Titanic

Instalar paquetes y llamar librerias

#install.packages("rpart")
library(rpart)
#install.packages("rpart.plot")
library(rpart.plot)
library(readr)

Importar base de datos

titanic <- read_csv("~/Documents/Modulo2/titanic.csv")
## Rows: 1310 Columns: 14
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (7): name, sex, ticket, cabin, embarked, boat, home.dest
## dbl (7): pclass, survived, age, sibsp, parch, fare, body
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Entender la base de datos

summary(titanic)
##      pclass         survived         name               sex           
##  Min.   :1.000   Min.   :0.000   Length:1310        Length:1310       
##  1st Qu.:2.000   1st Qu.:0.000   Class :character   Class :character  
##  Median :3.000   Median :0.000   Mode  :character   Mode  :character  
##  Mean   :2.295   Mean   :0.382                                        
##  3rd Qu.:3.000   3rd Qu.:1.000                                        
##  Max.   :3.000   Max.   :1.000                                        
##  NA's   :1       NA's   :1                                            
##       age              sibsp            parch          ticket         
##  Min.   : 0.1667   Min.   :0.0000   Min.   :0.000   Length:1310       
##  1st Qu.:21.0000   1st Qu.:0.0000   1st Qu.:0.000   Class :character  
##  Median :28.0000   Median :0.0000   Median :0.000   Mode  :character  
##  Mean   :29.8811   Mean   :0.4989   Mean   :0.385                     
##  3rd Qu.:39.0000   3rd Qu.:1.0000   3rd Qu.:0.000                     
##  Max.   :80.0000   Max.   :8.0000   Max.   :9.000                     
##  NA's   :264       NA's   :1        NA's   :1                         
##       fare            cabin             embarked             boat          
##  Min.   :  0.000   Length:1310        Length:1310        Length:1310       
##  1st Qu.:  7.896   Class :character   Class :character   Class :character  
##  Median : 14.454   Mode  :character   Mode  :character   Mode  :character  
##  Mean   : 33.295                                                           
##  3rd Qu.: 31.275                                                           
##  Max.   :512.329                                                           
##  NA's   :2                                                                 
##       body        home.dest        
##  Min.   :  1.0   Length:1310       
##  1st Qu.: 72.0   Class :character  
##  Median :155.0   Mode  :character  
##  Mean   :160.8                     
##  3rd Qu.:256.0                     
##  Max.   :328.0                     
##  NA's   :1189
str(titanic)
## spc_tbl_ [1,310 × 14] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ pclass   : num [1:1310] 1 1 1 1 1 1 1 1 1 1 ...
##  $ survived : num [1:1310] 1 1 0 0 0 1 1 0 1 0 ...
##  $ name     : chr [1:1310] "Allen, Miss. Elisabeth Walton" "Allison, Master. Hudson Trevor" "Allison, Miss. Helen Loraine" "Allison, Mr. Hudson Joshua Creighton" ...
##  $ sex      : chr [1:1310] "female" "male" "female" "male" ...
##  $ age      : num [1:1310] 29 0.917 2 30 25 ...
##  $ sibsp    : num [1:1310] 0 1 1 1 1 0 1 0 2 0 ...
##  $ parch    : num [1:1310] 0 2 2 2 2 0 0 0 0 0 ...
##  $ ticket   : chr [1:1310] "24160" "113781" "113781" "113781" ...
##  $ fare     : num [1:1310] 211 152 152 152 152 ...
##  $ cabin    : chr [1:1310] "B5" "C22 C26" "C22 C26" "C22 C26" ...
##  $ embarked : chr [1:1310] "S" "S" "S" "S" ...
##  $ boat     : chr [1:1310] "2" "11" NA NA ...
##  $ body     : num [1:1310] NA NA NA 135 NA NA NA NA NA 22 ...
##  $ home.dest: chr [1:1310] "St Louis, MO" "Montreal, PQ / Chesterville, ON" "Montreal, PQ / Chesterville, ON" "Montreal, PQ / Chesterville, ON" ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   pclass = col_double(),
##   ..   survived = col_double(),
##   ..   name = col_character(),
##   ..   sex = col_character(),
##   ..   age = col_double(),
##   ..   sibsp = col_double(),
##   ..   parch = col_double(),
##   ..   ticket = col_character(),
##   ..   fare = col_double(),
##   ..   cabin = col_character(),
##   ..   embarked = col_character(),
##   ..   boat = col_character(),
##   ..   body = col_double(),
##   ..   home.dest = col_character()
##   .. )
##  - attr(*, "problems")=<externalptr>
head(titanic)
## # A tibble: 6 × 14
##   pclass survived name      sex      age sibsp parch ticket  fare cabin embarked
##    <dbl>    <dbl> <chr>     <chr>  <dbl> <dbl> <dbl> <chr>  <dbl> <chr> <chr>   
## 1      1        1 Allen, M… fema… 29         0     0 24160  211.  B5    S       
## 2      1        1 Allison,… male   0.917     1     2 113781 152.  C22 … S       
## 3      1        0 Allison,… fema…  2         1     2 113781 152.  C22 … S       
## 4      1        0 Allison,… male  30         1     2 113781 152.  C22 … S       
## 5      1        0 Allison,… fema… 25         1     2 113781 152.  C22 … S       
## 6      1        1 Anderson… male  48         0     0 19952   26.6 E12   S       
## # ℹ 3 more variables: boat <chr>, body <dbl>, home.dest <chr>

