Data Manipulations

# Get US county socio-economic variables from Area resource file 2019-2020

arf2020<-import("ahrf2020.sas7bdat") 
 arf2020<-arf2020%>%
  mutate(cofips=as.factor(f00004), 
         coname=f00010,
         state = f00011,
         medhouvl=f1461314,
         pctcrpop= round(100*(f1492010/f0453010),2),
         medhinc= f1434514,
         pctctyunemp=round(100*(f1451214/f1451014),2),
         ctypopdes= (f0453010/f1387410),  
         rucc= as.numeric(f0002013),
         pctperpov= f1332118,
         obgyn10_pc= 1000*(f1168410/ f0453010) )%>%
  dplyr::select(medhouvl, pctcrpop,medhinc, pctctyunemp,state, cofips, coname, ctypopdes, rucc, obgyn10_pc,pctperpov)%>%
    mutate(rurality= car::Recode(rucc, recodes ="1:3 ='Metro';4:9='Non-Metro'")) 


# Get other  US county socioeconomic variables from the 5 year (2015-2019) ASC data source.

 US_county <- get_acs(geography = 'county',variables = c(totPop19 = "B03003_001", 
                                                   hispanic ="B03003_003", 
                                                   afrAm = "B03002_004",
                                                   white="B03002_003",
                                                   gini="B19083_001"), 
                    year = 2019, geometry = TRUE, shift_geo = TRUE) %>% 
            dplyr::select(GEOID, NAME, variable, estimate) %>% 
            spread(variable, estimate) %>% 
            mutate(pcthispPr19  = round((hispanic/totPop19)*100),1, 
                   pctnhblackpr19 = round((afrAm/totPop19)*100),1 , pctnhpwhite19=round((white/totPop19)*100),1, cofips=as.factor(GEOID)) %>%
            dplyr::select(cofips,totPop19,pcthispPr19, pctnhblackpr19, pctnhpwhite19,gini)


#Merge the socioeconomic variables from the Area resource file 2019-2020 with the other socioeconomic variables from the 5 year (2015-2019) ACS estimates.

 sevar <- geo_join( US_county, arf2020, by_sp="cofips", by_df="cofips",how="left") 

 #load and calculate maternal mortality rates for counties in US for  a 5year period (2015-2019)
alldat<-readRDS("~/OneDrive - University of Texas at San Antonio/maternalmortality/aggregate/alldat.rds") 
 countyMMR <-  alldat %>% 
  group_by(cofips)%>%
  summarise(nbir=sum(nbirths, na.rm = T), ndea = sum(ndeaths, na.rm = T))  %>% 
  mutate(mmrate =round(100000*(ndea/nbir),2))
 
  #Merge the socioeconomic variables with US counties maternal mortality rates for a 5- years period(2015-2019)
MMRdata<- geo_join( sevar, countyMMR, by_sp="cofips", by_df="cofips",how="left") %>% 
  mutate(rmmrate=ifelse(mmrate>=1,mmrate,NA)) %>% 
  filter(!is.na(ndea), mmrate!=Inf) %>% 
  mutate(Expdd=nbir*(sum(ndea)/sum(nbir))) %>% 
  subset(!state%in%c("02", "15", "60", "66", "69", "72", "78"))

Descriptive Maps

Defining Variables

The denominator/ offset variable for this analysis is Total number of births in US county. Five socioeconomic variables were used as predictors in the models–percentage of county population that is rural;the median household income in the county; the county’s median house value; the population density per square mile of the county; and ercentage of non Hispanic black population in the counties. All variables were Z scored

Estimating Generalized Linear Model

## 
## Call:
## glm.nb(formula = ndea ~ offset(log(nbir)) + rurality + medhouvlz + 
##     pctcrpopz + ctypopdesz + pctnhblackpr19z + medhincz, data = usctymmrr, 
##     init.theta = 5.899607279, link = log)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -6.2118  -0.5258  -0.0194   0.5125   7.4889  
## 
## Coefficients:
##                   Estimate Std. Error  z value Pr(>|z|)    
## (Intercept)       -7.58730    0.04983 -152.272  < 2e-16 ***
## ruralityNon-Metro  0.26511    0.06884    3.851 0.000118 ***
## medhouvlz         -0.17240    0.03194   -5.397 6.78e-08 ***
## pctcrpopz          0.58867    0.03533   16.663  < 2e-16 ***
## ctypopdesz         0.37666    0.01060   35.544  < 2e-16 ***
## pctnhblackpr19z    0.11650    0.02286    5.095 3.49e-07 ***
## medhincz          -0.06808    0.03387   -2.010 0.044417 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for Negative Binomial(5.8996) family taken to be 1)
## 
##     Null deviance: 2283.94  on 1242  degrees of freedom
## Residual deviance:  883.55  on 1236  degrees of freedom
##   (29 observations deleted due to missingness)
## AIC: 4540.5
## 
## Number of Fisher Scoring iterations: 1
## 
## 
##               Theta:  5.900 
##           Std. Err.:  0.498 
## Warning while fitting theta: alternation limit reached 
## 
##  2 x log-likelihood:  -4524.466
##       (Intercept) ruralityNon-Metro         medhouvlz         pctcrpopz 
##      0.0005068469      1.3035721968      0.8416453538      1.8015897782 
##        ctypopdesz   pctnhblackpr19z          medhincz 
##      1.4574054974      1.1235551354      0.9341852600

The model above shows a 30% increase in relative risk for maternal death in non metropolitan counties compared to metropolitan counties. Also, for every one unit increase in county’s median house value and median household income, maternal death decrease by 15% and 7.5% respectively. One unit increase in county’s percentage of rural population, County’s population density, and percentage of Non-Hispanic black increase maternal mortality significantly.

Testing for Overdispersion

# Testing for overdispersion  using the ratio of residual deviance and residual degree of freedom from the poisson model. 
scale<-sqrt(fit_nb$deviance/fit_nb$df.residual)
scale
## [1] 0.845486
# Testing for overdispersion using the goodness of fit statistic.
1-pchisq(fit_nb$deviance, df = fit_nb$df.residual)
## [1] 1

The overdispersion test shows that the model fits the data properly. The scale test is approximately equals to 1 showing that the mean and the variance of the model is equal to 1. Likewise the goodness of fit statistic gave a large p value of 1. Hence, the model fit the data.

Testing model for Residual Autocorrelation

