2. Mineo de texto
2.1. Prerrequisitos
Cargamos el conjunto de librería que vamos a utilizar dentro del análisis. A continuación se detalla algunas de ellas:
|
stringi
|
Procesamiento de cadenas de caracteres
|
|
udpipe
|
Análisis de texto y permite el entrenamiento de modelos
|
|
tidyverse
|
Manipulación de datos (incluye ggplot2 y dplyr)
|
|
igraph-ggraph
|
Visualización
|
#Librerias que se van a usar para todo el análisis
pckg <- c("easypackages","tidyverse","rvest","purrr","kable","tidytext",
"readxl","udpipe","tm","igraph","ggraph","influential")
# install.packages("pckg") desomentar en caso de no tener innstalados los paquetes
library(easypackages)
libraries(pckg)
2.2. Obtención de los datos
La fuente de datos que se utilizó es Google News, donde se realizó web scraping (raspado web), para extraer información de las noticias relacionadas con el objetivo de análisis.
# Definición de funciones
## Función para el scrapeo de noticias en google news.
obtieneNoticiasBusqueda <- function(busqueda){
news_pag = "https://news.google.com/"
parametro_busqueda = "search?q="
busqueda_no_espacios = gsub(" ","%20", busqueda)
parametro_final = "&hl=es-419&gl=US&ceid=US:es-419"
html_dir = paste0(news_pag,parametro_busqueda,busqueda_no_espacios,parametro_final)
google_news = read_html(html_dir)
noticias = google_news %>%
html_nodes(css = ".xP6mwf") %>%
html_children()
noticiasDF = map(noticias,obtieneNoticiasData)
noticiasDF = bind_rows(noticiasDF)
noticiasDF = noticiasDF[!is.na(noticiasDF$Titular),]
return(noticiasDF)
}
## Función auxiliar para obtener características de la noticia.
obtieneNoticiasData = function(noticia){
news_pag = "https://news.google.com/"
titular = noticia %>% html_node("h3") %>% html_text()
fecha = noticia %>% html_node("time") %>% html_attr("datetime")
diario = noticia %>% html_node("a.wEwyrc.AVN2gc.uQIVzc.Sksgp") %>% html_text()
link_enmascarado = noticia %>% html_node("h3 a") %>% html_attr("href")
link_enmascarado = paste0(news_pag,substring(link_enmascarado,3))
link_leido = read_html(link_enmascarado)
link = link_leido %>%
html_nodes(css='a') %>%
tail(1) %>%
html_attr("href")
noticiaDF = data.frame(Titular=titular, Fecha=fecha, Diario=diario, Link=link, stringsAsFactors = F)
return(noticiaDF)
}
Obtener noticias sobre violencia contra a mujer en Ecuador
noticiasMujer <- obtieneNoticiasBusqueda("Violencia contra la mujer Ecuador")
Hata la fecha de corte los diarios ecuatorianos que más noticias relacionados con la violencia contra la mujer publicaron fueron los que se presentan a continuación:
Para poder obtener la noticia completa se obtiene mediante el complemento de Google inspector gadget un diccionario de los CSS de cada uno de los diarios estudiados, el CSS es un lenguaje que define la apariencia de un documento. Posterior a esto, La función obtenerNoticiaNacional nos permitirá obtener la noticia completa que se encuentre dentro de los diccionarios CSS definidos previamente.
# Diccionario CSS de los diarios
Diarios <- c("El Comercio (Ecuador)", "El Telégrafo (por eliminar)",
"El Universo","La Hora (Ecuador)","Primicias")
Estructura = data.frame(Diario=Diarios)
Estructura$CSS = NA
Estructura$CSS[Estructura$Diario=='El Comercio (Ecuador)'] = '.paragraphs'
Estructura$CSS[Estructura$Diario=='El Telégrafo (por eliminar)'] = '.itemFullText'
Estructura$CSS[Estructura$Diario=='El Universo'] = '.field-name-body'
Estructura$CSS[Estructura$Diario=='La Hora (Ecuador)'] = '#contenedorGeneral'
Estructura$CSS[Estructura$Diario=='Primicias'] = '#entry-content-inarticle'
# Función para obtener la noticia completa.
obtenerNoticiaNacional = function(link_noticia, diario, diccionario_css){
noticia_leida = read_html(link_noticia)
css = diccionario_css$CSS[diccionario_css$Diario==diario]
text_nodes = noticia_leida %>%
html_nodes(css = css) %>%
html_nodes("p")
text = text_nodes %>%
html_text()
text = paste0(text, collapse = " ")
return(text)
}
Para obtener la noticia completa se toma como input el dataframe de la busqueda realizada mediante web scraping, se filtra solo los 5 diarios que se van a tomar en cuenta dentro del análisis y se ejecuta la función que se definió para la extracción de todas las noticias.
noticiasMujer <- noticiasMujer %>% filter(Diario %in% Diarios)
news = map2_chr(noticiasMujer$Link, noticiasMujer$Diario, obtenerNoticiaNacional, diccionario_css=Estructura)
noticiasMujer$Noticia = news
El dataframe que nos da como resultado recoge: la fecha en que se publicó la noticia, el diario que la publicó, el titular, el link de acceso al sitio web donde se encuentra la noticia, y la noticia como tal.
2.3. Tokenización del texto
Dentro del proceso de tokenización se a procedido a dividir un texto en las unidades que los conforman, para el caso de estudio se dividió en el elemento más sencillo, las palabras. Sin embargo, más adelante se busca realizar un análisis de n-gramas específicamente bigramas (n=2).
Al momento de realizar la tokenización, se incumple el condición tidy de nuestro dataframe, ya que nuestro objeto de análisis son las noticias que antes de la tokenización se encontraban una en cada fila del dataframe, para poder cumplir con la estructura incial, se duplica cada elemento de las demás columnas las veces que sea necesario, al proceso descrito se lo conoce como expansión, y se lo realiza con la función unnest_tokens del paquete tidytext.
2.3. Limpieza del texto (stopwords)
Después de haber realizado la tokenización del texto correspondiente a las noticias, se procede a la limpieza de palabras que no tienen significado para el análisis (stopwords), como se observa a continuación las palabras más frecuentes son preposiciones, artículos, y pronombres en su mayoría que no permiten obtener conclusiones sobre lo que se los medios electrónicos están transmitiendo a sus lectores.
Remoción de palabras vacías
Al remover las palabras que no dan sentido a mi análisis, ahora ya se puede evidenciar como el objetivo de estudio va tomando forma. Se puede evidenciar que los términos más frecuentes ya nos hablan sobre la violencia contra la mujer en el Ecuador.
stopwords_es_1 = read_excel("CustomStopWords.xlsx")
names(stopwords_es_1) = c("Token","Fuente")
stopwords_es_2 = tibble(Token=tm::stopwords(kind = "es"), Fuente="tm")
stopwords_es = rbind(stopwords_es_1, stopwords_es_2)
stopwords_es = stopwords_es[!duplicated(stopwords_es$Token),]
remove(stopwords_es_1, stopwords_es_2)
stopwords_es[sample(nrow(stopwords_es),size = 10, replace = F),]
tidy_Mujer <- tidy_Mujer %>%
anti_join(stopwords_es)
Joining, by = "Token"
tidy_Mujer %>%
count(Token) %>%
slice_max(order_by = n,n=8)
Dentro de las palabras más frecuentes se encuentran las palabras mujer y mujeres, para poder corregir esto se ha procedido a la lematización de las palabras para poder extraer su lemma, con la palabra raíz se espera tener mejor resultado al momento de visualizar las palabras más frecuentes para cada uno de los diarios. El método para lematizar que se empleará es a través de un modeo pre-entrenado, conjuntamente con la librería udpipe
Antes de proceder con la lematización, se da un vistazo breve de discurso que presenta cada uno de los diarios, esto servirá para tener una idea de si cada uno de ellos tiene un patrón que lo diferencie.

Como se puede observar en el siguiente gráfico, las palabras más usadas en las noticias que se publica sobre la violencia contra la mujer, permiten conocer el contexto del problema en el Ecuador. La violencia de género en donde la mujer es la víctima, es un problema social que se busca mitigar a través de la política y de esta forma se busca hacer cumplir los derechos de las mujeres.
Lematización
Para proceder con la lematización de las noticias se usará un modelo en español pre-entrenado, adicional a esto se eliminarán la palabras que generan ruido dentro del análisis.
# Cargar el modelo pre-entrenado
udpipe::udpipe_download_model('spanish') # Descomentar al ejecutar por primera vez
model <- udpipe_load_model(file = "spanish-gsd-ud-2.5-191206.udpipe")
tidy_Mujer_lemmatiza <- udpipe_annotate(model,
x = noticiasMujer$Noticia,
doc_id = noticiasMujer$Titular)
# Transformar la data en un formato tidy
tidy_Mujer_lemmatiza <- as_tibble(tidy_Mujer_lemmatiza)
names(tidy_Mujer_lemmatiza)[6] <- "Token"
# Remoción de stopwords
tidy_Mujer_lemmatiza1 <- tidy_Mujer_lemmatiza %>%
mutate(Token=removePunctuation(Token)) %>%
anti_join(stopwords_es) %>%
filter(Token!="")
Si se representan la frecuencia de las etiquetas POS, se obtiene el gráfico que muestra las categorías de POS que más se repiten, algo que hay que tomar en cuenta particularmente en este análisis es que el POS de números es bastante frecuente, esto se debe a que algunas noticias pueden mostrar cifras acerca de las víctimas de violencia, y femicidio. Para ahondar más en este tema nos servirá el análisis de bigramas que se realizará más adelante.

Si se toma en cuenta las categorías POS que más se repiten se puede optener más información acerca del contexto del problema de análisis. La tipos de violencia que sufren y más denuncian las mujeres son: la sexual, psicológica, y económica, además se habla de los casos de femicidios que ocurren cada año.

