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í.


I. Introducción

En este trabajo haremos un estudio sobre la producción de alcachofas en Europa y España.

Explorando la base de datos de Eurostat di con unos datos completos y detallados de la producción agrícola en Europa, de modo que me decanté por ellos. La elección de este tema ha sido motivada por la disponibilidad de un dataset lo suficientemente detallado, además de que me gustan las alcachofas.

Opté por centrarme en un solo producto, que han sido las alcachofas. Aunque los datos llegan hasta 2020 hay muchos paises que no tienen datos para ese año, por lo que he optado por considerar 2019 como el año más reciente.

II. Datos

El estudio se realiza con unos datos de producción agrícola de la base de datos Eurostat.

A continuación podemos ver el proceso de obtención y limpieza de los datos, que acaba con un archivo definivo a partir del cual se han elaborado los contenidos.

1. Obtención y limpieza

El estudio se realiza con unos datos de producción agrícola de la base de datos Eurostat.

A continuación podemos ver el proceso de obtención y limpieza de los datos, que acaba con un archivo definivo a partir del cual se han elaborado los contenidos.

Exploración de datos

# Función resumidora del profesor
zz <- pjpv2020.01::pjp_f_unique_values(df_5, truncate = TRUE, nn_truncate = 47) 


# Crop production in EU standard humidity (apro_cpsh1)  
df1 <- get_eurostat("apro_cpsh1", time_format = 'raw', keepFlags = T )
df_1 <- label_eurostat(df1) 

df1 <- label_eurostat(df1, code= c("crops", "strucpro", "geo") )
df1 <- df1 %>% filter (crops == 'Artichokes') %>%
  mutate(values = ifelse(is.na(values), 0, values))


rio::export(df, "./datos/Produccion_agri.xlsx")
rio::export(df_1, "./datos/Produccion_agri_lab.xlsx")

# Unit values at basic prices (aact_uv01)   
df2 <- get_eurostat("aact_uv01", time_format = 'raw', keepFlags = T)
df_2 <- label_eurostat(df2)

df2 <- label_eurostat(df2, code = c("itm_newa", "geo", "unit"))
df2 <- df2 %>% filter (itm_newa == 'ARTICHOKES') %>% filter (unit == 'Euro per tonne')


# Unit values quantities (en miles de t) (aact_uv03)    
df3 <- get_eurostat("aact_uv03", time_format = 'raw', keepFlags = T)
df_3 <- label_eurostat(df3)

df3 <- label_eurostat(df3, code = c("itm_newa", "geo"))
df3 <- df3 %>% filter (itm_newa == 'ARTICHOKES') %>%
  rename ( uds_prod_1000t = values)


# Dataframe conjunto df2 y df3
df4 <- full_join(df2, df3, by = c("geo_code", "time")) 
df4 <- df4 %>% select (geo_code, unit, geo.x, itm_newa.x, time, values, uds_prod_1000t)

Limpieza de los datos definitivos

# Función resumidora del profesor
zz <- pjpv2020.01::pjp_f_unique_values(df1, truncate = TRUE, nn_truncate = 47) 

# Crop production in EU standard humidity (1000 t) (apro_cpsh1) 
df1 <- get_eurostat("apro_cpsh1", time_format = 'raw', keepFlags = T )
df_1 <- label_eurostat(df1) 

dffull <- label_eurostat(df1, code= c("crops", "strucpro", "geo") )

df1 <- dffull %>% filter (crops == 'Artichokes') %>%
  mutate(values = ifelse(is.na(values), 0, values)) %>%
  select(strucpro_code, geo_code, crops, strucpro, geo, time, values)

# Crop production - historical data (1955-1999) (apro_cpnh1_h)   
df2 <- get_eurostat("apro_cpnh1_h", time_format = 'raw', keepFlags = T )
df_2 <- label_eurostat(df2) 

dffull2 <- label_eurostat(df2, code= c("crops", "strucpro", "geo"))
df2 <- dffull2 %>% filter (crops == 'Artichokes') %>%
  mutate(values = ifelse(is.na(values), 0, values)) %>%
  select(strucpro_code, geo_code, crops, strucpro, geo, time, values)

# Juntamos los dataframes, asumiendo que la producción en estándar de humedad de la UE es el mismo que el histórico
dftodo <- full_join(dffull, dffull2)
dftodored <- full_join(df1, df2)

dfbueno <- dftodored

# Cambiamos algunos valores
dfbueno$strucpro_code[dfbueno$strucpro_code == "PR_HU_EU"] <- "PR"
dfbueno$strucpro[dfbueno$strucpro == "Harvested production in EU standard humidity (1000 t)"] <- "Harvested production (1000 t)"

rio::export(dfbueno, './datos/alcachofas.csv')
rio::export(dftodo, './datos/produccionext.csv')
rio::export(dftodored, './datos/produccion.csv')

rm(df_1, df_2, df1, df2, dffull, dffull2, dftodo, dftodored, dfbueno)

datos <- rio::import ('./datos/alcachofas.csv')

#- Descargamos geometrías de Europa
geometrias <- get_eurostat_geospatial(resolution = "20", nuts_level = "0")
plot(geometrias, max.plot = 1)

mapdata <- full_join(datos, geometrias, by = c("geo_code" = "id"))

2. Tabla de datos

AR representa los valores para área cultivada en miles de hectáreas, y PR representa la producción en miles de toneladas.

datos <- rio::import ('./datos/alcachofas.csv') %>% select(!c(strucpro, crops))
datos$geo[datos$geo_code == "DE"] <- "Germany"
datos$geo[datos$geo_code == "XK"] <- "Kosovo"

DT::datatable(datos)

III. Estudios realizados

1. Área dedicada al cultivo de alcachofas

Mapa de área cultivada

Como podemos observar en el siguiente mapa, los paises que dedican una mayor área al cultivo de alcachofas en Europa son Italia y España, con un área dedicada de entre 11 y 20, y de más de 20 miles de hectáreas respectivamente.

Los siguientes paises que encontramos son Francia, Turquía y Malta, que dedican una área de entre 1000 y 10000 hectáreas al cultivo de alcachofas.
El resto de paises o bien no cultivan, o bien dedican menos de mil hectáreas a producir alcachofas, por lo que consideramos su contribución como insignificante.

Código

# Cargamos datos y geometrías
datos <- rio::import ('./datos/alcachofas.csv')
datos19 <- datos %>% filter(time == '2019', strucpro_code == 'AR')

geometrias <- get_eurostat_geospatial(resolution = "20", nuts_level = "0")
mapdata <- full_join(datos, geometrias, by = c("geo_code" = "id"))

ha_19 <- mapdata %>% filter (strucpro_code == 'AR', time == '2019')

#- Creamos grupos según los valores para que poder mostrarlos en el mapa. He tenido que convertirlos en enteros porque no conseguía que leyera los números con decimales
ha_19 <- ha_19 %>% mutate (values = as.integer(values)) %>%
  mutate(grupos  = case_when( 
  values %in% (-1:0) ~ "0-1",
  values %in% (0:10) ~ "1-10",
  values %in% (10:20) ~ "11-20",
  values %in% (21:100) ~ '20 o más'))
  
# Mapa area cultivada en 2019 
p <- ggplot(ha_19) +
     geom_sf(aes(fill= grupos, geometry = geometry), color = "black", size = .1) +
     scale_fill_brewer(palette = "RdYlBu")  +
     labs(title = "Área dedicada al cultivo de alcachofas en 2019",
       subtitle = "En miles de hectáreas",
       fill = "Miles de Ha",
       caption = "(C) EuroGeographics for the administrative boundaries") + 
     theme_light() + coord_sf(xlim = c(-20,43), ylim = c(34,67))

p

2. Producción de alcachofas en 2019

Mapa de producción

Este mapa nos muestra la producción de alcachofas en Europa en 2019.

Rápidamente podemos ver que España e Italia son los principales producctores, seguidos por Turquía, Francia y Grecia, aunque estos en mucha menor medida.
El resto de paises o bien no producen o su producción es insignificante a escala Europea.

Producción de alcachofas en Europa
Cantidades producidas en 2019
País Cantidad producida (miles de t)
Italia 378
España 199
Turquía 39
Francia 38
Grecia 15
(C) EuroGeographics for the administrative boundaries

Código

# Cargamos datos y geometrías
datos <- rio::import ('./datos/alcachofas.csv')
datos19 <- datos %>% filter(time == '2019', strucpro_code == 'PR') %>% mutate (values = as.integer(values))

geometrias <- get_eurostat_geospatial(resolution = "20", nuts_level = "0")

mapdata <- full_join(datos, geometrias, by = c("geo_code" = "id"))

pr_19 <- mapdata %>% filter (strucpro_code == 'PR', time == '2019')

#- Creamos grupos según los valores para que poder mostrarlos en el mapa. He tenido que convertirlos en enteros porque no conseguía que leyera los números con decimales
pr_19 <- pr_19 %>% mutate (values = as.integer(values)) %>%
  mutate(grupos  = case_when( 
  values %in% (0) ~ "0",
  values %in% (1:100) ~ "1-100",
  values %in% (101:200) ~ "101-200",
  values %in% (201:1000) ~ '200 o más'))
  
# Mapa area cultivada en 2019 
p <- ggplot(pr_19) +
     geom_sf(aes(fill= grupos, geometry = geometry), color = "black", size = .1) +
     scale_fill_brewer(palette = "BrBG")  +
     labs(title = "Producción de alcachofas en 2019",
       subtitle = "En miles de toneladas",
       fill = "Miles de t",
       caption = "(C) EuroGeographics for the administrative boundaries") + theme_light() +
     coord_sf(xlim = c(-20,43), ylim = c(34,67))

p
# Tabla mayores productores

italy <- './imagenes/it'
spain <- './imagenes/es'
turkey <- './imagenes/tr'
france <- './imagenes/fr'
greece <- './imagenes/gr'
banderas <- c(italy, spain, turkey, france, greece)


tabla19 <- datos19 %>% filter (values < 600) %>% select (geo, values)  %>% 
  slice_max (values, n = 5) %>% arrange ( desc(values)) %>% mutate(values= as.numeric(values)) %>%
  rename('País' = geo, 'Cantidad producida (miles de t)' = values)

tabla19$País[tabla19$País == "Italy"] <- "Italia"
tabla19$País[tabla19$País == "Spain"] <- "España"
tabla19$País[tabla19$País == "Turkey"] <- "Turquía"
tabla19$País[tabla19$País == "France"] <- "Francia"
tabla19$País[tabla19$País == "Greece"] <- "Grecia"

# No he podido hacer funcionar las banderas
# add_column(banderas, .before = 'geo') %>% 

tabla19 %>% gt() %>%
  tab_header(title = md("**Producción de alcachofas en Europa**"),  
            subtitle = md("Cantidades producidas en 2019"))%>%
  tab_source_note(md("(C) EuroGeographics for the administrative boundaries")) %>% 
  tab_options(heading.background.color = "darkred", column_labels.font.weight = "bold")

3. Producción histórica acumulada

Wordcloud

Este Wordcloud nos da una primera impresión rápida de la escala de los números de producción histórica.
Como podemos ver España e Italia son prácticamente los únicos productores, seguidos de Francia con una producción mucho menor.

Mapa de producción acumulada

En esta sección hay que tener en cuenta que algunos países, como Turquía que tenía más producción en la sección anterior, no tienen datos que lleguen hasta 1964.
Sin embargo, la gran escala de producción de Italia y España no deja lugar a dudas de que son los mayores productores de alcachofas de Europa, tanto históricamente como en la actualidad.

Producción acumulada de alcachofas en Europa
Cantidades producidas entre 1964 y 2019
País Cantidad producida (miles de t)
Italia 28028.17
España 14233.41
Francia 4316.29
Turquía 605.30
Grecia 432.19
(C) EuroGeographics for the administrative boundaries

Código

# Cargamos datos y geometrías
datos <- rio::import ('./datos/alcachofas.csv')
datoscum <- datos %>% filter(strucpro_code == 'PR') %>% select(geo_code, geo, time, values) %>%
  group_by(geo_code) %>% arrange(time) %>% mutate(acum = cumsum(values)) %>% ungroup() %>%
  mutate (acum = as.numeric(acum))


# wordcloud
datosfin <- datoscum %>% filter (time == "2019") %>% select (geo, acum)

wordcloud2(datosfin)

# mapa

geometrias <- get_eurostat_geospatial(resolution = "20", nuts_level = "0")
mapdata <- full_join(datoscum, geometrias, by = c("geo_code" = "id"))

pr_acum <- mapdata %>% filter (time == '2019') %>% filter (geo_code != 'EU', geo_code != 'EU27_2020', geo_code != 'EU28') %>%
  mutate(acum= as.numeric(acum))

pr_acum <- pr_acum %>% mutate (acum = as.integer(acum)) %>%
  mutate(grupos  = case_when( 
  acum %in% (0) ~ "0",
  acum %in% (1:100) ~ "1 a 100",
  acum %in% (101:1000) ~ "100 a 1000",
  acum %in% (1001:10000) ~ '1000 a 10000',
  acum %in% (10001:100000) ~ '10000 o más'  ))

p <- ggplot(pr_acum) +
     geom_sf(aes(fill= grupos, geometry = geometry), color = "black", size = .1) +
     scale_fill_brewer(palette = "PuOr")  +
     labs(title = "Producción de alcachofas histórica acumulada",
       subtitle = "Datos desde 1964 hasta 2019",
       fill = "Miles de t",
       caption = "(C) EuroGeographics for the administrative boundaries") + theme_light() +
     coord_sf(xlim = c(-20,43), ylim = c(34,67))
p
# Tabla mayores productores acumulado

tabla_acum <- datoscum %>% filter (geo_code != 'EU', geo_code != 'EU27_2020', geo_code != 'EU28', time == '2019') %>% 
  select (geo, acum)  %>% 
  slice_max (acum, n = 5) %>% arrange ( desc(acum)) %>% 
  rename('País' = geo, 'Cantidad producida (miles de t)' = acum)

tabla_acum$País[tabla_acum$País == "Italy"] <- "Italia"
tabla_acum$País[tabla_acum$País == "Spain"] <- "España"
tabla_acum$País[tabla_acum$País == "Turkey"] <- "Turquía"
tabla_acum$País[tabla_acum$País == "France"] <- "Francia"
tabla_acum$País[tabla_acum$País == "Greece"] <- "Grecia"

  
tabla_acum %>% gt() %>%
  tab_header(title = md("**Producción acumulada de alcachofas en Europa**"),  
            subtitle = md("Cantidades producidas entre 1964 y 2019"))%>%
  tab_source_note(md("(C) EuroGeographics for the administrative boundaries")) %>% 
  tab_options(heading.background.color = "darkred", column_labels.font.weight = "bold")

4. Producción en España

Área

Como podemos ver representada por la linea amarilla, el área utilizada en España para el cultivo de alachofas fue subiendo hasta 1990, donde alcanzó un pico de aproximandamente 32.000 hectáreas.

Actualmente el área utilizada ronda las 15.000 hectáreas.

La linea verde representa la producción de alcachofas por hectárea, siendo la producción en toneladas de alcachofas. Esta linea también la podemos encontrar en el siguiente gráfico.

Producción

