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. La página web de la asignatura puede verse aquí: https://perezp44.github.io/intro-ds-20-21-web/. Los trabajos de mis compañeros de curso pueden verse aquí.


1. Introducción

El año 2020 no será un año recordado por todos los habitantes del planeta con una sonrisa en el rostro. Una pandemia se apoderaba del planeta 100 años después de la mal llamada gripe española y nos hacía entrar en una pesadilla que a día de hoy todavía tiene un incierto final.

Las causas de la pandemia, después de 1 año, aún no están claras. La mayoría de los cientifícos (incluida la OMS) sostienen que la covid19 podría ser de origen animal pero para otros la existencia del mayor centro chino de investigación virológica sobre Coronavirus a poca distancia del mercado de Wuhan (epicentro del virus), alimenta las teorías de la conspiración.

Este trabajo se va a basar en las consecuencias de la Covid19 en nuestra región. Primero explicaremos brevemente que es la Covid19 y que medidas básicas tomar para prevenirnos de ella. Posteriormente presentaremos las distintas variables que se utilizan para estudiar la evolución de la pandemia. La última parte (y la más densa) estudiará la evolución de la pandemia en los municipios que integran nuestra “Comunitat”. Todos los días nos llegan noticias sobre los países que tienen más infectados, más fallecidos, los que tienen una tasa de incidencia acumulada más alta… etc. ¿Sabemos como calcular estas variables?¿Sabemos interpretarlas?¿Alguien sabe algo sobre estos datos en nuestra región? ¿Que muninipio tiene una tasa de incidencia acumulada más alta?¿Y una tasa de mortalidad mayor? LO VEMOS.

2. Información básica sobre la Covid-19

2.1. ¿Qué es la Covid-19?

La COVID-19 es una enfermedad infecciosa causada por el coronavirus SARS- CoV-2. Los coronavirus son una familia de virus que normalmente afectan solo a animales. Algunos de ellos también tienen la capacidad de transmitirse de los animales a las personas lo que causa problemas respiratorios.

El coronavirus SARS-CoV-2 es un nuevo tipo de coronavirus que puede afectar a las personas y que se detectó por primera vez en diciembre de 2019 en la ciudad de Wuhan, provincia de Hubei, en China.

1

2.2. Formas de transmisión del SARS-CoV-2.

El coronavirus es un virus que se contagia con las gotas respiratorias que expulsamos los humanos. Esto quiere decir que las personas infectadas cuando hablan, gritan, estornudan o cantan expulsan continuamente unas gotas que contienen el virus. Estas partículas pueden ir hasta dos metros si estamos hablando, hasta 5 metros si estamos cantando o gritando o hasta 8 metros si estornudamos sin taparnos. También hablar en alto o a gritos puede generar el triple de partículas que hacerlo en voz baja. Si alguien está interesado sobre esto último puede consultar aquí la información.

Estas gotas pueden infectar directamente a personas que tenemos cerca, aferrándose a las células ubicadas en la mucosa de la nariz, garganta y/o ojos de las persona infectadas, pero también contaminan la superficie donde caen. Si personas tocan estas superficies y se tocan nariz, garganta u ojos, con una alta probabilidad, se infectarán. Estas son las dos transmisiones de la enfermedad que se conocieron desde el principio pero no es la única parece ser. La gran parte de la comunidad científica (menos la OMS), basados en la evidencia científica, están de acuerdo que estas gotas pueden permanecer suspendidas en el aire hasta 8 horas despúes de haber sido expulsadas. Por tanto, si alguien portador del virus está sin mascarilla en una zona interior sin ventilación, toda persona que no lleve una mascarilla FFP2 podría contagiarse si entra en ese ambiente y permanece un tiempo en él.

2.3. Medidas preventivas.

El título de este sub-apartado no es casual. A día de hoy no existe medicamento ni vacuna efectiva demostrada que pueda erradicar la COVID-19. Un virus se puede eliminar cuando se consigue en una comunidad la inmunidad de grupo (que el 70% de la población haya pasado la enfermedad) o desarrollando una vacuna que lo neutralice. La primera medida fue tomada por algunos países (Reino Unido, Suecia, EEUU y Brasil) y tristemente, ya conocemos los resultados.

Por esta secilla razón y hasta que aparezca la ansiada vacuna tenemos que seguir cumpliendo una serie de medidas para intentar frenar el avance de la pandemia:

  • Uso de mascarillas. FUNDAMENTAL!!.
  • Lavado continuo de manos.
  • Evitar los espacios cerrados sin ventilación.
  • Evitar locales de interior en los que la mascarilla no sea obligatoria.

Os dejamos dos campañas que nos han gustado especialmente:

3. Indicadores de evolución de la pandemia.

Más adelante vamos a analizar 4 indicadores distintos que se utilizan para saber en que punto de evolución está la pandemia en cada área geográfica. Si estos indicadores arrojan resultados negativos, la administración se ve obligada a intervenir y toma medidas más restrictivas. Vamos a analizar dos que pueden llevar a una mala interpretación de los resultados:

3.1. Indicadores explicados

3.1.1. Tasa de Incidencia acumulada.

Son las personas que han enfermado por Covid-19 por cada 100.000 habitantes. Se calcula por cada 100.000 habitantes para poder comparar entre municipios ya que en términos absolutos siempre sería mayor en los municipios con mayor población y no sería posible la comparación.

En este informe vamos a utilizar la tasa de incidencia acumulada y la tasa de incidencia de los últimos 14 días. La primera de ella se utiliza para poder comparar los datos de incidencia de la Covid19 desde el inicio de la pandemia y la segunda se utiliza para poder comparar los datos de incidencia de la Covid19 en los últimos 14 días.

Si queremos obtener la incidencia a 14 días la podemos calcular dividiendo el número de casos aparecidos entre el número de personas que están libres de la enfermedad al inicio del periodo. Normalmente se suele tener en cuenta cada 100.000 habitantes y a 14 días.Se calcula así:

3.1.1. Tasa de mortalidad.

Normalmente se expresa como el número de muertes por cada 100.000 habitantes Se obtiene multiplicando los fallecimientos por Covid por 100.000 y dividiendo el resultado entre la población total:

4. Efectos de la Covid-19 en la C.V.

4.1. Evolución de los contagios.


dfpositivos <- rio::import("./datos/covid-19-serie-de-casos-con-pdia-positiva-en-la-comunitat-valenciana.csv")

dfpositivos <- dfpositivos %>% select(`Data diagnòstic laboratori/fecha diagnóstico laboratorio`, `Homes/Hombres`, `Dones/Mujeres`, 
                                      `Prov. Alacant/Alicante`, `Prov. Castelló/Castellón`, `Prov. València`)  #- los departamentos de salud no me interesan para este trabajo

#aquí lo primero que tenemos que hacer es cambiar nombres raros de columnas

nombres_originales1 <- names(dfpositivos)
nombres_originales1
#> [1] "Data diagnòstic laboratori/fecha diagnóstico laboratorio"
#> [2] "Homes/Hombres"                                             
#> [3] "Dones/Mujeres"                                             
#> [4] "Prov. Alacant/Alicante"                                    
#> [5] "Prov. Castelló/Castellón"                                
#> [6] "Prov. València"
names(dfpositivos)[1] <- "Fecha PCR Positiva"
names(dfpositivos)[2] <- "Hombres"
names(dfpositivos)[3] <- "Mujeres"
names(dfpositivos)[4] <- "Alicante"
names(dfpositivos)[5] <- "Castellón"
names(dfpositivos)[6] <- "Valencia"

#install.packages("gifski")
#install.packages("gganimate")

dfpositivos$C.Valenciana <- dfpositivos$Alicante + dfpositivos$Castellón + dfpositivos$Valencia

grafico1 <- ggplot(dfpositivos, aes(`Fecha PCR Positiva`, `C.Valenciana`)) + 
  geom_line(color="green", size=1)+ labs(title = "Positivos detectados por PCR el día {frame_along}", "x = Fecha", caption = "Fuente GVA")+ theme_minimal()+  
  transition_reveal(`Fecha PCR Positiva`)

grafico1

La evolución de los contagios por Covid-19 que nos enseña este gráfico animado refleja muy bien las llamadas “olas” que nos ha dejado, por el momento, esta pandemia.

Podemos observar un aumento rápido de los contagios entre marzo y abril. Aquí cabría reseñar que estos datos no son tan fidedignos como los de meses posteriores ya que no se hacían las suficientes pruebas por la falta de pruebas diagnósticas PCR. Según un estudio de seroprevalencia realizado en los meses de abril y mayo más de 125.000 valencianos infectados se contagiaron durante los primeros meses.

El confinamiento decretado de dos meses nos sirvió para ir descendiendo el número de contagios gradualmente desde mayo, hasta llegar a tener cifras diarias de contagios relativamente bajas, ya en en el mes de junio.

La rápida desescalada hecha por el gobierno (presionado por las CCAA), unida a la actitud irresponsable de muchos ciudadanos durante el verano, provocó la segunda ola de la pandemia. Podemos observar que la gráfica refleja que a partir de finales de julio, los datos empiezan a dispararse de nuevo. Esta segunda ola tendrá su pico a medidados de noviembre, donde parece descender hasta nuestros días.

4.2. Evolución de los fallecidos.


dffall <- rio::import("./datos/covid-19-serie-de-personas-fallecidas-en-la-comunitat-valenciana.csv")

#- los departamentos de salud no me interesan para este trabajo
dffall <- dffall %>% select(`Data de defunció/fecha de defunción`, `Homes/Hombres`, `Dones/Mujeres`,
                            `Prov. Alacant/Alicante`, `Prov. Castelló/Castellón`, `Prov. València`) 

#aquí lo primero que tenemos que hacer es cambiar nombres raros de columnas

nombres_originales <- names(dffall)
nombres_originales
#> [1] "Data de defunció/fecha de defunción"
#> [2] "Homes/Hombres"                        
#> [3] "Dones/Mujeres"                        
#> [4] "Prov. Alacant/Alicante"               
#> [5] "Prov. Castelló/Castellón"           
#> [6] "Prov. València"
names(dffall)[1] <- "Fecha_Defunción"
names(dffall)[2] <- "Hombres"
names(dffall)[3] <- "Mujeres"
names(dffall)[4] <- "Alicante"
names(dffall)[5] <- "Castellón"
names(dffall)[6] <- "Valencia"

dffall$C.Valenciana <- dffall$Alicante + dffall$Castellón + dffall$Valencia

grafico2 <- ggplot(dffall, aes(`Fecha_Defunción`, `C.Valenciana`)) + 
  geom_line(color="orange", size=1)+ labs(title = "Fallecidos por Covid-19 el día {frame_along}")+ theme_minimal()+  
  transition_reveal(`Fecha_Defunción`)

grafico2

La evolución de los fallecidos muestra una evolución idéntica a la evolución de contagios pero con dos matices:

  • Los incrementos de contagios se reflejan en número de muertes aproximadamente 15 días después de producirse dichos contagios, por lo que habrá un desfase temporal en estos dos gráficos.

  • La mayor disponibilidad de equipos de protección adecuados para sanitarios y personal de residencias, la imposición de la mascarilla obligatoria para toda la ciudadania, el incremento espectacular en el número de pruebas PCR realizadas, la “bunquerización” de las residencias de ancianos y la experiencia ganada por las distintas administraciones en la gestión de la pandemia, ha conseguido reducir el número de fallecimientos en esta segunda ola (no el número de infectados).

Hay que advertir que el número de fallecidos de las estadísticas no refleja el número de fallecidos real que ha habido en nuestro país. En un primer momento, con los hospitales colapsados, la prioridad fue tratar a los enfermos sin hacer pruebas forenses a los fallecidos que determinaran si estas muertes eran provocadas por la Covid-19. Cuando a la persona fallecida no se le había hecho una PCR previa al fallecimiento, los médicos ponían en sus informes la Covid-19 como causa probable de la muerte pero el gobierno no las incluía en las estadísticas oficiales de víctimas por Covid-19.

De todas maneras se puede saber aproximadamente el número de fallecidos reales que ha habido en nuestro país si comparamos los datos de fallecidos que tiene el INE entre un año y otro. Según esta noticia hay 70.717 fallecidos más que en 2019 y todavía no ha terminado el año.

dffall <- rio::import("./datos/covid-19-serie-de-personas-fallecidas-en-la-comunitat-valenciana.csv")

#- los departamentos de salud no me interesan para este trabajo
dffall <- dffall %>% select(`Data de defunció/fecha de defunción`, `Homes/Hombres`, `Dones/Mujeres`,
                            `Prov. Alacant/Alicante`, `Prov. Castelló/Castellón`, `Prov. València`) 

#aquí lo primero que tenemos que hacer es cambiar nombres raros de columnas

nombres_originales <- names(dffall)
nombres_originales
#> [1] "Data de defunció/fecha de defunción"
#> [2] "Homes/Hombres"                        
#> [3] "Dones/Mujeres"                        
#> [4] "Prov. Alacant/Alicante"               
#> [5] "Prov. Castelló/Castellón"           
#> [6] "Prov. València"
names(dffall)[1] <- "Fecha_Defunción"
names(dffall)[2] <- "Hombres"
names(dffall)[3] <- "Mujeres"
names(dffall)[4] <- "Alicante"
names(dffall)[5] <- "Castellón"
names(dffall)[6] <- "Valencia"

dffall$C.Valenciana <- dffall$Alicante + dffall$Castellón + dffall$Valencia


p <- ggplot(dffall) + geom_line(aes(x= Fecha_Defunción, y= Hombres),color = "yellow") +
  geom_line (aes(x= Fecha_Defunción, y = Mujeres), color = "blue")+
    labs(title = "Fallecidos por género",
         subtitle = "Comparación",
       caption = "Datos proporcionados por la GVA",
       x="Fecha", y="Número de fallecidos")+
  theme_dark()

ggplotly(p)

Como curiosidad aportamos este gráfico interactivo en el que se muestra que se han producido más fallecimientos en hombres que en mujeres.


aa <- as.data.frame(colours())

dffalledad <- rio::import("./datos/covid-19-datos-de-casos-y-personas-fallecidas-por-grupo-de-edad-y-sexo-acumulados-desde-el-31-01.csv")

dffalledadmujeres <- dffalledad %>%  slice(c(1:10))

dffalledadhombres <- dffalledad %>%  slice(c(11:20))

janitor::clean_names(dffalledadmujeres) %>% names()
#> [1] "grup_edat"         "sexe"              "percentatge"      
#> [4] "casos_acumulats"   "percentatge_morts" "defuncions"

p1 <- ggplot (dffalledadmujeres, aes(Grup_edat, Percentatge_morts)) + geom_col(fill= "tomato") + coord_flip() +
  labs (title = "% muertes de mujeres",
    subtitle = "Clasificado por grupo de edad",
    y = "% muertes COVID19",
    x = "Grupo de edad") + theme_solarized()

p2 <- ggplot (dffalledadhombres, aes(Grup_edat, Percentatge_morts)) + geom_col(fill= "brown") + coord_flip() + 
  labs (title = "% muertes de hombres",
    subtitle = "Clasificado por grupo de edad",
    caption = "Fuente GVA",
    y = "% muertes COVID19",
    x = "Grupo de edad") + theme_solarized()

p1+p2

Este otro gráfico muestra los tramos de edad de las personas fallecidas y los compara además por género.

Podemos observar que, desgraciadamente, los individuos que tenían más de 70 años han sido las grandes víctimas de esta pandemia.

5. Variables analizadas.

5.1. Tabla para consulta sobre datos .

En esta tabla resumen interactiva, con todos los datos obtenidos en la web de la GVA, podemos consultar los datos del municipio en el que residimos pero además permite exportar cualquier dato en el formato que a cada persona le interese.


load("./datos/geometrias_clase_10.RData")
dfgva <- rio::import("./datos/covid-19-casos-confirmados-por-pcr-casos-pcr-en-los-ultimos-14-dias-y-personas-fallecidas-por-mu.csv")
dfpoblacion_gva <- rio::import("./datos/poblacion_muni_vlc.xls")

nombres_originales <- names(dfgva)
nombres_originales
#> [1] "CodMunicipio"                 "Municipi"                    
#> [3] "Casos PCR+"                   "Incidència acumulada PCR+"  
#> [5] "Casos PCR+ 14 dies"           "Incidència acumulada PCR+14"
#> [7] "Defuncions"                   "Taxa de defunció"
names(dfgva)[1] <- "CodMunicipio"
names(dfgva)[2] <- "Municipi"
names(dfgva)[3] <- "Casos"
names(dfgva)[4] <- "Incidencia_acumulada"
names(dfgva)[5] <- "Casos_ult14d"
names(dfgva)[6] <- "Incidencia_ acumulada_ult14d"
names(dfgva)[7] <- "Defuncions"
names(dfgva)[8] <- "Tasa_defuncion"

dfgva <- dfgva %>% mutate(CodMunicipio = as.numeric(CodMunicipio))
municipios_2017 <- municipios_2017 %>% mutate(INECodMuni = as.numeric(INECodMuni))

dfpueblos <- inner_join(dfgva, municipios_2017, by = c("CodMunicipio" = "INECodMuni" ))

dfpueblos_def <- inner_join(dfpueblos, dfpoblacion_gva, by = c("CodMunicipio" = "Codi_Municipi" ))

dfmunicipios <- dfpueblos_def %>% select(`CodMunicipio`,`NombreMuni`, `Poblacions`,`Casos`,`Incidencia_acumulada`,`Defuncions`, `Casos_ult14d`, `Incidencia_ acumulada_ult14d`, `Tasa_defuncion`) %>% arrange(desc(`Incidencia_ acumulada_ult14d`, `Tasa_defuncion`))

dfmunicipios %>% DT::datatable(extensions = 'Buttons', 
                              options = list(dom = 'Blfrtip', 
                                             buttons = c('copy', 'csv', 'excel', 'pdf', 'print'), 
                                             pageLength = 5, autoWidth = TRUE )) %>% formatStyle (
                                               'Incidencia_ acumulada_ult14d', 
                                               backgroundColor = '#F59985', )

5.2. Incidencia acumulada últimos 14 días.

Hemos explicado en el apartado 3, qué es y como calcular,la incidencia acumulada a 14 días. Se utiliza para tener un indicador de la evolución de la pandemia en los últimos 14 días, proporcionando una herramienta útil a los responsables de las administraciones públicas para tomar decisiones sobre las restricciones a aplicar.

5.2.1. Semáforo Covid-19.

Se ha creado el Semáforo Covid para determinar que medidas aplicar según el riesgo en que se encuentre cada municipio. El semáforo analiza varios indicadores: incidencia acumulada a 14 días, presión UCI, hospitalizaciones, incidencia a 7 días… etc.

Hemos querido mostrar los 5 municipios valencianos (con mayor número de población) que se encuentran en cada estado según incidencia a 14 días.


dfgva <- rio::import("./datos/covid-19-casos-confirmados-por-pcr-casos-pcr-en-los-ultimos-14-dias-y-personas-fallecidas-por-mu.csv")
dfpoblacion_gva <- rio::import("./datos/poblacion_muni_vlc.xls")
load("./datos/geometrias_clase_10.RData")

nombres_originales <- names(dfgva)
nombres_originales
#> [1] "CodMunicipio"                 "Municipi"                    
#> [3] "Casos PCR+"                   "Incidència acumulada PCR+"  
#> [5] "Casos PCR+ 14 dies"           "Incidència acumulada PCR+14"
#> [7] "Defuncions"                   "Taxa de defunció"
names(dfgva)[1] <- "CodMunicipio"
names(dfgva)[2] <- "Municipi"
names(dfgva)[3] <- "Casos"
names(dfgva)[4] <- "Incidencia_acumulada"
names(dfgva)[5] <- "Casos_ult14d"
names(dfgva)[6] <- "Incidencia_ acumulada_ult14d"
names(dfgva)[7] <- "Defuncions"
names(dfgva)[8] <- "Tasa_defuncion"

dfgva <- dfgva %>% mutate(CodMunicipio = as.numeric(CodMunicipio))
municipios_2017 <- municipios_2017 %>% mutate(INECodMuni = as.numeric(INECodMuni))
dfpueblos <- inner_join(dfgva, municipios_2017, by = c("CodMunicipio" = "INECodMuni" ))
dfpueblos_def <- inner_join(dfpueblos, dfpoblacion_gva, by = c("CodMunicipio" = "Codi_Municipi" ))
dfmunicipios <- dfpueblos_def %>% select(`CodMunicipio`,`NombreMuni`, `Poblacions`,`Casos`,`Incidencia_acumulada`,`Defuncions`, `Casos_ult14d`, `Incidencia_ acumulada_ult14d`, `Tasa_defuncion`, `INECodProv`, `INECodCCAA`, `NombreMuni`, `NombreProv`, `geometry` )
rm(dfgva,dfpoblacion_gva,dfpueblos,dfpueblos_def, municipios_2017, IGN_nomencla_muni, rios, world)

dfmunicipios_25 <- dfmunicipios %>% filter(`Incidencia_ acumulada_ult14d` <= 25)%>% arrange(desc(`Poblacions`))%>% slice(1:5)%>% arrange(desc(`Incidencia_ acumulada_ult14d`)) 
dfmunicipios_25_tabla <- dfmunicipios_25 %>% select(`NombreMuni`,`Poblacions`, `Incidencia_ acumulada_ult14d`) %>% arrange(desc(`Incidencia_ acumulada_ult14d`)) 

dfmunicipios_25_tabla %>%
  kbl() %>%
  kable_classic(full_width = F, html_font = "Cambria") %>%
  kable_styling(bootstrap_options = c("striped", "hover")) %>% row_spec(row = 0:5 ,bold = T,background = "#c4f1b7", font_size = 15)%>%
  scroll_box(width = "100%", height = "300px")
NombreMuni Poblacions Incidencia_ acumulada_ult14d
Oropesa del Mar/Orpesa 9076 0
Benitachell/el Poble Nou de Benitatxell 4276 0
Godelleta 3533 0
Altura 3528 0
Busot 2978 0
“Incidencia a 14 días menor a 25”

dfgva <- rio::import("./datos/covid-19-casos-confirmados-por-pcr-casos-pcr-en-los-ultimos-14-dias-y-personas-fallecidas-por-mu.csv")
dfpoblacion_gva <- rio::import("./datos/poblacion_muni_vlc.xls")
load("./datos/geometrias_clase_10.RData")

nombres_originales <- names(dfgva)
nombres_originales
#> [1] "CodMunicipio"                 "Municipi"                    
#> [3] "Casos PCR+"                   "Incidència acumulada PCR+"  
#> [5] "Casos PCR+ 14 dies"           "Incidència acumulada PCR+14"
#> [7] "Defuncions"                   "Taxa de defunció"
names(dfgva)[1] <- "CodMunicipio"
names(dfgva)[2] <- "Municipi"
names(dfgva)[3] <- "Casos"
names(dfgva)[4] <- "Incidencia_acumulada"
names(dfgva)[5] <- "Casos_ult14d"
names(dfgva)[6] <- "Incidencia_ acumulada_ult14d"
names(dfgva)[7] <- "Defuncions"
names(dfgva)[8] <- "Tasa_defuncion"

dfgva <- dfgva %>% mutate(CodMunicipio = as.numeric(CodMunicipio))
municipios_2017 <- municipios_2017 %>% mutate(INECodMuni = as.numeric(INECodMuni))
dfpueblos <- inner_join(dfgva, municipios_2017, by = c("CodMunicipio" = "INECodMuni" ))
dfpueblos_def <- inner_join(dfpueblos, dfpoblacion_gva, by = c("CodMunicipio" = "Codi_Municipi" ))
dfmunicipios <- dfpueblos_def %>% select(`CodMunicipio`,`NombreMuni`, `Poblacions`,`Casos`,`Incidencia_acumulada`,`Defuncions`, `Casos_ult14d`, `Incidencia_ acumulada_ult14d`, `Tasa_defuncion`, `INECodProv`, `INECodCCAA`, `NombreMuni`, `NombreProv`, `geometry` )
rm(dfgva,dfpoblacion_gva,dfpueblos,dfpueblos_def, municipios_2017, IGN_nomencla_muni, rios, world)

dfmunicipios25_50 <- dfmunicipios %>% filter(`Incidencia_ acumulada_ult14d` %in% (25:50))%>% arrange(desc(`Poblacions`))%>% slice(1:5)%>% arrange(desc(`Incidencia_ acumulada_ult14d`)) 
dfmunicipios_25_50_tabla <- dfmunicipios25_50 %>% select(`NombreMuni`,`Poblacions`, `Incidencia_ acumulada_ult14d`) %>% arrange(desc(`Incidencia_ acumulada_ult14d`)) 

dfmunicipios_25_50_tabla %>%
  kbl() %>% 
  kable_classic(full_width = F, html_font = "Cambria") %>%
  kable_styling(bootstrap_options = c("striped", "hover")) %>% row_spec(row = 0:5 ,bold = T, background = "#f3e2ab", font_size = 15)%>%
  scroll_box(width = "100%", height = "300px")
NombreMuni Poblacions Incidencia_ acumulada_ult14d
Benaguasil 10988 46
Moncofa 6525 46
Bigastro 6733 45
Buñol 9408 32
La Nucia 18603 27
“Incidencia a 14 días entre 25 y 50”

dfgva <- rio::import("./datos/covid-19-casos-confirmados-por-pcr-casos-pcr-en-los-ultimos-14-dias-y-personas-fallecidas-por-mu.csv")
dfpoblacion_gva <- rio::import("./datos/poblacion_muni_vlc.xls")
load("./datos/geometrias_clase_10.RData")

nombres_originales <- names(dfgva)
nombres_originales
#> [1] "CodMunicipio"                 "Municipi"                    
#> [3] "Casos PCR+"                   "Incidència acumulada PCR+"  
#> [5] "Casos PCR+ 14 dies"           "Incidència acumulada PCR+14"
#> [7] "Defuncions"                   "Taxa de defunció"
names(dfgva)[1] <- "CodMunicipio"
names(dfgva)[2] <- "Municipi"
names(dfgva)[3] <- "Casos"
names(dfgva)[4] <- "Incidencia_acumulada"
names(dfgva)[5] <- "Casos_ult14d"
names(dfgva)[6] <- "Incidencia_ acumulada_ult14d"
names(dfgva)[7] <- "Defuncions"
names(dfgva)[8] <- "Tasa_defuncion"

dfgva <- dfgva %>% mutate(CodMunicipio = as.numeric(CodMunicipio))
municipios_2017 <- municipios_2017 %>% mutate(INECodMuni = as.numeric(INECodMuni))
dfpueblos <- inner_join(dfgva, municipios_2017, by = c("CodMunicipio" = "INECodMuni" ))
dfpueblos_def <- inner_join(dfpueblos, dfpoblacion_gva, by = c("CodMunicipio" = "Codi_Municipi" ))
dfmunicipios <- dfpueblos_def %>% select(`CodMunicipio`,`NombreMuni`, `Poblacions`,`Casos`,`Incidencia_acumulada`,`Defuncions`, `Casos_ult14d`, `Incidencia_ acumulada_ult14d`, `Tasa_defuncion`, `INECodProv`, `INECodCCAA`, `NombreMuni`, `NombreProv`, `geometry` )
rm(dfgva,dfpoblacion_gva,dfpueblos,dfpueblos_def, municipios_2017, IGN_nomencla_muni, rios, world)

dfmunicipios50_150 <- dfmunicipios %>% filter(`Incidencia_ acumulada_ult14d` %in% (50:150))%>% arrange(desc(`Poblacions`))%>% slice(1:5) %>% arrange(desc(`Incidencia_ acumulada_ult14d`)) 
dfmunicipios_50_150_tabla <- dfmunicipios50_150 %>% select(`NombreMuni`,`Poblacions`, `Incidencia_ acumulada_ult14d`) %>% arrange(desc(`Incidencia_ acumulada_ult14d`)) 

dfmunicipios_50_150_tabla %>%
  kbl() %>%
  kable_classic(full_width = F, html_font = "Cambria") %>%
  kable_styling(bootstrap_options = c("striped", "hover")) %>% row_spec(row = 0:5 , bold = T, background = "#f3c364", font_size = 15)%>%
  scroll_box(width = "100%", height = "300px")
NombreMuni Poblacions Incidencia_ acumulada_ult14d
Castellón de la Plana/Castelló de la Plana 171728 126
Benidorm 68721 98
Mislata 43691 94
Torrevieja 83337 70
Orihuela 77414 62
“Incidencia a 14 días entre 50 y 150”

dfgva <- rio::import("./datos/covid-19-casos-confirmados-por-pcr-casos-pcr-en-los-ultimos-14-dias-y-personas-fallecidas-por-mu.csv")
dfpoblacion_gva <- rio::import("./datos/poblacion_muni_vlc.xls")
load("./datos/geometrias_clase_10.RData")

nombres_originales <- names(dfgva)
nombres_originales
#> [1] "CodMunicipio"                 "Municipi"                    
#> [3] "Casos PCR+"                   "Incidència acumulada PCR+"  
#> [5] "Casos PCR+ 14 dies"           "Incidència acumulada PCR+14"
#> [7] "Defuncions"                   "Taxa de defunció"
names(dfgva)[1] <- "CodMunicipio"
names(dfgva)[2] <- "Municipi"
names(dfgva)[3] <- "Casos"
names(dfgva)[4] <- "Incidencia_acumulada"
names(dfgva)[5] <- "Casos_ult14d"
names(dfgva)[6] <- "Incidencia_ acumulada_ult14d"
names(dfgva)[7] <- "Defuncions"
names(dfgva)[8] <- "Tasa_defuncion"

dfgva <- dfgva %>% mutate(CodMunicipio = as.numeric(CodMunicipio))
municipios_2017 <- municipios_2017 %>% mutate(INECodMuni = as.numeric(INECodMuni))
dfpueblos <- inner_join(dfgva, municipios_2017, by = c("CodMunicipio" = "INECodMuni" ))
dfpueblos_def <- inner_join(dfpueblos, dfpoblacion_gva, by = c("CodMunicipio" = "Codi_Municipi" ))
dfmunicipios <- dfpueblos_def %>% select(`CodMunicipio`,`NombreMuni`, `Poblacions`,`Casos`,`Incidencia_acumulada`,`Defuncions`, `Casos_ult14d`, `Incidencia_ acumulada_ult14d`, `Tasa_defuncion`, `INECodProv`, `INECodCCAA`, `NombreMuni`, `NombreProv`, `geometry` )
rm(dfgva,dfpoblacion_gva,dfpueblos,dfpueblos_def, municipios_2017, IGN_nomencla_muni, rios, world)

dfmunicipios150_250 <- dfmunicipios %>% filter(`Incidencia_ acumulada_ult14d` %in% (150:250))%>% arrange(desc(`Poblacions`)) %>% slice(1:5) %>% arrange(desc(`Incidencia_ acumulada_ult14d`)) 
dfmunicipios_150_250_tabla <- dfmunicipios150_250 %>% select(`NombreMuni`,`Poblacions`, `Incidencia_ acumulada_ult14d`) %>% arrange(desc(`Incidencia_ acumulada_ult14d`)) 

dfmunicipios_150_250_tabla %>%
  kbl() %>%
  kable_classic(full_width = F, html_font = "Cambria") %>%
  kable_styling(bootstrap_options = c("striped", "hover")) %>% row_spec(row = 0:5 ,bold = T,background = "#e35b43", font_size = 15)%>%
  scroll_box(width = "100%", height = "300px")
NombreMuni Poblacions Incidencia_ acumulada_ult14d
Sagunto/Sagunt 66140 227
Elche/Elx 232517 217
Alacant/Alicante 334887 192
Paterna 70195 181
San Vicente del Raspeig/Sant Vicent del Raspeig 58385 178
“Incidencia a 14 días entre 150 y 250”

dfgva <- rio::import("./datos/covid-19-casos-confirmados-por-pcr-casos-pcr-en-los-ultimos-14-dias-y-personas-fallecidas-por-mu.csv")
dfpoblacion_gva <- rio::import("./datos/poblacion_muni_vlc.xls")
load("./datos/geometrias_clase_10.RData")

