Proyecto realizado para la asignatura’’Programación y manejo de datos en la era del Big Data" impartida por el profesor Pedro J. Pérez en el Grado de Economía de la Universidad de Valencia. La página web de la asignatura se puede ver aquí . Los trabajos elaborados por nuestros compañeros de curso pueden verse aquí


1.Introducción

La palabra turismo —según la OMT Organización Mundial del Turismo— comprende «las actividades que realizan las personas durante sus viajes y estancias en lugares distintos a su entorno habitual durante un período de tiempo inferior a un año, con fines de ocio, negocios u otros».

La industria turística presenta gran importancia a nivel global, pues es la responsable de la creación de numerosos puestos de trabajo y además, tiene aportación directa en el PIB mundial. La actividad generada por los sectores de la hostelería, las agencias de viaje, el transporte de pasajeros y del ocio en general consigue atraer, además, una importante inversión pública y de capital privado.

Es por ello que el objetivo de este trabajo es analizar el sector turístico centrándonos básicamente en España, con el fin de obtener información acerca de :

  • El origen de los flujos de turistas
  • Motivos de su llegada
  • Su gasto

2.Datos para la realización del proyecto

Descarga directa

Estos han sido los datos más fáciles de obtener, ya que primero los descargamos directamente de diferentes páginas web y luego los alojamos en GitHub. Esta manera es muy cómoda, por lo que ha sido la que más hemos usado. Los datos utiizados para la elaboración del presente proyecto son extraidos , principalmente de la base de datos de la página oficial del Instituto Nacional de Estadística (INE) , que puede verse aquí

Web Scraping

Para obtener los datos de los monumentos más visitados del mundo, decidimos hacer Web Scraping. El Web Scraping es bastante más complejo que el metodo anterior, ya que hay que buscar datos en el código fuente de la página web. En nuestro caso, decidimos utilizar este método para extraer los datos de una tabla de WikiPedia, así aprendimos cosas nuevas y añadimos variedad al trabajo.

A continuación mostramos la tabla que extraímos y el código utilizado.

Tabla Wikipedia

url <- "https://en.wikipedia.org/wiki/List_of_most_visited_palaces_and_monuments"
#Aquí sacamos la tabla
w <- read_html(url)
bb <- w %>% rvest::html_nodes(xpath = '/html/body/div[3]/div[3]/div[5]/div[1]/table') %>% rvest::html_table()
names(bb[[1]]) <- c(1:6)
#Aquí la arreglamos un poco, cambiando nombres, ordenando etc...
aa <- as_tibble(bb[[1]]) %>% select(-c(1,5,6)) %>% slice(c(2:11)) %>% mutate(Country = c("China","El Vaticano","Francia","Estados Unidos","Italia","Grecia","India","Francia","Alemania","Rusia")) %>% rename("Monumento" = 1, "Ciudad" = 2, "Visitantes" = 3) %>% relocate(4,.before = 3) %>% mutate(Visitantes = parse_number(Visitantes), Monumento = factor(Monumento, levels = Monumento[order(Visitantes)]), VisitantesM = (Visitantes/1000000), VisitantesM = round(VisitantesM,2))

APIS

Por último, también hemos obtenido algunos datos de Eurostat a través de su API. Para ello hemos utilizado el paquete library(eurostat) y el siguiente código:

#PIB en Millones
GDP <- eurostat::get_eurostat("nama_10_gdp")
GDP <- GDP %>% filter( na_item == "B1GQ", unit == "CP_MEUR") %>% select(geo,time,values)
GDP <- GDP %>% rename( code = geo)
cid <- eurostat::eu_countries
GDP <- inner_join(GDP,cid, by = "code" )
GDP <- GDP %>% select(-c(label)) %>% relocate(name, .before = code)
GDP <- GDP %>% rename_at(vars(colnames(GDP)), ~ c("Country","Code","Date","PIB"))
#GASTO TURISTICO Miles
GT <- eurostat::get_eurostat("tour_dem_extot")
GT <- GT %>% filter(duration == "N_GE1", purpose == "TOTAL",unit =="THS_EUR", partner == "WORLD")
GT <- GT %>% select(geo,time,values) %>% rename( code = geo)
cid <- eurostat::eu_countries
GT <- inner_join(GT,cid, by = "code" )
GT <- GT %>% select(-c(label)) %>% relocate(name, .before = code)
GT <- GT %>% rename_at(vars(colnames(GT)), ~ c("Country","Code","Date","GT"))


#POBLACIÓN
POB <- eurostat::get_eurostat("demo_gind")
POB <- POB %>% filter( indic_de == "JAN") %>% select(-c(indic_de))
POB <- POB %>% rename(code = geo)
cid <- eurostat::eu_countries
POB <- inner_join(POB,cid, by = "code" )
POB <- POB %>% select(-c(label)) %>% relocate(name, .before = code)
POB <- POB %>% rename_at(vars(colnames(POB)), ~ c("Country","Code","Date","POB"))

3. Turismo a nivel mundial

Países más visitados

El turismo ha sido un sector en auge durante las últimas décadas. Más de 1.100 millones de personas realizan turismo internacional cada año, la mitad en Europa. A favor del viejo continente juega un espacio de libre circulación de personas, una extendida moneda común y un entorno político fragmentado con muchos Estados pequeños y medianos, además de una amplia riqueza patrimonial y playas y buen clima en el sur. De todos modos en el listado de países más visitados también entran Estados Unidos y varios Estados asiáticos.

Según los datos provenientes de la Organización Mundial de Turismo (UNWTO por sus siglas en inglés),en su informe emitido en noviembre de 2019 , los países más visitados son Francia, España y Estados Unidos, con entre 80 y 90 millones de turistas internacionales; seguidos de China e Italia, con más de 60; a los que siguen ya a mayor distancia Turquía o México en el rango de los 40-50 millones. El crecimiento del turismo internacional se ha dejado notar sobretodo en España, que ganó atrajo mucho turismo y sigue manteniendo la segunda posición por varios años consecutivos; pero también se puede observar en paises como Tailandia, un pais lejano, que tiene cerca de los 40 millons de turistas anuales (en el año 2019) La evolución de la tecnología, la mejora de las infraestructuras y el abaratamiento de costes hace que cada vez más seres humanos puedan viajar con más frecuencia y más lejos.

Viajando se accede a culturas que no son como la tuya, a monumentos que no se parecen a los que conoces, a gastronomías que llevan a tu plato productos y sabores inimaginables.

#Importamos los datos del ranking países más visitados 
url2 <- "https://raw.githubusercontent.com/Pavlinadinkova/10/main/ranking.csv"
bb<- rio::import(url2, setclass="tibble")%>% mutate(Pais = c("FRANCIA ","ESPAÑA","EEUU","CHINA","ITALIA","TURQUIA","MÉXICO","ALEMANIA","TAILANDIA","REINO UNIDO","JAPÓN","AUSTRIA","GRECIA","HONG KONG","MALASIA","RUSIA","PORTUGAL","CANADA","POLONIA","PAISES BAJOS","MACAO","INDIA","HUNGRIA","CROACIA","EAU"),Pais = factor(Pais, levels = Pais[order(Viajeros_internacionales, decreasing = TRUE)]), Viajeros_internacionales = stringr::str_remove_all(Viajeros_internacionales, pattern = "[^[:alnum:]]"), Viajeros_internacionales = as.numeric(Viajeros_internacionales), )
d <- ggplot(bb) +
  geom_point(aes(x = Ranking, y = Viajeros_internacionales, colour = Ranking )) +
  facet_wrap(vars(Pais))+ labs(title = "Países más visitados del mundo ",
              subtitle = "anño 2019", 
              caption = "Datos provenientes de www.entereat.com",
              x = "Ranking ",
              y = "Nº de viajeros",
              color = "Ranking")

plotly::ggplotly(d, width = 900, height = 500)
  #Grafico paises más visitados (lollipop)

pl <- ggplot(bb, aes(x=Pais , y=Viajeros_internacionales))+ geom_point(aes(color=Pais), size=3 )+geom_segment(aes(x=Pais, xend=Pais, y=0 , yend=Viajeros_internacionales, color=Pais))+geom_text(aes(label=Pais), size=3, angle=90, vjust=0, nudge_y = -5000000)+theme(legend.position="none")+ labs(y="Número de viajeros", x=NULL,title = "Paises más visitados en el mundo", subtitle = "Datos de 2019" , caption= "Fuente:OMT") +  theme(axis.text.x = element_blank(),axis.line = element_line(color = "black",size=0.5), axis.ticks.x = element_blank(), panel.background = element_rect(fill = "#d5fffd"), panel.grid.major.y = element_line("grey"), panel.grid.major.x = element_blank(), panel.grid.minor.y = element_blank()) + scale_y_continuous(expand = c(0,0),breaks = seq(0,90000000,5000000), labels = paste((seq(0,90000000,5000000)/1000000),"M"), limits = c(0,95000000))


ggdraw(pl) + draw_image("https://upload.wikimedia.org/wikipedia/commons/b/ba/Flag_of_Germany.svg",x= 0.35, y = 0.43, width = 0.02, height = 0.02) + draw_image("https://upload.wikimedia.org/wikipedia/commons/4/41/Flag_of_Austria.svg", x=0.49, y=0.35, width=0.02, height = 0.02) + draw_image("https://upload.wikimedia.org/wikipedia/commons/c/c3/Flag_of_France.svg", x=0.10, y=0.87, width=0.018, height = 0.018) +
  draw_image("https://upload.wikimedia.org/wikipedia/commons/8/81/Bandera_de_Espa%C3%B1a_1978.png", x=0.13, y=0.81, width=0.018, height = 0.018) +
  draw_image("https://alphapedia.net/wp-content/uploads/2019/12/IMAGENES-DE-LA-BANDERA-DE-ESTADOS-UNIDOS-300x200.jpg", x=0.175, y=0.78, width=0.018, height = 0.018) + draw_image("https://upload.wikimedia.org/wikipedia/commons/thumb/f/fa/Flag_of_the_People%27s_Republic_of_China.svg/1280px-Flag_of_the_People%27s_Republic_of_China.svg.png", x=0.21, y=0.63, width=0.018, height = 0.018)  + draw_image("https://upload.wikimedia.org/wikipedia/commons/0/03/Flag_of_Italy.svg", x=0.24, y=0.62, width=0.018, height = 0.018)   + draw_image("https://upload.wikimedia.org/wikipedia/commons/b/b4/Flag_of_Turkey.svg", x=0.27, y=0.48, width=0.018, height = 0.018)  + draw_image("https://upload.wikimedia.org/wikipedia/commons/f/fc/Flag_of_Mexico.svg", x=0.31, y=0.47, width=0.018, height = 0.018) + draw_image("https://upload.wikimedia.org/wikipedia/commons/a/a9/Flag_of_Thailand.svg", x=0.38, y=0.41, width=0.018, height = 0.018) + draw_image("https://upload.wikimedia.org/wikipedia/en/a/ae/Flag_of_the_United_Kingdom.svg", x=0.41, y=0.40, width=0.018, height = 0.018) + draw_image("https://upload.wikimedia.org/wikipedia/en/9/9e/Flag_of_Japan.svg", x=0.465, y=0.36, width=0.018, height = 0.018)  + draw_image("https://upload.wikimedia.org/wikipedia/commons/5/5c/Flag_of_Greece.svg", x=0.53, y=0.36, width=0.018, height = 0.018) + draw_image("https://upload.wikimedia.org/wikipedia/commons/5/5b/Flag_of_Hong_Kong.svg", x=0.56, y=0.36, width=0.018, height = 0.018) + draw_image("https://upload.wikimedia.org/wikipedia/commons/6/66/Flag_of_Malaysia.svg", x=0.60, y=0.32, width=0.018, height = 0.018)  + draw_image("https://upload.wikimedia.org/wikipedia/commons/f/f3/Flag_of_Russia.svg", x=0.63, y=0.30, width=0.018, height = 0.018) + draw_image("https://upload.wikimedia.org/wikipedia/commons/5/5c/Flag_of_Portugal.svg", x=0.66, y=0.29, width=0.018, height = 0.018) + draw_image("https://upload.wikimedia.org/wikipedia/commons/thumb/d/d9/Flag_of_Canada_%28Pantone%29.svg/1920px-Flag_of_Canada_%28Pantone%29.svg.png", x=0.705, y=0.28, width=0.018, height = 0.018) + draw_image("https://upload.wikimedia.org/wikipedia/en/1/12/Flag_of_Poland.svg", x=0.74, y=0.27, width=0.018, height = 0.018)  + draw_image("https://www.paisesbajosytu.nl/binaries/medium/content/gallery/netherlandsandyou/content-afbeeldingen/algemeen/vlag-nederland.png", x=0.78, y=0.28, width=0.018, height = 0.018) + draw_image("https://upload.wikimedia.org/wikipedia/commons/6/63/Flag_of_Macau.svg", x=0.82, y=0.26, width=0.018, height = 0.018) + draw_image("https://upload.wikimedia.org/wikipedia/en/4/41/Flag_of_India.svg", x=0.847, y=0.24, width=0.018, height = 0.018 ) + draw_image("https://upload.wikimedia.org/wikipedia/commons/c/c1/Flag_of_Hungary.svg", x=0.89, y=0.23, width=0.018, height = 0.018) + draw_image("https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/Flag_of_Croatia.svg/1920px-Flag_of_Croatia.svg.png", x=0.92, y=0.23, width=0.018, height = 0.018)  + draw_image("https://upload.wikimedia.org/wikipedia/commons/c/cb/Flag_of_the_United_Arab_Emirates.svg", x=0.96, y=0.22, width=0.018, height = 0.018  )

Esta estadística presenta el número de llegadas de turistas internacionales que se produjeron en el mundo en 2016, según el área geográfica. Ese año la región Asia-Pacífico recibió alrededor de 300 millones de turistas, una cifra solo superada por la registrada en Europa. En el caso del continente americano, la cifra superó los 200 millones de turistas internacionales. En África y Oriente Medio, estos llegaron a los 58 y a los 56 millones respectivamente.

#Importamos datos TURISMO MUNDIAL
url6 <- "https://raw.githubusercontent.com/Pavlinadinkova/10/main/turismo_mundial.csv"
tt<- rio::import(url6, setclass="tibble")
names(tt)=c("Continente","Fecha","Turistas")
#Hacemos el gráfico de llegadas de turistas internacionales en Europa

 mundo_Europa <- tt %>% filter(Continente=="Europa")

  grafEuropa <- ggplot(mundo_Europa, aes(x=Fecha, y=Turistas , group=Continente, color=Fecha)) + geom_line() + facet_grid(Continente ~ .) +
  expand_limits(y=2) + theme(legend.position = "none") + labs(title = "Llegadas de turistas internacionales en Europa ",    caption = "Source:http://mkt.unwto.org/barometer",
              x = "Fecha ",
              y = NULL,
              color = "Continente",
              subtitle = "en millones de visitantes")

#Hacemos lo mismo para los otros continentes por separado , y finalmente las unimos.
library(patchwork)
(grafAfrica + grafEuropa) / (grafAmericas+grafAsia+ grafOriente )

Los 10 monumentos más visitados

Ambos gráficos salían descuadrados al ejecutarlos directamente en el .Rmd, así que los hemos alojado en github e insertado mediante url.

En el primer gráfico podemos ver los diez monumentos más visitados del mundo, se muestra: el número de visitantes anuales en Millones, la bandera y el nombre del país donde se encuentra el monumento.

Se puede observar como la Ciudad prohibida de Pekín es el monumento más visitado del mundo, con 17 millones de visitantes anuales. También cabe destacar que seis de los diez monumentos más visitados del mundo se encuentran en Europa.

Estos datos los hemos obtenido de WikiPedia mediante la técnnica WebScraping, ya hemos explicado este proceso en el punto 2.

url <- "https://en.wikipedia.org/wiki/List_of_most_visited_palaces_and_monuments"

#Sacamos la tabla de la página web, usamos el metodo web scrapling.
w <- read_html(url)
bb <- w %>% rvest::html_nodes(xpath = '/html/body/div[3]/div[3]/div[5]/div[1]/table') %>% rvest::html_table()
names(bb[[1]]) <- c(1:6)

#Arreglamos los datos: cambiamos los nombres, hacemos factores y cambiamos los datos a Millones.
aa <- as_tibble(bb[[1]]) %>% select(-c(1,5,6)) %>% slice(c(2:11)) %>% mutate(Country = c("China","El Vaticano","Francia","Estados Unidos","Italia","Grecia","India","Francia","Alemania","Rusia")) %>% rename("Monumento" = 1, "Ciudad" = 2, "Visitantes" = 3) %>% relocate(4,.before = 3) %>% mutate(Visitantes = parse_number(Visitantes), Monumento = factor(Monumento, levels = Monumento[order(Visitantes)]), VisitantesM = (Visitantes/1000000), VisitantesM = round(VisitantesM,2))

#Arreglamos la foto que vamos a utilizar de fondo.
url <- "https://d2gg9evh47fn9z.cloudfront.net/800px_COLOURBOX1682440.jpg"
img <- image_read(url) %>% image_resize("1500x750") %>% image_colorize(60,"#ffffff")
################################################################################
#Hacemos el gráfico principal
plot <- ggplot(aa,aes(x=VisitantesM,y=Monumento)) +
              geom_bar(color = "#000000",fill = "blue",stat="identity", width = 0.5) +
              geom_text(size = 12, stat = "identity", aes(label= VisitantesM), hjust= -1) +
              scale_y_discrete(labels = c("Palacio Peterhof, San Petesburgo","Catedral de Colonia, Colonia","Torre Eiffel, París","Taj Mahal, Agra","Partenón, Atenas","Coliseo, Roma","Monumento a Lincoln, Washington","Palacio de Versalles, Versailles","Basílica de San Pedro, El Vaticano","Ciudad prohibida, Pekín")) +
              scale_x_continuous(limits = c(0,20), expand = c(0.1,2)) +
              labs(fill=NULL,
               x= NULL,
               y=NULL,
               title="Monumentos más visitados del mundo",
               subtitle = "en Millones de visitantes anuales",
               caption="Fuente: Wikipedia") +
               theme( plot.background = NULL,
              panel.background = element_blank(),
              panel.grid  = element_blank(),
              axis.ticks = element_blank(),
              axis.text.x = element_blank(),
              axis.text.y = element_text(face = "bold",size = 20),
              plot.title = element_text(hjust = 0.5, size = 30),
              plot.subtitle = element_text(hjust = 0.5, size = 20),
              panel.border = element_blank(),
              legend.position = "none",
              plot.margin = margin(t = 5, r = 25, b = 5,15),
              strip.background = element_rect(fill = "#e8d7a3",colour = NULL))
#Añadimos unas imágenes al gráfico principal
plotd <- ggdraw(plot) + draw_image("https://upload.wikimedia.org/wikipedia/commons/thumb/f/fa/Flag_of_the_People%27s_Republic_of_China.svg/1200px-Flag_of_the_People%27s_Republic_of_China.svg.png", x= 0.27, y = 0.84, width = 0.05, height = 0.05) + draw_image("https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Flag_of_the_Vatican_City.svg/500px-Flag_of_the_Vatican_City.svg.png",x= 0.27, y = 0.75, width =0.05, height = 0.05, scale = 1.3) + draw_image("https://upload.wikimedia.org/wikipedia/en/thumb/c/c3/Flag_of_France.svg/800px-Flag_of_France.svg.png", x=0.27, y=0.66, width=0.05, height = 0.05) + draw_image("https://upload.wikimedia.org/wikipedia/en/thumb/a/a4/Flag_of_the_United_States.svg/125px-Flag_of_the_United_States.svg.png", x=0.27, y=0.575, width=0.045, height = 0.05, scale = 0.9) + draw_image("https://upload.wikimedia.org/wikipedia/en/thumb/0/03/Flag_of_Italy.svg/125px-Flag_of_Italy.svg.png", x=0.27, y=0.49, width=0.05, height = 0.05) + draw_image("https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Flag_of_Greece.svg/125px-Flag_of_Greece.svg.png", x=0.27, y=0.40, width=0.05, height = 0.05) + draw_image("https://upload.wikimedia.org/wikipedia/en/thumb/4/41/Flag_of_India.svg/125px-Flag_of_India.svg.png", x=0.27, y=0.315, width=0.05, height = 0.05) + draw_image("https://upload.wikimedia.org/wikipedia/en/thumb/c/c3/Flag_of_France.svg/800px-Flag_of_France.svg.png", x=0.27, y=0.225, width=0.05, height = 0.05) + draw_image("https://upload.wikimedia.org/wikipedia/en/thumb/b/ba/Flag_of_Germany.svg/125px-Flag_of_Germany.svg.png", x=0.27, y=0.14, width=0.05, height = 0.05) + draw_image("https://upload.wikimedia.org/wikipedia/en/thumb/f/f3/Flag_of_Russia.svg/125px-Flag_of_Russia.svg.png", x=0.27, y=0.06, width=0.05, height = 0.05)
#Por último añadimos un fondo
graficomon <- ggdraw() + draw_image(img) + draw_plot(plotd)
dir.create(here::here("imagenes"))
#Guardamos el gráfico
ggsave(filename = "graficmonworld.png",plot = graficomon, device = "png", path = here::here("imagenes"), width = 50.8, height = 28.575, units = "cm")

Monumentos más visitados del mundo

También hemos hecho un mapa donde se muestra las ubicaciones de los ya mencionados monumentos.

#Aprovechamos los datos empleados para el gráfico anterior y los arreglamos un poco
world <- map_data("world") %>% mutate(color = case_when(region == "China" ~ 1,
                                                        region == "Vatican" ~ 2,
                                                        region == "France" ~ 3,
                                                        region == "USA" ~ 4,
                                                        region == "Italy" ~ 5,
                                                        region == "Greece" ~ 6,
                                                        region == "India" ~ 7,
                                                        region == "Germany" ~ 8,
                                                        region == "Russia" ~ 9)) %>% mutate(color = if_else(is.na(color),0,color))

#Hacemos un dataframe con las coordenadas de cada monumento
ciudades <- c("Pekín","El Vaticano","Versailles","Washington","Roma","Atenas","Agra","París","Colonia","San Petesburgo")
lat <- c(39.9042,41.9029,48.8014,38.9072,41.9028,37.9838,27.1767,48.8566,50.9375,59.9311)
long <- c(116.4074,12.4534,2.1301,-77.0369,12.4964,23.7275,78.0081,2.3522,6.9603,30.3609)

coordciudades <- data.frame(ciudades,lat,long)
#Hacemos las líneas que uniran las imágenes con la ubicación de cada monumento.
lineas <- data.frame(id = c("Pekín","El Vaticano","Versailles","Washington","Roma","Atenas","Agra","París","Colonia","San Petesburgo"),
                     lat_1 = c(39.9042,41.9029,48.8014,38.9072,41.9028,37.9838,27.1767,48.8566,50.9375,59.9311),
                     long_1 = c(116.4074,12.4534,2.1301,-77.0369,12.4964,23.7275,78.0081,2.3522,6.9603,30.3609),
                     lat_2 = c(45,13,45,25,20,50,0,75,100,90),
                     long_2 = c(150,40,-50,-130,-20,60,115,-50,-10,40))
#Cargamos la imágen de cada monumento y le añadimos un borde.
china <- image_read("https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/Forbidden_City_Beijing_Shenwumen_Gate.JPG/800px-Forbidden_City_Beijing_Shenwumen_Gate.JPG") %>% image_border("#ffffff","10x10")
vaticano <- image_read("https://upload.wikimedia.org/wikipedia/commons/thumb/f/f5/Basilica_di_San_Pietro_in_Vaticano_September_2015-1a.jpg/1200px-Basilica_di_San_Pietro_in_Vaticano_September_2015-1a.jpg") %>% image_border("#ffffff","10x10")
versaill <- image_read("https://upload.wikimedia.org/wikipedia/commons/thumb/2/28/Parc_chateau_versailles.jpg/800px-Parc_chateau_versailles.jpg") %>% image_border("#ffffff","10x10")
wash <- image_read("https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Lincoln_Memorial_%28May_2014%29_crop.jpg/800px-Lincoln_Memorial_%28May_2014%29_crop.jpg") %>% image_border("#ffffff","10x10")
roma <- image_read("https://upload.wikimedia.org/wikipedia/commons/thumb/7/74/Colosseo_2008.jpg/800px-Colosseo_2008.jpg") %>% image_border("#ffffff","10x10")
atenas <- image_read("https://historiaeweb.com/wp-content/uploads/2018/02/Vista-general-del-Parten%C3%B3n-de-Atenas.jpg") %>% image_border("#ffffff","10x10")
agra <- image_read("https://upload.wikimedia.org/wikipedia/commons/thumb/1/1d/Taj_Mahal_%28Edited%29.jpeg/800px-Taj_Mahal_%28Edited%29.jpeg") %>% image_border("#ffffff","10x10")
paris <- image_read("https://upload.wikimedia.org/wikipedia/commons/thumb/8/85/Tour_Eiffel_Wikimedia_Commons_%28cropped%29.jpg/360px-Tour_Eiffel_Wikimedia_Commons_%28cropped%29.jpg") %>% image_border("#ffffff","10x10")
colonia <- image_read("https://megaconstrucciones.net/images/edificios-religiosos/foto/colonia-catedral.jpg") %>% image_border("#ffffff","10x10")
pete <- image_read("https://upload.wikimedia.org/wikipedia/commons/thumb/f/f5/Grand_Cascade_in_Peterhof_01.jpg/800px-Grand_Cascade_in_Peterhof_01.jpg") %>% image_border("#ffffff","10x10")
#Hacemos el gráfico principal
mapam <- ggplot() + geom_map(data = world, map = world, aes(long, lat, map_id = region), color = "#000000", fill = "#f7eca1") +
                    geom_map(data = world %>% filter(color==1), map = world, aes(long, lat, map_id = region), color = "#000000", fill = "red") +
                    geom_map(data = world %>% filter(color==2), map = world, aes(long, lat, map_id = region), color = "#000000", fill = "yellow") +
                    geom_map(data = world %>% filter(color==3), map = world, aes(long, lat, map_id = region), color = "#000000", fill = "#9d05ff") +
                    geom_map(data = world %>% filter(color==4), map = world, aes(long, lat, map_id = region), color = "#000000", fill = "#ab6800") +
                    geom_map(data = world %>% filter(color==5), map = world, aes(long, lat, map_id = region), color = "#000000", fill = "yellow") +
                    geom_map(data = world %>% filter(color==6), map = world, aes(long, lat, map_id = region), color = "#000000", fill = "#004dff") +
                    geom_map(data = world %>% filter(color==7), map = world, aes(long, lat, map_id = region), color = "#000000", fill = "#ff9300") +
                    geom_map(data = world %>% filter(color==8), map = world, aes(long, lat, map_id = region), color = "#000000", fill = "#a4034b") +
                    geom_map(data = world %>% filter(color==9), map = world, aes(long, lat, map_id = region), color = "#000000", fill = "#238a00") +
                    geom_segment(data = lineas, aes(x = long_1, y = lat_1, xend = long_2, yend = lat_2), color = "#000000", size = 2, alpha = 0.8, lineend = "round") +
                    geom_point(data = coordciudades, aes(x = long,y = lat), size = 2) +
                    ylim(-55,NA) +
                    theme(panel.background = element_rect(fill = "#a6fffb"), panel.grid = element_line(colour = "#000000"), axis.title = element_blank(),
                    axis.text = element_blank(), axis.ticks = element_blank())
#Añadimos las imágenes de los monumentos al gráfico principal.
plotmap <- ggdraw(mapam) +  draw_image(china, x = 0.8, y = 0.55, width = 0.15, height = 0.15) +
                            draw_image(vaticano, x = 0.55, y = 0.4, width = 0.1, height = 0.1) +
                            draw_image(versaill, x = 0.35, y = 0.6, width = 0.10, height = 0.10) +
                            draw_image(wash, x = 0.1, y = 0.5, width = 0.15, height = 0.15) +
                            draw_image(roma, x = 0.4, y = 0.45, width = 0.1, height = 0.1) +
                            draw_image(atenas, x = 0.6, y = 0.6, width = 0.10, height = 0.10) +
                            draw_image(agra, x = 0.7, y = 0.3, width = 0.15, height = 0.15) +
                            draw_image(paris, x = 0.3, y = 0.8, width = 0.15, height = 0.15) +
                            draw_image(colonia, x = 0.4, y = 0.83, width = 0.15, height = 0.15) +
                            draw_image(pete, x = 0.55, y = 0.85, width = 0.1, height = 0.1)
#Guardamos el gráfico
ggsave(filename = "mapmonworld.png",plot = plotmap, device = "png", path = here::here("imagenes"), width = 50.8, height = 28.575, units = "cm")

Ubicación de los 10 monumentos más visitados del mundo

Ingresos y gastos por el turismo

España es el segundo país con más ingresos por el turismo

Se mantiene en el podio gracias a los 83 millones de extranjeros que visitaron el país y a los cerca de 67.300 millones que dejaron

El turismo es una mina de oro para España. Nuestro país logró mantenerse en la tercera posición en la clasificación mundial tanto por el número de turistas internacionales como por la cantidad de ingresos por el turismo. En concreto, 83 millones de viajeros visitaron España en 2018, un 1% más que el año anterior, y dejaron alrededor de 67.300 millones de euros, un 4% más, según indica la Organización Mundial del Turismo (OMT).

Por llegadas, nuestro país sólo se situó por detrás de Francia, que registró 89 millones de turistas (+3%), y se colocó por delante de Estados unidos (80 millones y un aumento del 4%). En cuanto a los ingresos, es EE UU el que lidera el ranking y Francia se sitúa por detrás de España. Estados Unidos ingresó el año pasado 214.000 millones de dólares por turismo (un 2% más) y Francia, 67.000 millones (un 6% más). Los siguientes destinos en cuanto a las llegadas son China, Italia, Turquía, México, Alemania, Tailandia y el Reino Unido.

En cuanto a ingresos, Tailandia se encuentra en cuarto lugar, seguida del Reino Unido, Italia, Australia, Alemania, Japón –que entró en el grupo de los diez primeros después de siete años de crecimiento– y China, con un incremento del 21%.

#Importamos los datos de los ingresos
url3 <- "https://raw.githubusercontent.com/Pavlinadinkova/10/main/ingresos_paises.csv"
rr<- rio::import(url3, setclass="tibble")

 ingresos <- ggplot(rr, aes(x=reorder(Pais,Miles_millones_dolares), y=Miles_millones_dolares, fill=Pais))+
  geom_bar(stat="identity") +
  theme(legend.position = "none") +
  coord_polar(start = 0) +
  labs (x="Paises") + labs(y="Miles de millones de dólares") + labs(title = "Paises con más ingresos por el sector turístico ") + labs(subtitle = "En miles de millones de dólares")

ingresos

Gasto turístico en Europa

En primer lugar hemos hecho un gráfico de puntos en el que hemos intentado buscar si había relación entre la renta per capita de los países y el gasto en turismo de sus habitantes.

Para ello hemos obtenido datos del PIB, la población y el gasto turístico de los países de la Unión Europea. Los datos los hemos obtenido a través de la API de Eurostat como ya hemos comentado en el apartado 2.

Gráfico de puntos

En este gráfico podemos ver como si que hay una relación positiva entre el PIB per capita y el gasto en turismo de sus habitantes, esto se debe a que el turismo no es un servicio de primera necesidad. Este gráfico nos parece útil para saber que países deberían ser objetivo de las campañas de publicidad del sector turístico español.

Mapa de Europa

En este mapa hemos ilustrado los datos obtenidos anteriormente. Mirando el gráfico rápidamente podemos identificar los países que más gastan en turismo por habitante. Cabe destacar que los países del Norte de Europa son los que más gastan en turismo, así como que los países del Este son los que menos.

#En los siguientes códigos obtenemos los datos de la API de eurostat y los arreglamos un poco
#PIB en Millones
GDP <- eurostat::get_eurostat("nama_10_gdp")
GDP <- GDP %>% filter( na_item == "B1GQ", unit == "CP_MEUR") %>% select(geo,time,values)
GDP <- GDP %>% rename( code = geo)
cid <- eurostat::eu_countries
GDP <- inner_join(GDP,cid, by = "code" )
GDP <- GDP %>% select(-c(label)) %>% relocate(name, .before = code)
GDP <- GDP %>% rename_at(vars(colnames(GDP)), ~ c("Country","Code","Date","PIB"))
#GASTO TURISTICO Miles
GT <- eurostat::get_eurostat("tour_dem_extot")
GT <- GT %>% filter(duration == "N_GE1", purpose == "TOTAL",unit =="THS_EUR", partner == "WORLD")
GT <- GT %>% select(geo,time,values) %>% rename( code = geo)
cid <- eurostat::eu_countries
GT <- inner_join(GT,cid, by = "code" )
GT <- GT %>% select(-c(label)) %>% relocate(name, .before = code)
GT <- GT %>% rename_at(vars(colnames(GT)), ~ c("Country","Code","Date","GT"))