En concordancia con el área utilizada, la producción de alcachofas en España también alcanzo un pico en los años 90, produciendo 440.000 toneladas de alcachofas.
Los datos más recientes (2019) muestran una producción de 199.000 toneladas de alcachofas, menos de la mitad que las producidas en el pico de producción, pero todavía siendo una cantidad muy respetable, solo superada por Italia.

La linea verde representa la producción de alcachofas por hectárea, siendo la producción en toneladas de alcachofas.

Producción acumulada

La producción histórica acumulada ha ido en un ascenso continuo hasta hoy.
Con los datos más recientes podemos ver que España ha producido 14.233.000 toneladas de alcachofas desde 1964, una cifra bastante impresionante y solo superada por Italia.

Código

# Cargamos datos y geometrías
datos <- rio::import ('./datos/alcachofas.csv')

pr_esp <- datos %>% filter(strucpro_code == 'PR', geo_code == 'ES') %>% select(geo_code, geo, time, values) %>%
  group_by(geo_code) %>% arrange(time) %>% mutate(acum = cumsum(values)) %>% ungroup() %>%
  mutate (acum = as.numeric(acum)) %>% rename(prod = values, prsum = acum)

ar_esp <- datos %>% filter(strucpro_code == 'AR', geo_code == 'ES') %>% select(geo_code, geo, time, values) %>%
  group_by(geo_code) %>% arrange(time) %>% rename (area = values)

esp <- full_join(pr_esp, ar_esp)
esp <- esp %>% mutate (prodxha = prod/area)


#- Gráfico área
p1 <- ggplot(esp) +
      geom_line(aes(x = time, y = area), alpha = 0.7, size = 1.7, color = "yellow") +
      geom_line(aes(x = time, y = prodxha), alpha = 0.7, size = 1.7, color = "green") +
      scale_color_viridis_d() +
     labs(x = "Año", 
       y = "Área utilizada (miles de Ha)",
       title= 'Área dedicacada al cultivo de alcachofas en {frame_along}', 
       subtitle = 'Datos de 1964 a 2019', 
       caption = '(C) EuroGeographics for the administrative boundaries') + 
     transition_reveal(time)

p1

#- Gráfico producción anual
p2 <- ggplot(esp) +
      geom_line(aes(x = time, y = prod), alpha = 0.7, size = 1.7, color = "red") +
      scale_color_viridis_d() +
     labs(x = "Año", 
       y = "Producción (miles de t)",
       title= 'Producción de alcachofas en España en {frame_along}', 
       subtitle = 'Datos de 1964 a 2019', 
       caption = '(C) EuroGeographics for the administrative boundaries') + 
     transition_reveal(time)
p2 


#- Gráfico producción acumulada
p3 <- ggplot(esp) +
      geom_line(aes(x = time, y = prsum), alpha = 0.7, size = 1.7, color = "blue") +
      scale_color_viridis_d() +
     labs(x = "Año", 
       y = "Producción (miles de t)",
       title= 'Producción acumulada en España en {frame_along}', 
       subtitle = 'Datos de 1964 a 2019', 
       caption = '(C) EuroGeographics for the administrative boundaries') + 
      transition_reveal(time)

p3


# Gráfico interactivo todo -> Este gráfico se muestra en la siguiente sección 

p4 <- ggplot(esp, aes(x = time)) +
      geom_line(aes(y = prod), alpha = 0.7, size = 1.7, color = "red") +
      geom_line(aes(y = area), alpha = 0.7, size = 1.7, color = "yellow") +
      geom_line(aes(y = prodxha ), alpha = 0.7, size = 1.7, color = "green") +
     labs(x = "Año", 
       y = "Producción (miles de t) / Área (miles de Ha)",
       title= 'Producción de alcachofas y área utilizada en España', 
       subtitle = 'Datos de 1964 a 2019', 
       caption = '(C) EuroGeographics for the administrative boundaries') 

ggplotly(p4)

5. Gráfico resumen datos de España

En este gráfico interactivo podemos ver un resumen de los datos de España, pudiendo ver el detalle de producción, área dedicada a la producción y producción por hectárea.

La línea roja representa la Producción de alchofas a lo largo de los años, en miles de toneladas.

La línea amarilla representa el Área dedicada al cultivo de alcachofas, en miles de hectáreas.

La línea verde representa la Producción por hectárea, en toneladas por hectárea.

Podemos desplazarnos por las lineas para ver la información detallada de cada año.

IV. Conclusiones

A partir de los datos podemos concluir rapidamente que España es uno de los mayores productores de alcachofas de Europa, superado solo por Italia.

Es razonable asumir que Italia y España son los principales suministradores de alcachofas al resto de paises de Europa, sobretodo a los países del espacio Schengen de libre mercado.

