Load the data
library(dplyr)
library(ggplot2)
library(lme4)
library(broom)
library(jtools)
plot_estimates <- function(glmod, title=NULL,
subtitle=NULL, estimate_name="odds"){
vline_intercept = 0
(glmod
%>% tidy(conf.int = T)
%>% mutate(is_significant=p.value < 0.05)
-> coefs)
if (family(glmod)$family %in% c("binomial", "Gamma")){
(mutate_at(
coefs,
vars("estimate","conf.low","conf.high"),
~exp(.))
%>% mutate(std.error=std.error*estimate)
%>% mutate(term=str_remove(term, " TRUE"))
-> coefs)
vline_intercept = 1
}
if(exists('group', where=coefs))
coefs %<>% filter(group == "fixed")
(coefs
%>% ggcoef(sort = "ascending",
vline_intercept = vline_intercept,
mapping = aes_string(y = "term", x = "estimate", color="is_significant")
)
+ scale_color_manual(values=c("black", "#F4511E"))
+ scale_y_discrete(name="Variable")
+ scale_x_continuous(name=sprintf("Estimate (%s)", estimate_name))
+ theme_minimal()
+ theme(legend.position = "none")
+ ggtitle(title, subtitle = subtitle))
}
Trials <- read.csv("trials.csv")
Targets <- read.csv("target-metadata.csv")
Trials <- left_join(Trials, Targets, by=c("task", "stimuli"))
Trials$features_pretty <- factor(Trials$features_pretty,
levels = c("baseline-deficient", "+position", "+size", "+color", "+speed",
"+direction", "+area increase", "baseline-charged",
"-position", "-size", "-color", "-speed",
"-direction", "-area increase"),
ordered = T)
Model Fitting
Correctness - Speed
g_speed <- glmer(correct ~
position +
color +
size +
direction +
size_increase +
(1|subject) +
(1|scene),
data=filter(Trials, task=="speed"),
family="binomial")
summary(g_speed)
Generalized linear mixed model fit by maximum likelihood (Laplace Approximation) ['glmerMod']
Family: binomial ( logit )
Formula: correct ~ position + color + size + direction + size_increase + (1 | subject) + (1 | scene)
Data: filter(Trials, task == "speed")
AIC BIC logLik deviance df.resid
2498.7 2545.0 -1241.3 2482.7 2392
Scaled residuals:
Min 1Q Median 3Q Max
-6.7437 -0.6043 0.2306 0.5945 9.7967
Random effects:
Groups Name Variance Std.Dev.
subject (Intercept) 0.8610 0.9279
scene (Intercept) 0.6222 0.7888
Number of obs: 2400, groups: subject, 61; scene, 10
Fixed effects:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -1.45948 0.29661 -4.920 8.63e-07 ***
position TRUE 1.06561 0.11327 9.408 < 2e-16 ***
color TRUE 0.66738 0.11415 5.847 5.02e-09 ***
size TRUE 0.08019 0.11943 0.671 0.502
direction TRUE 1.54940 0.11403 13.588 < 2e-16 ***
size_increase TRUE -0.07778 0.12126 -0.641 0.521
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Correlation of Fixed Effects:
(Intr) psTRUE clTRUE szTRUE drTRUE
positinTRUE -0.100
color TRUE -0.088 -0.075
size TRUE -0.048 -0.161 -0.183
directnTRUE -0.111 -0.015 -0.052 -0.146
sz_ncrsTRUE -0.042 -0.186 -0.209 -0.268 -0.174
plot_estimates(g_speed, "Speed Task")
binding factor and character vector, coercing into character vectorbinding character and factor vector, coercing into character vector

