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

The Degust part of this session is based on the tutorial Differential gene expression using Galaxy and Degust from Antibiotic Resistant Pathogens Initiative (ARPI)

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

Recap

Previous sections have illustrated how to

We will now use the published counts as the input for a differential expression analysis.

Differential expression

The term differential expression was first used to refer to the process of finding statistically significant genes from a microarray gene expression study.

Such methods were developed on the premise that microarray expression values are approximately normally-distributed when appropriately transformed (e.g. by using a log\(_2\) transformation) so that a modified version of the standard t-test can be used. The same test is applied to each gene under investigation yielding a test statistic, fold-change and p-value. Similar methods have been adapted to RNA-seq data to account for the fact that the data are count-based and do not follow a normal distribution.

Interactive exploration of the results with DEGUST

http://degust.erc.monash.edu/

Degust is a web tool that can analyse the counts files produced in the step above, to test for differential gene expression. It offers and interactive view of the differential expression results

The input file is a count matrix where each row is a measured gene, and each column is a different biological sample. Within the tool we can configure which samples belong to the different biological groups of interest.

Read counts have to be normalised first prior to differential expression testing. There are two main biases that need to be accounted for:-

  • size of gene
    • longer genes will have more reads assigned to them
  • library size
    • a sample that is sequenced to a higher depth will receive more reads

However, R-based methods such as edgeR (implemented in Degust) and DESeq2 have their own method of normalising counts. You will probably encounter other methods of normalising RNA-seq reads such as RPKM, CPM, TPM etc. This blog provides a nice explanation of the current thinking. As part of the Degust output, you have the option of downloading normalised counts in various formats. Some other online visualisation tools require normalised counts as input, so it is good to have these to-hand.

To make this a more-realistic example, we will use the published count matrix for this dataset. This was downloaded from the Gene Expression Omnibus (GEO) under the accession number GSE60450. Note that we have shortened the column headings and added gene symbols to help with visualisation and annotation

Download the counts from this link

Uploading the count matrix to Degust

  • From the main degust page, click Upload your counts file
  • Click on Browse
  • Select the location of the file GSE60450_Lactation-GenewiseCounts_rename_symbol.csv, and click Open.
  • Click Upload
  • A Configuration page will appear.

  • For Name type “GSE60450” (or whatever you want to call the analysis)
  • For Info columns select SYMBOL
  • Click Add condition
    • Referring to the experiment design (below), select the Basal samples and call the condition Basal
    • Repeat for the Luminal samples
  • Save the settings and then View the results
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

Overview of Degust sections

  • Top black panel with Configure settings at right.
  • Left: Conditions: Control and Treatment.
  • Left: Method selection for DGE. Select edgeR for your method
  • Top centre: Plots, with options at right.
  • When either of the expression plots are selected, a heatmap appears below.
  • A table of genes (or features); expression in treatment relative to control (Treatment column); and significance (FDR column).

(Not that the screenshots are for illustration purposes and taken from a different dataset to that being analysed in the tutorial)

MDS plot

This is a multidimensional scaling plot which represents the variation between samples. It is a similar concept to a Principal Components Analysis (PCA) plot. The x-axis is the dimension with the highest magnitude. In a standard control/treatment setup, samples should be split along this axis. A desirable plot is shown below:-

MA-plot

Each dot shows the change in expression in one gene.

  • The average expression (over both condition and treatment samples) is represented on the x-axis.
    • Plot points should be symmetrical around the x-axis.
    • We can see that many genes are expressed at a low level, and some are highly expressed.
  • The fold change is represented on the y axis.
    • If expression is significantly different between batch and chem, the dots are red. If not, they are blue. (In Degust, significant means FDR <0.05).
    • At low levels of gene expression (low values of the x axis), fold changes are less likely to be significant.

Click on the dot to see the gene name.

Parallel coordinates and heatmap

Each line shows the change in expression in one gene, between control and treatment.

  • Go to Options at the right.
    • For FDR cut-off set at 0.001.
    • This is a significance level (an adjusted p value). We will set it quite low in this example, to ensure we only examine key differences.
  • Look at the Parallel Coordinates plot. There are two axes:
    • Left: Control: Gene expression in the control samples. All values are set at zero.
    • Right: Treatment Gene expression in the treatment samples, relative to expression in the control.
  • The blocks of blue and red underneath the plot are called a heatmap.
    • Each block is a gene. Click on a block to see its line in the plot above.
    • Look at the row for the chem. Relative to batch, genes expressed more are red; genes expressed less are blue.

Table of genes

Table of genes

  • gene_id: names of genes. Note that gene names are sometimes specific to a species, or they may be only named as a locus ID (a chromosomal location specified in the genome annotation).
  • FDR: False Discovery Rate. This is an adjusted p value to show the significance of the difference in gene expression between two conditions. Click on column headings to sort. By default, this table is sorted by FDR.
  • basal and luminal: log2(Fold Change) of gene expression. The default display is of fold change in the treatment relative to the control. Therefore, values in the batch column are zero. This can be changed in the Options panel at the top right.
    • In some cases, a large fold change will be meaningful but in others, even a small fold change can be important biologically.

The table can be sorted according to any of the columns (e.g. fold-change or p-value)

Download and R code

Above the genes table is the option to download the results of the current analysis to a csv file. You can also download the R code required to reproduce the analysis by clicking the Show R code box underneath the Options box.

Plots such as the MDS, MA and heatmap can also be exported by right-clicking on the plot.

Exercise

Question: Do the sample groupings in the MDS plot make sense? Do any samples appear to be mislabeled? What effect might this have on the analysis?

Question: Having identified the problem with the analysis, modify the configuration and repeat. How many genes are differentially expressed this time?

Analysing a different contrast

Comparing Basal vs Luminal wasn’t really the main question of interest in the dataset, but it serves to illustrate the importance of checking QC plots.

  • Create conditions Basal.Pregnant, Basal.Lactation, etc using the corrected experimental design
  • Make sure that Basal.Pregnant and Basal.Lactation are both ticked as initial select

Take some time to understand the various parts of the report

Exercise: Make sure the FDR cut-off and abs LogFC cutoffs are set to default and download the file and rename to background.csv. We will use this later.

Exercise: How many genes are differentially-expressed with an FDR < 0.05 and abs logFC > 1. Download this file and rename it to B.preg_vs_lactation.csv.

Exercise: Repeat the analysis for Luminal.Pregnant vs Luminal.Lactation and download the table of differentially-expressed results (same FDR and log fold-change).

File Downloads

If you didn’t manage to complete these analyses, you can download the files from here by right-clicking on each link and selecting “Save Link as” (or equivalent). They are also available in the course google drive.

Overlapping Gene Lists

We might sometimes want to compare the lists of genes that we identify using different methods, or genes identified from more than one contrast. In our example dataset we can compare the genes in the contrast of pregnant vs luminal in basal and luminal cells

