1 Copy reads to the working tree

I prefer to concatenate the multiple sequence files into a single file for each the forward(R1) and reverse(R2) sequences. Interestingly, for this data I decided to handle all steps in one shot with a single script which is invoked with 1 argument for each sample. The text of that script ‘copy_process.sh’ follows:

cd preprocessing
for i in $(/bin/ls hpgl*); do
  ./copy_process.sh ${i}
done

## startdir=$(pwd)
## for i in "$@"; do
##   cd $startdir
##   cyoa --task rnaseq --method copyraw --raw_dir "/cbcb/lab/nelsayed/raw_data/ade" --hpgl ${i}
##   cd $i
##   inputs="${i}_forward.fastq.gz:${i}_reverse.fastq.gz"
##   trimmed="${i}_forward-trimmed.fastq.gz:${i}_reverse-trimmed.fastq.gz"
##   cyoa --task rnaseq --method fastqc --input ${inputs}
##   cyoa --task rnaseq --method trimomatic --input ${inputs}
##   trim_id=$(cat last_job.txt)
##   cyoa --task rnaseq --method tophat --input ${trimmed} -s lpanamensis --depends "${trim_id}"
##   lp_id=$(cat last_job.txt)
##   cyoa --task rnaseq --method tophat --input ${trimmed} -s lbraziliensis --depends "${trim_id}"
##   lb_id=$(cat last_job.txt)
##   cyoa --task rnaseq --method tophat --input ${trimmed} -s hsapiens --depends "${trim_id}"
##   hs_id=$(cat last_job.txt)
##   rm last_job.txt
##   cd $startdir
## done

This process is therefore done in 6 steps: 1. Copy the raw data from Najib’s raw_data directory 2. Perform fastqc on the raw reads 3. Perform trimomatic 4. Align with bowtie2 the L.braziliensis genome

2 Fastqc

The cyoa tool writes out a script which looks like the following:

## This FastQC run is against rnaseq data and is used for
## an initial estimation of the overall sequencing quality.
mkdir -p outputs/fastqc && \
  fastqc --extract -o outputs/fastqc hpgl0241_forward-trimmed.fastq hpgl0241_reverse-trimmed.fastq \
  2>outputs/fastqc.out 1>&2

A relevant plot from fastqc is (from sample hpgl0241):

Forward qualities: forward quality Reverse qualities: reverse quality

3 Trimomatic

The trimomatic script looks like: It is worth noting that in some cases, the illumina adapter removal results in a java exception. If that happens, rather than lose the data I made my cyoa script re-invoke trimomatic without the illumina clipping. In addition, if things need to be redone, then the sequences may in fact have been moved into the sequences/ directory and compressed with xz -9e, thus the if [[]] at the beginning testing for those files.

## Trimomatic_Pairwise: In case a trimming needs to be redone...
if [[ ! -r "axa1_forward.fastq.gz" ]]; then
  if [[ -r "sequences/axa1_forward.fastq.xz" ]]; then
    mv sequences/axa1_forward.fastq.xz . && pxz -d axa1_forward.fastq.xz && pigz axa1_forward.fastq && mv sequences/axa1_reverse.fastq.xz . &&
 pxz -d axa1_reverse.fastq.xz && pigz axa1_reverse.fastq
  else
    echo "Missing files. Did not find axa1_forward.fastq.gz nor sequences/axa1_forward.fastq.xz"
    exit 1
  fi
fi
trimomatic PE -threads 1 -phred33 axa1_forward.fastq.gz axa1_reverse.fastq.gz axa1_forward-trimmed_paired.fastq.gz axa1_forward-trimmed_unpair
ed.fastq.gz axa1_reverse-trimmed_paired.fastq.gz axa1_reverse-trimmed_unpaired.fastq.gz ILLUMINACLIP:/cbcbhomes/abelew/libraries/adapters.fa:2:20:4 SL
IDINGWINDOW:4:25 1>outputs/axa1-trimomatic.out 2>&1
excepted=$(grep "Exception" outputs/axa1-trimomatic.out)
## The following is in case the illumina clipping fails, which it does if this has already been run I think.
if [[ "${excepted}" != "" ]]; then
  trimomatic PE -threads 1 -phred33 axa1_forward.fastq.gz axa1_reverse.fastq.gz axa1_forward-trimmed_paired.fastq.gz axa1_forward-trimmed_unpa
ired.fastq.gz axa1_reverse-trimmed_paired.fastq.gz axa1_reverse-trimmed_unpaired.fastq.gz SLIDINGWINDOW:4:25 1>>outputs/axa1-trimomatic.out 2>&1
fi
sleep 10
mv axa1_forward-trimmed_paired.fastq.gz axa1_forward-trimmed.fastq.gz && mv axa1_reverse-trimmed_paired.fastq.gz axa1_reverse-trimmed.fastq.gz

