Teoria

La minería de texto (TM) es el proceso de extraer información útil, patrones o conocimiento de textos no estructurados.

Consta de 3 etapas:

    1. Obtener datos: El reconocimiento óptico de caracteres (OCR) es una tecnología que permite convertir imágenes de texto en texto editable. También conocido como extracción de texto de imagenes..
    1. Explorar datos: Representación gráfica o visual de los datos para su interpretación. Los métodos más comunes son el Análisis de Sentimientos, la Nube de Palabras y el Topic Modeling.
    1. Análisis predictivo: Son las técnicas y modelos estadísticos para predecir resultados futuros. Los modelos más usados son el Random Forest, redes neuronales y regresiones.

Instalar paquetes y llamar librerias

library(tidyverse) # (data wrangling) manejo de tablas, aplicar filtros, hacer resumen
library(tesseract) # Generar OCR
library(magick) # Trabajar con imagenes de formato "PNG"
library(officer) # Exportar a formatos "Office" (word, powerpoint, etc)
library(pdftools) # Trabajar con PDF's
library(purrr) # Para la función map, (no funcion para hacer mapas)
library(tm) # Text Mining
library(RColorBrewer) # Manejar Colores
library(wordcloud) # Nubes de palabras
library(topicmodels) # Modelos de temas
library(ggplot2) # gráficas

1. OCR

Obtener Datos Mediante OCR

imagen1 <- image_read("/Users/marcelotam/Desktop/concentracion AI/M2/imagen1.PNG")
texto1 <- ocr(imagen1)
doc1 <- read_docx() # Crea un documento de Word en blanco.
doc1 <- doc1 %>% body_add_par(texto1, style = "Normal") # Pega el texto en el word
#print(doc1, target = "texto1.docx") # Guarda el word en la computadora

Imagen en español PNG a texto en WORD

Consultar idiomas

imagen2 <- image_read("/Users/marcelotam/Desktop/concentracion AI/M2/imagen2.PNG")
tesseract_download("spa")
## [1] "/Users/marcelotam/Library/Application Support/tesseract5/tessdata/spa.traineddata"
texto2 <- ocr(imagen2, engine = tesseract("spa"))
texto2
## [1] "Un importante, y quizá controversial, asunto político es el que se refiere al efecto del salario mínimo sobre\nlas tasas de desempleo en diversos grupos de trabajadores. Aunque este problema puede ser estudiado con\ndiversos tipos de datos (corte transversal, series de tiempo o datos de panel), suelen usarse las series de\ntiempo para observar los efectos agregados. En la tabla 1.3 se presenta un ejemplo de una base de datos\nde series de tiempo sobre tasas de desempleo y salarios mínimos.\n"
doc2 <- read_docx() # Crea un documento de Word en blanco.
doc2 <- doc2 %>% body_add_par(texto2, style = "Normal") # Pega el texto en el word
#print(doc2, target = "texto1.docx") # Guarda el word en la computadora

De PDF a imágenes

#pdf1 <- pdf_convert("/Users/marcelotam/Desktop/concentracion AI/M2/pdf1.pdf", dpi = 600) %>% map(ocr)

Actividad 1. Novela IT

#eso_pags <- pdf_convert("/Users/marcelotam/Desktop/concentracion AI/M2/eso3.pdf", dpi = 600) %>% map(ocr)
# repetir pasos previos para convertir imágenes a texto en WORD
it1 <- image_read("/Users/marcelotam/Desktop/concentracion AI/M2/eso3_1.png")
it2 <- image_read("/Users/marcelotam/Desktop/concentracion AI/M2/eso3_2.png")
it3 <- image_read("/Users/marcelotam/Desktop/concentracion AI/M2/eso3_3.png")

tesseract_download("spa")
## [1] "/Users/marcelotam/Library/Application Support/tesseract5/tessdata/spa.traineddata"
it_1 <- ocr(it1, engine = tesseract("spa"))
it_2 <- ocr(it2, engine = tesseract("spa"))
it_3 <- ocr(it3, engine = tesseract("spa"))

eso_word <- read_docx() # Crea un documento de Word en blanco.
eso_word <- eso_word %>% body_add_par(it_1, style = "Normal") %>% body_add_par(it_2, style = "Normal") %>% body_add_par(it_3, style = "Normal") # Pega el texto en el word
# print(eso_word, target = "eso.docx") # Guarda el word en la computadora

2. Exploración de Datos

Análisis de Frecuencias

text <- readLines("http://www.sthda.com/sthda/RDoc/example-files/martin-luther-king-i-have-a-dream-speech.txt") # Traer texto de internet

corpus <- Corpus(VectorSource(text)) # Pone cada renglón en una celda de vector
#inspect(corpus) # inspeccionar el texto
corpus <- tm_map(corpus, content_transformer(tolower)) # Pone todo en minúsculas
## Warning in tm_map.SimpleCorpus(corpus, content_transformer(tolower)):
## transformation drops documents
corpus <- tm_map(corpus, removePunctuation) # Elimina puntuación
## Warning in tm_map.SimpleCorpus(corpus, removePunctuation): transformation drops
## documents
corpus <- tm_map(corpus, removeNumbers) # Elimina números
## Warning in tm_map.SimpleCorpus(corpus, removeNumbers): transformation drops
## documents
#inspect(corpus)
corpus <- tm_map(corpus, removeWords, stopwords("en")) # Elimina palabras que no hablan del tema
## Warning in tm_map.SimpleCorpus(corpus, removeWords, stopwords("en")):
## transformation drops documents
# corpus <- tm_map(corpus, removeWords, c("palabra","palabra")) # Elimina palabras específicas
# inspect(corpus) # para ir revisando los cambios

