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 2021-2022. El repo del trabajo está aquí.

La página web de la asignatura y los trabajos de mis compañeros pueden verse aquí.


INTRODUCCIÓN

Hoy en día el cine se ha convertido en uno de los medios más populares para la difusión del arte, cultura y sobre todo entretenimiento. Es por eso que en este trabajo vamos a mostrar de una forma algo más detallada los aspectos más relevantes del cine en estos últimos años. Recorreremos a lo largo del proyecto las películas favoritas por la audiencia. Esperamos que este trabajo os sirva para incrementar vuestra cultura cineasta y os incite a ver alguna de las películas mencionadas.

1.- PRIMERA PARTE (10K PELICULAS)

1.1 DATOS A ANALIZAR

A continuación, vamos a mostrar una lista de las 10000 películas con las que vamos a trabajar inicialmente.

peliculas <- top10mil %>%
select(original_title)
reactable(peliculas, defaultPageSize =  8,  paginationType = "jump", showPageSizeOptions =  TRUE , pageSizeOptions =  c ( 10 , 50 , 100, 150, 200, 260 ),defaultColDef = colDef(
    align = "center",
    minWidth = 70,
    headerStyle = list(background = "#FFD700"),
    filterable = TRUE),  highlight = TRUE, outlined = TRUE,
    columns = list(
  `Item` = colDef(style = function(value) {
    if (value > 0) {
      color <- "#F5C710"}
      else {
      color <- "#B22222"
    }
    list(color = color, fontWeight = "bold",background = "#CD2626")
  })))

1.2 IDIOMA ESTRELLA

En este apartado hemos querido representar cual es el idioma que predomina como lengua original en el paquete de datos con el que estamos trabajando. Claramente, de entre las diez mil películas, el idioma en la que la mayoría de ellas está es en Inglés (sin hacer distinción entre inglés británico o americano).

topmil_pais <- top10mil %>%
  group_by(original_language)  %>%  
   mutate(numpelis = sum(NN=n())) %>%
  distinct(original_language, numpelis) %>% 
  arrange(desc(numpelis)) %>% 
  filter(numpelis>200) %>% 
  mutate(idioma = case_when(original_language == "en" ~ "Inglés", 
                            original_language == "ja" ~ "Japonés" ,
                            original_language == "es" ~ "Español",
                            original_language == "fr" ~ "Francés"))
  
ggplot(topmil_pais, aes(x = idioma, y = numpelis, fill = idioma)) +  
  geom_bar(stat="identity") +
  scale_fill_manual(values = c("yellow", "white", "blue", "red") ) +
  scale_y_continuous( breaks = seq(0, 8000, 1000),
    limits = c(0, 8000))

1.3 TOP PELÍCULAS

La siguiente gráfica es probablemente una de las más interesantes del trabajo, ya que básicamente nos muestra las 7 películas con más popularidad. Como podemos observar, el top 1 es Venom: Let There Be Carnage

popularidad <- top10mil %>% 
  arrange(desc(popularity)) %>% 
  filter(popularity > 1300)
 

  ggplot(popularidad, aes(x=original_title, y=popularity)) +
    geom_bar(stat="identity") +
    coord_flip() +
    xlab("") +
    theme_bw() +
      scale_y_continuous( breaks = seq(0, 5500, 500),
    limits = c(0, 5500))

Venom: Let There Be Carnage

1.4 MÁXIMA VOTACIÓN

A continuación mostraremos en un gráfico animado las cuatro películas con una votación más elevada.

votos <- top10mil %>% 
  arrange(desc(vote_average)) %>% 
  filter(vote_average > 9.1) %>% 
  filter(original_language %in% c("zh", "es", "fr"))

votos$original_title <- iconv(votos$original_title, from = "UTF-8", to = "LATIN1")

ggvotos <- ggplot(votos, aes(x = original_title, y = vote_average)) +
  geom_point() +
  geom_segment( aes(x = original_title, xend = original_title, y = 0, yend = vote_average))

ggplotly(ggvotos)

Días de CANGREBURGERS Ebola Zombies


2.- SEGUNDA PARTE (4K PELICULAS)

2.1 DATOS A ANALIZAR

La idea ahora es mostrar algunos de los apartados vistos anteriormente pero cambiando el paquete de datos usando ahora uno con menos películas y algo más recientes.

Mostramos a contiuación pues, los datos con los que vamos a trabajar ahora.

names(top4mil)[names(top4mil) == 'Movie Title'] <- 'movietitle'



peliculas4 <- top4mil %>%
select(movietitle)
reactable(peliculas4, defaultPageSize =  8,  paginationType = "jump", showPageSizeOptions =  TRUE , pageSizeOptions =  c ( 10 , 50 , 100, 150, 200, 260 ),defaultColDef = colDef(
    align = "center",
    minWidth = 70,
    headerStyle = list(background = "#FFD700"),
    filterable = TRUE),  highlight = TRUE, outlined = TRUE,
    columns = list(
  `Item` = colDef(style = function(value) {
    if (value > 0) {
      color <- "#F5C710"}
      else {
      color <- "#B22222"
    }
    list(color = color, fontWeight = "bold",background = "#CD2626")
  })))

2.2 MAYOR PIB DOMÉSTICO

En este otro punto ordenamos las películas de forma descendente, las películas que han generado mayor PIB nacional.

names(top4mil)[names(top4mil) == 'Domestic Gross'] <- 'domesticPIB'

PIB <- top4mil %>% 
  arrange(desc(domesticPIB)) %>% 
  filter(domesticPIB > 543638042)
 

  ggplot(PIB, aes(x=movietitle, y=domesticPIB)) +
    geom_bar(stat="identity") +
    coord_flip() +
    xlab("") +
    theme_bw() +
      scale_y_continuous( breaks = seq(0, 80000, 858373000),
    limits = c(0, 8583730000))

Como vemos en el gráfico, la pelicula que más ha aportado al PIB doméstico ha sido Star Wars Ep. VII: The Force Awakens

Star Wars Ep. VII: The Force Awakens

2.3 MAYOR PIB MUNDIAL

Muy parecido al apartado anterior, ahora las distinguimos pero mediante la aportación al PIB mundial.

names(top4mil)[names(top4mil) == 'Worldwide Gross'] <- 'PIB'

