TeorĂ­a

La mĂ­neria de texto (TM) es el proceso de extraer informaciĂłn Ăștil, patrones o conocimientos 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 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 metodos mås comunes son el Anålisis de Sentimientos, la Nube de Palabras y el Topic Modeling. 3. Anålisis predictivo: Son las tecnicas y modelos estadísticos para predecir resultados futuros. Los modelos mås usados son Random Forest, Redes Neuronales y Regressiones.

Instalar paquetes y llamar librerĂ­as

#Data Wrangling
library(tidyverse)

#OCR
#install.packages("tesseract")
library(tesseract)

#PNG
#install.packages("magick")
library(magick)

#Office (word)
#install.packages("officer")
library(officer)

#PDF
#install.packages("pdftools")
library(pdftools)

#Para la funciĂłn map para aplicar la funciĂłn a cada elemento de un vector 
#install.packages("purrr")
library(purrr)

#Text Mining
#install.packages("tm")
library(tm)

#Colores
#install.packages("RColorBrewer")
library(RColorBrewer)

#Nube de Palabras 
#install.packages("wordcloud")
library(wordcloud)

#Modelos de temas
#install.packages("topicmodels")
library(topicmodels)

#Graficas con mas diseño
#install.packages("ggplot2")
library(ggplot2)

Obtener datos mediante OCR

De imagen PNG a texto en WORD

