index.html

1 Repeat a previous set of analyses and see where we differ

I am going to intersperse the original comments and code, then compare with my own analyses.

#metacyclic to 4-hr amastigote transition and the amastigote samples across timepoints.
#This log is for parasite samples only using the count table restricted to CDS only.

#Count table generation is described in logs:
#lminfectome_dillonl_20141001_TopHat_HTSeq_Count_Table_hg19_Lamazonensis_Lmajor_beads_HPGL0434-446_452-472_cecilia.log
#lminfectome_dillonl_20141211_TopHat_HTSeq_Count_Table_hg19_Lamazonensis_Lmajor_beads_HPGL0491-510_cecilia.log

#Lmexicana81 (L. amazonensis) samples
#Name           condition       batch
#HPGL0435       metac           D
#HPGL0437       amastLA4        D
#HPGL0440       amastLA24       D
#HPGL0443       amastLA48       D
#HPGL0446       amastLA72       D
#HPGL0454       metac           E
#HPGL0458       amastLA4        E
#HPGL0462       amastLA24       E
#HPGL0466       amastLA48       E
#HPGL0470       amastLA72       E
#HPGL0492       metac           F
#HPGL0496       amastLA4        F
#HPGL0500       amastLA24       F
#HPGL0504       amastLA48       F
#HPGL0508       amastLA72       F
#Count table is:
#20141211_Lmexicana81_434-435_437_440_443_446_453-454_458_462_466_470_491-492_496_500_504_508_CDSonly.count
#Includes headers

#7-28-15
#L. amazonensis
#Create diagnostic plots
#Hector recommended that all diagnostics be done using the rawest data possible. For correlation analyses between samples,
#use countsTable data without filtering out lowly expressed genes and without normalization. Size factor normalization
#will be used to show the distribution of gene expression levels.

#This analysis uses count tables that have not been restricted to _CDS only.
library(cbcbSEQ)
## Loading required package: limma
## Loading required package: corpcor
## Loading required package: preprocessCore
## Loading required package: sva
## Loading required package: mgcv
## Loading required package: nlme
## This is mgcv 1.8-23. For overview type 'help("mgcv-package")'.
## Loading required package: genefilter
## Loading required package: BiocParallel
## 
## Attaching package: 'cbcbSEQ'
## The following object is masked from 'package:hpgltools':
## 
##     pcRes
library(gplots)
## 
## Attaching package: 'gplots'
## The following object is masked from 'package:stats':
## 
##     lowess
library(matrixStats)
## 
## Attaching package: 'matrixStats'
## The following objects are masked from 'package:genefilter':
## 
##     rowSds, rowVars
library(siggenes)
## Loading required package: Biobase
## Loading required package: BiocGenerics
## Loading required package: parallel
## 
## Attaching package: 'BiocGenerics'
## The following objects are masked from 'package:parallel':
## 
##     clusterApply, clusterApplyLB, clusterCall, clusterEvalQ,
##     clusterExport, clusterMap, parApply, parCapply, parLapply,
##     parLapplyLB, parRapply, parSapply, parSapplyLB
## The following object is masked from 'package:limma':
## 
##     plotMA
## The following objects are masked from 'package:stats':
## 
##     IQR, mad, sd, var, xtabs
## The following objects are masked from 'package:base':
## 
##     anyDuplicated, append, as.data.frame, cbind, colMeans,
##     colnames, colSums, do.call, duplicated, eval, evalq, Filter,
##     Find, get, grep, grepl, intersect, is.unsorted, lapply,
##     lengths, Map, mapply, match, mget, order, paste, pmax,
##     pmax.int, pmin, pmin.int, Position, rank, rbind, Reduce,
##     rowMeans, rownames, rowSums, sapply, setdiff, sort, table,
##     tapply, union, unique, unsplit, which, which.max, which.min
## Welcome to Bioconductor
## 
##     Vignettes contain introductory material; view with
##     'browseVignettes()'. To cite Bioconductor, see
##     'citation("Biobase")', and for packages 'citation("pkgname")'.
## 
## Attaching package: 'Biobase'
## The following objects are masked from 'package:matrixStats':
## 
##     anyMissing, rowMedians
## Loading required package: multtest
## 
## Attaching package: 'multtest'
## The following object is masked from 'package:gplots':
## 
##     wapply
## Loading required package: splines
library(ReportingTools)
## Loading required package: knitr
## 
## 
library(hwriter)
library(DESeq2)
## Loading required package: S4Vectors
## Loading required package: stats4
## 
## Attaching package: 'S4Vectors'
## The following object is masked from 'package:gplots':
## 
##     space
## The following object is masked from 'package:base':
## 
##     expand.grid
## Loading required package: IRanges
## 
## Attaching package: 'IRanges'
## The following object is masked from 'package:nlme':
## 
##     collapse
## Loading required package: GenomicRanges
## Loading required package: GenomeInfoDb
## Loading required package: SummarizedExperiment
## Loading required package: DelayedArray
## 
## Attaching package: 'DelayedArray'
## The following objects are masked from 'package:matrixStats':
## 
##     colMaxs, colMins, colRanges, rowMaxs, rowMins, rowRanges
## The following object is masked from 'package:base':
## 
##     apply
library(RColorBrewer)

#Read in counts table
countsTable <- read.table("preprocessing/dillonl/20141211_Lmexicana81_434-435_437_440_443_446_453-454_458_462_466_470_491-492_496_500_504_508_CDSonly.count.xz", header=TRUE)
#Remove id as an actual column, use as row names instead
rownames(countsTable) <- countsTable$id
countsTable <- countsTable[,-1]
#Restrict to samples of interest (exclude procyclic promastigote samples)
countsTable <- countsTable[,-c(1, 7, 13)]
head(countsTable, n=3L)
##                HPGL0435 HPGL0437 HPGL0440 HPGL0443 HPGL0446 HPGL0454
## LmxM.01.0010-1     1910      154       34       38       56     2255
## LmxM.01.0020-1     1103      370      119      162      277     1639
## LmxM.01.0030-1      849      211       60      100      195      789
##                HPGL0458 HPGL0462 HPGL0466 HPGL0470 HPGL0492 HPGL0496
## LmxM.01.0010-1      264      151      217      203     1512       51
## LmxM.01.0020-1     1153     1519     1315     1345     1528      153
## LmxM.01.0030-1      475      668      735      689      785       88
##                HPGL0500 HPGL0504 HPGL0508
## LmxM.01.0010-1       52       13        8
## LmxM.01.0020-1      225       62       66
## LmxM.01.0030-1      135       29       48
#               HPGL0435 HPGL0437 HPGL0440 HPGL0443 HPGL0446 HPGL0454 HPGL0458 HPGL0462 HPGL0466 HPGL0470 HPGL0492 HPGL0496 HPGL0500 HPGL0504 HPGL0508
#LmxM.01.0010-1     1910      154       34       38       56     2255      264      151      217      203     1512       51       52       13        8
#LmxM.01.0020-1     1103      370      119      162      277     1639     1153     1519     1315     1345     1528      153      225       62       66
#LmxM.01.0030-1      849      211       60      100      195      789      475      668      735      689      785       88      135       29       48
#Establish metadata for samples
sampleID <- colnames(countsTable)
condition <- rep(c("metac", "amast4", "amast24", "amast48", "amast72"), times=3)
batch <- rep(c("D", "E", "F"), each=5)
#Create condition and batch factor
condition <- factor(condition, levels=c("metac", "amast4", "amast24", "amast48", "amast72"))
batch <- factor(batch, levels=c("D", "E", "F"))
design <- data.frame(sampleID=sampleID, condition=condition, batch=batch)
design
##    sampleID condition batch
## 1  HPGL0435     metac     D
## 2  HPGL0437    amast4     D
## 3  HPGL0440   amast24     D
## 4  HPGL0443   amast48     D
## 5  HPGL0446   amast72     D
## 6  HPGL0454     metac     E
## 7  HPGL0458    amast4     E
## 8  HPGL0462   amast24     E
## 9  HPGL0466   amast48     E
## 10 HPGL0470   amast72     E
## 11 HPGL0492     metac     F
## 12 HPGL0496    amast4     F
## 13 HPGL0500   amast24     F
## 14 HPGL0504   amast48     F
## 15 HPGL0508   amast72     F
#   sampleID condition batch
#1  HPGL0435     metac     D
#2  HPGL0437    amast4     D
#3  HPGL0440   amast24     D
#4  HPGL0443   amast48     D
#5  HPGL0446   amast72     D
#6  HPGL0454     metac     E
#7  HPGL0458    amast4     E
#8  HPGL0462   amast24     E
#9  HPGL0466   amast48     E
#10 HPGL0470   amast72     E
#11 HPGL0492     metac     F
#12 HPGL0496    amast4     F
#13 HPGL0500   amast24     F
#14 HPGL0504   amast48     F
#15 HPGL0508   amast72     F
colnames(countsTable) <- paste(condition, batch, 1:length(condition), sep=".")

barplot(colSums(countsTable), las=3, ylim=c(0,3e+07))

#Normalize raw counts using DESeq size factors
df <- data.frame(cond=(condition))
dds <- DESeqDataSetFromMatrix(countData=countsTable, colData = df, design = ~ cond)
dds <- estimateSizeFactors(dds)
ncts <- counts(dds, normalized=TRUE)
y <- log(ncts + 1)

#Determine median and quantiles of the size factor normalized, log2 counts
median(y)
## [1] 5.789
#[1] 5.788727
quantile(y)
##     0%    25%    50%    75%   100% 
##  0.000  5.331  5.789  6.257 10.702
#       0%       25%       50%       75%      100%
# 0.000000  5.330752  5.788727  6.256596 10.701582
#Determine number of genes per sample with less than log2 of 2 counts (less than 4 counts per mill)
ydf <- as.data.frame(y)
colnames(ydf) <- sampleID

col.nam <- paste(condition, batch, 1:length(condition), sep=".")
#Boxplot of per sample log of size-factor-normalized counts (+ 1)
par(mar=c(10.5,4.5,2,1))
par(oma=c(0,0,0,0))
boxplot(y, names=col.nam, las=3)

#Heatmap of Pearson correlation between samples
#(delete Rowv, Colv, and dendrogram parameters if want samples to sort and show dendrogram)
#Correlation analysis (Pearson is default for cor unless othewise specified)
#Using raw counts
datCor <- cor(countsTable)
heatmap.2(datCor, Rowv=NA, Colv=NA,
          margins=c(10, 10),
          labRow=col.nam,
          labCol=col.nam,
          dendrogram="none",
          scale="none",
          trace="none",
          srtCol=45)

#Median pairwise correlation
#Using raw counts
corM <- matrixStats::rowMedians(cor(countsTable))
qs <- quantile(corM,p=c(1,3)/4)
iqr <- diff(qs)
outLimit <- qs[1] - 1.5 * iqr

ylim <- c(pmin(min(corM),outLimit),max(corM))
col <-  ifelse(condition=="amast4", "cornflowerblue",
        ifelse(condition=="amast24", "gold",
        ifelse(condition=="amast48", "green3",
        ifelse(condition=="amast72", "coral", "mediumorchid4"))))

plot(corM, xaxt="n", ylim=ylim, ylab="Median Pairwise Correlation", xlab="", main="", col=col, pch=16, cex=2.2)
axis(side=1,at=seq(along=corM),labels=paste(condition,batch,sep=":"),las=2)
abline(h=outLimit,lty=2)
abline(v=1:length(col.nam), lty=3, col="black")

#Plot without IQR cutoff
#Use filterCounts method to filter for low counts
#Define filterCounts function

