Purpose

This pipeline is intended to:

As the lab is beginning to shift towards running many of these libraries a simple python script was produced to automate much of the repetition in this process.

Requirements

This document assumes you ran paired-end RNAseq with UMIs and have access to the FASTQ files.

This document heavily focuses on using a small python script called Windchime to handle sbatch shell generation. When ran it will generate two sbatch shell scripts. The first script will align reads using STAR and deduplicate reads using UMI-tools. The second sbatch shell script uses bedtools genomecov to calculate read coverage for each genome feature.

Step zero - Set up environment

Step one - Setup configuration File

Windchime uses a tab delimited configuration file to define necessary parameters and samples for the run. These come in two varieties: samples with replicates (Table 1) and without (Table 2).

Each table requires the same kinds of run parameters (noted as ‘meta’ in column 1). Lines can be commented out by using a hash ‘#’ character at the start of the line.

Table 1 - Example of configuration file for samples with replicates

#data_type  variable    value
meta    set_name    Project_Windchime_HGG72DRXY
meta    data_dir    /scratch/cgsb/gencore/out/Gresham/2021-08-09_HGG72DRXY/merged/
meta    work_dir    /scratch/cgsb/gresham/LABSHARE/Data/HGG72DRXY/
meta    output_dir  /scratch/cgsb/gresham/LABSHARE/Data/HGG72DRXY/results/
meta    genome_fa   /scratch/cgsb/gresham/pieter/genome/ensembl_50/Saccharomyces_cerevisiae.R64-1-1.dna.toplevel.fa
meta    genome_features /scratch/cgsb/gresham/pieter/genome/Saccharomyces_cerevisiae.R64-1-1.dna.toplevel.gtf
meta    intron_max  100
meta    adapter_seq_R1  AGATCGGAAGAGCACACGTCTGAACTCCAGTCA
meta    adapter_seq_R2  AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGT
meta    prefix  HGG72DRXY
meta    fastq_name_template {prefix}_n01_{strain}_{replicate}
meta    qc_locus  XII:451439-468985
sample  1   1
sample  1   2
sample  1   3
sample  1222    1
sample  1222    2
sample  1222    3

Table 2 - Example of configuration file for samples without replicates

#data_type  variable    value
meta    set_name    Project_CAlbicans
meta    data_dir    /scratch/cgsb/gencore/out/Gresham/2021-10-25_HK7CCDRXY/merged/
meta    work_dir    /scratch/cgsb/gresham/LABSHARE/Data/HK7CCDRXY/
meta    output_dir  /scratch/cgsb/gresham/LABSHARE/Data/HK7CCDRXY/results/
meta    genome_fa   /scratch/cgsb/gresham/pieter/genome/Candida_albicans_sc5314/C_albicans_SC5314_A22_current_chromosomes.fasta
meta    genome_features /scratch/cgsb/gresham/pieter/genome/Candida_albicans_sc5314/C_albicans_SC5314_A22_current_features.gff
meta    intron_max  500
meta    adapter_seq_R1  AGATCGGAAGAGCACACGTCTGAACTCCAGTCA
meta    adapter_seq_R2  AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGT
meta    prefix  HK7CCDRXY
meta    fastq_name_template {prefix}_n01_{strain}
meta    qc_locus    Ca22chrRA_C_albicans_SC5314:1891108-1896912
sample  CAWT1_C-LIM_2H
sample  CAWT1_C-LIM_5H

Step two - Make STAR alignment sbatch file

python windchime.py -a -i cfg_file.tab -o run_windchime_star.sh
# -a 'alignment' flag
# [optional] -rep flag, include if you ar using replicates
# [optional] -mem flag, set sbatch memory allocation in GB. (Default 60GB)
# -i input configuration file name
# -o output STAR sbatch file name

sbatch run_windchime_star.sh

Step three - Evaluate summary performance statistics

python windchime.py -e -i cfg_file.tab -o evaluate_run.txt
# -e 'evaluate' flag
# [optional] -rep flag, include if you ar using replicates
# -i input configuration file name
# -o output evaluation statistics file name

Step four - Calculate sequence rarefaction

python windchime.py -r -i ctrl_file.tab
# -r 'rarefaction' flag
# [optional] -rep flag, include if you ar using replicates
# [optional] -tol parameter, allows you to specify the percent tolerance point (default 50)
# -i input configuration file name

Step five - Calculate coverage of aligned reads to genome features

python windchime.py -c -i cfg_file.tab -o coverage_run.sh
# -c 'coverage' flag
# [optional] -rep flag, include if you ar using replicates
# [optional] -mem flag, set sbatch memory allocation in GB. (Default 60GB)
# -i input configuration file name
# -o output coverage sbatch file name

sbatch coverage_run.sh

Step six - combine feature coverage counts into a single table

python windchime.py -t -i cfg_file.tab -o coverage_table.txt
# -t 'table' flag
# [optional] -rep flag, include if you ar using replicates
# -i input configuration file name
# -o output combined coverage table file name

