Experimental
conditions
# pick one configuration that likely leads to an unpopular norm, and explore multiple 'seeds':
run_one_seed <- function(
i,
base_seed = 12532812,
params = list(s = 15, e = 10, w = 40, z = 50, lambda1 = 5, lambda2 = 1.8),
# tweak network
k_min = 3,
k_max = 15,
alpha = 2.4,
rho = 0.4,
r = -0.1,
# retrieve network
return_network = FALSE
) {
# derived seed for this run
seed_i <- base_seed + i
set.seed(seed_i)
# --- network creation ---
degseq <- fdegseq(
n = 20,
alpha = alpha,
k_min = k_min,
k_max = k_max,
dist = "log-normal", #use log-normal
seed = seed_i
)
network <- sample_degseq(degseq, method = "vl")
V(network)$role <- sample(
c(rep("trendsetter", 3), rep("conformist", 17))
)
rewired_network <- frewire_r(network, r, verbose = FALSE, max_iter = 1e5)
final_network <- fswap_rho(rewired_network, rho, verbose = FALSE, max_iter = 1e4)
# --- stats ---
stats <- list(
run = i,
seed = seed_i,
num_nodes = vcount(final_network),
num_edges = ecount(final_network),
avg_degree = mean(degree(final_network)),
sd_degree = sd(degree(final_network)),
net_density = edge_density(final_network),
net_diameter = diameter(final_network, directed = FALSE, unconnected = TRUE),
avg_path_len = average.path.length(final_network, directed = FALSE),
clust_coeff = transitivity(final_network, type = "global"),
assort_deg = assortativity_degree(final_network),
deg_trait_cor = fdegtraitcor(final_network)$cor,
components = components(final_network)$no
)
fplot_graph(final_network, layout = layout_with_fr(final_network))
# --- initial actions ---
V(final_network)$action <- ifelse(V(final_network)$role == "trendsetter", 1, 0)
# --- deterministic simulation ---
sim_det <- fabm(
network = final_network,
params = params,
max_rounds = 35,
mi_threshold = 0.49,
choice_rule = "deterministic",
plot = TRUE,
histories = TRUE
)
# generate the gif for the current network
gif_filename <- paste0("./figures/animation_network_", seed_i, ".gif")
gif_path <- fnetworkgif(final_network, sim_det$decision_history, rounds = sim_det$equilibrium$round, output_dir = "./figures")
# rename the gif to match the naming pattern
file.rename(gif_path, gif_filename)
if (!is.null(sim_det$plot)) {
print(sim_det$plot)
}
# --- probabilistic simulation ---
sim_prob <- fabm(
network = final_network,
params = params,
max_rounds = 50,
mi_threshold = 0.49,
choice_rule = "probabilistic",
stable_window = 8, # the length of the window of adoption values
required_stable_rounds = 20, # number of windows needed to declare equilibrium
plot = TRUE
)
if (!is.null(sim_prob$plot)) {
print(sim_prob$plot)
}
result <- list(
segregation_det = sim_det$equilibrium$segregation,
segregation_prob = sim_prob$equilibrium$segregation,
stats = stats
)
if (return_network) {
result$network <- final_network
}
result
}
#and one "random" network
run_one_sw <- function(
i,
base_seed = 12532812,
model = "watts-strogatz",
beta = 0,
nei = 3,
clique_size = 5,
pmin = 0.1,
params = list(s = 15, e = 10, w = 40, z = 50, lambda1 = 5, lambda2 = 1.8),
# retrieve network
return_network = FALSE
) {
# derived seed for this run
seed_i <- base_seed + i
set.seed(seed_i)
if (model == "watts-strogatz") {
network <- sample_smallworld(dim = 1, size = 20, nei = 3, p = beta) }
else if (model == "caveman") {
network <- simulate_caveman(n = 20, clique_size = clique_size)
}
V(network)$role <- sample(
c(rep("trendsetter", 3), rep("conformist", 17))
)
final_network <- network
# --- stats ---
stats <- list(
run = i,
seed = seed_i,
num_nodes = vcount(final_network),
num_edges = ecount(final_network),
avg_degree = mean(degree(final_network)),
sd_degree = sd(degree(final_network)),
net_density = edge_density(final_network),
net_diameter = diameter(final_network, directed = FALSE, unconnected = TRUE),
avg_path_len = average.path.length(final_network, directed = FALSE),
clust_coeff = transitivity(final_network, type = "global"),
assort_deg = assortativity_degree(final_network),
deg_trait_cor = fdegtraitcor(final_network)$cor,
components = components(final_network)$no
)
stats_df <- data.frame(
Metric = names(stats),
Value = unlist(stats),
row.names = NULL
)
#print(stats_df)
fplot_graph(final_network, layout = layout.kamada.kawai(final_network))
# --- initial actions ---
V(final_network)$action <- ifelse(V(final_network)$role == "trendsetter", 1, 0)
# --- deterministic simulation ---
sim_det <- fabm(
network = final_network,
params = params,
max_rounds = 35,
mi_threshold = 0.49,
choice_rule = "deterministic",
plot = TRUE,
histories = TRUE
)
# generate the gif for the current network
gif_filename <- paste0("./figures/animation_network_", seed_i, ".gif")
gif_path <- fnetworkgif(final_network, sim_det$decision_history, rounds = sim_det$equilibrium$round, output_dir = "./figures")
# rename the gif to match the naming pattern
file.rename(gif_path, gif_filename)
if (!is.null(sim_det$plot)) {
print(sim_det$plot)
}
# --- probabilistic simulation ---
sim_prob <- fabm(
network = final_network,
params = params,
max_rounds = 50,
mi_threshold = 0.49,
choice_rule = "probabilistic",
stable_window = 8, # the length of the window of adoption values
required_stable_rounds = 20, # number of windows needed to declare equilibrium
plot = TRUE
)
if (!is.null(sim_prob$plot)) {
print(sim_prob$plot)
}
result <- list(
segregation_det = sim_det$equilibrium$segregation,
segregation_prob = sim_prob$equilibrium$segregation,
stats = stats
)
if (return_network) {
result$network <- final_network
}
result
}
SRDA computer-lab
demonstation
WG1: heterogenous
degree distribution; centralized “fanatics”:
test <- run_one_seed(38, k_min = 4, k_max = 16, alpha = 2.3, rho = 1, r = -0.2, return_network = TRUE)