filterCounts = function (counts, lib.size = NULL, thresh = 1, minSamples = 2) {
    cpms <- 2^log2CPM(counts, lib.size = lib.size)$y
    keep <- rowSums(cpms > thresh) >= minSamples
    counts <- counts[keep, ]
    counts
}
x <- table(condition)
dim(countsTable)
## [1] 8336   15
#[1] 8336   15
counts <- filterCounts(countsTable, thresh=1, minSamples=min(x))
dim(counts)
## [1] 8310   15
#[1] 8310   15
#Quantile normalize counts
countsSubQ <- qNorm(counts)
#Explore data for batch effects
#Transform data to log2 counts per million
x <- log2CPM(countsSubQ)
#Compute principal components
s <- makeSVD(x$y)
#Compute variance of each PC and how they correlate with batch and condition
pcRes(s$v, s$d, condition, batch)
##    propVar cumPropVar cond.R2 batch.R2
## 1    59.12      59.12   96.62     2.72
## 2     9.04      68.16   75.86    11.13
## 3     6.50      74.66   21.37    38.43
## 4     5.03      79.69   14.54    67.85
## 5     4.03      83.72    1.61    48.30
## 6     3.36      87.08   26.63    17.28
## 7     2.85      89.93   18.80     5.67
## 8     2.52      92.45   48.05     0.46
## 9     1.77      94.22   12.92     3.09
## 10    1.67      95.89   19.51     0.70
## 11    1.37      97.26    9.44     0.57
## 12    1.21      98.47   16.94     0.59
## 13    1.10      99.57   11.11     3.03
## 14    0.44     100.01   26.60     0.18
#   propVar cumPropVar cond.R2 batch.R2
#1    59.12      59.12   96.62     2.72
#2     9.04      68.16   75.86    11.13
#3     6.50      74.66   21.37    38.43
#4     5.03      79.69   14.54    67.85
#5     4.03      83.72    1.61    48.30
#6     3.36      87.08   26.63    17.28
#7     2.85      89.93   18.80     5.67
#8     2.52      92.45   48.05     0.46
#9     1.77      94.22   12.92     3.09
#10    1.67      95.89   19.51     0.70
#11    1.37      97.26    9.44     0.57
#12    1.21      98.47   16.94     0.59
#13    1.10      99.57   11.11     3.03
#14    0.44     100.01   26.60     0.18


#Plot PC1 vs. PC2, with black outlines and color fills
#Save as eps
condnum <- as.numeric(condition)
plotPC(s$v,
       s$d,
       col="black",
       pch=ifelse(batch=="D", 25, ifelse(batch=="B", 21, ifelse(batch=="C", 22, ifelse(batch=="E", 24, 23)))),
       bg=ifelse(condnum==1, "mediumorchid4", ifelse(condnum==2, "cornflowerblue", ifelse(condnum==3, "gold", ifelse(condnum==4, "green3", "coral")))), cex=2.6
       )
legend(x=-0.23, y=0.39, legend=c("metac", "amast4", "amast24", "amast48", "amast72"), pch=22, col=0,
pt.bg=c("mediumorchid4", "cornflowerblue", "gold", "green3", "coral"), pt.cex=2.6, bty="n")
text(s$v[,1], s$v[,2], colnames(countsTable), cex=.7, pos=4)

#View as a Euclidean distance heatmap
dists <- dist(t(counts))
mat <- as.matrix(dists)
rownames(mat) <- colnames(mat) <- with(design, paste(colnames(countsTable)))
hmcol <- colorRampPalette(brewer.pal(9, "GnBu"))(100)
vec.batch <- rainbow(nlevels(batch), start=0, end=.8)
batch.color <- rep(0, length(batch))
for (i in 1:length(batch)) {
    batch.color[i] <- vec.batch[batch[i]==levels(batch)]
}
vec.condition <- c("mediumorchid4", "cornflowerblue", "gold", "green3", "coral")
condition.color <- rep(0, length(condition))
for (i in 1:length(condition)) {
    condition.color[i] <- vec.condition[condition[i]==levels(condition)]
}

heatmap <- heatmap.2(mat, trace="none", col = rev(hmcol), margin=c(11,11), ColSideColors=condition.color,
RowSideColors=batch.color, key="FALSE", srtCol=45)

dev.off()
## null device 
##           1
#I would like to create a PCA plot and heatmap to reflect the use of batch in the limma model
#Specify model
mod <- model.matrix(~batch)
#Use voom to determine weights for fitting the mean-variance trend for each gene
v <- voom(countsSubQ, mod)
#Fit the linear model for each gene
fit <- lmFit(v)
#Get the residual (i.e. everything except for the batch effect)
newData <- residuals(fit, v)
#Explore data for batch effects
#Compute principal components
s <- makeSVD(newData)
#Compute variance of each PC and how they correlate with batch and condition
pcRes(s$v, s$d, condition, batch)
##    propVar cumPropVar cond.R2 batch.R2
## 1    65.02      65.02   99.34        0
## 2     9.65      74.67   89.05        0
## 3     6.18      80.85   15.30        0
## 4     4.18      85.03   31.59        0
## 5     3.31      88.34   22.22        0
## 6     2.85      91.19   50.41        0
## 7     2.11      93.30   12.60        0
## 8     1.91      95.21   19.87        0
## 9     1.57      96.78    6.37        0
## 10    1.40      98.18   17.29        0
## 11    1.33      99.51   10.67        0
## 12    0.51     100.02   25.31        0
## 13    0.00     100.02    0.00      100
## 14    0.00     100.02    0.00      100
#   propVar cumPropVar cond.R2 batch.R2
#1    65.02      65.02   99.34        0
#2     9.65      74.67   89.05        0
#3     6.18      80.85   15.30        0
#4     4.18      85.03   31.59        0
#5     3.31      88.34   22.22        0
#6     2.85      91.19   50.41        0
#7     2.11      93.30   12.60        0
#8     1.91      95.21   19.87        0
#9     1.57      96.78    6.37        0
#10    1.40      98.18   17.29        0
#11    1.33      99.51   10.67        0
#12    0.51     100.02   25.31        0
#13    0.00     100.02    0.00      100
#14    0.00     100.02    0.00      100
#Plot PC1 vs. PC2, with black outlines and color fills

condnum <- as.numeric(condition)
plotPC(s$v,
       s$d,
       col="black",
       pch=ifelse(batch=="D", 25, ifelse(batch=="B", 21, ifelse(batch=="C", 22, ifelse(batch=="E", 24, 23)))),
       bg=ifelse(condnum==1, "mediumorchid4", ifelse(condnum==2, "cornflowerblue", ifelse(condnum==3, "gold", ifelse(condnum==4, "green3", "coral")))), cex=2.6
       )
legend(x=-0.48, y=-0.24, legend=c("metac", "amast4", "amast24", "amast48", "amast72"), pch=22, col=0,
pt.bg=c("mediumorchid4", "cornflowerblue", "gold", "green3", "coral"), pt.cex=2.6, bty="n")
text(s$v[,1], s$v[,2], colnames(countsTable), cex=.7, pos=4)
#View as a Euclidean distance heatmap
dists <- dist(t(newData))
mat <- as.matrix(dists)
rownames(mat) <- colnames(mat) <- with(design, paste(colnames(countsTable)))
hmcol <- colorRampPalette(brewer.pal(9, "GnBu"))(100)
vec.batch <- rainbow(nlevels(batch), start=0, end=.8)
batch.color <- rep(0, length(batch))
for (i in 1:length(batch)) {
    batch.color[i] <- vec.batch[batch[i]==levels(batch)]
}
vec.condition <- c("mediumorchid4", "cornflowerblue", "gold", "green3", "coral")
condition.color <- rep(0, length(condition))
for (i in 1:length(condition)) {
    condition.color[i] <- vec.condition[condition[i]==levels(condition)]
}
heatmap <- heatmap.2(mat, trace="none", col = rev(hmcol), margin=c(11,11), ColSideColors=condition.color,
RowSideColors=batch.color, key="FALSE", srtCol=45)

#############################
#############################
#DE analysis
#Quantile normalize counts
countsSubQ <- qNorm(counts)
#Specify model
mod = model.matrix(~0+condition+batch)
#View mean-variance trend
voom(countsSubQ, mod, plot=TRUE)
## An object of class "EList"
## $E
##                metac.D.1 amast4.D.2 amast24.D.3 amast48.D.4 amast72.D.5
## LmxM.01.0010-1     6.872      5.124       4.686       4.055       4.147
## LmxM.01.0020-1     6.183      6.444       6.524       6.220       6.580
## LmxM.01.0030-1     5.842      5.599       5.498       5.496       6.041
## LmxM.01.0040-1     5.248      5.579       5.340       4.670       4.986
## LmxM.01.0050-1     6.555      6.640       6.931       6.445       6.731
##                metac.E.6 amast4.E.7 amast24.E.8 amast48.E.9 amast72.E.10
## LmxM.01.0010-1     6.862      4.549       3.743       3.998        4.062
## LmxM.01.0020-1     6.435      6.784       7.028       6.728        6.909
## LmxM.01.0030-1     5.414      5.428       5.754       5.858        5.875
## LmxM.01.0040-1     5.578      5.712       5.873       5.459        5.637
## LmxM.01.0050-1     6.487      6.679       6.877       6.861        7.005
##                metac.F.11 amast4.F.12 amast24.F.13 amast48.F.14
## LmxM.01.0010-1      6.479       4.832        4.295        4.253
## LmxM.01.0020-1      6.495       6.449        6.411        6.373
## LmxM.01.0030-1      5.568       5.630        5.681        5.313
## LmxM.01.0040-1      5.368       4.744        5.248        4.985
## LmxM.01.0050-1      6.524       6.647        6.826        6.565
##                amast72.F.15
## LmxM.01.0010-1        3.286
## LmxM.01.0020-1        6.173
## LmxM.01.0030-1        5.695
## LmxM.01.0040-1        5.261
## LmxM.01.0050-1        6.744
## 8305 more rows ...
## 
## $weights
##       [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9]  [,10] [,11]
## [1,] 38.25 21.44 14.88 13.67 11.61 36.74 17.46 12.15 11.18  9.523 36.67
## [2,] 34.43 35.62 36.18 34.89 35.59 36.75 37.69 38.06 37.11 37.662 34.36
## [3,] 28.87 28.23 29.28 28.27 31.66 28.53 27.86 28.94 27.90 31.367 27.46
## [4,] 23.88 23.21 25.02 19.29 22.53 29.79 29.18 30.71 25.49 28.604 23.34
## [5,] 35.90 36.65 37.76 36.49 37.52 36.59 37.28 38.23 37.13 38.027 35.91
##      [,12] [,13] [,14]  [,15]
## [1,] 17.32 12.05 11.09  9.445
## [2,] 35.56 36.12 34.83 35.530
## [3,] 26.81 27.90 26.85 30.459
## [4,] 22.63 24.46 18.79 21.965
## [5,] 36.66 37.76 36.49 37.523
## 8305 more rows ...
## 
## $design
##   conditionmetac conditionamast4 conditionamast24 conditionamast48
## 1              1               0                0                0
## 2              0               1                0                0
## 3              0               0                1                0
## 4              0               0                0                1
## 5              0               0                0                0
##   conditionamast72 batchE batchF
## 1                0      0      0
## 2                0      0      0
## 3                0      0      0
## 4                0      0      0
## 5                1      0      0
## 10 more rows ...
## 
## $targets
##             lib.size
## metac.D.1    7666699
## amast4.D.2   7666679
## amast24.D.3  7666716
## amast48.D.4  7666698
## amast72.D.5  7666711
## 10 more rows ...
#Use voom to transform quantile-normalized count data to log2-counts per million, estimate mean-variance relationship
#and use m-v relationship to computer appropriate observational-level weights
v <- voom(countsSubQ, mod)
#Fit a linear model for each gene using the specified design contained in v
fit <- lmFit(v)
##metac v amast4##
#eBayes finds an F-statistic from the set of t-statistics for that gene
metac.amast4.contr.mat <- makeContrasts(metac_v_amast4=conditionamast4-conditionmetac, levels=v$design)
metac.amast4.fit <- contrasts.fit(fit, metac.amast4.contr.mat)
metac.amast4.eb <- eBayes(metac.amast4.fit)
metac.amast4.topTab <- topTable(metac.amast4.eb, coef="metac_v_amast4", number=nrow(v$E))
#View the list of DE genes
head(metac.amast4.topTab, n=3L)
##                        logFC AveExpr      t   P.Value adj.P.Val     B
## LmxM.31.1680-1        -3.044   5.086 -20.99 2.381e-15 1.978e-11 24.65
## LmxM.30.1450partial-1  2.429   9.485  18.74 2.181e-14 5.010e-11 23.02
## LmxM.29.2850-1        -2.509   6.005 -18.79 2.072e-14 5.010e-11 22.95
#                          logFC  AveExpr         t      P.Value    adj.P.Val        B
#LmxM.31.1680-1        -3.043546 5.085537 -20.98676 2.380772e-15 1.978422e-11 24.65466
#LmxM.30.1450partial-1  2.429366 9.484824  18.73963 2.181083e-14 5.009522e-11 23.02019
metac.amast4.topTab$fold_change <- 2 ^ metac.amast4.topTab$logFC
write.csv(file="csv/lamazonensis_metac_vs_amast4.csv", x=metac.amast4.topTab)

