Introduction
Tôi thực hiện thử nghiệm với bộ dữ liệu Video Game Sales được thống kê từ các năm từ 1980 đến 2020 chứa các số liệu bán hàng khác nhau trên toàn cầu, JP, EU, NA.
Phần trình bày dưới đây của tôi vẫn còn nhiều thiếu xót, vì vậy tôi sẽ tiếp tục nghiên cứu và cập nhật trong thời gian tới.
Sum of Global Sales by Year
- Biểu đồ thể hiện tổng doanh số bán hàng của Global, North America, Europe, Japan, The Rest of the World từ năm 1980 - 2020. Từ hình vẽ ta có thể kết luận rằng North America là khu vực có giữ doanh số về trò chơi điện tử lớn nhất qua các năm.Vì đây là quốc gia có nền kinh tế và công nghệ phát triển, nhu cầu về những trò chơi giải trí cũng trở nên phổ biến và đạt đến đỉnh cao vào năm 2008.
#-----------------------------
#Sum of Global Sales by Year
#----------------------------
sum_of_sales <- games %>%
group_by(Year) %>%
summarise(sum_global_sales = sum(Global_Sales), sum_others_sales = sum(Other_Sales),
sum_jb_sales = sum(JP_Sales), sum_eu_sales = sum(EU_Sales),
sum_na_sales = sum(NA_Sales), .groups = 'drop')
sum_of_sales %>%
ggplot(aes(x = Year)) +
geom_line(aes(y = sum_global_sales,group=1,color="Global Sales")) +
geom_line(aes(y= sum_na_sales,group=1,color="North America Sales")) +
geom_line(aes(y= sum_eu_sales,group=1,color="Europe Sales")) +
geom_line(aes(y= sum_jb_sales,group=1,color="Japan Sales")) +
geom_line(aes(y= sum_others_sales,group=1,color="The Rest of the World")) +
theme(plot.title = element_text(family = my_font, size = 40, color = "grey10", face = "bold")) +
theme(plot.caption = element_text(family = my_font, size = 12, color = "grey40", face = "italic")) +
theme(legend.title = element_text(size = 30, face = "bold", family = my_font)) +
theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1),legend.position="top") +
scale_color_manual(name="Sales",values = colors)+
theme(plot.caption = element_text(family = my_font, size = 12, color = "grey40", face = "italic")) +
labs(x = NULL, y = NULL,
title = "Sum of Global Sales by Year",
caption = "Data Source: Kaggle") +
theme_classic() +
theme(panel.grid = element_blank())

Top 10 Games by Sales
- Bên cạnh đó, bộ dữ liệu chứa các trò chơi khác nhau từ nhiều năm trên nền tảng khác nhau, rất khó để hiển thị top 10 trò chơi/ nhà phát hành/ nền tảng nổi tiếng nhất mà người dùng thích chơi. Do đó, tôi sẽ vẽ biểu đồ khác nhau về 10 trò chơi hàng đầu mà người dùng thích chơi bằng cách sử dụng nền tảng khác nhau. Tiếp tục với biểu đồ về top 10 trò chơi hàng đầu trong khoảng từ năm 1980 - 2020, Wii Sport đứng đầu doanh số bán hàng, theo sau đó là Grand Theft Auto V có khoảng cách với Wii Sport là 26,82 triệu.
#-------------------------
# Top 10 Games by Sales
#-------------------------
year_count <- games %>%
group_by(Year) %>%
summarise(count_year = n())
# tail(year_count)
games <- games[games$Year!='2017'& games$Year!='2020',]
gsales10 <-games %>%
group_by(Name) %>%
summarise(sum_global_sales = sum(Global_Sales),.groups = 'drop') %>%
arrange(desc(sum_global_sales))
games_totalsales <- head(gsales10, 10)
#plot
games_totalsales %>%
ggplot(aes(x= Name, y=sum_global_sales)) +
geom_bar(stat = "identity", aes(x= Name, y=sum_global_sales, fill = Name)) +
theme(plot.title = element_text(size = 30, face = 'bold', family = my_font)) +
labs(x = NULL, y = NULL,
title = "Top 10 Games by Sales",
caption = "Data Source: Kaggle") +
theme_classic() +
theme(panel.grid = element_blank()) +
theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1, size = 10, face = 'italic'),
legend.position="none")

