The dataset I am exploring is the English language keystroke pairs in
the Microsoft
Research Spelling-Correction Data collected through MTurk. Each
keystroke pair consists of a user’s spelling error and their correction.
There are 44,104 keystroke pairs in the dataset, so I decided to look at
smaller categories within the data to make it more manageable.
library(tidyverse)
errors <- read.delim("C:/Users/delee/OneDrive/Desktop/all_keystroke_pairs.txt", quote = "")
View(errors)
Error Frequency by Number
First, I filtered the data for errors that were corrected to number
terms from one to ten. Notably, this discounts keystroke pairs in which
both the error and the correction are misspelled number terms. Many
items in this dataset are pairs in which the typer still did not spell a
word correctly in their second attempt (who among us), but we don’t know
what they were trying to type in these cases.
I had to do some finagling to order the data correctly. Even when I
managed to get them in numerical order in the dataset by introducing a
column of the corresponding digits, they appeared in alphabetical order
in the visualization. I went through a lot of grief trying to correct
this, and eventually Leyla helped me out by recommending a line of code
involving factors and levels.
number_errors_vector <- c("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten")
number_errors <- errors %>%
filter(correction %in% c("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten")) %>%
mutate(digit = case_when(
endsWith(correction, "one") ~ "01",
endsWith(correction, "two") ~ "02",
endsWith(correction, "three") ~ "03",
endsWith(correction, "four") ~ "04",
endsWith(correction, "five") ~ "05",
endsWith(correction, "six") ~ "06",
endsWith(correction, "seven") ~ "07",
endsWith(correction, "eight") ~ "08",
endsWith(correction, "nine") ~ "09",
endsWith(correction, "ten") ~ "10"))
number_errors$digit <- as.numeric(as.character(number_errors$digit))
number_errors <- number_errors[order(number_errors$digit), ]
number_errors$correction <- factor(number_errors$correction,levels = unique(number_errors$correction),ordered = T)
View(number_errors)
ggplot(number_errors) +
geom_bar(aes(x = correction, fill = correction)) +
labs(title = "Error Frequency by Number",
x = "Numbers",
y = "Frequency") +
theme(legend.position = "none", panel.background = element_rect(fill = "pink"))

It looks like “two” is the most-misspelled number term by a long
shot, with over 150 misspellings in the dataset. There is also a major
drop off in misspellings of numbers after three, which I can only assume
can be attributed to people using digits in favor of spelled-out number
terms for higher numbers. I think it makes more sense that there would
be an overall lower frequency for larger number terms as opposed to a
higher accuracy rate in typing them.
Error Frequency by Color
Then I turned to color terms. I opted to stick to the widely- (though
I’m sure not universally-) agreed-upon eleven basic color terms in
English, partially because many non-basic color terms in English derive
from nouns with the same spelling, meaning it would be hard to tell
whether or not the typer was using the word as a color term. The only
basic color term where that issue arises is orange, but I decided I
could live with that.
Here, I added two columns to the dataset: one with digits so I could
get the data in the desired order, and one with shortened keys for each
color name so that they could all fit comfortably and legibly as labels
on the bar graph.
color_errors_vector <- c("pink", "red", "orange", "yellow", "green", "blue", "purple", "brown", "black", "grey", "gray", "white")
color_errors <- errors %>%
filter(correction %in% c("pink", "red", "orange", "yellow", "green", "blue", "purple", "brown", "black", "grey", "gray", "white")) %>%
mutate(color_lab = case_when(
correction == "pink" ~ "Pi",
correction == "red" ~ "R",
correction == "orange" ~ "O",
correction == "yellow" ~ "Y",
correction == "green" ~ "Green",
correction == "blue" ~ "Blue",
correction == "purple" ~ "Pu",
correction == "brown" ~ "Br",
correction == "black" ~ "Bla",
correction == "grey" | correction == "gray" ~ "Grey",
correction == "white" ~ "W")) %>%
mutate(color_id = case_when(
correction == "pink" ~ "01",
correction == "red" ~ "02",
correction == "orange" ~ "03",
correction == "yellow" ~ "04",
correction == "green" ~ "05",
correction == "blue" ~ "06",
correction == "purple" ~ "07",
correction == "brown" ~ "08",
correction == "black" ~ "09",
correction == "grey" | correction == "gray" ~ "10",
correction == "white" ~ "11"))
color_errors$color_id <- as.numeric(as.character(color_errors$color_id))
color_errors <- color_errors[order(color_errors$color_id), ]
color_errors$color_lab <- factor(color_errors$color_lab,levels = unique(color_errors$color_lab),ordered = T)
View(color_errors)
ggplot(color_errors) +
geom_bar(aes(x = color_lab, fill = correction)) +
labs(title = "Error Frequency by Color",
x = "Colors",
y = "Frequency") +
theme(legend.position = "none", panel.background = element_rect(fill = "#1D2257")) +
scale_fill_manual("legend", values = c("pink" = "#FB7189", "red" = "#F03621", "orange" = "#F68f1d", "yellow" = "#FBD236", "green" = "#539232", "blue" = "#3D8FC6", "purple" = "#772B7F", "brown" = "#7D451E", "black" = "black", "white" = "white", "gray" = "gray", "grey" = "grey"))

