FastQC/MultiQC (Ewels et al. 2016; Andrews, n.d.) assessment of raw and flexbar-trimmed (Dodt et al. 2012; Roehr, Dieterich, and Reinert 2017) sequences of E5 P.evermanni sRNAseq data from 20230515.

Inputs:

  • sRNAseq gzipped FastQs (e.g. *.fastq.gz)

Outputs:

  • FastQC HTML reports for raw and trimmed reads.

  • MultiQC HTML summaries of FastQC for raw and trimmed reads.

  • Trimmed reads with final length of 25bp: *flexbar_trim.25bp.fastq.gz

Libraries were prepared and sequenced by Azenta:


1 Create a Bash variables file

This allows usage of Bash variables across R Markdown chunks.

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

echo "# Data directories"
echo 'export deep_dive_dir=/home/shared/8TB_HDD_01/sam/gitrepos/deep-dive'
echo 'export output_dir_top=${deep_dive_dir}/E-Peve/output/06-Peve-sRNAseq-trimming'
echo 'export raw_fastqc_dir=${deep_dive_dir}/E-Peve/output/06-Peve-sRNAseq-trimming/raw-fastqc'
echo 'export raw_reads_dir=${deep_dive_dir}/E-Peve/data/06-Peve-sRNAseq-trimming/raw-reads'
echo 'export raw_reads_url="https://owl.fish.washington.edu/nightingales/P_evermanni/30-852430235/"'
echo 'export trimmed_fastqc_dir=${deep_dive_dir}/E-Peve/output/06-Peve-sRNAseq-trimming/trimmed-fastqc'
echo 'export trimmed_reads_dir=${deep_dive_dir}/E-Peve/output/06-Peve-sRNAseq-trimming/trimmed-reads'
echo ""

echo "# Paths to programs"
echo 'export fastqc=/home/shared/FastQC-0.12.1/fastqc'
echo 'export flexbar=/home/shared/flexbar-3.5.0-linux/flexbar'
echo 'export multiqc=/home/sam/programs/mambaforge/bin/multiqc'
echo ""



echo "# Set FastQ filename patterns"
echo "export fastq_pattern='*.fastq.gz'"
echo "export R1_fastq_pattern='*_R1_*.fastq.gz'"
echo "export R2_fastq_pattern='*_R2_*.fastq.gz'"
echo ""

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

echo "# Set maximum read length"
echo 'export max_read_length=25'
echo ""

echo "# Input/output files"
echo 'export fastq_checksums=input_fastq_checksums.md5'
echo 'export trimmed_checksums=trimmed_fastq_checksums.md5'
echo 'export NEB_adapters_fasta=NEB-adapters.fasta'
echo ""

echo "## NEB nebnext-small-rna-library-prep-set-for-illumina adapters"
echo 'export first_adapter="AGATCGGAAGAGCACACGTCTGAACTCCAGTCAC"'
echo 'export second_adapter="GATCGTCGGACTGTAGAACTCTGAACGTGTAGATCTCGGTGGTCGCCGTATCATT"'
echo ""

echo "## Inititalize arrays"
echo 'export fastq_array_R1=()'
echo 'export fastq_array_R2=()'
echo 'export raw_fastqs_array=()'
echo 'export R1_names_array=()'
echo 'export R2_names_array=()'
echo 'export trimmed_fastqs_array=()'
echo ""

echo "# Programs associative array"
echo "declare -A programs_array"
echo "programs_array=("
echo '[fastqc]="${fastqc}" \'
echo '[multiqc]="${multiqc}" \'
echo '[flexbar]="${flexbar}"'
echo ")"
} > .bashvars

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

# Data directories
export deep_dive_dir=/home/shared/8TB_HDD_01/sam/gitrepos/deep-dive
export output_dir_top=${deep_dive_dir}/E-Peve/output/06-Peve-sRNAseq-trimming
export raw_fastqc_dir=${deep_dive_dir}/E-Peve/output/06-Peve-sRNAseq-trimming/raw-fastqc
export raw_reads_dir=${deep_dive_dir}/E-Peve/data/06-Peve-sRNAseq-trimming/raw-reads
export raw_reads_url="https://owl.fish.washington.edu/nightingales/P_evermanni/30-852430235/"
export trimmed_fastqc_dir=${deep_dive_dir}/E-Peve/output/06-Peve-sRNAseq-trimming/trimmed-fastqc
export trimmed_reads_dir=${deep_dive_dir}/E-Peve/output/06-Peve-sRNAseq-trimming/trimmed-reads

# Paths to programs
export fastqc=/home/shared/FastQC-0.12.1/fastqc
export flexbar=/home/shared/flexbar-3.5.0-linux/flexbar
export multiqc=/home/sam/programs/mambaforge/bin/multiqc

# Set FastQ filename patterns
export fastq_pattern='*.fastq.gz'
export R1_fastq_pattern='*_R1_*.fastq.gz'
export R2_fastq_pattern='*_R2_*.fastq.gz'

# Set number of CPUs to use
export threads=40

# Set maximum read length
export max_read_length=25

# Input/output files
export fastq_checksums=input_fastq_checksums.md5
export trimmed_checksums=trimmed_fastq_checksums.md5
export NEB_adapters_fasta=NEB-adapters.fasta

## NEB nebnext-small-rna-library-prep-set-for-illumina adapters
export first_adapter="AGATCGGAAGAGCACACGTCTGAACTCCAGTCAC"
export second_adapter="GATCGTCGGACTGTAGAACTCTGAACGTGTAGATCTCGGTGGTCGCCGTATCATT"

## Inititalize arrays
export fastq_array_R1=()
export fastq_array_R2=()
export raw_fastqs_array=()
export R1_names_array=()
export R2_names_array=()
export trimmed_fastqs_array=()

# Programs associative array
declare -A programs_array
programs_array=(
[fastqc]="${fastqc}" \
[multiqc]="${multiqc}" \
[flexbar]="${flexbar}"
)

2 Download raw sRNAseq reads

Reads are downloaded from https://owl.fish.washington.edu/nightingales/P_evermanni/30-852430235/

The --cut-dirs 3 command cuts the preceding directory structure (i.e. nightingales/P_evermanni/30-852430235/) so that we just end up with the reads.

# Load bash variables into memory
source .bashvars

wget \
--directory-prefix ${raw_reads_dir} \
--recursive \
--no-check-certificate \
--continue \
--cut-dirs 3 \
--no-host-directories \
--no-parent \
--quiet \
--accept "sRNA*,checksums.md5" ${raw_reads_url}

