Hi there, in this brief tutorial I will show you how to create a lisa map from scratch in R… For some reason the p-values in R
and the p-values computed in Geoda
for the local Moran’s I are slightly different. Any questions (or suggestions in order to improve this tutorial) are always welcome! Regards, Felipe.
loading required packages
## -- Attaching packages --------
## v ggplot2 3.3.0 v purrr 0.3.4
## v tibble 3.0.1 v dplyr 0.8.5
## v tidyr 1.0.3 v stringr 1.4.0
## v readr 1.3.1 v forcats 0.5.0
## -- Conflicts -----------------
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
## Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1
## Loading required package: spData
## To access larger datasets in this package, install the spDataLarge
## package with: `install.packages('spDataLarge',
## repos='https://nowosad.github.io/drat/', type='source')`
## rgeos version: 0.5-3, (SVN revision 634)
## GEOS runtime version: 3.8.0-CAPI-1.13.1
## Linking to sp version: 1.4-1
## Polygon checking: TRUE
##
## Attaching package: 'rgeoda'
## The following object is masked from 'package:spdep':
##
## skater
Import the different shapefiles for Pakistan
## Reading layer `gadm36_PAK_0' from data source `C:\Users\felip\OneDrive\Desktop\Meidai\Seminar Research\GitHub\tutorial-local-morans-I-spatial-scales\shapefiles\gadm36_PAK_0.shp' using driver `ESRI Shapefile'
## Simple feature collection with 1 feature and 2 fields
## geometry type: MULTIPOLYGON
## dimension: XY
## bbox: xmin: 60.89944 ymin: 23.70292 xmax: 77.84308 ymax: 37.09701
## geographic CRS: WGS 84
## [1] "SpatialPolygonsDataFrame"
## attr(,"package")
## [1] "sp"
## Reading layer `gadm36_PAK_1' from data source `C:\Users\felip\OneDrive\Desktop\Meidai\Seminar Research\GitHub\tutorial-local-morans-I-spatial-scales\shapefiles\gadm36_PAK_1.shp' using driver `ESRI Shapefile'
## Simple feature collection with 8 features and 10 fields
## geometry type: MULTIPOLYGON
## dimension: XY
## bbox: xmin: 60.89944 ymin: 23.70292 xmax: 77.84308 ymax: 37.09701
## geographic CRS: WGS 84
## [1] "SpatialPolygonsDataFrame"
## attr(,"package")
## [1] "sp"
## Reading layer `gadm36_PAK_2noNA' from data source `C:\Users\felip\OneDrive\Desktop\Meidai\Seminar Research\GitHub\tutorial-local-morans-I-spatial-scales\shapefiles\gadm36_PAK_2noNA.shp' using driver `ESRI Shapefile'
## Simple feature collection with 29 features and 14 fields
## geometry type: MULTIPOLYGON
## dimension: XY
## bbox: xmin: 60.89944 ymin: 23.70292 xmax: 75.367 ymax: 36.8898
## geographic CRS: WGS 84
## [1] "SpatialPolygonsDataFrame"
## attr(,"package")
## [1] "sp"
## Reading layer `gadm36_PAK_3_noNA' from data source `C:\Users\felip\OneDrive\Desktop\Meidai\Seminar Research\GitHub\tutorial-local-morans-I-spatial-scales\shapefiles\gadm36_PAK_3_noNA.shp' using driver `ESRI Shapefile'
## Simple feature collection with 116 features and 21 fields
## geometry type: MULTIPOLYGON
## dimension: XY
## bbox: xmin: 60.89944 ymin: 23.70292 xmax: 75.367 ymax: 36.8898
## geographic CRS: WGS 84
## [1] "SpatialPolygonsDataFrame"
## attr(,"package")
## [1] "sp"
quick-maps



Do the shapefiles have the same projection?
## [1] "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
## [1] "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
## [1] TRUE
Creating a quantile map for the variable ANC with the borders of the provinces