#POBLACIÓN
POB <- eurostat::get_eurostat("demo_gind")
POB <- POB %>% filter( indic_de == "JAN") %>% select(-c(indic_de))
POB <- POB %>% rename(code = geo)
cid <- eurostat::eu_countries
POB <- inner_join(POB,cid, by = "code" )
POB <- POB %>% select(-c(label)) %>% relocate(name, .before = code)
POB <- POB %>% rename_at(vars(colnames(POB)), ~ c("Country","Code","Date","POB"))

#Juntamos todos los datos que hemos obtenido en un único dataframe.
##JOIN
data2 <- inner_join(GT,GDP, by = c("Date","Country","Code")) %>% inner_join(POB, by = c("Date","Country","Code") )
data2 <- data2 %>% mutate( GT = (GT/1000)) #GT en Millones, igual que PIB
data2 <- data2 %>% mutate( GTporcPIB = (GT/PIB), GTpc = (GT/POB), PIBpc = (PIB/POB))#PIBpc en Millones
data2 <- data2 %>% separate(Date, c("Year","Month","Day"), sep = "[-]") %>% select(-c("Month","Day"))  %>% filter(Year == "2018") 
#Hacemos los gráficos
###GRÁFICO DE PUNTOS
plot <- ggplot(data2,aes(x=PIBpc,y=GTpc)) +
        geom_point() +
        geom_smooth(method = "lm", formula = "y~x", show.legend = TRUE, colour = "red", alpha = 0.3) +
        geom_text(label = data2$Country, nudge_y = 0.0002, check_overlap = TRUE) +
        labs(fill="% PIB",
        x="PIBpc",
        y="Gasto en Turismo pc",
        title="Gasto en turismo",
        caption="Fuente: Eurostat") +
        theme( plot.background = element_rect( fill = "#ffffff"),
              panel.background = element_rect( fill = "#fffbdc", colour = "lavenderblush", size = 0.1 ),
              panel.grid  = element_line( colour ="#dadada"),
              axis.ticks = element_blank(),
              axis.text = element_blank(),
              plot.title = element_text(hjust = 0.5),
              panel.border = element_rect(fill = NA,colour = "black"),
              legend.background = element_rect( fill = "cornsilk2", colour = "black" ),
              plot.margin = margin(t = 5, r = 25, b = 5,15) )
plot

###MAPA
#Filtramos por los países europeos
mapdata <- map_data("world") %>% filter(region %in% c("Austria","Belgium","Bulgaria","Croatia","Cyprus",
                   "Czech Republic","Denmark","Estonia","Finland","France",
                   "Germany","Greece","Hungary","Ireland","Italy","Latvia",
                   "Lithuania","Luxembourg","Malta","Netherlands","Poland",
                   "Portugal","Romania","Slovakia","Slovenia","Spain",
                   "Sweden","UK","Switzerland","Bosnia and Herzegovina","Serbia","Ukraine","Belarus","Albania","Montenegro","Kosovo","Macedonia","Moldova"))
#Juntamos los datos obtenidos anteriormente con los datos del mapa.
mapdata2 <- full_join(mapdata,data2 %>% mutate(Country = if_else(Country=="Czechia", true = "Czech Republic", false = Country)), by = c("region"="Country"))
#Hacemos el gráfico
mapaplot <- ggplot(mapdata2, aes(x = long, y = lat, group=group, fill = GTpc) ) +
            geom_polygon(color ="#ffffff") +
            scale_fill_gradient(low = "#313200",high = "#f7ff00") +
            labs(fill="Gasto en turismo pc",
            x=NULL,
            y=NULL,
            title="Gasto en turismo per capita en la UE",
            caption="Fuente: Elaboración propia, datos de Eurostat") +
            theme( plot.background = element_rect( fill = "#ffffff"),
              panel.background = element_rect( fill = "cornsilk2", colour = "lavenderblush", size = 0.1 ),
              panel.grid  = element_line( colour ="grey"),
              axis.ticks = element_blank(),
              axis.text = element_blank(),
              plot.title = element_text(hjust = 0.5),
              panel.border = element_rect(fill = NA,colour = "black"),
              legend.background = element_rect( fill = "cornsilk2", colour = "black" ),
              plot.margin = margin(t = 5, r = 5, b = 5,10) )
mapaplot

4.Turismo en España

España es un país que puede presumir de su riqueza cultural , teniendo algunas de las catedrales más bonitas del mundo, quince ciudades que son Patromonio de la Humanidad para la ONU o 52 Reservas de la Biosfera declaradas por la UNESCO. Por eso, no es de extrañar que cada año millones de turistas visitan España, y no sólo por el buen tiempo, las playas o el ocio, sino también para visitar los monumentos culturales.

Importancia del turismo

Actualmente el turismo es una de las actividades económicas y culturales más importantes para el desarrollo de un país o un región. El turismo se puede presentar en muchas variantes, tales como : turismo cultural, de aventura, de entretenimiento, de relajación.

Independientemente de las posibles variantes que haya del turismo, la importancia de esta actividad reside en dos pilares principales. El primero es aquel que tiene que ver con el movimiento y la reactivación económica que genera en la región específica en la que se realiza. Así, todos los países y regiones del planeta cuentan con el turismo como una actividad económica más que genera empleos, obras de infraestructura, desarrollo de establecimientos gastronómicos y hoteleros, crecimiento del transporte aéreo, terrestre o marítimo, etc. Obviamente, hay regiones en el mundo que están catalogadas como algunos de los puntos de turismo más importantes o dinámicos mientras que otros no, y esto tendrá que ver con la atención que cada país puede prestarle a esta actividad, creando más posibilidades para que los visitantes disfruten.

Efectos positivos del turismo

  • El turismo es un gran generador de empleo

El turismo ha sido el principal creador de empleo en España desde el estallido de la crisis, mitigando sus efectos sobre una parte importante de la sociedad española. De hecho en los años transcurridos desde 2009 a 2016, el empleo de las ramas de actividad turísticas se ha elevado un 13,4%.

Es un sector abierto que facilita la incorporación al mercado laboral de colectivos con dificultades de inserción laboral (p.ej. jóvenes, mujeres, mayores de 45 años,personal con bajos niveles de estudios) a la vez que contribuye a conciliar y compaginar el desempeño laboral con otras actividades personales.

De todas las actividades relacionadas con el sector turístico la más relevante con diferencia por volumen de empleo es el de la restauración que representa con 1,2 millones de empleos casi la mitad del empleo turístico (el 45,8%), de forma que sus características y condicionantes laborales afectan en gran medida la imagen del conjunto del sector (alojamientos, restaurantes, empresas de transporte, de alquiler de coches, comercios o actividades de ocio).

Dentro de las diferentes actividades que se desarrollan en el sector turístico, el transporte de viajeros ha sido clave para que aumente el empleo, ya que tanto en hoteles como en bares y restaurantes menguó.

Sin embargo, una parte creciente de la sociedad no valora positivamente su notable contribución social debido a la congestión y a la existencia de algunas prácticas laborales.

De hecho, las últimas estadísticas muestran una clara desaceleración en la creación de empleo. Sigue aumentando la ocupación, pero no como lo hacía desde que comenzó la recuperación.

el_url <- "https://raw.githubusercontent.com/xi765/TrabajoGrupo/main/empleo_tur.csv"

empleo <- rio::import(el_url)

#Gráfico

empleo1 <- empleo %>% ggplot(aes(x = Periodo, y = Total, colors(Periodo))) + geom_line() + geom_point(aes(fill = Periodo))+ labs(title = "Número de ocupados en el sector turístico",    caption = "Source:Datos INE",x = "Fecha ",y = NULL,color = "Periodo", subtitle= "Desde 2015 a 2019")
empleo1

  • Gran promotor de la marca país

El turismo también es un aspecto clave en la promoción de un país para el mejoramiento de la reputación y el posicionamiento, promoviendo todas sus fortalezas como cultura, deportes, empresas, destinos históricos, eventos, educación, inversión, etc., y así poderle dar al mundo incentivos para visitar o invertir.

  • PIB

Según los datos extraídos de la página oficial del Instituto Nacional de Estadística (INE), el turismo aporta un 12,5% al PIB nacional.Es el sector que más riqueza aporta a la economía española.En términos de contribución al PIB y empleo, la industria turística es la más importante del país gracias al crecimiento imparable de la llegada de viajeros extranjeros.


#Importamos datos de PIB
url5 <- "https://raw.githubusercontent.com/Pavlinadinkova/10/main/pibturi.csv"
pp<- rio::import(url5, setclass="tibble")
names(pp)= c("Componente_PIB","Vtype","Fecha","Total")
#Grafico PIB
gg <- ggplot(pp, aes(x=Fecha, y=Total, color= Fecha))  + geom_point( ) + geom_line() +
  labs(title = "Aportacion del turismo en el PIB de España" , subtitle="Datos en porcentajes", x="% del PIB", y="Años")
gg

Número de turistas

Han aumentado el número de turistas internacionales considerablemente en los últimos años. Concretamente, 30,7 millones de personas más visitan nuestro país desde 2009.

De hecho, España logró en 2019 batir por séptimo año consecutivo su récord histórico en llegadas de turistas internacionales, con un registro de 83,7 millones de visitantes, lo que supone un crecimiento del 1,1% con respecto al año anterior, según los datos de la encuesta Frontur publicada por el Instituto Nacional de Estadística (INE).

Y en cuanto al número de turistas por nacionalidad, como podemos ver en el gráfico, el Reino Unido es el principal emisor de turistas a España. En julio de 2019, el número de turistas británicos que visitaron España fue de 2.166.289, seguido por alemanes (1.242.766 visitantes) y franceses (1.420.601 turistas).
el_url <- "https://raw.githubusercontent.com/AnaMaria1198/Trabajo/main/10822bd%20(2).csv"
datos <- rio::import(el_url)

datos <- datos %>% mutate( Total = stringr::str_remove_all(Total, pattern = "([.])"))
datos <- datos %>% mutate( Total = stringr::str_replace_all(Total , pattern = "[,]" , replacement = "." ))
datos <- datos %>% mutate( Total = as.numeric(Total))


#Arreglar-lo
datos <- datos %>% mutate( VType = stringr::str_replace_all(VType , pattern = "[³]" , replacement = "" ))
datos <- datos %>% mutate( VType = stringr::str_replace_all(VType , pattern = "[±]" , replacement = "ny" ))
datos <- datos %>% mutate( VType = stringr::str_replace_all(VType , pattern = "[Ã]" , replacement = "o" ))
datos <- datos %>% mutate( Country = stringr::str_replace_all(Country , pattern = "[é]" , replacement = "e" ))
datos <- datos %>% mutate( Country = stringr::str_replace_all(Country , pattern = "[³]" , replacement = "o" ))

#Arreglar datos
aa <- datos %>% filter(VType == "Dato base")
bb <- aa %>% separate(Date, c("year","month"), sep = "[-]") %>% select(-c(month))

cc <- bb %>% group_by(year, Country) %>% filter(Country!=Total) %>% mutate(SumaTotal= sum(Total)) %>% mutate(year = unique(year))

#GRÁFICOS
filtro <- cc %>% filter(Country!="Total") %>% select(-c(Total)) %>% unique() %>% group_by(year) %>% mutate (Country = factor(Country, levels = Country[order(SumaTotal)]))
p <- filtro %>% ggplot(.,aes(x = year, y = SumaTotal ))+
    geom_bar(aes(fill = Country), stat = "identity")+
    labs(title = "España 2015-2020",
    subtitle = "Número de turistas por país", source = "INE") +
    scale_y_continuous(expand = c(0,2000000),breaks = seq(0,90000000,5000000), labels = paste((seq(0,90000000,5000000)/1000000),"M"))


plotly::ggplotly(p)
#Gráfico de lineas
filtro <- cc %>% filter(Country!="Total")
cc1 <- filtro %>%
  group_by(year) %>%
  arrange(year, desc(SumaTotal)) %>%
  mutate(ranking = row_number()) %>%
  filter(ranking <=21)

pl <- ggplot(cc1, aes(x=year, y=SumaTotal , group=Country, color=Country)) + geom_line() + facet_grid(Country ~ .) +
  expand_limits(y=2) + theme(legend.position = "none") + labs(title = "Paises con mayor número de turistas ",    caption = "Source:Datos INE",
              x = "Fecha ",
              y = NULL,
              color = "Continente",
              subtitle = "En millones de visitantes")



#Intente fer-ho per separa't
#Alemania
filtro2 <- filtro %>% filter(Country=="Alemania")
pl1 <- ggplot(filtro2, aes(x=year, y=SumaTotal , group=Country, color=Country)) + geom_line() + facet_grid(Country ~ .) +
  expand_limits(y=2) + theme(legend.position = "none") + labs(title = "Número de turistas de Alemania",    caption = "Source:Datos INE",
              x = "Fecha ",
              y = NULL,
              color = "Continente",
              subtitle = "En millones de visitantes")

plotly::ggplotly(pl1)

#Francia
filtro3 <- filtro %>% filter(Country=="Francia")
pl2 <- ggplot(filtro3, aes(x=year, y=SumaTotal , group=Country, color=Country)) + geom_line() + facet_grid(Country ~ .) +
  expand_limits(y=2) + theme(legend.position = "none") + labs(title = "Número de turistas de Francia",    caption = "Source:Datos INE",
              x = "Fecha ",
              y = NULL,
              color = "Continente",
              subtitle = "En millones de visitantes")

plotly::ggplotly(pl2)

#Reino Unido
filtro4 <- filtro %>% filter(Country=="Reino Unido")
pl3 <- ggplot(filtro4, aes(x=year, y=SumaTotal , group=Country, color=Country)) + geom_line() + facet_grid(Country ~ .) +
  expand_limits(y=2) + theme(legend.position = "none") + labs(title = "Número de turistas del Reino Unido ",    caption = "Source:Datos INE",
              x = "Fecha ",
              y = NULL,
              color = "Continente",
              subtitle = "En millones de visitantes")

plotly::ggplotly(pl3)

#Intentar Unir
library(patchwork)
(pl1)/(pl2)/(pl3)

Motivos de sus llegadas

Según los datos proporcionados por el INE , los turistas que visitan España en su gran mayoria lo hacen para disfutar del ocio.De hecho el ocio abarca el turismo en todas sus múltiples facetas:Turismo cultural, Turismo de salud, Turismo de sol y playa, Turismo itinerante, Turismo residencial, Turismo rural, Turismo urbano….

Los viajes realizados con fines de negocio son el segundo gran motivo, aunque sin ser capaz de superar al ocio. Mientras que el último lugar, los extranjeros visitan España con otros fines distintos, entre los que podemos destacar :Compras, Formación y Educación, Incentivos de empresa, religiosos y de salud.

#Importamos los datos de los motivos del turismo
url <- "https://raw.githubusercontent.com/Pavlinadinkova/10/main/csv.csv"
aa<- rio::import(url, setclass="tibble")
names(aa)= c("Reason","VType", "Fecha","Total")
data <- aa %>% mutate( Total = stringr::str_remove_all(Total, pattern = "([.])"))
data <- data %>% mutate( Total = stringr::str_replace_all(Total , pattern = "[,]" , replacement = "." ))
data <- data %>% mutate( Total = as.numeric(Total))

cc<- data %>% filter(Reason !="Total")

g <- ggplot(cc, aes( Fecha, Total))
g + geom_bar(aes(fill=Reason),stat = "identity", width = 0.5) +
  theme(axis.text.x = element_text(angle=65, vjust=0.6)) +
  labs(title="Motivos de viajes",
       subtitle="Viajes")

Principales destinos turisticos

En este gráfico tipo Lollipop podemos ver las comunidades autónomas que más turistas recibieron en 2019. Podemos ver como Cataluña ha sido la comunidad que más turistas ha recibido, también cabe destacar que tan solo 6 comunidades autónomas reciben prácticamente la totalidad de turistas que viajan a España.

Los datos para realizar este gráfico los hemos obtenido del INE.

#Cargamos los datos alojados en github
url <- "https://raw.githubusercontent.com/xi765/TrabajoGrupo/main/tur_ccaa_2019.csv"
#Arreglamos los datos: Cambiamos nombres, quitamos signos de puntuación y ordenamos en factores.
data <- rio::import(url) %>% select(-c(2)) %>% setNames(c("CCAA","año","valor")) %>% 
                             mutate(valor = stringr::str_remove_all(valor,"[.]"), 
                                    valor = as.numeric(valor),
                                    CCAA = factor(CCAA, levels = CCAA[order(valor, decreasing = TRUE)]))

ejey <- seq(0,20,2.5)
# Hacemos el gráfico
theme_set(theme_classic())
ggplot(data, aes(x=CCAA, y=valor)) +
  scale_x_discrete(labels = c("Cataluña","Baleares","Canarias","Andalucía","Valencia","Madrid","Galicia","País Vasco","CyL","Murcia","Aragón","Extremadura","Navarra","Cantabria","Asturias","CyM","La Rioja"))+
  scale_y_continuous(labels = paste0(ejey,"M"),breaks = 10^6*ejey) +
  geom_point(size=3) +
  geom_segment(aes(x=CCAA,
                   xend=CCAA,
                   y=0,
                   yend=valor))+
  labs(title="Comunidades autónomas más visitadas",
       subtitle="Año: 2019",
       caption="Fuente: INE",
       x="Comunidad autonoma",
       y="Visitantes anuales") +
  theme(panel.grid.major.y = element_line(colour = "#dadada"),axis.text.x = element_text(angle=65, vjust=0.6))

Monumentos más visitados

España es el paraíso de la arquitectura, literalmente. Pocos países reúnen de manera tan compacta tantos estilos arquitectónicos y edificios tan sobrecogedoramente bellos como lo hace España. Pasear por cualquiera de sus ciudades es como emprender un viaje por el tiempo a través de sus calles adoquinadas, monumentos históricos y piezas arquitectónicas únicas. De hecho, algunos de los monumentos de la lista fueron pioneros en su época.

En el gráfico podemos ver cuáles son los 10 monumentos más visitados en España, medido en millones de turistas anuales. Además, se ha añadido una foto del monumento.

Podemos observar que, el monumento más visitado en España es la Sagrada Familia en Barcelona con unos 4,5 millones de visitantes anuales. Sin embargo, es visitada tanto por nacionales como por internacionales, pues es considerada como uno de los monumentos más bonitos y famosos a nivel nacional e incluso internacional.

#Importamos datos de monumentos
url4 <- "https://raw.githubusercontent.com/Pavlinadinkova/10/main/monumentos.csv"
mm<- rio::import(url4, setclass="tibble")  %>%  mutate(Monumento = c("Palacio Real de Madrid","Museo de Reina Sofia","Camp Nou","Reales Alcázares","Mezquita de Córdoba","Catedral de Sevilla","Alhambra de Granada","Ciudad de las Artes y Ciencias","Catedral Santiago de Compostela","Museo de Prado","Sagrada Familia"),Monumento = factor(Monumento, levels = Monumento[order(Numero_visitantes, decreasing = TRUE)]), Numero_visitantes = stringr::str_remove_all(Numero_visitantes, pattern = "[^[:alnum:]]"), Numero_visitantes = as.numeric(Numero_visitantes), )

#Ejecutamos el gráfico de los monumentos más visitados
ml <- ggplot(mm,aes(Monumento,Numero_visitantes,color = Monumento,fill= Monumento)) +
  geom_bar(position = "stack",  width =.18,stat="identity") +
  coord_flip()+
  geom_text(aes(label= Numero_visitantes ,hjust=-.03,  colour="black"),size=3.2)+

  theme(axis.line = element_line(color = "orange",size=1))+
      theme(panel.background=element_blank())+
      scale_x_discrete() +
    xlab(NULL)+ylab(NULL)+
  theme(legend.position = "none",
                     axis.text = element_text(size = 8,face="bold"),
        plot.title = element_text(size=14,face = "bold")) +
  ggtitle("Monumentos más visitados en España " ,subtitle = "Por número de visitantes en el año 2019")


#A este gráfico  le añadimos el comando ''draw_image'' para poner las imágenes.

Ingresos por país

Para reflejar los países que más ingresos turísticos dejan en España hemos hecho varios gráficos tipo Queso. En estos gráficos podemos observar como más del 50% de los ingresos de nuestro sector turístico vienen de nuestros vecinos europeos, haciendose evidente lo dependientes que somos de Europa en este sentido.

#Cargamos los datos alojados en github
url <- "https://raw.githubusercontent.com/xi765/TrabajoGrupo/main/23994bd.csv"
data <- rio::import(url)
#Arreglamos los datos: Cambiamos nombres y eliminamos signos de puntuación.
data <- data %>% rename(Date = Periodo)
data <- data %>% relocate( Date, .before = `Gastos y duración media de los viajes`)
data <- data %>% rename( Country = `País de residencia` , VType = `Tipo de dato` , Variable = `Gastos y duración media de los viajes`)
data <- data %>% mutate( Total = stringr::str_remove_all(Total, pattern = "([.])"))
data <- data %>% mutate( Total = stringr::str_replace_all(Total , pattern = "[,]" , replacement = "." ))
data <- data %>% mutate( Total = as.numeric(Total))

#GRÁFICO DE BARRAS
#Acabamos de arreglar los datos para adaptarlos a este gráfico en concreto
aa <- data %>% filter(Variable == "Gasto total" , !Country %in% c("Total"),VType == "Dato base")
aa <- aa %>% mutate(Country = replace(Country, Country %in% c("Suiza","Rusia","Irlanda","Resto América","Resto de Europa","Resto del Mundo"),"Otros"))
aa <- aa %>% group_by(Country,Date) %>% summarise( Total = sum(Total))
aa <- aa %>% group_by(Date) %>% mutate( TotalY = sum(Total))
aa <- aa %>% mutate( perc. = (Total/TotalY))

#Ordenamos las variables mediante factores.
bb <- aa %>% group_by(Date) %>% mutate(Country = factor(Country, levels = Country[order(perc.)]))
#Hacemos el gráfico.
plot <- bb %>% ggplot(aes(x = Country, y = perc.,fill = Country)) +
               geom_bar(stat = "identity", color = "black") +
               facet_wrap(vars(Date),nrow = 2, ncol = 2) +
               scale_fill_brewer(palette = "Spectral", direction = -1) +
               scale_y_continuous(breaks = seq(0,1,0.05),labels = scales::percent) +
               labs(fill="Países",
               x=NULL,
               y="% sobre el total de gasto",
               title="Gasto en turismo por país",
               caption="Fuente: INE") +
               theme( plot.background = element_rect( fill = "#e8d7a3"),
              panel.background = element_rect( fill = "cornsilk2", colour = "lavenderblush", size = 0.1 ),
              panel.grid  = element_line( colour ="grey"),
              axis.ticks = element_blank(),
              axis.text.x = element_blank(),
              plot.title = element_text(hjust = 0.5),
              panel.border = element_rect(fill = NA,colour = "black"),
              legend.background = element_rect( fill = "cornsilk2", colour = "black" ),
              plot.margin = margin(t = 5, r = 25, b = 5,15),
              strip.background = element_rect(fill = "#e8d7a3",colour = NULL))
plot

Adicionalmente hemos hecho un gráfico de barras con los mismos datos. Observando el gráfico llegamos a las mismas conclusiones que con el anterior, siendo Alemania y Reino Unido los que más ingresos turísticos dejan en nuestro país.

#Cargamos los datos y los arreglamos.
url <- "https://raw.githubusercontent.com/xi765/TrabajoGrupo/main/10838bd.csv"
data <- rio::import(url)
data <- data %>% mutate( Date = stringr::str_replace_all(Periodo , pattern = "([A-Z])" , replacement = "-") , .keep = "unused" )
data <- data %>% relocate( Date, .before = `Gastos y duración media de los viajes`)
data <- data %>% rename( Country = `País de residencia` , VType = `Tipo de dato` , Variable = `Gastos y duración media de los viajes`)
data <- data %>% mutate( Total = stringr::str_remove_all(Total, pattern = "([.])"))
data <- data %>% mutate( Total = stringr::str_replace_all(Total , pattern = "[,]" , replacement = "." ))
data <- data %>% mutate( Total = as.numeric(Total))

aa <- data %>% separate( col = Date , into = c("Year","Month") , sep = "-")
aa <- aa %>% filter(Variable == "Gasto total" , Country != "Total" , Year %in% c(2016,2017,2018,2019),VType == "Dato base")
#Creamos variables nuevas
aa <- aa %>% group_by(Country,Year) %>% summarise( Total = sum(Total))
aa <- aa %>% group_by(Year) %>% mutate( TotalY = sum(Total))
aa <- aa %>% mutate( perc. = (Total/TotalY))

#Hacemos el gráfico
plot <- ggplot(aa, aes(x = "", y=perc., fill = factor(Country))) +
  geom_bar(width = 1, stat = "identity",color = "#000000") +
  coord_polar(theta = "y", start=0) +
  labs(fill="País",
       x=NULL,
       y=NULL,
       title="Gasto por país y año",
       caption="Fuente: INE") + facet_wrap(vars(Year),nrow = 2, ncol = 2) +
      scale_y_continuous(breaks = seq(0,0.8,0.2),labels = scales::percent) +
      scale_fill_brewer(palette = "Set1") +
      theme( strip.background = element_rect( fill = "#ffffff", colour = NULL),
              panel.background = element_rect( fill = "cornsilk2", colour = "black" ),
              panel.grid  = element_line( colour ="cornsilk2"),
              axis.ticks = element_line(colour = "cornsilk2"),
              axis.text = element_text(size = 10, face = "bold"),
              plot.title = element_text(hjust = 0.5),
              plot.background = element_rect(fill = "#ffffff"),
              panel.border = element_rect(fill = NA,color = "black"),
              legend.background = element_rect(fill = "cornsilk2", colour = "black"),
              strip.text = element_text(face = "bold",colour = "black"))
plot

5. El turismo en tiempos de COVID-19

España figura entre los países más golpeados por la pandemia en pérdida de turistas internacionales y de los ingresos que éstos generan. Según los últimos datos oficiales conocidos del Instituto Nacional de Estadística (INE), entre enero y septiembre llegaron a territorio español un total de 16.8 millones de extranjeros, un 74.9% menos que en el mismo periodo de 2019 - año récord-. Son 50.1 millones menos.

En una línea similar , el gasto de estos turistas se limitó a 17.775 millones de euros, un 75.9% menos, que se traduce en una caída de 55.980 millones menos.

Todo ello es consecuencia de las restricciones a la movilidad en todo el mundo. En este entorno de incertidumbre por la pandemia y de falta de confianza, este organismo prevé una caída global cercana al 70% en el conjunto de 2020 y la mayoría de los expertos consultados no esperan un repunte hasta el tercer trimestre de 2021 o incluso 2022, si bien todo dependerá de los avances en la vacuna.

knitr::include_graphics("https://www.garrigues.com/sites/default/files/turismo-digital-covid-19.jpg")

el_url <- "https://raw.githubusercontent.com/AnaMaria1198/Trabajo/main/10822bd%20(2).csv"


datos <- rio::import(el_url)
datos <- datos %>% mutate( Total = stringr::str_remove_all(Total, pattern = "([.])"))
datos <- datos %>% mutate( Total = stringr::str_replace_all(Total , pattern = "[,]" , replacement = "." ))
datos <- datos %>% mutate( Total = as.numeric(Total))
#Arreglar-lo
datos <- datos %>% mutate( VType = stringr::str_replace_all(VType , pattern = "[³]" , replacement = "" ))
datos <- datos %>% mutate( VType = stringr::str_replace_all(VType , pattern = "[±]" , replacement = "ny" ))
datos <- datos %>% mutate( VType = stringr::str_replace_all(VType , pattern = "[Ã]" , replacement = "o" ))
datos <- datos %>% mutate( Country = stringr::str_replace_all(Country , pattern = "[é]" , replacement = "e" ))
datos <- datos %>% mutate( Country = stringr::str_replace_all(Country , pattern = "[³]" , replacement = "o" ))

#Arreglar datos
aa <- datos %>% filter(VType == "Dato base")
bb <- aa %>% separate(Date, c("year","month"), sep = "[-]") %>% select(-c(month))

cc <- bb %>% group_by(year, Country) %>% filter(Country!=Total) %>% mutate(SumaTotal= sum(Total)) %>% mutate(year = unique(year)) %>% ungroup()

#GRÁFICOS
datos11 <- cc

df<- datos11 %>% filter(Country=="Total") %>% select(c(year,SumaTotal)) %>% unique() %>% mutate(year = as.numeric(year))

dd <- ggplot(df, aes(year, SumaTotal)) + geom_point() + geom_line() +
  theme_minimal() +
  transition_reveal(year)
dd

6. Conclusiones

Con este trabajo hemos podido analizar la importancia que el sector turistico tiene en el mundo, centrandonos en España, tanto dentro de esta, analizando los tipos de turismo, gastos o número de turistas, como en el exterior viendo su posición a nivel global. Tras los analisis realizados hemos podido comprobar que depende mucho del turismo.Estos países dependen en gran medida del tercer sector para crecer, ya que buena parte de su PIB está ligado a la llegada de visitantes y su gasto en el territorio.

Por otra parte hemos visto que la pandemia global en la que estamos viviendo ha afectado considerablemente la economia española ya que ha paralizado su sector más importante. Pero no solo eso,también hemos visto como ha pesar de ser un sector en crecimiento, este crecimiento se ha estado reduciendo en los últimos años, mucho antes de la llegada de la nueva situación sanitaria.

Así que creemos que es importante ser conscientes de esto y buscar alternativas en el mismo sector o en otros sectores para en un futuro evitar una situación similar a la de ahora.

7. Bibliografia

  • Página oficial del Instituto Nacional de Estadística. aquí
  • Ministerio de Industria, Comercio y Turismo. aquí
  • Artículo del periódico El País aquí
  • Agencia de Noticias Europa Pressaquí
  • Institut d’Estadistica de les Illes Balears aquí
  • APIE: Asociación de Periodistas de Información aquí



Para acabar este chunk para incluir tu session info:

sessioninfo::session_info() %>% details::details(summary = 'current session info') 

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-18                  

