Overview

Using one or more TidyVerse packages, and any dataset from fivethirtyeight.com or Kaggle, create a programming sample “vignette” that demonstrates how to use one or more of the capabilities of the selected TidyVerse package with your selected dataset. In this case I selected Kaggle ‘COVID’ datset from Kaggle. The original dataset is from NY times.

Load required libraries

Step 1 is to install and load required libraries to extract data from NY times GIT library

The default packages loaded from the library ‘tidyverse’ are ggplot2, purrr,tibble,dplyr, tidyr, stringr,readr,forcats. My focus is on ggplot2 and dplyr

We will use read.csv() function from readr() package when we load the dataset.

Load the dataset

Raw data looks like this:

It contains time series data containing cumulative counts of coronavirus cases in the United States, at the state and county level, over time.

Data exploration using dplyr

  1. Filter function in dplyr()

Description Use filter() to choose rows/cases where conditions are true. Unlike base subsetting with [, rows where the condition evaluates to NA are dropped.

date county state fips cases deaths
2020-10-24 Autauga Alabama 1001 2048 31
2020-10-24 Baldwin Alabama 1003 6637 69
2020-10-24 Barbour Alabama 1005 1031 9
2020-10-24 Bibb Alabama 1007 828 14
2020-10-24 Blount Alabama 1009 1925 25

Now we have latest county level COVID data in the dataset covid_county_latest

  1. Arrange and group_by functions in dplyr()

Description Order tbl rows by an expression involving its variables.Most data operations are done on groups defined by variables. group_by() takes an existing tbl and converts it into a grouped tbl where operations are performed “by group”. ungroup() removes grouping.

date county state fips cases deaths
2020-10-24 Jefferson Alabama 1073 23129 377
2020-10-24 Mobile Alabama 1097 16849 315
2020-10-24 Tuscaloosa Alabama 1125 10296 140
2020-10-24 Montgomery Alabama 1101 10197 197
2020-10-24 Madison Alabama 1089 9280 96

We obtained COVID cases sorted by each state from highest to lowest in each of the counties.

  1. Select and rename functions in dplyr()

Description Choose or rename variables from a tbl. select() keeps only the variables you mention; rename() keeps all variables

county state covid_cases covid_deaths
Jefferson Alabama 23129 377
Mobile Alabama 16849 315
Tuscaloosa Alabama 10296 140
Montgomery Alabama 10197 197
Madison Alabama 9280 96

Selected only the required columns and renamed the columns so that it’s more intuitive to understand.

  1. Summarize function in dplyr()

Description Create one or more scalar variables summarizing the variables of an existing tbl. Tbls with groups created by group_by() will result in one row in the output for each group. Tbls with no groups will result in one row.

state US_cases US_deaths
California 906644 17345
Texas 906033 17998
Florida 776243 16416
New York 498568 33049
Illinois 376034 9765

Note that here, we obtained COVID cases by state by applying multiple functions such as arrange,group_by and summarise.

  1. Mutate function in dplyr()

Description mutate() adds new variables and preserves existing ones; transmute() adds new variables and drops existing ones. Both functions preserve the number of rows of the input. New variables overwrite existing variables of the same name.

state US_cases US_deaths mortality_rate cases_density
California 906644 17345 1.9 10.5
Texas 906033 17998 2.0 10.5
Florida 776243 16416 2.1 9.0
New York 498568 33049 6.6 5.8
Illinois 376034 9765 2.6 4.4

Mortality rate metric defined as deaths per cases is a better metric to understand the impact of COVID pandemic.

Visualization

  1. ggplot function in ggplot2 Description ggplot() initializes a ggplot object. It can be used to declare the input data frame for a graphic and to specify the set of plot aesthetics intended to be common throughout all subsequent layers unless specifically overridden.

The graph shows COVID cases spread by states from highest to lowest order. Let’s now plot mortality rate to understand where the cases caused were more deadly.

  1. geom_smooth function in ggplot2 Description Aids the eye in seeing patterns in the presence of overplotting. geom_smooth() and stat_smooth() are effectively aliases: they both use the same arguments. Use stat_smooth() if you want to display the results with a non-standard geom.

Conclusion

There are three clear outliers which are possibly stopping us from understanding the clear relation between mortality rate and case density.

After removing the outliers, the distribution seems more linear where COVID mortality rate is higher in the states with higher COVID density.

LS0tDQp0aXRsZTogJ0Fzc2lnbm1lbnQ6IFRpZHlWZXJzZSBDUkVBVEUgYXNzaWdubWVudCcNCmF1dGhvcjogIkJoYXJhbmkgTml0dGFsYSINCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCINCm91dHB1dDoNCiAgb3BlbmludHJvOjpsYWJfcmVwb3J0OiBkZWZhdWx0DQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KICBodG1sX2RvY3VtZW50Og0KICAgIGluY2x1ZGVzOg0KICAgICAgaW5faGVhZGVyOiBoZWFkZXIuaHRtbA0KICAgIGNzczogLi9sYWIuY3NzDQogICAgaGlnaGxpZ2h0OiBweWdtZW50cw0KICAgIHRoZW1lOiBjZXJ1bGVhbg0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgd29yZF9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KZWRpdG9yX29wdGlvbnM6DQogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlDQotLS0NCg0KIyMjIE92ZXJ2aWV3DQoNClVzaW5nIG9uZSBvciBtb3JlIFRpZHlWZXJzZSBwYWNrYWdlcywgYW5kIGFueSBkYXRhc2V0IGZyb20gZml2ZXRoaXJ0eWVpZ2h0LmNvbSBvciBLYWdnbGUsIGNyZWF0ZSBhIHByb2dyYW1taW5nIHNhbXBsZSDigJx2aWduZXR0ZeKAnSB0aGF0IGRlbW9uc3RyYXRlcyBob3cgdG8gdXNlIG9uZSBvciBtb3JlIG9mIHRoZSBjYXBhYmlsaXRpZXMgb2YgdGhlIHNlbGVjdGVkIFRpZHlWZXJzZSBwYWNrYWdlIHdpdGggeW91ciBzZWxlY3RlZCBkYXRhc2V0LiBJbiB0aGlzIGNhc2UgSSBzZWxlY3RlZCBLYWdnbGUgJ0NPVklEJyBkYXRzZXQgZnJvbSBbS2FnZ2xlXShodHRwczovL3d3dy5rYWdnbGUuY29tL2ZpcmViYWxsYnllZGlteXJubW9tL3VzLWNvdW50aWVzLWNvdmlkLTE5LWRhdGFzZXQpLiBUaGUgb3JpZ2luYWwgZGF0YXNldCBpcyBmcm9tIE5ZIHRpbWVzLiAgICANCg0KDQojIyMgTG9hZCByZXF1aXJlZCBsaWJyYXJpZXMNCg0KU3RlcCAxIGlzIHRvIGluc3RhbGwgYW5kIGxvYWQgcmVxdWlyZWQgbGlicmFyaWVzIHRvIGV4dHJhY3QgZGF0YSBmcm9tIE5ZIHRpbWVzIEdJVCBsaWJyYXJ5DQoNCmBgYHtyIGxpYnJhcmllcywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChldmFsID0gVFJVRSwgcmVzdWx0cyA9IEZBTFNFKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpsaWJyYXJ5KHJtYXJrZG93bikNCmxpYnJhcnkoUkN1cmwpDQoNCmBgYA0KDQojIyMjIFRoZSBkZWZhdWx0IHBhY2thZ2VzIGxvYWRlZCBmcm9tIHRoZSBsaWJyYXJ5ICd0aWR5dmVyc2UnIGFyZSAqZ2dwbG90MiosICpwdXJyciosKnRpYmJsZSosKmRwbHlyKiwgKnRpZHlyKiwgKnN0cmluZ3IqLCpyZWFkciosKmZvcmNhdHMqLiBNeSBmb2N1cyBpcyBvbiAqKmdncGxvdDIqKiBhbmQgKipkcGx5cioqDQoNCldlIHdpbGwgdXNlIHJlYWQuY3N2KCkgZnVuY3Rpb24gZnJvbSByZWFkcigpIHBhY2thZ2Ugd2hlbiB3ZSBsb2FkIHRoZSBkYXRhc2V0LiANCg0KDQojIyMgTG9hZCB0aGUgZGF0YXNldA0KDQpSYXcgZGF0YSBsb29rcyBsaWtlIHRoaXM6DQpgYGB7ciAsIG1lc3NhZ2U9RkFMU0UsZWNobz0gRkFMU0V9DQpjb3ZpZF9jb3VudHlfdXJsIDwtIGdldFVSTCgiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL255dGltZXMvY292aWQtMTktZGF0YS9tYXN0ZXIvdXMtY291bnRpZXMuY3N2IikgDQpjb3ZpZF9jb3VudHlfcmF3IDwtIHJlYWQuY3N2KHRleHQgPSBjb3ZpZF9jb3VudHlfdXJsKQ0KDQpoZWFkKGNvdmlkX2NvdW50eV9yYXcsNSkgJT4lIGthYmxlKCkgJT4lIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIpLCBmaXhlZF90aGVhZCA9IFQpDQpgYGANCg0KSXQgY29udGFpbnMgdGltZSBzZXJpZXMgZGF0YSBjb250YWluaW5nIGN1bXVsYXRpdmUgY291bnRzIG9mIGNvcm9uYXZpcnVzIGNhc2VzIGluIHRoZSBVbml0ZWQgU3RhdGVzLCBhdCB0aGUgc3RhdGUgYW5kIGNvdW50eSBsZXZlbCwgb3ZlciB0aW1lLg0KDQoNCiMjIyBEYXRhIGV4cGxvcmF0aW9uIHVzaW5nIGRwbHlyDQoNClxuDQoxKSBGaWx0ZXIgZnVuY3Rpb24gaW4gZHBseXIoKQ0KIA0KKipEZXNjcmlwdGlvbioqDQpVc2UgZmlsdGVyKCkgdG8gY2hvb3NlIHJvd3MvY2FzZXMgd2hlcmUgY29uZGl0aW9ucyBhcmUgdHJ1ZS4gVW5saWtlIGJhc2Ugc3Vic2V0dGluZyB3aXRoIFssIHJvd3Mgd2hlcmUgdGhlIGNvbmRpdGlvbiBldmFsdWF0ZXMgdG8gTkEgYXJlIGRyb3BwZWQuDQpgYGB7ciAsIG1lc3NhZ2U9RkFMU0UscmVzdWx0cz0iYXNpcyJ9DQpjb3ZpZF9jb3VudHlfbGF0ZXN0ID0gZmlsdGVyKGNvdmlkX2NvdW50eV9yYXcsZGF0ZSA9PSBtYXgoY292aWRfY291bnR5X3JhdyRkYXRlKSkNCmhlYWQoY292aWRfY291bnR5X2xhdGVzdCw1KSAlPiUga2FibGUoKSAlPiUga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiLCAiY29uZGVuc2VkIiksIGZpeGVkX3RoZWFkID0gVCkNCmBgYA0KDQpOb3cgd2UgaGF2ZSBsYXRlc3QgY291bnR5IGxldmVsIENPVklEIGRhdGEgaW4gdGhlIGRhdGFzZXQgY292aWRfY291bnR5X2xhdGVzdA0KDQoyKSBBcnJhbmdlIGFuZCBncm91cF9ieSBmdW5jdGlvbnMgaW4gZHBseXIoKQ0KXG4gDQoNCioqRGVzY3JpcHRpb24qKg0KT3JkZXIgdGJsIHJvd3MgYnkgYW4gZXhwcmVzc2lvbiBpbnZvbHZpbmcgaXRzIHZhcmlhYmxlcy5Nb3N0IGRhdGEgb3BlcmF0aW9ucyBhcmUgZG9uZSBvbiBncm91cHMgZGVmaW5lZCBieSB2YXJpYWJsZXMuIGdyb3VwX2J5KCkgdGFrZXMgYW4gZXhpc3RpbmcgdGJsIGFuZCBjb252ZXJ0cyBpdCBpbnRvIGEgZ3JvdXBlZCB0Ymwgd2hlcmUgb3BlcmF0aW9ucyBhcmUgcGVyZm9ybWVkICJieSBncm91cCIuIHVuZ3JvdXAoKSByZW1vdmVzIGdyb3VwaW5nLg0KYGBge3IgLCBtZXNzYWdlPUZBTFNFLHJlc3VsdHM9ImFzaXMifQ0KY292aWRfY291bnR5X2xhdGVzdCA8LSBjb3ZpZF9jb3VudHlfbGF0ZXN0ICU+JSBncm91cF9ieShzdGF0ZSkgICU+JSBhcnJhbmdlKGRlc2MoY2FzZXMpLCAuYnlfZ3JvdXAgPSBUUlVFKQ0KaGVhZChjb3ZpZF9jb3VudHlfbGF0ZXN0LDUpICU+JSBrYWJsZSgpICU+JSBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJjb25kZW5zZWQiKSwgZml4ZWRfdGhlYWQgPSBUKQ0KYGBgDQoNCldlIG9idGFpbmVkIENPVklEIGNhc2VzIHNvcnRlZCBieSBlYWNoIHN0YXRlIGZyb20gaGlnaGVzdCB0byBsb3dlc3QgaW4gZWFjaCBvZiB0aGUgY291bnRpZXMuIA0KDQpcbg0KMykgU2VsZWN0IGFuZCByZW5hbWUgZnVuY3Rpb25zIGluIGRwbHlyKCkNCg0KKipEZXNjcmlwdGlvbioqDQpDaG9vc2Ugb3IgcmVuYW1lIHZhcmlhYmxlcyBmcm9tIGEgdGJsLiBzZWxlY3QoKSBrZWVwcyBvbmx5IHRoZSB2YXJpYWJsZXMgeW91IG1lbnRpb247IHJlbmFtZSgpIGtlZXBzIGFsbCB2YXJpYWJsZXMNCmBgYHtyICwgbWVzc2FnZT1GQUxTRSxyZXN1bHRzPSJhc2lzIn0NCmNvdmlkX2NvdW50eV9sYXRlc3QgPC0gY292aWRfY291bnR5X2xhdGVzdCU+JXNlbGVjdChjb3VudHksc3RhdGUsY2FzZXMsZGVhdGhzKQ0KY292aWRfY291bnR5X2xhdGVzdCA8LSByZW5hbWUoY292aWRfY291bnR5X2xhdGVzdCxjb3ZpZF9jYXNlcyA9IGNhc2VzLGNvdmlkX2RlYXRocyA9IGRlYXRocykNCmhlYWQoY292aWRfY291bnR5X2xhdGVzdCw1KSAlPiUga2FibGUoKSAlPiUga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiLCAiY29uZGVuc2VkIiksIGZpeGVkX3RoZWFkID0gVCkNCmBgYA0KDQpTZWxlY3RlZCBvbmx5IHRoZSByZXF1aXJlZCBjb2x1bW5zIGFuZCByZW5hbWVkIHRoZSBjb2x1bW5zIHNvIHRoYXQgaXQncyBtb3JlIGludHVpdGl2ZSB0byB1bmRlcnN0YW5kLg0KDQpcbg0KNCkgU3VtbWFyaXplIGZ1bmN0aW9uIGluIGRwbHlyKCkNCg0KKipEZXNjcmlwdGlvbioqDQpDcmVhdGUgb25lIG9yIG1vcmUgc2NhbGFyIHZhcmlhYmxlcyBzdW1tYXJpemluZyB0aGUgdmFyaWFibGVzIG9mIGFuIGV4aXN0aW5nIHRibC4gVGJscyB3aXRoIGdyb3VwcyBjcmVhdGVkIGJ5IGdyb3VwX2J5KCkgd2lsbCByZXN1bHQgaW4gb25lIHJvdyBpbiB0aGUgb3V0cHV0IGZvciBlYWNoIGdyb3VwLiBUYmxzIHdpdGggbm8gZ3JvdXBzIHdpbGwgcmVzdWx0IGluIG9uZSByb3cuDQpgYGB7ciAsIG1lc3NhZ2U9RkFMU0UscmVzdWx0cz0iYXNpcyJ9DQoNCmNvdmlkX3N0YXRlIDwtIGNvdmlkX2NvdW50eV9sYXRlc3QgJT4lIGdyb3VwX2J5KHN0YXRlKSAlPiUgc3VtbWFyaXNlKFVTX2Nhc2VzID0gc3VtKGNvdmlkX2Nhc2VzKSxVU19kZWF0aHMgPSBzdW0oY292aWRfZGVhdGhzKSkgJT4lICBhcnJhbmdlKGRlc2MoVVNfY2FzZXMpLCAuYnlfZ3JvdXAgPSBUUlVFKQ0KaGVhZChjb3ZpZF9zdGF0ZSw1KSAlPiUga2FibGUoKSAlPiUga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiLCAiY29uZGVuc2VkIiksIGZpeGVkX3RoZWFkID0gVCkNCg0KYGBgDQoNCk5vdGUgdGhhdCBoZXJlLCB3ZSBvYnRhaW5lZCBDT1ZJRCBjYXNlcyBieSBzdGF0ZSBieSBhcHBseWluZyBtdWx0aXBsZSBmdW5jdGlvbnMgc3VjaCBhcyBhcnJhbmdlLGdyb3VwX2J5IGFuZCBzdW1tYXJpc2UuIA0KDQo1KSBNdXRhdGUgZnVuY3Rpb24gaW4gZHBseXIoKQ0KDQoqKkRlc2NyaXB0aW9uKioNCm11dGF0ZSgpIGFkZHMgbmV3IHZhcmlhYmxlcyBhbmQgcHJlc2VydmVzIGV4aXN0aW5nIG9uZXM7IHRyYW5zbXV0ZSgpIGFkZHMgbmV3IHZhcmlhYmxlcyBhbmQgZHJvcHMgZXhpc3Rpbmcgb25lcy4gQm90aCBmdW5jdGlvbnMgcHJlc2VydmUgdGhlIG51bWJlciBvZiByb3dzIG9mIHRoZSBpbnB1dC4gTmV3IHZhcmlhYmxlcyBvdmVyd3JpdGUgZXhpc3RpbmcgdmFyaWFibGVzIG9mIHRoZSBzYW1lIG5hbWUuDQpgYGB7ciAsIG1lc3NhZ2U9RkFMU0UscmVzdWx0cz0iYXNpcyJ9DQoNCmNvdmlkX3N0YXRlIDwtIGNvdmlkX3N0YXRlICU+JSBtdXRhdGUobW9ydGFsaXR5X3JhdGUgPSByb3VuZCgoVVNfZGVhdGhzKjEwMCkvVVNfY2FzZXMsMSksY2FzZXNfZGVuc2l0eSA9IHJvdW5kKFVTX2Nhc2VzKjEwMC9zdW0oVVNfY2FzZXMpLDEpKSANCmhlYWQoY292aWRfc3RhdGUsNSkgJT4lIGthYmxlKCkgJT4lIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIpLCBmaXhlZF90aGVhZCA9IFQpDQoNCmBgYA0KDQoNCk1vcnRhbGl0eSByYXRlIG1ldHJpYyBkZWZpbmVkIGFzIGRlYXRocyBwZXIgY2FzZXMgaXMgYSBiZXR0ZXIgbWV0cmljIHRvIHVuZGVyc3RhbmQgdGhlIGltcGFjdCBvZiBDT1ZJRCBwYW5kZW1pYy4gDQoNCiMjIyBWaXN1YWxpemF0aW9uDQoNCjEpIGdncGxvdCBmdW5jdGlvbiBpbiBnZ3Bsb3QyDQpcbg0KKipEZXNjcmlwdGlvbioqDQpnZ3Bsb3QoKSBpbml0aWFsaXplcyBhIGdncGxvdCBvYmplY3QuIEl0IGNhbiBiZSB1c2VkIHRvIGRlY2xhcmUgdGhlIGlucHV0IGRhdGEgZnJhbWUgZm9yIGEgZ3JhcGhpYyBhbmQgdG8gc3BlY2lmeSB0aGUgc2V0IG9mIHBsb3QgYWVzdGhldGljcyBpbnRlbmRlZCB0byBiZSBjb21tb24gdGhyb3VnaG91dCBhbGwgc3Vic2VxdWVudCBsYXllcnMgdW5sZXNzIHNwZWNpZmljYWxseSBvdmVycmlkZGVuLg0KYGBge3IgLCBtZXNzYWdlPUZBTFNFLHJlc3VsdHM9ImFzaXMifQ0KDQpjb3ZpZF9zdGF0ZSAlPiUgYXJyYW5nZShjYXNlc19kZW5zaXR5KSAlPiUgIG11dGF0ZShzdGF0ZSA9IGZjdF9yZW9yZGVyKHN0YXRlLCBjYXNlc19kZW5zaXR5KSkgJT4lDQpnZ3Bsb3QoYWVzKCB4PXN0YXRlLHk9Y2FzZXNfZGVuc2l0eSkpICsgDQogICAgZ2VvbV9iYXIoIHN0YXQ9ImlkZW50aXR5Iixjb2xvcj0iYmxhY2siKSsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsPXBhc3RlMChjYXNlc19kZW5zaXR5LCIlIikpLGNvbG9yID0gIm9yYW5nZSIsaGp1c3Q9MSx2anVzdD0wLjMsc2l6ZSA9IDMpKw0KICB0aGVtZSggYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIsIA0KICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAxLCBsaW5ldHlwZSA9ICJzb2xpZCIpKSsNCiAgY29vcmRfZmxpcCgpKw0KICAgIHhsYWIoIiIpKyB5bGFiKCIiKSsNCiAgdGhlbWUoIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siLCANCiAgICAgICAgICAgICAgICAgICAgICBzaXplID0xLCBsaW5ldHlwZSA9ICJzb2xpZCIpKSsNCiAgIGdndGl0bGUoIkNPVklEIERlbnNpdHkgUmF0ZSBpbiB0aGUgVVMgU3RhdGVzIChhcyBvZiBPY3QgMjQgJzIwKSIpICsgDQogICAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQobGluZWhlaWdodD0uOCwgZmFjZT0iYm9sZCIpKQ0KDQpgYGANCg0KVGhlIGdyYXBoIHNob3dzIENPVklEIGNhc2VzIHNwcmVhZCBieSBzdGF0ZXMgZnJvbSBoaWdoZXN0IHRvIGxvd2VzdCBvcmRlci4gTGV0J3Mgbm93IHBsb3QgbW9ydGFsaXR5IHJhdGUgdG8gdW5kZXJzdGFuZCB3aGVyZSB0aGUgY2FzZXMgY2F1c2VkIHdlcmUgbW9yZSBkZWFkbHkuIA0KDQpgYGB7ciAsIG1lc3NhZ2U9RkFMU0UscmVzdWx0cz0iYXNpcyJ9DQoNCmNvdmlkX3N0YXRlICU+JSBhcnJhbmdlKG1vcnRhbGl0eV9yYXRlKSAlPiUgIG11dGF0ZShzdGF0ZSA9IGZjdF9yZW9yZGVyKHN0YXRlLCBtb3J0YWxpdHlfcmF0ZSkpICU+JQ0KZ2dwbG90KGFlcyggeD1zdGF0ZSx5PW1vcnRhbGl0eV9yYXRlKSkgKyANCiAgICBnZW9tX2Jhciggc3RhdD0iaWRlbnRpdHkiLGNvbG9yPSJibGFjayIpKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWw9cGFzdGUwKG1vcnRhbGl0eV9yYXRlLCIlIikpLGNvbG9yID0gIm9yYW5nZSIsaGp1c3Q9MSx2anVzdD0wLjMsc2l6ZSA9IDMpKw0KICB0aGVtZSggYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIsIA0KICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAxLCBsaW5ldHlwZSA9ICJzb2xpZCIpKSsNCiAgY29vcmRfZmxpcCgpKw0KICAgIHhsYWIoIiIpKyB5bGFiKCIiKSsNCiAgdGhlbWUoIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siLCANCiAgICAgICAgICAgICAgICAgICAgICBzaXplID0gMSwgbGluZXR5cGUgPSAic29saWQiKSkrDQogICBnZ3RpdGxlKCJDT1ZJRCBNb3J0YWxpdHkgUmF0ZSBpbiB0aGUgVVMgU3RhdGVzIChhcyBvZiBPY3QgMjQgJzIwKSIpICsgDQogICAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQobGluZWhlaWdodD0uOCwgZmFjZT0iYm9sZCIpKQ0KDQpgYGANCg0KMikgZ2VvbV9zbW9vdGggZnVuY3Rpb24gaW4gZ2dwbG90Mg0KXG4NCioqRGVzY3JpcHRpb24qKg0KQWlkcyB0aGUgZXllIGluIHNlZWluZyBwYXR0ZXJucyBpbiB0aGUgcHJlc2VuY2Ugb2Ygb3ZlcnBsb3R0aW5nLiBnZW9tX3Ntb290aCgpIGFuZCBzdGF0X3Ntb290aCgpIGFyZSBlZmZlY3RpdmVseSBhbGlhc2VzOiB0aGV5IGJvdGggdXNlIHRoZSBzYW1lIGFyZ3VtZW50cy4gVXNlIHN0YXRfc21vb3RoKCkgaWYgeW91IHdhbnQgdG8gZGlzcGxheSB0aGUgcmVzdWx0cyB3aXRoIGEgbm9uLXN0YW5kYXJkIGdlb20uDQpgYGB7ciAsIG1lc3NhZ2U9RkFMU0UscmVzdWx0cz0iYXNpcyJ9DQoNCmdncGxvdChjb3ZpZF9zdGF0ZSwgYWVzKHggPSBtb3J0YWxpdHlfcmF0ZSAsIHk9IGNhc2VzX2RlbnNpdHkpKSArIGdlb21fcG9pbnQoKSArIGdlb21fc21vb3RoKG1ldGhvZD1sbSkrDQogICBnZ3RpdGxlKCJDT1ZJRCBNb3J0YWxpdHkgUmF0ZSB2cyBDT1ZJRCBDYXNlIERlbnNpdHkgaW4gdGhlIFVTIFN0YXRlcyIpICsgDQogICAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQobGluZWhlaWdodD0uOCwgZmFjZT0iYm9sZCIpKQ0KDQpgYGANCg0KDQojIyMgQ29uY2x1c2lvbg0KDQpUaGVyZSBhcmUgdGhyZWUgY2xlYXIgb3V0bGllcnMgd2hpY2ggYXJlIHBvc3NpYmx5IHN0b3BwaW5nIHVzIGZyb20gdW5kZXJzdGFuZGluZyB0aGUgY2xlYXIgcmVsYXRpb24gYmV0d2VlbiBtb3J0YWxpdHkgcmF0ZSBhbmQgY2FzZSBkZW5zaXR5Lg0KDQpBZnRlciByZW1vdmluZyB0aGUgb3V0bGllcnMsIHRoZSBkaXN0cmlidXRpb24gc2VlbXMgbW9yZSBsaW5lYXIgd2hlcmUgQ09WSUQgbW9ydGFsaXR5IHJhdGUgaXMgaGlnaGVyIGluIHRoZSBzdGF0ZXMgd2l0aCBoaWdoZXIgQ09WSUQgZGVuc2l0eS4gDQpgYGB7ciAsIG1lc3NhZ2U9RkFMU0UscmVzdWx0cz0iYXNpcyJ9DQoNCmdncGxvdChzdWJzZXQoY292aWRfc3RhdGUsY2FzZXNfZGVuc2l0eSA8NiksIGFlcyh4ID0gbW9ydGFsaXR5X3JhdGUgLCB5PSBjYXNlc19kZW5zaXR5KSkgKyBnZW9tX3BvaW50KCkgKyBnZW9tX3Ntb290aChtZXRob2Q9IGxtKSsNCiAgIGdndGl0bGUoIkNPVklEIE1vcnRhbGl0eSBSYXRlIHZzIENPVklEIENhc2UgRGVuc2l0eSBpbiB0aGUgVVMgU3RhdGVzIikgKyANCiAgICAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChsaW5laGVpZ2h0PS44LCBmYWNlPSJib2xkIikpDQoNCmBgYA0KDQoNCg==