Spatial Analysis
creating a spatial weight matrix
Computing the Global Moran’s I
##
## Moran I test under randomisation
##
## data: mun_merge$ANC
## weights: listw
##
## Moran I statistic standard deviate = 10.211, p-value <
## 0.00000000000000022
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic Expectation Variance
## 0.600578644 -0.008695652 0.003560323
Creating a table with the Local Moran’s I
Also Adding a quadrant variable to the local Moran’s I table
lmoran<- cbind(mun_merge@data, localmoran(mun_merge$ANC, listw, p.adjust.method="none", adjust.x=TRUE))
#lmoran
# centers the local Moran's around the mean
lmoran$Ii <- lmoran$Ii - mean(lmoran$Ii, na.rm = TRUE)
lmoran$lag.ANC<- lag.listw(listw,lmoran$ANC, NAOK = TRUE)
# centers the variable of interest around its mean
lmoran$ANCs <- lmoran$ANC - mean(lmoran$ANC, na.rm = TRUE)
lmoran$lag.ANC <- lmoran$lag.ANC - mean(lmoran$lag.ANC, na.rm = TRUE)
signif <- 0.05
#lmoran
lmoran <- lmoran%>%
mutate(quadrant= ifelse(ANCs>0 & lag.ANC > 0, 1, 0)) %>%
mutate(quadrant= ifelse(ANCs<0 & lag.ANC < 0, 2, quadrant)) %>%
mutate(quadrant= ifelse(ANCs<0 & lag.ANC > 0, 3, quadrant)) %>%
mutate(quadrant= ifelse(ANCs>0 & lag.ANC < 0, 4, quadrant)) %>% mutate(quadrant= ifelse(lmoran$`Pr(z > 0)` > signif, 0, quadrant)) %>%
mutate(quadrant2= ifelse(ANC_st>0 & lagANC_st > 0, 1, 0)) %>%
mutate(quadrant2= ifelse(ANC_st<0 & lagANC_st < 0, 2, quadrant2)) %>%
mutate(quadrant2= ifelse(ANC_st<0 & lagANC_st > 0, 3, quadrant2)) %>%
mutate(quadrant2= ifelse(ANC_st>0 & lagANC_st < 0, 4, quadrant2)) %>%
mutate(quadrant2= ifelse(lmoran$LISA_PANC > signif, 0, quadrant2))
mun_merge_new<- merge(mun_merge, lmoran, by.x="GID_3", by.y="GID_3")
comparing the geoda p-values and the R p-values
LISA MAPS (P-VALUE < 0.05)
# R p value
breaks = c(0, 1, 2, 3, 4, 5)
LISA1<-tm_shape(mun_merge_new) + tm_fill(col = "quadrant", breaks = breaks, palette= c("white","red","blue",rgb(0,0,1,alpha=0.4),rgb(1,0,0,alpha=0.4)), labels = c("Not significant", "High-High","Low-Low","Low-High","High-Low"), title="")+
tm_legend(text.size = 1) +
# tm_scale_bar(position = c("LEFT", "BOTTOM"),text.size = 1.0)+
# tm_compass(type = "8star", position = c("RIGHT", "BOTTOM"), show.labels = 2, text.size = 0.5)+
tm_borders(alpha=.5) +
tm_layout( frame = FALSE, title = "LISA with the R p-values ")
# Geoda p Value
breaks = c(0, 1, 2, 3, 4, 5)
LISA2<- tm_shape(mun_merge_new) + tm_fill(col = "quadrant2", breaks = breaks, palette= c("white","red","blue",rgb(0,0,1,alpha=0.4),rgb(1,0,0,alpha=0.4)), labels = c("Not significant", "High-High","Low-Low","Low-High","High-Low"), title="")+
tm_legend(text.size = 1) +
# tm_scale_bar(position = c("LEFT", "BOTTOM"),text.size = 1.0)+
# tm_compass(type = "8star", position = c("RIGHT", "BOTTOM"), show.labels = 2, text.size = 0.5)+
tm_borders(alpha=.5) +
tm_layout( frame = FALSE, title = "LISA with the GEODA p-values")
tmap_arrange(LISA1, LISA2)

creating a nicer map with the p values of GEODA
tm_shape(mun_merge_new) + tm_fill(col = "quadrant2", breaks = breaks, palette= c("white","red","blue",rgb(0,0,1,alpha=0.4),rgb(1,0,0,alpha=0.4)), labels = c("Not significant", "High-High","Low-Low","Low-High","High-Low"), title="")+
tm_legend(text.size = 1) +
# tm_scale_bar(position = c("LEFT", "BOTTOM"),text.size = 1.0)+
# tm_compass(type = "8star", position = c("RIGHT", "BOTTOM"), show.labels = 2, text.size = 0.5)+
tm_borders(lwd =.05) +
tm_shape(pro.sp)+
tm_borders(lwd=3)+
tm_layout( frame = FALSE, title = "LISA (GEODA p-values)")

