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
Using these notes
Sections with this background indicate exercises to be completed
during the workshop.
Sections with this background give information about potential error
messages you might encounter, or problems that might arise in your own
data analysis.
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:-
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.
The summarised data for this experiment were made available
on the Gene Expression Omnibus with accession GSE60450,
and full raw data can be obtained via the SRA
run browser. For the purposes of this workshop we have
created a downsampled dataset
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.
To aid the process of data upload (which can take a while) we have
created a link that you can use to access the data for this
practical
After clicking the link above, you should see the option to Import
the shared history. This will make the input data available to you in
Galaxy

Combining lanes
In a sequencing experiment, the data for a particular sample might be
spread across multiple lanes. For example, we might have files
named SRR1552444_L001.fastq.gz
and
SRR1552444_L002.fastq.gz
indicating that the reads for the
sample SRR1552444
are containing in two separate files. If
so, the two fastq.gz files will need to be combined. The
fastq.gz
files will need to be decompressed on your machine
first (the 7zip tool
can do this on Windows) and then uploaded as fastq. The Concatentate
Datasets tool can then be used to combine the files for each
sample.
Uploading large files
Galaxy recommend that large datasets (Gbs of data) are uploaded using
FTP. Instructions for doing this can be found here:-
https://galaxyproject.org/ftp-upload/
N.B. If you are using the European server, replace
usegalaxy.org
with usegalaxy.eu
when following
the instructions
You will need an FTP program such as filezilla, which has
a free download.
Deriving the Quality Score
First of all, we convert the base-calling probability (p) into a
Q
score using the formula
- Quality scores \[ Q =
-10log_{10}p\]
- Q = 30, p=0.001
- Q = 20, p=0.01
- Q = 10, p=0.1
- These numeric quanties are encoded as ASCII code

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.
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.
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 4 output files; one 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.
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 md5sum “digital 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
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.
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
If you view the output you will see that it is not very easy to
interpret.
Section 4. Quantification (Counting reads in features)
In order to test for differential expression, we need to count up how
many times each “feature” is observed in 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

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 (mm10
) 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
- table UCSC RefSeq (refGene)
- 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
- 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
- Repeat for the remaining bam files if running on each bam
separately.
- To make things easier to track, rename the ht-seq output for each
sample to contain the corresponding sample name (e.g. SRR1552444.htseq).
Do not rename the outputs that have “(no feature)” in their
name
When you are returned to Galaxy from UCSC it might look like you have
lost all th files in your analysis and are no longer logged in.
To solve this, log back in and choose the View all
histories option under the History panel.

There should be two “histories”; one containing all the outputs you
generated before accessing UCSC, and one containing the UCSC output. All
this point you can switch back to your previous history, and drag the
box containing the UCSC ouput to this history

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%.
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.
- 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
(Optional) Assessing Differential Expression with
DESeq2
There are several sensible and respected choices for performing a
differential expression analysis on RNA-seq data. Here, we will
illustrate the DESeq2
method because it is readily
available through Galaxy.
In the Galaxy tool panel, under NGS Analysis, select NGS: RNA
Analysis > DESeq2 and set the parameters as follows:
- 1. Factor level Virgin
- Count files
SRR1552444.htseq
SRR1552450.htseq
- 2. Factor level: Pregnant
- Select columns containing control:
SRR1552452.htseq
SRR1552453.htseq
- For Output normalized counts table select
Yes
- Execute
2. Examine the outputs from the previous step
- Examine the
DeSeq2 result file
by clicking on the
eye icon. This file is a list of genes sorted by
p-value from using DESeq2 to perform differential expression
analysis.
- Examine the
DeSeq2 plots
file. This file has some plots
from running DESeq2, including PCA and
clustering.
DESeq2
reports, for each gene that is being tested, some
information that we can use to determine if the gene is different
between our conditions of interest. We will do more exploration of
differential expression analysis in the next section using a tool that
is not included in Galaxy. For now we will concentrate on the task on
finding out which genes have sufficient statistical evidence
for being differentially expressed between our two conditions.
(Opional) 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
A quick tour of IGV
For more details

