• Packages used
  • Case study
  • Preprocessing
  • Data Visualization
  • Differential Expression Analysis
  • Results inspection
  • Volcano plot
  • Gene Enrichment

Packages used

library(Biobase)
library(RColorBrewer)
library(pheatmap)
library(tidyverse)
library(edgeR)
library(DESeq2)
library(ashr)
library(RColorBrewer)
library(limma)
library(leukemiasEset)

In this lab we will perform a differential expression analysis starting from scratch.

Case study

Doxorubicin is a commonly prescribed cancer drug, but one of its side effects is cardiotoxicity. This drug damages heart cells by binding to the protein topoisomerase-II beta, or Top2b.

A 2x2 factorial experiment will be performed: 1.Two types of mice in this case: - genetically normal wild type (wt) - Top2b knockout mice (mice that have had Top2b removed from heart cells) (top2b)

2.Two treatments: - PBS control solution (pbs) - Doxorubicin (dox)

If doxorubicin requires Top2b to exert its cardiotoxic effect, Top2b knockout mice should not be affected by doxorubicin treatment. This is the hypothesis to be tested. The data contains measurements from 29,532 genes and 12 mice, with three replicates for each factor combination.

# First we load the three types of data
doxorrubicina_exprs<-as.matrix(read.csv("E:/02 Estudio/00 NOTAS IMPORTANTES/R - Notas/Datasets/doxorrubicina_exprs.csv",row.names=1))
doxorrubicina_pData<-read.csv("E:/02 Estudio/00 NOTAS IMPORTANTES/R - Notas/Datasets/doxorrubicina_pData.csv",row.names=1)
doxorrubicina_fData<-read.csv("E:/02 Estudio/00 NOTAS IMPORTANTES/R - Notas/Datasets/doxorrubicina_fData.csv", row.names = 1)   

# Then we create the object ExpressionSet
eset <- ExpressionSet(assayData = doxorrubicina_exprs,
                      phenoData = AnnotatedDataFrame(doxorrubicina_pData),
                      featureData = AnnotatedDataFrame(doxorrubicina_fData))

Preprocessing

# First we do the logarithmic transformation
exprs(eset) <- log(exprs(eset))

# We visualize the already transformed data (classified according to the genotype)
plotDensities(eset,  group = pData(eset)[, "genotype"], legend = "topright")

# We normalize the data by quantiles
exprs(eset) <- normalizeBetweenArrays(exprs(eset))

# We visualize again to compare the distribution after normalization
plotDensities(eset,  group = pData(eset)[, "genotype"], legend = "topright")

# Now we determine the genes that present an expression level greater than zero
keep <- rowMeans(exprs(eset)) > 0
sum(keep)
## [1] 18361
# We filter the selected genes
eset <- eset[keep]

# We visualize genes with an expression level greater than zero
plotDensities(eset, group = pData(eset)[,"genotype"], legend = "topright")

Data Visualization

# Next we look for the row that contains the expression data of Top2b in the data characteristics
top2b <- which(fData(eset)[, "symbol"] == "Top2b")
top2b
## [1] 3809
# We plot the expression of top2b against the genotype in a boxplot.
boxplot(exprs(eset)[top2b, ] ~ pData(eset)[, "genotype"],
        main = fData(eset)[top2b, ])

# Next, we use principal component analysis to check for sources of variation in the data and to check whether samples cluster by genotype (WT vs. Top2b null) and treatment (PBS vs. Dox).
plotMDS(eset, labels = pData(eset)[, "genotype"], gene.selection = "common") # by genotype

plotMDS(eset, labels = pData(eset)[, "treatment"], gene.selection = "common") # per treatment

# Interestingly, Top2b null samples cluster more tightly compared to wild-type samples. Three groups are formed. wild-type mice are separated by treatment, whereas Top2b knockout mice form one large group.

Differential Expression Analysis

After carrying out the multidimensional scaling analyses, it is observed that three groups are formed. wild-type mice are separated by treatment, whereas Top2b knockout mice form one large group. This supports the hypothesis that Top2b knockout mice are resistant to the cardiotoxic effects of doxorubicin. To test this formally a differential expression analysis will be performed.

To test the mechanism of doxorubicin-induced cardiotoxicity, three contrasts will be tested: 1. Response of wild-type (wt) mice to doxorubicin (dox) treatment 2. Response of top2b knockout mice (top2b) to doxorubicin (dox) treatment 3. Differences between top2b and wt mice in response to doxorubicin (dox) treatment

# First the design matrix without intercepts is constructed
group <- with(pData(eset), paste(genotype, treatment, sep = ".")) # A simple variable is created by combining genotype and treatment
group <- factor(group)
design <- model.matrix(~0 + group)
colnames(design) <- levels(group)

colSums(design)
## top2b.dox top2b.pbs    wt.dox    wt.pbs 
##         3         3         3         3
# Then the contrast matrix is built and the three aforementioned contrasts are tested.
cm <- makeContrasts(dox_wt = wt.dox - wt.pbs,
                    dox_top2b = top2b.dox - top2b.pbs,
                    interaction = (top2b.dox - top2b.pbs) - (wt.dox - wt.pbs),
                    levels = design)