The website venny provides a really nice interface for doing this.

  • Open both your Basal Pregnant vs Basal Lactation and Luminal Pregnant vs Luminal Lactation results files in Excel
  • Go to the venny website
  • Copy the names of genes with adjusted p-value less than 0.05 in the Basal analysis into the List 1 box on the venny website. List 1 can be renamed to Basal
    • You can select all entries in a column with the shortcut CTRL + SPACE
  • Copy the names of genes with adjusted p-value less than 0.05 in the Luminal analysis into the List 2 box on the venny website. List 2 can be renamed to Luminal
  • venny should now report the number of genes found in each list, the size of the intersection, and genes unique to each method

Modified analysis using Hidden Factors

Let’s consider the situation where we want to identify genes that are different between pregnancy and lactating samples regardless of the cell type. We have already done this using the venn diagram approach above, but in this final analysis we will include all the pregnancy and lactating samples, but correct for the differences in cell type. This is more efficient than analysing each cell type separately and comparing the results. Each statistical test we do will involve calling many false positives. We can achieve the same outcome by performing just one statistical test.

This can be done by telling Degust about the hidden factors in our dataset. The hidden factor in this dataset is whether the sample is from the basal or luminal samples. In other words, this is a technical factor that influences our results but not a factor that we wish to compare. We only need to specify which samples are from basal and DEGUST will infer that the other samples belong to a different cell type. Other hidden factors you might need to include could be (depending on the MDS plot) :-

  • sample batch
  • gender

See below for the correct configuration to include the hidden factors.

You should see that on the MDS plot the samples cluster according to cell type. However, this is fine because we are going to incorporate this hidden factor in the analysis

You are now ready to complete the final section on annotation and enrichment analysis