Top 5 Publisher Distribution
- Trong bộ dữ liệu có rất nhiều nhà xuất bản các trò chơi điện tử khác nhau. Tôi lấy ra Top 5 nhà xuất bản dựa theo doanh số bán ra của sản phẩm. Từ biểu đồ này có thể suy ra rằng Nintendo tạo ra doanh số bán hàng cao nhất so với các nhà xuất bản khác (lớn nhất trong giai đoạn 2003 - 2008). Điều này cũng có nghĩa là hầu hết các trò chơi của Nintendo đều phổ biến với người dùng hoặc là những trò chơi có giá cả đắt đỏ hơn so với các sản phẩm còn lại.
#-------------------------------------------------------------------
# Top 5 Publisher Distribution by Yearly Number of Game and Sales
#-------------------------------------------------------------------
publisher_count <- games %>%
group_by(Publisher) %>%
summarise(GlobalSales = sum(Global_Sales),count_game = length(unique(Name)),.groups = 'drop') %>%
arrange(desc(count_game)) %>%
select(Publisher)%>% head(5)
publisher_count20 <- as.vector(publisher_count$Publisher)
publisher_bubble <- games %>%
filter(Publisher %in% publisher_count20) %>%
group_by(Year,Publisher) %>%
summarise(GlobalSales = sum(Global_Sales),count_game = length(unique(Name)),.groups = 'drop') %>%
arrange(desc(Year))
#plot
publisher_bubble %>%
ggplot(aes(x=Year, y=GlobalSales, size=count_game, fill=Publisher)) +
geom_point(alpha=0.5, shape=21, color="black") +
scale_size(range = c(.1, 24), name="Number of Games") +
theme(plot.background =element_blank()) +
labs(x = NULL, y = NULL,
title = "Top 5 Publisher Distribution by Yearly Number of Game and Sales",
caption = "Data Source: Kaggle") +
theme(legend.position="right",axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) +
theme(plot.title = element_text(size = 50, face = 'bold', family = my_font)) +
theme_classic() +
theme(panel.grid = element_blank())

