Data Visualization Titanic - Machine Learning from Disaster

Intro

Small Talks

Dataset Titanic diambil dari Kaggle yang diperuntukan untuk kompetisi Machine Learning, pada pembahasan ini kita akan menggunakan dataset tersebut untuk analisa dan visualisasi. Kita hanya menggunakan satu file dari compiled dataset yaitu train.csv yang berisi data penumpang dengan kolom sebagai berikut :

PassengerId id

pclass Ticket class, key 1 = 1st, 2 = 2nd, 3 = 3rd

Sex Jenis Kelamin

Age Umur dalam tahun

SibSp saudara atau pasangan yang ikut berlayar

Parch orang tua atau anak yang ikut berlayar

Ticket Ticket number

Fare Passenger fare

Cabin Cabin number

EmbarkedPort of Embarkation

What will we do?

Dari dataset diatas beberapa hal yang akan kita lakukan adalah

Melihat jumlah penumpang berdasarkan kategori jenis kelamin, Umur, dan Kelas yang dibeli

Data Preparation

Memanggil Library yang dibutuhkan

library(dplyr)
library(tidyverse)
library(ggplot2)

Mengunduh data Titanic Train

Data yang diunduh akan disimpan dalam variable t_train

t_train <- read.csv("titanic/test.csv")
head(t_train)

Pengecekan missing values dan treatment terhadap missing values

anyNA(t_train)
#> [1] TRUE
colSums(is.na(t_train))
#> PassengerId      Pclass        Name         Sex         Age       SibSp 
#>           0           0           0           0          86           0 
#>       Parch      Ticket        Fare       Cabin    Embarked 
#>           0           0           1           0           0

missing values ditemukan di kolom Fare sebanyak 1 row dan kolom Age sebanyak 86, yaitu sebanyak 2% ((86+1)/418) dari total data. Untuk memudahkan analisa maka kita perlu membuang baris data tersebut.

t_train_2 <- na.omit(t_train)
glimpse(t_train_2)
#> Rows: 331
#> Columns: 11
#> $ PassengerId <int> 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 903, 904…
#> $ Pclass      <int> 3, 3, 2, 3, 3, 3, 3, 2, 3, 3, 1, 1, 2, 1, 2, 2, 3, 3, 3, 1…
#> $ Name        <chr> "Kelly, Mr. James", "Wilkes, Mrs. James (Ellen Needs)", "M…
#> $ Sex         <chr> "male", "female", "male", "male", "female", "male", "femal…
#> $ Age         <dbl> 34.5, 47.0, 62.0, 27.0, 22.0, 14.0, 30.0, 26.0, 18.0, 21.0…
#> $ SibSp       <int> 0, 1, 0, 0, 1, 0, 0, 1, 0, 2, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1…
#> $ Parch       <int> 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
#> $ Ticket      <chr> "330911", "363272", "240276", "315154", "3101298", "7538",…
#> $ Fare        <dbl> 7.8292, 7.0000, 9.6875, 8.6625, 12.2875, 9.2250, 7.6292, 2…
#> $ Cabin       <chr> "", "", "", "", "", "", "", "", "", "", "", "B45", "", "E3…
#> $ Embarked    <chr> "Q", "S", "Q", "S", "S", "S", "Q", "S", "C", "S", "S", "S"…

Melihat tipe data dan mengubahnya ke format yang tepat

train_clean <- 
  t_train_2 %>% 
  mutate(PassengerId = as.character(PassengerId),
         Pclass = as.factor(Pclass),
         Sex = as.factor(Sex),
         Age = as.factor(round(Age,0)),
         SibSp = as.factor(SibSp),
         Parch = as.factor(Parch),
         Embarked = as.factor(Embarked))
