This script replicates Figure 3 of the manuscript (Ego-alter
influence plots).
Preparation
Clean the working environment
# clean the working environment
rm(list = ls())
Define some functions
{
fcentring <- function(actors) {
centored <- actors - mean(actors)
return(centored)
}
fsimij <- function(actors, min, max) {
# rv <- max(actors) - min(actors)
rv <- max - min
mat1 <- matrix(actors, nrow = length(actors), ncol = length(actors), byrow = TRUE)
mat2 <- t(mat1)
simij <- 1 - (abs(mat1 - mat2)/rv)
return(simij)
}
flinear <- function(ego, alters, ...) {
actors <- c(ego, alters) #define the network
beh_centered <- fcentring(actors) #center behavior scores
statistic <- beh_centered[1] #the actual statistic
return(statistic)
}
fquad <- function(ego, alters, ...) {
actors <- c(ego, alters) #define the network
beh_centered <- fcentring(actors) #center behavior scores
statistic <- (beh_centered[1])^2 #the actual statistic
return(statistic)
}
favSim <- function(ego, alters, min, max) {
actors <- c(ego, alters) #define the network
beh_centered <- fcentring(actors) #center behavior scores
simij <- fsimij(beh_centered, min, max) #calculate the similarity scores
diag(simij) <- NA
msimij <- mean(simij, na.rm = TRUE) #calculate the mean similarity score. only calculate mean on non-diagonal cells??!!
simij_c <- simij - msimij #center the similarity scores
statistic <- sum(simij_c[1, ], na.rm = TRUE)/length(alters) #the actual statistic
return(statistic)
}
favSim2 <- function(ego, alters, min, max) {
actors <- c(ego, alters) #define the network
beh_centered <- fcentring(actors) #center behavior scores
simij <- fsimij(beh_centered, min, max) #calculate the similarity scores
diag(simij) <- NA
# msimij <- mean(simij, na.rm=TRUE) #calculate the mean similarity score. only calculate
# mean on non-diagonal cells??!!
simij_c <- simij # - msimij #center the similarity scores
statistic <- sum(simij_c[1, ], na.rm = TRUE)/length(alters) #the actual statistic
return(statistic)
}
favAttHigher <- function(ego, alters, min, max) {
actors <- c(ego, alters)
beh_centered <- fcentring(actors)
simij <- fsimij(beh_centered, min, max)
diag(simij) <- NA
# msimij <- mean(simij, na.rm=TRUE) #only calculate mean on non-diagonal cells??!! simij_c
# <- simij - msimij diag(simij_c) <- NA
simijH <- simij[1, ]
simijH[beh_centered <= beh_centered[1]] <- 1
simijH[1] <- NA
statistic <- sum(simijH, na.rm = TRUE)/length(alters)
return(statistic)
}
favAttLower <- function(ego, alters, min, max) {
actors <- c(ego, alters)
beh_centered <- fcentring(actors)
simij <- fsimij(beh_centered, min, max)
diag(simij) <- NA
simijL <- simij[1, ]
simijL[beh_centered >= beh_centered[1]] <- 1
simijL[1] <- NA
statistic <- sum(simijL, na.rm = TRUE)/length(alters)
return(statistic)
}
favAlt <- function(ego, alters, ...) {
actors <- c(ego, alters)
beh_centered <- fcentring(actors)
statistic <- beh_centered[1] * (sum(beh_centered[-1], na.rm = TRUE)/length(alters))
return(statistic)
}
fAttMean <- function(ego, alters, min, max, ...) {
rv <- max - min
actors <- c(ego, alters)
beh_centered <- fcentring(actors)
statistic <- 1 - abs(beh_centered[1] - (sum(beh_centered[-1], na.rm = TRUE)/length(alters)))/rv #thus we strive for a highest local similarity score!
return(statistic)
}
finluenceplot <- function(alters, min, max, fun, params, results = TRUE, plot = TRUE) {
# check correct number of parameters are given
if (length(fun) != length(params))
stop("Please provide one (and only one) parameter for each of the behavioral effects!")
# calculuate value of evaluation function
s <- NA
for (i in min:max) {
s[i] <- 0
for (j in 1:length(fun)) {
s[i] <- s[i] + params[j] * fun[[j]](i, alters, min, max)
}
}
# calculate the probabilities
p <- NA
for (i in min:max) {
p[i] <- exp(s[i])/sum(exp(s))
}
# calculate the probabilities of choice set
p2 <- NA
for (i in min:max) {
if (i == min) {
p2[i] <- exp(s[i])/sum(exp(s[i]) + exp(s[i + 1]))
} else if (i == max) {
p2[i] <- exp(s[i])/sum(exp(s[i]) + exp(s[i - 1]))
} else {
p2[i] <- exp(s[i])/sum(exp(s[i]) + exp(s[i - 1]) + exp(s[i + 1]))
}
}
# calculate the probability ratio
r <- NA
for (i in min:max) {
r[i] <- p[i]/p[1]
}
# some simple plots
if (plot) {
name <- deparse(substitute(fun))
name <- stringr::str_sub(as.character(name), 6, -2)
par(mfrow = c(2, 2))
plot(y = s, x = min:max, xlab = "ego behavioral score", ylab = name, type = "b")
mtext("EVALUATION", line = 1)
mtext(paste("alters:", paste0(alters, collapse = ",")))
plot(y = p, x = min:max, xlab = "ego behavioral score", ylab = name, ylim = c(0, 1), type = "b")
mtext("PROBABILITIES", line = 1)
mtext(paste("alters:", paste0(alters, collapse = ",")))
plot(y = p2, x = min:max, xlab = "ego behavioral score", ylab = name, ylim = c(0, 1), type = "b")
mtext("PROBABILITIES choice set", line = 1)
mtext(paste("alters:", paste0(alters, collapse = ",")))
plot(y = r, x = min:max, xlab = "ego behavioral score", ylab = name, type = "b")
mtext("RATIOS", line = 1)
mtext(paste("alters:", paste0(alters, collapse = ",")))
}
# return results for more fancy plotting
if (results) {
x <- min:max
df <- data.frame(x, s, p, p2, r)
return(df)
}
}
}
We consider different scenarios, where ego’s alters have different
running frequency values.
alters1 <- rep(c(2), 6)
alters2 <- rep(c(5), 6)
alters3 <- rep(c(2, 2, 2, 5, 5, 5))
alters4 <- rep(c(1, 2, 3, 4, 5, 6, 7))
Our club estimates:
# frequency
club1 <- c(-0.008, -0.071, 0.017, 4.762)
club2 <- c(-0.077, 0.04, 1.385, 4.413)
club3 <- c(-0.086, -0.009, 1.499, 2.41)
club4 <- c(0.149, -0.201, -4.482, 6.216)
club5 <- c(0.247, 0.062, -0.184, 9.062)
# scenario 1 club1
p1 <- finluenceplot(alters = alters1, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club1)
# club2
p2 <- finluenceplot(alters = alters1, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club2)
# club 3
p3 <- finluenceplot(alters = alters1, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club3)
# club 4
p4 <- finluenceplot(alters = alters1, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club4)
# club 5
p5 <- finluenceplot(alters = alters1, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club5)
plot1 <- rbind(p1, p2, p3, p4, p5)
plot1$Club <- as.character(sort(rep(1:5, 7)))
plot1$scenario <- paste("A) Behavior alters:", paste0(alters1, collapse = ", "))
# scenario 2 club1
p1 <- finluenceplot(alters = alters2, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club1)
# club2
p2 <- finluenceplot(alters = alters2, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club2)
# club 3
p3 <- finluenceplot(alters = alters2, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club3)
# club 4
p4 <- finluenceplot(alters = alters2, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club4)
# club 5
p5 <- finluenceplot(alters = alters2, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club5)
plot2 <- rbind(p1, p2, p3, p4, p5)
plot2$Club <- as.character(sort(rep(1:5, 7)))
plot2$scenario <- paste("B) Behavior alters:", paste0(alters2, collapse = ", "))
# scenario 3 club1
p1 <- finluenceplot(alters = alters3, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club1)
# club2
p2 <- finluenceplot(alters = alters3, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club2)
# club 3
p3 <- finluenceplot(alters = alters3, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club3)
# club 4
p4 <- finluenceplot(alters = alters3, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club4)
# club 5
p5 <- finluenceplot(alters = alters3, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club5)
plot3 <- rbind(p1, p2, p3, p4, p5)
plot3$Club <- as.character(sort(rep(1:5, 7)))
plot3$scenario <- paste("C) Behavior alters:", paste0(alters3, collapse = ", "))
# scenario 4 club1
p1 <- finluenceplot(alters = alters4, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club1)
# club2
p2 <- finluenceplot(alters = alters4, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club2)
# club 3
p3 <- finluenceplot(alters = alters4, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club3)
# club 4
p4 <- finluenceplot(alters = alters4, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club4)
# club 5
p5 <- finluenceplot(alters = alters4, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club5)
plot4 <- rbind(p1, p2, p3, p4, p5)
plot4$Club <- as.character(sort(rep(1:5, 7)))
plot4$scenario <- paste("D) Behavior alters:", paste0(alters4, collapse = ", "))
multiplot <- rbind(plot1, plot2, plot3, plot4)
multiplot$Attribute <- "Frequency"
We do the same for running volume.
# volume
club1 <- c(-0.056, -0.033, 0.277, 3.475)
club2 <- c(-0.22, 0.012, 1.721, 1.227)
club3 <- c(-0.129, -0.008, 1.929, 1.78)
club4 <- c(1.294, -0.409, -18.608, 16.761)
club5 <- c(-0.012, 0.024, 1.915, 8.61)
p1 <- finluenceplot(alters = alters1, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club1)
# club2
p2 <- finluenceplot(alters = alters1, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club2)
# club 3
p3 <- finluenceplot(alters = alters1, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club3)
# club 4
p4 <- finluenceplot(alters = alters1, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club4)
# club 5
p5 <- finluenceplot(alters = alters1, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club5)
plot1 <- rbind(p1, p2, p3, p4, p5)
plot1$Club <- as.character(sort(rep(1:5, 7)))
plot1$scenario <- paste("A) Behavior alters:", paste0(alters1, collapse = ", "))
# scenario 2 club1
p1 <- finluenceplot(alters = alters2, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club1)
# club2
p2 <- finluenceplot(alters = alters2, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club2)
# club 3
p3 <- finluenceplot(alters = alters2, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club3)
# club 4
p4 <- finluenceplot(alters = alters2, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club4)
# club 5
p5 <- finluenceplot(alters = alters2, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club5)
plot2 <- rbind(p1, p2, p3, p4, p5)
plot2$Club <- as.character(sort(rep(1:5, 7)))
plot2$scenario <- paste("B) Behavior alters:", paste0(alters2, collapse = ", "))
# scenario 3 club1
p1 <- finluenceplot(alters = alters3, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club1)
# club2
p2 <- finluenceplot(alters = alters3, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club2)
# club 3
p3 <- finluenceplot(alters = alters3, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club3)
# club 4
p4 <- finluenceplot(alters = alters3, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club4)
# club 5
p5 <- finluenceplot(alters = alters3, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club5)
plot3 <- rbind(p1, p2, p3, p4, p5)
plot3$Club <- as.character(sort(rep(1:5, 7)))
plot3$scenario <- paste("C) Behavior alters:", paste0(alters3, collapse = ", "))
# scenario 4 club1
p1 <- finluenceplot(alters = alters4, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club1)
# club2
p2 <- finluenceplot(alters = alters4, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club2)
# club 3
p3 <- finluenceplot(alters = alters4, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club3)
# club 4
p4 <- finluenceplot(alters = alters4, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club4)
# club 5
p5 <- finluenceplot(alters = alters4, min = 1, max = 7, results = T, plot = F, fun = list(flinear, fquad,
favAttHigher, favAttLower), params = club5)
plot4 <- rbind(p1, p2, p3, p4, p5)
plot4$Club <- as.character(sort(rep(1:5, 7)))
plot4$scenario <- paste("D) Behavior alters:", paste0(alters4, collapse = ", "))
multiplot2 <- rbind(plot1, plot2, plot3, plot4)
multiplot2$Attribute <- "Volume"
# merge them together
multiplot <- rbind(multiplot, multiplot2)
LS0tDQp0aXRsZTogIlJlcGxpY2F0aW5nIGVnby1hbHRlciBpbmZsdWVuY2UgcGxvdCINCmRhdGU6ICJMYXN0IGNvbXBpbGVkIG9uIGByIGZvcm1hdChTeXMudGltZSgpLCAnJUIsICVZJylgIg0KYmlibGlvZ3JhcGh5OiByZWZlcmVuY2VzLmJpYg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KDQogICAgY3NzOiB0d2Vha3MuY3NzDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgY29sbGFwc2VkOiBmYWxzZQ0KICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UNCiAgICB0b2NfZGVwdGg6IDENCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCi0tLQ0KDQoNCg0KDQpgYGB7ciwgZ2xvYmFsc2V0dGluZ3MsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkoZ2dwbG90MikNCg0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQ0Kb3B0c19jaHVuayRzZXQodGlkeS5vcHRzPWxpc3Qod2lkdGguY3V0b2ZmPTEwMCksdGlkeT1UUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSxjb21tZW50ID0gIiM+IiwgY2FjaGU9VFJVRSwgY2xhc3Muc291cmNlPWMoInRlc3QiKSwgY2xhc3Mub3V0cHV0PWMoInRlc3QyIikpDQpvcHRpb25zKHdpZHRoID0gMTAwKQ0KcmdsOjpzZXR1cEtuaXRyKCkNCg0KDQoNCmNvbG9yaXplIDwtIGZ1bmN0aW9uKHgsIGNvbG9yKSB7c3ByaW50ZigiPHNwYW4gc3R5bGU9J2NvbG9yOiAlczsnPiVzPC9zcGFuPiIsIGNvbG9yLCB4KSB9DQoNCmBgYA0KDQpgYGB7ciBrbGlwcHksIGVjaG89RkFMU0UsIGluY2x1ZGU9VFJVRX0NCmtsaXBweTo6a2xpcHB5KHBvc2l0aW9uID0gYygndG9wJywgJ3JpZ2h0JykpDQoja2xpcHB5OjprbGlwcHkoY29sb3IgPSAnZGFya3JlZCcpDQoja2xpcHB5OjprbGlwcHkodG9vbHRpcF9tZXNzYWdlID0gJ0NsaWNrIHRvIGNvcHknLCB0b29sdGlwX3N1Y2Nlc3MgPSAnRG9uZScpDQpgYGANCg0KLS0tDQoNCg0KVGhpcyBzY3JpcHQgcmVwbGljYXRlcyBGaWd1cmUgMyBvZiB0aGUgbWFudXNjcmlwdCAoRWdvLWFsdGVyIGluZmx1ZW5jZSBwbG90cykuDQoNCiMgUHJlcGFyYXRpb24NCg0KQ2xlYW4gdGhlIHdvcmtpbmcgZW52aXJvbm1lbnQNCg0KYGBge3IsIHdhcm5pbmc9RkFMU0V9DQojIGNsZWFuIHRoZSB3b3JraW5nIGVudmlyb25tZW50IA0Kcm0gKGxpc3QgPSBscyggKSkNCmBgYA0KDQo8YnI+DQoNCkRlZmluZSBzb21lIGZ1bmN0aW9ucw0KDQpgYGB7ciBldmFsPVR9DQp7DQoNCmZjZW50cmluZyA8LSBmdW5jdGlvbihhY3RvcnMpew0KICBjZW50b3JlZCA8LSBhY3RvcnMgLSBtZWFuKGFjdG9ycykNCiAgcmV0dXJuKGNlbnRvcmVkKQ0KfQ0KDQoNCmZzaW1paiA8LSBmdW5jdGlvbihhY3RvcnMsIG1pbiwgbWF4KXsNCiAgI3J2IDwtIG1heChhY3RvcnMpIC0gbWluKGFjdG9ycykNCiAgcnYgPC0gbWF4IC0gbWluDQogIG1hdDEgPC0gbWF0cml4KGFjdG9ycywgbnJvdz1sZW5ndGgoYWN0b3JzKSwgbmNvbD1sZW5ndGgoYWN0b3JzKSwgYnlyb3c9VFJVRSkNCiAgbWF0MiA8LSB0KG1hdDEpDQogIHNpbWlqIDwtIDEgLSAoIGFicyhtYXQxLW1hdDIpIC8gcnYpDQogIHJldHVybihzaW1paikNCn0NCg0KZmxpbmVhciA8LSBmdW5jdGlvbihlZ28sIGFsdGVycywgLi4uKSB7DQogIGFjdG9ycyA8LSBjKGVnbyxhbHRlcnMpICNkZWZpbmUgdGhlIG5ldHdvcmsNCiAgYmVoX2NlbnRlcmVkIDwtIGZjZW50cmluZyhhY3RvcnMpICNjZW50ZXIgYmVoYXZpb3Igc2NvcmVzDQogIA0KICBzdGF0aXN0aWMgPC0gYmVoX2NlbnRlcmVkWzFdICN0aGUgYWN0dWFsIHN0YXRpc3RpYw0KICANCiAgcmV0dXJuKHN0YXRpc3RpYykNCn0NCg0KZnF1YWQgPC0gZnVuY3Rpb24oZWdvLCBhbHRlcnMsIC4uLikgew0KICBhY3RvcnMgPC0gYyhlZ28sYWx0ZXJzKSAjZGVmaW5lIHRoZSBuZXR3b3JrDQogIGJlaF9jZW50ZXJlZCA8LSBmY2VudHJpbmcoYWN0b3JzKSAjY2VudGVyIGJlaGF2aW9yIHNjb3Jlcw0KICANCiAgc3RhdGlzdGljIDwtIChiZWhfY2VudGVyZWRbMV0pXjIgI3RoZSBhY3R1YWwgc3RhdGlzdGljDQogIA0KICByZXR1cm4oc3RhdGlzdGljKQ0KfQ0KDQoNCmZhdlNpbSA8LSBmdW5jdGlvbihlZ28sIGFsdGVycywgbWluLCBtYXgpIHsNCiAgYWN0b3JzIDwtIGMoZWdvLGFsdGVycykgI2RlZmluZSB0aGUgbmV0d29yaw0KICBiZWhfY2VudGVyZWQgPC0gZmNlbnRyaW5nKGFjdG9ycykgI2NlbnRlciBiZWhhdmlvciBzY29yZXMNCiAgc2ltaWogPC0gZnNpbWlqKGJlaF9jZW50ZXJlZCwgbWluLCBtYXgpICNjYWxjdWxhdGUgdGhlIHNpbWlsYXJpdHkgc2NvcmVzDQogIGRpYWcoc2ltaWopIDwtIE5BDQogIG1zaW1paiA8LSBtZWFuKHNpbWlqLCBuYS5ybT1UUlVFKSAjY2FsY3VsYXRlIHRoZSBtZWFuIHNpbWlsYXJpdHkgc2NvcmUuIG9ubHkgY2FsY3VsYXRlIG1lYW4gb24gbm9uLWRpYWdvbmFsIGNlbGxzPz8hIQ0KICBzaW1pal9jIDwtIHNpbWlqIC0gbXNpbWlqICNjZW50ZXIgdGhlIHNpbWlsYXJpdHkgc2NvcmVzDQogIA0KICBzdGF0aXN0aWMgPC0gc3VtKHNpbWlqX2NbMSxdLCBuYS5ybSA9IFRSVUUpIC8gbGVuZ3RoKGFsdGVycykgI3RoZSBhY3R1YWwgc3RhdGlzdGljDQogIA0KICByZXR1cm4oc3RhdGlzdGljKQ0KfQ0KDQpmYXZTaW0yIDwtIGZ1bmN0aW9uKGVnbywgYWx0ZXJzLCBtaW4sIG1heCkgew0KICBhY3RvcnMgPC0gYyhlZ28sYWx0ZXJzKSAjZGVmaW5lIHRoZSBuZXR3b3JrDQogIGJlaF9jZW50ZXJlZCA8LSBmY2VudHJpbmcoYWN0b3JzKSAjY2VudGVyIGJlaGF2aW9yIHNjb3Jlcw0KICBzaW1paiA8LSBmc2ltaWooYmVoX2NlbnRlcmVkLCBtaW4sIG1heCkgI2NhbGN1bGF0ZSB0aGUgc2ltaWxhcml0eSBzY29yZXMNCiAgZGlhZyhzaW1paikgPC0gTkENCiAgI21zaW1paiA8LSBtZWFuKHNpbWlqLCBuYS5ybT1UUlVFKSAjY2FsY3VsYXRlIHRoZSBtZWFuIHNpbWlsYXJpdHkgc2NvcmUuIG9ubHkgY2FsY3VsYXRlIG1lYW4gb24gbm9uLWRpYWdvbmFsIGNlbGxzPz8hIQ0KICBzaW1pal9jIDwtIHNpbWlqICMgLSBtc2ltaWogI2NlbnRlciB0aGUgc2ltaWxhcml0eSBzY29yZXMNCiAgDQogIHN0YXRpc3RpYyA8LSBzdW0oc2ltaWpfY1sxLF0sIG5hLnJtID0gVFJVRSkgLyBsZW5ndGgoYWx0ZXJzKSAjdGhlIGFjdHVhbCBzdGF0aXN0aWMNCiAgDQogIHJldHVybihzdGF0aXN0aWMpDQp9DQoNCmZhdkF0dEhpZ2hlciA8LSBmdW5jdGlvbihlZ28sIGFsdGVycywgbWluLCBtYXgpIHsNCiAgYWN0b3JzIDwtIGMoZWdvLGFsdGVycykNCiAgYmVoX2NlbnRlcmVkIDwtIGZjZW50cmluZyhhY3RvcnMpDQogIHNpbWlqIDwtIGZzaW1paihiZWhfY2VudGVyZWQsIG1pbiwgbWF4KQ0KICBkaWFnKHNpbWlqKSA8LSBOQQ0KICAjbXNpbWlqIDwtIG1lYW4oc2ltaWosIG5hLnJtPVRSVUUpICNvbmx5IGNhbGN1bGF0ZSBtZWFuIG9uIG5vbi1kaWFnb25hbCBjZWxscz8/ISENCiAgI3NpbWlqX2MgPC0gc2ltaWogLSBtc2ltaWoNCiAgI2RpYWcoc2ltaWpfYykgPC0gTkEgDQogIHNpbWlqSCA8LSBzaW1palsxLF0NCiAgc2ltaWpIW2JlaF9jZW50ZXJlZCA8PSBiZWhfY2VudGVyZWRbMV1dIDwtIDENCiAgc2ltaWpIWzFdIDwtIE5BDQogIHN0YXRpc3RpYyA8LSBzdW0oc2ltaWpILCBuYS5ybSA9IFRSVUUpIC8gbGVuZ3RoKGFsdGVycykNCg0KICByZXR1cm4oc3RhdGlzdGljKQ0KfQ0KDQpmYXZBdHRMb3dlciA8LSBmdW5jdGlvbihlZ28sIGFsdGVycywgbWluLCBtYXgpIHsNCiAgYWN0b3JzIDwtIGMoZWdvLGFsdGVycykNCiAgYmVoX2NlbnRlcmVkIDwtIGZjZW50cmluZyhhY3RvcnMpDQogIHNpbWlqIDwtIGZzaW1paihiZWhfY2VudGVyZWQsIG1pbiwgbWF4KQ0KICBkaWFnKHNpbWlqKSA8LSBOQQ0KICANCiAgc2ltaWpMIDwtIHNpbWlqWzEsXQ0KICBzaW1pakxbYmVoX2NlbnRlcmVkID49IGJlaF9jZW50ZXJlZFsxXV0gPC0gMQ0KICBzaW1pakxbMV0gPC0gTkENCiAgc3RhdGlzdGljIDwtIHN1bShzaW1pakwsIG5hLnJtID0gVFJVRSkgLyBsZW5ndGgoYWx0ZXJzKQ0KICANCiAgDQogIHJldHVybihzdGF0aXN0aWMpDQp9DQoNCmZhdkFsdCA8LSBmdW5jdGlvbihlZ28sIGFsdGVycywgLi4uKSB7DQogIGFjdG9ycyA8LSBjKGVnbyxhbHRlcnMpDQogIGJlaF9jZW50ZXJlZCA8LSBmY2VudHJpbmcoYWN0b3JzKQ0KICANCiAgDQogIHN0YXRpc3RpYyA8LSBiZWhfY2VudGVyZWRbMV0gKiAoc3VtKGJlaF9jZW50ZXJlZFstMV0sIG5hLnJtID0gVFJVRSkgLyBsZW5ndGgoYWx0ZXJzKSkNCiAgDQogIA0KICByZXR1cm4oc3RhdGlzdGljKQ0KfQ0KDQpmQXR0TWVhbiA8LSBmdW5jdGlvbihlZ28sIGFsdGVycywgbWluLCBtYXgsIC4uLikgew0KICBydiA8LSBtYXggLSBtaW4NCiAgYWN0b3JzIDwtIGMoZWdvLGFsdGVycykNCiAgYmVoX2NlbnRlcmVkIDwtIGZjZW50cmluZyhhY3RvcnMpDQogIA0KICBzdGF0aXN0aWMgPC0gMSAtICBhYnMoYmVoX2NlbnRlcmVkWzFdIC0gKHN1bShiZWhfY2VudGVyZWRbLTFdLCBuYS5ybSA9IFRSVUUpIC8gbGVuZ3RoKGFsdGVycykpKS9ydiAjdGh1cyB3ZSBzdHJpdmUgZm9yIGEgaGlnaGVzdCBsb2NhbCBzaW1pbGFyaXR5IHNjb3JlIQ0KICANCiAgDQogIHJldHVybihzdGF0aXN0aWMpDQp9DQoNCmZpbmx1ZW5jZXBsb3QgPC0gZnVuY3Rpb24oYWx0ZXJzLCBtaW4sIG1heCwgZnVuLCBwYXJhbXMsIHJlc3VsdHM9VFJVRSwgcGxvdD1UUlVFKSB7DQogICNjaGVjayBjb3JyZWN0IG51bWJlciBvZiBwYXJhbWV0ZXJzIGFyZSBnaXZlbg0KICBpZiAobGVuZ3RoKGZ1bikgIT0gbGVuZ3RoKHBhcmFtcykpIHN0b3AoIlBsZWFzZSBwcm92aWRlIG9uZSAoYW5kIG9ubHkgb25lKSBwYXJhbWV0ZXIgZm9yIGVhY2ggb2YgdGhlIGJlaGF2aW9yYWwgZWZmZWN0cyEiKQ0KICANCiAgI2NhbGN1bHVhdGUgdmFsdWUgb2YgZXZhbHVhdGlvbiBmdW5jdGlvbg0KICBzIDwtIE5BDQogIGZvciAoaSBpbiBtaW46bWF4KSB7DQogICAgc1tpXSA8LSAwDQogICAgZm9yIChqIGluIDE6bGVuZ3RoKGZ1bikpIHsNCiAgICAgIHNbaV0gPC0gc1tpXSArIHBhcmFtc1tqXSpmdW5bW2pdXShpLCBhbHRlcnMsIG1pbiwgbWF4KSAgICAgIA0KICAgIH0NCiAgfQ0KICANCiAgI2NhbGN1bGF0ZSB0aGUgcHJvYmFiaWxpdGllcyAgDQogIHAgPC0gTkENCiAgZm9yIChpIGluIG1pbjptYXgpIHsNCiAgICBwW2ldIDwtIGV4cChzW2ldKSAvIHN1bShleHAocykpDQogIH0NCiAgDQogICNjYWxjdWxhdGUgdGhlIHByb2JhYmlsaXRpZXMgb2YgY2hvaWNlIHNldCAgDQogIHAyIDwtIE5BDQogIGZvciAoaSBpbiBtaW46bWF4KSB7DQogICAgaWYgKGk9PW1pbikgeyANCiAgICAgIHAyW2ldIDwtIGV4cChzW2ldKSAvIHN1bShleHAoc1tpXSkgKyBleHAoc1tpICsgMV0pKSANCiAgICB9IGVsc2UgaWYgKGk9PW1heCkgeyANCiAgICAgIHAyW2ldIDwtIGV4cChzW2ldKSAvIHN1bShleHAoc1tpXSkgKyBleHAoc1tpIC0gMV0pKQ0KICAgIH0gZWxzZSB7DQogICAgICBwMltpXSA8LSBleHAoc1tpXSkgLyBzdW0oZXhwKHNbaV0pICsgZXhwKHNbaSAtIDFdKSArIGV4cChzW2kgKyAxXSkpDQogICAgfQ0KICB9DQogIA0KICAjY2FsY3VsYXRlIHRoZSBwcm9iYWJpbGl0eSByYXRpbyAgDQogIHIgPC0gTkENCiAgZm9yIChpIGluIG1pbjptYXgpIHsNCiAgICByW2ldIDwtIHBbaV0gLyBwWzFdDQogIH0NCiAgDQogICNzb21lIHNpbXBsZSBwbG90cw0KICBpZiAocGxvdCkgeyANCiAgICBuYW1lIDwtIGRlcGFyc2Uoc3Vic3RpdHV0ZShmdW4pKQ0KICAgIG5hbWUgPC0gc3RyaW5ncjo6c3RyX3N1Yihhcy5jaGFyYWN0ZXIobmFtZSksIDYsIC0yKQ0KICAgIHBhcihtZnJvdz1jKDIsMikpDQogICAgcGxvdCh5PXMsIHg9bWluOm1heCwgeGxhYj0iZWdvIGJlaGF2aW9yYWwgc2NvcmUiLCB5bGFiPW5hbWUsIHR5cGU9ImIiKQ0KICAgIG10ZXh0KCJFVkFMVUFUSU9OIiwgbGluZT0xKQ0KICAgIG10ZXh0KHBhc3RlKCJhbHRlcnM6IiwgcGFzdGUwKGFsdGVycywgY29sbGFwc2U9IiwiKSkpDQogICAgcGxvdCh5PXAsIHg9bWluOm1heCwgeGxhYj0iZWdvIGJlaGF2aW9yYWwgc2NvcmUiLCB5bGFiPW5hbWUsIHlsaW09YygwLDEpLCB0eXBlPSJiIikNCiAgICBtdGV4dCgiUFJPQkFCSUxJVElFUyIsIGxpbmU9MSkNCiAgICBtdGV4dChwYXN0ZSgiYWx0ZXJzOiIsIHBhc3RlMChhbHRlcnMsIGNvbGxhcHNlPSIsIikpKQ0KICAgIHBsb3QoeT1wMiwgeD1taW46bWF4LCB4bGFiPSJlZ28gYmVoYXZpb3JhbCBzY29yZSIsIHlsYWI9bmFtZSwgeWxpbT1jKDAsMSksIHR5cGU9ImIiKQ0KICAgIG10ZXh0KCJQUk9CQUJJTElUSUVTIGNob2ljZSBzZXQiLCBsaW5lPTEpDQogICAgbXRleHQocGFzdGUoImFsdGVyczoiLCBwYXN0ZTAoYWx0ZXJzLCBjb2xsYXBzZT0iLCIpKSkNCiAgICBwbG90KHk9ciwgeD1taW46bWF4LCB4bGFiPSJlZ28gYmVoYXZpb3JhbCBzY29yZSIsIHlsYWI9bmFtZSwgdHlwZT0iYiIpDQogICAgbXRleHQoIlJBVElPUyIsIGxpbmU9MSkNCiAgICBtdGV4dChwYXN0ZSgiYWx0ZXJzOiIsIHBhc3RlMChhbHRlcnMsIGNvbGxhcHNlPSIsIikpKQ0KICB9DQogIA0KICAjcmV0dXJuIHJlc3VsdHMgZm9yIG1vcmUgZmFuY3kgcGxvdHRpbmcNCiAgaWYgKHJlc3VsdHMpIHsNCiAgICB4IDwtIG1pbjptYXgNCiAgICBkZiA8LSBkYXRhLmZyYW1lKHgsIHMsIHAscDIsIHIpDQogICAgcmV0dXJuKGRmKQ0KICB9DQogIA0KfQ0KfQ0KYGBgDQoNCg0KPGJyPg0KDQpXZSBjb25zaWRlciBkaWZmZXJlbnQgc2NlbmFyaW9zLCB3aGVyZSBlZ2/igJlzIGFsdGVycyBoYXZlIGRpZmZlcmVudCBydW5uaW5nIGZyZXF1ZW5jeSB2YWx1ZXMuDQoNCmBgYHtyfQ0KYWx0ZXJzMSA8LSByZXAoYygyKSwgNikNCmFsdGVyczIgPC0gcmVwKGMoNSksIDYpDQphbHRlcnMzIDwtIHJlcChjKDIsIDIsIDIsIDUsIDUsIDUpKQ0KYWx0ZXJzNCA8LSByZXAoYygxLCAyLCAzLCA0LCA1LCA2LCA3KSkNCmBgYA0KDQo8YnI+DQoNCk91ciBjbHViIGVzdGltYXRlczoNCg0KYGBge3J9DQojIGZyZXF1ZW5jeQ0KY2x1YjEgPC0gYygtMC4wMDgsIC0wLjA3MSwgMC4wMTcsIDQuNzYyKQ0KY2x1YjIgPC0gYygtMC4wNzcsIDAuMDQwLCAxLjM4NSwgNC40MTMpDQpjbHViMyA8LSBjKC0wLjA4NiwgLTAuMDA5LCAxLjQ5OSwgMi40MTApDQpjbHViNCA8LSBjKDAuMTQ5LCAtMC4yMDEsIC00LjQ4MiwgNi4yMTYpDQpjbHViNSA8LSBjKDAuMjQ3LCAwLjA2MiwgLTAuMTg0LCA5LjA2MikNCmBgYA0KDQo8YnI+DQoNCmBgYHtyfQ0KIyBzY2VuYXJpbyAxDQojIGNsdWIxDQpwMSA8LSBmaW5sdWVuY2VwbG90KGFsdGVycyA9IGFsdGVyczEsIA0KICAgICAgICAgICAgICAgICAgICAgIG1pbiA9IDEsIG1heCA9IDcsIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBULCBwbG90PUYsDQogICAgICAgICAgICAgICAgICAgICAgZnVuID0gbGlzdChmbGluZWFyLCBmcXVhZCwgZmF2QXR0SGlnaGVyLGZhdkF0dExvd2VyKSwgDQogICAgICAgICAgICAgICAgICAgICAgcGFyYW1zID0gY2x1YjEpDQojIGNsdWIyDQpwMiA8LSBmaW5sdWVuY2VwbG90KGFsdGVycyA9IGFsdGVyczEsIA0KICAgICAgICAgICAgICAgICAgICAgIG1pbiA9IDEsIG1heCA9IDcsIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBULCBwbG90PUYsDQogICAgICAgICAgICAgICAgICAgICAgZnVuID0gbGlzdChmbGluZWFyLCBmcXVhZCwgZmF2QXR0SGlnaGVyLGZhdkF0dExvd2VyKSwgDQogICAgICAgICAgICAgICAgICAgICAgcGFyYW1zID0gY2x1YjIpDQojIGNsdWIgMw0KcDMgPC0gZmlubHVlbmNlcGxvdChhbHRlcnMgPSBhbHRlcnMxLCANCiAgICAgICAgICAgICAgICAgICAgICBtaW4gPSAxLCBtYXggPSA3LCANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVCwgcGxvdD1GLA0KICAgICAgICAgICAgICAgICAgICAgIGZ1biA9IGxpc3QoZmxpbmVhciwgZnF1YWQsIGZhdkF0dEhpZ2hlcixmYXZBdHRMb3dlciksIA0KICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcyA9IGNsdWIzKQ0KIyBjbHViIDQNCnA0IDwtIGZpbmx1ZW5jZXBsb3QoYWx0ZXJzID0gYWx0ZXJzMSwgDQogICAgICAgICAgICAgICAgICAgICAgbWluID0gMSwgbWF4ID0gNywgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFQsIHBsb3Q9RiwNCiAgICAgICAgICAgICAgICAgICAgICBmdW4gPSBsaXN0KGZsaW5lYXIsIGZxdWFkLCBmYXZBdHRIaWdoZXIsZmF2QXR0TG93ZXIpLCANCiAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMgPSBjbHViNCkNCiMgY2x1YiA1DQpwNSA8LSBmaW5sdWVuY2VwbG90KGFsdGVycyA9IGFsdGVyczEsIA0KICAgICAgICAgICAgICAgICAgICAgIG1pbiA9IDEsIG1heCA9IDcsIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBULCBwbG90PUYsDQogICAgICAgICAgICAgICAgICAgICAgZnVuID0gbGlzdChmbGluZWFyLCBmcXVhZCwgZmF2QXR0SGlnaGVyLGZhdkF0dExvd2VyKSwgDQogICAgICAgICAgICAgICAgICAgICAgcGFyYW1zID0gY2x1YjUpDQoNCnBsb3QxIDwtIHJiaW5kKHAxLCBwMiwgcDMsIHA0LCBwNSkNCnBsb3QxJENsdWIgPC0gYXMuY2hhcmFjdGVyKHNvcnQocmVwKDE6NSw3KSkpDQpwbG90MSRzY2VuYXJpbyA8LSBwYXN0ZSgiQSkgQmVoYXZpb3IgYWx0ZXJzOiIsIHBhc3RlMChhbHRlcnMxLCBjb2xsYXBzZT0iLCAiICkpDQoNCiMgc2NlbmFyaW8gMg0KIyBjbHViMQ0KcDEgPC0gZmlubHVlbmNlcGxvdChhbHRlcnMgPSBhbHRlcnMyLCANCiAgICAgICAgICAgICAgICAgICAgICBtaW4gPSAxLCBtYXggPSA3LCANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVCwgcGxvdD1GLA0KICAgICAgICAgICAgICAgICAgICAgIGZ1biA9IGxpc3QoZmxpbmVhciwgZnF1YWQsIGZhdkF0dEhpZ2hlcixmYXZBdHRMb3dlciksIA0KICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcyA9IGNsdWIxKQ0KIyBjbHViMg0KcDIgPC0gZmlubHVlbmNlcGxvdChhbHRlcnMgPSBhbHRlcnMyLCANCiAgICAgICAgICAgICAgICAgICAgICBtaW4gPSAxLCBtYXggPSA3LCANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVCwgcGxvdD1GLA0KICAgICAgICAgICAgICAgICAgICAgIGZ1biA9IGxpc3QoZmxpbmVhciwgZnF1YWQsIGZhdkF0dEhpZ2hlcixmYXZBdHRMb3dlciksIA0KICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcyA9IGNsdWIyKQ0KIyBjbHViIDMNCnAzIDwtIGZpbmx1ZW5jZXBsb3QoYWx0ZXJzID0gYWx0ZXJzMiwgDQogICAgICAgICAgICAgICAgICAgICAgbWluID0gMSwgbWF4ID0gNywgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFQsIHBsb3Q9RiwNCiAgICAgICAgICAgICAgICAgICAgICBmdW4gPSBsaXN0KGZsaW5lYXIsIGZxdWFkLCBmYXZBdHRIaWdoZXIsZmF2QXR0TG93ZXIpLCANCiAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMgPSBjbHViMykNCiMgY2x1YiA0DQpwNCA8LSBmaW5sdWVuY2VwbG90KGFsdGVycyA9IGFsdGVyczIsIA0KICAgICAgICAgICAgICAgICAgICAgIG1pbiA9IDEsIG1heCA9IDcsIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBULCBwbG90PUYsDQogICAgICAgICAgICAgICAgICAgICAgZnVuID0gbGlzdChmbGluZWFyLCBmcXVhZCwgZmF2QXR0SGlnaGVyLGZhdkF0dExvd2VyKSwgDQogICAgICAgICAgICAgICAgICAgICAgcGFyYW1zID0gY2x1YjQpDQojIGNsdWIgNQ0KcDUgPC0gZmlubHVlbmNlcGxvdChhbHRlcnMgPSBhbHRlcnMyLCANCiAgICAgICAgICAgICAgICAgICAgICBtaW4gPSAxLCBtYXggPSA3LCANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVCwgcGxvdD1GLA0KICAgICAgICAgICAgICAgICAgICAgIGZ1biA9IGxpc3QoZmxpbmVhciwgZnF1YWQsIGZhdkF0dEhpZ2hlcixmYXZBdHRMb3dlciksIA0KICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcyA9IGNsdWI1KQ0KDQpwbG90MiA8LSByYmluZChwMSwgcDIsIHAzLCBwNCwgcDUpDQpwbG90MiRDbHViIDwtIGFzLmNoYXJhY3Rlcihzb3J0KHJlcCgxOjUsNykpKQ0KcGxvdDIkc2NlbmFyaW8gPC0gcGFzdGUoIkIpIEJlaGF2aW9yIGFsdGVyczoiLCBwYXN0ZTAoYWx0ZXJzMiwgY29sbGFwc2U9IiwgIiApKQ0KDQojIHNjZW5hcmlvIDMNCiMgY2x1YjENCnAxIDwtIGZpbmx1ZW5jZXBsb3QoYWx0ZXJzID0gYWx0ZXJzMywgDQogICAgICAgICAgICAgICAgICAgICAgbWluID0gMSwgbWF4ID0gNywgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFQsIHBsb3Q9RiwNCiAgICAgICAgICAgICAgICAgICAgICBmdW4gPSBsaXN0KGZsaW5lYXIsIGZxdWFkLCBmYXZBdHRIaWdoZXIsZmF2QXR0TG93ZXIpLCANCiAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMgPSBjbHViMSkNCiMgY2x1YjINCnAyIDwtIGZpbmx1ZW5jZXBsb3QoYWx0ZXJzID0gYWx0ZXJzMywgDQogICAgICAgICAgICAgICAgICAgICAgbWluID0gMSwgbWF4ID0gNywgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFQsIHBsb3Q9RiwNCiAgICAgICAgICAgICAgICAgICAgICBmdW4gPSBsaXN0KGZsaW5lYXIsIGZxdWFkLCBmYXZBdHRIaWdoZXIsZmF2QXR0TG93ZXIpLCANCiAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMgPSBjbHViMikNCiMgY2x1YiAzDQpwMyA8LSBmaW5sdWVuY2VwbG90KGFsdGVycyA9IGFsdGVyczMsIA0KICAgICAgICAgICAgICAgICAgICAgIG1pbiA9IDEsIG1heCA9IDcsIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBULCBwbG90PUYsDQogICAgICAgICAgICAgICAgICAgICAgZnVuID0gbGlzdChmbGluZWFyLCBmcXVhZCwgZmF2QXR0SGlnaGVyLGZhdkF0dExvd2VyKSwgDQogICAgICAgICAgICAgICAgICAgICAgcGFyYW1zID0gY2x1YjMpDQojIGNsdWIgNA0KcDQgPC0gZmlubHVlbmNlcGxvdChhbHRlcnMgPSBhbHRlcnMzLCANCiAgICAgICAgICAgICAgICAgICAgICBtaW4gPSAxLCBtYXggPSA3LCANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVCwgcGxvdD1GLA0KICAgICAgICAgICAgICAgICAgICAgIGZ1biA9IGxpc3QoZmxpbmVhciwgZnF1YWQsIGZhdkF0dEhpZ2hlcixmYXZBdHRMb3dlciksIA0KICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcyA9IGNsdWI0KQ0KIyBjbHViIDUNCnA1IDwtIGZpbmx1ZW5jZXBsb3QoYWx0ZXJzID0gYWx0ZXJzMywgDQogICAgICAgICAgICAgICAgICAgICAgbWluID0gMSwgbWF4ID0gNywgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFQsIHBsb3Q9RiwNCiAgICAgICAgICAgICAgICAgICAgICBmdW4gPSBsaXN0KGZsaW5lYXIsIGZxdWFkLCBmYXZBdHRIaWdoZXIsZmF2QXR0TG93ZXIpLCANCiAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMgPSBjbHViNSkNCg0KcGxvdDMgPC0gcmJpbmQocDEsIHAyLCBwMywgcDQsIHA1KQ0KcGxvdDMkQ2x1YiA8LSBhcy5jaGFyYWN0ZXIoc29ydChyZXAoMTo1LDcpKSkNCnBsb3QzJHNjZW5hcmlvIDwtIHBhc3RlKCJDKSBCZWhhdmlvciBhbHRlcnM6IiwgcGFzdGUwKGFsdGVyczMsIGNvbGxhcHNlPSIsICIgKSkNCg0KIyBzY2VuYXJpbyA0DQojIGNsdWIxDQpwMSA8LSBmaW5sdWVuY2VwbG90KGFsdGVycyA9IGFsdGVyczQsIA0KICAgICAgICAgICAgICAgICAgICAgIG1pbiA9IDEsIG1heCA9IDcsIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBULCBwbG90PUYsDQogICAgICAgICAgICAgICAgICAgICAgZnVuID0gbGlzdChmbGluZWFyLCBmcXVhZCwgZmF2QXR0SGlnaGVyLGZhdkF0dExvd2VyKSwgDQogICAgICAgICAgICAgICAgICAgICAgcGFyYW1zID0gY2x1YjEpDQojIGNsdWIyDQpwMiA8LSBmaW5sdWVuY2VwbG90KGFsdGVycyA9IGFsdGVyczQsIA0KICAgICAgICAgICAgICAgICAgICAgIG1pbiA9IDEsIG1heCA9IDcsIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBULCBwbG90PUYsDQogICAgICAgICAgICAgICAgICAgICAgZnVuID0gbGlzdChmbGluZWFyLCBmcXVhZCwgZmF2QXR0SGlnaGVyLGZhdkF0dExvd2VyKSwgDQogICAgICAgICAgICAgICAgICAgICAgcGFyYW1zID0gY2x1YjIpDQojIGNsdWIgMw0KcDMgPC0gZmlubHVlbmNlcGxvdChhbHRlcnMgPSBhbHRlcnM0LCANCiAgICAgICAgICAgICAgICAgICAgICBtaW4gPSAxLCBtYXggPSA3LCANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVCwgcGxvdD1GLA0KICAgICAgICAgICAgICAgICAgICAgIGZ1biA9IGxpc3QoZmxpbmVhciwgZnF1YWQsIGZhdkF0dEhpZ2hlcixmYXZBdHRMb3dlciksIA0KICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcyA9IGNsdWIzKQ0KIyBjbHViIDQNCnA0IDwtIGZpbmx1ZW5jZXBsb3QoYWx0ZXJzID0gYWx0ZXJzNCwgDQogICAgICAgICAgICAgICAgICAgICAgbWluID0gMSwgbWF4ID0gNywgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFQsIHBsb3Q9RiwNCiAgICAgICAgICAgICAgICAgICAgICBmdW4gPSBsaXN0KGZsaW5lYXIsIGZxdWFkLCBmYXZBdHRIaWdoZXIsZmF2QXR0TG93ZXIpLCANCiAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMgPSBjbHViNCkNCiMgY2x1YiA1DQpwNSA8LSBmaW5sdWVuY2VwbG90KGFsdGVycyA9IGFsdGVyczQsIA0KICAgICAgICAgICAgICAgICAgICAgIG1pbiA9IDEsIG1heCA9IDcsIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBULCBwbG90PUYsDQogICAgICAgICAgICAgICAgICAgICAgZnVuID0gbGlzdChmbGluZWFyLCBmcXVhZCwgZmF2QXR0SGlnaGVyLGZhdkF0dExvd2VyKSwgDQogICAgICAgICAgICAgICAgICAgICAgcGFyYW1zID0gY2x1YjUpDQoNCnBsb3Q0IDwtIHJiaW5kKHAxLCBwMiwgcDMsIHA0LCBwNSkNCnBsb3Q0JENsdWIgPC0gYXMuY2hhcmFjdGVyKHNvcnQocmVwKDE6NSw3KSkpDQpwbG90NCRzY2VuYXJpbyA8LSBwYXN0ZSgiRCkgQmVoYXZpb3IgYWx0ZXJzOiIsIHBhc3RlMChhbHRlcnM0LCBjb2xsYXBzZT0iLCAiICkpDQoNCg0KbXVsdGlwbG90IDwtIHJiaW5kKHBsb3QxLHBsb3QyLHBsb3QzLHBsb3Q0KQ0KbXVsdGlwbG90JEF0dHJpYnV0ZSA8LSAiRnJlcXVlbmN5Ig0KYGBgDQoNCjxicj4gDQoNCldlIGRvIHRoZSBzYW1lIGZvciBydW5uaW5nIHZvbHVtZS4NCg0KYGBge3J9DQojdm9sdW1lDQpjbHViMSA8LSBjKC0wLjA1NiwgLTAuMDMzLDAuMjc3LDMuNDc1KQ0KY2x1YjIgPC0gYygtMC4yMjAsMC4wMTIsMS43MjEsMS4yMjcpDQpjbHViMyA8LSBjKC0wLjEyOSwgLTAuMDA4LDEuOTI5LDEuNzgwKQ0KY2x1YjQgPC0gYygxLjI5NCwgLTAuNDA5LCAtMTguNjA4LCAxNi43NjEpDQpjbHViNSA8LSBjKC0wLjAxMiwgMC4wMjQsIDEuOTE1LCA4LjYxMCkNCg0KcDEgPC0gZmlubHVlbmNlcGxvdChhbHRlcnMgPSBhbHRlcnMxLCANCiAgICAgICAgICAgICAgICAgICAgICBtaW4gPSAxLCBtYXggPSA3LCANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVCwgcGxvdD1GLA0KICAgICAgICAgICAgICAgICAgICAgIGZ1biA9IGxpc3QoZmxpbmVhciwgZnF1YWQsIGZhdkF0dEhpZ2hlcixmYXZBdHRMb3dlciksIA0KICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcyA9IGNsdWIxKQ0KIyBjbHViMg0KcDIgPC0gZmlubHVlbmNlcGxvdChhbHRlcnMgPSBhbHRlcnMxLCANCiAgICAgICAgICAgICAgICAgICAgICBtaW4gPSAxLCBtYXggPSA3LCANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVCwgcGxvdD1GLA0KICAgICAgICAgICAgICAgICAgICAgIGZ1biA9IGxpc3QoZmxpbmVhciwgZnF1YWQsIGZhdkF0dEhpZ2hlcixmYXZBdHRMb3dlciksIA0KICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcyA9IGNsdWIyKQ0KIyBjbHViIDMNCnAzIDwtIGZpbmx1ZW5jZXBsb3QoYWx0ZXJzID0gYWx0ZXJzMSwgDQogICAgICAgICAgICAgICAgICAgICAgbWluID0gMSwgbWF4ID0gNywgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFQsIHBsb3Q9RiwNCiAgICAgICAgICAgICAgICAgICAgICBmdW4gPSBsaXN0KGZsaW5lYXIsIGZxdWFkLCBmYXZBdHRIaWdoZXIsZmF2QXR0TG93ZXIpLCANCiAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMgPSBjbHViMykNCiMgY2x1YiA0DQpwNCA8LSBmaW5sdWVuY2VwbG90KGFsdGVycyA9IGFsdGVyczEsIA0KICAgICAgICAgICAgICAgICAgICAgIG1pbiA9IDEsIG1heCA9IDcsIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBULCBwbG90PUYsDQogICAgICAgICAgICAgICAgICAgICAgZnVuID0gbGlzdChmbGluZWFyLCBmcXVhZCwgZmF2QXR0SGlnaGVyLGZhdkF0dExvd2VyKSwgDQogICAgICAgICAgICAgICAgICAgICAgcGFyYW1zID0gY2x1YjQpDQojIGNsdWIgNQ0KcDUgPC0gZmlubHVlbmNlcGxvdChhbHRlcnMgPSBhbHRlcnMxLCANCiAgICAgICAgICAgICAgICAgICAgICBtaW4gPSAxLCBtYXggPSA3LCANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVCwgcGxvdD1GLA0KICAgICAgICAgICAgICAgICAgICAgIGZ1biA9IGxpc3QoZmxpbmVhciwgZnF1YWQsIGZhdkF0dEhpZ2hlcixmYXZBdHRMb3dlciksIA0KICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcyA9IGNsdWI1KQ0KDQpwbG90MSA8LSByYmluZChwMSwgcDIsIHAzLCBwNCwgcDUpDQpwbG90MSRDbHViIDwtIGFzLmNoYXJhY3Rlcihzb3J0KHJlcCgxOjUsNykpKQ0KcGxvdDEkc2NlbmFyaW8gPC0gcGFzdGUoIkEpIEJlaGF2aW9yIGFsdGVyczoiLCBwYXN0ZTAoYWx0ZXJzMSwgY29sbGFwc2U9IiwgIiApKQ0KDQojIHNjZW5hcmlvIDINCiMgY2x1YjENCnAxIDwtIGZpbmx1ZW5jZXBsb3QoYWx0ZXJzID0gYWx0ZXJzMiwgDQogICAgICAgICAgICAgICAgICAgICAgbWluID0gMSwgbWF4ID0gNywgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFQsIHBsb3Q9RiwNCiAgICAgICAgICAgICAgICAgICAgICBmdW4gPSBsaXN0KGZsaW5lYXIsIGZxdWFkLCBmYXZBdHRIaWdoZXIsZmF2QXR0TG93ZXIpLCANCiAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMgPSBjbHViMSkNCiMgY2x1YjINCnAyIDwtIGZpbmx1ZW5jZXBsb3QoYWx0ZXJzID0gYWx0ZXJzMiwgDQogICAgICAgICAgICAgICAgICAgICAgbWluID0gMSwgbWF4ID0gNywgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFQsIHBsb3Q9RiwNCiAgICAgICAgICAgICAgICAgICAgICBmdW4gPSBsaXN0KGZsaW5lYXIsIGZxdWFkLCBmYXZBdHRIaWdoZXIsZmF2QXR0TG93ZXIpLCANCiAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMgPSBjbHViMikNCiMgY2x1YiAzDQpwMyA8LSBmaW5sdWVuY2VwbG90KGFsdGVycyA9IGFsdGVyczIsIA0KICAgICAgICAgICAgICAgICAgICAgIG1pbiA9IDEsIG1heCA9IDcsIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBULCBwbG90PUYsDQogICAgICAgICAgICAgICAgICAgICAgZnVuID0gbGlzdChmbGluZWFyLCBmcXVhZCwgZmF2QXR0SGlnaGVyLGZhdkF0dExvd2VyKSwgDQogICAgICAgICAgICAgICAgICAgICAgcGFyYW1zID0gY2x1YjMpDQojIGNsdWIgNA0KcDQgPC0gZmlubHVlbmNlcGxvdChhbHRlcnMgPSBhbHRlcnMyLCANCiAgICAgICAgICAgICAgICAgICAgICBtaW4gPSAxLCBtYXggPSA3LCANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVCwgcGxvdD1GLA0KICAgICAgICAgICAgICAgICAgICAgIGZ1biA9IGxpc3QoZmxpbmVhciwgZnF1YWQsIGZhdkF0dEhpZ2hlcixmYXZBdHRMb3dlciksIA0KICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcyA9IGNsdWI0KQ0KIyBjbHViIDUNCnA1IDwtIGZpbmx1ZW5jZXBsb3QoYWx0ZXJzID0gYWx0ZXJzMiwgDQogICAgICAgICAgICAgICAgICAgICAgbWluID0gMSwgbWF4ID0gNywgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFQsIHBsb3Q9RiwNCiAgICAgICAgICAgICAgICAgICAgICBmdW4gPSBsaXN0KGZsaW5lYXIsIGZxdWFkLCBmYXZBdHRIaWdoZXIsZmF2QXR0TG93ZXIpLCANCiAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMgPSBjbHViNSkNCg0KcGxvdDIgPC0gcmJpbmQocDEsIHAyLCBwMywgcDQsIHA1KQ0KcGxvdDIkQ2x1YiA8LSBhcy5jaGFyYWN0ZXIoc29ydChyZXAoMTo1LDcpKSkNCnBsb3QyJHNjZW5hcmlvIDwtIHBhc3RlKCJCKSBCZWhhdmlvciBhbHRlcnM6IiwgcGFzdGUwKGFsdGVyczIsIGNvbGxhcHNlPSIsICIgKSkNCg0KIyBzY2VuYXJpbyAzDQojIGNsdWIxDQpwMSA8LSBmaW5sdWVuY2VwbG90KGFsdGVycyA9IGFsdGVyczMsIA0KICAgICAgICAgICAgICAgICAgICAgIG1pbiA9IDEsIG1heCA9IDcsIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBULCBwbG90PUYsDQogICAgICAgICAgICAgICAgICAgICAgZnVuID0gbGlzdChmbGluZWFyLCBmcXVhZCwgZmF2QXR0SGlnaGVyLGZhdkF0dExvd2VyKSwgDQogICAgICAgICAgICAgICAgICAgICAgcGFyYW1zID0gY2x1YjEpDQojIGNsdWIyDQpwMiA8LSBmaW5sdWVuY2VwbG90KGFsdGVycyA9IGFsdGVyczMsIA0KICAgICAgICAgICAgICAgICAgICAgIG1pbiA9IDEsIG1heCA9IDcsIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBULCBwbG90PUYsDQogICAgICAgICAgICAgICAgICAgICAgZnVuID0gbGlzdChmbGluZWFyLCBmcXVhZCwgZmF2QXR0SGlnaGVyLGZhdkF0dExvd2VyKSwgDQogICAgICAgICAgICAgICAgICAgICAgcGFyYW1zID0gY2x1YjIpDQojIGNsdWIgMw0KcDMgPC0gZmlubHVlbmNlcGxvdChhbHRlcnMgPSBhbHRlcnMzLCANCiAgICAgICAgICAgICAgICAgICAgICBtaW4gPSAxLCBtYXggPSA3LCANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVCwgcGxvdD1GLA0KICAgICAgICAgICAgICAgICAgICAgIGZ1biA9IGxpc3QoZmxpbmVhciwgZnF1YWQsIGZhdkF0dEhpZ2hlcixmYXZBdHRMb3dlciksIA0KICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcyA9IGNsdWIzKQ0KIyBjbHViIDQNCnA0IDwtIGZpbmx1ZW5jZXBsb3QoYWx0ZXJzID0gYWx0ZXJzMywgDQogICAgICAgICAgICAgICAgICAgICAgbWluID0gMSwgbWF4ID0gNywgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFQsIHBsb3Q9RiwNCiAgICAgICAgICAgICAgICAgICAgICBmdW4gPSBsaXN0KGZsaW5lYXIsIGZxdWFkLCBmYXZBdHRIaWdoZXIsZmF2QXR0TG93ZXIpLCANCiAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMgPSBjbHViNCkNCiMgY2x1YiA1DQpwNSA8LSBmaW5sdWVuY2VwbG90KGFsdGVycyA9IGFsdGVyczMsIA0KICAgICAgICAgICAgICAgICAgICAgIG1pbiA9IDEsIG1heCA9IDcsIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBULCBwbG90PUYsDQogICAgICAgICAgICAgICAgICAgICAgZnVuID0gbGlzdChmbGluZWFyLCBmcXVhZCwgZmF2QXR0SGlnaGVyLGZhdkF0dExvd2VyKSwgDQogICAgICAgICAgICAgICAgICAgICAgcGFyYW1zID0gY2x1YjUpDQoNCnBsb3QzIDwtIHJiaW5kKHAxLCBwMiwgcDMsIHA0LCBwNSkNCnBsb3QzJENsdWIgPC0gYXMuY2hhcmFjdGVyKHNvcnQocmVwKDE6NSw3KSkpDQpwbG90MyRzY2VuYXJpbyA8LSBwYXN0ZSgiQykgQmVoYXZpb3IgYWx0ZXJzOiIsIHBhc3RlMChhbHRlcnMzLCBjb2xsYXBzZT0iLCAiICkpDQoNCiMgc2NlbmFyaW8gNA0KIyBjbHViMQ0KcDEgPC0gZmlubHVlbmNlcGxvdChhbHRlcnMgPSBhbHRlcnM0LCANCiAgICAgICAgICAgICAgICAgICAgICBtaW4gPSAxLCBtYXggPSA3LCANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVCwgcGxvdD1GLA0KICAgICAgICAgICAgICAgICAgICAgIGZ1biA9IGxpc3QoZmxpbmVhciwgZnF1YWQsIGZhdkF0dEhpZ2hlcixmYXZBdHRMb3dlciksIA0KICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcyA9IGNsdWIxKQ0KIyBjbHViMg0KcDIgPC0gZmlubHVlbmNlcGxvdChhbHRlcnMgPSBhbHRlcnM0LCANCiAgICAgICAgICAgICAgICAgICAgICBtaW4gPSAxLCBtYXggPSA3LCANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVCwgcGxvdD1GLA0KICAgICAgICAgICAgICAgICAgICAgIGZ1biA9IGxpc3QoZmxpbmVhciwgZnF1YWQsIGZhdkF0dEhpZ2hlcixmYXZBdHRMb3dlciksIA0KICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcyA9IGNsdWIyKQ0KIyBjbHViIDMNCnAzIDwtIGZpbmx1ZW5jZXBsb3QoYWx0ZXJzID0gYWx0ZXJzNCwgDQogICAgICAgICAgICAgICAgICAgICAgbWluID0gMSwgbWF4ID0gNywgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFQsIHBsb3Q9RiwNCiAgICAgICAgICAgICAgICAgICAgICBmdW4gPSBsaXN0KGZsaW5lYXIsIGZxdWFkLCBmYXZBdHRIaWdoZXIsZmF2QXR0TG93ZXIpLCANCiAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMgPSBjbHViMykNCiMgY2x1YiA0DQpwNCA8LSBmaW5sdWVuY2VwbG90KGFsdGVycyA9IGFsdGVyczQsIA0KICAgICAgICAgICAgICAgICAgICAgIG1pbiA9IDEsIG1heCA9IDcsIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBULCBwbG90PUYsDQogICAgICAgICAgICAgICAgICAgICAgZnVuID0gbGlzdChmbGluZWFyLCBmcXVhZCwgZmF2QXR0SGlnaGVyLGZhdkF0dExvd2VyKSwgDQogICAgICAgICAgICAgICAgICAgICAgcGFyYW1zID0gY2x1YjQpDQojIGNsdWIgNQ0KcDUgPC0gZmlubHVlbmNlcGxvdChhbHRlcnMgPSBhbHRlcnM0LCANCiAgICAgICAgICAgICAgICAgICAgICBtaW4gPSAxLCBtYXggPSA3LCANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVCwgcGxvdD1GLA0KICAgICAgICAgICAgICAgICAgICAgIGZ1biA9IGxpc3QoZmxpbmVhciwgZnF1YWQsIGZhdkF0dEhpZ2hlcixmYXZBdHRMb3dlciksIA0KICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcyA9IGNsdWI1KQ0KDQpwbG90NCA8LSByYmluZChwMSwgcDIsIHAzLCBwNCwgcDUpDQpwbG90NCRDbHViIDwtIGFzLmNoYXJhY3Rlcihzb3J0KHJlcCgxOjUsNykpKQ0KcGxvdDQkc2NlbmFyaW8gPC0gcGFzdGUoIkQpIEJlaGF2aW9yIGFsdGVyczoiLCBwYXN0ZTAoYWx0ZXJzNCwgY29sbGFwc2U9IiwgIiApKQ0KDQoNCm11bHRpcGxvdDIgPC0gcmJpbmQocGxvdDEscGxvdDIscGxvdDMscGxvdDQpDQptdWx0aXBsb3QyJEF0dHJpYnV0ZSA8LSAiVm9sdW1lIg0KDQojIG1lcmdlIHRoZW0gdG9nZXRoZXINCm11bHRpcGxvdCA8LSByYmluZChtdWx0aXBsb3QsIG11bHRpcGxvdDIpDQoNCmBgYA0KDQojIFBsb3QNCg0KV2UgY3JlYXRlIGEgbmljZSBtdWx0aXBhbmVsIHBsb3Qgb2YgdGhlIGRpZmZlcmVudCBzY2VuYXJpb3M6DQoNCg0KYGBge3IgZmlnMywgY2xhc3Muc291cmNlID0gJ2ZvbGQtaGlkZScsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD04fQ0KDQoNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkobGVtb24pICMgZm9yIHJlcGVhdGluZyBheGlzIGxhYmVscyBhY3Jvc3MgZmFjZXRzDQpsaWJyYXJ5KGdndGV4dCkgICNmb3IgY29sb3JpemluZyBwYXJ0cyBvZiB0aGUgdGl0bGUuIA0KDQpnZ3Bsb3QoDQogIGRhdGEgPSBtdWx0aXBsb3QsIA0KICBhZXMoeCwgcywgZ3JvdXA9Q2x1YiwgY29sb3I9Q2x1YikpICsgDQogIGdlb21fbGluZShzaXplID0gMSkgKyBnZW9tX3BvaW50KGFlcyhzaGFwZT1DbHViKSwgc2l6ZSA9IDIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9IjxiPjxzcGFuIHN0eWxlID0gJ2ZvbnQtc2l6ZToxOHB0Jz5JbmZsdWVuY2UgZWZmZWN0cyBvbiBydW5uaW5nIGZyZXF1ZW5jeTwvc3Bhbj48L2I+PGJyPjxzcGFuIHN0eWxlID0gJ2ZvbnQtc2l6ZToxNHB0Jz5FdmFsdWF0aW9uIG9mIHByb3NwZWN0aXZlIGJlaGF2aW9yIGJhc2VkIG9uIDxpPmxpbmVhcjwvaT4gYW5kIDxpPnF1YWRyYXRpYzwvaT4gc2hhcGUgZWZmZWN0cyBhbmQgdGhlIDxpPmF2ZXJhZ2UgYXR0cmFjdGlvbiB0b3dhcmRzIGhpZ2hlcjwvaT4gYW5kIDxpPmxvd2VyPC9pPiBlZmZlY3RzLiIsDQogICAgICAgY2FwdGlvbiA9ICJOb3RlczogVGhlIHktYXhpcyByZXByZXNlbnRzIHRoZSBldmFsdWF0aW9uIGZ1bmN0aW9uIHN0YXRpc3RpYzsgdGhlIHgtYXhpcyByZXByZXNlbnRzIGRpZmZlcmVudCB2YWx1ZXMgZm9yIGVnb+KAmXMgcHJvc3BlY3RpdmUgYmVoYXZpb3IuIExpbmVzIHJlcHJlc2VudCB0aGUgcHJlZGljdGVkIOKAmGF0dHJhY3RpdmVuZXNz4oCZIG9mIGRpZmZlcmVudCBiZWhhdmlvciB2YWx1ZXMuIFBhbmVscyBBLUQgcmVwcmVzZW50IGRpZmZlcmVudCBzY2VuYXJpb3Mgd2l0aCBkaWZmZXJlbnQgdmFsdWVzIGZvciB0aGUgYmVoYXZpb3Igb2YgZWdv4oCZcyBhbHRlcnMuIEJlaGF2aW9yIGR5bmFtaWNzIHByZXNlbnRlZCBoZXJlIHdvdWxkIGJlIGNvbXBvdW5kZWQgaGFkIHRoZSBvYmplY3RpdmUgZnVuY3Rpb24gY29udGFpbmVkIG1vcmUgZWZmZWN0cyAoZS5nLiwgaW5kZWdyZWUsIGdlbmRlcikuIikgKw0KICANCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgtMTAsIDIwLCBieSA9IDIuNSkpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgxLCA3LCBieSA9IDEpKSArDQogIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXM9YyhyZXAoMTksIDUpKSkgKw0KICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1jKCIjRTY5RjAwIiwgIiM1NkI0RTkiLCAiIzAwMDAwMCIsICIjMDA5RTczIiwgIiNGMEU0NDIiKSkgKw0KICBmYWNldF9ncmlkKEF0dHJpYnV0ZX5zY2VuYXJpbywgDQogICAgICAgICAgICAgc3dpdGNoID0gInkiDQogICMgICAgICAgICAsIHNjYWxlcyA9ICJmcmVlX3kiDQogICkgKw0KICB5bGFiKCJFdmFsdWF0aW9uIGZ1bmN0aW9uIHN0YXRpc3RpYyIpICsgeGxhYigiRWdvJ3MgcHJvc3BlY3RpdmUgYmVoYXZpb3IiKSArDQogIA0KdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dGJveF9zaW1wbGUoDQogICAgcGFkZGluZyA9IG1hcmdpbig1LjUsIDUuNSwgNS41LCA1LjUpLA0KICAgIG1hcmdpbiA9IG1hcmdpbigwLCAwLCA1LjUsIDApLA0KICAgIGZpbGwgPSAibGlnaHRzdGVlbGJsdWUyIiwNCiAgICBsaW5laGVpZ2h0PTEsDQogICAgciA9IGdyaWQ6OnVuaXQoOCwgInB0IikpLA0KICAgIA0KICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dGJveF9zaW1wbGUoDQogICAgcGFkZGluZyA9IG1hcmdpbigyLCAyLCAyLCAyKSwNCiAgICBtYXJnaW4gPSBtYXJnaW4oMCwgMCwgMiwgMCksDQogICAgZmlsbCA9ICJsaWdodHN0ZWVsYmx1ZTIiLA0KICAgIGxpbmVoZWlnaHQ9MSwNCiAgICB2anVzdD0xLjUsDQogICAgciA9IGdyaWQ6OnVuaXQoOCwgInB0IikpLA0KICAgIA0KICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dGJveCgNCiAgICAgICAgICBzaXplID0gOSwNCiAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIsIGZpbGwgPSAiIzVENzI5RCIsIGJveC5jb2xvciA9ICIjNEE2MThDIiwNCiAgICAgICAgICBoYWxpZ24gPSAwLjUsIGxpbmV0eXBlID0gMSwgciA9IHVuaXQoNSwgInB0IiksIHdpZHRoID0gdW5pdCgxLCAibnBjIiksDQogICAgICAgICAgcGFkZGluZyA9IG1hcmdpbigyLCAwLCAxLCAwKSwgbWFyZ2luID0gbWFyZ2luKDMsIDMsIDMsIDMpDQogICAgICAgICksDQogICAgDQogICAgc3RyaXAudGV4dC55ID0gZWxlbWVudF90ZXh0Ym94X3NpbXBsZSgNCiAgICAgICAgICBzaXplPTEyLA0KICAgICAgICAgIGZhY2U9ImJvbGQiLA0KICAgICAgICAgIHZqdXN0PTEpLA0KDQoNCiAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHN0cmlwLnBsYWNlbWVudCA9ICJvdXRzaWRlIiwNCiAgICANCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplPTkpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwNCiAgICAgICAgYXhpcy5saW5lLnkgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiYmxhY2siLCBzaXplPS42KQ0KKQ0KDQpnZ3NhdmUoImluZnBsLnBkZiIpDQogIA0KDQpgYGANCg0KDQo=