Correctness - Direction
g_direction <- glmer(correct ~
position +
color +
size +
speed +
size_increase +
(1|subject) +
(1|scene),
data=filter(Trials, task=="direction"),
family="binomial")
summary(g_direction)
Generalized linear mixed model fit by maximum likelihood (Laplace Approximation) ['glmerMod']
Family: binomial ( logit )
Formula: correct ~ position + color + size + speed + size_increase + (1 | subject) + (1 | scene)
Data: filter(Trials, task == "direction")
AIC BIC logLik deviance df.resid
2440.5 2486.8 -1212.3 2424.5 2392
Scaled residuals:
Min 1Q Median 3Q Max
-4.0627 -0.5641 -0.2490 0.6116 8.2269
Random effects:
Groups Name Variance Std.Dev.
subject (Intercept) 1.6255 1.2749
scene (Intercept) 0.3044 0.5517
Number of obs: 2400, groups: subject, 61; scene, 10
Fixed effects:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -2.17183 0.26879 -8.080 6.47e-16 ***
position TRUE 1.16983 0.11665 10.029 < 2e-16 ***
color TRUE 0.36758 0.11728 3.134 0.001724 **
size TRUE 0.44090 0.11707 3.766 0.000166 ***
speed TRUE 0.97281 0.11629 8.366 < 2e-16 ***
size_increase TRUE -0.06062 0.12104 -0.501 0.616465
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Correlation of Fixed Effects:
(Intr) psTRUE clTRUE szTRUE spTRUE
positinTRUE -0.137
color TRUE -0.090 -0.120
size TRUE -0.095 -0.115 -0.163
speed TRUE -0.127 -0.060 -0.131 -0.124
sz_ncrsTRUE -0.056 -0.176 -0.215 -0.210 -0.183
plot_estimates(g_direction, "Direction Task")
binding factor and character vector, coercing into character vectorbinding character and factor vector, coercing into character vector

Number of views (Plays)
Trials %>%
mutate(num_trials = factor(num_trials)) %>%
group_by(task, features_pretty, correct, num_trials) %>%
summarise(count=n(), group=group[1]) %>%
ungroup() %>%
mutate(num_trials = as.numeric(num_trials)) %>%
arrange(task, features_pretty) %>%
ggplot(aes(x=num_trials, y=count, color=group, linetype=correct)) +
geom_line(size=1.2) +
scale_x_continuous(breaks = c(1,2,3)) +
scale_linetype_manual(values=c("twodash", "solid")) +
ylab("Count") +
xlab("Number of Views") +
facet_grid(task~features_pretty) +
theme_minimal() +
theme(strip.text = element_text(angle = 90, hjust = 0)) +
theme(legend.position = "bottom")

Which features mislead?
scale_this <- function(x){(x - mean(x, na.rm=TRUE)) / sd(x, na.rm=TRUE)}
Scenes = read.csv("scenes.csv")
IncorrectSelections =
filter(Scenes, name < 50, count > 0) %>%
mutate(task = ifelse(str_detect(stimulus, "speed"), "speed", "direction")) %>%
rename(speed=change)
ScaledIncorrectSelections = mutate_at(IncorrectSelections,
vars(matches('saliency|speed')),
scale_this) %>%
mutate(direction = scale_this(abs(mean(theta)-theta)))
Error count - Speed
g_errors_speed = glm(count ~ speed +
(saliency_direction +
saliency_color +
saliency_xy1 +
saliency_xy2 +
saliency_size)*speed,
data=filter(ScaledIncorrectSelections, task=="speed"),
family=Gamma(link = 'log'))
summary(g_errors_speed)
Call:
glm(formula = count ~ speed + (saliency_direction + saliency_color +
saliency_xy1 + saliency_xy2 + saliency_size) * speed, family = Gamma(link = "log"),
data = filter(ScaledIncorrectSelections, task == "speed"))
Deviance Residuals:
Min 1Q Median 3Q Max
-0.98964 -0.37617 -0.14822 0.09759 2.06064
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.40990 0.02356 17.399 < 2e-16 ***
speed 0.23589 0.02495 9.453 < 2e-16 ***
saliency_direction 0.17222 0.02182 7.893 1.25e-14 ***
saliency_color 0.04042 0.02264 1.785 0.07470 .
saliency_xy1 0.11038 0.03662 3.015 0.00267 **
saliency_xy2 0.08845 0.03734 2.369 0.01815 *
saliency_size 0.05002 0.02403 2.082 0.03777 *
speed:saliency_direction 0.11026 0.02365 4.662 3.80e-06 ***
speed:saliency_color 0.01700 0.02184 0.778 0.43668
speed:saliency_xy1 0.07753 0.03860 2.009 0.04498 *
speed:saliency_xy2 0.01533 0.03855 0.398 0.69108
speed:saliency_size 0.02078 0.02351 0.884 0.37719
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for Gamma family taken to be 0.3189045)
Null deviance: 245.67 on 664 degrees of freedom
Residual deviance: 154.99 on 653 degrees of freedom
AIC: 1379.6
Number of Fisher Scoring iterations: 7
plot_estimates(g_errors_speed,
title = "Errors",
subtitle = "Speed task",
estimate_name = "count")