#Limit list to genes with an adjusted p value < 0.05
metac.amast4.sigGenes <- metac.amast4.topTab[metac.amast4.topTab$adj.P.Val <0.05, ]
length(metac.amast4.sigGenes$logFC)
## [1] 3896
#3896
#Filter out rows with less than 2-fold change (log2 fold change of > 1)
metac.amast4.sigGenesFold1 <- subset(metac.amast4.sigGenes, abs(logFC) > 1)
length(metac.amast4.sigGenesFold1$logFC)
## [1] 649
#649
#Filter out rows with less than 4-fold change (log2 fold change of > 2)
metac.amast4.sigGenesFold2 <- subset(metac.amast4.sigGenes, abs(logFC) > 2)
length(metac.amast4.sigGenesFold2$logFC)
## [1] 44
#44

metac.amast4.sigGenes <- metac.amast4.sigGenes[order(-metac.amast4.sigGenes$logFC), ]
#Make an MA plot
sel = metac.amast4.topTab$adj.P.Val < 0.05
top = metac.amast4.topTab
sub = paste("No. of sig. genes: ", sum(sel),"/",length(sel))
cpm = v$E
plot(rowMeans(cpm[rownames(top),]), top$logFC, pch=16, cex=0.5,col="darkgrey",
        main="metac_amast4 model batch adjusted",
        ylab="log FC", xlab="Average Expression",
        ylim=c(-3,3), sub=sub)
points(rowMeans(cpm[rownames(top),])[sel], top$logFC[sel], col="red", cex=0.5)
abline(h=c(-1,0,1), col="red")

##amast4 v amast24##
#eBayes finds an F-statistic from the set of t-statistics for that gene
amast4.amast24.contr.mat <- makeContrasts(amast4_v_amast24=conditionamast24-conditionamast4, levels=v$design)
amast4.amast24.fit <- contrasts.fit(fit, amast4.amast24.contr.mat)
amast4.amast24.eb <- eBayes(amast4.amast24.fit)
amast4.amast24.topTab <- topTable(amast4.amast24.eb, coef="amast4_v_amast24", number=nrow(v$E))

#View the list of DE genes
head(amast4.amast24.topTab, n=3L)
##                 logFC AveExpr       t   P.Value adj.P.Val      B
## LmxM.09.0060-1  1.543   9.332  10.945 5.039e-10  3.34e-06 12.916
## LmxM.17.0890-1 -1.712   7.707 -10.658 8.040e-10  3.34e-06 12.499
## LmxM.23.1665-1 -1.647   5.517  -9.207 9.855e-09  2.73e-05  9.985
#                   logFC  AveExpr          t      P.Value    adj.P.Val         B
#LmxM.09.0060-1  1.543364 9.332460  10.944657 5.038502e-10 3.340466e-06 12.915671
#LmxM.17.0890-1 -1.712316 7.707216 -10.657815 8.039628e-10 3.340466e-06 12.499147
#LmxM.23.1665-1 -1.646699 5.517480  -9.207189 9.854612e-09 2.729727e-05  9.985394
#Limit list to genes with an adjusted p value < 0.05
amast4.amast24.sigGenes <- amast4.amast24.topTab[amast4.amast24.topTab$adj.P.Val <0.05, ]
length(amast4.amast24.sigGenes$logFC)
## [1] 577
#577
#Filter out rows with less than 2-fold change (log2 fold change of > 1)
amast4.amast24.sigGenesFold1 <- subset(amast4.amast24.sigGenes, abs(logFC) > 1)
length(amast4.amast24.sigGenesFold1$logFC)
## [1] 104
#104
#Filter out rows with less than 4-fold change (log2 fold change of > 2)
amast4.amast24.sigGenesFold2 <- subset(amast4.amast24.sigGenes, abs(logFC) > 2)
length(amast4.amast24.sigGenesFold2$logFC)
## [1] 1
#1
amast4.amast24.sigGenes <- amast4.amast24.sigGenes[order(-amast4.amast24.sigGenes$logFC), ]
#Make an MA plot
sel = amast4.amast24.topTab$adj.P.Val < 0.05
top = amast4.amast24.topTab
sub = paste("No. of sig. genes: ", sum(sel),"/",length(sel))
cpm = v$E
plot(rowMeans(cpm[rownames(top),]), top$logFC, pch=16, cex=0.5,col="darkgrey",
        main="amast4_amast24 model batch adjusted",
        ylab="log FC", xlab="Average Expression",
        ylim=c(-3,3), sub=sub)
points(rowMeans(cpm[rownames(top),])[sel], top$logFC[sel], col="red", cex=0.5)
abline(h=c(-1,0,1), col="red")


##amast24 v amast48##
#eBayes finds an F-statistic from the set of t-statistics for that gene
amast24.amast48.contr.mat <- makeContrasts(amast24_v_amast48=conditionamast48-conditionamast24, levels=v$design)
amast24.amast48.fit <- contrasts.fit(fit, amast24.amast48.contr.mat)
amast24.amast48.eb <- eBayes(amast24.amast48.fit)
amast24.amast48.topTab <- topTable(amast24.amast48.eb, coef="amast24_v_amast48", number=nrow(v$E))
#View the list of DE genes
head(amast24.amast48.topTab, n=3L)
##                  logFC AveExpr      t   P.Value adj.P.Val     B
## LmxM.02.0460-1 -1.0270   6.482 -7.943 1.082e-07 0.0008988 4.933
## LmxM.30.1165-1  1.0818   5.463  7.038 6.838e-07 0.0028414 3.130
## LmxM.30.1190-1  0.8976   6.136  5.998 6.518e-06 0.0180550 2.413
#                    logFC  AveExpr         t      P.Value    adj.P.Val        B
#LmxM.02.0460-1 -1.0270442 6.481687 -7.943049 1.081563e-07 0.0008987787 4.933005
#LmxM.30.1165-1  1.0817746 5.463023  7.038413 6.838410e-07 0.0028413593 3.129606
#LmxM.30.1190-1  0.8976157 6.135557  5.998049 6.518059e-06 0.0180550222 2.413080
#Limit list to genes with an adjusted p value < 0.05
amast24.amast48.sigGenes <- amast24.amast48.topTab[amast24.amast48.topTab$adj.P.Val <0.05, ]
length(amast24.amast48.sigGenes$logFC)
## [1] 3
#3
#Filter out rows with less than 2-fold change (log2 fold change of > 1)
amast24.amast48.sigGenesFold1 <- subset(amast24.amast48.sigGenes, abs(logFC) > 1)
length(amast24.amast48.sigGenesFold1$logFC)
## [1] 2
#2
#Filter out rows with less than 4-fold change (log2 fold change of > 2)
amast24.amast48.sigGenesFold2 <- subset(amast24.amast48.sigGenes, abs(logFC) > 2)
length(amast24.amast48.sigGenesFold2$logFC)
## [1] 0
#0
amast24.amast48.sigGenes <- amast24.amast48.sigGenes[order(-amast24.amast48.sigGenes$logFC), ]
#Make an MA plot
sel = amast24.amast48.topTab$adj.P.Val < 0.05
top = amast24.amast48.topTab
sub = paste("No. of sig. genes: ", sum(sel),"/",length(sel))
cpm = v$E
plot(rowMeans(cpm[rownames(top),]), top$logFC, pch=16, cex=0.5,col="darkgrey",
        main="amast24_amast48 model batch adjusted",
        ylab="log FC", xlab="Average Expression",
        ylim=c(-3,3), sub=sub)
points(rowMeans(cpm[rownames(top),])[sel], top$logFC[sel], col="red", cex=0.5)
abline(h=c(-1,0,1), col="red")


##amast48 v amast72##
#eBayes finds an F-statistic from the set of t-statistics for that gene
amast48.amast72.contr.mat <- makeContrasts(amast48_v_amast72=conditionamast72-conditionamast48, levels=v$design)
amast48.amast72.fit <- contrasts.fit(fit, amast48.amast72.contr.mat)
amast48.amast72.eb <- eBayes(amast48.amast72.fit)
amast48.amast72.topTab <- topTable(amast48.amast72.eb, coef="amast48_v_amast72", number=nrow(v$E))

#View the list of DE genes
head(amast48.amast72.topTab, n=3L)
##                     logFC AveExpr      t  P.Value adj.P.Val      B
## LmxM.02.0460-1    -0.6433   6.482 -4.585 0.000169    0.9987 -2.970
## LmxM.13.0390-1    -0.4710  12.405 -3.565 0.001878    0.9987 -3.190
## LmxM.08_29.0251-1 -0.7466   6.216 -3.701 0.001365    0.9987 -3.248
#                       logFC   AveExpr         t      P.Value adj.P.Val         B
#LmxM.02.0460-1    -0.6433210  6.481687 -4.584932 0.0001689891 0.9987343 -2.970448
#LmxM.13.0390-1    -0.4709751 12.404965 -3.565121 0.0018782419 0.9987343 -3.190347
#LmxM.08_29.0251-1 -0.7466192  6.215922 -3.700966 0.0013650425 0.9987343 -3.248311
#Limit list to genes with an adjusted p value < 0.05
amast48.amast72.sigGenes <- amast48.amast72.topTab[amast48.amast72.topTab$adj.P.Val <0.05, ]
length(amast48.amast72.sigGenes$logFC)
## [1] 0
#0
#Make an MA plot
sel = amast48.amast72.topTab$adj.P.Val < 0.05
top = amast48.amast72.topTab
sub = paste("No. of sig. genes: ", sum(sel),"/",length(sel))
cpm = v$E
plot(rowMeans(cpm[rownames(top),]), top$logFC, pch=16, cex=0.5,col="darkgrey",
        main="amast48_amast72 model batch adjusted",
        ylab="log FC", xlab="Average Expression",
        ylim=c(-3,3), sub=sub)
