Motivations
Báo cáo CPI2018 khá đẹp nhưng vẫn còn và i thiếu sót như không nhất quán trong trình bà y, lúc thì thừa lúc thì thiếu và sỠdụng mà u sắc, legend không tốt. Chúng ta có thể cải tiến, và dụ, Bar Plot ở trang 26 của báo cáo nà y.
R Codes
# Reference: http://pci2018.pcivietnam.vn/uploads/2019/ho-so-63-tinh-vie.pdf
# Data Source: http://pci2018.pcivietnam.vn/
# cpi_colors <- c("#892890", "#034EA2", "#4792CF", "#8ED8F8", "#BAE1D1")
rm(list = ls())
library(viridis)
library(tidyverse)
library(readxl)
library(extrafont)
df_cpi <- read_excel("C:\\Users\\Zbook\\Downloads\\du-lieu-pci-2018.xlsx", sheet = 1) %>%
select(1:3) %>%
slice(1:63)
names(df_cpi) <- c("Province", "Rank", "Score")
df_cpi %>%
mutate(Province = case_when(str_detect(Province, "BRVT") ~ "Bà Rịa - Vũng Tà u", TRUE ~ Province)) %>%
mutate(fake_rank = case_when(Rank < 10 ~ paste0("0", Rank), TRUE ~ as.character(Rank))) %>%
mutate(Province = paste(Province, fake_rank)) %>%
mutate(my_colors = case_when(Rank <= 2 ~ "Excellent",
Rank >= 3 & Rank <= 9 ~ "Good",
Rank >= 10 & Rank <= 41 ~ "Fair",
Rank >= 42 & Rank <= 61 ~ "Mediocre",
TRUE ~ "Poor")) %>%
arrange(-Rank) %>%
mutate(Province = factor(Province, levels = Province)) %>%
mutate(my_colors = factor(my_colors, levels = my_colors %>% unique() %>% .[5:1])) %>%
mutate(label = round(Score, 2) %>% as.character()) %>%
mutate(label = case_when(str_count(label) == 2 ~ paste0(label, ".00"),
str_count(label) == 4 ~ paste0(label, "0"),
TRUE ~ label)) -> df_ploting2
#-------------
# Bar Plot
#-------------
my_font <- "Roboto Condensed"
df_ploting2 %>%
ggplot(aes(Province, Score, fill = my_colors)) +
geom_col(width = 0.85) +
coord_flip() +
scale_fill_viridis(discrete = TRUE, name = "", option = "D") +
geom_text(aes(label = label), size = 3, hjust = -0.1) +
scale_y_continuous(limits = c(0, 80), expand = c(0.001, 0)) +
theme_minimal() +
theme(panel.grid = element_blank()) +
theme(axis.text.x = element_blank()) +
theme(axis.text.y = element_text(size = 8, family = my_font, color = "black")) +
theme(plot.title = element_text(family = my_font, color = "grey20", size = 22, face = "bold")) +
theme(plot.subtitle = element_text(family = my_font, size = 13, color = "gray40")) +
theme(plot.caption = element_text(family = my_font, size = 11, colour = "grey40", face = "italic")) +
theme(legend.text = element_text(family = my_font, size = 10)) +
theme(plot.margin = unit(c(1, 1, 1, 2), "cm")) +
labs(x = NULL, y = NULL,
title = "Vietnam CPI Index 2018",
subtitle = "R Used for Data Visualization",
caption = "Data Source: http://pci2018.pcivietnam.vn") -> p1
#--------------
# Mapping
#--------------
# Get geospatial data for Viet Nam:
library(raster)
vietnam_province <- getData("GADM", country = "Vietnam", level = 1)
detach(package:raster)
vietnam_df <- vietnam_province %>% fortify(region = "NAME_1")
library(stringi)
vietnam_df %>%
mutate(id_prov = stri_trans_general(id, "Latin-ASCII")) %>%
mutate(id_prov = case_when(str_detect(id_prov, "Ba Ria") ~ "BRVT",
str_detect(id_prov, "Ho Chi Minh") ~ "TP.HCM",
str_detect(id_prov, "Thua Thien Hue") ~ "TT-Hue",
TRUE ~ id_prov)) -> vietnam_df
df_cpi %>%
mutate(id_prov = stri_trans_general(Province, "Latin-ASCII")) -> df_cpi
# Joint data sets:
df_cpi_mapping <- right_join(vietnam_df, df_cpi, by = "id_prov")
# Function creates new theme:
ggplot() +
geom_polygon(data = df_cpi_mapping, aes(long, lat, group = group, fill = Score), color = "white") +
coord_map("albers", lat0 = 30, lat1 = 40) +
labs(title = "Vietnam CPI Index 2018",
subtitle = "Vietnam's Paracel and Spratly Islands\nare not shown in this map.",
caption = "Data Source: http://pci2018.pcivietnam.vn") +
theme(axis.line = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank(),
axis.ticks = element_blank(),
axis.title.x = element_blank(),
axis.title.y = element_blank(),
panel.grid = element_blank(),
plot.background = element_rect(fill = "white", color = NA),
panel.background = element_rect(fill = "white", color = NA),
legend.background = element_rect(fill = "white", color = NA),
panel.border = element_blank()) +
theme(plot.title = element_text(family = my_font, color = "grey20", size = 22, face = "bold")) +
theme(plot.subtitle = element_text(family = my_font, size = 13, color = "gray40")) +
theme(plot.caption = element_text(family = my_font, size = 11, colour = "grey40", face = "italic")) +
theme(legend.text = element_text(family = my_font, color = "grey40", size = 12)) +
theme(legend.title = element_text(family = my_font, color = "grey20", size = 12)) +
theme(plot.margin = unit(c(1, 1, 1, 1), "cm")) +
# theme(legend.position = "top") +
theme(legend.position = c(0.3, 0.5)) +
scale_fill_viridis(direction = -1,
option = "D",
name = "CPI Index",
guide = guide_colourbar(direction = "horizontal",
barheight = unit(3, units = "mm"),
barwidth = unit(40, units = "mm"),
title.hjust = 0.5,
label.hjust = 0.5,
title.position = "top")) -> p2
gridExtra::grid.arrange(p2, p1, ncol = 2)

