index.html

1 Fastqc sample estimations

Fastqc is a quick and easy tool to ensure that the data is suitable for further analysis.

cd preprocessing && ./fastqc.sh  ## The script contains the following:
## start=$(pwd)
## for i in $(/bin/ls -d hpgl*); do
##   echo "cd into ${i}"
##   cd ${i}
##   input=$(/bin/ls *.fastq.gz)
##   cyoa --input ${input} --task rnaseq --method fastqc
##   cd ${start}
## done
## A representative script generated looks like this: (without the logging)
## mkdir -p outputs/fastqc &&\
##   fastqc --extract -o outputs/fastqc hpgl0689_forward.fastq.gz \
##   2>outputs/hpgl0689_forward-unfiltered_fastqc.out 1>&2

The results from fastqc are generally not of much interest unless they find something wrong in the data. The most commonly queried result from it is the score distribution with respect to nucleotide.

quality distribution.

quality distribution.

2 Sample trimming

We usually use trimomatic to remove sequence adapters and trim away poor quality bases. It is worth noting that for this data I created three test directories into which I copied 100,000 reads each in order to test each task.

cd preprocessing && ./trim.sh
## start=$(pwd)
## for i in $(/bin/ls -d hpgl*); do
##   echo "cd into ${i}"
##   cd ${i}
##   input=$(/bin/ls *.fastq.gz)
##   cyoa --input ${input} --task rnaseq --method trim
##   cd ${start}
##done
## A representative script looks like this:

## This call to trimomatic removes illumina and epicentre adapters from hpgl0689_forward.fastq.gz.
## It also performs a sliding window removal of anything with quality <25;
## cutadapt provides an alternative to this tool.
## The original sequence data is recompressed and saved in the sequences/ directory.
## Trimomatic_Single: In case a trimming needs to be redone...
## if [[ ! -r "hpgl0689_forward.fastq.gz" ]]; then
##   if [[ -r "sequences/hpgl0689_forward.fastq.gz.xz" ]]; then
##     mv sequences/hpgl0689_forward.fastq.gz.xz . && pxz -d hpgl0689_forward.fastq.gz.xz
##   else
##     echo "Missing files. Did not find hpgl0689_forward.fastq.gz nor sequences/hpgl0689_forward.fastq.gz.xz"
##     exit 1
##   fi
## fi
## trimomatic SE -phred33 hpgl0689_forward.fastq.gz hpgl0689_forward-trimmed.fastq ILLUMINACLIP:/cbcbhomes/abelew/libraries/adapters.fa:2:20:4 SLIDINGWINDOW:4:25 1>outputs/hpgl0689_forward-trimomatic.out 2>&1

3 Sample estimation with biopieces

The biopieces framework provides some pretty metrics.

cd preprocessing && ./biopieces.sh
## start=$(pwd)
## for i in $(/bin/ls -d hpgl*); do
##   echo "cd into ${i}"
##   cd ${i}
##   input=$(/bin/ls *trimmed.fastq)
##   cyoa --input ${input} --task rnaseq --method biopieces
##   cd ${start}
## done
## A representative script looks like this:
## This script uses biopieces to draw some simple graphs of the sequence.
## Do not forget that _only_ the last command in a biopieces string is allowed to have the -x.
## mkdir -p outputs/biopieces
## less hpgl0689_forward-trimmed.fastq | read_fastq -i - -e base_33 |\
##  plot_scores -T 'Quality Scores' -t svg -o outputs/biopieces/hpgl0689_forward-trimmed_quality_scores.svg |\
##  plot_nucleotide_distribution -T 'NT. Distribution' -t svg -o outputs/biopieces/hpgl0689_forward-trimmed_ntdist.svg |\
##  plot_lendist -T 'Length Distribution' -k SEQ_LEN -t svg -o outputs/biopieces/hpgl0689_forward-trimmed_lendist.svg |\
##  analyze_gc |\
##      bin_vals -b 20 -k 'GC%' |\
##      plot_distribution -k 'GC%_BIN' -t svg -o outputs/biopieces/hpgl0689_forward-trimmed_gc_dist.svg |\
##  analyze_gc |\
##      mean_vals -k 'GC%' -o outputs/biopieces/hpgl0689_forward-trimmed_gc.txt |\
##  count_records -o outputs/biopieces/hpgl0689_forward-trimmed_count.txt -x

Length distribution of a sample: length distribution. Quality scores of a sample: quality distribution. Nucleotide distributions of a sample: quality distribution. GC distribution of a sample: quality distribution.

4 Tophat alignments

For these intron rich genomes, we use tophat and/or kallisto. As you can see at the end of the tophat command, I make an attempt to convert all the generated samfiles as quickly as possible into sorted, indexed bamfiles.

