Análisis de políticos
1- Descargar tweets
Creo una lista de cuentas de las cuales voy a descargar sus tweets, y además una asignación para saber a quién representa cada cuenta.
La idea original es tener 4 miembros de cada uno de los dos partidos principales, los últimos 4 candidatos en las elecciones 2019 y también las 4 cuentas partidarias en Twitter.
- Frente de todos: Alberto Fernández, Cristina Kirchner, Gines González García y Axel Kicillof
- PRO: Mauricio Macri, Horacio Rodríguez Larreta, Fernán Quiroz y Patricia Bullrich
- Otros candidatos: José Luis Espert, Roberto Lavagna, Juan José Gómez Centurión y Nicolas del Caño
- Partidarias: Frente de Todos, PRO, GEN y Unión Cívica Radical
print("Muestra")
[1] "Muestra"
print(Tweets_DF %>%
select(text)%>%
head(5))
NA
2-Limpieza
Vamos a limpiar ciertos elementos que pueden complicar el análisis del texto, como son los links, los números, los gráficos y pasar todo a minúscula.
Además, creamos varios campos para lo que es la fecha, desagregando el campo en varios distintos, que se van a utilizar a futuro, y también se actualiza el horario a la zona horaria donde fue realizado el tweet (Argentina).
Finalmente filtramos por fecha, la idea es tener solo tweets del periodo 1/3/2020 hasta la fecha de publicación (Sep/2020)
Tweets_DF <-
Tweets_DF %>%
##Todo el texto a minuscula##
mutate(text = tolower(text)) %>%
##Sin graficos##
mutate(text = gsub("[^[:graph:]]", " ", text)) %>%
##Sin links##
mutate(text = gsub("http//S", " ", text)) %>%
##Sin numeros##
mutate(text = gsub("[[:digit:]]", " ", text)) %>%
##Sin numeros##
mutate(text = chartr('áéíóúñ','aeioun',text)) %>%
##Cambiamos a la zona horaria correspondiente##
mutate(created_at = with_tz(created_at, "America/Argentina/Buenos_Aires"))%>%
##Separamos en dia y hora el campo created_at##
separate(created_at, into = c("date", "hour"), sep = " ")%>%
##Separamos la hora en hora,minutos y segundos##
separate(hour, into = c("hour", "minutes","seconds"), sep = ":")%>%
##Cambiamos la columna con el nombre del politico##
rename(Politico = screen_name) %>%
##Creamos una columna con el numero de año, mes, dia, nombre de dia y de mes.##
mutate(periodo = year(date),
mes = month(date, label = F, abbr = F),
dia = as.numeric(day(date)),
dia_sem = wday(date, label = T, abbr = F, week_start = 1),
dia_per = yday(date),
date = as.Date(date)
) %>%
##Solo vamos a utilizar info de marzo 2020 en adelante##
filter(periodo == 2020 & mes > 2)
print("Muestra")
[1] "Muestra"
print(Tweets_DF %>%
select(Politico, status_id, periodo, mes, dia)%>%
head(10))
NA
3-Normalización
Normalizamos algunos campos, para ayudar al análisis y también a la visualización.
Le agregamos el partido a cada uno de los analizados, y además cambiamos su nombre del @ que vemos en Twitter, a un nombre fácil de entender para todos
Tweets_DF <-
Tweets_DF %>%
mutate (Partido = ifelse (Politico == "alferdez", "Peronismo",
ifelse (Politico == "CFKArgentina", "Peronismo",
ifelse (Politico == "ginesggarcia", "Peronismo",
ifelse (Politico == "Kicillofok", "Peronismo",
ifelse (Politico == "UCRNacional", "cuenta partidaria",
ifelse (Politico == "FrenteDeTodos", "cuenta partidaria",
ifelse (Politico == "proargentina", "cuenta partidaria",
ifelse (Politico == "PartidoGEN", "cuenta partidaria",
ifelse (Politico == "mauriciomacri", "PRO",
ifelse (Politico == "PatoBullrich", "PRO",
ifelse (Politico == "horaciorlarreta", "PRO",
ifelse (Politico == "FernanQuirosBA", "PRO",
"otros candidatos")))))))))))))
Tweets_DF <-
Tweets_DF %>%
mutate (Politico = ifelse (Politico == "alferdez", "A.Fernandez",
ifelse (Politico == "CFKArgentina", "C.Kirchner",
ifelse (Politico == "ginesggarcia", "Gines.GG",
ifelse (Politico == "Kicillofok", "A.Kicillof",
ifelse (Politico == "UCRNacional", "UCR",
ifelse (Politico == "FrenteDeTodos", "TODOS",
ifelse (Politico == "proargentina", "PRO",
ifelse (Politico == "PartidoGEN", "GEN",
ifelse (Politico == "mauriciomacri", "M.Macri",
ifelse (Politico == "PatoBullrich", "P.Bullrich",
ifelse (Politico == "horaciorlarreta", "H.Larreta",
ifelse (Politico == "FernanQuirosBA", "F.Quiros",
ifelse (Politico == "NicolasdelCano", "N.DelCaño",
ifelse (Politico == "jlespert", "J.Espert",
ifelse (Politico == "RLavagna", "R.Lavagna",
"GomezCenturion"
))))))))))))))))
print("Muestra")
[1] "Muestra"
print(Tweets_DF %>%
select(Politico, Partido, source)%>%
tail(10))
4-Cantidad de tweets
La primera aproximación que vamos a tener, es la cantidad de veces que twitteo cada uno desde marzo del 2020 hasta la fecha de publicación del informe.
Se presentan diferencias considerables entre todos, se deberá normalizar o utilizar proporciones más de una vez
- Macri y Lavagna tienen menos tweets que el resto
- Cristina Kirchner es también de poca participación
- Las cuentas de Frente de Todos, Espert, Del Caño y la UCR son la de más utilización
Cantidad_tweets = Tweets_DF %>%
group_by(Politico, Partido) %>%
count(Politico)
Cantidad_tweets%>%
ggplot()+
aes(x=reorder(Politico, n), y= n, fill= Politico) +
geom_col() +
facet_wrap("Partido", scales = "free_y") +
coord_flip() +
labs(title = "Cantidad total de tweets", x = "tweets", y = "Cantidad") +
tema1

5-Fecha de los tweets
Vemos cuando han ido publicando cada uno de los analizados sus tweets, con el fin de mostrar en que época tuvieron más o menos acción.
- En el caso de la cuenta de Frente de todos, como tuvo más de 3200 tweets, el análisis arranca desde los primeros días de abril
Tweets_DF %>%
filter(Partido == "PRO") %>%
ggplot(aes(x = as.Date(date), fill = Politico)) +
geom_histogram(position = "identity", bins = 20, show.legend = FALSE) +
scale_x_date(date_labels = "%d-%m", date_breaks = "1 month") +
labs(x = "fecha de publicación", y = "número de tweets") +
facet_wrap(~ Politico, ncol = 1) +
tema2 +
theme(axis.text.x = element_text(angle = 90))

Tweets_DF %>%
filter(Partido == "Peronismo") %>%
ggplot(aes(x = as.Date(date), fill = Politico)) +
geom_histogram(position = "identity", bins = 20, show.legend = FALSE) +
scale_x_date(date_labels = "%d-%m", date_breaks = "1 month") +
labs(x = "fecha de publicación", y = "número de tweets") +
facet_wrap(~ Politico, ncol = 1) +
tema1 +
theme(axis.text.x = element_text(angle = 90))

Tweets_DF %>%
filter(Partido == "otros candidatos") %>%
ggplot(aes(x = as.Date(date), fill = Politico)) +
geom_histogram(position = "identity", bins = 20, show.legend = FALSE) +
scale_x_date(date_labels = "%d-%m", date_breaks = "1 month") +
labs(x = "fecha de publicación", y = "número de tweets") +
facet_wrap(~ Politico, ncol = 1) +
tema1 +
theme(axis.text.x = element_text(angle = 90))

Tweets_DF %>%
filter(Partido == "cuenta partidaria") %>%
ggplot(aes(x = as.Date(date), fill = Politico)) +
geom_histogram(position = "identity", bins = 20, show.legend = FALSE) +
scale_x_date(date_labels = "%d-%m", date_breaks = "1 month") +
labs(x = "fecha de publicación", y = "número de tweets") +
facet_wrap(~ Politico, ncol = 1) +
tema2 +
theme(axis.text.x = element_text(angle = 90))

6-Cantidad de tweets sobre COVID
El tema más importante del año es el coronavirus, la idea es ver qué porcentaje de los tweets realizados estos meses trato sobre el coronavirus, para eso se van a buscar palabras claves que determinen que el tweet trata sobre la pandemia.
Claramente los ministros son los que más hablaron sobre el Coronavirus, con el 75% de sus tweets.
Siguen los gobernadores Kiciloff y Larreta, que trataron sobre la evolución de la pandemia en sus distritos.
En menor medida hablaron los líderes de los dos principales partidos.
Del Caño es el que más hablo entre los otros candidatos, lo sigue Espert, mientras que Lavagna y Gómez Centurión hablaron muy poco.
Las cuentas partidarias, salvo las de la UCR no fueron muy usadas para hablar sobre el Coronavirus
#Buscamos tweets con la palabra covid
Palabras_covid <- "covid|covid-19|covid19|coronavirus|#covid|#covid-19|#covid19|#coronavirus|test|testeo|testeos|pcr|serologico|hisopado|antibioticos|aplanar|curva|cuarentena|contagio|enfermedad|epidemia|pandemia|alarma|gel|cuidados|incubacion|jabon|barbijo|barbijos|mascarilla|mascarillas|mers|sars|vacuna|wuhan|oxford|astra|zeneca|transmision|exponencial|casos|duplicacion|distanciamiento|colapso|salud|letalidad|mortalidad|ventilador|icu|uci|uti|inmunidad|serologica|distanciamiento|virus|asintomatico|caso sospechoso|olfato|gusto|terapia|saturacion|clinica|positividad|positivios|rebaño|inmunidad|hospital|hospitales|aspo|aislamiento"
Tweets_DF$Covid <- grepl(Palabras_covid, Tweets_DF$text, ignore.case ="True")
Tweets_DF %>%
count(Politico, Partido,Covid) %>%
group_by(Politico) %>%
mutate(Proporcion = n / sum(n)) %>%
mutate(Covid = ifelse(Covid == T, "Sobre COVID", "Otro tema"))%>%
ggplot() +
aes(Politico, Proporcion, fill = Covid) +
geom_col() +
scale_y_continuous(labels = percent_format()) +
facet_wrap("Partido", scales = "free") +
theme(legend.position = "top")

7- Wordcloud
La idea de la nube de palabras es saber cuáles son las 200 palabras que más se usaron por los analizados estos meses, como era de esperarse sobresalen “coronavirus”, “covid”, “pandemia” o “cuarentena”
tuits_tokens <-
Tweets_DF %>%
unnest_tokens(input = text, output = Palabra, token = "words") %>%
select(Politico, Palabra, status_id, periodo, mes, hour, Partido) %>%
mutate(status_id = gsub("<(.*)>+?", "", status_id)) %>%
filter(!Palabra %in% stopwords("es")) %>%
filter(!Palabra %in% c("t.co", "https", "vÃa", "youtube", "amp"))
Palabras_sinhoymas = tuits_tokens %>%
filter(Palabra != "mas" & Palabra != "hoy")
wordcloud(words = Palabras_sinhoymas$Palabra,
scale=c(2,.2),
max.words=200, random.order=FALSE, rot.per=0.35,
colors=brewer.pal(8, "Dark2"),
)
transformation drops documentstransformation drops documents

8-Descargamos un diccionario
Descargamos un diccionario que tiene las palabras en español, y le asigna un valor entre -5 a 5, mostrando la positividad o negatividad de la palabra.
Eliminamos la palabra “No” que la toma como negativa, cuando en español es un conector a veces, y la palabra “Negro” (Nigga) que la toma con el máximo valor negativo
download.file("https://raw.githubusercontent.com/jboscomendoza/rpubs/master/sentimientos_afinn/lexico_afinn.en.es.csv",
"lexico_afinn.en.es.csv")
probando la URL 'https://raw.githubusercontent.com/jboscomendoza/rpubs/master/sentimientos_afinn/lexico_afinn.en.es.csv'
Content type 'text/plain; charset=utf-8' length 51625 bytes (50 KB)
downloaded 50 KB
afinn <- read.csv("lexico_afinn.en.es.csv", stringsAsFactors = F, fileEncoding = "latin1") %>%
tbl_df()
afinn$Puntuacion <- ifelse(afinn$Palabra == "no", 0, afinn$Puntuacion)
afinn$Puntuacion <- ifelse(afinn$Palabra == "negro", 0, afinn$Puntuacion)
print("Muestra")
[1] "Muestra"
afinn %>%
select(Palabra, Puntuacion) %>%
arrange(Puntuacion) %>%
print(head(10))
afinn %>%
select(Palabra, Puntuacion) %>%
arrange(-Puntuacion) %>%
print(tail(10))
9- Separacion de palabras
Separamos las distintas palabras que usaron cada uno de los políticos en sus tweets, y eliminamos algunas palabras propias de Twitter y las llamadas stopwords que son las palabras más frecuentes en el idioma español.
print ("Muestra")
[1] "Muestra"
print (tuits_tokens %>%
select(Politico, Palabra) %>%
head (10))
10- Le damos valor a las palabras
Unimos el diccionario de puntuación con las palabras que uso cada uno de los analizados, con el fin de que cada palabra tenga un valor, y nos sirva para analizar que escribió cada político.
Las palabras serán: - Si tienen valor mayor a 0 Positivas
tuits_tokens_emociones <-
tuits_tokens %>%
inner_join(afinn, ., by = "Palabra") %>%
mutate(Calificacion = ifelse(Puntuacion > 0, "Positiva",
ifelse(Puntuacion == 0, "Neutral",
"Negativa")
)
)
print ("Muestra")
[1] "Muestra"
print (tuits_tokens_emociones %>%
select(Politico, Palabra, Puntuacion, Calificacion) %>%
tail (10))
11- ¿Quién usa más caracteres?
La idea es buscar cual es el promedio del largo (cantidad de caracteres) de los tweets que realiza cada uno de los analizados.
Mientras más a la derecha este la caja, más largo son los tweets que escriben, en ese aspecto se destacan: - Lavagna, Patricia Bullrich, Larreta y Fernán Quirós son los que escriben los tweets más largos. - Aquellos relacionados al PRO son de escribir tweets más largos
Tweets_DF %>%
ggplot()+
aes(x= Politico, y= display_text_width, color= Politico) +
geom_boxplot () +
labs(title = "Largo promedio del tweet", x = "Politico", y = "Cantidad caracteres") +
coord_flip() +
tema1

12- ¿Quién usa más palabras?
La idea es analizar quien es el que uso más palabras distintas en promedio durante este tiempo, en este caso vamos a dividir por la cantidad de tweets que hizo, así queda normalizado para todos los analizados.
No se cuentan los conectores comunes como “en”, “a”, “de”, etc.
- Espert esta abajo de las 15 palabras por tweet, es el de menor uso.
- El resto está en una cantidad similares de entre 15 y 20 palabras.
Cantidad_palabras= tuits_tokens%>%
group_by(Politico, Partido)%>%
count(Politico)%>%
inner_join(Cantidad_tweets, ., by = "Politico")%>%
mutate(cantidad_promedio = n.y / n.x)
Cantidad_palabras%>% ggplot()+
aes(x=reorder(Politico, -cantidad_promedio), y= cantidad_promedio, fill= Politico) +
geom_col() +
facet_wrap("Partido.x", scales = "free_y") +
labs(title = "Uso de palabras", x = "tweets", y = "Cantidad") +
coord_flip() +
tema1

NA
NA
13- ¿Quien usa mas palabras distintas?
Buscamos ver el léxico distintivo que hay en cada una de las cuentas, contando sus palabras únicas y se nota:
Diferencias entre Lavagna, Macri, Cristina con el resto de los que escriben
Espert que es el de léxico menos variado
tuits_tokens%>%
group_by(Politico, Partido)%>%
distinct(Palabra)%>%
count(Politico)%>%
inner_join(Cantidad_tweets, ., by = "Politico") %>%
mutate(cantidad_promedio = n.y / n.x) %>%
ggplot()+
aes(x=reorder(Politico, cantidad_promedio), y= cantidad_promedio, fill= Politico) +
geom_col() +
facet_wrap("Partido.x", scales = "free_y") +
labs(title = "Palabras distintas", x = "tweets", y = "Cantidad") +
coord_flip() +
tema1

NA
14- Palabras más usadas
Ahora que ya sabemos con qué variedad de palabras, podemos analizar cuáles son las que más usaron En este caso, cada grafico tiene una escala distinta para que no se pierda por la cantidad de tweets realizados.
Las palabras más utilizadas fueron:
- “evitar”
- “deuda”
- “justicia”
- “libertad” usada principalmente por Espert.
tuits_tokens_emociones %>%
group_by(Partido, Politico) %>%
count(Palabra, sort = T) %>%
slice_max(order_by = n, n= 10) %>%
filter(Partido == "PRO") %>%
ggplot() +
aes(Palabra, n, fill = Politico) +
geom_col() +
facet_wrap("Politico", scales = "free") +
scale_y_continuous(expand = c(0, 0)) +
coord_flip() +
labs(title = "Palabras más usadas") +
tema1

tuits_tokens_emociones %>%
group_by(Partido, Politico) %>%
count(Palabra, sort = T) %>%
slice_max(order_by = n, n= 10) %>%
filter(Partido == "Peronismo") %>%
ggplot() +
aes(Palabra, n, fill = Politico) +
geom_col() +
facet_wrap("Politico", scales = "free") +
scale_y_continuous(expand = c(0, 0)) +
coord_flip() +
labs(title = "Palabras más usadas") +
tema1

tuits_tokens_emociones %>%
group_by(Partido, Politico) %>%
count(Palabra, sort = T) %>%
slice_max(order_by = n, n= 10) %>%
filter(Partido == "otros candidatos") %>%
ggplot() +
aes(Palabra, n, fill = Politico) +
geom_col() +
facet_wrap("Politico", scales = "free") +
scale_y_continuous(expand = c(0, 0)) +
coord_flip() +
labs(title = "Palabras más usadas") +
tema1

tuits_tokens_emociones %>%
group_by(Partido, Politico) %>%
count(Palabra, sort = T) %>%
slice_max(order_by = n, n= 10) %>%
filter(Partido == "cuenta partidaria") %>%
ggplot() +
aes(Palabra, n, fill = Politico) +
geom_col() +
facet_wrap("Politico", scales = "free") +
scale_y_continuous(expand = c(0, 0)) +
coord_flip() +
labs(title = "Palabras más usadas") +
tema1

15- Palabras positivas más usadas
Al tener una puntuación cada palabra otorgada por el diccionario de léxico, también podemos buscar cuales son las palabras positivas que más uso cada uno de los políticos.
En este caso:
Se nota el uso de las palabras “libertad” y “justicia” que son consideradas positivas
Aparece bastante el uso de la palabra “gracias”, principalmente de aquellas cuentas relacionada a la salud (Gines González García y Fernán Quirós)
tuits_tokens_emociones %>%
filter(Calificacion == "Positiva") %>%
group_by(Partido, Politico) %>%
count(Palabra, sort = T) %>%
slice_max(order_by = n, n= 10) %>%
filter(Partido == "PRO") %>%
ggplot() +
aes(Palabra, n, fill = Politico) +
geom_col() +
facet_wrap("Politico", scales = "free") +
scale_y_continuous(expand = c(0, 0)) +
coord_flip() +
labs(title = "Palabras Positivas más usadas")

tuits_tokens_emociones %>%
filter(Calificacion == "Positiva") %>%
group_by(Partido, Politico) %>%
count(Palabra, sort = T) %>%
slice_max(order_by = n, n= 10) %>%
filter(Partido == "Peronismo") %>%
ggplot() +
aes(Palabra, n, fill = Politico) +
geom_col() +
facet_wrap("Politico", scales = "free") +
scale_y_continuous(expand = c(0, 0)) +
coord_flip() +
labs(title = "Palabras Positivas más usadas")

tuits_tokens_emociones %>%
filter(Calificacion == "Positiva") %>%
group_by(Partido, Politico) %>%
count(Palabra, sort = T) %>%
slice_max(order_by = n, n= 10) %>%
filter(Partido == "otros candidatos") %>%
ggplot() +
aes(Palabra, n, fill = Politico) +
geom_col() +
facet_wrap("Politico", scales = "free") +
scale_y_continuous(expand = c(0, 0)) +
coord_flip() +
labs(title = "Palabras Positivas más usadas")

tuits_tokens_emociones %>%
filter(Calificacion == "Positiva") %>%
group_by(Partido, Politico) %>%
count(Palabra, sort = T) %>%
slice_max(order_by = n, n= 10) %>%
filter(Partido == "cuenta partidaria") %>%
ggplot() +
aes(Palabra, n, fill = Politico) +
geom_col() +
facet_wrap("Politico", scales = "free") +
scale_y_continuous(expand = c(0, 0)) +
coord_flip() +
labs(title = "Palabras Positivas más usadas")

16- Palabras negativas más usadas
Al tener una puntuación cada palabra otorgada por el diccionario de léxico, también podemos buscar cuales son las palabras negativas que más uso cada uno de los políticos.
Evitar, Emergencia o Problema son las palabras que más aparecen, dentro del principal tema de habla que es la pandemia.
Deuda es otra palabra muy utilizada, un tema difícil de esquivar este año.
tuits_tokens_emociones %>%
filter(Calificacion == "Negativa") %>%
group_by(Partido, Politico) %>%
count(Palabra, sort = T) %>%
slice_max(order_by = n, n= 10) %>%
filter(Partido == "PRO") %>%
ggplot() +
aes(Palabra, n, fill = Politico) +
geom_col() +
facet_wrap("Politico", scales = "free") +
scale_y_continuous(expand = c(0, 0)) +
coord_flip() +
labs(title = "Palabras Negativas más usadas")

tuits_tokens_emociones %>%
filter(Calificacion == "Negativa") %>%
group_by(Partido, Politico) %>%
count(Palabra, sort = T) %>%
slice_max(order_by = n, n= 10) %>%
filter(Partido == "Peronismo") %>%
ggplot() +
aes(Palabra, n, fill = Politico) +
geom_col() +
facet_wrap("Politico", scales = "free") +
scale_y_continuous(expand = c(0, 0)) +
coord_flip() +
labs(title = "Palabras Negativas más usadas")

tuits_tokens_emociones %>%
filter(Calificacion == "Negativa") %>%
group_by(Partido, Politico) %>%
count(Palabra, sort = T) %>%
slice_max(order_by = n, n= 10) %>%
filter(Partido == "otros candidatos") %>%
ggplot() +
aes(Palabra, n, fill = Politico) +
geom_col() +
facet_wrap("Politico", scales = "free") +
scale_y_continuous(expand = c(0, 0)) +
coord_flip() +
labs(title = "Palabras Negativas más usadas")

tuits_tokens_emociones %>%
filter(Calificacion == "Negativa") %>%
group_by(Partido, Politico) %>%
count(Palabra, sort = T) %>%
slice_max(order_by = n, n= 10) %>%
filter(Partido == "cuenta partidaria") %>%
ggplot() +
aes(Palabra, n, fill = Politico) +
geom_col() +
facet_wrap("Politico", scales = "free") +
scale_y_continuous(expand = c(0, 0)) +
coord_flip() +
labs(title = "Palabras Negativas más usadas")

17- Sentimientos en el tweet
Volviendo a usar la puntuación del diccionario afinn, volvemos a unir las palabras a los tweets y sacamos el promedio de puntos de todas las palabras, pasando del valor unitario de palabra a un valor unitario por cada tweet publicado.
La mayoría de los tweets fueron neutros.
Los más positivos en este transcurso fueron M. Macri, A. Fernandez y R. Lavagna.
Los más negativos fueron N. Del Caño y la cuenta oficial del PRO.
Tweets_DF <-
tuits_tokens_emociones %>%
group_by(status_id) %>%
summarise(Puntuacion_tweet.x = mean(Puntuacion)) %>%
left_join(Tweets_DF, ., by = "status_id")
`summarise()` ungrouping output (override with `.groups` argument)
Tweets_DF <- Tweets_DF %>%
mutate(Puntuacion_tweet.x_letra = ifelse(is.na(Puntuacion_tweet.x), "Neutral",
ifelse(Puntuacion_tweet.x > 0, "Positiva",
ifelse(Puntuacion_tweet.x == 0, "Neutral",
"Negativa")
)
)
)
Tweets_DF %>%
count(Politico, Partido, Puntuacion_tweet.x_letra) %>%
group_by(Politico) %>%
mutate(Proporcion = n / sum(n)) %>%
ggplot() +
aes(Politico, Proporcion, fill = Puntuacion_tweet.x_letra) +
geom_col() +
scale_y_continuous(labels = percent_format()) +
facet_wrap("Partido", scales = "free") +
theme(legend.position = "top")

NA
NA
18- Sentimientos en el tweet PRO vs Peronismo
Tomamos los 4 miembros que ya analizamos de cada uno de los partidos (PRO y Todos), y lo unimos en un solo gráfico por partido, vemos que la distribución es algo parecido, si bien el Peronismo tuvo un poco más de tweets positivos y menos de tweets negativos, pero no a niveles significativos.
Tweets_DF %>%
count(Partido, Puntuacion_tweet.x_letra) %>%
group_by(Partido) %>%
filter(Partido == "PRO" |Partido == "Peronismo")%>%
mutate(Proporcion = n / sum(n)) %>%
ggplot() +
aes(Partido, Proporcion, fill = Puntuacion_tweet.x_letra) +
geom_col() +
scale_y_continuous(labels = percent_format()) +
theme(legend.position = "top")