# Finally the contrasts will be tested
cm
##            Contrasts
## Levels      dox_wt dox_top2b interaction
##   top2b.dox      0         1           1
##   top2b.pbs      0        -1          -1
##   wt.dox         1         0          -1
##   wt.pbs        -1         0           1
# Fits the model
fit <- lmFit(eset, design)

# Contrasts are adjusted
fit2 <- contrasts.fit(fit, contrasts = cm)

# The t statistic is calculated for the contrasts
fit2 <- eBayes(fit2)

# Results are summarized
results <- decideTests(fit2)
summary(results)
##        dox_wt dox_top2b interaction
## Down     3180         0        1254
## NotSig  12265     18361       15621
## Up       2916         0        1486
# A Venn diagram is created to visualize the results.
vennDiagram(results)

Results inspection

The results will be inspected later. Since several contrasts (comparisons between groups) have been carried out, it must be specified in each case which one is referred to by means of the “coef” argument (for example: coef=“dox_wt)

# It will be corroborated that it was modeled correctly by plotting the histogram of p values for each contrast performed.
stats_dox_wt <- topTable(fit2, coef = "dox_wt", number = nrow(fit2),
                         sort.by = "none") # For comparison of treatments in wt mice

stats_dox_top2b <- topTable(fit2, coef = "dox_top2b", number = nrow(fit2),
                            sort.by = "none") # For comparison of treatments in top2b mice

stats_interaction <- topTable(fit2, coef = "interaction", number = nrow(fit2),
                              sort.by = "none") # For comparison between wt and top2b mice

# Histograms are created for each case
hist(stats_dox_wt[, "P.Value"])

hist(stats_dox_top2b[,"P.Value"])

hist(stats_interaction[,"P.Value"])

Volcano plot

The volcano plot is one of the most popular plots and probably the most informative, as it summarizes both the rate of expression (logFC) and the statistical significance (p-value). It is a scatterplot of the log10-transformed negative p-values of the gene-specific test (on the y-axis) versus rate of expression (on the x-axis). The plot shows data points with low (highly significant) p-values appearing toward the top of the plot. The logFC values are used to determine the direction of change (up and down) that appears equidistant from the center. Features declared as differentially expressed are highlighted in red.

Fold change is a measurement that describes how much a quantity changes between an original measurement and a subsequent one. It is defined as the ratio between the two quantities; for quantities A and B, the fold change of B with respect to A is B/A. In other words, a change from 30 to 60 is defined as a change of 2.

The fold change is often used in microarray gene expression data analysis and RNA-Seq experiments to measure the change in the expression level of a gene. However, when the denominator is close to zero, the relationship is not stable and the fold change value can be disproportionately affected by measurement noise.

The magnitude of the differential expression will be displayed with a volcano graph (the 5 genes with the highest differential expression) for each case.

gene_symbols <- fit2$genes[, "symbol"] # First we extract the gene names to an independent variable

volcanoplot(fit2, coef = "dox_wt", highlight = 5, names = gene_symbols) # For comparison of treatments in wt mice

volcanoplot(fit2, coef = "dox_top2b", highlight = 5, names = gene_symbols) # For comparison of treatments in top2b mice

volcanoplot(fit2, coef = "interaction", highlight = 5, names = gene_symbols) # For comparison between wt and top2b mice

Gene Enrichment

Finally, pathway-level changes in response to doxorucibin treatment will be tested using KEGG. This will identify KEGG pathways that are enriched for differentially expressed genes more than expected by chance. In this case, the 5 most enriched genes will be shown.

entrez <- fit2$genes[, "entrez"] # We extract the IDs of the genes to an independent variable

# Enrichment analysis for comparison of treatments in wt mice

topKEGG(kegga(fit2, coef = "dox_wt", geneid = entrez, species = "Mm"), number = 5)  # Top5 most enriched genes
##                                                  Pathway  N Up Down
## mmu05322                    Systemic lupus erythematosus 77 37    1
## mmu03008               Ribosome biogenesis in eukaryotes 71 34    4
## mmu05412 Arrhythmogenic right ventricular cardiomyopathy 56  2   27
## mmu05330                             Allograft rejection 26 16    0
## mmu05332                       Graft-versus-host disease 26 16    0
##                  P.Up       P.Down
## mmu05322 8.678388e-10 9.999999e-01
## mmu03008 4.661802e-09 9.996444e-01
## mmu05412 9.997626e-01 4.555290e-07
## mmu05330 7.642645e-07 1.000000e+00
## mmu05332 7.642645e-07 1.000000e+00
# Enrichment analysis for comparison between wt and top2b mice

