Teoría

Una Red Neuronal Artificial (ANN) modela la relación entre un conjunto de entradas y una salida, resolviendo un porblema de aprendizaje.

Ejemplos prácticos de aplicación de Redes Neuronales son:

  • La recomendación de contenido de Netflix
  • El feed de Instagram o Tiktok
  • Determinar el número o letra escrito a mano

Instalar paquetes y llamar libreria

# install.packages("neuralnet")
library(neuralnet)

#install.packages("ggplot2") # Gráfica
library(ggplot2)
#install.packages("lattice") # Gráfica
library(lattice)
#install.packages("caret") # Algoritmos de aprendizaje automatico
library(caret)
#install.packages("datasets") # Usar bases de datos, en este caso iris
library(datasets)
#install.packages("DataExplorer") # Análisis Exploratorio
library(DataExplorer)
#install.packages("kernlab")
#install.packages("cluster") #Análisis de agrupamiento
library(cluster)
#install.packages("ggplot2") #Graficar
library(ggplot2)
#install.packages("data.table") # Manejo de muchos datos
library(data.table)
#install.packages("factoextra") # Gráfica de optimización de número de clusters
library(factoextra)

#install.packages("rpart") # Gráfica de optimización de número de clusters
library(rpart)

#install.packages("rpart.plot") # Gráfica de optimización de número de clusters
library(rpart.plot)

Alimentar con ejemplos

examen <- c(20,10,30,20,80,30)
proyecto <- c(90,20,40,50,50,80)
estatus <- c(1,0,0,0,0,1)
df <- data.frame(examen, proyecto,estatus)

Plottear la red

red_neuronal <- neuralnet(estatus~.,data=df)
plot(red_neuronal, rep="best")

# Predecir con la Red Neuronal

prueba_examen <- c(30,40,85)
prueba_proyecto <- c(85,50,40)
prueba <- data.frame(prueba_examen, prueba_proyecto)
prediccion <- compute(red_neuronal, prueba)
prediccion$net.result
##             [,1]
## [1,]  1.01471645
## [2,]  0.02099815
## [3,] -0.01738797
probabilidad <- prediccion$net.result
resultado <- ifelse(probabilidad>0.5,1,0)
resultado
##      [,1]
## [1,]    1
## [2,]    0
## [3,]    0

CANCER MAMA

Importar la base de datos

cancer_mama <- read.csv("/Users/humbertocs/Desktop/Tec/Concentración IA/M2_Programacion R IA/RedesNeuronales/cancer_de_mama.csv")

Entender la base de datos