19- Sentimiento mes a mes
La idea es analizar si hay fluctuaciones en lo que han ido twitteando en el transcurso del tiempo y sus sentimientos.
En el PRO no hubo grandes cambios, los últimos tweets de Bullrich son más positivo.
Entre los otros candidatos Nicolas Del Caño siempre es negativo, pero viene siendo menos negativo ultimamente.
Entre el Frente de Todos hay mucha fluctuación, el Presidente parece estar en un camino hacia la negatividad.
Tweets_DF$Puntuacion_tweet.x = ifelse(is.na(Tweets_DF$Puntuacion_tweet.x), 0, Tweets_DF$Puntuacion_tweet.x)
Tweets_DF %>%
group_by(Politico, Partido, mes) %>%
filter(Partido == "PRO")%>%
summarise(sentimiento = mean(Puntuacion_tweet.x)) %>%
ggplot() +
aes(mes, sentimiento, color = Politico) +
geom_hline(yintercept = 0, alpha = .35) +
geom_line() +
facet_grid(Politico~.) +
tema1 +
theme(legend.position = "none")
`summarise()` regrouping output by 'Politico', 'Partido' (override with `.groups` argument)

Tweets_DF %>%
group_by(Politico, Partido, mes) %>%
filter(Partido == "otros candidatos")%>%
summarise(sentimiento = mean(Puntuacion_tweet.x)) %>%
ggplot() +
aes(mes, sentimiento, color = Politico) +
geom_hline(yintercept = 0, alpha = .35) +
geom_line() +
facet_grid(Politico~.) +
tema1 +
theme(legend.position = "none")
`summarise()` regrouping output by 'Politico', 'Partido' (override with `.groups` argument)

Tweets_DF %>%
group_by(Politico, Partido, mes) %>%
filter(Partido == "Peronismo")%>%
summarise(sentimiento = mean(Puntuacion_tweet.x)) %>%
ggplot() +
aes(mes, sentimiento, color = Politico) +
geom_hline(yintercept = 0, alpha = .35) +
geom_line() +
facet_grid(Politico~.) +
tema1 +
theme(legend.position = "none")
`summarise()` regrouping output by 'Politico', 'Partido' (override with `.groups` argument)

Tweets_DF %>%
group_by(Politico, Partido, mes) %>%
filter(Partido == "cuenta partidaria")%>%
summarise(sentimiento = mean(Puntuacion_tweet.x)) %>%
ggplot() +
aes(mes, sentimiento, color = Politico) +
geom_hline(yintercept = 0, alpha = .35) +
geom_line() +
facet_grid(Politico~.) +
tema1 +
theme(legend.position = "none")
`summarise()` regrouping output by 'Politico', 'Partido' (override with `.groups` argument)

20- Boxplot sentimientos
La distribución de los sentimientos entre todos los tweets, aquellos que están encerrados en las cajas son los normales, mientras que los puntos sueltos son tweets aislados a lo que suelen escribir.
- Espert no presenta ningun tipo de patrón de sentimientos
Tweets_DF %>%
ggplot() +
aes(Politico, Puntuacion_tweet.x, fill = Politico) +
geom_boxplot() +
coord_flip() +
labs(y= "Sentimiento") +
tema1

21- Correlación entre lo twitteado PRO vs Peronismo
Se busca a través de las palabras que utilizaron cual es la correlación que hay entre los distintos políticos y sus tweets, y se pueden realizar varias observaciones:
Quirós y Larreta son los de mayor correlación, demostrando un buen manejo de la comunicación porteña, donde ambos siguen en misma dirección.
Macri es el de menor correlación con el resto de los participantes, pero así mismo tiene lógica que su mayor nivel de relación lo tenga con Bullrich.
Entre Kiciloff y Gines, hay una relación importante, así como también de ellos dos con sus similares porteños (Quirós y Larreta).
Cristina Kirchner es otra que no tiene un alto nivel de relación en sus tweets con otros políticos.
Es sorprendente que uno de los mayores niveles de relación en cuanto lo que se comunica este entre Alberto Fernández y Patricia Bullrich.
tweets_spread2 <- tuits_tokens %>%
filter(Partido == "PRO" | Partido == "Peronismo")%>%
group_by(Politico, Palabra) %>%
count(Palabra) %>%
spread(key = Politico, value = n, fill = NA, drop = TRUE)
tweets_spread2[is.na(tweets_spread2)] <- 0
names(tweets_spread2) <- c("Palabra", "A.Fernandez", "A.Kicillof",
"C.Kirchner", "F.Quiros", "Gines.GG","H.Larreta", "M.Macri", "P.Bullrich" )
method <- "pearson"
m_cor <- matrix(nrow = 8, ncol = 8)
for (i in 1:dim(m_cor)[1]) {
for (j in 1:dim(m_cor)[2]) {
form <- as.formula(paste("~", names(tweets_spread2)[i+1],
"+", names(tweets_spread2)[j+1]))
if(i!=j){
m_cor[i,j] <- cor.test(form, method = method,
data = tweets_spread2)$estimate
}
if(i==j){m_cor[i,j] <- 1}
}
}
colnames(m_cor) <- names(tweets_spread2)[2:9]
rownames(m_cor) <- names(tweets_spread2)[2:9]
corrplot(m_cor, method="color", type="upper", order="hclust",
addCoef.col = "black", tl.col="black", tl.srt=45,
sig.level = 0.01, insig = "blank", diag=FALSE)

22- Correlación entre lo twitteado candidatos a presidente.
La relación entre lo que escriben los candidatos tiene un clúster que se destaca sobre el resto que es la relación entre Espert, Gómez Centurión y Alberto Fernández.
Nicolas Del Caño tiene un alto nivel de relación con Gómez Centurión, y en medida mediana con Alberto Fernández y Espert.
Lavagna y Macri no presentan una gran correlación con el resto de los políticos.
tweets_spread2 <- tuits_tokens %>%
filter(Partido == "otros candidatos" | Politico == "A.Fernandez"| Politico == "M.Macri")%>%
group_by(Politico, Palabra) %>%
count(Palabra) %>%
spread(key = Politico, value = n, fill = NA, drop = TRUE)
tweets_spread2[is.na(tweets_spread2)] <- 0
names(tweets_spread2) <- c("Palabra", "A.Fernandez", "J.Espert",
"GomezCenturion", "M.Macri", "N.DelCaño","R.Lavagna")
method <- "pearson"
m_cor <- matrix(nrow = 6, ncol = 6)
for (i in 1:dim(m_cor)[1]) {
for (j in 1:dim(m_cor)[2]) {
form <- as.formula(paste("~", names(tweets_spread2)[i+1],
"+", names(tweets_spread2)[j+1]))
if(i!=j){
m_cor[i,j] <- cor.test(form, method = method,
data = tweets_spread2)$estimate
}
if(i==j){m_cor[i,j] <- 1}
}
}
colnames(m_cor) <- names(tweets_spread2)[2:7]
rownames(m_cor) <- names(tweets_spread2)[2:7]
corrplot(m_cor, method="color", type="upper", order="hclust",
addCoef.col = "black", tl.col="black", tl.srt=45,
sig.level = 0.01, insig = "blank", diag=FALSE)

23- Correlación entre lo twitteado entre cuentas partidarias
Este puede ser un análisis interesante, ya que la cantidad de tweets es significativa para todos.
Sorpresivamente el máximo nivel de relación se da entre la UCR y TODOS, dos partidos que hoy se presentan como opuesto
Tiene mayor lógica la alta relación entre el PRO y la UCR.
El GEN pareciera ser el partido que escribe de manera más distinta al resto.
Sin embargo, podemos notar que, a diferencia de las cuentas individuales, las partidarias tienen más relación, por su lenguaje más neutro y comunicación orgánica.
tweets_spread2 <- tuits_tokens %>%
filter(Partido == "cuenta partidaria")%>%
group_by(Politico, Palabra) %>%
count(Palabra) %>%
spread(key = Politico, value = n, fill = NA, drop = TRUE)
tweets_spread2[is.na(tweets_spread2)] <- 0
names(tweets_spread2) <- c("Palabra", "GEN", "PRO",
"TODOS", "UCR")
method <- "pearson"
m_cor <- matrix(nrow = 4, ncol = 4)
for (i in 1:dim(m_cor)[1]) {
for (j in 1:dim(m_cor)[2]) {
form <- as.formula(paste("~", names(tweets_spread2)[i+1],
"+", names(tweets_spread2)[j+1]))
if(i!=j){
m_cor[i,j] <- cor.test(form, method = method,
data = tweets_spread2)$estimate
}
if(i==j){m_cor[i,j] <- 1}
}
}
colnames(m_cor) <- names(tweets_spread2)[2:5]
rownames(m_cor) <- names(tweets_spread2)[2:5]
corrplot(m_cor, method="color", type="upper", order="hclust",
addCoef.col = "black", tl.col="black", tl.srt=45,
sig.level = 0.01, insig = "blank", diag=FALSE)

24- Comparación de uso de palabras Macri vs Fernandez
La idea de este gráfico es de mostrar cuales son las palabras más diferencias en su uso, en este caso entre Mauricio Macri y Alberto Fernández
# Pivotaje y despivotaje
tweets_unpivot <- tuits_tokens %>% group_by(Politico, Palabra) %>%
count(Palabra) %>%
spread(key = Politico, value = n, fill = 0, drop = TRUE) %>%
gather(key = "Politico", value = "n", -Palabra)
# Selección de los autores
tweets_unpivot2 <- tweets_unpivot %>%
filter(Politico %in% c("M.Macri", "A.Fernandez"))
# Se añade el total de palabras de cada autor
tweets_unpivot2 <- tweets_unpivot2 %>%
left_join(Tweets_DF %>% group_by(Politico) %>%
summarise(N = n()), by = "Politico")
`summarise()` ungrouping output (override with `.groups` argument)
# Cálculo de odds y log of odds de cada palabra
tweets_logOdds <- tweets_unpivot2 %>%
mutate(odds = (n + 1) / (N + 1)) %>%
select(Politico, Palabra, odds) %>%
spread(key = Politico, value = odds)
tweets_logOdds[,4] <- log(tweets_logOdds[,2]/tweets_logOdds[,3])
names(tweets_logOdds)[4] <- "log_odds"
tweets_logOdds[,5] <- abs(tweets_logOdds$log_odds)
names(tweets_logOdds)[5] <- "abs_log_odds"
tweets_logOdds <- tweets_logOdds %>%
mutate(autor_frecuente = if_else(log_odds > 0,
names(tweets_logOdds)[2],
names(tweets_logOdds)[3]))
Diferencia_AF <- tweets_logOdds %>%
arrange(-abs_log_odds, bygroup = FALSE)%>%
filter(autor_frecuente == "A.Fernandez")%>%
head(15)
Diferencia_MM <- tweets_logOdds %>%
arrange(log_odds, bygroup = FALSE)%>%
filter(autor_frecuente == "M.Macri")%>%
head(15)
Diferencia_AF_MM <- rbind(Diferencia_AF,Diferencia_MM)
Diferencia_AF_MM%>%
ggplot(aes(x = reorder(Palabra, log_odds), y= log_odds, fill = autor_frecuente)) +
geom_col() +
labs(x = "-palabra", y = "Uso", title = "Fernandez vs Macri") +
coord_flip() +
tema2

25- Comparación de uso de palabras Larreta vs Kicillof
La idea de este gráfico es de mostrar cuales son las palabras más diferencias en su uso, en este caso entre Horacio Larreta y Axel Kicillof
# Pivotaje y despivotaje
tweets_unpivot <- tuits_tokens %>% group_by(Politico, Palabra) %>%
count(Palabra) %>%
spread(key = Politico, value = n, fill = 0, drop = TRUE) %>%
gather(key = "Politico", value = "n", -Palabra)
# Selección de los autores
tweets_unpivot2 <- tweets_unpivot %>%
filter(Politico %in% c("H.Larreta", "A.Kicillof"))
# Se añade el total de palabras de cada autor
tweets_unpivot2 <- tweets_unpivot2 %>%
left_join(Tweets_DF %>% group_by(Politico) %>%
summarise(N = n()), by = "Politico")
`summarise()` ungrouping output (override with `.groups` argument)
# Cálculo de odds y log of odds de cada palabra
tweets_logOdds <- tweets_unpivot2 %>%
mutate(odds = (n + 1) / (N + 1)) %>%
select(Politico, Palabra, odds) %>%
spread(key = Politico, value = odds)
tweets_logOdds[,4] <- log(tweets_logOdds[,2]/tweets_logOdds[,3])
names(tweets_logOdds)[4] <- "log_odds"
tweets_logOdds[,5] <- abs(tweets_logOdds$log_odds)
names(tweets_logOdds)[5] <- "abs_log_odds"
tweets_logOdds <- tweets_logOdds %>%
mutate(autor_frecuente = if_else(log_odds > 0,
names(tweets_logOdds)[2],
names(tweets_logOdds)[3]))
Diferencia_AK <- tweets_logOdds %>%
arrange(-log_odds, bygroup = FALSE)%>%
filter(autor_frecuente == "A.Kicillof")%>%
head(15)
Diferencia_HL <- tweets_logOdds %>%
arrange(abs_log_odds, bygroup = FALSE)%>%
filter(autor_frecuente == "H.Larreta")%>%
tail(15)
Diferencia_AK_HL <- rbind(Diferencia_AK,Diferencia_HL)
Diferencia_AK_HL%>%
ggplot(aes(x = reorder(Palabra, log_odds), y= log_odds, fill = autor_frecuente)) +
geom_col() +
labs(x = "-palabra", y = "Uso", title = "Kicillof vs Larreta") +
coord_flip() +
tema2

26- Comparación de uso de palabras Gines vs Quirós
La idea de este gráfico es de mostrar cuales son las palabras más diferencias en su uso, en este caso entre Gines Gonzalez y Fernán Quirós
tweets_unpivot <- tuits_tokens %>% group_by(Politico, Palabra) %>%
count(Palabra) %>%
spread(key = Politico, value = n, fill = 0, drop = TRUE) %>%
gather(key = "Politico", value = "n", -Palabra)
# Selección de los autores
tweets_unpivot2 <- tweets_unpivot %>%
filter(Politico %in% c("Gines.GG", "F.Quiros"))
# Se añade el total de palabras de cada autor
tweets_unpivot2 <- tweets_unpivot2 %>%
left_join(Tweets_DF %>% group_by(Politico) %>%
summarise(N = n()), by = "Politico")
`summarise()` ungrouping output (override with `.groups` argument)
# Cálculo de odds y log of odds de cada palabra
tweets_logOdds <- tweets_unpivot2 %>%
mutate(odds = (n + 1) / (N + 1)) %>%
select(Politico, Palabra, odds) %>%
spread(key = Politico, value = odds)
tweets_logOdds[,4] <- log(tweets_logOdds[,2]/tweets_logOdds[,3])
names(tweets_logOdds)[4] <- "log_odds"
tweets_logOdds[,5] <- abs(tweets_logOdds$log_odds)
names(tweets_logOdds)[5] <- "abs_log_odds"
tweets_logOdds <- tweets_logOdds %>%
mutate(autor_frecuente = if_else(log_odds > 0,
names(tweets_logOdds)[2],
names(tweets_logOdds)[3]))
Diferencia_GG <- tweets_logOdds %>%
arrange(-log_odds, bygroup = FALSE)%>%
filter(autor_frecuente == "Gines.GG")%>%
tail(15)
Diferencia_FQ <- tweets_logOdds %>%
arrange(-abs_log_odds, bygroup = FALSE)%>%
filter(autor_frecuente == "F.Quiros")%>%
head(15)
Diferencia_GG_FQ <- rbind(Diferencia_GG,Diferencia_FQ)
Diferencia_GG_FQ%>%
ggplot(aes(x = reorder(Palabra, log_odds), y= log_odds, fill = autor_frecuente)) +
geom_col() +
labs(x = "-palabra", y = "Uso", title = "Quirós vs Gines") +
coord_flip() +
tema2

27- Comparación de uso de palabras Bullrich vs Cristina
La idea de este gráfico es de mostrar cuales son las palabras más diferencias en su uso, en este caso entre Cristina Kirchner y Patricia Bullrich
tweets_unpivot <- tuits_tokens %>% group_by(Politico, Palabra) %>%
count(Palabra) %>%
spread(key = Politico, value = n, fill = 0, drop = TRUE) %>%
gather(key = "Politico", value = "n", -Palabra)
# Selección de los autores
tweets_unpivot2 <- tweets_unpivot %>%
filter(Politico %in% c("P.Bullrich", "C.Kirchner"))
# Se añade el total de palabras de cada autor
tweets_unpivot2 <- tweets_unpivot2 %>%
left_join(Tweets_DF %>% group_by(Politico) %>%
summarise(N = n()), by = "Politico")
`summarise()` ungrouping output (override with `.groups` argument)
# Cálculo de odds y log of odds de cada palabra
tweets_logOdds <- tweets_unpivot2 %>%
mutate(odds = (n + 1) / (N + 1)) %>%
select(Politico, Palabra, odds) %>%
spread(key = Politico, value = odds)
tweets_logOdds[,4] <- log(tweets_logOdds[,2]/tweets_logOdds[,3])
names(tweets_logOdds)[4] <- "log_odds"
tweets_logOdds[,5] <- abs(tweets_logOdds$log_odds)
names(tweets_logOdds)[5] <- "abs_log_odds"
tweets_logOdds <- tweets_logOdds %>%
mutate(autor_frecuente = if_else(log_odds > 0,
names(tweets_logOdds)[2],
names(tweets_logOdds)[3]))
Diferencia_PB <- tweets_logOdds %>%
arrange(-log_odds, bygroup = FALSE)%>%
filter(autor_frecuente == "P.Bullrich")%>%
tail(15)
Diferencia_CFK <- tweets_logOdds %>%
arrange(-abs_log_odds, bygroup = FALSE)%>%
filter(autor_frecuente == "C.Kirchner")%>%
head(15)
Diferencia_PB_CFK <- rbind(Diferencia_PB,Diferencia_CFK)
Diferencia_PB_CFK%>%
ggplot(aes(x = reorder(Palabra, log_odds), y= log_odds, fill = autor_frecuente)) +
geom_col() +
labs(x = "-palabra", y = "Uso", title = "Cristina vs Bullrich") +
coord_flip() +
tema2

28- Emociones en los tweets
Ahora analizamos un campo más amplio de emociones que fueron usado por los distintos políticos entre todos los tweets que han ido publicando en este periodo.
Entre los miembros del PRO y el Peronismo se destaca la confianza como principal sentimiento expuesto
En cuentas como la de Espert o Del Caño lo que más muestran sus tweets es el miedo.
Las cuentas del PRO y Peronismo, principalmente por los ministros y jefes de gobiernos buscan un sentimiento de anticipación
Otras cuentas son mayores el tono de angustia sobre el tiempo.
La tristeza es un sentimiento general que está incorporado en todos los tweets, y se entiende por la situación compleja que significa una pandemia.
gather(Tweets_DF_sentimiento, "sentiment", "values", 103:112) %>%
group_by(Politico, Partido, sentiment) %>%
filter(Partido == "cuenta partidaria")%>%
filter(sentiment != "Positivo" & sentiment !="Negativo")%>%
summarise(Total = sum(values)) %>%
mutate(Proporcion = Total / sum(Total)) %>%
ggplot() +
aes(Politico, Proporcion, fill = sentiment) +
geom_col(position = "stack", color = "black") +
coord_flip() +
scale_y_continuous(expand = c(0,0)) +
labs(y = "Palabras") +
theme_minimal()
`summarise()` regrouping output by 'Politico', 'Partido' (override with `.groups` argument)

gather(Tweets_DF_sentimiento, "sentiment", "values", 103:112) %>%
group_by(Politico, Partido, sentiment) %>%
filter(Partido == "PRO")%>%
filter(sentiment != "Positivo" & sentiment !="Negativo")%>%
summarise(Total = sum(values)) %>%
mutate(Proporcion = Total / sum(Total)) %>%
ggplot() +
aes(Politico, Proporcion, fill = sentiment) +
geom_col(position = "stack", color = "black") +
coord_flip() +
scale_y_continuous(expand = c(0,0)) +
labs(y = "Palabras") +
theme_minimal()
`summarise()` regrouping output by 'Politico', 'Partido' (override with `.groups` argument)

gather(Tweets_DF_sentimiento, "sentiment", "values", 103:112) %>%
group_by(Politico, Partido, sentiment) %>%
filter(Partido == "Peronismo")%>%
filter(sentiment != "Positivo" & sentiment !="Negativo")%>%
summarise(Total = sum(values)) %>%
mutate(Proporcion = Total / sum(Total)) %>%
ggplot() +
aes(Politico, Proporcion, fill = sentiment) +
geom_col(position = "stack", color = "black") +
coord_flip() +
scale_y_continuous(expand = c(0,0)) +
labs(y = "Palabras") +
theme_minimal()
`summarise()` regrouping output by 'Politico', 'Partido' (override with `.groups` argument)

gather(Tweets_DF_sentimiento, "sentiment", "values", 103:112) %>%
group_by(Politico, Partido, sentiment) %>%
filter(Partido == "otros candidatos")%>%
filter(sentiment != "Positivo" & sentiment !="Negativo")%>%
summarise(Total = sum(values)) %>%
mutate(Proporcion = Total / sum(Total)) %>%
ggplot() +
aes(Politico, Proporcion, fill = sentiment) +
geom_col(position = "stack", color = "black") +
coord_flip() +
scale_y_continuous(expand = c(0,0)) +
labs(y = "Palabras") +
theme_minimal()
`summarise()` regrouping output by 'Politico', 'Partido' (override with `.groups` argument)

29- Emociones mes a mes
Si bien no hay grandes cambios a la hora de hacer los análisis de sentimientos mes a mes, se nota algunos detalles:
Los ministros de salud cada vez transmiten mayor confianza.
Los llamados otros candidatos va decayendo la transmisión de confianza.
Larreta si bien tiene bajas en el sentimiento de confianza, sigue exponiendo uno de anticipación.
Kicillof cada vez tiene mayor mensaje de angustia.
gather(Tweets_DF_sentimiento, "sentiment", "values", 103:112) %>%
group_by(Politico, Partido, mes, sentiment) %>%
filter(Partido == "cuenta partidaria")%>%
filter(sentiment != "Positivo" & sentiment !="Negativo")%>%
summarise(Total = sum(values)) %>%
mutate(Proporcion = Total / sum(Total)) %>%
ggplot() +
aes(x = mes, y =Proporcion, color = sentiment) +
geom_point() +
geom_line(aes(group = sentiment)) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = .4),
text = element_text(family = "serif")) +
tema2 +
facet_wrap(~ Politico) +
labs(title = "Cambio de los sentimientos en el tiempo",
x = "Mes", y = "Porporción", color = "Sentimiento")
`summarise()` regrouping output by 'Politico', 'Partido', 'mes' (override with `.groups` argument)

gather(Tweets_DF_sentimiento, "sentiment", "values", 103:112) %>%
group_by(Politico, Partido, mes, sentiment) %>%
filter(Partido == "otros candidatos")%>%
filter(sentiment != "Positivo" & sentiment !="Negativo")%>%
summarise(Total = sum(values)) %>%
mutate(Proporcion = Total / sum(Total)) %>%
ggplot() +
aes(x = mes, y =Proporcion, color = sentiment) +
geom_point() +
geom_line(aes(group = sentiment)) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = .4),
text = element_text(family = "serif")) +
tema2 +
facet_wrap(~ Politico) +
labs(title = "Cambio de los sentimientos en el tiempo",
x = "Mes", y = "Porporción", color = "Sentimiento")
`summarise()` regrouping output by 'Politico', 'Partido', 'mes' (override with `.groups` argument)

gather(Tweets_DF_sentimiento, "sentiment", "values", 103:112) %>%
group_by(Politico, Partido, mes, sentiment) %>%
filter(Partido == "Peronismo")%>%
filter(sentiment != "Positivo" & sentiment !="Negativo")%>%
summarise(Total = sum(values)) %>%
mutate(Proporcion = Total / sum(Total)) %>%
ggplot() +
aes(x = mes, y =Proporcion, color = sentiment) +
geom_point() +
geom_line(aes(group = sentiment)) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = .4),
text = element_text(family = "serif")) +
tema2 +
facet_wrap(~ Politico) +
labs(title = "Cambio de los sentimientos en el tiempo",
x = "Mes", y = "Porporción", color = "Sentimiento")
`summarise()` regrouping output by 'Politico', 'Partido', 'mes' (override with `.groups` argument)

gather(Tweets_DF_sentimiento, "sentiment", "values", 103:112) %>%
group_by(Politico, Partido, mes, sentiment) %>%
filter(Partido == "PRO")%>%
filter(sentiment != "Positivo" & sentiment !="Negativo")%>%
summarise(Total = sum(values)) %>%
mutate(Proporcion = Total / sum(Total)) %>%
ggplot() +
aes(x = mes, y =Proporcion, color = sentiment) +
geom_point() +
geom_line(aes(group = sentiment)) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = .4),
text = element_text(family = "serif")) +
tema2 +
facet_wrap(~ Politico) +
labs(title = "Cambio de los sentimientos en el tiempo",
x = "Mes", y = "Porporción", color = "Sentimiento")
`summarise()` regrouping output by 'Politico', 'Partido', 'mes' (override with `.groups` argument)

