1 Trying out alternative splicing tools, starting with suppa

index.html

2 Suppa fun, version: 20180302

## This assumes salmon has run happily on all the samples in the cwd.

## This first command collects the salmon data and makes a table of tpm by sample.
multipleFieldSelection.py -i $(find -L . -name 'quant.sf') \
                          -k 1 \
                          -f 4 \
                          -o iso_tpm.txt

## Unfortunately, the previous step provides ensembl transcript IDs looking like:
## 'ENSTxxxx.1' rather than the canonical 'ENSTxxxx'
## The following step strips off the trailing .number
format_Ensembl_ids.R iso_tpm.txt

## Now make a library of splicing events (SE,SS,MX,RI,FL) from our annotations in the ioe format.
suppa.py generateEvents \
         -i ~/scratch/libraries/genome/hg38_91.gtf \
         -o hg38_19.events \
         -e SE SS MX RI FL \
         -f ioe

## Combine them into a single file (why the hell the previous step doesn't do this beats me)
awk '
    FNR==1 && NR!=1 { while (/^<header>/) getline; }
    1 {print}
' *.ioe > ensembl_hg38.events.ioe

## Calculate the psi score using the tpms for the events just collated.
suppa.py psiPerEvent \
         --ioe-file ensembl_hg38.events.ioe \
         --expression-file iso_tpm_formatted.txt \
         -o events \
         2>psi_per_event.out 1>&2

## Calculate the same metrics by isoform rather than event.
suppa.py psiPerIsoform \
         -g ~/scratch/libraries/genome/hg38_91.gtf \
         -e iso_tpm_formatted.txt \
         -o uninf_inf \
         2>psi_per_iso.out 1>&2

## Now make separate files of the infected and uninfected samples (this is also dumb imo)
split_file.R events.psi \
             HPGL0082_R1_filtered_trimmed.fastq,HPGL0086_R1_filtered_trimmed.fastq,HPGL0090_R1_filtered_trimmed.fastq \
             HPGL0083_R1_filtered_trimmed.fastq,HPGL0087_R1_filtered_trimmed.fastq,HPGL0091_R1_filtered_trimmed.fastq,HPGL0330_R1_filtered_trimmed.fastq,HPGL0331_R1_filtered_trimmed.fastq,HPGL0332_R1_filtered_trimmed.fastq \
             uninf_events.psi \
             inf_events.psi \
             -e

split_file.R uninf_inf_isoforms.psi \
             HPGL0082_R1_filtered_trimmed.fastq,HPGL0086_R1_filtered_trimmed.fastq,HPGL0090_R1_filtered_trimmed.fastq \
             HPGL0083_R1_filtered_trimmed.fastq,HPGL0087_R1_filtered_trimmed.fastq,HPGL0091_R1_filtered_trimmed.fastq,HPGL0330_R1_filtered_trimmed.fastq,HPGL0331_R1_filtered_trimmed.fastq,HPGL0332_R1_filtered_trimmed.fastq \
             uninf_isoforms.psi \
             inf_isoforms.psi \
             -e

## Using the split tpms, split psi by event, and the catalog of events;
## calculate differential splicing metrics.
## Make sure to use --save-tpm-events so that we get a bridge between ENSG->ENST->tpm->psi
suppa.py diffSplice \
         -m empirical \
         -gc -i ensembl_hg38.events.ioe \
         -p uninf_events.psi inf_events.psi \
         -e uninf.tpm inf.tpm \
         -o uninf_inf_diffsplice \
         --save_tpm_events \
         2>diffsplice_event.out 1>&2

suppa.py diffSplice \
         -m empirical \
         -gc -i ensembl_hg38.events.ioe \
         -p uninf_isoforms.psi inf_isoforms.psi \
         -e uninf.tpm inf.tpm \
         -o uninf_inf_isoform_diffsplice \
         --save_tpm_events \
         2>diffsplice_uninf_isoform.out 1>&2