table(degree(test$network))
#>
#> 4 5 6 8 9 16
#> 12 1 1 1 3 2
cbind(degree(test$network), V(test$network)$role)
#> [,1] [,2]
#> [1,] "4" "conformist"
#> [2,] "16" "trendsetter"
#> [3,] "4" "conformist"
#> [4,] "4" "conformist"
#> [5,] "4" "conformist"
#> [6,] "4" "conformist"
#> [7,] "4" "conformist"
#> [8,] "5" "conformist"
#> [9,] "16" "trendsetter"
#> [10,] "9" "conformist"
#> [11,] "9" "trendsetter"
#> [12,] "8" "conformist"
#> [13,] "4" "conformist"
#> [14,] "4" "conformist"
#> [15,] "4" "conformist"
#> [16,] "6" "conformist"
#> [17,] "4" "conformist"
#> [18,] "9" "conformist"
#> [19,] "4" "conformist"
#> [20,] "4" "conformist"
base = 12532812
seed = base + 38
knitr::include_graphics(paste0("./figures/animation_network_", seed, ".gif"))

# use this as the network structure for an otree session:
# cbind(degree(test$network),V(test$network)$role)
# convert to adjacency matrix
adj_matrix <- as.matrix(as_adjacency_matrix(test$network))
# get roles
role_vector <- ifelse(V(test$network)$role == "trendsetter", 1, 0)
# create a list to store the network data
net <- list(adj_matrix = adj_matrix, role_vector = role_vector)
# save the list as a JSON file
write_json(net, "SRDA_n20_heterogenous.json")
WG2: homogenous
degree distribution–“random network”
test <- run_one_sw(i = 513, beta = 1, pmin = 0.1, return_network = TRUE)



table(degree(test$network))
#>
#> 2 3 4 5 6 7 8 9
#> 1 1 2 4 2 6 3 1
cbind(degree(test$network), V(test$network)$role)
#> [,1] [,2]
#> [1,] "4" "conformist"
#> [2,] "8" "conformist"
#> [3,] "7" "conformist"
#> [4,] "7" "conformist"
#> [5,] "8" "conformist"
#> [6,] "7" "conformist"
#> [7,] "7" "conformist"
#> [8,] "3" "trendsetter"
#> [9,] "4" "conformist"
#> [10,] "5" "conformist"
#> [11,] "8" "conformist"
#> [12,] "6" "conformist"
#> [13,] "6" "conformist"
#> [14,] "5" "conformist"
#> [15,] "2" "trendsetter"
#> [16,] "5" "conformist"
#> [17,] "7" "conformist"
#> [18,] "5" "conformist"
#> [19,] "9" "conformist"
#> [20,] "7" "trendsetter"
base_seed = 12532812
seed = base_seed + 513
knitr::include_graphics(paste0("./figures/animation_network_", seed, ".gif"))

