TidyTuesday Project (210810)
This notebook is about Measuring Infrastructure in the Bureau of Economic Analytics National Economic Accounts.
Introduction
Infrastructure provides critical support for economic activity. Hence it contributes in a significant way to our living standards. This notebook will analyze the trends of infrastructure investment through the years (decades) using the measurements of infrastructure data in the U.S. National Economic Accounts(NEAs).
For this notebook, I will use the chain_investment.csv dataset. I think that using the chained dollars(*) will give us better insights about how important the investment was in that year(decade) comparing it with nowadays infrastructure investments.
- Chained dollars: Chained dollars is a method of adjusting real dollar amounts for inflation over time, to allow the comparison of figures from different years. The U.S. Department of Commerce introduced the chained-dollar measure in 1996.
Why is it important?
This study is a challenge that will provide a huge value in understanding the nature of the surrounding infrastructure and its behavior as a connected multi-network.
A glance to the data
Following the Bureau of Economic Analysis paper, there are three main categories of infrastructure: basic, social and digital.
Basic infrastructure: Mainly determined by trends in transportation and power. Water, sewer, and conservation and development (dams, levees, sea walls, and related assets) make up a relatively small share of basic infrastructure.
Social infrastructure: Determined by trends in health, education, and public safety. For social infrastructure, the share of privately owned net stock grew over time while the share of state.
Digital infrastructure: Communications, software…etc.
That being said, let’s start working with those three main categories from the chain_investment.csv.
df_main_cat = chinvestment %>%
filter(group_num == 1) %>%
mutate(
label = case_when(
category == "Total basic infrastructure"~"Basic",
category == "Total digital infrastructure"~"Digital",
category == "Total social infrastructure"~"Social"
),
colorL = case_when(
category == "Total basic infrastructure"~"#ef476f",
category == "Total digital infrastructure"~"#ffd166",
category == "Total social infrastructure"~"#06d6a0"
)
)
chart_lines <- df_main_cat %>%
ggplot(aes(x=year, y=gross_inv_chain)) +
geom_line(aes(color=category))+
geom_point(aes(color=category))+
guides(fill=FALSE, color=FALSE)+
theme_minimal()+
scale_color_manual(breaks=df_main_cat$category,values=df_main_cat$colorL)+
ylab("Total $ in Infrastructure Investment") +
theme(legend.position="none", legend.title=element_blank())
chart_area <- df_main_cat %>%
ggplot(aes(x=year, y=gross_inv_chain, fill=category)) +
geom_area()+
scale_fill_manual(breaks=df_main_cat$category,values=df_main_cat$colorL)+
scale_color_manual(breaks=df_main_cat$category,values=df_main_cat$colorL)+
ylab("Infrastructure Investment ($) per category") +
guides(fill=FALSE, color=FALSE)+
theme_minimal()+
theme(legend.position="none", legend.title=element_blank())+
annotate(geom = "segment", x=1947,xend=2017, y=600000,yend=600000, color="#343a40")+
annotate(geom = "segment", x=1947,xend=2017, y=300000,yend=300000, color="#343a40")+
annotate(geom = "text", x=1947, y=630000, label="600 billions $", color="#343a40",
hjust=0, size=6,family=fontfamily)+
annotate(geom = "text", x=1947, y=330000, label="300 billions $", color="#343a40",
hjust=0, size=6,family=fontfamily)

ggarrange(chart_area, chart_lines, ncol = 2, heights = c(10, 10), align = "v")