suppa.py diffSplice \
         -m empirical \
         -gc -i ensembl_hg38.events.ioe \
         -p uninf_isoforms.psi \
         -e uninf.tpm \
         -o uninf_isoform_diffsplice \
         --save_tpm_events \
         2>diffsplice_uninf_isoform.out 1>&2

suppa.py diffSplice \
         -m empirical \
         -gc -i ensembl_hg38.events.ioe \
         -p inf_isoforms.psi \
         -e inf.tpm \
         -o inf_isoform_diffsplice \
         --save_tpm_events \
         2>diffsplice_inf_isoform.out 1>&2

## We don't have sufficient samples for clustering.
## suppa.py clusterEvents \
##          --dpsi uninf_inf_diffsplice.dpsi \
##          --psivec uninf_inf_diffsplice.psivec \
##          --sig-threshold 0.05 \
##          --eps 0.2 \
##          --separation 0.11 \
##          -dt 0.2 \
##          --min-pts 10 \
##          -c OPTICS \
##          -o optics

Well, to be honest, I am moving backwards, I tried the various commands last night and will try to plot the results now, rather than, you know, the actual order that I did things…

## Warning: Removed 43147 rows containing missing values (geom_point).

dpsi pvalue avglogtpm log10pval adjp psig adjpsig gene_name category coordinates plot_cat event alternative_transcripts total_transcripts denominator1 denominator2 denominator3 numerator1 numerator2 numerator3 numerator4 numerator5 numerator6
ENSG00000000003;A5:X:100635746-100636191:100635746-100636608:- NaN 1.0000 -0.3956 0.0000 1.0000 FALSE FALSE ENSG00000000003 Alternate 5 prime X:100635746-100636191:100635746-100636608:- Insignificant ENSG00000000003;A5:X:100635746-100636191:100635746-100636608:- ENST00000496771 ENST00000496771,ENST00000373020 NaN NaN NaN NaN NaN NaN NaN NaN NaN
ENSG00000000003;A5:X:100635746-100636608:100635746-100636793:- NaN 1.0000 -0.0988 0.0000 1.0000 FALSE FALSE ENSG00000000003 Alternate 5 prime X:100635746-100636608:100635746-100636793:- Insignificant ENSG00000000003;A5:X:100635746-100636608:100635746-100636793:- ENST00000373020 ENST00000373020,ENST00000612152,ENST00000614008,ENST00000494424 NaN NaN NaN NaN NaN NaN NaN NaN NaN
ENSG00000000003;SE:X:100630866-100632485:100632568-100633405:- -0.0875 0.2023 -0.1432 0.6940 0.9302 FALSE FALSE ENSG00000000003 Skipping exon X:100630866-100632485:100632568-100633405:- Insignificant ENSG00000000003;SE:X:100630866-100632485:100632568-100633405:- ENST00000373020 ENST00000373020,ENST00000612152 1.0000 0.5826 0.4456 0.8273 0.8367 0.4118 0.1723 1.0000 0.2833
ENSG00000000419;A3:20:50940955-50941105:50940933-50941105:- NaN 1.0000 0.8031 0.0000 1.0000 FALSE FALSE ENSG00000000419 Alternate 3 prime 20:50940955-50941105:50940933-50941105:- Insignificant ENSG00000000419;A3:20:50940955-50941105:50940933-50941105:- ENST00000494752 ENST00000494752,ENST00000371584 NaN NaN NaN NaN NaN NaN NaN NaN NaN
ENSG00000000419;A3:20:50940955-50942031:50940933-50942031:- NaN 1.0000 1.3710 0.0000 1.0000 FALSE FALSE ENSG00000000419 Alternate 3 prime 20:50940955-50942031:50940933-50942031:- Insignificant ENSG00000000419;A3:20:50940955-50942031:50940933-50942031:- ENST00000466152 ENST00000466152,ENST00000371588 NaN NaN NaN NaN NaN NaN NaN NaN NaN
ENSG00000000419;A5:20:50940933-50941105:50940933-50941129:- -0.0806 0.2907 0.9346 0.5365 0.9302 FALSE FALSE ENSG00000000419 Alternate 5 prime 20:50940933-50941105:50940933-50941129:- Insignificant ENSG00000000419;A5:20:50940933-50941105:50940933-50941129:- ENST00000371584 ENST00000413082,ENST00000371582,ENST00000371584 0.8497 0.7415 0.7522 0.7260 0.7368 0.6626 0.6987 0.6559 0.7234
## The biomart annotations file already exists, loading from it.
## Saving to: excel/suppa_table.xlsx