tdm <- TermDocumentMatrix(corpus)
m <- as.matrix(tdm) # Cuenta las veces que aparece cada palabra por reglón
frecuencia <- sort(rowSums(m), decreasing = TRUE) # Cuenta la frecuencia de cada palabra en el texto completo
frecuencia_df <- data.frame(word=names(frecuencia), freq=frecuencia)
frecuencia_df # Convierte la frecuencia en un data frame
##                        word freq
## will                   will   17
## freedom             freedom   13
## ring                   ring   12
## dream                 dream   11
## day                     day   11
## let                     let   11
## every                 every    9
## one                     one    8
## able                   able    8
## together           together    7
## nation               nation    4
## mountain           mountain    4
## shall                 shall    4
## faith                 faith    4
## free                   free    4
## today                 today    3
## men                     men    3
## state                 state    3
## children           children    3
## little               little    3
## black                 black    3
## white                 white    3
## made                   made    3
## god                     god    3
## new                     new    3
## sing                   sing    3
## land                   land    3
## last                   last    3
## even                   even    2
## live                   live    2
## meaning             meaning    2
## true                   true    2
## brotherhood     brotherhood    2
## former               former    2
## georgia             georgia    2
## sons                   sons    2
## heat                   heat    2
## mississippi     mississippi    2
## sweltering       sweltering    2
## alabama             alabama    2
## boys                   boys    2
## girls                 girls    2
## hands                 hands    2
## join                   join    2
## words                 words    2
## hill                   hill    2
## places               places    2
## hope                   hope    2
## stone                 stone    2
## thee                   thee    2
## mountainside   mountainside    2
## american           american    1
## deeply               deeply    1
## difficulties   difficulties    1
## face                   face    1
## rooted               rooted    1
## still                 still    1
## though               though    1
## tomorrow           tomorrow    1
## creed                 creed    1
## rise                   rise    1
## created             created    1
## equal                 equal    1
## hold                   hold    1
## selfevident     selfevident    1
## truths               truths    1
## hills                 hills    1
## owners               owners    1
## red                     red    1
## sit                     sit    1
## slave                 slave    1
## slaves               slaves    1
## table                 table    1
## injustice         injustice    1
## justice             justice    1
## oasis                 oasis    1
## oppression       oppression    1
## transformed     transformed    1
## character         character    1
## color                 color    1
## content             content    1
## four                   four    1
## judged               judged    1
## skin                   skin    1
## brothers           brothers    1
## dripping           dripping    1
## governor           governor    1
## interposition interposition    1
## lips                   lips    1
## nullification nullification    1
## racists             racists    1
## right                 right    1
## sisters             sisters    1
## vicious             vicious    1
## crooked             crooked    1
## exalted             exalted    1
## flesh                 flesh    1
## glory                 glory    1
## lord                   lord    1
## low                     low    1
## plain                 plain    1
## revealed           revealed    1
## rough                 rough    1
## see                     see    1
## straight           straight    1
## valley               valley    1
## back                   back    1
## south                 south    1
## beautiful         beautiful    1
## despair             despair    1
## discords           discords    1
## hew                     hew    1
## jail                   jail    1
## jangling           jangling    1
## knowing             knowing    1
## pray                   pray    1
## stand                 stand    1
## struggle           struggle    1
## symphony           symphony    1
## transform         transform    1
## work                   work    1
## country             country    1
## liberty             liberty    1
## sweet                 sweet    1
## tis                     tis    1
## died                   died    1
## fathers             fathers    1
## pilgrim             pilgrim    1
## pride                 pride    1
## america             america    1
## become               become    1
## great                 great    1
## must                   must    1
## hampshire         hampshire    1
## hilltops           hilltops    1
## prodigious       prodigious    1
## mighty               mighty    1
## mountains         mountains    1
## york                   york    1
## alleghenies     alleghenies    1
## heightening     heightening    1
## pennsylvania   pennsylvania    1
## colorado           colorado    1
## rockies             rockies    1
## snowcapped       snowcapped    1
## california       california    1
## curvaceous       curvaceous    1
## slopes               slopes    1
## lookout             lookout    1
## tennessee         tennessee    1
## molehill           molehill    1
## allow                 allow    1
## catholics         catholics    1
## city                   city    1
## gentiles           gentiles    1
## hamlet               hamlet    1
## happens             happens    1
## jews                   jews    1
## negro                 negro    1
## old                     old    1
## protestants     protestants    1
## speed                 speed    1
## spiritual         spiritual    1
## village             village    1
## almighty           almighty    1
## thank                 thank    1
ggplot(head(frecuencia_df, 10), aes(x=reorder(word, -freq), y=freq)) + 
  geom_bar(stat= "identity", fill= "lightblue") + 
  geom_text(aes(label= freq), vjust = -0.5) + 
  labs(title = "Top 10 palabras más frecuentes", subtitle = "Discurso 'I have a Dream' de M. L. King", x = "Palabra", y="Frecuencia") + 
  ylim(0,20)

Nube de Palabras

# Eñ procedimiento de datos antes de la nube de palabras es igual que en el Análoisis de Frecuencias, desde importar el texto hasta frecuencia_df
set.seed(123)
wordcloud(words = frecuencia_df$word, freq = frecuencia_df$freq, min.freq = 1, random.order = FALSE, colors = brewer.pal(8, "OrRd"))

#tmaptools::palette_explorer()
# https://r-graph-gallery.com/38-rcolorbrewers-palettes.html paleta de colores de brewer pal

Actividad 2. Novela IT

text_eso <- readLines("/Users/marcelotam/Desktop/concentracion AI/M2/it.txt")