nbs<-knearneigh(coordinates(as(usctymmrr, "Spatial")), k = 2, longlat = T)
nbs<-knn2nb(nbs, sym = T)
us.wt2<-nb2listw(nbs, style = "W")
lm.morantest(fit_nb, listw = us.wt2)
## 
##  Global Moran I for regression residuals
## 
## data:  
## model: glm.nb(formula = ndea ~ offset(log(nbir)) + rurality + medhouvlz
## + pctcrpopz + ctypopdesz + pctnhblackpr19z + medhincz, data =
## usctymmrr, init.theta = 5.899607279, link = log)
## weights: us.wt2
## 
## Moran I statistic standard deviate = 0.64628, p-value = 0.259
## alternative hypothesis: greater
## sample estimates:
## Observed Moran I      Expectation         Variance 
##     0.0161639772    -0.0005525404     0.0006690314

Given the result from the above model; testing for autocorrelation, it appears there is no autocorrelation in our data. The global Moran I is 0.013 with a p-value that is larger than 0.05. At this point, I am not sure on how to move forward with the rest of the assignment.

Construct Spatial Relationship for INLA

mmrinla <- usctymmr  %>% 
  arrange(cofips) %>% 
  rowid_to_column("id")
#constructing a K neighborhood
nbs<-knearneigh(st_centroid(mmrinla), k = 5, longlat = T)  
nbs<-knn2nb(nbs, row.names = mmrinla$id, sym = T)
nb2INLA("cl_graph",nbs)
am_adj <-paste(getwd(),"/cl_graph",sep="")
H<-inla.read.graph(filename="cl_graph")

Model Estimation without Sptial Pattern

f1<-ndea~rurality+ medhouvlz+ pctcrpopz + ctypopdesz + pctnhblackpr19z+medhincz+ #fixed effects
  f(id, model = "iid")  #random effects

mod2<-inla(formula = f1,
           data = mmrinla,
           family = "poisson",
           E = Expdd, 
           control.compute = list(waic=T), 
           control.predictor = list(link=1),
           num.threads = 3, 
               verbose = F)

#total model summary
summary(mod2)
## 
## Call:
##    c("inla(formula = f1, family = \"poisson\", data = mmrinla, E = Expdd, 
##    ", " verbose = F, control.compute = list(waic = T), control.predictor = 
##    list(link = 1), ", " num.threads = 3)") 
## Time used:
##     Pre = 4.03, Running = 7.94, Post = 0.139, Total = 12.1 
## Fixed effects:
##                     mean    sd 0.025quant 0.5quant 0.975quant   mode kld
## (Intercept)        0.134 0.048      0.039    0.135      0.228  0.135   0
## ruralityNon-Metro -0.033 0.066     -0.162   -0.033      0.096 -0.033   0
## medhouvlz         -0.150 0.034     -0.218   -0.150     -0.084 -0.150   0
## pctcrpopz          0.188 0.034      0.121    0.188      0.254  0.189   0
## ctypopdesz         0.284 0.013      0.258    0.284      0.309  0.284   0
## pctnhblackpr19z    0.169 0.023      0.123    0.169      0.214  0.169   0
## medhincz          -0.121 0.036     -0.192   -0.121     -0.051 -0.121   0
## 
## Random effects:
##   Name     Model
##     id IID model
## 
## Model hyperparameters:
##                  mean    sd 0.025quant 0.5quant 0.975quant mode
## Precision for id 3.59 0.309       3.04     3.57       4.25 3.53
## 
## Watanabe-Akaike information criterion (WAIC) ...: 6270.16
## Effective number of parameters .................: 398.25
## 
## Marginal log-Likelihood:  -3263.01 
## Posterior summaries for the linear predictor and the fitted values are computed
## (Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')

Marginal Distributions of hyperparameters

m2<- inla.tmarginal(
        function(x) (1/x), #invert the precision to be on variance scale
        mod2$marginals.hyperpar$`Precision for id`)
#95% credible interval for the variance
inla.hpdmarginal(.95, marginal=m2)
##                  low      high
## level:0.95 0.2333311 0.3266912
plot(m2,
     type="l",
     main=c("Posterior distibution for between county variance", "- IID model -"), 
     xlim=c(0, .5))

map1

f3<-ndea~rurality+ medhouvlz+ pctcrpopz + ctypopdesz + pctnhblackpr19z+medhincz+
  f(id, model = "bym",scale.model = T, constr = T, graph = H)

mod3<-inla(formula = f3,data = mmrinla,
           family = "poisson",
           E = Expdd, 
           control.compute = list(waic=T,return.marginals.predictor=TRUE), 
           control.predictor = list(link=1), 
           num.threads = 3, 
               verbose = F)

#total model summary
summary(mod3)
## 
## Call:
##    c("inla(formula = f3, family = \"poisson\", data = mmrinla, E = Expdd, 
##    ", " verbose = F, control.compute = list(waic = T, 
##    return.marginals.predictor = TRUE), ", " control.predictor = list(link 
##    = 1), num.threads = 3)") 
## Time used:
##     Pre = 4.01, Running = 19.5, Post = 0.37, Total = 23.8 
## Fixed effects:
##                     mean    sd 0.025quant 0.5quant 0.975quant   mode kld
## (Intercept)        0.105 0.051      0.004    0.105      0.203  0.106   0
## ruralityNon-Metro -0.009 0.067     -0.139   -0.009      0.122 -0.009   0
## medhouvlz         -0.089 0.047     -0.181   -0.089      0.003 -0.089   0
## pctcrpopz          0.178 0.037      0.106    0.179      0.250  0.179   0
## ctypopdesz         0.266 0.015      0.236    0.266      0.294  0.266   0
## pctnhblackpr19z    0.113 0.033      0.048    0.113      0.177  0.113   0
## medhincz          -0.129 0.044     -0.216   -0.129     -0.043 -0.129   0
## 
## Random effects:
##   Name     Model
##     id BYM model
## 
## Model hyperparameters:
##                                      mean    sd 0.025quant 0.5quant 0.975quant
## Precision for id (iid component)     5.30 0.651       4.14     5.26       6.70
## Precision for id (spatial component) 8.25 2.386       4.70     7.86      13.99
##                                      mode
## Precision for id (iid component)     5.17
## Precision for id (spatial component) 7.14
## 
## Watanabe-Akaike information criterion (WAIC) ...: 6184.10
## Effective number of parameters .................: 371.87
## 
## Marginal log-Likelihood:  -2106.61 
## Posterior summaries for the linear predictor and the fitted values are computed
## (Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
mod2$waic$waic
## [1] 6270.163
mod3$waic$waic
## [1] 6184.104

Regression effect posterior distributions

b1 <- inla.emarginal(exp, mod2$marginals.fixed[[2]])
b1 #Posterior mean
## [1] 0.9699767
b1ci <-inla.qmarginal(c(.025, .975), 
                      inla.tmarginal(exp, mod2$marginals.fixed[[2]]))
