Teoría

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 tecnolgía que permite convertir imágenes de texto en texto editable.También es conocido como extracción de texto de imágenes.
2. 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.
3. Análisis Predictivo: Son las técnicas y modelos estadisticos para predecir resultados futuros. Los modelos más usados son el Random Forest, redes neuronales y regresiones.

Instalar paquetes y llamar librerías

#install.packages("tidyverse") #Data Wrangling
library(tidyverse)
#install.packages("tesseract") #OCR
library(tesseract)
#install.packages("magick") #PNG
library (magick)
#install.packages("officer") #Office(Word)
library(officer)
#install.packages("pdftools") #PDF
library(pdftools)
#install.packages(purrr) #Para la función map
library(purrr)
#install.packages("tm") #Text Mining
library(tm)
#install.packages("RColorBrewer") #Colores
library(RColorBrewer)
#install.packages("wordcloud") # Nube de Palabras
library(wordcloud)
#install.packages("topicmodels") #Modelos de Temas
library(topicmodels)
library(ggplot2)

1. Obtener datos mediante OCR

imagen1 <- image_read("C:\\Users\\Luis Rodriguez\\Downloads\\imagen1.PNG")
texto1 <- ocr(imagen1)
texto1
## [1] "Linear regression with one variable x is also known as univariate linear regression\nor simple linear regression. Simple linear regression is used to predict a single\noutput from a single input. This is an example of supervised learning, which means\nthat the data is labeled, i.e., the output values are known in the training data. Let us\nfit a line through the data using simple linear regression as shown in Fig. 4.1.\n"
doc1<- read_docx() # Crea un documentos de word en blanco
doc1 <- doc1 %>% body_add_par(texto1, style = "Normal") #Pega el texto en el word
print (doc1, target ="texto.docx") # Guarda el word en la computadora

Imagen en español PNG a texto en WORD

Consultar idiomas disponibles

imagen2 <- image_read("C:\\Users\\Luis Rodriguez\\Downloads\\imagen2.PNG")
tesseract_download("spa")
## [1] "C:\\Users\\Luis Rodriguez\\AppData\\Local\\tesseract5\\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 documentos de word en blanco
doc2 <- doc2 %>% body_add_par(texto2, style = "Normal") #Pega el texto en el word
print (doc2, target ="texto2.docx") # Guarda el word en la computadora

De PDF a texto en WORD

pdf1 <- pdf_convert("C:\\Users\\Luis Rodriguez\\Downloads\\pdf1.pdf", dpi = 600) %>% map(ocr)
## Converting page 1 to pdf1_1.png... done!
## Converting page 2 to pdf1_2.png... done!
## Converting page 3 to pdf1_3.png... done!
## Converting page 4 to pdf1_4.png... done!
## Converting page 5 to pdf1_5.png... done!
## Converting page 6 to pdf1_6.png... done!
## Converting page 7 to pdf1_7.png... done!
## Converting page 8 to pdf1_8.png... done!

Actividad 1. I have a dream

pdf2 <- pdf_convert("C:\\Users\\Luis Rodriguez\\Downloads\\eso3.pdf", dpi = 600) %>% map(ocr)
## Converting page 1 to eso3_1.png... done!
## Converting page 2 to eso3_2.png... done!
## Converting page 3 to eso3_3.png... done!
imagen3 <- ("C:\\Users\\Luis Rodriguez\\Documents\\eso3_1.png")
tesseract_download("spa")
## [1] "C:\\Users\\Luis Rodriguez\\AppData\\Local\\tesseract5\\tesseract5\\tessdata/spa.traineddata"
texto3 <- ocr(imagen3, engine = tesseract("spa"))


imagen4 <- ("C:\\Users\\Luis Rodriguez\\Documents\\eso3_2.png")
tesseract_download("spa")
## [1] "C:\\Users\\Luis Rodriguez\\AppData\\Local\\tesseract5\\tesseract5\\tessdata/spa.traineddata"
texto4 <- ocr(imagen4, engine = tesseract("spa"))