corpus2 <- Corpus(VectorSource(text_eso))
corpus2 <- tm_map(corpus2, content_transformer(tolower))
corpus2 <- tm_map(corpus2, removePunctuation)
corpus2 <- tm_map(corpus2, removeNumbers)
corpus2 <- tm_map(corpus2, removeWords, stopwords("spanish"))
inspect(corpus2) # para ir revisando los cambios
## <<SimpleCorpus>>
## Metadata:  corpus specific: 1, document level (indexed): 0
## Content:  documents: 154
## 
##   [1]  alli  persiguiendo  barco  papel   lado izquierdo  witcham street corría              
##   [2] deprisa   agua  ganaba   barquito  sacando ventaja oyó  rugido profundo                
##   [3] vio cómo cincuenta metros  adelante colina abajo  agua   cuneta  precipitaba           
##   [4] dentro   boca  tormenta  aún continuaba abierta   largo semicirculo oscuro             
##   [5] abierto   bordillo   acera  mientras george miraba  rama desgarrada   corteza          
##   [6] oscura  reluciente  hundió  aquellas fauces allí pendió   momento  luego  deslizó      
##   [7] hacia  interior hacia allí  encaminaba  bote                                           
##   [8]                                                                                        
##   [9] — ¡mierda —chilló horrorizado                                                          
##  [10]                                                                                        
##  [11] forzó  paso    momento pareció  iba  alcanzar  barquito     ples                       
##  [12] resbaló  george cayo despatarrado despellejándose  rodilla   grito  dolor              
##  [13] nueva perspectiva   altura  pavimento vio   barco giraba  redondo dos veces            
##  [14] momentáneamente atrapado   remolino   desaparecer                                      
##  [15]                                                                                        
##  [16] —¡mierda   mierda —volvió  chillar estrellando  puño   pavimento                       
##  [17]                                                                                        
##  [18]   dolió   echó  sollozar ¡ manera tan estupida  perder  barco                          
##  [19]                                                                                        
##  [20]  levantó  caminar hacia  boca  tormenta  allí  dejó caer  rodillas  mirar hacia        
##  [21]  interior  agua hacía  ruido hueco  húmedo  caer   oscuridad  sonido  daba             
##  [22] escalofrios hacía pensar                                                               
##  [23]                                                                                        
##  [24] —¡eh                                                                                   
##  [25]                                                                                        
##  [26]  exclamación   arrancada    cordel retrocedioó                                         
##  [27]                                                                                        
##  [28] allí adentro   ojos amarillos  tipo  ojos   siempre imaginaba  verlos                  
##  [29] nunca   oscuridad  sótano   animal —penso incoherente—     animal                      
##  [30] mejor  gato  quedó atrapado                                                            
##  [31]                                                                                        
##  [32]   modos   echar  correr habria corrido   dos segundos                                  
##  [33] tablero mental   hecho cargo  espanto   produjeron  dos ojos amarillos                 
##  [34] brillantes sintió  áspera superficie  pavimento bajo  dedos   fina lámina  agua fría   
##  [35]  corría alrededor  vio   mismo levantándose  retrocediendo   entonces                  
##  [36]  voz  voz perfectamente razonable  bastante simpática  habló  dentro                   
##  [37] boca  tormenta                                                                         
##  [38]                                                                                        
##  [39] —hola george —dijo                                                                     
##  [40]                                                                                        
##  [41] george parpadeo  volvió  mirar apenas podía dar crédito    vela    sacado              
##  [42]   cuento    película   sabe   animales hablan  bailan si                               
##  [43]  diez años   habria creido     viendo   tenia dieciséis años sino                      
##  [44] seis                                                                                   
##  [45]                                                                                        
##  [46]   boca  tormenta habia  payaso  luz distaba  ser buena  bastó                          
##  [47] george denbrough  seguro    vela   payaso    circo    tele                             
##  [48] parecia  mezcla  bozo  clarabell   hablaba haciendo sonar  bocina  howdy               
##  [49] doody  sábados   mañana búfalo bob   único  entendía  clarabell                        
##  [50] siempre hacia reir  george  cara  payaso metido   boca  tormenta  blanca tenia         
##  [51] cómicos mechones  pelo rojo  cada lado   calva   gran sonrisa  payaso pintada          
##  [52]                                                                                        
##  [53] alrededor   boca si george  vivido años después habria pensado  ronald                 
##  [54] mcdonald    bozo   clarabell                                                           
##  [55]                                                                                        
##  [56]  payaso    mano  manojo  globos    colores  tentadora fruta                            
##  [57] madura                                                                                 
##  [58]                                                                                        
##  [59]     barquito  papel  george                                                            
##  [60]                                                                                        
##  [61] —¿quieres  barquito georgie — payaso sonrela                                           
##  [62]                                                                                        
##  [63] george  sonrió  podía evitarlo aquella sonrisa   tipo   devuelve                       
##  [64] querer                                                                                 
##  [65]                                                                                        
##  [66] — supuesto                                                                             
##  [67]                                                                                        
##  [68]  payaso  echó  reir                                                                    
##  [69]                                                                                        
##  [70] —« supuesto» ¡así  gusta ¡así  gusta ¿  globo ¿  parece ¿quieres  globo”               
##  [71] —bueno   supuesto —alargó  mano   inmediato  retiró   voluntad—                        
##  [72] debo coger    ofrezca  desconocido  dice  papá                                         
##  [73]                                                                                        
##  [74] —  papa  mucha razón —replicó  payaso   boca  tormenta sonriendo george                
##  [75] preguntó cómo podia haber creido   ojos  amarillos si    color azul brillante          
##  [76] bailarin   ojos   mamá   bill — muchísima razón   creo    voy                          
##  [77] presentarme george   señor bob gray  conocido  pennywise  payaso                       
##  [78] ballarin pennywise  presento  george denbrough george  presento  pennywise  ahora      
##  [79]   conocemos     desconocido   tampoco ¿correcto                                        
##  [80]                                                                                        
##  [81] george soltó  risita                                                                   
##  [82]                                                                                        
##  [83] —correcto —volvió  estirar  mano   retirarla— ¿cómo  metiste alli adentro              
##  [84]                                                                                        
##  [85] — tormenta  trajo volaaaando —dijo pennywise  payaso bailarin—  llevó   circo          
##  [86] ¿ sientes olor  circo george                                                           
##  [87]                                                                                        
##  [88] george  inclinó hacia adelante ¡ pronto olía  cacahuetes ¡cacahuetes tostados ¡ vinagre
##  [89] blanco    pone   patatas fritas   agujero   tapa  olía  algodón                        
##  [90] azucar  buñuelos   leve  poderosamente  estiercol  animales salvajes olia              
##  [91] aroma regocijante  aserrin   embargo                                                   
##  [92]                                                                                        
##  [93]  embargo bajo   olía  inundación  hojas deshechas   oscuras sombras  bocas             
##  [94]  tormenta   olor húmedo  putrido  olor  sótano                                         
##  [95]                                                                                        
##  [96]    olores   fuertes                                                                    
##  [97]                                                                                        
##  [98] —claro   huelo —dlijo                                                                  
##  [99]                                                                                        
## [100] —¿quieres  barquito george —preguntó pennywise—   pregunto  vez                        
## [101] pareces desearlo                                                                       
## [102]                                                                                        
## [103]   mostró  alto sonriendo llevaba  traje  seda abolsado  grandes botones color          
## [104] naranja  corbata brillante  color azul eléctrico   derramaba   pechera                 
## [105] manos llevaba grandes guantes blancos  mickey  donald                                  
## [106]                                                                                        
## [107] —si claro —dijo george mirando dentro   boca  tormenta                                 
## [108]                                                                                        
## [109] —¿  globo   rojos verdes amarillos azules                                              
## [110]                                                                                        
## [111] —¿flotan                                                                               
## [112]                                                                                        
## [113] —¿ si flotan — sonrisa  payaso  acentuó— oh  claro   ¡flotan                           
## [114] algodón  azucar                                                                        
## [115]                                                                                        
## [116] george estiró  mano                                                                    
## [117]                                                                                        
## [118]  payaso  sujeto  brazo                                                                 
## [119]                                                                                        
## [120]  entonces george vio cómo  cara  payaso cambiaba                                       
## [121]                                                                                        
## [122]   vio entonces  tan terrible   peor   imaginado   cosa  sótano                         
## [123] parecía  dulce sueño   vio destruyó  cordura   zarpazo                                 
## [124]                                                                                        
## [125] —flotan —croó  cosa   alcantarilla   voz  reía   coágulos                              
## [126]                                                                                        
## [127] sujetaba  brazo  george   puño grueso  agusanado tiró   hacia  horrible                
## [128] oscuridad    agua corría  rugía  aullaba llevando hacia  mar  desechos                 
## [129] tormenta george estiró  cuello  apartarse   negrura definitiva  empezó  gritar hacia   
## [130]  lluvia  gritar   loco hacia  gris cielo otoñal   curvaba  derry aquel día             
## [131] otoño    gritos  agudos  penetrantes    largo  toda  calle  gente                      
## [132] asomó   ventanas   lanzó   porches                                                     
## [133]                                                                                        
## [134] —flotan —gruñó  cosa— flotan georgie    aqui abajo conmigo                             
## [135] flotarás                                                                               
## [136]                                                                                        
## [137]  hombro  george  clavó   cemento  bordillo dave gardener   día                         
## [138] habia ido  trabajar  shoeboat debido   inundación vio sólo   niño  impermeable         
## [139] amarillo  niño  gritaba   retorcia   arroyo mientras  agua lodosa  corría              
## [140] cara haciendo   alaridos sonaran burbujeantes                                          
## [141]                                                                                        
## [142] —aqui abajo  flota —susurró  voz podrida riendo   pronto sonó  desgarro                
## [143]  destello  agonía  george denbrough   supo                                             
## [144]                                                                                        
## [145] dave gardener   primero  llegar aunque llegó sólo cuarenta  cinco segundos después     
## [146]  primer grito george denbrough  habia muerto gardener  agarró   impermeable tiró       
## [147]    sacarlo   calle   girar   manos  cuerpo  george   empezó                            
## [148] gritar  lado izquierdo  impermeable  niño    rojo intenso  sangre fluía hacia          
## [149]  alcantarilla   agujero     brazo izquierdo  trozo  hueso                              
## [150] horriblemente brillante asomaba   tela rota                                            
## [151]                                                                                        
## [152]  ojos  niño miraban fijamente  cielo gris  mientras dave retrocedía  tropezones hacia  
## [153]     corrian   calle empezaron  llenarse  lluvia                                        
## [154]
corpus2 <- tm_map(corpus2, removeWords, c("!","¡","¿","-"))

