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


1. Introducción

Este trabajo consiste en un análisis de los distintos torneos de tenis que existen, así como de los tenistas que participan en los campeonatos. El objetivo fundamental del trabajo, además de demostrar lo aprendido en la asignatura de Programación y manejo de datos en la era del Big Data es, profundizar un poco en la historia de este deporte.
Figura 1

Figura 1

2. Datos

Los datos los he obtenido de la ruta que se muestra en el siguiente chunk. Al tener tantos datos he tenido que ir haciendo modificacines a los datos originales y realizar el análisis diviendo estos en segmentos.
datos_tenis <- read_excel("./Datos/datos_tenis.xlsx")

2.1. Procesando los datos

Para poder usar los datos: Primero, he separado la columna de Date en tres: Año, mes y día y después he eliminado las columnas: Serie, Court y Best of. De esta forma he conseguido unos datos limpios y fáciles de manipular.
datos_tenis1 <- datos_tenis %>% separate(col = Date, 
              into = c("Año", "Mes", "Dia"),
              sep  = "-")
datos_tenis2 <- datos_tenis1 %>% select(-Series, -Court, -`Best of`)

3. Cuestiones

3.1 ¿Cuántos campeonatos de tenis existen?.

Con el siguiente código agrupamos los diferentes torneos y averiguamos que se juegan en todo el mundo 206 torneos distintos.

tabla1 <- datos_tenis2 %>% group_by(Tournament) %>% count() %>% arrange(desc(n))
Figura 2

Figura 2

La sigiente tabla muestra los torneos que existen por nombre y número de veces que se han jugado.

3.2 Análisis del torneo Wimbledon.

Es el más prestigioso y antiguo del mundo. Lo organiza el All England Lawn Tennis and Croquet Club y se lleva a cabo en junio/julio en Wimbledon, Londres, desde el año 1877. Se juegan torneos simultáneos de individuales masculinos y femeninos, dobles masculinos y femeninos, y dobles mixtos e incluso se hacen torneos juveniles individuales masculinos y femeninos y en dobles. Los campeones en el año 2016 en la categoría de individuales fueron Andy Murray y Serena Williams.
Figura 3

Figura 3

FEDERER

El tenista que más torneos Wimbledon ha ganado es Federer. Roger Federer es un tenista suizo. Vencedor de 20 títulos individuales en torneos de Grand Slam, el mayor número de toda la historia en tenis masculino junto a Rafael Nadal y ha mantenido el puesto número 1 en el ranking de la ATP por un tiempo récord de 310 semanas, 237 consecutivas. Actualmente ocupa el quinto lugar en la clasificación ATP.
Ha logrado ocho títulos del Campeonato de Wimbledon, seis del Abierto de Australia y cinco del Abierto de Estados Unidos, así como un título del Torneo de Roland Garros. Es uno de los ocho tenistas que ha logrado vencer en los cuatro torneos del Grand Slam. También ostenta el mejor registro en el número de finales de Grand Slam jugadas: 31, diez de estas consecutivas, entre la final de Wimbledon 2005 y el Abierto de Estados Unidos 2007. Así mismo, ha logrado un registro imbatido de seis ATP World Tour Finals, 28 Masters 1000, récord de 24 títulos ATP World Tour 500 y 25 ATP World Tour 250.
tablawimbledon2 <- tablawimbledon1 %>%group_by(Winner) %>% summarise(n=n()) %>% na.omit(datos) %>% slice_max(n,n =1)
Winner n
Federer R. 82
Figura 4

Figura 4

Los 10 tenistas que más torneos han ganado:

En el siguiente gráfico se pueden observar los 10 tenistas que más torneos Wimbledon han ganado. Se puede observar como Federer va en cabeza con un poco de ventaja, le siguen Murray y Djokovic.

3.3 Análisis torneo Australian Open.

Tiene lugar cada mes de enero en Melbourne, Australia, en el complejo deportivo situado en Melbourne Park y es famoso por las elevadas temperaturas en las que se juega. La competición se divide en categorías, existiendo categorías individuales y de dobles tanto para hombres como para mujeres, así como mixtos dobles y en estos últimos años, se han incluido también competiciones para jugadores en silla de ruedas. En el año 2017 el campeón de la categoría masculina fue Roger Federer venciendo en la final al mallorquín Rafa Nadal. En la categoría femenina la ganadora fue la conocida tenista estado unidense Serena Williams que curiosamente jugó la final contra su hermana Venus Williams.
Figura 5

Figura 5

Winners

A continuación se pueden observar los nombres de los ganadores del torneo Australian Open según el número de victorias.

De forma más visual se pueden observar los ganadores del torneo relacionando el número de victorias con el tamaño de la letra.

Torneos completados Vs Torneos retirados

En la tabla siguiente se puede observar como de los 2159 torneos que se han jugado tan solo en 89 ocasiones un jugador se ha retirado.

tablaAustralianOpen2 <- tablaAustralianOpen %>% group_by(Tournament, Comment)%>% count()
Tournament Comment n
Australian Open Completed 2067
Australian Open Retired 89
Australian Open Walkover 3

3.4 Análisis torneo US Open.

El torneo US Open se celebra anualmente entre agosto y septiembre en el USTA Billie Jean King National Tennis Center de Nueva York y consta de cinco modalidades: individuales de hombres y mujeres, dobles de hombres y mujeres y dobles mixtos, y también torneos adicionales para jugadores Junior y Senior. El torneo reparte casi veinticuatro millones de dólares en premios.

FELICIANO LÓPEZ

Con el siguiente chunk podemos ver que el tenista que más torneos US Open ha perido es:

tablaUSOpen2 <- tablaUSOpen1 %>%group_by(Loser) %>% summarise(n=n()) %>% na.omit(datos) %>% slice_max(n,n =1)
Loser n
Lopez F. 15
La derrota de Feliciano López ante Gilles Simon por 6-4 y 6-3 en su debut en el Torneo de Viena ha hecho que el toledano se convierta en el tenista con más derrotas sufridas en el circuito ATP junto al francés Fabrice Santoro. A sus 38 años y tras 22 temporadas como profesional (debutó en 1997), Feliciano es uno de los jugadores más veteranos del circuito junto con Roger Federer. Esto no quiere decir que Feliciano sea uno de los peores tenistas del circuito, sino que los números se deben a su longevidad en el mismo. Feliciano López ha disputado un total de 929 partidos con 485 victorias y 444 derrotas, con un porcentaje de triunfos del 52,3%
Figura 6

Figura 6

WINNERS Vs LOSERS

Con el siguiente chunk podemos observar las diferencias entre los 10 jugadores que más veces han ganado el US Open y los 10 jugadores que más tonreos han perdido

tablaWRank <- tablaUSOpen1 %>%group_by(Winner) %>% summarise(Ranking=n()) %>% na.omit(datos) %>% slice_max(Ranking,n =10)

graficoWRank <- tablaWRank %>% mutate(Winner = forcats::as_factor(Winner))
graficoWRank1.1 <- ggplot (graficoWRank,aes(x=Winner, y = Ranking), aes(fct_rev(Winner))) + geom_bar(stat="identity", fill = "green") + coord_flip()
graficoWRank1.1 + labs(title = "Gráfico de los 10 jugadores que más veces han ganado el US Open",
       caption = "Datos provenientes del datos_tenis2",
       x = "Winner",
       y = "n",
       color = "Especie de lirio")

tablaWRank2 <- tablaUSOpen1 %>%group_by(Loser) %>% summarise(Ranking=n()) %>% na.omit(datos) %>% slice_max(Ranking,n =10)

graficoWRank2 <- tablaWRank2 %>% mutate(Loser = forcats::as_factor(Loser))
graficoWRank1.2 <- ggplot (graficoWRank2,aes(x=Loser, y = Ranking), aes(fct_rev(Loser))) + geom_bar(stat="identity", fill = "green") + coord_flip()
graficoWRank1.1 + labs(title = "Gráfico de los 10 jugadores que más veces han perdido el US Open",
       caption = "Datos provenientes del datos_tenis2",
       x = "Loser",
       y = "n",
       color = "Especie de lirio")
Dos gra´ficos R cara a caraDos gra´ficos R cara a cara

Dos gra´ficos R cara a cara

4. Las 10 ciudades en las que se juegan más torneos

En este gráfico se pueden observar las 10 ciudades en las que más torneos se juegan.

Este mapa nos muestra de forma más visual las 10 ciudades mencionadas anteriormente.


par(mar=c(0,0,0,0))
map('world',
    col="#f2f2f2", fill=TRUE, bg="white", lwd=0.05,
    mar=rep(0,4),border=0, ylim=c(-80,80)
)

London <- c(-0.12,51)
Paris <- c(2,49)
Melbourne <- c(145,-38)
New_York <- c(-73,40)
Miami <- c(-80,25)
Indian_Wells <- c(-116,33)
Cincinnati <- c(-84,39)
Monte_Carlo <- c(7,43)
Rome <- c(12,41)
Barcelona <- c(2,41)


