Reading in the Data from Deliverable 1 Will take a subset of this data which includes country, health expenditure levels in 2018, life expectancy in 2018, and the country’s gini coefficient (measuring inequality in the country, with higher scores meaning higher inequality.)

NOTE FOR WHOLE DELIVERABLE: R instance could not load rgl, a required package for many of these sections (got errors with neverending loading.) The section taking out only the poorly scoring countries based on silhouettes would not run.

allData <- read.csv ("https://raw.githubusercontent.com/rhsu4/542_Deliv1/main/allDataWide.csv")
Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 
row.names(allData) = NULL

#check data types
str(allData)
'data.frame':   193 obs. of  9 variables:
 $ Country    : chr  "Afghanistan" "Albania" "Algeria" "Andorra" ...
 $ HE2002     : num  78 314 335 2196 119 ...
 $ HE2010     : num  138 452 648 2771 168 ...
 $ HE2018     : num  186 697 963 3607 165 ...
 $ GiniPercent: num  NA 33.2 27.6 NA 51.3 NA 41.4 34.4 34.4 29.7 ...
 $ GiniYear   : num  NA 2017 2011 NA 2018 ...
 $ LE2002     : chr  "56.784" "74.579" "71.605" ".." ...
 $ LE2010     : chr  "61.028" "76.562" "74.938" ".." ...
 $ LE2018     : chr  "64.486" "78.458" "76.693" ".." ...
#Have to make LE2018 numeric
allData$LE2018<-as.numeric(allData$LE2018)
NAs introduced by coercion
str(allData)
'data.frame':   193 obs. of  9 variables:
 $ Country    : chr  "Afghanistan" "Albania" "Algeria" "Andorra" ...
 $ HE2002     : num  78 314 335 2196 119 ...
 $ HE2010     : num  138 452 648 2771 168 ...
 $ HE2018     : num  186 697 963 3607 165 ...
 $ GiniPercent: num  NA 33.2 27.6 NA 51.3 NA 41.4 34.4 34.4 29.7 ...
 $ GiniYear   : num  NA 2017 2011 NA 2018 ...
 $ LE2002     : chr  "56.784" "74.579" "71.605" ".." ...
 $ LE2010     : chr  "61.028" "76.562" "74.938" ".." ...
 $ LE2018     : num  64.5 78.5 76.7 NA 60.8 ...

Preparing Data for clustering

#Setting row names as country names doesn't work because countries are repeating
selection=c("Country", "GiniPercent", "HE2018", "LE2018")
dataToCluster=allData[,selection]

#set labels as row index

row.names(dataToCluster) = dataToCluster$Country
dataToCluster$Country=NULL

#This will give you an error if the country is repeated (because row index names need to be unique)

#Decide if data needs to be transformed
boxplot(dataToCluster, horizontal=T)

#Yes, has to be transformed, on different scales

Standardizing Data, because on a different scale

#### standardizing
DataToClusterStd<-as.data.frame(scale(dataToCluster))

### or smoothing
#log(DataToClusterStd)

boxplot(DataToClusterStd)

  1. Compute the DISTANCE MATRIX
set.seed(999) # this is for replicability of results
dtcsFinal <- na.omit(DataToClusterStd)
Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 
#This includes only instances that have no missing values (153 obs left)
library(cluster)
dtcsFinal_DM = daisy (x=dtcsFinal, metric = "gower")

Compute Clusters - Computer suggestions Using function fviz_nbclust from the library factoextra we can see how many clustered are suggested.

#for partitioning
library(factoextra)
Loading required package: ggplot2
Registered S3 methods overwritten by 'rgl':
  method               from
  knit_print.rglId         
  knit_print.rglOpen3d     
  sew.rglRecordedplot      
Error in dyn.load(dynlib <- getDynlib(dir)) : 
  unable to load shared object '/Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so':
  dlopen(/Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so, 0x0006): Library not loaded: /opt/X11/lib/libGLU.1.dylib
  Referenced from: /Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so
  Reason: tried: '/opt/X11/lib/libGLU.1.dylib' (no such file), '/Library/Frameworks/R.framework/Resources/lib/libGLU.1.dylib' (no such file), '/Users/Becca/lib/libGLU.1.dylib' (no such file), '/usr/local/lib/libGLU.1.dylib' (no such file), '/usr/lib/libGLU.1.dylib' (no such file), '/libGLU.1.dylib' (no such file), '/libGLU.1.dylib' (no such file), '/lib/libGLU.1.dylib' (no such file), '/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/server/libGLU.1.dylib' (no such file)
Warning:    Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330
Warning: Trying without OpenGL...
Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
#Missing values - have to either add imputed (mean) values, or remove variables that have missing data
##Life Expectancy - have to replace ".." with "NaN" (in python?)
##health expectancy - maybe just use this for now, and drop missing countries


fviz_nbclust(dtcsFinal, 
             pam,
             diss=dataToCluster_DM,
             method = "gap_stat",
             k.max = 10,verbose = F)


#Optimal number of clusters = 9
#hierarchical - agglomerative 
fviz_nbclust(dtcsFinal, 
             hcut,
             diss=dataToCluster_DM,
             method = "gap_stat",
             k.max = 10,
             verbose = F,
             hc_func = "agnes")

#agglomerative optimal # of clusters = 4
#hierarchical (divisive)
fviz_nbclust(dtcsFinal, 
             hcut,
             diss=dataToCluster_DM,
             method = "gap_stat",
             k.max = 10,
             verbose = F,
             hc_func = "diana")


#divisive clusters = 2

Apply function a priori clusters: (partitioning? first kind) = 9 agglomerative = 4 (or 8, test both) divisive = 7 (or 2, test both)

Because the agglomerative and divisive approaches had local maximums, I tested both the suggested number of clusters and the later maximums to see which gave the highest average silhouette width.

NumberOfClusterDesired=4

#For clusters = 9, highest avg silhouette width = .33
#For clusters = 4, highest avg silhouette width = .37 (pam and agnes)
#For clusters = 2, highest avg silhouette width = .38 (pam and diana)

#For clusters = 7, highest avg silhouette width = .34 (agnes)
#For clusters = 8, highest avg silhouette width = .34 (diana)


#FLAG: Is 2 clusters enough clusters?
#Will go with 4, highest avg silhouette width while > 2 clusters

# Partitioning technique
res.pam = pam(x=dataToCluster_DM,
              k = NumberOfClusterDesired,
              cluster.only = F)

# Hierarchical technique- agglomerative approach

#library(factoextra)
res.agnes= hcut(dataToCluster_DM, 
                k = NumberOfClusterDesired,
                isdiss=TRUE,
                hc_func='agnes',
                hc_method = "ward.D2")

# Hierarchical technique- divisive approach
res.diana= hcut(dataToCluster_DM, 
                k = NumberOfClusterDesired,
                isdiss=TRUE,
                hc_func='diana',
                hc_method = "ward.D2")
#Is recoding supposed to put these in order?
library(dplyr)

Attaching package: ‘dplyr’

The following object is masked from ‘package:car’:

    recode

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
  1. Clustering Results Creating clusters using the different techniques and with the optimal cluster number (4).
#2.1 Add results to original data frame:
dtcsFinal$pam=as.factor(res.pam$clustering)
dtcsFinal$agn=as.factor(res.agnes$cluster)
dtcsFinal$dia=as.factor(res.diana$cluster)
#Verify ordinality in clusters
#aggregate(data=dtcsFinal,
#          Overallscore~pam, #how do we know what the dependent variable should be?
#          FUN=mean)

aggregate(data=dtcsFinal,
          LE2018~pam,
          FUN=mean)
#FLAG: Why is this not ordering low to high?
aggregate(data=dtcsFinal,
         LE2018~agn,
          FUN=mean)
aggregate(data=dtcsFinal,
          LE2018~dia,
          FUN=mean)

Reordering the clusters based on above

dtcsFinal$pam=dplyr::recode_factor(dtcsFinal$pam, 
                  `1` = '2',`2`='1',`3`='3',`4`='4')
dtcsFinal$agn=dplyr::recode_factor(dtcsFinal$agn, 
                  `1` = '2',`2`='4',`3`='4',`4`='3')
dtcsFinal$dia=dplyr::recode_factor(dtcsFinal$dia, 
                  `1` = '3',`2`='2',`3`='4',`4`='1')
  1. Evaluate Results

fviz_silhouette(res.agnes)
NA

library(factoextra)
fviz_silhouette(res.diana)
NA

3.2 Detecting badly clustered cases

save individual silhouettes

head(data.frame(res.pam$silinfo$widths),10)

#Reordering cluster indices doesn't seeem to affect nearest neighbor. Why reorder?

Keeping only the negative clusters

pamEval=data.frame(res.pam$silinfo$widths)
agnEval=data.frame(res.agnes$silinfo$widths)
diaEval=data.frame(res.diana$silinfo$widths)

pamPoor=rownames(pamEval[pamEval$sil_width<0,])
agnPoor=rownames(agnEval[agnEval$sil_width<0,])
diaPoor=rownames(diaEval[diaEval$sil_width<0,])
#install."qpcr"
library("qpcR")

^^NOTE for homework: could not get “qpcr” to work because rgl wouldn’t work. Tried installing pckgs separately, uninstalling whole thing, didn’t work

#If I can ever get rgl to work - see which instances are badly clustered
bap_Clus=as.data.frame(qpcR:::cbind.na(sort(pamPoor), sort(agnPoor),sort(diaPoor)))
Error in loadNamespace(j <- i[[1L]], c(lib.loc, .libPaths()), versionCheck = vI[[j]]) : 
  there is no package called ‘rgl’

HOW TO COMPARE CLUSTERING

Prepare a bidimensional map. The function cmdscale can produce a two dimension map of points using the distance matrix:

projectedData = cmdscale(dataToCluster_DM, k=2)

The object projectedData is saving coordinates for each element in the data:

#
# save coordinates to original data frame:
dtcsFinal$dim1 = projectedData[,1]
dtcsFinal$dim2 = projectedData[,2]

# see some:

dtcsFinal[,c('dim1','dim2')][1:10,]

Use those points and see the “map”:

#base= ggplot(data=dtcsFinal,
#             aes(x=dim1, y=dim2,
#                 label=Country)) 
#base + geom_text(size=2)

base= ggplot(data=dtcsFinal,
             aes(x=dim1, y=dim2,
                label = rownames(dtcsFinal))) 
base + geom_text(size=2)