LS0tDQp0aXRsZTogIkVzdHVkaW8gZGVsIHNlY3RvciBhZ3LDrWNvbGE6IExhIEFsY2FjaG9mYSINCnN1YnRpdGxlOiAiTWlndWVsIE1vbnRhbHZvIChtb25kaWVzQGFsdW1uaS51di5lcykiICMtIHBvbmdvIHTDuiBub21icmUgYWjDrSBwYXJhIHEgYXBhcmV6Y2EgbcOhcyBncmFuZGUgcSBlbCBkZSBsYSBVVg0KYXV0aG9yOiAiVW5pdmVyc2l0YXQgZGUgVmFsw6huY2lhIg0KZGF0ZTogIkRpY2llbWJyZSBkZSAyMDIwIChhY3R1YWxpemFkbyBlbCBgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkLSVtLSVZJylgKSINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICAjY3NzOiAiLi9hc3NldHMvbXlfY3NzX2ZpbGUuY3NzIg0KICAgIHRoZW1lOiBqb3VybmFsDQogICAgaGlnaGxpZ2h0OiB0ZXh0bWF0ZSANCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZGVwdGg6IDMgDQogICAgdG9jX2Zsb2F0OiANCiAgICAgIGNvbGxhcHNlZDogdHJ1ZQ0KICAgICAgc21vb3RoX3Njcm9sbDogdHJ1ZQ0KICAgIHNlbGZfY29udGFpbmVkOiB0cnVlDQogICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQ0KICAgIGRmX3ByaW50OiBrYWJsZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCmVkaXRvcl9vcHRpb25zOiANCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUNCi0tLQ0KDQpgYGB7ciBwYWNrYWdlcy1zZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGV1cm9zdGF0KQ0KbGlicmFyeShyaW8pDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkoa2FibGVFeHRyYSkNCmxpYnJhcnkoZ3QpDQpsaWJyYXJ5KHdvcmRjbG91ZDIpDQpsaWJyYXJ5KGdnYW5pbWF0ZSkNCmxpYnJhcnkoZ2d0aGVtZXMpDQpgYGANCg0KYGBge3IgY2h1bmstc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCBjb21tZW50ID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgI3Jlc3VsdHMgPSAiaG9sZCIsDQogICAgICAgICAgICAgICAgICAgICAgY2FjaGUgPSBGQUxTRSwgY2FjaGUucGF0aCA9ICIvY2FjaGVzLyIsIGNvbW1lbnQgPSAiIz4iLA0KICAgICAgICAgICAgICAgICAgICAgICNmaWcud2lkdGggPSAxNSwgIGZpZy5oZWlnaHQ9IDE1LCAgIA0KICAgICAgICAgICAgICAgICAgICAgICNvdXQud2lkdGggPSA3LCBvdXQuaGVpZ2h0ID0gNywNCiAgICAgICAgICAgICAgICAgICAgICBjb2xsYXBzZSA9IFRSVUUsICBmaWcuc2hvdyA9ICJob2xkIiwNCiAgICAgICAgICAgICAgICAgICAgICBmaWcuYXNwID0gNy85LCBvdXQud2lkdGggPSAiNzAlIiwgZmlnLmFsaWduID0gImNlbnRlciIpDQprbml0cjo6b3B0c19jaHVuayRzZXQoZGV2ID0gInBuZyIsIGRldi5hcmdzID0gbGlzdCh0eXBlID0gImNhaXJvLXBuZyIpKQ0KYGBgDQoNCmBgYHtyIG9wdGlvbnMtc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCm9wdGlvbnMoc2NpcGVuID0gOTk5KSAjLSBwYXJhIHF1aXRhciBsYSBub3RhY2nDs24gY2llbnTDrWZpY2ENCm9wdGlvbnMoInlhbWwuZXZhbC5leHByIiA9IFRSVUUpIA0KYGBgDQoNCg0KYGBge3Iga2xpcHB5LCBlY2hvID0gRkFMU0V9DQprbGlwcHk6OmtsaXBweShwb3NpdGlvbiA9IGMoInRvcCIsICJyaWdodCIpKSAjLSByZW1vdGVzOjppbnN0YWxsX2dpdGh1Yigicmxlc3VyL2tsaXBweSIpDQpgYGANCg0KPGhyIGNsYXNzPSJsaW5lYS1ibGFjayI+DQoNClRyYWJham8gZWxhYm9yYWRvIHBhcmEgbGEgYXNpZ25hdHVyYSAiUHJvZ3JhbWFjacOzbiB5IG1hbmVqbyBkZSBkYXRvcyBlbiBsYSBlcmEgZGVsIEJpZyBEYXRhIiBkZSBsYSBVbml2ZXJzaXRhdCBkZSBWYWzDqG5jaWEgZHVyYW50ZSBlbCBjdXJzbyAyMDIwLTIwMjEuIEVsIHJlcG8gZGVsIHRyYWJham8gZXN0w6EgW2FxdcOtXShodHRwczovL2dpdGh1Yi5jb20vbWlndWVyY2lvcy90cmFiYWpvX0JpZ0RhdGEpe3RhcmdldD0iX2JsYW5rIn0uIExhIHDDoWdpbmEgd2ViIGRlIGxhIGFzaWduYXR1cmEgeSBsb3MgdHJhYmFqb3MgZGUgbWlzIGNvbXBhw7Flcm9zIHB1ZWRlbiB2ZXJzZSBbYXF1w61dKGh0dHBzOi8vcGVyZXpwNDQuZ2l0aHViLmlvL2ludHJvLWRzLTIwLTIxLXdlYi8wNy10cmFiYWpvcy5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9Lg0KDQo8aHIgY2xhc3M9ImxpbmVhLXJlZCI+DQoNCiMgSS4gSW50cm9kdWNjacOzbiANCiAgDQpFbiBlc3RlIHRyYWJham8gaGFyZW1vcyB1biBlc3R1ZGlvIHNvYnJlIGxhICoqcHJvZHVjY2nDs24gZGUgYWxjYWNob2ZhcyBlbiBFdXJvcGEgeSBFc3Bhw7FhKiouICANCiAgDQpFeHBsb3JhbmRvIGxhIGJhc2UgZGUgZGF0b3MgZGUgKipFdXJvc3RhdCoqIGRpIGNvbiB1bm9zIGRhdG9zIGNvbXBsZXRvcyB5IGRldGFsbGFkb3MgZGUgbGEgcHJvZHVjY2nDs24gYWdyw61jb2xhIGVuIEV1cm9wYSwgZGUgbW9kbyBxdWUgbWUgZGVjYW50w6kgcG9yIGVsbG9zLiBMYSBlbGVjY2nDs24gZGUgZXN0ZSB0ZW1hIGhhIHNpZG8gbW90aXZhZGEgcG9yIGxhIGRpc3BvbmliaWxpZGFkIGRlIHVuIGRhdGFzZXQgbG8gc3VmaWNpZW50ZW1lbnRlIGRldGFsbGFkbywgYWRlbcOhcyBkZSBxdWUgbWUgZ3VzdGFuIGxhcyBhbGNhY2hvZmFzLiANCiAgDQpPcHTDqSBwb3IgY2VudHJhcm1lIGVuIHVuIHNvbG8gcHJvZHVjdG8sIHF1ZSBoYW4gc2lkbyBsYXMgYWxjYWNob2Zhcy4gQXVucXVlIGxvcyBkYXRvcyBsbGVnYW4gaGFzdGEgMjAyMCBoYXkgbXVjaG9zIHBhaXNlcyBxdWUgbm8gdGllbmVuIGRhdG9zIHBhcmEgZXNlIGHDsW8sIHBvciBsbyBxdWUgaGUgb3B0YWRvIHBvciBjb25zaWRlcmFyICoqMjAxOSoqIGNvbW8gZWwgYcOxbyBtw6FzIHJlY2llbnRlLiANCg0KPCEtLSBtZXRlciBhcXXDrSBhbGNhY2hvZmEgLS0+DQoNCmBgYHtyIGFsY2FjaG9mYSwgZXZhbCA9IFRSVUUsIGVjaG8gPSBGQUxTRX0NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCcuL2ltYWdlbmVzL2FsY2FjaG9mYTIuanBnJykNCmBgYA0KDQoNCmBgYHtyLCBldmFsPSBUUlVFLCBlY2hvID0gRkFMU0UsIGluY2x1ZGUgPSBGQUxTRSB9DQojRXN0ZSBjw7NkaWdvIGVzdMOhIGFxdcOtIHBvcnF1ZSBzaSBubyBubyBmdW5jaW9uYSBtw6FzIGFiYWpvLiBObyBsZSBlbmN1ZW50cm8gZXhwbGljYWNpw7NuDQoNCiMgQ2FyZ2Ftb3MgZGF0b3MgeSBnZW9tZXRyw61hcw0KZGF0b3MgPC0gcmlvOjppbXBvcnQgKCcuL2RhdG9zL2FsY2FjaG9mYXMuY3N2JykNCg0KcHJfZXNwIDwtIGRhdG9zICU+JSBmaWx0ZXIoc3RydWNwcm9fY29kZSA9PSAnUFInLCBnZW9fY29kZSA9PSAnRVMnKSAlPiUgc2VsZWN0KGdlb19jb2RlLCBnZW8sIHRpbWUsIHZhbHVlcykgJT4lDQogIGdyb3VwX2J5KGdlb19jb2RlKSAlPiUgYXJyYW5nZSh0aW1lKSAlPiUgbXV0YXRlKGFjdW0gPSBjdW1zdW0odmFsdWVzKSkgJT4lIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlIChhY3VtID0gYXMubnVtZXJpYyhhY3VtKSkgJT4lIHJlbmFtZShwcm9kID0gdmFsdWVzLCBwcnN1bSA9IGFjdW0pDQoNCmFyX2VzcCA8LSBkYXRvcyAlPiUgZmlsdGVyKHN0cnVjcHJvX2NvZGUgPT0gJ0FSJywgZ2VvX2NvZGUgPT0gJ0VTJykgJT4lIHNlbGVjdChnZW9fY29kZSwgZ2VvLCB0aW1lLCB2YWx1ZXMpICU+JQ0KICBncm91cF9ieShnZW9fY29kZSkgJT4lIGFycmFuZ2UodGltZSkgJT4lIHJlbmFtZSAoYXJlYSA9IHZhbHVlcykNCg0KZXNwIDwtIGZ1bGxfam9pbihwcl9lc3AsIGFyX2VzcCkNCmVzcCA8LSBlc3AgJT4lIG11dGF0ZSAocHJvZHhoYSA9IHByb2QvYXJlYSkNCg0KcDQgPC0gZ2dwbG90KGVzcCwgYWVzKHggPSB0aW1lKSkgKw0KICAgICAgZ2VvbV9saW5lKGFlcyh5ID0gcHJvZCksIGFscGhhID0gMC43LCBzaXplID0gMS43LCBjb2xvciA9ICJyZWQiKSArDQogICAgICBnZW9tX2xpbmUoYWVzKHkgPSBhcmVhKSwgYWxwaGEgPSAwLjcsIHNpemUgPSAxLjcsIGNvbG9yID0gInllbGxvdyIpICsNCiAgICAgIGdlb21fbGluZShhZXMoeSA9IHByb2R4aGEgKSwgYWxwaGEgPSAwLjcsIHNpemUgPSAxLjcsIGNvbG9yID0gImdyZWVuIikgKw0KICAgICBsYWJzKHggPSAiQcOxbyIsIA0KICAgICAgIHkgPSAiUHJvZHVjY2nDs24gKG1pbGVzIGRlIHQpIC8gw4FyZWEgKG1pbGVzIGRlIEhhKSIsDQogICAgICAgdGl0bGU9ICdQcm9kdWNjacOzbiBkZSBhbGNhY2hvZmFzIHkgw6FyZWEgdXRpbGl6YWRhIGVuIEVzcGHDsWEnLCANCiAgICAgICBzdWJ0aXRsZSA9ICdEYXRvcyBkZSAxOTY0IGEgMjAxOScsIA0KICAgICAgIGNhcHRpb24gPSAnKEMpIEV1cm9HZW9ncmFwaGljcyBmb3IgdGhlIGFkbWluaXN0cmF0aXZlIGJvdW5kYXJpZXMnKSANCg0KZ2dwbG90bHkocDQpDQoNCmBgYA0KDQojIElJLiBEYXRvcw0KICANCkVsIGVzdHVkaW8gc2UgcmVhbGl6YSBjb24gdW5vcyAqKmRhdG9zIGRlIHByb2R1Y2Npw7NuIGFncsOtY29sYSoqIGRlIGxhIGJhc2UgZGUgZGF0b3MgKipFdXJvc3RhdCoqLg0KICANCkEgY29udGludWFjacOzbiBwb2RlbW9zIHZlciBlbCBwcm9jZXNvIGRlIG9idGVuY2nDs24geSBsaW1waWV6YSBkZSBsb3MgZGF0b3MsIHF1ZSBhY2FiYSBjb24gdW4gYXJjaGl2byBkZWZpbml2byBhIHBhcnRpciBkZWwgY3VhbCBzZSBoYW4gZWxhYm9yYWRvIGxvcyBjb250ZW5pZG9zLiANCg0KIyMgMS4gT2J0ZW5jacOzbiB5IGxpbXBpZXphIHsudGFic2V0fQ0KDQpFbCBlc3R1ZGlvIHNlIHJlYWxpemEgY29uIHVub3MgKipkYXRvcyBkZSBwcm9kdWNjacOzbiBhZ3LDrWNvbGEqKiBkZSBsYSBiYXNlIGRlIGRhdG9zICoqRXVyb3N0YXQqKi4NCiAgDQpBIGNvbnRpbnVhY2nDs24gcG9kZW1vcyB2ZXIgZWwgcHJvY2VzbyBkZSBvYnRlbmNpw7NuIHkgbGltcGllemEgZGUgbG9zIGRhdG9zLCBxdWUgYWNhYmEgY29uIHVuIGFyY2hpdm8gZGVmaW5pdm8gYSBwYXJ0aXIgZGVsIGN1YWwgc2UgaGFuIGVsYWJvcmFkbyBsb3MgY29udGVuaWRvcy4gDQogIA0KIyMjIEV4cGxvcmFjacOzbiBkZSBkYXRvcw0KDQpgYGB7ciwgZXZhbCA9IEZBTFNFfQ0KIyBGdW5jacOzbiByZXN1bWlkb3JhIGRlbCBwcm9mZXNvcg0KenogPC0gcGpwdjIwMjAuMDE6OnBqcF9mX3VuaXF1ZV92YWx1ZXMoZGZfNSwgdHJ1bmNhdGUgPSBUUlVFLCBubl90cnVuY2F0ZSA9IDQ3KSANCg0KDQojIENyb3AgcHJvZHVjdGlvbiBpbiBFVSBzdGFuZGFyZCBodW1pZGl0eSAoYXByb19jcHNoMSkJDQpkZjEgPC0gZ2V0X2V1cm9zdGF0KCJhcHJvX2Nwc2gxIiwgdGltZV9mb3JtYXQgPSAncmF3Jywga2VlcEZsYWdzID0gVCApDQpkZl8xIDwtIGxhYmVsX2V1cm9zdGF0KGRmMSkgDQoNCmRmMSA8LSBsYWJlbF9ldXJvc3RhdChkZjEsIGNvZGU9IGMoImNyb3BzIiwgInN0cnVjcHJvIiwgImdlbyIpICkNCmRmMSA8LSBkZjEgJT4lIGZpbHRlciAoY3JvcHMgPT0gJ0FydGljaG9rZXMnKSAlPiUNCiAgbXV0YXRlKHZhbHVlcyA9IGlmZWxzZShpcy5uYSh2YWx1ZXMpLCAwLCB2YWx1ZXMpKQ0KDQoNCnJpbzo6ZXhwb3J0KGRmLCAiLi9kYXRvcy9Qcm9kdWNjaW9uX2FncmkueGxzeCIpDQpyaW86OmV4cG9ydChkZl8xLCAiLi9kYXRvcy9Qcm9kdWNjaW9uX2FncmlfbGFiLnhsc3giKQ0KDQojIFVuaXQgdmFsdWVzIGF0IGJhc2ljIHByaWNlcyAoYWFjdF91djAxKQkNCmRmMiA8LSBnZXRfZXVyb3N0YXQoImFhY3RfdXYwMSIsIHRpbWVfZm9ybWF0ID0gJ3JhdycsIGtlZXBGbGFncyA9IFQpDQpkZl8yIDwtIGxhYmVsX2V1cm9zdGF0KGRmMikNCg0KZGYyIDwtIGxhYmVsX2V1cm9zdGF0KGRmMiwgY29kZSA9IGMoIml0bV9uZXdhIiwgImdlbyIsICJ1bml0IikpDQpkZjIgPC0gZGYyICU+JSBmaWx0ZXIgKGl0bV9uZXdhID09ICdBUlRJQ0hPS0VTJykgJT4lIGZpbHRlciAodW5pdCA9PSAnRXVybyBwZXIgdG9ubmUnKQ0KDQoNCiMgVW5pdCB2YWx1ZXMgcXVhbnRpdGllcyAoZW4gbWlsZXMgZGUgdCkgKGFhY3RfdXYwMykJDQpkZjMgPC0gZ2V0X2V1cm9zdGF0KCJhYWN0X3V2MDMiLCB0aW1lX2Zvcm1hdCA9ICdyYXcnLCBrZWVwRmxhZ3MgPSBUKQ0KZGZfMyA8LSBsYWJlbF9ldXJvc3RhdChkZjMpDQoNCmRmMyA8LSBsYWJlbF9ldXJvc3RhdChkZjMsIGNvZGUgPSBjKCJpdG1fbmV3YSIsICJnZW8iKSkNCmRmMyA8LSBkZjMgJT4lIGZpbHRlciAoaXRtX25ld2EgPT0gJ0FSVElDSE9LRVMnKSAlPiUNCiAgcmVuYW1lICggdWRzX3Byb2RfMTAwMHQgPSB2YWx1ZXMpDQoNCg0KIyBEYXRhZnJhbWUgY29uanVudG8gZGYyIHkgZGYzDQpkZjQgPC0gZnVsbF9qb2luKGRmMiwgZGYzLCBieSA9IGMoImdlb19jb2RlIiwgInRpbWUiKSkgDQpkZjQgPC0gZGY0ICU+JSBzZWxlY3QgKGdlb19jb2RlLCB1bml0LCBnZW8ueCwgaXRtX25ld2EueCwgdGltZSwgdmFsdWVzLCB1ZHNfcHJvZF8xMDAwdCkNCg0KYGBgDQoNCiMjIyBMaW1waWV6YSBkZSBsb3MgZGF0b3MgZGVmaW5pdGl2b3MNCg0KYGBge3IsIGV2YWwgPSBGQUxTRX0NCiMgRnVuY2nDs24gcmVzdW1pZG9yYSBkZWwgcHJvZmVzb3INCnp6IDwtIHBqcHYyMDIwLjAxOjpwanBfZl91bmlxdWVfdmFsdWVzKGRmMSwgdHJ1bmNhdGUgPSBUUlVFLCBubl90cnVuY2F0ZSA9IDQ3KSANCg0KIyBDcm9wIHByb2R1Y3Rpb24gaW4gRVUgc3RhbmRhcmQgaHVtaWRpdHkgKDEwMDAgdCkgKGFwcm9fY3BzaDEpCQ0KZGYxIDwtIGdldF9ldXJvc3RhdCgiYXByb19jcHNoMSIsIHRpbWVfZm9ybWF0ID0gJ3JhdycsIGtlZXBGbGFncyA9IFQgKQ0KZGZfMSA8LSBsYWJlbF9ldXJvc3RhdChkZjEpIA0KDQpkZmZ1bGwgPC0gbGFiZWxfZXVyb3N0YXQoZGYxLCBjb2RlPSBjKCJjcm9wcyIsICJzdHJ1Y3BybyIsICJnZW8iKSApDQoNCmRmMSA8LSBkZmZ1bGwgJT4lIGZpbHRlciAoY3JvcHMgPT0gJ0FydGljaG9rZXMnKSAlPiUNCiAgbXV0YXRlKHZhbHVlcyA9IGlmZWxzZShpcy5uYSh2YWx1ZXMpLCAwLCB2YWx1ZXMpKSAlPiUNCiAgc2VsZWN0KHN0cnVjcHJvX2NvZGUsIGdlb19jb2RlLCBjcm9wcywgc3RydWNwcm8sIGdlbywgdGltZSwgdmFsdWVzKQ0KDQojIENyb3AgcHJvZHVjdGlvbiAtIGhpc3RvcmljYWwgZGF0YSAoMTk1NS0xOTk5KSAoYXByb19jcG5oMV9oKQkgDQpkZjIgPC0gZ2V0X2V1cm9zdGF0KCJhcHJvX2NwbmgxX2giLCB0aW1lX2Zvcm1hdCA9ICdyYXcnLCBrZWVwRmxhZ3MgPSBUICkNCmRmXzIgPC0gbGFiZWxfZXVyb3N0YXQoZGYyKSANCg0KZGZmdWxsMiA8LSBsYWJlbF9ldXJvc3RhdChkZjIsIGNvZGU9IGMoImNyb3BzIiwgInN0cnVjcHJvIiwgImdlbyIpKQ0KZGYyIDwtIGRmZnVsbDIgJT4lIGZpbHRlciAoY3JvcHMgPT0gJ0FydGljaG9rZXMnKSAlPiUNCiAgbXV0YXRlKHZhbHVlcyA9IGlmZWxzZShpcy5uYSh2YWx1ZXMpLCAwLCB2YWx1ZXMpKSAlPiUNCiAgc2VsZWN0KHN0cnVjcHJvX2NvZGUsIGdlb19jb2RlLCBjcm9wcywgc3RydWNwcm8sIGdlbywgdGltZSwgdmFsdWVzKQ0KDQojIEp1bnRhbW9zIGxvcyBkYXRhZnJhbWVzLCBhc3VtaWVuZG8gcXVlIGxhIHByb2R1Y2Npw7NuIGVuIGVzdMOhbmRhciBkZSBodW1lZGFkIGRlIGxhIFVFIGVzIGVsIG1pc21vIHF1ZSBlbCBoaXN0w7NyaWNvDQpkZnRvZG8gPC0gZnVsbF9qb2luKGRmZnVsbCwgZGZmdWxsMikNCmRmdG9kb3JlZCA8LSBmdWxsX2pvaW4oZGYxLCBkZjIpDQoNCmRmYnVlbm8gPC0gZGZ0b2RvcmVkDQoNCiMgQ2FtYmlhbW9zIGFsZ3Vub3MgdmFsb3Jlcw0KZGZidWVubyRzdHJ1Y3Byb19jb2RlW2RmYnVlbm8kc3RydWNwcm9fY29kZSA9PSAiUFJfSFVfRVUiXSA8LSAiUFIiDQpkZmJ1ZW5vJHN0cnVjcHJvW2RmYnVlbm8kc3RydWNwcm8gPT0gIkhhcnZlc3RlZCBwcm9kdWN0aW9uIGluIEVVIHN0YW5kYXJkIGh1bWlkaXR5ICgxMDAwIHQpIl0gPC0gIkhhcnZlc3RlZCBwcm9kdWN0aW9uICgxMDAwIHQpIg0KDQpyaW86OmV4cG9ydChkZmJ1ZW5vLCAnLi9kYXRvcy9hbGNhY2hvZmFzLmNzdicpDQpyaW86OmV4cG9ydChkZnRvZG8sICcuL2RhdG9zL3Byb2R1Y2Npb25leHQuY3N2JykNCnJpbzo6ZXhwb3J0KGRmdG9kb3JlZCwgJy4vZGF0b3MvcHJvZHVjY2lvbi5jc3YnKQ0KDQpybShkZl8xLCBkZl8yLCBkZjEsIGRmMiwgZGZmdWxsLCBkZmZ1bGwyLCBkZnRvZG8sIGRmdG9kb3JlZCwgZGZidWVubykNCg0KZGF0b3MgPC0gcmlvOjppbXBvcnQgKCcuL2RhdG9zL2FsY2FjaG9mYXMuY3N2JykNCg0KIy0gRGVzY2FyZ2Ftb3MgZ2VvbWV0csOtYXMgZGUgRXVyb3BhDQpnZW9tZXRyaWFzIDwtIGdldF9ldXJvc3RhdF9nZW9zcGF0aWFsKHJlc29sdXRpb24gPSAiMjAiLCBudXRzX2xldmVsID0gIjAiKQ0KcGxvdChnZW9tZXRyaWFzLCBtYXgucGxvdCA9IDEpDQoNCm1hcGRhdGEgPC0gZnVsbF9qb2luKGRhdG9zLCBnZW9tZXRyaWFzLCBieSA9IGMoImdlb19jb2RlIiA9ICJpZCIpKQ0KYGBgDQoNCiMjIDIuIFRhYmxhIGRlIGRhdG9zIA0KICANCioqQVIqKiByZXByZXNlbnRhIGxvcyB2YWxvcmVzIHBhcmEgw6FyZWEgY3VsdGl2YWRhIGVuIG1pbGVzIGRlIGhlY3TDoXJlYXMsIHkgKipQUioqIHJlcHJlc2VudGEgbGEgcHJvZHVjY2nDs24gZW4gbWlsZXMgZGUgdG9uZWxhZGFzLg0KDQpgYGB7ciwgZXZhbCA9IFRSVUV9DQpkYXRvcyA8LSByaW86OmltcG9ydCAoJy4vZGF0b3MvYWxjYWNob2Zhcy5jc3YnKSAlPiUgc2VsZWN0KCFjKHN0cnVjcHJvLCBjcm9wcykpDQpkYXRvcyRnZW9bZGF0b3MkZ2VvX2NvZGUgPT0gIkRFIl0gPC0gIkdlcm1hbnkiDQpkYXRvcyRnZW9bZGF0b3MkZ2VvX2NvZGUgPT0gIlhLIl0gPC0gIktvc292byINCg0KRFQ6OmRhdGF0YWJsZShkYXRvcykNCmBgYA0KICANCg0KIyBJSUkuIEVzdHVkaW9zIHJlYWxpemFkb3MNCiAgDQojIyAxLiDDgXJlYSBkZWRpY2FkYSBhbCBjdWx0aXZvIGRlIGFsY2FjaG9mYXMgey50YWJzZXR9DQogIA0KIyMjIE1hcGEgZGUgw6FyZWEgY3VsdGl2YWRhDQogIA0KQ29tbyBwb2RlbW9zIG9ic2VydmFyIGVuIGVsIHNpZ3VpZW50ZSBtYXBhLCBsb3MgcGFpc2VzIHF1ZSBkZWRpY2FuIHVuYSBtYXlvciDDoXJlYSBhbCBjdWx0aXZvIGRlIGFsY2FjaG9mYXMgZW4gRXVyb3BhIHNvbiAqKkl0YWxpYSB5IEVzcGHDsWEqKiwgY29uIHVuIMOhcmVhIGRlZGljYWRhIGRlIGVudHJlIDExIHkgMjAsIHkgZGUgbcOhcyBkZSAyMCBtaWxlcyBkZSBoZWN0w6FyZWFzIHJlc3BlY3RpdmFtZW50ZS4gIA0KICANCkxvcyBzaWd1aWVudGVzIHBhaXNlcyBxdWUgZW5jb250cmFtb3Mgc29uICoqRnJhbmNpYSwgVHVycXXDrWEgeSBNYWx0YSoqLCBxdWUgZGVkaWNhbiB1bmEgw6FyZWEgZGUgZW50cmUgMTAwMCB5IDEwMDAwIGhlY3TDoXJlYXMgYWwgY3VsdGl2byBkZSBhbGNhY2hvZmFzLiAgIA0KRWwgcmVzdG8gZGUgcGFpc2VzIG8gYmllbiBubyBjdWx0aXZhbiwgbyBiaWVuIGRlZGljYW4gbWVub3MgZGUgbWlsIGhlY3TDoXJlYXMgYSBwcm9kdWNpciBhbGNhY2hvZmFzLCBwb3IgbG8gcXVlIGNvbnNpZGVyYW1vcyBzdSBjb250cmlidWNpw7NuIGNvbW8gaW5zaWduaWZpY2FudGUuIA0KDQoNCmBgYHtyIGVzdHVkaW8xLCBldmFsPSBUUlVFLCBlY2hvPSBGQUxTRSwgd2FybmluZz0gRkFMU0UsIGNvbW1lbnQgPSBGQUxTRX0NCiMgQ2FyZ2Ftb3MgZGF0b3MgeSBnZW9tZXRyw61hcw0KZGF0b3MgPC0gcmlvOjppbXBvcnQgKCcuL2RhdG9zL2FsY2FjaG9mYXMuY3N2JykNCmRhdG9zMTkgPC0gZGF0b3MgJT4lIGZpbHRlcih0aW1lID09ICcyMDE5Jywgc3RydWNwcm9fY29kZSA9PSAnQVInKQ0KDQpnZW9tZXRyaWFzIDwtIGdldF9ldXJvc3RhdF9nZW9zcGF0aWFsKHJlc29sdXRpb24gPSAiMjAiLCBudXRzX2xldmVsID0gIjAiKQ0KbWFwZGF0YSA8LSBmdWxsX2pvaW4oZGF0b3MsIGdlb21ldHJpYXMsIGJ5ID0gYygiZ2VvX2NvZGUiID0gImlkIikpDQoNCmhhXzE5IDwtIG1hcGRhdGEgJT4lIGZpbHRlciAoc3RydWNwcm9fY29kZSA9PSAnQVInLCB0aW1lID09ICcyMDE5JykNCg0KIy0gQ3JlYW1vcyBncnVwb3Mgc2Vnw7puIGxvcyB2YWxvcmVzIHBhcmEgcXVlIHBvZGVyIG1vc3RyYXJsb3MgZW4gZWwgbWFwYS4gSGUgdGVuaWRvIHF1ZSBjb252ZXJ0aXJsb3MgZW4gZW50ZXJvcyBwb3JxdWUgbm8gY29uc2VndcOtYSBxdWUgbGV5ZXJhIGxvcyBuw7ptZXJvcyBjb24gZGVjaW1hbGVzDQpoYV8xOSA8LSBoYV8xOSAlPiUgbXV0YXRlICh2YWx1ZXMgPSBhcy5pbnRlZ2VyKHZhbHVlcykpICU+JQ0KICBtdXRhdGUoZ3J1cG9zICA9IGNhc2Vfd2hlbiggDQogIHZhbHVlcyAlaW4lICgtMTowKSB+ICIwLTEiLA0KICB2YWx1ZXMgJWluJSAoMDoxMCkgfiAiMS0xMCIsDQogIHZhbHVlcyAlaW4lICgxMDoyMCkgfiAiMTEtMjAiLA0KICB2YWx1ZXMgJWluJSAoMjE6MTAwKSB+ICcyMCBvIG3DoXMnKSkNCiAgDQojIE1hcGEgYXJlYSBjdWx0aXZhZGEgZW4gMjAxOSANCnAgPC0gZ2dwbG90KGhhXzE5KSArDQogICAgIGdlb21fc2YoYWVzKGZpbGw9IGdydXBvcywgZ2VvbWV0cnkgPSBnZW9tZXRyeSksIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IC4xKSArDQogICAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUmRZbEJ1IikgICsNCiAgICAgbGFicyh0aXRsZSA9ICLDgXJlYSBkZWRpY2FkYSBhbCBjdWx0aXZvIGRlIGFsY2FjaG9mYXMgZW4gMjAxOSIsDQogICAgICAgc3VidGl0bGUgPSAiRW4gbWlsZXMgZGUgaGVjdMOhcmVhcyIsDQogICAgICAgZmlsbCA9ICJNaWxlcyBkZSBIYSIsDQogICAgICAgY2FwdGlvbiA9ICIoQykgRXVyb0dlb2dyYXBoaWNzIGZvciB0aGUgYWRtaW5pc3RyYXRpdmUgYm91bmRhcmllcyIpICsgdGhlbWVfbGlnaHQoKSArDQogICAgIGNvb3JkX3NmKHhsaW0gPSBjKC0yMCw0MyksIHlsaW0gPSBjKDM0LDY3KSkNCg0KcA0KYGBgDQoNCiMjIyBDw7NkaWdvIA0KDQpgYGB7ciBjb2Rlc3R1ZGlvMSwgZXZhbD0gRkFMU0UsIGVjaG89IFRSVUUsIHdhcm5pbmc9IEZBTFNFLCBjb21tZW50ID0gRkFMU0V9DQojIENhcmdhbW9zIGRhdG9zIHkgZ2VvbWV0csOtYXMNCmRhdG9zIDwtIHJpbzo6aW1wb3J0ICgnLi9kYXRvcy9hbGNhY2hvZmFzLmNzdicpDQpkYXRvczE5IDwtIGRhdG9zICU+JSBmaWx0ZXIodGltZSA9PSAnMjAxOScsIHN0cnVjcHJvX2NvZGUgPT0gJ0FSJykNCg0KZ2VvbWV0cmlhcyA8LSBnZXRfZXVyb3N0YXRfZ2Vvc3BhdGlhbChyZXNvbHV0aW9uID0gIjIwIiwgbnV0c19sZXZlbCA9ICIwIikNCm1hcGRhdGEgPC0gZnVsbF9qb2luKGRhdG9zLCBnZW9tZXRyaWFzLCBieSA9IGMoImdlb19jb2RlIiA9ICJpZCIpKQ0KDQpoYV8xOSA8LSBtYXBkYXRhICU+JSBmaWx0ZXIgKHN0cnVjcHJvX2NvZGUgPT0gJ0FSJywgdGltZSA9PSAnMjAxOScpDQoNCiMtIENyZWFtb3MgZ3J1cG9zIHNlZ8O6biBsb3MgdmFsb3JlcyBwYXJhIHF1ZSBwb2RlciBtb3N0cmFybG9zIGVuIGVsIG1hcGEuIEhlIHRlbmlkbyBxdWUgY29udmVydGlybG9zIGVuIGVudGVyb3MgcG9ycXVlIG5vIGNvbnNlZ3XDrWEgcXVlIGxleWVyYSBsb3MgbsO6bWVyb3MgY29uIGRlY2ltYWxlcw0KaGFfMTkgPC0gaGFfMTkgJT4lIG11dGF0ZSAodmFsdWVzID0gYXMuaW50ZWdlcih2YWx1ZXMpKSAlPiUNCiAgbXV0YXRlKGdydXBvcyAgPSBjYXNlX3doZW4oIA0KICB2YWx1ZXMgJWluJSAoLTE6MCkgfiAiMC0xIiwNCiAgdmFsdWVzICVpbiUgKDA6MTApIH4gIjEtMTAiLA0KICB2YWx1ZXMgJWluJSAoMTA6MjApIH4gIjExLTIwIiwNCiAgdmFsdWVzICVpbiUgKDIxOjEwMCkgfiAnMjAgbyBtw6FzJykpDQogIA0KIyBNYXBhIGFyZWEgY3VsdGl2YWRhIGVuIDIwMTkgDQpwIDwtIGdncGxvdChoYV8xOSkgKw0KICAgICBnZW9tX3NmKGFlcyhmaWxsPSBncnVwb3MsIGdlb21ldHJ5ID0gZ2VvbWV0cnkpLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSAuMSkgKw0KICAgICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlJkWWxCdSIpICArDQogICAgIGxhYnModGl0bGUgPSAiw4FyZWEgZGVkaWNhZGEgYWwgY3VsdGl2byBkZSBhbGNhY2hvZmFzIGVuIDIwMTkiLA0KICAgICAgIHN1YnRpdGxlID0gIkVuIG1pbGVzIGRlIGhlY3TDoXJlYXMiLA0KICAgICAgIGZpbGwgPSAiTWlsZXMgZGUgSGEiLA0KICAgICAgIGNhcHRpb24gPSAiKEMpIEV1cm9HZW9ncmFwaGljcyBmb3IgdGhlIGFkbWluaXN0cmF0aXZlIGJvdW5kYXJpZXMiKSArIA0KICAgICB0aGVtZV9saWdodCgpICsgY29vcmRfc2YoeGxpbSA9IGMoLTIwLDQzKSwgeWxpbSA9IGMoMzQsNjcpKQ0KDQpwDQpgYGANCiAgDQogDQojIyAyLiBQcm9kdWNjacOzbiBkZSBhbGNhY2hvZmFzIGVuIDIwMTkgey50YWJzZXR9DQogIA0KIyMjIE1hcGEgZGUgcHJvZHVjY2nDs24NCiAgDQpFc3RlIG1hcGEgbm9zIG11ZXN0cmEgbGEgcHJvZHVjY2nDs24gZGUgYWxjYWNob2ZhcyBlbiBFdXJvcGEgZW4gMjAxOS4gIA0KICANClLDoXBpZGFtZW50ZSBwb2RlbW9zIHZlciBxdWUgKipFc3Bhw7FhIGUgSXRhbGlhKiogc29uIGxvcyBwcmluY2lwYWxlcyBwcm9kdWNjdG9yZXMsIHNlZ3VpZG9zIHBvciAqKlR1cnF1w61hLCBGcmFuY2lhIHkgR3JlY2lhKiosIGF1bnF1ZSBlc3RvcyBlbiBtdWNoYSBtZW5vciBtZWRpZGEuICANCkVsIHJlc3RvIGRlIHBhaXNlcyBvIGJpZW4gbm8gcHJvZHVjZW4gbyBzdSBwcm9kdWNjacOzbiBlcyBpbnNpZ25pZmljYW50ZSBhIGVzY2FsYSBFdXJvcGVhLiANCiAgICANCmBgYHtyIGVzdHVkaW8yIHAxLCBldmFsPSBUUlVFLCBlY2hvPSBGQUxTRSwgd2FybmluZz0gRkFMU0UsIGNvbW1lbnQgPSBGQUxTRX0NCiMgQ2FyZ2Ftb3MgZGF0b3MgeSBnZW9tZXRyw61hcw0KZGF0b3MgPC0gcmlvOjppbXBvcnQgKCcuL2RhdG9zL2FsY2FjaG9mYXMuY3N2JykNCmRhdG9zMTkgPC0gZGF0b3MgJT4lIGZpbHRlcih0aW1lID09ICcyMDE5Jywgc3RydWNwcm9fY29kZSA9PSAnUFInKSAlPiUgbXV0YXRlICh2YWx1ZXMgPSBhcy5pbnRlZ2VyKHZhbHVlcykpDQoNCmdlb21ldHJpYXMgPC0gZ2V0X2V1cm9zdGF0X2dlb3NwYXRpYWwocmVzb2x1dGlvbiA9ICIyMCIsIG51dHNfbGV2ZWwgPSAiMCIpDQoNCm1hcGRhdGEgPC0gZnVsbF9qb2luKGRhdG9zLCBnZW9tZXRyaWFzLCBieSA9IGMoImdlb19jb2RlIiA9ICJpZCIpKQ0KDQpwcl8xOSA8LSBtYXBkYXRhICU+JSBmaWx0ZXIgKHN0cnVjcHJvX2NvZGUgPT0gJ1BSJywgdGltZSA9PSAnMjAxOScpDQoNCiMtIENyZWFtb3MgZ3J1cG9zIHNlZ8O6biBsb3MgdmFsb3JlcyBwYXJhIHF1ZSBwb2RlciBtb3N0cmFybG9zIGVuIGVsIG1hcGEuIEhlIHRlbmlkbyBxdWUgY29udmVydGlybG9zIGVuIGVudGVyb3MgcG9ycXVlIG5vIGNvbnNlZ3XDrWEgcXVlIGxleWVyYSBsb3MgbsO6bWVyb3MgY29uIGRlY2ltYWxlcw0KcHJfMTkgPC0gcHJfMTkgJT4lIG11dGF0ZSAodmFsdWVzID0gYXMuaW50ZWdlcih2YWx1ZXMpKSAlPiUNCiAgbXV0YXRlKGdydXBvcyAgPSBjYXNlX3doZW4oIA0KICB2YWx1ZXMgJWluJSAoMCkgfiAiMCIsDQogIHZhbHVlcyAlaW4lICgxOjEwMCkgfiAiMS0xMDAiLA0KICB2YWx1ZXMgJWluJSAoMTAxOjIwMCkgfiAiMTAxLTIwMCIsDQogIHZhbHVlcyAlaW4lICgyMDE6MTAwMCkgfiAnMjAwIG8gbcOhcycpKQ0KICANCiMgTWFwYSBhcmVhIGN1bHRpdmFkYSBlbiAyMDE5IA0KcCA8LSBnZ3Bsb3QocHJfMTkpICsNCiAgICAgZ2VvbV9zZihhZXMoZmlsbD0gZ3J1cG9zLCBnZW9tZXRyeSA9IGdlb21ldHJ5KSwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gLjEpICsNCiAgICAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJCckJHIikgICsNCiAgICAgbGFicyh0aXRsZSA9ICJQcm9kdWNjacOzbiBkZSBhbGNhY2hvZmFzIGVuIDIwMTkiLA0KICAgICAgIHN1YnRpdGxlID0gIkVuIG1pbGVzIGRlIHRvbmVsYWRhcyIsDQogICAgICAgZmlsbCA9ICJNaWxlcyBkZSB0IiwNCiAgICAgICBjYXB0aW9uID0gIihDKSBFdXJvR2VvZ3JhcGhpY3MgZm9yIHRoZSBhZG1pbmlzdHJhdGl2ZSBib3VuZGFyaWVzIikgKyB0aGVtZV9saWdodCgpICsNCiAgICAgY29vcmRfc2YoeGxpbSA9IGMoLTIwLDQzKSwgeWxpbSA9IGMoMzQsNjcpKQ0KDQpwDQpgYGANCg0KYGBge3IgZXN0dWRpbzIgcDIsIGV2YWw9IFRSVUUsIGVjaG89IEZBTFNFLCB3YXJuaW5nPSBGQUxTRSwgY29tbWVudCA9IEZBTFNFfQ0KIyBUYWJsYSBtYXlvcmVzIHByb2R1Y3RvcmVzDQoNCml0YWx5IDwtICcuL2ltYWdlbmVzL2l0Jw0Kc3BhaW4gPC0gJy4vaW1hZ2VuZXMvZXMnDQp0dXJrZXkgPC0gJy4vaW1hZ2VuZXMvdHInDQpmcmFuY2UgPC0gJy4vaW1hZ2VuZXMvZnInDQpncmVlY2UgPC0gJy4vaW1hZ2VuZXMvZ3InDQpiYW5kZXJhcyA8LSBjKGl0YWx5LCBzcGFpbiwgdHVya2V5LCBmcmFuY2UsIGdyZWVjZSkNCg0KDQp0YWJsYTE5IDwtIGRhdG9zMTkgJT4lIGZpbHRlciAodmFsdWVzIDwgNjAwKSAlPiUgc2VsZWN0IChnZW8sIHZhbHVlcykgICU+JSANCiAgc2xpY2VfbWF4ICh2YWx1ZXMsIG4gPSA1KSAlPiUgYXJyYW5nZSAoIGRlc2ModmFsdWVzKSkgJT4lIG11dGF0ZSh2YWx1ZXM9IGFzLm51bWVyaWModmFsdWVzKSkgJT4lDQogIHJlbmFtZSgnUGHDrXMnID0gZ2VvLCAnQ2FudGlkYWQgcHJvZHVjaWRhIChtaWxlcyBkZSB0KScgPSB2YWx1ZXMpDQoNCnRhYmxhMTkkUGHDrXNbdGFibGExOSRQYcOtcyA9PSAiSXRhbHkiXSA8LSAiSXRhbGlhIg0KdGFibGExOSRQYcOtc1t0YWJsYTE5JFBhw61zID09ICJTcGFpbiJdIDwtICJFc3Bhw7FhIg0KdGFibGExOSRQYcOtc1t0YWJsYTE5JFBhw61zID09ICJUdXJrZXkiXSA8LSAiVHVycXXDrWEiDQp0YWJsYTE5JFBhw61zW3RhYmxhMTkkUGHDrXMgPT0gIkZyYW5jZSJdIDwtICJGcmFuY2lhIg0KdGFibGExOSRQYcOtc1t0YWJsYTE5JFBhw61zID09ICJHcmVlY2UiXSA8LSAiR3JlY2lhIg0KDQojIE5vIGhlIHBvZGlkbyBoYWNlciBmdW5jaW9uYXIgbGFzIGJhbmRlcmFzDQojIGFkZF9jb2x1bW4oYmFuZGVyYXMsIC5iZWZvcmUgPSAnZ2VvJykgJT4lIA0KICANCnRhYmxhMTkgJT4lIGd0KCkgJT4lDQogIHRhYl9oZWFkZXIodGl0bGUgPSBtZCgiKipQcm9kdWNjacOzbiBkZSBhbGNhY2hvZmFzIGVuIEV1cm9wYSoqIiksICANCiAgICAgICAgICAgIHN1YnRpdGxlID0gbWQoIkNhbnRpZGFkZXMgcHJvZHVjaWRhcyBlbiAyMDE5IikpJT4lDQogIHRhYl9zb3VyY2Vfbm90ZShtZCgiKEMpIEV1cm9HZW9ncmFwaGljcyBmb3IgdGhlIGFkbWluaXN0cmF0aXZlIGJvdW5kYXJpZXMiKSkgJT4lIA0KICB0YWJfb3B0aW9ucyhoZWFkaW5nLmJhY2tncm91bmQuY29sb3IgPSAiZGFya3JlZCIsIGNvbHVtbl9sYWJlbHMuZm9udC53ZWlnaHQgPSAiYm9sZCIpDQpgYGANCg0KDQojIyMgQ8OzZGlnbw0KDQpgYGB7ciBjb2Rlc3R1ZGlvMiBwMSwgZXZhbD0gRkFMU0UsIGVjaG89IFRSVUUsIHdhcm5pbmc9IEZBTFNFLCBjb21tZW50ID0gRkFMU0V9DQojIENhcmdhbW9zIGRhdG9zIHkgZ2VvbWV0csOtYXMNCmRhdG9zIDwtIHJpbzo6aW1wb3J0ICgnLi9kYXRvcy9hbGNhY2hvZmFzLmNzdicpDQpkYXRvczE5IDwtIGRhdG9zICU+JSBmaWx0ZXIodGltZSA9PSAnMjAxOScsIHN0cnVjcHJvX2NvZGUgPT0gJ1BSJykgJT4lIG11dGF0ZSAodmFsdWVzID0gYXMuaW50ZWdlcih2YWx1ZXMpKQ0KDQpnZW9tZXRyaWFzIDwtIGdldF9ldXJvc3RhdF9nZW9zcGF0aWFsKHJlc29sdXRpb24gPSAiMjAiLCBudXRzX2xldmVsID0gIjAiKQ0KDQptYXBkYXRhIDwtIGZ1bGxfam9pbihkYXRvcywgZ2VvbWV0cmlhcywgYnkgPSBjKCJnZW9fY29kZSIgPSAiaWQiKSkNCg0KcHJfMTkgPC0gbWFwZGF0YSAlPiUgZmlsdGVyIChzdHJ1Y3Byb19jb2RlID09ICdQUicsIHRpbWUgPT0gJzIwMTknKQ0KDQojLSBDcmVhbW9zIGdydXBvcyBzZWfDum4gbG9zIHZhbG9yZXMgcGFyYSBxdWUgcG9kZXIgbW9zdHJhcmxvcyBlbiBlbCBtYXBhLiBIZSB0ZW5pZG8gcXVlIGNvbnZlcnRpcmxvcyBlbiBlbnRlcm9zIHBvcnF1ZSBubyBjb25zZWd1w61hIHF1ZSBsZXllcmEgbG9zIG7Dum1lcm9zIGNvbiBkZWNpbWFsZXMNCnByXzE5IDwtIHByXzE5ICU+JSBtdXRhdGUgKHZhbHVlcyA9IGFzLmludGVnZXIodmFsdWVzKSkgJT4lDQogIG11dGF0ZShncnVwb3MgID0gY2FzZV93aGVuKCANCiAgdmFsdWVzICVpbiUgKDApIH4gIjAiLA0KICB2YWx1ZXMgJWluJSAoMToxMDApIH4gIjEtMTAwIiwNCiAgdmFsdWVzICVpbiUgKDEwMToyMDApIH4gIjEwMS0yMDAiLA0KICB2YWx1ZXMgJWluJSAoMjAxOjEwMDApIH4gJzIwMCBvIG3DoXMnKSkNCiAgDQojIE1hcGEgYXJlYSBjdWx0aXZhZGEgZW4gMjAxOSANCnAgPC0gZ2dwbG90KHByXzE5KSArDQogICAgIGdlb21fc2YoYWVzKGZpbGw9IGdydXBvcywgZ2VvbWV0cnkgPSBnZW9tZXRyeSksIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IC4xKSArDQogICAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiQnJCRyIpICArDQogICAgIGxhYnModGl0bGUgPSAiUHJvZHVjY2nDs24gZGUgYWxjYWNob2ZhcyBlbiAyMDE5IiwNCiAgICAgICBzdWJ0aXRsZSA9ICJFbiBtaWxlcyBkZSB0b25lbGFkYXMiLA0KICAgICAgIGZpbGwgPSAiTWlsZXMgZGUgdCIsDQogICAgICAgY2FwdGlvbiA9ICIoQykgRXVyb0dlb2dyYXBoaWNzIGZvciB0aGUgYWRtaW5pc3RyYXRpdmUgYm91bmRhcmllcyIpICsgdGhlbWVfbGlnaHQoKSArDQogICAgIGNvb3JkX3NmKHhsaW0gPSBjKC0yMCw0MyksIHlsaW0gPSBjKDM0LDY3KSkNCg0KcA0KYGBgDQoNCmBgYHtyIGNvZGVzdHVkaW8yIHAzLCBldmFsPSBGQUxTRSwgZWNobz0gVFJVRSwgd2FybmluZz0gRkFMU0UsIGNvbW1lbnQgPSBGQUxTRX0NCiMgVGFibGEgbWF5b3JlcyBwcm9kdWN0b3Jlcw0KDQppdGFseSA8LSAnLi9pbWFnZW5lcy9pdCcNCnNwYWluIDwtICcuL2ltYWdlbmVzL2VzJw0KdHVya2V5IDwtICcuL2ltYWdlbmVzL3RyJw0KZnJhbmNlIDwtICcuL2ltYWdlbmVzL2ZyJw0KZ3JlZWNlIDwtICcuL2ltYWdlbmVzL2dyJw0KYmFuZGVyYXMgPC0gYyhpdGFseSwgc3BhaW4sIHR1cmtleSwgZnJhbmNlLCBncmVlY2UpDQoNCg0KdGFibGExOSA8LSBkYXRvczE5ICU+JSBmaWx0ZXIgKHZhbHVlcyA8IDYwMCkgJT4lIHNlbGVjdCAoZ2VvLCB2YWx1ZXMpICAlPiUgDQogIHNsaWNlX21heCAodmFsdWVzLCBuID0gNSkgJT4lIGFycmFuZ2UgKCBkZXNjKHZhbHVlcykpICU+JSBtdXRhdGUodmFsdWVzPSBhcy5udW1lcmljKHZhbHVlcykpICU+JQ0KICByZW5hbWUoJ1Bhw61zJyA9IGdlbywgJ0NhbnRpZGFkIHByb2R1Y2lkYSAobWlsZXMgZGUgdCknID0gdmFsdWVzKQ0KDQp0YWJsYTE5JFBhw61zW3RhYmxhMTkkUGHDrXMgPT0gIkl0YWx5Il0gPC0gIkl0YWxpYSINCnRhYmxhMTkkUGHDrXNbdGFibGExOSRQYcOtcyA9PSAiU3BhaW4iXSA8LSAiRXNwYcOxYSINCnRhYmxhMTkkUGHDrXNbdGFibGExOSRQYcOtcyA9PSAiVHVya2V5Il0gPC0gIlR1cnF1w61hIg0KdGFibGExOSRQYcOtc1t0YWJsYTE5JFBhw61zID09ICJGcmFuY2UiXSA8LSAiRnJhbmNpYSINCnRhYmxhMTkkUGHDrXNbdGFibGExOSRQYcOtcyA9PSAiR3JlZWNlIl0gPC0gIkdyZWNpYSINCg0KIyBObyBoZSBwb2RpZG8gaGFjZXIgZnVuY2lvbmFyIGxhcyBiYW5kZXJhcw0KIyBhZGRfY29sdW1uKGJhbmRlcmFzLCAuYmVmb3JlID0gJ2dlbycpICU+JSANCg0KdGFibGExOSAlPiUgZ3QoKSAlPiUNCiAgdGFiX2hlYWRlcih0aXRsZSA9IG1kKCIqKlByb2R1Y2Npw7NuIGRlIGFsY2FjaG9mYXMgZW4gRXVyb3BhKioiKSwgIA0KICAgICAgICAgICAgc3VidGl0bGUgPSBtZCgiQ2FudGlkYWRlcyBwcm9kdWNpZGFzIGVuIDIwMTkiKSklPiUNCiAgdGFiX3NvdXJjZV9ub3RlKG1kKCIoQykgRXVyb0dlb2dyYXBoaWNzIGZvciB0aGUgYWRtaW5pc3RyYXRpdmUgYm91bmRhcmllcyIpKSAlPiUgDQogIHRhYl9vcHRpb25zKGhlYWRpbmcuYmFja2dyb3VuZC5jb2xvciA9ICJkYXJrcmVkIiwgY29sdW1uX2xhYmVscy5mb250LndlaWdodCA9ICJib2xkIikNCg0KYGBgDQogIA0KICANCiMjIDMuIFByb2R1Y2Npw7NuIGhpc3TDs3JpY2EgYWN1bXVsYWRhIHsudGFic2V0fQ0KICANCiMjIyBXb3JkY2xvdWQNCiAgDQpFc3RlIFdvcmRjbG91ZCBub3MgZGEgdW5hIHByaW1lcmEgaW1wcmVzacOzbiByw6FwaWRhIGRlIGxhIGVzY2FsYSBkZSBsb3MgKipuw7ptZXJvcyBkZSBwcm9kdWNjacOzbiBoaXN0w7NyaWNhKiouICANCkNvbW8gcG9kZW1vcyB2ZXIgKipFc3Bhw7FhIGUgSXRhbGlhKiogc29uIHByw6FjdGljYW1lbnRlIGxvcyDDum5pY29zIHByb2R1Y3RvcmVzLCBzZWd1aWRvcyBkZSAqKkZyYW5jaWEqKiBjb24gdW5hIHByb2R1Y2Npw7NuIG11Y2hvIG1lbm9yLiAgDQogIA0KYGBge3IgZXN0dWRpbzMgcDEsIGV2YWw9IFRSVUUsIGVjaG89IEZBTFNFLCB3YXJuaW5nPSBGQUxTRSwgY29tbWVudCA9IEZBTFNFfQ0KIyBDYXJnYW1vcyBkYXRvcyB5IGdlb21ldHLDrWFzDQpkYXRvcyA8LSByaW86OmltcG9ydCAoJy4vZGF0b3MvYWxjYWNob2Zhcy5jc3YnKQ0KZGF0b3NjdW0gPC0gZGF0b3MgJT4lIGZpbHRlcihzdHJ1Y3Byb19jb2RlID09ICdQUicpICU+JSBzZWxlY3QoZ2VvX2NvZGUsIGdlbywgdGltZSwgdmFsdWVzKSAlPiUNCiAgZ3JvdXBfYnkoZ2VvX2NvZGUpICU+JSBhcnJhbmdlKHRpbWUpICU+JSBtdXRhdGUoYWN1bSA9IGN1bXN1bSh2YWx1ZXMpKSAlPiUgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUgKGFjdW0gPSBhcy5udW1lcmljKGFjdW0pKQ0KDQojIHdvcmRjbG91ZA0KZGF0b3NmaW4gPC0gZGF0b3NjdW0gJT4lIGZpbHRlciAodGltZSA9PSAiMjAxOSIpICU+JSBzZWxlY3QgKGdlbywgYWN1bSkNCmRhdG9zZmluJGdlb1tkYXRvc2ZpbiRnZW8gPT0gIkl0YWx5Il0gPC0gIkl0YWxpYSINCmRhdG9zZmluJGdlb1tkYXRvc2ZpbiRnZW8gPT0gIlNwYWluIl0gPC0gIkVzcGHDsWEiDQpkYXRvc2ZpbiRnZW9bZGF0b3NmaW4kZ2VvID09ICJUdXJrZXkiXSA8LSAiVHVycXXDrWEiDQpkYXRvc2ZpbiRnZW9bZGF0b3NmaW4kZ2VvID09ICJGcmFuY2UiXSA8LSAiRnJhbmNpYSINCmRhdG9zZmluJGdlb1tkYXRvc2ZpbiRnZW8gPT0gIkdyZWVjZSJdIDwtICJHcmVjaWEiDQoNCndvcmRjbG91ZDIoZGF0b3NmaW4sIHNpemUgPSAxKQ0KDQpgYGANCiAgDQojIyMgTWFwYSBkZSBwcm9kdWNjacOzbiBhY3VtdWxhZGENCiAgDQpFbiBlc3RhIHNlY2Npw7NuIGhheSBxdWUgdGVuZXIgZW4gY3VlbnRhIHF1ZSBhbGd1bm9zIHBhw61zZXMsIGNvbW8gVHVycXXDrWEgcXVlIHRlbsOtYSBtw6FzIHByb2R1Y2Npw7NuIGVuIGxhIHNlY2Npw7NuIGFudGVyaW9yLCBubyB0aWVuZW4gZGF0b3MgcXVlIGxsZWd1ZW4gaGFzdGEgMTk2NC4gIA0KU2luIGVtYmFyZ28sIGxhIGdyYW4gZXNjYWxhIGRlIHByb2R1Y2Npw7NuIGRlICoqSXRhbGlhIHkgRXNwYcOxYSoqIG5vIGRlamEgbHVnYXIgYSBkdWRhcyBkZSBxdWUgc29uIGxvcyBtYXlvcmVzIHByb2R1Y3RvcmVzIGRlIGFsY2FjaG9mYXMgZGUgRXVyb3BhLCB0YW50byAqKmhpc3TDs3JpY2FtZW50ZSBjb21vIGVuIGxhIGFjdHVhbGlkYWQqKi4gIA0KICAgIA0KYGBge3IgZXN0dWRpbzMgcDIsIGV2YWw9IFRSVUUsIGVjaG89IEZBTFNFLCB3YXJuaW5nPSBGQUxTRSwgY29tbWVudCA9IEZBTFNFfQ0KIyBtYXBhDQoNCmdlb21ldHJpYXMgPC0gZ2V0X2V1cm9zdGF0X2dlb3NwYXRpYWwocmVzb2x1dGlvbiA9ICIyMCIsIG51dHNfbGV2ZWwgPSAiMCIpDQptYXBkYXRhIDwtIGZ1bGxfam9pbihkYXRvc2N1bSwgZ2VvbWV0cmlhcywgYnkgPSBjKCJnZW9fY29kZSIgPSAiaWQiKSkNCg0KcHJfYWN1bSA8LSBtYXBkYXRhICU+JSBmaWx0ZXIgKHRpbWUgPT0gJzIwMTknKSAlPiUgZmlsdGVyIChnZW9fY29kZSAhPSAnRVUnLCBnZW9fY29kZSAhPSAnRVUyN18yMDIwJywgZ2VvX2NvZGUgIT0gJ0VVMjgnKSAlPiUNCiAgbXV0YXRlKGFjdW09IGFzLm51bWVyaWMoYWN1bSkpDQoNCnByX2FjdW0gPC0gcHJfYWN1bSAlPiUgbXV0YXRlIChhY3VtID0gYXMuaW50ZWdlcihhY3VtKSkgJT4lDQogIG11dGF0ZShncnVwb3MgID0gY2FzZV93aGVuKCANCiAgYWN1bSAlaW4lICgwKSB+ICIwIiwNCiAgYWN1bSAlaW4lICgxOjEwMCkgfiAiMSBhIDEwMCIsDQogIGFjdW0gJWluJSAoMTAxOjEwMDApIH4gIjEwMCBhIDEwMDAiLA0KICBhY3VtICVpbiUgKDEwMDE6MTAwMDApIH4gJzEwMDAgYSAxMDAwMCcsDQogIGFjdW0gJWluJSAoMTAwMDE6MTAwMDAwKSB+ICcxMDAwMCBvIG3DoXMnICApKQ0KDQpwIDwtIGdncGxvdChwcl9hY3VtKSArDQogICAgIGdlb21fc2YoYWVzKGZpbGw9IGdydXBvcywgZ2VvbWV0cnkgPSBnZW9tZXRyeSksIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IC4xKSArDQogICAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUHVPciIpICArDQogICAgIGxhYnModGl0bGUgPSAiUHJvZHVjY2nDs24gZGUgYWxjYWNob2ZhcyBoaXN0w7NyaWNhIGFjdW11bGFkYSIsDQogICAgICAgc3VidGl0bGUgPSAiRGF0b3MgZGVzZGUgMTk2NCBoYXN0YSAyMDE5IiwNCiAgICAgICBmaWxsID0gIk1pbGVzIGRlIHQiLA0KICAgICAgIGNhcHRpb24gPSAiKEMpIEV1cm9HZW9ncmFwaGljcyBmb3IgdGhlIGFkbWluaXN0cmF0aXZlIGJvdW5kYXJpZXMiKSArIHRoZW1lX2xpZ2h0KCkgKw0KICAgICBjb29yZF9zZih4bGltID0gYygtMjAsNDMpLCB5bGltID0gYygzNCw2NykpDQpwDQoNCmBgYA0KDQpgYGB7ciBlc3R1ZGlvMyBwMywgZXZhbD0gVFJVRSwgZWNobz0gRkFMU0UsIHdhcm5pbmc9IEZBTFNFLCBjb21tZW50ID0gRkFMU0V9DQojIFRhYmxhIG1heW9yZXMgcHJvZHVjdG9yZXMgYWN1bXVsYWRvDQoNCnRhYmxhX2FjdW0gPC0gZGF0b3NjdW0gJT4lIGZpbHRlciAoZ2VvX2NvZGUgIT0gJ0VVJywgZ2VvX2NvZGUgIT0gJ0VVMjdfMjAyMCcsIGdlb19jb2RlICE9ICdFVTI4JywgdGltZSA9PSAnMjAxOScpICU+JSANCiAgc2VsZWN0IChnZW8sIGFjdW0pICAlPiUgDQogIHNsaWNlX21heCAoYWN1bSwgbiA9IDUpICU+JSBhcnJhbmdlICggZGVzYyhhY3VtKSkgJT4lIA0KICByZW5hbWUoJ1Bhw61zJyA9IGdlbywgJ0NhbnRpZGFkIHByb2R1Y2lkYSAobWlsZXMgZGUgdCknID0gYWN1bSkNCg0KdGFibGFfYWN1bSRQYcOtc1t0YWJsYV9hY3VtJFBhw61zID09ICJJdGFseSJdIDwtICJJdGFsaWEiDQp0YWJsYV9hY3VtJFBhw61zW3RhYmxhX2FjdW0kUGHDrXMgPT0gIlNwYWluIl0gPC0gIkVzcGHDsWEiDQp0YWJsYV9hY3VtJFBhw61zW3RhYmxhX2FjdW0kUGHDrXMgPT0gIlR1cmtleSJdIDwtICJUdXJxdcOtYSINCnRhYmxhX2FjdW0kUGHDrXNbdGFibGFfYWN1bSRQYcOtcyA9PSAiRnJhbmNlIl0gPC0gIkZyYW5jaWEiDQp0YWJsYV9hY3VtJFBhw61zW3RhYmxhX2FjdW0kUGHDrXMgPT0gIkdyZWVjZSJdIDwtICJHcmVjaWEiDQoNCiAgDQp0YWJsYV9hY3VtICU+JSBndCgpICU+JQ0KICB0YWJfaGVhZGVyKHRpdGxlID0gbWQoIioqUHJvZHVjY2nDs24gYWN1bXVsYWRhIGRlIGFsY2FjaG9mYXMgZW4gRXVyb3BhKioiKSwgIA0KICAgICAgICAgICAgc3VidGl0bGUgPSBtZCgiQ2FudGlkYWRlcyBwcm9kdWNpZGFzIGVudHJlIDE5NjQgeSAyMDE5IikpJT4lDQogIHRhYl9zb3VyY2Vfbm90ZShtZCgiKEMpIEV1cm9HZW9ncmFwaGljcyBmb3IgdGhlIGFkbWluaXN0cmF0aXZlIGJvdW5kYXJpZXMiKSkgJT4lIA0KICB0YWJfb3B0aW9ucyhoZWFkaW5nLmJhY2tncm91bmQuY29sb3IgPSAiZGFya3JlZCIsIGNvbHVtbl9sYWJlbHMuZm9udC53ZWlnaHQgPSAiYm9sZCIpDQpgYGANCg0KIyMjIEPDs2RpZ28NCg0KYGBge3IgY29kZXN0dWRpbzMgcDEsIGV2YWw9IEZBTFNFLCBlY2hvPSBUUlVFLCB3YXJuaW5nPSBGQUxTRSwgY29tbWVudCA9IEZBTFNFfQ0KIyBDYXJnYW1vcyBkYXRvcyB5IGdlb21ldHLDrWFzDQpkYXRvcyA8LSByaW86OmltcG9ydCAoJy4vZGF0b3MvYWxjYWNob2Zhcy5jc3YnKQ0KZGF0b3NjdW0gPC0gZGF0b3MgJT4lIGZpbHRlcihzdHJ1Y3Byb19jb2RlID09ICdQUicpICU+JSBzZWxlY3QoZ2VvX2NvZGUsIGdlbywgdGltZSwgdmFsdWVzKSAlPiUNCiAgZ3JvdXBfYnkoZ2VvX2NvZGUpICU+JSBhcnJhbmdlKHRpbWUpICU+JSBtdXRhdGUoYWN1bSA9IGN1bXN1bSh2YWx1ZXMpKSAlPiUgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUgKGFjdW0gPSBhcy5udW1lcmljKGFjdW0pKQ0KDQoNCiMgd29yZGNsb3VkDQpkYXRvc2ZpbiA8LSBkYXRvc2N1bSAlPiUgZmlsdGVyICh0aW1lID09ICIyMDE5IikgJT4lIHNlbGVjdCAoZ2VvLCBhY3VtKQ0KDQp3b3JkY2xvdWQyKGRhdG9zZmluKQ0KDQojIG1hcGENCg0KZ2VvbWV0cmlhcyA8LSBnZXRfZXVyb3N0YXRfZ2Vvc3BhdGlhbChyZXNvbHV0aW9uID0gIjIwIiwgbnV0c19sZXZlbCA9ICIwIikNCm1hcGRhdGEgPC0gZnVsbF9qb2luKGRhdG9zY3VtLCBnZW9tZXRyaWFzLCBieSA9IGMoImdlb19jb2RlIiA9ICJpZCIpKQ0KDQpwcl9hY3VtIDwtIG1hcGRhdGEgJT4lIGZpbHRlciAodGltZSA9PSAnMjAxOScpICU+JSBmaWx0ZXIgKGdlb19jb2RlICE9ICdFVScsIGdlb19jb2RlICE9ICdFVTI3XzIwMjAnLCBnZW9fY29kZSAhPSAnRVUyOCcpICU+JQ0KICBtdXRhdGUoYWN1bT0gYXMubnVtZXJpYyhhY3VtKSkNCg0KcHJfYWN1bSA8LSBwcl9hY3VtICU+JSBtdXRhdGUgKGFjdW0gPSBhcy5pbnRlZ2VyKGFjdW0pKSAlPiUNCiAgbXV0YXRlKGdydXBvcyAgPSBjYXNlX3doZW4oIA0KICBhY3VtICVpbiUgKDApIH4gIjAiLA0KICBhY3VtICVpbiUgKDE6MTAwKSB+ICIxIGEgMTAwIiwNCiAgYWN1bSAlaW4lICgxMDE6MTAwMCkgfiAiMTAwIGEgMTAwMCIsDQogIGFjdW0gJWluJSAoMTAwMToxMDAwMCkgfiAnMTAwMCBhIDEwMDAwJywNCiAgYWN1bSAlaW4lICgxMDAwMToxMDAwMDApIH4gJzEwMDAwIG8gbcOhcycgICkpDQoNCnAgPC0gZ2dwbG90KHByX2FjdW0pICsNCiAgICAgZ2VvbV9zZihhZXMoZmlsbD0gZ3J1cG9zLCBnZW9tZXRyeSA9IGdlb21ldHJ5KSwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gLjEpICsNCiAgICAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJQdU9yIikgICsNCiAgICAgbGFicyh0aXRsZSA9ICJQcm9kdWNjacOzbiBkZSBhbGNhY2hvZmFzIGhpc3TDs3JpY2EgYWN1bXVsYWRhIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJEYXRvcyBkZXNkZSAxOTY0IGhhc3RhIDIwMTkiLA0KICAgICAgIGZpbGwgPSAiTWlsZXMgZGUgdCIsDQogICAgICAgY2FwdGlvbiA9ICIoQykgRXVyb0dlb2dyYXBoaWNzIGZvciB0aGUgYWRtaW5pc3RyYXRpdmUgYm91bmRhcmllcyIpICsgdGhlbWVfbGlnaHQoKSArDQogICAgIGNvb3JkX3NmKHhsaW0gPSBjKC0yMCw0MyksIHlsaW0gPSBjKDM0LDY3KSkNCnANCmBgYA0KDQpgYGB7ciBjb2Rlc3R1ZGlvMyBwMiwgZXZhbD0gRkFMU0UsIGVjaG89IFRSVUUsIHdhcm5pbmc9IEZBTFNFLCBjb21tZW50ID0gRkFMU0V9DQojIFRhYmxhIG1heW9yZXMgcHJvZHVjdG9yZXMgYWN1bXVsYWRvDQoNCnRhYmxhX2FjdW0gPC0gZGF0b3NjdW0gJT4lIGZpbHRlciAoZ2VvX2NvZGUgIT0gJ0VVJywgZ2VvX2NvZGUgIT0gJ0VVMjdfMjAyMCcsIGdlb19jb2RlICE9ICdFVTI4JywgdGltZSA9PSAnMjAxOScpICU+JSANCiAgc2VsZWN0IChnZW8sIGFjdW0pICAlPiUgDQogIHNsaWNlX21heCAoYWN1bSwgbiA9IDUpICU+JSBhcnJhbmdlICggZGVzYyhhY3VtKSkgJT4lIA0KICByZW5hbWUoJ1Bhw61zJyA9IGdlbywgJ0NhbnRpZGFkIHByb2R1Y2lkYSAobWlsZXMgZGUgdCknID0gYWN1bSkNCg0KdGFibGFfYWN1bSRQYcOtc1t0YWJsYV9hY3VtJFBhw61zID09ICJJdGFseSJdIDwtICJJdGFsaWEiDQp0YWJsYV9hY3VtJFBhw61zW3RhYmxhX2FjdW0kUGHDrXMgPT0gIlNwYWluIl0gPC0gIkVzcGHDsWEiDQp0YWJsYV9hY3VtJFBhw61zW3RhYmxhX2FjdW0kUGHDrXMgPT0gIlR1cmtleSJdIDwtICJUdXJxdcOtYSINCnRhYmxhX2FjdW0kUGHDrXNbdGFibGFfYWN1bSRQYcOtcyA9PSAiRnJhbmNlIl0gPC0gIkZyYW5jaWEiDQp0YWJsYV9hY3VtJFBhw61zW3RhYmxhX2FjdW0kUGHDrXMgPT0gIkdyZWVjZSJdIDwtICJHcmVjaWEiDQoNCiAgDQp0YWJsYV9hY3VtICU+JSBndCgpICU+JQ0KICB0YWJfaGVhZGVyKHRpdGxlID0gbWQoIioqUHJvZHVjY2nDs24gYWN1bXVsYWRhIGRlIGFsY2FjaG9mYXMgZW4gRXVyb3BhKioiKSwgIA0KICAgICAgICAgICAgc3VidGl0bGUgPSBtZCgiQ2FudGlkYWRlcyBwcm9kdWNpZGFzIGVudHJlIDE5NjQgeSAyMDE5IikpJT4lDQogIHRhYl9zb3VyY2Vfbm90ZShtZCgiKEMpIEV1cm9HZW9ncmFwaGljcyBmb3IgdGhlIGFkbWluaXN0cmF0aXZlIGJvdW5kYXJpZXMiKSkgJT4lIA0KICB0YWJfb3B0aW9ucyhoZWFkaW5nLmJhY2tncm91bmQuY29sb3IgPSAiZGFya3JlZCIsIGNvbHVtbl9sYWJlbHMuZm9udC53ZWlnaHQgPSAiYm9sZCIpDQpgYGANCiAgDQoNCiMjIDQuIFByb2R1Y2Npw7NuIGVuIEVzcGHDsWEgey50YWJzZXR9DQoNCmBgYHtyLCBlY2hvID0gRkFMU0V9DQojIENhcmdhbW9zIGRhdG9zIHkgZ2VvbWV0csOtYXMNCmRhdG9zIDwtIHJpbzo6aW1wb3J0ICgnLi9kYXRvcy9hbGNhY2hvZmFzLmNzdicpDQoNCnByX2VzcCA8LSBkYXRvcyAlPiUgZmlsdGVyKHN0cnVjcHJvX2NvZGUgPT0gJ1BSJywgZ2VvX2NvZGUgPT0gJ0VTJykgJT4lIHNlbGVjdChnZW9fY29kZSwgZ2VvLCB0aW1lLCB2YWx1ZXMpICU+JQ0KICBncm91cF9ieShnZW9fY29kZSkgJT4lIGFycmFuZ2UodGltZSkgJT4lIG11dGF0ZShhY3VtID0gY3Vtc3VtKHZhbHVlcykpICU+JSB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSAoYWN1bSA9IGFzLm51bWVyaWMoYWN1bSkpICU+JSByZW5hbWUocHJvZCA9IHZhbHVlcywgcHJzdW0gPSBhY3VtKQ0KDQphcl9lc3AgPC0gZGF0b3MgJT4lIGZpbHRlcihzdHJ1Y3Byb19jb2RlID09ICdBUicsIGdlb19jb2RlID09ICdFUycpICU+JSBzZWxlY3QoZ2VvX2NvZGUsIGdlbywgdGltZSwgdmFsdWVzKSAlPiUNCiAgZ3JvdXBfYnkoZ2VvX2NvZGUpICU+JSBhcnJhbmdlKHRpbWUpICU+JSByZW5hbWUgKGFyZWEgPSB2YWx1ZXMpDQoNCmVzcCA8LSBmdWxsX2pvaW4ocHJfZXNwLCBhcl9lc3ApDQplc3AgPC0gZXNwICU+JSBtdXRhdGUgKHByb2R4aGEgPSBwcm9kL2FyZWEpDQpgYGANCg0KIyMjIMOBcmVhDQogIA0KQ29tbyBwb2RlbW9zIHZlciByZXByZXNlbnRhZGEgcG9yIGxhIGxpbmVhIGFtYXJpbGxhLCBlbCDDoXJlYSB1dGlsaXphZGEgZW4gRXNwYcOxYSBwYXJhIGVsIGN1bHRpdm8gZGUgYWxhY2hvZmFzIGZ1ZSBzdWJpZW5kbyBoYXN0YSAxOTkwLCBkb25kZSBhbGNhbnrDsyB1biBwaWNvIGRlIGFwcm94aW1hbmRhbWVudGUgKiozMi4wMDAgaGVjdMOhcmVhcyoqLg0KICANCkFjdHVhbG1lbnRlIGVsIMOhcmVhIHV0aWxpemFkYSByb25kYSBsYXMgKioxNS4wMDAgaGVjdMOhcmVhcyoqLg0KICANCkxhIGxpbmVhIHZlcmRlIHJlcHJlc2VudGEgbGEgKipwcm9kdWNjacOzbiBkZSBhbGNhY2hvZmFzIHBvciBoZWN0w6FyZWEqKiwgc2llbmRvIGxhIHByb2R1Y2Npw7NuIGVuICoqdG9uZWxhZGFzIGRlIGFsY2FjaG9mYXMqKi4gRXN0YSBsaW5lYSB0YW1iacOpbiBsYSBwb2RlbW9zIGVuY29udHJhciBlbiBlbCBzaWd1aWVudGUgZ3LDoWZpY28uICAgDQoNCmBgYHtyLCBlY2hvID0gRkFMU0V9DQojLSBHcsOhZmljbyDDoXJlYQ0KcDEgPC0gZ2dwbG90KGVzcCkgKw0KICAgICAgZ2VvbV9saW5lKGFlcyh4ID0gdGltZSwgeSA9IGFyZWEpLCBhbHBoYSA9IDAuNywgc2l6ZSA9IDEuNywgY29sb3IgPSAieWVsbG93IikgKw0KICAgICAgZ2VvbV9saW5lKGFlcyh4ID0gdGltZSwgeSA9IHByb2R4aGEpLCBhbHBoYSA9IDAuNywgc2l6ZSA9IDEuNywgY29sb3IgPSAiZ3JlZW4iKSArDQogICAgICBzY2FsZV9jb2xvcl92aXJpZGlzX2QoKSArDQogICAgIGxhYnMoeCA9ICJBw7FvIiwgDQogICAgICAgeSA9ICLDgXJlYSB1dGlsaXphZGEgKG1pbGVzIGRlIEhhKSIsDQogICAgICAgdGl0bGU9ICfDgXJlYSBkZWRpY2FjYWRhIGFsIGN1bHRpdm8gZGUgYWxjYWNob2ZhcyBlbiB7ZnJhbWVfYWxvbmd9JywgDQogICAgICAgc3VidGl0bGUgPSAnRGF0b3MgZGUgMTk2NCBhIDIwMTknLCANCiAgICAgICBjYXB0aW9uID0gJyhDKSBFdXJvR2VvZ3JhcGhpY3MgZm9yIHRoZSBhZG1pbmlzdHJhdGl2ZSBib3VuZGFyaWVzJykgKyANCiAgICAgdHJhbnNpdGlvbl9yZXZlYWwodGltZSkNCg0KcDENCg0KYGBgDQoNCg0KIyMjIFByb2R1Y2Npw7NuDQogIA0KRW4gY29uY29yZGFuY2lhIGNvbiBlbCDDoXJlYSB1dGlsaXphZGEsIGxhIHByb2R1Y2Npw7NuIGRlIGFsY2FjaG9mYXMgZW4gRXNwYcOxYSB0YW1iacOpbiBhbGNhbnpvIHVuIHBpY28gZW4gbG9zIGHDsW9zIDkwLCBwcm9kdWNpZW5kbyAqKjQ0MC4wMDAgdG9uZWxhZGFzIGRlIGFsY2FjaG9mYXMqKi4gICANCkxvcyBkYXRvcyBtw6FzIHJlY2llbnRlcyAoMjAxOSkgbXVlc3RyYW4gdW5hIHByb2R1Y2Npw7NuIGRlICoqMTk5LjAwMCB0b25lbGFkYXMgZGUgYWxjYWNob2ZhcyoqLCBtZW5vcyBkZSBsYSBtaXRhZCBxdWUgbGFzIHByb2R1Y2lkYXMgZW4gZWwgcGljbyBkZSBwcm9kdWNjacOzbiwgcGVybyB0b2RhdsOtYSBzaWVuZG8gdW5hIGNhbnRpZGFkIG11eSByZXNwZXRhYmxlLCBzb2xvIHN1cGVyYWRhIHBvciBJdGFsaWEuICANCiAgDQpMYSBsaW5lYSB2ZXJkZSByZXByZXNlbnRhIGxhICoqcHJvZHVjY2nDs24gZGUgYWxjYWNob2ZhcyBwb3IgaGVjdMOhcmVhKiosIHNpZW5kbyBsYSBwcm9kdWNjacOzbiBlbiAqKnRvbmVsYWRhcyBkZSBhbGNhY2hvZmFzKiouDQogICAgDQpgYGB7ciwgZWNobyA9IEZBTFNFfQ0KIy0gR3LDoWZpY28gcHJvZHVjY2nDs24gYW51YWwNCnAyIDwtIGdncGxvdChlc3ApICsNCiAgICAgIGdlb21fbGluZShhZXMoeCA9IHRpbWUsIHkgPSBwcm9kKSwgYWxwaGEgPSAwLjcsIHNpemUgPSAxLjcsIGNvbG9yID0gInJlZCIpICsNCiAgICAgIGdlb21fbGluZShhZXMoeCA9IHRpbWUsIHkgPSBwcm9keGhhKSwgYWxwaGEgPSAwLjcsIHNpemUgPSAxLjcsIGNvbG9yID0gImdyZWVuIikgKw0KICAgICAgc2NhbGVfY29sb3JfdmlyaWRpc19kKCkgKw0KICAgICBsYWJzKHggPSAiQcOxbyIsIA0KICAgICAgIHkgPSAiUHJvZHVjY2nDs24gKG1pbGVzIGRlIHQpIiwNCiAgICAgICB0aXRsZT0gJ1Byb2R1Y2Npw7NuIGRlIGFsY2FjaG9mYXMgZW4gRXNwYcOxYSBlbiB7ZnJhbWVfYWxvbmd9JywgDQogICAgICAgc3VidGl0bGUgPSAnRGF0b3MgZGUgMTk2NCBhIDIwMTknLCANCiAgICAgICBjYXB0aW9uID0gJyhDKSBFdXJvR2VvZ3JhcGhpY3MgZm9yIHRoZSBhZG1pbmlzdHJhdGl2ZSBib3VuZGFyaWVzJykgKyANCiAgICAgdHJhbnNpdGlvbl9yZXZlYWwodGltZSkNCnAyIA0KYGBgDQoNCiMjIyBQcm9kdWNjacOzbiBhY3VtdWxhZGENCiAgDQpMYSBwcm9kdWNjacOzbiBoaXN0w7NyaWNhIGFjdW11bGFkYSBoYSBpZG8gZW4gdW4gYXNjZW5zbyBjb250aW51byBoYXN0YSBob3kuICANCkNvbiBsb3MgZGF0b3MgbcOhcyByZWNpZW50ZXMgcG9kZW1vcyB2ZXIgcXVlIEVzcGHDsWEgaGEgcHJvZHVjaWRvICoqMTQuMjMzLjAwMCB0b25lbGFkYXMgZGUgYWxjYWNob2ZhcyoqIGRlc2RlIDE5NjQsIHVuYSBjaWZyYSBiYXN0YW50ZSBpbXByZXNpb25hbnRlIHkgc29sbyBzdXBlcmFkYSBwb3IgSXRhbGlhLiANCiAgDQpgYGB7ciwgZWNobyA9IEZBTFNFfQ0KIy0gR3LDoWZpY28gcHJvZHVjY2nDs24gYWN1bXVsYWRhDQpwMyA8LSBnZ3Bsb3QoZXNwKSArDQogICAgICBnZW9tX2xpbmUoYWVzKHggPSB0aW1lLCB5ID0gcHJzdW0pLCBhbHBoYSA9IDAuNywgc2l6ZSA9IDEuNywgY29sb3IgPSAiYmx1ZSIpICsNCiAgICAgIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZCgpICsNCiAgICAgbGFicyh4ID0gIkHDsW8iLCANCiAgICAgICB5ID0gIlByb2R1Y2Npw7NuIChtaWxlcyBkZSB0KSIsDQogICAgICAgdGl0bGU9ICdQcm9kdWNjacOzbiBhY3VtdWxhZGEgZW4gRXNwYcOxYSBlbiB7ZnJhbWVfYWxvbmd9JywgDQogICAgICAgc3VidGl0bGUgPSAnRGF0b3MgZGUgMTk2NCBhIDIwMTknLCANCiAgICAgICBjYXB0aW9uID0gJyhDKSBFdXJvR2VvZ3JhcGhpY3MgZm9yIHRoZSBhZG1pbmlzdHJhdGl2ZSBib3VuZGFyaWVzJykgKyANCiAgICAgIHRyYW5zaXRpb25fcmV2ZWFsKHRpbWUpDQoNCnAzDQpgYGANCg0KDQojIyMgQ8OzZGlnbw0KDQpgYGB7ciwgZXZhbD0gRkFMU0UsIGVjaG8gPSBUUlVFfQ0KIyBDYXJnYW1vcyBkYXRvcyB5IGdlb21ldHLDrWFzDQpkYXRvcyA8LSByaW86OmltcG9ydCAoJy4vZGF0b3MvYWxjYWNob2Zhcy5jc3YnKQ0KDQpwcl9lc3AgPC0gZGF0b3MgJT4lIGZpbHRlcihzdHJ1Y3Byb19jb2RlID09ICdQUicsIGdlb19jb2RlID09ICdFUycpICU+JSBzZWxlY3QoZ2VvX2NvZGUsIGdlbywgdGltZSwgdmFsdWVzKSAlPiUNCiAgZ3JvdXBfYnkoZ2VvX2NvZGUpICU+JSBhcnJhbmdlKHRpbWUpICU+JSBtdXRhdGUoYWN1bSA9IGN1bXN1bSh2YWx1ZXMpKSAlPiUgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUgKGFjdW0gPSBhcy5udW1lcmljKGFjdW0pKSAlPiUgcmVuYW1lKHByb2QgPSB2YWx1ZXMsIHByc3VtID0gYWN1bSkNCg0KYXJfZXNwIDwtIGRhdG9zICU+JSBmaWx0ZXIoc3RydWNwcm9fY29kZSA9PSAnQVInLCBnZW9fY29kZSA9PSAnRVMnKSAlPiUgc2VsZWN0KGdlb19jb2RlLCBnZW8sIHRpbWUsIHZhbHVlcykgJT4lDQogIGdyb3VwX2J5KGdlb19jb2RlKSAlPiUgYXJyYW5nZSh0aW1lKSAlPiUgcmVuYW1lIChhcmVhID0gdmFsdWVzKQ0KDQplc3AgPC0gZnVsbF9qb2luKHByX2VzcCwgYXJfZXNwKQ0KZXNwIDwtIGVzcCAlPiUgbXV0YXRlIChwcm9keGhhID0gcHJvZC9hcmVhKQ0KDQoNCiMtIEdyw6FmaWNvIMOhcmVhDQpwMSA8LSBnZ3Bsb3QoZXNwKSArDQogICAgICBnZW9tX2xpbmUoYWVzKHggPSB0aW1lLCB5ID0gYXJlYSksIGFscGhhID0gMC43LCBzaXplID0gMS43LCBjb2xvciA9ICJ5ZWxsb3ciKSArDQogICAgICBnZW9tX2xpbmUoYWVzKHggPSB0aW1lLCB5ID0gcHJvZHhoYSksIGFscGhhID0gMC43LCBzaXplID0gMS43LCBjb2xvciA9ICJncmVlbiIpICsNCiAgICAgIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZCgpICsNCiAgICAgbGFicyh4ID0gIkHDsW8iLCANCiAgICAgICB5ID0gIsOBcmVhIHV0aWxpemFkYSAobWlsZXMgZGUgSGEpIiwNCiAgICAgICB0aXRsZT0gJ8OBcmVhIGRlZGljYWNhZGEgYWwgY3VsdGl2byBkZSBhbGNhY2hvZmFzIGVuIHtmcmFtZV9hbG9uZ30nLCANCiAgICAgICBzdWJ0aXRsZSA9ICdEYXRvcyBkZSAxOTY0IGEgMjAxOScsIA0KICAgICAgIGNhcHRpb24gPSAnKEMpIEV1cm9HZW9ncmFwaGljcyBmb3IgdGhlIGFkbWluaXN0cmF0aXZlIGJvdW5kYXJpZXMnKSArIA0KICAgICB0cmFuc2l0aW9uX3JldmVhbCh0aW1lKQ0KDQpwMQ0KDQojLSBHcsOhZmljbyBwcm9kdWNjacOzbiBhbnVhbA0KcDIgPC0gZ2dwbG90KGVzcCkgKw0KICAgICAgZ2VvbV9saW5lKGFlcyh4ID0gdGltZSwgeSA9IHByb2QpLCBhbHBoYSA9IDAuNywgc2l6ZSA9IDEuNywgY29sb3IgPSAicmVkIikgKw0KICAgICAgc2NhbGVfY29sb3JfdmlyaWRpc19kKCkgKw0KICAgICBsYWJzKHggPSAiQcOxbyIsIA0KICAgICAgIHkgPSAiUHJvZHVjY2nDs24gKG1pbGVzIGRlIHQpIiwNCiAgICAgICB0aXRsZT0gJ1Byb2R1Y2Npw7NuIGRlIGFsY2FjaG9mYXMgZW4gRXNwYcOxYSBlbiB7ZnJhbWVfYWxvbmd9JywgDQogICAgICAgc3VidGl0bGUgPSAnRGF0b3MgZGUgMTk2NCBhIDIwMTknLCANCiAgICAgICBjYXB0aW9uID0gJyhDKSBFdXJvR2VvZ3JhcGhpY3MgZm9yIHRoZSBhZG1pbmlzdHJhdGl2ZSBib3VuZGFyaWVzJykgKyANCiAgICAgdHJhbnNpdGlvbl9yZXZlYWwodGltZSkNCnAyIA0KDQoNCiMtIEdyw6FmaWNvIHByb2R1Y2Npw7NuIGFjdW11bGFkYQ0KcDMgPC0gZ2dwbG90KGVzcCkgKw0KICAgICAgZ2VvbV9saW5lKGFlcyh4ID0gdGltZSwgeSA9IHByc3VtKSwgYWxwaGEgPSAwLjcsIHNpemUgPSAxLjcsIGNvbG9yID0gImJsdWUiKSArDQogICAgICBzY2FsZV9jb2xvcl92aXJpZGlzX2QoKSArDQogICAgIGxhYnMoeCA9ICJBw7FvIiwgDQogICAgICAgeSA9ICJQcm9kdWNjacOzbiAobWlsZXMgZGUgdCkiLA0KICAgICAgIHRpdGxlPSAnUHJvZHVjY2nDs24gYWN1bXVsYWRhIGVuIEVzcGHDsWEgZW4ge2ZyYW1lX2Fsb25nfScsIA0KICAgICAgIHN1YnRpdGxlID0gJ0RhdG9zIGRlIDE5NjQgYSAyMDE5JywgDQogICAgICAgY2FwdGlvbiA9ICcoQykgRXVyb0dlb2dyYXBoaWNzIGZvciB0aGUgYWRtaW5pc3RyYXRpdmUgYm91bmRhcmllcycpICsgDQogICAgICB0cmFuc2l0aW9uX3JldmVhbCh0aW1lKQ0KDQpwMw0KDQoNCiMgR3LDoWZpY28gaW50ZXJhY3Rpdm8gdG9kbyAtPiBFc3RlIGdyw6FmaWNvIHNlIG11ZXN0cmEgZW4gbGEgc2lndWllbnRlIHNlY2Npw7NuIA0KDQpwNCA8LSBnZ3Bsb3QoZXNwLCBhZXMoeCA9IHRpbWUpKSArDQogICAgICBnZW9tX2xpbmUoYWVzKHkgPSBwcm9kKSwgYWxwaGEgPSAwLjcsIHNpemUgPSAxLjcsIGNvbG9yID0gInJlZCIpICsNCiAgICAgIGdlb21fbGluZShhZXMoeSA9IGFyZWEpLCBhbHBoYSA9IDAuNywgc2l6ZSA9IDEuNywgY29sb3IgPSAieWVsbG93IikgKw0KICAgICAgZ2VvbV9saW5lKGFlcyh5ID0gcHJvZHhoYSApLCBhbHBoYSA9IDAuNywgc2l6ZSA9IDEuNywgY29sb3IgPSAiZ3JlZW4iKSArDQogICAgIGxhYnMoeCA9ICJBw7FvIiwgDQogICAgICAgeSA9ICJQcm9kdWNjacOzbiAobWlsZXMgZGUgdCkgLyDDgXJlYSAobWlsZXMgZGUgSGEpIiwNCiAgICAgICB0aXRsZT0gJ1Byb2R1Y2Npw7NuIGRlIGFsY2FjaG9mYXMgeSDDoXJlYSB1dGlsaXphZGEgZW4gRXNwYcOxYScsIA0KICAgICAgIHN1YnRpdGxlID0gJ0RhdG9zIGRlIDE5NjQgYSAyMDE5JywgDQogICAgICAgY2FwdGlvbiA9ICcoQykgRXVyb0dlb2dyYXBoaWNzIGZvciB0aGUgYWRtaW5pc3RyYXRpdmUgYm91bmRhcmllcycpIA0KDQpnZ3Bsb3RseShwNCkNCmBgYA0KDQoNCg0KIyMgNS4gR3LDoWZpY28gcmVzdW1lbiBkYXRvcyBkZSBFc3Bhw7FhDQogIA0KRW4gZXN0ZSAqKmdyw6FmaWNvIGludGVyYWN0aXZvKiogcG9kZW1vcyB2ZXIgdW4gcmVzdW1lbiBkZSBsb3MgZGF0b3MgZGUgRXNwYcOxYSwgcHVkaWVuZG8gdmVyIGVsIGRldGFsbGUgZGUgcHJvZHVjY2nDs24sIMOhcmVhIGRlZGljYWRhIGEgbGEgcHJvZHVjY2nDs24geSBwcm9kdWNjacOzbiBwb3IgaGVjdMOhcmVhLiAgIA0KICANCkxhIDxGT05UIENPTE9SPSJyZWQiPioqbMOtbmVhIHJvamEqKjwvRk9OVD4gcmVwcmVzZW50YSBsYSAqKlByb2R1Y2Npw7NuIGRlIGFsY2hvZmFzKiogYSBsbyBsYXJnbyBkZSBsb3MgYcOxb3MsIGVuIG1pbGVzIGRlIHRvbmVsYWRhcy4gIA0KICANCkxhIDxGT05UIENPTE9SPSJ5ZWxsb3ciPioqbMOtbmVhIGFtYXJpbGxhKio8L0ZPTlQ+IHJlcHJlc2VudGEgZWwgKirDgXJlYSBkZWRpY2FkYSBhbCBjdWx0aXZvIGRlIGFsY2FjaG9mYXMqKiwgZW4gbWlsZXMgZGUgaGVjdMOhcmVhcy4gDQogIA0KTGEgPEZPTlQgQ09MT1I9ImdyZWVuIj4qKmzDrW5lYSB2ZXJkZSoqPC9GT05UPiByZXByZXNlbnRhIGxhICoqUHJvZHVjY2nDs24gcG9yIGhlY3TDoXJlYSoqLCBlbiB0b25lbGFkYXMgcG9yIGhlY3TDoXJlYS4gIA0KDQpQb2RlbW9zIGRlc3BsYXphcm5vcyBwb3IgbGFzIGxpbmVhcyBwYXJhIHZlciBsYSBpbmZvcm1hY2nDs24gZGV0YWxsYWRhIGRlIGNhZGEgYcOxby4NCiAgDQpgYGB7ciwgZXZhbD0gVFJVRSwgZWNobyA9IEZBTFNFIH0NCiMgQ2FyZ2Ftb3MgZGF0b3MgeSBnZW9tZXRyw61hcw0KZGF0b3MgPC0gcmlvOjppbXBvcnQgKCcuL2RhdG9zL2FsY2FjaG9mYXMuY3N2JykNCg0KcHJfZXNwIDwtIGRhdG9zICU+JSBmaWx0ZXIoc3RydWNwcm9fY29kZSA9PSAnUFInLCBnZW9fY29kZSA9PSAnRVMnKSAlPiUgc2VsZWN0KGdlb19jb2RlLCBnZW8sIHRpbWUsIHZhbHVlcykgJT4lDQogIGdyb3VwX2J5KGdlb19jb2RlKSAlPiUgYXJyYW5nZSh0aW1lKSAlPiUgbXV0YXRlKGFjdW0gPSBjdW1zdW0odmFsdWVzKSkgJT4lIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlIChhY3VtID0gYXMubnVtZXJpYyhhY3VtKSkgJT4lIHJlbmFtZShwcm9kID0gdmFsdWVzLCBwcnN1bSA9IGFjdW0pDQoNCmFyX2VzcCA8LSBkYXRvcyAlPiUgZmlsdGVyKHN0cnVjcHJvX2NvZGUgPT0gJ0FSJywgZ2VvX2NvZGUgPT0gJ0VTJykgJT4lIHNlbGVjdChnZW9fY29kZSwgZ2VvLCB0aW1lLCB2YWx1ZXMpICU+JQ0KICBncm91cF9ieShnZW9fY29kZSkgJT4lIGFycmFuZ2UodGltZSkgJT4lIHJlbmFtZSAoYXJlYSA9IHZhbHVlcykNCg0KZXNwIDwtIGZ1bGxfam9pbihwcl9lc3AsIGFyX2VzcCkNCmVzcCA8LSBlc3AgJT4lIG11dGF0ZSAocHJvZHhoYSA9IHByb2QvYXJlYSkNCg0KcDQgPC0gZ2dwbG90KGVzcCwgYWVzKHggPSB0aW1lKSkgKw0KICAgICAgZ2VvbV9saW5lKGFlcyh5ID0gcHJvZCksIGFscGhhID0gMC43LCBzaXplID0gMS43LCBjb2xvciA9ICJyZWQiKSArDQogICAgICBnZW9tX2xpbmUoYWVzKHkgPSBhcmVhKSwgYWxwaGEgPSAwLjcsIHNpemUgPSAxLjcsIGNvbG9yID0gInllbGxvdyIpICsNCiAgICAgIGdlb21fbGluZShhZXMoeSA9IHByb2R4aGEgKSwgYWxwaGEgPSAwLjcsIHNpemUgPSAxLjcsIGNvbG9yID0gImdyZWVuIikgKw0KICAgICBsYWJzKHggPSAiQcOxbyIsIA0KICAgICAgIHkgPSAiUHJvZHVjY2nDs24gKG1pbGVzIGRlIHQpIC8gw4FyZWEgKG1pbGVzIGRlIEhhKSIsDQogICAgICAgdGl0bGU9ICdQcm9kdWNjacOzbiBkZSBhbGNhY2hvZmFzIHkgw6FyZWEgdXRpbGl6YWRhIGVuIEVzcGHDsWEnLCANCiAgICAgICBzdWJ0aXRsZSA9ICdEYXRvcyBkZSAxOTY0IGEgMjAxOScsIA0KICAgICAgIGNhcHRpb24gPSAnKEMpIEV1cm9HZW9ncmFwaGljcyBmb3IgdGhlIGFkbWluaXN0cmF0aXZlIGJvdW5kYXJpZXMnKSANCg0KZ2dwbG90bHkocDQpDQoNCmBgYA0KDQojIElWLiBDb25jbHVzaW9uZXMNCiAgDQpBIHBhcnRpciBkZSBsb3MgZGF0b3MgcG9kZW1vcyBjb25jbHVpciByYXBpZGFtZW50ZSBxdWUgKipFc3Bhw7FhKiogZXMgdW5vIGRlIGxvcyBtYXlvcmVzIHByb2R1Y3RvcmVzIGRlIGFsY2FjaG9mYXMgZGUgRXVyb3BhLCBzdXBlcmFkbyBzb2xvIHBvciAqKkl0YWxpYSoqLg0KDQpFcyByYXpvbmFibGUgYXN1bWlyIHF1ZSAqKkl0YWxpYSB5IEVzcGHDsWEqKiBzb24gbG9zIHByaW5jaXBhbGVzIHN1bWluaXN0cmFkb3JlcyBkZSBhbGNhY2hvZmFzIGFsIHJlc3RvIGRlIHBhaXNlcyBkZSBFdXJvcGEsIHNvYnJldG9kbyBhIGxvcyBwYcOtc2VzIGRlbCBlc3BhY2lvIFNjaGVuZ2VuIGRlIGxpYnJlIG1lcmNhZG8uIA0KDQpgYGB7ciBhbGNhY2hvZmEyLCBldmFsID0gVFJVRSwgZWNobyA9IEZBTFNFfQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoJy4vaW1hZ2VuZXMvYWxjYWNob2ZhLmpwZycpDQpgYGANCg0KICANCiMgVi4gQmlibGlvZ3JhZsOtYQ0KICANCiAgLSBEYXRvcyBkZSBFdXJvc3RhdDogPGh0dHBzOi8vZWMuZXVyb3BhLmV1L2V1cm9zdGF0L3dlYi9hZ3JpY3VsdHVyZS9kYXRhL2RhdGFiYXNlPg0KICAtIFDDoWdpbmEgV2ViIGRlbCBwcm9mZXNvciBQZWRybyBQw6lyZXo6IDxodHRwczovL3BlcmV6cDQ0LmdpdGh1Yi5pby9pbnRyby1kcy0yMC0yMS13ZWIvPiANCiAgLSBDb25zdWx0YXMgZW4gU3RhY2sgb3ZlcmZsb3c6IDxodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy81ODI0MTczL3JlcGxhY2UtYS12YWx1ZS1pbi1hLWRhdGEtZnJhbWUtYmFzZWQtb24tYS1jb25kaXRpb25hbC1pZi1zdGF0ZW1lbnQ+DQogIA0KICANCiAg