glimpse(train_clean)
#> Rows: 331
#> Columns: 11
#> $ PassengerId <chr> "892", "893", "894", "895", "896", "897", "898", "899", "9…
#> $ Pclass      <fct> 3, 3, 2, 3, 3, 3, 3, 2, 3, 3, 1, 1, 2, 1, 2, 2, 3, 3, 3, 1…
#> $ Name        <chr> "Kelly, Mr. James", "Wilkes, Mrs. James (Ellen Needs)", "M…
#> $ Sex         <fct> male, female, male, male, female, male, female, male, fema…
#> $ Age         <fct> 34, 47, 62, 27, 22, 14, 30, 26, 18, 21, 46, 23, 63, 47, 24…
#> $ SibSp       <fct> 0, 1, 0, 0, 1, 0, 0, 1, 0, 2, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1…
#> $ Parch       <fct> 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
#> $ Ticket      <chr> "330911", "363272", "240276", "315154", "3101298", "7538",…
#> $ Fare        <dbl> 7.8292, 7.0000, 9.6875, 8.6625, 12.2875, 9.2250, 7.6292, 2…
#> $ Cabin       <chr> "", "", "", "", "", "", "", "", "", "", "", "B45", "", "E3…
#> $ Embarked    <fct> Q, S, Q, S, S, S, Q, S, C, S, S, S, S, S, C, Q, C, S, C, C…

Data Processing

Data Exploration

Melihat rangkuman data dari train_clean

summary(train_clean)
#>  PassengerId        Pclass      Name               Sex           Age     
#>  Length:331         1: 98   Length:331         female:127   21     : 17  
#>  Class :character   2: 88   Class :character   male  :204   22     : 17  
#>  Mode  :character   3:145   Mode  :character                24     : 17  
#>                                                             18     : 16  
#>                                                             30     : 15  
#>                                                             26     : 13  
#>                                                             (Other):236  
#>  SibSp   Parch      Ticket               Fare           Cabin          
#>  0:213   0:246   Length:331         Min.   :  0.00   Length:331        
#>  1: 97   1: 50   Class :character   1st Qu.:  8.05   Class :character  
#>  2: 11   2: 29   Mode  :character   Median : 16.00   Mode  :character  
#>  3:  4   3:  3                      Mean   : 40.98                     
#>  4:  4   4:  1                      3rd Qu.: 40.63                     
#>  5:  1   5:  1                      Max.   :512.33                     
#>  8:  1   6:  1                                                         
#>  Embarked
#>  C: 82   
#>  Q: 22   
#>  S:227   
#>          
#>          
#>          
#> 
unique(train_clean$Age)
#>  [1] 34 47 62 27 22 14 30 26 18 21 46 23 63 24 35 45 55 9  48 50 41 33 25 39 60
#> [26] 36 20 28 10 17 32 13 31 29 6  67 49 2  76 43 16 1  12 42 53 40 61 7  15 54
#> [51] 64 37 8  0  38 57 19 58 59 44 5  51 3 
#> 63 Levels: 0 1 2 3 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 21 22 23 24 ... 76

Melihat jumlah penumpang berdasarkan kategori umur.

vic_age <- train_clean %>% 
  group_by(Age) %>% 
  summarise(total_passenger = n()) %>% 
  ungroup() %>% 
  arrange(desc(total_passenger)) %>% 
  head(10)%>%
  arrange((Age))
vic_age

Melihat Jumlah penumpang berdasarkan Kelas dan Jenis Kelamin

vic_class <- train_clean %>% 
  group_by(Pclass,Sex) %>% 
  summarise(total_pclass = n()) %>% 
  arrange(desc(total_pclass))
vic_class

Plotting

Plot_Age <- ggplot(data = vic_age,
              mapping = aes(x = total_passenger,
                            y = reorder(Age,total_passenger)))+
  geom_col(aes(fill = total_passenger),show.legend = F)+
  scale_fill_gradient(low = "#f8d979",high = "#363fe6" )+
  geom_text(aes(label = vic_age$total_passenger ),col = "#040b5b")+
  geom_vline(aes(xintercept = mean(total_passenger))) +
    labs(
    title = "Jumlah Penumpang Titanic Kategori Umur",
    subtitle = "Penumpang Titanic Terbanyak di Rentang Umur 18 sd 30 Tahun",
    y = "Umur",
    x = "Jumlah Penumpang",
    caption = "Source : Titanic - Machine Learning from Disaster"
  )