Conclusion

After a successful run you should have the following files:

LS0tDQp0aXRsZTogIldpbmRjaGltZSBwaXBlbGluZSINCmF1dGhvcjogIlBpZXRlciBTcGVhbG1hbiINCmRhdGU6ICIxMS8yMS8yMDIxIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQoNCmBgYA0KIyMjIyBQdXJwb3NlDQpUaGlzIHBpcGVsaW5lIGlzIGludGVuZGVkIHRvOiANCg0KKiB0cmltIGFuZCBhbGlnbiBwYWlyZWQtZW5kIFJOQXNlcSByZWFkcyB3aXRoIFVNSXMgKHByZXN1bWFibHkgcHJvZHVjZWQgYnkgTGV4b2dlbiBDT1JBTEwgbGlicmFyeSBwcmVwIGtpdCkNCiogZGVkdXBsaWNhdGUgcmVhZHMgdXNpbmcgVU1Jcw0KKiBjYWxjdWxhdGUgVU1JIGR1cGxpY2F0aW9uIGFuZCByUk5BIGNvbnRhbWluYXRpb24NCiogY2FsY3VsYXRlIHVubm9ybWFsaXplZCByZWFkIGNvdmVyYWdlIHBlciBmZWF0dXJlIGZvciBhbGwgc2FtcGxlcyAoaW50ZW5kZWQgZm9yIHVzZSBpbiBERVNlcTIgYW5hbHlzaXMpIA0KDQpBcyB0aGUgbGFiIGlzIGJlZ2lubmluZyB0byBzaGlmdCB0b3dhcmRzIHJ1bm5pbmcgbWFueSBvZiB0aGVzZSBsaWJyYXJpZXMgYSBzaW1wbGUgcHl0aG9uIHNjcmlwdCB3YXMgcHJvZHVjZWQgdG8gYXV0b21hdGUgbXVjaCBvZiB0aGUgcmVwZXRpdGlvbiBpbiB0aGlzIHByb2Nlc3MuDQoNCiMjIyMgUmVxdWlyZW1lbnRzDQpUaGlzIGRvY3VtZW50IGFzc3VtZXMgeW91IHJhbiBwYWlyZWQtZW5kIFJOQXNlcSB3aXRoIFVNSXMgYW5kIGhhdmUgYWNjZXNzIHRvIHRoZSBGQVNUUSBmaWxlcy4gDQoNClRoaXMgZG9jdW1lbnQgaGVhdmlseSBmb2N1c2VzIG9uIHVzaW5nIGEgc21hbGwgcHl0aG9uIHNjcmlwdCBjYWxsZWQgV2luZGNoaW1lIHRvIGhhbmRsZSBzYmF0Y2ggc2hlbGwgZ2VuZXJhdGlvbi4gV2hlbiByYW4gaXQgd2lsbCBnZW5lcmF0ZSB0d28gc2JhdGNoIHNoZWxsIHNjcmlwdHMuIFRoZSBmaXJzdCBzY3JpcHQgd2lsbCBhbGlnbiByZWFkcyB1c2luZyBTVEFSIGFuZCBkZWR1cGxpY2F0ZSByZWFkcyB1c2luZyBVTUktdG9vbHMuIFRoZSBzZWNvbmQgc2JhdGNoIHNoZWxsIHNjcmlwdCB1c2VzIGJlZHRvb2xzIGdlbm9tZWNvdiB0byBjYWxjdWxhdGUgcmVhZCBjb3ZlcmFnZSBmb3IgZWFjaCBnZW5vbWUgZmVhdHVyZS4gDQoNCiMjIyMgU3RlcCB6ZXJvIC0gU2V0IHVwIGVudmlyb25tZW50DQoqIF9fVU1JLVRvb2xzX18gRm9yIFVNSS10b29scyB5b3Ugd2lsbCBuZWVkIHRvIGFjdGl2YXRlIGEgcHl0aG9uIDMuOCBlbnZpcm9ubWVudCB3aXRoIFVNSS10b29scyBpbnN0YWxsZWQ6DQogIGBgYA0KICBjb25kYSBjcmVhdGUgLW4gdW1pX3Rvb2xzIHB5dGhvbj0zLjgNCiAgY29uZGEgYWN0aXZhdGUgdW1pX3Rvb2xzDQogIGNvbmRhIGluc3RhbGwgLWMgYmlvY29uZGEgdW1pX3Rvb2xzDQogIGBgYA0KDQoqIF9fV2luZGNoaW1lX18gWW91IHdpbGwgYWxzbyBuZWVkIHRoZSB3aW5kY2hpbWUgc2NyaXB0IHdoaWNoIGlzIGF2YWlsYWJsZSBoZXJlOg0KICBgYGANCiAgZ2l0IGNsb25lIGh0dHBzOi8vZ2l0aHViLmNvbS9wc3BlYWxtYW4vd2luZGNoaW1lLmdpdA0KICBjZCB3aW5kY2hpbWUNCiAgcHdkDQogIGBgYA0KICBUaGlzIGlzIGEgc3RhbmRhbG9uZSBzY3JpcHQgd2hpY2ggcmVxdWlyZXMgb25seSB0aGUgc3RhbmRhcmQgcHl0aG9uICgzLjYrKSBwYWNrYWdlcy4gWW91IGNhbiBhbHdheXMgdXNlIGl0IGJ5IHBvaW50aW5nIHRvIHRoZSBkaXJlY3RvcnkgcHJpbnRlZCBvdXQgYWJvdmUgb3IgYnkgY29weWluZyB0aGUgc2NyaXB0IGludG8gYSBwcmVmZXJyZWQgZm9sZGVyLiANCg0KKiBfX3NydW5fXyBTdGVwcyAzLCA0LCBhbmQgNiBjYW4gY29uc3VtZSBzaWduaWZpY2FudCBjb21wdXRhdGlvbmFsIHJlc291cmNlcyBpbiBvcmRlciB0byBwcmVzZXJ2ZSB0aGVzZSByZXNvdXJjZXMgb24gdGhlIGxvZ2luIG5vZGVzIHlvdSBzaG91bGQgZW50ZXIgYW4gaW50ZXJhY3RpdmUgc2Vzc2lvbiBvbiBhIGNvbXB1dGF0aW9uYWwgbm9kZSB1c2luZyBzcnVuLiANCiAgYGBgDQogIHNydW4gLWMgMSAtdCAxMjowMDowMCAtLW1lbSAxMDAwMDAgLS1wdHkgL2Jpbi9iYXNoDQogIGBgYA0KICBfX05CX18gdGhlc2Ugc3J1biBwYXJhbWV0ZXJzIG1heSBuZWVkIHRvIGJlIG1vZGlmaWVkIGZvciBzbWFsbGVyIG9yIGxhcmdlciBkYXRhc2V0cy4gSWYgeW91IGNvbXBsZXRlIHN0ZXBzIDMsNCwgYW5kIDYgeW91IGNhbiBjbG9zZSB5b3VyIHNlc3Npb24gYnkgdHlwaW5nIGBgYGV4aXRgYGANCg0KIyMjIyBTdGVwIG9uZSAtIFNldHVwIGNvbmZpZ3VyYXRpb24gRmlsZQ0KDQpXaW5kY2hpbWUgdXNlcyBhIF9fdGFiIGRlbGltaXRlZF9fIGNvbmZpZ3VyYXRpb24gZmlsZSB0byBkZWZpbmUgbmVjZXNzYXJ5IHBhcmFtZXRlcnMgYW5kIHNhbXBsZXMgZm9yIHRoZSBydW4uIFRoZXNlIGNvbWUgaW4gdHdvIHZhcmlldGllczogc2FtcGxlcyB3aXRoIHJlcGxpY2F0ZXMgKFRhYmxlIDEpIGFuZCB3aXRob3V0IChUYWJsZSAyKS4gDQoNCkVhY2ggdGFibGUgcmVxdWlyZXMgdGhlIHNhbWUga2luZHMgb2YgcnVuIHBhcmFtZXRlcnMgKG5vdGVkIGFzICdtZXRhJyBpbiBjb2x1bW4gMSkuIExpbmVzIGNhbiBiZSBjb21tZW50ZWQgb3V0IGJ5IHVzaW5nIGEgaGFzaCAnIycgY2hhcmFjdGVyIGF0IHRoZSBzdGFydCBvZiB0aGUgbGluZS4NCg0KKiBzZXRfbmFtZSAtIHVzZXIgZGVmaW5lZCBuYW1lDQoqIGRhdGFfZGlyIC0gd2hlcmUgdGhlIGZhc3RxIGZpbGVzIGFyZSBzdG9yZWQNCiogd29ya19kaXIgLSB3aGVyZSB0aGUgdGVtcG9yYXJ5IGFuZCBydW4gZmlsZXMgYXJlIHN0b3JlZA0KKiBvdXRwdXRfZGlyIC0gd2hlcmUgdGhlIGZpbmFsIHJlc3VsdHMgYXJlIG91dHB1dA0KKiBnZW5vbWVfZmEgLSByZWZlcmVuY2UgZmFzdGEgZmlsZSAoeW91IG1heSBuZWVkIHRvIGNvcHkgaXQgbG9jYWxseSBmb3IgaW5kZXhpbmcgaXNzdWVzKQ0KKiBnZW5vbWVfZmVhdHVyZXMgLSBlaXRoZXIgR0ZGLCBHRkYzLCBvciBHVEYgZm9ybWF0IGZpbGUNCiogaW50cm9uX21heCAtIHNpemUgaW4gbnVjbGVvdGlkZXMgb2YgbWF4aW11bSBpbnRyb24NCiogYWRhcHRlcl9zZXFfUjEsIGFkYXB0ZXJfc2VxX1IyIC0gcmVhZCAxIGFuZCByZWFkIDIgYWRhcHRlciBzZXF1ZW5jZXMNCiogcHJlZml4IC0gcnVuIGlkLCB1c3VhbGx5IHN1cHBsaWVkIGJ5IHRoZSBzZXF1ZW5jaW5nIGNvcmUgKGVnLiBIR0cuLi4sIEhHSy4uLiwgZXRjLikNCiogZmFzdHFfbmFtZV90ZW1wbGF0ZSAtIHNpbmNlIHRoZSBmaWxlcyBnZW5lcmF0ZWQgYnkgZ2Vub3JlIGhhdmUgYWxsIGtpbmRzIG9mIGZpbGUgbmFtZSBjb252ZW50aW9ucyB0aGVyZSBtYXkgYmUgc2V2ZXJhbCB3YXlzIHlvdXIgZmFzdHEgZmlsZXMgaW5jb3Jwb3JhdGUgdGhlIGluZm9ybWF0aW9uIG9mIHRoZSBydW4gaWQgKHByZWZpeCksIHN0cmFpbiBvciBzYW1wbGUgKHN0cmFpbikgYW5kIHJlcGxpY2F0ZSAocmVwbGljYXRlKS4gVGhpcyBsaW5lIGFsbG93cyB5b3UgdG8gc2V0IHRoZXNlIHBhcmFtZXRlcnMgdXNpbmcgYSBzaW1wbGUgZm9ybWF0dGluZyBvcHRpb24gdXNpbmcgY3VybHkgYnJhY2tldHMgY29udGFpbmluZyB0aGUga2V5d29yZHMgJ3ByZWZpeCcsICdzdHJhaW4nLCBvciByZXBsaWNhdGUgKGlmIHlvdSBhcmUgdXNpbmcgdGhlIHJlcGxpY2F0ZSBmb3JtYXQpLiANCiogcWNfbG9jdXMgLSBsb2N1cyBjb29yZGluYXRlcyBmb3IgY2FsY3VsYXRpb24gb2YgclJOQSBjb250YW1pbmF0aW9uIChlZy4gY2hyb21vc29tZTpzdGFydC1zdG9wKQ0KIA0KICBgYGANCiAgZm9yIFNhY2NoYXJvbXljZXMgY2VyZXZpc2lhZSBTMjg4QyBSNjQ6IFhJSTo0NTE0MzktNDY4OTg1DQogIGZvciBDYW5kaWRhIGFsYmljYW5zIFNDIDUzMTQgQTIyOiBDYTIyY2hyUkFfQ19hbGJpY2Fuc19TQzUzMTQ6MTg5MTEwOC0xODk2OTEyDQogIGBgYA0KKiBzYW1wbGUgLSB1bmlxdWUgc2FtcGxlIG5hbWUgKGlmIHJlcGxpY2F0ZXMgYXJlIGJlaW5nIHVzZWQgdGhlIHNhbXBsZSBuYW1lIGFuZCByZXBsaWNhdGUgSUQgY29tYmluZWQgbXVzdCBiZSB1bmlxdWUpDQogDQojIyMjIFRhYmxlIDEgLSBFeGFtcGxlIG9mIGNvbmZpZ3VyYXRpb24gZmlsZSBmb3Igc2FtcGxlcyB3aXRoIHJlcGxpY2F0ZXMNCmBgYA0KI2RhdGFfdHlwZQl2YXJpYWJsZQl2YWx1ZQ0KbWV0YQlzZXRfbmFtZQlQcm9qZWN0X1dpbmRjaGltZV9IR0c3MkRSWFkNCm1ldGEJZGF0YV9kaXIJL3NjcmF0Y2gvY2dzYi9nZW5jb3JlL291dC9HcmVzaGFtLzIwMjEtMDgtMDlfSEdHNzJEUlhZL21lcmdlZC8NCm1ldGEJd29ya19kaXIJL3NjcmF0Y2gvY2dzYi9ncmVzaGFtL0xBQlNIQVJFL0RhdGEvSEdHNzJEUlhZLw0KbWV0YQlvdXRwdXRfZGlyCS9zY3JhdGNoL2Nnc2IvZ3Jlc2hhbS9MQUJTSEFSRS9EYXRhL0hHRzcyRFJYWS9yZXN1bHRzLw0KbWV0YQlnZW5vbWVfZmEJL3NjcmF0Y2gvY2dzYi9ncmVzaGFtL3BpZXRlci9nZW5vbWUvZW5zZW1ibF81MC9TYWNjaGFyb215Y2VzX2NlcmV2aXNpYWUuUjY0LTEtMS5kbmEudG9wbGV2ZWwuZmENCm1ldGEJZ2Vub21lX2ZlYXR1cmVzCS9zY3JhdGNoL2Nnc2IvZ3Jlc2hhbS9waWV0ZXIvZ2Vub21lL1NhY2NoYXJvbXljZXNfY2VyZXZpc2lhZS5SNjQtMS0xLmRuYS50b3BsZXZlbC5ndGYNCm1ldGEJaW50cm9uX21heAkxMDANCm1ldGEJYWRhcHRlcl9zZXFfUjEJQUdBVENHR0FBR0FHQ0FDQUNHVENUR0FBQ1RDQ0FHVENBDQptZXRhCWFkYXB0ZXJfc2VxX1IyCUFHQVRDR0dBQUdBR0NHVENHVEdUQUdHR0FBQUdBR1RHVA0KbWV0YQlwcmVmaXgJSEdHNzJEUlhZDQptZXRhCWZhc3RxX25hbWVfdGVtcGxhdGUJe3ByZWZpeH1fbjAxX3tzdHJhaW59X3tyZXBsaWNhdGV9DQptZXRhCXFjX2xvY3VzICBYSUk6NDUxNDM5LTQ2ODk4NQ0Kc2FtcGxlCTEJMQ0Kc2FtcGxlCTEJMg0Kc2FtcGxlCTEJMw0Kc2FtcGxlCTEyMjIJMQ0Kc2FtcGxlCTEyMjIJMg0Kc2FtcGxlCTEyMjIJMw0KYGBgDQoNCiMjIyMgVGFibGUgMiAtIEV4YW1wbGUgb2YgY29uZmlndXJhdGlvbiBmaWxlIGZvciBzYW1wbGVzIHdpdGhvdXQgcmVwbGljYXRlcw0KYGBgDQojZGF0YV90eXBlCXZhcmlhYmxlCXZhbHVlDQptZXRhCXNldF9uYW1lCVByb2plY3RfQ0FsYmljYW5zDQptZXRhCWRhdGFfZGlyCS9zY3JhdGNoL2Nnc2IvZ2VuY29yZS9vdXQvR3Jlc2hhbS8yMDIxLTEwLTI1X0hLN0NDRFJYWS9tZXJnZWQvDQptZXRhCXdvcmtfZGlyCS9zY3JhdGNoL2Nnc2IvZ3Jlc2hhbS9MQUJTSEFSRS9EYXRhL0hLN0NDRFJYWS8NCm1ldGEJb3V0cHV0X2Rpcgkvc2NyYXRjaC9jZ3NiL2dyZXNoYW0vTEFCU0hBUkUvRGF0YS9ISzdDQ0RSWFkvcmVzdWx0cy8NCm1ldGEJZ2Vub21lX2ZhCS9zY3JhdGNoL2Nnc2IvZ3Jlc2hhbS9waWV0ZXIvZ2Vub21lL0NhbmRpZGFfYWxiaWNhbnNfc2M1MzE0L0NfYWxiaWNhbnNfU0M1MzE0X0EyMl9jdXJyZW50X2Nocm9tb3NvbWVzLmZhc3RhDQptZXRhCWdlbm9tZV9mZWF0dXJlcwkvc2NyYXRjaC9jZ3NiL2dyZXNoYW0vcGlldGVyL2dlbm9tZS9DYW5kaWRhX2FsYmljYW5zX3NjNTMxNC9DX2FsYmljYW5zX1NDNTMxNF9BMjJfY3VycmVudF9mZWF0dXJlcy5nZmYNCm1ldGEJaW50cm9uX21heAk1MDANCm1ldGEJYWRhcHRlcl9zZXFfUjEJQUdBVENHR0FBR0FHQ0FDQUNHVENUR0FBQ1RDQ0FHVENBDQptZXRhCWFkYXB0ZXJfc2VxX1IyCUFHQVRDR0dBQUdBR0NHVENHVEdUQUdHR0FBQUdBR1RHVA0KbWV0YQlwcmVmaXgJSEs3Q0NEUlhZDQptZXRhCWZhc3RxX25hbWVfdGVtcGxhdGUJe3ByZWZpeH1fbjAxX3tzdHJhaW59DQptZXRhCXFjX2xvY3VzCUNhMjJjaHJSQV9DX2FsYmljYW5zX1NDNTMxNDoxODkxMTA4LTE4OTY5MTINCnNhbXBsZQlDQVdUMV9DLUxJTV8ySA0Kc2FtcGxlCUNBV1QxX0MtTElNXzVIDQpgYGANCiMjIyMgU3RlcCB0d28gLSBNYWtlIFNUQVIgYWxpZ25tZW50IHNiYXRjaCBmaWxlDQpgYGANCnB5dGhvbiB3aW5kY2hpbWUucHkgLWEgLWkgY2ZnX2ZpbGUudGFiIC1vIHJ1bl93aW5kY2hpbWVfc3Rhci5zaA0KIyAtYSAnYWxpZ25tZW50JyBmbGFnDQojIFtvcHRpb25hbF0gLXJlcCBmbGFnLCBpbmNsdWRlIGlmIHlvdSBhciB1c2luZyByZXBsaWNhdGVzDQojIFtvcHRpb25hbF0gLW1lbSBmbGFnLCBzZXQgc2JhdGNoIG1lbW9yeSBhbGxvY2F0aW9uIGluIEdCLiAoRGVmYXVsdCA2MEdCKQ0KIyAtaSBpbnB1dCBjb25maWd1cmF0aW9uIGZpbGUgbmFtZQ0KIyAtbyBvdXRwdXQgU1RBUiBzYmF0Y2ggZmlsZSBuYW1lDQoNCnNiYXRjaCBydW5fd2luZGNoaW1lX3N0YXIuc2gNCmBgYA0KKiBUaGUgYWJvdmUgY29kZSB3aWxsIGdlbmVyYXRlIGEgX19iYXNoIHNjcmlwdCAicnVuX3dpbmRjaGltZV9zdGFyLnNoIl9fIHVzaW5nIHRoZSBpbmZvcm1hdGlvbiBnaXZlbiBpbiB0aGUgX18taV9fIGlucHV0IGNvbmZpZ3VyYXRpb24gZmlsZS4gX0lmIGJlaW5nIHVzZWQgd2l0aCByZXBsaWNhdGVzIGluY2x1ZGUgdGhlIC1yZXAgZmxhZ18NCg0KDQojIyMjIFN0ZXAgdGhyZWUgLSBFdmFsdWF0ZSBzdW1tYXJ5IHBlcmZvcm1hbmNlIHN0YXRpc3RpY3MNCmBgYA0KcHl0aG9uIHdpbmRjaGltZS5weSAtZSAtaSBjZmdfZmlsZS50YWIgLW8gZXZhbHVhdGVfcnVuLnR4dA0KIyAtZSAnZXZhbHVhdGUnIGZsYWcNCiMgW29wdGlvbmFsXSAtcmVwIGZsYWcsIGluY2x1ZGUgaWYgeW91IGFyIHVzaW5nIHJlcGxpY2F0ZXMNCiMgLWkgaW5wdXQgY29uZmlndXJhdGlvbiBmaWxlIG5hbWUNCiMgLW8gb3V0cHV0IGV2YWx1YXRpb24gc3RhdGlzdGljcyBmaWxlIG5hbWUNCmBgYA0KKiBUaGUgYWJvdmUgY29kZSB3aWxsIGNvbXBpbGUgdGhlIHFjIHN0YXRzIGdlbmVyYXRlZCBkdXJpbmcgX19zdGVwIHR3b19fIGFuZCBvdXRwdXQgdGhlbSBpbnRvIGEgdGFiIGRlbGltaXRlZCBzdW1tYXJ5IGZpbGUuDQoNCiogVGhpcyB3aWxsIG91dHB1dCBhIHRhYiBkZWxpbWl0ZWQgZmlsZSB3aXRoIHRoZSBmb2xsb3dpbmcgY29sdW1uczoNCiAgYGBgDQogIFN0cmFpbiAgUmVwbGljYXRlICBUb3RhbF9yZWFkcyAgVU1JX3VuaXF1ZV9yZWFkcyAgVU1JX3VuaXF1ZV9wY3QgIFFDX2xvY3VzX3JlYWRzICBRQ19sb2N1c19wY3QNCiAgREdZMSAgICAxICAgMzA5MDg4MzggICAgMTMwMzU3MTMgICAgMC40MjE3NDcxMDcgICA2MDA2Mzg5ICAgMC40NjA3NjQxMzMNCiAgREdZMSAgICAyICAgMzEyNzMxNDIgICAgMTMxNjY4MTEgICAgMC40MjEwMjYxNjQgICA0MjQ2NzI4ICAgMC4zMjI1MzI3NjgNCiAgLi4uDQogIGBgYA0KKiBVTUlfdW5pcXVlX3JlYWRzIGFyZSBjYWxjdWxhdGVkIGFmdGVyIGRlZHVwbGljYXRpb24gdXNpbmcgVU1JLXRvb2xzLCB0aGV5IHJlcHJlc2VudCB0aGUgX191bmlxdWUgcmVhZHNfXy4NCiogVU1JX3VuaXF1ZV9wY3QgaXMgKFVNSV91bmlxdWVfcmVhZHMgLyBUb3RhbF9yZWFkcykgKiAxMDANCiogUUNfbG9jdXNfcmVhZHMgYXJlIGNhbGN1bGF0ZWQgZnJvbSB0aGUgdW5pcXVlIHJlYWRzIGFsaWduZWQgdG8gdGhlIFFDX2xvY3VzIGRlZmluZWQgaW4gdGhlIGNvbmZpZ3VyYXRpb24gZmlsZSAoU3RlcCBvbmUpDQoqIFFDX2xvY3VzX3BjdCBpcyAoUUNfbG9jdXNfcmVhZHMgLyBVTUlfdW5pcXVlX3JlYWRzKSAqIDEwMA0KDQojIyMjIFN0ZXAgZm91ciAtIENhbGN1bGF0ZSBzZXF1ZW5jZSByYXJlZmFjdGlvbg0KYGBgDQpweXRob24gd2luZGNoaW1lLnB5IC1yIC1pIGN0cmxfZmlsZS50YWINCiMgLXIgJ3JhcmVmYWN0aW9uJyBmbGFnDQojIFtvcHRpb25hbF0gLXJlcCBmbGFnLCBpbmNsdWRlIGlmIHlvdSBhciB1c2luZyByZXBsaWNhdGVzDQojIFtvcHRpb25hbF0gLXRvbCBwYXJhbWV0ZXIsIGFsbG93cyB5b3UgdG8gc3BlY2lmeSB0aGUgcGVyY2VudCB0b2xlcmFuY2UgcG9pbnQgKGRlZmF1bHQgNTApDQojIC1pIGlucHV0IGNvbmZpZ3VyYXRpb24gZmlsZSBuYW1lDQpgYGANCiogVGhlIGFib3ZlIGNvZGUgd2lsbCBwZXJmb3JtIGEgcmFyZWZhY3Rpb24gY2FsY3VsYXRpb24gdXNpbmcgdGhlIGNvbWJpbmF0aW9uIG9mDQpVTUkgYW4gYWxpZ25lZCBzZXF1ZW5jZS4gQWxsIHJhcmVmYWN0aW9uIGlzIGNhbGN1bGF0ZWQgdXNpbmcgcmFuZG9tIGRvd25zYW1wbGluZy4gDQoqIFRoaXMgY29tbWFuZCB3aWxsIHByb2R1Y2UgcmFyZWZhY3Rpb24gY3VydmVzIHNhdmVkIGFzIC5wZGYgZmlsZXMgaW4gdGhlIF9fb3V0cHV0X2Rpcl9fIGRpcmVjdG9yeSBzcGVjaWZpZWQgaW4gdGhlIGNvbmZpZ3VyYXRpb24gZmlsZS4NCiFbUmFyZWZhY3Rpb24gY3VydmVdKGltYWdlcy9leGFtcGxlLnBuZykNCiogVGhlIHBsb3Qgd2lsbCBzaG93IGJvdGggdGhlIF9faWRlYWwgY2FzZV9fIChyZWQsIGRhc2hlZCBsaW5lKSwgdGhlIF9fb2JzZXJ2ZWQgY2FzZV9fIChibHVlIHNvbGlkIGN1cnZlKSwgYW5kIHRoZSBhcHByb3hpbWF0ZSBfX3RvbGVyYW5jZSBwb2ludF9fIGlmIHByZXNlbnQgKGJsYWNrIHNvbGlkIGxpbmVzKS4gDQoqIFRoZSB0b2xlcmFuY2UgcG9pbnQsIGJ5IGRlZmF1bHQgNTAlLCBpcyB0aGUgcG9pbnQgYXQgd2hpY2ggdGhlIHJhdGUgb2YgYWRkaW5nIGEgbm92ZWwgc2VxdWVuY2UgZHJvcHMgYmVsb3cgNTAlICh0aGlzIGNhbiBiZSBjaGFuZ2VkIGJ5IHVzaW5nIHRoZSBfXy10b2xfXyBwYXJhbWV0ZXIpLiBJbiB0aGUgYWJvdmUgZXhhbXBsZSwgYSA3NSUgdG9sZXJhbmNlIHBvaW50IGlzIGNyb3NzZWQgdmVyeSBlYXJseSBpbiB0aGUgcnVuICh+MC43ZTggcmVhZHMpLiANCg0KIyMjIyBTdGVwIGZpdmUgLSBDYWxjdWxhdGUgY292ZXJhZ2Ugb2YgYWxpZ25lZCByZWFkcyB0byBnZW5vbWUgZmVhdHVyZXMNCmBgYA0KcHl0aG9uIHdpbmRjaGltZS5weSAtYyAtaSBjZmdfZmlsZS50YWIgLW8gY292ZXJhZ2VfcnVuLnNoDQojIC1jICdjb3ZlcmFnZScgZmxhZw0KIyBbb3B0aW9uYWxdIC1yZXAgZmxhZywgaW5jbHVkZSBpZiB5b3UgYXIgdXNpbmcgcmVwbGljYXRlcw0KIyBbb3B0aW9uYWxdIC1tZW0gZmxhZywgc2V0IHNiYXRjaCBtZW1vcnkgYWxsb2NhdGlvbiBpbiBHQi4gKERlZmF1bHQgNjBHQikNCiMgLWkgaW5wdXQgY29uZmlndXJhdGlvbiBmaWxlIG5hbWUNCiMgLW8gb3V0cHV0IGNvdmVyYWdlIHNiYXRjaCBmaWxlIG5hbWUNCg0Kc2JhdGNoIGNvdmVyYWdlX3J1bi5zaA0KYGBgDQoqIFRoZSBhYm92ZSBjb2RlIHdpbGwgZ2VuZXJhdGUgYSBfX2Jhc2ggc2NyaXB0ICJjb3ZlcmFnZV9ydW4uc2giX18gdXNpbmcgdGhlIGluZm9ybWF0aW9uIGdpdmVuIGluIHRoZSBfXy1pX18gaW5wdXQgY29uZmlndXJhdGlvbiBmaWxlLg0KKiBDb3ZlcmFnZSBpcyBjYWxjdWxhdGVkIHVzaW5nIF9fYmVkdG9vbHMgLWdlbm9tZWNvdmVyYWdlX18gY29tbWFuZCB3aXRoIGRlZmF1bHQgc2V0dGluZ3MuIFRoZSBmZWF0dXJlIGZpbGUgc3BlY2lmaWVkIGJ5IF9fJ2dlbm9tZV9mZWF0dXJlcydfXyBpbiB0aGUgY29uZmlndXJhdGlvbiBmaWxlIHdpbGwgYmUgdXNlZCBmb3IgYWxsIGNhbGN1bGF0aW9ucy4NCg0KIyMjIyBTdGVwIHNpeCAtIGNvbWJpbmUgZmVhdHVyZSBjb3ZlcmFnZSBjb3VudHMgaW50byBhIHNpbmdsZSB0YWJsZQ0KYGBgDQpweXRob24gd2luZGNoaW1lLnB5IC10IC1pIGNmZ19maWxlLnRhYiAtbyBjb3ZlcmFnZV90YWJsZS50eHQNCiMgLXQgJ3RhYmxlJyBmbGFnDQojIFtvcHRpb25hbF0gLXJlcCBmbGFnLCBpbmNsdWRlIGlmIHlvdSBhciB1c2luZyByZXBsaWNhdGVzDQojIC1pIGlucHV0IGNvbmZpZ3VyYXRpb24gZmlsZSBuYW1lDQojIC1vIG91dHB1dCBjb21iaW5lZCBjb3ZlcmFnZSB0YWJsZSBmaWxlIG5hbWUNCmBgYA0KDQoqIFRoaXMgd2lsbCBwcm9kdWNlIGEgdGFiLWRlbGltaXRlZCBmaWxlIHdoZXJlIGNvbHVtbnMgYXJlIHRoZSBzYW1wbGUgaWRlbnRpZmllciBhbmQgcm93cyBhcmUgdGhlIGZlYXR1cmUgKGVnLiBnZW5lKSBuYW1lLiAgIEFsbCB2YWx1ZXMgYXJlIHVuY29ycmVjdGVkLCB1bm5vcm1hbGl6ZWQsIGRlZHVwbGljYXRlZCByZWFkcy4gQm90aCBwYWlyZWQgcmVhZHMgbXVzdCBiZSAxMDAlIHdpdGhpbiB0aGUgc2FtZSBmZWF0dXJlIGluIG9yZGVyIHRvIGJlIGNvdW50ZWQuIFRoaXMgdGFibGUgaXMgY29tcGF0aWJsZSB3aXRoIGRvd25zdHJlYW0gYW5hbHlzaXMgYnkgREVTZXEyDQoNCiAgYGBgDQogIGdlbmUJREdZMS0xCURHWTEtMglER1kxLTMgICAgLi4uDQogIFlBTDAwMUMJNzM3CTg5NAk2NzcNCiAgWUFMMDAyVwk4MjUJMTA2Nwk4NzgNCiAgWUFMMDAzVwk0MjY4CTQzNjkJNjQ2Mw0KICAuLi4NCiAgYGBgDQoNCiMjIyMgQ29uY2x1c2lvbiANCkFmdGVyIGEgc3VjY2Vzc2Z1bCBydW4geW91IHNob3VsZCBoYXZlIHRoZSBmb2xsb3dpbmcgZmlsZXM6DQoNCiogSW4gdGhlIGNvbmZpZ3VyYXRpb24gc3BlY2lmaWVkIG91dHB1dCBkaXJlY3RvcnkgKGVnLiBfX291dHB1dF9kaXJfXyk6DQogICsgQWxpZ25lZCwgc29ydGVkLCBpbmRleGVkIGJhbSBmaWxlcw0KICArIFJhcmVmYWN0aW9uIGN1cnZlIHBsb3RzDQogICsgUmF3IGNvdmVyYWdlIGNvdW50IGZpbGVzDQoNCiogQ29tbWFuZCBsaW5lIHNwZWNpZmllZCBsb2NhdGlvbnMgKGVnLiBfXy1vX18pOg0KICArIFF1YWxpdHkgY29udHJvbCBldmFsdWF0aW9uDQogICsgQ29tYmluZWQgY292ZXJhZ2UgdGFibGUNCg==