Infrastructure Investment Breakdown (sankey)
We already know how the money is invested in the three main categories (basic, social and digital) so let’s break it down in order to see how much money is invested in each subcategory.
In order to do that, Sankey (*) charts are a viable option.
Following the Google Charts definition, a sankey diagram is a visualization used to depict a flow from one set of values to another. The things being connected are called nodes and the connections are called links. Sankeys are best used when you want to show a many-to-many mapping between two domains.
Splitting the dataset in different levels will be necessary for generating the Sankey chart (spoiler alert: There are three different levels regarding the investments). In order to do that:
Level 1: We will start analyzing from the meta_cat to the category when category is one of the three main categories: Basic, Social or Digital. That’s because Total infrastructure will be our root node.
From Level 2 to Level 3: We will use meta_cat using the categories from the previous level in order to get the new nodes and so on and so forth.
options(dplyr.summarise.inform = FALSE)
# Remember: We need to remove the fund sources
dfch_grp <- chinvestment %>%
group_by(category, meta_cat, group_num) %>%
filter(!(category %in% c("Federal", "S&L", "Private")) &(group_num!=14)) %>%
summarise(inv = sum(gross_inv_chain))
dfch_grp <- dfch_grp %>%
mutate(
category = case_when(
category == "Total basic infrastructure"~"Basic",
category == "Total digital infrastructure"~"Digital",
category == "Total social infrastructure"~"Social",
TRUE ~category
), meta_cat =case_when(
meta_cat == "Total basic infrastructure"~"Basic",
TRUE ~meta_cat
)
)
# dfch_grp$category <- as.factor(dfch_grp$category)
# dfch_grp$meta_cat <- as.factor(dfch_grp$meta_cat)
# Level 1: Total infrastructure => Total basic/social/digital infrastructure
lvl1 <- dfch_grp %>%
filter(meta_cat %in% "Total infrastructure")
lvl2 <- dfch_grp %>% filter(meta_cat %in% c(
"Basic",
"Digital",
"Social"
))
lvl3 <- dfch_grp %>% filter(meta_cat %in% lvl2$category)
labelsV <- c(unique(lvl1$meta_cat), unique(lvl2$meta_cat), unique(lvl2$category),unique(lvl3$category))
sourceV <-c(match(lvl1$meta_cat, labels), match(lvl2$meta_cat,labels), match(lvl3$meta_cat,labels))
targetV <- c(match(lvl1$category, labels), match(lvl2$category,labels), match(lvl3$category,labels))
valueV <- c(lvl1$inv, lvl2$inv, lvl3$inv)
# lvl1
# lvl2
# lvl3
LS0tDQp0aXRsZTogIkJFQSBJbmZyYXN0cnVjdHVyZSBJbnZlc3RtZW50Ig0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KDQoqKlRpZHlUdWVzZGF5IFByb2plY3QgKDIxMDgxMCkqKg0KDQotLS0tLS0NCg0KPiAgLSDwn5OxIExpbmtlZGluIFtKdWFuIEFudG9uaW8gQ2FiZXphIFNvdXNhDQpdKGh0dHBzOi8vd3d3LmxpbmtlZGluLmNvbS9pbi9qdWFuLWFudG9uaW8tY2FiZXphLXNvdXNhLTViOTU0OTY4LykNCj4gIC0g8J+TrCBFbWFpbDogIGp1YWFuY2Fic291QGdtYWlsLmNvbQ0KPiAgLSDwn5al77iPIFR3aXR0ZXI6IEBbQWNlY29uaGllbG9dKGh0dHBzOi8vdHdpdHRlci5jb20vQWNlY29uaGllbG8pDQoNCg0KVGhpcyBub3RlYm9vayBpcyBhYm91dCAqTWVhc3VyaW5nIEluZnJhc3RydWN0dXJlIGluIHRoZSBCdXJlYXUgb2YgRWNvbm9taWMgQW5hbHl0aWNzIE5hdGlvbmFsIEVjb25vbWljIEFjY291bnRzKi4NCg0KIyBJbnRyb2R1Y3Rpb24NCkluZnJhc3RydWN0dXJlIHByb3ZpZGVzIGNyaXRpY2FsIHN1cHBvcnQgZm9yIGVjb25vbWljIGFjdGl2aXR5LiBIZW5jZSBpdCBjb250cmlidXRlcyBpbiBhIHNpZ25pZmljYW50IHdheSB0byBvdXIgbGl2aW5nIHN0YW5kYXJkcy4gVGhpcyBub3RlYm9vayB3aWxsIGFuYWx5emUgdGhlIHRyZW5kcyBvZiBpbmZyYXN0cnVjdHVyZSBpbnZlc3RtZW50IHRocm91Z2ggdGhlIHllYXJzIChkZWNhZGVzKSB1c2luZyB0aGUgbWVhc3VyZW1lbnRzIG9mIGluZnJhc3RydWN0dXJlIGRhdGEgaW4gdGhlIFUuUy4gTmF0aW9uYWwgRWNvbm9taWMgQWNjb3VudHMoTkVBcykuDQoNCkZvciB0aGlzIG5vdGVib29rLCBJIHdpbGwgdXNlIHRoZSBjaGFpbl9pbnZlc3RtZW50LmNzdiBkYXRhc2V0LiBJIHRoaW5rIHRoYXQgdXNpbmcgdGhlIGNoYWluZWQgZG9sbGFycygqKSB3aWxsIGdpdmUgdXMgYmV0dGVyIGluc2lnaHRzIGFib3V0IGhvdyBpbXBvcnRhbnQgdGhlIGludmVzdG1lbnQgd2FzIGluIHRoYXQgeWVhcihkZWNhZGUpIGNvbXBhcmluZyBpdCB3aXRoIG5vd2FkYXlzIGluZnJhc3RydWN0dXJlIGludmVzdG1lbnRzLg0KDQoqICpDaGFpbmVkIGRvbGxhcnM6IENoYWluZWQgZG9sbGFycyBpcyBhIG1ldGhvZCBvZiBhZGp1c3RpbmcgcmVhbCBkb2xsYXIgYW1vdW50cyBmb3IgaW5mbGF0aW9uIG92ZXIgdGltZSwgdG8gYWxsb3cgdGhlIGNvbXBhcmlzb24gb2YgZmlndXJlcyBmcm9tIGRpZmZlcmVudCB5ZWFycy4gVGhlIFUuUy4gRGVwYXJ0bWVudCBvZiBDb21tZXJjZSBpbnRyb2R1Y2VkIHRoZSBjaGFpbmVkLWRvbGxhciBtZWFzdXJlIGluIDE5OTYqLg0KDQoqKldoeSBpcyBpdCBpbXBvcnRhbnQ/KioNCg0KVGhpcyBzdHVkeSBpcyBhIGNoYWxsZW5nZSB0aGF0IHdpbGwgcHJvdmlkZSBhIGh1Z2UgdmFsdWUgaW4gdW5kZXJzdGFuZGluZyB0aGUgbmF0dXJlIG9mIHRoZSBzdXJyb3VuZGluZyBpbmZyYXN0cnVjdHVyZSBhbmQgaXRzIGJlaGF2aW9yIGFzIGEgY29ubmVjdGVkIG11bHRpLW5ldHdvcmsuDQoNCg0KDQpgYGB7ciBMaWJyYXJpZXMsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSwgd2Fybi5jb25mbGljdHMgPSBGQUxTRSkNCmxpYnJhcnkoZ2dhbmltYXRlKQ0KbGlicmFyeShocmJydGhlbWVzKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShnZ3B1YnIpDQpsaWJyYXJ5KHBsb3RseSkNCmZvbnRmYW1pbHkgPC0iT3BlbiBTYW5zIg0KDQpgYGANCg0KDQpgYGB7ciBEb3dubG9hZCB0aGUgZGF0YSwgbWVzc2FnZT1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCnR1ZXNkYXRhIDwtIHRpZHl0dWVzZGF5Ujo6dHRfbG9hZCgnMjAyMS0wOC0xMCcpDQp0dWVzZGF0YSA8LSB0aWR5dHVlc2RheVI6OnR0X2xvYWQoMjAyMSwgd2VlayA9IDMzKQ0KDQpjaGludmVzdG1lbnQgPC0gdHVlc2RhdGEkY2hhaW5faW52ZXN0bWVudA0KDQpgYGANCg0KDQojIEEgZ2xhbmNlIHRvIHRoZSBkYXRhDQpGb2xsb3dpbmcgdGhlIFtCdXJlYXUgb2YgRWNvbm9taWMgQW5hbHlzaXMgcGFwZXJdKGh0dHBzOi8vd3d3LmJlYS5nb3Yvc3lzdGVtL2ZpbGVzL3BhcGVycy9CRUEtV1AyMDIwLTEyLnBkZiksICoqdGhlcmUgYXJlIHRocmVlIG1haW4gY2F0ZWdvcmllcyBvZiBpbmZyYXN0cnVjdHVyZTogYmFzaWMsIHNvY2lhbCBhbmQgZGlnaXRhbCoqLiANCg0KKiAqKkJhc2ljIGluZnJhc3RydWN0dXJlKio6IE1haW5seSBkZXRlcm1pbmVkIGJ5IHRyZW5kcyBpbiB0cmFuc3BvcnRhdGlvbiBhbmQgcG93ZXIuIFdhdGVyLCBzZXdlciwgYW5kIGNvbnNlcnZhdGlvbiBhbmQgZGV2ZWxvcG1lbnQgKGRhbXMsIGxldmVlcywgc2VhIHdhbGxzLCBhbmQgcmVsYXRlZCBhc3NldHMpIG1ha2UgdXAgYSByZWxhdGl2ZWx5IHNtYWxsIHNoYXJlIG9mIGJhc2ljIGluZnJhc3RydWN0dXJlLg0KDQoqICoqU29jaWFsIGluZnJhc3RydWN0dXJlKio6IERldGVybWluZWQgYnkgdHJlbmRzIGluIGhlYWx0aCwgZWR1Y2F0aW9uLCBhbmQgcHVibGljIHNhZmV0eS4gRm9yIHNvY2lhbCBpbmZyYXN0cnVjdHVyZSwgdGhlIHNoYXJlIG9mIHByaXZhdGVseSBvd25lZCBuZXQgc3RvY2sgZ3JldyBvdmVyIHRpbWUgd2hpbGUgdGhlIHNoYXJlIG9mIHN0YXRlLg0KDQoqICoqRGlnaXRhbCBpbmZyYXN0cnVjdHVyZSoqOiBDb21tdW5pY2F0aW9ucywgc29mdHdhcmUuLi5ldGMuDQpgYGB7ciBHbGFuY2luZyB0aGUgZGF0YSwgZWNobz1GQUxTRX0NCmhlYWQoY2hpbnZlc3RtZW50KQ0KDQpgYGANCg0KVGhhdCBiZWluZyBzYWlkLCBsZXQncyBzdGFydCB3b3JraW5nIHdpdGggdGhvc2UgdGhyZWUgbWFpbiBjYXRlZ29yaWVzIGZyb20gdGhlIGBjaGFpbl9pbnZlc3RtZW50LmNzdmAuIA0KDQpgYGB7ciBNYWluQ2F0IC0gRGF0YSBXcmFuZ2xpbmcgSSB9DQpkZl9tYWluX2NhdCA9IGNoaW52ZXN0bWVudCAlPiUNCiAgZmlsdGVyKGdyb3VwX251bSA9PSAxKSAlPiUNCiAgbXV0YXRlKA0KICAgIGxhYmVsID0gY2FzZV93aGVuKA0KICAgICAgY2F0ZWdvcnkgPT0gIlRvdGFsIGJhc2ljIGluZnJhc3RydWN0dXJlIn4iQmFzaWMiLA0KICAgICAgY2F0ZWdvcnkgPT0gIlRvdGFsIGRpZ2l0YWwgaW5mcmFzdHJ1Y3R1cmUifiJEaWdpdGFsIiwNCiAgICAgIGNhdGVnb3J5ID09ICJUb3RhbCBzb2NpYWwgaW5mcmFzdHJ1Y3R1cmUifiJTb2NpYWwiDQogICAgKSwNCiAgICAgIGNvbG9yTCA9IGNhc2Vfd2hlbigNCiAgICAgIGNhdGVnb3J5ID09ICJUb3RhbCBiYXNpYyBpbmZyYXN0cnVjdHVyZSJ+IiNlZjQ3NmYiLA0KICAgICAgY2F0ZWdvcnkgPT0gIlRvdGFsIGRpZ2l0YWwgaW5mcmFzdHJ1Y3R1cmUifiIjZmZkMTY2IiwNCiAgICAgIGNhdGVnb3J5ID09ICJUb3RhbCBzb2NpYWwgaW5mcmFzdHJ1Y3R1cmUifiIjMDZkNmEwIg0KICAgICkNCiAgKQ0KDQoNCmBgYA0KDQoNCg0KDQoNCmBgYHtyIE1haW5DYXQgLSBEYXRhIFBsb3QgSSwgbWVzc2FnZT1GQUxTRSwgaW5jbHVkZT1GQUxTRSwgcmVzdWx0cz1GQUxTRSwgZmlnLndpZHRoID0gMTIsIGZpZy5oZWlnaHQgPSA1fQ0KIyBQbG90DQpjaGFydF90aSA8LSBkZl9tYWluX2NhdCAlPiUNCiAgZ2dwbG90KGFlcyh4PXllYXIsIHk9Z3Jvc3NfaW52X2NoYWluLCBmaWxsPWNhdGVnb3J5KSkgKw0KICBnZW9tX2FyZWEoKSsNCiAgZ2d0aXRsZSgiQmFzaWMgSW5mcmFzdHJ1Y3R1cmVzIEludmVzdG1lbnRzICgkKSIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwoYnJlYWtzPWRmX21haW5fY2F0JGNhdGVnb3J5LHZhbHVlcz1kZl9tYWluX2NhdCRjb2xvckwpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwoYnJlYWtzPWRmX21haW5fY2F0JGNhdGVnb3J5LHZhbHVlcz1kZl9tYWluX2NhdCRjb2xvckwpKw0KICB5bGFiKCJUb3RhbCAkIGluIEluZnJhc3RydWN0dXJlIEludmVzdG1lbnQiKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIiwgbGVnZW5kLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSkrDQogIGFubm90YXRlKGdlb20gPSAic2VnbWVudCIsIHg9MTk0Nyx4ZW5kPTIwMTcsIHk9NjAwMDAwLHllbmQ9NjAwMDAwLCBjb2xvcj0iIzM0M2E0MCIpKw0KICBhbm5vdGF0ZShnZW9tID0gInNlZ21lbnQiLCB4PTE5NDcseGVuZD0yMDE3LCB5PTMwMDAwMCx5ZW5kPTMwMDAwMCwgY29sb3I9IiMzNDNhNDAiKSsNCiAgYW5ub3RhdGUoZ2VvbSA9ICJ0ZXh0IiwgeD0xOTQ3LCB5PTYzMDAwMCwgbGFiZWw9IjYwMCBiaWxsaW9ucyAkIiwgY29sb3I9IiMzNDNhNDAiLA0KICAgICAgICAgICAgaGp1c3Q9MCwgc2l6ZT02LGZhbWlseT1mb250ZmFtaWx5KSsNCiAgYW5ub3RhdGUoZ2VvbSA9ICJ0ZXh0IiwgeD0xOTQ3LCB5PTMzMDAwMCwgbGFiZWw9IjMwMCBiaWxsaW9ucyAkIiwgY29sb3I9IiMzNDNhNDAiLA0KICAgICAgICAgICAgaGp1c3Q9MCwgc2l6ZT02LGZhbWlseT1mb250ZmFtaWx5KSsNCiAgdHJhbnNpdGlvbl9yZXZlYWwoeWVhcikNCg0KYW5pbWF0ZShjaGFydF90aSwgaGVpZ2h0ID0gNTAwLCB3aWR0aCA9OTAwKQ0KYW5pbV9zYXZlKCJjaGFydF90aS5naWYiKQ0KDQpgYGANCg0KDQoNCg0KDQpgYGB7ciBtZXNzYWdlPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gNX0NCmNoYXJ0X2xpbmVzIDwtIGRmX21haW5fY2F0ICU+JQ0KICBnZ3Bsb3QoYWVzKHg9eWVhciwgeT1ncm9zc19pbnZfY2hhaW4pKSArDQogIGdlb21fbGluZShhZXMoY29sb3I9Y2F0ZWdvcnkpKSsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9Y2F0ZWdvcnkpKSsNCiAgZ3VpZGVzKGZpbGw9RkFMU0UsIGNvbG9yPUZBTFNFKSsNCiAgdGhlbWVfbWluaW1hbCgpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwoYnJlYWtzPWRmX21haW5fY2F0JGNhdGVnb3J5LHZhbHVlcz1kZl9tYWluX2NhdCRjb2xvckwpKw0KICB5bGFiKCJUb3RhbCAkIGluIEluZnJhc3RydWN0dXJlIEludmVzdG1lbnQiKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIsIGxlZ2VuZC50aXRsZT1lbGVtZW50X2JsYW5rKCkpDQoNCg0KY2hhcnRfYXJlYSA8LSBkZl9tYWluX2NhdCAlPiUNCiAgZ2dwbG90KGFlcyh4PXllYXIsIHk9Z3Jvc3NfaW52X2NoYWluLCBmaWxsPWNhdGVnb3J5KSkgKw0KICBnZW9tX2FyZWEoKSsNCiAgc2NhbGVfZmlsbF9tYW51YWwoYnJlYWtzPWRmX21haW5fY2F0JGNhdGVnb3J5LHZhbHVlcz1kZl9tYWluX2NhdCRjb2xvckwpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwoYnJlYWtzPWRmX21haW5fY2F0JGNhdGVnb3J5LHZhbHVlcz1kZl9tYWluX2NhdCRjb2xvckwpKw0KICB5bGFiKCJJbmZyYXN0cnVjdHVyZSBJbnZlc3RtZW50ICgkKSBwZXIgY2F0ZWdvcnkiKSArDQogIGd1aWRlcyhmaWxsPUZBTFNFLCBjb2xvcj1GQUxTRSkrDQogIHRoZW1lX21pbmltYWwoKSsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIiwgbGVnZW5kLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSkrDQogIGFubm90YXRlKGdlb20gPSAic2VnbWVudCIsIHg9MTk0Nyx4ZW5kPTIwMTcsIHk9NjAwMDAwLHllbmQ9NjAwMDAwLCBjb2xvcj0iIzM0M2E0MCIpKw0KICBhbm5vdGF0ZShnZW9tID0gInNlZ21lbnQiLCB4PTE5NDcseGVuZD0yMDE3LCB5PTMwMDAwMCx5ZW5kPTMwMDAwMCwgY29sb3I9IiMzNDNhNDAiKSsNCiAgYW5ub3RhdGUoZ2VvbSA9ICJ0ZXh0IiwgeD0xOTQ3LCB5PTYzMDAwMCwgbGFiZWw9IjYwMCBiaWxsaW9ucyAkIiwgY29sb3I9IiMzNDNhNDAiLA0KICAgICAgICAgICAgaGp1c3Q9MCwgc2l6ZT02LGZhbWlseT1mb250ZmFtaWx5KSsNCiAgYW5ub3RhdGUoZ2VvbSA9ICJ0ZXh0IiwgeD0xOTQ3LCB5PTMzMDAwMCwgbGFiZWw9IjMwMCBiaWxsaW9ucyAkIiwgY29sb3I9IiMzNDNhNDAiLA0KICAgICAgICAgICAgaGp1c3Q9MCwgc2l6ZT02LGZhbWlseT1mb250ZmFtaWx5KQ0KICANCiAgDQpgYGANCiMgIVtdKGNoYXJ0X3RpLmdpZikNCg0KYGBge3IgbWVzc2FnZT1UUlVFLCB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGggPSAxMiwgZmlnLmhlaWdodCA9IDV9DQpnZ2FycmFuZ2UoY2hhcnRfYXJlYSwgY2hhcnRfbGluZXMsIG5jb2wgPSAyLCBoZWlnaHRzID0gYygxMCwgMTApLCBhbGlnbiA9ICJ2IikNCmBgYA0KDQoNCiMgSW5mcmFzdHJ1Y3R1cmUgSW52ZXN0bWVudCBCcmVha2Rvd24gKHNhbmtleSkNCg0KV2UgYWxyZWFkeSBrbm93IGhvdyB0aGUgbW9uZXkgaXMgaW52ZXN0ZWQgaW4gdGhlIHRocmVlIG1haW4gY2F0ZWdvcmllcyAoYmFzaWMsIHNvY2lhbCBhbmQgZGlnaXRhbCkgc28gbGV0J3MgYnJlYWsgaXQgZG93biBpbiBvcmRlciB0byBzZWUgaG93IG11Y2ggbW9uZXkgaXMgaW52ZXN0ZWQgaW4gZWFjaCBzdWJjYXRlZ29yeS4gDQoNCkluIG9yZGVyIHRvIGRvIHRoYXQsIFNhbmtleSAoKikgY2hhcnRzIGFyZSBhIHZpYWJsZSBvcHRpb24uDQoNCkZvbGxvd2luZyB0aGUgR29vZ2xlIENoYXJ0cyBkZWZpbml0aW9uLCAqYSBzYW5rZXkgZGlhZ3JhbSBpcyBhIHZpc3VhbGl6YXRpb24gdXNlZCB0byBkZXBpY3QgYSBmbG93IGZyb20gb25lIHNldCBvZiB2YWx1ZXMgdG8gYW5vdGhlci4gVGhlIHRoaW5ncyBiZWluZyBjb25uZWN0ZWQgYXJlIGNhbGxlZCBub2RlcyBhbmQgdGhlIGNvbm5lY3Rpb25zIGFyZSBjYWxsZWQgbGlua3MuIFNhbmtleXMgYXJlIGJlc3QgdXNlZCB3aGVuIHlvdSB3YW50IHRvIHNob3cgYSBtYW55LXRvLW1hbnkgbWFwcGluZyBiZXR3ZWVuIHR3byBkb21haW5zLioNCg0KU3BsaXR0aW5nIHRoZSBkYXRhc2V0IGluIGRpZmZlcmVudCBsZXZlbHMgd2lsbCBiZSBuZWNlc3NhcnkgZm9yIGdlbmVyYXRpbmcgdGhlIFNhbmtleSBjaGFydCAoc3BvaWxlciBhbGVydDogVGhlcmUgYXJlIHRocmVlIGRpZmZlcmVudCBsZXZlbHMgcmVnYXJkaW5nIHRoZSBpbnZlc3RtZW50cykuIEluIG9yZGVyIHRvIGRvIHRoYXQ6DQoNCiogKipMZXZlbCAxOioqIFdlIHdpbGwgc3RhcnQgYW5hbHl6aW5nIGZyb20gdGhlIGBtZXRhX2NhdGAgdG8gdGhlIGBjYXRlZ29yeWAgd2hlbiBjYXRlZ29yeSBpcyBvbmUgb2YgdGhlIHRocmVlIG1haW4gY2F0ZWdvcmllczogQmFzaWMsIFNvY2lhbCBvciBEaWdpdGFsLiBUaGF0J3MgYmVjYXVzZSBgVG90YWwgaW5mcmFzdHJ1Y3R1cmVgIHdpbGwgYmUgb3VyIHJvb3Qgbm9kZS4NCg0KKiAqKkZyb20gTGV2ZWwgMiB0byBMZXZlbCAzOioqIFdlIHdpbGwgdXNlIGBtZXRhX2NhdGAgdXNpbmcgdGhlIGNhdGVnb3JpZXMgZnJvbSB0aGUgcHJldmlvdXMgbGV2ZWwgaW4gb3JkZXIgdG8gZ2V0IHRoZSBuZXcgbm9kZXMgYW5kIHNvIG9uIGFuZCAgc28gZm9ydGguDQoNCmBgYHtyIEludkJyZWFrZG93biAtIERhdGEgV3JhbmdsaW5nIEksIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpvcHRpb25zKGRwbHlyLnN1bW1hcmlzZS5pbmZvcm0gPSBGQUxTRSkNCg0KIyBSZW1lbWJlcjogV2UgbmVlZCB0byByZW1vdmUgdGhlIGZ1bmQgc291cmNlcw0KZGZjaF9ncnAgPC0gY2hpbnZlc3RtZW50ICU+JSANCiAgZ3JvdXBfYnkoY2F0ZWdvcnksIG1ldGFfY2F0LCBncm91cF9udW0pICU+JQ0KICBmaWx0ZXIoIShjYXRlZ29yeSAlaW4lIGMoIkZlZGVyYWwiLCAiUyZMIiwgIlByaXZhdGUiKSkgJihncm91cF9udW0hPTE0KSkgICAlPiUNCiAgc3VtbWFyaXNlKGludiA9IHN1bShncm9zc19pbnZfY2hhaW4pKQ0KDQpkZmNoX2dycCA8LSBkZmNoX2dycCAlPiUNCiAgICAgIG11dGF0ZSgNCiAgICAgICAgY2F0ZWdvcnkgPSBjYXNlX3doZW4oDQogICAgICAgIGNhdGVnb3J5ID09ICJUb3RhbCBiYXNpYyBpbmZyYXN0cnVjdHVyZSJ+IkJhc2ljIiwNCiAgICAgICAgY2F0ZWdvcnkgPT0gIlRvdGFsIGRpZ2l0YWwgaW5mcmFzdHJ1Y3R1cmUifiJEaWdpdGFsIiwNCiAgICAgICAgY2F0ZWdvcnkgPT0gIlRvdGFsIHNvY2lhbCBpbmZyYXN0cnVjdHVyZSJ+IlNvY2lhbCIsDQogICAgICAgIFRSVUUgfmNhdGVnb3J5DQogICAgICAgICksIG1ldGFfY2F0ID1jYXNlX3doZW4oDQogICAgICAgICAgbWV0YV9jYXQgPT0gIlRvdGFsIGJhc2ljIGluZnJhc3RydWN0dXJlIn4iQmFzaWMiLA0KICAgICAgICAgIFRSVUUgfm1ldGFfY2F0DQogICAgICAgICkNCiAgICApDQoNCiMgZGZjaF9ncnAkY2F0ZWdvcnkgPC0gYXMuZmFjdG9yKGRmY2hfZ3JwJGNhdGVnb3J5KQ0KIyBkZmNoX2dycCRtZXRhX2NhdCA8LSBhcy5mYWN0b3IoZGZjaF9ncnAkbWV0YV9jYXQpDQojIExldmVsIDE6IFRvdGFsIGluZnJhc3RydWN0dXJlID0+IFRvdGFsIGJhc2ljL3NvY2lhbC9kaWdpdGFsIGluZnJhc3RydWN0dXJlDQpsdmwxIDwtIGRmY2hfZ3JwICU+JSANCiAgICAgIGZpbHRlcihtZXRhX2NhdCAlaW4lICJUb3RhbCBpbmZyYXN0cnVjdHVyZSIpDQoNCg0KbHZsMiA8LSBkZmNoX2dycCAlPiUgZmlsdGVyKG1ldGFfY2F0ICVpbiUgYygNCiAgICAgICJCYXNpYyIsDQogICAgICAiRGlnaXRhbCIsDQogICAgICAiU29jaWFsIg0KICApKQ0KDQoNCg0KbHZsMyA8LSBkZmNoX2dycCAlPiUgZmlsdGVyKG1ldGFfY2F0ICVpbiUgbHZsMiRjYXRlZ29yeSkNCmxhYmVsc1YgPC0gYyh1bmlxdWUobHZsMSRtZXRhX2NhdCksIHVuaXF1ZShsdmwyJG1ldGFfY2F0KSwgdW5pcXVlKGx2bDIkY2F0ZWdvcnkpLHVuaXF1ZShsdmwzJGNhdGVnb3J5KSkNCg0Kc291cmNlViA8LWMobWF0Y2gobHZsMSRtZXRhX2NhdCwgbGFiZWxzKSwgbWF0Y2gobHZsMiRtZXRhX2NhdCxsYWJlbHMpLCBtYXRjaChsdmwzJG1ldGFfY2F0LGxhYmVscykpDQp0YXJnZXRWIDwtIGMobWF0Y2gobHZsMSRjYXRlZ29yeSwgbGFiZWxzKSwgbWF0Y2gobHZsMiRjYXRlZ29yeSxsYWJlbHMpLCBtYXRjaChsdmwzJGNhdGVnb3J5LGxhYmVscykpDQp2YWx1ZVYgPC0gYyhsdmwxJGludiwgbHZsMiRpbnYsIGx2bDMkaW52KQ0KICAgICAgICAgICAgIA0KDQojIGx2bDENCiMgbHZsMg0KIyBsdmwzDQoNCmBgYA0KDQoNCg0KYGBge3IgSW52QnJlYWtkb3duIC0gUGxvdHRpbmcsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTgsIHdhcm5pbmc9RkFMU0V9DQoNCmZpZ19zYW5rZXkgPC0gcGxvdF9seSgNCiAgICB0eXBlID0gInNhbmtleSIsDQogICAgb3JpZW50YXRpb24gPSAiaCIsDQogIA0KICAgIG5vZGUgPSBsaXN0KA0KICAgICAgbGFiZWwgPSBsYWJlbHNWLA0KICAgICAgIyBjb2xvciA9IGMoImJsdWUiLCAiYmx1ZSIsICJibHVlIiwgImJsdWUiLCAiYmx1ZSIsICJibHVlIiksDQogICAgICBwYWQgPSAxNSwNCiAgICAgIHRoaWNrbmVzcyA9IDIwLA0KICAgICAgbGluZSA9IGxpc3QoDQogICAgICAgIGNvbG9yID0gImJsYWNrIiwNCiAgICAgICAgd2lkdGggPSAwLjUNCiAgICAgICkNCiAgICApLA0KICBsaW5rID0gbGlzdCgNCiAgICBzb3VyY2UgPSBzb3VyY2VWLTEsDQogICAgdGFyZ2V0ID0gdGFyZ2V0Vi0xLA0KICAgIHZhbHVlID0gdmFsdWVWDQogICkNCikNCg0KZmlnX3NhbmtleSA8LSBmaWdfc2Fua2V5ICU+JSBsYXlvdXQoDQogIHRpdGxlPSdVU0EgSW5mcmFlc3RydWN0dXJlIEludmVzdG1lbnQgQnJlYWtkb3duICgkKScsDQogIGZvbnQgPSBsaXN0KHNpemU9MTApDQopDQoNCmZpZ19zYW5rZXkNCg0KYGBgDQoNCg==