data <- rbind(London, Paris, Melbourne, New_York, Miami, Indian_Wells, Cincinnati, Monte_Carlo, Rome, Barcelona) %>% 
  as.data.frame()
colnames(data) <- c("long","lat")

map('world',
    col="#f2f2f2", fill=TRUE, bg="white", lwd=0.05,
    mar=rep(0,4),border=0, ylim=c(-80,80) 
)
points(x=data$long, y=data$lat, col="slateblue", cex=3, pch=20)

5. Conclusiones

En conclusión, existen un gran número de torneos de tenis dividos en distintas categorías. Los puestos ganadores de los grandes torneos suelen estas disputados siempre por los mismos tenistas. Después de este análisis podemos ver como llegar a alcanzar el historial de Federer, Djokovic y Nadal está muy dificil hoy en día. También hemos visto como importa mucho la longevidad que se tiene en este deporte ya que el porcentaje de victorias y derrotas puede variar. Por otro lado, en el apartado del gráfico del mapa del mundo se puede observar como la mayoría de las ciudades en las que más torneos de tenis se juegan son ciudades Europeas.

6. Bibliografía

Apuntes de la asignatura de Programación y Manejo de datos en la era del Big Data: https://perezp44.github.io/intro-ds-20-21-web/04-tutoriales.html

Información sobre distintos torneos: http://www.tenispontdincanou.com/blog/torneos/principales-campeonatos-y-torneos-del-tenis

Información sobre Feliciano Lopez: https://as.com/tenis/2019/10/23/mas_tenis/1571813516_380403.html

Página de referencia para los gráficos: https://www.r-graph-gallery.com/196-the-wordcloud2-library.html

Excel con los datos: https://www.kaggle.com/edouardthomas/beat-the-bookmakers-with-machine-learning-tennis

7. Sesión Informativa

    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     2021-01-16                  

- Packages -------------------------------------------------------------------
 package       * version    date       lib source                        
 assertthat      0.2.1      2019-03-21 [1] CRAN (R 4.0.2)                
 backports       1.2.0      2020-11-02 [1] CRAN (R 4.0.3)                
 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)                
 cli             2.2.0      2020-11-20 [1] CRAN (R 4.0.2)                
 clipr           0.7.1      2020-10-08 [1] CRAN (R 4.0.3)                
 colorspace      2.0-0      2020-11-11 [1] CRAN (R 4.0.3)                
 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)                
 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)                
 desc            1.2.0      2018-05-01 [1] CRAN (R 4.0.2)                
 details         0.2.1      2020-01-12 [1] CRAN (R 4.0.3)                
 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)                
 ellipsis        0.3.1      2020-05-15 [1] CRAN (R 4.0.2)                
 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)                
 fastmap         1.0.1      2019-10-08 [1] CRAN (R 4.0.2)                
 forcats       * 0.5.0      2020-03-01 [1] CRAN (R 4.0.2)                
 formatR         1.7        2019-06-11 [1] CRAN (R 4.0.3)                
 fs              1.5.0      2020-07-31 [1] CRAN (R 4.0.3)                
 gapminder     * 0.3.0      2017-10-31 [1] CRAN (R 4.0.3)                
 generics        0.1.0      2020-10-31 [1] CRAN (R 4.0.3)                
 gganimate     * 1.0.7      2020-10-15 [1] CRAN (R 4.0.3)                
 ggplot2       * 3.3.2      2020-06-19 [1] CRAN (R 4.0.2)                
 ggThemeAssist * 0.1.5      2016-08-13 [1] CRAN (R 4.0.3)                
 gifski          0.8.6      2018-09-28 [1] CRAN (R 4.0.3)                
 glue            1.4.2      2020-08-27 [1] CRAN (R 4.0.2)                
 gt            * 0.2.2      2020-11-20 [1] Github (rstudio/gt@416ca71)   
 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            1.0.0      2020-11-15 [1] CRAN (R 4.0.3)                
 highr           0.8        2019-03-20 [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.2      2020-10-03 [1] CRAN (R 4.0.3)                
 httpuv          1.5.4      2020-06-06 [1] CRAN (R 4.0.2)                
 httr            1.4.2      2020-07-20 [1] CRAN (R 4.0.2)                
 jsonlite        1.7.2      2020-12-09 [1] CRAN (R 4.0.3)                
 klippy        * 0.0.0.9500 2020-11-14 [1] Github (rlesur/klippy@378c247)
 knitr         * 1.30       2020-09-22 [1] CRAN (R 4.0.3)                
 labeling        0.4.2      2020-10-20 [1] CRAN (R 4.0.3)                
 later           1.1.0.1    2020-06-05 [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.2    2020-11-13 [1] CRAN (R 4.0.3)                
 magrittr        2.0.1      2020-11-17 [1] CRAN (R 4.0.3)                
 maps          * 3.3.0      2018-04-03 [1] CRAN (R 4.0.3)                
 mime            0.9        2020-02-04 [1] CRAN (R 4.0.0)                
 miniUI          0.1.1.1    2018-05-18 [1] CRAN (R 4.0.3)                
 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)                
 pillar          1.4.7      2020-11-20 [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.3)                
 png             0.1-7      2013-12-03 [1] CRAN (R 4.0.0)                
 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)                
 promises        1.1.1      2020-06-09 [1] CRAN (R 4.0.2)                
 purrr         * 0.3.4      2020-04-17 [1] CRAN (R 4.0.2)                
 R6              2.5.0      2020-10-28 [1] CRAN (R 4.0.3)                
 Rcpp            1.0.5      2020-07-06 [1] CRAN (R 4.0.2)                
 reactable     * 0.2.3      2020-10-04 [1] CRAN (R 4.0.3)                
 reactR          0.4.3      2020-07-12 [1] CRAN (R 4.0.3)                
 readr         * 1.4.0      2020-10-05 [1] CRAN (R 4.0.3)                
 readxl        * 1.3.1      2019-03-13 [1] CRAN (R 4.0.2)                
 reprex          0.3.0      2019-05-16 [1] CRAN (R 4.0.2)                
 rlang           0.4.9      2020-11-26 [1] CRAN (R 4.0.3)                
 rmarkdown       2.5        2020-10-21 [1] CRAN (R 4.0.3)                
 rprojroot       2.0.2      2020-11-15 [1] CRAN (R 4.0.3)                
 rstudioapi      0.13       2020-11-12 [1] CRAN (R 4.0.3)                
 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.3)                
 sessioninfo     1.1.1      2018-11-05 [1] CRAN (R 4.0.2)                
 shiny           1.5.0      2020-06-23 [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.4      2020-10-12 [1] CRAN (R 4.0.3)                
 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.3)                
 tweenr          1.0.1      2018-12-14 [1] CRAN (R 4.0.2)                
 vctrs           0.3.5      2020-11-17 [1] CRAN (R 4.0.3)                
 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.3)                
 wordcloud2    * 0.2.1      2018-01-03 [1] CRAN (R 4.0.3)                
 xfun            0.19       2020-10-30 [1] CRAN (R 4.0.3)                
 xml2            1.3.2      2020-04-23 [1] CRAN (R 4.0.2)                
 xtable          1.8-4      2019-04-21 [1] CRAN (R 4.0.2)                
 yaml            2.2.1      2020-02-01 [1] CRAN (R 4.0.2)                

[1] C:/Users/noeli/OneDrive/Documentos/R/win-library/4.0
[2] C:/Program Files/R/R-4.0.2/library