Error count - Direction
g_errors_direction = glm(count ~ direction +
(saliency_speed+
saliency_color +
saliency_xy1 +
saliency_xy2 +
saliency_size)*direction,
data=filter(ScaledIncorrectSelections, task=="direction"),
family=Gamma(link = 'log'))
summary(g_errors_direction)
Call:
glm(formula = count ~ direction + (saliency_speed + saliency_color +
saliency_xy1 + saliency_xy2 + saliency_size) * direction,
family = Gamma(link = "log"), data = filter(ScaledIncorrectSelections,
task == "direction"))
Deviance Residuals:
Min 1Q Median 3Q Max
-1.0219 -0.4208 -0.1653 0.1909 1.6568
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.439153 0.019882 22.088 < 2e-16 ***
direction 0.271668 0.021539 12.613 < 2e-16 ***
saliency_speed 0.113799 0.017853 6.374 3.01e-10 ***
saliency_color 0.062911 0.020942 3.004 0.002742 **
saliency_xy1 0.015986 0.036124 0.443 0.658220
saliency_xy2 0.219453 0.035706 6.146 1.22e-09 ***
saliency_size -0.031221 0.018622 -1.677 0.093985 .
direction:saliency_speed -0.002005 0.020260 -0.099 0.921191
direction:saliency_color 0.042631 0.020231 2.107 0.035391 *
direction:saliency_xy1 0.153920 0.036695 4.195 3.02e-05 ***
direction:saliency_xy2 -0.131537 0.035738 -3.681 0.000247 ***
direction:saliency_size 0.035604 0.021198 1.680 0.093400 .
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for Gamma family taken to be 0.2961768)
Null deviance: 319.72 on 864 degrees of freedom
Residual deviance: 203.51 on 853 degrees of freedom
AIC: 1875.9
Number of Fisher Scoring iterations: 8
plot_estimates(g_errors_direction,
title = "Errors",
subtitle = "Direction task",
estimate_name = "count")

rbind(
interact_plot(g_errors_speed, "speed", "saliency_direction")$data
%>% mutate(variable="saliency_direction"),
interact_plot(g_errors_speed, "speed", "saliency_color")$data
%>% mutate(variable="saliency_color"),
interact_plot(g_errors_speed, "speed", "saliency_xy1")$data
%>% mutate(variable="saliency_xy1")
) %>%
ggplot(aes(x=speed, y=count, color=modx_group, linetype=modx_group)) +
geom_line(size=.85) +
scale_color_brewer(
palette="Blues",
breaks=c("+ 1 SD", "Mean", "- 1 SD"),
direction=-1) +
facet_wrap(~ variable) +
theme_minimal() +
theme(legend.title = element_blank(),
legend.position = "bottom") +
ggtitle(
"Errors - Significant interaction terms",
"Speed task")
invalid factor level, NA generatedinvalid factor level, NA generated