30- Comparación de emociones
La idea de comparar las emociones de todos en un gráfico ayuda para una visualización general (eliminando las cuentas partidarias):
Si bien la cantidad de tweets de Macri son pocos, es el que mayor confianza transmite.
Aquellos que tienen poder electo son los que más confianza buscan en sus tweets.
Los candidatos que han perdido, tienen mezcla de sentimientos, con alto nivel de miedo y angustia en sus escritos.
Se descartan aquellos sentimientos que representen menos del 10% de los tweets.
gather(Tweets_DF_sentimiento, "sentiment", "values", 103:112) %>%
group_by(Politico, Partido, sentiment) %>%
filter(sentiment != "Positivo" & sentiment !="Negativo" & Partido != "cuenta partidaria")%>%
summarise(Total = sum(values)) %>%
mutate(Proporcion = Total / sum(Total)) %>%
ggplot() +
aes(Politico, Proporcion, color = sentiment, alpha = Proporcion) +
geom_point(fill = "white", stroke = 1, shape = 21) +
geom_text(aes(label = sentiment), vjust = -.9, family = "serif") +
scale_y_continuous(labels = percent_format ()) +
tema1 +
theme(legend.position = "none",
panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank(),
text = element_text(family = "serif")) +
coord_flip() +
labs(title = "Sentimientos totales comparativo",
x = "Politico",
y = "Proporción del sentimiento")
`summarise()` regrouping output by 'Politico', 'Partido' (override with `.groups` argument)

gather(Tweets_DF_sentimiento, "sentiment", "values", 103:112) %>%
group_by(Politico, Partido, sentiment) %>%
filter(sentiment != "Positivo" & sentiment !="Negativo" & sentiment !="Alegria" & sentiment !="Sorpresa" & Partido != "cuenta partidaria")%>%
summarise(Total = sum(values)) %>%
mutate(Proporcion = Total / sum(Total)) %>%
ggplot() +
aes(sentiment, Proporcion, color = sentiment) +
geom_point() +
geom_text(aes(label = Politico) ,vjust = -.3, size = 3) +
scale_y_continuous(limits = c(0.15, 0.47)) +
labs(title = "Sentimientos totales comparativo",
x = "Politico",
y = "Proporción del sentimiento") +
theme_minimal() +
theme(legend.position = "none")
`summarise()` regrouping output by 'Politico', 'Partido' (override with `.groups` argument)