LS0tDQp0aXRsZTogIkludHJvc3BlY2Npw7NuIGFsIG11bmRvIGRlbCB0ZW5pcyINCmF1dGhvcjogIlVuaXZlcnNpdGF0IGRlIFZhbMOobmNpYSINCmRhdGU6ICJFbmVybyBkZSAyMDIxIChhY3R1YWxpemFkbyBlbCBgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkLSVtLSVZJylgKSINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0aGVtZTogcGFwZXINCiAgICBoaWdobGlnaHQ6IHRleHRtYXRlDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDMNCiAgICB0b2NfZmxvYXQ6DQogICAgICBjb2xsYXBzZWQ6IHllcw0KICAgICAgc21vb3RoX3Njcm9sbDogeWVzDQogICAgc2VsZl9jb250YWluZWQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogbm8NCiAgICBkZl9wcmludDoga2FibGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgcGRmX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiAnMycNCnN1YnRpdGxlOiBNYXIgVmFsbGRlY2FicmVzIEx1bGwodmFsbGRlY2FAYWx1bW5pLnV2LmVzKQ0KZWRpdG9yX29wdGlvbnM6DQogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlDQotLS0NCg0KYGBge3IgcGFja2FnZXMtc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShrbGlwcHkpICAjLSByZW1vdGVzOjppbnN0YWxsX2dpdGh1Yigicmxlc3VyL2tsaXBweSIpDQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShnZ1RoZW1lQXNzaXN0KQ0KbGlicmFyeShzY2FsZXMpDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkoZ2FwbWluZGVyKQ0KbGlicmFyeShnZ2FuaW1hdGUpDQpsaWJyYXJ5KHJlYWN0YWJsZSkNCmxpYnJhcnkoZ3QpDQpsaWJyYXJ5KHdvcmRjbG91ZDIpDQpsaWJyYXJ5KG1hcHMpDQpgYGANCg0KYGBge3IgY2h1bmstc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCANCiAgICAgICAgICAgICAgICAgICAgICAjcmVzdWx0cyA9ICJob2xkIiwNCiAgICAgICAgICAgICAgICAgICAgICBjYWNoZSA9IEZBTFNFLCBjYWNoZS5wYXRoID0gIi9jYWNoZXMvIiwgY29tbWVudCA9ICIjPiIsDQogICAgICAgICAgICAgICAgICAgICAgI2ZpZy53aWR0aCA9IDcsICNmaWcuaGVpZ2h0PSA3LCAgIA0KICAgICAgICAgICAgICAgICAgICAgICNvdXQud2lkdGggPSA3LCBvdXQuaGVpZ2h0ID0gNywNCiAgICAgICAgICAgICAgICAgICAgICBjb2xsYXBzZSA9IFRSVUUsICBmaWcuc2hvdyA9ICJob2xkIiwNCiAgICAgICAgICAgICAgICAgICAgICBmaWcuYXNwID0gNy85LCBvdXQud2lkdGggPSAiNjAlIiwgZmlnLmFsaWduID0gImNlbnRlciIpDQprbml0cjo6b3B0c19jaHVuayRzZXQoZGV2ID0gInBuZyIsIGRldi5hcmdzID0gbGlzdCh0eXBlID0gImNhaXJvLXBuZyIpKQ0KYGBgDQoNCmBgYHtyIG9wdGlvbnMtc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCm9wdGlvbnMoc2NpcGVuID0gOTk5KSAjLSBwYXJhIHF1aXRhciBsYSBub3RhY2nDs24gY2llbnTDrWZpY2ENCm9wdGlvbnMoInlhbWwuZXZhbC5leHByIiA9IFRSVUUpIA0KYGBgDQoNCg0KYGBge3Iga2xpcHB5LCBlY2hvID0gRkFMU0V9DQprbGlwcHk6OmtsaXBweShwb3NpdGlvbiA9IGMoInRvcCIsICJyaWdodCIpKSAjLSByZW1vdGVzOjppbnN0YWxsX2dpdGh1Yigicmxlc3VyL2tsaXBweSIpDQpgYGANCg0KPGhyIGNsYXNzPSJsaW5lYS1ibGFjayI+DQoNClRyYWJham8gZWxhYm9yYWRvIHBhcmEgbGEgYXNpZ25hdHVyYSAiUHJvZ3JhbWFjacOzbiB5IG1hbmVqbyBkZSBkYXRvcyBlbiBsYSBlcmEgZGVsIEJpZyBEYXRhIiBkZSBsYSBVbml2ZXJzaXRhdCBkZSBWYWzDqG5jaWEgZHVyYW50ZSBlbCBjdXJzbyAyMDIwLTIwMjEuIEVsIHJlcG8gZGVsIHRyYWJham8gZXN0w6EgW2FxdcOtXShodHRwczovL2dpdGh1Yi5jb20vdmFsbGRlY2FicmVzL3RyYWJham9fQmlnRGF0YSl7dGFyZ2V0PSJfYmxhbmsifS4gTGEgcMOhZ2luYSB3ZWIgZGUgbGEgYXNpZ25hdHVyYSB5IGxvcyB0cmFiYWpvcyBkZSBtaXMgY29tcGHDsWVyb3MgcHVlZGVuIHZlcnNlIFthcXXDrV0oaHR0cHM6Ly9wZXJlenA0NC5naXRodWIuaW8vaW50cm8tZHMtMjAtMjEtd2ViLzA3LXRyYWJham9zLmh0bWwpe3RhcmdldD0iX2JsYW5rIn0uDQoNCjwhLS0gRWwgcMOhcnJhZm8gZGUgYXJyaWJhIGhhcyBkZSBkZWphcmxvIGNhc2kgaWd1YWwsIA0KICAgICAgICBzb2xvIEhBUyBkZSBTVVNUSVRVSVIgbGFzIDIgdmVjZXMgcXVlIGFwYXJlY2UgInBlcmV6cDQ0IiBwb3IgdHUgdXN1YXJpbyBkZSBHaXRodWItLT4NCg0KPGhyIGNsYXNzPSJsaW5lYS1yZWQiPg0KDQojICoqMS4gSW50cm9kdWNjacOzbioqDQoNCjxkaXYgc3R5bGUgPSAidGV4dC1hbGlnbjoganVzdGlmeSI+RXN0ZSB0cmFiYWpvIGNvbnNpc3RlIGVuIHVuIGFuw6FsaXNpcyBkZSBsb3MgZGlzdGludG9zIHRvcm5lb3MgZGUgdGVuaXMgcXVlIGV4aXN0ZW4sIGFzw60gY29tbyBkZSBsb3MgdGVuaXN0YXMgcXVlIHBhcnRpY2lwYW4gZW4gbG9zIGNhbXBlb25hdG9zLiBFbCBvYmpldGl2byBmdW5kYW1lbnRhbCBkZWwgdHJhYmFqbywgYWRlbcOhcyBkZSBkZW1vc3RyYXIgbG8gYXByZW5kaWRvIGVuIGxhIGFzaWduYXR1cmEgZGUgUHJvZ3JhbWFjacOzbiB5IG1hbmVqbyBkZSBkYXRvcyBlbiBsYSBlcmEgZGVsIEJpZyBEYXRhIGVzLCBwcm9mdW5kaXphciB1biBwb2NvIGVuIGxhIGhpc3RvcmlhIGRlIGVzdGUgZGVwb3J0ZS4gPC9kaXYvPg0KDQoNCg0KYGBge3IsIGVjaG8gPSBGQUxTRSwgZXZhbCA9IFRSVUUsIG91dC53aWR0aCA9ICI0MCUiLCBmaWcuYWxpZ24gPSAiY2VudGVyIiwgZmlnLmNhcD0iRmlndXJhIDEifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1hZ2VuZXMiLCAiMS5qcGciKSApIA0KYGBgDQoNCg0KDQojICoqMi4gRGF0b3MqKg0KDQo8ZGl2IHN0eWxlID0gInRleHQtYWxpZ246IGp1c3RpZnkiPkxvcyBkYXRvcyBsb3MgaGUgb2J0ZW5pZG8gZGUgbGEgcnV0YSBxdWUgc2UgbXVlc3RyYSBlbiBlbCBzaWd1aWVudGUgY2h1bmsuIEFsIHRlbmVyIHRhbnRvcyBkYXRvcyBoZSB0ZW5pZG8gcXVlIGlyIGhhY2llbmRvIG1vZGlmaWNhY2luZXMgYSBsb3MgZGF0b3Mgb3JpZ2luYWxlcyB5IHJlYWxpemFyIGVsIGFuw6FsaXNpcyBkaXZpZW5kbyBlc3RvcyBlbiBzZWdtZW50b3MuPC9kaXYvPg0KDQpgYGB7ciwgZXZhbCA9IFRSVUV9DQpkYXRvc190ZW5pcyA8LSByZWFkX2V4Y2VsKCIuL0RhdG9zL2RhdG9zX3RlbmlzLnhsc3giKQ0KYGBgDQoNCg0KIyMgMi4xLiBQcm9jZXNhbmRvIGxvcyBkYXRvcw0KDQo8ZGl2IHN0eWxlID0gInRleHQtYWxpZ246IGp1c3RpZnkiPlBhcmEgcG9kZXIgdXNhciBsb3MgZGF0b3M6IFByaW1lcm8sIGhlIHNlcGFyYWRvIGxhIGNvbHVtbmEgZGUgRGF0ZSBlbiB0cmVzOiBBw7FvLCBtZXMgeSBkw61hIHkgZGVzcHXDqXMgaGUgZWxpbWluYWRvIGxhcyBjb2x1bW5hczogU2VyaWUsIENvdXJ0IHkgQmVzdCBvZi4gRGUgZXN0YSBmb3JtYSBoZSBjb25zZWd1aWRvIHVub3MgZGF0b3MgbGltcGlvcyB5IGbDoWNpbGVzIGRlIG1hbmlwdWxhci4gPC9kaXYvPg0KDQpgYGB7ciwgZXZhbCA9IFRSVUV9DQpkYXRvc190ZW5pczEgPC0gZGF0b3NfdGVuaXMgJT4lIHNlcGFyYXRlKGNvbCA9IERhdGUsIA0KICAgICAgICAgICAgICBpbnRvID0gYygiQcOxbyIsICJNZXMiLCAiRGlhIiksDQogICAgICAgICAgICAgIHNlcCAgPSAiLSIpDQpkYXRvc190ZW5pczIgPC0gZGF0b3NfdGVuaXMxICU+JSBzZWxlY3QoLVNlcmllcywgLUNvdXJ0LCAtYEJlc3Qgb2ZgKQ0KYGBgDQoNCg0KIyAqKjMuIEN1ZXN0aW9uZXMqKg0KDQojIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjpibHVlIj4zLjEgwr9DdcOhbnRvcyBjYW1wZW9uYXRvcyBkZSB0ZW5pcyBleGlzdGVuPy48L3NwYW4+DQoNCkNvbiBlbCBzaWd1aWVudGUgY8OzZGlnbyBhZ3J1cGFtb3MgbG9zIGRpZmVyZW50ZXMgdG9ybmVvcyB5IGF2ZXJpZ3VhbW9zIHF1ZSBzZSBqdWVnYW4gZW4gdG9kbyBlbCBtdW5kbyAyMDYgdG9ybmVvcyBkaXN0aW50b3MuDQoNCmBgYHtyLCBlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUV9DQp0YWJsYTEgPC0gZGF0b3NfdGVuaXMyICU+JSBncm91cF9ieShUb3VybmFtZW50KSAlPiUgY291bnQoKSAlPiUgYXJyYW5nZShkZXNjKG4pKQ0KYGBgDQoNCmBgYHtyLCBlY2hvID0gRkFMU0UsIGV2YWwgPSBUUlVFLCBvdXQud2lkdGggPSAiNTAlIiwgZmlnLmFsaWduID0gImNlbnRlciIsIGZpZy5jYXA9IkZpZ3VyYSAyIn0NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltYWdlbmVzIiwgIkxvZ29zLmpwZyIpICkgDQpgYGANCg0KTGEgc2lnaWVudGUgdGFibGEgbXVlc3RyYSBsb3MgdG9ybmVvcyBxdWUgZXhpc3RlbiBwb3Igbm9tYnJlIHkgbsO6bWVybyBkZSB2ZWNlcyBxdWUgc2UgaGFuIGp1Z2Fkby4NCg0KYGBge3IgZXZhbD1UUlVFLCBlY2hvPUZBTFNFfQ0KDQpyZWFjdGFibGUodGFibGExLCBkZWZhdWx0UGFnZVNpemUgPSAgMTAsICBwYWdpbmF0aW9uVHlwZSA9ICJqdW1wIiwgc2hvd1BhZ2VTaXplT3B0aW9ucyA9ICBUUlVFICwgcGFnZVNpemVPcHRpb25zID0gIGMgKCAxMCAsIDUwICwgMTAwICksZGVmYXVsdENvbERlZiA9IGNvbERlZigNCiAgICBhbGlnbiA9ICJjZW50ZXIiLA0KICAgIG1pbldpZHRoID0gNzAsDQogICAgaGVhZGVyU3R5bGUgPSBsaXN0KGJhY2tncm91bmQgPSAiYWxpY2VibHVlIiksDQogICAgZmlsdGVyYWJsZSA9IFRSVUUpLCAgaGlnaGxpZ2h0ID0gVFJVRSwgb3V0bGluZWQgPSBUUlVFLA0KICAgIGNvbHVtbnMgPSBsaXN0KA0KICBgTW92aWVzJlRWU2hvdy9hw7FvYCA9IGNvbERlZihzdHlsZSA9IGZ1bmN0aW9uKHZhbHVlKSB7DQogICAgaWYgKHZhbHVlID4gMCkgew0KICAgICAgY29sb3IgPC0gIiNlMDAwMDAifQ0KICAgICAgZWxzZSB7DQogICAgICBjb2xvciA8LSAiIzAwODAwMCINCiAgICB9DQogICAgbGlzdChjb2xvciA9IGNvbG9yLCBmb250V2VpZ2h0ID0gImJvbGQiKQ0KICB9KSkpDQoNCmBgYA0KDQojIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjpibHVlIj4zLjIgQW7DoWxpc2lzIGRlbCB0b3JuZW8gV2ltYmxlZG9uLjwvc3Bhbj57LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQo+PGRpdiBzdHlsZSA9ICJ0ZXh0LWFsaWduOiBqdXN0aWZ5Ij5FcyBlbCBtw6FzIHByZXN0aWdpb3NvIHkgYW50aWd1byBkZWwgbXVuZG8uIExvIG9yZ2FuaXphIGVsIEFsbCBFbmdsYW5kIExhd24gVGVubmlzIGFuZCBDcm9xdWV0IENsdWIgeSBzZSBsbGV2YSBhIGNhYm8gZW4ganVuaW8vanVsaW8gZW4gV2ltYmxlZG9uLCBMb25kcmVzLCBkZXNkZSBlbCBhw7FvIDE4NzcuIFNlIGp1ZWdhbiB0b3JuZW9zIHNpbXVsdMOhbmVvcyBkZSBpbmRpdmlkdWFsZXMgbWFzY3VsaW5vcyB5IGZlbWVuaW5vcywgZG9ibGVzIG1hc2N1bGlub3MgeSBmZW1lbmlub3MsIHkgZG9ibGVzIG1peHRvcyBlIGluY2x1c28gc2UgaGFjZW4gdG9ybmVvcyBqdXZlbmlsZXMgaW5kaXZpZHVhbGVzIG1hc2N1bGlub3MgeSBmZW1lbmlub3MgeSBlbiBkb2JsZXMuIExvcyBjYW1wZW9uZXMgZW4gZWwgYcOxbyAyMDE2IGVuIGxhIGNhdGVnb3LDrWEgZGUgaW5kaXZpZHVhbGVzIGZ1ZXJvbiBBbmR5IE11cnJheSB5IFNlcmVuYSBXaWxsaWFtcy4gPC9kaXYvPg0KDQpgYGB7ciwgZWNobyA9IEZBTFNFLCBldmFsID0gVFJVRSwgb3V0LndpZHRoID0gIjUwJSIsIGZpZy5hbGlnbiA9ICJjZW50ZXIiLCBmaWcuY2FwPSJGaWd1cmEgMyJ9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbWFnZW5lcyIsICJXaW1ibGVkb24uanBnIikgKSANCmBgYA0KDQoNCmBgYHtyLCBlY2hvID0gRkFMU0UsIGV2YWwgPSBUUlVFfQ0KdGFibGF3aW1ibGVkb24xIDwtIGRhdG9zX3RlbmlzMiAlPiUgZmlsdGVyKFRvdXJuYW1lbnQgPT0gIldpbWJsZWRvbiIpIA0KDQpgYGANCg0KIyMjIEZFREVSRVINCg0KPjxkaXYgc3R5bGUgPSAidGV4dC1hbGlnbjoganVzdGlmeSI+RWwgdGVuaXN0YSBxdWUgbcOhcyB0b3JuZW9zIFdpbWJsZWRvbiBoYSBnYW5hZG8gZXMgRmVkZXJlci4gDQpSb2dlciBGZWRlcmVyIGVzIHVuIHRlbmlzdGEgc3Vpem8uIFZlbmNlZG9yIGRlIDIwIHTDrXR1bG9zIGluZGl2aWR1YWxlcyBlbiB0b3JuZW9zIGRlIEdyYW5kIFNsYW0sIGVsIG1heW9yIG7Dum1lcm8gZGUgdG9kYSBsYSBoaXN0b3JpYSBlbiB0ZW5pcyBtYXNjdWxpbm8ganVudG8gYSBSYWZhZWwgTmFkYWwgeSBoYSBtYW50ZW5pZG8gZWwgcHVlc3RvIG7Dum1lcm8gMSBlbiBlbCByYW5raW5nIGRlIGxhIEFUUCBwb3IgdW4gdGllbXBvIHLDqWNvcmQgZGUgMzEwIHNlbWFuYXMsIDIzNyBjb25zZWN1dGl2YXMuIEFjdHVhbG1lbnRlIG9jdXBhIGVsIHF1aW50byBsdWdhciBlbiBsYSBjbGFzaWZpY2FjacOzbiBBVFAuPC9kaXYvPg0KPjxkaXYgc3R5bGUgPSAidGV4dC1hbGlnbjoganVzdGlmeSI+SGEgbG9ncmFkbyBvY2hvIHTDrXR1bG9zIGRlbCBDYW1wZW9uYXRvIGRlIFdpbWJsZWRvbiwgc2VpcyBkZWwgQWJpZXJ0byBkZSBBdXN0cmFsaWEgeSBjaW5jbyBkZWwgQWJpZXJ0byBkZSBFc3RhZG9zIFVuaWRvcywgYXPDrSBjb21vIHVuIHTDrXR1bG8gZGVsIFRvcm5lbyBkZSBSb2xhbmQgR2Fycm9zLiBFcyB1bm8gZGUgbG9zIG9jaG8gdGVuaXN0YXMgcXVlIGhhIGxvZ3JhZG8gdmVuY2VyIGVuIGxvcyBjdWF0cm8gdG9ybmVvcyBkZWwgR3JhbmQgU2xhbS4gVGFtYmnDqW4gb3N0ZW50YSBlbCBtZWpvciByZWdpc3RybyBlbiBlbCBuw7ptZXJvIGRlIGZpbmFsZXMgZGUgR3JhbmQgU2xhbSBqdWdhZGFzOiAzMSwgZGlleiBkZSBlc3RhcyBjb25zZWN1dGl2YXMsIGVudHJlIGxhIGZpbmFsIGRlIFdpbWJsZWRvbiAyMDA1IHkgZWwgQWJpZXJ0byBkZSBFc3RhZG9zIFVuaWRvcyAyMDA3LiBBc8OtIG1pc21vLCBoYSBsb2dyYWRvIHVuIHJlZ2lzdHJvIGltYmF0aWRvIGRlIHNlaXMgQVRQIFdvcmxkIFRvdXIgRmluYWxzLCAyOCBNYXN0ZXJzIDEwMDAsIHLDqWNvcmQgZGUgMjQgdMOtdHVsb3MgQVRQIFdvcmxkIFRvdXIgNTAwIHkgMjUgQVRQIFdvcmxkIFRvdXIgMjUwLiA8L2Rpdi8+DQoNCg0KYGBge3IsIGVjaG8gPSBUUlVFLCBldmFsID0gVFJVRX0NCnRhYmxhd2ltYmxlZG9uMiA8LSB0YWJsYXdpbWJsZWRvbjEgJT4lZ3JvdXBfYnkoV2lubmVyKSAlPiUgc3VtbWFyaXNlKG49bigpKSAlPiUgbmEub21pdChkYXRvcykgJT4lIHNsaWNlX21heChuLG4gPTEpDQoNCmBgYA0KDQpgYGB7ciBldmFsPVRSVUUsIGVjaG89RkFMU0V9DQprbml0cjo6a2FibGUoVG91cm5hbWVudCA8LSB0YWJsYXdpbWJsZWRvbjIpDQoNCmBgYA0KDQpgYGB7ciwgZWNobyA9IEZBTFNFLCBldmFsID0gVFJVRSwgb3V0LndpZHRoID0gIjUwJSIsIGZpZy5hbGlnbiA9ICJjZW50ZXIiLCBmaWcuY2FwPSJGaWd1cmEgNCJ9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbWFnZW5lcyIsICJGZWRlcmVyMS5qcGciKSApIA0KYGBgDQoNCiMjIyBMb3MgMTAgdGVuaXN0YXMgcXVlIG3DoXMgdG9ybmVvcyBoYW4gZ2FuYWRvOg0KDQo8ZGl2IHN0eWxlID0gInRleHQtYWxpZ246IGp1c3RpZnkiPkVuIGVsIHNpZ3VpZW50ZSBncsOhZmljbyBzZSBwdWVkZW4gb2JzZXJ2YXIgbG9zIDEwIHRlbmlzdGFzIHF1ZSBtw6FzIHRvcm5lb3MgV2ltYmxlZG9uIGhhbiBnYW5hZG8uIFNlIHB1ZWRlIG9ic2VydmFyIGNvbW8gRmVkZXJlciB2YSBlbiBjYWJlemEgY29uIHVuIHBvY28gZGUgdmVudGFqYSwgbGUgc2lndWVuIE11cnJheSB5IERqb2tvdmljLjwvZGl2Lz4NCg0KYGBge3IsIGVjaG8gPSBGQUxTRSwgZXZhbCA9IFRSVUUsIG91dC53aWR0aCA9ICI2MCUiLCBmaWcuYWxpZ24gPSAiY2VudGVyIn0NCg0KdGFibGF3aW1ibGVkb24zIDwtIHRhYmxhd2ltYmxlZG9uMSAlPiVncm91cF9ieShXaW5uZXIpICU+JSBzdW1tYXJpc2Uobj1uKCkpICU+JSBuYS5vbWl0KGRhdG9zKSAlPiUgc2xpY2VfbWF4KG4sbiA9MTApIA0KZ3JhZmljb1dpbWJsZWRvbjwtIHRhYmxhd2ltYmxlZG9uMyAlPiUgbXV0YXRlKFdpbm5lciA9IGZvcmNhdHM6OmFzX2ZhY3RvcihXaW5uZXIpKQ0KZ3JhZmljb1dpbWJsZWRvbjIgPC0gZ2dwbG90IChncmFmaWNvV2ltYmxlZG9uLGFlcyh4PVdpbm5lciwgeSA9IG4pLCBhZXMoZmN0X3JldihXaW5uZXIpKSkgKyBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsIGZpbGwgPSAiYmx1ZSIpICsgY29vcmRfZmxpcCgpDQpncmFmaWNvV2ltYmxlZG9uMiArIGxhYnModGl0bGUgPSAiR3LDoWZpY28gZGUgbG9zIDEwIHRlbmlzdGFzIHF1ZSBtw6FzIHRvcm5lb3MgV2ltYmxlZG9uIGhhbiBnYW5hZG8iLA0KICAgICAgIGNhcHRpb24gPSAiRGF0b3MgcHJvdmVuaWVudGVzIGRlbCBkYXRvc190ZW5pczIiLA0KICAgICAgIHggPSAiV2lubmVyIiwNCiAgICAgICB5ID0gIm4iLA0KICAgICAgIGNvbG9yID0gImJsdWUiKQ0KDQpgYGANCg0KIyMgey19DQoNCiMjIDxzcGFuIHN0eWxlID0gImNvbG9yOmJsdWUiPjMuMyBBbsOhbGlzaXMgdG9ybmVvIEF1c3RyYWxpYW4gT3Blbi4gPC9zcGFuPiB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQo+PGRpdiBzdHlsZSA9ICJ0ZXh0LWFsaWduOiBqdXN0aWZ5Ij5UaWVuZSBsdWdhciBjYWRhIG1lcyBkZSBlbmVybyBlbiBNZWxib3VybmUsIEF1c3RyYWxpYSwgZW4gZWwgY29tcGxlam8gZGVwb3J0aXZvIHNpdHVhZG8gZW4gTWVsYm91cm5lIFBhcmsgeSBlcyBmYW1vc28gcG9yIGxhcyBlbGV2YWRhcyB0ZW1wZXJhdHVyYXMgZW4gbGFzIHF1ZSBzZSBqdWVnYS4gTGEgY29tcGV0aWNpw7NuIHNlIGRpdmlkZSBlbiBjYXRlZ29yw61hcywgZXhpc3RpZW5kbyBjYXRlZ29yw61hcyBpbmRpdmlkdWFsZXMgeSBkZSBkb2JsZXMgdGFudG8gcGFyYSBob21icmVzIGNvbW8gcGFyYSBtdWplcmVzLCBhc8OtIGNvbW8gbWl4dG9zIGRvYmxlcyB5IGVuIGVzdG9zIMO6bHRpbW9zIGHDsW9zLCBzZSBoYW4gaW5jbHVpZG8gdGFtYmnDqW4gY29tcGV0aWNpb25lcyBwYXJhIGp1Z2Fkb3JlcyBlbiBzaWxsYSBkZSBydWVkYXMuIEVuIGVsIGHDsW8gMjAxNyBlbCBjYW1wZcOzbiBkZSBsYSBjYXRlZ29yw61hIG1hc2N1bGluYSBmdWUgUm9nZXIgRmVkZXJlciB2ZW5jaWVuZG8gZW4gbGEgZmluYWwgYWwgbWFsbG9ycXXDrW4gUmFmYSBOYWRhbC4gRW4gbGEgY2F0ZWdvcsOtYSBmZW1lbmluYSBsYSBnYW5hZG9yYSBmdWUgbGEgY29ub2NpZGEgdGVuaXN0YSBlc3RhZG8gdW5pZGVuc2UgU2VyZW5hIFdpbGxpYW1zIHF1ZSBjdXJpb3NhbWVudGUganVnw7MgbGEgZmluYWwgY29udHJhIHN1IGhlcm1hbmEgVmVudXMgV2lsbGlhbXMuIDwvZGl2Lz4NCg0KYGBge3IsIGVjaG8gPSBGQUxTRSwgZXZhbCA9IFRSVUV9DQp0YWJsYUF1c3RyYWxpYW5PcGVuIDwtIGRhdG9zX3RlbmlzMiAlPiUgZmlsdGVyKFRvdXJuYW1lbnQgPT0gIkF1c3RyYWxpYW4gT3BlbiIpIA0KDQpgYGANCg0KYGBge3IsIGVjaG8gPSBGQUxTRSwgZXZhbCA9IFRSVUUsIG91dC53aWR0aCA9ICI1MCUiLCBmaWcuYWxpZ24gPSAiY2VudGVyIiwgZmlnLmNhcD0iRmlndXJhIDUifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1hZ2VuZXMiLCAiRkROLmpwZyIpICkgDQpgYGANCg0KIyMjIFdpbm5lcnMNCg0KQSBjb250aW51YWNpw7NuIHNlIHB1ZWRlbiBvYnNlcnZhciBsb3Mgbm9tYnJlcyBkZSBsb3MgZ2FuYWRvcmVzIGRlbCB0b3JuZW8gQXVzdHJhbGlhbiBPcGVuIHNlZ8O6biBlbCBuw7ptZXJvIGRlIHZpY3Rvcmlhcy4NCg0KYGBge3IsIGVjaG8gPSBGQUxTRSwgZXZhbCA9IFRSVUUsIG91dC53aWR0aCA9ICI3MCUiLCBmaWcuYWxpZ24gPSAiY2VudGVyIn0NCg0KdGFibGFBdXN0cmFsaWFuT3BlbjEgPC0gdGFibGFBdXN0cmFsaWFuT3BlbiAlPiVncm91cF9ieShXaW5uZXIpICU+JSBzdW1tYXJpc2Uobj1uKCkpICU+JSBuYS5vbWl0KGRhdG9zKSAlPiUgYXJyYW5nZShkZXNjKG4pKQ0KDQpgYGANCg0KDQpgYGB7ciBldmFsPVRSVUUsIGVjaG89RkFMU0V9DQoNCnJlYWN0YWJsZSh0YWJsYUF1c3RyYWxpYW5PcGVuMSwgZGVmYXVsdFBhZ2VTaXplID0gIDUsICBwYWdpbmF0aW9uVHlwZSA9ICJqdW1wIiwgc2hvd1BhZ2VTaXplT3B0aW9ucyA9ICBUUlVFICwgcGFnZVNpemVPcHRpb25zID0gIGMgKCAxMCAsIDUwICwgMTAwICksZGVmYXVsdENvbERlZiA9IGNvbERlZigNCiAgICBhbGlnbiA9ICJjZW50ZXIiLA0KICAgIG1pbldpZHRoID0gNzAsDQogICAgaGVhZGVyU3R5bGUgPSBsaXN0KGJhY2tncm91bmQgPSAiYXF1YW1hcmluZSIpLA0KICAgIGZpbHRlcmFibGUgPSBUUlVFKSwgIGhpZ2hsaWdodCA9IFRSVUUsIG91dGxpbmVkID0gVFJVRSwNCiAgICBjb2x1bW5zID0gbGlzdCgNCiAgYE1vdmllcyZUVlNob3cvYcOxb2AgPSBjb2xEZWYoc3R5bGUgPSBmdW5jdGlvbih2YWx1ZSkgew0KICAgIGlmICh2YWx1ZSA+IDApIHsNCiAgICAgIGNvbG9yIDwtICIjZTAwMDAwIn0NCiAgICAgIGVsc2Ugew0KICAgICAgY29sb3IgPC0gIiMwMDgwMDAiDQogICAgfQ0KICAgIGxpc3QoY29sb3IgPSBjb2xvciwgZm9udFdlaWdodCA9ICJib2xkIikNCiAgfSkpKQ0KDQpgYGANCg0KRGUgZm9ybWEgbcOhcyB2aXN1YWwgc2UgcHVlZGVuIG9ic2VydmFyIGxvcyBnYW5hZG9yZXMgZGVsIHRvcm5lbyByZWxhY2lvbmFuZG8gZWwgbsO6bWVybyBkZSB2aWN0b3JpYXMgY29uIGVsIHRhbWHDsW8gZGUgbGEgbGV0cmEuDQoNCmBgYHtyLCBlY2hvID0gRkFMU0UsIGV2YWwgPSBUUlVFLCBvdXQud2lkdGggPSAiNzAlIiwgZmlnLmFsaWduID0gImNlbnRlciJ9DQoNCnRhYmxhQXVzdHJhbGlhbk9wZW4xIDwtIHRhYmxhQXVzdHJhbGlhbk9wZW4gJT4lZ3JvdXBfYnkoV2lubmVyKSAlPiUgc3VtbWFyaXNlKG49bigpKSAlPiUgbmEub21pdChkYXRvcykgJT4lIGFycmFuZ2UoZGVzYyhuKSkNCg0KDQpub21icmVzd2lubmVyIDwtIHRhYmxhQXVzdHJhbGlhbk9wZW4xICU+JSBzZWxlY3QoV2lubmVyLCBuKQ0KDQp3b3JkY2xvdWQyKGRhdGEgPSBub21icmVzd2lubmVyLCBzaXplID0gMC42KQ0KDQpgYGANCg0KIyMjIFRvcm5lb3MgY29tcGxldGFkb3MgVnMgVG9ybmVvcyByZXRpcmFkb3MNCg0KRW4gbGEgdGFibGEgc2lndWllbnRlIHNlIHB1ZWRlIG9ic2VydmFyIGNvbW8gZGUgbG9zIDIxNTkgdG9ybmVvcyBxdWUgc2UgaGFuIGp1Z2FkbyB0YW4gc29sbyBlbiA4OSBvY2FzaW9uZXMgdW4ganVnYWRvciBzZSBoYSByZXRpcmFkby4NCg0KYGBge3IsIGVjaG8gPSBUUlVFLCBldmFsID0gVFJVRSwgb3V0LndpZHRoID0gIjcwJSIsIGZpZy5hbGlnbiA9ICJjZW50ZXIifQ0KdGFibGFBdXN0cmFsaWFuT3BlbjIgPC0gdGFibGFBdXN0cmFsaWFuT3BlbiAlPiUgZ3JvdXBfYnkoVG91cm5hbWVudCwgQ29tbWVudCklPiUgY291bnQoKQ0KDQpgYGANCg0KYGBge3IgZXZhbD1UUlVFLCBlY2hvPUZBTFNFfQ0Ka25pdHI6OmthYmxlKFRvdXJuYW1lbnQgPC0gdGFibGFBdXN0cmFsaWFuT3BlbjIpDQoNCmBgYA0KDQoNCiMjIDxzcGFuIHN0eWxlID0gImNvbG9yOmJsdWUiPjMuNCBBbsOhbGlzaXMgdG9ybmVvIFVTIE9wZW4uPC9zcGFuPnsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCmBgYHtyLCBlY2hvID0gRkFMU0UsIGV2YWwgPSBUUlVFfQ0KdGFibGFVU09wZW4xIDwtIGRhdG9zX3RlbmlzMiAlPiUgZmlsdGVyKFRvdXJuYW1lbnQgPT0gIlVTIE9wZW4iKSANCg0KYGBgDQoNCj48ZGl2IHN0eWxlID0gInRleHQtYWxpZ246IGp1c3RpZnkiPioqKkVsIHRvcm5lbyBVUyBPcGVuIHNlIGNlbGVicmEgYW51YWxtZW50ZSBlbnRyZSBhZ29zdG8geSBzZXB0aWVtYnJlIGVuIGVsIFVTVEEgQmlsbGllIEplYW4gS2luZyBOYXRpb25hbCBUZW5uaXMgQ2VudGVyIGRlIE51ZXZhIFlvcmsgeSBjb25zdGEgZGUgY2luY28gbW9kYWxpZGFkZXM6IGluZGl2aWR1YWxlcyBkZSBob21icmVzIHkgbXVqZXJlcywgZG9ibGVzIGRlIGhvbWJyZXMgeSBtdWplcmVzIHkgZG9ibGVzIG1peHRvcywgeSAgdGFtYmnDqW4gdG9ybmVvcyBhZGljaW9uYWxlcyBwYXJhIGp1Z2Fkb3JlcyBKdW5pb3IgeSBTZW5pb3IuIEVsIHRvcm5lbyByZXBhcnRlIGNhc2kgdmVpbnRpY3VhdHJvIG1pbGxvbmVzIGRlIGTDs2xhcmVzIGVuIHByZW1pb3MuKioqIDwvZGl2Lz4NCg0KIyMjIEZFTElDSUFOTyBMw5NQRVoNCg0KQ29uIGVsIHNpZ3VpZW50ZSBjaHVuayBwb2RlbW9zIHZlciBxdWUgZWwgdGVuaXN0YSBxdWUgbcOhcyB0b3JuZW9zIFVTIE9wZW4gaGEgcGVyaWRvIGVzOg0KDQoNCmBgYHtyLCBlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUV9DQp0YWJsYVVTT3BlbjIgPC0gdGFibGFVU09wZW4xICU+JWdyb3VwX2J5KExvc2VyKSAlPiUgc3VtbWFyaXNlKG49bigpKSAlPiUgbmEub21pdChkYXRvcykgJT4lIHNsaWNlX21heChuLG4gPTEpDQoNCmBgYA0KDQpgYGB7ciBldmFsPVRSVUUsIGVjaG89RkFMU0V9DQprbml0cjo6a2FibGUoVG91cm5hbWVudCA8LSB0YWJsYVVTT3BlbjIpDQoNCmBgYA0KDQo8ZGl2IHN0eWxlID0gInRleHQtYWxpZ246IGp1c3RpZnkiPj4gKioqTGEgZGVycm90YSBkZSBGZWxpY2lhbm8gTMOzcGV6IGFudGUgR2lsbGVzIFNpbW9uIHBvciA2LTQgeSA2LTMgZW4gc3UgZGVidXQgZW4gZWwgVG9ybmVvIGRlIFZpZW5hIGhhIGhlY2hvIHF1ZSBlbCB0b2xlZGFubyBzZSBjb252aWVydGEgZW4gZWwgdGVuaXN0YSBjb24gbcOhcyBkZXJyb3RhcyBzdWZyaWRhcyBlbiBlbCBjaXJjdWl0byBBVFAganVudG8gYWwgZnJhbmPDqXMgRmFicmljZSBTYW50b3JvLiBBIHN1cyAzOCBhw7FvcyB5IHRyYXMgMjIgdGVtcG9yYWRhcyBjb21vIHByb2Zlc2lvbmFsIChkZWJ1dMOzIGVuIDE5OTcpLCBGZWxpY2lhbm8gZXMgdW5vIGRlIGxvcyBqdWdhZG9yZXMgbcOhcyB2ZXRlcmFub3MgZGVsIGNpcmN1aXRvIGp1bnRvIGNvbiBSb2dlciBGZWRlcmVyLiBFc3RvIG5vIHF1aWVyZSBkZWNpciBxdWUgRmVsaWNpYW5vIHNlYSB1bm8gZGUgbG9zIHBlb3JlcyB0ZW5pc3RhcyBkZWwgY2lyY3VpdG8sIHNpbm8gcXVlIGxvcyBuw7ptZXJvcyBzZSBkZWJlbiBhIHN1IGxvbmdldmlkYWQgZW4gZWwgbWlzbW8uIEZlbGljaWFubyBMw7NwZXogaGEgZGlzcHV0YWRvIHVuIHRvdGFsIGRlIDkyOSBwYXJ0aWRvcyBjb24gNDg1IHZpY3RvcmlhcyB5IDQ0NCBkZXJyb3RhcywgY29uIHVuIHBvcmNlbnRhamUgZGUgdHJpdW5mb3MgZGVsIDUyLDMlKioqIDwvZGl2Lz4NCg0KYGBge3IsIGVjaG8gPSBGQUxTRSwgZXZhbCA9IFRSVUUsIG91dC53aWR0aCA9ICI1MCUiLCBmaWcuYWxpZ24gPSAiY2VudGVyIiwgZmlnLmNhcD0iRmlndXJhIDYifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1hZ2VuZXMiLCAiRl9Mb3Blei5qcGciKSApIA0KYGBgDQoNCiMjIyBXSU5ORVJTIFZzIExPU0VSUw0KDQo8ZGl2IHN0eWxlID0gInRleHQtYWxpZ246IGp1c3RpZnkiPkNvbiBlbCBzaWd1aWVudGUgY2h1bmsgcG9kZW1vcyBvYnNlcnZhciBsYXMgZGlmZXJlbmNpYXMgZW50cmUgbG9zIDEwIGp1Z2Fkb3JlcyBxdWUgbcOhcyB2ZWNlcyBoYW4gZ2FuYWRvIGVsIFVTIE9wZW4gIHkgbG9zIDEwIGp1Z2Fkb3JlcyBxdWUgbcOhcyB0b25yZW9zIGhhbiBwZXJkaWRvPC9kaXYvPg0KDQpgYGB7ciwgb3V0LndpZHRoPSc1MCUnLGZpZy5zaG93PSdob2xkJyxmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5jYXA9IkRvcyBncmHMgWZpY29zIFIgY2FyYSBhIGNhcmEifQ0KDQp0YWJsYVdSYW5rIDwtIHRhYmxhVVNPcGVuMSAlPiVncm91cF9ieShXaW5uZXIpICU+JSBzdW1tYXJpc2UoUmFua2luZz1uKCkpICU+JSBuYS5vbWl0KGRhdG9zKSAlPiUgc2xpY2VfbWF4KFJhbmtpbmcsbiA9MTApDQoNCmdyYWZpY29XUmFuayA8LSB0YWJsYVdSYW5rICU+JSBtdXRhdGUoV2lubmVyID0gZm9yY2F0czo6YXNfZmFjdG9yKFdpbm5lcikpDQpncmFmaWNvV1JhbmsxLjEgPC0gZ2dwbG90IChncmFmaWNvV1JhbmssYWVzKHg9V2lubmVyLCB5ID0gUmFua2luZyksIGFlcyhmY3RfcmV2KFdpbm5lcikpKSArIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IiwgZmlsbCA9ICJncmVlbiIpICsgY29vcmRfZmxpcCgpDQpncmFmaWNvV1JhbmsxLjEgKyBsYWJzKHRpdGxlID0gIkdyw6FmaWNvIGRlIGxvcyAxMCBqdWdhZG9yZXMgcXVlIG3DoXMgdmVjZXMgaGFuIGdhbmFkbyBlbCBVUyBPcGVuIiwNCiAgICAgICBjYXB0aW9uID0gIkRhdG9zIHByb3ZlbmllbnRlcyBkZWwgZGF0b3NfdGVuaXMyIiwNCiAgICAgICB4ID0gIldpbm5lciIsDQogICAgICAgeSA9ICJuIiwNCiAgICAgICBjb2xvciA9ICJFc3BlY2llIGRlIGxpcmlvIikNCg0KdGFibGFXUmFuazIgPC0gdGFibGFVU09wZW4xICU+JWdyb3VwX2J5KExvc2VyKSAlPiUgc3VtbWFyaXNlKFJhbmtpbmc9bigpKSAlPiUgbmEub21pdChkYXRvcykgJT4lIHNsaWNlX21heChSYW5raW5nLG4gPTEwKQ0KDQpncmFmaWNvV1JhbmsyIDwtIHRhYmxhV1JhbmsyICU+JSBtdXRhdGUoTG9zZXIgPSBmb3JjYXRzOjphc19mYWN0b3IoTG9zZXIpKQ0KZ3JhZmljb1dSYW5rMS4yIDwtIGdncGxvdCAoZ3JhZmljb1dSYW5rMixhZXMoeD1Mb3NlciwgeSA9IFJhbmtpbmcpLCBhZXMoZmN0X3JldihMb3NlcikpKSArIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IiwgZmlsbCA9ICJncmVlbiIpICsgY29vcmRfZmxpcCgpDQpncmFmaWNvV1JhbmsxLjEgKyBsYWJzKHRpdGxlID0gIkdyw6FmaWNvIGRlIGxvcyAxMCBqdWdhZG9yZXMgcXVlIG3DoXMgdmVjZXMgaGFuIHBlcmRpZG8gZWwgVVMgT3BlbiIsDQogICAgICAgY2FwdGlvbiA9ICJEYXRvcyBwcm92ZW5pZW50ZXMgZGVsIGRhdG9zX3RlbmlzMiIsDQogICAgICAgeCA9ICJMb3NlciIsDQogICAgICAgeSA9ICJuIiwNCiAgICAgICBjb2xvciA9ICJFc3BlY2llIGRlIGxpcmlvIikNCg0KYGBgDQoNCiMgKio0LiBMYXMgMTAgY2l1ZGFkZXMgZW4gbGFzIHF1ZSBzZSBqdWVnYW4gbcOhcyB0b3JuZW9zKioNCg0KRW4gZXN0ZSBncsOhZmljbyBzZSBwdWVkZW4gb2JzZXJ2YXIgbGFzIDEwIGNpdWRhZGVzIGVuIGxhcyBxdWUgbcOhcyB0b3JuZW9zIHNlIGp1ZWdhbi4NCg0KYGBge3IsIGVjaG8gPSBGQUxTRSwgZXZhbCA9IFRSVUV9DQoNCnRhYmxhbG9jYXRpb24gPC0gZGF0b3NfdGVuaXMyICU+JWdyb3VwX2J5KExvY2F0aW9uKSAlPiUgc3VtbWFyaXNlKENpdWRhZGVzPW4oKSkgJT4lIG5hLm9taXQoZGF0b3MpICU+JSBzbGljZV9tYXgoQ2l1ZGFkZXMsbiA9MTApDQoNCnRhYmxhbG9jYXRpb24xIDwtIHRhYmxhbG9jYXRpb24gJT4lIG11dGF0ZShMb2NhdGlvbiA9IGZvcmNhdHM6OmFzX2ZhY3RvcihMb2NhdGlvbikpDQp0YWJsYWxvY2F0aW9uMS4xIDwtIGdncGxvdCAodGFibGFsb2NhdGlvbjEsYWVzKHg9TG9jYXRpb24sIHkgPSBDaXVkYWRlcyksIGFlcyhmY3RfcmV2KExvY2F0aW9uKSkpICsgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCBmaWxsID0gImJsYWNrIikgKyBjb29yZF9mbGlwKCkNCnRhYmxhbG9jYXRpb24xLjEgKyBsYWJzKHRpdGxlID0gIkdyw6FmaWNvIGRlIGxhcyAxMCBjaXVkYWRlcyBjb24gbcOhcyB0b3JuZW9zIGp1Z2Fkb3MiLA0KICAgICAgIGNhcHRpb24gPSAiRGF0b3MgcHJvdmVuaWVudGVzIGRlbCBkYXRvc190ZW5pczIiLA0KICAgICAgIHggPSAiTG9jYXRpb24iLA0KICAgICAgIHkgPSAiQ2l1ZGFkZXMiLA0KICAgICAgIGNvbG9yID0gIkVzcGVjaWUgZGUgbGlyaW8iKQ0KYGBgDQoNCg0KRXN0ZSBtYXBhIG5vcyBtdWVzdHJhIGRlIGZvcm1hIG3DoXMgdmlzdWFsIGxhcyAxMCBjaXVkYWRlcyBtZW5jaW9uYWRhcyBhbnRlcmlvcm1lbnRlLg0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIGV2YWwgPSBUUlVFLCBvdXQud2lkdGggPSAiNzAlIiwgZmlnLmFsaWduID0gImNlbnRlciJ9DQoNCnBhcihtYXI9YygwLDAsMCwwKSkNCm1hcCgnd29ybGQnLA0KICAgIGNvbD0iI2YyZjJmMiIsIGZpbGw9VFJVRSwgYmc9IndoaXRlIiwgbHdkPTAuMDUsDQogICAgbWFyPXJlcCgwLDQpLGJvcmRlcj0wLCB5bGltPWMoLTgwLDgwKQ0KKQ0KDQpMb25kb24gPC0gYygtMC4xMiw1MSkNClBhcmlzIDwtIGMoMiw0OSkNCk1lbGJvdXJuZSA8LSBjKDE0NSwtMzgpDQpOZXdfWW9yayA8LSBjKC03Myw0MCkNCk1pYW1pIDwtIGMoLTgwLDI1KQ0KSW5kaWFuX1dlbGxzIDwtIGMoLTExNiwzMykNCkNpbmNpbm5hdGkgPC0gYygtODQsMzkpDQpNb250ZV9DYXJsbyA8LSBjKDcsNDMpDQpSb21lIDwtIGMoMTIsNDEpDQpCYXJjZWxvbmEgPC0gYygyLDQxKQ0KDQoNCmRhdGEgPC0gcmJpbmQoTG9uZG9uLCBQYXJpcywgTWVsYm91cm5lLCBOZXdfWW9yaywgTWlhbWksIEluZGlhbl9XZWxscywgQ2luY2lubmF0aSwgTW9udGVfQ2FybG8sIFJvbWUsIEJhcmNlbG9uYSkgJT4lIA0KICBhcy5kYXRhLmZyYW1lKCkNCmNvbG5hbWVzKGRhdGEpIDwtIGMoImxvbmciLCJsYXQiKQ0KDQptYXAoJ3dvcmxkJywNCiAgICBjb2w9IiNmMmYyZjIiLCBmaWxsPVRSVUUsIGJnPSJ3aGl0ZSIsIGx3ZD0wLjA1LA0KICAgIG1hcj1yZXAoMCw0KSxib3JkZXI9MCwgeWxpbT1jKC04MCw4MCkgDQopDQpwb2ludHMoeD1kYXRhJGxvbmcsIHk9ZGF0YSRsYXQsIGNvbD0ic2xhdGVibHVlIiwgY2V4PTMsIHBjaD0yMCkNCg0KYGBgDQoNCiMgKio1LiBDb25jbHVzaW9uZXMqKg0KDQo8ZGl2IHN0eWxlID0gInRleHQtYWxpZ246IGp1c3RpZnkiPj4gRW4gY29uY2x1c2nDs24sIGV4aXN0ZW4gdW4gZ3JhbiBuw7ptZXJvIGRlIHRvcm5lb3MgZGUgdGVuaXMgZGl2aWRvcyBlbiBkaXN0aW50YXMgY2F0ZWdvcsOtYXMuIExvcyBwdWVzdG9zIGdhbmFkb3JlcyBkZSBsb3MgZ3JhbmRlcyB0b3JuZW9zIHN1ZWxlbiBlc3RhcyBkaXNwdXRhZG9zIHNpZW1wcmUgcG9yIGxvcyBtaXNtb3MgdGVuaXN0YXMuIERlc3B1w6lzIGRlIGVzdGUgYW7DoWxpc2lzIHBvZGVtb3MgdmVyIGNvbW8gbGxlZ2FyIGEgYWxjYW56YXIgZWwgaGlzdG9yaWFsIGRlIEZlZGVyZXIsIERqb2tvdmljIHkgTmFkYWwgZXN0w6EgbXV5IGRpZmljaWwgaG95IGVuIGTDrWEuIFRhbWJpw6luIGhlbW9zIHZpc3RvIGNvbW8gaW1wb3J0YSBtdWNobyBsYSBsb25nZXZpZGFkIHF1ZSBzZSB0aWVuZSBlbiBlc3RlIGRlcG9ydGUgeWEgcXVlIGVsIHBvcmNlbnRhamUgZGUgdmljdG9yaWFzIHkgZGVycm90YXMgcHVlZGUgdmFyaWFyLiBQb3Igb3RybyBsYWRvLCBlbiBlbCBhcGFydGFkbyBkZWwgZ3LDoWZpY28gZGVsIG1hcGEgZGVsIG11bmRvIHNlIHB1ZWRlIG9ic2VydmFyIGNvbW8gbGEgbWF5b3LDrWEgZGUgbGFzIGNpdWRhZGVzIGVuIGxhcyBxdWUgbcOhcyB0b3JuZW9zIGRlIHRlbmlzIHNlIGp1ZWdhbiBzb24gY2l1ZGFkZXMgRXVyb3BlYXMuIDwvZGl2Lz4NCg0KDQojICoqNi4gQmlibGlvZ3JhZsOtYSoqDQoNCj5BcHVudGVzIGRlIGxhIGFzaWduYXR1cmEgZGUgUHJvZ3JhbWFjacOzbiB5IE1hbmVqbyBkZSBkYXRvcyBlbiBsYSBlcmEgZGVsIEJpZyBEYXRhOg0KaHR0cHM6Ly9wZXJlenA0NC5naXRodWIuaW8vaW50cm8tZHMtMjAtMjEtd2ViLzA0LXR1dG9yaWFsZXMuaHRtbA0KDQo+IEluZm9ybWFjacOzbiBzb2JyZSBkaXN0aW50b3MgdG9ybmVvczoNCmh0dHA6Ly93d3cudGVuaXNwb250ZGluY2Fub3UuY29tL2Jsb2cvdG9ybmVvcy9wcmluY2lwYWxlcy1jYW1wZW9uYXRvcy15LXRvcm5lb3MtZGVsLXRlbmlzDQoNCj5JbmZvcm1hY2nDs24gc29icmUgRmVsaWNpYW5vIExvcGV6Og0KaHR0cHM6Ly9hcy5jb20vdGVuaXMvMjAxOS8xMC8yMy9tYXNfdGVuaXMvMTU3MTgxMzUxNl8zODA0MDMuaHRtbA0KDQo+UMOhZ2luYSBkZSByZWZlcmVuY2lhIHBhcmEgbG9zIGdyw6FmaWNvczoNCmh0dHBzOi8vd3d3LnItZ3JhcGgtZ2FsbGVyeS5jb20vMTk2LXRoZS13b3JkY2xvdWQyLWxpYnJhcnkuaHRtbA0KDQo+RXhjZWwgY29uIGxvcyBkYXRvczoNCmh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZWRvdWFyZHRob21hcy9iZWF0LXRoZS1ib29rbWFrZXJzLXdpdGgtbWFjaGluZS1sZWFybmluZy10ZW5uaXMNCg0KIyAqKjcuIFNlc2nDs24gSW5mb3JtYXRpdmEqKg0KYGBge3J9DQogICAgc2Vzc2lvbmluZm86OnNlc3Npb25faW5mbygpICU+JSBkZXRhaWxzOjpkZXRhaWxzKHN1bW1hcnkgPSAnY3VycmVudCBzZXNzaW9uIGluZm8nKQ0KYGBg