Introduction
The below code is written for the Agriculture Victoria BASC computing
cluster.
This workflow is designed for the marine surveillance project using
the mlCOIintF-jgHCO2198 COI primer set
Clone the pipeRline github repository
# Define the directory you will be running the analysis in
working_dir=/group/pathogens/IAWS/Personal/Alexp/metabarcoding/marine_surveillance #CHANGE TO YOUR DIRECTORY
git clone https://github.com/alexpiper/piperline.git $working_dir
cd $working_dir
Updating the pipeline
IF you already have the pipeline cloned and wish to update to the
latest version, run the below code in the terminal.
git pull
# if an error occurs, run:
git stash
git pull
Demultiplex MiSeq run
For this workflow to run, we will need some sequencing runs to work
with. If you are working with MiSeq data, it is recommended that the
data is demultiplexed again using bcl2fastq, as the miseq does not put
indexes in fasta headers by default which is required for the index
swtiching calculation.
The below code is written for the Agriculture Victoria BASC computing
cluster, and the locations will be different if you are using a
different HPC cluster.
#load module
module load bcl2fastq2/2.20.0-foss-2018b
#raise amount of available file handles
ulimit -n 4000
###Run1
#Set up input and outputs
input_dir=/group/sequencing/240426_M01054_0007_000000000-LJRVM #CHANGE TO YOUR SEQ RUN
fcid=$(echo $input_dir | sed 's/^.*-//')
outputdir=$working_dir/data/$fcid
samplesheet=$input_dir/SampleSheet.csv
# convert samplesheet to unix format
dos2unix $samplesheet
#Demultiplex
bcl2fastq -p 12 --runfolder-dir $input_dir \
--output-dir $outputdir \
--sample-sheet $samplesheet \
--no-lane-splitting --barcode-mismatches 1
# Copy other necessary files and move fastqs
cd $outputdir
cp -r $input_dir/InterOp $outputdir
cp $input_dir/RunInfo.xml $outputdir
cp $input_dir/[Rr]unParameters.xml $outputdir
cp $samplesheet $outputdir
mv **/*.fastq.gz $outputdir
# Append fcid to start of sample names if missing
for i in *.fastq.gz; do
if ! [[ $i == $fcid* ]]; then
new=$(echo ${fcid} ${i}) #append together
new=$(echo ${new// /_}) #remove any white space
mv -v "$i" "$new"
fi
done
Copy reference databases
Reference databases are stored in the referencedata directory on
BASC
The Marine surveillance workflow first assigns ASVs against an
internal database, then anything that remains unidentified to species is
then assigned against a broader scope MARES database
# Change 'folder-name' to the directory you are running the analysis in
cp /group/referencedata/mspd-db/metabarcoding/marine/COI_deakin/* $working_dir/reference/.
cp /group/referencedata/mspd-db/metabarcoding/marine/COI_mares/* $working_dir/reference/.
Submit job with parameters
The parameters for the run are parsed along with the slurm
script.
if you wish to use multiple values (i.e. multiple reference
databases, multiple primers per index) encapsulate them in a ’’ and
seperate them with a ;
You will need to change your email address and account code
below, see BASC
account code lists
cd $working_dir
# Submit slurm job - CHANGE EMAIL TO YOUR OWN EMAIL
sbatch --mail-user=your.name@email.com --account=your.account --cpus-per-task=10 \
supplementary_scripts/basc_shifter.slurm \
--pcr_primers mlCOIintF-jgHCO2198 \
--for_primer_seq GGWACWGGWTGAACWGTWTAYCCYCC \
--rev_primer_seq TAIACYTCIGGRTGICCRAARAAYCA \
--target_gene COI \
--max_primer_mismatch 0 \
--read_min_length 20 \
--read_max_length Inf \
--read_max_ee 1 \
--read_trunc_length 224 \
--read_trim_left 0 \
--read_trim_right 0 \
--asv_min_length 303 \
--asv_max_length 323 \
--high_sensitivity TRUE \
--concat_unmerged FALSE \
--genetic_code SGC4 \
--coding TRUE \
--phmm NA \
--idtaxa_db 'reference/COI_taxreturnmodel_idtaxa.rds;reference/mares_COI_taxreturnmodel_idtaxa.rds' \
--ref_fasta 'reference/COI_taxreturnmodel_hierarchial.fa.gz;reference/mares_COI_taxreturnmodel_hierarchial.fa.gz' \
--idtaxa_confidence 60 \
--run_blast TRUE \
--blast_min_identity 97 \
--blast_min_coverage 90 \
--target_kingdom NA \
--target_phylum NA \
--target_class NA \
--target_order NA \
--target_family NA \
--target_genus NA \
--target_species NA \
--min_sample_reads 0 \
--min_taxa_reads 0 \
--min_taxa_ra 0 \
--start_fresh FALSE
Parameter descriptions
- Primer parameters:
- pcr_primers - Name of PCR primers
- for_primer_seq - Forward primer sequence
- rev_primer_seq - Reverse primer sequence
- target_gene - Name of target gene
- max_primer_mismatch - How much mismatch to allow
when detecting primer sequences
- Read filtering:
- read_min_length - Minimum length of primer trimmed
reads
- read_max_length - Maximum length of primer trimmed
reads
- read_max_ee - Maximum expected errors of primer
trimmed reads
- read_trunc_length - Length to cut all longer reads
to
- read_trim_left - Remove this many bp from left side
of primer trimmed reads
- read_trim_right - Remove this many bp from right
side of primer trimmed reads
- ASV filtering
- asv_min_length - Minimum length of amplicon
- asv_max_length - Maximum length of amplicon
- high_sensitivity - Option to turn on pseudo pooling,
setting this to FALSE greatly speeds up ASV inference at the expense of
detecting fewer rare (<5 reads) taxa.
- concat_unmerged - Retain any unmerged read pairs by
concatenating them together separated by a string of 10 N bases
- genetic_code - Genetic code for amplicon - see
Biostrings::GENETIC_CODE_TABLE
- coding - Is the amplicon from a protein coding
gene
- phmm - Path to profile hidden markov model
(Optional)
- Taxonomic assignment:
- idtaxa_db - Path to trained IDTAXA model
- ref_fasta - Path to fasta file of reference
database
- idtaxa_confidence - Minimum bootstrap confidence
for IDTAXA
- run_blast - Whether a blast top hit search should
be conducted in addition to IDTAXA
- blast_min_identity - Minimum nucleotide identity
for BLAST
- blast_min_coverage - Minimum query coverage for
BLAST
- target_kingdom - Subset to target kingdom
- target_phylum - Subset to target phylum
- target_class - Subset to target class
- target_order - Subset to target order
- target_family - Subset to target family
- target_genus - Subset to target genus
- target_species - Subset to target species
- Sample & Taxon filtering:
- min_sample_reads - Minimum reads per sample after
filtering
- min_taxa_reads - Minimum reads per ASV to
retain
- min_taxa_ra - Minimum relative abundance per ASV to
retain. 1e-4 is 0.01%
- General pipeline parameters
- threads - Number of CPU threads to run the pipeline
across - NOT USED FOR BASC
- start_fresh - Whether to remove all intermediate
files and start the pipeline fresh
LS0tDQp0aXRsZTogIlBpcGVSbGluZSINCnN1YnRpdGxlOiAiTWFyaW5lIHN1cnZlaWxsYW5jZSAoQ09JIG9ubHkpIG9uIEJBU0MiDQphdXRob3I6ICJBLk0uIFBpcGVyIg0KZGF0ZTogImByIFN5cy5EYXRlKClgIg0Kb3V0cHV0Og0KICANCiAgaHRtbF9kb2N1bWVudDoNCiAgICBoaWdobGlnaHRlcjogbnVsbA0KICAgIHRoZW1lOiAiZmxhdGx5Ig0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6IA0KICAgICAgY29sbGFwc2VkOiBmYWxzZQ0KICAgICAgc21vb3RoX3Njcm9sbDogdHJ1ZQ0KICAgIGRmX3ByaW50OiBwYWdlZCAgICANCiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0DQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQojIEtuaXRyIGdsb2JhbCBzZXR1cCAtIGNoYW5nZSBldmFsIHRvIHRydWUgdG8gcnVuIGNvZGUNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KHRhcmdldHMpDQpsaWJyYXJ5KHRhcmNoZXR5cGVzKQ0KDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsZXJyb3I9RkFMU0UsIGZpZy5zaG93ID0gImhvbGQiLCBmaWcua2VlcCA9ICJhbGwiKQ0Kb3B0c19jaHVuayRzZXQoZGV2ID0gJ3BuZycpDQpgYGANCg0KIyBJbnRyb2R1Y3Rpb24NCg0KVGhlIGJlbG93IGNvZGUgaXMgd3JpdHRlbiBmb3IgdGhlIEFncmljdWx0dXJlIFZpY3RvcmlhIEJBU0MgY29tcHV0aW5nIGNsdXN0ZXIuDQoNClRoaXMgd29ya2Zsb3cgaXMgZGVzaWduZWQgZm9yIHRoZSBtYXJpbmUgc3VydmVpbGxhbmNlIHByb2plY3QgdXNpbmcgdGhlIG1sQ09JaW50Ri1qZ0hDTzIxOTggQ09JIHByaW1lciBzZXQNCg0KIyBDbG9uZSB0aGUgcGlwZVJsaW5lIGdpdGh1YiByZXBvc2l0b3J5DQoNCmBgYHtiYXNofQ0KIyBEZWZpbmUgdGhlIGRpcmVjdG9yeSB5b3Ugd2lsbCBiZSBydW5uaW5nIHRoZSBhbmFseXNpcyBpbg0Kd29ya2luZ19kaXI9L2dyb3VwL3BhdGhvZ2Vucy9JQVdTL1BlcnNvbmFsL0FsZXhwL21ldGFiYXJjb2RpbmcvbWFyaW5lX3N1cnZlaWxsYW5jZSAjQ0hBTkdFIFRPIFlPVVIgRElSRUNUT1JZDQoNCmdpdCBjbG9uZSBodHRwczovL2dpdGh1Yi5jb20vYWxleHBpcGVyL3BpcGVybGluZS5naXQgJHdvcmtpbmdfZGlyDQpjZCAkd29ya2luZ19kaXINCmBgYA0KDQojIyBVcGRhdGluZyB0aGUgcGlwZWxpbmUNCg0KSUYgeW91IGFscmVhZHkgaGF2ZSB0aGUgcGlwZWxpbmUgY2xvbmVkIGFuZCB3aXNoIHRvIHVwZGF0ZSB0byB0aGUgbGF0ZXN0IHZlcnNpb24sIHJ1biB0aGUgYmVsb3cgY29kZSBpbiB0aGUgdGVybWluYWwuDQoNCmBgYHtiYXNofQ0KZ2l0IHB1bGwNCg0KIyBpZiBhbiBlcnJvciBvY2N1cnMsIHJ1bjoNCmdpdCBzdGFzaA0KZ2l0IHB1bGwNCmBgYA0KDQojIERlbXVsdGlwbGV4IE1pU2VxIHJ1bg0KDQpGb3IgdGhpcyB3b3JrZmxvdyB0byBydW4sIHdlIHdpbGwgbmVlZCBzb21lIHNlcXVlbmNpbmcgcnVucyB0byB3b3JrIHdpdGguIElmIHlvdSBhcmUgd29ya2luZyB3aXRoIE1pU2VxIGRhdGEsIGl0IGlzIHJlY29tbWVuZGVkIHRoYXQgdGhlIGRhdGEgaXMgZGVtdWx0aXBsZXhlZCBhZ2FpbiB1c2luZyBiY2wyZmFzdHEsIGFzIHRoZSBtaXNlcSBkb2VzIG5vdCBwdXQgaW5kZXhlcyBpbiBmYXN0YSBoZWFkZXJzIGJ5IGRlZmF1bHQgd2hpY2ggaXMgcmVxdWlyZWQgZm9yIHRoZSBpbmRleCBzd3RpY2hpbmcgY2FsY3VsYXRpb24uDQoNClRoZSBiZWxvdyBjb2RlIGlzIHdyaXR0ZW4gZm9yIHRoZSBBZ3JpY3VsdHVyZSBWaWN0b3JpYSBCQVNDIGNvbXB1dGluZyBjbHVzdGVyLCBhbmQgdGhlIGxvY2F0aW9ucyB3aWxsIGJlIGRpZmZlcmVudCBpZiB5b3UgYXJlIHVzaW5nIGEgZGlmZmVyZW50IEhQQyBjbHVzdGVyLg0KDQpgYGB7YmFzaCBkZW11bHRpcGxleCAxIG1pc21hdGNofQ0KI2xvYWQgbW9kdWxlDQptb2R1bGUgbG9hZCBiY2wyZmFzdHEyLzIuMjAuMC1mb3NzLTIwMThiDQoNCiNyYWlzZSBhbW91bnQgb2YgYXZhaWxhYmxlIGZpbGUgaGFuZGxlcw0KdWxpbWl0IC1uIDQwMDANCg0KIyMjUnVuMQ0KDQojU2V0IHVwIGlucHV0IGFuZCBvdXRwdXRzDQppbnB1dF9kaXI9L2dyb3VwL3NlcXVlbmNpbmcvMjQwNDI2X00wMTA1NF8wMDA3XzAwMDAwMDAwMC1MSlJWTSAjQ0hBTkdFIFRPIFlPVVIgU0VRIFJVTg0KDQpmY2lkPSQoZWNobyAkaW5wdXRfZGlyIHwgc2VkICdzL14uKi0vLycpDQpvdXRwdXRkaXI9JHdvcmtpbmdfZGlyL2RhdGEvJGZjaWQNCnNhbXBsZXNoZWV0PSRpbnB1dF9kaXIvU2FtcGxlU2hlZXQuY3N2DQoNCiMgY29udmVydCBzYW1wbGVzaGVldCB0byB1bml4IGZvcm1hdA0KZG9zMnVuaXggJHNhbXBsZXNoZWV0DQoNCiNEZW11bHRpcGxleA0KYmNsMmZhc3RxIC1wIDEyIC0tcnVuZm9sZGVyLWRpciAkaW5wdXRfZGlyIFwNCi0tb3V0cHV0LWRpciAkb3V0cHV0ZGlyIFwNCi0tc2FtcGxlLXNoZWV0ICRzYW1wbGVzaGVldCBcDQotLW5vLWxhbmUtc3BsaXR0aW5nIC0tYmFyY29kZS1taXNtYXRjaGVzIDENCg0KIyBDb3B5IG90aGVyIG5lY2Vzc2FyeSBmaWxlcyBhbmQgbW92ZSBmYXN0cXMNCmNkICRvdXRwdXRkaXINCmNwIC1yICRpbnB1dF9kaXIvSW50ZXJPcCAkb3V0cHV0ZGlyDQpjcCAkaW5wdXRfZGlyL1J1bkluZm8ueG1sICRvdXRwdXRkaXINCmNwICRpbnB1dF9kaXIvW1JyXXVuUGFyYW1ldGVycy54bWwgJG91dHB1dGRpcg0KY3AgJHNhbXBsZXNoZWV0ICRvdXRwdXRkaXINCm12ICoqLyouZmFzdHEuZ3ogJG91dHB1dGRpcg0KDQojIEFwcGVuZCBmY2lkIHRvIHN0YXJ0IG9mIHNhbXBsZSBuYW1lcyBpZiBtaXNzaW5nDQpmb3IgaSBpbiAqLmZhc3RxLmd6OyBkbw0KICBpZiAhIFtbICRpID09ICRmY2lkKiBdXTsgdGhlbg0KICBuZXc9JChlY2hvICR7ZmNpZH0gJHtpfSkgI2FwcGVuZCB0b2dldGhlcg0KICBuZXc9JChlY2hvICR7bmV3Ly8gL199KSAjcmVtb3ZlIGFueSB3aGl0ZSBzcGFjZQ0KICBtdiAtdiAiJGkiICIkbmV3Ig0KICBmaQ0KZG9uZQ0KDQpgYGANCg0KIyMgQ29weSByZWZlcmVuY2UgZGF0YWJhc2VzDQoNClJlZmVyZW5jZSBkYXRhYmFzZXMgYXJlIHN0b3JlZCBpbiB0aGUgcmVmZXJlbmNlZGF0YSBkaXJlY3Rvcnkgb24gQkFTQw0KDQpUaGUgTWFyaW5lIHN1cnZlaWxsYW5jZSB3b3JrZmxvdyBmaXJzdCBhc3NpZ25zIEFTVnMgYWdhaW5zdCBhbiBpbnRlcm5hbCBkYXRhYmFzZSwgdGhlbiBhbnl0aGluZyB0aGF0IHJlbWFpbnMgdW5pZGVudGlmaWVkIHRvIHNwZWNpZXMgaXMgdGhlbiBhc3NpZ25lZCBhZ2FpbnN0IGEgYnJvYWRlciBzY29wZSBNQVJFUyBkYXRhYmFzZQ0KDQpgYGB7YmFzaH0NCiMgQ2hhbmdlICdmb2xkZXItbmFtZScgdG8gdGhlIGRpcmVjdG9yeSB5b3UgYXJlIHJ1bm5pbmcgdGhlIGFuYWx5c2lzIGluDQpjcCAvZ3JvdXAvcmVmZXJlbmNlZGF0YS9tc3BkLWRiL21ldGFiYXJjb2RpbmcvbWFyaW5lL0NPSV9kZWFraW4vKiAkd29ya2luZ19kaXIvcmVmZXJlbmNlLy4NCmNwIC9ncm91cC9yZWZlcmVuY2VkYXRhL21zcGQtZGIvbWV0YWJhcmNvZGluZy9tYXJpbmUvQ09JX21hcmVzLyogJHdvcmtpbmdfZGlyL3JlZmVyZW5jZS8uDQoNCmBgYA0KDQojIFN1Ym1pdCBqb2Igd2l0aCBwYXJhbWV0ZXJzDQoNClRoZSBwYXJhbWV0ZXJzIGZvciB0aGUgcnVuIGFyZSBwYXJzZWQgYWxvbmcgd2l0aCB0aGUgc2x1cm0gc2NyaXB0Lg0KDQppZiB5b3Ugd2lzaCB0byB1c2UgbXVsdGlwbGUgdmFsdWVzIChpLmUuIG11bHRpcGxlIHJlZmVyZW5jZSBkYXRhYmFzZXMsIG11bHRpcGxlIHByaW1lcnMgcGVyIGluZGV4KSBlbmNhcHN1bGF0ZSB0aGVtIGluIGEgJycgYW5kIHNlcGVyYXRlIHRoZW0gd2l0aCBhIDsNCg0KKipZb3Ugd2lsbCBuZWVkIHRvIGNoYW5nZSB5b3VyIGVtYWlsIGFkZHJlc3MgYW5kIGFjY291bnQgY29kZSBiZWxvdywgc2VlIFtCQVNDIGFjY291bnQgY29kZSBsaXN0c10oaHR0cHM6Ly91c2Vycy5iYXNjLnNjaWVuY2UuZGVwaS52aWMuZ292LmF1L2pvYnMvc2x1cm0vc2x1cm1fYWNjb3VudHMvKSoqDQoNCmBgYHtiYXNofQ0KDQpjZCAkd29ya2luZ19kaXIgDQoNCiMgU3VibWl0IHNsdXJtIGpvYiAtIENIQU5HRSBFTUFJTCBUTyBZT1VSIE9XTiBFTUFJTA0Kc2JhdGNoIC0tbWFpbC11c2VyPXlvdXIubmFtZUBlbWFpbC5jb20gLS1hY2NvdW50PXlvdXIuYWNjb3VudCAtLWNwdXMtcGVyLXRhc2s9MTAgXA0Kc3VwcGxlbWVudGFyeV9zY3JpcHRzL2Jhc2Nfc2hpZnRlci5zbHVybSBcDQogIC0tcGNyX3ByaW1lcnMgbWxDT0lpbnRGLWpnSENPMjE5OCBcDQogIC0tZm9yX3ByaW1lcl9zZXEgR0dXQUNXR0dXVEdBQUNXR1RXVEFZQ0NZQ0MgXA0KICAtLXJldl9wcmltZXJfc2VxIFRBSUFDWVRDSUdHUlRHSUNDUkFBUkFBWUNBIFwNCiAgLS10YXJnZXRfZ2VuZSBDT0kgXA0KICAtLW1heF9wcmltZXJfbWlzbWF0Y2ggMCBcDQogIC0tcmVhZF9taW5fbGVuZ3RoIDIwIFwNCiAgLS1yZWFkX21heF9sZW5ndGggSW5mIFwNCiAgLS1yZWFkX21heF9lZSAxIFwNCiAgLS1yZWFkX3RydW5jX2xlbmd0aCAyMjQgXA0KICAtLXJlYWRfdHJpbV9sZWZ0IDAgXA0KICAtLXJlYWRfdHJpbV9yaWdodCAwIFwNCiAgLS1hc3ZfbWluX2xlbmd0aCAzMDMgXA0KICAtLWFzdl9tYXhfbGVuZ3RoIDMyMyBcDQogIC0taGlnaF9zZW5zaXRpdml0eSBUUlVFIFwNCiAgLS1jb25jYXRfdW5tZXJnZWQgRkFMU0UgXA0KICAtLWdlbmV0aWNfY29kZSBTR0M0IFwNCiAgLS1jb2RpbmcgVFJVRSBcDQogIC0tcGhtbSBOQSBcDQogIC0taWR0YXhhX2RiICdyZWZlcmVuY2UvQ09JX3RheHJldHVybm1vZGVsX2lkdGF4YS5yZHM7cmVmZXJlbmNlL21hcmVzX0NPSV90YXhyZXR1cm5tb2RlbF9pZHRheGEucmRzJyBcDQogIC0tcmVmX2Zhc3RhICdyZWZlcmVuY2UvQ09JX3RheHJldHVybm1vZGVsX2hpZXJhcmNoaWFsLmZhLmd6O3JlZmVyZW5jZS9tYXJlc19DT0lfdGF4cmV0dXJubW9kZWxfaGllcmFyY2hpYWwuZmEuZ3onIFwNCiAgLS1pZHRheGFfY29uZmlkZW5jZSA2MCBcDQogIC0tcnVuX2JsYXN0IFRSVUUgXA0KICAtLWJsYXN0X21pbl9pZGVudGl0eSA5NyBcDQogIC0tYmxhc3RfbWluX2NvdmVyYWdlIDkwIFwNCiAgLS10YXJnZXRfa2luZ2RvbSBOQSBcDQogIC0tdGFyZ2V0X3BoeWx1bSBOQSBcDQogIC0tdGFyZ2V0X2NsYXNzIE5BIFwNCiAgLS10YXJnZXRfb3JkZXIgTkEgXA0KICAtLXRhcmdldF9mYW1pbHkgTkEgXA0KICAtLXRhcmdldF9nZW51cyBOQSBcDQogIC0tdGFyZ2V0X3NwZWNpZXMgTkEgXA0KICAtLW1pbl9zYW1wbGVfcmVhZHMgMCBcDQogIC0tbWluX3RheGFfcmVhZHMgMCBcDQogIC0tbWluX3RheGFfcmEgMCBcDQogIC0tc3RhcnRfZnJlc2ggRkFMU0UNCg0KYGBgDQoNCiMgUGFyYW1ldGVyIGRlc2NyaXB0aW9ucw0KDQoqICoqUHJpbWVyIHBhcmFtZXRlcnM6KioNCiAgICArICoqcGNyX3ByaW1lcnMqKiAtIE5hbWUgb2YgUENSIHByaW1lcnMgDQogICAgKyAqKmZvcl9wcmltZXJfc2VxKiogLSBGb3J3YXJkIHByaW1lciBzZXF1ZW5jZQ0KICAgICsgKipyZXZfcHJpbWVyX3NlcSoqIC0gUmV2ZXJzZSBwcmltZXIgc2VxdWVuY2UNCiAgICArICoqdGFyZ2V0X2dlbmUqKiAtIE5hbWUgb2YgdGFyZ2V0IGdlbmUNCiAgICArICoqbWF4X3ByaW1lcl9taXNtYXRjaCoqIC0gSG93IG11Y2ggbWlzbWF0Y2ggdG8gYWxsb3cgd2hlbiBkZXRlY3RpbmcgcHJpbWVyIHNlcXVlbmNlcw0KDQoqICoqUmVhZCBmaWx0ZXJpbmc6KioNCiAgICArICoqcmVhZF9taW5fbGVuZ3RoKiogLSBNaW5pbXVtIGxlbmd0aCBvZiBwcmltZXIgdHJpbW1lZCByZWFkcw0KICAgICsgKipyZWFkX21heF9sZW5ndGgqKiAtIE1heGltdW0gbGVuZ3RoIG9mIHByaW1lciB0cmltbWVkIHJlYWRzDQogICAgKyAqKnJlYWRfbWF4X2VlKiogLSBNYXhpbXVtIGV4cGVjdGVkIGVycm9ycyBvZiBwcmltZXIgdHJpbW1lZCByZWFkcw0KICAgICsgKipyZWFkX3RydW5jX2xlbmd0aCoqIC0gTGVuZ3RoIHRvIGN1dCBhbGwgbG9uZ2VyIHJlYWRzIHRvDQogICAgKyAqKnJlYWRfdHJpbV9sZWZ0KiogLSBSZW1vdmUgdGhpcyBtYW55IGJwIGZyb20gbGVmdCBzaWRlIG9mIHByaW1lciB0cmltbWVkIHJlYWRzDQogICAgKyAqKnJlYWRfdHJpbV9yaWdodCoqIC0gUmVtb3ZlIHRoaXMgbWFueSBicCBmcm9tIHJpZ2h0IHNpZGUgb2YgcHJpbWVyIHRyaW1tZWQgcmVhZHMNCg0KKiAqKkFTViBmaWx0ZXJpbmcqKg0KICAgICsgKiphc3ZfbWluX2xlbmd0aCoqIC0gTWluaW11bSBsZW5ndGggb2YgYW1wbGljb24NCiAgICArICoqYXN2X21heF9sZW5ndGgqKiAtIE1heGltdW0gbGVuZ3RoIG9mIGFtcGxpY29uDQogICAgKyAqKmhpZ2hfc2Vuc2l0aXZpdHkqKiAtIE9wdGlvbiB0byB0dXJuIG9uIFtwc2V1ZG8gcG9vbGluZ10oaHR0cHM6Ly9iZW5qam5lYi5naXRodWIuaW8vZGFkYTIvcHNldWRvLmh0bWwpLCBzZXR0aW5nIHRoaXMgdG8gRkFMU0UgZ3JlYXRseSBzcGVlZHMgdXAgQVNWIGluZmVyZW5jZSBhdCB0aGUgZXhwZW5zZSBvZiBkZXRlY3RpbmcgZmV3ZXIgcmFyZSAoPDUgcmVhZHMpIHRheGEuDQogICAgKyAqKmNvbmNhdF91bm1lcmdlZCoqIC0gUmV0YWluIGFueSB1bm1lcmdlZCByZWFkIHBhaXJzIGJ5IGNvbmNhdGVuYXRpbmcgdGhlbSB0b2dldGhlciBzZXBhcmF0ZWQgYnkgYSBzdHJpbmcgb2YgMTAgTiBiYXNlcw0KICAgICsgKipnZW5ldGljX2NvZGUqKiAtIEdlbmV0aWMgY29kZSBmb3IgYW1wbGljb24gLSBzZWUgQmlvc3RyaW5nczo6R0VORVRJQ19DT0RFX1RBQkxFDQogICAgKyAqKmNvZGluZyoqIC0gSXMgdGhlIGFtcGxpY29uIGZyb20gYSBwcm90ZWluIGNvZGluZyBnZW5lDQogICAgKyAqKnBobW0qKiAtIFBhdGggdG8gcHJvZmlsZSBoaWRkZW4gbWFya292IG1vZGVsIChPcHRpb25hbCkNCg0KKiAqKlRheG9ub21pYyBhc3NpZ25tZW50OioqDQogICAgKyAqKmlkdGF4YV9kYioqIC0gUGF0aCB0byB0cmFpbmVkIElEVEFYQSBtb2RlbA0KICAgICsgKipyZWZfZmFzdGEqKiAtIFBhdGggdG8gZmFzdGEgZmlsZSBvZiByZWZlcmVuY2UgZGF0YWJhc2UNCiAgICArICoqaWR0YXhhX2NvbmZpZGVuY2UqKiAtIE1pbmltdW0gYm9vdHN0cmFwIGNvbmZpZGVuY2UgZm9yIElEVEFYQQ0KICAgICsgKipydW5fYmxhc3QqKiAtIFdoZXRoZXIgYSBibGFzdCB0b3AgaGl0IHNlYXJjaCBzaG91bGQgYmUgY29uZHVjdGVkIGluIGFkZGl0aW9uIHRvIElEVEFYQQ0KICAgICsgKipibGFzdF9taW5faWRlbnRpdHkqKiAtIE1pbmltdW0gbnVjbGVvdGlkZSBpZGVudGl0eSBmb3IgQkxBU1QNCiAgICArICoqYmxhc3RfbWluX2NvdmVyYWdlKiogLSBNaW5pbXVtIHF1ZXJ5IGNvdmVyYWdlIGZvciBCTEFTVA0KICAgICsgKip0YXJnZXRfa2luZ2RvbSoqIC0gU3Vic2V0IHRvIHRhcmdldCBraW5nZG9tDQogICAgKyAqKnRhcmdldF9waHlsdW0qKiAtIFN1YnNldCB0byB0YXJnZXQgcGh5bHVtDQogICAgKyAqKnRhcmdldF9jbGFzcyoqIC0gU3Vic2V0IHRvIHRhcmdldCBjbGFzcw0KICAgICsgKip0YXJnZXRfb3JkZXIqKiAtIFN1YnNldCB0byB0YXJnZXQgb3JkZXINCiAgICArICoqdGFyZ2V0X2ZhbWlseSoqIC0gU3Vic2V0IHRvIHRhcmdldCBmYW1pbHkNCiAgICArICoqdGFyZ2V0X2dlbnVzKiogLSBTdWJzZXQgdG8gdGFyZ2V0IGdlbnVzDQogICAgKyAqKnRhcmdldF9zcGVjaWVzKiogLSBTdWJzZXQgdG8gdGFyZ2V0IHNwZWNpZXMNCg0KKiAqKlNhbXBsZSAmIFRheG9uIGZpbHRlcmluZzoqKg0KICAgICsgKiptaW5fc2FtcGxlX3JlYWRzKiogLSBNaW5pbXVtIHJlYWRzIHBlciBzYW1wbGUgYWZ0ZXIgZmlsdGVyaW5nDQogICAgKyAqKm1pbl90YXhhX3JlYWRzKiogLSBNaW5pbXVtIHJlYWRzIHBlciBBU1YgdG8gcmV0YWluDQogICAgKyAqKm1pbl90YXhhX3JhKiogLSBNaW5pbXVtIHJlbGF0aXZlIGFidW5kYW5jZSBwZXIgQVNWIHRvIHJldGFpbi4gMWUtNCBpcyAwLjAxJQ0KICAgIA0KICAgIA0KKiAqKkdlbmVyYWwgcGlwZWxpbmUgcGFyYW1ldGVycyoqDQogICAgKyAqKnRocmVhZHMqKiAtIE51bWJlciBvZiBDUFUgdGhyZWFkcyB0byBydW4gdGhlIHBpcGVsaW5lIGFjcm9zcyAtICoqTk9UIFVTRUQgRk9SIEJBU0MqKg0KICAgICsgKipzdGFydF9mcmVzaCoqIC0gV2hldGhlciB0byByZW1vdmUgYWxsIGludGVybWVkaWF0ZSBmaWxlcyBhbmQgc3RhcnQgdGhlIHBpcGVsaW5lIGZyZXNoDQo=