LS0tDQp0aXRsZTogJ1ByYWN0aWNlIDY6IFZpZGVvIEdhbWUgU2FsZXMnDQphdXRob3I6ICJOZ3V5ZW4gVGhpIE5nb2MgSHV5ZW4iDQpkYXRlOiAiNC83LzIwMjEiDQpvdXRwdXQ6IA0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBoaWdobGlnaHQ6IHplbmJ1cm4NCiAgICAjIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdGhlbWU6IGZsYXRseQ0KICAgIHRvYzogVFJVRQ0KICAgIHRvY19mbG9hdDogVFJVRQ0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSkNCg0KYGBgDQoNCiMgSW50cm9kdWN0aW9uDQoNCiAgVMO0aSB0aOG7sWMgaGnhu4duIHRo4butIG5naGnhu4dtIHbhu5tpIGLhu5kgZOG7ryBsaeG7h3UgVmlkZW8gR2FtZSBTYWxlcyDEkcaw4bujYyB0aOG7kW5nIGvDqiB04burIGPDoWMgbsSDbSB04burIDE5ODAgxJHhur9uIDIwMjAgY2jhu6lhIGPDoWMgc+G7kSBsaeG7h3UgYsOhbiBow6BuZyBraMOhYyBuaGF1IHRyw6puIHRvw6BuIGPhuqd1LCBKUCwgRVUsIE5BLg0KIA0KICBQaOG6p24gdHLDrG5oIGLDoHkgZMaw4bubaSDEkcOieSBj4bunYSB0w7RpIHbhuqtuIGPDsm4gbmhp4buBdSB0aGnhur91IHjDs3QsIHbDrCB24bqteSB0w7RpIHPhur0gdGnhur9wIHThu6VjIG5naGnDqm4gY+G7qXUgdsOgIGPhuq1wIG5o4bqtdCB0cm9uZyB0aOG7nWkgZ2lhbiB04bubaS4NCg0KIyBOdW1iZXIgb2YgR2FtZXMgaW4gZWFjaCBQbGF0Zm9ybXMNCg0KMS4gQmnhu4N1IMSR4buTIHbhu4Egc+G7kSBsxrDhu6NuZyB0csOyIGNoxqFpIGPhu6dhIG3hu5dpIG7hu4FuIHThuqNuZy4NCg0KICBUaMOhY2ggdGjhu6ljIGPhu6dhIHThu4dwIGThu68gbGnhu4d1IG7DoHkga2jDtG5nIGPDsyB04buVbmcgZG9hbmggc+G7kSBjaG8gdOG7q25nIG5ow6Agc+G6o24geHXhuqV0IGhv4bq3YyB0aOG7gyBsb+G6oWkgaG/hurdjIG7hu4FuIHThuqNuZy4gRG8gxJHDsyBj4bqnbiB0w61uaCB04buVbmcgZG9hbmggc+G7kSB0aGVvIGPDoWNoIHRo4bunIGPDtG5nLCB0w7RpIHPhur0gdOG7lW5nIGjhu6NwIDQgZG9hbmggc+G7kSBiw6FuIGjDoG5nIGtow6FjIG5oYXUgdMawxqFuZyDhu6luZyB2w6AgcGjDom4gbG/huqFpIHRoZW8gbmjDoCBz4bqjbiB4deG6pXQsIHRo4buDIGxv4bqhaSBob+G6t2MgbuG7gW4gdOG6o25nLg0KICBU4burIGJp4buDdSDEkeG7kyBjaMO6bmcgdGEgY8OzIHRo4buDIHN1eSByYSBj4bqjIERTIHbDoCBQUzIgxJHhu4F1IHLhuqV0IGfhuqduIG5oYXUuIERTIGPDsyB04buVbmcgY+G7mW5nIDIxNjMgdHLDsiBjaMahaSB2w6AgUFMyIGPDsyB04buVbmcgY+G7mW5nIDIxNjEgdHLDsiBjaMahaS4gTeG6t3Qga2jDoWMsIFBDRlggY8OzIHPhu5EgbMaw4bujbmcgdHLDsiBjaMahaSB0aOG6pXAgbmjhuqV0ICgxIHRyw7IgY2jGoWkpLg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCg0KIyBMb2FkIHBhY2thZ2UgYW5kIGRhdGE6IA0KbGlicmFyeSh0aWR5dmVyc2UpDQoNCiMgZ2FtZXMgPC0gcmVhZC5jc3YoInZnc2FsZXMxLmNzdiIsIGhlYWRlciA9IFQpDQoNCmdhbWVzIDwtIHJlYWRfY3N2KCJEOlxcUlxcRGF0YVxcdmdzYWxlczEuY3N2IikNCg0Kb3B0aW9ucyhyZXByLnBsb3Qud2lkdGggPSAxNiwgcmVwci5wbG90LmhlaWdodCA9IDgpDQoNCmdhbWVzIDwtIGdhbWVzW2dhbWVzJFllYXIhPSdOL0EnLF0NCmdhbWVzJFllYXIgPC0gZmFjdG9yKGdhbWVzJFllYXIpDQoNCmdhbWVzIDwtIGdhbWVzWywyOjExXQ0KDQojZm9udCAmIGNvbG9yDQpjb2xvcnMgPC0gYygiR2xvYmFsIFNhbGVzIj0icmVkIiwgIk5vcnRoIEFtZXJpY2EgU2FsZXMiPSJibHVlIiwgIkV1cm9wZSBTYWxlcyI9ImdyZWVuIiwgIkphcGFuIFNhbGVzIj0ib3JhbmdlIiwNCiAgICAgICAgICAgICJUaGUgUmVzdCBvZiB0aGUgV29ybGQiPSJ2aW9sZXQiKQ0KbXlfZm9udCA8LSAiUm9ib3RvIg0KDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgTnVtYmVyIG9mIEdhbWVzIGluIGVhY2ggUGxhdGZvcm1zDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NClBGIDwtIGdhbWVzICU+JSANCiAgZ3JvdXBfYnkoUGxhdGZvcm0pICU+JSBjb3VudCgpDQoNClBGICU+JSBnZ3Bsb3QoYWVzKHggPSBQbGF0Zm9ybSwgeSA9IG4pKSArDQogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknLCBmaWxsID0gIiMyYzdiYjYiKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDQwLCBmYWNlID0gJ2JvbGQnLCBmYW1pbHkgPSBteV9mb250KSkgKw0KICBsYWJzKHggPSBOVUxMLCB5ID0gTlVMTCwgDQogICAgICAgdGl0bGUgPSAiTnVtYmVyIG9mIEdhbWVzIGluIGVhY2ggUGxhdGZvcm1zIiwNCiAgICAgICBjYXB0aW9uID0gIkRhdGEgU291cmNlOiBLYWdnbGUiKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCkpDQoNCmBgYA0KDQohW10oRDpcUlxwcmFjdGljZVxwaWN0dXJlXG51bWJlcm9mZ2FtZXMucG5nKQ0KDQojIFN1bSBvZiBHbG9iYWwgU2FsZXMgYnkgWWVhcg0KMi4gQmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiB04buVbmcgZG9hbmggc+G7kSBiw6FuIGjDoG5nIGPhu6dhIEdsb2JhbCwgTm9ydGggQW1lcmljYSwgRXVyb3BlLCBKYXBhbiwgVGhlIFJlc3Qgb2YgdGhlIFdvcmxkIHThu6sgbsSDbSAxOTgwIC0gMjAyMC4NClThu6sgaMOsbmggduG6vSB0YSBjw7MgdGjhu4Mga+G6v3QgbHXhuq1uIHLhurFuZyBOb3J0aCBBbWVyaWNhIGzDoCBraHUgduG7sWMgY8OzIGdp4buvIGRvYW5oIHPhu5EgduG7gSB0csOyIGNoxqFpIMSRaeG7h24gdOG7rSBs4bubbiBuaOG6pXQgcXVhIGPDoWMgbsSDbS5Ww6wgxJHDonkgbMOgIHF14buRYyBnaWEgY8OzIG7hu4FuIGtpbmggdOG6vyB2w6AgY8O0bmcgbmdo4buHIHBow6F0IHRyaeG7g24sIG5odSBj4bqndSB24buBIG5o4buvbmcgdHLDsiBjaMahaSBnaeG6o2kgdHLDrSBjxaluZyB0cuG7nyBuw6puIHBo4buVIGJp4bq/biB2w6AgxJHhuqF0IMSR4bq/biDEkeG7iW5oIGNhbyB2w6BvIG7Eg20gMjAwOC4NCmBgYHtyLCBldmFsPUZBTFNFfQ0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojU3VtIG9mIEdsb2JhbCBTYWxlcyBieSBZZWFyDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQpzdW1fb2Zfc2FsZXMgPC0gZ2FtZXMgJT4lIA0KICBncm91cF9ieShZZWFyKSAlPiUgDQogIHN1bW1hcmlzZShzdW1fZ2xvYmFsX3NhbGVzID0gc3VtKEdsb2JhbF9TYWxlcyksIHN1bV9vdGhlcnNfc2FsZXMgPSBzdW0oT3RoZXJfU2FsZXMpLA0KICAgICAgICAgICAgc3VtX2piX3NhbGVzID0gc3VtKEpQX1NhbGVzKSwgc3VtX2V1X3NhbGVzID0gc3VtKEVVX1NhbGVzKSwNCiAgICAgICAgICAgIHN1bV9uYV9zYWxlcyA9IHN1bShOQV9TYWxlcyksIC5ncm91cHMgPSAnZHJvcCcpDQoNCg0Kc3VtX29mX3NhbGVzICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gWWVhcikpICsNCiAgZ2VvbV9saW5lKGFlcyh5ID0gc3VtX2dsb2JhbF9zYWxlcyxncm91cD0xLGNvbG9yPSJHbG9iYWwgU2FsZXMiKSkgKw0KICBnZW9tX2xpbmUoYWVzKHk9IHN1bV9uYV9zYWxlcyxncm91cD0xLGNvbG9yPSJOb3J0aCBBbWVyaWNhIFNhbGVzIikpICsNCiAgZ2VvbV9saW5lKGFlcyh5PSBzdW1fZXVfc2FsZXMsZ3JvdXA9MSxjb2xvcj0iRXVyb3BlIFNhbGVzIikpICsNCiAgZ2VvbV9saW5lKGFlcyh5PSBzdW1famJfc2FsZXMsZ3JvdXA9MSxjb2xvcj0iSmFwYW4gU2FsZXMiKSkgKw0KICBnZW9tX2xpbmUoYWVzKHk9IHN1bV9vdGhlcnNfc2FsZXMsZ3JvdXA9MSxjb2xvcj0iVGhlIFJlc3Qgb2YgdGhlIFdvcmxkIikpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSBteV9mb250LCBzaXplID0gNDAsIGNvbG9yID0gImdyZXkxMCIsIGZhY2UgPSAiYm9sZCIpKSArDQogIHRoZW1lKHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSBteV9mb250LCBzaXplID0gMTIsIGNvbG9yID0gImdyZXk0MCIsIGZhY2UgPSAiaXRhbGljIikpICsNCiAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAzMCwgZmFjZSA9ICJib2xkIiwgZmFtaWx5ID0gbXlfZm9udCkpICsgDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41LCBoanVzdD0xKSxsZWdlbmQucG9zaXRpb249InRvcCIpICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWU9IlNhbGVzIix2YWx1ZXMgPSBjb2xvcnMpKw0KICB0aGVtZShwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gbXlfZm9udCwgc2l6ZSA9IDEyLCBjb2xvciA9ICJncmV5NDAiLCBmYWNlID0gIml0YWxpYyIpKSArDQogIGxhYnMoeCA9IE5VTEwsIHkgPSBOVUxMLA0KICAgICAgIHRpdGxlID0gIlN1bSBvZiBHbG9iYWwgU2FsZXMgYnkgWWVhciIsDQogICAgICAgY2FwdGlvbiA9ICJEYXRhIFNvdXJjZTogS2FnZ2xlIikgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpKQ0KYGBgDQoNCiFbXShEOlxSXHByYWN0aWNlXHBpY3R1cmVcUnBsb3QyLnBuZykNCg0KIyBUb3AgMTAgR2FtZXMgYnkgU2FsZXMNCg0KMy4gQsOqbiBj4bqhbmggxJHDsywgYuG7mSBk4buvIGxp4buHdSBjaOG7qWEgY8OhYyB0csOyIGNoxqFpIGtow6FjIG5oYXUgdOG7qyBuaGnhu4F1IG7Eg20gdHLDqm4gbuG7gW4gdOG6o25nIGtow6FjIG5oYXUsIHLhuqV0IGtow7MgxJHhu4MgaGnhu4NuIHRo4buLIHRvcCAxMCB0csOyIGNoxqFpLyBuaMOgIHBow6F0IGjDoG5oLyBu4buBbiB04bqjbmcgbuG7lWkgdGnhur9uZyBuaOG6pXQgbcOgIG5nxrDhu51pIGTDuW5nIHRow61jaCBjaMahaS4gRG8gxJHDsywgdMO0aSBz4bq9IHbhur0gYmnhu4N1IMSR4buTIGtow6FjIG5oYXUgduG7gSAxMCB0csOyIGNoxqFpIGjDoG5nIMSR4bqndSBtw6AgbmfGsOG7nWkgZMO5bmcgdGjDrWNoIGNoxqFpIGLhurFuZyBjw6FjaCBz4butIGThu6VuZyBu4buBbiB04bqjbmcga2jDoWMgbmhhdS4NCiAgVGnhur9wIHThu6VjIHbhu5tpIGJp4buDdSDEkeG7kyB24buBIHRvcCAxMCB0csOyIGNoxqFpIGjDoG5nIMSR4bqndSB0cm9uZyBraG/huqNuZyB04burIG7Eg20gMTk4MCAtIDIwMjAsIFdpaSBTcG9ydCDEkeG7qW5nIMSR4bqndSBkb2FuaCBz4buRIGLDoW4gaMOgbmcsIHRoZW8gc2F1IMSRw7MgbMOgIEdyYW5kIFRoZWZ0IEF1dG8gViBjw7Mga2hv4bqjbmcgY8OhY2ggduG7m2kgV2lpIFNwb3J0IGzDoCAyNiw4MiB0cmnhu4d1Lg0KYGBge3IsIGV2YWw9RkFMU0V9DQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBUb3AgMTAgR2FtZXMgYnkgU2FsZXMNCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCnllYXJfY291bnQgPC0gZ2FtZXMgJT4lIA0KICBncm91cF9ieShZZWFyKSAlPiUgDQogIHN1bW1hcmlzZShjb3VudF95ZWFyID0gbigpKQ0KDQojIHRhaWwoeWVhcl9jb3VudCkNCg0KZ2FtZXMgPC0gZ2FtZXNbZ2FtZXMkWWVhciE9JzIwMTcnJiBnYW1lcyRZZWFyIT0nMjAyMCcsXQ0KDQpnc2FsZXMxMCA8LWdhbWVzICU+JQ0KICAgIGdyb3VwX2J5KE5hbWUpICU+JQ0KICAgIHN1bW1hcmlzZShzdW1fZ2xvYmFsX3NhbGVzID0gc3VtKEdsb2JhbF9TYWxlcyksLmdyb3VwcyA9ICdkcm9wJykgJT4lDQogICAgYXJyYW5nZShkZXNjKHN1bV9nbG9iYWxfc2FsZXMpKQ0KZ2FtZXNfdG90YWxzYWxlcyA8LSBoZWFkKGdzYWxlczEwLCAxMCkNCg0KI3Bsb3QNCg0KZ2FtZXNfdG90YWxzYWxlcyAlPiUgDQogIGdncGxvdChhZXMoeD0gTmFtZSwgeT1zdW1fZ2xvYmFsX3NhbGVzKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgIGFlcyh4PSBOYW1lLCB5PXN1bV9nbG9iYWxfc2FsZXMsIGZpbGwgPSBOYW1lKSkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAzMCwgZmFjZSA9ICdib2xkJywgZmFtaWx5ID0gbXlfZm9udCkpICsNCiAgbGFicyh4ID0gTlVMTCwgeSA9IE5VTEwsDQogICAgICAgdGl0bGUgPSAiVG9wIDEwIEdhbWVzIGJ5IFNhbGVzIiwNCiAgICAgICBjYXB0aW9uID0gIkRhdGEgU291cmNlOiBLYWdnbGUiKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCkpICsNCiAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDAuNSwgaGp1c3Q9MSwgc2l6ZSA9IDEwLCBmYWNlID0gJ2l0YWxpYycpLA0KICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpDQpgYGANCg0KIVtdKEQ6XFJccHJhY3RpY2VccGljdHVyZVx0b3AxMC5wbmcpDQoNCiMgVG9wIDUgUHVibGlzaGVyIERpc3RyaWJ1dGlvbg0KDQo0LiBUcm9uZyBi4buZIGThu68gbGnhu4d1IGPDsyBy4bqldCBuaGnhu4F1IG5ow6AgeHXhuqV0IGLhuqNuIGPDoWMgdHLDsiBjaMahaSDEkWnhu4duIHThu60ga2jDoWMgbmhhdS4gVMO0aSBs4bqleSByYSBUb3AgNSBuaMOgIHh14bqldCBi4bqjbiBk4buxYSB0aGVvIGRvYW5oIHPhu5EgYsOhbiByYSBj4bunYSBz4bqjbiBwaOG6qW0uIFThu6sgYmnhu4N1IMSR4buTIG7DoHkgY8OzIHRo4buDIHN1eSByYSBy4bqxbmcgTmludGVuZG8gdOG6oW8gcmEgZG9hbmggc+G7kSBiw6FuIGjDoG5nIGNhbyBuaOG6pXQgc28gduG7m2kgY8OhYyBuaMOgIHh14bqldCBi4bqjbiBraMOhYyAobOG7m24gbmjhuqV0IHRyb25nIGdpYWkgxJFv4bqhbiAyMDAzIC0gMjAwOCkuIMSQaeG7gXUgbsOgeSBjxaluZyBjw7MgbmdoxKlhIGzDoCBo4bqndSBo4bq/dCBjw6FjIHRyw7IgY2jGoWkgY+G7p2EgTmludGVuZG8gxJHhu4F1IHBo4buVIGJp4bq/biB24bubaSBuZ8aw4budaSBkw7luZyBob+G6t2MgbMOgIG5o4buvbmcgdHLDsiBjaMahaSBjw7MgZ2nDoSBj4bqjIMSR4bqvdCDEkeG7jyBoxqFuIHNvIHbhu5tpIGPDoWMgc+G6o24gcGjhuqltIGPDsm4gbOG6oWkuDQpgYGB7ciwgZXZhbD1GQUxTRX0NCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIFRvcCA1IFB1Ymxpc2hlciBEaXN0cmlidXRpb24gYnkgWWVhcmx5IE51bWJlciBvZiBHYW1lIGFuZCBTYWxlcw0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KcHVibGlzaGVyX2NvdW50IDwtIGdhbWVzICU+JQ0KICAgIGdyb3VwX2J5KFB1Ymxpc2hlcikgJT4lDQogICAgc3VtbWFyaXNlKEdsb2JhbFNhbGVzID0gc3VtKEdsb2JhbF9TYWxlcyksY291bnRfZ2FtZSA9IGxlbmd0aCh1bmlxdWUoTmFtZSkpLC5ncm91cHMgPSAnZHJvcCcpICU+JQ0KICAgIGFycmFuZ2UoZGVzYyhjb3VudF9nYW1lKSkgJT4lDQogICAgc2VsZWN0KFB1Ymxpc2hlciklPiUgaGVhZCg1KQ0KDQpwdWJsaXNoZXJfY291bnQyMCA8LSBhcy52ZWN0b3IocHVibGlzaGVyX2NvdW50JFB1Ymxpc2hlcikNCg0KcHVibGlzaGVyX2J1YmJsZSA8LSBnYW1lcyAlPiUNCiAgICBmaWx0ZXIoUHVibGlzaGVyICVpbiUgcHVibGlzaGVyX2NvdW50MjApICU+JQ0KICAgIGdyb3VwX2J5KFllYXIsUHVibGlzaGVyKSAlPiUNCiAgICBzdW1tYXJpc2UoR2xvYmFsU2FsZXMgPSBzdW0oR2xvYmFsX1NhbGVzKSxjb3VudF9nYW1lID0gbGVuZ3RoKHVuaXF1ZShOYW1lKSksLmdyb3VwcyA9ICdkcm9wJykgJT4lDQogICAgYXJyYW5nZShkZXNjKFllYXIpKQ0KDQojcGxvdA0KcHVibGlzaGVyX2J1YmJsZSAlPiUgDQogIGdncGxvdChhZXMoeD1ZZWFyLCB5PUdsb2JhbFNhbGVzLCBzaXplPWNvdW50X2dhbWUsIGZpbGw9UHVibGlzaGVyKSkgKw0KICBnZW9tX3BvaW50KGFscGhhPTAuNSwgc2hhcGU9MjEsIGNvbG9yPSJibGFjayIpICsNCiAgc2NhbGVfc2l6ZShyYW5nZSA9IGMoLjEsIDI0KSwgbmFtZT0iTnVtYmVyIG9mIEdhbWVzIikgKw0KICB0aGVtZShwbG90LmJhY2tncm91bmQgPWVsZW1lbnRfYmxhbmsoKSkgKw0KICBsYWJzKHggPSBOVUxMLCB5ID0gTlVMTCwNCiAgICAgICB0aXRsZSA9ICJUb3AgNSBQdWJsaXNoZXIgRGlzdHJpYnV0aW9uIGJ5IFllYXJseSBOdW1iZXIgb2YgR2FtZSBhbmQgU2FsZXMiLA0KICAgICAgIGNhcHRpb24gPSAiRGF0YSBTb3VyY2U6IEthZ2dsZSIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJyaWdodCIsYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAwLjUsIGhqdXN0PTEpKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDUwLCBmYWNlID0gJ2JvbGQnLCBmYW1pbHkgPSBteV9mb250KSkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpKQ0KDQpgYGANCg0KDQohW10oRDpcUlxwcmFjdGljZVxwaWN0dXJlXHRvcDUucG5nKQ0K