cd preprocessing && ./tophat.sh
## start=$(pwd)
## for i in $(/bin/ls -d hpgl*); do
##   echo "cd into ${i}"
##   cd ${i}
##   input=$(/bin/ls *-trimmed.fastq.gz)
##   cyoa --input ${input} --task rnaseq --method tophat --species iscapularis --htseq_type mRNA
##   cd ${start}
## done
## A representative script looks like this:
## However, I know that -g 1 will allow only 1 hit in the case of multihits, but randomly place it
## From the manual:  "If there are more alignments with the same score than this
## number, TopHat will randomly report only this many alignments"
## -N 1 will discard anything with >1 mismatch (default is 2)
## -r adjusts the allowable mean distance between the paired reads
## --mate-std-dev sets the deviation of -r
## --microexon-search will tell it to search short exons for reads >=50
## mkdir -p outputs/tophat_iscapularis && tophat  -g 1  \
##   -G /cbcbhomes/abelew/libraries/genome/iscapularis.gff \
##   --b2-very-sensitive -p 4 -o outputs/tophat_iscapularis \
##   /cbcbhomes/abelew/libraries/genome/indexes/iscapularis \
##   hpgl0689_forward-trimmed.fastq.gz 2>outputs/tophat.out 1>&2 && \
##  samtools sort -l 9 -n outputs/tophat_iscapularis/accepted_hits.bam outputs/tophat_iscapularis/accepted_sorted && \
##  mv outputs/tophat_iscapularis/accepted_sorted.bam outputs/tophat_iscapularis/accepted_hits.bam && \
##  samtools index outputs/tophat_iscapularis/accepted_hits.bam && \
##  samtools sort -l 9 -n outputs/tophat_iscapularis/unmapped.bam outputs/tophat_iscapularis/unmapped_sorted && \
##  mv outputs/tophat_iscapularis/unmapped_sorted.bam outputs/tophat_iscapularis/unmapped.bam && \
## samtools index outputs/tophat_iscapularis/unmapped.bam

5 Counting reads

HTSeq is the most common tool for this task. The invocation of this is actually handled in the same command as tophat above, the following is a relevant script generated by it in order to count against the Ixodes scapularis annotations.

## Counting the number of hits in outputs/tophat_iscapularis/accepted_hits.bam for each feature found in /cbcbhomes/abelew/libraries/genome/iscapularis.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  -t mRNA \
  outputs/tophat_iscapularis/accepted_hits.bam /cbcbhomes/abelew/libraries/genome/iscapularis.gff \
  1>outputs/tophat_iscapularis/accepted_hits.count 2>outputs/tophat_iscapularis/accepted_hits_htseq.err && \
    xz -9e outputs/tophat_iscapularis/accepted_hits.count

The result of this process is the creation of files named ‘accepted_hits.count.xz’ in each sample’s outputs/tophat_iscapularis/ directory. After finishing this, I decided to have the cyoa script put these count tables in their own htseq_(species) directory, so if they disappear that is where they went. (The thinking is that this way I can try out some different counters.) At this point, the data is ready for analysis, I merely need to update the all_samples spreadsheet to reflect the locations of the new count tables in a column named ‘file’. Also, I modified it slightly, as R gets angry at the word ‘naive’ with the umlaut over the i.

With that I can move on to reading in annotations and performing sample estimations.

library('pander')
pander(sessionInfo())

R version 3.3.3 (2017-03-06)

**Platform:** x86_64-pc-linux-gnu (64-bit)

locale: LC_CTYPE=en_US.UTF-8, LC_NUMERIC=C, LC_TIME=en_US.UTF-8, LC_COLLATE=en_US.UTF-8, LC_MONETARY=en_US.UTF-8, LC_MESSAGES=en_US.UTF-8, LC_PAPER=en_US.UTF-8, LC_NAME=C, LC_ADDRESS=C, LC_TELEPHONE=C, LC_MEASUREMENT=en_US.UTF-8 and LC_IDENTIFICATION=C

attached base packages: stats, graphics, grDevices, utils, datasets, methods and base

other attached packages: RMySQL(v.0.10.11), DBI(v.0.6-1), hpgltools(v.2017.01) and pander(v.0.6.0)

loaded via a namespace (and not attached): SummarizedExperiment(v.1.4.0), lattice(v.0.20-35), colorspace(v.1.3-2), testthat(v.1.0.2), htmltools(v.0.3.5), stats4(v.3.3.3), rtracklayer(v.1.34.2), yaml(v.2.1.14), base64enc(v.0.1-3), XML(v.3.98-1.6), withr(v.1.0.2), BiocParallel(v.1.8.2), BiocGenerics(v.0.20.0), foreach(v.1.4.3), plyr(v.1.8.4), stringr(v.1.2.0), zlibbioc(v.1.20.0), Biostrings(v.2.42.1), munsell(v.0.4.3), commonmark(v.1.2), gtable(v.0.2.0), devtools(v.1.12.0), codetools(v.0.2-15), evaluate(v.0.10), memoise(v.1.1.0), Biobase(v.2.34.0), knitr(v.1.15.1), IRanges(v.2.8.2), GenomeInfoDb(v.1.10.3), parallel(v.3.3.3), Rcpp(v.0.12.10), backports(v.1.0.5), scales(v.0.4.1), S4Vectors(v.0.12.2), XVector(v.0.14.1), Rsamtools(v.1.26.2), ggplot2(v.2.2.1), digest(v.0.6.12), stringi(v.1.1.5), GenomicRanges(v.1.26.4), grid(v.3.3.3), rprojroot(v.1.2), tools(v.3.3.3), bitops(v.1.0-6), magrittr(v.1.5), lazyeval(v.0.2.0), RCurl(v.1.95-4.8), tibble(v.1.3.0), crayon(v.1.3.2), Matrix(v.1.2-8), data.table(v.1.10.4), xml2(v.1.1.1), rmarkdown(v.1.4), roxygen2(v.6.0.1), iterators(v.1.0.8), R6(v.2.2.0), GenomicAlignments(v.1.10.1) and compiler(v.3.3.3)

