Hands-on RNA-seq Analysis in Galaxy

Acknowledgement

Based on the RNA-Seq workshop by Melbourne Bioinformatics written by Mahtab Mirmomeni, Andrew Lonie, Jessica Chung Original

Modified by David Powell (Monash Bioinformatics Platform)

Further Modified by Mark Dunning of Sheffield Bioinformatics Core

Sheffield Bioinformatics Core

web : sbc.shef.ac.uk
twitter: [@SheffBioinfCore](https://twitter.com/SheffBioinfCore)
email: bioinformatics-core@sheffield.ac.uk


Tutorial Overview

This tutorial will cover the basics of RNA-seq using Galaxy; a open-source web-based platform for the analysis of biological data. You should gain an appreciation of the tasks involved in a typical RNA-seq analysis and be comfortable with the outputs generated by the Bioinformatician.

More on Galaxy

The official Galaxy page has many tutorials on using the service, and examples of other types of analysis that can be performed on the platform.

Those eventually wanted to perform their own RNA-seq analysis (for example in R), should look out for other courses

Courses on analysing RNA-seq data in R


Background

Where do the data in this tutorial come from?

The data for this tutorial comes from a Nature Cell Biology paper, EGF-mediated induction of Mcl-1 at the switch to lactation is essential for alveolar cell survival [@Fu2015].

This study examines the expression profiles of basal stem-cell enriched cells (B) and committed luminal cells (L) in the mammary gland of virgin, pregnant and lactating mice. Six groups are present, with one for each combination of cell type and mouse status. Each group contains two biological replicates.

The full experimental design is as follows:-

Run Name CellType Status
SRR1552444 MCL1-LA basal virgin
SRR1552445 MCL1-LB luminal virgin
SRR1552446 MCL1-LC Luminal pregnancy
SRR1552447 MCL1-LD Luminal pregnancy
SRR1552448 MCL1-LE luminal lactation
SRR1552449 MCL1-LF luminal lactation
SRR1552450 MCL1-DG basal virgin
SRR1552451 MCL1-DH luminal virgin
SRR1552452 MCL1-DI basal pregnancy
SRR1552453 MCL1-DJ basal pregnancy
SRR1552454 MCL1-DK basal lactation
SRR1552455 MCL1-DL basal lactation

For this tutorial, we will assume that the wet-lab stages of the experiment have been performed and we are now in the right-hand branch of the workflow. In this tutorial we will demonstrate the steps of Quality assessment, alignment, quantification and differential expression testing.

Section 1: Preparation

1. Sign-up to the European Galaxy server

Make sure you check your email to activate your account

2. Import the RNA-seq data for the workshop.

We can going to import the fastq files for this experiment. This is a standard format for storing raw sequencing reads and their associated quality scores. To make the practical quicker, we have downsampled the original fastq files to half a million reads.

Get Data -> Upload File

You can import the data by:

  1. In the tool panel located on the left, under Basic Tools select Get Data > Upload File. Click on the **Choose local file* button on the bottom section of the pop-up window.
  2. Navigate to the fastq directory of the zip file that you downloaded from google drive There are two files are single-end samples from the basal-virgin condition.

SRR1552444.fastq.gz SRR1552450.fastq.gz

and these two files are single-end samples from the basal pregnant condition.

SRR1552452.fastq.gz SRR1552453.fastq.gz
  1. You should now have these 4 files in your history:
    • SRR1552444.fastq.gz
    • SRR1552450.fastq.gz
    • SRR1552452.fastq.gz
    • SRR1552453.fastq.gz

Each read is described by 4 lines in the file:-

The quality scores are ASCII representations of how confident we are that a particular base has been called correctly. Letters that are further along the alphabet indicate higher confidence. This is important when trying to identify types of genome variation such as single base changes, but is also indicative of the overall quality of the sequencing. Different scales have been employed over time (resulting in a different set of characters appearing in the file). We will need to tell Galaxy which scale has been used in order that we can process the data correctly.

Deriving the Quality Score

First of all, we convert the base-calling probability (p) into a Q score using the formula

Quality Scores to probabilities

  • look-up the ASCII code for each character
  • subtract the offset to get the Q score
  • convert to a probability using the formula:-

\[ p = 10^{-Q/10} \]

In practice, we don’t have to convert the values as we have software that will do this automatically


Section 2: Quality assessment with FastQC

FastQC is a popular tool from Babraham Institute Bioinformatics Group used for quality assessment of sequencing data. Most Bioinformatics pipelines will use FastQC, or similar tools in the first stage of the analysis. The documentation for FastQC will help you to interpret the plots and stats produced by the tool. A traffic light system is used to alert the user’s attention to possible issues. However, it is worth bearing in mind that the tool is blind to the particular type of sequencing you are performing (i.e. whole-genome, ChIP-seq, RNA-seq), so some warnings might be expected due to the nature of your experiment.

FastQ Quality Control -> FastQC Read Quality reports

Make sure you select this tool. There is another version of FastQC present, which does not produce some of the output we need for a later step

  • Select one of the FASTQ files as input and Execute the tool.
  • When the tool finishes running, you should have an HTML file in your History. Click on the eye icon to view the various quality metrics.
  • Run Fastqc on the remaing fastq files, but don’t examine the results just yet.

Question: Do the data seem to be of reasonable quality?

You can use the documentation to help interpret the plots

If poor quality reads towards the ends of reads are considered to be a problem, or there is considerable adapter contamination, we can employ various tools to trim our data.

However, a recent paper demonstrated that read trimming is no longer required prior to alignment:- https://www.biorxiv.org/content/10.1101/833962v1

If you suspect contamination from adapter sequence or unacceptable quality scores towards the ends of reads various trimming options are supported by the Trimmomatic tool (amongst others)

FASTA/FASTQ -> Trimmomatic

The operations supported by trimmomatic will probably not be very informative on our example data (as it has already been processed), but you can try several operations if you get time:-

  • Removing Illumina adapter sequences by setting Perform initial ILLUMINACLIP to Yes and selecting the appropriate adapter type
  • Remove poor quality bases at the end of reads by choosing Cut bases off the end of a read, if below a threshold quality (TRAILING) under Select Trimmomatic operation to perform
  • Remove poor quality bases at the start of reads by choosing Cut bases off the start of a read, if below a threshold quality (LEADING) under Select Trimmomatic operation to perform
  • You can apply multiple operations in turn by clicking Insert Trimmomatic Operation

If you also suspect contamination by another organism, or rRNA present in your data, you can use the sortMeRNA tool to remove this artefact.

Combining QC reports

It can be quite tiresome to click through multiple QC reports and compare the results for different samples. It is useful to have all the QC plots on the same page so that we can more easily spot trends in the data.

The multiqc tool has been designed for the tasks of aggregating qc reports and combining into a single report that is easy to digest.

FASTQ Quality Control -> Multiqc

Under Which tool was used generate logs? Choose fastqc and select the RawData output from the fastqc run on each of your bam files.

Question: Repeat the FastQC analysis for the remaining fastq files and combine the reports with multiQC. Do the fastq files seem to have consistently high-quality?

Section 3: Alignment

In this section we map the reads in our FASTQ files to a reference genome. As these reads originate from mRNA, we expect some of them will cross exon/intron boundaries when we align them to the reference genome. HISAT2 is a splice-aware mapper for RNA-seq reads that is based on Bowtie. It uses the mapping results from Bowtie to identify splice junctions between exons. More information on HISAT2 can be found here.

Mapping -> HISAT2

1. Map/align the reads with HISAT2 to the mm10 reference genome

In the left tool panel menu, under NGS Analysis, select Mapping > HISAT2 and set the parameters as follows:

  • Is this single-end or paired-end data? Single-end (as individual datasets)
  • FASTQ file
    (Click on the multiple datasets icon and select all four of the FASTQ files)
    • SRR1552444.fastq.gz
    • SRR1552450.fastq.gz
    • SRR1552452.fastq.gz
    • SRR1552453.fastq.gz
  • Source for the reference genome Use built-in genome
  • Select a reference genome: Mouse (Mus Musculus): mm10
  • Use defaults for the other fields
  • Execute

Note: This may take a few minutes, depending on how busy the server is.

2. Rename the output files

You should have 5 output files for each of the FASTQ input files:

HISAT2 on data.. aligned reads (BAM)

It will be helpful to rename these to something shorter for the next steps.

  • SRR1552444.bam
  • SRR1552450.bam
  • SRR1552452.bam
  • SRR1552453.bam

If this step is taking too long, there is an aligned bam file present in the google drive link. You can use this in the following steps of the tutorial.

STAR is also another popular option for aligned RNA-seq reads. We won’t cover this today, or the relative merits of different methods. If you want to try STAR in your own time you can find it under.

Mapping -> RNA STAR

About the aligned read format

Unlike most of Bioinfomatics, a single standard file format has emerged for aligned reads. Moreoever, this file format is consistent regardless of whether you have DNA-seq, RNA-seq, ChIP-seq… data.

The first part of the header lists the names (SN) of the sequences (chromosomes) used in alignment, their length (LN). Sometimes, a md5sumdigital fingerprint” of the .fasta file used for alignment (M5) is shown.

@HD VN:1.0 SO:coordinate
@SQ SN:chr1 LN:195471971
@SQ SN:chr10 LN:130694993
@SQ SN:chr11 LN:122082543
.....
.....

If mutliple samples were present in the file (i.e. the samples have been multiplexed), read groups can be used to identify which sequencing library, sequencing centre, Lane, sample name etc.

(not present for the example data in this course)

@RG ID:SRR077850    CN:bi   LB:Solexa-42057 PL:illumina PU:ILLUMINA SM:NA06984
@RG ID:SRR081675    CN:bi   LB:Solexa-42316 PL:illumina PU:ILLUMINA SM:NA06984
@RG ID:SRR080818    CN:bi   LB:Solexa-44770 PL:illumina PU:ILLUMINA SM:NA06984
@RG ID:SRR084838    CN:bi   LB:Solexa-42316 PL:illumina PU:ILLUMINA SM:NA06984
@RG ID:SRR081730    CN:bi   LB:Solexa-42316 PL:illumina PU:ILLUMINA SM:NA06984
.....
.....

Finally, we have a section where we can record the processing steps used to derive the file. This is

@PG ID:hisat2 PN:hisat2 VN:2.1.0 CL:"/mnt/pulsar/dependencies/_conda/envs/mulled-v1-e7321ba46fa5ea4c6b9a06b78e6cd5182b33c0a47c2c86b5d610e1361f8b1686/bin/hisat2-align-s --wrapper basic-0 -p 4 -x /cvmfs/data.galaxyproject.org/managed/hisat2_index/mm10/mm10 -U /tmp/16282.unp"
....
....

Next is a tab-delimited section that describes the alignment of each sequence in detail.

SRR1552450.220289   0   chr1    3200839 60  100M    *   0   0   GGCTCACCAAGTATGATGGTTTCATACCCAGAAAAACATTTGTTCTTTTGGATGCCATTAGTTCAGCCAGTGTCAACATGACTAGTGGTTTCCCAAGCAC    CCCFFFFDHHGDHGIIJJJIHGHGGIGHIIIGFHGHBIIHIJAGIJIJJGGCHJJIGIJJJGHCAGGHHIICGGHHHHHHFFFFFDCE;?AACCDCDDDC    AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:100 YT:Z:UU NH:i:1
SRR1552450.138797   16  chr1    3201132 60  100M    *   0   0   CATTTTTAACAGCATATTTGTCTTAGCTTTAAATCCAGAGTACTGTTTGGCTTCAAAGAAGATAGTCATCTCTGGTTCTCTTACTGAGAATAGAAAGTCT    DDEEEEEEEFFFFFFFHHHHHIIGCHGEJJJJJJJJJJIJJJJJJJJJJJJIJIJJJJJJJJJJJJIGJJJJJIJJJJJJJIHJJJJHHHHHFFFFFCCC    AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:100 YT:Z:UU NH:i:1

The first 11 columns of each line have an official specification

Column Official Name Brief
1 QNAME Sequence ID
2 FLAG Sequence quality expressed as a bitwise flag
3 RNAME Chromosome
4 POS Start Position
5 MAPQ Mapping Quality
6 CIGAR Describes positions of matches, insertions, deletions w.r.t reference
7 RNEXT Ref. name of mate / next read
8 PNEXT Postion of mate / next read
9 TLEN Observed Template length
10 SEQ Sequence
11 QUAL Base Qualities

There can also be all manner of optional tags as extra columns introduce by an aligner or downstream analysis tool. A common use is the RG tag which refers back to the read groups in the header.

Quality Control Flags

The “flags” in the sam file can represent useful QC information

  • Read is unmapped
  • Read is paired / unpaired
  • Read failed QC
  • Read is a PCR duplicate (see later)

The combination of any of these properties is used to derive a numeric value. For instance, a particular read might have a flag of 163

Derivation

There is a set of properties that a read can possess. If a particular property is observed, a corresponding power of 2 is added multiplied by 1. The final value is derived by summing all the powers of 2.

    ReadHasProperty     Binary  MultiplyBy
isPaired    TRUE    1   1
isProperPair    TRUE    1   2
isUnmappedQuery     FALSE   0   4
hasUnmappedMate     FALSE   0   8
isMinusStrand   FALSE   0   16
isMateMinusStrand   TRUE    1   32
isFirstMateRead     FALSE   0   64
isSecondMateRead    TRUE    1   128
isSecondaryAlignment    FALSE   0   256
isNotPassingQualityControls     FALSE   0   512
isDuplicate     FALSE   0   1024

Value of flag is given by

1x1 + 1x2 + 0x4 + 0x8 + 0x16 + 1x32 + 0x64 + 1x128 + 0x256 + 0x512 + 0x1024 = 163

See also

Have a CIGAR!

The CIGAR (Compact Idiosyncratic Gapped Alignment Report) string is a way of encoding the match between a given sequence and the position it has been assigned in the genome. It is comprised by a series of letters and numbers to indicate how many consecutive bases have that mapping.

Code Description
M alignment match
I insertion
D deletion
N skipped
S soft-clipping
H hard-clipping

e.g.

  • 101M
    • 101 bases matching the reference
  • 1S100M
    • 1 soft-clipped read followed by 100 matches
  • 15M87N70M90N16M
    • 15 matches following by 87 bases skipped followed by 70 matches etc.

sam or bam?

Alignment algorithms such as HISAT2 tend to produce a sam file as their raw output, whereas we usually analyse a .bam file. The contents of both files are exactly the same. Whereas a sam file is designed to be human-readable, a bam file can be processed more efficiently by a computer as it is compressed and indexed.

The reads in a sam file tend to be arranged in the order that they were generated by the sequencer. On the other hand, the bam file that you see in Galaxy has been sorted according to the position that the reads map. If you run your own alignments using command line software, you will need to use a tool to sort and index the data before analysis.


Quality assessment of the aligned reads

samtools will calculate QC statistics for a set of aligned reads in bam format

SAM/BAM -> Samtools stats

If you view the output you will see that it is not very easy to interpret.

FASTQ Quality Control -> Multiqc

make sure Which tool was used to generate logs is set to Samtools and select the Samtools stats…. files that were produced in the previous step

Section 4. Visualise the aligned reads with IGV

Download the bam files you have created in the previous step by clicking the disk icon on the right-hand panel. Make sure to click both the Download dataset and Download index buttons. We will now visualise the alignments using the Integrative Genomics Viewer (IGV).

Introducing the IGV Browser

Whilst tools like R are very powerful and allow you to perform statistical analyses and test hypotheses, there is no substitute for looking at the data. A trained-eye can quite quickly get a sense of the data quality before any computational analyses have been run. Futhermore, as the person requesting the sequencing, you probably know a lot about the biological context of the samples and what to expect.

  • IGV has been developed by the Broad Institute and is able to display most kinds of genomic data
    • expression
    • ChIP
    • whole-genome resequencing
    • shRNA
  • It is a Java desktop application and can be run either locally of from the Broad website
  • To run IGV yourself you will need to agree to the license and download the version for your OS

If you have problems running IGV, you may need to download an updated version of Java

https://java.com/download

A quick tour of IGV

For more details

  1. Sample information panel
    • Information about samples you have loaded
    • e.g. Sample ID, Gender, Age, Tumour / Normal
  2. Genome Navigation panel
    • Jump to a genomic region in Chr:Start-End format
    • Jump to a gene symbol of interest
  3. Data panel
    • Your sequencing reads will be displayed here
    • Or whatever data you have loaded
  4. Attribute panel
    • Gene locations
    • Genome sequence (if zoomed-in at appropriate level)
    • Proteins

Example

Go to File -> Load from file and select the aligned bam files from HISAT2. Note that the index files .bai need to be present in the same directory. However, you only need to click on the .bam

Make sure that the genome selected is mm10. The default wil be human hg19

  • The black dotted vertical lines indicates the centre of the view
  • Each of the grey pointed rectangles represents a sequencing reads
    • whether the pointed bit is on the left or right indicates if the read is forward or reverse.
  • A coverage track is also generated
  • You should see the read that we described in detail in the previous section by hovering over the reads to display the information from the .bam file

The view in IGV is not static and we can scroll-along the genome by holding-down the left mouse in the data panel and dragging left and right

It’s worth noting that the display settings may be showing fewer reads than you have (downsampling) in order to conserve memory. Also, some QC-fail or PCR duplicates may be filtered.

We also have some options on how to display the reads themselves, which we can acccess by right-clicking on the bam track

Sorting alignments by:-

  • start
  • strand
  • base
  • mapping quality
  • insert size

The reads themselves can also be coloured according to

  • insert size
  • read strand
  • sample

Section 5. Quantification (Counting reads in features)

In order to test for differential expression, we need to count up how many times each “feature” is observed is each sample. The goal of such operations is to produce a count table such as that shown below. We can then apply statistical tests to these data

HTSeq-count creates a count matrix using the number of the reads from each bam file that map to the genomic features. For each feature (a gene for example) a count matrix shows how many reads were mapped to this feature.

Various rules can be used to assign counts to features

To obtain the coordinates of each gene, we can use the UCSC genome browser which is integrated into Galaxy.

Obtaining gene coordinates

Get Data -> UCSC Main table browser

Selecting the UCSC Main tool from Galaxy will take you to the UCSC table browser. From here we can extract gene coordinates for our genome of interest (sacCer3) in gtf format for processing with galaxy.

  • Set clade to Mammal
  • Set genome to Mouse
  • assembly Dec.2011 (GRCm38/mm10)
  • group Genes and Gene Prediction
  • track NCBI RefSeq
  • region genome
  • output format GTF - gene transfer format (limited) and send output to Galaxy

Click get output and send query to Galaxy to be returned to Galaxy. A new job will be submitted to retrieve the coordinates from UCSC

RNA Analysis > htseq-count

  1. Use HTSeq-count to count the number of reads for each feature.
    In the left tool panel menu, under NGS Analysis, select NGS Analysis > htseq-count and set the parameters as follows:
    • Aligned SAM/BAM file
      (Select one of four bam files, or all four using the multiple datasets option)
    • GFF file UCSC Main on Mouse:ncbiRefSeq (genome)
    • Use defaults for the other fields
    • Execute
  2. Repeat for the remaining bam files if running on each bam separately.
  3. Rename the ht-seq output for each sample. Do not rename the outputs that have “(no feature)” in their name

Further QC on the aligned reads

Additional QC of the aligned reads can be obtained with the Qualimap tool. This also uses information from the genome transcript file to calculate how many reads are counted in exonic, intronic and intergenic regions. For RNA-seq this percentage should be high; at least 80 to 90%.

RNA-Seq > Qualimap RNA-Seq QC

Create a count matrix

The htseq tool is designed to produce a separate table of counts for each sample. This is not particularly useful for other tools such as Degust (see next section) which require the counts to be presented in a data matrix where each row is a gene and each column is a particular sample in the dataset.

Collection Operations -> Column Join on Collections

  • In the Tabular Files section, select the ht-seq count files from your history SRR1552444.htseq, SRR1552450, etc… Holding the CTRL key allows multiple files to be selected
  • Keep Identifier column as 1

The output should look something like this…

  • Download to your computer

You are now ready to follow the next tutorial on Differential Expression

References

[1] Nookaew I, Papini M, Pornputtpong N, Scalcinati G, Fagerberg L, Uhlén M, Nielsen J: A comprehensive comparison of RNA-Seq-based transcriptome analysis from reads to differential gene expression and cross-comparison with microarrays: a case study in Saccharomyces cerevisiae. Nucleic Acids Res 2012, 40 (20):10084 – 10097. doi:10.1093/nar/gks804. Epub 2012 Sep 10

[2] Guirguis A, Slape C, Failla L, Saw J, Tremblay C, Powell D, Rossello F, Wei A, Strasser A, Curtis D: PUMA promotes apoptosis of hematopoietic progenitors driving leukemic progression in a mouse model of myelodysplasia. Cell Death Differ. 2016 Jun;23(6)

LS0tCnRpdGxlOiAiUk5BLXNlcSBQcmUtcHJvY2Vzc2luZyB0dXRvcmlhbCIKYXV0aG9yOiAiTWFyayBEdW5uaW5nIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogIGh0bWxfZG9jdW1lbnQ6CiAgICBkZl9wcmludDogcGFnZWQKICAgIHRvYzogeWVzCmVkaXRvcl9vcHRpb25zOgogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUKLS0tCgoKCiMgSGFuZHMtb24gUk5BLXNlcSBBbmFseXNpcyBpbiBHYWxheHkKCiMjIEFja25vd2xlZGdlbWVudAoKX0Jhc2VkIG9uIHRoZSBSTkEtU2VxIHdvcmtzaG9wIGJ5IE1lbGJvdXJuZSBCaW9pbmZvcm1hdGljcyB3cml0dGVuIGJ5IE1haHRhYiBNaXJtb21lbmksIEFuZHJldyBMb25pZSwgSmVzc2ljYSBDaHVuZ18gW09yaWdpbmFsXShodHRwOi8vdmxzY2kuZ2l0aHViLmlvL2xzY2NfZG9jcy90dXRvcmlhbHMvcm5hX3NlcV9kZ2VfYWR2YW5jZWQvcm5hX3NlcV9hZHZhbmNlZF90dXRvcmlhbC8pCgpfTW9kaWZpZWQgYnkgRGF2aWQgUG93ZWxsIChNb25hc2ggQmlvaW5mb3JtYXRpY3MgUGxhdGZvcm0pXwoKX0Z1cnRoZXIgTW9kaWZpZWQgYnkgTWFyayBEdW5uaW5nIG9mIFNoZWZmaWVsZCBCaW9pbmZvcm1hdGljcyBDb3JlXwoKCiMjIyBTaGVmZmllbGQgQmlvaW5mb3JtYXRpY3MgQ29yZQo8aW1nIHNyYz0ibWVkaWEvbG9nby1zbS5wbmciIGFsaWduPXJpZ2h0PgoKd2ViIDogW3NiYy5zaGVmLmFjLnVrXShodHRwczovL3NiYy5zaGVmLmFjLnVrKSAgCnR3aXR0ZXI6IFtAU2hlZmZCaW9pbmZDb3JlXShodHRwczovL3R3aXR0ZXIuY29tL1NoZWZmQmlvaW5mQ29yZSkgIAplbWFpbDogW2Jpb2luZm9ybWF0aWNzLWNvcmVAc2hlZmZpZWxkLmFjLnVrXShiaW9pbmZvcm1hdGljcy1jb3JlQHNoZWZmaWVsZC5hYy51aykKCi0tLS0tCgojIyBUdXRvcmlhbCBPdmVydmlldwoKVGhpcyB0dXRvcmlhbCB3aWxsIGNvdmVyIHRoZSBiYXNpY3Mgb2YgUk5BLXNlcSB1c2luZyBHYWxheHk7IGEgb3Blbi1zb3VyY2Ugd2ViLWJhc2VkIHBsYXRmb3JtIGZvciB0aGUgYW5hbHlzaXMgb2YgYmlvbG9naWNhbCBkYXRhLiBZb3Ugc2hvdWxkIGdhaW4gYW4gYXBwcmVjaWF0aW9uIG9mIHRoZSB0YXNrcyBpbnZvbHZlZCBpbiBhIHR5cGljYWwgUk5BLXNlcSBhbmFseXNpcyBhbmQgYmUgY29tZm9ydGFibGUgd2l0aCB0aGUgb3V0cHV0cyBnZW5lcmF0ZWQgYnkgdGhlIEJpb2luZm9ybWF0aWNpYW4uCgojIyMgTW9yZSBvbiBHYWxheHkKClRoZSBvZmZpY2lhbCBHYWxheHkgcGFnZSBoYXMgbWFueSBbdHV0b3JpYWxzXShodHRwczovL2dhbGF4eXByb2plY3Qub3JnL2xlYXJuLykgb24gdXNpbmcgdGhlIHNlcnZpY2UsIGFuZCBleGFtcGxlcyBvZiBvdGhlciB0eXBlcyBvZiBhbmFseXNpcyB0aGF0IGNhbiBiZSBwZXJmb3JtZWQgb24gdGhlIHBsYXRmb3JtLgoKVGhvc2UgZXZlbnR1YWxseSB3YW50ZWQgdG8gcGVyZm9ybSB0aGVpciBvd24gUk5BLXNlcSBhbmFseXNpcyAoZm9yIGV4YW1wbGUgaW4gUiksIHNob3VsZCBsb29rIG91dCBmb3Igb3RoZXIgY291cnNlcwoKIyMjIENvdXJzZXMgb24gYW5hbHlzaW5nIFJOQS1zZXEgZGF0YSBpbiBSCgotIFtTaGVmZmllbGQgQmlvaW5mb3JtYXRpY3MgQ29yZV0oaHR0cDovL3NiYy5zaGVmLmFjLnVrL3RyYWluaW5nL3JuYS1zZXEtaW4tci0yMDE5LTAxLTE0LykKLSBbTW9uYXNoIEJpb2luZm9ybWF0aWNzIFBsYXRmb3JtXShodHRwOi8vbW9uYXNoYmlvaW5mb3JtYXRpY3NwbGF0Zm9ybS5naXRodWIuaW8vUk5Bc2VxLURFLWFuYWx5c2lzLXdpdGgtUi8pCgoKCi0tLS0tCgojIyBCYWNrZ3JvdW5kCgojIyMjIFdoZXJlIGRvIHRoZSBkYXRhIGluIHRoaXMgdHV0b3JpYWwgY29tZSBmcm9tPwpUaGUgZGF0YSBmb3IgdGhpcyB0dXRvcmlhbCBjb21lcyBmcm9tIGEgTmF0dXJlIENlbGwgQmlvbG9neSBwYXBlciwgWypFR0YtbWVkaWF0ZWQgaW5kdWN0aW9uIG9mIE1jbC0xIGF0IHRoZSBzd2l0Y2ggdG8gbGFjdGF0aW9uIGlzIGVzc2VudGlhbCBmb3IgYWx2ZW9sYXIgY2VsbCBzdXJ2aXZhbCpdKGh0dHA6Ly93d3cubmNiaS5ubG0ubmloLmdvdi9wdWJtZWQvMjU3MzA0NzIpIFtARnUyMDE1XS4gCgpUaGlzIHN0dWR5IGV4YW1pbmVzIHRoZSBleHByZXNzaW9uIHByb2ZpbGVzIG9mIGJhc2FsIHN0ZW0tY2VsbCBlbnJpY2hlZCBjZWxscyAoQikgYW5kIGNvbW1pdHRlZCBsdW1pbmFsIGNlbGxzIChMKSBpbiB0aGUgbWFtbWFyeSBnbGFuZCBvZiB2aXJnaW4sIHByZWduYW50IGFuZCBsYWN0YXRpbmcgbWljZS4gU2l4IGdyb3VwcyBhcmUgcHJlc2VudCwgd2l0aCBvbmUgZm9yIGVhY2ggY29tYmluYXRpb24gb2YgY2VsbCB0eXBlIGFuZCBtb3VzZSBzdGF0dXMuIEVhY2ggZ3JvdXAgY29udGFpbnMgdHdvIGJpb2xvZ2ljYWwgcmVwbGljYXRlcy4KClRoZSBmdWxsIGV4cGVyaW1lbnRhbCBkZXNpZ24gaXMgYXMgZm9sbG93czotCgpSdW4gIHwgTmFtZSB8IENlbGxUeXBlIHwgU3RhdHVzCi0tLS0tLS0tLS0tLS0gfCAtLS0tLS0tLS0tLS0tIHwgLS0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0tLS0gIApTUlIxNTUyNDQ0IHwgTUNMMS1MQSB8IGJhc2FsIHwgdmlyZ2luClNSUjE1NTI0NDUgfCBNQ0wxLUxCIHwgbHVtaW5hbCB8IHZpcmdpbgpTUlIxNTUyNDQ2IHwgTUNMMS1MQyB8IEx1bWluYWwgfCBwcmVnbmFuY3kKU1JSMTU1MjQ0NyB8IE1DTDEtTEQgfCBMdW1pbmFsIHwgcHJlZ25hbmN5ClNSUjE1NTI0NDggfCBNQ0wxLUxFIHwgbHVtaW5hbCB8IGxhY3RhdGlvbgpTUlIxNTUyNDQ5IHwgTUNMMS1MRiB8IGx1bWluYWwgfCBsYWN0YXRpb24KU1JSMTU1MjQ1MCB8IE1DTDEtREcgfCBiYXNhbCB8IHZpcmdpbgpTUlIxNTUyNDUxIHwgTUNMMS1ESCB8IGx1bWluYWwgfCB2aXJnaW4KU1JSMTU1MjQ1MiB8IE1DTDEtREkgfCBiYXNhbCB8IHByZWduYW5jeQpTUlIxNTUyNDUzIHwgTUNMMS1ESiB8IGJhc2FsIHwgcHJlZ25hbmN5ClNSUjE1NTI0NTQgfCBNQ0wxLURLIHwgYmFzYWwgfCBsYWN0YXRpb24KU1JSMTU1MjQ1NSB8IE1DTDEtREwgfCBiYXNhbCB8IGxhY3RhdGlvbgoKCgpGb3IgdGhpcyB0dXRvcmlhbCwgd2Ugd2lsbCBhc3N1bWUgdGhhdCB0aGUgKndldC1sYWIqIHN0YWdlcyBvZiB0aGUgZXhwZXJpbWVudCBoYXZlIGJlZW4gcGVyZm9ybWVkIGFuZCB3ZSBhcmUgbm93IGluIHRoZSByaWdodC1oYW5kIGJyYW5jaCBvZiB0aGUgd29ya2Zsb3cuIEluIHRoaXMgdHV0b3JpYWwgd2Ugd2lsbCBkZW1vbnN0cmF0ZSB0aGUgc3RlcHMgb2YgKipRdWFsaXR5IGFzc2Vzc21lbnQqKiwgKiphbGlnbm1lbnQqKiwgKipxdWFudGlmaWNhdGlvbioqIGFuZCAqKmRpZmZlcmVudGlhbCBleHByZXNzaW9uIHRlc3RpbmcqKi4KCgojIyBTZWN0aW9uIDE6IFByZXBhcmF0aW9uCiMjIyMgMS4gU2lnbi11cCB0byB0aGUgRXVyb3BlYW4gR2FsYXh5IHNlcnZlcgoKCi0gaHR0cHM6Ly91c2VnYWxheHkuZXUKLSBVc2UgdGhpcyBsaW5rIHRvIGFjY2VzcyB0aGUgc3BlY2lhbCBxdWV1ZSBjcmVhdGVkIGZvciB0aGlzIGNvdXJzZQogICsgaHR0cHM6Ly91c2VnYWxheHkuZXUvam9pbi10cmFpbmluZy9zYmMtMjAxOTAtMTIKCgoqKk1ha2Ugc3VyZSB5b3UgY2hlY2sgeW91ciBlbWFpbCB0byBhY3RpdmF0ZSB5b3VyIGFjY291bnQqKgoKIyMjIyAyLiAgSW1wb3J0IHRoZSBSTkEtc2VxIGRhdGEgZm9yIHRoZSB3b3Jrc2hvcC4KCldlIGNhbiBnb2luZyB0byBpbXBvcnQgdGhlIFsqZmFzdHEqIGZpbGVzXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9GQVNUUV9mb3JtYXQpIGZvciB0aGlzIGV4cGVyaW1lbnQuIFRoaXMgaXMgYSBzdGFuZGFyZCBmb3JtYXQgZm9yIHN0b3JpbmcgcmF3IHNlcXVlbmNpbmcgcmVhZHMgYW5kIHRoZWlyIGFzc29jaWF0ZWQgcXVhbGl0eSBzY29yZXMuIFRvIG1ha2UgdGhlIHByYWN0aWNhbCBxdWlja2VyLCB3ZSBoYXZlICpkb3duc2FtcGxlZCogdGhlIG9yaWdpbmFsIGZhc3RxIGZpbGVzIHRvIGhhbGYgYSBtaWxsaW9uIHJlYWRzLgoKCjxkaXYgY2xhc3M9ImFsZXJ0IGFsZXJ0LWluZm8iPgoKIyMjIyAqKkdldCBEYXRhIC0+IFVwbG9hZCBGaWxlICoqIAoKPC9kaXY+CgpZb3UgY2FuIGltcG9ydCB0aGUgZGF0YSBieToKCjEuICBJbiB0aGUgdG9vbCBwYW5lbCBsb2NhdGVkIG9uIHRoZSBsZWZ0LCB1bmRlciBCYXNpYyBUb29scyBzZWxlY3QgKipHZXQKICAgIERhdGEgPiBVcGxvYWQgRmlsZSoqLiBDbGljayBvbiB0aGUgKipDaG9vc2UgbG9jYWwgZmlsZSogYnV0dG9uIG9uIHRoZQogICAgYm90dG9tIHNlY3Rpb24gb2YgdGhlIHBvcC11cCB3aW5kb3cuCjIuICBOYXZpZ2F0ZSB0byB0aGUgYGZhc3RxYCBkaXJlY3Rvcnkgb2YgdGhlIHppcCBmaWxlIHRoYXQgeW91IGRvd25sb2FkZWQgZnJvbSBnb29nbGUgZHJpdmUKICAgIFRoZXJlIGFyZSB0d28gZmlsZXMgYXJlIHNpbmdsZS1lbmQgc2FtcGxlcyBmcm9tIHRoZSBiYXNhbC12aXJnaW4gY29uZGl0aW9uLiAKCmBTUlIxNTUyNDQ0LmZhc3RxLmd6YApgU1JSMTU1MjQ1MC5mYXN0cS5nemAKIAogYW5kIHRoZXNlIHR3byBmaWxlcyBhcmUgc2luZ2xlLWVuZCBzYW1wbGVzIGZyb20gdGhlIGJhc2FsIHByZWduYW50IGNvbmRpdGlvbi4KCmBTUlIxNTUyNDUyLmZhc3RxLmd6YApgU1JSMTU1MjQ1My5mYXN0cS5nemAKPC9kaXY+CgozLiAgWW91IHNob3VsZCBub3cgaGF2ZSB0aGVzZSA0IGZpbGVzIGluIHlvdXIgaGlzdG9yeToKICAgIC0gYFNSUjE1NTI0NDQuZmFzdHEuZ3pgCiAgICAtIGBTUlIxNTUyNDUwLmZhc3RxLmd6YAogICAgLSBgU1JSMTU1MjQ1Mi5mYXN0cS5nemAKICAgIC0gYFNSUjE1NTI0NTMuZmFzdHEuZ3pgCgoKCkVhY2ggcmVhZCBpcyBkZXNjcmliZWQgYnkgNCBsaW5lcyBpbiB0aGUgZmlsZTotCgo8aW1nIHNyYz0ibWVkaWEvZmFzdHEtaGVhZGVyLnBuZyI+CgpUaGUgcXVhbGl0eSBzY29yZXMgYXJlIFtBU0NJSV0oaHR0cDovL2FzY2lpLWNvZGUuY29tLykgcmVwcmVzZW50YXRpb25zIG9mIGhvdyBjb25maWRlbnQgd2UgYXJlIHRoYXQgYSBwYXJ0aWN1bGFyIGJhc2UgaGFzIGJlZW4gY2FsbGVkIGNvcnJlY3RseS4gTGV0dGVycyB0aGF0IGFyZSBmdXJ0aGVyIGFsb25nIHRoZSBhbHBoYWJldCBpbmRpY2F0ZSBoaWdoZXIgY29uZmlkZW5jZS4gVGhpcyBpcyBpbXBvcnRhbnQgd2hlbiB0cnlpbmcgdG8gaWRlbnRpZnkgdHlwZXMgb2YgZ2Vub21lIHZhcmlhdGlvbiBzdWNoIGFzIHNpbmdsZSBiYXNlIGNoYW5nZXMsIGJ1dCBpcyBhbHNvIGluZGljYXRpdmUgb2YgdGhlIG92ZXJhbGwgcXVhbGl0eSBvZiB0aGUgc2VxdWVuY2luZy4gRGlmZmVyZW50IHNjYWxlcyBoYXZlIGJlZW4gZW1wbG95ZWQgb3ZlciB0aW1lIChyZXN1bHRpbmcgaW4gYSBkaWZmZXJlbnQgc2V0IG9mIGNoYXJhY3RlcnMgYXBwZWFyaW5nIGluIHRoZSBmaWxlKS4gV2Ugd2lsbCBuZWVkIHRvIHRlbGwgR2FsYXh5IHdoaWNoIHNjYWxlIGhhcyBiZWVuIHVzZWQgaW4gb3JkZXIgdGhhdCB3ZSBjYW4gcHJvY2VzcyB0aGUgZGF0YSBjb3JyZWN0bHkuCgoKIyMjIERlcml2aW5nIHRoZSBRdWFsaXR5IFNjb3JlCgpGaXJzdCBvZiBhbGwsIHdlIGNvbnZlcnQgdGhlIGJhc2UtY2FsbGluZyBwcm9iYWJpbGl0eSAocCkgaW50byBhIGBRYCBzY29yZSB1c2luZyB0aGUgZm9ybXVsYQoKLSBRdWFsaXR5IHNjb3JlcyAkJCBRID0gLTEwbG9nX3sxMH1wJCQKICAgICsgUSA9IDMwLCBwPTAuMDAxCiAgICArIFEgPSAyMCwgcD0wLjAxCiAgICArIFEgPSAxMCwgcD0wLjEKLSBUaGVzZSBudW1lcmljIHF1YW50aWVzIGFyZSAqZW5jb2RlZCogYXMgWyoqQVNDSUkqKl0oaHR0cDovL2FzY2lpLWNvZGUuY29tLykgY29kZQogICAgKyBBdCBsZWFzdCAzMyB0byBnZXQgdG8gbWVhbmluZ2Z1bCBjaGFyYWN0ZXJzCiAgICAoaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRkFTVFFfZm9ybWF0KQogICAgCiFbXShtZWRpYS9waHJlZC5wbmcpICAgICAgCgojIyMgUXVhbGl0eSBTY29yZXMgdG8gcHJvYmFiaWxpdGllcwoKLSBsb29rLXVwIHRoZSBBU0NJSSBjb2RlIGZvciBlYWNoIGNoYXJhY3RlcgotIHN1YnRyYWN0IHRoZSBvZmZzZXQgdG8gZ2V0IHRoZSBRIHNjb3JlCi0gY29udmVydCB0byBhIHByb2JhYmlsaXR5IHVzaW5nIHRoZSBmb3JtdWxhOi0KCiQkIHAgPSAxMF57LVEvMTB9ICQkCgohW10obWVkaWEvcXVhbGl0eS10by1wcm9iLnBuZykKCkluIHByYWN0aWNlLCB3ZSBkb24ndCBoYXZlIHRvIGNvbnZlcnQgdGhlIHZhbHVlcyBhcyB3ZSBoYXZlIHNvZnR3YXJlIHRoYXQgd2lsbCBkbyB0aGlzIGF1dG9tYXRpY2FsbHkKCgotLS0tLQoKIyMgU2VjdGlvbiAyOiBRdWFsaXR5IGFzc2Vzc21lbnQgd2l0aCBGYXN0UUMKCltGYXN0UUNdKGh0dHBzOi8vd3d3LmJpb2luZm9ybWF0aWNzLmJhYnJhaGFtLmFjLnVrL3Byb2plY3RzL2Zhc3RxYy8pIGlzIGEgcG9wdWxhciB0b29sIGZyb20gW0JhYnJhaGFtIEluc3RpdHV0ZSBCaW9pbmZvcm1hdGljcyBHcm91cF0oaHR0cHM6Ly93d3cuYmlvaW5mb3JtYXRpY3MuYmFicmFoYW0uYWMudWsvaW5kZXguaHRtbCkgdXNlZCBmb3IgKnF1YWxpdHkgYXNzZXNzbWVudCogb2Ygc2VxdWVuY2luZyBkYXRhLiBNb3N0IEJpb2luZm9ybWF0aWNzIHBpcGVsaW5lcyB3aWxsIHVzZSBGYXN0UUMsIG9yIHNpbWlsYXIgdG9vbHMgaW4gdGhlIGZpcnN0IHN0YWdlIG9mIHRoZSBhbmFseXNpcy4gVGhlIFtkb2N1bWVudGF0aW9uXShodHRwczovL3d3dy5iaW9pbmZvcm1hdGljcy5iYWJyYWhhbS5hYy51ay9wcm9qZWN0cy9mYXN0cWMvSGVscC8pIGZvciBGYXN0UUMgd2lsbCBoZWxwIHlvdSB0byBpbnRlcnByZXQgdGhlIHBsb3RzIGFuZCBzdGF0cyBwcm9kdWNlZCBieSB0aGUgdG9vbC4gQSB0cmFmZmljIGxpZ2h0IHN5c3RlbSBpcyB1c2VkIHRvIGFsZXJ0IHRoZSB1c2VyJ3MgYXR0ZW50aW9uIHRvIHBvc3NpYmxlIGlzc3Vlcy4gSG93ZXZlciwgaXQgaXMgd29ydGggYmVhcmluZyBpbiBtaW5kIHRoYXQgdGhlIHRvb2wgaXMgYmxpbmQgdG8gdGhlIHBhcnRpY3VsYXIgdHlwZSBvZiBzZXF1ZW5jaW5nIHlvdSBhcmUgcGVyZm9ybWluZyAoaS5lLiB3aG9sZS1nZW5vbWUsIENoSVAtc2VxLCBSTkEtc2VxKSwgc28gc29tZSB3YXJuaW5ncyBtaWdodCBiZSBleHBlY3RlZCBkdWUgdG8gdGhlIG5hdHVyZSBvZiB5b3VyIGV4cGVyaW1lbnQuCgo8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC1pbmZvIj4KCiMjIyMgKkZhc3RRIFF1YWxpdHkgQ29udHJvbCogLT4gKkZhc3RRQyBSZWFkIFF1YWxpdHkgcmVwb3J0cyoKCjwvZGl2PgoKKipNYWtlIHN1cmUgeW91IHNlbGVjdCB0aGlzIHRvb2wuIFRoZXJlIGlzIGFub3RoZXIgdmVyc2lvbiBvZiBGYXN0UUMgcHJlc2VudCwgd2hpY2ggZG9lcyBub3QgcHJvZHVjZSBzb21lIG9mIHRoZSBvdXRwdXQgd2UgbmVlZCBmb3IgYSBsYXRlciBzdGVwKioKCi0gU2VsZWN0IG9uZSBvZiB0aGUgRkFTVFEgZmlsZXMgYXMgaW5wdXQgYW5kICpFeGVjdXRlKiB0aGUgdG9vbC4KLSBXaGVuIHRoZSB0b29sIGZpbmlzaGVzIHJ1bm5pbmcsIHlvdSBzaG91bGQgaGF2ZSBhbiBIVE1MIGZpbGUgaW4geW91ciBIaXN0b3J5LiBDbGljayBvbiB0aGUgZXllIGljb24gdG8gdmlldyB0aGUgdmFyaW91cyBxdWFsaXR5IG1ldHJpY3MuCi0gUnVuIEZhc3RxYyBvbiB0aGUgcmVtYWluZyBmYXN0cSBmaWxlcywgYnV0IGRvbid0IGV4YW1pbmUgdGhlIHJlc3VsdHMganVzdCB5ZXQuCgoKPGRpdiBjbGFzcz0iYWxlcnQgYWxlcnQtd2FybmluZyI+CgoqKlF1ZXN0aW9uOiBEbyB0aGUgZGF0YSBzZWVtIHRvIGJlIG9mIHJlYXNvbmFibGUgcXVhbGl0eT8gKioKCllvdSBjYW4gdXNlIHRoZSBbZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly93d3cuYmlvaW5mb3JtYXRpY3MuYmFicmFoYW0uYWMudWsvcHJvamVjdHMvZmFzdHFjL0hlbHAvMyUyMEFuYWx5c2lzJTIwTW9kdWxlcy8pIHRvIGhlbHAgaW50ZXJwcmV0IHRoZSBwbG90cwoKPC9kaXY+CgpJZiBwb29yIHF1YWxpdHkgcmVhZHMgdG93YXJkcyB0aGUgZW5kcyBvZiByZWFkcyBhcmUgY29uc2lkZXJlZCB0byBiZSBhIHByb2JsZW0sIG9yIHRoZXJlIGlzIGNvbnNpZGVyYWJsZSBhZGFwdGVyIGNvbnRhbWluYXRpb24sIHdlIGNhbiBlbXBsb3kgdmFyaW91cyB0b29scyB0byAqdHJpbSogb3VyIGRhdGEuCgpIb3dldmVyLCBhIHJlY2VudCBwYXBlciBkZW1vbnN0cmF0ZWQgdGhhdCByZWFkIHRyaW1taW5nIGlzIG5vIGxvbmdlciByZXF1aXJlZCBwcmlvciB0byBhbGlnbm1lbnQ6LSBodHRwczovL3d3dy5iaW9yeGl2Lm9yZy9jb250ZW50LzEwLjExMDEvODMzOTYydjEKCjxkaXYgY2xhc3M9ImFsZXJ0IGFsZXJ0LWluZm8iPgoKSWYgeW91IHN1c3BlY3QgY29udGFtaW5hdGlvbiBmcm9tIGFkYXB0ZXIgc2VxdWVuY2Ugb3IgdW5hY2NlcHRhYmxlIHF1YWxpdHkgc2NvcmVzIHRvd2FyZHMgdGhlIGVuZHMgb2YgcmVhZHMgdmFyaW91cyB0cmltbWluZyBvcHRpb25zIGFyZSBzdXBwb3J0ZWQgYnkgdGhlICpUcmltbW9tYXRpYyogdG9vbCAoYW1vbmdzdCBvdGhlcnMpCgojIyMjICpGQVNUQS9GQVNUUSogLT4gKlRyaW1tb21hdGljKgoKVGhlIG9wZXJhdGlvbnMgc3VwcG9ydGVkIGJ5IHRyaW1tb21hdGljIHdpbGwgcHJvYmFibHkgbm90IGJlIHZlcnkgaW5mb3JtYXRpdmUgb24gb3VyIGV4YW1wbGUgZGF0YSAoYXMgaXQgaGFzIGFscmVhZHkgYmVlbiBwcm9jZXNzZWQpLCBidXQgeW91IGNhbiB0cnkgc2V2ZXJhbCBvcGVyYXRpb25zIGlmIHlvdSBnZXQgdGltZTotCgotIFJlbW92aW5nIElsbHVtaW5hIGFkYXB0ZXIgc2VxdWVuY2VzIGJ5IHNldHRpbmcgKlBlcmZvcm0gaW5pdGlhbCBJTExVTUlOQUNMSVAqIHRvICpZZXMqIGFuZCBzZWxlY3RpbmcgdGhlIGFwcHJvcHJpYXRlIGFkYXB0ZXIgdHlwZQotIFJlbW92ZSBwb29yIHF1YWxpdHkgYmFzZXMgYXQgdGhlIGVuZCBvZiByZWFkcyBieSBjaG9vc2luZyAqQ3V0IGJhc2VzIG9mZiB0aGUgZW5kIG9mIGEgcmVhZCwgaWYgYmVsb3cgYSB0aHJlc2hvbGQgcXVhbGl0eSAoVFJBSUxJTkcpKiB1bmRlciAqU2VsZWN0IFRyaW1tb21hdGljIG9wZXJhdGlvbiB0byBwZXJmb3JtKgotIFJlbW92ZSBwb29yIHF1YWxpdHkgYmFzZXMgYXQgdGhlIHN0YXJ0IG9mIHJlYWRzIGJ5IGNob29zaW5nICpDdXQgYmFzZXMgb2ZmIHRoZSBzdGFydCBvZiBhIHJlYWQsIGlmIGJlbG93IGEgdGhyZXNob2xkIHF1YWxpdHkgKExFQURJTkcpKiB1bmRlciAqU2VsZWN0IFRyaW1tb21hdGljIG9wZXJhdGlvbiB0byBwZXJmb3JtKgotIFlvdSBjYW4gYXBwbHkgbXVsdGlwbGUgb3BlcmF0aW9ucyBpbiB0dXJuIGJ5IGNsaWNraW5nICpJbnNlcnQgVHJpbW1vbWF0aWMgT3BlcmF0aW9uKgoKPC9kaXY+Cgo8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC1pbmZvIj4KCklmIHlvdSBhbHNvIHN1c3BlY3QgY29udGFtaW5hdGlvbiBieSBhbm90aGVyIG9yZ2FuaXNtLCBvciByUk5BIHByZXNlbnQgaW4geW91ciBkYXRhLCB5b3UgY2FuIHVzZSB0aGUgc29ydE1lUk5BIHRvb2wgdG8gcmVtb3ZlIHRoaXMgYXJ0ZWZhY3QuCjwvZGl2PgoKCiMjIENvbWJpbmluZyBRQyByZXBvcnRzCgpJdCBjYW4gYmUgcXVpdGUgdGlyZXNvbWUgdG8gY2xpY2sgdGhyb3VnaCBtdWx0aXBsZSBRQyByZXBvcnRzIGFuZCBjb21wYXJlIHRoZSByZXN1bHRzIGZvciBkaWZmZXJlbnQgc2FtcGxlcy4gSXQgaXMgdXNlZnVsIHRvIGhhdmUgYWxsIHRoZSBRQyBwbG90cyBvbiB0aGUgc2FtZSBwYWdlIHNvIHRoYXQgd2UgY2FuIG1vcmUgZWFzaWx5IHNwb3QgdHJlbmRzIGluIHRoZSBkYXRhLgoKVGhlIFttdWx0aXFjXShodHRwczovL211bHRpcWMuaW5mby8pIHRvb2wgaGFzIGJlZW4gZGVzaWduZWQgZm9yIHRoZSB0YXNrcyBvZiBhZ2dyZWdhdGluZyBxYyByZXBvcnRzIGFuZCBjb21iaW5pbmcgaW50byBhIHNpbmdsZSByZXBvcnQgdGhhdCBpcyBlYXN5IHRvIGRpZ2VzdC4KCgo8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC1pbmZvIj4KCipGQVNUUSBRdWFsaXR5IENvbnRyb2wqIC0+ICpNdWx0aXFjKgoKPC9kaXY+CgpVbmRlciAqV2hpY2ggdG9vbCB3YXMgdXNlZCBnZW5lcmF0ZSBsb2dzPyogQ2hvb3NlICpmYXN0cWMqIGFuZCBzZWxlY3QgdGhlIFJhd0RhdGEgb3V0cHV0IGZyb20gdGhlIGZhc3RxYyBydW4gb24gZWFjaCBvZiB5b3VyIGJhbSBmaWxlcy4KCgo8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC13YXJuaW5nIj4KClF1ZXN0aW9uOiBSZXBlYXQgdGhlIEZhc3RRQyBhbmFseXNpcyBmb3IgdGhlIHJlbWFpbmluZyBmYXN0cSBmaWxlcyBhbmQgY29tYmluZSB0aGUgcmVwb3J0cyB3aXRoIGBtdWx0aVFDYC4gRG8gdGhlIGZhc3RxIGZpbGVzIHNlZW0gdG8gaGF2ZSBjb25zaXN0ZW50bHkgaGlnaC1xdWFsaXR5Pwo8L2Rpdj4KCgojIyBTZWN0aW9uIDM6IEFsaWdubWVudAoKSW4gdGhpcyBzZWN0aW9uIHdlIG1hcCB0aGUgcmVhZHMgaW4gb3VyIEZBU1RRIGZpbGVzIHRvIGEgcmVmZXJlbmNlIGdlbm9tZS4gQXMKdGhlc2UgcmVhZHMgb3JpZ2luYXRlIGZyb20gbVJOQSwgd2UgZXhwZWN0IHNvbWUgb2YgdGhlbSB3aWxsIGNyb3NzIGV4b24vaW50cm9uCmJvdW5kYXJpZXMgd2hlbiB3ZSBhbGlnbiB0aGVtIHRvIHRoZSByZWZlcmVuY2UgZ2Vub21lLiBgSElTQVQyYCBpcyBhIHNwbGljZS1hd2FyZQptYXBwZXIgZm9yIFJOQS1zZXEgcmVhZHMgdGhhdCBpcyBiYXNlZCBvbiBCb3d0aWUuIEl0IHVzZXMgdGhlIG1hcHBpbmcgcmVzdWx0cwpmcm9tIEJvd3RpZSB0byBpZGVudGlmeSBzcGxpY2UganVuY3Rpb25zIGJldHdlZW4gZXhvbnMuIE1vcmUgaW5mb3JtYXRpb24gb24KSElTQVQyIGNhbiBiZSBmb3VuZCBbaGVyZV0oaHR0cHM6Ly9jY2Iuamh1LmVkdS9zb2Z0d2FyZS9oaXNhdDIvaW5kZXguc2h0bWwpLgoKCjxkaXYgY2xhc3M9ImFsZXJ0IGFsZXJ0LWluZm8iPgoKTWFwcGluZyAtPiBISVNBVDIKCjwvZGl2PgoKCgojIyMjIDEuICBNYXAvYWxpZ24gdGhlIHJlYWRzIHdpdGggSElTQVQyIHRvIHRoZSBtbTEwIHJlZmVyZW5jZSBnZW5vbWUKSW4gdGhlIGxlZnQgdG9vbCBwYW5lbCBtZW51LCB1bmRlciBOR1MgQW5hbHlzaXMsIHNlbGVjdAoqKk1hcHBpbmcgPiBISVNBVDIqKiBhbmQgc2V0IHRoZSBwYXJhbWV0ZXJzIGFzIGZvbGxvd3M6ICAKCi0gKipJcyB0aGlzIHNpbmdsZS1lbmQgb3IgcGFpcmVkLWVuZCBkYXRhPyoqIFNpbmdsZS1lbmQgKGFzIGluZGl2aWR1YWwgZGF0YXNldHMpICAKLSAqKkZBU1RRIGZpbGUqKiAgCihDbGljayBvbiB0aGUgbXVsdGlwbGUgZGF0YXNldHMgaWNvbiBhbmQgc2VsZWN0IGFsbCBmb3VyIG9mIHRoZQpGQVNUUSBmaWxlcykKICAgIC0gYFNSUjE1NTI0NDQuZmFzdHEuZ3pgCiAgICAtIGBTUlIxNTUyNDUwLmZhc3RxLmd6YAogICAgLSBgU1JSMTU1MjQ1Mi5mYXN0cS5nemAKICAgIC0gYFNSUjE1NTI0NTMuZmFzdHEuZ3pgCgotICoqU291cmNlIGZvciB0aGUgcmVmZXJlbmNlIGdlbm9tZSoqIFVzZQpidWlsdC1pbiBnZW5vbWUKLSAqKlNlbGVjdCBhIHJlZmVyZW5jZSBnZW5vbWU6KiogTW91c2UgKE11cyBNdXNjdWx1cyk6IG1tMTAKLSBVc2UgZGVmYXVsdHMgZm9yIHRoZSBvdGhlciBmaWVsZHMKLSBFeGVjdXRlCgoKTm90ZTogVGhpcyBtYXkgdGFrZSBhIGZldyBtaW51dGVzLCBkZXBlbmRpbmcgb24gaG93IGJ1c3kgdGhlIHNlcnZlciBpcy4KCgoKIyMjIyAyLiAgUmVuYW1lIHRoZSBvdXRwdXQgZmlsZXMKWW91IHNob3VsZCBoYXZlIDUgb3V0cHV0IGZpbGVzIGZvciBlYWNoIG9mIHRoZSBGQVNUUSBpbnB1dCBmaWxlczoKCmBISVNBVDIgb24gZGF0YS4uIGFsaWduZWQgcmVhZHMgKEJBTSlgCgpJdCB3aWxsIGJlIGhlbHBmdWwgdG8gcmVuYW1lIHRoZXNlIHRvIHNvbWV0aGluZyBzaG9ydGVyIGZvciB0aGUgbmV4dCBzdGVwcy4KCi0gYFNSUjE1NTI0NDQuYmFtYAotIGBTUlIxNTUyNDUwLmJhbWAKLSBgU1JSMTU1MjQ1Mi5iYW1gCi0gYFNSUjE1NTI0NTMuYmFtYAoKPGRpdiBjbGFzcz0iYWxlcnQgYWxlcnQtaW5mbyI+CgpJZiB0aGlzIHN0ZXAgaXMgdGFraW5nIHRvbyBsb25nLCB0aGVyZSBpcyBhbiBhbGlnbmVkIGJhbSBmaWxlIHByZXNlbnQgaW4gdGhlIGdvb2dsZSBkcml2ZSBsaW5rLiBZb3UgY2FuIHVzZSB0aGlzIGluIHRoZSBmb2xsb3dpbmcgc3RlcHMgb2YgdGhlIHR1dG9yaWFsLgoKPC9kaXY+Cgo8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC1pbmZvIj4KCipTVEFSKiBpcyBhbHNvIGFub3RoZXIgcG9wdWxhciBvcHRpb24gZm9yIGFsaWduZWQgUk5BLXNlcSByZWFkcy4gV2Ugd29uJ3QgY292ZXIgdGhpcyB0b2RheSwgb3IgdGhlIHJlbGF0aXZlIG1lcml0cyBvZiBkaWZmZXJlbnQgbWV0aG9kcy4gSWYgeW91IHdhbnQgdG8gdHJ5IFNUQVIgaW4geW91ciBvd24gdGltZSB5b3UgY2FuIGZpbmQgaXQgdW5kZXIuCgoKPGRpdiBjbGFzcz0iYWxlcnQgYWxlcnQtaW5mbyI+CgpNYXBwaW5nIC0+IFJOQSBTVEFSCgo8L2Rpdj4KCiMjIEFib3V0IHRoZSBhbGlnbmVkIHJlYWQgZm9ybWF0CgpVbmxpa2UgbW9zdCBvZiBCaW9pbmZvbWF0aWNzLCBhICpzaW5nbGUgc3RhbmRhcmQqIGZpbGUgZm9ybWF0IGhhcyBlbWVyZ2VkIGZvciBhbGlnbmVkIHJlYWRzLiBNb3Jlb2V2ZXIsIHRoaXMgZmlsZSBmb3JtYXQgaXMgY29uc2lzdGVudCByZWdhcmRsZXNzIG9mIHdoZXRoZXIgeW91IGhhdmUgRE5BLXNlcSwgUk5BLXNlcSwgQ2hJUC1zZXEuLi4gZGF0YS4gCgoKVGhlIGZpcnN0IHBhcnQgb2YgdGhlIGhlYWRlciBsaXN0cyB0aGUgbmFtZXMgKGBTTmApIG9mIHRoZSBzZXF1ZW5jZXMgKGNocm9tb3NvbWVzKSB1c2VkIGluIGFsaWdubWVudCwgdGhlaXIgbGVuZ3RoIChgTE5gKS4gU29tZXRpbWVzLCAgYSAqbWQ1c3VtKiAiW2RpZ2l0YWwgZmluZ2VycHJpbnRdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL01kNXN1bSkiIG9mIHRoZSBgLmZhc3RhYCBmaWxlIHVzZWQgZm9yIGFsaWdubWVudCAoYE01YCkgaXMgc2hvd24uCgpgYGAKQEhEIFZOOjEuMCBTTzpjb29yZGluYXRlCkBTUSBTTjpjaHIxIExOOjE5NTQ3MTk3MQpAU1EgU046Y2hyMTAgTE46MTMwNjk0OTkzCkBTUSBTTjpjaHIxMSBMTjoxMjIwODI1NDMKLi4uLi4KLi4uLi4KCmBgYAoKSWYgbXV0bGlwbGUgc2FtcGxlcyB3ZXJlIHByZXNlbnQgaW4gdGhlIGZpbGUgKGkuZS4gdGhlIHNhbXBsZXMgaGF2ZSBiZWVuICptdWx0aXBsZXhlZCopLCAqcmVhZCBncm91cHMqIGNhbiBiZSB1c2VkIHRvIGlkZW50aWZ5IHdoaWNoIHNlcXVlbmNpbmcgbGlicmFyeSwgc2VxdWVuY2luZyBjZW50cmUsIExhbmUsIHNhbXBsZSBuYW1lIGV0Yy4KCigqKm5vdCBwcmVzZW50IGZvciB0aGUgZXhhbXBsZSBkYXRhIGluIHRoaXMgY291cnNlKiopCgpgYGAKQFJHCUlEOlNSUjA3Nzg1MAlDTjpiaQlMQjpTb2xleGEtNDIwNTcJUEw6aWxsdW1pbmEJUFU6SUxMVU1JTkEJU006TkEwNjk4NApAUkcJSUQ6U1JSMDgxNjc1CUNOOmJpCUxCOlNvbGV4YS00MjMxNglQTDppbGx1bWluYQlQVTpJTExVTUlOQQlTTTpOQTA2OTg0CkBSRwlJRDpTUlIwODA4MTgJQ046YmkJTEI6U29sZXhhLTQ0NzcwCVBMOmlsbHVtaW5hCVBVOklMTFVNSU5BCVNNOk5BMDY5ODQKQFJHCUlEOlNSUjA4NDgzOAlDTjpiaQlMQjpTb2xleGEtNDIzMTYJUEw6aWxsdW1pbmEJUFU6SUxMVU1JTkEJU006TkEwNjk4NApAUkcJSUQ6U1JSMDgxNzMwCUNOOmJpCUxCOlNvbGV4YS00MjMxNglQTDppbGx1bWluYQlQVTpJTExVTUlOQQlTTTpOQTA2OTg0Ci4uLi4uCi4uLi4uCgpgYGAKCkZpbmFsbHksIHdlIGhhdmUgYSBzZWN0aW9uIHdoZXJlIHdlIGNhbiByZWNvcmQgdGhlIHByb2Nlc3Npbmcgc3RlcHMgdXNlZCB0byBkZXJpdmUgdGhlIGZpbGUuIFRoaXMgaXMgCmBgYApAUEcgSUQ6aGlzYXQyIFBOOmhpc2F0MiBWTjoyLjEuMCBDTDoiL21udC9wdWxzYXIvZGVwZW5kZW5jaWVzL19jb25kYS9lbnZzL211bGxlZC12MS1lNzMyMWJhNDZmYTVlYTRjNmI5YTA2Yjc4ZTZjZDUxODJiMzNjMGE0N2MyYzg2YjVkNjEwZTEzNjFmOGIxNjg2L2Jpbi9oaXNhdDItYWxpZ24tcyAtLXdyYXBwZXIgYmFzaWMtMCAtcCA0IC14IC9jdm1mcy9kYXRhLmdhbGF4eXByb2plY3Qub3JnL21hbmFnZWQvaGlzYXQyX2luZGV4L21tMTAvbW0xMCAtVSAvdG1wLzE2MjgyLnVucCIKLi4uLgouLi4uCgpgYGAKCk5leHQgaXMgYSAqdGFiLWRlbGltaXRlZCogc2VjdGlvbiB0aGF0IGRlc2NyaWJlcyB0aGUgYWxpZ25tZW50IG9mIGVhY2ggc2VxdWVuY2UgaW4gZGV0YWlsLiAKCmBgYApTUlIxNTUyNDUwLjIyMDI4OQkwCWNocjEJMzIwMDgzOQk2MAkxMDBNCSoJMAkwCUdHQ1RDQUNDQUFHVEFUR0FUR0dUVFRDQVRBQ0NDQUdBQUFBQUNBVFRUR1RUQ1RUVFRHR0FUR0NDQVRUQUdUVENBR0NDQUdUR1RDQUFDQVRHQUNUQUdUR0dUVFRDQ0NBQUdDQUMJQ0NDRkZGRkRISEdESEdJSUpKSklIR0hHR0lHSElJSUdGSEdIQklJSElKQUdJSklKSkdHQ0hKSklHSUpKSkdIQ0FHR0hISUlDR0dISEhISEhGRkZGRkRDRTs/QUFDQ0RDREREQwlBUzppOjAgWE46aTowIFhNOmk6MCBYTzppOjAgWEc6aTowIE5NOmk6MCBNRDpaOjEwMCBZVDpaOlVVIE5IOmk6MQpTUlIxNTUyNDUwLjEzODc5NwkxNgljaHIxCTMyMDExMzIJNjAJMTAwTQkqCTAJMAlDQVRUVFRUQUFDQUdDQVRBVFRUR1RDVFRBR0NUVFRBQUFUQ0NBR0FHVEFDVEdUVFRHR0NUVENBQUFHQUFHQVRBR1RDQVRDVENUR0dUVENUQ1RUQUNUR0FHQUFUQUdBQUFHVENUCURERUVFRUVFRUZGRkZGRkZISEhISElJR0NIR0VKSkpKSkpKSkpKSUpKSkpKSkpKSkpKSklKSUpKSkpKSkpKSkpKSklHSkpKSkpJSkpKSkpKSklISkpKSkhISEhIRkZGRkZDQ0MJQVM6aTowIFhOOmk6MCBYTTppOjAgWE86aTowIFhHOmk6MCBOTTppOjAgTUQ6WjoxMDAgWVQ6WjpVVSBOSDppOjEKCmBgYAoKVGhlIGZpcnN0IDExIGNvbHVtbnMgb2YgZWFjaCBsaW5lIGhhdmUgYW4gb2ZmaWNpYWwgc3BlY2lmaWNhdGlvbgoKQ29sdW1uIHwgT2ZmaWNpYWwgTmFtZSB8IEJyaWVmCi0tLS0tLSB8IC0tLS0tLS0tLS0tLS0tIHwgLS0tLS0tLS0tLS0KMSAgICAgIHwgUU5BTUUgICAgICAgICAgfCBTZXF1ZW5jZSBJRAoyICAgICAgfCBGTEFHICAgICAgICAgICB8IFNlcXVlbmNlIHF1YWxpdHkgZXhwcmVzc2VkIGFzIGEgYml0d2lzZSBmbGFnCjMgICAgICB8IFJOQU1FICAgICAgICAgIHwgQ2hyb21vc29tZQo0ICAgICAgfCBQT1MgICAgICAgICAgICB8IFN0YXJ0IFBvc2l0aW9uCjUgICAgICB8IE1BUFEgICAgICAgICAgIHwgTWFwcGluZyBRdWFsaXR5CjYgICAgICB8IENJR0FSICAgICAgICAgIHwgRGVzY3JpYmVzIHBvc2l0aW9ucyBvZiBtYXRjaGVzLCBpbnNlcnRpb25zLCBkZWxldGlvbnMgdy5yLnQgcmVmZXJlbmNlCjcgICAgICB8IFJORVhUICAgICAgICAgIHwgUmVmLiBuYW1lIG9mIG1hdGUgLyBuZXh0IHJlYWQKOCAgICAgIHwgUE5FWFQgICAgICAgICAgfCBQb3N0aW9uIG9mIG1hdGUgLyBuZXh0IHJlYWQKOSAgICAgIHwgVExFTiAgICAgICAgICAgfCBPYnNlcnZlZCBUZW1wbGF0ZSBsZW5ndGgKMTAgICAgIHwgU0VRICAgICAgICAgICAgfCBTZXF1ZW5jZQoxMSAgICAgfCBRVUFMICAgICAgICAgICB8IEJhc2UgUXVhbGl0aWVzCgpUaGVyZSBjYW4gYWxzbyBiZSBhbGwgbWFubmVyIG9mIG9wdGlvbmFsIHRhZ3MgYXMgZXh0cmEgY29sdW1ucyBpbnRyb2R1Y2UgYnkgYW4gYWxpZ25lciBvciBkb3duc3RyZWFtIGFuYWx5c2lzIHRvb2wuIEEgY29tbW9uIHVzZSBpcyB0aGUgYFJHYCB0YWcgd2hpY2ggcmVmZXJzIGJhY2sgdG8gdGhlIHJlYWQgZ3JvdXBzIGluIHRoZSBoZWFkZXIuCgoKIyMjIFF1YWxpdHkgQ29udHJvbCBGbGFncwoKVGhlICoiZmxhZ3MiKiBpbiB0aGUgc2FtIGZpbGUgY2FuIHJlcHJlc2VudCB1c2VmdWwgUUMgaW5mb3JtYXRpb24KCiAgKyBSZWFkIGlzIHVubWFwcGVkCiAgKyBSZWFkIGlzIHBhaXJlZCAvIHVucGFpcmVkCiAgKyBSZWFkIGZhaWxlZCBRQwogICsgUmVhZCBpcyBhIFBDUiBkdXBsaWNhdGUgKHNlZSBsYXRlcikKClRoZSBjb21iaW5hdGlvbiBvZiBhbnkgb2YgdGhlc2UgcHJvcGVydGllcyBpcyB1c2VkIHRvIGRlcml2ZSBhIG51bWVyaWMgdmFsdWUuIEZvciBpbnN0YW5jZSwgYSBwYXJ0aWN1bGFyIHJlYWQgbWlnaHQgaGF2ZSBhIGZsYWcgb2YgMTYzCgojIyMgRGVyaXZhdGlvbgoKVGhlcmUgaXMgYSBzZXQgb2YgcHJvcGVydGllcyB0aGF0IGEgcmVhZCBjYW4gcG9zc2Vzcy4gSWYgYSBwYXJ0aWN1bGFyIHByb3BlcnR5IGlzIG9ic2VydmVkLCBhIGNvcnJlc3BvbmRpbmcgcG93ZXIgb2YgMiBpcyBhZGRlZCBtdWx0aXBsaWVkIGJ5IDEuIFRoZSBmaW5hbCB2YWx1ZSBpcyBkZXJpdmVkIGJ5IHN1bW1pbmcgYWxsIHRoZSBwb3dlcnMgb2YgMi4KCgpgYGAKIAlSZWFkSGFzUHJvcGVydHkgCUJpbmFyeSAJTXVsdGlwbHlCeQppc1BhaXJlZCAJVFJVRSAJMSAJMQppc1Byb3BlclBhaXIgCVRSVUUgCTEgCTIKaXNVbm1hcHBlZFF1ZXJ5IAlGQUxTRSAJMCAJNApoYXNVbm1hcHBlZE1hdGUgCUZBTFNFIAkwIAk4CmlzTWludXNTdHJhbmQgCUZBTFNFIAkwIAkxNgppc01hdGVNaW51c1N0cmFuZCAJVFJVRSAJMSAJMzIKaXNGaXJzdE1hdGVSZWFkIAlGQUxTRSAJMCAJNjQKaXNTZWNvbmRNYXRlUmVhZCAJVFJVRSAJMSAJMTI4CmlzU2Vjb25kYXJ5QWxpZ25tZW50IAlGQUxTRSAJMCAJMjU2CmlzTm90UGFzc2luZ1F1YWxpdHlDb250cm9scyAJRkFMU0UgCTAgCTUxMgppc0R1cGxpY2F0ZSAJRkFMU0UgCTAgCTEwMjQKCmBgYApWYWx1ZSBvZiBmbGFnIGlzIGdpdmVuIGJ5IApgYGAKMXgxICsgMXgyICsgMHg0ICsgMHg4ICsgMHgxNiArIDF4MzIgKyAweDY0ICsgMXgxMjggKyAweDI1NiArIDB4NTEyICsgMHgxMDI0ID0gMTYzCmBgYAoKU2VlIGFsc28KCi0gaHR0cHM6Ly9icm9hZGluc3RpdHV0ZS5naXRodWIuaW8vcGljYXJkL2V4cGxhaW4tZmxhZ3MuaHRtbAoKIyMjIEhhdmUgYSBDSUdBUiEKCgpUaGUgKioqQ0lHQVIqKiogKCoqQyoqb21wYWN0ICoqSSoqZGlvc3luY3JhdGljICoqRyoqYXBwZWQgKipBbGlnbm1lbnQqKiAqKlIqKmVwb3J0KSBzdHJpbmcgaXMgYSB3YXkgb2YgZW5jb2RpbmcgdGhlIG1hdGNoIGJldHdlZW4gYSBnaXZlbiBzZXF1ZW5jZSBhbmQgdGhlIHBvc2l0aW9uIGl0IGhhcyBiZWVuIGFzc2lnbmVkIGluIHRoZSBnZW5vbWUuIEl0IGlzIGNvbXByaXNlZCBieSBhIHNlcmllcyBvZiBsZXR0ZXJzIGFuZCBudW1iZXJzIHRvIGluZGljYXRlIGhvdyBtYW55IGNvbnNlY3V0aXZlIGJhc2VzIGhhdmUgdGhhdCBtYXBwaW5nLgoKCiAKIENvZGUgIHwgRGVzY3JpcHRpb24KLS0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0tLS0KTSAgfCBhbGlnbm1lbnQgbWF0Y2gKSSAgfCBpbnNlcnRpb24KRCAgfCBkZWxldGlvbgpOICB8IHNraXBwZWQKUyAgfCBzb2Z0LWNsaXBwaW5nCkggIHwgaGFyZC1jbGlwcGluZwoKCmUuZy4KCi0gYDEwMU1gCiAgICArIDEwMSBiYXNlcyBtYXRjaGluZyB0aGUgcmVmZXJlbmNlCi0gYDFTMTAwTWAKICAgICsgMSBzb2Z0LWNsaXBwZWQgcmVhZCBmb2xsb3dlZCBieSAxMDAgbWF0Y2hlcwotIGAxNU04N043ME05ME4xNk1gCiAgICArIDE1IG1hdGNoZXMgZm9sbG93aW5nIGJ5IDg3IGJhc2VzIHNraXBwZWQgZm9sbG93ZWQgYnkgNzAgbWF0Y2hlcyBldGMuCgojIyMgYHNhbWAgb3IgYGJhbT9gCgpBbGlnbm1lbnQgYWxnb3JpdGhtcyBzdWNoIGFzIGBISVNBVDJgIHRlbmQgdG8gcHJvZHVjZSBhIGBzYW1gIGZpbGUgYXMgdGhlaXIgcmF3IG91dHB1dCwgd2hlcmVhcyB3ZSB1c3VhbGx5IGFuYWx5c2UgYSBgLmJhbWAgZmlsZS4gVGhlIGNvbnRlbnRzIG9mIGJvdGggZmlsZXMgYXJlICpleGFjdGx5IHRoZSBzYW1lKi4gV2hlcmVhcyBhIGBzYW1gIGZpbGUgaXMgZGVzaWduZWQgdG8gYmUgKmh1bWFuLXJlYWRhYmxlKiwgYSBgYmFtYCBmaWxlIGNhbiBiZSBwcm9jZXNzZWQgKm1vcmUgZWZmaWNpZW50bHkgYnkgYSBjb21wdXRlciogYXMgaXQgaXMgY29tcHJlc3NlZCBhbmQgaW5kZXhlZC4gCgpUaGUgcmVhZHMgaW4gYSBgc2FtYCBmaWxlIHRlbmQgdG8gYmUgYXJyYW5nZWQgaW4gdGhlIG9yZGVyIHRoYXQgdGhleSB3ZXJlIGdlbmVyYXRlZCBieSB0aGUgc2VxdWVuY2VyLiBPbiB0aGUgb3RoZXIgaGFuZCwgdGhlIGBiYW1gIGZpbGUgdGhhdCB5b3Ugc2VlIGluIEdhbGF4eSBoYXMgYmVlbiBzb3J0ZWQgYWNjb3JkaW5nIHRvIHRoZSBwb3NpdGlvbiB0aGF0IHRoZSByZWFkcyBtYXAuIElmIHlvdSBydW4geW91ciBvd24gYWxpZ25tZW50cyB1c2luZyBjb21tYW5kIGxpbmUgc29mdHdhcmUsIHlvdSB3aWxsIG5lZWQgdG8gdXNlIGEgdG9vbCB0byAqc29ydCBhbmQgaW5kZXgqIHRoZSBkYXRhIGJlZm9yZSBhbmFseXNpcy4KCi0tLS0tCgojIyBRdWFsaXR5IGFzc2Vzc21lbnQgb2YgdGhlIGFsaWduZWQgcmVhZHMKCipzYW10b29scyogd2lsbCBjYWxjdWxhdGUgUUMgc3RhdGlzdGljcyBmb3IgYSBzZXQgb2YgYWxpZ25lZCByZWFkcyBpbiAqYmFtKiBmb3JtYXQKCjxkaXYgY2xhc3M9ImFsZXJ0IGFsZXJ0LWluZm8iPgoqU0FNL0JBTSAtPiBTYW10b29scyBzdGF0cyoKPC9kaXY+CgpJZiB5b3UgdmlldyB0aGUgb3V0cHV0IHlvdSB3aWxsIHNlZSB0aGF0IGl0IGlzIG5vdCB2ZXJ5IGVhc3kgdG8gaW50ZXJwcmV0LiAKPGRpdiBjbGFzcz0iYWxlcnQgYWxlcnQtaW5mbyI+CipGQVNUUSBRdWFsaXR5IENvbnRyb2wqIC0+ICpNdWx0aXFjKgoKbWFrZSBzdXJlICoqV2hpY2ggdG9vbCB3YXMgdXNlZCB0byBnZW5lcmF0ZSBsb2dzKiogaXMgc2V0IHRvICoqU2FtdG9vbHMqKiBhbmQgc2VsZWN0IHRoZSBTYW10b29scyBzdGF0cy4uLi4gZmlsZXMgdGhhdCB3ZXJlIHByb2R1Y2VkIGluIHRoZSBwcmV2aW91cyBzdGVwCjwvZGl2PgoKCiMjIFNlY3Rpb24gNC4gIFZpc3VhbGlzZSB0aGUgYWxpZ25lZCByZWFkcyB3aXRoIElHVgoKRG93bmxvYWQgdGhlIGJhbSBmaWxlcyB5b3UgaGF2ZSBjcmVhdGVkIGluIHRoZSBwcmV2aW91cyBzdGVwIGJ5IGNsaWNraW5nIHRoZSBkaXNrIGljb24gb24gdGhlIHJpZ2h0LWhhbmQgcGFuZWwuIE1ha2Ugc3VyZSB0byBjbGljayBib3RoIHRoZSAqKkRvd25sb2FkIGRhdGFzZXQqKiBhbmQgKipEb3dubG9hZCBpbmRleCoqIGJ1dHRvbnMuIFdlIHdpbGwgbm93IHZpc3VhbGlzZSB0aGUgYWxpZ25tZW50cyB1c2luZyB0aGUgSW50ZWdyYXRpdmUgR2Vub21pY3MgVmlld2VyIChJR1YpLgoKPGltZyBzcmM9Im1lZGlhL2Rvd25sb2FkX2JhbS5wbmciPgoKCiMjIyBJbnRyb2R1Y2luZyB0aGUgSUdWIEJyb3dzZXIKCiFbXShtZWRpYS9pZ3YucG5nKQoKV2hpbHN0IHRvb2xzIGxpa2UgUiBhcmUgdmVyeSBwb3dlcmZ1bCBhbmQgYWxsb3cgeW91IHRvIHBlcmZvcm0gc3RhdGlzdGljYWwgYW5hbHlzZXMgYW5kIHRlc3QgaHlwb3RoZXNlcywgdGhlcmUgaXMgbm8gc3Vic3RpdHV0ZSBmb3IgKioqbG9va2luZyBhdCB0aGUgZGF0YSoqKi4gQSB0cmFpbmVkLWV5ZSBjYW4gcXVpdGUgcXVpY2tseSBnZXQgYSBzZW5zZSBvZiB0aGUgZGF0YSBxdWFsaXR5IGJlZm9yZSBhbnkgY29tcHV0YXRpb25hbCBhbmFseXNlcyBoYXZlIGJlZW4gcnVuLiBGdXRoZXJtb3JlLCBhcyB0aGUgcGVyc29uIHJlcXVlc3RpbmcgdGhlIHNlcXVlbmNpbmcsIHlvdSBwcm9iYWJseSBrbm93IGEgbG90IGFib3V0IHRoZSBiaW9sb2dpY2FsIGNvbnRleHQgb2YgdGhlIHNhbXBsZXMgYW5kIHdoYXQgdG8gZXhwZWN0LiAKCi0gSUdWIGhhcyBiZWVuIGRldmVsb3BlZCBieSB0aGUgQnJvYWQgSW5zdGl0dXRlIGFuZCBpcyBhYmxlIHRvIGRpc3BsYXkgbW9zdCBraW5kcyBvZiBnZW5vbWljIGRhdGEKICAgICsgZXhwcmVzc2lvbgogICAgKyBDaElQCiAgICArIHdob2xlLWdlbm9tZSByZXNlcXVlbmNpbmcKICAgICsgc2hSTkEKLSBJdCBpcyBhICpKYXZhKiBkZXNrdG9wIGFwcGxpY2F0aW9uIGFuZCBjYW4gYmUgcnVuIGVpdGhlciBsb2NhbGx5IG9mIGZyb20gdGhlIEJyb2FkIHdlYnNpdGUKLSBUbyBydW4gSUdWIHlvdXJzZWxmIHlvdSB3aWxsIG5lZWQgdG8gYWdyZWUgdG8gdGhlIGxpY2Vuc2UgYW5kIFtkb3dubG9hZCB0aGUgdmVyc2lvbiBmb3IgeW91ciBPU10oaHR0cDovL3d3dy5icm9hZGluc3RpdHV0ZS5vcmcvc29mdHdhcmUvaWd2L2Rvd25sb2FkKQoKPGRpdiBjbGFzcz0iYWxlcnQgYWxlcnQtaW5mbyI+CklmIHlvdSBoYXZlIHByb2JsZW1zIHJ1bm5pbmcgSUdWLCB5b3UgbWF5IG5lZWQgdG8gZG93bmxvYWQgYW4gdXBkYXRlZCB2ZXJzaW9uIG9mIEphdmEKCmh0dHBzOi8vamF2YS5jb20vZG93bmxvYWQKCjwvZGl2PgoKIyMjIEEgcXVpY2sgdG91ciBvZiBJR1YKRm9yIG1vcmUgZGV0YWlscwoKLSBGdWxsIHNldCBvZiBzbGlkZXMgZnJvbSBbTVJDIENsaW5pY2FsIFNjaWVuY2VzIENlbnRyZV0oaHR0cDovL21yY2NzYy5naXRodWIuaW8vSUdWX2NvdXJzZS9pZ3YuaHRtbCMvKQotIElHViB0dXRvcmlhbCBmcm9tIHRoZSBbR3JpZmZ0aCBsYWIgLSBXYXNoVV0oaHR0cHM6Ly9naXRodWIuY29tL2dyaWZmaXRobGFiL3JuYXNlcV90dXRvcmlhbC93aWtpL0lHVi1UdXRvcmlhbCkKCiFbXShtZWRpYS9JR1YyLnBuZykKCjEpIFNhbXBsZSBpbmZvcm1hdGlvbiBwYW5lbAogICAgLSBJbmZvcm1hdGlvbiBhYm91dCBzYW1wbGVzIHlvdSBoYXZlIGxvYWRlZAogICAgLSBlLmcuIFNhbXBsZSBJRCwgR2VuZGVyLCBBZ2UsIFR1bW91ciAvIE5vcm1hbAogICAgCjIpIEdlbm9tZSBOYXZpZ2F0aW9uIHBhbmVsCiAgICAtIEp1bXAgdG8gYSBnZW5vbWljIHJlZ2lvbiBpbiBgQ2hyOlN0YXJ0LUVuZGAgZm9ybWF0CiAgICAtIEp1bXAgdG8gYSBnZW5lIHN5bWJvbCBvZiBpbnRlcmVzdAogICAgCjMpIERhdGEgcGFuZWwKICAgIC0gWW91ciBzZXF1ZW5jaW5nIHJlYWRzIHdpbGwgYmUgZGlzcGxheWVkIGhlcmUKICAgIC0gT3Igd2hhdGV2ZXIgZGF0YSB5b3UgaGF2ZSBsb2FkZWQKICAgICAgICArIHNlZSBpbmZvcm1hdGlvbiBvbiBbYWNjZXB0ZWQgZmlsZSBmb3JtYXRzXShodHRwOi8vd3d3LmJyb2FkaW5zdGl0dXRlLm9yZy9zb2Z0d2FyZS9pZ3YvUmVjb21tZW5kZWRGaWxlRm9ybWF0cykKCjQpIEF0dHJpYnV0ZSBwYW5lbAogICAgLSBHZW5lIGxvY2F0aW9ucwogICAgLSBHZW5vbWUgc2VxdWVuY2UgKGlmIHpvb21lZC1pbiBhdCBhcHByb3ByaWF0ZSBsZXZlbCkKICAgIC0gUHJvdGVpbnMKICAgIAojIyMgRXhhbXBsZQoKR28gdG8gKioqRmlsZSoqKiAtPiAqKipMb2FkIGZyb20gZmlsZSoqKiBhbmQgc2VsZWN0IHRoZSBhbGlnbmVkIGBiYW1gIGZpbGVzIGZyb20gYEhJU0FUMmAuIE5vdGUgdGhhdCB0aGUgaW5kZXggZmlsZXMgYC5iYWlgIG5lZWQgdG8gYmUgcHJlc2VudCBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuIEhvd2V2ZXIsIHlvdSBvbmx5IG5lZWQgdG8gY2xpY2sgb24gdGhlIGAuYmFtYAoKPGRpdiBjbGFzcz0iYWxlcnQgYWxlcnQtaW5mbyI+Ck1ha2Ugc3VyZSB0aGF0IHRoZSBnZW5vbWUgc2VsZWN0ZWQgaXMgYG1tMTBgLiBUaGUgZGVmYXVsdCB3aWwgYmUgaHVtYW4gaGcxOQo8L2Rpdj4KCi0gVGhlIGJsYWNrIGRvdHRlZCB2ZXJ0aWNhbCBsaW5lcyBpbmRpY2F0ZXMgdGhlIGNlbnRyZSBvZiB0aGUgdmlldwotIEVhY2ggb2YgdGhlIGdyZXkgcG9pbnRlZCByZWN0YW5nbGVzIHJlcHJlc2VudHMgYSBzZXF1ZW5jaW5nIHJlYWRzCiAgICArIHdoZXRoZXIgdGhlIHBvaW50ZWQgYml0IGlzIG9uIHRoZSBsZWZ0IG9yIHJpZ2h0IGluZGljYXRlcyBpZiB0aGUgcmVhZCBpcyBmb3J3YXJkIG9yIHJldmVyc2UuCi0gQSBjb3ZlcmFnZSB0cmFjayBpcyBhbHNvIGdlbmVyYXRlZAotIFlvdSBzaG91bGQgc2VlIHRoZSByZWFkIHRoYXQgd2UgZGVzY3JpYmVkIGluIGRldGFpbCBpbiB0aGUgcHJldmlvdXMgc2VjdGlvbiBieSAqaG92ZXIqaW5nIG92ZXIgdGhlIHJlYWRzIHRvIGRpc3BsYXkgdGhlIGluZm9ybWF0aW9uIGZyb20gdGhlIGAuYmFtYCBmaWxlCgpUaGUgdmlldyBpbiBJR1YgaXMgbm90IHN0YXRpYyBhbmQgd2UgY2FuIHNjcm9sbC1hbG9uZyB0aGUgZ2Vub21lIGJ5IGhvbGRpbmctZG93biB0aGUgbGVmdCBtb3VzZSBpbiB0aGUgZGF0YSBwYW5lbCBhbmQgZHJhZ2dpbmcgbGVmdCBhbmQgcmlnaHQKCkl0J3Mgd29ydGggbm90aW5nIHRoYXQgdGhlIGRpc3BsYXkgc2V0dGluZ3MgbWF5IGJlIHNob3dpbmcgZmV3ZXIgcmVhZHMgdGhhbiB5b3UgaGF2ZSAoKmRvd25zYW1wbGluZyopIGluIG9yZGVyIHRvIGNvbnNlcnZlIG1lbW9yeS4gQWxzbywgc29tZSBRQy1mYWlsIG9yIFBDUiBkdXBsaWNhdGVzIG1heSBiZSBmaWx0ZXJlZC4KCldlIGFsc28gaGF2ZSBzb21lIG9wdGlvbnMgb24gaG93IHRvIGRpc3BsYXkgdGhlIHJlYWRzIHRoZW1zZWx2ZXMsIHdoaWNoIHdlIGNhbiBhY2NjZXNzIGJ5IHJpZ2h0LWNsaWNraW5nIG9uIHRoZSBiYW0gdHJhY2sKClNvcnRpbmcgYWxpZ25tZW50cyBieTotCgogIC0gc3RhcnQKICAtIHN0cmFuZAogIC0gYmFzZQogIC0gbWFwcGluZyBxdWFsaXR5CiAgLSBpbnNlcnQgc2l6ZQogIApUaGUgcmVhZHMgdGhlbXNlbHZlcyBjYW4gYWxzbyBiZSBjb2xvdXJlZCBhY2NvcmRpbmcgdG8KCiAgLSBpbnNlcnQgc2l6ZQogIC0gcmVhZCBzdHJhbmQKICAtIHNhbXBsZQoKCiMjIFNlY3Rpb24gNS4gUXVhbnRpZmljYXRpb24gKENvdW50aW5nIHJlYWRzIGluIGZlYXR1cmVzKQoKSW4gb3JkZXIgdG8gdGVzdCBmb3IgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24sIHdlIG5lZWQgdG8gY291bnQgdXAgaG93IG1hbnkgdGltZXMgZWFjaCAiZmVhdHVyZSIgaXMgb2JzZXJ2ZWQgaXMgZWFjaCBzYW1wbGUuIFRoZSBnb2FsIG9mIHN1Y2ggb3BlcmF0aW9ucyBpcyB0byBwcm9kdWNlIGEgKmNvdW50IHRhYmxlKiBzdWNoIGFzIHRoYXQgc2hvd24gYmVsb3cuIFdlIGNhbiB0aGVuIGFwcGx5IHN0YXRpc3RpY2FsIHRlc3RzIHRvIHRoZXNlIGRhdGEKCiFbXShtZWRpYS9jb3VudHMucG5nKQoKSFRTZXEtY291bnQgY3JlYXRlcyBhIGNvdW50IG1hdHJpeCB1c2luZyB0aGUgbnVtYmVyIG9mIHRoZSByZWFkcyBmcm9tIGVhY2ggYmFtCmZpbGUgdGhhdCBtYXAgdG8gdGhlIGdlbm9taWMgZmVhdHVyZXMuIEZvciBlYWNoIGZlYXR1cmUgKGEKZ2VuZSBmb3IgZXhhbXBsZSkgYSBjb3VudCBtYXRyaXggc2hvd3MgaG93IG1hbnkgcmVhZHMgd2VyZSBtYXBwZWQgdG8gdGhpcwpmZWF0dXJlLgoKVmFyaW91cyBydWxlcyBjYW4gYmUgdXNlZCB0byBhc3NpZ24gY291bnRzIHRvIGZlYXR1cmVzCgohW10obWVkaWEvaHRzZXEucG5nKQoKVG8gb2J0YWluIHRoZSBjb29yZGluYXRlcyBvZiBlYWNoIGdlbmUsIHdlIGNhbiB1c2UgdGhlIFVDU0MgZ2Vub21lIGJyb3dzZXIgd2hpY2ggaXMgaW50ZWdyYXRlZCBpbnRvIEdhbGF4eS4KCiMjIyBPYnRhaW5pbmcgZ2VuZSBjb29yZGluYXRlcwoKCgo8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC1pbmZvIj4KCioqR2V0IERhdGEqKiAtPiAqKlVDU0MgTWFpbioqIHRhYmxlIGJyb3dzZXIKCjwvZGl2PgoKCiFbXShtZWRpYS91Y3NjX2Jyb3dzZXIucG5nKQoKU2VsZWN0aW5nIHRoZSAqKlVDU0MgTWFpbioqIHRvb2wgZnJvbSBHYWxheHkgd2lsbCB0YWtlIHlvdSB0byB0aGUgVUNTQyB0YWJsZSBicm93c2VyLiBGcm9tIGhlcmUgd2UgY2FuIGV4dHJhY3QgZ2VuZSBjb29yZGluYXRlcyBmb3Igb3VyIGdlbm9tZSBvZiBpbnRlcmVzdCAoYHNhY0NlcjNgKSBpbiBgZ3RmYCBmb3JtYXQgZm9yIHByb2Nlc3Npbmcgd2l0aCBnYWxheHkuCgotIFNldCAqY2xhZGUqIHRvICoqTWFtbWFsKioKLSBTZXQgKmdlbm9tZSogdG8gKipNb3VzZSoqCi0gKmFzc2VtYmx5KiAqKkRlYy4yMDExIChHUkNtMzgvbW0xMCkqKgotICpncm91cCogKipHZW5lcyBhbmQgR2VuZSBQcmVkaWN0aW9uKioKLSAqdHJhY2sqICoqTkNCSSBSZWZTZXEqKgotICpyZWdpb24qICoqZ2Vub21lKioKLSAqb3V0cHV0IGZvcm1hdCogKipHVEYgLSBnZW5lIHRyYW5zZmVyIGZvcm1hdCAobGltaXRlZCkqKiBhbmQgKnNlbmQgb3V0cHV0IHRvKiAqKkdhbGF4eSoqCgpDbGljayAqZ2V0IG91dHB1dCogYW5kICpzZW5kIHF1ZXJ5IHRvIEdhbGF4eSogdG8gYmUgcmV0dXJuZWQgdG8gR2FsYXh5LiBBIG5ldyBqb2Igd2lsbCBiZSBzdWJtaXR0ZWQgdG8gcmV0cmlldmUgdGhlIGNvb3JkaW5hdGVzIGZyb20gVUNTQwoKCgo8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC1pbmZvIj4KKipSTkEgQW5hbHlzaXMgPiBodHNlcS1jb3VudCoqCjwvZGl2PgoKMS4gIFVzZSBIVFNlcS1jb3VudCB0byBjb3VudCB0aGUgbnVtYmVyIG9mIHJlYWRzIGZvciBlYWNoIGZlYXR1cmUuICAKICAgIEluIHRoZSBsZWZ0IHRvb2wgcGFuZWwgbWVudSwgdW5kZXIgTkdTIEFuYWx5c2lzLCBzZWxlY3QKICAgICoqTkdTIEFuYWx5c2lzID4gaHRzZXEtY291bnQqKiBhbmQgc2V0IHRoZSBwYXJhbWV0ZXJzIGFzIGZvbGxvd3M6ICAKICAgIC0gKipBbGlnbmVkIFNBTS9CQU0gZmlsZSoqICAKICAgICAgKFNlbGVjdCBvbmUgb2YgZm91ciBiYW0gZmlsZXMsIG9yIGFsbCBmb3VyIHVzaW5nIHRoZSBtdWx0aXBsZSBkYXRhc2V0cyBvcHRpb24pCiAgICAtICoqR0ZGIGZpbGUqKiBVQ1NDIE1haW4gb24gTW91c2U6bmNiaVJlZlNlcSAoZ2Vub21lKQogICAgLSBVc2UgZGVmYXVsdHMgZm9yIHRoZSBvdGhlciBmaWVsZHMKICAgIC0gRXhlY3V0ZQoyLiAgUmVwZWF0IGZvciB0aGUgcmVtYWluaW5nIGJhbSBmaWxlcyBpZiBydW5uaW5nIG9uIGVhY2ggYmFtIHNlcGFyYXRlbHkuCjMuICBSZW5hbWUgdGhlIGh0LXNlcSBvdXRwdXQgZm9yIGVhY2ggc2FtcGxlLiAqKkRvIG5vdCByZW5hbWUgdGhlIG91dHB1dHMgdGhhdCBoYXZlICIobm8gZmVhdHVyZSkiIGluIHRoZWlyIG5hbWUqKgoKIyMgRnVydGhlciBRQyBvbiB0aGUgYWxpZ25lZCByZWFkcwoKQWRkaXRpb25hbCBRQyBvZiB0aGUgYWxpZ25lZCByZWFkcyBjYW4gYmUgb2J0YWluZWQgd2l0aCB0aGUgUXVhbGltYXAgdG9vbC4gVGhpcyBhbHNvIHVzZXMgaW5mb3JtYXRpb24gZnJvbSB0aGUgZ2Vub21lIHRyYW5zY3JpcHQgZmlsZSB0byBjYWxjdWxhdGUgaG93IG1hbnkgcmVhZHMgYXJlIGNvdW50ZWQgaW4gZXhvbmljLCBpbnRyb25pYyBhbmQgaW50ZXJnZW5pYyByZWdpb25zLiBGb3IgUk5BLXNlcSB0aGlzIHBlcmNlbnRhZ2Ugc2hvdWxkIGJlICpoaWdoKjsgYXQgbGVhc3QgODAgdG8gOTAlLgoKPGRpdiBjbGFzcz0iYWxlcnQgYWxlcnQtaW5mbyI+CioqUk5BLVNlcSA+IFF1YWxpbWFwIFJOQS1TZXEgUUMqKgo8L2Rpdj4KCiMjIyBDcmVhdGUgYSBjb3VudCBtYXRyaXgKClRoZSBodHNlcSB0b29sIGlzIGRlc2lnbmVkIHRvIHByb2R1Y2UgYSBzZXBhcmF0ZSB0YWJsZSBvZiBjb3VudHMgZm9yIGVhY2ggc2FtcGxlLiBUaGlzIGlzIG5vdCBwYXJ0aWN1bGFybHkgdXNlZnVsIGZvciBvdGhlciB0b29scyBzdWNoIGFzIERlZ3VzdCAoc2VlIG5leHQgc2VjdGlvbikgd2hpY2ggcmVxdWlyZSB0aGUgY291bnRzIHRvIGJlIHByZXNlbnRlZCBpbiBhIGRhdGEgbWF0cml4IHdoZXJlIGVhY2ggcm93IGlzIGEgZ2VuZSBhbmQgZWFjaCBjb2x1bW4gaXMgYSBwYXJ0aWN1bGFyIHNhbXBsZSBpbiB0aGUgZGF0YXNldC4KCjxkaXYgY2xhc3M9ImFsZXJ0IGFsZXJ0LWluZm8iPgoqQ29sbGVjdGlvbiBPcGVyYXRpb25zIC0+IENvbHVtbiBKb2luKiBvbiBDb2xsZWN0aW9ucwo8L2Rpdj4KCi0gSW4gdGhlICpUYWJ1bGFyIEZpbGVzKiBzZWN0aW9uLCBzZWxlY3QgdGhlIGBodC1zZXFgIGNvdW50IGZpbGVzIGZyb20geW91ciBoaXN0b3J5ICpTUlIxNTUyNDQ0Lmh0c2VxKiwgKlNSUjE1NTI0NTAqLCBldGMuLi4gSG9sZGluZyB0aGUgQ1RSTCBrZXkgYWxsb3dzIG11bHRpcGxlIGZpbGVzIHRvIGJlIHNlbGVjdGVkCi0gS2VlcCAqSWRlbnRpZmllciBjb2x1bW4qIGFzIGAxYAoKVGhlIG91dHB1dCBzaG91bGQgbG9vayBzb21ldGhpbmcgbGlrZSB0aGlzLi4uCiFbXShtZWRpYS9jb3VudF9tYXRyaXgucG5nKQoKLSBEb3dubG9hZCB0byB5b3VyIGNvbXB1dGVyCgoKKipZb3UgYXJlIG5vdyByZWFkeSB0byBmb2xsb3cgdGhlIG5leHQgdHV0b3JpYWwgb24gW0RpZmZlcmVudGlhbCBFeHByZXNzaW9uXSgwMi1kaWZmZXJlbnRpYWwtZXhwcmVzc2lvbi5uYi5odG1sKSoqCgoKCiMjIFJlZmVyZW5jZXMKClsxXSBOb29rYWV3IEksIFBhcGluaSBNLCBQb3JucHV0dHBvbmcgTiwgU2NhbGNpbmF0aSBHLCBGYWdlcmJlcmcgTCwgVWhsw6luIE0sIE5pZWxzZW4gSjogQSBjb21wcmVoZW5zaXZlIGNvbXBhcmlzb24gb2YgUk5BLVNlcS1iYXNlZCB0cmFuc2NyaXB0b21lIGFuYWx5c2lzIGZyb20gcmVhZHMgdG8gZGlmZmVyZW50aWFsIGdlbmUgZXhwcmVzc2lvbiBhbmQgY3Jvc3MtY29tcGFyaXNvbiB3aXRoIG1pY3JvYXJyYXlzOiBhIGNhc2Ugc3R1ZHkgaW4gU2FjY2hhcm9teWNlcyBjZXJldmlzaWFlLiBOdWNsZWljIEFjaWRzIFJlcyAyMDEyLCA0MCAoMjApOjEwMDg0IOKAkyAxMDA5Ny4gZG9pOjEwLjEwOTMvbmFyL2drczgwNC4gRXB1YiAyMDEyIFNlcCAxMAoKWzJdIEd1aXJndWlzIEEsIFNsYXBlIEMsIEZhaWxsYSBMLCBTYXcgSiwgVHJlbWJsYXkgQywgUG93ZWxsIEQsIFJvc3NlbGxvIEYsIFdlaSBBLCBTdHJhc3NlciBBLCBDdXJ0aXMgRDogUFVNQSBwcm9tb3RlcyBhcG9wdG9zaXMgb2YgaGVtYXRvcG9pZXRpYyBwcm9nZW5pdG9ycyBkcml2aW5nIGxldWtlbWljIHByb2dyZXNzaW9uIGluIGEgbW91c2UgbW9kZWwgb2YgbXllbG9keXNwbGFzaWEuIENlbGwgRGVhdGggRGlmZmVyLiAyMDE2IEp1bjsyMyg2KQo=