- Packages -------------------------------------------------------------------
 package      * version    date       lib source                        
 assertthat     0.2.1      2019-03-21 [1] CRAN (R 4.0.2)                
 backports      1.1.10     2020-09-15 [1] CRAN (R 4.0.2)                
 base64enc      0.1-3      2015-07-28 [1] CRAN (R 4.0.0)                
 bibtex         0.4.2.3    2020-09-19 [1] CRAN (R 4.0.2)                
 blob           1.2.1      2020-01-20 [1] CRAN (R 4.0.2)                
 broom          0.7.0      2020-07-09 [1] CRAN (R 4.0.2)                
 cellranger     1.1.0      2016-07-27 [1] CRAN (R 4.0.2)                
 class          7.3-17     2020-04-26 [1] CRAN (R 4.0.2)                
 classInt       0.4-3      2020-04-07 [1] CRAN (R 4.0.2)                
 cli            2.0.2      2020-02-28 [1] CRAN (R 4.0.2)                
 colorspace     1.4-1      2019-03-18 [1] CRAN (R 4.0.2)                
 countrycode    1.2.0      2020-05-22 [1] CRAN (R 4.0.2)                
 cowplot      * 1.1.0      2020-09-08 [1] CRAN (R 4.0.2)                
 crayon         1.3.4      2017-09-16 [1] CRAN (R 4.0.2)                
 crosstalk      1.1.0.1    2020-03-13 [1] CRAN (R 4.0.2)                
 curl           4.3        2019-12-02 [1] CRAN (R 4.0.2)                
 data.table     1.13.0     2020-07-24 [1] CRAN (R 4.0.2)                
 DBI            1.1.0      2019-12-15 [1] CRAN (R 4.0.2)                
 dbplyr         1.4.4      2020-05-27 [1] CRAN (R 4.0.2)                
 digest         0.6.27     2020-10-24 [1] CRAN (R 4.0.3)                
 dplyr        * 1.0.2      2020-08-18 [1] CRAN (R 4.0.2)                
 e1071          1.7-3      2019-11-26 [1] CRAN (R 4.0.2)                
 ellipsis       0.3.1      2020-05-15 [1] CRAN (R 4.0.2)                
 eurostat       3.6.1      2020-02-11 [1] CRAN (R 4.0.0)                
 evaluate       0.14       2019-05-28 [1] CRAN (R 4.0.2)                
 fansi          0.4.1      2020-01-08 [1] CRAN (R 4.0.2)                
 farver         2.0.3      2020-01-16 [1] CRAN (R 4.0.2)                
 forcats      * 0.5.0      2020-03-01 [1] CRAN (R 4.0.2)                
 foreign        0.8-80     2020-05-24 [1] CRAN (R 4.0.2)                
 fs             1.5.0      2020-07-31 [1] CRAN (R 4.0.2)                
 generics       0.0.2      2018-11-29 [1] CRAN (R 4.0.2)                
 gganimate    * 1.0.6      2020-07-08 [1] CRAN (R 4.0.2)                
 ggplot2      * 3.3.2      2020-06-19 [1] CRAN (R 4.0.2)                
 gifski         0.8.6      2018-09-28 [1] CRAN (R 4.0.2)                
 glue           1.4.2      2020-08-27 [1] CRAN (R 4.0.2)                
 gtable         0.3.0      2019-03-25 [1] CRAN (R 4.0.2)                
 haven          2.3.1      2020-06-01 [1] CRAN (R 4.0.2)                
 here           0.1        2017-05-28 [1] CRAN (R 4.0.2)                
 hms            0.5.3      2020-01-08 [1] CRAN (R 4.0.2)                
 htmltools      0.5.0      2020-06-16 [1] CRAN (R 4.0.2)                
 htmlwidgets    1.5.1      2019-10-08 [1] CRAN (R 4.0.2)                
 httr           1.4.2      2020-07-20 [1] CRAN (R 4.0.2)                
 jsonlite       1.7.1      2020-09-07 [1] CRAN (R 4.0.2)                
 KernSmooth     2.23-17    2020-04-26 [1] CRAN (R 4.0.2)                
 klippy       * 0.0.0.9500 2020-12-10 [1] Github (rlesur/klippy@378c247)
 knitr        * 1.30       2020-09-22 [1] CRAN (R 4.0.2)                
 labeling       0.3        2014-08-23 [1] CRAN (R 4.0.0)                
 lattice        0.20-41    2020-04-02 [1] CRAN (R 4.0.2)                
 lazyeval       0.2.2      2019-03-15 [1] CRAN (R 4.0.2)                
 lifecycle      0.2.0      2020-03-06 [1] CRAN (R 4.0.2)                
 lubridate      1.7.9      2020-06-08 [1] CRAN (R 4.0.2)                
 magick       * 2.4.0      2020-06-23 [1] CRAN (R 4.0.2)                
 magrittr       1.5        2014-11-22 [1] CRAN (R 4.0.2)                
 maps         * 3.3.0      2018-04-03 [1] CRAN (R 4.0.3)                
 Matrix         1.2-18     2019-11-27 [1] CRAN (R 4.0.2)                
 mgcv           1.8-31     2019-11-09 [1] CRAN (R 4.0.2)                
 modelr         0.1.8      2020-05-19 [1] CRAN (R 4.0.2)                
 munsell        0.5.0      2018-06-12 [1] CRAN (R 4.0.2)                
 nlme           3.1-148    2020-05-24 [1] CRAN (R 4.0.2)                
 openxlsx       4.2.2      2020-09-17 [1] CRAN (R 4.0.2)                
 patchwork    * 1.0.1      2020-06-22 [1] CRAN (R 4.0.2)                
 pillar         1.4.6      2020-07-10 [1] CRAN (R 4.0.2)                
 pkgconfig      2.0.3      2019-09-22 [1] CRAN (R 4.0.2)                
 plotly         4.9.2.1    2020-04-04 [1] CRAN (R 4.0.2)                
 plyr           1.8.6      2020-03-03 [1] CRAN (R 4.0.2)                
 prettyunits    1.1.1      2020-01-24 [1] CRAN (R 4.0.2)                
 progress       1.2.2      2019-05-16 [1] CRAN (R 4.0.2)                
 purrr        * 0.3.4      2020-04-17 [1] CRAN (R 4.0.2)                
 R6             2.4.1      2019-11-12 [1] CRAN (R 4.0.2)                
 RColorBrewer   1.1-2      2014-12-07 [1] CRAN (R 4.0.0)                
 Rcpp           1.0.5      2020-07-06 [1] CRAN (R 4.0.2)                
 readr        * 1.3.1      2018-12-21 [1] CRAN (R 4.0.2)                
 readxl         1.3.1      2019-03-13 [1] CRAN (R 4.0.2)                
 RefManageR     1.2.12     2019-04-03 [1] CRAN (R 4.0.2)                
 reprex         0.3.0      2019-05-16 [1] CRAN (R 4.0.2)                
 rio          * 0.5.16     2018-11-26 [1] CRAN (R 4.0.2)                
 rlang          0.4.9      2020-11-26 [1] CRAN (R 4.0.3)                
 rmarkdown      2.3        2020-06-18 [1] CRAN (R 4.0.2)                
 rprojroot      1.3-2      2018-01-03 [1] CRAN (R 4.0.2)                
 rstudioapi     0.11       2020-02-07 [1] CRAN (R 4.0.2)                
 rvest          0.3.6      2020-07-25 [1] CRAN (R 4.0.2)                
 scales         1.1.1      2020-05-11 [1] CRAN (R 4.0.2)                
 selectr        0.4-2      2019-11-20 [1] CRAN (R 4.0.2)                
 sessioninfo    1.1.1      2018-11-05 [1] CRAN (R 4.0.2)                
 sf             0.9-6      2020-09-13 [1] CRAN (R 4.0.2)                
 sp             1.4-2      2020-05-20 [1] CRAN (R 4.0.2)                
 stringi        1.5.3      2020-09-09 [1] CRAN (R 4.0.2)                
 stringr      * 1.4.0      2019-02-10 [1] CRAN (R 4.0.2)                
 tibble       * 3.0.3      2020-07-10 [1] CRAN (R 4.0.2)                
 tidyr        * 1.1.2      2020-08-27 [1] CRAN (R 4.0.2)                
 tidyselect     1.1.0      2020-05-11 [1] CRAN (R 4.0.2)                
 tidyverse    * 1.3.0      2019-11-21 [1] CRAN (R 4.0.2)                
 tweenr         1.0.1      2018-12-14 [1] CRAN (R 4.0.2)                
 units          0.6-7      2020-06-13 [1] CRAN (R 4.0.2)                
 vctrs          0.3.4      2020-08-29 [1] CRAN (R 4.0.2)                
 viridisLite    0.3.0      2018-02-01 [1] CRAN (R 4.0.2)                
 withr          2.3.0      2020-09-22 [1] CRAN (R 4.0.2)                
 xfun           0.17       2020-09-09 [1] CRAN (R 4.0.2)                
 xml2         * 1.3.2      2020-04-23 [1] CRAN (R 4.0.2)                
 yaml           2.2.1      2020-02-01 [1] CRAN (R 4.0.2)                
 zip            2.1.1      2020-08-27 [1] CRAN (R 4.0.2)                

[1] D:/R-4.0.2/library