tdm2 <- TermDocumentMatrix(corpus2)
m2 <- as.matrix(tdm2)
frecuencia_eso <- sort(rowSums(m2), decreasing = TRUE)
frecuenciaeso_df <- data.frame(word=names(frecuencia_eso), freq=frecuencia_eso)

frecuenciaeso_df <- frecuenciaeso_df[-7, ]

ggplot(head(frecuenciaeso_df, 10), aes(x=reorder(word, -freq), y=freq)) + 
  geom_bar(stat= "identity", fill= "lightyellow") + 
  geom_text(aes(label= freq), vjust = -0.5) + 
  labs(title = "Top 10 palabras más frecuentes", subtitle = "Pedazo Novela IT", x = "Palabra", y="Frecuencia")

set.seed(123)
wordcloud(words = frecuenciaeso_df$word, freq = frecuenciaeso_df$freq, min.freq = 3, random.order = FALSE, colors = brewer.pal(8, "Spectral"))

LS0tCnRpdGxlOiAiVGV4dCBNaW5pbmciCmF1dGhvcjogIk1hcmNlbG8gVGFtIEFyaWNhIC0gQTAxNzIyMTQwIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDogCiAgICB0b2M6IFRSVUUKICAgIHRvY19mbG9hdDogVFJVRQogICAgY29kZV9kb3dubG9hZDogVFJVRQogICAgdGhlbWU6IGpvdXJuYWwKLS0tCgohW10oL1VzZXJzL21hcmNlbG90YW0vRGVza3RvcC9jb25jZW50cmFjaW9uIEFJL00yL2l0LmdpZikKCiMgVGVvcmlhCgpMYSAqKm1pbmVyw61hIGRlIHRleHRvKiogKFRNKSBlcyBlbCBwcm9jZXNvIGRlIGV4dHJhZXIgaW5mb3JtYWNpw7NuIMO6dGlsLCBwYXRyb25lcyBvIGNvbm9jaW1pZW50byBkZSB0ZXh0b3Mgbm8gZXN0cnVjdHVyYWRvcy4KCkNvbnN0YSBkZSAzIGV0YXBhczoKCi0gMS4gIE9idGVuZXIgZGF0b3M6IEVsICoqcmVjb25vY2ltaWVudG8gw7NwdGljbyBkZSBjYXJhY3RlcmVzIChPQ1IpKiogZXMgdW5hIHRlY25vbG9nw61hIHF1ZSBwZXJtaXRlIGNvbnZlcnRpciBpbcOhZ2VuZXMgZGUgdGV4dG8gZW4gdGV4dG8gZWRpdGFibGUuIFRhbWJpw6luIGNvbm9jaWRvIGNvbW8gKipleHRyYWNjacOzbiBkZSB0ZXh0byBkZSBpbWFnZW5lcy4qKi4KCi0gMi4gIEV4cGxvcmFyIGRhdG9zOiBSZXByZXNlbnRhY2nDs24gZ3LDoWZpY2EgbyB2aXN1YWwgZGUgbG9zIGRhdG9zIHBhcmEgc3UgaW50ZXJwcmV0YWNpw7NuLiBMb3MgbcOpdG9kb3MgbcOhcyBjb211bmVzIHNvbiBlbCBBbsOhbGlzaXMgZGUgU2VudGltaWVudG9zLCBsYSBOdWJlIGRlIFBhbGFicmFzIHkgZWwgVG9waWMgTW9kZWxpbmcuCgotIDMuICBBbsOhbGlzaXMgcHJlZGljdGl2bzogU29uIGxhcyB0w6ljbmljYXMgeSBtb2RlbG9zIGVzdGFkw61zdGljb3MgcGFyYSBwcmVkZWNpciByZXN1bHRhZG9zIGZ1dHVyb3MuIExvcyBtb2RlbG9zIG3DoXMgdXNhZG9zIHNvbiBlbCBSYW5kb20gRm9yZXN0LCByZWRlcyBuZXVyb25hbGVzIHkgcmVncmVzaW9uZXMuCgojIDxzcGFuIHN0eWxlPSJjb2xvcjpkYXJrcmVkOyI+SW5zdGFsYXIgcGFxdWV0ZXMgeSBsbGFtYXIgbGlicmVyaWFzPC9zcGFuPgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkgIyAoZGF0YSB3cmFuZ2xpbmcpIG1hbmVqbyBkZSB0YWJsYXMsIGFwbGljYXIgZmlsdHJvcywgaGFjZXIgcmVzdW1lbgpsaWJyYXJ5KHRlc3NlcmFjdCkgIyBHZW5lcmFyIE9DUgpsaWJyYXJ5KG1hZ2ljaykgIyBUcmFiYWphciBjb24gaW1hZ2VuZXMgZGUgZm9ybWF0byAiUE5HIgpsaWJyYXJ5KG9mZmljZXIpICMgRXhwb3J0YXIgYSBmb3JtYXRvcyAiT2ZmaWNlIiAod29yZCwgcG93ZXJwb2ludCwgZXRjKQpsaWJyYXJ5KHBkZnRvb2xzKSAjIFRyYWJhamFyIGNvbiBQREYncwpsaWJyYXJ5KHB1cnJyKSAjIFBhcmEgbGEgZnVuY2nDs24gbWFwLCAobm8gZnVuY2lvbiBwYXJhIGhhY2VyIG1hcGFzKQpsaWJyYXJ5KHRtKSAjIFRleHQgTWluaW5nCmxpYnJhcnkoUkNvbG9yQnJld2VyKSAjIE1hbmVqYXIgQ29sb3JlcwpsaWJyYXJ5KHdvcmRjbG91ZCkgIyBOdWJlcyBkZSBwYWxhYnJhcwpsaWJyYXJ5KHRvcGljbW9kZWxzKSAjIE1vZGVsb3MgZGUgdGVtYXMKbGlicmFyeShnZ3Bsb3QyKSAjIGdyw6FmaWNhcwpgYGAKCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmRhcmtyZWQ7Ij4xLiBPQ1I8L3NwYW4+CgojIyA8c3BhbiBzdHlsZT0iY29sb3I6ZGFya3JlZDsiPk9idGVuZXIgRGF0b3MgTWVkaWFudGUgT0NSPC9zcGFuPgpgYGB7cn0KaW1hZ2VuMSA8LSBpbWFnZV9yZWFkKCIvVXNlcnMvbWFyY2Vsb3RhbS9EZXNrdG9wL2NvbmNlbnRyYWNpb24gQUkvTTIvaW1hZ2VuMS5QTkciKQp0ZXh0bzEgPC0gb2NyKGltYWdlbjEpCmRvYzEgPC0gcmVhZF9kb2N4KCkgIyBDcmVhIHVuIGRvY3VtZW50byBkZSBXb3JkIGVuIGJsYW5jby4KZG9jMSA8LSBkb2MxICU+JSBib2R5X2FkZF9wYXIodGV4dG8xLCBzdHlsZSA9ICJOb3JtYWwiKSAjIFBlZ2EgZWwgdGV4dG8gZW4gZWwgd29yZAojcHJpbnQoZG9jMSwgdGFyZ2V0ID0gInRleHRvMS5kb2N4IikgIyBHdWFyZGEgZWwgd29yZCBlbiBsYSBjb21wdXRhZG9yYQpgYGAKCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjpkYXJrcmVkOyI+SW1hZ2VuIGVuIGVzcGHDsW9sIFBORyBhIHRleHRvIGVuIFdPUkQ8L3NwYW4+CltDb25zdWx0YXIgaWRpb21hc10oaHR0cHM6Ly90ZXNzZXJhY3Qtb2NyLmdpdGh1Yi5pby90ZXNzZG9jL0RhdGEtRmlsZXMtaW4tZGlmZmVyZW50LXZlcnNpb25zLmh0bWwpCmBgYHtyfQppbWFnZW4yIDwtIGltYWdlX3JlYWQoIi9Vc2Vycy9tYXJjZWxvdGFtL0Rlc2t0b3AvY29uY2VudHJhY2lvbiBBSS9NMi9pbWFnZW4yLlBORyIpCnRlc3NlcmFjdF9kb3dubG9hZCgic3BhIikKdGV4dG8yIDwtIG9jcihpbWFnZW4yLCBlbmdpbmUgPSB0ZXNzZXJhY3QoInNwYSIpKQp0ZXh0bzIKZG9jMiA8LSByZWFkX2RvY3goKSAjIENyZWEgdW4gZG9jdW1lbnRvIGRlIFdvcmQgZW4gYmxhbmNvLgpkb2MyIDwtIGRvYzIgJT4lIGJvZHlfYWRkX3Bhcih0ZXh0bzIsIHN0eWxlID0gIk5vcm1hbCIpICMgUGVnYSBlbCB0ZXh0byBlbiBlbCB3b3JkCiNwcmludChkb2MyLCB0YXJnZXQgPSAidGV4dG8xLmRvY3giKSAjIEd1YXJkYSBlbCB3b3JkIGVuIGxhIGNvbXB1dGFkb3JhCmBgYAoKIyMgPHNwYW4gc3R5bGU9ImNvbG9yOmRhcmtyZWQ7Ij5EZSBQREYgYSBpbcOhZ2VuZXM8L3NwYW4+CmBgYHtyfQojcGRmMSA8LSBwZGZfY29udmVydCgiL1VzZXJzL21hcmNlbG90YW0vRGVza3RvcC9jb25jZW50cmFjaW9uIEFJL00yL3BkZjEucGRmIiwgZHBpID0gNjAwKSAlPiUgbWFwKG9jcikKYGBgCgojIyA8c3BhbiBzdHlsZT0iY29sb3I6ZGFya3JlZDsiPkFjdGl2aWRhZCAxLiBOb3ZlbGEgSVQ8L3NwYW4+CmBgYHtyfQojZXNvX3BhZ3MgPC0gcGRmX2NvbnZlcnQoIi9Vc2Vycy9tYXJjZWxvdGFtL0Rlc2t0b3AvY29uY2VudHJhY2lvbiBBSS9NMi9lc28zLnBkZiIsIGRwaSA9IDYwMCkgJT4lIG1hcChvY3IpCiMgcmVwZXRpciBwYXNvcyBwcmV2aW9zIHBhcmEgY29udmVydGlyIGltw6FnZW5lcyBhIHRleHRvIGVuIFdPUkQKaXQxIDwtIGltYWdlX3JlYWQoIi9Vc2Vycy9tYXJjZWxvdGFtL0Rlc2t0b3AvY29uY2VudHJhY2lvbiBBSS9NMi9lc28zXzEucG5nIikKaXQyIDwtIGltYWdlX3JlYWQoIi9Vc2Vycy9tYXJjZWxvdGFtL0Rlc2t0b3AvY29uY2VudHJhY2lvbiBBSS9NMi9lc28zXzIucG5nIikKaXQzIDwtIGltYWdlX3JlYWQoIi9Vc2Vycy9tYXJjZWxvdGFtL0Rlc2t0b3AvY29uY2VudHJhY2lvbiBBSS9NMi9lc28zXzMucG5nIikKCnRlc3NlcmFjdF9kb3dubG9hZCgic3BhIikKaXRfMSA8LSBvY3IoaXQxLCBlbmdpbmUgPSB0ZXNzZXJhY3QoInNwYSIpKQppdF8yIDwtIG9jcihpdDIsIGVuZ2luZSA9IHRlc3NlcmFjdCgic3BhIikpCml0XzMgPC0gb2NyKGl0MywgZW5naW5lID0gdGVzc2VyYWN0KCJzcGEiKSkKCmVzb193b3JkIDwtIHJlYWRfZG9jeCgpICMgQ3JlYSB1biBkb2N1bWVudG8gZGUgV29yZCBlbiBibGFuY28uCmVzb193b3JkIDwtIGVzb193b3JkICU+JSBib2R5X2FkZF9wYXIoaXRfMSwgc3R5bGUgPSAiTm9ybWFsIikgJT4lIGJvZHlfYWRkX3BhcihpdF8yLCBzdHlsZSA9ICJOb3JtYWwiKSAlPiUgYm9keV9hZGRfcGFyKGl0XzMsIHN0eWxlID0gIk5vcm1hbCIpICMgUGVnYSBlbCB0ZXh0byBlbiBlbCB3b3JkCiMgcHJpbnQoZXNvX3dvcmQsIHRhcmdldCA9ICJlc28uZG9jeCIpICMgR3VhcmRhIGVsIHdvcmQgZW4gbGEgY29tcHV0YWRvcmEKYGBgCgojIDxzcGFuIHN0eWxlPSJjb2xvcjpkYXJrcmVkOyI+Mi4gRXhwbG9yYWNpw7NuIGRlIERhdG9zPC9zcGFuPgoKIyMgPHNwYW4gc3R5bGU9ImNvbG9yOmRhcmtyZWQ7Ij5BbsOhbGlzaXMgZGUgRnJlY3VlbmNpYXM8L3NwYW4+CmBgYHtyfQp0ZXh0IDwtIHJlYWRMaW5lcygiaHR0cDovL3d3dy5zdGhkYS5jb20vc3RoZGEvUkRvYy9leGFtcGxlLWZpbGVzL21hcnRpbi1sdXRoZXIta2luZy1pLWhhdmUtYS1kcmVhbS1zcGVlY2gudHh0IikgIyBUcmFlciB0ZXh0byBkZSBpbnRlcm5ldAoKY29ycHVzIDwtIENvcnB1cyhWZWN0b3JTb3VyY2UodGV4dCkpICMgUG9uZSBjYWRhIHJlbmdsw7NuIGVuIHVuYSBjZWxkYSBkZSB2ZWN0b3IKI2luc3BlY3QoY29ycHVzKSAjIGluc3BlY2Npb25hciBlbCB0ZXh0bwpjb3JwdXMgPC0gdG1fbWFwKGNvcnB1cywgY29udGVudF90cmFuc2Zvcm1lcih0b2xvd2VyKSkgIyBQb25lIHRvZG8gZW4gbWluw7pzY3VsYXMKY29ycHVzIDwtIHRtX21hcChjb3JwdXMsIHJlbW92ZVB1bmN0dWF0aW9uKSAjIEVsaW1pbmEgcHVudHVhY2nDs24KY29ycHVzIDwtIHRtX21hcChjb3JwdXMsIHJlbW92ZU51bWJlcnMpICMgRWxpbWluYSBuw7ptZXJvcwojaW5zcGVjdChjb3JwdXMpCmNvcnB1cyA8LSB0bV9tYXAoY29ycHVzLCByZW1vdmVXb3Jkcywgc3RvcHdvcmRzKCJlbiIpKSAjIEVsaW1pbmEgcGFsYWJyYXMgcXVlIG5vIGhhYmxhbiBkZWwgdGVtYQojIGNvcnB1cyA8LSB0bV9tYXAoY29ycHVzLCByZW1vdmVXb3JkcywgYygicGFsYWJyYSIsInBhbGFicmEiKSkgIyBFbGltaW5hIHBhbGFicmFzIGVzcGVjw61maWNhcwojIGluc3BlY3QoY29ycHVzKSAjIHBhcmEgaXIgcmV2aXNhbmRvIGxvcyBjYW1iaW9zCgp0ZG0gPC0gVGVybURvY3VtZW50TWF0cml4KGNvcnB1cykKbSA8LSBhcy5tYXRyaXgodGRtKSAjIEN1ZW50YSBsYXMgdmVjZXMgcXVlIGFwYXJlY2UgY2FkYSBwYWxhYnJhIHBvciByZWdsw7NuCmZyZWN1ZW5jaWEgPC0gc29ydChyb3dTdW1zKG0pLCBkZWNyZWFzaW5nID0gVFJVRSkgIyBDdWVudGEgbGEgZnJlY3VlbmNpYSBkZSBjYWRhIHBhbGFicmEgZW4gZWwgdGV4dG8gY29tcGxldG8KZnJlY3VlbmNpYV9kZiA8LSBkYXRhLmZyYW1lKHdvcmQ9bmFtZXMoZnJlY3VlbmNpYSksIGZyZXE9ZnJlY3VlbmNpYSkKZnJlY3VlbmNpYV9kZiAjIENvbnZpZXJ0ZSBsYSBmcmVjdWVuY2lhIGVuIHVuIGRhdGEgZnJhbWUKCmdncGxvdChoZWFkKGZyZWN1ZW5jaWFfZGYsIDEwKSwgYWVzKHg9cmVvcmRlcih3b3JkLCAtZnJlcSksIHk9ZnJlcSkpICsgCiAgZ2VvbV9iYXIoc3RhdD0gImlkZW50aXR5IiwgZmlsbD0gImxpZ2h0Ymx1ZSIpICsgCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD0gZnJlcSksIHZqdXN0ID0gLTAuNSkgKyAKICBsYWJzKHRpdGxlID0gIlRvcCAxMCBwYWxhYnJhcyBtw6FzIGZyZWN1ZW50ZXMiLCBzdWJ0aXRsZSA9ICJEaXNjdXJzbyAnSSBoYXZlIGEgRHJlYW0nIGRlIE0uIEwuIEtpbmciLCB4ID0gIlBhbGFicmEiLCB5PSJGcmVjdWVuY2lhIikgKyAKICB5bGltKDAsMjApCmBgYAoKIyMgPHNwYW4gc3R5bGU9ImNvbG9yOmRhcmtyZWQ7Ij5OdWJlIGRlIFBhbGFicmFzPC9zcGFuPgpgYGB7cn0KIyBFw7EgcHJvY2VkaW1pZW50byBkZSBkYXRvcyBhbnRlcyBkZSBsYSBudWJlIGRlIHBhbGFicmFzIGVzIGlndWFsIHF1ZSBlbiBlbCBBbsOhbG9pc2lzIGRlIEZyZWN1ZW5jaWFzLCBkZXNkZSBpbXBvcnRhciBlbCB0ZXh0byBoYXN0YSBmcmVjdWVuY2lhX2RmCnNldC5zZWVkKDEyMykKd29yZGNsb3VkKHdvcmRzID0gZnJlY3VlbmNpYV9kZiR3b3JkLCBmcmVxID0gZnJlY3VlbmNpYV9kZiRmcmVxLCBtaW4uZnJlcSA9IDEsIHJhbmRvbS5vcmRlciA9IEZBTFNFLCBjb2xvcnMgPSBicmV3ZXIucGFsKDgsICJPclJkIikpCiN0bWFwdG9vbHM6OnBhbGV0dGVfZXhwbG9yZXIoKQojIGh0dHBzOi8vci1ncmFwaC1nYWxsZXJ5LmNvbS8zOC1yY29sb3JicmV3ZXJzLXBhbGV0dGVzLmh0bWwgcGFsZXRhIGRlIGNvbG9yZXMgZGUgYnJld2VyIHBhbApgYGAKCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjpkYXJrcmVkOyI+QWN0aXZpZGFkIDIuIE5vdmVsYSBJVDwvc3Bhbj4KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KdGV4dF9lc28gPC0gcmVhZExpbmVzKCIvVXNlcnMvbWFyY2Vsb3RhbS9EZXNrdG9wL2NvbmNlbnRyYWNpb24gQUkvTTIvaXQudHh0IikKCmNvcnB1czIgPC0gQ29ycHVzKFZlY3RvclNvdXJjZSh0ZXh0X2VzbykpCmNvcnB1czIgPC0gdG1fbWFwKGNvcnB1czIsIGNvbnRlbnRfdHJhbnNmb3JtZXIodG9sb3dlcikpCmNvcnB1czIgPC0gdG1fbWFwKGNvcnB1czIsIHJlbW92ZVB1bmN0dWF0aW9uKQpjb3JwdXMyIDwtIHRtX21hcChjb3JwdXMyLCByZW1vdmVOdW1iZXJzKQpjb3JwdXMyIDwtIHRtX21hcChjb3JwdXMyLCByZW1vdmVXb3Jkcywgc3RvcHdvcmRzKCJzcGFuaXNoIikpCmluc3BlY3QoY29ycHVzMikgIyBwYXJhIGlyIHJldmlzYW5kbyBsb3MgY2FtYmlvcwpjb3JwdXMyIDwtIHRtX21hcChjb3JwdXMyLCByZW1vdmVXb3JkcywgYygiISIsIsKhIiwiwr8iLCItIikpCgp0ZG0yIDwtIFRlcm1Eb2N1bWVudE1hdHJpeChjb3JwdXMyKQptMiA8LSBhcy5tYXRyaXgodGRtMikKZnJlY3VlbmNpYV9lc28gPC0gc29ydChyb3dTdW1zKG0yKSwgZGVjcmVhc2luZyA9IFRSVUUpCmZyZWN1ZW5jaWFlc29fZGYgPC0gZGF0YS5mcmFtZSh3b3JkPW5hbWVzKGZyZWN1ZW5jaWFfZXNvKSwgZnJlcT1mcmVjdWVuY2lhX2VzbykKCmZyZWN1ZW5jaWFlc29fZGYgPC0gZnJlY3VlbmNpYWVzb19kZlstNywgXQoKZ2dwbG90KGhlYWQoZnJlY3VlbmNpYWVzb19kZiwgMTApLCBhZXMoeD1yZW9yZGVyKHdvcmQsIC1mcmVxKSwgeT1mcmVxKSkgKyAKICBnZW9tX2JhcihzdGF0PSAiaWRlbnRpdHkiLCBmaWxsPSAibGlnaHR5ZWxsb3ciKSArIAogIGdlb21fdGV4dChhZXMobGFiZWw9IGZyZXEpLCB2anVzdCA9IC0wLjUpICsgCiAgbGFicyh0aXRsZSA9ICJUb3AgMTAgcGFsYWJyYXMgbcOhcyBmcmVjdWVudGVzIiwgc3VidGl0bGUgPSAiUGVkYXpvIE5vdmVsYSBJVCIsIHggPSAiUGFsYWJyYSIsIHk9IkZyZWN1ZW5jaWEiKQoKc2V0LnNlZWQoMTIzKQp3b3JkY2xvdWQod29yZHMgPSBmcmVjdWVuY2lhZXNvX2RmJHdvcmQsIGZyZXEgPSBmcmVjdWVuY2lhZXNvX2RmJGZyZXEsIG1pbi5mcmVxID0gMywgcmFuZG9tLm9yZGVyID0gRkFMU0UsIGNvbG9ycyA9IGJyZXdlci5wYWwoOCwgIlNwZWN0cmFsIikpCmBgYAoK