Intro
This notebook will align trimmed/repaired FastQs generated by 00.00-trimming-fastp.Rmd
to the C.viginica genome using Bismark (Krueger and Andrews 2011) and Bowtie2 (Langmead et al. 2018; Langmead and Salzberg 2012). Alignment results will be summarized by MultiQC (Ewels et al. 2016).
Alignments were run with the Bowtie score setting of L,0,-0.6
.
NOTE: This process will take ~2 weeks to complete, when run on a computer with 48 CPUs!
NOTE: This notebook was not used for this project. It was superseded by 02.01-bismark-bowtie2-alignment-SLURM-array.sh
, which was executed as part of an array of nodes on the Univ. of Washington HPC. However, the code has been left here to use for those who do not have access to such resources.
Outputs
The expected outputs will be:
*_R1_001.fastp-trim_bismark_bt2_PE_report.txt
: A text file summarizing the alignment input and results. Despite the R1
naming, these reports are based on paired reads; the R1
naming is a quirk of Bismark.
*_R1_001.fastp-trim_bismark_bt2_pe.bam
:A BAM alignment. Despite the R1
naming, these BAMs are paired reads; the R1
naming is a quirk of Bismark.
bismark_summary.txt
: An overall summary report of the alignment process. Essentially, this is all of the individual *report.txt
files combined into a single file.
multiqc_report.html
: A summary report of the alignment results generated by MultiQC, in HTML format.
Due to the large file sizes of BAMS, these cannot be hosted in the ceasmallr GitHub repo. As such these files are available for download here:
Create a Bash variables file
This allows usage of Bash variables across R Markdown chunks.
{
echo "#### Assign Variables ####"
echo ""
echo "# Data directories"
echo 'export repo_dir=/home/shared/8TB_HDD_01/sam/gitrepos/ceasmallr'
echo 'export output_dir_top=${repo_dir}/output/02.00-bismark-bowtie2-alignment'
echo 'export trimmed_reads_url="https://gannet.fish.washington.edu/Atumefaciens/20220826-cvir-larvae_zygote-BSseq-fastp_trimming/"'
echo 'export trimmed_fastqs_dir="${repo_dir}/output/00.00-trimming-fastp"'
echo ""
echo "# Input files"
echo 'export bisulfite_genome_url="http://owl.fish.washington.edu/halfshell/genomic-databank/Cvirginica_v300_bisulfite.tar.gz"'
echo 'export bisulfite_genome_gz="Cvirginica_v300_bisulfite.tar.gz"'
echo 'export bisulfite_genome_dir="${repo_dir}/data/Cvirginica_v300"'
echo ""
echo "# Paths to programs"
echo 'export programs_dir="/home/shared"'
echo 'export bismark_dir="${programs_dir}/Bismark-0.24.0"'
echo 'export bowtie2_dir="${programs_dir}/bowtie2-2.4.4-linux-x86_64"'
echo 'export multiqc="/home/sam/programs/mambaforge/bin/multiqc"'
echo 'export samtools_dir="${programs_dir}/samtools-1.12"'
echo ""
echo "# Program settings"
echo 'export bowtie2_min_score="L,0,-0.6"'
echo ""
echo "# Set FastQ filename patterns"
echo "export fastq_pattern='*.fq.gz'"
echo "export R1_fastq_pattern='*_R1_*.fq.gz'"
echo "export R2_fastq_pattern='*_R2_*.fq.gz'"
echo "export trimmed_fastq_pattern='*fastp-trim*.fq.gz'"
echo ""
echo "# Set number of CPUs to use"
echo 'export threads=10'
echo "# Bismark already spawns multiple instances and additional threads are multiplicative."
echo 'export bismark_threads=8'
echo ""
echo "## Inititalize arrays"
echo 'export fastq_array_R1=()'
echo 'export fastq_array_R2=()'
echo 'export trimmed_fastqs_array=()'
echo 'export R1_names_array=()'
echo 'export R2_names_array=()'
echo ""
echo "# Print formatting"
echo 'export line="--------------------------------------------------------"'
echo ""
} > .bashvars
cat .bashvars
#### Assign Variables ####
# Data directories
export repo_dir=/home/shared/8TB_HDD_01/sam/gitrepos/ceasmallr
export output_dir_top=${repo_dir}/output/02.00-bismark-bowtie2-alignment
export trimmed_reads_url="https://gannet.fish.washington.edu/Atumefaciens/20220826-cvir-larvae_zygote-BSseq-fastp_trimming/"
export trimmed_fastqs_dir="${repo_dir}/output/00.00-trimming-fastp"
# Input files
export bisulfite_genome_url="http://owl.fish.washington.edu/halfshell/genomic-databank/Cvirginica_v300_bisulfite.tar.gz"
export bisulfite_genome_gz="Cvirginica_v300_bisulfite.tar.gz"
export bisulfite_genome_dir="${repo_dir}/data/Cvirginica_v300"
# Paths to programs
export programs_dir="/home/shared"
export bismark_dir="${programs_dir}/Bismark-0.24.0"
export bowtie2_dir="${programs_dir}/bowtie2-2.4.4-linux-x86_64"
export multiqc="/home/sam/programs/mambaforge/bin/multiqc"
export samtools_dir="${programs_dir}/samtools-1.12"
# Program settings
export bowtie2_min_score="L,0,-0.6"
# Set FastQ filename patterns
export fastq_pattern='*.fq.gz'
export R1_fastq_pattern='*_R1_*.fq.gz'
export R2_fastq_pattern='*_R2_*.fq.gz'
export trimmed_fastq_pattern='*fastp-trim*.fq.gz'
# Set number of CPUs to use
export threads=10
# Bismark already spawns multiple instances and additional threads are multiplicative.
export bismark_threads=8
## Inititalize arrays
export fastq_array_R1=()
export fastq_array_R2=()
export trimmed_fastqs_array=()
export R1_names_array=()
export R2_names_array=()
# Print formatting
export line="--------------------------------------------------------"
Download bisulfite genome
# Load bash variables into memory
source .bashvars
cd "${repo_dir}"/data
wget --quiet \
--continue \
"${bisulfite_genome_url}"
ls -ltrh
Unpack bisulfite genome
# Load bash variables into memory
source .bashvars
cd "${repo_dir}"/data
if [ ! -d "${bisulfite_genome_dir}" ]; then
tar -xzf "${bisulfite_genome_gz}"
fi
tree "${bisulfite_genome_dir}"
Alignment
Find read pairs
This step is not needed and was only used as a “quick fix” measure to generate a file for use by 02.01-bismark-bowtie2-alignment-SLURM-array.sh
.
# Load bash variables into memory
source .bashvars
cd "${trimmed_fastqs_dir}"
if [[ -f "${output_dir_top}"/fastq_pairs.txt ]]; then
rm "${output_dir_top}"/fastq_pairs.txt
fi
# Find all _R1_ files and match them with their corresponding _R2_ files
for R1_file in *_R1_*.fq.gz; do
R2_file="${R1_file/_R1_/_R2_}"
if [[ -f "$R2_file" ]]; then
echo "$R1_file $R2_file" >> "${output_dir_top}"/fastq_pairs.txt
else
echo "Warning: No matching R2 file for $R1_file"
fi
done
cat "${output_dir_top}"/fastq_pairs.txt
CF01-CM01-Zygote_R1_001.fastp-trim.REPAIRED.fq.gz CF01-CM01-Zygote_R2_001.fastp-trim.REPAIRED.fq.gz
CF01-CM02-Larvae_R1_001.fastp-trim.fq.gz CF01-CM02-Larvae_R2_001.fastp-trim.fq.gz
CF02-CM02-Zygote_R1_001.fastp-trim.fq.gz CF02-CM02-Zygote_R2_001.fastp-trim.fq.gz
CF03-CM03-Zygote_R1_001.fastp-trim.fq.gz CF03-CM03-Zygote_R2_001.fastp-trim.fq.gz
CF03-CM04-Larvae_R1_001.fastp-trim.fq.gz CF03-CM04-Larvae_R2_001.fastp-trim.fq.gz
CF03-CM05-Larvae_R1_001.fastp-trim.fq.gz CF03-CM05-Larvae_R2_001.fastp-trim.fq.gz
CF04-CM04-Zygote_R1_001.fastp-trim.fq.gz CF04-CM04-Zygote_R2_001.fastp-trim.fq.gz
CF05-CM02-Larvae_R1_001.fastp-trim.fq.gz CF05-CM02-Larvae_R2_001.fastp-trim.fq.gz
CF05-CM05-Zygote_R1_001.fastp-trim.fq.gz CF05-CM05-Zygote_R2_001.fastp-trim.fq.gz
CF06-CM01-Zygote_R1_001.fastp-trim.fq.gz CF06-CM01-Zygote_R2_001.fastp-trim.fq.gz
CF06-CM02-Larvae_R1_001.fastp-trim.fq.gz CF06-CM02-Larvae_R2_001.fastp-trim.fq.gz
CF07-CM02-Zygote_R1_001.fastp-trim.fq.gz CF07-CM02-Zygote_R2_001.fastp-trim.fq.gz
CF08-CM03-Zygote_R1_001.fastp-trim.fq.gz CF08-CM03-Zygote_R2_001.fastp-trim.fq.gz
CF08-CM04-Larvae_R1_001.fastp-trim.REPAIRED.fq.gz CF08-CM04-Larvae_R2_001.fastp-trim.REPAIRED.fq.gz
CF08-CM05-Larvae_R1_001.fastp-trim.fq.gz CF08-CM05-Larvae_R2_001.fastp-trim.fq.gz
EF01-EM01-Zygote_R1_001.fastp-trim.fq.gz EF01-EM01-Zygote_R2_001.fastp-trim.fq.gz
EF02-EM02-Zygote_R1_001.fastp-trim.fq.gz EF02-EM02-Zygote_R2_001.fastp-trim.fq.gz
EF03-EM03-Zygote_R1_001.fastp-trim.REPAIRED.fq.gz EF03-EM03-Zygote_R2_001.fastp-trim.REPAIRED.fq.gz
EF03-EM04-Larvae_R1_001.fastp-trim.fq.gz EF03-EM04-Larvae_R2_001.fastp-trim.fq.gz
EF03-EM05-Larvae_R1_001.fastp-trim.fq.gz EF03-EM05-Larvae_R2_001.fastp-trim.fq.gz
EF04-EM04-Zygote_R1_001.fastp-trim.fq.gz EF04-EM04-Zygote_R2_001.fastp-trim.fq.gz
EF04-EM05-Larvae_R1_001.fastp-trim.fq.gz EF04-EM05-Larvae_R2_001.fastp-trim.fq.gz
EF05-EM01-Larvae_R1_001.fastp-trim.fq.gz EF05-EM01-Larvae_R2_001.fastp-trim.fq.gz
EF05-EM05-Zygote_R1_001.fastp-trim.fq.gz EF05-EM05-Zygote_R2_001.fastp-trim.fq.gz
EF05-EM06-Larvae_R1_001.fastp-trim.fq.gz EF05-EM06-Larvae_R2_001.fastp-trim.fq.gz
EF06-EM01-Larvae_R1_001.fastp-trim.fq.gz EF06-EM01-Larvae_R2_001.fastp-trim.fq.gz
EF06-EM02-Larvae_R1_001.fastp-trim.fq.gz EF06-EM02-Larvae_R2_001.fastp-trim.fq.gz
EF06-EM06-Larvae_R1_001.fastp-trim.fq.gz EF06-EM06-Larvae_R2_001.fastp-trim.fq.gz
EF07-EM01-Zygote_R1_001.fastp-trim.fq.gz EF07-EM01-Zygote_R2_001.fastp-trim.fq.gz
EF07-EM03-Larvae_R1_001.fastp-trim.fq.gz EF07-EM03-Larvae_R2_001.fastp-trim.fq.gz
EF08-EM03-Larvae_R1_001.fastp-trim.fq.gz EF08-EM03-Larvae_R2_001.fastp-trim.fq.gz
EF08-EM04-Larvae_R1_001.fastp-trim.fq.gz EF08-EM04-Larvae_R2_001.fastp-trim.fq.gz
List outputs
# Load bash variables into memory
source .bashvars
cd "${output_dir_top}"
ls -lh
MultiQC
# Load bash variables into memory
source .bashvars
cd "${output_dir_top}"
${multiqc} .
Checksums
# Load bash variables into memory
source .bashvars
cd "${output_dir_top}"
for file in *; do
if [ "${file}" != "checksums.md5" ]; then
md5sum "${file}" >> checksums.md5
fi
done
Citations
Ewels, Philip, Måns Magnusson, Sverker Lundin, and Max Käller. 2016.
“MultiQC: Summarize Analysis Results for Multiple Tools and Samples in a Single Report.” Bioinformatics 32 (19): 3047–48.
https://doi.org/10.1093/bioinformatics/btw354.
Krueger, Felix, and Simon R. Andrews. 2011.
“Bismark: A Flexible Aligner and Methylation Caller for Bisulfite-Seq Applications.” Bioinformatics 27 (11): 1571–72.
https://doi.org/10.1093/bioinformatics/btr167.
Langmead, Ben, and Steven L Salzberg. 2012.
“Fast Gapped-Read Alignment with Bowtie 2.” Nature Methods 9 (4): 357–59.
https://doi.org/10.1038/nmeth.1923.
Langmead, Ben, Christopher Wilks, Valentin Antonescu, and Rone Charles. 2018.
“Scaling Read Aligners to Hundreds of Threads on General-Purpose Processors.” Edited by John Hancock.
Bioinformatics 35 (3): 421–32.
https://doi.org/10.1093/bioinformatics/bty648.
LS0tCnRpdGxlOiAiMDIuMDAtYmlzbWFyay1ib3d0aWUyLWFsaWdubWVudCIKYXV0aG9yOiAiU2FtIFdoaXRlIgpkYXRlOiAiMjAyNC0xMC0yMyIKb3V0cHV0OiAKICBib29rZG93bjo6aHRtbF9kb2N1bWVudDI6CiAgICB0aGVtZTogY29zbW8KICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogIGdpdGh1Yl9kb2N1bWVudDoKICAgIHRvYzogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgaHRtbF9kb2N1bWVudDoKICAgIHRoZW1lOiBjb3NtbwogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCmJpYmxpb2dyYXBoeTogcmVmZXJlbmNlcy5iaWIKLS0tCiMgSW50cm8KClRoaXMgbm90ZWJvb2sgd2lsbCBhbGlnbiB0cmltbWVkL3JlcGFpcmVkIEZhc3RRcyBnZW5lcmF0ZWQgYnkgW2AwMC4wMC10cmltbWluZy1mYXN0cC5SbWRgXSguLzAwLjAwLXRyaW1taW5nLWZhc3RwLlJtZCkgdG8gdGhlICpDLnZpZ2luaWNhKiBnZW5vbWUgdXNpbmcgW0Jpc21hcmtdKGh0dHBzOi8vZmVsaXhrcnVlZ2VyLmdpdGh1Yi5pby9CaXNtYXJrLykgW0BrcnVlZ2VyMjAxMV0gYW5kIFtCb3d0aWUyXShodHRwczovL2dpdGh1Yi5jb20vQmVuTGFuZ21lYWQvYm93dGllMikgW0BsYW5nbWVhZDIwMTg7IEBsYW5nbWVhZDIwMTJdLiBBbGlnbm1lbnQgcmVzdWx0cyB3aWxsIGJlIHN1bW1hcml6ZWQgYnkgW011bHRpUUNdKGh0dHBzOi8vZ2l0aHViLmNvbS9NdWx0aVFDL011bHRpUUMpIFtAZXdlbHMyMDE2XS4KCkFsaWdubWVudHMgd2VyZSBydW4gd2l0aCB0aGUgQm93dGllIHNjb3JlIHNldHRpbmcgb2YgYEwsMCwtMC42YC4KCk5PVEU6IFRoaXMgcHJvY2VzcyB3aWxsIHRha2UgfjIgd2Vla3MgdG8gY29tcGxldGUsIHdoZW4gcnVuIG9uIGEgY29tcHV0ZXIgd2l0aCA0OCBDUFVzIQoKTk9URTogVGhpcyBub3RlYm9vayB3YXMgbm90IHVzZWQgZm9yIHRoaXMgcHJvamVjdC4gSXQgd2FzIHN1cGVyc2VkZWQgYnkgW2AwMi4wMS1iaXNtYXJrLWJvd3RpZTItYWxpZ25tZW50LVNMVVJNLWFycmF5LnNoYF0oLi8wMi4wMS1iaXNtYXJrLWJvd3RpZTItYWxpZ25tZW50LVNMVVJNLWFycmF5LnNoKSwgd2hpY2ggd2FzIGV4ZWN1dGVkIGFzIHBhcnQgb2YgYW4gYXJyYXkgb2Ygbm9kZXMgb24gdGhlIFVuaXYuIG9mIFdhc2hpbmd0b24gSFBDLiBIb3dldmVyLCB0aGUgY29kZSBoYXMgYmVlbiBsZWZ0IGhlcmUgdG8gdXNlIGZvciB0aG9zZSB3aG8gZG8gbm90IGhhdmUgYWNjZXNzIHRvIHN1Y2ggcmVzb3VyY2VzLgoKIyMgSW5wdXRzCgpFeHBlY3RzIHRyaW1tZWQvcmVwYWlyZWQgRmFzdFFzIGdlbmVyYXRlZCBieSBbYDAwLjAwLXRyaW1taW5nLWZhc3RwLlJtZGBdKC4vMDAuMDAtdHJpbW1pbmctZmFzdHAuUm1kKSwgd2l0aCB0aGUgZm9sbG93aW5nIGZvcm1hdDoKCi0gYCpmYXN0cC10cmltKi5mcS5nemAKCiMjIE91dHB1dHMKClRoZSBleHBlY3RlZCBvdXRwdXRzIHdpbGwgYmU6CgotICAgYCpfUjFfMDAxLmZhc3RwLXRyaW1fYmlzbWFya19idDJfUEVfcmVwb3J0LnR4dGA6IEEgdGV4dCBmaWxlIHN1bW1hcml6aW5nIHRoZSBhbGlnbm1lbnQgaW5wdXQgYW5kIHJlc3VsdHMuIERlc3BpdGUgdGhlIGBSMWAgbmFtaW5nLCB0aGVzZSByZXBvcnRzIGFyZSBiYXNlZCBvbiAqcGFpcmVkIHJlYWRzKjsgdGhlIGBSMWAgbmFtaW5nIGlzIGEgcXVpcmsgb2YgW0Jpc21hcmtdKGh0dHBzOi8vZmVsaXhrcnVlZ2VyLmdpdGh1Yi5pby9CaXNtYXJrLykuCgotICAgYCpfUjFfMDAxLmZhc3RwLXRyaW1fYmlzbWFya19idDJfcGUuYmFtYDpBIEJBTSBhbGlnbm1lbnQuIERlc3BpdGUgdGhlIGBSMWAgbmFtaW5nLCB0aGVzZSBCQU1zIGFyZSAqcGFpcmVkIHJlYWRzKjsgdGhlIGBSMWAgbmFtaW5nIGlzIGEgcXVpcmsgb2YgW0Jpc21hcmtdKGh0dHBzOi8vZmVsaXhrcnVlZ2VyLmdpdGh1Yi5pby9CaXNtYXJrLykuCgotICAgYGJpc21hcmtfc3VtbWFyeS50eHRgOiBBbiBvdmVyYWxsIHN1bW1hcnkgcmVwb3J0IG9mIHRoZSBhbGlnbm1lbnQgcHJvY2Vzcy4gRXNzZW50aWFsbHksIHRoaXMgaXMgYWxsIG9mIHRoZSBpbmRpdmlkdWFsIGAqcmVwb3J0LnR4dGAgZmlsZXMgY29tYmluZWQgaW50byBhIHNpbmdsZSBmaWxlLgoKLSAgIGBtdWx0aXFjX3JlcG9ydC5odG1sYDogQSBzdW1tYXJ5IHJlcG9ydCBvZiB0aGUgYWxpZ25tZW50IHJlc3VsdHMgZ2VuZXJhdGVkIGJ5IFtNdWx0aVFDXShodHRwczovL2dpdGh1Yi5jb20vTXVsdGlRQy9NdWx0aVFDKSwgaW4gSFRNTCBmb3JtYXQuCgpEdWUgdG8gdGhlIGxhcmdlIGZpbGUgc2l6ZXMgb2YgQkFNUywgdGhlc2UgY2Fubm90IGJlIGhvc3RlZCBpbiB0aGUgW2NlYXNtYWxsciBHaXRIdWIgcmVwb10oaHR0cHM6Ly9naXRodWIuY29tL3NyMzIwL2NlYXNtYWxscikuIEFzIHN1Y2ggdGhlc2UgZmlsZXMgYXJlIGF2YWlsYWJsZSBmb3IgZG93bmxvYWQgaGVyZToKCi0gW2h0dHBzOi8vZ2FubmV0LmZpc2gud2FzaGluZ3Rvbi5lZHUvZ2l0cmVwb3MvY2Vhc21hbGxyL10oaHR0cHM6Ly9nYW5uZXQuZmlzaC53YXNoaW5ndG9uLmVkdS9naXRyZXBvcy9jZWFzbWFsbHIvKQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoa25pdHIpCmtuaXRyOjpvcHRzX2NodW5rJHNldCgKICBlY2hvID0gVFJVRSwgICAgICAgICAjIERpc3BsYXkgY29kZSBjaHVua3MKICBldmFsID0gRkFMU0UsICAgICAgICAjIEV2YWx1YXRlIGNvZGUgY2h1bmtzCiAgd2FybmluZyA9IEZBTFNFLCAgICAgIyBIaWRlIHdhcm5pbmdzCiAgbWVzc2FnZSA9IEZBTFNFLCAgICAgIyBIaWRlIG1lc3NhZ2VzCiAgY29tbWVudCA9ICIiICAgICAgICAgIyBQcmV2ZW50cyBhcHBlbmRpbmcgJyMjJyB0byBiZWdpbm5pbmcgb2YgbGluZXMgaW4gY29kZSBvdXRwdXQKKQpgYGAKCiMgQ3JlYXRlIGEgQmFzaCB2YXJpYWJsZXMgZmlsZQoKVGhpcyBhbGxvd3MgdXNhZ2Ugb2YgQmFzaCB2YXJpYWJsZXMgYWNyb3NzIFIgTWFya2Rvd24gY2h1bmtzLgoKYGBge3Igc2F2ZS1iYXNoLXZhcmlhYmxlcy10by1ydmFycy1maWxlLCBlbmdpbmU9J2Jhc2gnLCBldmFsPVRSVUV9CnsKZWNobyAiIyMjIyBBc3NpZ24gVmFyaWFibGVzICMjIyMiCmVjaG8gIiIKCmVjaG8gIiMgRGF0YSBkaXJlY3RvcmllcyIKZWNobyAnZXhwb3J0IHJlcG9fZGlyPS9ob21lL3NoYXJlZC84VEJfSEREXzAxL3NhbS9naXRyZXBvcy9jZWFzbWFsbHInCmVjaG8gJ2V4cG9ydCBvdXRwdXRfZGlyX3RvcD0ke3JlcG9fZGlyfS9vdXRwdXQvMDIuMDAtYmlzbWFyay1ib3d0aWUyLWFsaWdubWVudCcKZWNobyAnZXhwb3J0IHRyaW1tZWRfcmVhZHNfdXJsPSJodHRwczovL2dhbm5ldC5maXNoLndhc2hpbmd0b24uZWR1L0F0dW1lZmFjaWVucy8yMDIyMDgyNi1jdmlyLWxhcnZhZV96eWdvdGUtQlNzZXEtZmFzdHBfdHJpbW1pbmcvIicKZWNobyAnZXhwb3J0IHRyaW1tZWRfZmFzdHFzX2Rpcj0iJHtyZXBvX2Rpcn0vb3V0cHV0LzAwLjAwLXRyaW1taW5nLWZhc3RwIicKZWNobyAiIgoKZWNobyAiIyBJbnB1dCBmaWxlcyIKZWNobyAnZXhwb3J0IGJpc3VsZml0ZV9nZW5vbWVfdXJsPSJodHRwOi8vb3dsLmZpc2gud2FzaGluZ3Rvbi5lZHUvaGFsZnNoZWxsL2dlbm9taWMtZGF0YWJhbmsvQ3ZpcmdpbmljYV92MzAwX2Jpc3VsZml0ZS50YXIuZ3oiJwplY2hvICdleHBvcnQgYmlzdWxmaXRlX2dlbm9tZV9nej0iQ3ZpcmdpbmljYV92MzAwX2Jpc3VsZml0ZS50YXIuZ3oiJwplY2hvICdleHBvcnQgYmlzdWxmaXRlX2dlbm9tZV9kaXI9IiR7cmVwb19kaXJ9L2RhdGEvQ3ZpcmdpbmljYV92MzAwIicKZWNobyAiIgoKZWNobyAiIyBQYXRocyB0byBwcm9ncmFtcyIKZWNobyAnZXhwb3J0IHByb2dyYW1zX2Rpcj0iL2hvbWUvc2hhcmVkIicKZWNobyAnZXhwb3J0IGJpc21hcmtfZGlyPSIke3Byb2dyYW1zX2Rpcn0vQmlzbWFyay0wLjI0LjAiJwplY2hvICdleHBvcnQgYm93dGllMl9kaXI9IiR7cHJvZ3JhbXNfZGlyfS9ib3d0aWUyLTIuNC40LWxpbnV4LXg4Nl82NCInCmVjaG8gJ2V4cG9ydCBtdWx0aXFjPSIvaG9tZS9zYW0vcHJvZ3JhbXMvbWFtYmFmb3JnZS9iaW4vbXVsdGlxYyInCmVjaG8gJ2V4cG9ydCBzYW10b29sc19kaXI9IiR7cHJvZ3JhbXNfZGlyfS9zYW10b29scy0xLjEyIicKZWNobyAiIgoKZWNobyAiIyBQcm9ncmFtIHNldHRpbmdzIgplY2hvICdleHBvcnQgYm93dGllMl9taW5fc2NvcmU9IkwsMCwtMC42IicKZWNobyAiIgoKZWNobyAiIyBTZXQgRmFzdFEgZmlsZW5hbWUgcGF0dGVybnMiCmVjaG8gImV4cG9ydCBmYXN0cV9wYXR0ZXJuPScqLmZxLmd6JyIKZWNobyAiZXhwb3J0IFIxX2Zhc3RxX3BhdHRlcm49JypfUjFfKi5mcS5neiciCmVjaG8gImV4cG9ydCBSMl9mYXN0cV9wYXR0ZXJuPScqX1IyXyouZnEuZ3onIgoKZWNobyAiZXhwb3J0IHRyaW1tZWRfZmFzdHFfcGF0dGVybj0nKmZhc3RwLXRyaW0qLmZxLmd6JyIKZWNobyAiIgoKZWNobyAiIyBTZXQgbnVtYmVyIG9mIENQVXMgdG8gdXNlIgplY2hvICdleHBvcnQgdGhyZWFkcz0xMCcKZWNobyAiIyBCaXNtYXJrIGFscmVhZHkgc3Bhd25zIG11bHRpcGxlIGluc3RhbmNlcyBhbmQgYWRkaXRpb25hbCB0aHJlYWRzIGFyZSBtdWx0aXBsaWNhdGl2ZS4iCmVjaG8gJ2V4cG9ydCBiaXNtYXJrX3RocmVhZHM9OCcgCmVjaG8gIiIKCgplY2hvICIjIyBJbml0aXRhbGl6ZSBhcnJheXMiCmVjaG8gJ2V4cG9ydCBmYXN0cV9hcnJheV9SMT0oKScKZWNobyAnZXhwb3J0IGZhc3RxX2FycmF5X1IyPSgpJwplY2hvICdleHBvcnQgdHJpbW1lZF9mYXN0cXNfYXJyYXk9KCknCmVjaG8gJ2V4cG9ydCBSMV9uYW1lc19hcnJheT0oKScKZWNobyAnZXhwb3J0IFIyX25hbWVzX2FycmF5PSgpJwplY2hvICIiCgplY2hvICIjIFByaW50IGZvcm1hdHRpbmciCmVjaG8gJ2V4cG9ydCBsaW5lPSItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSInCmVjaG8gIiIKfSA+IC5iYXNodmFycwoKY2F0IC5iYXNodmFycwpgYGAKCiMgRG93bmxvYWQgYmlzdWxmaXRlIGdlbm9tZQoKYGBge2Jhc2ggZG93bmxvYWQtYmlzdWxmaXRlLWdlbm9tZSwgZW5naW5lPSdiYXNoJywgZXZhbD1GQUxTRX0KIyBMb2FkIGJhc2ggdmFyaWFibGVzIGludG8gbWVtb3J5CnNvdXJjZSAuYmFzaHZhcnMKCmNkICIke3JlcG9fZGlyfSIvZGF0YQoKd2dldCAtLXF1aWV0IFwKLS1jb250aW51ZSBcCiIke2Jpc3VsZml0ZV9nZW5vbWVfdXJsfSIKCmxzIC1sdHJoCmBgYAoKIyMgVW5wYWNrIGJpc3VsZml0ZSBnZW5vbWUKCmBgYHtiYXNoIHVucGFjay1iaXN1bGZpdGUtZ2Vub21lLCBlbmdpbmU9J2Jhc2gnLCBldmFsPUZBTFNFfQojIExvYWQgYmFzaCB2YXJpYWJsZXMgaW50byBtZW1vcnkKc291cmNlIC5iYXNodmFycwoKY2QgIiR7cmVwb19kaXJ9Ii9kYXRhCgppZiBbICEgLWQgIiR7YmlzdWxmaXRlX2dlbm9tZV9kaXJ9IiBdOyB0aGVuCiAgdGFyIC14emYgIiR7YmlzdWxmaXRlX2dlbm9tZV9nen0iCmZpCgp0cmVlICIke2Jpc3VsZml0ZV9nZW5vbWVfZGlyfSIKYGBgCgoKIyBBbGlnbm1lbnQKCiMjIEZpbmQgcmVhZCBwYWlycwoKVGhpcyBzdGVwIGlzIG5vdCBuZWVkZWQgYW5kIHdhcyBvbmx5IHVzZWQgYXMgYSAicXVpY2sgZml4IiBtZWFzdXJlIHRvIGdlbmVyYXRlIGEgZmlsZSBmb3IgdXNlIGJ5IFtgMDIuMDEtYmlzbWFyay1ib3d0aWUyLWFsaWdubWVudC1TTFVSTS1hcnJheS5zaGBdKC4vMDIuMDEtYmlzbWFyay1ib3d0aWUyLWFsaWdubWVudC1TTFVSTS1hcnJheS5zaCkuCgpgYGB7ciBmaW5kLXJlYWQtcGFpcnMsIGVuZ2luZT0nYmFzaCcsIGV2YWw9VFJVRX0KIyBMb2FkIGJhc2ggdmFyaWFibGVzIGludG8gbWVtb3J5CnNvdXJjZSAuYmFzaHZhcnMKCgpjZCAiJHt0cmltbWVkX2Zhc3Rxc19kaXJ9IgoKaWYgW1sgLWYgIiR7b3V0cHV0X2Rpcl90b3B9Ii9mYXN0cV9wYWlycy50eHQgXV07IHRoZW4KICBybSAiJHtvdXRwdXRfZGlyX3RvcH0iL2Zhc3RxX3BhaXJzLnR4dApmaQoKIyBGaW5kIGFsbCBfUjFfIGZpbGVzIGFuZCBtYXRjaCB0aGVtIHdpdGggdGhlaXIgY29ycmVzcG9uZGluZyBfUjJfIGZpbGVzCmZvciBSMV9maWxlIGluICpfUjFfKi5mcS5nejsgZG8KICAgIFIyX2ZpbGU9IiR7UjFfZmlsZS9fUjFfL19SMl99IgogICAgaWYgW1sgLWYgIiRSMl9maWxlIiBdXTsgdGhlbgogICAgICAgIGVjaG8gIiRSMV9maWxlICRSMl9maWxlIiA+PiAiJHtvdXRwdXRfZGlyX3RvcH0iL2Zhc3RxX3BhaXJzLnR4dAogICAgZWxzZQogICAgICAgIGVjaG8gIldhcm5pbmc6IE5vIG1hdGNoaW5nIFIyIGZpbGUgZm9yICRSMV9maWxlIgogICAgZmkKZG9uZQoKCmNhdCAiJHtvdXRwdXRfZGlyX3RvcH0iL2Zhc3RxX3BhaXJzLnR4dAoKCmBgYAoKCiMjIFBlcmZvcm0gYWxpZ25tZW50cwoKYGBge2Jhc2ggYWxpZ25tZW50LCBlbmdpbmU9J2Jhc2gnLCBldmFsPUZBTFNFfQojIExvYWQgYmFzaCB2YXJpYWJsZXMgaW50byBtZW1vcnkKc291cmNlIC5iYXNodmFycwoKY2QgIiR7dHJpbW1lZF9mYXN0cXNfZGlyfSIKCmZpbmQgJHt0cmltbWVkX2Zhc3Rxc19kaXJ9LyR7UjFfZmFzdHFfcGF0dGVybn0gXAp8IHhhcmdzIGJhc2VuYW1lIC1zICIke1IxX3JlYWRzX2Jhc2VuYW1lfSIgXAp8IHhhcmdzIC1JIHt9ICR7YmlzbWFya19kaXJ9L2Jpc21hcmsgXAotLXBhdGhfdG9fYm93dGllMiAke2Jvd3RpZTJfZGlyfSBcCi0tZ2Vub21lICR7YmlzdWxmaXRlX2dlbm9tZV9kaXJ9IFwKLS1zY29yZV9taW4gIiR7Ym93dGllMl9taW5fc2NvcmV9IiBcCi0tcGFyYWxsZWwgIiR7YmlzbWFya190aHJlYWRzfSIgXAotLW5vbl9kaXJlY3Rpb25hbCBcCi0tc2FtdG9vbHNfcGF0aCAiJHtzYW10b29sc19kaXJ9IiBcCi0tZ3ppcCBcCi1wICIke3RocmVhZHN9IiBcCi0xICR7dHJpbW1lZF9mYXN0cXNfZGlyfS97fSIke1IxX3JlYWRzX2Jhc2VuYW1lfSIgXAotMiAke3RyaW1tZWRfZmFzdHFzX2Rpcn0ve30iJHtSMl9yZWFkc19iYXNlbmFtZX0iIFwKLS1vdXRwdXRfZGlyICIke291dHB1dF9kaXJfdG9wfSIgXAoyPiAiJHtvdXRwdXRfZGlyX3RvcH0iL2Jpc21hcmtfc3VtbWFyeS50eHQKCmBgYAoKIyMgTGlzdCBvdXRwdXRzCgpgYGB7ciBsaXN0LW91dHB1dHMsIGVuZ2luZT0nYmFzaCcsIGV2YWw9RkFMU0V9CiMgTG9hZCBiYXNoIHZhcmlhYmxlcyBpbnRvIG1lbW9yeQpzb3VyY2UgLmJhc2h2YXJzCgpjZCAiJHtvdXRwdXRfZGlyX3RvcH0iCgpscyAtbGgKYGBgCgojIE11bHRpUUMKCmBgYHtyIG11bHRpcWMsIGVuZ2luZT0nYmFzaCcsIGV2YWw9RkFMU0V9CiMgTG9hZCBiYXNoIHZhcmlhYmxlcyBpbnRvIG1lbW9yeQpzb3VyY2UgLmJhc2h2YXJzCgpjZCAiJHtvdXRwdXRfZGlyX3RvcH0iCgoke211bHRpcWN9IC4KYGBgCgojIENoZWNrc3VtcwoKYGBge3IgZ2VuZXJhdGUtY2hlY2tzdW1zLCBlbmdpbmU9J2Jhc2gnLCBldmFsPUZBTFNFfQojIExvYWQgYmFzaCB2YXJpYWJsZXMgaW50byBtZW1vcnkKc291cmNlIC5iYXNodmFycwoKY2QgIiR7b3V0cHV0X2Rpcl90b3B9IgoKZm9yIGZpbGUgaW4gKjsgZG8KICBpZiBbICIke2ZpbGV9IiAhPSAiY2hlY2tzdW1zLm1kNSIgXTsgdGhlbgogICAgbWQ1c3VtICIke2ZpbGV9IiA+PiBjaGVja3N1bXMubWQ1CiAgZmkKZG9uZQpgYGAKCiMgQ2l0YXRpb25zCg==