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=