Crear árbol de decisión

titanic <- titanic[,c("pclass", "age", "sex", "survived")]
titanic$survived <- as.factor (titanic$survived)
titanic$pclass <- as.factor (titanic$pclass)
titanic$sex <- as.factor (titanic$sex)
str(titanic)
## tibble [1,310 × 4] (S3: tbl_df/tbl/data.frame)
##  $ pclass  : Factor w/ 3 levels "1","2","3": 1 1 1 1 1 1 1 1 1 1 ...
##  $ age     : num [1:1310] 29 0.917 2 30 25 ...
##  $ sex     : Factor w/ 2 levels "female","male": 1 2 1 2 1 2 1 2 1 2 ...
##  $ survived: Factor w/ 2 levels "0","1": 2 2 1 1 1 2 2 1 2 1 ...
arbol_titanic <- rpart (survived~., data=titanic)
rpart.plot(arbol_titanic)

prp(arbol_titanic, extra=7, prefix="fraccion\n")

# Conclusiones En conclusión, las más altas probabilidades de sobrevivir en el naufragio del Titanic son: * 100%: si eres niño varón menor de 9.5 años de 1° o 2° clase. * 73%: si eres mujer.

Y, por el contrario, las más bajas probabilidades de sobrevivir son: * 17%: si eres hombre mayor a 9.5 años. * 38%: si eres niño varón menor de 9.5 años de 3° clase.

Cancer de mama

# Importar la base de datos

cancer <- read_csv("~/Documents/cancer_de_mama.csv")
## Rows: 569 Columns: 31
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr  (1): diagnosis
## dbl (30): radius_mean, texture_mean, perimeter_mean, area_mean, smoothness_m...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Analisis de base de datos