rbind(
interact_plot(g_errors_direction, "direction", "saliency_xy1")$data
%>% mutate(variable="saliency_xy1"),
interact_plot(g_errors_direction, "direction", "saliency_color")$data
%>% mutate(variable="saliency_color"),
interact_plot(g_errors_direction, "direction", "saliency_xy2")$data
%>% mutate(variable="saliency_xy2")
) %>%
ggplot(aes(x=direction, y=count, color=modx_group, linetype=modx_group)) +
geom_line(size=.85) +
scale_color_brewer(
palette="Blues",
breaks=c("+ 1 SD", "Mean", "- 1 SD"),
direction=-1) +
facet_wrap(~ variable) +
theme_minimal() +
theme(legend.title = element_blank(),
legend.position = "bottom") +
ggtitle("Errors - Significant interaction terms",
"Direction task")
invalid factor level, NA generatedinvalid factor level, NA generated

LS0tCnRpdGxlOiAiQW5hbHlzaXMgLSBTYWxpZW5jeSBEZWZpY2l0IGFuZCBNb3Rpb24gT3V0bGllciBEZXRlY3Rpb24gaW4gQW5pbWF0ZWQgU2NhdHRlcnBsb3RzIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojIyBMb2FkIHRoZSBfZGF0YV8KCmBgYHtyfQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkobG1lNCkKbGlicmFyeShicm9vbSkKbGlicmFyeShqdG9vbHMpCgpwbG90X2VzdGltYXRlcyA8LSBmdW5jdGlvbihnbG1vZCwgdGl0bGU9TlVMTCwgCiAgc3VidGl0bGU9TlVMTCwgZXN0aW1hdGVfbmFtZT0ib2RkcyIpewogIAogICAgdmxpbmVfaW50ZXJjZXB0ID0gMAogIAogICAgKGdsbW9kCiAgICAgICU+JSB0aWR5KGNvbmYuaW50ID0gVCkKICAgICAgJT4lIG11dGF0ZShpc19zaWduaWZpY2FudD1wLnZhbHVlIDwgMC4wNSkgCiAgICAgIC0+IGNvZWZzKQogICAgCiAgICBpZiAoZmFtaWx5KGdsbW9kKSRmYW1pbHkgJWluJSBjKCJiaW5vbWlhbCIsICJHYW1tYSIpKXsKICAgICAgKG11dGF0ZV9hdCggCiAgICAgICAgY29lZnMsCiAgICAgICAgdmFycygiZXN0aW1hdGUiLCJjb25mLmxvdyIsImNvbmYuaGlnaCIpLCAKICAgICAgICB+ZXhwKC4pKQogICAgICAlPiUgbXV0YXRlKHN0ZC5lcnJvcj1zdGQuZXJyb3IqZXN0aW1hdGUpCiAgICAgICU+JSBtdXRhdGUodGVybT1zdHJfcmVtb3ZlKHRlcm0sICIgVFJVRSIpKQogICAgICAtPiAgY29lZnMpCiAgICAgIAogICAgICB2bGluZV9pbnRlcmNlcHQgPSAxCiAgICB9CiAgICAKICAgIGlmKGV4aXN0cygnZ3JvdXAnLCB3aGVyZT1jb2VmcykpCiAgICAgIGNvZWZzICU8PiUgZmlsdGVyKGdyb3VwID09ICJmaXhlZCIpCgogICAgKGNvZWZzCiAgICAlPiUgZ2djb2VmKHNvcnQgPSAiYXNjZW5kaW5nIiwKICAgICAgdmxpbmVfaW50ZXJjZXB0ID0gdmxpbmVfaW50ZXJjZXB0LAogICAgICBtYXBwaW5nID0gYWVzX3N0cmluZyh5ID0gInRlcm0iLCB4ID0gImVzdGltYXRlIiwgY29sb3I9ImlzX3NpZ25pZmljYW50IikKICAgICkKICAgICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCJibGFjayIsICIjRjQ1MTFFIikpCiAgICArIHNjYWxlX3lfZGlzY3JldGUobmFtZT0iVmFyaWFibGUiKQogICAgKyBzY2FsZV94X2NvbnRpbnVvdXMobmFtZT1zcHJpbnRmKCJFc3RpbWF0ZSAoJXMpIiwgZXN0aW1hdGVfbmFtZSkpCiAgICArIHRoZW1lX21pbmltYWwoKQogICAgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCiAgICArIGdndGl0bGUodGl0bGUsIHN1YnRpdGxlID0gc3VidGl0bGUpKQp9CgoKCmBgYAoKCmBgYHtyIGVjaG89VFJVRX0KVHJpYWxzICA8LSByZWFkLmNzdigidHJpYWxzLmNzdiIpClRhcmdldHMgPC0gcmVhZC5jc3YoInRhcmdldC1tZXRhZGF0YS5jc3YiKQpUcmlhbHMgIDwtIGxlZnRfam9pbihUcmlhbHMsIFRhcmdldHMsIGJ5PWMoInRhc2siLCAic3RpbXVsaSIpKQpgYGAKCmBgYHtyfQpUcmlhbHMkZmVhdHVyZXNfcHJldHR5IDwtIGZhY3RvcihUcmlhbHMkZmVhdHVyZXNfcHJldHR5LAogIGxldmVscyA9IGMoImJhc2VsaW5lLWRlZmljaWVudCIsICIrcG9zaXRpb24iLCAiK3NpemUiLCAiK2NvbG9yIiwgIitzcGVlZCIsCiAgICAiK2RpcmVjdGlvbiIsICIrYXJlYSBpbmNyZWFzZSIsICJiYXNlbGluZS1jaGFyZ2VkIiwgCiAgICAiLXBvc2l0aW9uIiwgIi1zaXplIiwgIi1jb2xvciIsICItc3BlZWQiLAogICAgIi1kaXJlY3Rpb24iLCAiLWFyZWEgaW5jcmVhc2UiKSwKICBvcmRlcmVkID0gVCkKYGBgCgojIyBDYWxjdWxhdGUgQWNjdXJhY3kKCmBgYHtyfQpBY2N1cmFjeSA8LSBUcmlhbHMgJT4lCiAgZ3JvdXBfYnkodGFzaywgZ3JvdXAsIGZlYXR1cmVzLCBzdGltdWxpKSAlPiUKICBzdW1tYXJpc2UoYWNjdXJhY3kgPSBzdW0oY29ycmVjdCkvbigpLAogICAgbiA9IG4oKSwKICAgIGZlYXR1cmVzX3ByZXR0eSA9IGZlYXR1cmVzX3ByZXR0eVsxXSwKICAgIHNjZW5lID0gc2NlbmVbMV0pICU+JQogIHVuZ3JvdXAoKQpgYGAKCiMjIFBsb3QgQWNjdXJhY3kgeCBUYXNrIHggQ29uZGl0aW9uCgoKYGBge3J9CmdncGxvdChBY2N1cmFjeSkgKwogIGdlb21fYm94cGxvdChhZXMoeD1mZWF0dXJlc19wcmV0dHksIHk9YWNjdXJhY3ksIGZpbGw9Z3JvdXApKSArIAogIHlsYWIoIkFjY3VyYWN5IikgKwogIHhsYWIoIkNvbmRpdGlvbiIpICsKICBnZ3RpdGxlKCJUYXNrcyIpICsKICBmYWNldF93cmFwKH50YXNrKSArCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGFuZ2xlID0gLTkwLCBoanVzdCA9IDApKQpgYGAKCiMjIE1vZGVsIEZpdHRpbmcKCiMjIyBDb3JyZWN0bmVzcyAtIFNwZWVkCgpgYGB7cn0KZ19zcGVlZCA8LSBnbG1lcihjb3JyZWN0IH4gCiAgICBwb3NpdGlvbiAgICAgICsgCiAgICBjb2xvciAgICAgICAgICsgCiAgICBzaXplICAgICAgICAgICsgCiAgICBkaXJlY3Rpb24gICAgICsgCiAgICBzaXplX2luY3JlYXNlICsgCiAgICAoMXxzdWJqZWN0KSAgICsgCiAgICAoMXxzY2VuZSksCiAgZGF0YT1maWx0ZXIoVHJpYWxzLCB0YXNrPT0ic3BlZWQiKSwKICBmYW1pbHk9ImJpbm9taWFsIikKCnN1bW1hcnkoZ19zcGVlZCkKcGxvdF9lc3RpbWF0ZXMoZ19zcGVlZCwgIlNwZWVkIFRhc2siKQpgYGAKCgojIyMgQ29ycmVjdG5lc3MgLSBEaXJlY3Rpb24KCmBgYHtyfQpnX2RpcmVjdGlvbiA8LSBnbG1lcihjb3JyZWN0IH4gCiAgICBwb3NpdGlvbiAgICAgICsgCiAgICBjb2xvciAgICAgICAgICsgCiAgICBzaXplICAgICAgICAgICsgCiAgICBzcGVlZCAgICAgICAgICsgCiAgICBzaXplX2luY3JlYXNlICsgCiAgICAoMXxzdWJqZWN0KSAgICsgCiAgICAoMXxzY2VuZSksCiAgZGF0YT1maWx0ZXIoVHJpYWxzLCB0YXNrPT0iZGlyZWN0aW9uIiksCiAgZmFtaWx5PSJiaW5vbWlhbCIpCgpzdW1tYXJ5KGdfZGlyZWN0aW9uKQpwbG90X2VzdGltYXRlcyhnX2RpcmVjdGlvbiwgIkRpcmVjdGlvbiBUYXNrIikKYGBgCgojIyMgTnVtYmVyIG9mIHZpZXdzIChQbGF5cykKCmBgYHtyfQpUcmlhbHMgJT4lCiAgbXV0YXRlKG51bV90cmlhbHMgPSBmYWN0b3IobnVtX3RyaWFscykpICU+JQogIGdyb3VwX2J5KHRhc2ssIGZlYXR1cmVzX3ByZXR0eSwgY29ycmVjdCwgbnVtX3RyaWFscykgJT4lCiAgc3VtbWFyaXNlKGNvdW50PW4oKSwgZ3JvdXA9Z3JvdXBbMV0pICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUobnVtX3RyaWFscyA9IGFzLm51bWVyaWMobnVtX3RyaWFscykpICU+JQogIGFycmFuZ2UodGFzaywgZmVhdHVyZXNfcHJldHR5KSAlPiUKICBnZ3Bsb3QoYWVzKHg9bnVtX3RyaWFscywgeT1jb3VudCwgY29sb3I9Z3JvdXAsIGxpbmV0eXBlPWNvcnJlY3QpKSArCiAgZ2VvbV9saW5lKHNpemU9MS4yKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoMSwyLDMpKSArCiAgc2NhbGVfbGluZXR5cGVfbWFudWFsKHZhbHVlcz1jKCJ0d29kYXNoIiwgInNvbGlkIikpICsKICB5bGFiKCJDb3VudCIpICsKICB4bGFiKCJOdW1iZXIgb2YgVmlld3MiKSArCiAgZmFjZXRfZ3JpZCh0YXNrfmZlYXR1cmVzX3ByZXR0eSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDApKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCmBgYAoKCiMjIyBXaGljaCBmZWF0dXJlcyBtaXNsZWFkPwoKYGBge3J9CnNjYWxlX3RoaXMgPC0gZnVuY3Rpb24oeCl7KHggLSBtZWFuKHgsIG5hLnJtPVRSVUUpKSAvIHNkKHgsIG5hLnJtPVRSVUUpfQpTY2VuZXMgPSByZWFkLmNzdigic2NlbmVzLmNzdiIpCkluY29ycmVjdFNlbGVjdGlvbnMgPSAKICBmaWx0ZXIoU2NlbmVzLCBuYW1lIDwgNTAsIGNvdW50ID4gMCkgJT4lCiAgbXV0YXRlKHRhc2sgPSBpZmVsc2Uoc3RyX2RldGVjdChzdGltdWx1cywgInNwZWVkIiksICJzcGVlZCIsICJkaXJlY3Rpb24iKSkgJT4lCiAgcmVuYW1lKHNwZWVkPWNoYW5nZSkKClNjYWxlZEluY29ycmVjdFNlbGVjdGlvbnMgPSBtdXRhdGVfYXQoSW5jb3JyZWN0U2VsZWN0aW9ucywKICB2YXJzKG1hdGNoZXMoJ3NhbGllbmN5fHNwZWVkJykpLAogIHNjYWxlX3RoaXMpICU+JQogIG11dGF0ZShkaXJlY3Rpb24gPSBzY2FsZV90aGlzKGFicyhtZWFuKHRoZXRhKS10aGV0YSkpKQoKYGBgCgojIyMgRXJyb3IgY291bnQgLSBTcGVlZAoKYGBge3J9CmdfZXJyb3JzX3NwZWVkID0gZ2xtKGNvdW50IH4gc3BlZWQgKyAKICAgIChzYWxpZW5jeV9kaXJlY3Rpb24gKyAKICAgICAgICBzYWxpZW5jeV9jb2xvciArIAogICAgICAgIHNhbGllbmN5X3h5MSArIAogICAgICAgIHNhbGllbmN5X3h5MiArCiAgICAgICAgc2FsaWVuY3lfc2l6ZSkqc3BlZWQsCiAgZGF0YT1maWx0ZXIoU2NhbGVkSW5jb3JyZWN0U2VsZWN0aW9ucywgdGFzaz09InNwZWVkIiksCiAgZmFtaWx5PUdhbW1hKGxpbmsgPSAnbG9nJykpCnN1bW1hcnkoZ19lcnJvcnNfc3BlZWQpCmBgYAoKCmBgYHtyfQpwbG90X2VzdGltYXRlcyhnX2Vycm9yc19zcGVlZCwgCiAgdGl0bGUgPSAiRXJyb3JzIiwKICBzdWJ0aXRsZSA9ICJTcGVlZCB0YXNrIiwKICBlc3RpbWF0ZV9uYW1lID0gImNvdW50IikKYGBgCgojIyMgRXJyb3IgY291bnQgLSBEaXJlY3Rpb24KCmBgYHtyfQpnX2Vycm9yc19kaXJlY3Rpb24gPSBnbG0oY291bnQgfiBkaXJlY3Rpb24gKyAKICAgIChzYWxpZW5jeV9zcGVlZCsKICAgICAgICBzYWxpZW5jeV9jb2xvciArIAogICAgICAgIHNhbGllbmN5X3h5MSArIAogICAgICAgIHNhbGllbmN5X3h5MiArIAogICAgICAgIHNhbGllbmN5X3NpemUpKmRpcmVjdGlvbiwKICBkYXRhPWZpbHRlcihTY2FsZWRJbmNvcnJlY3RTZWxlY3Rpb25zLCB0YXNrPT0iZGlyZWN0aW9uIiksCiAgZmFtaWx5PUdhbW1hKGxpbmsgPSAnbG9nJykpCgpzdW1tYXJ5KGdfZXJyb3JzX2RpcmVjdGlvbikKYGBgCgpgYGB7cn0KcGxvdF9lc3RpbWF0ZXMoZ19lcnJvcnNfZGlyZWN0aW9uLCAKICB0aXRsZSA9ICJFcnJvcnMiLAogIHN1YnRpdGxlID0gIkRpcmVjdGlvbiB0YXNrIiwKICBlc3RpbWF0ZV9uYW1lID0gImNvdW50IikKYGBgCgpgYGB7cn0KcmJpbmQoCiAgaW50ZXJhY3RfcGxvdChnX2Vycm9yc19zcGVlZCwgInNwZWVkIiwgInNhbGllbmN5X2RpcmVjdGlvbiIpJGRhdGEKICAgICU+JSBtdXRhdGUodmFyaWFibGU9InNhbGllbmN5X2RpcmVjdGlvbiIpLAogIGludGVyYWN0X3Bsb3QoZ19lcnJvcnNfc3BlZWQsICJzcGVlZCIsICJzYWxpZW5jeV9jb2xvciIpJGRhdGEKICAgICU+JSBtdXRhdGUodmFyaWFibGU9InNhbGllbmN5X2NvbG9yIiksCiAgaW50ZXJhY3RfcGxvdChnX2Vycm9yc19zcGVlZCwgInNwZWVkIiwgInNhbGllbmN5X3h5MSIpJGRhdGEKICAgICU+JSBtdXRhdGUodmFyaWFibGU9InNhbGllbmN5X3h5MSIpCikgJT4lCiAgZ2dwbG90KGFlcyh4PXNwZWVkLCB5PWNvdW50LCBjb2xvcj1tb2R4X2dyb3VwLCBsaW5ldHlwZT1tb2R4X2dyb3VwKSkgKwogICAgZ2VvbV9saW5lKHNpemU9Ljg1KSArCiAgICBzY2FsZV9jb2xvcl9icmV3ZXIoCiAgICAgIHBhbGV0dGU9IkJsdWVzIiwgCiAgICAgIGJyZWFrcz1jKCIrIDEgU0QiLCAiTWVhbiIsICItIDEgU0QiKSwKICAgICAgZGlyZWN0aW9uPS0xKSArCiAgICBmYWNldF93cmFwKH4gdmFyaWFibGUpICsKICAgIHRoZW1lX21pbmltYWwoKSArCiAgICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgICBnZ3RpdGxlKAogICAgICAiRXJyb3JzIC0gU2lnbmlmaWNhbnQgaW50ZXJhY3Rpb24gdGVybXMiLCAKICAgICAgIlNwZWVkIHRhc2siKQpgYGAKCmBgYHtyfQpyYmluZCgKICBpbnRlcmFjdF9wbG90KGdfZXJyb3JzX2RpcmVjdGlvbiwgImRpcmVjdGlvbiIsICJzYWxpZW5jeV94eTEiKSRkYXRhCiAgJT4lIG11dGF0ZSh2YXJpYWJsZT0ic2FsaWVuY3lfeHkxIiksCiAgaW50ZXJhY3RfcGxvdChnX2Vycm9yc19kaXJlY3Rpb24sICJkaXJlY3Rpb24iLCAic2FsaWVuY3lfY29sb3IiKSRkYXRhCiAgJT4lIG11dGF0ZSh2YXJpYWJsZT0ic2FsaWVuY3lfY29sb3IiKSwKICBpbnRlcmFjdF9wbG90KGdfZXJyb3JzX2RpcmVjdGlvbiwgImRpcmVjdGlvbiIsICJzYWxpZW5jeV94eTIiKSRkYXRhCiAgJT4lIG11dGF0ZSh2YXJpYWJsZT0ic2FsaWVuY3lfeHkyIikKKSAlPiUKICBnZ3Bsb3QoYWVzKHg9ZGlyZWN0aW9uLCB5PWNvdW50LCBjb2xvcj1tb2R4X2dyb3VwLCBsaW5ldHlwZT1tb2R4X2dyb3VwKSkgKwogIGdlb21fbGluZShzaXplPS44NSkgKwogIHNjYWxlX2NvbG9yX2JyZXdlcigKICAgIHBhbGV0dGU9IkJsdWVzIiwgCiAgICBicmVha3M9YygiKyAxIFNEIiwgIk1lYW4iLCAiLSAxIFNEIiksCiAgICBkaXJlY3Rpb249LTEpICsKICBmYWNldF93cmFwKH4gdmFyaWFibGUpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgZ2d0aXRsZSgiRXJyb3JzIC0gU2lnbmlmaWNhbnQgaW50ZXJhY3Rpb24gdGVybXMiLCAKICAgICJEaXJlY3Rpb24gdGFzayIpCmBgYAoKCg==