# use this as the network structure for an otree session:
# cbind(degree(test$network),V(test$network)$role)
# convert to adjacency matrix
adj_matrix <- as.matrix(as_adjacency_matrix(test$network))
# get roles
role_vector <- ifelse(V(test$network)$role == "trendsetter", 1, 0)
# create a list to store the network data
net <- list(adj_matrix = adj_matrix, role_vector = role_vector)
# save the list as a JSON file
write_json(net, "SRDA_n20_random.json")
LS0tDQp0aXRsZTogIkV4cGVyaW1lbnQgaW4gU1JEQSBjb21wdXRlci1sYWIiDQpiaWJsaW9ncmFwaHk6IHJlZmVyZW5jZXMuYmliDQpsaW5rLWNpdGF0aW9uczogdHJ1ZQ0KZGF0ZTogIkxhc3QgY29tcGlsZWQgb24gYHIgZm9ybWF0KFN5cy50aW1lKCksICclZC0lbS0lWScpYCINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgc2VsZl9jb250YWluZWQ6IHRydWUNCiAgICBjc3M6IHR3ZWFrcy5jc3MNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCi0tLQ0KDQpgYGB7ciwgZ2xvYmFsc2V0dGluZ3MsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHM9J2hpZGUnLCBtZXNzYWdlPUZBTFNFfQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkodGlkeXZlcnNlKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQ0Kb3B0c19jaHVuayRzZXQodGlkeS5vcHRzPWxpc3Qod2lkdGguY3V0b2ZmPTEwMCksdGlkeT1UUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSxjb21tZW50ID0gIiM+IiwgY2FjaGU9VFJVRSwgY2xhc3Muc291cmNlPWMoInRlc3QiKSwgY2xhc3Mub3V0cHV0PWMoInRlc3QzIikpDQpvcHRpb25zKHdpZHRoID0gMTAwKQ0KcmdsOjpzZXR1cEtuaXRyKCkNCg0KY29sb3JpemUgPC0gZnVuY3Rpb24oeCwgY29sb3IpIHtzcHJpbnRmKCI8c3BhbiBzdHlsZT0nY29sb3I6ICVzOyc+JXM8L3NwYW4+IiwgY29sb3IsIHgpIH0NCmBgYA0KDQpgYGB7ciBrbGlwcHksIGVjaG89RkFMU0UsIGluY2x1ZGU9VFJVRX0NCmtsaXBweTo6a2xpcHB5KHBvc2l0aW9uID0gYygndG9wJywgJ3JpZ2h0JykpDQoja2xpcHB5OjprbGlwcHkoY29sb3IgPSAnZGFya3JlZCcpDQoja2xpcHB5OjprbGlwcHkodG9vbHRpcF9tZXNzYWdlID0gJ0NsaWNrIHRvIGNvcHknLCB0b29sdGlwX3N1Y2Nlc3MgPSAnRG9uZScpDQpgYGANCg0KLS0tDQoNCiMgR2V0dGluZyBzdGFydGVkDQoNClRvIGNvcHkgdGhlIGNvZGUsIGNsaWNrIHRoZSBidXR0b24gaW4gdGhlIHVwcGVyIHJpZ2h0IGNvcm5lciBvZiB0aGUgY29kZS1jaHVua3MuDQoNCiMjIGNsZWFuIHVwDQoNCmBgYHtyLCBjbGVhbl91cCwgcmVzdWx0cz0naGlkZSd9DQpybShsaXN0PWxzKCkpDQpnYygpDQpgYGANCg0KPGJyPg0KDQojIyBjdXN0b20gZnVuY3Rpb25zDQoNCldlIGRlZmluZWQgYSBudW1iZXIgY3VzdG9tIGZ1bmN0aW9ucywgYXQgYHIgeGZ1bjo6ZW1iZWRfZmlsZSgiLi9jdXN0b21fZnVuY3Rpb25zLlIiKWAuDQoNCmBgYHtyLCBjdXN0b21fZnVuY3Rpb25zfQ0Kc291cmNlKCIuL2N1c3RvbV9mdW5jdGlvbnMuUiIpDQpgYGANCg0KPGJyPg0KDQojIyBuZWNlc3NhcnkgcGFja2FnZXMNCg0KLSBgdGlkeXZlcnNlYDogZGF0YSB3cmFuZ2xpbmcNCi0gYGlncmFwaGA6IGdlbmVyYXRlIGFuZCB2aXN1YWxpemUgZ3JhcGhzDQotIGBwYXJhbGxlbGA6IHBhcmFsbGVsIGNvbXB1dGluZyB0byBzcGVlZCB1cCBzaW11bGF0aW9uDQotIGBmb3JlYWNoYDogbG9vcGluZyBpbiBwYXJhbGxlbA0KLSBgZG9QYXJhbGxlbGA6IHBhcmFsbGVsIGJhY2tlbmQgZm9yIGBmb3JlYWNoYA0KLSBgZ2dwbG90MmA6IGRhdGEgdmlzdWFsaXphdGlvbg0KLSBgZ2doNHhgOiBoYWNrcyBmb3IgYGdncGxvdDJgDQotIGBnZ3B1YnJgOiBtYWtlIHZpc3VhbGl6YXRpb25zIHB1YmxpY2F0aW9uLXJlYWR5DQoNCmBgYHtyLCBwYWNrYWdlc30NCnBhY2thZ2VzID0gYygidGlkeXZlcnNlIiwgImlncmFwaCIsICJnZ3Bsb3QyIiwgInBhcmFsbGVsIiwgImRvUGFyYWxsZWwiLCAiZm9yZWFjaCIsICJnZ2g0eCIsICJnZ3B1YnIiLCAicGxvdGx5IiwgIlJDb2xvckJyZXdlciIsICJncmlkIiwgImdyaWRFeHRyYSIsICJwYXRjaHdvcmsiLCAiZ2dwbG90aWZ5IiwgImdncmFwaCIsICJnZ2FuaW1hdGUiLCAiUkNvbG9yQnJld2VyIiwNCiAgICAiZ2d0ZXh0IiwgIm1hZ2ljayIsICJqc29ubGl0ZSIpDQoNCmludmlzaWJsZShmcGFja2FnZS5jaGVjayhwYWNrYWdlcykpDQpybShwYWNrYWdlcykNCmBgYA0KDQotLS0NCg0KIyBFeHBlcmltZW50YWwgY29uZGl0aW9ucw0KDQpgYGB7ciwgZWNobz1UUlVFLCBmaWcuc2hvdz0naG9sZCcsIGZpZy5rZWVwPSdhbGwnLCBtZXNzYWdlPUZBTFNFLCBmaWcuaGVpZ2h0PTV9DQojIHBpY2sgb25lIGNvbmZpZ3VyYXRpb24gdGhhdCBsaWtlbHkgbGVhZHMgdG8gYW4gdW5wb3B1bGFyIG5vcm0sIGFuZCBleHBsb3JlIG11bHRpcGxlICdzZWVkcyc6DQpydW5fb25lX3NlZWQgPC0gZnVuY3Rpb24oDQogIGksDQogIGJhc2Vfc2VlZCA9IDEyNTMyODEyLA0KICBwYXJhbXMgPSBsaXN0KHMgPSAxNSwgZSA9IDEwLCB3ID0gNDAsIHogPSA1MCwgbGFtYmRhMSA9IDUsIGxhbWJkYTIgPSAxLjgpLA0KICANCiAgIyB0d2VhayBuZXR3b3JrDQogIGtfbWluID0gMywgDQogIGtfbWF4ID0gMTUsDQogIGFscGhhID0gMi40LA0KICByaG8gPSAwLjQsDQogIHIgPSAtMC4xLA0KICANCiAgIyByZXRyaWV2ZSBuZXR3b3JrDQogIHJldHVybl9uZXR3b3JrID0gRkFMU0UNCiAgDQopIHsNCiAgIyBkZXJpdmVkIHNlZWQgZm9yIHRoaXMgcnVuDQogIHNlZWRfaSA8LSBiYXNlX3NlZWQgKyBpDQogIHNldC5zZWVkKHNlZWRfaSkNCg0KICAjIC0tLSBuZXR3b3JrIGNyZWF0aW9uIC0tLQ0KICBkZWdzZXEgPC0gZmRlZ3NlcSgNCiAgICBuID0gMjAsDQogICAgYWxwaGEgID0gYWxwaGEsDQogICAga19taW4gID0ga19taW4sDQogICAga19tYXggID0ga19tYXgsDQogICAgZGlzdCAgID0gImxvZy1ub3JtYWwiLCAjdXNlIGxvZy1ub3JtYWwgDQogICAgc2VlZCAgID0gc2VlZF9pDQogICkNCg0KICBuZXR3b3JrIDwtIHNhbXBsZV9kZWdzZXEoZGVnc2VxLCBtZXRob2QgPSAidmwiKQ0KICANCiAgDQogICBWKG5ldHdvcmspJHJvbGUgPC0gc2FtcGxlKA0KICAgIGMocmVwKCJ0cmVuZHNldHRlciIsIDMpLCByZXAoImNvbmZvcm1pc3QiLCAxNykpDQogICkNCiAgDQogIHJld2lyZWRfbmV0d29yayA8LSBmcmV3aXJlX3IobmV0d29yaywgciwgdmVyYm9zZSA9IEZBTFNFLCBtYXhfaXRlciA9IDFlNSkNCiAgZmluYWxfbmV0d29yayAgIDwtIGZzd2FwX3JobyhyZXdpcmVkX25ldHdvcmssIHJobywgdmVyYm9zZSA9IEZBTFNFLCBtYXhfaXRlciA9IDFlNCkNCiAgDQogICMgLS0tIHN0YXRzIC0tLQ0KICBzdGF0cyA8LSBsaXN0KA0KICAgIHJ1biAgICAgICAgICAgPSBpLA0KICAgIHNlZWQgICAgICAgICAgPSBzZWVkX2ksDQogICAgbnVtX25vZGVzICAgICA9IHZjb3VudChmaW5hbF9uZXR3b3JrKSwNCiAgICBudW1fZWRnZXMgICAgID0gZWNvdW50KGZpbmFsX25ldHdvcmspLA0KICAgIGF2Z19kZWdyZWUgICAgPSBtZWFuKGRlZ3JlZShmaW5hbF9uZXR3b3JrKSksDQogICAgc2RfZGVncmVlICAgICA9IHNkKGRlZ3JlZShmaW5hbF9uZXR3b3JrKSksDQogICAgbmV0X2RlbnNpdHkgICA9IGVkZ2VfZGVuc2l0eShmaW5hbF9uZXR3b3JrKSwNCiAgICBuZXRfZGlhbWV0ZXIgID0gZGlhbWV0ZXIoZmluYWxfbmV0d29yaywgZGlyZWN0ZWQgPSBGQUxTRSwgdW5jb25uZWN0ZWQgPSBUUlVFKSwNCiAgICBhdmdfcGF0aF9sZW4gID0gYXZlcmFnZS5wYXRoLmxlbmd0aChmaW5hbF9uZXR3b3JrLCBkaXJlY3RlZCA9IEZBTFNFKSwNCiAgICBjbHVzdF9jb2VmZiAgID0gdHJhbnNpdGl2aXR5KGZpbmFsX25ldHdvcmssIHR5cGUgPSAiZ2xvYmFsIiksDQogICAgYXNzb3J0X2RlZyAgICA9IGFzc29ydGF0aXZpdHlfZGVncmVlKGZpbmFsX25ldHdvcmspLA0KICAgIGRlZ190cmFpdF9jb3IgPSBmZGVndHJhaXRjb3IoZmluYWxfbmV0d29yaykkY29yLA0KICAgIGNvbXBvbmVudHMgICAgPSBjb21wb25lbnRzKGZpbmFsX25ldHdvcmspJG5vDQogICkNCiAgDQogIGZwbG90X2dyYXBoKGZpbmFsX25ldHdvcmssIGxheW91dCA9IGxheW91dF93aXRoX2ZyKGZpbmFsX25ldHdvcmspKSANCiAgDQogIA0KICAjIC0tLSBpbml0aWFsIGFjdGlvbnMgLS0tDQogIFYoZmluYWxfbmV0d29yaykkYWN0aW9uIDwtIGlmZWxzZShWKGZpbmFsX25ldHdvcmspJHJvbGUgPT0gInRyZW5kc2V0dGVyIiwgMSwgMCkNCiAgDQogICMgLS0tIGRldGVybWluaXN0aWMgc2ltdWxhdGlvbiAtLS0NCiAgc2ltX2RldCA8LSBmYWJtKA0KICAgIG5ldHdvcmsgICAgICA9IGZpbmFsX25ldHdvcmssDQogICAgcGFyYW1zICAgICAgID0gcGFyYW1zLA0KICAgIG1heF9yb3VuZHMgICA9IDM1LA0KICAgIG1pX3RocmVzaG9sZCA9IDAuNDksDQogICAgY2hvaWNlX3J1bGUgID0gImRldGVybWluaXN0aWMiLA0KICAgIHBsb3QgICAgICAgICA9IFRSVUUsDQogICAgaGlzdG9yaWVzICAgID0gVFJVRQ0KICApDQogIA0KICAjIGdlbmVyYXRlIHRoZSBnaWYgZm9yIHRoZSBjdXJyZW50IG5ldHdvcmsNCiAgZ2lmX2ZpbGVuYW1lIDwtIHBhc3RlMCgiLi9maWd1cmVzL2FuaW1hdGlvbl9uZXR3b3JrXyIsIHNlZWRfaSwgIi5naWYiKQ0KICBnaWZfcGF0aCA8LSBmbmV0d29ya2dpZihmaW5hbF9uZXR3b3JrLCBzaW1fZGV0JGRlY2lzaW9uX2hpc3RvcnksIHJvdW5kcyA9IHNpbV9kZXQkZXF1aWxpYnJpdW0kcm91bmQsIG91dHB1dF9kaXIgPSAiLi9maWd1cmVzIikNCiAgIyByZW5hbWUgdGhlIGdpZiB0byBtYXRjaCB0aGUgbmFtaW5nIHBhdHRlcm4NCiAgZmlsZS5yZW5hbWUoZ2lmX3BhdGgsIGdpZl9maWxlbmFtZSkNCg0KICBpZiAoIWlzLm51bGwoc2ltX2RldCRwbG90KSkgew0KICAgIHByaW50KHNpbV9kZXQkcGxvdCkNCiAgfQ0KICANCiAgIyAtLS0gcHJvYmFiaWxpc3RpYyBzaW11bGF0aW9uIC0tLQ0KICBzaW1fcHJvYiA8LSBmYWJtKA0KICAgIG5ldHdvcmsgICAgICAgICAgICAgICAgPSBmaW5hbF9uZXR3b3JrLA0KICAgIHBhcmFtcyAgICAgICAgICAgICAgICAgPSBwYXJhbXMsDQogICAgbWF4X3JvdW5kcyAgICAgICAgICAgICA9IDUwLA0KICAgIG1pX3RocmVzaG9sZCAgICAgICAgICAgPSAwLjQ5LA0KICAgIGNob2ljZV9ydWxlICAgICAgICAgICAgPSAicHJvYmFiaWxpc3RpYyIsDQogICAgc3RhYmxlX3dpbmRvdyAgICAgICAgICA9IDgsICAgIyB0aGUgbGVuZ3RoIG9mIHRoZSB3aW5kb3cgb2YgYWRvcHRpb24gdmFsdWVzDQogICAgcmVxdWlyZWRfc3RhYmxlX3JvdW5kcyA9IDIwLCAjIG51bWJlciBvZiB3aW5kb3dzIG5lZWRlZCB0byBkZWNsYXJlIGVxdWlsaWJyaXVtDQogICAgcGxvdCAgICAgICAgICAgICAgICAgICA9IFRSVUUNCiAgKQ0KICBpZiAoIWlzLm51bGwoc2ltX3Byb2IkcGxvdCkpIHsNCiAgICBwcmludChzaW1fcHJvYiRwbG90KQ0KICB9DQogIA0KICAgcmVzdWx0IDwtIGxpc3QoDQogICAgc2VncmVnYXRpb25fZGV0ICA9IHNpbV9kZXQkZXF1aWxpYnJpdW0kc2VncmVnYXRpb24sDQogICAgc2VncmVnYXRpb25fcHJvYiA9IHNpbV9wcm9iJGVxdWlsaWJyaXVtJHNlZ3JlZ2F0aW9uLA0KICAgIHN0YXRzICAgICAgICAgICAgPSBzdGF0cw0KICApDQogIA0KICBpZiAocmV0dXJuX25ldHdvcmspIHsNCiAgICByZXN1bHQkbmV0d29yayA8LSBmaW5hbF9uZXR3b3JrDQogIH0NCiAgDQogIHJlc3VsdA0KfQ0KDQojYW5kIG9uZSAicmFuZG9tIiBuZXR3b3JrDQpydW5fb25lX3N3IDwtIGZ1bmN0aW9uKA0KICBpLA0KICBiYXNlX3NlZWQgPSAxMjUzMjgxMiwNCiAgbW9kZWwgPSAid2F0dHMtc3Ryb2dhdHoiLA0KICBiZXRhID0gMCwNCiAgbmVpID0gMywNCiAgY2xpcXVlX3NpemUgPSA1LA0KICBwbWluID0gMC4xLA0KICANCiAgcGFyYW1zID0gbGlzdChzID0gMTUsIGUgPSAxMCwgdyA9IDQwLCB6ID0gNTAsIGxhbWJkYTEgPSA1LCBsYW1iZGEyID0gMS44KSwNCiAgDQogICMgcmV0cmlldmUgbmV0d29yaw0KICByZXR1cm5fbmV0d29yayA9IEZBTFNFDQogIA0KKSB7DQogICMgZGVyaXZlZCBzZWVkIGZvciB0aGlzIHJ1bg0KICBzZWVkX2kgPC0gYmFzZV9zZWVkICsgaQ0KICBzZXQuc2VlZChzZWVkX2kpDQoNCiAgaWYgKG1vZGVsID09ICJ3YXR0cy1zdHJvZ2F0eiIpIHsNCiAgICBuZXR3b3JrIDwtIHNhbXBsZV9zbWFsbHdvcmxkKGRpbSA9IDEsIHNpemUgPSAyMCwgbmVpID0gMywgcCA9IGJldGEpIH0NCiAgZWxzZSBpZiAobW9kZWwgPT0gImNhdmVtYW4iKSB7DQogICAgbmV0d29yayA8LSBzaW11bGF0ZV9jYXZlbWFuKG4gPSAyMCwgY2xpcXVlX3NpemUgPSBjbGlxdWVfc2l6ZSkgDQogIH0NCg0KICBWKG5ldHdvcmspJHJvbGUgPC0gc2FtcGxlKA0KICAgIGMocmVwKCJ0cmVuZHNldHRlciIsIDMpLCByZXAoImNvbmZvcm1pc3QiLCAxNykpDQogICkNCiAgDQogIA0KICBmaW5hbF9uZXR3b3JrIDwtIG5ldHdvcmsNCg0KICANCiAgIyAtLS0gc3RhdHMgLS0tDQogIHN0YXRzIDwtIGxpc3QoDQogICAgcnVuICAgICAgICAgICA9IGksDQogICAgc2VlZCAgICAgICAgICA9IHNlZWRfaSwNCiAgICBudW1fbm9kZXMgICAgID0gdmNvdW50KGZpbmFsX25ldHdvcmspLA0KICAgIG51bV9lZGdlcyAgICAgPSBlY291bnQoZmluYWxfbmV0d29yayksDQogICAgYXZnX2RlZ3JlZSAgICA9IG1lYW4oZGVncmVlKGZpbmFsX25ldHdvcmspKSwNCiAgICBzZF9kZWdyZWUgICAgID0gc2QoZGVncmVlKGZpbmFsX25ldHdvcmspKSwNCiAgICBuZXRfZGVuc2l0eSAgID0gZWRnZV9kZW5zaXR5KGZpbmFsX25ldHdvcmspLA0KICAgIG5ldF9kaWFtZXRlciAgPSBkaWFtZXRlcihmaW5hbF9uZXR3b3JrLCBkaXJlY3RlZCA9IEZBTFNFLCB1bmNvbm5lY3RlZCA9IFRSVUUpLA0KICAgIGF2Z19wYXRoX2xlbiAgPSBhdmVyYWdlLnBhdGgubGVuZ3RoKGZpbmFsX25ldHdvcmssIGRpcmVjdGVkID0gRkFMU0UpLA0KICAgIGNsdXN0X2NvZWZmICAgPSB0cmFuc2l0aXZpdHkoZmluYWxfbmV0d29yaywgdHlwZSA9ICJnbG9iYWwiKSwNCiAgICBhc3NvcnRfZGVnICAgID0gYXNzb3J0YXRpdml0eV9kZWdyZWUoZmluYWxfbmV0d29yayksDQogICAgZGVnX3RyYWl0X2NvciA9IGZkZWd0cmFpdGNvcihmaW5hbF9uZXR3b3JrKSRjb3IsDQogICAgY29tcG9uZW50cyAgICA9IGNvbXBvbmVudHMoZmluYWxfbmV0d29yaykkbm8NCiAgKQ0KICANCiAgc3RhdHNfZGYgPC0gZGF0YS5mcmFtZSgNCiAgICBNZXRyaWMgPSBuYW1lcyhzdGF0cyksDQogICAgVmFsdWUgID0gdW5saXN0KHN0YXRzKSwNCiAgICByb3cubmFtZXMgPSBOVUxMDQogICkNCiAgDQogICNwcmludChzdGF0c19kZikNCiAgZnBsb3RfZ3JhcGgoZmluYWxfbmV0d29yaywgbGF5b3V0ID0gbGF5b3V0LmthbWFkYS5rYXdhaShmaW5hbF9uZXR3b3JrKSkNCiAgDQoNCiAgIyAtLS0gaW5pdGlhbCBhY3Rpb25zIC0tLQ0KICBWKGZpbmFsX25ldHdvcmspJGFjdGlvbiA8LSBpZmVsc2UoVihmaW5hbF9uZXR3b3JrKSRyb2xlID09ICJ0cmVuZHNldHRlciIsIDEsIDApDQogIA0KICAjIC0tLSBkZXRlcm1pbmlzdGljIHNpbXVsYXRpb24gLS0tDQogIHNpbV9kZXQgPC0gZmFibSgNCiAgICBuZXR3b3JrICAgICAgPSBmaW5hbF9uZXR3b3JrLA0KICAgIHBhcmFtcyAgICAgICA9IHBhcmFtcywNCiAgICBtYXhfcm91bmRzICAgPSAzNSwNCiAgICBtaV90aHJlc2hvbGQgPSAwLjQ5LA0KICAgIGNob2ljZV9ydWxlICA9ICJkZXRlcm1pbmlzdGljIiwNCiAgICBwbG90ICAgICAgICAgPSBUUlVFLA0KICAgIGhpc3RvcmllcyAgICA9IFRSVUUNCiAgKQ0KDQogICMgZ2VuZXJhdGUgdGhlIGdpZiBmb3IgdGhlIGN1cnJlbnQgbmV0d29yaw0KICBnaWZfZmlsZW5hbWUgPC0gcGFzdGUwKCIuL2ZpZ3VyZXMvYW5pbWF0aW9uX25ldHdvcmtfIiwgc2VlZF9pLCAiLmdpZiIpDQogIGdpZl9wYXRoIDwtIGZuZXR3b3JrZ2lmKGZpbmFsX25ldHdvcmssIHNpbV9kZXQkZGVjaXNpb25faGlzdG9yeSwgcm91bmRzID0gc2ltX2RldCRlcXVpbGlicml1bSRyb3VuZCwgb3V0cHV0X2RpciA9ICIuL2ZpZ3VyZXMiKQ0KICAjIHJlbmFtZSB0aGUgZ2lmIHRvIG1hdGNoIHRoZSBuYW1pbmcgcGF0dGVybg0KICBmaWxlLnJlbmFtZShnaWZfcGF0aCwgZ2lmX2ZpbGVuYW1lKQ0KICANCiAgDQogIGlmICghaXMubnVsbChzaW1fZGV0JHBsb3QpKSB7DQogICAgcHJpbnQoc2ltX2RldCRwbG90KQ0KICB9DQogIA0KICAjIC0tLSBwcm9iYWJpbGlzdGljIHNpbXVsYXRpb24gLS0tDQogIHNpbV9wcm9iIDwtIGZhYm0oDQogICAgbmV0d29yayAgICAgICAgICAgICAgICA9IGZpbmFsX25ldHdvcmssDQogICAgcGFyYW1zICAgICAgICAgICAgICAgICA9IHBhcmFtcywNCiAgICBtYXhfcm91bmRzICAgICAgICAgICAgID0gNTAsDQogICAgbWlfdGhyZXNob2xkICAgICAgICAgICA9IDAuNDksDQogICAgY2hvaWNlX3J1bGUgICAgICAgICAgICA9ICJwcm9iYWJpbGlzdGljIiwNCiAgICBzdGFibGVfd2luZG93ICAgICAgICAgID0gOCwgICAjIHRoZSBsZW5ndGggb2YgdGhlIHdpbmRvdyBvZiBhZG9wdGlvbiB2YWx1ZXMNCiAgICByZXF1aXJlZF9zdGFibGVfcm91bmRzID0gMjAsICMgbnVtYmVyIG9mIHdpbmRvd3MgbmVlZGVkIHRvIGRlY2xhcmUgZXF1aWxpYnJpdW0NCiAgICBwbG90ICAgICAgICAgICAgICAgICAgID0gVFJVRQ0KICApDQogIGlmICghaXMubnVsbChzaW1fcHJvYiRwbG90KSkgew0KICAgIHByaW50KHNpbV9wcm9iJHBsb3QpDQogIH0NCiAgDQogIA0KICByZXN1bHQgPC0gbGlzdCgNCiAgICBzZWdyZWdhdGlvbl9kZXQgID0gc2ltX2RldCRlcXVpbGlicml1bSRzZWdyZWdhdGlvbiwNCiAgICBzZWdyZWdhdGlvbl9wcm9iID0gc2ltX3Byb2IkZXF1aWxpYnJpdW0kc2VncmVnYXRpb24sDQogICAgc3RhdHMgICAgICAgICAgICA9IHN0YXRzDQogICkNCiAgDQogIGlmIChyZXR1cm5fbmV0d29yaykgew0KICAgIHJlc3VsdCRuZXR3b3JrIDwtIGZpbmFsX25ldHdvcmsNCiAgfQ0KICANCiAgcmVzdWx0DQp9DQpgYGANCg0KDQotLS0tLQ0KDQojIyBTUkRBIGNvbXB1dGVyLWxhYiBkZW1vbnN0YXRpb24NCg0KIyMjIFdHMTogaGV0ZXJvZ2Vub3VzIGRlZ3JlZSBkaXN0cmlidXRpb247IGNlbnRyYWxpemVkICJmYW5hdGljcyI6DQoNCmBgYHtyfQ0KdGVzdCA8LSBydW5fb25lX3NlZWQoMzgsIGtfbWluID0gNCwga19tYXggPSAxNiwgYWxwaGEgPSAyLjMsIHJobyA9IDEsIHIgPSAtMC4yLCByZXR1cm5fbmV0d29yayA9IFRSVUUpDQoNCnRhYmxlKGRlZ3JlZSh0ZXN0JG5ldHdvcmspKQ0KY2JpbmQoZGVncmVlKHRlc3QkbmV0d29yayksVih0ZXN0JG5ldHdvcmspJHJvbGUpDQpgYGANCg0KDQpgYGB7ciwgb3V0LndpZHRoPSI2MCUifQ0KYmFzZSA9IDEyNTMyODEyDQpzZWVkID0gYmFzZSArIDM4DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXN0ZTAoIi4vZmlndXJlcy9hbmltYXRpb25fbmV0d29ya18iLCBzZWVkICwiLmdpZiIpKQ0KYGBgIA0KDQoNCmBgYHtyLCBldmFsID0gRkFMU0V9DQojIHVzZSB0aGlzIGFzIHRoZSBuZXR3b3JrIHN0cnVjdHVyZSBmb3IgYW4gb3RyZWUgc2Vzc2lvbjoNCiNjYmluZChkZWdyZWUodGVzdCRuZXR3b3JrKSxWKHRlc3QkbmV0d29yaykkcm9sZSkNCg0KIyBjb252ZXJ0IHRvIGFkamFjZW5jeSBtYXRyaXgNCmFkal9tYXRyaXggPC0gYXMubWF0cml4KGFzX2FkamFjZW5jeV9tYXRyaXgodGVzdCRuZXR3b3JrKSkNCg0KI2dldCByb2xlcw0Kcm9sZV92ZWN0b3IgPC0gaWZlbHNlKFYodGVzdCRuZXR3b3JrKSRyb2xlID09ICJ0cmVuZHNldHRlciIsMSwwKQ0KIyBjcmVhdGUgYSBsaXN0IHRvIHN0b3JlIHRoZSBuZXR3b3JrIGRhdGENCm5ldCA8LSBsaXN0KGFkal9tYXRyaXggPSBhZGpfbWF0cml4LCByb2xlX3ZlY3RvciA9IHJvbGVfdmVjdG9yKQ0KIyBzYXZlIHRoZSBsaXN0IGFzIGEgSlNPTiBmaWxlDQp3cml0ZV9qc29uKG5ldCwgIlNSREFfbjIwX2hldGVyb2dlbm91cy5qc29uIikNCmBgYA0KDQoNCiMjIyBXRzI6IGhvbW9nZW5vdXMgZGVncmVlIGRpc3RyaWJ1dGlvbi0tInJhbmRvbSBuZXR3b3JrIg0KDQoNCmBgYHtyfQ0KdGVzdCA8LSBydW5fb25lX3N3KGk9NTEzLCBiZXRhPTEsIHBtaW49LjEsIHJldHVybl9uZXR3b3JrID0gVFJVRSApDQoNCnRhYmxlKGRlZ3JlZSh0ZXN0JG5ldHdvcmspKQ0KY2JpbmQoZGVncmVlKHRlc3QkbmV0d29yayksVih0ZXN0JG5ldHdvcmspJHJvbGUpDQpgYGANCg0KDQpgYGB7ciwgb3V0LndpZHRoPSI2MCUifQ0KYmFzZV9zZWVkID0gMTI1MzI4MTINCnNlZWQgPSBiYXNlX3NlZWQgKyA1MTMNCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGFzdGUwKCIuL2ZpZ3VyZXMvYW5pbWF0aW9uX25ldHdvcmtfIiwgc2VlZCAsIi5naWYiKSkNCmBgYCANCg0KDQoNCmBgYHtyLCBldmFsID0gRkFMU0V9DQojIHVzZSB0aGlzIGFzIHRoZSBuZXR3b3JrIHN0cnVjdHVyZSBmb3IgYW4gb3RyZWUgc2Vzc2lvbjoNCiNjYmluZChkZWdyZWUodGVzdCRuZXR3b3JrKSxWKHRlc3QkbmV0d29yaykkcm9sZSkNCg0KIyBjb252ZXJ0IHRvIGFkamFjZW5jeSBtYXRyaXgNCmFkal9tYXRyaXggPC0gYXMubWF0cml4KGFzX2FkamFjZW5jeV9tYXRyaXgodGVzdCRuZXR3b3JrKSkNCg0KI2dldCByb2xlcw0Kcm9sZV92ZWN0b3IgPC0gaWZlbHNlKFYodGVzdCRuZXR3b3JrKSRyb2xlID09ICJ0cmVuZHNldHRlciIsMSwwKQ0KIyBjcmVhdGUgYSBsaXN0IHRvIHN0b3JlIHRoZSBuZXR3b3JrIGRhdGENCm5ldCA8LSBsaXN0KGFkal9tYXRyaXggPSBhZGpfbWF0cml4LCByb2xlX3ZlY3RvciA9IHJvbGVfdmVjdG9yKQ0KIyBzYXZlIHRoZSBsaXN0IGFzIGEgSlNPTiBmaWxlDQp3cml0ZV9qc29uKG5ldCwgIlNSREFfbjIwX3JhbmRvbS5qc29uIikNCmBgYA0K