PIB <- top4mil %>% 
  arrange(desc(PIB)) %>% 
  filter(PIB >  1654367425)
 

  ggplot(PIB, aes(x=movietitle, y=PIB)) +
    geom_bar(stat="identity") +
    coord_flip() +
    xlab("") +
    theme_bw() +
      scale_y_continuous( breaks = seq(0, 429186500, 858373000),
    limits = c(0, 8583730000))

En este otro gráfico podemos observar que las películas que más PIB mundial han aportado han sido, Avatar y Avengers: Endgame, con números bastante similares.

Avatar Avengers: Endgame

3.- TERCERA PARTE ( MÁS PELIS)

3.1 DATOS A ANALIZAR

Cambiamos ahora otra vez el conjunto de datos con el que vamos a trabajar y disminuimos el paquete a tan solo 118 películas. Pasaremos a analizar otros aspectos distintos de los anteriores.

peliculas <- maspelis %>%
select(Title)
reactable(peliculas, defaultPageSize =  8,  paginationType = "jump", showPageSizeOptions =  TRUE , pageSizeOptions =  c ( 10 , 50 , 100, 150, 200, 260 ),defaultColDef = colDef(
    align = "center",
    minWidth = 70,
    headerStyle = list(background = "#FFD700"),
    filterable = TRUE),  highlight = TRUE, outlined = TRUE,
    columns = list(
  `Item` = colDef(style = function(value) {
    if (value > 0) {
      color <- "#F5C710"}
      else {
      color <- "#B22222"
    }
    list(color = color, fontWeight = "bold",background = "#CD2626")
  })))

3.2 GÉNERO DE LAS PELÍCULAS

categorias <- maspelis %>%
  group_by(Genre1)  %>%  
   mutate(numeroxgenero = sum(NN=n())) %>%
  distinct(Genre1, numeroxgenero) %>% 
  arrange(desc(numeroxgenero))  

  
ggplot(categorias, aes(x = Genre1, y = numeroxgenero, fill = Genre1)) +  
  geom_bar(stat="identity") +
  scale_fill_manual(values = c("pink", "black", "purple", "red", "yellow", "green", "brown", "grey") ) +
  scale_y_continuous( breaks = seq(0, 29, 6),
    limits = c(0, 29))

Hemos querido representar con este gráfico tan colorido, los géneros de las películas. Podríamos decir que hay muchas más películas de acción y drama que de los otros géneros. Es cierto que es aquí en este conjunto de datos que se da así, pero si cogiésemos todas las películas que existen, las proporciones serían parecidas ya que son los géneros que más venden y más gustan a la mayoría de la población.

3.3 DURACIÓN PELÍCULAS

duration <- maspelis %>%
  group_by(Runtime) %>%
  mutate(sameduration = sum(NN=n())) %>%
  distinct(Runtime, sameduration, Title) %>%
  filter(Runtime >0) %>%
  filter(Runtime > 166) %>%
  filter(Runtime < 9) %>%
  arrange(desc(Runtime)) 
 






grafduration <- ggplot (duration, aes(x = Title, y = Runtime)) + geom_bar(stat = "identity", fill = "steelblue")
grafduration + labs(title = "Gráfico: Duración de las películas",
       subtitle = "(diferenciando por año)",
       x = "Películas",
       y = "Duración",
       color = "Especie de lirio")

A través de este gráfico vemos las películas que más duran. En este top 3 están: - Interstellar (un peliculón, vale la pena la duración) - El hobbit (para gustos colores yo no la he visto) - El lobo de Wall Street, bastante conocida y famosa, con una duración de 3horas.

The Wolf of Wall Street

4.- CUARTA PARTE ( AÚN MÁS PELIS)

Con este cuarto y último paquete de datos que vamos a utilizar en este trabajo, vamos a mostrar la recaudación bruta de las películas en los Estados Unidos.

recaud <- aunmaspelis %>%
  select(movie_name, us_grossMillions) %>%
  head(us_grossMillions, n = 10)%>%
  group_by(movie_name, us_grossMillions) %>%
  arrange(desc(us_grossMillions))

recaud
movie_name us_grossMillions
Avengers: Endgame 858.37000
Joker 335.45000
Knives Out 165.36000
1917 159.23000
Once Upon a Time… in Hollywood 142.50000
Little Women 108.10000
The Ten Commandments 93.74000
The Gentlemen 69.04371
Parasite 53.37000
The Shawshank Redemption 28.34000
wordcloud2(data=recaud, size=0.35)

En este gráfico interactivo se muestran las películas con más recaudación con un tamaño más grande y a medida que los títulos se hacen más pequeños significa que la recaudación es menor. Si mantenemos el cursor encima de los títulos de las películas nos dice exactamente el importe de la recaudación bruta. Destacaríamos sin duda Avengers: End Game y seguidamente Joker.