LS0tDQp0aXRsZTogIk1hcHBpbmcgVmlldG5hbSBQcm92aW5jaWFsIENvbXBldGl0aXZlbmVzcyBJbmRleCAyMDE4Ig0KYXV0aG9yOiAiTmd1eWVuIENoaSBEdW5nIg0Kc3VidGl0bGU6ICJEYWlseSBHcmFwaCBTZXJpZXMiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgaGlnaGxpZ2h0OiB6ZW5idXJuDQogICAgdGhlbWU6IGZsYXRseQ0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgd29yZF9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KLS0tDQoNCmBgYHtyIHNldHVwLGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFLCBmaWcucmV0aW5hPTIpDQpgYGANCg0KIyBNb3RpdmF0aW9ucw0KDQpCw6FvIGPDoW8gW0NQSTIwMThdKGh0dHA6Ly9wY2kyMDE4LnBjaXZpZXRuYW0udm4vdXBsb2Fkcy8yMDE5L2hvLXNvLTYzLXRpbmgtdmllLnBkZikga2jDoSDEkeG6uXAgbmjGsG5nIHbhuqtuIGPDsm4gdsOgaSB0aGnhur91IHPDs3QgbmjGsCBraMO0bmcgbmjhuqV0IHF1w6FuIHRyb25nIHRyw6xuaCBiw6B5LCBsw7pjIHRow6wgdGjhu6thIGzDumMgdGjDrCB0aGnhur91IHbDoCBz4butIGThu6VuZyBtw6B1IHPhuq9jLCBsZWdlbmQga2jDtG5nIHThu5F0LiBDaMO6bmcgdGEgY8OzIHRo4buDIGPhuqNpIHRp4bq/biwgdsOtIGThu6UsIEJhciBQbG90IOG7nyB0cmFuZyAyNiBj4bunYSBiw6FvIGPDoW8gbsOgeS4gDQoNCiMgUiBDb2Rlcw0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCg0KDQoNCiMgUmVmZXJlbmNlOiBodHRwOi8vcGNpMjAxOC5wY2l2aWV0bmFtLnZuL3VwbG9hZHMvMjAxOS9oby1zby02My10aW5oLXZpZS5wZGYNCiMgRGF0YSBTb3VyY2U6IGh0dHA6Ly9wY2kyMDE4LnBjaXZpZXRuYW0udm4vDQoNCg0KIyBjcGlfY29sb3JzIDwtIGMoIiM4OTI4OTAiLCAiIzAzNEVBMiIsICIjNDc5MkNGIiwgIiM4RUQ4RjgiLCAiI0JBRTFEMSIpDQoNCnJtKGxpc3QgPSBscygpKQ0KDQpsaWJyYXJ5KHZpcmlkaXMpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkocmVhZHhsKQ0KbGlicmFyeShleHRyYWZvbnQpDQoNCmRmX2NwaSA8LSByZWFkX2V4Y2VsKCJDOlxcVXNlcnNcXFpib29rXFxEb3dubG9hZHNcXGR1LWxpZXUtcGNpLTIwMTgueGxzeCIsIHNoZWV0ID0gMSkgJT4lIA0KICBzZWxlY3QoMTozKSAlPiUgDQogIHNsaWNlKDE6NjMpDQoNCm5hbWVzKGRmX2NwaSkgPC0gYygiUHJvdmluY2UiLCAiUmFuayIsICJTY29yZSIpDQoNCg0KDQpkZl9jcGkgJT4lIA0KICBtdXRhdGUoUHJvdmluY2UgPSBjYXNlX3doZW4oc3RyX2RldGVjdChQcm92aW5jZSwgIkJSVlQiKSB+ICJCw6AgUuG7i2EgLSBWxaluZyBUw6B1IiwgVFJVRSB+IFByb3ZpbmNlKSkgJT4lIA0KICBtdXRhdGUoZmFrZV9yYW5rID0gY2FzZV93aGVuKFJhbmsgPCAxMCB+IHBhc3RlMCgiMCIsIFJhbmspLCBUUlVFIH4gYXMuY2hhcmFjdGVyKFJhbmspKSkgJT4lIA0KICBtdXRhdGUoUHJvdmluY2UgPSBwYXN0ZShQcm92aW5jZSwgZmFrZV9yYW5rKSkgJT4lIA0KICBtdXRhdGUobXlfY29sb3JzID0gY2FzZV93aGVuKFJhbmsgPD0gMiB+ICJFeGNlbGxlbnQiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSYW5rID49IDMgJiBSYW5rIDw9IDkgfiAiR29vZCIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJhbmsgPj0gMTAgJiBSYW5rIDw9IDQxIH4gIkZhaXIiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSYW5rID49IDQyICYgUmFuayA8PSA2MSB+ICJNZWRpb2NyZSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiAiUG9vciIpKSAlPiUgDQogIGFycmFuZ2UoLVJhbmspICU+JSANCiAgbXV0YXRlKFByb3ZpbmNlID0gZmFjdG9yKFByb3ZpbmNlLCBsZXZlbHMgPSBQcm92aW5jZSkpICU+JSANCiAgbXV0YXRlKG15X2NvbG9ycyA9IGZhY3RvcihteV9jb2xvcnMsIGxldmVscyA9IG15X2NvbG9ycyAlPiUgdW5pcXVlKCkgJT4lIC5bNToxXSkpICU+JSANCiAgbXV0YXRlKGxhYmVsID0gcm91bmQoU2NvcmUsIDIpICU+JSBhcy5jaGFyYWN0ZXIoKSkgJT4lIA0KICBtdXRhdGUobGFiZWwgPSBjYXNlX3doZW4oc3RyX2NvdW50KGxhYmVsKSA9PSAyIH4gcGFzdGUwKGxhYmVsLCAiLjAwIiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyX2NvdW50KGxhYmVsKSA9PSA0IH4gcGFzdGUwKGxhYmVsLCAiMCIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiBsYWJlbCkpIC0+IGRmX3Bsb3RpbmcyDQoNCg0KIy0tLS0tLS0tLS0tLS0NCiMgIEJhciBQbG90IA0KIy0tLS0tLS0tLS0tLS0NCg0KDQpteV9mb250IDwtICJSb2JvdG8gQ29uZGVuc2VkIg0KDQpkZl9wbG90aW5nMiAlPiUgDQogIGdncGxvdChhZXMoUHJvdmluY2UsIFNjb3JlLCBmaWxsID0gbXlfY29sb3JzKSkgKyANCiAgZ2VvbV9jb2wod2lkdGggPSAwLjg1KSArIA0KICBjb29yZF9mbGlwKCkgKyANCiAgc2NhbGVfZmlsbF92aXJpZGlzKGRpc2NyZXRlID0gVFJVRSwgbmFtZSA9ICIiLCBvcHRpb24gPSAiRCIpICsgDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBsYWJlbCksIHNpemUgPSAzLCBoanVzdCA9IC0wLjEpICsgDQogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDgwKSwgZXhwYW5kID0gYygwLjAwMSwgMCkpICsNCiAgdGhlbWVfbWluaW1hbCgpICsgDQogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCkpICsgDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpKSArIA0KICB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgZmFtaWx5ID0gbXlfZm9udCwgY29sb3IgPSAiYmxhY2siKSkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9IG15X2ZvbnQsIGNvbG9yID0gImdyZXkyMCIsIHNpemUgPSAyMiwgZmFjZSA9ICJib2xkIikpICsgDQogIHRoZW1lKHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gbXlfZm9udCwgc2l6ZSA9IDEzLCBjb2xvciA9ICJncmF5NDAiKSkgKyANCiAgdGhlbWUocGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KGZhbWlseSA9IG15X2ZvbnQsIHNpemUgPSAxMSwgY29sb3VyID0gImdyZXk0MCIsIGZhY2UgPSAiaXRhbGljIikpICsgDQogIHRoZW1lKGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KGZhbWlseSA9IG15X2ZvbnQsIHNpemUgPSAxMCkpICsgDQogIHRoZW1lKHBsb3QubWFyZ2luID0gdW5pdChjKDEsIDEsIDEsIDIpLCAiY20iKSkgKw0KICBsYWJzKHggPSBOVUxMLCB5ID0gTlVMTCwgDQogICAgICAgdGl0bGUgPSAiVmlldG5hbSBDUEkgSW5kZXggMjAxOCIsIA0KICAgICAgIHN1YnRpdGxlID0gIlIgVXNlZCBmb3IgRGF0YSBWaXN1YWxpemF0aW9uIiwgDQogICAgICAgY2FwdGlvbiA9ICJEYXRhIFNvdXJjZTogaHR0cDovL3BjaTIwMTgucGNpdmlldG5hbS52biIpIC0+IHAxDQoNCiMtLS0tLS0tLS0tLS0tLQ0KIyAgTWFwcGluZw0KIy0tLS0tLS0tLS0tLS0tDQoNCg0KIyBHZXQgZ2Vvc3BhdGlhbCBkYXRhIGZvciBWaWV0IE5hbTogDQoNCmxpYnJhcnkocmFzdGVyKQ0KdmlldG5hbV9wcm92aW5jZSA8LSBnZXREYXRhKCJHQURNIiwgY291bnRyeSA9ICJWaWV0bmFtIiwgbGV2ZWwgPSAxKQ0KDQpkZXRhY2gocGFja2FnZTpyYXN0ZXIpDQp2aWV0bmFtX2RmIDwtIHZpZXRuYW1fcHJvdmluY2UgJT4lIGZvcnRpZnkocmVnaW9uID0gIk5BTUVfMSIpDQoNCg0KbGlicmFyeShzdHJpbmdpKQ0KDQp2aWV0bmFtX2RmICU+JSANCiAgbXV0YXRlKGlkX3Byb3YgPSBzdHJpX3RyYW5zX2dlbmVyYWwoaWQsICJMYXRpbi1BU0NJSSIpKSAlPiUgDQogIG11dGF0ZShpZF9wcm92ID0gY2FzZV93aGVuKHN0cl9kZXRlY3QoaWRfcHJvdiwgIkJhIFJpYSIpIH4gIkJSVlQiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyX2RldGVjdChpZF9wcm92LCAiSG8gQ2hpIE1pbmgiKSB+ICJUUC5IQ00iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyX2RldGVjdChpZF9wcm92LCAiVGh1YSBUaGllbiBIdWUiKSB+ICJUVC1IdWUiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+IGlkX3Byb3YpKSAtPiB2aWV0bmFtX2RmDQoNCmRmX2NwaSAlPiUgDQogIG11dGF0ZShpZF9wcm92ID0gc3RyaV90cmFuc19nZW5lcmFsKFByb3ZpbmNlLCAiTGF0aW4tQVNDSUkiKSkgLT4gZGZfY3BpDQoNCg0KIyBKb2ludCBkYXRhIHNldHM6IA0KDQpkZl9jcGlfbWFwcGluZyA8LSByaWdodF9qb2luKHZpZXRuYW1fZGYsIGRmX2NwaSwgYnkgPSAiaWRfcHJvdiIpDQoNCiMgRnVuY3Rpb24gY3JlYXRlcyBuZXcgdGhlbWU6IA0KDQoNCg0KZ2dwbG90KCkgKyANCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSBkZl9jcGlfbWFwcGluZywgYWVzKGxvbmcsIGxhdCwgZ3JvdXAgPSBncm91cCwgZmlsbCA9IFNjb3JlKSwgY29sb3IgPSAid2hpdGUiKSArDQogIGNvb3JkX21hcCgiYWxiZXJzIiwgbGF0MCA9IDMwLCBsYXQxID0gNDApICsgDQogIGxhYnModGl0bGUgPSAiVmlldG5hbSBDUEkgSW5kZXggMjAxOCIsDQogICAgICAgc3VidGl0bGUgPSAiVmlldG5hbSdzIFBhcmFjZWwgYW5kIFNwcmF0bHkgSXNsYW5kc1xuYXJlIG5vdCBzaG93biBpbiB0aGlzIG1hcC4iLA0KICAgICAgIGNhcHRpb24gPSAiRGF0YSBTb3VyY2U6IGh0dHA6Ly9wY2kyMDE4LnBjaXZpZXRuYW0udm4iKSArIA0KICB0aGVtZShheGlzLmxpbmUgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIiwgY29sb3IgPSBOQSksDQogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIsIGNvbG9yID0gTkEpLA0KICAgICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIiwgY29sb3IgPSBOQSksDQogICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9IG15X2ZvbnQsIGNvbG9yID0gImdyZXkyMCIsIHNpemUgPSAyMiwgZmFjZSA9ICJib2xkIikpICsgDQogIHRoZW1lKHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gbXlfZm9udCwgc2l6ZSA9IDEzLCBjb2xvciA9ICJncmF5NDAiKSkgKyANCiAgdGhlbWUocGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KGZhbWlseSA9IG15X2ZvbnQsIHNpemUgPSAxMSwgY29sb3VyID0gImdyZXk0MCIsIGZhY2UgPSAiaXRhbGljIikpICsgDQogIHRoZW1lKGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KGZhbWlseSA9IG15X2ZvbnQsIGNvbG9yID0gImdyZXk0MCIsIHNpemUgPSAxMikpICsgDQogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSBteV9mb250LCBjb2xvciA9ICJncmV5MjAiLCBzaXplID0gMTIpKSArIA0KICB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygxLCAxLCAxLCAxKSwgImNtIikpICsgDQogICMgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC4zLCAwLjUpKSArIA0KICBzY2FsZV9maWxsX3ZpcmlkaXMoZGlyZWN0aW9uID0gLTEsIA0KICAgICAgICAgICAgICAgICAgICAgb3B0aW9uID0gIkQiLCANCiAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiQ1BJIEluZGV4IiwgDQogICAgICAgICAgICAgICAgICAgICBndWlkZSA9IGd1aWRlX2NvbG91cmJhcihkaXJlY3Rpb24gPSAiaG9yaXpvbnRhbCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXJoZWlnaHQgPSB1bml0KDMsIHVuaXRzID0gIm1tIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXJ3aWR0aCA9IHVuaXQoNDAsIHVuaXRzID0gIm1tIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZS5oanVzdCA9IDAuNSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsLmhqdXN0ID0gMC41LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlLnBvc2l0aW9uID0gInRvcCIpKSAtPiBwMg0KDQoNCmdyaWRFeHRyYTo6Z3JpZC5hcnJhbmdlKHAyLCBwMSwgbmNvbCA9IDIpDQpgYGANCg0KDQohW10oQzpcXFVzZXJzXFxaYm9va1xcRGVza3RvcFxccGljXFxtYXBfY3BpLmpwZyk=