Analysis
Version 1 (Lab)
The following code chunk reads in the data
# Read in the data
raw_results_lab <- read.csv("results_all/csvFiles/20180320/expt_2_results_lab_long_20180320.csv")
# Rename 1st column name (excel issue)
colnames(raw_results_lab)[1] <- "timeReceived"
# Remove data for self-reported non-native English speakers (participants 104, 108, 114, 118, 124, 127, 130, 143)
raw_results_lab %>%
subset(subject != 104) %>%
subset(subject != 108) %>%
subset(subject != 114) %>%
subset(subject != 118) %>%
subset(subject != 124) %>%
subset(subject != 127) %>%
subset(subject != 130) %>%
subset(subject != 143) %>%
droplevels -> raw_results_lab_native
# Extract experiment and filler data
raw_results_lab %>%
subset(itemType == "experimental") %>%
droplevels -> experiment_data_lab
raw_results_lab %>%
subset(itemType == "filler") %>%
droplevels -> filler_data_lab
The experiment results are presented in the following table by condition.
# Make sure ratings data is numeric so that it can be averaged
experiment_data_lab$rating %<>% as.numeric
# Reverse levels of the intermSubj (subject) factor to mirror discussion
# Indefinite before Definite
experiment_data_lab$intermSubj <- relevel(experiment_data_lab$intermSubj, "indef")
# 'there' before indefinite and definite
experiment_data_lab$intermSubj <- relevel(experiment_data_lab$intermSubj, "there")
# Organize the data by condition
experiment_data_lab %>%
group_by(intermSubj, dependencyType) %>%
dplyr::summarize(mean_rating = mean(rating),
sd_rating = sd(rating),
n = n(),
se_rating = sd_rating/sqrt(n)) -> descriptive_summary_lab
# Save descriptive summary for use in other scripts
saveRDS(descriptive_summary_lab, file="expt2_descriptive_summary.rds")
# Print summary
print(descriptive_summary_lab)
The results are visualized in the plot generated by the following code chunk.
descriptive_summary_lab %>%
ggplot(aes(x = intermSubj,
y = mean_rating,
colour = dependencyType,
group = dependencyType)) -> descriptive_plot_lab
descriptive_plot_lab +
theme_minimal() +
labs(x = "Subject",
y = "Mean rating",
colour = "Dependency type") +
scale_color_discrete("Dependency type", labels = c("Anaphoric", "Movement")) +
geom_errorbar(aes(ymin = mean_rating - se_rating,
ymax = mean_rating + se_rating),
width = 0.15) +
geom_point(aes(col = dependencyType),
size = 2) +
scale_y_continuous(breaks = seq(1:6)) +
theme(panel.grid.minor = element_blank(),
legend.text = element_text(size = 12),
axis.text = element_text(size = 12), # column labels
axis.title.x = element_text(size = 15, # text of x-axis title (here, "Intermediate subject")
margin = margin(0.5, NA, 0.5, NA, "cm")),
axis.title.y = element_text(size = 15, # text of y-axis title (here, "Mean rating")
margin = margin(NA, 0.5, NA, 0.5, "cm"))) -> descriptive_plot_lab
descriptive_plot_lab
The mean rating for the there|movement looks like it could be at floor here, so it would be good to look at the filler sentences that were expected to be ungrammatical and see if any of them were rated below this condition. The following code generates a plot in which the average rating for each filler sentences is represented as a thin orange line crossing the plot.
descriptive_summary_lab %>%
ggplot(aes(x = intermSubj,
y = mean_rating,
ymin = 1,
ymax = 6,
colour = dependencyType,
group = dependencyType)) -> descriptive_plot_w_fillers
descriptive_plot_w_fillers +
theme_minimal() +
labs(x = "Subject",
y = "Mean rating",
colour = "Dependency type",
linetype = "Item type") +
scale_linetype_discrete(labels = "Filler") +
scale_color_discrete(labels = c("Anaphoric", "Movement")) +
geom_hline(data = descriptive_summary_lab_fillers,
aes(yintercept = mean_rating,
linetype = itemType),
color = "orange",
alpha = 0.35,
show.legend = TRUE) +
geom_errorbar(aes(ymin = mean_rating - se_rating,
ymax = mean_rating + se_rating),
width = 0.15) +
geom_point(aes(col = dependencyType),
size = 2) +
scale_y_continuous(breaks = seq(1:6)) +
theme(panel.grid.minor = element_blank(),
legend.text = element_text(size = 12),
axis.text = element_text(size = 12), # column labels
axis.title.x = element_text(size = 15, # text of x-axis title (here, "Intermediate subject")
margin = margin(0.5, NA, 0.5, NA, "cm")),
axis.title.y = element_text(size = 15, # text of y-axis title (here, "Mean rating")
margin = margin(NA, 0.5, NA, 0.5, "cm"))) -> descriptive_plot_w_fillers
print(descriptive_plot_w_fillers)
Version 2 (Mechanical Turk)
Since the concern about a floor effect was not diffused by the ungrammatical filler sentences, a replicate version of this experiment was run on Mechanical Turk. The following code chunk reads in the second set of data.
# Import the data
read.csv("results_all/csvFiles/20180306/expt_2_results_mturk_long_20180306.csv") -> raw_results_mturk
# Fix excel first col. name issue
colnames(raw_results_mturk)[1] <- "timeReceived"
# Separate fillers and experimental data
raw_results_mturk %>% subset(itemType == "experimental") %>% droplevels -> experiment_data_mturk
raw_results_mturk %>% subset(itemType == "filler") %>% droplevels -> filler_data_mturk
Participants were excluded whose average rating for ungrammatical filler sentences was higher than their average rating for grammatical filler sentences. This code chunk identifies participants who meet this criterion.
filler_data_mturk %>%
# Group filler data by subject
group_by(subject) %>%
# Average the ratings for each subject, including separate averages for expected grammatical and expected ungrammatical ratings
summarize(mean_rating = mean(rating),
sd_rating = sd(rating),
n = n(),
se_rating = sd_rating/sqrt(n),
mean_gramm = mean(rating[expectedGramm == "1"]),
mean_ungramm = mean(rating[expectedGramm == "0"])) -> worker_summary
# Find workers whose mean gramm is less than or equal to their mean ungramm
worker_summary %>%
subset(mean_ungramm >= mean_gramm) %>%
print
The average ratings for each condition are presented in the following table, and in the following plot, these ratings are plotted with the average rating for each filler sentence as above. The pattern of ratings was similar, although the experiment conditions were rated higher on average, and the filler sentences received a broader range of ratings.
# Make sure ratings data is numeric
experiment_data_mturk$rating %<>% as.numeric
# Reverse levels of the intermSubj (subject) factor to mirror discussion
# Indefinite before Definite
experiment_data_mturk$intermSubj <- relevel(experiment_data_mturk$intermSubj, "indef")
# 'there' before indefinite and definite
experiment_data_mturk$intermSubj <- relevel(experiment_data_mturk$intermSubj, "there")
# Summarize the experimental data
experiment_data_mturk %>%
group_by(intermSubj, dependencyType) %>%
dplyr::summarize(meanRating = mean(rating),
sd.rating = sd(rating),
n = n(),
se.rating = sd.rating/sqrt(n)) -> descriptive_summary_mturk
# Summarize the filler data
filler_data_mturk %>% group_by(itemID,
expectedGramm,
itemType) %>%
dplyr::summarize(mean_rating = mean(rating),
sd_rating = sd(rating),
n = n(),
se_rating = sd_rating/sqrt(n)) -> descriptive_summary_mturk_fillers
# Make a table
print(descriptive_summary_mturk)
# Same plot for Expt2 MTurk version w/ fillers overlaid
descriptive_summary_mturk %>%
ggplot(aes(x = intermSubj,
y = meanRating,
ymin = 1,
ymax = 6,
colour = dependencyType,
group = dependencyType)) -> descriptive_plot_fillers_mturk
descriptive_plot_fillers_mturk +
theme_minimal() +
labs(x = "Subject",
y = "Mean rating",
colour = "Dependency type",
linetype = "Item type") +
scale_linetype_discrete(labels = "Filler") +
scale_color_discrete(labels = c("Anaphoric", "Movement")) +
geom_hline(data = descriptive_summary_mturk_fillers,
aes(yintercept = mean_rating,
linetype = itemType),
color = "orange",
alpha = 0.35,
show.legend = TRUE) +
geom_errorbar(aes(ymin = meanRating - se.rating,
ymax = meanRating + se.rating),
width = 0.10) +
geom_point(aes(col = dependencyType),
size = 3) +
scale_y_continuous(breaks = seq(1:6)) +
theme(panel.grid.minor = element_blank(),
legend.text = element_text(size = 12),
axis.text = element_text(size = 12), # column labels
axis.title.x = element_text(size = 15, # text of x-axis title (here, "Intermediate subject")
margin = margin(0.5, NA, 0.5, NA, "cm")),
axis.title.y = element_text(size = 15, # text of y-axis title (here, "Mean rating")
margin = margin(NA, 0.5, NA, 0.5, "cm"))) -> descriptive_plot_fillers_mturk
descriptive_plot_fillers_mturk
Ordinal regression analysis
The ordinal regression analysis printed below was run on the hummingbird cluster using the ratings data from Version 2 of this experiment. The following code chunk sets the contrasts for the two dfiferent factors. For the three-level factor, Helmert contrast coding was used so that the existential (there) conditions would be compared to the combination of the other conditions, and so that the indefinite and definite conditions would only be compared directly to each other.
# Make sure ratings data is a factor
experiment_data_mturk$rating %<>% as.factor
# Helmert contrast-coding
contrasts(experiment_data_mturk$intermSubj) <- "contr.helmert"
# Rename contrast column names
dimnames(contrasts(experiment_data_mturk$intermSubj))[[2]] <- c("definiteness", "height")
# Fix Helmert contrast coding so that in DEFINITENESS comparison, 'there' is neutralized, and in HEIGHT comparison, 'there' is compared to both def and indef
contrasts(experiment_data_mturk$intermSubj)[1,] <- c(0, 2)
contrasts(experiment_data_mturk$intermSubj)[2,] <- c(1, -1)
contrasts(experiment_data_mturk$intermSubj)[3,] <- c(-1, -1)
# Show contrasts for Subject factor
contrasts(experiment_data_mturk$intermSubj)
definiteness height
there 0 2
indef 1 -1
def -1 -1
# Set contrasts for dependency type & show
contrasts(experiment_data_mturk$dependencyType) <- c(-0.5, 0.5)
# Show contrasts for dependency type factor
contrasts(experiment_data_mturk$dependencyType)
[,1]
coref -0.5
move 0.5
# Save RDS file for use in other scripts
saveRDS(experiment_data_mturk, file = "expt2_data_mturk.rds")
The mixed effects ordinal regression analysis was run on the UCSC hummingbird cluster as follows.
# Full mixed effects analysis run on the hummingbird cluster as follows
# Read in the data saved from personal computer
readRDS(file = "expt2_data_mturk.rds") -> expt2_data
# Run ordinal regression analysis
clmm(data = expt2_data,
# Rating as dependent variable, fixed effects as intermSubj, dependencyType, and their interactions
formula = rating ~ intermSubj * dependencyType +
# Random effects by subject
(1 + intermSubj * dependencyType | subject) +
# Random effects by item
(1 + intermSubj * dependencyType | itemSet)
) -> expt2_clmm_full
# Save expt2_clmm_full
saveRDS(expt2_clmm_full, "expt2_clmm_full_20181118.rds")
# Read in clmm data saved from cluster
readRDS("expt2_clmm_full_20181118.rds") -> expt2_clmm_cluster
summary(expt2_clmm_cluster)
Cumulative Link Mixed Model fitted with the Laplace approximation
formula: rating ~ intermSubj * dependencyType + (1 + intermSubj * dependencyType |
subject) + (1 + intermSubj * dependencyType | itemSet)
data: expt2_data
Random effects:
Groups Name Variance Std.Dev. Corr
subject (Intercept) 4.3385 2.0829
intermSubjindef 0.3675 0.6062 -0.774
intermSubjthere 2.2816 1.5105 -0.849 0.540
dependencyTypemove 6.9260 2.6317 -0.780 0.691 0.929
intermSubjindef:dependencyTypemove 1.3518 1.1627 0.266 -0.134 -0.441 -0.502
intermSubjthere:dependencyTypemove 4.7399 2.1771 0.459 0.007 -0.740 -0.600 0.781
itemSet (Intercept) 0.7054 0.8399
intermSubjindef 0.2425 0.4924 0.286
intermSubjthere 0.2896 0.5381 -0.128 0.914
dependencyTypemove 0.4536 0.6735 -0.935 -0.607 -0.232
intermSubjindef:dependencyTypemove 0.3698 0.6081 -0.300 -1.000 -0.908 0.618
intermSubjthere:dependencyTypemove 0.6563 0.8101 0.146 -0.906 -1.000 0.214 0.900
Number of groups: subject 37, itemSet 24
Coefficients:
Estimate Std. Error z value Pr(>|z|)
intermSubjdefiniteness -0.03465 0.12163 -0.285 0.776
intermSubjheight -0.42393 0.07023 -6.037 1.57e-09 ***
dependencyType1 -4.52988 0.46279 -9.788 < 2e-16 ***
intermSubjdefiniteness:dependencyType1 0.24417 0.23122 1.056 0.291
intermSubjheight:dependencyType1 0.62476 0.15586 4.008 6.11e-05 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Threshold coefficients:
Estimate Std. Error z value
1|2 -4.0539 0.2898 -13.986
2|3 -1.9714 0.2581 -7.639
3|4 -0.6482 0.2511 -2.581
4|5 1.0279 0.2524 4.072
5|6 2.9003 0.2692 10.775
Sprouse, Jon, Matthew W. Wagers, and Colin Phillips. 2013. “Deriving competing predictions from grammatical approaches and reductionist approaches to island effects.” In Experimental Syntax and Island Effects, edited by Jon Sprouse and Norbert Hornstein, 21–41. Cambridge, United Kingdom: Cambridge University Press. https://doi.org/10.1017/CBO9781139035309.003.
LS0tDQp0aXRsZTogIlJDIHN1YmV4dHJhY3Rpb24gaW4gRW5nbGlzaDogRXhwZXJpbWVudCAyIG5vdGVib29rIg0KYXV0aG9yOiBKYWtlIFcuIFZpbmNlbnQgKCYjMTA2OyYjMTE5OyYjMTE4OyYjMTA1OyYjMTEwOyYjOTk7JiMxMDE7biYjNjQ7JiMxMTc7YyYjMTE1O2MuZSYjMTAwO3UpDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgY29kZV9mb2xkaW5nOiBzaG93DQogICAgZGZfcHJpbnQ6IHBhZ2VkDQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIHRoZW1lOiBmbGF0bHkNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIGNzczogc3R5bGUuY3NzDQogIHBkZl9kb2N1bWVudDoNCiAgICBrZWVwX3RleDogeWVzDQpiaWJsaW9ncmFwaHk6IC4uLy4uLy4uLy4uLy4uLy4uL0RvY3VtZW50cy9saWJyYXJ5LmJpYg0KLS0tDQoNCiMgTW90aXZhdGlvbg0KDQpFeHBlcmltZW50IDIgZm9sbG93cyBbRXhwZXJpbWVudCAxXShSQ19leHBlcmltZW50MS5odG1sKS4gRXhwZXJpbWVudCAxIGVtcGxveWVkIGEgbGVuZ3RoIGJ5IGNvbXBsZXhpdHkgZGVzaWduIChmb2xsb3dpbmcgQFNwcm91c2UyMDEzYSksIGFuZCBhIGRlZmluaXRlbmVzcyBmYWN0b3IgdGhhdCBtYW5pcHVsYXRlZCB0aGUgZGVmaW5pdGVuZXNzIG9mIGEgdHJhbnNpdGl2ZSBvYmplY3QgRFAgY29udGFpbmluZyBhIENvbXBsZXggTlAgaXNsYW5kLiBObyBlZmZlY3Qgb2YgZGVmaW5pdGVuZXNzIG9uIHRyYW5zcGFyZW5jeSB0byBleHRyYWN0aW9uIHdhcyBmb3VuZC4gRXhwZXJpbWVudCAyIGZvbGxvd3MgdXAgb24gRXhwZXJpbWVudCAxIGJ5IGNvbXBhcmluZyBSQ3MgZW1iZWRkZWQgaW5zaWRlIHN1YmplY3RzIGluIGRlcml2ZWQgcG9zaXRpb25zIChTcGVjLCBUUCkgdG8gUkNzIGluc2lkZSBzdWJqZWN0cyBpbiBub24tZGVyaXZlZCBwb3NpdGlvbnMgKHRoZSBwaXZvdCBvZiBhbiBleGlzdGVudGlhbCkuIENvbXBhcmluZyBEUHMgaW4gdGhlc2UgZW52aXJvbm1lbnRzIGFsbG93cyB1cyB0byBnYXVnZSB0aGUgZWZmZWN0IG9mIHByZXN1cHBvc2l0aW9uYWxpdHkgb24gdHJhbnNwYXJlbmN5IHRvIGV4dHJhY3Rpb24sIHNpbmNlIERQcyBpbiB0aGUgcGl2b3Qgb2YgYW4gZXhpc3RlbnRpYWwgYXJlIG5vbi1wcmVzdXBwb3NlZCwgd2hpbGUgRFBzIGluIGhpZ2ggc3ViamVjdCBwb3NpdGlvbiBtYXkgYmUgcHJlc3VwcG9zZWQuDQoNCiMgRGVzaWduDQoNClRoaXMgZXhwZXJpbWVudCB1c2VzIGEgZGlmZmVyZW50IGRlc2lnbiB0aGFuIEV4cGVyaW1lbnQgMSB0aGF0IGNyb3NzZXMgdHdvIGZhY3RvcnM6IHRoZSBwb3NpdGlvbiBvZiB0aGUgRFAgc3ViamVjdCBvdXQgb2Ygd2hpY2ggZXh0cmFjdGlvbiBvY2N1cnMgKDxzcGFuIGNsYXNzPSJzbWFsbGNhcHMiPnN1YmplY3Q8L3NwYW4+KSBhbmQgdGhlIHR5cGUgb2YgZGVwZW5kZW5jeSB0aGF0IGlzIGNvbnN0cnVjdGVkIGludG8gdGhhdCBEUCAoPHNwYW4gY2xhc3M9InNtYWxsY2FwcyI+PC9zcGFuPikuIFR3byBsZXZlbHMgb2YgZGVmaW5pdGVuZXNzIHdlcmUgdXNlZCBmb3IgdGhlIERQcyBpbiBoaWdoIHN1YmplY3QgcG9zaXRpb246IGRlZmluaXRlIGFuZCBpbmRlZmluaXRlLiBUaGUgdHdvIGRlcGVuZGVuY3kgdHlwZXMgdXNlZCBhcmUgYSBwcm9ub21pbmFsIGRlcGVuZGVuY3kgKG5vbi1pc2xhbmQtc2Vuc2l0aXZlKSBhbmQgYSBtb3ZlbWVudCBkZXBlbmRlbmN5IChpc2xhbmQtc2Vuc2l0aXZlKS4gVGhpcyByZXN1bHRlZCBpbiBhIDPDlzIgZGVzaWduLg0KDQoxLiAqKkZhY3RvcnMqKg0KICAgIGEuIDxzcGFuIGNsYXNzPSJzbWFsbGNhcHMiPlN1YmplY3Q8L3NwYW4+DQogICAgICAgIGkuIDxzcGFuIGNsYXNzPSJzbWFsbGNhcHMiPnRoZXJlPC9zcGFuPiAobG93IHN1YmplY3QgaW4gcGl2b3Qgb2YgZXhpc3RlbnRpYWwpDQogICAgICAgIGlpLiA8c3BhbiBjbGFzcz0ic21hbGxjYXBzIj5pbmRlZmluaXRlPC9zcGFuPiAoaGlnaCBpbmRlZmluaXRlIHN1YmplY3QpDQogICAgICAgIGlpaS4gPHNwYW4gY2xhc3M9InNtYWxsY2FwcyI+ZGVmaW5pdGU8L3NwYW4+IChoaWdoIGRlZmluaXRlIHN1YmplY3QpDQogICAgYi4gPHNwYW4gY2xhc3M9InNtYWxsY2FwcyI+RGVwZW5kZW5jeSB0eXBlPC9zcGFuPg0KICAgICAgICBpLiA8c3BhbiBjbGFzcz0ic21hbGxjYXBzIj5hbmFwaG9yaWM8L3NwYW4+DQogICAgICAgIGlpLiA8c3BhbiBjbGFzcz0ic21hbGxjYXBzIj5tb3ZlbWVudDwvc3Bhbj4NCiAgICAgICAgDQoyLiAqKlNhbXBsZSBpdGVtIHNldCoqDQogICAgYS4gVGhlIHByZXNpZGVudCB0aGlua3MgdGhhdCB0aGVyZSBhcmUgbWFueSBBbWVyaWNhbnMgd2hvIHN1cHBvcnRlZCBoaW0gaW4gdGhlIGVsZWN0aW9uIGxpdmluZyBpbiBydXJhbCBhcmVhcy48ZGl2IGNsYXNzPSJhbGlnbnJpZ2h0Ij4oPHNwYW4gY2xhc3M9InNtYWxsY2FwcyI+dGhlcmV8YW5hcGhvcmljPC9zcGFuPik8L2Rpdj4NCiAgICBiLiBUaGUgcHJlc2lkZW50IGlzIHNvbWVvbmUgdGhhdCB0aGVyZSBhcmUgbWFueSBBbWVyaWNhbnMgd2hvIHN1cHBvcnRlZCBpbiB0aGUgZWxlY3Rpb24gbGl2aW5nIGluIHJ1cmFsIGFyZWFzLjxkaXYgY2xhc3M9ImFsaWducmlnaHQiPig8c3BhbiBjbGFzcz0ic21hbGxjYXBzIj50aGVyZXxtb3ZlbWVudDwvc3Bhbj4pPC9kaXY+DQogICAgYy4gVGhlIHByZXNpZGVudCB0aGlua3MgdGhhdCBtYW55IEFtZXJpY2FucyB3aG8gc3VwcG9ydGVkIGhpbSBpbiB0aGUgZWxlY3Rpb24gYXJlIGxpdmluZyBpbiBydXJhbCBhcmVhcy48ZGl2IGNsYXNzPSJhbGlnbnJpZ2h0Ij4oPHNwYW4gY2xhc3M9InNtYWxsY2FwcyI+aW5kZWZpbml0ZXxhbmFwaG9yaWM8L3NwYW4+KTwvZGl2Pg0KICAgIGQuIFRoZSBwcmVzaWRlbnQgaXMgc29tZW9uZSB0aGF0IG1hbnkgQW1lcmljYW5zIHdobyBzdXBwb3J0ZWQgaW4gdGhlIGVsZWN0aW9uIGFyZSBsaXZpbmcgaW4gcnVyYWwgYXJlYXMuPGRpdiBjbGFzcz0iYWxpZ25yaWdodCI+KDxzcGFuIGNsYXNzPSJzbWFsbGNhcHMiPmluZGVmaW5pdGV8bW92ZW1lbnQ8L3NwYW4+KTwvZGl2Pg0KICAgIGUuIFRoZSBwcmVzaWRlbnQgdGhpbmtzIHRoYXQgdGhlIEFtZXJpY2FucyB3aG8gc3VwcG9ydGVkIGhpbSBpbiB0aGUgZWxlY3Rpb24gYXJlIGxpdmluZyBpbiBydXJhbCBhcmVhcy48ZGl2IGNsYXNzPSJhbGlnbnJpZ2h0Ij4oPHNwYW4gY2xhc3M9InNtYWxsY2FwcyI+ZGVmaW5pdGV8YW5hcGhvcmljPC9zcGFuPik8L2Rpdj4NCiAgICBmLiBUaGUgcHJlc2lkZW50IGlzIHNvbWVvbmUgdGhhdCB0aGUgQW1lcmljYW5zIHdobyBzdXBwb3J0ZWQgaW4gdGhlIGVsZWN0aW9uIGFyZSBsaXZpbmcgaW4gcnVyYWwgYXJlYXMuPGRpdiBjbGFzcz0iYWxpZ25yaWdodCI+KDxzcGFuIGNsYXNzPSJzbWFsbGNhcHMiPmRlZmluaXRlfG1vdmVtZW50PC9zcGFuPik8L2Rpdj4NCiAgICANCg0KIyBBbmFseXNpcw0KDQojIyBWZXJzaW9uIDEgKExhYikNCg0KVGhlIGZvbGxvd2luZyBjb2RlIGNodW5rIHJlYWRzIGluIHRoZSBkYXRhDQoNCmBgYHtyIGxpYnJhcmllcywgaW5jbHVkZSA9IEZBTFNFfQ0KIyBHZXQgbGlicmFyaWVzDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHBseXIpICMgbmVlZHMgdG8gYmUgbG9hZGVkIGJlZm9yZSBkcGx5cg0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkobWFncml0dHIpDQpsaWJyYXJ5KHRpZHlyKQ0KbGlicmFyeShvcmRpbmFsKQ0KcmVxdWlyZShrbml0cikNCmBgYA0KDQpgYGB7ciBzZXR1cExhYn0NCiMgUmVhZCBpbiB0aGUgZGF0YQ0KcmF3X3Jlc3VsdHNfbGFiIDwtIHJlYWQuY3N2KCJyZXN1bHRzX2FsbC9jc3ZGaWxlcy8yMDE4MDMyMC9leHB0XzJfcmVzdWx0c19sYWJfbG9uZ18yMDE4MDMyMC5jc3YiKQ0KDQojIFJlbmFtZSAxc3QgY29sdW1uIG5hbWUgKGV4Y2VsIGlzc3VlKQ0KY29sbmFtZXMocmF3X3Jlc3VsdHNfbGFiKVsxXSA8LSAidGltZVJlY2VpdmVkIg0KDQojIFJlbW92ZSBkYXRhIGZvciBzZWxmLXJlcG9ydGVkIG5vbi1uYXRpdmUgRW5nbGlzaCBzcGVha2VycyAocGFydGljaXBhbnRzIDEwNCwgMTA4LCAxMTQsIDExOCwgMTI0LCAxMjcsIDEzMCwgMTQzKQ0KcmF3X3Jlc3VsdHNfbGFiICU+JQ0KICBzdWJzZXQoc3ViamVjdCAhPSAxMDQpICU+JQ0KICBzdWJzZXQoc3ViamVjdCAhPSAxMDgpICU+JQ0KICBzdWJzZXQoc3ViamVjdCAhPSAxMTQpICU+JQ0KICBzdWJzZXQoc3ViamVjdCAhPSAxMTgpICU+JQ0KICBzdWJzZXQoc3ViamVjdCAhPSAxMjQpICU+JQ0KICBzdWJzZXQoc3ViamVjdCAhPSAxMjcpICU+JQ0KICBzdWJzZXQoc3ViamVjdCAhPSAxMzApICU+JQ0KICBzdWJzZXQoc3ViamVjdCAhPSAxNDMpICU+JQ0KICBkcm9wbGV2ZWxzIC0+IHJhd19yZXN1bHRzX2xhYl9uYXRpdmUNCg0KIyBFeHRyYWN0IGV4cGVyaW1lbnQgYW5kIGZpbGxlciBkYXRhDQpyYXdfcmVzdWx0c19sYWIgJT4lDQogIHN1YnNldChpdGVtVHlwZSA9PSAiZXhwZXJpbWVudGFsIikgJT4lDQogIGRyb3BsZXZlbHMgLT4gZXhwZXJpbWVudF9kYXRhX2xhYg0KcmF3X3Jlc3VsdHNfbGFiICU+JQ0KICBzdWJzZXQoaXRlbVR5cGUgPT0gImZpbGxlciIpICU+JQ0KICBkcm9wbGV2ZWxzIC0+IGZpbGxlcl9kYXRhX2xhYg0KYGBgDQoNClRoZSBleHBlcmltZW50IHJlc3VsdHMgYXJlIHByZXNlbnRlZCBpbiB0aGUgZm9sbG93aW5nIHRhYmxlIGJ5IGNvbmRpdGlvbi4NCg0KYGBge3IgcmVzdWx0c190YWJsZX0NCiMgTWFrZSBzdXJlIHJhdGluZ3MgZGF0YSBpcyBudW1lcmljIHNvIHRoYXQgaXQgY2FuIGJlIGF2ZXJhZ2VkDQpleHBlcmltZW50X2RhdGFfbGFiJHJhdGluZyAlPD4lIGFzLm51bWVyaWMNCg0KIyBSZXZlcnNlIGxldmVscyBvZiB0aGUgaW50ZXJtU3ViaiAoc3ViamVjdCkgZmFjdG9yIHRvIG1pcnJvciBkaXNjdXNzaW9uDQojIEluZGVmaW5pdGUgYmVmb3JlIERlZmluaXRlDQpleHBlcmltZW50X2RhdGFfbGFiJGludGVybVN1YmogPC0gcmVsZXZlbChleHBlcmltZW50X2RhdGFfbGFiJGludGVybVN1YmosICJpbmRlZiIpDQojICd0aGVyZScgYmVmb3JlIGluZGVmaW5pdGUgYW5kIGRlZmluaXRlDQpleHBlcmltZW50X2RhdGFfbGFiJGludGVybVN1YmogPC0gcmVsZXZlbChleHBlcmltZW50X2RhdGFfbGFiJGludGVybVN1YmosICJ0aGVyZSIpDQoNCg0KIyBPcmdhbml6ZSB0aGUgZGF0YSBieSBjb25kaXRpb24NCmV4cGVyaW1lbnRfZGF0YV9sYWIgJT4lDQogIGdyb3VwX2J5KGludGVybVN1YmosIGRlcGVuZGVuY3lUeXBlKSAlPiUNCiAgZHBseXI6OnN1bW1hcml6ZShtZWFuX3JhdGluZyA9IG1lYW4ocmF0aW5nKSwNCiAgICAgICAgICAgICAgICAgICBzZF9yYXRpbmcgPSBzZChyYXRpbmcpLA0KICAgICAgICAgICAgICAgICAgIG4gPSBuKCksDQogICAgICAgICAgICAgICAgICAgc2VfcmF0aW5nID0gc2RfcmF0aW5nL3NxcnQobikpIC0+IGRlc2NyaXB0aXZlX3N1bW1hcnlfbGFiDQoNCiMgU2F2ZSBkZXNjcmlwdGl2ZSBzdW1tYXJ5IGZvciB1c2UgaW4gb3RoZXIgc2NyaXB0cw0Kc2F2ZVJEUyhkZXNjcmlwdGl2ZV9zdW1tYXJ5X2xhYiwgZmlsZT0iZXhwdDJfZGVzY3JpcHRpdmVfc3VtbWFyeS5yZHMiKQ0KDQojIFByaW50IHN1bW1hcnkNCnByaW50KGRlc2NyaXB0aXZlX3N1bW1hcnlfbGFiKQ0KYGBgDQoNClRoZSByZXN1bHRzIGFyZSB2aXN1YWxpemVkIGluIHRoZSBwbG90IGdlbmVyYXRlZCBieSB0aGUgZm9sbG93aW5nIGNvZGUgY2h1bmsuDQoNCmBgYHtyIGRlc2NyaXB0aXZlX3Bsb3RfbGFifQ0KZGVzY3JpcHRpdmVfc3VtbWFyeV9sYWIgJT4lDQogIGdncGxvdChhZXMoeCA9IGludGVybVN1YmosDQogICAgICAgICAgICAgeSA9IG1lYW5fcmF0aW5nLA0KICAgICAgICAgICAgIGNvbG91ciA9IGRlcGVuZGVuY3lUeXBlLA0KICAgICAgICAgICAgIGdyb3VwID0gZGVwZW5kZW5jeVR5cGUpKSAtPiBkZXNjcmlwdGl2ZV9wbG90X2xhYg0KDQpkZXNjcmlwdGl2ZV9wbG90X2xhYiArDQogIHRoZW1lX21pbmltYWwoKSArDQogIGxhYnMoeCA9ICJTdWJqZWN0IiwNCiAgICAgICB5ID0gIk1lYW4gcmF0aW5nIiwNCiAgICAgICBjb2xvdXIgPSAiRGVwZW5kZW5jeSB0eXBlIikgKw0KICBzY2FsZV9jb2xvcl9kaXNjcmV0ZSgiRGVwZW5kZW5jeSB0eXBlIiwgbGFiZWxzID0gYygiQW5hcGhvcmljIiwgIk1vdmVtZW50IikpICsNCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IG1lYW5fcmF0aW5nIC0gc2VfcmF0aW5nLA0KICAgICAgICAgICAgICAgICAgICB5bWF4ID0gbWVhbl9yYXRpbmcgKyBzZV9yYXRpbmcpLA0KICAgICAgICAgICAgICAgICAgICB3aWR0aCA9IDAuMTUpICsNCiAgZ2VvbV9wb2ludChhZXMoY29sID0gZGVwZW5kZW5jeVR5cGUpLA0KICAgICAgICAgICAgIHNpemUgPSAyKSArDQogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoMTo2KSkgKw0KICB0aGVtZShwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwgIyBjb2x1bW4gbGFiZWxzDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsICMgdGV4dCBvZiB4LWF4aXMgdGl0bGUgKGhlcmUsICJJbnRlcm1lZGlhdGUgc3ViamVjdCIpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSBtYXJnaW4oMC41LCBOQSwgMC41LCBOQSwgImNtIikpLA0KICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCAjIHRleHQgb2YgeS1heGlzIHRpdGxlIChoZXJlLCAiTWVhbiByYXRpbmciKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luID0gbWFyZ2luKE5BLCAwLjUsIE5BLCAwLjUsICJjbSIpKSkgLT4gZGVzY3JpcHRpdmVfcGxvdF9sYWINCmRlc2NyaXB0aXZlX3Bsb3RfbGFiDQpgYGANCg0KVGhlIG1lYW4gcmF0aW5nIGZvciB0aGUgPHNwYW4gY2xhc3M9InNtYWxsY2FwcyI+dGhlcmV8bW92ZW1lbnQ8L3NwYW4+IGxvb2tzIGxpa2UgaXQgY291bGQgYmUgYXQgZmxvb3IgaGVyZSwgc28gaXQgd291bGQgYmUgZ29vZCB0byBsb29rIGF0IHRoZSBmaWxsZXIgc2VudGVuY2VzIHRoYXQgd2VyZSBleHBlY3RlZCB0byBiZSB1bmdyYW1tYXRpY2FsIGFuZCBzZWUgaWYgYW55IG9mIHRoZW0gd2VyZSByYXRlZCBiZWxvdyB0aGlzIGNvbmRpdGlvbi4gVGhlIGZvbGxvd2luZyBjb2RlIGdlbmVyYXRlcyBhIHBsb3QgaW4gd2hpY2ggdGhlIGF2ZXJhZ2UgcmF0aW5nIGZvciBlYWNoIGZpbGxlciBzZW50ZW5jZXMgaXMgcmVwcmVzZW50ZWQgYXMgYSB0aGluIG9yYW5nZSBsaW5lIGNyb3NzaW5nIHRoZSBwbG90Lg0KDQpgYGB7ciBkZXNjcmlwdGl2ZV9wbG90X3dfZmlsbGVyc30NCmRlc2NyaXB0aXZlX3N1bW1hcnlfbGFiICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBpbnRlcm1TdWJqLA0KICAgICAgICAgICAgIHkgPSBtZWFuX3JhdGluZywNCiAgICAgICAgICAgICB5bWluID0gMSwNCiAgICAgICAgICAgICB5bWF4ID0gNiwNCiAgICAgICAgICAgICBjb2xvdXIgPSBkZXBlbmRlbmN5VHlwZSwNCiAgICAgICAgICAgICBncm91cCA9IGRlcGVuZGVuY3lUeXBlKSkgLT4gZGVzY3JpcHRpdmVfcGxvdF93X2ZpbGxlcnMNCg0KZGVzY3JpcHRpdmVfcGxvdF93X2ZpbGxlcnMgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICBsYWJzKHggPSAiU3ViamVjdCIsDQogICAgICAgeSA9ICJNZWFuIHJhdGluZyIsDQogICAgICAgY29sb3VyID0gIkRlcGVuZGVuY3kgdHlwZSIsDQogICAgICAgbGluZXR5cGUgPSAiSXRlbSB0eXBlIikgKw0KICBzY2FsZV9saW5ldHlwZV9kaXNjcmV0ZShsYWJlbHMgPSAiRmlsbGVyIikgKw0KICBzY2FsZV9jb2xvcl9kaXNjcmV0ZShsYWJlbHMgPSBjKCJBbmFwaG9yaWMiLCAiTW92ZW1lbnQiKSkgKw0KICBnZW9tX2hsaW5lKGRhdGEgPSBkZXNjcmlwdGl2ZV9zdW1tYXJ5X2xhYl9maWxsZXJzLA0KICAgICAgICAgICAgIGFlcyh5aW50ZXJjZXB0ID0gbWVhbl9yYXRpbmcsDQogICAgICAgICAgICAgICAgIGxpbmV0eXBlID0gaXRlbVR5cGUpLA0KICAgICAgICAgICAgIGNvbG9yID0gIm9yYW5nZSIsDQogICAgICAgICAgICAgYWxwaGEgPSAwLjM1LA0KICAgICAgICAgICAgIHNob3cubGVnZW5kID0gVFJVRSkgKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gbWVhbl9yYXRpbmcgLSBzZV9yYXRpbmcsDQogICAgICAgICAgICAgICAgICAgIHltYXggPSBtZWFuX3JhdGluZyArIHNlX3JhdGluZyksDQogICAgICAgICAgICAgICAgICAgIHdpZHRoID0gMC4xNSkgKw0KICBnZW9tX3BvaW50KGFlcyhjb2wgPSBkZXBlbmRlbmN5VHlwZSksDQogICAgICAgICAgICAgc2l6ZSA9IDIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgxOjYpKSArDQogIHRoZW1lKHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLCAjIGNvbHVtbiBsYWJlbHMNCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgIyB0ZXh0IG9mIHgtYXhpcyB0aXRsZSAoaGVyZSwgIkludGVybWVkaWF0ZSBzdWJqZWN0IikNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbiA9IG1hcmdpbigwLjUsIE5BLCAwLjUsIE5BLCAiY20iKSksDQogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsICMgdGV4dCBvZiB5LWF4aXMgdGl0bGUgKGhlcmUsICJNZWFuIHJhdGluZyIpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSBtYXJnaW4oTkEsIDAuNSwgTkEsIDAuNSwgImNtIikpKSAtPiBkZXNjcmlwdGl2ZV9wbG90X3dfZmlsbGVycw0KcHJpbnQoZGVzY3JpcHRpdmVfcGxvdF93X2ZpbGxlcnMpDQpgYGANCg0KIyMgVmVyc2lvbiAyIChNZWNoYW5pY2FsIFR1cmspDQoNClNpbmNlIHRoZSBjb25jZXJuIGFib3V0IGEgZmxvb3IgZWZmZWN0IHdhcyBub3QgZGlmZnVzZWQgYnkgdGhlIHVuZ3JhbW1hdGljYWwgZmlsbGVyIHNlbnRlbmNlcywgYSByZXBsaWNhdGUgdmVyc2lvbiBvZiB0aGlzIGV4cGVyaW1lbnQgd2FzIHJ1biBvbiBNZWNoYW5pY2FsIFR1cmsuIFRoZSBmb2xsb3dpbmcgY29kZSBjaHVuayByZWFkcyBpbiB0aGUgc2Vjb25kIHNldCBvZiBkYXRhLg0KDQpgYGB7ciBzZXR1cF9tdHVya30NCiMgSW1wb3J0IHRoZSBkYXRhDQpyZWFkLmNzdigicmVzdWx0c19hbGwvY3N2RmlsZXMvMjAxODAzMDYvZXhwdF8yX3Jlc3VsdHNfbXR1cmtfbG9uZ18yMDE4MDMwNi5jc3YiKSAtPiByYXdfcmVzdWx0c19tdHVyaw0KDQojIEZpeCBleGNlbCBmaXJzdCBjb2wuIG5hbWUgaXNzdWUNCmNvbG5hbWVzKHJhd19yZXN1bHRzX210dXJrKVsxXSA8LSAidGltZVJlY2VpdmVkIg0KDQojIFNlcGFyYXRlIGZpbGxlcnMgYW5kIGV4cGVyaW1lbnRhbCBkYXRhDQpyYXdfcmVzdWx0c19tdHVyayAlPiUgc3Vic2V0KGl0ZW1UeXBlID09ICJleHBlcmltZW50YWwiKSAlPiUgZHJvcGxldmVscyAtPiBleHBlcmltZW50X2RhdGFfbXR1cmsNCnJhd19yZXN1bHRzX210dXJrICU+JSBzdWJzZXQoaXRlbVR5cGUgPT0gImZpbGxlciIpICU+JSBkcm9wbGV2ZWxzIC0+IGZpbGxlcl9kYXRhX210dXJrDQpgYGANCg0KUGFydGljaXBhbnRzIHdlcmUgZXhjbHVkZWQgd2hvc2UgYXZlcmFnZSByYXRpbmcgZm9yIHVuZ3JhbW1hdGljYWwgZmlsbGVyIHNlbnRlbmNlcyB3YXMgaGlnaGVyIHRoYW4gdGhlaXIgYXZlcmFnZSByYXRpbmcgZm9yIGdyYW1tYXRpY2FsIGZpbGxlciBzZW50ZW5jZXMuIFRoaXMgY29kZSBjaHVuayBpZGVudGlmaWVzIHBhcnRpY2lwYW50cyB3aG8gbWVldCB0aGlzIGNyaXRlcmlvbi4NCg0KYGBge3IgcGFydGljaXBhbnRfZXhjbHVzaW9uX210dXJrfQ0KZmlsbGVyX2RhdGFfbXR1cmsgJT4lDQogICMgR3JvdXAgZmlsbGVyIGRhdGEgYnkgc3ViamVjdA0KICBncm91cF9ieShzdWJqZWN0KSAlPiUNCiAgIyBBdmVyYWdlIHRoZSByYXRpbmdzIGZvciBlYWNoIHN1YmplY3QsIGluY2x1ZGluZyBzZXBhcmF0ZSBhdmVyYWdlcyBmb3IgZXhwZWN0ZWQgZ3JhbW1hdGljYWwgYW5kIGV4cGVjdGVkIHVuZ3JhbW1hdGljYWwgcmF0aW5ncw0KICBzdW1tYXJpemUobWVhbl9yYXRpbmcgPSBtZWFuKHJhdGluZyksDQogICAgICAgICAgICBzZF9yYXRpbmcgPSBzZChyYXRpbmcpLA0KICAgICAgICAgICAgbiA9IG4oKSwNCiAgICAgICAgICAgIHNlX3JhdGluZyA9IHNkX3JhdGluZy9zcXJ0KG4pLA0KICAgICAgICAgICAgbWVhbl9ncmFtbSA9IG1lYW4ocmF0aW5nW2V4cGVjdGVkR3JhbW0gPT0gIjEiXSksDQogICAgICAgICAgICBtZWFuX3VuZ3JhbW0gPSBtZWFuKHJhdGluZ1tleHBlY3RlZEdyYW1tID09ICIwIl0pKSAtPiB3b3JrZXJfc3VtbWFyeQ0KDQojIEZpbmQgd29ya2VycyB3aG9zZSBtZWFuIGdyYW1tIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGVpciBtZWFuIHVuZ3JhbW0NCndvcmtlcl9zdW1tYXJ5ICU+JQ0KICBzdWJzZXQobWVhbl91bmdyYW1tID49IG1lYW5fZ3JhbW0pICU+JQ0KICBwcmludA0KYGBgDQoNClRoZSBhdmVyYWdlIHJhdGluZ3MgZm9yIGVhY2ggY29uZGl0aW9uIGFyZSBwcmVzZW50ZWQgaW4gdGhlIGZvbGxvd2luZyB0YWJsZSwgYW5kIGluIHRoZSBmb2xsb3dpbmcgcGxvdCwgdGhlc2UgcmF0aW5ncyBhcmUgcGxvdHRlZCB3aXRoIHRoZSBhdmVyYWdlIHJhdGluZyBmb3IgZWFjaCBmaWxsZXIgc2VudGVuY2UgYXMgYWJvdmUuIFRoZSBwYXR0ZXJuIG9mIHJhdGluZ3Mgd2FzIHNpbWlsYXIsIGFsdGhvdWdoIHRoZSBleHBlcmltZW50IGNvbmRpdGlvbnMgd2VyZSByYXRlZCBoaWdoZXIgb24gYXZlcmFnZSwgYW5kIHRoZSBmaWxsZXIgc2VudGVuY2VzIHJlY2VpdmVkIGEgYnJvYWRlciByYW5nZSBvZiByYXRpbmdzLg0KDQpgYGB7ciByZXN1bHRzX3RhYmxlX210dXJrfQ0KIyBNYWtlIHN1cmUgcmF0aW5ncyBkYXRhIGlzIG51bWVyaWMNCmV4cGVyaW1lbnRfZGF0YV9tdHVyayRyYXRpbmcgJTw+JSBhcy5udW1lcmljDQoNCiMgUmV2ZXJzZSBsZXZlbHMgb2YgdGhlIGludGVybVN1YmogKHN1YmplY3QpIGZhY3RvciB0byBtaXJyb3IgZGlzY3Vzc2lvbg0KIyBJbmRlZmluaXRlIGJlZm9yZSBEZWZpbml0ZQ0KZXhwZXJpbWVudF9kYXRhX210dXJrJGludGVybVN1YmogPC0gcmVsZXZlbChleHBlcmltZW50X2RhdGFfbXR1cmskaW50ZXJtU3ViaiwgImluZGVmIikNCiMgJ3RoZXJlJyBiZWZvcmUgaW5kZWZpbml0ZSBhbmQgZGVmaW5pdGUNCmV4cGVyaW1lbnRfZGF0YV9tdHVyayRpbnRlcm1TdWJqIDwtIHJlbGV2ZWwoZXhwZXJpbWVudF9kYXRhX210dXJrJGludGVybVN1YmosICJ0aGVyZSIpDQoNCiMgU3VtbWFyaXplIHRoZSBleHBlcmltZW50YWwgZGF0YQ0KZXhwZXJpbWVudF9kYXRhX210dXJrICU+JQ0KICBncm91cF9ieShpbnRlcm1TdWJqLCBkZXBlbmRlbmN5VHlwZSkgJT4lDQogIGRwbHlyOjpzdW1tYXJpemUobWVhblJhdGluZyA9IG1lYW4ocmF0aW5nKSwNCiAgICAgICAgICAgICAgICAgICBzZC5yYXRpbmcgPSBzZChyYXRpbmcpLA0KICAgICAgICAgICAgICAgICAgIG4gPSBuKCksDQogICAgICAgICAgICAgICAgICAgc2UucmF0aW5nID0gc2QucmF0aW5nL3NxcnQobikpIC0+IGRlc2NyaXB0aXZlX3N1bW1hcnlfbXR1cmsNCg0KIyBTdW1tYXJpemUgdGhlIGZpbGxlciBkYXRhDQpmaWxsZXJfZGF0YV9tdHVyayAlPiUgZ3JvdXBfYnkoaXRlbUlELA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkR3JhbW0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbVR5cGUpICU+JQ0KICBkcGx5cjo6c3VtbWFyaXplKG1lYW5fcmF0aW5nID0gbWVhbihyYXRpbmcpLA0KICAgICAgICAgICAgICAgICAgIHNkX3JhdGluZyA9IHNkKHJhdGluZyksDQogICAgICAgICAgICAgICAgICAgbiA9IG4oKSwNCiAgICAgICAgICAgICAgICAgICBzZV9yYXRpbmcgPSBzZF9yYXRpbmcvc3FydChuKSkgLT4gZGVzY3JpcHRpdmVfc3VtbWFyeV9tdHVya19maWxsZXJzDQoNCiMgTWFrZSBhIHRhYmxlDQpwcmludChkZXNjcmlwdGl2ZV9zdW1tYXJ5X210dXJrKQ0KYGBgDQoNCmBgYHtyIHJhdGluZ3NfcGxvdF93X2ZpbGxlcnNfbXR1cmt9DQojIFNhbWUgcGxvdCBmb3IgRXhwdDIgTVR1cmsgdmVyc2lvbiB3LyBmaWxsZXJzIG92ZXJsYWlkDQpkZXNjcmlwdGl2ZV9zdW1tYXJ5X210dXJrICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBpbnRlcm1TdWJqLA0KICAgICAgICAgICAgIHkgPSBtZWFuUmF0aW5nLA0KICAgICAgICAgICAgIHltaW4gPSAxLA0KICAgICAgICAgICAgIHltYXggPSA2LA0KICAgICAgICAgICAgIGNvbG91ciA9IGRlcGVuZGVuY3lUeXBlLA0KICAgICAgICAgICAgIGdyb3VwID0gZGVwZW5kZW5jeVR5cGUpKSAtPiBkZXNjcmlwdGl2ZV9wbG90X2ZpbGxlcnNfbXR1cmsNCg0KZGVzY3JpcHRpdmVfcGxvdF9maWxsZXJzX210dXJrICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgbGFicyh4ID0gIlN1YmplY3QiLA0KICAgICAgIHkgPSAiTWVhbiByYXRpbmciLA0KICAgICAgIGNvbG91ciA9ICJEZXBlbmRlbmN5IHR5cGUiLA0KICAgICAgIGxpbmV0eXBlID0gIkl0ZW0gdHlwZSIpICsNCiAgc2NhbGVfbGluZXR5cGVfZGlzY3JldGUobGFiZWxzID0gIkZpbGxlciIpICsNCiAgc2NhbGVfY29sb3JfZGlzY3JldGUobGFiZWxzID0gYygiQW5hcGhvcmljIiwgIk1vdmVtZW50IikpICsNCiAgZ2VvbV9obGluZShkYXRhID0gZGVzY3JpcHRpdmVfc3VtbWFyeV9tdHVya19maWxsZXJzLA0KICAgICAgICAgICAgIGFlcyh5aW50ZXJjZXB0ID0gbWVhbl9yYXRpbmcsDQogICAgICAgICAgICAgICAgIGxpbmV0eXBlID0gaXRlbVR5cGUpLA0KICAgICAgICAgICAgIGNvbG9yID0gIm9yYW5nZSIsDQogICAgICAgICAgICAgYWxwaGEgPSAwLjM1LA0KICAgICAgICAgICAgIHNob3cubGVnZW5kID0gVFJVRSkgKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gbWVhblJhdGluZyAtIHNlLnJhdGluZywNCiAgICAgICAgICAgICAgICAgICAgeW1heCA9IG1lYW5SYXRpbmcgKyBzZS5yYXRpbmcpLA0KICAgICAgICAgICAgICAgIHdpZHRoID0gMC4xMCkgKw0KICBnZW9tX3BvaW50KGFlcyhjb2wgPSBkZXBlbmRlbmN5VHlwZSksDQogICAgICAgICAgICAgc2l6ZSA9IDMpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgxOjYpKSArDQogIHRoZW1lKHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLCAjIGNvbHVtbiBsYWJlbHMNCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgIyB0ZXh0IG9mIHgtYXhpcyB0aXRsZSAoaGVyZSwgIkludGVybWVkaWF0ZSBzdWJqZWN0IikNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbiA9IG1hcmdpbigwLjUsIE5BLCAwLjUsIE5BLCAiY20iKSksDQogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsICMgdGV4dCBvZiB5LWF4aXMgdGl0bGUgKGhlcmUsICJNZWFuIHJhdGluZyIpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSBtYXJnaW4oTkEsIDAuNSwgTkEsIDAuNSwgImNtIikpKSAtPiBkZXNjcmlwdGl2ZV9wbG90X2ZpbGxlcnNfbXR1cmsNCmRlc2NyaXB0aXZlX3Bsb3RfZmlsbGVyc19tdHVyaw0KYGBgDQoNCiMjIE9yZGluYWwgcmVncmVzc2lvbiBhbmFseXNpcw0KDQpUaGUgb3JkaW5hbCByZWdyZXNzaW9uIGFuYWx5c2lzIHByaW50ZWQgYmVsb3cgd2FzIHJ1biBvbiB0aGUgaHVtbWluZ2JpcmQgY2x1c3RlciB1c2luZyB0aGUgcmF0aW5ncyBkYXRhIGZyb20gVmVyc2lvbiAyIG9mIHRoaXMgZXhwZXJpbWVudC4gVGhlIGZvbGxvd2luZyBjb2RlIGNodW5rIHNldHMgdGhlIGNvbnRyYXN0cyBmb3IgdGhlIHR3byBkZmlmZXJlbnQgZmFjdG9ycy4gRm9yIHRoZSB0aHJlZS1sZXZlbCBmYWN0b3IsIEhlbG1lcnQgY29udHJhc3QgY29kaW5nIHdhcyB1c2VkIHNvIHRoYXQgdGhlIGV4aXN0ZW50aWFsICgqdGhlcmUqKSBjb25kaXRpb25zIHdvdWxkIGJlIGNvbXBhcmVkIHRvIHRoZSBjb21iaW5hdGlvbiBvZiB0aGUgb3RoZXIgY29uZGl0aW9ucywgYW5kIHNvIHRoYXQgdGhlIGluZGVmaW5pdGUgYW5kIGRlZmluaXRlIGNvbmRpdGlvbnMgd291bGQgb25seSBiZSBjb21wYXJlZCBkaXJlY3RseSB0byBlYWNoIG90aGVyLg0KDQpgYGB7ciBjb250cmFzdHN9DQojIE1ha2Ugc3VyZSByYXRpbmdzIGRhdGEgaXMgYSBmYWN0b3INCmV4cGVyaW1lbnRfZGF0YV9tdHVyayRyYXRpbmcgJTw+JSBhcy5mYWN0b3INCg0KIyBIZWxtZXJ0IGNvbnRyYXN0LWNvZGluZw0KY29udHJhc3RzKGV4cGVyaW1lbnRfZGF0YV9tdHVyayRpbnRlcm1TdWJqKSA8LSAiY29udHIuaGVsbWVydCINCg0KIyBSZW5hbWUgY29udHJhc3QgY29sdW1uIG5hbWVzDQpkaW1uYW1lcyhjb250cmFzdHMoZXhwZXJpbWVudF9kYXRhX210dXJrJGludGVybVN1YmopKVtbMl1dIDwtIGMoImRlZmluaXRlbmVzcyIsICJoZWlnaHQiKQ0KDQojIEZpeCBIZWxtZXJ0IGNvbnRyYXN0IGNvZGluZyBzbyB0aGF0IGluIERFRklOSVRFTkVTUyBjb21wYXJpc29uLCAndGhlcmUnIGlzIG5ldXRyYWxpemVkLCBhbmQgaW4gSEVJR0hUIGNvbXBhcmlzb24sICd0aGVyZScgaXMgY29tcGFyZWQgdG8gYm90aCBkZWYgYW5kIGluZGVmDQpjb250cmFzdHMoZXhwZXJpbWVudF9kYXRhX210dXJrJGludGVybVN1YmopWzEsXSA8LSBjKDAsIDIpDQpjb250cmFzdHMoZXhwZXJpbWVudF9kYXRhX210dXJrJGludGVybVN1YmopWzIsXSA8LSBjKDEsIC0xKQ0KY29udHJhc3RzKGV4cGVyaW1lbnRfZGF0YV9tdHVyayRpbnRlcm1TdWJqKVszLF0gPC0gYygtMSwgLTEpDQoNCiMgU2hvdyBjb250cmFzdHMgZm9yIFN1YmplY3QgZmFjdG9yDQpjb250cmFzdHMoZXhwZXJpbWVudF9kYXRhX210dXJrJGludGVybVN1YmopDQoNCiMgU2V0IGNvbnRyYXN0cyBmb3IgZGVwZW5kZW5jeSB0eXBlICYgc2hvdw0KY29udHJhc3RzKGV4cGVyaW1lbnRfZGF0YV9tdHVyayRkZXBlbmRlbmN5VHlwZSkgPC0gYygtMC41LCAwLjUpDQoNCiMgU2hvdyBjb250cmFzdHMgZm9yIGRlcGVuZGVuY3kgdHlwZSBmYWN0b3INCmNvbnRyYXN0cyhleHBlcmltZW50X2RhdGFfbXR1cmskZGVwZW5kZW5jeVR5cGUpDQoNCiMgU2F2ZSBSRFMgZmlsZSBmb3IgdXNlIGluIG90aGVyIHNjcmlwdHMNCnNhdmVSRFMoZXhwZXJpbWVudF9kYXRhX210dXJrLCBmaWxlID0gImV4cHQyX2RhdGFfbXR1cmsucmRzIikNCmBgYA0KDQpUaGUgbWl4ZWQgZWZmZWN0cyBvcmRpbmFsIHJlZ3Jlc3Npb24gYW5hbHlzaXMgd2FzIHJ1biBvbiB0aGUgW1VDU0MgaHVtbWluZ2JpcmQgY2x1c3Rlcl0oaHR0cHM6Ly93d3cuaGIudWNzYy5lZHUpIGFzIGZvbGxvd3MuDQoNCmBgYHtyIGNsbW1fYW5hbHlzaXMsIGV2YWwgPSBGQUxTRX0NCiMgRnVsbCBtaXhlZCBlZmZlY3RzIGFuYWx5c2lzIHJ1biBvbiB0aGUgaHVtbWluZ2JpcmQgY2x1c3RlciBhcyBmb2xsb3dzDQojIFJlYWQgaW4gdGhlIGRhdGEgc2F2ZWQgZnJvbSBwZXJzb25hbCBjb21wdXRlcg0KcmVhZFJEUyhmaWxlID0gImV4cHQyX2RhdGFfbXR1cmsucmRzIikgLT4gZXhwdDJfZGF0YQ0KDQojIFJ1biBvcmRpbmFsIHJlZ3Jlc3Npb24gYW5hbHlzaXMNCmNsbW0oZGF0YSA9IGV4cHQyX2RhdGEsDQogICAgICMgUmF0aW5nIGFzIGRlcGVuZGVudCB2YXJpYWJsZSwgZml4ZWQgZWZmZWN0cyBhcyBpbnRlcm1TdWJqLCBkZXBlbmRlbmN5VHlwZSwgYW5kIHRoZWlyIGludGVyYWN0aW9ucw0KICAgICBmb3JtdWxhID0gcmF0aW5nIH4gaW50ZXJtU3ViaiAqIGRlcGVuZGVuY3lUeXBlICsNCiAgICAgICAjIFJhbmRvbSBlZmZlY3RzIGJ5IHN1YmplY3QNCiAgICAgICAoMSArIGludGVybVN1YmogKiBkZXBlbmRlbmN5VHlwZSB8IHN1YmplY3QpICsNCiAgICAgICAjIFJhbmRvbSBlZmZlY3RzIGJ5IGl0ZW0NCiAgICAgICAoMSArIGludGVybVN1YmogKiBkZXBlbmRlbmN5VHlwZSB8IGl0ZW1TZXQpDQogICAgICkgLT4gZXhwdDJfY2xtbV9mdWxsDQoNCiMgU2F2ZSBleHB0Ml9jbG1tX2Z1bGwNCnNhdmVSRFMoZXhwdDJfY2xtbV9mdWxsLCAiZXhwdDJfY2xtbV9mdWxsXzIwMTgxMTE4LnJkcyIpDQpgYGANCg0KDQpgYGB7ciBjbG1tX291dHB1dH0NCiMgUmVhZCBpbiBjbG1tIGRhdGEgc2F2ZWQgZnJvbSBjbHVzdGVyDQpyZWFkUkRTKCJleHB0Ml9jbG1tX2Z1bGxfMjAxODExMTgucmRzIikgLT4gZXhwdDJfY2xtbV9jbHVzdGVyDQpzdW1tYXJ5KGV4cHQyX2NsbW1fY2x1c3RlcikNCmBgYA0KDQpgYGB7ciBwbG90X2NsbW0sIGluY2x1ZGUgPSBGQUxTRX0NCmxpYnJhcnkoTUFTUykNCmxpYnJhcnkoZWZmZWN0cykNCnBsb3QoRWZmZWN0KGMoImludGVybVN1YmoiLCAiZGVwZW5kZW5jeVR5cGUiKSwgZXhwdDJfY2xtbV9jbHVzdGVyKSwgbGluZXM9bGlzdChtdWx0aWxpbmU9VFJVRSkpDQpgYGA=