summary(cancer_mama)
##   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_mama)
## 'data.frame':    569 obs. of  31 variables:
##  $ diagnosis              : chr  "M" "M" "M" "M" ...
##  $ radius_mean            : num  18 20.6 19.7 11.4 20.3 ...
##  $ texture_mean           : num  10.4 17.8 21.2 20.4 14.3 ...
##  $ perimeter_mean         : num  122.8 132.9 130 77.6 135.1 ...
##  $ area_mean              : num  1001 1326 1203 386 1297 ...
##  $ smoothness_mean        : num  0.1184 0.0847 0.1096 0.1425 0.1003 ...
##  $ compactness_mean       : num  0.2776 0.0786 0.1599 0.2839 0.1328 ...
##  $ concavity_mean         : num  0.3001 0.0869 0.1974 0.2414 0.198 ...
##  $ concave_points_mean    : num  0.1471 0.0702 0.1279 0.1052 0.1043 ...
##  $ symmetry_mean          : num  0.242 0.181 0.207 0.26 0.181 ...
##  $ fractal_dimension_mean : num  0.0787 0.0567 0.06 0.0974 0.0588 ...
##  $ radius_se              : num  1.095 0.543 0.746 0.496 0.757 ...
##  $ texture_se             : num  0.905 0.734 0.787 1.156 0.781 ...
##  $ perimeter_se           : num  8.59 3.4 4.58 3.44 5.44 ...
##  $ area_se                : num  153.4 74.1 94 27.2 94.4 ...
##  $ smoothness_se          : num  0.0064 0.00522 0.00615 0.00911 0.01149 ...
##  $ compactness_se         : num  0.049 0.0131 0.0401 0.0746 0.0246 ...
##  $ concavity_se           : num  0.0537 0.0186 0.0383 0.0566 0.0569 ...
##  $ concave_points_se      : num  0.0159 0.0134 0.0206 0.0187 0.0188 ...
##  $ symmetry_se            : num  0.03 0.0139 0.0225 0.0596 0.0176 ...
##  $ fractal_dimension_se   : num  0.00619 0.00353 0.00457 0.00921 0.00511 ...
##  $ radius_worst           : num  25.4 25 23.6 14.9 22.5 ...
##  $ texture_worst          : num  17.3 23.4 25.5 26.5 16.7 ...
##  $ perimeter_worst        : num  184.6 158.8 152.5 98.9 152.2 ...
##  $ area_worst             : num  2019 1956 1709 568 1575 ...
##  $ smoothness_worst       : num  0.162 0.124 0.144 0.21 0.137 ...
##  $ compactness_worst      : num  0.666 0.187 0.424 0.866 0.205 ...
##  $ concavity_worst        : num  0.712 0.242 0.45 0.687 0.4 ...
##  $ concave_points_worst   : num  0.265 0.186 0.243 0.258 0.163 ...
##  $ symmetry_worst         : num  0.46 0.275 0.361 0.664 0.236 ...
##  $ fractal_dimension_worst: num  0.1189 0.089 0.0876 0.173 0.0768 ...
head(cancer_mama)
##   diagnosis radius_mean texture_mean perimeter_mean area_mean smoothness_mean
## 1         M       17.99        10.38         122.80    1001.0         0.11840
## 2         M       20.57        17.77         132.90    1326.0         0.08474
## 3         M       19.69        21.25         130.00    1203.0         0.10960
## 4         M       11.42        20.38          77.58     386.1         0.14250
## 5         M       20.29        14.34         135.10    1297.0         0.10030
## 6         M       12.45        15.70          82.57     477.1         0.12780
##   compactness_mean concavity_mean concave_points_mean symmetry_mean
## 1          0.27760         0.3001             0.14710        0.2419
## 2          0.07864         0.0869             0.07017        0.1812
## 3          0.15990         0.1974             0.12790        0.2069
## 4          0.28390         0.2414             0.10520        0.2597
## 5          0.13280         0.1980             0.10430        0.1809
## 6          0.17000         0.1578             0.08089        0.2087
##   fractal_dimension_mean radius_se texture_se perimeter_se area_se
## 1                0.07871    1.0950     0.9053        8.589  153.40
## 2                0.05667    0.5435     0.7339        3.398   74.08
## 3                0.05999    0.7456     0.7869        4.585   94.03
## 4                0.09744    0.4956     1.1560        3.445   27.23
## 5                0.05883    0.7572     0.7813        5.438   94.44
## 6                0.07613    0.3345     0.8902        2.217   27.19
##   smoothness_se compactness_se concavity_se concave_points_se symmetry_se
## 1      0.006399        0.04904      0.05373           0.01587     0.03003
## 2      0.005225        0.01308      0.01860           0.01340     0.01389
## 3      0.006150        0.04006      0.03832           0.02058     0.02250
## 4      0.009110        0.07458      0.05661           0.01867     0.05963
## 5      0.011490        0.02461      0.05688           0.01885     0.01756
## 6      0.007510        0.03345      0.03672           0.01137     0.02165
##   fractal_dimension_se radius_worst texture_worst perimeter_worst area_worst
## 1             0.006193        25.38         17.33          184.60     2019.0
## 2             0.003532        24.99         23.41          158.80     1956.0
## 3             0.004571        23.57         25.53          152.50     1709.0
## 4             0.009208        14.91         26.50           98.87      567.7
## 5             0.005115        22.54         16.67          152.20     1575.0
## 6             0.005082        15.47         23.75          103.40      741.6
##   smoothness_worst compactness_worst concavity_worst concave_points_worst
## 1           0.1622            0.6656          0.7119               0.2654
## 2           0.1238            0.1866          0.2416               0.1860
## 3           0.1444            0.4245          0.4504               0.2430
## 4           0.2098            0.8663          0.6869               0.2575
## 5           0.1374            0.2050          0.4000               0.1625
## 6           0.1791            0.5249          0.5355               0.1741
##   symmetry_worst fractal_dimension_worst
## 1         0.4601                 0.11890
## 2         0.2750                 0.08902
## 3         0.3613                 0.08758
## 4         0.6638                 0.17300
## 5         0.2364                 0.07678
## 6         0.3985                 0.12440