Color the map using the labels from PAM:

pamPlot=base + labs(title = "PAM") + geom_point(size=2,
                                              aes(color=pam),
                                              show.legend = T) 

Color the map using the labels from Hierarchical AGNES:

agnPlot=base + labs(title = "AGNES") + geom_point(size=2,
                                              aes(color=agn),
                                              show.legend = T) 

Color the map using the labels from Hierarchical DIANA:

diaPlot=base + labs(title = "DIANA") + geom_point(size=2,
                                              aes(color=dia),
                                              show.legend = T) 

Compare visually:

library(ggpubr)

ggarrange(pamPlot, agnPlot, diaPlot,ncol = 3,common.legend = T)

Annotating outliers:

Prepare labels FLAG: need to have country var I think, this code doesn’t work without it. Or rowname?

# If name of country in black list, use it, else get rid of it
#LABELpam=ifelse(dtcsFinal$rowname%in%pamPoor,dtcsFinal$rowname,"")
#LABELdia=ifelse(dtcsFinal$Country%in%diaPoor,dtcsFinal$Country,"")
#LABELagn=ifelse(dtcsFinal$Country%in%agnPoor,dtcsFinal$Country,"")

LABELpam=ifelse(dtcsFinal$rowname%in%pamPoor,dtcsFinal$rowname,"")
LABELdia=ifelse(dtcsFinal$rowname%in%diaPoor,dtcsFinal$rowname,"")
LABELagn=ifelse(dtcsFinal$rowname%in%agnPoor,dtcsFinal$rowname,"")
library(ggrepel)
pamPlot + geom_text_repel(aes(label=LABELpam))
Error in `check_aesthetics()`:
! Aesthetics must be either length 1 or the same as the data (153): label
Backtrace:
 1. base `<fn>`(x)
 2. ggplot2:::print.ggplot(x)
 4. ggplot2:::ggplot_build.ggplot(x)
 5. ggplot2 by_layer(function(l, d) l$compute_aesthetics(d, plot))
 6. ggplot2 f(l = layers[[i]], d = data[[i]])
 7. l$compute_aesthetics(d, plot)
 8. ggplot2 f(..., self = self)
 9. ggplot2:::check_aesthetics(evaled, n)

diaPlot + geom_text_repel(aes(label=LABELdia))
Error in `check_aesthetics()`:
! Aesthetics must be either length 1 or the same as the data (153): label
Backtrace:
 1. base `<fn>`(x)
 2. ggplot2:::print.ggplot(x)
 4. ggplot2:::ggplot_build.ggplot(x)
 5. ggplot2 by_layer(function(l, d) l$compute_aesthetics(d, plot))
 6. ggplot2 f(l = layers[[i]], d = data[[i]])
 7. l$compute_aesthetics(d, plot)
 8. ggplot2 f(..., self = self)
 9. ggplot2:::check_aesthetics(evaled, n)
Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 

agnPlot + geom_text_repel(aes(label=LABELagn))

NOTE: Above section doesn’t work because it depends on rgl (in qpcR) which won’t load or install

The Dendogram (for hierarchical approaches)

fviz_dend(res.agnes,k=NumberOfClusterDesired, cex = 0.45, horiz = T,main = "AGNES approach")
Registered S3 methods overwritten by 'rgl':
  method               from
  knit_print.rglId         
  knit_print.rglOpen3d     
  sew.rglRecordedplot      
Error in dyn.load(dynlib <- getDynlib(dir)) : 
  unable to load shared object '/Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so':
  dlopen(/Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so, 0x0006): Library not loaded: /opt/X11/lib/libGLU.1.dylib
  Referenced from: /Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so
  Reason: tried: '/opt/X11/lib/libGLU.1.dylib' (no such file), '/Library/Frameworks/R.framework/Resources/lib/libGLU.1.dylib' (no such file), '/Users/Becca/lib/libGLU.1.dylib' (no such file), '/usr/local/lib/libGLU.1.dylib' (no such file), '/usr/lib/libGLU.1.dylib' (no such file), '/libGLU.1.dylib' (no such file), '/libGLU.1.dylib' (no such file), '/lib/libGLU.1.dylib' (no such file), '/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/server/libGLU.1.dylib' (no such file)
In addition: Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 
Warning:    Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330
Warning: Trying without OpenGL...
`guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> = "none")` instead.

fviz_dend(res.diana,k=NumberOfClusterDesired, cex = 0.45, horiz = T,main = "DIANA approach")
Registered S3 methods overwritten by 'rgl':
  method               from
  knit_print.rglId         
  knit_print.rglOpen3d     
  sew.rglRecordedplot      
Error in dyn.load(dynlib <- getDynlib(dir)) : 
  unable to load shared object '/Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so':
  dlopen(/Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so, 0x0006): Library not loaded: /opt/X11/lib/libGLU.1.dylib
  Referenced from: /Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so
  Reason: tried: '/opt/X11/lib/libGLU.1.dylib' (no such file), '/Library/Frameworks/R.framework/Resources/lib/libGLU.1.dylib' (no such file), '/Users/Becca/lib/libGLU.1.dylib' (no such file), '/usr/local/lib/libGLU.1.dylib' (no such file), '/usr/lib/libGLU.1.dylib' (no such file), '/libGLU.1.dylib' (no such file), '/libGLU.1.dylib' (no such file), '/lib/libGLU.1.dylib' (no such file), '/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/server/libGLU.1.dylib' (no such file)
Warning:    Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330
Warning: Trying without OpenGL...
`guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> = "none")` instead.

Factor Analysis - Latent Concepts

#Creating FA data
Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 
#selection
dataForFA = dtcsFinal
names(dataForFA)
[1] "GiniPercent" "HE2018"      "LE2018"     
library(lavaan)
model = 'healthsys=~ HE2018 + LE2018 + GiniPercent'
Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 
fit <- cfa(model, data = dataForFA, std.lv = TRUE)
indexCFA=lavPredict(fit)
indexCFA[1:10]
 [1]  0.47060846  0.47371795 -1.30874907  0.35562305  0.22450684  1.39878912  1.52759672  0.14741568
 [9] -0.07564263  0.34613209
Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 
#Rescale to 0:10

library(scales)
indexCFANorm=rescale(as.vector(indexCFA), 
                     to = c(0, 10))
indexCFANorm[1:10]
 [1] 6.275947 6.283759 1.805721 5.987073 5.657673 8.607787 8.931387 5.463999 4.903617 5.963229
#This is our index

dataForFA$demo_FA=indexCFANorm

Comparing new index with original score

base=ggplot(data=dataForFA,
            aes(x=demo_FA,y=LE2018))
base+geom_point()


evalCFA1=parameterEstimates(fit, standardized =TRUE)

evalCFA1[evalCFA1$op=="=~",c('rhs','std.all','pvalue')]
NA
NA

Some coefficients

evalCFA2=as.list(fitMeasures(fit))

You want p.value of chi-square greater than .05

evalCFA2[c("chisq", "df", "pvalue")] 
$chisq
[1] 1.358913e-13

$df
[1] 0

$pvalue
[1] NA
Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 

This is not a greater p-value than .05

You want Tucker-Lewis > .9

evalCFA2$tli # > 0.90
[1] 1

This is does satisfy Tucker-Lewis criteria

You want RMSEA < 0.05:

evalCFA2[c( 'rmsea.ci.lower','rmsea','rmsea.ci.upper')] 
$rmsea.ci.lower
[1] 0

$rmsea
[1] 0

$rmsea.ci.upper
[1] 0
Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 

Does satisfy RMSEA critera

See how it looks:

#install.packages("semPlot")
Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 
library(semPlot)
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
Registered S3 methods overwritten by 'rgl':
  method               from
  knit_print.rglId         
  knit_print.rglOpen3d     
  sew.rglRecordedplot      
Error in dyn.load(dynlib <- getDynlib(dir)) : 
  unable to load shared object '/Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so':
  dlopen(/Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so, 0x0006): Library not loaded: /opt/X11/lib/libGLU.1.dylib
  Referenced from: /Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so
  Reason: tried: '/opt/X11/lib/libGLU.1.dylib' (no such file), '/Library/Frameworks/R.framework/Resources/lib/libGLU.1.dylib' (no such file), '/Users/Becca/lib/libGLU.1.dylib' (no such file), '/usr/local/lib/libGLU.1.dylib' (no such file), '/usr/lib/libGLU.1.dylib' (no such file), '/libGLU.1.dylib' (no such file), '/libGLU.1.dylib' (no such file), '/lib/libGLU.1.dylib' (no such file), '/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/server/libGLU.1.dylib' (no such file)
Warning:    Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330
Warning: Trying without OpenGL...
semPaths(fit, what='std', nCharNodes=0, sizeMan=12,
         edge.label.cex=1.5, fade=T,residuals = F)

Health expenditure and Life expectancy are positively associated with model, gini percent is negatively associated. Life expectancy is most associated with the health system

REGRESSION

Outcome variable as Life Expectancy, HE2018 and GiniPercent as independent variables?

regData = dtcsFinal
Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 
  1. State hypothesis: Health Expenditure and the Gini Index of a country have an impact on the life expectancy in that country

Prepare your hypothesis:

#FLAG -  Gini is negatively coded (higher gini = higher inequality)
Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 
# hypothesis 1: 2018LE increases as gini percent DECREASES (higher equality):
hypo1=formula(LE2018~ GiniPercent)

# hypothesis 2: 2018 LE increases as health expenditure of a country increases 

hypo2=formula(LE2018~ HE2018)

#hypothesis 3: 2018 LE increases with higher health expenditure and lower gini score
# -  does this mean needing to make gini negative?
hypo3=formula(LE2018~ HE2018 + GiniPercent)
  1. Compute regression models
#
# results
gauss1=glm(hypo1,
           data = regData,
           family = 'gaussian')

gauss2=glm(hypo2,
           data = regData,
           family = 'gaussian')


gauss3=glm(hypo3,
           data = regData,
           family = 'gaussian')
  1. See Results

Hypothesis 1:

summary(gauss1)

Call:
glm(formula = hypo1, family = "gaussian", data = regData)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-2.5296  -0.7054   0.2065   0.7032   1.5589  

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -0.02443    0.07543  -0.324    0.746    
GiniPercent -0.42332    0.07531  -5.621 8.93e-08 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for gaussian family taken to be 0.8704231)

    Null deviance: 158.93  on 152  degrees of freedom
Residual deviance: 131.43  on 151  degrees of freedom
AIC: 416.95