nombres_originales <- names(dfgva)
nombres_originales
#> [1] "CodMunicipio"                 "Municipi"                    
#> [3] "Casos PCR+"                   "Incidència acumulada PCR+"  
#> [5] "Casos PCR+ 14 dies"           "Incidència acumulada PCR+14"
#> [7] "Defuncions"                   "Taxa de defunció"
names(dfgva)[1] <- "CodMunicipio"
names(dfgva)[2] <- "Municipi"
names(dfgva)[3] <- "Casos"
names(dfgva)[4] <- "Incidencia_acumulada"
names(dfgva)[5] <- "Casos_ult14d"
names(dfgva)[6] <- "Incidencia_ acumulada_ult14d"
names(dfgva)[7] <- "Defuncions"
names(dfgva)[8] <- "Tasa_defuncion"

dfgva <- dfgva %>% mutate(CodMunicipio = as.numeric(CodMunicipio))
municipios_2017 <- municipios_2017 %>% mutate(INECodMuni = as.numeric(INECodMuni))
dfpueblos <- inner_join(dfgva, municipios_2017, by = c("CodMunicipio" = "INECodMuni" ))
dfpueblos_def <- inner_join(dfpueblos, dfpoblacion_gva, by = c("CodMunicipio" = "Codi_Municipi" ))
dfmunicipios <- dfpueblos_def %>% select(`CodMunicipio`,`NombreMuni`, `Poblacions`,`Casos`,`Incidencia_acumulada`,`Defuncions`, `Casos_ult14d`, `Incidencia_ acumulada_ult14d`, `Tasa_defuncion`, `INECodProv`, `INECodCCAA`, `NombreMuni`, `NombreProv`, `geometry` )
rm(dfgva,dfpoblacion_gva,dfpueblos,dfpueblos_def, municipios_2017, IGN_nomencla_muni, rios, world)

dfmunicipios250 <- dfmunicipios %>% filter(`Incidencia_ acumulada_ult14d` >= 250)%>% arrange(desc(`Poblacions`)) %>% slice(1:5) %>%  arrange(desc(`Incidencia_ acumulada_ult14d`)) 
dfmunicipios_250_tabla <- dfmunicipios250 %>% select(`NombreMuni`,`Poblacions`, `Incidencia_ acumulada_ult14d`) %>% arrange(desc(`Incidencia_ acumulada_ult14d`)) 

dfmunicipios_250_tabla %>%
  kbl() %>%
  kable_classic(full_width = F, html_font = "Cambria") %>%
  kable_styling(bootstrap_options = c("striped", "hover")) %>% row_spec(row = 0:5 ,bold = T,background = "#a3042b", font_size = 15)%>%
  scroll_box(width = "100%", height = "300px")
NombreMuni Poblacions Incidencia_ acumulada_ult14d
Elda 52618 430
Gandia 74562 384
Alcoy/Alcoi 58994 312
Torrent 82208 264
Valencia 794288 252
“Incidencia a 14 días mayor de 250”

5.2.1. Comparación Ciudades & Pueblos.

En este gráfico hemos querido hacer constar la diferencia que existe entre pueblos (menos de 10.000 habitantes) y ciudades (más de 10.000 habitantes) respecto a la variable analizada.


dfgva <- rio::import("./datos/covid-19-casos-confirmados-por-pcr-casos-pcr-en-los-ultimos-14-dias-y-personas-fallecidas-por-mu.csv")
dfpoblacion_gva <- rio::import("./datos/poblacion_muni_vlc.xls")
load("./datos/geometrias_clase_10.RData")

nombres_originales <- names(dfgva)
nombres_originales
#> [1] "CodMunicipio"                 "Municipi"                    
#> [3] "Casos PCR+"                   "Incidència acumulada PCR+"  
#> [5] "Casos PCR+ 14 dies"           "Incidència acumulada PCR+14"
#> [7] "Defuncions"                   "Taxa de defunció"
names(dfgva)[1] <- "CodMunicipio"
names(dfgva)[2] <- "Municipi"
names(dfgva)[3] <- "Casos"
names(dfgva)[4] <- "Incidencia_acumulada"
names(dfgva)[5] <- "Casos_ult14d"
names(dfgva)[6] <- "Incidencia_ acumulada_ult14d"
names(dfgva)[7] <- "Defuncions"
names(dfgva)[8] <- "Tasa_defuncion"

dfgva <- dfgva %>% mutate(CodMunicipio = as.numeric(CodMunicipio))
municipios_2017 <- municipios_2017 %>% mutate(INECodMuni = as.numeric(INECodMuni))
dfpueblos <- inner_join(dfgva, municipios_2017, by = c("CodMunicipio" = "INECodMuni" ))
dfpueblos_def <- inner_join(dfpueblos, dfpoblacion_gva, by = c("CodMunicipio" = "Codi_Municipi" ))
dfmunicipios <- dfpueblos_def %>% select(`CodMunicipio`,`NombreMuni`, `Poblacions`,`Casos`,`Incidencia_acumulada`,`Defuncions`, `Casos_ult14d`, `Incidencia_ acumulada_ult14d`, `Tasa_defuncion`, `INECodProv`, `INECodCCAA`, `NombreMuni`, `NombreProv`, `geometry` )
rm(dfgva,dfpoblacion_gva,dfpueblos,dfpueblos_def, municipios_2017, IGN_nomencla_muni, rios, world)

dfmunicipios250 <- dfmunicipios %>% filter(`Incidencia_ acumulada_ult14d` >= 250)%>% arrange(desc(`Poblacions`)) %>% slice(1:5) %>%  arrange(desc(`Incidencia_ acumulada_ult14d`)) 
dfmunicipios_250_tabla <- dfmunicipios250 %>% select(`NombreMuni`,`Poblacions`, `Incidencia_ acumulada_ult14d`) %>% arrange(desc(`Incidencia_ acumulada_ult14d`))

dfciudades <- dfmunicipios %>% filter(`Poblacions` >= 10000)
dfpueblos <- dfmunicipios %>% filter(`Poblacions` <= 10000)

dfciudades_25 <- dfciudades %>% filter(`Incidencia_ acumulada_ult14d` <= 25)%>% arrange(desc(`Incidencia_ acumulada_ult14d`)) # No hay ninguna ciudad
dfciudades25_50 <- dfciudades %>% filter (`Incidencia_ acumulada_ult14d` %in% (25:50))%>% arrange(desc(`Incidencia_ acumulada_ult14d`))
dfciudades50_150 <- dfciudades %>% filter (`Incidencia_ acumulada_ult14d` %in% (50:150))%>% arrange(desc(`Incidencia_ acumulada_ult14d`))
dfciudades150_250 <- dfciudades %>% filter (`Incidencia_ acumulada_ult14d` %in% (150:250)) %>% arrange(desc(`Incidencia_ acumulada_ult14d`))
dfciudades_250 <- dfciudades %>% filter(`Incidencia_ acumulada_ult14d` >= 250)%>% arrange(desc(`Incidencia_ acumulada_ult14d`))

dfpueblos_25 <- dfpueblos %>% filter(`Incidencia_ acumulada_ult14d` <= 25) %>% arrange(desc(`Incidencia_ acumulada_ult14d`))
dfpueblos25_50 <- dfpueblos %>% filter (`Incidencia_ acumulada_ult14d` %in% (25:50)) %>% arrange(desc(`Incidencia_ acumulada_ult14d`))
dfpueblos50_150 <- dfpueblos %>% filter (`Incidencia_ acumulada_ult14d` %in% (50:150)) %>% arrange(desc(`Incidencia_ acumulada_ult14d`))
dfpueblos150_250 <- dfpueblos %>% filter (`Incidencia_ acumulada_ult14d` %in% (150:250)) %>% arrange(desc(`Incidencia_ acumulada_ult14d`))
dfpueblos_250 <- dfpueblos %>% filter(`Incidencia_ acumulada_ult14d` >= 250) %>% arrange(desc(`Poblacions`))

tabla_resumen <- data.frame(
  Número_Incidencias  = c("Incidencia_menos_25", "Incidencia_entre_25_50","Incidencia_entre_50_150","Incidencia_entre_150_250","Incidencia_más_250" ),  
  Pueblos = c(211, 17, 71, 54, 91), 
  Ciudades = c(0, 2, 32, 30, 37)  )

p <- ggplot (tabla_resumen, aes(Número_Incidencias, Pueblos))+
geom_col(fill= "steelblue") + coord_flip() + 
  labs (title = "Incidencia últ.14d",
                                                   y = "Grupos_Incidencia",
                                                   x = "Número_Pueblos") 


g  <- ggplot (tabla_resumen, aes(Número_Incidencias, Ciudades)) + 
  geom_col(fill= "tomato") + coord_flip()+
  labs (title = "Incidencia últ.14d",
        y = "Grupos_Incidencia",
        x = "Número_Ciudades") 

p+g

Mientras que la mayoría de los pueblos se sitúan en un riesgo bajo (menor a 25), la mayoría de las ciudades se situán en un riesgo extremo (más de 250). Además podemos observar que no hay ni una sola ciudad valenciana que no tiene un riesgo bajo (menor a 25).

5.3. Incidencia acumulada.

La incidencia acumulada nos sirve para comparar la incidencia de la Covid-19 en los municipios valencianos pero desde el inicio de la pandemia.


#buscamos los 5 municipios que tienen un tasa de incidencia acumulada mayor. Hacemos tabla.

dfgva <- rio::import("./datos/covid-19-casos-confirmados-por-pcr-casos-pcr-en-los-ultimos-14-dias-y-personas-fallecidas-por-mu.csv")
dfpoblacion_gva <- rio::import("./datos/poblacion_muni_vlc.xls")
load("./datos/geometrias_clase_10.RData")

nombres_originales <- names(dfgva)
nombres_originales
#> [1] "CodMunicipio"                 "Municipi"                    
#> [3] "Casos PCR+"                   "Incidència acumulada PCR+"  
#> [5] "Casos PCR+ 14 dies"           "Incidència acumulada PCR+14"
#> [7] "Defuncions"                   "Taxa de defunció"
names(dfgva)[1] <- "CodMunicipio"
names(dfgva)[2] <- "Municipi"
names(dfgva)[3] <- "Casos"
names(dfgva)[4] <- "Incidencia_acumulada"
names(dfgva)[5] <- "Casos_ult14d"
names(dfgva)[6] <- "Incidencia_ acumulada_ult14d"
names(dfgva)[7] <- "Defuncions"
names(dfgva)[8] <- "Tasa_defuncion"

dfgva <- dfgva %>% mutate(CodMunicipio = as.numeric(CodMunicipio))
municipios_2017 <- municipios_2017 %>% mutate(INECodMuni = as.numeric(INECodMuni))
dfpueblos <- inner_join(dfgva, municipios_2017, by = c("CodMunicipio" = "INECodMuni" ))
dfpueblos_def <- inner_join(dfpueblos, dfpoblacion_gva, by = c("CodMunicipio" = "Codi_Municipi" ))
dfmunicipios <- dfpueblos_def %>% select(`CodMunicipio`,`NombreMuni`, `Poblacions`,`Casos`,`Incidencia_acumulada`,`Defuncions`, `Casos_ult14d`, `Incidencia_ acumulada_ult14d`, `Tasa_defuncion`, `INECodProv`, `INECodCCAA`, `NombreMuni`, `NombreProv`, `geometry` )
rm(dfgva,dfpoblacion_gva,dfpueblos,dfpueblos_def, municipios_2017, IGN_nomencla_muni, rios, world)

dfmunicipios_masI <- dfmunicipios %>% slice_max(Incidencia_acumulada, n = 5) %>% arrange(desc(`Incidencia_acumulada`))

dfmunicipios_masI_tabla <- dfmunicipios_masI %>% select(`NombreMuni`,`Poblacions`, `Incidencia_acumulada`) %>% arrange(desc(`Incidencia_acumulada`))

kbl(dfmunicipios_masI_tabla) %>% 
  kable_paper("striped", full_width = F) %>%
  column_spec(1:3, bold = T) %>%
  row_spec(0, bold = T, color = "white", background = "#452AE6")%>%
  scroll_box(width = "100%", height = "300px")
NombreMuni Poblacions Incidencia_acumulada
Villahermosa del Río 489 15133
Olocau del Rey 119 14286
Forcall 465 10968
Caudete de las Fuentes 700 8143
Benirredrà 1592 6407

Estos son los 5 municipios valencianos con una incidencia acumulada mayor.


#Tabla con Bandera de Villahermosa del río.

dfgva <- rio::import("./datos/covid-19-casos-confirmados-por-pcr-casos-pcr-en-los-ultimos-14-dias-y-personas-fallecidas-por-mu.csv")
dfpoblacion_gva <- rio::import("./datos/poblacion_muni_vlc.xls")
load("./datos/geometrias_clase_10.RData")

nombres_originales <- names(dfgva)
nombres_originales
#> [1] "CodMunicipio"                 "Municipi"                    
#> [3] "Casos PCR+"                   "Incidència acumulada PCR+"  
#> [5] "Casos PCR+ 14 dies"           "Incidència acumulada PCR+14"
#> [7] "Defuncions"                   "Taxa de defunció"
names(dfgva)[1] <- "CodMunicipio"
names(dfgva)[2] <- "Municipi"
names(dfgva)[3] <- "Casos"
names(dfgva)[4] <- "Incidencia_acumulada"
names(dfgva)[5] <- "Casos_ult14d"
names(dfgva)[6] <- "Incidencia_ acumulada_ult14d"
names(dfgva)[7] <- "Defuncions"
names(dfgva)[8] <- "Tasa_defuncion"

dfgva <- dfgva %>% mutate(CodMunicipio = as.numeric(CodMunicipio))
municipios_2017 <- municipios_2017 %>% mutate(INECodMuni = as.numeric(INECodMuni))
dfpueblos <- inner_join(dfgva, municipios_2017, by = c("CodMunicipio" = "INECodMuni" ))
dfpueblos_def <- inner_join(dfpueblos, dfpoblacion_gva, by = c("CodMunicipio" = "Codi_Municipi" ))
dfmunicipios <- dfpueblos_def %>% select(`CodMunicipio`,`NombreMuni`, `Poblacions`,`Casos`,`Incidencia_acumulada`,`Defuncions`, `Casos_ult14d`, `Incidencia_ acumulada_ult14d`, `Tasa_defuncion`, `INECodProv`, `INECodCCAA`, `NombreMuni`, `NombreProv`, `geometry` )
rm(dfgva,dfpoblacion_gva,dfpueblos,dfpueblos_def, municipios_2017, IGN_nomencla_muni, rios, world)

MunicipioMayorInciAcu <- dfmunicipios %>% slice_max(Incidencia_acumulada, n=1)

ImagenVilla <- "https://www.comprarbanderas.es/images/banderas/400/7015-villahermosa-del-rio_400px.jpg"

Tabla_MunicipioMayorInciAcu <- MunicipioMayorInciAcu %>% gt()

Tabla_MunicipioMayorInciAcu <- MunicipioMayorInciAcu %>% group_by(NombreMuni) %>% slice_max(Incidencia_acumulada, n = 1) %>% add_column(ImagenVilla) %>% 
  select(NombreMuni,Poblacions,Incidencia_acumulada,ImagenVilla) %>% ungroup()

Tabla_MunicipioMayorInciAcu %>% gt() %>% 
  gt::text_transform(locations = cells_body(columns = vars(ImagenVilla)),
                     fn = function(x) {gt::web_image(x, height = 50)}) %>% tab_header(title = md("**Municipio con mayor incidencia acumulada**"),subtitle = md("**Comunidad Valenciana**")) %>%
  tab_options(heading.background.color = "orange", column_labels.font.weight = "bold")
Municipio con mayor incidencia acumulada
Comunidad Valenciana
NombreMuni Poblacions Incidencia_acumulada ImagenVilla
Villahermosa del Río 489 15133
#buscamos las 5 ciudades que tienen un tasa de incidencia acumulada menor. Hacemos tabla y los situamos en el mapa

dfmunicipios_menosI <- dfmunicipios %>% slice_min(Incidencia_acumulada, n = 5) %>% arrange(desc(`Poblacions`)) %>% slice (1:5)

dfmunicipios_menosI_tabla <- dfmunicipios_menosI %>% select(`NombreMuni`,`Poblacions`, `Incidencia_acumulada`) %>% arrange(desc(`Poblacions`))

kbl(dfmunicipios_menosI_tabla) %>% 
  kable_paper("striped", full_width = F) %>%
  column_spec(1:3, bold = T) %>%
  row_spec(0, bold = T, color = "white", background = "#452AE6")%>%
  scroll_box(width = "100%", height = "300px")
NombreMuni Poblacions Incidencia_acumulada
Vall de Gallinera 571 0
Guardamar de la Safor 526 0
Benigembla 490 0
Gaianes 452 0
Salem 424 0

Estos son los 5 municipios valencianos con una incidencia acumulada menor. Como había muchos municipios con una incidencia de 0, hemos cogido los 5 que tenía una población mayor.


#Tabla con bandera de Vall de Gallinera.

dfgva <- rio::import("./datos/covid-19-casos-confirmados-por-pcr-casos-pcr-en-los-ultimos-14-dias-y-personas-fallecidas-por-mu.csv")
dfpoblacion_gva <- rio::import("./datos/poblacion_muni_vlc.xls")
load("./datos/geometrias_clase_10.RData")

nombres_originales <- names(dfgva)
nombres_originales
#> [1] "CodMunicipio"                 "Municipi"                    
#> [3] "Casos PCR+"                   "Incidència acumulada PCR+"  
#> [5] "Casos PCR+ 14 dies"           "Incidència acumulada PCR+14"
#> [7] "Defuncions"                   "Taxa de defunció"
names(dfgva)[1] <- "CodMunicipio"
names(dfgva)[2] <- "Municipi"
names(dfgva)[3] <- "Casos"
names(dfgva)[4] <- "Incidencia_acumulada"
names(dfgva)[5] <- "Casos_ult14d"
names(dfgva)[6] <- "Incidencia_ acumulada_ult14d"
names(dfgva)[7] <- "Defuncions"
names(dfgva)[8] <- "Tasa_defuncion"

dfgva <- dfgva %>% mutate(CodMunicipio = as.numeric(CodMunicipio))
municipios_2017 <- municipios_2017 %>% mutate(INECodMuni = as.numeric(INECodMuni))
dfpueblos <- inner_join(dfgva, municipios_2017, by = c("CodMunicipio" = "INECodMuni" ))
dfpueblos_def <- inner_join(dfpueblos, dfpoblacion_gva, by = c("CodMunicipio" = "Codi_Municipi" ))
dfmunicipios <- dfpueblos_def %>% select(`CodMunicipio`,`NombreMuni`, `Poblacions`,`Casos`,`Incidencia_acumulada`,`Defuncions`, `Casos_ult14d`, `Incidencia_ acumulada_ult14d`, `Tasa_defuncion`, `INECodProv`, `INECodCCAA`, `NombreMuni`, `NombreProv`, `geometry` )
rm(dfgva,dfpoblacion_gva,dfpueblos,dfpueblos_def, municipios_2017, IGN_nomencla_muni, rios, world)

MunicipioMenorInciAcu <- dfmunicipios %>% slice_min(Incidencia_acumulada, n=1)%>% arrange(desc(`Poblacions`))%>% slice(1:1)

ImagenVall <- "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Escut_de_la_Vall_de_Gallinera.svg/85px-Escut_de_la_Vall_de_Gallinera.svg.png"

Tabla_MunicipioMenorInciAcu <- MunicipioMenorInciAcu %>% gt()

Tabla_MunicipioMenorInciAcu <- MunicipioMenorInciAcu %>% group_by(NombreMuni) %>% slice_max(Incidencia_acumulada, n = 1) %>% add_column(ImagenVall) %>% 
  select(NombreMuni,Poblacions,Incidencia_acumulada,ImagenVall) %>% ungroup()

Tabla_MunicipioMenorInciAcu %>% gt() %>% 
  gt::text_transform(locations = cells_body(columns = vars(ImagenVall)),
                     fn = function(x) {gt::web_image(x, height = 50)}) %>% tab_header(title = md("**Mucicipio con menor incidencia acumulada**"),subtitle = md("**Comunidad Valenciana**")) %>%
  tab_options(heading.background.color = "tomato", column_labels.font.weight = "bold")
Mucicipio con menor incidencia acumulada
Comunidad Valenciana
NombreMuni Poblacions Incidencia_acumulada ImagenVall
Vall de Gallinera 571 0

mapaCiudadyPueblomayorinciAcu <- leaflet() %>%
  setView(lng = -0.243591, lat = 38.821, zoom = 7) %>% 
  addMarkers(lng = -0.243591, lat = 38.821 , popup = "Vall de Gallinera")%>%
  setView(lng = -0.418598, lat = 40.2011, zoom = 7) %>% 
  addMarkers(lng = -0.418598, lat = 40.2011 , popup = "Villahermosa del rio") %>% addTiles()
mapaCiudadyPueblomayorinciAcu

Situamos en un mapa a los dos municipios con mayor y menor índice de incidencia acumulada.

5.4. Tasa de defunciones .

En este subapartado hemos querido buscar los cinco municipios valencianos con mayor y menor tasa de defunciones en la Comunidad Valenciana.


# buscamos los 5 municipios que tienen un tasa de mortalidad mayor. Hacemos tabla y los situamos en el mapa

dfgva <- rio::import("./datos/covid-19-casos-confirmados-por-pcr-casos-pcr-en-los-ultimos-14-dias-y-personas-fallecidas-por-mu.csv")
dfpoblacion_gva <- rio::import("./datos/poblacion_muni_vlc.xls")
load("./datos/geometrias_clase_10.RData")

nombres_originales <- names(dfgva)
nombres_originales
#> [1] "CodMunicipio"                 "Municipi"                    
#> [3] "Casos PCR+"                   "Incidència acumulada PCR+"  
#> [5] "Casos PCR+ 14 dies"           "Incidència acumulada PCR+14"
#> [7] "Defuncions"                   "Taxa de defunció"
names(dfgva)[1] <- "CodMunicipio"
names(dfgva)[2] <- "Municipi"
names(dfgva)[3] <- "Casos"
names(dfgva)[4] <- "Incidencia_acumulada"
names(dfgva)[5] <- "Casos_ult14d"
names(dfgva)[6] <- "Incidencia_ acumulada_ult14d"
names(dfgva)[7] <- "Defuncions"
names(dfgva)[8] <- "Tasa_defuncion"

dfgva <- dfgva %>% mutate(CodMunicipio = as.numeric(CodMunicipio))
municipios_2017 <- municipios_2017 %>% mutate(INECodMuni = as.numeric(INECodMuni))
dfpueblos <- inner_join(dfgva, municipios_2017, by = c("CodMunicipio" = "INECodMuni" ))
dfpueblos_def <- inner_join(dfpueblos, dfpoblacion_gva, by = c("CodMunicipio" = "Codi_Municipi" ))
dfmunicipios <- dfpueblos_def %>% select(`CodMunicipio`,`NombreMuni`, `Poblacions`,`Casos`,`Incidencia_acumulada`,`Defuncions`, `Casos_ult14d`, `Incidencia_ acumulada_ult14d`, `Tasa_defuncion`, `INECodProv`, `INECodCCAA`, `NombreMuni`, `NombreProv`, `geometry` )
rm(dfgva,dfpoblacion_gva,dfpueblos,dfpueblos_def, municipios_2017, IGN_nomencla_muni, rios, world)

dfmunicipios_masM <- dfmunicipios %>% slice_max(Tasa_defuncion, n = 5) %>% arrange(desc(`Tasa_defuncion`))

dfmunicipios_masM_tabla <- dfmunicipios_masM %>% select(`NombreMuni`,`Poblacions`, `Tasa_defuncion`)%>% arrange(desc(`Tasa_defuncion`))

dfmunicipios_masM_tabla %>%
  kbl() %>%
  kable_material_dark()
NombreMuni Poblacions Tasa_defuncion
Villahermosa del Río 489 3067
Montán 370 1351
Jalance 830 964
Morella 2430 905
Alborache 1160 776

# Bandera del municipio con una mayor tasa de defunción

dfgva <- rio::import("./datos/covid-19-casos-confirmados-por-pcr-casos-pcr-en-los-ultimos-14-dias-y-personas-fallecidas-por-mu.csv")
dfpoblacion_gva <- rio::import("./datos/poblacion_muni_vlc.xls")
load("./datos/geometrias_clase_10.RData")

nombres_originales <- names(dfgva)
nombres_originales
#> [1] "CodMunicipio"                 "Municipi"                    
#> [3] "Casos PCR+"                   "Incidència acumulada PCR+"  
#> [5] "Casos PCR+ 14 dies"           "Incidència acumulada PCR+14"
#> [7] "Defuncions"                   "Taxa de defunció"
names(dfgva)[1] <- "CodMunicipio"
names(dfgva)[2] <- "Municipi"
names(dfgva)[3] <- "Casos"
names(dfgva)[4] <- "Incidencia_acumulada"
names(dfgva)[5] <- "Casos_ult14d"
names(dfgva)[6] <- "Incidencia_ acumulada_ult14d"
names(dfgva)[7] <- "Defuncions"
names(dfgva)[8] <- "Tasa_defuncion"

dfgva <- dfgva %>% mutate(CodMunicipio = as.numeric(CodMunicipio))
municipios_2017 <- municipios_2017 %>% mutate(INECodMuni = as.numeric(INECodMuni))
dfpueblos <- inner_join(dfgva, municipios_2017, by = c("CodMunicipio" = "INECodMuni" ))
dfpueblos_def <- inner_join(dfpueblos, dfpoblacion_gva, by = c("CodMunicipio" = "Codi_Municipi" ))
dfmunicipios <- dfpueblos_def %>% select(`CodMunicipio`,`NombreMuni`, `Poblacions`,`Casos`,`Incidencia_acumulada`,`Defuncions`, `Casos_ult14d`, `Incidencia_ acumulada_ult14d`, `Tasa_defuncion`, `INECodProv`, `INECodCCAA`, `NombreMuni`, `NombreProv`, `geometry` )
rm(dfgva,dfpoblacion_gva,dfpueblos,dfpueblos_def, municipios_2017, IGN_nomencla_muni, rios, world)

municipioMayortasaM <- dfmunicipios %>% slice_max(Tasa_defuncion, n=1)

ImagenVilla <- "https://www.comprarbanderas.es/images/banderas/400/7015-villahermosa-del-rio_400px.jpg"

Tabla_municipioMayortasaM <- municipioMayortasaM %>% gt()

Tabla_municipioMayortasaM <- municipioMayortasaM %>% group_by(NombreMuni) %>% slice_max(Tasa_defuncion, n = 1) %>% add_column(ImagenVilla) %>% 
  select(NombreMuni,Poblacions, Tasa_defuncion,ImagenVilla) %>% ungroup()

Tabla_municipioMayortasaM%>% gt() %>% 
  gt::text_transform(locations = cells_body(columns = vars(ImagenVilla)),
                     fn = function(x) {gt::web_image(x, height = 50)}) %>% tab_header(title = md("**Municipio con mayor tasa de mortalidad**"),subtitle = md("**Comunidad Valenciana**")) %>%
  tab_options(heading.background.color = "black", column_labels.font.weight = "bold")
Municipio con mayor tasa de mortalidad
Comunidad Valenciana
NombreMuni Poblacions Tasa_defuncion ImagenVilla
Villahermosa del Río 489 3067

# buscamos las 5 municipios que tienen un tasa de mortalidad menor. Hacemos tabla y los situamos en el mapa
# Aquí hay muchos pueblos con una tasa del 0. Hemos cogido 5 y ordenamos por población.


dfgva <- rio::import("./datos/covid-19-casos-confirmados-por-pcr-casos-pcr-en-los-ultimos-14-dias-y-personas-fallecidas-por-mu.csv")
dfpoblacion_gva <- rio::import("./datos/poblacion_muni_vlc.xls")
load("./datos/geometrias_clase_10.RData")

nombres_originales <- names(dfgva)
nombres_originales
#> [1] "CodMunicipio"                 "Municipi"                    
#> [3] "Casos PCR+"                   "Incidència acumulada PCR+"  
#> [5] "Casos PCR+ 14 dies"           "Incidència acumulada PCR+14"
#> [7] "Defuncions"                   "Taxa de defunció"
names(dfgva)[1] <- "CodMunicipio"
names(dfgva)[2] <- "Municipi"
names(dfgva)[3] <- "Casos"
names(dfgva)[4] <- "Incidencia_acumulada"
names(dfgva)[5] <- "Casos_ult14d"
names(dfgva)[6] <- "Incidencia_ acumulada_ult14d"
names(dfgva)[7] <- "Defuncions"
names(dfgva)[8] <- "Tasa_defuncion"

dfgva <- dfgva %>% mutate(CodMunicipio = as.numeric(CodMunicipio))
municipios_2017 <- municipios_2017 %>% mutate(INECodMuni = as.numeric(INECodMuni))
dfpueblos <- inner_join(dfgva, municipios_2017, by = c("CodMunicipio" = "INECodMuni" ))
dfpueblos_def <- inner_join(dfpueblos, dfpoblacion_gva, by = c("CodMunicipio" = "Codi_Municipi" ))
dfmunicipios <- dfpueblos_def %>% select(`CodMunicipio`,`NombreMuni`, `Poblacions`,`Casos`,`Incidencia_acumulada`,`Defuncions`, `Casos_ult14d`, `Incidencia_ acumulada_ult14d`, `Tasa_defuncion`, `INECodProv`, `INECodCCAA`, `NombreMuni`, `NombreProv`, `geometry` )
rm(dfgva,dfpoblacion_gva,dfpueblos,dfpueblos_def, municipios_2017, IGN_nomencla_muni, rios, world)

dfmunicipios_menosM <- dfmunicipios %>% slice_min(Tasa_defuncion, n = 5) %>% arrange(desc(`Poblacions`)) %>% slice(1:5) 

dfmunicipios_menosM_tabla <- dfmunicipios_menosM %>% select(`NombreMuni`,`Poblacions`, `Tasa_defuncion`)%>% arrange(desc(`Tasa_defuncion`))

dfmunicipios_menosM_tabla %>%
  kbl() %>%
  kable_material_dark()
NombreMuni Poblacions Tasa_defuncion
Benaguasil 10988 0
Pego 10128 0
Rocafort 7240 0
Turís 6646 0
Náquera 6577 0

# Hemos puesto la bandera del municipio con la tasa de mortalidad más baja y que además tenía la poblacion mayor

dfgva <- rio::import("./datos/covid-19-casos-confirmados-por-pcr-casos-pcr-en-los-ultimos-14-dias-y-personas-fallecidas-por-mu.csv")
dfpoblacion_gva <- rio::import("./datos/poblacion_muni_vlc.xls")
load("./datos/geometrias_clase_10.RData")

nombres_originales <- names(dfgva)
nombres_originales
#> [1] "CodMunicipio"                 "Municipi"                    
#> [3] "Casos PCR+"                   "Incidència acumulada PCR+"  
#> [5] "Casos PCR+ 14 dies"           "Incidència acumulada PCR+14"
#> [7] "Defuncions"                   "Taxa de defunció"
names(dfgva)[1] <- "CodMunicipio"
names(dfgva)[2] <- "Municipi"
names(dfgva)[3] <- "Casos"
names(dfgva)[4] <- "Incidencia_acumulada"
names(dfgva)[5] <- "Casos_ult14d"
names(dfgva)[6] <- "Incidencia_ acumulada_ult14d"
names(dfgva)[7] <- "Defuncions"
names(dfgva)[8] <- "Tasa_defuncion"