3 TODO

  • 2017-06-14:
## If you wish to reproduce this exact build of hpgltools, invoke the following:
## > git clone http://github.com/abelew/hpgltools.git
## > git reset 1b009834267dea125ee94934203413fbd606e783
## R> packrat::restore()
## This is hpgltools commit: Mon Apr 23 14:59:56 2018 -0400: 1b009834267dea125ee94934203413fbd606e783
## Saving to 03_suppa_invocation-v20180302.rda.xz

R version 3.4.4 (2018-03-15)

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

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

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

other attached packages: hpgltools(v.2018.03)

loaded via a namespace (and not attached): Rcpp(v.0.12.16), highr(v.0.6), compiler(v.3.4.4), pillar(v.1.2.1), plyr(v.1.8.4), base64enc(v.0.1-3), iterators(v.1.0.9), tools(v.3.4.4), digest(v.0.6.15), evaluate(v.0.10.1), memoise(v.1.1.0), tibble(v.1.4.2), gtable(v.0.2.0), rlang(v.0.2.0.9001), openxlsx(v.4.0.17), foreach(v.1.4.4), commonmark(v.1.4), ggrepel(v.0.7.0), yaml(v.2.1.18), parallel(v.3.4.4), withr(v.2.1.2), stringr(v.1.3.0), knitr(v.1.20), roxygen2(v.6.0.1), xml2(v.1.2.0), devtools(v.1.13.5), rprojroot(v.1.3-2), grid(v.3.4.4), data.table(v.1.10.4-3), Biobase(v.2.38.0), R6(v.2.2.2), rmarkdown(v.1.9), pander(v.0.6.1), ggplot2(v.2.2.1), magrittr(v.1.5), backports(v.1.1.2), scales(v.0.5.0.9000), codetools(v.0.2-15), htmltools(v.0.3.6), BiocGenerics(v.0.24.0), colorspace(v.1.3-2), labeling(v.0.3), stringi(v.1.1.7), lazyeval(v.0.2.1) and munsell(v.0.4.3)