Cabe señalar que dentro de la lematización el modelo entrenado muestra errores al momento de extraer la palabra raíz. Por ejemplo, en la categoría VERB (verbos) aparece la palabra asesinado que a pesar que la categoriza como ver no extrae el verbo como tal que sería asesinar.
2.4. Análisis de bigramas
Para poder construir los bigramas se realiza la tokenización de las noticias extraidas desde la web, pero ahora se cambia el argumento de la tokenización a n-gramas con un n=2.
Algunos de los bigramas más usuales son palabras vacías que deben ser eliminadas para poder tener un análisis más limpio, por lo que se procede a eliminarlas.
Eliminando las stopwords ha permitido que ahora los bigramas tengan mucho más sentido orientado a lo que se está buscando. Un término que particularmente llama la atención es que se habla de violencia política y este término está relacionado con la restricción de acceso a derechos humanos y libertades por cuestiones de sexo, y la relaciones desiguales entre hombre y mujer por ejemplo en el ámbito laboral.
Red de bigramas
La relación entre palabras es muy importante y lo que nos ofrece la representación gráfica de una red de bigramas (grafo) es poder conocer las temáticas que se pueden estar tratando dentro de las noticias.
bigrama_grafo_mujer
IGRAPH 9ab1d7d DN-- 135 97 --
+ attr: name (v/c), n (e/n)
+ edges from 9ab1d7d (vertex names):
[1] covid ->19 violencia ->intrafamiliar
[3] derechos ->humanos correo ->electrónico
[5] electrónico ->requerido requerido ->asunto
[7] ecu ->911 violencia ->machista
[9] violencia ->sexual emergencia ->sanitaria
[11] ley ->orgánica redes ->sociales
[13] diciembre ->ecuador organizaciones->sociales
[15] violencia ->física acoso ->laboral
+ ... omitted several edges

Un pequeño resumen del grafo nos da la idea de la información que se está transmitiendo a los lectores de los diarios tomados en cuenta para este trabajo. Se habla mucho del empoderamiento femenino, que busca a través de la organización en las redes sociales pronuciarse como sociedad civil exigiendo el cumplimiento de sus derechosa ya que no obtienen ayuda de las organizaciones gubernamentales ; los distintos tipos de violencia que sufren las mujeres en el ámbito familiar, y laboral; y finalmente las cifras muertes violentas y femicidios en el Ecuador.
3. Aprendizaje no supervisado
Una de las ventajas de poder aplicar un modelo no supervisado, es conocer los patrones que siguen los datos y poder ir formando clusters. Para realizar la clustrización de las noticias se usa el modelado de tópicos. Para este modelado se utilizará la técnica de Asignación Latente de Dirichlet (LDA). Para poder utilizar el algoritmo de LDA, se parte de la creación de la matriz documento-término:
# Creación de la matriz documento-término
dtm_noticias <- tidy_Mujer_model %>%
count(doc_id, lemma, sort = TRUE) %>%
ungroup() %>%
cast_dtm(doc_id, lemma, n)
# Creación de la matriz documento-término
dtm_noticias <- tidy_Mujer_model %>%
count(doc_id, lemma, sort = TRUE) %>%
ungroup() %>%
cast_dtm(doc_id, lemma, n)
dtm_noticias
<<DocumentTermMatrix (documents: 65, terms: 4106)>>
Non-/sparse entries: 11898/254992
Sparsity : 96%
Maximal term length: 73
Weighting : term frequency (tf)
Ahora para poder generar las temáticas se necesita definir un número k de grupos que se van a formar, el número de temática tomados se determino tras realizar algunas pruebas, aunque se podría haber utilizado técnicas más avanzadas para determinar el número óptimo de grupos.
class(lda)
[1] "LDA_Gibbs"
attr(,"package")
[1] "topicmodels"
Tras haber realizado la modelización se ontiene la matriz beta, la cual nos permite saber la probabilidad de que cada término pueda pertenecer a una temática en específico. Por ejemplol la palabra violencia tiene más probabilidad de pertenecer al la temática número 1.
Top de términos de cada temática
Las tres temáticas que se obtuvieron nos dan idea de los siguiente:
Temática 1: Habla sobre la violencia sexual que sufren las mujeres, adolescentes y niñas, y que se necesita una atención a través de políticas que pueda garantizar sus derechos.
Temática 2: Se hace mención al 25 de noviembre fecha en la que se celebra el día contra la violencia de la mujer, y la organización de marchas que se efectuaron en todo el país, para reclamar justicia por las vidas perdidas a causas de los femicidios.
Temática 3: La última temática trata sobre la violencia de género que es otro tipo diferente de violencia, pero que esta relacionado al objetivo de estudio, y que hace mención a la crisis sanitaria del COVID-19 y las agresiones denunciadas en la fiscalía durante todo la temporada del confinamiento.

También se puede trabajar con la matriz gamma para conocer que probabilidad tiene cada documento de pertenecer a una de las tres temáticas. Para ello se obtuvo una muestra de tres documento aleatorios para conocer a que temática pertenecen.
Mediante el gráfico se puede evidenciar a que temática pertenece cada noticia y efectivamente se comprueba al revisar los títulares de las tres noticias tomadas al azar. Por un lado la temática uno que habla de la busqueda de justicia por los temás de femicidio, y por el otro la relacionada a la violencia contra las mujeres como tal.