Number of Fisher Scoring iterations: 2
Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 

– yes, negative coeff on gini percent, p<.05

Hypothesis 2

summary(gauss2)

Call:
glm(formula = hypo2, family = "gaussian", data = regData)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-4.2330  -0.3632   0.2508   0.5781   1.1319  

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -0.02489    0.06767  -0.368    0.714    
HE2018       0.56127    0.06444   8.710 4.97e-15 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for gaussian family taken to be 0.7005489)

    Null deviance: 158.93  on 152  degrees of freedom
Residual deviance: 105.78  on 151  degrees of freedom
AIC: 383.73

Number of Fisher Scoring iterations: 2

coefficient on health expenditure is positive, p>.05

summary(gauss3)

Call:
glm(formula = hypo3, family = "gaussian", data = regData)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-3.8734  -0.3875   0.1500   0.5842   1.4118  

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -0.02272    0.06516  -0.349 0.727837    
HE2018       0.47876    0.06618   7.234 2.25e-11 ***
GiniPercent -0.24870    0.06940  -3.584 0.000457 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for gaussian family taken to be 0.6496024)

    Null deviance: 158.93  on 152  degrees of freedom
Residual deviance:  97.44  on 150  degrees of freedom
AIC: 373.16

Number of Fisher Scoring iterations: 2

Hypothesis as expected, HE 2018 pos coeff & significant, GiniPercent negative coeff and significant

  1. Search for a better model
anova(gauss1, gauss2, test="Chisq")
Analysis of Deviance Table

Model 1: LE2018 ~ GiniPercent
Model 2: LE2018 ~ HE2018
  Resid. Df Resid. Dev Df Deviance Pr(>Chi)
1       151     131.43                     
2       151     105.78  0   25.651         
anova(gauss1, gauss3, test="Chisq")
Analysis of Deviance Table

Model 1: LE2018 ~ GiniPercent
Model 2: LE2018 ~ HE2018 + GiniPercent
  Resid. Df Resid. Dev Df Deviance  Pr(>Chi)    
1       151     131.43                          
2       150      97.44  1   33.994 4.692e-13 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
anova(gauss2, gauss3, test="Chisq")
Analysis of Deviance Table

Model 1: LE2018 ~ HE2018
Model 2: LE2018 ~ HE2018 + GiniPercent
  Resid. Df Resid. Dev Df Deviance  Pr(>Chi)    
1       151     105.78                          
2       150      97.44  1   8.3425 0.0003388 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Model for the third hypothesis is chosen (combined HE + gini)

#install.packages("rsq")
library(rsq)
rsq(gauss3, adj=T)
[1] 0.3787309

Model 3 has the highest r2 at .379

  1. Verify the situation of the chosen model:

5.1 Linearity between dependent variable and predictors is assumed, then these dots should follow a linear and horizontal trend

plot(gauss3,1)
Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 

Linear relationship doesn’t hold

5.2 Normality of residuals is assumed Visual exploration

plot(gauss3,2)
Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 

Mathematical exploration

# The data is normal if the p-value is above 0.05
shapiro.test(gauss3$residuals)

    Shapiro-Wilk normality test

data:  gauss3$residuals
W = 0.92613, p-value = 4.317e-07

so, data is not normally distributed

5.3. Homoscedasticity is assumed, so you need to check if residuals are spread equally along the ranges of predictors:

Visual exploration

plot(gauss2, 3)
Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 

Mathematical exploration

#install.packages("lmtest")
library(lmtest)
Loading required package: zoo

Attaching package: ‘zoo’

The following objects are masked from ‘package:base’:

    as.Date, as.Date.numeric
#pvalue<0.05 you cannot assume Homoscedasticity
Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 
bptest(gauss3) 

    studentized Breusch-Pagan test

data:  gauss3
BP = 17.152, df = 2, p-value = 0.0001886

Cannot assume homoskedacity; p<.05

5.4. We assume that there is no colinearity, that is, that the predictors are not correlated.

library(car)
Loading required package: carData
Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 
vif(gauss3)
     HE2018 GiniPercent 
   1.137649    1.137649 
Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 

yes, lower than 5 - collinearity is not a problem

5.5. Analize the effect of atypical values. Determine if outliers (points that are far from the rest, but still in the trend) or high-leverage points (far from the trend but close to the rest) are influential:

Visual exploration

plot(gauss3,5)
Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 

??What does this mean

Querying

gaussInf=as.data.frame(influence.measures(gauss3)$is.inf)
Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 
gaussInf[gaussInf$cook.d,]
  1. Finally, a nice summary plot of your work:
#install.packages("sjPlot")
library(sjPlot)
plot_models(gauss3,vline.color="grey")
Registered S3 methods overwritten by 'rgl':
  method               from
  knit_print.rglId         
  knit_print.rglOpen3d     
  sew.rglRecordedplot      
Error in dyn.load(dynlib <- getDynlib(dir)) : 
  unable to load shared object '/Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so':
  dlopen(/Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so, 0x0006): Library not loaded: /opt/X11/lib/libGLU.1.dylib
  Referenced from: /Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so
  Reason: tried: '/opt/X11/lib/libGLU.1.dylib' (no such file), '/Library/Frameworks/R.framework/Resources/lib/libGLU.1.dylib' (no such file), '/Users/Becca/lib/libGLU.1.dylib' (no such file), '/usr/local/lib/libGLU.1.dylib' (no such file), '/usr/lib/libGLU.1.dylib' (no such file), '/libGLU.1.dylib' (no such file), '/libGLU.1.dylib' (no such file), '/lib/libGLU.1.dylib' (no such file), '/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/server/libGLU.1.dylib' (no such file)
Warning:    Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330
Warning: Trying without OpenGL...

PREDICTIVE APPROACH 1. Split the data set

Registered S3 methods overwritten by 'rgl':
  method               from
  knit_print.rglId         
  knit_print.rglOpen3d     
  sew.rglRecordedplot      
Error in dyn.load(dynlib <- getDynlib(dir)) : 
  unable to load shared object '/Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so':
  dlopen(/Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so, 0x0006): Library not loaded: /opt/X11/lib/libGLU.1.dylib
  Referenced from: /Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so
  Reason: tried: '/opt/X11/lib/libGLU.1.dylib' (no such file), '/Library/Frameworks/R.framework/Resources/lib/libGLU.1.dylib' (no such file), '/Users/Becca/lib/libGLU.1.dylib' (no such file), '/usr/local/lib/libGLU.1.dylib' (no such file), '/usr/lib/libGLU.1.dylib' (no such file), '/libGLU.1.dylib' (no such file), '/libGLU.1.dylib' (no such file), '/lib/libGLU.1.dylib' (no such file), '/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/server/libGLU.1.dylib' (no such file)
In addition: Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 
Warning:    Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330
Warning: Trying without OpenGL...
Registered S3 methods overwritten by 'rgl':
  method               from
  knit_print.rglId         
  knit_print.rglOpen3d     
  sew.rglRecordedplot      
Error in dyn.load(dynlib <- getDynlib(dir)) : 
  unable to load shared object '/Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so':
  dlopen(/Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so, 0x0006): Library not loaded: /opt/X11/lib/libGLU.1.dylib
  Referenced from: /Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so
  Reason: tried: '/opt/X11/lib/libGLU.1.dylib' (no such file), '/Library/Frameworks/R.framework/Resources/lib/libGLU.1.dylib' (no such file), '/Users/Becca/lib/libGLU.1.dylib' (no such file), '/usr/local/lib/libGLU.1.dylib' (no such file), '/usr/lib/libGLU.1.dylib' (no such file), '/libGLU.1.dylib' (no such file), '/libGLU.1.dylib' (no such file), '/lib/libGLU.1.dylib' (no such file), '/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/server/libGLU.1.dylib' (no such file)
Warning:    Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330
Warning: Trying without OpenGL...
#install.packages("caret")
Registered S3 methods overwritten by 'rgl':
  method               from
  knit_print.rglId         
  knit_print.rglOpen3d     
  sew.rglRecordedplot      
Error in dyn.load(dynlib <- getDynlib(dir)) : 
  unable to load shared object '/Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so':
  dlopen(/Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so, 0x0006): Library not loaded: /opt/X11/lib/libGLU.1.dylib
  Referenced from: /Library/Frameworks/R.framework/Versions/4.1/Resources/library/rgl/libs/rgl.so
  Reason: tried: '/opt/X11/lib/libGLU.1.dylib' (no such file), '/Library/Frameworks/R.framework/Resources/lib/libGLU.1.dylib' (no such file), '/Users/Becca/lib/libGLU.1.dylib' (no such file), '/usr/local/lib/libGLU.1.dylib' (no such file), '/usr/lib/libGLU.1.dylib' (no such file), '/libGLU.1.dylib' (no such file), '/libGLU.1.dylib' (no such file), '/lib/libGLU.1.dylib' (no such file), '/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/server/libGLU.1.dylib' (no such file)
Warning:    Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330
Warning: Trying without OpenGL...
set.seed(123)
Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 
selection = createDataPartition(regData$LE2018,
                                p = 0.75,
                                list = FALSE)
#
trainGauss = regData[ selection, ]
#
testGauss  = regData[-selection, ]
ctrl = trainControl(method = 'cv',number = 5)

gauss3CV = train(hypo3,
                 data = trainGauss, 
                 method = 'glm',
                 trControl = ctrl)
non-uniform 'Rounding' sampler used
gauss3CV
Generalized Linear Model 

117 samples
  2 predictor

No pre-processing
Resampling: Cross-Validated (5 fold) 
Summary of sample sizes: 93, 94, 94, 93, 94 
Resampling results:

  RMSE       Rsquared  MAE     
  0.8785279  0.393698  0.638966

R2 = .394

  1. Evaluate performance
predictedVal<-predict(gauss3CV,testGauss)
Warning messages:
1:  Loading rgl's DLL failed. 
    This build of rgl depends on XQuartz, which failed to load.
 See the discussion in https://stackoverflow.com/a/66127391/2554330 
2: Trying without OpenGL... 
postResample(obs = testGauss$LE2018,
             pred=predictedVal)
     RMSE  Rsquared       MAE 
0.7520189 0.5470718 0.5711473 

From the information above, you do noy a better prediction: the Rsquared from postResample is below 0.5.

BINARY OUTCOME Ignore all below here, data is not binary If you have a binary dependent variable (this data is not binary)

#regData$LE2018dico=ifelse(regData$LE2018>median(regData$LE2018,
#                                       na.rm = T),
#                     1,0)

