Work in Progress: Word frequencies
This page is about some of my current work in progress on word frequencies. The visualizations are some experiments concerning the general types of visualizations that I might use. I have included here only the ones that have made the first cut. As I elaborate these static visualizations, I also keep in mind what kinds of interactions would be relevant.
EBB and RB word frequencies
One of the main things we’re interested in when we have a collection of letters is exploring what they are talking about. Word frequencies are a first step on the path in that exploration.
Of course, “small” words like the, a, etc. are common. But with natural language processing, we can identify nouns, pronouns, verbs, etc., and look at them separately. We can also group together the different forms of words (singulars and plurals, past and present tense, …) under their dictionary form (the lemma). That’s what I’ve done here.
As with many of the other examples in the demo videos, I am using the letters between Elizabeth Barrett (EBB, or just E) and Robert Browning (RB, or just R).
Comparing word rankings
The first type of visualization is a slope graph popularized by Edward Tufte. It lets us easily compare the rankings (by frequency) between EBB and RB.
Nouns
First up are nouns. I’m using just the top 20 nouns for each. Lines connect the same word (lemma) for E and R; where there is no line, that means that word does not occur in the other person’s top 20 nouns. For example, Ba (a nickname for EBB) is R’s top noun, but it is not one of EBB’s top 20, even though she signs many of her letters “Ba”. So looking for missing lines, we can see that there is far from complete overlap in EBB and RB’s top 20 nouns.
When we do have a line between EBB’s and RB’s sides, the slope of the line indicates how different their rankings are. For example Mr. is the most frequent noun for EBB, but only 12th for RB. On the other hand, they both have letter in second place.
Main Verbs
Main verbs show a slightly different pattern: here there is much more overlap between the top 20 verbs between them, as seen by the relatively few missing lines. However, their rankings do differ.
Modal Verbs
The modal verbs ( can, could, may, might, …) show yet another pattern. There aren’t very many of them, so it’s not surpising that there is complete overlap. More surprising is that their rankings are very similar, with 4 out the 10 having identical rankings (compared to 1 verb and no nouns with identical rankings).
Pronouns
Pronouns show a mixed pattern, with the top 8 pronouns being very similar, and the rest more different.
Pronouns across time
In addition to looking at the overall rankings of words, we can also look at how the frequency in letters varies over time. In particular, we might want to find the words that vary the most, or the words that vary the least, in terms of their frequency. To do this, we can use the statistical notion of variance to measure variabilty.
When we plot relative frequency vs variance for the pronouns as below, we see that I and you both have relatively high variance, in addition to being frequent. However, we can see that RB uses I much more variably than EBB does: his I is higher in the chart than hers. (We can also see that for both of them, I is more variable than you.)
Of course, we can also see the details of the variability in EBB and RB’s use of I and you over the course of their letters:
In the chart of variance above he, his, and your were the least variable. Here’s what they look like over time.
At first glance, it looks they are just as variable as I and you, but that’s because the scale of the vertical axis covers a narrower range, effectively magnifying the differences. However, if we use the same vertical range as we had for I and you, we see that the variability is in indeed much smaller, though of course it still exists.
In the next part of Work in Progess, I look at another aspect of figuring out what the letters are about: key words.
LS0tCnRpdGxlOiAiV29yayBpbiBQcm9ncmVzczogV29yZCBmcmVxdWVuY2llcyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyMgQ2hyaXMgQ3VseQojIyMjIGluZm9AY2hyaXNjdWx5Lm5ldCAKIyMjIyBbY2hyaXNjdWx5Lm5ldF0oaHR0cDovL2NocmlzY3VseS5uZXQpCiMjIyMgW0JhY2sgdG8gdGhlIGRlbW8gdmlkZW9zXSguLi9pbmRleC5odG1sKQojIyMjIyBSZXZpc2VkIDI3IEF1Z3VzdCAyMDE3CgojIFdvcmsgaW4gUHJvZ3Jlc3M6IFdvcmQgZnJlcXVlbmNpZXMKClRoaXMgcGFnZSBpcyBhYm91dCBzb21lIG9mIG15IGN1cnJlbnQgd29yayBpbiBwcm9ncmVzcyBvbiB3b3JkIGZyZXF1ZW5jaWVzLiBUaGUgdmlzdWFsaXphdGlvbnMgYXJlIHNvbWUgZXhwZXJpbWVudHMgY29uY2VybmluZyB0aGUgZ2VuZXJhbCB0eXBlcyBvZiB2aXN1YWxpemF0aW9ucyB0aGF0IEkgbWlnaHQgdXNlLiBJIGhhdmUgaW5jbHVkZWQgaGVyZSBvbmx5IHRoZSBvbmVzIHRoYXQgaGF2ZSBtYWRlIHRoZSBmaXJzdCBjdXQuIEFzIEkgZWxhYm9yYXRlIHRoZXNlICpzdGF0aWMqIHZpc3VhbGl6YXRpb25zLCBJIGFsc28ga2VlcCBpbiBtaW5kIHdoYXQga2luZHMgb2YgaW50ZXJhY3Rpb25zIHdvdWxkIGJlIHJlbGV2YW50LgoKIyBFQkIgYW5kIFJCIHdvcmQgZnJlcXVlbmNpZXMKCk9uZSBvZiB0aGUgbWFpbiB0aGluZ3Mgd2UncmUgaW50ZXJlc3RlZCBpbiB3aGVuIHdlIGhhdmUgYSBjb2xsZWN0aW9uIG9mIGxldHRlcnMgaXMgZXhwbG9yaW5nIHdoYXQgdGhleSBhcmUgdGFsa2luZyBhYm91dC4gV29yZCBmcmVxdWVuY2llcyBhcmUgYSBmaXJzdCBzdGVwIG9uIHRoZSBwYXRoIGluIHRoYXQgZXhwbG9yYXRpb24uCgpPZiBjb3Vyc2UsICJzbWFsbCIgd29yZHMgbGlrZSBfdGhlXywgX2FfLCBldGMuIGFyZSBjb21tb24uIEJ1dCB3aXRoIG5hdHVyYWwgbGFuZ3VhZ2UgcHJvY2Vzc2luZywgd2UgY2FuIGlkZW50aWZ5IG5vdW5zLCBwcm9ub3VucywgdmVyYnMsIGV0Yy4sIGFuZCBsb29rIGF0IHRoZW0gc2VwYXJhdGVseS4gV2UgY2FuIGFsc28gZ3JvdXAgdG9nZXRoZXIgdGhlIGRpZmZlcmVudCBmb3JtcyBvZiB3b3JkcyAoc2luZ3VsYXJzIGFuZCBwbHVyYWxzLCBwYXN0IGFuZCBwcmVzZW50IHRlbnNlLCAuLi4pIHVuZGVyIHRoZWlyIGRpY3Rpb25hcnkgZm9ybSAodGhlICpsZW1tYSopLiBUaGF0J3Mgd2hhdCBJJ3ZlIGRvbmUgaGVyZS4KCkFzIHdpdGggbWFueSBvZiB0aGUgb3RoZXIgZXhhbXBsZXMgaW4gdGhlIGRlbW8gdmlkZW9zLCBJIGFtIHVzaW5nIHRoZSBsZXR0ZXJzIGJldHdlZW4gRWxpemFiZXRoIEJhcnJldHQgKEVCQiwgb3IganVzdCBFKSBhbmQgUm9iZXJ0IEJyb3duaW5nIChSQiwgb3IganVzdCBSKS4KCgpgYGB7ciBzZXR1cCwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KCmxpYnJhcnkocmVhZHIpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHJlc2hhcGUyKQoKCmluZm8gPC0gcmVhZF9jc3YoIn4vRHJvcGJveC9weXRob25fdGV4dC9nZW5zaW1fdG9waWNzL2ViYnJiX2xlbW1hc19wb3MuY3N2IiwgCiAgICBjb2xfdHlwZXMgPSBjb2xzKGRhdGUgPSBjb2xfZGF0ZShmb3JtYXQgPSAiJVktJW0tJWQiKSwgCiAgICAgICAgZnJvbSA9IGNvbF9mYWN0b3IobGV2ZWxzID0gYygiRSIsICJSIikpKSkKCmBgYAoKYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0Kbm91bnMgPC0gYygiTk4iLCJOTlMiLCJOUCIsIk5QUyIpCnZlcmJzIDwtIGMoJ1ZCWicsICdWQlAnLCAnVkInLCAnVkJHJywgJ1ZCTicsICdWQkQnKQptb2RhbHMgPC0gYygiTUQiKQpwcm9ub3VucyA8LSBjKCJQUCIsIlBQJCIpCmFkamVjdGl2ZXMgPC0gYygiSkoiKSAjbm8gY29tcGFyYXRpdmVzLCBzdXBlcmxhdGl2ZXMgPwphZHZlcmJzIDwtIGMoIlJCIikgI25vIGNvbXBhcmF0aXZlcywgc3VwZXJsYXRpdmVzID8KCgoKYGBgCgpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQoKZmlsdGVyTGVtbWFzIDwtIGZ1bmN0aW9uKGluZm9GLHJlbW92ZUxlbW1hcz1OVUxMLCBpbmNsdWRlTGVtbWFzPU5VTEwpIHsKICAgaW5mb1ggPC0gaW5mb0YKICAgaWYgKCEgaXMubnVsbChyZW1vdmVMZW1tYXMpKSB7CiAgICAgIGluZm9YIDwtIGZpbHRlcihpbmZvWCwgISAobGVtbWEgJWluJSByZW1vdmVMZW1tYXMpKQogICAgfSBlbHNlIGlmICghIGlzLm51bGwoaW5jbHVkZUxlbW1hcykpIHsKICAgICAgaW5mb1ggPC0gZmlsdGVyKGluZm9YLCBsZW1tYSAlaW4lIGluY2x1ZGVMZW1tYXMpCiAgICB9IAogICAgcmV0dXJuKGluZm9YKQp9CgptYWtlVmFycyA8LSBmdW5jdGlvbihwYXJ0c09mU3BlZWNoLCB0b3BuLCByZW1vdmVMZW1tYXM9TlVMTCwgaW5jbHVkZUxlbW1hcz1OVUxMKSB7CiAgICBpbmZvWCA8LSBmaWx0ZXIoaW5mbywgcG9zICVpbiUgcGFydHNPZlNwZWVjaCkKICAgIAogICAgWEJ5RG9jIDwtIGluZm9YICU+JSBjb3VudChpZCxsZW1tYSkKICAgIFhDb3VudHMgPC0gbGVmdF9qb2luKGdyb3VwX2J5KGluZm9YLGZyb20pLFhCeURvYykKICAgIFhCeVBlcnNvbiA8LSBpbmZvWCAlPiUgY291bnQoZnJvbSkgJT4lIHNlbGVjdChmcm9tPWZyb20sdG90YWw9bikKICAgIFhDb3VudHMgPC0gbGVmdF9qb2luKFhDb3VudHMsWEJ5UGVyc29uKSAlPiUKICAgICAgZmlsdGVyTGVtbWFzKHJlbW92ZUxlbW1hcz1yZW1vdmVMZW1tYXMsaW5jbHVkZUxlbW1hcz1pbmNsdWRlTGVtbWFzKQoKCiAgICBYUmFua3MgPC0gaW5mb1ggJT4lIAogICAgICBmaWx0ZXJMZW1tYXMocmVtb3ZlTGVtbWFzPXJlbW92ZUxlbW1hcyxpbmNsdWRlTGVtbWFzPWluY2x1ZGVMZW1tYXMpICU+JQogICAgICBjb3VudChmcm9tLGxlbW1hLCBzb3J0PVRSVUUpICU+JSAKICAgICAgZ3JvdXBfYnkoZnJvbSkgJT4lIAogICAgICBtdXRhdGUocmFuaz1yb3dfbnVtYmVyKCkpCiAgICAKICAgIFhSYW5rcyA8LSBsZWZ0X2pvaW4oWFJhbmtzLCBYQnlQZXJzb24pICU+JSBtdXRhdGUodGY9bi90b3RhbCkKICAgIAogICAgWFJhbmtzVG9wTiA8LSBmaWx0ZXIoWFJhbmtzLCByYW5rPD10b3BuKQogICAgCiAgICBYQ291bnRzVG9wTiA8LSBmaWx0ZXIoWENvdW50cywgbGVtbWEgJWluJSB1bmlxdWUoWFJhbmtzVG9wTiRsZW1tYSkpCiAgICAKICAgIHJldHVybiggbGlzdCgiY291bnRzIiA9IFhDb3VudHNUb3BOLCAicmFua3MiID0gWFJhbmtzVG9wTikgKQp9CgptYWtlVmFyaWFuY2UgPC0gZnVuY3Rpb24ocGFydHNPZlNwZWVjaCwgcmVtb3ZlTGVtbWFzPU5VTEwsIGluY2x1ZGVMZW1tYXM9TlVMTCkgewogICAgaW5mb1ggPC0gZmlsdGVyKGluZm8sIHBvcyAlaW4lIHBhcnRzT2ZTcGVlY2gpCiAgICAKICAgIFhDb3VudHMgPC0gaW5mb1ggJT4lIGNvdW50KGlkLGZyb20sbGVtbWEpCiAgICBYQnlQZXJzb24gPC0gaW5mb1ggJT4lIGNvdW50KGZyb20pICU+JSBzZWxlY3QoZnJvbT1mcm9tLHRvdGFsPW4pCiAgICBYQ291bnRzIDwtIGxlZnRfam9pbihYQ291bnRzLFhCeVBlcnNvbikgCiAgICAKICAgIFhCeUxlbW1hIDwtIGluZm9YICU+JSBjb3VudChmcm9tLGxlbW1hKQogICAgWFJlbEZyZXEgPC0gbGVmdF9qb2luKFhCeUxlbW1hLFhCeVBlcnNvbikgJT4lIG11dGF0ZShyZj1uL3RvdGFsKQogICAgCiAgICBYVmFyIDwtIFhDb3VudHMgJT4lIGdyb3VwX2J5KGxlbW1hLGZyb20pICU+JSBzdW1tYXJpemUodmFyPXZhcihuL3RvdGFsKSkgJT4lIGZpbHRlcighIGlzLm5hKHZhcikpICNOQXMgYXJlIGhhcGF4CiAgICAKICAgIGxlZnRfam9pbihYVmFyLCBYUmVsRnJlcSkgJT4lIAogICAgICBmaWx0ZXJMZW1tYXMocmVtb3ZlTGVtbWFzID0gcmVtb3ZlTGVtbWFzLCBpbmNsdWRlTGVtbWFzID0gaW5jbHVkZUxlbW1hcykKfQoKZ2dTaWRlQnlTaWRlIDwtIGZ1bmN0aW9uKGNvdW50cywgdGl0bGUsIG1heFk9TkEpIHsKICBjb3VudHMgJT4lIGdncGxvdCgpICsgCiAgICBnZW9tX2xpbmUoYWVzKGRhdGUsbi90b3RhbCxjb2xvcj1mcm9tKSkgKyAKICAgIHhsaW0ocmFuZ2UoY291bnRzJGRhdGUpKSArCiAgICB5bGltKDAsbWF4WSkgKwogICAgZmFjZXRfd3JhcChsZW1tYX5mcm9tLG5jb2w9Miwgc2NhbGVzPSJmcmVlX3giLCBsYWJlbGxlciA9IGxhYmVsX3dyYXBfZ2VuKG11bHRpX2xpbmU9RkFMU0UpKSArIAogICAgdGhlbWVfY2xhc3NpYygpICsgCiAgICBsYWJzKHRpdGxlPXRpdGxlLCB5PSJSZWxhdGl2ZSBGcmVxdWVuY3kiKSArCiAgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKfQoKZ2dTbG9wZSA8LSBmdW5jdGlvbihyYW5rcywgdGl0bGUpIHsKICByYW5rcyAlPiUgZ2dwbG90KCkgKyAKICAgIGdlb21fbGluZShhZXMoZnJvbSxyYW5rLGdyb3VwPWxlbW1hLCBjb2xvcj1sZW1tYSksIHNob3cubGVnZW5kPUZBTFNFKSArIAogICAgZ2VvbV90ZXh0KGRhdGE9ZmlsdGVyKHJhbmtzLGZyb209PSJFIiksYWVzKGZyb20scmFuayxsYWJlbD1sZW1tYSxjb2xvcj1sZW1tYSksIGhqdXN0PSJyaWdodCIsIG51ZGdlX3g9LTAuMDUsIHNob3cubGVnZW5kID0gRkFMU0UpICsgCiAgICBnZW9tX3RleHQoZGF0YT1maWx0ZXIocmFua3MsZnJvbT09IlIiKSxhZXMoZnJvbSxyYW5rLGxhYmVsPWxlbW1hLGNvbG9yPWxlbW1hKSwgaGp1c3Q9ImxlZnQiLCBudWRnZV94PTAuMDUsIHNob3cubGVnZW5kID0gRkFMU0UpICsgCiAgICBzY2FsZV94X2Rpc2NyZXRlKHBvc2l0aW9uID0gInRvcCIpICsKICAgIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJyZXZlcnNlIiwgYnJlYWtzID0gdW5pcXVlKHJhbmtzJHJhbmspLCBzZWMuYXhpcyA9IGR1cF9heGlzKCkpICsgCiAgICB0aGVtZV9jbGFzc2ljKCkgKyAKICAgIHRoZW1lKGF4aXMubGluZT1lbGVtZW50X2JsYW5rKCksIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKSArIAogICAgbGFicyh0aXRsZT10aXRsZSwgeD0iIikKfQpgYGAKCiMgQ29tcGFyaW5nIHdvcmQgcmFua2luZ3MKClRoZSBmaXJzdCB0eXBlIG9mIHZpc3VhbGl6YXRpb24gaXMgYSBfc2xvcGUgZ3JhcGhfIHBvcHVsYXJpemVkIGJ5IEVkd2FyZCBUdWZ0ZS4gSXQgbGV0cyB1cyBlYXNpbHkgY29tcGFyZSB0aGUgcmFua2luZ3MgKGJ5IGZyZXF1ZW5jeSkgYmV0d2VlbiBFQkIgYW5kIFJCLgoKIyMgTm91bnMKCkZpcnN0IHVwIGFyZSBub3Vucy4gSSdtIHVzaW5nIGp1c3QgdGhlIHRvcCAyMCBub3VucyBmb3IgX2VhY2hfLiBMaW5lcyBjb25uZWN0IHRoZSBzYW1lIHdvcmQgKGxlbW1hKSBmb3IgRSBhbmQgUjsgd2hlcmUgdGhlcmUgaXMgbm8gbGluZSwgdGhhdCBtZWFucyB0aGF0IHdvcmQgZG9lcyBub3Qgb2NjdXIgaW4gdGhlIG90aGVyIHBlcnNvbidzIHRvcCAyMCBub3Vucy4gRm9yIGV4YW1wbGUsIF9CYV8gKGEgbmlja25hbWUgZm9yIEVCQikgaXMgUidzIHRvcCBub3VuLCBidXQgaXQgaXMgbm90IG9uZSBvZiBFQkIncyB0b3AgMjAsIGV2ZW4gdGhvdWdoIHNoZSBzaWducyBtYW55IG9mIGhlciBsZXR0ZXJzICJCYSIuIFNvIGxvb2tpbmcgZm9yIG1pc3NpbmcgbGluZXMsIHdlIGNhbiBzZWUgdGhhdCB0aGVyZSBpcyBmYXIgZnJvbSBjb21wbGV0ZSBvdmVybGFwIGluIEVCQiBhbmQgUkIncyB0b3AgMjAgbm91bnMuCgpXaGVuIHdlIF9kb18gaGF2ZSBhIGxpbmUgYmV0d2VlbiBFQkIncyBhbmQgUkIncyBzaWRlcywgdGhlIHNsb3BlIG9mIHRoZSBsaW5lIGluZGljYXRlcyBob3cgZGlmZmVyZW50IHRoZWlyIHJhbmtpbmdzIGFyZS4gRm9yIGV4YW1wbGUgX01yLl8gaXMgdGhlIG1vc3QgZnJlcXVlbnQgbm91biBmb3IgRUJCLCBidXQgb25seSAxMnRoIGZvciBSQi4gT24gdGhlIG90aGVyIGhhbmQsIHRoZXkgYm90aCBoYXZlIF9sZXR0ZXJfIGluIHNlY29uZCBwbGFjZS4KCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KdG9wbiA9IDIwCnYgPC0gbWFrZVZhcnMobm91bnMsdG9wbj10b3BuLCByZW1vdmVMZW1tYXM9Yygi4oCUIiwi4oCTIiwiJmMiKSkKYGBgCgpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD00IH0KKGdnU2xvcGUodiRyYW5rcyxwYXN0ZSgiRUJCICYgUkIgVG9wIix0b3BuLCJub3VucyIsIHNlcD0iICIpKSkKYGBgCgojIyBNYWluIFZlcmJzCgpNYWluIHZlcmJzIHNob3cgYSBzbGlnaHRseSBkaWZmZXJlbnQgcGF0dGVybjogaGVyZSB0aGVyZSBpcyBtdWNoIG1vcmUgb3ZlcmxhcCBiZXR3ZWVuIHRoZSB0b3AgMjAgdmVyYnMgYmV0d2VlbiB0aGVtLCBhcyBzZWVuIGJ5IHRoZSByZWxhdGl2ZWx5IGZldyBtaXNzaW5nIGxpbmVzLiBIb3dldmVyLCB0aGVpciByYW5raW5ncyBkbyBkaWZmZXIuCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KdG9wbiA9IDIwCnYgPC0gbWFrZVZhcnModmVyYnMsdG9wbj10b3BuLCByZW1vdmVMZW1tYXM9YygiYmUiLCJkbyIsImhhdmUiKSkgI2Nhbid0IHRlbGwgZG8saGF2ZSBhcGFydCBmcm9tIGF1eGlsaWFyaWVzCmBgYAoKYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9NH0KKGdnU2xvcGUodiRyYW5rcyxwYXN0ZSgiRUJCICYgUkIgVG9wIix0b3BuLCJtYWluIHZlcmJzIiwgc2VwPSIgIikpKQpgYGAKCgojIyBNb2RhbCBWZXJicwoKVGhlIG1vZGFsIHZlcmJzICggX2Nhbl8sIF9jb3VsZF8sIF9tYXlfLCBfbWlnaHRfLCAuLi4pIHNob3cgeWV0IGFub3RoZXIgcGF0dGVybi4gVGhlcmUgYXJlbid0IHZlcnkgbWFueSBvZiB0aGVtLCBzbyBpdCdzIG5vdCBzdXJwaXNpbmcgdGhhdCB0aGVyZSBpcyBjb21wbGV0ZSBvdmVybGFwLiBNb3JlIHN1cnByaXNpbmcgaXMgdGhhdCB0aGVpciByYW5raW5ncyBhcmUgdmVyeSBzaW1pbGFyLCB3aXRoIDQgb3V0IHRoZSAxMCBoYXZpbmcgaWRlbnRpY2FsIHJhbmtpbmdzIChjb21wYXJlZCB0byAxIHZlcmIgYW5kIG5vIG5vdW5zIHdpdGggaWRlbnRpY2FsIHJhbmtpbmdzKS4KCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQp0b3BuID0gMTAKdiA8LSBtYWtlVmFycyhtb2RhbHMsdG9wbj10b3BuLCByZW1vdmVMZW1tYXMgPSBjKCJjYSIsIndvIikpCmBgYAoKCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTR9CihnZ1Nsb3BlKHYkcmFua3MscGFzdGUoIkVCQiAmIFJCIFRvcCIsdG9wbiwiTW9kYWwgVmVyYnMiLCBzZXA9IiAiKSkpCmBgYAoKIyMgUHJvbm91bnMKClByb25vdW5zIHNob3cgYSBtaXhlZCBwYXR0ZXJuLCB3aXRoIHRoZSB0b3AgOCBwcm9ub3VucyBiZWluZyB2ZXJ5IHNpbWlsYXIsIGFuZCB0aGUgcmVzdCBtb3JlIGRpZmZlcmVudC4KCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQp0b3BuID0gMjAKdiA8LSBtYWtlVmFycyhwcm9ub3Vucyx0b3BuPXRvcG4pCmBgYAoKYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9NH0KKGdnU2xvcGUodiRyYW5rcyxwYXN0ZSgiRUJCICYgUkIgVG9wIix0b3BuLCJQcm9ub3VucyIsIHNlcD0iICIpKSkKYGBgCgojIFByb25vdW5zIGFjcm9zcyB0aW1lCgpJbiBhZGRpdGlvbiB0byBsb29raW5nIGF0IHRoZSBvdmVyYWxsIHJhbmtpbmdzIG9mIHdvcmRzLCB3ZSBjYW4gYWxzbyBsb29rIGF0IGhvdyB0aGUgZnJlcXVlbmN5IGluIGxldHRlcnMgdmFyaWVzIG92ZXIgdGltZS4gSW4gcGFydGljdWxhciwgd2UgbWlnaHQgd2FudCB0byBmaW5kIHRoZSB3b3JkcyB0aGF0IHZhcnkgdGhlIG1vc3QsIG9yIHRoZSB3b3JkcyB0aGF0IHZhcnkgdGhlIGxlYXN0LCBpbiB0ZXJtcyBvZiB0aGVpciBmcmVxdWVuY3kuIFRvIGRvIHRoaXMsIHdlIGNhbiB1c2UgdGhlIHN0YXRpc3RpY2FsIG5vdGlvbiBvZiBfdmFyaWFuY2VfIHRvIG1lYXN1cmUgdmFyaWFiaWx0eS4gCgpXaGVuIHdlIHBsb3QgcmVsYXRpdmUgZnJlcXVlbmN5IHZzIHZhcmlhbmNlIGZvciB0aGUgcHJvbm91bnMgYXMgYmVsb3csIHdlIHNlZSB0aGF0IF9JXyBhbmQgX3lvdV8gYm90aCBoYXZlIHJlbGF0aXZlbHkgaGlnaCB2YXJpYW5jZSwgaW4gYWRkaXRpb24gdG8gYmVpbmcgZnJlcXVlbnQuIEhvd2V2ZXIsIHdlIGNhbiBzZWUgdGhhdCBSQiB1c2VzIF9JXyBtdWNoIG1vcmUgdmFyaWFibHkgdGhhbiBFQkIgZG9lczogaGlzIF9JXyBpcyBoaWdoZXIgaW4gdGhlIGNoYXJ0IHRoYW4gaGVycy4gKFdlIGNhbiBhbHNvIHNlZSB0aGF0IGZvciBib3RoIG9mIHRoZW0sIF9JXyBpcyBtb3JlIHZhcmlhYmxlIHRoYW4gX3lvdV8uKQoKYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KcFRvVXNlIDwtIGMoIkkiLCJ5b3UiLCJpdCIsIm1lIiwibXkiLCJ5b3VyIiwiaGUiLCJoaXMiKQpwVmFyIDwtIG1ha2VWYXJpYW5jZShwcm9ub3VucywgaW5jbHVkZUxlbW1hcyA9IHBUb1VzZSkKKHBWYXIgJT4lICBnZ3Bsb3QoKSArIGdlb21fdGV4dChhZXMocmYsdmFyLGxhYmVsPWxlbW1hLGNvbG9yPWZyb20pKSArIHRoZW1lX2NsYXNzaWMoKSArIGxhYnModGl0bGU9IkVCQiAmIFJCOiB2YXJpYWJpbGl0eSBvZiB0b3AgcHJvbm91bnMiLCB4PSJPdmVyYWxsIFJlbGF0aXZlIEZyZXF1ZW5jeSIsIHk9IlZhcmlhbmNlIikgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkpCmBgYAoKT2YgY291cnNlLCB3ZSBjYW4gYWxzbyBzZWUgdGhlIGRldGFpbHMgb2YgdGhlIHZhcmlhYmlsaXR5IGluIEVCQiBhbmQgUkIncyB1c2Ugb2YgX0lfIGFuZCBfeW91XyBvdmVyIHRoZSBjb3Vyc2Ugb2YgdGhlaXIgbGV0dGVyczoKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQp0b3BuID0gMjAKdiA8LSBtYWtlVmFycyhwcm9ub3Vucyx0b3BuPXRvcG4pCmBgYAoKCmBgYHtyLCBmaWcud2lkdGggPSA4LjUsIGZpZy5oZWlnaHQgPSA2LCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpwVG9Vc2UgPSBjKCJJIiwieW91IikKKGdnU2lkZUJ5U2lkZShmaWx0ZXIodiRjb3VudHMsIGxlbW1hICVpbiUgcFRvVXNlKSwgIkVCQiAmIFJCOiBJIGFuZCB5b3UiKSkKCmBgYAoKSW4gdGhlIGNoYXJ0IG9mIHZhcmlhbmNlIGFib3ZlIF9oZV8sIF9oaXNfLCBhbmQgX3lvdXJfIHdlcmUgdGhlIGxlYXN0IHZhcmlhYmxlLiBIZXJlJ3Mgd2hhdCB0aGV5IGxvb2sgbGlrZSBvdmVyIHRpbWUuIAoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CnRvcG4gPSAxMAp2IDwtIG1ha2VWYXJzKHByb25vdW5zLHRvcG49dG9wbiwgaW5jbHVkZUxlbW1hcz1jKCJoaXMiLCJoZSIsInlvdXIiKSkKYGBgCgoKYGBge3IsIGZpZy53aWR0aCA9IDguNSwgZmlnLmhlaWdodCA9IDgsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CihnZ1NpZGVCeVNpZGUodiRjb3VudHMsICJFQkIgJiBSQjogaGUsIGhpcywgeW91ciIpKQoKYGBgCgpBdCBmaXJzdCBnbGFuY2UsIGl0IGxvb2tzIHRoZXkgYXJlIGp1c3QgYXMgdmFyaWFibGUgYXMgX0lfIGFuZCBfeW91XywgYnV0IHRoYXQncyBiZWNhdXNlIHRoZSBfc2NhbGVfIG9mIHRoZSB2ZXJ0aWNhbCBheGlzIGNvdmVycyBhIG5hcnJvd2VyIHJhbmdlLCBlZmZlY3RpdmVseSBtYWduaWZ5aW5nIHRoZSBkaWZmZXJlbmNlcy4gSG93ZXZlciwgaWYgd2UgdXNlIHRoZSBzYW1lIHZlcnRpY2FsIHJhbmdlIGFzIHdlIGhhZCBmb3IgX0lfIGFuZCBfeW91Xywgd2Ugc2VlIHRoYXQgdGhlIHZhcmlhYmlsaXR5IGlzIGluIGluZGVlZCBtdWNoIHNtYWxsZXIsIHRob3VnaCBvZiBjb3Vyc2UgaXQgc3RpbGwgZXhpc3RzLgoKCmBgYHtyLCBmaWcud2lkdGggPSA4LjUsIGZpZy5oZWlnaHQgPSA4LCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQooZ2dTaWRlQnlTaWRlKHYkY291bnRzLCAiRUJCICYgUkI6IGhlLCBoaXMsIHlvdXIiLCBtYXhZPTAuMDA0KSkKCmBgYAoKSW4gdGhlIFtuZXh0IHBhcnRdKHdpcF90ZmlkZi5odG1sKSBvZiBXb3JrIGluIFByb2dlc3MsIEkgbG9vayBhdCBhbm90aGVyIGFzcGVjdCBvZiBmaWd1cmluZyBvdXQgd2hhdCB0aGUgbGV0dGVycyBhcmUgYWJvdXQ6IGtleSB3b3Jkcy4gCgojIyMgW0JhY2sgdG8gdGhlIGRlbW9zXSguLi9pbmRleC5odG1sKQo=