LS0tDQp0aXRsZTogIkRpZmZlcmVudGlhbCBFeHByZXNzaW9uIFR1dG9yaWFsIg0KYXV0aG9yOiAiTWFyayBEdW5uaW5nIg0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOg0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICBjc3M6IHN0eWxlc2hlZXRzL3N0eWxlcy5jc3MNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBkZl9wcmludDogcGFnZWQNCiAgICB0b2M6IHllcw0KZWRpdG9yX29wdGlvbnM6DQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KDQoNCg0KIyBIYW5kcy1vbiBSTkEtc2VxIEFuYWx5c2lzIGluIEdhbGF4eQ0KDQojIyBBY2tub3dsZWRnZW1lbnQNCg0KX0Jhc2VkIG9uIHRoZSBSTkEtU2VxIHdvcmtzaG9wIGJ5IE1lbGJvdXJuZSBCaW9pbmZvcm1hdGljcyB3cml0dGVuIGJ5IE1haHRhYiBNaXJtb21lbmksIEFuZHJldyBMb25pZSwgSmVzc2ljYSBDaHVuZ18gW09yaWdpbmFsXShodHRwOi8vdmxzY2kuZ2l0aHViLmlvL2xzY2NfZG9jcy90dXRvcmlhbHMvcm5hX3NlcV9kZ2VfYWR2YW5jZWQvcm5hX3NlcV9hZHZhbmNlZF90dXRvcmlhbC8pDQoNCl9Nb2RpZmllZCBieSBEYXZpZCBQb3dlbGwgKE1vbmFzaCBCaW9pbmZvcm1hdGljcyBQbGF0Zm9ybSlfDQoNCl9GdXJ0aGVyIE1vZGlmaWVkIGJ5IE1hcmsgRHVubmluZyBvZiBTaGVmZmllbGQgQmlvaW5mb3JtYXRpY3MgQ29yZV8NCg0KVGhlIERlZ3VzdCBwYXJ0IG9mIHRoaXMgc2Vzc2lvbiBpcyBiYXNlZCBvbiB0aGUgdHV0b3JpYWwgW0RpZmZlcmVudGlhbCBnZW5lIGV4cHJlc3Npb24gdXNpbmcgR2FsYXh5IGFuZCBEZWd1c3RdKGh0dHA6Ly9zZXBzaXMtb21pY3MuZ2l0aHViLmlvL3R1dG9yaWFscy9tb2R1bGVzL2RnZS8pIGZyb20gQW50aWJpb3RpYyBSZXNpc3RhbnQgUGF0aG9nZW5zIEluaXRpYXRpdmUgKEFSUEkpDQoNCiMjIyBTaGVmZmllbGQgQmlvaW5mb3JtYXRpY3MgQ29yZQ0KPGltZyBzcmM9Im1lZGlhL2xvZ28tc20ucG5nIiBhbGlnbj1yaWdodD4NCg0Kd2ViIDogW3NiYy5zaGVmLmFjLnVrXShodHRwczovL3NiYy5zaGVmLmFjLnVrKSAgDQp0d2l0dGVyOiBbQFNoZWZmQmlvaW5mQ29yZV0oaHR0cHM6Ly90d2l0dGVyLmNvbS9TaGVmZkJpb2luZkNvcmUpICANCmVtYWlsOiBbYmlvaW5mb3JtYXRpY3MtY29yZUBzaGVmZmllbGQuYWMudWtdKGJpb2luZm9ybWF0aWNzLWNvcmVAc2hlZmZpZWxkLmFjLnVrKQ0KDQotLS0tLQ0KDQojIyBUdXRvcmlhbCBPdmVydmlldw0KDQpUaGlzIHR1dG9yaWFsIHdpbGwgY292ZXIgdGhlIGJhc2ljcyBvZiBSTkEtc2VxIHVzaW5nIEdhbGF4eTsgYSBvcGVuLXNvdXJjZSB3ZWItYmFzZWQgcGxhdGZvcm0gZm9yIHRoZSBhbmFseXNpcyBvZiBiaW9sb2dpY2FsIGRhdGEuIFlvdSBzaG91bGQgZ2FpbiBhbiBhcHByZWNpYXRpb24gb2YgdGhlIHRhc2tzIGludm9sdmVkIGluIGEgdHlwaWNhbCBSTkEtc2VxIGFuYWx5c2lzIGFuZCBiZSBjb21mb3J0YWJsZSB3aXRoIHRoZSBvdXRwdXRzIGdlbmVyYXRlZCBieSB0aGUgQmlvaW5mb3JtYXRpY2lhbi4NCg0KIyMjIE1vcmUgb24gR2FsYXh5DQoNClRoZSBvZmZpY2lhbCBHYWxheHkgcGFnZSBoYXMgbWFueSBbdHV0b3JpYWxzXShodHRwczovL2dhbGF4eXByb2plY3Qub3JnL2xlYXJuLykgb24gdXNpbmcgdGhlIHNlcnZpY2UsIGFuZCBleGFtcGxlcyBvZiBvdGhlciB0eXBlcyBvZiBhbmFseXNpcyB0aGF0IGNhbiBiZSBwZXJmb3JtZWQgb24gdGhlIHBsYXRmb3JtLg0KDQpUaG9zZSBldmVudHVhbGx5IHdhbnRlZCB0byBwZXJmb3JtIHRoZWlyIG93biBSTkEtc2VxIGFuYWx5c2lzIChmb3IgZXhhbXBsZSBpbiBSKSwgc2hvdWxkIGxvb2sgb3V0IGZvciBvdGhlciBjb3Vyc2VzDQoNCiMjIyBDb3Vyc2VzIG9uIGFuYWx5c2luZyBSTkEtc2VxIGRhdGEgaW4gUg0KDQotIFtTaGVmZmllbGQgQmlvaW5mb3JtYXRpY3MgQ29yZV0oaHR0cDovL3NiYy5zaGVmLmFjLnVrL3RyYWluaW5nL3JuYS1zZXEtaW4tci0yMDE5LTAxLTE0LykNCi0gW01vbmFzaCBCaW9pbmZvcm1hdGljcyBQbGF0Zm9ybV0oaHR0cDovL21vbmFzaGJpb2luZm9ybWF0aWNzcGxhdGZvcm0uZ2l0aHViLmlvL1JOQXNlcS1ERS1hbmFseXNpcy13aXRoLVIvKQ0KDQojIyBSZWNhcA0KDQpQcmV2aW91cyBzZWN0aW9ucyBoYXZlIGlsbHVzdHJhdGVkIGhvdyB0bw0KDQotIFtwZXJmb3JtIHF1YWxpdHkgYXNzZXNzbWVudCBvbiBvdXIgZmFzdHEgZmlsZXNdKDAxLXByZS1wcm9jZXNzaW5nLm5iLmh0bWwjc2VjdGlvbl8yOl9xdWFsaXR5X2Fzc2Vzc21lbnRfd2l0aF9mYXN0cWMpDQotIFthbGlnbiBmYXN0cSBmaWxlcyB0byB0aGUgcmVmZXJlbmNlIGdlbm9tZV0oMDEtcHJlLXByb2Nlc3NpbmcubmIuaHRtbCNzZWN0aW9uXzM6X2FsaWdubWVudCkNCi0gW3Zpc3VhbGlzZSB0aGUgcmVhZHMgaW4gSUdWXSgwMS1wcmUtcHJvY2Vzc2luZy5uYi5odG1sI3NlY3Rpb25fNF92aXN1YWxpc2VfdGhlX2FsaWduZWRfcmVhZHNfd2l0aF9pZ3YpDQotIFtjb3VudCBhZ2FpbnN0IGEgc2V0IG9mIHJlZmVyZW5jZSB0cmFuc2NyaXB0c10oMDEtcHJlLXByb2Nlc3NpbmcubmIuaHRtbCNzZWN0aW9uXzVfcXVhbnRpZmljYXRpb25fKGNvdW50aW5nX3JlYWRzX2luX2ZlYXR1cmVzKSkNCg0KV2Ugd2lsbCBub3cgdXNlIHRoZSBwdWJsaXNoZWQgY291bnRzIGFzIHRoZSBpbnB1dCBmb3IgYSBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBhbmFseXNpcy4NCg0KDQojIyBEaWZmZXJlbnRpYWwgZXhwcmVzc2lvbg0KDQpUaGUgdGVybSAqZGlmZmVyZW50aWFsIGV4cHJlc3Npb24qIHdhcyBmaXJzdCB1c2VkIHRvIHJlZmVyIHRvIHRoZSBwcm9jZXNzIG9mIGZpbmRpbmcgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBnZW5lcyBmcm9tIGEgKm1pY3JvYXJyYXkqIGdlbmUgZXhwcmVzc2lvbiBzdHVkeS4NCg0KIVtdKG1lZGlhL2RlX2V4cGxhaW5lZC5wbmcpDQoNCg0KU3VjaCBtZXRob2RzIHdlcmUgZGV2ZWxvcGVkIG9uIHRoZSBwcmVtaXNlIHRoYXQgbWljcm9hcnJheSBleHByZXNzaW9uIHZhbHVlcyBhcmUgYXBwcm94aW1hdGVseSAqbm9ybWFsbHktZGlzdHJpYnV0ZWQqIHdoZW4gYXBwcm9wcmlhdGVseSB0cmFuc2Zvcm1lZCAoZS5nLiBieSB1c2luZyBhIGxvZyRfMiQgdHJhbnNmb3JtYXRpb24pIHNvIHRoYXQgYSBtb2RpZmllZCB2ZXJzaW9uIG9mIHRoZSBzdGFuZGFyZCAqdC10ZXN0KiBjYW4gYmUgdXNlZC4gVGhlIHNhbWUgdGVzdCBpcyBhcHBsaWVkIHRvIGVhY2ggZ2VuZSB1bmRlciBpbnZlc3RpZ2F0aW9uIHlpZWxkaW5nIGEgKnRlc3Qgc3RhdGlzdGljKiwgKmZvbGQtY2hhbmdlKiBhbmQgKnAtdmFsdWUqLiBTaW1pbGFyIG1ldGhvZHMgaGF2ZSBiZWVuIGFkYXB0ZWQgdG8gUk5BLXNlcSBkYXRhIHRvIGFjY291bnQgZm9yIHRoZSBmYWN0IHRoYXQgdGhlIGRhdGEgYXJlICpjb3VudC1iYXNlZCogYW5kIGRvIG5vdCBmb2xsb3cgYSBub3JtYWwgZGlzdHJpYnV0aW9uLg0KDQoNCiMjIEludGVyYWN0aXZlIGV4cGxvcmF0aW9uIG9mIHRoZSByZXN1bHRzIHdpdGggKkRFR1VTVCoNCg0KIVtdKG1lZGlhL3JuYV9hZHZhbmNlZF9kZWd1c3RfMS5wbmcpDQoNCjxmb250IHNpemU9IjgiPltodHRwOi8vZGVndXN0LmVyYy5tb25hc2guZWR1L10oaHR0cDovL2RlZ3VzdC5lcmMubW9uYXNoLmVkdS8pPC9mb250Pg0KDQpgRGVndXN0YCBpcyBhIHdlYiB0b29sIHRoYXQgY2FuIGFuYWx5c2UgdGhlIGNvdW50cyBmaWxlcyBwcm9kdWNlZCBpbiB0aGUgc3RlcCBhYm92ZSwgdG8gdGVzdCBmb3IgZGlmZmVyZW50aWFsIGdlbmUgZXhwcmVzc2lvbi4gSXQgb2ZmZXJzIGFuZCBpbnRlcmFjdGl2ZSB2aWV3IG9mIHRoZSBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiByZXN1bHRzDQoNClRoZSBpbnB1dCBmaWxlIGlzIGEgY291bnQgbWF0cml4IHdoZXJlIGVhY2ggcm93IGlzIGEgbWVhc3VyZWQgZ2VuZSwgYW5kIGVhY2ggY29sdW1uIGlzIGEgZGlmZmVyZW50IGJpb2xvZ2ljYWwgc2FtcGxlLiBXaXRoaW4gdGhlIHRvb2wgd2UgY2FuIGNvbmZpZ3VyZSB3aGljaCBzYW1wbGVzIGJlbG9uZyB0byB0aGUgZGlmZmVyZW50IGJpb2xvZ2ljYWwgZ3JvdXBzIG9mIGludGVyZXN0Lg0KDQpSZWFkIGNvdW50cyBoYXZlIHRvIGJlIG5vcm1hbGlzZWQgZmlyc3QgcHJpb3IgdG8gZGlmZmVyZW50aWFsIGV4cHJlc3Npb24gdGVzdGluZy4gVGhlcmUgYXJlIHR3byBtYWluIGJpYXNlcyB0aGF0IG5lZWQgdG8gYmUgYWNjb3VudGVkIGZvcjotDQoNCi0gc2l6ZSBvZiBnZW5lDQogICAgKyAqbG9uZ2VyKiBnZW5lcyB3aWxsIGhhdmUgbW9yZSByZWFkcyBhc3NpZ25lZCB0byB0aGVtDQotIGxpYnJhcnkgc2l6ZQ0KICAgICsgYSBzYW1wbGUgdGhhdCBpcyBzZXF1ZW5jZWQgdG8gYSBoaWdoZXIgZGVwdGggd2lsbCByZWNlaXZlIG1vcmUgcmVhZHMNCiAgDQpIb3dldmVyLCBSLWJhc2VkIG1ldGhvZHMgc3VjaCBhcyBgZWRnZVJgIChpbXBsZW1lbnRlZCBpbiBEZWd1c3QpIGFuZCBgREVTZXEyYCBoYXZlIHRoZWlyIG93biBtZXRob2Qgb2Ygbm9ybWFsaXNpbmcgY291bnRzLiBZb3Ugd2lsbCBwcm9iYWJseSBlbmNvdW50ZXIgb3RoZXIgbWV0aG9kcyBvZiBub3JtYWxpc2luZyBSTkEtc2VxIHJlYWRzIHN1Y2ggYXMgKlJQS00qLCAqQ1BNKiwgKlRQTSogZXRjLiBbVGhpcyBibG9nXShodHRwczovL3d3dy5ybmEtc2VxYmxvZy5jb20vcnBrbS1mcGttLWFuZC10cG0tY2xlYXJseS1leHBsYWluZWQvKSBwcm92aWRlcyBhIG5pY2UgZXhwbGFuYXRpb24gb2YgdGhlIGN1cnJlbnQgdGhpbmtpbmcuIEFzIHBhcnQgb2YgdGhlIGBEZWd1c3RgIG91dHB1dCwgeW91IGhhdmUgdGhlIG9wdGlvbiBvZiBkb3dubG9hZGluZyBub3JtYWxpc2VkIGNvdW50cyBpbiB2YXJpb3VzIGZvcm1hdHMuIFNvbWUgb3RoZXIgb25saW5lIHZpc3VhbGlzYXRpb24gdG9vbHMgcmVxdWlyZSBub3JtYWxpc2VkIGNvdW50cyBhcyBpbnB1dCwgc28gaXQgaXMgZ29vZCB0byBoYXZlIHRoZXNlIHRvLWhhbmQuDQoNCg0KKioqVG8gbWFrZSB0aGlzIGEgbW9yZS1yZWFsaXN0aWMgZXhhbXBsZSwgd2Ugd2lsbCB1c2UgdGhlIHB1Ymxpc2hlZCBjb3VudCBtYXRyaXggZm9yIHRoaXMgZGF0YXNldC4gVGhpcyB3YXMgZG93bmxvYWRlZCBmcm9tIHRoZSBHZW5lIEV4cHJlc3Npb24gT21uaWJ1cyAoR0VPKSB1bmRlciB0aGUgYWNjZXNzaW9uIG51bWJlciBbR1NFNjA0NTBdKGh0dHBzOi8vd3d3Lm5jYmkubmxtLm5paC5nb3YvZ2VvL3F1ZXJ5L2FjYy5jZ2k/YWNjPUdTRTYwNDUwKS4gTm90ZSB0aGF0IHdlIGhhdmUgc2hvcnRlbmVkIHRoZSBjb2x1bW4gaGVhZGluZ3MgYW5kIGFkZGVkIGdlbmUgc3ltYm9scyB0byBoZWxwIHdpdGggdmlzdWFsaXNhdGlvbiBhbmQgYW5ub3RhdGlvbioqKg0KDQpEb3dubG9hZCB0aGUgY291bnRzIGZyb20gW3RoaXMgbGlua10oR1NFNjA0NTBfTGFjdGF0aW9uLUdlbmV3aXNlQ291bnRzX3JlbmFtZV9zeW1ib2wuY3N2KQ0KDQoNCiMjIyBVcGxvYWRpbmcgdGhlIGNvdW50IG1hdHJpeCB0byBEZWd1c3QNCg0KDQotIEZyb20gdGhlIG1haW4gZGVndXN0IHBhZ2UsIGNsaWNrICpVcGxvYWQgeW91ciBjb3VudHMgZmlsZSoNCi0gQ2xpY2sgb24gQnJvd3NlDQotIFNlbGVjdCB0aGUgbG9jYXRpb24gb2YgdGhlIGZpbGUgYEdTRTYwNDUwX0xhY3RhdGlvbi1HZW5ld2lzZUNvdW50c19yZW5hbWVfc3ltYm9sLmNzdmAsIGFuZCBjbGljayAqT3BlbiouDQotIENsaWNrICpVcGxvYWQqDQotIEEgQ29uZmlndXJhdGlvbiBwYWdlIHdpbGwgYXBwZWFyLg0KDQohW10obWVkaWEvZGVndXN0X2NvbmZpZy5wbmcpDQoNCi0gRm9yIE5hbWUgdHlwZSAiKkdTRTYwNDUwKiIgKG9yIHdoYXRldmVyIHlvdSB3YW50IHRvIGNhbGwgdGhlIGFuYWx5c2lzKQ0KLSBGb3IgSW5mbyBjb2x1bW5zIHNlbGVjdCAqU1lNQk9MKg0KLSBDbGljayBBZGQgY29uZGl0aW9uDQogICAgKyBSZWZlcnJpbmcgdG8gdGhlIGV4cGVyaW1lbnQgZGVzaWduIChiZWxvdyksIHNlbGVjdCB0aGUgQmFzYWwgc2FtcGxlcyBhbmQgY2FsbCB0aGUgY29uZGl0aW9uIEJhc2FsDQogICAgKyBSZXBlYXQgZm9yIHRoZSBMdW1pbmFsIHNhbXBsZXMNCi0gU2F2ZSB0aGUgc2V0dGluZ3MgYW5kIHRoZW4gVmlldyB0aGUgcmVzdWx0cw0KDQpSdW4gIHwgTmFtZSB8IENlbGxUeXBlIHwgU3RhdHVzDQotLS0tLS0tLS0tLS0tIHwgLS0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0tLS0gfCAtLS0tLS0tLS0tLS0tICANClNSUjE1NTI0NDQgfCBNQ0wxLUxBIHwgYmFzYWwgfCB2aXJnaW4NClNSUjE1NTI0NDUgfCBNQ0wxLUxCIHwgbHVtaW5hbCB8IHZpcmdpbg0KU1JSMTU1MjQ0NiB8IE1DTDEtTEMgfCBMdW1pbmFsIHwgcHJlZ25hbmN5DQpTUlIxNTUyNDQ3IHwgTUNMMS1MRCB8IEx1bWluYWwgfCBwcmVnbmFuY3kNClNSUjE1NTI0NDggfCBNQ0wxLUxFIHwgbHVtaW5hbCB8IGxhY3RhdGlvbg0KU1JSMTU1MjQ0OSB8IE1DTDEtTEYgfCBsdW1pbmFsIHwgbGFjdGF0aW9uDQpTUlIxNTUyNDUwIHwgTUNMMS1ERyB8IGJhc2FsIHwgdmlyZ2luDQpTUlIxNTUyNDUxIHwgTUNMMS1ESCB8IGx1bWluYWwgfCB2aXJnaW4NClNSUjE1NTI0NTIgfCBNQ0wxLURJIHwgYmFzYWwgfCBwcmVnbmFuY3kNClNSUjE1NTI0NTMgfCBNQ0wxLURKIHwgYmFzYWwgfCBwcmVnbmFuY3kNClNSUjE1NTI0NTQgfCBNQ0wxLURLIHwgYmFzYWwgfCBsYWN0YXRpb24NClNSUjE1NTI0NTUgfCBNQ0wxLURMIHwgYmFzYWwgfCBsYWN0YXRpb24NCg0KIyMgT3ZlcnZpZXcgb2YgRGVndXN0IHNlY3Rpb25zDQoNCi0gVG9wIGJsYWNrIHBhbmVsIHdpdGggQ29uZmlndXJlIHNldHRpbmdzIGF0IHJpZ2h0Lg0KLSBMZWZ0OiBDb25kaXRpb25zOiBDb250cm9sIGFuZCBUcmVhdG1lbnQuDQotIExlZnQ6IE1ldGhvZCBzZWxlY3Rpb24gZm9yIERHRS4gKipTZWxlY3QgZWRnZVIgZm9yIHlvdXIgbWV0aG9kKioNCi0gVG9wIGNlbnRyZTogUGxvdHMsIHdpdGggb3B0aW9ucyBhdCByaWdodC4NCi0gV2hlbiBlaXRoZXIgb2YgdGhlIGV4cHJlc3Npb24gcGxvdHMgYXJlIHNlbGVjdGVkLCBhIGhlYXRtYXAgYXBwZWFycyBiZWxvdy4NCi0gQSB0YWJsZSBvZiBnZW5lcyAob3IgZmVhdHVyZXMpOyBleHByZXNzaW9uIGluIHRyZWF0bWVudCByZWxhdGl2ZSB0byBjb250cm9sIChUcmVhdG1lbnQgY29sdW1uKTsgYW5kIHNpZ25pZmljYW5jZSAoRkRSIGNvbHVtbikuDQoNCigqKk5vdCB0aGF0IHRoZSBzY3JlZW5zaG90cyBhcmUgZm9yIGlsbHVzdHJhdGlvbiBwdXJwb3NlcyBhbmQgdGFrZW4gZnJvbSBhIGRpZmZlcmVudCBkYXRhc2V0IHRvIHRoYXQgYmVpbmcgYW5hbHlzZWQgaW4gdGhlIHR1dG9yaWFsKiopDQoNCiFbXShodHRwOi8vc2Vwc2lzLW9taWNzLmdpdGh1Yi5pby90dXRvcmlhbHMvbW9kdWxlcy9kZ2UvaW1hZ2VzL2ltYWdlMTIucG5nKQ0KDQojIyBNRFMgcGxvdA0KDQoNCg0KVGhpcyBpcyBhIG11bHRpZGltZW5zaW9uYWwgc2NhbGluZyBwbG90IHdoaWNoIHJlcHJlc2VudHMgdGhlIHZhcmlhdGlvbiBiZXR3ZWVuIHNhbXBsZXMuIEl0IGlzIGEgc2ltaWxhciBjb25jZXB0IHRvIGEgUHJpbmNpcGFsIENvbXBvbmVudHMgQW5hbHlzaXMgKFBDQSkgcGxvdC4gVGhlIHgtYXhpcyBpcyB0aGUgZGltZW5zaW9uIHdpdGggdGhlIGhpZ2hlc3QgbWFnbml0dWRlLiBJbiBhIHN0YW5kYXJkIGNvbnRyb2wvdHJlYXRtZW50IHNldHVwLCBzYW1wbGVzIHNob3VsZCBiZSBzcGxpdCBhbG9uZyB0aGlzIGF4aXMuIEEgZGVzaXJhYmxlIHBsb3QgaXMgc2hvd24gYmVsb3c6LQ0KDQohW10obWVkaWEvZGVndXN0X21kcy5wbmcpDQoNCiMjIE1BLXBsb3QNCg0KIVtdKG1lZGlhL2RlZ3VzdF9tYS5wbmcpDQoNCkVhY2ggZG90IHNob3dzIHRoZSBjaGFuZ2UgaW4gZXhwcmVzc2lvbiBpbiBvbmUgZ2VuZS4NCg0KLSBUaGUgYXZlcmFnZSBleHByZXNzaW9uIChvdmVyIGJvdGggY29uZGl0aW9uIGFuZCB0cmVhdG1lbnQgc2FtcGxlcykgaXMgcmVwcmVzZW50ZWQgb24gdGhlIHgtYXhpcy4NCiAgICArIFBsb3QgcG9pbnRzIHNob3VsZCBiZSBzeW1tZXRyaWNhbCBhcm91bmQgdGhlIHgtYXhpcy4NCiAgICArIFdlIGNhbiBzZWUgdGhhdCBtYW55IGdlbmVzIGFyZSBleHByZXNzZWQgYXQgYSBsb3cgbGV2ZWwsIGFuZCBzb21lIGFyZSBoaWdobHkgZXhwcmVzc2VkLg0KLSBUaGUgZm9sZCBjaGFuZ2UgaXMgcmVwcmVzZW50ZWQgb24gdGhlIHkgYXhpcy4NCiAgICArIElmIGV4cHJlc3Npb24gaXMgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnQgYmV0d2VlbiBiYXRjaCBhbmQgY2hlbSwgdGhlIGRvdHMgYXJlIHJlZC4gSWYgbm90LCB0aGV5IGFyZSBibHVlLiAoSW4gRGVndXN0LCBzaWduaWZpY2FudCBtZWFucyBGRFIgPDAuMDUpLg0KICAgICsgQXQgbG93IGxldmVscyBvZiBnZW5lIGV4cHJlc3Npb24gKGxvdyB2YWx1ZXMgb2YgdGhlIHggYXhpcyksIGZvbGQgY2hhbmdlcyBhcmUgbGVzcyBsaWtlbHkgdG8gYmUgc2lnbmlmaWNhbnQuDQoNCkNsaWNrIG9uIHRoZSBkb3QgdG8gc2VlIHRoZSBnZW5lIG5hbWUuDQoNCiMjIFBhcmFsbGVsIGNvb3JkaW5hdGVzIGFuZCBoZWF0bWFwDQoNCiFbXShtZWRpYS9kZWd1c3RfcGFyYWxsZWxfaGVhdG1hcC5wbmcpDQoNCkVhY2ggbGluZSBzaG93cyB0aGUgY2hhbmdlIGluIGV4cHJlc3Npb24gaW4gb25lIGdlbmUsIGJldHdlZW4gY29udHJvbCBhbmQgdHJlYXRtZW50Lg0KDQotIEdvIHRvIE9wdGlvbnMgYXQgdGhlIHJpZ2h0Lg0KICAgICsgRm9yIEZEUiBjdXQtb2ZmIHNldCBhdCAwLjAwMS4NCiAgICArIFRoaXMgaXMgYSBzaWduaWZpY2FuY2UgbGV2ZWwgKGFuIGFkanVzdGVkIHAgdmFsdWUpLiBXZSB3aWxsIHNldCBpdCBxdWl0ZSBsb3cgaW4gdGhpcyBleGFtcGxlLCB0byBlbnN1cmUgd2Ugb25seSBleGFtaW5lIGtleSBkaWZmZXJlbmNlcy4NCi0gTG9vayBhdCB0aGUgUGFyYWxsZWwgQ29vcmRpbmF0ZXMgcGxvdC4gVGhlcmUgYXJlIHR3byBheGVzOg0KICAgICsgTGVmdDogQ29udHJvbDogR2VuZSBleHByZXNzaW9uIGluIHRoZSBjb250cm9sIHNhbXBsZXMuIEFsbCB2YWx1ZXMgYXJlIHNldCBhdCB6ZXJvLg0KICAgICsgUmlnaHQ6IFRyZWF0bWVudCBHZW5lIGV4cHJlc3Npb24gaW4gdGhlIHRyZWF0bWVudCBzYW1wbGVzLCByZWxhdGl2ZSB0byBleHByZXNzaW9uIGluIHRoZSBjb250cm9sLg0KLSBUaGUgYmxvY2tzIG9mIGJsdWUgYW5kIHJlZCB1bmRlcm5lYXRoIHRoZSBwbG90IGFyZSBjYWxsZWQgYSBoZWF0bWFwLg0KICAgICsgRWFjaCBibG9jayBpcyBhIGdlbmUuIENsaWNrIG9uIGEgYmxvY2sgdG8gc2VlIGl0cyBsaW5lIGluIHRoZSBwbG90IGFib3ZlLg0KICAgICsgTG9vayBhdCB0aGUgcm93IGZvciB0aGUgY2hlbS4gUmVsYXRpdmUgdG8gYmF0Y2gsIGdlbmVzIGV4cHJlc3NlZCBtb3JlIGFyZSByZWQ7IGdlbmVzIGV4cHJlc3NlZCBsZXNzIGFyZSBibHVlLg0KDQojIyBUYWJsZSBvZiBnZW5lcw0KDQohW10obWVkaWEvZGVndXN0X2dlbmVfdGFibGUucG5nKQ0KDQpUYWJsZSBvZiBnZW5lcw0KDQotIGdlbmVfaWQ6IG5hbWVzIG9mIGdlbmVzLiBOb3RlIHRoYXQgZ2VuZSBuYW1lcyBhcmUgc29tZXRpbWVzIHNwZWNpZmljIHRvIGEgc3BlY2llcywgb3IgdGhleSBtYXkgYmUgb25seSBuYW1lZCBhcyBhIGxvY3VzIElEIChhIGNocm9tb3NvbWFsIGxvY2F0aW9uIHNwZWNpZmllZCBpbiB0aGUgZ2Vub21lIGFubm90YXRpb24pLg0KLSBGRFI6IEZhbHNlIERpc2NvdmVyeSBSYXRlLiBUaGlzIGlzIGFuIGFkanVzdGVkIHAgdmFsdWUgdG8gc2hvdyB0aGUgc2lnbmlmaWNhbmNlIG9mIHRoZSBkaWZmZXJlbmNlIGluIGdlbmUgZXhwcmVzc2lvbiBiZXR3ZWVuIHR3byBjb25kaXRpb25zLiBDbGljayBvbiBjb2x1bW4gaGVhZGluZ3MgdG8gc29ydC4gQnkgZGVmYXVsdCwgdGhpcyB0YWJsZSBpcyBzb3J0ZWQgYnkgRkRSLg0KLSBiYXNhbCBhbmQgbHVtaW5hbDogbG9nMihGb2xkIENoYW5nZSkgb2YgZ2VuZSBleHByZXNzaW9uLiBUaGUgZGVmYXVsdCBkaXNwbGF5IGlzIG9mIGZvbGQgY2hhbmdlIGluIHRoZSB0cmVhdG1lbnQgcmVsYXRpdmUgdG8gdGhlIGNvbnRyb2wuIFRoZXJlZm9yZSwgdmFsdWVzIGluIHRoZSBiYXRjaCBjb2x1bW4gYXJlIHplcm8uIFRoaXMgY2FuIGJlIGNoYW5nZWQgaW4gdGhlIE9wdGlvbnMgcGFuZWwgYXQgdGhlIHRvcCByaWdodC4NCiAgICArIEluIHNvbWUgY2FzZXMsIGEgbGFyZ2UgZm9sZCBjaGFuZ2Ugd2lsbCBiZSBtZWFuaW5nZnVsIGJ1dCBpbiBvdGhlcnMsIGV2ZW4gYSBzbWFsbCBmb2xkIGNoYW5nZSBjYW4gYmUgaW1wb3J0YW50IGJpb2xvZ2ljYWxseS4NCg0KVGhlIHRhYmxlIGNhbiBiZSBzb3J0ZWQgYWNjb3JkaW5nIHRvIGFueSBvZiB0aGUgY29sdW1ucyAoZS5nLiBmb2xkLWNoYW5nZSBvciBwLXZhbHVlKQ0KDQoNCiMjIERvd25sb2FkIGFuZCBSIGNvZGUNCg0KQWJvdmUgdGhlIGdlbmVzIHRhYmxlIGlzIHRoZSBvcHRpb24gdG8gZG93bmxvYWQgdGhlIHJlc3VsdHMgb2YgdGhlIGN1cnJlbnQgYW5hbHlzaXMgdG8gYSBjc3YgZmlsZS4gWW91IGNhbiBhbHNvIGRvd25sb2FkIHRoZSAqUiogY29kZSByZXF1aXJlZCB0byByZXByb2R1Y2UgdGhlIGFuYWx5c2lzIGJ5IGNsaWNraW5nIHRoZSAqU2hvdyBSIGNvZGUqIGJveCB1bmRlcm5lYXRoIHRoZSBPcHRpb25zIGJveC4NCg0KUGxvdHMgc3VjaCBhcyB0aGUgTURTLCBNQSBhbmQgaGVhdG1hcCBjYW4gYWxzbyBiZSBleHBvcnRlZCBieSByaWdodC1jbGlja2luZyBvbiB0aGUgcGxvdC4NCg0KIyMgRXhlcmNpc2UNCg0KPGRpdiBjbGFzcz0iZXhlcmNpc2UiPg0KKipRdWVzdGlvbjoqKiBEbyB0aGUgc2FtcGxlIGdyb3VwaW5ncyBpbiB0aGUgTURTIHBsb3QgbWFrZSBzZW5zZT8gRG8gYW55IHNhbXBsZXMgYXBwZWFyIHRvIGJlIG1pc2xhYmVsZWQ/IFdoYXQgZWZmZWN0IG1pZ2h0IHRoaXMgaGF2ZSBvbiB0aGUgYW5hbHlzaXM/DQo8L2Rpdj4NCg0KPGRpdiBjbGFzcz0iZXhlcmNpc2UiPg0KKipRdWVzdGlvbjoqKiBIYXZpbmcgaWRlbnRpZmllZCB0aGUgcHJvYmxlbSB3aXRoIHRoZSBhbmFseXNpcywgbW9kaWZ5IHRoZSBjb25maWd1cmF0aW9uIGFuZCByZXBlYXQuIEhvdyBtYW55IGdlbmVzIGFyZSBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgdGhpcyB0aW1lPw0KPC9kaXY+DQoNCiMgQW5hbHlzaW5nIGEgZGlmZmVyZW50IGNvbnRyYXN0DQoNCkNvbXBhcmluZyBCYXNhbCB2cyBMdW1pbmFsIHdhc24ndCByZWFsbHkgdGhlIG1haW4gcXVlc3Rpb24gb2YgaW50ZXJlc3QgaW4gdGhlIGRhdGFzZXQsIGJ1dCBpdCBzZXJ2ZXMgdG8gaWxsdXN0cmF0ZSB0aGUgaW1wb3J0YW5jZSBvZiBjaGVja2luZyBRQyBwbG90cy4gDQoNCi0gQ3JlYXRlIGNvbmRpdGlvbnMgKkJhc2FsLlByZWduYW50KiwgKkJhc2FsLkxhY3RhdGlvbiosIGV0YyB1c2luZyB0aGUgY29ycmVjdGVkIGV4cGVyaW1lbnRhbCBkZXNpZ24NCi0gTWFrZSBzdXJlIHRoYXQgKkJhc2FsLlByZWduYW50KiBhbmQgKkJhc2FsLkxhY3RhdGlvbiogYXJlIGJvdGggdGlja2VkIGFzIGluaXRpYWwgc2VsZWN0DQoNCiFbXShtZWRpYS9kZWd1c3QtY29ycmVjdC1jb25maWcucG5nKQ0KDQpUYWtlIHNvbWUgdGltZSB0byB1bmRlcnN0YW5kIHRoZSB2YXJpb3VzIHBhcnRzIG9mIHRoZSByZXBvcnQNCg0KPGRpdiBjbGFzcz0iZXhlcmNpc2UiPg0KKipFeGVyY2lzZToqKiBNYWtlIHN1cmUgdGhlIEZEUiBjdXQtb2ZmIGFuZCBhYnMgTG9nRkMgY3V0b2ZmcyBhcmUgc2V0IHRvIGRlZmF1bHQgYW5kICpkb3dubG9hZCogdGhlIGZpbGUgYW5kIHJlbmFtZSB0byBgYmFja2dyb3VuZC5jc3ZgLiBXZSB3aWxsIHVzZSB0aGlzIGxhdGVyLg0KPC9kaXY+DQoNCjxkaXYgY2xhc3M9ImV4ZXJjaXNlIj4NCioqRXhlcmNpc2UqKjogSG93IG1hbnkgZ2VuZXMgYXJlIGRpZmZlcmVudGlhbGx5LWV4cHJlc3NlZCB3aXRoIGFuIEZEUiA8IDAuMDUgYW5kIGFicyBsb2dGQyA+IDEuIERvd25sb2FkIHRoaXMgZmlsZSBhbmQgcmVuYW1lIGl0IHRvIGBCLnByZWdfdnNfbGFjdGF0aW9uLmNzdmAuDQo8L2Rpdj4NCg0KDQo8ZGl2IGNsYXNzPSJleGVyY2lzZSI+DQoqKkV4ZXJjaXNlKio6IFJlcGVhdCB0aGUgYW5hbHlzaXMgZm9yIEx1bWluYWwuUHJlZ25hbnQgdnMgTHVtaW5hbC5MYWN0YXRpb24gYW5kIGRvd25sb2FkIHRoZSB0YWJsZSBvZiBkaWZmZXJlbnRpYWxseS1leHByZXNzZWQgcmVzdWx0cyAoc2FtZSBGRFIgYW5kIGxvZyBmb2xkLWNoYW5nZSkuIA0KPC9kaXY+DQoNCiMjIEZpbGUgRG93bmxvYWRzDQoNCjxkaXYgY2xhc3M9ImluZm9ybWF0aW9uIj4NCklmIHlvdSBkaWRuJ3QgbWFuYWdlIHRvIGNvbXBsZXRlIHRoZXNlIGFuYWx5c2VzLCB5b3UgY2FuIGRvd25sb2FkIHRoZSBmaWxlcyBmcm9tIGhlcmUgYnkgcmlnaHQtY2xpY2tpbmcgb24gZWFjaCBsaW5rIGFuZCBzZWxlY3RpbmcgIlNhdmUgTGluayBhcyIgKG9yIGVxdWl2YWxlbnQpLiBUaGV5IGFyZSBhbHNvIGF2YWlsYWJsZSBpbiB0aGUgY291cnNlIGdvb2dsZSBkcml2ZS4NCg0KLSBbQi5wcmVnX3ZzX2xhY3RhdGlvbi5jc3ZdKEIucHJlZ192c19sYWN0YXRpb24uY3N2KQ0KLSBbTC5wcmVnX3ZzX2xhY3RhdGlvbi5jc3ZdKEwucHJlZ192c19sYWN0YXRpb24uY3N2KQ0KLSBbYmFja2dyb3VuZC5jc3ZdKGJhY2tncm91bmQuY3N2KQ0KDQo8L2Rpdj4NCg0KIyMgT3ZlcmxhcHBpbmcgR2VuZSBMaXN0cw0KDQoNCldlIG1pZ2h0IHNvbWV0aW1lcyB3YW50IHRvIGNvbXBhcmUgdGhlIGxpc3RzIG9mIGdlbmVzIHRoYXQgd2UgaWRlbnRpZnkgdXNpbmcgZGlmZmVyZW50IG1ldGhvZHMsIG9yIGdlbmVzIGlkZW50aWZpZWQgZnJvbSBtb3JlIHRoYW4gb25lIGNvbnRyYXN0LiBJbiBvdXIgZXhhbXBsZSBkYXRhc2V0IHdlIGNhbiBjb21wYXJlIHRoZSBnZW5lcyBpbiB0aGUgY29udHJhc3Qgb2YgcHJlZ25hbnQgdnMgbHVtaW5hbCBpbiBiYXNhbCBhbmQgbHVtaW5hbCBjZWxscw0KDQpUaGUgd2Vic2l0ZSAqdmVubnkqIHByb3ZpZGVzIGEgcmVhbGx5IG5pY2UgaW50ZXJmYWNlIGZvciBkb2luZyB0aGlzLg0KDQohW10obWVkaWEvdmVubnktY29uZmlnLnBuZykNCg0KLSBPcGVuIGJvdGggeW91ciAqQmFzYWwgUHJlZ25hbnQgdnMgQmFzYWwgTGFjdGF0aW9uKiBhbmQgKkx1bWluYWwgUHJlZ25hbnQgdnMgTHVtaW5hbCBMYWN0YXRpb24qIHJlc3VsdHMgZmlsZXMgaW4gRXhjZWwNCi0gR28gdG8gdGhlIHZlbm55IHdlYnNpdGUNCiAgICArIGh0dHA6Ly9iaW9pbmZvZ3AuY25iLmNzaWMuZXMvdG9vbHMvdmVubnkvDQotIENvcHkgdGhlIG5hbWVzIG9mIGdlbmVzIHdpdGggYWRqdXN0ZWQgcC12YWx1ZSBsZXNzIHRoYW4gMC4wNSBpbiB0aGUgQmFzYWwgYW5hbHlzaXMgaW50byB0aGUgKipMaXN0IDEqKiBib3ggb24gdGhlIHZlbm55IHdlYnNpdGUuICoqTGlzdCAxKiogY2FuIGJlIHJlbmFtZWQgdG8gKkJhc2FsKg0KICAgICsgKllvdSBjYW4gc2VsZWN0IGFsbCBlbnRyaWVzIGluIGEgY29sdW1uIHdpdGggdGhlIHNob3J0Y3V0IENUUkwgKyBTUEFDRSoNCi0gQ29weSB0aGUgbmFtZXMgb2YgZ2VuZXMgd2l0aCBhZGp1c3RlZCBwLXZhbHVlIGxlc3MgdGhhbiAwLjA1IGluIHRoZSBMdW1pbmFsIGFuYWx5c2lzIGludG8gdGhlICoqTGlzdCAyKiogYm94IG9uIHRoZSB2ZW5ueSB3ZWJzaXRlLiAqKkxpc3QgMioqIGNhbiBiZSByZW5hbWVkIHRvICoqTHVtaW5hbCoqDQotIHZlbm55IHNob3VsZCBub3cgcmVwb3J0IHRoZSBudW1iZXIgb2YgZ2VuZXMgZm91bmQgaW4gZWFjaCBsaXN0LCB0aGUgc2l6ZSBvZiB0aGUgaW50ZXJzZWN0aW9uLCBhbmQgZ2VuZXMgdW5pcXVlIHRvIGVhY2ggbWV0aG9kDQoNCiMjIE1vZGlmaWVkIGFuYWx5c2lzIHVzaW5nIEhpZGRlbiBGYWN0b3JzDQoNCkxldCdzIGNvbnNpZGVyIHRoZSBzaXR1YXRpb24gd2hlcmUgd2Ugd2FudCB0byBpZGVudGlmeSBnZW5lcyB0aGF0IGFyZSBkaWZmZXJlbnQgYmV0d2VlbiBwcmVnbmFuY3kgYW5kIGxhY3RhdGluZyBzYW1wbGVzICpyZWdhcmRsZXNzIG9mIHRoZSBjZWxsIHR5cGUqLiBXZSBoYXZlIGFscmVhZHkgZG9uZSB0aGlzIHVzaW5nIHRoZSB2ZW5uIGRpYWdyYW0gYXBwcm9hY2ggYWJvdmUsIGJ1dCBpbiB0aGlzIGZpbmFsIGFuYWx5c2lzIHdlIHdpbGwgaW5jbHVkZSBhbGwgdGhlIHByZWduYW5jeSBhbmQgbGFjdGF0aW5nIHNhbXBsZXMsIGJ1dCBjb3JyZWN0IGZvciB0aGUgZGlmZmVyZW5jZXMgaW4gY2VsbCB0eXBlLiBUaGlzIGlzIG1vcmUgZWZmaWNpZW50IHRoYW4gYW5hbHlzaW5nIGVhY2ggY2VsbCB0eXBlIHNlcGFyYXRlbHkgYW5kIGNvbXBhcmluZyB0aGUgcmVzdWx0cy4gRWFjaCBzdGF0aXN0aWNhbCB0ZXN0IHdlIGRvIHdpbGwgaW52b2x2ZSBjYWxsaW5nIG1hbnkgZmFsc2UgcG9zaXRpdmVzLiBXZSBjYW4gYWNoaWV2ZSB0aGUgc2FtZSBvdXRjb21lIGJ5IHBlcmZvcm1pbmcganVzdCBvbmUgc3RhdGlzdGljYWwgdGVzdC4NCg0KDQpUaGlzIGNhbiBiZSBkb25lIGJ5IHRlbGxpbmcgRGVndXN0IGFib3V0IHRoZSAqaGlkZGVuIGZhY3RvcnMqIGluIG91ciBkYXRhc2V0LiBUaGUgaGlkZGVuIGZhY3RvciBpbiB0aGlzIGRhdGFzZXQgaXMgd2hldGhlciB0aGUgc2FtcGxlIGlzIGZyb20gdGhlIGBiYXNhbGAgb3IgYGx1bWluYWxgIHNhbXBsZXMuIEluIG90aGVyIHdvcmRzLCB0aGlzIGlzIGEgdGVjaG5pY2FsIGZhY3RvciB0aGF0IGluZmx1ZW5jZXMgb3VyIHJlc3VsdHMgYnV0IG5vdCBhIGZhY3RvciB0aGF0IHdlIHdpc2ggdG8gY29tcGFyZS4gV2Ugb25seSBuZWVkIHRvIHNwZWNpZnkgd2hpY2ggc2FtcGxlcyBhcmUgZnJvbSBgYmFzYWxgIGFuZCBERUdVU1Qgd2lsbCBpbmZlciB0aGF0IHRoZSBvdGhlciBzYW1wbGVzIGJlbG9uZyB0byBhIGRpZmZlcmVudCBjZWxsIHR5cGUuIE90aGVyIGhpZGRlbiBmYWN0b3JzIHlvdSBtaWdodCBuZWVkIHRvIGluY2x1ZGUgY291bGQgYmUgKGRlcGVuZGluZyBvbiB0aGUgTURTIHBsb3QpIDotDQoNCi0gc2FtcGxlIGJhdGNoDQotIGdlbmRlcg0KDQpTZWUgYmVsb3cgZm9yIHRoZSBjb3JyZWN0IGNvbmZpZ3VyYXRpb24gdG8gaW5jbHVkZSB0aGUgaGlkZGVuIGZhY3RvcnMuDQoNCiFbXShtZWRpYS9oaWRkZW5fZmFjdG9yLlBORykNCg0KWW91IHNob3VsZCBzZWUgdGhhdCBvbiB0aGUgTURTIHBsb3QgdGhlIHNhbXBsZXMgY2x1c3RlciBhY2NvcmRpbmcgdG8gY2VsbCB0eXBlLiBIb3dldmVyLCB0aGlzIGlzIGZpbmUgYmVjYXVzZSB3ZSBhcmUgZ29pbmcgdG8gaW5jb3Jwb3JhdGUgdGhpcyBoaWRkZW4gZmFjdG9yIGluIHRoZSBhbmFseXNpcw0KDQohW10obWVkaWEvaGlkZGVuX2ZhY3Rvcl9iYXRjaGVzLlBORykNCg0KWW91IGFyZSBub3cgcmVhZHkgdG8gY29tcGxldGUgdGhlIGZpbmFsIHNlY3Rpb24gb24gW2Fubm90YXRpb24gYW5kIGVucmljaG1lbnQgYW5hbHlzaXNdKDAzLWVucmljaG1lbnQubmIuaHRtbCkNCg0KPGJyPg0KPGJyPg0KDQoNCg==