Main analysis results
if (file.exists(
"data_analysis/results/nsum_output/main/combined_data/df_models_nsum_long.rds"
)) {
load(file = "data_analysis/results/nsum_output/main/combined_data/df_models_nsum_long.rds")
} else {
list_files <-
as.list(
dir(
"data_analysis/results/nsum_output/main/model/",
full.names = T
)
)
#create loop lists
kds <- list()
kdssd <- list()
data <- list()
list_df <- list()
#loop to extract information
for (i in 1:length(list_files)) {
#i = 1
print(paste0("Number ", i, " of ", length(list_files)))
load(list_files[[i]])
kds[[i]] <-
rowMeans(degree$d.values, na.rm = TRUE) # calculate rowmean of netsize iterations: so the retained chains
kdssd[[i]] <-
matrixStats::rowSds(degree$d.values) # calculate sd of 4k estimates per row: sd for those values
data[[i]] <- cbind(kds[[i]], kdssd[[i]]) # combine them
list_df[[i]] <-
cbind(as_tibble(data[[i]]), nells_nsum$id) # add NELLS id variable
strings <-
str_split(str_extract(list_files[[i]][1], pattern = "estimates.+"),
pattern = "_") # add holdout number
list_df[[i]] <- list_df[[i]] %>%
mutate(
holdout = as.numeric(str_extract(strings[[1]][2], pattern = "[[:digit:]]{1,}")))
}
#combine results and save
df_models_nsum_long <- list_df %>%
bind_rows() %>%
rename(mean = V1,
sd = V2,
id = 3)
#save image
save(df_models_nsum_long, file = "data_analysis/results/nsum_output/main/combined_data/df_models_nsum_long.rds")
}
Holdout sensitivity analysis
In the estimation we need to set one of the known populations to
missing. We will now check how sensitive variables ommission is for the
network size estimate and see whether some groups are more sensitive to
this than others.
First of all, create a table of median, mean, and the SD of network
size for each unknown variable.
#create summary table
nsum_sum_long <- df_models_nsum_long %>%
mutate(Unknown = factor(
holdout,
levels = 1:16,
labels = c(
"Daan",
"Kevin",
"Edwin",
"Albert",
"Emma",
"Linda",
"Ingrid",
"Willemina",
"Ibrahim",
"Prison",
"MBO",
"HBO",
"University",
"Secundary education",
"Owns second home",
"Unemployed"
)
)) %>%
group_by(Unknown) %>%
summarise(
Mean = mean(mean),
Median = median(mean),
SD = mean(sd),
.groups = "drop"
)
nsum_sum_long %>%
kbl() %>%
kable_paper(full_width = F,
)
Unknown
|
Mean
|
Median
|
SD
|
Daan
|
935.0754
|
699.8811
|
337.5926
|
Kevin
|
969.7256
|
736.7016
|
351.2121
|
Edwin
|
1003.2393
|
766.4572
|
355.3362
|
Albert
|
1042.2279
|
788.9354
|
364.7517
|
Emma
|
960.7677
|
720.3704
|
340.0373
|
Linda
|
996.7474
|
765.4803
|
349.0902
|
Ingrid
|
1040.9216
|
800.1643
|
373.5502
|
Willemina
|
1023.1083
|
776.8069
|
361.9219
|
Ibrahim
|
803.5329
|
629.7463
|
265.5233
|
Prison
|
1035.6435
|
797.1834
|
369.2989
|
MBO
|
1025.8919
|
802.1888
|
352.6240
|
HBO
|
1035.5729
|
811.7983
|
358.5143
|
University
|
1018.8204
|
782.1697
|
349.7081
|
Secundary education
|
1034.6165
|
809.8754
|
361.0537
|
Owns second home
|
1025.6079
|
789.9623
|
357.7683
|
Unemployed
|
1034.3700
|
801.8969
|
363.9277
|
In mean network size there is realtively litte difference in the
different size estimates with different unkown populations. The
exception is when we set ibrahim to unknown, the mean and median size
drops marekdly. Also, the median of network sizes is more sensitive than
the mean network size. In the figure below, we show the differneces in
boxplot which shows a similar pciture. Overall, bar the exception of
Ibrahim, differences are small and neglible.
df_models_nsum_long %>%
mutate(ommitted = factor(
holdout,
levels = 1:16,
labels = c(
"Daan",
"Kevin",
"Edwin",
"Albert",
"Emma",
"Linda",
"Ingrid",
"Willemina",
"Ibrahim",
"Prison",
"MBO",
"HBO",
"University",
"Secundary education",
"Owns second home",
"Unemployed"
)
)) %>%
ggplot(aes(x = mean,
y = ommitted)) +
geom_boxplot(position = position_dodge(width = 1)) +
scale_fill_viridis_d(option = "D") +
scale_color_viridis_d(option = "D") +
theme_minimal() +
theme(legend.position = 'none',
#plot.background = element_rect(fill = '#404040', colour = '#404040'),
#panel.background = element_rect(fill = '#404040', colour = '#404040'),
axis.title.y = element_text(hjust = 1),
axis.title.x = element_text(hjust = 1),
text = element_text(colour = "black"),
strip.text = element_text(colour = "black")
) +
labs(y = "Unknown population",
x = "Extended network size",
title = "Fig.1: Network size estimates for different unknown populations")
This only showed differences at the aggregate level. We also want to
know whether these different size estimates are also robust on the
individual. For this reason we created a correlation plot which shows
the correlation between network size of the different unknown
populations. OVerall these seem reliable ( r > 0.85), however, we
find a discrepancy between names and categories. The within correlation
between these is larger (~95) than the between these groups (~85).
#create wide file for correlation plot
df_models_nsum_wide <- df_models_nsum_long %>%
mutate(Ommitted = factor(
holdout,
levels = 1:16,
labels = c(
"Daan",
"Kevin",
"Edwin",
"Albert",
"Emma",
"Linda",
"Ingrid",
"Willemina",
"Ibrahim",
"Prison",
"MBO",
"HBO",
"University",
"Secundary education",
"Owns second home",
"Unemployed"
)
)) %>%
arrange(id, Ommitted) %>%
select(-sd, -holdout) %>%
tidyr::pivot_wider(names_from = c(Ommitted),
values_from = c(mean))
#create correlation file
cor_df <- df_models_nsum_wide %>%
select(-id) %>%
select(!contains("sd")) %>%
cor() %>%
as_tibble() %>%
mutate(variable_x = factor(1:16,
levels = 1:16,
labels = c(
"Daan",
"Kevin",
"Edwin",
"Albert",
"Emma",
"Linda",
"Ingrid",
"Willemina",
"Ibrahim",
"Prison",
"MBO",
"HBO",
"University",
"Secundary education",
"Owns second home",
"Unemployed"
))) %>%
tidyr::pivot_longer(1:16,
names_to = "variable_y",
values_to = "value") %>%
mutate(variable_y = fct_relevel(variable_y,
c(
"Daan",
"Kevin",
"Edwin",
"Albert",
"Emma",
"Linda",
"Ingrid",
"Willemina",
"Ibrahim",
"Prison",
"MBO",
"HBO",
"University",
"Secundary education",
"Owns second home",
"Unemployed"
)))
#correlation plot
cor_df %>%
ggplot(aes(x = variable_x, y = variable_y, fill = value)) +
geom_tile(alpha = 0.5) +
geom_text(aes(label = round(value, 2))) +
theme_minimal() +
scale_fill_viridis(option = "D") +
theme(axis.text.x = element_text(angle = 45,
vjust = 0.4),
#plot.background = element_rect(fill = "#D4D9DE", colour = "#D4D9DE"),
#panel.background = element_rect(fill ="#D4D9DE", colour = "#D4D9DE"),
axis.title.y = element_text(hjust = 1),
axis.title.x = element_text(hjust = 1),
text = element_text(colour = "black"),
strip.text = element_text(colour = "black")
) +
labs(x = "Unknown population",
y = "Unknown population",
title = "Fig.2: Correlations between network size estimates from models with different unknown populations")
Since we are interested in group differences in network size, we
would want to know whether groups differ in their sensitivity to
different specifications of the main NSUM model. Based on the figure
presented below, there are no major group differences bar Ibrahim.
nells_test_df <- df_models_nsum_long %>%
left_join(nells_nsum)
nells_test_df %>%
mutate(ommitted = factor(holdout,
levels = 1:16,
labels = c(
"Daan",
"Kevin",
"Edwin",
"Albert",
"Emma",
"Linda",
"Ingrid",
"Willemina",
"Ibrahim",
"Prison",
"MBO",
"HBO",
"University",
"Secundary education",
"Owns second home",
"Unemployed"
))) %>%
ggplot(aes(x = mean,
y = ommitted,
color = migration_background_fac)) +
geom_boxplot(position = position_dodge(width = 1)
#,
#fill = "#D4D9DE"
) +
facet_wrap(vars(migration_background_fac)) +
scale_fill_viridis_d(option = "D") +
scale_color_viridis_d(option = "D") +
theme_minimal() +
theme(legend.position = 'none',
#plot.background = element_rect(fill = "#D4D9DE", colour = "#D4D9DE"),
#panel.background = element_rect(fill ="#D4D9DE", colour = "#D4D9DE"),
axis.title.y = element_text(hjust = 1),
axis.title.x = element_text(hjust = 1),
text = element_text(colour = "black"),
strip.text = element_text(colour = "black")
) +
labs(y = "Unknown population",
x = "Extended network size",
title = "Fig.3: Group differences in sensitivy to different unknown populations")
LS0tDQp0aXRsZTogIlNpemUgUm9idXN0bmVzcyBBbmFseXNpcyINCmF1dGhvcjogIlRoaWptZW4gSmVyb2Vuc2UiDQpkYXRlOiAiTGFzdCBjb21waWxlZCBvbiBgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkICVCLCAlWScpYCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IFRSVUUNCiAgICB0b2NfZGVwdGg6IDMNCiAgICB0b2NfZmxvYXQ6IFRSVUUNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFDQotLS0NCg0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChjYWNoZSA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCByZXN1bHRzID0gImFzaXMiLA0KICAgICAgICAgICAgICAgICAgICAgIGZpZy5hbGlnbiA9ICJjZW50ZXIiKQ0KYGBgDQoNCiMgUHJlcGFyaW5nIGRhdGENCg0KTGlicmFyaWVzDQoNCmBgYHtyIGxpYnJhcmllcyBhbmQgZmlsZXMsIHJlc3VsdHM9J2hpZGUnfQ0KZnBhY2thZ2UuY2hlY2sgPC0gZnVuY3Rpb24ocGFja2FnZXMpIHsgIyAoYykgSm9jaGVtIFRvbHNtYQ0KICBsYXBwbHkocGFja2FnZXMsIEZVTiA9IGZ1bmN0aW9uKHgpIHsNCiAgICBpZiAoIXJlcXVpcmUoeCwgY2hhcmFjdGVyLm9ubHkgPSBUUlVFKSkgew0KICAgICAgaW5zdGFsbC5wYWNrYWdlcyh4LCBkZXBlbmRlbmNpZXMgPSBUUlVFKQ0KICAgICAgbGlicmFyeSh4LCBjaGFyYWN0ZXIub25seSA9IFRSVUUpDQogICAgfQ0KICB9KQ0KfQ0KcGFja2FnZXMgPSBjKCJ0aWR5dmVyc2UiLCAidmlyaWRpcyIsICJrYWJsZUV4dHJhIiwiZ2dyaWRnZXMiLCAidmlyaWRpcyIsICJnZ2RhcmsiLCAiZ2dwbG90MiIsICJwYXRjaHdvcmsiLCAic2pQbG90IikNCmZwYWNrYWdlLmNoZWNrKHBhY2thZ2VzKQ0KYGBgDQoNCkltcG9ydCB0aGUgTlNVTSBkYXRhIGFuZCByZWNyZWF0ZSB0aGUgTlNVTSBtb2R1bGUuIA0KDQpgYGB7ciBmaWxlc30NCiNpbXBvcnQgbmVsbHMgZmlsZS4NCmxvYWQoZmlsZSA9ICJkYXRhX2FuYWx5c2lzL2RhdGEvZGF0YV9wcm9jZXNzZWQvbmVsbHNfZGF0YS8yMDIyLTExLTA5X25lbGxzLW5zdW0tcHJlcHBlZC1kYXRhLnJkcyIpDQoNCmBgYA0KDQpJbXBvcnQgdGhlIG1vZGVsIGVzdGltYXRlcyBmcm9tIHRoZSBlc3RpbWF0ZWQgTlNVTSBtb2RlbHMuIEkgaGF2ZSBjaG9vc2VuIHRoZSBtb2RlbCB3aGljaCB1c2VzIElicmFoaW0gZm9yIHRoZSBldGhuaWMgbmFtZXMuDQoNCiMgTWFpbiBhbmFseXNpcyByZXN1bHRzDQpgYGB7ciBpbXBvcnQgcmVzdWx0cywgcmVzdWx0cz0naGlkZSd9DQoNCmlmIChmaWxlLmV4aXN0cygNCiAgImRhdGFfYW5hbHlzaXMvcmVzdWx0cy9uc3VtX291dHB1dC9tYWluL2NvbWJpbmVkX2RhdGEvZGZfbW9kZWxzX25zdW1fbG9uZy5yZHMiDQopKSB7DQogIGxvYWQoZmlsZSA9ICJkYXRhX2FuYWx5c2lzL3Jlc3VsdHMvbnN1bV9vdXRwdXQvbWFpbi9jb21iaW5lZF9kYXRhL2RmX21vZGVsc19uc3VtX2xvbmcucmRzIikNCn0gZWxzZSB7DQogIGxpc3RfZmlsZXMgPC0NCiAgICBhcy5saXN0KA0KICAgICAgZGlyKA0KICAgICAgICAiZGF0YV9hbmFseXNpcy9yZXN1bHRzL25zdW1fb3V0cHV0L21haW4vbW9kZWwvIiwNCiAgICAgICAgZnVsbC5uYW1lcyA9IFQNCiAgICAgICkNCiAgICApDQogICNjcmVhdGUgbG9vcCBsaXN0cw0KICBrZHMgPC0gbGlzdCgpDQogIGtkc3NkIDwtIGxpc3QoKQ0KICBkYXRhIDwtIGxpc3QoKQ0KICBsaXN0X2RmIDwtIGxpc3QoKQ0KICANCiAgI2xvb3AgdG8gZXh0cmFjdCBpbmZvcm1hdGlvbg0KICBmb3IgKGkgaW4gMTpsZW5ndGgobGlzdF9maWxlcykpIHsNCiAgICAjaSA9IDENCiAgICBwcmludChwYXN0ZTAoIk51bWJlciAiLCBpLCAiIG9mICIsIGxlbmd0aChsaXN0X2ZpbGVzKSkpDQogICAgbG9hZChsaXN0X2ZpbGVzW1tpXV0pDQogICAga2RzW1tpXV0gPC0NCiAgICAgIHJvd01lYW5zKGRlZ3JlZSRkLnZhbHVlcywgbmEucm0gPSBUUlVFKSAjIGNhbGN1bGF0ZSByb3dtZWFuIG9mIG5ldHNpemUgaXRlcmF0aW9uczogc28gdGhlIHJldGFpbmVkIGNoYWlucw0KICAgIGtkc3NkW1tpXV0gPC0NCiAgICAgIG1hdHJpeFN0YXRzOjpyb3dTZHMoZGVncmVlJGQudmFsdWVzKSAjIGNhbGN1bGF0ZSBzZCBvZiA0ayBlc3RpbWF0ZXMgcGVyIHJvdzogc2QgZm9yIHRob3NlIHZhbHVlcw0KICAgIGRhdGFbW2ldXSA8LSBjYmluZChrZHNbW2ldXSwga2Rzc2RbW2ldXSkgIyBjb21iaW5lIHRoZW0NCiAgICBsaXN0X2RmW1tpXV0gPC0NCiAgICAgIGNiaW5kKGFzX3RpYmJsZShkYXRhW1tpXV0pLCBuZWxsc19uc3VtJGlkKSAjIGFkZCBORUxMUyBpZCB2YXJpYWJsZQ0KICAgIHN0cmluZ3MgPC0NCiAgICAgIHN0cl9zcGxpdChzdHJfZXh0cmFjdChsaXN0X2ZpbGVzW1tpXV1bMV0sIHBhdHRlcm4gPSAiZXN0aW1hdGVzLisiKSwNCiAgICAgICAgICAgICAgICBwYXR0ZXJuID0gIl8iKSAgIyBhZGQgaG9sZG91dCBudW1iZXINCiAgICBsaXN0X2RmW1tpXV0gPC0gbGlzdF9kZltbaV1dICU+JQ0KICAgICAgbXV0YXRlKA0KICAgICAgICBob2xkb3V0ID0gYXMubnVtZXJpYyhzdHJfZXh0cmFjdChzdHJpbmdzW1sxXV1bMl0sIHBhdHRlcm4gPSAiW1s6ZGlnaXQ6XV17MSx9IikpKQ0KICB9DQogICAgI2NvbWJpbmUgcmVzdWx0cyBhbmQgc2F2ZQ0KICAgIGRmX21vZGVsc19uc3VtX2xvbmcgPC0gbGlzdF9kZiAlPiUNCiAgICAgIGJpbmRfcm93cygpICU+JQ0KICAgICAgcmVuYW1lKG1lYW4gPSBWMSwNCiAgICAgICAgICAgICBzZCA9IFYyLA0KICAgICAgICAgICAgIGlkID0gMykNCiAgICAjc2F2ZSBpbWFnZQ0KICAgIHNhdmUoZGZfbW9kZWxzX25zdW1fbG9uZywgZmlsZSA9ICJkYXRhX2FuYWx5c2lzL3Jlc3VsdHMvbnN1bV9vdXRwdXQvbWFpbi9jb21iaW5lZF9kYXRhL2RmX21vZGVsc19uc3VtX2xvbmcucmRzIikNCn0NCmBgYA0KDQoNCiMgSG9sZG91dCBzZW5zaXRpdml0eSBhbmFseXNpcw0KDQpJbiB0aGUgZXN0aW1hdGlvbiB3ZSBuZWVkIHRvIHNldCBvbmUgb2YgdGhlIGtub3duIHBvcHVsYXRpb25zIHRvIG1pc3NpbmcuIFdlIHdpbGwgbm93IGNoZWNrIGhvdyBzZW5zaXRpdmUgdmFyaWFibGVzIG9tbWlzc2lvbiBpcyBmb3IgdGhlIG5ldHdvcmsgc2l6ZSBlc3RpbWF0ZSBhbmQgc2VlIHdoZXRoZXIgc29tZSBncm91cHMgYXJlIG1vcmUgc2Vuc2l0aXZlIHRvIHRoaXMgdGhhbiBvdGhlcnMuIA0KDQpGaXJzdCBvZiBhbGwsIGNyZWF0ZSBhIHRhYmxlIG9mIG1lZGlhbiwgbWVhbiwgYW5kIHRoZSBTRCBvZiBuZXR3b3JrIHNpemUgZm9yIGVhY2ggdW5rbm93biB2YXJpYWJsZS4gDQoNCmBgYHtyIFVua25vd24gdGFibGV9DQojY3JlYXRlIHN1bW1hcnkgdGFibGUNCm5zdW1fc3VtX2xvbmcgPC0gZGZfbW9kZWxzX25zdW1fbG9uZyAlPiUNCiAgbXV0YXRlKFVua25vd24gPSBmYWN0b3IoDQogICAgaG9sZG91dCwNCiAgICBsZXZlbHMgPSAxOjE2LA0KICAgIGxhYmVscyA9IGMoDQogICAgICAiRGFhbiIsDQogICAgICAiS2V2aW4iLA0KICAgICAgIkVkd2luIiwNCiAgICAgICJBbGJlcnQiLA0KICAgICAgIkVtbWEiLA0KICAgICAgIkxpbmRhIiwNCiAgICAgICJJbmdyaWQiLA0KICAgICAgIldpbGxlbWluYSIsDQogICAgICAiSWJyYWhpbSIsDQogICAgICAiUHJpc29uIiwNCiAgICAgICJNQk8iLA0KICAgICAgIkhCTyIsDQogICAgICAiVW5pdmVyc2l0eSIsDQogICAgICAiU2VjdW5kYXJ5IGVkdWNhdGlvbiIsDQogICAgICAiT3ducyBzZWNvbmQgaG9tZSIsDQogICAgICAiVW5lbXBsb3llZCINCiAgICApDQogICkpICU+JQ0KICBncm91cF9ieShVbmtub3duKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIE1lYW4gPSBtZWFuKG1lYW4pLA0KICAgIE1lZGlhbiA9IG1lZGlhbihtZWFuKSwNCiAgICBTRCA9IG1lYW4oc2QpLA0KICAgIC5ncm91cHMgPSAiZHJvcCINCiAgKQ0KDQpuc3VtX3N1bV9sb25nICU+JSANCiAga2JsKCkgJT4lIA0KICBrYWJsZV9wYXBlcihmdWxsX3dpZHRoID0gRiwNCiAgICAgICAgICAgICAgKQ0KYGBgDQpJbiBtZWFuIG5ldHdvcmsgc2l6ZSB0aGVyZSBpcyByZWFsdGl2ZWx5IGxpdHRlIGRpZmZlcmVuY2UgaW4gdGhlIGRpZmZlcmVudCBzaXplIGVzdGltYXRlcyB3aXRoIGRpZmZlcmVudCB1bmtvd24gcG9wdWxhdGlvbnMuIFRoZSBleGNlcHRpb24gaXMgd2hlbiB3ZSBzZXQgaWJyYWhpbSB0byB1bmtub3duLCB0aGUgbWVhbiBhbmQgbWVkaWFuIHNpemUgZHJvcHMgbWFyZWtkbHkuIEFsc28sIHRoZSBtZWRpYW4gb2YgbmV0d29yayBzaXplcyBpcyBtb3JlIHNlbnNpdGl2ZSB0aGFuIHRoZSBtZWFuIG5ldHdvcmsgc2l6ZS4gSW4gdGhlIGZpZ3VyZSBiZWxvdywgd2Ugc2hvdyB0aGUgZGlmZmVybmVjZXMgaW4gYm94cGxvdCB3aGljaCBzaG93cyBhIHNpbWlsYXIgcGNpdHVyZS4gT3ZlcmFsbCwgYmFyIHRoZSBleGNlcHRpb24gb2YgSWJyYWhpbSwgZGlmZmVyZW5jZXMgYXJlIHNtYWxsIGFuZCBuZWdsaWJsZS4gIA0KDQpgYGB7ciBVbmtub3duIHN1bSBncmFwaH0NCmRmX21vZGVsc19uc3VtX2xvbmcgJT4lDQogIG11dGF0ZShvbW1pdHRlZCA9IGZhY3RvcigNCiAgICBob2xkb3V0LA0KICAgIGxldmVscyA9IDE6MTYsDQogICAgbGFiZWxzID0gYygNCiAgICAgICJEYWFuIiwNCiAgICAgICJLZXZpbiIsDQogICAgICAiRWR3aW4iLA0KICAgICAgIkFsYmVydCIsDQogICAgICAiRW1tYSIsDQogICAgICAiTGluZGEiLA0KICAgICAgIkluZ3JpZCIsDQogICAgICAiV2lsbGVtaW5hIiwNCiAgICAgICJJYnJhaGltIiwNCiAgICAgICJQcmlzb24iLA0KICAgICAgIk1CTyIsDQogICAgICAiSEJPIiwNCiAgICAgICJVbml2ZXJzaXR5IiwNCiAgICAgICJTZWN1bmRhcnkgZWR1Y2F0aW9uIiwNCiAgICAgICJPd25zIHNlY29uZCBob21lIiwNCiAgICAgICJVbmVtcGxveWVkIg0KICAgICkNCiAgKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBtZWFuLA0KICAgICAgICAgICAgIHkgPSBvbW1pdHRlZCkpICsNCiAgZ2VvbV9ib3hwbG90KHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAxKSkgKyANCiAgc2NhbGVfZmlsbF92aXJpZGlzX2Qob3B0aW9uID0gIkQiKSArDQogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAiRCIpICsgDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJywNCiAgICAgICAgI3Bsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gJyM0MDQwNDAnLCBjb2xvdXIgPSAnIzQwNDA0MCcpLA0KICAgICAgICAjcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gJyM0MDQwNDAnLCBjb2xvdXIgPSAnIzQwNDA0MCcpLA0KICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAxKSwNCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMSksDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoY29sb3VyID0gImJsYWNrIiksDQogICAgICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3VyID0gImJsYWNrIikNCiAgICAgICAgKSArDQogIGxhYnMoeSA9ICJVbmtub3duIHBvcHVsYXRpb24iLA0KICAgICAgIHggPSAiRXh0ZW5kZWQgbmV0d29yayBzaXplIiwNCiAgICAgICB0aXRsZSA9ICJGaWcuMTogTmV0d29yayBzaXplIGVzdGltYXRlcyBmb3IgZGlmZmVyZW50IHVua25vd24gcG9wdWxhdGlvbnMiKQ0KDQoNCmBgYA0KVGhpcyBvbmx5IHNob3dlZCBkaWZmZXJlbmNlcyBhdCB0aGUgYWdncmVnYXRlIGxldmVsLiBXZSBhbHNvIHdhbnQgdG8ga25vdyB3aGV0aGVyIHRoZXNlIGRpZmZlcmVudCBzaXplIGVzdGltYXRlcyBhcmUgYWxzbyByb2J1c3Qgb24gdGhlIGluZGl2aWR1YWwuIEZvciB0aGlzIHJlYXNvbiB3ZSBjcmVhdGVkIGEgY29ycmVsYXRpb24gcGxvdCB3aGljaCBzaG93cyB0aGUgY29ycmVsYXRpb24gYmV0d2VlbiBuZXR3b3JrIHNpemUgb2YgdGhlIGRpZmZlcmVudCB1bmtub3duIHBvcHVsYXRpb25zLiBPVmVyYWxsIHRoZXNlIHNlZW0gcmVsaWFibGUgKCByID4gMC44NSksIGhvd2V2ZXIsIHdlIGZpbmQgYSBkaXNjcmVwYW5jeSBiZXR3ZWVuIG5hbWVzIGFuZCBjYXRlZ29yaWVzLiBUaGUgd2l0aGluIGNvcnJlbGF0aW9uIGJldHdlZW4gdGhlc2UgaXMgbGFyZ2VyICh+OTUpIHRoYW4gdGhlIGJldHdlZW4gdGhlc2UgZ3JvdXBzICh+ODUpLg0KDQpgYGB7ciBjb3JyIHBsb3QsIGZpZy5oZWlnaHQgPSAxMCwgZmlnLndpZHRoID0gMTAsIGZpZy5hbGlnbiA9ICJjZW50ZXIifQ0KI2NyZWF0ZSB3aWRlIGZpbGUgZm9yIGNvcnJlbGF0aW9uIHBsb3QNCmRmX21vZGVsc19uc3VtX3dpZGUgPC0gZGZfbW9kZWxzX25zdW1fbG9uZyAlPiUgDQogIG11dGF0ZShPbW1pdHRlZCA9IGZhY3RvcigNCiAgICBob2xkb3V0LA0KICAgIGxldmVscyA9IDE6MTYsDQogICAgbGFiZWxzID0gYygNCiAgICAgICJEYWFuIiwNCiAgICAgICJLZXZpbiIsDQogICAgICAiRWR3aW4iLA0KICAgICAgIkFsYmVydCIsDQogICAgICAiRW1tYSIsDQogICAgICAiTGluZGEiLA0KICAgICAgIkluZ3JpZCIsDQogICAgICAiV2lsbGVtaW5hIiwNCiAgICAgICJJYnJhaGltIiwNCiAgICAgICJQcmlzb24iLA0KICAgICAgIk1CTyIsDQogICAgICAiSEJPIiwNCiAgICAgICJVbml2ZXJzaXR5IiwNCiAgICAgICJTZWN1bmRhcnkgZWR1Y2F0aW9uIiwNCiAgICAgICJPd25zIHNlY29uZCBob21lIiwNCiAgICAgICJVbmVtcGxveWVkIg0KICAgICkNCiAgKSkgJT4lIA0KICBhcnJhbmdlKGlkLCBPbW1pdHRlZCkgJT4lIA0KICBzZWxlY3QoLXNkLCAtaG9sZG91dCkgJT4lIA0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IGMoT21taXR0ZWQpLA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IGMobWVhbikpIA0KDQojY3JlYXRlIGNvcnJlbGF0aW9uIGZpbGUNCmNvcl9kZiA8LSBkZl9tb2RlbHNfbnN1bV93aWRlICU+JSANCiAgc2VsZWN0KC1pZCkgJT4lIA0KICBzZWxlY3QoIWNvbnRhaW5zKCJzZCIpKSAlPiUgDQogIGNvcigpICU+JSANCiAgYXNfdGliYmxlKCkgJT4lIA0KICBtdXRhdGUodmFyaWFibGVfeCA9IGZhY3RvcigxOjE2LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSAxOjE2LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKA0KICAgICAgIkRhYW4iLA0KICAgICAgIktldmluIiwNCiAgICAgICJFZHdpbiIsDQogICAgICAiQWxiZXJ0IiwNCiAgICAgICJFbW1hIiwNCiAgICAgICJMaW5kYSIsDQogICAgICAiSW5ncmlkIiwNCiAgICAgICJXaWxsZW1pbmEiLA0KICAgICAgIklicmFoaW0iLA0KICAgICAgIlByaXNvbiIsDQogICAgICAiTUJPIiwNCiAgICAgICJIQk8iLA0KICAgICAgIlVuaXZlcnNpdHkiLA0KICAgICAgIlNlY3VuZGFyeSBlZHVjYXRpb24iLA0KICAgICAgIk93bnMgc2Vjb25kIGhvbWUiLA0KICAgICAgIlVuZW1wbG95ZWQiDQogICAgKSkpICU+JSANCiAgdGlkeXI6OnBpdm90X2xvbmdlcigxOjE2LA0KICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAidmFyaWFibGVfeSIsDQogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidmFsdWUiKSAgJT4lIA0KICBtdXRhdGUodmFyaWFibGVfeSA9IGZjdF9yZWxldmVsKHZhcmlhYmxlX3ksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYygNCiAgICAgICJEYWFuIiwNCiAgICAgICJLZXZpbiIsDQogICAgICAiRWR3aW4iLA0KICAgICAgIkFsYmVydCIsDQogICAgICAiRW1tYSIsDQogICAgICAiTGluZGEiLA0KICAgICAgIkluZ3JpZCIsDQogICAgICAiV2lsbGVtaW5hIiwNCiAgICAgICJJYnJhaGltIiwNCiAgICAgICJQcmlzb24iLA0KICAgICAgIk1CTyIsDQogICAgICAiSEJPIiwNCiAgICAgICJVbml2ZXJzaXR5IiwNCiAgICAgICJTZWN1bmRhcnkgZWR1Y2F0aW9uIiwNCiAgICAgICJPd25zIHNlY29uZCBob21lIiwNCiAgICAgICJVbmVtcGxveWVkIg0KICAgICkpKQ0KDQojY29ycmVsYXRpb24gcGxvdA0KY29yX2RmICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gdmFyaWFibGVfeCwgeSA9IHZhcmlhYmxlX3ksIGZpbGwgPSB2YWx1ZSkpICsNCiAgZ2VvbV90aWxlKGFscGhhID0gMC41KSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZCh2YWx1ZSwgMikpKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHNjYWxlX2ZpbGxfdmlyaWRpcyhvcHRpb24gPSAiRCIpICsgDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZqdXN0ID0gMC40KSwNCiAgICAgICAgI3Bsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNENEQ5REUiLCBjb2xvdXIgPSAiI0Q0RDlERSIpLA0KICAgICAgICAjcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0iI0Q0RDlERSIsIGNvbG91ciA9ICIjRDREOURFIiksDQogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDEpLA0KICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAxKSwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSAiYmxhY2siKSwNCiAgICAgICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSAiYmxhY2siKQ0KICAgICAgICApICsNCiAgbGFicyh4ID0gIlVua25vd24gcG9wdWxhdGlvbiIsDQogICAgICAgeSA9ICJVbmtub3duIHBvcHVsYXRpb24iLA0KICAgICAgIHRpdGxlID0gIkZpZy4yOiBDb3JyZWxhdGlvbnMgYmV0d2VlbiBuZXR3b3JrIHNpemUgZXN0aW1hdGVzIGZyb20gbW9kZWxzIHdpdGggZGlmZmVyZW50IHVua25vd24gcG9wdWxhdGlvbnMiKQ0KYGBgDQoNClNpbmNlIHdlIGFyZSBpbnRlcmVzdGVkIGluIGdyb3VwIGRpZmZlcmVuY2VzIGluIG5ldHdvcmsgc2l6ZSwgd2Ugd291bGQgd2FudCB0byBrbm93IHdoZXRoZXIgZ3JvdXBzIGRpZmZlciBpbiB0aGVpciBzZW5zaXRpdml0eSB0byBkaWZmZXJlbnQgc3BlY2lmaWNhdGlvbnMgb2YgdGhlIG1haW4gTlNVTSBtb2RlbC4gQmFzZWQgb24gdGhlIGZpZ3VyZSBwcmVzZW50ZWQgYmVsb3csIHRoZXJlIGFyZSBubyBtYWpvciBncm91cCBkaWZmZXJlbmNlcyBiYXIgSWJyYWhpbS4gDQoNCmBgYHtyIGhvbGRvdXQgMiwgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9N30NCm5lbGxzX3Rlc3RfZGYgPC0gZGZfbW9kZWxzX25zdW1fbG9uZyAlPiUgDQogIGxlZnRfam9pbihuZWxsc19uc3VtKSANCg0KbmVsbHNfdGVzdF9kZiAlPiUgDQogIG11dGF0ZShvbW1pdHRlZCA9IGZhY3Rvcihob2xkb3V0LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gMToxNiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygNCiAgICAgICJEYWFuIiwNCiAgICAgICJLZXZpbiIsDQogICAgICAiRWR3aW4iLA0KICAgICAgIkFsYmVydCIsDQogICAgICAiRW1tYSIsDQogICAgICAiTGluZGEiLA0KICAgICAgIkluZ3JpZCIsDQogICAgICAiV2lsbGVtaW5hIiwNCiAgICAgICJJYnJhaGltIiwNCiAgICAgICJQcmlzb24iLA0KICAgICAgIk1CTyIsDQogICAgICAiSEJPIiwNCiAgICAgICJVbml2ZXJzaXR5IiwNCiAgICAgICJTZWN1bmRhcnkgZWR1Y2F0aW9uIiwNCiAgICAgICJPd25zIHNlY29uZCBob21lIiwNCiAgICAgICJVbmVtcGxveWVkIg0KICAgICkpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1lYW4sDQogICAgICAgICAgICAgeSA9IG9tbWl0dGVkLA0KICAgICAgICAgICAgIGNvbG9yID0gbWlncmF0aW9uX2JhY2tncm91bmRfZmFjKSkgKw0KICBnZW9tX2JveHBsb3QocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDEpDQogICAgICAgICAgICAgICAjLA0KICAgICAgICAgICAgICAgI2ZpbGwgPSAiI0Q0RDlERSINCiAgICAgICAgICAgICAgICkgKw0KICBmYWNldF93cmFwKHZhcnMobWlncmF0aW9uX2JhY2tncm91bmRfZmFjKSkgKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfZChvcHRpb24gPSAiRCIpICsNCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJEIikgKyANCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnLA0KICAgICAgICAjcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0Q0RDlERSIsIGNvbG91ciA9ICIjRDREOURFIiksDQogICAgICAgICNwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSIjRDREOURFIiwgY29sb3VyID0gIiNENEQ5REUiKSwNCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMSksDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDEpLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICJibGFjayIpLA0KICAgICAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICJibGFjayIpDQogICAgICAgICkgKw0KICBsYWJzKHkgPSAiVW5rbm93biBwb3B1bGF0aW9uIiwNCiAgICAgICB4ID0gIkV4dGVuZGVkIG5ldHdvcmsgc2l6ZSIsDQogICAgICAgdGl0bGUgPSAiRmlnLjM6IEdyb3VwIGRpZmZlcmVuY2VzIGluIHNlbnNpdGl2eSB0byBkaWZmZXJlbnQgdW5rbm93biBwb3B1bGF0aW9ucyIpDQoNCmBgYA0KDQoNCg0K