Crear árbol de decisión

#cancer_mama$survived <- as.factor(titanic$survived)
#cancer_mama$pclass <- as.factor(titanic$pclass)
#cancer_mama$sex <- as.factor(titanic$sex)

arbol_cancer_mama <- rpart(diagnosis~., data=cancer_mama)
rpart.plot(arbol_cancer_mama)

prp(arbol_cancer_mama, extra=7, prefix="fracción/n")

Alimentar con ejemplos

cancer_mama <- read.csv("/Users/humbertocs/Desktop/Tec/Concentración IA/M2_Programacion R IA/RedesNeuronales/cancer_de_mama.csv")

Entender la base de datos

#summary(cancer_mama)

str(cancer_mama)
## 'data.frame':    569 obs. of  31 variables:
##  $ diagnosis              : chr  "M" "M" "M" "M" ...
##  $ radius_mean            : num  18 20.6 19.7 11.4 20.3 ...
##  $ texture_mean           : num  10.4 17.8 21.2 20.4 14.3 ...
##  $ perimeter_mean         : num  122.8 132.9 130 77.6 135.1 ...
##  $ area_mean              : num  1001 1326 1203 386 1297 ...
##  $ smoothness_mean        : num  0.1184 0.0847 0.1096 0.1425 0.1003 ...
##  $ compactness_mean       : num  0.2776 0.0786 0.1599 0.2839 0.1328 ...
##  $ concavity_mean         : num  0.3001 0.0869 0.1974 0.2414 0.198 ...
##  $ concave_points_mean    : num  0.1471 0.0702 0.1279 0.1052 0.1043 ...
##  $ symmetry_mean          : num  0.242 0.181 0.207 0.26 0.181 ...
##  $ fractal_dimension_mean : num  0.0787 0.0567 0.06 0.0974 0.0588 ...
##  $ radius_se              : num  1.095 0.543 0.746 0.496 0.757 ...
##  $ texture_se             : num  0.905 0.734 0.787 1.156 0.781 ...
##  $ perimeter_se           : num  8.59 3.4 4.58 3.44 5.44 ...
##  $ area_se                : num  153.4 74.1 94 27.2 94.4 ...
##  $ smoothness_se          : num  0.0064 0.00522 0.00615 0.00911 0.01149 ...
##  $ compactness_se         : num  0.049 0.0131 0.0401 0.0746 0.0246 ...
##  $ concavity_se           : num  0.0537 0.0186 0.0383 0.0566 0.0569 ...
##  $ concave_points_se      : num  0.0159 0.0134 0.0206 0.0187 0.0188 ...
##  $ symmetry_se            : num  0.03 0.0139 0.0225 0.0596 0.0176 ...
##  $ fractal_dimension_se   : num  0.00619 0.00353 0.00457 0.00921 0.00511 ...
##  $ radius_worst           : num  25.4 25 23.6 14.9 22.5 ...
##  $ texture_worst          : num  17.3 23.4 25.5 26.5 16.7 ...
##  $ perimeter_worst        : num  184.6 158.8 152.5 98.9 152.2 ...
##  $ area_worst             : num  2019 1956 1709 568 1575 ...
##  $ smoothness_worst       : num  0.162 0.124 0.144 0.21 0.137 ...
##  $ compactness_worst      : num  0.666 0.187 0.424 0.866 0.205 ...
##  $ concavity_worst        : num  0.712 0.242 0.45 0.687 0.4 ...
##  $ concave_points_worst   : num  0.265 0.186 0.243 0.258 0.163 ...
##  $ symmetry_worst         : num  0.46 0.275 0.361 0.664 0.236 ...
##  $ fractal_dimension_worst: num  0.1189 0.089 0.0876 0.173 0.0768 ...
# create_report(df)

