Link for downloading the Doctor Who font: https://fontmeme.com/fuentes/fuente-doctor-who/
# Loading packages and data
library(tidyverse)
library(waffle)
library(patchwork)
tuesdata <- tidytuesdayR::tt_load('2021-11-23')
episodes <- tuesdata$episodes
writers <- tuesdata$writers
imdb <- tuesdata$imdb
directors <- tuesdata$directors
# setwd(here::here())
#
# library(extrafont)
Examining the distribution of episodes by director
writers %>% count(writer, sort = TRUE)
Manipulating the data to get the amount of episodes from the 5
directors with most episodes, and grouping everybody else in
“Other”.
# Episodes by type
episodes_by_type <-
episodes %>%
select(story_number, type) %>%
mutate(type = ifelse(type == "episode", "Regular Episode", "Special"),
type = fct_relevel(type, "Special", "Regular Episode"))
df_eps_writers <-
writers %>%
left_join(episodes_by_type) %>%
mutate(writer = fct_lump_n(writer, n = 6)) %>%
count(writer, type) %>%
mutate(writer = fct_reorder(writer, n, .fun = sum, .desc = TRUE),
writer = fct_relevel(writer, "Other", after = Inf)) %>%
ungroup()
Joining, by = "story_number"
df_eps_writers
Creating the waffle plot of total episodes by director:
# Defining breaks for Y axis
max_value_y_axis <- max(df_eps_writers$n) %/% 5
seq_breaks <- seq(0, max_value_y_axis, by = 2)
plot_waffle <-
ggplot(df_eps_writers) +
waffle::geom_waffle(aes(fill = type, values = n),
color = "#01050e", size = 0.25, n_rows = 5, flip = TRUE) +
facet_wrap(~writer, nrow = 1, strip.position = "bottom") +
scale_x_discrete() +
scale_y_continuous(labels = function(x) x * 5, #this should be the same as n_rows
breaks = seq_breaks,
expand = c(0, 0),
name = "Number of episodes") +
coord_equal() +
scale_fill_manual(name = NULL,
values = c("Regular Episode" = "#003b6f",
"Special" = "#e04006")) +
theme_minimal(base_family = "Bahnschrift") +
theme(panel.grid = element_blank(),
axis.ticks.y = element_line(color = "white"),
legend.position = c(0.6, 0.7),
plot.title = element_text(family = "Doctor Who", size = 22,
color = "white", face = "plain"),
plot.subtitle = element_text(size = 12,
color = "white", face = "plain"),
plot.background = element_rect(fill = '#01050e'),
axis.title.y = element_text(color = "white"),
axis.text = element_text(color = "white"),
strip.text = element_text(color = "white"),
legend.text = element_text(color = "white")
) +
labs(title = "Doctor Who episodes by director",
subtitle = "Who has been the best?")
plot_waffle
Another plot: IMDB ratings by director. Joining and manipulating to
get the scores associated to the directors, and the average score by
director.
episodes2 <-
episodes %>%
select(story_number, type, season_number, episode_number, episode_title)
epi_writ_imdb <-
writers %>%
left_join(episodes2) %>%
left_join(imdb,
by = c("season_number" = "season",
"episode_number" = "ep_num")) %>%
mutate(writer = fct_lump_n(writer, n = 6),
writer = fct_reorder(writer, rep(1, n()), .fun = sum, .desc = TRUE),
writer = fct_relevel(writer, "Other", after = Inf))
Joining, by = "story_number"
rat_by_writer <-
epi_writ_imdb %>%
group_by(writer) %>%
summarise(avg_rating = mean(rating, na.rm = TRUE))
rat_by_writer
Creating the dataframe with the best and worst episode by
director
best_and_worst <-
epi_writ_imdb %>%
filter(complete.cases(.)) %>%
group_by(writer) %>%
mutate(worst = row_number(rating) == 1,
best = row_number(desc(rating)) == 1) %>%
filter(best | worst) %>%
mutate(rating_label = ifelse(best,
rating + 0.2,
rating - 0.2))
best_and_worst
Plot of distributions of IMDB scores by director:
data_plot <- epi_writ_imdb %>%
select(writer, rating, episode_title) %>%
anti_join(best_and_worst,
by = c("writer", "rating", "episode_title"))
plot_best_worst <-
data_plot %>%
ggplot(aes(writer, y = rating)) +
geom_point(alpha = 0.4,
position = position_jitter(seed = 1989),
color = "white") +
geom_label(data = rat_by_writer,
aes(writer, y = avg_rating, label = round(avg_rating, 1)),
fill = "black",
color = "white",
size = 5.2,
family = "Bahnschrift",
label.r = unit(0, "lines"),
label.size = 0.1,
label.padding = unit(0.3, "lines"),
alpha = 0.8) +
geom_text(data = best_and_worst,
family = "Bahnschrift",
aes(y = rating_label, label = str_wrap(episode_title, 15)),
size = 3,
vjust = best_and_worst$worst,
color = "white") +
geom_point(data = best_and_worst,
color = "white") +
facet_wrap(~writer, nrow = 1, scales = "free_x") +
scale_x_discrete(breaks = c(0.5, 1.5, 2.5)) +
theme_minimal(base_family = "Bahnschrift") +
theme(panel.grid.major.y = element_blank(),
panel.grid.minor.y = element_blank(),
axis.ticks.y = element_line(),
axis.title.x = element_blank(),
axis.text.x = element_blank(),
strip.text.x = element_blank(),
plot.background = element_rect(fill = '#01050e'),
axis.title.y = element_text(color = "white"),
axis.text = element_text(color = "white"),
strip.text = element_text(color = "white"),
legend.text = element_text(color = "white"),
plot.caption = element_text(color = "#6f8ea9")) +
labs(y = "IMDB Ratings",
caption = "@franciscoyira\ngithub.com/franciscoyira\nSource: {datardis} R package")
plot_best_worst
Warning: Removed 28 rows containing missing values (geom_point).
Putting both plots together with patchwork:
combined_plot <-
(plot_waffle / plot_best_worst)
combined_plot <-
combined_plot &
theme(plot.background = element_rect(fill = '#01050e',
color = '#01050e'))
combined_plot
Warning: Removed 28 rows containing missing values (geom_point).
LS0tDQp0aXRsZTogIlRpZHlUdWVzZGF5IDIwMjEtMTEtMjMiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpMaW5rIGZvciBkb3dubG9hZGluZyB0aGUgRG9jdG9yIFdobyBmb250OiBodHRwczovL2ZvbnRtZW1lLmNvbS9mdWVudGVzL2Z1ZW50ZS1kb2N0b3Itd2hvLw0KDQpgYGB7ciBzZXR1cCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiMgTG9hZGluZyBwYWNrYWdlcyBhbmQgZGF0YQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHdhZmZsZSkNCmxpYnJhcnkocGF0Y2h3b3JrKQ0KDQp0dWVzZGF0YSA8LSB0aWR5dHVlc2RheVI6OnR0X2xvYWQoJzIwMjEtMTEtMjMnKQ0KDQplcGlzb2RlcyA8LSB0dWVzZGF0YSRlcGlzb2Rlcw0Kd3JpdGVycyA8LSB0dWVzZGF0YSR3cml0ZXJzDQppbWRiIDwtIHR1ZXNkYXRhJGltZGINCmRpcmVjdG9ycyA8LSB0dWVzZGF0YSRkaXJlY3RvcnMNCg0KIyBzZXR3ZChoZXJlOjpoZXJlKCkpDQojIA0KIyBsaWJyYXJ5KGV4dHJhZm9udCkNCg0KYGBgDQoNCkV4YW1pbmluZyB0aGUgZGlzdHJpYnV0aW9uIG9mIGVwaXNvZGVzIGJ5IGRpcmVjdG9yDQoNCmBgYHtyfQ0Kd3JpdGVycyAlPiUgY291bnQod3JpdGVyLCBzb3J0ID0gVFJVRSkNCmBgYA0KDQpNYW5pcHVsYXRpbmcgdGhlIGRhdGEgdG8gZ2V0IHRoZSBhbW91bnQgb2YgZXBpc29kZXMgZnJvbSB0aGUgNSBkaXJlY3RvcnMgd2l0aCBtb3N0IGVwaXNvZGVzLCBhbmQgZ3JvdXBpbmcgZXZlcnlib2R5IGVsc2UgaW4gIk90aGVyIi4NCg0KYGBge3J9DQojIEVwaXNvZGVzIGJ5IHR5cGUNCmVwaXNvZGVzX2J5X3R5cGUgPC0gDQogIGVwaXNvZGVzICU+JSANCiAgc2VsZWN0KHN0b3J5X251bWJlciwgdHlwZSkgJT4lIA0KICBtdXRhdGUodHlwZSA9IGlmZWxzZSh0eXBlID09ICJlcGlzb2RlIiwgIlJlZ3VsYXIgRXBpc29kZSIsICJTcGVjaWFsIiksDQogICAgICAgICB0eXBlID0gZmN0X3JlbGV2ZWwodHlwZSwgIlNwZWNpYWwiLCAiUmVndWxhciBFcGlzb2RlIikpDQoNCiAgDQpkZl9lcHNfd3JpdGVycyA8LSANCiAgd3JpdGVycyAlPiUgDQogIGxlZnRfam9pbihlcGlzb2Rlc19ieV90eXBlKSAlPiUgDQogIG11dGF0ZSh3cml0ZXIgPSBmY3RfbHVtcF9uKHdyaXRlciwgbiA9IDYpKSAlPiUgDQogIGNvdW50KHdyaXRlciwgdHlwZSkgJT4lIA0KICBtdXRhdGUod3JpdGVyID0gZmN0X3Jlb3JkZXIod3JpdGVyLCBuLCAuZnVuID0gc3VtLCAuZGVzYyA9IFRSVUUpLA0KICAgICAgICAgd3JpdGVyID0gZmN0X3JlbGV2ZWwod3JpdGVyLCAiT3RoZXIiLCBhZnRlciA9IEluZikpICU+JSANCiAgdW5ncm91cCgpDQoNCmRmX2Vwc193cml0ZXJzDQpgYGANCg0KQ3JlYXRpbmcgdGhlIHdhZmZsZSBwbG90IG9mIHRvdGFsIGVwaXNvZGVzIGJ5IGRpcmVjdG9yOg0KYGBge3J9DQojIERlZmluaW5nIGJyZWFrcyBmb3IgWSBheGlzDQptYXhfdmFsdWVfeV9heGlzIDwtIG1heChkZl9lcHNfd3JpdGVycyRuKSAgJS8lIDUNCnNlcV9icmVha3MgPC0gc2VxKDAsIG1heF92YWx1ZV95X2F4aXMsIGJ5ID0gMikNCg0KcGxvdF93YWZmbGUgPC0gDQogIGdncGxvdChkZl9lcHNfd3JpdGVycykgKw0KICB3YWZmbGU6Omdlb21fd2FmZmxlKGFlcyhmaWxsID0gdHlwZSwgdmFsdWVzID0gbiksDQogICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAiIzAxMDUwZSIsIHNpemUgPSAwLjI1LCBuX3Jvd3MgPSA1LCBmbGlwID0gVFJVRSkgKw0KICBmYWNldF93cmFwKH53cml0ZXIsIG5yb3cgPSAxLCBzdHJpcC5wb3NpdGlvbiA9ICJib3R0b20iKSArDQogIHNjYWxlX3hfZGlzY3JldGUoKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBmdW5jdGlvbih4KSB4ICogNSwgI3RoaXMgc2hvdWxkIGJlIHRoZSBzYW1lIGFzIG5fcm93cw0KICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gc2VxX2JyZWFrcywNCiAgICAgICAgICAgICAgICAgICAgIGV4cGFuZCA9IGMoMCwgMCksDQogICAgICAgICAgICAgICAgICAgICBuYW1lID0gIk51bWJlciBvZiBlcGlzb2RlcyIpICsNCiAgY29vcmRfZXF1YWwoKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgPSBOVUxMLA0KICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBjKCJSZWd1bGFyIEVwaXNvZGUiID0gIiMwMDNiNmYiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTcGVjaWFsIiA9ICIjZTA0MDA2IikpICsNCiAgdGhlbWVfbWluaW1hbChiYXNlX2ZhbWlseSA9ICJCYWhuc2NocmlmdCIpICsNCiAgdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9saW5lKGNvbG9yID0gIndoaXRlIiksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC42LCAwLjcpLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJEb2N0b3IgV2hvIiwgc2l6ZSA9IDIyLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIiwgZmFjZSA9ICJwbGFpbiIpLA0KICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIsIGZhY2UgPSAicGxhaW4iKSwNCiAgICAgICAgcGxvdC5iYWNrZ3JvdW5kICA9IGVsZW1lbnRfcmVjdChmaWxsID0gJyMwMTA1MGUnKSwNCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gIndoaXRlIiksDQogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJ3aGl0ZSIpLA0KICAgICAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gIndoaXRlIiksDQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gIndoaXRlIikNCiAgICAgICAgKSArDQogIGxhYnModGl0bGUgPSAiRG9jdG9yIFdobyBlcGlzb2RlcyBieSBkaXJlY3RvciIsDQogICAgICAgc3VidGl0bGUgPSAiV2hvIGhhcyBiZWVuIHRoZSBiZXN0PyIpDQogIA0KcGxvdF93YWZmbGUNCmBgYA0KDQpBbm90aGVyIHBsb3Q6IElNREIgcmF0aW5ncyBieSBkaXJlY3Rvci4NCkpvaW5pbmcgYW5kIG1hbmlwdWxhdGluZyB0byBnZXQgdGhlIHNjb3JlcyBhc3NvY2lhdGVkIHRvIHRoZSBkaXJlY3RvcnMsIGFuZCB0aGUgYXZlcmFnZSBzY29yZSBieSBkaXJlY3Rvci4NCmBgYHtyfQ0KZXBpc29kZXMyIDwtIA0KICBlcGlzb2RlcyAlPiUgDQogIHNlbGVjdChzdG9yeV9udW1iZXIsIHR5cGUsIHNlYXNvbl9udW1iZXIsIGVwaXNvZGVfbnVtYmVyLCBlcGlzb2RlX3RpdGxlKQ0KDQplcGlfd3JpdF9pbWRiIDwtIA0KICB3cml0ZXJzICU+JSANCiAgbGVmdF9qb2luKGVwaXNvZGVzMikgJT4lIA0KICBsZWZ0X2pvaW4oaW1kYiwNCiAgICAgICAgICAgIGJ5ID0gYygic2Vhc29uX251bWJlciIgPSAic2Vhc29uIiwNCiAgICAgICAgICAgICAgICAgICAiZXBpc29kZV9udW1iZXIiID0gImVwX251bSIpKSAlPiUgDQogIG11dGF0ZSh3cml0ZXIgPSBmY3RfbHVtcF9uKHdyaXRlciwgbiA9IDYpLA0KICAgICAgICAgd3JpdGVyID0gZmN0X3Jlb3JkZXIod3JpdGVyLCByZXAoMSwgbigpKSwgLmZ1biA9IHN1bSwgLmRlc2MgPSBUUlVFKSwNCiAgICAgICAgIHdyaXRlciA9IGZjdF9yZWxldmVsKHdyaXRlciwgIk90aGVyIiwgYWZ0ZXIgPSBJbmYpKQ0KDQpyYXRfYnlfd3JpdGVyIDwtIA0KICBlcGlfd3JpdF9pbWRiICU+JSANCiAgZ3JvdXBfYnkod3JpdGVyKSAlPiUgDQogIHN1bW1hcmlzZShhdmdfcmF0aW5nID0gbWVhbihyYXRpbmcsIG5hLnJtID0gVFJVRSkpDQoNCnJhdF9ieV93cml0ZXINCmBgYA0KDQpDcmVhdGluZyB0aGUgZGF0YWZyYW1lIHdpdGggdGhlIGJlc3QgYW5kIHdvcnN0IGVwaXNvZGUgYnkgZGlyZWN0b3INCmBgYHtyfQ0KYmVzdF9hbmRfd29yc3QgPC0gDQogIGVwaV93cml0X2ltZGIgJT4lIA0KICBmaWx0ZXIoY29tcGxldGUuY2FzZXMoLikpICU+JSANCiAgZ3JvdXBfYnkod3JpdGVyKSAlPiUgDQogIG11dGF0ZSh3b3JzdCA9IHJvd19udW1iZXIocmF0aW5nKSA9PSAxLA0KICAgICAgICAgYmVzdCA9IHJvd19udW1iZXIoZGVzYyhyYXRpbmcpKSA9PSAxKSAlPiUgDQogIGZpbHRlcihiZXN0IHwgd29yc3QpICU+JSANCiAgbXV0YXRlKHJhdGluZ19sYWJlbCA9IGlmZWxzZShiZXN0LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhdGluZyArIDAuMiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXRpbmcgLSAwLjIpKQ0KDQpiZXN0X2FuZF93b3JzdA0KYGBgDQoNClBsb3Qgb2YgZGlzdHJpYnV0aW9ucyBvZiBJTURCIHNjb3JlcyBieSBkaXJlY3RvcjoNCmBgYHtyfQ0KZGF0YV9wbG90IDwtIGVwaV93cml0X2ltZGIgJT4lIA0KICBzZWxlY3Qod3JpdGVyLCByYXRpbmcsIGVwaXNvZGVfdGl0bGUpICU+JSANCiAgYW50aV9qb2luKGJlc3RfYW5kX3dvcnN0LA0KICAgICAgICAgICAgYnkgPSBjKCJ3cml0ZXIiLCAicmF0aW5nIiwgImVwaXNvZGVfdGl0bGUiKSkNCg0KcGxvdF9iZXN0X3dvcnN0IDwtIA0KICBkYXRhX3Bsb3QgJT4lIA0KICBnZ3Bsb3QoYWVzKHdyaXRlciwgeSA9IHJhdGluZykpICsNCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNCwNCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcihzZWVkID0gMTk4OSksDQogICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiKSArDQogIGdlb21fbGFiZWwoZGF0YSA9IHJhdF9ieV93cml0ZXIsDQogICAgICAgICAgICAgYWVzKHdyaXRlciwgeSA9IGF2Z19yYXRpbmcsIGxhYmVsID0gcm91bmQoYXZnX3JhdGluZywgMSkpLA0KICAgICAgICAgICAgIGZpbGwgPSAiYmxhY2siLA0KICAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIiwNCiAgICAgICAgICAgICBzaXplID0gNS4yLA0KICAgICAgICAgICAgIGZhbWlseSA9ICJCYWhuc2NocmlmdCIsDQogICAgICAgICAgICAgbGFiZWwuciA9IHVuaXQoMCwgImxpbmVzIiksDQogICAgICAgICAgICAgbGFiZWwuc2l6ZSA9IDAuMSwNCiAgICAgICAgICAgICBsYWJlbC5wYWRkaW5nID0gdW5pdCgwLjMsICJsaW5lcyIpLA0KICAgICAgICAgICAgIGFscGhhID0gMC44KSArDQogIGdlb21fdGV4dChkYXRhID0gYmVzdF9hbmRfd29yc3QsDQogICAgICAgICAgICBmYW1pbHkgPSAiQmFobnNjaHJpZnQiLA0KICAgICAgICAgICAgYWVzKHkgPSByYXRpbmdfbGFiZWwsIGxhYmVsID0gc3RyX3dyYXAoZXBpc29kZV90aXRsZSwgMTUpKSwNCiAgICAgICAgICAgIHNpemUgPSAzLA0KICAgICAgICAgICAgdmp1c3QgPSBiZXN0X2FuZF93b3JzdCR3b3JzdCwNCiAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIikgKw0KICBnZW9tX3BvaW50KGRhdGEgPSBiZXN0X2FuZF93b3JzdCwNCiAgICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgZmFjZXRfd3JhcCh+d3JpdGVyLCBucm93ID0gMSwgc2NhbGVzID0gImZyZWVfeCIpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZShicmVha3MgPSBjKDAuNSwgMS41LCAyLjUpKSArDQogIHRoZW1lX21pbmltYWwoYmFzZV9mYW1pbHkgPSAiQmFobnNjaHJpZnQiKSArDQogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2xpbmUoKSwNCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBwbG90LmJhY2tncm91bmQgID0gZWxlbWVudF9yZWN0KGZpbGwgPSAnIzAxMDUwZScpLA0KICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoY29sb3IgPSAid2hpdGUiKSwNCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gIndoaXRlIiksDQogICAgICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3IgPSAid2hpdGUiKSwNCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3IgPSAid2hpdGUiKSwNCiAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KGNvbG9yID0gIiM2ZjhlYTkiKSkgKw0KICAgbGFicyh5ID0gIklNREIgUmF0aW5ncyIsDQogICAgICAgIGNhcHRpb24gPSAiQGZyYW5jaXNjb3lpcmFcbmdpdGh1Yi5jb20vZnJhbmNpc2NveWlyYVxuU291cmNlOiB7ZGF0YXJkaXN9IFIgcGFja2FnZSIpDQoNCnBsb3RfYmVzdF93b3JzdA0KYGBgDQoNClB1dHRpbmcgYm90aCBwbG90cyB0b2dldGhlciB3aXRoIHBhdGNod29yazoNCmBgYHtyfQ0KY29tYmluZWRfcGxvdCA8LSANCiAgKHBsb3Rfd2FmZmxlIC8gcGxvdF9iZXN0X3dvcnN0KQ0KDQpjb21iaW5lZF9wbG90IDwtIA0KICBjb21iaW5lZF9wbG90ICYNCiAgdGhlbWUocGxvdC5iYWNrZ3JvdW5kICA9IGVsZW1lbnRfcmVjdChmaWxsID0gJyMwMTA1MGUnLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gJyMwMTA1MGUnKSkNCmBgYA0KDQpgYGB7ciwgZmlnLmhlaWdodD01LjgsIGZpZy53aWR0aD03LjV9DQpjb21iaW5lZF9wbG90DQpgYGANCg0K