imagen5 <- ("C:\\Users\\Luis Rodriguez\\Documents\\eso3_3.png")
tesseract_download("spa")
## [1] "C:\\Users\\Luis Rodriguez\\AppData\\Local\\tesseract5\\tesseract5\\tessdata/spa.traineddata"
texto5 <- ocr(imagen5, engine = tesseract("spa"))

doc3<- read_docx() # Crea un documentos de word en blanco

doc3 <- doc3 %>%
  body_add_par(texto3, style = "Normal") %>%
  body_add_par(texto4, style = "Normal") %>%
  body_add_par(texto5, style = "Normal")

print (doc3, 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")

corpus <- Corpus(VectorSource(text))

corpus <- tm_map(corpus, content_transformer(tolower))
corpus <- tm_map(corpus, removePunctuation)
corpus <- tm_map(corpus, removeNumbers)
corpus <- tm_map(corpus, removeWords, stopwords("en"))
#corpus <- tm_map (corpus, removeWords, c("dream", "will"))

tdm <- TermDocumentMatrix(corpus)
m <- as.matrix(tdm)

frecuencia <- sort(rowSums(m), decreasing = TRUE)

frecuencia_df <- data.frame(word=names(frecuencia),freq =frecuencia)

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)

inspect(corpus)
## <<SimpleCorpus>>
## Metadata:  corpus specific: 1, document level (indexed): 0
## Content:  documents: 46
## 
##  [1]                                                                                                                                                                                                                                                                                                       
##  [2]   even though  face  difficulties  today  tomorrow  still   dream    dream deeply rooted   american dream                                                                                                                                                                                             
##  [3]                                                                                                                                                                                                                                                                                                       
##  [4]    dream  one day  nation will rise   live   true meaning   creed                                                                                                                                                                                                                                     
##  [5]                                                                                                                                                                                                                                                                                                       
##  [6]  hold  truths   selfevident   men  created equal                                                                                                                                                                                                                                                      
##  [7]                                                                                                                                                                                                                                                                                                       
##  [8]    dream  one day   red hills  georgia  sons  former slaves   sons  former slave owners will  able  sit  together   table  brotherhood                                                                                                                                                                
##  [9]                                                                                                                                                                                                                                                                                                       
## [10]    dream  one day even  state  mississippi  state sweltering   heat  injustice sweltering   heat  oppression will  transformed   oasis  freedom  justice                                                                                                                                              
## [11]                                                                                                                                                                                                                                                                                                       
## [12]    dream   four little children will one day live   nation   will   judged   color   skin    content   character                                                                                                                                                                                      
## [13]                                                                                                                                                                                                                                                                                                       
## [14]    dream today                                                                                                                                                                                                                                                                                        
## [15]                                                                                                                                                                                                                                                                                                       
## [16]    dream  one day   alabama   vicious racists   governor   lips dripping   words  interposition  nullification one day right   alabama little black boys  black girls will  able  join hands  little white boys  white girls  sisters  brothers                                                       
## [17]                                                                                                                                                                                                                                                                                                       
## [18]    dream today                                                                                                                                                                                                                                                                                        
## [19]                                                                                                                                                                                                                                                                                                       
## [20]    dream  one day every valley shall  exalted  every hill  mountain shall  made low  rough places will  made plain   crooked places will  made straight   glory   lord shall  revealed   flesh shall see  together                                                                                    
## [21]                                                                                                                                                                                                                                                                                                       
## [22]    hope     faith   go back   south                                                                                                                                                                                                                                                                   
## [23]                                                                                                                                                                                                                                                                                                       
## [24]   faith  will  able  hew    mountain  despair  stone  hope   faith  will  able  transform  jangling discords   nation   beautiful symphony  brotherhood   faith  will  able  work together  pray together  struggle together  go  jail together  stand   freedom together knowing   will  free one day
## [25]                                                                                                                                                                                                                                                                                                       
## [26]   will   day  will   day    god s children will  able  sing  new meaning                                                                                                                                                                                                                              
## [27]                                                                                                                                                                                                                                                                                                       
## [28]  country  tis  thee sweet land  liberty  thee  sing                                                                                                                                                                                                                                                   
## [29] land   fathers died land   pilgrim s pride                                                                                                                                                                                                                                                            
## [30]  every mountainside let freedom ring                                                                                                                                                                                                                                                                  
## [31]   america     great nation  must become true                                                                                                                                                                                                                                                          
## [32]   let freedom ring   prodigious hilltops  new hampshire                                                                                                                                                                                                                                               
## [33] let freedom ring   mighty mountains  new york                                                                                                                                                                                                                                                         
## [34] let freedom ring   heightening alleghenies  pennsylvania                                                                                                                                                                                                                                              
## [35] let freedom ring   snowcapped rockies  colorado                                                                                                                                                                                                                                                       
## [36] let freedom ring   curvaceous slopes  california                                                                                                                                                                                                                                                      
## [37]                                                                                                                                                                                                                                                                                                       
## [38]                                                                                                                                                                                                                                                                                                       
## [39] let freedom ring  stone mountain  georgia                                                                                                                                                                                                                                                             
## [40] let freedom ring  lookout mountain  tennessee                                                                                                                                                                                                                                                         
## [41] let freedom ring  every hill  molehill  mississippi                                                                                                                                                                                                                                                   
## [42]  every mountainside let freedom ring                                                                                                                                                                                                                                                                  
## [43]    happens   allow freedom ring   let  ring  every village  every hamlet  every state  every city  will  able  speed   day    god s children black men  white men jews  gentiles protestants  catholics will  able  join hands  sing   words   old negro spiritual                                    
## [44] free  last free  last                                                                                                                                                                                                                                                                                 
## [45]                                                                                                                                                                                                                                                                                                       
## [46] thank god almighty   free  last