ls -lh "${raw_reads_dir}"
total 5.6G
-rw-r--r-- 1 sam sam  798 May 17 11:23 checksums.md5
-rw-r--r-- 1 sam sam 953M May 17 10:46 sRNA-POR-73-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 sam sam 1.1G May 17 10:47 sRNA-POR-73-S1-TP2_R2_001.fastq.gz
-rw-r--r-- 1 sam sam 899M May 17 10:48 sRNA-POR-79-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 sam sam 916M May 17 10:49 sRNA-POR-79-S1-TP2_R2_001.fastq.gz
-rw-r--r-- 1 sam sam 934M May 17 10:51 sRNA-POR-82-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 sam sam 959M May 17 10:52 sRNA-POR-82-S1-TP2_R2_001.fastq.gz

2.1 Verify raw read checksums

# Load bash variables into memory
source .bashvars

cd "${raw_reads_dir}"

# Checksums file contains other files, so this just looks for the sRNAseq files.
grep "sRNA" checksums.md5 | md5sum --check
sRNA-POR-73-S1-TP2_R1_001.fastq.gz: OK
sRNA-POR-73-S1-TP2_R2_001.fastq.gz: OK
sRNA-POR-79-S1-TP2_R1_001.fastq.gz: OK
sRNA-POR-79-S1-TP2_R2_001.fastq.gz: OK
sRNA-POR-82-S1-TP2_R1_001.fastq.gz: OK
sRNA-POR-82-S1-TP2_R2_001.fastq.gz: OK

3 Create adapters FastA for use with flexbar trimming

# Load bash variables into memory
source .bashvars

echo "Creating adapters FastA."
echo ""
adapter_count=0

# Check for adapters file first
# Then create adapters file if doesn't exist
if [ -f "${output_dir_top}/${NEB_adapters_fasta}" ]; then
  echo "${output_dir_top}/${NEB_adapters_fasta} already exists. Nothing to do."
else
  for adapter in "${first_adapter}" "${second_adapter}"
  do
    adapter_count=$((adapter_count + 1))
    printf ">%s\n%s\n" "adapter_${adapter_count}" "${adapter}"
  done >> "${output_dir_top}/${NEB_adapters_fasta}"
fi

echo ""
echo "Adapters FastA:"
echo ""
cat "${output_dir_top}/${NEB_adapters_fasta}"
echo ""
Creating adapters FastA.

/home/shared/8TB_HDD_01/sam/gitrepos/deep-dive/E-Peve/output/06-Peve-sRNAseq-trimming/NEB-adapters.fasta already exists. Nothing to do.

Adapters FastA:

>adapter_1
AGATCGGAAGAGCACACGTCTGAACTCCAGTCAC
>adapter_2
GATCGTCGGACTGTAGAACTCTGAACGTGTAGATCTCGGTGGTCGCCGTATCATT

4 FastQC/MultiQC on raw reads

# Load bash variables into memory
source .bashvars

############ RUN FASTQC ############


# Create array of trimmed FastQs
raw_fastqs_array=(${raw_reads_dir}/${fastq_pattern})

# Pass array contents to new variable as space-delimited list
raw_fastqc_list=$(echo "${raw_fastqs_array[*]}")

echo "Beginning FastQC on raw reads..."
echo ""

# Run FastQC
### NOTE: Do NOT quote raw_fastqc_list
${programs_array[fastqc]} \
--threads ${threads} \
--outdir ${raw_fastqc_dir} \
--quiet \
${raw_fastqc_list}

echo "FastQC on raw reads complete!"
echo ""

############ END FASTQC ############

############ RUN MULTIQC ############
echo "Beginning MultiQC on raw FastQC..."
echo ""

${programs_array[multiqc]} ${raw_fastqc_dir} -o ${raw_fastqc_dir}

echo ""
echo "MultiQC on raw FastQs complete."
echo ""

############ END MULTIQC ############