- Sample information panel
- Information about samples you have loaded
- e.g. Sample ID, Gender, Age, Tumour / Normal
- Genome Navigation panel
- Jump to a genomic region in
Chr:Start-End
format
- Jump to a gene symbol of interest
- Data panel
- Your sequencing reads will be displayed here
- Or whatever data you have loaded
- 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
LS0tCnRpdGxlOiAiUk5BLXNlcSBQcmUtcHJvY2Vzc2luZyB0dXRvcmlhbCIKYXV0aG9yOiAiTWFyayBEdW5uaW5nIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogICAgY3NzOiBzdHlsZXNoZWV0cy9zdHlsZXMuY3NzCiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAogICAgdG9jOiB5ZXMKZWRpdG9yX29wdGlvbnM6CiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQotLS0KCgoKIyBIYW5kcy1vbiBSTkEtc2VxIEFuYWx5c2lzIGluIEdhbGF4eQoKIyMgQWNrbm93bGVkZ2VtZW50CgpfQmFzZWQgb24gdGhlIFJOQS1TZXEgd29ya3Nob3AgYnkgTWVsYm91cm5lIEJpb2luZm9ybWF0aWNzIHdyaXR0ZW4gYnkgTWFodGFiIE1pcm1vbWVuaSwgQW5kcmV3IExvbmllLCBKZXNzaWNhIENodW5nXyBbT3JpZ2luYWxdKGh0dHA6Ly92bHNjaS5naXRodWIuaW8vbHNjY19kb2NzL3R1dG9yaWFscy9ybmFfc2VxX2RnZV9hZHZhbmNlZC9ybmFfc2VxX2FkdmFuY2VkX3R1dG9yaWFsLykKCl9Nb2RpZmllZCBieSBEYXZpZCBQb3dlbGwgKE1vbmFzaCBCaW9pbmZvcm1hdGljcyBQbGF0Zm9ybSlfCgpfRnVydGhlciBNb2RpZmllZCBieSBNYXJrIER1bm5pbmcgb2YgU2hlZmZpZWxkIEJpb2luZm9ybWF0aWNzIENvcmVfCgoKIyMjIFNoZWZmaWVsZCBCaW9pbmZvcm1hdGljcyBDb3JlCjxpbWcgc3JjPSJtZWRpYS9sb2dvLXNtLnBuZyIgYWxpZ249cmlnaHQ+Cgp3ZWIgOiBbc2JjLnNoZWYuYWMudWtdKGh0dHBzOi8vc2JjLnNoZWYuYWMudWspICAKdHdpdHRlcjogW0BTaGVmZkJpb2luZkNvcmVdKGh0dHBzOi8vdHdpdHRlci5jb20vU2hlZmZCaW9pbmZDb3JlKSAgCmVtYWlsOiBbYmlvaW5mb3JtYXRpY3MtY29yZUBzaGVmZmllbGQuYWMudWtdKGJpb2luZm9ybWF0aWNzLWNvcmVAc2hlZmZpZWxkLmFjLnVrKQoKLS0tLS0KCiMjIFR1dG9yaWFsIE92ZXJ2aWV3CgpUaGlzIHR1dG9yaWFsIHdpbGwgY292ZXIgdGhlIGJhc2ljcyBvZiBSTkEtc2VxIHVzaW5nIEdhbGF4eTsgYSBvcGVuLXNvdXJjZSB3ZWItYmFzZWQgcGxhdGZvcm0gZm9yIHRoZSBhbmFseXNpcyBvZiBiaW9sb2dpY2FsIGRhdGEuIFlvdSBzaG91bGQgZ2FpbiBhbiBhcHByZWNpYXRpb24gb2YgdGhlIHRhc2tzIGludm9sdmVkIGluIGEgdHlwaWNhbCBSTkEtc2VxIGFuYWx5c2lzIGFuZCBiZSBjb21mb3J0YWJsZSB3aXRoIHRoZSBvdXRwdXRzIGdlbmVyYXRlZCBieSB0aGUgQmlvaW5mb3JtYXRpY2lhbi4KCiMjIFVzaW5nIHRoZXNlIG5vdGVzCgo8ZGl2IGNsYXNzPSJleGVyY2lzZSI+ClNlY3Rpb25zIHdpdGggdGhpcyBiYWNrZ3JvdW5kIGluZGljYXRlIGV4ZXJjaXNlcyB0byBiZSBjb21wbGV0ZWQgZHVyaW5nIHRoZSB3b3Jrc2hvcC4KPC9kaXY+Cgo8ZGl2IGNsYXNzPSJpbmZvcm1hdGlvbiI+ClNlY3Rpb25zIHdpdGggdGhpcyBiYWNrZ3JvdW5kIGhpZ2hsaWdodCBwYXJ0aWN1bGFyIHNob3J0Y3V0cyBvciBvdGhlciByZWZlcmVuY2VzIHRoYXQgbWlnaHQgYmUgdXNlZnVsLgo8L2Rpdj4KCjxkaXYgY2xhc3M9Indhcm5pbmciPgpTZWN0aW9ucyB3aXRoIHRoaXMgYmFja2dyb3VuZCBnaXZlIGluZm9ybWF0aW9uIGFib3V0IHBvdGVudGlhbCBlcnJvciBtZXNzYWdlcyB5b3UgbWlnaHQgZW5jb3VudGVyLCBvciBwcm9ibGVtcyB0aGF0IG1pZ2h0IGFyaXNlIGluIHlvdXIgb3duIGRhdGEgYW5hbHlzaXMuCjwvZGl2PgoKIyMjIE1vcmUgb24gR2FsYXh5CgpUaGUgb2ZmaWNpYWwgR2FsYXh5IHBhZ2UgaGFzIG1hbnkgW3R1dG9yaWFsc10oaHR0cHM6Ly9nYWxheHlwcm9qZWN0Lm9yZy9sZWFybi8pIG9uIHVzaW5nIHRoZSBzZXJ2aWNlLCBhbmQgZXhhbXBsZXMgb2Ygb3RoZXIgdHlwZXMgb2YgYW5hbHlzaXMgdGhhdCBjYW4gYmUgcGVyZm9ybWVkIG9uIHRoZSBwbGF0Zm9ybS4KClRob3NlIGV2ZW50dWFsbHkgd2FudGVkIHRvIHBlcmZvcm0gdGhlaXIgb3duIFJOQS1zZXEgYW5hbHlzaXMgKGZvciBleGFtcGxlIGluIFIpLCBzaG91bGQgbG9vayBvdXQgZm9yIG90aGVyIGNvdXJzZXMKCiMjIyBDb3Vyc2VzIG9uIGFuYWx5c2luZyBSTkEtc2VxIGRhdGEgaW4gUgoKLSBbU2hlZmZpZWxkIEJpb2luZm9ybWF0aWNzIENvcmVdKGh0dHBzOi8vc2JjLnNoZWYuYWMudWsvdHJhaW5pbmcvcm5hLXNlcS1pbi1yLTIwMjAtMDItMTMvKQotIFtNb25hc2ggQmlvaW5mb3JtYXRpY3MgUGxhdGZvcm1dKGh0dHA6Ly9tb25hc2hiaW9pbmZvcm1hdGljc3BsYXRmb3JtLmdpdGh1Yi5pby9STkFzZXEtREUtYW5hbHlzaXMtd2l0aC1SLykKCgojIyBSTkEtc2VxIHdvcmtmbG93CgohW10oaHR0cHM6Ly9kYXRhYmVhdXR5LmNvbS9maWd1cmVzLzIwMTYtMDktMTMtUk5BLXNlcS1hbmFseXNpcy9ybmFfc2VxX3dvcmtmbG93LnBuZykKCldvcmtmbG93IGltYWdlIGZyb20gVGluZy15b3UgV2FuZydzIFtSTkEtc2VxIGRhdGEgYW5hbHlzaXMgcGFnZV0oaHR0cHM6Ly9kYXRhYmVhdXR5LmNvbS9ibG9nL3R1dG9yaWFsLzIwMTYvMDkvMTMvUk5BLXNlcS1hbmFseXNpcy5odG1sKQoKLS0tLS0KCiMjIEJhY2tncm91bmQKCiMjIyMgV2hlcmUgZG8gdGhlIGRhdGEgaW4gdGhpcyB0dXRvcmlhbCBjb21lIGZyb20/ClRoZSBkYXRhIGZvciB0aGlzIHR1dG9yaWFsIGNvbWVzIGZyb20gYSBOYXR1cmUgQ2VsbCBCaW9sb2d5IHBhcGVyLCBbKkVHRi1tZWRpYXRlZCBpbmR1Y3Rpb24gb2YgTWNsLTEgYXQgdGhlIHN3aXRjaCB0byBsYWN0YXRpb24gaXMgZXNzZW50aWFsIGZvciBhbHZlb2xhciBjZWxsIHN1cnZpdmFsKl0oaHR0cDovL3d3dy5uY2JpLm5sbS5uaWguZ292L3B1Ym1lZC8yNTczMDQ3MikgW0BGdTIwMTVdLiAKClRoaXMgc3R1ZHkgZXhhbWluZXMgdGhlIGV4cHJlc3Npb24gcHJvZmlsZXMgb2YgYmFzYWwgc3RlbS1jZWxsIGVucmljaGVkIGNlbGxzIChCKSBhbmQgY29tbWl0dGVkIGx1bWluYWwgY2VsbHMgKEwpIGluIHRoZSBtYW1tYXJ5IGdsYW5kIG9mIHZpcmdpbiwgcHJlZ25hbnQgYW5kIGxhY3RhdGluZyBtaWNlLiBTaXggZ3JvdXBzIGFyZSBwcmVzZW50LCB3aXRoIG9uZSBmb3IgZWFjaCBjb21iaW5hdGlvbiBvZiBjZWxsIHR5cGUgYW5kIG1vdXNlIHN0YXR1cy4gRWFjaCBncm91cCBjb250YWlucyB0d28gYmlvbG9naWNhbCByZXBsaWNhdGVzLgoKVGhlIGZ1bGwgZXhwZXJpbWVudGFsIGRlc2lnbiBpcyBhcyBmb2xsb3dzOi0KClJ1biAgfCBOYW1lIHwgQ2VsbFR5cGUgfCBTdGF0dXMKLS0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0tLS0gfCAtLS0tLS0tLS0tLS0tIHwgLS0tLS0tLS0tLS0tLSAgClNSUjE1NTI0NDQgfCBNQ0wxLUxBIHwgYmFzYWwgfCB2aXJnaW4KU1JSMTU1MjQ0NSB8IE1DTDEtTEIgfCBsdW1pbmFsIHwgdmlyZ2luClNSUjE1NTI0NDYgfCBNQ0wxLUxDIHwgTHVtaW5hbCB8IHByZWduYW5jeQpTUlIxNTUyNDQ3IHwgTUNMMS1MRCB8IEx1bWluYWwgfCBwcmVnbmFuY3kKU1JSMTU1MjQ0OCB8IE1DTDEtTEUgfCBsdW1pbmFsIHwgbGFjdGF0aW9uClNSUjE1NTI0NDkgfCBNQ0wxLUxGIHwgbHVtaW5hbCB8IGxhY3RhdGlvbgpTUlIxNTUyNDUwIHwgTUNMMS1ERyB8IGJhc2FsIHwgdmlyZ2luClNSUjE1NTI0NTEgfCBNQ0wxLURIIHwgbHVtaW5hbCB8IHZpcmdpbgpTUlIxNTUyNDUyIHwgTUNMMS1ESSB8IGJhc2FsIHwgcHJlZ25hbmN5ClNSUjE1NTI0NTMgfCBNQ0wxLURKIHwgYmFzYWwgfCBwcmVnbmFuY3kKU1JSMTU1MjQ1NCB8IE1DTDEtREsgfCBiYXNhbCB8IGxhY3RhdGlvbgpTUlIxNTUyNDU1IHwgTUNMMS1ETCB8IGJhc2FsIHwgbGFjdGF0aW9uCgoKCkZvciB0aGlzIHR1dG9yaWFsLCB3ZSB3aWxsIGFzc3VtZSB0aGF0IHRoZSAqd2V0LWxhYiogc3RhZ2VzIG9mIHRoZSBleHBlcmltZW50IGhhdmUgYmVlbiBwZXJmb3JtZWQgYW5kIHdlIGFyZSBub3cgaW4gdGhlIHJpZ2h0LWhhbmQgYnJhbmNoIG9mIHRoZSB3b3JrZmxvdy4gSW4gdGhpcyB0dXRvcmlhbCB3ZSB3aWxsIGRlbW9uc3RyYXRlIHRoZSBzdGVwcyBvZiAqKlF1YWxpdHkgYXNzZXNzbWVudCoqLCAqKmFsaWdubWVudCoqLCAqKnF1YW50aWZpY2F0aW9uKiogYW5kICoqZGlmZmVyZW50aWFsIGV4cHJlc3Npb24gdGVzdGluZyoqLgoKVGhlICpzdW1tYXJpc2VkKiBkYXRhIGZvciB0aGlzIGV4cGVyaW1lbnQgd2VyZSBtYWRlIGF2YWlsYWJsZSBvbiB0aGUgR2VuZSBFeHByZXNzaW9uIE9tbmlidXMgd2l0aCBhY2Nlc3Npb24gW0dTRTYwNDUwXShodHRwczovL3d3dy5uY2JpLm5sbS5uaWguZ292L2dlby9xdWVyeS9hY2MuY2dpP2FjYz1HU0U2MDQ1MCksIGFuZCBmdWxsIHJhdyBkYXRhIGNhbiBiZSBvYnRhaW5lZCB2aWEgdGhlIFtTUkEgcnVuIGJyb3dzZXJdKGh0dHBzOi8vdHJhY2UubmNiaS5ubG0ubmloLmdvdi9UcmFjZXMvc3R1ZHkvP2FjYz1TUlAwNDU1MzQmbz1hY2NfcyUzQWEpLiAqKkZvciB0aGUgcHVycG9zZXMgb2YgdGhpcyB3b3Jrc2hvcCB3ZSBoYXZlIGNyZWF0ZWQgYSBkb3duc2FtcGxlZCBkYXRhc2V0KioKCiMjIFNlY3Rpb24gMTogUHJlcGFyYXRpb24KIyMjIyAxLiBTaWduLXVwIHRvIHRoZSBFdXJvcGVhbiBHYWxheHkgc2VydmVyCgoKLSBodHRwczovL3VzZWdhbGF4eS5ldQotIFRoZSBBdXN0cmFsaWFuIHNlcnZlciBpcyBhbiBhbHRlcm5hdGl2ZSBpZiB0aGUgRXVyb3BlYW4gb25lIGlzIGRvd246LSBodHRwczovL3VzZWdhbGF4eS5vcmcuYXUvCgoKKipNYWtlIHN1cmUgeW91IGNoZWNrIHlvdXIgZW1haWwgdG8gYWN0aXZhdGUgeW91ciBhY2NvdW50KioKCgojIyMjIDIuICBJbXBvcnQgdGhlIFJOQS1zZXEgZGF0YSBmb3IgdGhlIHdvcmtzaG9wLgoKVG8gYWlkIHRoZSBwcm9jZXNzIG9mIGRhdGEgdXBsb2FkICh3aGljaCBjYW4gdGFrZSBhIHdoaWxlKSB3ZSBoYXZlIGNyZWF0ZWQgYSBsaW5rIHRoYXQgeW91IGNhbiB1c2UgdG8gYWNjZXNzIHRoZSBkYXRhIGZvciB0aGlzIHByYWN0aWNhbAoKLSBbSWYgdXNpbmcgRXVyb3BlYW4gc2VydmVyXShodHRwczovL3VzZWdhbGF4eS5ldS91L21hcmtkdW5uaW5nL2gvbXNjLXJuYS1zZXEtY291cnNlKQotIFtJZiB1c2luZyBBdXN0cmFsaWFuIHNlcnZlciBdKGh0dHBzOi8vdXNlZ2FsYXh5Lm9yZy5hdS91L21hcmtkdW5uaW5nL2gvYmVnaW5uZXJzcm5hc2Vxc2FsbW9uKQoKQWZ0ZXIgY2xpY2tpbmcgdGhlIGxpbmsgYWJvdmUsIHlvdSBzaG91bGQgc2VlIHRoZSBvcHRpb24gdG8gSW1wb3J0IHRoZSBzaGFyZWQgaGlzdG9yeS4gVGhpcyB3aWxsIG1ha2UgdGhlIGlucHV0IGRhdGEgYXZhaWxhYmxlIHRvIHlvdSBpbiBHYWxheHkKCiFbXShtZWRpYS9pbXBvcnRfaGlzdG9yeS5QTkcpCgojIyMgQ29tYmluaW5nIGxhbmVzCgo8ZGl2IGNsYXNzPSJ3YXJuaW5nIj4KSW4gYSBzZXF1ZW5jaW5nIGV4cGVyaW1lbnQsIHRoZSBkYXRhIGZvciBhIHBhcnRpY3VsYXIgc2FtcGxlIG1pZ2h0IGJlIHNwcmVhZCBhY3Jvc3MgbXVsdGlwbGUgKmxhbmVzKi4gRm9yIGV4YW1wbGUsIHdlIG1pZ2h0IGhhdmUgZmlsZXMgbmFtZWQgYFNSUjE1NTI0NDRfTDAwMS5mYXN0cS5nemAgYW5kIGBTUlIxNTUyNDQ0X0wwMDIuZmFzdHEuZ3pgIGluZGljYXRpbmcgdGhhdCB0aGUgcmVhZHMgZm9yIHRoZSBzYW1wbGUgYFNSUjE1NTI0NDRgIGFyZSBjb250YWluaW5nIGluIHR3byBzZXBhcmF0ZSBmaWxlcy4gSWYgc28sIHRoZSB0d28gZmFzdHEuZ3ogZmlsZXMgd2lsbCBuZWVkIHRvIGJlIGNvbWJpbmVkLiBUaGUgYGZhc3RxLmd6YCBmaWxlcyB3aWxsIG5lZWQgdG8gYmUgZGVjb21wcmVzc2VkIG9uIHlvdXIgbWFjaGluZSBmaXJzdCAodGhlIFs3emlwIHRvb2xdKGh0dHBzOi8vd3d3LjctemlwLm9yZy9kb3dubG9hZC5odG1sKSBjYW4gZG8gdGhpcyBvbiBXaW5kb3dzKSBhbmQgdGhlbiB1cGxvYWRlZCBhcyBmYXN0cS4gVGhlICpDb25jYXRlbnRhdGUgRGF0YXNldHMqIHRvb2wgY2FuIHRoZW4gYmUgdXNlZCB0byBjb21iaW5lIHRoZSBmaWxlcyBmb3IgZWFjaCBzYW1wbGUuCgo8L2Rpdj4KCiMjIyBVcGxvYWRpbmcgbGFyZ2UgZmlsZXMKCjxkaXYgY2xhc3M9Indhcm5pbmciPgpHYWxheHkgcmVjb21tZW5kIHRoYXQgbGFyZ2UgZGF0YXNldHMgKEdicyBvZiBkYXRhKSBhcmUgdXBsb2FkZWQgdXNpbmcgKkZUUCouIEluc3RydWN0aW9ucyBmb3IgZG9pbmcgdGhpcyBjYW4gYmUgZm91bmQgaGVyZTotCgpodHRwczovL2dhbGF4eXByb2plY3Qub3JnL2Z0cC11cGxvYWQvCgoqKk4uQi4gSWYgeW91IGFyZSB1c2luZyB0aGUgRXVyb3BlYW4gc2VydmVyLCByZXBsYWNlIGB1c2VnYWxheHkub3JnYCB3aXRoIGB1c2VnYWxheHkuZXVgIHdoZW4gZm9sbG93aW5nIHRoZSBpbnN0cnVjdGlvbnMqKgoKWW91IHdpbGwgbmVlZCBhbiBGVFAgcHJvZ3JhbSBzdWNoIGFzIFsqZmlsZXppbGxhKl0oaHR0cHM6Ly9maWxlemlsbGEtcHJvamVjdC5vcmcvKSwgd2hpY2ggaGFzIGEgZnJlZSBkb3dubG9hZC4gCgoKPC9kaXY+CgojIyMgVW5kZXJzdGFuZGluZyBmYXN0cSBmb3JtYXQKCkVhY2ggcmVhZCBpcyBkZXNjcmliZWQgYnkgNCBsaW5lcyBpbiB0aGUgZmlsZTotCgo8aW1nIHNyYz0ibWVkaWEvZmFzdHEtaGVhZGVyLnBuZyI+CgpUaGUgcXVhbGl0eSBzY29yZXMgYXJlIFtBU0NJSV0oaHR0cDovL2FzY2lpLWNvZGUuY29tLykgcmVwcmVzZW50YXRpb25zIG9mIGhvdyBjb25maWRlbnQgd2UgYXJlIHRoYXQgYSBwYXJ0aWN1bGFyIGJhc2UgaGFzIGJlZW4gY2FsbGVkIGNvcnJlY3RseS4gTGV0dGVycyB0aGF0IGFyZSBmdXJ0aGVyIGFsb25nIHRoZSBhbHBoYWJldCBpbmRpY2F0ZSBoaWdoZXIgY29uZmlkZW5jZS4gVGhpcyBpcyBpbXBvcnRhbnQgd2hlbiB0cnlpbmcgdG8gaWRlbnRpZnkgdHlwZXMgb2YgZ2Vub21lIHZhcmlhdGlvbiBzdWNoIGFzIHNpbmdsZSBiYXNlIGNoYW5nZXMsIGJ1dCBpcyBhbHNvIGluZGljYXRpdmUgb2YgdGhlIG92ZXJhbGwgcXVhbGl0eSBvZiB0aGUgc2VxdWVuY2luZy4gRGlmZmVyZW50IHNjYWxlcyBoYXZlIGJlZW4gZW1wbG95ZWQgb3ZlciB0aW1lIChyZXN1bHRpbmcgaW4gYSBkaWZmZXJlbnQgc2V0IG9mIGNoYXJhY3RlcnMgYXBwZWFyaW5nIGluIHRoZSBmaWxlKS4gV2Ugd2lsbCBuZWVkIHRvIHRlbGwgR2FsYXh5IHdoaWNoIHNjYWxlIGhhcyBiZWVuIHVzZWQgaW4gb3JkZXIgdGhhdCB3ZSBjYW4gcHJvY2VzcyB0aGUgZGF0YSBjb3JyZWN0bHkuCgoKIyMjIERlcml2aW5nIHRoZSBRdWFsaXR5IFNjb3JlCgpGaXJzdCBvZiBhbGwsIHdlIGNvbnZlcnQgdGhlIGJhc2UtY2FsbGluZyBwcm9iYWJpbGl0eSAocCkgaW50byBhIGBRYCBzY29yZSB1c2luZyB0aGUgZm9ybXVsYQoKLSBRdWFsaXR5IHNjb3JlcyAkJCBRID0gLTEwbG9nX3sxMH1wJCQKICAgICsgUSA9IDMwLCBwPTAuMDAxCiAgICArIFEgPSAyMCwgcD0wLjAxCiAgICArIFEgPSAxMCwgcD0wLjEKLSBUaGVzZSBudW1lcmljIHF1YW50aWVzIGFyZSAqZW5jb2RlZCogYXMgWyoqQVNDSUkqKl0oaHR0cDovL2FzY2lpLWNvZGUuY29tLykgY29kZQogICAgKyBBdCBsZWFzdCAzMyB0byBnZXQgdG8gbWVhbmluZ2Z1bCBjaGFyYWN0ZXJzCiAgICAoaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRkFTVFFfZm9ybWF0KQogICAgCiFbXShtZWRpYS9waHJlZC5wbmcpICAgICAgCgojIyMgUXVhbGl0eSBTY29yZXMgdG8gcHJvYmFiaWxpdGllcwoKLSBsb29rLXVwIHRoZSBBU0NJSSBjb2RlIGZvciBlYWNoIGNoYXJhY3RlcgotIHN1YnRyYWN0IHRoZSBvZmZzZXQgdG8gZ2V0IHRoZSBRIHNjb3JlCi0gY29udmVydCB0byBhIHByb2JhYmlsaXR5IHVzaW5nIHRoZSBmb3JtdWxhOi0KCiQkIHAgPSAxMF57LVEvMTB9ICQkCgohW10obWVkaWEvcXVhbGl0eS10by1wcm9iLnBuZykKCkluIHByYWN0aWNlLCB3ZSBkb24ndCBoYXZlIHRvIGNvbnZlcnQgdGhlIHZhbHVlcyBhcyB3ZSBoYXZlIHNvZnR3YXJlIHRoYXQgd2lsbCBkbyB0aGlzIGF1dG9tYXRpY2FsbHkKCgotLS0tLQoKIyMgU2VjdGlvbiAyOiBRdWFsaXR5IGFzc2Vzc21lbnQgd2l0aCBGYXN0UUMKCltGYXN0UUNdKGh0dHBzOi8vd3d3LmJpb2luZm9ybWF0aWNzLmJhYnJhaGFtLmFjLnVrL3Byb2plY3RzL2Zhc3RxYy8pIGlzIGEgcG9wdWxhciB0b29sIGZyb20gW0JhYnJhaGFtIEluc3RpdHV0ZSBCaW9pbmZvcm1hdGljcyBHcm91cF0oaHR0cHM6Ly93d3cuYmlvaW5mb3JtYXRpY3MuYmFicmFoYW0uYWMudWsvaW5kZXguaHRtbCkgdXNlZCBmb3IgKnF1YWxpdHkgYXNzZXNzbWVudCogb2Ygc2VxdWVuY2luZyBkYXRhLiBNb3N0IEJpb2luZm9ybWF0aWNzIHBpcGVsaW5lcyB3aWxsIHVzZSBGYXN0UUMsIG9yIHNpbWlsYXIgdG9vbHMgaW4gdGhlIGZpcnN0IHN0YWdlIG9mIHRoZSBhbmFseXNpcy4gVGhlIFtkb2N1bWVudGF0aW9uXShodHRwczovL3d3dy5iaW9pbmZvcm1hdGljcy5iYWJyYWhhbS5hYy51ay9wcm9qZWN0cy9mYXN0cWMvSGVscC8pIGZvciBGYXN0UUMgd2lsbCBoZWxwIHlvdSB0byBpbnRlcnByZXQgdGhlIHBsb3RzIGFuZCBzdGF0cyBwcm9kdWNlZCBieSB0aGUgdG9vbC4gQSB0cmFmZmljIGxpZ2h0IHN5c3RlbSBpcyB1c2VkIHRvIGFsZXJ0IHRoZSB1c2VyJ3MgYXR0ZW50aW9uIHRvIHBvc3NpYmxlIGlzc3Vlcy4gSG93ZXZlciwgaXQgaXMgd29ydGggYmVhcmluZyBpbiBtaW5kIHRoYXQgdGhlIHRvb2wgaXMgYmxpbmQgdG8gdGhlIHBhcnRpY3VsYXIgdHlwZSBvZiBzZXF1ZW5jaW5nIHlvdSBhcmUgcGVyZm9ybWluZyAoaS5lLiB3aG9sZS1nZW5vbWUsIENoSVAtc2VxLCBSTkEtc2VxKSwgc28gc29tZSB3YXJuaW5ncyBtaWdodCBiZSBleHBlY3RlZCBkdWUgdG8gdGhlIG5hdHVyZSBvZiB5b3VyIGV4cGVyaW1lbnQuCgo8ZGl2IGNsYXNzPSJpbmZvcm1hdGlvbiI+CgojIyMjICpGYXN0USBRdWFsaXR5IENvbnRyb2wqIC0+ICpGYXN0UUMgUmVhZCBRdWFsaXR5IHJlcG9ydHMqCgo8L2Rpdj4KCioqTWFrZSBzdXJlIHlvdSBzZWxlY3QgdGhpcyB0b29sLiBUaGVyZSBpcyBhbm90aGVyIHZlcnNpb24gb2YgRmFzdFFDIHByZXNlbnQsIHdoaWNoIGRvZXMgbm90IHByb2R1Y2Ugc29tZSBvZiB0aGUgb3V0cHV0IHdlIG5lZWQgZm9yIGEgbGF0ZXIgc3RlcCoqCgotIFNlbGVjdCBvbmUgb2YgdGhlIEZBU1RRIGZpbGVzIGFzIGlucHV0IGFuZCAqRXhlY3V0ZSogdGhlIHRvb2wuCi0gV2hlbiB0aGUgdG9vbCBmaW5pc2hlcyBydW5uaW5nLCB5b3Ugc2hvdWxkIGhhdmUgYW4gSFRNTCBmaWxlIGluIHlvdXIgSGlzdG9yeS4gQ2xpY2sgb24gdGhlIGV5ZSBpY29uIHRvIHZpZXcgdGhlIHZhcmlvdXMgcXVhbGl0eSBtZXRyaWNzLgotIFJ1biBGYXN0cWMgb24gdGhlIHJlbWFpbmcgZmFzdHEgZmlsZXMsIGJ1dCBkb24ndCBleGFtaW5lIHRoZSByZXN1bHRzIGp1c3QgeWV0LgoKCjxkaXYgY2xhc3M9ImV4ZXJjaXNlIj4KCioqUXVlc3Rpb246IERvIHRoZSBkYXRhIHNlZW0gdG8gYmUgb2YgcmVhc29uYWJsZSBxdWFsaXR5PyAqKgoKWW91IGNhbiB1c2UgdGhlIFtkb2N1bWVudGF0aW9uXShodHRwczovL3d3dy5iaW9pbmZvcm1hdGljcy5iYWJyYWhhbS5hYy51ay9wcm9qZWN0cy9mYXN0cWMvSGVscC8zJTIwQW5hbHlzaXMlMjBNb2R1bGVzLykgdG8gaGVscCBpbnRlcnByZXQgdGhlIHBsb3RzCgo8L2Rpdj4KCklmIHBvb3IgcXVhbGl0eSByZWFkcyB0b3dhcmRzIHRoZSBlbmRzIG9mIHJlYWRzIGFyZSBjb25zaWRlcmVkIHRvIGJlIGEgcHJvYmxlbSwgb3IgdGhlcmUgaXMgY29uc2lkZXJhYmxlIGFkYXB0ZXIgY29udGFtaW5hdGlvbiwgd2UgY2FuIGVtcGxveSB2YXJpb3VzIHRvb2xzIHRvICp0cmltKiBvdXIgZGF0YS4KCkhvd2V2ZXIsIGEgcmVjZW50IHBhcGVyIGRlbW9uc3RyYXRlZCB0aGF0IHJlYWQgdHJpbW1pbmcgaXMgbm8gbG9uZ2VyIHJlcXVpcmVkIHByaW9yIHRvIGFsaWdubWVudDotIGh0dHBzOi8vd3d3LmJpb3J4aXYub3JnL2NvbnRlbnQvMTAuMTEwMS84MzM5NjJ2MQoKPGRpdiBjbGFzcz0id2FybmluZyI+CgpJZiB5b3Ugc3VzcGVjdCBjb250YW1pbmF0aW9uIGZyb20gYWRhcHRlciBzZXF1ZW5jZSBvciB1bmFjY2VwdGFibGUgcXVhbGl0eSBzY29yZXMgdG93YXJkcyB0aGUgZW5kcyBvZiByZWFkcyB2YXJpb3VzIHRyaW1taW5nIG9wdGlvbnMgYXJlIHN1cHBvcnRlZCBieSB0aGUgKlRyaW1tb21hdGljKiB0b29sIChhbW9uZ3N0IG90aGVycykKCiMjIyMgKkZBU1RBL0ZBU1RRKiAtPiAqVHJpbW1vbWF0aWMqCgpUaGUgb3BlcmF0aW9ucyBzdXBwb3J0ZWQgYnkgdHJpbW1vbWF0aWMgd2lsbCBwcm9iYWJseSBub3QgYmUgdmVyeSBpbmZvcm1hdGl2ZSBvbiBvdXIgZXhhbXBsZSBkYXRhIChhcyBpdCBoYXMgYWxyZWFkeSBiZWVuIHByb2Nlc3NlZCksIGJ1dCB5b3UgY2FuIHRyeSBzZXZlcmFsIG9wZXJhdGlvbnMgaWYgeW91IGdldCB0aW1lOi0KCi0gUmVtb3ZpbmcgSWxsdW1pbmEgYWRhcHRlciBzZXF1ZW5jZXMgYnkgc2V0dGluZyAqUGVyZm9ybSBpbml0aWFsIElMTFVNSU5BQ0xJUCogdG8gKlllcyogYW5kIHNlbGVjdGluZyB0aGUgYXBwcm9wcmlhdGUgYWRhcHRlciB0eXBlCi0gUmVtb3ZlIHBvb3IgcXVhbGl0eSBiYXNlcyBhdCB0aGUgZW5kIG9mIHJlYWRzIGJ5IGNob29zaW5nICpDdXQgYmFzZXMgb2ZmIHRoZSBlbmQgb2YgYSByZWFkLCBpZiBiZWxvdyBhIHRocmVzaG9sZCBxdWFsaXR5IChUUkFJTElORykqIHVuZGVyICpTZWxlY3QgVHJpbW1vbWF0aWMgb3BlcmF0aW9uIHRvIHBlcmZvcm0qCi0gUmVtb3ZlIHBvb3IgcXVhbGl0eSBiYXNlcyBhdCB0aGUgc3RhcnQgb2YgcmVhZHMgYnkgY2hvb3NpbmcgKkN1dCBiYXNlcyBvZmYgdGhlIHN0YXJ0IG9mIGEgcmVhZCwgaWYgYmVsb3cgYSB0aHJlc2hvbGQgcXVhbGl0eSAoTEVBRElORykqIHVuZGVyICpTZWxlY3QgVHJpbW1vbWF0aWMgb3BlcmF0aW9uIHRvIHBlcmZvcm0qCi0gWW91IGNhbiBhcHBseSBtdWx0aXBsZSBvcGVyYXRpb25zIGluIHR1cm4gYnkgY2xpY2tpbmcgKkluc2VydCBUcmltbW9tYXRpYyBPcGVyYXRpb24qCgo8L2Rpdj4KCjxkaXYgY2xhc3M9Indhcm5pbmciPgoKSWYgeW91IGFsc28gc3VzcGVjdCBjb250YW1pbmF0aW9uIGJ5IGFub3RoZXIgb3JnYW5pc20sIG9yIHJSTkEgcHJlc2VudCBpbiB5b3VyIGRhdGEsIHlvdSBjYW4gdXNlIHRoZSBzb3J0TWVSTkEgdG9vbCB0byByZW1vdmUgdGhpcyBhcnRlZmFjdC4KPC9kaXY+CgoKIyMgQ29tYmluaW5nIFFDIHJlcG9ydHMKCkl0IGNhbiBiZSBxdWl0ZSB0aXJlc29tZSB0byBjbGljayB0aHJvdWdoIG11bHRpcGxlIFFDIHJlcG9ydHMgYW5kIGNvbXBhcmUgdGhlIHJlc3VsdHMgZm9yIGRpZmZlcmVudCBzYW1wbGVzLiBJdCBpcyB1c2VmdWwgdG8gaGF2ZSBhbGwgdGhlIFFDIHBsb3RzIG9uIHRoZSBzYW1lIHBhZ2Ugc28gdGhhdCB3ZSBjYW4gbW9yZSBlYXNpbHkgc3BvdCB0cmVuZHMgaW4gdGhlIGRhdGEuCgpUaGUgW211bHRpcWNdKGh0dHBzOi8vbXVsdGlxYy5pbmZvLykgdG9vbCBoYXMgYmVlbiBkZXNpZ25lZCBmb3IgdGhlIHRhc2tzIG9mIGFnZ3JlZ2F0aW5nIHFjIHJlcG9ydHMgYW5kIGNvbWJpbmluZyBpbnRvIGEgc2luZ2xlIHJlcG9ydCB0aGF0IGlzIGVhc3kgdG8gZGlnZXN0LgoKCjxkaXYgY2xhc3M9ImluZm9ybWF0aW9uIj4KCipGQVNUUSBRdWFsaXR5IENvbnRyb2wqIC0+ICpNdWx0aXFjKgoKPC9kaXY+CgpVbmRlciAqV2hpY2ggdG9vbCB3YXMgdXNlZCBnZW5lcmF0ZSBsb2dzPyogQ2hvb3NlICpmYXN0cWMqIGFuZCBzZWxlY3QgdGhlIFJhd0RhdGEgb3V0cHV0IGZyb20gdGhlIGZhc3RxYyBydW4gb24gZWFjaCBvZiB5b3VyIGJhbSBmaWxlcy4KCgo8ZGl2IGNsYXNzPSJleGVyY2lzZSI+CgpRdWVzdGlvbjogUmVwZWF0IHRoZSBGYXN0UUMgYW5hbHlzaXMgZm9yIHRoZSByZW1haW5pbmcgZmFzdHEgZmlsZXMgYW5kIGNvbWJpbmUgdGhlIHJlcG9ydHMgd2l0aCBgbXVsdGlRQ2AuIERvIHRoZSBmYXN0cSBmaWxlcyBzZWVtIHRvIGhhdmUgY29uc2lzdGVudGx5IGhpZ2gtcXVhbGl0eT8KPC9kaXY+CgoKIyMgU2VjdGlvbiAzOiBBbGlnbm1lbnQKCkluIHRoaXMgc2VjdGlvbiB3ZSBtYXAgdGhlIHJlYWRzIGluIG91ciBGQVNUUSBmaWxlcyB0byBhIHJlZmVyZW5jZSBnZW5vbWUuIEFzCnRoZXNlIHJlYWRzIG9yaWdpbmF0ZSBmcm9tIG1STkEsIHdlIGV4cGVjdCBzb21lIG9mIHRoZW0gd2lsbCBjcm9zcyBleG9uL2ludHJvbgpib3VuZGFyaWVzIHdoZW4gd2UgYWxpZ24gdGhlbSB0byB0aGUgcmVmZXJlbmNlIGdlbm9tZS4gYEhJU0FUMmAgaXMgYSBzcGxpY2UtYXdhcmUKbWFwcGVyIGZvciBSTkEtc2VxIHJlYWRzIHRoYXQgaXMgYmFzZWQgb24gQm93dGllLiBJdCB1c2VzIHRoZSBtYXBwaW5nIHJlc3VsdHMKZnJvbSBCb3d0aWUgdG8gaWRlbnRpZnkgc3BsaWNlIGp1bmN0aW9ucyBiZXR3ZWVuIGV4b25zLiBNb3JlIGluZm9ybWF0aW9uIG9uCkhJU0FUMiBjYW4gYmUgZm91bmQgW2hlcmVdKGh0dHBzOi8vY2NiLmpodS5lZHUvc29mdHdhcmUvaGlzYXQyL2luZGV4LnNodG1sKS4KCgo8ZGl2IGNsYXNzPSJpbmZvcm1hdGlvbiI+CgpNYXBwaW5nIC0+IEhJU0FUMgoKPC9kaXY+CgoKCiMjIyMgMS4gIE1hcC9hbGlnbiB0aGUgcmVhZHMgd2l0aCBISVNBVDIgdG8gdGhlIG1tMTAgcmVmZXJlbmNlIGdlbm9tZQpJbiB0aGUgbGVmdCB0b29sIHBhbmVsIG1lbnUsIHVuZGVyIE5HUyBBbmFseXNpcywgc2VsZWN0CioqTWFwcGluZyA+IEhJU0FUMioqIGFuZCBzZXQgdGhlIHBhcmFtZXRlcnMgYXMgZm9sbG93czogIAoKLSAqKklzIHRoaXMgc2luZ2xlLWVuZCBvciBwYWlyZWQtZW5kIGRhdGE/KiogU2luZ2xlLWVuZCAoYXMgaW5kaXZpZHVhbCBkYXRhc2V0cykgIAotICoqRkFTVFEgZmlsZSoqICAKKENsaWNrIG9uIHRoZSBtdWx0aXBsZSBkYXRhc2V0cyBpY29uIGFuZCBzZWxlY3QgYWxsIGZvdXIgb2YgdGhlCkZBU1RRIGZpbGVzKQogICAgLSBgU1JSMTU1MjQ0NC5mYXN0cS5nemAKICAgIC0gYFNSUjE1NTI0NTAuZmFzdHEuZ3pgCiAgICAtIGBTUlIxNTUyNDUyLmZhc3RxLmd6YAogICAgLSBgU1JSMTU1MjQ1My5mYXN0cS5nemAKCi0gKipTb3VyY2UgZm9yIHRoZSByZWZlcmVuY2UgZ2Vub21lKiogVXNlCmJ1aWx0LWluIGdlbm9tZQotICoqU2VsZWN0IGEgcmVmZXJlbmNlIGdlbm9tZToqKiBNb3VzZSAoTXVzIE11c2N1bHVzKTogbW0xMAotIFVzZSBkZWZhdWx0cyBmb3IgdGhlIG90aGVyIGZpZWxkcwotIEV4ZWN1dGUKCgpOb3RlOiBUaGlzIG1heSB0YWtlIGEgZmV3IG1pbnV0ZXMsIGRlcGVuZGluZyBvbiBob3cgYnVzeSB0aGUgc2VydmVyIGlzLgoKCgojIyMjIDIuICBSZW5hbWUgdGhlIG91dHB1dCBmaWxlcwpZb3Ugc2hvdWxkIGhhdmUgNCBvdXRwdXQgZmlsZXM7IG9uZSBmb3IgZWFjaCBvZiB0aGUgRkFTVFEgaW5wdXQgZmlsZXM6CgpgSElTQVQyIG9uIGRhdGEuLiBhbGlnbmVkIHJlYWRzIChCQU0pYAoKSXQgd2lsbCBiZSBoZWxwZnVsIHRvIHJlbmFtZSB0aGVzZSB0byBzb21ldGhpbmcgc2hvcnRlciBmb3IgdGhlIG5leHQgc3RlcHMuCgotIGBTUlIxNTUyNDQ0LmJhbWAKLSBgU1JSMTU1MjQ1MC5iYW1gCi0gYFNSUjE1NTI0NTIuYmFtYAotIGBTUlIxNTUyNDUzLmJhbWAKCjxkaXYgY2xhc3M9Indhcm5pbmciPgoKSWYgdGhpcyBzdGVwIGlzIHRha2luZyB0b28gbG9uZywgdGhlcmUgaXMgYW4gYWxpZ25lZCBiYW0gZmlsZSBwcmVzZW50IGluIHRoZSBnb29nbGUgZHJpdmUgbGluay4gWW91IGNhbiB1c2UgdGhpcyBpbiB0aGUgZm9sbG93aW5nIHN0ZXBzIG9mIHRoZSB0dXRvcmlhbC4KCjwvZGl2PgoKPGRpdiBjbGFzcz0iaW5mb3JtYXRpb24iPgoKKlNUQVIqIGlzIGFsc28gYW5vdGhlciBwb3B1bGFyIG9wdGlvbiBmb3IgYWxpZ25lZCBSTkEtc2VxIHJlYWRzLiBXZSB3b24ndCBjb3ZlciB0aGlzIHRvZGF5LCBvciB0aGUgcmVsYXRpdmUgbWVyaXRzIG9mIGRpZmZlcmVudCBtZXRob2RzLiBJZiB5b3Ugd2FudCB0byB0cnkgU1RBUiBpbiB5b3VyIG93biB0aW1lIHlvdSBjYW4gZmluZCBpdCB1bmRlci4KCgo8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC1pbmZvIj4KCk1hcHBpbmcgLT4gUk5BIFNUQVIKCjwvZGl2PgoKIyMgQWJvdXQgdGhlIGFsaWduZWQgcmVhZCBmb3JtYXQKClVubGlrZSBtb3N0IG9mIEJpb2luZm9tYXRpY3MsIGEgKnNpbmdsZSBzdGFuZGFyZCogZmlsZSBmb3JtYXQgaGFzIGVtZXJnZWQgZm9yIGFsaWduZWQgcmVhZHMuIE1vcmVvZXZlciwgdGhpcyBmaWxlIGZvcm1hdCBpcyBjb25zaXN0ZW50IHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB5b3UgaGF2ZSBETkEtc2VxLCBSTkEtc2VxLCBDaElQLXNlcS4uLiBkYXRhLiAKCgpUaGUgZmlyc3QgcGFydCBvZiB0aGUgaGVhZGVyIGxpc3RzIHRoZSBuYW1lcyAoYFNOYCkgb2YgdGhlIHNlcXVlbmNlcyAoY2hyb21vc29tZXMpIHVzZWQgaW4gYWxpZ25tZW50LCB0aGVpciBsZW5ndGggKGBMTmApLiBTb21ldGltZXMsICBhICptZDVzdW0qICJbZGlnaXRhbCBmaW5nZXJwcmludF0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTWQ1c3VtKSIgb2YgdGhlIGAuZmFzdGFgIGZpbGUgdXNlZCBmb3IgYWxpZ25tZW50IChgTTVgKSBpcyBzaG93bi4KCmBgYApASEQgVk46MS4wIFNPOmNvb3JkaW5hdGUKQFNRIFNOOmNocjEgTE46MTk1NDcxOTcxCkBTUSBTTjpjaHIxMCBMTjoxMzA2OTQ5OTMKQFNRIFNOOmNocjExIExOOjEyMjA4MjU0MwouLi4uLgouLi4uLgoKYGBgCgpJZiBtdXRsaXBsZSBzYW1wbGVzIHdlcmUgcHJlc2VudCBpbiB0aGUgZmlsZSAoaS5lLiB0aGUgc2FtcGxlcyBoYXZlIGJlZW4gKm11bHRpcGxleGVkKiksICpyZWFkIGdyb3VwcyogY2FuIGJlIHVzZWQgdG8gaWRlbnRpZnkgd2hpY2ggc2VxdWVuY2luZyBsaWJyYXJ5LCBzZXF1ZW5jaW5nIGNlbnRyZSwgTGFuZSwgc2FtcGxlIG5hbWUgZXRjLgoKKCoqbm90IHByZXNlbnQgZm9yIHRoZSBleGFtcGxlIGRhdGEgaW4gdGhpcyBjb3Vyc2UqKikKCmBgYApAUkcJSUQ6U1JSMDc3ODUwCUNOOmJpCUxCOlNvbGV4YS00MjA1NwlQTDppbGx1bWluYQlQVTpJTExVTUlOQQlTTTpOQTA2OTg0CkBSRwlJRDpTUlIwODE2NzUJQ046YmkJTEI6U29sZXhhLTQyMzE2CVBMOmlsbHVtaW5hCVBVOklMTFVNSU5BCVNNOk5BMDY5ODQKQFJHCUlEOlNSUjA4MDgxOAlDTjpiaQlMQjpTb2xleGEtNDQ3NzAJUEw6aWxsdW1pbmEJUFU6SUxMVU1JTkEJU006TkEwNjk4NApAUkcJSUQ6U1JSMDg0ODM4CUNOOmJpCUxCOlNvbGV4YS00MjMxNglQTDppbGx1bWluYQlQVTpJTExVTUlOQQlTTTpOQTA2OTg0CkBSRwlJRDpTUlIwODE3MzAJQ046YmkJTEI6U29sZXhhLTQyMzE2CVBMOmlsbHVtaW5hCVBVOklMTFVNSU5BCVNNOk5BMDY5ODQKLi4uLi4KLi4uLi4KCmBgYAoKRmluYWxseSwgd2UgaGF2ZSBhIHNlY3Rpb24gd2hlcmUgd2UgY2FuIHJlY29yZCB0aGUgcHJvY2Vzc2luZyBzdGVwcyB1c2VkIHRvIGRlcml2ZSB0aGUgZmlsZS4gVGhpcyBpcyAKYGBgCkBQRyBJRDpoaXNhdDIgUE46aGlzYXQyIFZOOjIuMS4wIENMOiIvbW50L3B1bHNhci9kZXBlbmRlbmNpZXMvX2NvbmRhL2VudnMvbXVsbGVkLXYxLWU3MzIxYmE0NmZhNWVhNGM2YjlhMDZiNzhlNmNkNTE4MmIzM2MwYTQ3YzJjODZiNWQ2MTBlMTM2MWY4YjE2ODYvYmluL2hpc2F0Mi1hbGlnbi1zIC0td3JhcHBlciBiYXNpYy0wIC1wIDQgLXggL2N2bWZzL2RhdGEuZ2FsYXh5cHJvamVjdC5vcmcvbWFuYWdlZC9oaXNhdDJfaW5kZXgvbW0xMC9tbTEwIC1VIC90bXAvMTYyODIudW5wIgouLi4uCi4uLi4KCmBgYAoKTmV4dCBpcyBhICp0YWItZGVsaW1pdGVkKiBzZWN0aW9uIHRoYXQgZGVzY3JpYmVzIHRoZSBhbGlnbm1lbnQgb2YgZWFjaCBzZXF1ZW5jZSBpbiBkZXRhaWwuIAoKYGBgClNSUjE1NTI0NTAuMjIwMjg5CTAJY2hyMQkzMjAwODM5CTYwCTEwME0JKgkwCTAJR0dDVENBQ0NBQUdUQVRHQVRHR1RUVENBVEFDQ0NBR0FBQUFBQ0FUVFRHVFRDVFRUVEdHQVRHQ0NBVFRBR1RUQ0FHQ0NBR1RHVENBQUNBVEdBQ1RBR1RHR1RUVENDQ0FBR0NBQwlDQ0NGRkZGREhIR0RIR0lJSkpKSUhHSEdHSUdISUlJR0ZIR0hCSUlISUpBR0lKSUpKR0dDSEpKSUdJSkpKR0hDQUdHSEhJSUNHR0hISEhISEZGRkZGRENFOz9BQUNDRENERERDCUFTOmk6MCBYTjppOjAgWE06aTowIFhPOmk6MCBYRzppOjAgTk06aTowIE1EOlo6MTAwIFlUOlo6VVUgTkg6aToxClNSUjE1NTI0NTAuMTM4Nzk3CTE2CWNocjEJMzIwMTEzMgk2MAkxMDBNCSoJMAkwCUNBVFRUVFRBQUNBR0NBVEFUVFRHVENUVEFHQ1RUVEFBQVRDQ0FHQUdUQUNUR1RUVEdHQ1RUQ0FBQUdBQUdBVEFHVENBVENUQ1RHR1RUQ1RDVFRBQ1RHQUdBQVRBR0FBQUdUQ1QJRERFRUVFRUVFRkZGRkZGRkhISEhISUlHQ0hHRUpKSkpKSkpKSkpJSkpKSkpKSkpKSkpKSUpJSkpKSkpKSkpKSkpKSUdKSkpKSklKSkpKSkpKSUhKSkpKSEhISEhGRkZGRkNDQwlBUzppOjAgWE46aTowIFhNOmk6MCBYTzppOjAgWEc6aTowIE5NOmk6MCBNRDpaOjEwMCBZVDpaOlVVIE5IOmk6MQoKYGBgCgpUaGUgZmlyc3QgMTEgY29sdW1ucyBvZiBlYWNoIGxpbmUgaGF2ZSBhbiBvZmZpY2lhbCBzcGVjaWZpY2F0aW9uCgpDb2x1bW4gfCBPZmZpY2lhbCBOYW1lIHwgQnJpZWYKLS0tLS0tIHwgLS0tLS0tLS0tLS0tLS0gfCAtLS0tLS0tLS0tLQoxICAgICAgfCBRTkFNRSAgICAgICAgICB8IFNlcXVlbmNlIElECjIgICAgICB8IEZMQUcgICAgICAgICAgIHwgU2VxdWVuY2UgcXVhbGl0eSBleHByZXNzZWQgYXMgYSBiaXR3aXNlIGZsYWcKMyAgICAgIHwgUk5BTUUgICAgICAgICAgfCBDaHJvbW9zb21lCjQgICAgICB8IFBPUyAgICAgICAgICAgIHwgU3RhcnQgUG9zaXRpb24KNSAgICAgIHwgTUFQUSAgICAgICAgICAgfCBNYXBwaW5nIFF1YWxpdHkKNiAgICAgIHwgQ0lHQVIgICAgICAgICAgfCBEZXNjcmliZXMgcG9zaXRpb25zIG9mIG1hdGNoZXMsIGluc2VydGlvbnMsIGRlbGV0aW9ucyB3LnIudCByZWZlcmVuY2UKNyAgICAgIHwgUk5FWFQgICAgICAgICAgfCBSZWYuIG5hbWUgb2YgbWF0ZSAvIG5leHQgcmVhZAo4ICAgICAgfCBQTkVYVCAgICAgICAgICB8IFBvc3Rpb24gb2YgbWF0ZSAvIG5leHQgcmVhZAo5ICAgICAgfCBUTEVOICAgICAgICAgICB8IE9ic2VydmVkIFRlbXBsYXRlIGxlbmd0aAoxMCAgICAgfCBTRVEgICAgICAgICAgICB8IFNlcXVlbmNlCjExICAgICB8IFFVQUwgICAgICAgICAgIHwgQmFzZSBRdWFsaXRpZXMKClRoZXJlIGNhbiBhbHNvIGJlIGFsbCBtYW5uZXIgb2Ygb3B0aW9uYWwgdGFncyBhcyBleHRyYSBjb2x1bW5zIGludHJvZHVjZSBieSBhbiBhbGlnbmVyIG9yIGRvd25zdHJlYW0gYW5hbHlzaXMgdG9vbC4gQSBjb21tb24gdXNlIGlzIHRoZSBgUkdgIHRhZyB3aGljaCByZWZlcnMgYmFjayB0byB0aGUgcmVhZCBncm91cHMgaW4gdGhlIGhlYWRlci4KCgojIyMgUXVhbGl0eSBDb250cm9sIEZsYWdzCgpUaGUgKiJmbGFncyIqIGluIHRoZSBzYW0gZmlsZSBjYW4gcmVwcmVzZW50IHVzZWZ1bCBRQyBpbmZvcm1hdGlvbgoKICArIFJlYWQgaXMgdW5tYXBwZWQKICArIFJlYWQgaXMgcGFpcmVkIC8gdW5wYWlyZWQKICArIFJlYWQgZmFpbGVkIFFDCiAgKyBSZWFkIGlzIGEgUENSIGR1cGxpY2F0ZSAoc2VlIGxhdGVyKQoKVGhlIGNvbWJpbmF0aW9uIG9mIGFueSBvZiB0aGVzZSBwcm9wZXJ0aWVzIGlzIHVzZWQgdG8gZGVyaXZlIGEgbnVtZXJpYyB2YWx1ZS4gRm9yIGluc3RhbmNlLCBhIHBhcnRpY3VsYXIgcmVhZCBtaWdodCBoYXZlIGEgZmxhZyBvZiAxNjMKCiMjIyBEZXJpdmF0aW9uCgpUaGVyZSBpcyBhIHNldCBvZiBwcm9wZXJ0aWVzIHRoYXQgYSByZWFkIGNhbiBwb3NzZXNzLiBJZiBhIHBhcnRpY3VsYXIgcHJvcGVydHkgaXMgb2JzZXJ2ZWQsIGEgY29ycmVzcG9uZGluZyBwb3dlciBvZiAyIGlzIGFkZGVkIG11bHRpcGxpZWQgYnkgMS4gVGhlIGZpbmFsIHZhbHVlIGlzIGRlcml2ZWQgYnkgc3VtbWluZyBhbGwgdGhlIHBvd2VycyBvZiAyLgoKCmBgYAogCVJlYWRIYXNQcm9wZXJ0eSAJQmluYXJ5IAlNdWx0aXBseUJ5CmlzUGFpcmVkIAlUUlVFIAkxIAkxCmlzUHJvcGVyUGFpciAJVFJVRSAJMSAJMgppc1VubWFwcGVkUXVlcnkgCUZBTFNFIAkwIAk0Cmhhc1VubWFwcGVkTWF0ZSAJRkFMU0UgCTAgCTgKaXNNaW51c1N0cmFuZCAJRkFMU0UgCTAgCTE2CmlzTWF0ZU1pbnVzU3RyYW5kIAlUUlVFIAkxIAkzMgppc0ZpcnN0TWF0ZVJlYWQgCUZBTFNFIAkwIAk2NAppc1NlY29uZE1hdGVSZWFkIAlUUlVFIAkxIAkxMjgKaXNTZWNvbmRhcnlBbGlnbm1lbnQgCUZBTFNFIAkwIAkyNTYKaXNOb3RQYXNzaW5nUXVhbGl0eUNvbnRyb2xzIAlGQUxTRSAJMCAJNTEyCmlzRHVwbGljYXRlIAlGQUxTRSAJMCAJMTAyNAoKYGBgClZhbHVlIG9mIGZsYWcgaXMgZ2l2ZW4gYnkgCmBgYAoxeDEgKyAxeDIgKyAweDQgKyAweDggKyAweDE2ICsgMXgzMiArIDB4NjQgKyAxeDEyOCArIDB4MjU2ICsgMHg1MTIgKyAweDEwMjQgPSAxNjMKYGBgCgpTZWUgYWxzbwoKLSBodHRwczovL2Jyb2FkaW5zdGl0dXRlLmdpdGh1Yi5pby9waWNhcmQvZXhwbGFpbi1mbGFncy5odG1sCgojIyMgSGF2ZSBhIENJR0FSIQoKClRoZSAqKipDSUdBUioqKiAoKipDKipvbXBhY3QgKipJKipkaW9zeW5jcmF0aWMgKipHKiphcHBlZCAqKkFsaWdubWVudCoqICoqUioqZXBvcnQpIHN0cmluZyBpcyBhIHdheSBvZiBlbmNvZGluZyB0aGUgbWF0Y2ggYmV0d2VlbiBhIGdpdmVuIHNlcXVlbmNlIGFuZCB0aGUgcG9zaXRpb24gaXQgaGFzIGJlZW4gYXNzaWduZWQgaW4gdGhlIGdlbm9tZS4gSXQgaXMgY29tcHJpc2VkIGJ5IGEgc2VyaWVzIG9mIGxldHRlcnMgYW5kIG51bWJlcnMgdG8gaW5kaWNhdGUgaG93IG1hbnkgY29uc2VjdXRpdmUgYmFzZXMgaGF2ZSB0aGF0IG1hcHBpbmcuCgoKIAogQ29kZSAgfCBEZXNjcmlwdGlvbgotLS0tLS0tLS0tLS0tIHwgLS0tLS0tLS0tLS0tLQpNICB8IGFsaWdubWVudCBtYXRjaApJICB8IGluc2VydGlvbgpEICB8IGRlbGV0aW9uCk4gIHwgc2tpcHBlZApTICB8IHNvZnQtY2xpcHBpbmcKSCAgfCBoYXJkLWNsaXBwaW5nCgoKZS5nLgoKLSBgMTAxTWAKICAgICsgMTAxIGJhc2VzIG1hdGNoaW5nIHRoZSByZWZlcmVuY2UKLSBgMVMxMDBNYAogICAgKyAxIHNvZnQtY2xpcHBlZCByZWFkIGZvbGxvd2VkIGJ5IDEwMCBtYXRjaGVzCi0gYDE1TTg3TjcwTTkwTjE2TWAKICAgICsgMTUgbWF0Y2hlcyBmb2xsb3dpbmcgYnkgODcgYmFzZXMgc2tpcHBlZCBmb2xsb3dlZCBieSA3MCBtYXRjaGVzIGV0Yy4KCiMjIyBgc2FtYCBvciBgYmFtP2AKCkFsaWdubWVudCBhbGdvcml0aG1zIHN1Y2ggYXMgYEhJU0FUMmAgdGVuZCB0byBwcm9kdWNlIGEgYHNhbWAgZmlsZSBhcyB0aGVpciByYXcgb3V0cHV0LCB3aGVyZWFzIHdlIHVzdWFsbHkgYW5hbHlzZSBhIGAuYmFtYCBmaWxlLiBUaGUgY29udGVudHMgb2YgYm90aCBmaWxlcyBhcmUgKmV4YWN0bHkgdGhlIHNhbWUqLiBXaGVyZWFzIGEgYHNhbWAgZmlsZSBpcyBkZXNpZ25lZCB0byBiZSAqaHVtYW4tcmVhZGFibGUqLCBhIGBiYW1gIGZpbGUgY2FuIGJlIHByb2Nlc3NlZCAqbW9yZSBlZmZpY2llbnRseSBieSBhIGNvbXB1dGVyKiBhcyBpdCBpcyBjb21wcmVzc2VkIGFuZCBpbmRleGVkLiAKClRoZSByZWFkcyBpbiBhIGBzYW1gIGZpbGUgdGVuZCB0byBiZSBhcnJhbmdlZCBpbiB0aGUgb3JkZXIgdGhhdCB0aGV5IHdlcmUgZ2VuZXJhdGVkIGJ5IHRoZSBzZXF1ZW5jZXIuIE9uIHRoZSBvdGhlciBoYW5kLCB0aGUgYGJhbWAgZmlsZSB0aGF0IHlvdSBzZWUgaW4gR2FsYXh5IGhhcyBiZWVuIHNvcnRlZCBhY2NvcmRpbmcgdG8gdGhlIHBvc2l0aW9uIHRoYXQgdGhlIHJlYWRzIG1hcC4gSWYgeW91IHJ1biB5b3VyIG93biBhbGlnbm1lbnRzIHVzaW5nIGNvbW1hbmQgbGluZSBzb2Z0d2FyZSwgeW91IHdpbGwgbmVlZCB0byB1c2UgYSB0b29sIHRvICpzb3J0IGFuZCBpbmRleCogdGhlIGRhdGEgYmVmb3JlIGFuYWx5c2lzLgoKLS0tLS0KCiMjIFF1YWxpdHkgYXNzZXNzbWVudCBvZiB0aGUgYWxpZ25lZCByZWFkcwoKKnNhbXRvb2xzKiB3aWxsIGNhbGN1bGF0ZSBRQyBzdGF0aXN0aWNzIGZvciBhIHNldCBvZiBhbGlnbmVkIHJlYWRzIGluICpiYW0qIGZvcm1hdAoKPGRpdiBjbGFzcz0iaW5mb3JtYXRpb24iPgoqU0FNL0JBTSAtPiBTYW10b29scyBzdGF0cyoKPC9kaXY+CgpJZiB5b3UgdmlldyB0aGUgb3V0cHV0IHlvdSB3aWxsIHNlZSB0aGF0IGl0IGlzIG5vdCB2ZXJ5IGVhc3kgdG8gaW50ZXJwcmV0LiAKPGRpdiBjbGFzcz0iaW5mb3JtYXRpb24iPgoqRkFTVFEgUXVhbGl0eSBDb250cm9sKiAtPiAqTXVsdGlxYyoKCm1ha2Ugc3VyZSAqKldoaWNoIHRvb2wgd2FzIHVzZWQgdG8gZ2VuZXJhdGUgbG9ncyoqIGlzIHNldCB0byAqKlNhbXRvb2xzKiogYW5kIHNlbGVjdCB0aGUgU2FtdG9vbHMgc3RhdHMuLi4uIGZpbGVzIHRoYXQgd2VyZSBwcm9kdWNlZCBpbiB0aGUgcHJldmlvdXMgc3RlcAo8L2Rpdj4KCgojIyBTZWN0aW9uIDQuIFF1YW50aWZpY2F0aW9uIChDb3VudGluZyByZWFkcyBpbiBmZWF0dXJlcykKCkluIG9yZGVyIHRvIHRlc3QgZm9yIGRpZmZlcmVudGlhbCBleHByZXNzaW9uLCB3ZSBuZWVkIHRvIGNvdW50IHVwIGhvdyBtYW55IHRpbWVzIGVhY2ggImZlYXR1cmUiIGlzIG9ic2VydmVkIGluIGVhY2ggc2FtcGxlLiBUaGUgZ29hbCBvZiBzdWNoIG9wZXJhdGlvbnMgaXMgdG8gcHJvZHVjZSBhICpjb3VudCB0YWJsZSogc3VjaCBhcyB0aGF0IHNob3duIGJlbG93LiBXZSBjYW4gdGhlbiBhcHBseSBzdGF0aXN0aWNhbCB0ZXN0cyB0byB0aGVzZSBkYXRhCgohW10obWVkaWEvY291bnRzLnBuZykKCkhUU2VxLWNvdW50IGNyZWF0ZXMgYSBjb3VudCBtYXRyaXggdXNpbmcgdGhlIG51bWJlciBvZiB0aGUgcmVhZHMgZnJvbSBlYWNoIGJhbQpmaWxlIHRoYXQgbWFwIHRvIHRoZSBnZW5vbWljIGZlYXR1cmVzLiBGb3IgZWFjaCBmZWF0dXJlIChhCmdlbmUgZm9yIGV4YW1wbGUpIGEgY291bnQgbWF0cml4IHNob3dzIGhvdyBtYW55IHJlYWRzIHdlcmUgbWFwcGVkIHRvIHRoaXMKZmVhdHVyZS4KClZhcmlvdXMgcnVsZXMgY2FuIGJlIHVzZWQgdG8gYXNzaWduIGNvdW50cyB0byBmZWF0dXJlcwoKIVtdKG1lZGlhL2h0c2VxLnBuZykKClRvIG9idGFpbiB0aGUgY29vcmRpbmF0ZXMgb2YgZWFjaCBnZW5lLCB3ZSBjYW4gdXNlIHRoZSBVQ1NDIGdlbm9tZSBicm93c2VyIHdoaWNoIGlzIGludGVncmF0ZWQgaW50byBHYWxheHkuCgojIyMgT2J0YWluaW5nIGdlbmUgY29vcmRpbmF0ZXMKCgoKPGRpdiBjbGFzcz0iaW5mb3JtYXRpb24iPgoKKipHZXQgRGF0YSoqIC0+ICoqVUNTQyBNYWluKiogdGFibGUgYnJvd3NlcgoKPC9kaXY+CgoKIVtdKG1lZGlhL3Vjc2NfYnJvd3Nlci5wbmcpCgpTZWxlY3RpbmcgdGhlICoqVUNTQyBNYWluKiogdG9vbCBmcm9tIEdhbGF4eSB3aWxsIHRha2UgeW91IHRvIHRoZSBVQ1NDIHRhYmxlIGJyb3dzZXIuIEZyb20gaGVyZSB3ZSBjYW4gZXh0cmFjdCBnZW5lIGNvb3JkaW5hdGVzIGZvciBvdXIgZ2Vub21lIG9mIGludGVyZXN0IChgbW0xMGApIGluIGBndGZgIGZvcm1hdCBmb3IgcHJvY2Vzc2luZyB3aXRoIGdhbGF4eS4KCi0gU2V0ICpjbGFkZSogdG8gKipNYW1tYWwqKgotIFNldCAqZ2Vub21lKiB0byAqKk1vdXNlKioKLSAqYXNzZW1ibHkqICoqRGVjLjIwMTEgKEdSQ20zOC9tbTEwKSoqCi0gKmdyb3VwKiAqKkdlbmVzIGFuZCBHZW5lIFByZWRpY3Rpb24qKgotICp0cmFjayogKipOQ0JJIFJlZlNlcSoqCi0gKnRhYmxlKiAqKlVDU0MgUmVmU2VxIChyZWZHZW5lKSoqCi0gKnJlZ2lvbiogKipnZW5vbWUqKgotICpvdXRwdXQgZm9ybWF0KiAqKkdURiAtIGdlbmUgdHJhbnNmZXIgZm9ybWF0IChsaW1pdGVkKSoqIGFuZCAqc2VuZCBvdXRwdXQgdG8qICoqR2FsYXh5KioKCkNsaWNrICpnZXQgb3V0cHV0KiBhbmQgKnNlbmQgcXVlcnkgdG8gR2FsYXh5KiB0byBiZSByZXR1cm5lZCB0byBHYWxheHkuIEEgbmV3IGpvYiB3aWxsIGJlIHN1Ym1pdHRlZCB0byByZXRyaWV2ZSB0aGUgY29vcmRpbmF0ZXMgZnJvbSBVQ1NDCgoKCjxkaXYgY2xhc3M9ImluZm9ybWF0aW9uIj4KKipSTkEgQW5hbHlzaXMgPiBodHNlcS1jb3VudCoqCjwvZGl2PgoKMS4gIFVzZSBIVFNlcS1jb3VudCB0byBjb3VudCB0aGUgbnVtYmVyIG9mIHJlYWRzIGZvciBlYWNoIGZlYXR1cmUuICAKICAgIEluIHRoZSBsZWZ0IHRvb2wgcGFuZWwgbWVudSwgdW5kZXIgTkdTIEFuYWx5c2lzLCBzZWxlY3QKICAgICoqTkdTIEFuYWx5c2lzID4gaHRzZXEtY291bnQqKiBhbmQgc2V0IHRoZSBwYXJhbWV0ZXJzIGFzIGZvbGxvd3M6ICAKICAgIC0gKipBbGlnbmVkIFNBTS9CQU0gZmlsZSoqICAKICAgICAgKFNlbGVjdCBvbmUgb2YgZm91ciBiYW0gZmlsZXMsIG9yIGFsbCBmb3VyIHVzaW5nIHRoZSBtdWx0aXBsZSBkYXRhc2V0cyBvcHRpb24pCiAgICAtICoqR0ZGIGZpbGUqKiBVQ1NDIE1haW4gb24gTW91c2U6bmNiaVJlZlNlcSAoZ2Vub21lKQogICAgLSBVc2UgZGVmYXVsdHMgZm9yIHRoZSBvdGhlciBmaWVsZHMKICAgIC0gRXhlY3V0ZQoyLiAgUmVwZWF0IGZvciB0aGUgcmVtYWluaW5nIGJhbSBmaWxlcyBpZiBydW5uaW5nIG9uIGVhY2ggYmFtIHNlcGFyYXRlbHkuCjMuICBUbyBtYWtlIHRoaW5ncyBlYXNpZXIgdG8gdHJhY2ssIHJlbmFtZSB0aGUgaHQtc2VxIG91dHB1dCBmb3IgZWFjaCBzYW1wbGUgdG8gY29udGFpbiB0aGUgY29ycmVzcG9uZGluZyBzYW1wbGUgbmFtZSAoZS5nLiBTUlIxNTUyNDQ0Lmh0c2VxKS4gKipEbyBub3QgcmVuYW1lIHRoZSBvdXRwdXRzIHRoYXQgaGF2ZSAiKG5vIGZlYXR1cmUpIiBpbiB0aGVpciBuYW1lKioKCjxkaXYgY2xhc3M9Indhcm5pbmciPgoKV2hlbiB5b3UgYXJlIHJldHVybmVkIHRvIEdhbGF4eSBmcm9tIFVDU0MgaXQgbWlnaHQgbG9vayBsaWtlIHlvdSBoYXZlIGxvc3QgYWxsIHRoIGZpbGVzIGluIHlvdXIgYW5hbHlzaXMgYW5kIGFyZSBubyBsb25nZXIgbG9nZ2VkIGluLiAKClRvIHNvbHZlIHRoaXMsIGxvZyBiYWNrIGluIGFuZCBjaG9vc2UgdGhlICoqVmlldyBhbGwgaGlzdG9yaWVzKiogb3B0aW9uIHVuZGVyIHRoZSBIaXN0b3J5IHBhbmVsLgoKIVtdKG1lZGlhL2dhbGF4eV9oaXN0b3J5LlBORykKClRoZXJlIHNob3VsZCBiZSB0d28gImhpc3RvcmllcyI7IG9uZSBjb250YWluaW5nIGFsbCB0aGUgb3V0cHV0cyB5b3UgZ2VuZXJhdGVkIGJlZm9yZSBhY2Nlc3NpbmcgVUNTQywgYW5kIG9uZSBjb250YWluaW5nIHRoZSBVQ1NDIG91dHB1dC4gQWxsIHRoaXMgcG9pbnQgeW91IGNhbiBzd2l0Y2ggYmFjayB0byB5b3VyIHByZXZpb3VzIGhpc3RvcnksIGFuZCBkcmFnIHRoZSBib3ggY29udGFpbmluZyB0aGUgVUNTQyBvdXB1dCB0byB0aGlzIGhpc3RvcnkKCiFbXShtZWRpYS9zd2l0Y2hfaGlzdG9yaWVzLlBORykKCjwvZGl2PgoKCiMjIyBGdXJ0aGVyIFFDIG9uIHRoZSBhbGlnbmVkIHJlYWRzCgpBZGRpdGlvbmFsIFFDIG9mIHRoZSBhbGlnbmVkIHJlYWRzIGNhbiBiZSBvYnRhaW5lZCB3aXRoIHRoZSBRdWFsaW1hcCB0b29sLiBUaGlzIGFsc28gdXNlcyBpbmZvcm1hdGlvbiBmcm9tIHRoZSBnZW5vbWUgdHJhbnNjcmlwdCBmaWxlIHRvIGNhbGN1bGF0ZSBob3cgbWFueSByZWFkcyBhcmUgY291bnRlZCBpbiBleG9uaWMsIGludHJvbmljIGFuZCBpbnRlcmdlbmljIHJlZ2lvbnMuIEZvciBSTkEtc2VxIHRoaXMgcGVyY2VudGFnZSBzaG91bGQgYmUgKmhpZ2gqOyBhdCBsZWFzdCA4MCB0byA5MCUuCgo8ZGl2IGNsYXNzPSJpbmZvcm1hdGlvbiI+CioqUk5BLVNlcSA+IFF1YWxpbWFwIFJOQS1TZXEgUUMqKgo8L2Rpdj4KCiMjIyBDcmVhdGUgYSBjb3VudCBtYXRyaXgKClRoZSBodHNlcSB0b29sIGlzIGRlc2lnbmVkIHRvIHByb2R1Y2UgYSBzZXBhcmF0ZSB0YWJsZSBvZiBjb3VudHMgZm9yIGVhY2ggc2FtcGxlLiBUaGlzIGlzIG5vdCBwYXJ0aWN1bGFybHkgdXNlZnVsIGZvciBvdGhlciB0b29scyBzdWNoIGFzIERlZ3VzdCAoc2VlIG5leHQgc2VjdGlvbikgd2hpY2ggcmVxdWlyZSB0aGUgY291bnRzIHRvIGJlIHByZXNlbnRlZCBpbiBhIGRhdGEgbWF0cml4IHdoZXJlIGVhY2ggcm93IGlzIGEgZ2VuZSBhbmQgZWFjaCBjb2x1bW4gaXMgYSBwYXJ0aWN1bGFyIHNhbXBsZSBpbiB0aGUgZGF0YXNldC4KCjxkaXYgY2xhc3M9ImluZm9ybWF0aW9uIj4KKkNvbGxlY3Rpb24gT3BlcmF0aW9ucyAtPiBDb2x1bW4gSm9pbiogb24gQ29sbGVjdGlvbnMKPC9kaXY+CgotIEluIHRoZSAqVGFidWxhciBGaWxlcyogc2VjdGlvbiwgc2VsZWN0IHRoZSBgaHQtc2VxYCBjb3VudCBmaWxlcyBmcm9tIHlvdXIgaGlzdG9yeSAqU1JSMTU1MjQ0NC5odHNlcSosICpTUlIxNTUyNDUwKiwgZXRjLi4uIEhvbGRpbmcgdGhlIENUUkwga2V5IGFsbG93cyBtdWx0aXBsZSBmaWxlcyB0byBiZSBzZWxlY3RlZAotIEtlZXAgKklkZW50aWZpZXIgY29sdW1uKiBhcyBgMWAKClRoZSBvdXRwdXQgc2hvdWxkIGxvb2sgc29tZXRoaW5nIGxpa2UgdGhpcy4uLgohW10obWVkaWEvY291bnRfbWF0cml4LnBuZykKCi0gRG93bmxvYWQgdG8geW91ciBjb21wdXRlcgoKCioqWW91IGFyZSBub3cgcmVhZHkgdG8gZm9sbG93IHRoZSBuZXh0IHR1dG9yaWFsIG9uIFtEaWZmZXJlbnRpYWwgRXhwcmVzc2lvbl0oMDItZGlmZmVyZW50aWFsLWV4cHJlc3Npb24ubmIuaHRtbCkqKgoKIyMgQWRkaW5nIGV4dHJhIGFubm90YXRpb24gdG8gcmVzdWx0cwoKVGhlIGNvdW50IG1hdHJpeCBoYXMgKlJlZlNlcSBJRCogaW4gdGhlIGZpcnN0IGNvbHVtbiwgYnV0IG5vIG90aGVyIHVzZWZ1bCBhbm5vdGF0aW9uLiBTb21ldGltZXMgd2UgbWlnaHQgd2FudCBvdGhlciBJRHMgdG8gYmUgYWRkZWQgaW4gb3JkZXIgdG8gaW50ZXJwcmV0IG91ciByZXN1bHRzLiBJbmRpdmlkdWFsIHF1ZXJpZXMgY2FuIGJlIG1hZGUgb25saW5lIChlLmcuIEVuc2VtYmwsIGJpb21hcnQpIGJ1dCB0ZWRpb3VzIGZvciBsYXJnZSBudW1iZXJzIG9mIGdlbmVzLiBUaGUgR2FsYXh5IHRvb2wgKiphbm5vdGF0ZU15SURzKiogaXMgYSBzaW1wbGUgdG9vbCBmb3IgYW5ub3RhdGluZyBhIGZpbGUgY29udGFpbmluZyBhIGNvbHVtbiBvZiBJRHMuCgo8ZGl2IGNsYXNzPSJpbmZvcm1hdGlvbiI+CioqQW5ub3RhdGlvbioqIC0+ICoqYW5ub3RhdGVNeUlEcyoqCjwvZGl2PgoKLSBGaWxlIHdpdGggSURzOiAqQ29sdW1uIEpvaW4gb24gRGF0YS4uLioKLSBPcmdhbmlzbTogTW91c2UKLSBJRCBUeXBlOiBSZWZTZXEKLSBLZWVwIGFsbCBvdGhlciBkZWZhdWx0cwoKVGhpcyBzaG91bGQgcHJvZHVjZSBhbiBvdXRwdXQgdGFibGUgY29udGFpbmluZyB0aGUgb3JpZ2luYWwgSUQsIGFuZCB0aGUgZXF1aXZsZW50IEdlbmUgU3ltYm9sLCBFbnNlbWJsIElELgoKVGhlIG91dHB1dCBjYW4gdGhlbiBiZSAqam9pbmVkKiB0byB0aGUgb3JpZ2luYWwgcmVzdWx0cyBmaWxlIHRvIHByb2R1Y2UgYSBtb3JlIGRldGFpbGVkIHJlc3VsdAoKPGRpdiBjbGFzcz0iaW5mb3JtYXRpb24iPgoqKlRleHQgTWFuaXB1bGF0aW9uKiogLT4gKipKb2luIHR3byBmaWxlcyoqCjwvZGl2PgoKLSAxc3QgZmlsZTogKkNvbHVtbiBKb2luIG9uIGRhdGEuLi4uKgotIENvbHVtbiB0byB1c2UgZnJvbSAxc3QgZmlsZTogQ29sdW1uIDEKLSAybmQgZmlsZTogcmVzdWx0IGZyb20gKmFubm90YXRlTXlJRHMgb24gZGF0YS4uLioKLSBDb2x1bW4gdG8gdXNlIGZyb20gMm5kIGZpbGU6IENvbHVtbiAxCgo8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC1pbmZvIj4KVGhlIHN0ZXAgb2YgYW5ub3RhdGluZyB5b3VyIHJlc3VsdHMgbWF5IG5lZWQgbW9kaWZ5aW5nIChvciBtYXkgbm90IGJlIG5lY2Vzc2FyeSkgZGVwZW5kaW5nIG9uIHdoYXQgSURzIHlvdSBoYXZlIHVzZWQgaW4gdGhlIGNvdW50aW5nLiBNYWtlIHN1cmUgeW91IGNob29zZSB0aGUgb3B0aW9ucyBjYXJlZnVsbHkgd2hlbiB1c2luZyB0aGlzIHRvb2wuCjwvZGl2PgoKIyBFeGVyY2lzZSBiZWZvcmUgdGhlIG5leHQgc2Vzc2lvbgoKPGRpdiBjbGFzcz0iZXhlcmNpc2UiPgoKSW4gdGhlIGZvbGRlciB5b3UgZG93bmxvYWRlZCBmcm9tIGdvb2dsZSBkcml2ZSwgeW91IGhhdmUgdGhlIGZhc3RxIGZpbGVzIGZvciBhbGwgb3RoZXIgc2FtcGxlcyBpbiB0aGUgZGF0YXNldC4gUmVwZWF0IHRoZSB3b3JrZmxvdyBzdGVwcyBmb3IgdGhlc2UgcmVtYWluaW5nIGZpbGVzCgotIFFDIHdpdGggZmFzdFFDCi0gQWxpZ25tZW50IGFnYWluc3QgdGhlIG1tMTAgZ2Vub21lIHdpdGggSGlTYXQyCi0gQ291bnRpbmcgd2l0aCBodHNlcQoKQ3JlYXRlIGEgY29tYmluZWQgUUMgcmVwb3J0IGFuZCBjb21iaW5lZCBjb3VudCBtYXRyaXggKipmb3IgYWxsIHNhbXBsZXMqKi4KCjwvZGl2PgoKIyBPcHRpb25hbAoKPGZvbnQgc2l6ZT0iNCI+KioqV2Ugd2lsbCBub3QgZ28gdGhyb3VnaCB0aGUgZm9sbG93aW5nIHNlY3Rpb24gaW4gdGhlIHdvcmtzaG9wLCBidXQgZmVlbCBmcmVlIHRvIHdvcmsgdGhyb3VnaCBpbiB5b3VyIG93biB0aW1lKioqPC9mb250PgoKIyAoT3B0aW9uYWwpIEFzc2Vzc2luZyBEaWZmZXJlbnRpYWwgRXhwcmVzc2lvbiB3aXRoICpERVNlcTIqCgpUaGVyZSBhcmUgc2V2ZXJhbCBzZW5zaWJsZSBhbmQgcmVzcGVjdGVkIGNob2ljZXMgZm9yIHBlcmZvcm1pbmcgYSBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBhbmFseXNpcyBvbiBSTkEtc2VxIGRhdGEuIEhlcmUsIHdlICB3aWxsIGlsbHVzdHJhdGUgdGhlIGBERVNlcTJgIG1ldGhvZCBiZWNhdXNlIGl0IGlzIHJlYWRpbHkgYXZhaWxhYmxlIHRocm91Z2ggR2FsYXh5LiAKCjxkaXYgY2xhc3M9ImluZm9ybWF0aW9uIj4KCioqTkdTOiBSTkEgQW5hbHlzaXMgPiBERVNlcTIqKgo8L2Rpdj4KCkluIHRoZSBHYWxheHkgdG9vbCBwYW5lbCwgdW5kZXIgTkdTIEFuYWx5c2lzLCBzZWxlY3QKKipOR1M6IFJOQSBBbmFseXNpcyA+IERFU2VxMioqIGFuZCBzZXQgdGhlIHBhcmFtZXRlcnMgYXMgZm9sbG93czoKCgotICoqMS4gRmFjdG9yIGxldmVsKiogVmlyZ2luCi0gKipDb3VudCBmaWxlcyoqICAKICAgIC0gYFNSUjE1NTI0NDQuaHRzZXFgCiAgICAtIGBTUlIxNTUyNDUwLmh0c2VxYAotICoqMi4gRmFjdG9yIGxldmVsOioqIFByZWduYW50Ci0gKipTZWxlY3QgY29sdW1ucyBjb250YWluaW5nIGNvbnRyb2w6KiogIAogICAgLSBgU1JSMTU1MjQ1Mi5odHNlcWAKICAgIC0gYFNSUjE1NTI0NTMuaHRzZXFgCi0gRm9yICoqT3V0cHV0IG5vcm1hbGl6ZWQgY291bnRzIHRhYmxlKiogc2VsZWN0ICoqWWVzKioKLSBFeGVjdXRlCgojIyMjIDIuICBFeGFtaW5lIHRoZSBvdXRwdXRzIGZyb20gdGhlIHByZXZpb3VzIHN0ZXAKMS4gIEV4YW1pbmUgdGhlIGBEZVNlcTIgcmVzdWx0IGZpbGVgYnkKICAgIGNsaWNraW5nIG9uIHRoZSAqKmV5ZSBpY29uKiouCiAgICBUaGlzIGZpbGUgaXMgYSBsaXN0IG9mIGdlbmVzIHNvcnRlZCBieSBwLXZhbHVlIGZyb20gdXNpbmcgREVTZXEyIHRvCiAgICBwZXJmb3JtIGRpZmZlcmVudGlhbCBleHByZXNzaW9uIGFuYWx5c2lzLgoyLiAgRXhhbWluZSB0aGUgYERlU2VxMiBwbG90c2AgZmlsZS4gVGhpcyBmaWxlIGhhcyBzb21lCiAgICBwbG90cyBmcm9tIHJ1bm5pbmcgREVTZXEyLCBpbmNsdWRpbmcgW1BDQV0oaHR0cDovL3NldG9zYS5pby9ldi9wcmluY2lwYWwtY29tcG9uZW50LWFuYWx5c2lzLykgYW5kIGNsdXN0ZXJpbmcuCiAgICAKCmBERVNlcTJgIHJlcG9ydHMsIGZvciBlYWNoIGdlbmUgdGhhdCBpcyBiZWluZyB0ZXN0ZWQsIHNvbWUgaW5mb3JtYXRpb24gdGhhdCB3ZSBjYW4gdXNlIHRvIGRldGVybWluZSBpZiB0aGUgZ2VuZSBpcyBkaWZmZXJlbnQgYmV0d2VlbiBvdXIgY29uZGl0aW9ucyBvZiBpbnRlcmVzdC4gV2Ugd2lsbCBkbyBtb3JlIGV4cGxvcmF0aW9uIG9mIGRpZmZlcmVudGlhbCBleHByZXNzaW9uIGFuYWx5c2lzIGluIHRoZSBuZXh0IHNlY3Rpb24gdXNpbmcgYSB0b29sIHRoYXQgaXMgbm90IGluY2x1ZGVkIGluIEdhbGF4eS4gRm9yIG5vdyB3ZSB3aWxsIGNvbmNlbnRyYXRlIG9uIHRoZSB0YXNrIG9uIGZpbmRpbmcgb3V0IHdoaWNoIGdlbmVzIGhhdmUgKnN1ZmZpY2llbnQgc3RhdGlzdGljYWwgZXZpZGVuY2UqIGZvciBiZWluZyBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgYmV0d2VlbiBvdXIgdHdvIGNvbmRpdGlvbnMuCgoKCiMjIChPcGlvbmFsKSBWaXN1YWxpc2UgdGhlIGFsaWduZWQgcmVhZHMgd2l0aCBJR1YKCkRvd25sb2FkIHRoZSBiYW0gZmlsZXMgeW91IGhhdmUgY3JlYXRlZCBpbiB0aGUgcHJldmlvdXMgc3RlcCBieSBjbGlja2luZyB0aGUgZGlzayBpY29uIG9uIHRoZSByaWdodC1oYW5kIHBhbmVsLiBNYWtlIHN1cmUgdG8gY2xpY2sgYm90aCB0aGUgKipEb3dubG9hZCBkYXRhc2V0KiogYW5kICoqRG93bmxvYWQgaW5kZXgqKiBidXR0b25zLiBXZSB3aWxsIG5vdyB2aXN1YWxpc2UgdGhlIGFsaWdubWVudHMgdXNpbmcgdGhlIEludGVncmF0aXZlIEdlbm9taWNzIFZpZXdlciAoSUdWKS4KCjxpbWcgc3JjPSJtZWRpYS9kb3dubG9hZF9iYW0ucG5nIj4KCgojIyMgSW50cm9kdWNpbmcgdGhlIElHViBCcm93c2VyCgohW10obWVkaWEvaWd2LnBuZykKCldoaWxzdCB0b29scyBsaWtlIFIgYXJlIHZlcnkgcG93ZXJmdWwgYW5kIGFsbG93IHlvdSB0byBwZXJmb3JtIHN0YXRpc3RpY2FsIGFuYWx5c2VzIGFuZCB0ZXN0IGh5cG90aGVzZXMsIHRoZXJlIGlzIG5vIHN1YnN0aXR1dGUgZm9yICoqKmxvb2tpbmcgYXQgdGhlIGRhdGEqKiouIEEgdHJhaW5lZC1leWUgY2FuIHF1aXRlIHF1aWNrbHkgZ2V0IGEgc2Vuc2Ugb2YgdGhlIGRhdGEgcXVhbGl0eSBiZWZvcmUgYW55IGNvbXB1dGF0aW9uYWwgYW5hbHlzZXMgaGF2ZSBiZWVuIHJ1bi4gRnV0aGVybW9yZSwgYXMgdGhlIHBlcnNvbiByZXF1ZXN0aW5nIHRoZSBzZXF1ZW5jaW5nLCB5b3UgcHJvYmFibHkga25vdyBhIGxvdCBhYm91dCB0aGUgYmlvbG9naWNhbCBjb250ZXh0IG9mIHRoZSBzYW1wbGVzIGFuZCB3aGF0IHRvIGV4cGVjdC4gCgotIElHViBoYXMgYmVlbiBkZXZlbG9wZWQgYnkgdGhlIEJyb2FkIEluc3RpdHV0ZSBhbmQgaXMgYWJsZSB0byBkaXNwbGF5IG1vc3Qga2luZHMgb2YgZ2Vub21pYyBkYXRhCiAgICArIGV4cHJlc3Npb24KICAgICsgQ2hJUAogICAgKyB3aG9sZS1nZW5vbWUgcmVzZXF1ZW5jaW5nCiAgICArIHNoUk5BCi0gSXQgaXMgYSAqSmF2YSogZGVza3RvcCBhcHBsaWNhdGlvbiBhbmQgY2FuIGJlIHJ1biBlaXRoZXIgbG9jYWxseSBvZiBmcm9tIHRoZSBCcm9hZCB3ZWJzaXRlCi0gVG8gcnVuIElHViB5b3Vyc2VsZiB5b3Ugd2lsbCBuZWVkIHRvIGFncmVlIHRvIHRoZSBsaWNlbnNlIGFuZCBbZG93bmxvYWQgdGhlIHZlcnNpb24gZm9yIHlvdXIgT1NdKGh0dHA6Ly93d3cuYnJvYWRpbnN0aXR1dGUub3JnL3NvZnR3YXJlL2lndi9kb3dubG9hZCkKCjxkaXYgY2xhc3M9Indhcm5pbmciPgpJZiB5b3UgaGF2ZSBwcm9ibGVtcyBydW5uaW5nIElHViwgeW91IG1heSBuZWVkIHRvIGRvd25sb2FkIGFuIHVwZGF0ZWQgdmVyc2lvbiBvZiBKYXZhCgpodHRwczovL2phdmEuY29tL2Rvd25sb2FkCgo8L2Rpdj4KCiMjIyBBIHF1aWNrIHRvdXIgb2YgSUdWCkZvciBtb3JlIGRldGFpbHMKCi0gRnVsbCBzZXQgb2Ygc2xpZGVzIGZyb20gW01SQyBDbGluaWNhbCBTY2llbmNlcyBDZW50cmVdKGh0dHA6Ly9tcmNjc2MuZ2l0aHViLmlvL0lHVl9jb3Vyc2UvaWd2Lmh0bWwjLykKLSBJR1YgdHV0b3JpYWwgZnJvbSB0aGUgW0dyaWZmdGggbGFiIC0gV2FzaFVdKGh0dHBzOi8vZ2l0aHViLmNvbS9ncmlmZml0aGxhYi9ybmFzZXFfdHV0b3JpYWwvd2lraS9JR1YtVHV0b3JpYWwpCgohW10obWVkaWEvSUdWMi5wbmcpCgoxKSBTYW1wbGUgaW5mb3JtYXRpb24gcGFuZWwKICAgIC0gSW5mb3JtYXRpb24gYWJvdXQgc2FtcGxlcyB5b3UgaGF2ZSBsb2FkZWQKICAgIC0gZS5nLiBTYW1wbGUgSUQsIEdlbmRlciwgQWdlLCBUdW1vdXIgLyBOb3JtYWwKICAgIAoyKSBHZW5vbWUgTmF2aWdhdGlvbiBwYW5lbAogICAgLSBKdW1wIHRvIGEgZ2Vub21pYyByZWdpb24gaW4gYENocjpTdGFydC1FbmRgIGZvcm1hdAogICAgLSBKdW1wIHRvIGEgZ2VuZSBzeW1ib2wgb2YgaW50ZXJlc3QKICAgIAozKSBEYXRhIHBhbmVsCiAgICAtIFlvdXIgc2VxdWVuY2luZyByZWFkcyB3aWxsIGJlIGRpc3BsYXllZCBoZXJlCiAgICAtIE9yIHdoYXRldmVyIGRhdGEgeW91IGhhdmUgbG9hZGVkCiAgICAgICAgKyBzZWUgaW5mb3JtYXRpb24gb24gW2FjY2VwdGVkIGZpbGUgZm9ybWF0c10oaHR0cDovL3d3dy5icm9hZGluc3RpdHV0ZS5vcmcvc29mdHdhcmUvaWd2L1JlY29tbWVuZGVkRmlsZUZvcm1hdHMpCgo0KSBBdHRyaWJ1dGUgcGFuZWwKICAgIC0gR2VuZSBsb2NhdGlvbnMKICAgIC0gR2Vub21lIHNlcXVlbmNlIChpZiB6b29tZWQtaW4gYXQgYXBwcm9wcmlhdGUgbGV2ZWwpCiAgICAtIFByb3RlaW5zCiAgICAKIyMjIEV4YW1wbGUKCkdvIHRvICoqKkZpbGUqKiogLT4gKioqTG9hZCBmcm9tIGZpbGUqKiogYW5kIHNlbGVjdCB0aGUgYWxpZ25lZCBgYmFtYCBmaWxlcyBmcm9tIGBISVNBVDJgLiBOb3RlIHRoYXQgdGhlIGluZGV4IGZpbGVzIGAuYmFpYCBuZWVkIHRvIGJlIHByZXNlbnQgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LiBIb3dldmVyLCB5b3Ugb25seSBuZWVkIHRvIGNsaWNrIG9uIHRoZSBgLmJhbWAKCjxkaXYgY2xhc3M9ImFsZXJ0IGFsZXJ0LWluZm8iPgpNYWtlIHN1cmUgdGhhdCB0aGUgZ2Vub21lIHNlbGVjdGVkIGlzIGBtbTEwYC4gVGhlIGRlZmF1bHQgd2lsIGJlIGh1bWFuIGhnMTkKPC9kaXY+CgotIFRoZSBibGFjayBkb3R0ZWQgdmVydGljYWwgbGluZXMgaW5kaWNhdGVzIHRoZSBjZW50cmUgb2YgdGhlIHZpZXcKLSBFYWNoIG9mIHRoZSBncmV5IHBvaW50ZWQgcmVjdGFuZ2xlcyByZXByZXNlbnRzIGEgc2VxdWVuY2luZyByZWFkcwogICAgKyB3aGV0aGVyIHRoZSBwb2ludGVkIGJpdCBpcyBvbiB0aGUgbGVmdCBvciByaWdodCBpbmRpY2F0ZXMgaWYgdGhlIHJlYWQgaXMgZm9yd2FyZCBvciByZXZlcnNlLgotIEEgY292ZXJhZ2UgdHJhY2sgaXMgYWxzbyBnZW5lcmF0ZWQKLSBZb3Ugc2hvdWxkIHNlZSB0aGUgcmVhZCB0aGF0IHdlIGRlc2NyaWJlZCBpbiBkZXRhaWwgaW4gdGhlIHByZXZpb3VzIHNlY3Rpb24gYnkgKmhvdmVyKmluZyBvdmVyIHRoZSByZWFkcyB0byBkaXNwbGF5IHRoZSBpbmZvcm1hdGlvbiBmcm9tIHRoZSBgLmJhbWAgZmlsZQoKVGhlIHZpZXcgaW4gSUdWIGlzIG5vdCBzdGF0aWMgYW5kIHdlIGNhbiBzY3JvbGwtYWxvbmcgdGhlIGdlbm9tZSBieSBob2xkaW5nLWRvd24gdGhlIGxlZnQgbW91c2UgaW4gdGhlIGRhdGEgcGFuZWwgYW5kIGRyYWdnaW5nIGxlZnQgYW5kIHJpZ2h0CgpJdCdzIHdvcnRoIG5vdGluZyB0aGF0IHRoZSBkaXNwbGF5IHNldHRpbmdzIG1heSBiZSBzaG93aW5nIGZld2VyIHJlYWRzIHRoYW4geW91IGhhdmUgKCpkb3duc2FtcGxpbmcqKSBpbiBvcmRlciB0byBjb25zZXJ2ZSBtZW1vcnkuIEFsc28sIHNvbWUgUUMtZmFpbCBvciBQQ1IgZHVwbGljYXRlcyBtYXkgYmUgZmlsdGVyZWQuCgpXZSBhbHNvIGhhdmUgc29tZSBvcHRpb25zIG9uIGhvdyB0byBkaXNwbGF5IHRoZSByZWFkcyB0aGVtc2VsdmVzLCB3aGljaCB3ZSBjYW4gYWNjY2VzcyBieSByaWdodC1jbGlja2luZyBvbiB0aGUgYmFtIHRyYWNrCgpTb3J0aW5nIGFsaWdubWVudHMgYnk6LQoKICAtIHN0YXJ0CiAgLSBzdHJhbmQKICAtIGJhc2UKICAtIG1hcHBpbmcgcXVhbGl0eQogIC0gaW5zZXJ0IHNpemUKICAKVGhlIHJlYWRzIHRoZW1zZWx2ZXMgY2FuIGFsc28gYmUgY29sb3VyZWQgYWNjb3JkaW5nIHRvCgogIC0gaW5zZXJ0IHNpemUKICAtIHJlYWQgc3RyYW5kCiAgLSBzYW1wbGUKCg==