LS0tCnRpdGxlOiAiUHJlcHJvY2Vzc2luZyBJeG9kZXMgc2NhcHVsYXJpcyByYXcgZGF0YS4iCmF1dGhvcjogImF0YiBhYmVsZXdAZ21haWwuY29tIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKIGh0bWxfZG9jdW1lbnQ6CiAgY29kZV9kb3dubG9hZDogdHJ1ZQogIGNvZGVfZm9sZGluZzogc2hvdwogIGZpZ19jYXB0aW9uOiB0cnVlCiAgZmlnX2hlaWdodDogNwogIGZpZ193aWR0aDogNwogIGhpZ2hsaWdodDogdGFuZ28KICBrZWVwX21kOiBmYWxzZQogIG1vZGU6IHNlbGZjb250YWluZWQKICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQogIHRoZW1lOiBjb3NtbwogIHRvYzogdHJ1ZQogIHRvY19mbG9hdDoKICAgIGNvbGxhcHNlZDogZmFsc2UKICAgIHNtb290aF9zY3JvbGw6IGZhbHNlCi0tLQoKPHN0eWxlPgogIDwhLS0gRG9jdW1lbnQgcHJlbHVkZSByZXZpc2lvbiAyMDE2LTEwIC0tPgogIGJvZHkgLm1haW4tY29udGFpbmVyIHsKICAgIG1heC13aWR0aDogMTYwMHB4Owp9Cjwvc3R5bGU+CgpgYGB7ciBvcHRpb25zLCBpbmNsdWRlPUZBTFNFfQojIyBUaGVzZSBhcmUgdGhlIG9wdGlvbnMgSSB0ZW5kIHRvIGZhdm9yCmxpYnJhcnkoImhwZ2x0b29scyIpCmtuaXRyOjpvcHRzX2tuaXQkc2V0KAogICAgcHJvZ3Jlc3MgPSBUUlVFLAogICAgdmVyYm9zZSA9IFRSVUUsCiAgICB3aWR0aCA9IDkwLAogICAgZWNobyA9IFRSVUUpCmtuaXRyOjpvcHRzX2NodW5rJHNldCgKICAgIGVycm9yID0gVFJVRSwKICAgIGZpZy53aWR0aCA9IDgsCiAgICBmaWcuaGVpZ2h0ID0gOCwKICAgIGRwaSA9IDk2KQpvcHRpb25zKAogICAgZGlnaXRzID0gNCwKICAgIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSwKICAgIGtuaXRyLmR1cGxpY2F0ZS5sYWJlbCA9ICJhbGxvdyIpCmdncGxvdDI6OnRoZW1lX3NldChnZ3Bsb3QyOjp0aGVtZV9idyhiYXNlX3NpemU9MTApKQpzZXQuc2VlZCgxKQpwcmV2aW91c19maWxlIDwtICJpbmRleC5SbWQiCnJtZF9maWxlIDwtICJhbm5vdGF0aW9uLlJtZCIKdmVyIDwtICIyMDE3MDQyNCIKcHJldmlvdXNfc2F2ZSA8LSBwYXN0ZTAoZ3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSIiLCB4PXByZXZpb3VzX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikKdGhpc19zYXZlIDwtIHBhc3RlMChnc3ViKHBhdHRlcm49IlxcLlJtZCIsIHJlcGxhY2U9IiIsIHg9cm1kX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikKYGBgCgpbaW5kZXguaHRtbF0oaW5kZXguaHRtbCkKCmBgYHtyIHJlbmRlcmluZywgaW5jbHVkZT1GQUxTRSwgZXZhbD1GQUxTRX0KIyMgVGhpcyBibG9jayBpcyB1c2VkIHRvIHJlbmRlciBhIGRvY3VtZW50IGZyb20gd2l0aGluIGl0LgpybWFya2Rvd246OnJlbmRlcihybWRfZmlsZSkKCiMjIEFuIGV4dHJhIHJlbmRlcmVyIGZvciBwZGYgb3V0cHV0CnJtYXJrZG93bjo6cmVuZGVyKHJtZF9maWxlLCBvdXRwdXRfZm9ybWF0PSJwZGZfZG9jdW1lbnQiLCBvdXRwdXRfb3B0aW9ucz1jKCJza2lwX2h0bWwiKSkKIyMgT3IgdG8gc2F2ZS9sb2FkIGxhcmdlIFJkYXRhIGZpbGVzLgpocGdsdG9vbHM6OjpzYXZlbWUoKQpocGdsdG9vbHM6Ojpsb2FkbWUoKQpybShsaXN0PWxzKCkpCmBgYAoKIyBGYXN0cWMgc2FtcGxlIGVzdGltYXRpb25zCgpGYXN0cWMgaXMgYSBxdWljayBhbmQgZWFzeSB0b29sIHRvIGVuc3VyZSB0aGF0IHRoZSBkYXRhIGlzIHN1aXRhYmxlIGZvciBmdXJ0aGVyIGFuYWx5c2lzLgoKYGBge3IgZmFzdHFjLCBlbmdpbmU9J2Jhc2gnLCBldmFsPUZBTFNFfQpjZCBwcmVwcm9jZXNzaW5nICYmIC4vZmFzdHFjLnNoICAjIyBUaGUgc2NyaXB0IGNvbnRhaW5zIHRoZSBmb2xsb3dpbmc6CiMjIHN0YXJ0PSQocHdkKQojIyBmb3IgaSBpbiAkKC9iaW4vbHMgLWQgaHBnbCopOyBkbwojIyAgIGVjaG8gImNkIGludG8gJHtpfSIKIyMgICBjZCAke2l9CiMjICAgaW5wdXQ9JCgvYmluL2xzICouZmFzdHEuZ3opCiMjICAgY3lvYSAtLWlucHV0ICR7aW5wdXR9IC0tdGFzayBybmFzZXEgLS1tZXRob2QgZmFzdHFjCiMjICAgY2QgJHtzdGFydH0KIyMgZG9uZQojIyBBIHJlcHJlc2VudGF0aXZlIHNjcmlwdCBnZW5lcmF0ZWQgbG9va3MgbGlrZSB0aGlzOiAod2l0aG91dCB0aGUgbG9nZ2luZykKIyMgbWtkaXIgLXAgb3V0cHV0cy9mYXN0cWMgJiZcCiMjICAgZmFzdHFjIC0tZXh0cmFjdCAtbyBvdXRwdXRzL2Zhc3RxYyBocGdsMDY4OV9mb3J3YXJkLmZhc3RxLmd6IFwKIyMgICAyPm91dHB1dHMvaHBnbDA2ODlfZm9yd2FyZC11bmZpbHRlcmVkX2Zhc3RxYy5vdXQgMT4mMgpgYGAKClRoZSByZXN1bHRzIGZyb20gZmFzdHFjIGFyZSBnZW5lcmFsbHkgbm90IG9mIG11Y2ggaW50ZXJlc3QgdW5sZXNzIHRoZXkgZmluZCBzb21ldGhpbmcgd3JvbmcgaW4gdGhlCmRhdGEuICBUaGUgbW9zdCBjb21tb25seSBxdWVyaWVkIHJlc3VsdCBmcm9tIGl0IGlzIHRoZSBzY29yZSBkaXN0cmlidXRpb24gd2l0aCByZXNwZWN0IHRvCm51Y2xlb3RpZGUuCgohW3F1YWxpdHkgZGlzdHJpYnV0aW9uLl0ocHJlcHJvY2Vzc2luZy9ocGdsMDY4OS9vdXRwdXRzL2Zhc3RxYy9ocGdsMDY4OV9mb3J3YXJkX2Zhc3RxYy9JbWFnZXMvcGVyX2Jhc2VfcXVhbGl0eS5wbmcpCgojIFNhbXBsZSB0cmltbWluZwoKV2UgdXN1YWxseSB1c2UgdHJpbW9tYXRpYyB0byByZW1vdmUgc2VxdWVuY2UgYWRhcHRlcnMgYW5kIHRyaW0gYXdheSBwb29yIHF1YWxpdHkgYmFzZXMuICBJdCBpcyB3b3J0aApub3RpbmcgdGhhdCBmb3IgdGhpcyBkYXRhIEkgY3JlYXRlZCB0aHJlZSB0ZXN0IGRpcmVjdG9yaWVzIGludG8gd2hpY2ggSSBjb3BpZWQgMTAwLDAwMCByZWFkcyBlYWNoIGluCm9yZGVyIHRvIHRlc3QgZWFjaCB0YXNrLgoKYGBge3IgdHJpbW9tYXRpYywgZW5naW5lPSdiYXNoJywgZXZhbD1GQUxTRX0KY2QgcHJlcHJvY2Vzc2luZyAmJiAuL3RyaW0uc2gKIyMgc3RhcnQ9JChwd2QpCiMjIGZvciBpIGluICQoL2Jpbi9scyAtZCBocGdsKik7IGRvCiMjICAgZWNobyAiY2QgaW50byAke2l9IgojIyAgIGNkICR7aX0KIyMgICBpbnB1dD0kKC9iaW4vbHMgKi5mYXN0cS5neikKIyMgICBjeW9hIC0taW5wdXQgJHtpbnB1dH0gLS10YXNrIHJuYXNlcSAtLW1ldGhvZCB0cmltCiMjICAgY2QgJHtzdGFydH0KIyNkb25lCiMjIEEgcmVwcmVzZW50YXRpdmUgc2NyaXB0IGxvb2tzIGxpa2UgdGhpczoKCiMjIFRoaXMgY2FsbCB0byB0cmltb21hdGljIHJlbW92ZXMgaWxsdW1pbmEgYW5kIGVwaWNlbnRyZSBhZGFwdGVycyBmcm9tIGhwZ2wwNjg5X2ZvcndhcmQuZmFzdHEuZ3ouCiMjIEl0IGFsc28gcGVyZm9ybXMgYSBzbGlkaW5nIHdpbmRvdyByZW1vdmFsIG9mIGFueXRoaW5nIHdpdGggcXVhbGl0eSA8MjU7CiMjIGN1dGFkYXB0IHByb3ZpZGVzIGFuIGFsdGVybmF0aXZlIHRvIHRoaXMgdG9vbC4KIyMgVGhlIG9yaWdpbmFsIHNlcXVlbmNlIGRhdGEgaXMgcmVjb21wcmVzc2VkIGFuZCBzYXZlZCBpbiB0aGUgc2VxdWVuY2VzLyBkaXJlY3RvcnkuCiMjIFRyaW1vbWF0aWNfU2luZ2xlOiBJbiBjYXNlIGEgdHJpbW1pbmcgbmVlZHMgdG8gYmUgcmVkb25lLi4uCiMjIGlmIFtbICEgLXIgImhwZ2wwNjg5X2ZvcndhcmQuZmFzdHEuZ3oiIF1dOyB0aGVuCiMjICAgaWYgW1sgLXIgInNlcXVlbmNlcy9ocGdsMDY4OV9mb3J3YXJkLmZhc3RxLmd6Lnh6IiBdXTsgdGhlbgojIyAgICAgbXYgc2VxdWVuY2VzL2hwZ2wwNjg5X2ZvcndhcmQuZmFzdHEuZ3oueHogLiAmJiBweHogLWQgaHBnbDA2ODlfZm9yd2FyZC5mYXN0cS5nei54egojIyAgIGVsc2UKIyMgICAgIGVjaG8gIk1pc3NpbmcgZmlsZXMuIERpZCBub3QgZmluZCBocGdsMDY4OV9mb3J3YXJkLmZhc3RxLmd6IG5vciBzZXF1ZW5jZXMvaHBnbDA2ODlfZm9yd2FyZC5mYXN0cS5nei54eiIKIyMgICAgIGV4aXQgMQojIyAgIGZpCiMjIGZpCiMjIHRyaW1vbWF0aWMgU0UgLXBocmVkMzMgaHBnbDA2ODlfZm9yd2FyZC5mYXN0cS5neiBocGdsMDY4OV9mb3J3YXJkLXRyaW1tZWQuZmFzdHEgSUxMVU1JTkFDTElQOi9jYmNiaG9tZXMvYWJlbGV3L2xpYnJhcmllcy9hZGFwdGVycy5mYToyOjIwOjQgU0xJRElOR1dJTkRPVzo0OjI1IDE+b3V0cHV0cy9ocGdsMDY4OV9mb3J3YXJkLXRyaW1vbWF0aWMub3V0IDI+JjEKYGBgCgojIFNhbXBsZSBlc3RpbWF0aW9uIHdpdGggYmlvcGllY2VzCgpUaGUgYmlvcGllY2VzIGZyYW1ld29yayBwcm92aWRlcyBzb21lIHByZXR0eSBtZXRyaWNzLgoKYGBge3IgYmlvcGllY2VzLCBlbmdpbmU9J2Jhc2gnLCBldmFsPUZBTFNFfQpjZCBwcmVwcm9jZXNzaW5nICYmIC4vYmlvcGllY2VzLnNoCiMjIHN0YXJ0PSQocHdkKQojIyBmb3IgaSBpbiAkKC9iaW4vbHMgLWQgaHBnbCopOyBkbwojIyAgIGVjaG8gImNkIGludG8gJHtpfSIKIyMgICBjZCAke2l9CiMjICAgaW5wdXQ9JCgvYmluL2xzICp0cmltbWVkLmZhc3RxKQojIyAgIGN5b2EgLS1pbnB1dCAke2lucHV0fSAtLXRhc2sgcm5hc2VxIC0tbWV0aG9kIGJpb3BpZWNlcwojIyAgIGNkICR7c3RhcnR9CiMjIGRvbmUKIyMgQSByZXByZXNlbnRhdGl2ZSBzY3JpcHQgbG9va3MgbGlrZSB0aGlzOgojIyBUaGlzIHNjcmlwdCB1c2VzIGJpb3BpZWNlcyB0byBkcmF3IHNvbWUgc2ltcGxlIGdyYXBocyBvZiB0aGUgc2VxdWVuY2UuCiMjIERvIG5vdCBmb3JnZXQgdGhhdCBfb25seV8gdGhlIGxhc3QgY29tbWFuZCBpbiBhIGJpb3BpZWNlcyBzdHJpbmcgaXMgYWxsb3dlZCB0byBoYXZlIHRoZSAteC4KIyMgbWtkaXIgLXAgb3V0cHV0cy9iaW9waWVjZXMKIyMgbGVzcyBocGdsMDY4OV9mb3J3YXJkLXRyaW1tZWQuZmFzdHEgfCByZWFkX2Zhc3RxIC1pIC0gLWUgYmFzZV8zMyB8XAojIyAgcGxvdF9zY29yZXMgLVQgJ1F1YWxpdHkgU2NvcmVzJyAtdCBzdmcgLW8gb3V0cHV0cy9iaW9waWVjZXMvaHBnbDA2ODlfZm9yd2FyZC10cmltbWVkX3F1YWxpdHlfc2NvcmVzLnN2ZyB8XAojIyAgcGxvdF9udWNsZW90aWRlX2Rpc3RyaWJ1dGlvbiAtVCAnTlQuIERpc3RyaWJ1dGlvbicgLXQgc3ZnIC1vIG91dHB1dHMvYmlvcGllY2VzL2hwZ2wwNjg5X2ZvcndhcmQtdHJpbW1lZF9udGRpc3Quc3ZnIHxcCiMjICBwbG90X2xlbmRpc3QgLVQgJ0xlbmd0aCBEaXN0cmlidXRpb24nIC1rIFNFUV9MRU4gLXQgc3ZnIC1vIG91dHB1dHMvYmlvcGllY2VzL2hwZ2wwNjg5X2ZvcndhcmQtdHJpbW1lZF9sZW5kaXN0LnN2ZyB8XAojIyAgYW5hbHl6ZV9nYyB8XAojIyAgICAgIGJpbl92YWxzIC1iIDIwIC1rICdHQyUnIHxcCiMjICAgICAgcGxvdF9kaXN0cmlidXRpb24gLWsgJ0dDJV9CSU4nIC10IHN2ZyAtbyBvdXRwdXRzL2Jpb3BpZWNlcy9ocGdsMDY4OV9mb3J3YXJkLXRyaW1tZWRfZ2NfZGlzdC5zdmcgfFwKIyMgIGFuYWx5emVfZ2MgfFwKIyMgICAgICBtZWFuX3ZhbHMgLWsgJ0dDJScgLW8gb3V0cHV0cy9iaW9waWVjZXMvaHBnbDA2ODlfZm9yd2FyZC10cmltbWVkX2djLnR4dCB8XAojIyAgY291bnRfcmVjb3JkcyAtbyBvdXRwdXRzL2Jpb3BpZWNlcy9ocGdsMDY4OV9mb3J3YXJkLXRyaW1tZWRfY291bnQudHh0IC14CmBgYAoKTGVuZ3RoIGRpc3RyaWJ1dGlvbiBvZiBhIHNhbXBsZToKIVtsZW5ndGggZGlzdHJpYnV0aW9uLl0ocHJlcHJvY2Vzc2luZy9ocGdsMDY4OS9vdXRwdXRzL2Jpb3BpZWNlcy9ocGdsMDY4OV9mb3J3YXJkLXRyaW1tZWRfbGVuZGlzdC5zdmcpClF1YWxpdHkgc2NvcmVzIG9mIGEgc2FtcGxlOgohW3F1YWxpdHkgZGlzdHJpYnV0aW9uLl0ocHJlcHJvY2Vzc2luZy9ocGdsMDY4OS9vdXRwdXRzL2Jpb3BpZWNlcy9ocGdsMDY4OV9mb3J3YXJkLXRyaW1tZWRfcXVhbGl0eV9zY29yZXMuc3ZnKQpOdWNsZW90aWRlIGRpc3RyaWJ1dGlvbnMgb2YgYSBzYW1wbGU6CiFbcXVhbGl0eSBkaXN0cmlidXRpb24uXShwcmVwcm9jZXNzaW5nL2hwZ2wwNjg5L291dHB1dHMvYmlvcGllY2VzL2hwZ2wwNjg5X2ZvcndhcmQtdHJpbW1lZF9udGRpc3Quc3ZnKQpHQyBkaXN0cmlidXRpb24gb2YgYSBzYW1wbGU6CiFbcXVhbGl0eSBkaXN0cmlidXRpb24uXShwcmVwcm9jZXNzaW5nL2hwZ2wwNjg5L291dHB1dHMvYmlvcGllY2VzL2hwZ2wwNjg5X2ZvcndhcmQtdHJpbW1lZF9nY2Rpc3Quc3ZnKQoKIyBUb3BoYXQgYWxpZ25tZW50cwoKRm9yIHRoZXNlIGludHJvbiByaWNoIGdlbm9tZXMsIHdlIHVzZSB0b3BoYXQgYW5kL29yIGthbGxpc3RvLiAgQXMgeW91IGNhbiBzZWUgYXQgdGhlIGVuZCBvZiB0aGUKdG9waGF0IGNvbW1hbmQsIEkgbWFrZSBhbiBhdHRlbXB0IHRvIGNvbnZlcnQgYWxsIHRoZSBnZW5lcmF0ZWQgc2FtZmlsZXMgYXMgcXVpY2tseSBhcyBwb3NzaWJsZSBpbnRvCnNvcnRlZCwgaW5kZXhlZCBiYW1maWxlcy4KCmBgYHtyIHRvcGhhdCwgZW5naW5lPSdiYXNoJywgZXZhbD1GQUxTRX0KY2QgcHJlcHJvY2Vzc2luZyAmJiAuL3RvcGhhdC5zaAojIyBzdGFydD0kKHB3ZCkKIyMgZm9yIGkgaW4gJCgvYmluL2xzIC1kIGhwZ2wqKTsgZG8KIyMgICBlY2hvICJjZCBpbnRvICR7aX0iCiMjICAgY2QgJHtpfQojIyAgIGlucHV0PSQoL2Jpbi9scyAqLXRyaW1tZWQuZmFzdHEuZ3opCiMjICAgY3lvYSAtLWlucHV0ICR7aW5wdXR9IC0tdGFzayBybmFzZXEgLS1tZXRob2QgdG9waGF0IC0tc3BlY2llcyBpc2NhcHVsYXJpcyAtLWh0c2VxX3R5cGUgbVJOQQojIyAgIGNkICR7c3RhcnR9CiMjIGRvbmUKIyMgQSByZXByZXNlbnRhdGl2ZSBzY3JpcHQgbG9va3MgbGlrZSB0aGlzOgojIyBIb3dldmVyLCBJIGtub3cgdGhhdCAtZyAxIHdpbGwgYWxsb3cgb25seSAxIGhpdCBpbiB0aGUgY2FzZSBvZiBtdWx0aWhpdHMsIGJ1dCByYW5kb21seSBwbGFjZSBpdAojIyBGcm9tIHRoZSBtYW51YWw6ICAiSWYgdGhlcmUgYXJlIG1vcmUgYWxpZ25tZW50cyB3aXRoIHRoZSBzYW1lIHNjb3JlIHRoYW4gdGhpcwojIyBudW1iZXIsIFRvcEhhdCB3aWxsIHJhbmRvbWx5IHJlcG9ydCBvbmx5IHRoaXMgbWFueSBhbGlnbm1lbnRzIgojIyAtTiAxIHdpbGwgZGlzY2FyZCBhbnl0aGluZyB3aXRoID4xIG1pc21hdGNoIChkZWZhdWx0IGlzIDIpCiMjIC1yIGFkanVzdHMgdGhlIGFsbG93YWJsZSBtZWFuIGRpc3RhbmNlIGJldHdlZW4gdGhlIHBhaXJlZCByZWFkcwojIyAtLW1hdGUtc3RkLWRldiBzZXRzIHRoZSBkZXZpYXRpb24gb2YgLXIKIyMgLS1taWNyb2V4b24tc2VhcmNoIHdpbGwgdGVsbCBpdCB0byBzZWFyY2ggc2hvcnQgZXhvbnMgZm9yIHJlYWRzID49NTAKIyMgbWtkaXIgLXAgb3V0cHV0cy90b3BoYXRfaXNjYXB1bGFyaXMgJiYgdG9waGF0ICAtZyAxICBcCiMjICAgLUcgL2NiY2Job21lcy9hYmVsZXcvbGlicmFyaWVzL2dlbm9tZS9pc2NhcHVsYXJpcy5nZmYgXAojIyAgIC0tYjItdmVyeS1zZW5zaXRpdmUgLXAgNCAtbyBvdXRwdXRzL3RvcGhhdF9pc2NhcHVsYXJpcyBcCiMjICAgL2NiY2Job21lcy9hYmVsZXcvbGlicmFyaWVzL2dlbm9tZS9pbmRleGVzL2lzY2FwdWxhcmlzIFwKIyMgICBocGdsMDY4OV9mb3J3YXJkLXRyaW1tZWQuZmFzdHEuZ3ogMj5vdXRwdXRzL3RvcGhhdC5vdXQgMT4mMiAmJiBcCiMjICBzYW10b29scyBzb3J0IC1sIDkgLW4gb3V0cHV0cy90b3BoYXRfaXNjYXB1bGFyaXMvYWNjZXB0ZWRfaGl0cy5iYW0gb3V0cHV0cy90b3BoYXRfaXNjYXB1bGFyaXMvYWNjZXB0ZWRfc29ydGVkICYmIFwKIyMgIG12IG91dHB1dHMvdG9waGF0X2lzY2FwdWxhcmlzL2FjY2VwdGVkX3NvcnRlZC5iYW0gb3V0cHV0cy90b3BoYXRfaXNjYXB1bGFyaXMvYWNjZXB0ZWRfaGl0cy5iYW0gJiYgXAojIyAgc2FtdG9vbHMgaW5kZXggb3V0cHV0cy90b3BoYXRfaXNjYXB1bGFyaXMvYWNjZXB0ZWRfaGl0cy5iYW0gJiYgXAojIyAgc2FtdG9vbHMgc29ydCAtbCA5IC1uIG91dHB1dHMvdG9waGF0X2lzY2FwdWxhcmlzL3VubWFwcGVkLmJhbSBvdXRwdXRzL3RvcGhhdF9pc2NhcHVsYXJpcy91bm1hcHBlZF9zb3J0ZWQgJiYgXAojIyAgbXYgb3V0cHV0cy90b3BoYXRfaXNjYXB1bGFyaXMvdW5tYXBwZWRfc29ydGVkLmJhbSBvdXRwdXRzL3RvcGhhdF9pc2NhcHVsYXJpcy91bm1hcHBlZC5iYW0gJiYgXAojIyBzYW10b29scyBpbmRleCBvdXRwdXRzL3RvcGhhdF9pc2NhcHVsYXJpcy91bm1hcHBlZC5iYW0KYGBgCgojIENvdW50aW5nIHJlYWRzCgpIVFNlcSBpcyB0aGUgbW9zdCBjb21tb24gdG9vbCBmb3IgdGhpcyB0YXNrLiAgVGhlIGludm9jYXRpb24gb2YgdGhpcyBpcyBhY3R1YWxseSBoYW5kbGVkIGluIHRoZSBzYW1lCmNvbW1hbmQgYXMgdG9waGF0IGFib3ZlLCB0aGUgZm9sbG93aW5nIGlzIGEgcmVsZXZhbnQgc2NyaXB0IGdlbmVyYXRlZCBieSBpdCBpbiBvcmRlciB0byBjb3VudAphZ2FpbnN0IHRoZSBJeG9kZXMgc2NhcHVsYXJpcyBhbm5vdGF0aW9ucy4KCmBgYHtyIGh0c2VxLCBlbmdpbmU9J2Jhc2gnLCBldmFsPUZBTFNFfQojIyBDb3VudGluZyB0aGUgbnVtYmVyIG9mIGhpdHMgaW4gb3V0cHV0cy90b3BoYXRfaXNjYXB1bGFyaXMvYWNjZXB0ZWRfaGl0cy5iYW0gZm9yIGVhY2ggZmVhdHVyZSBmb3VuZCBpbiAvY2JjYmhvbWVzL2FiZWxldy9saWJyYXJpZXMvZ2Vub21lL2lzY2FwdWxhcmlzLmdmZgojIyBJcyB0aGlzIHN0cmFuZGVkPyBuby4gIFRoZSBkZWZhdWx0cyBvZiBodHNlcSBhcmU6CiMjICAtLW9yZGVyPW5hbWUgLS1pZGF0dHI9Z2VuZV9pZCAtLW1pbmFxdWFsPTEwIC0tdHlwZT1leG9uIC0tc3RyYW5kZWQ9eWVzIC0tbW9kZT11bmlvbgpodHNlcS1jb3VudCAtcSAtZiBiYW0gLXMgbm8gIC1pIElEICAtdCBtUk5BIFwKICBvdXRwdXRzL3RvcGhhdF9pc2NhcHVsYXJpcy9hY2NlcHRlZF9oaXRzLmJhbSAvY2JjYmhvbWVzL2FiZWxldy9saWJyYXJpZXMvZ2Vub21lL2lzY2FwdWxhcmlzLmdmZiBcCiAgMT5vdXRwdXRzL3RvcGhhdF9pc2NhcHVsYXJpcy9hY2NlcHRlZF9oaXRzLmNvdW50IDI+b3V0cHV0cy90b3BoYXRfaXNjYXB1bGFyaXMvYWNjZXB0ZWRfaGl0c19odHNlcS5lcnIgJiYgXAogICAgeHogLTllIG91dHB1dHMvdG9waGF0X2lzY2FwdWxhcmlzL2FjY2VwdGVkX2hpdHMuY291bnQKYGBgCgpUaGUgcmVzdWx0IG9mIHRoaXMgcHJvY2VzcyBpcyB0aGUgY3JlYXRpb24gb2YgZmlsZXMgbmFtZWQgJ2FjY2VwdGVkX2hpdHMuY291bnQueHonIGluIGVhY2ggc2FtcGxlJ3MKb3V0cHV0cy90b3BoYXRfaXNjYXB1bGFyaXMvIGRpcmVjdG9yeS4gIEFmdGVyIGZpbmlzaGluZyB0aGlzLCBJIGRlY2lkZWQgdG8gaGF2ZSB0aGUgY3lvYSBzY3JpcHQgcHV0CnRoZXNlIGNvdW50IHRhYmxlcyBpbiB0aGVpciBvd24gaHRzZXFfKHNwZWNpZXMpIGRpcmVjdG9yeSwgc28gaWYgdGhleSBkaXNhcHBlYXIgdGhhdCBpcyB3aGVyZSB0aGV5CndlbnQuICAoVGhlIHRoaW5raW5nIGlzIHRoYXQgdGhpcyB3YXkgSSBjYW4gdHJ5IG91dCBzb21lIGRpZmZlcmVudCBjb3VudGVycy4pICBBdCB0aGlzIHBvaW50LCB0aGUKZGF0YSBpcyByZWFkeSBmb3IgYW5hbHlzaXMsIEkgbWVyZWx5IG5lZWQgdG8gdXBkYXRlIHRoZSBhbGxfc2FtcGxlcyBzcHJlYWRzaGVldCB0byByZWZsZWN0IHRoZQpsb2NhdGlvbnMgb2YgdGhlIG5ldyBjb3VudCB0YWJsZXMgaW4gYSBjb2x1bW4gbmFtZWQgJ2ZpbGUnLiAgQWxzbywgSSBtb2RpZmllZCBpdCBzbGlnaHRseSwgYXMgUiBnZXRzCmFuZ3J5IGF0IHRoZSB3b3JkICduYWl2ZScgd2l0aCB0aGUgdW1sYXV0IG92ZXIgdGhlIGkuCgpXaXRoIHRoYXQgSSBjYW4gbW92ZSBvbiB0byByZWFkaW5nIGluIGFubm90YXRpb25zIGFuZCBwZXJmb3JtaW5nIHNhbXBsZSBlc3RpbWF0aW9ucy4KCiogW0Fubm90YXRpb25dKGFubm90YXRpb24uaHRtbCkKKiBbU2FtcGxlIEVzdGltYXRpb25dKHNhbXBsZV9lc3RpbWF0aW9uLmh0bWwpCgpgYGB7ciBzeXNpbmZvLCByZXN1bHRzPSdhc2lzJ30KbGlicmFyeSgncGFuZGVyJykKcGFuZGVyKHNlc3Npb25JbmZvKCkpCmBgYAo=