LS0tCnRpdGxlOiAiTS50dWJlcmN1bG9zaXMgMjAxODogQWx0ZXJuYXRpdmUgc3BsaWNpbmcsIHN1cHBhLiIKYXV0aG9yOiAiYXRiIGFiZWxld0BnbWFpbC5jb20iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogaHRtbF9kb2N1bWVudDoKICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgY29kZV9mb2xkaW5nOiBzaG93CiAgZmlnX2NhcHRpb246IHRydWUKICBmaWdfaGVpZ2h0OiA3CiAgZmlnX3dpZHRoOiA3CiAgaGlnaGxpZ2h0OiB0YW5nbwogIGtlZXBfbWQ6IGZhbHNlCiAgbW9kZTogc2VsZmNvbnRhaW5lZAogIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgdGhlbWU6IGNvc21vCiAgdG9jOiB0cnVlCiAgdG9jX2Zsb2F0OgogICAgY29sbGFwc2VkOiBmYWxzZQogICAgc21vb3RoX3Njcm9sbDogZmFsc2UKLS0tCgo8c3R5bGU+CiAgYm9keSAubWFpbi1jb250YWluZXIgewogICAgbWF4LXdpZHRoOiAxNjAwcHg7Cn0KPC9zdHlsZT4KCmBgYHtyIG9wdGlvbnMsIGluY2x1ZGU9RkFMU0V9CmlmICghaXNUUlVFKGdldDAoInNraXBfbG9hZCIpKSkgewogIGxpYnJhcnkoImhwZ2x0b29scyIpCiAgdHQgPC0gZGV2dG9vbHM6OmxvYWRfYWxsKCJ+L2hwZ2x0b29scyIpCiAga25pdHI6Om9wdHNfa25pdCRzZXQocHJvZ3Jlc3M9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgICB2ZXJib3NlPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg9OTAsCiAgICAgICAgICAgICAgICAgICAgICAgZWNobz1UUlVFKQogIGtuaXRyOjpvcHRzX2NodW5rJHNldChlcnJvcj1UUlVFLAogICAgICAgICAgICAgICAgICAgICAgICBmaWcud2lkdGg9OCwKICAgICAgICAgICAgICAgICAgICAgICAgZmlnLmhlaWdodD04LAogICAgICAgICAgICAgICAgICAgICAgICBkcGk9OTYpCiAgb3B0aW9ucyhkaWdpdHM9NCwKICAgICAgICAgIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UsCiAgICAgICAgICBrbml0ci5kdXBsaWNhdGUubGFiZWw9ImFsbG93IikKICBnZ3Bsb3QyOjp0aGVtZV9zZXQoZ2dwbG90Mjo6dGhlbWVfYncoYmFzZV9zaXplPTEwKSkKICBzZXQuc2VlZCgxKQogIHZlciA8LSAiMjAxODAzMDIiCiAgcHJldmlvdXNfZmlsZSA8LSAiaW5kZXguUm1kIgoKICB0bXAgPC0gdHJ5KHNtKGxvYWRtZShmaWxlbmFtZT1wYXN0ZTAoZ3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSIiLCB4PXByZXZpb3VzX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikpKSkKICBybWRfZmlsZSA8LSAiMDNfc3VwcGFfaW52b2NhdGlvbi5SbWQiCn0KYGBgCgpUcnlpbmcgb3V0IGFsdGVybmF0aXZlIHNwbGljaW5nIHRvb2xzLCBzdGFydGluZyB3aXRoIHN1cHBhCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCltpbmRleC5odG1sXShpbmRleC5odG1sKQoKIyBTdXBwYSBmdW4sIHZlcnNpb246IGByIHZlcmAKCmBgYHtiYXNoIHN1cHBfaW52b2NhdGlvbnMsIGV2YWw9RkFMU0V9CiMjIFRoaXMgYXNzdW1lcyBzYWxtb24gaGFzIHJ1biBoYXBwaWx5IG9uIGFsbCB0aGUgc2FtcGxlcyBpbiB0aGUgY3dkLgoKIyMgVGhpcyBmaXJzdCBjb21tYW5kIGNvbGxlY3RzIHRoZSBzYWxtb24gZGF0YSBhbmQgbWFrZXMgYSB0YWJsZSBvZiB0cG0gYnkgc2FtcGxlLgptdWx0aXBsZUZpZWxkU2VsZWN0aW9uLnB5IC1pICQoZmluZCAtTCAuIC1uYW1lICdxdWFudC5zZicpIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAtayAxIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAtZiA0IFwKICAgICAgICAgICAgICAgICAgICAgICAgICAtbyBpc29fdHBtLnR4dAoKIyMgVW5mb3J0dW5hdGVseSwgdGhlIHByZXZpb3VzIHN0ZXAgcHJvdmlkZXMgZW5zZW1ibCB0cmFuc2NyaXB0IElEcyBsb29raW5nIGxpa2U6CiMjICdFTlNUeHh4eC4xJyByYXRoZXIgdGhhbiB0aGUgY2Fub25pY2FsICdFTlNUeHh4eCcKIyMgVGhlIGZvbGxvd2luZyBzdGVwIHN0cmlwcyBvZmYgdGhlIHRyYWlsaW5nIC5udW1iZXIKZm9ybWF0X0Vuc2VtYmxfaWRzLlIgaXNvX3RwbS50eHQKCiMjIE5vdyBtYWtlIGEgbGlicmFyeSBvZiBzcGxpY2luZyBldmVudHMgKFNFLFNTLE1YLFJJLEZMKSBmcm9tIG91ciBhbm5vdGF0aW9ucyBpbiB0aGUgaW9lIGZvcm1hdC4Kc3VwcGEucHkgZ2VuZXJhdGVFdmVudHMgXAogICAgICAgICAtaSB+L3NjcmF0Y2gvbGlicmFyaWVzL2dlbm9tZS9oZzM4XzkxLmd0ZiBcCiAgICAgICAgIC1vIGhnMzhfMTkuZXZlbnRzIFwKICAgICAgICAgLWUgU0UgU1MgTVggUkkgRkwgXAogICAgICAgICAtZiBpb2UKCiMjIENvbWJpbmUgdGhlbSBpbnRvIGEgc2luZ2xlIGZpbGUgKHdoeSB0aGUgaGVsbCB0aGUgcHJldmlvdXMgc3RlcCBkb2Vzbid0IGRvIHRoaXMgYmVhdHMgbWUpCmF3ayAnCiAgICBGTlI9PTEgJiYgTlIhPTEgeyB3aGlsZSAoL148aGVhZGVyPi8pIGdldGxpbmU7IH0KICAgIDEge3ByaW50fQonICouaW9lID4gZW5zZW1ibF9oZzM4LmV2ZW50cy5pb2UKCiMjIENhbGN1bGF0ZSB0aGUgcHNpIHNjb3JlIHVzaW5nIHRoZSB0cG1zIGZvciB0aGUgZXZlbnRzIGp1c3QgY29sbGF0ZWQuCnN1cHBhLnB5IHBzaVBlckV2ZW50IFwKICAgICAgICAgLS1pb2UtZmlsZSBlbnNlbWJsX2hnMzguZXZlbnRzLmlvZSBcCiAgICAgICAgIC0tZXhwcmVzc2lvbi1maWxlIGlzb190cG1fZm9ybWF0dGVkLnR4dCBcCiAgICAgICAgIC1vIGV2ZW50cyBcCiAgICAgICAgIDI+cHNpX3Blcl9ldmVudC5vdXQgMT4mMgoKIyMgQ2FsY3VsYXRlIHRoZSBzYW1lIG1ldHJpY3MgYnkgaXNvZm9ybSByYXRoZXIgdGhhbiBldmVudC4Kc3VwcGEucHkgcHNpUGVySXNvZm9ybSBcCiAgICAgICAgIC1nIH4vc2NyYXRjaC9saWJyYXJpZXMvZ2Vub21lL2hnMzhfOTEuZ3RmIFwKICAgICAgICAgLWUgaXNvX3RwbV9mb3JtYXR0ZWQudHh0IFwKICAgICAgICAgLW8gdW5pbmZfaW5mIFwKICAgICAgICAgMj5wc2lfcGVyX2lzby5vdXQgMT4mMgoKIyMgTm93IG1ha2Ugc2VwYXJhdGUgZmlsZXMgb2YgdGhlIGluZmVjdGVkIGFuZCB1bmluZmVjdGVkIHNhbXBsZXMgKHRoaXMgaXMgYWxzbyBkdW1iIGltbykKc3BsaXRfZmlsZS5SIGV2ZW50cy5wc2kgXAogICAgICAgICAgICAgSFBHTDAwODJfUjFfZmlsdGVyZWRfdHJpbW1lZC5mYXN0cSxIUEdMMDA4Nl9SMV9maWx0ZXJlZF90cmltbWVkLmZhc3RxLEhQR0wwMDkwX1IxX2ZpbHRlcmVkX3RyaW1tZWQuZmFzdHEgXAogICAgICAgICAgICAgSFBHTDAwODNfUjFfZmlsdGVyZWRfdHJpbW1lZC5mYXN0cSxIUEdMMDA4N19SMV9maWx0ZXJlZF90cmltbWVkLmZhc3RxLEhQR0wwMDkxX1IxX2ZpbHRlcmVkX3RyaW1tZWQuZmFzdHEsSFBHTDAzMzBfUjFfZmlsdGVyZWRfdHJpbW1lZC5mYXN0cSxIUEdMMDMzMV9SMV9maWx0ZXJlZF90cmltbWVkLmZhc3RxLEhQR0wwMzMyX1IxX2ZpbHRlcmVkX3RyaW1tZWQuZmFzdHEgXAogICAgICAgICAgICAgdW5pbmZfZXZlbnRzLnBzaSBcCiAgICAgICAgICAgICBpbmZfZXZlbnRzLnBzaSBcCiAgICAgICAgICAgICAtZQoKc3BsaXRfZmlsZS5SIHVuaW5mX2luZl9pc29mb3Jtcy5wc2kgXAogICAgICAgICAgICAgSFBHTDAwODJfUjFfZmlsdGVyZWRfdHJpbW1lZC5mYXN0cSxIUEdMMDA4Nl9SMV9maWx0ZXJlZF90cmltbWVkLmZhc3RxLEhQR0wwMDkwX1IxX2ZpbHRlcmVkX3RyaW1tZWQuZmFzdHEgXAogICAgICAgICAgICAgSFBHTDAwODNfUjFfZmlsdGVyZWRfdHJpbW1lZC5mYXN0cSxIUEdMMDA4N19SMV9maWx0ZXJlZF90cmltbWVkLmZhc3RxLEhQR0wwMDkxX1IxX2ZpbHRlcmVkX3RyaW1tZWQuZmFzdHEsSFBHTDAzMzBfUjFfZmlsdGVyZWRfdHJpbW1lZC5mYXN0cSxIUEdMMDMzMV9SMV9maWx0ZXJlZF90cmltbWVkLmZhc3RxLEhQR0wwMzMyX1IxX2ZpbHRlcmVkX3RyaW1tZWQuZmFzdHEgXAogICAgICAgICAgICAgdW5pbmZfaXNvZm9ybXMucHNpIFwKICAgICAgICAgICAgIGluZl9pc29mb3Jtcy5wc2kgXAogICAgICAgICAgICAgLWUKCiMjIFVzaW5nIHRoZSBzcGxpdCB0cG1zLCBzcGxpdCBwc2kgYnkgZXZlbnQsIGFuZCB0aGUgY2F0YWxvZyBvZiBldmVudHM7CiMjIGNhbGN1bGF0ZSBkaWZmZXJlbnRpYWwgc3BsaWNpbmcgbWV0cmljcy4KIyMgTWFrZSBzdXJlIHRvIHVzZSAtLXNhdmUtdHBtLWV2ZW50cyBzbyB0aGF0IHdlIGdldCBhIGJyaWRnZSBiZXR3ZWVuIEVOU0ctPkVOU1QtPnRwbS0+cHNpCnN1cHBhLnB5IGRpZmZTcGxpY2UgXAogICAgICAgICAtbSBlbXBpcmljYWwgXAogICAgICAgICAtZ2MgLWkgZW5zZW1ibF9oZzM4LmV2ZW50cy5pb2UgXAogICAgICAgICAtcCB1bmluZl9ldmVudHMucHNpIGluZl9ldmVudHMucHNpIFwKICAgICAgICAgLWUgdW5pbmYudHBtIGluZi50cG0gXAogICAgICAgICAtbyB1bmluZl9pbmZfZGlmZnNwbGljZSBcCiAgICAgICAgIC0tc2F2ZV90cG1fZXZlbnRzIFwKICAgICAgICAgMj5kaWZmc3BsaWNlX2V2ZW50Lm91dCAxPiYyCgpzdXBwYS5weSBkaWZmU3BsaWNlIFwKICAgICAgICAgLW0gZW1waXJpY2FsIFwKICAgICAgICAgLWdjIC1pIGVuc2VtYmxfaGczOC5ldmVudHMuaW9lIFwKICAgICAgICAgLXAgdW5pbmZfaXNvZm9ybXMucHNpIGluZl9pc29mb3Jtcy5wc2kgXAogICAgICAgICAtZSB1bmluZi50cG0gaW5mLnRwbSBcCiAgICAgICAgIC1vIHVuaW5mX2luZl9pc29mb3JtX2RpZmZzcGxpY2UgXAogICAgICAgICAtLXNhdmVfdHBtX2V2ZW50cyBcCiAgICAgICAgIDI+ZGlmZnNwbGljZV91bmluZl9pc29mb3JtLm91dCAxPiYyCgpzdXBwYS5weSBkaWZmU3BsaWNlIFwKICAgICAgICAgLW0gZW1waXJpY2FsIFwKICAgICAgICAgLWdjIC1pIGVuc2VtYmxfaGczOC5ldmVudHMuaW9lIFwKICAgICAgICAgLXAgdW5pbmZfaXNvZm9ybXMucHNpIFwKICAgICAgICAgLWUgdW5pbmYudHBtIFwKICAgICAgICAgLW8gdW5pbmZfaXNvZm9ybV9kaWZmc3BsaWNlIFwKICAgICAgICAgLS1zYXZlX3RwbV9ldmVudHMgXAogICAgICAgICAyPmRpZmZzcGxpY2VfdW5pbmZfaXNvZm9ybS5vdXQgMT4mMgoKc3VwcGEucHkgZGlmZlNwbGljZSBcCiAgICAgICAgIC1tIGVtcGlyaWNhbCBcCiAgICAgICAgIC1nYyAtaSBlbnNlbWJsX2hnMzguZXZlbnRzLmlvZSBcCiAgICAgICAgIC1wIGluZl9pc29mb3Jtcy5wc2kgXAogICAgICAgICAtZSBpbmYudHBtIFwKICAgICAgICAgLW8gaW5mX2lzb2Zvcm1fZGlmZnNwbGljZSBcCiAgICAgICAgIC0tc2F2ZV90cG1fZXZlbnRzIFwKICAgICAgICAgMj5kaWZmc3BsaWNlX2luZl9pc29mb3JtLm91dCAxPiYyCgojIyBXZSBkb24ndCBoYXZlIHN1ZmZpY2llbnQgc2FtcGxlcyBmb3IgY2x1c3RlcmluZy4KIyMgc3VwcGEucHkgY2x1c3RlckV2ZW50cyBcCiMjICAgICAgICAgIC0tZHBzaSB1bmluZl9pbmZfZGlmZnNwbGljZS5kcHNpIFwKIyMgICAgICAgICAgLS1wc2l2ZWMgdW5pbmZfaW5mX2RpZmZzcGxpY2UucHNpdmVjIFwKIyMgICAgICAgICAgLS1zaWctdGhyZXNob2xkIDAuMDUgXAojIyAgICAgICAgICAtLWVwcyAwLjIgXAojIyAgICAgICAgICAtLXNlcGFyYXRpb24gMC4xMSBcCiMjICAgICAgICAgIC1kdCAwLjIgXAojIyAgICAgICAgICAtLW1pbi1wdHMgMTAgXAojIyAgICAgICAgICAtYyBPUFRJQ1MgXAojIyAgICAgICAgICAtbyBvcHRpY3MKYGBgCgpXZWxsLCB0byBiZSBob25lc3QsIEkgYW0gbW92aW5nIGJhY2t3YXJkcywgSSB0cmllZCB0aGUgdmFyaW91cyBjb21tYW5kcyBsYXN0Cm5pZ2h0IGFuZCB3aWxsIHRyeSB0byBwbG90IHRoZSByZXN1bHRzIG5vdywgcmF0aGVyIHRoYW4sIHlvdSBrbm93LCB0aGUKYWN0dWFsIG9yZGVyIHRoYXQgSSBkaWQgdGhpbmdzLi4uCgpgYGB7ciBwbG90X3N1cHBhfQpiYXNlZGlyIDwtICJwcmVwcm9jZXNzaW5nL291dHB1dHMvc3VwcGFfaGczOF85MSIKZHBzaV9maWxlIDwtIGZpbGUucGF0aChiYXNlZGlyLCAidW5pbmZfaW5mX2RpZmZzcGxpY2UuZHBzaSIpCnRwbV9maWxlIDwtIGZpbGUucGF0aChiYXNlZGlyLCAidW5pbmZfaW5mX2RpZmZzcGxpY2VfYXZnbG9ndHBtLnRhYiIpCmV2ZW50c19maWxlIDwtIGZpbGUucGF0aChiYXNlZGlyLCAiZW5zZW1ibF9oZzM4LmV2ZW50cy5pb2UiKQpwc2lfZmlsZSA8LSBmaWxlLnBhdGgoYmFzZWRpciwgInVuaW5mX2luZl9kaWZmc3BsaWNlLnBzaXZlYyIpCgppbml0aWFsX3N1cHBhX3Bsb3RzIDwtIHBsb3Rfc3VwcGEoZHBzaV9maWxlLCB0cG1fZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cz1ldmVudHNfZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsX3R5cGU9IlNraXBwaW5nIGV4b24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHNpPXBzaV9maWxlKQppbml0aWFsX3N1cHBhX3Bsb3RzJG1hCgpzdXBwYV9kZiA8LSBpbml0aWFsX3N1cHBhX3Bsb3RzJGRhdGEKa25pdHI6OmthYmxlKGhlYWQoc3VwcGFfZGYpKQphbm5vdGF0aW9uIDwtIGxvYWRfYmlvbWFydF9hbm5vdGF0aW9ucygpW1siYW5ub3RhdGlvbiJdXQoKc3R1ZmYgPC0gd3JpdGVfc3VwcGFfdGFibGUoc3VwcGFfZGYsIGFubm90YXRpb25zPWFubm90YXRpb24pCgpyZXRhaW5lZF9pZHggPC0gc3VwcGFfZGZbWyJjYXRlZ29yeSJdXSA9PSAiUmV0YWluZWQgaW50cm9uIgpyZXRhaW5lZF9zdXBwYSA8LSBzdXBwYV9kZltyZXRhaW5lZF9pZHgsIF0KYGBgCgojIFRPRE8KCiogMjAxNy0wNi0xNDoKCmBgYHtyIHNhdmVtZX0KaWYgKCFpc1RSVUUoZ2V0MCgic2tpcF9sb2FkIikpKSB7CiAgbWVzc2FnZShwYXN0ZTAoIlRoaXMgaXMgaHBnbHRvb2xzIGNvbW1pdDogIiwgZ2V0X2dpdF9jb21taXQoKSkpCiAgdGhpc19zYXZlIDwtIHBhc3RlMChnc3ViKHBhdHRlcm49IlxcLlJtZCIsIHJlcGxhY2U9IiIsIHg9cm1kX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikKICBtZXNzYWdlKHBhc3RlMCgiU2F2aW5nIHRvICIsIHRoaXNfc2F2ZSkpCiAgdG1wIDwtIHNtKHNhdmVtZShmaWxlbmFtZT10aGlzX3NhdmUpKQogIHBhbmRlcjo6cGFuZGVyKHNlc3Npb25JbmZvKCkpCn0KYGBgCg==