1 Introduction

This document aims to record the tasks performed to re-preprocess the IPRGC samples of the Speer lab. I have every confidence that Theresa did everything perfectly, the only reason I wish to redo these tasks lies in the fact that we reorganized slightly the data to represent the new files produced by April following a reassessment of the samples in ~202404. It turns out that a small number of samples were misnamed and therefore it is difficult to ensure with absolute certainty that the existing state of Theresa’s working tree is representative of the new state of the samples.

Thus it is worth explaining slightly what I did before starting this document:

  1. I spent some time with Najib and April in order to create the sample sheet ‘20240521_speer_consolidated_sample_sheet.xlsx’. This is mostly identical to Theresa’s with a few caveats:

    1. There is now a series of columns with the suffix ‘AH’. With Najib’s help, I reconciled the existing IPRGC IDs created by Theresa with the extant samples and copied April’s sample sheet information into these columns. They have the names ‘Project # AH’, ‘Sample # AH’, ‘Rashmi’s Sample Name AH’, ‘Prep & Clean AH’, ‘Sequencing Run AH’, ‘Read 1 AH’, ‘Read 2 AH’, ‘Reload & Map Again AH’ and comprise columns AO-AV. These columns are only populated for samples iprgc62-iprgc130, because these are (I think) the only samples sequenced by April, and definitely the only samples potentially affected by the file re-copying.
    2. Given these new columns, I created a series of columns with the suffix ‘atb’: ‘genotype_atb’, ‘location_atb’, ‘time_atb’, ‘time_geo_location_source_atb’, and ‘rashmi_code_atb’. These columns are generally identical to Theresa’s columns of the same information with potential exceptions in the cases of the files which were moved/reorganized. The ‘time_geo_location_source’ column is used to signify where I took the information for the previous columns, e.g. if it says TAA_meta, then I took the genotype etc classifications from Theresa’s metadata without any interpretation/modification. When it says ‘AH filename’, then I took that, as one might expect, from April’s newly provided filenames.
    3. I later added Column AN when assaying Najib’s raw_data tree for these samples. Najib had previously not populated his raw directory tree with any sample >= iprgc_64; so I recorded in this column any actions I took. These actions fell into three categories: 1. Nothing (the first 2), 2. Almost nothing (the raw files were actually in Najib’s tree, but he had not yet put them into the ‘unprocessed’ directory. 3. Nothing existed yet, so I copied the files from my fresh tree (downloaded from the sequencer earlier in 202405) to the appropriate directories in Najib’s tree. I then copy/pasted my command into this column so that we may later double-check them. I probably could have put this information into this file…
    4. At this moment I added a column ‘sequence_type_atb’ which is either ‘previous’ or ‘takara’ so that I can record the likely required trimming process. I am hopeful that this column will not be needed and that I will be able to use fastp to identically treat all samples old and new. I hypothesize this is possible after spending a little time reading the takara cogent package code. It seems to me that their trimming operations are either close-to or identical to what fastp will perform. If that is not true, then I will do my default trimomatic/fastp trimming for the previous samples and the cogent method for the others. It should also be noted that I am making the assumption that any sample < 2021 is not takara and vice versa (e.g. anything received with a date after 20201221 is takara).
  2. It is hoped that 1c. above has left me in a consistent state and that I have every sample required in the appropriate location in Najib’s tree and that they match the modified sample sheet.

  3. Thus I created a fresh working tree named ‘mmusculus_iprgc_2024’ and populated it with empty directories ‘sample_sheets’, ‘reference’, and ‘preprocessing’.

2 Populating the raw data

From this point on, any command run will be performed in this text document, so you will get to read along as I make my decisions/mistakes.

I decided I will work using the read-only copies in Najib’s tree.

cd preprocessing
ln -s /fs/cbcb-lab/nelsayed/raw_data/speer/iprgc* .

I now have 129 symlinks in my preprocessing directory with one hole where a sample got changed and a couple new iprgc IDs due to the changes introduced by April’s reprocessing.

After staring at the screen for a moment, I decided to split these samples into subdirectories named after the sequencing year, thus:

mkdir 2019 2020 2022 2023

mv iprgc_0[1-8] 2019

mv iprgc_09 iprgc_1* iprgc_2* iprgc_3* iprgc_4* iprgc_5* iprgc_60 iprgc_61 2020

mv iprgc_6* iprgc_7* iprgc_8[0-4] 2022

mv iprgc* 2023

## haha I was a doofus and moved the 100s into 2020 directory because iprgc_1* matches 100+
mv 2020/iprgc_1[0-9][0-9] 2023

## I later decided to put all the umd sequenced data into the same tree
mkdir umd_sequenced
mv 2022/* umd_sequenced/
mv 2023/* umd_sequenced/

I am doing this because I am guessing there may be relevant differences in the various rounds of sequencing. In addition I am reasonably certain all the takara samples are in 2022 and 2023.

Ok, so now I should be able to comfortably process different sequencing platform data using for-loops without worrying too much about shenanigans.

3 Trimming

I am therefore going to take a moment and peek in Theresa’s tree and see how the early samples were trimmed.

Looking in Theresa’s tree, I see that she likely kept my original trimmed data using cutadapt Martin (2011) and also performed a trimomatic Bolger, Lohse, and Usadel (2014) run. I took a momemt and see that I used cutadapt because the version of trimomatic at that time did not have the primers in it for this library type; but that has since been ameliorated. I therefore assume that I can comfortably trim with either trimomatic or fastp Chen et al. (2018) without problems. I will definitely need to use fastqc “S-Andrews/FastQC: A Quality Control Analysis Tool for High Throughput Sequencing Data” (n.d.) after trimming and make certain that none of the weirdo i3/i5(or whatever they are called) adapters remain.

Oh, an important note: I only configured fastp recently in my pipeline and it defaults to trying to do a UMI extraction, which is inappropriate for these first samples. I need to remember to tell it not to do that for these. Also, I do not fully understand UMIs yet.

module add cyoa/202406
cd 2019
start=$(pwd)
for i in $(/bin/ls -d iprgc*); do
    echo "Starting $i"
    cd $i
    inputs=$(/bin/ls unprocessed/*.fastq.gz | tr '\n' ':' | sed 's/:$//g')
    echo "The inputs are: ${inputs}"
    cyoa --method trim --input "${inputs}" --jprefix 01
    cyoa --method fastp --input "${inputs}" --jprefix 01 --do_umi 0
    cyoa --method umitools --input "${inputs} --jprefix 01
    cd $start
done

cd ../2020
start=$(pwd)
for i in $(/bin/ls -d iprgc*); do
    echo "Starting $i"
    cd $i
    inputs=$(/bin/ls unprocessed/*.fastq.gz | tr '\n' ':' | sed 's/:$//g')
    echo "The inputs are: ${inputs}"
    cyoa --method trim --input "${inputs}" --jprefix 01
    cyoa --method fastp --input "${inputs}" --jprefix 01 --do_umi 0
    cd $start
done

Next steps, which will have to wait a few minutes: download a new musculus assembly and check that my trimming results look like Theresa’s.

For the 2022/2023 samples, I should at the very least be ready to use cogent, so let us take a moment and look at Theresa’s tree and recall how to use it.

Before I went poking through Theresa’s tree, I copy/pasted the following from April’s report:

  • The workflow used in this kit takes advantage of a novel technology allowing removal of ribosomal cDNA (originating from rRNA) after cDNA synthesis using probes specific to mammalian rRNA. These R-Probes target nuclear and mitochondrial rRNA sequences; however, the mitochondrial R-Probes are derived from the human mitochondrial genome and are therefore strictly human-specific. The rRNA depletion method used in this kit makes it especially well-suited for working with very small quantities of total RNA. Therefore, you will likely see reads mapping to mouse mitochondrial rRNA.
  • This kit adds an 8 nucleotide (nt) unique molecular identifier (UMI) through the reverse-transcription step to mitigate potential PCR bias as well as to provide customers with additional information for transcript quantification, specifically for true variants and rare mutations. This kit is designed for analysis with Takara Bio’s Cogent NGS Analysis Pipeline Software, which removes PCR duplicates and errors based on the UMIs.
  • The directionality of the template-switching reaction preserves the strand orientation of the original RNA, making it possible to obtain strand-specific sequencing data from the synthesized cDNA. Illustrated below are the cDNA library construction process and technologies employed by the kit (Figure 1), and the structural details of final libraries (Figure 2).

4 Umi Trimming

The images which follow provide a diagram of the library layout which I think answers my questions and looks a little like this:

5’-> Read 2 P7 i7 R2start UMI 5’ sequence 3’ sequence <- R1 i5 p5 pppp iii RRRRUUNNNXXX actual sequence data from library……………. RRRRR iii ppp

R1 is of course the reverse complement of this. Thus I think I can expect a 8 nt UMI specific to each sample followed by the NNNXXX UMI which immediately precedes the library sequence. This should be at the beginning of R2 and end of R1 if I interpret this correctly.

With this in mind, I used the umi_tools in order to perform deduplication via the following path:

  1. label each read with its UMI with umi_tools Smith, Heger, and Sudbery (2017)
  2. mapped the full set of reads with hisat2 Kim et al. (2019) and the mm39_112 genome “Mus_musculus - Ensembl Genome Browser 112” (n.d.)
  3. Sorted/indexed/compressed the alignment with samtools Li et al. (2009)
  4. Counted the reads/gene via htseq Putri et al. (2022)
  5. Invoked umi_tools using the output from #3 to remove reads which share the same start/end positions and UMI (e.g. the duplicates) but keeping the first.
  6. Counted the reads/gene via htseq using the output from #5.

4.1 Brief chat with Colenso on 20240605

I spoke briefly with Colenso today and quickly realized that I was foolishly chasing the goal of treating samples <2022 identically to those which are >=2022. They (currently) do not wish to work with any of those earlier samples, which makes my life considerably easier. As a result I copied my sample sheet to ‘20240606_speer_samples.xlsx’ and deleted from it all IDs from iprgc_01 to iprgc_61. This means that every sample was sequenced identically and all have the same UMI configuration.

cd preprocessing
cd umd_sequenced
start=$(pwd)
cd $start
for i in $(/bin/ls -d iprgc*); do
    cd $i
    echo $i
    r1_input=$(/bin/ls unprocessed/*R1*.fastq.gz)
    r2_input=$(/bin/ls unprocessed/*R2*.fastq.gz)
    input="${r1_input}:${r2_input}"
    cyoa --method umi --input ${input}
    cd $start
done

The previous block serves to remove the UMI prefix of read2 and move that information to the suffix of the read ID. I would argue that it should be put in the read comment, but whatever. From that step, we perform the alignment as per usual, then use umi_tools dedup to exclude reads with the same ID which map to the same place, then count up the remaining reads/gene.

I think the previous analysis did not perform the deduplication step, at least I have not yet found it in the logs. As a result, I am going to do one round with and one without the deduplication. My hope is that they will be:

  1. quite similar to each other
  2. the without-deduplication result will be nearly identical to the previous set
  3. the with-deduplication step will slightly improve the results.

Let’s find out!

5 Mapping against the ensembl mus musculus 112 release

Note, I could/should have piped the output of umi_tools directly into hisat, but I didn’t.

cd preprocessing/umd_sequenced
start=$(pwd)
cd $start
for i in $(/bin/ls -d iprgc*); do
    cd $i
    echo $i
    input="outputs/01umi_tools/r1_extracted.fastq.gz:outputs/01umi_tools/r2_extracted.fastq.gz"
    cyoa --method hisat --species mm39_112 --input ${input} --gff_type gene --gff_tag ID \
         --stranded reverse
    cyoa --method hisat --species mm39_112 --libtype rRNA --gff_type rRNA --gff_tag ID \
         --stranded reverse --input ${input}
    cd $start
done

6 Deduplication

A note to self, here are the dedup options:

--output-stats=STATS
                    Specify location to output stats

Barcode extraction options: –extract-umi-method=GET_UMI_METHOD how is the read UMI +/ cell barcode encoded? [default=read_id] –umi-separator=UMI_SEP separator between read id and UMI –umi-tag=UMI_TAG tag containing umi –umi-tag-split=UMI_TAG_SPLIT split UMI in tag and take the first element –umi-tag-delimiter=UMI_TAG_DELIM concatenate UMI in tag separated by delimiter –cell-tag=CELL_TAG tag containing cell barcode –cell-tag-split=CELL_TAG_SPLIT split cell barcode in tag and take the firstelement for e.g 10X GEM tags –cell-tag-delimiter=CELL_TAG_DELIM concatenate cell barcode in tag separated by delimiter

UMI grouping options: –method=METHOD method to use for umi grouping [default=directional] –edit-distance-threshold=THRESHOLD Edit distance theshold at which to join two UMIs when grouping UMIs. [default=1] –spliced-is-unique Treat a spliced read as different to an unspliced one [default=False] –soft-clip-threshold=SOFT_CLIP_THRESHOLD number of bases clipped from 5’ end before read is counted as spliced [default=4] –read-length use read length in addition to position and UMI to identify possible duplicates [default=False]

single-cell RNA-Seq options: –per-gene Group/Dedup/Count per gene. Must combine with either –gene-tag or –per-contig –gene-tag=GENE_TAG Gene is defined by this bam tag [default=none] –assigned-status-tag=ASSIGNED_TAG Bam tag describing whether read is assigned to a gene By defualt, this is set as the same tag as –gene-tag –skip-tags-regex=SKIP_REGEX Used with –gene-tag. Ignore reads where the gene-tag matches this regex –per-contig group/dedup/count UMIs per contig (field 3 in BAM; RNAME), e.g for transcriptome where contig = gene –gene-transcript-map=GENE_TRANSCRIPT_MAP File mapping transcripts to genes (tab separated) –per-cell group/dedup/count per cell

group/dedup options: –buffer-whole-contig Read whole contig before outputting bundles: guarantees that no reads are missed, but increases memory usage –multimapping-detection-method=DETECTION_METHOD Some aligners identify multimapping using bam tags. Setting this option to NH, X0 or XT will use these tags when selecting the best read amongst reads with the same position and umi [default=none]

SAM/BAM options: –mapping-quality=MAPPING_QUALITY Minimum mapping quality for a read to be retained [default=0] –ignore-umi Ignore UMI and dedup only on position –ignore-tlen Option to dedup paired end reads based solely on read1, whether or not the template length is the same –chrom=CHROM Restrict to one chromosome –subset=SUBSET Use only a fraction of reads, specified by subset -i, –in-sam Input file is in sam format [default=False] –paired paired input BAM. [default=False] -o, –out-sam Output alignments in sam format [default=False] –no-sort-output Don’t Sort the output

Dedup and Count SAM/BAM options: –unmapped-reads=UNMAPPED_READS How to handle unmapped reads. Options are ‘discard’ or ‘use’ [default=discard] –chimeric-pairs=CHIMERIC_PAIRS How to handle chimeric read pairs. Options are ‘discard’ or ‘use’ [default=use] –unpaired-reads=UNPAIRED_READS How to handle unpaired reads. Options are ‘discard’or ’use’ [default=use]

input/output options: -I FILE, –stdin=FILE file to read stdin from [default = stdin]. -L FILE, –log=FILE file with logging information [default = stdout]. -E FILE, –error=FILE file with error information [default = stderr]. -S FILE, –stdout=FILE file where output is to go [default = stdout]. –temp-dir=FILE Directory for temporary files. If not set, the bash environmental variable TMPDIR is used[default = None]. –log2stderr send logging information to stderr [default = False]. –compresslevel=COMPRESSLEVEL Level of Gzip compression to use. Default (6) matchesGNU gzip rather than python gzip default (which is 9)

profiling options: –timeit=TIMEIT_FILE store timeing information in file [none]. –timeit-name=TIMEIT_NAME name in timing file for this class of jobs [all]. –timeit-header add header for timing information [none].

common options: -v LOGLEVEL, –verbose=LOGLEVEL loglevel [1]. The higher, the more output. -h, –help output short help (command line options only). –help-extended Output full documentation –random-seed=RANDOM_SEED random seed to initialize number generator with [none].

umi_tools dedup --output-stats=umi_dedup_stats.txt \
          --buffer-whole-contig -I mm39_112_genome.bam \
          -L dedup.stdout -E dedup.stderr -S dedup.bam

I added a version of this to cyoa which also re-performs htseq and should be usable via:

cd preprocessing/umd_sequenced
start=$(pwd)
cd $start
for i in $(/bin/ls -d iprgc*); do
    cd $i
    echo $i
    input="outputs/40hisat_mm39_112/mm39_112_genome.bam"
    cyoa --method umidedup --species mm39_112 --input ${input} --gff_type gene --gff_tag ID \
         --stranded reverse
    cd $start
done

Note that I explicitly mapped against my mm39_112 rRNA database, but neglected to document how I made it, here are those commands:

6.0.1 Making a mouse rRNA database

First I copied my full genome fasta and gff to /tmp/ just to make sure that if I messed up I would not hurt anything

cd /tmp
cp ~/libraries/genome/fasta/mm39* .
cp ~/libraries/genome/gff/mm39* .
## Note, that when typing the following I actually type 'Control-v<tab>'
grep "rRNA\t" mm39_112.gff > mm39_112_rrna.gff
cyoa --method gff2fasta --input mm39_112.fasta --gff mm39_112_rrna.gff --gff_type rRNA --gff_tag ID

The above created a couple of new files which extracted from the full genome the amino acid and nucleotide sequences of all features in the gff which matched my requirements (the amino acid sequences were of course gibberish). So, I copied these new fasta/gff files to my index tree and indexed them for hisat2:

## Still in /tmp/
mv mm39_112_rrna.gff ~/libraries/rRNA/gff/mm39_112.gff
mv mm39_112_nt_rRNA_ID.fasta ~/libraries/rRNA/fasta/mm39_112.fasta
cyoa --method indexhisat --input ~/libraries/rRNA/fasta/mm39_112.fasta \
     --gff ~/libraries/rRNA/gff/mm39_112.gff --libtype rRNA

That last command handles the invocation of the hisat2 indexer to create for me a mouse-specific rRNA database.

Bibliography

Bolger, Anthony M., Marc Lohse, and Bjoern Usadel. 2014. “Trimmomatic: A Flexible Trimmer for Illumina Sequence Data.” Bioinformatics 30 (15): 2114–20. https://doi.org/10.1093/bioinformatics/btu170.
Chen, Shifu, Yanqing Zhou, Yaru Chen, and Jia Gu. 2018. “Fastp: An Ultra-Fast All-in-One FASTQ Preprocessor.” Bioinformatics 34 (17): i884–90. https://doi.org/10.1093/bioinformatics/bty560.
Kim, Daehwan, Joseph M. Paggi, Chanhee Park, Christopher Bennett, and Steven L. Salzberg. 2019. “Graph-Based Genome Alignment and Genotyping with HISAT2 and HISAT-genotype.” Nature Biotechnology 37 (8): 907–15. https://doi.org/10.1038/s41587-019-0201-4.
Li, Heng, Bob Handsaker, Alec Wysoker, Tim Fennell, Jue Ruan, Nils Homer, Gabor Marth, Goncalo Abecasis, and Richard Durbin. 2009. “The Sequence Alignment/Map Format and SAMtools.” Bioinformatics (Oxford, England) 25 (16): 2078–79. https://doi.org/10.1093/bioinformatics/btp352.
Martin, Marcel. 2011. “Cutadapt Removes Adapter Sequences from High-Throughput Sequencing Reads.” EMBnet.journal 17 (1): 10–12. https://doi.org/10.14806/ej.17.1.200.
“Mus_musculus - Ensembl Genome Browser 112.” n.d. http://May2024.archive.ensembl.org/Mus_musculus/Info/Index. Accessed August 8, 2024.
Putri, Givanna H, Simon Anders, Paul Theodor Pyl, John E Pimanda, and Fabio Zanini. 2022. “Analysing High-Throughput Sequencing Data in Python with HTSeq 2.0.” Bioinformatics 38 (10): 2943–45. https://doi.org/10.1093/bioinformatics/btac166.
“S-Andrews/FastQC: A Quality Control Analysis Tool for High Throughput Sequencing Data.” n.d. https://github.com/s-andrews/FastQC. Accessed August 8, 2024.
Smith, Tom, Andreas Heger, and Ian Sudbery. 2017. UMI-tools: Modeling Sequencing Errors in Unique Molecular Identifiers to Improve Quantification Accuracy.” Genome Research 27 (3): 491–99. https://doi.org/10.1101/gr.209601.116.
LS0tCnRpdGxlOiAiUHJlcHJvY2Vzc2luZyB0aGUgSVBSR0Mgc2FtcGxlcyBkZS1ub3ZvLiIKYXV0aG9yOiAiYXRiIGFiZWxld0BnbWFpbC5jb20iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKYmlibGlvZ3JhcGh5OiBhdGIuYmliCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgZmlnX2hlaWdodDogNwogICAgZmlnX3dpZHRoOiA3CiAgICBoaWdobGlnaHQ6IHplbmJ1cm4KICAgIGtlZXBfbWQ6IGZhbHNlCiAgICBtb2RlOiBzZWxmY29udGFpbmVkCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgICB0aGVtZTogcmVhZGFibGUKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICAgIHNtb290aF9zY3JvbGw6IGZhbHNlCiAgcm1kZm9ybWF0czo6cmVhZHRoZWRvd246CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGRmX3ByaW50OiBwYWdlZAogICAgZmlnX2NhcHRpb246IHRydWUKICAgIGZpZ19oZWlnaHQ6IDcKICAgIGZpZ193aWR0aDogNwogICAgaGlnaGxpZ2h0OiB6ZW5idXJuCiAgICB3aWR0aDogMzAwCiAgICBrZWVwX21kOiBmYWxzZQogICAgbW9kZTogc2VsZmNvbnRhaW5lZAogICAgdG9jX2Zsb2F0OiB0cnVlCiAgQmlvY1N0eWxlOjpodG1sX2RvY3VtZW50OgogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgZmlnX2hlaWdodDogNwogICAgZmlnX3dpZHRoOiA3CiAgICBoaWdobGlnaHQ6IHplbmJ1cm4KICAgIGtlZXBfbWQ6IGZhbHNlCiAgICBtb2RlOiBzZWxmY29udGFpbmVkCiAgICB0b2NfZmxvYXQ6IHRydWUKLS0tCgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgpib2R5LCB0ZCB7CiAgZm9udC1zaXplOiAxNnB4Owp9CmNvZGUucnsKICBmb250LXNpemU6IDE2cHg7Cn0KcHJlIHsKICBmb250LXNpemU6IDE2cHgKfQpib2R5IC5tYWluLWNvbnRhaW5lciB7CiAgbWF4LXdpZHRoOiAxNjAwcHg7Cn0KPC9zdHlsZT4KCmBgYHtyIG9wdGlvbnMsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoaHBnbHRvb2xzKQpsaWJyYXJ5KHJldGljdWxhdGUpCnR0IDwtIHRyeShkZXZ0b29sczo6bG9hZF9hbGwoIn4vaHBnbHRvb2xzIikpCmtuaXRyOjpvcHRzX2tuaXQkc2V0KAogIHByb2dyZXNzID0gVFJVRSwgdmVyYm9zZSA9IFRSVUUsIHdpZHRoID0gOTAsIGVjaG8gPSBUUlVFKQprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgZXJyb3IgPSBUUlVFLCBmaWcud2lkdGggPSA4LCBmaWcuaGVpZ2h0ID0gOCwgZmlnLnJldGluYSA9IDIsCiAgb3V0LndpZHRoID0gIjEwMCUiLCBkZXYgPSAicG5nIiwKICBkZXYuYXJncyA9IGxpc3QocG5nID0gbGlzdCh0eXBlID0gImNhaXJvLXBuZyIpKSkKb2xkX29wdGlvbnMgPC0gb3B0aW9ucyhkaWdpdHMgPSA0LCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UsIGtuaXRyLmR1cGxpY2F0ZS5sYWJlbCA9ICJhbGxvdyIpCmdncGxvdDI6OnRoZW1lX3NldChnZ3Bsb3QyOjp0aGVtZV9idyhiYXNlX3NpemUgPSAxMikpCnZlciA8LSAiMjAyMzA1IgpwcmV2aW91c19maWxlIDwtICIiCnZlciA8LSBmb3JtYXQoU3lzLkRhdGUoKSwgIiVZJW0lZCIpCgojI3RtcCA8LSBzbShsb2FkbWUoZmlsZW5hbWU9cGFzdGUwKGdzdWIocGF0dGVybj0iXFwuUm1kIiwgcmVwbGFjZT0iIiwgeD1wcmV2aW91c19maWxlKSwgIi12IiwgdmVyLCAiLnJkYS54eiIpKSkKcm1kX2ZpbGUgPC0gInByZXByb2Nlc3NpbmcuUm1kIgpgYGAKCiMgSW50cm9kdWN0aW9uCgpUaGlzIGRvY3VtZW50IGFpbXMgdG8gcmVjb3JkIHRoZSB0YXNrcyBwZXJmb3JtZWQgdG8gcmUtcHJlcHJvY2VzcyB0aGUKSVBSR0Mgc2FtcGxlcyBvZiB0aGUgU3BlZXIgbGFiLiAgSSBoYXZlIGV2ZXJ5IGNvbmZpZGVuY2UgdGhhdCBUaGVyZXNhCmRpZCBldmVyeXRoaW5nIHBlcmZlY3RseSwgdGhlIG9ubHkgcmVhc29uIEkgd2lzaCB0byByZWRvIHRoZXNlIHRhc2tzCmxpZXMgaW4gdGhlIGZhY3QgdGhhdCB3ZSByZW9yZ2FuaXplZCBzbGlnaHRseSB0aGUgZGF0YSB0byByZXByZXNlbnQKdGhlIG5ldyBmaWxlcyBwcm9kdWNlZCBieSBBcHJpbCBmb2xsb3dpbmcgYSByZWFzc2Vzc21lbnQgb2YgdGhlCnNhbXBsZXMgaW4gfjIwMjQwNC4gIEl0IHR1cm5zIG91dCB0aGF0IGEgc21hbGwgbnVtYmVyIG9mIHNhbXBsZXMgd2VyZQptaXNuYW1lZCBhbmQgdGhlcmVmb3JlIGl0IGlzIGRpZmZpY3VsdCB0byBlbnN1cmUgd2l0aCBhYnNvbHV0ZQpjZXJ0YWludHkgdGhhdCB0aGUgZXhpc3Rpbmcgc3RhdGUgb2YgVGhlcmVzYSdzIHdvcmtpbmcgdHJlZSBpcwpyZXByZXNlbnRhdGl2ZSBvZiB0aGUgbmV3IHN0YXRlIG9mIHRoZSBzYW1wbGVzLgoKVGh1cyBpdCBpcyB3b3J0aCBleHBsYWluaW5nIHNsaWdodGx5IHdoYXQgSSBkaWQgYmVmb3JlIHN0YXJ0aW5nIHRoaXMKZG9jdW1lbnQ6CgoxLiAgSSBzcGVudCBzb21lIHRpbWUgd2l0aCBOYWppYiBhbmQgQXByaWwgaW4gb3JkZXIgdG8gY3JlYXRlIHRoZQogICAgc2FtcGxlIHNoZWV0ICcyMDI0MDUyMV9zcGVlcl9jb25zb2xpZGF0ZWRfc2FtcGxlX3NoZWV0Lnhsc3gnLgogICAgVGhpcyBpcyBtb3N0bHkgaWRlbnRpY2FsIHRvIFRoZXJlc2EncyB3aXRoIGEgZmV3IGNhdmVhdHM6CgogICAgYS4gIFRoZXJlIGlzIG5vdyBhIHNlcmllcyBvZiBjb2x1bW5zIHdpdGggdGhlIHN1ZmZpeCAnQUgnLiAgV2l0aAogICAgICAgIE5hamliJ3MgaGVscCwgSSByZWNvbmNpbGVkIHRoZSBleGlzdGluZyBJUFJHQyBJRHMgY3JlYXRlZCBieQogICAgICAgIFRoZXJlc2Egd2l0aCB0aGUgZXh0YW50IHNhbXBsZXMgYW5kIGNvcGllZCBBcHJpbCdzIHNhbXBsZQogICAgICAgIHNoZWV0IGluZm9ybWF0aW9uIGludG8gdGhlc2UgY29sdW1ucy4gIFRoZXkgaGF2ZSB0aGUgbmFtZXMKICAgICAgICAnUHJvamVjdCAjIEFIJywgJ1NhbXBsZSAjIEFIJywgJ1Jhc2htaSdzIFNhbXBsZSBOYW1lIEFIJywKICAgICAgICAnUHJlcCAmIENsZWFuIEFIJywgJ1NlcXVlbmNpbmcgUnVuIEFIJywgJ1JlYWQgMSBBSCcsICdSZWFkIDIKICAgICAgICBBSCcsICdSZWxvYWQgJiBNYXAgQWdhaW4gQUgnIGFuZCBjb21wcmlzZSBjb2x1bW5zIEFPLUFWLgogICAgICAgIFRoZXNlIGNvbHVtbnMgYXJlIG9ubHkgcG9wdWxhdGVkIGZvciBzYW1wbGVzIGlwcmdjNjItaXByZ2MxMzAsCiAgICAgICAgYmVjYXVzZSB0aGVzZSBhcmUgKEkgdGhpbmspIHRoZSBvbmx5IHNhbXBsZXMgc2VxdWVuY2VkIGJ5CiAgICAgICAgQXByaWwsIGFuZCBkZWZpbml0ZWx5IHRoZSBvbmx5IHNhbXBsZXMgcG90ZW50aWFsbHkgYWZmZWN0ZWQgYnkKICAgICAgICB0aGUgZmlsZSByZS1jb3B5aW5nLgogICAgYi4gIEdpdmVuIHRoZXNlIG5ldyBjb2x1bW5zLCBJIGNyZWF0ZWQgYSBzZXJpZXMgb2YgY29sdW1ucyB3aXRoCiAgICAgICAgdGhlIHN1ZmZpeCAnYXRiJzogJ2dlbm90eXBlX2F0YicsICdsb2NhdGlvbl9hdGInLCAndGltZV9hdGInLAogICAgICAgICd0aW1lX2dlb19sb2NhdGlvbl9zb3VyY2VfYXRiJywgYW5kICdyYXNobWlfY29kZV9hdGInLiAgVGhlc2UKICAgICAgICBjb2x1bW5zIGFyZSBnZW5lcmFsbHkgaWRlbnRpY2FsIHRvIFRoZXJlc2EncyBjb2x1bW5zIG9mIHRoZQogICAgICAgIHNhbWUgaW5mb3JtYXRpb24gd2l0aCBwb3RlbnRpYWwgZXhjZXB0aW9ucyBpbiB0aGUgY2FzZXMgb2YgdGhlCiAgICAgICAgZmlsZXMgd2hpY2ggd2VyZSBtb3ZlZC9yZW9yZ2FuaXplZC4gIFRoZQogICAgICAgICd0aW1lX2dlb19sb2NhdGlvbl9zb3VyY2UnIGNvbHVtbiBpcyB1c2VkIHRvIHNpZ25pZnkgd2hlcmUgSQogICAgICAgIHRvb2sgdGhlIGluZm9ybWF0aW9uIGZvciB0aGUgcHJldmlvdXMgY29sdW1ucywgZS5nLiBpZiBpdCBzYXlzCiAgICAgICAgVEFBX21ldGEsIHRoZW4gSSB0b29rIHRoZSBnZW5vdHlwZSBldGMgY2xhc3NpZmljYXRpb25zIGZyb20KICAgICAgICBUaGVyZXNhJ3MgbWV0YWRhdGEgd2l0aG91dCBhbnkgaW50ZXJwcmV0YXRpb24vbW9kaWZpY2F0aW9uLgogICAgICAgIFdoZW4gaXQgc2F5cyAnQUggZmlsZW5hbWUnLCB0aGVuIEkgdG9vayB0aGF0LCBhcyBvbmUgbWlnaHQKICAgICAgICBleHBlY3QsIGZyb20gQXByaWwncyBuZXdseSBwcm92aWRlZCBmaWxlbmFtZXMuCiAgICBjLiAgSSBsYXRlciBhZGRlZCBDb2x1bW4gQU4gd2hlbiBhc3NheWluZyBOYWppYidzIHJhd19kYXRhIHRyZWUKICAgICAgICBmb3IgdGhlc2Ugc2FtcGxlcy4gIE5hamliIGhhZCBwcmV2aW91c2x5IG5vdCBwb3B1bGF0ZWQgaGlzIHJhdwogICAgICAgIGRpcmVjdG9yeSB0cmVlIHdpdGggYW55IHNhbXBsZSA+PSBpcHJnY182NDsgc28gSSByZWNvcmRlZCBpbgogICAgICAgIHRoaXMgY29sdW1uIGFueSBhY3Rpb25zIEkgdG9vay4gIFRoZXNlIGFjdGlvbnMgZmVsbCBpbnRvIHRocmVlCiAgICAgICAgY2F0ZWdvcmllczogIDEuICBOb3RoaW5nICh0aGUgZmlyc3QgMiksIDIuIEFsbW9zdCBub3RoaW5nICh0aGUKICAgICAgICByYXcgZmlsZXMgd2VyZSBhY3R1YWxseSBpbiBOYWppYidzIHRyZWUsIGJ1dCBoZSBoYWQgbm90IHlldAogICAgICAgIHB1dCB0aGVtIGludG8gdGhlICd1bnByb2Nlc3NlZCcgZGlyZWN0b3J5LiAgMy4gIE5vdGhpbmcKICAgICAgICBleGlzdGVkIHlldCwgc28gSSBjb3BpZWQgdGhlIGZpbGVzIGZyb20gbXkgZnJlc2ggdHJlZQogICAgICAgIChkb3dubG9hZGVkIGZyb20gdGhlIHNlcXVlbmNlciBlYXJsaWVyIGluIDIwMjQwNSkgdG8gdGhlCiAgICAgICAgYXBwcm9wcmlhdGUgZGlyZWN0b3JpZXMgaW4gTmFqaWIncyB0cmVlLiAgSSB0aGVuIGNvcHkvcGFzdGVkCiAgICAgICAgbXkgY29tbWFuZCBpbnRvIHRoaXMgY29sdW1uIHNvIHRoYXQgd2UgbWF5IGxhdGVyIGRvdWJsZS1jaGVjawogICAgICAgIHRoZW0uICBJIHByb2JhYmx5IGNvdWxkIGhhdmUgcHV0IHRoaXMgaW5mb3JtYXRpb24gaW50byB0aGlzCiAgICAgICAgZmlsZS4uLgogICAgZC4gIEF0IHRoaXMgbW9tZW50IEkgYWRkZWQgYSBjb2x1bW4gJ3NlcXVlbmNlX3R5cGVfYXRiJyB3aGljaCBpcwogICAgICAgIGVpdGhlciAncHJldmlvdXMnIG9yICd0YWthcmEnIHNvIHRoYXQgSSBjYW4gcmVjb3JkIHRoZSBsaWtlbHkKICAgICAgICByZXF1aXJlZCB0cmltbWluZyBwcm9jZXNzLiAgSSBhbSBob3BlZnVsIHRoYXQgdGhpcyBjb2x1bW4gd2lsbAogICAgICAgIG5vdCBiZSBuZWVkZWQgYW5kIHRoYXQgSSB3aWxsIGJlIGFibGUgdG8gdXNlIGZhc3RwIHRvCiAgICAgICAgaWRlbnRpY2FsbHkgdHJlYXQgYWxsIHNhbXBsZXMgb2xkIGFuZCBuZXcuICBJIGh5cG90aGVzaXplIHRoaXMKICAgICAgICBpcyBwb3NzaWJsZSBhZnRlciBzcGVuZGluZyBhIGxpdHRsZSB0aW1lIHJlYWRpbmcgdGhlIHRha2FyYQogICAgICAgIGNvZ2VudCBwYWNrYWdlIGNvZGUuICBJdCBzZWVtcyB0byBtZSB0aGF0IHRoZWlyIHRyaW1taW5nCiAgICAgICAgb3BlcmF0aW9ucyBhcmUgZWl0aGVyIGNsb3NlLXRvIG9yIGlkZW50aWNhbCB0byB3aGF0IGZhc3RwIHdpbGwKICAgICAgICBwZXJmb3JtLiAgSWYgdGhhdCBpcyBub3QgdHJ1ZSwgdGhlbiBJIHdpbGwgZG8gbXkgZGVmYXVsdAogICAgICAgIHRyaW1vbWF0aWMvZmFzdHAgdHJpbW1pbmcgZm9yIHRoZSBwcmV2aW91cyBzYW1wbGVzIGFuZCB0aGUKICAgICAgICBjb2dlbnQgbWV0aG9kIGZvciB0aGUgb3RoZXJzLiAgSXQgc2hvdWxkIGFsc28gYmUgbm90ZWQgdGhhdCBJCiAgICAgICAgYW0gbWFraW5nIHRoZSBhc3N1bXB0aW9uIHRoYXQgYW55IHNhbXBsZSA8IDIwMjEgaXMgbm90IHRha2FyYQogICAgICAgIGFuZCB2aWNlIHZlcnNhIChlLmcuIGFueXRoaW5nIHJlY2VpdmVkIHdpdGggYSBkYXRlIGFmdGVyCiAgICAgICAgMjAyMDEyMjEgaXMgdGFrYXJhKS4KCjIuICBJdCBpcyBob3BlZCB0aGF0IDFjLiBhYm92ZSBoYXMgbGVmdCBtZSBpbiBhIGNvbnNpc3RlbnQgc3RhdGUgYW5kCiAgICB0aGF0IEkgaGF2ZSBldmVyeSBzYW1wbGUgcmVxdWlyZWQgaW4gdGhlIGFwcHJvcHJpYXRlIGxvY2F0aW9uIGluCiAgICBOYWppYidzIHRyZWUgYW5kIHRoYXQgdGhleSBtYXRjaCB0aGUgbW9kaWZpZWQgc2FtcGxlIHNoZWV0LgozLiAgVGh1cyBJIGNyZWF0ZWQgYSBmcmVzaCB3b3JraW5nIHRyZWUgbmFtZWQgJ21tdXNjdWx1c19pcHJnY18yMDI0JwogICAgYW5kIHBvcHVsYXRlZCBpdCB3aXRoIGVtcHR5IGRpcmVjdG9yaWVzICdzYW1wbGVfc2hlZXRzJywKICAgICdyZWZlcmVuY2UnLCBhbmQgJ3ByZXByb2Nlc3NpbmcnLgoKIyBQb3B1bGF0aW5nIHRoZSByYXcgZGF0YQoKRnJvbSB0aGlzIHBvaW50IG9uLCBhbnkgY29tbWFuZCBydW4gd2lsbCBiZSBwZXJmb3JtZWQgaW4gdGhpcyB0ZXh0CmRvY3VtZW50LCBzbyB5b3Ugd2lsbCBnZXQgdG8gcmVhZCBhbG9uZyBhcyBJIG1ha2UgbXkKZGVjaXNpb25zL21pc3Rha2VzLgoKSSBkZWNpZGVkIEkgd2lsbCB3b3JrIHVzaW5nIHRoZSByZWFkLW9ubHkgY29waWVzIGluIE5hamliJ3MgdHJlZS4KCmBgYHtiYXNoLCBldmFsPUZBTFNFfQpjZCBwcmVwcm9jZXNzaW5nCmxuIC1zIC9mcy9jYmNiLWxhYi9uZWxzYXllZC9yYXdfZGF0YS9zcGVlci9pcHJnYyogLgpgYGAKCkkgbm93IGhhdmUgMTI5IHN5bWxpbmtzIGluIG15IHByZXByb2Nlc3NpbmcgZGlyZWN0b3J5IHdpdGggb25lIGhvbGUKd2hlcmUgYSBzYW1wbGUgZ290IGNoYW5nZWQgYW5kIGEgY291cGxlIG5ldyBpcHJnYyBJRHMgZHVlIHRvIHRoZQpjaGFuZ2VzIGludHJvZHVjZWQgYnkgQXByaWwncyByZXByb2Nlc3NpbmcuCgpBZnRlciBzdGFyaW5nIGF0IHRoZSBzY3JlZW4gZm9yIGEgbW9tZW50LCBJIGRlY2lkZWQgdG8gc3BsaXQgdGhlc2UKc2FtcGxlcyBpbnRvIHN1YmRpcmVjdG9yaWVzIG5hbWVkIGFmdGVyIHRoZSBzZXF1ZW5jaW5nIHllYXIsIHRodXM6CgpgYGB7YmFzaCwgZXZhbD1GQUxTRX0KbWtkaXIgMjAxOSAyMDIwIDIwMjIgMjAyMwoKbXYgaXByZ2NfMFsxLThdIDIwMTkKCm12IGlwcmdjXzA5IGlwcmdjXzEqIGlwcmdjXzIqIGlwcmdjXzMqIGlwcmdjXzQqIGlwcmdjXzUqIGlwcmdjXzYwIGlwcmdjXzYxIDIwMjAKCm12IGlwcmdjXzYqIGlwcmdjXzcqIGlwcmdjXzhbMC00XSAyMDIyCgptdiBpcHJnYyogMjAyMwoKIyMgaGFoYSBJIHdhcyBhIGRvb2Z1cyBhbmQgbW92ZWQgdGhlIDEwMHMgaW50byAyMDIwIGRpcmVjdG9yeSBiZWNhdXNlIGlwcmdjXzEqIG1hdGNoZXMgMTAwKwptdiAyMDIwL2lwcmdjXzFbMC05XVswLTldIDIwMjMKCiMjIEkgbGF0ZXIgZGVjaWRlZCB0byBwdXQgYWxsIHRoZSB1bWQgc2VxdWVuY2VkIGRhdGEgaW50byB0aGUgc2FtZSB0cmVlCm1rZGlyIHVtZF9zZXF1ZW5jZWQKbXYgMjAyMi8qIHVtZF9zZXF1ZW5jZWQvCm12IDIwMjMvKiB1bWRfc2VxdWVuY2VkLwpgYGAKCkkgYW0gZG9pbmcgdGhpcyBiZWNhdXNlIEkgYW0gZ3Vlc3NpbmcgdGhlcmUgbWF5IGJlIHJlbGV2YW50CmRpZmZlcmVuY2VzIGluIHRoZSB2YXJpb3VzIHJvdW5kcyBvZiBzZXF1ZW5jaW5nLiAgSW4gYWRkaXRpb24gSSBhbQpyZWFzb25hYmx5IGNlcnRhaW4gYWxsIHRoZSB0YWthcmEgc2FtcGxlcyBhcmUgaW4gMjAyMiBhbmQgMjAyMy4KCk9rLCBzbyBub3cgSSBzaG91bGQgYmUgYWJsZSB0byBjb21mb3J0YWJseSBwcm9jZXNzIGRpZmZlcmVudApzZXF1ZW5jaW5nIHBsYXRmb3JtIGRhdGEgdXNpbmcgZm9yLWxvb3BzIHdpdGhvdXQgd29ycnlpbmcgdG9vIG11Y2gKYWJvdXQgc2hlbmFuaWdhbnMuCgojIFRyaW1taW5nCgpJIGFtIHRoZXJlZm9yZSBnb2luZyB0byB0YWtlIGEgbW9tZW50IGFuZCBwZWVrIGluIFRoZXJlc2EncyB0cmVlIGFuZApzZWUgaG93IHRoZSBlYXJseSBzYW1wbGVzIHdlcmUgdHJpbW1lZC4KCkxvb2tpbmcgaW4gVGhlcmVzYSdzIHRyZWUsIEkgc2VlIHRoYXQgc2hlIGxpa2VseSBrZXB0IG15IG9yaWdpbmFsCnRyaW1tZWQgZGF0YSB1c2luZyBjdXRhZGFwdCBAbWFydGluQ3V0YWRhcHRSZW1vdmVzQWRhcHRlcjIwMTFhICBhbmQKYWxzbyBwZXJmb3JtZWQgYSB0cmltb21hdGljIEBib2xnZXJUcmltbW9tYXRpY0ZsZXhpYmxlVHJpbW1lcjIwMTQgcnVuLiAgSQp0b29rIGEgbW9tZW10IGFuZCBzZWUgdGhhdCBJIHVzZWQgY3V0YWRhcHQgYmVjYXVzZSB0aGUgdmVyc2lvbiBvZgp0cmltb21hdGljIGF0IHRoYXQgdGltZSBkaWQgbm90IGhhdmUgdGhlIHByaW1lcnMgaW4gaXQgZm9yIHRoaXMKbGlicmFyeSB0eXBlOyBidXQgdGhhdCBoYXMgc2luY2UgYmVlbiBhbWVsaW9yYXRlZC4gIEkgdGhlcmVmb3JlIGFzc3VtZQp0aGF0IEkgY2FuIGNvbWZvcnRhYmx5IHRyaW0gd2l0aCBlaXRoZXIgdHJpbW9tYXRpYyBvciBmYXN0cApAY2hlbkZhc3RwVWx0cmFmYXN0QWxsaW5vbmUyMDE4IHdpdGhvdXQgcHJvYmxlbXMuICBJIHdpbGwgZGVmaW5pdGVseQpuZWVkIHRvIHVzZSBmYXN0cWMgQFNhbmRyZXdzRmFzdFFDUXVhbGl0eSBhZnRlciB0cmltbWluZyBhbmQgbWFrZQpjZXJ0YWluIHRoYXQgbm9uZSBvZiB0aGUgd2VpcmRvIGkzL2k1KG9yIHdoYXRldmVyIHRoZXkgYXJlIGNhbGxlZCkKYWRhcHRlcnMgcmVtYWluLgoKT2gsIGFuIGltcG9ydGFudCBub3RlOiBJIG9ubHkgY29uZmlndXJlZCBmYXN0cCByZWNlbnRseSBpbiBteSBwaXBlbGluZQphbmQgaXQgZGVmYXVsdHMgdG8gdHJ5aW5nIHRvIGRvIGEgVU1JIGV4dHJhY3Rpb24sIHdoaWNoIGlzCmluYXBwcm9wcmlhdGUgZm9yIHRoZXNlIGZpcnN0IHNhbXBsZXMuICBJIG5lZWQgdG8gcmVtZW1iZXIgdG8gdGVsbCBpdApub3QgdG8gZG8gdGhhdCBmb3IgdGhlc2UuICBBbHNvLCBJIGRvIG5vdCBmdWxseSB1bmRlcnN0YW5kIFVNSXMgeWV0LgoKYGBge2Jhc2gsIGV2YWw9RkFMU0V9Cm1vZHVsZSBhZGQgY3lvYS8yMDI0MDYKY2QgMjAxOQpzdGFydD0kKHB3ZCkKZm9yIGkgaW4gJCgvYmluL2xzIC1kIGlwcmdjKik7IGRvCiAgICBlY2hvICJTdGFydGluZyAkaSIKICAgIGNkICRpCiAgICBpbnB1dHM9JCgvYmluL2xzIHVucHJvY2Vzc2VkLyouZmFzdHEuZ3ogfCB0ciAnXG4nICc6JyB8IHNlZCAncy86JC8vZycpCiAgICBlY2hvICJUaGUgaW5wdXRzIGFyZTogJHtpbnB1dHN9IgogICAgY3lvYSAtLW1ldGhvZCB0cmltIC0taW5wdXQgIiR7aW5wdXRzfSIgLS1qcHJlZml4IDAxCiAgICBjeW9hIC0tbWV0aG9kIGZhc3RwIC0taW5wdXQgIiR7aW5wdXRzfSIgLS1qcHJlZml4IDAxIC0tZG9fdW1pIDAKICAgIGN5b2EgLS1tZXRob2QgdW1pdG9vbHMgLS1pbnB1dCAiJHtpbnB1dHN9IC0tanByZWZpeCAwMQogICAgY2QgJHN0YXJ0CmRvbmUKCmNkIC4uLzIwMjAKc3RhcnQ9JChwd2QpCmZvciBpIGluICQoL2Jpbi9scyAtZCBpcHJnYyopOyBkbwogICAgZWNobyAiU3RhcnRpbmcgJGkiCiAgICBjZCAkaQogICAgaW5wdXRzPSQoL2Jpbi9scyB1bnByb2Nlc3NlZC8qLmZhc3RxLmd6IHwgdHIgJ1xuJyAnOicgfCBzZWQgJ3MvOiQvL2cnKQogICAgZWNobyAiVGhlIGlucHV0cyBhcmU6ICR7aW5wdXRzfSIKICAgIGN5b2EgLS1tZXRob2QgdHJpbSAtLWlucHV0ICIke2lucHV0c30iIC0tanByZWZpeCAwMQogICAgY3lvYSAtLW1ldGhvZCBmYXN0cCAtLWlucHV0ICIke2lucHV0c30iIC0tanByZWZpeCAwMSAtLWRvX3VtaSAwCiAgICBjZCAkc3RhcnQKZG9uZQoKYGBgCgpOZXh0IHN0ZXBzLCB3aGljaCB3aWxsIGhhdmUgdG8gd2FpdCBhIGZldyBtaW51dGVzOiBkb3dubG9hZCBhIG5ldwptdXNjdWx1cyBhc3NlbWJseSBhbmQgY2hlY2sgdGhhdCBteSB0cmltbWluZyByZXN1bHRzIGxvb2sgbGlrZQpUaGVyZXNhJ3MuCgpGb3IgdGhlIDIwMjIvMjAyMyBzYW1wbGVzLCBJIHNob3VsZCBhdCB0aGUgdmVyeSBsZWFzdCBiZSByZWFkeSB0byB1c2UKY29nZW50LCBzbyBsZXQgdXMgdGFrZSBhIG1vbWVudCBhbmQgbG9vayBhdCBUaGVyZXNhJ3MgdHJlZSBhbmQgcmVjYWxsCmhvdyB0byB1c2UgaXQuCgpCZWZvcmUgSSB3ZW50IHBva2luZyB0aHJvdWdoIFRoZXJlc2EncyB0cmVlLCBJIGNvcHkvcGFzdGVkIHRoZQpmb2xsb3dpbmcgZnJvbSBBcHJpbCdzIHJlcG9ydDoKCgoqICBUaGUgd29ya2Zsb3cgdXNlZCBpbiB0aGlzIGtpdCB0YWtlcyBhZHZhbnRhZ2Ugb2YgYSBub3ZlbAogICB0ZWNobm9sb2d5IGFsbG93aW5nIHJlbW92YWwgb2Ygcmlib3NvbWFsIGNETkEgKG9yaWdpbmF0aW5nIGZyb20KICAgclJOQSkgYWZ0ZXIgY0ROQSBzeW50aGVzaXMgdXNpbmcgcHJvYmVzIHNwZWNpZmljIHRvIG1hbW1hbGlhbgogICByUk5BLiBUaGVzZSBSLVByb2JlcyB0YXJnZXQgbnVjbGVhciBhbmQgbWl0b2Nob25kcmlhbCByUk5BCiAgIHNlcXVlbmNlczsgaG93ZXZlciwgdGhlIG1pdG9jaG9uZHJpYWwgUi1Qcm9iZXMgYXJlIGRlcml2ZWQgZnJvbQogICB0aGUgaHVtYW4gbWl0b2Nob25kcmlhbCBnZW5vbWUgYW5kIGFyZSB0aGVyZWZvcmUgc3RyaWN0bHkKICAgaHVtYW4tc3BlY2lmaWMuIFRoZSByUk5BIGRlcGxldGlvbiBtZXRob2QgdXNlZCBpbiB0aGlzIGtpdCBtYWtlcwogICBpdCBlc3BlY2lhbGx5IHdlbGwtc3VpdGVkIGZvciB3b3JraW5nIHdpdGggdmVyeSBzbWFsbCBxdWFudGl0aWVzCiAgIG9mIHRvdGFsIFJOQS4gVGhlcmVmb3JlLCB5b3Ugd2lsbCBsaWtlbHkgc2VlIHJlYWRzIG1hcHBpbmcgdG8KICAgbW91c2UgbWl0b2Nob25kcmlhbCByUk5BLgoqICBUaGlzIGtpdCBhZGRzIGFuIDggbnVjbGVvdGlkZSAobnQpIHVuaXF1ZSBtb2xlY3VsYXIgaWRlbnRpZmllcgogICAoVU1JKSB0aHJvdWdoIHRoZSByZXZlcnNlLXRyYW5zY3JpcHRpb24gc3RlcCB0byBtaXRpZ2F0ZQogICBwb3RlbnRpYWwgUENSIGJpYXMgYXMgd2VsbCBhcyB0byBwcm92aWRlIGN1c3RvbWVycyB3aXRoCiAgIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gZm9yIHRyYW5zY3JpcHQgcXVhbnRpZmljYXRpb24sCiAgIHNwZWNpZmljYWxseSBmb3IgdHJ1ZSB2YXJpYW50cyBhbmQgcmFyZSBtdXRhdGlvbnMuIFRoaXMga2l0IGlzCiAgIGRlc2lnbmVkIGZvciBhbmFseXNpcyB3aXRoIFRha2FyYSBCaW/igJlzIENvZ2VudCBOR1MgQW5hbHlzaXMKICAgUGlwZWxpbmUgU29mdHdhcmUsIHdoaWNoIHJlbW92ZXMgUENSIGR1cGxpY2F0ZXMgYW5kIGVycm9ycwogICBiYXNlZCBvbiB0aGUgVU1Jcy4KKiAgVGhlIGRpcmVjdGlvbmFsaXR5IG9mIHRoZSB0ZW1wbGF0ZS1zd2l0Y2hpbmcgcmVhY3Rpb24KICAgcHJlc2VydmVzIHRoZSBzdHJhbmQgb3JpZW50YXRpb24gb2YgdGhlIG9yaWdpbmFsIFJOQSwKICAgbWFraW5nIGl0IHBvc3NpYmxlIHRvIG9idGFpbiBzdHJhbmQtc3BlY2lmaWMgc2VxdWVuY2luZwogICBkYXRhIGZyb20gdGhlIHN5bnRoZXNpemVkIGNETkEuIElsbHVzdHJhdGVkIGJlbG93IGFyZSB0aGUKICAgY0ROQSBsaWJyYXJ5IGNvbnN0cnVjdGlvbiBwcm9jZXNzIGFuZCB0ZWNobm9sb2dpZXMKICAgZW1wbG95ZWQgYnkgdGhlIGtpdCAoRmlndXJlIDEpLCBhbmQgdGhlIHN0cnVjdHVyYWwgZGV0YWlscwogICBvZiBmaW5hbCBsaWJyYXJpZXMgKEZpZ3VyZSAyKS4KCiMgVW1pIFRyaW1taW5nCgpUaGUgaW1hZ2VzIHdoaWNoIGZvbGxvdyBwcm92aWRlIGEgZGlhZ3JhbSBvZiB0aGUgbGlicmFyeSBsYXlvdXQgd2hpY2gKSSB0aGluayBhbnN3ZXJzIG15IHF1ZXN0aW9ucyBhbmQgbG9va3MgYSBsaXR0bGUgbGlrZSB0aGlzOgoKNSctPiBSZWFkIDIKUDcgIGk3ICBSMnN0YXJ0IFVNSSAgIDUnIHNlcXVlbmNlICAgICAgICAgICAgICAgICAgICAgICAgICAgMycgc2VxdWVuY2UgPC0gUjEgIGk1ICBwNQpwcHBwIGlpaSBSUlJSVVVOTk5YWFggYWN0dWFsIHNlcXVlbmNlIGRhdGEgZnJvbSBsaWJyYXJ5Li4uLi4uLi4uLi4uLi4uLiBSUlJSUiBpaWkgcHBwCgpSMSBpcyBvZiBjb3Vyc2UgdGhlIHJldmVyc2UgY29tcGxlbWVudCBvZiB0aGlzLiAgVGh1cyBJIHRoaW5rIEkgY2FuCmV4cGVjdCBhIDggbnQgVU1JIHNwZWNpZmljIHRvIGVhY2ggc2FtcGxlIGZvbGxvd2VkIGJ5IHRoZSBOTk5YWFggVU1JCndoaWNoIGltbWVkaWF0ZWx5IHByZWNlZGVzIHRoZSBsaWJyYXJ5IHNlcXVlbmNlLiAgVGhpcyBzaG91bGQgYmUgYXQKdGhlIGJlZ2lubmluZyBvZiBSMiBhbmQgZW5kIG9mIFIxIGlmIEkgaW50ZXJwcmV0IHRoaXMgY29ycmVjdGx5LgoKV2l0aCB0aGlzIGluIG1pbmQsIEkgdXNlZCB0aGUgdW1pX3Rvb2xzIGluIG9yZGVyIHRvIHBlcmZvcm0KZGVkdXBsaWNhdGlvbiB2aWEgdGhlIGZvbGxvd2luZyBwYXRoOgoKMS4gbGFiZWwgZWFjaCByZWFkIHdpdGggaXRzIFVNSSB3aXRoIHVtaV90b29scwogICBAc21pdGhVTUl0b29sc01vZGVsaW5nU2VxdWVuY2luZzIwMTcKMi4gbWFwcGVkIHRoZSBmdWxsIHNldCBvZiByZWFkcyB3aXRoIGhpc2F0MgogICBAa2ltR3JhcGhiYXNlZEdlbm9tZUFsaWdubWVudDIwMTkgYW5kIHRoZSBtbTM5XzExMiBnZW5vbWUKICAgQE11c19tdXNjdWx1c0Vuc2VtYmxHZW5vbWUKMy4gU29ydGVkL2luZGV4ZWQvY29tcHJlc3NlZCB0aGUgYWxpZ25tZW50IHdpdGggc2FtdG9vbHMKICAgQGxpU2VxdWVuY2VBbGlnbm1lbnRNYXAyMDA5CjQuIENvdW50ZWQgdGhlIHJlYWRzL2dlbmUgdmlhIGh0c2VxIEBwdXRyaUFuYWx5c2luZ0hpZ2h0aHJvdWdocHV0U2VxdWVuY2luZzIwMjIKNS4gSW52b2tlZCB1bWlfdG9vbHMgdXNpbmcgdGhlIG91dHB1dCBmcm9tICMzIHRvIHJlbW92ZSByZWFkcyB3aGljaAogICBzaGFyZSB0aGUgc2FtZSBzdGFydC9lbmQgcG9zaXRpb25zIGFuZCBVTUkgKGUuZy4gdGhlIGR1cGxpY2F0ZXMpCiAgIGJ1dCBrZWVwaW5nIHRoZSBmaXJzdC4KNi4gQ291bnRlZCB0aGUgcmVhZHMvZ2VuZSB2aWEgaHRzZXEgdXNpbmcgdGhlIG91dHB1dCBmcm9tICM1LgoKIyMgQnJpZWYgY2hhdCB3aXRoIENvbGVuc28gb24gMjAyNDA2MDUKCkkgc3Bva2UgYnJpZWZseSB3aXRoIENvbGVuc28gdG9kYXkgYW5kIHF1aWNrbHkgcmVhbGl6ZWQgdGhhdCBJIHdhcwpmb29saXNobHkgY2hhc2luZyB0aGUgZ29hbCBvZiB0cmVhdGluZyBzYW1wbGVzIDwyMDIyIGlkZW50aWNhbGx5IHRvCnRob3NlIHdoaWNoIGFyZSA+PTIwMjIuICBUaGV5IChjdXJyZW50bHkpIGRvIG5vdCB3aXNoIHRvIHdvcmsgd2l0aCBhbnkKb2YgdGhvc2UgZWFybGllciBzYW1wbGVzLCB3aGljaCBtYWtlcyBteSBsaWZlIGNvbnNpZGVyYWJseSBlYXNpZXIuICBBcwphIHJlc3VsdCBJIGNvcGllZCBteSBzYW1wbGUgc2hlZXQgdG8gJzIwMjQwNjA2X3NwZWVyX3NhbXBsZXMueGxzeCcgYW5kCmRlbGV0ZWQgZnJvbSBpdCBhbGwgSURzIGZyb20gaXByZ2NfMDEgdG8gaXByZ2NfNjEuICBUaGlzIG1lYW5zIHRoYXQKZXZlcnkgc2FtcGxlIHdhcyBzZXF1ZW5jZWQgaWRlbnRpY2FsbHkgYW5kIGFsbCBoYXZlIHRoZSBzYW1lIFVNSQpjb25maWd1cmF0aW9uLgoKYGBge2Jhc2gsIGV2YWw9RkFMU0V9CmNkIHByZXByb2Nlc3NpbmcKY2QgdW1kX3NlcXVlbmNlZApzdGFydD0kKHB3ZCkKY2QgJHN0YXJ0CmZvciBpIGluICQoL2Jpbi9scyAtZCBpcHJnYyopOyBkbwogICAgY2QgJGkKICAgIGVjaG8gJGkKICAgIHIxX2lucHV0PSQoL2Jpbi9scyB1bnByb2Nlc3NlZC8qUjEqLmZhc3RxLmd6KQogICAgcjJfaW5wdXQ9JCgvYmluL2xzIHVucHJvY2Vzc2VkLypSMiouZmFzdHEuZ3opCiAgICBpbnB1dD0iJHtyMV9pbnB1dH06JHtyMl9pbnB1dH0iCiAgICBjeW9hIC0tbWV0aG9kIHVtaSAtLWlucHV0ICR7aW5wdXR9CiAgICBjZCAkc3RhcnQKZG9uZQpgYGAKClRoZSBwcmV2aW91cyBibG9jayBzZXJ2ZXMgdG8gcmVtb3ZlIHRoZSBVTUkgcHJlZml4IG9mIHJlYWQyIGFuZCBtb3ZlCnRoYXQgaW5mb3JtYXRpb24gdG8gdGhlIHN1ZmZpeCBvZiB0aGUgcmVhZCBJRC4gIEkgd291bGQgYXJndWUgdGhhdCBpdApzaG91bGQgYmUgcHV0IGluIHRoZSByZWFkIGNvbW1lbnQsIGJ1dCB3aGF0ZXZlci4gIEZyb20gdGhhdCBzdGVwLCB3ZQpwZXJmb3JtIHRoZSBhbGlnbm1lbnQgYXMgcGVyIHVzdWFsLCB0aGVuIHVzZSB1bWlfdG9vbHMgZGVkdXAgdG8KZXhjbHVkZSByZWFkcyB3aXRoIHRoZSBzYW1lIElEIHdoaWNoIG1hcCB0byB0aGUgc2FtZSBwbGFjZSwgdGhlbiBjb3VudAp1cCB0aGUgcmVtYWluaW5nIHJlYWRzL2dlbmUuCgpJIHRoaW5rIHRoZSBwcmV2aW91cyBhbmFseXNpcyBkaWQgbm90IHBlcmZvcm0gdGhlIGRlZHVwbGljYXRpb24gc3RlcCwKYXQgbGVhc3QgSSBoYXZlIG5vdCB5ZXQgZm91bmQgaXQgaW4gdGhlIGxvZ3MuICBBcyBhIHJlc3VsdCwgSSBhbSBnb2luZwp0byBkbyBvbmUgcm91bmQgd2l0aCBhbmQgb25lIHdpdGhvdXQgdGhlIGRlZHVwbGljYXRpb24uICBNeSBob3BlIGlzCnRoYXQgdGhleSB3aWxsIGJlOgoKYS4gcXVpdGUgc2ltaWxhciB0byBlYWNoIG90aGVyCmIuIHRoZSB3aXRob3V0LWRlZHVwbGljYXRpb24gcmVzdWx0IHdpbGwgYmUgbmVhcmx5IGlkZW50aWNhbCB0byB0aGUKICAgcHJldmlvdXMgc2V0CmMuIHRoZSB3aXRoLWRlZHVwbGljYXRpb24gc3RlcCB3aWxsIHNsaWdodGx5IGltcHJvdmUgdGhlIHJlc3VsdHMuCgpMZXQncyBmaW5kIG91dCEKCiMgTWFwcGluZyBhZ2FpbnN0IHRoZSBlbnNlbWJsIG11cyBtdXNjdWx1cyAxMTIgcmVsZWFzZQoKTm90ZSwgSSBjb3VsZC9zaG91bGQgaGF2ZSBwaXBlZCB0aGUgb3V0cHV0IG9mIHVtaV90b29scyBkaXJlY3RseSBpbnRvCmhpc2F0LCBidXQgSSBkaWRuJ3QuCgpgYGB7YmFzaCwgZXZhbD1GQUxTRX0KY2QgcHJlcHJvY2Vzc2luZy91bWRfc2VxdWVuY2VkCnN0YXJ0PSQocHdkKQpjZCAkc3RhcnQKZm9yIGkgaW4gJCgvYmluL2xzIC1kIGlwcmdjKik7IGRvCiAgICBjZCAkaQogICAgZWNobyAkaQogICAgaW5wdXQ9Im91dHB1dHMvMDF1bWlfdG9vbHMvcjFfZXh0cmFjdGVkLmZhc3RxLmd6Om91dHB1dHMvMDF1bWlfdG9vbHMvcjJfZXh0cmFjdGVkLmZhc3RxLmd6IgogICAgY3lvYSAtLW1ldGhvZCBoaXNhdCAtLXNwZWNpZXMgbW0zOV8xMTIgLS1pbnB1dCAke2lucHV0fSAtLWdmZl90eXBlIGdlbmUgLS1nZmZfdGFnIElEIFwKICAgICAgICAgLS1zdHJhbmRlZCByZXZlcnNlCiAgICBjeW9hIC0tbWV0aG9kIGhpc2F0IC0tc3BlY2llcyBtbTM5XzExMiAtLWxpYnR5cGUgclJOQSAtLWdmZl90eXBlIHJSTkEgLS1nZmZfdGFnIElEIFwKICAgICAgICAgLS1zdHJhbmRlZCByZXZlcnNlIC0taW5wdXQgJHtpbnB1dH0KICAgIGNkICRzdGFydApkb25lCmBgYAoKIyBEZWR1cGxpY2F0aW9uCgpBIG5vdGUgdG8gc2VsZiwgaGVyZSBhcmUgdGhlIGRlZHVwIG9wdGlvbnM6CgogICAgLS1vdXRwdXQtc3RhdHM9U1RBVFMKICAgICAgICAgICAgICAgICAgICAgICAgU3BlY2lmeSBsb2NhdGlvbiB0byBvdXRwdXQgc3RhdHMKCiAgQmFyY29kZSBleHRyYWN0aW9uIG9wdGlvbnM6CiAgICAtLWV4dHJhY3QtdW1pLW1ldGhvZD1HRVRfVU1JX01FVEhPRAogICAgICAgICAgICAgICAgICAgICAgICBob3cgaXMgdGhlIHJlYWQgVU1JICsvIGNlbGwgYmFyY29kZSBlbmNvZGVkPyBbZGVmYXVsdD1yZWFkX2lkXQogICAgLS11bWktc2VwYXJhdG9yPVVNSV9TRVAKICAgICAgICAgICAgICAgICAgICAgICAgc2VwYXJhdG9yIGJldHdlZW4gcmVhZCBpZCBhbmQgVU1JCiAgICAtLXVtaS10YWc9VU1JX1RBRyAgIHRhZyBjb250YWluaW5nIHVtaQogICAgLS11bWktdGFnLXNwbGl0PVVNSV9UQUdfU1BMSVQKICAgICAgICAgICAgICAgICAgICAgICAgc3BsaXQgVU1JIGluIHRhZyBhbmQgdGFrZSB0aGUgZmlyc3QgZWxlbWVudAogICAgLS11bWktdGFnLWRlbGltaXRlcj1VTUlfVEFHX0RFTElNCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmNhdGVuYXRlIFVNSSBpbiB0YWcgc2VwYXJhdGVkIGJ5IGRlbGltaXRlcgogICAgLS1jZWxsLXRhZz1DRUxMX1RBRwogICAgICAgICAgICAgICAgICAgICAgICB0YWcgY29udGFpbmluZyBjZWxsIGJhcmNvZGUKICAgIC0tY2VsbC10YWctc3BsaXQ9Q0VMTF9UQUdfU1BMSVQKICAgICAgICAgICAgICAgICAgICAgICAgc3BsaXQgY2VsbCBiYXJjb2RlIGluIHRhZyBhbmQgdGFrZSB0aGUgZmlyc3RlbGVtZW50IGZvciBlLmcgMTBYIEdFTSB0YWdzCiAgICAtLWNlbGwtdGFnLWRlbGltaXRlcj1DRUxMX1RBR19ERUxJTQogICAgICAgICAgICAgICAgICAgICAgICBjb25jYXRlbmF0ZSBjZWxsIGJhcmNvZGUgaW4gdGFnIHNlcGFyYXRlZCBieSBkZWxpbWl0ZXIKCiAgVU1JIGdyb3VwaW5nIG9wdGlvbnM6CiAgICAtLW1ldGhvZD1NRVRIT0QgICAgIG1ldGhvZCB0byB1c2UgZm9yIHVtaSBncm91cGluZyBbZGVmYXVsdD1kaXJlY3Rpb25hbF0KICAgIC0tZWRpdC1kaXN0YW5jZS10aHJlc2hvbGQ9VEhSRVNIT0xECiAgICAgICAgICAgICAgICAgICAgICAgIEVkaXQgZGlzdGFuY2UgdGhlc2hvbGQgYXQgd2hpY2ggdG8gam9pbiB0d28gVU1JcyB3aGVuIGdyb3VwaW5nIFVNSXMuIFtkZWZhdWx0PTFdCiAgICAtLXNwbGljZWQtaXMtdW5pcXVlCiAgICAgICAgICAgICAgICAgICAgICAgIFRyZWF0IGEgc3BsaWNlZCByZWFkIGFzIGRpZmZlcmVudCB0byBhbiB1bnNwbGljZWQgb25lIFtkZWZhdWx0PUZhbHNlXQogICAgLS1zb2Z0LWNsaXAtdGhyZXNob2xkPVNPRlRfQ0xJUF9USFJFU0hPTEQKICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyIG9mIGJhc2VzIGNsaXBwZWQgZnJvbSA1JyBlbmQgYmVmb3JlIHJlYWQgaXMgY291bnRlZCBhcyBzcGxpY2VkIFtkZWZhdWx0PTRdCiAgICAtLXJlYWQtbGVuZ3RoICAgICAgIHVzZSByZWFkIGxlbmd0aCBpbiBhZGRpdGlvbiB0byBwb3NpdGlvbiBhbmQgVU1JIHRvIGlkZW50aWZ5IHBvc3NpYmxlIGR1cGxpY2F0ZXMgW2RlZmF1bHQ9RmFsc2VdCgogIHNpbmdsZS1jZWxsIFJOQS1TZXEgb3B0aW9uczoKICAgIC0tcGVyLWdlbmUgICAgICAgICAgR3JvdXAvRGVkdXAvQ291bnQgcGVyIGdlbmUuIE11c3QgY29tYmluZSB3aXRoIGVpdGhlciAtLWdlbmUtdGFnIG9yIC0tcGVyLWNvbnRpZwogICAgLS1nZW5lLXRhZz1HRU5FX1RBRwogICAgICAgICAgICAgICAgICAgICAgICBHZW5lIGlzIGRlZmluZWQgYnkgdGhpcyBiYW0gdGFnIFtkZWZhdWx0PW5vbmVdCiAgICAtLWFzc2lnbmVkLXN0YXR1cy10YWc9QVNTSUdORURfVEFHCiAgICAgICAgICAgICAgICAgICAgICAgIEJhbSB0YWcgZGVzY3JpYmluZyB3aGV0aGVyIHJlYWQgaXMgYXNzaWduZWQgdG8gYSBnZW5lIEJ5IGRlZnVhbHQsIHRoaXMgaXMgc2V0IGFzIHRoZSBzYW1lIHRhZyBhcyAtLWdlbmUtdGFnCiAgICAtLXNraXAtdGFncy1yZWdleD1TS0lQX1JFR0VYCiAgICAgICAgICAgICAgICAgICAgICAgIFVzZWQgd2l0aCAtLWdlbmUtdGFnLiBJZ25vcmUgcmVhZHMgd2hlcmUgdGhlIGdlbmUtdGFnIG1hdGNoZXMgdGhpcyByZWdleAogICAgLS1wZXItY29udGlnICAgICAgICBncm91cC9kZWR1cC9jb3VudCBVTUlzIHBlciBjb250aWcgKGZpZWxkIDMgaW4gQkFNOyBSTkFNRSksIGUuZyBmb3IgdHJhbnNjcmlwdG9tZSB3aGVyZSBjb250aWcgPSBnZW5lCiAgICAtLWdlbmUtdHJhbnNjcmlwdC1tYXA9R0VORV9UUkFOU0NSSVBUX01BUAogICAgICAgICAgICAgICAgICAgICAgICBGaWxlIG1hcHBpbmcgdHJhbnNjcmlwdHMgdG8gZ2VuZXMgKHRhYiBzZXBhcmF0ZWQpCiAgICAtLXBlci1jZWxsICAgICAgICAgIGdyb3VwL2RlZHVwL2NvdW50IHBlciBjZWxsCgogIGdyb3VwL2RlZHVwIG9wdGlvbnM6CiAgICAtLWJ1ZmZlci13aG9sZS1jb250aWcKICAgICAgICAgICAgICAgICAgICAgICAgUmVhZCB3aG9sZSBjb250aWcgYmVmb3JlIG91dHB1dHRpbmcgYnVuZGxlczogZ3VhcmFudGVlcyB0aGF0IG5vIHJlYWRzIGFyZSBtaXNzZWQsIGJ1dCBpbmNyZWFzZXMgbWVtb3J5IHVzYWdlCiAgICAtLW11bHRpbWFwcGluZy1kZXRlY3Rpb24tbWV0aG9kPURFVEVDVElPTl9NRVRIT0QKICAgICAgICAgICAgICAgICAgICAgICAgU29tZSBhbGlnbmVycyBpZGVudGlmeSBtdWx0aW1hcHBpbmcgdXNpbmcgYmFtIHRhZ3MuIFNldHRpbmcgdGhpcyBvcHRpb24gdG8gTkgsIFgwIG9yIFhUIHdpbGwgdXNlIHRoZXNlIHRhZ3Mgd2hlbgogICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RpbmcgdGhlIGJlc3QgcmVhZCBhbW9uZ3N0IHJlYWRzIHdpdGggdGhlIHNhbWUgcG9zaXRpb24gYW5kIHVtaSBbZGVmYXVsdD1ub25lXQoKICBTQU0vQkFNIG9wdGlvbnM6CiAgICAtLW1hcHBpbmctcXVhbGl0eT1NQVBQSU5HX1FVQUxJVFkKICAgICAgICAgICAgICAgICAgICAgICAgTWluaW11bSBtYXBwaW5nIHF1YWxpdHkgZm9yIGEgcmVhZCB0byBiZSByZXRhaW5lZCBbZGVmYXVsdD0wXQogICAgLS1pZ25vcmUtdW1pICAgICAgICBJZ25vcmUgVU1JIGFuZCBkZWR1cCBvbmx5IG9uIHBvc2l0aW9uCiAgICAtLWlnbm9yZS10bGVuICAgICAgIE9wdGlvbiB0byBkZWR1cCBwYWlyZWQgZW5kIHJlYWRzIGJhc2VkIHNvbGVseSBvbiByZWFkMSwgd2hldGhlciBvciBub3QgdGhlIHRlbXBsYXRlIGxlbmd0aCBpcyB0aGUgc2FtZQogICAgLS1jaHJvbT1DSFJPTSAgICAgICBSZXN0cmljdCB0byBvbmUgY2hyb21vc29tZQogICAgLS1zdWJzZXQ9U1VCU0VUICAgICBVc2Ugb25seSBhIGZyYWN0aW9uIG9mIHJlYWRzLCBzcGVjaWZpZWQgYnkgc3Vic2V0CiAgICAtaSwgLS1pbi1zYW0gICAgICAgIElucHV0IGZpbGUgaXMgaW4gc2FtIGZvcm1hdCBbZGVmYXVsdD1GYWxzZV0KICAgIC0tcGFpcmVkICAgICAgICAgICAgcGFpcmVkIGlucHV0IEJBTS4gW2RlZmF1bHQ9RmFsc2VdCiAgICAtbywgLS1vdXQtc2FtICAgICAgIE91dHB1dCBhbGlnbm1lbnRzIGluIHNhbSBmb3JtYXQgW2RlZmF1bHQ9RmFsc2VdCiAgICAtLW5vLXNvcnQtb3V0cHV0ICAgIERvbid0IFNvcnQgdGhlIG91dHB1dAoKICBEZWR1cCBhbmQgQ291bnQgU0FNL0JBTSBvcHRpb25zOgogICAgLS11bm1hcHBlZC1yZWFkcz1VTk1BUFBFRF9SRUFEUwogICAgICAgICAgICAgICAgICAgICAgICBIb3cgdG8gaGFuZGxlIHVubWFwcGVkIHJlYWRzLiBPcHRpb25zIGFyZSAnZGlzY2FyZCcgb3IgJ3VzZScgW2RlZmF1bHQ9ZGlzY2FyZF0KICAgIC0tY2hpbWVyaWMtcGFpcnM9Q0hJTUVSSUNfUEFJUlMKICAgICAgICAgICAgICAgICAgICAgICAgSG93IHRvIGhhbmRsZSBjaGltZXJpYyByZWFkIHBhaXJzLiBPcHRpb25zIGFyZSAnZGlzY2FyZCcgb3IgJ3VzZScgIFtkZWZhdWx0PXVzZV0KICAgIC0tdW5wYWlyZWQtcmVhZHM9VU5QQUlSRURfUkVBRFMKICAgICAgICAgICAgICAgICAgICAgICAgSG93IHRvIGhhbmRsZSB1bnBhaXJlZCByZWFkcy4gT3B0aW9ucyBhcmUgJ2Rpc2NhcmQnb3IgJ3VzZScgW2RlZmF1bHQ9dXNlXQoKICBpbnB1dC9vdXRwdXQgb3B0aW9uczoKICAgIC1JIEZJTEUsIC0tc3RkaW49RklMRQogICAgICAgICAgICAgICAgICAgICAgICBmaWxlIHRvIHJlYWQgc3RkaW4gZnJvbSBbZGVmYXVsdCA9IHN0ZGluXS4KICAgIC1MIEZJTEUsIC0tbG9nPUZJTEUKICAgICAgICAgICAgICAgICAgICAgICAgZmlsZSB3aXRoIGxvZ2dpbmcgaW5mb3JtYXRpb24gW2RlZmF1bHQgPSBzdGRvdXRdLgogICAgLUUgRklMRSwgLS1lcnJvcj1GSUxFCiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUgd2l0aCBlcnJvciBpbmZvcm1hdGlvbiBbZGVmYXVsdCA9IHN0ZGVycl0uCiAgICAtUyBGSUxFLCAtLXN0ZG91dD1GSUxFCiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUgd2hlcmUgb3V0cHV0IGlzIHRvIGdvIFtkZWZhdWx0ID0gc3Rkb3V0XS4KICAgIC0tdGVtcC1kaXI9RklMRSAgICAgRGlyZWN0b3J5IGZvciB0ZW1wb3JhcnkgZmlsZXMuIElmIG5vdCBzZXQsIHRoZSBiYXNoIGVudmlyb25tZW50YWwgdmFyaWFibGUgVE1QRElSIGlzIHVzZWRbZGVmYXVsdCA9IE5vbmVdLgogICAgLS1sb2cyc3RkZXJyICAgICAgICBzZW5kIGxvZ2dpbmcgaW5mb3JtYXRpb24gdG8gc3RkZXJyIFtkZWZhdWx0ID0gRmFsc2VdLgogICAgLS1jb21wcmVzc2xldmVsPUNPTVBSRVNTTEVWRUwKICAgICAgICAgICAgICAgICAgICAgICAgTGV2ZWwgb2YgR3ppcCBjb21wcmVzc2lvbiB0byB1c2UuIERlZmF1bHQgKDYpIG1hdGNoZXNHTlUgZ3ppcCByYXRoZXIgdGhhbiBweXRob24gZ3ppcCBkZWZhdWx0ICh3aGljaCBpcyA5KQoKICBwcm9maWxpbmcgb3B0aW9uczoKICAgIC0tdGltZWl0PVRJTUVJVF9GSUxFCiAgICAgICAgICAgICAgICAgICAgICAgIHN0b3JlIHRpbWVpbmcgaW5mb3JtYXRpb24gaW4gZmlsZSBbbm9uZV0uCiAgICAtLXRpbWVpdC1uYW1lPVRJTUVJVF9OQU1FCiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgaW4gdGltaW5nIGZpbGUgZm9yIHRoaXMgY2xhc3Mgb2Ygam9icyBbYWxsXS4KICAgIC0tdGltZWl0LWhlYWRlciAgICAgYWRkIGhlYWRlciBmb3IgdGltaW5nIGluZm9ybWF0aW9uIFtub25lXS4KCiAgY29tbW9uIG9wdGlvbnM6CiAgICAtdiBMT0dMRVZFTCwgLS12ZXJib3NlPUxPR0xFVkVMCiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2xldmVsIFsxXS4gVGhlIGhpZ2hlciwgdGhlIG1vcmUgb3V0cHV0LgogICAgLWgsIC0taGVscCAgICAgICAgICBvdXRwdXQgc2hvcnQgaGVscCAoY29tbWFuZCBsaW5lIG9wdGlvbnMgb25seSkuCiAgICAtLWhlbHAtZXh0ZW5kZWQgICAgIE91dHB1dCBmdWxsIGRvY3VtZW50YXRpb24KICAgIC0tcmFuZG9tLXNlZWQ9UkFORE9NX1NFRUQKICAgICAgICAgICAgICAgICAgICAgICAgcmFuZG9tIHNlZWQgdG8gaW5pdGlhbGl6ZSBudW1iZXIgZ2VuZXJhdG9yIHdpdGggW25vbmVdLgoKCmBgYHtiYXNoLCBldmFsPUZBTFNFfQp1bWlfdG9vbHMgZGVkdXAgLS1vdXRwdXQtc3RhdHM9dW1pX2RlZHVwX3N0YXRzLnR4dCBcCiAgICAgICAgICAtLWJ1ZmZlci13aG9sZS1jb250aWcgLUkgbW0zOV8xMTJfZ2Vub21lLmJhbSBcCiAgICAgICAgICAtTCBkZWR1cC5zdGRvdXQgLUUgZGVkdXAuc3RkZXJyIC1TIGRlZHVwLmJhbQpgYGAKCkkgYWRkZWQgYSB2ZXJzaW9uIG9mIHRoaXMgdG8gY3lvYSB3aGljaCBhbHNvIHJlLXBlcmZvcm1zIGh0c2VxIGFuZCBzaG91bGQgYmUgdXNhYmxlIHZpYToKCmBgYHtiYXNoLCBldmFsPUZBTFNFfQpjZCBwcmVwcm9jZXNzaW5nL3VtZF9zZXF1ZW5jZWQKc3RhcnQ9JChwd2QpCmNkICRzdGFydApmb3IgaSBpbiAkKC9iaW4vbHMgLWQgaXByZ2MqKTsgZG8KICAgIGNkICRpCiAgICBlY2hvICRpCiAgICBpbnB1dD0ib3V0cHV0cy80MGhpc2F0X21tMzlfMTEyL21tMzlfMTEyX2dlbm9tZS5iYW0iCiAgICBjeW9hIC0tbWV0aG9kIHVtaWRlZHVwIC0tc3BlY2llcyBtbTM5XzExMiAtLWlucHV0ICR7aW5wdXR9IC0tZ2ZmX3R5cGUgZ2VuZSAtLWdmZl90YWcgSUQgXAogICAgICAgICAtLXN0cmFuZGVkIHJldmVyc2UKICAgIGNkICRzdGFydApkb25lCmBgYAoKTm90ZSB0aGF0IEkgZXhwbGljaXRseSBtYXBwZWQgYWdhaW5zdCBteSBtbTM5XzExMiByUk5BIGRhdGFiYXNlLCBidXQKbmVnbGVjdGVkIHRvIGRvY3VtZW50IGhvdyBJIG1hZGUgaXQsIGhlcmUgYXJlIHRob3NlIGNvbW1hbmRzOgoKIyMjIE1ha2luZyBhIG1vdXNlIHJSTkEgZGF0YWJhc2UKCkZpcnN0IEkgY29waWVkIG15IGZ1bGwgZ2Vub21lIGZhc3RhIGFuZCBnZmYgdG8gL3RtcC8ganVzdCB0byBtYWtlIHN1cmUKdGhhdCBpZiBJIG1lc3NlZCB1cCBJIHdvdWxkIG5vdCBodXJ0IGFueXRoaW5nCgpgYGB7YmFzaCwgZXZhbD1GQUxTRX0KY2QgL3RtcApjcCB+L2xpYnJhcmllcy9nZW5vbWUvZmFzdGEvbW0zOSogLgpjcCB+L2xpYnJhcmllcy9nZW5vbWUvZ2ZmL21tMzkqIC4KIyMgTm90ZSwgdGhhdCB3aGVuIHR5cGluZyB0aGUgZm9sbG93aW5nIEkgYWN0dWFsbHkgdHlwZSAnQ29udHJvbC12PHRhYj4nCmdyZXAgInJSTkFcdCIgbW0zOV8xMTIuZ2ZmID4gbW0zOV8xMTJfcnJuYS5nZmYKY3lvYSAtLW1ldGhvZCBnZmYyZmFzdGEgLS1pbnB1dCBtbTM5XzExMi5mYXN0YSAtLWdmZiBtbTM5XzExMl9ycm5hLmdmZiAtLWdmZl90eXBlIHJSTkEgLS1nZmZfdGFnIElECmBgYAoKVGhlIGFib3ZlIGNyZWF0ZWQgYSBjb3VwbGUgb2YgbmV3IGZpbGVzIHdoaWNoIGV4dHJhY3RlZCBmcm9tIHRoZSBmdWxsCmdlbm9tZSB0aGUgYW1pbm8gYWNpZCBhbmQgbnVjbGVvdGlkZSBzZXF1ZW5jZXMgb2YgYWxsIGZlYXR1cmVzIGluIHRoZQpnZmYgd2hpY2ggbWF0Y2hlZCBteSByZXF1aXJlbWVudHMgKHRoZSBhbWlubyBhY2lkIHNlcXVlbmNlcyB3ZXJlIG9mCmNvdXJzZSBnaWJiZXJpc2gpLiAgU28sIEkgY29waWVkIHRoZXNlIG5ldyBmYXN0YS9nZmYgZmlsZXMgdG8gbXkgaW5kZXgKdHJlZSBhbmQgaW5kZXhlZCB0aGVtIGZvciBoaXNhdDI6CgpgYGB7YmFzaCwgZXZhbD1GQUxTRX0KIyMgU3RpbGwgaW4gL3RtcC8KbXYgbW0zOV8xMTJfcnJuYS5nZmYgfi9saWJyYXJpZXMvclJOQS9nZmYvbW0zOV8xMTIuZ2ZmCm12IG1tMzlfMTEyX250X3JSTkFfSUQuZmFzdGEgfi9saWJyYXJpZXMvclJOQS9mYXN0YS9tbTM5XzExMi5mYXN0YQpjeW9hIC0tbWV0aG9kIGluZGV4aGlzYXQgLS1pbnB1dCB+L2xpYnJhcmllcy9yUk5BL2Zhc3RhL21tMzlfMTEyLmZhc3RhIFwKICAgICAtLWdmZiB+L2xpYnJhcmllcy9yUk5BL2dmZi9tbTM5XzExMi5nZmYgLS1saWJ0eXBlIHJSTkEKYGBgCgpUaGF0IGxhc3QgY29tbWFuZCBoYW5kbGVzIHRoZSBpbnZvY2F0aW9uIG9mIHRoZSBoaXNhdDIgaW5kZXhlciB0bwpjcmVhdGUgZm9yIG1lIGEgbW91c2Utc3BlY2lmaWMgclJOQSBkYXRhYmFzZS4KCiMgQmlibGlvZ3JhcGh5Cg==