dfgva <- dfgva %>% mutate(CodMunicipio = as.numeric(CodMunicipio))
municipios_2017 <- municipios_2017 %>% mutate(INECodMuni = as.numeric(INECodMuni))
dfpueblos <- inner_join(dfgva, municipios_2017, by = c("CodMunicipio" = "INECodMuni" ))
dfpueblos_def <- inner_join(dfpueblos, dfpoblacion_gva, by = c("CodMunicipio" = "Codi_Municipi" ))
dfmunicipios <- dfpueblos_def %>% select(`CodMunicipio`,`NombreMuni`, `Poblacions`,`Casos`,`Incidencia_acumulada`,`Defuncions`, `Casos_ult14d`, `Incidencia_ acumulada_ult14d`, `Tasa_defuncion`, `INECodProv`, `INECodCCAA`, `NombreMuni`, `NombreProv`, `geometry` )
rm(dfgva,dfpoblacion_gva,dfpueblos,dfpueblos_def, municipios_2017, IGN_nomencla_muni, rios, world)


municipioMenortasaM <- dfmunicipios %>% slice_min(Tasa_defuncion, n = 20) %>% arrange(desc(`Poblacions`)) %>% slice(1:1) 

ImagenBeguasil <- "https://upload.wikimedia.org/wikipedia/commons/thumb/a/ab/Escut_de_Benaguasil.svg/101px-Escut_de_Benaguasil.svg.png"

Tabla_municipioMenortasaM <- municipioMenortasaM %>% gt()

Tabla_municipioMenortasaM <- municipioMenortasaM %>% group_by(NombreMuni) %>% slice_max(Tasa_defuncion, n = 1) %>% add_column(ImagenBeguasil) %>% 
  select(NombreMuni,Poblacions,Tasa_defuncion,ImagenBeguasil) %>% ungroup()

Tabla_municipioMenortasaM%>% gt() %>% 
  gt::text_transform(locations = cells_body(columns = vars(ImagenBeguasil)),
                     fn = function(x) {gt::web_image(x, height = 50)}) %>% tab_header(title = md("**Municipio con menor tasa de mortalidad**"),subtitle = md("**Comunidad Valenciana**")) %>%
  tab_options(heading.background.color = "black", column_labels.font.weight = "bold")
Municipio con menor tasa de mortalidad
Comunidad Valenciana
NombreMuni Poblacions Tasa_defuncion ImagenBeguasil
Benaguasil 10988 0

Hemos puesto la bandera del municipio con la tasa de mortalidad más baja y que además tenía la poblacion mayor porque tiene más mérito ya que a mayor población todos los virus son más difíciles de controlar.


mapaCiudadyPueblomenortasaM <- leaflet() %>%
  setView(lng = -0.589056, lat = 39.5915, zoom = 7) %>% 
  addMarkers(lng = -0.589056, lat = 39.5915 , popup = "Benaguasil")%>%
  setView(lng = -0.418598, lat = 40.2011, zoom = 7) %>% 
  addMarkers(lng = -0.418598, lat = 40.2011 , popup = "Villahermosa del rio") %>% addTiles()
mapaCiudadyPueblomenortasaM

Situamos en un mapa a los dos municipios con mayor y menor tasa de defunciones.

5.5. Defunciones .

Hemos querido mostrar los 10 municipios con más fallecidos y mostrar cuantos han tenido. A menudo cuando vemos tasas de mortalidad u otros índices no somos conscientes de la crudeza de las cifras absolutas:


#buscamos los 10 municipios que han tenido mayor número de fallecidos para que se vean las muertes en números absolutos. Hacemos tabla.

dfgva <- rio::import("./datos/covid-19-casos-confirmados-por-pcr-casos-pcr-en-los-ultimos-14-dias-y-personas-fallecidas-por-mu.csv")
dfpoblacion_gva <- rio::import("./datos/poblacion_muni_vlc.xls")
load("./datos/geometrias_clase_10.RData")

nombres_originales <- names(dfgva)
nombres_originales
#> [1] "CodMunicipio"                 "Municipi"                    
#> [3] "Casos PCR+"                   "Incidència acumulada PCR+"  
#> [5] "Casos PCR+ 14 dies"           "Incidència acumulada PCR+14"
#> [7] "Defuncions"                   "Taxa de defunció"
names(dfgva)[1] <- "CodMunicipio"
names(dfgva)[2] <- "Municipi"
names(dfgva)[3] <- "Casos"
names(dfgva)[4] <- "Incidencia_acumulada"
names(dfgva)[5] <- "Casos_ult14d"
names(dfgva)[6] <- "Incidencia_ acumulada_ult14d"
names(dfgva)[7] <- "Defuncions"
names(dfgva)[8] <- "Tasa_defuncion"

dfgva <- dfgva %>% mutate(CodMunicipio = as.numeric(CodMunicipio))
municipios_2017 <- municipios_2017 %>% mutate(INECodMuni = as.numeric(INECodMuni))
dfpueblos <- inner_join(dfgva, municipios_2017, by = c("CodMunicipio" = "INECodMuni" ))
dfpueblos_def <- inner_join(dfpueblos, dfpoblacion_gva, by = c("CodMunicipio" = "Codi_Municipi" ))
dfmunicipios <- dfpueblos_def %>% select(`CodMunicipio`,`NombreMuni`, `Poblacions`,`Casos`,`Incidencia_acumulada`,`Defuncions`, `Casos_ult14d`, `Incidencia_ acumulada_ult14d`, `Tasa_defuncion`, `INECodProv`, `INECodCCAA`, `NombreMuni`, `NombreProv`, `geometry` )
rm(dfgva,dfpoblacion_gva,dfpueblos,dfpueblos_def, municipios_2017, IGN_nomencla_muni, rios, world)

dfmunicipios_masF <- dfmunicipios %>% slice_max(Defuncions, n = 10) %>% arrange(desc(`Defuncions`))

dfmunicipios_masF_tabla <- dfmunicipios_masF  %>% select(`NombreMuni`,`Poblacions`, `Defuncions`) %>% arrange(desc(`Defuncions`))

dfmunicipios_masF_tabla %>%
  kbl(caption = "Pueblos con más fallecidos") %>%
  kable_minimal(full_width = F) %>% kable_styling(bootstrap_options = c("striped", "hover")) %>% row_spec(row = 0 ,background = "#DAF7A6 ", font_size = 15)
Pueblos con más fallecidos
NombreMuni Poblacions Defuncions
Valencia 794288 449
Alacant/Alicante 334887 119
Alcoy/Alcoi 58994 93
Castellón de la Plana/Castelló de la Plana 171728 82
Torrent 82208 78
Benidorm 68721 75
Elda 52618 58
Torrevieja 83337 52
Vila-real 50893 52
Elche/Elx 232517 41
#escudo ciudad más muertes

dfgva <- rio::import("./datos/covid-19-casos-confirmados-por-pcr-casos-pcr-en-los-ultimos-14-dias-y-personas-fallecidas-por-mu.csv")
dfpoblacion_gva <- rio::import("./datos/poblacion_muni_vlc.xls")
load("./datos/geometrias_clase_10.RData")

nombres_originales <- names(dfgva)
nombres_originales
#> [1] "CodMunicipio"                 "Municipi"                    
#> [3] "Casos PCR+"                   "Incidència acumulada PCR+"  
#> [5] "Casos PCR+ 14 dies"           "Incidència acumulada PCR+14"
#> [7] "Defuncions"                   "Taxa de defunció"
names(dfgva)[1] <- "CodMunicipio"
names(dfgva)[2] <- "Municipi"
names(dfgva)[3] <- "Casos"
names(dfgva)[4] <- "Incidencia_acumulada"
names(dfgva)[5] <- "Casos_ult14d"
names(dfgva)[6] <- "Incidencia_ acumulada_ult14d"
names(dfgva)[7] <- "Defuncions"
names(dfgva)[8] <- "Tasa_defuncion"

dfgva <- dfgva %>% mutate(CodMunicipio = as.numeric(CodMunicipio))
municipios_2017 <- municipios_2017 %>% mutate(INECodMuni = as.numeric(INECodMuni))
dfpueblos <- inner_join(dfgva, municipios_2017, by = c("CodMunicipio" = "INECodMuni" ))
dfpueblos_def <- inner_join(dfpueblos, dfpoblacion_gva, by = c("CodMunicipio" = "Codi_Municipi" ))
dfmunicipios <- dfpueblos_def %>% select(`CodMunicipio`,`NombreMuni`, `Poblacions`,`Casos`,`Incidencia_acumulada`,`Defuncions`, `Casos_ult14d`, `Incidencia_ acumulada_ult14d`, `Tasa_defuncion`, `INECodProv`, `INECodCCAA`, `NombreMuni`, `NombreProv`, `geometry` )
rm(dfgva,dfpoblacion_gva,dfpueblos,dfpueblos_def, municipios_2017, IGN_nomencla_muni, rios, world)

MunicipioMasMuertes <- dfmunicipios %>% slice_max(Defuncions, n=1)

ImagenValencia <- "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4e/Escut_de_Val%C3%A8ncia.svg/108px-Escut_de_Val%C3%A8ncia.svg.png"

Tabla_MunicipiomasMuertes <- MunicipioMasMuertes %>% gt()

Tabla_MunicipiomasMuertes <- MunicipioMasMuertes %>% group_by(NombreMuni) %>% slice_max(Defuncions, n = 1) %>% add_column(ImagenValencia) %>% 
  select(NombreMuni,Poblacions,Defuncions,ImagenValencia) %>% ungroup()

Tabla_MunicipiomasMuertes %>% gt() %>% 
  gt::text_transform(locations = cells_body(columns = vars(ImagenValencia)),
                     fn = function(x) {gt::web_image(x, height = 50)}) %>% tab_header(title = md("Municipio con más defunciones"),subtitle = md("Comunidad Valenciana")) %>%
  tab_options(heading.background.color = "black", column_labels.font.weight = "bold")
Municipio con más defunciones
Comunidad Valenciana
NombreMuni Poblacions Defuncions ImagenValencia
Valencia 794288 449

mapaCiudadMasMuertes <- leaflet() %>%
  setView(lng = -0.37739, lat = 39.46975, zoom = 11) %>% 
  addMarkers(lng = -0.37739, lat = 39.46975 , popup = "Valencia") %>% addTiles()
mapaCiudadMasMuertes

6. Consejo.

El amanecer llega después de la oscuridad — Lisa Wingate.

“Salvemos la Navidad de 2021”

7. Bibliografía.

Página web de la GVA

Página web del INE

Tutoriales de profesar de Universidad de Valencia, D.Pedro J. Pérez

Página web del Hospital Clínic de Barcelonahttps://www.clinicbarcelona.org/

Vídeo explicativo de Rafa González Gouveia sobre como animar las gráficas

Averiguar como se calcula la tasa de fallecimientos

Averiguar como se calcula la tasa de incidencia

Datos del dataframe y geometrias dados en clase por D.Pedro J. Pérez.

Ayuda “logística” del foro creado en piazza para ayudarnos entre los compañeros, para situar los municipios en los mapas (¡Gracias Noelia!).

Nos ha inspirado el trabajo “ANÁLISIS SOBRE LA COVID-19” de nuestros compañeros de clase: Andreu Esparza i Martinez, Ignacio Montava Peralta y Noelia Sánchez March

current session info


- Session info ---------------------------------------------------------------
 setting  value                       
 version  R version 4.0.2 (2020-06-22)
 os       Windows 10 x64              
 system   x86_64, mingw32             
 ui       RTerm                       
 language (EN)                        
 collate  Spanish_Spain.1252          
 ctype    Spanish_Spain.1252          
 tz       Europe/Paris                
 date     2020-12-17                  

- Packages -------------------------------------------------------------------
 package           * version    date       lib
 assertthat          0.2.1      2019-03-21 [1]
 backports           1.1.9      2020-08-24 [1]
 base64enc           0.1-3      2015-07-28 [1]
 blob                1.2.1      2020-01-20 [1]
 broom               0.7.0      2020-07-09 [1]
 cellranger          1.1.0      2016-07-27 [1]
 checkmate           2.0.0      2020-02-06 [1]
 class               7.3-17     2020-04-26 [2]
 classInt            0.4-3      2020-04-07 [1]
 cli                 2.2.0      2020-11-20 [1]
 clipr               0.7.1      2020-10-08 [1]
 codetools           0.2-16     2018-12-24 [2]
 colorspace          1.4-1      2019-03-18 [1]
 commonmark          1.7        2018-12-01 [1]
 crayon              1.3.4      2017-09-16 [1]
 crosstalk           1.1.0.1    2020-03-13 [1]
 curl                4.3        2019-12-02 [1]
 data.table          1.13.0     2020-07-24 [1]
 DBI                 1.1.0      2019-12-15 [1]
 dbplyr              1.4.4      2020-05-27 [1]
 desc                1.2.0      2018-05-01 [1]
 details             0.2.1      2020-01-12 [1]
 digest              0.6.27     2020-10-24 [1]
 dplyr             * 1.0.2      2020-08-18 [1]
 DT                * 0.15       2020-08-05 [1]
 e1071               1.7-3      2019-11-26 [1]
 ellipsis            0.3.1      2020-05-15 [1]
 evaluate            0.14       2019-05-28 [1]
 fansi               0.4.1      2020-01-08 [1]
 farver              2.0.3      2020-01-16 [1]
 forcats           * 0.5.0      2020-03-01 [1]
 foreign             0.8-80     2020-05-24 [2]
 fs                  1.5.0      2020-07-31 [1]
 generics            0.1.0      2020-10-31 [1]
 gganimate         * 1.0.7      2020-10-15 [1]
 ggplot2           * 3.3.2      2020-06-19 [1]
 ggrepel           * 0.8.2      2020-03-08 [1]
 ggspatial         * 1.1.4      2020-07-12 [1]
 ggthemes          * 4.2.0      2019-05-13 [1]
 gifski            * 0.8.6      2018-09-28 [1]
 glue                1.4.2      2020-08-27 [1]
 gt                * 0.2.2      2020-08-05 [1]
 gtable              0.3.0      2019-03-25 [1]
 haven               2.3.1      2020-06-01 [1]
 here                0.1        2017-05-28 [1]
 highr               0.8        2019-03-20 [1]
 hms                 0.5.3      2020-01-08 [1]
 htmltools           0.5.0      2020-06-16 [1]
 htmlwidgets         1.5.1      2019-10-08 [1]
 httr                1.4.2      2020-07-20 [1]
 janitor             2.0.1      2020-04-12 [1]
 jsonlite            1.7.1      2020-09-07 [1]
 kableExtra        * 1.3.1      2020-10-22 [1]
 KernSmooth          2.23-17    2020-04-26 [2]
 klippy            * 0.0.0.9500 2020-11-20 [1]
 knitr             * 1.29       2020-06-23 [1]
 labeling            0.3        2014-08-23 [1]
 lattice             0.20-41    2020-04-02 [2]
 lazyeval            0.2.2      2019-03-15 [1]
 leafem            * 0.1.3      2020-07-26 [1]
 leaflet           * 2.0.3      2019-11-16 [1]
 lifecycle           0.2.0      2020-03-06 [1]
 lubridate           1.7.9.2    2020-11-13 [1]
 magrittr            2.0.1      2020-11-17 [1]
 modelr              0.1.8      2020-05-19 [1]
 munsell             0.5.0      2018-06-12 [1]
 openxlsx            4.2.2      2020-09-17 [1]
 patchwork         * 1.1.0      2020-11-09 [1]
 pillar              1.4.7      2020-11-20 [1]
 pjpv2020.01       * 0.0.0.9000 2020-11-20 [1]
 pkgconfig           2.0.3      2019-09-22 [1]
 plotly            * 4.9.2.1    2020-04-04 [1]
 plyr                1.8.6      2020-03-03 [1]
 png                 0.1-7      2013-12-03 [1]
 prettyunits         1.1.1      2020-01-24 [1]
 progress            1.2.2      2019-05-16 [1]
 purrr             * 0.3.4      2020-04-17 [1]
 R6                  2.5.0      2020-10-28 [1]
 raster              3.4-5      2020-11-14 [1]
 Rcpp                1.0.5      2020-07-06 [1]
 readr             * 1.4.0      2020-10-05 [1]
 readxl              1.3.1      2019-03-13 [1]
 reprex              0.3.0      2019-05-16 [1]
 rio                 0.5.16     2018-11-26 [1]
 rlang               0.4.8      2020-10-08 [1]
 rmarkdown           2.3        2020-06-18 [1]
 rnaturalearth     * 0.1.0      2017-03-21 [1]
 rnaturalearthdata * 0.1.0      2017-02-21 [1]
 rprojroot           1.3-2      2018-01-03 [1]
 rstudioapi          0.11       2020-02-07 [1]
 rvest               0.3.6      2020-07-25 [1]
 sass                0.2.0      2020-03-18 [1]
 scales              1.1.1      2020-05-11 [1]
 sessioninfo         1.1.1      2018-11-05 [1]
 sf                * 0.9-5      2020-07-14 [1]
 snakecase           0.11.0     2019-05-25 [1]
 sp                  1.4-2      2020-05-20 [1]
 stringi             1.5.3      2020-09-09 [1]
 stringr           * 1.4.0      2019-02-10 [1]
 tibble            * 3.0.4      2020-10-12 [1]
 tidyr             * 1.1.2      2020-08-27 [1]
 tidyselect          1.1.0      2020-05-11 [1]
 tidyverse         * 1.3.0      2019-11-21 [1]
 tweenr              1.0.1      2018-12-14 [1]
 units               0.6-7      2020-06-13 [1]
 vctrs               0.3.5      2020-11-17 [1]
 vembedr           * 0.1.4      2020-10-10 [1]
 viridisLite         0.3.0      2018-02-01 [1]
 webshot             0.5.2      2019-11-22 [1]
 withr               2.2.0      2020-04-20 [1]
 xfun                0.17       2020-09-09 [1]
 xml2                1.3.2      2020-04-23 [1]
 yaml                2.2.1      2020-02-01 [1]
 zip                 2.1.1      2020-08-27 [1]
 source                               
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.0)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 Github (rlesur/klippy@378c247)       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.0)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 Github (perezp44/pjpv2020.01@91df4e6)
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       

[1] C:/Users/carlo/Documents/R/win-library/4.0
[2] C:/Program Files/R/R-4.0.2/library



  1. Información y video sacado de la web del Hospital Clinic de Barcelona.↩︎