topKEGG(kegga(fit2, coef = "interaction", geneid = entrez, species = "Mm"), number = 5) # Top5 most enriched genes
##                                                  Pathway   N Up Down
## mmu05322                    Systemic lupus erythematosus  77  0   27
## mmu04613         Neutrophil extracellular trap formation 128  9   31
## mmu03008               Ribosome biogenesis in eukaryotes  71  1   19
## mmu05034                                      Alcoholism 133  9   27
## mmu05412 Arrhythmogenic right ventricular cardiomyopathy  56 16    1
##                  P.Up       P.Down
## mmu05322 1.000000e+00 8.289360e-12
## mmu04613 8.309868e-01 8.514544e-09
## mmu03008 9.988454e-01 1.277807e-06
## mmu05034 8.619950e-01 3.234677e-06
## mmu05412 2.388104e-05 9.893896e-01

One of the most enriched genes corresponds to a pathway for cardiomyopathy, so genes for this pathway would be worth further investigation. This analysis helps to better understand the effect of differentially expressed genes in the doxorubicin study.

LS0tDQp0aXRsZTogIkRpZmZlcmVudGlhbCBFeHByZXNzaW9uIGFuYWx5c2lzIg0KZW1haWw6IGFsZWphbmRyb3JleDk1QGdtYWlsLmNvbQ0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogVFJVRQ0KICAgIHRvY19mbG9hdDogVFJVRQ0KICAgIGNvZGVfZG93bmxvYWQ6IFRSVUUNCiAgICB0aGVtZTogdW5pdGVkDQogIGNzbDogYXBhLmNzbA0KLS0tDQoNCiMjIFBhY2thZ2VzIHVzZWQNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KEJpb2Jhc2UpDQpsaWJyYXJ5KFJDb2xvckJyZXdlcikNCmxpYnJhcnkocGhlYXRtYXApDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZWRnZVIpDQpsaWJyYXJ5KERFU2VxMikNCmxpYnJhcnkoYXNocikNCmxpYnJhcnkoUkNvbG9yQnJld2VyKQ0KbGlicmFyeShsaW1tYSkNCmxpYnJhcnkobGV1a2VtaWFzRXNldCkNCmBgYA0KDQpJbiB0aGlzIGxhYiB3ZSB3aWxsIHBlcmZvcm0gYSBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBhbmFseXNpcyBzdGFydGluZyBmcm9tIHNjcmF0Y2guDQoNCiMjIENhc2Ugc3R1ZHkNCg0KRG94b3J1YmljaW4gaXMgYSBjb21tb25seSBwcmVzY3JpYmVkIGNhbmNlciBkcnVnLCBidXQgb25lIG9mIGl0cyBzaWRlIGVmZmVjdHMgaXMgY2FyZGlvdG94aWNpdHkuIFRoaXMgZHJ1ZyBkYW1hZ2VzIGhlYXJ0IGNlbGxzIGJ5IGJpbmRpbmcgdG8gdGhlIHByb3RlaW4gdG9wb2lzb21lcmFzZS1JSSBiZXRhLCBvciBUb3AyYi4NCg0KQSAyeDIgZmFjdG9yaWFsIGV4cGVyaW1lbnQgd2lsbCBiZSBwZXJmb3JtZWQ6DQoxLlR3byB0eXBlcyBvZiBtaWNlIGluIHRoaXMgY2FzZToNCi0gZ2VuZXRpY2FsbHkgbm9ybWFsIHdpbGQgdHlwZSAod3QpDQotIFRvcDJiIGtub2Nrb3V0IG1pY2UgKG1pY2UgdGhhdCBoYXZlIGhhZCBUb3AyYiByZW1vdmVkIGZyb20gaGVhcnQgY2VsbHMpICh0b3AyYikNCg0KMi5Ud28gdHJlYXRtZW50czoNCi0gUEJTIGNvbnRyb2wgc29sdXRpb24gKHBicykNCi0gRG94b3J1YmljaW4gKGRveCkNCg0KSWYgZG94b3J1YmljaW4gcmVxdWlyZXMgVG9wMmIgdG8gZXhlcnQgaXRzIGNhcmRpb3RveGljIGVmZmVjdCwgVG9wMmIga25vY2tvdXQgbWljZSBzaG91bGQgbm90IGJlIGFmZmVjdGVkIGJ5IGRveG9ydWJpY2luIHRyZWF0bWVudC4gVGhpcyBpcyB0aGUgaHlwb3RoZXNpcyB0byBiZSB0ZXN0ZWQuDQpUaGUgZGF0YSBjb250YWlucyBtZWFzdXJlbWVudHMgZnJvbSAyOSw1MzIgZ2VuZXMgYW5kIDEyIG1pY2UsIHdpdGggdGhyZWUgcmVwbGljYXRlcyBmb3IgZWFjaCBmYWN0b3IgY29tYmluYXRpb24uDQoNCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQ0KIyBGaXJzdCB3ZSBsb2FkIHRoZSB0aHJlZSB0eXBlcyBvZiBkYXRhDQpkb3hvcnJ1YmljaW5hX2V4cHJzPC1hcy5tYXRyaXgocmVhZC5jc3YoIkU6LzAyIEVzdHVkaW8vMDAgTk9UQVMgSU1QT1JUQU5URVMvUiAtIE5vdGFzL0RhdGFzZXRzL2RveG9ycnViaWNpbmFfZXhwcnMuY3N2Iixyb3cubmFtZXM9MSkpDQpkb3hvcnJ1YmljaW5hX3BEYXRhPC1yZWFkLmNzdigiRTovMDIgRXN0dWRpby8wMCBOT1RBUyBJTVBPUlRBTlRFUy9SIC0gTm90YXMvRGF0YXNldHMvZG94b3JydWJpY2luYV9wRGF0YS5jc3YiLHJvdy5uYW1lcz0xKQ0KZG94b3JydWJpY2luYV9mRGF0YTwtcmVhZC5jc3YoIkU6LzAyIEVzdHVkaW8vMDAgTk9UQVMgSU1QT1JUQU5URVMvUiAtIE5vdGFzL0RhdGFzZXRzL2RveG9ycnViaWNpbmFfZkRhdGEuY3N2Iiwgcm93Lm5hbWVzID0gMSkgICANCg0KIyBUaGVuIHdlIGNyZWF0ZSB0aGUgb2JqZWN0IEV4cHJlc3Npb25TZXQNCmVzZXQgPC0gRXhwcmVzc2lvblNldChhc3NheURhdGEgPSBkb3hvcnJ1YmljaW5hX2V4cHJzLA0KICAgICAgICAgICAgICAgICAgICAgIHBoZW5vRGF0YSA9IEFubm90YXRlZERhdGFGcmFtZShkb3hvcnJ1YmljaW5hX3BEYXRhKSwNCiAgICAgICAgICAgICAgICAgICAgICBmZWF0dXJlRGF0YSA9IEFubm90YXRlZERhdGFGcmFtZShkb3hvcnJ1YmljaW5hX2ZEYXRhKSkNCg0KDQpgYGANCg0KDQojIyBQcmVwcm9jZXNzaW5nDQoNCmBgYHtyfQ0KIyBGaXJzdCB3ZSBkbyB0aGUgbG9nYXJpdGhtaWMgdHJhbnNmb3JtYXRpb24NCmV4cHJzKGVzZXQpIDwtIGxvZyhleHBycyhlc2V0KSkNCg0KIyBXZSB2aXN1YWxpemUgdGhlIGFscmVhZHkgdHJhbnNmb3JtZWQgZGF0YSAoY2xhc3NpZmllZCBhY2NvcmRpbmcgdG8gdGhlIGdlbm90eXBlKQ0KcGxvdERlbnNpdGllcyhlc2V0LCAgZ3JvdXAgPSBwRGF0YShlc2V0KVssICJnZW5vdHlwZSJdLCBsZWdlbmQgPSAidG9wcmlnaHQiKQ0KDQojIFdlIG5vcm1hbGl6ZSB0aGUgZGF0YSBieSBxdWFudGlsZXMNCmV4cHJzKGVzZXQpIDwtIG5vcm1hbGl6ZUJldHdlZW5BcnJheXMoZXhwcnMoZXNldCkpDQoNCiMgV2UgdmlzdWFsaXplIGFnYWluIHRvIGNvbXBhcmUgdGhlIGRpc3RyaWJ1dGlvbiBhZnRlciBub3JtYWxpemF0aW9uDQpwbG90RGVuc2l0aWVzKGVzZXQsICBncm91cCA9IHBEYXRhKGVzZXQpWywgImdlbm90eXBlIl0sIGxlZ2VuZCA9ICJ0b3ByaWdodCIpDQoNCiMgTm93IHdlIGRldGVybWluZSB0aGUgZ2VuZXMgdGhhdCBwcmVzZW50IGFuIGV4cHJlc3Npb24gbGV2ZWwgZ3JlYXRlciB0aGFuIHplcm8NCmtlZXAgPC0gcm93TWVhbnMoZXhwcnMoZXNldCkpID4gMA0Kc3VtKGtlZXApDQoNCiMgV2UgZmlsdGVyIHRoZSBzZWxlY3RlZCBnZW5lcw0KZXNldCA8LSBlc2V0W2tlZXBdDQoNCiMgV2UgdmlzdWFsaXplIGdlbmVzIHdpdGggYW4gZXhwcmVzc2lvbiBsZXZlbCBncmVhdGVyIHRoYW4gemVybw0KcGxvdERlbnNpdGllcyhlc2V0LCBncm91cCA9IHBEYXRhKGVzZXQpWywiZ2Vub3R5cGUiXSwgbGVnZW5kID0gInRvcHJpZ2h0IikNCmBgYA0KDQojIyBEYXRhIFZpc3VhbGl6YXRpb24NCg0KYGBge3IsIHdhcm5pbmc9RkFMU0V9DQojIE5leHQgd2UgbG9vayBmb3IgdGhlIHJvdyB0aGF0IGNvbnRhaW5zIHRoZSBleHByZXNzaW9uIGRhdGEgb2YgVG9wMmIgaW4gdGhlIGRhdGEgY2hhcmFjdGVyaXN0aWNzDQp0b3AyYiA8LSB3aGljaChmRGF0YShlc2V0KVssICJzeW1ib2wiXSA9PSAiVG9wMmIiKQ0KdG9wMmINCg0KIyBXZSBwbG90IHRoZSBleHByZXNzaW9uIG9mIHRvcDJiIGFnYWluc3QgdGhlIGdlbm90eXBlIGluIGEgYm94cGxvdC4NCmJveHBsb3QoZXhwcnMoZXNldClbdG9wMmIsIF0gfiBwRGF0YShlc2V0KVssICJnZW5vdHlwZSJdLA0KICAgICAgICBtYWluID0gZkRhdGEoZXNldClbdG9wMmIsIF0pDQoNCiMgTmV4dCwgd2UgdXNlIHByaW5jaXBhbCBjb21wb25lbnQgYW5hbHlzaXMgdG8gY2hlY2sgZm9yIHNvdXJjZXMgb2YgdmFyaWF0aW9uIGluIHRoZSBkYXRhIGFuZCB0byBjaGVjayB3aGV0aGVyIHNhbXBsZXMgY2x1c3RlciBieSBnZW5vdHlwZSAoV1QgdnMuIFRvcDJiIG51bGwpIGFuZCB0cmVhdG1lbnQgKFBCUyB2cy4gRG94KS4NCnBsb3RNRFMoZXNldCwgbGFiZWxzID0gcERhdGEoZXNldClbLCAiZ2Vub3R5cGUiXSwgZ2VuZS5zZWxlY3Rpb24gPSAiY29tbW9uIikgIyBieSBnZW5vdHlwZQ0KDQpwbG90TURTKGVzZXQsIGxhYmVscyA9IHBEYXRhKGVzZXQpWywgInRyZWF0bWVudCJdLCBnZW5lLnNlbGVjdGlvbiA9ICJjb21tb24iKSAjIHBlciB0cmVhdG1lbnQNCg0KIyBJbnRlcmVzdGluZ2x5LCBUb3AyYiBudWxsIHNhbXBsZXMgY2x1c3RlciBtb3JlIHRpZ2h0bHkgY29tcGFyZWQgdG8gd2lsZC10eXBlIHNhbXBsZXMuIFRocmVlIGdyb3VwcyBhcmUgZm9ybWVkLiB3aWxkLXR5cGUgbWljZSBhcmUgc2VwYXJhdGVkIGJ5IHRyZWF0bWVudCwgd2hlcmVhcyBUb3AyYiBrbm9ja291dCBtaWNlIGZvcm0gb25lIGxhcmdlIGdyb3VwLg0KYGBgDQoNCiMjIERpZmZlcmVudGlhbCBFeHByZXNzaW9uIEFuYWx5c2lzDQoNCkFmdGVyIGNhcnJ5aW5nIG91dCB0aGUgbXVsdGlkaW1lbnNpb25hbCBzY2FsaW5nIGFuYWx5c2VzLCBpdCBpcyBvYnNlcnZlZCB0aGF0IHRocmVlIGdyb3VwcyBhcmUgZm9ybWVkLiB3aWxkLXR5cGUgbWljZSBhcmUgc2VwYXJhdGVkIGJ5IHRyZWF0bWVudCwgd2hlcmVhcyBUb3AyYiBrbm9ja291dCBtaWNlIGZvcm0gb25lIGxhcmdlIGdyb3VwLiBUaGlzIHN1cHBvcnRzIHRoZSBoeXBvdGhlc2lzIHRoYXQgVG9wMmIga25vY2tvdXQgbWljZSBhcmUgcmVzaXN0YW50IHRvIHRoZSBjYXJkaW90b3hpYyBlZmZlY3RzIG9mIGRveG9ydWJpY2luLg0KVG8gdGVzdCB0aGlzIGZvcm1hbGx5IGEgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24gYW5hbHlzaXMgd2lsbCBiZSBwZXJmb3JtZWQuDQoNClRvIHRlc3QgdGhlIG1lY2hhbmlzbSBvZiBkb3hvcnViaWNpbi1pbmR1Y2VkIGNhcmRpb3RveGljaXR5LCB0aHJlZSBjb250cmFzdHMgd2lsbCBiZSB0ZXN0ZWQ6DQoxLiBSZXNwb25zZSBvZiB3aWxkLXR5cGUgKHd0KSBtaWNlIHRvIGRveG9ydWJpY2luIChkb3gpIHRyZWF0bWVudA0KMi4gUmVzcG9uc2Ugb2YgdG9wMmIga25vY2tvdXQgbWljZSAodG9wMmIpIHRvIGRveG9ydWJpY2luIChkb3gpIHRyZWF0bWVudA0KMy4gRGlmZmVyZW5jZXMgYmV0d2VlbiB0b3AyYiBhbmQgd3QgbWljZSBpbiByZXNwb25zZSB0byBkb3hvcnViaWNpbiAoZG94KSB0cmVhdG1lbnQNCg0KYGBge3IsIHdhcm5pbmc9RkFMU0V9DQojIEZpcnN0IHRoZSBkZXNpZ24gbWF0cml4IHdpdGhvdXQgaW50ZXJjZXB0cyBpcyBjb25zdHJ1Y3RlZA0KZ3JvdXAgPC0gd2l0aChwRGF0YShlc2V0KSwgcGFzdGUoZ2Vub3R5cGUsIHRyZWF0bWVudCwgc2VwID0gIi4iKSkgIyBBIHNpbXBsZSB2YXJpYWJsZSBpcyBjcmVhdGVkIGJ5IGNvbWJpbmluZyBnZW5vdHlwZSBhbmQgdHJlYXRtZW50DQpncm91cCA8LSBmYWN0b3IoZ3JvdXApDQpkZXNpZ24gPC0gbW9kZWwubWF0cml4KH4wICsgZ3JvdXApDQpjb2xuYW1lcyhkZXNpZ24pIDwtIGxldmVscyhncm91cCkNCg0KY29sU3VtcyhkZXNpZ24pDQogDQojIFRoZW4gdGhlIGNvbnRyYXN0IG1hdHJpeCBpcyBidWlsdCBhbmQgdGhlIHRocmVlIGFmb3JlbWVudGlvbmVkIGNvbnRyYXN0cyBhcmUgdGVzdGVkLg0KY20gPC0gbWFrZUNvbnRyYXN0cyhkb3hfd3QgPSB3dC5kb3ggLSB3dC5wYnMsDQogICAgICAgICAgICAgICAgICAgIGRveF90b3AyYiA9IHRvcDJiLmRveCAtIHRvcDJiLnBicywNCiAgICAgICAgICAgICAgICAgICAgaW50ZXJhY3Rpb24gPSAodG9wMmIuZG94IC0gdG9wMmIucGJzKSAtICh3dC5kb3ggLSB3dC5wYnMpLA0KICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBkZXNpZ24pDQoNCiMgRmluYWxseSB0aGUgY29udHJhc3RzIHdpbGwgYmUgdGVzdGVkDQpjbQ0KDQojIEZpdHMgdGhlIG1vZGVsDQpmaXQgPC0gbG1GaXQoZXNldCwgZGVzaWduKQ0KDQojIENvbnRyYXN0cyBhcmUgYWRqdXN0ZWQNCmZpdDIgPC0gY29udHJhc3RzLmZpdChmaXQsIGNvbnRyYXN0cyA9IGNtKQ0KDQojIFRoZSB0IHN0YXRpc3RpYyBpcyBjYWxjdWxhdGVkIGZvciB0aGUgY29udHJhc3RzDQpmaXQyIDwtIGVCYXllcyhmaXQyKQ0KDQojIFJlc3VsdHMgYXJlIHN1bW1hcml6ZWQNCnJlc3VsdHMgPC0gZGVjaWRlVGVzdHMoZml0MikNCnN1bW1hcnkocmVzdWx0cykNCg0KIyBBIFZlbm4gZGlhZ3JhbSBpcyBjcmVhdGVkIHRvIHZpc3VhbGl6ZSB0aGUgcmVzdWx0cy4NCnZlbm5EaWFncmFtKHJlc3VsdHMpDQpgYGANCg0KIyMgUmVzdWx0cyBpbnNwZWN0aW9uDQoNClRoZSByZXN1bHRzIHdpbGwgYmUgaW5zcGVjdGVkIGxhdGVyLg0KU2luY2Ugc2V2ZXJhbCBjb250cmFzdHMgKGNvbXBhcmlzb25zIGJldHdlZW4gZ3JvdXBzKSBoYXZlIGJlZW4gY2FycmllZCBvdXQsIGl0IG11c3QgYmUgc3BlY2lmaWVkIGluIGVhY2ggY2FzZSB3aGljaCBvbmUgaXMgcmVmZXJyZWQgdG8gYnkgbWVhbnMgb2YgdGhlICJjb2VmIiBhcmd1bWVudCAoZm9yIGV4YW1wbGU6IGNvZWY9ImRveF93dCkNCg0KYGBge3IsIHdhcm5pbmc9RkFMU0V9DQojIEl0IHdpbGwgYmUgY29ycm9ib3JhdGVkIHRoYXQgaXQgd2FzIG1vZGVsZWQgY29ycmVjdGx5IGJ5IHBsb3R0aW5nIHRoZSBoaXN0b2dyYW0gb2YgcCB2YWx1ZXMgZm9yIGVhY2ggY29udHJhc3QgcGVyZm9ybWVkLg0Kc3RhdHNfZG94X3d0IDwtIHRvcFRhYmxlKGZpdDIsIGNvZWYgPSAiZG94X3d0IiwgbnVtYmVyID0gbnJvdyhmaXQyKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBzb3J0LmJ5ID0gIm5vbmUiKSAjIEZvciBjb21wYXJpc29uIG9mIHRyZWF0bWVudHMgaW4gd3QgbWljZQ0KDQpzdGF0c19kb3hfdG9wMmIgPC0gdG9wVGFibGUoZml0MiwgY29lZiA9ICJkb3hfdG9wMmIiLCBudW1iZXIgPSBucm93KGZpdDIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvcnQuYnkgPSAibm9uZSIpICMgRm9yIGNvbXBhcmlzb24gb2YgdHJlYXRtZW50cyBpbiB0b3AyYiBtaWNlDQoNCnN0YXRzX2ludGVyYWN0aW9uIDwtIHRvcFRhYmxlKGZpdDIsIGNvZWYgPSAiaW50ZXJhY3Rpb24iLCBudW1iZXIgPSBucm93KGZpdDIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc29ydC5ieSA9ICJub25lIikgIyBGb3IgY29tcGFyaXNvbiBiZXR3ZWVuIHd0IGFuZCB0b3AyYiBtaWNlDQoNCiMgSGlzdG9ncmFtcyBhcmUgY3JlYXRlZCBmb3IgZWFjaCBjYXNlDQpoaXN0KHN0YXRzX2RveF93dFssICJQLlZhbHVlIl0pDQpoaXN0KHN0YXRzX2RveF90b3AyYlssIlAuVmFsdWUiXSkNCmhpc3Qoc3RhdHNfaW50ZXJhY3Rpb25bLCJQLlZhbHVlIl0pDQoNCmBgYA0KDQojIyBWb2xjYW5vIHBsb3QNCg0KVGhlIHZvbGNhbm8gcGxvdCBpcyBvbmUgb2YgdGhlIG1vc3QgcG9wdWxhciBwbG90cyBhbmQgcHJvYmFibHkgdGhlIG1vc3QgaW5mb3JtYXRpdmUsIGFzIGl0IHN1bW1hcml6ZXMgYm90aCB0aGUgcmF0ZSBvZiBleHByZXNzaW9uIChsb2dGQykgYW5kIHRoZSBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2UgKHAtdmFsdWUpLiBJdCBpcyBhIHNjYXR0ZXJwbG90IG9mIHRoZSBsb2cxMC10cmFuc2Zvcm1lZCBuZWdhdGl2ZSBwLXZhbHVlcyBvZiB0aGUgZ2VuZS1zcGVjaWZpYyB0ZXN0IChvbiB0aGUgeS1heGlzKSB2ZXJzdXMgcmF0ZSBvZiBleHByZXNzaW9uIChvbiB0aGUgeC1heGlzKS4gVGhlIHBsb3Qgc2hvd3MgZGF0YSBwb2ludHMgd2l0aCBsb3cgKGhpZ2hseSBzaWduaWZpY2FudCkgcC12YWx1ZXMgYXBwZWFyaW5nIHRvd2FyZCB0aGUgdG9wIG9mIHRoZSBwbG90LiBUaGUgbG9nRkMgdmFsdWVzIGFyZSB1c2VkIHRvIGRldGVybWluZSB0aGUgZGlyZWN0aW9uIG9mIGNoYW5nZSAodXAgYW5kIGRvd24pIHRoYXQgYXBwZWFycyBlcXVpZGlzdGFudCBmcm9tIHRoZSBjZW50ZXIuIEZlYXR1cmVzIGRlY2xhcmVkIGFzIGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBhcmUgaGlnaGxpZ2h0ZWQgaW4gcmVkLg0KDQpGb2xkIGNoYW5nZSBpcyBhIG1lYXN1cmVtZW50IHRoYXQgZGVzY3JpYmVzIGhvdyBtdWNoIGEgcXVhbnRpdHkgY2hhbmdlcyBiZXR3ZWVuIGFuIG9yaWdpbmFsIG1lYXN1cmVtZW50IGFuZCBhIHN1YnNlcXVlbnQgb25lLiBJdCBpcyBkZWZpbmVkIGFzIHRoZSByYXRpbyBiZXR3ZWVuIHRoZSB0d28gcXVhbnRpdGllczsgZm9yIHF1YW50aXRpZXMgQSBhbmQgQiwgdGhlIGZvbGQgY2hhbmdlIG9mIEIgd2l0aCByZXNwZWN0IHRvIEEgaXMgQi9BLiBJbiBvdGhlciB3b3JkcywgYSBjaGFuZ2UgZnJvbSAzMCB0byA2MCBpcyBkZWZpbmVkIGFzIGEgY2hhbmdlIG9mIDIuDQoNClRoZSBmb2xkIGNoYW5nZSBpcyBvZnRlbiB1c2VkIGluIG1pY3JvYXJyYXkgZ2VuZSBleHByZXNzaW9uIGRhdGEgYW5hbHlzaXMgYW5kIFJOQS1TZXEgZXhwZXJpbWVudHMgdG8gbWVhc3VyZSB0aGUgY2hhbmdlIGluIHRoZSBleHByZXNzaW9uIGxldmVsIG9mIGEgZ2VuZS4gSG93ZXZlciwgd2hlbiB0aGUgZGVub21pbmF0b3IgaXMgY2xvc2UgdG8gemVybywgdGhlIHJlbGF0aW9uc2hpcCBpcyBub3Qgc3RhYmxlIGFuZCB0aGUgZm9sZCBjaGFuZ2UgdmFsdWUgY2FuIGJlIGRpc3Byb3BvcnRpb25hdGVseSBhZmZlY3RlZCBieSBtZWFzdXJlbWVudCBub2lzZS4NCg0KVGhlIG1hZ25pdHVkZSBvZiB0aGUgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24gd2lsbCBiZSBkaXNwbGF5ZWQgd2l0aCBhIHZvbGNhbm8gZ3JhcGggKHRoZSA1IGdlbmVzIHdpdGggdGhlIGhpZ2hlc3QgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24pIGZvciBlYWNoIGNhc2UuDQoNCmBgYHtyfQ0KZ2VuZV9zeW1ib2xzIDwtIGZpdDIkZ2VuZXNbLCAic3ltYm9sIl0gIyBGaXJzdCB3ZSBleHRyYWN0IHRoZSBnZW5lIG5hbWVzIHRvIGFuIGluZGVwZW5kZW50IHZhcmlhYmxlDQoNCnZvbGNhbm9wbG90KGZpdDIsIGNvZWYgPSAiZG94X3d0IiwgaGlnaGxpZ2h0ID0gNSwgbmFtZXMgPSBnZW5lX3N5bWJvbHMpICMgRm9yIGNvbXBhcmlzb24gb2YgdHJlYXRtZW50cyBpbiB3dCBtaWNlDQoNCnZvbGNhbm9wbG90KGZpdDIsIGNvZWYgPSAiZG94X3RvcDJiIiwgaGlnaGxpZ2h0ID0gNSwgbmFtZXMgPSBnZW5lX3N5bWJvbHMpICMgRm9yIGNvbXBhcmlzb24gb2YgdHJlYXRtZW50cyBpbiB0b3AyYiBtaWNlDQoNCnZvbGNhbm9wbG90KGZpdDIsIGNvZWYgPSAiaW50ZXJhY3Rpb24iLCBoaWdobGlnaHQgPSA1LCBuYW1lcyA9IGdlbmVfc3ltYm9scykgIyBGb3IgY29tcGFyaXNvbiBiZXR3ZWVuIHd0IGFuZCB0b3AyYiBtaWNlDQoNCmBgYA0KDQojIyBHZW5lIEVucmljaG1lbnQNCg0KRmluYWxseSwgcGF0aHdheS1sZXZlbCBjaGFuZ2VzIGluIHJlc3BvbnNlIHRvIGRveG9ydWNpYmluIHRyZWF0bWVudCB3aWxsIGJlIHRlc3RlZCB1c2luZyBLRUdHLiBUaGlzIHdpbGwgaWRlbnRpZnkgS0VHRyBwYXRod2F5cyB0aGF0IGFyZSBlbnJpY2hlZCBmb3IgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIGdlbmVzIG1vcmUgdGhhbiBleHBlY3RlZCBieSBjaGFuY2UuIEluIHRoaXMgY2FzZSwgdGhlIDUgbW9zdCBlbnJpY2hlZCBnZW5lcyB3aWxsIGJlIHNob3duLg0KDQpgYGB7cn0NCmVudHJleiA8LSBmaXQyJGdlbmVzWywgImVudHJleiJdICMgV2UgZXh0cmFjdCB0aGUgSURzIG9mIHRoZSBnZW5lcyB0byBhbiBpbmRlcGVuZGVudCB2YXJpYWJsZQ0KDQojIEVucmljaG1lbnQgYW5hbHlzaXMgZm9yIGNvbXBhcmlzb24gb2YgdHJlYXRtZW50cyBpbiB3dCBtaWNlDQoNCnRvcEtFR0coa2VnZ2EoZml0MiwgY29lZiA9ICJkb3hfd3QiLCBnZW5laWQgPSBlbnRyZXosIHNwZWNpZXMgPSAiTW0iKSwgbnVtYmVyID0gNSkgICMgVG9wNSBtb3N0IGVucmljaGVkIGdlbmVzDQoNCiMgRW5yaWNobWVudCBhbmFseXNpcyBmb3IgY29tcGFyaXNvbiBiZXR3ZWVuIHd0IGFuZCB0b3AyYiBtaWNlDQoNCnRvcEtFR0coa2VnZ2EoZml0MiwgY29lZiA9ICJpbnRlcmFjdGlvbiIsIGdlbmVpZCA9IGVudHJleiwgc3BlY2llcyA9ICJNbSIpLCBudW1iZXIgPSA1KSAjIFRvcDUgbW9zdCBlbnJpY2hlZCBnZW5lcw0KDQpgYGANCg0KT25lIG9mIHRoZSBtb3N0IGVucmljaGVkIGdlbmVzIGNvcnJlc3BvbmRzIHRvIGEgcGF0aHdheSBmb3IgY2FyZGlvbXlvcGF0aHksIHNvIGdlbmVzIGZvciB0aGlzIHBhdGh3YXkgd291bGQgYmUgd29ydGggZnVydGhlciBpbnZlc3RpZ2F0aW9uLiBUaGlzIGFuYWx5c2lzIGhlbHBzIHRvIGJldHRlciB1bmRlcnN0YW5kIHRoZSBlZmZlY3Qgb2YgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIGdlbmVzIGluIHRoZSBkb3hvcnViaWNpbiBzdHVkeS4NCg0KDQoNCg==