4 Bowtie 2

The end result should be a set of files with trimmed, paired sequences separated from unpaired sequences.

5 Tophat

The tophat process is actually a couple of steps rolled into one, the trimmed/paired reads are fed to tophat, then the accepted_hits.bam is tested for properly paired reads and those reads are separated into accepted_paired.bam. These 2 bam files are sorted and indexed, and finally passed to htseq. Thus the tophat scripts look like:

These scripts however, do not include the additional processing step which split the accepted_hits.bam into accepted_paired.bam I am not sure why, but these scripts are missing the following step which was performed but not properly logged:

if [ -r "${tophat_dir}/accepted_hits.bam" ]; then
  samtools view -b -f 2 ${tophat_dir}/accepted_hits.bam > ${tophat_dir}/accepted_paired.bam && samtools index ${tophat_dir}/accepted_paired.bam
fi

I know this step was performed, because the files accepted_paired.bam exists for each directory, but the option -f 2 says that the ‘2’ flag must be set, which is the flag for an alignment which is paired.

## scripts/th_lbraziliensis-axa1.sh
mkdir -p outputs/tophat_lbraziliensis && tophat  -g 1  \
  -G /cbcbhomes/abelew/libraries/genome/lbraziliensis.gff \
  --b2-very-sensitive -p 4 -o outputs/tophat_lbraziliensis \
/cbcbhomes/abelew/libraries/genome/indexes/lbraziliensis \
  axa1_forward-trimmed.fastq.gz axa1_reverse-trimmed.fastq.gz && \
  samtools sort -l 9 -n outputs/tophat_lbraziliensis/accepted_hits.bam outputs/tophat_lbraziliensis/accepted_sorted && \
  mv outputs/tophat_lbraziliensis/accepted_sorted.bam outputs/tophat_lbraziliensis/accepted_hits.bam && \
  samtools index outputs/tophat_lbraziliensis/accepted_hits.bam && \
  samtools sort -l 9 -n outputs/tophat_lbraziliensis/unmapped.bam outputs/tophat_lbraziliensis/unmapped_sorted && \
  mv outputs/tophat_lbraziliensis/unmapped_sorted.bam outputs/tophat_lbraziliensis/unmapped.bam && \
  samtools index outputs/tophat_lbraziliensis/unmapped.bam

6 Run htseq

The above scripts create sorted accepted_hits.bam files, I think that I manually made the accepted_paired.bam files and added those steps to the cyoa script post-facto, but the end result is the same and so I needed to run htseq on both:

## scripts/th_lbraziliensis-hpgl0241.sh
## Counting the number of hits in outputs/tophat_lbraziliensis/accepted_hits.bam for each feature found in /cbcbhomes/abelew/libraries/genome/lbraziliensis.gff
## Is this stranded? no.  The defaults of htseq are:
##  --order=name --idattr=gene_id --minaqual=10 --type=exon --stranded=yes --mode=union
htseq-count -q -f bam -s no  -i ID  \
  outputs/tophat_lbraziliensis/accepted_hits.bam /cbcbhomes/abelew/libraries/genome/lbraziliensis.gff \
  1>outputs/tophat_lbraziliensis/accepted_hits.count 2>outputs/tophat_lbraziliensis/accepted_hits.error && \
    xz -9e outputs/tophat_lbraziliensis/accepted_hits.count