echo "Removing FastQC zip files."
echo ""
rm ${raw_fastqc_dir}/*.zip
echo "FastQC zip files removed."
echo ""

# View directory contents
ls -lh ${raw_fastqc_dir}

5 Trimming with flexbar

# Load bash variables into memory
source .bashvars

# Change to directory with raw reads
cd "${raw_reads_dir}"

# Create arrays of FastQ R1 files and sample names
# Do NOT quote R1_fastq_pattern variable
for fastq in ${R1_fastq_pattern}
do
  fastq_array_R1+=("${fastq}")

  # Use parameter substitution to remove all text up to and including last "." from
  # right side of string.
  R1_names_array+=("${fastq%%.*}")
done

# Create array of FastQ R2 files
# Do NOT quote R2_fastq_pattern variable
for fastq in ${R2_fastq_pattern}
do
  fastq_array_R2+=("${fastq}")

  # Use parameter substitution to remove all text up to and including last "." from
  # right side of string.
  R2_names_array+=("${fastq%%.*}")
done


############ RUN FLEXBAR ############
# Uses parameter substitution (e.g. ${R1_sample_name%%_*})to rm the _R[12]
# Uses NEB adapter file
# --adapter-pair-overlap ON: Recommended by NEB sRNA kit
# --qtrim-threshold 25: Minimum quality
# --qtrim-format i1.8: Sets sequencer as illumina
# --post-trim-length: Trim reads from 3' end to max length
# --target: Sets file naming patterns
# --zip-output GZ: Sets type of compression. GZ = gzip

# Run flexbar on files
echo "Beginning flexbar trimming."
echo ""

time \
for index in "${!fastq_array_R1[@]}"
do
  R1_sample_name="${R1_names_array[index]}"
  R2_sample_name="${R2_names_array[index]}"

  # Begin flexbar trimming
  ${programs_array[flexbar]} \
  --reads ${fastq_array_R1[index]} \
  --reads2 ${fastq_array_R2[index]}  \
  --adapters ${output_dir_top}/${NEB_adapters_fasta} \
  --adapter-pair-overlap ON \
  --qtrim-format i1.8 \
  --qtrim-threshold 25 \
  --post-trim-length ${max_read_length} \
  --threads ${threads} \
  --target "${trimmed_reads_dir}/${R1_sample_name%%_*}.flexbar_trim.${max_read_length}bp" \
  --zip-output GZ
        
    # Move to trimmed directory
    # This is done so checksums file doesn't include excess path
    cd ${trimmed_reads_dir}

    # Generate md5 checksums for newly trimmed files
    {
      md5sum "${R1_sample_name%%_*}.flexbar_trim.${max_read_length}bp_1.fastq.gz"
      md5sum "${R2_sample_name%%_*}.flexbar_trim.${max_read_length}bp_2.fastq.gz"
    } >> "${trimmed_checksums}"
    
    # Change back to to raw reads directory
    cd "${raw_reads_dir}"

done

echo ""
echo "flexbar trimming complete."
echo ""

echo "Trimmed FastQs MD5 checksums:"
echo ""

cat "${trimmed_reads_dir}/${trimmed_checksums}"

############ END FLEXBAR ############

6 FastQC/MultiQC on trimmed reads

# Load bash variables into memory
source .bashvars

############ RUN FASTQC ############

### NOTE: Do NOT quote raw_fastqc_list
# Create array of trimmed FastQs
trimmed_fastqs_array=(${trimmed_reads_dir}/${fastq_pattern})

# Pass array contents to new variable as space-delimited list
trimmed_fastqc_list=$(echo "${trimmed_fastqs_array[*]}")

echo "Beginning FastQC on raw reads..."
echo ""

# Run FastQC
${programs_array[fastqc]} \
--threads ${threads} \
--outdir ${trimmed_fastqc_dir} \
--quiet \
${trimmed_fastqc_list}

echo "FastQC on trimmed reads complete!"
echo ""

############ END FASTQC ############

############ RUN MULTIQC ############
echo "Beginning MultiQC on raw FastQC..."
echo ""

${programs_array[multiqc]} ${trimmed_fastqc_dir} -o ${trimmed_fastqc_dir}

echo ""
echo "MultiQC on trimmed FastQs complete."
echo ""

############ END MULTIQC ############

echo "Removing FastQC zip files."
echo ""
rm ${trimmed_fastqc_dir}/*.zip
echo "FastQC zip files removed."
echo ""

# View directory contents
ls -lh ${trimmed_fastqc_dir}

7 Summary

A quick comparison of raw and trimmed reads to show trimming worked:

  • quality is improved
  • length is 25bp
  • adapters removed
RAW TRIMMED
Raw MultiQC per base sequence quality plot Trimmed MultiQC per base sequence quality plot
Raw MultiQC adapter content plot Trimmed MultiQC adapter content plot

Citations

Andrews, Simon. n.d. FastQC.” Github.
Dodt, Matthias, Johannes T Roehr, Rina Ahmed, and Christoph Dieterich. 2012. FLEXBAR-Flexible Barcode and Adapter Processing for Next-Generation Sequencing Platforms.” Biology 1 (3): 895–905.
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.
Roehr, Johannes T, Christoph Dieterich, and Knut Reinert. 2017. “Flexbar 3.0 - SIMD and Multicore Parallelization.” Bioinformatics 33 (18): 2941–42.
LS0tCnRpdGxlOiAiMDYtUGV2ZS1zUk5Bc2VxLXRyaW1taW5nIgphdXRob3I6ICJTYW0gV2hpdGUiCmRhdGU6ICIyMDIzLTExLTE1IgpvdXRwdXQ6IAogIGJvb2tkb3duOjpodG1sX2RvY3VtZW50MjoKICAgIHRoZW1lOiBjb3NtbwogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgZ2l0aHViX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICBodG1sX2RvY3VtZW50OgogICAgdGhlbWU6IGNvc21vCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKYmlibGlvZ3JhcGh5OiByZWZlcmVuY2VzLmJpYgpsaW5rLWNpdGF0aW9uczogdHJ1ZQotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkocmV0aWN1bGF0ZSkKa25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVjaG8gPSBUUlVFLCAgICAgICAgICMgRGlzcGxheSBjb2RlIGNodW5rcwogIGV2YWwgPSBGQUxTRSwgICAgICAgICMgRXZhbHVhdGUgY29kZSBjaHVua3MKICB3YXJuaW5nID0gRkFMU0UsICAgICAjIEhpZGUgd2FybmluZ3MKICBtZXNzYWdlID0gRkFMU0UsICAgICAjIEhpZGUgbWVzc2FnZXMKICBjb21tZW50ID0gIiIgICAgICAgICAjIFByZXZlbnRzIGFwcGVuZGluZyAnIyMnIHRvIGJlZ2lubmluZyBvZiBsaW5lcyBpbiBjb2RlIG91dHB1dAopCmBgYAoKRmFzdFFDL011bHRpUUMgW0Bld2VsczIwMTY7IEBBbmRyZXdzX3VuZGF0ZWQtbmZdIGFzc2Vzc21lbnQgb2YgcmF3IGFuZCBbZmxleGJhcl0oaHR0cHM6Ly9naXRodWIuY29tL3NlcWFuL2ZsZXhiYXIpLXRyaW1tZWQgW0BEb2R0MjAxMi1ydDsgQFJvZWhyMjAxNy1kcl0gc2VxdWVuY2VzIG9mIEU1ICpQLmV2ZXJtYW5uaSogc1JOQXNlcSBkYXRhIGZyb20gWzIwMjMwNTE1XShodHRwczovL3JvYmVydHNsYWIuZ2l0aHViLmlvL3NhbXMtbm90ZWJvb2svcG9zdHMvMjAyMy8yMDIzLTA1LTE3LURhdGEtTWFuYWdlbWVudC0tLUU1LUNvcmFsLVJOQS1zZXEtYW5kLXNSTkEtc2VxLVJlb3JnYW5pemluZy1hbmQtUmVuYW1pbmcvKS4KCklucHV0czoKCi0gICBzUk5Bc2VxIGd6aXBwZWQgRmFzdFFzIChlLmcuIGAqLmZhc3RxLmd6YCkKCk91dHB1dHM6CgotICAgW2BGYXN0UUNgXShodHRwczovL3d3dy5iaW9pbmZvcm1hdGljcy5iYWJyYWhhbS5hYy51ay9wcm9qZWN0cy9mYXN0cWMvKSBIVE1MIHJlcG9ydHMgZm9yIHJhdyBhbmQgdHJpbW1lZCByZWFkcy4KCi0gICBbYE11bHRpUUNgXShodHRwczovL211bHRpcWMuaW5mby8pIEhUTUwgc3VtbWFyaWVzIG9mIFtgRmFzdFFDYF0oaHR0cHM6Ly93d3cuYmlvaW5mb3JtYXRpY3MuYmFicmFoYW0uYWMudWsvcHJvamVjdHMvZmFzdHFjLykgZm9yIHJhdyBhbmQgdHJpbW1lZCByZWFkcy4KCi0gICBUcmltbWVkIHJlYWRzIHdpdGggZmluYWwgbGVuZ3RoIG9mIDI1YnA6IGAqZmxleGJhcl90cmltLjI1YnAuZmFzdHEuZ3pgCgpMaWJyYXJpZXMgd2VyZSBwcmVwYXJlZCBhbmQgc2VxdWVuY2VkIGJ5IEF6ZW50YToKCi0gICBMaWJyYXJ5IHByZXA6IFtORUIgbmVibmV4dC1zbWFsbC1ybmEtbGlicmFyeS1wcmVwLXNldC1mb3ItaWxsdW1pbmEga2l0XShodHRwczovL3d3dy5uZWIuY29tL2VuLXVzLy0vbWVkaWEvbmVidXMvZmlsZXMvbWFudWFscy9tYW51YWxlNzMwMF9lNzMzMF9lNzU2MF9lNzU4MC5wZGY/cmV2PWQwOTY0YTJlNjM3ODQzYjFhZmNiOWY3ZDY2NmQwN2IyJmhhc2g9N0FDMEIwRUIwMTI3MDhFRkFCMEU0REJFRUFGMTQ0NkEpIChQREYpCgotICAgU2VxdWVuY2luZzogSWxsdW1pbmEgSGlTZXEgNDAwMCwgMTUwYnAgUEUKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyBDcmVhdGUgYSBCYXNoIHZhcmlhYmxlcyBmaWxlCgpUaGlzIGFsbG93cyB1c2FnZSBvZiBCYXNoIHZhcmlhYmxlcyBhY3Jvc3MgUiBNYXJrZG93biBjaHVua3MuCgpgYGB7ciBzYXZlLWJhc2gtdmFyaWFibGVzLXRvLXJ2YXJzLWZpbGUsIGVuZ2luZT0nYmFzaCcsIGV2YWw9VFJVRX0KewplY2hvICIjIyMjIEFzc2lnbiBWYXJpYWJsZXMgIyMjIyIKZWNobyAiIgoKZWNobyAiIyBEYXRhIGRpcmVjdG9yaWVzIgplY2hvICdleHBvcnQgZGVlcF9kaXZlX2Rpcj0vaG9tZS9zaGFyZWQvOFRCX0hERF8wMS9zYW0vZ2l0cmVwb3MvZGVlcC1kaXZlJwplY2hvICdleHBvcnQgb3V0cHV0X2Rpcl90b3A9JHtkZWVwX2RpdmVfZGlyfS9FLVBldmUvb3V0cHV0LzA2LVBldmUtc1JOQXNlcS10cmltbWluZycKZWNobyAnZXhwb3J0IHJhd19mYXN0cWNfZGlyPSR7ZGVlcF9kaXZlX2Rpcn0vRS1QZXZlL291dHB1dC8wNi1QZXZlLXNSTkFzZXEtdHJpbW1pbmcvcmF3LWZhc3RxYycKZWNobyAnZXhwb3J0IHJhd19yZWFkc19kaXI9JHtkZWVwX2RpdmVfZGlyfS9FLVBldmUvZGF0YS8wNi1QZXZlLXNSTkFzZXEtdHJpbW1pbmcvcmF3LXJlYWRzJwplY2hvICdleHBvcnQgcmF3X3JlYWRzX3VybD0iaHR0cHM6Ly9vd2wuZmlzaC53YXNoaW5ndG9uLmVkdS9uaWdodGluZ2FsZXMvUF9ldmVybWFubmkvMzAtODUyNDMwMjM1LyInCmVjaG8gJ2V4cG9ydCB0cmltbWVkX2Zhc3RxY19kaXI9JHtkZWVwX2RpdmVfZGlyfS9FLVBldmUvb3V0cHV0LzA2LVBldmUtc1JOQXNlcS10cmltbWluZy90cmltbWVkLWZhc3RxYycKZWNobyAnZXhwb3J0IHRyaW1tZWRfcmVhZHNfZGlyPSR7ZGVlcF9kaXZlX2Rpcn0vRS1QZXZlL291dHB1dC8wNi1QZXZlLXNSTkFzZXEtdHJpbW1pbmcvdHJpbW1lZC1yZWFkcycKZWNobyAiIgoKZWNobyAiIyBQYXRocyB0byBwcm9ncmFtcyIKZWNobyAnZXhwb3J0IGZhc3RxYz0vaG9tZS9zaGFyZWQvRmFzdFFDLTAuMTIuMS9mYXN0cWMnCmVjaG8gJ2V4cG9ydCBmbGV4YmFyPS9ob21lL3NoYXJlZC9mbGV4YmFyLTMuNS4wLWxpbnV4L2ZsZXhiYXInCmVjaG8gJ2V4cG9ydCBtdWx0aXFjPS9ob21lL3NhbS9wcm9ncmFtcy9tYW1iYWZvcmdlL2Jpbi9tdWx0aXFjJwplY2hvICIiCgoKCmVjaG8gIiMgU2V0IEZhc3RRIGZpbGVuYW1lIHBhdHRlcm5zIgplY2hvICJleHBvcnQgZmFzdHFfcGF0dGVybj0nKi5mYXN0cS5neiciCmVjaG8gImV4cG9ydCBSMV9mYXN0cV9wYXR0ZXJuPScqX1IxXyouZmFzdHEuZ3onIgplY2hvICJleHBvcnQgUjJfZmFzdHFfcGF0dGVybj0nKl9SMl8qLmZhc3RxLmd6JyIKZWNobyAiIgoKZWNobyAiIyBTZXQgbnVtYmVyIG9mIENQVXMgdG8gdXNlIgplY2hvICdleHBvcnQgdGhyZWFkcz00MCcKZWNobyAiIgoKZWNobyAiIyBTZXQgbWF4aW11bSByZWFkIGxlbmd0aCIKZWNobyAnZXhwb3J0IG1heF9yZWFkX2xlbmd0aD0yNScKZWNobyAiIgoKZWNobyAiIyBJbnB1dC9vdXRwdXQgZmlsZXMiCmVjaG8gJ2V4cG9ydCBmYXN0cV9jaGVja3N1bXM9aW5wdXRfZmFzdHFfY2hlY2tzdW1zLm1kNScKZWNobyAnZXhwb3J0IHRyaW1tZWRfY2hlY2tzdW1zPXRyaW1tZWRfZmFzdHFfY2hlY2tzdW1zLm1kNScKZWNobyAnZXhwb3J0IE5FQl9hZGFwdGVyc19mYXN0YT1ORUItYWRhcHRlcnMuZmFzdGEnCmVjaG8gIiIKCmVjaG8gIiMjIE5FQiBuZWJuZXh0LXNtYWxsLXJuYS1saWJyYXJ5LXByZXAtc2V0LWZvci1pbGx1bWluYSBhZGFwdGVycyIKZWNobyAnZXhwb3J0IGZpcnN0X2FkYXB0ZXI9IkFHQVRDR0dBQUdBR0NBQ0FDR1RDVEdBQUNUQ0NBR1RDQUMiJwplY2hvICdleHBvcnQgc2Vjb25kX2FkYXB0ZXI9IkdBVENHVENHR0FDVEdUQUdBQUNUQ1RHQUFDR1RHVEFHQVRDVENHR1RHR1RDR0NDR1RBVENBVFQiJwplY2hvICIiCgplY2hvICIjIyBJbml0aXRhbGl6ZSBhcnJheXMiCmVjaG8gJ2V4cG9ydCBmYXN0cV9hcnJheV9SMT0oKScKZWNobyAnZXhwb3J0IGZhc3RxX2FycmF5X1IyPSgpJwplY2hvICdleHBvcnQgcmF3X2Zhc3Rxc19hcnJheT0oKScKZWNobyAnZXhwb3J0IFIxX25hbWVzX2FycmF5PSgpJwplY2hvICdleHBvcnQgUjJfbmFtZXNfYXJyYXk9KCknCmVjaG8gJ2V4cG9ydCB0cmltbWVkX2Zhc3Rxc19hcnJheT0oKScKZWNobyAiIgoKZWNobyAiIyBQcm9ncmFtcyBhc3NvY2lhdGl2ZSBhcnJheSIKZWNobyAiZGVjbGFyZSAtQSBwcm9ncmFtc19hcnJheSIKZWNobyAicHJvZ3JhbXNfYXJyYXk9KCIKZWNobyAnW2Zhc3RxY109IiR7ZmFzdHFjfSIgXCcKZWNobyAnW211bHRpcWNdPSIke211bHRpcWN9IiBcJwplY2hvICdbZmxleGJhcl09IiR7ZmxleGJhcn0iJwplY2hvICIpIgp9ID4gLmJhc2h2YXJzCgpjYXQgLmJhc2h2YXJzCmBgYAoKIyBEb3dubG9hZCByYXcgc1JOQXNlcSByZWFkcwoKUmVhZHMgYXJlIGRvd25sb2FkZWQgZnJvbSA8aHR0cHM6Ly9vd2wuZmlzaC53YXNoaW5ndG9uLmVkdS9uaWdodGluZ2FsZXMvUF9ldmVybWFubmkvMzAtODUyNDMwMjM1Lz4KClRoZSBgLS1jdXQtZGlycyAzYCBjb21tYW5kIGN1dHMgdGhlIHByZWNlZGluZyBkaXJlY3Rvcnkgc3RydWN0dXJlIChpLmUuIGBuaWdodGluZ2FsZXMvUF9ldmVybWFubmkvMzAtODUyNDMwMjM1L2ApIHNvIHRoYXQgd2UganVzdCBlbmQgdXAgd2l0aCB0aGUgcmVhZHMuCgpgYGB7YmFzaCBkb3dubG9hZC1yYXctcmVhZHMsIGVuZ2luZT0nYmFzaCcsIGV2YWw9VFJVRX0KIyBMb2FkIGJhc2ggdmFyaWFibGVzIGludG8gbWVtb3J5CnNvdXJjZSAuYmFzaHZhcnMKCndnZXQgXAotLWRpcmVjdG9yeS1wcmVmaXggJHtyYXdfcmVhZHNfZGlyfSBcCi0tcmVjdXJzaXZlIFwKLS1uby1jaGVjay1jZXJ0aWZpY2F0ZSBcCi0tY29udGludWUgXAotLWN1dC1kaXJzIDMgXAotLW5vLWhvc3QtZGlyZWN0b3JpZXMgXAotLW5vLXBhcmVudCBcCi0tcXVpZXQgXAotLWFjY2VwdCAic1JOQSosY2hlY2tzdW1zLm1kNSIgJHtyYXdfcmVhZHNfdXJsfQoKbHMgLWxoICIke3Jhd19yZWFkc19kaXJ9IgpgYGAKCiMjIFZlcmlmeSByYXcgcmVhZCBjaGVja3N1bXMKCmBgYHtiYXNoIHZlcmlmeS1yYXctcmVhZC1jaGVja3N1bXMsIGVuZ2luZT0nYmFzaCcsIGV2YWw9VFJVRX0KIyBMb2FkIGJhc2ggdmFyaWFibGVzIGludG8gbWVtb3J5CnNvdXJjZSAuYmFzaHZhcnMKCmNkICIke3Jhd19yZWFkc19kaXJ9IgoKIyBDaGVja3N1bXMgZmlsZSBjb250YWlucyBvdGhlciBmaWxlcywgc28gdGhpcyBqdXN0IGxvb2tzIGZvciB0aGUgc1JOQXNlcSBmaWxlcy4KZ3JlcCAic1JOQSIgY2hlY2tzdW1zLm1kNSB8IG1kNXN1bSAtLWNoZWNrCmBgYAoKIyBDcmVhdGUgYWRhcHRlcnMgRmFzdEEgZm9yIHVzZSB3aXRoIFtmbGV4YmFyXShodHRwczovL2dpdGh1Yi5jb20vc2VxYW4vZmxleGJhcikgdHJpbW1pbmcKCmBgYHtiYXNoIGNyZWF0ZS1GYXN0QS1vZi1hZGFwdGVycywgZW5naW5lPSdiYXNoJywgZXZhbD1UUlVFfQojIExvYWQgYmFzaCB2YXJpYWJsZXMgaW50byBtZW1vcnkKc291cmNlIC5iYXNodmFycwoKZWNobyAiQ3JlYXRpbmcgYWRhcHRlcnMgRmFzdEEuIgplY2hvICIiCmFkYXB0ZXJfY291bnQ9MAoKIyBDaGVjayBmb3IgYWRhcHRlcnMgZmlsZSBmaXJzdAojIFRoZW4gY3JlYXRlIGFkYXB0ZXJzIGZpbGUgaWYgZG9lc24ndCBleGlzdAppZiBbIC1mICIke291dHB1dF9kaXJfdG9wfS8ke05FQl9hZGFwdGVyc19mYXN0YX0iIF07IHRoZW4KICBlY2hvICIke291dHB1dF9kaXJfdG9wfS8ke05FQl9hZGFwdGVyc19mYXN0YX0gYWxyZWFkeSBleGlzdHMuIE5vdGhpbmcgdG8gZG8uIgplbHNlCiAgZm9yIGFkYXB0ZXIgaW4gIiR7Zmlyc3RfYWRhcHRlcn0iICIke3NlY29uZF9hZGFwdGVyfSIKICBkbwogICAgYWRhcHRlcl9jb3VudD0kKChhZGFwdGVyX2NvdW50ICsgMSkpCiAgICBwcmludGYgIj4lc1xuJXNcbiIgImFkYXB0ZXJfJHthZGFwdGVyX2NvdW50fSIgIiR7YWRhcHRlcn0iCiAgZG9uZSA+PiAiJHtvdXRwdXRfZGlyX3RvcH0vJHtORUJfYWRhcHRlcnNfZmFzdGF9IgpmaQoKZWNobyAiIgplY2hvICJBZGFwdGVycyBGYXN0QToiCmVjaG8gIiIKY2F0ICIke291dHB1dF9kaXJfdG9wfS8ke05FQl9hZGFwdGVyc19mYXN0YX0iCmVjaG8gIiIKYGBgCgojIEZhc3RRQy9NdWx0aVFDIG9uIHJhdyByZWFkcwoKYGBge2Jhc2ggcmF3LWZhc3RxYy1tdWx0aXFjLCBlbmdpbmU9J2Jhc2gnLCBldmFsPUZBTFNFfQojIExvYWQgYmFzaCB2YXJpYWJsZXMgaW50byBtZW1vcnkKc291cmNlIC5iYXNodmFycwoKIyMjIyMjIyMjIyMjIFJVTiBGQVNUUUMgIyMjIyMjIyMjIyMjCgoKIyBDcmVhdGUgYXJyYXkgb2YgdHJpbW1lZCBGYXN0UXMKcmF3X2Zhc3Rxc19hcnJheT0oJHtyYXdfcmVhZHNfZGlyfS8ke2Zhc3RxX3BhdHRlcm59KQoKIyBQYXNzIGFycmF5IGNvbnRlbnRzIHRvIG5ldyB2YXJpYWJsZSBhcyBzcGFjZS1kZWxpbWl0ZWQgbGlzdApyYXdfZmFzdHFjX2xpc3Q9JChlY2hvICIke3Jhd19mYXN0cXNfYXJyYXlbKl19IikKCmVjaG8gIkJlZ2lubmluZyBGYXN0UUMgb24gcmF3IHJlYWRzLi4uIgplY2hvICIiCgojIFJ1biBGYXN0UUMKIyMjIE5PVEU6IERvIE5PVCBxdW90ZSByYXdfZmFzdHFjX2xpc3QKJHtwcm9ncmFtc19hcnJheVtmYXN0cWNdfSBcCi0tdGhyZWFkcyAke3RocmVhZHN9IFwKLS1vdXRkaXIgJHtyYXdfZmFzdHFjX2Rpcn0gXAotLXF1aWV0IFwKJHtyYXdfZmFzdHFjX2xpc3R9CgplY2hvICJGYXN0UUMgb24gcmF3IHJlYWRzIGNvbXBsZXRlISIKZWNobyAiIgoKIyMjIyMjIyMjIyMjIEVORCBGQVNUUUMgIyMjIyMjIyMjIyMjCgojIyMjIyMjIyMjIyMgUlVOIE1VTFRJUUMgIyMjIyMjIyMjIyMjCmVjaG8gIkJlZ2lubmluZyBNdWx0aVFDIG9uIHJhdyBGYXN0UUMuLi4iCmVjaG8gIiIKCiR7cHJvZ3JhbXNfYXJyYXlbbXVsdGlxY119ICR7cmF3X2Zhc3RxY19kaXJ9IC1vICR7cmF3X2Zhc3RxY19kaXJ9CgplY2hvICIiCmVjaG8gIk11bHRpUUMgb24gcmF3IEZhc3RRcyBjb21wbGV0ZS4iCmVjaG8gIiIKCiMjIyMjIyMjIyMjIyBFTkQgTVVMVElRQyAjIyMjIyMjIyMjIyMKCmVjaG8gIlJlbW92aW5nIEZhc3RRQyB6aXAgZmlsZXMuIgplY2hvICIiCnJtICR7cmF3X2Zhc3RxY19kaXJ9LyouemlwCmVjaG8gIkZhc3RRQyB6aXAgZmlsZXMgcmVtb3ZlZC4iCmVjaG8gIiIKCiMgVmlldyBkaXJlY3RvcnkgY29udGVudHMKbHMgLWxoICR7cmF3X2Zhc3RxY19kaXJ9CgpgYGAKCiMgVHJpbW1pbmcgd2l0aCBbZmxleGJhcl0oaHR0cHM6Ly9naXRodWIuY29tL3NlcWFuL2ZsZXhiYXIpCgpgYGB7YmFzaCBmbGV4YmFyLXRyaW1taW5nLCBlbmdpbmU9J2Jhc2gnLCBjYWNoZT1UUlVFfQojIExvYWQgYmFzaCB2YXJpYWJsZXMgaW50byBtZW1vcnkKc291cmNlIC5iYXNodmFycwoKIyBDaGFuZ2UgdG8gZGlyZWN0b3J5IHdpdGggcmF3IHJlYWRzCmNkICIke3Jhd19yZWFkc19kaXJ9IgoKIyBDcmVhdGUgYXJyYXlzIG9mIEZhc3RRIFIxIGZpbGVzIGFuZCBzYW1wbGUgbmFtZXMKIyBEbyBOT1QgcXVvdGUgUjFfZmFzdHFfcGF0dGVybiB2YXJpYWJsZQpmb3IgZmFzdHEgaW4gJHtSMV9mYXN0cV9wYXR0ZXJufQpkbwogIGZhc3RxX2FycmF5X1IxKz0oIiR7ZmFzdHF9IikKCiAgIyBVc2UgcGFyYW1ldGVyIHN1YnN0aXR1dGlvbiB0byByZW1vdmUgYWxsIHRleHQgdXAgdG8gYW5kIGluY2x1ZGluZyBsYXN0ICIuIiBmcm9tCiAgIyByaWdodCBzaWRlIG9mIHN0cmluZy4KICBSMV9uYW1lc19hcnJheSs9KCIke2Zhc3RxJSUuKn0iKQpkb25lCgojIENyZWF0ZSBhcnJheSBvZiBGYXN0USBSMiBmaWxlcwojIERvIE5PVCBxdW90ZSBSMl9mYXN0cV9wYXR0ZXJuIHZhcmlhYmxlCmZvciBmYXN0cSBpbiAke1IyX2Zhc3RxX3BhdHRlcm59CmRvCiAgZmFzdHFfYXJyYXlfUjIrPSgiJHtmYXN0cX0iKQoKICAjIFVzZSBwYXJhbWV0ZXIgc3Vic3RpdHV0aW9uIHRvIHJlbW92ZSBhbGwgdGV4dCB1cCB0byBhbmQgaW5jbHVkaW5nIGxhc3QgIi4iIGZyb20KICAjIHJpZ2h0IHNpZGUgb2Ygc3RyaW5nLgogIFIyX25hbWVzX2FycmF5Kz0oIiR7ZmFzdHElJS4qfSIpCmRvbmUKCgojIyMjIyMjIyMjIyMgUlVOIEZMRVhCQVIgIyMjIyMjIyMjIyMjCiMgVXNlcyBwYXJhbWV0ZXIgc3Vic3RpdHV0aW9uIChlLmcuICR7UjFfc2FtcGxlX25hbWUlJV8qfSl0byBybSB0aGUgX1JbMTJdCiMgVXNlcyBORUIgYWRhcHRlciBmaWxlCiMgLS1hZGFwdGVyLXBhaXItb3ZlcmxhcCBPTjogUmVjb21tZW5kZWQgYnkgTkVCIHNSTkEga2l0CiMgLS1xdHJpbS10aHJlc2hvbGQgMjU6IE1pbmltdW0gcXVhbGl0eQojIC0tcXRyaW0tZm9ybWF0IGkxLjg6IFNldHMgc2VxdWVuY2VyIGFzIGlsbHVtaW5hCiMgLS1wb3N0LXRyaW0tbGVuZ3RoOiBUcmltIHJlYWRzIGZyb20gMycgZW5kIHRvIG1heCBsZW5ndGgKIyAtLXRhcmdldDogU2V0cyBmaWxlIG5hbWluZyBwYXR0ZXJucwojIC0temlwLW91dHB1dCBHWjogU2V0cyB0eXBlIG9mIGNvbXByZXNzaW9uLiBHWiA9IGd6aXAKCiMgUnVuIGZsZXhiYXIgb24gZmlsZXMKZWNobyAiQmVnaW5uaW5nIGZsZXhiYXIgdHJpbW1pbmcuIgplY2hvICIiCgp0aW1lIFwKZm9yIGluZGV4IGluICIkeyFmYXN0cV9hcnJheV9SMVtAXX0iCmRvCiAgUjFfc2FtcGxlX25hbWU9IiR7UjFfbmFtZXNfYXJyYXlbaW5kZXhdfSIKICBSMl9zYW1wbGVfbmFtZT0iJHtSMl9uYW1lc19hcnJheVtpbmRleF19IgoKICAjIEJlZ2luIGZsZXhiYXIgdHJpbW1pbmcKICAke3Byb2dyYW1zX2FycmF5W2ZsZXhiYXJdfSBcCiAgLS1yZWFkcyAke2Zhc3RxX2FycmF5X1IxW2luZGV4XX0gXAogIC0tcmVhZHMyICR7ZmFzdHFfYXJyYXlfUjJbaW5kZXhdfSAgXAogIC0tYWRhcHRlcnMgJHtvdXRwdXRfZGlyX3RvcH0vJHtORUJfYWRhcHRlcnNfZmFzdGF9IFwKICAtLWFkYXB0ZXItcGFpci1vdmVybGFwIE9OIFwKICAtLXF0cmltLWZvcm1hdCBpMS44IFwKICAtLXF0cmltLXRocmVzaG9sZCAyNSBcCiAgLS1wb3N0LXRyaW0tbGVuZ3RoICR7bWF4X3JlYWRfbGVuZ3RofSBcCiAgLS10aHJlYWRzICR7dGhyZWFkc30gXAogIC0tdGFyZ2V0ICIke3RyaW1tZWRfcmVhZHNfZGlyfS8ke1IxX3NhbXBsZV9uYW1lJSVfKn0uZmxleGJhcl90cmltLiR7bWF4X3JlYWRfbGVuZ3RofWJwIiBcCiAgLS16aXAtb3V0cHV0IEdaCiAgICAgICAgCiAgICAjIE1vdmUgdG8gdHJpbW1lZCBkaXJlY3RvcnkKICAgICMgVGhpcyBpcyBkb25lIHNvIGNoZWNrc3VtcyBmaWxlIGRvZXNuJ3QgaW5jbHVkZSBleGNlc3MgcGF0aAogICAgY2QgJHt0cmltbWVkX3JlYWRzX2Rpcn0KCiAgICAjIEdlbmVyYXRlIG1kNSBjaGVja3N1bXMgZm9yIG5ld2x5IHRyaW1tZWQgZmlsZXMKICAgIHsKICAgICAgbWQ1c3VtICIke1IxX3NhbXBsZV9uYW1lJSVfKn0uZmxleGJhcl90cmltLiR7bWF4X3JlYWRfbGVuZ3RofWJwXzEuZmFzdHEuZ3oiCiAgICAgIG1kNXN1bSAiJHtSMl9zYW1wbGVfbmFtZSUlXyp9LmZsZXhiYXJfdHJpbS4ke21heF9yZWFkX2xlbmd0aH1icF8yLmZhc3RxLmd6IgogICAgfSA+PiAiJHt0cmltbWVkX2NoZWNrc3Vtc30iCiAgICAKICAgICMgQ2hhbmdlIGJhY2sgdG8gdG8gcmF3IHJlYWRzIGRpcmVjdG9yeQogICAgY2QgIiR7cmF3X3JlYWRzX2Rpcn0iCgpkb25lCgplY2hvICIiCmVjaG8gImZsZXhiYXIgdHJpbW1pbmcgY29tcGxldGUuIgplY2hvICIiCgplY2hvICJUcmltbWVkIEZhc3RRcyBNRDUgY2hlY2tzdW1zOiIKZWNobyAiIgoKY2F0ICIke3RyaW1tZWRfcmVhZHNfZGlyfS8ke3RyaW1tZWRfY2hlY2tzdW1zfSIKCiMjIyMjIyMjIyMjIyBFTkQgRkxFWEJBUiAjIyMjIyMjIyMjIyMKCmBgYAoKIyBGYXN0UUMvTXVsdGlRQyBvbiB0cmltbWVkIHJlYWRzCgpgYGB7YmFzaCBGYXN0UUMtTXVsdGlRQy10cmltbWVkLXJlYWRzLCBlbmdpbmU9J2Jhc2gnLCBldmFsPUZBTFNFfQojIExvYWQgYmFzaCB2YXJpYWJsZXMgaW50byBtZW1vcnkKc291cmNlIC5iYXNodmFycwoKIyMjIyMjIyMjIyMjIFJVTiBGQVNUUUMgIyMjIyMjIyMjIyMjCgojIyMgTk9URTogRG8gTk9UIHF1b3RlIHJhd19mYXN0cWNfbGlzdAojIENyZWF0ZSBhcnJheSBvZiB0cmltbWVkIEZhc3RRcwp0cmltbWVkX2Zhc3Rxc19hcnJheT0oJHt0cmltbWVkX3JlYWRzX2Rpcn0vJHtmYXN0cV9wYXR0ZXJufSkKCiMgUGFzcyBhcnJheSBjb250ZW50cyB0byBuZXcgdmFyaWFibGUgYXMgc3BhY2UtZGVsaW1pdGVkIGxpc3QKdHJpbW1lZF9mYXN0cWNfbGlzdD0kKGVjaG8gIiR7dHJpbW1lZF9mYXN0cXNfYXJyYXlbKl19IikKCmVjaG8gIkJlZ2lubmluZyBGYXN0UUMgb24gcmF3IHJlYWRzLi4uIgplY2hvICIiCgojIFJ1biBGYXN0UUMKJHtwcm9ncmFtc19hcnJheVtmYXN0cWNdfSBcCi0tdGhyZWFkcyAke3RocmVhZHN9IFwKLS1vdXRkaXIgJHt0cmltbWVkX2Zhc3RxY19kaXJ9IFwKLS1xdWlldCBcCiR7dHJpbW1lZF9mYXN0cWNfbGlzdH0KCmVjaG8gIkZhc3RRQyBvbiB0cmltbWVkIHJlYWRzIGNvbXBsZXRlISIKZWNobyAiIgoKIyMjIyMjIyMjIyMjIEVORCBGQVNUUUMgIyMjIyMjIyMjIyMjCgojIyMjIyMjIyMjIyMgUlVOIE1VTFRJUUMgIyMjIyMjIyMjIyMjCmVjaG8gIkJlZ2lubmluZyBNdWx0aVFDIG9uIHJhdyBGYXN0UUMuLi4iCmVjaG8gIiIKCiR7cHJvZ3JhbXNfYXJyYXlbbXVsdGlxY119ICR7dHJpbW1lZF9mYXN0cWNfZGlyfSAtbyAke3RyaW1tZWRfZmFzdHFjX2Rpcn0KCmVjaG8gIiIKZWNobyAiTXVsdGlRQyBvbiB0cmltbWVkIEZhc3RRcyBjb21wbGV0ZS4iCmVjaG8gIiIKCiMjIyMjIyMjIyMjIyBFTkQgTVVMVElRQyAjIyMjIyMjIyMjIyMKCmVjaG8gIlJlbW92aW5nIEZhc3RRQyB6aXAgZmlsZXMuIgplY2hvICIiCnJtICR7dHJpbW1lZF9mYXN0cWNfZGlyfS8qLnppcAplY2hvICJGYXN0UUMgemlwIGZpbGVzIHJlbW92ZWQuIgplY2hvICIiCgojIFZpZXcgZGlyZWN0b3J5IGNvbnRlbnRzCmxzIC1saCAke3RyaW1tZWRfZmFzdHFjX2Rpcn0KCmBgYAoKIyBTdW1tYXJ5CgpBIHF1aWNrIGNvbXBhcmlzb24gb2YgcmF3IGFuZCB0cmltbWVkIHJlYWRzIHRvIHNob3cgdHJpbW1pbmcgd29ya2VkOgoKLSAgIHF1YWxpdHkgaXMgaW1wcm92ZWQKLSAgIGxlbmd0aCBpcyAyNWJwCi0gICBhZGFwdGVycyByZW1vdmVkCgp8IFJBVyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgVFJJTU1FRCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAp8ICFbUmF3IE11bHRpUUMgcGVyIGJhc2Ugc2VxdWVuY2UgcXVhbGl0eSBwbG90XShodHRwczovL2dpdGh1Yi5jb20vdXJvbC1lNS9kZWVwLWRpdmUvYmxvYi9tYWluL0UtUGV2ZS9vdXRwdXQvMDYtUGV2ZS1zUk5Bc2VxLXRyaW1taW5nL3Jhdy1mYXN0cWMvZmFzdHFjX3Blcl9iYXNlX3NlcXVlbmNlX3F1YWxpdHlfcGxvdC5wbmc/cmF3PXRydWUpIHwgIVtUcmltbWVkIE11bHRpUUMgcGVyIGJhc2Ugc2VxdWVuY2UgcXVhbGl0eSBwbG90XShodHRwczovL2dpdGh1Yi5jb20vdXJvbC1lNS9kZWVwLWRpdmUvYmxvYi9tYWluL0UtUGV2ZS9vdXRwdXQvMDYtUGV2ZS1zUk5Bc2VxLXRyaW1taW5nL3RyaW1tZWQtZmFzdHFjL2Zhc3RxY19wZXJfYmFzZV9zZXF1ZW5jZV9xdWFsaXR5X3Bsb3QucG5nP3Jhdz10cnVlKSB8CnwgIVtSYXcgTXVsdGlRQyBhZGFwdGVyIGNvbnRlbnQgcGxvdF0oaHR0cHM6Ly9naXRodWIuY29tL3Vyb2wtZTUvZGVlcC1kaXZlL2Jsb2IvbWFpbi9FLVBldmUvb3V0cHV0LzA2LVBldmUtc1JOQXNlcS10cmltbWluZy9yYXctZmFzdHFjL2Zhc3RxY19hZGFwdGVyX2NvbnRlbnRfcGxvdC5wbmc/cmF3PXRydWUpICAgICAgICAgICAgICAgICAgICAgfCAhW1RyaW1tZWQgTXVsdGlRQyBhZGFwdGVyIGNvbnRlbnQgcGxvdF0oaHR0cHM6Ly9naXRodWIuY29tL3Vyb2wtZTUvZGVlcC1kaXZlL2Jsb2IvbWFpbi9FLVBldmUvb3V0cHV0LzA2LVBldmUtc1JOQXNlcS10cmltbWluZy90cmltbWVkLWZhc3RxYy9mYXN0cWNfYWRhcHRlcl9jb250ZW50X3Bsb3QucG5nP3Jhdz10cnVlKSAgICAgICAgICAgICAgICAgICAgIHwKCiMgQ2l0YXRpb25zCg==