4. Conclusiones
El problema de la violencia contra la mujer es un mal que durante esta pandemía a retomado fuerza ya que se habla de violencia intrafamiliar, sexual, económica e incluso patrimonial. Lo que se pide es reformar el código orgánico integral penal, pero los entes gubernamentales hacen caso omiso frente a este problema, es por esta razón que se habla de la violencia política que sufren las mujeres y que al no sentirse respaldadas por la justicia en el Ecuador, deben a través de organizaciones civiles buscar ayuda para hacer cumplir sus derechos.
Los medios de comunicación que se analizaron parecen tener un mismo patrón al momento de presentar sus noticias, muestran las cifras de violencia, pero no se habla de una posible solución emitida por algún ente gubernamental, solo se trata de casos en donde la mujer es víctima no solo en su entorno familiar, si no también se detalla el acoso y discriminación que sufren en el ámbito laboral. El mensaje es claro las mujeres se sienten vulnerables en un país donde la violencia de género y contra la mujer se queda solo en cifras.
LS0tDQp0aXRsZTogIlByb2Nlc2FtaWVudG8gZGUgTGVuZ3VhamUgTmF0dXJhbCINCnN1YnRpdGxlOiAiQ2FzbyBkZSBlc3R1ZGlvOiBWaW9sZW5jaWEgY29udHJhIGxhIE11amVyIg0KYXV0aG9yOiBDcmlzdG9waGVyIEFndWlycmUgQ3Jpb2xsbw0KZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJUIsICVZJylgIg0Kb3V0cHV0OiANCiAgaHRtbF9ub3RlYm9vazoNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZGVwdGg6IDINCiAgICB0b2NfZmxvYXQ6DQogICAgICBjb2xsYXBzZWQ6IHRydWUNCiAgICAgIHNtb290aF9zY3JvbGw6IGZhbHNlDQpiaWJsaW9ncmFwaHk6IGJpYmxpby5iaWINCi0tLQ0KDQojICoqMS4gQ29udGV4dG8gZGVsIEFuw6FsaXNpcyoqDQoNCiMjICoqMS4yLiBPYmpldGl2byoqDQoNCisgQW5hbGl6YXIgZWwgY29udGVuaWRvIGRlIGxhcyBub3RpY2lhcyByZWxhY2lvbmFkYXMgYSAqKlZpb2xlbmNpYSBjb250cmEgbGEgbXVqZXIqKiBkZSBjaW5jbyBwZXLDrW9kaWNvcyBlY3VhdG9yaWFub3MsIGNvbiBlbCBmaW4gZGUgY29ub2NlciBlbCBtZW5zYWplIHF1ZSB0cmFuc21pdGVuIGxvcyBtZWRpb3MgZGUgY29tdW5pY2FjacOzbiBkZW50cm8gZGUgbGEgbHVjaGEgY29udHJhIGxhIHZpb2xlbmNpYSBkZSBnw6luZXJvLiANCg0KIyAqKjIuIE1pbmVvIGRlIHRleHRvKioNCg0KIyMgKioyLjEuIFByZXJyZXF1aXNpdG9zKioNCg0KQ2FyZ2Ftb3MgZWwgY29uanVudG8gZGUgbGlicmVyw61hIHF1ZSB2YW1vcyBhIHV0aWxpemFyIGRlbnRybyBkZWwgYW7DoWxpc2lzLiBBIGNvbnRpbnVhY2nDs24gc2UgZGV0YWxsYSBhbGd1bmFzIGRlIGVsbGFzOg0KDQoNCjx0YWJsZT4NCjx0aGVhZD4NCjx0ciBjbGFzcz0iaGVhZGVyIj4NCjx0aD5MaWJyZXJpYTwvdGg+IDx0aD5EZXRhbGxlPC90aD4NCjwvdHI+DQo8L3RoZWFkPg0KPHRib2R5Pjx0ciBjbGFzcz0ib2RkIj4NCjx0ZD5zdHJpbmdpPC90ZD48dGQ+UHJvY2VzYW1pZW50byBkZSBjYWRlbmFzIGRlIGNhcmFjdGVyZXMgPC90ZD4NCjwvdHI+DQo8dHIgY2xhc3M9ImV2ZW4iPg0KPHRkPnVkcGlwZTwvdGQ+PHRkPkFuw6FsaXNpcyBkZSB0ZXh0byB5IHBlcm1pdGUgZWwgZW50cmVuYW1pZW50byBkZSBtb2RlbG9zPC90ZD4NCjwvdHI+DQo8dHIgY2xhc3M9Im9kZCI+DQo8dGQ+dGlkeXZlcnNlPC90ZD48dGQ+TWFuaXB1bGFjacOzbiBkZSBkYXRvcyAoaW5jbHV5ZSBnZ3Bsb3QyIHkgZHBseXIpPC90ZD4NCjwvdHI+DQo8dHIgY2xhc3M9ImV2ZW4iPg0KPHRkPmlncmFwaC1nZ3JhcGg8L3RkPjx0ZD5WaXN1YWxpemFjacOzbjwvdGQ+DQo8L3RyPg0KPC90Ym9keT4NCjwvdGFibGU+DQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9Rn0NCiNMaWJyZXJpYXMgcXVlIHNlIHZhbiBhIHVzYXIgcGFyYSB0b2RvIGVsIGFuw6FsaXNpcw0KcGNrZyA8LSBjKCJlYXN5cGFja2FnZXMiLCJ0aWR5dmVyc2UiLCJydmVzdCIsInB1cnJyIiwia2FibGUiLCJ0aWR5dGV4dCIsDQogICAgICAgICAgInJlYWR4bCIsInVkcGlwZSIsInRtIiwiaWdyYXBoIiwiZ2dyYXBoIiwiaW5mbHVlbnRpYWwiKQ0KIyBpbnN0YWxsLnBhY2thZ2VzKCJwY2tnIikgZGVzb21lbnRhciBlbiBjYXNvIGRlIG5vIHRlbmVyIGlubnN0YWxhZG9zIGxvcyBwYXF1ZXRlcw0KbGlicmFyeShlYXN5cGFja2FnZXMpDQpsaWJyYXJpZXMocGNrZykNCmBgYA0KDQoNCiMjICoqMi4yLiBPYnRlbmNpw7NuIGRlIGxvcyBkYXRvcyoqDQoNCkxhIGZ1ZW50ZSBkZSBkYXRvcyBxdWUgc2UgdXRpbGl6w7MgZXMgR29vZ2xlIE5ld3MsIGRvbmRlIHNlIHJlYWxpesOzIHdlYiBzY3JhcGluZyAocmFzcGFkbyB3ZWIpLCBwYXJhIGV4dHJhZXIgaW5mb3JtYWNpw7NuIGRlIGxhcyBub3RpY2lhcyByZWxhY2lvbmFkYXMgY29uIGVsIG9iamV0aXZvIGRlIGFuw6FsaXNpcy4gIA0KDQpgYGB7cn0NCiMgRGVmaW5pY2nDs24gZGUgZnVuY2lvbmVzDQoNCiMjIEZ1bmNpw7NuIHBhcmEgZWwgc2NyYXBlbyBkZSBub3RpY2lhcyBlbiBnb29nbGUgbmV3cy4NCg0Kb2J0aWVuZU5vdGljaWFzQnVzcXVlZGEgPC0gIGZ1bmN0aW9uKGJ1c3F1ZWRhKXsNCiAgbmV3c19wYWcgPSAiaHR0cHM6Ly9uZXdzLmdvb2dsZS5jb20vIg0KICBwYXJhbWV0cm9fYnVzcXVlZGEgPSAic2VhcmNoP3E9Ig0KICBidXNxdWVkYV9ub19lc3BhY2lvcyA9IGdzdWIoIiAiLCIlMjAiLCBidXNxdWVkYSkNCiAgcGFyYW1ldHJvX2ZpbmFsID0gIiZobD1lcy00MTkmZ2w9VVMmY2VpZD1VUzplcy00MTkiDQogIGh0bWxfZGlyID0gcGFzdGUwKG5ld3NfcGFnLHBhcmFtZXRyb19idXNxdWVkYSxidXNxdWVkYV9ub19lc3BhY2lvcyxwYXJhbWV0cm9fZmluYWwpDQogIGdvb2dsZV9uZXdzID0gcmVhZF9odG1sKGh0bWxfZGlyKQ0KICBub3RpY2lhcyA9IGdvb2dsZV9uZXdzICU+JSANCiAgICBodG1sX25vZGVzKGNzcyA9ICIueFA2bXdmIikgJT4lIA0KICAgIGh0bWxfY2hpbGRyZW4oKQ0KICBub3RpY2lhc0RGID0gbWFwKG5vdGljaWFzLG9idGllbmVOb3RpY2lhc0RhdGEpDQogIG5vdGljaWFzREYgPSBiaW5kX3Jvd3Mobm90aWNpYXNERikNCiAgbm90aWNpYXNERiA9IG5vdGljaWFzREZbIWlzLm5hKG5vdGljaWFzREYkVGl0dWxhciksXQ0KICByZXR1cm4obm90aWNpYXNERikNCn0NCg0KIyMgRnVuY2nDs24gYXV4aWxpYXIgcGFyYSBvYnRlbmVyIGNhcmFjdGVyw61zdGljYXMgZGUgbGEgbm90aWNpYS4NCg0Kb2J0aWVuZU5vdGljaWFzRGF0YSA9IGZ1bmN0aW9uKG5vdGljaWEpew0KICBuZXdzX3BhZyA9ICJodHRwczovL25ld3MuZ29vZ2xlLmNvbS8iDQogIHRpdHVsYXIgPSBub3RpY2lhICU+JSBodG1sX25vZGUoImgzIikgJT4lIGh0bWxfdGV4dCgpDQogIGZlY2hhID0gbm90aWNpYSAlPiUgaHRtbF9ub2RlKCJ0aW1lIikgJT4lIGh0bWxfYXR0cigiZGF0ZXRpbWUiKQ0KICBkaWFyaW8gPSBub3RpY2lhICU+JSBodG1sX25vZGUoImEud0V3eXJjLkFWTjJnYy51UUlWemMuU2tzZ3AiKSAlPiUgaHRtbF90ZXh0KCkNCiAgbGlua19lbm1hc2NhcmFkbyA9IG5vdGljaWEgJT4lIGh0bWxfbm9kZSgiaDMgYSIpICU+JSBodG1sX2F0dHIoImhyZWYiKQ0KICBsaW5rX2VubWFzY2FyYWRvID0gcGFzdGUwKG5ld3NfcGFnLHN1YnN0cmluZyhsaW5rX2VubWFzY2FyYWRvLDMpKSAgDQogIGxpbmtfbGVpZG8gPSByZWFkX2h0bWwobGlua19lbm1hc2NhcmFkbykNCiAgbGluayA9IGxpbmtfbGVpZG8gJT4lIA0KICAgIGh0bWxfbm9kZXMoY3NzPSdhJykgJT4lIA0KICAgIHRhaWwoMSkgJT4lIA0KICAgIGh0bWxfYXR0cigiaHJlZiIpDQogIG5vdGljaWFERiA9IGRhdGEuZnJhbWUoVGl0dWxhcj10aXR1bGFyLCBGZWNoYT1mZWNoYSwgRGlhcmlvPWRpYXJpbywgTGluaz1saW5rLCBzdHJpbmdzQXNGYWN0b3JzID0gRikNCiAgcmV0dXJuKG5vdGljaWFERikNCn0NCg0KYGBgDQoNCioqT2J0ZW5lciBub3RpY2lhcyBzb2JyZSB2aW9sZW5jaWEgY29udHJhIGEgbXVqZXIgZW4gRWN1YWRvcioqDQpgYGB7cn0NCm5vdGljaWFzTXVqZXIgPC0gb2J0aWVuZU5vdGljaWFzQnVzcXVlZGEoIlZpb2xlbmNpYSBjb250cmEgbGEgbXVqZXIgRWN1YWRvciIpDQpgYGANCg0KSGF0YSBsYSBmZWNoYSBkZSBjb3J0ZSBsb3MgZGlhcmlvcyBlY3VhdG9yaWFub3MgcXVlIG3DoXMgbm90aWNpYXMgcmVsYWNpb25hZG9zIGNvbiAqKmxhIHZpb2xlbmNpYSBjb250cmEgbGEgbXVqZXIqKiBwdWJsaWNhcm9uIGZ1ZXJvbiBsb3MgcXVlIHNlIHByZXNlbnRhbiBhIGNvbnRpbnVhY2nDs246IA0KDQpgYGB7cn0NCm5vdGljaWFzTXVqZXIgJT4lIGNvdW50KERpYXJpbykgJT4lIHNsaWNlX21heChvcmRlcl9ieSA9IG4sbj01KQ0KYGBgDQoNClBhcmEgcG9kZXIgb2J0ZW5lciBsYSBub3RpY2lhIGNvbXBsZXRhIHNlIG9idGllbmUgbWVkaWFudGUgZWwgY29tcGxlbWVudG8gZGUgR29vZ2xlICoqaW5zcGVjdG9yIGdhZGdldCoqIHVuIGRpY2Npb25hcmlvIGRlIGxvcyBDU1MgZGUgY2FkYSB1bm8gZGUgbG9zIGRpYXJpb3MgZXN0dWRpYWRvcywgZWwgQ1NTIGVzIHVuIGxlbmd1YWplIHF1ZSBkZWZpbmUgbGEgYXBhcmllbmNpYSBkZSB1biBkb2N1bWVudG8uIFBvc3RlcmlvciBhIGVzdG8sIExhIGZ1bmNpw7NuICoqb2J0ZW5lck5vdGljaWFOYWNpb25hbCoqIG5vcyBwZXJtaXRpcsOhIG9idGVuZXIgbGEgbm90aWNpYSBjb21wbGV0YSBxdWUgc2UgZW5jdWVudHJlIGRlbnRybyBkZSBsb3MgZGljY2lvbmFyaW9zIENTUyBkZWZpbmlkb3MgcHJldmlhbWVudGUuDQoNCmBgYHtyfQ0KDQojIERpY2Npb25hcmlvIENTUyBkZSBsb3MgZGlhcmlvcw0KDQpEaWFyaW9zIDwtICBjKCJFbCBDb21lcmNpbyAoRWN1YWRvcikiLCAiRWwgVGVsw6lncmFmbyAocG9yIGVsaW1pbmFyKSIsIA0KICAgICAgICAgICAgIkVsIFVuaXZlcnNvIiwiTGEgSG9yYSAoRWN1YWRvcikiLCJQcmltaWNpYXMiKQ0KDQpFc3RydWN0dXJhID0gZGF0YS5mcmFtZShEaWFyaW89RGlhcmlvcykNCkVzdHJ1Y3R1cmEkQ1NTID0gTkENCkVzdHJ1Y3R1cmEkQ1NTW0VzdHJ1Y3R1cmEkRGlhcmlvPT0nRWwgQ29tZXJjaW8gKEVjdWFkb3IpJ10gPSAnLnBhcmFncmFwaHMnDQpFc3RydWN0dXJhJENTU1tFc3RydWN0dXJhJERpYXJpbz09J0VsIFRlbMOpZ3JhZm8gKHBvciBlbGltaW5hciknXSA9ICcuaXRlbUZ1bGxUZXh0Jw0KRXN0cnVjdHVyYSRDU1NbRXN0cnVjdHVyYSREaWFyaW89PSdFbCBVbml2ZXJzbyddID0gJy5maWVsZC1uYW1lLWJvZHknDQpFc3RydWN0dXJhJENTU1tFc3RydWN0dXJhJERpYXJpbz09J0xhIEhvcmEgKEVjdWFkb3IpJ10gPSAnI2NvbnRlbmVkb3JHZW5lcmFsJw0KRXN0cnVjdHVyYSRDU1NbRXN0cnVjdHVyYSREaWFyaW89PSdQcmltaWNpYXMnXSA9ICcjZW50cnktY29udGVudC1pbmFydGljbGUnDQoNCg0KIyBGdW5jacOzbiBwYXJhIG9idGVuZXIgbGEgbm90aWNpYSBjb21wbGV0YS4gDQoNCm9idGVuZXJOb3RpY2lhTmFjaW9uYWwgPSBmdW5jdGlvbihsaW5rX25vdGljaWEsIGRpYXJpbywgZGljY2lvbmFyaW9fY3NzKXsNCiAgDQogIG5vdGljaWFfbGVpZGEgPSByZWFkX2h0bWwobGlua19ub3RpY2lhKQ0KICBjc3MgPSBkaWNjaW9uYXJpb19jc3MkQ1NTW2RpY2Npb25hcmlvX2NzcyREaWFyaW89PWRpYXJpb10NCiAgDQogIHRleHRfbm9kZXMgPSBub3RpY2lhX2xlaWRhICU+JSANCiAgICBodG1sX25vZGVzKGNzcyA9IGNzcykgJT4lIA0KICAgIGh0bWxfbm9kZXMoInAiKQ0KICANCiAgdGV4dCA9IHRleHRfbm9kZXMgJT4lIA0KICAgIGh0bWxfdGV4dCgpDQogIA0KICB0ZXh0ID0gcGFzdGUwKHRleHQsIGNvbGxhcHNlID0gIiAiKQ0KICANCiAgcmV0dXJuKHRleHQpDQp9DQpgYGANCg0KUGFyYSBvYnRlbmVyIGxhIG5vdGljaWEgY29tcGxldGEgc2UgdG9tYSBjb21vIGlucHV0IGVsIGRhdGFmcmFtZSBkZSBsYSBidXNxdWVkYSByZWFsaXphZGEgbWVkaWFudGUgd2ViIHNjcmFwaW5nLCBzZSBmaWx0cmEgc29sbyBsb3MgNSBkaWFyaW9zIHF1ZSBzZSB2YW4gYSB0b21hciBlbiBjdWVudGEgZGVudHJvIGRlbCBhbsOhbGlzaXMgeSBzZSBlamVjdXRhIGxhIGZ1bmNpw7NuIHF1ZSBzZSBkZWZpbmnDsyBwYXJhIGxhIGV4dHJhY2Npw7NuIGRlIHRvZGFzIGxhcyBub3RpY2lhcy4gDQoNCmBgYHtyfQ0Kbm90aWNpYXNNdWplciA8LSAgbm90aWNpYXNNdWplciAlPiUgZmlsdGVyKERpYXJpbyAlaW4lIERpYXJpb3MpDQpuZXdzID0gbWFwMl9jaHIobm90aWNpYXNNdWplciRMaW5rLCBub3RpY2lhc011amVyJERpYXJpbywgb2J0ZW5lck5vdGljaWFOYWNpb25hbCwgZGljY2lvbmFyaW9fY3NzPUVzdHJ1Y3R1cmEpDQpub3RpY2lhc011amVyJE5vdGljaWEgPSBuZXdzDQpgYGANCg0KYGBge3J9DQpoZWFkKG5vdGljaWFzTXVqZXIgJT4lIHNlbGVjdChGZWNoYSwgRGlhcmlvLCBUaXR1bGFyLCBMaW5rLCBOb3RpY2lhKSkNCmBgYA0KDQpFbCBkYXRhZnJhbWUgcXVlIG5vcyBkYSBjb21vIHJlc3VsdGFkbyByZWNvZ2U6IGxhIGZlY2hhIGVuIHF1ZSBzZSBwdWJsaWPDsyBsYSBub3RpY2lhLCBlbCBkaWFyaW8gcXVlIGxhIHB1YmxpY8OzLCBlbCB0aXR1bGFyLCBlbCBsaW5rIGRlIGFjY2VzbyBhbCBzaXRpbyB3ZWIgZG9uZGUgc2UgZW5jdWVudHJhIGxhIG5vdGljaWEsIHkgbGEgbm90aWNpYSBjb21vIHRhbC4gDQoNCg0KIyMgKioyLjMuIFRva2VuaXphY2nDs24gZGVsIHRleHRvKioNCg0KRGVudHJvIGRlbCBwcm9jZXNvIGRlIHRva2VuaXphY2nDs24gc2UgYSBwcm9jZWRpZG8gYSBkaXZpZGlyIHVuIHRleHRvIGVuIGxhcyB1bmlkYWRlcyBxdWUgbG9zIGNvbmZvcm1hbiwgcGFyYSBlbCBjYXNvIGRlIGVzdHVkaW8gc2UgZGl2aWRpw7MgZW4gZWwgZWxlbWVudG8gbcOhcyBzZW5jaWxsbywgbGFzIHBhbGFicmFzLiBTaW4gZW1iYXJnbywgbcOhcyBhZGVsYW50ZSBzZSBidXNjYSByZWFsaXphciB1biBhbsOhbGlzaXMgZGUgbi1ncmFtYXMgZXNwZWPDrWZpY2FtZW50ZSBiaWdyYW1hcyAqKihuPTIpKiouDQoNCkFsIG1vbWVudG8gZGUgcmVhbGl6YXIgbGEgdG9rZW5pemFjacOzbiwgc2UgaW5jdW1wbGUgZWwgY29uZGljacOzbiB0aWR5IGRlIG51ZXN0cm8gZGF0YWZyYW1lLCB5YSBxdWUgbnVlc3RybyBvYmpldG8gZGUgYW7DoWxpc2lzIHNvbiBsYXMgbm90aWNpYXMgcXVlIGFudGVzIGRlIGxhIHRva2VuaXphY2nDs24gc2UgZW5jb250cmFiYW4gdW5hIGVuIGNhZGEgZmlsYSBkZWwgZGF0YWZyYW1lLCBwYXJhIHBvZGVyIGN1bXBsaXIgY29uIGxhIGVzdHJ1Y3R1cmEgaW5jaWFsLCBzZSBkdXBsaWNhIGNhZGEgZWxlbWVudG8gZGUgbGFzIGRlbcOhcyBjb2x1bW5hcyBsYXMgdmVjZXMgcXVlIHNlYSBuZWNlc2FyaW8sIGFsIHByb2Nlc28gZGVzY3JpdG8gc2UgbG8gY29ub2NlIGNvbW8gZXhwYW5zacOzbiwgeSBzZSBsbyByZWFsaXphIGNvbiBsYSBmdW5jacOzbiAqKnVubmVzdF90b2tlbnMqKiBkZWwgcGFxdWV0ZSAqKnRpZHl0ZXh0KiouDQoNCmBgYHtyfQ0KIG5vdGljaWFzTXVqZXIgJT4lIA0KICB1bm5lc3RfdG9rZW5zKFRva2VuLCBOb3RpY2lhLCB0b2tlbiA9ICJ3b3JkcyIsdG9fbG93ZXIgPSBGKSAlPiUgDQogIG11dGF0ZShUb2tlbiA9IHJlbW92ZU51bWJlcnMoVG9rZW4pKSAlPiUgDQogIG11dGF0ZShUb2tlbiA9IHJlbW92ZVB1bmN0dWF0aW9uKFRva2VuKSkgJT4lIA0KICBzZWxlY3QoVG9rZW4pIA0KYGBgDQoNCg0KYGBge3J9DQp0aWR5X011amVyIDwtICBub3RpY2lhc011amVyICU+JSB1bm5lc3RfdG9rZW5zKG91dHB1dCA9IFRva2VuLCBpbnB1dCA9IE5vdGljaWEpDQoNCnRpZHlfTXVqZXIgJT4lIA0KICAgICAgIHNlbGVjdChEaWFyaW8sIFRpdHVsYXIsIFRva2VuKSAlPiUgDQogICAgICAgaGVhZCgpDQpgYGANCg0KIyMgKioyLjMuIExpbXBpZXphIGRlbCB0ZXh0byAoc3RvcHdvcmRzKSoqDQoNCkRlc3B1w6lzIGRlIGhhYmVyIHJlYWxpemFkbyBsYSB0b2tlbml6YWNpw7NuIGRlbCB0ZXh0byBjb3JyZXNwb25kaWVudGUgYSBsYXMgbm90aWNpYXMsIHNlIHByb2NlZGUgYSBsYSBsaW1waWV6YSBkZSBwYWxhYnJhcyBxdWUgbm8gdGllbmVuIHNpZ25pZmljYWRvIHBhcmEgZWwgYW7DoWxpc2lzIChzdG9wd29yZHMpLCBjb21vIHNlIG9ic2VydmEgYSBjb250aW51YWNpw7NuIGxhcyBwYWxhYnJhcyBtw6FzIGZyZWN1ZW50ZXMgc29uIHByZXBvc2ljaW9uZXMsIGFydMOtY3Vsb3MsIHkgcHJvbm9tYnJlcyBlbiBzdSBtYXlvcsOtYSBxdWUgbm8gcGVybWl0ZW4gb2J0ZW5lciBjb25jbHVzaW9uZXMgc29icmUgbG8gcXVlIHNlIGxvcyBtZWRpb3MgZWxlY3Ryw7NuaWNvcyBlc3TDoW4gdHJhbnNtaXRpZW5kbyBhIHN1cyBsZWN0b3Jlcy4gDQoNCmBgYHtyfQ0KdGlkeV9NdWplciAlPiUgDQogIGNvdW50KFRva2VuKSAlPiUgDQogIHNsaWNlX21heChvcmRlcl9ieSA9IG4sbj0xMCkNCmBgYA0KDQoqKlJlbW9jacOzbiBkZSBwYWxhYnJhcyB2YWPDrWFzKioNCg0KQWwgcmVtb3ZlciBsYXMgcGFsYWJyYXMgcXVlIG5vIGRhbiBzZW50aWRvIGEgbWkgYW7DoWxpc2lzLCBhaG9yYSB5YSBzZSBwdWVkZSBldmlkZW5jaWFyIGNvbW8gZWwgb2JqZXRpdm8gZGUgZXN0dWRpbyB2YSB0b21hbmRvIGZvcm1hLiBTZSBwdWVkZSBldmlkZW5jaWFyIHF1ZSBsb3MgdMOpcm1pbm9zIG3DoXMgZnJlY3VlbnRlcyB5YSBub3MgaGFibGFuIHNvYnJlIGxhIHZpb2xlbmNpYSBjb250cmEgbGEgbXVqZXIgZW4gZWwgRWN1YWRvci4NCg0KYGBge3J9DQpzdG9wd29yZHNfZXNfMSA9IHJlYWRfZXhjZWwoIkN1c3RvbVN0b3BXb3Jkcy54bHN4IikNCm5hbWVzKHN0b3B3b3Jkc19lc18xKSA9IGMoIlRva2VuIiwiRnVlbnRlIikNCnN0b3B3b3Jkc19lc18yID0gdGliYmxlKFRva2VuPXRtOjpzdG9wd29yZHMoa2luZCA9ICJlcyIpLCBGdWVudGU9InRtIikNCnN0b3B3b3Jkc19lcyA9IHJiaW5kKHN0b3B3b3Jkc19lc18xLCBzdG9wd29yZHNfZXNfMikNCnN0b3B3b3Jkc19lcyA9IHN0b3B3b3Jkc19lc1shZHVwbGljYXRlZChzdG9wd29yZHNfZXMkVG9rZW4pLF0NCnJlbW92ZShzdG9wd29yZHNfZXNfMSwgc3RvcHdvcmRzX2VzXzIpDQoNCnN0b3B3b3Jkc19lc1tzYW1wbGUobnJvdyhzdG9wd29yZHNfZXMpLHNpemUgPSAxMCwgcmVwbGFjZSA9IEYpLF0NCg0KdGlkeV9NdWplciA8LSAgdGlkeV9NdWplciAlPiUNCiAgYW50aV9qb2luKHN0b3B3b3Jkc19lcykNCg0KdGlkeV9NdWplciAlPiUgDQogIGNvdW50KFRva2VuKSAlPiUgDQogIHNsaWNlX21heChvcmRlcl9ieSA9IG4sbj04KQ0KYGBgDQoNCkRlbnRybyBkZSBsYXMgcGFsYWJyYXMgbcOhcyBmcmVjdWVudGVzIHNlIGVuY3VlbnRyYW4gbGFzIHBhbGFicmFzIG11amVyIHkgbXVqZXJlcywgcGFyYSBwb2RlciBjb3JyZWdpciBlc3RvIHNlIGhhIHByb2NlZGlkbyBhIGxhIGxlbWF0aXphY2nDs24gZGUgbGFzIHBhbGFicmFzIHBhcmEgcG9kZXIgZXh0cmFlciBzdSBsZW1tYSwgY29uIGxhIHBhbGFicmEgcmHDrXogc2UgZXNwZXJhIHRlbmVyIG1lam9yIHJlc3VsdGFkbyBhbCBtb21lbnRvIGRlIHZpc3VhbGl6YXIgbGFzIHBhbGFicmFzIG3DoXMgZnJlY3VlbnRlcyBwYXJhIGNhZGEgdW5vIGRlIGxvcyBkaWFyaW9zLiBFbCBtw6l0b2RvIHBhcmEgbGVtYXRpemFyIHF1ZSBzZSBlbXBsZWFyw6EgZXMgYSB0cmF2w6lzIGRlIHVuIG1vZGVvIHByZS1lbnRyZW5hZG8sIGNvbmp1bnRhbWVudGUgY29uIGxhIGxpYnJlcsOtYSAqKnVkcGlwZSoqDQoNCkFudGVzIGRlIHByb2NlZGVyIGNvbiBsYSBsZW1hdGl6YWNpw7NuLCBzZSBkYSB1biB2aXN0YXpvIGJyZXZlIGRlIGRpc2N1cnNvIHF1ZSBwcmVzZW50YSBjYWRhIHVubyBkZSBsb3MgZGlhcmlvcywgZXN0byBzZXJ2aXLDoSBwYXJhIHRlbmVyIHVuYSBpZGVhIGRlIHNpIGNhZGEgdW5vIGRlIGVsbG9zIHRpZW5lIHVuIHBhdHLDs24gcXVlIGxvIGRpZmVyZW5jaWUuIA0KDQpgYGB7cn0NCnRpZHlfTXVqZXIlPiUgZ3JvdXBfYnkoRGlhcmlvLCBUb2tlbikgJT4lIA0KICAgICAgICAgICAgICBncm91cF9ieShEaWFyaW8pICU+JQ0KICAgICAgICAgICAgICBjb3VudChUb2tlbikgJT4lDQogICAgICAgICAgICAgIHRvcF9uKDcsIG4pICU+JSANCiAgICAgICAgICAgICAgYXJyYW5nZShEaWFyaW8sIGRlc2MobikpICU+JQ0KICAgICAgZ2dwbG90KGFlcyh4ID0gcmVvcmRlcl93aXRoaW4oVG9rZW4sbixEaWFyaW8pLCB5ID0gbiwgZmlsbCA9IERpYXJpbykpKyAgICAgICAgICAgICAgICAgICAgICBzY2FsZV94X3Jlb3JkZXJlZCgpKw0KICAgICAgICAgICAgICAgIGdlb21fY29sKCkgKw0KICAgICAgICAgICAgICAgIHRoZW1lX2J3KCkgKw0KICAgICAgICAgICAgICAgIGxhYnMoeSA9ICIiLCB4ID0gIiIpICsNCiAgICAgICAgICAgICAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsNCiAgICAgICAgICAgICAgICBjb29yZF9mbGlwKCkgKw0KICAgICAgICAgICAgICAgIGZhY2V0X3dyYXAofkRpYXJpbyxzY2FsZXMgPSAiZnJlZSIsIG5jb2wgPSAyLCBkcm9wID0gVFJVRSkNCmBgYA0KDQpDb21vIHNlIHB1ZWRlIG9ic2VydmFyIGVuIGVsIHNpZ3VpZW50ZSBncsOhZmljbywgbGFzIHBhbGFicmFzIG3DoXMgdXNhZGFzIGVuIGxhcyBub3RpY2lhcyBxdWUgc2UgcHVibGljYSBzb2JyZSBsYSB2aW9sZW5jaWEgY29udHJhIGxhIG11amVyLCBwZXJtaXRlbiBjb25vY2VyIGVsIGNvbnRleHRvIGRlbCBwcm9ibGVtYSBlbiBlbCBFY3VhZG9yLiBMYSB2aW9sZW5jaWEgZGUgZ8OpbmVybyBlbiBkb25kZSBsYSBtdWplciBlcyBsYSB2w61jdGltYSwgZXMgdW4gcHJvYmxlbWEgc29jaWFsIHF1ZSBzZSBidXNjYSBtaXRpZ2FyIGEgdHJhdsOpcyBkZSBsYSBwb2zDrXRpY2EgeSBkZSBlc3RhIGZvcm1hIHNlIGJ1c2NhIGhhY2VyIGN1bXBsaXIgbG9zIGRlcmVjaG9zIGRlIGxhcyBtdWplcmVzLiANCg0KKipMZW1hdGl6YWNpw7NuKioNCg0KUGFyYSBwcm9jZWRlciBjb24gbGEgbGVtYXRpemFjacOzbiBkZSBsYXMgbm90aWNpYXMgc2UgdXNhcsOhIHVuIG1vZGVsbyBlbiBlc3Bhw7FvbCBwcmUtZW50cmVuYWRvLCBhZGljaW9uYWwgYSBlc3RvIHNlIGVsaW1pbmFyw6FuIGxhIHBhbGFicmFzIHF1ZSBnZW5lcmFuIHJ1aWRvIGRlbnRybyBkZWwgYW7DoWxpc2lzLg0KDQpgYGB7cn0NCiMgQ2FyZ2FyIGVsIG1vZGVsbyBwcmUtZW50cmVuYWRvDQp1ZHBpcGU6OnVkcGlwZV9kb3dubG9hZF9tb2RlbCgnc3BhbmlzaCcpICMgRGVzY29tZW50YXIgYWwgZWplY3V0YXIgcG9yIHByaW1lcmEgdmV6DQptb2RlbCA8LSAgdWRwaXBlX2xvYWRfbW9kZWwoZmlsZSA9ICJzcGFuaXNoLWdzZC11ZC0yLjUtMTkxMjA2LnVkcGlwZSIpDQp0aWR5X011amVyX2xlbW1hdGl6YSA8LSAgdWRwaXBlX2Fubm90YXRlKG1vZGVsLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gbm90aWNpYXNNdWplciROb3RpY2lhLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2NfaWQgPSBub3RpY2lhc011amVyJFRpdHVsYXIpDQoNCiMgVHJhbnNmb3JtYXIgbGEgZGF0YSBlbiB1biBmb3JtYXRvIHRpZHkNCnRpZHlfTXVqZXJfbGVtbWF0aXphIDwtICBhc190aWJibGUodGlkeV9NdWplcl9sZW1tYXRpemEpDQpuYW1lcyh0aWR5X011amVyX2xlbW1hdGl6YSlbNl0gPC0gICJUb2tlbiIgDQojIFJlbW9jacOzbiBkZSBzdG9wd29yZHMNCnRpZHlfTXVqZXJfbGVtbWF0aXphMSA8LSAgdGlkeV9NdWplcl9sZW1tYXRpemEgJT4lIA0KICBtdXRhdGUoVG9rZW49cmVtb3ZlUHVuY3R1YXRpb24oVG9rZW4pKSAlPiUgDQogICAgYW50aV9qb2luKHN0b3B3b3Jkc19lcykgJT4lDQogIGZpbHRlcihUb2tlbiE9IiIpDQoNCmBgYA0KDQpTaSBzZSByZXByZXNlbnRhbiBsYSBmcmVjdWVuY2lhIGRlIGxhcyBldGlxdWV0YXMgUE9TLCBzZSBvYnRpZW5lIGVsIGdyw6FmaWNvIHF1ZSBtdWVzdHJhIGxhcyBjYXRlZ29yw61hcyBkZSBQT1MgcXVlIG3DoXMgc2UgcmVwaXRlbiwgYWxnbyBxdWUgaGF5IHF1ZSB0b21hciBlbiBjdWVudGEgcGFydGljdWxhcm1lbnRlIGVuIGVzdGUgYW7DoWxpc2lzIGVzIHF1ZSBlbCBQT1MgZGUgbsO6bWVyb3MgZXMgYmFzdGFudGUgZnJlY3VlbnRlLCBlc3RvIHNlIGRlYmUgYSBxdWUgYWxndW5hcyBub3RpY2lhcyBwdWVkZW4gbW9zdHJhciBjaWZyYXMgYWNlcmNhIGRlIGxhcyB2w61jdGltYXMgZGUgdmlvbGVuY2lhLCB5IGZlbWljaWRpby4gUGFyYSBhaG9uZGFyIG3DoXMgZW4gZXN0ZSB0ZW1hIG5vcyBzZXJ2aXLDoSBlbCBhbsOhbGlzaXMgZGUgYmlncmFtYXMgcXVlIHNlIHJlYWxpemFyw6EgbcOhcyBhZGVsYW50ZS4gDQoNCmBgYHtyfQ0KdGlkeV9NdWplcl9sZW1tYXRpemExJT4lIA0KICBjb3VudCh1cG9zKSAlPiUgDQogIGdncGxvdCgpKw0KICBnZW9tX2NvbChhZXMoeD1yZW9yZGVyKHVwb3MsbikseT1uLGZpbGw9dXBvcykpKw0KICBsYWJzKHg9IkV0aXF1ZXRhIFBPUyIsIHk9IkZyZWN1ZW5jaWEiLCB0aXRsZT0iTm90aWNpYXM6IFZpb2xlbmNpYSBjb250cmEgbGEgbXVqZXIiKSsNCiAgY29vcmRfZmxpcCgpKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIHRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTgpKQ0KYGBgDQoNClNpIHNlIHRvbWEgZW4gY3VlbnRhIGxhcyBjYXRlZ29yw61hcyBQT1MgcXVlIG3DoXMgc2UgcmVwaXRlbiBzZSBwdWVkZSBvcHRlbmVyIG3DoXMgaW5mb3JtYWNpw7NuIGFjZXJjYSBkZWwgY29udGV4dG8gZGVsIHByb2JsZW1hIGRlIGFuw6FsaXNpcy4gTGEgdGlwb3MgZGUgdmlvbGVuY2lhIHF1ZSBzdWZyZW4geSBtw6FzIGRlbnVuY2lhbiBsYXMgbXVqZXJlcyBzb246IGxhIHNleHVhbCwgcHNpY29sw7NnaWNhLCB5IGVjb27Ds21pY2EsIGFkZW3DoXMgc2UgaGFibGEgZGUgbG9zIGNhc29zIGRlIGZlbWljaWRpb3MgcXVlIG9jdXJyZW4gY2FkYSBhw7FvLiANCg0KYGBge3J9DQp0aWR5X011amVyX2xlbW1hdGl6YTElPiUgDQogIGZpbHRlcih1cG9zICVpbiUgYygnTk9VTicsJ1BST1BOJywnVkVSQicsJ0FESicpKSAlPiUgDQogIGNvdW50KHVwb3MsIGxlbW1hKSAlPiUgDQogIGdyb3VwX2J5KHVwb3MpICU+JSANCiAgc2xpY2VfbWF4KG9yZGVyX2J5ID0gbiwgbiA9IDcpICU+JSANCiAgZ2dwbG90KCkrDQogIGdlb21fY29sKGFlcyh4PXJlb3JkZXJfd2l0aGluKGxlbW1hLG4sdXBvcykseT1uLGZpbGw9bGVtbWEpKSsNCiAgc2NhbGVfeF9yZW9yZGVyZWQoKSsNCiAgbGFicyh4PSJMZW1tYSIsIHk9IkZyZWN1ZW5jaWEiLCB0aXRsZT0iTm90aWNpYXM6IFZpb2xlbmNpYSBjb250cmEgbGEgbXVqZXIiKSsNCiAgZmFjZXRfd3JhcCh2YXJzKHVwb3MpLCBzY2FsZXMgPSAiZnJlZSIsIG5jb2wgPSAyKSsNCiAgY29vcmRfZmxpcCgpKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIHRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTgpKQ0KYGBgDQoNCkNhYmUgc2XDsWFsYXIgcXVlIGRlbnRybyBkZSBsYSBsZW1hdGl6YWNpw7NuIGVsIG1vZGVsbyBlbnRyZW5hZG8gbXVlc3RyYSBlcnJvcmVzIGFsIG1vbWVudG8gZGUgZXh0cmFlciBsYSBwYWxhYnJhIHJhw616LiBQb3IgZWplbXBsbywgZW4gbGEgY2F0ZWdvcsOtYSBWRVJCICh2ZXJib3MpIGFwYXJlY2UgbGEgcGFsYWJyYSAqKmFzZXNpbmFkbyoqIHF1ZSBhIHBlc2FyIHF1ZSBsYSBjYXRlZ29yaXphIGNvbW8gdmVyIG5vIGV4dHJhZSBlbCB2ZXJibyBjb21vIHRhbCBxdWUgc2Vyw61hIGFzZXNpbmFyLiANCg0KIyMgKioyLjQuIEFuw6FsaXNpcyBkZSBiaWdyYW1hcyoqDQoNClBhcmEgcG9kZXIgY29uc3RydWlyIGxvcyBiaWdyYW1hcyBzZSByZWFsaXphIGxhIHRva2VuaXphY2nDs24gZGUgbGFzIG5vdGljaWFzIGV4dHJhaWRhcyBkZXNkZSBsYSB3ZWIsIHBlcm8gYWhvcmEgc2UgY2FtYmlhIGVsIGFyZ3VtZW50byBkZSBsYSB0b2tlbml6YWNpw7NuIGEgbi1ncmFtYXMgY29uIHVuIG49Mi4NCg0KYGBge3J9DQp0aWR5X011amVyX2JpZ3JhbWFzIDwtIG5vdGljaWFzTXVqZXIgJT4lIA0KICB1bm5lc3RfdG9rZW5zKG91dHB1dCA9IGJpZ3JhbWEsIA0KICAgICAgICAgICAgICAgIGlucHV0ID0gTm90aWNpYSwNCiAgICAgICAgICAgICAgICB0b2tlbiA9ICduZ3JhbXMnLA0KICAgICAgICAgICAgICAgIG4gPSAyLA0KICAgICAgICAgICAgICAgIHRvX2xvd2VyID0gVCkgDQojIEJpZ3JhbWFzIG1hcyByZXBldGlkb3MNCg0KdGlkeV9NdWplcl9iaWdyYW1hcyAlPiUgDQogIGNvdW50KGJpZ3JhbWEpICU+JSANCiAgc2xpY2VfbWF4KG9yZGVyX2J5ID0gbixuPTEwKQ0KYGBgDQoNCkFsZ3Vub3MgZGUgbG9zIGJpZ3JhbWFzIG3DoXMgdXN1YWxlcyBzb24gcGFsYWJyYXMgdmFjw61hcyBxdWUgZGViZW4gc2VyIGVsaW1pbmFkYXMgcGFyYSBwb2RlciB0ZW5lciB1biBhbsOhbGlzaXMgbcOhcyBsaW1waW8sIHBvciBsbyBxdWUgc2UgcHJvY2VkZSBhIGVsaW1pbmFybGFzLiANCg0KYGBge3J9DQojIHN0b3B3b3Jkcw0KDQpiaWdyYW1hc19tdWplciA8LSAgdGlkeV9NdWplcl9iaWdyYW1hcyAlPiUNCiAgc2VwYXJhdGUoYmlncmFtYSwgYygicGFsYWJyYTEiLCAicGFsYWJyYTIiKSwgc2VwID0gIiAiKSAlPiUNCiAgZmlsdGVyKCFwYWxhYnJhMSAlaW4lIGMoc3RvcHdvcmRzX2VzJFRva2VuKSkgJT4lDQogIGZpbHRlcighcGFsYWJyYTIgJWluJSBjKHN0b3B3b3Jkc19lcyRUb2tlbikpDQoNCmJpZ3JhbWFzX2ZyZWNfbXVqZXIgPC0gIGJpZ3JhbWFzX211amVyICU+JSANCiAgY291bnQoVGl0dWxhciwgcGFsYWJyYTEsIHBhbGFicmEyLCBzb3J0ID0gVFJVRSkgJT4lIA0KICB1bml0ZShiaWdyYW1hLCBwYWxhYnJhMSwgcGFsYWJyYTIsIHNlcCA9ICIgIikNCg0KYmlncmFtYXNfZnJlY19tdWplciAlPiUgc2VsZWN0KGJpZ3JhbWEsIG4pICU+JSBoZWFkKCkNCmBgYA0KDQpFbGltaW5hbmRvIGxhcyBzdG9wd29yZHMgaGEgcGVybWl0aWRvIHF1ZSBhaG9yYSBsb3MgYmlncmFtYXMgdGVuZ2FuIG11Y2hvIG3DoXMgc2VudGlkbyBvcmllbnRhZG8gYSBsbyBxdWUgc2UgZXN0w6EgYnVzY2FuZG8uIFVuIHTDqXJtaW5vIHF1ZSBwYXJ0aWN1bGFybWVudGUgbGxhbWEgbGEgYXRlbmNpw7NuIGVzIHF1ZSBzZSBoYWJsYSBkZSB2aW9sZW5jaWEgcG9sw610aWNhIHkgZXN0ZSB0w6lybWlubyBlc3TDoSByZWxhY2lvbmFkbyBjb24gbGEgcmVzdHJpY2Npw7NuIGRlIGFjY2VzbyBhIGRlcmVjaG9zIGh1bWFub3MgeSBsaWJlcnRhZGVzIHBvciBjdWVzdGlvbmVzIGRlIHNleG8sIHkgbGEgcmVsYWNpb25lcyBkZXNpZ3VhbGVzIGVudHJlIGhvbWJyZSB5IG11amVyIHBvciBlamVtcGxvIGVuIGVsIMOhbWJpdG8gbGFib3JhbC4NCg0KKipSZWQgZGUgYmlncmFtYXMqKg0KDQpMYSByZWxhY2nDs24gZW50cmUgcGFsYWJyYXMgZXMgbXV5IGltcG9ydGFudGUgeSBsbyBxdWUgbm9zIG9mcmVjZSBsYSByZXByZXNlbnRhY2nDs24gZ3LDoWZpY2EgZGUgdW5hIHJlZCBkZSBiaWdyYW1hcyAoZ3JhZm8pIGVzIHBvZGVyIGNvbm9jZXIgbGFzIHRlbcOhdGljYXMgcXVlIHNlIHB1ZWRlbiBlc3RhciB0cmF0YW5kbyBkZW50cm8gZGUgbGFzIG5vdGljaWFzLg0KDQpgYGB7cn0NCmJpZ3JhbWFfZ3JhZm9fbXVqZXIgPC0gIGJpZ3JhbWFzX211amVyICU+JQ0KICBjb3VudChwYWxhYnJhMSwgcGFsYWJyYTIsIHNvcnQgPSBUUlVFKSAlPiUgDQogIGZpbHRlcihuID49IDUpICU+JQ0KICBncmFwaF9mcm9tX2RhdGFfZnJhbWUoKQ0KDQpiaWdyYW1hX2dyYWZvX211amVyDQpgYGANCg0KYGBge3J9DQoNCnNldC5zZWVkKDE5OTgpDQoNCmdncmFwaChiaWdyYW1hX2dyYWZvX211amVyLCBsYXlvdXQgPSAiZnIiKSArDQogIGdlb21fZWRnZV9saW5rKGFlcyhlZGdlX2FscGhhID0gbiksIHNob3cubGVnZW5kID0gRkFMU0UsDQogICAgICAgICAgICAgICAgIGFycm93ID0gYSwgZW5kX2NhcCA9IGNpcmNsZSguMDcsICdpbmNoZXMnKSkgKw0KICBnZW9tX25vZGVfcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIiwgc2l6ZSA9IDUpICsNCiAgZ2VvbV9ub2RlX3RleHQoYWVzKGxhYmVsID0gbmFtZSksIHZqdXN0ID0gMSwgaGp1c3QgPSAxKSArDQogIHRoZW1lX3ZvaWQoKQ0KDQoNCmBgYA0KDQpVbiBwZXF1ZcOxbyByZXN1bWVuIGRlbCBncmFmbyBub3MgZGEgbGEgaWRlYSBkZSBsYSBpbmZvcm1hY2nDs24gcXVlIHNlIGVzdMOhIHRyYW5zbWl0aWVuZG8gYSBsb3MgbGVjdG9yZXMgZGUgbG9zIGRpYXJpb3MgdG9tYWRvcyBlbiBjdWVudGEgcGFyYSBlc3RlIHRyYWJham8uIFNlIGhhYmxhIG11Y2hvIGRlbCBlbXBvZGVyYW1pZW50byBmZW1lbmlubywgcXVlIGJ1c2NhIGEgdHJhdsOpcyBkZSBsYSBvcmdhbml6YWNpw7NuIGVuIGxhcyByZWRlcyBzb2NpYWxlcyBwcm9udWNpYXJzZSBjb21vIHNvY2llZGFkIGNpdmlsIGV4aWdpZW5kbyBlbCBjdW1wbGltaWVudG8gZGUgc3VzIGRlcmVjaG9zYSB5YSBxdWUgbm8gb2J0aWVuZW4gYXl1ZGEgZGUgbGFzIG9yZ2FuaXphY2lvbmVzIGd1YmVybmFtZW50YWxlcyA7IGxvcyBkaXN0aW50b3MgdGlwb3MgZGUgdmlvbGVuY2lhIHF1ZSBzdWZyZW4gbGFzIG11amVyZXMgZW4gZWwgw6FtYml0byBmYW1pbGlhciwgeSBsYWJvcmFsOyB5IGZpbmFsbWVudGUgbGFzIGNpZnJhcyBtdWVydGVzIHZpb2xlbnRhcyB5IGZlbWljaWRpb3MgZW4gZWwgRWN1YWRvci4NCg0KIyMgKiozLiBBcHJlbmRpemFqZSBubyBzdXBlcnZpc2FkbyoqDQoNClVuYSBkZSBsYXMgdmVudGFqYXMgZGUgcG9kZXIgYXBsaWNhciB1biBtb2RlbG8gbm8gc3VwZXJ2aXNhZG8sIGVzIGNvbm9jZXIgbG9zIHBhdHJvbmVzIHF1ZSBzaWd1ZW4gbG9zIGRhdG9zIHkgcG9kZXIgaXIgZm9ybWFuZG8gY2x1c3RlcnMuIFBhcmEgcmVhbGl6YXIgbGEgY2x1c3RyaXphY2nDs24gZGUgbGFzIG5vdGljaWFzIHNlIHVzYSBlbCBtb2RlbGFkbyBkZSB0w7NwaWNvcy4gUGFyYSBlc3RlIG1vZGVsYWRvIHNlIHV0aWxpemFyw6EgbGEgdMOpY25pY2EgZGUgQXNpZ25hY2nDs24gTGF0ZW50ZSBkZSBEaXJpY2hsZXQgKExEQSkuIFBhcmEgcG9kZXIgdXRpbGl6YXIgZWwgYWxnb3JpdG1vIGRlIExEQSwgc2UgcGFydGUgZGUgbGEgY3JlYWNpw7NuIGRlIGxhIG1hdHJpeiBkb2N1bWVudG8tdMOpcm1pbm86DQoNCmBgYHtyfQ0KdGlkeV9NdWplcl9tb2RlbCA8LSB0aWR5X011amVyX2xlbW1hdGl6YTElPiUgDQogIGZpbHRlcighdXBvcyAlaW4lIGMoIlgiLCJOVU0iLCJQVU5DVCIsIlNZTSIsIkRFVCIpLA0KICAgICAgICAgIWxlbW1hICVpbiUgc3RvcHdvcmRzX2VzJFRva2VuLA0KICAgICAgICAgIWlzLm5hKGxlbW1hKSkNCg0KIyBDcmVhY2nDs24gZGUgbGEgbWF0cml6IGRvY3VtZW50by10w6lybWlubw0KZHRtX25vdGljaWFzIDwtIHRpZHlfTXVqZXJfbW9kZWwgJT4lDQogIGNvdW50KGRvY19pZCwgbGVtbWEsIHNvcnQgPSBUUlVFKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBjYXN0X2R0bShkb2NfaWQsIGxlbW1hLCBuKQ0KDQpkdG1fbm90aWNpYXMNCmBgYA0KQWhvcmEgcGFyYSBwb2RlciBnZW5lcmFyIGxhcyB0ZW3DoXRpY2FzIHNlIG5lY2VzaXRhIGRlZmluaXIgdW4gbsO6bWVybyBrIGRlIGdydXBvcyBxdWUgc2UgdmFuIGEgZm9ybWFyLCBlbCBuw7ptZXJvIGRlIHRlbcOhdGljYSB0b21hZG9zIHNlIGRldGVybWlubyB0cmFzIHJlYWxpemFyIGFsZ3VuYXMgcHJ1ZWJhcywgYXVucXVlIHNlIHBvZHLDrWEgaGFiZXIgdXRpbGl6YWRvIHTDqWNuaWNhcyBtw6FzIGF2YW56YWRhcyBwYXJhIGRldGVybWluYXIgZWwgbsO6bWVybyDDs3B0aW1vIGRlIGdydXBvcy4gDQoNCmBgYHtyfQ0KbGlicmFyeSh0b3BpY21vZGVscykNCiMgTW9kZWxhZG8gZGUgdMOzcGljb3MgY29uIExEQQ0KayA9IDMNCnNlZWQgPSAxOTk4DQpsZGEgPSBMREEoZHRtX25vdGljaWFzLCBrID0gaywgbWV0aG9kID0gIkdJQkJTIiwgY29udHJvbCA9IGxpc3Qoc2VlZCA9IHNlZWQpKQ0KY2xhc3MobGRhKQ0KYGBgDQpUcmFzIGhhYmVyIHJlYWxpemFkbyBsYSBtb2RlbGl6YWNpw7NuIHNlIG9udGllbmUgbGEgbWF0cml6IGJldGEsIGxhIGN1YWwgbm9zIHBlcm1pdGUgc2FiZXIgbGEgcHJvYmFiaWxpZGFkIGRlIHF1ZSBjYWRhIHTDqXJtaW5vIHB1ZWRhIHBlcnRlbmVjZXIgYSB1bmEgdGVtw6F0aWNhIGVuIGVzcGVjw61maWNvLiBQb3IgZWplbXBsb2wgbGEgcGFsYWJyYSB2aW9sZW5jaWEgdGllbmUgbcOhcyBwcm9iYWJpbGlkYWQgZGUgcGVydGVuZWNlciBhbCBsYSB0ZW3DoXRpY2EgbsO6bWVybyAxLg0KDQpgYGB7cn0NCiMgUHJvYmFiaWxpZGFkZXMgcG9yIHTDqXJtaW5vDQpsZGFfdGlkeSA9IHRpZHkobGRhLCBtYXRyaXg9ImJldGEiKQ0KbGRhX3RpZHkgJT4lIGZpbHRlcih0ZXJtID09ICJ2aW9sZW5jaWEiKSAlPiUgYXJyYW5nZShkZXNjKGJldGEpKQ0KYGBgDQoNCioqVG9wIGRlIHTDqXJtaW5vcyBkZSBjYWRhIHRlbcOhdGljYSoqDQoNCkxhcyB0cmVzIHRlbcOhdGljYXMgcXVlIHNlIG9idHV2aWVyb24gbm9zIGRhbiBpZGVhIGRlIGxvcyBzaWd1aWVudGU6DQoNCi0gKipUZW3DoXRpY2EgMSoqOiBIYWJsYSBzb2JyZSBsYSB2aW9sZW5jaWEgc2V4dWFsIHF1ZSBzdWZyZW4gbGFzIG11amVyZXMsIGFkb2xlc2NlbnRlcyB5IG5pw7FhcywgeSBxdWUgc2UgbmVjZXNpdGEgdW5hIGF0ZW5jacOzbiBhIHRyYXbDqXMgZGUgcG9sw610aWNhcyBxdWUgcHVlZGEgZ2FyYW50aXphciBzdXMgZGVyZWNob3MuDQoNCi0gKipUZW3DoXRpY2EgMioqOiBTZSBoYWNlIG1lbmNpw7NuIGFsIDI1IGRlIG5vdmllbWJyZSBmZWNoYSBlbiBsYSBxdWUgc2UgY2VsZWJyYSBlbCBkw61hIGNvbnRyYSBsYSB2aW9sZW5jaWEgZGUgbGEgbXVqZXIsIHkgbGEgb3JnYW5pemFjacOzbiBkZSBtYXJjaGFzIHF1ZSBzZSBlZmVjdHVhcm9uIGVuIHRvZG8gZWwgcGHDrXMsIHBhcmEgcmVjbGFtYXIganVzdGljaWEgcG9yIGxhcyB2aWRhcyBwZXJkaWRhcyBhIGNhdXNhcyBkZSBsb3MgZmVtaWNpZGlvcy4gDQoNCi0gKipUZW3DoXRpY2EgMyoqOiBMYSDDumx0aW1hIHRlbcOhdGljYSB0cmF0YSBzb2JyZSBsYSB2aW9sZW5jaWEgZGUgZ8OpbmVybyBxdWUgZXMgb3RybyB0aXBvIGRpZmVyZW50ZSBkZSB2aW9sZW5jaWEsIHBlcm8gcXVlIGVzdGEgcmVsYWNpb25hZG8gYWwgb2JqZXRpdm8gZGUgZXN0dWRpbywgeSBxdWUgaGFjZSBtZW5jacOzbiBhIGxhIGNyaXNpcyBzYW5pdGFyaWEgZGVsIENPVklELTE5IHkgbGFzIGFncmVzaW9uZXMgZGVudW5jaWFkYXMgZW4gbGEgZmlzY2Fsw61hIGR1cmFudGUgdG9kbyBsYSB0ZW1wb3JhZGEgZGVsIGNvbmZpbmFtaWVudG8uDQoNCg0KYGBge3J9DQojIEdyw6FmaWNvIGRlbCB0b3AgNSBkZSBwYWxhYnJhcyBwb3IgdGVtw6F0aWNhDQpsZGFfdGlkeSAlPiUgDQogIGFycmFuZ2UodG9waWMsIGRlc2MoYmV0YSkpICU+JSANCiAgZ3JvdXBfYnkodG9waWMpICU+JSANCiAgbXV0YXRlKHJuPTE6bigpKSAlPiUgDQogIGZpbHRlcihybjw9MTIpICU+JSANCiAgbXV0YXRlKHRvcGljPXBhc3RlMCgiVGVtw6F0aWNhICIsdG9waWMpKSAlPiUgDQogIGdncGxvdChhZXMocmVvcmRlcl93aXRoaW4odGVybSxiZXRhLHRvcGljKSxiZXRhLGxhYmVsPXRlcm0sZmlsbD1hcy5mYWN0b3IodG9waWMpKSkrDQogIHNjYWxlX3hfcmVvcmRlcmVkKCkrDQogIGdlb21fY29sKCkrDQogIGZhY2V0X3dyYXAodmFycyh0b3BpYyksIHNjYWxlcyA9ICJmcmVlIixuY29sID0gMikrDQogIGxhYnMoeD1OVUxMLHk9IkJldGEiLHRpdGxlPSJUb3AgMTAgdMOpcm1pbm9zIExEQSIpKw0KICBjb29yZF9mbGlwKCkrDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgdGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xMikpDQpgYGANCg0KVGFtYmnDqW4gc2UgcHVlZGUgdHJhYmFqYXIgY29uIGxhIG1hdHJpeiBnYW1tYSBwYXJhIGNvbm9jZXIgcXVlIHByb2JhYmlsaWRhZCB0aWVuZSBjYWRhIGRvY3VtZW50byBkZSBwZXJ0ZW5lY2VyIGEgdW5hIGRlIGxhcyB0cmVzIHRlbcOhdGljYXMuIFBhcmEgZWxsbyBzZSBvYnR1dm8gdW5hIG11ZXN0cmEgZGUgdHJlcyBkb2N1bWVudG8gYWxlYXRvcmlvcyBwYXJhIGNvbm9jZXIgYSBxdWUgdGVtw6F0aWNhIHBlcnRlbmVjZW4uDQoNCmBgYHtyfQ0KIyBQcm9iYWJpbGlkYWRlcyBwb3IgZG9jdW1lbnRvDQpzZXQuc2VlZCgxMjMpDQpub3RpY2lhc19nYW1tYSA8LSBzYW1wbGUodGlkeV9NdWplcl9tb2RlbCRkb2NfaWQsMyxyZXBsYWNlID0gRikNCg0KDQp0aWR5KGxkYSwgbWF0cml4PSJnYW1tYSIpICU+JSANCiAgZmlsdGVyKGRvY3VtZW50ICVpbiUgbm90aWNpYXNfZ2FtbWEgKSAlPiUgDQogIGFycmFuZ2UoZG9jdW1lbnQsIGRlc2MoZ2FtbWEpKSAlPiUgDQogIGdyb3VwX2J5KGRvY3VtZW50KSAlPiUgDQogIG11dGF0ZShybj0xOm4oKSkgJT4lIA0KICBmaWx0ZXIocm49PTEpDQpgYGANCg0KTWVkaWFudGUgZWwgZ3LDoWZpY28gc2UgcHVlZGUgZXZpZGVuY2lhciBhIHF1ZSB0ZW3DoXRpY2EgcGVydGVuZWNlIGNhZGEgbm90aWNpYSB5IGVmZWN0aXZhbWVudGUgc2UgY29tcHJ1ZWJhIGFsIHJldmlzYXIgbG9zIHTDrXR1bGFyZXMgZGUgbGFzIHRyZXMgbm90aWNpYXMgdG9tYWRhcyBhbCBhemFyLiBQb3IgdW4gbGFkbyBsYSB0ZW3DoXRpY2EgdW5vIHF1ZSBoYWJsYSBkZSBsYSBidXNxdWVkYSBkZSBqdXN0aWNpYSBwb3IgbG9zIHRlbcOhcyBkZSBmZW1pY2lkaW8sIHkgcG9yIGVsIG90cm8gbGEgcmVsYWNpb25hZGEgYSBsYSB2aW9sZW5jaWEgY29udHJhIGxhcyBtdWplcmVzIGNvbW8gdGFsLiANCg0KYGBge3J9DQojIENvbXBvc2ljacOzbiBkZSBjYWRhIGRvY3VtZW50bw0KdGlkeShsZGEsIG1hdHJpeCA9ICJnYW1tYSIpICU+JQ0KICBmaWx0ZXIoZG9jdW1lbnQgJWluJSBub3RpY2lhc19nYW1tYSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHg9ZG9jdW1lbnQseT1nYW1tYSxmaWxsPWFzLmZhY3Rvcih0b3BpYykpKSsNCiAgZ2VvbV9jb2woKSsNCiAgbGFicyh4PSJUaXR1bGFyIiwgeT0iR2FtbWEiLCBmaWxsPSJUZW3DoXRpY2EiKSsNCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBjKCInU29uaWRvcyBkZSBsYSBNZW1vcmlhJyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIkV2ZW50byBwb3IgbGEgbm8gXG52aW9sZW5jaWEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICJOacOxYXMgZGUgRWN1YWRvciBlbGFib3Jhcm9uIFxuaW5mb3JtZSBwYXJhIGxhIENlZGF3IikpDQoNCg0KYGBgDQoNCiMjICoqNC4gQ29uY2x1c2lvbmVzKioNCg0KLSBFbCBwcm9ibGVtYSBkZSBsYSB2aW9sZW5jaWEgY29udHJhIGxhIG11amVyIGVzIHVuIG1hbCBxdWUgZHVyYW50ZSBlc3RhIHBhbmRlbcOtYSBhIHJldG9tYWRvIGZ1ZXJ6YSB5YSBxdWUgc2UgaGFibGEgZGUgdmlvbGVuY2lhIGludHJhZmFtaWxpYXIsIHNleHVhbCwgZWNvbsOzbWljYSBlIGluY2x1c28gcGF0cmltb25pYWwuIExvIHF1ZSBzZSBwaWRlIGVzIHJlZm9ybWFyIGVsIGPDs2RpZ28gb3Jnw6FuaWNvIGludGVncmFsIHBlbmFsLCBwZXJvIGxvcyBlbnRlcyBndWJlcm5hbWVudGFsZXMgaGFjZW4gY2FzbyBvbWlzbyBmcmVudGUgYSBlc3RlIHByb2JsZW1hLCBlcyBwb3IgZXN0YSByYXrDs24gcXVlIHNlIGhhYmxhIGRlIGxhIHZpb2xlbmNpYSBwb2zDrXRpY2EgcXVlIHN1ZnJlbiBsYXMgbXVqZXJlcyB5IHF1ZSBhbCBubyBzZW50aXJzZSByZXNwYWxkYWRhcyBwb3IgbGEganVzdGljaWEgZW4gZWwgRWN1YWRvciwgZGViZW4gYSB0cmF2w6lzIGRlIG9yZ2FuaXphY2lvbmVzIGNpdmlsZXMgYnVzY2FyIGF5dWRhIHBhcmEgaGFjZXIgY3VtcGxpciBzdXMgZGVyZWNob3MuIA0KDQotIExvcyBtZWRpb3MgZGUgY29tdW5pY2FjacOzbiBxdWUgc2UgYW5hbGl6YXJvbiBwYXJlY2VuIHRlbmVyIHVuIG1pc21vIHBhdHLDs24gYWwgbW9tZW50byBkZSBwcmVzZW50YXIgc3VzIG5vdGljaWFzLCBtdWVzdHJhbiBsYXMgY2lmcmFzIGRlIHZpb2xlbmNpYSwgcGVybyBubyBzZSBoYWJsYSBkZSB1bmEgcG9zaWJsZSBzb2x1Y2nDs24gZW1pdGlkYSBwb3IgYWxnw7puIGVudGUgZ3ViZXJuYW1lbnRhbCwgc29sbyBzZSB0cmF0YSBkZSBjYXNvcyBlbiBkb25kZSBsYSBtdWplciBlcyB2w61jdGltYSBubyBzb2xvIGVuIHN1IGVudG9ybm8gZmFtaWxpYXIsIHNpIG5vIHRhbWJpw6luIHNlIGRldGFsbGEgZWwgYWNvc28geSBkaXNjcmltaW5hY2nDs24gcXVlIHN1ZnJlbiBlbiBlbCDDoW1iaXRvIGxhYm9yYWwuIEVsIG1lbnNhamUgZXMgY2xhcm8gbGFzIG11amVyZXMgc2Ugc2llbnRlbiB2dWxuZXJhYmxlcyBlbiB1biBwYcOtcyBkb25kZSBsYSB2aW9sZW5jaWEgZGUgZ8OpbmVybyB5IGNvbnRyYSBsYSBtdWplciBzZSBxdWVkYSBzb2xvIGVuIGNpZnJhcy4gDQoNCg0KDQoNCg==