summary(cancer)
##   diagnosis          radius_mean      texture_mean   perimeter_mean  
##  Length:569         Min.   : 6.981   Min.   : 9.71   Min.   : 43.79  
##  Class :character   1st Qu.:11.700   1st Qu.:16.17   1st Qu.: 75.17  
##  Mode  :character   Median :13.370   Median :18.84   Median : 86.24  
##                     Mean   :14.127   Mean   :19.29   Mean   : 91.97  
##                     3rd Qu.:15.780   3rd Qu.:21.80   3rd Qu.:104.10  
##                     Max.   :28.110   Max.   :39.28   Max.   :188.50  
##    area_mean      smoothness_mean   compactness_mean  concavity_mean   
##  Min.   : 143.5   Min.   :0.05263   Min.   :0.01938   Min.   :0.00000  
##  1st Qu.: 420.3   1st Qu.:0.08637   1st Qu.:0.06492   1st Qu.:0.02956  
##  Median : 551.1   Median :0.09587   Median :0.09263   Median :0.06154  
##  Mean   : 654.9   Mean   :0.09636   Mean   :0.10434   Mean   :0.08880  
##  3rd Qu.: 782.7   3rd Qu.:0.10530   3rd Qu.:0.13040   3rd Qu.:0.13070  
##  Max.   :2501.0   Max.   :0.16340   Max.   :0.34540   Max.   :0.42680  
##  concave_points_mean symmetry_mean    fractal_dimension_mean   radius_se     
##  Min.   :0.00000     Min.   :0.1060   Min.   :0.04996        Min.   :0.1115  
##  1st Qu.:0.02031     1st Qu.:0.1619   1st Qu.:0.05770        1st Qu.:0.2324  
##  Median :0.03350     Median :0.1792   Median :0.06154        Median :0.3242  
##  Mean   :0.04892     Mean   :0.1812   Mean   :0.06280        Mean   :0.4052  
##  3rd Qu.:0.07400     3rd Qu.:0.1957   3rd Qu.:0.06612        3rd Qu.:0.4789  
##  Max.   :0.20120     Max.   :0.3040   Max.   :0.09744        Max.   :2.8730  
##    texture_se      perimeter_se       area_se        smoothness_se     
##  Min.   :0.3602   Min.   : 0.757   Min.   :  6.802   Min.   :0.001713  
##  1st Qu.:0.8339   1st Qu.: 1.606   1st Qu.: 17.850   1st Qu.:0.005169  
##  Median :1.1080   Median : 2.287   Median : 24.530   Median :0.006380  
##  Mean   :1.2169   Mean   : 2.866   Mean   : 40.337   Mean   :0.007041  
##  3rd Qu.:1.4740   3rd Qu.: 3.357   3rd Qu.: 45.190   3rd Qu.:0.008146  
##  Max.   :4.8850   Max.   :21.980   Max.   :542.200   Max.   :0.031130  
##  compactness_se      concavity_se     concave_points_se   symmetry_se      
##  Min.   :0.002252   Min.   :0.00000   Min.   :0.000000   Min.   :0.007882  
##  1st Qu.:0.013080   1st Qu.:0.01509   1st Qu.:0.007638   1st Qu.:0.015160  
##  Median :0.020450   Median :0.02589   Median :0.010930   Median :0.018730  
##  Mean   :0.025478   Mean   :0.03189   Mean   :0.011796   Mean   :0.020542  
##  3rd Qu.:0.032450   3rd Qu.:0.04205   3rd Qu.:0.014710   3rd Qu.:0.023480  
##  Max.   :0.135400   Max.   :0.39600   Max.   :0.052790   Max.   :0.078950  
##  fractal_dimension_se  radius_worst   texture_worst   perimeter_worst 
##  Min.   :0.0008948    Min.   : 7.93   Min.   :12.02   Min.   : 50.41  
##  1st Qu.:0.0022480    1st Qu.:13.01   1st Qu.:21.08   1st Qu.: 84.11  
##  Median :0.0031870    Median :14.97   Median :25.41   Median : 97.66  
##  Mean   :0.0037949    Mean   :16.27   Mean   :25.68   Mean   :107.26  
##  3rd Qu.:0.0045580    3rd Qu.:18.79   3rd Qu.:29.72   3rd Qu.:125.40  
##  Max.   :0.0298400    Max.   :36.04   Max.   :49.54   Max.   :251.20  
##    area_worst     smoothness_worst  compactness_worst concavity_worst 
##  Min.   : 185.2   Min.   :0.07117   Min.   :0.02729   Min.   :0.0000  
##  1st Qu.: 515.3   1st Qu.:0.11660   1st Qu.:0.14720   1st Qu.:0.1145  
##  Median : 686.5   Median :0.13130   Median :0.21190   Median :0.2267  
##  Mean   : 880.6   Mean   :0.13237   Mean   :0.25427   Mean   :0.2722  
##  3rd Qu.:1084.0   3rd Qu.:0.14600   3rd Qu.:0.33910   3rd Qu.:0.3829  
##  Max.   :4254.0   Max.   :0.22260   Max.   :1.05800   Max.   :1.2520  
##  concave_points_worst symmetry_worst   fractal_dimension_worst
##  Min.   :0.00000      Min.   :0.1565   Min.   :0.05504        
##  1st Qu.:0.06493      1st Qu.:0.2504   1st Qu.:0.07146        
##  Median :0.09993      Median :0.2822   Median :0.08004        
##  Mean   :0.11461      Mean   :0.2901   Mean   :0.08395        
##  3rd Qu.:0.16140      3rd Qu.:0.3179   3rd Qu.:0.09208        
##  Max.   :0.29100      Max.   :0.6638   Max.   :0.20750
str(cancer)
## spc_tbl_ [569 × 31] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ diagnosis              : chr [1:569] "M" "M" "M" "M" ...
##  $ radius_mean            : num [1:569] 18 20.6 19.7 11.4 20.3 ...
##  $ texture_mean           : num [1:569] 10.4 17.8 21.2 20.4 14.3 ...
##  $ perimeter_mean         : num [1:569] 122.8 132.9 130 77.6 135.1 ...
##  $ area_mean              : num [1:569] 1001 1326 1203 386 1297 ...
##  $ smoothness_mean        : num [1:569] 0.1184 0.0847 0.1096 0.1425 0.1003 ...
##  $ compactness_mean       : num [1:569] 0.2776 0.0786 0.1599 0.2839 0.1328 ...
##  $ concavity_mean         : num [1:569] 0.3001 0.0869 0.1974 0.2414 0.198 ...
##  $ concave_points_mean    : num [1:569] 0.1471 0.0702 0.1279 0.1052 0.1043 ...
##  $ symmetry_mean          : num [1:569] 0.242 0.181 0.207 0.26 0.181 ...
##  $ fractal_dimension_mean : num [1:569] 0.0787 0.0567 0.06 0.0974 0.0588 ...
##  $ radius_se              : num [1:569] 1.095 0.543 0.746 0.496 0.757 ...
##  $ texture_se             : num [1:569] 0.905 0.734 0.787 1.156 0.781 ...
##  $ perimeter_se           : num [1:569] 8.59 3.4 4.58 3.44 5.44 ...
##  $ area_se                : num [1:569] 153.4 74.1 94 27.2 94.4 ...
##  $ smoothness_se          : num [1:569] 0.0064 0.00522 0.00615 0.00911 0.01149 ...
##  $ compactness_se         : num [1:569] 0.049 0.0131 0.0401 0.0746 0.0246 ...
##  $ concavity_se           : num [1:569] 0.0537 0.0186 0.0383 0.0566 0.0569 ...
##  $ concave_points_se      : num [1:569] 0.0159 0.0134 0.0206 0.0187 0.0188 ...
##  $ symmetry_se            : num [1:569] 0.03 0.0139 0.0225 0.0596 0.0176 ...
##  $ fractal_dimension_se   : num [1:569] 0.00619 0.00353 0.00457 0.00921 0.00511 ...
##  $ radius_worst           : num [1:569] 25.4 25 23.6 14.9 22.5 ...
##  $ texture_worst          : num [1:569] 17.3 23.4 25.5 26.5 16.7 ...
##  $ perimeter_worst        : num [1:569] 184.6 158.8 152.5 98.9 152.2 ...
##  $ area_worst             : num [1:569] 2019 1956 1709 568 1575 ...
##  $ smoothness_worst       : num [1:569] 0.162 0.124 0.144 0.21 0.137 ...
##  $ compactness_worst      : num [1:569] 0.666 0.187 0.424 0.866 0.205 ...
##  $ concavity_worst        : num [1:569] 0.712 0.242 0.45 0.687 0.4 ...
##  $ concave_points_worst   : num [1:569] 0.265 0.186 0.243 0.258 0.163 ...
##  $ symmetry_worst         : num [1:569] 0.46 0.275 0.361 0.664 0.236 ...
##  $ fractal_dimension_worst: num [1:569] 0.1189 0.089 0.0876 0.173 0.0768 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   diagnosis = col_character(),
##   ..   radius_mean = col_double(),
##   ..   texture_mean = col_double(),
##   ..   perimeter_mean = col_double(),
##   ..   area_mean = col_double(),
##   ..   smoothness_mean = col_double(),
##   ..   compactness_mean = col_double(),
##   ..   concavity_mean = col_double(),
##   ..   concave_points_mean = col_double(),
##   ..   symmetry_mean = col_double(),
##   ..   fractal_dimension_mean = col_double(),
##   ..   radius_se = col_double(),
##   ..   texture_se = col_double(),
##   ..   perimeter_se = col_double(),
##   ..   area_se = col_double(),
##   ..   smoothness_se = col_double(),
##   ..   compactness_se = col_double(),
##   ..   concavity_se = col_double(),
##   ..   concave_points_se = col_double(),
##   ..   symmetry_se = col_double(),
##   ..   fractal_dimension_se = col_double(),
##   ..   radius_worst = col_double(),
##   ..   texture_worst = col_double(),
##   ..   perimeter_worst = col_double(),
##   ..   area_worst = col_double(),
##   ..   smoothness_worst = col_double(),
##   ..   compactness_worst = col_double(),
##   ..   concavity_worst = col_double(),
##   ..   concave_points_worst = col_double(),
##   ..   symmetry_worst = col_double(),
##   ..   fractal_dimension_worst = col_double()
##   .. )
##  - attr(*, "problems")=<externalptr>
head(cancer)
## # A tibble: 6 × 31
##   diagnosis radius_mean texture_mean perimeter_mean area_mean smoothness_mean
##   <chr>           <dbl>        <dbl>          <dbl>     <dbl>           <dbl>
## 1 M                18.0         10.4          123.      1001           0.118 
## 2 M                20.6         17.8          133.      1326           0.0847
## 3 M                19.7         21.2          130       1203           0.110 
## 4 M                11.4         20.4           77.6      386.          0.142 
## 5 M                20.3         14.3          135.      1297           0.100 
## 6 M                12.4         15.7           82.6      477.          0.128 
## # ℹ 25 more variables: compactness_mean <dbl>, concavity_mean <dbl>,
## #   concave_points_mean <dbl>, symmetry_mean <dbl>,
## #   fractal_dimension_mean <dbl>, radius_se <dbl>, texture_se <dbl>,
## #   perimeter_se <dbl>, area_se <dbl>, smoothness_se <dbl>,
## #   compactness_se <dbl>, concavity_se <dbl>, concave_points_se <dbl>,
## #   symmetry_se <dbl>, fractal_dimension_se <dbl>, radius_worst <dbl>,
## #   texture_worst <dbl>, perimeter_worst <dbl>, area_worst <dbl>, …