*EXPLANATORY APPROACH – IGNORE, data is not binary. Just including for practice 1. State hypothesis

hypoDico1=formula(LE2018dico~ GiniPercent)
hypoDico2=formula(LE2018dico~ HE2018 + GiniPercent)
  1. Reformat
demoidh$LE2018dico=factor(regData$LE2018dico)

Compute regression models

Log1=glm(hypoDico1,data = regData,
         family="binomial")

Logi2=glm(hypoDico2, data=regData,
          family="binomial")

See Results - First Hypothesis

summary(Logi1)
summary(Logi2)

Search for a better model:

lrtest(Logi1,Logi2)

Verify situation of a chosen model

9.1 Linearity assumption (Box-Tidwell test)

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Cmd+Option+I.

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Cmd+Shift+K to preview the HTML file).

The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.

LS0tCnRpdGxlOiAiRGVsaXZlcmFibGUgMjogQ2x1c3RlciBBbmFseXNpcywgRmFjdG9yIEFuYWx5c2lzLCBSZWdyZXNzaW9uIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tClJlYWRpbmcgaW4gdGhlIERhdGEgZnJvbSBEZWxpdmVyYWJsZSAxCldpbGwgdGFrZSBhIHN1YnNldCBvZiB0aGlzIGRhdGEgd2hpY2ggaW5jbHVkZXMgY291bnRyeSwgaGVhbHRoIGV4cGVuZGl0dXJlIGxldmVscyBpbiAyMDE4LCBsaWZlIGV4cGVjdGFuY3kgaW4gMjAxOCwgYW5kIHRoZSBjb3VudHJ5J3MgZ2luaSBjb2VmZmljaWVudCAobWVhc3VyaW5nIGluZXF1YWxpdHkgaW4gdGhlIGNvdW50cnksIHdpdGggaGlnaGVyIHNjb3JlcyBtZWFuaW5nIGhpZ2hlciBpbmVxdWFsaXR5LikKCk5PVEUgRk9SIFdIT0xFIERFTElWRVJBQkxFOiBSIGluc3RhbmNlIGNvdWxkIG5vdCBsb2FkIHJnbCwgYSByZXF1aXJlZCBwYWNrYWdlIGZvciBtYW55IG9mIHRoZXNlIHNlY3Rpb25zIChnb3QgZXJyb3JzIHdpdGggbmV2ZXJlbmRpbmcgbG9hZGluZy4pIFRoZSBzZWN0aW9uIHRha2luZyBvdXQgb25seSB0aGUgcG9vcmx5IHNjb3JpbmcgY291bnRyaWVzIGJhc2VkIG9uIHNpbGhvdWV0dGVzIHdvdWxkIG5vdCBydW4uCmBgYHtyfQphbGxEYXRhIDwtIHJlYWQuY3N2ICgiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3Joc3U0LzU0Ml9EZWxpdjEvbWFpbi9hbGxEYXRhV2lkZS5jc3YiKQoKcm93Lm5hbWVzKGFsbERhdGEpID0gTlVMTAoKI2NoZWNrIGRhdGEgdHlwZXMKc3RyKGFsbERhdGEpCgojSGF2ZSB0byBtYWtlIExFMjAxOCBudW1lcmljCmFsbERhdGEkTEUyMDE4PC1hcy5udW1lcmljKGFsbERhdGEkTEUyMDE4KQoKc3RyKGFsbERhdGEpCgpgYGAKUHJlcGFyaW5nIERhdGEgZm9yIGNsdXN0ZXJpbmcKCmBgYHtyfQojU2V0dGluZyByb3cgbmFtZXMgYXMgY291bnRyeSBuYW1lcyBkb2Vzbid0IHdvcmsgYmVjYXVzZSBjb3VudHJpZXMgYXJlIHJlcGVhdGluZwpzZWxlY3Rpb249YygiQ291bnRyeSIsICJHaW5pUGVyY2VudCIsICJIRTIwMTgiLCAiTEUyMDE4IikKZGF0YVRvQ2x1c3Rlcj1hbGxEYXRhWyxzZWxlY3Rpb25dCgojc2V0IGxhYmVscyBhcyByb3cgaW5kZXgKCnJvdy5uYW1lcyhkYXRhVG9DbHVzdGVyKSA9IGRhdGFUb0NsdXN0ZXIkQ291bnRyeQpkYXRhVG9DbHVzdGVyJENvdW50cnk9TlVMTAoKI1RoaXMgd2lsbCBnaXZlIHlvdSBhbiBlcnJvciBpZiB0aGUgY291bnRyeSBpcyByZXBlYXRlZCAoYmVjYXVzZSByb3cgaW5kZXggbmFtZXMgbmVlZCB0byBiZSB1bmlxdWUpCgojRGVjaWRlIGlmIGRhdGEgbmVlZHMgdG8gYmUgdHJhbnNmb3JtZWQKYm94cGxvdChkYXRhVG9DbHVzdGVyLCBob3Jpem9udGFsPVQpCiNZZXMsIGhhcyB0byBiZSB0cmFuc2Zvcm1lZCwgb24gZGlmZmVyZW50IHNjYWxlcwoKYGBgClN0YW5kYXJkaXppbmcgRGF0YSwgYmVjYXVzZSBvbiBhIGRpZmZlcmVudCBzY2FsZQoKYGBge3J9CiMjIyMgc3RhbmRhcmRpemluZwpEYXRhVG9DbHVzdGVyU3RkPC1hcy5kYXRhLmZyYW1lKHNjYWxlKGRhdGFUb0NsdXN0ZXIpKQoKIyMjIG9yIHNtb290aGluZwojbG9nKERhdGFUb0NsdXN0ZXJTdGQpCgpib3hwbG90KERhdGFUb0NsdXN0ZXJTdGQpCmBgYApJSS4gQ29tcHV0ZSB0aGUgRElTVEFOQ0UgTUFUUklYCgpgYGB7cn0Kc2V0LnNlZWQoOTk5KSAjIHRoaXMgaXMgZm9yIHJlcGxpY2FiaWxpdHkgb2YgcmVzdWx0cwpgYGAKCgpgYGB7cn0KZHRjc0ZpbmFsIDwtIG5hLm9taXQoRGF0YVRvQ2x1c3RlclN0ZCkKI1RoaXMgaW5jbHVkZXMgb25seSBpbnN0YW5jZXMgdGhhdCBoYXZlIG5vIG1pc3NpbmcgdmFsdWVzICgxNTMgb2JzIGxlZnQpCmBgYAoKYGBge3J9CmxpYnJhcnkoY2x1c3RlcikKZHRjc0ZpbmFsX0RNID0gZGFpc3kgKHg9ZHRjc0ZpbmFsLCBtZXRyaWMgPSAiZ293ZXIiKQojVGhpcyBjcmVhdGVzIHRoZSBkaXN0YW5jZSBtZXRyaWMKYGBgCgoKQ29tcHV0ZSBDbHVzdGVycyAtIENvbXB1dGVyIHN1Z2dlc3Rpb25zClVzaW5nIGZ1bmN0aW9uIGZ2aXpfbmJjbHVzdCBmcm9tIHRoZSBsaWJyYXJ5IGZhY3RvZXh0cmEgd2UgY2FuIHNlZSBob3cgbWFueSBjbHVzdGVyZWQgYXJlIHN1Z2dlc3RlZC4KCgpgYGB7cn0KI2ZvciBwYXJ0aXRpb25pbmcKbGlicmFyeShmYWN0b2V4dHJhKQpgYGAKCmBgYHtyfQojTWlzc2luZyB2YWx1ZXMgLSBoYXZlIHRvIGVpdGhlciBhZGQgaW1wdXRlZCAobWVhbikgdmFsdWVzLCBvciByZW1vdmUgdmFyaWFibGVzIHRoYXQgaGF2ZSBtaXNzaW5nIGRhdGEKI0hlcmUsIHJlbW92aW5nIE5BcwoKZnZpel9uYmNsdXN0KGR0Y3NGaW5hbCwgCiAgICAgICAgICAgICBwYW0sCiAgICAgICAgICAgICBkaXNzPWRhdGFUb0NsdXN0ZXJfRE0sCiAgICAgICAgICAgICBtZXRob2QgPSAiZ2FwX3N0YXQiLAogICAgICAgICAgICAgay5tYXggPSAxMCx2ZXJib3NlID0gRikKCiNPcHRpbWFsIG51bWJlciBvZiBjbHVzdGVycyA9IDkKYGBgCgpgYGB7cn0KI2hpZXJhcmNoaWNhbCAtIGFnZ2xvbWVyYXRpdmUgCmZ2aXpfbmJjbHVzdChkdGNzRmluYWwsIAogICAgICAgICAgICAgaGN1dCwKICAgICAgICAgICAgIGRpc3M9ZGF0YVRvQ2x1c3Rlcl9ETSwKICAgICAgICAgICAgIG1ldGhvZCA9ICJnYXBfc3RhdCIsCiAgICAgICAgICAgICBrLm1heCA9IDEwLAogICAgICAgICAgICAgdmVyYm9zZSA9IEYsCiAgICAgICAgICAgICBoY19mdW5jID0gImFnbmVzIikKI2FnZ2xvbWVyYXRpdmUgb3B0aW1hbCAjIG9mIGNsdXN0ZXJzID0gND8gNCBpcyBhIGxvY2FsIGF2ZXJhZ2UgdGhvdWdoLCBzbyBtYXliZSA4IG9yIDkgaXMgYmV0dGVyCmBgYAoKYGBge3J9CiNoaWVyYXJjaGljYWwgKGRpdmlzaXZlKQpmdml6X25iY2x1c3QoZHRjc0ZpbmFsLCAKICAgICAgICAgICAgIGhjdXQsCiAgICAgICAgICAgICBkaXNzPWRhdGFUb0NsdXN0ZXJfRE0sCiAgICAgICAgICAgICBtZXRob2QgPSAiZ2FwX3N0YXQiLAogICAgICAgICAgICAgay5tYXggPSAxMCwKICAgICAgICAgICAgIHZlcmJvc2UgPSBGLAogICAgICAgICAgICAgaGNfZnVuYyA9ICJkaWFuYSIpCgojZGl2aXNpdmUgY2x1c3RlcnMgPSAyIHdpdGggbG9jYWwgYXZlcmFnZS4gQWN0dWFsIGlkZWFsIG1pZ2h0IGJlIDcKYGBgCgpBcHBseSBmdW5jdGlvbgphIHByaW9yaSBjbHVzdGVyczoKKHBhcnRpdGlvbmluZz8gZmlyc3Qga2luZCkgPSA5CmFnZ2xvbWVyYXRpdmUgPSA0IChvciA4LCB0ZXN0IGJvdGgpCmRpdmlzaXZlID0gNyAob3IgMiwgdGVzdCBib3RoKQoKQmVjYXVzZSB0aGUgYWdnbG9tZXJhdGl2ZSBhbmQgZGl2aXNpdmUgYXBwcm9hY2hlcyBoYWQgbG9jYWwgbWF4aW11bXMsIEkgdGVzdGVkIGJvdGggdGhlIHN1Z2dlc3RlZCBudW1iZXIgb2YgY2x1c3RlcnMgYW5kIHRoZSBsYXRlciBtYXhpbXVtcyB0byBzZWUgd2hpY2ggZ2F2ZSB0aGUgaGlnaGVzdCBhdmVyYWdlIHNpbGhvdWV0dGUgd2lkdGguCgpgYGB7cn0KTnVtYmVyT2ZDbHVzdGVyRGVzaXJlZD00CgojRm9yIGNsdXN0ZXJzID0gOSwgaGlnaGVzdCBhdmcgc2lsaG91ZXR0ZSB3aWR0aCA9IC4zMwojRm9yIGNsdXN0ZXJzID0gNCwgaGlnaGVzdCBhdmcgc2lsaG91ZXR0ZSB3aWR0aCA9IC4zNyAocGFtIGFuZCBhZ25lcykKI0ZvciBjbHVzdGVycyA9IDIsIGhpZ2hlc3QgYXZnIHNpbGhvdWV0dGUgd2lkdGggPSAuMzggKHBhbSBhbmQgZGlhbmEpCgojRm9yIGNsdXN0ZXJzID0gNywgaGlnaGVzdCBhdmcgc2lsaG91ZXR0ZSB3aWR0aCA9IC4zNCAoYWduZXMpCiNGb3IgY2x1c3RlcnMgPSA4LCBoaWdoZXN0IGF2ZyBzaWxob3VldHRlIHdpZHRoID0gLjM0IChkaWFuYSkKCgojRkxBRzogSXMgMiBjbHVzdGVycyBlbm91Z2ggY2x1c3RlcnM/CiNXaWxsIGdvIHdpdGggNCwgaGlnaGVzdCBhdmcgc2lsaG91ZXR0ZSB3aWR0aCB3aGlsZSA+IDIgY2x1c3RlcnMKCiMgUGFydGl0aW9uaW5nIHRlY2huaXF1ZQpyZXMucGFtID0gcGFtKHg9ZGF0YVRvQ2x1c3Rlcl9ETSwKICAgICAgICAgICAgICBrID0gTnVtYmVyT2ZDbHVzdGVyRGVzaXJlZCwKICAgICAgICAgICAgICBjbHVzdGVyLm9ubHkgPSBGKQoKIyBIaWVyYXJjaGljYWwgdGVjaG5pcXVlLSBhZ2dsb21lcmF0aXZlIGFwcHJvYWNoCgojbGlicmFyeShmYWN0b2V4dHJhKQpyZXMuYWduZXM9IGhjdXQoZGF0YVRvQ2x1c3Rlcl9ETSwgCiAgICAgICAgICAgICAgICBrID0gTnVtYmVyT2ZDbHVzdGVyRGVzaXJlZCwKICAgICAgICAgICAgICAgIGlzZGlzcz1UUlVFLAogICAgICAgICAgICAgICAgaGNfZnVuYz0nYWduZXMnLAogICAgICAgICAgICAgICAgaGNfbWV0aG9kID0gIndhcmQuRDIiKQoKIyBIaWVyYXJjaGljYWwgdGVjaG5pcXVlLSBkaXZpc2l2ZSBhcHByb2FjaApyZXMuZGlhbmE9IGhjdXQoZGF0YVRvQ2x1c3Rlcl9ETSwgCiAgICAgICAgICAgICAgICBrID0gTnVtYmVyT2ZDbHVzdGVyRGVzaXJlZCwKICAgICAgICAgICAgICAgIGlzZGlzcz1UUlVFLAogICAgICAgICAgICAgICAgaGNfZnVuYz0nZGlhbmEnLAogICAgICAgICAgICAgICAgaGNfbWV0aG9kID0gIndhcmQuRDIiKQoKYGBgCgpgYGB7cn0KI0lzIHJlY29kaW5nIHN1cHBvc2VkIHRvIHB1dCB0aGVzZSBpbiBvcmRlcj8KbGlicmFyeShkcGx5cikKYGBgCgoyLiBDbHVzdGVyaW5nIFJlc3VsdHMKQ3JlYXRpbmcgY2x1c3RlcnMgdXNpbmcgdGhlIGRpZmZlcmVudCB0ZWNobmlxdWVzIGFuZCB3aXRoIHRoZSBvcHRpbWFsIGNsdXN0ZXIgbnVtYmVyICg0KS4KCmBgYHtyfQojMi4xIEFkZCByZXN1bHRzIHRvIG9yaWdpbmFsIGRhdGEgZnJhbWU6CmR0Y3NGaW5hbCRwYW09YXMuZmFjdG9yKHJlcy5wYW0kY2x1c3RlcmluZykKZHRjc0ZpbmFsJGFnbj1hcy5mYWN0b3IocmVzLmFnbmVzJGNsdXN0ZXIpCmR0Y3NGaW5hbCRkaWE9YXMuZmFjdG9yKHJlcy5kaWFuYSRjbHVzdGVyKQpgYGAKCgpgYGB7cn0KI1ZlcmlmeSBvcmRpbmFsaXR5IGluIGNsdXN0ZXJzCiNhZ2dyZWdhdGUoZGF0YT1kdGNzRmluYWwsCiMgICAgICAgICAgT3ZlcmFsbHNjb3JlfnBhbSwgI2hvdyBkbyB3ZSBrbm93IHdoYXQgdGhlIGRlcGVuZGVudCB2YXJpYWJsZSBzaG91bGQgYmU/CiMgICAgICAgICAgRlVOPW1lYW4pCgphZ2dyZWdhdGUoZGF0YT1kdGNzRmluYWwsCiAgICAgICAgICBMRTIwMTh+cGFtLAogICAgICAgICAgRlVOPW1lYW4pCiNUaGVzZSBhcmUgbm90IG9yZGluYWwgZGF0YQpgYGAKCmBgYHtyfQphZ2dyZWdhdGUoZGF0YT1kdGNzRmluYWwsCiAgICAgICAgIExFMjAxOH5hZ24sCiAgICAgICAgICBGVU49bWVhbikKYGBgCgpgYGB7cn0KYWdncmVnYXRlKGRhdGE9ZHRjc0ZpbmFsLAogICAgICAgICAgTEUyMDE4fmRpYSwKICAgICAgICAgIEZVTj1tZWFuKQpgYGAKClJlb3JkZXJpbmcgdGhlIGNsdXN0ZXJzIGJhc2VkIG9uIGFib3ZlCmBgYHtyfQpkdGNzRmluYWwkcGFtPWRwbHlyOjpyZWNvZGVfZmFjdG9yKGR0Y3NGaW5hbCRwYW0sIAogICAgICAgICAgICAgICAgICBgMWAgPSAnMicsYDJgPScxJyxgM2A9JzMnLGA0YD0nNCcpCmR0Y3NGaW5hbCRhZ249ZHBseXI6OnJlY29kZV9mYWN0b3IoZHRjc0ZpbmFsJGFnbiwgCiAgICAgICAgICAgICAgICAgIGAxYCA9ICcyJyxgMmA9JzQnLGAzYD0nNCcsYDRgPSczJykKZHRjc0ZpbmFsJGRpYT1kcGx5cjo6cmVjb2RlX2ZhY3RvcihkdGNzRmluYWwkZGlhLCAKICAgICAgICAgICAgICAgICAgYDFgID0gJzMnLGAyYD0nMicsYDNgPSc0JyxgNGA9JzEnKQpgYGAKCgoKMy4gRXZhbHVhdGUgUmVzdWx0cwpgYGB7cn0KZnZpel9zaWxob3VldHRlKHJlcy5wYW0pCgpgYGAKCgoKYGBge3J9CmZ2aXpfc2lsaG91ZXR0ZShyZXMuYWduZXMpCgpgYGAKCmBgYHtyfQpsaWJyYXJ5KGZhY3RvZXh0cmEpCmZ2aXpfc2lsaG91ZXR0ZShyZXMuZGlhbmEpCgpgYGAKCjMuMiBEZXRlY3RpbmcgYmFkbHkgY2x1c3RlcmVkIGNhc2VzCgpzYXZlIGluZGl2aWR1YWwgc2lsaG91ZXR0ZXMKCmBgYHtyfQpoZWFkKGRhdGEuZnJhbWUocmVzLnBhbSRzaWxpbmZvJHdpZHRocyksMTApCmBgYApLZWVwaW5nIG9ubHkgdGhlIG5lZ2F0aXZlIGNsdXN0ZXJzCgpgYGB7cn0KcGFtRXZhbD1kYXRhLmZyYW1lKHJlcy5wYW0kc2lsaW5mbyR3aWR0aHMpCmFnbkV2YWw9ZGF0YS5mcmFtZShyZXMuYWduZXMkc2lsaW5mbyR3aWR0aHMpCmRpYUV2YWw9ZGF0YS5mcmFtZShyZXMuZGlhbmEkc2lsaW5mbyR3aWR0aHMpCgpwYW1Qb29yPXJvd25hbWVzKHBhbUV2YWxbcGFtRXZhbCRzaWxfd2lkdGg8MCxdKQphZ25Qb29yPXJvd25hbWVzKGFnbkV2YWxbYWduRXZhbCRzaWxfd2lkdGg8MCxdKQpkaWFQb29yPXJvd25hbWVzKGRpYUV2YWxbZGlhRXZhbCRzaWxfd2lkdGg8MCxdKQpgYGAKCmBgYHtyfQojaW5zdGFsbC4icXBjciIKbGlicmFyeSgicXBjUiIpCgpgYGAKCl5eTk9URSBmb3IgaG9tZXdvcms6IGNvdWxkIG5vdCBnZXQgInFwY3IiIHRvIHdvcmsgYmVjYXVzZSByZ2wgd291bGRuJ3Qgd29yay4gVHJpZWQgaW5zdGFsbGluZyBwY2tncyBzZXBhcmF0ZWx5LCB1bmluc3RhbGxpbmcgd2hvbGUgdGhpbmcsIGRpZG4ndCB3b3JrCgpgYGB7cn0KI0lmIEkgY2FuIGV2ZXIgZ2V0IHJnbCB0byB3b3JrIC0gc2VlIHdoaWNoIGluc3RhbmNlcyBhcmUgYmFkbHkgY2x1c3RlcmVkCmJhcF9DbHVzPWFzLmRhdGEuZnJhbWUocXBjUjo6OmNiaW5kLm5hKHNvcnQocGFtUG9vciksIHNvcnQoYWduUG9vciksc29ydChkaWFQb29yKSkpCm5hbWVzKGJhcF9DbHVzKT1jKCJwYW0iLCJhZ24iLCJkaWEiKQpiYXBfQ2x1cwoKYGBgCgoKSE9XIFRPIENPTVBBUkUgQ0xVU1RFUklORwoKUHJlcGFyZSBhIGJpZGltZW5zaW9uYWwgbWFwLiBUaGUgZnVuY3Rpb24gY21kc2NhbGUgY2FuIHByb2R1Y2UgYSB0d28gZGltZW5zaW9uIG1hcCBvZiBwb2ludHMgdXNpbmcgdGhlIGRpc3RhbmNlIG1hdHJpeDoKCmBgYHtyfQpwcm9qZWN0ZWREYXRhID0gY21kc2NhbGUoZGF0YVRvQ2x1c3Rlcl9ETSwgaz0yKQoKYGBgCgpUaGUgb2JqZWN0IHByb2plY3RlZERhdGEgaXMgc2F2aW5nIGNvb3JkaW5hdGVzIGZvciBlYWNoIGVsZW1lbnQgaW4gdGhlIGRhdGE6CgpgYGB7cn0KIwojIHNhdmUgY29vcmRpbmF0ZXMgdG8gb3JpZ2luYWwgZGF0YSBmcmFtZToKZHRjc0ZpbmFsJGRpbTEgPSBwcm9qZWN0ZWREYXRhWywxXQpkdGNzRmluYWwkZGltMiA9IHByb2plY3RlZERhdGFbLDJdCgojIHNlZSBzb21lOgoKZHRjc0ZpbmFsWyxjKCdkaW0xJywnZGltMicpXVsxOjEwLF0KYGBgCgpVc2UgdGhvc2UgcG9pbnRzIGFuZCBzZWUgdGhlIOKAnG1hcOKAnToKCmBgYHtyfQojYmFzZT0gZ2dwbG90KGRhdGE9ZHRjc0ZpbmFsLAojICAgICAgICAgICAgIGFlcyh4PWRpbTEsIHk9ZGltMiwKIyAgICAgICAgICAgICAgICAgbGFiZWw9Q291bnRyeSkpIAojYmFzZSArIGdlb21fdGV4dChzaXplPTIpCgpiYXNlPSBnZ3Bsb3QoZGF0YT1kdGNzRmluYWwsCiAgICAgICAgICAgICBhZXMoeD1kaW0xLCB5PWRpbTIsCiAgICAgICAgICAgICAgICBsYWJlbCA9IHJvd25hbWVzKGR0Y3NGaW5hbCkpKSAKYmFzZSArIGdlb21fdGV4dChzaXplPTIpCmBgYAoKQ29sb3IgdGhlIG1hcCB1c2luZyB0aGUgbGFiZWxzIGZyb20gUEFNOgoKYGBge3J9CnBhbVBsb3Q9YmFzZSArIGxhYnModGl0bGUgPSAiUEFNIikgKyBnZW9tX3BvaW50KHNpemU9MiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyhjb2xvcj1wYW0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvdy5sZWdlbmQgPSBUKSAKYGBgCgpDb2xvciB0aGUgbWFwIHVzaW5nIHRoZSBsYWJlbHMgZnJvbSBIaWVyYXJjaGljYWwgQUdORVM6CgpgYGB7cn0KYWduUGxvdD1iYXNlICsgbGFicyh0aXRsZSA9ICJBR05FUyIpICsgZ2VvbV9wb2ludChzaXplPTIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoY29sb3I9YWduKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3cubGVnZW5kID0gVCkgCmBgYAoKQ29sb3IgdGhlIG1hcCB1c2luZyB0aGUgbGFiZWxzIGZyb20gSGllcmFyY2hpY2FsIERJQU5BOgpgYGB7cn0KZGlhUGxvdD1iYXNlICsgbGFicyh0aXRsZSA9ICJESUFOQSIpICsgZ2VvbV9wb2ludChzaXplPTIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoY29sb3I9ZGlhKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3cubGVnZW5kID0gVCkgCmBgYAoKQ29tcGFyZSB2aXN1YWxseToKCmBgYHtyfQpsaWJyYXJ5KGdncHVicikKCmdnYXJyYW5nZShwYW1QbG90LCBhZ25QbG90LCBkaWFQbG90LG5jb2wgPSAzLGNvbW1vbi5sZWdlbmQgPSBUKQpgYGAKCkFubm90YXRpbmcgb3V0bGllcnM6CgpQcmVwYXJlIGxhYmVscwpGTEFHOiBuZWVkIHRvIGhhdmUgY291bnRyeSB2YXIgSSB0aGluaywgdGhpcyBjb2RlIGRvZXNuJ3Qgd29yayB3aXRob3V0IGl0LiBPciByb3duYW1lPwpgYGB7cn0KIyBJZiBuYW1lIG9mIGNvdW50cnkgaW4gYmxhY2sgbGlzdCwgdXNlIGl0LCBlbHNlIGdldCByaWQgb2YgaXQKI0xBQkVMcGFtPWlmZWxzZShkdGNzRmluYWwkcm93bmFtZSVpbiVwYW1Qb29yLGR0Y3NGaW5hbCRyb3duYW1lLCIiKQojTEFCRUxkaWE9aWZlbHNlKGR0Y3NGaW5hbCRDb3VudHJ5JWluJWRpYVBvb3IsZHRjc0ZpbmFsJENvdW50cnksIiIpCiNMQUJFTGFnbj1pZmVsc2UoZHRjc0ZpbmFsJENvdW50cnklaW4lYWduUG9vcixkdGNzRmluYWwkQ291bnRyeSwiIikKCiNIT01FV09SSyBOT1RFOiBUaGlzIGlzbid0IHdvcmtpbmcgYmVjYXVzZSByZ2wgcGFja2FnZSB3b24ndCB3b3JrCkxBQkVMcGFtPWlmZWxzZShkdGNzRmluYWwkcm93bmFtZSVpbiVwYW1Qb29yLGR0Y3NGaW5hbCRyb3duYW1lLCIiKQpMQUJFTGRpYT1pZmVsc2UoZHRjc0ZpbmFsJHJvd25hbWUlaW4lZGlhUG9vcixkdGNzRmluYWwkcm93bmFtZSwiIikKTEFCRUxhZ249aWZlbHNlKGR0Y3NGaW5hbCRyb3duYW1lJWluJWFnblBvb3IsZHRjc0ZpbmFsJHJvd25hbWUsIiIpCmBgYAoKYGBge3J9CmxpYnJhcnkoZ2dyZXBlbCkKcGFtUGxvdCArIGdlb21fdGV4dF9yZXBlbChhZXMobGFiZWw9TEFCRUxwYW0pKQpgYGAKCmBgYHtyfQpkaWFQbG90ICsgZ2VvbV90ZXh0X3JlcGVsKGFlcyhsYWJlbD1MQUJFTGRpYSkpCmBgYAoKYGBge3J9CmFnblBsb3QgKyBnZW9tX3RleHRfcmVwZWwoYWVzKGxhYmVsPUxBQkVMYWduKSkKYGBgCgpOT1RFOiBBYm92ZSBzZWN0aW9uIGRvZXNuJ3Qgd29yayBiZWNhdXNlIGl0IGRlcGVuZHMgb24gcmdsIChpbiBxcGNSKSB3aGljaCB3b24ndCBsb2FkIG9yIGluc3RhbGwKClRoZSBEZW5kb2dyYW0gKGZvciBoaWVyYXJjaGljYWwgYXBwcm9hY2hlcykKYGBge3J9CmZ2aXpfZGVuZChyZXMuYWduZXMsaz1OdW1iZXJPZkNsdXN0ZXJEZXNpcmVkLCBjZXggPSAwLjQ1LCBob3JpeiA9IFQsbWFpbiA9ICJBR05FUyBhcHByb2FjaCIpCmBgYAoKYGBge3J9CmZ2aXpfZGVuZChyZXMuZGlhbmEsaz1OdW1iZXJPZkNsdXN0ZXJEZXNpcmVkLCBjZXggPSAwLjQ1LCBob3JpeiA9IFQsbWFpbiA9ICJESUFOQSBhcHByb2FjaCIpCgpgYGAKCgoKCkZhY3RvciBBbmFseXNpcwotIExhdGVudCBDb25jZXB0cwpgYGB7cn0KI0NyZWF0aW5nIEZBIGRhdGEKI3NlbGVjdGlvbgpkYXRhRm9yRkEgPSBkdGNzRmluYWwKbmFtZXMoZGF0YUZvckZBKQoKYGBgCgpgYGB7cn0KbGlicmFyeShsYXZhYW4pCmBgYAoKYGBge3J9Cm1vZGVsID0gJ2hlYWx0aHN5cz1+IEhFMjAxOCArIExFMjAxOCArIEdpbmlQZXJjZW50JwoKZml0IDwtIGNmYShtb2RlbCwgZGF0YSA9IGRhdGFGb3JGQSwgc3RkLmx2ID0gVFJVRSkKaW5kZXhDRkE9bGF2UHJlZGljdChmaXQpCgpgYGAKCmBgYHtyfQppbmRleENGQVsxOjEwXQoKI1Jlc2NhbGUgdG8gMDoxMAoKbGlicmFyeShzY2FsZXMpCmluZGV4Q0ZBTm9ybT1yZXNjYWxlKGFzLnZlY3RvcihpbmRleENGQSksIAogICAgICAgICAgICAgICAgICAgICB0byA9IGMoMCwgMTApKQppbmRleENGQU5vcm1bMToxMF0KCgojVGhpcyBpcyBvdXIgaW5kZXgKCmRhdGFGb3JGQSRkZW1vX0ZBPWluZGV4Q0ZBTm9ybQpgYGAKIApDb21wYXJpbmcgbmV3IGluZGV4IHdpdGggb3JpZ2luYWwgc2NvcmUKYGBge3J9CmJhc2U9Z2dwbG90KGRhdGE9ZGF0YUZvckZBLAogICAgICAgICAgICBhZXMoeD1kZW1vX0ZBLHk9TEUyMDE4KSkKYmFzZStnZW9tX3BvaW50KCkKYGBgCgpgYGB7cn0KCmV2YWxDRkExPXBhcmFtZXRlckVzdGltYXRlcyhmaXQsIHN0YW5kYXJkaXplZCA9VFJVRSkKCmV2YWxDRkExW2V2YWxDRkExJG9wPT0iPX4iLGMoJ3JocycsJ3N0ZC5hbGwnLCdwdmFsdWUnKV0KCgpgYGAKClNvbWUgY29lZmZpY2llbnRzCmBgYHtyfQpldmFsQ0ZBMj1hcy5saXN0KGZpdE1lYXN1cmVzKGZpdCkpCmBgYAoKCllvdSB3YW50IHAudmFsdWUgb2YgY2hpLXNxdWFyZSBncmVhdGVyIHRoYW4gLjA1CmBgYHtyfQpldmFsQ0ZBMltjKCJjaGlzcSIsICJkZiIsICJwdmFsdWUiKV0gCmBgYApUaGlzIGlzIG5vdCBhIGdyZWF0ZXIgcC12YWx1ZSB0aGFuIC4wNQoKWW91IHdhbnQgVHVja2VyLUxld2lzID4gLjkKYGBge3J9CmV2YWxDRkEyJHRsaSAjID4gMC45MApgYGAKVGhpcyBpcyBkb2VzIHNhdGlzZnkgVHVja2VyLUxld2lzIGNyaXRlcmlhCgpZb3Ugd2FudCBSTVNFQSA8IDAuMDU6CmBgYHtyfQpldmFsQ0ZBMltjKCAncm1zZWEuY2kubG93ZXInLCdybXNlYScsJ3Jtc2VhLmNpLnVwcGVyJyldIApgYGAKCkRvZXMgc2F0aXNmeSBSTVNFQSBjcml0ZXJhCgpTZWUgaG93IGl0IGxvb2tzOiAKYGBge3J9CiNpbnN0YWxsLnBhY2thZ2VzKCJzZW1QbG90IikKbGlicmFyeShzZW1QbG90KQoKYGBgCgoKYGBge3J9CnNlbVBhdGhzKGZpdCwgd2hhdD0nc3RkJywgbkNoYXJOb2Rlcz0wLCBzaXplTWFuPTEyLAogICAgICAgICBlZGdlLmxhYmVsLmNleD0xLjUsIGZhZGU9VCxyZXNpZHVhbHMgPSBGKQpgYGAKSGVhbHRoIGV4cGVuZGl0dXJlIGFuZCBMaWZlIGV4cGVjdGFuY3kgYXJlIHBvc2l0aXZlbHkgYXNzb2NpYXRlZCB3aXRoIG1vZGVsLCBnaW5pIHBlcmNlbnQgaXMgbmVnYXRpdmVseSBhc3NvY2lhdGVkLiBMaWZlIGV4cGVjdGFuY3kgaXMgbW9zdCBhc3NvY2lhdGVkIHdpdGggdGhlIGhlYWx0aCBzeXN0ZW0KCgpSRUdSRVNTSU9OIAoKT3V0Y29tZSB2YXJpYWJsZSBhcyBMaWZlIEV4cGVjdGFuY3ksIEhFMjAxOCBhbmQgR2luaVBlcmNlbnQgYXMgaW5kZXBlbmRlbnQgdmFyaWFibGVzPwoKYGBge3J9CnJlZ0RhdGEgPSBkdGNzRmluYWwKYApgYGAKCiogRVhQTEFOQVRPUlkgQVBQUk9BQ0gKMS4gU3RhdGUgaHlwb3RoZXNpczogSGVhbHRoIEV4cGVuZGl0dXJlIGFuZCB0aGUgR2luaSBJbmRleCBvZiBhIGNvdW50cnkgaGF2ZSBhbiBpbXBhY3Qgb24gdGhlIGxpZmUgZXhwZWN0YW5jeSBpbiB0aGF0IGNvdW50cnkKClByZXBhcmUgeW91ciBoeXBvdGhlc2lzOgpgYGB7cn0KI0ZMQUcgLSAgR2luaSBpcyBuZWdhdGl2ZWx5IGNvZGVkIChoaWdoZXIgZ2luaSA9IGhpZ2hlciBpbmVxdWFsaXR5KQojIGh5cG90aGVzaXMgMTogMjAxOExFIGluY3JlYXNlcyBhcyBnaW5pIHBlcmNlbnQgREVDUkVBU0VTIChoaWdoZXIgZXF1YWxpdHkpOgpoeXBvMT1mb3JtdWxhKExFMjAxOH4gR2luaVBlcmNlbnQpCgojIGh5cG90aGVzaXMgMjogMjAxOCBMRSBpbmNyZWFzZXMgYXMgaGVhbHRoIGV4cGVuZGl0dXJlIG9mIGEgY291bnRyeSBpbmNyZWFzZXMgCgpoeXBvMj1mb3JtdWxhKExFMjAxOH4gSEUyMDE4KQoKI2h5cG90aGVzaXMgMzogMjAxOCBMRSBpbmNyZWFzZXMgd2l0aCBoaWdoZXIgaGVhbHRoIGV4cGVuZGl0dXJlIGFuZCBsb3dlciBnaW5pIHNjb3JlCiMgLSAgZG9lcyB0aGlzIG1lYW4gbmVlZGluZyB0byBtYWtlIGdpbmkgbmVnYXRpdmU/Cmh5cG8zPWZvcm11bGEoTEUyMDE4fiBIRTIwMTggKyBHaW5pUGVyY2VudCkKCmBgYAoKMi4gQ29tcHV0ZSByZWdyZXNzaW9uIG1vZGVscwoKYGBge3J9CiMKIyByZXN1bHRzCmdhdXNzMT1nbG0oaHlwbzEsCiAgICAgICAgICAgZGF0YSA9IHJlZ0RhdGEsCiAgICAgICAgICAgZmFtaWx5ID0gJ2dhdXNzaWFuJykKCmdhdXNzMj1nbG0oaHlwbzIsCiAgICAgICAgICAgZGF0YSA9IHJlZ0RhdGEsCiAgICAgICAgICAgZmFtaWx5ID0gJ2dhdXNzaWFuJykKCgpnYXVzczM9Z2xtKGh5cG8zLAogICAgICAgICAgIGRhdGEgPSByZWdEYXRhLAogICAgICAgICAgIGZhbWlseSA9ICdnYXVzc2lhbicpCmBgYAoKMy4gU2VlIFJlc3VsdHMKCkh5cG90aGVzaXMgMToKYGBge3J9CnN1bW1hcnkoZ2F1c3MxKQoKYGBgCgotLSB5ZXMsIG5lZ2F0aXZlIGNvZWZmIG9uIGdpbmkgcGVyY2VudCwgcDwuMDUKCkh5cG90aGVzaXMgMgoKYGBge3J9CnN1bW1hcnkoZ2F1c3MyKQpgYGAKCmNvZWZmaWNpZW50IG9uIGhlYWx0aCBleHBlbmRpdHVyZSBpcyBwb3NpdGl2ZSwgcD4uMDUKCmBgYHtyfQpzdW1tYXJ5KGdhdXNzMykKYGBgCkh5cG90aGVzaXMgYXMgZXhwZWN0ZWQsIEhFIDIwMTggcG9zIGNvZWZmICYgc2lnbmlmaWNhbnQsIEdpbmlQZXJjZW50IG5lZ2F0aXZlIGNvZWZmIGFuZCBzaWduaWZpY2FudAoKNC4gU2VhcmNoIGZvciBhIGJldHRlciBtb2RlbApgYGB7cn0KYW5vdmEoZ2F1c3MxLCBnYXVzczIsIHRlc3Q9IkNoaXNxIikKYW5vdmEoZ2F1c3MxLCBnYXVzczMsIHRlc3Q9IkNoaXNxIikKYW5vdmEoZ2F1c3MyLCBnYXVzczMsIHRlc3Q9IkNoaXNxIikKCmBgYAoKTW9kZWwgZm9yIHRoZSB0aGlyZCBoeXBvdGhlc2lzIGlzIGNob3NlbiAoY29tYmluZWQgSEUgKyBnaW5pKQpgYGB7cn0KI2luc3RhbGwucGFja2FnZXMoInJzcSIpCmxpYnJhcnkocnNxKQpgYGAKYGBge3J9CnJzcShnYXVzczMsIGFkaj1UKQpgYGAKCk1vZGVsIDMgaGFzIHRoZSBoaWdoZXN0IHIyIGF0IC4zNzkKCjUuIFZlcmlmeSB0aGUgc2l0dWF0aW9uIG9mIHRoZSBjaG9zZW4gbW9kZWw6Cgo1LjEgTGluZWFyaXR5IGJldHdlZW4gZGVwZW5kZW50IHZhcmlhYmxlIGFuZCBwcmVkaWN0b3JzIGlzIGFzc3VtZWQsIHRoZW4gdGhlc2UgZG90cyBzaG91bGQgZm9sbG93IGEgbGluZWFyIGFuZCBob3Jpem9udGFsIHRyZW5kCmBgYHtyfQpwbG90KGdhdXNzMywxKQpgYGAKTGluZWFyIHJlbGF0aW9uc2hpcCBkb2Vzbid0IGhvbGQKCjUuMiBOb3JtYWxpdHkgb2YgcmVzaWR1YWxzIGlzIGFzc3VtZWQKVmlzdWFsIGV4cGxvcmF0aW9uCgpgYGB7cn0KcGxvdChnYXVzczMsMikKYGBgCk1hdGhlbWF0aWNhbCBleHBsb3JhdGlvbgpgYGB7cn0KIyBUaGUgZGF0YSBpcyBub3JtYWwgaWYgdGhlIHAtdmFsdWUgaXMgYWJvdmUgMC4wNQpzaGFwaXJvLnRlc3QoZ2F1c3MzJHJlc2lkdWFscykKYGBgCgpzbywgZGF0YSBpcyBub3Qgbm9ybWFsbHkgZGlzdHJpYnV0ZWQKCgo1LjMuIEhvbW9zY2VkYXN0aWNpdHkgaXMgYXNzdW1lZCwgc28geW91IG5lZWQgdG8gY2hlY2sgaWYgcmVzaWR1YWxzIGFyZSBzcHJlYWQgZXF1YWxseSBhbG9uZyB0aGUgcmFuZ2VzIG9mIHByZWRpY3RvcnM6CgpWaXN1YWwgZXhwbG9yYXRpb24KCmBgYHtyfQpwbG90KGdhdXNzMiwgMykKYGBgCgpNYXRoZW1hdGljYWwgZXhwbG9yYXRpb24KYGBge3J9CiNpbnN0YWxsLnBhY2thZ2VzKCJsbXRlc3QiKQpsaWJyYXJ5KGxtdGVzdCkKYGBgCgpgYGB7cn0KI3B2YWx1ZTwwLjA1IHlvdSBjYW5ub3QgYXNzdW1lIEhvbW9zY2VkYXN0aWNpdHkKYnB0ZXN0KGdhdXNzMykgCmBgYApDYW5ub3QgYXNzdW1lIGhvbW9za2VkYWNpdHk7IHA8LjA1Cgo1LjQuIFdlIGFzc3VtZSB0aGF0IHRoZXJlIGlzIG5vIGNvbGluZWFyaXR5LCB0aGF0IGlzLCB0aGF0IHRoZSBwcmVkaWN0b3JzIGFyZSBub3QgY29ycmVsYXRlZC4KCmBgYHtyfQpsaWJyYXJ5KGNhcikKYGBgCgpgYGB7cn0KdmlmKGdhdXNzMykKYGBgCnllcywgbG93ZXIgdGhhbiA1IC0gY29sbGluZWFyaXR5IGlzIG5vdCBhIHByb2JsZW0KCjUuNS4gQW5hbGl6ZSB0aGUgZWZmZWN0IG9mIGF0eXBpY2FsIHZhbHVlcy4gRGV0ZXJtaW5lIGlmIG91dGxpZXJzIChwb2ludHMgdGhhdCBhcmUgZmFyIGZyb20gdGhlIHJlc3QsIGJ1dCBzdGlsbCBpbiB0aGUgdHJlbmQpIG9yIGhpZ2gtbGV2ZXJhZ2UgcG9pbnRzIChmYXIgZnJvbSB0aGUgdHJlbmQgYnV0IGNsb3NlIHRvIHRoZSByZXN0KSBhcmUgaW5mbHVlbnRpYWw6CgpWaXN1YWwgZXhwbG9yYXRpb24KYGBge3J9CnBsb3QoZ2F1c3MzLDUpCmBgYAo/P1doYXQgZG9lcyB0aGlzIG1lYW4KClF1ZXJ5aW5nCgpgYGB7cn0KZ2F1c3NJbmY9YXMuZGF0YS5mcmFtZShpbmZsdWVuY2UubWVhc3VyZXMoZ2F1c3MzKSRpcy5pbmYpCmdhdXNzSW5mW2dhdXNzSW5mJGNvb2suZCxdCmBgYAo2LiBGaW5hbGx5LCBhIG5pY2Ugc3VtbWFyeSBwbG90IG9mIHlvdXIgd29yazoKYGBge3J9CiNpbnN0YWxsLnBhY2thZ2VzKCJzalBsb3QiKQpsaWJyYXJ5KHNqUGxvdCkKYGBgCgpgYGB7cn0KcGxvdF9tb2RlbHMoZ2F1c3MzLHZsaW5lLmNvbG9yPSJncmV5IikKYGBgClBSRURJQ1RJVkUgQVBQUk9BQ0gKMS4gU3BsaXQgdGhlIGRhdGEgc2V0CmBgYHtyfQojaW5zdGFsbC5wYWNrYWdlcygiY2FyZXQiKQpsaWJyYXJ5KGNhcmV0KQpgYGAKCmBgYHtyfQpzZXQuc2VlZCgxMjMpCgpzZWxlY3Rpb24gPSBjcmVhdGVEYXRhUGFydGl0aW9uKHJlZ0RhdGEkTEUyMDE4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAgPSAwLjc1LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QgPSBGQUxTRSkKIwp0cmFpbkdhdXNzID0gcmVnRGF0YVsgc2VsZWN0aW9uLCBdCiMKdGVzdEdhdXNzICA9IHJlZ0RhdGFbLXNlbGVjdGlvbiwgXQpgYGAKCgpgYGB7cn0KY3RybCA9IHRyYWluQ29udHJvbChtZXRob2QgPSAnY3YnLG51bWJlciA9IDUpCgpnYXVzczNDViA9IHRyYWluKGh5cG8zLAogICAgICAgICAgICAgICAgIGRhdGEgPSB0cmFpbkdhdXNzLCAKICAgICAgICAgICAgICAgICBtZXRob2QgPSAnZ2xtJywKICAgICAgICAgICAgICAgICB0ckNvbnRyb2wgPSBjdHJsKQoKZ2F1c3MzQ1YKYGBgCgpSMiA9IC4zOTQKCjMuIEV2YWx1YXRlIHBlcmZvcm1hbmNlCgpgYGB7cn0KcHJlZGljdGVkVmFsPC1wcmVkaWN0KGdhdXNzM0NWLHRlc3RHYXVzcykKCnBvc3RSZXNhbXBsZShvYnMgPSB0ZXN0R2F1c3MkTEUyMDE4LAogICAgICAgICAgICAgcHJlZD1wcmVkaWN0ZWRWYWwpCmBgYAoKRnJvbSB0aGUgaW5mb3JtYXRpb24gYWJvdmUsIHlvdSBkbyBub3kgYSBiZXR0ZXIgcHJlZGljdGlvbjogdGhlIFJzcXVhcmVkIGZyb20gcG9zdFJlc2FtcGxlIGlzIGJlbG93IDAuNS4KCkJJTkFSWSBPVVRDT01FCklnbm9yZSBhbGwgYmVsb3cgaGVyZSwgZGF0YSBpcyBub3QgYmluYXJ5CklmIHlvdSBoYXZlIGEgYmluYXJ5IGRlcGVuZGVudCB2YXJpYWJsZSAodGhpcyBkYXRhIGlzIG5vdCBiaW5hcnkpCgpgYGB7cn0KI3JlZ0RhdGEkTEUyMDE4ZGljbz1pZmVsc2UocmVnRGF0YSRMRTIwMTg+bWVkaWFuKHJlZ0RhdGEkTEUyMDE4LAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmEucm0gPSBUKSwKIyAgICAgICAgICAgICAgICAgICAgIDEsMCkKYGBgCgoqRVhQTEFOQVRPUlkgQVBQUk9BQ0ggLS0gSUdOT1JFLCBkYXRhIGlzIG5vdCBiaW5hcnkuIEp1c3QgaW5jbHVkaW5nIGZvciBwcmFjdGljZQoxLiBTdGF0ZSBoeXBvdGhlc2lzCmBgYHtyfQpoeXBvRGljbzE9Zm9ybXVsYShMRTIwMThkaWNvfiBHaW5pUGVyY2VudCkKaHlwb0RpY28yPWZvcm11bGEoTEUyMDE4ZGljb34gSEUyMDE4ICsgR2luaVBlcmNlbnQpCmBgYAoKMi4gUmVmb3JtYXQKYGBge3J9CmRlbW9pZGgkTEUyMDE4ZGljbz1mYWN0b3IocmVnRGF0YSRMRTIwMThkaWNvKQpgYGAKCkNvbXB1dGUgcmVncmVzc2lvbiBtb2RlbHMKYGBge3J9CkxvZzE9Z2xtKGh5cG9EaWNvMSxkYXRhID0gcmVnRGF0YSwKICAgICAgICAgZmFtaWx5PSJiaW5vbWlhbCIpCgpMb2dpMj1nbG0oaHlwb0RpY28yLCBkYXRhPXJlZ0RhdGEsCiAgICAgICAgICBmYW1pbHk9ImJpbm9taWFsIikKCmBgYApTZWUgUmVzdWx0cwotIEZpcnN0IEh5cG90aGVzaXMKCmBgYHtyfQpzdW1tYXJ5KExvZ2kxKQpgYGAKCi0gU2Vjb25kIEh5cG90aGVzaXMKYGBge3J9CnN1bW1hcnkoTG9naTIpCmBgYAoKU2VhcmNoIGZvciBhIGJldHRlciBtb2RlbDoKYGBge3J9CmxydGVzdChMb2dpMSxMb2dpMikKYGBgCgpWZXJpZnkgc2l0dWF0aW9uIG9mIGEgY2hvc2VuIG1vZGVsCgo5LjEgTGluZWFyaXR5IGFzc3VtcHRpb24gKEJveC1UaWR3ZWxsIHRlc3QpCgpBZGQgYSBuZXcgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpJbnNlcnQgQ2h1bmsqIGJ1dHRvbiBvbiB0aGUgdG9vbGJhciBvciBieSBwcmVzc2luZyAqQ21kK09wdGlvbitJKi4KCldoZW4geW91IHNhdmUgdGhlIG5vdGVib29rLCBhbiBIVE1MIGZpbGUgY29udGFpbmluZyB0aGUgY29kZSBhbmQgb3V0cHV0IHdpbGwgYmUgc2F2ZWQgYWxvbmdzaWRlIGl0IChjbGljayB0aGUgKlByZXZpZXcqIGJ1dHRvbiBvciBwcmVzcyAqQ21kK1NoaWZ0K0sqIHRvIHByZXZpZXcgdGhlIEhUTUwgZmlsZSkuIAoKVGhlIHByZXZpZXcgc2hvd3MgeW91IGEgcmVuZGVyZWQgSFRNTCBjb3B5IG9mIHRoZSBjb250ZW50cyBvZiB0aGUgZWRpdG9yLiBDb25zZXF1ZW50bHksIHVubGlrZSAqS25pdCosICpQcmV2aWV3KiBkb2VzIG5vdCBydW4gYW55IFIgY29kZSBjaHVua3MuIEluc3RlYWQsIHRoZSBvdXRwdXQgb2YgdGhlIGNodW5rIHdoZW4gaXQgd2FzIGxhc3QgcnVuIGluIHRoZSBlZGl0b3IgaXMgZGlzcGxheWVkLgoK