LS0tDQp0aXRsZTogIlRPUCBQZWxpY3VsYXMiDQpzdWJ0aXRsZTogIkFMQkEgRVNURUxBIEdBUkNJQSAoYWxlc2dhcjNAYWx1bW5pLnV2LmVzKSIgIy0gcG9uZ28gdMO6IG5vbWJyZSBhaMOtIHBhcmEgcSBhcGFyZXpjYSBtw6FzIGdyYW5kZSBxIGVsIGRlIGxhIFVWDQphdXRob3I6ICJVbml2ZXJzaXRhdCBkZSBWYWzDqG5jaWEiDQpkYXRlOiAiRGljaWVtYnJlIGRlIDIwMjEgKGFjdHVhbGl6YWRvIGVsIGByIGZvcm1hdChTeXMudGltZSgpLCAnJWQtJW0tJVknKWApIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgICNjc3M6ICIuL2Fzc2V0cy9teV9jc3NfZmlsZS5jc3MiDQogICAgdGhlbWU6IHBhcGVyDQogICAgaGlnaGxpZ2h0OiB0ZXh0bWF0ZSANCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZGVwdGg6IDMgDQogICAgdG9jX2Zsb2F0OiANCiAgICAgIGNvbGxhcHNlZDogdHJ1ZQ0KICAgICAgc21vb3RoX3Njcm9sbDogdHJ1ZQ0KICAgIHNlbGZfY29udGFpbmVkOiB0cnVlDQogICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQ0KICAgIGRmX3ByaW50OiBrYWJsZQ0KICAgIGNvZGVfZm9sZGluZzogc2hvdw0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCmVkaXRvcl9vcHRpb25zOiANCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUNCi0tLQ0KDQpgYGB7Y3NzLCBlY2hvID0gRkFMU0V9DQouY29sdW1ucyB7ZGlzcGxheTpmbGV4O30NCmgxLnRpdGxlIHtmb250LXNpemU6IDUwIHB4O2NvbG9yOiAjMDAwMDAwfQ0KaDEge2NvbG9yOiMwYTBhMGE7IGZvbnQtc2l6ZTogMzBweCA7Zm9udC1mYW1pbHk6IEFyaWFsIEJsYWNrfQ0KaDJ7Y29sb3I6ICMwYTBhMGE7IGZvbnQtc2l6ZTogMjBweDsgZm9udC1mYW1pbHk6IEFyaWFsIEJsYWNrfQ0KYm9keSB7IGJhY2tncm91bmQtY29sb3I6ICM3M2VmZmF9DQphIHtjb2xvcjogIzAxMDEwMTt9DQoubGlzdC1ncm91cC1pdGVtLmFjdGl2ZSwgLmxpc3QtZ3JvdXAtaXRlbS5hY3RpdmU6Zm9jdXMsIC5saXN0LWdyb3VwLWl0ZW0uYWN0aXZlOmhvdmVyIHsNCiAgICB6LWluZGV4OiAyOw0KICAgIGNvbG9yOiA7DQogICAgYmFja2dyb3VuZC1jb2xvcjogI2M0MzQyZDsNCiAgICBib3JkZXItY29sb3I6IHBhbGVyZWQ7DQp9DQoubmF2LXBpbGxzID4gbGkuYWN0aXZlID4gYSwgLm5hdi1waWxscyA+IGxpLmFjdGl2ZSA+IGE6aG92ZXIsIC5uYXYtcGlsbHMgPiBsaS5hY3RpdmUgPiANCmBgYA0KDQoNCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkocmVhY3RhYmxlKQ0KbGlicmFyeSh0aWJibGUpDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkodGlkeXZlcnNlKQ0KDQpsaWJyYXJ5KGhyYnJ0aGVtZXMpDQpsaWJyYXJ5KHBhdGNod29yaykNCmxpYnJhcnkoZ2dhbmltYXRlKQ0KbGlicmFyeSh3b3JkY2xvdWQyKQ0KbGlicmFyeSh3ZWJzaG90KQ0KbGlicmFyeShjb3JycGxvdCkNCmxpYnJhcnkoc3FsZGYpDQpsaWJyYXJ5KFJDb2xvckJyZXdlcikgDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpsaWJyYXJ5KGdnVGhlbWVBc3Npc3QpDQoNCg0KdG9wMTBtaWwgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvVE9QMTAwME1PVklFUy5jc3YiKQ0KdG9wNG1pbCA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9UT1A0MDAwTU9WSUVTLmNzdiIpDQptYXNwZWxpcyA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9JTURCLmNzdiIpDQphdW5tYXNwZWxpcyA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9tb3ZpZXNfSU1EQi5jc3YiKQ0KDQoNCmBgYA0KDQoNCg0KDQoNCmBgYHtyIG9wdGlvbnMtc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCm9wdGlvbnMoc2NpcGVuID0gOTk5KSAjLSBwYXJhIHF1aXRhciBsYSBub3RhY2nDs24gY2llbnTDrWZpY2ENCm9wdGlvbnMoInlhbWwuZXZhbC5leHByIiA9IFRSVUUpIA0KYGBgDQoNCg0KYGBge3Iga2xpcHB5LCBlY2hvID0gRkFMU0V9DQprbGlwcHk6OmtsaXBweShwb3NpdGlvbiA9IGMoInRvcCIsICJyaWdodCIpKSAjLSByZW1vdGVzOjppbnN0YWxsX2dpdGh1Yigicmxlc3VyL2tsaXBweSIpDQpgYGANCg0KDQo8aHIgY2xhc3M9ImxpbmVhLWJsYWNrIj4NCg0KPCEtLSBFbCBww6FycmFmbyBkZSBhYmFqbyBoYXMgZGUgZGVqYXJsbyBjYXNpIGlndWFsLCBzb2xvIEhBUyBkZSBTVVNUSVRVSVIgInBlcmV6cDQ0IiBwb3IgdHUgdXN1YXJpbyBkZSBHaXRodWItLT4NClRyYWJham8gZWxhYm9yYWRvIHBhcmEgbGEgYXNpZ25hdHVyYSAiUHJvZ3JhbWFjacOzbiB5IG1hbmVqbyBkZSBkYXRvcyBlbiBsYSBlcmEgZGVsIEJpZyBEYXRhIiBkZSBsYSBVbml2ZXJzaXRhdCBkZSBWYWzDqG5jaWEgZHVyYW50ZSBlbCBjdXJzbyAyMDIxLTIwMjIuIEVsIHJlcG8gZGVsIHRyYWJham8gZXN0w6EgW2FxdcOtXShodHRwczovL2dpdGh1Yi5jb20vYWxiYWVzdGVsYTE0L3RyYWJham9fQmlnRGF0YSl7dGFyZ2V0PSJfYmxhbmsifS4gDQoNCjwhLS0gRWwgcMOhcnJhZm8gZGUgYWJham8gaGFzIGRlIGRlamFybG8gZXhhY3RhbWVudGUgaWd1YWwsIE5PIEhBUyBERSBDQU1CSUFSIE5BREEtLT4NCg0KTGEgcMOhZ2luYSB3ZWIgZGUgbGEgYXNpZ25hdHVyYSB5IGxvcyB0cmFiYWpvcyBkZSBtaXMgY29tcGHDsWVyb3MgcHVlZGVuIHZlcnNlIFthcXXDrV0oaHR0cHM6Ly9wZXJlenA0NC5naXRodWIuaW8vaW50cm8tZHMtMjEtMjItd2ViLzA3LXRyYWJham9zLmh0bWwpe3RhcmdldD0iX2JsYW5rIn0uDQoNCg0KPGhyIGNsYXNzPSJsaW5lYS1yZWQiPg0KDQoNCiMgKipJTlRST0RVQ0NJw5NOKioNCg0KSG95IGVuIGTDrWEgZWwgY2luZSBzZSBoYSBjb252ZXJ0aWRvIGVuIHVubyBkZSBsb3MgbWVkaW9zIG3DoXMgcG9wdWxhcmVzIHBhcmEgbGEgZGlmdXNpw7NuIGRlbCBhcnRlLCBjdWx0dXJhIHkgc29icmUgdG9kbyBlbnRyZXRlbmltaWVudG8uIEVzIHBvciBlc28gcXVlIGVuIGVzdGUgdHJhYmFqbyB2YW1vcyBhIG1vc3RyYXIgZGUgdW5hIGZvcm1hIGFsZ28gbcOhcyBkZXRhbGxhZGEgbG9zIGFzcGVjdG9zIG3DoXMgcmVsZXZhbnRlcyBkZWwgY2luZSBlbiBlc3RvcyDDumx0aW1vcyBhw7Fvcy4gUmVjb3JyZXJlbW9zIGEgbG8gbGFyZ28gZGVsIHByb3llY3RvIGxhcyBwZWzDrWN1bGFzIGZhdm9yaXRhcyBwb3IgbGEgYXVkaWVuY2lhLg0KRXNwZXJhbW9zIHF1ZSBlc3RlIHRyYWJham8gb3Mgc2lydmEgcGFyYSBpbmNyZW1lbnRhciB2dWVzdHJhIGN1bHR1cmEgY2luZWFzdGEgeSBvcyBpbmNpdGUgYSB2ZXIgYWxndW5hIGRlIGxhcyBwZWzDrWN1bGFzIG1lbmNpb25hZGFzLg0KDQojICoqMS4tIFBSSU1FUkEgUEFSVEUgKigxMEsgUEVMSUNVTEFTKSoqKg0KDQojIyAxLjEgREFUT1MgQSBBTkFMSVpBUiANCg0KQSBjb250aW51YWNpw7NuLCB2YW1vcyBhIG1vc3RyYXIgdW5hIGxpc3RhIGRlIGxhcyAxMDAwMCBwZWzDrWN1bGFzIGNvbiBsYXMgcXVlIHZhbW9zIGEgdHJhYmFqYXIgaW5pY2lhbG1lbnRlLg0KDQoNCmBgYHtyfQ0KcGVsaWN1bGFzIDwtIHRvcDEwbWlsICU+JQ0Kc2VsZWN0KG9yaWdpbmFsX3RpdGxlKQ0KcmVhY3RhYmxlKHBlbGljdWxhcywgZGVmYXVsdFBhZ2VTaXplID0gIDgsICBwYWdpbmF0aW9uVHlwZSA9ICJqdW1wIiwgc2hvd1BhZ2VTaXplT3B0aW9ucyA9ICBUUlVFICwgcGFnZVNpemVPcHRpb25zID0gIGMgKCAxMCAsIDUwICwgMTAwLCAxNTAsIDIwMCwgMjYwICksZGVmYXVsdENvbERlZiA9IGNvbERlZigNCiAgICBhbGlnbiA9ICJjZW50ZXIiLA0KICAgIG1pbldpZHRoID0gNzAsDQogICAgaGVhZGVyU3R5bGUgPSBsaXN0KGJhY2tncm91bmQgPSAiI0ZGRDcwMCIpLA0KICAgIGZpbHRlcmFibGUgPSBUUlVFKSwgIGhpZ2hsaWdodCA9IFRSVUUsIG91dGxpbmVkID0gVFJVRSwNCiAgICBjb2x1bW5zID0gbGlzdCgNCiAgYEl0ZW1gID0gY29sRGVmKHN0eWxlID0gZnVuY3Rpb24odmFsdWUpIHsNCiAgICBpZiAodmFsdWUgPiAwKSB7DQogICAgICBjb2xvciA8LSAiI0Y1QzcxMCJ9DQogICAgICBlbHNlIHsNCiAgICAgIGNvbG9yIDwtICIjQjIyMjIyIg0KICAgIH0NCiAgICBsaXN0KGNvbG9yID0gY29sb3IsIGZvbnRXZWlnaHQgPSAiYm9sZCIsYmFja2dyb3VuZCA9ICIjQ0QyNjI2IikNCiAgfSkpKQ0KYGBgDQoNCg0KDQoNCg0KDQojIyAxLjIgSURJT01BIEVTVFJFTExBDQoNCkVuIGVzdGUgYXBhcnRhZG8gaGVtb3MgcXVlcmlkbyByZXByZXNlbnRhciBjdWFsIGVzIGVsIGlkaW9tYSBxdWUgcHJlZG9taW5hIGNvbW8gbGVuZ3VhIG9yaWdpbmFsIGVuIGVsIHBhcXVldGUgZGUgZGF0b3MgY29uIGVsIHF1ZSBlc3RhbW9zIHRyYWJhamFuZG8uIENsYXJhbWVudGUsIGRlIGVudHJlIGxhcyBkaWV6IG1pbCBwZWzDrWN1bGFzLCBlbCBpZGlvbWEgZW4gbGEgcXVlIGxhIG1heW9yw61hIGRlIGVsbGFzIGVzdMOhIGVzIGVuIEluZ2zDqXMgKHNpbiBoYWNlciBkaXN0aW5jacOzbiBlbnRyZSBpbmdsw6lzIGJyaXTDoW5pY28gbyBhbWVyaWNhbm8pLg0KDQpgYGB7ciwgd2FybmluZz1GQUxTRX0NCnRvcG1pbF9wYWlzIDwtIHRvcDEwbWlsICU+JQ0KICBncm91cF9ieShvcmlnaW5hbF9sYW5ndWFnZSkgICU+JSAgDQogICBtdXRhdGUobnVtcGVsaXMgPSBzdW0oTk49bigpKSkgJT4lDQogIGRpc3RpbmN0KG9yaWdpbmFsX2xhbmd1YWdlLCBudW1wZWxpcykgJT4lIA0KICBhcnJhbmdlKGRlc2MobnVtcGVsaXMpKSAlPiUgDQogIGZpbHRlcihudW1wZWxpcz4yMDApICU+JSANCiAgbXV0YXRlKGlkaW9tYSA9IGNhc2Vfd2hlbihvcmlnaW5hbF9sYW5ndWFnZSA9PSAiZW4iIH4gIkluZ2zDqXMiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbF9sYW5ndWFnZSA9PSAiamEiIH4gIkphcG9uw6lzIiAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxfbGFuZ3VhZ2UgPT0gImVzIiB+ICJFc3Bhw7FvbCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxfbGFuZ3VhZ2UgPT0gImZyIiB+ICJGcmFuY8OpcyIpKQ0KICANCmdncGxvdCh0b3BtaWxfcGFpcywgYWVzKHggPSBpZGlvbWEsIHkgPSBudW1wZWxpcywgZmlsbCA9IGlkaW9tYSkpICsgIA0KICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygieWVsbG93IiwgIndoaXRlIiwgImJsdWUiLCAicmVkIikgKSArDQogIHNjYWxlX3lfY29udGludW91cyggYnJlYWtzID0gc2VxKDAsIDgwMDAsIDEwMDApLA0KICAgIGxpbWl0cyA9IGMoMCwgODAwMCkpDQogDQpgYGANCg0KDQojIyAxLjMgVE9QIFBFTMONQ1VMQVMNCg0KTGEgc2lndWllbnRlIGdyw6FmaWNhIGVzIHByb2JhYmxlbWVudGUgdW5hIGRlIGxhcyBtw6FzIGludGVyZXNhbnRlcyBkZWwgdHJhYmFqbywgeWEgcXVlIGLDoXNpY2FtZW50ZSBub3MgbXVlc3RyYSBsYXMgNyBwZWzDrWN1bGFzIGNvbiBtw6FzIHBvcHVsYXJpZGFkLiBDb21vIHBvZGVtb3Mgb2JzZXJ2YXIsIGVsIHRvcCAxIGVzICoqVmVub206IExldCBUaGVyZSBCZSBDYXJuYWdlKioNCg0KDQoNCg0KDQpgYGB7ciwgd2FybmluZz1GQUxTRX0NCnBvcHVsYXJpZGFkIDwtIHRvcDEwbWlsICU+JSANCiAgYXJyYW5nZShkZXNjKHBvcHVsYXJpdHkpKSAlPiUgDQogIGZpbHRlcihwb3B1bGFyaXR5ID4gMTMwMCkNCiANCg0KICBnZ3Bsb3QocG9wdWxhcmlkYWQsIGFlcyh4PW9yaWdpbmFsX3RpdGxlLCB5PXBvcHVsYXJpdHkpKSArDQogICAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArDQogICAgY29vcmRfZmxpcCgpICsNCiAgICB4bGFiKCIiKSArDQogICAgdGhlbWVfYncoKSArDQogICAgICBzY2FsZV95X2NvbnRpbnVvdXMoIGJyZWFrcyA9IHNlcSgwLCA1NTAwLCA1MDApLA0KICAgIGxpbWl0cyA9IGMoMCwgNTUwMCkpDQpgYGANCg0KIVtWZW5vbTogTGV0IFRoZXJlIEJlIENhcm5hZ2VdKC4vaW1hZ2VuZXMvdmVub20uanBnKSANCg0KDQojIyAxLjQgTcOBWElNQSBWT1RBQ0nDk04NCg0KQSBjb250aW51YWNpw7NuIG1vc3RyYXJlbW9zIGVuIHVuIGdyw6FmaWNvIGFuaW1hZG8gbGFzIGN1YXRybyBwZWzDrWN1bGFzIGNvbiB1bmEgdm90YWNpw7NuIG3DoXMgZWxldmFkYS4NCg0KDQpgYGB7ciwgd2FybmluZz1GQUxTRX0NCnZvdG9zIDwtIHRvcDEwbWlsICU+JSANCiAgYXJyYW5nZShkZXNjKHZvdGVfYXZlcmFnZSkpICU+JSANCiAgZmlsdGVyKHZvdGVfYXZlcmFnZSA+IDkuMSkgJT4lIA0KICBmaWx0ZXIob3JpZ2luYWxfbGFuZ3VhZ2UgJWluJSBjKCJ6aCIsICJlcyIsICJmciIpKQ0KDQp2b3RvcyRvcmlnaW5hbF90aXRsZSA8LSBpY29udih2b3RvcyRvcmlnaW5hbF90aXRsZSwgZnJvbSA9ICJVVEYtOCIsIHRvID0gIkxBVElOMSIpDQoNCmdndm90b3MgPC0gZ2dwbG90KHZvdG9zLCBhZXMoeCA9IG9yaWdpbmFsX3RpdGxlLCB5ID0gdm90ZV9hdmVyYWdlKSkgKw0KICBnZW9tX3BvaW50KCkgKw0KICBnZW9tX3NlZ21lbnQoIGFlcyh4ID0gb3JpZ2luYWxfdGl0bGUsIHhlbmQgPSBvcmlnaW5hbF90aXRsZSwgeSA9IDAsIHllbmQgPSB2b3RlX2F2ZXJhZ2UpKQ0KDQpnZ3Bsb3RseShnZ3ZvdG9zKQ0KDQpgYGANCg0KDQohW0TDrWFzIGRlIENBTkdSRUJVUkdFUlNdKC4vaW1hZ2VuZXMvYm9iZXNwb25qYTEucG5nKSAhW0Vib2xhIFpvbWJpZXNdKC4vaW1hZ2VuZXMvZWJvbGEuanBnKSANCg0KDQoNCjxociBjbGFzcz0ibGluZWEtcmVkIj4NCg0KIyAqKjIuLSBTRUdVTkRBIFBBUlRFICooNEsgUEVMSUNVTEFTKSoqKg0KDQojIyAyLjEgREFUT1MgQSBBTkFMSVpBUg0KDQpMYSBpZGVhIGFob3JhIGVzIG1vc3RyYXIgYWxndW5vcyBkZSBsb3MgYXBhcnRhZG9zIHZpc3RvcyBhbnRlcmlvcm1lbnRlIHBlcm8gY2FtYmlhbmRvIGVsIHBhcXVldGUgZGUgZGF0b3MgdXNhbmRvIGFob3JhIHVubyBjb24gbWVub3MgcGVsw61jdWxhcyB5IGFsZ28gbcOhcyByZWNpZW50ZXMuDQoNCk1vc3RyYW1vcyBhIGNvbnRpdWFjacOzbiBwdWVzLCBsb3MgZGF0b3MgY29uIGxvcyBxdWUgdmFtb3MgYSB0cmFiYWphciBhaG9yYS4NCg0KYGBge3J9DQpuYW1lcyh0b3A0bWlsKVtuYW1lcyh0b3A0bWlsKSA9PSAnTW92aWUgVGl0bGUnXSA8LSAnbW92aWV0aXRsZScNCg0KDQoNCnBlbGljdWxhczQgPC0gdG9wNG1pbCAlPiUNCnNlbGVjdChtb3ZpZXRpdGxlKQ0KcmVhY3RhYmxlKHBlbGljdWxhczQsIGRlZmF1bHRQYWdlU2l6ZSA9ICA4LCAgcGFnaW5hdGlvblR5cGUgPSAianVtcCIsIHNob3dQYWdlU2l6ZU9wdGlvbnMgPSAgVFJVRSAsIHBhZ2VTaXplT3B0aW9ucyA9ICBjICggMTAgLCA1MCAsIDEwMCwgMTUwLCAyMDAsIDI2MCApLGRlZmF1bHRDb2xEZWYgPSBjb2xEZWYoDQogICAgYWxpZ24gPSAiY2VudGVyIiwNCiAgICBtaW5XaWR0aCA9IDcwLA0KICAgIGhlYWRlclN0eWxlID0gbGlzdChiYWNrZ3JvdW5kID0gIiNGRkQ3MDAiKSwNCiAgICBmaWx0ZXJhYmxlID0gVFJVRSksICBoaWdobGlnaHQgPSBUUlVFLCBvdXRsaW5lZCA9IFRSVUUsDQogICAgY29sdW1ucyA9IGxpc3QoDQogIGBJdGVtYCA9IGNvbERlZihzdHlsZSA9IGZ1bmN0aW9uKHZhbHVlKSB7DQogICAgaWYgKHZhbHVlID4gMCkgew0KICAgICAgY29sb3IgPC0gIiNGNUM3MTAifQ0KICAgICAgZWxzZSB7DQogICAgICBjb2xvciA8LSAiI0IyMjIyMiINCiAgICB9DQogICAgbGlzdChjb2xvciA9IGNvbG9yLCBmb250V2VpZ2h0ID0gImJvbGQiLGJhY2tncm91bmQgPSAiI0NEMjYyNiIpDQogIH0pKSkNCg0KYGBgDQoNCg0KIyMgMi4yIE1BWU9SIFBJQiBET03DiVNUSUNPDQoNCkVuIGVzdGUgb3RybyBwdW50byBvcmRlbmFtb3MgbGFzIHBlbMOtY3VsYXMgZGUgZm9ybWEgZGVzY2VuZGVudGUsIGxhcyBwZWzDrWN1bGFzIHF1ZSBoYW4gZ2VuZXJhZG8gbWF5b3IgUElCIG5hY2lvbmFsLg0KDQoNCmBgYHtyfQ0KbmFtZXModG9wNG1pbClbbmFtZXModG9wNG1pbCkgPT0gJ0RvbWVzdGljIEdyb3NzJ10gPC0gJ2RvbWVzdGljUElCJw0KDQpQSUIgPC0gdG9wNG1pbCAlPiUgDQogIGFycmFuZ2UoZGVzYyhkb21lc3RpY1BJQikpICU+JSANCiAgZmlsdGVyKGRvbWVzdGljUElCID4gNTQzNjM4MDQyKQ0KIA0KDQogIGdncGxvdChQSUIsIGFlcyh4PW1vdmlldGl0bGUsIHk9ZG9tZXN0aWNQSUIpKSArDQogICAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArDQogICAgY29vcmRfZmxpcCgpICsNCiAgICB4bGFiKCIiKSArDQogICAgdGhlbWVfYncoKSArDQogICAgICBzY2FsZV95X2NvbnRpbnVvdXMoIGJyZWFrcyA9IHNlcSgwLCA4MDAwMCwgODU4MzczMDAwKSwNCiAgICBsaW1pdHMgPSBjKDAsIDg1ODM3MzAwMDApKQ0KDQpgYGANCg0KDQoNCg0KDQpDb21vIHZlbW9zIGVuIGVsIGdyw6FmaWNvLCBsYSBwZWxpY3VsYSBxdWUgbcOhcyBoYSBhcG9ydGFkbyBhbCBQSUIgZG9tw6lzdGljbyBoYSBzaWRvICoqU3RhciBXYXJzIEVwLiBWSUk6IFRoZSBGb3JjZSBBd2FrZW5zKioNCg0KIVtTdGFyIFdhcnMgRXAuIFZJSTogVGhlIEZvcmNlIEF3YWtlbnNdKC4vaW1hZ2VuZXMvc3RhcndhcnMxLmpwZykgICAgDQoNCg0KIyMgMi4zIE1BWU9SIFBJQiBNVU5ESUFMDQoNCk11eSBwYXJlY2lkbyBhbCBhcGFydGFkbyBhbnRlcmlvciwgYWhvcmEgbGFzIGRpc3Rpbmd1aW1vcyBwZXJvIG1lZGlhbnRlIGxhIGFwb3J0YWNpw7NuIGFsIFBJQiBtdW5kaWFsLg0KDQpgYGB7cn0NCm5hbWVzKHRvcDRtaWwpW25hbWVzKHRvcDRtaWwpID09ICdXb3JsZHdpZGUgR3Jvc3MnXSA8LSAnUElCJw0KDQpQSUIgPC0gdG9wNG1pbCAlPiUgDQogIGFycmFuZ2UoZGVzYyhQSUIpKSAlPiUgDQogIGZpbHRlcihQSUIgPiAJMTY1NDM2NzQyNSkNCiANCg0KICBnZ3Bsb3QoUElCLCBhZXMoeD1tb3ZpZXRpdGxlLCB5PVBJQikpICsNCiAgICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsNCiAgICBjb29yZF9mbGlwKCkgKw0KICAgIHhsYWIoIiIpICsNCiAgICB0aGVtZV9idygpICsNCiAgICAgIHNjYWxlX3lfY29udGludW91cyggYnJlYWtzID0gc2VxKDAsIDQyOTE4NjUwMCwgODU4MzczMDAwKSwNCiAgICBsaW1pdHMgPSBjKDAsIDg1ODM3MzAwMDApKQ0KDQoNCmBgYA0KDQoNCg0KDQpFbiBlc3RlIG90cm8gZ3LDoWZpY28gcG9kZW1vcyBvYnNlcnZhciBxdWUgbGFzIHBlbMOtY3VsYXMgcXVlIG3DoXMgUElCIG11bmRpYWwgaGFuIGFwb3J0YWRvIGhhbiBzaWRvLCAqKkF2YXRhcioqIHkgKipBdmVuZ2VyczogRW5kZ2FtZSoqLCBjb24gbsO6bWVyb3MgYmFzdGFudGUgc2ltaWxhcmVzLg0KDQohW0F2YXRhcl0oLi9pbWFnZW5lcy9hdmF0YXIxLmpwZykgIVtBdmVuZ2VyczogRW5kZ2FtZV0oLi9pbWFnZW5lcy9hdmVuZ2Vycy5qcGcpDQoNCg0KDQojICoqMy4tIFRFUkNFUkEgUEFSVEUgKiggTcOBUyBQRUxJUykqKioNCg0KDQojIyAzLjEgREFUT1MgQSBBTkFMSVpBUg0KDQpDYW1iaWFtb3MgYWhvcmEgb3RyYSB2ZXogZWwgY29uanVudG8gZGUgZGF0b3MgY29uIGVsIHF1ZSB2YW1vcyBhIHRyYWJhamFyIHkgZGlzbWludWltb3MgZWwgcGFxdWV0ZSBhIHRhbiBzb2xvIDExOCBwZWzDrWN1bGFzLiBQYXNhcmVtb3MgYSBhbmFsaXphciBvdHJvcyBhc3BlY3RvcyBkaXN0aW50b3MgZGUgbG9zIGFudGVyaW9yZXMuDQoNCg0KYGBge3J9DQpwZWxpY3VsYXMgPC0gbWFzcGVsaXMgJT4lDQpzZWxlY3QoVGl0bGUpDQpyZWFjdGFibGUocGVsaWN1bGFzLCBkZWZhdWx0UGFnZVNpemUgPSAgOCwgIHBhZ2luYXRpb25UeXBlID0gImp1bXAiLCBzaG93UGFnZVNpemVPcHRpb25zID0gIFRSVUUgLCBwYWdlU2l6ZU9wdGlvbnMgPSAgYyAoIDEwICwgNTAgLCAxMDAsIDE1MCwgMjAwLCAyNjAgKSxkZWZhdWx0Q29sRGVmID0gY29sRGVmKA0KICAgIGFsaWduID0gImNlbnRlciIsDQogICAgbWluV2lkdGggPSA3MCwNCiAgICBoZWFkZXJTdHlsZSA9IGxpc3QoYmFja2dyb3VuZCA9ICIjRkZENzAwIiksDQogICAgZmlsdGVyYWJsZSA9IFRSVUUpLCAgaGlnaGxpZ2h0ID0gVFJVRSwgb3V0bGluZWQgPSBUUlVFLA0KICAgIGNvbHVtbnMgPSBsaXN0KA0KICBgSXRlbWAgPSBjb2xEZWYoc3R5bGUgPSBmdW5jdGlvbih2YWx1ZSkgew0KICAgIGlmICh2YWx1ZSA+IDApIHsNCiAgICAgIGNvbG9yIDwtICIjRjVDNzEwIn0NCiAgICAgIGVsc2Ugew0KICAgICAgY29sb3IgPC0gIiNCMjIyMjIiDQogICAgfQ0KICAgIGxpc3QoY29sb3IgPSBjb2xvciwgZm9udFdlaWdodCA9ICJib2xkIixiYWNrZ3JvdW5kID0gIiNDRDI2MjYiKQ0KICB9KSkpDQpgYGANCg0KIyMgMy4yIEfDiU5FUk8gREUgTEFTIFBFTMONQ1VMQVMNCg0KYGBge3J9DQpjYXRlZ29yaWFzIDwtIG1hc3BlbGlzICU+JQ0KICBncm91cF9ieShHZW5yZTEpICAlPiUgIA0KICAgbXV0YXRlKG51bWVyb3hnZW5lcm8gPSBzdW0oTk49bigpKSkgJT4lDQogIGRpc3RpbmN0KEdlbnJlMSwgbnVtZXJveGdlbmVybykgJT4lIA0KICBhcnJhbmdlKGRlc2MobnVtZXJveGdlbmVybykpICANCg0KICANCmdncGxvdChjYXRlZ29yaWFzLCBhZXMoeCA9IEdlbnJlMSwgeSA9IG51bWVyb3hnZW5lcm8sIGZpbGwgPSBHZW5yZTEpKSArICANCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoInBpbmsiLCAiYmxhY2siLCAicHVycGxlIiwgInJlZCIsICJ5ZWxsb3ciLCAiZ3JlZW4iLCAiYnJvd24iLCAiZ3JleSIpICkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIGJyZWFrcyA9IHNlcSgwLCAyOSwgNiksDQogICAgbGltaXRzID0gYygwLCAyOSkpDQoNCmBgYA0KDQpIZW1vcyBxdWVyaWRvIHJlcHJlc2VudGFyIGNvbiBlc3RlIGdyw6FmaWNvIHRhbiBjb2xvcmlkbywgbG9zIGfDqW5lcm9zIGRlIGxhcyBwZWzDrWN1bGFzLiBQb2Ryw61hbW9zIGRlY2lyIHF1ZSBoYXkgbXVjaGFzIG3DoXMgcGVsw61jdWxhcyBkZSBhY2Npw7NuIHkgZHJhbWEgcXVlIGRlIGxvcyBvdHJvcyBnw6luZXJvcy4gRXMgY2llcnRvIHF1ZSBlcyBhcXXDrSBlbiBlc3RlIGNvbmp1bnRvIGRlIGRhdG9zIHF1ZSBzZSBkYSBhc8OtLCBwZXJvIHNpIGNvZ2nDqXNlbW9zIHRvZGFzIGxhcyBwZWzDrWN1bGFzIHF1ZSBleGlzdGVuLCBsYXMgcHJvcG9yY2lvbmVzIHNlcsOtYW4gcGFyZWNpZGFzIHlhIHF1ZSBzb24gbG9zIGfDqW5lcm9zIHF1ZSBtw6FzIHZlbmRlbiB5IG3DoXMgZ3VzdGFuIGEgbGEgbWF5b3LDrWEgZGUgbGEgcG9ibGFjacOzbi4NCg0KIyMgMy4zIERVUkFDScOTTiBQRUzDjUNVTEFTDQoNCmBgYHtyfQ0KZHVyYXRpb24gPC0gbWFzcGVsaXMgJT4lDQogIGdyb3VwX2J5KFJ1bnRpbWUpICU+JQ0KICBtdXRhdGUoc2FtZWR1cmF0aW9uID0gc3VtKE5OPW4oKSkpICU+JQ0KICBkaXN0aW5jdChSdW50aW1lLCBzYW1lZHVyYXRpb24sIFRpdGxlKSAlPiUNCiAgZmlsdGVyKFJ1bnRpbWUgPjApICU+JQ0KICBmaWx0ZXIoUnVudGltZSA+IDE2NikgJT4lDQogIGZpbHRlcihSdW50aW1lIDwgOSkgJT4lDQogIGFycmFuZ2UoZGVzYyhSdW50aW1lKSkgDQogDQoNCg0KDQoNCg0KDQpncmFmZHVyYXRpb24gPC0gZ2dwbG90IChkdXJhdGlvbiwgYWVzKHggPSBUaXRsZSwgeSA9IFJ1bnRpbWUpKSArIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gInN0ZWVsYmx1ZSIpDQpncmFmZHVyYXRpb24gKyBsYWJzKHRpdGxlID0gIkdyw6FmaWNvOiBEdXJhY2nDs24gZGUgbGFzIHBlbMOtY3VsYXMiLA0KICAgICAgIHN1YnRpdGxlID0gIihkaWZlcmVuY2lhbmRvIHBvciBhw7FvKSIsDQogICAgICAgeCA9ICJQZWzDrWN1bGFzIiwNCiAgICAgICB5ID0gIkR1cmFjacOzbiIsDQogICAgICAgY29sb3IgPSAiRXNwZWNpZSBkZSBsaXJpbyIpDQogIA0KICANCg0KYGBgDQoNCkEgdHJhdsOpcyBkZSBlc3RlIGdyw6FmaWNvIHZlbW9zIGxhcyBwZWzDrWN1bGFzIHF1ZSBtw6FzIGR1cmFuLiBFbiBlc3RlIHRvcCAzIGVzdMOhbjoNCi0gSW50ZXJzdGVsbGFyICoodW4gcGVsaWN1bMOzbiwgdmFsZSBsYSBwZW5hIGxhIGR1cmFjacOzbikqDQotIEVsIGhvYmJpdCAqKHBhcmEgZ3VzdG9zIGNvbG9yZXMgeW8gbm8gbGEgaGUgdmlzdG8pKg0KLSAqKkVsIGxvYm8gZGUgV2FsbCBTdHJlZXQqKiwgYmFzdGFudGUgY29ub2NpZGEgeSBmYW1vc2EsIGNvbiB1bmEgZHVyYWNpw7NuIGRlIDNob3Jhcy4NCg0KIVtUaGUgV29sZiBvZiBXYWxsIFN0cmVldF0oLi9pbWFnZW5lcy9sb2JvLmpwZykNCg0KDQoNCiMgKio0Li0gQ1VBUlRBIFBBUlRFICooIEHDmk4gTcOBUyBQRUxJUykqKioNCg0KQ29uIGVzdGUgY3VhcnRvIHkgw7psdGltbyBwYXF1ZXRlIGRlIGRhdG9zIHF1ZSB2YW1vcyBhIHV0aWxpemFyIGVuIGVzdGUgdHJhYmFqbywgdmFtb3MgYSBtb3N0cmFyIGxhIHJlY2F1ZGFjacOzbiBicnV0YSBkZSBsYXMgcGVsw61jdWxhcyBlbiBsb3MgRXN0YWRvcyBVbmlkb3MuDQoNCg0KYGBge3J9DQpyZWNhdWQgPC0gYXVubWFzcGVsaXMgJT4lDQogIHNlbGVjdChtb3ZpZV9uYW1lLCB1c19ncm9zc01pbGxpb25zKSAlPiUNCiAgaGVhZCh1c19ncm9zc01pbGxpb25zLCBuID0gMTApJT4lDQogIGdyb3VwX2J5KG1vdmllX25hbWUsIHVzX2dyb3NzTWlsbGlvbnMpICU+JQ0KICBhcnJhbmdlKGRlc2ModXNfZ3Jvc3NNaWxsaW9ucykpDQoNCnJlY2F1ZA0KDQoNCndvcmRjbG91ZDIoZGF0YT1yZWNhdWQsIHNpemU9MC4zNSkNCg0KDQpgYGANCg0KRW4gZXN0ZSBncsOhZmljbyBpbnRlcmFjdGl2byBzZSBtdWVzdHJhbiBsYXMgcGVsw61jdWxhcyBjb24gbcOhcyByZWNhdWRhY2nDs24gY29uIHVuIHRhbWHDsW8gbcOhcyBncmFuZGUgeSBhIG1lZGlkYSBxdWUgbG9zIHTDrXR1bG9zIHNlIGhhY2VuIG3DoXMgcGVxdWXDsW9zIHNpZ25pZmljYSBxdWUgbGEgcmVjYXVkYWNpw7NuIGVzIG1lbm9yLiBTaSBtYW50ZW5lbW9zIGVsIGN1cnNvciBlbmNpbWEgZGUgbG9zIHTDrXR1bG9zIGRlIGxhcyBwZWzDrWN1bGFzIG5vcyBkaWNlIGV4YWN0YW1lbnRlIGVsIGltcG9ydGUgZGUgbGEgcmVjYXVkYWNpw7NuIGJydXRhLiBEZXN0YWNhcsOtYW1vcyBzaW4gZHVkYSAqKkF2ZW5nZXJzOiBFbmQgR2FtZSoqIHkgc2VndWlkYW1lbnRlICoqSm9rZXIqKi4NCg0KDQoNCg0KDQoNCg0KDQojICBCSUJMSU9HUkFGw41BDQoNCg0KDQoNCi0gW0VubGFjZSBhIGxhIHDDoWdpbmEgd2ViIGRlIGxhIGFzaWduYXR1cmFdKGh0dHBzOi8vcGVyZXpwNDQuZ2l0aHViLmlvL2ludHJvLWRzLTIxLTIyLXdlYi9pbmRleC5odG1sKQ0KDQotIFtFbmxhY2UgZ2FsZXJpYSBkZSBncsOhZmljb3MgZGUgZ2dwbG90Ml0oaHR0cHM6Ly93d3cuci1ncmFwaC1nYWxsZXJ5LmNvbS8pDQoNCi0gW1R1dG9yaWFsZXMgZGUgbGEgYXNpZ25hdHVyYV0oaHR0cHM6Ly9wZXJlenA0NC5naXRodWIuaW8vaW50cm8tZHMtMjEtMjItd2ViLzA0LXR1dG9yaWFsZXMuaHRtbCkNCg0KLSBbRW5sYWNlIGEgbGEgcMOhZ2luYSB3ZWIgZGUgZ2dhbmltYXRlXShodHRwczovL2dnYW5pbWF0ZS5jb20vKQ0KDQo=