Árbol de decisiones

cancer$texture_worst <- as.numeric(as.character(cancer$texture_worst))
cancer$radius_worst <- as.numeric(as.character(cancer$radius_worst))
arbol_cancer <- rpart(diagnosis ~ ., data = cancer)
rpart.plot(arbol_cancer)

prp(arbol_cancer, extra = 7, prefix = "fraccion\n")

Conclusiones

Los pacientes que presentan un valor de radius_worst mayor o igual a 17 tienen mayores probabilidades de tener un tumor maligno(94%).

LS0tCnRpdGxlOiAiQXJib2xlcyBkZSBkZWNpc2nDs24iCmF1dGhvcjogIkR5YW5uIEVzdGVmYW7DrWEgSGVybsOhbmRleiBBeWFsYSBBMDA4MzcxOTEiCmRhdGU6ICIyMDI1LTA4LTIwIgpvdXRwdXQ6IAogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IFRSVUUKICAgIHRvY19mbG9hdDogVFJVRQogICAgY29kZV9kb3dubG9hZDogVFJVRQogICAgdGhlbWU6IHlldGkKLS0tCgoKIyA8c3BhbiBzdHlsZT0iY29sb3I6cmVkOyI+VGl0YW5pYyA8L3NwYW4+CgoKIVtdKGh0dHBzOi8vaS5waW5pbWcuY29tL29yaWdpbmFscy83My9jMS82Mi83M2MxNjIxZjMwMDk2ZDlmOWM3MDVhZDRhMDE1Y2RmNS5naWYpCgoKIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZTsiPkluc3RhbGFyIHBhcXVldGVzIHkgbGxhbWFyIGxpYnJlcmlhcyA8L3NwYW4+CgpgYGB7cn0KI2luc3RhbGwucGFja2FnZXMoInJwYXJ0IikKbGlicmFyeShycGFydCkKI2luc3RhbGwucGFja2FnZXMoInJwYXJ0LnBsb3QiKQpsaWJyYXJ5KHJwYXJ0LnBsb3QpCmxpYnJhcnkocmVhZHIpCmBgYAoKIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZTsiPkltcG9ydGFyIGJhc2UgZGUgZGF0b3MgPC9zcGFuPgpgYGB7cn0KdGl0YW5pYyA8LSByZWFkX2Nzdigifi9Eb2N1bWVudHMvTW9kdWxvMi90aXRhbmljLmNzdiIpCmBgYAoKIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZTsiPkVudGVuZGVyIGxhIGJhc2UgZGUgZGF0b3MgPC9zcGFuPgpgYGB7cn0Kc3VtbWFyeSh0aXRhbmljKQpzdHIodGl0YW5pYykKaGVhZCh0aXRhbmljKQpgYGAKCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWU7Ij5DcmVhciDDoXJib2wgZGUgZGVjaXNpw7NuIDwvc3Bhbj4KYGBge3J9CnRpdGFuaWMgPC0gdGl0YW5pY1ssYygicGNsYXNzIiwgImFnZSIsICJzZXgiLCAic3Vydml2ZWQiKV0KdGl0YW5pYyRzdXJ2aXZlZCA8LSBhcy5mYWN0b3IgKHRpdGFuaWMkc3Vydml2ZWQpCnRpdGFuaWMkcGNsYXNzIDwtIGFzLmZhY3RvciAodGl0YW5pYyRwY2xhc3MpCnRpdGFuaWMkc2V4IDwtIGFzLmZhY3RvciAodGl0YW5pYyRzZXgpCnN0cih0aXRhbmljKQphcmJvbF90aXRhbmljIDwtIHJwYXJ0IChzdXJ2aXZlZH4uLCBkYXRhPXRpdGFuaWMpCnJwYXJ0LnBsb3QoYXJib2xfdGl0YW5pYykKcHJwKGFyYm9sX3RpdGFuaWMsIGV4dHJhPTcsIHByZWZpeD0iZnJhY2Npb25cbiIpCmBgYAojIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlOyI+Q29uY2x1c2lvbmVzIDwvc3Bhbj4KRW4gY29uY2x1c2nDs24sIGxhcyBtw6FzIGFsdGFzIHByb2JhYmlsaWRhZGVzIGRlIHNvYnJldml2aXIgZW4gZWwgbmF1ZnJhZ2lvIGRlbCBUaXRhbmljIHNvbjoKKiAxMDAlOiBzaSBlcmVzIG5pw7FvIHZhcsOzbiBtZW5vciBkZSA5LjUgYcOxb3MgZGUgMcKwIG8gMsKwIGNsYXNlLgoqIDczJTogc2kgZXJlcyBtdWplci4KClksIHBvciBlbCBjb250cmFyaW8sIGxhcyBtw6FzIGJhamFzIHByb2JhYmlsaWRhZGVzIGRlIHNvYnJldml2aXIgc29uOgoqIDE3JTogc2kgZXJlcyBob21icmUgbWF5b3IgYSA5LjUgYcOxb3MuCiogMzglOiBzaSBlcmVzIG5pw7FvIHZhcsOzbiBtZW5vciBkZSA5LjUgYcOxb3MgZGUgM8KwIGNsYXNlLgoKIyA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIDsiPkNhbmNlciBkZSBtYW1hIDwvc3Bhbj4KCiFbXShodHRwczovL2JhamFuZXdzLm14L3VwbG9hZHMvaW1hZ2VzL3Bvc3RzLzUwMTU3OTE1NjcxNDFhOGE3NGQ0ZC5qcGcpIAojIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlOyI+SW1wb3J0YXIgbGEgYmFzZSBkZSBkYXRvcyA8L3NwYW4+CgpgYGB7cn0KY2FuY2VyIDwtIHJlYWRfY3N2KCJ+L0RvY3VtZW50cy9jYW5jZXJfZGVfbWFtYS5jc3YiKQpgYGAKIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZTsiPkFuYWxpc2lzIGRlIGJhc2UgZGUgZGF0b3MgPC9zcGFuPgoKYGBge3J9CnN1bW1hcnkoY2FuY2VyKQpzdHIoY2FuY2VyKQpoZWFkKGNhbmNlcikKYGBgCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWU7Ij7DgXJib2wgZGUgZGVjaXNpb25lcyA8L3NwYW4+CgpgYGB7cn0KY2FuY2VyJHRleHR1cmVfd29yc3QgPC0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoY2FuY2VyJHRleHR1cmVfd29yc3QpKQpjYW5jZXIkcmFkaXVzX3dvcnN0IDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGNhbmNlciRyYWRpdXNfd29yc3QpKQphcmJvbF9jYW5jZXIgPC0gcnBhcnQoZGlhZ25vc2lzIH4gLiwgZGF0YSA9IGNhbmNlcikKcnBhcnQucGxvdChhcmJvbF9jYW5jZXIpCnBycChhcmJvbF9jYW5jZXIsIGV4dHJhID0gNywgcHJlZml4ID0gImZyYWNjaW9uXG4iKQoKYGBgCgoKCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWU7Ij5Db25jbHVzaW9uZXMgPC9zcGFuPgoKTG9zIHBhY2llbnRlcyBxdWUgcHJlc2VudGFuIHVuIHZhbG9yIGRlIHJhZGl1c193b3JzdCBtYXlvciBvIGlndWFsIGEgMTcgIHRpZW5lbiBtYXlvcmVzIHByb2JhYmlsaWRhZGVzIGRlIHRlbmVyIHVuIHR1bW9yIG1hbGlnbm8oOTQlKS4gIAo=