Inspired by this Tweet: https://twitter.com/hspter/status/1134098154167496704

I laughed, but I did not think that this was possible. I imagined it was just playing into my acknowledged stereotype that Germany and Switzerland are impressively rule following and have a special relationship with their vehicles.

Did a quick Google search: rates of seat belt use Germany.

Found this: https://www.who.int/violence_injury_prevention/road_safety_status/2013/country_profiles/germany.pdf?ua=1

So a quick scan of the datasheet says that 98% of people in the front seat use seat belts. Seems pretty great, but then I wanted to know how it all compares.

So I decided to do a #чистый_четвер! (That’s a clean Thursday in Russian as a play off of #TidyTuesday)

My libraries:

rr library(tidyverse) library(ggrepel) library(jsonlite)

Grab the JSON from the WHO site: (My first time getting a JSON independently!!!!)

Notes:

fromJSON(txt, simplifyVector = TRUE, simplifyDataFrame = simplifyVector, simplifyMatrix = simplifyVector, flatten = FALSE, …)

rr seatbelt_who <- fromJSON(://apps.who.int/gho/athena/data/GHO/RS_212.json?filter=COUNTRY:;SEATTYPE:)

Take a peak to make sure I imported correctly.

rr str(seatbelt_who)

List of 5
 $ copyright: chr \(c) World Health Organization\
 $ dataset  :'data.frame':  1 obs. of  2 variables:
  ..$ label  : chr \RSGSR\
  ..$ display: chr \ROAD_SAFETY_GLOBAL_STATUS_REPORT\
 $ attribute:'data.frame':  24 obs. of  2 variables:
  ..$ label  : chr [1:24] \DS\ \FIPS\ \IOC\ \ISO2\ ...
  ..$ display: chr [1:24] \DS\ \FIPS\ \IOC\ \ISO2\ ...
 $ dimension:'data.frame':  6 obs. of  4 variables:
  ..$ label    : chr [1:6] \GHO\ \PUBLISHSTATE\ \YEAR\ \REGION\ ...
  ..$ display  : chr [1:6] \Indicator\ \PUBLISH STATES\ \Year\ \WHO region\ ...
  ..$ isMeasure: logi [1:6] TRUE FALSE FALSE FALSE FALSE FALSE
  ..$ code     :List of 6
  .. ..$ :'data.frame': 1 obs. of  5 variables:
  .. .. ..$ label           : chr \RS_212\
  .. .. ..$ display         : chr \Seat-belt wearing rate (%)\
  .. .. ..$ display_sequence: int 73
  .. .. ..$ url             : chr \http://apps.who.int/gho/indicatorregistry/App_Main/view_indicator.aspx?iid=212\
  .. .. ..$ attr            :List of 1
  .. .. .. ..$ :'data.frame':   2 obs. of  2 variables:
  .. .. .. .. ..$ category: chr [1:2] \CATEGORY\ \DEFINITION_XML\
  .. .. .. .. ..$ value   : chr [1:2] \Injuries and violence\ \http://apps.who.int/gho/indicatorregistryservice/publicapiservice.asmx/IndicatorGetAsXml?profileCode=WHO&applic\| __truncated__
  .. ..$ :'data.frame': 1 obs. of  5 variables:
  .. .. ..$ label           : chr \PUBLISHED\
  .. .. ..$ display         : chr \Published\
  .. .. ..$ display_sequence: int 0
  .. .. ..$ url             : chr \\
  .. .. ..$ attr            :List of 1
  .. .. .. ..$ : list()
  .. ..$ :'data.frame': 1 obs. of  5 variables:
  .. .. ..$ label           : chr \2013\
  .. .. ..$ display         : chr \2013\
  .. .. ..$ display_sequence: int 79867987
  .. .. ..$ url             : chr \\
  .. .. ..$ attr            :List of 1
  .. .. .. ..$ : list()
  .. ..$ :'data.frame': 6 obs. of  5 variables:
  .. .. ..$ label           : chr [1:6] \AFR\ \AMR\ \SEAR\ \EUR\ ...
  .. .. ..$ display         : chr [1:6] \Africa\ \Americas\ \South-East Asia\ \Europe\ ...
  .. .. ..$ display_sequence: int [1:6] 10 20 30 40 50 60
  .. .. ..$ url             : chr [1:6] \\ \\ \\ \\ ...
  .. .. ..$ attr            :List of 6
  .. .. .. ..$ : list()
  .. .. .. ..$ : list()
  .. .. .. ..$ : list()
  .. .. .. ..$ : list()
  .. .. .. ..$ : list()
  .. .. .. ..$ : list()
  .. ..$ :'data.frame': 179 obs. of  5 variables:
  .. .. ..$ label           : chr [1:179] \AFG\ \ALB\ \DZA\ \AND\ ...
  .. .. ..$ display         : chr [1:179] \Afghanistan\ \Albania\ \Algeria\ \Andorra\ ...
  .. .. ..$ display_sequence: int [1:179] 10 20 30 40 50 60 70 80 90 100 ...
  .. .. ..$ url             : chr [1:179] \\ \\ \\ \\ ...
  .. .. ..$ attr            :List of 179
  .. .. .. ..$ :'data.frame':   22 obs. of  2 variables:
  .. .. .. .. ..$ category: chr [1:22] \WORLD_BANK_INCOME_GROUP_GNI_REFERENCE_YEAR\ \WORLD_BANK_INCOME_GROUP_RELEASE_DATE\ \WHO_REGION\ \WORLD_BANK_INCOME_GROUP\ ...
  .. .. .. .. ..$ value   : chr [1:22] \2017\ \2018\ \Eastern Mediterranean\ \Low income\ ...
  .. .. .. ..$ :'data.frame':   22 obs. of  2 variables:
  .. .. .. .. ..$ category: chr [1:22] \WORLD_BANK_INCOME_GROUP_GNI_REFERENCE_YEAR\ \WORLD_BANK_INCOME_GROUP_RELEASE_DATE\ \WHO_REGION\ \WORLD_BANK_INCOME_GROUP\ ...
  .. .. .. .. ..$ value   : chr [1:22] \2017\ \2018\ \Europe\ \Upper middle income\ ...
  .. .. .. ..$ :'data.frame':   22 obs. of  2 variables:
  .. .. .. .. ..$ category: chr [1:22] \WORLD_BANK_INCOME_GROUP_GNI_REFERENCE_YEAR\ \WORLD_BANK_INCOME_GROUP_RELEASE_DATE\ \LAND_AREA_KMSQ_2012\ \LANGUAGES_EN_2012\ ...
  .. .. .. .. ..$ value   : chr [1:22] \2017\ \2018\ \2

Goodness that looks crazy. Seems like there are nested datasets. I’ll try the the simplifed Json to see if I can get started faster.

rr simple_sb <- fromJSON(://apps.who.int/gho/athena/data/GHO/RS_212.json?profile=simple&filter=COUNTRY:;SEATTYPE:)

Check that out.

rr str(simple_sb)

List of 2
 $ dimension:'data.frame':  6 obs. of  2 variables:
  ..$ label  : chr [1:6] \GHO\ \PUBLISHSTATE\ \YEAR\ \REGION\ ...
  ..$ display: chr [1:6] \Indicator\ \PUBLISH STATES\ \Year\ \WHO region\ ...
 $ fact     :'data.frame':  716 obs. of  3 variables:
  ..$ dim     :'data.frame':    716 obs. of  6 variables:
  .. ..$ PUBLISHSTATE: chr [1:716] \Published\ \Published\ \Published\ \Published\ ...
  .. ..$ COUNTRY     : chr [1:716] \Mauritius\ \Serbia\ \Ecuador\ \Ghana\ ...
  .. ..$ YEAR        : chr [1:716] \2013\ \2013\ \2013\ \2013\ ...
  .. ..$ SEATTYPE    : chr [1:716] \Rear seat\ \Rear seat\ \Rear seat\ \Front seat\ ...
  .. ..$ REGION      : chr [1:716] \Africa\ \Europe\ \Americas\ \Africa\ ...
  .. ..$ GHO         : chr [1:716] \Seat-belt wearing rate (%)\ \Seat-belt wearing rate (%)\ \Seat-belt wearing rate (%)\ \Seat-belt wearing rate (%)\ ...
  ..$ Value   : chr [1:716] \0.2\ \3.1\ \3.4\ \4.9\ ...
  ..$ Comments: chr [1:716] NA NA NA NA ...

AHHH! I just want to do some stuff.

rr str(simple_sb$fact)

'data.frame':   716 obs. of  3 variables:
 $ dim     :'data.frame':   716 obs. of  6 variables:
  ..$ PUBLISHSTATE: chr  \Published\ \Published\ \Published\ \Published\ ...
  ..$ COUNTRY     : chr  \Mauritius\ \Serbia\ \Ecuador\ \Ghana\ ...
  ..$ YEAR        : chr  \2013\ \2013\ \2013\ \2013\ ...
  ..$ SEATTYPE    : chr  \Rear seat\ \Rear seat\ \Rear seat\ \Front seat\ ...
  ..$ REGION      : chr  \Africa\ \Europe\ \Americas\ \Africa\ ...
  ..$ GHO         : chr  \Seat-belt wearing rate (%)\ \Seat-belt wearing rate (%)\ \Seat-belt wearing rate (%)\ \Seat-belt wearing rate (%)\ ...
 $ Value   : chr  \0.2\ \3.1\ \3.4\ \4.9\ ...
 $ Comments: chr  NA NA NA NA ...

Omg that worked.

rr sb_facts <- simple_sb$fact str(sb_facts)

'data.frame':   716 obs. of  3 variables:
 $ dim     :'data.frame':   716 obs. of  6 variables:
  ..$ PUBLISHSTATE: chr  \Published\ \Published\ \Published\ \Published\ ...
  ..$ COUNTRY     : chr  \Mauritius\ \Serbia\ \Ecuador\ \Ghana\ ...
  ..$ YEAR        : chr  \2013\ \2013\ \2013\ \2013\ ...
  ..$ SEATTYPE    : chr  \Rear seat\ \Rear seat\ \Rear seat\ \Front seat\ ...
  ..$ REGION      : chr  \Africa\ \Europe\ \Americas\ \Africa\ ...
  ..$ GHO         : chr  \Seat-belt wearing rate (%)\ \Seat-belt wearing rate (%)\ \Seat-belt wearing rate (%)\ \Seat-belt wearing rate (%)\ ...
 $ Value   : chr  \0.2\ \3.1\ \3.4\ \4.9\ ...
 $ Comments: chr  NA NA NA NA ...

Hyperventilating from excitment!!!

names(sb_facts)
[1] "dim"      "Value"    "Comments"

Very confused because when I look at the dataframe it seems to have many columns but only these list and then the data are described as having 3 variables. I think I am missing something about how the data are organized. Gonna try to clean some of it up with janitor.

rr library(janitor) clean_names(sb_facts) r names(sb_facts)

[1] \dim\      \Value\    \Comments\

Still not what I expected. I did see something about simplify and flatten. Maybe that means something I want.

rr seatbelt_flatten <- fromJSON(://apps.who.int/gho/athena/data/GHO/RS_212.json?profile=simple&filter=COUNTRY:;SEATTYPE:, flatten = TRUE)

str(seatbelt_flatten$fact)

'data.frame':   716 obs. of  8 variables:
 $ Value           : chr  \0.2\ \3.1\ \3.4\ \4.9\ ...
 $ Comments        : chr  NA NA NA NA ...
 $ dim.PUBLISHSTATE: chr  \Published\ \Published\ \Published\ \Published\ ...
 $ dim.COUNTRY     : chr  \Mauritius\ \Serbia\ \Ecuador\ \Ghana\ ...
 $ dim.YEAR        : chr  \2013\ \2013\ \2013\ \2013\ ...
 $ dim.SEATTYPE    : chr  \Rear seat\ \Rear seat\ \Rear seat\ \Front seat\ ...
 $ dim.REGION      : chr  \Africa\ \Europe\ \Americas\ \Africa\ ...
 $ dim.GHO         : chr  \Seat-belt wearing rate (%)\ \Seat-belt wearing rate (%)\ \Seat-belt wearing rate (%)\ \Seat-belt wearing rate (%)\ ...

Ok still a bit confused but seemingly having 2 diminesion but better. Seems like I have 8 variables now in $fact part. Going to rename to make easier and attempt to clean.

rr seatbelt_1 <- seatbelt_flatten$fact

str(seatbelt_1)

'data.frame':   716 obs. of  8 variables:
 $ Value           : chr  \0.2\ \3.1\ \3.4\ \4.9\ ...
 $ Comments        : chr  NA NA NA NA ...
 $ dim.PUBLISHSTATE: chr  \Published\ \Published\ \Published\ \Published\ ...
 $ dim.COUNTRY     : chr  \Mauritius\ \Serbia\ \Ecuador\ \Ghana\ ...
 $ dim.YEAR        : chr  \2013\ \2013\ \2013\ \2013\ ...
 $ dim.SEATTYPE    : chr  \Rear seat\ \Rear seat\ \Rear seat\ \Front seat\ ...
 $ dim.REGION      : chr  \Africa\ \Europe\ \Americas\ \Africa\ ...
 $ dim.GHO         : chr  \Seat-belt wearing rate (%)\ \Seat-belt wearing rate (%)\ \Seat-belt wearing rate (%)\ \Seat-belt wearing rate (%)\ ...

rr seatbelt_1 <- clean_names(seatbelt_1)

rr colnames(seatbelt_1)

[1] \value\            \comments\        
[3] \dim_publishstate\ \dim_country\     
[5] \dim_year\         \dim_seattype\    
[7] \dim_region\       \dim_gho\         

Great. Names look better. But everything looks like a chr. I am going to coerece some cols. … I fell down a rabbit hole. I read some stuff on stackoverflow https://stackoverflow.com/questions/22772279/converting-multiple-columns-from-character-to-numeric-format-in-r

But also as totally unrelated to this analysis commentary. I like stackoverflow but I get anxious reading the comments sometime. The comments can be sooo snippy: https://stackoverflow.com/a/53857448/11484875 . Doesn’t seem very welcoming and I don’t have the confidence to post there, yet. I am so thankful for everyone that does though!

Ok back to analysis

This looks promising: df %>% mutate_at(‘x1’,as.numeric) %>% str()

Also lots about lapply

data[] <- lapply(data, function(x) type.convert(as.character(x), as.is = TRUE)) #change all vars to their best fitting data type

rr lapply(seatbelt_1, class)

$value
[1] \character\

$comments
[1] \character\

$dim_publishstate
[1] \character\

$dim_country
[1] \character\

$dim_year
[1] \character\

$dim_seattype
[1] \character\

$dim_region
[1] \character\

$dim_gho
[1] \character\

rr seatbelt_convert_1 <- lapply(seatbelt_1, function(x) type.convert(as.character(x), as.is = TRUE)) #change all vars to their best fitting data type str(seatbelt_convert_1)

List of 8
 $ value           : chr [1:716] \0.2\ \3.1\ \3.4\ \4.9\ ...
 $ comments        : chr [1:716] NA NA NA NA ...
 $ dim_publishstate: chr [1:716] \Published\ \Published\ \Published\ \Published\ ...
 $ dim_country     : chr [1:716] \Mauritius\ \Serbia\ \Ecuador\ \Ghana\ ...
 $ dim_year        : int [1:716] 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
 $ dim_seattype    : chr [1:716] \Rear seat\ \Rear seat\ \Rear seat\ \Front seat\ ...
 $ dim_region      : chr [1:716] \Africa\ \Europe\ \Americas\ \Africa\ ...
 $ dim_gho         : chr [1:716] \Seat-belt wearing rate (%)\ \Seat-belt wearing rate (%)\ \Seat-belt wearing rate (%)\ \Seat-belt wearing rate (%)\ ...

Nope

Try again # by specific columns: df %>% mutate_at(vars(x, y, z), ~as.numeric(as.character(.)))

seatbelt_convert_2 <- seatbelt_1 %>% mutate_at(vars(1,5), ~as.numeric(as.character(.))) %>% mutate_at(vars(3, 6, 7, 8), ~as.factor(as.character(.))) 
NAs introduced by coercion
str(seatbelt_convert_2)
'data.frame':   716 obs. of  8 variables:
 $ value           : num  0.2 3.1 3.4 4.9 12.5 12.6 13.4 13.7 17.5 17.6 ...
 $ comments        : chr  NA NA NA NA ...
 $ dim_publishstate: Factor w/ 1 level "Published": 1 1 1 1 1 1 1 1 1 1 ...
 $ dim_country     : chr  "Mauritius" "Serbia" "Ecuador" "Ghana" ...
 $ dim_year        : num  2013 2013 2013 2013 2013 ...
 $ dim_seattype    : Factor w/ 4 levels "All occupants",..: 4 4 4 3 4 4 4 2 4 2 ...
 $ dim_region      : Factor w/ 6 levels "Africa","Americas",..: 1 4 2 1 6 2 4 3 4 1 ...
 $ dim_gho         : Factor w/ 1 level "Seat-belt wearing rate (%)": 1 1 1 1 1 1 1 1 1 1 ...

Looks like that worked!!!

Okay these seems great. I don’t quite understand some of the piping behavior, but moving forward!!!

Time to plot!!! Lets look at counties in europe. still a lot, so just front seat rates and then exclude ones with NA

europe_seatbelt <-  filter(seatbelt_convert_2, dim_region=="Europe")

europe_seatbelt_front <- filter(europe_seatbelt, dim_seattype =="Front seat")

europe_seatbelt_final <- filter(europe_seatbelt_front,  !is.na(value))
europe_graph <- ggplot(europe_seatbelt_final) + aes(x = reorder(dim_country, value)) + aes(y = value) + geom_point()

europe_graph

I am so pleased!! I did not know about reorder until now!!!! I knew it must exist but hadn’t used it!

titles <- labs(title = "Who has their seatbelt on in Europe? (2013)", subtitle = "Exploring seatbelt use after falling into a Tweethole by @MaraAlexeev", x = "", y = "Front Seatbelt Use % -- Red line is 95%", caption = "Data from WHO")

europe_graph + titles

Ok to fix the country names and add color



  
europe_graph + titles + coord_flip() + scale_color_gradient() +
 theme_classic() + geom_hline(yintercept=95, linetype="dashed", color = "red") + scale_y_continuous(position = "right") + scale_x_discrete(position = "top") 

Omg. THe data looks like a buckled seat belt!!!!!!!!

LS0tCnRpdGxlOiAiU2VhdGJlbHQgQW5hbHlzaXMiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCkluc3BpcmVkIGJ5IHRoaXMgVHdlZXQ6Cmh0dHBzOi8vdHdpdHRlci5jb20vaHNwdGVyL3N0YXR1cy8xMTM0MDk4MTU0MTY3NDk2NzA0CgpJIGxhdWdoZWQsIGJ1dCBJIGRpZCBub3QgdGhpbmsgdGhhdCB0aGlzIHdhcyBwb3NzaWJsZS4gSSBpbWFnaW5lZCBpdCB3YXMganVzdCBwbGF5aW5nIGludG8gbXkgYWNrbm93bGVkZ2VkIHN0ZXJlb3R5cGUgdGhhdCBHZXJtYW55IGFuZCBTd2l0emVybGFuZCBhcmUgaW1wcmVzc2l2ZWx5IHJ1bGUgZm9sbG93aW5nIGFuZCBoYXZlIGEgc3BlY2lhbCByZWxhdGlvbnNoaXAgd2l0aCB0aGVpciB2ZWhpY2xlcy4gCgpEaWQgYSBxdWljayBHb29nbGUgc2VhcmNoOiByYXRlcyBvZiBzZWF0IGJlbHQgdXNlIEdlcm1hbnkuCgpGb3VuZCB0aGlzOiBodHRwczovL3d3dy53aG8uaW50L3Zpb2xlbmNlX2luanVyeV9wcmV2ZW50aW9uL3JvYWRfc2FmZXR5X3N0YXR1cy8yMDEzL2NvdW50cnlfcHJvZmlsZXMvZ2VybWFueS5wZGY/dWE9MQoKU28gYSBxdWljayBzY2FuIG9mIHRoZSBkYXRhc2hlZXQgc2F5cyB0aGF0IDk4JSBvZiBwZW9wbGUgaW4gdGhlIGZyb250IHNlYXQgdXNlIHNlYXQgYmVsdHMuIFNlZW1zIHByZXR0eSBncmVhdCwgYnV0IHRoZW4gSSB3YW50ZWQgdG8ga25vdyBob3cgaXQgYWxsIGNvbXBhcmVzLiAKClNvIEkgZGVjaWRlZCB0byBkbyBhICPRh9C40YHRgtGL0Llf0YfQtdGC0LLQtdGAISAoVGhhdCdzIGEgY2xlYW4gVGh1cnNkYXkgaW4gUnVzc2lhbiBhcyBhIHBsYXkgb2ZmIG9mICNUaWR5VHVlc2RheSkKCk15IGxpYnJhcmllczoKCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShnZ3JlcGVsKQpsaWJyYXJ5KGpzb25saXRlKQpgYGAKCgpHcmFiIHRoZSBKU09OIGZyb20gdGhlIFdITyBzaXRlOgooTXkgZmlyc3QgdGltZSBnZXR0aW5nIGEgSlNPTiBpbmRlcGVuZGVudGx5ISEhISkKCk5vdGVzOiAKCmZyb21KU09OKHR4dCwgc2ltcGxpZnlWZWN0b3IgPSBUUlVFLApzaW1wbGlmeURhdGFGcmFtZSA9IHNpbXBsaWZ5VmVjdG9yLCBzaW1wbGlmeU1hdHJpeCA9IHNpbXBsaWZ5VmVjdG9yLApmbGF0dGVuID0gRkFMU0UsIC4uLikKCmBgYHtyfQpzZWF0YmVsdF93aG8gPC0gZnJvbUpTT04oImh0dHBzOi8vYXBwcy53aG8uaW50L2doby9hdGhlbmEvZGF0YS9HSE8vUlNfMjEyLmpzb24/ZmlsdGVyPUNPVU5UUlk6KjtTRUFUVFlQRToqIikKYGBgCgpUYWtlIGEgcGVhayB0byBtYWtlIHN1cmUgSSBpbXBvcnRlZCBjb3JyZWN0bHkuCgpgYGB7cn0Kc3RyKHNlYXRiZWx0X3dobykKYGBgCkdvb2RuZXNzIHRoYXQgbG9va3MgY3JhenkuIFNlZW1zIGxpa2UgdGhlcmUgYXJlIG5lc3RlZCBkYXRhc2V0cy4gSSdsbCB0cnkgdGhlIHRoZSBzaW1wbGlmZWQgSnNvbiB0byBzZWUgaWYgSSBjYW4gZ2V0IHN0YXJ0ZWQgZmFzdGVyLiAKCmBgYHtyfQpzaW1wbGVfc2IgPC0gZnJvbUpTT04oImh0dHBzOi8vYXBwcy53aG8uaW50L2doby9hdGhlbmEvZGF0YS9HSE8vUlNfMjEyLmpzb24/cHJvZmlsZT1zaW1wbGUmZmlsdGVyPUNPVU5UUlk6KjtTRUFUVFlQRToqIikKYGBgCgpDaGVjayB0aGF0IG91dC4KYGBge3J9CnN0cihzaW1wbGVfc2IpCmBgYAoKQUhISCEgSSBqdXN0IHdhbnQgdG8gZG8gc29tZSBzdHVmZi4gCgpgYGB7cn0Kc3RyKHNpbXBsZV9zYiRmYWN0KQpgYGAKT21nIHRoYXQgd29ya2VkLgoKYGBge3J9CnNiX2ZhY3RzIDwtIHNpbXBsZV9zYiRmYWN0CnN0cihzYl9mYWN0cykKYGBgCgpIeXBlcnZlbnRpbGF0aW5nIGZyb20gZXhjaXRtZW50ISEhCgpgYGB7cn0KbmFtZXMoc2JfZmFjdHMpCmBgYApWZXJ5IGNvbmZ1c2VkIGJlY2F1c2Ugd2hlbiBJIGxvb2sgYXQgdGhlIGRhdGFmcmFtZSBpdCBzZWVtcyB0byBoYXZlIG1hbnkgY29sdW1ucyBidXQgb25seSB0aGVzZSBsaXN0IGFuZCB0aGVuIHRoZSBkYXRhIGFyZSBkZXNjcmliZWQgYXMgaGF2aW5nIDMgdmFyaWFibGVzLiBJIHRoaW5rIEkgYW0gbWlzc2luZyBzb21ldGhpbmcgYWJvdXQgaG93IHRoZSBkYXRhIGFyZSBvcmdhbml6ZWQuIEdvbm5hIHRyeSB0byBjbGVhbiBzb21lIG9mIGl0IHVwIHdpdGggamFuaXRvci4KCmBgYHtyfQpsaWJyYXJ5KGphbml0b3IpCmNsZWFuX25hbWVzKHNiX2ZhY3RzKQpuYW1lcyhzYl9mYWN0cykKYGBgCgpTdGlsbCBub3Qgd2hhdCBJIGV4cGVjdGVkLiBJIGRpZCBzZWUgc29tZXRoaW5nIGFib3V0IHNpbXBsaWZ5IGFuZCBmbGF0dGVuLiBNYXliZSB0aGF0IG1lYW5zIHNvbWV0aGluZyBJIHdhbnQuIApgYGB7cn0Kc2VhdGJlbHRfZmxhdHRlbiA8LSBmcm9tSlNPTigiaHR0cHM6Ly9hcHBzLndoby5pbnQvZ2hvL2F0aGVuYS9kYXRhL0dITy9SU18yMTIuanNvbj9wcm9maWxlPXNpbXBsZSZmaWx0ZXI9Q09VTlRSWToqO1NFQVRUWVBFOioiLCBmbGF0dGVuID0gVFJVRSkKICAKc3RyKHNlYXRiZWx0X2ZsYXR0ZW4kZmFjdCkKYGBgCgpPayBzdGlsbCBhIGJpdCBjb25mdXNlZCBidXQgc2VlbWluZ2x5IGhhdmluZyAyIGRpbWluZXNpb24gYnV0IGJldHRlci4gU2VlbXMgbGlrZSBJIGhhdmUgOCB2YXJpYWJsZXMgbm93IGluICRmYWN0IHBhcnQuIEdvaW5nIHRvIHJlbmFtZSB0byBtYWtlIGVhc2llciBhbmQgYXR0ZW1wdCB0byBjbGVhbi4gCgpgYGB7cn0Kc2VhdGJlbHRfMSA8LSBzZWF0YmVsdF9mbGF0dGVuJGZhY3QKCnN0cihzZWF0YmVsdF8xKQpzZWF0YmVsdF8xIDwtIGNsZWFuX25hbWVzKHNlYXRiZWx0XzEpCgpgYGAKCmBgYHtyfQpjb2xuYW1lcyhzZWF0YmVsdF8xKQpgYGAKCkdyZWF0LiBOYW1lcyBsb29rIGJldHRlci4gQnV0IGV2ZXJ5dGhpbmcgbG9va3MgbGlrZSBhIGNoci4gSSBhbSBnb2luZyB0byBjb2VyZWNlIHNvbWUgY29scy4gCi4uLgpJIGZlbGwgZG93biBhIHJhYmJpdCBob2xlLiBJIHJlYWQgc29tZSBzdHVmZiBvbiBzdGFja292ZXJmbG93Cmh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzIyNzcyMjc5L2NvbnZlcnRpbmctbXVsdGlwbGUtY29sdW1ucy1mcm9tLWNoYXJhY3Rlci10by1udW1lcmljLWZvcm1hdC1pbi1yCgoKQnV0IGFsc28gYXMgdG90YWxseSB1bnJlbGF0ZWQgdG8gdGhpcyBhbmFseXNpcyBjb21tZW50YXJ5LiBJIGxpa2Ugc3RhY2tvdmVyZmxvdyBidXQgSSBnZXQgYW54aW91cyByZWFkaW5nIHRoZSBjb21tZW50cyBzb21ldGltZS4gVGhlIGNvbW1lbnRzIGNhbiBiZSBzb29vIHNuaXBweTogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzUzODU3NDQ4LzExNDg0ODc1IC4gRG9lc24ndCBzZWVtIHZlcnkgd2VsY29taW5nIGFuZCBJIGRvbid0IGhhdmUgdGhlIGNvbmZpZGVuY2UgdG8gcG9zdCB0aGVyZSwgeWV0LiAKSSBhbSBzbyB0aGFua2Z1bCBmb3IgZXZlcnlvbmUgdGhhdCBkb2VzIHRob3VnaCEgCgoKT2sgYmFjayB0byBhbmFseXNpcwoKVGhpcyBsb29rcyBwcm9taXNpbmc6IApkZiAlPiUgbXV0YXRlX2F0KCd4MScsYXMubnVtZXJpYykgJT4lIHN0cigpCgpBbHNvIGxvdHMgYWJvdXQgbGFwcGx5CgogIGRhdGFbXSA8LSBsYXBwbHkoZGF0YSwgZnVuY3Rpb24oeCkgdHlwZS5jb252ZXJ0KGFzLmNoYXJhY3Rlcih4KSwgYXMuaXMgPSBUUlVFKSkgI2NoYW5nZSBhbGwgdmFycyB0byB0aGVpciBiZXN0IGZpdHRpbmcgZGF0YSB0eXBlCmBgYHtyfQpsYXBwbHkoc2VhdGJlbHRfMSwgY2xhc3MpCmBgYAoKYGBge3J9CiAgc2VhdGJlbHRfY29udmVydF8xIDwtIGxhcHBseShzZWF0YmVsdF8xLCBmdW5jdGlvbih4KSB0eXBlLmNvbnZlcnQoYXMuY2hhcmFjdGVyKHgpLCBhcy5pcyA9IFRSVUUpKSAjY2hhbmdlIGFsbCB2YXJzIHRvIHRoZWlyIGJlc3QgZml0dGluZyBkYXRhIHR5cGUKc3RyKHNlYXRiZWx0X2NvbnZlcnRfMSkKYGBgCgpOb3BlCgpUcnkgYWdhaW4KIyBieSBzcGVjaWZpYyBjb2x1bW5zOgpkZiAlPiUgCiAgbXV0YXRlX2F0KHZhcnMoeCwgeSwgeiksIH5hcy5udW1lcmljKGFzLmNoYXJhY3RlciguKSkpIAogIApgYGB7cn0Kc2VhdGJlbHRfY29udmVydF8yIDwtIHNlYXRiZWx0XzEgJT4lIG11dGF0ZV9hdCh2YXJzKDEsNSksIH5hcy5udW1lcmljKGFzLmNoYXJhY3RlciguKSkpICU+JSBtdXRhdGVfYXQodmFycygzLCA2LCA3LCA4KSwgfmFzLmZhY3Rvcihhcy5jaGFyYWN0ZXIoLikpKSAKc3RyKHNlYXRiZWx0X2NvbnZlcnRfMikKYGBgCiAgCkxvb2tzIGxpa2UgdGhhdCB3b3JrZWQhISEKCk9rYXkgdGhlc2Ugc2VlbXMgZ3JlYXQuIEkgZG9uJ3QgcXVpdGUgdW5kZXJzdGFuZCBzb21lIG9mIHRoZSBwaXBpbmcgYmVoYXZpb3IsIGJ1dCBtb3ZpbmcgZm9yd2FyZCEhIQoKVGltZSB0byBwbG90ISEhCkxldHMgbG9vayBhdCBjb3VudGllcyBpbiBldXJvcGUuIHN0aWxsIGEgbG90LCBzbyBqdXN0IGZyb250IHNlYXQgcmF0ZXMgYW5kIHRoZW4gZXhjbHVkZSBvbmVzIHdpdGggTkEKCmBgYHtyfQpldXJvcGVfc2VhdGJlbHQgPC0gIGZpbHRlcihzZWF0YmVsdF9jb252ZXJ0XzIsIGRpbV9yZWdpb249PSJFdXJvcGUiKQoKZXVyb3BlX3NlYXRiZWx0X2Zyb250IDwtIGZpbHRlcihldXJvcGVfc2VhdGJlbHQsIGRpbV9zZWF0dHlwZSA9PSJGcm9udCBzZWF0IikKCmV1cm9wZV9zZWF0YmVsdF9maW5hbCA8LSBmaWx0ZXIoZXVyb3BlX3NlYXRiZWx0X2Zyb250LCAgIWlzLm5hKHZhbHVlKSkKYGBgCgpgYGB7cn0KZXVyb3BlX2dyYXBoIDwtIGdncGxvdChldXJvcGVfc2VhdGJlbHRfZmluYWwpICsgYWVzKHggPSByZW9yZGVyKGRpbV9jb3VudHJ5LCB2YWx1ZSkpICsgYWVzKHkgPSB2YWx1ZSkgKyBnZW9tX3BvaW50KCkKCmV1cm9wZV9ncmFwaApgYGAKSSBhbSBzbyBwbGVhc2VkISEgSSBkaWQgbm90IGtub3cgYWJvdXQgcmVvcmRlciB1bnRpbCBub3chISEhIEkga25ldyBpdCBtdXN0IGV4aXN0IGJ1dCBoYWRuJ3QgdXNlZCBpdCEKCmBgYHtyfQp0aXRsZXMgPC0gbGFicyh0aXRsZSA9ICJXaG8gaGFzIHRoZWlyIHNlYXRiZWx0IG9uIGluIEV1cm9wZT8gKDIwMTMpIiwgc3VidGl0bGUgPSAiRXhwbG9yaW5nIHNlYXRiZWx0IHVzZSBhZnRlciBmYWxsaW5nIGludG8gYSBUd2VldGhvbGUgYnkgQE1hcmFBbGV4ZWV2IiwgeCA9ICIiLCB5ID0gIkZyb250IFNlYXRiZWx0IFVzZSAlIC0tIFJlZCBsaW5lIGlzIDk1JSIsIGNhcHRpb24gPSAiRGF0YSBmcm9tIFdITyIpCgpldXJvcGVfZ3JhcGggKyB0aXRsZXMKYGBgCgpPayB0byBmaXggdGhlIGNvdW50cnkgbmFtZXMgYW5kIGFkZCBjb2xvciAKYGBge3J9CgoKICAKZXVyb3BlX2dyYXBoICsgdGl0bGVzICsgY29vcmRfZmxpcCgpICsgc2NhbGVfY29sb3JfZ3JhZGllbnQoKSArCiB0aGVtZV9jbGFzc2ljKCkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQ9OTUsIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJyZWQiKSArIHNjYWxlX3lfY29udGludW91cyhwb3NpdGlvbiA9ICJyaWdodCIpICsgc2NhbGVfeF9kaXNjcmV0ZShwb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCk9tZy4gVEhlIGRhdGEgbG9va3MgbGlrZSBhIGJ1Y2tsZWQgc2VhdCBiZWx0ISEhISEhISEK