LS0tDQp0aXRsZTogPEZPTlQgQ09MT1I9IkdyZWVuIj4iSW5jaWRlbmNpYSBkZWwgQ292aWQtMTkgZW4gbGEgQ29tdW5pZGFkIFZhbGVuY2lhbmEgIjwvRk9OVD4gDQphdXRob3I6ICJKdWFuIENhcmxvcyBHYXJjw61hIEd1YXJkZcOxbyAoZ2FyZ3VhcjJAYWx1bW5pLnV2LmVzKSAgXG5cbiBIdWdvIE1vbmVvIEhlcm7DoW5kZXogKGh1bW9oZXJAYWx1bW5pLnV2LmVzKSAgXG4gXG4gTWlndWVsIE1vbnRhbHZvIERpZXN0cm8gKG1vbmRpZXNAYWx1bW5pLnV2LmVzKS4gXG5cbiBVbml2ZXJzaXRhdCBkZSBWYWzDqG5jaWEiDQpkYXRlOiAiRGljaWVtYnJlIGRlIDIwMjAgKGFjdHVhbGl6YWRvIGVsIGByIGZvcm1hdChTeXMudGltZSgpLCAnJWQtJW0tJVknKWApIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRoZW1lOiBwYXBlcg0KICAgIGhpZ2hsaWdodDogdGV4dG1hdGUgDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2RlcHRoOiAzIA0KICAgIHRvY19mbG9hdDogDQogICAgICBjb2xsYXBzZWQ6IHRydWUNCiAgICAgIHNtb290aF9zY3JvbGw6IHRydWUNCiAgICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQ0KICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UNCiAgICBkZl9wcmludDoga2FibGUNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlDQotLS0NCg0KYGBge3IgcGFja2FnZXMtc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShrbGlwcHkpICANCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KHRpYmJsZSkNCmxpYnJhcnkoZ2d0aGVtZXMpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShwYXRjaHdvcmspDQpsaWJyYXJ5KGdncmVwZWwpDQpsaWJyYXJ5KHNmKQ0KbGlicmFyeShnZ3NwYXRpYWwpDQpsaWJyYXJ5KHJuYXR1cmFsZWFydGgpDQpsaWJyYXJ5KHJuYXR1cmFsZWFydGhkYXRhKQ0KbGlicmFyeShwanB2MjAyMC4wMSkNCmxpYnJhcnkocGxvdGx5KQ0KbGlicmFyeShnZ2FuaW1hdGUpDQpsaWJyYXJ5IChnaWZza2kpDQpsaWJyYXJ5KGd0KQ0KbGlicmFyeShrYWJsZUV4dHJhKQ0KbGlicmFyeShEVCkNCmxpYnJhcnkobGVhZmxldCkgDQpsaWJyYXJ5KGxlYWZlbSkgDQpgYGANCg0KYGBge3IgY2h1bmstc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCANCiAgICAgICAgICAgICAgICAgICAgICAjcmVzdWx0cyA9ICJob2xkIiwNCiAgICAgICAgICAgICAgICAgICAgICBjYWNoZSA9IEZBTFNFLCBjYWNoZS5wYXRoID0gIi9jYWNoZXMvIiwgY29tbWVudCA9ICIjPiIsDQogICAgICAgICAgICAgICAgICAgICAgI2ZpZy53aWR0aCA9IDcsICNmaWcuaGVpZ2h0PSA3LCAgIA0KICAgICAgICAgICAgICAgICAgICAgICNvdXQud2lkdGggPSA3LCBvdXQuaGVpZ2h0ID0gNywNCiAgICAgICAgICAgICAgICAgICAgICBjb2xsYXBzZSA9IFRSVUUsICBmaWcuc2hvdyA9ICJob2xkIiwNCiAgICAgICAgICAgICAgICAgICAgICBmaWcuYXNwID0gNy85LCBvdXQud2lkdGggPSAiNjAlIiwgZmlnLmFsaWduID0gImNlbnRlciIpDQprbml0cjo6b3B0c19jaHVuayRzZXQoZGV2ID0gInBuZyIsIGRldi5hcmdzID0gbGlzdCh0eXBlID0gImNhaXJvLXBuZyIpKQ0KYGBgDQoNCmBgYHtyIG9wdGlvbnMtc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCm9wdGlvbnMoc2NpcGVuID0gOTk5KSAjLSBwYXJhIHF1aXRhciBsYSBub3RhY2nDs24gY2llbnTDrWZpY2ENCm9wdGlvbnMoInlhbWwuZXZhbC5leHByIiA9IFRSVUUpIA0KYGBgDQoNCg0KYGBge3Iga2xpcHB5LCBlY2hvID0gRkFMU0V9DQprbGlwcHk6OmtsaXBweShwb3NpdGlvbiA9IGMoInRvcCIsICJyaWdodCIpKSAjLSByZW1vdGVzOjppbnN0YWxsX2dpdGh1Yigicmxlc3VyL2tsaXBweSIpDQpgYGANCg0KLS0tLS0tLS0tLS0tLS0tLS0NCg0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeSI+VHJhYmFqbyAgZWxhYm9yYWRvIHBhcmEgbGEgYXNpZ25hdHVyYSAiUHJvZ3JhbWFjacOzbiB5IG1hbmVqbyBkZSBkYXRvcyBlbiBsYSBlcmEgZGVsIEJpZyBEYXRhIiBkZSBsYSBVbml2ZXJzaXRhdCBkZSBWYWzDqG5jaWEgZHVyYW50ZSBlbCBjdXJzbyAyMDIwLTIwMjEuIExhIHDDoWdpbmEgd2ViIGRlIGxhIGFzaWduYXR1cmEgcHVlZGUgdmVyc2UgYXF1w606IDxodHRwczovL3BlcmV6cDQ0LmdpdGh1Yi5pby9pbnRyby1kcy0yMC0yMS13ZWIvPi4gTG9zIHRyYWJham9zIGRlIG1pcyBjb21wYcOxZXJvcyBkZSBjdXJzbyBwdWVkZW4gdmVyc2UgW2FxdcOtXShodHRwczovL3BlcmV6cDQ0LmdpdGh1Yi5pby9pbnRyby1kcy0yMC0yMS13ZWIvMDctdHJhYmFqb3MuaHRtbCkuPGRpdi8+DQoNCi0tLS0tLS0tLS0tLS0tLQ0KDQo8YnI+DQoNCiMgPEZPTlQgQ09MT1I9IkdyZWVuIj4xLiBJbnRyb2R1Y2Npw7NuIDwvRk9OVD4NCg0KDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5Ij4NCg0KRWwgYcOxbyAyMDIwIG5vIHNlcsOhIHVuIGHDsW8gcmVjb3JkYWRvIHBvciB0b2RvcyBsb3MgaGFiaXRhbnRlcyBkZWwgcGxhbmV0YSBjb24gdW5hIHNvbnJpc2EgZW4gZWwgcm9zdHJvLiBVbmEgcGFuZGVtaWEgc2UgYXBvZGVyYWJhIGRlbCBwbGFuZXRhIDEwMCBhw7FvcyBkZXNwdcOpcyBkZSBsYSBtYWwgbGxhbWFkYSBbZ3JpcGUgZXNwYcOxb2xhXShodHRwczovL2VzLndpa2lwZWRpYS5vcmcvd2lraS9QYW5kZW1pYV9kZV9ncmlwZV9kZV8xOTE4KSB5IG5vcyBoYWPDrWEgZW50cmFyIGVuIHVuYSBwZXNhZGlsbGEgcXVlIGEgZMOtYSBkZSBob3kgdG9kYXbDrWEgdGllbmUgdW4gaW5jaWVydG8gZmluYWwuDQoNCkxhcyBjYXVzYXMgZGUgbGEgcGFuZGVtaWEsIGRlc3B1w6lzIGRlIDEgYcOxbywgYcO6biBubyBlc3TDoW4gY2xhcmFzLiBMYSBtYXlvcsOtYSBkZSBsb3MgY2llbnRpZsOtY29zIChpbmNsdWlkYSBsYSBPTVMpIHNvc3RpZW5lbiBxdWUgbGEgKipjb3ZpZDE5KiogcG9kcsOtYSBzZXIgZGUgb3JpZ2VuIGFuaW1hbCBwZXJvIHBhcmEgb3Ryb3MgbGEgZXhpc3RlbmNpYSBkZWwgKm1heW9yIGNlbnRybyBjaGlubyBkZSBpbnZlc3RpZ2FjacOzbiB2aXJvbMOzZ2ljYSBzb2JyZSBDb3JvbmF2aXJ1cyogYSBwb2NhIGRpc3RhbmNpYSBkZWwgbWVyY2FkbyBkZSBXdWhhbiAoZXBpY2VudHJvIGRlbCB2aXJ1cyksIGFsaW1lbnRhIGxhcyB0ZW9yw61hcyBkZSBsYSBjb25zcGlyYWNpw7NuLiANCg0KRXN0ZSB0cmFiYWpvIHNlIHZhIGEgYmFzYXIgZW4gbGFzIGNvbnNlY3VlbmNpYXMgZGUgbGEgQ292aWQxOSBlbiBudWVzdHJhIHJlZ2nDs24uIFByaW1lcm8gZXhwbGljYXJlbW9zIGJyZXZlbWVudGUgcXVlIGVzIGxhIENvdmlkMTkgeSBxdWUgbWVkaWRhcyBiw6FzaWNhcyB0b21hciBwYXJhIHByZXZlbmlybm9zIGRlIGVsbGEuIFBvc3Rlcmlvcm1lbnRlIHByZXNlbnRhcmVtb3MgbGFzIGRpc3RpbnRhcyB2YXJpYWJsZXMgcXVlIHNlIHV0aWxpemFuIHBhcmEgZXN0dWRpYXIgbGEgZXZvbHVjacOzbiBkZSBsYSBwYW5kZW1pYS4gTGEgw7psdGltYSBwYXJ0ZSAoeSBsYSBtw6FzIGRlbnNhKSBlc3R1ZGlhcsOhIGxhIGV2b2x1Y2nDs24gZGUgbGEgcGFuZGVtaWEgZW4gbG9zIG11bmljaXBpb3MgcXVlIGludGVncmFuIG51ZXN0cmEgKiJDb211bml0YXQiKi4gVG9kb3MgbG9zIGTDrWFzIG5vcyBsbGVnYW4gbm90aWNpYXMgc29icmUgbG9zIHBhw61zZXMgcXVlIHRpZW5lbiBtw6FzIGluZmVjdGFkb3MsIG3DoXMgZmFsbGVjaWRvcywgbG9zIHF1ZSB0aWVuZW4gdW5hIHRhc2EgZGUgaW5jaWRlbmNpYSBhY3VtdWxhZGEgbcOhcyBhbHRhLi4uIGV0Yy4gwr9TYWJlbW9zIGNvbW8gY2FsY3VsYXIgZXN0YXMgdmFyaWFibGVzP8K/U2FiZW1vcyBpbnRlcnByZXRhcmxhcz/Cv0FsZ3VpZW4gc2FiZSBhbGdvIHNvYnJlIGVzdG9zIGRhdG9zIGVuIG51ZXN0cmEgcmVnacOzbj8gwr9RdWUgbXVuaW5pcGlvIHRpZW5lIHVuYSB0YXNhIGRlIGluY2lkZW5jaWEgYWN1bXVsYWRhIG3DoXMgYWx0YT/Cv1kgdW5hIHRhc2EgZGUgbW9ydGFsaWRhZCBtYXlvcj8gKipMTyBWRU1PUyoqLiANCg0KPGRpdi8+DQoNCiMgPEZPTlQgQ09MT1I9IkdyZWVuIj4yLiBJbmZvcm1hY2nDs24gYsOhc2ljYSBzb2JyZSBsYSBDb3ZpZC0xOSA8L0ZPTlQ+DQoNCiMjIDxGT05UIENPTE9SPSJHcmVlbiI+Mi4xLiDCv1F1w6kgZXMgbGEgQ292aWQtMTk/IDwvRk9OVD4NCg0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeSI+DQoNCkxhIENPVklELTE5IGVzIHVuYSBlbmZlcm1lZGFkIGluZmVjY2lvc2EgY2F1c2FkYSBwb3IgZWwgY29yb25hdmlydXMgU0FSUy0gQ29WLTIuIExvcyBjb3JvbmF2aXJ1cyBzb24gdW5hIGZhbWlsaWEgZGUgdmlydXMgcXVlIG5vcm1hbG1lbnRlIGFmZWN0YW4gc29sbyBhIGFuaW1hbGVzLiBBbGd1bm9zIGRlIGVsbG9zIHRhbWJpw6luIHRpZW5lbiBsYSBjYXBhY2lkYWQgZGUgdHJhbnNtaXRpcnNlIGRlIGxvcyBhbmltYWxlcyBhIGxhcyBwZXJzb25hcyBsbyBxdWUgY2F1c2EgcHJvYmxlbWFzIHJlc3BpcmF0b3Jpb3MuDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gRkFMU0V9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbcOhZ2VuZXMiLCAiaW1hZ2VuMS5qcGciKSAgKQ0KYGBgDQoNCkVsICoqY29yb25hdmlydXMgU0FSUy1Db1YtMioqIGVzIHVuIG51ZXZvIHRpcG8gZGUgY29yb25hdmlydXMgcXVlIHB1ZWRlIGFmZWN0YXIgYSBsYXMgcGVyc29uYXMgeSBxdWUgc2UgZGV0ZWN0w7MgcG9yIHByaW1lcmEgdmV6IGVuIGRpY2llbWJyZSBkZSAyMDE5IGVuIGxhIGNpdWRhZCBkZSBXdWhhbiwgcHJvdmluY2lhIGRlIEh1YmVpLCBlbiBDaGluYS4gDQoNCjxkaXYvPg0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IEZBTFNFfQ0KbGlicmFyeSgidmVtYmVkciIpDQplbWJlZF91cmwoImh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9SWFqOHlFcHV2Z2ciKQ0KYGBgDQoNCl5bSW5mb3JtYWNpw7NuIHkgdmlkZW8gc2FjYWRvIGRlIGxhIHdlYiBkZWwgSG9zcGl0YWwgQ2xpbmljIGRlIEJhcmNlbG9uYS5dDQoNCiMjIDxGT05UIENPTE9SPSJHcmVlbiI+Mi4yLiBGb3JtYXMgZGUgdHJhbnNtaXNpw7NuIGRlbCBTQVJTLUNvVi0yLiA8L0ZPTlQ+DQoNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnkiPg0KDQpFbCBjb3JvbmF2aXJ1cyBlcyB1biB2aXJ1cyBxdWUgc2UgY29udGFnaWEgY29uIGxhcyBnb3RhcyByZXNwaXJhdG9yaWFzIHF1ZSBleHB1bHNhbW9zIGxvcyBodW1hbm9zLiBFc3RvIHF1aWVyZSBkZWNpciBxdWUgbGFzIHBlcnNvbmFzIGluZmVjdGFkYXMgY3VhbmRvIGhhYmxhbiwgZ3JpdGFuLCBlc3Rvcm51ZGFuIG8gY2FudGFuIGV4cHVsc2FuIGNvbnRpbnVhbWVudGUgdW5hcyBnb3RhcyBxdWUgY29udGllbmVuIGVsIHZpcnVzLiBFc3RhcyBwYXJ0w61jdWxhcyBwdWVkZW4gaXIgaGFzdGEgZG9zIG1ldHJvcyBzaSBlc3RhbW9zIGhhYmxhbmRvLCBoYXN0YSA1IG1ldHJvcyBzaSBlc3RhbW9zIGNhbnRhbmRvIG8gZ3JpdGFuZG8gbyAqKmhhc3RhIDggbWV0cm9zKiogc2kgZXN0b3JudWRhbW9zIHNpbiB0YXBhcm5vcy4gVGFtYmnDqW4gaGFibGFyIGVuIGFsdG8gbyBhIGdyaXRvcyBwdWVkZSBnZW5lcmFyIGVsIHRyaXBsZSBkZSBwYXJ0w61jdWxhcyBxdWUgaGFjZXJsbyBlbiB2b3ogYmFqYS4gU2kgYWxndWllbiBlc3TDoSBpbnRlcmVzYWRvIHNvYnJlIGVzdG8gw7psdGltbyBwdWVkZSBjb25zdWx0YXIgW2FxdcOtXShodHRwczovL21hbGRpdGEuZXMvbWFsZGl0YWNpZW5jaWEvMjAyMC8wOC8yNC9nb3RpY3VsYXMtZ2VuZXJhZGFzLWdyaXRhci1jYW50YXItbGxlZ2FyLW1hcy1sZWpvcy1kb3MtbWV0cm9zLykgbGEgaW5mb3JtYWNpw7NuLg0KDQpFc3RhcyBnb3RhcyBwdWVkZW4gaW5mZWN0YXIgZGlyZWN0YW1lbnRlIGEgcGVyc29uYXMgcXVlIHRlbmVtb3MgY2VyY2EsIGFmZXJyw6FuZG9zZSBhIGxhcyBjw6lsdWxhcyB1YmljYWRhcyBlbiBsYSAqbXVjb3NhKiBkZSBsYSBuYXJpeiwgZ2FyZ2FudGEgeS9vIG9qb3MgZGUgbGFzIHBlcnNvbmEgaW5mZWN0YWRhcywgcGVybyB0YW1iacOpbiBjb250YW1pbmFuIGxhIHN1cGVyZmljaWUgZG9uZGUgY2Flbi4gU2kgcGVyc29uYXMgdG9jYW4gZXN0YXMgc3VwZXJmaWNpZXMgeSBzZSB0b2NhbiBuYXJpeiwgZ2FyZ2FudGEgdSBvam9zLCBjb24gdW5hIGFsdGEgcHJvYmFiaWxpZGFkLCBzZSBpbmZlY3RhcsOhbi4gIEVzdGFzIHNvbiBsYXMgZG9zIHRyYW5zbWlzaW9uZXMgZGUgbGEgZW5mZXJtZWRhZCBxdWUgc2UgY29ub2NpZXJvbiBkZXNkZSBlbCBwcmluY2lwaW8gcGVybyBubyBlcyBsYSDDum5pY2EgcGFyZWNlIHNlci4gTGEgZ3JhbiBwYXJ0ZSBkZSBsYSBjb211bmlkYWQgY2llbnTDrWZpY2EgKG1lbm9zIGxhIE9NUyksIGJhc2Fkb3MgZW4gbGEgZXZpZGVuY2lhIGNpZW50w61maWNhLCBlc3TDoW4gZGUgYWN1ZXJkbyBxdWUgZXN0YXMgZ290YXMgcHVlZGVuIHBlcm1hbmVjZXIgc3VzcGVuZGlkYXMgZW4gZWwgYWlyZSBoYXN0YSA4IGhvcmFzIGRlc3DDumVzIGRlIGhhYmVyIHNpZG8gZXhwdWxzYWRhcy4gUG9yIHRhbnRvLCBzaSBhbGd1aWVuIHBvcnRhZG9yIGRlbCB2aXJ1cyBlc3TDoSBzaW4gbWFzY2FyaWxsYSBlbiB1bmEgem9uYSBpbnRlcmlvciBzaW4gdmVudGlsYWNpw7NuLCB0b2RhIHBlcnNvbmEgcXVlIG5vIGxsZXZlIHVuYSBtYXNjYXJpbGxhIEZGUDIgcG9kcsOtYSBjb250YWdpYXJzZSBzaSBlbnRyYSBlbiBlc2UgYW1iaWVudGUgeSBwZXJtYW5lY2UgdW4gdGllbXBvIGVuIMOpbC4gDQoNCjxkaXYvPg0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IEZBTFNFfQ0KbGlicmFyeSgidmVtYmVkciIpDQplbWJlZF91cmwoImh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9SDM1dXNVU0o1RGsiKSANCmBgYA0KDQojIyA8Rk9OVCBDT0xPUj0iR3JlZW4iPjIuMy4gTWVkaWRhcyBwcmV2ZW50aXZhcy4gPC9GT05UPg0KDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5Ij4NCg0KRWwgdMOtdHVsbyBkZSBlc3RlIHN1Yi1hcGFydGFkbyBubyBlcyBjYXN1YWwuIEEgZMOtYSBkZSBob3kgKipubyBleGlzdGUgbWVkaWNhbWVudG8gbmkgdmFjdW5hIGVmZWN0aXZhIGRlbW9zdHJhZGEqKiBxdWUgcHVlZGEgZXJyYWRpY2FyIGxhIENPVklELTE5LiBVbiB2aXJ1cyBzZSBwdWVkZSBlbGltaW5hciBjdWFuZG8gc2UgY29uc2lndWUgZW4gdW5hIGNvbXVuaWRhZCBsYSBpbm11bmlkYWQgZGUgZ3J1cG8gKHF1ZSBlbCA3MCUgZGUgbGEgcG9ibGFjacOzbiBoYXlhIHBhc2FkbyBsYSBlbmZlcm1lZGFkKSBvIGRlc2Fycm9sbGFuZG8gdW5hIHZhY3VuYSBxdWUgbG8gbmV1dHJhbGljZS4gTGEgcHJpbWVyYSBtZWRpZGEgZnVlIHRvbWFkYSBwb3IgYWxndW5vcyBwYcOtc2VzIChSZWlubyBVbmlkbywgU3VlY2lhLCBFRVVVIHkgQnJhc2lsKSB5IHRyaXN0ZW1lbnRlLCB5YSBjb25vY2Vtb3MgbG9zIHJlc3VsdGFkb3MuIA0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IEZBTFNFfQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW3DoWdlbmVzIiwgIm1lZGlkYXMuanBnIikgICkNCmBgYA0KDQpQb3IgZXN0YSBzZWNpbGxhIHJhesOzbiB5IGhhc3RhIHF1ZSBhcGFyZXpjYSBsYSBhbnNpYWRhIHZhY3VuYSB0ZW5lbW9zIHF1ZSBzZWd1aXIgY3VtcGxpZW5kbyB1bmEgc2VyaWUgZGUgbWVkaWRhcyBwYXJhIGludGVudGFyIGZyZW5hciBlbCBhdmFuY2UgZGUgbGEgcGFuZGVtaWE6ICANCg0KPHN0eWxlPg0KZGl2LmJsdWUgeyBiYWNrZ3JvdW5kLWNvbG9yOiNlNmYwZmY7IGJvcmRlci1yYWRpdXM6IDVweDsgcGFkZGluZzogMjBweDt9DQo8L3N0eWxlPg0KPGRpdiBjbGFzcyA9ICJibHVlIj4NCg0KLSBVc28gZGUgbWFzY2FyaWxsYXMuIDxGT05UIENPTE9SPSJSZWQiPkZVTkRBTUVOVEFMISE8L0ZPTlQ+Lg0KLSBMYXZhZG8gY29udGludW8gZGUgbWFub3MuDQotIEV2aXRhciBsb3MgZXNwYWNpb3MgY2VycmFkb3Mgc2luICB2ZW50aWxhY2nDs24uDQotIEV2aXRhciBsb2NhbGVzIGRlIGludGVyaW9yIGVuIGxvcyBxdWUgbGEgbWFzY2FyaWxsYSBubyBzZWEgb2JsaWdhdG9yaWEuDQo8L2Rpdj4NCg0KT3MgZGVqYW1vcyBkb3MgY2FtcGHDsWFzIHF1ZSBub3MgaGFuIGd1c3RhZG8gZXNwZWNpYWxtZW50ZToNCg0KYGBge3IgZXZhbCA9IFRSVUUsIGVjaG8gPSBGQUxTRX0NCmxpYnJhcnkoInZlbWJlZHIiKQ0KZW1iZWRfdXJsKCJodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PUtCbDllWktMMW04IikNCmBgYA0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IEZBTFNFfQ0KbGlicmFyeSgidmVtYmVkciIpDQplbWJlZF91cmwoImh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9V09XSllFRnF0UTgiKSANCmBgYA0KDQo8ZGl2Lz4NCg0KIyA8Rk9OVCBDT0xPUj0iR3JlZW4iPjMuIEluZGljYWRvcmVzIGRlIGV2b2x1Y2nDs24gZGUgbGEgcGFuZGVtaWEuIDwvRk9OVD4NCg0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeSI+DQoNCk3DoXMgYWRlbGFudGUgdmFtb3MgYSBhbmFsaXphciA0IGluZGljYWRvcmVzIGRpc3RpbnRvcyBxdWUgc2UgdXRpbGl6YW4gcGFyYSBzYWJlciBlbiBxdWUgcHVudG8gZGUgZXZvbHVjacOzbiBlc3TDoSBsYSBwYW5kZW1pYSBlbiBjYWRhIMOhcmVhIGdlb2dyw6FmaWNhLiBTaSBlc3RvcyBpbmRpY2Fkb3JlcyBhcnJvamFuIHJlc3VsdGFkb3MgbmVnYXRpdm9zLCBsYSBhZG1pbmlzdHJhY2nDs24gc2UgdmUgb2JsaWdhZGEgYSBpbnRlcnZlbmlyIHkgdG9tYSBtZWRpZGFzIG3DoXMgcmVzdHJpY3RpdmFzLiBWYW1vcyBhIGFuYWxpemFyIGRvcyBxdWUgcHVlZGVuIGxsZXZhciBhIHVuYSBtYWxhIGludGVycHJldGFjacOzbiBkZSBsb3MgcmVzdWx0YWRvczoNCg0KPGRpdi8+DQoNCiMjIDxGT05UIENPTE9SPSJHcmVlbiI+My4xLiBJbmRpY2Fkb3JlcyBleHBsaWNhZG9zIDwvRk9OVD4gey50YWJzZXR9DQoNCiMjIyA8Rk9OVCBDT0xPUj0iR3JlZW4iPjMuMS4xLiBUYXNhIGRlIEluY2lkZW5jaWEgYWN1bXVsYWRhLiA8L0ZPTlQ+DQoNClNvbiBsYXMgcGVyc29uYXMgcXVlIGhhbiBlbmZlcm1hZG8gcG9yIENvdmlkLTE5IHBvciBjYWRhIDEwMC4wMDAgaGFiaXRhbnRlcy4gU2UgY2FsY3VsYSBwb3IgY2FkYSAxMDAuMDAwIGhhYml0YW50ZXMgcGFyYSBwb2RlciBjb21wYXJhciBlbnRyZSBtdW5pY2lwaW9zIHlhIHF1ZSBlbiB0w6lybWlub3MgYWJzb2x1dG9zIHNpZW1wcmUgc2Vyw61hIG1heW9yIGVuIGxvcyBtdW5pY2lwaW9zIGNvbiBtYXlvciBwb2JsYWNpw7NuIHkgbm8gc2Vyw61hIHBvc2libGUgbGEgY29tcGFyYWNpw7NuLiANCg0KRW4gZXN0ZSBpbmZvcm1lIHZhbW9zIGEgdXRpbGl6YXIgbGEgdGFzYSBkZSBpbmNpZGVuY2lhIGFjdW11bGFkYSB5IGxhIHRhc2EgZGUgaW5jaWRlbmNpYSBkZSBsb3Mgw7psdGltb3MgMTQgZMOtYXMuIExhIHByaW1lcmEgZGUgZWxsYSBzZSB1dGlsaXphIHBhcmEgcG9kZXIgY29tcGFyYXIgbG9zIGRhdG9zIGRlIGluY2lkZW5jaWEgZGUgbGEgQ292aWQxOSBkZXNkZSBlbCAqaW5pY2lvIGRlIGxhIHBhbmRlbWlhKiB5IGxhIHNlZ3VuZGEgc2UgdXRpbGl6YSBwYXJhIHBvZGVyIGNvbXBhcmFyIGxvcyBkYXRvcyBkZSBpbmNpZGVuY2lhIGRlIGxhIENvdmlkMTkgKiplbiBsb3Mgw7psdGltb3MgMTQgZMOtYXMqKi4NCg0KU2kgcXVlcmVtb3Mgb2J0ZW5lciBsYSBpbmNpZGVuY2lhIGEgMTQgZMOtYXMgbGEgcG9kZW1vcyBjYWxjdWxhciBkaXZpZGllbmRvIGVsIG7Dum1lcm8gZGUgY2Fzb3MgYXBhcmVjaWRvcyBlbnRyZSBlbCBuw7ptZXJvIGRlIHBlcnNvbmFzIHF1ZSBlc3TDoW4gbGlicmVzIGRlIGxhIGVuZmVybWVkYWQgYWwgaW5pY2lvIGRlbCBwZXJpb2RvLiBOb3JtYWxtZW50ZSBzZSBzdWVsZSB0ZW5lciBlbiBjdWVudGEgY2FkYSAxMDAuMDAwIGhhYml0YW50ZXMgeSBhIDE0IGTDrWFzLlNlIGNhbGN1bGEgYXPDrTogDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gRkFMU0V9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbcOhZ2VuZXMiLCAiaS5hY3VtdWxhZGExNC5wbmciKSAgKQ0KYGBgDQoNCg0KDQoNCg0KIyMjIDxGT05UIENPTE9SPSJHcmVlbiI+My4xLjEuIFRhc2EgZGUgbW9ydGFsaWRhZC4gPC9GT05UPg0KDQpOb3JtYWxtZW50ZSBzZSBleHByZXNhIGNvbW8gZWwgbsO6bWVybyBkZSBtdWVydGVzIHBvciBjYWRhIDEwMC4wMDAgaGFiaXRhbnRlcyBTZSBvYnRpZW5lIG11bHRpcGxpY2FuZG8gbG9zIGZhbGxlY2ltaWVudG9zIHBvciBDb3ZpZCBwb3IgMTAwLjAwMCB5IGRpdmlkaWVuZG8gZWwgcmVzdWx0YWRvIGVudHJlIGxhIHBvYmxhY2nDs24gdG90YWw6DQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gRkFMU0V9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbcOhZ2VuZXMiLCAiZm9ybXVsYV90YXNhX2ZhbGxlY2lkb3NfY292aWQucG5nIikgICkNCmBgYCANCg0KICAgICAgICAgICAgICAgICANCg0KDQoNCg0KDQojIDxGT05UIENPTE9SPSJHcmVlbiI+NC4gRWZlY3RvcyBkZSBsYSBDb3ZpZC0xOSBlbiBsYSBDLlYuIDwvRk9OVD4NCg0KIyMgPEZPTlQgQ09MT1I9IkdyZWVuIj40LjEuIEV2b2x1Y2nDs24gZGUgbG9zIGNvbnRhZ2lvcy4gPC9GT05UPg0KDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gVFJVRX0NCg0KZGZwb3NpdGl2b3MgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvY292aWQtMTktc2VyaWUtZGUtY2Fzb3MtY29uLXBkaWEtcG9zaXRpdmEtZW4tbGEtY29tdW5pdGF0LXZhbGVuY2lhbmEuY3N2IikNCg0KZGZwb3NpdGl2b3MgPC0gZGZwb3NpdGl2b3MgJT4lIHNlbGVjdChgRGF0YSBkaWFnbsODwrJzdGljIGxhYm9yYXRvcmkvZmVjaGEgZGlhZ27Dg8Kzc3RpY28gbGFib3JhdG9yaW9gLCBgSG9tZXMvSG9tYnJlc2AsIGBEb25lcy9NdWplcmVzYCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBQcm92LiBBbGFjYW50L0FsaWNhbnRlYCwgYFByb3YuIENhc3RlbGzDg8KzL0Nhc3RlbGzDg8KzbmAsIGBQcm92LiBWYWzDg8KobmNpYWApICAjLSBsb3MgZGVwYXJ0YW1lbnRvcyBkZSBzYWx1ZCBubyBtZSBpbnRlcmVzYW4gcGFyYSBlc3RlIHRyYWJham8NCg0KI2FxdcOtIGxvIHByaW1lcm8gcXVlIHRlbmVtb3MgcXVlIGhhY2VyIGVzIGNhbWJpYXIgbm9tYnJlcyByYXJvcyBkZSBjb2x1bW5hcw0KDQpub21icmVzX29yaWdpbmFsZXMxIDwtIG5hbWVzKGRmcG9zaXRpdm9zKQ0Kbm9tYnJlc19vcmlnaW5hbGVzMQ0KbmFtZXMoZGZwb3NpdGl2b3MpWzFdIDwtICJGZWNoYSBQQ1IgUG9zaXRpdmEiDQpuYW1lcyhkZnBvc2l0aXZvcylbMl0gPC0gIkhvbWJyZXMiDQpuYW1lcyhkZnBvc2l0aXZvcylbM10gPC0gIk11amVyZXMiDQpuYW1lcyhkZnBvc2l0aXZvcylbNF0gPC0gIkFsaWNhbnRlIg0KbmFtZXMoZGZwb3NpdGl2b3MpWzVdIDwtICJDYXN0ZWxsw7NuIg0KbmFtZXMoZGZwb3NpdGl2b3MpWzZdIDwtICJWYWxlbmNpYSINCg0KI2luc3RhbGwucGFja2FnZXMoImdpZnNraSIpDQojaW5zdGFsbC5wYWNrYWdlcygiZ2dhbmltYXRlIikNCg0KZGZwb3NpdGl2b3MkQy5WYWxlbmNpYW5hIDwtIGRmcG9zaXRpdm9zJEFsaWNhbnRlICsgZGZwb3NpdGl2b3MkQ2FzdGVsbMOzbiArIGRmcG9zaXRpdm9zJFZhbGVuY2lhDQoNCmdyYWZpY28xIDwtIGdncGxvdChkZnBvc2l0aXZvcywgYWVzKGBGZWNoYSBQQ1IgUG9zaXRpdmFgLCBgQy5WYWxlbmNpYW5hYCkpICsgDQogIGdlb21fbGluZShjb2xvcj0iZ3JlZW4iLCBzaXplPTEpKyBsYWJzKHRpdGxlID0gIlBvc2l0aXZvcyBkZXRlY3RhZG9zIHBvciBQQ1IgZWwgZMOtYSB7ZnJhbWVfYWxvbmd9IiwgInggPSBGZWNoYSIsIGNhcHRpb24gPSAiRnVlbnRlIEdWQSIpKyB0aGVtZV9taW5pbWFsKCkrICANCiAgdHJhbnNpdGlvbl9yZXZlYWwoYEZlY2hhIFBDUiBQb3NpdGl2YWApDQoNCmdyYWZpY28xDQpgYGANCg0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeSI+IA0KDQpMYSBldm9sdWNpw7NuIGRlIGxvcyBjb250YWdpb3MgcG9yIENvdmlkLTE5IHF1ZSBub3MgZW5zZcOxYSBlc3RlIGdyw6FmaWNvIGFuaW1hZG8gcmVmbGVqYSBtdXkgYmllbiBsYXMgbGxhbWFkYXMgIm9sYXMiIHF1ZSBub3MgaGEgZGVqYWRvLCBwb3IgZWwgbW9tZW50bywgZXN0YSBwYW5kZW1pYS4gDQoNClBvZGVtb3Mgb2JzZXJ2YXIgdW4gKmF1bWVudG8gcsOhcGlkbyBkZSBsb3MgY29udGFnaW9zIGVudHJlIG1hcnpvIHkgYWJyaWwqLiBBcXXDrSBjYWJyw61hIHJlc2XDsWFyIHF1ZSBlc3RvcyBkYXRvcyBubyBzb24gdGFuIGZpZGVkaWdub3MgY29tbyBsb3MgZGUgbWVzZXMgcG9zdGVyaW9yZXMgeWEgcXVlIG5vIHNlIGhhY8OtYW4gbGFzIHN1ZmljaWVudGVzIHBydWViYXMgcG9yIGxhIGZhbHRhIGRlIHBydWViYXMgZGlhZ27Ds3N0aWNhcyBQQ1IuIFNlZ8O6biB1biBbZXN0dWRpbyBkZSBzZXJvcHJldmFsZW5jaWEgcmVhbGl6YWRvIGVuIGxvcyBtZXNlcyBkZSBhYnJpbCB5IG1heW8gXShodHRwczovL3d3dy5hYmMuZXMvZXNwYW5hL2NvbXVuaWRhZC12YWxlbmNpYW5hL2FiY2ktdGVzdC1yZXZlbGFuLTEyNTAwMC1wZXJzb25hcy1wYXNhZG8tY29yb25hdmlydXMtY29tdW5pZGFkLXZhbGVuY2lhbmEtMjAyMDA1MTMyMzI5X25vdGljaWEuaHRtbCkgbcOhcyBkZSAqKjEyNS4wMDAgdmFsZW5jaWFub3MgaW5mZWN0YWRvcyoqIHNlIGNvbnRhZ2lhcm9uIGR1cmFudGUgbG9zIHByaW1lcm9zIG1lc2VzLg0KDQpFbCBjb25maW5hbWllbnRvIGRlY3JldGFkbyBkZSBkb3MgbWVzZXMgbm9zIHNpcnZpw7MgcGFyYSBpciBkZXNjZW5kaWVuZG8gZWwgbsO6bWVybyBkZSBjb250YWdpb3MgZ3JhZHVhbG1lbnRlIGRlc2RlIG1heW8sIGhhc3RhIGxsZWdhciBhIHRlbmVyIGNpZnJhcyBkaWFyaWFzIGRlIGNvbnRhZ2lvcyByZWxhdGl2YW1lbnRlIGJhamFzLCB5YSBlbiBlbiBlbCBtZXMgZGUganVuaW8uIA0KDQpMYSByw6FwaWRhIGRlc2VzY2FsYWRhIGhlY2hhIHBvciBlbCBnb2JpZXJubyAocHJlc2lvbmFkbyBwb3IgbGFzIENDQUEpLCB1bmlkYSBhIGxhIGFjdGl0dWQgaXJyZXNwb25zYWJsZSBkZSBtdWNob3MgY2l1ZGFkYW5vcyBkdXJhbnRlIGVsIHZlcmFubywgcHJvdm9jw7MgbGEgc2VndW5kYSBvbGEgZGUgbGEgcGFuZGVtaWEuIFBvZGVtb3Mgb2JzZXJ2YXIgcXVlIGxhIGdyw6FmaWNhIHJlZmxlamEgcXVlIGEgcGFydGlyIGRlIGZpbmFsZXMgZGUganVsaW8sIGxvcyBkYXRvcyBlbXBpZXphbiBhIGRpc3BhcmFyc2UgZGUgbnVldm8uIEVzdGEgc2VndW5kYSBvbGEgdGVuZHLDoSBzdSBwaWNvIGEgbWVkaWRhZG9zIGRlIG5vdmllbWJyZSwgZG9uZGUgcGFyZWNlIGRlc2NlbmRlciBoYXN0YSBudWVzdHJvcyBkw61hcy4NCg0KPGRpdi8+DQoNCiMjIDxGT05UIENPTE9SPSJHcmVlbiI+NC4yLiBFdm9sdWNpw7NuIGRlIGxvcyBmYWxsZWNpZG9zLiA8L0ZPTlQ+DQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gRkFMU0V9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbcOhZ2VuZXMiLCAibGF6b19uZWdyby5wbmciKSAgKQ0KYGBgDQoNCg0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IFRSVUV9DQoNCmRmZmFsbCA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jb3ZpZC0xOS1zZXJpZS1kZS1wZXJzb25hcy1mYWxsZWNpZGFzLWVuLWxhLWNvbXVuaXRhdC12YWxlbmNpYW5hLmNzdiIpDQoNCiMtIGxvcyBkZXBhcnRhbWVudG9zIGRlIHNhbHVkIG5vIG1lIGludGVyZXNhbiBwYXJhIGVzdGUgdHJhYmFqbw0KZGZmYWxsIDwtIGRmZmFsbCAlPiUgc2VsZWN0KGBEYXRhIGRlIGRlZnVuY2nDg8KzL2ZlY2hhIGRlIGRlZnVuY2nDg8KzbmAsIGBIb21lcy9Ib21icmVzYCwgYERvbmVzL011amVyZXNgLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBQcm92LiBBbGFjYW50L0FsaWNhbnRlYCwgYFByb3YuIENhc3RlbGzDg8KzL0Nhc3RlbGzDg8KzbmAsIGBQcm92LiBWYWzDg8KobmNpYWApIA0KDQojYXF1w60gbG8gcHJpbWVybyBxdWUgdGVuZW1vcyBxdWUgaGFjZXIgZXMgY2FtYmlhciBub21icmVzIHJhcm9zIGRlIGNvbHVtbmFzDQoNCm5vbWJyZXNfb3JpZ2luYWxlcyA8LSBuYW1lcyhkZmZhbGwpDQpub21icmVzX29yaWdpbmFsZXMNCm5hbWVzKGRmZmFsbClbMV0gPC0gIkZlY2hhX0RlZnVuY2nDs24iDQpuYW1lcyhkZmZhbGwpWzJdIDwtICJIb21icmVzIg0KbmFtZXMoZGZmYWxsKVszXSA8LSAiTXVqZXJlcyINCm5hbWVzKGRmZmFsbClbNF0gPC0gIkFsaWNhbnRlIg0KbmFtZXMoZGZmYWxsKVs1XSA8LSAiQ2FzdGVsbMOzbiINCm5hbWVzKGRmZmFsbClbNl0gPC0gIlZhbGVuY2lhIg0KDQpkZmZhbGwkQy5WYWxlbmNpYW5hIDwtIGRmZmFsbCRBbGljYW50ZSArIGRmZmFsbCRDYXN0ZWxsw7NuICsgZGZmYWxsJFZhbGVuY2lhDQoNCmdyYWZpY28yIDwtIGdncGxvdChkZmZhbGwsIGFlcyhgRmVjaGFfRGVmdW5jacOzbmAsIGBDLlZhbGVuY2lhbmFgKSkgKyANCiAgZ2VvbV9saW5lKGNvbG9yPSJvcmFuZ2UiLCBzaXplPTEpKyBsYWJzKHRpdGxlID0gIkZhbGxlY2lkb3MgcG9yIENvdmlkLTE5IGVsIGTDrWEge2ZyYW1lX2Fsb25nfSIpKyB0aGVtZV9taW5pbWFsKCkrICANCiAgdHJhbnNpdGlvbl9yZXZlYWwoYEZlY2hhX0RlZnVuY2nDs25gKQ0KDQpncmFmaWNvMg0KYGBgDQoNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnkiPg0KDQpMYSBldm9sdWNpw7NuIGRlIGxvcyBmYWxsZWNpZG9zIG11ZXN0cmEgdW5hIGV2b2x1Y2nDs24gaWTDqW50aWNhIGEgbGEgZXZvbHVjacOzbiBkZSBjb250YWdpb3MgcGVybyBjb24gZG9zIG1hdGljZXM6DQoNCi0gTG9zIGluY3JlbWVudG9zIGRlIGNvbnRhZ2lvcyBzZSByZWZsZWphbiBlbiBuw7ptZXJvIGRlIG11ZXJ0ZXMgYXByb3hpbWFkYW1lbnRlIDE1IGTDrWFzIGRlc3B1w6lzIGRlIHByb2R1Y2lyc2UgZGljaG9zIGNvbnRhZ2lvcywgcG9yIGxvIHF1ZSBoYWJyw6EgdW4gZGVzZmFzZSB0ZW1wb3JhbCBlbiBlc3RvcyBkb3MgZ3LDoWZpY29zLg0KDQotIExhIG1heW9yIGRpc3BvbmliaWxpZGFkIGRlIGVxdWlwb3MgZGUgcHJvdGVjY2nDs24gYWRlY3VhZG9zIHBhcmEgc2FuaXRhcmlvcyB5IHBlcnNvbmFsIGRlIHJlc2lkZW5jaWFzLCBsYSBpbXBvc2ljacOzbiBkZSBsYSBtYXNjYXJpbGxhIG9ibGlnYXRvcmlhIHBhcmEgdG9kYSBsYSBjaXVkYWRhbmlhLCBlbCBpbmNyZW1lbnRvIGVzcGVjdGFjdWxhciBlbiBlbCBuw7ptZXJvIGRlIHBydWViYXMgUENSIHJlYWxpemFkYXMsIGxhICJidW5xdWVyaXphY2nDs24iIGRlIGxhcyByZXNpZGVuY2lhcyBkZSBhbmNpYW5vcyB5IGxhIGV4cGVyaWVuY2lhIGdhbmFkYSBwb3IgbGFzIGRpc3RpbnRhcyBhZG1pbmlzdHJhY2lvbmVzIGVuIGxhIGdlc3Rpw7NuIGRlIGxhIHBhbmRlbWlhLCBoYSBjb25zZWd1aWRvIHJlZHVjaXIgZWwgbsO6bWVybyBkZSBmYWxsZWNpbWllbnRvcyBlbiBlc3RhIHNlZ3VuZGEgb2xhIChubyBlbCBuw7ptZXJvIGRlIGluZmVjdGFkb3MpLg0KDQpIYXkgcXVlIGFkdmVydGlyIHF1ZSBlbCBuw7ptZXJvIGRlIGZhbGxlY2lkb3MgZGUgbGFzIGVzdGFkw61zdGljYXMgbm8gcmVmbGVqYSBlbCBuw7ptZXJvIGRlIGZhbGxlY2lkb3MgcmVhbCBxdWUgaGEgaGFiaWRvIGVuIG51ZXN0cm8gcGHDrXMuIEVuIHVuIHByaW1lciBtb21lbnRvLCBjb24gbG9zIGhvc3BpdGFsZXMgY29sYXBzYWRvcywgbGEgcHJpb3JpZGFkIGZ1ZSB0cmF0YXIgYSBsb3MgZW5mZXJtb3Mgc2luIGhhY2VyIHBydWViYXMgZm9yZW5zZXMgYSBsb3MgZmFsbGVjaWRvcyBxdWUgZGV0ZXJtaW5hcmFuIHNpIGVzdGFzIG11ZXJ0ZXMgZXJhbiBwcm92b2NhZGFzIHBvciBsYSBDb3ZpZC0xOS4gQ3VhbmRvIGEgbGEgcGVyc29uYSBmYWxsZWNpZGEgbm8gc2UgbGUgaGFiw61hIGhlY2hvIHVuYSBQQ1IgcHJldmlhIGFsIGZhbGxlY2ltaWVudG8sIGxvcyBtw6lkaWNvcyBwb27DrWFuIGVuIHN1cyBpbmZvcm1lcyBsYSBDb3ZpZC0xOSBjb21vIGNhdXNhIHByb2JhYmxlIGRlIGxhIG11ZXJ0ZSBwZXJvIGVsIGdvYmllcm5vIG5vIGxhcyBpbmNsdcOtYSBlbiBsYXMgZXN0YWTDrXN0aWNhcyBvZmljaWFsZXMgZGUgdsOtY3RpbWFzIHBvciBDb3ZpZC0xOS4NCg0KRGUgdG9kYXMgbWFuZXJhcyBzZSBwdWVkZSBzYWJlciBhcHJveGltYWRhbWVudGUgKmVsIG7Dum1lcm8gZGUgZmFsbGVjaWRvcyByZWFsZXMqIHF1ZSBoYSBoYWJpZG8gZW4gbnVlc3RybyBwYcOtcyBzaSBjb21wYXJhbW9zIGxvcyBkYXRvcyBkZSBmYWxsZWNpZG9zIHF1ZSB0aWVuZSBlbCBJTkUgZW50cmUgdW4gYcOxbyB5IG90cm8uIFNlZ8O6biBbZXN0YSBub3RpY2lhIF0oaHR0cHM6Ly93d3cucmVkYWNjaW9ubWVkaWNhLmNvbS9zZWNjaW9uZXMvc2FuaWRhZC1ob3kvY29yb25hdmlydXMtZXNwYW5hLWV4Y2Vzby03MDcxNy1tdWVydGVzLXJlc3BlY3RvLTIwMTktNjI1NykgaGF5ICoqNzAuNzE3IGZhbGxlY2lkb3MgbcOhcyBxdWUgZW4gMjAxOSoqIHkgdG9kYXbDrWEgbm8gaGEgdGVybWluYWRvIGVsIGHDsW8uDQoNCg0KPGRpdi8+DQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gVFJVRX0NCmRmZmFsbCA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jb3ZpZC0xOS1zZXJpZS1kZS1wZXJzb25hcy1mYWxsZWNpZGFzLWVuLWxhLWNvbXVuaXRhdC12YWxlbmNpYW5hLmNzdiIpDQoNCiMtIGxvcyBkZXBhcnRhbWVudG9zIGRlIHNhbHVkIG5vIG1lIGludGVyZXNhbiBwYXJhIGVzdGUgdHJhYmFqbw0KZGZmYWxsIDwtIGRmZmFsbCAlPiUgc2VsZWN0KGBEYXRhIGRlIGRlZnVuY2nDg8KzL2ZlY2hhIGRlIGRlZnVuY2nDg8KzbmAsIGBIb21lcy9Ib21icmVzYCwgYERvbmVzL011amVyZXNgLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBQcm92LiBBbGFjYW50L0FsaWNhbnRlYCwgYFByb3YuIENhc3RlbGzDg8KzL0Nhc3RlbGzDg8KzbmAsIGBQcm92LiBWYWzDg8KobmNpYWApIA0KDQojYXF1w60gbG8gcHJpbWVybyBxdWUgdGVuZW1vcyBxdWUgaGFjZXIgZXMgY2FtYmlhciBub21icmVzIHJhcm9zIGRlIGNvbHVtbmFzDQoNCm5vbWJyZXNfb3JpZ2luYWxlcyA8LSBuYW1lcyhkZmZhbGwpDQpub21icmVzX29yaWdpbmFsZXMNCm5hbWVzKGRmZmFsbClbMV0gPC0gIkZlY2hhX0RlZnVuY2nDs24iDQpuYW1lcyhkZmZhbGwpWzJdIDwtICJIb21icmVzIg0KbmFtZXMoZGZmYWxsKVszXSA8LSAiTXVqZXJlcyINCm5hbWVzKGRmZmFsbClbNF0gPC0gIkFsaWNhbnRlIg0KbmFtZXMoZGZmYWxsKVs1XSA8LSAiQ2FzdGVsbMOzbiINCm5hbWVzKGRmZmFsbClbNl0gPC0gIlZhbGVuY2lhIg0KDQpkZmZhbGwkQy5WYWxlbmNpYW5hIDwtIGRmZmFsbCRBbGljYW50ZSArIGRmZmFsbCRDYXN0ZWxsw7NuICsgZGZmYWxsJFZhbGVuY2lhDQoNCg0KcCA8LSBnZ3Bsb3QoZGZmYWxsKSArIGdlb21fbGluZShhZXMoeD0gRmVjaGFfRGVmdW5jacOzbiwgeT0gSG9tYnJlcyksY29sb3IgPSAieWVsbG93IikgKw0KICBnZW9tX2xpbmUgKGFlcyh4PSBGZWNoYV9EZWZ1bmNpw7NuLCB5ID0gTXVqZXJlcyksIGNvbG9yID0gImJsdWUiKSsNCiAgICBsYWJzKHRpdGxlID0gIkZhbGxlY2lkb3MgcG9yIGfDqW5lcm8iLA0KICAgICAgICAgc3VidGl0bGUgPSAiQ29tcGFyYWNpw7NuIiwNCiAgICAgICBjYXB0aW9uID0gIkRhdG9zIHByb3BvcmNpb25hZG9zIHBvciBsYSBHVkEiLA0KICAgICAgIHg9IkZlY2hhIiwgeT0iTsO6bWVybyBkZSBmYWxsZWNpZG9zIikrDQogIHRoZW1lX2RhcmsoKQ0KDQpnZ3Bsb3RseShwKQ0KDQpgYGANCg0KQ29tbyBjdXJpb3NpZGFkIGFwb3J0YW1vcyBlc3RlIGdyw6FmaWNvIGludGVyYWN0aXZvIGVuIGVsIHF1ZSBzZSBtdWVzdHJhIHF1ZSBzZSBoYW4gcHJvZHVjaWRvIG3DoXMgZmFsbGVjaW1pZW50b3MgZW4gaG9tYnJlcyBxdWUgZW4gbXVqZXJlcy4NCg0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IFRSVUV9DQoNCmFhIDwtIGFzLmRhdGEuZnJhbWUoY29sb3VycygpKQ0KDQpkZmZhbGxlZGFkIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL2NvdmlkLTE5LWRhdG9zLWRlLWNhc29zLXktcGVyc29uYXMtZmFsbGVjaWRhcy1wb3ItZ3J1cG8tZGUtZWRhZC15LXNleG8tYWN1bXVsYWRvcy1kZXNkZS1lbC0zMS0wMS5jc3YiKQ0KDQpkZmZhbGxlZGFkbXVqZXJlcyA8LSBkZmZhbGxlZGFkICU+JSAgc2xpY2UoYygxOjEwKSkNCg0KZGZmYWxsZWRhZGhvbWJyZXMgPC0gZGZmYWxsZWRhZCAlPiUgIHNsaWNlKGMoMTE6MjApKQ0KDQpqYW5pdG9yOjpjbGVhbl9uYW1lcyhkZmZhbGxlZGFkbXVqZXJlcykgJT4lIG5hbWVzKCkNCg0KcDEgPC0gZ2dwbG90IChkZmZhbGxlZGFkbXVqZXJlcywgYWVzKEdydXBfZWRhdCwgUGVyY2VudGF0Z2VfbW9ydHMpKSArIGdlb21fY29sKGZpbGw9ICJ0b21hdG8iKSArIGNvb3JkX2ZsaXAoKSArDQogIGxhYnMgKHRpdGxlID0gIiUgbXVlcnRlcyBkZSBtdWplcmVzIiwNCiAgICBzdWJ0aXRsZSA9ICJDbGFzaWZpY2FkbyBwb3IgZ3J1cG8gZGUgZWRhZCIsDQogICAgeSA9ICIlIG11ZXJ0ZXMgQ09WSUQxOSIsDQogICAgeCA9ICJHcnVwbyBkZSBlZGFkIikgKyB0aGVtZV9zb2xhcml6ZWQoKQ0KDQpwMiA8LSBnZ3Bsb3QgKGRmZmFsbGVkYWRob21icmVzLCBhZXMoR3J1cF9lZGF0LCBQZXJjZW50YXRnZV9tb3J0cykpICsgZ2VvbV9jb2woZmlsbD0gImJyb3duIikgKyBjb29yZF9mbGlwKCkgKyANCiAgbGFicyAodGl0bGUgPSAiJSBtdWVydGVzIGRlIGhvbWJyZXMiLA0KICAgIHN1YnRpdGxlID0gIkNsYXNpZmljYWRvIHBvciBncnVwbyBkZSBlZGFkIiwNCiAgICBjYXB0aW9uID0gIkZ1ZW50ZSBHVkEiLA0KICAgIHkgPSAiJSBtdWVydGVzIENPVklEMTkiLA0KICAgIHggPSAiR3J1cG8gZGUgZWRhZCIpICsgdGhlbWVfc29sYXJpemVkKCkNCg0KcDErcDINCmBgYA0KDQpFc3RlIG90cm8gZ3LDoWZpY28gbXVlc3RyYSBsb3MgdHJhbW9zIGRlIGVkYWQgZGUgbGFzIHBlcnNvbmFzIGZhbGxlY2lkYXMgeSBsb3MgY29tcGFyYSBhZGVtw6FzIHBvciBnw6luZXJvLg0KDQpQb2RlbW9zIG9ic2VydmFyIHF1ZSwgZGVzZ3JhY2lhZGFtZW50ZSwgbG9zIGluZGl2aWR1b3MgcXVlIHRlbsOtYW4gbcOhcyBkZSA3MCBhw7FvcyBoYW4gc2lkbyBsYXMgZ3JhbmRlcyB2w61jdGltYXMgZGUgZXN0YSBwYW5kZW1pYS4NCg0KIyA8Rk9OVCBDT0xPUj0iR3JlZW4iPjUuIFZhcmlhYmxlcyBhbmFsaXphZGFzLiA8L0ZPTlQ+DQoNCiMjIDxGT05UIENPTE9SPSJHcmVlbiI+NS4xLiBUYWJsYSBwYXJhIGNvbnN1bHRhIHNvYnJlIGRhdG9zIC4gPC9GT05UPg0KDQpFbiBlc3RhIHRhYmxhIHJlc3VtZW4gaW50ZXJhY3RpdmEsIGNvbiB0b2RvcyBsb3MgZGF0b3Mgb2J0ZW5pZG9zIGVuIGxhIHdlYiBkZSBsYSBHVkEsIHBvZGVtb3MgY29uc3VsdGFyIGxvcyBkYXRvcyBkZWwgbXVuaWNpcGlvIGVuIGVsIHF1ZSByZXNpZGltb3MgcGVybyBhZGVtw6FzIHBlcm1pdGUgZXhwb3J0YXIgY3VhbHF1aWVyIGRhdG8gZW4gZWwgZm9ybWF0byBxdWUgYSBjYWRhIHBlcnNvbmEgbGUgaW50ZXJlc2UuDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gVFJVRX0NCg0KbG9hZCgiLi9kYXRvcy9nZW9tZXRyaWFzX2NsYXNlXzEwLlJEYXRhIikNCmRmZ3ZhIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL2NvdmlkLTE5LWNhc29zLWNvbmZpcm1hZG9zLXBvci1wY3ItY2Fzb3MtcGNyLWVuLWxvcy11bHRpbW9zLTE0LWRpYXMteS1wZXJzb25hcy1mYWxsZWNpZGFzLXBvci1tdS5jc3YiKQ0KZGZwb2JsYWNpb25fZ3ZhIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL3BvYmxhY2lvbl9tdW5pX3ZsYy54bHMiKQ0KDQpub21icmVzX29yaWdpbmFsZXMgPC0gbmFtZXMoZGZndmEpDQpub21icmVzX29yaWdpbmFsZXMNCm5hbWVzKGRmZ3ZhKVsxXSA8LSAiQ29kTXVuaWNpcGlvIg0KbmFtZXMoZGZndmEpWzJdIDwtICJNdW5pY2lwaSINCm5hbWVzKGRmZ3ZhKVszXSA8LSAiQ2Fzb3MiDQpuYW1lcyhkZmd2YSlbNF0gPC0gIkluY2lkZW5jaWFfYWN1bXVsYWRhIg0KbmFtZXMoZGZndmEpWzVdIDwtICJDYXNvc191bHQxNGQiDQpuYW1lcyhkZmd2YSlbNl0gPC0gIkluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGQiDQpuYW1lcyhkZmd2YSlbN10gPC0gIkRlZnVuY2lvbnMiDQpuYW1lcyhkZmd2YSlbOF0gPC0gIlRhc2FfZGVmdW5jaW9uIg0KDQpkZmd2YSA8LSBkZmd2YSAlPiUgbXV0YXRlKENvZE11bmljaXBpbyA9IGFzLm51bWVyaWMoQ29kTXVuaWNpcGlvKSkNCm11bmljaXBpb3NfMjAxNyA8LSBtdW5pY2lwaW9zXzIwMTcgJT4lIG11dGF0ZShJTkVDb2RNdW5pID0gYXMubnVtZXJpYyhJTkVDb2RNdW5pKSkNCg0KZGZwdWVibG9zIDwtIGlubmVyX2pvaW4oZGZndmEsIG11bmljaXBpb3NfMjAxNywgYnkgPSBjKCJDb2RNdW5pY2lwaW8iID0gIklORUNvZE11bmkiICkpDQoNCmRmcHVlYmxvc19kZWYgPC0gaW5uZXJfam9pbihkZnB1ZWJsb3MsIGRmcG9ibGFjaW9uX2d2YSwgYnkgPSBjKCJDb2RNdW5pY2lwaW8iID0gIkNvZGlfTXVuaWNpcGkiICkpDQoNCmRmbXVuaWNpcGlvcyA8LSBkZnB1ZWJsb3NfZGVmICU+JSBzZWxlY3QoYENvZE11bmljaXBpb2AsYE5vbWJyZU11bmlgLCBgUG9ibGFjaW9uc2AsYENhc29zYCxgSW5jaWRlbmNpYV9hY3VtdWxhZGFgLGBEZWZ1bmNpb25zYCwgYENhc29zX3VsdDE0ZGAsIGBJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkYCwgYFRhc2FfZGVmdW5jaW9uYCkgJT4lIGFycmFuZ2UoZGVzYyhgSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZGAsIGBUYXNhX2RlZnVuY2lvbmApKQ0KDQpkZm11bmljaXBpb3MgJT4lIERUOjpkYXRhdGFibGUoZXh0ZW5zaW9ucyA9ICdCdXR0b25zJywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zID0gbGlzdChkb20gPSAnQmxmcnRpcCcsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnV0dG9ucyA9IGMoJ2NvcHknLCAnY3N2JywgJ2V4Y2VsJywgJ3BkZicsICdwcmludCcpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VMZW5ndGggPSA1LCBhdXRvV2lkdGggPSBUUlVFICkpICU+JSBmb3JtYXRTdHlsZSAoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkJywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvciA9ICcjRjU5OTg1JywgKQ0KYGBgDQoNCg0KIyMgPEZPTlQgQ09MT1I9IkdyZWVuIj41LjIuIEluY2lkZW5jaWEgYWN1bXVsYWRhIMO6bHRpbW9zIDE0IGTDrWFzLiA8L0ZPTlQ+DQoNCkhlbW9zIGV4cGxpY2FkbyBlbiBlbCAqYXBhcnRhZG8gMyosIHF1w6kgZXMgeSBjb21vIGNhbGN1bGFyLGxhIGluY2lkZW5jaWEgYWN1bXVsYWRhIGEgMTQgZMOtYXMuIFNlIHV0aWxpemEgcGFyYSB0ZW5lciB1biBpbmRpY2Fkb3IgZGUgbGEgZXZvbHVjacOzbiBkZSBsYSBwYW5kZW1pYSBlbiBsb3Mgw7psdGltb3MgMTQgZMOtYXMsIHByb3BvcmNpb25hbmRvIHVuYSBoZXJyYW1pZW50YSDDunRpbCBhIGxvcyByZXNwb25zYWJsZXMgZGUgbGFzIGFkbWluaXN0cmFjaW9uZXMgcMO6YmxpY2FzIHBhcmEgdG9tYXIgZGVjaXNpb25lcyBzb2JyZSBsYXMgcmVzdHJpY2Npb25lcyBhIGFwbGljYXIuDQoNCiMjIyA8Rk9OVCBDT0xPUj0iR3JlZW4iPjUuMi4xLiBTZW3DoWZvcm8gQ292aWQtMTkuIDwvRk9OVD4NCg0KU2UgaGEgY3JlYWRvIGVsICpTZW3DoWZvcm8gQ292aWQqIHBhcmEgZGV0ZXJtaW5hciBxdWUgbWVkaWRhcyBhcGxpY2FyIHNlZ8O6biBlbCByaWVzZ28gZW4gcXVlIHNlIGVuY3VlbnRyZSBjYWRhIG11bmljaXBpby4gRWwgc2Vtw6Fmb3JvIGFuYWxpemEgdmFyaW9zIGluZGljYWRvcmVzOiBpbmNpZGVuY2lhIGFjdW11bGFkYSBhIDE0IGTDrWFzLCBwcmVzacOzbiBVQ0ksIGhvc3BpdGFsaXphY2lvbmVzLCBpbmNpZGVuY2lhIGEgNyBkw61hcy4uLiBldGMuIA0KDQpIZW1vcyBxdWVyaWRvIG1vc3RyYXIgbG9zIDUgbXVuaWNpcGlvcyB2YWxlbmNpYW5vcyAoY29uIG1heW9yIG7Dum1lcm8gZGUgcG9ibGFjacOzbikgcXVlIHNlIGVuY3VlbnRyYW4gZW4gY2FkYSBlc3RhZG8gc2Vnw7puIGluY2lkZW5jaWEgYSAxNCBkw61hcy4NCg0KYGBge3IgZXZhbCA9IFRSVUUsIGVjaG8gPSBGQUxTRX0NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltw6FnZW5lcyIsICJzZW1hZm9yb19jb3ZpZC5wbmciKSAgKQ0KYGBgDQoNCg0KYGBge3IgZXZhbCA9IFRSVUUsIGVjaG8gPSBUUlVFfQ0KDQpkZmd2YSA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jb3ZpZC0xOS1jYXNvcy1jb25maXJtYWRvcy1wb3ItcGNyLWNhc29zLXBjci1lbi1sb3MtdWx0aW1vcy0xNC1kaWFzLXktcGVyc29uYXMtZmFsbGVjaWRhcy1wb3ItbXUuY3N2IikNCmRmcG9ibGFjaW9uX2d2YSA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9wb2JsYWNpb25fbXVuaV92bGMueGxzIikNCmxvYWQoIi4vZGF0b3MvZ2VvbWV0cmlhc19jbGFzZV8xMC5SRGF0YSIpDQoNCm5vbWJyZXNfb3JpZ2luYWxlcyA8LSBuYW1lcyhkZmd2YSkNCm5vbWJyZXNfb3JpZ2luYWxlcw0KbmFtZXMoZGZndmEpWzFdIDwtICJDb2RNdW5pY2lwaW8iDQpuYW1lcyhkZmd2YSlbMl0gPC0gIk11bmljaXBpIg0KbmFtZXMoZGZndmEpWzNdIDwtICJDYXNvcyINCm5hbWVzKGRmZ3ZhKVs0XSA8LSAiSW5jaWRlbmNpYV9hY3VtdWxhZGEiDQpuYW1lcyhkZmd2YSlbNV0gPC0gIkNhc29zX3VsdDE0ZCINCm5hbWVzKGRmZ3ZhKVs2XSA8LSAiSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZCINCm5hbWVzKGRmZ3ZhKVs3XSA8LSAiRGVmdW5jaW9ucyINCm5hbWVzKGRmZ3ZhKVs4XSA8LSAiVGFzYV9kZWZ1bmNpb24iDQoNCmRmZ3ZhIDwtIGRmZ3ZhICU+JSBtdXRhdGUoQ29kTXVuaWNpcGlvID0gYXMubnVtZXJpYyhDb2RNdW5pY2lwaW8pKQ0KbXVuaWNpcGlvc18yMDE3IDwtIG11bmljaXBpb3NfMjAxNyAlPiUgbXV0YXRlKElORUNvZE11bmkgPSBhcy5udW1lcmljKElORUNvZE11bmkpKQ0KZGZwdWVibG9zIDwtIGlubmVyX2pvaW4oZGZndmEsIG11bmljaXBpb3NfMjAxNywgYnkgPSBjKCJDb2RNdW5pY2lwaW8iID0gIklORUNvZE11bmkiICkpDQpkZnB1ZWJsb3NfZGVmIDwtIGlubmVyX2pvaW4oZGZwdWVibG9zLCBkZnBvYmxhY2lvbl9ndmEsIGJ5ID0gYygiQ29kTXVuaWNpcGlvIiA9ICJDb2RpX011bmljaXBpIiApKQ0KZGZtdW5pY2lwaW9zIDwtIGRmcHVlYmxvc19kZWYgJT4lIHNlbGVjdChgQ29kTXVuaWNpcGlvYCxgTm9tYnJlTXVuaWAsIGBQb2JsYWNpb25zYCxgQ2Fzb3NgLGBJbmNpZGVuY2lhX2FjdW11bGFkYWAsYERlZnVuY2lvbnNgLCBgQ2Fzb3NfdWx0MTRkYCwgYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgLCBgVGFzYV9kZWZ1bmNpb25gLCBgSU5FQ29kUHJvdmAsIGBJTkVDb2RDQ0FBYCwgYE5vbWJyZU11bmlgLCBgTm9tYnJlUHJvdmAsIGBnZW9tZXRyeWAgKQ0Kcm0oZGZndmEsZGZwb2JsYWNpb25fZ3ZhLGRmcHVlYmxvcyxkZnB1ZWJsb3NfZGVmLCBtdW5pY2lwaW9zXzIwMTcsIElHTl9ub21lbmNsYV9tdW5pLCByaW9zLCB3b3JsZCkNCg0KZGZtdW5pY2lwaW9zXzI1IDwtIGRmbXVuaWNpcGlvcyAlPiUgZmlsdGVyKGBJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkYCA8PSAyNSklPiUgYXJyYW5nZShkZXNjKGBQb2JsYWNpb25zYCkpJT4lIHNsaWNlKDE6NSklPiUgYXJyYW5nZShkZXNjKGBJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkYCkpIA0KZGZtdW5pY2lwaW9zXzI1X3RhYmxhIDwtIGRmbXVuaWNpcGlvc18yNSAlPiUgc2VsZWN0KGBOb21icmVNdW5pYCxgUG9ibGFjaW9uc2AsIGBJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkYCkgJT4lIGFycmFuZ2UoZGVzYyhgSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZGApKSANCg0KZGZtdW5pY2lwaW9zXzI1X3RhYmxhICU+JQ0KICBrYmwoKSAlPiUNCiAga2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gRiwgaHRtbF9mb250ID0gIkNhbWJyaWEiKSAlPiUNCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiKSkgJT4lIHJvd19zcGVjKHJvdyA9IDA6NSAsYm9sZCA9IFQsYmFja2dyb3VuZCA9ICIjYzRmMWI3IiwgZm9udF9zaXplID0gMTUpJT4lDQogIHNjcm9sbF9ib3god2lkdGggPSAiMTAwJSIsIGhlaWdodCA9ICIzMDBweCIpDQoNCg0KDQpgYGANCg0KPENFTlRFUj48Rk9OVCBDT0xPUj0iR3JleSI+IkluY2lkZW5jaWEgYSAxNCBkw61hcyBtZW5vciBhIDI1IjwvRk9OVD48L0NFTlRFUj4NCg0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IFRSVUV9DQoNCmRmZ3ZhIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL2NvdmlkLTE5LWNhc29zLWNvbmZpcm1hZG9zLXBvci1wY3ItY2Fzb3MtcGNyLWVuLWxvcy11bHRpbW9zLTE0LWRpYXMteS1wZXJzb25hcy1mYWxsZWNpZGFzLXBvci1tdS5jc3YiKQ0KZGZwb2JsYWNpb25fZ3ZhIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL3BvYmxhY2lvbl9tdW5pX3ZsYy54bHMiKQ0KbG9hZCgiLi9kYXRvcy9nZW9tZXRyaWFzX2NsYXNlXzEwLlJEYXRhIikNCg0Kbm9tYnJlc19vcmlnaW5hbGVzIDwtIG5hbWVzKGRmZ3ZhKQ0Kbm9tYnJlc19vcmlnaW5hbGVzDQpuYW1lcyhkZmd2YSlbMV0gPC0gIkNvZE11bmljaXBpbyINCm5hbWVzKGRmZ3ZhKVsyXSA8LSAiTXVuaWNpcGkiDQpuYW1lcyhkZmd2YSlbM10gPC0gIkNhc29zIg0KbmFtZXMoZGZndmEpWzRdIDwtICJJbmNpZGVuY2lhX2FjdW11bGFkYSINCm5hbWVzKGRmZ3ZhKVs1XSA8LSAiQ2Fzb3NfdWx0MTRkIg0KbmFtZXMoZGZndmEpWzZdIDwtICJJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkIg0KbmFtZXMoZGZndmEpWzddIDwtICJEZWZ1bmNpb25zIg0KbmFtZXMoZGZndmEpWzhdIDwtICJUYXNhX2RlZnVuY2lvbiINCg0KZGZndmEgPC0gZGZndmEgJT4lIG11dGF0ZShDb2RNdW5pY2lwaW8gPSBhcy5udW1lcmljKENvZE11bmljaXBpbykpDQptdW5pY2lwaW9zXzIwMTcgPC0gbXVuaWNpcGlvc18yMDE3ICU+JSBtdXRhdGUoSU5FQ29kTXVuaSA9IGFzLm51bWVyaWMoSU5FQ29kTXVuaSkpDQpkZnB1ZWJsb3MgPC0gaW5uZXJfam9pbihkZmd2YSwgbXVuaWNpcGlvc18yMDE3LCBieSA9IGMoIkNvZE11bmljaXBpbyIgPSAiSU5FQ29kTXVuaSIgKSkNCmRmcHVlYmxvc19kZWYgPC0gaW5uZXJfam9pbihkZnB1ZWJsb3MsIGRmcG9ibGFjaW9uX2d2YSwgYnkgPSBjKCJDb2RNdW5pY2lwaW8iID0gIkNvZGlfTXVuaWNpcGkiICkpDQpkZm11bmljaXBpb3MgPC0gZGZwdWVibG9zX2RlZiAlPiUgc2VsZWN0KGBDb2RNdW5pY2lwaW9gLGBOb21icmVNdW5pYCwgYFBvYmxhY2lvbnNgLGBDYXNvc2AsYEluY2lkZW5jaWFfYWN1bXVsYWRhYCxgRGVmdW5jaW9uc2AsIGBDYXNvc191bHQxNGRgLCBgSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZGAsIGBUYXNhX2RlZnVuY2lvbmAsIGBJTkVDb2RQcm92YCwgYElORUNvZENDQUFgLCBgTm9tYnJlTXVuaWAsIGBOb21icmVQcm92YCwgYGdlb21ldHJ5YCApDQpybShkZmd2YSxkZnBvYmxhY2lvbl9ndmEsZGZwdWVibG9zLGRmcHVlYmxvc19kZWYsIG11bmljaXBpb3NfMjAxNywgSUdOX25vbWVuY2xhX211bmksIHJpb3MsIHdvcmxkKQ0KDQpkZm11bmljaXBpb3MyNV81MCA8LSBkZm11bmljaXBpb3MgJT4lIGZpbHRlcihgSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZGAgJWluJSAoMjU6NTApKSU+JSBhcnJhbmdlKGRlc2MoYFBvYmxhY2lvbnNgKSklPiUgc2xpY2UoMTo1KSU+JSBhcnJhbmdlKGRlc2MoYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgKSkgDQpkZm11bmljaXBpb3NfMjVfNTBfdGFibGEgPC0gZGZtdW5pY2lwaW9zMjVfNTAgJT4lIHNlbGVjdChgTm9tYnJlTXVuaWAsYFBvYmxhY2lvbnNgLCBgSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZGApICU+JSBhcnJhbmdlKGRlc2MoYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgKSkgDQoNCmRmbXVuaWNpcGlvc18yNV81MF90YWJsYSAlPiUNCiAga2JsKCkgJT4lIA0KICBrYWJsZV9jbGFzc2ljKGZ1bGxfd2lkdGggPSBGLCBodG1sX2ZvbnQgPSAiQ2FtYnJpYSIpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIpKSAlPiUgcm93X3NwZWMocm93ID0gMDo1ICxib2xkID0gVCwgYmFja2dyb3VuZCA9ICIjZjNlMmFiIiwgZm9udF9zaXplID0gMTUpJT4lDQogIHNjcm9sbF9ib3god2lkdGggPSAiMTAwJSIsIGhlaWdodCA9ICIzMDBweCIpDQoNCmBgYA0KDQo8Q0VOVEVSPjxGT05UIENPTE9SPSJHcmV5Ij4iSW5jaWRlbmNpYSBhIDE0IGTDrWFzIGVudHJlIDI1IHkgNTAiPC9GT05UPjwvQ0VOVEVSPg0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IFRSVUV9DQoNCmRmZ3ZhIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL2NvdmlkLTE5LWNhc29zLWNvbmZpcm1hZG9zLXBvci1wY3ItY2Fzb3MtcGNyLWVuLWxvcy11bHRpbW9zLTE0LWRpYXMteS1wZXJzb25hcy1mYWxsZWNpZGFzLXBvci1tdS5jc3YiKQ0KZGZwb2JsYWNpb25fZ3ZhIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL3BvYmxhY2lvbl9tdW5pX3ZsYy54bHMiKQ0KbG9hZCgiLi9kYXRvcy9nZW9tZXRyaWFzX2NsYXNlXzEwLlJEYXRhIikNCg0Kbm9tYnJlc19vcmlnaW5hbGVzIDwtIG5hbWVzKGRmZ3ZhKQ0Kbm9tYnJlc19vcmlnaW5hbGVzDQpuYW1lcyhkZmd2YSlbMV0gPC0gIkNvZE11bmljaXBpbyINCm5hbWVzKGRmZ3ZhKVsyXSA8LSAiTXVuaWNpcGkiDQpuYW1lcyhkZmd2YSlbM10gPC0gIkNhc29zIg0KbmFtZXMoZGZndmEpWzRdIDwtICJJbmNpZGVuY2lhX2FjdW11bGFkYSINCm5hbWVzKGRmZ3ZhKVs1XSA8LSAiQ2Fzb3NfdWx0MTRkIg0KbmFtZXMoZGZndmEpWzZdIDwtICJJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkIg0KbmFtZXMoZGZndmEpWzddIDwtICJEZWZ1bmNpb25zIg0KbmFtZXMoZGZndmEpWzhdIDwtICJUYXNhX2RlZnVuY2lvbiINCg0KZGZndmEgPC0gZGZndmEgJT4lIG11dGF0ZShDb2RNdW5pY2lwaW8gPSBhcy5udW1lcmljKENvZE11bmljaXBpbykpDQptdW5pY2lwaW9zXzIwMTcgPC0gbXVuaWNpcGlvc18yMDE3ICU+JSBtdXRhdGUoSU5FQ29kTXVuaSA9IGFzLm51bWVyaWMoSU5FQ29kTXVuaSkpDQpkZnB1ZWJsb3MgPC0gaW5uZXJfam9pbihkZmd2YSwgbXVuaWNpcGlvc18yMDE3LCBieSA9IGMoIkNvZE11bmljaXBpbyIgPSAiSU5FQ29kTXVuaSIgKSkNCmRmcHVlYmxvc19kZWYgPC0gaW5uZXJfam9pbihkZnB1ZWJsb3MsIGRmcG9ibGFjaW9uX2d2YSwgYnkgPSBjKCJDb2RNdW5pY2lwaW8iID0gIkNvZGlfTXVuaWNpcGkiICkpDQpkZm11bmljaXBpb3MgPC0gZGZwdWVibG9zX2RlZiAlPiUgc2VsZWN0KGBDb2RNdW5pY2lwaW9gLGBOb21icmVNdW5pYCwgYFBvYmxhY2lvbnNgLGBDYXNvc2AsYEluY2lkZW5jaWFfYWN1bXVsYWRhYCxgRGVmdW5jaW9uc2AsIGBDYXNvc191bHQxNGRgLCBgSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZGAsIGBUYXNhX2RlZnVuY2lvbmAsIGBJTkVDb2RQcm92YCwgYElORUNvZENDQUFgLCBgTm9tYnJlTXVuaWAsIGBOb21icmVQcm92YCwgYGdlb21ldHJ5YCApDQpybShkZmd2YSxkZnBvYmxhY2lvbl9ndmEsZGZwdWVibG9zLGRmcHVlYmxvc19kZWYsIG11bmljaXBpb3NfMjAxNywgSUdOX25vbWVuY2xhX211bmksIHJpb3MsIHdvcmxkKQ0KDQpkZm11bmljaXBpb3M1MF8xNTAgPC0gZGZtdW5pY2lwaW9zICU+JSBmaWx0ZXIoYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgICVpbiUgKDUwOjE1MCkpJT4lIGFycmFuZ2UoZGVzYyhgUG9ibGFjaW9uc2ApKSU+JSBzbGljZSgxOjUpICU+JSBhcnJhbmdlKGRlc2MoYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgKSkgDQpkZm11bmljaXBpb3NfNTBfMTUwX3RhYmxhIDwtIGRmbXVuaWNpcGlvczUwXzE1MCAlPiUgc2VsZWN0KGBOb21icmVNdW5pYCxgUG9ibGFjaW9uc2AsIGBJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkYCkgJT4lIGFycmFuZ2UoZGVzYyhgSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZGApKSANCg0KZGZtdW5pY2lwaW9zXzUwXzE1MF90YWJsYSAlPiUNCiAga2JsKCkgJT4lDQogIGthYmxlX2NsYXNzaWMoZnVsbF93aWR0aCA9IEYsIGh0bWxfZm9udCA9ICJDYW1icmlhIikgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIikpICU+JSByb3dfc3BlYyhyb3cgPSAwOjUgLCBib2xkID0gVCwgYmFja2dyb3VuZCA9ICIjZjNjMzY0IiwgZm9udF9zaXplID0gMTUpJT4lDQogIHNjcm9sbF9ib3god2lkdGggPSAiMTAwJSIsIGhlaWdodCA9ICIzMDBweCIpDQpgYGANCg0KPENFTlRFUj48Rk9OVCBDT0xPUj0iR3JleSI+IkluY2lkZW5jaWEgYSAxNCBkw61hcyBlbnRyZSA1MCB5IDE1MCI8L0ZPTlQ+PC9DRU5URVI+DQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gVFJVRX0NCg0KZGZndmEgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvY292aWQtMTktY2Fzb3MtY29uZmlybWFkb3MtcG9yLXBjci1jYXNvcy1wY3ItZW4tbG9zLXVsdGltb3MtMTQtZGlhcy15LXBlcnNvbmFzLWZhbGxlY2lkYXMtcG9yLW11LmNzdiIpDQpkZnBvYmxhY2lvbl9ndmEgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvcG9ibGFjaW9uX211bmlfdmxjLnhscyIpDQpsb2FkKCIuL2RhdG9zL2dlb21ldHJpYXNfY2xhc2VfMTAuUkRhdGEiKQ0KDQpub21icmVzX29yaWdpbmFsZXMgPC0gbmFtZXMoZGZndmEpDQpub21icmVzX29yaWdpbmFsZXMNCm5hbWVzKGRmZ3ZhKVsxXSA8LSAiQ29kTXVuaWNpcGlvIg0KbmFtZXMoZGZndmEpWzJdIDwtICJNdW5pY2lwaSINCm5hbWVzKGRmZ3ZhKVszXSA8LSAiQ2Fzb3MiDQpuYW1lcyhkZmd2YSlbNF0gPC0gIkluY2lkZW5jaWFfYWN1bXVsYWRhIg0KbmFtZXMoZGZndmEpWzVdIDwtICJDYXNvc191bHQxNGQiDQpuYW1lcyhkZmd2YSlbNl0gPC0gIkluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGQiDQpuYW1lcyhkZmd2YSlbN10gPC0gIkRlZnVuY2lvbnMiDQpuYW1lcyhkZmd2YSlbOF0gPC0gIlRhc2FfZGVmdW5jaW9uIg0KDQpkZmd2YSA8LSBkZmd2YSAlPiUgbXV0YXRlKENvZE11bmljaXBpbyA9IGFzLm51bWVyaWMoQ29kTXVuaWNpcGlvKSkNCm11bmljaXBpb3NfMjAxNyA8LSBtdW5pY2lwaW9zXzIwMTcgJT4lIG11dGF0ZShJTkVDb2RNdW5pID0gYXMubnVtZXJpYyhJTkVDb2RNdW5pKSkNCmRmcHVlYmxvcyA8LSBpbm5lcl9qb2luKGRmZ3ZhLCBtdW5pY2lwaW9zXzIwMTcsIGJ5ID0gYygiQ29kTXVuaWNpcGlvIiA9ICJJTkVDb2RNdW5pIiApKQ0KZGZwdWVibG9zX2RlZiA8LSBpbm5lcl9qb2luKGRmcHVlYmxvcywgZGZwb2JsYWNpb25fZ3ZhLCBieSA9IGMoIkNvZE11bmljaXBpbyIgPSAiQ29kaV9NdW5pY2lwaSIgKSkNCmRmbXVuaWNpcGlvcyA8LSBkZnB1ZWJsb3NfZGVmICU+JSBzZWxlY3QoYENvZE11bmljaXBpb2AsYE5vbWJyZU11bmlgLCBgUG9ibGFjaW9uc2AsYENhc29zYCxgSW5jaWRlbmNpYV9hY3VtdWxhZGFgLGBEZWZ1bmNpb25zYCwgYENhc29zX3VsdDE0ZGAsIGBJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkYCwgYFRhc2FfZGVmdW5jaW9uYCwgYElORUNvZFByb3ZgLCBgSU5FQ29kQ0NBQWAsIGBOb21icmVNdW5pYCwgYE5vbWJyZVByb3ZgLCBgZ2VvbWV0cnlgICkNCnJtKGRmZ3ZhLGRmcG9ibGFjaW9uX2d2YSxkZnB1ZWJsb3MsZGZwdWVibG9zX2RlZiwgbXVuaWNpcGlvc18yMDE3LCBJR05fbm9tZW5jbGFfbXVuaSwgcmlvcywgd29ybGQpDQoNCmRmbXVuaWNpcGlvczE1MF8yNTAgPC0gZGZtdW5pY2lwaW9zICU+JSBmaWx0ZXIoYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgICVpbiUgKDE1MDoyNTApKSU+JSBhcnJhbmdlKGRlc2MoYFBvYmxhY2lvbnNgKSkgJT4lIHNsaWNlKDE6NSkgJT4lIGFycmFuZ2UoZGVzYyhgSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZGApKSANCmRmbXVuaWNpcGlvc18xNTBfMjUwX3RhYmxhIDwtIGRmbXVuaWNpcGlvczE1MF8yNTAgJT4lIHNlbGVjdChgTm9tYnJlTXVuaWAsYFBvYmxhY2lvbnNgLCBgSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZGApICU+JSBhcnJhbmdlKGRlc2MoYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgKSkgDQoNCmRmbXVuaWNpcGlvc18xNTBfMjUwX3RhYmxhICU+JQ0KICBrYmwoKSAlPiUNCiAga2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gRiwgaHRtbF9mb250ID0gIkNhbWJyaWEiKSAlPiUNCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiKSkgJT4lIHJvd19zcGVjKHJvdyA9IDA6NSAsYm9sZCA9IFQsYmFja2dyb3VuZCA9ICIjZTM1YjQzIiwgZm9udF9zaXplID0gMTUpJT4lDQogIHNjcm9sbF9ib3god2lkdGggPSAiMTAwJSIsIGhlaWdodCA9ICIzMDBweCIpDQoNCmBgYA0KDQo8Q0VOVEVSPjxGT05UIENPTE9SPSJHcmV5Ij4iSW5jaWRlbmNpYSBhIDE0IGTDrWFzIGVudHJlIDE1MCB5IDI1MCI8L0ZPTlQ+PC9DRU5URVI+DQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gVFJVRX0NCg0KZGZndmEgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvY292aWQtMTktY2Fzb3MtY29uZmlybWFkb3MtcG9yLXBjci1jYXNvcy1wY3ItZW4tbG9zLXVsdGltb3MtMTQtZGlhcy15LXBlcnNvbmFzLWZhbGxlY2lkYXMtcG9yLW11LmNzdiIpDQpkZnBvYmxhY2lvbl9ndmEgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvcG9ibGFjaW9uX211bmlfdmxjLnhscyIpDQpsb2FkKCIuL2RhdG9zL2dlb21ldHJpYXNfY2xhc2VfMTAuUkRhdGEiKQ0KDQpub21icmVzX29yaWdpbmFsZXMgPC0gbmFtZXMoZGZndmEpDQpub21icmVzX29yaWdpbmFsZXMNCm5hbWVzKGRmZ3ZhKVsxXSA8LSAiQ29kTXVuaWNpcGlvIg0KbmFtZXMoZGZndmEpWzJdIDwtICJNdW5pY2lwaSINCm5hbWVzKGRmZ3ZhKVszXSA8LSAiQ2Fzb3MiDQpuYW1lcyhkZmd2YSlbNF0gPC0gIkluY2lkZW5jaWFfYWN1bXVsYWRhIg0KbmFtZXMoZGZndmEpWzVdIDwtICJDYXNvc191bHQxNGQiDQpuYW1lcyhkZmd2YSlbNl0gPC0gIkluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGQiDQpuYW1lcyhkZmd2YSlbN10gPC0gIkRlZnVuY2lvbnMiDQpuYW1lcyhkZmd2YSlbOF0gPC0gIlRhc2FfZGVmdW5jaW9uIg0KDQpkZmd2YSA8LSBkZmd2YSAlPiUgbXV0YXRlKENvZE11bmljaXBpbyA9IGFzLm51bWVyaWMoQ29kTXVuaWNpcGlvKSkNCm11bmljaXBpb3NfMjAxNyA8LSBtdW5pY2lwaW9zXzIwMTcgJT4lIG11dGF0ZShJTkVDb2RNdW5pID0gYXMubnVtZXJpYyhJTkVDb2RNdW5pKSkNCmRmcHVlYmxvcyA8LSBpbm5lcl9qb2luKGRmZ3ZhLCBtdW5pY2lwaW9zXzIwMTcsIGJ5ID0gYygiQ29kTXVuaWNpcGlvIiA9ICJJTkVDb2RNdW5pIiApKQ0KZGZwdWVibG9zX2RlZiA8LSBpbm5lcl9qb2luKGRmcHVlYmxvcywgZGZwb2JsYWNpb25fZ3ZhLCBieSA9IGMoIkNvZE11bmljaXBpbyIgPSAiQ29kaV9NdW5pY2lwaSIgKSkNCmRmbXVuaWNpcGlvcyA8LSBkZnB1ZWJsb3NfZGVmICU+JSBzZWxlY3QoYENvZE11bmljaXBpb2AsYE5vbWJyZU11bmlgLCBgUG9ibGFjaW9uc2AsYENhc29zYCxgSW5jaWRlbmNpYV9hY3VtdWxhZGFgLGBEZWZ1bmNpb25zYCwgYENhc29zX3VsdDE0ZGAsIGBJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkYCwgYFRhc2FfZGVmdW5jaW9uYCwgYElORUNvZFByb3ZgLCBgSU5FQ29kQ0NBQWAsIGBOb21icmVNdW5pYCwgYE5vbWJyZVByb3ZgLCBgZ2VvbWV0cnlgICkNCnJtKGRmZ3ZhLGRmcG9ibGFjaW9uX2d2YSxkZnB1ZWJsb3MsZGZwdWVibG9zX2RlZiwgbXVuaWNpcGlvc18yMDE3LCBJR05fbm9tZW5jbGFfbXVuaSwgcmlvcywgd29ybGQpDQoNCmRmbXVuaWNpcGlvczI1MCA8LSBkZm11bmljaXBpb3MgJT4lIGZpbHRlcihgSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZGAgPj0gMjUwKSU+JSBhcnJhbmdlKGRlc2MoYFBvYmxhY2lvbnNgKSkgJT4lIHNsaWNlKDE6NSkgJT4lICBhcnJhbmdlKGRlc2MoYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgKSkgDQpkZm11bmljaXBpb3NfMjUwX3RhYmxhIDwtIGRmbXVuaWNpcGlvczI1MCAlPiUgc2VsZWN0KGBOb21icmVNdW5pYCxgUG9ibGFjaW9uc2AsIGBJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkYCkgJT4lIGFycmFuZ2UoZGVzYyhgSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZGApKSANCg0KZGZtdW5pY2lwaW9zXzI1MF90YWJsYSAlPiUNCiAga2JsKCkgJT4lDQogIGthYmxlX2NsYXNzaWMoZnVsbF93aWR0aCA9IEYsIGh0bWxfZm9udCA9ICJDYW1icmlhIikgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIikpICU+JSByb3dfc3BlYyhyb3cgPSAwOjUgLGJvbGQgPSBULGJhY2tncm91bmQgPSAiI2EzMDQyYiIsIGZvbnRfc2l6ZSA9IDE1KSU+JQ0KICBzY3JvbGxfYm94KHdpZHRoID0gIjEwMCUiLCBoZWlnaHQgPSAiMzAwcHgiKQ0KYGBgDQoNCjxDRU5URVI+PEZPTlQgQ09MT1I9IkdyZXkiPiJJbmNpZGVuY2lhIGEgMTQgZMOtYXMgbWF5b3IgZGUgMjUwIjwvRk9OVD48L0NFTlRFUj4NCg0KIyMjIDxGT05UIENPTE9SPSJHcmVlbiI+NS4yLjEuIENvbXBhcmFjacOzbiBDaXVkYWRlcyAmIFB1ZWJsb3MuIDwvRk9OVD4NCg0KRW4gZXN0ZSBncsOhZmljbyBoZW1vcyBxdWVyaWRvIGhhY2VyIGNvbnN0YXIgbGEgZGlmZXJlbmNpYSBxdWUgZXhpc3RlIGVudHJlIHB1ZWJsb3MgKG1lbm9zIGRlIDEwLjAwMCBoYWJpdGFudGVzKSB5IGNpdWRhZGVzIChtw6FzIGRlIDEwLjAwMCBoYWJpdGFudGVzKSByZXNwZWN0byBhIGxhIHZhcmlhYmxlIGFuYWxpemFkYS4gDQoNCg0KYGBge3IgZXZhbCA9IFRSVUUsIGVjaG8gPSBUUlVFfQ0KDQpkZmd2YSA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jb3ZpZC0xOS1jYXNvcy1jb25maXJtYWRvcy1wb3ItcGNyLWNhc29zLXBjci1lbi1sb3MtdWx0aW1vcy0xNC1kaWFzLXktcGVyc29uYXMtZmFsbGVjaWRhcy1wb3ItbXUuY3N2IikNCmRmcG9ibGFjaW9uX2d2YSA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9wb2JsYWNpb25fbXVuaV92bGMueGxzIikNCmxvYWQoIi4vZGF0b3MvZ2VvbWV0cmlhc19jbGFzZV8xMC5SRGF0YSIpDQoNCm5vbWJyZXNfb3JpZ2luYWxlcyA8LSBuYW1lcyhkZmd2YSkNCm5vbWJyZXNfb3JpZ2luYWxlcw0KbmFtZXMoZGZndmEpWzFdIDwtICJDb2RNdW5pY2lwaW8iDQpuYW1lcyhkZmd2YSlbMl0gPC0gIk11bmljaXBpIg0KbmFtZXMoZGZndmEpWzNdIDwtICJDYXNvcyINCm5hbWVzKGRmZ3ZhKVs0XSA8LSAiSW5jaWRlbmNpYV9hY3VtdWxhZGEiDQpuYW1lcyhkZmd2YSlbNV0gPC0gIkNhc29zX3VsdDE0ZCINCm5hbWVzKGRmZ3ZhKVs2XSA8LSAiSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZCINCm5hbWVzKGRmZ3ZhKVs3XSA8LSAiRGVmdW5jaW9ucyINCm5hbWVzKGRmZ3ZhKVs4XSA8LSAiVGFzYV9kZWZ1bmNpb24iDQoNCmRmZ3ZhIDwtIGRmZ3ZhICU+JSBtdXRhdGUoQ29kTXVuaWNpcGlvID0gYXMubnVtZXJpYyhDb2RNdW5pY2lwaW8pKQ0KbXVuaWNpcGlvc18yMDE3IDwtIG11bmljaXBpb3NfMjAxNyAlPiUgbXV0YXRlKElORUNvZE11bmkgPSBhcy5udW1lcmljKElORUNvZE11bmkpKQ0KZGZwdWVibG9zIDwtIGlubmVyX2pvaW4oZGZndmEsIG11bmljaXBpb3NfMjAxNywgYnkgPSBjKCJDb2RNdW5pY2lwaW8iID0gIklORUNvZE11bmkiICkpDQpkZnB1ZWJsb3NfZGVmIDwtIGlubmVyX2pvaW4oZGZwdWVibG9zLCBkZnBvYmxhY2lvbl9ndmEsIGJ5ID0gYygiQ29kTXVuaWNpcGlvIiA9ICJDb2RpX011bmljaXBpIiApKQ0KZGZtdW5pY2lwaW9zIDwtIGRmcHVlYmxvc19kZWYgJT4lIHNlbGVjdChgQ29kTXVuaWNpcGlvYCxgTm9tYnJlTXVuaWAsIGBQb2JsYWNpb25zYCxgQ2Fzb3NgLGBJbmNpZGVuY2lhX2FjdW11bGFkYWAsYERlZnVuY2lvbnNgLCBgQ2Fzb3NfdWx0MTRkYCwgYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgLCBgVGFzYV9kZWZ1bmNpb25gLCBgSU5FQ29kUHJvdmAsIGBJTkVDb2RDQ0FBYCwgYE5vbWJyZU11bmlgLCBgTm9tYnJlUHJvdmAsIGBnZW9tZXRyeWAgKQ0Kcm0oZGZndmEsZGZwb2JsYWNpb25fZ3ZhLGRmcHVlYmxvcyxkZnB1ZWJsb3NfZGVmLCBtdW5pY2lwaW9zXzIwMTcsIElHTl9ub21lbmNsYV9tdW5pLCByaW9zLCB3b3JsZCkNCg0KZGZtdW5pY2lwaW9zMjUwIDwtIGRmbXVuaWNpcGlvcyAlPiUgZmlsdGVyKGBJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkYCA+PSAyNTApJT4lIGFycmFuZ2UoZGVzYyhgUG9ibGFjaW9uc2ApKSAlPiUgc2xpY2UoMTo1KSAlPiUgIGFycmFuZ2UoZGVzYyhgSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZGApKSANCmRmbXVuaWNpcGlvc18yNTBfdGFibGEgPC0gZGZtdW5pY2lwaW9zMjUwICU+JSBzZWxlY3QoYE5vbWJyZU11bmlgLGBQb2JsYWNpb25zYCwgYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgKSAlPiUgYXJyYW5nZShkZXNjKGBJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkYCkpDQoNCmRmY2l1ZGFkZXMgPC0gZGZtdW5pY2lwaW9zICU+JSBmaWx0ZXIoYFBvYmxhY2lvbnNgID49IDEwMDAwKQ0KZGZwdWVibG9zIDwtIGRmbXVuaWNpcGlvcyAlPiUgZmlsdGVyKGBQb2JsYWNpb25zYCA8PSAxMDAwMCkNCg0KZGZjaXVkYWRlc18yNSA8LSBkZmNpdWRhZGVzICU+JSBmaWx0ZXIoYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgIDw9IDI1KSU+JSBhcnJhbmdlKGRlc2MoYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgKSkgIyBObyBoYXkgbmluZ3VuYSBjaXVkYWQNCmRmY2l1ZGFkZXMyNV81MCA8LSBkZmNpdWRhZGVzICU+JSBmaWx0ZXIgKGBJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkYCAlaW4lICgyNTo1MCkpJT4lIGFycmFuZ2UoZGVzYyhgSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZGApKQ0KZGZjaXVkYWRlczUwXzE1MCA8LSBkZmNpdWRhZGVzICU+JSBmaWx0ZXIgKGBJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkYCAlaW4lICg1MDoxNTApKSU+JSBhcnJhbmdlKGRlc2MoYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgKSkNCmRmY2l1ZGFkZXMxNTBfMjUwIDwtIGRmY2l1ZGFkZXMgJT4lIGZpbHRlciAoYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgICVpbiUgKDE1MDoyNTApKSAlPiUgYXJyYW5nZShkZXNjKGBJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkYCkpDQpkZmNpdWRhZGVzXzI1MCA8LSBkZmNpdWRhZGVzICU+JSBmaWx0ZXIoYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgID49IDI1MCklPiUgYXJyYW5nZShkZXNjKGBJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkYCkpDQoNCmRmcHVlYmxvc18yNSA8LSBkZnB1ZWJsb3MgJT4lIGZpbHRlcihgSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZGAgPD0gMjUpICU+JSBhcnJhbmdlKGRlc2MoYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgKSkNCmRmcHVlYmxvczI1XzUwIDwtIGRmcHVlYmxvcyAlPiUgZmlsdGVyIChgSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZGAgJWluJSAoMjU6NTApKSAlPiUgYXJyYW5nZShkZXNjKGBJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkYCkpDQpkZnB1ZWJsb3M1MF8xNTAgPC0gZGZwdWVibG9zICU+JSBmaWx0ZXIgKGBJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkYCAlaW4lICg1MDoxNTApKSAlPiUgYXJyYW5nZShkZXNjKGBJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkYCkpDQpkZnB1ZWJsb3MxNTBfMjUwIDwtIGRmcHVlYmxvcyAlPiUgZmlsdGVyIChgSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZGAgJWluJSAoMTUwOjI1MCkpICU+JSBhcnJhbmdlKGRlc2MoYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgKSkNCmRmcHVlYmxvc18yNTAgPC0gZGZwdWVibG9zICU+JSBmaWx0ZXIoYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgID49IDI1MCkgJT4lIGFycmFuZ2UoZGVzYyhgUG9ibGFjaW9uc2ApKQ0KDQp0YWJsYV9yZXN1bWVuIDwtIGRhdGEuZnJhbWUoDQogIE7Dum1lcm9fSW5jaWRlbmNpYXMgID0gYygiSW5jaWRlbmNpYV9tZW5vc18yNSIsICJJbmNpZGVuY2lhX2VudHJlXzI1XzUwIiwiSW5jaWRlbmNpYV9lbnRyZV81MF8xNTAiLCJJbmNpZGVuY2lhX2VudHJlXzE1MF8yNTAiLCJJbmNpZGVuY2lhX23DoXNfMjUwIiApLCAgDQogIFB1ZWJsb3MgPSBjKDIxMSwgMTcsIDcxLCA1NCwgOTEpLCANCiAgQ2l1ZGFkZXMgPSBjKDAsIDIsIDMyLCAzMCwgMzcpICApDQoNCnAgPC0gZ2dwbG90ICh0YWJsYV9yZXN1bWVuLCBhZXMoTsO6bWVyb19JbmNpZGVuY2lhcywgUHVlYmxvcykpKw0KZ2VvbV9jb2woZmlsbD0gInN0ZWVsYmx1ZSIpICsgY29vcmRfZmxpcCgpICsgDQogIGxhYnMgKHRpdGxlID0gIkluY2lkZW5jaWEgw7psdC4xNGQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9ICJHcnVwb3NfSW5jaWRlbmNpYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gIk7Dum1lcm9fUHVlYmxvcyIpIA0KDQoNCmcgIDwtIGdncGxvdCAodGFibGFfcmVzdW1lbiwgYWVzKE7Dum1lcm9fSW5jaWRlbmNpYXMsIENpdWRhZGVzKSkgKyANCiAgZ2VvbV9jb2woZmlsbD0gInRvbWF0byIpICsgY29vcmRfZmxpcCgpKw0KICBsYWJzICh0aXRsZSA9ICJJbmNpZGVuY2lhIMO6bHQuMTRkIiwNCiAgICAgICAgeSA9ICJHcnVwb3NfSW5jaWRlbmNpYSIsDQogICAgICAgIHggPSAiTsO6bWVyb19DaXVkYWRlcyIpIA0KDQpwK2cNCg0KDQpgYGANCg0KTWllbnRyYXMgcXVlIGxhIG1heW9yw61hIGRlIGxvcyBwdWVibG9zIHNlIHNpdMO6YW4gZW4gdW4gcmllc2dvIGJham8gKG1lbm9yIGEgMjUpLCBsYSBtYXlvcsOtYSBkZSBsYXMgY2l1ZGFkZXMgc2Ugc2l0dcOhbiBlbiB1biByaWVzZ28gZXh0cmVtbyAobcOhcyBkZSAyNTApLiAqKkFkZW3DoXMgcG9kZW1vcyBvYnNlcnZhciBxdWUgbm8gaGF5IG5pIHVuYSBzb2xhIGNpdWRhZCB2YWxlbmNpYW5hIHF1ZSBubyB0aWVuZSB1biByaWVzZ28gYmFqbyAobWVub3IgYSAyNSkuKioNCg0KIyMgPEZPTlQgQ09MT1I9IkdyZWVuIj41LjMuIEluY2lkZW5jaWEgYWN1bXVsYWRhLiA8L0ZPTlQ+DQoNCkxhIGluY2lkZW5jaWEgYWN1bXVsYWRhIG5vcyBzaXJ2ZSBwYXJhIGNvbXBhcmFyIGxhIGluY2lkZW5jaWEgZGUgbGEgQ292aWQtMTkgZW4gbG9zIG11bmljaXBpb3MgdmFsZW5jaWFub3MgKipwZXJvIGRlc2RlIGVsIGluaWNpbyBkZSBsYSBwYW5kZW1pYSoqLg0KDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gVFJVRX0NCg0KI2J1c2NhbW9zIGxvcyA1IG11bmljaXBpb3MgcXVlIHRpZW5lbiB1biB0YXNhIGRlIGluY2lkZW5jaWEgYWN1bXVsYWRhIG1heW9yLiBIYWNlbW9zIHRhYmxhLg0KDQpkZmd2YSA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jb3ZpZC0xOS1jYXNvcy1jb25maXJtYWRvcy1wb3ItcGNyLWNhc29zLXBjci1lbi1sb3MtdWx0aW1vcy0xNC1kaWFzLXktcGVyc29uYXMtZmFsbGVjaWRhcy1wb3ItbXUuY3N2IikNCmRmcG9ibGFjaW9uX2d2YSA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9wb2JsYWNpb25fbXVuaV92bGMueGxzIikNCmxvYWQoIi4vZGF0b3MvZ2VvbWV0cmlhc19jbGFzZV8xMC5SRGF0YSIpDQoNCm5vbWJyZXNfb3JpZ2luYWxlcyA8LSBuYW1lcyhkZmd2YSkNCm5vbWJyZXNfb3JpZ2luYWxlcw0KbmFtZXMoZGZndmEpWzFdIDwtICJDb2RNdW5pY2lwaW8iDQpuYW1lcyhkZmd2YSlbMl0gPC0gIk11bmljaXBpIg0KbmFtZXMoZGZndmEpWzNdIDwtICJDYXNvcyINCm5hbWVzKGRmZ3ZhKVs0XSA8LSAiSW5jaWRlbmNpYV9hY3VtdWxhZGEiDQpuYW1lcyhkZmd2YSlbNV0gPC0gIkNhc29zX3VsdDE0ZCINCm5hbWVzKGRmZ3ZhKVs2XSA8LSAiSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZCINCm5hbWVzKGRmZ3ZhKVs3XSA8LSAiRGVmdW5jaW9ucyINCm5hbWVzKGRmZ3ZhKVs4XSA8LSAiVGFzYV9kZWZ1bmNpb24iDQoNCmRmZ3ZhIDwtIGRmZ3ZhICU+JSBtdXRhdGUoQ29kTXVuaWNpcGlvID0gYXMubnVtZXJpYyhDb2RNdW5pY2lwaW8pKQ0KbXVuaWNpcGlvc18yMDE3IDwtIG11bmljaXBpb3NfMjAxNyAlPiUgbXV0YXRlKElORUNvZE11bmkgPSBhcy5udW1lcmljKElORUNvZE11bmkpKQ0KZGZwdWVibG9zIDwtIGlubmVyX2pvaW4oZGZndmEsIG11bmljaXBpb3NfMjAxNywgYnkgPSBjKCJDb2RNdW5pY2lwaW8iID0gIklORUNvZE11bmkiICkpDQpkZnB1ZWJsb3NfZGVmIDwtIGlubmVyX2pvaW4oZGZwdWVibG9zLCBkZnBvYmxhY2lvbl9ndmEsIGJ5ID0gYygiQ29kTXVuaWNpcGlvIiA9ICJDb2RpX011bmljaXBpIiApKQ0KZGZtdW5pY2lwaW9zIDwtIGRmcHVlYmxvc19kZWYgJT4lIHNlbGVjdChgQ29kTXVuaWNpcGlvYCxgTm9tYnJlTXVuaWAsIGBQb2JsYWNpb25zYCxgQ2Fzb3NgLGBJbmNpZGVuY2lhX2FjdW11bGFkYWAsYERlZnVuY2lvbnNgLCBgQ2Fzb3NfdWx0MTRkYCwgYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgLCBgVGFzYV9kZWZ1bmNpb25gLCBgSU5FQ29kUHJvdmAsIGBJTkVDb2RDQ0FBYCwgYE5vbWJyZU11bmlgLCBgTm9tYnJlUHJvdmAsIGBnZW9tZXRyeWAgKQ0Kcm0oZGZndmEsZGZwb2JsYWNpb25fZ3ZhLGRmcHVlYmxvcyxkZnB1ZWJsb3NfZGVmLCBtdW5pY2lwaW9zXzIwMTcsIElHTl9ub21lbmNsYV9tdW5pLCByaW9zLCB3b3JsZCkNCg0KZGZtdW5pY2lwaW9zX21hc0kgPC0gZGZtdW5pY2lwaW9zICU+JSBzbGljZV9tYXgoSW5jaWRlbmNpYV9hY3VtdWxhZGEsIG4gPSA1KSAlPiUgYXJyYW5nZShkZXNjKGBJbmNpZGVuY2lhX2FjdW11bGFkYWApKQ0KDQpkZm11bmljaXBpb3NfbWFzSV90YWJsYSA8LSBkZm11bmljaXBpb3NfbWFzSSAlPiUgc2VsZWN0KGBOb21icmVNdW5pYCxgUG9ibGFjaW9uc2AsIGBJbmNpZGVuY2lhX2FjdW11bGFkYWApICU+JSBhcnJhbmdlKGRlc2MoYEluY2lkZW5jaWFfYWN1bXVsYWRhYCkpDQoNCmtibChkZm11bmljaXBpb3NfbWFzSV90YWJsYSkgJT4lIA0KICBrYWJsZV9wYXBlcigic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGKSAlPiUNCiAgY29sdW1uX3NwZWMoMTozLCBib2xkID0gVCkgJT4lDQogIHJvd19zcGVjKDAsIGJvbGQgPSBULCBjb2xvciA9ICJ3aGl0ZSIsIGJhY2tncm91bmQgPSAiIzQ1MkFFNiIpJT4lDQogIHNjcm9sbF9ib3god2lkdGggPSAiMTAwJSIsIGhlaWdodCA9ICIzMDBweCIpDQoNCmBgYA0KDQpFc3RvcyBzb24gbG9zIDUgbXVuaWNpcGlvcyB2YWxlbmNpYW5vcyBjb24gdW5hIGluY2lkZW5jaWEgYWN1bXVsYWRhIG1heW9yLg0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IFRSVUV9DQoNCiNUYWJsYSBjb24gQmFuZGVyYSBkZSBWaWxsYWhlcm1vc2EgZGVsIHLDrW8uDQoNCmRmZ3ZhIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL2NvdmlkLTE5LWNhc29zLWNvbmZpcm1hZG9zLXBvci1wY3ItY2Fzb3MtcGNyLWVuLWxvcy11bHRpbW9zLTE0LWRpYXMteS1wZXJzb25hcy1mYWxsZWNpZGFzLXBvci1tdS5jc3YiKQ0KZGZwb2JsYWNpb25fZ3ZhIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL3BvYmxhY2lvbl9tdW5pX3ZsYy54bHMiKQ0KbG9hZCgiLi9kYXRvcy9nZW9tZXRyaWFzX2NsYXNlXzEwLlJEYXRhIikNCg0Kbm9tYnJlc19vcmlnaW5hbGVzIDwtIG5hbWVzKGRmZ3ZhKQ0Kbm9tYnJlc19vcmlnaW5hbGVzDQpuYW1lcyhkZmd2YSlbMV0gPC0gIkNvZE11bmljaXBpbyINCm5hbWVzKGRmZ3ZhKVsyXSA8LSAiTXVuaWNpcGkiDQpuYW1lcyhkZmd2YSlbM10gPC0gIkNhc29zIg0KbmFtZXMoZGZndmEpWzRdIDwtICJJbmNpZGVuY2lhX2FjdW11bGFkYSINCm5hbWVzKGRmZ3ZhKVs1XSA8LSAiQ2Fzb3NfdWx0MTRkIg0KbmFtZXMoZGZndmEpWzZdIDwtICJJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkIg0KbmFtZXMoZGZndmEpWzddIDwtICJEZWZ1bmNpb25zIg0KbmFtZXMoZGZndmEpWzhdIDwtICJUYXNhX2RlZnVuY2lvbiINCg0KZGZndmEgPC0gZGZndmEgJT4lIG11dGF0ZShDb2RNdW5pY2lwaW8gPSBhcy5udW1lcmljKENvZE11bmljaXBpbykpDQptdW5pY2lwaW9zXzIwMTcgPC0gbXVuaWNpcGlvc18yMDE3ICU+JSBtdXRhdGUoSU5FQ29kTXVuaSA9IGFzLm51bWVyaWMoSU5FQ29kTXVuaSkpDQpkZnB1ZWJsb3MgPC0gaW5uZXJfam9pbihkZmd2YSwgbXVuaWNpcGlvc18yMDE3LCBieSA9IGMoIkNvZE11bmljaXBpbyIgPSAiSU5FQ29kTXVuaSIgKSkNCmRmcHVlYmxvc19kZWYgPC0gaW5uZXJfam9pbihkZnB1ZWJsb3MsIGRmcG9ibGFjaW9uX2d2YSwgYnkgPSBjKCJDb2RNdW5pY2lwaW8iID0gIkNvZGlfTXVuaWNpcGkiICkpDQpkZm11bmljaXBpb3MgPC0gZGZwdWVibG9zX2RlZiAlPiUgc2VsZWN0KGBDb2RNdW5pY2lwaW9gLGBOb21icmVNdW5pYCwgYFBvYmxhY2lvbnNgLGBDYXNvc2AsYEluY2lkZW5jaWFfYWN1bXVsYWRhYCxgRGVmdW5jaW9uc2AsIGBDYXNvc191bHQxNGRgLCBgSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZGAsIGBUYXNhX2RlZnVuY2lvbmAsIGBJTkVDb2RQcm92YCwgYElORUNvZENDQUFgLCBgTm9tYnJlTXVuaWAsIGBOb21icmVQcm92YCwgYGdlb21ldHJ5YCApDQpybShkZmd2YSxkZnBvYmxhY2lvbl9ndmEsZGZwdWVibG9zLGRmcHVlYmxvc19kZWYsIG11bmljaXBpb3NfMjAxNywgSUdOX25vbWVuY2xhX211bmksIHJpb3MsIHdvcmxkKQ0KDQpNdW5pY2lwaW9NYXlvckluY2lBY3UgPC0gZGZtdW5pY2lwaW9zICU+JSBzbGljZV9tYXgoSW5jaWRlbmNpYV9hY3VtdWxhZGEsIG49MSkNCg0KSW1hZ2VuVmlsbGEgPC0gImh0dHBzOi8vd3d3LmNvbXByYXJiYW5kZXJhcy5lcy9pbWFnZXMvYmFuZGVyYXMvNDAwLzcwMTUtdmlsbGFoZXJtb3NhLWRlbC1yaW9fNDAwcHguanBnIg0KDQpUYWJsYV9NdW5pY2lwaW9NYXlvckluY2lBY3UgPC0gTXVuaWNpcGlvTWF5b3JJbmNpQWN1ICU+JSBndCgpDQoNClRhYmxhX011bmljaXBpb01heW9ySW5jaUFjdSA8LSBNdW5pY2lwaW9NYXlvckluY2lBY3UgJT4lIGdyb3VwX2J5KE5vbWJyZU11bmkpICU+JSBzbGljZV9tYXgoSW5jaWRlbmNpYV9hY3VtdWxhZGEsIG4gPSAxKSAlPiUgYWRkX2NvbHVtbihJbWFnZW5WaWxsYSkgJT4lIA0KICBzZWxlY3QoTm9tYnJlTXVuaSxQb2JsYWNpb25zLEluY2lkZW5jaWFfYWN1bXVsYWRhLEltYWdlblZpbGxhKSAlPiUgdW5ncm91cCgpDQoNClRhYmxhX011bmljaXBpb01heW9ySW5jaUFjdSAlPiUgZ3QoKSAlPiUgDQogIGd0Ojp0ZXh0X3RyYW5zZm9ybShsb2NhdGlvbnMgPSBjZWxsc19ib2R5KGNvbHVtbnMgPSB2YXJzKEltYWdlblZpbGxhKSksDQogICAgICAgICAgICAgICAgICAgICBmbiA9IGZ1bmN0aW9uKHgpIHtndDo6d2ViX2ltYWdlKHgsIGhlaWdodCA9IDUwKX0pICU+JSB0YWJfaGVhZGVyKHRpdGxlID0gbWQoIioqTXVuaWNpcGlvIGNvbiBtYXlvciBpbmNpZGVuY2lhIGFjdW11bGFkYSoqIiksc3VidGl0bGUgPSBtZCgiKipDb211bmlkYWQgVmFsZW5jaWFuYSoqIikpICU+JQ0KICB0YWJfb3B0aW9ucyhoZWFkaW5nLmJhY2tncm91bmQuY29sb3IgPSAib3JhbmdlIiwgY29sdW1uX2xhYmVscy5mb250LndlaWdodCA9ICJib2xkIikNCg0KDQpgYGANCg0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IFRSVUV9DQojYnVzY2Ftb3MgbGFzIDUgY2l1ZGFkZXMgcXVlIHRpZW5lbiB1biB0YXNhIGRlIGluY2lkZW5jaWEgYWN1bXVsYWRhIG1lbm9yLiBIYWNlbW9zIHRhYmxhIHkgbG9zIHNpdHVhbW9zIGVuIGVsIG1hcGENCg0KZGZtdW5pY2lwaW9zX21lbm9zSSA8LSBkZm11bmljaXBpb3MgJT4lIHNsaWNlX21pbihJbmNpZGVuY2lhX2FjdW11bGFkYSwgbiA9IDUpICU+JSBhcnJhbmdlKGRlc2MoYFBvYmxhY2lvbnNgKSkgJT4lIHNsaWNlICgxOjUpDQoNCmRmbXVuaWNpcGlvc19tZW5vc0lfdGFibGEgPC0gZGZtdW5pY2lwaW9zX21lbm9zSSAlPiUgc2VsZWN0KGBOb21icmVNdW5pYCxgUG9ibGFjaW9uc2AsIGBJbmNpZGVuY2lhX2FjdW11bGFkYWApICU+JSBhcnJhbmdlKGRlc2MoYFBvYmxhY2lvbnNgKSkNCg0Ka2JsKGRmbXVuaWNpcGlvc19tZW5vc0lfdGFibGEpICU+JSANCiAga2FibGVfcGFwZXIoInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRikgJT4lDQogIGNvbHVtbl9zcGVjKDE6MywgYm9sZCA9IFQpICU+JQ0KICByb3dfc3BlYygwLCBib2xkID0gVCwgY29sb3IgPSAid2hpdGUiLCBiYWNrZ3JvdW5kID0gIiM0NTJBRTYiKSU+JQ0KICBzY3JvbGxfYm94KHdpZHRoID0gIjEwMCUiLCBoZWlnaHQgPSAiMzAwcHgiKQ0KDQpgYGANCg0KRXN0b3Mgc29uIGxvcyA1IG11bmljaXBpb3MgdmFsZW5jaWFub3MgY29uIHVuYSBpbmNpZGVuY2lhIGFjdW11bGFkYSBtZW5vci4gQ29tbyBoYWLDrWEgbXVjaG9zIG11bmljaXBpb3MgY29uIHVuYSBpbmNpZGVuY2lhIGRlIDAsIGhlbW9zIGNvZ2lkbyBsb3MgNSBxdWUgdGVuw61hIHVuYSBwb2JsYWNpw7NuIG1heW9yLg0KDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gVFJVRX0NCg0KI1RhYmxhIGNvbiBiYW5kZXJhIGRlIFZhbGwgZGUgR2FsbGluZXJhLg0KDQpkZmd2YSA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jb3ZpZC0xOS1jYXNvcy1jb25maXJtYWRvcy1wb3ItcGNyLWNhc29zLXBjci1lbi1sb3MtdWx0aW1vcy0xNC1kaWFzLXktcGVyc29uYXMtZmFsbGVjaWRhcy1wb3ItbXUuY3N2IikNCmRmcG9ibGFjaW9uX2d2YSA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9wb2JsYWNpb25fbXVuaV92bGMueGxzIikNCmxvYWQoIi4vZGF0b3MvZ2VvbWV0cmlhc19jbGFzZV8xMC5SRGF0YSIpDQoNCm5vbWJyZXNfb3JpZ2luYWxlcyA8LSBuYW1lcyhkZmd2YSkNCm5vbWJyZXNfb3JpZ2luYWxlcw0KbmFtZXMoZGZndmEpWzFdIDwtICJDb2RNdW5pY2lwaW8iDQpuYW1lcyhkZmd2YSlbMl0gPC0gIk11bmljaXBpIg0KbmFtZXMoZGZndmEpWzNdIDwtICJDYXNvcyINCm5hbWVzKGRmZ3ZhKVs0XSA8LSAiSW5jaWRlbmNpYV9hY3VtdWxhZGEiDQpuYW1lcyhkZmd2YSlbNV0gPC0gIkNhc29zX3VsdDE0ZCINCm5hbWVzKGRmZ3ZhKVs2XSA8LSAiSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZCINCm5hbWVzKGRmZ3ZhKVs3XSA8LSAiRGVmdW5jaW9ucyINCm5hbWVzKGRmZ3ZhKVs4XSA8LSAiVGFzYV9kZWZ1bmNpb24iDQoNCmRmZ3ZhIDwtIGRmZ3ZhICU+JSBtdXRhdGUoQ29kTXVuaWNpcGlvID0gYXMubnVtZXJpYyhDb2RNdW5pY2lwaW8pKQ0KbXVuaWNpcGlvc18yMDE3IDwtIG11bmljaXBpb3NfMjAxNyAlPiUgbXV0YXRlKElORUNvZE11bmkgPSBhcy5udW1lcmljKElORUNvZE11bmkpKQ0KZGZwdWVibG9zIDwtIGlubmVyX2pvaW4oZGZndmEsIG11bmljaXBpb3NfMjAxNywgYnkgPSBjKCJDb2RNdW5pY2lwaW8iID0gIklORUNvZE11bmkiICkpDQpkZnB1ZWJsb3NfZGVmIDwtIGlubmVyX2pvaW4oZGZwdWVibG9zLCBkZnBvYmxhY2lvbl9ndmEsIGJ5ID0gYygiQ29kTXVuaWNpcGlvIiA9ICJDb2RpX011bmljaXBpIiApKQ0KZGZtdW5pY2lwaW9zIDwtIGRmcHVlYmxvc19kZWYgJT4lIHNlbGVjdChgQ29kTXVuaWNpcGlvYCxgTm9tYnJlTXVuaWAsIGBQb2JsYWNpb25zYCxgQ2Fzb3NgLGBJbmNpZGVuY2lhX2FjdW11bGFkYWAsYERlZnVuY2lvbnNgLCBgQ2Fzb3NfdWx0MTRkYCwgYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgLCBgVGFzYV9kZWZ1bmNpb25gLCBgSU5FQ29kUHJvdmAsIGBJTkVDb2RDQ0FBYCwgYE5vbWJyZU11bmlgLCBgTm9tYnJlUHJvdmAsIGBnZW9tZXRyeWAgKQ0Kcm0oZGZndmEsZGZwb2JsYWNpb25fZ3ZhLGRmcHVlYmxvcyxkZnB1ZWJsb3NfZGVmLCBtdW5pY2lwaW9zXzIwMTcsIElHTl9ub21lbmNsYV9tdW5pLCByaW9zLCB3b3JsZCkNCg0KTXVuaWNpcGlvTWVub3JJbmNpQWN1IDwtIGRmbXVuaWNpcGlvcyAlPiUgc2xpY2VfbWluKEluY2lkZW5jaWFfYWN1bXVsYWRhLCBuPTEpJT4lIGFycmFuZ2UoZGVzYyhgUG9ibGFjaW9uc2ApKSU+JSBzbGljZSgxOjEpDQoNCkltYWdlblZhbGwgPC0gImh0dHBzOi8vdXBsb2FkLndpa2ltZWRpYS5vcmcvd2lraXBlZGlhL2NvbW1vbnMvdGh1bWIvYS9hNC9Fc2N1dF9kZV9sYV9WYWxsX2RlX0dhbGxpbmVyYS5zdmcvODVweC1Fc2N1dF9kZV9sYV9WYWxsX2RlX0dhbGxpbmVyYS5zdmcucG5nIg0KDQpUYWJsYV9NdW5pY2lwaW9NZW5vckluY2lBY3UgPC0gTXVuaWNpcGlvTWVub3JJbmNpQWN1ICU+JSBndCgpDQoNClRhYmxhX011bmljaXBpb01lbm9ySW5jaUFjdSA8LSBNdW5pY2lwaW9NZW5vckluY2lBY3UgJT4lIGdyb3VwX2J5KE5vbWJyZU11bmkpICU+JSBzbGljZV9tYXgoSW5jaWRlbmNpYV9hY3VtdWxhZGEsIG4gPSAxKSAlPiUgYWRkX2NvbHVtbihJbWFnZW5WYWxsKSAlPiUgDQogIHNlbGVjdChOb21icmVNdW5pLFBvYmxhY2lvbnMsSW5jaWRlbmNpYV9hY3VtdWxhZGEsSW1hZ2VuVmFsbCkgJT4lIHVuZ3JvdXAoKQ0KDQpUYWJsYV9NdW5pY2lwaW9NZW5vckluY2lBY3UgJT4lIGd0KCkgJT4lIA0KICBndDo6dGV4dF90cmFuc2Zvcm0obG9jYXRpb25zID0gY2VsbHNfYm9keShjb2x1bW5zID0gdmFycyhJbWFnZW5WYWxsKSksDQogICAgICAgICAgICAgICAgICAgICBmbiA9IGZ1bmN0aW9uKHgpIHtndDo6d2ViX2ltYWdlKHgsIGhlaWdodCA9IDUwKX0pICU+JSB0YWJfaGVhZGVyKHRpdGxlID0gbWQoIioqTXVjaWNpcGlvIGNvbiBtZW5vciBpbmNpZGVuY2lhIGFjdW11bGFkYSoqIiksc3VidGl0bGUgPSBtZCgiKipDb211bmlkYWQgVmFsZW5jaWFuYSoqIikpICU+JQ0KICB0YWJfb3B0aW9ucyhoZWFkaW5nLmJhY2tncm91bmQuY29sb3IgPSAidG9tYXRvIiwgY29sdW1uX2xhYmVscy5mb250LndlaWdodCA9ICJib2xkIikNCg0KYGBgDQoNCg0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IFRSVUV9DQoNCm1hcGFDaXVkYWR5UHVlYmxvbWF5b3JpbmNpQWN1IDwtIGxlYWZsZXQoKSAlPiUNCiAgc2V0VmlldyhsbmcgPSAtMC4yNDM1OTEsIGxhdCA9IDM4LjgyMSwgem9vbSA9IDcpICU+JSANCiAgYWRkTWFya2VycyhsbmcgPSAtMC4yNDM1OTEsIGxhdCA9IDM4LjgyMSAsIHBvcHVwID0gIlZhbGwgZGUgR2FsbGluZXJhIiklPiUNCiAgc2V0VmlldyhsbmcgPSAtMC40MTg1OTgsIGxhdCA9IDQwLjIwMTEsIHpvb20gPSA3KSAlPiUgDQogIGFkZE1hcmtlcnMobG5nID0gLTAuNDE4NTk4LCBsYXQgPSA0MC4yMDExICwgcG9wdXAgPSAiVmlsbGFoZXJtb3NhIGRlbCByaW8iKSAlPiUgYWRkVGlsZXMoKQ0KbWFwYUNpdWRhZHlQdWVibG9tYXlvcmluY2lBY3UNCg0KYGBgDQoNClNpdHVhbW9zIGVuIHVuIG1hcGEgYSBsb3MgZG9zIG11bmljaXBpb3MgY29uIG1heW9yIHkgbWVub3Igw61uZGljZSBkZSBpbmNpZGVuY2lhIGFjdW11bGFkYS4NCg0KIyMgPEZPTlQgQ09MT1I9IkdyZWVuIj41LjQuIFRhc2EgZGUgZGVmdW5jaW9uZXMgLiA8L0ZPTlQ+DQoNCkVuIGVzdGUgc3ViYXBhcnRhZG8gaGVtb3MgcXVlcmlkbyBidXNjYXIgbG9zIGNpbmNvIG11bmljaXBpb3MgdmFsZW5jaWFub3MgY29uIG1heW9yIHkgbWVub3IgdGFzYSBkZSBkZWZ1bmNpb25lcyBlbiBsYSBDb211bmlkYWQgVmFsZW5jaWFuYS4NCg0KYGBge3IgZXZhbCA9IFRSVUUsIGVjaG8gPSBUUlVFfQ0KDQojIGJ1c2NhbW9zIGxvcyA1IG11bmljaXBpb3MgcXVlIHRpZW5lbiB1biB0YXNhIGRlIG1vcnRhbGlkYWQgbWF5b3IuIEhhY2Vtb3MgdGFibGEgeSBsb3Mgc2l0dWFtb3MgZW4gZWwgbWFwYQ0KDQpkZmd2YSA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jb3ZpZC0xOS1jYXNvcy1jb25maXJtYWRvcy1wb3ItcGNyLWNhc29zLXBjci1lbi1sb3MtdWx0aW1vcy0xNC1kaWFzLXktcGVyc29uYXMtZmFsbGVjaWRhcy1wb3ItbXUuY3N2IikNCmRmcG9ibGFjaW9uX2d2YSA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9wb2JsYWNpb25fbXVuaV92bGMueGxzIikNCmxvYWQoIi4vZGF0b3MvZ2VvbWV0cmlhc19jbGFzZV8xMC5SRGF0YSIpDQoNCm5vbWJyZXNfb3JpZ2luYWxlcyA8LSBuYW1lcyhkZmd2YSkNCm5vbWJyZXNfb3JpZ2luYWxlcw0KbmFtZXMoZGZndmEpWzFdIDwtICJDb2RNdW5pY2lwaW8iDQpuYW1lcyhkZmd2YSlbMl0gPC0gIk11bmljaXBpIg0KbmFtZXMoZGZndmEpWzNdIDwtICJDYXNvcyINCm5hbWVzKGRmZ3ZhKVs0XSA8LSAiSW5jaWRlbmNpYV9hY3VtdWxhZGEiDQpuYW1lcyhkZmd2YSlbNV0gPC0gIkNhc29zX3VsdDE0ZCINCm5hbWVzKGRmZ3ZhKVs2XSA8LSAiSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZCINCm5hbWVzKGRmZ3ZhKVs3XSA8LSAiRGVmdW5jaW9ucyINCm5hbWVzKGRmZ3ZhKVs4XSA8LSAiVGFzYV9kZWZ1bmNpb24iDQoNCmRmZ3ZhIDwtIGRmZ3ZhICU+JSBtdXRhdGUoQ29kTXVuaWNpcGlvID0gYXMubnVtZXJpYyhDb2RNdW5pY2lwaW8pKQ0KbXVuaWNpcGlvc18yMDE3IDwtIG11bmljaXBpb3NfMjAxNyAlPiUgbXV0YXRlKElORUNvZE11bmkgPSBhcy5udW1lcmljKElORUNvZE11bmkpKQ0KZGZwdWVibG9zIDwtIGlubmVyX2pvaW4oZGZndmEsIG11bmljaXBpb3NfMjAxNywgYnkgPSBjKCJDb2RNdW5pY2lwaW8iID0gIklORUNvZE11bmkiICkpDQpkZnB1ZWJsb3NfZGVmIDwtIGlubmVyX2pvaW4oZGZwdWVibG9zLCBkZnBvYmxhY2lvbl9ndmEsIGJ5ID0gYygiQ29kTXVuaWNpcGlvIiA9ICJDb2RpX011bmljaXBpIiApKQ0KZGZtdW5pY2lwaW9zIDwtIGRmcHVlYmxvc19kZWYgJT4lIHNlbGVjdChgQ29kTXVuaWNpcGlvYCxgTm9tYnJlTXVuaWAsIGBQb2JsYWNpb25zYCxgQ2Fzb3NgLGBJbmNpZGVuY2lhX2FjdW11bGFkYWAsYERlZnVuY2lvbnNgLCBgQ2Fzb3NfdWx0MTRkYCwgYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgLCBgVGFzYV9kZWZ1bmNpb25gLCBgSU5FQ29kUHJvdmAsIGBJTkVDb2RDQ0FBYCwgYE5vbWJyZU11bmlgLCBgTm9tYnJlUHJvdmAsIGBnZW9tZXRyeWAgKQ0Kcm0oZGZndmEsZGZwb2JsYWNpb25fZ3ZhLGRmcHVlYmxvcyxkZnB1ZWJsb3NfZGVmLCBtdW5pY2lwaW9zXzIwMTcsIElHTl9ub21lbmNsYV9tdW5pLCByaW9zLCB3b3JsZCkNCg0KZGZtdW5pY2lwaW9zX21hc00gPC0gZGZtdW5pY2lwaW9zICU+JSBzbGljZV9tYXgoVGFzYV9kZWZ1bmNpb24sIG4gPSA1KSAlPiUgYXJyYW5nZShkZXNjKGBUYXNhX2RlZnVuY2lvbmApKQ0KDQpkZm11bmljaXBpb3NfbWFzTV90YWJsYSA8LSBkZm11bmljaXBpb3NfbWFzTSAlPiUgc2VsZWN0KGBOb21icmVNdW5pYCxgUG9ibGFjaW9uc2AsIGBUYXNhX2RlZnVuY2lvbmApJT4lIGFycmFuZ2UoZGVzYyhgVGFzYV9kZWZ1bmNpb25gKSkNCg0KZGZtdW5pY2lwaW9zX21hc01fdGFibGEgJT4lDQogIGtibCgpICU+JQ0KICBrYWJsZV9tYXRlcmlhbF9kYXJrKCkNCg0KYGBgDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gVFJVRX0NCg0KIyBCYW5kZXJhIGRlbCBtdW5pY2lwaW8gY29uIHVuYSBtYXlvciB0YXNhIGRlIGRlZnVuY2nDs24NCg0KZGZndmEgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvY292aWQtMTktY2Fzb3MtY29uZmlybWFkb3MtcG9yLXBjci1jYXNvcy1wY3ItZW4tbG9zLXVsdGltb3MtMTQtZGlhcy15LXBlcnNvbmFzLWZhbGxlY2lkYXMtcG9yLW11LmNzdiIpDQpkZnBvYmxhY2lvbl9ndmEgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvcG9ibGFjaW9uX211bmlfdmxjLnhscyIpDQpsb2FkKCIuL2RhdG9zL2dlb21ldHJpYXNfY2xhc2VfMTAuUkRhdGEiKQ0KDQpub21icmVzX29yaWdpbmFsZXMgPC0gbmFtZXMoZGZndmEpDQpub21icmVzX29yaWdpbmFsZXMNCm5hbWVzKGRmZ3ZhKVsxXSA8LSAiQ29kTXVuaWNpcGlvIg0KbmFtZXMoZGZndmEpWzJdIDwtICJNdW5pY2lwaSINCm5hbWVzKGRmZ3ZhKVszXSA8LSAiQ2Fzb3MiDQpuYW1lcyhkZmd2YSlbNF0gPC0gIkluY2lkZW5jaWFfYWN1bXVsYWRhIg0KbmFtZXMoZGZndmEpWzVdIDwtICJDYXNvc191bHQxNGQiDQpuYW1lcyhkZmd2YSlbNl0gPC0gIkluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGQiDQpuYW1lcyhkZmd2YSlbN10gPC0gIkRlZnVuY2lvbnMiDQpuYW1lcyhkZmd2YSlbOF0gPC0gIlRhc2FfZGVmdW5jaW9uIg0KDQpkZmd2YSA8LSBkZmd2YSAlPiUgbXV0YXRlKENvZE11bmljaXBpbyA9IGFzLm51bWVyaWMoQ29kTXVuaWNpcGlvKSkNCm11bmljaXBpb3NfMjAxNyA8LSBtdW5pY2lwaW9zXzIwMTcgJT4lIG11dGF0ZShJTkVDb2RNdW5pID0gYXMubnVtZXJpYyhJTkVDb2RNdW5pKSkNCmRmcHVlYmxvcyA8LSBpbm5lcl9qb2luKGRmZ3ZhLCBtdW5pY2lwaW9zXzIwMTcsIGJ5ID0gYygiQ29kTXVuaWNpcGlvIiA9ICJJTkVDb2RNdW5pIiApKQ0KZGZwdWVibG9zX2RlZiA8LSBpbm5lcl9qb2luKGRmcHVlYmxvcywgZGZwb2JsYWNpb25fZ3ZhLCBieSA9IGMoIkNvZE11bmljaXBpbyIgPSAiQ29kaV9NdW5pY2lwaSIgKSkNCmRmbXVuaWNpcGlvcyA8LSBkZnB1ZWJsb3NfZGVmICU+JSBzZWxlY3QoYENvZE11bmljaXBpb2AsYE5vbWJyZU11bmlgLCBgUG9ibGFjaW9uc2AsYENhc29zYCxgSW5jaWRlbmNpYV9hY3VtdWxhZGFgLGBEZWZ1bmNpb25zYCwgYENhc29zX3VsdDE0ZGAsIGBJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkYCwgYFRhc2FfZGVmdW5jaW9uYCwgYElORUNvZFByb3ZgLCBgSU5FQ29kQ0NBQWAsIGBOb21icmVNdW5pYCwgYE5vbWJyZVByb3ZgLCBgZ2VvbWV0cnlgICkNCnJtKGRmZ3ZhLGRmcG9ibGFjaW9uX2d2YSxkZnB1ZWJsb3MsZGZwdWVibG9zX2RlZiwgbXVuaWNpcGlvc18yMDE3LCBJR05fbm9tZW5jbGFfbXVuaSwgcmlvcywgd29ybGQpDQoNCm11bmljaXBpb01heW9ydGFzYU0gPC0gZGZtdW5pY2lwaW9zICU+JSBzbGljZV9tYXgoVGFzYV9kZWZ1bmNpb24sIG49MSkNCg0KSW1hZ2VuVmlsbGEgPC0gImh0dHBzOi8vd3d3LmNvbXByYXJiYW5kZXJhcy5lcy9pbWFnZXMvYmFuZGVyYXMvNDAwLzcwMTUtdmlsbGFoZXJtb3NhLWRlbC1yaW9fNDAwcHguanBnIg0KDQpUYWJsYV9tdW5pY2lwaW9NYXlvcnRhc2FNIDwtIG11bmljaXBpb01heW9ydGFzYU0gJT4lIGd0KCkNCg0KVGFibGFfbXVuaWNpcGlvTWF5b3J0YXNhTSA8LSBtdW5pY2lwaW9NYXlvcnRhc2FNICU+JSBncm91cF9ieShOb21icmVNdW5pKSAlPiUgc2xpY2VfbWF4KFRhc2FfZGVmdW5jaW9uLCBuID0gMSkgJT4lIGFkZF9jb2x1bW4oSW1hZ2VuVmlsbGEpICU+JSANCiAgc2VsZWN0KE5vbWJyZU11bmksUG9ibGFjaW9ucywgVGFzYV9kZWZ1bmNpb24sSW1hZ2VuVmlsbGEpICU+JSB1bmdyb3VwKCkNCg0KVGFibGFfbXVuaWNpcGlvTWF5b3J0YXNhTSU+JSBndCgpICU+JSANCiAgZ3Q6OnRleHRfdHJhbnNmb3JtKGxvY2F0aW9ucyA9IGNlbGxzX2JvZHkoY29sdW1ucyA9IHZhcnMoSW1hZ2VuVmlsbGEpKSwNCiAgICAgICAgICAgICAgICAgICAgIGZuID0gZnVuY3Rpb24oeCkge2d0Ojp3ZWJfaW1hZ2UoeCwgaGVpZ2h0ID0gNTApfSkgJT4lIHRhYl9oZWFkZXIodGl0bGUgPSBtZCgiKipNdW5pY2lwaW8gY29uIG1heW9yIHRhc2EgZGUgbW9ydGFsaWRhZCoqIiksc3VidGl0bGUgPSBtZCgiKipDb211bmlkYWQgVmFsZW5jaWFuYSoqIikpICU+JQ0KICB0YWJfb3B0aW9ucyhoZWFkaW5nLmJhY2tncm91bmQuY29sb3IgPSAiYmxhY2siLCBjb2x1bW5fbGFiZWxzLmZvbnQud2VpZ2h0ID0gImJvbGQiKQ0KDQpgYGANCg0KYGBge3IgZXZhbCA9IFRSVUUsIGVjaG8gPSBUUlVFfQ0KDQojIGJ1c2NhbW9zIGxhcyA1IG11bmljaXBpb3MgcXVlIHRpZW5lbiB1biB0YXNhIGRlIG1vcnRhbGlkYWQgbWVub3IuIEhhY2Vtb3MgdGFibGEgeSBsb3Mgc2l0dWFtb3MgZW4gZWwgbWFwYQ0KIyBBcXXDrSBoYXkgbXVjaG9zIHB1ZWJsb3MgY29uIHVuYSB0YXNhIGRlbCAwLiBIZW1vcyBjb2dpZG8gNSB5IG9yZGVuYW1vcyBwb3IgcG9ibGFjacOzbi4NCg0KDQpkZmd2YSA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jb3ZpZC0xOS1jYXNvcy1jb25maXJtYWRvcy1wb3ItcGNyLWNhc29zLXBjci1lbi1sb3MtdWx0aW1vcy0xNC1kaWFzLXktcGVyc29uYXMtZmFsbGVjaWRhcy1wb3ItbXUuY3N2IikNCmRmcG9ibGFjaW9uX2d2YSA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9wb2JsYWNpb25fbXVuaV92bGMueGxzIikNCmxvYWQoIi4vZGF0b3MvZ2VvbWV0cmlhc19jbGFzZV8xMC5SRGF0YSIpDQoNCm5vbWJyZXNfb3JpZ2luYWxlcyA8LSBuYW1lcyhkZmd2YSkNCm5vbWJyZXNfb3JpZ2luYWxlcw0KbmFtZXMoZGZndmEpWzFdIDwtICJDb2RNdW5pY2lwaW8iDQpuYW1lcyhkZmd2YSlbMl0gPC0gIk11bmljaXBpIg0KbmFtZXMoZGZndmEpWzNdIDwtICJDYXNvcyINCm5hbWVzKGRmZ3ZhKVs0XSA8LSAiSW5jaWRlbmNpYV9hY3VtdWxhZGEiDQpuYW1lcyhkZmd2YSlbNV0gPC0gIkNhc29zX3VsdDE0ZCINCm5hbWVzKGRmZ3ZhKVs2XSA8LSAiSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZCINCm5hbWVzKGRmZ3ZhKVs3XSA8LSAiRGVmdW5jaW9ucyINCm5hbWVzKGRmZ3ZhKVs4XSA8LSAiVGFzYV9kZWZ1bmNpb24iDQoNCmRmZ3ZhIDwtIGRmZ3ZhICU+JSBtdXRhdGUoQ29kTXVuaWNpcGlvID0gYXMubnVtZXJpYyhDb2RNdW5pY2lwaW8pKQ0KbXVuaWNpcGlvc18yMDE3IDwtIG11bmljaXBpb3NfMjAxNyAlPiUgbXV0YXRlKElORUNvZE11bmkgPSBhcy5udW1lcmljKElORUNvZE11bmkpKQ0KZGZwdWVibG9zIDwtIGlubmVyX2pvaW4oZGZndmEsIG11bmljaXBpb3NfMjAxNywgYnkgPSBjKCJDb2RNdW5pY2lwaW8iID0gIklORUNvZE11bmkiICkpDQpkZnB1ZWJsb3NfZGVmIDwtIGlubmVyX2pvaW4oZGZwdWVibG9zLCBkZnBvYmxhY2lvbl9ndmEsIGJ5ID0gYygiQ29kTXVuaWNpcGlvIiA9ICJDb2RpX011bmljaXBpIiApKQ0KZGZtdW5pY2lwaW9zIDwtIGRmcHVlYmxvc19kZWYgJT4lIHNlbGVjdChgQ29kTXVuaWNpcGlvYCxgTm9tYnJlTXVuaWAsIGBQb2JsYWNpb25zYCxgQ2Fzb3NgLGBJbmNpZGVuY2lhX2FjdW11bGFkYWAsYERlZnVuY2lvbnNgLCBgQ2Fzb3NfdWx0MTRkYCwgYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgLCBgVGFzYV9kZWZ1bmNpb25gLCBgSU5FQ29kUHJvdmAsIGBJTkVDb2RDQ0FBYCwgYE5vbWJyZU11bmlgLCBgTm9tYnJlUHJvdmAsIGBnZW9tZXRyeWAgKQ0Kcm0oZGZndmEsZGZwb2JsYWNpb25fZ3ZhLGRmcHVlYmxvcyxkZnB1ZWJsb3NfZGVmLCBtdW5pY2lwaW9zXzIwMTcsIElHTl9ub21lbmNsYV9tdW5pLCByaW9zLCB3b3JsZCkNCg0KZGZtdW5pY2lwaW9zX21lbm9zTSA8LSBkZm11bmljaXBpb3MgJT4lIHNsaWNlX21pbihUYXNhX2RlZnVuY2lvbiwgbiA9IDUpICU+JSBhcnJhbmdlKGRlc2MoYFBvYmxhY2lvbnNgKSkgJT4lIHNsaWNlKDE6NSkgDQoNCmRmbXVuaWNpcGlvc19tZW5vc01fdGFibGEgPC0gZGZtdW5pY2lwaW9zX21lbm9zTSAlPiUgc2VsZWN0KGBOb21icmVNdW5pYCxgUG9ibGFjaW9uc2AsIGBUYXNhX2RlZnVuY2lvbmApJT4lIGFycmFuZ2UoZGVzYyhgVGFzYV9kZWZ1bmNpb25gKSkNCg0KZGZtdW5pY2lwaW9zX21lbm9zTV90YWJsYSAlPiUNCiAga2JsKCkgJT4lDQogIGthYmxlX21hdGVyaWFsX2RhcmsoKQ0KDQoNCmBgYA0KDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gVFJVRX0NCg0KIyBIZW1vcyBwdWVzdG8gbGEgYmFuZGVyYSBkZWwgbXVuaWNpcGlvIGNvbiBsYSB0YXNhIGRlIG1vcnRhbGlkYWQgbcOhcyBiYWphIHkgcXVlIGFkZW3DoXMgdGVuw61hIGxhIHBvYmxhY2lvbiBtYXlvcg0KDQpkZmd2YSA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jb3ZpZC0xOS1jYXNvcy1jb25maXJtYWRvcy1wb3ItcGNyLWNhc29zLXBjci1lbi1sb3MtdWx0aW1vcy0xNC1kaWFzLXktcGVyc29uYXMtZmFsbGVjaWRhcy1wb3ItbXUuY3N2IikNCmRmcG9ibGFjaW9uX2d2YSA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9wb2JsYWNpb25fbXVuaV92bGMueGxzIikNCmxvYWQoIi4vZGF0b3MvZ2VvbWV0cmlhc19jbGFzZV8xMC5SRGF0YSIpDQoNCm5vbWJyZXNfb3JpZ2luYWxlcyA8LSBuYW1lcyhkZmd2YSkNCm5vbWJyZXNfb3JpZ2luYWxlcw0KbmFtZXMoZGZndmEpWzFdIDwtICJDb2RNdW5pY2lwaW8iDQpuYW1lcyhkZmd2YSlbMl0gPC0gIk11bmljaXBpIg0KbmFtZXMoZGZndmEpWzNdIDwtICJDYXNvcyINCm5hbWVzKGRmZ3ZhKVs0XSA8LSAiSW5jaWRlbmNpYV9hY3VtdWxhZGEiDQpuYW1lcyhkZmd2YSlbNV0gPC0gIkNhc29zX3VsdDE0ZCINCm5hbWVzKGRmZ3ZhKVs2XSA8LSAiSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZCINCm5hbWVzKGRmZ3ZhKVs3XSA8LSAiRGVmdW5jaW9ucyINCm5hbWVzKGRmZ3ZhKVs4XSA8LSAiVGFzYV9kZWZ1bmNpb24iDQoNCmRmZ3ZhIDwtIGRmZ3ZhICU+JSBtdXRhdGUoQ29kTXVuaWNpcGlvID0gYXMubnVtZXJpYyhDb2RNdW5pY2lwaW8pKQ0KbXVuaWNpcGlvc18yMDE3IDwtIG11bmljaXBpb3NfMjAxNyAlPiUgbXV0YXRlKElORUNvZE11bmkgPSBhcy5udW1lcmljKElORUNvZE11bmkpKQ0KZGZwdWVibG9zIDwtIGlubmVyX2pvaW4oZGZndmEsIG11bmljaXBpb3NfMjAxNywgYnkgPSBjKCJDb2RNdW5pY2lwaW8iID0gIklORUNvZE11bmkiICkpDQpkZnB1ZWJsb3NfZGVmIDwtIGlubmVyX2pvaW4oZGZwdWVibG9zLCBkZnBvYmxhY2lvbl9ndmEsIGJ5ID0gYygiQ29kTXVuaWNpcGlvIiA9ICJDb2RpX011bmljaXBpIiApKQ0KZGZtdW5pY2lwaW9zIDwtIGRmcHVlYmxvc19kZWYgJT4lIHNlbGVjdChgQ29kTXVuaWNpcGlvYCxgTm9tYnJlTXVuaWAsIGBQb2JsYWNpb25zYCxgQ2Fzb3NgLGBJbmNpZGVuY2lhX2FjdW11bGFkYWAsYERlZnVuY2lvbnNgLCBgQ2Fzb3NfdWx0MTRkYCwgYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgLCBgVGFzYV9kZWZ1bmNpb25gLCBgSU5FQ29kUHJvdmAsIGBJTkVDb2RDQ0FBYCwgYE5vbWJyZU11bmlgLCBgTm9tYnJlUHJvdmAsIGBnZW9tZXRyeWAgKQ0Kcm0oZGZndmEsZGZwb2JsYWNpb25fZ3ZhLGRmcHVlYmxvcyxkZnB1ZWJsb3NfZGVmLCBtdW5pY2lwaW9zXzIwMTcsIElHTl9ub21lbmNsYV9tdW5pLCByaW9zLCB3b3JsZCkNCg0KDQptdW5pY2lwaW9NZW5vcnRhc2FNIDwtIGRmbXVuaWNpcGlvcyAlPiUgc2xpY2VfbWluKFRhc2FfZGVmdW5jaW9uLCBuID0gMjApICU+JSBhcnJhbmdlKGRlc2MoYFBvYmxhY2lvbnNgKSkgJT4lIHNsaWNlKDE6MSkgDQoNCkltYWdlbkJlZ3Vhc2lsIDwtICJodHRwczovL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9jb21tb25zL3RodW1iL2EvYWIvRXNjdXRfZGVfQmVuYWd1YXNpbC5zdmcvMTAxcHgtRXNjdXRfZGVfQmVuYWd1YXNpbC5zdmcucG5nIg0KDQpUYWJsYV9tdW5pY2lwaW9NZW5vcnRhc2FNIDwtIG11bmljaXBpb01lbm9ydGFzYU0gJT4lIGd0KCkNCg0KVGFibGFfbXVuaWNpcGlvTWVub3J0YXNhTSA8LSBtdW5pY2lwaW9NZW5vcnRhc2FNICU+JSBncm91cF9ieShOb21icmVNdW5pKSAlPiUgc2xpY2VfbWF4KFRhc2FfZGVmdW5jaW9uLCBuID0gMSkgJT4lIGFkZF9jb2x1bW4oSW1hZ2VuQmVndWFzaWwpICU+JSANCiAgc2VsZWN0KE5vbWJyZU11bmksUG9ibGFjaW9ucyxUYXNhX2RlZnVuY2lvbixJbWFnZW5CZWd1YXNpbCkgJT4lIHVuZ3JvdXAoKQ0KDQpUYWJsYV9tdW5pY2lwaW9NZW5vcnRhc2FNJT4lIGd0KCkgJT4lIA0KICBndDo6dGV4dF90cmFuc2Zvcm0obG9jYXRpb25zID0gY2VsbHNfYm9keShjb2x1bW5zID0gdmFycyhJbWFnZW5CZWd1YXNpbCkpLA0KICAgICAgICAgICAgICAgICAgICAgZm4gPSBmdW5jdGlvbih4KSB7Z3Q6OndlYl9pbWFnZSh4LCBoZWlnaHQgPSA1MCl9KSAlPiUgdGFiX2hlYWRlcih0aXRsZSA9IG1kKCIqKk11bmljaXBpbyBjb24gbWVub3IgdGFzYSBkZSBtb3J0YWxpZGFkKioiKSxzdWJ0aXRsZSA9IG1kKCIqKkNvbXVuaWRhZCBWYWxlbmNpYW5hKioiKSkgJT4lDQogIHRhYl9vcHRpb25zKGhlYWRpbmcuYmFja2dyb3VuZC5jb2xvciA9ICJibGFjayIsIGNvbHVtbl9sYWJlbHMuZm9udC53ZWlnaHQgPSAiYm9sZCIpDQoNCmBgYA0KDQpIZW1vcyBwdWVzdG8gbGEgYmFuZGVyYSBkZWwgbXVuaWNpcGlvIGNvbiBsYSB0YXNhIGRlIG1vcnRhbGlkYWQgbcOhcyBiYWphIHkgcXVlIGFkZW3DoXMgdGVuw61hIGxhIHBvYmxhY2lvbiBtYXlvciBwb3JxdWUgdGllbmUgbcOhcyBtw6lyaXRvIHlhIHF1ZSBhIG1heW9yIHBvYmxhY2nDs24gdG9kb3MgbG9zIHZpcnVzIHNvbiBtw6FzIGRpZsOtY2lsZXMgZGUgY29udHJvbGFyLg0KDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gVFJVRX0NCg0KbWFwYUNpdWRhZHlQdWVibG9tZW5vcnRhc2FNIDwtIGxlYWZsZXQoKSAlPiUNCiAgc2V0VmlldyhsbmcgPSAtMC41ODkwNTYsIGxhdCA9IDM5LjU5MTUsIHpvb20gPSA3KSAlPiUgDQogIGFkZE1hcmtlcnMobG5nID0gLTAuNTg5MDU2LCBsYXQgPSAzOS41OTE1ICwgcG9wdXAgPSAiQmVuYWd1YXNpbCIpJT4lDQogIHNldFZpZXcobG5nID0gLTAuNDE4NTk4LCBsYXQgPSA0MC4yMDExLCB6b29tID0gNykgJT4lIA0KICBhZGRNYXJrZXJzKGxuZyA9IC0wLjQxODU5OCwgbGF0ID0gNDAuMjAxMSAsIHBvcHVwID0gIlZpbGxhaGVybW9zYSBkZWwgcmlvIikgJT4lIGFkZFRpbGVzKCkNCm1hcGFDaXVkYWR5UHVlYmxvbWVub3J0YXNhTQ0KDQpgYGANCg0KU2l0dWFtb3MgZW4gdW4gbWFwYSBhIGxvcyBkb3MgbXVuaWNpcGlvcyBjb24gbWF5b3IgeSBtZW5vciB0YXNhIGRlIGRlZnVuY2lvbmVzLg0KDQojIyA8Rk9OVCBDT0xPUj0iR3JlZW4iPjUuNS4gRGVmdW5jaW9uZXMgLiA8L0ZPTlQ+DQoNCkhlbW9zIHF1ZXJpZG8gbW9zdHJhciBsb3MgMTAgbXVuaWNpcGlvcyBjb24gbcOhcyBmYWxsZWNpZG9zIHkgbW9zdHJhciBjdWFudG9zIGhhbiB0ZW5pZG8uIEEgbWVudWRvIGN1YW5kbyB2ZW1vcyB0YXNhcyBkZSBtb3J0YWxpZGFkIHUgb3Ryb3Mgw61uZGljZXMgbm8gc29tb3MgY29uc2NpZW50ZXMgZGUgbGEgY3J1ZGV6YSBkZSBsYXMgY2lmcmFzIGFic29sdXRhczoNCg0KYGBge3IgZXZhbCA9IFRSVUUsIGVjaG8gPSBUUlVFfQ0KDQojYnVzY2Ftb3MgbG9zIDEwIG11bmljaXBpb3MgcXVlIGhhbiB0ZW5pZG8gbWF5b3IgbsO6bWVybyBkZSBmYWxsZWNpZG9zIHBhcmEgcXVlIHNlIHZlYW4gbGFzIG11ZXJ0ZXMgZW4gbsO6bWVyb3MgYWJzb2x1dG9zLiBIYWNlbW9zIHRhYmxhLg0KDQpkZmd2YSA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jb3ZpZC0xOS1jYXNvcy1jb25maXJtYWRvcy1wb3ItcGNyLWNhc29zLXBjci1lbi1sb3MtdWx0aW1vcy0xNC1kaWFzLXktcGVyc29uYXMtZmFsbGVjaWRhcy1wb3ItbXUuY3N2IikNCmRmcG9ibGFjaW9uX2d2YSA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9wb2JsYWNpb25fbXVuaV92bGMueGxzIikNCmxvYWQoIi4vZGF0b3MvZ2VvbWV0cmlhc19jbGFzZV8xMC5SRGF0YSIpDQoNCm5vbWJyZXNfb3JpZ2luYWxlcyA8LSBuYW1lcyhkZmd2YSkNCm5vbWJyZXNfb3JpZ2luYWxlcw0KbmFtZXMoZGZndmEpWzFdIDwtICJDb2RNdW5pY2lwaW8iDQpuYW1lcyhkZmd2YSlbMl0gPC0gIk11bmljaXBpIg0KbmFtZXMoZGZndmEpWzNdIDwtICJDYXNvcyINCm5hbWVzKGRmZ3ZhKVs0XSA8LSAiSW5jaWRlbmNpYV9hY3VtdWxhZGEiDQpuYW1lcyhkZmd2YSlbNV0gPC0gIkNhc29zX3VsdDE0ZCINCm5hbWVzKGRmZ3ZhKVs2XSA8LSAiSW5jaWRlbmNpYV8gYWN1bXVsYWRhX3VsdDE0ZCINCm5hbWVzKGRmZ3ZhKVs3XSA8LSAiRGVmdW5jaW9ucyINCm5hbWVzKGRmZ3ZhKVs4XSA8LSAiVGFzYV9kZWZ1bmNpb24iDQoNCmRmZ3ZhIDwtIGRmZ3ZhICU+JSBtdXRhdGUoQ29kTXVuaWNpcGlvID0gYXMubnVtZXJpYyhDb2RNdW5pY2lwaW8pKQ0KbXVuaWNpcGlvc18yMDE3IDwtIG11bmljaXBpb3NfMjAxNyAlPiUgbXV0YXRlKElORUNvZE11bmkgPSBhcy5udW1lcmljKElORUNvZE11bmkpKQ0KZGZwdWVibG9zIDwtIGlubmVyX2pvaW4oZGZndmEsIG11bmljaXBpb3NfMjAxNywgYnkgPSBjKCJDb2RNdW5pY2lwaW8iID0gIklORUNvZE11bmkiICkpDQpkZnB1ZWJsb3NfZGVmIDwtIGlubmVyX2pvaW4oZGZwdWVibG9zLCBkZnBvYmxhY2lvbl9ndmEsIGJ5ID0gYygiQ29kTXVuaWNpcGlvIiA9ICJDb2RpX011bmljaXBpIiApKQ0KZGZtdW5pY2lwaW9zIDwtIGRmcHVlYmxvc19kZWYgJT4lIHNlbGVjdChgQ29kTXVuaWNpcGlvYCxgTm9tYnJlTXVuaWAsIGBQb2JsYWNpb25zYCxgQ2Fzb3NgLGBJbmNpZGVuY2lhX2FjdW11bGFkYWAsYERlZnVuY2lvbnNgLCBgQ2Fzb3NfdWx0MTRkYCwgYEluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGRgLCBgVGFzYV9kZWZ1bmNpb25gLCBgSU5FQ29kUHJvdmAsIGBJTkVDb2RDQ0FBYCwgYE5vbWJyZU11bmlgLCBgTm9tYnJlUHJvdmAsIGBnZW9tZXRyeWAgKQ0Kcm0oZGZndmEsZGZwb2JsYWNpb25fZ3ZhLGRmcHVlYmxvcyxkZnB1ZWJsb3NfZGVmLCBtdW5pY2lwaW9zXzIwMTcsIElHTl9ub21lbmNsYV9tdW5pLCByaW9zLCB3b3JsZCkNCg0KZGZtdW5pY2lwaW9zX21hc0YgPC0gZGZtdW5pY2lwaW9zICU+JSBzbGljZV9tYXgoRGVmdW5jaW9ucywgbiA9IDEwKSAlPiUgYXJyYW5nZShkZXNjKGBEZWZ1bmNpb25zYCkpDQoNCmRmbXVuaWNpcGlvc19tYXNGX3RhYmxhIDwtIGRmbXVuaWNpcGlvc19tYXNGICAlPiUgc2VsZWN0KGBOb21icmVNdW5pYCxgUG9ibGFjaW9uc2AsIGBEZWZ1bmNpb25zYCkgJT4lIGFycmFuZ2UoZGVzYyhgRGVmdW5jaW9uc2ApKQ0KDQpkZm11bmljaXBpb3NfbWFzRl90YWJsYSAlPiUNCiAga2JsKGNhcHRpb24gPSAiUHVlYmxvcyBjb24gbcOhcyBmYWxsZWNpZG9zIikgJT4lDQogIGthYmxlX21pbmltYWwoZnVsbF93aWR0aCA9IEYpICU+JSBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIpKSAlPiUgcm93X3NwZWMocm93ID0gMCAsYmFja2dyb3VuZCA9ICIjREFGN0E2ICIsIGZvbnRfc2l6ZSA9IDE1KQ0KDQoNCmBgYA0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IFRSVUV9DQojZXNjdWRvIGNpdWRhZCBtw6FzIG11ZXJ0ZXMNCg0KZGZndmEgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvY292aWQtMTktY2Fzb3MtY29uZmlybWFkb3MtcG9yLXBjci1jYXNvcy1wY3ItZW4tbG9zLXVsdGltb3MtMTQtZGlhcy15LXBlcnNvbmFzLWZhbGxlY2lkYXMtcG9yLW11LmNzdiIpDQpkZnBvYmxhY2lvbl9ndmEgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvcG9ibGFjaW9uX211bmlfdmxjLnhscyIpDQpsb2FkKCIuL2RhdG9zL2dlb21ldHJpYXNfY2xhc2VfMTAuUkRhdGEiKQ0KDQpub21icmVzX29yaWdpbmFsZXMgPC0gbmFtZXMoZGZndmEpDQpub21icmVzX29yaWdpbmFsZXMNCm5hbWVzKGRmZ3ZhKVsxXSA8LSAiQ29kTXVuaWNpcGlvIg0KbmFtZXMoZGZndmEpWzJdIDwtICJNdW5pY2lwaSINCm5hbWVzKGRmZ3ZhKVszXSA8LSAiQ2Fzb3MiDQpuYW1lcyhkZmd2YSlbNF0gPC0gIkluY2lkZW5jaWFfYWN1bXVsYWRhIg0KbmFtZXMoZGZndmEpWzVdIDwtICJDYXNvc191bHQxNGQiDQpuYW1lcyhkZmd2YSlbNl0gPC0gIkluY2lkZW5jaWFfIGFjdW11bGFkYV91bHQxNGQiDQpuYW1lcyhkZmd2YSlbN10gPC0gIkRlZnVuY2lvbnMiDQpuYW1lcyhkZmd2YSlbOF0gPC0gIlRhc2FfZGVmdW5jaW9uIg0KDQpkZmd2YSA8LSBkZmd2YSAlPiUgbXV0YXRlKENvZE11bmljaXBpbyA9IGFzLm51bWVyaWMoQ29kTXVuaWNpcGlvKSkNCm11bmljaXBpb3NfMjAxNyA8LSBtdW5pY2lwaW9zXzIwMTcgJT4lIG11dGF0ZShJTkVDb2RNdW5pID0gYXMubnVtZXJpYyhJTkVDb2RNdW5pKSkNCmRmcHVlYmxvcyA8LSBpbm5lcl9qb2luKGRmZ3ZhLCBtdW5pY2lwaW9zXzIwMTcsIGJ5ID0gYygiQ29kTXVuaWNpcGlvIiA9ICJJTkVDb2RNdW5pIiApKQ0KZGZwdWVibG9zX2RlZiA8LSBpbm5lcl9qb2luKGRmcHVlYmxvcywgZGZwb2JsYWNpb25fZ3ZhLCBieSA9IGMoIkNvZE11bmljaXBpbyIgPSAiQ29kaV9NdW5pY2lwaSIgKSkNCmRmbXVuaWNpcGlvcyA8LSBkZnB1ZWJsb3NfZGVmICU+JSBzZWxlY3QoYENvZE11bmljaXBpb2AsYE5vbWJyZU11bmlgLCBgUG9ibGFjaW9uc2AsYENhc29zYCxgSW5jaWRlbmNpYV9hY3VtdWxhZGFgLGBEZWZ1bmNpb25zYCwgYENhc29zX3VsdDE0ZGAsIGBJbmNpZGVuY2lhXyBhY3VtdWxhZGFfdWx0MTRkYCwgYFRhc2FfZGVmdW5jaW9uYCwgYElORUNvZFByb3ZgLCBgSU5FQ29kQ0NBQWAsIGBOb21icmVNdW5pYCwgYE5vbWJyZVByb3ZgLCBgZ2VvbWV0cnlgICkNCnJtKGRmZ3ZhLGRmcG9ibGFjaW9uX2d2YSxkZnB1ZWJsb3MsZGZwdWVibG9zX2RlZiwgbXVuaWNpcGlvc18yMDE3LCBJR05fbm9tZW5jbGFfbXVuaSwgcmlvcywgd29ybGQpDQoNCk11bmljaXBpb01hc011ZXJ0ZXMgPC0gZGZtdW5pY2lwaW9zICU+JSBzbGljZV9tYXgoRGVmdW5jaW9ucywgbj0xKQ0KDQpJbWFnZW5WYWxlbmNpYSA8LSAiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy90aHVtYi80LzRlL0VzY3V0X2RlX1ZhbCVDMyVBOG5jaWEuc3ZnLzEwOHB4LUVzY3V0X2RlX1ZhbCVDMyVBOG5jaWEuc3ZnLnBuZyINCg0KVGFibGFfTXVuaWNpcGlvbWFzTXVlcnRlcyA8LSBNdW5pY2lwaW9NYXNNdWVydGVzICU+JSBndCgpDQoNClRhYmxhX011bmljaXBpb21hc011ZXJ0ZXMgPC0gTXVuaWNpcGlvTWFzTXVlcnRlcyAlPiUgZ3JvdXBfYnkoTm9tYnJlTXVuaSkgJT4lIHNsaWNlX21heChEZWZ1bmNpb25zLCBuID0gMSkgJT4lIGFkZF9jb2x1bW4oSW1hZ2VuVmFsZW5jaWEpICU+JSANCiAgc2VsZWN0KE5vbWJyZU11bmksUG9ibGFjaW9ucyxEZWZ1bmNpb25zLEltYWdlblZhbGVuY2lhKSAlPiUgdW5ncm91cCgpDQoNClRhYmxhX011bmljaXBpb21hc011ZXJ0ZXMgJT4lIGd0KCkgJT4lIA0KICBndDo6dGV4dF90cmFuc2Zvcm0obG9jYXRpb25zID0gY2VsbHNfYm9keShjb2x1bW5zID0gdmFycyhJbWFnZW5WYWxlbmNpYSkpLA0KICAgICAgICAgICAgICAgICAgICAgZm4gPSBmdW5jdGlvbih4KSB7Z3Q6OndlYl9pbWFnZSh4LCBoZWlnaHQgPSA1MCl9KSAlPiUgdGFiX2hlYWRlcih0aXRsZSA9IG1kKCJNdW5pY2lwaW8gY29uIG3DoXMgZGVmdW5jaW9uZXMiKSxzdWJ0aXRsZSA9IG1kKCJDb211bmlkYWQgVmFsZW5jaWFuYSIpKSAlPiUNCiAgdGFiX29wdGlvbnMoaGVhZGluZy5iYWNrZ3JvdW5kLmNvbG9yID0gImJsYWNrIiwgY29sdW1uX2xhYmVscy5mb250LndlaWdodCA9ICJib2xkIikNCg0KYGBgDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gVFJVRX0NCg0KbWFwYUNpdWRhZE1hc011ZXJ0ZXMgPC0gbGVhZmxldCgpICU+JQ0KICBzZXRWaWV3KGxuZyA9IC0wLjM3NzM5LCBsYXQgPSAzOS40Njk3NSwgem9vbSA9IDExKSAlPiUgDQogIGFkZE1hcmtlcnMobG5nID0gLTAuMzc3MzksIGxhdCA9IDM5LjQ2OTc1ICwgcG9wdXAgPSAiVmFsZW5jaWEiKSAlPiUgYWRkVGlsZXMoKQ0KbWFwYUNpdWRhZE1hc011ZXJ0ZXMNCg0KYGBgDQoNCiMgPEZPTlQgQ09MT1I9IkdyZWVuIj42LiBDb25zZWpvLiA8L0ZPTlQ+DQoNCj4gRWwgYW1hbmVjZXIgbGxlZ2EgZGVzcHXDqXMgZGUgbGEgb3NjdXJpZGFkIOKAlCBMaXNhIFdpbmdhdGUuDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gRkFMU0V9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbcOhZ2VuZXMiLCAiZmFtaWxpYV9mZWxpei5qcGciKSAgKQ0KYGBgDQoNCg0KPENFTlRFUj48Rk9OVCBDT0xPUj0iR3JleSI+IlNhbHZlbW9zIGxhIE5hdmlkYWQgZGUgMjAyMSI8L0ZPTlQ+PC9DRU5URVI+DQoNCiMgPEZPTlQgQ09MT1I9IkdyZWVuIj43LiBCaWJsaW9ncmFmw61hLiA8L0ZPTlQ+DQoNCltQw6FnaW5hIHdlYiBkZSBsYSBHVkFdKGh0dHA6Ly93d3cuZ3Zhb2JlcnRhLmd2YS5lcy92YS9jb3ZpZC0xOSkNCg0KW1DDoWdpbmEgd2ViIGRlbCBJTkVdKGh0dHBzOi8vd3d3LmluZS5lcy8pDQoNClR1dG9yaWFsZXMgZGUgcHJvZmVzYXIgZGUgVW5pdmVyc2lkYWQgZGUgVmFsZW5jaWEsIFtELlBlZHJvIEouIFDDqXJleiBdKGh0dHBzOi8vcGVyZXpwNDQuZ2l0aHViLmlvL2ludHJvLWRzLTIwLTIxLXdlYi9pbmRleC5odG1sKSANCg0KW1DDoWdpbmEgd2ViIGRlbCBIb3NwaXRhbCBDbMOtbmljIGRlIEJhcmNlbG9uYV0oaHR0cHM6Ly93d3cuY2xpbmljYmFyY2Vsb25hLm9yZy8paHR0cHM6Ly93d3cuY2xpbmljYmFyY2Vsb25hLm9yZy8NCg0KW1bDrWRlbyBleHBsaWNhdGl2byBkZSBSYWZhIEdvbnrDoWxleiBHb3V2ZWlhIHNvYnJlIGNvbW8gYW5pbWFyIGxhcyBncsOhZmljYXNdKGh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9cG5TTXRjMVBIX3cpDQoNCltBdmVyaWd1YXIgY29tbyBzZSBjYWxjdWxhIGxhIHRhc2EgZGUgZmFsbGVjaW1pZW50b3NdKGh0dHBzOi8vd3d3LmJiYy5jb20vbXVuZG8vbm90aWNpYXMtNTIyMzA4NDYpDQoNCltBdmVyaWd1YXIgY29tbyBzZSBjYWxjdWxhIGxhIHRhc2EgZGUgaW5jaWRlbmNpYV0oaHR0cHM6Ly93d3cuYWJjLmVzL3NvY2llZGFkL2FiY2ktaW5jaWRlbmNpYS1hY3VtdWxhZGEtY292aWQtbnN2LTIwMjAxMTIzMTIzOF9ub3RpY2lhLmh0bWwpDQoNCkRhdG9zIGRlbCBkYXRhZnJhbWUgeSBnZW9tZXRyaWFzIGRhZG9zIGVuIGNsYXNlIHBvciBELlBlZHJvIEouIFDDqXJlei4NCg0KQXl1ZGEgKiJsb2fDrXN0aWNhIiogZGVsIGZvcm8gY3JlYWRvIGVuIHBpYXp6YSBwYXJhIGF5dWRhcm5vcyBlbnRyZSBsb3MgY29tcGHDsWVyb3MsIHBhcmEgc2l0dWFyIGxvcyBtdW5pY2lwaW9zIGVuIGxvcyBtYXBhcyAowqFHcmFjaWFzIE5vZWxpYSEpLiANCg0KW05vcyBoYSBpbnNwaXJhZG8gZWwgdHJhYmFqbyAiQU7DgUxJU0lTIFNPQlJFIExBIENPVklELTE5IiBkZSBudWVzdHJvcyAgY29tcGHDsWVyb3MgZGUgY2xhc2U6IEFuZHJldSBFc3BhcnphIGkgTWFydGluZXosIElnbmFjaW8gTW9udGF2YSBQZXJhbHRhIHkgTm9lbGlhIFPDoW5jaGV6IE1hcmNoXShodHRwczovL25vc2FuNS5naXRodWIuaW8vdHJhYmFqb19CaWdEYXRhX2VxdWlwby8pIA0KDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gRkFMU0V9DQpzZXNzaW9uaW5mbzo6c2Vzc2lvbl9pbmZvKCkgJT4lIGRldGFpbHM6OmRldGFpbHMoc3VtbWFyeSA9ICdjdXJyZW50IHNlc3Npb24gaW5mbycpDQpgYGANCg==