LS0tDQp0aXRsZTogIkxvY2FsIE1vcmFuJ3MgSSBhbmQgc3BhdGlhbCBzY2FsZXMgKHVzaW5nIFIgYW5kIHRtYXApIg0KYXV0aG9yOiAiRmVsaXBlIFNhbnRvcyBNYXJxdWV6Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICBkZl9wcmludDogcGFnZWQNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6DQogICAgICBjb2xsYXBzZWQ6IGZhbHNlDQogICAgICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQ0KICAgIHRvY19kZXB0aDogNA0KICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQ0KICAgIGNvZGVfZm9sZGluZzogInNob3ciDQogICAgdGhlbWU6ICJjb3NtbyINCiAgICBoaWdobGlnaHQ6ICJtb25vY2hyb21lIg0KICBodG1sX25vdGVib29rOg0KICAgIGNvZGVfZm9sZGluZzogc2hvdw0KICAgIGhpZ2hsaWdodDogbW9ub2Nocm9tZQ0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdGhlbWU6IGNvc21vDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6DQogICAgICBjb2xsYXBzZWQ6IG5vDQogICAgICBzbW9vdGhfc2Nyb2xsOiBubw0KICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQNCiAgd29yZF9kb2N1bWVudDogZGVmYXVsdA0KLS0tDQoNCjxzdHlsZT4NCmgxLnRpdGxlIHtmb250LXNpemU6IDE4cHQ7IGNvbG9yOiBEYXJrQmx1ZTt9IA0KYm9keSwgaDEsIGgyLCBoMywgaDQge2ZvbnQtZmFtaWx5OiAiUGFsYXRpbm8iLCBzZXJpZjt9DQpib2R5IHtmb250LXNpemU6IDEycHQ7fQ0KLyogSGVhZGVycyAqLw0KaDEsaDIsaDMsaDQsaDUsaDZ7Zm9udC1zaXplOiAxNHB0OyBjb2xvcjogIzAwMDA4Qjt9DQpib2R5IHtjb2xvcjogIzMzMzMzMzt9DQphLCBhOmhvdmVyIHtjb2xvcjogIzhCM0E2Mjt9DQpwcmUge2ZvbnQtc2l6ZTogMTJweDt9DQo8L3N0eWxlPg0KDQoNCkhpIHRoZXJlLCBpbiB0aGlzIGJyaWVmIHR1dG9yaWFsIEkgd2lsbCBzaG93IHlvdSBob3cgdG8gY3JlYXRlIGEgbGlzYSBtYXAgZnJvbSBzY3JhdGNoIGluIFIuLi4gRm9yIHNvbWUgcmVhc29uIHRoZSBwLXZhbHVlcyBpbiBgUmAgYW5kIHRoZSBwLXZhbHVlcyBjb21wdXRlZCBpbiBgR2VvZGFgIGZvciB0aGUgbG9jYWwgTW9yYW4ncyBJIGFyZSBzbGlnaHRseSBkaWZmZXJlbnQuIA0KQW55IHF1ZXN0aW9ucyAob3Igc3VnZ2VzdGlvbnMgaW4gb3JkZXIgdG8gaW1wcm92ZSB0aGlzIHR1dG9yaWFsKSBhcmUgYWx3YXlzIHdlbGNvbWUhIA0KUmVnYXJkcywgRmVsaXBlLg0KDQojIGxvYWRpbmcgcmVxdWlyZWQgcGFja2FnZXMNCg0KYGBge3Igc2V0dXB9DQprbml0cjo6b3B0c19jaHVuayRzZXQod2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoc3ApDQpsaWJyYXJ5KHNmKQ0KbGlicmFyeShmYXN0bWFwKQ0KbGlicmFyeShza2ltcikNCmxpYnJhcnkodG1hcCkNCmxpYnJhcnkodG1hcHRvb2xzKQ0KbGlicmFyeShzcGRlcCkNCmxpYnJhcnkocmdlb3MpDQojcmVtb3Rlczo6aW5zdGFsbF9naXRodWIoImxpeHVuOTEwL3JnZW9kYSIpDQpsaWJyYXJ5KHJnZW9kYSkNCiMgQ2hhbmdlIHRoZSBwcmVzZW50YXRpb24gb2YgZGVjaW1hbCBudW1iZXJzIHRvIDQgYW5kIGF2b2lkIHNjaWVudGlmaWMgbm90YXRpb24NCm9wdGlvbnMocHJvbXB0PSJSPiAiLCBkaWdpdHM9Nywgc2NpcGVuPTk5OSkNCmBgYA0KDQoNCiMgSW1wb3J0IHRoZSBkaWZmZXJlbnQgc2hhcGVmaWxlcyBmb3IgUGFraXN0YW4NCg0KYGBge3J9DQpuYXQ8LSBzdF9yZWFkKCJzaGFwZWZpbGVzL2dhZG0zNl9QQUtfMC5zaHAiKQ0KbmF0LnNwIDwtIGFzKG5hdCwgIlNwYXRpYWwiKQ0KY2xhc3MobmF0LnNwKQ0KDQpuYXQyPC0gc3RfcmVhZCgic2hhcGVmaWxlcy9nYWRtMzZfUEFLXzEuc2hwIikNCm5hdDIuc3AgPC0gYXMobmF0MiwgIlNwYXRpYWwiKQ0KY2xhc3MobmF0Mi5zcCkNCg0KcHJvPC0gc3RfcmVhZCgic2hhcGVmaWxlcy9nYWRtMzZfUEFLXzJub05BLnNocCIpDQpwcm8uc3AgPC0gYXMocHJvLCAiU3BhdGlhbCIpDQpjbGFzcyhwcm8uc3ApDQoNCmRpczwtIHN0X3JlYWQoInNoYXBlZmlsZXMvZ2FkbTM2X1BBS18zX25vTkEuc2hwIikNCiNkaXM8LSBzdF9yZWFkKCJzaGFwZWZpbGVzL2dhZG0zNl9QQUtfMy5zaHAiKQ0KI2RpczwtIGRpcyAlPiUgZmlsdGVyKCFpcy5uYShBTkMpKQ0KZGlzLnNwIDwtIGFzKGRpcywgIlNwYXRpYWwiKQ0KY2xhc3MoZGlzLnNwKQ0KDQpgYGANCg0KcXVpY2stbWFwcw0KDQpgYGB7cn0NCnF0bShuYXQpDQpxdG0ocHJvKQ0KcXRtKGRpcykNCmBgYA0KDQpgYGB7cn0NCm11bl9tZXJnZTwtIGRpcy5zcA0KI3N0X2Ryb3BfZ2VvbWV0cnkoZGlzKQ0KI211bl9tZXJnZSRBTkMNCmBgYA0KDQojIyBEbyB0aGUgc2hhcGVmaWxlcyBoYXZlIHRoZSBzYW1lIHByb2plY3Rpb24/DQoNCmBgYHtyfQ0KcHJvajRzdHJpbmcobXVuX21lcmdlKQ0KcHJvajRzdHJpbmcocHJvLnNwKQ0KDQpwcm9qNHN0cmluZyhtdW5fbWVyZ2UpPT1wcm9qNHN0cmluZyhwcm8uc3ApDQoNCmBgYA0KDQojIENyZWF0aW5nIGEgcXVhbnRpbGUgbWFwIGZvciB0aGUgdmFyaWFibGUgQU5DIHdpdGggdGhlIGJvcmRlcnMgb2YgdGhlIHByb3ZpbmNlcw0KDQpgYGB7cn0NCnRtX3NoYXBlKG11bl9tZXJnZSkrDQogIHRtX2ZpbGwoY29sPSJBTkMiLHN0eWxlID0gInF1YW50aWxlIiwgbj0zLCAgdGl0bGUgPSAiQU5DIikrDQogIHRtX2xheW91dChmcmFtZSA9IEZBTFNFLGxlZ2VuZC5vdXRzaWRlID0gVFJVRSkrDQogdG1fYm9yZGVycyhsd2Q9MC4wMSkrDQogICB0bV9zaGFwZShwcm8uc3ApKw0KICB0bV9ib3JkZXJzKGx3ZD0zKQ0KdG1hcF9zYXZlKGZpbGVuYW1lID0gIkFOQy5wbmciLCBoZWlnaHQ9NSwgd2lkdGg9NSkNCmBgYA0KDQojIFNwYXRpYWwgQW5hbHlzaXMNCg0KIyMgY3JlYXRpbmcgYSBzcGF0aWFsIHdlaWdodCBtYXRyaXgNCg0KYGBge3J9DQpuYjwtIHBvbHkybmIobXVuX21lcmdlKQ0KbGlzdHc8LSBuYjJsaXN0dyhuYiwgc3R5bGUgPSAiVyIpDQpgYGANCg0KIyMgQ29tcHV0aW5nIHRoZSBHbG9iYWwgTW9yYW4ncyBJDQoNCmBgYHtyfQ0KZ2xvYmFsTW9yYW4gPC0gbW9yYW4udGVzdChtdW5fbWVyZ2UkQU5DLCBsaXN0dywgbmEuYWN0aW9uID0gIG5hLmV4Y2x1ZGUpDQpnbG9iYWxNb3Jhbg0KYGBgDQoNCiMjIGRhdGEgaW4gdGhlIHNoYXBlZmlsZQ0KDQpgYGB7cn0NCmhlYWQoc3RfZHJvcF9nZW9tZXRyeShzdF9hc19zZiggbXVuX21lcmdlKSkpDQpoZWFkKG11bl9tZXJnZUBkYXRhKQ0KYGBgDQoNCiMjIENyZWF0aW5nIGEgdGFibGUgd2l0aCB0aGUgTG9jYWwgTW9yYW4ncyBJDQoNCkFsc28gQWRkaW5nIGEgcXVhZHJhbnQgdmFyaWFibGUgdG8gdGhlIGxvY2FsIE1vcmFuJ3MgSSB0YWJsZQ0KDQpgYGB7cn0NCmxtb3JhbjwtIGNiaW5kKG11bl9tZXJnZUBkYXRhLCBsb2NhbG1vcmFuKG11bl9tZXJnZSRBTkMsIGxpc3R3LCBwLmFkanVzdC5tZXRob2Q9Im5vbmUiLCBhZGp1c3QueD1UUlVFKSkNCiNsbW9yYW4NCg0KIyBjZW50ZXJzIHRoZSBsb2NhbCBNb3JhbidzIGFyb3VuZCB0aGUgbWVhbg0KbG1vcmFuJElpIDwtIGxtb3JhbiRJaSAtIG1lYW4obG1vcmFuJElpLCBuYS5ybSA9IFRSVUUpIA0KbG1vcmFuJGxhZy5BTkM8LSAgbGFnLmxpc3R3KGxpc3R3LGxtb3JhbiRBTkMsIE5BT0sgPSBUUlVFKQ0KDQojIGNlbnRlcnMgdGhlIHZhcmlhYmxlIG9mIGludGVyZXN0IGFyb3VuZCBpdHMgbWVhbg0KDQpsbW9yYW4kQU5DcyA8LSBsbW9yYW4kQU5DIC0gbWVhbihsbW9yYW4kQU5DLCBuYS5ybSA9IFRSVUUpIA0KbG1vcmFuJGxhZy5BTkMgPC0gbG1vcmFuJGxhZy5BTkMgLSBtZWFuKGxtb3JhbiRsYWcuQU5DLCBuYS5ybSA9IFRSVUUpIA0KDQpzaWduaWYgPC0gMC4wNQ0KI2xtb3Jhbg0KDQoNCmxtb3JhbiA8LSBsbW9yYW4lPiUgDQogIG11dGF0ZShxdWFkcmFudD0gaWZlbHNlKEFOQ3M+MCAmIGxhZy5BTkMgPiAwLCAxLCAwKSkgJT4lIA0KICBtdXRhdGUocXVhZHJhbnQ9IGlmZWxzZShBTkNzPDAgJiBsYWcuQU5DIDwgMCwgMiwgcXVhZHJhbnQpKSAlPiUgDQogbXV0YXRlKHF1YWRyYW50PSBpZmVsc2UoQU5DczwwICYgbGFnLkFOQyA+IDAsIDMsIHF1YWRyYW50KSkgJT4lIA0KIG11dGF0ZShxdWFkcmFudD0gaWZlbHNlKEFOQ3M+MCAmIGxhZy5BTkMgPCAwLCA0LCBxdWFkcmFudCkpICU+JSAgIG11dGF0ZShxdWFkcmFudD0gaWZlbHNlKGxtb3JhbiRgUHIoeiA+IDApYCA+IHNpZ25pZiwgMCwgcXVhZHJhbnQpKSAlPiUgDQogIG11dGF0ZShxdWFkcmFudDI9IGlmZWxzZShBTkNfc3Q+MCAmIGxhZ0FOQ19zdCA+IDAsIDEsIDApKSAlPiUgDQptdXRhdGUocXVhZHJhbnQyPSBpZmVsc2UoQU5DX3N0PDAgJiBsYWdBTkNfc3QgPCAwLCAyLCBxdWFkcmFudDIpKSAlPiUgDQogIG11dGF0ZShxdWFkcmFudDI9IGlmZWxzZShBTkNfc3Q8MCAmIGxhZ0FOQ19zdCA+IDAsIDMsIHF1YWRyYW50MikpICU+JSANCiBtdXRhdGUocXVhZHJhbnQyPSBpZmVsc2UoQU5DX3N0PjAgJiBsYWdBTkNfc3QgPCAwLCA0LCBxdWFkcmFudDIpKSAlPiUgDQogbXV0YXRlKHF1YWRyYW50Mj0gaWZlbHNlKGxtb3JhbiRMSVNBX1BBTkMgPiBzaWduaWYsIDAsIHF1YWRyYW50MikpDQogIA0KbXVuX21lcmdlX25ldzwtIG1lcmdlKG11bl9tZXJnZSwgbG1vcmFuLCBieS54PSJHSURfMyIsIGJ5Lnk9IkdJRF8zIikNCmBgYA0KDQojIyAgY29tcGFyaW5nIHRoZSBnZW9kYSBwLXZhbHVlcyBhbmQgdGhlIFIgcC12YWx1ZXMNCg0KYGBge3J9DQpoZWFkKG11bl9tZXJnZV9uZXdAZGF0YSAlPiUgDQogIHNlbGVjdChMSVNBX1BBTkMueSxgUHIoeiA+IDApYCApKQ0KYGBgDQoNCg0KIyMgTElTQSBNQVBTIChQLVZBTFVFIDwgMC4wNSkNCiANCmBgYHtyfQ0KDQojIFIgcCB2YWx1ZQ0KIGJyZWFrcyA9IGMoMCwgMSwgMiwgMywgNCwgNSkgDQpMSVNBMTwtdG1fc2hhcGUobXVuX21lcmdlX25ldykgKyB0bV9maWxsKGNvbCA9ICJxdWFkcmFudCIsIGJyZWFrcyA9IGJyZWFrcywgcGFsZXR0ZT0gIGMoIndoaXRlIiwicmVkIiwiYmx1ZSIscmdiKDAsMCwxLGFscGhhPTAuNCkscmdiKDEsMCwwLGFscGhhPTAuNCkpLCBsYWJlbHMgPSBjKCJOb3Qgc2lnbmlmaWNhbnQiLCAiSGlnaC1IaWdoIiwiTG93LUxvdyIsIkxvdy1IaWdoIiwiSGlnaC1Mb3ciKSwgdGl0bGU9IiIpKw0KICB0bV9sZWdlbmQodGV4dC5zaXplID0gMSkgICsNCiAjIHRtX3NjYWxlX2Jhcihwb3NpdGlvbiA9IGMoIkxFRlQiLCAiQk9UVE9NIiksdGV4dC5zaXplID0gMS4wKSsNCiAgIyB0bV9jb21wYXNzKHR5cGUgPSAiOHN0YXIiLCAgIHBvc2l0aW9uID0gYygiUklHSFQiLCAiQk9UVE9NIiksICAgICAgc2hvdy5sYWJlbHMgPSAyLCAgIHRleHQuc2l6ZSA9IDAuNSkrDQogICAgdG1fYm9yZGVycyhhbHBoYT0uNSkgKw0KICAgdG1fbGF5b3V0KCBmcmFtZSA9IEZBTFNFLCAgdGl0bGUgPSAiTElTQSB3aXRoIHRoZSBSIHAtdmFsdWVzICIpDQoNCiMgR2VvZGEgcCBWYWx1ZQ0KDQpicmVha3MgPSBjKDAsIDEsIDIsIDMsIDQsIDUpIA0KTElTQTI8LSB0bV9zaGFwZShtdW5fbWVyZ2VfbmV3KSArIHRtX2ZpbGwoY29sID0gInF1YWRyYW50MiIsIGJyZWFrcyA9IGJyZWFrcywgcGFsZXR0ZT0gIGMoIndoaXRlIiwicmVkIiwiYmx1ZSIscmdiKDAsMCwxLGFscGhhPTAuNCkscmdiKDEsMCwwLGFscGhhPTAuNCkpLCBsYWJlbHMgPSBjKCJOb3Qgc2lnbmlmaWNhbnQiLCAiSGlnaC1IaWdoIiwiTG93LUxvdyIsIkxvdy1IaWdoIiwiSGlnaC1Mb3ciKSwgdGl0bGU9IiIpKw0KICB0bV9sZWdlbmQodGV4dC5zaXplID0gMSkgICsNCiAjIHRtX3NjYWxlX2Jhcihwb3NpdGlvbiA9IGMoIkxFRlQiLCAiQk9UVE9NIiksdGV4dC5zaXplID0gMS4wKSsNCiAgIyB0bV9jb21wYXNzKHR5cGUgPSAiOHN0YXIiLCAgIHBvc2l0aW9uID0gYygiUklHSFQiLCAiQk9UVE9NIiksICAgICAgc2hvdy5sYWJlbHMgPSAyLCAgIHRleHQuc2l6ZSA9IDAuNSkrDQogICAgdG1fYm9yZGVycyhhbHBoYT0uNSkgKw0KICAgdG1fbGF5b3V0KCBmcmFtZSA9IEZBTFNFLCB0aXRsZSA9ICJMSVNBIHdpdGggdGhlIEdFT0RBIHAtdmFsdWVzIikNCg0KdG1hcF9hcnJhbmdlKExJU0ExLCBMSVNBMikNCg0KYGBgDQoNCiMgY3JlYXRpbmcgYSBuaWNlciBtYXAgd2l0aCB0aGUgcCB2YWx1ZXMgb2YgR0VPREENCg0KYGBge3J9DQogdG1fc2hhcGUobXVuX21lcmdlX25ldykgKyB0bV9maWxsKGNvbCA9ICJxdWFkcmFudDIiLCBicmVha3MgPSBicmVha3MsIHBhbGV0dGU9ICBjKCJ3aGl0ZSIsInJlZCIsImJsdWUiLHJnYigwLDAsMSxhbHBoYT0wLjQpLHJnYigxLDAsMCxhbHBoYT0wLjQpKSwgbGFiZWxzID0gYygiTm90IHNpZ25pZmljYW50IiwgIkhpZ2gtSGlnaCIsIkxvdy1Mb3ciLCJMb3ctSGlnaCIsIkhpZ2gtTG93IiksIHRpdGxlPSIiKSsNCiAgdG1fbGVnZW5kKHRleHQuc2l6ZSA9IDEpICArDQogIyB0bV9zY2FsZV9iYXIocG9zaXRpb24gPSBjKCJMRUZUIiwgIkJPVFRPTSIpLHRleHQuc2l6ZSA9IDEuMCkrDQogICMgdG1fY29tcGFzcyh0eXBlID0gIjhzdGFyIiwgICBwb3NpdGlvbiA9IGMoIlJJR0hUIiwgIkJPVFRPTSIpLCAgICAgIHNob3cubGFiZWxzID0gMiwgICB0ZXh0LnNpemUgPSAwLjUpKw0KICAgIHRtX2JvcmRlcnMobHdkID0uMDUpICsNCiAgICB0bV9zaGFwZShwcm8uc3ApKw0KICB0bV9ib3JkZXJzKGx3ZD0zKSsNCiAgIHRtX2xheW91dCggZnJhbWUgPSBGQUxTRSwgdGl0bGUgPSAiTElTQSAoR0VPREEgcC12YWx1ZXMpIikNCnRtYXBfc2F2ZShmaWxlbmFtZSA9ICJBTkNfbGlzYS5wbmciLCBoZWlnaHQ9NSwgd2lkdGg9NSkNCg0KYGBgDQoNCg==