Here we can see that the most-misspelled basic color term is “white”,
followed closely by “black”–a duo that is often considered by artists,
scientists, and other pedants not to be colors at all. Interesting! I
would guess that in this case as well, it’s an issue of frequency.
“Black” and “white” can be used imprecisely to describe things that are
dark and light in a way that’s less strict than how the word “purple” is
mostly just used to describe things that are purple. There are other
applications of these words, too, beyond their color meanings, like as
race descriptors.
“Grey” (and “gray”–I’ve combined the two into one column) scores the
least misspellings. I wonder if the dual spellings make us think extra
carefully when we type the word. Two of the “errors” corrected to “gray”
were simply the with-an-E variant–it’s just as likely that the typers
couldn’t make up their minds between the two spellings as the
possibility that they typed the first one by accident when aiming for
the other, which I consider to be the prototypical typo narrative.
Discussion
I think there are plenty of other worthwhile inquiries to be made
about this data. I spoke on Monday with Kaung Zan, Michael, and Eliana
about various ways of measuring the “distance” between the error and the
correction, like the number of letters that are different between the
two, or the distance between two keys on a keyboard in the case of
letter substitution errors.
I know there are also different factors that drive us to make
different kinds of errors (which I’ve been noticing much more while
working on this project)–typing fast can cause us to miss a key or
switch two letters around, mentally narrating as we type can cause us to
substitute phonologically similar letters, and thinking about something
else or hearing someone speak while we type can cause us to output
something totally wrong. Trying to quantify these motivations would take
a lot of guesswork, but it’s possible to measure the ways they manifest,
at least in the case of more frequent and straightforward errors
(e.g. elision, substitution, swapping).
Another metric to measure here could be the proportion of errors that
were corrected to real, correctly-spelled words. However, there would be
similar complications to the above in drawing conclusions about this
set, and we would not be able to say for sure that they qualify as
“true” corrections (as opposed to further errors). For example, since
the data stops only after the correction immediately following the
error, who’s to say what the final corrected term was? What if the typer
intended to misspell the word? What if the immediate correction is a
real, correctly-spelled word, but still the wrong one? What is a “real
word”? What about terms in the data that include digits or punctuation?
It could still be an interesting inquiry, and my hunch from scrolling
through the data is that correctly-spelled corrections would prevail
over incorrectly-spelled corrections.
People type differently from one another for a host of reasons
including motor skills, what kind of keyboard they use, and how they
learned to type. These differences may influence the kinds of errors we
produce when we type. It was interesting looking at the full set of
typing errors and seeing the wide range of ways we make typos, which we
often quickly delete and move on from without a second thought.
I would be remiss if I didn’t mention that I think Amazon’s
Mechanical Turk (the source of this dataset) and other similar digital
micro-job platforms are highly exploitative operations.
Thnak yuou fr readig y ntebook :)
(^all real errors from the dataset)
Data: (2024, July 15). Microsoft Research Spelling-Correction
Data. Microsoft Download Center. https://www.microsoft.com/en-us/download/details.aspx?id=52418
LS0tDQp0aXRsZTogIlNwZWxsaW5nIEVycm9yIEZyZXF1ZW5jeSBieSBXb3JkIENhdGVnb3J5Ig0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOg0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KLS0tDQoNClRoZSBkYXRhc2V0IEkgYW0gZXhwbG9yaW5nIGlzIHRoZSBFbmdsaXNoIGxhbmd1YWdlIGtleXN0cm9rZSBwYWlycyBpbiB0aGUgW01pY3Jvc29mdCBSZXNlYXJjaCBTcGVsbGluZy1Db3JyZWN0aW9uIERhdGEgY29sbGVjdGVkIHRocm91Z2ggTVR1cmtdKGh0dHBzOi8vd3d3Lm1pY3Jvc29mdC5jb20vZW4tdXMvZG93bmxvYWQvZGV0YWlscy5hc3B4P2lkPTUyNDE4KS4gRWFjaCBrZXlzdHJva2UgcGFpciBjb25zaXN0cyBvZiBhIHVzZXIncyBzcGVsbGluZyBlcnJvciBhbmQgdGhlaXIgY29ycmVjdGlvbi4gVGhlcmUgYXJlIDQ0LDEwNCBrZXlzdHJva2UgcGFpcnMgaW4gdGhlIGRhdGFzZXQsIHNvIEkgZGVjaWRlZCB0byBsb29rIGF0IHNtYWxsZXIgY2F0ZWdvcmllcyB3aXRoaW4gdGhlIGRhdGEgdG8gbWFrZSBpdCBtb3JlIG1hbmFnZWFibGUuDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KZXJyb3JzIDwtIHJlYWQuZGVsaW0oIkM6L1VzZXJzL2RlbGVlL09uZURyaXZlL0Rlc2t0b3AvYWxsX2tleXN0cm9rZV9wYWlycy50eHQiLCBxdW90ZSA9ICIiKQ0KVmlldyhlcnJvcnMpDQpgYGANCiMjIEVycm9yIEZyZXF1ZW5jeSBieSBOdW1iZXINCg0KRmlyc3QsIEkgZmlsdGVyZWQgdGhlIGRhdGEgZm9yIGVycm9ycyB0aGF0IHdlcmUgY29ycmVjdGVkIHRvIG51bWJlciB0ZXJtcyBmcm9tIG9uZSB0byB0ZW4uICBOb3RhYmx5LCB0aGlzIGRpc2NvdW50cyBrZXlzdHJva2UgcGFpcnMgaW4gd2hpY2ggYm90aCB0aGUgZXJyb3IgYW5kIHRoZSBjb3JyZWN0aW9uIGFyZSBtaXNzcGVsbGVkIG51bWJlciB0ZXJtcy4gIE1hbnkgaXRlbXMgaW4gdGhpcyBkYXRhc2V0IGFyZSBwYWlycyBpbiB3aGljaCB0aGUgdHlwZXIgc3RpbGwgZGlkIG5vdCBzcGVsbCBhIHdvcmQgY29ycmVjdGx5IGluIHRoZWlyIHNlY29uZCBhdHRlbXB0ICh3aG8gYW1vbmcgdXMpLCBidXQgd2UgZG9uJ3Qga25vdyB3aGF0IHRoZXkgd2VyZSB0cnlpbmcgdG8gdHlwZSBpbiB0aGVzZSBjYXNlcy4NCg0KSSBoYWQgdG8gZG8gc29tZSBmaW5hZ2xpbmcgdG8gb3JkZXIgdGhlIGRhdGEgY29ycmVjdGx5LiAgRXZlbiB3aGVuIEkgbWFuYWdlZCB0byBnZXQgdGhlbSBpbiBudW1lcmljYWwgb3JkZXIgaW4gdGhlIGRhdGFzZXQgYnkgaW50cm9kdWNpbmcgYSBjb2x1bW4gb2YgdGhlIGNvcnJlc3BvbmRpbmcgZGlnaXRzLCB0aGV5IGFwcGVhcmVkIGluIGFscGhhYmV0aWNhbCBvcmRlciBpbiB0aGUgdmlzdWFsaXphdGlvbi4gIEkgd2VudCB0aHJvdWdoIGEgbG90IG9mIGdyaWVmIHRyeWluZyB0byBjb3JyZWN0IHRoaXMsIGFuZCBldmVudHVhbGx5IExleWxhIGhlbHBlZCBtZSBvdXQgYnkgcmVjb21tZW5kaW5nIGEgbGluZSBvZiBjb2RlIGludm9sdmluZyBmYWN0b3JzIGFuZCBsZXZlbHMuDQpgYGB7cn0NCm51bWJlcl9lcnJvcnNfdmVjdG9yIDwtIGMoIm9uZSIsICJ0d28iLCAidGhyZWUiLCAiZm91ciIsICJmaXZlIiwgInNpeCIsICJzZXZlbiIsICJlaWdodCIsICJuaW5lIiwgInRlbiIpDQpudW1iZXJfZXJyb3JzIDwtIGVycm9ycyAlPiUNCiAgZmlsdGVyKGNvcnJlY3Rpb24gJWluJSBjKCJvbmUiLCAidHdvIiwgInRocmVlIiwgImZvdXIiLCAiZml2ZSIsICJzaXgiLCAic2V2ZW4iLCAiZWlnaHQiLCAibmluZSIsICJ0ZW4iKSkgJT4lDQogIG11dGF0ZShkaWdpdCA9IGNhc2Vfd2hlbigNCiAgICBlbmRzV2l0aChjb3JyZWN0aW9uLCAib25lIikgfiAiMDEiLA0KICAgIGVuZHNXaXRoKGNvcnJlY3Rpb24sICJ0d28iKSB+ICIwMiIsDQogICAgZW5kc1dpdGgoY29ycmVjdGlvbiwgInRocmVlIikgfiAiMDMiLA0KICAgIGVuZHNXaXRoKGNvcnJlY3Rpb24sICJmb3VyIikgfiAiMDQiLA0KICAgIGVuZHNXaXRoKGNvcnJlY3Rpb24sICJmaXZlIikgfiAiMDUiLA0KICAgIGVuZHNXaXRoKGNvcnJlY3Rpb24sICJzaXgiKSB+ICIwNiIsDQogICAgZW5kc1dpdGgoY29ycmVjdGlvbiwgInNldmVuIikgfiAiMDciLA0KICAgIGVuZHNXaXRoKGNvcnJlY3Rpb24sICJlaWdodCIpIH4gIjA4IiwgDQogICAgZW5kc1dpdGgoY29ycmVjdGlvbiwgIm5pbmUiKSB+ICIwOSIsDQogICAgZW5kc1dpdGgoY29ycmVjdGlvbiwgInRlbiIpIH4gIjEwIikpDQpudW1iZXJfZXJyb3JzJGRpZ2l0IDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKG51bWJlcl9lcnJvcnMkZGlnaXQpKQ0KbnVtYmVyX2Vycm9ycyA8LSBudW1iZXJfZXJyb3JzW29yZGVyKG51bWJlcl9lcnJvcnMkZGlnaXQpLCBdDQpudW1iZXJfZXJyb3JzJGNvcnJlY3Rpb24gPC0gZmFjdG9yKG51bWJlcl9lcnJvcnMkY29ycmVjdGlvbixsZXZlbHMgPSB1bmlxdWUobnVtYmVyX2Vycm9ycyRjb3JyZWN0aW9uKSxvcmRlcmVkID0gVCkNClZpZXcobnVtYmVyX2Vycm9ycykNCmdncGxvdChudW1iZXJfZXJyb3JzKSArDQogIGdlb21fYmFyKGFlcyh4ID0gY29ycmVjdGlvbiwgZmlsbCA9IGNvcnJlY3Rpb24pKSArDQogIGxhYnModGl0bGUgPSAiRXJyb3IgRnJlcXVlbmN5IGJ5IE51bWJlciIsDQogICAgICAgeCA9ICJOdW1iZXJzIiwNCiAgICAgICB5ID0gIkZyZXF1ZW5jeSIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAicGluayIpKQ0KYGBgDQoNCkl0IGxvb2tzIGxpa2UgInR3byIgaXMgdGhlIG1vc3QtbWlzc3BlbGxlZCBudW1iZXIgdGVybSBieSBhIGxvbmcgc2hvdCwgd2l0aCBvdmVyIDE1MCBtaXNzcGVsbGluZ3MgaW4gdGhlIGRhdGFzZXQuICBUaGVyZSBpcyBhbHNvIGEgbWFqb3IgZHJvcCBvZmYgaW4gbWlzc3BlbGxpbmdzIG9mIG51bWJlcnMgYWZ0ZXIgdGhyZWUsIHdoaWNoIEkgY2FuIG9ubHkgYXNzdW1lIGNhbiBiZSBhdHRyaWJ1dGVkIHRvIHBlb3BsZSB1c2luZyBkaWdpdHMgaW4gZmF2b3Igb2Ygc3BlbGxlZC1vdXQgbnVtYmVyIHRlcm1zIGZvciBoaWdoZXIgbnVtYmVycy4gIEkgdGhpbmsgaXQgbWFrZXMgbW9yZSBzZW5zZSB0aGF0IHRoZXJlIHdvdWxkIGJlIGFuIG92ZXJhbGwgbG93ZXIgZnJlcXVlbmN5IGZvciBsYXJnZXIgbnVtYmVyIHRlcm1zIGFzIG9wcG9zZWQgdG8gYSBoaWdoZXIgYWNjdXJhY3kgcmF0ZSBpbiB0eXBpbmcgdGhlbS4NCg0KIyMgRXJyb3IgRnJlcXVlbmN5IGJ5IENvbG9yDQoNClRoZW4gSSB0dXJuZWQgdG8gY29sb3IgdGVybXMuICBJIG9wdGVkIHRvIHN0aWNrIHRvIHRoZSB3aWRlbHktICh0aG91Z2ggSSdtIHN1cmUgbm90IHVuaXZlcnNhbGx5LSkgYWdyZWVkLXVwb24gZWxldmVuIGJhc2ljIGNvbG9yIHRlcm1zIGluIEVuZ2xpc2gsIHBhcnRpYWxseSBiZWNhdXNlIG1hbnkgbm9uLWJhc2ljIGNvbG9yIHRlcm1zIGluIEVuZ2xpc2ggZGVyaXZlIGZyb20gbm91bnMgd2l0aCB0aGUgc2FtZSBzcGVsbGluZywgbWVhbmluZyBpdCB3b3VsZCBiZSBoYXJkIHRvIHRlbGwgd2hldGhlciBvciBub3QgdGhlIHR5cGVyIHdhcyB1c2luZyB0aGUgd29yZCBhcyBhIGNvbG9yIHRlcm0uICBUaGUgb25seSBiYXNpYyBjb2xvciB0ZXJtIHdoZXJlIHRoYXQgaXNzdWUgYXJpc2VzIGlzIG9yYW5nZSwgYnV0IEkgZGVjaWRlZCBJIGNvdWxkIGxpdmUgd2l0aCB0aGF0Lg0KDQpIZXJlLCBJIGFkZGVkIHR3byBjb2x1bW5zIHRvIHRoZSBkYXRhc2V0OiBvbmUgd2l0aCBkaWdpdHMgc28gSSBjb3VsZCBnZXQgdGhlIGRhdGEgaW4gdGhlIGRlc2lyZWQgb3JkZXIsIGFuZCBvbmUgd2l0aCBzaG9ydGVuZWQga2V5cyBmb3IgZWFjaCBjb2xvciBuYW1lIHNvIHRoYXQgdGhleSBjb3VsZCBhbGwgZml0IGNvbWZvcnRhYmx5IGFuZCBsZWdpYmx5IGFzIGxhYmVscyBvbiB0aGUgYmFyIGdyYXBoLg0KYGBge3J9DQpjb2xvcl9lcnJvcnNfdmVjdG9yIDwtIGMoInBpbmsiLCAicmVkIiwgIm9yYW5nZSIsICJ5ZWxsb3ciLCAiZ3JlZW4iLCAiYmx1ZSIsICJwdXJwbGUiLCAiYnJvd24iLCAiYmxhY2siLCAiZ3JleSIsICJncmF5IiwgIndoaXRlIikNCmNvbG9yX2Vycm9ycyA8LSBlcnJvcnMgJT4lDQogIGZpbHRlcihjb3JyZWN0aW9uICVpbiUgYygicGluayIsICJyZWQiLCAib3JhbmdlIiwgInllbGxvdyIsICJncmVlbiIsICJibHVlIiwgInB1cnBsZSIsICJicm93biIsICJibGFjayIsICJncmV5IiwgImdyYXkiLCAid2hpdGUiKSkgJT4lDQogIG11dGF0ZShjb2xvcl9sYWIgPSBjYXNlX3doZW4oDQogICAgY29ycmVjdGlvbiA9PSAicGluayIgfiAiUGkiLA0KICAgIGNvcnJlY3Rpb24gPT0gInJlZCIgfiAiUiIsDQogICAgY29ycmVjdGlvbiA9PSAib3JhbmdlIiB+ICJPIiwNCiAgICBjb3JyZWN0aW9uID09ICJ5ZWxsb3ciIH4gIlkiLA0KICAgIGNvcnJlY3Rpb24gPT0gImdyZWVuIiB+ICJHcmVlbiIsDQogICAgY29ycmVjdGlvbiA9PSAiYmx1ZSIgfiAiQmx1ZSIsDQogICAgY29ycmVjdGlvbiA9PSAicHVycGxlIiB+ICJQdSIsDQogICAgY29ycmVjdGlvbiA9PSAiYnJvd24iIH4gIkJyIiwgDQogICAgY29ycmVjdGlvbiA9PSAiYmxhY2siIH4gIkJsYSIsDQogICAgY29ycmVjdGlvbiA9PSAiZ3JleSIgfCBjb3JyZWN0aW9uID09ICJncmF5IiB+ICJHcmV5IiwNCiAgICBjb3JyZWN0aW9uID09ICJ3aGl0ZSIgfiAiVyIpKSAlPiUNCiAgbXV0YXRlKGNvbG9yX2lkID0gY2FzZV93aGVuKA0KICAgIGNvcnJlY3Rpb24gPT0gInBpbmsiIH4gIjAxIiwNCiAgICBjb3JyZWN0aW9uID09ICJyZWQiIH4gIjAyIiwNCiAgICBjb3JyZWN0aW9uID09ICJvcmFuZ2UiIH4gIjAzIiwNCiAgICBjb3JyZWN0aW9uID09ICJ5ZWxsb3ciIH4gIjA0IiwNCiAgICBjb3JyZWN0aW9uID09ICJncmVlbiIgfiAiMDUiLA0KICAgIGNvcnJlY3Rpb24gPT0gImJsdWUiIH4gIjA2IiwNCiAgICBjb3JyZWN0aW9uID09ICJwdXJwbGUiIH4gIjA3IiwNCiAgICBjb3JyZWN0aW9uID09ICJicm93biIgfiAiMDgiLCANCiAgICBjb3JyZWN0aW9uID09ICJibGFjayIgfiAiMDkiLA0KICAgIGNvcnJlY3Rpb24gPT0gImdyZXkiIHwgY29ycmVjdGlvbiA9PSAiZ3JheSIgfiAiMTAiLA0KICAgIGNvcnJlY3Rpb24gPT0gIndoaXRlIiB+ICIxMSIpKQ0KY29sb3JfZXJyb3JzJGNvbG9yX2lkIDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGNvbG9yX2Vycm9ycyRjb2xvcl9pZCkpDQpjb2xvcl9lcnJvcnMgPC0gY29sb3JfZXJyb3JzW29yZGVyKGNvbG9yX2Vycm9ycyRjb2xvcl9pZCksIF0NCmNvbG9yX2Vycm9ycyRjb2xvcl9sYWIgPC0gZmFjdG9yKGNvbG9yX2Vycm9ycyRjb2xvcl9sYWIsbGV2ZWxzID0gdW5pcXVlKGNvbG9yX2Vycm9ycyRjb2xvcl9sYWIpLG9yZGVyZWQgPSBUKQ0KVmlldyhjb2xvcl9lcnJvcnMpDQpnZ3Bsb3QoY29sb3JfZXJyb3JzKSArDQogIGdlb21fYmFyKGFlcyh4ID0gY29sb3JfbGFiLCBmaWxsID0gY29ycmVjdGlvbikpICsNCiAgbGFicyh0aXRsZSA9ICJFcnJvciBGcmVxdWVuY3kgYnkgQ29sb3IiLA0KICAgICAgIHggPSAiQ29sb3JzIiwNCiAgICAgICB5ID0gIkZyZXF1ZW5jeSIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiIzFEMjI1NyIpKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKCJsZWdlbmQiLCB2YWx1ZXMgPSBjKCJwaW5rIiA9ICIjRkI3MTg5IiwgInJlZCIgPSAiI0YwMzYyMSIsICJvcmFuZ2UiID0gIiNGNjhmMWQiLCAieWVsbG93IiA9ICIjRkJEMjM2IiwgImdyZWVuIiA9ICIjNTM5MjMyIiwgImJsdWUiID0gIiMzRDhGQzYiLCAicHVycGxlIiA9ICIjNzcyQjdGIiwgImJyb3duIiA9ICIjN0Q0NTFFIiwgImJsYWNrIiA9ICJibGFjayIsICJ3aGl0ZSIgPSAid2hpdGUiLCAiZ3JheSIgPSAiZ3JheSIsICJncmV5IiA9ICJncmV5IikpDQpgYGANCg0KSGVyZSB3ZSBjYW4gc2VlIHRoYXQgdGhlIG1vc3QtbWlzc3BlbGxlZCBiYXNpYyBjb2xvciB0ZXJtIGlzICJ3aGl0ZSIsIGZvbGxvd2VkIGNsb3NlbHkgYnkgImJsYWNrIi0tYSBkdW8gdGhhdCBpcyBvZnRlbiBjb25zaWRlcmVkIGJ5IGFydGlzdHMsIHNjaWVudGlzdHMsIGFuZCBvdGhlciBwZWRhbnRzIG5vdCB0byBiZSBjb2xvcnMgYXQgYWxsLiAgSW50ZXJlc3RpbmchICBJIHdvdWxkIGd1ZXNzIHRoYXQgaW4gdGhpcyBjYXNlIGFzIHdlbGwsIGl0J3MgYW4gaXNzdWUgb2YgZnJlcXVlbmN5LiAgIkJsYWNrIiBhbmQgIndoaXRlIiBjYW4gYmUgdXNlZCBpbXByZWNpc2VseSB0byBkZXNjcmliZSB0aGluZ3MgdGhhdCBhcmUgZGFyayBhbmQgbGlnaHQgaW4gYSB3YXkgdGhhdCdzIGxlc3Mgc3RyaWN0IHRoYW4gaG93IHRoZSB3b3JkICJwdXJwbGUiIGlzIG1vc3RseSBqdXN0IHVzZWQgdG8gZGVzY3JpYmUgdGhpbmdzIHRoYXQgYXJlIHB1cnBsZS4gIFRoZXJlIGFyZSBvdGhlciBhcHBsaWNhdGlvbnMgb2YgdGhlc2Ugd29yZHMsIHRvbywgYmV5b25kIHRoZWlyIGNvbG9yIG1lYW5pbmdzLCBsaWtlIGFzIHJhY2UgZGVzY3JpcHRvcnMuDQoNCiJHcmV5IiAoYW5kICJncmF5Ii0tSSd2ZSBjb21iaW5lZCB0aGUgdHdvIGludG8gb25lIGNvbHVtbikgc2NvcmVzIHRoZSBsZWFzdCBtaXNzcGVsbGluZ3MuICBJIHdvbmRlciBpZiB0aGUgZHVhbCBzcGVsbGluZ3MgbWFrZSB1cyB0aGluayBleHRyYSBjYXJlZnVsbHkgd2hlbiB3ZSB0eXBlIHRoZSB3b3JkLiAgVHdvIG9mIHRoZSAiZXJyb3JzIiBjb3JyZWN0ZWQgdG8gImdyYXkiIHdlcmUgc2ltcGx5IHRoZSB3aXRoLWFuLUUgdmFyaWFudC0taXQncyBqdXN0IGFzIGxpa2VseSB0aGF0IHRoZSB0eXBlcnMgY291bGRuJ3QgbWFrZSB1cCB0aGVpciBtaW5kcyBiZXR3ZWVuIHRoZSB0d28gc3BlbGxpbmdzIGFzIHRoZSBwb3NzaWJpbGl0eSB0aGF0IHRoZXkgdHlwZWQgdGhlIGZpcnN0IG9uZSBieSBhY2NpZGVudCB3aGVuIGFpbWluZyBmb3IgdGhlIG90aGVyLCB3aGljaCBJIGNvbnNpZGVyIHRvIGJlIHRoZSBwcm90b3R5cGljYWwgdHlwbyBuYXJyYXRpdmUuIA0KDQojIyBEaXNjdXNzaW9uDQoNCkkgdGhpbmsgdGhlcmUgYXJlIHBsZW50eSBvZiBvdGhlciB3b3J0aHdoaWxlIGlucXVpcmllcyB0byBiZSBtYWRlIGFib3V0IHRoaXMgZGF0YS4gIEkgc3Bva2Ugb24gTW9uZGF5IHdpdGggS2F1bmcgWmFuLCBNaWNoYWVsLCBhbmQgRWxpYW5hIGFib3V0IHZhcmlvdXMgd2F5cyBvZiBtZWFzdXJpbmcgdGhlICJkaXN0YW5jZSIgYmV0d2VlbiB0aGUgZXJyb3IgYW5kIHRoZSBjb3JyZWN0aW9uLCBsaWtlIHRoZSBudW1iZXIgb2YgbGV0dGVycyB0aGF0IGFyZSBkaWZmZXJlbnQgYmV0d2VlbiB0aGUgdHdvLCBvciB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0d28ga2V5cyBvbiBhIGtleWJvYXJkIGluIHRoZSBjYXNlIG9mIGxldHRlciBzdWJzdGl0dXRpb24gZXJyb3JzLg0KDQpJIGtub3cgdGhlcmUgYXJlIGFsc28gZGlmZmVyZW50IGZhY3RvcnMgdGhhdCBkcml2ZSB1cyB0byBtYWtlIGRpZmZlcmVudCBraW5kcyBvZiBlcnJvcnMgKHdoaWNoIEkndmUgYmVlbiBub3RpY2luZyBtdWNoIG1vcmUgd2hpbGUgd29ya2luZyBvbiB0aGlzIHByb2plY3QpLS10eXBpbmcgZmFzdCBjYW4gY2F1c2UgdXMgdG8gbWlzcyBhIGtleSBvciBzd2l0Y2ggdHdvIGxldHRlcnMgYXJvdW5kLCBtZW50YWxseSBuYXJyYXRpbmcgYXMgd2UgdHlwZSBjYW4gY2F1c2UgdXMgdG8gc3Vic3RpdHV0ZSBwaG9ub2xvZ2ljYWxseSBzaW1pbGFyIGxldHRlcnMsIGFuZCB0aGlua2luZyBhYm91dCBzb21ldGhpbmcgZWxzZSBvciBoZWFyaW5nIHNvbWVvbmUgc3BlYWsgd2hpbGUgd2UgdHlwZSBjYW4gY2F1c2UgdXMgdG8gb3V0cHV0IHNvbWV0aGluZyB0b3RhbGx5IHdyb25nLiAgVHJ5aW5nIHRvIHF1YW50aWZ5IHRoZXNlIG1vdGl2YXRpb25zIHdvdWxkIHRha2UgYSBsb3Qgb2YgZ3Vlc3N3b3JrLCBidXQgaXQncyBwb3NzaWJsZSB0byBtZWFzdXJlIHRoZSB3YXlzIHRoZXkgbWFuaWZlc3QsIGF0IGxlYXN0IGluIHRoZSBjYXNlIG9mIG1vcmUgZnJlcXVlbnQgYW5kIHN0cmFpZ2h0Zm9yd2FyZCBlcnJvcnMgKGUuZy4gZWxpc2lvbiwgc3Vic3RpdHV0aW9uLCBzd2FwcGluZykuDQoNCkFub3RoZXIgbWV0cmljIHRvIG1lYXN1cmUgaGVyZSBjb3VsZCBiZSB0aGUgcHJvcG9ydGlvbiBvZiBlcnJvcnMgdGhhdCB3ZXJlIGNvcnJlY3RlZCB0byByZWFsLCBjb3JyZWN0bHktc3BlbGxlZCB3b3Jkcy4gIEhvd2V2ZXIsIHRoZXJlIHdvdWxkIGJlIHNpbWlsYXIgY29tcGxpY2F0aW9ucyB0byB0aGUgYWJvdmUgaW4gZHJhd2luZyBjb25jbHVzaW9ucyBhYm91dCB0aGlzIHNldCwgYW5kIHdlIHdvdWxkIG5vdCBiZSBhYmxlIHRvIHNheSBmb3Igc3VyZSB0aGF0IHRoZXkgcXVhbGlmeSBhcyAidHJ1ZSIgY29ycmVjdGlvbnMgKGFzIG9wcG9zZWQgdG8gZnVydGhlciBlcnJvcnMpLiAgRm9yIGV4YW1wbGUsIHNpbmNlIHRoZSBkYXRhIHN0b3BzIG9ubHkgYWZ0ZXIgdGhlIGNvcnJlY3Rpb24gaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRoZSBlcnJvciwgd2hvJ3MgdG8gc2F5IHdoYXQgdGhlIGZpbmFsIGNvcnJlY3RlZCB0ZXJtIHdhcz8gIFdoYXQgaWYgdGhlIHR5cGVyIGludGVuZGVkIHRvIG1pc3NwZWxsIHRoZSB3b3JkPyAgV2hhdCBpZiB0aGUgaW1tZWRpYXRlIGNvcnJlY3Rpb24gaXMgYSByZWFsLCBjb3JyZWN0bHktc3BlbGxlZCB3b3JkLCBidXQgc3RpbGwgdGhlIHdyb25nIG9uZT8gIFdoYXQgaXMgYSAicmVhbCB3b3JkIj8gIFdoYXQgYWJvdXQgdGVybXMgaW4gdGhlIGRhdGEgdGhhdCBpbmNsdWRlIGRpZ2l0cyBvciBwdW5jdHVhdGlvbj8gIEl0IGNvdWxkIHN0aWxsIGJlIGFuIGludGVyZXN0aW5nIGlucXVpcnksIGFuZCBteSBodW5jaCBmcm9tIHNjcm9sbGluZyB0aHJvdWdoIHRoZSBkYXRhIGlzIHRoYXQgY29ycmVjdGx5LXNwZWxsZWQgY29ycmVjdGlvbnMgd291bGQgcHJldmFpbCBvdmVyIGluY29ycmVjdGx5LXNwZWxsZWQgY29ycmVjdGlvbnMuDQoNClBlb3BsZSB0eXBlIGRpZmZlcmVudGx5IGZyb20gb25lIGFub3RoZXIgZm9yIGEgaG9zdCBvZiByZWFzb25zIGluY2x1ZGluZyBtb3RvciBza2lsbHMsIHdoYXQga2luZCBvZiBrZXlib2FyZCB0aGV5IHVzZSwgYW5kIGhvdyB0aGV5IGxlYXJuZWQgdG8gdHlwZS4gIFRoZXNlIGRpZmZlcmVuY2VzIG1heSBpbmZsdWVuY2UgdGhlIGtpbmRzIG9mIGVycm9ycyB3ZSBwcm9kdWNlIHdoZW4gd2UgdHlwZS4gIEl0IHdhcyBpbnRlcmVzdGluZyBsb29raW5nIGF0IHRoZSBmdWxsIHNldCBvZiB0eXBpbmcgZXJyb3JzIGFuZCBzZWVpbmcgdGhlIHdpZGUgcmFuZ2Ugb2Ygd2F5cyB3ZSBtYWtlIHR5cG9zLCB3aGljaCB3ZSBvZnRlbiBxdWlja2x5IGRlbGV0ZSBhbmQgbW92ZSBvbiBmcm9tIHdpdGhvdXQgYSBzZWNvbmQgdGhvdWdodC4NCg0KSSB3b3VsZCBiZSByZW1pc3MgaWYgSSBkaWRuJ3QgbWVudGlvbiB0aGF0IEkgdGhpbmsgQW1hem9uJ3MgTWVjaGFuaWNhbCBUdXJrICh0aGUgc291cmNlIG9mIHRoaXMgZGF0YXNldCkgYW5kIG90aGVyIHNpbWlsYXIgZGlnaXRhbCBtaWNyby1qb2IgcGxhdGZvcm1zIGFyZSBoaWdobHkgZXhwbG9pdGF0aXZlIG9wZXJhdGlvbnMuDQoNClRobmFrIHl1b3UgZnIgcmVhZGlnIHkgbnRlYm9vayA6KQ0KDQooXmFsbCByZWFsIGVycm9ycyBmcm9tIHRoZSBkYXRhc2V0KQ0KDQpEYXRhOg0KKDIwMjQsIEp1bHkgMTUpLiAqTWljcm9zb2Z0IFJlc2VhcmNoIFNwZWxsaW5nLUNvcnJlY3Rpb24gRGF0YSouIE1pY3Jvc29mdCBEb3dubG9hZCBDZW50ZXIuIFtodHRwczovL3d3dy5taWNyb3NvZnQuY29tL2VuLXVzL2Rvd25sb2FkL2RldGFpbHMuYXNweD9pZD01MjQxOF0oaHR0cHM6Ly93d3cubWljcm9zb2Z0LmNvbS9lbi11cy9kb3dubG9hZC9kZXRhaWxzLmFzcHg/aWQ9NTI0MTgp