Trabajo elaborado para la asignatura “Programación y manejo de datos en la era del Big Data” de la Universitat de València durante el curso 2020-2021. El repo del trabajo está aquí. La página web de la asignatura y los trabajos de mis compañeros pueden verse aquí.


1. Introducción

La razón por la que he escogido hacer mi trabajo sobre este tema es mi interés por el comercio internacional, ya que es interesante e importante para la economía.

En cuanto al objetivo del trabajo, principalmente es poder reflejar de manera sencilla tanto la estructura del sector exterior español como su situación a nivel internacional.

2. Datos

La fuente principal de los datos para mi proyecto ha sido el portal DataComex, que es administrado por el Ministerio de comercio, industria y turismo. Este portal ofrece una gran variedad de datos sobre el comercio español, siendo el más completo de todos los que he consultado. Sin embargo, tiene algunos inconvenientes respecto a otros portales como eurostat. El mayor inconveniente de este portal que he encontrado durante la realización del proyecto han sido los acentos, ya que al cargarlos en R aparecían de esta forma: Andalucía. Más adelante explicaré cómo he resuelto este problema. En cuanto a la obtención de los datos, esta plataforma no tiene API por lo que he recurrido a descargar los datos a través del navegador y cargarlos en github.

Excepcionalmente he utilizado datos de la organización mundial del comercio (OMC) y del Banco Mundial. A pesar de que estas plataformas si que cuentan con una API, como sólo las he utilizado de manera excepcional he recurrido al mismo metodo de obtención de los datos anterior: descargarlos a través del navegador y cargarlos en github.

2.1. Problemas limpiando los datos

El procesado de los datos ha sido con diferencia la parte más laboriosa. A continuación explicaré algunos de los problemas a los que he tenido que hacer frente.

El primer problema con el que me encontré es un ejemplo perfecto de cómo resolver un pequeño problema de programación, que a simple vista parece una tontería, puede llevar horas y horas.

Los datos del PIB anual de todos los países del mundo, de los cuales sólo acabe utilizando los datos de España e Italia, presentaba los años de la siguiente forma :
2000 [YR2000] 2001 [YR2001] 2002 [YR2002] 2003 [YR2003] 2004 [YR2004] 2005 [YR2005]

Como se puede observar, sobran tanto los corchetes como su contenido. A pesar de que ya conocía la función str_remove_all(), el patrón de dicha función hay que escribirlo en lenguaje regex. Dicho lenguaje me es totalmente desconocido, por lo que después de estar horas probando diferentes combinaciones y buscando información hallé la respuesta en un post de stackoverflow. La solución fue la siguiente:

mutate(name = str_remove_all(name,"\\[[^\\]]*\\]")

En cuanto a los datos procedentes del portal DataComex, me he encontrado dos problemas recurrentes: el formato de los números y los acentos.

El problema de los números fue relativamente sencillo de solucionar, una vez caí en que la razón por la que no me dejaba cambiar el formato de carácter a numérico era el formato de los números fue sencillo de solucionar. Con la ya mencionada función str_replace() cambié las comas de los decimales por puntos, usando el siguiente código:

mutate(valor = str_replace(valor,"[,]","."))

Los acentos fueron más difíciles de solucionar, ya que no sólo tuve que dedicarle bastante tiempo a pensar la solución, sino que la propia solución no era todo lo rápida que me hubiera gustado. Como ya he mencionado en el punto anterior, al cargar los datos en R los acentos aparecían de la siguiente forma: “Andalucía”. Para solucionar este problema usé la función case_when(), empleando el siguiente código:

mutate(columna = case_when(columna == "Andalucía" ~ "Andalucía",
                           columna == "Aragón" ~ "Aragón",
                           columna == "Castilla y León" ~ "Castilla y León",
                           columna == "Cataluña" ~ "Cataluña",
                           columna == "Murcia, Región de" ~ "Murcia",
                           columna == "País Vasco" ~ "País Vasco", 
                           columna == columna ~ columna))

Estos han sido sólo algunos de los inconvenientes que me he encontrado durante la limpieza de los datos, ya que realmente han sido muchos más. Además de los ya mencionados, también he tenido que: ordenar las variables usando factores, pivotar las tablas, agrupar, filtrar, hacer mutates, cambiar nombres de las variables etc… En definitiva: He aplicado todo lo que hemos estudiado de la mejor manera que he sido capaz.

2.2 Procesado de datos

A continuación presentaré y explicaré brevemente el código que he utilizado para limpiar todos los datos.

Datos del Banco Mundial

Además del ya mencionado problema del formato de la fecha, los datos del Banco Mundial también me ocasionaron problemas con los NAs. Estos datos representaban los NAs con “..”, lo que también me llevó trabajo corregir. Finalmente lo solucioné con la función replace_with_na() del paquete naniar. Además de eso, transformé la tabla a formato largo, cambié los valores del PIB de dólares a Millones de dólares y renombré las variables con la función setNames(). Finalmente exporté los datos limpios y los subí a github.

datos <- here::here("Data","GDPWorld.csv")
#Limpieza
dfa <- rio::import(datos) %>% pivot_longer(cols = 5:65) %>%
                              select(-c(2)) %>% naniar::replace_with_na(replace = list(value = ".."))%>%
                              mutate(name = str_remove_all(name,"\\[[^\\]]*\\]"), name = as.numeric(name), value = as.numeric(value), value = (value/1000000)) %>%
                              setNames(c("indicador","country","countryiso3code","year","value")) #Ahora está en Millones de dolares
#Exportación
rio::export(dfa,file = here::here("Data","GDPWorldC.csv"))

Organización Mundial del Comercio

Los datos de las importaciones y exportaciones por país fueron ligeramente más sencillos de limpiar que los del Banco Mundial, aunque seguí el mismo procedimiento: los importé, los limpié, los exporté y los subí a github. La limpieza de estos datos básicamente consistió en: eliminar columnas irrelevantes con select() y reubicarlas con relocate(),filtrar los datos para quedarme sólo con los datos totales y cambiar los nombres tanto de filas como de columnas. Quizá lo más relevante de este trozo de código fue que utilicé la función if_else() para cambiar los nombres de los indicadores de importaciones y exportaciones.

datos <- here::here("Data","XMWorld.csv")
#Limpieza
dfb <- rio::import(datos) %>% select(-c(1,2,7,8,9,16,17,21,22,23)) %>%
                             rename("product_code" = 7) %>%
                             filter(product_code == "TO") %>% select(-c(5:11)) %>%
                             mutate(Indicator = if_else(Indicator=="Merchandise imports by product group – annual","importsy","exportsy")) %>%
                             relocate(6,.after = 4) %>%
                             setNames(c("indicador","countrycode","countryiso3code","country","year","unidad","value"))
#Exportación
rio::export(dfb,file = here::here("Data","XMWorldC.csv"))

DataComex

En primer lugar descargué las importaciones y exportaciones anuales totales de España. Trás subirlos a github procedí a limpiarlos. Estos datos estaban bastante limpios, por lo que solamente tuve que hacer un par de modificaciones. Cambié los nombres de las variables, esta vez usando la función rename_at() del paquete dyplr, cambié el formato de los números usando el metodo explicado anteriormente y por último filtré las fechas para eliminar algunos datos irrelevantes.

url <- "https://raw.githubusercontent.com/xi765/MiProyectoIndividualArchivos/main/DataComex_201130122036.csv"
data <- read.csv(url) %>% rename_at(vars(colnames(data)), ~ c("Country","Date","Columna","Variable","Valor")) %>% 
                          filter(Date != "Total Fechas") %>% 
                          mutate(Valor = stringr::str_replace(Valor,"([,])","."),Valor = as.numeric(Valor), Date = as.numeric(Date))

En segundo lugar busqué los datos de importaciones y exportaciones españolas por continente de origen y destino. Al igual que los datos anteriores, los alojé en github. Tuve problemas con los nombres de los continentes, ya que el formato no era adecuado y además algunos nombres tenían acentos. Para solucionar este problema opté por la ya mencionada función case_when(), con la que cambié los nombres antiguos por unos más claros. A partir de estos datos hice dos tablas distintas: una con las exportaciones e importaciones por continente y otra con la evolución de estos mismos flujos pero sólo con la UE 28. Lo más complejo de este código fue el obtener los porcentajes, ya que la variable Total estaba en la misma columna que las variables por continente. Para extraer dicha variable utilicé una combinación de la función inner_join() y la función filter(), para posteriormente obtener el porcentaje mediante la función mutate().

#Exportaciones e importaciones por continentes en millones de euros (fuente datacomex)
datos <- here::here("Data","XMContinentes.csv")
dfxmc <- rio::import(datos) %>% filter(subfila != "Total seleccionado") %>% select(-c(4)) %>%
mutate(fila = case_when( fila == "AF - Africa" ~ "Africa", fila == "AM - América" ~ "America", fila == "AS - Asia" ~"Asia", fila == "OC - Oceanía" ~ "Oceania", fila == "UE - Unión Europea 28 países(d.2013-07 h.2020-01)" ~ "Union Europea (28)", fila == "Total Mundo" ~ "Total"), valor = str_replace(valor,"[,]","."), valor = as.numeric(valor), subfila = as.numeric(subfila))
#EXPORTACIONES POR CONTINENTE
aa <- inner_join(x = dfxmc %>% filter(fila != "Total"),y = dfxmc %>% filter(fila == "Total"), by = c("columna","subfila")) %>% select(-c(5)) %>% mutate(porc = (valor.x/valor.y)) %>% filter(subfila == 2019)
#EXPORTACIONES E IMPORTACIONES A LA UE
dfexpc <- dfxmc %>% filter(fila == "Union Europea (28)")
dfexpcb <- inner_join(dfexpc,espxm, by = c("subfila"="Date","columna"="Variable")) %>% select(-c(5)) %>% mutate(valorporc = (valor/ValorM))

En tercer lugar busqué los flujos comerciales de España con el resto de países. La limpieza de estos datos fue sencilla, simplemente repetí los pasos que ya he descrito anteriormente, con la excepción de que hice un slice_max() para quedarme solamente con los 10 países más relevantes. Esta tabla también la dividí en dos nuevas tablas: una relativa a las exportaciones y una a las importaciones.

#Exportaciones e importaciones por país en millones de euros
datos <- here::here("Data","XMPais.csv")
dfxmp <- rio::import(datos) %>% mutate( valor = str_replace(valor,"[,]","."), valor = as.numeric(valor))
#EXPORTACIONES
dfxp <- dfxmp %>% filter(subcolumna == "EXPORT", subfila == "2019", !fila %in% c("Total seleccionado","UE - Unión Europea 28 países(d.2013-07 h.2020-01)")) %>% slice_max(order_by = valor,n = 10)
#IMPORTACIONES
dfmp <- dfxmp %>% filter(subcolumna == "IMPORT", subfila == "2019", !fila %in% c("Total seleccionado","UE - Unión Europea 28 países(d.2013-07 h.2020-01)")) %>% slice_max(order_by = valor,n = 10)

En quinto lugar busqué y limpíe los datos de flujos comerciales por producto y año para hacer una tabla. En este código si se puede apreciar mayor complejidad que respecto a los anteriores. Además de emplear algunos metodos que ya utilicé anteriormente cómo la función case_when() para arreglar los nombres o la combinación de las funciones inner_join() y filter() para sacar porcentajes, también utilicé algunos nuevos. Por ejemplo, descubrí las funciones comma() y percent(), que utilicé para que los datos se vieran más limpios en la tabla.

#XM POR PRODUCTO Y FECHA EN MILLONES DE EUROS
datos <- here::here("Data","XMProducto.csv")
dfprod <- rio::import(datos) %>% select(-c(2)) %>% filter(columna %in% c("2015","2016","2017","2018","2019","2020")) %>% mutate( valor = str_replace(valor,"[,]","."), valor = as.numeric(valor))

a <- inner_join(x = dfprod, y = dfprod %>% filter(fila == "Total seleccionado"), by = c("columna","subcolumna")) %>% mutate(porc = (valor.x/valor.y)) %>% select(-c(5,6)) %>% mutate(fila.x = case_when(fila.x == "Total seleccionado" ~ "Total", fila.x == "1 ALIMENTACIÓN, BEBIDAS Y TABACO" ~ "Alimentación, bebidas y tabaco", fila.x == "2 PRODUCTOS ENERGETICOS" ~ "Productos energéticos", fila.x == "3 MATERIAS PRIMAS" ~ "Materias primas", fila.x == "4 SEMIMANUFACTURAS" ~ "Semimanufacturas", fila.x == "5 BIENES DE EQUIPO" ~ "Bienes de equipo",fila.x == "6 SECTOR AUTOMOVIL" ~ "Sector automóvil",fila.x == "7 BIENES DE CONSUMO DURADERO" ~ "Bienes de consumo duradero",fila.x == "8 MANUFACTURAS DE CONSUMO" ~ "Manufacturas de consumo",fila.x == "9 OTRAS MERCANCIAS" ~ "Otras mercancías"), porc = percent(porc), valor.x = comma(valor.x, digits = 0))
aa <- a %>% pivot_wider(names_from = c(subcolumna,columna), values_from = c(valor.x,porc)) %>% rename(" " = 1) %>% select(1,2,14,3,15,4,16,5,17,6,18,7,19,8,20,9,21,10,22,11,23,12,24,13,25) %>% setNames(c("","Mill. de €","%","Mill. de €","%","Mill. de €","%","Mill. de €","%","Mill. de €","%","Mill. de €","%","Mill. de €","%","Mill. de €","%","Mill. de €","%","Mill. de €","%","Mill. de €","%","Mill. de €","%"))

En sexto lugar utilicé datos de exportaciones e importaciones por provincias, aunque finalmente sólo usé las exportaciones. El código ya tiene poco nuevo, lo único es que en esta ocasión además de transformar los valores a Millones de euros también los transformé a logaritmos con la función log().

#PROVINCIAS MÁS EXPORTADORAS
url <- "https://raw.githubusercontent.com/xi765/MiProyectoIndividualArchivos/main/exp_imp_prov_2019.csv"
exppr <- read.csv(url)
exppr <- exppr %>% select(-c(subfila,subcolumna))
exppr <- exppr %>% rename_at(vars(colnames(exppr)), ~ c("Provincia","Variable","Valor"))
exppr <- exppr %>% mutate(Valor = stringr::str_replace(Valor,"([,])",".")) %>% mutate(Valor = as.numeric(Valor), ValorEnMill = (Valor/1000000), ValorLog = log(Valor, base = exp(2)))
exppr <- exppr %>% mutate(Valorporc = (Valor/exppr[1,3]))

En septimo lugar preparé los datos de exportaciones por producto y provincia en 2019 para hacer una nueva tabla. De nuevo seguí los pasos descritos anteriormente. Cabe destacar que escribiendo este código tuve que volver a descifrar el lenguaje regex, ya que los nombres de los productos tenían varios números que finalmente conseguí quitar con la ya mencionada funcion str_remove().

#DATOS DE EXPORTACIÓN POR PRODUCTO Y PROVINCIA EN MILLONES DE EUROS 2019
datos <- here::here("Data","XComProd.csv")
dfccaa <- rio::import(datos) %>% select(c(1,3,5)) %>% filter(!columna %in% c("Total Nacional","No determinado")) %>% mutate( valor = str_replace(valor,"[,]","."), valor = as.numeric(valor), fila = str_remove(fila,"[[:digit:]]+"), fila = case_when(fila == "A GRASAS Y ACEITES" ~ "GRASAS Y ACEITES",fila == "B SEMILLAS Y FRUTOS OLEAGINOSOS" ~ "SEMILLAS Y FRUTOS OLEAGINOSOS",fila == "C PIENSOS ANIMALES" ~ "PIENSOS ANIMALES", fila == fila ~ fila), columna = case_when(columna == "Andalucía" ~ "Andalucía",columna == "Aragón" ~ "Aragón",columna == "Castilla y León" ~ "Castilla y León",columna == "Cataluña" ~ "Cataluña",columna == "Murcia, Región de" ~ "Murcia",columna == "País Vasco" ~ "País Vasco", columna == columna ~ columna))
aa <- dfccaa %>% pivot_wider(names_from = columna, values_from = valor) %>% column_to_rownames("fila")

Por último limpié datos de transporte de mercancías. En este código además de las técnicas descritas anteriormente, también tuve que agrupar una serie de variables, creando una nueva variable llamada “Otro”. Hice esto porque habían cuatro variables que representaban muy poco, por lo que pensé que de esta forma se vería más claro. Para realizar esta agrupación primero cambié los nombres de las variables por “Otro”, luego con una combinación de group_by() y summarise() junto a la función sum() conseguí el resultado que buscaba.

#Medios de transporte más utilizados 2019 en millones de euros
datos <- here::here("Data","XMMedioTransporte.csv")
dftrans <- rio::import(datos)%>% select(-c(2)) %>% mutate( valor = str_replace(valor,"[,]","."), valor = as.numeric(valor), fila = str_remove(fila,"[[:digit:]]+"), fila = case_when( fila == "  Marítimo" ~ "  Marítimo", fila == "  Tráfico postal" ~ "  Tráfico postal", fila == "  Propulsión propia" ~ "  Propulsión propia", fila == fila ~ fila)) %>% filter(columna != "Total seleccionado")

a <- inner_join( x = dftrans%>%filter(subcolumna == "EXPORT"), y = dftrans%>%filter(subcolumna == "IMPORT"), by = c("fila","columna")) %>% mutate(totalxm = (valor.x+valor.y)) %>% select(-c(3:6))
aa <- inner_join( x = a%>%filter(fila!="Total modo transporte"), y = a %>% filter(fila=="Total modo transporte"), by = c("columna")) %>% mutate(porc = (totalxm.x/totalxm.y)) %>% select(-c(4,5)) %>% mutate(fila.x = case_when(fila.x == "  Desconocido" ~ "Otro",fila.x == "  Plataforma fija" ~ "Otro",fila.x == "  Propulsión propia" ~ "Otro",fila.x == "  Tráfico postal" ~ "Otro",fila.x == "  Transporte fluvial" ~ "Otro", fila.x == fila.x ~ fila.x)) %>% group_by(columna,fila.x) %>% summarise(totalxm.x = sum(totalxm.x), porc = sum(porc)) %>% group_by(columna) %>% mutate(fila.x = factor(fila.x, levels = fila.x[order(porc)]))

3. El sector exterior español

3.1 Los socios comerciales de España

Continentes

En este gráfico de barras podemos ver las grandes áreas con las que comercia España. Lo más relevante de este gráfico es la importancia de la Unión Europea, suponiendo un más de un 60% de nuestras exportaciones y más de un 50% de nuestras importaciones, siendo así nuestro principal socio comercial. También cabe destacar el importante saldo positivo de la balanza comercial con la Unión Europea, que por otra parte se ve contrarestado por el saldo negativo que sostiene España frente a Asia.

Código

Para elaborar este gráfico he usado el geoma geom_bar(). A dicho geoma le he añadido dos opciones stat = “identity” y position = “dodge”, la primera para poder representar valores continuos y la segunda para presentar dos columnas por continente. Adicionalmente he puesto el eje y en porcentaje usando scale_y_continuous(breaks = seq(0,0.65,0.1), labels = scales::percent).

En cuanto al tema, a parte de quitar las líneas del eje menor y, el eje x y los bordes, también he modificado la leyenda. Con legend.position = “top” he cambiado la posición de la leyenda desde la derecha hasta arriba del gráfico.

ggplot(aa, aes(x = fila.x, y = porc, fill = columna)) + geom_bar(stat = "identity", position = "dodge", color = "#000000") +
               scale_y_continuous(breaks = seq(0,0.65,0.1), labels = scales::percent) +
               scale_fill_discrete(labels = c("% del total de Exportaciones","% del total de Importaciones")) +
              labs(fill=NULL,
               x=NULL,
               y=NULL,
               title="Flujos comerciales por continente",
               subtitle = "Año 2019",
               caption="Fuente: DataComex") +
               theme(
              panel.background = element_rect( fill = "#ffffff", colour = "#ffffff"),
              panel.grid  = element_line( colour ="grey"),
              axis.ticks = element_blank(),
              plot.title = element_text(vjust = 2.5, size = 15),
              panel.border = element_blank(),
              panel.grid.minor.y = element_blank(),
              panel.grid.major.x = element_blank(),
              legend.margin = margin(t=25),
              legend.position = "top",
              legend.background = element_rect( fill = "#ffffff", colour = "#ffffff" ),
              plot.margin = margin(t = 5, r = 25, b = 5,15))

Países

En estos gráficos fragmentamos la información analizada en el apartado anterior, viendo la misma información pero por país. Estos gráficos nos reafirman el hecho de que Europa es nuestro principal socio comercial, especialmente en lo referente a las exportaciones. Los cinco países a los que exportamos más mercancías por valor son europeos, siendo Francia nuestro principal cliente. En cuanto a las importaciones la situación es ligeramente distinta, aunque Alemania y Francia siguen siendo los países de los que más importamos, China se encuentra en tercera posición y Estados Unidos en la quinta.

Código

Para hacer este gráfico he vuelto a usar un geom_bar(), aunque en esta ocasión he optado por representar las Exportaciones e Importaciones por separado. El tema que he usado ha sido el mismo que en el gráfico anterior, a excepción de el eje y. En esta ocasión los valores del eje y estaban en millones, así que usé la función scale_y_continuous() para cambiar el formato y hacerlo más sencillo. Dentro de dicha función incluí labels = paste(scales::comma(seq(0,45000,5000)),“M€”), que básicamente ponía en formato coma la secuencia escrita y le pegaba un “M€”.

#Exportaciones
ggplot(dfxp, aes(x = fila, y = valor, fill = fila)) + geom_bar(stat = "identity",color = "#000000") +
             scale_fill_brewer(palette = "Spectral", labels = c("Francia","Alemania","Italia","Portugal","Reino Unido","Estados Unidos","Países Bajos","Marruecos","Bélgica","China")) +
             scale_x_discrete(labels = c("Francia","Alemania","Italia","Portugal","Reino Unido","Estados Unidos","Países Bajos","Marruecos","Bélgica","China")) +
             scale_y_continuous(breaks = seq(0,45000,5000), labels = paste(scales::comma(seq(0,45000,5000)),"M€")) +
             labs(fill=NULL,
               x=NULL,
               y=NULL,
               title="Exportaciones por país",
               subtitle = "Año 2019",
               caption="Fuente: DataComex") +
               theme( plot.background = element_rect( fill = "#ffffff"),
              panel.background = element_rect( fill = "#ffffff", colour = "#ffffff", size = 0.1 ),
              panel.grid  = element_line( colour ="grey"),
              panel.grid.major.x = element_blank(),
              panel.grid.minor.y = element_blank(),
              axis.ticks = element_blank(),
              axis.text.x = element_text(angle = 75, face = "bold", vjust = 0.95, hjust = 1),
              plot.title = element_text(vjust = 2.5, size = 15),
              panel.border = element_blank(),
              legend.position = "none",
              plot.margin = margin(t = 5, r = 25, b = 5,15),
              strip.background = element_rect(fill = "#e8d7a3",colour = NULL))

Europa: Nuestro gran aliado

Con este gráfico he querido hacer un mayor énfasis en la relevancia que tiene la Unión Europea como socio comercial de España. En el gráfico podemos ver la evolución del peso de los flujos comerciales con la Unión Europea desde 1995 hasta la actualidad. Hay dos aspectos que cabe destacar sobre este gráfico: Primero la caída de los flujos comerciales con la Unión Europea desde principios de sigo hasta el 2012 aproximadamente. Esto podría haber sido causado por el avance de la globalización, que ha hecho que terceros países en vías de desarrollo entren a competir directamente en los mercados europeos, un claro ejemplo de esto sería el aumento de las importaciones chinas; Segundo, la reciente brusca recuperación que han sufrido ambos flujos. Esto lo podríamos asociar a la crisis del Covid-19, que ha supuesto un freno a los flujos de comercio internacional, esta crisis ha afectado más al comercio con países fuera de la UE porque dichos países además de estar más alejados, también han tenido mayores trabas.

Código

Para realizar este gráfico he usado un geom_line(). En cuanto al tema, he reciclado el de los gráficos anteriores, a excepción de la leyenda. En este gráfico he incorporado la leyenda en el subtítulo con el paquete ggtext(). Este paquete permite escribir los textos en Markdown, permitiendo entre otras cosas, cambiar el color del texto.

ggplot(dfexpcb, aes(x=subfila, y=valorporc, color = columna)) + geom_line(size=1) +
        scale_y_continuous(breaks = seq(0.5,0.75,0.05), labels = scales::percent)+
        scale_x_continuous(breaks = seq(1995,2020,1)) +
        labs(fill=NULL,
        x=NULL,
        y=NULL,
        title="Flujos comerciales con la Unión Europea (28)",
        subtitle = "<span style='color:#ff0505;'>Exportaciones</span> e <span style='color:#24ff05;'>Importaciones </span>en % del total",
        caption="Fuente: DataComex") +
        scale_color_manual( values = c("EXPORT"="#ff0000","IMPORT"="#24d800"), labels = c("Exp.","Imp.")) +
        theme( plot.background = element_rect( fill = "#ffffff"),
              panel.background = element_rect( fill = "#ffffff"),
              panel.grid  = element_line( colour ="#979e9e"),
              panel.grid.minor.x = element_blank(),
              panel.grid.minor.y = element_blank(),
              panel.grid.major.x = element_blank(),
              axis.line = element_line(color = "#000000"),
              axis.ticks = element_line(colour = "#000000"),
              axis.text = element_text(colour = "#000000"),
              axis.text.x = element_text(angle = 90),
              axis.title.y = element_text(vjust = 4),
              axis.title.x = element_text(hjust = 0.5),
              plot.title = element_text(hjust = 0.5),
              plot.subtitle = element_markdown(hjust = 0.5),
              panel.border = element_rect(fill = NA,colour = "#ffffff"),
              legend.position = "none")

3.2 El sector exterior español

En este gráfico se muestra el total de importaciones y exportaciones por año, además se ha resaltado en amarillo el déficit de la balanza comercial. En este gráfico me gustaría destacar dos cosas: En primer lugar, las dos importantes caídas sufridas en 2008 y 2020; En segundo lugar, el hecho de que el sector exportador español se ha comportado relativamente bien en todos los periodos de crisis económica. Esto lo podemos ver bien observando el déficit de la balanza comercial, en los periodos de crisis este déficit siempre se reduce.

Código

Para elaborar este gráfico he seguido el mismo metodo que en el gráfico anterior, sin embargo, esta vez he añadido un geom_ribbon() para representar el déficit de la balanza comercial. Para este geoma he tenido que crear dos nuevas columnas en el dataframe: min y max. Estas columnas las creé con las funciones min() y max(), cogiendo el valor mínimo y máximo de cada año, dichos valores actuan como límites del polígono.

ggplot(espxm,aes(x = Date, y = ValorM, color = Variable)) +
        geom_line() +
        geom_point() +
        geom_ribbon(aes(x = Date, ymin = min, ymax = max), fill = "#f4ff05", alpha = 0.3, color = NA) +
        labs(fill=NULL,
        x=NULL,
        y=NULL,
        title="<span style='color:#ff0505;'>Exportaciones</span> e <span style='color:#24ff05;'>Importaciones </span>en España",
        caption="Fuente: DataComex") +
        scale_color_manual( values = c("EXPORT"="#ff0000","IMPORT"="#24d800")) +
        scale_fill_manual( values = c("EXPORT"="#ff0000","IMPORT"="#24d800")) +
        scale_y_continuous(breaks = seq(0,300000,50000),labels = (paste(scales::comma(seq(0,300000,50000)),"M€"))) +
        scale_x_continuous(breaks = seq(1995,2020,1)) +
        theme( plot.background = element_rect( fill = "#ffffff"),
              panel.background = element_rect( fill = "#ffffff"),
              panel.grid  = element_line( colour ="#979e9e"),
              panel.grid.minor.y = element_blank(),
              panel.grid.major.x = element_blank(),
              panel.grid.minor.x = element_blank(),
              axis.ticks = element_line(colour = "#000000"),
              axis.text = element_text(colour = "#000000"),
              axis.text.x = element_text(angle = 90),
              axis.title.y = element_text(vjust = 4),
              axis.title.x = element_text(hjust = 0.5),
              axis.line = element_line(color = "#000000"),
              panel.border = element_rect(fill = NA,colour ="#ffffff"),               plot.title = element_markdown(hjust = 0.5),
              legend.position = "none",
              plot.margin = margin(t = 5, r = 10, b = 5,20) )

Peso y evolución los flujos comerciales

En este gráfico podemos observar la evolución del peso en porcentaje del PIB tanto de las exportaciones como de las importaciones. Me gustaría destacar en primer lugar la divergencia que se produce a partir de 1960 entre las exportaciones y las importaciones, y en segundo lugar la caída que sufrieron ambas en la crisis de 2008. Esta divergencia que se produce a partir de 1960 la podemos asociar a los planes de Estabilización y Desarrollo llevados a cabo en la úlima etapa del franquismo, dichos planes permitieron abrir España al comercio internacional entre otras cosas.

Código

Para elaborar este gráfico he seguido el mismo metodo que en el gráfico anterior, únicamente he modificado las líneas menores del eje y y los brakes de la variable x.

ggplot(dft,aes(x=year,y=porcpib,color=indicador)) + geom_line(size=1) + labs(color=NULL,
        x=NULL,
        y=NULL,
        title="Peso de las <span style='color:#ff0505;'>Exportaciones</span> e <span style='color:#24ff05;'>Importaciones </span>en el PIB",
        caption="Fuente: DataComex") +
        scale_x_continuous(breaks = seq(1960,2020,5),limits = c(1960,2019)) +
        scale_y_continuous(breaks = seq(0,0.3,0.05),labels = scales::percent)+
        scale_color_manual( values = c("exportsy"="#ff0000","importsy"="#24d800"), labels = c("Exportaciones","Importaciones")) +
        theme( plot.background = element_rect( fill = "#ffffff"),
              panel.background = element_rect( fill = "#ffffff"),
              panel.grid  = element_line( colour ="#979e9e"),
              panel.grid.major.x = element_blank(),
              panel.grid.minor.x = element_blank(),
              axis.ticks = element_line(colour = "#000000"),
              axis.text.x = element_text(angle = 90),
              axis.line = element_line(color = "#000000"),
              plot.title = element_markdown(hjust = 0.5),
              panel.border = element_rect(fill = NA,colour = "#ffffff"),
              legend.position = "none")

Exportación por comunidades

En este gráfico podemos ver las comunidades que exportaron mercancías por más valor en 2019. Cabe destacar la dominancia de Barcelona, muy lejos de Madrid y mucho más de cualquier otra. Nuestra comunidad, Valencia, se encuentra en tercera posición, más cerca de Zaragoza que de Madrid.

Código

Esta vez he escogido uno de los temas que ofrece el paquete ggplot, que se parece mucho al que he creado yo y he usado anteriormente.

En cuanto al gráfico, esta vez he hecho un gráfico estilo Lollipop. Para construir el gráfico he usado un geom_point() junto a un geom_segment(). Para configurar el geom_segment() he usado factores, ya que hay que especificar un punto de inicio y uno de final.

theme_set(theme_classic())
ggplot(dataplot2,aes(y = ValorEnMill, x = forcats::fct_reorder(Provincia, ValorEnMill, .desc = TRUE))) + geom_point() + geom_segment(aes(x=forcats::fct_reorder(Provincia, ValorEnMill, .desc = TRUE),
                   xend=forcats::fct_reorder(Provincia, ValorEnMill, .desc = TRUE),
                   y=0,
                   yend=ValorEnMill))+ 
      scale_y_continuous(breaks = seq(0,60000,5000),labels = paste(scales::comma(seq(0,60000,5000)),"M€"), limits = c(0,62500)) +
      scale_x_discrete(labels = c("Barcelona","Madrid","Valencia","Zaragoza","A Coruña","Murcia","Navarra","Bizkaia","Pontevedra","Tarragona"))+ labs(title="Comunidades que más exportan",
       subtitle="Año: 2019",
       caption="Fuente: DataComex",
       x=NULL,
       y=NULL) +
  theme(panel.grid.major.y = element_line(colour = "#dadada"),axis.text.x = element_text(angle=65, vjust=0.95, hjust = 1))

Adicionalmente he construido una tabla interactiva en la que se muestran las exportaciones por grupo de productos de cada comunidad autónoma en 2019.

He usado el paquete DT para hacerla interactiva y añadirle algunas extensiones:la extensión “Fixed Columns” para que los nombres de las variables no desaparecieran al hacer scroll horizontal y la extensión buttons para añadirle un boton que permite guardar la tabla en formato excel.

DT::datatable(aa, extensions = c("FixedColumns","Buttons"),
  options = list(
    dom = "Btip",
    scrollX = TRUE,
    fixedColumns = TRUE,
    autoWidth = TRUE,
    buttons = c("excel"),
    pageLength = 5))

Desglose de las exportaciones españolas

En esta tabla he desglosado el total de importaciones y exportaciones españolas por grupos de producto y año. Cabe destacar el peso del sector de las semimanufacturas en nuestras Exportaciones. Respecto a 1995, el sector automóvil ha perdido peso a favor de las semimanufacturas y los bienes de equipo.

Código

Una vez limpiados los datos he usado el paquete KableExtra para hacer esta tabla. Básicamente he usado la función kbl() para hacer la tabla junto a la función add_header_above() para crear los títulos de cada columna. Finalmente he usado la función kable_styling() con los argumentos “striped” y “hover” para dejarla más aseada.

kbl(aa, format = "html", booktabs = T, linesep = "") %>% add_header_above(c("","Exportaciones" = 2, "Importaciones" = 2, "Exportaciones" = 2, "Importaciones" = 2)) %>% add_header_above(c("", "1995" = 4, "2019" = 4), line = T) %>%  kable_styling(c("striped","hover")) %>% row_spec(1, bold = TRUE)
1995
2019
Exportaciones
Importaciones
Exportaciones
Importaciones
Mill. de € % Mill. de € % Mill. de € % Mill. de € %
Total 69,962,211 100.000% 87,142,300 100.000% 290,089,074 100.000% 322,068,688 100.000%
Sector automóvil 16,043,749 22.932% 12,027,638 13.802% 44,216,996 15.243% 40,400,906 12.544%
Semimanufacturas 15,417,036 22.036% 20,216,806 23.200% 71,627,090 24.691% 74,014,523 22.981%
Bienes de equipo 14,050,833 20.083% 20,322,937 23.322% 59,110,716 20.377% 68,727,079 21.339%
Alimentación, bebidas y tabaco 10,587,649 15.133% 11,881,800 13.635% 48,634,647 16.765% 35,691,326 11.082%
Manufacturas de consumo 7,403,600 10.582% 8,674,005 9.954% 29,392,062 10.132% 38,702,291 12.017%
Bienes de consumo duradero 2,380,397 3.402% 2,543,579 2.919% 4,593,328 1.583% 8,508,190 2.642%
Productos energéticos 1,463,212 2.091% 7,273,590 8.347% 21,154,087 7.292% 44,396,482 13.785%
Materias primas 1,434,247 2.050% 3,908,597 4.485% 7,079,278 2.440% 10,182,710 3.162%
Otras mercancías 1,181,489 1.689% 293,346 0.337% 4,280,870 1.476% 1,445,181 0.449%

Medios de transporte más utilizados

En estos gráficos circulares podemos identificar los medios de transporte más utilizados por el sector exterior español. Cabe destacar que desde 1995 se ha reducido la importancia del transporte por carretera a favor del marítimo. También me gustaría destacar el poco peso del transporte por ferrocaril, siendo que España tiene unas muy buenas infraestructuras férreas el ferrocarril podría ser una opción de transporte más sostenible que el transporte por carretera.

Código

La realización de este gráfico es realmente sencilla, ya que simplemente hay que añadir un geom_bar() junto a un coord_polar(). Además he usado la paleta Set1 del conjunto de paletas Brewer y he puesto la leyenda debajo del gráfico.

ggplot(aa, aes(x = "", y=porc, fill = factor(fila.x))) +
  geom_bar(width = 1, stat = "identity",color = "#000000") +
  coord_polar(theta = "y", start=0) +
  labs(fill=NULL,
       x=NULL,
       y=NULL,
       title="Medios de transporte de mercancías más utilizados",
       caption="Fuente: DataComex") + facet_wrap(vars(columna),nrow = 2, ncol = 2) +
      scale_y_continuous(breaks = seq(0,0.8,0.2),labels = scales::percent) +
      scale_fill_brewer(palette = "Set1") +
      theme( strip.background = element_blank(),
              panel.background = element_rect( fill = "#ffffff", colour = "#ffffff" ),
              panel.grid  = element_line( colour ="#ffffff"),
              axis.ticks = element_line(colour = "#ffffff"),
              axis.text = element_text(size = 10, face = "bold", color = "#000000"),
              axis.line = element_blank(),
              plot.title = element_text(hjust = 0.5),
              plot.background = element_rect(fill = "#ffffff"),
              panel.border = element_blank(),
              legend.background = element_rect(fill = "#ffffff", colour = "#ffffff"),
              strip.text = element_text(face = "bold",colour = "black"),
              legend.position = "bottom")

4. Trabajos en los que te has basado

No he utilizado ningún trabajo en especifico como referencia, la estructura y gráficos del trabajo han sido idea mia. La mayoría de problemas que he tenido los he resuelto gracias al foro stackoverflow y a la web de la asignatura.En cuanto al diseño de los gráficos, he cogido ideas de esta página web. También me ha resultado muy útil esta viñeta para crear los temas.

LS0tDQp0aXRsZTogIkVsIGNvbWVyY2lvIGV4dGVyaW9yIGVzcGHDsW9sIg0Kc3VidGl0bGU6ICJIdWdvIE1hcnRpbiBDaGlzdmVydChtYXJ0aWluQGFsdW1uaS51di5lcykiICMtIHBvbmdvIHTDuiBub21icmUgYWjDrSBwYXJhIHEgYXBhcmV6Y2EgbcOhcyBncmFuZGUgcSBlbCBkZSBsYSBVVg0KYXV0aG9yOiAiVW5pdmVyc2l0YXQgZGUgVmFsw6huY2lhIg0KZGF0ZTogIkRpY2llbWJyZSBkZSAyMDIwIChhY3R1YWxpemFkbyBlbCBgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkLSVtLSVZJylgKSINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICAjY3NzOiAiLi9hc3NldHMvbXlfY3NzX2ZpbGUuY3NzIg0KICAgIHRoZW1lOiBwYXBlcg0KICAgIGhpZ2hsaWdodDogdGV4dG1hdGUgDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2RlcHRoOiAzIA0KICAgIHRvY19mbG9hdDogDQogICAgICBjb2xsYXBzZWQ6IHRydWUNCiAgICAgIHNtb290aF9zY3JvbGw6IHRydWUNCiAgICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQ0KICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UNCiAgICBkZl9wcmludDoga2FibGUNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlDQotLS0NCg0KYGBge3IgcGFja2FnZXMtc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShrbGlwcHkpICAjLSByZW1vdGVzOjppbnN0YWxsX2dpdGh1Yigicmxlc3VyL2tsaXBweSIpDQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeShrYWJsZUV4dHJhKQ0KbGlicmFyeShyaW8pDQpsaWJyYXJ5KGhlcmUpDQpsaWJyYXJ5KHN0cmluZ3IpDQpsaWJyYXJ5KGZvcmNhdHMpDQpsaWJyYXJ5KERUKQ0KbGlicmFyeShzY2FsZXMpDQpsaWJyYXJ5KG5hbmlhcikNCmxpYnJhcnkoZ2d0ZXh0KQ0KYGBgDQoNCmBgYHtyIGNodW5rLXNldHVwLCBpbmNsdWRlID0gRkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIGV2YWwgPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgDQogICAgICAgICAgICAgICAgICAgICAgI3Jlc3VsdHMgPSAiaG9sZCIsDQogICAgICAgICAgICAgICAgICAgICAgY2FjaGUgPSBGQUxTRSwgY2FjaGUucGF0aCA9ICIvY2FjaGVzLyIsIGNvbW1lbnQgPSAiIz4iLA0KICAgICAgICAgICAgICAgICAgICAgICNmaWcud2lkdGggPSA3LCAjZmlnLmhlaWdodD0gNywgICANCiAgICAgICAgICAgICAgICAgICAgICAjb3V0LndpZHRoID0gNywgb3V0LmhlaWdodCA9IDcsDQogICAgICAgICAgICAgICAgICAgICAgY29sbGFwc2UgPSBUUlVFLCAgZmlnLnNob3cgPSAiaG9sZCIsDQogICAgICAgICAgICAgICAgICAgICAgZmlnLmFzcCA9IDcvOSwgb3V0LndpZHRoID0gIjYwJSIsIGZpZy5hbGlnbiA9ICJjZW50ZXIiKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGRldiA9ICJwbmciLCBkZXYuYXJncyA9IGxpc3QodHlwZSA9ICJjYWlyby1wbmciKSkNCmBgYA0KDQpgYGB7ciBvcHRpb25zLXNldHVwLCBpbmNsdWRlID0gRkFMU0V9DQpvcHRpb25zKHNjaXBlbiA9IDk5OSkgIy0gcGFyYSBxdWl0YXIgbGEgbm90YWNpw7NuIGNpZW50w61maWNhDQpvcHRpb25zKCJ5YW1sLmV2YWwuZXhwciIgPSBUUlVFKSANCmBgYA0KDQoNCmBgYHtyIGtsaXBweSwgZWNobyA9IEZBTFNFfQ0Ka2xpcHB5OjprbGlwcHkocG9zaXRpb24gPSBjKCJ0b3AiLCAicmlnaHQiKSkgIy0gcmVtb3Rlczo6aW5zdGFsbF9naXRodWIoInJsZXN1ci9rbGlwcHkiKQ0KYGBgDQoNCjxociBjbGFzcz0ibGluZWEtYmxhY2siPg0KDQpUcmFiYWpvIGVsYWJvcmFkbyBwYXJhIGxhIGFzaWduYXR1cmEgIlByb2dyYW1hY2nDs24geSBtYW5lam8gZGUgZGF0b3MgZW4gbGEgZXJhIGRlbCBCaWcgRGF0YSIgZGUgbGEgVW5pdmVyc2l0YXQgZGUgVmFsw6huY2lhIGR1cmFudGUgZWwgY3Vyc28gMjAyMC0yMDIxLiBFbCByZXBvIGRlbCB0cmFiYWpvIGVzdMOhIFthcXXDrV0oaHR0cHM6Ly9naXRodWIuY29tL3hpNzY1L3RyYWJham9fQmlnRGF0YSl7dGFyZ2V0PSJfYmxhbmsifS4gTGEgcMOhZ2luYSB3ZWIgZGUgbGEgYXNpZ25hdHVyYSB5IGxvcyB0cmFiYWpvcyBkZSBtaXMgY29tcGHDsWVyb3MgcHVlZGVuIHZlcnNlIFthcXXDrV0oaHR0cHM6Ly9wZXJlenA0NC5naXRodWIuaW8vaW50cm8tZHMtMjAtMjEtd2ViLzA3LXRyYWJham9zLmh0bWwpe3RhcmdldD0iX2JsYW5rIn0uDQoNCjwhLS0gRWwgcMOhcnJhZm8gZGUgYXJyaWJhIGhhcyBkZSBkZWphcmxvIGNhc2kgaWd1YWwsIA0KICAgICAgICBzb2xvIEhBUyBkZSBTVVNUSVRVSVIgbGFzIDIgdmVjZXMgcXVlIGFwYXJlY2UgInBlcmV6cDQ0IiBwb3IgdHUgdXN1YXJpbyBkZSBHaXRodWItLT4NCg0KPGhyIGNsYXNzPSJsaW5lYS1yZWQiPg0KDQojIDEuIEludHJvZHVjY2nDs24NCg0KTGEgcmF6w7NuIHBvciBsYSBxdWUgaGUgZXNjb2dpZG8gaGFjZXIgbWkgdHJhYmFqbyBzb2JyZSBlc3RlIHRlbWEgZXMgbWkgaW50ZXLDqXMgcG9yIGVsIGNvbWVyY2lvIGludGVybmFjaW9uYWwsIHlhIHF1ZSBlcyBpbnRlcmVzYW50ZSBlIGltcG9ydGFudGUgcGFyYSBsYSBlY29ub23DrWEuIA0KDQpFbiBjdWFudG8gYWwgb2JqZXRpdm8gZGVsIHRyYWJham8sIHByaW5jaXBhbG1lbnRlIGVzIHBvZGVyIHJlZmxlamFyIGRlIG1hbmVyYSBzZW5jaWxsYSB0YW50byBsYSBlc3RydWN0dXJhIGRlbCBzZWN0b3IgZXh0ZXJpb3IgZXNwYcOxb2wgY29tbyBzdSBzaXR1YWNpw7NuIGEgbml2ZWwgaW50ZXJuYWNpb25hbC4NCg0KIyAyLiBEYXRvcw0KDQpMYSBmdWVudGUgcHJpbmNpcGFsIGRlIGxvcyBkYXRvcyBwYXJhIG1pIHByb3llY3RvIGhhIHNpZG8gZWwgcG9ydGFsIERhdGFDb21leCwgcXVlIGVzIGFkbWluaXN0cmFkbyBwb3IgZWwgTWluaXN0ZXJpbyBkZSBjb21lcmNpbywgaW5kdXN0cmlhIHkgdHVyaXNtby4gRXN0ZSBwb3J0YWwgb2ZyZWNlIHVuYSBncmFuIHZhcmllZGFkIGRlIGRhdG9zIHNvYnJlIGVsIGNvbWVyY2lvIGVzcGHDsW9sLCBzaWVuZG8gZWwgbcOhcyBjb21wbGV0byBkZSB0b2RvcyBsb3MgcXVlIGhlIGNvbnN1bHRhZG8uIFNpbiBlbWJhcmdvLCB0aWVuZSBhbGd1bm9zIGluY29udmVuaWVudGVzIHJlc3BlY3RvIGEgb3Ryb3MgcG9ydGFsZXMgY29tbyBldXJvc3RhdC4gRWwgbWF5b3IgaW5jb252ZW5pZW50ZSBkZSBlc3RlIHBvcnRhbCBxdWUgaGUgZW5jb250cmFkbyBkdXJhbnRlIGxhIHJlYWxpemFjacOzbiBkZWwgcHJveWVjdG8gaGFuIHNpZG8gbG9zIGFjZW50b3MsIHlhIHF1ZSBhbCBjYXJnYXJsb3MgZW4gUiBhcGFyZWPDrWFuIGRlIGVzdGEgZm9ybWE6IEFuZGFsdWPDg8KtYS4gTcOhcyBhZGVsYW50ZSBleHBsaWNhcsOpIGPDs21vIGhlIHJlc3VlbHRvIGVzdGUgcHJvYmxlbWEuIEVuIGN1YW50byBhIGxhIG9idGVuY2nDs24gZGUgbG9zIGRhdG9zLCBlc3RhIHBsYXRhZm9ybWEgbm8gdGllbmUgQVBJIHBvciBsbyBxdWUgaGUgcmVjdXJyaWRvIGEgZGVzY2FyZ2FyIGxvcyBkYXRvcyBhIHRyYXbDqXMgZGVsIG5hdmVnYWRvciB5IGNhcmdhcmxvcyBlbiBnaXRodWIuDQoNCkV4Y2VwY2lvbmFsbWVudGUgaGUgdXRpbGl6YWRvIGRhdG9zIGRlIGxhIG9yZ2FuaXphY2nDs24gbXVuZGlhbCBkZWwgY29tZXJjaW8gKE9NQykgeSBkZWwgQmFuY28gTXVuZGlhbC4gQSBwZXNhciBkZSBxdWUgZXN0YXMgcGxhdGFmb3JtYXMgc2kgcXVlIGN1ZW50YW4gY29uIHVuYSBBUEksIGNvbW8gc8OzbG8gbGFzIGhlIHV0aWxpemFkbyBkZSBtYW5lcmEgZXhjZXBjaW9uYWwgaGUgcmVjdXJyaWRvIGFsIG1pc21vIG1ldG9kbyBkZSBvYnRlbmNpw7NuIGRlIGxvcyBkYXRvcyBhbnRlcmlvcjogZGVzY2FyZ2FybG9zIGEgdHJhdsOpcyBkZWwgbmF2ZWdhZG9yIHkgY2FyZ2FybG9zIGVuIGdpdGh1Yi4NCg0KIyMgMi4xLiBQcm9ibGVtYXMgbGltcGlhbmRvIGxvcyBkYXRvcw0KDQpFbCBwcm9jZXNhZG8gZGUgbG9zIGRhdG9zIGhhIHNpZG8gY29uIGRpZmVyZW5jaWEgbGEgcGFydGUgbcOhcyBsYWJvcmlvc2EuIEEgY29udGludWFjacOzbiBleHBsaWNhcsOpIGFsZ3Vub3MgZGUgbG9zIHByb2JsZW1hcyBhIGxvcyBxdWUgaGUgdGVuaWRvIHF1ZSBoYWNlciBmcmVudGUuDQoNCkVsIHByaW1lciBwcm9ibGVtYSBjb24gZWwgcXVlIG1lIGVuY29udHLDqSBlcyB1biBlamVtcGxvIHBlcmZlY3RvIGRlIGPDs21vIHJlc29sdmVyIHVuIHBlcXVlw7FvIHByb2JsZW1hIGRlIHByb2dyYW1hY2nDs24sIHF1ZSBhIHNpbXBsZSB2aXN0YSBwYXJlY2UgdW5hIHRvbnRlcsOtYSwgcHVlZGUgbGxldmFyIGhvcmFzIHkgaG9yYXMuDQoNCkxvcyBkYXRvcyBkZWwgUElCIGFudWFsIGRlIHRvZG9zIGxvcyBwYcOtc2VzIGRlbCBtdW5kbywgZGUgbG9zIGN1YWxlcyBzw7NsbyBhY2FiZSB1dGlsaXphbmRvIGxvcyBkYXRvcyBkZSBFc3Bhw7FhIGUgSXRhbGlhLCBwcmVzZW50YWJhIGxvcyBhw7FvcyBkZSBsYSBzaWd1aWVudGUgZm9ybWEgOiANCmBgYHtyLCBlY2hvPUZBTFNFfQ0KZGF0b3MgPC0gImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS94aTc2NS9NaVByb3llY3RvSW5kaXZpZHVhbEFyY2hpdm9zL21haW4vR0RQV29ybGQuY3N2Ig0KZGZiIDwtIHJpbzo6aW1wb3J0KGRhdG9zKSU+JSBzZWxlY3QoYyg0NTo1MCkpICU+JSBzbGljZSgwKQ0KZGZiDQpgYGANCkNvbW8gc2UgcHVlZGUgb2JzZXJ2YXIsIHNvYnJhbiB0YW50byBsb3MgY29yY2hldGVzIGNvbW8gc3UgY29udGVuaWRvLiBBIHBlc2FyIGRlIHF1ZSB5YSBjb25vY8OtYSBsYSBmdW5jacOzbiBzdHJfcmVtb3ZlX2FsbCgpLCBlbCBwYXRyw7NuIGRlIGRpY2hhIGZ1bmNpw7NuIGhheSBxdWUgZXNjcmliaXJsbyBlbiBsZW5ndWFqZSByZWdleC4gRGljaG8gbGVuZ3VhamUgbWUgZXMgdG90YWxtZW50ZSBkZXNjb25vY2lkbywgcG9yIGxvIHF1ZSBkZXNwdcOpcyBkZSBlc3RhciBob3JhcyBwcm9iYW5kbyBkaWZlcmVudGVzIGNvbWJpbmFjaW9uZXMgeSBidXNjYW5kbyBpbmZvcm1hY2nDs24gaGFsbMOpIGxhIHJlc3B1ZXN0YSBlbiB1biBwb3N0IGRlIHN0YWNrb3ZlcmZsb3cuIExhIHNvbHVjacOzbiBmdWUgbGEgc2lndWllbnRlOg0KYGBge3IsIGV2YWwgPSBGQUxTRX0NCm11dGF0ZShuYW1lID0gc3RyX3JlbW92ZV9hbGwobmFtZSwiXFxbW15cXF1dKlxcXSIpDQpgYGANCg0KRW4gY3VhbnRvIGEgbG9zIGRhdG9zIHByb2NlZGVudGVzIGRlbCBwb3J0YWwgRGF0YUNvbWV4LCBtZSBoZSBlbmNvbnRyYWRvIGRvcyBwcm9ibGVtYXMgcmVjdXJyZW50ZXM6IGVsIGZvcm1hdG8gZGUgbG9zIG7Dum1lcm9zIHkgbG9zIGFjZW50b3MuIA0KDQpFbCBwcm9ibGVtYSBkZSBsb3MgbsO6bWVyb3MgZnVlIHJlbGF0aXZhbWVudGUgc2VuY2lsbG8gZGUgc29sdWNpb25hciwgdW5hIHZleiBjYcOtIGVuIHF1ZSBsYSByYXrDs24gcG9yIGxhIHF1ZSBubyBtZSBkZWphYmEgY2FtYmlhciBlbCBmb3JtYXRvIGRlIGNhcsOhY3RlciBhIG51bcOpcmljbyBlcmEgZWwgZm9ybWF0byBkZSBsb3MgbsO6bWVyb3MgZnVlIHNlbmNpbGxvIGRlIHNvbHVjaW9uYXIuIENvbiBsYSB5YSBtZW5jaW9uYWRhIGZ1bmNpw7NuIHN0cl9yZXBsYWNlKCkgY2FtYmnDqSBsYXMgY29tYXMgZGUgbG9zIGRlY2ltYWxlcyBwb3IgcHVudG9zLCB1c2FuZG8gZWwgc2lndWllbnRlIGPDs2RpZ286DQpgYGB7ciwgZXZhbD0gRkFMU0V9DQptdXRhdGUodmFsb3IgPSBzdHJfcmVwbGFjZSh2YWxvciwiWyxdIiwiLiIpKQ0KYGBgDQoNCkxvcyBhY2VudG9zIGZ1ZXJvbiBtw6FzIGRpZsOtY2lsZXMgZGUgc29sdWNpb25hciwgeWEgcXVlIG5vIHPDs2xvIHR1dmUgcXVlIGRlZGljYXJsZSBiYXN0YW50ZSB0aWVtcG8gYSBwZW5zYXIgbGEgc29sdWNpw7NuLCBzaW5vIHF1ZSBsYSBwcm9waWEgc29sdWNpw7NuIG5vIGVyYSB0b2RvIGxvIHLDoXBpZGEgcXVlIG1lIGh1YmllcmEgZ3VzdGFkby4gQ29tbyB5YSBoZSBtZW5jaW9uYWRvIGVuIGVsIHB1bnRvIGFudGVyaW9yLCBhbCBjYXJnYXIgbG9zIGRhdG9zIGVuIFIgbG9zIGFjZW50b3MgYXBhcmVjw61hbiBkZSBsYSBzaWd1aWVudGUgZm9ybWE6ICJBbmRhbHVjw4PCrWEiLiBQYXJhIHNvbHVjaW9uYXIgZXN0ZSBwcm9ibGVtYSB1c8OpIGxhIGZ1bmNpw7NuIGNhc2Vfd2hlbigpLCBlbXBsZWFuZG8gZWwgc2lndWllbnRlIGPDs2RpZ286DQpgYGB7ciwgZXZhbD0gRkFMU0V9DQptdXRhdGUoY29sdW1uYSA9IGNhc2Vfd2hlbihjb2x1bW5hID09ICJBbmRhbHVjw4PCrWEiIH4gIkFuZGFsdWPDrWEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uYSA9PSAiQXJhZ8ODwrNuIiB+ICJBcmFnw7NuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbmEgPT0gIkNhc3RpbGxhIHkgTGXDg8KzbiIgfiAiQ2FzdGlsbGEgeSBMZcOzbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW5hID09ICJDYXRhbHXDg8KxYSIgfiAiQ2F0YWx1w7FhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbmEgPT0gIk11cmNpYSwgUmVnacODwrNuIGRlIiB+ICJNdXJjaWEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uYSA9PSAiUGHDg8KtcyBWYXNjbyIgfiAiUGHDrXMgVmFzY28iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbmEgPT0gY29sdW1uYSB+IGNvbHVtbmEpKQ0KYGBgDQoNCkVzdG9zIGhhbiBzaWRvIHPDs2xvIGFsZ3Vub3MgZGUgbG9zIGluY29udmVuaWVudGVzIHF1ZSBtZSBoZSBlbmNvbnRyYWRvIGR1cmFudGUgbGEgbGltcGllemEgZGUgbG9zIGRhdG9zLCB5YSBxdWUgcmVhbG1lbnRlIGhhbiBzaWRvIG11Y2hvcyBtw6FzLiBBZGVtw6FzIGRlIGxvcyB5YSBtZW5jaW9uYWRvcywgdGFtYmnDqW4gaGUgdGVuaWRvIHF1ZTogb3JkZW5hciBsYXMgdmFyaWFibGVzIHVzYW5kbyBmYWN0b3JlcywgcGl2b3RhciBsYXMgdGFibGFzLCBhZ3J1cGFyLCBmaWx0cmFyLCBoYWNlciBtdXRhdGVzLCBjYW1iaWFyIG5vbWJyZXMgZGUgbGFzIHZhcmlhYmxlcyBldGMuLi4gRW4gZGVmaW5pdGl2YTogSGUgYXBsaWNhZG8gdG9kbyBsbyBxdWUgaGVtb3MgZXN0dWRpYWRvIGRlIGxhIG1lam9yIG1hbmVyYSBxdWUgaGUgc2lkbyBjYXBhei4NCg0KIyMgMi4yIFByb2Nlc2FkbyBkZSBkYXRvcw0KDQpBIGNvbnRpbnVhY2nDs24gcHJlc2VudGFyw6kgeSBleHBsaWNhcsOpIGJyZXZlbWVudGUgZWwgY8OzZGlnbyBxdWUgaGUgdXRpbGl6YWRvIHBhcmEgbGltcGlhciB0b2RvcyBsb3MgZGF0b3MuDQoNCiMjIyBEYXRvcyBkZWwgQmFuY28gTXVuZGlhbA0KDQpBZGVtw6FzIGRlbCB5YSBtZW5jaW9uYWRvIHByb2JsZW1hIGRlbCBmb3JtYXRvIGRlIGxhIGZlY2hhLCBsb3MgZGF0b3MgZGVsIEJhbmNvIE11bmRpYWwgdGFtYmnDqW4gbWUgb2Nhc2lvbmFyb24gcHJvYmxlbWFzIGNvbiBsb3MgTkFzLiBFc3RvcyBkYXRvcyByZXByZXNlbnRhYmFuIGxvcyBOQXMgY29uICIuLiIsIGxvIHF1ZSB0YW1iacOpbiBtZSBsbGV2w7MgdHJhYmFqbyBjb3JyZWdpci4gRmluYWxtZW50ZSBsbyBzb2x1Y2lvbsOpIGNvbiBsYSBmdW5jacOzbiByZXBsYWNlX3dpdGhfbmEoKSBkZWwgcGFxdWV0ZSBuYW5pYXIuIEFkZW3DoXMgZGUgZXNvLCB0cmFuc2Zvcm3DqSBsYSB0YWJsYSBhIGZvcm1hdG8gbGFyZ28sIGNhbWJpw6kgbG9zIHZhbG9yZXMgZGVsIFBJQiBkZSBkw7NsYXJlcyBhIE1pbGxvbmVzIGRlIGTDs2xhcmVzIHkgcmVub21icsOpIGxhcyB2YXJpYWJsZXMgY29uIGxhIGZ1bmNpw7NuIHNldE5hbWVzKCkuIEZpbmFsbWVudGUgZXhwb3J0w6kgbG9zIGRhdG9zIGxpbXBpb3MgeSBsb3Mgc3Viw60gYSBnaXRodWIuDQpgYGB7cixldmFsPUZBTFNFfQ0KZGF0b3MgPC0gaGVyZTo6aGVyZSgiRGF0YSIsIkdEUFdvcmxkLmNzdiIpDQojTGltcGllemENCmRmYSA8LSByaW86OmltcG9ydChkYXRvcykgJT4lIHBpdm90X2xvbmdlcihjb2xzID0gNTo2NSkgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3QoLWMoMikpICU+JSBuYW5pYXI6OnJlcGxhY2Vfd2l0aF9uYShyZXBsYWNlID0gbGlzdCh2YWx1ZSA9ICIuLiIpKSU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKG5hbWUgPSBzdHJfcmVtb3ZlX2FsbChuYW1lLCJcXFtbXlxcXV0qXFxdIiksIG5hbWUgPSBhcy5udW1lcmljKG5hbWUpLCB2YWx1ZSA9IGFzLm51bWVyaWModmFsdWUpLCB2YWx1ZSA9ICh2YWx1ZS8xMDAwMDAwKSkgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXROYW1lcyhjKCJpbmRpY2Fkb3IiLCJjb3VudHJ5IiwiY291bnRyeWlzbzNjb2RlIiwieWVhciIsInZhbHVlIikpICNBaG9yYSBlc3TDoSBlbiBNaWxsb25lcyBkZSBkb2xhcmVzDQojRXhwb3J0YWNpw7NuDQpyaW86OmV4cG9ydChkZmEsZmlsZSA9IGhlcmU6OmhlcmUoIkRhdGEiLCJHRFBXb3JsZEMuY3N2IikpDQpgYGANCg0KIyMjIE9yZ2FuaXphY2nDs24gTXVuZGlhbCBkZWwgQ29tZXJjaW8NCg0KTG9zIGRhdG9zIGRlIGxhcyBpbXBvcnRhY2lvbmVzIHkgZXhwb3J0YWNpb25lcyBwb3IgcGHDrXMgZnVlcm9uIGxpZ2VyYW1lbnRlIG3DoXMgc2VuY2lsbG9zIGRlIGxpbXBpYXIgcXVlIGxvcyBkZWwgQmFuY28gTXVuZGlhbCwgYXVucXVlIHNlZ3XDrSBlbCBtaXNtbyBwcm9jZWRpbWllbnRvOiBsb3MgaW1wb3J0w6ksIGxvcyBsaW1wacOpLCBsb3MgZXhwb3J0w6kgeSBsb3Mgc3Viw60gYSBnaXRodWIuIExhIGxpbXBpZXphIGRlIGVzdG9zIGRhdG9zIGLDoXNpY2FtZW50ZSBjb25zaXN0acOzIGVuOiBlbGltaW5hciBjb2x1bW5hcyBpcnJlbGV2YW50ZXMgY29uIHNlbGVjdCgpIHkgcmV1YmljYXJsYXMgY29uIHJlbG9jYXRlKCksZmlsdHJhciBsb3MgZGF0b3MgcGFyYSBxdWVkYXJtZSBzw7NsbyBjb24gbG9zIGRhdG9zIHRvdGFsZXMgeSBjYW1iaWFyIGxvcyBub21icmVzIHRhbnRvIGRlIGZpbGFzIGNvbW8gZGUgY29sdW1uYXMuIFF1aXrDoSBsbyBtw6FzIHJlbGV2YW50ZSBkZSBlc3RlIHRyb3pvIGRlIGPDs2RpZ28gZnVlIHF1ZSB1dGlsaWPDqSBsYSBmdW5jacOzbiBpZl9lbHNlKCkgcGFyYSBjYW1iaWFyIGxvcyBub21icmVzIGRlIGxvcyBpbmRpY2Fkb3JlcyBkZSBpbXBvcnRhY2lvbmVzIHkgZXhwb3J0YWNpb25lcy4NCmBgYHtyLCBldmFsPUZBTFNFfQ0KZGF0b3MgPC0gaGVyZTo6aGVyZSgiRGF0YSIsIlhNV29ybGQuY3N2IikNCiNMaW1waWV6YQ0KZGZiIDwtIHJpbzo6aW1wb3J0KGRhdG9zKSAlPiUgc2VsZWN0KC1jKDEsMiw3LDgsOSwxNiwxNywyMSwyMiwyMykpICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW5hbWUoInByb2R1Y3RfY29kZSIgPSA3KSAlPiUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKHByb2R1Y3RfY29kZSA9PSAiVE8iKSAlPiUgc2VsZWN0KC1jKDU6MTEpKSAlPiUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKEluZGljYXRvciA9IGlmX2Vsc2UoSW5kaWNhdG9yPT0iTWVyY2hhbmRpc2UgaW1wb3J0cyBieSBwcm9kdWN0IGdyb3VwIOKAkyBhbm51YWwiLCJpbXBvcnRzeSIsImV4cG9ydHN5IikpICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWxvY2F0ZSg2LC5hZnRlciA9IDQpICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXROYW1lcyhjKCJpbmRpY2Fkb3IiLCJjb3VudHJ5Y29kZSIsImNvdW50cnlpc28zY29kZSIsImNvdW50cnkiLCJ5ZWFyIiwidW5pZGFkIiwidmFsdWUiKSkNCiNFeHBvcnRhY2nDs24NCnJpbzo6ZXhwb3J0KGRmYixmaWxlID0gaGVyZTo6aGVyZSgiRGF0YSIsIlhNV29ybGRDLmNzdiIpKQ0KYGBgDQoNCiMjIyBEYXRhQ29tZXgNCg0KRW4gcHJpbWVyIGx1Z2FyIGRlc2Nhcmd1w6kgbGFzIGltcG9ydGFjaW9uZXMgeSBleHBvcnRhY2lvbmVzIGFudWFsZXMgdG90YWxlcyBkZSBFc3Bhw7FhLiBUcsOhcyBzdWJpcmxvcyBhIGdpdGh1YiBwcm9jZWTDrSBhIGxpbXBpYXJsb3MuIEVzdG9zIGRhdG9zIGVzdGFiYW4gYmFzdGFudGUgbGltcGlvcywgcG9yIGxvIHF1ZSBzb2xhbWVudGUgdHV2ZSBxdWUgaGFjZXIgdW4gcGFyIGRlIG1vZGlmaWNhY2lvbmVzLiBDYW1iacOpIGxvcyBub21icmVzIGRlIGxhcyB2YXJpYWJsZXMsIGVzdGEgdmV6IHVzYW5kbyBsYSBmdW5jacOzbiByZW5hbWVfYXQoKSBkZWwgcGFxdWV0ZSBkeXBsciwgY2FtYmnDqSBlbCBmb3JtYXRvIGRlIGxvcyBuw7ptZXJvcyB1c2FuZG8gZWwgbWV0b2RvIGV4cGxpY2FkbyBhbnRlcmlvcm1lbnRlIHkgcG9yIMO6bHRpbW8gZmlsdHLDqSBsYXMgZmVjaGFzIHBhcmEgZWxpbWluYXIgYWxndW5vcyBkYXRvcyBpcnJlbGV2YW50ZXMuDQpgYGB7ciwgZXZhbD1GQUxTRX0NCnVybCA8LSAiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3hpNzY1L01pUHJveWVjdG9JbmRpdmlkdWFsQXJjaGl2b3MvbWFpbi9EYXRhQ29tZXhfMjAxMTMwMTIyMDM2LmNzdiINCmRhdGEgPC0gcmVhZC5jc3YodXJsKSAlPiUgcmVuYW1lX2F0KHZhcnMoY29sbmFtZXMoZGF0YSkpLCB+IGMoIkNvdW50cnkiLCJEYXRlIiwiQ29sdW1uYSIsIlZhcmlhYmxlIiwiVmFsb3IiKSkgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoRGF0ZSAhPSAiVG90YWwgRmVjaGFzIikgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUoVmFsb3IgPSBzdHJpbmdyOjpzdHJfcmVwbGFjZShWYWxvciwiKFssXSkiLCIuIiksVmFsb3IgPSBhcy5udW1lcmljKFZhbG9yKSwgRGF0ZSA9IGFzLm51bWVyaWMoRGF0ZSkpDQoNCmBgYA0KDQpFbiBzZWd1bmRvIGx1Z2FyIGJ1c3F1w6kgbG9zIGRhdG9zIGRlIGltcG9ydGFjaW9uZXMgeSBleHBvcnRhY2lvbmVzIGVzcGHDsW9sYXMgcG9yIGNvbnRpbmVudGUgZGUgb3JpZ2VuIHkgZGVzdGluby4gQWwgaWd1YWwgcXVlIGxvcyBkYXRvcyBhbnRlcmlvcmVzLCBsb3MgYWxvasOpIGVuIGdpdGh1Yi4gVHV2ZSBwcm9ibGVtYXMgY29uIGxvcyBub21icmVzIGRlIGxvcyBjb250aW5lbnRlcywgeWEgcXVlIGVsIGZvcm1hdG8gbm8gZXJhIGFkZWN1YWRvIHkgYWRlbcOhcyBhbGd1bm9zIG5vbWJyZXMgdGVuw61hbiBhY2VudG9zLiBQYXJhIHNvbHVjaW9uYXIgZXN0ZSBwcm9ibGVtYSBvcHTDqSBwb3IgbGEgeWEgbWVuY2lvbmFkYSBmdW5jacOzbiBjYXNlX3doZW4oKSwgY29uIGxhIHF1ZSBjYW1iacOpIGxvcyBub21icmVzIGFudGlndW9zIHBvciB1bm9zIG3DoXMgY2xhcm9zLiBBIHBhcnRpciBkZSBlc3RvcyBkYXRvcyBoaWNlIGRvcyB0YWJsYXMgZGlzdGludGFzOiB1bmEgY29uIGxhcyBleHBvcnRhY2lvbmVzIGUgaW1wb3J0YWNpb25lcyBwb3IgY29udGluZW50ZSB5IG90cmEgY29uIGxhIGV2b2x1Y2nDs24gZGUgZXN0b3MgbWlzbW9zIGZsdWpvcyBwZXJvIHPDs2xvIGNvbiBsYSBVRSAyOC4gTG8gbcOhcyBjb21wbGVqbyBkZSBlc3RlIGPDs2RpZ28gZnVlIGVsIG9idGVuZXIgbG9zIHBvcmNlbnRhamVzLCB5YSBxdWUgbGEgdmFyaWFibGUgVG90YWwgZXN0YWJhIGVuIGxhIG1pc21hIGNvbHVtbmEgcXVlIGxhcyB2YXJpYWJsZXMgcG9yIGNvbnRpbmVudGUuIFBhcmEgZXh0cmFlciBkaWNoYSB2YXJpYWJsZSB1dGlsaWPDqSB1bmEgY29tYmluYWNpw7NuIGRlIGxhIGZ1bmNpw7NuIGlubmVyX2pvaW4oKSB5IGxhIGZ1bmNpw7NuIGZpbHRlcigpLCBwYXJhIHBvc3Rlcmlvcm1lbnRlIG9idGVuZXIgZWwgcG9yY2VudGFqZSBtZWRpYW50ZSBsYSBmdW5jacOzbiBtdXRhdGUoKS4NCmBgYHtyLCBldmFsPUZBTFNFfQ0KI0V4cG9ydGFjaW9uZXMgZSBpbXBvcnRhY2lvbmVzIHBvciBjb250aW5lbnRlcyBlbiBtaWxsb25lcyBkZSBldXJvcyAoZnVlbnRlIGRhdGFjb21leCkNCmRhdG9zIDwtIGhlcmU6OmhlcmUoIkRhdGEiLCJYTUNvbnRpbmVudGVzLmNzdiIpDQpkZnhtYyA8LSByaW86OmltcG9ydChkYXRvcykgJT4lIGZpbHRlcihzdWJmaWxhICE9ICJUb3RhbCBzZWxlY2Npb25hZG8iKSAlPiUgc2VsZWN0KC1jKDQpKSAlPiUNCm11dGF0ZShmaWxhID0gY2FzZV93aGVuKCBmaWxhID09ICJBRiAtIEFmcmljYSIgfiAiQWZyaWNhIiwgZmlsYSA9PSAiQU0gLSBBbcODwqlyaWNhIiB+ICJBbWVyaWNhIiwgZmlsYSA9PSAiQVMgLSBBc2lhIiB+IkFzaWEiLCBmaWxhID09ICJPQyAtIE9jZWFuw4PCrWEiIH4gIk9jZWFuaWEiLCBmaWxhID09ICJVRSAtIFVuacODwrNuIEV1cm9wZWEgMjggcGHDg8Ktc2VzKGQuMjAxMy0wNyBoLjIwMjAtMDEpIiB+ICJVbmlvbiBFdXJvcGVhICgyOCkiLCBmaWxhID09ICJUb3RhbCBNdW5kbyIgfiAiVG90YWwiKSwgdmFsb3IgPSBzdHJfcmVwbGFjZSh2YWxvciwiWyxdIiwiLiIpLCB2YWxvciA9IGFzLm51bWVyaWModmFsb3IpLCBzdWJmaWxhID0gYXMubnVtZXJpYyhzdWJmaWxhKSkNCiNFWFBPUlRBQ0lPTkVTIFBPUiBDT05USU5FTlRFDQphYSA8LSBpbm5lcl9qb2luKHggPSBkZnhtYyAlPiUgZmlsdGVyKGZpbGEgIT0gIlRvdGFsIikseSA9IGRmeG1jICU+JSBmaWx0ZXIoZmlsYSA9PSAiVG90YWwiKSwgYnkgPSBjKCJjb2x1bW5hIiwic3ViZmlsYSIpKSAlPiUgc2VsZWN0KC1jKDUpKSAlPiUgbXV0YXRlKHBvcmMgPSAodmFsb3IueC92YWxvci55KSkgJT4lIGZpbHRlcihzdWJmaWxhID09IDIwMTkpDQojRVhQT1JUQUNJT05FUyBFIElNUE9SVEFDSU9ORVMgQSBMQSBVRQ0KZGZleHBjIDwtIGRmeG1jICU+JSBmaWx0ZXIoZmlsYSA9PSAiVW5pb24gRXVyb3BlYSAoMjgpIikNCmRmZXhwY2IgPC0gaW5uZXJfam9pbihkZmV4cGMsZXNweG0sIGJ5ID0gYygic3ViZmlsYSI9IkRhdGUiLCJjb2x1bW5hIj0iVmFyaWFibGUiKSkgJT4lIHNlbGVjdCgtYyg1KSkgJT4lIG11dGF0ZSh2YWxvcnBvcmMgPSAodmFsb3IvVmFsb3JNKSkNCmBgYA0KRW4gdGVyY2VyIGx1Z2FyIGJ1c3F1w6kgbG9zIGZsdWpvcyBjb21lcmNpYWxlcyBkZSBFc3Bhw7FhIGNvbiBlbCByZXN0byBkZSBwYcOtc2VzLiBMYSBsaW1waWV6YSBkZSBlc3RvcyBkYXRvcyBmdWUgc2VuY2lsbGEsIHNpbXBsZW1lbnRlIHJlcGV0w60gbG9zIHBhc29zIHF1ZSB5YSBoZSBkZXNjcml0byBhbnRlcmlvcm1lbnRlLCBjb24gbGEgZXhjZXBjacOzbiBkZSBxdWUgaGljZSB1biBzbGljZV9tYXgoKSBwYXJhIHF1ZWRhcm1lIHNvbGFtZW50ZSBjb24gbG9zIDEwIHBhw61zZXMgbcOhcyByZWxldmFudGVzLiBFc3RhIHRhYmxhIHRhbWJpw6luIGxhIGRpdmlkw60gZW4gZG9zIG51ZXZhcyB0YWJsYXM6IHVuYSByZWxhdGl2YSBhIGxhcyBleHBvcnRhY2lvbmVzIHkgdW5hIGEgbGFzIGltcG9ydGFjaW9uZXMuDQpgYGB7ciwgZXZhbD1GQUxTRX0NCiNFeHBvcnRhY2lvbmVzIGUgaW1wb3J0YWNpb25lcyBwb3IgcGHDrXMgZW4gbWlsbG9uZXMgZGUgZXVyb3MNCmRhdG9zIDwtIGhlcmU6OmhlcmUoIkRhdGEiLCJYTVBhaXMuY3N2IikNCmRmeG1wIDwtIHJpbzo6aW1wb3J0KGRhdG9zKSAlPiUgbXV0YXRlKCB2YWxvciA9IHN0cl9yZXBsYWNlKHZhbG9yLCJbLF0iLCIuIiksIHZhbG9yID0gYXMubnVtZXJpYyh2YWxvcikpDQojRVhQT1JUQUNJT05FUw0KZGZ4cCA8LSBkZnhtcCAlPiUgZmlsdGVyKHN1YmNvbHVtbmEgPT0gIkVYUE9SVCIsIHN1YmZpbGEgPT0gIjIwMTkiLCAhZmlsYSAlaW4lIGMoIlRvdGFsIHNlbGVjY2lvbmFkbyIsIlVFIC0gVW5pw4PCs24gRXVyb3BlYSAyOCBwYcODwq1zZXMoZC4yMDEzLTA3IGguMjAyMC0wMSkiKSkgJT4lIHNsaWNlX21heChvcmRlcl9ieSA9IHZhbG9yLG4gPSAxMCkNCiNJTVBPUlRBQ0lPTkVTDQpkZm1wIDwtIGRmeG1wICU+JSBmaWx0ZXIoc3ViY29sdW1uYSA9PSAiSU1QT1JUIiwgc3ViZmlsYSA9PSAiMjAxOSIsICFmaWxhICVpbiUgYygiVG90YWwgc2VsZWNjaW9uYWRvIiwiVUUgLSBVbmnDg8KzbiBFdXJvcGVhIDI4IHBhw4PCrXNlcyhkLjIwMTMtMDcgaC4yMDIwLTAxKSIpKSAlPiUgc2xpY2VfbWF4KG9yZGVyX2J5ID0gdmFsb3IsbiA9IDEwKQ0KYGBgDQpFbiBxdWludG8gbHVnYXIgYnVzcXXDqSB5IGxpbXDDrWUgbG9zIGRhdG9zIGRlIGZsdWpvcyBjb21lcmNpYWxlcyBwb3IgcHJvZHVjdG8geSBhw7FvIHBhcmEgaGFjZXIgdW5hIHRhYmxhLiBFbiBlc3RlIGPDs2RpZ28gc2kgc2UgcHVlZGUgYXByZWNpYXIgbWF5b3IgY29tcGxlamlkYWQgcXVlIHJlc3BlY3RvIGEgbG9zIGFudGVyaW9yZXMuIEFkZW3DoXMgZGUgZW1wbGVhciBhbGd1bm9zIG1ldG9kb3MgcXVlIHlhIHV0aWxpY8OpIGFudGVyaW9ybWVudGUgY8OzbW8gbGEgZnVuY2nDs24gY2FzZV93aGVuKCkgcGFyYSBhcnJlZ2xhciBsb3Mgbm9tYnJlcyBvIGxhIGNvbWJpbmFjacOzbiBkZSBsYXMgZnVuY2lvbmVzIGlubmVyX2pvaW4oKSB5IGZpbHRlcigpIHBhcmEgc2FjYXIgcG9yY2VudGFqZXMsIHRhbWJpw6luIHV0aWxpY8OpIGFsZ3Vub3MgbnVldm9zLiBQb3IgZWplbXBsbywgZGVzY3VicsOtIGxhcyBmdW5jaW9uZXMgY29tbWEoKSB5IHBlcmNlbnQoKSwgcXVlIHV0aWxpY8OpIHBhcmEgcXVlIGxvcyBkYXRvcyBzZSB2aWVyYW4gbcOhcyBsaW1waW9zIGVuIGxhIHRhYmxhLg0KYGBge3IsIGV2YWw9RkFMU0V9DQojWE0gUE9SIFBST0RVQ1RPIFkgRkVDSEEgRU4gTUlMTE9ORVMgREUgRVVST1MNCmRhdG9zIDwtIGhlcmU6OmhlcmUoIkRhdGEiLCJYTVByb2R1Y3RvLmNzdiIpDQpkZnByb2QgPC0gcmlvOjppbXBvcnQoZGF0b3MpICU+JSBzZWxlY3QoLWMoMikpICU+JSBmaWx0ZXIoY29sdW1uYSAlaW4lIGMoIjIwMTUiLCIyMDE2IiwiMjAxNyIsIjIwMTgiLCIyMDE5IiwiMjAyMCIpKSAlPiUgbXV0YXRlKCB2YWxvciA9IHN0cl9yZXBsYWNlKHZhbG9yLCJbLF0iLCIuIiksIHZhbG9yID0gYXMubnVtZXJpYyh2YWxvcikpDQoNCmEgPC0gaW5uZXJfam9pbih4ID0gZGZwcm9kLCB5ID0gZGZwcm9kICU+JSBmaWx0ZXIoZmlsYSA9PSAiVG90YWwgc2VsZWNjaW9uYWRvIiksIGJ5ID0gYygiY29sdW1uYSIsInN1YmNvbHVtbmEiKSkgJT4lIG11dGF0ZShwb3JjID0gKHZhbG9yLngvdmFsb3IueSkpICU+JSBzZWxlY3QoLWMoNSw2KSkgJT4lIG11dGF0ZShmaWxhLnggPSBjYXNlX3doZW4oZmlsYS54ID09ICJUb3RhbCBzZWxlY2Npb25hZG8iIH4gIlRvdGFsIiwgZmlsYS54ID09ICIxIEFMSU1FTlRBQ0nDg+KAnE4sIEJFQklEQVMgWSBUQUJBQ08iIH4gIkFsaW1lbnRhY2nDs24sIGJlYmlkYXMgeSB0YWJhY28iLCBmaWxhLnggPT0gIjIgUFJPRFVDVE9TIEVORVJHRVRJQ09TIiB+ICJQcm9kdWN0b3MgZW5lcmfDqXRpY29zIiwgZmlsYS54ID09ICIzIE1BVEVSSUFTIFBSSU1BUyIgfiAiTWF0ZXJpYXMgcHJpbWFzIiwgZmlsYS54ID09ICI0IFNFTUlNQU5VRkFDVFVSQVMiIH4gIlNlbWltYW51ZmFjdHVyYXMiLCBmaWxhLnggPT0gIjUgQklFTkVTIERFIEVRVUlQTyIgfiAiQmllbmVzIGRlIGVxdWlwbyIsZmlsYS54ID09ICI2IFNFQ1RPUiBBVVRPTU9WSUwiIH4gIlNlY3RvciBhdXRvbcOzdmlsIixmaWxhLnggPT0gIjcgQklFTkVTIERFIENPTlNVTU8gRFVSQURFUk8iIH4gIkJpZW5lcyBkZSBjb25zdW1vIGR1cmFkZXJvIixmaWxhLnggPT0gIjggTUFOVUZBQ1RVUkFTIERFIENPTlNVTU8iIH4gIk1hbnVmYWN0dXJhcyBkZSBjb25zdW1vIixmaWxhLnggPT0gIjkgT1RSQVMgTUVSQ0FOQ0lBUyIgfiAiT3RyYXMgbWVyY2FuY8OtYXMiKSwgcG9yYyA9IHBlcmNlbnQocG9yYyksIHZhbG9yLnggPSBjb21tYSh2YWxvci54LCBkaWdpdHMgPSAwKSkNCmFhIDwtIGEgJT4lIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBjKHN1YmNvbHVtbmEsY29sdW1uYSksIHZhbHVlc19mcm9tID0gYyh2YWxvci54LHBvcmMpKSAlPiUgcmVuYW1lKCIgIiA9IDEpICU+JSBzZWxlY3QoMSwyLDE0LDMsMTUsNCwxNiw1LDE3LDYsMTgsNywxOSw4LDIwLDksMjEsMTAsMjIsMTEsMjMsMTIsMjQsMTMsMjUpICU+JSBzZXROYW1lcyhjKCIiLCJNaWxsLiBkZSDigqwiLCIlIiwiTWlsbC4gZGUg4oKsIiwiJSIsIk1pbGwuIGRlIOKCrCIsIiUiLCJNaWxsLiBkZSDigqwiLCIlIiwiTWlsbC4gZGUg4oKsIiwiJSIsIk1pbGwuIGRlIOKCrCIsIiUiLCJNaWxsLiBkZSDigqwiLCIlIiwiTWlsbC4gZGUg4oKsIiwiJSIsIk1pbGwuIGRlIOKCrCIsIiUiLCJNaWxsLiBkZSDigqwiLCIlIiwiTWlsbC4gZGUg4oKsIiwiJSIsIk1pbGwuIGRlIOKCrCIsIiUiKSkNCmBgYA0KRW4gc2V4dG8gbHVnYXIgdXRpbGljw6kgZGF0b3MgZGUgZXhwb3J0YWNpb25lcyBlIGltcG9ydGFjaW9uZXMgcG9yIHByb3ZpbmNpYXMsIGF1bnF1ZSBmaW5hbG1lbnRlIHPDs2xvIHVzw6kgbGFzIGV4cG9ydGFjaW9uZXMuIEVsIGPDs2RpZ28geWEgdGllbmUgcG9jbyBudWV2bywgbG8gw7puaWNvIGVzIHF1ZSBlbiBlc3RhIG9jYXNpw7NuIGFkZW3DoXMgZGUgdHJhbnNmb3JtYXIgbG9zIHZhbG9yZXMgYSBNaWxsb25lcyBkZSBldXJvcyB0YW1iacOpbiBsb3MgdHJhbnNmb3Jtw6kgYSBsb2dhcml0bW9zIGNvbiBsYSBmdW5jacOzbiBsb2coKS4NCmBgYHtyLCBldmFsPUZBTFNFfQ0KI1BST1ZJTkNJQVMgTcOBUyBFWFBPUlRBRE9SQVMNCnVybCA8LSAiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3hpNzY1L01pUHJveWVjdG9JbmRpdmlkdWFsQXJjaGl2b3MvbWFpbi9leHBfaW1wX3Byb3ZfMjAxOS5jc3YiDQpleHBwciA8LSByZWFkLmNzdih1cmwpDQpleHBwciA8LSBleHBwciAlPiUgc2VsZWN0KC1jKHN1YmZpbGEsc3ViY29sdW1uYSkpDQpleHBwciA8LSBleHBwciAlPiUgcmVuYW1lX2F0KHZhcnMoY29sbmFtZXMoZXhwcHIpKSwgfiBjKCJQcm92aW5jaWEiLCJWYXJpYWJsZSIsIlZhbG9yIikpDQpleHBwciA8LSBleHBwciAlPiUgbXV0YXRlKFZhbG9yID0gc3RyaW5ncjo6c3RyX3JlcGxhY2UoVmFsb3IsIihbLF0pIiwiLiIpKSAlPiUgbXV0YXRlKFZhbG9yID0gYXMubnVtZXJpYyhWYWxvciksIFZhbG9yRW5NaWxsID0gKFZhbG9yLzEwMDAwMDApLCBWYWxvckxvZyA9IGxvZyhWYWxvciwgYmFzZSA9IGV4cCgyKSkpDQpleHBwciA8LSBleHBwciAlPiUgbXV0YXRlKFZhbG9ycG9yYyA9IChWYWxvci9leHBwclsxLDNdKSkNCmBgYA0KRW4gc2VwdGltbyBsdWdhciBwcmVwYXLDqSBsb3MgZGF0b3MgZGUgZXhwb3J0YWNpb25lcyBwb3IgcHJvZHVjdG8geSBwcm92aW5jaWEgZW4gMjAxOSBwYXJhIGhhY2VyIHVuYSBudWV2YSB0YWJsYS4gRGUgbnVldm8gc2VndcOtIGxvcyBwYXNvcyBkZXNjcml0b3MgYW50ZXJpb3JtZW50ZS4gQ2FiZSBkZXN0YWNhciBxdWUgZXNjcmliaWVuZG8gZXN0ZSBjw7NkaWdvIHR1dmUgcXVlIHZvbHZlciBhIGRlc2NpZnJhciBlbCBsZW5ndWFqZSByZWdleCwgeWEgcXVlICBsb3Mgbm9tYnJlcyBkZSBsb3MgcHJvZHVjdG9zIHRlbsOtYW4gdmFyaW9zIG7Dum1lcm9zIHF1ZSBmaW5hbG1lbnRlIGNvbnNlZ3XDrSBxdWl0YXIgY29uIGxhIHlhIG1lbmNpb25hZGEgZnVuY2lvbiBzdHJfcmVtb3ZlKCkuDQpgYGB7ciwgZXZhbD1GQUxTRX0NCiNEQVRPUyBERSBFWFBPUlRBQ0nDk04gUE9SIFBST0RVQ1RPIFkgUFJPVklOQ0lBIEVOIE1JTExPTkVTIERFIEVVUk9TIDIwMTkNCmRhdG9zIDwtIGhlcmU6OmhlcmUoIkRhdGEiLCJYQ29tUHJvZC5jc3YiKQ0KZGZjY2FhIDwtIHJpbzo6aW1wb3J0KGRhdG9zKSAlPiUgc2VsZWN0KGMoMSwzLDUpKSAlPiUgZmlsdGVyKCFjb2x1bW5hICVpbiUgYygiVG90YWwgTmFjaW9uYWwiLCJObyBkZXRlcm1pbmFkbyIpKSAlPiUgbXV0YXRlKCB2YWxvciA9IHN0cl9yZXBsYWNlKHZhbG9yLCJbLF0iLCIuIiksIHZhbG9yID0gYXMubnVtZXJpYyh2YWxvciksIGZpbGEgPSBzdHJfcmVtb3ZlKGZpbGEsIltbOmRpZ2l0Ol1dKyIpLCBmaWxhID0gY2FzZV93aGVuKGZpbGEgPT0gIkEgR1JBU0FTIFkgQUNFSVRFUyIgfiAiR1JBU0FTIFkgQUNFSVRFUyIsZmlsYSA9PSAiQiBTRU1JTExBUyBZIEZSVVRPUyBPTEVBR0lOT1NPUyIgfiAiU0VNSUxMQVMgWSBGUlVUT1MgT0xFQUdJTk9TT1MiLGZpbGEgPT0gIkMgUElFTlNPUyBBTklNQUxFUyIgfiAiUElFTlNPUyBBTklNQUxFUyIsIGZpbGEgPT0gZmlsYSB+IGZpbGEpLCBjb2x1bW5hID0gY2FzZV93aGVuKGNvbHVtbmEgPT0gIkFuZGFsdWPDg8KtYSIgfiAiQW5kYWx1Y8OtYSIsY29sdW1uYSA9PSAiQXJhZ8ODwrNuIiB+ICJBcmFnw7NuIixjb2x1bW5hID09ICJDYXN0aWxsYSB5IExlw4PCs24iIH4gIkNhc3RpbGxhIHkgTGXDs24iLGNvbHVtbmEgPT0gIkNhdGFsdcODwrFhIiB+ICJDYXRhbHXDsWEiLGNvbHVtbmEgPT0gIk11cmNpYSwgUmVnacODwrNuIGRlIiB+ICJNdXJjaWEiLGNvbHVtbmEgPT0gIlBhw4PCrXMgVmFzY28iIH4gIlBhw61zIFZhc2NvIiwgY29sdW1uYSA9PSBjb2x1bW5hIH4gY29sdW1uYSkpDQphYSA8LSBkZmNjYWEgJT4lIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBjb2x1bW5hLCB2YWx1ZXNfZnJvbSA9IHZhbG9yKSAlPiUgY29sdW1uX3RvX3Jvd25hbWVzKCJmaWxhIikNCmBgYA0KUG9yIMO6bHRpbW8gbGltcGnDqSBkYXRvcyBkZSB0cmFuc3BvcnRlIGRlIG1lcmNhbmPDrWFzLiBFbiBlc3RlIGPDs2RpZ28gYWRlbcOhcyBkZSBsYXMgdMOpY25pY2FzIGRlc2NyaXRhcyBhbnRlcmlvcm1lbnRlLCB0YW1iacOpbiB0dXZlIHF1ZSBhZ3J1cGFyIHVuYSBzZXJpZSBkZSB2YXJpYWJsZXMsIGNyZWFuZG8gdW5hIG51ZXZhIHZhcmlhYmxlIGxsYW1hZGEgIk90cm8iLiBIaWNlIGVzdG8gcG9ycXVlIGhhYsOtYW4gY3VhdHJvIHZhcmlhYmxlcyBxdWUgcmVwcmVzZW50YWJhbiBtdXkgcG9jbywgcG9yIGxvIHF1ZSBwZW5zw6kgcXVlIGRlIGVzdGEgZm9ybWEgc2UgdmVyw61hIG3DoXMgY2xhcm8uIFBhcmEgcmVhbGl6YXIgZXN0YSBhZ3J1cGFjacOzbiBwcmltZXJvIGNhbWJpw6kgbG9zIG5vbWJyZXMgZGUgbGFzIHZhcmlhYmxlcyBwb3IgIk90cm8iLCBsdWVnbyBjb24gdW5hIGNvbWJpbmFjacOzbiBkZSBncm91cF9ieSgpIHkgc3VtbWFyaXNlKCkganVudG8gYSBsYSBmdW5jacOzbiBzdW0oKSBjb25zZWd1w60gZWwgcmVzdWx0YWRvIHF1ZSBidXNjYWJhLg0KYGBge3IsIGV2YWw9RkFMU0V9DQojTWVkaW9zIGRlIHRyYW5zcG9ydGUgbcOhcyB1dGlsaXphZG9zIDIwMTkgZW4gbWlsbG9uZXMgZGUgZXVyb3MNCmRhdG9zIDwtIGhlcmU6OmhlcmUoIkRhdGEiLCJYTU1lZGlvVHJhbnNwb3J0ZS5jc3YiKQ0KZGZ0cmFucyA8LSByaW86OmltcG9ydChkYXRvcyklPiUgc2VsZWN0KC1jKDIpKSAlPiUgbXV0YXRlKCB2YWxvciA9IHN0cl9yZXBsYWNlKHZhbG9yLCJbLF0iLCIuIiksIHZhbG9yID0gYXMubnVtZXJpYyh2YWxvciksIGZpbGEgPSBzdHJfcmVtb3ZlKGZpbGEsIltbOmRpZ2l0Ol1dKyIpLCBmaWxhID0gY2FzZV93aGVuKCBmaWxhID09ICIgIE1hcsODwq10aW1vIiB+ICIgIE1hcsOtdGltbyIsIGZpbGEgPT0gIiAgVHLDg8KhZmljbyBwb3N0YWwiIH4gIiAgVHLDoWZpY28gcG9zdGFsIiwgZmlsYSA9PSAiICBQcm9wdWxzacODwrNuIHByb3BpYSIgfiAiICBQcm9wdWxzacOzbiBwcm9waWEiLCBmaWxhID09IGZpbGEgfiBmaWxhKSkgJT4lIGZpbHRlcihjb2x1bW5hICE9ICJUb3RhbCBzZWxlY2Npb25hZG8iKQ0KDQphIDwtIGlubmVyX2pvaW4oIHggPSBkZnRyYW5zJT4lZmlsdGVyKHN1YmNvbHVtbmEgPT0gIkVYUE9SVCIpLCB5ID0gZGZ0cmFucyU+JWZpbHRlcihzdWJjb2x1bW5hID09ICJJTVBPUlQiKSwgYnkgPSBjKCJmaWxhIiwiY29sdW1uYSIpKSAlPiUgbXV0YXRlKHRvdGFseG0gPSAodmFsb3IueCt2YWxvci55KSkgJT4lIHNlbGVjdCgtYygzOjYpKQ0KYWEgPC0gaW5uZXJfam9pbiggeCA9IGElPiVmaWx0ZXIoZmlsYSE9IlRvdGFsIG1vZG8gdHJhbnNwb3J0ZSIpLCB5ID0gYSAlPiUgZmlsdGVyKGZpbGE9PSJUb3RhbCBtb2RvIHRyYW5zcG9ydGUiKSwgYnkgPSBjKCJjb2x1bW5hIikpICU+JSBtdXRhdGUocG9yYyA9ICh0b3RhbHhtLngvdG90YWx4bS55KSkgJT4lIHNlbGVjdCgtYyg0LDUpKSAlPiUgbXV0YXRlKGZpbGEueCA9IGNhc2Vfd2hlbihmaWxhLnggPT0gIiAgRGVzY29ub2NpZG8iIH4gIk90cm8iLGZpbGEueCA9PSAiICBQbGF0YWZvcm1hIGZpamEiIH4gIk90cm8iLGZpbGEueCA9PSAiICBQcm9wdWxzacOzbiBwcm9waWEiIH4gIk90cm8iLGZpbGEueCA9PSAiICBUcsOhZmljbyBwb3N0YWwiIH4gIk90cm8iLGZpbGEueCA9PSAiICBUcmFuc3BvcnRlIGZsdXZpYWwiIH4gIk90cm8iLCBmaWxhLnggPT0gZmlsYS54IH4gZmlsYS54KSkgJT4lIGdyb3VwX2J5KGNvbHVtbmEsZmlsYS54KSAlPiUgc3VtbWFyaXNlKHRvdGFseG0ueCA9IHN1bSh0b3RhbHhtLngpLCBwb3JjID0gc3VtKHBvcmMpKSAlPiUgZ3JvdXBfYnkoY29sdW1uYSkgJT4lIG11dGF0ZShmaWxhLnggPSBmYWN0b3IoZmlsYS54LCBsZXZlbHMgPSBmaWxhLnhbb3JkZXIocG9yYyldKSkNCmBgYA0KDQojIDMuIEVsIHNlY3RvciBleHRlcmlvciBlc3Bhw7FvbA0KIyMgMy4xIExvcyBzb2Npb3MgY29tZXJjaWFsZXMgZGUgRXNwYcOxYQ0KIyMjIENvbnRpbmVudGVzDQpFbiBlc3RlIGdyw6FmaWNvIGRlIGJhcnJhcyBwb2RlbW9zIHZlciBsYXMgZ3JhbmRlcyDDoXJlYXMgY29uIGxhcyBxdWUgY29tZXJjaWEgRXNwYcOxYS4gTG8gbcOhcyByZWxldmFudGUgZGUgZXN0ZSBncsOhZmljbyBlcyBsYSBpbXBvcnRhbmNpYSBkZSBsYSBVbmnDs24gRXVyb3BlYSwgc3Vwb25pZW5kbyB1biBtw6FzIGRlIHVuIDYwJSBkZSBudWVzdHJhcyBleHBvcnRhY2lvbmVzIHkgbcOhcyBkZSB1biA1MCUgZGUgbnVlc3RyYXMgaW1wb3J0YWNpb25lcywgc2llbmRvIGFzw60gbnVlc3RybyBwcmluY2lwYWwgc29jaW8gY29tZXJjaWFsLiBUYW1iacOpbiBjYWJlIGRlc3RhY2FyIGVsIGltcG9ydGFudGUgc2FsZG8gcG9zaXRpdm8gZGUgbGEgYmFsYW56YSBjb21lcmNpYWwgY29uIGxhIFVuacOzbiBFdXJvcGVhLCBxdWUgcG9yIG90cmEgcGFydGUgc2UgdmUgY29udHJhcmVzdGFkbyBwb3IgZWwgc2FsZG8gbmVnYXRpdm8gcXVlIHNvc3RpZW5lIEVzcGHDsWEgZnJlbnRlIGEgQXNpYS4NCg0KIyMjIyBDw7NkaWdvDQoNClBhcmEgZWxhYm9yYXIgZXN0ZSBncsOhZmljbyBoZSB1c2FkbyBlbCBnZW9tYSBnZW9tX2JhcigpLiBBIGRpY2hvIGdlb21hIGxlIGhlIGHDsWFkaWRvIGRvcyBvcGNpb25lcyBzdGF0ID0gImlkZW50aXR5IiB5IHBvc2l0aW9uID0gImRvZGdlIiwgbGEgcHJpbWVyYSBwYXJhIHBvZGVyIHJlcHJlc2VudGFyIHZhbG9yZXMgY29udGludW9zIHkgbGEgc2VndW5kYSBwYXJhIHByZXNlbnRhciBkb3MgY29sdW1uYXMgcG9yIGNvbnRpbmVudGUuIEFkaWNpb25hbG1lbnRlIGhlIHB1ZXN0byBlbCBlamUgeSBlbiBwb3JjZW50YWplIHVzYW5kbyBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsMC42NSwwLjEpLCBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpLiANCg0KRW4gY3VhbnRvIGFsIHRlbWEsIGEgcGFydGUgZGUgcXVpdGFyIGxhcyBsw61uZWFzIGRlbCBlamUgbWVub3IgeSwgZWwgZWplIHggeSBsb3MgYm9yZGVzLCB0YW1iacOpbiBoZSBtb2RpZmljYWRvIGxhIGxleWVuZGEuIENvbiBsZWdlbmQucG9zaXRpb24gPSAidG9wIiBoZSBjYW1iaWFkbyBsYSBwb3NpY2nDs24gZGUgbGEgbGV5ZW5kYSBkZXNkZSBsYSBkZXJlY2hhIGhhc3RhIGFycmliYSBkZWwgZ3LDoWZpY28uDQpgYGB7cixlY2hvPUZBTFNFLCBldmFsPVRSVUV9DQoNCiNFeHBvcnRhY2lvbmVzIGUgaW1wb3J0YWNpb25lcyBwb3IgY29udGluZW50ZXMgZW4gbWlsbG9uZXMgZGUgZXVyb3MgKGZ1ZW50ZSBkYXRhY29tZXgpDQpkYXRvcyA8LSAiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3hpNzY1L01pUHJveWVjdG9JbmRpdmlkdWFsQXJjaGl2b3MvbWFpbi9YTUNvbnRpbmVudGVzLmNzdiINCmRmeG1jIDwtIHJpbzo6aW1wb3J0KGRhdG9zKSAlPiUgZmlsdGVyKHN1YmZpbGEgIT0gIlRvdGFsIHNlbGVjY2lvbmFkbyIpICU+JSBzZWxlY3QoLWMoNCkpICU+JQ0KbXV0YXRlKGZpbGEgPSBjYXNlX3doZW4oIGZpbGEgPT0gIkFGIC0gQWZyaWNhIiB+ICJBZnJpY2EiLCBmaWxhID09ICJBTSAtIEFtw4PCqXJpY2EiIH4gIkFtZXJpY2EiLCBmaWxhID09ICJBUyAtIEFzaWEiIH4iQXNpYSIsIGZpbGEgPT0gIk9DIC0gT2NlYW7Dg8KtYSIgfiAiT2NlYW5pYSIsIGZpbGEgPT0gIlVFIC0gVW5pw4PCs24gRXVyb3BlYSAyOCBwYcODwq1zZXMoZC4yMDEzLTA3IGguMjAyMC0wMSkiIH4gIlVuaW9uIEV1cm9wZWEgKDI4KSIsIGZpbGEgPT0gIlRvdGFsIE11bmRvIiB+ICJUb3RhbCIpLCB2YWxvciA9IHN0cl9yZXBsYWNlKHZhbG9yLCJbLF0iLCIuIiksIHZhbG9yID0gYXMubnVtZXJpYyh2YWxvciksIHN1YmZpbGEgPSBhcy5udW1lcmljKHN1YmZpbGEpKQ0KI0VYUE9SVEFDSU9ORVMgUE9SIENPTlRJTkVOVEUNCmFhIDwtIGlubmVyX2pvaW4oeCA9IGRmeG1jICU+JSBmaWx0ZXIoZmlsYSAhPSAiVG90YWwiKSx5ID0gZGZ4bWMgJT4lIGZpbHRlcihmaWxhID09ICJUb3RhbCIpLCBieSA9IGMoImNvbHVtbmEiLCJzdWJmaWxhIikpICU+JSBzZWxlY3QoLWMoNSkpICU+JSBtdXRhdGUocG9yYyA9ICh2YWxvci54L3ZhbG9yLnkpKSAlPiUgZmlsdGVyKHN1YmZpbGEgPT0gMjAxOSkgJT4lIGdyb3VwX2J5KGNvbHVtbmEpICU+JSBtdXRhdGUoZmlsYS54ID0gZmFjdG9yKGZpbGEueCwgbGV2ZWxzID0gZmlsYS54W29yZGVyKHBvcmMsIGRlY3JlYXNpbmcgPSBUUlVFKV0pKQ0KYGBgDQpgYGB7cixlY2hvPVRSVUUsIGV2YWw9VFJVRSwgb3V0LndpZHRoID0gIjE1MCUifQ0KZ2dwbG90KGFhLCBhZXMoeCA9IGZpbGEueCwgeSA9IHBvcmMsIGZpbGwgPSBjb2x1bW5hKSkgKyBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICIjMDAwMDAwIikgKw0KICAgICAgICAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLDAuNjUsMC4xKSwgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50KSArDQogICAgICAgICAgICAgICBzY2FsZV9maWxsX2Rpc2NyZXRlKGxhYmVscyA9IGMoIiUgZGVsIHRvdGFsIGRlIEV4cG9ydGFjaW9uZXMiLCIlIGRlbCB0b3RhbCBkZSBJbXBvcnRhY2lvbmVzIikpICsNCiAgICAgICAgICAgICAgbGFicyhmaWxsPU5VTEwsDQogICAgICAgICAgICAgICB4PU5VTEwsDQogICAgICAgICAgICAgICB5PU5VTEwsDQogICAgICAgICAgICAgICB0aXRsZT0iRmx1am9zIGNvbWVyY2lhbGVzIHBvciBjb250aW5lbnRlIiwNCiAgICAgICAgICAgICAgIHN1YnRpdGxlID0gIkHDsW8gMjAxOSIsDQogICAgICAgICAgICAgICBjYXB0aW9uPSJGdWVudGU6IERhdGFDb21leCIpICsNCiAgICAgICAgICAgICAgIHRoZW1lKA0KICAgICAgICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KCBmaWxsID0gIiNmZmZmZmYiLCBjb2xvdXIgPSAiI2ZmZmZmZiIpLA0KICAgICAgICAgICAgICBwYW5lbC5ncmlkICA9IGVsZW1lbnRfbGluZSggY29sb3VyID0iZ3JleSIpLA0KICAgICAgICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gMi41LCBzaXplID0gMTUpLA0KICAgICAgICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgICAgIHBhbmVsLmdyaWQubWlub3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgICAgICBsZWdlbmQubWFyZ2luID0gbWFyZ2luKHQ9MjUpLA0KICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwNCiAgICAgICAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiI2ZmZmZmZiIsIGNvbG91ciA9ICIjZmZmZmZmIiApLA0KICAgICAgICAgICAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbih0ID0gNSwgciA9IDI1LCBiID0gNSwxNSkpDQpgYGANCg0KIyMjIFBhw61zZXMNCg0KRW4gZXN0b3MgZ3LDoWZpY29zIGZyYWdtZW50YW1vcyBsYSBpbmZvcm1hY2nDs24gYW5hbGl6YWRhIGVuIGVsIGFwYXJ0YWRvIGFudGVyaW9yLCB2aWVuZG8gbGEgbWlzbWEgaW5mb3JtYWNpw7NuIHBlcm8gcG9yIHBhw61zLiBFc3RvcyBncsOhZmljb3Mgbm9zIHJlYWZpcm1hbiBlbCBoZWNobyBkZSBxdWUgRXVyb3BhIGVzIG51ZXN0cm8gcHJpbmNpcGFsIHNvY2lvIGNvbWVyY2lhbCwgZXNwZWNpYWxtZW50ZSBlbiBsbyByZWZlcmVudGUgYSBsYXMgZXhwb3J0YWNpb25lcy4gTG9zIGNpbmNvIHBhw61zZXMgYSBsb3MgcXVlIGV4cG9ydGFtb3MgbcOhcyBtZXJjYW5jw61hcyBwb3IgdmFsb3Igc29uIGV1cm9wZW9zLCBzaWVuZG8gRnJhbmNpYSBudWVzdHJvIHByaW5jaXBhbCBjbGllbnRlLiBFbiBjdWFudG8gYSBsYXMgaW1wb3J0YWNpb25lcyBsYSBzaXR1YWNpw7NuIGVzIGxpZ2VyYW1lbnRlIGRpc3RpbnRhLCBhdW5xdWUgQWxlbWFuaWEgeSBGcmFuY2lhIHNpZ3VlbiBzaWVuZG8gbG9zIHBhw61zZXMgZGUgbG9zIHF1ZSBtw6FzIGltcG9ydGFtb3MsIENoaW5hIHNlIGVuY3VlbnRyYSBlbiB0ZXJjZXJhIHBvc2ljacOzbiB5IEVzdGFkb3MgVW5pZG9zIGVuIGxhIHF1aW50YS4NCg0KIyMjIyBDw7NkaWdvDQoNClBhcmEgaGFjZXIgZXN0ZSBncsOhZmljbyBoZSB2dWVsdG8gYSB1c2FyIHVuIGdlb21fYmFyKCksIGF1bnF1ZSBlbiBlc3RhIG9jYXNpw7NuIGhlIG9wdGFkbyBwb3IgcmVwcmVzZW50YXIgbGFzIEV4cG9ydGFjaW9uZXMgZSBJbXBvcnRhY2lvbmVzIHBvciBzZXBhcmFkby4gRWwgdGVtYSBxdWUgaGUgdXNhZG8gaGEgc2lkbyBlbCBtaXNtbyBxdWUgZW4gZWwgZ3LDoWZpY28gYW50ZXJpb3IsIGEgZXhjZXBjacOzbiBkZSBlbCBlamUgeS4gRW4gZXN0YSBvY2FzacOzbiBsb3MgdmFsb3JlcyBkZWwgZWplIHkgZXN0YWJhbiBlbiBtaWxsb25lcywgYXPDrSBxdWUgdXPDqSBsYSBmdW5jacOzbiBzY2FsZV95X2NvbnRpbnVvdXMoKSBwYXJhIGNhbWJpYXIgZWwgZm9ybWF0byB5IGhhY2VybG8gbcOhcyBzZW5jaWxsby4gRGVudHJvIGRlIGRpY2hhIGZ1bmNpw7NuIGluY2x1w60gbGFiZWxzID0gcGFzdGUoc2NhbGVzOjpjb21tYShzZXEoMCw0NTAwMCw1MDAwKSksIk3igqwiKSwgcXVlIGLDoXNpY2FtZW50ZSBwb27DrWEgZW4gZm9ybWF0byBjb21hIGxhIHNlY3VlbmNpYSBlc2NyaXRhIHkgbGUgcGVnYWJhIHVuICJN4oKsIi4NCmBgYHtyLGVjaG89RkFMU0UsIGV2YWw9VFJVRX0NCiNFeHBvcnRhY2lvbmVzIGUgaW1wb3J0YWNpb25lcyBwb3IgcGHDrXMgZW4gbWlsbG9uZXMgZGUgZXVyb3MNCmRhdG9zIDwtICJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20veGk3NjUvTWlQcm95ZWN0b0luZGl2aWR1YWxBcmNoaXZvcy9tYWluL1hNUGFpcy5jc3YiDQpkZnhtcCA8LSByaW86OmltcG9ydChkYXRvcykgJT4lIG11dGF0ZSggdmFsb3IgPSBzdHJfcmVwbGFjZSh2YWxvciwiWyxdIiwiLiIpLCB2YWxvciA9IGFzLm51bWVyaWModmFsb3IpKQ0KI0VYUE9SVEFDSU9ORVMNCmRmeHAgPC0gZGZ4bXAgJT4lIGZpbHRlcihzdWJjb2x1bW5hID09ICJFWFBPUlQiLCBzdWJmaWxhID09ICIyMDE5IiwgIWZpbGEgJWluJSBjKCJUb3RhbCBzZWxlY2Npb25hZG8iLCJVRSAtIFVuacODwrNuIEV1cm9wZWEgMjggcGHDg8Ktc2VzKGQuMjAxMy0wNyBoLjIwMjAtMDEpIikpICU+JSBzbGljZV9tYXgob3JkZXJfYnkgPSB2YWxvcixuID0gMTApICU+JSBtdXRhdGUoZmlsYSA9IGZhY3RvcihmaWxhLCBsZXZlbHMgPSBmaWxhW29yZGVyKHZhbG9yLCBkZWNyZWFzaW5nID0gVFJVRSldKSkNCiNJTVBPUlRBQ0lPTkVTDQpkZm1wIDwtIGRmeG1wICU+JSBmaWx0ZXIoc3ViY29sdW1uYSA9PSAiSU1QT1JUIiwgc3ViZmlsYSA9PSAiMjAxOSIsICFmaWxhICVpbiUgYygiVG90YWwgc2VsZWNjaW9uYWRvIiwiVUUgLSBVbmnDg8KzbiBFdXJvcGVhIDI4IHBhw4PCrXNlcyhkLjIwMTMtMDcgaC4yMDIwLTAxKSIpKSAlPiUgc2xpY2VfbWF4KG9yZGVyX2J5ID0gdmFsb3IsbiA9IDEwKSAlPiUgbXV0YXRlKGZpbGEgPSBmYWN0b3IoZmlsYSwgbGV2ZWxzID0gZmlsYVtvcmRlcih2YWxvciwgZGVjcmVhc2luZyA9IFRSVUUpXSkpDQpgYGANCmBgYHtyLGVjaG89VFJVRSwgZXZhbD1UUlVFLCBvdXQud2lkdGggPSAiMTUwJSJ9DQojRXhwb3J0YWNpb25lcw0KZ2dwbG90KGRmeHAsIGFlcyh4ID0gZmlsYSwgeSA9IHZhbG9yLCBmaWxsID0gZmlsYSkpICsgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsY29sb3IgPSAiIzAwMDAwMCIpICsNCiAgICAgICAgICAgICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNwZWN0cmFsIiwgbGFiZWxzID0gYygiRnJhbmNpYSIsIkFsZW1hbmlhIiwiSXRhbGlhIiwiUG9ydHVnYWwiLCJSZWlubyBVbmlkbyIsIkVzdGFkb3MgVW5pZG9zIiwiUGHDrXNlcyBCYWpvcyIsIk1hcnJ1ZWNvcyIsIkLDqWxnaWNhIiwiQ2hpbmEiKSkgKw0KICAgICAgICAgICAgIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gYygiRnJhbmNpYSIsIkFsZW1hbmlhIiwiSXRhbGlhIiwiUG9ydHVnYWwiLCJSZWlubyBVbmlkbyIsIkVzdGFkb3MgVW5pZG9zIiwiUGHDrXNlcyBCYWpvcyIsIk1hcnJ1ZWNvcyIsIkLDqWxnaWNhIiwiQ2hpbmEiKSkgKw0KICAgICAgICAgICAgIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoMCw0NTAwMCw1MDAwKSwgbGFiZWxzID0gcGFzdGUoc2NhbGVzOjpjb21tYShzZXEoMCw0NTAwMCw1MDAwKSksIk3igqwiKSkgKw0KICAgICAgICAgICAgIGxhYnMoZmlsbD1OVUxMLA0KICAgICAgICAgICAgICAgeD1OVUxMLA0KICAgICAgICAgICAgICAgeT1OVUxMLA0KICAgICAgICAgICAgICAgdGl0bGU9IkV4cG9ydGFjaW9uZXMgcG9yIHBhw61zIiwNCiAgICAgICAgICAgICAgIHN1YnRpdGxlID0gIkHDsW8gMjAxOSIsDQogICAgICAgICAgICAgICBjYXB0aW9uPSJGdWVudGU6IERhdGFDb21leCIpICsNCiAgICAgICAgICAgICAgIHRoZW1lKCBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiI2ZmZmZmZiIpLA0KICAgICAgICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KCBmaWxsID0gIiNmZmZmZmYiLCBjb2xvdXIgPSAiI2ZmZmZmZiIsIHNpemUgPSAwLjEgKSwNCiAgICAgICAgICAgICAgcGFuZWwuZ3JpZCAgPSBlbGVtZW50X2xpbmUoIGNvbG91ciA9ImdyZXkiKSwNCiAgICAgICAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNzUsIGZhY2UgPSAiYm9sZCIsIHZqdXN0ID0gMC45NSwgaGp1c3QgPSAxKSwNCiAgICAgICAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IDIuNSwgc2l6ZSA9IDE1KSwNCiAgICAgICAgICAgICAgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgICAgICAgICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKHQgPSA1LCByID0gMjUsIGIgPSA1LDE1KSwNCiAgICAgICAgICAgICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNlOGQ3YTMiLGNvbG91ciA9IE5VTEwpKQ0KDQpgYGANCg0KYGBge3IgZWNobz1GQUxTRSwgb3V0LndpZHRoID0gIjE1MCUifQ0KI0ltcG9ydGFjaW9uZXMNCmdncGxvdChkZm1wLCBhZXMoeCA9IGZpbGEsIHkgPSB2YWxvciwgZmlsbCA9IGZpbGEpKSArIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLGNvbG9yID0gIiMwMDAwMDAiKSArDQogICAgICAgICAgICAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTcGVjdHJhbCIsIGxhYmVscyA9IGMoIkZyYW5jaWEiLCJBbGVtYW5pYSIsIkl0YWxpYSIsIlBvcnR1Z2FsIiwiUmVpbm8gVW5pZG8iLCJFc3RhZG9zIFVuaWRvcyIsIlBhw61zZXMgQmFqb3MiLCJNYXJydWVjb3MiLCJCw6lsZ2ljYSIsIkNoaW5hIikpICsNCiAgICAgICAgICAgICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscyA9IGMoIkFsZW1hbmlhIiwiRnJhbmNpYSIsIkNoaW5hIiwiSXRhbGlhIiwiRXN0YWRvcyBVbmlkb3MiLCJQYcOtc2VzIEJham9zIiwiUmVpbm8gVW5pZG8iLCJQb3J0dWdhbCIsIlR1cnF1w61hIiwiQsOpbGdpY2EiKSkgKw0KICAgICAgICAgICAgIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoMCw0NTAwMCw1MDAwKSwgbGFiZWxzID0gcGFzdGUoc2NhbGVzOjpjb21tYShzZXEoMCw0NTAwMCw1MDAwKSksIk3igqwiKSkgKw0KICAgICAgICAgICAgIGxhYnMoZmlsbD1OVUxMLA0KICAgICAgICAgICAgICAgeD1OVUxMLA0KICAgICAgICAgICAgICAgeT1OVUxMLA0KICAgICAgICAgICAgICAgdGl0bGU9IkltcG9ydGFjaW9uZXMgcG9yIHBhw61zIiwNCiAgICAgICAgICAgICAgc3VidGl0bGUgPSAiQcOxbyAyMDE5IiwNCiAgICAgICAgICAgICAgIGNhcHRpb249IkZ1ZW50ZTogRGF0YUNvbWV4IikgKw0KICAgICAgICAgICAgICAgdGhlbWUoIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCggZmlsbCA9ICIjZmZmZmZmIiksDQogICAgICAgICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiI2ZmZmZmZiIsIGNvbG91ciA9ICIjZmZmZmZmIiwgc2l6ZSA9IDAuMSApLA0KICAgICAgICAgICAgICBwYW5lbC5ncmlkICA9IGVsZW1lbnRfbGluZSggY29sb3VyID0iZ3JleSIpLA0KICAgICAgICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgICAgIHBhbmVsLmdyaWQubWlub3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA3NSwgZmFjZSA9ICJib2xkIiwgdmp1c3QgPSAwLjk1LCBoanVzdCA9IDEpLA0KICAgICAgICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gMi41LCBzaXplID0gMTUpLA0KICAgICAgICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICAgICAgICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4odCA9IDUsIHIgPSAyNSwgYiA9IDUsMTUpLA0KICAgICAgICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI2U4ZDdhMyIsY29sb3VyID0gTlVMTCkpDQpgYGANCg0KIyMjIEV1cm9wYTogTnVlc3RybyBncmFuIGFsaWFkbw0KDQpDb24gZXN0ZSBncsOhZmljbyBoZSBxdWVyaWRvIGhhY2VyIHVuIG1heW9yIMOpbmZhc2lzIGVuIGxhIHJlbGV2YW5jaWEgcXVlIHRpZW5lIGxhIFVuacOzbiBFdXJvcGVhIGNvbW8gc29jaW8gY29tZXJjaWFsIGRlIEVzcGHDsWEuIEVuIGVsIGdyw6FmaWNvIHBvZGVtb3MgdmVyIGxhIGV2b2x1Y2nDs24gZGVsIHBlc28gZGUgbG9zIGZsdWpvcyBjb21lcmNpYWxlcyBjb24gbGEgVW5pw7NuIEV1cm9wZWEgZGVzZGUgMTk5NSBoYXN0YSBsYSBhY3R1YWxpZGFkLiBIYXkgZG9zIGFzcGVjdG9zIHF1ZSBjYWJlIGRlc3RhY2FyIHNvYnJlIGVzdGUgZ3LDoWZpY286IFByaW1lcm8gbGEgY2HDrWRhIGRlIGxvcyBmbHVqb3MgY29tZXJjaWFsZXMgY29uIGxhIFVuacOzbiBFdXJvcGVhIGRlc2RlIHByaW5jaXBpb3MgZGUgc2lnbyBoYXN0YSBlbCAyMDEyIGFwcm94aW1hZGFtZW50ZS4gRXN0byBwb2Ryw61hIGhhYmVyIHNpZG8gY2F1c2FkbyBwb3IgZWwgYXZhbmNlIGRlIGxhIGdsb2JhbGl6YWNpw7NuLCBxdWUgaGEgaGVjaG8gcXVlIHRlcmNlcm9zIHBhw61zZXMgZW4gdsOtYXMgZGUgZGVzYXJyb2xsbyBlbnRyZW4gYSBjb21wZXRpciBkaXJlY3RhbWVudGUgZW4gbG9zIG1lcmNhZG9zIGV1cm9wZW9zLCB1biBjbGFybyBlamVtcGxvIGRlIGVzdG8gc2Vyw61hIGVsIGF1bWVudG8gZGUgbGFzIGltcG9ydGFjaW9uZXMgY2hpbmFzOyBTZWd1bmRvLCBsYSByZWNpZW50ZSBicnVzY2EgcmVjdXBlcmFjacOzbiBxdWUgaGFuIHN1ZnJpZG8gYW1ib3MgZmx1am9zLiBFc3RvIGxvIHBvZHLDrWFtb3MgYXNvY2lhciBhIGxhIGNyaXNpcyBkZWwgQ292aWQtMTksIHF1ZSBoYSBzdXB1ZXN0byB1biBmcmVubyBhIGxvcyBmbHVqb3MgZGUgY29tZXJjaW8gaW50ZXJuYWNpb25hbCwgZXN0YSBjcmlzaXMgaGEgYWZlY3RhZG8gbcOhcyBhbCBjb21lcmNpbyBjb24gcGHDrXNlcyBmdWVyYSBkZSBsYSBVRSBwb3JxdWUgZGljaG9zIHBhw61zZXMgYWRlbcOhcyBkZSBlc3RhciBtw6FzIGFsZWphZG9zLCB0YW1iacOpbiBoYW4gdGVuaWRvIG1heW9yZXMgdHJhYmFzLg0KDQojIyMjIEPDs2RpZ28NCg0KUGFyYSByZWFsaXphciBlc3RlIGdyw6FmaWNvIGhlIHVzYWRvIHVuIGdlb21fbGluZSgpLiBFbiBjdWFudG8gYWwgdGVtYSwgaGUgcmVjaWNsYWRvIGVsIGRlIGxvcyBncsOhZmljb3MgYW50ZXJpb3JlcywgYSBleGNlcGNpw7NuIGRlIGxhIGxleWVuZGEuIEVuIGVzdGUgZ3LDoWZpY28gaGUgaW5jb3Jwb3JhZG8gbGEgbGV5ZW5kYSBlbiBlbCBzdWJ0w610dWxvIGNvbiBlbCBwYXF1ZXRlIGdndGV4dCgpLiBFc3RlIHBhcXVldGUgcGVybWl0ZSBlc2NyaWJpciBsb3MgdGV4dG9zIGVuIE1hcmtkb3duLCBwZXJtaXRpZW5kbyBlbnRyZSBvdHJhcyBjb3NhcywgY2FtYmlhciBlbCBjb2xvciBkZWwgdGV4dG8uDQpgYGB7cixlY2hvPUZBTFNFLCBldmFsPVRSVUV9DQp1cmwgPC0gImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS94aTc2NS9NaVByb3llY3RvSW5kaXZpZHVhbEFyY2hpdm9zL21haW4vRGF0YUNvbWV4XzIwMTEzMDEyMjAzNi5jc3YiDQoNCmRhdGEgPC0gcmVhZC5jc3YodXJsKQ0KZGF0YSA8LSBkYXRhICU+JSByZW5hbWVfYXQodmFycyhjb2xuYW1lcyhkYXRhKSksIH4gYygiQ291bnRyeSIsIkRhdGUiLCJDb2x1bW5hIiwiVmFyaWFibGUiLCJWYWxvciIpKQ0KZGF0YSA8LSBkYXRhICU+JSBmaWx0ZXIoRGF0ZSAhPSAiVG90YWwgRmVjaGFzIikNCmRhdGEgPC0gZGF0YSAlPiUgbXV0YXRlKFZhbG9yID0gc3RyaW5ncjo6c3RyX3JlcGxhY2UoVmFsb3IsIihbLF0pIiwiLiIpLFZhbG9yID0gYXMubnVtZXJpYyhWYWxvciksIERhdGUgPSBhcy5udW1lcmljKERhdGUpKQ0KZXNweG0gPC0gZGF0YSAlPiUgZmlsdGVyKENvdW50cnkgPT0gIlRvdGFsIE11bmRvIikgJT4lIHNlbGVjdCgtYyhDb2x1bW5hLENvdW50cnkpKQ0KZXNweG0gPC0gZXNweG0gJT4lIG11dGF0ZShWYWxvck0gPSAoVmFsb3IvMTAwMDAwMCkpICU+JSBncm91cF9ieShEYXRlKSAlPiUgbXV0YXRlKG1pbiA9IG1pbihWYWxvck0pLCBtYXggPSBtYXgoVmFsb3JNKSkNCiNFWFBPUlRBQ0lPTkVTIEUgSU1QT1JUQUNJT05FUyBBIExBIFVFDQpkZmV4cGMgPC0gZGZ4bWMgJT4lIGZpbHRlcihmaWxhID09ICJVbmlvbiBFdXJvcGVhICgyOCkiKQ0KZGZleHBjYiA8LSBpbm5lcl9qb2luKGRmZXhwYyxlc3B4bSwgYnkgPSBjKCJzdWJmaWxhIj0iRGF0ZSIsImNvbHVtbmEiPSJWYXJpYWJsZSIpKSAlPiUgc2VsZWN0KC1jKDUpKSAlPiUgbXV0YXRlKHZhbG9ycG9yYyA9ICh2YWxvci9WYWxvck0pKQ0KYGBgDQpgYGB7cixlY2hvPVRSVUUsIGV2YWw9VFJVRSwgb3V0LndpZHRoID0gIjE1MCUifQ0KZ2dwbG90KGRmZXhwY2IsIGFlcyh4PXN1YmZpbGEsIHk9dmFsb3Jwb3JjLCBjb2xvciA9IGNvbHVtbmEpKSArIGdlb21fbGluZShzaXplPTEpICsNCiAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLjUsMC43NSwwLjA1KSwgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50KSsNCiAgICAgICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgxOTk1LDIwMjAsMSkpICsNCiAgICAgICAgbGFicyhmaWxsPU5VTEwsDQogICAgICAgIHg9TlVMTCwNCiAgICAgICAgeT1OVUxMLA0KICAgICAgICB0aXRsZT0iRmx1am9zIGNvbWVyY2lhbGVzIGNvbiBsYSBVbmnDs24gRXVyb3BlYSAoMjgpIiwNCiAgICAgICAgc3VidGl0bGUgPSAiPHNwYW4gc3R5bGU9J2NvbG9yOiNmZjA1MDU7Jz5FeHBvcnRhY2lvbmVzPC9zcGFuPiBlIDxzcGFuIHN0eWxlPSdjb2xvcjojMjRmZjA1Oyc+SW1wb3J0YWNpb25lcyA8L3NwYW4+ZW4gJSBkZWwgdG90YWwiLA0KICAgICAgICBjYXB0aW9uPSJGdWVudGU6IERhdGFDb21leCIpICsNCiAgICAgICAgc2NhbGVfY29sb3JfbWFudWFsKCB2YWx1ZXMgPSBjKCJFWFBPUlQiPSIjZmYwMDAwIiwiSU1QT1JUIj0iIzI0ZDgwMCIpLCBsYWJlbHMgPSBjKCJFeHAuIiwiSW1wLiIpKSArDQogICAgICAgIHRoZW1lKCBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiI2ZmZmZmZiIpLA0KICAgICAgICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KCBmaWxsID0gIiNmZmZmZmYiKSwNCiAgICAgICAgICAgICAgcGFuZWwuZ3JpZCAgPSBlbGVtZW50X2xpbmUoIGNvbG91ciA9IiM5NzllOWUiKSwNCiAgICAgICAgICAgICAgcGFuZWwuZ3JpZC5taW5vci54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgICAgIHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICAgICAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG9yID0gIiMwMDAwMDAiKSwNCiAgICAgICAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiIzAwMDAwMCIpLA0KICAgICAgICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3VyID0gIiMwMDAwMDAiKSwNCiAgICAgICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCksDQogICAgICAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IDQpLA0KICAgICAgICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLA0KICAgICAgICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwNCiAgICAgICAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfbWFya2Rvd24oaGp1c3QgPSAwLjUpLA0KICAgICAgICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BLGNvbG91ciA9ICIjZmZmZmZmIiksDQogICAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCmBgYA0KDQojIyAzLjIgRWwgc2VjdG9yIGV4dGVyaW9yIGVzcGHDsW9sDQoNCkVuIGVzdGUgZ3LDoWZpY28gc2UgbXVlc3RyYSBlbCB0b3RhbCBkZSBpbXBvcnRhY2lvbmVzIHkgZXhwb3J0YWNpb25lcyBwb3IgYcOxbywgYWRlbcOhcyBzZSBoYSByZXNhbHRhZG8gZW4gYW1hcmlsbG8gZWwgZMOpZmljaXQgZGUgbGEgYmFsYW56YSBjb21lcmNpYWwuIEVuIGVzdGUgZ3LDoWZpY28gbWUgZ3VzdGFyw61hIGRlc3RhY2FyIGRvcyBjb3NhczogRW4gcHJpbWVyIGx1Z2FyLCBsYXMgZG9zIGltcG9ydGFudGVzIGNhw61kYXMgc3VmcmlkYXMgZW4gMjAwOCB5IDIwMjA7IEVuIHNlZ3VuZG8gbHVnYXIsIGVsIGhlY2hvIGRlIHF1ZSBlbCBzZWN0b3IgZXhwb3J0YWRvciBlc3Bhw7FvbCBzZSBoYSBjb21wb3J0YWRvIHJlbGF0aXZhbWVudGUgYmllbiBlbiB0b2RvcyBsb3MgcGVyaW9kb3MgZGUgY3Jpc2lzIGVjb27Ds21pY2EuIEVzdG8gbG8gcG9kZW1vcyB2ZXIgYmllbiBvYnNlcnZhbmRvIGVsIGTDqWZpY2l0IGRlIGxhIGJhbGFuemEgY29tZXJjaWFsLCBlbiBsb3MgcGVyaW9kb3MgZGUgY3Jpc2lzIGVzdGUgZMOpZmljaXQgc2llbXByZSBzZSByZWR1Y2UuDQoNCiMjIyBDw7NkaWdvDQpQYXJhIGVsYWJvcmFyIGVzdGUgZ3LDoWZpY28gaGUgc2VndWlkbyBlbCBtaXNtbyBtZXRvZG8gcXVlIGVuIGVsIGdyw6FmaWNvIGFudGVyaW9yLCBzaW4gZW1iYXJnbywgZXN0YSB2ZXogaGUgYcOxYWRpZG8gdW4gZ2VvbV9yaWJib24oKSBwYXJhIHJlcHJlc2VudGFyIGVsIGTDqWZpY2l0IGRlIGxhIGJhbGFuemEgY29tZXJjaWFsLiBQYXJhIGVzdGUgZ2VvbWEgaGUgdGVuaWRvIHF1ZSBjcmVhciBkb3MgbnVldmFzIGNvbHVtbmFzIGVuIGVsIGRhdGFmcmFtZTogbWluIHkgbWF4LiBFc3RhcyBjb2x1bW5hcyBsYXMgY3Jlw6kgY29uIGxhcyBmdW5jaW9uZXMgbWluKCkgeSBtYXgoKSwgY29naWVuZG8gZWwgdmFsb3IgbcOtbmltbyB5IG3DoXhpbW8gZGUgY2FkYSBhw7FvLCBkaWNob3MgdmFsb3JlcyBhY3R1YW4gY29tbyBsw61taXRlcyBkZWwgcG9sw61nb25vLg0KYGBge3IsZWNobz1GQUxTRSwgZXZhbD1UUlVFfQ0KI0V4cG9ydGFjaW9uZXMgZSBpbXBvcnRhY2lvbmVzIEVTUEHDkUENCnVybCA8LSAiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3hpNzY1L01pUHJveWVjdG9JbmRpdmlkdWFsQXJjaGl2b3MvbWFpbi9EYXRhQ29tZXhfMjAxMTMwMTIyMDM2LmNzdiINCmRhdGEgPC0gcmVhZC5jc3YodXJsKQ0KZGF0YSA8LSBkYXRhICU+JSByZW5hbWVfYXQodmFycyhjb2xuYW1lcyhkYXRhKSksIH4gYygiQ291bnRyeSIsIkRhdGUiLCJDb2x1bW5hIiwiVmFyaWFibGUiLCJWYWxvciIpKQ0KZGF0YSA8LSBkYXRhICU+JSBmaWx0ZXIoRGF0ZSAhPSAiVG90YWwgRmVjaGFzIikNCmRhdGEgPC0gZGF0YSAlPiUgbXV0YXRlKFZhbG9yID0gc3RyaW5ncjo6c3RyX3JlcGxhY2UoVmFsb3IsIihbLF0pIiwiLiIpLFZhbG9yID0gYXMubnVtZXJpYyhWYWxvciksIERhdGUgPSBhcy5udW1lcmljKERhdGUpKQ0KZXNweG0gPC0gZGF0YSAlPiUgZmlsdGVyKENvdW50cnkgPT0gIlRvdGFsIE11bmRvIikgJT4lIHNlbGVjdCgtYyhDb2x1bW5hLENvdW50cnkpKQ0KZXNweG0gPC0gZXNweG0gJT4lIG11dGF0ZShWYWxvck0gPSAoVmFsb3IvMTAwMDAwMCkpICU+JSBncm91cF9ieShEYXRlKSAlPiUgbXV0YXRlKG1pbiA9IG1pbihWYWxvck0pLCBtYXggPSBtYXgoVmFsb3JNKSkNCmBgYA0KYGBge3IsZWNobz1UUlVFLCBldmFsPVRSVUUsIG91dC53aWR0aCA9ICIxNTAlIn0NCmdncGxvdChlc3B4bSxhZXMoeCA9IERhdGUsIHkgPSBWYWxvck0sIGNvbG9yID0gVmFyaWFibGUpKSArDQogICAgICAgIGdlb21fbGluZSgpICsNCiAgICAgICAgZ2VvbV9wb2ludCgpICsNCiAgICAgICAgZ2VvbV9yaWJib24oYWVzKHggPSBEYXRlLCB5bWluID0gbWluLCB5bWF4ID0gbWF4KSwgZmlsbCA9ICIjZjRmZjA1IiwgYWxwaGEgPSAwLjMsIGNvbG9yID0gTkEpICsNCiAgICAgICAgbGFicyhmaWxsPU5VTEwsDQogICAgICAgIHg9TlVMTCwNCiAgICAgICAgeT1OVUxMLA0KICAgICAgICB0aXRsZT0iPHNwYW4gc3R5bGU9J2NvbG9yOiNmZjA1MDU7Jz5FeHBvcnRhY2lvbmVzPC9zcGFuPiBlIDxzcGFuIHN0eWxlPSdjb2xvcjojMjRmZjA1Oyc+SW1wb3J0YWNpb25lcyA8L3NwYW4+ZW4gRXNwYcOxYSIsDQogICAgICAgIGNhcHRpb249IkZ1ZW50ZTogRGF0YUNvbWV4IikgKw0KICAgICAgICBzY2FsZV9jb2xvcl9tYW51YWwoIHZhbHVlcyA9IGMoIkVYUE9SVCI9IiNmZjAwMDAiLCJJTVBPUlQiPSIjMjRkODAwIikpICsNCiAgICAgICAgc2NhbGVfZmlsbF9tYW51YWwoIHZhbHVlcyA9IGMoIkVYUE9SVCI9IiNmZjAwMDAiLCJJTVBPUlQiPSIjMjRkODAwIikpICsNCiAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLDMwMDAwMCw1MDAwMCksbGFiZWxzID0gKHBhc3RlKHNjYWxlczo6Y29tbWEoc2VxKDAsMzAwMDAwLDUwMDAwKSksIk3igqwiKSkpICsNCiAgICAgICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgxOTk1LDIwMjAsMSkpICsNCiAgICAgICAgdGhlbWUoIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCggZmlsbCA9ICIjZmZmZmZmIiksDQogICAgICAgICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiI2ZmZmZmZiIpLA0KICAgICAgICAgICAgICBwYW5lbC5ncmlkICA9IGVsZW1lbnRfbGluZSggY29sb3VyID0iIzk3OWU5ZSIpLA0KICAgICAgICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgICAgIHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICAgICAgcGFuZWwuZ3JpZC5taW5vci54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICIjMDAwMDAwIiksDQogICAgICAgICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSAiIzAwMDAwMCIpLA0KICAgICAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSwNCiAgICAgICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gNCksDQogICAgICAgICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksDQogICAgICAgICAgICAgIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvciA9ICIjMDAwMDAwIiksDQogICAgICAgICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEsY29sb3VyID0iI2ZmZmZmZiIpLCAgICAgICAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X21hcmtkb3duKGhqdXN0ID0gMC41KSwNCiAgICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICAgICAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbih0ID0gNSwgciA9IDEwLCBiID0gNSwyMCkgKQ0KYGBgDQoNCiMjIFBlc28geSBldm9sdWNpw7NuIGxvcyBmbHVqb3MgY29tZXJjaWFsZXMNCg0KRW4gZXN0ZSBncsOhZmljbyBwb2RlbW9zIG9ic2VydmFyIGxhIGV2b2x1Y2nDs24gZGVsIHBlc28gZW4gcG9yY2VudGFqZSBkZWwgUElCIHRhbnRvIGRlIGxhcyBleHBvcnRhY2lvbmVzIGNvbW8gZGUgbGFzIGltcG9ydGFjaW9uZXMuIE1lIGd1c3RhcsOtYSBkZXN0YWNhciBlbiBwcmltZXIgbHVnYXIgbGEgZGl2ZXJnZW5jaWEgcXVlIHNlIHByb2R1Y2UgYSBwYXJ0aXIgZGUgMTk2MCBlbnRyZSBsYXMgZXhwb3J0YWNpb25lcyB5IGxhcyBpbXBvcnRhY2lvbmVzLCB5IGVuIHNlZ3VuZG8gbHVnYXIgbGEgY2HDrWRhIHF1ZSBzdWZyaWVyb24gYW1iYXMgZW4gbGEgY3Jpc2lzIGRlIDIwMDguIEVzdGEgZGl2ZXJnZW5jaWEgcXVlIHNlIHByb2R1Y2UgYSBwYXJ0aXIgZGUgMTk2MCBsYSBwb2RlbW9zIGFzb2NpYXIgYSBsb3MgcGxhbmVzIGRlIEVzdGFiaWxpemFjacOzbiB5IERlc2Fycm9sbG8gbGxldmFkb3MgYSBjYWJvIGVuIGxhIMO6bGltYSBldGFwYSBkZWwgZnJhbnF1aXNtbywgZGljaG9zIHBsYW5lcyBwZXJtaXRpZXJvbiBhYnJpciBFc3Bhw7FhIGFsIGNvbWVyY2lvIGludGVybmFjaW9uYWwgZW50cmUgb3RyYXMgY29zYXMuDQoNCiMjIyBDw7NkaWdvDQpQYXJhIGVsYWJvcmFyIGVzdGUgZ3LDoWZpY28gaGUgc2VndWlkbyBlbCBtaXNtbyBtZXRvZG8gcXVlIGVuIGVsIGdyw6FmaWNvIGFudGVyaW9yLCDDum5pY2FtZW50ZSBoZSBtb2RpZmljYWRvIGxhcyBsw61uZWFzIG1lbm9yZXMgZGVsIGVqZSB5IHkgbG9zIGJyYWtlcyBkZSBsYSB2YXJpYWJsZSB4Lg0KDQpgYGB7cixlY2hvPUZBTFNFLCBldmFsPVRSVUV9DQpkYXRvc3ggPC0gImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS94aTc2NS9NaVByb3llY3RvSW5kaXZpZHVhbEFyY2hpdm9zL21haW4vWE1Xb3JsZEMuY3N2Ig0KZGF0b3NnIDwtICJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20veGk3NjUvTWlQcm95ZWN0b0luZGl2aWR1YWxBcmNoaXZvcy9tYWluL0dEUFdvcmxkQy5jc3YiDQojQ29nZW1vcyBkYXRvcyBkZSBFc3Bhw7FhIHkgb3Ryb3MgcGHDrXNlcyByZWxldmFudGVzIGVuIGVsIGNvbWVyY2lvIGludGVybmFjaW9uYWwNCmRmYSA8LSByaW86OmltcG9ydChkYXRvc2cpICU+JSBmaWx0ZXIoY291bnRyeWlzbzNjb2RlICVpbiUgYygiRVNQIikpDQpkZmIgPC0gcmlvOjppbXBvcnQoZGF0b3N4KSAlPiUgZmlsdGVyKGNvdW50cnlpc28zY29kZSAlaW4lIGMoIkVTUCIpKQ0KZGZ0IDwtIGlubmVyX2pvaW4oZGZhLGRmYiwgYnkgPSBjKCJjb3VudHJ5aXNvM2NvZGUiLCJ5ZWFyIikpICU+JSBzZWxlY3QoLWMoMSw4KSkgJT4lIHJlbG9jYXRlKDUsIC5iZWZvcmUgPSAxKSAlPiUgcmVsb2NhdGUoNiwgLmJlZm9yZSA9IDQpICU+JSByZWxvY2F0ZSg3LCAuYmVmb3JlID0gNikgJT4lIHJlbmFtZSgiaW5kaWNhZG9yIj0xLCJjb3VudHJ5Ij0yLCJnZHAiPTcsInhtIj04KSAlPiUgbXV0YXRlKHBvcmNwaWIgPSAoeG0vZ2RwKSkNCiNQbG90IGRlIGV4cG9ydGFjaW9uZXMNCg0KZGZwbG90IDwtIGRmdCAlPiUgZmlsdGVyKHllYXIgJWluJSBjKDE5NzA6MjAyMCkpDQpgYGANCmBgYHtyLGVjaG89VFJVRSwgZXZhbD1UUlVFLCBvdXQud2lkdGggPSAiMTUwJSJ9DQpnZ3Bsb3QoZGZ0LGFlcyh4PXllYXIseT1wb3JjcGliLGNvbG9yPWluZGljYWRvcikpICsgZ2VvbV9saW5lKHNpemU9MSkgKyBsYWJzKGNvbG9yPU5VTEwsDQogICAgICAgIHg9TlVMTCwNCiAgICAgICAgeT1OVUxMLA0KICAgICAgICB0aXRsZT0iUGVzbyBkZSBsYXMgPHNwYW4gc3R5bGU9J2NvbG9yOiNmZjA1MDU7Jz5FeHBvcnRhY2lvbmVzPC9zcGFuPiBlIDxzcGFuIHN0eWxlPSdjb2xvcjojMjRmZjA1Oyc+SW1wb3J0YWNpb25lcyA8L3NwYW4+ZW4gZWwgUElCIiwNCiAgICAgICAgY2FwdGlvbj0iRnVlbnRlOiBEYXRhQ29tZXgiKSArDQogICAgICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMTk2MCwyMDIwLDUpLGxpbWl0cyA9IGMoMTk2MCwyMDE5KSkgKw0KICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsMC4zLDAuMDUpLGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCkrDQogICAgICAgIHNjYWxlX2NvbG9yX21hbnVhbCggdmFsdWVzID0gYygiZXhwb3J0c3kiPSIjZmYwMDAwIiwiaW1wb3J0c3kiPSIjMjRkODAwIiksIGxhYmVscyA9IGMoIkV4cG9ydGFjaW9uZXMiLCJJbXBvcnRhY2lvbmVzIikpICsNCiAgICAgICAgdGhlbWUoIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCggZmlsbCA9ICIjZmZmZmZmIiksDQogICAgICAgICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiI2ZmZmZmZiIpLA0KICAgICAgICAgICAgICBwYW5lbC5ncmlkICA9IGVsZW1lbnRfbGluZSggY29sb3VyID0iIzk3OWU5ZSIpLA0KICAgICAgICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgICAgIHBhbmVsLmdyaWQubWlub3IueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiIzAwMDAwMCIpLA0KICAgICAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSwNCiAgICAgICAgICAgICAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG9yID0gIiMwMDAwMDAiKSwNCiAgICAgICAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfbWFya2Rvd24oaGp1c3QgPSAwLjUpLA0KICAgICAgICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BLGNvbG91ciA9ICIjZmZmZmZmIiksDQogICAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCmBgYA0KDQojIyBFeHBvcnRhY2nDs24gcG9yIGNvbXVuaWRhZGVzDQoNCkVuIGVzdGUgZ3LDoWZpY28gcG9kZW1vcyB2ZXIgbGFzIGNvbXVuaWRhZGVzIHF1ZSBleHBvcnRhcm9uIG1lcmNhbmPDrWFzIHBvciBtw6FzIHZhbG9yIGVuIDIwMTkuIENhYmUgZGVzdGFjYXIgbGEgZG9taW5hbmNpYSBkZSBCYXJjZWxvbmEsIG11eSBsZWpvcyBkZSBNYWRyaWQgeSBtdWNobyBtw6FzIGRlIGN1YWxxdWllciBvdHJhLiBOdWVzdHJhIGNvbXVuaWRhZCwgVmFsZW5jaWEsIHNlIGVuY3VlbnRyYSBlbiB0ZXJjZXJhIHBvc2ljacOzbiwgbcOhcyBjZXJjYSBkZSBaYXJhZ296YSBxdWUgZGUgTWFkcmlkLg0KDQojIyMgQ8OzZGlnbw0KRXN0YSB2ZXogaGUgZXNjb2dpZG8gdW5vIGRlIGxvcyB0ZW1hcyBxdWUgb2ZyZWNlIGVsIHBhcXVldGUgZ2dwbG90LCBxdWUgc2UgcGFyZWNlIG11Y2hvIGFsIHF1ZSBoZSBjcmVhZG8geW8geSBoZSB1c2FkbyBhbnRlcmlvcm1lbnRlLiANCg0KRW4gY3VhbnRvIGFsIGdyw6FmaWNvLCBlc3RhIHZleiBoZSBoZWNobyB1biBncsOhZmljbyBlc3RpbG8gTG9sbGlwb3AuIFBhcmEgY29uc3RydWlyIGVsIGdyw6FmaWNvIGhlIHVzYWRvIHVuIGdlb21fcG9pbnQoKSBqdW50byBhIHVuIGdlb21fc2VnbWVudCgpLiBQYXJhIGNvbmZpZ3VyYXIgZWwgZ2VvbV9zZWdtZW50KCkgaGUgdXNhZG8gZmFjdG9yZXMsIHlhIHF1ZSBoYXkgcXVlIGVzcGVjaWZpY2FyIHVuIHB1bnRvIGRlIGluaWNpbyB5IHVubyBkZSBmaW5hbC4NCmBgYHtyLGVjaG89RkFMU0UsIGV2YWw9VFJVRX0NCiNHUsOBRklDTyBERSBCQVJSQVMgUFJPVklOQ0lBUyBNw4FTIEVYUE9SVEFET1JBUw0KdXJsIDwtICJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20veGk3NjUvTWlQcm95ZWN0b0luZGl2aWR1YWxBcmNoaXZvcy9tYWluL2V4cF9pbXBfcHJvdl8yMDE5LmNzdiINCmV4cHByIDwtIHJlYWQuY3N2KHVybCkNCmV4cHByIDwtIGV4cHByICU+JSBzZWxlY3QoLWMoc3ViZmlsYSxzdWJjb2x1bW5hKSkNCmV4cHByIDwtIGV4cHByICU+JSByZW5hbWVfYXQodmFycyhjb2xuYW1lcyhleHBwcikpLCB+IGMoIlByb3ZpbmNpYSIsIlZhcmlhYmxlIiwiVmFsb3IiKSkNCmV4cHByIDwtIGV4cHByICU+JSBtdXRhdGUoVmFsb3IgPSBzdHJpbmdyOjpzdHJfcmVwbGFjZShWYWxvciwiKFssXSkiLCIuIikpICU+JSBtdXRhdGUoVmFsb3IgPSBhcy5udW1lcmljKFZhbG9yKSwgVmFsb3JFbk1pbGwgPSAoVmFsb3IvMTAwMDAwMCksIFZhbG9yTG9nID0gbG9nKFZhbG9yLCBiYXNlID0gZXhwKDIpKSkNCmV4cHByIDwtIGV4cHByICU+JSBtdXRhdGUoVmFsb3Jwb3JjID0gKFZhbG9yL2V4cHByWzEsM10pKQ0KIw0KZGF0YXBsb3QyIDwtIGV4cHByICU+JSBmaWx0ZXIoIFByb3ZpbmNpYSAhPSAiVG90YWwgc2VsZWNjaW9uYWRvIiwgVmFyaWFibGUgPT0gIkVYUE9SVCIpICU+JSBzbGljZV9tYXgob3JkZXJfYnkgPSBWYWxvcnBvcmMsIG4gPSAxMCkNCmBgYA0KYGBge3IsZWNobz1UUlVFLCBldmFsPVRSVUUsIG91dC53aWR0aCA9ICIxNTAlIn0NCnRoZW1lX3NldCh0aGVtZV9jbGFzc2ljKCkpDQpnZ3Bsb3QoZGF0YXBsb3QyLGFlcyh5ID0gVmFsb3JFbk1pbGwsIHggPSBmb3JjYXRzOjpmY3RfcmVvcmRlcihQcm92aW5jaWEsIFZhbG9yRW5NaWxsLCAuZGVzYyA9IFRSVUUpKSkgKyBnZW9tX3BvaW50KCkgKyBnZW9tX3NlZ21lbnQoYWVzKHg9Zm9yY2F0czo6ZmN0X3Jlb3JkZXIoUHJvdmluY2lhLCBWYWxvckVuTWlsbCwgLmRlc2MgPSBUUlVFKSwNCiAgICAgICAgICAgICAgICAgICB4ZW5kPWZvcmNhdHM6OmZjdF9yZW9yZGVyKFByb3ZpbmNpYSwgVmFsb3JFbk1pbGwsIC5kZXNjID0gVFJVRSksDQogICAgICAgICAgICAgICAgICAgeT0wLA0KICAgICAgICAgICAgICAgICAgIHllbmQ9VmFsb3JFbk1pbGwpKSsgDQogICAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsNjAwMDAsNTAwMCksbGFiZWxzID0gcGFzdGUoc2NhbGVzOjpjb21tYShzZXEoMCw2MDAwMCw1MDAwKSksIk3igqwiKSwgbGltaXRzID0gYygwLDYyNTAwKSkgKw0KICAgICAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBjKCJCYXJjZWxvbmEiLCJNYWRyaWQiLCJWYWxlbmNpYSIsIlphcmFnb3phIiwiQSBDb3J1w7FhIiwiTXVyY2lhIiwiTmF2YXJyYSIsIkJpemthaWEiLCJQb250ZXZlZHJhIiwiVGFycmFnb25hIikpKyBsYWJzKHRpdGxlPSJDb211bmlkYWRlcyBxdWUgbcOhcyBleHBvcnRhbiIsDQogICAgICAgc3VidGl0bGU9IkHDsW86IDIwMTkiLA0KICAgICAgIGNhcHRpb249IkZ1ZW50ZTogRGF0YUNvbWV4IiwNCiAgICAgICB4PU5VTEwsDQogICAgICAgeT1OVUxMKSArDQogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiI2RhZGFkYSIpLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTY1LCB2anVzdD0wLjk1LCBoanVzdCA9IDEpKQ0KYGBgDQoNCmBgYHtyLGVjaG89RkFMU0UsIGV2YWw9VFJVRX0NCmRhdG9zIDwtICJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20veGk3NjUvTWlQcm95ZWN0b0luZGl2aWR1YWxBcmNoaXZvcy9tYWluL1hDb21Qcm9kLmNzdiINCmRmY2NhYSA8LSByaW86OmltcG9ydChkYXRvcykgJT4lIHNlbGVjdChjKDEsMyw1KSkgJT4lIGZpbHRlcighY29sdW1uYSAlaW4lIGMoIlRvdGFsIE5hY2lvbmFsIiwiTm8gZGV0ZXJtaW5hZG8iKSkgJT4lIG11dGF0ZSggdmFsb3IgPSBzdHJfcmVwbGFjZSh2YWxvciwiWyxdIiwiLiIpLCB2YWxvciA9IGFzLm51bWVyaWModmFsb3IpLCBmaWxhID0gc3RyX3JlbW92ZShmaWxhLCJbWzpkaWdpdDpdXSsiKSwgZmlsYSA9IGNhc2Vfd2hlbihmaWxhID09ICJBIEdSQVNBUyBZIEFDRUlURVMiIH4gIkdSQVNBUyBZIEFDRUlURVMiLGZpbGEgPT0gIkIgU0VNSUxMQVMgWSBGUlVUT1MgT0xFQUdJTk9TT1MiIH4gIlNFTUlMTEFTIFkgRlJVVE9TIE9MRUFHSU5PU09TIixmaWxhID09ICJDIFBJRU5TT1MgQU5JTUFMRVMiIH4gIlBJRU5TT1MgQU5JTUFMRVMiLGZpbGEgPT0gIiBQUk9EVUNUT1MgQ8ODwoFSTklDT1MiIH4gIlBST0RVQ1RPUyBDw4FSTklDT1MiLCBmaWxhID09IGZpbGEgfiBmaWxhKSwgY29sdW1uYSA9IGNhc2Vfd2hlbihjb2x1bW5hID09ICJBbmRhbHVjw4PCrWEiIH4gIkFuZGFsdWPDrWEiLGNvbHVtbmEgPT0gIkFyYWfDg8KzbiIgfiAiQXJhZ8OzbiIsY29sdW1uYSA9PSAiQ2FzdGlsbGEgeSBMZcODwrNuIiB+ICJDYXN0aWxsYSB5IExlw7NuIixjb2x1bW5hID09ICJDYXRhbHXDg8KxYSIgfiAiQ2F0YWx1w7FhIixjb2x1bW5hID09ICJNdXJjaWEsIFJlZ2nDg8KzbiBkZSIgfiAiTXVyY2lhIixjb2x1bW5hID09ICJQYcODwq1zIFZhc2NvIiB+ICJQYcOtcyBWYXNjbyIsIGNvbHVtbmEgPT0gY29sdW1uYSB+IGNvbHVtbmEpLCBmaWxhID0gcGFzdGUoZmlsYSwiKE1pbGwuIGRlIOKCrCkiKSkNCg0KYWEgPC0gZGZjY2FhICU+JSBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gY29sdW1uYSwgdmFsdWVzX2Zyb20gPSB2YWxvcikgJT4lIGNvbHVtbl90b19yb3duYW1lcygiZmlsYSIpDQpgYGANCkFkaWNpb25hbG1lbnRlIGhlIGNvbnN0cnVpZG8gdW5hIHRhYmxhIGludGVyYWN0aXZhIGVuIGxhIHF1ZSBzZSBtdWVzdHJhbiBsYXMgZXhwb3J0YWNpb25lcyBwb3IgZ3J1cG8gZGUgcHJvZHVjdG9zIGRlIGNhZGEgY29tdW5pZGFkIGF1dMOzbm9tYSBlbiAyMDE5Lg0KDQpIZSB1c2FkbyBlbCBwYXF1ZXRlIERUIHBhcmEgaGFjZXJsYSBpbnRlcmFjdGl2YSB5IGHDsWFkaXJsZSBhbGd1bmFzIGV4dGVuc2lvbmVzOmxhIGV4dGVuc2nDs24gIkZpeGVkIENvbHVtbnMiIHBhcmEgcXVlIGxvcyBub21icmVzIGRlIGxhcyB2YXJpYWJsZXMgbm8gZGVzYXBhcmVjaWVyYW4gYWwgaGFjZXIgc2Nyb2xsIGhvcml6b250YWwgeSBsYSBleHRlbnNpw7NuIGJ1dHRvbnMgcGFyYSBhw7FhZGlybGUgdW4gYm90b24gcXVlIHBlcm1pdGUgZ3VhcmRhciBsYSB0YWJsYSBlbiBmb3JtYXRvIGV4Y2VsLg0KYGBge3IsZWNobz1UUlVFLCBldmFsPVRSVUV9DQpEVDo6ZGF0YXRhYmxlKGFhLCBleHRlbnNpb25zID0gYygiRml4ZWRDb2x1bW5zIiwiQnV0dG9ucyIpLA0KICBvcHRpb25zID0gbGlzdCgNCiAgICBkb20gPSAiQnRpcCIsDQogICAgc2Nyb2xsWCA9IFRSVUUsDQogICAgZml4ZWRDb2x1bW5zID0gVFJVRSwNCiAgICBhdXRvV2lkdGggPSBUUlVFLA0KICAgIGJ1dHRvbnMgPSBjKCJleGNlbCIpLA0KICAgIHBhZ2VMZW5ndGggPSA1KSkNCmBgYA0KDQojIyBEZXNnbG9zZSBkZSBsYXMgZXhwb3J0YWNpb25lcyBlc3Bhw7FvbGFzDQoNCkVuIGVzdGEgdGFibGEgaGUgZGVzZ2xvc2FkbyBlbCB0b3RhbCBkZSBpbXBvcnRhY2lvbmVzIHkgZXhwb3J0YWNpb25lcyBlc3Bhw7FvbGFzIHBvciBncnVwb3MgZGUgcHJvZHVjdG8geSBhw7FvLiBDYWJlIGRlc3RhY2FyIGVsIHBlc28gZGVsIHNlY3RvciBkZSBsYXMgc2VtaW1hbnVmYWN0dXJhcyBlbiBudWVzdHJhcyBFeHBvcnRhY2lvbmVzLiBSZXNwZWN0byBhIDE5OTUsIGVsIHNlY3RvciBhdXRvbcOzdmlsIGhhIHBlcmRpZG8gcGVzbyBhIGZhdm9yIGRlIGxhcyBzZW1pbWFudWZhY3R1cmFzIHkgbG9zIGJpZW5lcyBkZSBlcXVpcG8uDQoNCiMjIyBDw7NkaWdvDQoNClVuYSB2ZXogbGltcGlhZG9zIGxvcyBkYXRvcyBoZSB1c2FkbyBlbCBwYXF1ZXRlIEthYmxlRXh0cmEgcGFyYSBoYWNlciBlc3RhIHRhYmxhLiBCw6FzaWNhbWVudGUgaGUgdXNhZG8gbGEgZnVuY2nDs24ga2JsKCkgcGFyYSBoYWNlciBsYSB0YWJsYSBqdW50byBhIGxhIGZ1bmNpw7NuIGFkZF9oZWFkZXJfYWJvdmUoKSBwYXJhIGNyZWFyIGxvcyB0w610dWxvcyBkZSBjYWRhIGNvbHVtbmEuIEZpbmFsbWVudGUgaGUgdXNhZG8gbGEgZnVuY2nDs24ga2FibGVfc3R5bGluZygpIGNvbiBsb3MgYXJndW1lbnRvcyAic3RyaXBlZCIgeSAiaG92ZXIiIHBhcmEgZGVqYXJsYSBtw6FzIGFzZWFkYS4NCmBgYHtyLGVjaG89RkFMU0UsIGV2YWw9VFJVRX0NCiNYTSBQT1IgUFJPRFVDVE8gWSBGRUNIQSBFTiBNSUxMT05FUyBERSBFVVJPUw0KZGF0b3MgPC0gImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS94aTc2NS9NaVByb3llY3RvSW5kaXZpZHVhbEFyY2hpdm9zL21haW4vWE1Qcm9kdWN0by5jc3YiDQpkZnByb2QgPC0gcmlvOjppbXBvcnQoZGF0b3MpICU+JSBzZWxlY3QoLWMoMikpICU+JSBmaWx0ZXIoY29sdW1uYSAlaW4lIGMoIjE5OTUiLCIyMDE5IikpICU+JSBtdXRhdGUoIHZhbG9yID0gc3RyX3JlcGxhY2UodmFsb3IsIlssXSIsIi4iKSwgdmFsb3IgPSBhcy5udW1lcmljKHZhbG9yKSkNCg0KYSA8LSBpbm5lcl9qb2luKHggPSBkZnByb2QsIHkgPSBkZnByb2QgJT4lIGZpbHRlcihmaWxhID09ICJUb3RhbCBzZWxlY2Npb25hZG8iKSwgYnkgPSBjKCJjb2x1bW5hIiwic3ViY29sdW1uYSIpKSAlPiUgbXV0YXRlKHBvcmMgPSAodmFsb3IueC92YWxvci55KSkgJT4lIHNlbGVjdCgtYyg1LDYpKSAlPiUgbXV0YXRlKGZpbGEueCA9IGNhc2Vfd2hlbihmaWxhLnggPT0gIlRvdGFsIHNlbGVjY2lvbmFkbyIgfiAiVG90YWwiLCBmaWxhLnggPT0gIjEgQUxJTUVOVEFDScOD4oCcTiwgQkVCSURBUyBZIFRBQkFDTyIgfiAiQWxpbWVudGFjacOzbiwgYmViaWRhcyB5IHRhYmFjbyIsIGZpbGEueCA9PSAiMiBQUk9EVUNUT1MgRU5FUkdFVElDT1MiIH4gIlByb2R1Y3RvcyBlbmVyZ8OpdGljb3MiLCBmaWxhLnggPT0gIjMgTUFURVJJQVMgUFJJTUFTIiB+ICJNYXRlcmlhcyBwcmltYXMiLCBmaWxhLnggPT0gIjQgU0VNSU1BTlVGQUNUVVJBUyIgfiAiU2VtaW1hbnVmYWN0dXJhcyIsIGZpbGEueCA9PSAiNSBCSUVORVMgREUgRVFVSVBPIiB+ICJCaWVuZXMgZGUgZXF1aXBvIixmaWxhLnggPT0gIjYgU0VDVE9SIEFVVE9NT1ZJTCIgfiAiU2VjdG9yIGF1dG9tw7N2aWwiLGZpbGEueCA9PSAiNyBCSUVORVMgREUgQ09OU1VNTyBEVVJBREVSTyIgfiAiQmllbmVzIGRlIGNvbnN1bW8gZHVyYWRlcm8iLGZpbGEueCA9PSAiOCBNQU5VRkFDVFVSQVMgREUgQ09OU1VNTyIgfiAiTWFudWZhY3R1cmFzIGRlIGNvbnN1bW8iLGZpbGEueCA9PSAiOSBPVFJBUyBNRVJDQU5DSUFTIiB+ICJPdHJhcyBtZXJjYW5jw61hcyIpLCBwb3JjID0gcGVyY2VudChwb3JjKSwgdmFsb3IueCA9IGNvbW1hKHZhbG9yLngsIGRpZ2l0cyA9IDApKQ0KYWEgPC0gYSAlPiUgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IGMoc3ViY29sdW1uYSxjb2x1bW5hKSwgdmFsdWVzX2Zyb20gPSBjKHZhbG9yLngscG9yYykpICU+JSByZW5hbWUoIiAiID0gMSklPiUgc2VsZWN0KDEsMiw2LDMsNyw0LDgsNSw5KSAlPiUgc2xpY2UoMSw3LDUsNiwyLDEwLDgsMyw0LDkpICU+JSBzZXROYW1lcyhjKCIiLCJNaWxsLiBkZSDigqwiLCIlIiwiTWlsbC4gZGUg4oKsIiwiJSIsIk1pbGwuIGRlIOKCrCIsIiUiLCJNaWxsLiBkZSDigqwiLCIlIikpDQpgYGANCg0KYGBge3IsZWNobz1UUlVFLCBldmFsPVRSVUV9DQprYmwoYWEsIGZvcm1hdCA9ICJodG1sIiwgYm9va3RhYnMgPSBULCBsaW5lc2VwID0gIiIpICU+JSBhZGRfaGVhZGVyX2Fib3ZlKGMoIiIsIkV4cG9ydGFjaW9uZXMiID0gMiwgIkltcG9ydGFjaW9uZXMiID0gMiwgIkV4cG9ydGFjaW9uZXMiID0gMiwgIkltcG9ydGFjaW9uZXMiID0gMikpICU+JSBhZGRfaGVhZGVyX2Fib3ZlKGMoIiIsICIxOTk1IiA9IDQsICIyMDE5IiA9IDQpLCBsaW5lID0gVCkgJT4lICBrYWJsZV9zdHlsaW5nKGMoInN0cmlwZWQiLCJob3ZlciIpKSAlPiUgcm93X3NwZWMoMSwgYm9sZCA9IFRSVUUpDQpgYGANCiMjIE1lZGlvcyBkZSB0cmFuc3BvcnRlIG3DoXMgdXRpbGl6YWRvcw0KDQpFbiBlc3RvcyBncsOhZmljb3MgY2lyY3VsYXJlcyBwb2RlbW9zIGlkZW50aWZpY2FyIGxvcyBtZWRpb3MgZGUgdHJhbnNwb3J0ZSBtw6FzIHV0aWxpemFkb3MgcG9yIGVsIHNlY3RvciBleHRlcmlvciBlc3Bhw7FvbC4gQ2FiZSBkZXN0YWNhciBxdWUgZGVzZGUgMTk5NSBzZSBoYSByZWR1Y2lkbyBsYSBpbXBvcnRhbmNpYSBkZWwgdHJhbnNwb3J0ZSBwb3IgY2FycmV0ZXJhIGEgZmF2b3IgZGVsIG1hcsOtdGltby4gVGFtYmnDqW4gbWUgZ3VzdGFyw61hIGRlc3RhY2FyIGVsIHBvY28gcGVzbyBkZWwgdHJhbnNwb3J0ZSBwb3IgZmVycm9jYXJpbCwgc2llbmRvIHF1ZSBFc3Bhw7FhIHRpZW5lIHVuYXMgbXV5IGJ1ZW5hcyBpbmZyYWVzdHJ1Y3R1cmFzIGbDqXJyZWFzIGVsIGZlcnJvY2FycmlsIHBvZHLDrWEgc2VyIHVuYSBvcGNpw7NuIGRlIHRyYW5zcG9ydGUgbcOhcyBzb3N0ZW5pYmxlIHF1ZSBlbCB0cmFuc3BvcnRlIHBvciBjYXJyZXRlcmEuDQoNCiMjIyBDw7NkaWdvDQoNCkxhIHJlYWxpemFjacOzbiBkZSBlc3RlIGdyw6FmaWNvIGVzIHJlYWxtZW50ZSBzZW5jaWxsYSwgeWEgcXVlIHNpbXBsZW1lbnRlIGhheSBxdWUgYcOxYWRpciB1biBnZW9tX2JhcigpIGp1bnRvIGEgdW4gY29vcmRfcG9sYXIoKS4gQWRlbcOhcyBoZSB1c2FkbyBsYSBwYWxldGEgU2V0MSBkZWwgY29uanVudG8gZGUgcGFsZXRhcyBCcmV3ZXIgeSBoZSBwdWVzdG8gbGEgbGV5ZW5kYSBkZWJham8gZGVsIGdyw6FmaWNvLg0KYGBge3IsZWNobz1GQUxTRSwgZXZhbD1UUlVFfQ0KI01lZGlvcyBkZSB0cmFuc3BvcnRlIG3DoXMgdXRpbGl6YWRvcyAyMDE5IGVuIG1pbGxvbmVzIGRlIGV1cm9zDQpkYXRvcyA8LSAiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3hpNzY1L01pUHJveWVjdG9JbmRpdmlkdWFsQXJjaGl2b3MvbWFpbi9YTU1lZGlvVHJhbnNwb3J0ZS5jc3YiDQpkZnRyYW5zIDwtIHJpbzo6aW1wb3J0KGRhdG9zKSU+JSBzZWxlY3QoLWMoMikpICU+JSBtdXRhdGUoIHZhbG9yID0gc3RyX3JlcGxhY2UodmFsb3IsIlssXSIsIi4iKSwgdmFsb3IgPSBhcy5udW1lcmljKHZhbG9yKSwgZmlsYSA9IHN0cl9yZW1vdmUoZmlsYSwiW1s6ZGlnaXQ6XV0rIiksIGZpbGEgPSBjYXNlX3doZW4oIGZpbGEgPT0gIiAgTWFyw4PCrXRpbW8iIH4gIiAgTWFyw610aW1vIiwgZmlsYSA9PSAiICBUcsODwqFmaWNvIHBvc3RhbCIgfiAiICBUcsOhZmljbyBwb3N0YWwiLCBmaWxhID09ICIgIFByb3B1bHNpw4PCs24gcHJvcGlhIiB+ICIgIFByb3B1bHNpw7NuIHByb3BpYSIsIGZpbGEgPT0gZmlsYSB+IGZpbGEpKSAlPiUgZmlsdGVyKGNvbHVtbmEgIT0gIlRvdGFsIHNlbGVjY2lvbmFkbyIpDQoNCmEgPC0gaW5uZXJfam9pbiggeCA9IGRmdHJhbnMlPiVmaWx0ZXIoc3ViY29sdW1uYSA9PSAiRVhQT1JUIiksIHkgPSBkZnRyYW5zJT4lZmlsdGVyKHN1YmNvbHVtbmEgPT0gIklNUE9SVCIpLCBieSA9IGMoImZpbGEiLCJjb2x1bW5hIikpICU+JSBtdXRhdGUodG90YWx4bSA9ICh2YWxvci54K3ZhbG9yLnkpKSAlPiUgc2VsZWN0KC1jKDM6NikpDQphYSA8LSBpbm5lcl9qb2luKCB4ID0gYSU+JWZpbHRlcihmaWxhIT0iVG90YWwgbW9kbyB0cmFuc3BvcnRlIiksIHkgPSBhICU+JSBmaWx0ZXIoZmlsYT09IlRvdGFsIG1vZG8gdHJhbnNwb3J0ZSIpLCBieSA9IGMoImNvbHVtbmEiKSkgJT4lIG11dGF0ZShwb3JjID0gKHRvdGFseG0ueC90b3RhbHhtLnkpKSAlPiUgc2VsZWN0KC1jKDQsNSkpICU+JSBtdXRhdGUoZmlsYS54ID0gY2FzZV93aGVuKGZpbGEueCA9PSAiICBEZXNjb25vY2lkbyIgfiAiT3RybyIsZmlsYS54ID09ICIgIFBsYXRhZm9ybWEgZmlqYSIgfiAiT3RybyIsZmlsYS54ID09ICIgIFByb3B1bHNpw7NuIHByb3BpYSIgfiAiT3RybyIsZmlsYS54ID09ICIgIFRyw6FmaWNvIHBvc3RhbCIgfiAiT3RybyIsZmlsYS54ID09ICIgIFRyYW5zcG9ydGUgZmx1dmlhbCIgfiAiT3RybyIsIGZpbGEueCA9PSBmaWxhLnggfiBmaWxhLngpKSAlPiUgZ3JvdXBfYnkoY29sdW1uYSxmaWxhLngpICU+JSBzdW1tYXJpc2UodG90YWx4bS54ID0gc3VtKHRvdGFseG0ueCksIHBvcmMgPSBzdW0ocG9yYykpICU+JSBncm91cF9ieShjb2x1bW5hKSAlPiUgbXV0YXRlKGZpbGEueCA9IGZhY3RvcihmaWxhLngsIGxldmVscyA9IGZpbGEueFtvcmRlcihwb3JjLCBkZWNyZWFzaW5nID0gVFJVRSldKSkNCg0KYGBgDQpgYGB7cixlY2hvPVRSVUUsIGV2YWw9VFJVRSwgb3V0LndpZHRoID0gIjE1MCUifQ0KZ2dwbG90KGFhLCBhZXMoeCA9ICIiLCB5PXBvcmMsIGZpbGwgPSBmYWN0b3IoZmlsYS54KSkpICsNCiAgZ2VvbV9iYXIod2lkdGggPSAxLCBzdGF0ID0gImlkZW50aXR5Iixjb2xvciA9ICIjMDAwMDAwIikgKw0KICBjb29yZF9wb2xhcih0aGV0YSA9ICJ5Iiwgc3RhcnQ9MCkgKw0KICBsYWJzKGZpbGw9TlVMTCwNCiAgICAgICB4PU5VTEwsDQogICAgICAgeT1OVUxMLA0KICAgICAgIHRpdGxlPSJNZWRpb3MgZGUgdHJhbnNwb3J0ZSBkZSBtZXJjYW5jw61hcyBtw6FzIHV0aWxpemFkb3MiLA0KICAgICAgIGNhcHRpb249IkZ1ZW50ZTogRGF0YUNvbWV4IikgKyBmYWNldF93cmFwKHZhcnMoY29sdW1uYSksbnJvdyA9IDIsIG5jb2wgPSAyKSArDQogICAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsMC44LDAuMiksbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50KSArDQogICAgICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSArDQogICAgICB0aGVtZSggc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCggZmlsbCA9ICIjZmZmZmZmIiwgY29sb3VyID0gIiNmZmZmZmYiICksDQogICAgICAgICAgICAgIHBhbmVsLmdyaWQgID0gZWxlbWVudF9saW5lKCBjb2xvdXIgPSIjZmZmZmZmIiksDQogICAgICAgICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gIiNmZmZmZmYiKSwNCiAgICAgICAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgZmFjZSA9ICJib2xkIiwgY29sb3IgPSAiIzAwMDAwMCIpLA0KICAgICAgICAgICAgICBheGlzLmxpbmUgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLA0KICAgICAgICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjZmZmZmZmIiksDQogICAgICAgICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjZmZmZmZmIiwgY29sb3VyID0gIiNmZmZmZmYiKSwNCiAgICAgICAgICAgICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLGNvbG91ciA9ICJibGFjayIpLA0KICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikNCmBgYA0KDQojIDQuIFRyYWJham9zIGVuIGxvcyBxdWUgdGUgaGFzIGJhc2Fkbw0KDQpObyBoZSB1dGlsaXphZG8gbmluZ8O6biB0cmFiYWpvIGVuIGVzcGVjaWZpY28gY29tbyByZWZlcmVuY2lhLCBsYSBlc3RydWN0dXJhIHkgZ3LDoWZpY29zIGRlbCB0cmFiYWpvIGhhbiBzaWRvIGlkZWEgbWlhLiBMYSBtYXlvcsOtYSBkZSBwcm9ibGVtYXMgcXVlIGhlIHRlbmlkbyBsb3MgaGUgcmVzdWVsdG8gZ3JhY2lhcyBhbCBmb3JvIFtzdGFja292ZXJmbG93XShodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tLykgeSBhIGxhIHdlYiBkZSBsYSBhc2lnbmF0dXJhLkVuIGN1YW50byBhbCBkaXNlw7FvIGRlIGxvcyBncsOhZmljb3MsIGhlIGNvZ2lkbyBpZGVhcyBkZSBbZXN0YV0oaHR0cDovL3Itc3RhdGlzdGljcy5jby9Ub3A1MC1HZ3Bsb3QyLVZpc3VhbGl6YXRpb25zLU1hc3Rlckxpc3QtUi1Db2RlLmh0bWwpIHDDoWdpbmEgd2ViLiBUYW1iacOpbiBtZSBoYSByZXN1bHRhZG8gbXV5IMO6dGlsIGVzdGEgW3Zpw7FldGFdKGh0dHBzOi8vaGVucnl3YW5nLm5sL2dncGxvdDItdGhlbWUtZWxlbWVudHMtZGVtb25zdHJhdGlvbi8pIHBhcmEgY3JlYXIgbG9zIHRlbWFzLg0KDQojIDUuIEJpYmxpb2dyYWbDrWENCiogW0RhdGFDb21leF0oaHR0cHM6Ly9jb21lcmNpby5zZXJ2aWNpb3NtaW4uZ29iLmVzL0RhdGFjb21leC8pDQoqIFtPcmdhbml6YWNpw7NuIE11bmRpYWwgZGVsIENvbWVyY2lvXShodHRwczovL3d3dy53dG8ub3JnLykNCiogW0JhbmNvIE11bmRpYWxdKGh0dHBzOi8vd3d3LndvcmxkYmFuay5vcmcvKQ0K