LS0tDQp0aXRsZTogIkFuYWxpc2lzIGRlIHR3aXR0ZXI6IFBvbMOtdGljb3MgZW4gY3VhcmVudGVuYSINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCjxjZW50ZXI+IDxzcGFuIHN0eWxlPSJjb2xvcjogIzAyMTgyQjsiPiA8aDI+IEFuw6FsaXNpcyBkZSBwb2zDrXRpY29zIDwvaDI+IDwvc3Bhbj4gPC9jZW50ZXI+DQoNCjxjZW50ZXI+IDxzcGFuIHN0eWxlPSJjb2xvcjogIzI4MkY0NDsiPiA8aDM+IDEtIERlc2NhcmdhciB0d2VldHMgPC9oMz4gPC9zcGFuPiA8L2NlbnRlcj4NCg0KQ3JlbyB1bmEgbGlzdGEgZGUgY3VlbnRhcyBkZSBsYXMgY3VhbGVzIHZveSBhIGRlc2NhcmdhciBzdXMgdHdlZXRzLCB5IGFkZW3DoXMgdW5hIGFzaWduYWNpw7NuIHBhcmEgc2FiZXIgYSBxdWnDqW4gcmVwcmVzZW50YSBjYWRhIGN1ZW50YS4NCg0KTGEgaWRlYSBvcmlnaW5hbCBlcyB0ZW5lciA0IG1pZW1icm9zIGRlIGNhZGEgdW5vIGRlIGxvcyBkb3MgcGFydGlkb3MgcHJpbmNpcGFsZXMsIGxvcyDDumx0aW1vcyA0IGNhbmRpZGF0b3MgZW4gbGFzIGVsZWNjaW9uZXMgMjAxOSB5IHRhbWJpw6luIGxhcyA0IGN1ZW50YXMgcGFydGlkYXJpYXMgZW4gVHdpdHRlci4NCg0KICAtICoqRnJlbnRlIGRlIHRvZG9zKio6ICpBbGJlcnRvIEZlcm7DoW5kZXosIENyaXN0aW5hIEtpcmNobmVyLCBHaW5lcyBHb256w6FsZXogR2FyY8OtYSB5IEF4ZWwgS2ljaWxsb2YqDQogIC0gKipQUk8qKjogKk1hdXJpY2lvIE1hY3JpLCBIb3JhY2lvIFJvZHLDrWd1ZXogTGFycmV0YSwgRmVybsOhbiBRdWlyb3ogeSBQYXRyaWNpYSBCdWxscmljaCoNCiAgLSAqKk90cm9zIGNhbmRpZGF0b3MqKjogKkpvc8OpIEx1aXMgRXNwZXJ0LCBSb2JlcnRvIExhdmFnbmEsIEp1YW4gSm9zw6kgR8OzbWV6IENlbnR1cmnDs24geSBOaWNvbGFzIGRlbCBDYcOxbyoNCiAgLSAqKlBhcnRpZGFyaWFzKio6ICpGcmVudGUgZGUgVG9kb3MsIFBSTywgR0VOIHkgVW5pw7NuIEPDrXZpY2EgUmFkaWNhbCoNCg0KYGBge3J9DQpjYW5kaWRhdG9zIDwtIGxpc3QoImFsZmVyZGV6IiwgDQogICAgICAgICAgICAgICAgICAgIkNGS0FyZ2VudGluYSIsIA0KICAgICAgICAgICAgICAgICAgICJnaW5lc2dnYXJjaWEiLA0KICAgICAgICAgICAgICAgICAgICJLaWNpbGxvZm9rIiwNCiAgICAgICAgICAgICAgICAgICAiUGFydGlkb0dFTiIsIA0KICAgICAgICAgICAgICAgICAgICJGcmVudGVEZVRvZG9zIiwNCiAgICAgICAgICAgICAgICAgICAgIm1hdXJpY2lvbWFjcmkiLA0KICAgICAgICAgICAgICAgICAgICJQYXRvQnVsbHJpY2giLA0KICAgICAgICAgICAgICAgICAgICJob3JhY2lvcmxhcnJldGEiLA0KICAgICAgICAgICAgICAgICAgICJGZXJuYW5RdWlyb3NCQSIsDQogICAgICAgICAgICAgICAgICAgInByb2FyZ2VudGluYSIsDQogICAgICAgICAgICAgICAgICAgIlVDUk5hY2lvbmFsIiwNCiAgICAgICAgICAgICAgICAgICAiamxlc3BlcnQiLA0KICAgICAgICAgICAgICAgICAgICJOaWNvbGFzZGVsQ2FubyIsDQogICAgICAgICAgICAgICAgICAgIlJMYXZhZ25hIiwNCiAgICAgICAgICAgICAgICAgICAianVhbmpvbWFsdmluYXMiKQ0KDQp0aXBvY3VlbnRhIDwtIGxpc3QgKCJQZXJvbmlzbW8iLCJjdWVudGEgcGFydGlkYXJpYSIsICJQUk8iLCJvdHJvcyBjYW5kaWRhdG9zIiApDQoNCiBUd2VldHM8LW1hcChjYW5kaWRhdG9zLCBmdW5jdGlvbih4KXsNCiAgICBnZXRfdGltZWxpbmUodXNlciA9IHgsIG4gPSAzMjAwLCBpbmNsdWRlUnRzID0gRiwgZXhjbHVkZVJlcGxpZXMgPSBGKQ0KICAgICB9ICkNCiANClR3ZWV0c19ERjwtIGRvX2NhbGxfcmJpbmQoVHdlZXRzKQ0KDQpwcmludCgiTXVlc3RyYSIpDQpwcmludChUd2VldHNfREYgJT4lIA0KICBzZWxlY3QodGV4dCklPiUgDQogICAgaGVhZCg1KSkNCg0KYGBgDQoNCg0KPGNlbnRlcj4gPHNwYW4gc3R5bGU9ImNvbG9yOiAjMjgyRjQ0OyI+IDxoMz4gMi1MaW1waWV6YSA8L2gzPiA8L3NwYW4+IDwvY2VudGVyPg0KDQoNClZhbW9zIGEgbGltcGlhciBjaWVydG9zIGVsZW1lbnRvcyBxdWUgcHVlZGVuIGNvbXBsaWNhciBlbCBhbsOhbGlzaXMgZGVsIHRleHRvLCBjb21vIHNvbiBsb3MgbGlua3MsIGxvcyBuw7ptZXJvcywgbG9zIGdyw6FmaWNvcyB5IHBhc2FyIHRvZG8gYSBtaW7DunNjdWxhLg0KDQpBZGVtw6FzLCBjcmVhbW9zIHZhcmlvcyBjYW1wb3MgcGFyYSBsbyBxdWUgZXMgbGEgZmVjaGEsIGRlc2FncmVnYW5kbyBlbCBjYW1wbyBlbiB2YXJpb3MgZGlzdGludG9zLCBxdWUgc2UgdmFuIGEgdXRpbGl6YXIgYSBmdXR1cm8sIHkgdGFtYmnDqW4gc2UgYWN0dWFsaXphIGVsIGhvcmFyaW8gYSBsYSB6b25hIGhvcmFyaWEgZG9uZGUgZnVlIHJlYWxpemFkbyBlbCB0d2VldCAqKEFyZ2VudGluYSkqLg0KDQpGaW5hbG1lbnRlIGZpbHRyYW1vcyBwb3IgZmVjaGEsIGxhIGlkZWEgZXMgdGVuZXIgc29sbyB0d2VldHMgZGVsIHBlcmlvZG8gMS8zLzIwMjAgaGFzdGEgbGEgZmVjaGEgZGUgcHVibGljYWNpw7NuICooU2VwLzIwMjApKg0KDQpgYGB7cn0NClR3ZWV0c19ERiA8LQ0KICBUd2VldHNfREYgJT4lDQogICMjVG9kbyBlbCB0ZXh0byBhIG1pbnVzY3VsYSMjDQogIG11dGF0ZSh0ZXh0ID0gdG9sb3dlcih0ZXh0KSkgJT4lIA0KICAjI1NpbiBncmFmaWNvcyMjDQogIG11dGF0ZSh0ZXh0ID0gZ3N1YigiW15bOmdyYXBoOl1dIiwgIiAiLCB0ZXh0KSkgJT4lIA0KICAjI1NpbiBsaW5rcyMjDQogIG11dGF0ZSh0ZXh0ID0gZ3N1YigiaHR0cC8vUyIsICIgIiwgdGV4dCkpICU+JSANCiAgIyNTaW4gbnVtZXJvcyMjDQogIG11dGF0ZSh0ZXh0ID0gZ3N1YigiW1s6ZGlnaXQ6XV0iLCAiICIsIHRleHQpKSAlPiUgDQogICMjU2luIG51bWVyb3MjIw0KICBtdXRhdGUodGV4dCA9IGNoYXJ0cignw6HDqcOtw7PDusOxJywnYWVpb3VuJyx0ZXh0KSkgJT4lDQogICMjQ2FtYmlhbW9zIGEgbGEgem9uYSBob3JhcmlhIGNvcnJlc3BvbmRpZW50ZSMjDQogIG11dGF0ZShjcmVhdGVkX2F0ID0gd2l0aF90eihjcmVhdGVkX2F0LCAiQW1lcmljYS9BcmdlbnRpbmEvQnVlbm9zX0FpcmVzIikpJT4lIA0KICAjI1NlcGFyYW1vcyBlbiBkaWEgeSBob3JhIGVsIGNhbXBvIGNyZWF0ZWRfYXQjIw0KICBzZXBhcmF0ZShjcmVhdGVkX2F0LCBpbnRvID0gYygiZGF0ZSIsICJob3VyIiksIHNlcCA9ICIgIiklPiUgDQogICMjU2VwYXJhbW9zIGxhIGhvcmEgZW4gaG9yYSxtaW51dG9zIHkgc2VndW5kb3MjIw0KICAgIHNlcGFyYXRlKGhvdXIsIGludG8gPSBjKCJob3VyIiwgIm1pbnV0ZXMiLCJzZWNvbmRzIiksIHNlcCA9ICI6IiklPiUgDQogICMjQ2FtYmlhbW9zIGxhIGNvbHVtbmEgY29uIGVsIG5vbWJyZSBkZWwgcG9saXRpY28jIw0KICAgcmVuYW1lKFBvbGl0aWNvID0gc2NyZWVuX25hbWUpICU+JSANCiAgIyNDcmVhbW9zIHVuYSBjb2x1bW5hIGNvbiBlbCBudW1lcm8gZGUgYcOxbywgbWVzLCBkaWEsIG5vbWJyZSBkZSBkaWEgeSBkZSBtZXMuIyMNCm11dGF0ZShwZXJpb2RvID0geWVhcihkYXRlKSwgDQogICAgICAgICBtZXMgPSBtb250aChkYXRlLCBsYWJlbCA9IEYsIGFiYnIgPSBGKSwNCiAgICAgICAgIGRpYSA9IGFzLm51bWVyaWMoZGF5KGRhdGUpKSwNCiAgICAgICAgIGRpYV9zZW0gPSB3ZGF5KGRhdGUsIGxhYmVsID0gVCwgYWJiciA9IEYsIHdlZWtfc3RhcnQgPSAxKSwNCiAgICAgICAgIGRpYV9wZXIgPSB5ZGF5KGRhdGUpLA0KICAgICAgICAgZGF0ZSA9IGFzLkRhdGUoZGF0ZSkgDQogICkgJT4lDQogICMjU29sbyB2YW1vcyBhIHV0aWxpemFyIGluZm8gZGUgbWFyem8gMjAyMCBlbiBhZGVsYW50ZSMjDQogIGZpbHRlcihwZXJpb2RvID09IDIwMjAgJiBtZXMgPiAyKSANCg0KcHJpbnQoIk11ZXN0cmEiKQ0KcHJpbnQoVHdlZXRzX0RGICU+JSANCiAgc2VsZWN0KFBvbGl0aWNvLCBzdGF0dXNfaWQsIHBlcmlvZG8sIG1lcywgZGlhKSU+JSANCiAgICBoZWFkKDEwKSkNCg0KYGBgDQoNCjxjZW50ZXI+IDxzcGFuIHN0eWxlPSJjb2xvcjogIzI4MkY0NDsiPiA8aDM+IDMtTm9ybWFsaXphY2nDs24gPC9oMz4gPC9zcGFuPiA8L2NlbnRlcj4NCg0KDQpOb3JtYWxpemFtb3MgYWxndW5vcyBjYW1wb3MsIHBhcmEgYXl1ZGFyIGFsIGFuw6FsaXNpcyB5IHRhbWJpw6luIGEgbGEgdmlzdWFsaXphY2nDs24uDQoNCkxlIGFncmVnYW1vcyBlbCBwYXJ0aWRvIGEgY2FkYSB1bm8gZGUgbG9zIGFuYWxpemFkb3MsIHkgYWRlbcOhcyBjYW1iaWFtb3Mgc3Ugbm9tYnJlIGRlbCBAIHF1ZSB2ZW1vcyBlbiBUd2l0dGVyLCBhIHVuIG5vbWJyZSBmw6FjaWwgZGUgZW50ZW5kZXIgcGFyYSB0b2Rvcw0KDQoNCmBgYHtyfQ0KVHdlZXRzX0RGIDwtDQogIFR3ZWV0c19ERiAlPiUNCiAgbXV0YXRlIChQYXJ0aWRvID0gaWZlbHNlIChQb2xpdGljbyA9PSAiYWxmZXJkZXoiLCAiUGVyb25pc21vIiwNCiAgICAgICAgICAgICAgICAgICAgaWZlbHNlIChQb2xpdGljbyA9PSAiQ0ZLQXJnZW50aW5hIiwgIlBlcm9uaXNtbyIsDQogICAgICAgICAgICAgICAgICAgIGlmZWxzZSAoUG9saXRpY28gPT0gImdpbmVzZ2dhcmNpYSIsICJQZXJvbmlzbW8iLCANCiAgICAgICAgICAgICAgICAgICAgaWZlbHNlIChQb2xpdGljbyA9PSAiS2ljaWxsb2ZvayIsICJQZXJvbmlzbW8iLA0KICAgICAgICAgICAgICAgICAgICBpZmVsc2UgKFBvbGl0aWNvID09ICJVQ1JOYWNpb25hbCIsICJjdWVudGEgcGFydGlkYXJpYSIsICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgaWZlbHNlIChQb2xpdGljbyA9PSAiRnJlbnRlRGVUb2RvcyIsICJjdWVudGEgcGFydGlkYXJpYSIsIA0KICAgICAgICAgICAgICAgICAgICBpZmVsc2UgKFBvbGl0aWNvID09ICJwcm9hcmdlbnRpbmEiLCAiY3VlbnRhIHBhcnRpZGFyaWEiLA0KICAgICAgICAgICAgICAgICAgICBpZmVsc2UgKFBvbGl0aWNvID09ICJQYXJ0aWRvR0VOIiwgImN1ZW50YSBwYXJ0aWRhcmlhIiwNCiAgICAgICAgICAgICAgICAgICAgaWZlbHNlIChQb2xpdGljbyA9PSAibWF1cmljaW9tYWNyaSIsICJQUk8iLA0KICAgICAgICAgICAgICAgICAgICBpZmVsc2UgKFBvbGl0aWNvID09ICJQYXRvQnVsbHJpY2giLCAiUFJPIiwNCiAgICAgICAgICAgICAgICAgICAgaWZlbHNlIChQb2xpdGljbyA9PSAiaG9yYWNpb3JsYXJyZXRhIiwgIlBSTyIsDQogICAgICAgICAgICAgICAgICAgIGlmZWxzZSAoUG9saXRpY28gPT0gIkZlcm5hblF1aXJvc0JBIiwgIlBSTyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvdHJvcyBjYW5kaWRhdG9zIikpKSkpKSkpKSkpKSkNCg0KVHdlZXRzX0RGIDwtDQogIFR3ZWV0c19ERiAlPiUNCiAgbXV0YXRlIChQb2xpdGljbyA9IGlmZWxzZSAoUG9saXRpY28gPT0gImFsZmVyZGV6IiwgIkEuRmVybmFuZGV6IiwNCiAgICAgICAgICAgICAgICAgICAgaWZlbHNlIChQb2xpdGljbyA9PSAiQ0ZLQXJnZW50aW5hIiwgIkMuS2lyY2huZXIiLA0KICAgICAgICAgICAgICAgICAgICBpZmVsc2UgKFBvbGl0aWNvID09ICJnaW5lc2dnYXJjaWEiLCAiR2luZXMuR0ciLCANCiAgICAgICAgICAgICAgICAgICAgaWZlbHNlIChQb2xpdGljbyA9PSAiS2ljaWxsb2ZvayIsICJBLktpY2lsbG9mIiwNCiAgICAgICAgICAgICAgICAgICAgaWZlbHNlIChQb2xpdGljbyA9PSAiVUNSTmFjaW9uYWwiLCAiVUNSIiwgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICBpZmVsc2UgKFBvbGl0aWNvID09ICJGcmVudGVEZVRvZG9zIiwgIlRPRE9TIiwgDQogICAgICAgICAgICAgICAgICAgIGlmZWxzZSAoUG9saXRpY28gPT0gInByb2FyZ2VudGluYSIsICJQUk8iLA0KICAgICAgICAgICAgICAgICAgICBpZmVsc2UgKFBvbGl0aWNvID09ICJQYXJ0aWRvR0VOIiwgIkdFTiIsDQogICAgICAgICAgICAgICAgICAgIGlmZWxzZSAoUG9saXRpY28gPT0gIm1hdXJpY2lvbWFjcmkiLCAiTS5NYWNyaSIsDQogICAgICAgICAgICAgICAgICAgIGlmZWxzZSAoUG9saXRpY28gPT0gIlBhdG9CdWxscmljaCIsICJQLkJ1bGxyaWNoIiwNCiAgICAgICAgICAgICAgICAgICAgaWZlbHNlIChQb2xpdGljbyA9PSAiaG9yYWNpb3JsYXJyZXRhIiwgIkguTGFycmV0YSIsDQogICAgICAgICAgICAgICAgICAgIGlmZWxzZSAoUG9saXRpY28gPT0gIkZlcm5hblF1aXJvc0JBIiwgIkYuUXVpcm9zIiwgDQogICAgICAgICAgICAgICAgICAgIGlmZWxzZSAoUG9saXRpY28gPT0gIk5pY29sYXNkZWxDYW5vIiwgIk4uRGVsQ2HDsW8iLA0KICAgICAgICAgICAgICAgICAgICBpZmVsc2UgKFBvbGl0aWNvID09ICJqbGVzcGVydCIsICJKLkVzcGVydCIsDQogICAgICAgICAgICAgICAgICAgIGlmZWxzZSAoUG9saXRpY28gPT0gIlJMYXZhZ25hIiwgIlIuTGF2YWduYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdvbWV6Q2VudHVyaW9uIg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICkpKSkpKSkpKSkpKSkpKSkNCg0KcHJpbnQoIk11ZXN0cmEiKQ0KcHJpbnQoVHdlZXRzX0RGICU+JSANCiAgc2VsZWN0KFBvbGl0aWNvLCBQYXJ0aWRvLCBzb3VyY2UpJT4lIA0KICAgIHRhaWwoMTApKQ0KYGBgDQoNCg0KPGNlbnRlcj4gPHNwYW4gc3R5bGU9ImNvbG9yOiAjMjgyRjQ0OyI+IDxoMz4gNC1DYW50aWRhZCBkZSB0d2VldHMgPC9oMz4gPC9zcGFuPiA8L2NlbnRlcj4NCg0KDQpMYSBwcmltZXJhIGFwcm94aW1hY2nDs24gcXVlIHZhbW9zIGEgdGVuZXIsIGVzIGxhIGNhbnRpZGFkIGRlIHZlY2VzIHF1ZSB0d2l0dGVvIGNhZGEgdW5vIGRlc2RlIG1hcnpvIGRlbCAyMDIwIGhhc3RhIGxhIGZlY2hhIGRlIHB1YmxpY2FjacOzbiBkZWwgaW5mb3JtZS4NCg0KU2UgcHJlc2VudGFuIGRpZmVyZW5jaWFzIGNvbnNpZGVyYWJsZXMgZW50cmUgdG9kb3MsIHNlIGRlYmVyw6Egbm9ybWFsaXphciBvIHV0aWxpemFyIHByb3BvcmNpb25lcyBtw6FzIGRlIHVuYSB2ZXoNCg0KICAtICpNYWNyaSB5IExhdmFnbmEgdGllbmVuIG1lbm9zIHR3ZWV0cyBxdWUgZWwgcmVzdG8qDQogIC0gKkNyaXN0aW5hIEtpcmNobmVyIGVzIHRhbWJpw6luIGRlIHBvY2EgcGFydGljaXBhY2nDs24qDQogIC0gKkxhcyBjdWVudGFzIGRlIEZyZW50ZSBkZSBUb2RvcywgRXNwZXJ0LCBEZWwgQ2HDsW8geSBsYSBVQ1Igc29uIGxhIGRlIG3DoXMgdXRpbGl6YWNpw7NuKg0KICANCiAgDQpgYGB7cn0NCkNhbnRpZGFkX3R3ZWV0cyA9IFR3ZWV0c19ERiAlPiUNCiAgZ3JvdXBfYnkoUG9saXRpY28sIFBhcnRpZG8pICU+JQ0KICBjb3VudChQb2xpdGljbykNCiAgDQpDYW50aWRhZF90d2VldHMlPiUgIA0KICBnZ3Bsb3QoKSsNCiAgYWVzKHg9cmVvcmRlcihQb2xpdGljbywgbiksIHk9IG4sIGZpbGw9IFBvbGl0aWNvKSArDQogIGdlb21fY29sKCkgKw0KICBmYWNldF93cmFwKCJQYXJ0aWRvIiwgc2NhbGVzID0gImZyZWVfeSIpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0aXRsZSA9ICJDYW50aWRhZCB0b3RhbCBkZSB0d2VldHMiLCB4ID0gInR3ZWV0cyIsIHkgPSAiQ2FudGlkYWQiKSArDQogICAgdGVtYTENCmBgYA0KDQoNCjxjZW50ZXI+IDxzcGFuIHN0eWxlPSJjb2xvcjogIzI4MkY0NDsiPiA8aDM+IDUtRmVjaGEgZGUgbG9zIHR3ZWV0cyA8L2gzPiA8L3NwYW4+IDwvY2VudGVyPg0KDQoNClZlbW9zIGN1YW5kbyBoYW4gaWRvIHB1YmxpY2FuZG8gY2FkYSB1bm8gZGUgbG9zIGFuYWxpemFkb3Mgc3VzIHR3ZWV0cywgY29uIGVsIGZpbiBkZSBtb3N0cmFyIGVuIHF1ZSDDqXBvY2EgdHV2aWVyb24gbcOhcyBvIG1lbm9zIGFjY2nDs24uDQoNCiAgLSAqRW4gZWwgY2FzbyBkZSBsYSBjdWVudGEgZGUgRnJlbnRlIGRlIHRvZG9zLCBjb21vIHR1dm8gbcOhcyBkZSAzMjAwIHR3ZWV0cywgZWwgYW7DoWxpc2lzIGFycmFuY2EgZGVzZGUgbG9zICAgICAgICAgICAgcHJpbWVyb3MgZMOtYXMgZGUgYWJyaWwqDQoNCg0KYGBge3J9DQpUd2VldHNfREYgJT4lDQogIGZpbHRlcihQYXJ0aWRvID09ICJQUk8iKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gYXMuRGF0ZShkYXRlKSwgZmlsbCA9IFBvbGl0aWNvKSkgKw0KICAgICAgZ2VvbV9oaXN0b2dyYW0ocG9zaXRpb24gPSAiaWRlbnRpdHkiLCBiaW5zID0gMjAsIHNob3cubGVnZW5kID0gRkFMU0UpICsNCiAgICAgIHNjYWxlX3hfZGF0ZShkYXRlX2xhYmVscyA9ICIlZC0lbSIsIGRhdGVfYnJlYWtzID0gIjEgbW9udGgiKSArDQogICAgICBsYWJzKHggPSAiZmVjaGEgZGUgcHVibGljYWNpw7NuIiwgeSA9ICJuw7ptZXJvIGRlIHR3ZWV0cyIpICsNCiAgICAgIGZhY2V0X3dyYXAofiBQb2xpdGljbywgbmNvbCA9IDEpICsNCiAgICAgIHRlbWEyICsNCiAgICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQpUd2VldHNfREYgJT4lDQogIGZpbHRlcihQYXJ0aWRvID09ICJQZXJvbmlzbW8iKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gYXMuRGF0ZShkYXRlKSwgZmlsbCA9IFBvbGl0aWNvKSkgKw0KICAgICAgZ2VvbV9oaXN0b2dyYW0ocG9zaXRpb24gPSAiaWRlbnRpdHkiLCBiaW5zID0gMjAsIHNob3cubGVnZW5kID0gRkFMU0UpICsNCiAgICAgIHNjYWxlX3hfZGF0ZShkYXRlX2xhYmVscyA9ICIlZC0lbSIsIGRhdGVfYnJlYWtzID0gIjEgbW9udGgiKSArDQogICAgICBsYWJzKHggPSAiZmVjaGEgZGUgcHVibGljYWNpw7NuIiwgeSA9ICJuw7ptZXJvIGRlIHR3ZWV0cyIpICsNCiAgICAgIGZhY2V0X3dyYXAofiBQb2xpdGljbywgbmNvbCA9IDEpICsNCiAgICAgIHRlbWExICsNCiAgICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQ0KDQpUd2VldHNfREYgJT4lDQogIGZpbHRlcihQYXJ0aWRvID09ICJvdHJvcyBjYW5kaWRhdG9zIikgJT4lDQogIGdncGxvdChhZXMoeCA9IGFzLkRhdGUoZGF0ZSksIGZpbGwgPSBQb2xpdGljbykpICsNCiAgICAgIGdlb21faGlzdG9ncmFtKHBvc2l0aW9uID0gImlkZW50aXR5IiwgYmlucyA9IDIwLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArDQogICAgICBzY2FsZV94X2RhdGUoZGF0ZV9sYWJlbHMgPSAiJWQtJW0iLCBkYXRlX2JyZWFrcyA9ICIxIG1vbnRoIikgKw0KICAgICAgbGFicyh4ID0gImZlY2hhIGRlIHB1YmxpY2FjacOzbiIsIHkgPSAibsO6bWVybyBkZSB0d2VldHMiKSArDQogICAgICBmYWNldF93cmFwKH4gUG9saXRpY28sIG5jb2wgPSAxKSArDQogICAgICB0ZW1hMSArDQogICAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KVHdlZXRzX0RGICU+JQ0KICBmaWx0ZXIoUGFydGlkbyA9PSAiY3VlbnRhIHBhcnRpZGFyaWEiKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gYXMuRGF0ZShkYXRlKSwgZmlsbCA9IFBvbGl0aWNvKSkgKw0KICAgICAgZ2VvbV9oaXN0b2dyYW0ocG9zaXRpb24gPSAiaWRlbnRpdHkiLCBiaW5zID0gMjAsIHNob3cubGVnZW5kID0gRkFMU0UpICsNCiAgICAgIHNjYWxlX3hfZGF0ZShkYXRlX2xhYmVscyA9ICIlZC0lbSIsIGRhdGVfYnJlYWtzID0gIjEgbW9udGgiKSArDQogICAgICBsYWJzKHggPSAiZmVjaGEgZGUgcHVibGljYWNpw7NuIiwgeSA9ICJuw7ptZXJvIGRlIHR3ZWV0cyIpICsNCiAgICAgIGZhY2V0X3dyYXAofiBQb2xpdGljbywgbmNvbCA9IDEpICsNCiAgICAgIHRlbWEyICArDQogICAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCmBgYA0KDQoNCg0KPGNlbnRlcj4gPHNwYW4gc3R5bGU9ImNvbG9yOiAjMjgyRjQ0OyI+IDxoMz4gNi1DYW50aWRhZCBkZSB0d2VldHMgc29icmUgQ09WSUQgPC9oMz4gPC9zcGFuPiA8L2NlbnRlcj4NCkVsIHRlbWEgbcOhcyBpbXBvcnRhbnRlIGRlbCBhw7FvIGVzIGVsIGNvcm9uYXZpcnVzLCBsYSBpZGVhIGVzIHZlciBxdcOpIHBvcmNlbnRhamUgZGUgbG9zIHR3ZWV0cyByZWFsaXphZG9zIGVzdG9zIG1lc2VzIHRyYXRvIHNvYnJlIGVsIGNvcm9uYXZpcnVzLCBwYXJhIGVzbyBzZSB2YW4gYSBidXNjYXIgcGFsYWJyYXMgY2xhdmVzIHF1ZSBkZXRlcm1pbmVuIHF1ZSBlbCB0d2VldCB0cmF0YSBzb2JyZSBsYSBwYW5kZW1pYS4NCg0KICAtICpDbGFyYW1lbnRlIGxvcyBtaW5pc3Ryb3Mgc29uIGxvcyBxdWUgbcOhcyBoYWJsYXJvbiBzb2JyZSBlbCBDb3JvbmF2aXJ1cywgY29uIGVsIDc1JSBkZSBzdXMgdHdlZXRzLioNCiAgDQogIC0gKlNpZ3VlbiBsb3MgZ29iZXJuYWRvcmVzIEtpY2lsb2ZmIHkgTGFycmV0YSwgcXVlIHRyYXRhcm9uIHNvYnJlIGxhIGV2b2x1Y2nDs24gZGUgbGEgcGFuZGVtaWEgZW4gc3VzIGRpc3RyaXRvcy4qIA0KDQogIC0gKkVuIG1lbm9yIG1lZGlkYSBoYWJsYXJvbiBsb3MgbMOtZGVyZXMgZGUgbG9zIGRvcyBwcmluY2lwYWxlcyBwYXJ0aWRvcy4qDQoNCiAgLSAqRGVsIENhw7FvIGVzIGVsIHF1ZSBtw6FzIGhhYmxvIGVudHJlIGxvcyBvdHJvcyBjYW5kaWRhdG9zLCBsbyBzaWd1ZSBFc3BlcnQsIG1pZW50cmFzIHF1ZSBMYXZhZ25hIHkgR8OzbWV6IENlbnR1cmnDs24gICAgIGhhYmxhcm9uIG11eSBwb2NvLioNCg0KICAtICpMYXMgY3VlbnRhcyBwYXJ0aWRhcmlhcywgc2Fsdm8gbGFzIGRlIGxhIFVDUiBubyBmdWVyb24gbXV5IHVzYWRhcyBwYXJhIGhhYmxhciBzb2JyZSBlbCBDb3JvbmF2aXJ1cyoNCg0KDQpgYGB7cn0NCiNCdXNjYW1vcyB0d2VldHMgY29uIGxhIHBhbGFicmEgY292aWQNClBhbGFicmFzX2NvdmlkIDwtICJjb3ZpZHxjb3ZpZC0xOXxjb3ZpZDE5fGNvcm9uYXZpcnVzfCNjb3ZpZHwjY292aWQtMTl8I2NvdmlkMTl8I2Nvcm9uYXZpcnVzfHRlc3R8dGVzdGVvfHRlc3Rlb3N8cGNyfHNlcm9sb2dpY298aGlzb3BhZG98YW50aWJpb3RpY29zfGFwbGFuYXJ8Y3VydmF8Y3VhcmVudGVuYXxjb250YWdpb3xlbmZlcm1lZGFkfGVwaWRlbWlhfHBhbmRlbWlhfGFsYXJtYXxnZWx8Y3VpZGFkb3N8aW5jdWJhY2lvbnxqYWJvbnxiYXJiaWpvfGJhcmJpam9zfG1hc2NhcmlsbGF8bWFzY2FyaWxsYXN8bWVyc3xzYXJzfHZhY3VuYXx3dWhhbnxveGZvcmR8YXN0cmF8emVuZWNhfHRyYW5zbWlzaW9ufGV4cG9uZW5jaWFsfGNhc29zfGR1cGxpY2FjaW9ufGRpc3RhbmNpYW1pZW50b3xjb2xhcHNvfHNhbHVkfGxldGFsaWRhZHxtb3J0YWxpZGFkfHZlbnRpbGFkb3J8aWN1fHVjaXx1dGl8aW5tdW5pZGFkfHNlcm9sb2dpY2F8ZGlzdGFuY2lhbWllbnRvfHZpcnVzfGFzaW50b21hdGljb3xjYXNvIHNvc3BlY2hvc298b2xmYXRvfGd1c3RvfHRlcmFwaWF8c2F0dXJhY2lvbnxjbGluaWNhfHBvc2l0aXZpZGFkfHBvc2l0aXZpb3N8cmViYcOxb3xpbm11bmlkYWR8aG9zcGl0YWx8aG9zcGl0YWxlc3xhc3BvfGFpc2xhbWllbnRvIg0KVHdlZXRzX0RGJENvdmlkIDwtIGdyZXBsKFBhbGFicmFzX2NvdmlkLCBUd2VldHNfREYkdGV4dCwgaWdub3JlLmNhc2UgPSJUcnVlIikNCg0KVHdlZXRzX0RGICU+JSANCmNvdW50KFBvbGl0aWNvLCBQYXJ0aWRvLENvdmlkKSAlPiUNCiAgZ3JvdXBfYnkoUG9saXRpY28pICU+JQ0KICBtdXRhdGUoUHJvcG9yY2lvbiA9IG4gLyBzdW0obikpICU+JQ0KICBtdXRhdGUoQ292aWQgPSBpZmVsc2UoQ292aWQgPT0gVCwgIlNvYnJlIENPVklEIiwgIk90cm8gdGVtYSIpKSU+JQ0KZ2dwbG90KCkgKw0KICBhZXMoUG9saXRpY28sIFByb3BvcmNpb24sIGZpbGwgPSBDb3ZpZCkgKw0KICBnZW9tX2NvbCgpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KCkpICsNCiAgICAgIGZhY2V0X3dyYXAoIlBhcnRpZG8iLCBzY2FsZXMgPSAiZnJlZSIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpDQpgYGANCg0KDQoNCjxjZW50ZXI+IDxzcGFuIHN0eWxlPSJjb2xvcjogIzI4MkY0NDsiPiA8aDM+ICA3LSBXb3JkY2xvdWQgPC9oMz4gPC9zcGFuPiA8L2NlbnRlcj4NCkxhIGlkZWEgZGUgbGEgbnViZSBkZSBwYWxhYnJhcyBlcyBzYWJlciBjdcOhbGVzIHNvbiBsYXMgMjAwIHBhbGFicmFzIHF1ZSBtw6FzIHNlIHVzYXJvbiBwb3IgbG9zIGFuYWxpemFkb3MgZXN0b3MgbWVzZXMsIGNvbW8gZXJhIGRlIGVzcGVyYXJzZSBzb2JyZXNhbGVuICoqImNvcm9uYXZpcnVzIioqLCAqKiJjb3ZpZCIqKiwgKioicGFuZGVtaWEiKiogbyAqKiJjdWFyZW50ZW5hIioqDQoNCg0KYGBge3J9DQp0dWl0c190b2tlbnMgPC0NCiAgVHdlZXRzX0RGICU+JQ0KICB1bm5lc3RfdG9rZW5zKGlucHV0ID0gdGV4dCwgb3V0cHV0ID0gUGFsYWJyYSwgdG9rZW4gPSAid29yZHMiKSAlPiUNCiAgc2VsZWN0KFBvbGl0aWNvLCBQYWxhYnJhLCBzdGF0dXNfaWQsIHBlcmlvZG8sIG1lcywgaG91ciwgUGFydGlkbykgJT4lDQogIG11dGF0ZShzdGF0dXNfaWQgPSBnc3ViKCI8KC4qKT4rPyIsICIiLCBzdGF0dXNfaWQpKSAlPiUNCiAgZmlsdGVyKCFQYWxhYnJhICVpbiUgc3RvcHdvcmRzKCJlcyIpKSAlPiUNCiAgZmlsdGVyKCFQYWxhYnJhICVpbiUgYygidC5jbyIsICJodHRwcyIsICJ2w4PCrWEiLCAieW91dHViZSIsICJhbXAiKSkNCg0KUGFsYWJyYXNfc2luaG95bWFzID0gdHVpdHNfdG9rZW5zICAlPiUNCiAgZmlsdGVyKFBhbGFicmEgIT0gIm1hcyIgJiBQYWxhYnJhICE9ICJob3kiKSANCg0Kd29yZGNsb3VkKHdvcmRzID0gUGFsYWJyYXNfc2luaG95bWFzJFBhbGFicmEsIA0KICAgICAgICAgIHNjYWxlPWMoMiwuMiksIA0KICAgICAgICAgIG1heC53b3Jkcz0yMDAsIHJhbmRvbS5vcmRlcj1GQUxTRSwgcm90LnBlcj0wLjM1LCANCiAgICAgICAgICBjb2xvcnM9YnJld2VyLnBhbCg4LCAiRGFyazIiKSwNCiAgICAgICAgICApDQoNCg0KYGBgDQoNCg0KDQo8Y2VudGVyPiA8c3BhbiBzdHlsZT0iY29sb3I6ICMyODJGNDQ7Ij4gPGgzPiA4LURlc2NhcmdhbW9zIHVuIGRpY2Npb25hcmlvIDwvaDM+IDwvc3Bhbj4gPC9jZW50ZXI+DQoNCg0KRGVzY2FyZ2Ftb3MgdW4gZGljY2lvbmFyaW8gcXVlIHRpZW5lIGxhcyBwYWxhYnJhcyBlbiBlc3Bhw7FvbCwgeSBsZSBhc2lnbmEgdW4gdmFsb3IgZW50cmUgLTUgYSA1LCBtb3N0cmFuZG8gbGEgcG9zaXRpdmlkYWQgbyBuZWdhdGl2aWRhZCBkZSBsYSBwYWxhYnJhLg0KDQpFbGltaW5hbW9zIGxhIHBhbGFicmEgKiJObyIqIHF1ZSBsYSB0b21hIGNvbW8gbmVnYXRpdmEsIGN1YW5kbyBlbiBlc3Bhw7FvbCBlcyB1biBjb25lY3RvciBhIHZlY2VzLCB5IGxhIHBhbGFicmEgKuKAnE5lZ3Jv4oCdKiAoTmlnZ2EpIHF1ZSBsYSB0b21hIGNvbiBlbCBtw6F4aW1vIHZhbG9yIG5lZ2F0aXZvDQoNCg0KYGBge3J9DQpkb3dubG9hZC5maWxlKCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vamJvc2NvbWVuZG96YS9ycHVicy9tYXN0ZXIvc2VudGltaWVudG9zX2FmaW5uL2xleGljb19hZmlubi5lbi5lcy5jc3YiLA0KICAgICAgICAgICAgICAibGV4aWNvX2FmaW5uLmVuLmVzLmNzdiIpDQoNCmFmaW5uIDwtIHJlYWQuY3N2KCJsZXhpY29fYWZpbm4uZW4uZXMuY3N2Iiwgc3RyaW5nc0FzRmFjdG9ycyA9IEYsIGZpbGVFbmNvZGluZyA9ICJsYXRpbjEiKSAlPiUgDQogIHRibF9kZigpDQoNCmFmaW5uJFB1bnR1YWNpb24gPC0gaWZlbHNlKGFmaW5uJFBhbGFicmEgPT0gIm5vIiwgMCwgYWZpbm4kUHVudHVhY2lvbikNCmFmaW5uJFB1bnR1YWNpb24gPC0gaWZlbHNlKGFmaW5uJFBhbGFicmEgPT0gIm5lZ3JvIiwgMCwgYWZpbm4kUHVudHVhY2lvbikNCg0KcHJpbnQoIk11ZXN0cmEiKQ0KYWZpbm4gJT4lDQogIHNlbGVjdChQYWxhYnJhLCBQdW50dWFjaW9uKSAlPiUNCiAgICBhcnJhbmdlKFB1bnR1YWNpb24pICU+JQ0KICBwcmludChoZWFkKDEwKSkNCg0KYWZpbm4gJT4lDQogIHNlbGVjdChQYWxhYnJhLCBQdW50dWFjaW9uKSAlPiUNCiAgICBhcnJhbmdlKC1QdW50dWFjaW9uKSAlPiUNCiAgcHJpbnQodGFpbCgxMCkpDQpgYGANCg0KDQoNCg0KPGNlbnRlcj4gPHNwYW4gc3R5bGU9ImNvbG9yOiAjMjgyRjQ0OyI+IDxoMz4gOS0gU2VwYXJhY2lvbiBkZSBwYWxhYnJhcyA8L2gzPiA8L3NwYW4+IDwvY2VudGVyPg0KDQoNClNlcGFyYW1vcyBsYXMgZGlzdGludGFzIHBhbGFicmFzIHF1ZSB1c2Fyb24gY2FkYSB1bm8gZGUgbG9zIHBvbMOtdGljb3MgZW4gc3VzIHR3ZWV0cywgeSBlbGltaW5hbW9zIGFsZ3VuYXMgcGFsYWJyYXMgcHJvcGlhcyBkZSBUd2l0dGVyIHkgbGFzIGxsYW1hZGFzIHN0b3B3b3JkcyBxdWUgc29uIGxhcyBwYWxhYnJhcyBtw6FzIGZyZWN1ZW50ZXMgZW4gZWwgaWRpb21hIGVzcGHDsW9sLg0KDQoNCmBgYHtyfQ0KcHJpbnQgKCJNdWVzdHJhIikNCnByaW50ICh0dWl0c190b2tlbnMgJT4lDQogICAgc2VsZWN0KFBvbGl0aWNvLCBQYWxhYnJhKSAlPiUgICAgDQogICAgICAgICBoZWFkICgxMCkpDQpgYGANCg0KPGNlbnRlcj4gPHNwYW4gc3R5bGU9ImNvbG9yOiAjMjgyRjQ0OyI+IDxoMz4gMTAtIExlIGRhbW9zIHZhbG9yIGEgbGFzIHBhbGFicmFzIDwvaDM+IDwvc3Bhbj4gPC9jZW50ZXI+DQoNCg0KVW5pbW9zIGVsIGRpY2Npb25hcmlvIGRlIHB1bnR1YWNpw7NuIGNvbiBsYXMgcGFsYWJyYXMgcXVlIHVzbyBjYWRhIHVubyBkZSBsb3MgYW5hbGl6YWRvcywgY29uIGVsIGZpbiBkZSBxdWUgY2FkYSBwYWxhYnJhIHRlbmdhIHVuIHZhbG9yLCB5IG5vcyBzaXJ2YSBwYXJhIGFuYWxpemFyIHF1ZSBlc2NyaWJpw7MgY2FkYSBwb2zDrXRpY28uDQoNCkxhcyBwYWxhYnJhcyBzZXLDoW46IA0KICAtICBTaSB0aWVuZW4gdmFsb3IgbWF5b3IgYSAwICoqUG9zaXRpdmFzKiogDQogIA0KICAtICBTaSBzb24gbWVub3JlcyBhIDAgKipOZWdhdGl2YXMqKiANCiAgDQogIC0gIEVuIGNhc28gZGUgcXVlIGxhIHBhbGFicmEgbm8gdGVuZ2EgY2FyZ2EgZGUgc2VudGltaWVudG9zKipOZXV0cmFsZXMqKiANCg0KDQpgYGB7cn0NCnR1aXRzX3Rva2Vuc19lbW9jaW9uZXMgPC0gICANCiB0dWl0c190b2tlbnMgJT4lDQppbm5lcl9qb2luKGFmaW5uLCAuLCBieSA9ICJQYWxhYnJhIikgJT4lDQogIG11dGF0ZShDYWxpZmljYWNpb24gPSBpZmVsc2UoUHVudHVhY2lvbiA+IDAsICJQb3NpdGl2YSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKFB1bnR1YWNpb24gPT0gMCwgIk5ldXRyYWwiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5lZ2F0aXZhIikNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICkgICAgICANCg0KcHJpbnQgKCJNdWVzdHJhIikNCnByaW50ICh0dWl0c190b2tlbnNfZW1vY2lvbmVzICU+JQ0KICAgIHNlbGVjdChQb2xpdGljbywgUGFsYWJyYSwgUHVudHVhY2lvbiwgQ2FsaWZpY2FjaW9uKSAlPiUgICAgDQogICAgICAgICB0YWlsICgxMCkpDQpgYGANCg0KDQoNCjxjZW50ZXI+IDxzcGFuIHN0eWxlPSJjb2xvcjogIzI4MkY0NDsiPiA8aDM+IDExLSDCv1F1acOpbiB1c2EgbcOhcyBjYXJhY3RlcmVzPyA8L2gzPiA8L3NwYW4+IDwvY2VudGVyPg0KDQoNCkxhIGlkZWEgZXMgYnVzY2FyIGN1YWwgZXMgZWwgcHJvbWVkaW8gZGVsIGxhcmdvIChjYW50aWRhZCBkZSBjYXJhY3RlcmVzKSBkZSBsb3MgdHdlZXRzIHF1ZSByZWFsaXphIGNhZGEgdW5vIGRlIGxvcyBhbmFsaXphZG9zLg0KDQpNaWVudHJhcyBtw6FzIGEgbGEgZGVyZWNoYSBlc3RlIGxhIGNhamEsIG3DoXMgbGFyZ28gc29uIGxvcyB0d2VldHMgcXVlIGVzY3JpYmVuLCBlbiBlc2UgYXNwZWN0byBzZSBkZXN0YWNhbjogDQogIC0JKkxhdmFnbmEsIFBhdHJpY2lhIEJ1bGxyaWNoLCBMYXJyZXRhIHkgRmVybsOhbiBRdWlyw7NzIHNvbiBsb3MgcXVlIGVzY3JpYmVuIGxvcyB0d2VldHMgbcOhcyBsYXJnb3MuKiANCiAgLQkqQXF1ZWxsb3MgcmVsYWNpb25hZG9zIGFsIFBSTyBzb24gZGUgZXNjcmliaXIgdHdlZXRzIG3DoXMgbGFyZ29zKg0KDQoNCmBgYHtyfQ0KVHdlZXRzX0RGICU+JSANCmdncGxvdCgpKw0KICBhZXMoeD0gUG9saXRpY28sIHk9IGRpc3BsYXlfdGV4dF93aWR0aCwgY29sb3I9IFBvbGl0aWNvKSArDQogIGdlb21fYm94cGxvdCAoKSArDQogICAgbGFicyh0aXRsZSA9ICJMYXJnbyBwcm9tZWRpbyBkZWwgdHdlZXQiLCB4ID0gIlBvbGl0aWNvIiwgeSA9ICJDYW50aWRhZCBjYXJhY3RlcmVzIikgKw0KICBjb29yZF9mbGlwKCkgKw0KICAgIHRlbWExDQpgYGANCg0KDQoNCg0KPGNlbnRlcj4gPHNwYW4gc3R5bGU9ImNvbG9yOiAjMjgyRjQ0OyI+IDxoMz4gMTItIMK/UXVpw6luIHVzYSBtw6FzIHBhbGFicmFzPyA8L2gzPiA8L3NwYW4+IDwvY2VudGVyPg0KDQoNCkxhIGlkZWEgZXMgYW5hbGl6YXIgcXVpZW4gZXMgZWwgcXVlIHVzbyBtw6FzIHBhbGFicmFzIGRpc3RpbnRhcyBlbiBwcm9tZWRpbyBkdXJhbnRlIGVzdGUgdGllbXBvLCBlbiBlc3RlIGNhc28gdmFtb3MgYSBkaXZpZGlyIHBvciBsYSBjYW50aWRhZCBkZSB0d2VldHMgcXVlIGhpem8sIGFzw60gcXVlZGEgbm9ybWFsaXphZG8gcGFyYSB0b2RvcyBsb3MgYW5hbGl6YWRvcy4NCg0KKk5vIHNlIGN1ZW50YW4gbG9zIGNvbmVjdG9yZXMgY29tdW5lcyBjb21vICJlbiIsICJhIiwgImRlIiwgZXRjLioNCg0KICAtCSpFc3BlcnQgZXN0YSBhYmFqbyBkZSBsYXMgMTUgcGFsYWJyYXMgcG9yIHR3ZWV0LCBlcyBlbCBkZSBtZW5vciB1c28uKg0KICAtCSpFbCByZXN0byBlc3TDoSBlbiB1bmEgY2FudGlkYWQgc2ltaWxhcmVzIGRlIGVudHJlIDE1IHkgMjAgcGFsYWJyYXMuKg0KDQoNCmBgYHtyfQ0KQ2FudGlkYWRfcGFsYWJyYXM9IHR1aXRzX3Rva2VucyU+JQ0KICBncm91cF9ieShQb2xpdGljbywgUGFydGlkbyklPiUNCiAgY291bnQoUG9saXRpY28pJT4lDQppbm5lcl9qb2luKENhbnRpZGFkX3R3ZWV0cywgLiwgYnkgPSAiUG9saXRpY28iKSU+JQ0KICBtdXRhdGUoY2FudGlkYWRfcHJvbWVkaW8gPSBuLnkgLyBuLngpDQoNCg0KQ2FudGlkYWRfcGFsYWJyYXMlPiUgZ2dwbG90KCkrDQogIGFlcyh4PXJlb3JkZXIoUG9saXRpY28sIC1jYW50aWRhZF9wcm9tZWRpbyksIHk9IGNhbnRpZGFkX3Byb21lZGlvLCBmaWxsPSBQb2xpdGljbykgKw0KICBnZW9tX2NvbCgpICsNCiAgZmFjZXRfd3JhcCgiUGFydGlkby54Iiwgc2NhbGVzID0gImZyZWVfeSIpICsNCiAgbGFicyh0aXRsZSA9ICJVc28gZGUgcGFsYWJyYXMiLCB4ID0gInR3ZWV0cyIsIHkgPSAiQ2FudGlkYWQiKSArDQogIGNvb3JkX2ZsaXAoKSArDQogICAgdGVtYTENCg0KDQpgYGANCg0KDQoNCg0KPGNlbnRlcj4gPHNwYW4gc3R5bGU9ImNvbG9yOiAjMjgyRjQ0OyI+IDxoMz4gIDEzLSDCv1F1aWVuIHVzYSBtYXMgcGFsYWJyYXMgZGlzdGludGFzPyA8L2gzPiA8L3NwYW4+IDwvY2VudGVyPg0KDQpCdXNjYW1vcyB2ZXIgZWwgbMOpeGljbyBkaXN0aW50aXZvIHF1ZSBoYXkgZW4gY2FkYSB1bmEgZGUgbGFzIGN1ZW50YXMsIGNvbnRhbmRvIHN1cyBwYWxhYnJhcyDDum5pY2FzIHkgc2Ugbm90YTogDQoNCi0JKkRpZmVyZW5jaWFzIGVudHJlIExhdmFnbmEsIE1hY3JpLCBDcmlzdGluYSBjb24gZWwgcmVzdG8gZGUgbG9zIHF1ZSBlc2NyaWJlbioNCg0KLQkqRXNwZXJ0IHF1ZSBlcyBlbCBkZSBsw6l4aWNvIG1lbm9zIHZhcmlhZG8qDQoNCg0KYGBge3J9DQp0dWl0c190b2tlbnMlPiUNCiAgZ3JvdXBfYnkoUG9saXRpY28sIFBhcnRpZG8pJT4lDQogIGRpc3RpbmN0KFBhbGFicmEpJT4lDQogIGNvdW50KFBvbGl0aWNvKSU+JQ0KaW5uZXJfam9pbihDYW50aWRhZF90d2VldHMsIC4sIGJ5ID0gIlBvbGl0aWNvIikgICU+JQ0KICBtdXRhdGUoY2FudGlkYWRfcHJvbWVkaW8gPSBuLnkgLyBuLngpICU+JSANCiAgZ2dwbG90KCkrDQogIGFlcyh4PXJlb3JkZXIoUG9saXRpY28sIGNhbnRpZGFkX3Byb21lZGlvKSwgeT0gY2FudGlkYWRfcHJvbWVkaW8sIGZpbGw9IFBvbGl0aWNvKSArDQogIGdlb21fY29sKCkgKw0KICBmYWNldF93cmFwKCJQYXJ0aWRvLngiLCBzY2FsZXMgPSAiZnJlZV95IikgKw0KICBsYWJzKHRpdGxlID0gIlBhbGFicmFzIGRpc3RpbnRhcyIsIHggPSAidHdlZXRzIiwgeSA9ICJDYW50aWRhZCIpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgICB0ZW1hMQ0KICANCmBgYA0KDQoNCg0KDQo8Y2VudGVyPiA8c3BhbiBzdHlsZT0iY29sb3I6ICMyODJGNDQ7Ij4gPGgzPiAxNC0gUGFsYWJyYXMgbcOhcyB1c2FkYXMgPC9oMz4gPC9zcGFuPiA8L2NlbnRlcj4NCg0KQWhvcmEgcXVlIHlhIHNhYmVtb3MgY29uIHF1w6kgdmFyaWVkYWQgZGUgcGFsYWJyYXMsIHBvZGVtb3MgYW5hbGl6YXIgY3XDoWxlcyBzb24gbGFzIHF1ZSBtw6FzIHVzYXJvbg0KRW4gZXN0ZSBjYXNvLCBjYWRhIGdyYWZpY28gdGllbmUgdW5hIGVzY2FsYSBkaXN0aW50YSBwYXJhIHF1ZSBubyBzZSBwaWVyZGEgcG9yIGxhIGNhbnRpZGFkIGRlIHR3ZWV0cyByZWFsaXphZG9zLg0KDQpMYXMgcGFsYWJyYXMgbcOhcyB1dGlsaXphZGFzIGZ1ZXJvbjogDQoNCi0gIipldml0YXIqIg0KLSAiKmRldWRhKiINCi0gIipqdXN0aWNpYSoiIA0KLSAiKmxpYmVydGFkKiIgdXNhZGEgcHJpbmNpcGFsbWVudGUgcG9yIEVzcGVydC4NCg0KDQpgYGB7cn0NCnR1aXRzX3Rva2Vuc19lbW9jaW9uZXMgJT4lDQogICAgZ3JvdXBfYnkoUGFydGlkbywgUG9saXRpY28pICU+JQ0KICAgIGNvdW50KFBhbGFicmEsIHNvcnQgPSBUKSAlPiUNCiAgICAgc2xpY2VfbWF4KG9yZGVyX2J5ID0gbiwgbj0gMTApICU+JQ0KICAgICAgZmlsdGVyKFBhcnRpZG8gPT0gICJQUk8iKSAlPiUNCiAgICBnZ3Bsb3QoKSArDQogICAgYWVzKFBhbGFicmEsIG4sIGZpbGwgPSBQb2xpdGljbykgKw0KICAgIGdlb21fY29sKCkgKw0KICAgIGZhY2V0X3dyYXAoIlBvbGl0aWNvIiwgc2NhbGVzID0gImZyZWUiKSArDQogICAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCkpICsNCiAgICBjb29yZF9mbGlwKCkgKw0KICAgIGxhYnModGl0bGUgPSAiUGFsYWJyYXMgbcOhcyB1c2FkYXMiKSArDQogICAgIHRlbWExDQoNCiB0dWl0c190b2tlbnNfZW1vY2lvbmVzICU+JQ0KICAgIGdyb3VwX2J5KFBhcnRpZG8sIFBvbGl0aWNvKSAlPiUNCiAgICBjb3VudChQYWxhYnJhLCBzb3J0ID0gVCkgJT4lDQogICAgIHNsaWNlX21heChvcmRlcl9ieSA9IG4sIG49IDEwKSAlPiUNCiAgICAgIGZpbHRlcihQYXJ0aWRvID09ICAiUGVyb25pc21vIikgJT4lDQogICAgZ2dwbG90KCkgKw0KICAgIGFlcyhQYWxhYnJhLCBuLCBmaWxsID0gUG9saXRpY28pICsNCiAgICBnZW9tX2NvbCgpICsNCiAgICBmYWNldF93cmFwKCJQb2xpdGljbyIsIHNjYWxlcyA9ICJmcmVlIikgKw0KICAgIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsIDApKSArDQogICAgY29vcmRfZmxpcCgpICsNCiAgICBsYWJzKHRpdGxlID0gIlBhbGFicmFzIG3DoXMgdXNhZGFzIikgKw0KICAgICB0ZW1hMQ0KIA0KICB0dWl0c190b2tlbnNfZW1vY2lvbmVzICU+JQ0KICAgIGdyb3VwX2J5KFBhcnRpZG8sIFBvbGl0aWNvKSAlPiUNCiAgICBjb3VudChQYWxhYnJhLCBzb3J0ID0gVCkgJT4lDQogICAgIHNsaWNlX21heChvcmRlcl9ieSA9IG4sIG49IDEwKSAlPiUNCiAgICAgIGZpbHRlcihQYXJ0aWRvID09ICAib3Ryb3MgY2FuZGlkYXRvcyIpICU+JQ0KICAgIGdncGxvdCgpICsNCiAgICBhZXMoUGFsYWJyYSwgbiwgZmlsbCA9IFBvbGl0aWNvKSArDQogICAgZ2VvbV9jb2woKSArDQogICAgZmFjZXRfd3JhcCgiUG9saXRpY28iLCBzY2FsZXMgPSAiZnJlZSIpICsNCiAgICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLCAwKSkgKw0KICAgIGNvb3JkX2ZsaXAoKSArDQogICAgbGFicyh0aXRsZSA9ICJQYWxhYnJhcyBtw6FzIHVzYWRhcyIpICsNCiAgICAgdGVtYTENCiAgDQogICB0dWl0c190b2tlbnNfZW1vY2lvbmVzICU+JQ0KICAgIGdyb3VwX2J5KFBhcnRpZG8sIFBvbGl0aWNvKSAlPiUNCiAgICBjb3VudChQYWxhYnJhLCBzb3J0ID0gVCkgJT4lDQogICAgIHNsaWNlX21heChvcmRlcl9ieSA9IG4sIG49IDEwKSAlPiUNCiAgICAgIGZpbHRlcihQYXJ0aWRvID09ICAiY3VlbnRhIHBhcnRpZGFyaWEiKSAlPiUNCiAgICBnZ3Bsb3QoKSArDQogICAgYWVzKFBhbGFicmEsIG4sIGZpbGwgPSBQb2xpdGljbykgKw0KICAgIGdlb21fY29sKCkgKw0KICAgIGZhY2V0X3dyYXAoIlBvbGl0aWNvIiwgc2NhbGVzID0gImZyZWUiKSArDQogICAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCkpICsNCiAgICBjb29yZF9mbGlwKCkgKw0KICAgIGxhYnModGl0bGUgPSAiUGFsYWJyYXMgbcOhcyB1c2FkYXMiKSArDQogICAgIHRlbWExDQpgYGANCg0KDQoNCg0KPGNlbnRlcj4gPHNwYW4gc3R5bGU9ImNvbG9yOiAjMjgyRjQ0OyI+IDxoMz4gMTUtIFBhbGFicmFzIHBvc2l0aXZhcyBtw6FzIHVzYWRhcyA8L2gzPiA8L3NwYW4+IDwvY2VudGVyPg0KDQpBbCB0ZW5lciB1bmEgcHVudHVhY2nDs24gY2FkYSBwYWxhYnJhIG90b3JnYWRhIHBvciBlbCBkaWNjaW9uYXJpbyBkZSBsw6l4aWNvLCB0YW1iacOpbiBwb2RlbW9zIGJ1c2NhciBjdWFsZXMgc29uIGxhcyBwYWxhYnJhcyBwb3NpdGl2YXMgcXVlIG3DoXMgdXNvIGNhZGEgdW5vIGRlIGxvcyBwb2zDrXRpY29zLg0KDQpFbiBlc3RlIGNhc286IA0KDQotIFNlIG5vdGEgZWwgdXNvIGRlIGxhcyBwYWxhYnJhcyAqKiJsaWJlcnRhZCIqKiB5ICoqImp1c3RpY2lhIioqIHF1ZSBzb24gY29uc2lkZXJhZGFzIHBvc2l0aXZhcw0KDQotIEFwYXJlY2UgYmFzdGFudGUgZWwgdXNvIGRlIGxhIHBhbGFicmEgKioiZ3JhY2lhcyIqKiwgcHJpbmNpcGFsbWVudGUgZGUgYXF1ZWxsYXMgY3VlbnRhcyByZWxhY2lvbmFkYSBhIGxhIHNhbHVkICoqKEdpbmVzIEdvbnrDoWxleiBHYXJjw61hIHkgRmVybsOhbiBRdWlyw7NzKSoqDQoNCg0KYGBge3J9DQogdHVpdHNfdG9rZW5zX2Vtb2Npb25lcyAlPiUNCiAgICBmaWx0ZXIoQ2FsaWZpY2FjaW9uID09ICAiUG9zaXRpdmEiKSAlPiUNCiAgICBncm91cF9ieShQYXJ0aWRvLCBQb2xpdGljbykgJT4lDQogICAgY291bnQoUGFsYWJyYSwgc29ydCA9IFQpICU+JQ0KICAgICBzbGljZV9tYXgob3JkZXJfYnkgPSBuLCBuPSAxMCkgJT4lDQogICAgICBmaWx0ZXIoUGFydGlkbyA9PSAgIlBSTyIpICU+JQ0KICAgIGdncGxvdCgpICsNCiAgICBhZXMoUGFsYWJyYSwgbiwgZmlsbCA9IFBvbGl0aWNvKSArDQogICAgZ2VvbV9jb2woKSArDQogICAgZmFjZXRfd3JhcCgiUG9saXRpY28iLCBzY2FsZXMgPSAiZnJlZSIpICsNCiAgICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLCAwKSkgKw0KICAgIGNvb3JkX2ZsaXAoKSArDQogICAgbGFicyh0aXRsZSA9ICJQYWxhYnJhcyBQb3NpdGl2YXMgbcOhcyB1c2FkYXMiKSANCg0KIHR1aXRzX3Rva2Vuc19lbW9jaW9uZXMgJT4lDQogICAgZmlsdGVyKENhbGlmaWNhY2lvbiA9PSAgIlBvc2l0aXZhIikgJT4lDQogICAgZ3JvdXBfYnkoUGFydGlkbywgUG9saXRpY28pICU+JQ0KICAgIGNvdW50KFBhbGFicmEsIHNvcnQgPSBUKSAlPiUNCiAgICAgc2xpY2VfbWF4KG9yZGVyX2J5ID0gbiwgbj0gMTApICU+JQ0KICAgICAgZmlsdGVyKFBhcnRpZG8gPT0gICJQZXJvbmlzbW8iKSAlPiUNCiAgICBnZ3Bsb3QoKSArDQogICAgYWVzKFBhbGFicmEsIG4sIGZpbGwgPSBQb2xpdGljbykgKw0KICAgIGdlb21fY29sKCkgKw0KICAgIGZhY2V0X3dyYXAoIlBvbGl0aWNvIiwgc2NhbGVzID0gImZyZWUiKSArDQogICAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCkpICsNCiAgICBjb29yZF9mbGlwKCkgKw0KICAgIGxhYnModGl0bGUgPSAiUGFsYWJyYXMgUG9zaXRpdmFzIG3DoXMgdXNhZGFzIikgDQogDQogIHR1aXRzX3Rva2Vuc19lbW9jaW9uZXMgJT4lDQogICAgZmlsdGVyKENhbGlmaWNhY2lvbiA9PSAgIlBvc2l0aXZhIikgJT4lDQogICAgZ3JvdXBfYnkoUGFydGlkbywgUG9saXRpY28pICU+JQ0KICAgIGNvdW50KFBhbGFicmEsIHNvcnQgPSBUKSAlPiUNCiAgICAgc2xpY2VfbWF4KG9yZGVyX2J5ID0gbiwgbj0gMTApICU+JQ0KICAgICAgZmlsdGVyKFBhcnRpZG8gPT0gICJvdHJvcyBjYW5kaWRhdG9zIikgJT4lDQogICAgZ2dwbG90KCkgKw0KICAgIGFlcyhQYWxhYnJhLCBuLCBmaWxsID0gUG9saXRpY28pICsNCiAgICBnZW9tX2NvbCgpICsNCiAgICBmYWNldF93cmFwKCJQb2xpdGljbyIsIHNjYWxlcyA9ICJmcmVlIikgKw0KICAgIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsIDApKSArDQogICAgY29vcmRfZmxpcCgpICsNCiAgICBsYWJzKHRpdGxlID0gIlBhbGFicmFzIFBvc2l0aXZhcyBtw6FzIHVzYWRhcyIpIA0KICANCiAgIHR1aXRzX3Rva2Vuc19lbW9jaW9uZXMgJT4lDQogICAgZmlsdGVyKENhbGlmaWNhY2lvbiA9PSAgIlBvc2l0aXZhIikgJT4lDQogICAgZ3JvdXBfYnkoUGFydGlkbywgUG9saXRpY28pICU+JQ0KICAgIGNvdW50KFBhbGFicmEsIHNvcnQgPSBUKSAlPiUNCiAgICAgc2xpY2VfbWF4KG9yZGVyX2J5ID0gbiwgbj0gMTApICU+JQ0KICAgICAgZmlsdGVyKFBhcnRpZG8gPT0gICJjdWVudGEgcGFydGlkYXJpYSIpICU+JQ0KICAgIGdncGxvdCgpICsNCiAgICBhZXMoUGFsYWJyYSwgbiwgZmlsbCA9IFBvbGl0aWNvKSArDQogICAgZ2VvbV9jb2woKSArDQogICAgZmFjZXRfd3JhcCgiUG9saXRpY28iLCBzY2FsZXMgPSAiZnJlZSIpICsNCiAgICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLCAwKSkgKw0KICAgIGNvb3JkX2ZsaXAoKSArDQogICAgbGFicyh0aXRsZSA9ICJQYWxhYnJhcyBQb3NpdGl2YXMgbcOhcyB1c2FkYXMiKSANCmBgYA0KDQoNCg0KDQo8Y2VudGVyPiA8c3BhbiBzdHlsZT0iY29sb3I6ICMyODJGNDQ7Ij4gPGgzPiAxNi0gUGFsYWJyYXMgbmVnYXRpdmFzIG3DoXMgdXNhZGFzIDwvaDM+IDwvc3Bhbj4gPC9jZW50ZXI+DQoNCg0KQWwgdGVuZXIgdW5hIHB1bnR1YWNpw7NuIGNhZGEgcGFsYWJyYSBvdG9yZ2FkYSBwb3IgZWwgZGljY2lvbmFyaW8gZGUgbMOpeGljbywgdGFtYmnDqW4gcG9kZW1vcyBidXNjYXIgY3VhbGVzIHNvbiBsYXMgcGFsYWJyYXMgbmVnYXRpdmFzIHF1ZSBtw6FzIHVzbyBjYWRhIHVubyBkZSBsb3MgcG9sw610aWNvcy4NCg0KICAtCSpFdml0YXIqLCAqRW1lcmdlbmNpYSogbyAqUHJvYmxlbWEqIHNvbiBsYXMgcGFsYWJyYXMgcXVlIG3DoXMgYXBhcmVjZW4sIGRlbnRybyBkZWwgcHJpbmNpcGFsIHRlbWEgZGUgaGFibGEgcXVlIGVzIGxhIHBhbmRlbWlhLiANCg0KICAtCSpEZXVkYSogZXMgb3RyYSBwYWxhYnJhIG11eSB1dGlsaXphZGEsIHVuIHRlbWEgZGlmw61jaWwgZGUgZXNxdWl2YXIgZXN0ZSBhw7FvLg0KDQoNCg0KYGBge3J9DQogdHVpdHNfdG9rZW5zX2Vtb2Npb25lcyAlPiUNCiAgICBmaWx0ZXIoQ2FsaWZpY2FjaW9uID09ICAiTmVnYXRpdmEiKSAlPiUNCiAgICBncm91cF9ieShQYXJ0aWRvLCBQb2xpdGljbykgJT4lDQogICAgY291bnQoUGFsYWJyYSwgc29ydCA9IFQpICU+JQ0KICAgICBzbGljZV9tYXgob3JkZXJfYnkgPSBuLCBuPSAxMCkgJT4lDQogICAgICBmaWx0ZXIoUGFydGlkbyA9PSAgIlBSTyIpICU+JQ0KICAgIGdncGxvdCgpICsNCiAgICBhZXMoUGFsYWJyYSwgbiwgZmlsbCA9IFBvbGl0aWNvKSArDQogICAgZ2VvbV9jb2woKSArDQogICAgZmFjZXRfd3JhcCgiUG9saXRpY28iLCBzY2FsZXMgPSAiZnJlZSIpICsNCiAgICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLCAwKSkgKw0KICAgIGNvb3JkX2ZsaXAoKSArDQogICAgbGFicyh0aXRsZSA9ICJQYWxhYnJhcyBOZWdhdGl2YXMgbcOhcyB1c2FkYXMiKSANCg0KIHR1aXRzX3Rva2Vuc19lbW9jaW9uZXMgJT4lDQogICAgZmlsdGVyKENhbGlmaWNhY2lvbiA9PSAgIk5lZ2F0aXZhIikgJT4lDQogICAgZ3JvdXBfYnkoUGFydGlkbywgUG9saXRpY28pICU+JQ0KICAgIGNvdW50KFBhbGFicmEsIHNvcnQgPSBUKSAlPiUNCiAgICAgc2xpY2VfbWF4KG9yZGVyX2J5ID0gbiwgbj0gMTApICU+JQ0KICAgICAgZmlsdGVyKFBhcnRpZG8gPT0gICJQZXJvbmlzbW8iKSAlPiUNCiAgICBnZ3Bsb3QoKSArDQogICAgYWVzKFBhbGFicmEsIG4sIGZpbGwgPSBQb2xpdGljbykgKw0KICAgIGdlb21fY29sKCkgKw0KICAgIGZhY2V0X3dyYXAoIlBvbGl0aWNvIiwgc2NhbGVzID0gImZyZWUiKSArDQogICAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCkpICsNCiAgICBjb29yZF9mbGlwKCkgKw0KICAgIGxhYnModGl0bGUgPSAiUGFsYWJyYXMgTmVnYXRpdmFzIG3DoXMgdXNhZGFzIikgDQogDQogIHR1aXRzX3Rva2Vuc19lbW9jaW9uZXMgJT4lDQogICAgZmlsdGVyKENhbGlmaWNhY2lvbiA9PSAgIk5lZ2F0aXZhIikgJT4lDQogICAgZ3JvdXBfYnkoUGFydGlkbywgUG9saXRpY28pICU+JQ0KICAgIGNvdW50KFBhbGFicmEsIHNvcnQgPSBUKSAlPiUNCiAgICAgc2xpY2VfbWF4KG9yZGVyX2J5ID0gbiwgbj0gMTApICU+JQ0KICAgICAgZmlsdGVyKFBhcnRpZG8gPT0gICJvdHJvcyBjYW5kaWRhdG9zIikgJT4lDQogICAgZ2dwbG90KCkgKw0KICAgIGFlcyhQYWxhYnJhLCBuLCBmaWxsID0gUG9saXRpY28pICsNCiAgICBnZW9tX2NvbCgpICsNCiAgICBmYWNldF93cmFwKCJQb2xpdGljbyIsIHNjYWxlcyA9ICJmcmVlIikgKw0KICAgIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsIDApKSArDQogICAgY29vcmRfZmxpcCgpICsNCiAgICBsYWJzKHRpdGxlID0gIlBhbGFicmFzIE5lZ2F0aXZhcyBtw6FzIHVzYWRhcyIpIA0KICANCiAgIHR1aXRzX3Rva2Vuc19lbW9jaW9uZXMgJT4lDQogICAgZmlsdGVyKENhbGlmaWNhY2lvbiA9PSAgIk5lZ2F0aXZhIikgJT4lDQogICAgZ3JvdXBfYnkoUGFydGlkbywgUG9saXRpY28pICU+JQ0KICAgIGNvdW50KFBhbGFicmEsIHNvcnQgPSBUKSAlPiUNCiAgICAgc2xpY2VfbWF4KG9yZGVyX2J5ID0gbiwgbj0gMTApICU+JQ0KICAgICAgZmlsdGVyKFBhcnRpZG8gPT0gICJjdWVudGEgcGFydGlkYXJpYSIpICU+JQ0KICAgIGdncGxvdCgpICsNCiAgICBhZXMoUGFsYWJyYSwgbiwgZmlsbCA9IFBvbGl0aWNvKSArDQogICAgZ2VvbV9jb2woKSArDQogICAgZmFjZXRfd3JhcCgiUG9saXRpY28iLCBzY2FsZXMgPSAiZnJlZSIpICsNCiAgICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLCAwKSkgKw0KICAgIGNvb3JkX2ZsaXAoKSArDQogICAgbGFicyh0aXRsZSA9ICJQYWxhYnJhcyBOZWdhdGl2YXMgbcOhcyB1c2FkYXMiKSANCmBgYA0KDQoNCg0KDQo8Y2VudGVyPiA8c3BhbiBzdHlsZT0iY29sb3I6ICMyODJGNDQ7Ij4gPGgzPiAgMTctIFNlbnRpbWllbnRvcyBlbiBlbCB0d2VldCA8L2gzPiA8L3NwYW4+IDwvY2VudGVyPg0KDQoNClZvbHZpZW5kbyBhIHVzYXIgbGEgcHVudHVhY2nDs24gZGVsIGRpY2Npb25hcmlvIGFmaW5uLCB2b2x2ZW1vcyBhIHVuaXIgbGFzIHBhbGFicmFzIGEgbG9zIHR3ZWV0cyB5IHNhY2Ftb3MgZWwgcHJvbWVkaW8gZGUgcHVudG9zIGRlIHRvZGFzIGxhcyBwYWxhYnJhcywgcGFzYW5kbyBkZWwgdmFsb3IgdW5pdGFyaW8gZGUgcGFsYWJyYSBhIHVuIHZhbG9yIHVuaXRhcmlvIHBvciBjYWRhIHR3ZWV0IHB1YmxpY2Fkby4NCg0KICAtICpMYSBtYXlvcsOtYSBkZSBsb3MgdHdlZXRzIGZ1ZXJvbiBuZXV0cm9zLioNCiAgDQogIC0gKkxvcyBtw6FzIHBvc2l0aXZvcyBlbiBlc3RlIHRyYW5zY3Vyc28gZnVlcm9uIE0uIE1hY3JpLCBBLiBGZXJuYW5kZXogeSBSLiBMYXZhZ25hLioNCiAgDQogIC0gKkxvcyBtw6FzIG5lZ2F0aXZvcyBmdWVyb24gTi4gRGVsIENhw7FvIHkgbGEgY3VlbnRhIG9maWNpYWwgZGVsIFBSTy4qDQoNCg0KYGBge3J9DQpUd2VldHNfREYgPC0NCiAgdHVpdHNfdG9rZW5zX2Vtb2Npb25lcyAlPiUNCiAgZ3JvdXBfYnkoc3RhdHVzX2lkKSAlPiUNCiAgc3VtbWFyaXNlKFB1bnR1YWNpb25fdHdlZXQueCA9IG1lYW4oUHVudHVhY2lvbikpICU+JQ0KICBsZWZ0X2pvaW4oVHdlZXRzX0RGLCAuLCBieSA9ICJzdGF0dXNfaWQiKQ0KDQoNClR3ZWV0c19ERiA8LSAgVHdlZXRzX0RGICU+JQ0KICBtdXRhdGUoUHVudHVhY2lvbl90d2VldC54X2xldHJhID0gaWZlbHNlKGlzLm5hKFB1bnR1YWNpb25fdHdlZXQueCksICJOZXV0cmFsIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKFB1bnR1YWNpb25fdHdlZXQueCA+IDAsICJQb3NpdGl2YSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKFB1bnR1YWNpb25fdHdlZXQueCA9PSAwLCAiTmV1dHJhbCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTmVnYXRpdmEiKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICkNCiAgKSAgICAgIA0KKQ0KDQpUd2VldHNfREYgJT4lDQogIGNvdW50KFBvbGl0aWNvLCBQYXJ0aWRvLCBQdW50dWFjaW9uX3R3ZWV0LnhfbGV0cmEpICU+JQ0KICBncm91cF9ieShQb2xpdGljbykgJT4lDQogIG11dGF0ZShQcm9wb3JjaW9uID0gbiAvIHN1bShuKSkgJT4lDQpnZ3Bsb3QoKSArDQogIGFlcyhQb2xpdGljbywgUHJvcG9yY2lvbiwgZmlsbCA9IFB1bnR1YWNpb25fdHdlZXQueF9sZXRyYSkgKw0KICBnZW9tX2NvbCgpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KCkpICsNCiAgICAgIGZhY2V0X3dyYXAoIlBhcnRpZG8iLCBzY2FsZXMgPSAiZnJlZSIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpDQoNCg0KYGBgDQoNCg0KDQoNCjxjZW50ZXI+IDxzcGFuIHN0eWxlPSJjb2xvcjogIzI4MkY0NDsiPiA8aDM+IDE4LSBTZW50aW1pZW50b3MgZW4gZWwgdHdlZXQgUFJPIHZzIFBlcm9uaXNtbyA8L2gzPiA8L3NwYW4+IDwvY2VudGVyPg0KDQoNClRvbWFtb3MgbG9zIDQgbWllbWJyb3MgcXVlIHlhIGFuYWxpemFtb3MgZGUgY2FkYSB1bm8gZGUgbG9zIHBhcnRpZG9zICooUFJPIHkgVG9kb3MpKiwgeSBsbyB1bmltb3MgZW4gdW4gc29sbyBncsOhZmljbyBwb3IgcGFydGlkbywgdmVtb3MgcXVlIGxhIGRpc3RyaWJ1Y2nDs24gZXMgYWxnbyBwYXJlY2lkbywgc2kgYmllbiBlbCBQZXJvbmlzbW8gdHV2byB1biBwb2NvIG3DoXMgZGUgdHdlZXRzIHBvc2l0aXZvcyB5IG1lbm9zIGRlIHR3ZWV0cyBuZWdhdGl2b3MsIHBlcm8gbm8gYSBuaXZlbGVzIHNpZ25pZmljYXRpdm9zLg0KDQoNCmBgYHtyfQ0KVHdlZXRzX0RGICU+JQ0KICBjb3VudChQYXJ0aWRvLCBQdW50dWFjaW9uX3R3ZWV0LnhfbGV0cmEpICU+JQ0KICBncm91cF9ieShQYXJ0aWRvKSAlPiUNCiAgZmlsdGVyKFBhcnRpZG8gPT0gIlBSTyIgfFBhcnRpZG8gPT0gIlBlcm9uaXNtbyIpJT4lDQogIG11dGF0ZShQcm9wb3JjaW9uID0gbiAvIHN1bShuKSkgJT4lDQpnZ3Bsb3QoKSArDQogIGFlcyhQYXJ0aWRvLCBQcm9wb3JjaW9uLCBmaWxsID0gUHVudHVhY2lvbl90d2VldC54X2xldHJhKSArDQogIGdlb21fY29sKCkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoKSkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikNCmBgYA0KDQoNCg0KDQo8Y2VudGVyPiA8c3BhbiBzdHlsZT0iY29sb3I6ICMyODJGNDQ7Ij4gPGgzPiAgMTktIFNlbnRpbWllbnRvIG1lcyBhIG1lcyA8L2gzPiA8L3NwYW4+IDwvY2VudGVyPg0KDQoNCkxhIGlkZWEgZXMgYW5hbGl6YXIgc2kgaGF5IGZsdWN0dWFjaW9uZXMgZW4gbG8gcXVlIGhhbiBpZG8gdHdpdHRlYW5kbyBlbiBlbCB0cmFuc2N1cnNvIGRlbCB0aWVtcG8geSBzdXMgc2VudGltaWVudG9zLg0KDQogIC0gRW4gZWwgKipQUk8qKiBubyBodWJvIGdyYW5kZXMgY2FtYmlvcywgbG9zIMO6bHRpbW9zIHR3ZWV0cyBkZSBCdWxscmljaCBzb24gbcOhcyBwb3NpdGl2by4NCiAgDQogIC0gRW50cmUgbG9zIG90cm9zIGNhbmRpZGF0b3MgKipOaWNvbGFzIERlbCBDYcOxbyoqIHNpZW1wcmUgZXMgbmVnYXRpdm8sIHBlcm8gdmllbmUgc2llbmRvIG1lbm9zIG5lZ2F0aXZvIHVsdGltYW1lbnRlLg0KICANCiAgLSBFbnRyZSBlbCAqKkZyZW50ZSBkZSBUb2RvcyoqIGhheSBtdWNoYSBmbHVjdHVhY2nDs24sIGVsIFByZXNpZGVudGUgcGFyZWNlIGVzdGFyIGVuIHVuIGNhbWlubyBoYWNpYSBsYSBuZWdhdGl2aWRhZC4NCiAgDQoNCmBgYHtyfQ0KVHdlZXRzX0RGJFB1bnR1YWNpb25fdHdlZXQueCA9IGlmZWxzZShpcy5uYShUd2VldHNfREYkUHVudHVhY2lvbl90d2VldC54KSwgMCwgVHdlZXRzX0RGJFB1bnR1YWNpb25fdHdlZXQueCkNCg0KVHdlZXRzX0RGICU+JQ0KZ3JvdXBfYnkoUG9saXRpY28sIFBhcnRpZG8sIG1lcykgJT4lDQogIGZpbHRlcihQYXJ0aWRvID09ICJQUk8iKSU+JQ0KICBzdW1tYXJpc2Uoc2VudGltaWVudG8gPSBtZWFuKFB1bnR1YWNpb25fdHdlZXQueCkpICU+JQ0KZ2dwbG90KCkgKw0KICBhZXMobWVzLCBzZW50aW1pZW50bywgY29sb3IgPSBQb2xpdGljbykgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBhbHBoYSA9IC4zNSkgKw0KICBnZW9tX2xpbmUoKSArDQogIGZhY2V0X2dyaWQoUG9saXRpY29+LikgKw0KICB0ZW1hMSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCg0KVHdlZXRzX0RGICU+JQ0KZ3JvdXBfYnkoUG9saXRpY28sIFBhcnRpZG8sIG1lcykgJT4lDQogIGZpbHRlcihQYXJ0aWRvID09ICJvdHJvcyBjYW5kaWRhdG9zIiklPiUNCiAgc3VtbWFyaXNlKHNlbnRpbWllbnRvID0gbWVhbihQdW50dWFjaW9uX3R3ZWV0LngpKSAlPiUNCmdncGxvdCgpICsNCiAgYWVzKG1lcywgc2VudGltaWVudG8sIGNvbG9yID0gUG9saXRpY28pICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgYWxwaGEgPSAuMzUpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBmYWNldF9ncmlkKFBvbGl0aWNvfi4pICsNCiAgdGVtYTEgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQoNClR3ZWV0c19ERiAlPiUNCmdyb3VwX2J5KFBvbGl0aWNvLCBQYXJ0aWRvLCBtZXMpICU+JQ0KICBmaWx0ZXIoUGFydGlkbyA9PSAiUGVyb25pc21vIiklPiUNCiAgc3VtbWFyaXNlKHNlbnRpbWllbnRvID0gbWVhbihQdW50dWFjaW9uX3R3ZWV0LngpKSAlPiUNCmdncGxvdCgpICsNCiAgYWVzKG1lcywgc2VudGltaWVudG8sIGNvbG9yID0gUG9saXRpY28pICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgYWxwaGEgPSAuMzUpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBmYWNldF9ncmlkKFBvbGl0aWNvfi4pICsNCiAgdGVtYTEgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQoNClR3ZWV0c19ERiAlPiUNCmdyb3VwX2J5KFBvbGl0aWNvLCBQYXJ0aWRvLCBtZXMpICU+JQ0KICBmaWx0ZXIoUGFydGlkbyA9PSAiY3VlbnRhIHBhcnRpZGFyaWEiKSU+JQ0KICBzdW1tYXJpc2Uoc2VudGltaWVudG8gPSBtZWFuKFB1bnR1YWNpb25fdHdlZXQueCkpICU+JQ0KZ2dwbG90KCkgKw0KICBhZXMobWVzLCBzZW50aW1pZW50bywgY29sb3IgPSBQb2xpdGljbykgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBhbHBoYSA9IC4zNSkgKw0KICBnZW9tX2xpbmUoKSArDQogIGZhY2V0X2dyaWQoUG9saXRpY29+LikgKw0KICB0ZW1hMSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCmBgYA0KDQoNCg0KDQo8Y2VudGVyPiA8c3BhbiBzdHlsZT0iY29sb3I6ICMyODJGNDQ7Ij4gPGgzPiAgMjAtIEJveHBsb3Qgc2VudGltaWVudG9zIDwvaDM+IDwvc3Bhbj4gPC9jZW50ZXI+DQoNCkxhIGRpc3RyaWJ1Y2nDs24gZGUgbG9zIHNlbnRpbWllbnRvcyBlbnRyZSB0b2RvcyBsb3MgdHdlZXRzLCBhcXVlbGxvcyBxdWUgZXN0w6FuIGVuY2VycmFkb3MgZW4gbGFzIGNhamFzIHNvbiBsb3Mgbm9ybWFsZXMsIG1pZW50cmFzIHF1ZSBsb3MgcHVudG9zIHN1ZWx0b3Mgc29uIHR3ZWV0cyBhaXNsYWRvcyBhIGxvIHF1ZSBzdWVsZW4gZXNjcmliaXIuDQoNCiAgLSAqRXNwZXJ0IG5vIHByZXNlbnRhIG5pbmd1biB0aXBvIGRlIHBhdHLDs24gZGUgc2VudGltaWVudG9zKg0KDQoNCmBgYHtyfQ0KVHdlZXRzX0RGICU+JQ0KICBnZ3Bsb3QoKSArDQogIGFlcyhQb2xpdGljbywgUHVudHVhY2lvbl90d2VldC54LCBmaWxsID0gUG9saXRpY28pICsNCiAgZ2VvbV9ib3hwbG90KCkgKw0KICBjb29yZF9mbGlwKCkgKyANCiAgbGFicyh5PSAiU2VudGltaWVudG8iKSArDQogIHRlbWExDQpgYGANCg0KDQoNCg0KPGNlbnRlcj4gPHNwYW4gc3R5bGU9ImNvbG9yOiAjMjgyRjQ0OyI+IDxoMz4gMjEtIENvcnJlbGFjacOzbiBlbnRyZSBsbyB0d2l0dGVhZG8gUFJPIHZzIFBlcm9uaXNtbzwvaDM+IDwvc3Bhbj4gPC9jZW50ZXI+DQoNClNlIGJ1c2NhIGEgdHJhdsOpcyBkZSBsYXMgcGFsYWJyYXMgcXVlIHV0aWxpemFyb24gY3VhbCBlcyBsYSBjb3JyZWxhY2nDs24gcXVlIGhheSBlbnRyZSBsb3MgZGlzdGludG9zIHBvbMOtdGljb3MgeSBzdXMgdHdlZXRzLCB5IHNlIHB1ZWRlbiByZWFsaXphciB2YXJpYXMgb2JzZXJ2YWNpb25lczoNCg0KICAtICpRdWlyw7NzIHkgTGFycmV0YSBzb24gbG9zIGRlIG1heW9yIGNvcnJlbGFjacOzbiwgZGVtb3N0cmFuZG8gdW4gYnVlbiBtYW5lam8gZGUgbGEgY29tdW5pY2FjacOzbiBwb3J0ZcOxYSwgZG9uZGUgYW1ib3Mgc2lndWVuIGVuIG1pc21hIGRpcmVjY2nDs24uKg0KDQogIC0gKk1hY3JpIGVzIGVsIGRlIG1lbm9yIGNvcnJlbGFjacOzbiBjb24gZWwgcmVzdG8gZGUgbG9zIHBhcnRpY2lwYW50ZXMsIHBlcm8gYXPDrSBtaXNtbyB0aWVuZSBsw7NnaWNhIHF1ZSBzdSBtYXlvciBuaXZlbCBkZSByZWxhY2nDs24gbG8gdGVuZ2EgY29uIEJ1bGxyaWNoLioNCg0KICAtICpFbnRyZSBLaWNpbG9mZiB5IEdpbmVzLCBoYXkgdW5hIHJlbGFjacOzbiBpbXBvcnRhbnRlLCBhc8OtIGNvbW8gdGFtYmnDqW4gZGUgZWxsb3MgZG9zIGNvbiBzdXMgc2ltaWxhcmVzIHBvcnRlw7FvcyAoUXVpcsOzcyB5IExhcnJldGEpLioNCg0KICAtICpDcmlzdGluYSBLaXJjaG5lciBlcyBvdHJhIHF1ZSBubyB0aWVuZSB1biBhbHRvIG5pdmVsIGRlIHJlbGFjacOzbiBlbiBzdXMgdHdlZXRzIGNvbiBvdHJvcyBwb2zDrXRpY29zLioNCg0KICAtICpFcyBzb3JwcmVuZGVudGUgcXVlIHVubyBkZSBsb3MgbWF5b3JlcyBuaXZlbGVzIGRlIHJlbGFjacOzbiBlbiBjdWFudG8gbG8gcXVlIHNlIGNvbXVuaWNhIGVzdGUgZW50cmUgQWxiZXJ0byBGZXJuw6FuZGV6IHkgUGF0cmljaWEgQnVsbHJpY2guKg0KDQoNCg0KYGBge3J9DQp0d2VldHNfc3ByZWFkMiA8LSB0dWl0c190b2tlbnMgJT4lIA0KIGZpbHRlcihQYXJ0aWRvID09ICAiUFJPIiB8IFBhcnRpZG8gPT0gIlBlcm9uaXNtbyIpJT4lIA0KICBncm91cF9ieShQb2xpdGljbywgUGFsYWJyYSkgJT4lIA0KICBjb3VudChQYWxhYnJhKSAlPiUNCiAgICAgIHNwcmVhZChrZXkgPSBQb2xpdGljbywgdmFsdWUgPSBuLCBmaWxsID0gTkEsIGRyb3AgPSBUUlVFKQ0KdHdlZXRzX3NwcmVhZDJbaXMubmEodHdlZXRzX3NwcmVhZDIpXSA8LSAwDQoNCm5hbWVzKHR3ZWV0c19zcHJlYWQyKSA8LSBjKCJQYWxhYnJhIiwgIkEuRmVybmFuZGV6IiwgIkEuS2ljaWxsb2YiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkMuS2lyY2huZXIiLCAiRi5RdWlyb3MiLCAiR2luZXMuR0ciLCJILkxhcnJldGEiLCAiTS5NYWNyaSIsICJQLkJ1bGxyaWNoIiApDQoNCm1ldGhvZCA8LSAicGVhcnNvbiINCm1fY29yIDwtIG1hdHJpeChucm93ID0gOCwgbmNvbCA9IDgpDQpmb3IgKGkgaW4gMTpkaW0obV9jb3IpWzFdKSB7DQogICAgICBmb3IgKGogaW4gMTpkaW0obV9jb3IpWzJdKSB7DQogICAgICAgICAgICBmb3JtIDwtIGFzLmZvcm11bGEocGFzdGUoIn4iLCBuYW1lcyh0d2VldHNfc3ByZWFkMilbaSsxXSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIrIiwgbmFtZXModHdlZXRzX3NwcmVhZDIpW2orMV0pKQ0KICAgICAgICAgICAgaWYoaSE9ail7DQogICAgICAgICAgICAgICAgICBtX2NvcltpLGpdIDwtIGNvci50ZXN0KGZvcm0sIG1ldGhvZCA9IG1ldGhvZCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSB0d2VldHNfc3ByZWFkMikkZXN0aW1hdGUNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmKGk9PWope21fY29yW2ksal0gPC0gMX0NCiAgICAgIH0NCn0NCmNvbG5hbWVzKG1fY29yKSA8LSBuYW1lcyh0d2VldHNfc3ByZWFkMilbMjo5XQ0Kcm93bmFtZXMobV9jb3IpIDwtIG5hbWVzKHR3ZWV0c19zcHJlYWQyKVsyOjldDQpjb3JycGxvdChtX2NvciwgbWV0aG9kPSJjb2xvciIsIHR5cGU9InVwcGVyIiwgb3JkZXI9ImhjbHVzdCIsIA0KICAgICAgICAgYWRkQ29lZi5jb2wgPSAiYmxhY2siLCB0bC5jb2w9ImJsYWNrIiwgdGwuc3J0PTQ1LA0KICAgICAgICAgc2lnLmxldmVsID0gMC4wMSwgaW5zaWcgPSAiYmxhbmsiLCBkaWFnPUZBTFNFKQ0KDQpgYGANCg0KDQoNCg0KPGNlbnRlcj4gPHNwYW4gc3R5bGU9ImNvbG9yOiAjMjgyRjQ0OyI+IDxoMz4gMjItIENvcnJlbGFjacOzbiBlbnRyZSBsbyB0d2l0dGVhZG8gY2FuZGlkYXRvcyBhIHByZXNpZGVudGUuIDwvaDM+IDwvc3Bhbj4gPC9jZW50ZXI+DQoNCg0KLQlMYSByZWxhY2nDs24gZW50cmUgbG8gcXVlIGVzY3JpYmVuIGxvcyBjYW5kaWRhdG9zIHRpZW5lIHVuIGNsw7pzdGVyIHF1ZSBzZSBkZXN0YWNhIHNvYnJlIGVsIHJlc3RvIHF1ZSBlcyBsYSByZWxhY2nDs24gZW50cmUgRXNwZXJ0LCBHw7NtZXogQ2VudHVyacOzbiB5IEFsYmVydG8gRmVybsOhbmRlei4NCg0KLQlOaWNvbGFzIERlbCBDYcOxbyB0aWVuZSB1biBhbHRvIG5pdmVsIGRlIHJlbGFjacOzbiBjb24gR8OzbWV6IENlbnR1cmnDs24sIHkgZW4gbWVkaWRhIG1lZGlhbmEgY29uIEFsYmVydG8gRmVybsOhbmRleiB5IEVzcGVydC4NCg0KLQlMYXZhZ25hIHkgTWFjcmkgbm8gcHJlc2VudGFuIHVuYSBncmFuIGNvcnJlbGFjacOzbiBjb24gZWwgcmVzdG8gZGUgbG9zIHBvbMOtdGljb3MuDQoNCg0KYGBge3J9DQp0d2VldHNfc3ByZWFkMiA8LSB0dWl0c190b2tlbnMgJT4lIA0KICBmaWx0ZXIoUGFydGlkbyA9PSAgIm90cm9zIGNhbmRpZGF0b3MiIHwgUG9saXRpY28gPT0gIkEuRmVybmFuZGV6InwgUG9saXRpY28gPT0gIk0uTWFjcmkiKSU+JSANCiAgZ3JvdXBfYnkoUG9saXRpY28sIFBhbGFicmEpICU+JSANCiAgY291bnQoUGFsYWJyYSkgJT4lDQogICAgICBzcHJlYWQoa2V5ID0gUG9saXRpY28sIHZhbHVlID0gbiwgZmlsbCA9IE5BLCBkcm9wID0gVFJVRSkNCnR3ZWV0c19zcHJlYWQyW2lzLm5hKHR3ZWV0c19zcHJlYWQyKV0gPC0gMA0KDQpuYW1lcyh0d2VldHNfc3ByZWFkMikgPC0gYygiUGFsYWJyYSIsICJBLkZlcm5hbmRleiIsICJKLkVzcGVydCIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAiR29tZXpDZW50dXJpb24iLCAiTS5NYWNyaSIsICJOLkRlbENhw7FvIiwiUi5MYXZhZ25hIikNCg0KbWV0aG9kIDwtICJwZWFyc29uIg0KbV9jb3IgPC0gbWF0cml4KG5yb3cgPSA2LCBuY29sID0gNikNCmZvciAoaSBpbiAxOmRpbShtX2NvcilbMV0pIHsNCiAgICAgIGZvciAoaiBpbiAxOmRpbShtX2NvcilbMl0pIHsNCiAgICAgICAgICAgIGZvcm0gPC0gYXMuZm9ybXVsYShwYXN0ZSgifiIsIG5hbWVzKHR3ZWV0c19zcHJlYWQyKVtpKzFdLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIisiLCBuYW1lcyh0d2VldHNfc3ByZWFkMilbaisxXSkpDQogICAgICAgICAgICBpZihpIT1qKXsNCiAgICAgICAgICAgICAgICAgIG1fY29yW2ksal0gPC0gY29yLnRlc3QoZm9ybSwgbWV0aG9kID0gbWV0aG9kLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHR3ZWV0c19zcHJlYWQyKSRlc3RpbWF0ZQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaWYoaT09ail7bV9jb3JbaSxqXSA8LSAxfQ0KICAgICAgfQ0KfQ0KY29sbmFtZXMobV9jb3IpIDwtIG5hbWVzKHR3ZWV0c19zcHJlYWQyKVsyOjddDQpyb3duYW1lcyhtX2NvcikgPC0gbmFtZXModHdlZXRzX3NwcmVhZDIpWzI6N10NCmNvcnJwbG90KG1fY29yLCBtZXRob2Q9ImNvbG9yIiwgdHlwZT0idXBwZXIiLCBvcmRlcj0iaGNsdXN0IiwgDQogICAgICAgICBhZGRDb2VmLmNvbCA9ICJibGFjayIsIHRsLmNvbD0iYmxhY2siLCB0bC5zcnQ9NDUsDQogICAgICAgICBzaWcubGV2ZWwgPSAwLjAxLCBpbnNpZyA9ICJibGFuayIsIGRpYWc9RkFMU0UpDQpgYGANCg0KDQoNCg0KPGNlbnRlcj4gPHNwYW4gc3R5bGU9ImNvbG9yOiAjMjgyRjQ0OyI+IDxoMz4gMjMtIENvcnJlbGFjacOzbiBlbnRyZSBsbyB0d2l0dGVhZG8gZW50cmUgY3VlbnRhcyBwYXJ0aWRhcmlhczwvaDM+IDwvc3Bhbj4gPC9jZW50ZXI+DQoNCg0KRXN0ZSBwdWVkZSBzZXIgdW4gYW7DoWxpc2lzIGludGVyZXNhbnRlLCB5YSBxdWUgbGEgY2FudGlkYWQgZGUgdHdlZXRzIGVzIHNpZ25pZmljYXRpdmEgcGFyYSB0b2Rvcy4NCg0KLQlTb3JwcmVzaXZhbWVudGUgZWwgbcOheGltbyBuaXZlbCBkZSByZWxhY2nDs24gc2UgZGEgZW50cmUgbGEgVUNSIHkgVE9ET1MsIGRvcyBwYXJ0aWRvcyBxdWUgaG95IHNlIHByZXNlbnRhbiBjb21vIG9wdWVzdG8NCg0KLQlUaWVuZSBtYXlvciBsw7NnaWNhIGxhIGFsdGEgcmVsYWNpw7NuIGVudHJlIGVsIFBSTyB5IGxhIFVDUi4NCg0KLQlFbCBHRU4gcGFyZWNpZXJhIHNlciBlbCBwYXJ0aWRvIHF1ZSBlc2NyaWJlIGRlIG1hbmVyYSBtw6FzIGRpc3RpbnRhIGFsIHJlc3RvLg0KDQotCVNpbiBlbWJhcmdvLCBwb2RlbW9zIG5vdGFyIHF1ZSwgYSBkaWZlcmVuY2lhIGRlIGxhcyBjdWVudGFzIGluZGl2aWR1YWxlcywgbGFzIHBhcnRpZGFyaWFzIHRpZW5lbiBtw6FzIHJlbGFjacOzbiwgcG9yIHN1IGxlbmd1YWplIG3DoXMgbmV1dHJvIHkgY29tdW5pY2FjacOzbiBvcmfDoW5pY2EuDQoNCg0KYGBge3J9DQp0d2VldHNfc3ByZWFkMiA8LSB0dWl0c190b2tlbnMgJT4lIA0KICBmaWx0ZXIoUGFydGlkbyA9PSAgImN1ZW50YSBwYXJ0aWRhcmlhIiklPiUgDQogIGdyb3VwX2J5KFBvbGl0aWNvLCBQYWxhYnJhKSAlPiUgDQogIGNvdW50KFBhbGFicmEpICU+JQ0KICAgICAgc3ByZWFkKGtleSA9IFBvbGl0aWNvLCB2YWx1ZSA9IG4sIGZpbGwgPSBOQSwgZHJvcCA9IFRSVUUpDQp0d2VldHNfc3ByZWFkMltpcy5uYSh0d2VldHNfc3ByZWFkMildIDwtIDANCg0KbmFtZXModHdlZXRzX3NwcmVhZDIpIDwtIGMoIlBhbGFicmEiLCAiR0VOIiwgIlBSTyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAiVE9ET1MiLCAiVUNSIikNCg0KbWV0aG9kIDwtICJwZWFyc29uIg0KbV9jb3IgPC0gbWF0cml4KG5yb3cgPSA0LCBuY29sID0gNCkNCmZvciAoaSBpbiAxOmRpbShtX2NvcilbMV0pIHsNCiAgICAgIGZvciAoaiBpbiAxOmRpbShtX2NvcilbMl0pIHsNCiAgICAgICAgICAgIGZvcm0gPC0gYXMuZm9ybXVsYShwYXN0ZSgifiIsIG5hbWVzKHR3ZWV0c19zcHJlYWQyKVtpKzFdLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIisiLCBuYW1lcyh0d2VldHNfc3ByZWFkMilbaisxXSkpDQogICAgICAgICAgICBpZihpIT1qKXsNCiAgICAgICAgICAgICAgICAgIG1fY29yW2ksal0gPC0gY29yLnRlc3QoZm9ybSwgbWV0aG9kID0gbWV0aG9kLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHR3ZWV0c19zcHJlYWQyKSRlc3RpbWF0ZQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaWYoaT09ail7bV9jb3JbaSxqXSA8LSAxfQ0KICAgICAgfQ0KfQ0KY29sbmFtZXMobV9jb3IpIDwtIG5hbWVzKHR3ZWV0c19zcHJlYWQyKVsyOjVdDQpyb3duYW1lcyhtX2NvcikgPC0gbmFtZXModHdlZXRzX3NwcmVhZDIpWzI6NV0NCmNvcnJwbG90KG1fY29yLCBtZXRob2Q9ImNvbG9yIiwgdHlwZT0idXBwZXIiLCBvcmRlcj0iaGNsdXN0IiwgDQogICAgICAgICBhZGRDb2VmLmNvbCA9ICJibGFjayIsIHRsLmNvbD0iYmxhY2siLCB0bC5zcnQ9NDUsDQogICAgICAgICBzaWcubGV2ZWwgPSAwLjAxLCBpbnNpZyA9ICJibGFuayIsIGRpYWc9RkFMU0UpDQpgYGANCg0KDQoNCg0KDQo8Y2VudGVyPiA8c3BhbiBzdHlsZT0iY29sb3I6ICMyODJGNDQ7Ij4gPGgzPiAyNC0gQ29tcGFyYWNpw7NuIGRlIHVzbyBkZSBwYWxhYnJhcyBNYWNyaSB2cyBGZXJuYW5kZXogPC9oMz4gPC9zcGFuPiA8L2NlbnRlcj4NCg0KDQpMYSBpZGVhIGRlIGVzdGUgZ3LDoWZpY28gZXMgZGUgbW9zdHJhciBjdWFsZXMgc29uIGxhcyBwYWxhYnJhcyBtw6FzIGRpZmVyZW5jaWFzIGVuIHN1IHVzbywgZW4gZXN0ZSBjYXNvIGVudHJlICpNYXVyaWNpbyBNYWNyaSogeSAqQWxiZXJ0byBGZXJuw6FuZGV6Kg0KDQoNCmBgYHtyfQ0KDQojIFBpdm90YWplIHkgZGVzcGl2b3RhamUNCnR3ZWV0c191bnBpdm90IDwtIHR1aXRzX3Rva2VucyAlPiUgZ3JvdXBfYnkoUG9saXRpY28sIFBhbGFicmEpICU+JQ0KICAgICAgY291bnQoUGFsYWJyYSkgJT4lDQogICAgICBzcHJlYWQoa2V5ID0gUG9saXRpY28sIHZhbHVlID0gbiwgZmlsbCA9IDAsIGRyb3AgPSBUUlVFKSAlPiUgDQogICAgICBnYXRoZXIoa2V5ID0gIlBvbGl0aWNvIiwgdmFsdWUgPSAibiIsIC1QYWxhYnJhKQ0KDQoNCiAgICAgICAgICAgICAgICAgICMgU2VsZWNjacOzbiBkZSBsb3MgYXV0b3Jlcw0KICAgICAgICAgICAgICAgICAgdHdlZXRzX3VucGl2b3QyIDwtIHR3ZWV0c191bnBpdm90ICU+JSANCiAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihQb2xpdGljbyAlaW4lIGMoIk0uTWFjcmkiLCAiQS5GZXJuYW5kZXoiKSkNCiAgICAgICAgICAgICAgICAgICMgU2UgYcOxYWRlIGVsIHRvdGFsIGRlIHBhbGFicmFzIGRlIGNhZGEgYXV0b3INCiAgICAgICAgICAgICAgICAgIHR3ZWV0c191bnBpdm90MiA8LSB0d2VldHNfdW5waXZvdDIgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICBsZWZ0X2pvaW4oVHdlZXRzX0RGICU+JSBncm91cF9ieShQb2xpdGljbykgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VtbWFyaXNlKE4gPSBuKCkpLCBieSA9ICJQb2xpdGljbyIpDQogICAgICAgICAgICAgICAgICAjIEPDoWxjdWxvIGRlIG9kZHMgeSBsb2cgb2Ygb2RkcyBkZSBjYWRhIHBhbGFicmENCiAgICAgICAgICAgICAgICAgIHR3ZWV0c19sb2dPZGRzIDwtIHR3ZWV0c191bnBpdm90MiAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUob2RkcyA9IChuICsgMSkgLyAoTiArIDEpKSAlPiUNCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdChQb2xpdGljbywgUGFsYWJyYSwgb2RkcykgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgc3ByZWFkKGtleSA9IFBvbGl0aWNvLCB2YWx1ZSA9IG9kZHMpDQogICAgICAgICAgICAgICAgICB0d2VldHNfbG9nT2Rkc1ssNF0gPC0gbG9nKHR3ZWV0c19sb2dPZGRzWywyXS90d2VldHNfbG9nT2Rkc1ssM10pDQogICAgICAgICAgICAgICAgICBuYW1lcyh0d2VldHNfbG9nT2RkcylbNF0gPC0gImxvZ19vZGRzIg0KICAgICAgICAgICAgICAgICAgdHdlZXRzX2xvZ09kZHNbLDVdIDwtIGFicyh0d2VldHNfbG9nT2RkcyRsb2dfb2RkcykNCiAgICAgICAgICAgICAgICAgIG5hbWVzKHR3ZWV0c19sb2dPZGRzKVs1XSA8LSAiYWJzX2xvZ19vZGRzIg0KICAgICAgICAgICAgICAgICAgdHdlZXRzX2xvZ09kZHMgPC0gdHdlZXRzX2xvZ09kZHMgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUoYXV0b3JfZnJlY3VlbnRlID0gaWZfZWxzZShsb2dfb2RkcyA+IDAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcyh0d2VldHNfbG9nT2RkcylbMl0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcyh0d2VldHNfbG9nT2RkcylbM10pKQ0KDQpEaWZlcmVuY2lhX0FGIDwtIHR3ZWV0c19sb2dPZGRzICU+JSANCiAgYXJyYW5nZSgtYWJzX2xvZ19vZGRzLCBieWdyb3VwID0gRkFMU0UpJT4lIA0KICBmaWx0ZXIoYXV0b3JfZnJlY3VlbnRlID09ICJBLkZlcm5hbmRleiIpJT4lIA0KICBoZWFkKDE1KQ0KDQpEaWZlcmVuY2lhX01NIDwtIHR3ZWV0c19sb2dPZGRzICU+JSANCiAgYXJyYW5nZShsb2dfb2RkcywgYnlncm91cCA9IEZBTFNFKSU+JSANCiAgZmlsdGVyKGF1dG9yX2ZyZWN1ZW50ZSA9PSAiTS5NYWNyaSIpJT4lIA0KICBoZWFkKDE1KQ0KDQpEaWZlcmVuY2lhX0FGX01NIDwtIHJiaW5kKERpZmVyZW5jaWFfQUYsRGlmZXJlbmNpYV9NTSkNCg0KRGlmZXJlbmNpYV9BRl9NTSU+JSANCiAgICBnZ3Bsb3QoYWVzKHggPSByZW9yZGVyKFBhbGFicmEsIGxvZ19vZGRzKSwgeT0gbG9nX29kZHMsIGZpbGwgPSBhdXRvcl9mcmVjdWVudGUpKSArDQogICAgZ2VvbV9jb2woKSArDQogICAgbGFicyh4ID0gIi1wYWxhYnJhIiwgeSA9ICJVc28iLCB0aXRsZSA9ICJGZXJuYW5kZXogdnMgTWFjcmkiKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIHRlbWEyDQoNCmBgYA0KDQoNCg0KDQo8Y2VudGVyPiA8c3BhbiBzdHlsZT0iY29sb3I6ICMyODJGNDQ7Ij4gPGgzPiAyNS0gQ29tcGFyYWNpw7NuIGRlIHVzbyBkZSBwYWxhYnJhcyBMYXJyZXRhIHZzIEtpY2lsbG9mIDwvaDM+IDwvc3Bhbj4gPC9jZW50ZXI+DQoNCg0KTGEgaWRlYSBkZSBlc3RlIGdyw6FmaWNvIGVzIGRlIG1vc3RyYXIgY3VhbGVzIHNvbiBsYXMgcGFsYWJyYXMgbcOhcyBkaWZlcmVuY2lhcyBlbiBzdSB1c28sIGVuIGVzdGUgY2FzbyBlbnRyZSAqSG9yYWNpbyBMYXJyZXRhKiB5ICpBeGVsIEtpY2lsbG9mKg0KDQoNCg0KYGBge3J9DQoNCg0KIyBQaXZvdGFqZSB5IGRlc3Bpdm90YWplDQp0d2VldHNfdW5waXZvdCA8LSB0dWl0c190b2tlbnMgJT4lIGdyb3VwX2J5KFBvbGl0aWNvLCBQYWxhYnJhKSAlPiUNCiAgICAgIGNvdW50KFBhbGFicmEpICU+JQ0KICAgICAgc3ByZWFkKGtleSA9IFBvbGl0aWNvLCB2YWx1ZSA9IG4sIGZpbGwgPSAwLCBkcm9wID0gVFJVRSkgJT4lIA0KICAgICAgZ2F0aGVyKGtleSA9ICJQb2xpdGljbyIsIHZhbHVlID0gIm4iLCAtUGFsYWJyYSkNCg0KDQogICAgICAgICAgICAgICAgICAjIFNlbGVjY2nDs24gZGUgbG9zIGF1dG9yZXMNCiAgICAgICAgICAgICAgICAgIHR3ZWV0c191bnBpdm90MiA8LSB0d2VldHNfdW5waXZvdCAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoUG9saXRpY28gJWluJSBjKCJILkxhcnJldGEiLCAiQS5LaWNpbGxvZiIpKQ0KICAgICAgICAgICAgICAgICAgIyBTZSBhw7FhZGUgZWwgdG90YWwgZGUgcGFsYWJyYXMgZGUgY2FkYSBhdXRvcg0KICAgICAgICAgICAgICAgICAgdHdlZXRzX3VucGl2b3QyIDwtIHR3ZWV0c191bnBpdm90MiAlPiUNCiAgICAgICAgICAgICAgICAgICAgICAgIGxlZnRfam9pbihUd2VldHNfREYgJT4lIGdyb3VwX2J5KFBvbGl0aWNvKSAlPiUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW1tYXJpc2UoTiA9IG4oKSksIGJ5ID0gIlBvbGl0aWNvIikNCiAgICAgICAgICAgICAgICAgICMgQ8OhbGN1bG8gZGUgb2RkcyB5IGxvZyBvZiBvZGRzIGRlIGNhZGEgcGFsYWJyYQ0KICAgICAgICAgICAgICAgICAgdHdlZXRzX2xvZ09kZHMgPC0gdHdlZXRzX3VucGl2b3QyICU+JSANCiAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZShvZGRzID0gKG4gKyAxKSAvIChOICsgMSkpICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0KFBvbGl0aWNvLCBQYWxhYnJhLCBvZGRzKSAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICBzcHJlYWQoa2V5ID0gUG9saXRpY28sIHZhbHVlID0gb2RkcykgDQogICAgICAgICAgICAgICAgICB0d2VldHNfbG9nT2Rkc1ssNF0gPC0gbG9nKHR3ZWV0c19sb2dPZGRzWywyXS90d2VldHNfbG9nT2Rkc1ssM10pDQogICAgICAgICAgICAgICAgICBuYW1lcyh0d2VldHNfbG9nT2RkcylbNF0gPC0gImxvZ19vZGRzIg0KICAgICAgICAgICAgICAgICAgdHdlZXRzX2xvZ09kZHNbLDVdIDwtIGFicyh0d2VldHNfbG9nT2RkcyRsb2dfb2RkcykNCiAgICAgICAgICAgICAgICAgIG5hbWVzKHR3ZWV0c19sb2dPZGRzKVs1XSA8LSAiYWJzX2xvZ19vZGRzIg0KICAgICAgICAgICAgICAgICAgdHdlZXRzX2xvZ09kZHMgPC0gdHdlZXRzX2xvZ09kZHMgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUoYXV0b3JfZnJlY3VlbnRlID0gaWZfZWxzZShsb2dfb2RkcyA+IDAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcyh0d2VldHNfbG9nT2RkcylbMl0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcyh0d2VldHNfbG9nT2RkcylbM10pKQ0KDQpEaWZlcmVuY2lhX0FLIDwtIHR3ZWV0c19sb2dPZGRzICU+JSANCiAgYXJyYW5nZSgtbG9nX29kZHMsIGJ5Z3JvdXAgPSBGQUxTRSklPiUgDQogIGZpbHRlcihhdXRvcl9mcmVjdWVudGUgPT0gIkEuS2ljaWxsb2YiKSU+JSANCiAgaGVhZCgxNSkNCg0KRGlmZXJlbmNpYV9ITCA8LSB0d2VldHNfbG9nT2RkcyAlPiUgDQogIGFycmFuZ2UoYWJzX2xvZ19vZGRzLCBieWdyb3VwID0gRkFMU0UpJT4lIA0KICBmaWx0ZXIoYXV0b3JfZnJlY3VlbnRlID09ICJILkxhcnJldGEiKSU+JSANCiAgdGFpbCgxNSkNCg0KRGlmZXJlbmNpYV9BS19ITCA8LSByYmluZChEaWZlcmVuY2lhX0FLLERpZmVyZW5jaWFfSEwpDQoNCkRpZmVyZW5jaWFfQUtfSEwlPiUgDQogICAgZ2dwbG90KGFlcyh4ID0gcmVvcmRlcihQYWxhYnJhLCBsb2dfb2RkcyksIHk9IGxvZ19vZGRzLCBmaWxsID0gYXV0b3JfZnJlY3VlbnRlKSkgKw0KICAgIGdlb21fY29sKCkgKw0KICAgIGxhYnMoeCA9ICItcGFsYWJyYSIsIHkgPSAiVXNvIiwgdGl0bGUgPSAiS2ljaWxsb2YgdnMgTGFycmV0YSIpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgdGVtYTINCg0KYGBgDQoNCg0KDQoNCjxjZW50ZXI+IDxzcGFuIHN0eWxlPSJjb2xvcjogIzI4MkY0NDsiPiA8aDM+IDI2LSBDb21wYXJhY2nDs24gZGUgdXNvIGRlIHBhbGFicmFzIEdpbmVzIHZzIFF1aXLDs3MgPC9oMz4gPC9zcGFuPiA8L2NlbnRlcj4NCg0KDQpMYSBpZGVhIGRlIGVzdGUgZ3LDoWZpY28gZXMgZGUgbW9zdHJhciBjdWFsZXMgc29uIGxhcyBwYWxhYnJhcyBtw6FzIGRpZmVyZW5jaWFzIGVuIHN1IHVzbywgZW4gZXN0ZSBjYXNvIGVudHJlICpHaW5lcyBHb256YWxleiogeSAqRmVybsOhbiBRdWlyw7NzKg0KDQoNCmBgYHtyfQ0KdHdlZXRzX3VucGl2b3QgPC0gdHVpdHNfdG9rZW5zICU+JSBncm91cF9ieShQb2xpdGljbywgUGFsYWJyYSkgJT4lDQogICAgICBjb3VudChQYWxhYnJhKSAlPiUNCiAgICAgIHNwcmVhZChrZXkgPSBQb2xpdGljbywgdmFsdWUgPSBuLCBmaWxsID0gMCwgZHJvcCA9IFRSVUUpICU+JSANCiAgICAgIGdhdGhlcihrZXkgPSAiUG9saXRpY28iLCB2YWx1ZSA9ICJuIiwgLVBhbGFicmEpDQoNCg0KICAgICAgICAgICAgICAgICAgIyBTZWxlY2Npw7NuIGRlIGxvcyBhdXRvcmVzDQogICAgICAgICAgICAgICAgICB0d2VldHNfdW5waXZvdDIgPC0gdHdlZXRzX3VucGl2b3QgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKFBvbGl0aWNvICVpbiUgYygiR2luZXMuR0ciLCAiRi5RdWlyb3MiKSkNCiAgICAgICAgICAgICAgICAgICMgU2UgYcOxYWRlIGVsIHRvdGFsIGRlIHBhbGFicmFzIGRlIGNhZGEgYXV0b3INCiAgICAgICAgICAgICAgICAgIHR3ZWV0c191bnBpdm90MiA8LSB0d2VldHNfdW5waXZvdDIgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICBsZWZ0X2pvaW4oVHdlZXRzX0RGICU+JSBncm91cF9ieShQb2xpdGljbykgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VtbWFyaXNlKE4gPSBuKCkpLCBieSA9ICJQb2xpdGljbyIpDQogICAgICAgICAgICAgICAgICAjIEPDoWxjdWxvIGRlIG9kZHMgeSBsb2cgb2Ygb2RkcyBkZSBjYWRhIHBhbGFicmENCiAgICAgICAgICAgICAgICAgIHR3ZWV0c19sb2dPZGRzIDwtIHR3ZWV0c191bnBpdm90MiAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUob2RkcyA9IChuICsgMSkgLyAoTiArIDEpKSAlPiUNCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdChQb2xpdGljbywgUGFsYWJyYSwgb2RkcykgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgc3ByZWFkKGtleSA9IFBvbGl0aWNvLCB2YWx1ZSA9IG9kZHMpIA0KICAgICAgICAgICAgICAgICAgdHdlZXRzX2xvZ09kZHNbLDRdIDwtIGxvZyh0d2VldHNfbG9nT2Rkc1ssMl0vdHdlZXRzX2xvZ09kZHNbLDNdKQ0KICAgICAgICAgICAgICAgICAgbmFtZXModHdlZXRzX2xvZ09kZHMpWzRdIDwtICJsb2dfb2RkcyINCiAgICAgICAgICAgICAgICAgIHR3ZWV0c19sb2dPZGRzWyw1XSA8LSBhYnModHdlZXRzX2xvZ09kZHMkbG9nX29kZHMpDQogICAgICAgICAgICAgICAgICBuYW1lcyh0d2VldHNfbG9nT2RkcylbNV0gPC0gImFic19sb2dfb2RkcyINCiAgICAgICAgICAgICAgICAgIHR3ZWV0c19sb2dPZGRzIDwtIHR3ZWV0c19sb2dPZGRzICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKGF1dG9yX2ZyZWN1ZW50ZSA9IGlmX2Vsc2UobG9nX29kZHMgPiAwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXModHdlZXRzX2xvZ09kZHMpWzJdLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXModHdlZXRzX2xvZ09kZHMpWzNdKSkNCg0KRGlmZXJlbmNpYV9HRyA8LSB0d2VldHNfbG9nT2RkcyAlPiUgDQogIGFycmFuZ2UoLWxvZ19vZGRzLCBieWdyb3VwID0gRkFMU0UpJT4lIA0KICBmaWx0ZXIoYXV0b3JfZnJlY3VlbnRlID09ICJHaW5lcy5HRyIpJT4lIA0KICB0YWlsKDE1KQ0KDQpEaWZlcmVuY2lhX0ZRIDwtIHR3ZWV0c19sb2dPZGRzICU+JSANCiAgYXJyYW5nZSgtYWJzX2xvZ19vZGRzLCBieWdyb3VwID0gRkFMU0UpJT4lIA0KICBmaWx0ZXIoYXV0b3JfZnJlY3VlbnRlID09ICJGLlF1aXJvcyIpJT4lIA0KICBoZWFkKDE1KQ0KDQpEaWZlcmVuY2lhX0dHX0ZRIDwtIHJiaW5kKERpZmVyZW5jaWFfR0csRGlmZXJlbmNpYV9GUSkNCg0KRGlmZXJlbmNpYV9HR19GUSU+JSANCiAgICBnZ3Bsb3QoYWVzKHggPSByZW9yZGVyKFBhbGFicmEsIGxvZ19vZGRzKSwgeT0gbG9nX29kZHMsIGZpbGwgPSBhdXRvcl9mcmVjdWVudGUpKSArDQogICAgZ2VvbV9jb2woKSArDQogICAgbGFicyh4ID0gIi1wYWxhYnJhIiwgeSA9ICJVc28iLCB0aXRsZSA9ICJRdWlyw7NzIHZzIEdpbmVzIikgKw0KICBjb29yZF9mbGlwKCkgKw0KICB0ZW1hMg0KYGBgDQoNCg0KDQoNCjxjZW50ZXI+IDxzcGFuIHN0eWxlPSJjb2xvcjogIzI4MkY0NDsiPiA8aDM+IDI3LSBDb21wYXJhY2nDs24gZGUgdXNvIGRlIHBhbGFicmFzIEJ1bGxyaWNoIHZzIENyaXN0aW5hIDwvaDM+IDwvc3Bhbj4gPC9jZW50ZXI+DQoNCg0KTGEgaWRlYSBkZSBlc3RlIGdyw6FmaWNvIGVzIGRlIG1vc3RyYXIgY3VhbGVzIHNvbiBsYXMgcGFsYWJyYXMgbcOhcyBkaWZlcmVuY2lhcyBlbiBzdSB1c28sIGVuIGVzdGUgY2FzbyBlbnRyZSAqQ3Jpc3RpbmEgS2lyY2huZXIqIHkgKlBhdHJpY2lhIEJ1bGxyaWNoKg0KDQoNCmBgYHtyfQ0KdHdlZXRzX3VucGl2b3QgPC0gdHVpdHNfdG9rZW5zICU+JSBncm91cF9ieShQb2xpdGljbywgUGFsYWJyYSkgJT4lDQogICAgICBjb3VudChQYWxhYnJhKSAlPiUNCiAgICAgIHNwcmVhZChrZXkgPSBQb2xpdGljbywgdmFsdWUgPSBuLCBmaWxsID0gMCwgZHJvcCA9IFRSVUUpICU+JSANCiAgICAgIGdhdGhlcihrZXkgPSAiUG9saXRpY28iLCB2YWx1ZSA9ICJuIiwgLVBhbGFicmEpDQoNCg0KICAgICAgICAgICAgICAgICAgIyBTZWxlY2Npw7NuIGRlIGxvcyBhdXRvcmVzDQogICAgICAgICAgICAgICAgICB0d2VldHNfdW5waXZvdDIgPC0gdHdlZXRzX3VucGl2b3QgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKFBvbGl0aWNvICVpbiUgYygiUC5CdWxscmljaCIsICJDLktpcmNobmVyIikpDQogICAgICAgICAgICAgICAgICAjIFNlIGHDsWFkZSBlbCB0b3RhbCBkZSBwYWxhYnJhcyBkZSBjYWRhIGF1dG9yDQogICAgICAgICAgICAgICAgICB0d2VldHNfdW5waXZvdDIgPC0gdHdlZXRzX3VucGl2b3QyICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgbGVmdF9qb2luKFR3ZWV0c19ERiAlPiUgZ3JvdXBfYnkoUG9saXRpY28pICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1bW1hcmlzZShOID0gbigpKSwgYnkgPSAiUG9saXRpY28iKQ0KICAgICAgICAgICAgICAgICAgIyBDw6FsY3VsbyBkZSBvZGRzIHkgbG9nIG9mIG9kZHMgZGUgY2FkYSBwYWxhYnJhDQogICAgICAgICAgICAgICAgICB0d2VldHNfbG9nT2RkcyA8LSB0d2VldHNfdW5waXZvdDIgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKG9kZHMgPSAobiArIDEpIC8gKE4gKyAxKSkgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3QoUG9saXRpY28sIFBhbGFicmEsIG9kZHMpICU+JSANCiAgICAgICAgICAgICAgICAgICAgICAgIHNwcmVhZChrZXkgPSBQb2xpdGljbywgdmFsdWUgPSBvZGRzKSANCiAgICAgICAgICAgICAgICAgIHR3ZWV0c19sb2dPZGRzWyw0XSA8LSBsb2codHdlZXRzX2xvZ09kZHNbLDJdL3R3ZWV0c19sb2dPZGRzWywzXSkNCiAgICAgICAgICAgICAgICAgIG5hbWVzKHR3ZWV0c19sb2dPZGRzKVs0XSA8LSAibG9nX29kZHMiDQogICAgICAgICAgICAgICAgICB0d2VldHNfbG9nT2Rkc1ssNV0gPC0gYWJzKHR3ZWV0c19sb2dPZGRzJGxvZ19vZGRzKQ0KICAgICAgICAgICAgICAgICAgbmFtZXModHdlZXRzX2xvZ09kZHMpWzVdIDwtICJhYnNfbG9nX29kZHMiDQogICAgICAgICAgICAgICAgICB0d2VldHNfbG9nT2RkcyA8LSB0d2VldHNfbG9nT2RkcyAlPiUNCiAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZShhdXRvcl9mcmVjdWVudGUgPSBpZl9lbHNlKGxvZ19vZGRzID4gMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzKHR3ZWV0c19sb2dPZGRzKVsyXSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzKHR3ZWV0c19sb2dPZGRzKVszXSkpDQoNCkRpZmVyZW5jaWFfUEIgPC0gdHdlZXRzX2xvZ09kZHMgJT4lIA0KICBhcnJhbmdlKC1sb2dfb2RkcywgYnlncm91cCA9IEZBTFNFKSU+JSANCiAgZmlsdGVyKGF1dG9yX2ZyZWN1ZW50ZSA9PSAiUC5CdWxscmljaCIpJT4lIA0KICB0YWlsKDE1KQ0KDQpEaWZlcmVuY2lhX0NGSyA8LSB0d2VldHNfbG9nT2RkcyAlPiUgDQogIGFycmFuZ2UoLWFic19sb2dfb2RkcywgYnlncm91cCA9IEZBTFNFKSU+JSANCiAgZmlsdGVyKGF1dG9yX2ZyZWN1ZW50ZSA9PSAiQy5LaXJjaG5lciIpJT4lIA0KICBoZWFkKDE1KQ0KDQpEaWZlcmVuY2lhX1BCX0NGSyA8LSByYmluZChEaWZlcmVuY2lhX1BCLERpZmVyZW5jaWFfQ0ZLKQ0KDQpEaWZlcmVuY2lhX1BCX0NGSyU+JSANCiAgICBnZ3Bsb3QoYWVzKHggPSByZW9yZGVyKFBhbGFicmEsIGxvZ19vZGRzKSwgeT0gbG9nX29kZHMsIGZpbGwgPSBhdXRvcl9mcmVjdWVudGUpKSArDQogICAgZ2VvbV9jb2woKSArDQogICAgbGFicyh4ID0gIi1wYWxhYnJhIiwgeSA9ICJVc28iLCB0aXRsZSA9ICJDcmlzdGluYSB2cyBCdWxscmljaCIpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgdGVtYTINCmBgYA0KDQoNCg0KDQo8Y2VudGVyPiA8c3BhbiBzdHlsZT0iY29sb3I6ICMyODJGNDQ7Ij4gPGgzPiAgMjgtIEVtb2Npb25lcyBlbiBsb3MgdHdlZXRzIDwvaDM+IDwvc3Bhbj4gPC9jZW50ZXI+DQoNCkFob3JhIGFuYWxpemFtb3MgdW4gY2FtcG8gbcOhcyBhbXBsaW8gZGUgZW1vY2lvbmVzIHF1ZSBmdWVyb24gdXNhZG8gcG9yIGxvcyBkaXN0aW50b3MgcG9sw610aWNvcyBlbnRyZSB0b2RvcyBsb3MgdHdlZXRzIHF1ZSBoYW4gaWRvIHB1YmxpY2FuZG8gZW4gZXN0ZSBwZXJpb2RvLg0KDQogIC0JRW50cmUgbG9zIG1pZW1icm9zIGRlbCAqKlBSTyoqIHkgZWwgKipQZXJvbmlzbW8qKiBzZSBkZXN0YWNhIGxhICpjb25maWFuemEqIGNvbW8gcHJpbmNpcGFsIHNlbnRpbWllbnRvIGV4cHVlc3RvDQoNCiAgLQlFbiBjdWVudGFzIGNvbW8gbGEgZGUgKipFc3BlcnQqKiBvICoqRGVsIENhw7FvKiogbG8gcXVlIG3DoXMgbXVlc3RyYW4gc3VzIHR3ZWV0cyBlcyBlbCAqbWllZG8qLg0KDQogIC0JTGFzIGN1ZW50YXMgZGVsICoqUFJPKiogeSAqKlBlcm9uaXNtbyoqLCBwcmluY2lwYWxtZW50ZSBwb3IgbG9zIG1pbmlzdHJvcyB5IGplZmVzIGRlIGdvYmllcm5vcyBidXNjYW4gdW4gc2VudGltaWVudG8gZGUgKmFudGljaXBhY2nDs24qDQoNCiAgLQlPdHJhcyBjdWVudGFzIHNvbiBtYXlvcmVzIGVsIHRvbm8gZGUgKmFuZ3VzdGlhKiBzb2JyZSBlbCB0aWVtcG8uDQoNCiAgLQlMYSAqdHJpc3RlemEqIGVzIHVuIHNlbnRpbWllbnRvIGdlbmVyYWwgcXVlIGVzdMOhIGluY29ycG9yYWRvIGVuIHRvZG9zIGxvcyB0d2VldHMsIHkgc2UgZW50aWVuZGUgcG9yIGxhIHNpdHVhY2nDs24gY29tcGxlamEgcXVlIHNpZ25pZmljYSB1bmEgcGFuZGVtaWEuDQoNCg0KYGBge3J9DQpUZXh0U2VudGltZW50IDwtIGdldF9ucmNfc2VudGltZW50KFR3ZWV0c19ERiR0ZXh0KQ0KbmFtZXMoVGV4dFNlbnRpbWVudCkgPC0gYyAoIkFuZ3VzdGlhIiwgIkFudGljaXBhY2lvbiIsICJEaXNndXN0byIsICJNaWVkbyIsICJBbGVncmlhIiwgIlRyaXN0ZXphIiwgIlNvcnByZXNhIiwgIkNvbmZpYW56YSIsICJOZWdhdGl2byIsICJQb3NpdGl2byIgKQ0KDQpUd2VldHNfREZfc2VudGltaWVudG8gPC0gY2JpbmQoVHdlZXRzX0RGLCBUZXh0U2VudGltZW50KQ0KDQoNCmdhdGhlcihUd2VldHNfREZfc2VudGltaWVudG8sICJzZW50aW1lbnQiLCAidmFsdWVzIiwgMTAzOjExMikgJT4lDQogIGdyb3VwX2J5KFBvbGl0aWNvLCBQYXJ0aWRvLCBzZW50aW1lbnQpICU+JQ0KICBmaWx0ZXIoUGFydGlkbyA9PSAgImN1ZW50YSBwYXJ0aWRhcmlhIiklPiUNCiAgZmlsdGVyKHNlbnRpbWVudCAhPSAiUG9zaXRpdm8iICYgc2VudGltZW50ICE9Ik5lZ2F0aXZvIiklPiUNCiAgICBzdW1tYXJpc2UoVG90YWwgPSBzdW0odmFsdWVzKSkgJT4lDQogICAgICBtdXRhdGUoUHJvcG9yY2lvbiA9IFRvdGFsIC8gc3VtKFRvdGFsKSkgJT4lDQpnZ3Bsb3QoKSArDQogIGFlcyhQb2xpdGljbywgUHJvcG9yY2lvbiwgZmlsbCA9IHNlbnRpbWVudCkgKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJzdGFjayIsIGNvbG9yID0gImJsYWNrIikgKw0KICBjb29yZF9mbGlwKCkgICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwwKSkgKw0KICBsYWJzKHkgPSAiUGFsYWJyYXMiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQpnYXRoZXIoVHdlZXRzX0RGX3NlbnRpbWllbnRvLCAic2VudGltZW50IiwgInZhbHVlcyIsIDEwMzoxMTIpICU+JQ0KICBncm91cF9ieShQb2xpdGljbywgUGFydGlkbywgc2VudGltZW50KSAlPiUNCiAgZmlsdGVyKFBhcnRpZG8gPT0gICJQUk8iKSU+JQ0KICBmaWx0ZXIoc2VudGltZW50ICE9ICJQb3NpdGl2byIgJiBzZW50aW1lbnQgIT0iTmVnYXRpdm8iKSU+JQ0KICAgIHN1bW1hcmlzZShUb3RhbCA9IHN1bSh2YWx1ZXMpKSAlPiUNCiAgICAgIG11dGF0ZShQcm9wb3JjaW9uID0gVG90YWwgLyBzdW0oVG90YWwpKSAlPiUNCmdncGxvdCgpICsNCiAgYWVzKFBvbGl0aWNvLCBQcm9wb3JjaW9uLCBmaWxsID0gc2VudGltZW50KSArDQogIGdlb21fY29sKHBvc2l0aW9uID0gInN0YWNrIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGNvb3JkX2ZsaXAoKSAgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLDApKSArDQogIGxhYnMoeSA9ICJQYWxhYnJhcyIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmdhdGhlcihUd2VldHNfREZfc2VudGltaWVudG8sICJzZW50aW1lbnQiLCAidmFsdWVzIiwgMTAzOjExMikgJT4lDQogIGdyb3VwX2J5KFBvbGl0aWNvLCBQYXJ0aWRvLCBzZW50aW1lbnQpICU+JQ0KICBmaWx0ZXIoUGFydGlkbyA9PSAgIlBlcm9uaXNtbyIpJT4lDQogIGZpbHRlcihzZW50aW1lbnQgIT0gIlBvc2l0aXZvIiAmIHNlbnRpbWVudCAhPSJOZWdhdGl2byIpJT4lDQogICAgc3VtbWFyaXNlKFRvdGFsID0gc3VtKHZhbHVlcykpICU+JQ0KICAgICAgbXV0YXRlKFByb3BvcmNpb24gPSBUb3RhbCAvIHN1bShUb3RhbCkpICU+JQ0KZ2dwbG90KCkgKw0KICBhZXMoUG9saXRpY28sIFByb3BvcmNpb24sIGZpbGwgPSBzZW50aW1lbnQpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAic3RhY2siLCBjb2xvciA9ICJibGFjayIpICsNCiAgY29vcmRfZmxpcCgpICArDQogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsMCkpICsNCiAgbGFicyh5ID0gIlBhbGFicmFzIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KZ2F0aGVyKFR3ZWV0c19ERl9zZW50aW1pZW50bywgInNlbnRpbWVudCIsICJ2YWx1ZXMiLCAxMDM6MTEyKSAlPiUNCiAgZ3JvdXBfYnkoUG9saXRpY28sIFBhcnRpZG8sIHNlbnRpbWVudCkgJT4lDQogIGZpbHRlcihQYXJ0aWRvID09ICAib3Ryb3MgY2FuZGlkYXRvcyIpJT4lDQogIGZpbHRlcihzZW50aW1lbnQgIT0gIlBvc2l0aXZvIiAmIHNlbnRpbWVudCAhPSJOZWdhdGl2byIpJT4lDQogICAgc3VtbWFyaXNlKFRvdGFsID0gc3VtKHZhbHVlcykpICU+JQ0KICAgICAgbXV0YXRlKFByb3BvcmNpb24gPSBUb3RhbCAvIHN1bShUb3RhbCkpICU+JQ0KZ2dwbG90KCkgKw0KICBhZXMoUG9saXRpY28sIFByb3BvcmNpb24sIGZpbGwgPSBzZW50aW1lbnQpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAic3RhY2siLCBjb2xvciA9ICJibGFjayIpICsNCiAgY29vcmRfZmxpcCgpICArDQogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsMCkpICsNCiAgbGFicyh5ID0gIlBhbGFicmFzIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQoNCg0KDQo8Y2VudGVyPiA8c3BhbiBzdHlsZT0iY29sb3I6ICMyODJGNDQ7Ij4gPGgzPiAgMjktIEVtb2Npb25lcyBtZXMgYSBtZXMgPC9oMz4gPC9zcGFuPiA8L2NlbnRlcj4NCg0KU2kgYmllbiBubyBoYXkgZ3JhbmRlcyBjYW1iaW9zIGEgbGEgaG9yYSBkZSBoYWNlciBsb3MgYW7DoWxpc2lzIGRlIHNlbnRpbWllbnRvcyBtZXMgYSBtZXMsIHNlIG5vdGEgYWxndW5vcyBkZXRhbGxlczoNCg0KLSBMb3MgbWluaXN0cm9zIGRlIHNhbHVkIGNhZGEgdmV6IHRyYW5zbWl0ZW4gbWF5b3IgKmNvbmZpYW56YSouDQoNCi0gTG9zIGxsYW1hZG9zIG90cm9zIGNhbmRpZGF0b3MgdmEgZGVjYXllbmRvIGxhIHRyYW5zbWlzacOzbiBkZSAqY29uZmlhbnphKi4NCg0KLSAqKkxhcnJldGEqKiBzaSBiaWVuIHRpZW5lIGJhamFzIGVuIGVsIHNlbnRpbWllbnRvIGRlICpjb25maWFuemEqLCBzaWd1ZSBleHBvbmllbmRvIHVubyBkZSAqYW50aWNpcGFjacOzbiouDQoNCi0gKipLaWNpbGxvZioqIGNhZGEgdmV6IHRpZW5lIG1heW9yIG1lbnNhamUgZGUgKmFuZ3VzdGlhKi4NCg0KDQoNCmBgYHtyfQ0KZ2F0aGVyKFR3ZWV0c19ERl9zZW50aW1pZW50bywgInNlbnRpbWVudCIsICJ2YWx1ZXMiLCAxMDM6MTEyKSAlPiUNCiAgZ3JvdXBfYnkoUG9saXRpY28sIFBhcnRpZG8sIG1lcywgc2VudGltZW50KSAlPiUNCiAgZmlsdGVyKFBhcnRpZG8gPT0gICJjdWVudGEgcGFydGlkYXJpYSIpJT4lDQogIGZpbHRlcihzZW50aW1lbnQgIT0gIlBvc2l0aXZvIiAmIHNlbnRpbWVudCAhPSJOZWdhdGl2byIpJT4lDQogICAgc3VtbWFyaXNlKFRvdGFsID0gc3VtKHZhbHVlcykpICU+JQ0KICAgICAgbXV0YXRlKFByb3BvcmNpb24gPSBUb3RhbCAvIHN1bShUb3RhbCkpICU+JQ0KZ2dwbG90KCkgKw0KYWVzKHggPSBtZXMsIHkgPVByb3BvcmNpb24sIGNvbG9yID0gc2VudGltZW50KSArDQogIGdlb21fcG9pbnQoKSArDQogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBzZW50aW1lbnQpKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSwgdmp1c3QgPSAuNCksIA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzZXJpZiIpKSArDQogIHRlbWEyICsNCiAgZmFjZXRfd3JhcCh+IFBvbGl0aWNvKSArDQogIGxhYnModGl0bGUgPSAiQ2FtYmlvIGRlIGxvcyBzZW50aW1pZW50b3MgZW4gZWwgdGllbXBvIiwgDQogICAgICAgeCA9ICJNZXMiLCB5ID0gIlBvcnBvcmNpw7NuIiwgY29sb3IgPSAiU2VudGltaWVudG8iKSANCg0KZ2F0aGVyKFR3ZWV0c19ERl9zZW50aW1pZW50bywgInNlbnRpbWVudCIsICJ2YWx1ZXMiLCAxMDM6MTEyKSAlPiUNCiAgZ3JvdXBfYnkoUG9saXRpY28sIFBhcnRpZG8sIG1lcywgc2VudGltZW50KSAlPiUNCiAgZmlsdGVyKFBhcnRpZG8gPT0gICJvdHJvcyBjYW5kaWRhdG9zIiklPiUNCiAgZmlsdGVyKHNlbnRpbWVudCAhPSAiUG9zaXRpdm8iICYgc2VudGltZW50ICE9Ik5lZ2F0aXZvIiklPiUNCiAgICBzdW1tYXJpc2UoVG90YWwgPSBzdW0odmFsdWVzKSkgJT4lDQogICAgICBtdXRhdGUoUHJvcG9yY2lvbiA9IFRvdGFsIC8gc3VtKFRvdGFsKSkgJT4lDQpnZ3Bsb3QoKSArDQphZXMoeCA9IG1lcywgeSA9UHJvcG9yY2lvbiwgY29sb3IgPSBzZW50aW1lbnQpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IHNlbnRpbWVudCkpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxLCB2anVzdCA9IC40KSwgDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gInNlcmlmIikpICsNCiAgdGVtYTIgKw0KICBmYWNldF93cmFwKH4gUG9saXRpY28pICsNCiAgbGFicyh0aXRsZSA9ICJDYW1iaW8gZGUgbG9zIHNlbnRpbWllbnRvcyBlbiBlbCB0aWVtcG8iLCANCiAgICAgICB4ID0gIk1lcyIsIHkgPSAiUG9ycG9yY2nDs24iLCBjb2xvciA9ICJTZW50aW1pZW50byIpIA0KDQoNCmdhdGhlcihUd2VldHNfREZfc2VudGltaWVudG8sICJzZW50aW1lbnQiLCAidmFsdWVzIiwgMTAzOjExMikgJT4lDQogIGdyb3VwX2J5KFBvbGl0aWNvLCBQYXJ0aWRvLCBtZXMsIHNlbnRpbWVudCkgJT4lDQogIGZpbHRlcihQYXJ0aWRvID09ICAiUGVyb25pc21vIiklPiUNCiAgZmlsdGVyKHNlbnRpbWVudCAhPSAiUG9zaXRpdm8iICYgc2VudGltZW50ICE9Ik5lZ2F0aXZvIiklPiUNCiAgICBzdW1tYXJpc2UoVG90YWwgPSBzdW0odmFsdWVzKSkgJT4lDQogICAgICBtdXRhdGUoUHJvcG9yY2lvbiA9IFRvdGFsIC8gc3VtKFRvdGFsKSkgJT4lDQpnZ3Bsb3QoKSArDQphZXMoeCA9IG1lcywgeSA9UHJvcG9yY2lvbiwgY29sb3IgPSBzZW50aW1lbnQpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IHNlbnRpbWVudCkpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxLCB2anVzdCA9IC40KSwgDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gInNlcmlmIikpICsNCiAgdGVtYTIgKw0KICBmYWNldF93cmFwKH4gUG9saXRpY28pICsNCiAgbGFicyh0aXRsZSA9ICJDYW1iaW8gZGUgbG9zIHNlbnRpbWllbnRvcyBlbiBlbCB0aWVtcG8iLCANCiAgICAgICB4ID0gIk1lcyIsIHkgPSAiUG9ycG9yY2nDs24iLCBjb2xvciA9ICJTZW50aW1pZW50byIpIA0KDQpnYXRoZXIoVHdlZXRzX0RGX3NlbnRpbWllbnRvLCAic2VudGltZW50IiwgInZhbHVlcyIsIDEwMzoxMTIpICU+JQ0KICBncm91cF9ieShQb2xpdGljbywgUGFydGlkbywgbWVzLCBzZW50aW1lbnQpICU+JQ0KICBmaWx0ZXIoUGFydGlkbyA9PSAgIlBSTyIpJT4lDQogIGZpbHRlcihzZW50aW1lbnQgIT0gIlBvc2l0aXZvIiAmIHNlbnRpbWVudCAhPSJOZWdhdGl2byIpJT4lDQogICAgc3VtbWFyaXNlKFRvdGFsID0gc3VtKHZhbHVlcykpICU+JQ0KICAgICAgbXV0YXRlKFByb3BvcmNpb24gPSBUb3RhbCAvIHN1bShUb3RhbCkpICU+JQ0KZ2dwbG90KCkgKw0KYWVzKHggPSBtZXMsIHkgPVByb3BvcmNpb24sIGNvbG9yID0gc2VudGltZW50KSArDQogIGdlb21fcG9pbnQoKSArDQogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBzZW50aW1lbnQpKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSwgdmp1c3QgPSAuNCksIA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzZXJpZiIpKSArDQogIHRlbWEyICsNCiAgZmFjZXRfd3JhcCh+IFBvbGl0aWNvKSArDQogIGxhYnModGl0bGUgPSAiQ2FtYmlvIGRlIGxvcyBzZW50aW1pZW50b3MgZW4gZWwgdGllbXBvIiwgDQogICAgICAgeCA9ICJNZXMiLCB5ID0gIlBvcnBvcmNpw7NuIiwgY29sb3IgPSAiU2VudGltaWVudG8iKSANCmBgYA0KDQoNCg0KDQo8Y2VudGVyPiA8c3BhbiBzdHlsZT0iY29sb3I6ICMyODJGNDQ7Ij4gPGgzPiAzMC0gQ29tcGFyYWNpw7NuIGRlIGVtb2Npb25lcyA8L2gzPiA8L3NwYW4+IDwvY2VudGVyPg0KDQoNCkxhIGlkZWEgZGUgY29tcGFyYXIgbGFzIGVtb2Npb25lcyBkZSB0b2RvcyBlbiB1biBncsOhZmljbyBheXVkYSBwYXJhIHVuYSB2aXN1YWxpemFjacOzbiBnZW5lcmFsIChlbGltaW5hbmRvIGxhcyBjdWVudGFzIHBhcnRpZGFyaWFzKToNCg0KLSBTaSBiaWVuIGxhIGNhbnRpZGFkIGRlIHR3ZWV0cyBkZSAqKk1hY3JpKiogc29uIHBvY29zLCBlcyBlbCBxdWUgbWF5b3IgKmNvbmZpYW56YSogdHJhbnNtaXRlLg0KDQotIEFxdWVsbG9zIHF1ZSB0aWVuZW4gcG9kZXIgZWxlY3RvIHNvbiBsb3MgcXVlIG3DoXMgKmNvbmZpYW56YSogYnVzY2FuIGVuIHN1cyB0d2VldHMuDQoNCi0gTG9zIGNhbmRpZGF0b3MgcXVlIGhhbiBwZXJkaWRvLCB0aWVuZW4gbWV6Y2xhIGRlIHNlbnRpbWllbnRvcywgY29uIGFsdG8gbml2ZWwgZGUgKm1pZWRvKiB5ICphbmd1c3RpYSogZW4gc3VzIGVzY3JpdG9zLg0KDQotICpTZSBkZXNjYXJ0YW4gYXF1ZWxsb3Mgc2VudGltaWVudG9zIHF1ZSByZXByZXNlbnRlbiBtZW5vcyBkZWwgMTAlIGRlIGxvcyB0d2VldHMuKg0KDQoNCg0KYGBge3J9DQpnYXRoZXIoVHdlZXRzX0RGX3NlbnRpbWllbnRvLCAic2VudGltZW50IiwgInZhbHVlcyIsIDEwMzoxMTIpICU+JQ0KICBncm91cF9ieShQb2xpdGljbywgUGFydGlkbywgc2VudGltZW50KSAlPiUNCiAgZmlsdGVyKHNlbnRpbWVudCAhPSAiUG9zaXRpdm8iICYgc2VudGltZW50ICE9Ik5lZ2F0aXZvIiAmIFBhcnRpZG8gIT0gImN1ZW50YSBwYXJ0aWRhcmlhIiklPiUNCiAgICBzdW1tYXJpc2UoVG90YWwgPSBzdW0odmFsdWVzKSkgJT4lDQogICAgICBtdXRhdGUoUHJvcG9yY2lvbiA9IFRvdGFsIC8gc3VtKFRvdGFsKSkgJT4lDQogICAgZ2dwbG90KCkgKw0KICBhZXMoUG9saXRpY28sIFByb3BvcmNpb24sIGNvbG9yID0gc2VudGltZW50LCBhbHBoYSA9IFByb3BvcmNpb24pICsNCiAgZ2VvbV9wb2ludChmaWxsID0gIndoaXRlIiwgc3Ryb2tlID0gMSwgc2hhcGUgPSAyMSkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gc2VudGltZW50KSwgdmp1c3QgPSAtLjksIGZhbWlseSA9ICJzZXJpZiIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0ICgpKSArDQogIHRlbWExICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHBhbmVsLmdyaWQubWlub3IueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgdGV4dCA9ICBlbGVtZW50X3RleHQoZmFtaWx5ID0gInNlcmlmIikpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0aXRsZSA9ICJTZW50aW1pZW50b3MgdG90YWxlcyBjb21wYXJhdGl2byIsDQogICAgICAgeCA9ICJQb2xpdGljbyIsDQogICAgICAgeSA9ICJQcm9wb3JjacOzbiBkZWwgc2VudGltaWVudG8iKQ0KDQpnYXRoZXIoVHdlZXRzX0RGX3NlbnRpbWllbnRvLCAic2VudGltZW50IiwgInZhbHVlcyIsIDEwMzoxMTIpICU+JQ0KICBncm91cF9ieShQb2xpdGljbywgUGFydGlkbywgc2VudGltZW50KSAlPiUNCiAgZmlsdGVyKHNlbnRpbWVudCAhPSAiUG9zaXRpdm8iICYgc2VudGltZW50ICE9Ik5lZ2F0aXZvIiAmIHNlbnRpbWVudCAhPSJBbGVncmlhIiAmIHNlbnRpbWVudCAhPSJTb3JwcmVzYSIgJiBQYXJ0aWRvICE9ICJjdWVudGEgcGFydGlkYXJpYSIpJT4lDQogICAgc3VtbWFyaXNlKFRvdGFsID0gc3VtKHZhbHVlcykpICU+JQ0KICAgICAgbXV0YXRlKFByb3BvcmNpb24gPSBUb3RhbCAvIHN1bShUb3RhbCkpICU+JQ0KICBnZ3Bsb3QoKSArDQogIGFlcyhzZW50aW1lbnQsIFByb3BvcmNpb24sIGNvbG9yID0gc2VudGltZW50KSArDQogIGdlb21fcG9pbnQoKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBQb2xpdGljbykgLHZqdXN0ID0gLS4zLCBzaXplID0gMykgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLjE1LCAwLjQ3KSkgKw0KICAgbGFicyh0aXRsZSA9ICJTZW50aW1pZW50b3MgdG90YWxlcyBjb21wYXJhdGl2byIsDQogICAgICAgeCA9ICJQb2xpdGljbyIsDQogICAgICAgeSA9ICJQcm9wb3JjacOzbiBkZWwgc2VudGltaWVudG8iKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCg0KDQpgYGANCg==