Nube de palabras

# El procesamiento de datos antes de la nube de palabras es igual que en el Análisis 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, "RdPu"))

Ejercicio 2. Novela IT

#texto_sin_acentos <- iconv(text1, to = "ASCII // TRANSLIT")

texto_it <- readLines("C:\\Users\\Luis Rodriguez\\Downloads\\eso3-_1_.txt")

texto_it2 <- iconv(texto_it, to = "UTF-8", sub = "byte")

corpus1 <- Corpus(VectorSource(texto_it2))

corpus1 <- tm_map(corpus1, content_transformer(tolower)) # Pone todo en minúsculas
corpus1 <- tm_map(corpus1, removePunctuation) # Elimina puntuación
corpus1 <- tm_map(corpus1, removeNumbers) # Elimina números
corpus1 <- tm_map(corpus1, removeWords, stopwords("spanish")) # Elimina palabras que no hablen del tema

tdm1 <- TermDocumentMatrix(corpus1)
m1 <- as.matrix(tdm1)

frecuencia1 <- sort(rowSums(m1), decreasing = TRUE)

frecuencia_df1 <- data.frame(word=names(frecuencia1),freq =frecuencia1)

ggplot(head(frecuencia_df1,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 = "It", x = "Palabra", y = "Frecuencia") +
         ylim(0,35)

#inspect(corpus1)

Nube de Palabras

set.seed(123)
wordcloud(words=frecuencia_df1$word,freq=frecuencia_df1$freq, min.freq=2,
random.order=FALSE, colors = brewer.pal(8, "Blues"))

LS0tDQp0aXRsZTogIklUIFRleHQgTWluaW5nIg0KYXV0aG9yOiAiTHVpcyBNZW5kb3phIC0gQTAwODI5MDk5Ig0KZGF0ZTogIjIwMjQtMDItMjYiDQpvdXRwdXQ6IA0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogVFJVRQ0KICAgIHRvY19mbG9hdDogVFJVRQ0KICAgIGNvZGVfZG93bmxvYWQ6IFRSVUUNCiAgICB0aGVtZTogY29zbW8NCi0tLQ0KDQohW10oQzpcXFVzZXJzXFxMdWlzIFJvZHJpZ3VlelxcRG93bmxvYWRzXFxpdC5naWYpDQoNCiMgPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQ7Ij5UZW9yw61hPC9zcGFuPg0KTGEgKiptaW5lcsOtYSBkZSB0ZXh0byoqIChUTSkgZXMgZWwgcHJvY2VzbyBkZSBleHRyYWVyIGluZm9ybWFjacOzbiDDunRpbCwgcGF0cm9uZXMgbyBjb25vY2ltaWVudG8gZGUgdGV4dG9zIG5vIGVzdHJ1Y3R1cmFkb3MNCg0KQ29uc3RhIGRlIDMgZXRhcGFzOiAgIA0KMS4gT2J0ZW5lciBkYXRvczogRWwgcmVjb25vY2ltaWVudG8gw7NwdGljbyBkZSBjYXJhY3RlcmVzIChPQ1IpIGVzIHVuYSB0ZWNub2xnw61hIHF1ZSBwZXJtaXRlIGNvbnZlcnRpciBpbcOhZ2VuZXMgZGUgdGV4dG8gZW4gdGV4dG8gZWRpdGFibGUuVGFtYmnDqW4gZXMgY29ub2NpZG8gY29tbyAqKmV4dHJhY2Npw7NuIGRlIHRleHRvIGRlIGltw6FnZW5lcy4qKiAgDQoyLiBFeHBsb3JhciBkYXRvczogUmVwcmVzZW50YWNpw7NuIGdyw6FmaWNhIG8gdmlzdWFsIGRlIGxvcyBkYXRvcyBwYXJhIHN1IGludGVycHJldGFjacOzbi4gTG9zIG3DqXRvZG9zIG3DoXMgY29tdW5lcyBzb24gZWwgQW7DoWxpc2lzIGRlIFNlbnRpbWllbnRvcywgbGEgTnViZSBkZSBQYWxhYnJhcyB5IGVsIFRvcGljIE1vZGVsaW5nLiAgDQozLiBBbsOhbGlzaXMgUHJlZGljdGl2bzogU29uIGxhcyB0w6ljbmljYXMgeSBtb2RlbG9zIGVzdGFkaXN0aWNvcyBwYXJhIHByZWRlY2lyIHJlc3VsdGFkb3MgZnV0dXJvcy4gTG9zIG1vZGVsb3MgbcOhcyB1c2Fkb3Mgc29uIGVsIFJhbmRvbSBGb3Jlc3QsIHJlZGVzIG5ldXJvbmFsZXMgeSByZWdyZXNpb25lcy4gIA0KDQojIDxzcGFuIHN0eWxlPSJjb2xvcjogcmVkOyI+SW5zdGFsYXIgcGFxdWV0ZXMgeSBsbGFtYXIgbGlicmVyw61hczwvc3Bhbj4NCmBgYHtyIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFfQ0KI2luc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpICNEYXRhIFdyYW5nbGluZw0KbGlicmFyeSh0aWR5dmVyc2UpDQojaW5zdGFsbC5wYWNrYWdlcygidGVzc2VyYWN0IikgI09DUg0KbGlicmFyeSh0ZXNzZXJhY3QpDQojaW5zdGFsbC5wYWNrYWdlcygibWFnaWNrIikgI1BORw0KbGlicmFyeSAobWFnaWNrKQ0KI2luc3RhbGwucGFja2FnZXMoIm9mZmljZXIiKSAjT2ZmaWNlKFdvcmQpDQpsaWJyYXJ5KG9mZmljZXIpDQojaW5zdGFsbC5wYWNrYWdlcygicGRmdG9vbHMiKSAjUERGDQpsaWJyYXJ5KHBkZnRvb2xzKQ0KI2luc3RhbGwucGFja2FnZXMocHVycnIpICNQYXJhIGxhIGZ1bmNpw7NuIG1hcA0KbGlicmFyeShwdXJycikNCiNpbnN0YWxsLnBhY2thZ2VzKCJ0bSIpICNUZXh0IE1pbmluZw0KbGlicmFyeSh0bSkNCiNpbnN0YWxsLnBhY2thZ2VzKCJSQ29sb3JCcmV3ZXIiKSAjQ29sb3Jlcw0KbGlicmFyeShSQ29sb3JCcmV3ZXIpDQojaW5zdGFsbC5wYWNrYWdlcygid29yZGNsb3VkIikgIyBOdWJlIGRlIFBhbGFicmFzDQpsaWJyYXJ5KHdvcmRjbG91ZCkNCiNpbnN0YWxsLnBhY2thZ2VzKCJ0b3BpY21vZGVscyIpICNNb2RlbG9zIGRlIFRlbWFzDQpsaWJyYXJ5KHRvcGljbW9kZWxzKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KYGBgDQoNCiMgPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQ7Ij4xLiBPYnRlbmVyIGRhdG9zIG1lZGlhbnRlIE9DUjwvc3Bhbj4NCg0KDQpgYGB7ciBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRX0NCmltYWdlbjEgPC0gaW1hZ2VfcmVhZCgiQzpcXFVzZXJzXFxMdWlzIFJvZHJpZ3VlelxcRG93bmxvYWRzXFxpbWFnZW4xLlBORyIpDQp0ZXh0bzEgPC0gb2NyKGltYWdlbjEpDQp0ZXh0bzENCmRvYzE8LSByZWFkX2RvY3goKSAjIENyZWEgdW4gZG9jdW1lbnRvcyBkZSB3b3JkIGVuIGJsYW5jbw0KZG9jMSA8LSBkb2MxICU+JSBib2R5X2FkZF9wYXIodGV4dG8xLCBzdHlsZSA9ICJOb3JtYWwiKSAjUGVnYSBlbCB0ZXh0byBlbiBlbCB3b3JkDQpwcmludCAoZG9jMSwgdGFyZ2V0ID0idGV4dG8uZG9jeCIpICMgR3VhcmRhIGVsIHdvcmQgZW4gbGEgY29tcHV0YWRvcmENCmBgYA0KIyA8c3BhbiBzdHlsZT0iY29sb3I6IHJlZDsiPkltYWdlbiBlbiBlc3Bhw7FvbCBQTkcgYSB0ZXh0byBlbiBXT1JEPC9zcGFuPg0KDQpbQ29uc3VsdGFyIGlkaW9tYXMgZGlzcG9uaWJsZXNdKGh0dHBzOi8vdGVzc2VyYWN0LW9jci5naXRodWIuaW8vdGVzc2RvYy9EYXRhLUZpbGVzLWluLWRpZmZlcmVudC12ZXJzaW9ucy5odG1sKQ0KDQpgYGB7ciBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRX0NCmltYWdlbjIgPC0gaW1hZ2VfcmVhZCgiQzpcXFVzZXJzXFxMdWlzIFJvZHJpZ3VlelxcRG93bmxvYWRzXFxpbWFnZW4yLlBORyIpDQp0ZXNzZXJhY3RfZG93bmxvYWQoInNwYSIpDQp0ZXh0bzIgPC0gb2NyIChpbWFnZW4yLCBlbmdpbmUgPSB0ZXNzZXJhY3QoInNwYSIpKQ0KdGV4dG8yDQpkb2MyPC0gcmVhZF9kb2N4KCkgIyBDcmVhIHVuIGRvY3VtZW50b3MgZGUgd29yZCBlbiBibGFuY28NCmRvYzIgPC0gZG9jMiAlPiUgYm9keV9hZGRfcGFyKHRleHRvMiwgc3R5bGUgPSAiTm9ybWFsIikgI1BlZ2EgZWwgdGV4dG8gZW4gZWwgd29yZA0KcHJpbnQgKGRvYzIsIHRhcmdldCA9InRleHRvMi5kb2N4IikgIyBHdWFyZGEgZWwgd29yZCBlbiBsYSBjb21wdXRhZG9yYQ0KYGBgDQojIDxzcGFuIHN0eWxlPSJjb2xvcjogcmVkOyI+RGUgUERGIGEgdGV4dG8gZW4gV09SRDwvc3Bhbj4NCmBgYHtyIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFfQ0KcGRmMSA8LSBwZGZfY29udmVydCgiQzpcXFVzZXJzXFxMdWlzIFJvZHJpZ3VlelxcRG93bmxvYWRzXFxwZGYxLnBkZiIsIGRwaSA9IDYwMCkgJT4lIG1hcChvY3IpDQpgYGANCg0KIyA8c3BhbiBzdHlsZT0iY29sb3I6IHJlZDsiPkFjdGl2aWRhZCAxLiBJIGhhdmUgYSBkcmVhbSA8L3NwYW4+DQoNCmBgYHtyIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFfQ0KcGRmMiA8LSBwZGZfY29udmVydCgiQzpcXFVzZXJzXFxMdWlzIFJvZHJpZ3VlelxcRG93bmxvYWRzXFxlc28zLnBkZiIsIGRwaSA9IDYwMCkgJT4lIG1hcChvY3IpDQpgYGANCg0KDQpgYGB7ciBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRX0NCmltYWdlbjMgPC0gKCJDOlxcVXNlcnNcXEx1aXMgUm9kcmlndWV6XFxEb2N1bWVudHNcXGVzbzNfMS5wbmciKQ0KdGVzc2VyYWN0X2Rvd25sb2FkKCJzcGEiKQ0KdGV4dG8zIDwtIG9jcihpbWFnZW4zLCBlbmdpbmUgPSB0ZXNzZXJhY3QoInNwYSIpKQ0KDQoNCmltYWdlbjQgPC0gKCJDOlxcVXNlcnNcXEx1aXMgUm9kcmlndWV6XFxEb2N1bWVudHNcXGVzbzNfMi5wbmciKQ0KdGVzc2VyYWN0X2Rvd25sb2FkKCJzcGEiKQ0KdGV4dG80IDwtIG9jcihpbWFnZW40LCBlbmdpbmUgPSB0ZXNzZXJhY3QoInNwYSIpKQ0KDQppbWFnZW41IDwtICgiQzpcXFVzZXJzXFxMdWlzIFJvZHJpZ3VlelxcRG9jdW1lbnRzXFxlc28zXzMucG5nIikNCnRlc3NlcmFjdF9kb3dubG9hZCgic3BhIikNCnRleHRvNSA8LSBvY3IoaW1hZ2VuNSwgZW5naW5lID0gdGVzc2VyYWN0KCJzcGEiKSkNCg0KZG9jMzwtIHJlYWRfZG9jeCgpICMgQ3JlYSB1biBkb2N1bWVudG9zIGRlIHdvcmQgZW4gYmxhbmNvDQoNCmRvYzMgPC0gZG9jMyAlPiUNCiAgYm9keV9hZGRfcGFyKHRleHRvMywgc3R5bGUgPSAiTm9ybWFsIikgJT4lDQogIGJvZHlfYWRkX3Bhcih0ZXh0bzQsIHN0eWxlID0gIk5vcm1hbCIpICU+JQ0KICBib2R5X2FkZF9wYXIodGV4dG81LCBzdHlsZSA9ICJOb3JtYWwiKQ0KDQpwcmludCAoZG9jMywgdGFyZ2V0ID0iZXNvLmRvY3giKSAjIEd1YXJkYSBlbCB3b3JkIGVuIGxhIGNvbXB1dGFkb3JhDQpgYGANCg0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQ7Ij4yLiBFeHBsb3JhY2nDs24gZGUgZGF0b3MgPC9zcGFuPg0KDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQ7Ij5BbsOhbGlzaXMgZGUgRnJlY3VlbmNpYXMgPC9zcGFuPg0KDQpgYGB7ciBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRX0NCnRleHQgPC0gcmVhZExpbmVzKCJodHRwOi8vd3d3LnN0aGRhLmNvbS9zdGhkYS9SRG9jL2V4YW1wbGUtZmlsZXMvbWFydGluLWx1dGhlci1raW5nLWktaGF2ZS1hLWRyZWFtLXNwZWVjaC50eHQiKQ0KDQpjb3JwdXMgPC0gQ29ycHVzKFZlY3RvclNvdXJjZSh0ZXh0KSkNCg0KY29ycHVzIDwtIHRtX21hcChjb3JwdXMsIGNvbnRlbnRfdHJhbnNmb3JtZXIodG9sb3dlcikpDQpjb3JwdXMgPC0gdG1fbWFwKGNvcnB1cywgcmVtb3ZlUHVuY3R1YXRpb24pDQpjb3JwdXMgPC0gdG1fbWFwKGNvcnB1cywgcmVtb3ZlTnVtYmVycykNCmNvcnB1cyA8LSB0bV9tYXAoY29ycHVzLCByZW1vdmVXb3Jkcywgc3RvcHdvcmRzKCJlbiIpKQ0KI2NvcnB1cyA8LSB0bV9tYXAgKGNvcnB1cywgcmVtb3ZlV29yZHMsIGMoImRyZWFtIiwgIndpbGwiKSkNCg0KdGRtIDwtIFRlcm1Eb2N1bWVudE1hdHJpeChjb3JwdXMpDQptIDwtIGFzLm1hdHJpeCh0ZG0pDQoNCmZyZWN1ZW5jaWEgPC0gc29ydChyb3dTdW1zKG0pLCBkZWNyZWFzaW5nID0gVFJVRSkNCg0KZnJlY3VlbmNpYV9kZiA8LSBkYXRhLmZyYW1lKHdvcmQ9bmFtZXMoZnJlY3VlbmNpYSksZnJlcSA9ZnJlY3VlbmNpYSkNCg0KZ2dwbG90KGhlYWQoZnJlY3VlbmNpYV9kZiwxMCksIGFlcyh4PXJlb3JkZXIod29yZCwgLWZyZXEpLCB5PWZyZXEpKSArIA0KICAgICAgICAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCBmaWxsID0gImxpZ2h0Ymx1ZSIpICsNCiAgICAgICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBmcmVxKSwgdmp1c3QgPSAtMC41KSArDQogICAgICAgICBsYWJzKHRpdGxlPSJUT1AgMTAgcGFsYWJyYXMgbcOhcyBmcmVjdWVudGVzIiwNCnN1YnRpdGxlID0gIkRpc2N1cnNvICdJIGhhdmUgYSBEcmVhbScgZGUgTS5MIEtpbmciLCB4ID0gIlBhbGFicmEiLCB5ID0gIkZyZWN1ZW5jaWEiKSArDQogICAgICAgICB5bGltKDAsMjApDQogICAgICANCmluc3BlY3QoY29ycHVzKQ0KYGBgDQoNCg0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQ7Ij5OdWJlIGRlIHBhbGFicmFzIDwvc3Bhbj4NCg0KYGBge3J9DQojIEVsIHByb2Nlc2FtaWVudG8gZGUgZGF0b3MgYW50ZXMgZGUgbGEgbnViZSBkZSBwYWxhYnJhcyBlcyBpZ3VhbCBxdWUgZW4gZWwgQW7DoWxpc2lzIGRlIEZyZWN1ZW5jaWFzLCBkZXNkZSBpbXBvcnRhciBlbCB0ZXh0byBoYXN0YSBmcmVjdWVuY2lhX2RmDQoNCnNldC5zZWVkKDEyMykNCndvcmRjbG91ZCggd29yZHMgPSBmcmVjdWVuY2lhX2RmJHdvcmQsIGZyZXEgPSBmcmVjdWVuY2lhX2RmJGZyZXEsIG1pbi5mcmVxPTEscmFuZG9tLm9yZGVyPUZBTFNFLCBjb2xvcnMgPSBicmV3ZXIucGFsKDgsICJSZFB1IikpDQpgYGANCg0KDQojIDxzcGFuIHN0eWxlPSJjb2xvcjogcmVkOyI+RWplcmNpY2lvIDIuIE5vdmVsYSBJVDwvc3Bhbj4NCg0KYGBge3IgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0V9DQojdGV4dG9fc2luX2FjZW50b3MgPC0gaWNvbnYodGV4dDEsIHRvID0gIkFTQ0lJIC8vIFRSQU5TTElUIikNCg0KdGV4dG9faXQgPC0gcmVhZExpbmVzKCJDOlxcVXNlcnNcXEx1aXMgUm9kcmlndWV6XFxEb3dubG9hZHNcXGVzbzMtXzFfLnR4dCIpDQoNCnRleHRvX2l0MiA8LSBpY29udih0ZXh0b19pdCwgdG8gPSAiVVRGLTgiLCBzdWIgPSAiYnl0ZSIpDQoNCmNvcnB1czEgPC0gQ29ycHVzKFZlY3RvclNvdXJjZSh0ZXh0b19pdDIpKQ0KDQpjb3JwdXMxIDwtIHRtX21hcChjb3JwdXMxLCBjb250ZW50X3RyYW5zZm9ybWVyKHRvbG93ZXIpKSAjIFBvbmUgdG9kbyBlbiBtaW7DunNjdWxhcw0KY29ycHVzMSA8LSB0bV9tYXAoY29ycHVzMSwgcmVtb3ZlUHVuY3R1YXRpb24pICMgRWxpbWluYSBwdW50dWFjacOzbg0KY29ycHVzMSA8LSB0bV9tYXAoY29ycHVzMSwgcmVtb3ZlTnVtYmVycykgIyBFbGltaW5hIG7Dum1lcm9zDQpjb3JwdXMxIDwtIHRtX21hcChjb3JwdXMxLCByZW1vdmVXb3Jkcywgc3RvcHdvcmRzKCJzcGFuaXNoIikpICMgRWxpbWluYSBwYWxhYnJhcyBxdWUgbm8gaGFibGVuIGRlbCB0ZW1hDQoNCnRkbTEgPC0gVGVybURvY3VtZW50TWF0cml4KGNvcnB1czEpDQptMSA8LSBhcy5tYXRyaXgodGRtMSkNCg0KZnJlY3VlbmNpYTEgPC0gc29ydChyb3dTdW1zKG0xKSwgZGVjcmVhc2luZyA9IFRSVUUpDQoNCmZyZWN1ZW5jaWFfZGYxIDwtIGRhdGEuZnJhbWUod29yZD1uYW1lcyhmcmVjdWVuY2lhMSksZnJlcSA9ZnJlY3VlbmNpYTEpDQoNCmdncGxvdChoZWFkKGZyZWN1ZW5jaWFfZGYxLDEwKSwgYWVzKHg9cmVvcmRlcih3b3JkLCAtZnJlcSksIHk9ZnJlcSkpICsgDQogICAgICAgICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsIGZpbGwgPSAibGlnaHRibHVlIikgKw0KICAgICAgICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGZyZXEpLCB2anVzdCA9IC0wLjUpICsNCiAgICAgICAgIGxhYnModGl0bGU9IlRPUCAxMCBwYWxhYnJhcyBtw6FzIGZyZWN1ZW50ZXMiLA0Kc3VidGl0bGUgPSAiSXQiLCB4ID0gIlBhbGFicmEiLCB5ID0gIkZyZWN1ZW5jaWEiKSArDQogICAgICAgICB5bGltKDAsMzUpDQogICAgICANCiNpbnNwZWN0KGNvcnB1czEpDQpgYGANCg0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQ7Ij5OdWJlIGRlIFBhbGFicmFzPC9zcGFuPg0KYGBge3IgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UgfQ0Kc2V0LnNlZWQoMTIzKQ0Kd29yZGNsb3VkKHdvcmRzPWZyZWN1ZW5jaWFfZGYxJHdvcmQsZnJlcT1mcmVjdWVuY2lhX2RmMSRmcmVxLCBtaW4uZnJlcT0yLA0KcmFuZG9tLm9yZGVyPUZBTFNFLCBjb2xvcnMgPSBicmV3ZXIucGFsKDgsICJCbHVlcyIpKQ0KYGBgDQoNCg==