LS0tDQp0aXRsZTogIlR1cmlzbW8gZW4gRXNwYcOxYSINCmF1dGhvcjogIkh1Z28gTWFydGluIENoaXN2ZXJ0ICwgUGF2bGluYSBEaW5rb3ZhIEdyb3pldmEsQW5hIE1hcsOtYSBCb3JyYXMgQ2Vib2xsYSIgDQpkYXRlOiAiMTAgZGUgRGljaWVtYnJlIGRlIDIwMjAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdGhlbWU6IHBhcGVyDQogICAgaGlnaGxpZ2h0OiB0ZXh0bWF0ZSANCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZGVwdGg6IDMgDQogICAgdG9jX2Zsb2F0OiANCiAgICAgIGNvbGxhcHNlZDogdHJ1ZQ0KICAgICAgc21vb3RoX3Njcm9sbDogdHJ1ZQ0KICAgIHNlbGZfY29udGFpbmVkOiB0cnVlDQogICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQ0KICAgIGRmX3ByaW50OiBrYWJsZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCmVkaXRvcl9vcHRpb25zOiANCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUNCi0tLQ0KDQo8Rk9OVCBDT0xPUj0iUHVycGxlIj5Qcm95ZWN0byByZWFsaXphZG8gcGFyYSBsYSBhc2lnbmF0dXJhJydQcm9ncmFtYWNpw7NuIHkgbWFuZWpvIGRlIGRhdG9zIGVuIGxhIGVyYSBkZWwgQmlnIERhdGEiIGltcGFydGlkYSBwb3IgZWwgcHJvZmVzb3IgUGVkcm8gSi4gUMOpcmV6IGVuIGVsIEdyYWRvIGRlIEVjb25vbcOtYSBkZSBsYSBVbml2ZXJzaWRhZCBkZSBWYWxlbmNpYS4gTGEgcMOhZ2luYSB3ZWIgZGUgbGEgYXNpZ25hdHVyYSBzZSBwdWVkZSB2ZXIgW2FxdcOtXSggaHR0cHM6Ly9wZXJlenA0NC5naXRodWIuaW8vaW50cm8tZHMtMjAtMjEtd2ViKSAuIExvcyB0cmFiYWpvcyBlbGFib3JhZG9zIHBvciBudWVzdHJvcyBjb21wYcOxZXJvcyBkZSBjdXJzbyBwdWVkZW4gdmVyc2UgW2FxdcOtXShodHRwczovL3BlcmV6cDQ0LmdpdGh1Yi5pby9pbnRyby1kcy0yMC0yMS13ZWIvMDctdHJhYmFqb3MuaHRtbCk8L0ZPTlQ+DQoNCmBgYHtyIHBhY2thZ2VzLXNldHVwLCBpbmNsdWRlID0gRkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoa2xpcHB5KSAgIy0gcmVtb3Rlczo6aW5zdGFsbF9naXRodWIoInJsZXN1ci9rbGlwcHkiKQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkoY293cGxvdCkNCmxpYnJhcnkoeG1sMikNCmxpYnJhcnkobWFnaWNrKQ0KbGlicmFyeShtYXBzKQ0KbGlicmFyeShnZ2FuaW1hdGUpDQpsaWJyYXJ5KHJpbykNCmxpYnJhcnkocGF0Y2h3b3JrKQ0KYGBgDQoNCmBgYHtyIGNodW5rLXNldHVwLCBpbmNsdWRlID0gRkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIGV2YWwgPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgDQogICAgICAgICAgICAgICAgICAgICAgI3Jlc3VsdHMgPSAiaG9sZCIsDQogICAgICAgICAgICAgICAgICAgICAgY2FjaGUgPSBGQUxTRSwgY2FjaGUucGF0aCA9ICIvY2FjaGVzLyIsIGNvbW1lbnQgPSAiIz4iLA0KICAgICAgICAgICAgICAgICAgICAgICNmaWcud2lkdGggPSA3LCAjZmlnLmhlaWdodD0gNywgICANCiAgICAgICAgICAgICAgICAgICAgICAjb3V0LndpZHRoID0gNywgb3V0LmhlaWdodCA9IDcsDQogICAgICAgICAgICAgICAgICAgICAgY29sbGFwc2UgPSBUUlVFLCAgZmlnLnNob3cgPSAiaG9sZCIsDQogICAgICAgICAgICAgICAgICAgICAgZmlnLmFzcCA9IDcvOSwgb3V0LndpZHRoID0gIjYwJSIsIGZpZy5hbGlnbiA9ICJjZW50ZXIiKQ0KIy0gcGFyYSBtZWpvcmFyIGxvcyBncsOhZmljb3MsIGJ1ZW5vIGVuIHJlYWxpZGFkIHBhcmEgcXVlIHNlIHZlYW4gaWd1YWwgZW4gZGlzdGludG9zIFNPDQojLSBodHRwczovL3d3dy5qdW1waW5ncml2ZXJzLmNvbS9ibG9nL3Ita25pdHItbWFya2Rvd24tcG5nLXBkZi1ncmFwaGljcy8NCmtuaXRyOjpvcHRzX2NodW5rJHNldChkZXYgPSAicG5nIiwgZGV2LmFyZ3MgPSBsaXN0KHR5cGUgPSAiY2Fpcm8tcG5nIikpDQpgYGANCg0KYGBge3Igb3B0aW9ucy1zZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQ0Kb3B0aW9ucyhzY2lwZW4gPSA5OTkpICMtIHBhcmEgcXVpdGFyIGxhIG5vdGFjacOzbiBjaWVudMOtZmljYQ0Kb3B0aW9ucygieWFtbC5ldmFsLmV4cHIiID0gVFJVRSkgIy0gaHR0cHM6Ly9naXRodWIuY29tL3Zpa2luZy9yLXlhbWwvaXNzdWVzLzQ3ICAobG8gcHVzZSB4IGVsIHBiIGNvbiBlbCB3YXJuaW5nKSBFbiByZWFsaWRhZCBjcmVvIHF1ZSBtZWpvciBzZXLDrWEgcG9uZXJsbyBlbiBSUHJvZmlsZQ0KYGBgDQoNCg0KYGBge3Iga2xpcHB5LCBlY2hvID0gRkFMU0V9DQprbGlwcHk6OmtsaXBweShwb3NpdGlvbiA9IGMoInRvcCIsICJyaWdodCIpKSAjLSByZW1vdGVzOjppbnN0YWxsX2dpdGh1Yigicmxlc3VyL2tsaXBweSIpDQpgYGANCg0KLS0tLS0tLS0tLS0tLS0tLS0NCiANCg0KIyMgIDxGT05UIENPTE9SPSJHcmVlbiI+IDEuSW50cm9kdWNjacOzbiA8L0ZPTlQ+DQoNCkxhIHBhbGFicmEgICoqdHVyaXNtbyoqIOKAlHNlZ8O6biBsYSBPTVQgT3JnYW5pemFjacOzbiBNdW5kaWFsIGRlbCBUdXJpc21v4oCUIGNvbXByZW5kZSDCq2xhcyBhY3RpdmlkYWRlcyBxdWUgcmVhbGl6YW4gbGFzIHBlcnNvbmFzIGR1cmFudGUgc3VzIHZpYWplcyB5IGVzdGFuY2lhcyBlbiBsdWdhcmVzIGRpc3RpbnRvcyBhIHN1IGVudG9ybm8gaGFiaXR1YWwgZHVyYW50ZSB1biBwZXLDrW9kbyBkZSB0aWVtcG8gaW5mZXJpb3IgYSB1biBhw7FvLCBjb24gZmluZXMgZGUgb2NpbywgbmVnb2Npb3MgdSBvdHJvc8K7Lg0KDQoNCkxhIGluZHVzdHJpYSB0dXLDrXN0aWNhIHByZXNlbnRhIGdyYW4gaW1wb3J0YW5jaWEgYSBuaXZlbCBnbG9iYWwsIHB1ZXMgZXMgbGEgcmVzcG9uc2FibGUgZGUgbGEgY3JlYWNpw7NuIGRlIG51bWVyb3NvcyBwdWVzdG9zIGRlIHRyYWJham8geSBhZGVtw6FzLCB0aWVuZSBhcG9ydGFjacOzbiBkaXJlY3RhIGVuIGVsIFBJQiBtdW5kaWFsLiBMYSBhY3RpdmlkYWQgZ2VuZXJhZGEgcG9yIGxvcyBzZWN0b3JlcyBkZSBsYSBob3N0ZWxlcsOtYSwgbGFzIGFnZW5jaWFzIGRlIHZpYWplLCBlbCB0cmFuc3BvcnRlIGRlIHBhc2FqZXJvcyB5IGRlbCBvY2lvIGVuIGdlbmVyYWwgY29uc2lndWUgYXRyYWVyLCBhZGVtw6FzLCB1bmEgaW1wb3J0YW50ZSBpbnZlcnNpw7NuIHDDumJsaWNhIHkgZGUgY2FwaXRhbCBwcml2YWRvLg0KDQpFcyBwb3IgZWxsbyBxdWUgZWwgb2JqZXRpdm8gZGUgZXN0ZSB0cmFiYWpvIGVzIGFuYWxpemFyIGVsIHNlY3RvciB0dXLDrXN0aWNvICBjZW50csOhbmRvbm9zIGLDoXNpY2FtZW50ZSBlbiBFc3Bhw7FhLCBjb24gZWwgZmluIGRlIG9idGVuZXIgaW5mb3JtYWNpw7NuIGFjZXJjYSBkZSA6DQoNCj4gLSBFbCBvcmlnZW4gZGUgbG9zIGZsdWpvcyBkZSB0dXJpc3Rhcw0KPiAtIE1vdGl2b3MgZGUgc3UgbGxlZ2FkYQ0KPiAtIFN1IGdhc3RvIA0KDQo8Y2VudGVyPjxpbWcgc3JjPSJodHRwczovL2ljaGVmLmJiY2kuY28udWsvbmV3cy84MDAvY3BzcHJvZHBiL0Q5MzkvcHJvZHVjdGlvbi9fMTAzNTkwNjU1X3ZhbGlqYS10dXJpc21vLnBuZyIgd2lkdGg9IjM1MHB4IiAvPjwvY2VudGVyPg0KDQoNCg0KIyMgIDxGT05UIENPTE9SPSJHcmVlbiI+IDIuRGF0b3MgcGFyYSBsYSByZWFsaXphY2nDs24gZGVsIHByb3llY3RvIDwvRk9OVD4gey50YWJzZXR9DQoNCiMjIyAqKkRlc2NhcmdhIGRpcmVjdGEqKg0KDQpFc3RvcyBoYW4gc2lkbyBsb3MgZGF0b3MgbcOhcyBmw6FjaWxlcyBkZSBvYnRlbmVyLCB5YSBxdWUgcHJpbWVybyBsb3MgZGVzY2FyZ2Ftb3MgZGlyZWN0YW1lbnRlIGRlIGRpZmVyZW50ZXMgcMOhZ2luYXMgd2ViIHkgbHVlZ28gbG9zIGFsb2phbW9zIGVuIEdpdEh1Yi4gRXN0YSBtYW5lcmEgZXMgbXV5IGPDs21vZGEsIHBvciBsbyBxdWUgaGEgc2lkbyBsYSBxdWUgbcOhcyBoZW1vcyB1c2Fkby4NCkxvcyBkYXRvcyB1dGlpemFkb3MgcGFyYSBsYSBlbGFib3JhY2nDs24gZGVsIHByZXNlbnRlIHByb3llY3RvIHNvbiBleHRyYWlkb3MgLCBwcmluY2lwYWxtZW50ZSBkZSBsYSBiYXNlIGRlIGRhdG9zIGRlIGxhICBww6FnaW5hIG9maWNpYWwgZGVsICoqSW5zdGl0dXRvIE5hY2lvbmFsIGRlIEVzdGFkw61zdGljYSoqICgqSU5FKikgLCBxdWUgcHVlZGUgdmVyc2UgW2FxdcOtXShodHRwczovL3d3dy5pbmUuZXMvZHluZ3MvSU5FYmFzZS9saXN0YW9wZXJhY2lvbmVzLmh0bSkgIA0KDQojIyMgKipXZWIgU2NyYXBpbmcqKg0KDQpQYXJhIG9idGVuZXIgbG9zIGRhdG9zIGRlIGxvcyBtb251bWVudG9zIG3DoXMgdmlzaXRhZG9zIGRlbCBtdW5kbywgZGVjaWRpbW9zIGhhY2VyIFdlYiBTY3JhcGluZy4gRWwgV2ViIFNjcmFwaW5nIGVzIGJhc3RhbnRlIG3DoXMgY29tcGxlam8gcXVlIGVsIG1ldG9kbyBhbnRlcmlvciwgeWEgcXVlIGhheSBxdWUgYnVzY2FyIGRhdG9zIGVuIGVsIGPDs2RpZ28gZnVlbnRlIGRlIGxhIHDDoWdpbmEgd2ViLiBFbiBudWVzdHJvIGNhc28sIGRlY2lkaW1vcyB1dGlsaXphciBlc3RlIG3DqXRvZG8gcGFyYSBleHRyYWVyIGxvcyBkYXRvcyBkZSB1bmEgW3RhYmxhIGRlIFdpa2lQZWRpYV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGlzdF9vZl9tb3N0X3Zpc2l0ZWRfcGFsYWNlc19hbmRfbW9udW1lbnRzKSwgYXPDrSBhcHJlbmRpbW9zIGNvc2FzIG51ZXZhcyB5IGHDsWFkaW1vcyB2YXJpZWRhZCBhbCB0cmFiYWpvLg0KDQpBIGNvbnRpbnVhY2nDs24gbW9zdHJhbW9zIGxhIHRhYmxhIHF1ZSBleHRyYcOtbW9zIHkgZWwgY8OzZGlnbyB1dGlsaXphZG8uDQoNCiFbVGFibGEgV2lraXBlZGlhXShodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20veGk3NjUvVHJhYmFqb0dydXBvL21haW4vU2NyZWVuc2hvdF8yMDIwLTEyLTE4JTIwTGlzdCUyMG9mJTIwbW9zdCUyMHZpc2l0ZWQlMjBwYWxhY2VzJTIwYW5kJTIwbW9udW1lbnRzJTIwLSUyMFdpa2lwZWRpYS5wbmcpDQoNCmBgYHtyLCBlY2hvPVRSVUUsZXZhbD1GQUxTRX0NCnVybCA8LSAiaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGlzdF9vZl9tb3N0X3Zpc2l0ZWRfcGFsYWNlc19hbmRfbW9udW1lbnRzIg0KI0FxdcOtIHNhY2Ftb3MgbGEgdGFibGENCncgPC0gcmVhZF9odG1sKHVybCkNCmJiIDwtIHcgJT4lIHJ2ZXN0OjpodG1sX25vZGVzKHhwYXRoID0gJy9odG1sL2JvZHkvZGl2WzNdL2RpdlszXS9kaXZbNV0vZGl2WzFdL3RhYmxlJykgJT4lIHJ2ZXN0OjpodG1sX3RhYmxlKCkNCm5hbWVzKGJiW1sxXV0pIDwtIGMoMTo2KQ0KI0FxdcOtIGxhIGFycmVnbGFtb3MgdW4gcG9jbywgY2FtYmlhbmRvIG5vbWJyZXMsIG9yZGVuYW5kbyBldGMuLi4NCmFhIDwtIGFzX3RpYmJsZShiYltbMV1dKSAlPiUgc2VsZWN0KC1jKDEsNSw2KSkgJT4lIHNsaWNlKGMoMjoxMSkpICU+JSBtdXRhdGUoQ291bnRyeSA9IGMoIkNoaW5hIiwiRWwgVmF0aWNhbm8iLCJGcmFuY2lhIiwiRXN0YWRvcyBVbmlkb3MiLCJJdGFsaWEiLCJHcmVjaWEiLCJJbmRpYSIsIkZyYW5jaWEiLCJBbGVtYW5pYSIsIlJ1c2lhIikpICU+JSByZW5hbWUoIk1vbnVtZW50byIgPSAxLCAiQ2l1ZGFkIiA9IDIsICJWaXNpdGFudGVzIiA9IDMpICU+JSByZWxvY2F0ZSg0LC5iZWZvcmUgPSAzKSAlPiUgbXV0YXRlKFZpc2l0YW50ZXMgPSBwYXJzZV9udW1iZXIoVmlzaXRhbnRlcyksIE1vbnVtZW50byA9IGZhY3RvcihNb251bWVudG8sIGxldmVscyA9IE1vbnVtZW50b1tvcmRlcihWaXNpdGFudGVzKV0pLCBWaXNpdGFudGVzTSA9IChWaXNpdGFudGVzLzEwMDAwMDApLCBWaXNpdGFudGVzTSA9IHJvdW5kKFZpc2l0YW50ZXNNLDIpKQ0KYGBgDQoNCiMjIyAqKkFQSVMqKg0KUG9yIMO6bHRpbW8sIHRhbWJpw6luIGhlbW9zIG9idGVuaWRvIGFsZ3Vub3MgZGF0b3MgZGUgRXVyb3N0YXQgYSB0cmF2w6lzIGRlIHN1IEFQSS4gUGFyYSBlbGxvIGhlbW9zIHV0aWxpemFkbyBlbCBwYXF1ZXRlICoqKmxpYnJhcnkoZXVyb3N0YXQpKioqIHkgZWwgc2lndWllbnRlIGPDs2RpZ286DQpgYGB7ciBldmFsPUZBTFNFLGVjaG89VFJVRX0NCiNQSUIgZW4gTWlsbG9uZXMNCkdEUCA8LSBldXJvc3RhdDo6Z2V0X2V1cm9zdGF0KCJuYW1hXzEwX2dkcCIpDQpHRFAgPC0gR0RQICU+JSBmaWx0ZXIoIG5hX2l0ZW0gPT0gIkIxR1EiLCB1bml0ID09ICJDUF9NRVVSIikgJT4lIHNlbGVjdChnZW8sdGltZSx2YWx1ZXMpDQpHRFAgPC0gR0RQICU+JSByZW5hbWUoIGNvZGUgPSBnZW8pDQpjaWQgPC0gZXVyb3N0YXQ6OmV1X2NvdW50cmllcw0KR0RQIDwtIGlubmVyX2pvaW4oR0RQLGNpZCwgYnkgPSAiY29kZSIgKQ0KR0RQIDwtIEdEUCAlPiUgc2VsZWN0KC1jKGxhYmVsKSkgJT4lIHJlbG9jYXRlKG5hbWUsIC5iZWZvcmUgPSBjb2RlKQ0KR0RQIDwtIEdEUCAlPiUgcmVuYW1lX2F0KHZhcnMoY29sbmFtZXMoR0RQKSksIH4gYygiQ291bnRyeSIsIkNvZGUiLCJEYXRlIiwiUElCIikpDQojR0FTVE8gVFVSSVNUSUNPIE1pbGVzDQpHVCA8LSBldXJvc3RhdDo6Z2V0X2V1cm9zdGF0KCJ0b3VyX2RlbV9leHRvdCIpDQpHVCA8LSBHVCAlPiUgZmlsdGVyKGR1cmF0aW9uID09ICJOX0dFMSIsIHB1cnBvc2UgPT0gIlRPVEFMIix1bml0ID09IlRIU19FVVIiLCBwYXJ0bmVyID09ICJXT1JMRCIpDQpHVCA8LSBHVCAlPiUgc2VsZWN0KGdlbyx0aW1lLHZhbHVlcykgJT4lIHJlbmFtZSggY29kZSA9IGdlbykNCmNpZCA8LSBldXJvc3RhdDo6ZXVfY291bnRyaWVzDQpHVCA8LSBpbm5lcl9qb2luKEdULGNpZCwgYnkgPSAiY29kZSIgKQ0KR1QgPC0gR1QgJT4lIHNlbGVjdCgtYyhsYWJlbCkpICU+JSByZWxvY2F0ZShuYW1lLCAuYmVmb3JlID0gY29kZSkNCkdUIDwtIEdUICU+JSByZW5hbWVfYXQodmFycyhjb2xuYW1lcyhHVCkpLCB+IGMoIkNvdW50cnkiLCJDb2RlIiwiRGF0ZSIsIkdUIikpDQoNCg0KI1BPQkxBQ0nDk04NClBPQiA8LSBldXJvc3RhdDo6Z2V0X2V1cm9zdGF0KCJkZW1vX2dpbmQiKQ0KUE9CIDwtIFBPQiAlPiUgZmlsdGVyKCBpbmRpY19kZSA9PSAiSkFOIikgJT4lIHNlbGVjdCgtYyhpbmRpY19kZSkpDQpQT0IgPC0gUE9CICU+JSByZW5hbWUoY29kZSA9IGdlbykNCmNpZCA8LSBldXJvc3RhdDo6ZXVfY291bnRyaWVzDQpQT0IgPC0gaW5uZXJfam9pbihQT0IsY2lkLCBieSA9ICJjb2RlIiApDQpQT0IgPC0gUE9CICU+JSBzZWxlY3QoLWMobGFiZWwpKSAlPiUgcmVsb2NhdGUobmFtZSwgLmJlZm9yZSA9IGNvZGUpDQpQT0IgPC0gUE9CICU+JSByZW5hbWVfYXQodmFycyhjb2xuYW1lcyhQT0IpKSwgfiBjKCJDb3VudHJ5IiwiQ29kZSIsIkRhdGUiLCJQT0IiKSkNCmBgYA0KDQoNCiMjIDxGT05UIENPTE9SPSJHcmVlbiI+ICAzLiBUdXJpc21vIGEgbml2ZWwgbXVuZGlhbCAgPC9GT05UPg0KDQojIyMgKipQYcOtc2VzIG3DoXMgdmlzaXRhZG9zKioNCg0KRWwgdHVyaXNtbyBoYSBzaWRvIHVuIHNlY3RvciBlbiBhdWdlIGR1cmFudGUgbGFzIMO6bHRpbWFzIGTDqWNhZGFzLiBNw6FzIGRlIDEuMTAwIG1pbGxvbmVzIGRlIHBlcnNvbmFzIHJlYWxpemFuIHR1cmlzbW8gaW50ZXJuYWNpb25hbCBjYWRhIGHDsW8sIGxhIG1pdGFkIGVuIEV1cm9wYS4gQSBmYXZvciBkZWwgdmllam8gY29udGluZW50ZSBqdWVnYSB1biBlc3BhY2lvIGRlIGxpYnJlIGNpcmN1bGFjacOzbiBkZSBwZXJzb25hcywgdW5hIGV4dGVuZGlkYSBtb25lZGEgY29tw7puIHkgdW4gZW50b3JubyBwb2zDrXRpY28gZnJhZ21lbnRhZG8gY29uIG11Y2hvcyBFc3RhZG9zIHBlcXVlw7FvcyB5IG1lZGlhbm9zLCBhZGVtw6FzIGRlIHVuYSBhbXBsaWEgcmlxdWV6YSBwYXRyaW1vbmlhbCB5IHBsYXlhcyB5IGJ1ZW4gY2xpbWEgZW4gZWwgc3VyLiBEZSB0b2RvcyBtb2RvcyBlbiBlbCBsaXN0YWRvIGRlIHBhw61zZXMgbcOhcyB2aXNpdGFkb3MgdGFtYmnDqW4gZW50cmFuIEVzdGFkb3MgVW5pZG9zIHkgdmFyaW9zIEVzdGFkb3MgYXNpw6F0aWNvcy4NCg0KU2Vnw7puIGxvcyBkYXRvcyBwcm92ZW5pZW50ZXMgZGUgbGEgT3JnYW5pemFjacOzbiBNdW5kaWFsIGRlIFR1cmlzbW8gIChVTldUTyBwb3Igc3VzIHNpZ2xhcyBlbiBpbmdsw6lzKSxlbiBzdSBpbmZvcm1lIGVtaXRpZG8gZW4gbm92aWVtYnJlIGRlIDIwMTkgLCBsb3MgcGHDrXNlcyBtw6FzIHZpc2l0YWRvcyBzb24gRnJhbmNpYSwgRXNwYcOxYSB5IEVzdGFkb3MgVW5pZG9zLCBjb24gZW50cmUgODAgeSA5MCBtaWxsb25lcyBkZSB0dXJpc3RhcyBpbnRlcm5hY2lvbmFsZXM7IHNlZ3VpZG9zIGRlIENoaW5hIGUgSXRhbGlhLCBjb24gbcOhcyBkZSA2MDsgYSBsb3MgcXVlIHNpZ3VlbiB5YSBhIG1heW9yIGRpc3RhbmNpYSBUdXJxdcOtYSBvIE3DqXhpY28gZW4gZWwgcmFuZ28gZGUgbG9zIDQwLTUwIG1pbGxvbmVzLiBFbCBjcmVjaW1pZW50byBkZWwgdHVyaXNtbyBpbnRlcm5hY2lvbmFsIHNlIGhhIGRlamFkbyBub3RhciBzb2JyZXRvZG8gZW4gRXNwYcOxYSwgcXVlIGdhbsOzIGF0cmFqbyBtdWNobyB0dXJpc21vIHkgc2lndWUgbWFudGVuaWVuZG8gbGEgc2VndW5kYSBwb3NpY2nDs24gcG9yIHZhcmlvcyBhw7FvcyBjb25zZWN1dGl2b3M7IHBlcm8gdGFtYmnDqW4gc2UgcHVlZGUgb2JzZXJ2YXIgZW4gcGFpc2VzIGNvbW8gVGFpbGFuZGlhLCB1biBwYWlzIGxlamFubywgcXVlIHRpZW5lIGNlcmNhIGRlIGxvcyA0MCBtaWxsb25zIGRlIHR1cmlzdGFzIGFudWFsZXMgKGVuIGVsIGHDsW8gMjAxOSkNCkxhIGV2b2x1Y2nDs24gZGUgbGEgdGVjbm9sb2fDrWEsIGxhIG1lam9yYSBkZSBsYXMgaW5mcmFlc3RydWN0dXJhcyB5IGVsIGFiYXJhdGFtaWVudG8gZGUgY29zdGVzIGhhY2UgcXVlIGNhZGEgdmV6IG3DoXMgc2VyZXMgaHVtYW5vcyBwdWVkYW4gdmlhamFyIGNvbiBtw6FzIGZyZWN1ZW5jaWEgeSBtw6FzIGxlam9zLg0KDQpWaWFqYW5kbyBzZSBhY2NlZGUgYSBjdWx0dXJhcyBxdWUgbm8gc29uIGNvbW8gbGEgdHV5YSwgYSBtb251bWVudG9zIHF1ZSBubyBzZSBwYXJlY2VuIGEgbG9zIHF1ZSBjb25vY2VzLCBhIGdhc3Ryb25vbcOtYXMgcXVlIGxsZXZhbiBhIHR1IHBsYXRvIHByb2R1Y3RvcyB5IHNhYm9yZXMgaW5pbWFnaW5hYmxlcy4NCg0KDQpgYGB7ciwgZWNobz1UUlVFfQ0KI0ltcG9ydGFtb3MgbG9zIGRhdG9zIGRlbCByYW5raW5nIHBhw61zZXMgbcOhcyB2aXNpdGFkb3MgDQp1cmwyIDwtICJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vUGF2bGluYWRpbmtvdmEvMTAvbWFpbi9yYW5raW5nLmNzdiINCmJiPC0gcmlvOjppbXBvcnQodXJsMiwgc2V0Y2xhc3M9InRpYmJsZSIpJT4lIG11dGF0ZShQYWlzID0gYygiRlJBTkNJQSAiLCJFU1BBw5FBIiwiRUVVVSIsIkNISU5BIiwiSVRBTElBIiwiVFVSUVVJQSIsIk3DiVhJQ08iLCJBTEVNQU5JQSIsIlRBSUxBTkRJQSIsIlJFSU5PIFVOSURPIiwiSkFQw5NOIiwiQVVTVFJJQSIsIkdSRUNJQSIsIkhPTkcgS09ORyIsIk1BTEFTSUEiLCJSVVNJQSIsIlBPUlRVR0FMIiwiQ0FOQURBIiwiUE9MT05JQSIsIlBBSVNFUyBCQUpPUyIsIk1BQ0FPIiwiSU5ESUEiLCJIVU5HUklBIiwiQ1JPQUNJQSIsIkVBVSIpLFBhaXMgPSBmYWN0b3IoUGFpcywgbGV2ZWxzID0gUGFpc1tvcmRlcihWaWFqZXJvc19pbnRlcm5hY2lvbmFsZXMsIGRlY3JlYXNpbmcgPSBUUlVFKV0pLCBWaWFqZXJvc19pbnRlcm5hY2lvbmFsZXMgPSBzdHJpbmdyOjpzdHJfcmVtb3ZlX2FsbChWaWFqZXJvc19pbnRlcm5hY2lvbmFsZXMsIHBhdHRlcm4gPSAiW15bOmFsbnVtOl1dIiksIFZpYWplcm9zX2ludGVybmFjaW9uYWxlcyA9IGFzLm51bWVyaWMoVmlhamVyb3NfaW50ZXJuYWNpb25hbGVzKSwgKQ0KZCA8LSBnZ3Bsb3QoYmIpICsNCiAgZ2VvbV9wb2ludChhZXMoeCA9IFJhbmtpbmcsIHkgPSBWaWFqZXJvc19pbnRlcm5hY2lvbmFsZXMsIGNvbG91ciA9IFJhbmtpbmcgKSkgKw0KICBmYWNldF93cmFwKHZhcnMoUGFpcykpKyBsYWJzKHRpdGxlID0gIlBhw61zZXMgbcOhcyB2aXNpdGFkb3MgZGVsIG11bmRvICIsDQogICAgICAgICAgICAgIHN1YnRpdGxlID0gImFuw7FvIDIwMTkiLCANCiAgICAgICAgICAgICAgY2FwdGlvbiA9ICJEYXRvcyBwcm92ZW5pZW50ZXMgZGUgd3d3LmVudGVyZWF0LmNvbSIsDQogICAgICAgICAgICAgIHggPSAiUmFua2luZyAiLA0KICAgICAgICAgICAgICB5ID0gIk7CuiBkZSB2aWFqZXJvcyIsDQogICAgICAgICAgICAgIGNvbG9yID0gIlJhbmtpbmciKQ0KDQpwbG90bHk6OmdncGxvdGx5KGQsIHdpZHRoID0gOTAwLCBoZWlnaHQgPSA1MDApDQoNCg0KYGBgDQoNCmBgYHtyfQ0KICAjR3JhZmljbyBwYWlzZXMgbcOhcyB2aXNpdGFkb3MgKGxvbGxpcG9wKQ0KDQpwbCA8LSBnZ3Bsb3QoYmIsIGFlcyh4PVBhaXMgLCB5PVZpYWplcm9zX2ludGVybmFjaW9uYWxlcykpKyBnZW9tX3BvaW50KGFlcyhjb2xvcj1QYWlzKSwgc2l6ZT0zICkrZ2VvbV9zZWdtZW50KGFlcyh4PVBhaXMsIHhlbmQ9UGFpcywgeT0wICwgeWVuZD1WaWFqZXJvc19pbnRlcm5hY2lvbmFsZXMsIGNvbG9yPVBhaXMpKStnZW9tX3RleHQoYWVzKGxhYmVsPVBhaXMpLCBzaXplPTMsIGFuZ2xlPTkwLCB2anVzdD0wLCBudWRnZV95ID0gLTUwMDAwMDApK3RoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKyBsYWJzKHk9Ik7Dum1lcm8gZGUgdmlhamVyb3MiLCB4PU5VTEwsdGl0bGUgPSAiUGFpc2VzIG3DoXMgdmlzaXRhZG9zIGVuIGVsIG11bmRvIiwgc3VidGl0bGUgPSAiRGF0b3MgZGUgMjAxOSIgLCBjYXB0aW9uPSAiRnVlbnRlOk9NVCIpICsgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJibGFjayIsc2l6ZT0wLjUpLCBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjZDVmZmZkIiksIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfbGluZSgiZ3JleSIpLCBwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IueSA9IGVsZW1lbnRfYmxhbmsoKSkgKyBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLDApLGJyZWFrcyA9IHNlcSgwLDkwMDAwMDAwLDUwMDAwMDApLCBsYWJlbHMgPSBwYXN0ZSgoc2VxKDAsOTAwMDAwMDAsNTAwMDAwMCkvMTAwMDAwMCksIk0iKSwgbGltaXRzID0gYygwLDk1MDAwMDAwKSkNCg0KDQpnZ2RyYXcocGwpICsgZHJhd19pbWFnZSgiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy9iL2JhL0ZsYWdfb2ZfR2VybWFueS5zdmciLHg9IDAuMzUsIHkgPSAwLjQzLCB3aWR0aCA9IDAuMDIsIGhlaWdodCA9IDAuMDIpICsgZHJhd19pbWFnZSgiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy80LzQxL0ZsYWdfb2ZfQXVzdHJpYS5zdmciLCB4PTAuNDksIHk9MC4zNSwgd2lkdGg9MC4wMiwgaGVpZ2h0ID0gMC4wMikgKyBkcmF3X2ltYWdlKCJodHRwczovL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9jb21tb25zL2MvYzMvRmxhZ19vZl9GcmFuY2Uuc3ZnIiwgeD0wLjEwLCB5PTAuODcsIHdpZHRoPTAuMDE4LCBoZWlnaHQgPSAwLjAxOCkgKw0KICBkcmF3X2ltYWdlKCJodHRwczovL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9jb21tb25zLzgvODEvQmFuZGVyYV9kZV9Fc3BhJUMzJUIxYV8xOTc4LnBuZyIsIHg9MC4xMywgeT0wLjgxLCB3aWR0aD0wLjAxOCwgaGVpZ2h0ID0gMC4wMTgpICsNCiAgZHJhd19pbWFnZSgiaHR0cHM6Ly9hbHBoYXBlZGlhLm5ldC93cC1jb250ZW50L3VwbG9hZHMvMjAxOS8xMi9JTUFHRU5FUy1ERS1MQS1CQU5ERVJBLURFLUVTVEFET1MtVU5JRE9TLTMwMHgyMDAuanBnIiwgeD0wLjE3NSwgeT0wLjc4LCB3aWR0aD0wLjAxOCwgaGVpZ2h0ID0gMC4wMTgpICsgZHJhd19pbWFnZSgiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy90aHVtYi9mL2ZhL0ZsYWdfb2ZfdGhlX1Blb3BsZSUyN3NfUmVwdWJsaWNfb2ZfQ2hpbmEuc3ZnLzEyODBweC1GbGFnX29mX3RoZV9QZW9wbGUlMjdzX1JlcHVibGljX29mX0NoaW5hLnN2Zy5wbmciLCB4PTAuMjEsIHk9MC42Mywgd2lkdGg9MC4wMTgsIGhlaWdodCA9IDAuMDE4KSAgKyBkcmF3X2ltYWdlKCJodHRwczovL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9jb21tb25zLzAvMDMvRmxhZ19vZl9JdGFseS5zdmciLCB4PTAuMjQsIHk9MC42Miwgd2lkdGg9MC4wMTgsIGhlaWdodCA9IDAuMDE4KSAgICsgZHJhd19pbWFnZSgiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy9iL2I0L0ZsYWdfb2ZfVHVya2V5LnN2ZyIsIHg9MC4yNywgeT0wLjQ4LCB3aWR0aD0wLjAxOCwgaGVpZ2h0ID0gMC4wMTgpICArIGRyYXdfaW1hZ2UoImh0dHBzOi8vdXBsb2FkLndpa2ltZWRpYS5vcmcvd2lraXBlZGlhL2NvbW1vbnMvZi9mYy9GbGFnX29mX01leGljby5zdmciLCB4PTAuMzEsIHk9MC40Nywgd2lkdGg9MC4wMTgsIGhlaWdodCA9IDAuMDE4KSArIGRyYXdfaW1hZ2UoImh0dHBzOi8vdXBsb2FkLndpa2ltZWRpYS5vcmcvd2lraXBlZGlhL2NvbW1vbnMvYS9hOS9GbGFnX29mX1RoYWlsYW5kLnN2ZyIsIHg9MC4zOCwgeT0wLjQxLCB3aWR0aD0wLjAxOCwgaGVpZ2h0ID0gMC4wMTgpICsgZHJhd19pbWFnZSgiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvZW4vYS9hZS9GbGFnX29mX3RoZV9Vbml0ZWRfS2luZ2RvbS5zdmciLCB4PTAuNDEsIHk9MC40MCwgd2lkdGg9MC4wMTgsIGhlaWdodCA9IDAuMDE4KSArIGRyYXdfaW1hZ2UoImh0dHBzOi8vdXBsb2FkLndpa2ltZWRpYS5vcmcvd2lraXBlZGlhL2VuLzkvOWUvRmxhZ19vZl9KYXBhbi5zdmciLCB4PTAuNDY1LCB5PTAuMzYsIHdpZHRoPTAuMDE4LCBoZWlnaHQgPSAwLjAxOCkgICsgZHJhd19pbWFnZSgiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy81LzVjL0ZsYWdfb2ZfR3JlZWNlLnN2ZyIsIHg9MC41MywgeT0wLjM2LCB3aWR0aD0wLjAxOCwgaGVpZ2h0ID0gMC4wMTgpICsgZHJhd19pbWFnZSgiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy81LzViL0ZsYWdfb2ZfSG9uZ19Lb25nLnN2ZyIsIHg9MC41NiwgeT0wLjM2LCB3aWR0aD0wLjAxOCwgaGVpZ2h0ID0gMC4wMTgpICsgZHJhd19pbWFnZSgiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy82LzY2L0ZsYWdfb2ZfTWFsYXlzaWEuc3ZnIiwgeD0wLjYwLCB5PTAuMzIsIHdpZHRoPTAuMDE4LCBoZWlnaHQgPSAwLjAxOCkgICsgZHJhd19pbWFnZSgiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy9mL2YzL0ZsYWdfb2ZfUnVzc2lhLnN2ZyIsIHg9MC42MywgeT0wLjMwLCB3aWR0aD0wLjAxOCwgaGVpZ2h0ID0gMC4wMTgpICsgZHJhd19pbWFnZSgiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy81LzVjL0ZsYWdfb2ZfUG9ydHVnYWwuc3ZnIiwgeD0wLjY2LCB5PTAuMjksIHdpZHRoPTAuMDE4LCBoZWlnaHQgPSAwLjAxOCkgKyBkcmF3X2ltYWdlKCJodHRwczovL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9jb21tb25zL3RodW1iL2QvZDkvRmxhZ19vZl9DYW5hZGFfJTI4UGFudG9uZSUyOS5zdmcvMTkyMHB4LUZsYWdfb2ZfQ2FuYWRhXyUyOFBhbnRvbmUlMjkuc3ZnLnBuZyIsIHg9MC43MDUsIHk9MC4yOCwgd2lkdGg9MC4wMTgsIGhlaWdodCA9IDAuMDE4KSArIGRyYXdfaW1hZ2UoImh0dHBzOi8vdXBsb2FkLndpa2ltZWRpYS5vcmcvd2lraXBlZGlhL2VuLzEvMTIvRmxhZ19vZl9Qb2xhbmQuc3ZnIiwgeD0wLjc0LCB5PTAuMjcsIHdpZHRoPTAuMDE4LCBoZWlnaHQgPSAwLjAxOCkgICsgZHJhd19pbWFnZSgiaHR0cHM6Ly93d3cucGFpc2VzYmFqb3N5dHUubmwvYmluYXJpZXMvbWVkaXVtL2NvbnRlbnQvZ2FsbGVyeS9uZXRoZXJsYW5kc2FuZHlvdS9jb250ZW50LWFmYmVlbGRpbmdlbi9hbGdlbWVlbi92bGFnLW5lZGVybGFuZC5wbmciLCB4PTAuNzgsIHk9MC4yOCwgd2lkdGg9MC4wMTgsIGhlaWdodCA9IDAuMDE4KSArIGRyYXdfaW1hZ2UoImh0dHBzOi8vdXBsb2FkLndpa2ltZWRpYS5vcmcvd2lraXBlZGlhL2NvbW1vbnMvNi82My9GbGFnX29mX01hY2F1LnN2ZyIsIHg9MC44MiwgeT0wLjI2LCB3aWR0aD0wLjAxOCwgaGVpZ2h0ID0gMC4wMTgpICsgZHJhd19pbWFnZSgiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvZW4vNC80MS9GbGFnX29mX0luZGlhLnN2ZyIsIHg9MC44NDcsIHk9MC4yNCwgd2lkdGg9MC4wMTgsIGhlaWdodCA9IDAuMDE4ICkgKyBkcmF3X2ltYWdlKCJodHRwczovL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9jb21tb25zL2MvYzEvRmxhZ19vZl9IdW5nYXJ5LnN2ZyIsIHg9MC44OSwgeT0wLjIzLCB3aWR0aD0wLjAxOCwgaGVpZ2h0ID0gMC4wMTgpICsgZHJhd19pbWFnZSgiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy90aHVtYi8xLzFiL0ZsYWdfb2ZfQ3JvYXRpYS5zdmcvMTkyMHB4LUZsYWdfb2ZfQ3JvYXRpYS5zdmcucG5nIiwgeD0wLjkyLCB5PTAuMjMsIHdpZHRoPTAuMDE4LCBoZWlnaHQgPSAwLjAxOCkgICsgZHJhd19pbWFnZSgiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy9jL2NiL0ZsYWdfb2ZfdGhlX1VuaXRlZF9BcmFiX0VtaXJhdGVzLnN2ZyIsIHg9MC45NiwgeT0wLjIyLCB3aWR0aD0wLjAxOCwgaGVpZ2h0ID0gMC4wMTggICkNCg0KYGBgDQoNCkVzdGEgZXN0YWTDrXN0aWNhIHByZXNlbnRhIGVsIG7Dum1lcm8gZGUgbGxlZ2FkYXMgZGUgdHVyaXN0YXMgaW50ZXJuYWNpb25hbGVzIHF1ZSBzZSBwcm9kdWplcm9uIGVuIGVsIG11bmRvIGVuIDIwMTYsIHNlZ8O6biBlbCDDoXJlYSBnZW9ncsOhZmljYS4gRXNlIGHDsW8gbGEgcmVnacOzbiBBc2lhLVBhY8OtZmljbyByZWNpYmnDsyBhbHJlZGVkb3IgZGUgMzAwIG1pbGxvbmVzIGRlIHR1cmlzdGFzLCB1bmEgY2lmcmEgc29sbyBzdXBlcmFkYSBwb3IgbGEgcmVnaXN0cmFkYSBlbiBFdXJvcGEuIEVuIGVsIGNhc28gZGVsIGNvbnRpbmVudGUgYW1lcmljYW5vLCBsYSBjaWZyYSBzdXBlcsOzIGxvcyAyMDAgbWlsbG9uZXMgZGUgdHVyaXN0YXMgaW50ZXJuYWNpb25hbGVzLiBFbiDDgWZyaWNhIHkgT3JpZW50ZSBNZWRpbywgZXN0b3MgbGxlZ2Fyb24gYSBsb3MgNTggeSBhIGxvcyA1NiBtaWxsb25lcyByZXNwZWN0aXZhbWVudGUuIA0KDQpgYGB7ciBFdXJvcGF9DQojSW1wb3J0YW1vcyBkYXRvcyBUVVJJU01PIE1VTkRJQUwNCnVybDYgPC0gImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9QYXZsaW5hZGlua292YS8xMC9tYWluL3R1cmlzbW9fbXVuZGlhbC5jc3YiDQp0dDwtIHJpbzo6aW1wb3J0KHVybDYsIHNldGNsYXNzPSJ0aWJibGUiKQ0KbmFtZXModHQpPWMoIkNvbnRpbmVudGUiLCJGZWNoYSIsIlR1cmlzdGFzIikNCiNIYWNlbW9zIGVsIGdyw6FmaWNvIGRlIGxsZWdhZGFzIGRlIHR1cmlzdGFzIGludGVybmFjaW9uYWxlcyBlbiBFdXJvcGENCg0KIG11bmRvX0V1cm9wYSA8LSB0dCAlPiUgZmlsdGVyKENvbnRpbmVudGU9PSJFdXJvcGEiKQ0KDQogIGdyYWZFdXJvcGEgPC0gZ2dwbG90KG11bmRvX0V1cm9wYSwgYWVzKHg9RmVjaGEsIHk9VHVyaXN0YXMgLCBncm91cD1Db250aW5lbnRlLCBjb2xvcj1GZWNoYSkpICsgZ2VvbV9saW5lKCkgKyBmYWNldF9ncmlkKENvbnRpbmVudGUgfiAuKSArDQogIGV4cGFuZF9saW1pdHMoeT0yKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKyBsYWJzKHRpdGxlID0gIkxsZWdhZGFzIGRlIHR1cmlzdGFzIGludGVybmFjaW9uYWxlcyBlbiBFdXJvcGEgIiwgICAgY2FwdGlvbiA9ICJTb3VyY2U6aHR0cDovL21rdC51bnd0by5vcmcvYmFyb21ldGVyIiwNCiAgICAgICAgICAgICAgeCA9ICJGZWNoYSAiLA0KICAgICAgICAgICAgICB5ID0gTlVMTCwNCiAgICAgICAgICAgICAgY29sb3IgPSAiQ29udGluZW50ZSIsDQogICAgICAgICAgICAgIHN1YnRpdGxlID0gImVuIG1pbGxvbmVzIGRlIHZpc2l0YW50ZXMiKQ0KDQojSGFjZW1vcyBsbyBtaXNtbyBwYXJhIGxvcyBvdHJvcyBjb250aW5lbnRlcyBwb3Igc2VwYXJhZG8gLCB5IGZpbmFsbWVudGUgbGFzIHVuaW1vcy4NCg0KYGBgIA0KDQpgYGB7ciBBZnJpY2EgLCBlY2hvPUZBTFNFfQ0KbXVuZG9fQWZyaWNhIDwtIHR0ICU+JSBmaWx0ZXIoQ29udGluZW50ZT09IkFmcmljYSIpDQogIGdyYWZBZnJpY2EgPC0gZ2dwbG90KG11bmRvX0FmcmljYSwgYWVzKHg9RmVjaGEsIHk9VHVyaXN0YXMgLCBncm91cD1Db250aW5lbnRlLCBjb2xvcj1GZWNoYSkpICsgZ2VvbV9saW5lKCkgKyBmYWNldF9ncmlkKENvbnRpbmVudGUgfiAuKSArDQogIGV4cGFuZF9saW1pdHMoeT0yKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKyBsYWJzKHRpdGxlID0gIkxsZWdhZGFzIGRlIHR1cmlzdGFzIGludGVybmFjaW9uYWxlcyBwb3IgY29udGluZW50ZSAiLCAgICBjYXB0aW9uID0gIlNvdXJjZTpodHRwOi8vbWt0LnVud3RvLm9yZy9iYXJvbWV0ZXIiLA0KICAgICAgICAgICAgICB4ID0gIkZlY2hhICIsDQogICAgICAgICAgICAgIHkgPSBOVUxMLA0KICAgICAgICAgICAgICBjb2xvciA9ICJDb250aW5lbnRlIiwNCiAgICAgICAgICAgICAgc3VidGl0bGUgPSAiZW4gbWlsbG9uZXMgZGUgdmlzaXRhbnRlcyIpDQogDQoNCmBgYA0KDQpgYGB7ciBBbWVyaWNhcyAsIGVjaG89RkFMU0V9DQoNCiBtdW5kb19BbWVyaWNhcyA8LSB0dCAlPiUgZmlsdGVyKENvbnRpbmVudGU9PSJBbWVyaWNhcyIpDQogIGdyYWZBbWVyaWNhcyA8LSBnZ3Bsb3QobXVuZG9fQW1lcmljYXMsIGFlcyh4PUZlY2hhLCB5PVR1cmlzdGFzICwgZ3JvdXA9Q29udGluZW50ZSwgY29sb3I9RmVjaGEpKSArIGdlb21fbGluZSgpICsgZmFjZXRfZ3JpZChDb250aW5lbnRlIH4gLikgKw0KICBleHBhbmRfbGltaXRzKHk9MikgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsgbGFicyh0aXRsZSA9ICJMbGVnYWRhcyBkZSB0dXJpc3RhcyBpbnRlcm5hY2lvbmFsZXMgZW4gQW1lcmljYSBkZWwgTm9ydGUsIENlbnRyYWwgeSBTdWQgIiwgICAgY2FwdGlvbiA9ICJTb3VyY2U6aHR0cDovL21rdC51bnd0by5vcmcvYmFyb21ldGVyIiwNCiAgICAgICAgICAgICAgeCA9ICJGZWNoYSAiLA0KICAgICAgICAgICAgICB5ID0gTlVMTCwNCiAgICAgICAgICAgICAgY29sb3IgPSAiQ29udGluZW50ZSIsDQogICAgICAgICAgICAgIHN1YnRpdGxlID0gImVuIG1pbGxvbmVzIGRlIHZpc2l0YW50ZXMiKQ0KDQpgYGANCg0KYGBge3IgQXNpYSwgZWNobz1GQUxTRX0NCm11bmRvX0FzaWEgPC0gdHQgJT4lIGZpbHRlcihDb250aW5lbnRlPT0iQXNpYV9QYWNpZmljIikNCiAgZ3JhZkFzaWEgPC0gZ2dwbG90KG11bmRvX0FzaWEsIGFlcyh4PUZlY2hhLCB5PVR1cmlzdGFzICwgZ3JvdXA9Q29udGluZW50ZSwgY29sb3I9RmVjaGEpKSArIGdlb21fbGluZSgpICsgZmFjZXRfZ3JpZChDb250aW5lbnRlIH4gLikgKw0KICBleHBhbmRfbGltaXRzKHk9MikgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsgbGFicyh0aXRsZSA9ICJMbGVnYWRhcyBkZSB0dXJpc3RhcyBpbnRlcm5hY2lvbmFsZXMgZW4gQXNpYSBQYWPDrWZpY2EgIiwgICAgY2FwdGlvbiA9ICJTb3VyY2U6aHR0cDovL21rdC51bnd0by5vcmcvYmFyb21ldGVyIiwNCiAgICAgICAgICAgICAgeCA9ICJGZWNoYSAiLA0KICAgICAgICAgICAgICB5ID0gTlVMTCwNCiAgICAgICAgICAgICAgY29sb3IgPSAiQ29udGluZW50ZSIsDQogICAgICAgICAgICAgIHN1YnRpdGxlID0gImVuIG1pbGxvbmVzIGRlIHZpc2l0YW50ZXMiKQ0KDQpgYGANCg0KYGBge3IgTWlkZGxlIEVhc3QgLCBlY2hvPUZBTFNFfQ0KDQoNCm11bmRvX09yaWVudGUgPC0gdHQgJT4lIGZpbHRlcihDb250aW5lbnRlPT0iTWlkZGxlX2Vhc3QiKQ0KICBncmFmT3JpZW50ZSA8LSBnZ3Bsb3QobXVuZG9fT3JpZW50ZSwgYWVzKHg9RmVjaGEsIHk9VHVyaXN0YXMgLCBncm91cD1Db250aW5lbnRlLCBjb2xvcj1GZWNoYSkpICsgZ2VvbV9saW5lKCkgKyBmYWNldF9ncmlkKENvbnRpbmVudGUgfiAuKSArDQogIGV4cGFuZF9saW1pdHMoeT0yKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKyBsYWJzKHRpdGxlID0gIkxsZWdhZGFzIGRlIHR1cmlzdGFzIGludGVybmFjaW9uYWxlcyBlbiBPcmllbnRlIE1lZGlvICIsICAgIGNhcHRpb24gPSAiU291cmNlOmh0dHA6Ly9ta3QudW53dG8ub3JnL2Jhcm9tZXRlciIsDQogICAgICAgICAgICAgIHggPSAiRmVjaGEgIiwNCiAgICAgICAgICAgICAgeSA9IE5VTEwsDQogICAgICAgICAgICAgIGNvbG9yID0gIkNvbnRpbmVudGUiLA0KICAgICAgICAgICAgICBzdWJ0aXRsZSA9ICJlbiBtaWxsb25lcyBkZSB2aXNpdGFudGVzIikNCg0KYGBgDQoNCg0KYGBge3IsIGVjaG89VFJVRX0NCmxpYnJhcnkocGF0Y2h3b3JrKQ0KKGdyYWZBZnJpY2EgKyBncmFmRXVyb3BhKSAvIChncmFmQW1lcmljYXMrZ3JhZkFzaWErIGdyYWZPcmllbnRlICkNCg0KYGBgDQoNCg0KIyMjICoqTG9zIDEwIG1vbnVtZW50b3MgbcOhcyB2aXNpdGFkb3MqKg0KDQoqKipBbWJvcyBncsOhZmljb3Mgc2Fsw61hbiBkZXNjdWFkcmFkb3MgYWwgZWplY3V0YXJsb3MgZGlyZWN0YW1lbnRlIGVuIGVsIC5SbWQsIGFzw60gcXVlIGxvcyBoZW1vcyBhbG9qYWRvIGVuIGdpdGh1YiBlIGluc2VydGFkbyBtZWRpYW50ZSB1cmwuKioqDQoNCkVuIGVsIHByaW1lciBncsOhZmljbyBwb2RlbW9zIHZlciBsb3MgZGlleiBtb251bWVudG9zIG3DoXMgdmlzaXRhZG9zIGRlbCBtdW5kbywgc2UgbXVlc3RyYTogZWwgbsO6bWVybyBkZSB2aXNpdGFudGVzIGFudWFsZXMgZW4gTWlsbG9uZXMsIGxhIGJhbmRlcmEgeSBlbCBub21icmUgZGVsIHBhw61zIGRvbmRlIHNlIGVuY3VlbnRyYSBlbCBtb251bWVudG8uDQoNClNlIHB1ZWRlIG9ic2VydmFyIGNvbW8gbGEgQ2l1ZGFkIHByb2hpYmlkYSBkZSBQZWvDrW4gZXMgZWwgbW9udW1lbnRvIG3DoXMgdmlzaXRhZG8gZGVsIG11bmRvLCBjb24gMTcgbWlsbG9uZXMgZGUgdmlzaXRhbnRlcyBhbnVhbGVzLiBUYW1iacOpbiBjYWJlIGRlc3RhY2FyIHF1ZSBzZWlzIGRlIGxvcyBkaWV6IG1vbnVtZW50b3MgbcOhcyB2aXNpdGFkb3MgZGVsIG11bmRvIHNlIGVuY3VlbnRyYW4gZW4gRXVyb3BhLg0KDQpFc3RvcyBkYXRvcyBsb3MgaGVtb3Mgb2J0ZW5pZG8gZGUgV2lraVBlZGlhIG1lZGlhbnRlIGxhIHTDqWNubmljYSBXZWJTY3JhcGluZywgeWEgaGVtb3MgZXhwbGljYWRvIGVzdGUgcHJvY2VzbyBlbiBlbCBwdW50byAyLg0KDQpgYGB7ciBtb25tdW5kbywgZWNobz1UUlVFfQ0KdXJsIDwtICJodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MaXN0X29mX21vc3RfdmlzaXRlZF9wYWxhY2VzX2FuZF9tb251bWVudHMiDQoNCiNTYWNhbW9zIGxhIHRhYmxhIGRlIGxhIHDDoWdpbmEgd2ViLCB1c2Ftb3MgZWwgbWV0b2RvIHdlYiBzY3JhcGxpbmcuDQp3IDwtIHJlYWRfaHRtbCh1cmwpDQpiYiA8LSB3ICU+JSBydmVzdDo6aHRtbF9ub2Rlcyh4cGF0aCA9ICcvaHRtbC9ib2R5L2RpdlszXS9kaXZbM10vZGl2WzVdL2RpdlsxXS90YWJsZScpICU+JSBydmVzdDo6aHRtbF90YWJsZSgpDQpuYW1lcyhiYltbMV1dKSA8LSBjKDE6NikNCg0KI0FycmVnbGFtb3MgbG9zIGRhdG9zOiBjYW1iaWFtb3MgbG9zIG5vbWJyZXMsIGhhY2Vtb3MgZmFjdG9yZXMgeSBjYW1iaWFtb3MgbG9zIGRhdG9zIGEgTWlsbG9uZXMuDQphYSA8LSBhc190aWJibGUoYmJbWzFdXSkgJT4lIHNlbGVjdCgtYygxLDUsNikpICU+JSBzbGljZShjKDI6MTEpKSAlPiUgbXV0YXRlKENvdW50cnkgPSBjKCJDaGluYSIsIkVsIFZhdGljYW5vIiwiRnJhbmNpYSIsIkVzdGFkb3MgVW5pZG9zIiwiSXRhbGlhIiwiR3JlY2lhIiwiSW5kaWEiLCJGcmFuY2lhIiwiQWxlbWFuaWEiLCJSdXNpYSIpKSAlPiUgcmVuYW1lKCJNb251bWVudG8iID0gMSwgIkNpdWRhZCIgPSAyLCAiVmlzaXRhbnRlcyIgPSAzKSAlPiUgcmVsb2NhdGUoNCwuYmVmb3JlID0gMykgJT4lIG11dGF0ZShWaXNpdGFudGVzID0gcGFyc2VfbnVtYmVyKFZpc2l0YW50ZXMpLCBNb251bWVudG8gPSBmYWN0b3IoTW9udW1lbnRvLCBsZXZlbHMgPSBNb251bWVudG9bb3JkZXIoVmlzaXRhbnRlcyldKSwgVmlzaXRhbnRlc00gPSAoVmlzaXRhbnRlcy8xMDAwMDAwKSwgVmlzaXRhbnRlc00gPSByb3VuZChWaXNpdGFudGVzTSwyKSkNCg0KI0FycmVnbGFtb3MgbGEgZm90byBxdWUgdmFtb3MgYSB1dGlsaXphciBkZSBmb25kby4NCnVybCA8LSAiaHR0cHM6Ly9kMmdnOWV2aDQ3Zm45ei5jbG91ZGZyb250Lm5ldC84MDBweF9DT0xPVVJCT1gxNjgyNDQwLmpwZyINCmltZyA8LSBpbWFnZV9yZWFkKHVybCkgJT4lIGltYWdlX3Jlc2l6ZSgiMTUwMHg3NTAiKSAlPiUgaW1hZ2VfY29sb3JpemUoNjAsIiNmZmZmZmYiKQ0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiNIYWNlbW9zIGVsIGdyw6FmaWNvIHByaW5jaXBhbA0KcGxvdCA8LSBnZ3Bsb3QoYWEsYWVzKHg9VmlzaXRhbnRlc00seT1Nb251bWVudG8pKSArDQogICAgICAgICAgICAgIGdlb21fYmFyKGNvbG9yID0gIiMwMDAwMDAiLGZpbGwgPSAiYmx1ZSIsc3RhdD0iaWRlbnRpdHkiLCB3aWR0aCA9IDAuNSkgKw0KICAgICAgICAgICAgICBnZW9tX3RleHQoc2l6ZSA9IDEyLCBzdGF0ID0gImlkZW50aXR5IiwgYWVzKGxhYmVsPSBWaXNpdGFudGVzTSksIGhqdXN0PSAtMSkgKw0KICAgICAgICAgICAgICBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9IGMoIlBhbGFjaW8gUGV0ZXJob2YsIFNhbiBQZXRlc2J1cmdvIiwiQ2F0ZWRyYWwgZGUgQ29sb25pYSwgQ29sb25pYSIsIlRvcnJlIEVpZmZlbCwgUGFyw61zIiwiVGFqIE1haGFsLCBBZ3JhIiwiUGFydGVuw7NuLCBBdGVuYXMiLCJDb2xpc2VvLCBSb21hIiwiTW9udW1lbnRvIGEgTGluY29sbiwgV2FzaGluZ3RvbiIsIlBhbGFjaW8gZGUgVmVyc2FsbGVzLCBWZXJzYWlsbGVzIiwiQmFzw61saWNhIGRlIFNhbiBQZWRybywgRWwgVmF0aWNhbm8iLCJDaXVkYWQgcHJvaGliaWRhLCBQZWvDrW4iKSkgKw0KICAgICAgICAgICAgICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDIwKSwgZXhwYW5kID0gYygwLjEsMikpICsNCiAgICAgICAgICAgICAgbGFicyhmaWxsPU5VTEwsDQogICAgICAgICAgICAgICB4PSBOVUxMLA0KICAgICAgICAgICAgICAgeT1OVUxMLA0KICAgICAgICAgICAgICAgdGl0bGU9Ik1vbnVtZW50b3MgbcOhcyB2aXNpdGFkb3MgZGVsIG11bmRvIiwNCiAgICAgICAgICAgICAgIHN1YnRpdGxlID0gImVuIE1pbGxvbmVzIGRlIHZpc2l0YW50ZXMgYW51YWxlcyIsDQogICAgICAgICAgICAgICBjYXB0aW9uPSJGdWVudGU6IFdpa2lwZWRpYSIpICsNCiAgICAgICAgICAgICAgIHRoZW1lKCBwbG90LmJhY2tncm91bmQgPSBOVUxMLA0KICAgICAgICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgICAgICBwYW5lbC5ncmlkICA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsc2l6ZSA9IDIwKSwNCiAgICAgICAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgc2l6ZSA9IDMwKSwNCiAgICAgICAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgc2l6ZSA9IDIwKSwNCiAgICAgICAgICAgICAgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgICAgICAgICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKHQgPSA1LCByID0gMjUsIGIgPSA1LDE1KSwNCiAgICAgICAgICAgICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNlOGQ3YTMiLGNvbG91ciA9IE5VTEwpKQ0KI0HDsWFkaW1vcyB1bmFzIGltw6FnZW5lcyBhbCBncsOhZmljbyBwcmluY2lwYWwNCnBsb3RkIDwtIGdnZHJhdyhwbG90KSArIGRyYXdfaW1hZ2UoImh0dHBzOi8vdXBsb2FkLndpa2ltZWRpYS5vcmcvd2lraXBlZGlhL2NvbW1vbnMvdGh1bWIvZi9mYS9GbGFnX29mX3RoZV9QZW9wbGUlMjdzX1JlcHVibGljX29mX0NoaW5hLnN2Zy8xMjAwcHgtRmxhZ19vZl90aGVfUGVvcGxlJTI3c19SZXB1YmxpY19vZl9DaGluYS5zdmcucG5nIiwgeD0gMC4yNywgeSA9IDAuODQsIHdpZHRoID0gMC4wNSwgaGVpZ2h0ID0gMC4wNSkgKyBkcmF3X2ltYWdlKCJodHRwczovL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9jb21tb25zL3RodW1iLzAvMDAvRmxhZ19vZl90aGVfVmF0aWNhbl9DaXR5LnN2Zy81MDBweC1GbGFnX29mX3RoZV9WYXRpY2FuX0NpdHkuc3ZnLnBuZyIseD0gMC4yNywgeSA9IDAuNzUsIHdpZHRoID0wLjA1LCBoZWlnaHQgPSAwLjA1LCBzY2FsZSA9IDEuMykgKyBkcmF3X2ltYWdlKCJodHRwczovL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9lbi90aHVtYi9jL2MzL0ZsYWdfb2ZfRnJhbmNlLnN2Zy84MDBweC1GbGFnX29mX0ZyYW5jZS5zdmcucG5nIiwgeD0wLjI3LCB5PTAuNjYsIHdpZHRoPTAuMDUsIGhlaWdodCA9IDAuMDUpICsgZHJhd19pbWFnZSgiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvZW4vdGh1bWIvYS9hNC9GbGFnX29mX3RoZV9Vbml0ZWRfU3RhdGVzLnN2Zy8xMjVweC1GbGFnX29mX3RoZV9Vbml0ZWRfU3RhdGVzLnN2Zy5wbmciLCB4PTAuMjcsIHk9MC41NzUsIHdpZHRoPTAuMDQ1LCBoZWlnaHQgPSAwLjA1LCBzY2FsZSA9IDAuOSkgKyBkcmF3X2ltYWdlKCJodHRwczovL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9lbi90aHVtYi8wLzAzL0ZsYWdfb2ZfSXRhbHkuc3ZnLzEyNXB4LUZsYWdfb2ZfSXRhbHkuc3ZnLnBuZyIsIHg9MC4yNywgeT0wLjQ5LCB3aWR0aD0wLjA1LCBoZWlnaHQgPSAwLjA1KSArIGRyYXdfaW1hZ2UoImh0dHBzOi8vdXBsb2FkLndpa2ltZWRpYS5vcmcvd2lraXBlZGlhL2NvbW1vbnMvdGh1bWIvNS81Yy9GbGFnX29mX0dyZWVjZS5zdmcvMTI1cHgtRmxhZ19vZl9HcmVlY2Uuc3ZnLnBuZyIsIHg9MC4yNywgeT0wLjQwLCB3aWR0aD0wLjA1LCBoZWlnaHQgPSAwLjA1KSArIGRyYXdfaW1hZ2UoImh0dHBzOi8vdXBsb2FkLndpa2ltZWRpYS5vcmcvd2lraXBlZGlhL2VuL3RodW1iLzQvNDEvRmxhZ19vZl9JbmRpYS5zdmcvMTI1cHgtRmxhZ19vZl9JbmRpYS5zdmcucG5nIiwgeD0wLjI3LCB5PTAuMzE1LCB3aWR0aD0wLjA1LCBoZWlnaHQgPSAwLjA1KSArIGRyYXdfaW1hZ2UoImh0dHBzOi8vdXBsb2FkLndpa2ltZWRpYS5vcmcvd2lraXBlZGlhL2VuL3RodW1iL2MvYzMvRmxhZ19vZl9GcmFuY2Uuc3ZnLzgwMHB4LUZsYWdfb2ZfRnJhbmNlLnN2Zy5wbmciLCB4PTAuMjcsIHk9MC4yMjUsIHdpZHRoPTAuMDUsIGhlaWdodCA9IDAuMDUpICsgZHJhd19pbWFnZSgiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvZW4vdGh1bWIvYi9iYS9GbGFnX29mX0dlcm1hbnkuc3ZnLzEyNXB4LUZsYWdfb2ZfR2VybWFueS5zdmcucG5nIiwgeD0wLjI3LCB5PTAuMTQsIHdpZHRoPTAuMDUsIGhlaWdodCA9IDAuMDUpICsgZHJhd19pbWFnZSgiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvZW4vdGh1bWIvZi9mMy9GbGFnX29mX1J1c3NpYS5zdmcvMTI1cHgtRmxhZ19vZl9SdXNzaWEuc3ZnLnBuZyIsIHg9MC4yNywgeT0wLjA2LCB3aWR0aD0wLjA1LCBoZWlnaHQgPSAwLjA1KQ0KI1BvciDDumx0aW1vIGHDsWFkaW1vcyB1biBmb25kbw0KZ3JhZmljb21vbiA8LSBnZ2RyYXcoKSArIGRyYXdfaW1hZ2UoaW1nKSArIGRyYXdfcGxvdChwbG90ZCkNCmRpci5jcmVhdGUoaGVyZTo6aGVyZSgiaW1hZ2VuZXMiKSkNCiNHdWFyZGFtb3MgZWwgZ3LDoWZpY28NCmdnc2F2ZShmaWxlbmFtZSA9ICJncmFmaWNtb253b3JsZC5wbmciLHBsb3QgPSBncmFmaWNvbW9uLCBkZXZpY2UgPSAicG5nIiwgcGF0aCA9IGhlcmU6OmhlcmUoImltYWdlbmVzIiksIHdpZHRoID0gNTAuOCwgaGVpZ2h0ID0gMjguNTc1LCB1bml0cyA9ICJjbSIpDQpgYGANCiFbTW9udW1lbnRvcyBtw6FzIHZpc2l0YWRvcyBkZWwgbXVuZG9dKGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS94aTc2NS9UcmFiYWpvR3J1cG8vbWFpbi9ncmFmaWNtb253b3JsZC5qcGVnKQ0KDQpUYW1iacOpbiBoZW1vcyBoZWNobyB1biBtYXBhIGRvbmRlIHNlIG11ZXN0cmEgbGFzIHViaWNhY2lvbmVzIGRlIGxvcyB5YSBtZW5jaW9uYWRvcyBtb251bWVudG9zLg0KDQpgYGB7ciwgZWNobz1UUlVFfQ0KI0Fwcm92ZWNoYW1vcyBsb3MgZGF0b3MgZW1wbGVhZG9zIHBhcmEgZWwgZ3LDoWZpY28gYW50ZXJpb3IgeSBsb3MgYXJyZWdsYW1vcyB1biBwb2NvDQp3b3JsZCA8LSBtYXBfZGF0YSgid29ybGQiKSAlPiUgbXV0YXRlKGNvbG9yID0gY2FzZV93aGVuKHJlZ2lvbiA9PSAiQ2hpbmEiIH4gMSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW9uID09ICJWYXRpY2FuIiB+IDIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lvbiA9PSAiRnJhbmNlIiB+IDMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lvbiA9PSAiVVNBIiB+IDQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lvbiA9PSAiSXRhbHkiIH4gNSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW9uID09ICJHcmVlY2UiIH4gNiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW9uID09ICJJbmRpYSIgfiA3LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpb24gPT0gIkdlcm1hbnkiIH4gOCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW9uID09ICJSdXNzaWEiIH4gOSkpICU+JSBtdXRhdGUoY29sb3IgPSBpZl9lbHNlKGlzLm5hKGNvbG9yKSwwLGNvbG9yKSkNCg0KI0hhY2Vtb3MgdW4gZGF0YWZyYW1lIGNvbiBsYXMgY29vcmRlbmFkYXMgZGUgY2FkYSBtb251bWVudG8NCmNpdWRhZGVzIDwtIGMoIlBla8OtbiIsIkVsIFZhdGljYW5vIiwiVmVyc2FpbGxlcyIsIldhc2hpbmd0b24iLCJSb21hIiwiQXRlbmFzIiwiQWdyYSIsIlBhcsOtcyIsIkNvbG9uaWEiLCJTYW4gUGV0ZXNidXJnbyIpDQpsYXQgPC0gYygzOS45MDQyLDQxLjkwMjksNDguODAxNCwzOC45MDcyLDQxLjkwMjgsMzcuOTgzOCwyNy4xNzY3LDQ4Ljg1NjYsNTAuOTM3NSw1OS45MzExKQ0KbG9uZyA8LSBjKDExNi40MDc0LDEyLjQ1MzQsMi4xMzAxLC03Ny4wMzY5LDEyLjQ5NjQsMjMuNzI3NSw3OC4wMDgxLDIuMzUyMiw2Ljk2MDMsMzAuMzYwOSkNCg0KY29vcmRjaXVkYWRlcyA8LSBkYXRhLmZyYW1lKGNpdWRhZGVzLGxhdCxsb25nKQ0KI0hhY2Vtb3MgbGFzIGzDrW5lYXMgcXVlIHVuaXJhbiBsYXMgaW3DoWdlbmVzIGNvbiBsYSB1YmljYWNpw7NuIGRlIGNhZGEgbW9udW1lbnRvLg0KbGluZWFzIDwtIGRhdGEuZnJhbWUoaWQgPSBjKCJQZWvDrW4iLCJFbCBWYXRpY2FubyIsIlZlcnNhaWxsZXMiLCJXYXNoaW5ndG9uIiwiUm9tYSIsIkF0ZW5hcyIsIkFncmEiLCJQYXLDrXMiLCJDb2xvbmlhIiwiU2FuIFBldGVzYnVyZ28iKSwNCiAgICAgICAgICAgICAgICAgICAgIGxhdF8xID0gYygzOS45MDQyLDQxLjkwMjksNDguODAxNCwzOC45MDcyLDQxLjkwMjgsMzcuOTgzOCwyNy4xNzY3LDQ4Ljg1NjYsNTAuOTM3NSw1OS45MzExKSwNCiAgICAgICAgICAgICAgICAgICAgIGxvbmdfMSA9IGMoMTE2LjQwNzQsMTIuNDUzNCwyLjEzMDEsLTc3LjAzNjksMTIuNDk2NCwyMy43Mjc1LDc4LjAwODEsMi4zNTIyLDYuOTYwMywzMC4zNjA5KSwNCiAgICAgICAgICAgICAgICAgICAgIGxhdF8yID0gYyg0NSwxMyw0NSwyNSwyMCw1MCwwLDc1LDEwMCw5MCksDQogICAgICAgICAgICAgICAgICAgICBsb25nXzIgPSBjKDE1MCw0MCwtNTAsLTEzMCwtMjAsNjAsMTE1LC01MCwtMTAsNDApKQ0KI0NhcmdhbW9zIGxhIGltw6FnZW4gZGUgY2FkYSBtb251bWVudG8geSBsZSBhw7FhZGltb3MgdW4gYm9yZGUuDQpjaGluYSA8LSBpbWFnZV9yZWFkKCJodHRwczovL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9jb21tb25zL3RodW1iL2EvYTcvRm9yYmlkZGVuX0NpdHlfQmVpamluZ19TaGVud3VtZW5fR2F0ZS5KUEcvODAwcHgtRm9yYmlkZGVuX0NpdHlfQmVpamluZ19TaGVud3VtZW5fR2F0ZS5KUEciKSAlPiUgaW1hZ2VfYm9yZGVyKCIjZmZmZmZmIiwiMTB4MTAiKQ0KdmF0aWNhbm8gPC0gaW1hZ2VfcmVhZCgiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy90aHVtYi9mL2Y1L0Jhc2lsaWNhX2RpX1Nhbl9QaWV0cm9faW5fVmF0aWNhbm9fU2VwdGVtYmVyXzIwMTUtMWEuanBnLzEyMDBweC1CYXNpbGljYV9kaV9TYW5fUGlldHJvX2luX1ZhdGljYW5vX1NlcHRlbWJlcl8yMDE1LTFhLmpwZyIpICU+JSBpbWFnZV9ib3JkZXIoIiNmZmZmZmYiLCIxMHgxMCIpDQp2ZXJzYWlsbCA8LSBpbWFnZV9yZWFkKCJodHRwczovL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9jb21tb25zL3RodW1iLzIvMjgvUGFyY19jaGF0ZWF1X3ZlcnNhaWxsZXMuanBnLzgwMHB4LVBhcmNfY2hhdGVhdV92ZXJzYWlsbGVzLmpwZyIpICU+JSBpbWFnZV9ib3JkZXIoIiNmZmZmZmYiLCIxMHgxMCIpDQp3YXNoIDwtIGltYWdlX3JlYWQoImh0dHBzOi8vdXBsb2FkLndpa2ltZWRpYS5vcmcvd2lraXBlZGlhL2NvbW1vbnMvdGh1bWIvNC80Zi9MaW5jb2xuX01lbW9yaWFsXyUyOE1heV8yMDE0JTI5X2Nyb3AuanBnLzgwMHB4LUxpbmNvbG5fTWVtb3JpYWxfJTI4TWF5XzIwMTQlMjlfY3JvcC5qcGciKSAlPiUgaW1hZ2VfYm9yZGVyKCIjZmZmZmZmIiwiMTB4MTAiKQ0Kcm9tYSA8LSBpbWFnZV9yZWFkKCJodHRwczovL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9jb21tb25zL3RodW1iLzcvNzQvQ29sb3NzZW9fMjAwOC5qcGcvODAwcHgtQ29sb3NzZW9fMjAwOC5qcGciKSAlPiUgaW1hZ2VfYm9yZGVyKCIjZmZmZmZmIiwiMTB4MTAiKQ0KYXRlbmFzIDwtIGltYWdlX3JlYWQoImh0dHBzOi8vaGlzdG9yaWFld2ViLmNvbS93cC1jb250ZW50L3VwbG9hZHMvMjAxOC8wMi9WaXN0YS1nZW5lcmFsLWRlbC1QYXJ0ZW4lQzMlQjNuLWRlLUF0ZW5hcy5qcGciKSAlPiUgaW1hZ2VfYm9yZGVyKCIjZmZmZmZmIiwiMTB4MTAiKQ0KYWdyYSA8LSBpbWFnZV9yZWFkKCJodHRwczovL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9jb21tb25zL3RodW1iLzEvMWQvVGFqX01haGFsXyUyOEVkaXRlZCUyOS5qcGVnLzgwMHB4LVRhal9NYWhhbF8lMjhFZGl0ZWQlMjkuanBlZyIpICU+JSBpbWFnZV9ib3JkZXIoIiNmZmZmZmYiLCIxMHgxMCIpDQpwYXJpcyA8LSBpbWFnZV9yZWFkKCJodHRwczovL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9jb21tb25zL3RodW1iLzgvODUvVG91cl9FaWZmZWxfV2lraW1lZGlhX0NvbW1vbnNfJTI4Y3JvcHBlZCUyOS5qcGcvMzYwcHgtVG91cl9FaWZmZWxfV2lraW1lZGlhX0NvbW1vbnNfJTI4Y3JvcHBlZCUyOS5qcGciKSAlPiUgaW1hZ2VfYm9yZGVyKCIjZmZmZmZmIiwiMTB4MTAiKQ0KY29sb25pYSA8LSBpbWFnZV9yZWFkKCJodHRwczovL21lZ2Fjb25zdHJ1Y2Npb25lcy5uZXQvaW1hZ2VzL2VkaWZpY2lvcy1yZWxpZ2lvc29zL2ZvdG8vY29sb25pYS1jYXRlZHJhbC5qcGciKSAlPiUgaW1hZ2VfYm9yZGVyKCIjZmZmZmZmIiwiMTB4MTAiKQ0KcGV0ZSA8LSBpbWFnZV9yZWFkKCJodHRwczovL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9jb21tb25zL3RodW1iL2YvZjUvR3JhbmRfQ2FzY2FkZV9pbl9QZXRlcmhvZl8wMS5qcGcvODAwcHgtR3JhbmRfQ2FzY2FkZV9pbl9QZXRlcmhvZl8wMS5qcGciKSAlPiUgaW1hZ2VfYm9yZGVyKCIjZmZmZmZmIiwiMTB4MTAiKQ0KI0hhY2Vtb3MgZWwgZ3LDoWZpY28gcHJpbmNpcGFsDQptYXBhbSA8LSBnZ3Bsb3QoKSArIGdlb21fbWFwKGRhdGEgPSB3b3JsZCwgbWFwID0gd29ybGQsIGFlcyhsb25nLCBsYXQsIG1hcF9pZCA9IHJlZ2lvbiksIGNvbG9yID0gIiMwMDAwMDAiLCBmaWxsID0gIiNmN2VjYTEiKSArDQogICAgICAgICAgICAgICAgICAgIGdlb21fbWFwKGRhdGEgPSB3b3JsZCAlPiUgZmlsdGVyKGNvbG9yPT0xKSwgbWFwID0gd29ybGQsIGFlcyhsb25nLCBsYXQsIG1hcF9pZCA9IHJlZ2lvbiksIGNvbG9yID0gIiMwMDAwMDAiLCBmaWxsID0gInJlZCIpICsNCiAgICAgICAgICAgICAgICAgICAgZ2VvbV9tYXAoZGF0YSA9IHdvcmxkICU+JSBmaWx0ZXIoY29sb3I9PTIpLCBtYXAgPSB3b3JsZCwgYWVzKGxvbmcsIGxhdCwgbWFwX2lkID0gcmVnaW9uKSwgY29sb3IgPSAiIzAwMDAwMCIsIGZpbGwgPSAieWVsbG93IikgKw0KICAgICAgICAgICAgICAgICAgICBnZW9tX21hcChkYXRhID0gd29ybGQgJT4lIGZpbHRlcihjb2xvcj09MyksIG1hcCA9IHdvcmxkLCBhZXMobG9uZywgbGF0LCBtYXBfaWQgPSByZWdpb24pLCBjb2xvciA9ICIjMDAwMDAwIiwgZmlsbCA9ICIjOWQwNWZmIikgKw0KICAgICAgICAgICAgICAgICAgICBnZW9tX21hcChkYXRhID0gd29ybGQgJT4lIGZpbHRlcihjb2xvcj09NCksIG1hcCA9IHdvcmxkLCBhZXMobG9uZywgbGF0LCBtYXBfaWQgPSByZWdpb24pLCBjb2xvciA9ICIjMDAwMDAwIiwgZmlsbCA9ICIjYWI2ODAwIikgKw0KICAgICAgICAgICAgICAgICAgICBnZW9tX21hcChkYXRhID0gd29ybGQgJT4lIGZpbHRlcihjb2xvcj09NSksIG1hcCA9IHdvcmxkLCBhZXMobG9uZywgbGF0LCBtYXBfaWQgPSByZWdpb24pLCBjb2xvciA9ICIjMDAwMDAwIiwgZmlsbCA9ICJ5ZWxsb3ciKSArDQogICAgICAgICAgICAgICAgICAgIGdlb21fbWFwKGRhdGEgPSB3b3JsZCAlPiUgZmlsdGVyKGNvbG9yPT02KSwgbWFwID0gd29ybGQsIGFlcyhsb25nLCBsYXQsIG1hcF9pZCA9IHJlZ2lvbiksIGNvbG9yID0gIiMwMDAwMDAiLCBmaWxsID0gIiMwMDRkZmYiKSArDQogICAgICAgICAgICAgICAgICAgIGdlb21fbWFwKGRhdGEgPSB3b3JsZCAlPiUgZmlsdGVyKGNvbG9yPT03KSwgbWFwID0gd29ybGQsIGFlcyhsb25nLCBsYXQsIG1hcF9pZCA9IHJlZ2lvbiksIGNvbG9yID0gIiMwMDAwMDAiLCBmaWxsID0gIiNmZjkzMDAiKSArDQogICAgICAgICAgICAgICAgICAgIGdlb21fbWFwKGRhdGEgPSB3b3JsZCAlPiUgZmlsdGVyKGNvbG9yPT04KSwgbWFwID0gd29ybGQsIGFlcyhsb25nLCBsYXQsIG1hcF9pZCA9IHJlZ2lvbiksIGNvbG9yID0gIiMwMDAwMDAiLCBmaWxsID0gIiNhNDAzNGIiKSArDQogICAgICAgICAgICAgICAgICAgIGdlb21fbWFwKGRhdGEgPSB3b3JsZCAlPiUgZmlsdGVyKGNvbG9yPT05KSwgbWFwID0gd29ybGQsIGFlcyhsb25nLCBsYXQsIG1hcF9pZCA9IHJlZ2lvbiksIGNvbG9yID0gIiMwMDAwMDAiLCBmaWxsID0gIiMyMzhhMDAiKSArDQogICAgICAgICAgICAgICAgICAgIGdlb21fc2VnbWVudChkYXRhID0gbGluZWFzLCBhZXMoeCA9IGxvbmdfMSwgeSA9IGxhdF8xLCB4ZW5kID0gbG9uZ18yLCB5ZW5kID0gbGF0XzIpLCBjb2xvciA9ICIjMDAwMDAwIiwgc2l6ZSA9IDIsIGFscGhhID0gMC44LCBsaW5lZW5kID0gInJvdW5kIikgKw0KICAgICAgICAgICAgICAgICAgICBnZW9tX3BvaW50KGRhdGEgPSBjb29yZGNpdWRhZGVzLCBhZXMoeCA9IGxvbmcseSA9IGxhdCksIHNpemUgPSAyKSArDQogICAgICAgICAgICAgICAgICAgIHlsaW0oLTU1LE5BKSArDQogICAgICAgICAgICAgICAgICAgIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjYTZmZmZiIiksIHBhbmVsLmdyaWQgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gIiMwMDAwMDAiKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICAgICAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpKQ0KI0HDsWFkaW1vcyBsYXMgaW3DoWdlbmVzIGRlIGxvcyBtb251bWVudG9zIGFsIGdyw6FmaWNvIHByaW5jaXBhbC4NCnBsb3RtYXAgPC0gZ2dkcmF3KG1hcGFtKSArICBkcmF3X2ltYWdlKGNoaW5hLCB4ID0gMC44LCB5ID0gMC41NSwgd2lkdGggPSAwLjE1LCBoZWlnaHQgPSAwLjE1KSArDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJhd19pbWFnZSh2YXRpY2FubywgeCA9IDAuNTUsIHkgPSAwLjQsIHdpZHRoID0gMC4xLCBoZWlnaHQgPSAwLjEpICsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcmF3X2ltYWdlKHZlcnNhaWxsLCB4ID0gMC4zNSwgeSA9IDAuNiwgd2lkdGggPSAwLjEwLCBoZWlnaHQgPSAwLjEwKSArDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJhd19pbWFnZSh3YXNoLCB4ID0gMC4xLCB5ID0gMC41LCB3aWR0aCA9IDAuMTUsIGhlaWdodCA9IDAuMTUpICsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcmF3X2ltYWdlKHJvbWEsIHggPSAwLjQsIHkgPSAwLjQ1LCB3aWR0aCA9IDAuMSwgaGVpZ2h0ID0gMC4xKSArDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJhd19pbWFnZShhdGVuYXMsIHggPSAwLjYsIHkgPSAwLjYsIHdpZHRoID0gMC4xMCwgaGVpZ2h0ID0gMC4xMCkgKw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRyYXdfaW1hZ2UoYWdyYSwgeCA9IDAuNywgeSA9IDAuMywgd2lkdGggPSAwLjE1LCBoZWlnaHQgPSAwLjE1KSArDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJhd19pbWFnZShwYXJpcywgeCA9IDAuMywgeSA9IDAuOCwgd2lkdGggPSAwLjE1LCBoZWlnaHQgPSAwLjE1KSArDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJhd19pbWFnZShjb2xvbmlhLCB4ID0gMC40LCB5ID0gMC44Mywgd2lkdGggPSAwLjE1LCBoZWlnaHQgPSAwLjE1KSArDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJhd19pbWFnZShwZXRlLCB4ID0gMC41NSwgeSA9IDAuODUsIHdpZHRoID0gMC4xLCBoZWlnaHQgPSAwLjEpDQojR3VhcmRhbW9zIGVsIGdyw6FmaWNvDQpnZ3NhdmUoZmlsZW5hbWUgPSAibWFwbW9ud29ybGQucG5nIixwbG90ID0gcGxvdG1hcCwgZGV2aWNlID0gInBuZyIsIHBhdGggPSBoZXJlOjpoZXJlKCJpbWFnZW5lcyIpLCB3aWR0aCA9IDUwLjgsIGhlaWdodCA9IDI4LjU3NSwgdW5pdHMgPSAiY20iKQ0KYGBgDQohW1ViaWNhY2nDs24gZGUgbG9zIDEwIG1vbnVtZW50b3MgbcOhcyB2aXNpdGFkb3MgZGVsIG11bmRvXShodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20veGk3NjUvVHJhYmFqb0dydXBvL21haW4vbWFwbW9ud29ybGQuanBlZykNCg0KIyMjICoqSW5ncmVzb3MgeSBnYXN0b3MgcG9yIGVsIHR1cmlzbW8qKg0KDQpFc3Bhw7FhIGVzIGVsIHNlZ3VuZG8gcGHDrXMgY29uIG3DoXMgaW5ncmVzb3MgcG9yIGVsIHR1cmlzbW8NCg0KU2UgbWFudGllbmUgZW4gZWwgcG9kaW8gZ3JhY2lhcyBhIGxvcyA4MyBtaWxsb25lcyBkZSBleHRyYW5qZXJvcyBxdWUgdmlzaXRhcm9uIGVsIHBhw61zIHkgYSBsb3MgY2VyY2EgZGUgNjcuMzAwIG1pbGxvbmVzIHF1ZSBkZWphcm9uDQoNCkVsIHR1cmlzbW8gZXMgdW5hIG1pbmEgZGUgb3JvIHBhcmEgRXNwYcOxYS4gTnVlc3RybyBwYcOtcyBsb2dyw7MgbWFudGVuZXJzZSBlbiBsYSB0ZXJjZXJhIHBvc2ljacOzbiBlbiBsYSBjbGFzaWZpY2FjacOzbiBtdW5kaWFsIHRhbnRvIHBvciBlbCBuw7ptZXJvIGRlIHR1cmlzdGFzIGludGVybmFjaW9uYWxlcyBjb21vIHBvciBsYSBjYW50aWRhZCBkZSBpbmdyZXNvcyBwb3IgZWwgdHVyaXNtby4gRW4gY29uY3JldG8sIDgzIG1pbGxvbmVzIGRlIHZpYWplcm9zIHZpc2l0YXJvbiBFc3Bhw7FhIGVuIDIwMTgsIHVuIDElIG3DoXMgcXVlIGVsIGHDsW8gYW50ZXJpb3IsIHkgZGVqYXJvbiBhbHJlZGVkb3IgZGUgNjcuMzAwIG1pbGxvbmVzIGRlIGV1cm9zLCB1biA0JSBtw6FzLCBzZWfDum4gaW5kaWNhIGxhIE9yZ2FuaXphY2nDs24gTXVuZGlhbCBkZWwgVHVyaXNtbyAoT01UKS4NCg0KUG9yIGxsZWdhZGFzLCBudWVzdHJvIHBhw61zIHPDs2xvIHNlIHNpdHXDsyBwb3IgZGV0csOhcyBkZSBGcmFuY2lhLCBxdWUgcmVnaXN0csOzIDg5IG1pbGxvbmVzIGRlIHR1cmlzdGFzICgrMyUpLCB5IHNlIGNvbG9jw7MgcG9yIGRlbGFudGUgZGUgRXN0YWRvcyB1bmlkb3MgKDgwIG1pbGxvbmVzIHkgdW4gYXVtZW50byBkZWwgNCUpLiBFbiBjdWFudG8gYSBsb3MgaW5ncmVzb3MsIGVzIEVFIFVVIGVsIHF1ZSBsaWRlcmEgZWwgcmFua2luZyB5IEZyYW5jaWEgc2Ugc2l0w7phIHBvciBkZXRyw6FzIGRlIEVzcGHDsWEuIEVzdGFkb3MgVW5pZG9zIGluZ3Jlc8OzIGVsIGHDsW8gcGFzYWRvIDIxNC4wMDAgbWlsbG9uZXMgZGUgZMOzbGFyZXMgcG9yIHR1cmlzbW8gKHVuIDIlIG3DoXMpIHkgRnJhbmNpYSwgNjcuMDAwIG1pbGxvbmVzICh1biA2JSBtw6FzKS4gTG9zIHNpZ3VpZW50ZXMgZGVzdGlub3MgZW4gY3VhbnRvIGEgbGFzIGxsZWdhZGFzIHNvbiBDaGluYSwgSXRhbGlhLCBUdXJxdcOtYSwgTcOpeGljbywgQWxlbWFuaWEsIFRhaWxhbmRpYSB5IGVsIFJlaW5vIFVuaWRvLg0KDQpFbiBjdWFudG8gYSBpbmdyZXNvcywgVGFpbGFuZGlhIHNlIGVuY3VlbnRyYSBlbiBjdWFydG8gbHVnYXIsIHNlZ3VpZGEgZGVsIFJlaW5vIFVuaWRvLCBJdGFsaWEsIEF1c3RyYWxpYSwgQWxlbWFuaWEsIEphcMOzbiDigJNxdWUgZW50csOzIGVuIGVsIGdydXBvIGRlIGxvcyBkaWV6IHByaW1lcm9zIGRlc3B1w6lzIGRlIHNpZXRlIGHDsW9zIGRlIGNyZWNpbWllbnRv4oCTIHkgQ2hpbmEsIGNvbiB1biBpbmNyZW1lbnRvIGRlbCAyMSUuDQoNCmBgYHtyLCBlY2hvPVRSVUV9DQojSW1wb3J0YW1vcyBsb3MgZGF0b3MgZGUgbG9zIGluZ3Jlc29zDQp1cmwzIDwtICJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vUGF2bGluYWRpbmtvdmEvMTAvbWFpbi9pbmdyZXNvc19wYWlzZXMuY3N2Ig0KcnI8LSByaW86OmltcG9ydCh1cmwzLCBzZXRjbGFzcz0idGliYmxlIikNCg0KIGluZ3Jlc29zIDwtIGdncGxvdChyciwgYWVzKHg9cmVvcmRlcihQYWlzLE1pbGVzX21pbGxvbmVzX2RvbGFyZXMpLCB5PU1pbGVzX21pbGxvbmVzX2RvbGFyZXMsIGZpbGw9UGFpcykpKw0KICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQogIGNvb3JkX3BvbGFyKHN0YXJ0ID0gMCkgKw0KICBsYWJzICh4PSJQYWlzZXMiKSArIGxhYnMoeT0iTWlsZXMgZGUgbWlsbG9uZXMgZGUgZMOzbGFyZXMiKSArIGxhYnModGl0bGUgPSAiUGFpc2VzIGNvbiBtw6FzIGluZ3Jlc29zIHBvciBlbCBzZWN0b3IgdHVyw61zdGljbyAiKSArIGxhYnMoc3VidGl0bGUgPSAiRW4gbWlsZXMgZGUgbWlsbG9uZXMgZGUgZMOzbGFyZXMiKQ0KDQppbmdyZXNvcw0KDQoNCmBgYA0KDQojIyMgKioqR2FzdG8gdHVyw61zdGljbyBlbiBFdXJvcGEqKioNCg0KRW4gcHJpbWVyIGx1Z2FyIGhlbW9zIGhlY2hvIHVuIGdyw6FmaWNvIGRlIHB1bnRvcyBlbiBlbCBxdWUgaGVtb3MgaW50ZW50YWRvIGJ1c2NhciBzaSBoYWLDrWEgcmVsYWNpw7NuIGVudHJlIGxhIHJlbnRhIHBlciBjYXBpdGEgZGUgbG9zIHBhw61zZXMgeSBlbCBnYXN0byBlbiB0dXJpc21vIGRlIHN1cyBoYWJpdGFudGVzLiANCg0KUGFyYSBlbGxvIGhlbW9zIG9idGVuaWRvIGRhdG9zIGRlbCBQSUIsIGxhIHBvYmxhY2nDs24geSBlbCBnYXN0byB0dXLDrXN0aWNvIGRlIGxvcyBwYcOtc2VzIGRlIGxhIFVuacOzbiBFdXJvcGVhLiBMb3MgZGF0b3MgbG9zIGhlbW9zIG9idGVuaWRvIGEgdHJhdsOpcyBkZSBsYSBBUEkgZGUgRXVyb3N0YXQgY29tbyB5YSBoZW1vcyBjb21lbnRhZG8gZW4gZWwgYXBhcnRhZG8gMi4NCg0KIyMjIyBHcsOhZmljbyBkZSBwdW50b3MNCg0KRW4gZXN0ZSBncsOhZmljbyBwb2RlbW9zIHZlciBjb21vIHNpIHF1ZSBoYXkgdW5hIHJlbGFjacOzbiBwb3NpdGl2YSBlbnRyZSBlbCBQSUIgcGVyIGNhcGl0YSB5IGVsIGdhc3RvIGVuIHR1cmlzbW8gZGUgc3VzIGhhYml0YW50ZXMsIGVzdG8gc2UgZGViZSBhIHF1ZSBlbCB0dXJpc21vIG5vIGVzIHVuIHNlcnZpY2lvIGRlIHByaW1lcmEgbmVjZXNpZGFkLiBFc3RlIGdyw6FmaWNvIG5vcyBwYXJlY2Ugw7p0aWwgcGFyYSBzYWJlciBxdWUgcGHDrXNlcyBkZWJlcsOtYW4gc2VyIG9iamV0aXZvIGRlIGxhcyBjYW1wYcOxYXMgZGUgcHVibGljaWRhZCBkZWwgc2VjdG9yIHR1csOtc3RpY28gZXNwYcOxb2wuDQoNCiMjIyMgTWFwYSBkZSBFdXJvcGENCg0KRW4gZXN0ZSBtYXBhIGhlbW9zIGlsdXN0cmFkbyBsb3MgZGF0b3Mgb2J0ZW5pZG9zIGFudGVyaW9ybWVudGUuIE1pcmFuZG8gZWwgZ3LDoWZpY28gcsOhcGlkYW1lbnRlIHBvZGVtb3MgaWRlbnRpZmljYXIgbG9zIHBhw61zZXMgcXVlIG3DoXMgZ2FzdGFuIGVuIHR1cmlzbW8gcG9yIGhhYml0YW50ZS4gQ2FiZSBkZXN0YWNhciBxdWUgbG9zIHBhw61zZXMgZGVsIE5vcnRlIGRlIEV1cm9wYSBzb24gbG9zIHF1ZSBtw6FzIGdhc3RhbiBlbiB0dXJpc21vLCBhc8OtIGNvbW8gcXVlIGxvcyBwYcOtc2VzIGRlbCBFc3RlIHNvbiBsb3MgcXVlIG1lbm9zLg0KDQoNCg0KYGBge3IsIGVjaG89VFJVRX0NCiNFbiBsb3Mgc2lndWllbnRlcyBjw7NkaWdvcyBvYnRlbmVtb3MgbG9zIGRhdG9zIGRlIGxhIEFQSSBkZSBldXJvc3RhdCB5IGxvcyBhcnJlZ2xhbW9zIHVuIHBvY28NCiNQSUIgZW4gTWlsbG9uZXMNCkdEUCA8LSBldXJvc3RhdDo6Z2V0X2V1cm9zdGF0KCJuYW1hXzEwX2dkcCIpDQpHRFAgPC0gR0RQICU+JSBmaWx0ZXIoIG5hX2l0ZW0gPT0gIkIxR1EiLCB1bml0ID09ICJDUF9NRVVSIikgJT4lIHNlbGVjdChnZW8sdGltZSx2YWx1ZXMpDQpHRFAgPC0gR0RQICU+JSByZW5hbWUoIGNvZGUgPSBnZW8pDQpjaWQgPC0gZXVyb3N0YXQ6OmV1X2NvdW50cmllcw0KR0RQIDwtIGlubmVyX2pvaW4oR0RQLGNpZCwgYnkgPSAiY29kZSIgKQ0KR0RQIDwtIEdEUCAlPiUgc2VsZWN0KC1jKGxhYmVsKSkgJT4lIHJlbG9jYXRlKG5hbWUsIC5iZWZvcmUgPSBjb2RlKQ0KR0RQIDwtIEdEUCAlPiUgcmVuYW1lX2F0KHZhcnMoY29sbmFtZXMoR0RQKSksIH4gYygiQ291bnRyeSIsIkNvZGUiLCJEYXRlIiwiUElCIikpDQojR0FTVE8gVFVSSVNUSUNPIE1pbGVzDQpHVCA8LSBldXJvc3RhdDo6Z2V0X2V1cm9zdGF0KCJ0b3VyX2RlbV9leHRvdCIpDQpHVCA8LSBHVCAlPiUgZmlsdGVyKGR1cmF0aW9uID09ICJOX0dFMSIsIHB1cnBvc2UgPT0gIlRPVEFMIix1bml0ID09IlRIU19FVVIiLCBwYXJ0bmVyID09ICJXT1JMRCIpDQpHVCA8LSBHVCAlPiUgc2VsZWN0KGdlbyx0aW1lLHZhbHVlcykgJT4lIHJlbmFtZSggY29kZSA9IGdlbykNCmNpZCA8LSBldXJvc3RhdDo6ZXVfY291bnRyaWVzDQpHVCA8LSBpbm5lcl9qb2luKEdULGNpZCwgYnkgPSAiY29kZSIgKQ0KR1QgPC0gR1QgJT4lIHNlbGVjdCgtYyhsYWJlbCkpICU+JSByZWxvY2F0ZShuYW1lLCAuYmVmb3JlID0gY29kZSkNCkdUIDwtIEdUICU+JSByZW5hbWVfYXQodmFycyhjb2xuYW1lcyhHVCkpLCB+IGMoIkNvdW50cnkiLCJDb2RlIiwiRGF0ZSIsIkdUIikpDQoNCg0KI1BPQkxBQ0nDk04NClBPQiA8LSBldXJvc3RhdDo6Z2V0X2V1cm9zdGF0KCJkZW1vX2dpbmQiKQ0KUE9CIDwtIFBPQiAlPiUgZmlsdGVyKCBpbmRpY19kZSA9PSAiSkFOIikgJT4lIHNlbGVjdCgtYyhpbmRpY19kZSkpDQpQT0IgPC0gUE9CICU+JSByZW5hbWUoY29kZSA9IGdlbykNCmNpZCA8LSBldXJvc3RhdDo6ZXVfY291bnRyaWVzDQpQT0IgPC0gaW5uZXJfam9pbihQT0IsY2lkLCBieSA9ICJjb2RlIiApDQpQT0IgPC0gUE9CICU+JSBzZWxlY3QoLWMobGFiZWwpKSAlPiUgcmVsb2NhdGUobmFtZSwgLmJlZm9yZSA9IGNvZGUpDQpQT0IgPC0gUE9CICU+JSByZW5hbWVfYXQodmFycyhjb2xuYW1lcyhQT0IpKSwgfiBjKCJDb3VudHJ5IiwiQ29kZSIsIkRhdGUiLCJQT0IiKSkNCg0KI0p1bnRhbW9zIHRvZG9zIGxvcyBkYXRvcyBxdWUgaGVtb3Mgb2J0ZW5pZG8gZW4gdW4gw7puaWNvIGRhdGFmcmFtZS4NCiMjSk9JTg0KZGF0YTIgPC0gaW5uZXJfam9pbihHVCxHRFAsIGJ5ID0gYygiRGF0ZSIsIkNvdW50cnkiLCJDb2RlIikpICU+JSBpbm5lcl9qb2luKFBPQiwgYnkgPSBjKCJEYXRlIiwiQ291bnRyeSIsIkNvZGUiKSApDQpkYXRhMiA8LSBkYXRhMiAlPiUgbXV0YXRlKCBHVCA9IChHVC8xMDAwKSkgI0dUIGVuIE1pbGxvbmVzLCBpZ3VhbCBxdWUgUElCDQpkYXRhMiA8LSBkYXRhMiAlPiUgbXV0YXRlKCBHVHBvcmNQSUIgPSAoR1QvUElCKSwgR1RwYyA9IChHVC9QT0IpLCBQSUJwYyA9IChQSUIvUE9CKSkjUElCcGMgZW4gTWlsbG9uZXMNCmRhdGEyIDwtIGRhdGEyICU+JSBzZXBhcmF0ZShEYXRlLCBjKCJZZWFyIiwiTW9udGgiLCJEYXkiKSwgc2VwID0gIlstXSIpICU+JSBzZWxlY3QoLWMoIk1vbnRoIiwiRGF5IikpICAlPiUgZmlsdGVyKFllYXIgPT0gIjIwMTgiKSANCiNIYWNlbW9zIGxvcyBncsOhZmljb3MNCiMjI0dSw4FGSUNPIERFIFBVTlRPUw0KcGxvdCA8LSBnZ3Bsb3QoZGF0YTIsYWVzKHg9UElCcGMseT1HVHBjKSkgKw0KICAgICAgICBnZW9tX3BvaW50KCkgKw0KICAgICAgICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBmb3JtdWxhID0gInl+eCIsIHNob3cubGVnZW5kID0gVFJVRSwgY29sb3VyID0gInJlZCIsIGFscGhhID0gMC4zKSArDQogICAgICAgIGdlb21fdGV4dChsYWJlbCA9IGRhdGEyJENvdW50cnksIG51ZGdlX3kgPSAwLjAwMDIsIGNoZWNrX292ZXJsYXAgPSBUUlVFKSArDQogICAgICAgIGxhYnMoZmlsbD0iJSBQSUIiLA0KICAgICAgICB4PSJQSUJwYyIsDQogICAgICAgIHk9Ikdhc3RvIGVuIFR1cmlzbW8gcGMiLA0KICAgICAgICB0aXRsZT0iR2FzdG8gZW4gdHVyaXNtbyIsDQogICAgICAgIGNhcHRpb249IkZ1ZW50ZTogRXVyb3N0YXQiKSArDQogICAgICAgIHRoZW1lKCBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiI2ZmZmZmZiIpLA0KICAgICAgICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KCBmaWxsID0gIiNmZmZiZGMiLCBjb2xvdXIgPSAibGF2ZW5kZXJibHVzaCIsIHNpemUgPSAwLjEgKSwNCiAgICAgICAgICAgICAgcGFuZWwuZ3JpZCAgPSBlbGVtZW50X2xpbmUoIGNvbG91ciA9IiNkYWRhZGEiKSwNCiAgICAgICAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwNCiAgICAgICAgICAgICAgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSxjb2xvdXIgPSAiYmxhY2siKSwNCiAgICAgICAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiY29ybnNpbGsyIiwgY29sb3VyID0gImJsYWNrIiApLA0KICAgICAgICAgICAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbih0ID0gNSwgciA9IDI1LCBiID0gNSwxNSkgKQ0KcGxvdA0KDQojIyNNQVBBDQojRmlsdHJhbW9zIHBvciBsb3MgcGHDrXNlcyBldXJvcGVvcw0KbWFwZGF0YSA8LSBtYXBfZGF0YSgid29ybGQiKSAlPiUgZmlsdGVyKHJlZ2lvbiAlaW4lIGMoIkF1c3RyaWEiLCJCZWxnaXVtIiwiQnVsZ2FyaWEiLCJDcm9hdGlhIiwiQ3lwcnVzIiwNCiAgICAgICAgICAgICAgICAgICAiQ3plY2ggUmVwdWJsaWMiLCJEZW5tYXJrIiwiRXN0b25pYSIsIkZpbmxhbmQiLCJGcmFuY2UiLA0KICAgICAgICAgICAgICAgICAgICJHZXJtYW55IiwiR3JlZWNlIiwiSHVuZ2FyeSIsIklyZWxhbmQiLCJJdGFseSIsIkxhdHZpYSIsDQogICAgICAgICAgICAgICAgICAgIkxpdGh1YW5pYSIsIkx1eGVtYm91cmciLCJNYWx0YSIsIk5ldGhlcmxhbmRzIiwiUG9sYW5kIiwNCiAgICAgICAgICAgICAgICAgICAiUG9ydHVnYWwiLCJSb21hbmlhIiwiU2xvdmFraWEiLCJTbG92ZW5pYSIsIlNwYWluIiwNCiAgICAgICAgICAgICAgICAgICAiU3dlZGVuIiwiVUsiLCJTd2l0emVybGFuZCIsIkJvc25pYSBhbmQgSGVyemVnb3ZpbmEiLCJTZXJiaWEiLCJVa3JhaW5lIiwiQmVsYXJ1cyIsIkFsYmFuaWEiLCJNb250ZW5lZ3JvIiwiS29zb3ZvIiwiTWFjZWRvbmlhIiwiTW9sZG92YSIpKQ0KI0p1bnRhbW9zIGxvcyBkYXRvcyBvYnRlbmlkb3MgYW50ZXJpb3JtZW50ZSBjb24gbG9zIGRhdG9zIGRlbCBtYXBhLg0KbWFwZGF0YTIgPC0gZnVsbF9qb2luKG1hcGRhdGEsZGF0YTIgJT4lIG11dGF0ZShDb3VudHJ5ID0gaWZfZWxzZShDb3VudHJ5PT0iQ3plY2hpYSIsIHRydWUgPSAiQ3plY2ggUmVwdWJsaWMiLCBmYWxzZSA9IENvdW50cnkpKSwgYnkgPSBjKCJyZWdpb24iPSJDb3VudHJ5IikpDQojSGFjZW1vcyBlbCBncsOhZmljbw0KbWFwYXBsb3QgPC0gZ2dwbG90KG1hcGRhdGEyLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwPWdyb3VwLCBmaWxsID0gR1RwYykgKSArDQogICAgICAgICAgICBnZW9tX3BvbHlnb24oY29sb3IgPSIjZmZmZmZmIikgKw0KICAgICAgICAgICAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiIzMxMzIwMCIsaGlnaCA9ICIjZjdmZjAwIikgKw0KICAgICAgICAgICAgbGFicyhmaWxsPSJHYXN0byBlbiB0dXJpc21vIHBjIiwNCiAgICAgICAgICAgIHg9TlVMTCwNCiAgICAgICAgICAgIHk9TlVMTCwNCiAgICAgICAgICAgIHRpdGxlPSJHYXN0byBlbiB0dXJpc21vIHBlciBjYXBpdGEgZW4gbGEgVUUiLA0KICAgICAgICAgICAgY2FwdGlvbj0iRnVlbnRlOiBFbGFib3JhY2nDs24gcHJvcGlhLCBkYXRvcyBkZSBFdXJvc3RhdCIpICsNCiAgICAgICAgICAgIHRoZW1lKCBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiI2ZmZmZmZiIpLA0KICAgICAgICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KCBmaWxsID0gImNvcm5zaWxrMiIsIGNvbG91ciA9ICJsYXZlbmRlcmJsdXNoIiwgc2l6ZSA9IDAuMSApLA0KICAgICAgICAgICAgICBwYW5lbC5ncmlkICA9IGVsZW1lbnRfbGluZSggY29sb3VyID0iZ3JleSIpLA0KICAgICAgICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLA0KICAgICAgICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BLGNvbG91ciA9ICJibGFjayIpLA0KICAgICAgICAgICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCggZmlsbCA9ICJjb3Juc2lsazIiLCBjb2xvdXIgPSAiYmxhY2siICksDQogICAgICAgICAgICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKHQgPSA1LCByID0gNSwgYiA9IDUsMTApICkNCm1hcGFwbG90DQoNCg0KYGBgDQoNCg0KDQoNCiMjIDxGT05UIENPTE9SPSJHcmVlbiI+IDQuVHVyaXNtbyBlbiBFc3Bhw7FhIDwvRk9OVD4NCg0KRXNwYcOxYSBlcyB1biBwYcOtcyBxdWUgcHVlZGUgcHJlc3VtaXIgZGUgc3UgcmlxdWV6YSBjdWx0dXJhbCAsIHRlbmllbmRvIGFsZ3VuYXMgZGUgbGFzIGNhdGVkcmFsZXMgbcOhcyBib25pdGFzIGRlbCBtdW5kbywgcXVpbmNlIGNpdWRhZGVzIHF1ZSBzb24gUGF0cm9tb25pbyBkZSBsYSBIdW1hbmlkYWQgcGFyYSBsYSBPTlUgbyA1MiBSZXNlcnZhcyBkZSBsYSBCaW9zZmVyYSBkZWNsYXJhZGFzIHBvciBsYSBVTkVTQ08uIFBvciBlc28sIG5vIGVzIGRlIGV4dHJhw7FhciBxdWUgY2FkYSBhw7FvIG1pbGxvbmVzIGRlIHR1cmlzdGFzIHZpc2l0YW4gRXNwYcOxYSwgeSBubyBzw7NsbyBwb3IgZWwgYnVlbiB0aWVtcG8sIGxhcyBwbGF5YXMgbyBlbCBvY2lvLCBzaW5vIHRhbWJpw6luIHBhcmEgdmlzaXRhciBsb3MgbW9udW1lbnRvcyBjdWx0dXJhbGVzLg0KDQoNCiMjIyAgKioqSW1wb3J0YW5jaWEgZGVsIHR1cmlzbW8qKiogDQoNCkFjdHVhbG1lbnRlIGVsIHR1cmlzbW8gZXMgdW5hIGRlIGxhcyBhY3RpdmlkYWRlcyBlY29uw7NtaWNhcyB5IGN1bHR1cmFsZXMgbcOhcyBpbXBvcnRhbnRlcyBwYXJhIGVsIGRlc2Fycm9sbG8gZGUgdW4gcGHDrXMgbyB1biByZWdpw7NuLiBFbCB0dXJpc21vIHNlIHB1ZWRlIHByZXNlbnRhciBlbiBtdWNoYXMgdmFyaWFudGVzLCB0YWxlcyBjb21vIDogPEZPTlQgQ09MT1I9Ik9yYW5nZSI+dHVyaXNtbyBjdWx0dXJhbCwgZGUgYXZlbnR1cmEsIGRlIGVudHJldGVuaW1pZW50bywgZGUgcmVsYWphY2nDs24uPC9GT05UPiANCg0KSW5kZXBlbmRpZW50ZW1lbnRlIGRlIGxhcyBwb3NpYmxlcyB2YXJpYW50ZXMgcXVlIGhheWEgZGVsIHR1cmlzbW8sIGxhIGltcG9ydGFuY2lhIGRlIGVzdGEgYWN0aXZpZGFkIHJlc2lkZSBlbiBkb3MgcGlsYXJlcyBwcmluY2lwYWxlcy4gRWwgcHJpbWVybyBlcyBhcXVlbCBxdWUgdGllbmUgcXVlIHZlciBjb24gZWwgbW92aW1pZW50byB5IGxhIHJlYWN0aXZhY2nDs24gZWNvbsOzbWljYSBxdWUgZ2VuZXJhIGVuIGxhIHJlZ2nDs24gZXNwZWPDrWZpY2EgZW4gbGEgcXVlIHNlIHJlYWxpemEuIEFzw60sIHRvZG9zIGxvcyBwYcOtc2VzIHkgcmVnaW9uZXMgZGVsIHBsYW5ldGEgY3VlbnRhbiBjb24gZWwgdHVyaXNtbyBjb21vIHVuYSBhY3RpdmlkYWQgZWNvbsOzbWljYSBtw6FzIHF1ZSBnZW5lcmEgZW1wbGVvcywgb2JyYXMgZGUgaW5mcmFlc3RydWN0dXJhLCBkZXNhcnJvbGxvIGRlIGVzdGFibGVjaW1pZW50b3MgZ2FzdHJvbsOzbWljb3MgeSBob3RlbGVyb3MsIGNyZWNpbWllbnRvIGRlbCB0cmFuc3BvcnRlIGHDqXJlbywgdGVycmVzdHJlIG8gbWFyw610aW1vLCBldGMuIE9idmlhbWVudGUsIGhheSByZWdpb25lcyBlbiBlbCBtdW5kbyBxdWUgZXN0w6FuIGNhdGFsb2dhZGFzIGNvbW8gYWxndW5vcyBkZSBsb3MgcHVudG9zIGRlIHR1cmlzbW8gbcOhcyBpbXBvcnRhbnRlcyBvIGRpbsOhbWljb3MgbWllbnRyYXMgcXVlIG90cm9zIG5vLCB5IGVzdG8gdGVuZHLDoSBxdWUgdmVyIGNvbiBsYSBhdGVuY2nDs24gcXVlIGNhZGEgcGHDrXMgcHVlZGUgcHJlc3RhcmxlIGEgZXN0YSBhY3RpdmlkYWQsIGNyZWFuZG8gbcOhcyBwb3NpYmlsaWRhZGVzIHBhcmEgcXVlIGxvcyB2aXNpdGFudGVzIGRpc2ZydXRlbi4NCg0KYGBge3IsIGVjaG89RkFMU0V9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiaHR0cHM6Ly93d3cuc3VzdGFpbmFiaWxpdHktdGltZXMuY29tL3dwLWNvbnRlbnQvdXBsb2Fkcy90aHVtYnMvVG91cmlzbS0zNzFlbXp2bWw3NDkzZHBocHE5MXhjLmpwZyIpDQoNCmBgYA0KDQoNCg0KIyMjICAqKipFZmVjdG9zIHBvc2l0aXZvcyBkZWwgdHVyaXNtbyoqKiANCg0KPi0gRWwgdHVyaXNtbyBlcyB1biBncmFuIGdlbmVyYWRvciBkZSBlbXBsZW8gDQoNCjxjZW50ZXI+PGltZyBzcmM9Imh0dHBzOi8vd3d3LnhpYm1zLmNvbS9ibG9nL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDIwLzA1L2NhcmVlci1wcm9zcGVjdHMtaW4taG90ZWwtbWFuYWdlbWVudC5wbmciIC8+PC9jZW50ZXI+DQoNCg0KRWwgdHVyaXNtbyBoYSBzaWRvIGVsIHByaW5jaXBhbCBjcmVhZG9yIGRlIGVtcGxlbyBlbiBFc3Bhw7FhIGRlc2RlIGVsIGVzdGFsbGlkbyBkZSBsYSBjcmlzaXMsIG1pdGlnYW5kbyBzdXMgZWZlY3RvcyBzb2JyZSB1bmEgcGFydGUgaW1wb3J0YW50ZSBkZSBsYSBzb2NpZWRhZCBlc3Bhw7FvbGEuIERlIGhlY2hvIGVuIGxvcyBhw7FvcyB0cmFuc2N1cnJpZG9zIGRlc2RlIDIwMDkgYSAyMDE2LCBlbCBlbXBsZW8gZGUgbGFzIHJhbWFzIGRlIGFjdGl2aWRhZCB0dXLDrXN0aWNhcyBzZSBoYSBlbGV2YWRvIHVuIDEzLDQlLg0KDQpFcyB1biBzZWN0b3IgYWJpZXJ0byBxdWUgZmFjaWxpdGEgbGEgaW5jb3Jwb3JhY2nDs24gYWwgbWVyY2FkbyBsYWJvcmFsIGRlIGNvbGVjdGl2b3MgY29uIGRpZmljdWx0YWRlcyBkZSBpbnNlcmNpw7NuIGxhYm9yYWwgKHAuZWouIGrDs3ZlbmVzLCBtdWplcmVzLCBtYXlvcmVzIGRlIDQ1IGHDsW9zLHBlcnNvbmFsIGNvbiBiYWpvcyBuaXZlbGVzIGRlIGVzdHVkaW9zKSBhIGxhIHZleiBxdWUgY29udHJpYnV5ZSBhIGNvbmNpbGlhciB5IGNvbXBhZ2luYXIgZWwgZGVzZW1wZcOxbyBsYWJvcmFsIGNvbiBvdHJhcyBhY3RpdmlkYWRlcyBwZXJzb25hbGVzLg0KDQpEZSB0b2RhcyBsYXMgYWN0aXZpZGFkZXMgcmVsYWNpb25hZGFzIGNvbiBlbCBzZWN0b3IgdHVyw61zdGljbyBsYSBtw6FzIHJlbGV2YW50ZSBjb24gZGlmZXJlbmNpYSBwb3Igdm9sdW1lbiBkZSBlbXBsZW8gZXMgZWwgZGUgbGEgcmVzdGF1cmFjacOzbiBxdWUgcmVwcmVzZW50YSBjb24gMSwyDQptaWxsb25lcyBkZSBlbXBsZW9zIGNhc2kgbGEgbWl0YWQgZGVsIGVtcGxlbyB0dXLDrXN0aWNvIChlbCA0NSw4JSksIGRlIGZvcm1hIHF1ZSBzdXMgY2FyYWN0ZXLDrXN0aWNhcyB5IGNvbmRpY2lvbmFudGVzDQpsYWJvcmFsZXMgYWZlY3RhbiBlbiBncmFuIG1lZGlkYSBsYSBpbWFnZW4gZGVsIGNvbmp1bnRvIGRlbCBzZWN0b3IgKGFsb2phbWllbnRvcywgcmVzdGF1cmFudGVzLCBlbXByZXNhcyBkZSB0cmFuc3BvcnRlLCBkZSBhbHF1aWxlciBkZSBjb2NoZXMsIGNvbWVyY2lvcyBvIGFjdGl2aWRhZGVzIGRlIG9jaW8pLg0KDQpEZW50cm8gZGUgbGFzIGRpZmVyZW50ZXMgYWN0aXZpZGFkZXMgcXVlIHNlIGRlc2Fycm9sbGFuIGVuIGVsIHNlY3RvciB0dXLDrXN0aWNvLCBlbCB0cmFuc3BvcnRlIGRlIHZpYWplcm9zIGhhIHNpZG8gY2xhdmUgcGFyYSBxdWUgYXVtZW50ZSBlbCBlbXBsZW8sIHlhIHF1ZSB0YW50byBlbiBob3RlbGVzIGNvbW8gZW4gYmFyZXMgeSByZXN0YXVyYW50ZXMgbWVuZ3XDsy4NCg0KU2luIGVtYmFyZ28sIHVuYSBwYXJ0ZSBjcmVjaWVudGUgZGUgbGEgc29jaWVkYWQgbm8gdmFsb3JhIHBvc2l0aXZhbWVudGUgc3Ugbm90YWJsZSBjb250cmlidWNpw7NuIHNvY2lhbCBkZWJpZG8gYSBsYSBjb25nZXN0acOzbiB5IGEgbGEgZXhpc3RlbmNpYSBkZSBhbGd1bmFzIHByw6FjdGljYXMgbGFib3JhbGVzLg0KDQpEZSBoZWNobywgbGFzIMO6bHRpbWFzIGVzdGFkw61zdGljYXMgbXVlc3RyYW4gdW5hIGNsYXJhIGRlc2FjZWxlcmFjacOzbiBlbiBsYSBjcmVhY2nDs24gZGUgZW1wbGVvLiBTaWd1ZSBhdW1lbnRhbmRvIGxhIG9jdXBhY2nDs24sIHBlcm8gbm8gY29tbyBsbyBoYWPDrWEgZGVzZGUgcXVlIGNvbWVuesOzIGxhIHJlY3VwZXJhY2nDs24uDQoNCg0KDQpgYGB7cixlY2hvID0gVFJVRX0NCmVsX3VybCA8LSAiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3hpNzY1L1RyYWJham9HcnVwby9tYWluL2VtcGxlb190dXIuY3N2Ig0KDQplbXBsZW8gPC0gcmlvOjppbXBvcnQoZWxfdXJsKQ0KDQojR3LDoWZpY28NCg0KZW1wbGVvMSA8LSBlbXBsZW8gJT4lIGdncGxvdChhZXMoeCA9IFBlcmlvZG8sIHkgPSBUb3RhbCwgY29sb3JzKFBlcmlvZG8pKSkgKyBnZW9tX2xpbmUoKSArIGdlb21fcG9pbnQoYWVzKGZpbGwgPSBQZXJpb2RvKSkrIGxhYnModGl0bGUgPSAiTsO6bWVybyBkZSBvY3VwYWRvcyBlbiBlbCBzZWN0b3IgdHVyw61zdGljbyIsICAgIGNhcHRpb24gPSAiU291cmNlOkRhdG9zIElORSIseCA9ICJGZWNoYSAiLHkgPSBOVUxMLGNvbG9yID0gIlBlcmlvZG8iLCBzdWJ0aXRsZT0gIkRlc2RlIDIwMTUgYSAyMDE5IikNCmVtcGxlbzENCg0KYGBgDQoNCj4tIEdyYW4gcHJvbW90b3IgZGUgbGEgbWFyY2EgcGHDrXMNCg0KPGNlbnRlcj48aW1nIHNyYz0iaHR0cHM6Ly9pbWFnZW5lcy4yMG1pbnV0b3MuZXMvZmlsZXMvaW1hZ2VfNjU2XzM3MC91cGxvYWRzL2ltYWdlbmVzLzIwMTIvMDYvMjYvNjY5MzIuanBnIiAvPjwvY2VudGVyPg0KDQoNCkVsIHR1cmlzbW8gdGFtYmnDqW4gZXMgdW4gYXNwZWN0byBjbGF2ZSBlbiBsYSBwcm9tb2Npw7NuIGRlIHVuIHBhw61zIHBhcmEgZWwgbWVqb3JhbWllbnRvIGRlIGxhIHJlcHV0YWNpw7NuIHkgZWwgcG9zaWNpb25hbWllbnRvLCBwcm9tb3ZpZW5kbyB0b2RhcyBzdXMgZm9ydGFsZXphcyBjb21vIGN1bHR1cmEsIGRlcG9ydGVzLCBlbXByZXNhcywgZGVzdGlub3MgaGlzdMOzcmljb3MsIGV2ZW50b3MsIGVkdWNhY2nDs24sIGludmVyc2nDs24sIGV0Yy4sIHkgYXPDrSBwb2RlcmxlIGRhciBhbCBtdW5kbyBpbmNlbnRpdm9zIHBhcmEgdmlzaXRhciBvIGludmVydGlyLg0KDQo+LSBQSUINCg0KU2Vnw7puIGxvcyBkYXRvcyBleHRyYcOtZG9zIGRlIGxhIHDDoWdpbmEgb2ZpY2lhbCBkZWwgSW5zdGl0dXRvIE5hY2lvbmFsIGRlIEVzdGFkw61zdGljYSAoKipJTkUqKiksIGVsIHR1cmlzbW8gYXBvcnRhIHVuIDEyLDUlIGFsIFBJQiBuYWNpb25hbC5FcyBlbCBzZWN0b3IgcXVlIG3DoXMgcmlxdWV6YSBhcG9ydGEgYSBsYSBlY29ub23DrWEgZXNwYcOxb2xhLkVuIHTDqXJtaW5vcyBkZSBjb250cmlidWNpw7NuIGFsIFBJQiB5IGVtcGxlbywgbGEgaW5kdXN0cmlhIHR1csOtc3RpY2EgZXMgbGEgbcOhcyBpbXBvcnRhbnRlIGRlbCBwYcOtcyBncmFjaWFzIGFsIGNyZWNpbWllbnRvIGltcGFyYWJsZSBkZSBsYSBsbGVnYWRhIGRlIHZpYWplcm9zIGV4dHJhbmplcm9zLg0KDQpgYGB7ciwgZWNobz1UUlVFfQ0KDQojSW1wb3J0YW1vcyBkYXRvcyBkZSBQSUINCnVybDUgPC0gImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9QYXZsaW5hZGlua292YS8xMC9tYWluL3BpYnR1cmkuY3N2Ig0KcHA8LSByaW86OmltcG9ydCh1cmw1LCBzZXRjbGFzcz0idGliYmxlIikNCm5hbWVzKHBwKT0gYygiQ29tcG9uZW50ZV9QSUIiLCJWdHlwZSIsIkZlY2hhIiwiVG90YWwiKQ0KI0dyYWZpY28gUElCDQpnZyA8LSBnZ3Bsb3QocHAsIGFlcyh4PUZlY2hhLCB5PVRvdGFsLCBjb2xvcj0gRmVjaGEpKSAgKyBnZW9tX3BvaW50KCApICsgZ2VvbV9saW5lKCkgKw0KICBsYWJzKHRpdGxlID0gIkFwb3J0YWNpb24gZGVsIHR1cmlzbW8gZW4gZWwgUElCIGRlIEVzcGHDsWEiICwgc3VidGl0bGU9IkRhdG9zIGVuIHBvcmNlbnRhamVzIiwgeD0iJSBkZWwgUElCIiwgeT0iQcOxb3MiKQ0KZ2cNCg0KDQpgYGANCg0KDQoNCiMjIyAgKioqTsO6bWVybyBkZSB0dXJpc3RhcyoqKiANCg0KDQpIYW4gYXVtZW50YWRvIGVsIG7Dum1lcm8gZGUgdHVyaXN0YXMgaW50ZXJuYWNpb25hbGVzIGNvbnNpZGVyYWJsZW1lbnRlIGVuIGxvcyDDumx0aW1vcyBhw7Fvcy4gQ29uY3JldGFtZW50ZSwgMzAsNyBtaWxsb25lcyBkZSBwZXJzb25hcyBtw6FzIHZpc2l0YW4gbnVlc3RybyBwYcOtcyBkZXNkZSAyMDA5Lg0KDQogICAgRGUgaGVjaG8sIEVzcGHDsWEgbG9ncsOzIGVuIDIwMTkgYmF0aXIgcG9yIHPDqXB0aW1vIGHDsW8gY29uc2VjdXRpdm8gc3UgcsOpY29yZCBoaXN0w7NyaWNvIGVuIGxsZWdhZGFzIGRlIHR1cmlzdGFzIGludGVybmFjaW9uYWxlcywgY29uIHVuIHJlZ2lzdHJvIGRlIDgzLDcgbWlsbG9uZXMgZGUgdmlzaXRhbnRlcywgbG8gcXVlIHN1cG9uZSB1biBjcmVjaW1pZW50byBkZWwgMSwxJSBjb24gcmVzcGVjdG8gYWwgYcOxbyBhbnRlcmlvciwgc2Vnw7puIGxvcyBkYXRvcyBkZSBsYSBlbmN1ZXN0YSBGcm9udHVyIHB1YmxpY2FkYSBwb3IgZWwgSW5zdGl0dXRvIE5hY2lvbmFsIGRlIEVzdGFkw61zdGljYSAoSU5FKS4NCg0KICAgIFkgZW4gY3VhbnRvIGFsIG7Dum1lcm8gZGUgdHVyaXN0YXMgcG9yIG5hY2lvbmFsaWRhZCwgY29tbyBwb2RlbW9zIHZlciBlbiBlbCBncsOhZmljbywgZWwgUmVpbm8gVW5pZG8gZXMgZWwgcHJpbmNpcGFsIGVtaXNvciBkZSB0dXJpc3RhcyBhIEVzcGHDsWEuIEVuIGp1bGlvIGRlIDIwMTksIGVsIG7Dum1lcm8gZGUgdHVyaXN0YXMgYnJpdMOhbmljb3MgcXVlIHZpc2l0YXJvbiBFc3Bhw7FhIGZ1ZSBkZSAyLjE2Ni4yODksIHNlZ3VpZG8gcG9yIGFsZW1hbmVzICgxLjI0Mi43NjYgdmlzaXRhbnRlcykgeSBmcmFuY2VzZXMgKDEuNDIwLjYwMSB0dXJpc3RhcykuDQoNCg0KDQoNCmBgYHtyLCBlY2hvPVRSVUV9DQplbF91cmwgPC0gImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9BbmFNYXJpYTExOTgvVHJhYmFqby9tYWluLzEwODIyYmQlMjAoMikuY3N2Ig0KZGF0b3MgPC0gcmlvOjppbXBvcnQoZWxfdXJsKQ0KDQpkYXRvcyA8LSBkYXRvcyAlPiUgbXV0YXRlKCBUb3RhbCA9IHN0cmluZ3I6OnN0cl9yZW1vdmVfYWxsKFRvdGFsLCBwYXR0ZXJuID0gIihbLl0pIikpDQpkYXRvcyA8LSBkYXRvcyAlPiUgbXV0YXRlKCBUb3RhbCA9IHN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbChUb3RhbCAsIHBhdHRlcm4gPSAiWyxdIiAsIHJlcGxhY2VtZW50ID0gIi4iICkpDQpkYXRvcyA8LSBkYXRvcyAlPiUgbXV0YXRlKCBUb3RhbCA9IGFzLm51bWVyaWMoVG90YWwpKQ0KDQoNCiNBcnJlZ2xhci1sbw0KZGF0b3MgPC0gZGF0b3MgJT4lIG11dGF0ZSggVlR5cGUgPSBzdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoVlR5cGUgLCBwYXR0ZXJuID0gIlvCs10iICwgcmVwbGFjZW1lbnQgPSAiIiApKQ0KZGF0b3MgPC0gZGF0b3MgJT4lIG11dGF0ZSggVlR5cGUgPSBzdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoVlR5cGUgLCBwYXR0ZXJuID0gIlvCsV0iICwgcmVwbGFjZW1lbnQgPSAibnkiICkpDQpkYXRvcyA8LSBkYXRvcyAlPiUgbXV0YXRlKCBWVHlwZSA9IHN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbChWVHlwZSAsIHBhdHRlcm4gPSAiW8ODXSIgLCByZXBsYWNlbWVudCA9ICJvIiApKQ0KZGF0b3MgPC0gZGF0b3MgJT4lIG11dGF0ZSggQ291bnRyeSA9IHN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbChDb3VudHJ5ICwgcGF0dGVybiA9ICJbw4PCqV0iICwgcmVwbGFjZW1lbnQgPSAiZSIgKSkNCmRhdG9zIDwtIGRhdG9zICU+JSBtdXRhdGUoIENvdW50cnkgPSBzdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoQ291bnRyeSAsIHBhdHRlcm4gPSAiW8KzXSIgLCByZXBsYWNlbWVudCA9ICJvIiApKQ0KDQojQXJyZWdsYXIgZGF0b3MNCmFhIDwtIGRhdG9zICU+JSBmaWx0ZXIoVlR5cGUgPT0gIkRhdG8gYmFzZSIpDQpiYiA8LSBhYSAlPiUgc2VwYXJhdGUoRGF0ZSwgYygieWVhciIsIm1vbnRoIiksIHNlcCA9ICJbLV0iKSAlPiUgc2VsZWN0KC1jKG1vbnRoKSkNCg0KY2MgPC0gYmIgJT4lIGdyb3VwX2J5KHllYXIsIENvdW50cnkpICU+JSBmaWx0ZXIoQ291bnRyeSE9VG90YWwpICU+JSBtdXRhdGUoU3VtYVRvdGFsPSBzdW0oVG90YWwpKSAlPiUgbXV0YXRlKHllYXIgPSB1bmlxdWUoeWVhcikpDQoNCiNHUsOBRklDT1MNCmZpbHRybyA8LSBjYyAlPiUgZmlsdGVyKENvdW50cnkhPSJUb3RhbCIpICU+JSBzZWxlY3QoLWMoVG90YWwpKSAlPiUgdW5pcXVlKCkgJT4lIGdyb3VwX2J5KHllYXIpICU+JSBtdXRhdGUgKENvdW50cnkgPSBmYWN0b3IoQ291bnRyeSwgbGV2ZWxzID0gQ291bnRyeVtvcmRlcihTdW1hVG90YWwpXSkpDQpwIDwtIGZpbHRybyAlPiUgZ2dwbG90KC4sYWVzKHggPSB5ZWFyLCB5ID0gU3VtYVRvdGFsICkpKw0KICAgIGdlb21fYmFyKGFlcyhmaWxsID0gQ291bnRyeSksIHN0YXQgPSAiaWRlbnRpdHkiKSsNCiAgICBsYWJzKHRpdGxlID0gIkVzcGHDsWEgMjAxNS0yMDIwIiwNCiAgICBzdWJ0aXRsZSA9ICJOw7ptZXJvIGRlIHR1cmlzdGFzIHBvciBwYcOtcyIsIHNvdXJjZSA9ICJJTkUiKSArDQogICAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwyMDAwMDAwKSxicmVha3MgPSBzZXEoMCw5MDAwMDAwMCw1MDAwMDAwKSwgbGFiZWxzID0gcGFzdGUoKHNlcSgwLDkwMDAwMDAwLDUwMDAwMDApLzEwMDAwMDApLCJNIikpDQoNCg0KcGxvdGx5OjpnZ3Bsb3RseShwKQ0KYGBgDQpgYGB7ciwgZWNobz1UUlVFfQ0KI0dyw6FmaWNvIGRlIGxpbmVhcw0KZmlsdHJvIDwtIGNjICU+JSBmaWx0ZXIoQ291bnRyeSE9IlRvdGFsIikNCmNjMSA8LSBmaWx0cm8gJT4lDQogIGdyb3VwX2J5KHllYXIpICU+JQ0KICBhcnJhbmdlKHllYXIsIGRlc2MoU3VtYVRvdGFsKSkgJT4lDQogIG11dGF0ZShyYW5raW5nID0gcm93X251bWJlcigpKSAlPiUNCiAgZmlsdGVyKHJhbmtpbmcgPD0yMSkNCg0KcGwgPC0gZ2dwbG90KGNjMSwgYWVzKHg9eWVhciwgeT1TdW1hVG90YWwgLCBncm91cD1Db3VudHJ5LCBjb2xvcj1Db3VudHJ5KSkgKyBnZW9tX2xpbmUoKSArIGZhY2V0X2dyaWQoQ291bnRyeSB+IC4pICsNCiAgZXhwYW5kX2xpbWl0cyh5PTIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArIGxhYnModGl0bGUgPSAiUGFpc2VzIGNvbiBtYXlvciBuw7ptZXJvIGRlIHR1cmlzdGFzICIsICAgIGNhcHRpb24gPSAiU291cmNlOkRhdG9zIElORSIsDQogICAgICAgICAgICAgIHggPSAiRmVjaGEgIiwNCiAgICAgICAgICAgICAgeSA9IE5VTEwsDQogICAgICAgICAgICAgIGNvbG9yID0gIkNvbnRpbmVudGUiLA0KICAgICAgICAgICAgICBzdWJ0aXRsZSA9ICJFbiBtaWxsb25lcyBkZSB2aXNpdGFudGVzIikNCg0KDQoNCiNJbnRlbnRlIGZlci1obyBwZXIgc2VwYXJhJ3QNCiNBbGVtYW5pYQ0KZmlsdHJvMiA8LSBmaWx0cm8gJT4lIGZpbHRlcihDb3VudHJ5PT0iQWxlbWFuaWEiKQ0KcGwxIDwtIGdncGxvdChmaWx0cm8yLCBhZXMoeD15ZWFyLCB5PVN1bWFUb3RhbCAsIGdyb3VwPUNvdW50cnksIGNvbG9yPUNvdW50cnkpKSArIGdlb21fbGluZSgpICsgZmFjZXRfZ3JpZChDb3VudHJ5IH4gLikgKw0KICBleHBhbmRfbGltaXRzKHk9MikgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsgbGFicyh0aXRsZSA9ICJOw7ptZXJvIGRlIHR1cmlzdGFzIGRlIEFsZW1hbmlhIiwgICAgY2FwdGlvbiA9ICJTb3VyY2U6RGF0b3MgSU5FIiwNCiAgICAgICAgICAgICAgeCA9ICJGZWNoYSAiLA0KICAgICAgICAgICAgICB5ID0gTlVMTCwNCiAgICAgICAgICAgICAgY29sb3IgPSAiQ29udGluZW50ZSIsDQogICAgICAgICAgICAgIHN1YnRpdGxlID0gIkVuIG1pbGxvbmVzIGRlIHZpc2l0YW50ZXMiKQ0KDQpwbG90bHk6OmdncGxvdGx5KHBsMSkNCg0KI0ZyYW5jaWENCmZpbHRybzMgPC0gZmlsdHJvICU+JSBmaWx0ZXIoQ291bnRyeT09IkZyYW5jaWEiKQ0KcGwyIDwtIGdncGxvdChmaWx0cm8zLCBhZXMoeD15ZWFyLCB5PVN1bWFUb3RhbCAsIGdyb3VwPUNvdW50cnksIGNvbG9yPUNvdW50cnkpKSArIGdlb21fbGluZSgpICsgZmFjZXRfZ3JpZChDb3VudHJ5IH4gLikgKw0KICBleHBhbmRfbGltaXRzKHk9MikgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsgbGFicyh0aXRsZSA9ICJOw7ptZXJvIGRlIHR1cmlzdGFzIGRlIEZyYW5jaWEiLCAgICBjYXB0aW9uID0gIlNvdXJjZTpEYXRvcyBJTkUiLA0KICAgICAgICAgICAgICB4ID0gIkZlY2hhICIsDQogICAgICAgICAgICAgIHkgPSBOVUxMLA0KICAgICAgICAgICAgICBjb2xvciA9ICJDb250aW5lbnRlIiwNCiAgICAgICAgICAgICAgc3VidGl0bGUgPSAiRW4gbWlsbG9uZXMgZGUgdmlzaXRhbnRlcyIpDQoNCnBsb3RseTo6Z2dwbG90bHkocGwyKQ0KDQojUmVpbm8gVW5pZG8NCmZpbHRybzQgPC0gZmlsdHJvICU+JSBmaWx0ZXIoQ291bnRyeT09IlJlaW5vIFVuaWRvIikNCnBsMyA8LSBnZ3Bsb3QoZmlsdHJvNCwgYWVzKHg9eWVhciwgeT1TdW1hVG90YWwgLCBncm91cD1Db3VudHJ5LCBjb2xvcj1Db3VudHJ5KSkgKyBnZW9tX2xpbmUoKSArIGZhY2V0X2dyaWQoQ291bnRyeSB+IC4pICsNCiAgZXhwYW5kX2xpbWl0cyh5PTIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArIGxhYnModGl0bGUgPSAiTsO6bWVybyBkZSB0dXJpc3RhcyBkZWwgUmVpbm8gVW5pZG8gIiwgICAgY2FwdGlvbiA9ICJTb3VyY2U6RGF0b3MgSU5FIiwNCiAgICAgICAgICAgICAgeCA9ICJGZWNoYSAiLA0KICAgICAgICAgICAgICB5ID0gTlVMTCwNCiAgICAgICAgICAgICAgY29sb3IgPSAiQ29udGluZW50ZSIsDQogICAgICAgICAgICAgIHN1YnRpdGxlID0gIkVuIG1pbGxvbmVzIGRlIHZpc2l0YW50ZXMiKQ0KDQpwbG90bHk6OmdncGxvdGx5KHBsMykNCg0KI0ludGVudGFyIFVuaXINCmxpYnJhcnkocGF0Y2h3b3JrKQ0KKHBsMSkvKHBsMikvKHBsMykNCmBgYA0KDQojIyMgICoqKk1vdGl2b3MgZGUgc3VzIGxsZWdhZGFzKioqIA0KDQpTZWfDum4gbG9zIGRhdG9zIHByb3BvcmNpb25hZG9zIHBvciBlbCBJTkUgLCBsb3MgdHVyaXN0YXMgcXVlIHZpc2l0YW4gRXNwYcOxYSBlbiBzdSBncmFuIG1heW9yaWEgbG8gaGFjZW4gIHBhcmEgZGlzZnV0YXIgZGVsIG9jaW8uRGUgaGVjaG8gZWwgb2NpbyBhYmFyY2EgZWwgdHVyaXNtbyBlbiB0b2RhcyBzdXMgbcO6bHRpcGxlcyBmYWNldGFzOlR1cmlzbW8gY3VsdHVyYWwsIFR1cmlzbW8gZGUgc2FsdWQsIFR1cmlzbW8gZGUgc29sIHkgcGxheWEsIFR1cmlzbW8gaXRpbmVyYW50ZSwgVHVyaXNtbyByZXNpZGVuY2lhbCwgVHVyaXNtbyBydXJhbCwgVHVyaXNtbyB1cmJhbm8uLi4uDQoNCkxvcyB2aWFqZXMgcmVhbGl6YWRvcyBjb24gZmluZXMgZGUgbmVnb2NpbyBzb24gZWwgc2VndW5kbyBncmFuIG1vdGl2bywgYXVucXVlIHNpbiBzZXIgY2FwYXogZGUgc3VwZXJhciBhbCBvY2lvLiBNaWVudHJhcyBxdWUgZWwgw7psdGltbyBsdWdhciwgbG9zIGV4dHJhbmplcm9zIHZpc2l0YW4gRXNwYcOxYSBjb24gb3Ryb3MgZmluZXMgZGlzdGludG9zLCBlbnRyZSBsb3MgcXVlIHBvZGVtb3MgZGVzdGFjYXIgOkNvbXByYXMsIEZvcm1hY2nDs24geSBFZHVjYWNpw7NuLCBJbmNlbnRpdm9zIGRlIGVtcHJlc2EsIHJlbGlnaW9zb3MgeSBkZSBzYWx1ZC4NCg0KYGBge3IsIGVjaG89VFJVRX0NCiNJbXBvcnRhbW9zIGxvcyBkYXRvcyBkZSBsb3MgbW90aXZvcyBkZWwgdHVyaXNtbw0KdXJsIDwtICJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vUGF2bGluYWRpbmtvdmEvMTAvbWFpbi9jc3YuY3N2Ig0KYWE8LSByaW86OmltcG9ydCh1cmwsIHNldGNsYXNzPSJ0aWJibGUiKQ0KbmFtZXMoYWEpPSBjKCJSZWFzb24iLCJWVHlwZSIsICJGZWNoYSIsIlRvdGFsIikNCmRhdGEgPC0gYWEgJT4lIG11dGF0ZSggVG90YWwgPSBzdHJpbmdyOjpzdHJfcmVtb3ZlX2FsbChUb3RhbCwgcGF0dGVybiA9ICIoWy5dKSIpKQ0KZGF0YSA8LSBkYXRhICU+JSBtdXRhdGUoIFRvdGFsID0gc3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKFRvdGFsICwgcGF0dGVybiA9ICJbLF0iICwgcmVwbGFjZW1lbnQgPSAiLiIgKSkNCmRhdGEgPC0gZGF0YSAlPiUgbXV0YXRlKCBUb3RhbCA9IGFzLm51bWVyaWMoVG90YWwpKQ0KDQpjYzwtIGRhdGEgJT4lIGZpbHRlcihSZWFzb24gIT0iVG90YWwiKQ0KDQpnIDwtIGdncGxvdChjYywgYWVzKCBGZWNoYSwgVG90YWwpKQ0KZyArIGdlb21fYmFyKGFlcyhmaWxsPVJlYXNvbiksc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMC41KSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTY1LCB2anVzdD0wLjYpKSArDQogIGxhYnModGl0bGU9Ik1vdGl2b3MgZGUgdmlhamVzIiwNCiAgICAgICBzdWJ0aXRsZT0iVmlhamVzIikNCg0KYGBgDQoNCg0KDQojIyMgICoqKlByaW5jaXBhbGVzIGRlc3Rpbm9zIHR1cmlzdGljb3MqKiogDQoNCkVuIGVzdGUgZ3LDoWZpY28gdGlwbyBMb2xsaXBvcCBwb2RlbW9zIHZlciBsYXMgY29tdW5pZGFkZXMgYXV0w7Nub21hcyBxdWUgbcOhcyB0dXJpc3RhcyByZWNpYmllcm9uIGVuIDIwMTkuIFBvZGVtb3MgdmVyIGNvbW8gQ2F0YWx1w7FhIGhhIHNpZG8gbGEgY29tdW5pZGFkIHF1ZSBtw6FzIHR1cmlzdGFzIGhhIHJlY2liaWRvLCB0YW1iacOpbiBjYWJlIGRlc3RhY2FyIHF1ZSB0YW4gc29sbyA2IGNvbXVuaWRhZGVzIGF1dMOzbm9tYXMgcmVjaWJlbiBwcsOhY3RpY2FtZW50ZSBsYSB0b3RhbGlkYWQgZGUgdHVyaXN0YXMgcXVlIHZpYWphbiBhIEVzcGHDsWEuIA0KDQpMb3MgZGF0b3MgcGFyYSByZWFsaXphciBlc3RlIGdyw6FmaWNvIGxvcyBoZW1vcyBvYnRlbmlkbyBkZWwgSU5FLg0KDQpgYGB7cixlY2hvPVRSVUV9DQojQ2FyZ2Ftb3MgbG9zIGRhdG9zIGFsb2phZG9zIGVuIGdpdGh1Yg0KdXJsIDwtICJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20veGk3NjUvVHJhYmFqb0dydXBvL21haW4vdHVyX2NjYWFfMjAxOS5jc3YiDQojQXJyZWdsYW1vcyBsb3MgZGF0b3M6IENhbWJpYW1vcyBub21icmVzLCBxdWl0YW1vcyBzaWdub3MgZGUgcHVudHVhY2nDs24geSBvcmRlbmFtb3MgZW4gZmFjdG9yZXMuDQpkYXRhIDwtIHJpbzo6aW1wb3J0KHVybCkgJT4lIHNlbGVjdCgtYygyKSkgJT4lIHNldE5hbWVzKGMoIkNDQUEiLCJhw7FvIiwidmFsb3IiKSkgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUodmFsb3IgPSBzdHJpbmdyOjpzdHJfcmVtb3ZlX2FsbCh2YWxvciwiWy5dIiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsb3IgPSBhcy5udW1lcmljKHZhbG9yKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENDQUEgPSBmYWN0b3IoQ0NBQSwgbGV2ZWxzID0gQ0NBQVtvcmRlcih2YWxvciwgZGVjcmVhc2luZyA9IFRSVUUpXSkpDQoNCmVqZXkgPC0gc2VxKDAsMjAsMi41KQ0KIyBIYWNlbW9zIGVsIGdyw6FmaWNvDQp0aGVtZV9zZXQodGhlbWVfY2xhc3NpYygpKQ0KZ2dwbG90KGRhdGEsIGFlcyh4PUNDQUEsIHk9dmFsb3IpKSArDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gYygiQ2F0YWx1w7FhIiwiQmFsZWFyZXMiLCJDYW5hcmlhcyIsIkFuZGFsdWPDrWEiLCJWYWxlbmNpYSIsIk1hZHJpZCIsIkdhbGljaWEiLCJQYcOtcyBWYXNjbyIsIkN5TCIsIk11cmNpYSIsIkFyYWfDs24iLCJFeHRyZW1hZHVyYSIsIk5hdmFycmEiLCJDYW50YWJyaWEiLCJBc3R1cmlhcyIsIkN5TSIsIkxhIFJpb2phIikpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gcGFzdGUwKGVqZXksIk0iKSxicmVha3MgPSAxMF42KmVqZXkpICsNCiAgZ2VvbV9wb2ludChzaXplPTMpICsNCiAgZ2VvbV9zZWdtZW50KGFlcyh4PUNDQUEsDQogICAgICAgICAgICAgICAgICAgeGVuZD1DQ0FBLA0KICAgICAgICAgICAgICAgICAgIHk9MCwNCiAgICAgICAgICAgICAgICAgICB5ZW5kPXZhbG9yKSkrDQogIGxhYnModGl0bGU9IkNvbXVuaWRhZGVzIGF1dMOzbm9tYXMgbcOhcyB2aXNpdGFkYXMiLA0KICAgICAgIHN1YnRpdGxlPSJBw7FvOiAyMDE5IiwNCiAgICAgICBjYXB0aW9uPSJGdWVudGU6IElORSIsDQogICAgICAgeD0iQ29tdW5pZGFkIGF1dG9ub21hIiwNCiAgICAgICB5PSJWaXNpdGFudGVzIGFudWFsZXMiKSArDQogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiI2RhZGFkYSIpLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTY1LCB2anVzdD0wLjYpKQ0KYGBgDQoNCg0KDQojIyMgICoqKk1vbnVtZW50b3MgbcOhcyB2aXNpdGFkb3MqKioNCg0KRXNwYcOxYSBlcyBlbCBwYXJhw61zbyBkZSBsYSBhcnF1aXRlY3R1cmEsIGxpdGVyYWxtZW50ZS4gUG9jb3MgcGHDrXNlcyByZcO6bmVuIGRlIG1hbmVyYSB0YW4gY29tcGFjdGEgdGFudG9zIGVzdGlsb3MgYXJxdWl0ZWN0w7NuaWNvcyB5IGVkaWZpY2lvcyB0YW4gc29icmVjb2dlZG9yYW1lbnRlIGJlbGxvcyBjb21vIGxvIGhhY2UgRXNwYcOxYS4gUGFzZWFyIHBvciBjdWFscXVpZXJhIGRlIHN1cyBjaXVkYWRlcyBlcyBjb21vIGVtcHJlbmRlciB1biB2aWFqZSBwb3IgZWwgdGllbXBvIGEgdHJhdsOpcyBkZSBzdXMgY2FsbGVzIGFkb3F1aW5hZGFzLCBtb251bWVudG9zIGhpc3TDs3JpY29zIHkgcGllemFzIGFycXVpdGVjdMOzbmljYXMgw7puaWNhcy4gRGUgaGVjaG8sIGFsZ3Vub3MgZGUgbG9zIG1vbnVtZW50b3MgZGUgbGEgbGlzdGEgZnVlcm9uIHBpb25lcm9zIGVuIHN1IMOpcG9jYS4NCg0KDQpFbiBlbCBncsOhZmljbyBwb2RlbW9zIHZlciBjdcOhbGVzIHNvbiBsb3MgMTAgbW9udW1lbnRvcyBtw6FzIHZpc2l0YWRvcyBlbiBFc3Bhw7FhLCBtZWRpZG8gZW4gbWlsbG9uZXMgZGUgdHVyaXN0YXMgYW51YWxlcy4gQWRlbcOhcywgc2UgaGEgYcOxYWRpZG8gdW5hIGZvdG8gZGVsIG1vbnVtZW50by4gDQoNClBvZGVtb3Mgb2JzZXJ2YXIgcXVlLCBlbCBtb251bWVudG8gbcOhcyB2aXNpdGFkbyBlbiBFc3Bhw7FhIGVzIGxhICoqU2FncmFkYSBGYW1pbGlhKiogZW4gQmFyY2Vsb25hIGNvbiB1bm9zIDQsNSBtaWxsb25lcyBkZSB2aXNpdGFudGVzIGFudWFsZXMuIFNpbiBlbWJhcmdvLCBlcyB2aXNpdGFkYSB0YW50byBwb3IgbmFjaW9uYWxlcyBjb21vIHBvciBpbnRlcm5hY2lvbmFsZXMsIHB1ZXMgZXMgY29uc2lkZXJhZGEgY29tbyB1bm8gZGUgbG9zIG1vbnVtZW50b3MgbcOhcyBib25pdG9zIHkgZmFtb3NvcyBhIG5pdmVsIG5hY2lvbmFsIGUgaW5jbHVzbyBpbnRlcm5hY2lvbmFsLiANCg0KDQpgYGB7ciB9DQojSW1wb3J0YW1vcyBkYXRvcyBkZSBtb251bWVudG9zDQp1cmw0IDwtICJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vUGF2bGluYWRpbmtvdmEvMTAvbWFpbi9tb251bWVudG9zLmNzdiINCm1tPC0gcmlvOjppbXBvcnQodXJsNCwgc2V0Y2xhc3M9InRpYmJsZSIpICAlPiUgIG11dGF0ZShNb251bWVudG8gPSBjKCJQYWxhY2lvIFJlYWwgZGUgTWFkcmlkIiwiTXVzZW8gZGUgUmVpbmEgU29maWEiLCJDYW1wIE5vdSIsIlJlYWxlcyBBbGPDoXphcmVzIiwiTWV6cXVpdGEgZGUgQ8OzcmRvYmEiLCJDYXRlZHJhbCBkZSBTZXZpbGxhIiwiQWxoYW1icmEgZGUgR3JhbmFkYSIsIkNpdWRhZCBkZSBsYXMgQXJ0ZXMgeSBDaWVuY2lhcyIsIkNhdGVkcmFsIFNhbnRpYWdvIGRlIENvbXBvc3RlbGEiLCJNdXNlbyBkZSBQcmFkbyIsIlNhZ3JhZGEgRmFtaWxpYSIpLE1vbnVtZW50byA9IGZhY3RvcihNb251bWVudG8sIGxldmVscyA9IE1vbnVtZW50b1tvcmRlcihOdW1lcm9fdmlzaXRhbnRlcywgZGVjcmVhc2luZyA9IFRSVUUpXSksIE51bWVyb192aXNpdGFudGVzID0gc3RyaW5ncjo6c3RyX3JlbW92ZV9hbGwoTnVtZXJvX3Zpc2l0YW50ZXMsIHBhdHRlcm4gPSAiW15bOmFsbnVtOl1dIiksIE51bWVyb192aXNpdGFudGVzID0gYXMubnVtZXJpYyhOdW1lcm9fdmlzaXRhbnRlcyksICkNCg0KI0VqZWN1dGFtb3MgZWwgZ3LDoWZpY28gZGUgbG9zIG1vbnVtZW50b3MgbcOhcyB2aXNpdGFkb3MNCm1sIDwtIGdncGxvdChtbSxhZXMoTW9udW1lbnRvLE51bWVyb192aXNpdGFudGVzLGNvbG9yID0gTW9udW1lbnRvLGZpbGw9IE1vbnVtZW50bykpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siLCAgd2lkdGggPS4xOCxzdGF0PSJpZGVudGl0eSIpICsNCiAgY29vcmRfZmxpcCgpKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsPSBOdW1lcm9fdmlzaXRhbnRlcyAsaGp1c3Q9LS4wMywgIGNvbG91cj0iYmxhY2siKSxzaXplPTMuMikrDQoNCiAgdGhlbWUoYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG9yID0gIm9yYW5nZSIsc2l6ZT0xKSkrDQogICAgICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kPWVsZW1lbnRfYmxhbmsoKSkrDQogICAgICBzY2FsZV94X2Rpc2NyZXRlKCkgKw0KICAgIHhsYWIoTlVMTCkreWxhYihOVUxMKSsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICAgICAgICAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LGZhY2U9ImJvbGQiKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTE0LGZhY2UgPSAiYm9sZCIpKSArDQogIGdndGl0bGUoIk1vbnVtZW50b3MgbcOhcyB2aXNpdGFkb3MgZW4gRXNwYcOxYSAiICxzdWJ0aXRsZSA9ICJQb3IgbsO6bWVybyBkZSB2aXNpdGFudGVzIGVuIGVsIGHDsW8gMjAxOSIpDQoNCg0KI0EgZXN0ZSBncsOhZmljbyAgbGUgYcOxYWRpbW9zIGVsIGNvbWFuZG8gJydkcmF3X2ltYWdlJycgcGFyYSBwb25lciBsYXMgaW3DoWdlbmVzLg0KYGBgDQpgYGB7ciwgZWNobz1GQUxTRX0NCmdnZHJhdyhtbCkgKyBkcmF3X2ltYWdlKCJodHRwczovL3d3dy5hZXJvYnVzYmNuLmNvbS9ibG9nL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDE5LzAyL3NhZ3JhZGEtZmFtaWxpYS03MDB4NTAwLmpwZyIseD0gMC44NywgeSA9IDAuMDYsIHdpZHRoID0gMC4wNiwgaGVpZ2h0ID0gMC4wNikgKyBkcmF3X2ltYWdlKCJodHRwczovL3d3dy5iYXJjZWxvLmNvbS9ndWlhLXR1cmlzbW8vd3AtY29udGVudC91cGxvYWRzLzIwMTkvMDMvUGFsYWNpby1SZWFsLWRlLU1hZHJpZC5qcGciLHg9IDAuNjQsIHkgPSAwLjgxLCB3aWR0aCA9IDAuMDYsIGhlaWdodCA9IDAuMDYpICsgZHJhd19pbWFnZSgiaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy9kL2Q5L01hZHJpZF8tX011c2VvX05hY2lvbmFsX0NlbnRyb19kZV9BcnRlX1JlaW5hX1NvZiVDMyVBRGFfJTI4TU5DQVJTJTI5XzAzLkpQRyIseD0gMC42OCwgeSA9IDAuNzUsIHdpZHRoID0gMC4wNiwgaGVpZ2h0ID0gMC4wNikgKyBkcmF3X2ltYWdlKCJodHRwczovL2ltZy5maWZhLmNvbS9pbWFnZS91cGxvYWQvdF90YzEvZHE2dGN6c3p2ZjRlYmJ1cnQ1YjguanBnIix4PSAwLjcwLCB5ID0gMC42OCwgd2lkdGggPSAwLjA2LCBoZWlnaHQgPSAwLjA2KSArIGRyYXdfaW1hZ2UoImh0dHBzOi8vY2VudHJvaGlzdG9yaWNvLmluZm8vd3AtY29udGVudC91cGxvYWRzLzIwMjAvMDIvYWxjYXphci1zZXZpbGxhLWV4cGVyaWVuY2lhc2FwaWUuanBnIix4PSAwLjcyLCB5ID0gMC42MCwgd2lkdGggPSAwLjA2LCBoZWlnaHQgPSAwLjA2KSArIGRyYXdfaW1hZ2UoImh0dHBzOi8vbXltb2Rlcm5tZXQuY29tL3dwL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDIwLzAyL01lenF1aXRhLUNvcmRvYmEtMS5qcGciLHg9IDAuNzMsIHkgPSAwLjUzLCB3aWR0aCA9IDAuMDYsIGhlaWdodCA9IDAuMDYpICsgZHJhd19pbWFnZSgiaHR0cHM6Ly9mb3Rvcy5ob3RlbGVzLm5ldC9hcnRpY3Vsb3MvY2F0ZWRyYWwtc2V2aWxsYS01NTYxLTEuanBnIix4PSAwLjc0LCB5ID0gMC40NSwgd2lkdGggPSAwLjA3LCBoZWlnaHQgPSAwLjA3KSArIGRyYXdfaW1hZ2UoImh0dHBzOi8vbWVkaWEudGFjZG4uY29tL21lZGlhL2F0dHJhY3Rpb25zLXNwbGljZS1zcHAtNjc0eDQ0Ni8wNi82Zi81OS9mOS5qcGciLHg9IDAuNzkyLCB5ID0gMC4zNzUsIHdpZHRoID0gMC4wNywgaGVpZ2h0ID0gMC4wNykgICsgZHJhd19pbWFnZSgiaHR0cHM6Ly93d3cuY3VhbnRvY2hvbGxvLmNvbS93cC1jb250ZW50L3VwbG9hZHMvMjAxOC8wMS9jaXVkYWQtYXJ0ZXMtY2llbmNpYXMtdmFsZW5jaWEtMS5qcGciLHg9IDAuODMsIHkgPSAwLjMwLCB3aWR0aCA9IDAuMDcsIGhlaWdodCA9IDAuMDcpICsgZHJhd19pbWFnZSgiaHR0cHM6Ly9mb3Rvcy5ob3RlbGVzLm5ldC9hcnRpY3Vsb3MvY2F0ZWRyYWwtc2FudGlhZ28tZGUtY29tcG9zdGVsYS0yNjA5LTEuanBnIix4PSAwLjg1LCB5ID0gMC4yMiwgd2lkdGggPSAwLjA2LCBoZWlnaHQgPSAwLjA2KSArIGRyYXdfaW1hZ2UoImh0dHBzOi8vd3d3LnZpYWphcm1hZHJpZC5jb20vd3AtY29udGVudC91cGxvYWRzL211c2VvLXByYWRvLmpwZyIseD0gMC45MCwgeSA9IDAuMTMsIHdpZHRoID0gMC4wNiwgaGVpZ2h0ID0gMC4wNikNCg0KDQpgYGANCg0KIyMjICAqKipJbmdyZXNvcyBwb3IgcGHDrXMqKioNCg0KDQpQYXJhIHJlZmxlamFyIGxvcyBwYcOtc2VzIHF1ZSBtw6FzIGluZ3Jlc29zIHR1csOtc3RpY29zIGRlamFuIGVuIEVzcGHDsWEgaGVtb3MgaGVjaG8gdmFyaW9zIGdyw6FmaWNvcyB0aXBvIFF1ZXNvLiBFbiBlc3RvcyBncsOhZmljb3MgcG9kZW1vcyBvYnNlcnZhciBjb21vIG3DoXMgZGVsIDUwJSBkZSBsb3MgaW5ncmVzb3MgZGUgbnVlc3RybyBzZWN0b3IgdHVyw61zdGljbyB2aWVuZW4gZGUgbnVlc3Ryb3MgdmVjaW5vcyBldXJvcGVvcywgaGFjaWVuZG9zZSBldmlkZW50ZSBsbyBkZXBlbmRpZW50ZXMgcXVlIHNvbW9zIGRlIEV1cm9wYSBlbiBlc3RlIHNlbnRpZG8uDQoNCg0KDQpgYGB7ciwgZWNobz1UUlVFfQ0KI0NhcmdhbW9zIGxvcyBkYXRvcyBhbG9qYWRvcyBlbiBnaXRodWINCnVybCA8LSAiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3hpNzY1L1RyYWJham9HcnVwby9tYWluLzIzOTk0YmQuY3N2Ig0KZGF0YSA8LSByaW86OmltcG9ydCh1cmwpDQojQXJyZWdsYW1vcyBsb3MgZGF0b3M6IENhbWJpYW1vcyBub21icmVzIHkgZWxpbWluYW1vcyBzaWdub3MgZGUgcHVudHVhY2nDs24uDQpkYXRhIDwtIGRhdGEgJT4lIHJlbmFtZShEYXRlID0gUGVyaW9kbykNCmRhdGEgPC0gZGF0YSAlPiUgcmVsb2NhdGUoIERhdGUsIC5iZWZvcmUgPSBgR2FzdG9zIHkgZHVyYWNpw7NuIG1lZGlhIGRlIGxvcyB2aWFqZXNgKQ0KZGF0YSA8LSBkYXRhICU+JSByZW5hbWUoIENvdW50cnkgPSBgUGHDrXMgZGUgcmVzaWRlbmNpYWAgLCBWVHlwZSA9IGBUaXBvIGRlIGRhdG9gICwgVmFyaWFibGUgPSBgR2FzdG9zIHkgZHVyYWNpw7NuIG1lZGlhIGRlIGxvcyB2aWFqZXNgKQ0KZGF0YSA8LSBkYXRhICU+JSBtdXRhdGUoIFRvdGFsID0gc3RyaW5ncjo6c3RyX3JlbW92ZV9hbGwoVG90YWwsIHBhdHRlcm4gPSAiKFsuXSkiKSkNCmRhdGEgPC0gZGF0YSAlPiUgbXV0YXRlKCBUb3RhbCA9IHN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbChUb3RhbCAsIHBhdHRlcm4gPSAiWyxdIiAsIHJlcGxhY2VtZW50ID0gIi4iICkpDQpkYXRhIDwtIGRhdGEgJT4lIG11dGF0ZSggVG90YWwgPSBhcy5udW1lcmljKFRvdGFsKSkNCg0KI0dSw4FGSUNPIERFIEJBUlJBUw0KI0FjYWJhbW9zIGRlIGFycmVnbGFyIGxvcyBkYXRvcyBwYXJhIGFkYXB0YXJsb3MgYSBlc3RlIGdyw6FmaWNvIGVuIGNvbmNyZXRvDQphYSA8LSBkYXRhICU+JSBmaWx0ZXIoVmFyaWFibGUgPT0gIkdhc3RvIHRvdGFsIiAsICFDb3VudHJ5ICVpbiUgYygiVG90YWwiKSxWVHlwZSA9PSAiRGF0byBiYXNlIikNCmFhIDwtIGFhICU+JSBtdXRhdGUoQ291bnRyeSA9IHJlcGxhY2UoQ291bnRyeSwgQ291bnRyeSAlaW4lIGMoIlN1aXphIiwiUnVzaWEiLCJJcmxhbmRhIiwiUmVzdG8gQW3DqXJpY2EiLCJSZXN0byBkZSBFdXJvcGEiLCJSZXN0byBkZWwgTXVuZG8iKSwiT3Ryb3MiKSkNCmFhIDwtIGFhICU+JSBncm91cF9ieShDb3VudHJ5LERhdGUpICU+JSBzdW1tYXJpc2UoIFRvdGFsID0gc3VtKFRvdGFsKSkNCmFhIDwtIGFhICU+JSBncm91cF9ieShEYXRlKSAlPiUgbXV0YXRlKCBUb3RhbFkgPSBzdW0oVG90YWwpKQ0KYWEgPC0gYWEgJT4lIG11dGF0ZSggcGVyYy4gPSAoVG90YWwvVG90YWxZKSkNCg0KI09yZGVuYW1vcyBsYXMgdmFyaWFibGVzIG1lZGlhbnRlIGZhY3RvcmVzLg0KYmIgPC0gYWEgJT4lIGdyb3VwX2J5KERhdGUpICU+JSBtdXRhdGUoQ291bnRyeSA9IGZhY3RvcihDb3VudHJ5LCBsZXZlbHMgPSBDb3VudHJ5W29yZGVyKHBlcmMuKV0pKQ0KI0hhY2Vtb3MgZWwgZ3LDoWZpY28uDQpwbG90IDwtIGJiICU+JSBnZ3Bsb3QoYWVzKHggPSBDb3VudHJ5LCB5ID0gcGVyYy4sZmlsbCA9IENvdW50cnkpKSArDQogICAgICAgICAgICAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgY29sb3IgPSAiYmxhY2siKSArDQogICAgICAgICAgICAgICBmYWNldF93cmFwKHZhcnMoRGF0ZSksbnJvdyA9IDIsIG5jb2wgPSAyKSArDQogICAgICAgICAgICAgICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNwZWN0cmFsIiwgZGlyZWN0aW9uID0gLTEpICsNCiAgICAgICAgICAgICAgIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoMCwxLDAuMDUpLGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCkgKw0KICAgICAgICAgICAgICAgbGFicyhmaWxsPSJQYcOtc2VzIiwNCiAgICAgICAgICAgICAgIHg9TlVMTCwNCiAgICAgICAgICAgICAgIHk9IiUgc29icmUgZWwgdG90YWwgZGUgZ2FzdG8iLA0KICAgICAgICAgICAgICAgdGl0bGU9Ikdhc3RvIGVuIHR1cmlzbW8gcG9yIHBhw61zIiwNCiAgICAgICAgICAgICAgIGNhcHRpb249IkZ1ZW50ZTogSU5FIikgKw0KICAgICAgICAgICAgICAgdGhlbWUoIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCggZmlsbCA9ICIjZThkN2EzIiksDQogICAgICAgICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiY29ybnNpbGsyIiwgY29sb3VyID0gImxhdmVuZGVyYmx1c2giLCBzaXplID0gMC4xICksDQogICAgICAgICAgICAgIHBhbmVsLmdyaWQgID0gZWxlbWVudF9saW5lKCBjb2xvdXIgPSJncmV5IiksDQogICAgICAgICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwNCiAgICAgICAgICAgICAgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSxjb2xvdXIgPSAiYmxhY2siKSwNCiAgICAgICAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiY29ybnNpbGsyIiwgY29sb3VyID0gImJsYWNrIiApLA0KICAgICAgICAgICAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbih0ID0gNSwgciA9IDI1LCBiID0gNSwxNSksDQogICAgICAgICAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjZThkN2EzIixjb2xvdXIgPSBOVUxMKSkNCnBsb3QNCmBgYA0KDQoNCkFkaWNpb25hbG1lbnRlIGhlbW9zIGhlY2hvIHVuIGdyw6FmaWNvIGRlIGJhcnJhcyBjb24gbG9zIG1pc21vcyBkYXRvcy4gT2JzZXJ2YW5kbyBlbCBncsOhZmljbyBsbGVnYW1vcyBhIGxhcyBtaXNtYXMgY29uY2x1c2lvbmVzIHF1ZSBjb24gZWwgYW50ZXJpb3IsIHNpZW5kbyBBbGVtYW5pYSB5IFJlaW5vIFVuaWRvIGxvcyBxdWUgbcOhcyBpbmdyZXNvcyB0dXLDrXN0aWNvcyBkZWphbiBlbiBudWVzdHJvIHBhw61zLg0KDQpgYGB7ciwgZWNobyA9IFRSVUV9DQojQ2FyZ2Ftb3MgbG9zIGRhdG9zIHkgbG9zIGFycmVnbGFtb3MuDQp1cmwgPC0gImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS94aTc2NS9UcmFiYWpvR3J1cG8vbWFpbi8xMDgzOGJkLmNzdiINCmRhdGEgPC0gcmlvOjppbXBvcnQodXJsKQ0KZGF0YSA8LSBkYXRhICU+JSBtdXRhdGUoIERhdGUgPSBzdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoUGVyaW9kbyAsIHBhdHRlcm4gPSAiKFtBLVpdKSIgLCByZXBsYWNlbWVudCA9ICItIikgLCAua2VlcCA9ICJ1bnVzZWQiICkNCmRhdGEgPC0gZGF0YSAlPiUgcmVsb2NhdGUoIERhdGUsIC5iZWZvcmUgPSBgR2FzdG9zIHkgZHVyYWNpw7NuIG1lZGlhIGRlIGxvcyB2aWFqZXNgKQ0KZGF0YSA8LSBkYXRhICU+JSByZW5hbWUoIENvdW50cnkgPSBgUGHDrXMgZGUgcmVzaWRlbmNpYWAgLCBWVHlwZSA9IGBUaXBvIGRlIGRhdG9gICwgVmFyaWFibGUgPSBgR2FzdG9zIHkgZHVyYWNpw7NuIG1lZGlhIGRlIGxvcyB2aWFqZXNgKQ0KZGF0YSA8LSBkYXRhICU+JSBtdXRhdGUoIFRvdGFsID0gc3RyaW5ncjo6c3RyX3JlbW92ZV9hbGwoVG90YWwsIHBhdHRlcm4gPSAiKFsuXSkiKSkNCmRhdGEgPC0gZGF0YSAlPiUgbXV0YXRlKCBUb3RhbCA9IHN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbChUb3RhbCAsIHBhdHRlcm4gPSAiWyxdIiAsIHJlcGxhY2VtZW50ID0gIi4iICkpDQpkYXRhIDwtIGRhdGEgJT4lIG11dGF0ZSggVG90YWwgPSBhcy5udW1lcmljKFRvdGFsKSkNCg0KYWEgPC0gZGF0YSAlPiUgc2VwYXJhdGUoIGNvbCA9IERhdGUgLCBpbnRvID0gYygiWWVhciIsIk1vbnRoIikgLCBzZXAgPSAiLSIpDQphYSA8LSBhYSAlPiUgZmlsdGVyKFZhcmlhYmxlID09ICJHYXN0byB0b3RhbCIgLCBDb3VudHJ5ICE9ICJUb3RhbCIgLCBZZWFyICVpbiUgYygyMDE2LDIwMTcsMjAxOCwyMDE5KSxWVHlwZSA9PSAiRGF0byBiYXNlIikNCiNDcmVhbW9zIHZhcmlhYmxlcyBudWV2YXMNCmFhIDwtIGFhICU+JSBncm91cF9ieShDb3VudHJ5LFllYXIpICU+JSBzdW1tYXJpc2UoIFRvdGFsID0gc3VtKFRvdGFsKSkNCmFhIDwtIGFhICU+JSBncm91cF9ieShZZWFyKSAlPiUgbXV0YXRlKCBUb3RhbFkgPSBzdW0oVG90YWwpKQ0KYWEgPC0gYWEgJT4lIG11dGF0ZSggcGVyYy4gPSAoVG90YWwvVG90YWxZKSkNCg0KI0hhY2Vtb3MgZWwgZ3LDoWZpY28NCnBsb3QgPC0gZ2dwbG90KGFhLCBhZXMoeCA9ICIiLCB5PXBlcmMuLCBmaWxsID0gZmFjdG9yKENvdW50cnkpKSkgKw0KICBnZW9tX2Jhcih3aWR0aCA9IDEsIHN0YXQgPSAiaWRlbnRpdHkiLGNvbG9yID0gIiMwMDAwMDAiKSArDQogIGNvb3JkX3BvbGFyKHRoZXRhID0gInkiLCBzdGFydD0wKSArDQogIGxhYnMoZmlsbD0iUGHDrXMiLA0KICAgICAgIHg9TlVMTCwNCiAgICAgICB5PU5VTEwsDQogICAgICAgdGl0bGU9Ikdhc3RvIHBvciBwYcOtcyB5IGHDsW8iLA0KICAgICAgIGNhcHRpb249IkZ1ZW50ZTogSU5FIikgKyBmYWNldF93cmFwKHZhcnMoWWVhciksbnJvdyA9IDIsIG5jb2wgPSAyKSArDQogICAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsMC44LDAuMiksbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50KSArDQogICAgICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSArDQogICAgICB0aGVtZSggc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCggZmlsbCA9ICIjZmZmZmZmIiwgY29sb3VyID0gTlVMTCksDQogICAgICAgICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiY29ybnNpbGsyIiwgY29sb3VyID0gImJsYWNrIiApLA0KICAgICAgICAgICAgICBwYW5lbC5ncmlkICA9IGVsZW1lbnRfbGluZSggY29sb3VyID0iY29ybnNpbGsyIiksDQogICAgICAgICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImNvcm5zaWxrMiIpLA0KICAgICAgICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBmYWNlID0gImJvbGQiKSwNCiAgICAgICAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksDQogICAgICAgICAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNmZmZmZmYiKSwNCiAgICAgICAgICAgICAgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSxjb2xvciA9ICJibGFjayIpLA0KICAgICAgICAgICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gImNvcm5zaWxrMiIsIGNvbG91ciA9ICJibGFjayIpLA0KICAgICAgICAgICAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsY29sb3VyID0gImJsYWNrIikpDQpwbG90DQoNCmBgYA0KDQoNCiMjIDxGT05UIENPTE9SPSJHcmVlbiI+ICA1LiBFbCB0dXJpc21vIGVuIHRpZW1wb3MgZGUgQ09WSUQtMTk8L0ZPTlQ+DQoNCkVzcGHDsWEgZmlndXJhICBlbnRyZSBsb3MgcGHDrXNlcyBtw6FzIGdvbHBlYWRvcyBwb3IgbGEgcGFuZGVtaWEgZW4gcMOpcmRpZGEgZGUgdHVyaXN0YXMgaW50ZXJuYWNpb25hbGVzIHkgZGUgbG9zIGluZ3Jlc29zIHF1ZSDDqXN0b3MgZ2VuZXJhbi4NClNlZ8O6biBsb3Mgw7psdGltb3MgZGF0b3Mgb2ZpY2lhbGVzIGNvbm9jaWRvcyBkZWwgSW5zdGl0dXRvIE5hY2lvbmFsIGRlIEVzdGFkw61zdGljYSAoKipJTkUqKiksIGVudHJlIGVuZXJvIHkgc2VwdGllbWJyZSBsbGVnYXJvbiBhIHRlcnJpdG9yaW8gZXNwYcOxb2wgdW4gdG90YWwgZGUgMTYuOCBtaWxsb25lcyBkZSBleHRyYW5qZXJvcywgdW4gNzQuOSUgbWVub3MgcXVlIGVuIGVsIG1pc21vIHBlcmlvZG8gZGUgMjAxOSAtIGHDsW8gcsOpY29yZC0uIFNvbiA1MC4xIG1pbGxvbmVzIG1lbm9zLg0KDQpFbiB1bmEgbMOtbmVhIHNpbWlsYXIgLCBlbCBnYXN0byBkZSBlc3RvcyB0dXJpc3RhcyBzZSBsaW1pdMOzIGEgMTcuNzc1IG1pbGxvbmVzIGRlIGV1cm9zLCB1biA3NS45JSBtZW5vcywgcXVlIHNlIHRyYWR1Y2UgZW4gdW5hIGNhw61kYSBkZSA1NS45ODAgbWlsbG9uZXMgbWVub3MuDQoNClRvZG8gZWxsbyBlcyBjb25zZWN1ZW5jaWEgZGUgbGFzIHJlc3RyaWNjaW9uZXMgYSBsYSBtb3ZpbGlkYWQgZW4gdG9kbyBlbCBtdW5kby4gRW4gZXN0ZSBlbnRvcm5vIGRlIGluY2VydGlkdW1icmUgcG9yIGxhIHBhbmRlbWlhIHkgZGUgZmFsdGEgZGUgY29uZmlhbnphLCBlc3RlIG9yZ2FuaXNtbyBwcmV2w6kgdW5hIGNhw61kYSBnbG9iYWwgY2VyY2FuYSBhbCA3MCUgZW4gZWwgY29uanVudG8gZGUgMjAyMCB5IGxhIG1heW9yw61hIGRlIGxvcyBleHBlcnRvcyBjb25zdWx0YWRvcyBubyBlc3BlcmFuIHVuIHJlcHVudGUgaGFzdGEgZWwgdGVyY2VyIHRyaW1lc3RyZSBkZSAyMDIxIG8gaW5jbHVzbyAyMDIyLCBzaSBiaWVuIHRvZG8gZGVwZW5kZXLDoSBkZSBsb3MgYXZhbmNlcyBlbiBsYSB2YWN1bmEuDQoNCmBgYHtyfQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoImh0dHBzOi8vd3d3LmdhcnJpZ3Vlcy5jb20vc2l0ZXMvZGVmYXVsdC9maWxlcy90dXJpc21vLWRpZ2l0YWwtY292aWQtMTkuanBnIikNCg0KYGBgDQoNCmBgYHtyLGVjaG8gPSBUUlVFfQ0KZWxfdXJsIDwtICJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vQW5hTWFyaWExMTk4L1RyYWJham8vbWFpbi8xMDgyMmJkJTIwKDIpLmNzdiINCg0KDQpkYXRvcyA8LSByaW86OmltcG9ydChlbF91cmwpDQpkYXRvcyA8LSBkYXRvcyAlPiUgbXV0YXRlKCBUb3RhbCA9IHN0cmluZ3I6OnN0cl9yZW1vdmVfYWxsKFRvdGFsLCBwYXR0ZXJuID0gIihbLl0pIikpDQpkYXRvcyA8LSBkYXRvcyAlPiUgbXV0YXRlKCBUb3RhbCA9IHN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbChUb3RhbCAsIHBhdHRlcm4gPSAiWyxdIiAsIHJlcGxhY2VtZW50ID0gIi4iICkpDQpkYXRvcyA8LSBkYXRvcyAlPiUgbXV0YXRlKCBUb3RhbCA9IGFzLm51bWVyaWMoVG90YWwpKQ0KI0FycmVnbGFyLWxvDQpkYXRvcyA8LSBkYXRvcyAlPiUgbXV0YXRlKCBWVHlwZSA9IHN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbChWVHlwZSAsIHBhdHRlcm4gPSAiW8KzXSIgLCByZXBsYWNlbWVudCA9ICIiICkpDQpkYXRvcyA8LSBkYXRvcyAlPiUgbXV0YXRlKCBWVHlwZSA9IHN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbChWVHlwZSAsIHBhdHRlcm4gPSAiW8KxXSIgLCByZXBsYWNlbWVudCA9ICJueSIgKSkNCmRhdG9zIDwtIGRhdG9zICU+JSBtdXRhdGUoIFZUeXBlID0gc3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKFZUeXBlICwgcGF0dGVybiA9ICJbw4NdIiAsIHJlcGxhY2VtZW50ID0gIm8iICkpDQpkYXRvcyA8LSBkYXRvcyAlPiUgbXV0YXRlKCBDb3VudHJ5ID0gc3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKENvdW50cnkgLCBwYXR0ZXJuID0gIlvDg8KpXSIgLCByZXBsYWNlbWVudCA9ICJlIiApKQ0KZGF0b3MgPC0gZGF0b3MgJT4lIG11dGF0ZSggQ291bnRyeSA9IHN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbChDb3VudHJ5ICwgcGF0dGVybiA9ICJbwrNdIiAsIHJlcGxhY2VtZW50ID0gIm8iICkpDQoNCiNBcnJlZ2xhciBkYXRvcw0KYWEgPC0gZGF0b3MgJT4lIGZpbHRlcihWVHlwZSA9PSAiRGF0byBiYXNlIikNCmJiIDwtIGFhICU+JSBzZXBhcmF0ZShEYXRlLCBjKCJ5ZWFyIiwibW9udGgiKSwgc2VwID0gIlstXSIpICU+JSBzZWxlY3QoLWMobW9udGgpKQ0KDQpjYyA8LSBiYiAlPiUgZ3JvdXBfYnkoeWVhciwgQ291bnRyeSkgJT4lIGZpbHRlcihDb3VudHJ5IT1Ub3RhbCkgJT4lIG11dGF0ZShTdW1hVG90YWw9IHN1bShUb3RhbCkpICU+JSBtdXRhdGUoeWVhciA9IHVuaXF1ZSh5ZWFyKSkgJT4lIHVuZ3JvdXAoKQ0KDQojR1LDgUZJQ09TDQpkYXRvczExIDwtIGNjDQoNCmRmPC0gZGF0b3MxMSAlPiUgZmlsdGVyKENvdW50cnk9PSJUb3RhbCIpICU+JSBzZWxlY3QoYyh5ZWFyLFN1bWFUb3RhbCkpICU+JSB1bmlxdWUoKSAlPiUgbXV0YXRlKHllYXIgPSBhcy5udW1lcmljKHllYXIpKQ0KDQpkZCA8LSBnZ3Bsb3QoZGYsIGFlcyh5ZWFyLCBTdW1hVG90YWwpKSArIGdlb21fcG9pbnQoKSArIGdlb21fbGluZSgpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdHJhbnNpdGlvbl9yZXZlYWwoeWVhcikNCmRkDQpgYGANCg0KDQoNCiMjIDxGT05UIENPTE9SPSJHcmVlbiI+ICA2LiBDb25jbHVzaW9uZXM8L0ZPTlQ+DQoNCkNvbiBlc3RlIHRyYWJham8gaGVtb3MgcG9kaWRvIGFuYWxpemFyIGxhIGltcG9ydGFuY2lhIHF1ZSBlbCBzZWN0b3IgdHVyaXN0aWNvIHRpZW5lIGVuIGVsIG11bmRvLCBjZW50cmFuZG9ub3MgZW4gRXNwYcOxYSwgdGFudG8gZGVudHJvIGRlIGVzdGEsIGFuYWxpemFuZG8gbG9zIHRpcG9zIGRlIHR1cmlzbW8sIGdhc3RvcyBvIG7Dum1lcm8gZGUgdHVyaXN0YXMsIGNvbW8gZW4gZWwgZXh0ZXJpb3IgdmllbmRvIHN1IHBvc2ljacOzbiBhIG5pdmVsIGdsb2JhbC4gVHJhcyBsb3MgYW5hbGlzaXMgcmVhbGl6YWRvcyBoZW1vcyBwb2RpZG8gY29tcHJvYmFyIHF1ZSBkZXBlbmRlIG11Y2hvIGRlbCB0dXJpc21vLkVzdG9zIHBhw61zZXMgZGVwZW5kZW4gZW4gZ3JhbiBtZWRpZGEgZGVsIHRlcmNlciBzZWN0b3IgcGFyYSBjcmVjZXIsIHlhIHF1ZSBidWVuYSBwYXJ0ZSBkZSBzdSBQSUIgZXN0w6EgbGlnYWRvIGEgbGEgbGxlZ2FkYSBkZSB2aXNpdGFudGVzIHkgc3UgZ2FzdG8gZW4gZWwgdGVycml0b3Jpby4NCg0KUG9yIG90cmEgcGFydGUgaGVtb3MgdmlzdG8gcXVlIGxhIHBhbmRlbWlhIGdsb2JhbCBlbiBsYSBxdWUgZXN0YW1vcyB2aXZpZW5kbyBoYSBhZmVjdGFkbyBjb25zaWRlcmFibGVtZW50ZSBsYSBlY29ub21pYSBlc3Bhw7FvbGEgeWEgcXVlIGhhIHBhcmFsaXphZG8gc3Ugc2VjdG9yIG3DoXMgaW1wb3J0YW50ZS4NClBlcm8gbm8gc29sbyBlc28sdGFtYmnDqW4gaGVtb3MgdmlzdG8gY29tbyBoYSBwZXNhciBkZSBzZXIgdW4gc2VjdG9yIGVuIGNyZWNpbWllbnRvLCBlc3RlIGNyZWNpbWllbnRvIHNlIGhhIGVzdGFkbyByZWR1Y2llbmRvIGVuIGxvcyDDumx0aW1vcyBhw7FvcywgbXVjaG8gYW50ZXMgZGUgbGEgbGxlZ2FkYSBkZSBsYSBudWV2YSBzaXR1YWNpw7NuIHNhbml0YXJpYS4NCg0KQXPDrSBxdWUgY3JlZW1vcyBxdWUgZXMgaW1wb3J0YW50ZSBzZXIgY29uc2NpZW50ZXMgZGUgZXN0byB5IGJ1c2NhciBhbHRlcm5hdGl2YXMgZW4gZWwgbWlzbW8gc2VjdG9yIG8gZW4gb3Ryb3Mgc2VjdG9yZXMgcGFyYSBlbiB1biBmdXR1cm8gZXZpdGFyIHVuYSBzaXR1YWNpw7NuIHNpbWlsYXIgYSBsYSBkZSBhaG9yYS4NCg0KDQojIyA8Rk9OVCBDT0xPUj0iR3JlZW4iPiA3LiBCaWJsaW9ncmFmaWEgPC9GT05UPg0KDQo+LSBQw6FnaW5hIG9maWNpYWwgZGVsIEluc3RpdHV0byBOYWNpb25hbCBkZSBFc3RhZMOtc3RpY2EuIFthcXXDrV0oaHR0cHM6Ly93d3cuaW5lLmVzL2R5bmdzL0lORWJhc2UvbGlzdGFvcGVyYWNpb25lcy5odG0pDQoNCj4tIE1pbmlzdGVyaW8gZGUgSW5kdXN0cmlhLCBDb21lcmNpbyB5IFR1cmlzbW8uIFthcXXDrV0oaHR0cHM6Ly93d3cubWluY290dXIuZ29iLmVzL2VzLWVzL0NPVklELTE5L3R1cmlzbW8vUGFnaW5hcy9pbmRleC5hc3B4KQ0KDQo+LSBBcnTDrWN1bG8gZGVsIHBlcmnDs2RpY28gKipFbCBQYcOtcyoqIFthcXXDrV0oaHR0cHM6Ly9lbHBhaXMuY29tL2Vjb25vbWlhLzIwMTkvMDgvMDYvYWN0dWFsaWRhZC8xNTY1MTA0MTUwXzA1MDUwMS5odG1sKQ0KDQoNCj4tIEFnZW5jaWEgZGUgTm90aWNpYXMgRXVyb3BhIFByZXNzW2FxdcOtXShodHRwczovL3d3dy5ldXJvcGFwcmVzcy5lcy90dXJpc21vL25hY2lvbmFsL25vdGljaWEtZXNwYW5hLWNpZXJyYS0yMDE5LTgzNy1taWxsb25lcy10dXJpc3Rhcy1leHRyYW5qZXJvcy0xMS1tYXMtbnVldm8tcmVjb3JkLWhpc3Rvcmljby0yMDIwMDIwMzA5MzIwNy5odG1sKQ0KDQo+LSBFdXJvc3RhdCBbYXF1w61dKGh0dHBzOi8vZWMuZXVyb3BhLmV1L2luZm8vZGVwYXJ0bWVudHMvZXVyb3N0YXQtZXVyb3BlYW4tc3RhdGlzdGljc19lcykNCg0KPi0gSW5zdGl0dXQgZCdFc3RhZGlzdGljYSBkZSBsZXMgSWxsZXMgQmFsZWFycyBbYXF1w61dKGh0dHBzOi8vaWJlc3RhdC5jYWliLmVzL2liZXN0YXQvZXN0YWRpc3RpcXVlcy9mZjVlOWIxYS1mNzM5LTQxMGItOTI0NC0wZTQ3MjMyZWYzYTYvYWFmYWJkYjUtYjliNi00ZmNlLWExNDctM2M4ZDYxN2RhMjdmL2VzL0kzMDIwMzNfdHUyMS5weCkNCg0KDQo+LSBBUElFOiBBc29jaWFjacOzbiBkZSBQZXJpb2Rpc3RhcyBkZSBJbmZvcm1hY2nDs24gW2FxdcOtXShodHRwczovL3d3dy5hcGllLmVzL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDE4LzA0L0VTVFVESU8tRU1QTEVPLVNFQ1RPUi1UVVJJU1RJQ08tRVhDRUxUVVIucGRmKQ0KDQoNCg0KIA0KDQoNCg0KDQoNCi0tLS0tLS0tLS0tLS0tLS0NCg0KPGJyPjxicj4NCg0KUGFyYSBhY2FiYXIgZXN0ZSBjaHVuayBwYXJhIGluY2x1aXIgdHUgYHNlc3Npb24gaW5mb2A6DQoNCmBgYHtyfQ0Kc2Vzc2lvbmluZm86OnNlc3Npb25faW5mbygpICU+JSBkZXRhaWxzOjpkZXRhaWxzKHN1bW1hcnkgPSAnY3VycmVudCBzZXNzaW9uIGluZm8nKSANCmBgYA0K