Plot_Age

plot_class <- 
ggplot(data = vic_class , aes(x= Pclass ,
                              y= reorder(total_pclass,Pclass), 
                              fill=Sex)) +
  geom_bar(position="stack", stat = "identity") +
  labs(
    title = "Proporsi Penumpang Berdasarkan Kelas dan Jenis Kelamin",
    subtitle = "Penumpang Pria Memiliki Proporsi Paling Besar di Semua Kelas",
    y = "Total Penumpang",
    x = "Kelas",
    caption = "Source : Titanic - Machine Learning from Disaster" ) 

plot_class

Conclusion

Dari pengolahan data dan pembuatan visualisasi diatas dapat disimpulkan bahwa :

1. Jumlah penumpang berdasarkan kategori umur tidak signifikan perbedaannya dari kategori umur satu dengan yang lainnya

2. Pada penumpang kelas 2, proporsi jenis kelamin wanita lebih kecil daripada penumpang di kelas 1 dan 3

3. walaupun jumlah pria lebih besar proporsinya dibanding wanita di masing-masing kelas,namun proporsi wanita berusia >50 tahun lebih besar dibanding proporsi pria > 50 tahun

LS0tDQp0aXRsZTogIkRhdGEgVmlzdWFsaXphdGlvbiBUaXRhbmljICAtIE1hY2hpbmUgTGVhcm5pbmcgZnJvbSBEaXNhc3RlciINCmRhdGU6ICJgciBmb3JtYXQoU3lzLkRhdGUoKSwgJyVCICVlLCAlWScpYCINCkF1dGhvciA6IENoZXJpc2EgVmluYXNhcmkNCm91dHB1dDoNCiAgIHJtZGZvcm1hdHM6OnJlYWR0aGVkb3duOg0KICAgIHNlbGZfY29udGFpbmVkOiB0cnVlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIHRvY19kZXB0aDogNA0KICAgIGRmX3ByaW50OiBwYWdlZA0KICAgICNjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgDQogICANCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMgY2xlYXItdXAgdGhlIGVudmlyb25tZW50DQpybShsaXN0ID0gbHMoKSkNCg0KIyBjaHVuayBvcHRpb25zDQprbml0cjo6b3B0c19jaHVuayRzZXQoDQogIG1lc3NhZ2UgPSBGQUxTRSwNCiAgd2FybmluZyA9IEZBTFNFLA0KICBmaWcuYWxpZ24gPSAiY2VudGVyIiwNCiAgY29tbWVudCA9ICIjPiINCikNCg0Kb3B0aW9ucyhzY2lwZW4gPSA5OTk5KQ0KYGBgDQoNCiMgSW50cm8gey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHMgfQ0KDQojIyBTbWFsbCBUYWxrcw0KDQpEYXRhc2V0IFRpdGFuaWMgZGlhbWJpbCBkYXJpIEthZ2dsZSB5YW5nIGRpcGVydW50dWthbiB1bnR1ayBrb21wZXRpc2kgTWFjaGluZSBMZWFybmluZywNCnBhZGEgcGVtYmFoYXNhbiBpbmkga2l0YSBha2FuIG1lbmdndW5ha2FuIGRhdGFzZXQgdGVyc2VidXQgdW50dWsgYW5hbGlzYSBkYW4gdmlzdWFsaXNhc2kuDQpLaXRhIGhhbnlhIG1lbmdndW5ha2FuIHNhdHUgZmlsZSBkYXJpIGNvbXBpbGVkIGRhdGFzZXQgeWFpdHUNCiBgdHJhaW4uY3N2YCAgeWFuZyBiZXJpc2kgZGF0YSBwZW51bXBhbmcgZGVuZ2FuIGtvbG9tIHNlYmFnYWkgYmVyaWt1dCA6DQogDQogYFBhc3NlbmdlcklkYCBpZA0KIA0KIGBwY2xhc3NgICBUaWNrZXQgY2xhc3MsIGtleSAgMSA9IDFzdCwgMiA9IDJuZCwgMyA9IDNyZA0KIA0KIGBTZXhgICAgICBKZW5pcyBLZWxhbWluDQogDQogYEFnZWAgICAgIFVtdXIgZGFsYW0gdGFodW4NCiANCiBgU2liU3BgICAgc2F1ZGFyYSBhdGF1IHBhc2FuZ2FuIHlhbmcgaWt1dCBiZXJsYXlhcg0KIA0KIGBQYXJjaGAgICBvcmFuZyB0dWEgYXRhdSBhbmFrIHlhbmcgaWt1dCBiZXJsYXlhcg0KIA0KIGBUaWNrZXRgICBUaWNrZXQgbnVtYmVyDQogDQogYEZhcmVgICAgIFBhc3NlbmdlciBmYXJlDQogDQogYENhYmluYCAgIENhYmluIG51bWJlcg0KIA0KIGBFbWJhcmtlZGBQb3J0IG9mIEVtYmFya2F0aW9uDQogDQoNCiANCg0KDQojIyBXaGF0IHdpbGwgd2UgZG8/DQoNCkRhcmkgZGF0YXNldCBkaWF0YXMgYmViZXJhcGEgaGFsIHlhbmcgYWthbiBraXRhIGxha3VrYW4gYWRhbGFoDQoNCk1lbGloYXQganVtbGFoIHBlbnVtcGFuZyBiZXJkYXNhcmthbiBrYXRlZ29yaSBqZW5pcyBrZWxhbWluLCBVbXVyLCBkYW4gS2VsYXMgeWFuZyBkaWJlbGkNCg0KDQojIERhdGEgUHJlcGFyYXRpb24NCg0KIyMjIE1lbWFuZ2dpbCBMaWJyYXJ5IHlhbmcgZGlidXR1aGthbiANCg0KYGBge3J9DQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGdncGxvdDIpDQoNCmBgYA0KDQoNCiMjIyBNZW5ndW5kdWggZGF0YSBUaXRhbmljIFRyYWluDQoNCkRhdGEgeWFuZyBkaXVuZHVoIGFrYW4gZGlzaW1wYW4gZGFsYW0gdmFyaWFibGUgYHRfdHJhaW5gDQpgYGB7cn0NCnRfdHJhaW4gPC0gcmVhZC5jc3YoInRpdGFuaWMvdGVzdC5jc3YiKQ0KaGVhZCh0X3RyYWluKQ0KYGBgDQojIyMgUGVuZ2VjZWthbiBfbWlzc2luZyB2YWx1ZXNfIGRhbiB0cmVhdG1lbnQgdGVyaGFkYXAgX21pc3NpbmcgdmFsdWVzXw0KYGBge3J9DQphbnlOQSh0X3RyYWluKQ0KYGBgDQpgYGB7cn0NCmNvbFN1bXMoaXMubmEodF90cmFpbikpDQpgYGANCl9taXNzaW5nIHZhbHVlc18gZGl0ZW11a2FuIGRpIGtvbG9tIEZhcmUgc2ViYW55YWsgMSByb3cgZGFuIGtvbG9tIEFnZSBzZWJhbnlhayA4NiwgeWFpdHUgc2ViYW55YWsgMiUgKCg4NisxKS80MTgpIGRhcmkgdG90YWwgZGF0YS4gVW50dWsgbWVtdWRhaGthbiBhbmFsaXNhIG1ha2Ega2l0YSBwZXJsdSBtZW1idWFuZyBiYXJpcyBkYXRhIHRlcnNlYnV0Lg0KDQpgYGB7cn0NCnRfdHJhaW5fMiA8LSBuYS5vbWl0KHRfdHJhaW4pDQpnbGltcHNlKHRfdHJhaW5fMikNCmBgYA0KDQoNCiMjIyBNZWxpaGF0IHRpcGUgZGF0YSBkYW4gbWVuZ3ViYWhueWEga2UgZm9ybWF0IHlhbmcgdGVwYXQNCg0KYGBge3J9DQp0cmFpbl9jbGVhbiA8LSANCiAgdF90cmFpbl8yICU+JSANCiAgbXV0YXRlKFBhc3NlbmdlcklkID0gYXMuY2hhcmFjdGVyKFBhc3NlbmdlcklkKSwNCiAgICAgICAgIFBjbGFzcyA9IGFzLmZhY3RvcihQY2xhc3MpLA0KICAgICAgICAgU2V4ID0gYXMuZmFjdG9yKFNleCksDQogICAgICAgICBBZ2UgPSBhcy5mYWN0b3Iocm91bmQoQWdlLDApKSwNCiAgICAgICAgIFNpYlNwID0gYXMuZmFjdG9yKFNpYlNwKSwNCiAgICAgICAgIFBhcmNoID0gYXMuZmFjdG9yKFBhcmNoKSwNCiAgICAgICAgIEVtYmFya2VkID0gYXMuZmFjdG9yKEVtYmFya2VkKSkNCmdsaW1wc2UodHJhaW5fY2xlYW4pDQpgYGANCiMgRGF0YSBQcm9jZXNzaW5nIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIH0NCg0KIyMgRGF0YSBFeHBsb3JhdGlvbg0KDQojIyMgTWVsaWhhdCByYW5na3VtYW4gZGF0YSBkYXJpIHRyYWluX2NsZWFuDQoNCmBgYHtyfQ0Kc3VtbWFyeSh0cmFpbl9jbGVhbikNCnVuaXF1ZSh0cmFpbl9jbGVhbiRBZ2UpDQpgYGANCg0KDQojIyMgTWVsaWhhdCBqdW1sYWggcGVudW1wYW5nIGJlcmRhc2Fya2FuIGthdGVnb3JpIHVtdXIuDQoNCg0KYGBge3J9DQp2aWNfYWdlIDwtIHRyYWluX2NsZWFuICU+JSANCiAgZ3JvdXBfYnkoQWdlKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9wYXNzZW5nZXIgPSBuKCkpICU+JSANCiAgdW5ncm91cCgpICU+JSANCiAgYXJyYW5nZShkZXNjKHRvdGFsX3Bhc3NlbmdlcikpICU+JSANCiAgaGVhZCgxMCklPiUNCiAgYXJyYW5nZSgoQWdlKSkNCnZpY19hZ2UNCmBgYA0KDQojIyMgTWVsaWhhdCBKdW1sYWggcGVudW1wYW5nIGJlcmRhc2Fya2FuIEtlbGFzIGRhbiBKZW5pcyBLZWxhbWluDQoNCmBgYHtyfQ0KdmljX2NsYXNzIDwtIHRyYWluX2NsZWFuICU+JSANCiAgZ3JvdXBfYnkoUGNsYXNzLFNleCkgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfcGNsYXNzID0gbigpKSAlPiUgDQogIGFycmFuZ2UoZGVzYyh0b3RhbF9wY2xhc3MpKQ0KdmljX2NsYXNzDQpgYGANCg0KIyMgUGxvdHRpbmcNCg0KYGBge3J9DQoNClBsb3RfQWdlIDwtIGdncGxvdChkYXRhID0gdmljX2FnZSwNCiAgICAgICAgICAgICAgbWFwcGluZyA9IGFlcyh4ID0gdG90YWxfcGFzc2VuZ2VyLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSByZW9yZGVyKEFnZSx0b3RhbF9wYXNzZW5nZXIpKSkrDQogIGdlb21fY29sKGFlcyhmaWxsID0gdG90YWxfcGFzc2VuZ2VyKSxzaG93LmxlZ2VuZCA9IEYpKw0KICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICIjZjhkOTc5IixoaWdoID0gIiMzNjNmZTYiICkrDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSB2aWNfYWdlJHRvdGFsX3Bhc3NlbmdlciApLGNvbCA9ICIjMDQwYjViIikrDQogIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQgPSBtZWFuKHRvdGFsX3Bhc3NlbmdlcikpKSArDQogICAgbGFicygNCiAgICB0aXRsZSA9ICJKdW1sYWggUGVudW1wYW5nIFRpdGFuaWMgS2F0ZWdvcmkgVW11ciIsDQogICAgc3VidGl0bGUgPSAiUGVudW1wYW5nIFRpdGFuaWMgVGVyYmFueWFrIGRpIFJlbnRhbmcgVW11ciAxOCBzZCAzMCBUYWh1biIsDQogICAgeSA9ICJVbXVyIiwNCiAgICB4ID0gIkp1bWxhaCBQZW51bXBhbmciLA0KICAgIGNhcHRpb24gPSAiU291cmNlIDogVGl0YW5pYyAtIE1hY2hpbmUgTGVhcm5pbmcgZnJvbSBEaXNhc3RlciINCiAgKQ0KUGxvdF9BZ2UNCg0KYGBgDQogIA0KYGBge3J9DQpwbG90X2NsYXNzIDwtIA0KZ2dwbG90KGRhdGEgPSB2aWNfY2xhc3MgLCBhZXMoeD0gUGNsYXNzICwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk9IHJlb3JkZXIodG90YWxfcGNsYXNzLFBjbGFzcyksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbD1TZXgpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uPSJzdGFjayIsIHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiUHJvcG9yc2kgUGVudW1wYW5nIEJlcmRhc2Fya2FuIEtlbGFzIGRhbiBKZW5pcyBLZWxhbWluIiwNCiAgICBzdWJ0aXRsZSA9ICJQZW51bXBhbmcgUHJpYSBNZW1pbGlraSBQcm9wb3JzaSBQYWxpbmcgQmVzYXIgZGkgU2VtdWEgS2VsYXMiLA0KICAgIHkgPSAiVG90YWwgUGVudW1wYW5nIiwNCiAgICB4ID0gIktlbGFzIiwNCiAgICBjYXB0aW9uID0gIlNvdXJjZSA6IFRpdGFuaWMgLSBNYWNoaW5lIExlYXJuaW5nIGZyb20gRGlzYXN0ZXIiICkgDQoNCnBsb3RfY2xhc3MNCmBgYA0KICANCg0KIyBDb25jbHVzaW9uDQoNCg0KDQpEYXJpIHBlbmdvbGFoYW4gZGF0YSBkYW4gcGVtYnVhdGFuIHZpc3VhbGlzYXNpIGRpYXRhcyBkYXBhdCBkaXNpbXB1bGthbiBiYWh3YSA6DQoNCiAqKjEuIEp1bWxhaCBwZW51bXBhbmcgYmVyZGFzYXJrYW4ga2F0ZWdvcmkgdW11ciB0aWRhayBzaWduaWZpa2FuIHBlcmJlZGFhbm55YSBkYXJpIGthdGVnb3JpIHVtdXIgc2F0dSBkZW5nYW4geWFuZyBsYWlubnlhKioNCiANCiAqKjIuIFBhZGEgcGVudW1wYW5nIGtlbGFzIDIsIHByb3BvcnNpIGplbmlzIGtlbGFtaW4gd2FuaXRhIGxlYmloIGtlY2lsIGRhcmlwYWRhIHBlbnVtcGFuZyBkaSBrZWxhcyAxIGRhbiAzKioNCiANCiAqKjMuIHdhbGF1cHVuIGp1bWxhaCBwcmlhIGxlYmloIGJlc2FyIHByb3BvcnNpbnlhIGRpYmFuZGluZyB3YW5pdGEgZGkgbWFzaW5nLW1hc2luZyBrZWxhcyxuYW11biBwcm9wb3JzaSB3YW5pdGEgYmVydXNpYSA+NTAgdGFodW4gbGViaWggYmVzYXIgZGliYW5kaW5nIHByb3BvcnNpIHByaWEgPiA1MCB0YWh1bioqDQo=