plot_missing(cancer_mama)

plot_histogram(cancer_mama)

plot_correlation(cancer_mama)

cancer_mama$diagnosis <- ifelse(cancer_mama$diagnosis == "M", 1, 0)

Hacer sets de prueba y entrenamiento

# Normalmente 80-20
set.seed(123)
renglones_entrenamiento <- createDataPartition(cancer_mama$diagnosis, p=0.8, list = FALSE)

entrenamiento_2 <- cancer_mama[renglones_entrenamiento, ]
prueba_2 <- cancer_mama[-renglones_entrenamiento, ]

Plottear la red

red_neuronal_2 <- neuralnet(diagnosis~.,data=entrenamiento_2)
plot(red_neuronal_2, rep="best")

# Predecir con la Red Neuronal

prueba_2_variables_independientes <- prueba_2[, -which(names(prueba_2) == "diagnosis")]

prediccion <- compute(red_neuronal_2, prueba_2_variables_independientes)
prediccion$net.result
##          [,1]
## 1   0.3486923
## 9   0.3486923
## 15  0.3486923
## 17  0.3486923
## 18  0.3486923
## 28  0.3486923
## 35  0.3486923
## 44  0.3486923
## 46  0.3486923
## 56  0.3486923
## 58  0.3486923
## 60  0.3486923
## 65  0.3486923
## 68  0.3486923
## 71  0.3486923
## 79  0.3486923
## 82  0.3486923
## 86  0.3486923
## 95  0.3486923
## 99  0.3486923
## 101 0.3486923
## 109 0.3486923
## 124 0.3486923
## 133 0.3486923
## 138 0.3486923
## 140 0.3486923
## 142 0.3486923
## 157 0.3486923
## 162 0.3486923
## 171 0.3486923
## 173 0.3486923
## 183 0.3486923
## 188 0.3486923
## 189 0.3486923
## 193 0.3486923
## 201 0.3486923
## 203 0.3486923
## 206 0.3486923
## 207 0.3486923
## 216 0.3486923
## 220 0.3486923
## 227 0.3486923
## 233 0.3486923
## 240 0.3486923
## 242 0.3486923
## 247 0.3486923
## 251 0.3486923
## 256 0.3486923
## 259 0.3486923
## 261 0.3486923
## 262 0.3486923
## 275 0.3486923
## 284 0.3486923
## 293 0.3486923
## 296 0.3486923
## 303 0.3486923
## 305 0.3486923
## 317 0.3486923
## 318 0.3486923
## 320 0.3486923
## 323 0.3486923
## 329 0.3486923
## 332 0.3486923
## 340 0.3486923
## 341 0.3486923
## 352 0.3486923
## 354 0.3486923
## 358 0.3486923
## 359 0.3486923
## 369 0.3486923
## 370 0.3486923
## 371 0.3486923
## 375 0.3486923
## 386 0.3486923
## 387 0.3486923
## 394 0.3486923
## 400 0.3486923
## 405 0.3486923
## 407 0.3486923
## 412 0.3486923
## 417 0.3486923
## 418 0.3486923
## 429 0.3486923
## 432 0.3486923
## 434 0.3486923
## 437 0.3486923
## 453 0.3486923
## 454 0.3486923
## 466 0.3486923
## 481 0.3486923
## 484 0.3486923
## 487 0.3486923
## 492 0.3486923
## 510 0.3486923
## 515 0.3486923
## 518 0.3486923
## 520 0.3486923
## 522 0.3486923
## 529 0.3486923
## 531 0.3486923
## 532 0.3486923
## 541 0.3486923
## 545 0.3486923
## 547 0.3486923
## 551 0.3486923
## 554 0.3486923
## 556 0.3486923
## 557 0.3486923
## 558 0.3486923
## 560 0.3486923
## 561 0.3486923
## 562 0.3486923
## 564 0.3486923
probabilidad <- prediccion$net.result
resultado <- ifelse(probabilidad>0.5,1,0)
resultado
##     [,1]
## 1      0
## 9      0
## 15     0
## 17     0
## 18     0
## 28     0
## 35     0
## 44     0
## 46     0
## 56     0
## 58     0
## 60     0
## 65     0
## 68     0
## 71     0
## 79     0
## 82     0
## 86     0
## 95     0
## 99     0
## 101    0
## 109    0
## 124    0
## 133    0
## 138    0
## 140    0
## 142    0
## 157    0
## 162    0
## 171    0
## 173    0
## 183    0
## 188    0
## 189    0
## 193    0
## 201    0
## 203    0
## 206    0
## 207    0
## 216    0
## 220    0
## 227    0
## 233    0
## 240    0
## 242    0
## 247    0
## 251    0
## 256    0
## 259    0
## 261    0
## 262    0
## 275    0
## 284    0
## 293    0
## 296    0
## 303    0
## 305    0
## 317    0
## 318    0
## 320    0
## 323    0
## 329    0
## 332    0
## 340    0
## 341    0
## 352    0
## 354    0
## 358    0
## 359    0
## 369    0
## 370    0
## 371    0
## 375    0
## 386    0
## 387    0
## 394    0
## 400    0
## 405    0
## 407    0
## 412    0
## 417    0
## 418    0
## 429    0
## 432    0
## 434    0
## 437    0
## 453    0
## 454    0
## 466    0
## 481    0
## 484    0
## 487    0
## 492    0
## 510    0
## 515    0
## 518    0
## 520    0
## 522    0
## 529    0
## 531    0
## 532    0
## 541    0
## 545    0
## 547    0
## 551    0
## 554    0
## 556    0
## 557    0
## 558    0
## 560    0
## 561    0
## 562    0
## 564    0
LS0tCnRpdGxlOiAiUmVkZXMgTmV1cm9uYWxlcyIKYXV0aG9yOiAiSHVtYmVydG8gQ29ydMOpcyBTYWxkYcOxYSIKZGF0ZTogIjIwMjUtMDgtMjUiCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogVFJVRQogICAgdG9jX2Zsb2F0OiBUUlVFCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFCi0tLQoKCiFbXShodHRwczovL2VuY3J5cHRlZC10Ym4wLmdzdGF0aWMuY29tL2ltYWdlcz9xPXRibjpBTmQ5R2NRVkd0eS16b1ZITUFKZzBtSWpMeFVxamtlWGJDN3FUalpDUWcmcykKCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWU7Ij4gVGVvcsOtYSA8L3NwYW4+ClVuYSAqKlJlZCBOZXVyb25hbCBBcnRpZmljaWFsIChBTk4pKiogbW9kZWxhIGxhIHJlbGFjacOzbiBlbnRyZSB1biBjb25qdW50byBkZSBlbnRyYWRhcyB5IHVuYSBzYWxpZGEsIHJlc29sdmllbmRvIHVuIHBvcmJsZW1hIGRlIGFwcmVuZGl6YWplLgoKRWplbXBsb3MgcHLDoWN0aWNvcyBkZSBhcGxpY2FjacOzbiBkZSBSZWRlcyBOZXVyb25hbGVzIHNvbjoKCiogTGEgcmVjb21lbmRhY2nDs24gZGUgY29udGVuaWRvIGRlIE5ldGZsaXgKKiBFbCBmZWVkIGRlIEluc3RhZ3JhbSBvIFRpa3RvawoqIERldGVybWluYXIgZWwgbsO6bWVybyBvIGxldHJhIGVzY3JpdG8gYSBtYW5vCgojIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlOyI+IEluc3RhbGFyIHBhcXVldGVzIHkgbGxhbWFyIGxpYnJlcmlhIDwvc3Bhbj4KCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgaW5zdGFsbC5wYWNrYWdlcygibmV1cmFsbmV0IikKbGlicmFyeShuZXVyYWxuZXQpCgojaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpICMgR3LDoWZpY2EKbGlicmFyeShnZ3Bsb3QyKQojaW5zdGFsbC5wYWNrYWdlcygibGF0dGljZSIpICMgR3LDoWZpY2EKbGlicmFyeShsYXR0aWNlKQojaW5zdGFsbC5wYWNrYWdlcygiY2FyZXQiKSAjIEFsZ29yaXRtb3MgZGUgYXByZW5kaXphamUgYXV0b21hdGljbwpsaWJyYXJ5KGNhcmV0KQojaW5zdGFsbC5wYWNrYWdlcygiZGF0YXNldHMiKSAjIFVzYXIgYmFzZXMgZGUgZGF0b3MsIGVuIGVzdGUgY2FzbyBpcmlzCmxpYnJhcnkoZGF0YXNldHMpCiNpbnN0YWxsLnBhY2thZ2VzKCJEYXRhRXhwbG9yZXIiKSAjIEFuw6FsaXNpcyBFeHBsb3JhdG9yaW8KbGlicmFyeShEYXRhRXhwbG9yZXIpCiNpbnN0YWxsLnBhY2thZ2VzKCJrZXJubGFiIikKI2luc3RhbGwucGFja2FnZXMoImNsdXN0ZXIiKSAjQW7DoWxpc2lzIGRlIGFncnVwYW1pZW50bwpsaWJyYXJ5KGNsdXN0ZXIpCiNpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikgI0dyYWZpY2FyCmxpYnJhcnkoZ2dwbG90MikKI2luc3RhbGwucGFja2FnZXMoImRhdGEudGFibGUiKSAjIE1hbmVqbyBkZSBtdWNob3MgZGF0b3MKbGlicmFyeShkYXRhLnRhYmxlKQojaW5zdGFsbC5wYWNrYWdlcygiZmFjdG9leHRyYSIpICMgR3LDoWZpY2EgZGUgb3B0aW1pemFjacOzbiBkZSBuw7ptZXJvIGRlIGNsdXN0ZXJzCmxpYnJhcnkoZmFjdG9leHRyYSkKCiNpbnN0YWxsLnBhY2thZ2VzKCJycGFydCIpICMgR3LDoWZpY2EgZGUgb3B0aW1pemFjacOzbiBkZSBuw7ptZXJvIGRlIGNsdXN0ZXJzCmxpYnJhcnkocnBhcnQpCgojaW5zdGFsbC5wYWNrYWdlcygicnBhcnQucGxvdCIpICMgR3LDoWZpY2EgZGUgb3B0aW1pemFjacOzbiBkZSBuw7ptZXJvIGRlIGNsdXN0ZXJzCmxpYnJhcnkocnBhcnQucGxvdCkKCmBgYAojIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlOyI+IEFsaW1lbnRhciBjb24gZWplbXBsb3MgPC9zcGFuPgoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KCmV4YW1lbiA8LSBjKDIwLDEwLDMwLDIwLDgwLDMwKQpwcm95ZWN0byA8LSBjKDkwLDIwLDQwLDUwLDUwLDgwKQplc3RhdHVzIDwtIGMoMSwwLDAsMCwwLDEpCmRmIDwtIGRhdGEuZnJhbWUoZXhhbWVuLCBwcm95ZWN0byxlc3RhdHVzKQoKCmBgYAojIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlOyI+IFBsb3R0ZWFyIGxhIHJlZCA8L3NwYW4+CgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpyZWRfbmV1cm9uYWwgPC0gbmV1cmFsbmV0KGVzdGF0dXN+LixkYXRhPWRmKQpwbG90KHJlZF9uZXVyb25hbCwgcmVwPSJiZXN0IikKCmBgYAojIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlOyI+IFByZWRlY2lyIGNvbiBsYSBSZWQgTmV1cm9uYWwgPC9zcGFuPgoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KcHJ1ZWJhX2V4YW1lbiA8LSBjKDMwLDQwLDg1KQpwcnVlYmFfcHJveWVjdG8gPC0gYyg4NSw1MCw0MCkKcHJ1ZWJhIDwtIGRhdGEuZnJhbWUocHJ1ZWJhX2V4YW1lbiwgcHJ1ZWJhX3Byb3llY3RvKQpwcmVkaWNjaW9uIDwtIGNvbXB1dGUocmVkX25ldXJvbmFsLCBwcnVlYmEpCnByZWRpY2Npb24kbmV0LnJlc3VsdApwcm9iYWJpbGlkYWQgPC0gcHJlZGljY2lvbiRuZXQucmVzdWx0CnJlc3VsdGFkbyA8LSBpZmVsc2UocHJvYmFiaWxpZGFkPjAuNSwxLDApCnJlc3VsdGFkbwoKYGBgCgoKCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWU7Ij4gQ0FOQ0VSIE1BTUEgPC9zcGFuPgoKCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWU7Ij4gSW1wb3J0YXIgbGEgYmFzZSBkZSBkYXRvcyA8L3NwYW4+CmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmNhbmNlcl9tYW1hIDwtIHJlYWQuY3N2KCIvVXNlcnMvaHVtYmVydG9jcy9EZXNrdG9wL1RlYy9Db25jZW50cmFjacOzbiBJQS9NMl9Qcm9ncmFtYWNpb24gUiBJQS9SZWRlc05ldXJvbmFsZXMvY2FuY2VyX2RlX21hbWEuY3N2IikKYGBgCgojIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlOyI+IEVudGVuZGVyIGxhIGJhc2UgZGUgZGF0b3MgPC9zcGFuPgpgYGB7cn0Kc3VtbWFyeShjYW5jZXJfbWFtYSkKc3RyKGNhbmNlcl9tYW1hKQpoZWFkKGNhbmNlcl9tYW1hKQpgYGAKCgojIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlOyI+IENyZWFyIMOhcmJvbCBkZSBkZWNpc2nDs24gPC9zcGFuPgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQoKI2NhbmNlcl9tYW1hJHN1cnZpdmVkIDwtIGFzLmZhY3Rvcih0aXRhbmljJHN1cnZpdmVkKQojY2FuY2VyX21hbWEkcGNsYXNzIDwtIGFzLmZhY3Rvcih0aXRhbmljJHBjbGFzcykKI2NhbmNlcl9tYW1hJHNleCA8LSBhcy5mYWN0b3IodGl0YW5pYyRzZXgpCgphcmJvbF9jYW5jZXJfbWFtYSA8LSBycGFydChkaWFnbm9zaXN+LiwgZGF0YT1jYW5jZXJfbWFtYSkKcnBhcnQucGxvdChhcmJvbF9jYW5jZXJfbWFtYSkKcHJwKGFyYm9sX2NhbmNlcl9tYW1hLCBleHRyYT03LCBwcmVmaXg9ImZyYWNjacOzbi9uIikKCmBgYAoKCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWU7Ij4gQWxpbWVudGFyIGNvbiBlamVtcGxvcyA8L3NwYW4+CgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpjYW5jZXJfbWFtYSA8LSByZWFkLmNzdigiL1VzZXJzL2h1bWJlcnRvY3MvRGVza3RvcC9UZWMvQ29uY2VudHJhY2nDs24gSUEvTTJfUHJvZ3JhbWFjaW9uIFIgSUEvUmVkZXNOZXVyb25hbGVzL2NhbmNlcl9kZV9tYW1hLmNzdiIpCmBgYAoKIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZTsiPiBFbnRlbmRlciBsYSBiYXNlIGRlIGRhdG9zIDwvc3Bhbj4KYGBge3J9CiNzdW1tYXJ5KGNhbmNlcl9tYW1hKQoKc3RyKGNhbmNlcl9tYW1hKQojIGNyZWF0ZV9yZXBvcnQoZGYpCgpwbG90X21pc3NpbmcoY2FuY2VyX21hbWEpCnBsb3RfaGlzdG9ncmFtKGNhbmNlcl9tYW1hKQpwbG90X2NvcnJlbGF0aW9uKGNhbmNlcl9tYW1hKQoKY2FuY2VyX21hbWEkZGlhZ25vc2lzIDwtIGlmZWxzZShjYW5jZXJfbWFtYSRkaWFnbm9zaXMgPT0gIk0iLCAxLCAwKQoKYGBgCgoKIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZTsiPiBIYWNlciBzZXRzIGRlIHBydWViYSB5IGVudHJlbmFtaWVudG8gPC9zcGFuPgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBwYWdlZC5wcmludD1GQUxTRX0KIyBOb3JtYWxtZW50ZSA4MC0yMApzZXQuc2VlZCgxMjMpCnJlbmdsb25lc19lbnRyZW5hbWllbnRvIDwtIGNyZWF0ZURhdGFQYXJ0aXRpb24oY2FuY2VyX21hbWEkZGlhZ25vc2lzLCBwPTAuOCwgbGlzdCA9IEZBTFNFKQoKZW50cmVuYW1pZW50b18yIDwtIGNhbmNlcl9tYW1hW3Jlbmdsb25lc19lbnRyZW5hbWllbnRvLCBdCnBydWViYV8yIDwtIGNhbmNlcl9tYW1hWy1yZW5nbG9uZXNfZW50cmVuYW1pZW50bywgXQpgYGAKCgojIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlOyI+IFBsb3R0ZWFyIGxhIHJlZCA8L3NwYW4+CgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpyZWRfbmV1cm9uYWxfMiA8LSBuZXVyYWxuZXQoZGlhZ25vc2lzfi4sZGF0YT1lbnRyZW5hbWllbnRvXzIpCnBsb3QocmVkX25ldXJvbmFsXzIsIHJlcD0iYmVzdCIpCgpgYGAKIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZTsiPiBQcmVkZWNpciBjb24gbGEgUmVkIE5ldXJvbmFsIDwvc3Bhbj4KCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CgpwcnVlYmFfMl92YXJpYWJsZXNfaW5kZXBlbmRpZW50ZXMgPC0gcHJ1ZWJhXzJbLCAtd2hpY2gobmFtZXMocHJ1ZWJhXzIpID09ICJkaWFnbm9zaXMiKV0KCnByZWRpY2Npb24gPC0gY29tcHV0ZShyZWRfbmV1cm9uYWxfMiwgcHJ1ZWJhXzJfdmFyaWFibGVzX2luZGVwZW5kaWVudGVzKQpwcmVkaWNjaW9uJG5ldC5yZXN1bHQKcHJvYmFiaWxpZGFkIDwtIHByZWRpY2Npb24kbmV0LnJlc3VsdApyZXN1bHRhZG8gPC0gaWZlbHNlKHByb2JhYmlsaWRhZD4wLjUsMSwwKQpyZXN1bHRhZG8KCmBgYAoKCgo=