points(rowMeans(cpm[rownames(top),])[sel], top$logFC[sel], col="red", cex=0.5)
abline(h=c(-1,0,1), col="red")
LS0tCnRpdGxlOiAiTC5tYWpvci9hbWF6b25lbnNpcyAyMDE2OiBSZXBlYXRpbmcgbGFtYXpvbmVuc2lzIG1vdXNlIGFuYWx5c2VzLiIKYXV0aG9yOiAiYXRiIGFiZWxld0BnbWFpbC5jb20iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogaHRtbF9kb2N1bWVudDoKICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgY29kZV9mb2xkaW5nOiBzaG93CiAgZmlnX2NhcHRpb246IHRydWUKICBmaWdfaGVpZ2h0OiA3CiAgZmlnX3dpZHRoOiA3CiAgaGlnaGxpZ2h0OiB0YW5nbwogIGtlZXBfbWQ6IGZhbHNlCiAgbW9kZTogc2VsZmNvbnRhaW5lZAogIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgdGhlbWU6IGNvc21vCiAgdG9jOiB0cnVlCiAgdG9jX2Zsb2F0OgogICBjb2xsYXBzZWQ6IGZhbHNlCiAgIHNtb290aF9zY3JvbGw6IGZhbHNlCi0tLQoKPHN0eWxlPgpib2R5IC5tYWluLWNvbnRhaW5lciB7Cm1heC13aWR0aDogMTYwMHB4Owp9Cjwvc3R5bGU+CgpgYGB7ciBvcHRpb25zLCBpbmNsdWRlPUZBTFNFfQojIyBUaGVzZSBhcmUgdGhlIG9wdGlvbnMgSSB0ZW5kIHRvIGZhdm9yCmxpYnJhcnkoImhwZ2x0b29scyIpCmtuaXRyOjpvcHRzX2tuaXQkc2V0KAogICAgcHJvZ3Jlc3MgPSBUUlVFLAogICAgdmVyYm9zZSA9IFRSVUUsCiAgICB3aWR0aCA9IDkwLAogICAgZWNobyA9IFRSVUUpCmtuaXRyOjpvcHRzX2NodW5rJHNldCgKICAgIGVycm9yID0gVFJVRSwKICAgIGZpZy53aWR0aCA9IDgsCiAgICBmaWcuaGVpZ2h0ID0gOCwKICAgIGRwaSA9IDk2KQpvcHRpb25zKAogICAgZGlnaXRzID0gNCwKICAgIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSwKICAgIGtuaXRyLmR1cGxpY2F0ZS5sYWJlbCA9ICJhbGxvdyIpCmdncGxvdDI6OnRoZW1lX3NldChnZ3Bsb3QyOjp0aGVtZV9idyhiYXNlX3NpemU9MTApKQpzZXQuc2VlZCgxKQpybWRfZmlsZSA8LSAicmVwZWF0X2xvZ19sYW1hem9uZW5zaXMuUm1kIgpgYGAKCltpbmRleC5odG1sXShpbmRleC5odG1sKQoKYGBge3IgcmVuZGVyaW5nLCBpbmNsdWRlPUZBTFNFLCBldmFsPUZBTFNFfQojIyBUaGlzIGJsb2NrIGlzIHVzZWQgdG8gcmVuZGVyIGEgZG9jdW1lbnQgZnJvbSB3aXRoaW4gaXQuCnJtYXJrZG93bjo6cmVuZGVyKHJtZF9maWxlKQoKIyMgQW4gZXh0cmEgcmVuZGVyZXIgZm9yIHBkZiBvdXRwdXQKcm1hcmtkb3duOjpyZW5kZXIocm1kX2ZpbGUsIG91dHB1dF9mb3JtYXQ9InBkZl9kb2N1bWVudCIsIG91dHB1dF9vcHRpb25zPWMoInNraXBfaHRtbCIpKQojIyBPciB0byBzYXZlL2xvYWQgbGFyZ2UgUmRhdGEgZmlsZXMuCmhwZ2x0b29sczo6OnNhdmVtZSgpCmhwZ2x0b29sczo6OmxvYWRtZSgpCnJtKGxpc3Q9bHMoKSkKYGBgCgojIFJlcGVhdCBhIHByZXZpb3VzIHNldCBvZiBhbmFseXNlcyBhbmQgc2VlIHdoZXJlIHdlIGRpZmZlcgoKSSBhbSBnb2luZyB0byBpbnRlcnNwZXJzZSB0aGUgb3JpZ2luYWwgY29tbWVudHMgYW5kIGNvZGUsIHRoZW4gY29tcGFyZSB3aXRoIG15IG93biBhbmFseXNlcy4KCjxwcmU+CiNtZXRhY3ljbGljIHRvIDQtaHIgYW1hc3RpZ290ZSB0cmFuc2l0aW9uIGFuZCB0aGUgYW1hc3RpZ290ZSBzYW1wbGVzIGFjcm9zcyB0aW1lcG9pbnRzLgojVGhpcyBsb2cgaXMgZm9yIHBhcmFzaXRlIHNhbXBsZXMgb25seSB1c2luZyB0aGUgY291bnQgdGFibGUgcmVzdHJpY3RlZCB0byBDRFMgb25seS4KCiNDb3VudCB0YWJsZSBnZW5lcmF0aW9uIGlzIGRlc2NyaWJlZCBpbiBsb2dzOgojbG1pbmZlY3RvbWVfZGlsbG9ubF8yMDE0MTAwMV9Ub3BIYXRfSFRTZXFfQ291bnRfVGFibGVfaGcxOV9MYW1hem9uZW5zaXNfTG1ham9yX2JlYWRzX0hQR0wwNDM0LTQ0Nl80NTItNDcyX2NlY2lsaWEubG9nCiNsbWluZmVjdG9tZV9kaWxsb25sXzIwMTQxMjExX1RvcEhhdF9IVFNlcV9Db3VudF9UYWJsZV9oZzE5X0xhbWF6b25lbnNpc19MbWFqb3JfYmVhZHNfSFBHTDA0OTEtNTEwX2NlY2lsaWEubG9nCgojTG1leGljYW5hODEgKEwuIGFtYXpvbmVuc2lzKSBzYW1wbGVzCiNOYW1lICAgICAgICAgICBjb25kaXRpb24gICAgICAgYmF0Y2gKI0hQR0wwNDM1ICAgICAgIG1ldGFjICAgICAgICAgICBECiNIUEdMMDQzNyAgICAgICBhbWFzdExBNCAgICAgICAgRAojSFBHTDA0NDAgICAgICAgYW1hc3RMQTI0ICAgICAgIEQKI0hQR0wwNDQzICAgICAgIGFtYXN0TEE0OCAgICAgICBECiNIUEdMMDQ0NiAgICAgICBhbWFzdExBNzIgICAgICAgRAojSFBHTDA0NTQgICAgICAgbWV0YWMgICAgICAgICAgIEUKI0hQR0wwNDU4ICAgICAgIGFtYXN0TEE0ICAgICAgICBFCiNIUEdMMDQ2MiAgICAgICBhbWFzdExBMjQgICAgICAgRQojSFBHTDA0NjYgICAgICAgYW1hc3RMQTQ4ICAgICAgIEUKI0hQR0wwNDcwICAgICAgIGFtYXN0TEE3MiAgICAgICBFCiNIUEdMMDQ5MiAgICAgICBtZXRhYyAgICAgICAgICAgRgojSFBHTDA0OTYgICAgICAgYW1hc3RMQTQgICAgICAgIEYKI0hQR0wwNTAwICAgICAgIGFtYXN0TEEyNCAgICAgICBGCiNIUEdMMDUwNCAgICAgICBhbWFzdExBNDggICAgICAgRgojSFBHTDA1MDggICAgICAgYW1hc3RMQTcyICAgICAgIEYKI0NvdW50IHRhYmxlIGlzOgojMjAxNDEyMTFfTG1leGljYW5hODFfNDM0LTQzNV80MzdfNDQwXzQ0M180NDZfNDUzLTQ1NF80NThfNDYyXzQ2Nl80NzBfNDkxLTQ5Ml80OTZfNTAwXzUwNF81MDhfQ0RTb25seS5jb3VudAojSW5jbHVkZXMgaGVhZGVycwoKIzctMjgtMTUKI0wuIGFtYXpvbmVuc2lzCiNDcmVhdGUgZGlhZ25vc3RpYyBwbG90cwojSGVjdG9yIHJlY29tbWVuZGVkIHRoYXQgYWxsIGRpYWdub3N0aWNzIGJlIGRvbmUgdXNpbmcgdGhlIHJhd2VzdCBkYXRhIHBvc3NpYmxlLiBGb3IgY29ycmVsYXRpb24gYW5hbHlzZXMgYmV0d2VlbiBzYW1wbGVzLAojdXNlIGNvdW50c1RhYmxlIGRhdGEgd2l0aG91dCBmaWx0ZXJpbmcgb3V0IGxvd2x5IGV4cHJlc3NlZCBnZW5lcyBhbmQgd2l0aG91dCBub3JtYWxpemF0aW9uLiBTaXplIGZhY3RvciBub3JtYWxpemF0aW9uCiN3aWxsIGJlIHVzZWQgdG8gc2hvdyB0aGUgZGlzdHJpYnV0aW9uIG9mIGdlbmUgZXhwcmVzc2lvbiBsZXZlbHMuCgojVGhpcyBhbmFseXNpcyB1c2VzIGNvdW50IHRhYmxlcyB0aGF0IGhhdmUgbm90IGJlZW4gcmVzdHJpY3RlZCB0byBfQ0RTIG9ubHkuCjwvcHJlPgoKYGBge3IgcmVwZWF0bWV9CmxpYnJhcnkoY2JjYlNFUSkKbGlicmFyeShncGxvdHMpCmxpYnJhcnkobWF0cml4U3RhdHMpCmxpYnJhcnkoc2lnZ2VuZXMpCmxpYnJhcnkoUmVwb3J0aW5nVG9vbHMpCmxpYnJhcnkoaHdyaXRlcikKbGlicmFyeShERVNlcTIpCmxpYnJhcnkoUkNvbG9yQnJld2VyKQoKI1JlYWQgaW4gY291bnRzIHRhYmxlCmNvdW50c1RhYmxlIDwtIHJlYWQudGFibGUoInByZXByb2Nlc3NpbmcvZGlsbG9ubC8yMDE0MTIxMV9MbWV4aWNhbmE4MV80MzQtNDM1XzQzN180NDBfNDQzXzQ0Nl80NTMtNDU0XzQ1OF80NjJfNDY2XzQ3MF80OTEtNDkyXzQ5Nl81MDBfNTA0XzUwOF9DRFNvbmx5LmNvdW50Lnh6IiwgaGVhZGVyPVRSVUUpCiNSZW1vdmUgaWQgYXMgYW4gYWN0dWFsIGNvbHVtbiwgdXNlIGFzIHJvdyBuYW1lcyBpbnN0ZWFkCnJvd25hbWVzKGNvdW50c1RhYmxlKSA8LSBjb3VudHNUYWJsZSRpZApjb3VudHNUYWJsZSA8LSBjb3VudHNUYWJsZVssLTFdCiNSZXN0cmljdCB0byBzYW1wbGVzIG9mIGludGVyZXN0IChleGNsdWRlIHByb2N5Y2xpYyBwcm9tYXN0aWdvdGUgc2FtcGxlcykKY291bnRzVGFibGUgPC0gY291bnRzVGFibGVbLC1jKDEsIDcsIDEzKV0KaGVhZChjb3VudHNUYWJsZSwgbj0zTCkKIyAgICAgICAgICAgICAgIEhQR0wwNDM1IEhQR0wwNDM3IEhQR0wwNDQwIEhQR0wwNDQzIEhQR0wwNDQ2IEhQR0wwNDU0IEhQR0wwNDU4IEhQR0wwNDYyIEhQR0wwNDY2IEhQR0wwNDcwIEhQR0wwNDkyIEhQR0wwNDk2IEhQR0wwNTAwIEhQR0wwNTA0IEhQR0wwNTA4CiNMbXhNLjAxLjAwMTAtMSAgICAgMTkxMCAgICAgIDE1NCAgICAgICAzNCAgICAgICAzOCAgICAgICA1NiAgICAgMjI1NSAgICAgIDI2NCAgICAgIDE1MSAgICAgIDIxNyAgICAgIDIwMyAgICAgMTUxMiAgICAgICA1MSAgICAgICA1MiAgICAgICAxMyAgICAgICAgOAojTG14TS4wMS4wMDIwLTEgICAgIDExMDMgICAgICAzNzAgICAgICAxMTkgICAgICAxNjIgICAgICAyNzcgICAgIDE2MzkgICAgIDExNTMgICAgIDE1MTkgICAgIDEzMTUgICAgIDEzNDUgICAgIDE1MjggICAgICAxNTMgICAgICAyMjUgICAgICAgNjIgICAgICAgNjYKI0xteE0uMDEuMDAzMC0xICAgICAgODQ5ICAgICAgMjExICAgICAgIDYwICAgICAgMTAwICAgICAgMTk1ICAgICAgNzg5ICAgICAgNDc1ICAgICAgNjY4ICAgICAgNzM1ICAgICAgNjg5ICAgICAgNzg1ICAgICAgIDg4ICAgICAgMTM1ICAgICAgIDI5ICAgICAgIDQ4CiNFc3RhYmxpc2ggbWV0YWRhdGEgZm9yIHNhbXBsZXMKc2FtcGxlSUQgPC0gY29sbmFtZXMoY291bnRzVGFibGUpCmNvbmRpdGlvbiA8LSByZXAoYygibWV0YWMiLCAiYW1hc3Q0IiwgImFtYXN0MjQiLCAiYW1hc3Q0OCIsICJhbWFzdDcyIiksIHRpbWVzPTMpCmJhdGNoIDwtIHJlcChjKCJEIiwgIkUiLCAiRiIpLCBlYWNoPTUpCiNDcmVhdGUgY29uZGl0aW9uIGFuZCBiYXRjaCBmYWN0b3IKY29uZGl0aW9uIDwtIGZhY3Rvcihjb25kaXRpb24sIGxldmVscz1jKCJtZXRhYyIsICJhbWFzdDQiLCAiYW1hc3QyNCIsICJhbWFzdDQ4IiwgImFtYXN0NzIiKSkKYmF0Y2ggPC0gZmFjdG9yKGJhdGNoLCBsZXZlbHM9YygiRCIsICJFIiwgIkYiKSkKZGVzaWduIDwtIGRhdGEuZnJhbWUoc2FtcGxlSUQ9c2FtcGxlSUQsIGNvbmRpdGlvbj1jb25kaXRpb24sIGJhdGNoPWJhdGNoKQpkZXNpZ24KIyAgIHNhbXBsZUlEIGNvbmRpdGlvbiBiYXRjaAojMSAgSFBHTDA0MzUgICAgIG1ldGFjICAgICBECiMyICBIUEdMMDQzNyAgICBhbWFzdDQgICAgIEQKIzMgIEhQR0wwNDQwICAgYW1hc3QyNCAgICAgRAojNCAgSFBHTDA0NDMgICBhbWFzdDQ4ICAgICBECiM1ICBIUEdMMDQ0NiAgIGFtYXN0NzIgICAgIEQKIzYgIEhQR0wwNDU0ICAgICBtZXRhYyAgICAgRQojNyAgSFBHTDA0NTggICAgYW1hc3Q0ICAgICBFCiM4ICBIUEdMMDQ2MiAgIGFtYXN0MjQgICAgIEUKIzkgIEhQR0wwNDY2ICAgYW1hc3Q0OCAgICAgRQojMTAgSFBHTDA0NzAgICBhbWFzdDcyICAgICBFCiMxMSBIUEdMMDQ5MiAgICAgbWV0YWMgICAgIEYKIzEyIEhQR0wwNDk2ICAgIGFtYXN0NCAgICAgRgojMTMgSFBHTDA1MDAgICBhbWFzdDI0ICAgICBGCiMxNCBIUEdMMDUwNCAgIGFtYXN0NDggICAgIEYKIzE1IEhQR0wwNTA4ICAgYW1hc3Q3MiAgICAgRgpjb2xuYW1lcyhjb3VudHNUYWJsZSkgPC0gcGFzdGUoY29uZGl0aW9uLCBiYXRjaCwgMTpsZW5ndGgoY29uZGl0aW9uKSwgc2VwPSIuIikKCmJhcnBsb3QoY29sU3Vtcyhjb3VudHNUYWJsZSksIGxhcz0zLCB5bGltPWMoMCwzZSswNykpCgojTm9ybWFsaXplIHJhdyBjb3VudHMgdXNpbmcgREVTZXEgc2l6ZSBmYWN0b3JzCmRmIDwtIGRhdGEuZnJhbWUoY29uZD0oY29uZGl0aW9uKSkKZGRzIDwtIERFU2VxRGF0YVNldEZyb21NYXRyaXgoY291bnREYXRhPWNvdW50c1RhYmxlLCBjb2xEYXRhID0gZGYsIGRlc2lnbiA9IH4gY29uZCkKZGRzIDwtIGVzdGltYXRlU2l6ZUZhY3RvcnMoZGRzKQpuY3RzIDwtIGNvdW50cyhkZHMsIG5vcm1hbGl6ZWQ9VFJVRSkKeSA8LSBsb2cobmN0cyArIDEpCgojRGV0ZXJtaW5lIG1lZGlhbiBhbmQgcXVhbnRpbGVzIG9mIHRoZSBzaXplIGZhY3RvciBub3JtYWxpemVkLCBsb2cyIGNvdW50cwptZWRpYW4oeSkKI1sxXSA1Ljc4ODcyNwpxdWFudGlsZSh5KQojICAgICAgIDAlICAgICAgIDI1JSAgICAgICA1MCUgICAgICAgNzUlICAgICAgMTAwJQojIDAuMDAwMDAwICA1LjMzMDc1MiAgNS43ODg3MjcgIDYuMjU2NTk2IDEwLjcwMTU4MgojRGV0ZXJtaW5lIG51bWJlciBvZiBnZW5lcyBwZXIgc2FtcGxlIHdpdGggbGVzcyB0aGFuIGxvZzIgb2YgMiBjb3VudHMgKGxlc3MgdGhhbiA0IGNvdW50cyBwZXIgbWlsbCkKeWRmIDwtIGFzLmRhdGEuZnJhbWUoeSkKY29sbmFtZXMoeWRmKSA8LSBzYW1wbGVJRAoKY29sLm5hbSA8LSBwYXN0ZShjb25kaXRpb24sIGJhdGNoLCAxOmxlbmd0aChjb25kaXRpb24pLCBzZXA9Ii4iKQojQm94cGxvdCBvZiBwZXIgc2FtcGxlIGxvZyBvZiBzaXplLWZhY3Rvci1ub3JtYWxpemVkIGNvdW50cyAoKyAxKQpwYXIobWFyPWMoMTAuNSw0LjUsMiwxKSkKcGFyKG9tYT1jKDAsMCwwLDApKQpib3hwbG90KHksIG5hbWVzPWNvbC5uYW0sIGxhcz0zKQoKI0hlYXRtYXAgb2YgUGVhcnNvbiBjb3JyZWxhdGlvbiBiZXR3ZWVuIHNhbXBsZXMKIyhkZWxldGUgUm93diwgQ29sdiwgYW5kIGRlbmRyb2dyYW0gcGFyYW1ldGVycyBpZiB3YW50IHNhbXBsZXMgdG8gc29ydCBhbmQgc2hvdyBkZW5kcm9ncmFtKQojQ29ycmVsYXRpb24gYW5hbHlzaXMgKFBlYXJzb24gaXMgZGVmYXVsdCBmb3IgY29yIHVubGVzcyBvdGhld2lzZSBzcGVjaWZpZWQpCiNVc2luZyByYXcgY291bnRzCmRhdENvciA8LSBjb3IoY291bnRzVGFibGUpCmhlYXRtYXAuMihkYXRDb3IsIFJvd3Y9TkEsIENvbHY9TkEsCiAgICAgICAgICBtYXJnaW5zPWMoMTAsIDEwKSwKICAgICAgICAgIGxhYlJvdz1jb2wubmFtLAogICAgICAgICAgbGFiQ29sPWNvbC5uYW0sCiAgICAgICAgICBkZW5kcm9ncmFtPSJub25lIiwKICAgICAgICAgIHNjYWxlPSJub25lIiwKICAgICAgICAgIHRyYWNlPSJub25lIiwKICAgICAgICAgIHNydENvbD00NSkKI01lZGlhbiBwYWlyd2lzZSBjb3JyZWxhdGlvbgojVXNpbmcgcmF3IGNvdW50cwpjb3JNIDwtIG1hdHJpeFN0YXRzOjpyb3dNZWRpYW5zKGNvcihjb3VudHNUYWJsZSkpCnFzIDwtIHF1YW50aWxlKGNvck0scD1jKDEsMykvNCkKaXFyIDwtIGRpZmYocXMpCm91dExpbWl0IDwtIHFzWzFdIC0gMS41ICogaXFyCgp5bGltIDwtIGMocG1pbihtaW4oY29yTSksb3V0TGltaXQpLG1heChjb3JNKSkKY29sIDwtICBpZmVsc2UoY29uZGl0aW9uPT0iYW1hc3Q0IiwgImNvcm5mbG93ZXJibHVlIiwKICAgICAgICBpZmVsc2UoY29uZGl0aW9uPT0iYW1hc3QyNCIsICJnb2xkIiwKICAgICAgICBpZmVsc2UoY29uZGl0aW9uPT0iYW1hc3Q0OCIsICJncmVlbjMiLAogICAgICAgIGlmZWxzZShjb25kaXRpb249PSJhbWFzdDcyIiwgImNvcmFsIiwgIm1lZGl1bW9yY2hpZDQiKSkpKQoKcGxvdChjb3JNLCB4YXh0PSJuIiwgeWxpbT15bGltLCB5bGFiPSJNZWRpYW4gUGFpcndpc2UgQ29ycmVsYXRpb24iLCB4bGFiPSIiLCBtYWluPSIiLCBjb2w9Y29sLCBwY2g9MTYsIGNleD0yLjIpCmF4aXMoc2lkZT0xLGF0PXNlcShhbG9uZz1jb3JNKSxsYWJlbHM9cGFzdGUoY29uZGl0aW9uLGJhdGNoLHNlcD0iOiIpLGxhcz0yKQphYmxpbmUoaD1vdXRMaW1pdCxsdHk9MikKYWJsaW5lKHY9MTpsZW5ndGgoY29sLm5hbSksIGx0eT0zLCBjb2w9ImJsYWNrIikKI1Bsb3Qgd2l0aG91dCBJUVIgY3V0b2ZmCiNVc2UgZmlsdGVyQ291bnRzIG1ldGhvZCB0byBmaWx0ZXIgZm9yIGxvdyBjb3VudHMKI0RlZmluZSBmaWx0ZXJDb3VudHMgZnVuY3Rpb24KCmZpbHRlckNvdW50cyA9IGZ1bmN0aW9uIChjb3VudHMsIGxpYi5zaXplID0gTlVMTCwgdGhyZXNoID0gMSwgbWluU2FtcGxlcyA9IDIpIHsKICAgIGNwbXMgPC0gMl5sb2cyQ1BNKGNvdW50cywgbGliLnNpemUgPSBsaWIuc2l6ZSkkeQogICAga2VlcCA8LSByb3dTdW1zKGNwbXMgPiB0aHJlc2gpID49IG1pblNhbXBsZXMKICAgIGNvdW50cyA8LSBjb3VudHNba2VlcCwgXQogICAgY291bnRzCn0KeCA8LSB0YWJsZShjb25kaXRpb24pCmRpbShjb3VudHNUYWJsZSkKI1sxXSA4MzM2ICAgMTUKY291bnRzIDwtIGZpbHRlckNvdW50cyhjb3VudHNUYWJsZSwgdGhyZXNoPTEsIG1pblNhbXBsZXM9bWluKHgpKQpkaW0oY291bnRzKQojWzFdIDgzMTAgICAxNQojUXVhbnRpbGUgbm9ybWFsaXplIGNvdW50cwpjb3VudHNTdWJRIDwtIHFOb3JtKGNvdW50cykKI0V4cGxvcmUgZGF0YSBmb3IgYmF0Y2ggZWZmZWN0cwojVHJhbnNmb3JtIGRhdGEgdG8gbG9nMiBjb3VudHMgcGVyIG1pbGxpb24KeCA8LSBsb2cyQ1BNKGNvdW50c1N1YlEpCiNDb21wdXRlIHByaW5jaXBhbCBjb21wb25lbnRzCnMgPC0gbWFrZVNWRCh4JHkpCiNDb21wdXRlIHZhcmlhbmNlIG9mIGVhY2ggUEMgYW5kIGhvdyB0aGV5IGNvcnJlbGF0ZSB3aXRoIGJhdGNoIGFuZCBjb25kaXRpb24KcGNSZXMocyR2LCBzJGQsIGNvbmRpdGlvbiwgYmF0Y2gpCiMgICBwcm9wVmFyIGN1bVByb3BWYXIgY29uZC5SMiBiYXRjaC5SMgojMSAgICA1OS4xMiAgICAgIDU5LjEyICAgOTYuNjIgICAgIDIuNzIKIzIgICAgIDkuMDQgICAgICA2OC4xNiAgIDc1Ljg2ICAgIDExLjEzCiMzICAgICA2LjUwICAgICAgNzQuNjYgICAyMS4zNyAgICAzOC40MwojNCAgICAgNS4wMyAgICAgIDc5LjY5ICAgMTQuNTQgICAgNjcuODUKIzUgICAgIDQuMDMgICAgICA4My43MiAgICAxLjYxICAgIDQ4LjMwCiM2ICAgICAzLjM2ICAgICAgODcuMDggICAyNi42MyAgICAxNy4yOAojNyAgICAgMi44NSAgICAgIDg5LjkzICAgMTguODAgICAgIDUuNjcKIzggICAgIDIuNTIgICAgICA5Mi40NSAgIDQ4LjA1ICAgICAwLjQ2CiM5ICAgICAxLjc3ICAgICAgOTQuMjIgICAxMi45MiAgICAgMy4wOQojMTAgICAgMS42NyAgICAgIDk1Ljg5ICAgMTkuNTEgICAgIDAuNzAKIzExICAgIDEuMzcgICAgICA5Ny4yNiAgICA5LjQ0ICAgICAwLjU3CiMxMiAgICAxLjIxICAgICAgOTguNDcgICAxNi45NCAgICAgMC41OQojMTMgICAgMS4xMCAgICAgIDk5LjU3ICAgMTEuMTEgICAgIDMuMDMKIzE0ICAgIDAuNDQgICAgIDEwMC4wMSAgIDI2LjYwICAgICAwLjE4CgoKI1Bsb3QgUEMxIHZzLiBQQzIsIHdpdGggYmxhY2sgb3V0bGluZXMgYW5kIGNvbG9yIGZpbGxzCiNTYXZlIGFzIGVwcwpjb25kbnVtIDwtIGFzLm51bWVyaWMoY29uZGl0aW9uKQpwbG90UEMocyR2LAogICAgICAgcyRkLAogICAgICAgY29sPSJibGFjayIsCiAgICAgICBwY2g9aWZlbHNlKGJhdGNoPT0iRCIsIDI1LCBpZmVsc2UoYmF0Y2g9PSJCIiwgMjEsIGlmZWxzZShiYXRjaD09IkMiLCAyMiwgaWZlbHNlKGJhdGNoPT0iRSIsIDI0LCAyMykpKSksCiAgICAgICBiZz1pZmVsc2UoY29uZG51bT09MSwgIm1lZGl1bW9yY2hpZDQiLCBpZmVsc2UoY29uZG51bT09MiwgImNvcm5mbG93ZXJibHVlIiwgaWZlbHNlKGNvbmRudW09PTMsICJnb2xkIiwgaWZlbHNlKGNvbmRudW09PTQsICJncmVlbjMiLCAiY29yYWwiKSkpKSwgY2V4PTIuNgogICAgICAgKQpsZWdlbmQoeD0tMC4yMywgeT0wLjM5LCBsZWdlbmQ9YygibWV0YWMiLCAiYW1hc3Q0IiwgImFtYXN0MjQiLCAiYW1hc3Q0OCIsICJhbWFzdDcyIiksIHBjaD0yMiwgY29sPTAsCnB0LmJnPWMoIm1lZGl1bW9yY2hpZDQiLCAiY29ybmZsb3dlcmJsdWUiLCAiZ29sZCIsICJncmVlbjMiLCAiY29yYWwiKSwgcHQuY2V4PTIuNiwgYnR5PSJuIikKdGV4dChzJHZbLDFdLCBzJHZbLDJdLCBjb2xuYW1lcyhjb3VudHNUYWJsZSksIGNleD0uNywgcG9zPTQpCiNWaWV3IGFzIGEgRXVjbGlkZWFuIGRpc3RhbmNlIGhlYXRtYXAKZGlzdHMgPC0gZGlzdCh0KGNvdW50cykpCm1hdCA8LSBhcy5tYXRyaXgoZGlzdHMpCnJvd25hbWVzKG1hdCkgPC0gY29sbmFtZXMobWF0KSA8LSB3aXRoKGRlc2lnbiwgcGFzdGUoY29sbmFtZXMoY291bnRzVGFibGUpKSkKaG1jb2wgPC0gY29sb3JSYW1wUGFsZXR0ZShicmV3ZXIucGFsKDksICJHbkJ1IikpKDEwMCkKdmVjLmJhdGNoIDwtIHJhaW5ib3cobmxldmVscyhiYXRjaCksIHN0YXJ0PTAsIGVuZD0uOCkKYmF0Y2guY29sb3IgPC0gcmVwKDAsIGxlbmd0aChiYXRjaCkpCmZvciAoaSBpbiAxOmxlbmd0aChiYXRjaCkpIHsKICAgIGJhdGNoLmNvbG9yW2ldIDwtIHZlYy5iYXRjaFtiYXRjaFtpXT09bGV2ZWxzKGJhdGNoKV0KfQp2ZWMuY29uZGl0aW9uIDwtIGMoIm1lZGl1bW9yY2hpZDQiLCAiY29ybmZsb3dlcmJsdWUiLCAiZ29sZCIsICJncmVlbjMiLCAiY29yYWwiKQpjb25kaXRpb24uY29sb3IgPC0gcmVwKDAsIGxlbmd0aChjb25kaXRpb24pKQpmb3IgKGkgaW4gMTpsZW5ndGgoY29uZGl0aW9uKSkgewogICAgY29uZGl0aW9uLmNvbG9yW2ldIDwtIHZlYy5jb25kaXRpb25bY29uZGl0aW9uW2ldPT1sZXZlbHMoY29uZGl0aW9uKV0KfQoKaGVhdG1hcCA8LSBoZWF0bWFwLjIobWF0LCB0cmFjZT0ibm9uZSIsIGNvbCA9IHJldihobWNvbCksIG1hcmdpbj1jKDExLDExKSwgQ29sU2lkZUNvbG9ycz1jb25kaXRpb24uY29sb3IsClJvd1NpZGVDb2xvcnM9YmF0Y2guY29sb3IsIGtleT0iRkFMU0UiLCBzcnRDb2w9NDUpCmRldi5vZmYoKQojSSB3b3VsZCBsaWtlIHRvIGNyZWF0ZSBhIFBDQSBwbG90IGFuZCBoZWF0bWFwIHRvIHJlZmxlY3QgdGhlIHVzZSBvZiBiYXRjaCBpbiB0aGUgbGltbWEgbW9kZWwKI1NwZWNpZnkgbW9kZWwKbW9kIDwtIG1vZGVsLm1hdHJpeCh+YmF0Y2gpCiNVc2Ugdm9vbSB0byBkZXRlcm1pbmUgd2VpZ2h0cyBmb3IgZml0dGluZyB0aGUgbWVhbi12YXJpYW5jZSB0cmVuZCBmb3IgZWFjaCBnZW5lCnYgPC0gdm9vbShjb3VudHNTdWJRLCBtb2QpCiNGaXQgdGhlIGxpbmVhciBtb2RlbCBmb3IgZWFjaCBnZW5lCmZpdCA8LSBsbUZpdCh2KQojR2V0IHRoZSByZXNpZHVhbCAoaS5lLiBldmVyeXRoaW5nIGV4Y2VwdCBmb3IgdGhlIGJhdGNoIGVmZmVjdCkKbmV3RGF0YSA8LSByZXNpZHVhbHMoZml0LCB2KQojRXhwbG9yZSBkYXRhIGZvciBiYXRjaCBlZmZlY3RzCiNDb21wdXRlIHByaW5jaXBhbCBjb21wb25lbnRzCnMgPC0gbWFrZVNWRChuZXdEYXRhKQojQ29tcHV0ZSB2YXJpYW5jZSBvZiBlYWNoIFBDIGFuZCBob3cgdGhleSBjb3JyZWxhdGUgd2l0aCBiYXRjaCBhbmQgY29uZGl0aW9uCnBjUmVzKHMkdiwgcyRkLCBjb25kaXRpb24sIGJhdGNoKQojICAgcHJvcFZhciBjdW1Qcm9wVmFyIGNvbmQuUjIgYmF0Y2guUjIKIzEgICAgNjUuMDIgICAgICA2NS4wMiAgIDk5LjM0ICAgICAgICAwCiMyICAgICA5LjY1ICAgICAgNzQuNjcgICA4OS4wNSAgICAgICAgMAojMyAgICAgNi4xOCAgICAgIDgwLjg1ICAgMTUuMzAgICAgICAgIDAKIzQgICAgIDQuMTggICAgICA4NS4wMyAgIDMxLjU5ICAgICAgICAwCiM1ICAgICAzLjMxICAgICAgODguMzQgICAyMi4yMiAgICAgICAgMAojNiAgICAgMi44NSAgICAgIDkxLjE5ICAgNTAuNDEgICAgICAgIDAKIzcgICAgIDIuMTEgICAgICA5My4zMCAgIDEyLjYwICAgICAgICAwCiM4ICAgICAxLjkxICAgICAgOTUuMjEgICAxOS44NyAgICAgICAgMAojOSAgICAgMS41NyAgICAgIDk2Ljc4ICAgIDYuMzcgICAgICAgIDAKIzEwICAgIDEuNDAgICAgICA5OC4xOCAgIDE3LjI5ICAgICAgICAwCiMxMSAgICAxLjMzICAgICAgOTkuNTEgICAxMC42NyAgICAgICAgMAojMTIgICAgMC41MSAgICAgMTAwLjAyICAgMjUuMzEgICAgICAgIDAKIzEzICAgIDAuMDAgICAgIDEwMC4wMiAgICAwLjAwICAgICAgMTAwCiMxNCAgICAwLjAwICAgICAxMDAuMDIgICAgMC4wMCAgICAgIDEwMAojUGxvdCBQQzEgdnMuIFBDMiwgd2l0aCBibGFjayBvdXRsaW5lcyBhbmQgY29sb3IgZmlsbHMKCmNvbmRudW0gPC0gYXMubnVtZXJpYyhjb25kaXRpb24pCnBsb3RQQyhzJHYsCiAgICAgICBzJGQsCiAgICAgICBjb2w9ImJsYWNrIiwKICAgICAgIHBjaD1pZmVsc2UoYmF0Y2g9PSJEIiwgMjUsIGlmZWxzZShiYXRjaD09IkIiLCAyMSwgaWZlbHNlKGJhdGNoPT0iQyIsIDIyLCBpZmVsc2UoYmF0Y2g9PSJFIiwgMjQsIDIzKSkpKSwKICAgICAgIGJnPWlmZWxzZShjb25kbnVtPT0xLCAibWVkaXVtb3JjaGlkNCIsIGlmZWxzZShjb25kbnVtPT0yLCAiY29ybmZsb3dlcmJsdWUiLCBpZmVsc2UoY29uZG51bT09MywgImdvbGQiLCBpZmVsc2UoY29uZG51bT09NCwgImdyZWVuMyIsICJjb3JhbCIpKSkpLCBjZXg9Mi42CiAgICAgICApCmxlZ2VuZCh4PS0wLjQ4LCB5PS0wLjI0LCBsZWdlbmQ9YygibWV0YWMiLCAiYW1hc3Q0IiwgImFtYXN0MjQiLCAiYW1hc3Q0OCIsICJhbWFzdDcyIiksIHBjaD0yMiwgY29sPTAsCnB0LmJnPWMoIm1lZGl1bW9yY2hpZDQiLCAiY29ybmZsb3dlcmJsdWUiLCAiZ29sZCIsICJncmVlbjMiLCAiY29yYWwiKSwgcHQuY2V4PTIuNiwgYnR5PSJuIikKdGV4dChzJHZbLDFdLCBzJHZbLDJdLCBjb2xuYW1lcyhjb3VudHNUYWJsZSksIGNleD0uNywgcG9zPTQpCiNWaWV3IGFzIGEgRXVjbGlkZWFuIGRpc3RhbmNlIGhlYXRtYXAKZGlzdHMgPC0gZGlzdCh0KG5ld0RhdGEpKQptYXQgPC0gYXMubWF0cml4KGRpc3RzKQpyb3duYW1lcyhtYXQpIDwtIGNvbG5hbWVzKG1hdCkgPC0gd2l0aChkZXNpZ24sIHBhc3RlKGNvbG5hbWVzKGNvdW50c1RhYmxlKSkpCmhtY29sIDwtIGNvbG9yUmFtcFBhbGV0dGUoYnJld2VyLnBhbCg5LCAiR25CdSIpKSgxMDApCnZlYy5iYXRjaCA8LSByYWluYm93KG5sZXZlbHMoYmF0Y2gpLCBzdGFydD0wLCBlbmQ9LjgpCmJhdGNoLmNvbG9yIDwtIHJlcCgwLCBsZW5ndGgoYmF0Y2gpKQpmb3IgKGkgaW4gMTpsZW5ndGgoYmF0Y2gpKSB7CiAgICBiYXRjaC5jb2xvcltpXSA8LSB2ZWMuYmF0Y2hbYmF0Y2hbaV09PWxldmVscyhiYXRjaCldCn0KdmVjLmNvbmRpdGlvbiA8LSBjKCJtZWRpdW1vcmNoaWQ0IiwgImNvcm5mbG93ZXJibHVlIiwgImdvbGQiLCAiZ3JlZW4zIiwgImNvcmFsIikKY29uZGl0aW9uLmNvbG9yIDwtIHJlcCgwLCBsZW5ndGgoY29uZGl0aW9uKSkKZm9yIChpIGluIDE6bGVuZ3RoKGNvbmRpdGlvbikpIHsKICAgIGNvbmRpdGlvbi5jb2xvcltpXSA8LSB2ZWMuY29uZGl0aW9uW2NvbmRpdGlvbltpXT09bGV2ZWxzKGNvbmRpdGlvbildCn0KaGVhdG1hcCA8LSBoZWF0bWFwLjIobWF0LCB0cmFjZT0ibm9uZSIsIGNvbCA9IHJldihobWNvbCksIG1hcmdpbj1jKDExLDExKSwgQ29sU2lkZUNvbG9ycz1jb25kaXRpb24uY29sb3IsClJvd1NpZGVDb2xvcnM9YmF0Y2guY29sb3IsIGtleT0iRkFMU0UiLCBzcnRDb2w9NDUpCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojREUgYW5hbHlzaXMKI1F1YW50aWxlIG5vcm1hbGl6ZSBjb3VudHMKY291bnRzU3ViUSA8LSBxTm9ybShjb3VudHMpCiNTcGVjaWZ5IG1vZGVsCm1vZCA9IG1vZGVsLm1hdHJpeCh+MCtjb25kaXRpb24rYmF0Y2gpCiNWaWV3IG1lYW4tdmFyaWFuY2UgdHJlbmQKdm9vbShjb3VudHNTdWJRLCBtb2QsIHBsb3Q9VFJVRSkKI1VzZSB2b29tIHRvIHRyYW5zZm9ybSBxdWFudGlsZS1ub3JtYWxpemVkIGNvdW50IGRhdGEgdG8gbG9nMi1jb3VudHMgcGVyIG1pbGxpb24sIGVzdGltYXRlIG1lYW4tdmFyaWFuY2UgcmVsYXRpb25zaGlwCiNhbmQgdXNlIG0tdiByZWxhdGlvbnNoaXAgdG8gY29tcHV0ZXIgYXBwcm9wcmlhdGUgb2JzZXJ2YXRpb25hbC1sZXZlbCB3ZWlnaHRzCnYgPC0gdm9vbShjb3VudHNTdWJRLCBtb2QpCiNGaXQgYSBsaW5lYXIgbW9kZWwgZm9yIGVhY2ggZ2VuZSB1c2luZyB0aGUgc3BlY2lmaWVkIGRlc2lnbiBjb250YWluZWQgaW4gdgpmaXQgPC0gbG1GaXQodikKIyNtZXRhYyB2IGFtYXN0NCMjCiNlQmF5ZXMgZmluZHMgYW4gRi1zdGF0aXN0aWMgZnJvbSB0aGUgc2V0IG9mIHQtc3RhdGlzdGljcyBmb3IgdGhhdCBnZW5lCm1ldGFjLmFtYXN0NC5jb250ci5tYXQgPC0gbWFrZUNvbnRyYXN0cyhtZXRhY192X2FtYXN0ND1jb25kaXRpb25hbWFzdDQtY29uZGl0aW9ubWV0YWMsIGxldmVscz12JGRlc2lnbikKbWV0YWMuYW1hc3Q0LmZpdCA8LSBjb250cmFzdHMuZml0KGZpdCwgbWV0YWMuYW1hc3Q0LmNvbnRyLm1hdCkKbWV0YWMuYW1hc3Q0LmViIDwtIGVCYXllcyhtZXRhYy5hbWFzdDQuZml0KQptZXRhYy5hbWFzdDQudG9wVGFiIDwtIHRvcFRhYmxlKG1ldGFjLmFtYXN0NC5lYiwgY29lZj0ibWV0YWNfdl9hbWFzdDQiLCBudW1iZXI9bnJvdyh2JEUpKQojVmlldyB0aGUgbGlzdCBvZiBERSBnZW5lcwpoZWFkKG1ldGFjLmFtYXN0NC50b3BUYWIsIG49M0wpCiMgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ0ZDICBBdmVFeHByICAgICAgICAgdCAgICAgIFAuVmFsdWUgICAgYWRqLlAuVmFsICAgICAgICBCCiNMbXhNLjMxLjE2ODAtMSAgICAgICAgLTMuMDQzNTQ2IDUuMDg1NTM3IC0yMC45ODY3NiAyLjM4MDc3MmUtMTUgMS45Nzg0MjJlLTExIDI0LjY1NDY2CiNMbXhNLjMwLjE0NTBwYXJ0aWFsLTEgIDIuNDI5MzY2IDkuNDg0ODI0ICAxOC43Mzk2MyAyLjE4MTA4M2UtMTQgNS4wMDk1MjJlLTExIDIzLjAyMDE5Cm1ldGFjLmFtYXN0NC50b3BUYWIkZm9sZF9jaGFuZ2UgPC0gMiBeIG1ldGFjLmFtYXN0NC50b3BUYWIkbG9nRkMKd3JpdGUuY3N2KGZpbGU9ImNzdi9sYW1hem9uZW5zaXNfbWV0YWNfdnNfYW1hc3Q0LmNzdiIsIHg9bWV0YWMuYW1hc3Q0LnRvcFRhYikKCiNMaW1pdCBsaXN0IHRvIGdlbmVzIHdpdGggYW4gYWRqdXN0ZWQgcCB2YWx1ZSA8IDAuMDUKbWV0YWMuYW1hc3Q0LnNpZ0dlbmVzIDwtIG1ldGFjLmFtYXN0NC50b3BUYWJbbWV0YWMuYW1hc3Q0LnRvcFRhYiRhZGouUC5WYWwgPDAuMDUsIF0KbGVuZ3RoKG1ldGFjLmFtYXN0NC5zaWdHZW5lcyRsb2dGQykKIzM4OTYKI0ZpbHRlciBvdXQgcm93cyB3aXRoIGxlc3MgdGhhbiAyLWZvbGQgY2hhbmdlIChsb2cyIGZvbGQgY2hhbmdlIG9mID4gMSkKbWV0YWMuYW1hc3Q0LnNpZ0dlbmVzRm9sZDEgPC0gc3Vic2V0KG1ldGFjLmFtYXN0NC5zaWdHZW5lcywgYWJzKGxvZ0ZDKSA+IDEpCmxlbmd0aChtZXRhYy5hbWFzdDQuc2lnR2VuZXNGb2xkMSRsb2dGQykKIzY0OQojRmlsdGVyIG91dCByb3dzIHdpdGggbGVzcyB0aGFuIDQtZm9sZCBjaGFuZ2UgKGxvZzIgZm9sZCBjaGFuZ2Ugb2YgPiAyKQptZXRhYy5hbWFzdDQuc2lnR2VuZXNGb2xkMiA8LSBzdWJzZXQobWV0YWMuYW1hc3Q0LnNpZ0dlbmVzLCBhYnMobG9nRkMpID4gMikKbGVuZ3RoKG1ldGFjLmFtYXN0NC5zaWdHZW5lc0ZvbGQyJGxvZ0ZDKQojNDQKCm1ldGFjLmFtYXN0NC5zaWdHZW5lcyA8LSBtZXRhYy5hbWFzdDQuc2lnR2VuZXNbb3JkZXIoLW1ldGFjLmFtYXN0NC5zaWdHZW5lcyRsb2dGQyksIF0KI01ha2UgYW4gTUEgcGxvdApzZWwgPSBtZXRhYy5hbWFzdDQudG9wVGFiJGFkai5QLlZhbCA8IDAuMDUKdG9wID0gbWV0YWMuYW1hc3Q0LnRvcFRhYgpzdWIgPSBwYXN0ZSgiTm8uIG9mIHNpZy4gZ2VuZXM6ICIsIHN1bShzZWwpLCIvIixsZW5ndGgoc2VsKSkKY3BtID0gdiRFCnBsb3Qocm93TWVhbnMoY3BtW3Jvd25hbWVzKHRvcCksXSksIHRvcCRsb2dGQywgcGNoPTE2LCBjZXg9MC41LGNvbD0iZGFya2dyZXkiLAogICAgICAgIG1haW49Im1ldGFjX2FtYXN0NCBtb2RlbCBiYXRjaCBhZGp1c3RlZCIsCiAgICAgICAgeWxhYj0ibG9nIEZDIiwgeGxhYj0iQXZlcmFnZSBFeHByZXNzaW9uIiwKICAgICAgICB5bGltPWMoLTMsMyksIHN1Yj1zdWIpCnBvaW50cyhyb3dNZWFucyhjcG1bcm93bmFtZXModG9wKSxdKVtzZWxdLCB0b3AkbG9nRkNbc2VsXSwgY29sPSJyZWQiLCBjZXg9MC41KQphYmxpbmUoaD1jKC0xLDAsMSksIGNvbD0icmVkIikKCiMjYW1hc3Q0IHYgYW1hc3QyNCMjCiNlQmF5ZXMgZmluZHMgYW4gRi1zdGF0aXN0aWMgZnJvbSB0aGUgc2V0IG9mIHQtc3RhdGlzdGljcyBmb3IgdGhhdCBnZW5lCmFtYXN0NC5hbWFzdDI0LmNvbnRyLm1hdCA8LSBtYWtlQ29udHJhc3RzKGFtYXN0NF92X2FtYXN0MjQ9Y29uZGl0aW9uYW1hc3QyNC1jb25kaXRpb25hbWFzdDQsIGxldmVscz12JGRlc2lnbikKYW1hc3Q0LmFtYXN0MjQuZml0IDwtIGNvbnRyYXN0cy5maXQoZml0LCBhbWFzdDQuYW1hc3QyNC5jb250ci5tYXQpCmFtYXN0NC5hbWFzdDI0LmViIDwtIGVCYXllcyhhbWFzdDQuYW1hc3QyNC5maXQpCmFtYXN0NC5hbWFzdDI0LnRvcFRhYiA8LSB0b3BUYWJsZShhbWFzdDQuYW1hc3QyNC5lYiwgY29lZj0iYW1hc3Q0X3ZfYW1hc3QyNCIsIG51bWJlcj1ucm93KHYkRSkpCgojVmlldyB0aGUgbGlzdCBvZiBERSBnZW5lcwpoZWFkKGFtYXN0NC5hbWFzdDI0LnRvcFRhYiwgbj0zTCkKIyAgICAgICAgICAgICAgICAgICBsb2dGQyAgQXZlRXhwciAgICAgICAgICB0ICAgICAgUC5WYWx1ZSAgICBhZGouUC5WYWwgICAgICAgICBCCiNMbXhNLjA5LjAwNjAtMSAgMS41NDMzNjQgOS4zMzI0NjAgIDEwLjk0NDY1NyA1LjAzODUwMmUtMTAgMy4zNDA0NjZlLTA2IDEyLjkxNTY3MQojTG14TS4xNy4wODkwLTEgLTEuNzEyMzE2IDcuNzA3MjE2IC0xMC42NTc4MTUgOC4wMzk2MjhlLTEwIDMuMzQwNDY2ZS0wNiAxMi40OTkxNDcKI0xteE0uMjMuMTY2NS0xIC0xLjY0NjY5OSA1LjUxNzQ4MCAgLTkuMjA3MTg5IDkuODU0NjEyZS0wOSAyLjcyOTcyN2UtMDUgIDkuOTg1Mzk0CiNMaW1pdCBsaXN0IHRvIGdlbmVzIHdpdGggYW4gYWRqdXN0ZWQgcCB2YWx1ZSA8IDAuMDUKYW1hc3Q0LmFtYXN0MjQuc2lnR2VuZXMgPC0gYW1hc3Q0LmFtYXN0MjQudG9wVGFiW2FtYXN0NC5hbWFzdDI0LnRvcFRhYiRhZGouUC5WYWwgPDAuMDUsIF0KbGVuZ3RoKGFtYXN0NC5hbWFzdDI0LnNpZ0dlbmVzJGxvZ0ZDKQojNTc3CiNGaWx0ZXIgb3V0IHJvd3Mgd2l0aCBsZXNzIHRoYW4gMi1mb2xkIGNoYW5nZSAobG9nMiBmb2xkIGNoYW5nZSBvZiA+IDEpCmFtYXN0NC5hbWFzdDI0LnNpZ0dlbmVzRm9sZDEgPC0gc3Vic2V0KGFtYXN0NC5hbWFzdDI0LnNpZ0dlbmVzLCBhYnMobG9nRkMpID4gMSkKbGVuZ3RoKGFtYXN0NC5hbWFzdDI0LnNpZ0dlbmVzRm9sZDEkbG9nRkMpCiMxMDQKI0ZpbHRlciBvdXQgcm93cyB3aXRoIGxlc3MgdGhhbiA0LWZvbGQgY2hhbmdlIChsb2cyIGZvbGQgY2hhbmdlIG9mID4gMikKYW1hc3Q0LmFtYXN0MjQuc2lnR2VuZXNGb2xkMiA8LSBzdWJzZXQoYW1hc3Q0LmFtYXN0MjQuc2lnR2VuZXMsIGFicyhsb2dGQykgPiAyKQpsZW5ndGgoYW1hc3Q0LmFtYXN0MjQuc2lnR2VuZXNGb2xkMiRsb2dGQykKIzEKYW1hc3Q0LmFtYXN0MjQuc2lnR2VuZXMgPC0gYW1hc3Q0LmFtYXN0MjQuc2lnR2VuZXNbb3JkZXIoLWFtYXN0NC5hbWFzdDI0LnNpZ0dlbmVzJGxvZ0ZDKSwgXQojTWFrZSBhbiBNQSBwbG90CnNlbCA9IGFtYXN0NC5hbWFzdDI0LnRvcFRhYiRhZGouUC5WYWwgPCAwLjA1CnRvcCA9IGFtYXN0NC5hbWFzdDI0LnRvcFRhYgpzdWIgPSBwYXN0ZSgiTm8uIG9mIHNpZy4gZ2VuZXM6ICIsIHN1bShzZWwpLCIvIixsZW5ndGgoc2VsKSkKY3BtID0gdiRFCnBsb3Qocm93TWVhbnMoY3BtW3Jvd25hbWVzKHRvcCksXSksIHRvcCRsb2dGQywgcGNoPTE2LCBjZXg9MC41LGNvbD0iZGFya2dyZXkiLAogICAgICAgIG1haW49ImFtYXN0NF9hbWFzdDI0IG1vZGVsIGJhdGNoIGFkanVzdGVkIiwKICAgICAgICB5bGFiPSJsb2cgRkMiLCB4bGFiPSJBdmVyYWdlIEV4cHJlc3Npb24iLAogICAgICAgIHlsaW09YygtMywzKSwgc3ViPXN1YikKcG9pbnRzKHJvd01lYW5zKGNwbVtyb3duYW1lcyh0b3ApLF0pW3NlbF0sIHRvcCRsb2dGQ1tzZWxdLCBjb2w9InJlZCIsIGNleD0wLjUpCmFibGluZShoPWMoLTEsMCwxKSwgY29sPSJyZWQiKQoKCiMjYW1hc3QyNCB2IGFtYXN0NDgjIwojZUJheWVzIGZpbmRzIGFuIEYtc3RhdGlzdGljIGZyb20gdGhlIHNldCBvZiB0LXN0YXRpc3RpY3MgZm9yIHRoYXQgZ2VuZQphbWFzdDI0LmFtYXN0NDguY29udHIubWF0IDwtIG1ha2VDb250cmFzdHMoYW1hc3QyNF92X2FtYXN0NDg9Y29uZGl0aW9uYW1hc3Q0OC1jb25kaXRpb25hbWFzdDI0LCBsZXZlbHM9diRkZXNpZ24pCmFtYXN0MjQuYW1hc3Q0OC5maXQgPC0gY29udHJhc3RzLmZpdChmaXQsIGFtYXN0MjQuYW1hc3Q0OC5jb250ci5tYXQpCmFtYXN0MjQuYW1hc3Q0OC5lYiA8LSBlQmF5ZXMoYW1hc3QyNC5hbWFzdDQ4LmZpdCkKYW1hc3QyNC5hbWFzdDQ4LnRvcFRhYiA8LSB0b3BUYWJsZShhbWFzdDI0LmFtYXN0NDguZWIsIGNvZWY9ImFtYXN0MjRfdl9hbWFzdDQ4IiwgbnVtYmVyPW5yb3codiRFKSkKI1ZpZXcgdGhlIGxpc3Qgb2YgREUgZ2VuZXMKaGVhZChhbWFzdDI0LmFtYXN0NDgudG9wVGFiLCBuPTNMKQojICAgICAgICAgICAgICAgICAgICBsb2dGQyAgQXZlRXhwciAgICAgICAgIHQgICAgICBQLlZhbHVlICAgIGFkai5QLlZhbCAgICAgICAgQgojTG14TS4wMi4wNDYwLTEgLTEuMDI3MDQ0MiA2LjQ4MTY4NyAtNy45NDMwNDkgMS4wODE1NjNlLTA3IDAuMDAwODk4Nzc4NyA0LjkzMzAwNQojTG14TS4zMC4xMTY1LTEgIDEuMDgxNzc0NiA1LjQ2MzAyMyAgNy4wMzg0MTMgNi44Mzg0MTBlLTA3IDAuMDAyODQxMzU5MyAzLjEyOTYwNgojTG14TS4zMC4xMTkwLTEgIDAuODk3NjE1NyA2LjEzNTU1NyAgNS45OTgwNDkgNi41MTgwNTllLTA2IDAuMDE4MDU1MDIyMiAyLjQxMzA4MAojTGltaXQgbGlzdCB0byBnZW5lcyB3aXRoIGFuIGFkanVzdGVkIHAgdmFsdWUgPCAwLjA1CmFtYXN0MjQuYW1hc3Q0OC5zaWdHZW5lcyA8LSBhbWFzdDI0LmFtYXN0NDgudG9wVGFiW2FtYXN0MjQuYW1hc3Q0OC50b3BUYWIkYWRqLlAuVmFsIDwwLjA1LCBdCmxlbmd0aChhbWFzdDI0LmFtYXN0NDguc2lnR2VuZXMkbG9nRkMpCiMzCiNGaWx0ZXIgb3V0IHJvd3Mgd2l0aCBsZXNzIHRoYW4gMi1mb2xkIGNoYW5nZSAobG9nMiBmb2xkIGNoYW5nZSBvZiA+IDEpCmFtYXN0MjQuYW1hc3Q0OC5zaWdHZW5lc0ZvbGQxIDwtIHN1YnNldChhbWFzdDI0LmFtYXN0NDguc2lnR2VuZXMsIGFicyhsb2dGQykgPiAxKQpsZW5ndGgoYW1hc3QyNC5hbWFzdDQ4LnNpZ0dlbmVzRm9sZDEkbG9nRkMpCiMyCiNGaWx0ZXIgb3V0IHJvd3Mgd2l0aCBsZXNzIHRoYW4gNC1mb2xkIGNoYW5nZSAobG9nMiBmb2xkIGNoYW5nZSBvZiA+IDIpCmFtYXN0MjQuYW1hc3Q0OC5zaWdHZW5lc0ZvbGQyIDwtIHN1YnNldChhbWFzdDI0LmFtYXN0NDguc2lnR2VuZXMsIGFicyhsb2dGQykgPiAyKQpsZW5ndGgoYW1hc3QyNC5hbWFzdDQ4LnNpZ0dlbmVzRm9sZDIkbG9nRkMpCiMwCmFtYXN0MjQuYW1hc3Q0OC5zaWdHZW5lcyA8LSBhbWFzdDI0LmFtYXN0NDguc2lnR2VuZXNbb3JkZXIoLWFtYXN0MjQuYW1hc3Q0OC5zaWdHZW5lcyRsb2dGQyksIF0KI01ha2UgYW4gTUEgcGxvdApzZWwgPSBhbWFzdDI0LmFtYXN0NDgudG9wVGFiJGFkai5QLlZhbCA8IDAuMDUKdG9wID0gYW1hc3QyNC5hbWFzdDQ4LnRvcFRhYgpzdWIgPSBwYXN0ZSgiTm8uIG9mIHNpZy4gZ2VuZXM6ICIsIHN1bShzZWwpLCIvIixsZW5ndGgoc2VsKSkKY3BtID0gdiRFCnBsb3Qocm93TWVhbnMoY3BtW3Jvd25hbWVzKHRvcCksXSksIHRvcCRsb2dGQywgcGNoPTE2LCBjZXg9MC41LGNvbD0iZGFya2dyZXkiLAogICAgICAgIG1haW49ImFtYXN0MjRfYW1hc3Q0OCBtb2RlbCBiYXRjaCBhZGp1c3RlZCIsCiAgICAgICAgeWxhYj0ibG9nIEZDIiwgeGxhYj0iQXZlcmFnZSBFeHByZXNzaW9uIiwKICAgICAgICB5bGltPWMoLTMsMyksIHN1Yj1zdWIpCnBvaW50cyhyb3dNZWFucyhjcG1bcm93bmFtZXModG9wKSxdKVtzZWxdLCB0b3AkbG9nRkNbc2VsXSwgY29sPSJyZWQiLCBjZXg9MC41KQphYmxpbmUoaD1jKC0xLDAsMSksIGNvbD0icmVkIikKCgojI2FtYXN0NDggdiBhbWFzdDcyIyMKI2VCYXllcyBmaW5kcyBhbiBGLXN0YXRpc3RpYyBmcm9tIHRoZSBzZXQgb2YgdC1zdGF0aXN0aWNzIGZvciB0aGF0IGdlbmUKYW1hc3Q0OC5hbWFzdDcyLmNvbnRyLm1hdCA8LSBtYWtlQ29udHJhc3RzKGFtYXN0NDhfdl9hbWFzdDcyPWNvbmRpdGlvbmFtYXN0NzItY29uZGl0aW9uYW1hc3Q0OCwgbGV2ZWxzPXYkZGVzaWduKQphbWFzdDQ4LmFtYXN0NzIuZml0IDwtIGNvbnRyYXN0cy5maXQoZml0LCBhbWFzdDQ4LmFtYXN0NzIuY29udHIubWF0KQphbWFzdDQ4LmFtYXN0NzIuZWIgPC0gZUJheWVzKGFtYXN0NDguYW1hc3Q3Mi5maXQpCmFtYXN0NDguYW1hc3Q3Mi50b3BUYWIgPC0gdG9wVGFibGUoYW1hc3Q0OC5hbWFzdDcyLmViLCBjb2VmPSJhbWFzdDQ4X3ZfYW1hc3Q3MiIsIG51bWJlcj1ucm93KHYkRSkpCgojVmlldyB0aGUgbGlzdCBvZiBERSBnZW5lcwpoZWFkKGFtYXN0NDguYW1hc3Q3Mi50b3BUYWIsIG49M0wpCiMgICAgICAgICAgICAgICAgICAgICAgIGxvZ0ZDICAgQXZlRXhwciAgICAgICAgIHQgICAgICBQLlZhbHVlIGFkai5QLlZhbCAgICAgICAgIEIKI0xteE0uMDIuMDQ2MC0xICAgIC0wLjY0MzMyMTAgIDYuNDgxNjg3IC00LjU4NDkzMiAwLjAwMDE2ODk4OTEgMC45OTg3MzQzIC0yLjk3MDQ0OAojTG14TS4xMy4wMzkwLTEgICAgLTAuNDcwOTc1MSAxMi40MDQ5NjUgLTMuNTY1MTIxIDAuMDAxODc4MjQxOSAwLjk5ODczNDMgLTMuMTkwMzQ3CiNMbXhNLjA4XzI5LjAyNTEtMSAtMC43NDY2MTkyICA2LjIxNTkyMiAtMy43MDA5NjYgMC4wMDEzNjUwNDI1IDAuOTk4NzM0MyAtMy4yNDgzMTEKI0xpbWl0IGxpc3QgdG8gZ2VuZXMgd2l0aCBhbiBhZGp1c3RlZCBwIHZhbHVlIDwgMC4wNQphbWFzdDQ4LmFtYXN0NzIuc2lnR2VuZXMgPC0gYW1hc3Q0OC5hbWFzdDcyLnRvcFRhYlthbWFzdDQ4LmFtYXN0NzIudG9wVGFiJGFkai5QLlZhbCA8MC4wNSwgXQpsZW5ndGgoYW1hc3Q0OC5hbWFzdDcyLnNpZ0dlbmVzJGxvZ0ZDKQojMAojTWFrZSBhbiBNQSBwbG90CnNlbCA9IGFtYXN0NDguYW1hc3Q3Mi50b3BUYWIkYWRqLlAuVmFsIDwgMC4wNQp0b3AgPSBhbWFzdDQ4LmFtYXN0NzIudG9wVGFiCnN1YiA9IHBhc3RlKCJOby4gb2Ygc2lnLiBnZW5lczogIiwgc3VtKHNlbCksIi8iLGxlbmd0aChzZWwpKQpjcG0gPSB2JEUKcGxvdChyb3dNZWFucyhjcG1bcm93bmFtZXModG9wKSxdKSwgdG9wJGxvZ0ZDLCBwY2g9MTYsIGNleD0wLjUsY29sPSJkYXJrZ3JleSIsCiAgICAgICAgbWFpbj0iYW1hc3Q0OF9hbWFzdDcyIG1vZGVsIGJhdGNoIGFkanVzdGVkIiwKICAgICAgICB5bGFiPSJsb2cgRkMiLCB4bGFiPSJBdmVyYWdlIEV4cHJlc3Npb24iLAogICAgICAgIHlsaW09YygtMywzKSwgc3ViPXN1YikKcG9pbnRzKHJvd01lYW5zKGNwbVtyb3duYW1lcyh0b3ApLF0pW3NlbF0sIHRvcCRsb2dGQ1tzZWxdLCBjb2w9InJlZCIsIGNleD0wLjUpCmFibGluZShoPWMoLTEsMCwxKSwgY29sPSJyZWQiKQpgYGAK