imagen1 <- image_read("/Users/valeriacantulobo/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 documento de word en blanco
doc1 <- doc1 %>% body_add_par(texto1, style = "Normal") #Pego el texto en el word
print(doc1, target = "texto1.docx") #Guarda el word en la computadora

De imagen PNG en español a texto en WORD

Consultar idiomas disponibles

imagen2 <- image_read("/Users/valeriacantulobo/Downloads/imagen2.PNG")
tesseract_download("spa")
## [1] "/Users/valeriacantulobo/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") #Pego 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("/Users/valeriacantulobo/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. Novela “IT”

pdf2 <- pdf_convert("/Users/valeriacantulobo/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 = image_read("/Users/valeriacantulobo/eso3_1.png")
tesseract_download("spa")
## [1] "/Users/valeriacantulobo/Library/Application Support/tesseract5/tessdata/spa.traineddata"
texto3 <- ocr(imagen3, engine = tesseract("spa"))
texto3
## [1] "Y alli estaba, persiguiendo su barco de papel por el lado izquierdo de Witcham Street. CorrĂ­a\ndeprisa, pero el agua le ganaba y el barquito estaba sacando ventaja. OyĂł un rugido profundo y\nvio cĂłmo cincuenta metros mĂĄs adelante, colina abajo, el agua de la cuneta se precipitaba\ndentro de una boca de tormenta que aĂșn continuaba abierta. Era un largo semicirculo oscuro\nabierto en el bordillo de la acera y mientras George miraba, una rama desgarrada, con la corteza\noscura y reluciente se hundiĂł en aquellas fauces. AllĂ­ pendiĂł por un momento y luego se deslizĂł\nhacia el interior. Hacia allĂ­ se encaminaba su bote.\n\n— ÂĄMierda! —chillĂł horrorizado.\n\nForzĂł el paso y, por un momento, pareciĂł que iba a alcanzar al barquito. Pero uno de sus ples\nresbalĂł y George cayo despatarrado despellejĂĄndose la rodilla con un grito de dolor. Desde su\nnueva perspectiva, a la altura del pavimento, vio que su barco giraba en redondo dos veces,\nmomentĂĄneamente atrapado en otro remolino, antes de desaparecer.\n\n—|ÂĄMierda y mĂĄs mierda! —volviĂł a chillar, estrellando el puño contra el pavimento.\n\nEso tambiĂ©n doliĂł, y se echĂł a sollozar. ÂĄQuĂ© manera tan estupida de perder el barco!\n\nSe levantĂł para caminar hacia la boca de tormenta y allĂ­ se dejĂł caer de rodillas, para mirar hacia\nel interior. El agua hacĂ­a un ruido hueco y hĂșmedo al caer en la oscuridad. Ese sonido le daba\nescalofrios. HacĂ­a pensar en..\n\n—|ÂĄEh!\n\nLa exclamaciĂłn le fue arrancada como con un cordel. RetrocedioĂł.\n\nAllĂ­ adentro habĂ­a unos ojos amarillos. Ese tipo de ojos que el siempre imaginaba, sin verlos\nnunca, en la oscuridad del sĂłtano. Es un animal —penso, incoherente—,; eso es todo: un animal; a lo\nmejor un gato que quedĂł atrapado...\n\nDe todos modos, estaba por echar a correr; habria corrido uno o dos segundos, cuando su\ntablero mental se hubiera hecho cargo del espanto que le produjeron esos dos ojos amarillos y\nbrillantes. SintiĂł la ĂĄspera superficie del pavimento bajo los dedos y la fina lĂĄmina de agua frĂ­a\nque corrĂ­a alrededor. Se vio a sĂ­ mismo levantĂĄndose y retrocediendo. Y fue entonces cuando\nuna voz, una voz perfectamente razonable y bastante simpĂĄtica, le hablĂł desde dentro de la\nboca de tormenta:\n\n—Hola, George —dijo.\n\nGeorge parpadeo y volviĂł a mirar. Apenas podĂ­a dar crĂ©dito a lo que vela; era como algo sacado\nde un cuento o de una pelĂ­cula donde uno sabe que los animales hablan y bailan. Si hubiera\ntenido diez años mĂĄs, no habria creido en lo que estaba viendo; pero no tenia diecisĂ©is años, sino\nseis.\n\nEn la boca de tormenta habia un payaso. La luz distaba de ser buena, pero bastĂł para que\nGeorge Denbrough estuviese seguro de lo que vela. Era un payaso, como en el circo o en la tele.\nParecia una mezcla de Bozo y Clarabell, el que hablaba haciendo sonar su bocina en Howdy\nDoody, los sĂĄbados por la mañana. BĂșfalo Bob era el Ășnico que entendĂ­a a Clarabell, y eso\nsiempre hacia reir a George. La cara del payaso metido en la boca de tormenta era blanca; tenia\ncĂłmicos mechones de pelo rojo a cada lado de la calva y una gran sonrisa de payaso pintada\n"
doc3 <- read_docx()
doc3 <- doc3%>% body_add_par(texto3, style = "Normal")

imagen4 = image_read("/Users/valeriacantulobo/eso3_2.png")
texto4 <- ocr(imagen4, engine = tesseract("spa"))
texto4
## [1] "alrededor de la boca. Si George hubiese vivido años despuĂ©s, habria pensado en Ronald\nMcDonald antes que en Bozo o en Clarabell.\n\nEl payaso tenĂ­a en una mano un manojo de globos de todos los colores, como tentadora fruta\nmadura.\n\nEn la otra, el barquito de papel de George.\n\n—¿Quieres tu barquito, Georgie? —El payaso sonrela.\n\nGeorge tambiĂ©n sonriĂł. No podĂ­a evitarlo; aquella sonrisa era del tipo que uno devuelve sin\nquerer.\n\n—Por supuesto.\n\nEl payaso se echĂł a reir.\n\n—«Por supuesto». ÂĄAsĂ­ me gusta! ÂĄAsĂ­ me gusta! ÂżY un globo? ÂżQue te parece? ÂżQuieres un globo”\n—Bueno.. sĂ­, por supuesto. —AlargĂł la mano, pero de inmediato la retirĂł contra su voluntad—. No\ndebo coger nada que me ofrezca un desconocido. Lo dice mi papĂĄ.\n\n—Y tu papa tiene mucha razĂłn —replicĂł el payaso de la boca de tormenta sonriendo. George se\npreguntĂł cĂłmo podia haber creido que sus ojos eran amarillos, si eran de un color azul brillante,\nbailarin, como los ojos de su mamĂĄ y de Bill —. MuchĂ­sima razĂłn, ya lo creo. Por lo tanto, voy a\npresentarme. George, soy el señor Bob Gray, tambiĂ©n conocido como Pennywise, el payaso\nBallarin. Pennywise, te presento a George Denbrough. George, te presento a Pennywise. Y ahora\nya nos conocemos. Yo no soy un desconocido y tu tampoco. ÂżCorrecto?\n\nGeorge soltĂł una risita.\n\n—Correcto. —VolviĂł a estirar la mano.. y a retirarla—. ÂżCĂłmo te metiste alli adentro?\n\n—La tormenta me trajo volaaaando —dijo Pennywise, el payaso Bailarin—. Se llevĂł todo el circo.\nÂżNo sientes olor a circo, George?\n\nGeorge se inclinĂł hacia adelante. ÂĄDe pronto olĂ­a a cacahuetes! ÂĄCacahuetes tostados! ÂĄY vinagre\nblanco, del que se pone en las patatas fritas por un agujero de la tapa! Y olĂ­a a algodĂłn de\nazucar, a buñuelos, y tambiĂ©n, leve, pero poderosamente, a estiercol de animales salvajes. Olia el\naroma regocijante del aserrin. Y sin embargo..\n\nSin embargo, bajo todo eso olĂ­a a inundaciĂłn, a hojas deshechas y a oscuras sombras en bocas\nde tormenta. Era un olor hĂșmedo y putrido. El olor del sĂłtano.\n\nPero los otros olores eran mĂĄs fuertes.\n\n—Claro que lo huelo —dijo.\n\n—¿Quieres tu barquito, George? —preguntĂł Pennywise—. Te lo pregunto otra vez porque no\npareces desearlo mucho.\n"
doc3 <- doc3%>% body_add_par(texto4, style = "Normal")

imagen5 = image_read("/Users/valeriacantulobo/eso3_3.png")
texto5 <- ocr(imagen5, engine = tesseract("spa"))
texto5
## [1] "Y lo mostrĂł en alto, sonriendo. Llevaba un traje de seda abolsado con grandes botones color\nnaranja. Una corbata brillante, de color azul elĂ©ctrico, se le derramaba por la pechera. En las\nmanos llevaba grandes guantes blancos, como Mickey y Donald.\n\n—Si, claro —dijo George, mirando dentro de la boca de tormenta.\n\n—¿Y un globo? Los tengo rojos, verdes, amarillos, aZules..\n\n—¿Flotan?\n\n—¿Que si flotan? —La sonrisa del payaso se acentuó—. Oh, sĂ­, claro que sĂ­. ÂĄFlotan! TambiĂ©n tengo\nalgodĂłn de azucar.\n\nGeorge estirĂł la mano.\n\nEl payaso le sujeto el brazo.\n\nY entonces George vio cĂłmo la cara del payaso cambiaba.\n\nLo que vio entonces fue tan terrible que lo peor que habĂ­a imaginado sobre la cosa del sĂłtano\nparecĂ­a un dulce sueño. Lo que vio destruyĂł su cordura de un zarpazo.\n\n—Flotan —croĂł la cosa de la alcantarilla con una voz que reĂ­a como entre coĂĄgulos.\n\nSujetaba el brazo de George con su puño grueso y agusanado. TirĂł de Ă©l hacia esa horrible\noscuridad por donde el agua corrĂ­a y rugĂ­a y aullaba llevando hacia el mar los desechos de la\ntormenta. George estirĂł el cuello para apartarse de esa negrura definitiva y empezĂł a gritar hacia\nla lluvia, a gritar como un loco hacia el gris cielo otoñal que se curvaba sobre Derry aquel dĂ­a de\notoño de 1957. Sus gritos eran agudos y penetrantes y a lo largo de toda la calle, la gente se\nasomĂł a las ventanas o se lanzĂł a los porches.\n\n—Flotan —gruñó la cosa—, flotan, Georgie. Y cuando estĂ©s aqui abajo, conmigo, tĂș tambiĂ©n\nflotarĂĄs.\n\nEl hombro de George se clavĂł contra el cemento del bordillo. Dave Gardener, que ese dĂ­a no\nhabia ido a trabajar al Shoeboat debido a la inundaciĂłn, vio sĂłlo a un niño de impermeable\namarillo, un niño que gritaba y se retorcia en el arroyo mientras el agua lodosa le corrĂ­a sobre la\ncara haciendo que sus alaridos sonaran burbujeantes.\n\n—Aqui abajo todo flota —susurrĂł esa voz podrida, riendo, y de pronto sonĂł un desgarro y hubo\nun destello de agonĂ­a y George Denbrough ya no supo mĂĄs.\n\nDave Gardener fue el primero en llegar. Aunque llegĂł sĂłlo cuarenta y cinco segundos despuĂ©s\ndel primer grito, George Denbrough ya habia muerto. Gardener lo agarrĂł por el impermeable, tirĂł\nde Ă©l hasta sacarlo a la calle.. y al girar en sus manos el cuerpo de George, tambiĂ©n el empezĂł a\ngritar. El lado izquierdo del impermeable del niño estaba de un rojo intenso. La sangre fluĂ­a hacia\nla alcantarilla desde el agujero donde habĂ­a estado el brazo izquierdo. Un trozo de hueso,\nhorriblemente brillante, asomaba por la tela rota.\n\nLos ojos del niño miraban fijamente el cielo gris y mientras Dave retrocedĂ­a a tropezones hacia\nlos otros que ya corrian por la calle, empezaron a llenarse de lluvia.\n"
doc3 <- doc3%>% body_add_par(texto5, style = "Normal")
print(doc3, target = "doc3.docx")

Actividad 2. Novela IT

# Cargar las librerĂ­as necesarias
library(tm)
library(wordcloud)
library(RColorBrewer)
library(officer)

# Leer el documento .docx
doc <- read_docx("/Users/valeriacantulobo/Desktop/doc3.docx")

# Extraer el texto del documento
texto <- docx_summary(doc)
texto_completo <- paste(texto$text, collapse=" ")

# Crear un corpus del texto
corpus <- Corpus(VectorSource(texto_completo))

# Preprocesar el texto
corpus <- tm_map(corpus, content_transformer(tolower)) # Convertir a minĂșsculas
corpus <- tm_map(corpus, removePunctuation) # Quitar puntuaciĂłn
corpus <- tm_map(corpus, removeNumbers) # Quitar nĂșmeros
corpus <- tm_map(corpus, removeWords, stopwords("spanish")) # Quitar stopwords en español
corpus <- tm_map(corpus, stripWhitespace) # Quitar espacios en blanco adicionales

# Crear una tabla de frecuencias de las palabras
dtm <- TermDocumentMatrix(corpus)
matriz <- as.matrix(dtm)
frecuencia <- sort(rowSums(matriz), decreasing=TRUE)
frecuencia_df <- data.frame(word = names(frecuencia), freq = frecuencia)

ggplot(head(frecuencia_df, 10), aes(x = reorder(word, -freq), y = freq, fill = freq)) + 
  geom_col() +  # Dibuja las barras permitiendo gradiente de color
  geom_text(aes(label = freq), vjust = -0.3) +  # Añade nĂșmeros encima de las barras
  scale_fill_gradient(low = "lightblue", high = "blue", limits = c(0, 30)) +  # Gradiente de azul con escala de 0 a 20
  labs(title = "TOP 10 Palabras MĂĄs Frecuentes", 
       subtitle = "IT: 3 CapĂ­tulos", 
       x = "Palabra", 
       y = "Frecuencia") +
  theme_minimal() 

# Generar la nube de palabras
set.seed(123)
wordcloud(words = frecuencia_df$word, freq = frecuencia_df$freq, min.freq = 2,
          random.order=FALSE, rot.per=0.35, colors=brewer.pal(8, "Dark2"), scale=c(4,0.5))

LS0tCnRpdGxlOiAiVGV4dCBNaW5pbmciCmF1dGhvcjogIlZhbGVyaWEgQ2FudMO6IC0gQTAxNTcwNzU4IgpkYXRlOiAiMjAyNC0wMi0yNiIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OiAKICAgIHRvYzogVFJVRQogICAgdG9jX2Zsb2F0OiBUUlVFCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFIAotLS0KCiFbXSgvVXNlcnMvdmFsZXJpYWNhbnR1bG9iby9Eb3dubG9hZHMvaXQuanBlZykKCiMgPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQ7Ij5UZW9yw61hPC9zcGFuPgpMYSAqbcOtbmVyaWEgZGUgdGV4dG8qIChUTSkgZXMgZWwgcHJvY2VzbyBkZSBleHRyYWVyIGluZm9ybWFjacOzbiDDunRpbCwgcGF0cm9uZXMgbyBjb25vY2ltaWVudG9zIGRlIHRleHRvcyBubyBlc3RydWN0dXJhZG9zLgoKQ29uc3RhIGRlIDMgZXRhcGFzOiAKMS4gT2J0ZW5lciBkYXRvczogRWwgcmVjb25vY2ltaWVudG8gw7NwdGljbyBkZSBjYXJhY3RlcmVzIChPQ1IpIGVzIHVuYSB0ZWNub2xvZ8OtYSBxdWUgcGVybWl0ZSBjb252ZXJ0aXIgaW3DoWdlbmVzIGRlIHRleHRvIGVuIHRleHRvIGVkaXRhYmxlLiBUYW1iacOpbiBlcyBjb25vY2lkbyBjb21vICoqZXh0cmFjY2nDs24gZGUgdGV4dG8gZGUgaW3DoWdlbmVzKiouCjIuIEV4cGxvcmFyIGRhdG9zOiBSZXByZXNlbnRhY2nDs24gZ3LDoWZpY2EgbyB2aXN1YWwgZGUgbG9zIGRhdG9zIHBhcmEgc3UgaW50ZXJwcmV0YWNpw7NuLiBMb3MgbWV0b2RvcyBtw6FzIGNvbXVuZXMgc29uIGVsIEFuw6FsaXNpcyBkZSBTZW50aW1pZW50b3MsIGxhIE51YmUgZGUgUGFsYWJyYXMgeSBlbCBUb3BpYyBNb2RlbGluZy4KMy4gQW7DoWxpc2lzIHByZWRpY3Rpdm86IFNvbiBsYXMgdGVjbmljYXMgeSBtb2RlbG9zIGVzdGFkw61zdGljb3MgcGFyYSBwcmVkZWNpciByZXN1bHRhZG9zIGZ1dHVyb3MuIExvcyBtb2RlbG9zIG3DoXMgdXNhZG9zIHNvbiBSYW5kb20gRm9yZXN0LCBSZWRlcyBOZXVyb25hbGVzIHkgUmVncmVzc2lvbmVzLgoKIyA8c3BhbiBzdHlsZT0iY29sb3I6IHJlZDsiPkluc3RhbGFyIHBhcXVldGVzIHkgbGxhbWFyIGxpYnJlcsOtYXM8L3NwYW4+CgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojRGF0YSBXcmFuZ2xpbmcKbGlicmFyeSh0aWR5dmVyc2UpCgojT0NSCiNpbnN0YWxsLnBhY2thZ2VzKCJ0ZXNzZXJhY3QiKQpsaWJyYXJ5KHRlc3NlcmFjdCkKCiNQTkcKI2luc3RhbGwucGFja2FnZXMoIm1hZ2ljayIpCmxpYnJhcnkobWFnaWNrKQoKI09mZmljZSAod29yZCkKI2luc3RhbGwucGFja2FnZXMoIm9mZmljZXIiKQpsaWJyYXJ5KG9mZmljZXIpCgojUERGCiNpbnN0YWxsLnBhY2thZ2VzKCJwZGZ0b29scyIpCmxpYnJhcnkocGRmdG9vbHMpCgojUGFyYSBsYSBmdW5jacOzbiBtYXAgcGFyYSBhcGxpY2FyIGxhIGZ1bmNpw7NuIGEgY2FkYSBlbGVtZW50byBkZSB1biB2ZWN0b3IgCiNpbnN0YWxsLnBhY2thZ2VzKCJwdXJyciIpCmxpYnJhcnkocHVycnIpCgojVGV4dCBNaW5pbmcKI2luc3RhbGwucGFja2FnZXMoInRtIikKbGlicmFyeSh0bSkKCiNDb2xvcmVzCiNpbnN0YWxsLnBhY2thZ2VzKCJSQ29sb3JCcmV3ZXIiKQpsaWJyYXJ5KFJDb2xvckJyZXdlcikKCiNOdWJlIGRlIFBhbGFicmFzIAojaW5zdGFsbC5wYWNrYWdlcygid29yZGNsb3VkIikKbGlicmFyeSh3b3JkY2xvdWQpCgojTW9kZWxvcyBkZSB0ZW1hcwojaW5zdGFsbC5wYWNrYWdlcygidG9waWNtb2RlbHMiKQpsaWJyYXJ5KHRvcGljbW9kZWxzKQoKI0dyYWZpY2FzIGNvbiBtYXMgZGlzZcOxbwojaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpCmxpYnJhcnkoZ2dwbG90MikKYGBgCgojIDxzcGFuIHN0eWxlPSJjb2xvcjogcmVkOyI+T2J0ZW5lciBkYXRvcyBtZWRpYW50ZSBPQ1I8L3NwYW4+CgojIyA8c3BhbiBzdHlsZT0iY29sb3I6IHJlZDsiPkRlIGltYWdlbiBQTkcgYSB0ZXh0byBlbiBXT1JEPC9zcGFuPgpgYGB7cn0KaW1hZ2VuMSA8LSBpbWFnZV9yZWFkKCIvVXNlcnMvdmFsZXJpYWNhbnR1bG9iby9Eb3dubG9hZHMvaW1hZ2VuMS5QTkciKQp0ZXh0bzEgPC0gb2NyKGltYWdlbjEpCnRleHRvMQpkb2MxIDwtIHJlYWRfZG9jeCgpICNDcmVhIHVuIGRvY3VtZW50byBkZSB3b3JkIGVuIGJsYW5jbwpkb2MxIDwtIGRvYzEgJT4lIGJvZHlfYWRkX3Bhcih0ZXh0bzEsIHN0eWxlID0gIk5vcm1hbCIpICNQZWdvIGVsIHRleHRvIGVuIGVsIHdvcmQKcHJpbnQoZG9jMSwgdGFyZ2V0ID0gInRleHRvMS5kb2N4IikgI0d1YXJkYSBlbCB3b3JkIGVuIGxhIGNvbXB1dGFkb3JhCmBgYAojIyA8c3BhbiBzdHlsZT0iY29sb3I6IHJlZDsiPkRlIGltYWdlbiBQTkcgZW4gZXNwYcOxb2wgYSB0ZXh0byBlbiBXT1JEPC9zcGFuPgpbQ29uc3VsdGFyIGlkaW9tYXMgZGlzcG9uaWJsZXNdKGh0dHBzOi8vdGVzc2VyYWN0LW9jci5naXRodWIuaW8vdGVzc2RvYy9EYXRhLUZpbGVzLWluLWRpZmZlcmVudC12ZXJzaW9ucy5odG1sKQpgYGB7cn0KaW1hZ2VuMiA8LSBpbWFnZV9yZWFkKCIvVXNlcnMvdmFsZXJpYWNhbnR1bG9iby9Eb3dubG9hZHMvaW1hZ2VuMi5QTkciKQp0ZXNzZXJhY3RfZG93bmxvYWQoInNwYSIpCnRleHRvMiA8LSBvY3IoaW1hZ2VuMiwgZW5naW5lID0gdGVzc2VyYWN0KCJzcGEiKSkKdGV4dG8yCmRvYzIgPC0gcmVhZF9kb2N4KCkgI0NyZWEgdW4gZG9jdW1lbnRvIGRlIHdvcmQgZW4gYmxhbmNvCmRvYzIgPC0gZG9jMiAlPiUgYm9keV9hZGRfcGFyKHRleHRvMiwgc3R5bGUgPSAiTm9ybWFsIikgI1BlZ28gZWwgdGV4dG8gZW4gZWwgd29yZApwcmludChkb2MyLCB0YXJnZXQgPSAidGV4dG8yLmRvY3giKSAjR3VhcmRhIGVsIHdvcmQgZW4gbGEgY29tcHV0YWRvcmEKYGBgCgojIyA8c3BhbiBzdHlsZT0iY29sb3I6IHJlZDsiPkRlIFBERiBhIHRleHRvIGVuIFdPUkQ8L3NwYW4+CmBgYHtyfQpwZGYxIDwtIHBkZl9jb252ZXJ0KCIvVXNlcnMvdmFsZXJpYWNhbnR1bG9iby9Eb3dubG9hZHMvcGRmMS5wZGYiLCBkcGk9NjAwKSAlPiUgbWFwKG9jcikKYGBgCgojIyA8c3BhbiBzdHlsZT0iY29sb3I6IHJlZDsiPkFjdGl2aWRhZCAxLiBOb3ZlbGEgIklUIjwvc3Bhbj4KCmBgYHtyfQpwZGYyIDwtIHBkZl9jb252ZXJ0KCIvVXNlcnMvdmFsZXJpYWNhbnR1bG9iby9Eb3dubG9hZHMvZXNvMy5wZGYiLCBkcGk9NjAwKSAlPiUgbWFwKG9jcikKYGBgCgpgYGB7cn0KaW1hZ2VuMyA9IGltYWdlX3JlYWQoIi9Vc2Vycy92YWxlcmlhY2FudHVsb2JvL2VzbzNfMS5wbmciKQp0ZXNzZXJhY3RfZG93bmxvYWQoInNwYSIpCnRleHRvMyA8LSBvY3IoaW1hZ2VuMywgZW5naW5lID0gdGVzc2VyYWN0KCJzcGEiKSkKdGV4dG8zCmRvYzMgPC0gcmVhZF9kb2N4KCkKZG9jMyA8LSBkb2MzJT4lIGJvZHlfYWRkX3Bhcih0ZXh0bzMsIHN0eWxlID0gIk5vcm1hbCIpCgppbWFnZW40ID0gaW1hZ2VfcmVhZCgiL1VzZXJzL3ZhbGVyaWFjYW50dWxvYm8vZXNvM18yLnBuZyIpCnRleHRvNCA8LSBvY3IoaW1hZ2VuNCwgZW5naW5lID0gdGVzc2VyYWN0KCJzcGEiKSkKdGV4dG80CmRvYzMgPC0gZG9jMyU+JSBib2R5X2FkZF9wYXIodGV4dG80LCBzdHlsZSA9ICJOb3JtYWwiKQoKaW1hZ2VuNSA9IGltYWdlX3JlYWQoIi9Vc2Vycy92YWxlcmlhY2FudHVsb2JvL2VzbzNfMy5wbmciKQp0ZXh0bzUgPC0gb2NyKGltYWdlbjUsIGVuZ2luZSA9IHRlc3NlcmFjdCgic3BhIikpCnRleHRvNQpkb2MzIDwtIGRvYzMlPiUgYm9keV9hZGRfcGFyKHRleHRvNSwgc3R5bGUgPSAiTm9ybWFsIikKcHJpbnQoZG9jMywgdGFyZ2V0ID0gImRvYzMuZG9jeCIpCmBgYAoKCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjogcmVkOyI+QWN0aXZpZGFkIDIuIE5vdmVsYSBJVDwvc3Bhbj4KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBDYXJnYXIgbGFzIGxpYnJlcsOtYXMgbmVjZXNhcmlhcwpsaWJyYXJ5KHRtKQpsaWJyYXJ5KHdvcmRjbG91ZCkKbGlicmFyeShSQ29sb3JCcmV3ZXIpCmxpYnJhcnkob2ZmaWNlcikKCiMgTGVlciBlbCBkb2N1bWVudG8gLmRvY3gKZG9jIDwtIHJlYWRfZG9jeCgiL1VzZXJzL3ZhbGVyaWFjYW50dWxvYm8vRGVza3RvcC9kb2MzLmRvY3giKQoKIyBFeHRyYWVyIGVsIHRleHRvIGRlbCBkb2N1bWVudG8KdGV4dG8gPC0gZG9jeF9zdW1tYXJ5KGRvYykKdGV4dG9fY29tcGxldG8gPC0gcGFzdGUodGV4dG8kdGV4dCwgY29sbGFwc2U9IiAiKQoKIyBDcmVhciB1biBjb3JwdXMgZGVsIHRleHRvCmNvcnB1cyA8LSBDb3JwdXMoVmVjdG9yU291cmNlKHRleHRvX2NvbXBsZXRvKSkKCiMgUHJlcHJvY2VzYXIgZWwgdGV4dG8KY29ycHVzIDwtIHRtX21hcChjb3JwdXMsIGNvbnRlbnRfdHJhbnNmb3JtZXIodG9sb3dlcikpICMgQ29udmVydGlyIGEgbWluw7pzY3VsYXMKY29ycHVzIDwtIHRtX21hcChjb3JwdXMsIHJlbW92ZVB1bmN0dWF0aW9uKSAjIFF1aXRhciBwdW50dWFjacOzbgpjb3JwdXMgPC0gdG1fbWFwKGNvcnB1cywgcmVtb3ZlTnVtYmVycykgIyBRdWl0YXIgbsO6bWVyb3MKY29ycHVzIDwtIHRtX21hcChjb3JwdXMsIHJlbW92ZVdvcmRzLCBzdG9wd29yZHMoInNwYW5pc2giKSkgIyBRdWl0YXIgc3RvcHdvcmRzIGVuIGVzcGHDsW9sCmNvcnB1cyA8LSB0bV9tYXAoY29ycHVzLCBzdHJpcFdoaXRlc3BhY2UpICMgUXVpdGFyIGVzcGFjaW9zIGVuIGJsYW5jbyBhZGljaW9uYWxlcwoKIyBDcmVhciB1bmEgdGFibGEgZGUgZnJlY3VlbmNpYXMgZGUgbGFzIHBhbGFicmFzCmR0bSA8LSBUZXJtRG9jdW1lbnRNYXRyaXgoY29ycHVzKQptYXRyaXogPC0gYXMubWF0cml4KGR0bSkKZnJlY3VlbmNpYSA8LSBzb3J0KHJvd1N1bXMobWF0cml6KSwgZGVjcmVhc2luZz1UUlVFKQpmcmVjdWVuY2lhX2RmIDwtIGRhdGEuZnJhbWUod29yZCA9IG5hbWVzKGZyZWN1ZW5jaWEpLCBmcmVxID0gZnJlY3VlbmNpYSkKCmdncGxvdChoZWFkKGZyZWN1ZW5jaWFfZGYsIDEwKSwgYWVzKHggPSByZW9yZGVyKHdvcmQsIC1mcmVxKSwgeSA9IGZyZXEsIGZpbGwgPSBmcmVxKSkgKyAKICBnZW9tX2NvbCgpICsgICMgRGlidWphIGxhcyBiYXJyYXMgcGVybWl0aWVuZG8gZ3JhZGllbnRlIGRlIGNvbG9yCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGZyZXEpLCB2anVzdCA9IC0wLjMpICsgICMgQcOxYWRlIG7Dum1lcm9zIGVuY2ltYSBkZSBsYXMgYmFycmFzCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAibGlnaHRibHVlIiwgaGlnaCA9ICJibHVlIiwgbGltaXRzID0gYygwLCAzMCkpICsgICMgR3JhZGllbnRlIGRlIGF6dWwgY29uIGVzY2FsYSBkZSAwIGEgMjAKICBsYWJzKHRpdGxlID0gIlRPUCAxMCBQYWxhYnJhcyBNw6FzIEZyZWN1ZW50ZXMiLCAKICAgICAgIHN1YnRpdGxlID0gIklUOiAzIENhcMOtdHVsb3MiLCAKICAgICAgIHggPSAiUGFsYWJyYSIsIAogICAgICAgeSA9ICJGcmVjdWVuY2lhIikgKwogIHRoZW1lX21pbmltYWwoKSAKCiMgR2VuZXJhciBsYSBudWJlIGRlIHBhbGFicmFzCnNldC5zZWVkKDEyMykKd29yZGNsb3VkKHdvcmRzID0gZnJlY3VlbmNpYV9kZiR3b3JkLCBmcmVxID0gZnJlY3VlbmNpYV9kZiRmcmVxLCBtaW4uZnJlcSA9IDIsCiAgICAgICAgICByYW5kb20ub3JkZXI9RkFMU0UsIHJvdC5wZXI9MC4zNSwgY29sb3JzPWJyZXdlci5wYWwoOCwgIkRhcmsyIiksIHNjYWxlPWMoNCwwLjUpKQpgYGAK