## I am not going to belabor the point and print the htseq commands for all species.
if (!isTRUE(get0("skip_load"))) {
  pander::pander(sessionInfo())
  message(paste0("This is hpgltools commit: ", get_git_commit()))
  this_save <- paste0(gsub(pattern="\\.Rmd", replace="", x=rmd_file), "-v", ver, ".rda.xz")
  message(paste0("Saving to ", this_save))
  tmp <- sm(saveme(filename=this_save))
}
## If you wish to reproduce this exact build of hpgltools, invoke the following:
## > git clone http://github.com/abelew/hpgltools.git
## > git reset 2a0661d6e37f8a3d8831eb3bbd6347c0d9c4b3b7
## R> packrat::restore()
## This is hpgltools commit: Thu Mar 29 16:59:07 2018 -0400: 2a0661d6e37f8a3d8831eb3bbd6347c0d9c4b3b7
## Saving to index-v20170201.rda.xz
LS0tCnRpdGxlOiAiTC5icmF6aWxpZW5zaXMgMjAxNzogUk5BU2VxIHNhbXBsZSBwcmVwcm9jZXNzaW5nLiIKYXV0aG9yOiAiYXRiIGFiZWxld0BnbWFpbC5jb20iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogaHRtbF9kb2N1bWVudDoKICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgY29kZV9mb2xkaW5nOiBzaG93CiAgZmlnX2NhcHRpb246IHRydWUKICBmaWdfaGVpZ2h0OiA3CiAgZmlnX3dpZHRoOiA3CiAgaGlnaGxpZ2h0OiBkZWZhdWx0CiAga2VlcF9tZDogZmFsc2UKICBtb2RlOiBzZWxmY29udGFpbmVkCiAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgc2VsZl9jb250YWluZWQ6IHRydWUKICB0aGVtZTogcmVhZGFibGUKICB0b2M6IHRydWUKICB0b2NfZmxvYXQ6CiAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQotLS0KCjxzdHlsZT4KICBib2R5IC5tYWluLWNvbnRhaW5lciB7CiAgICBtYXgtd2lkdGg6IDE2MDBweDsKICB9Cjwvc3R5bGU+CgpgYGB7ciBvcHRpb25zLCBpbmNsdWRlPUZBTFNFfQppZiAoIWlzVFJVRShnZXQwKCJza2lwX2xvYWQiKSkpIHsKICBsaWJyYXJ5KGhwZ2x0b29scykKICB0dCA8LSBkZXZ0b29sczo6bG9hZF9hbGwoIn4vaHBnbHRvb2xzIikKICBrbml0cjo6b3B0c19rbml0JHNldChwcm9ncmVzcz1UUlVFLAogICAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2U9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgICB3aWR0aD05MCwKICAgICAgICAgICAgICAgICAgICAgICBlY2hvPVRSVUUpCiAga25pdHI6Om9wdHNfY2h1bmskc2V0KGVycm9yPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgIGZpZy53aWR0aD04LAogICAgICAgICAgICAgICAgICAgICAgICBmaWcuaGVpZ2h0PTgsCiAgICAgICAgICAgICAgICAgICAgICAgIGRwaT05NikKICBvbGRfb3B0aW9ucyA8LSBvcHRpb25zKGRpZ2l0cz00LAogICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgIGtuaXRyLmR1cGxpY2F0ZS5sYWJlbD0iYWxsb3ciKQogIGdncGxvdDI6OnRoZW1lX3NldChnZ3Bsb3QyOjp0aGVtZV9idyhiYXNlX3NpemU9MTApKQogIHZlciA8LSAiMjAxNzAyMDEiCiAgcHJldmlvdXNfZmlsZSA8LSAiaW5kZXguUm1kIgoKICB0bXAgPC0gdHJ5KHNtKGxvYWRtZShmaWxlbmFtZT1wYXN0ZTAoZ3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSIiLCB4PXByZXZpb3VzX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikpKSkKICBybWRfZmlsZSA8LSAiaW5kZXguUm1kIgp9CmBgYAoKIyBDb3B5IHJlYWRzIHRvIHRoZSB3b3JraW5nIHRyZWUKCkkgcHJlZmVyIHRvIGNvbmNhdGVuYXRlIHRoZSBtdWx0aXBsZSBzZXF1ZW5jZSBmaWxlcyBpbnRvIGEgc2luZ2xlIGZpbGUgZm9yIGVhY2ggdGhlIGZvcndhcmQoUjEpIGFuZApyZXZlcnNlKFIyKSBzZXF1ZW5jZXMuICBJbnRlcmVzdGluZ2x5LCBmb3IgdGhpcyBkYXRhIEkgZGVjaWRlZCB0byBoYW5kbGUgYWxsIHN0ZXBzIGluIG9uZSBzaG90IHdpdGgKYSBzaW5nbGUgc2NyaXB0IHdoaWNoIGlzIGludm9rZWQgd2l0aCAxIGFyZ3VtZW50IGZvciBlYWNoIHNhbXBsZS4gIFRoZSB0ZXh0IG9mIHRoYXQgc2NyaXB0Cidjb3B5X3Byb2Nlc3Muc2gnIGZvbGxvd3M6CgpgYGB7YmFzaCBta2RpcnMsIGV2YWw9RkFMU0V9CmNkIHByZXByb2Nlc3NpbmcKZm9yIGkgaW4gJCgvYmluL2xzIGhwZ2wqKTsgZG8KICAuL2NvcHlfcHJvY2Vzcy5zaCAke2l9CmRvbmUKCiMjIHN0YXJ0ZGlyPSQocHdkKQojIyBmb3IgaSBpbiAiJEAiOyBkbwojIyAgIGNkICRzdGFydGRpcgojIyAgIGN5b2EgLS10YXNrIHJuYXNlcSAtLW1ldGhvZCBjb3B5cmF3IC0tcmF3X2RpciAiL2NiY2IvbGFiL25lbHNheWVkL3Jhd19kYXRhL2FkZSIgLS1ocGdsICR7aX0KIyMgICBjZCAkaQojIyAgIGlucHV0cz0iJHtpfV9mb3J3YXJkLmZhc3RxLmd6OiR7aX1fcmV2ZXJzZS5mYXN0cS5neiIKIyMgICB0cmltbWVkPSIke2l9X2ZvcndhcmQtdHJpbW1lZC5mYXN0cS5nejoke2l9X3JldmVyc2UtdHJpbW1lZC5mYXN0cS5neiIKIyMgICBjeW9hIC0tdGFzayBybmFzZXEgLS1tZXRob2QgZmFzdHFjIC0taW5wdXQgJHtpbnB1dHN9CiMjICAgY3lvYSAtLXRhc2sgcm5hc2VxIC0tbWV0aG9kIHRyaW1vbWF0aWMgLS1pbnB1dCAke2lucHV0c30KIyMgICB0cmltX2lkPSQoY2F0IGxhc3Rfam9iLnR4dCkKIyMgICBjeW9hIC0tdGFzayBybmFzZXEgLS1tZXRob2QgdG9waGF0IC0taW5wdXQgJHt0cmltbWVkfSAtcyBscGFuYW1lbnNpcyAtLWRlcGVuZHMgIiR7dHJpbV9pZH0iCiMjICAgbHBfaWQ9JChjYXQgbGFzdF9qb2IudHh0KQojIyAgIGN5b2EgLS10YXNrIHJuYXNlcSAtLW1ldGhvZCB0b3BoYXQgLS1pbnB1dCAke3RyaW1tZWR9IC1zIGxicmF6aWxpZW5zaXMgLS1kZXBlbmRzICIke3RyaW1faWR9IgojIyAgIGxiX2lkPSQoY2F0IGxhc3Rfam9iLnR4dCkKIyMgICBjeW9hIC0tdGFzayBybmFzZXEgLS1tZXRob2QgdG9waGF0IC0taW5wdXQgJHt0cmltbWVkfSAtcyBoc2FwaWVucyAtLWRlcGVuZHMgIiR7dHJpbV9pZH0iCiMjICAgaHNfaWQ9JChjYXQgbGFzdF9qb2IudHh0KQojIyAgIHJtIGxhc3Rfam9iLnR4dAojIyAgIGNkICRzdGFydGRpcgojIyBkb25lCmBgYAoKVGhpcyBwcm9jZXNzIGlzIHRoZXJlZm9yZSBkb25lIGluIDYgc3RlcHM6CjEuICBDb3B5IHRoZSByYXcgZGF0YSBmcm9tIE5hamliJ3MgcmF3X2RhdGEgZGlyZWN0b3J5CjIuICBQZXJmb3JtIGZhc3RxYyBvbiB0aGUgcmF3IHJlYWRzCjMuICBQZXJmb3JtIHRyaW1vbWF0aWMKNC4gIEFsaWduIHdpdGggYm93dGllMiB0aGUgTC5icmF6aWxpZW5zaXMgZ2Vub21lCgojIEZhc3RxYwoKVGhlIGN5b2EgdG9vbCB3cml0ZXMgb3V0IGEgc2NyaXB0IHdoaWNoIGxvb2tzIGxpa2UgdGhlIGZvbGxvd2luZzoKCmBgYHtiYXNoIGZhc3RxY19zY3JpcHQsIGV2YWw9RkFMU0V9CiMjIFRoaXMgRmFzdFFDIHJ1biBpcyBhZ2FpbnN0IHJuYXNlcSBkYXRhIGFuZCBpcyB1c2VkIGZvcgojIyBhbiBpbml0aWFsIGVzdGltYXRpb24gb2YgdGhlIG92ZXJhbGwgc2VxdWVuY2luZyBxdWFsaXR5Lgpta2RpciAtcCBvdXRwdXRzL2Zhc3RxYyAmJiBcCiAgZmFzdHFjIC0tZXh0cmFjdCAtbyBvdXRwdXRzL2Zhc3RxYyBocGdsMDI0MV9mb3J3YXJkLXRyaW1tZWQuZmFzdHEgaHBnbDAyNDFfcmV2ZXJzZS10cmltbWVkLmZhc3RxIFwKICAyPm91dHB1dHMvZmFzdHFjLm91dCAxPiYyCmBgYAoKQSByZWxldmFudCBwbG90IGZyb20gZmFzdHFjIGlzIChmcm9tIHNhbXBsZSBocGdsMDI0MSk6CgpGb3J3YXJkIHF1YWxpdGllczoKIVtmb3J3YXJkIHF1YWxpdHldKHByZXByb2Nlc3NpbmcvQVhBMi9wcm9jZXNzZWQvb3V0cHV0cy9mYXN0cWMvYXhhMl9mb3J3YXJkLXRyaW1tZWRfZmFzdHFjL0ltYWdlcy9wZXJfYmFzZV9xdWFsaXR5LnBuZykKUmV2ZXJzZSBxdWFsaXRpZXM6CiFbcmV2ZXJzZSBxdWFsaXR5XShwcmVwcm9jZXNzaW5nL0FYQTIvcHJvY2Vzc2VkL291dHB1dHMvZmFzdHFjL2F4YTJfcmV2ZXJzZS10cmltbWVkX2Zhc3RxYy9JbWFnZXMvcGVyX2Jhc2VfcXVhbGl0eS5wbmcpCgojIFRyaW1vbWF0aWMKClRoZSB0cmltb21hdGljIHNjcmlwdCBsb29rcyBsaWtlOgpJdCBpcyB3b3J0aCBub3RpbmcgdGhhdCBpbiBzb21lIGNhc2VzLCB0aGUgaWxsdW1pbmEgYWRhcHRlciByZW1vdmFsIHJlc3VsdHMgaW4gYSBqYXZhIGV4Y2VwdGlvbi4gIElmCnRoYXQgaGFwcGVucywgcmF0aGVyIHRoYW4gbG9zZSB0aGUgZGF0YSBJIG1hZGUgbXkgY3lvYSBzY3JpcHQgcmUtaW52b2tlIHRyaW1vbWF0aWMgd2l0aG91dCB0aGUKaWxsdW1pbmEgY2xpcHBpbmcuICBJbiBhZGRpdGlvbiwgaWYgdGhpbmdzIG5lZWQgdG8gYmUgcmVkb25lLCB0aGVuIHRoZSBzZXF1ZW5jZXMgbWF5IGluIGZhY3QgaGF2ZQpiZWVuIG1vdmVkIGludG8gdGhlIHNlcXVlbmNlcy8gZGlyZWN0b3J5IGFuZCBjb21wcmVzc2VkIHdpdGggeHogLTllLCB0aHVzIHRoZSBpZiBbW11dIGF0IHRoZQpiZWdpbm5pbmcgdGVzdGluZyBmb3IgdGhvc2UgZmlsZXMuCgpgYGB7YmFzaCB0cmltbW9tYXRpY19zY3JpcHQsIGV2YWw9RkFMU0V9CiMjIFRyaW1vbWF0aWNfUGFpcndpc2U6IEluIGNhc2UgYSB0cmltbWluZyBuZWVkcyB0byBiZSByZWRvbmUuLi4KaWYgW1sgISAtciAiYXhhMV9mb3J3YXJkLmZhc3RxLmd6IiBdXTsgdGhlbgogIGlmIFtbIC1yICJzZXF1ZW5jZXMvYXhhMV9mb3J3YXJkLmZhc3RxLnh6IiBdXTsgdGhlbgogICAgbXYgc2VxdWVuY2VzL2F4YTFfZm9yd2FyZC5mYXN0cS54eiAuICYmIHB4eiAtZCBheGExX2ZvcndhcmQuZmFzdHEueHogJiYgcGlneiBheGExX2ZvcndhcmQuZmFzdHEgJiYgbXYgc2VxdWVuY2VzL2F4YTFfcmV2ZXJzZS5mYXN0cS54eiAuICYmCiBweHogLWQgYXhhMV9yZXZlcnNlLmZhc3RxLnh6ICYmIHBpZ3ogYXhhMV9yZXZlcnNlLmZhc3RxCiAgZWxzZQogICAgZWNobyAiTWlzc2luZyBmaWxlcy4gRGlkIG5vdCBmaW5kIGF4YTFfZm9yd2FyZC5mYXN0cS5neiBub3Igc2VxdWVuY2VzL2F4YTFfZm9yd2FyZC5mYXN0cS54eiIKICAgIGV4aXQgMQogIGZpCmZpCnRyaW1vbWF0aWMgUEUgLXRocmVhZHMgMSAtcGhyZWQzMyBheGExX2ZvcndhcmQuZmFzdHEuZ3ogYXhhMV9yZXZlcnNlLmZhc3RxLmd6IGF4YTFfZm9yd2FyZC10cmltbWVkX3BhaXJlZC5mYXN0cS5neiBheGExX2ZvcndhcmQtdHJpbW1lZF91bnBhaXIKZWQuZmFzdHEuZ3ogYXhhMV9yZXZlcnNlLXRyaW1tZWRfcGFpcmVkLmZhc3RxLmd6IGF4YTFfcmV2ZXJzZS10cmltbWVkX3VucGFpcmVkLmZhc3RxLmd6IElMTFVNSU5BQ0xJUDovY2JjYmhvbWVzL2FiZWxldy9saWJyYXJpZXMvYWRhcHRlcnMuZmE6MjoyMDo0IFNMCklESU5HV0lORE9XOjQ6MjUgMT5vdXRwdXRzL2F4YTEtdHJpbW9tYXRpYy5vdXQgMj4mMQpleGNlcHRlZD0kKGdyZXAgIkV4Y2VwdGlvbiIgb3V0cHV0cy9heGExLXRyaW1vbWF0aWMub3V0KQojIyBUaGUgZm9sbG93aW5nIGlzIGluIGNhc2UgdGhlIGlsbHVtaW5hIGNsaXBwaW5nIGZhaWxzLCB3aGljaCBpdCBkb2VzIGlmIHRoaXMgaGFzIGFscmVhZHkgYmVlbiBydW4gSSB0aGluay4KaWYgW1sgIiR7ZXhjZXB0ZWR9IiAhPSAiIiBdXTsgdGhlbgogIHRyaW1vbWF0aWMgUEUgLXRocmVhZHMgMSAtcGhyZWQzMyBheGExX2ZvcndhcmQuZmFzdHEuZ3ogYXhhMV9yZXZlcnNlLmZhc3RxLmd6IGF4YTFfZm9yd2FyZC10cmltbWVkX3BhaXJlZC5mYXN0cS5neiBheGExX2ZvcndhcmQtdHJpbW1lZF91bnBhCmlyZWQuZmFzdHEuZ3ogYXhhMV9yZXZlcnNlLXRyaW1tZWRfcGFpcmVkLmZhc3RxLmd6IGF4YTFfcmV2ZXJzZS10cmltbWVkX3VucGFpcmVkLmZhc3RxLmd6IFNMSURJTkdXSU5ET1c6NDoyNSAxPj5vdXRwdXRzL2F4YTEtdHJpbW9tYXRpYy5vdXQgMj4mMQpmaQpzbGVlcCAxMAptdiBheGExX2ZvcndhcmQtdHJpbW1lZF9wYWlyZWQuZmFzdHEuZ3ogYXhhMV9mb3J3YXJkLXRyaW1tZWQuZmFzdHEuZ3ogJiYgbXYgYXhhMV9yZXZlcnNlLXRyaW1tZWRfcGFpcmVkLmZhc3RxLmd6IGF4YTFfcmV2ZXJzZS10cmltbWVkLmZhc3RxLmd6CmBgYAoKIyBCb3d0aWUgMgoKVGhlIGVuZCByZXN1bHQgc2hvdWxkIGJlIGEgc2V0IG9mIGZpbGVzIHdpdGggdHJpbW1lZCwgcGFpcmVkIHNlcXVlbmNlcyBzZXBhcmF0ZWQgZnJvbSB1bnBhaXJlZApzZXF1ZW5jZXMuCgojIFRvcGhhdAoKVGhlIHRvcGhhdCBwcm9jZXNzIGlzIGFjdHVhbGx5IGEgY291cGxlIG9mIHN0ZXBzIHJvbGxlZCBpbnRvIG9uZSwgdGhlIHRyaW1tZWQvcGFpcmVkIHJlYWRzIGFyZSBmZWQKdG8gdG9waGF0LCB0aGVuIHRoZSBhY2NlcHRlZF9oaXRzLmJhbSBpcyB0ZXN0ZWQgZm9yIHByb3Blcmx5IHBhaXJlZCByZWFkcyBhbmQgdGhvc2UgcmVhZHMgYXJlCnNlcGFyYXRlZCBpbnRvIGFjY2VwdGVkX3BhaXJlZC5iYW0uICBUaGVzZSAyIGJhbSBmaWxlcyBhcmUgc29ydGVkIGFuZCBpbmRleGVkLCBhbmQgZmluYWxseSBwYXNzZWQgdG8KaHRzZXEuICBUaHVzIHRoZSB0b3BoYXQgc2NyaXB0cyBsb29rIGxpa2U6CgpUaGVzZSBzY3JpcHRzIGhvd2V2ZXIsIGRvIG5vdCBpbmNsdWRlIHRoZSBhZGRpdGlvbmFsIHByb2Nlc3Npbmcgc3RlcCB3aGljaCBzcGxpdCB0aGUKYWNjZXB0ZWRfaGl0cy5iYW0gaW50byBhY2NlcHRlZF9wYWlyZWQuYmFtICBJIGFtIG5vdCBzdXJlIHdoeSwgYnV0IHRoZXNlIHNjcmlwdHMgYXJlIG1pc3NpbmcgdGhlCmZvbGxvd2luZyBzdGVwIHdoaWNoIHdhcyBwZXJmb3JtZWQgYnV0IG5vdCBwcm9wZXJseSBsb2dnZWQ6CgpgYGB7YmFzaCBwYWlyZWRfaGl0cywgZXZhbD1GQUxTRX0KaWYgWyAtciAiJHt0b3BoYXRfZGlyfS9hY2NlcHRlZF9oaXRzLmJhbSIgXTsgdGhlbgogIHNhbXRvb2xzIHZpZXcgLWIgLWYgMiAke3RvcGhhdF9kaXJ9L2FjY2VwdGVkX2hpdHMuYmFtID4gJHt0b3BoYXRfZGlyfS9hY2NlcHRlZF9wYWlyZWQuYmFtICYmIHNhbXRvb2xzIGluZGV4ICR7dG9waGF0X2Rpcn0vYWNjZXB0ZWRfcGFpcmVkLmJhbQpmaQpgYGAKCkkga25vdyB0aGlzIHN0ZXAgd2FzIHBlcmZvcm1lZCwgYmVjYXVzZSB0aGUgZmlsZXMgYWNjZXB0ZWRfcGFpcmVkLmJhbSBleGlzdHMgZm9yIGVhY2ggZGlyZWN0b3J5LCBidXQKdGhlIG9wdGlvbiAtZiAyIHNheXMgdGhhdCB0aGUgJzInIGZsYWcgbXVzdCBiZSBzZXQsIHdoaWNoIGlzIHRoZSBmbGFnIGZvciBhbiBhbGlnbm1lbnQgd2hpY2ggaXMKcGFpcmVkLgoKYGBge2Jhc2ggdG9waGF0X3J1bnMsIGV2YWw9RkFMU0V9CiMjIHNjcmlwdHMvdGhfbGJyYXppbGllbnNpcy1heGExLnNoCm1rZGlyIC1wIG91dHB1dHMvdG9waGF0X2xicmF6aWxpZW5zaXMgJiYgdG9waGF0ICAtZyAxICBcCiAgLUcgL2NiY2Job21lcy9hYmVsZXcvbGlicmFyaWVzL2dlbm9tZS9sYnJhemlsaWVuc2lzLmdmZiBcCiAgLS1iMi12ZXJ5LXNlbnNpdGl2ZSAtcCA0IC1vIG91dHB1dHMvdG9waGF0X2xicmF6aWxpZW5zaXMgXAovY2JjYmhvbWVzL2FiZWxldy9saWJyYXJpZXMvZ2Vub21lL2luZGV4ZXMvbGJyYXppbGllbnNpcyBcCiAgYXhhMV9mb3J3YXJkLXRyaW1tZWQuZmFzdHEuZ3ogYXhhMV9yZXZlcnNlLXRyaW1tZWQuZmFzdHEuZ3ogJiYgXAogIHNhbXRvb2xzIHNvcnQgLWwgOSAtbiBvdXRwdXRzL3RvcGhhdF9sYnJhemlsaWVuc2lzL2FjY2VwdGVkX2hpdHMuYmFtIG91dHB1dHMvdG9waGF0X2xicmF6aWxpZW5zaXMvYWNjZXB0ZWRfc29ydGVkICYmIFwKICBtdiBvdXRwdXRzL3RvcGhhdF9sYnJhemlsaWVuc2lzL2FjY2VwdGVkX3NvcnRlZC5iYW0gb3V0cHV0cy90b3BoYXRfbGJyYXppbGllbnNpcy9hY2NlcHRlZF9oaXRzLmJhbSAmJiBcCiAgc2FtdG9vbHMgaW5kZXggb3V0cHV0cy90b3BoYXRfbGJyYXppbGllbnNpcy9hY2NlcHRlZF9oaXRzLmJhbSAmJiBcCiAgc2FtdG9vbHMgc29ydCAtbCA5IC1uIG91dHB1dHMvdG9waGF0X2xicmF6aWxpZW5zaXMvdW5tYXBwZWQuYmFtIG91dHB1dHMvdG9waGF0X2xicmF6aWxpZW5zaXMvdW5tYXBwZWRfc29ydGVkICYmIFwKICBtdiBvdXRwdXRzL3RvcGhhdF9sYnJhemlsaWVuc2lzL3VubWFwcGVkX3NvcnRlZC5iYW0gb3V0cHV0cy90b3BoYXRfbGJyYXppbGllbnNpcy91bm1hcHBlZC5iYW0gJiYgXAogIHNhbXRvb2xzIGluZGV4IG91dHB1dHMvdG9waGF0X2xicmF6aWxpZW5zaXMvdW5tYXBwZWQuYmFtCmBgYAoKIyBSdW4gaHRzZXEKClRoZSBhYm92ZSBzY3JpcHRzIGNyZWF0ZSBzb3J0ZWQgYWNjZXB0ZWRfaGl0cy5iYW0gZmlsZXMsIEkgdGhpbmsgdGhhdCBJIG1hbnVhbGx5IG1hZGUgdGhlCmFjY2VwdGVkX3BhaXJlZC5iYW0gZmlsZXMgYW5kIGFkZGVkIHRob3NlIHN0ZXBzIHRvIHRoZSBjeW9hIHNjcmlwdCBwb3N0LWZhY3RvLCBidXQgdGhlIGVuZCByZXN1bHQgaXMKdGhlIHNhbWUgYW5kIHNvIEkgbmVlZGVkIHRvIHJ1biBodHNlcSBvbiBib3RoOgoKYGBge2Jhc2ggaHRzZXFfaW52b2NhdGlvbnMsIGV2YWw9RkFMU0V9CiMjIHNjcmlwdHMvdGhfbGJyYXppbGllbnNpcy1ocGdsMDI0MS5zaAojIyBDb3VudGluZyB0aGUgbnVtYmVyIG9mIGhpdHMgaW4gb3V0cHV0cy90b3BoYXRfbGJyYXppbGllbnNpcy9hY2NlcHRlZF9oaXRzLmJhbSBmb3IgZWFjaCBmZWF0dXJlIGZvdW5kIGluIC9jYmNiaG9tZXMvYWJlbGV3L2xpYnJhcmllcy9nZW5vbWUvbGJyYXppbGllbnNpcy5nZmYKIyMgSXMgdGhpcyBzdHJhbmRlZD8gbm8uICBUaGUgZGVmYXVsdHMgb2YgaHRzZXEgYXJlOgojIyAgLS1vcmRlcj1uYW1lIC0taWRhdHRyPWdlbmVfaWQgLS1taW5hcXVhbD0xMCAtLXR5cGU9ZXhvbiAtLXN0cmFuZGVkPXllcyAtLW1vZGU9dW5pb24KaHRzZXEtY291bnQgLXEgLWYgYmFtIC1zIG5vICAtaSBJRCAgXAogIG91dHB1dHMvdG9waGF0X2xicmF6aWxpZW5zaXMvYWNjZXB0ZWRfaGl0cy5iYW0gL2NiY2Job21lcy9hYmVsZXcvbGlicmFyaWVzL2dlbm9tZS9sYnJhemlsaWVuc2lzLmdmZiBcCiAgMT5vdXRwdXRzL3RvcGhhdF9sYnJhemlsaWVuc2lzL2FjY2VwdGVkX2hpdHMuY291bnQgMj5vdXRwdXRzL3RvcGhhdF9sYnJhemlsaWVuc2lzL2FjY2VwdGVkX2hpdHMuZXJyb3IgJiYgXAogICAgeHogLTllIG91dHB1dHMvdG9waGF0X2xicmF6aWxpZW5zaXMvYWNjZXB0ZWRfaGl0cy5jb3VudAojIyBJIGFtIG5vdCBnb2luZyB0byBiZWxhYm9yIHRoZSBwb2ludCBhbmQgcHJpbnQgdGhlIGh0c2VxIGNvbW1hbmRzIGZvciBhbGwgc3BlY2llcy4KYGBgCgpgYGB7ciBzYXZlbWV9CmlmICghaXNUUlVFKGdldDAoInNraXBfbG9hZCIpKSkgewogIHBhbmRlcjo6cGFuZGVyKHNlc3Npb25JbmZvKCkpCiAgbWVzc2FnZShwYXN0ZTAoIlRoaXMgaXMgaHBnbHRvb2xzIGNvbW1pdDogIiwgZ2V0X2dpdF9jb21taXQoKSkpCiAgdGhpc19zYXZlIDwtIHBhc3RlMChnc3ViKHBhdHRlcm49IlxcLlJtZCIsIHJlcGxhY2U9IiIsIHg9cm1kX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikKICBtZXNzYWdlKHBhc3RlMCgiU2F2aW5nIHRvICIsIHRoaXNfc2F2ZSkpCiAgdG1wIDwtIHNtKHNhdmVtZShmaWxlbmFtZT10aGlzX3NhdmUpKQp9CmBgYAo=