b1ci
## [1] 0.8512323 1.1001186

Hyper parameter distributions

m3a<- inla.tmarginal(
        function(x) (1/x),
        mod3$marginals.hyperpar$`Precision for id (iid component)`)
m3b<- inla.tmarginal(
        function(x) (1/x),
        mod3$marginals.hyperpar$`Precision for id (spatial component)`)

plot(m3a, type="l",
     main=c("Posterior distibution for between county variance", "- BYM model -"),
     xlim=c(0, .2)) # you may need to change this
#lines(m3b, col="red")
lines(m3b, col="green")

inla.hpdmarginal(.95,m3a)
##                  low      high
## level:0.95 0.1472058 0.2381321
inla.hpdmarginal(.95,m3b)
##                   low      high
## level:0.95 0.06573046 0.2019664

Spatial mapping of the fitted values

map2

Map of spatial random effects

map3

map4

LS0tCnRpdGxlOiAiU3BhdGlhbCBEZW1vZ3JhcGh5IC0gSG9tZXdrIDYgLVNwYXRpYWwgR0xNTShzKSB1c2luZyB0aGUgSU5MQSBBcHByb3hpbWF0aW9uIgphdXRob3I6ICJTYW1zb24gQS4gT2xvd29sYWp1LCBNUEgiCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkICVCLCAlWScpYCIKb3V0cHV0OgogICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBmaWdfaGVpZ2h0OiA3CiAgICBmaWdfd2lkdGg6IDcKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogICAgY29kZV9kb3dubG9hZDogdHJ1ZQotLS0KCgpgYGB7ciBsb2FkbGlicywgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSxlY2hvPUZBTFNFfQpsaWJyYXJ5KG5vcnRlc3QpCmxpYnJhcnkoY2FyKQpsaWJyYXJ5KE1BU1MpCmxpYnJhcnkobG10ZXN0KQpsaWJyYXJ5KGNsYXNzSW50KQpsaWJyYXJ5KHNhbmR3aWNoKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShzcGRlcCkKbGlicmFyeShyaW8pCmxpYnJhcnkoa2FibGVFeHRyYSkKbGlicmFyeShicm9vbSkKbGlicmFyeSh0aWR5Y2Vuc3VzKQpsaWJyYXJ5KHNmKQpsaWJyYXJ5KHRpZ3JpcykKbGlicmFyeShzcGF0aWFscmVnKQpsaWJyYXJ5KG1hcHZpZXcpCmxpYnJhcnkoZ3JpZEV4dHJhKQpsaWJyYXJ5KGd0c3VtbWFyeSkKbGlicmFyeShJTkxBKQpgYGAKCiMjIyBEYXRhIE1hbmlwdWxhdGlvbnMKYGBge3Isd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KIyBHZXQgVVMgY291bnR5IHNvY2lvLWVjb25vbWljIHZhcmlhYmxlcyBmcm9tIEFyZWEgcmVzb3VyY2UgZmlsZSAyMDE5LTIwMjAKCmFyZjIwMjA8LWltcG9ydCgiYWhyZjIwMjAuc2FzN2JkYXQiKSAKIGFyZjIwMjA8LWFyZjIwMjAlPiUKICBtdXRhdGUoY29maXBzPWFzLmZhY3RvcihmMDAwMDQpLCAKICAgICAgICAgY29uYW1lPWYwMDAxMCwKICAgICAgICAgc3RhdGUgPSBmMDAwMTEsCiAgICAgICAgIG1lZGhvdXZsPWYxNDYxMzE0LAogICAgICAgICBwY3RjcnBvcD0gcm91bmQoMTAwKihmMTQ5MjAxMC9mMDQ1MzAxMCksMiksCiAgICAgICAgIG1lZGhpbmM9IGYxNDM0NTE0LAogICAgICAgICBwY3RjdHl1bmVtcD1yb3VuZCgxMDAqKGYxNDUxMjE0L2YxNDUxMDE0KSwyKSwKICAgICAgICAgY3R5cG9wZGVzPSAoZjA0NTMwMTAvZjEzODc0MTApLCAgCiAgICAgICAgIHJ1Y2M9IGFzLm51bWVyaWMoZjAwMDIwMTMpLAogICAgICAgICBwY3RwZXJwb3Y9IGYxMzMyMTE4LAogICAgICAgICBvYmd5bjEwX3BjPSAxMDAwKihmMTE2ODQxMC8gZjA0NTMwMTApICklPiUKICBkcGx5cjo6c2VsZWN0KG1lZGhvdXZsLCBwY3RjcnBvcCxtZWRoaW5jLCBwY3RjdHl1bmVtcCxzdGF0ZSwgY29maXBzLCBjb25hbWUsIGN0eXBvcGRlcywgcnVjYywgb2JneW4xMF9wYyxwY3RwZXJwb3YpJT4lCiAgICBtdXRhdGUocnVyYWxpdHk9IGNhcjo6UmVjb2RlKHJ1Y2MsIHJlY29kZXMgPSIxOjMgPSdNZXRybyc7NDo5PSdOb24tTWV0cm8nIikpIAoKCiMgR2V0IG90aGVyICBVUyBjb3VudHkgc29jaW9lY29ub21pYyB2YXJpYWJsZXMgZnJvbSB0aGUgNSB5ZWFyICgyMDE1LTIwMTkpIEFTQyBkYXRhIHNvdXJjZS4KCiBVU19jb3VudHkgPC0gZ2V0X2FjcyhnZW9ncmFwaHkgPSAnY291bnR5Jyx2YXJpYWJsZXMgPSBjKHRvdFBvcDE5ID0gIkIwMzAwM18wMDEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGlzcGFuaWMgPSJCMDMwMDNfMDAzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFmckFtID0gIkIwMzAwMl8wMDQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGl0ZT0iQjAzMDAyXzAwMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdpbmk9IkIxOTA4M18wMDEiKSwgCiAgICAgICAgICAgICAgICAgICAgeWVhciA9IDIwMTksIGdlb21ldHJ5ID0gVFJVRSwgc2hpZnRfZ2VvID0gVFJVRSkgJT4lIAogICAgICAgICAgICBkcGx5cjo6c2VsZWN0KEdFT0lELCBOQU1FLCB2YXJpYWJsZSwgZXN0aW1hdGUpICU+JSAKICAgICAgICAgICAgc3ByZWFkKHZhcmlhYmxlLCBlc3RpbWF0ZSkgJT4lIAogICAgICAgICAgICBtdXRhdGUocGN0aGlzcFByMTkgID0gcm91bmQoKGhpc3BhbmljL3RvdFBvcDE5KSoxMDApLDEsIAogICAgICAgICAgICAgICAgICAgcGN0bmhibGFja3ByMTkgPSByb3VuZCgoYWZyQW0vdG90UG9wMTkpKjEwMCksMSAsIHBjdG5ocHdoaXRlMTk9cm91bmQoKHdoaXRlL3RvdFBvcDE5KSoxMDApLDEsIGNvZmlwcz1hcy5mYWN0b3IoR0VPSUQpKSAlPiUKICAgICAgICAgICAgZHBseXI6OnNlbGVjdChjb2ZpcHMsdG90UG9wMTkscGN0aGlzcFByMTksIHBjdG5oYmxhY2twcjE5LCBwY3RuaHB3aGl0ZTE5LGdpbmkpCgoKI01lcmdlIHRoZSBzb2Npb2Vjb25vbWljIHZhcmlhYmxlcyBmcm9tIHRoZSBBcmVhIHJlc291cmNlIGZpbGUgMjAxOS0yMDIwIHdpdGggdGhlIG90aGVyIHNvY2lvZWNvbm9taWMgdmFyaWFibGVzIGZyb20gdGhlIDUgeWVhciAoMjAxNS0yMDE5KSBBQ1MgZXN0aW1hdGVzLgoKIHNldmFyIDwtIGdlb19qb2luKCBVU19jb3VudHksIGFyZjIwMjAsIGJ5X3NwPSJjb2ZpcHMiLCBieV9kZj0iY29maXBzIixob3c9ImxlZnQiKSAKCiAjbG9hZCBhbmQgY2FsY3VsYXRlIG1hdGVybmFsIG1vcnRhbGl0eSByYXRlcyBmb3IgY291bnRpZXMgaW4gVVMgZm9yICBhIDV5ZWFyIHBlcmlvZCAoMjAxNS0yMDE5KQphbGxkYXQ8LXJlYWRSRFMoIn4vT25lRHJpdmUgLSBVbml2ZXJzaXR5IG9mIFRleGFzIGF0IFNhbiBBbnRvbmlvL21hdGVybmFsbW9ydGFsaXR5L2FnZ3JlZ2F0ZS9hbGxkYXQucmRzIikgCiBjb3VudHlNTVIgPC0gIGFsbGRhdCAlPiUgCiAgZ3JvdXBfYnkoY29maXBzKSU+JQogIHN1bW1hcmlzZShuYmlyPXN1bShuYmlydGhzLCBuYS5ybSA9IFQpLCBuZGVhID0gc3VtKG5kZWF0aHMsIG5hLnJtID0gVCkpICAlPiUgCiAgbXV0YXRlKG1tcmF0ZSA9cm91bmQoMTAwMDAwKihuZGVhL25iaXIpLDIpKQogCiAgI01lcmdlIHRoZSBzb2Npb2Vjb25vbWljIHZhcmlhYmxlcyB3aXRoIFVTIGNvdW50aWVzIG1hdGVybmFsIG1vcnRhbGl0eSByYXRlcyBmb3IgYSA1LSB5ZWFycyBwZXJpb2QoMjAxNS0yMDE5KQpNTVJkYXRhPC0gZ2VvX2pvaW4oIHNldmFyLCBjb3VudHlNTVIsIGJ5X3NwPSJjb2ZpcHMiLCBieV9kZj0iY29maXBzIixob3c9ImxlZnQiKSAlPiUgCiAgbXV0YXRlKHJtbXJhdGU9aWZlbHNlKG1tcmF0ZT49MSxtbXJhdGUsTkEpKSAlPiUgCiAgZmlsdGVyKCFpcy5uYShuZGVhKSwgbW1yYXRlIT1JbmYpICU+JSAKICBtdXRhdGUoRXhwZGQ9bmJpciooc3VtKG5kZWEpL3N1bShuYmlyKSkpICU+JSAKICBzdWJzZXQoIXN0YXRlJWluJWMoIjAyIiwgIjE1IiwgIjYwIiwgIjY2IiwgIjY5IiwgIjcyIiwgIjc4IikpCmBgYAoKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLGVjaG89RkFMU0V9CgojIEFzc2lnbiBDUlMgIHRvIHRoZSBkYXRhc2V0IGZvciBwcm9wZXIgbWFwIHByb2plY3Rpb24sCnVzY3R5bW1yPC0gc3RfdHJhbnNmb3JtKE1NUmRhdGEsIDIxNjMpCgoKI0dldCBTdGF0ZSBib3VuZGFyaWVzCnN0czwtIHN0YXRlcyhjYj1ULHByb2dyZXNzX2Jhcj1GQUxTRSklPiUKICBzaGlmdF9nZW9tZXRyeSgpICU+JSAKICBzdF90cmFuc2Zvcm0oY3JzPSAyMTYzKSU+JQogIHN0X2JvdW5kYXJ5KCkgJT4lIAogIHN1YnNldCghU1RBVEVGUCVpbiVjKCIwMiIsICIxNSIsICI2MCIsICI2NiIsICI2OSIsICI3MiIsICI3OCIpKQoKCiMgTWFrZSBVUyBjb3VudHkgTWF0ZXJuYWwgTW9ydGFsaXR5IFJhdGUgTWFwClVTbW1yIDwtIHVzY3R5bW1yJT4lCiAgbXV0YXRlKE1NUl9ncm91cCA9IGN1dChybW1yYXRlLCBicmVha3M9cXVhbnRpbGUocm1tcmF0ZSwgbmEucm09VFJVRSksIGluY2x1ZGUubG93ZXN0PVQgKSklPiUKICBnZ3Bsb3QoKSsKICBnZW9tX3NmKGFlcyhmaWxsPU1NUl9ncm91cCxjb2xvcj1OQSkpKwogIGdlb21fc2YoZGF0YT1zdHMsIGNvbG9yPSJibGFjayIpKwogIHNjYWxlX2NvbG91cl9icmV3ZXIocGFsZXR0ZSA9ICJSZEJ1IiApKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUmRCdSIsIG5hLnZhbHVlPSJncmV5IikrCiAgZ3VpZGVzKGZpbGw9Z3VpZGVfbGVnZW5kKHRpdGxlPSJNYXRlcm5hbCBNb3J0YWxpdHkgUmF0ZXMiKSkrCiAgZ2d0aXRsZSgiVVMgQ291bnRpZXMgTWF0ZXJuYWwgTW9ydGFsaXR5IFJhdGUgUGVyIDEwMCwwMDAsIDIwMTUtMjAxOSIpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCwgaGp1c3QgPSAwLjIpKSArCiAgdGhlbWUoCiAgICAgICAgbGVnZW5kLmtleS53aWR0aCA9IHVuaXQoMC4yNSwgImluIiksCiAgICAgICAgbGVnZW5kLmtleS5oZWlnaHQgPSB1bml0KDAuMiwgImluIiksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT04KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIsIGNvbG9yID0gTkEpKQoKYGBgCgojIyMgRGVzY3JpcHRpdmUgTWFwcwpgYGB7ciwgZWNobz1GQUxTRX0KVVNtbXIKYGBgCgoKIyMjIERlZmluaW5nIFZhcmlhYmxlcwpUaGUgZGVub21pbmF0b3IvIG9mZnNldCB2YXJpYWJsZSBmb3IgdGhpcyBhbmFseXNpcyBpcyBUb3RhbCBudW1iZXIgb2YgYmlydGhzIGluIFVTIGNvdW50eS4gRml2ZSBzb2Npb2Vjb25vbWljIHZhcmlhYmxlcyB3ZXJlIHVzZWQgYXMgcHJlZGljdG9ycyBpbiB0aGUgbW9kZWxzLS1wZXJjZW50YWdlIG9mIGNvdW50eSBwb3B1bGF0aW9uIHRoYXQgaXMgcnVyYWw7dGhlIG1lZGlhbiBob3VzZWhvbGQgaW5jb21lIGluIHRoZSBjb3VudHk7IHRoZSBjb3VudHnigJlzIG1lZGlhbiBob3VzZSB2YWx1ZTsgdGhlIHBvcHVsYXRpb24gZGVuc2l0eSBwZXIgc3F1YXJlIG1pbGUgb2YgdGhlIGNvdW50eTsgYW5kIGVyY2VudGFnZSBvZiBub24gSGlzcGFuaWMgYmxhY2sgcG9wdWxhdGlvbiBpbiB0aGUgY291bnRpZXMuIEFsbCB2YXJpYWJsZXMgd2VyZSBaIHNjb3JlZCAKCmBgYHtyLHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGVjaG89RkFMU0V9CiMgWiBzY29yZSBhbGwgdmFyaWFibGVzIAp1c2N0eW1tciRtZWRoaW5jejwtYXMubnVtZXJpYyhzY2FsZSh1c2N0eW1tciRtZWRoaW5jLCBjZW50ZXI9VCwgc2NhbGU9VCkpCnVzY3R5bW1yJG1lZGhvdXZsejwtYXMubnVtZXJpYyhzY2FsZSh1c2N0eW1tciRtZWRob3V2bCwgY2VudGVyPVQsIHNjYWxlPVQpKQp1c2N0eW1tciRwY3RjcnBvcHo8LWFzLm51bWVyaWMoc2NhbGUodXNjdHltbXIkcGN0Y3Jwb3AsIGNlbnRlcj1ULCBzY2FsZT1UKSkKdXNjdHltbXIkcGN0cGVycG92ejwtYXMubnVtZXJpYyhzY2FsZSh1c2N0eW1tciRwY3RwZXJwb3YsIGNlbnRlcj1ULCBzY2FsZT1UKSkKdXNjdHltbXIkY3R5cG9wZGVzejwtYXMubnVtZXJpYyhzY2FsZSh1c2N0eW1tciRjdHlwb3BkZXMsIGNlbnRlcj1ULCBzY2FsZT1UKSkKdXNjdHltbXIkb2JneW4xMF9wY3o8LWFzLm51bWVyaWMoc2NhbGUodXNjdHltbXIkb2JneW4xMF9wYywgY2VudGVyPVQsIHNjYWxlPVQpKQp1c2N0eW1tciRwY3RjdHl1bmVtcHo8LWFzLm51bWVyaWMoc2NhbGUodXNjdHltbXIkcGN0Y3R5dW5lbXAsIGNlbnRlcj1ULCBzY2FsZT1UKSkKdXNjdHltbXIkcnVjY3o8LWFzLm51bWVyaWMoc2NhbGUodXNjdHltbXIkcnVjYywgY2VudGVyPVQsIHNjYWxlPVQpKQp1c2N0eW1tciRwY3RoaXNwUHIxOXo8LWFzLm51bWVyaWMoc2NhbGUodXNjdHltbXIkcGN0aGlzcFByMTksIGNlbnRlcj1ULCBzY2FsZT1UKSkKdXNjdHltbXIkcGN0bmhibGFja3ByMTl6PC1hcy5udW1lcmljKHNjYWxlKHVzY3R5bW1yJHBjdG5oYmxhY2twcjE5LCBjZW50ZXI9VCwgc2NhbGU9VCkpCnVzY3R5bW1yJHBjdG5ocHdoaXRlMTl6PC1hcy5udW1lcmljKHNjYWxlKHVzY3R5bW1yJHBjdG5ocHdoaXRlMTksIGNlbnRlcj1ULCBzY2FsZT1UKSkKdXNjdHltbXIkZ2luaXo8LWFzLm51bWVyaWMoc2NhbGUodXNjdHltbXIkZ2luaSwgY2VudGVyPVQsIHNjYWxlPVQpKQpgYGAKCiMjIyBFc3RpbWF0aW5nIEdlbmVyYWxpemVkIExpbmVhciBNb2RlbApgYGB7cix3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlY2hvPUZBTFNFfQojIEZpbHRlciBvdXQgY291bnRpZXMgd2l0aG91dCBtYXRlcm5hbCBkZWF0aHMKdXNjdHltbXJyIDwtIHVzY3R5bW1yICU+JSAKICBmaWx0ZXIobmRlYT49MSkKI2ZpdCB0aGUgTmVnYXRpdmUgQmlub21pYWwgbW9kZWwgCmZpdF9uYjwtIGdsbS5uYihuZGVhIH4gb2Zmc2V0KGxvZyhuYmlyKSkgKyBydXJhbGl0eSsgbWVkaG91dmx6KyBwY3RjcnBvcHogKyBjdHlwb3BkZXN6ICsgcGN0bmhibGFja3ByMTl6K21lZGhpbmN6LAogICAgICAgICAgICAgICBkYXRhPXVzY3R5bW1ycikKc3VtbWFyeShmaXRfbmIpCiMgRXhwb25lbnRzIG9mIHRoZSBjb2VmZmljaWVudCAKZXhwKGNvZWYoZml0X25iKSkKYGBgCgpUaGUgbW9kZWwgYWJvdmUgc2hvd3MgYSAzMCUgaW5jcmVhc2UgaW4gcmVsYXRpdmUgcmlzayBmb3IgbWF0ZXJuYWwgZGVhdGggaW4gbm9uIG1ldHJvcG9saXRhbiBjb3VudGllcyBjb21wYXJlZCB0byBtZXRyb3BvbGl0YW4gY291bnRpZXMuIEFsc28sIGZvciBldmVyeSBvbmUgdW5pdCBpbmNyZWFzZSBpbiBjb3VudHkncyBtZWRpYW4gaG91c2UgdmFsdWUgYW5kIG1lZGlhbiBob3VzZWhvbGQgaW5jb21lLCBtYXRlcm5hbCBkZWF0aCBkZWNyZWFzZSBieSAxNSUgYW5kIDcuNSUgcmVzcGVjdGl2ZWx5LiBPbmUgdW5pdCBpbmNyZWFzZSBpbiBjb3VudHkncyBwZXJjZW50YWdlIG9mIHJ1cmFsIHBvcHVsYXRpb24sIENvdW50eSdzIHBvcHVsYXRpb24gZGVuc2l0eSwgYW5kIHBlcmNlbnRhZ2Ugb2YgTm9uLUhpc3BhbmljIGJsYWNrIGluY3JlYXNlIG1hdGVybmFsIG1vcnRhbGl0eSBzaWduaWZpY2FudGx5LiAgIAoKIyMjIFRlc3RpbmcgZm9yIE92ZXJkaXNwZXJzaW9uIApgYGB7cn0KIyBUZXN0aW5nIGZvciBvdmVyZGlzcGVyc2lvbiAgdXNpbmcgdGhlIHJhdGlvIG9mIHJlc2lkdWFsIGRldmlhbmNlIGFuZCByZXNpZHVhbCBkZWdyZWUgb2YgZnJlZWRvbSBmcm9tIHRoZSBwb2lzc29uIG1vZGVsLiAKc2NhbGU8LXNxcnQoZml0X25iJGRldmlhbmNlL2ZpdF9uYiRkZi5yZXNpZHVhbCkKc2NhbGUKCiMgVGVzdGluZyBmb3Igb3ZlcmRpc3BlcnNpb24gdXNpbmcgdGhlIGdvb2RuZXNzIG9mIGZpdCBzdGF0aXN0aWMuCjEtcGNoaXNxKGZpdF9uYiRkZXZpYW5jZSwgZGYgPSBmaXRfbmIkZGYucmVzaWR1YWwpCgpgYGAKClRoZSBvdmVyZGlzcGVyc2lvbiB0ZXN0IHNob3dzIHRoYXQgdGhlIG1vZGVsIGZpdHMgdGhlIGRhdGEgcHJvcGVybHkuIFRoZSBzY2FsZSB0ZXN0IGlzIGFwcHJveGltYXRlbHkgZXF1YWxzIHRvIDEgc2hvd2luZyB0aGF0IHRoZSAgbWVhbiBhbmQgdGhlIHZhcmlhbmNlIG9mIHRoZSBtb2RlbCBpcyBlcXVhbCB0byAxLiBMaWtld2lzZSB0aGUgZ29vZG5lc3Mgb2YgZml0IHN0YXRpc3RpYyBnYXZlIGEgbGFyZ2UgcCB2YWx1ZSBvZiAxLiBIZW5jZSwgdGhlIG1vZGVsIGZpdCB0aGUgZGF0YS4KCiMjIyBUZXN0aW5nIG1vZGVsIGZvciBSZXNpZHVhbCBBdXRvY29ycmVsYXRpb24gCmBgYHtyLHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9Cm5iczwta25lYXJuZWlnaChjb29yZGluYXRlcyhhcyh1c2N0eW1tcnIsICJTcGF0aWFsIikpLCBrID0gMiwgbG9uZ2xhdCA9IFQpCm5iczwta25uMm5iKG5icywgc3ltID0gVCkKdXMud3QyPC1uYjJsaXN0dyhuYnMsIHN0eWxlID0gIlciKQpsbS5tb3JhbnRlc3QoZml0X25iLCBsaXN0dyA9IHVzLnd0MikKYGBgCgpHaXZlbiB0aGUgcmVzdWx0IGZyb20gdGhlIGFib3ZlIG1vZGVsOyB0ZXN0aW5nIGZvciBhdXRvY29ycmVsYXRpb24sIGl0IGFwcGVhcnMgdGhlcmUgaXMgbm8gYXV0b2NvcnJlbGF0aW9uIGluIG91ciBkYXRhLiBUaGUgZ2xvYmFsIE1vcmFuIEkgaXMgMC4wMTMgd2l0aCBhIHAtdmFsdWUgdGhhdCBpcyBsYXJnZXIgdGhhbiAwLjA1LiBBdCB0aGlzIHBvaW50LCBJIGFtIG5vdCBzdXJlIG9uIGhvdyB0byBtb3ZlIGZvcndhcmQgd2l0aCB0aGUgcmVzdCBvZiB0aGUgYXNzaWdubWVudC4gCgojIyMgIENvbnN0cnVjdCBTcGF0aWFsIFJlbGF0aW9uc2hpcCBmb3IgSU5MQSAKYGBge3Isd2FybmluZz1GQUxTRX0KbW1yaW5sYSA8LSB1c2N0eW1tciAgJT4lIAogIGFycmFuZ2UoY29maXBzKSAlPiUgCiAgcm93aWRfdG9fY29sdW1uKCJpZCIpCiNjb25zdHJ1Y3RpbmcgYSBLIG5laWdoYm9yaG9vZApuYnM8LWtuZWFybmVpZ2goc3RfY2VudHJvaWQobW1yaW5sYSksIGsgPSA1LCBsb25nbGF0ID0gVCkgIApuYnM8LWtubjJuYihuYnMsIHJvdy5uYW1lcyA9IG1tcmlubGEkaWQsIHN5bSA9IFQpCm5iMklOTEEoImNsX2dyYXBoIixuYnMpCmFtX2FkaiA8LXBhc3RlKGdldHdkKCksIi9jbF9ncmFwaCIsc2VwPSIiKQpIPC1pbmxhLnJlYWQuZ3JhcGgoZmlsZW5hbWU9ImNsX2dyYXBoIikKYGBgCgojIyMgTW9kZWwgRXN0aW1hdGlvbiB3aXRob3V0IFNwdGlhbCBQYXR0ZXJuCmBgYHtyfQpmMTwtbmRlYX5ydXJhbGl0eSsgbWVkaG91dmx6KyBwY3RjcnBvcHogKyBjdHlwb3BkZXN6ICsgcGN0bmhibGFja3ByMTl6K21lZGhpbmN6KyAjZml4ZWQgZWZmZWN0cwogIGYoaWQsIG1vZGVsID0gImlpZCIpICAjcmFuZG9tIGVmZmVjdHMKCm1vZDI8LWlubGEoZm9ybXVsYSA9IGYxLAogICAgICAgICAgIGRhdGEgPSBtbXJpbmxhLAogICAgICAgICAgIGZhbWlseSA9ICJwb2lzc29uIiwKICAgICAgICAgICBFID0gRXhwZGQsIAogICAgICAgICAgIGNvbnRyb2wuY29tcHV0ZSA9IGxpc3Qod2FpYz1UKSwgCiAgICAgICAgICAgY29udHJvbC5wcmVkaWN0b3IgPSBsaXN0KGxpbms9MSksCiAgICAgICAgICAgbnVtLnRocmVhZHMgPSAzLCAKICAgICAgICAgICAgICAgdmVyYm9zZSA9IEYpCgojdG90YWwgbW9kZWwgc3VtbWFyeQpzdW1tYXJ5KG1vZDIpCmBgYAoKIyMjIE1hcmdpbmFsIERpc3RyaWJ1dGlvbnMgb2YgaHlwZXJwYXJhbWV0ZXJzCmBgYHtyfQptMjwtIGlubGEudG1hcmdpbmFsKAogICAgICAgIGZ1bmN0aW9uKHgpICgxL3gpLCAjaW52ZXJ0IHRoZSBwcmVjaXNpb24gdG8gYmUgb24gdmFyaWFuY2Ugc2NhbGUKICAgICAgICBtb2QyJG1hcmdpbmFscy5oeXBlcnBhciRgUHJlY2lzaW9uIGZvciBpZGApCiM5NSUgY3JlZGlibGUgaW50ZXJ2YWwgZm9yIHRoZSB2YXJpYW5jZQppbmxhLmhwZG1hcmdpbmFsKC45NSwgbWFyZ2luYWw9bTIpCgpwbG90KG0yLAogICAgIHR5cGU9ImwiLAogICAgIG1haW49YygiUG9zdGVyaW9yIGRpc3RpYnV0aW9uIGZvciBiZXR3ZWVuIGNvdW50eSB2YXJpYW5jZSIsICItIElJRCBtb2RlbCAtIiksIAogICAgIHhsaW09YygwLCAuNSkpCmBgYAoKYGBge3IsZWNobz1GQUxTRX0KbW1yaW5sYSRmaXR0ZWRfbTI8LW1vZDIkc3VtbWFyeS5maXR0ZWQudmFsdWVzJG1lYW4KCm1hcDEgPC1tbXJpbmxhJT4lCiMgIGZpbHRlcih5ZWFyJWluJWMoMjAwMCkpJT4lCiAgbXV0YXRlKHFycj1jdXQoZml0dGVkX20yLAogICAgICAgICAgICAgICAgIGJyZWFrcyA9IHF1YW50aWxlKGZpdHRlZF9tMiwgcD1zZXEoMCwxLGxlbmd0aC5vdXQgPSA2KSksCiAgICAgICAgICAgICAgICAgaW5jbHVkZS5sb3dlc3QgPSBUKSklPiUKICBnZ3Bsb3QoKStnZW9tX3NmKGFlcyhmaWxsPXFycikpKwogIHNjYWxlX2NvbG91cl9icmV3ZXIocGFsZXR0ZSA9ICJSZEJ1IiApKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUmRCdSIsIG5hLnZhbHVlPSJncmV5IikrCiAgZ3VpZGVzKGZpbGw9Z3VpZGVfbGVnZW5kKHRpdGxlPSJSZWxhdGl2ZSBSaXNrIFF1YXJ0aWxlIikpKwogIHRoZW1lX3ZvaWQoKSsKICBnZ3RpdGxlKGxhYmVsPSJSZWxhdGl2ZSBSaXNrIFF1YXJ0aWxlIC0gSUlEIE1vZGVsLCAyMDE5IikrCiAgY29vcmRfc2YoY3JzID0gMjE2MykKYGBgCgoKYGBge3J9Cm1hcDEKYGBgCgpgYGB7cn0KZjM8LW5kZWF+cnVyYWxpdHkrIG1lZGhvdXZseisgcGN0Y3Jwb3B6ICsgY3R5cG9wZGVzeiArIHBjdG5oYmxhY2twcjE5eittZWRoaW5jeisKICBmKGlkLCBtb2RlbCA9ICJieW0iLHNjYWxlLm1vZGVsID0gVCwgY29uc3RyID0gVCwgZ3JhcGggPSBIKQoKbW9kMzwtaW5sYShmb3JtdWxhID0gZjMsZGF0YSA9IG1tcmlubGEsCiAgICAgICAgICAgZmFtaWx5ID0gInBvaXNzb24iLAogICAgICAgICAgIEUgPSBFeHBkZCwgCiAgICAgICAgICAgY29udHJvbC5jb21wdXRlID0gbGlzdCh3YWljPVQscmV0dXJuLm1hcmdpbmFscy5wcmVkaWN0b3I9VFJVRSksIAogICAgICAgICAgIGNvbnRyb2wucHJlZGljdG9yID0gbGlzdChsaW5rPTEpLCAKICAgICAgICAgICBudW0udGhyZWFkcyA9IDMsIAogICAgICAgICAgICAgICB2ZXJib3NlID0gRikKCiN0b3RhbCBtb2RlbCBzdW1tYXJ5CnN1bW1hcnkobW9kMykKYGBgCgpgYGB7cn0KbW9kMiR3YWljJHdhaWMKbW9kMyR3YWljJHdhaWMKYGBgCgojIyMgUmVncmVzc2lvbiBlZmZlY3QgcG9zdGVyaW9yIGRpc3RyaWJ1dGlvbnMKYGBge3J9CmIxIDwtIGlubGEuZW1hcmdpbmFsKGV4cCwgbW9kMiRtYXJnaW5hbHMuZml4ZWRbWzJdXSkKYjEgI1Bvc3RlcmlvciBtZWFuCgpiMWNpIDwtaW5sYS5xbWFyZ2luYWwoYyguMDI1LCAuOTc1KSwgCiAgICAgICAgICAgICAgICAgICAgICBpbmxhLnRtYXJnaW5hbChleHAsIG1vZDIkbWFyZ2luYWxzLmZpeGVkW1syXV0pKQpiMWNpCmBgYAoKIyMjIEh5cGVyIHBhcmFtZXRlciBkaXN0cmlidXRpb25zCmBgYHtyfQptM2E8LSBpbmxhLnRtYXJnaW5hbCgKICAgICAgICBmdW5jdGlvbih4KSAoMS94KSwKICAgICAgICBtb2QzJG1hcmdpbmFscy5oeXBlcnBhciRgUHJlY2lzaW9uIGZvciBpZCAoaWlkIGNvbXBvbmVudClgKQptM2I8LSBpbmxhLnRtYXJnaW5hbCgKICAgICAgICBmdW5jdGlvbih4KSAoMS94KSwKICAgICAgICBtb2QzJG1hcmdpbmFscy5oeXBlcnBhciRgUHJlY2lzaW9uIGZvciBpZCAoc3BhdGlhbCBjb21wb25lbnQpYCkKCnBsb3QobTNhLCB0eXBlPSJsIiwKICAgICBtYWluPWMoIlBvc3RlcmlvciBkaXN0aWJ1dGlvbiBmb3IgYmV0d2VlbiBjb3VudHkgdmFyaWFuY2UiLCAiLSBCWU0gbW9kZWwgLSIpLAogICAgIHhsaW09YygwLCAuMikpICMgeW91IG1heSBuZWVkIHRvIGNoYW5nZSB0aGlzCiNsaW5lcyhtM2IsIGNvbD0icmVkIikKbGluZXMobTNiLCBjb2w9ImdyZWVuIikKYGBgCgpgYGB7cn0KaW5sYS5ocGRtYXJnaW5hbCguOTUsbTNhKQppbmxhLmhwZG1hcmdpbmFsKC45NSxtM2IpCmBgYAoKIyMjIFNwYXRpYWwgbWFwcGluZyBvZiB0aGUgZml0dGVkIHZhbHVlcwpgYGB7ciwgZWNobz1GQUxTRX0KbW1yaW5sYSRmaXR0ZWRfbTM8LW1vZDMkc3VtbWFyeS5maXR0ZWQudmFsdWVzJG1lYW4KCm1hcDIgPC0gbW1yaW5sYSU+JQogIyBmaWx0ZXIoeWVhciVpbiVjKDIwMDApKSU+JQogIG11dGF0ZShxcnI9Y3V0KGZpdHRlZF9tMywKICAgICAgICAgICAgICAgICBicmVha3MgPSBxdWFudGlsZShmaXR0ZWRfbTMsIHA9c2VxKDAsMSxsZW5ndGgub3V0ID0gNikpLAogICAgICAgICAgICAgICAgIGluY2x1ZGUubG93ZXN0ID0gVCkpJT4lCiAgZ2dwbG90KCkrCiAgZ2VvbV9zZihhZXMoZmlsbD1xcnIpKSsKICBzY2FsZV9jb2xvdXJfYnJld2VyKHBhbGV0dGUgPSAiUmRCdSIgKSsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlJkQnUiLCBuYS52YWx1ZT0iZ3JleSIpKwogIGd1aWRlcyhmaWxsPWd1aWRlX2xlZ2VuZCh0aXRsZT0iUmVsYXRpdmUgUmlzayBRdWFydGlsZSIpKSsKICB0aGVtZV92b2lkKCkrCiAgZ2d0aXRsZShsYWJlbD0iUmVsYXRpdmUgUmlzayBRdWFydGlsZSAtIEJZTSBNb2RlbCwgMjAxOSIpKwogIGNvb3JkX3NmKGNycyA9IDIxNjMpCmBgYAoKYGBge3J9Cm1hcDIKYGBgCgojIyMgTWFwIG9mIHNwYXRpYWwgcmFuZG9tIGVmZmVjdHMKYGBge3IsZWNobz1GQUxTRX0KbW1yaW5sYSRzcF9yZTwtbW9kMyRzdW1tYXJ5LnJhbmRvbSRpZCRtZWFuWzMwODU6NjIxNl0KbWFwMzwtbW1yaW5sYSU+JQogIG11dGF0ZShxc2U9Y3V0KHNwX3JlLCAKICAgICAgICAgICAgICAgICBicmVha3MgPSBxdWFudGlsZShzcF9yZSwgcD1zZXEoMCwxLGxlbmd0aC5vdXQgPSA2KSksCiAgICAgICAgICAgICAgICAgaW5jbHVkZS5sb3dlc3QgPSBUKSklPiUKICBnZ3Bsb3QoKSsKICBnZW9tX3NmKGFlcyhmaWxsPXFzZSwgY29sb3I9TkEpKSsKICBnZW9tX3NmKGRhdGE9c3RzKSsKICBzY2FsZV9jb2xvdXJfYnJld2VyKHBhbGV0dGUgPSAiUmRCdSIgKSsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlJkQnUiLCBuYS52YWx1ZT0iZ3JleSIpKwogIGd1aWRlcyhmaWxsPWd1aWRlX2xlZ2VuZCh0aXRsZT0iU3BhdGlhbCBFeGNlc3MgUmlzayIpKSsKICB0aGVtZV92b2lkKCkrCiAgZ2d0aXRsZShsYWJlbD0iU3BhdGlhbCBSYW5kb20gRWZmZWN0IC0gQllNIE1vZGVsIikrCiAgY29vcmRfc2YoY3JzID0gMjE2MykKYGBgCgpgYGB7cn0KbWFwMwpgYGAKCmBgYHtyLGVjaG89RkFMU0V9Cm1tcmlubGEkaV9yZTwtbW9kMyRzdW1tYXJ5LnJhbmRvbSRpZCRtZWFuWzE6MzEzMl0KbWFwNCA8LW1tcmlubGElPiUKICBtdXRhdGUocXNlPWN1dChpX3JlLCAKICAgICAgICAgICAgICAgICBicmVha3MgPSBxdWFudGlsZShpX3JlLCBwPXNlcSgwLDEsbGVuZ3RoLm91dCA9IDYpKSwKICAgICAgICAgICAgICAgICBpbmNsdWRlLmxvd2VzdCA9IFQpKSU+JQogIGdncGxvdCgpKwogIGdlb21fc2YoYWVzKGZpbGw9cXNlLCBjb2xvcj1OQSkpKwogIGdlb21fc2YoZGF0YT1zdHMpKwogIHNjYWxlX2NvbG91cl9icmV3ZXIocGFsZXR0ZSA9ICJSZEJ1IiApKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUmRCdSIsIG5hLnZhbHVlPSJncmV5IikrCiAgZ3VpZGVzKGZpbGw9Z3VpZGVfbGVnZW5kKHRpdGxlPSJTcGF0aWFsIEV4Y2VzcyBSaXNrIikpKwogIHRoZW1lX3ZvaWQoKSsKICBnZ3RpdGxlKGxhYmVsPSJVbnN0cnVjdHVyZWQgUmFuZG9tIEVmZmVjdCAtIEJZTSBNb2RlbCIpKwogIGNvb3JkX3NmKGNycyA9IDIxNjMpCmBgYAoKYGBge3J9Cm1hcDQKYGBgCgo=