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í.
1. INTRODUCCIÓN
En el presente trabajo vamos a mostrar algunos datos de interés de una de las empresas multinacionales más conocidas a nivel mundial, McDonald’s. Por un lado, veremos el menú de esta franquicia, así como los macronutrientes que contienen los productos y los valores nutricionales, mostrando y explicando los aspectos más relevantes. También trataremos de compararlo con otros grandes restaurantes de comida rápida en los Estados Unidos, país que acoge más cantidad de marcas de restaurantes de comida rápida en el mundo por excelencia. En la parte final, comentaremos de forma general la popularidad de los locales por ciudad, así como la evolución de sus ventas a lo largo de los últimos años. Por lo que en este trabajo nuestro objetivo es informar y concienciar a los lectores un poco acerca de los productos ofrecidos por McDonald’s así como el impacto que este ha tenido sobre la población estadounidense.
1.1 Breve Historia
El primer restaurante de McDonald’s se ubicaba en California, en el año 1948, como un bar de carretera. Fueron los dos hermanos Maurice y Richard Mcdonald quien llevaron a cabo este proyecto. Los elementos que lo caracterizaban y fueron motivo del éxito eran; por un lado, se podía pedir y recoger los productos desde el coche, los grandes ventanales que tenían permitían ver desde fuera como el pedido se preparaba y por último, los bajos precios que lo diferenciaban de competidores. Este último estuvo a punto de llevar a los hermanos a la quiebra, por lo que estos tuvieron que cerrar el negocio y organizar una buena estrategia. Resumiendo, Ray A. Kroc, alguien importante en los negocios por aquella zona, vio el potencial del restaurante en si y con la cesión del derecho de comercializar la marca por parte de los hermanos, abrió otro restaurante en Illinois. Y así se podría decir que empezó este negocio que actualmente tiene tanto éxito.
1.2 Logos.
Logo1
1940-1948: La historia de la cadena de restaurantes de comida rápida más famosa del mundo comenzó en 1937 cuando Patrick McDonald lanzó «The Airdome», el primer restaurante de la familia. Tres años más tarde, sus hijos le cambiaron el nombre a «McDonald’s Famous Barbecue». El primer logotipo del restaurante estaba compuesto por una marca denominativa negra, distribuida en tres niveles y ejecutada en tres estilos diferentes.
Logo2
1948-1953: El concepto de barbacoa fue reemplazado por las hamburguesas, que estaban ganando cada vez más popularidad en los Estados Unidos. El título del restaurante se modificó en 1948 y se rediseñó el logotipo. Se añade la especificación «buy em by the bag», para hacer hincapié en la posibilidad de consumir la comida también para llevar. En negrita (y repetido dos veces) aparece el precio super competitivo. Y un logotipo repleto de detalles, con la intención de resaltar todos los puntos fuertes del restaurante: la originalidad de la oferta, la modalidad de consumo y el ahorro.
Logo3
1953-1968: La compañía finalmente cambió su nombre a simplemente MacDonald’s y aquí es donde comienza todo. El logo aún estaba lejos de lo que todos conocemos hoy, pero el color rojo apareció en la paleta de colores, dando la dirección correcta para la marca.Era un logotipo bastante memorable y reconocible, que permaneció en la empresa durante 15 años.
Logo4
1961-1968: Es 1961 y hemos llegado a un momento decisivo para McDonald’s: el momento en que aparecen por primera vez los famosos «Golden Arches». Para el proyecto de un punto de venta en Downey (California), los hermanos McDonald encargan dos gigantescos arcos dorados en los extremos de la estructura. La idea era que se viese mejor incluso desde lejos. El logotipo de 1961, diseñado por el director creativo Jim Schindler, está inspirado en este detalle arquitectónico. Y eso no es todo: además se introduce el amarillo, un color que infunde el buen humor y que seguirá formando parte de la identidad visual de la empresa.
Logo5
1975: La nueva imagen se incorporó a la identidad visual en 1975. El emblema con la marca denominativa se colocó dentro de un rectángulo rojo con ángulos redondeados. Las letras se cambiaron de negro a blanco, lo que parecía más amigable y acogedor. Esta insignia es probablemente la versión más reconocible de todos los logotipos de leyendas de comida rápida y la compañía todavía la usa, siendo reconocible instantáneamente en todo el mundo y evocando una sensación de alegría, felicidad y pasión.
Logo6
A partir de 1985 se modifica y simplifica una vez más el logotipo en varios puntos del mundo : los arcos se solapan para formar la letra M. Hemos llegado al antepasado directo del logotipo de hoy.
Logo7
A partir de 2009, La compañía McDonald’s cambia su tradicional logo de color rojo por uno verde, según anunció la marca. Este cambio de color simboliza teóricamente una imagen más ecológica y una nueva estrategia por parte de la empresa. El cambio de logo es una de las técnicasde marketing que adoptó la cadena de comida rápida. Con el objetivo de mostrar un perfil más comprometido con la preservación de los recursos naturales, McDonald’s lanzó su nueva campaña que consiste en cambiar el tradicional fondo rojo de su logo por un color verde intenso.
Logo8
1993-Hoy: En Estados Unidos, McDonald’s introdujo a nivel nacional una línea de café llamada “McCafé”. A diferencia de lo que ocurre en otros países, “McCafé” es solo una línea de bebidas especiales, no una cafetería completa. El estilo del logotipo de McCafe no crea ningún vínculo con el logotipo de la marca matriz, McDonald’s. En cambio, las fuerzas del diseño detrás de McCafe han creado una identidad de marca distintiva y completamente independiente.
2. CARGAMOS DATOS Y PAQUETES
Este trabajo ha sido posible realizarlo con la ayuda de varias fuentes de donde hemos sacado los datos. En la página web facilitada por la asignatura (kaggle), hemos utilziado principalmente 5 datasests, que los indicaremos en la última parte, en la bibliografía. Por otro lado, hemos accedido a documentos oficiales del restaurante obtenidos en formato excel y los hemos transformado para trabajar con ellos y obtener más datos.
library(ggplot2)
library(dplyr)
library(reactable)
library(gt)
library(tibble)
library("plotly")
library(tidyverse)
library(hrbrthemes)
library(viridis)
library(patchwork)
library(gganimate)
library(wordcloud2)
library(webshot)
library(corrplot)
library(sqldf)
library(RColorBrewer)
library(kableExtra)
library(ggThemeAssist)
menu <- rio::import("./datos/menu1.1.csv")
restaurantesUS <- rio::import("./datos/FastFoodRestaurants.csv")
fastfoodrestaurants <- rio::import("./datos/fastfoodrestaurants.csv")
ruta4 <- here::here("datos", "Datafiniti_Fast_Food_Restaurants_May19.csv")
fastfoodrestaurants19 <- rio::import(ruta4)
ingresos <- rio::import("./datos/ingresos1.csv")
ventas <- rio::import("./datos/sales.csv")
3. RESTAURANTES FAST FOOD EN ESTADOS UNIDOS
3.1 Número de restaurantes FastFood
En este apartado observamos mediante el siguiente gráfico de barras el número de restaurantes de fast food en todo el país de EEUU. Hemos acotado entre los 10 nombres más populares, entre ellos McDonald’s, Burguer King o Taco Bell.
mas_restaurantes <- restaurantesUS %>%
group_by(name) %>%
mutate(n_restaurantes = sum(NN = n())) %>%
distinct(name, n_restaurantes) %>%
arrange(desc(n_restaurantes)) %>%
filter(n_restaurantes >=192)
gg_restaurantes <- ggplot(mas_restaurantes, aes(name, n_restaurantes)) +
geom_bar(stat = "identity") + theme(panel.grid.major = element_line(colour = "gray"),
panel.grid.minor = element_line(colour = "gray"),
panel.background = element_rect(fill = "#FFC40C",
colour = "aliceblue"), plot.background = element_rect(fill = "#FFC40C"))
gg_restaurantes
Como podemos ver, por clara diferencia, la marca con más locales es McDonald’s, seguida de Burguer King y luego de Taco Bell.
Una de las claves del éxito alcanzada por la empresa y que ha permitido su expansión mundial son las siguientes: por un lado, la consistencia. Esto es, en cualquier país en el que t encuentres, la experiencia en el restaurante va a ser muy similar, los clientes ya saben que esperar por lo que hace mucho más fáciles sus decisiones de que comer. Después destacaríamos la innovación, para que el negocio no quede estancado. Muy frecuentemente la franquicia lanza nuevos productos como respuesta de las demandas del cliente, se podría decir que evolucionan con el tiempo, como veremos un poco más adelante.
3.2 Ingresos restaurantes FastFood
En el siguiente apartado, analizaremos los ingresos en miles de millones de dólares de los mismos 10 restaurantes más famosos de EEUU.
df_ingresos <- ggplot(ingresos, aes(x=reorder(Resturantes, Value), y=Value, fill=Resturantes))+
geom_bar(stat="identity") +
theme(legend.position = "none") +
coord_polar(start = 0.01) +
labs (x="Restaurantes") + labs(y="Miles de millones de dólares") + labs(title = "Ingresos de los Resturantes FastFood") + labs(subtitle = "En miles de millones de dólares") + theme(panel.background = element_rect(fill = "#FFC40C"),
plot.background = element_rect(fill = "#FFC40C"))
df_ingresos
Como se observa claramente, en la primera posición volveríamos a encontrar a nuestro restaurante, que llega a los 40 mil millones de dólares anuales. Sus ingresos están muy por encima de cualquiera de las otras marcas.
4. MC DONALD’S
En este cuarto apartado, vamos a hablar sobre el restaurante en cuestión en términos generales y de los aspectos más relevantes.
4.1 Productos McDonalds
En la siguiente tabla, se pueden consultar todos los productos de la carta que ofrecen. Se muestran un total de 260 productos.
df_menu <- menu %>%
select(Item)
reactable(df_menu, 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")
})))
4.2 Categorias de productos en McDonalds
De entre todos los productos, estos se podrían diferenciar en las siguientes categorías:
m <- list(
l = 50,
r = 50,
b = 100,
t = 100,
pad = 4
)
marker = list(color = brewer.pal(9, "Set1"))
p <- plot_ly(
x = menu$Category,
marker = list(color = '#CD0BBC'),
type = "histogram"
)%>%
layout( xaxis = list(title = ""),
yaxis = list(title = ""),
autosize = T)
p
Y aun que parezca sorprendente, este restaurante cuenta con más variedad en cafés y tés. Incluso aunque a primera vista lo más demandado sea una simple hamburguesa de carne, al menos en nuestro país. De lo que menos variedad hay sería de ensaladas. Quizá tenga sentido porque es uno de lo productos que se ha incorporado más recientemente.
5.VALORES NUTRICIONALES
A continuación, vamos a destacar los aspectos y los puntos más relevantes y quizá destacables de los productos que ofrece la marca pero en términos de los valores nutricionales.
5.1 ¿Cuál es el producto con más calorias?
El producto más calórico del restaurante, son los nugguets, también es porque cuenta con 40 piezas.
df_calorias <- menu %>%
select(Item, Calories)
dftop1 <- df_calorias %>% slice_max(Calories, n=1)
Imagen <- "https://i.pinimg.com/originals/d5/5f/03/d55f035c37d84ec55934ba6d469bedce.jpg"
dftop1 <- dftop1 %>% add_column(Imagen)
Tabla_Pmascal <- dftop1 %>% gt()
Tabla_Pmascal <- Tabla_Pmascal %>%
tab_header(title = md("**Producto con mas calorias**"))
Tabla_Pmascal <- Tabla_Pmascal %>%
tab_options(heading.background.color = "coral") %>% tab_options(heading.title.font.size = 15, column_labels.font.weight = "bold")
Tabla_Pmascal <- Tabla_Pmascal %>%
gt::text_transform(locations = cells_body(columns = c(Imagen)), fn = function(x) {gt::web_image(x, height = 50)}) %>% cols_align(
align = "center")
Tabla_Pmascal
Item |
Calories |
Imagen |
Chicken McNuggets (40 piece) |
1880 |
|
5.2 ¿Cuál es el producto con menos calorias?
El menos calórico, lógicamente sería la botella de agua
dfmin1 <- df_calorias %>%
slice_min(Calories, n=1) %>%
filter (Item == "Dasani Water Bottle") #Dasani Water Bottle es uno de los productos con menos calorias
Imagen <- "https://i.pinimg.com/originals/3c/df/ae/3cdfaeaa504db8aaf100843a12aacc97.png"
dfmin1 <- dfmin1 %>% add_column(Imagen)
Tabla_Pmincal <- dfmin1 %>% gt()
Tabla_Pmincal <- Tabla_Pmincal %>%
tab_header(title = md("**Producto con menos calorias**"))
Tabla_Pmincal <- Tabla_Pmincal %>%
tab_options(heading.background.color = "coral") %>% tab_options(heading.title.font.size = 15, column_labels.font.weight = "bold")
Tabla_Pmincal <- Tabla_Pmincal %>%
gt::text_transform(locations = cells_body(columns = c(Imagen)), fn = function(x) {gt::web_image(x, height = 50)}) %>% cols_align(
align = "center")
Tabla_Pmincal
Item |
Calories |
Imagen |
Dasani Water Bottle |
0 |
|
5.3. Productos con mayor macronutrientes.
En este apartado, vamos a mostrar por separado, que 10 productos, en primer lugar, tienen más proteínas, luego cuáles cuentan con más grasas y cual está compuesto con más carbohidratos.
En los gráficos de cada macronutriente podemos verlo, sosteniendo el cursor sobre ellos.
Proteina
df14prod <- menu %>%
select(Item, Protein) %>%
head(Protein, n = 10L)%>%
group_by(Item, Protein) %>%
arrange(desc(Protein))
df14prod
Item
|
Protein
|
Steak & Egg McMuffin
|
26
|
Sausage McMuffin with Egg
|
21
|
Sausage McMuffin with Egg Whites
|
21
|
Bacon, Egg & Cheese Biscuit with Egg Whites (Regular Biscuit)
|
20
|
Bacon, Egg & Cheese Biscuit with Egg Whites (Large Biscuit)
|
20
|
Bacon, Egg & Cheese Biscuit (Regular Biscuit)
|
19
|
Bacon, Egg & Cheese Biscuit (Large Biscuit)
|
19
|
Egg White Delight
|
18
|
Egg McMuffin
|
17
|
Sausage McMuffin
|
14
|
wordcloud2(data=df14prod, size=0.1)
Grasas
totalfat <- menu %>%
select(Item, Fat)
df_fat <- totalfat %>%
head(Fat, n= 10L) %>%
group_by(Item, Fat) %>%
arrange(desc(Fat))
df_fat
Item
|
Fat
|
Bacon, Egg & Cheese Biscuit (Large Biscuit)
|
30
|
Sausage McMuffin with Egg
|
28
|
Bacon, Egg & Cheese Biscuit (Regular Biscuit)
|
26
|
Bacon, Egg & Cheese Biscuit with Egg Whites (Large Biscuit)
|
25
|
Sausage McMuffin
|
23
|
Sausage McMuffin with Egg Whites
|
23
|
Steak & Egg McMuffin
|
23
|
Bacon, Egg & Cheese Biscuit with Egg Whites (Regular Biscuit)
|
20
|
Egg McMuffin
|
13
|
Egg White Delight
|
8
|
plot_ly(x = df_fat$Item, y=df_fat$Fat,color = df_fat$Item,colors = palette("Pastel 2"), type = "box") %>%
layout(title = "Los 10 productos con más grasa",
xaxis = list(title = ""),
yaxis = list(title = ""),
showlegend=FALSE,
autosize = T)
Carbohidratos
carbos <- menu %>%
select(Item,Carbohydrates)
df_carbos <- carbos %>%
head(Carbohydrates, n= 10L) %>%
group_by(Item, Carbohydrates) %>%
arrange(desc(Carbohydrates))
df_carbos
Item
|
Carbohydrates
|
Bacon, Egg & Cheese Biscuit (Large Biscuit)
|
43
|
Bacon, Egg & Cheese Biscuit with Egg Whites (Large Biscuit)
|
42
|
Bacon, Egg & Cheese Biscuit (Regular Biscuit)
|
38
|
Bacon, Egg & Cheese Biscuit with Egg Whites (Regular Biscuit)
|
36
|
Egg McMuffin
|
31
|
Steak & Egg McMuffin
|
31
|
Egg White Delight
|
30
|
Sausage McMuffin with Egg
|
30
|
Sausage McMuffin with Egg Whites
|
30
|
Sausage McMuffin
|
29
|
plot_ly(x = df_carbos$Item, y=df_carbos$Carbohydrates,color = df_carbos$Item, colors = palette("alphabet"), type = "box") %>%
layout(title="Los 10 productos con más carbohidratos",
xaxis = list(title = ""),
yaxis = list(title = ""),
showlegend=FALSE,
autosize = T)
En cuanto al producto con más proteínas se encontraría el Steak & Egg McMuffin, que se encuenta dentro de la sección de los desayunos. Con más grasa y a la vez con más hidratos tendríamos al Bacon, Egg & Cheese Biscuit (Large Biscuit).
5.4. Productos con mayor micronutrientes .
VitaminaA
En este apartado, repetimos la misma operación que en el punto anterior pero ahora con los micronutrientes, separados en: vitamina A y C, fibra, calcio y hierro. En la parte inferior de cada lista, lo podemos observar también gráficamente
vitaminaA <- menu %>%
select(Item,VitaminA)
df_vitamina1 <- vitaminaA %>%
head(VitaminA, n= 10L)%>%
arrange(desc(VitaminA))
df_vitamina1
Item
|
VitaminA
|
Sausage McMuffin with Egg
|
15
|
Steak & Egg McMuffin
|
15
|
Bacon, Egg & Cheese Biscuit (Large Biscuit)
|
15
|
Egg McMuffin
|
10
|
Bacon, Egg & Cheese Biscuit (Regular Biscuit)
|
10
|
Sausage McMuffin
|
8
|
Egg White Delight
|
6
|
Sausage McMuffin with Egg Whites
|
6
|
Bacon, Egg & Cheese Biscuit with Egg Whites (Large Biscuit)
|
6
|
Bacon, Egg & Cheese Biscuit with Egg Whites (Regular Biscuit)
|
2
|
grafico <- df_vitamina1 %>%
ggplot( aes(Item, VitaminA, size = 0.75, color= "orange")) +
geom_point() +
theme_bw()+
theme(legend.position = "none") +
labs(x = NULL) + theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank()) + labs(title= "Los 10 productos con más Vitamina A") +
theme(panel.background = element_rect(fill = 'wheat1', colour = 'red')) + theme(panel.background = element_rect(fill = "#FFC40C"),
plot.background = element_rect(fill = "#FFC40C",
colour = "#FFC40C"))
ggplotly(grafico)
VitaminaC
vitaminaC <- menu %>%
select(Item,VitaminC)
df_vitamina2 <- vitaminaC %>%
head (VitaminC, n = 10L)%>%
arrange(desc(VitaminC))
df_vitamina2
Item
|
VitaminC
|
Bacon, Egg & Cheese Biscuit (Regular Biscuit)
|
8
|
Bacon, Egg & Cheese Biscuit (Large Biscuit)
|
8
|
Bacon, Egg & Cheese Biscuit with Egg Whites (Regular Biscuit)
|
8
|
Bacon, Egg & Cheese Biscuit with Egg Whites (Large Biscuit)
|
8
|
Steak & Egg McMuffin
|
2
|
Egg McMuffin
|
0
|
Egg White Delight
|
0
|
Sausage McMuffin
|
0
|
Sausage McMuffin with Egg
|
0
|
Sausage McMuffin with Egg Whites
|
0
|
dfgrafico1 <- ggplot(df_vitamina2, aes(Item, color=VitaminC)) +
geom_bar(fill=NA) +
coord_flip() +
theme(panel.background = element_rect(fill = 'lightblue1')) + theme(panel.background = element_rect(fill = "#FFC40C"),
plot.background = element_rect(fill = "#FFC40C"),
legend.background = element_rect(fill = "#FFC40C"))
ggplotly(dfgrafico1)
Fibra
fibra <- menu %>%
select(Item,DietaryFiber)
df_fibra <- fibra %>%
head(DietaryFiber, n= 10L) %>%
arrange(desc(DietaryFiber))
df_fibra
Item
|
DietaryFiber
|
Egg McMuffin
|
4
|
Egg White Delight
|
4
|
Sausage McMuffin
|
4
|
Sausage McMuffin with Egg
|
4
|
Sausage McMuffin with Egg Whites
|
4
|
Steak & Egg McMuffin
|
4
|
Bacon, Egg & Cheese Biscuit (Large Biscuit)
|
3
|
Bacon, Egg & Cheese Biscuit with Egg Whites (Large Biscuit)
|
3
|
Bacon, Egg & Cheese Biscuit (Regular Biscuit)
|
2
|
Bacon, Egg & Cheese Biscuit with Egg Whites (Regular Biscuit)
|
2
|
m <- list(
l = 50,
r = 50,
b = 100,
t = 100,
pad = 4
)
marker = list(color = brewer.pal(9, "Set1"))
p <- plot_ly(
x = menu$Category,
marker = list(color = '#45171D')
)
menu %>%
plot_ly( x = df_fibra$Item, y = df_fibra$DietaryFiber, type="scatter", mode = "markers" , marker=list( color=colorRampPalette(brewer.pal(8,"Dark2"))(100) , opacity=0.9) ) %>% layout(title = "Los 10 productos con más fibra",
xaxis = list(title = ""),
yaxis = list(title = ""),
showlegend=FALSE,autosize = F, width = 500, height = 400,margin=m)
Calcio
calcio <- menu %>%
select(Item,Calcium)
df_calcium <- calcio %>%
head(Calcium, n= 10L) %>%
arrange(desc(Calcium))
df_calcium
Item
|
Calcium
|
Sausage McMuffin with Egg
|
30
|
Steak & Egg McMuffin
|
30
|
Egg McMuffin
|
25
|
Egg White Delight
|
25
|
Sausage McMuffin
|
25
|
Sausage McMuffin with Egg Whites
|
25
|
Bacon, Egg & Cheese Biscuit (Large Biscuit)
|
20
|
Bacon, Egg & Cheese Biscuit (Regular Biscuit)
|
15
|
Bacon, Egg & Cheese Biscuit with Egg Whites (Regular Biscuit)
|
15
|
Bacon, Egg & Cheese Biscuit with Egg Whites (Large Biscuit)
|
15
|
p <- ggplot(df_calcium, aes(Item, Calcium)) +
geom_point() +
geom_segment(aes(x=forcats::fct_reorder(Item, Calcium, .desc = TRUE),
xend=forcats::fct_reorder(Item, Calcium, .desc = TRUE),
y=0,
yend=Calcium, color=palette("Tableau 10"))) +
geom_smooth() +
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank()) +
labs(title = "Los 10 productos con más calcio",
subtitle = "anño 2019",
caption = "Datos provenientes de Kaggle",
x = "Productos",
y = "Calcio") +
theme(legend.position="none") + theme(panel.background = element_rect(fill = "#FFC40C"),
plot.background = element_rect(fill = "#FFC40C"))
ggplotly(p)
Hierro
hierro <- menu %>%
select(Item, Iron)
df_hierro <- hierro %>%
head(Iron, n= 10L) %>%
group_by(Item, Iron) %>%
arrange(desc(Iron))
df_hierro
Item
|
Iron
|
Steak & Egg McMuffin
|
20
|
Bacon, Egg & Cheese Biscuit (Large Biscuit)
|
20
|
Egg McMuffin
|
15
|
Sausage McMuffin with Egg
|
15
|
Bacon, Egg & Cheese Biscuit (Regular Biscuit)
|
15
|
Bacon, Egg & Cheese Biscuit with Egg Whites (Large Biscuit)
|
15
|
Sausage McMuffin
|
10
|
Sausage McMuffin with Egg Whites
|
10
|
Bacon, Egg & Cheese Biscuit with Egg Whites (Regular Biscuit)
|
10
|
Egg White Delight
|
8
|
df <- ggplot(df_hierro, aes(x=Item, y=Iron)) +
geom_segment( aes(x=Item, xend=Item, y=0, yend=Iron)) +
geom_point( size=5, color="red", fill=alpha("orange", 0.3), alpha=0.7, shape=21, stroke=2) + theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank()) + labs(title = "Los 10 productos con más calcio",
subtitle = "anño 2019",
caption = "Datos provenientes de Kaggle",
x = "Productos",
y = "Calcio") +
theme(panel.background = element_rect(fill = "#FFC40C"),
plot.background = element_rect(fill = "#FFC40C"))
ggplotly(df)
El desayuno de Sausage McMuffin with Egg, es el que encontramos con más vitamina A y el Bacon, Egg & Cheese Biscuit (Regular Biscuit), con más vitamina C.
En cuanto al alimento con más fibra, diríamos el Egg McMuffin, que en lugar de carne, posee un huevo en su interior.
Sausage McMuffin with Egg vuelve a repetirse como el producto con más calcio de entre todos y Steak & Egg McMuffin es el que aparece con más hierro.
5.5 Correlación
En este gráfico se concentra y se muestra la correlación que tienen entre sí los nutrientes de los productos que se encuentran en la carta de McDonald’s.
menu <- na.omit(menu)
scaledmenu <- data.frame(scale(menu[c(4:24)]))
menu1<-cbind(menu[1:3],scaledmenu)
M <- cor(scaledmenu)
cex.before <- par("cex")
par(cex = 0.7)
corrplot(M, insig = "blank", method = "square", tl.cex = .75)
par(cex = cex.before)
5.6. Combi perfecta
En este punto llamamos combi perfecta, al producto menos calórico de cada categoría. Esto hace posible que aun siendo Mc Donald’s un lugar de comida poco saludable se pueda saber que opciones puede coger un cliente que pretenda comer las menos calorías posibles por lo que al tener los productos menos calóricos de cada categoria, el cliente puede conformarse así su propio menú atendiendo a lo que este solicita.
Mincal<-aggregate(menu$Calories, by=list(menu$Category), FUN=min)
colnames(Mincal)[1]<-"Category"
colnames(Mincal)[2]<-"Calories"
Mincalmenu<-sqldf("select a.Category,a.Item, a.Calories from menu a, Mincal b where a.Category==b.Category and a.Calories==b.Calories" )
## The below table gives the minumum Calorie Item from Each Category
Mincalmenu
Category
|
Item
|
Calories
|
Breakfast
|
Hash Brown
|
150
|
Beef & Pork
|
Hamburger
|
240
|
Chicken & Fish
|
Chicken McNuggets (4 piece)
|
190
|
Salads
|
Premium Bacon Ranch Salad (without Chicken)
|
140
|
Salads
|
Premium Southwest Salad (without Chicken)
|
140
|
Snacks & Sides
|
Apple Slices
|
15
|
Desserts
|
Kids Ice Cream Cone
|
45
|
Beverages
|
Diet Coke (Small)
|
0
|
Beverages
|
Diet Coke (Medium)
|
0
|
Beverages
|
Diet Coke (Large)
|
0
|
Beverages
|
Diet Coke (Child)
|
0
|
Beverages
|
Diet Dr Pepper (Small)
|
0
|
Beverages
|
Diet Dr Pepper (Medium)
|
0
|
Beverages
|
Diet Dr Pepper (Large)
|
0
|
Beverages
|
Diet Dr Pepper (Child)
|
0
|
Beverages
|
Dasani Water Bottle
|
0
|
Coffee & Tea
|
Iced Tea (Small)
|
0
|
Coffee & Tea
|
Iced Tea (Medium)
|
0
|
Coffee & Tea
|
Iced Tea (Large)
|
0
|
Coffee & Tea
|
Iced Tea (Child)
|
0
|
Coffee & Tea
|
Coffee (Small)
|
0
|
Coffee & Tea
|
Coffee (Medium)
|
0
|
Coffee & Tea
|
Coffee (Large)
|
0
|
Smoothies & Shakes
|
Strawberry Banana Smoothie (Small)
|
210
|
Smoothies & Shakes
|
Mango Pineapple Smoothie (Small)
|
210
|
knitr::kable(Mincalmenu) %>%
kableExtra::kable_styling(full_width = F) %>%
column_spec(1, bold = T, border_right = T) %>%
row_spec(1, bold = T, color = "white", background = palette("Pastel 2")) %>%
row_spec(2:2, bold = T, color = "white", background = palette("Tableau 10") ) %>%
row_spec(3:3, bold = T, color = "white", background = palette("Polychrome 36") ) %>%
row_spec(4:5, bold = T, color = "white", background = palette("Okabe-Ito") ) %>%
row_spec(6:6, bold = T, color = "white", background = palette("Paired") ) %>%
row_spec(7:7, bold = T, color = "white", background = "#2297E6") %>%
row_spec(8:16, bold = T, color = "white", background = "#28E2E5") %>%
row_spec(17:23, bold = T, color = "white", background = "#61D04F") %>%
row_spec(24:25, bold = T, color = "white", background = "#DF536B") %>%
row_spec(0, angle = 0)
Category
|
Item
|
Calories
|
Breakfast
|
Hash Brown
|
150
|
Beef & Pork
|
Hamburger
|
240
|
Chicken & Fish
|
Chicken McNuggets (4 piece)
|
190
|
Salads
|
Premium Bacon Ranch Salad (without Chicken)
|
140
|
Salads
|
Premium Southwest Salad (without Chicken)
|
140
|
Snacks & Sides
|
Apple Slices
|
15
|
Desserts
|
Kids Ice Cream Cone
|
45
|
Beverages
|
Diet Coke (Small)
|
0
|
Beverages
|
Diet Coke (Medium)
|
0
|
Beverages
|
Diet Coke (Large)
|
0
|
Beverages
|
Diet Coke (Child)
|
0
|
Beverages
|
Diet Dr Pepper (Small)
|
0
|
Beverages
|
Diet Dr Pepper (Medium)
|
0
|
Beverages
|
Diet Dr Pepper (Large)
|
0
|
Beverages
|
Diet Dr Pepper (Child)
|
0
|
Beverages
|
Dasani Water Bottle
|
0
|
Coffee & Tea
|
Iced Tea (Small)
|
0
|
Coffee & Tea
|
Iced Tea (Medium)
|
0
|
Coffee & Tea
|
Iced Tea (Large)
|
0
|
Coffee & Tea
|
Iced Tea (Child)
|
0
|
Coffee & Tea
|
Coffee (Small)
|
0
|
Coffee & Tea
|
Coffee (Medium)
|
0
|
Coffee & Tea
|
Coffee (Large)
|
0
|
Smoothies & Shakes
|
Strawberry Banana Smoothie (Small)
|
210
|
Smoothies & Shakes
|
Mango Pineapple Smoothie (Small)
|
210
|
6.TIPOS DE ALIMENTOS
Como todos sabemos McDonald’s ofrece una carta muy amplia de productos de todo tipo, más grandes o más pequeños, más calórico o menos, más sanos o menos nutricionalmente hablando, etc. Es conocido sobretodo por las comidas y cenas siendo estas en las que van más clientes, sin embargo Mc donald’s desde que abrio la zona de Mc Cafe cuenta con una gran variedad de cafés para cualquier hora del día así como de desayunos y de snacks. Y cabe destacar que también ha querido adaptarse a opciones más saludables para así llegar a todas las personas, ofreciendo comida más sana y menos sana.Por eso vamos a mostrar 3 tipos de alimentos, que probablemente no sean conocidos ni asociados a una franquicia como Mc Donald’s tan arraigada a las hamburguesas.
6.1.Breakfast
ggplot(subset(menu,Category=="Breakfast"), aes(reorder(Item,Calories),Calories,fill=Calories)) + geom_bar(stat = "identity") + theme(legend.position = "none")+ggtitle("Breakfast Vs Calories") + xlab("Item") + ylab("Calories") + coord_flip() + theme(panel.background = element_rect(fill = "#FFC40C"),
plot.background = element_rect(fill = "#FFC40C"))
6.3. Snacks
ggplot(subset(menu,Category=="Snacks & Sides"), aes(reorder(Item,Calories),Calories,fill=Calories)) + geom_bar(stat = "identity") + theme(legend.position = "none")+ggtitle("Snacks & Sides Menu Vs Calories") + xlab("Item") + ylab("Calories") + coord_flip() + theme(panel.background = element_rect(fill = "#FFC40C"),
plot.background = element_rect(fill = "#FFC40C"))
6.4. Coffee and Tea
Coffeeandtea<-subset(menu,Category=="Coffee & Tea")
Coffeeandtea <- Coffeeandtea[order(-Coffeeandtea$Calories),]
Coffeeandtea<-Coffeeandtea[1:20,]
ggplot(Coffeeandtea, aes(reorder(Item,Calories),Calories,fill=Calories)) + geom_bar(stat = "identity") + theme(legend.position = "none")+ggtitle("Coffee & Tea Menu Vs Calories") + xlab("Item") + ylab("Calories") + coord_flip() + theme(panel.background = element_rect(fill = "#FFC40C"),
plot.background = element_rect(fill = "#FFC40C"))
7.POPULARIDAD
En este apartado analizarmeos y mostraremos la “popularidad” de nuestro restaurante en algunas de las ciudades de EEUU, a través de un gráfico de barras. Veremos el número de locales de la franquicia con los que cuentan las ciudades que se muestran.
nummac <- restaurantesUS %>%
select(city, name) %>%
group_by(city) %>%
mutate(nn_mac = sum(NN=n())) %>%
filter(name == "McDonald's") %>%
distinct(city, nn_mac) %>%
ungroup()
top10 <- nummac %>%
slice_max(nn_mac , n=10)
grafico1 <- ggplot (top10, aes(x=nn_mac, y = city), aes(fct_rev(nn_mac))) + geom_bar(stat="identity", fill = "red") + coord_flip() + labs(x = "Numero de McDonalds", y = "City")+labs(title = "Locales por ciudad") + theme(panel.background = element_rect(fill = "#FFC40C"),
plot.background = element_rect(fill = "#FFC40C"))
grafico1
Con gran ventaja sobre los demás, la ciudad que cuenta con más locales sería Cincinnati.
Y es que este restaurante es mundialmente reconocido, tanto por ser una organización comercial de alta calidad, como por ser una de las mejores oportunidades de oferta de Franquicias. Puede pues, que la clave de su éxito es tener una base muy firme en sus franquiciatarios.
8. VENTAS
Por último, vamos a hablar sobre las ventas del restaurante, información que hemos considerado importante tener en cuenta y por ello mostraros. Y es que esta marca cuenta con 26 mil locales en todo el mundo, 14 mil millones de comidas vendidas al año, 5 establecimientos nuevos se abren cada día, venta de 145 hamburguesas por segundo y un millón y medio de empleados.
ventasmc <- ventas%>%
select(Años,Ventas)
ggplot( data= ventas, aes(x=Años, y=Ventas)) +
geom_line() +
geom_point() +
ggtitle("Evolución de las ventas de MC Donald's desde 2005-2019") +
theme_ipsum() +
ylab("Número de ventas") +
transition_reveal(Años) + theme(plot.subtitle = element_text(family = "sans"),
plot.caption = element_text(family = "sans"),
axis.title = element_text(family = "sans"),
plot.title = element_text(family = "sans"),
panel.background = element_rect(fill = "#FFC40C"),
plot.background = element_rect(fill = "#FFC40C"))
En este gráfico vemos la evolución de las ventas de McDonald’s entre 2005 y 2019
8.1 Locales y empleados
grafloc <- ggplot( data= ventas, aes(x=Años, y=Locales))
grafloc + geom_line() +
geom_point() +
ggtitle("Evolución de los establecimientos de MC Donald's desde 2005-2019") +
theme_ipsum() +
ylab("Número de establecimientos") +
transition_reveal(Años)+
labs(subtitle = "En miles") + theme(plot.subtitle = element_text(family = "sans"),
plot.caption = element_text(family = "sans"),
axis.title = element_text(family = "sans"),
plot.title = element_text(family = "sans"),
panel.background = element_rect(fill = "#FFC40C"),
plot.background = element_rect(fill = "#FFC40C"))
empleados <- ventas%>%
select(Años,Empleados)
grafempl <- ggplot( data= ventas, aes(x=Años, y=Empleados))
grafempl+ geom_line() +
geom_point() +
ggtitle("Evolución del número de empleados de MC Donald's desde 2013-2019") +
theme_ipsum() +
ylab("Número de Empleados") +
transition_reveal(Años) + theme(plot.subtitle = element_text(family = "sans"),
plot.caption = element_text(family = "sans"),
axis.title = element_text(family = "sans"),
plot.title = element_text(family = "sans"),
panel.background = element_rect(fill = "#FFC40C"),
plot.background = element_rect(fill = "#FFC40C"))
empleados<- na.omit(empleados)
Particularmente McDonald’s resulta un caso interesante a contemplar puesto que año con año es posible notar que tiene menos empleados pero crece de forma importante. La firma que en su momento pudo llegar a presumir de haber contratado a uno de cada ocho trabajadores en los Estados Unidos ha ido reduciendo la cantidad de colaboradores, cosa que podría parecer negativa pues el crecimiento muchas veces implica que es necesario sumar a más personas. Tal como lo presentamos en la gráfica de este día, de 2012 a 2018 es posible notar como ha ido disminuyendo de forma significativa la cantidad de empleados de McDonald’s a nivel global. Como se logra observar, durante 2012 había 440 mil trabajadores, para 2015 ya eran 420 mil mientras que para el año 2018 la cantidad ya se había reducido a la mitad con respecto a lo reportado en 2015, es decir, se tiene registro de solo 210 mil empleados hasta el año pasado.
¿Por qué hay menos empleados si hay más restaurantes?
El hecho de que la marca de los arcos dorados tenga menos personal y más restaurantes obedece principalmente a la visión a futuro de la compañía, a la tecnología y la forma en que ha decidido gestionarse. Específicamente en el caso de los empleados, es posible notar que McDonald’s ha decidido apostar en gran medida por acciones como la opción de que las personas pidan su comida a través de apps desde las cuales pueden incluso pagar y otras herramientas de self-service en los restaurantes, como kioscos desde los cuales los consumidores se encargan de gestionar sus órdenes. Se espera que para finales de este año, en Estados Unidos, más de 12 mil ubicaciones de McDonald’s cuenten con menús digitales y kioscos de autoservicio.
CONCLUSION
Después del análisis realizado en el presente trabajo podemos llegar a una serie de conclusiones respecto al restaurante en cuestión: Mc Donald’s. La franquicia más exitosa a nivel mundial, a pesar de haberse enfrentado a desafíos de competencia a nivel mundial, sigue en el top 1 de restaurantes del mundo.
Como todo el mundo sabe, el menú siempre ha sido muy parecido a lo largo de los años, suelen incorporar nuevos productos, suprimir otros, en función del éxito que tengan, pero como hemos mencionado anteriormente sí que es verdad que como destino para comer algo es una apuesta segura porque sabes perfectamente lo que vas a comer, el entorno o el local en el que te vas a encontrar, el ambiente, etc. Ya que todos los restaurantes, estés en la parte del mundo en la que estés, son muy similares entre sí.
A pesar de las críticas y opiniones que recibe este restaurante de comida rápida, la variedad de productos que ofrece es muy amplia y permite que el consumidor tenga diferentes opciones al gusto.
Otro aspecto importante comentado en este trabajo, es que aún que la gente no se pare a pensarlo, esta marca hace una gran labor social, con impacto positivo a la sociedad. Como por ejemplo en términos de puestos de trabajo, o como se menciona en la última parte, la inversión en nuevos métodos tecnológicos y la visión para el futuro que se prevé siempre adaptándose a los distintos cambios que suceden a nuestro alrededor.
Nuestro objetivo con este proyecto, y esperamos que conseguido, es dar a conocer un poco más el restaurante en lo que se trata de los productos que ofrece. Aunque ya bastante conocida es la marca y su menú, no está de más conocer completamente o por lo menos detalladamente los aspectos comentados aquí.
Por último, mencionar que el éxito que tuvo la franquicia en sus inicios ha continuado a lo largo de todos estos últimos años y se prevé que continúe al menos los mismos años que ya lleva en pie. Porque como ya hemos mencionado, es un destino atractivo para el público sobre todo joven y mientras siga así la demanda, la oferta no será menos.
LS0tCnRpdGxlOiAiRmFzdEZvb2Q6IEFuw6FsaXNpcyBkZWwgTWNEb25hbGRzIgphdXRob3I6ICJBbGJhIEVzdGVsYSBHYXJjaWEoYWxlc2dhcjNAYWx1bW5pLnV2LmVzKSAgXG5cbiBNZWxhbmllIE5ldWZjb3VyKG1lbmV1ZkBhbHVtbmkudXYuZXMpICBcbiBcbiBNaXJlaWEgWWFuZ8O8ZXoobWl5YW5vQGFsdW1uaS51di5lcykuIFxuXG4gVW5pdmVyc2l0YXQgZGUgVmFsw6huY2lhIgpkYXRlOiAiRGljaWVtYnJlIGRlIDIwMjEgKGFjdHVhbGl6YWRvIGVsIGByIGZvcm1hdChTeXMudGltZSgpLCAnJWQtJW0tJVknKWApIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgICNjc3M6ICIuL2Fzc2V0cy9teV9jc3NfZmlsZS5jc3MiCiAgICB0aGVtZTogcGFwZXIKICAgIGhpZ2hsaWdodDogdGV4dG1hdGUgCiAgICB0b2M6IHRydWUKICAgIHRvY19kZXB0aDogMyAKICAgIHRvY19mbG9hdDogCiAgICAgIGNvbGxhcHNlZDogdHJ1ZQogICAgICBzbW9vdGhfc2Nyb2xsOiB0cnVlCiAgICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQogICAgZGZfcHJpbnQ6IGthYmxlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKZWRpdG9yX29wdGlvbnM6IAogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlCi0tLQoKYGBge2NzcywgZWNobyA9IEZBTFNFfQouY29sdW1ucyB7ZGlzcGxheTpmbGV4O30KaDEudGl0bGUge2ZvbnQtc2l6ZTogNDAgcHg7Y29sb3I6ICNkNzIzMWF9CmgxIHtjb2xvcjojZDcyMzFhOyBmb250LXNpemU6IDMwcHggO2ZvbnQtZmFtaWx5OiBBcmlhbCBCbGFja30KaDJ7Y29sb3I6ICNmYTMzNDQ7IGZvbnQtc2l6ZTogMjBweDsgZm9udC1mYW1pbHk6IEFyaWFsfQoKYm9keSB7IGJhY2tncm91bmQtY29sb3I6ICNGRkM0MEN9CmEge2NvbG9yOiAjMDEwMTAxO30KLmxpc3QtZ3JvdXAtaXRlbS5hY3RpdmUsIC5saXN0LWdyb3VwLWl0ZW0uYWN0aXZlOmZvY3VzLCAubGlzdC1ncm91cC1pdGVtLmFjdGl2ZTpob3ZlciB7CiAgICB6LWluZGV4OiAyOwogICAgY29sb3I6IDsKICAgIGJhY2tncm91bmQtY29sb3I6ICNjNDM0MmQ7CiAgICBib3JkZXItY29sb3I6IHBhbGVyZWQ7Cn0KLm5hdi1waWxscyA+IGxpLmFjdGl2ZSA+IGEsIC5uYXYtcGlsbHMgPiBsaS5hY3RpdmUgPiBhOmhvdmVyLCAubmF2LXBpbGxzID4gbGkuYWN0aXZlID4gCgpgYGAKCmBgYHtyIGNodW5rLXNldHVwLCBpbmNsdWRlID0gRkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCAKICAgICAgICAgICAgICAgICAgICAgICNyZXN1bHRzID0gImhvbGQiLAogICAgICAgICAgICAgICAgICAgICAgY2FjaGUgPSBGQUxTRSwgY2FjaGUucGF0aCA9ICIvY2FjaGVzLyIsIGNvbW1lbnQgPSAiIz4iLAogICAgICAgICAgICAgICAgICAgICAgI2ZpZy53aWR0aCA9IDcsICNmaWcuaGVpZ2h0PSA3LCAgIAogICAgICAgICAgICAgICAgICAgICAgI291dC53aWR0aCA9IDcsIG91dC5oZWlnaHQgPSA3LAogICAgICAgICAgICAgICAgICAgICAgY29sbGFwc2UgPSBUUlVFLCAgZmlnLnNob3cgPSAiaG9sZCIsCiAgICAgICAgICAgICAgICAgICAgICBmaWcuYXNwID0gMC42MjgsIG91dC53aWR0aCA9ICI3NSUiLCBmaWcuYWxpZ24gPSAiY2VudGVyIikKYGBgCgpgYGB7ciBvcHRpb25zLXNldHVwLCBpbmNsdWRlID0gRkFMU0V9Cm9wdGlvbnMoc2NpcGVuID0gOTk5KSAjLSBwYXJhIHF1aXRhciBsYSBub3RhY2nDs24gY2llbnTDrWZpY2EKb3B0aW9ucygieWFtbC5ldmFsLmV4cHIiID0gVFJVRSkKYGBgCgpgYGB7ciBrbGlwcHksIGVjaG8gPSBGQUxTRX0Ka2xpcHB5OjprbGlwcHkocG9zaXRpb24gPSBjKCJ0b3AiLCAicmlnaHQiKSkgIy0gcmVtb3Rlczo6aW5zdGFsbF9naXRodWIoInJsZXN1ci9rbGlwcHkiKQpgYGAKCgoKPGhyIGNsYXNzPSJsaW5lYS1ibGFjayI+CgoKVHJhYmFqbyBlbGFib3JhZG8gcGFyYSBsYSBhc2lnbmF0dXJhICJQcm9ncmFtYWNpw7NuIHkgbWFuZWpvIGRlIGRhdG9zIGVuIGxhIGVyYSBkZWwgQmlnIERhdGEiIGRlIGxhIFVuaXZlcnNpdGF0IGRlIFZhbMOobmNpYSBkdXJhbnRlIGVsIGN1cnNvIDIwMjEtMjAyMi4gRWwgcmVwbyBkZWwgdHJhYmFqbyBlc3TDoSBbYXF1w61dKGh0dHBzOi8vZ2l0aHViLmNvbS9tZW5ldWYvdHJhYmFqb19CaWdEYXRhX2VxdWlwbyl7dGFyZ2V0PSJfYmxhbmsifS4gCgoKTGEgcMOhZ2luYSB3ZWIgZGUgbGEgYXNpZ25hdHVyYSB5IGxvcyB0cmFiYWpvcyBkZSBtaXMgY29tcGHDsWVyb3MgcHVlZGVuIHZlcnNlIFthcXXDrV0oaHR0cHM6Ly9wZXJlenA0NC5naXRodWIuaW8vaW50cm8tZHMtMjEtMjItd2ViLzA3LXRyYWJham9zLmh0bWwpe3RhcmdldD0iX2JsYW5rIn0uCgo8aHIgY2xhc3M9ImxpbmVhLXJlZCI+CgoKIyBbMS4gSU5UUk9EVUNDScOTTl17LnZlcmRlY2l0b30KCkVuIGVsIHByZXNlbnRlIHRyYWJham8gdmFtb3MgYSBtb3N0cmFyIGFsZ3Vub3MgZGF0b3MgZGUgaW50ZXLDqXMgZGUgdW5hIGRlIGxhcyBlbXByZXNhcyBtdWx0aW5hY2lvbmFsZXMgbcOhcyBjb25vY2lkYXMgYSBuaXZlbCBtdW5kaWFsLCBNY0RvbmFsZCdzLiBQb3IgdW4gbGFkbywgdmVyZW1vcyBlbCBtZW7DuiBkZSBlc3RhIGZyYW5xdWljaWEsIGFzw60gY29tbyBsb3MgbWFjcm9udXRyaWVudGVzIHF1ZSBjb250aWVuZW4gbG9zIHByb2R1Y3RvcyB5IGxvcyB2YWxvcmVzIG51dHJpY2lvbmFsZXMsIG1vc3RyYW5kbyB5IGV4cGxpY2FuZG8gbG9zIGFzcGVjdG9zIG3DoXMgcmVsZXZhbnRlcy4gVGFtYmnDqW4gdHJhdGFyZW1vcyBkZSBjb21wYXJhcmxvIGNvbiBvdHJvcyBncmFuZGVzIHJlc3RhdXJhbnRlcyBkZSBjb21pZGEgcsOhcGlkYSBlbiBsb3MgRXN0YWRvcyBVbmlkb3MsIHBhw61zIHF1ZSBhY29nZSBtw6FzIGNhbnRpZGFkIGRlIG1hcmNhcyBkZSByZXN0YXVyYW50ZXMgZGUgY29taWRhIHLDoXBpZGEgZW4gZWwgbXVuZG8gcG9yIGV4Y2VsZW5jaWEuIEVuIGxhIHBhcnRlIGZpbmFsLCBjb21lbnRhcmVtb3MgZGUgZm9ybWEgZ2VuZXJhbCBsYSBwb3B1bGFyaWRhZCBkZSBsb3MgbG9jYWxlcyBwb3IgY2l1ZGFkLCBhc8OtIGNvbW8gbGEgZXZvbHVjacOzbiBkZSBzdXMgdmVudGFzIGEgbG8gbGFyZ28gZGUgbG9zIMO6bHRpbW9zIGHDsW9zLiBQb3IgbG8gcXVlIGVuIGVzdGUgdHJhYmFqbyBudWVzdHJvIG9iamV0aXZvIGVzIGluZm9ybWFyIHkgY29uY2llbmNpYXIgYSBsb3MgbGVjdG9yZXMgdW4gcG9jbyBhY2VyY2EgZGUgbG9zIHByb2R1Y3RvcyBvZnJlY2lkb3MgcG9yIE1jRG9uYWxkJ3MgYXPDrSBjb21vIGVsIGltcGFjdG8gcXVlIGVzdGUgaGEgdGVuaWRvIHNvYnJlIGxhIHBvYmxhY2nDs24gZXN0YWRvdW5pZGVuc2UuCgohW01hcmNhIEZyYW5xdWljaWFdKC4vaW1hZ2VuZXMvaW50cm9kdWNjaW9uLmpwZWcpCgojIyAxLjEgQnJldmUgSGlzdG9yaWEKCkVsIHByaW1lciByZXN0YXVyYW50ZSBkZSBNY0RvbmFsZCdzIHNlIHViaWNhYmEgZW4gQ2FsaWZvcm5pYSwgZW4gZWwgYcOxbyAxOTQ4LCBjb21vIHVuIGJhciBkZSBjYXJyZXRlcmEuIEZ1ZXJvbiBsb3MgZG9zIGhlcm1hbm9zIE1hdXJpY2UgeSBSaWNoYXJkIE1jZG9uYWxkIHF1aWVuIGxsZXZhcm9uIGEgY2FibyBlc3RlIHByb3llY3RvLiBMb3MgZWxlbWVudG9zIHF1ZSBsbyBjYXJhY3Rlcml6YWJhbiB5IGZ1ZXJvbiBtb3Rpdm8gZGVsIMOpeGl0byBlcmFuOyBwb3IgdW4gbGFkbywgc2UgcG9kw61hIHBlZGlyIHkgcmVjb2dlciBsb3MgcHJvZHVjdG9zIGRlc2RlIGVsIGNvY2hlLCBsb3MgZ3JhbmRlcyB2ZW50YW5hbGVzIHF1ZSB0ZW7DrWFuIHBlcm1pdMOtYW4gdmVyIGRlc2RlIGZ1ZXJhIGNvbW8gZWwgcGVkaWRvIHNlIHByZXBhcmFiYSB5IHBvciDDumx0aW1vLCBsb3MgYmFqb3MgcHJlY2lvcyBxdWUgbG8gZGlmZXJlbmNpYWJhbiBkZSBjb21wZXRpZG9yZXMuIEVzdGUgw7psdGltbyBlc3R1dm8gYSBwdW50byBkZSBsbGV2YXIgYSBsb3MgaGVybWFub3MgYSBsYSBxdWllYnJhLCBwb3IgbG8gcXVlIGVzdG9zIHR1dmllcm9uIHF1ZSBjZXJyYXIgZWwgbmVnb2NpbyB5IG9yZ2FuaXphciB1bmEgYnVlbmEgZXN0cmF0ZWdpYS4gUmVzdW1pZW5kbywgUmF5IEEuIEtyb2MsIGFsZ3VpZW4gaW1wb3J0YW50ZSBlbiBsb3MgbmVnb2Npb3MgcG9yIGFxdWVsbGEgem9uYSwgdmlvIGVsIHBvdGVuY2lhbCBkZWwgcmVzdGF1cmFudGUgZW4gc2kgeSBjb24gbGEgY2VzacOzbiBkZWwgZGVyZWNobyBkZSBjb21lcmNpYWxpemFyIGxhIG1hcmNhIHBvciBwYXJ0ZSBkZSBsb3MgaGVybWFub3MsIGFicmnDsyBvdHJvIHJlc3RhdXJhbnRlIGVuIElsbGlub2lzLiBZIGFzw60gc2UgcG9kcsOtYSBkZWNpciBxdWUgZW1wZXrDsyBlc3RlIG5lZ29jaW8gcXVlIGFjdHVhbG1lbnRlIHRpZW5lIHRhbnRvIMOpeGl0by4KCgoKIVtQcmltZXIgbG9jYWwgZGUgTWNEb25hbGQnc10oLi9pbWFnZW5lcy9oaXN0b3JpYS5qcGVnKQoKCiMjIDEuMiAgTG9nb3M8L0ZPTlQ+LiB7LnRhYnNldH0KCiMjIyA8Rk9OVCBDT0xPUiA9IkZGNEQwMCI+TG9nbzE8L0ZPTlQ+CgohW0xvZ28xXSguL2ltYWdlbmVzL2xvZ28xLmpwZykKMTk0MC0xOTQ4OgpMYSBoaXN0b3JpYSBkZSBsYSBjYWRlbmEgZGUgcmVzdGF1cmFudGVzIGRlIGNvbWlkYSByw6FwaWRhIG3DoXMgZmFtb3NhIGRlbCBtdW5kbyBjb21lbnrDsyBlbiAxOTM3IGN1YW5kbyBQYXRyaWNrIE1jRG9uYWxkIGxhbnrDsyDCq1RoZSBBaXJkb21lwrssIGVsIHByaW1lciByZXN0YXVyYW50ZSBkZSBsYSBmYW1pbGlhLiBUcmVzIGHDsW9zIG3DoXMgdGFyZGUsIHN1cyBoaWpvcyBsZSBjYW1iaWFyb24gZWwgbm9tYnJlIGEgwqtNY0RvbmFsZOKAmXMgRmFtb3VzIEJhcmJlY3VlwrsuCkVsIHByaW1lciBsb2dvdGlwbyBkZWwgcmVzdGF1cmFudGUgZXN0YWJhIGNvbXB1ZXN0byBwb3IgdW5hIG1hcmNhIGRlbm9taW5hdGl2YSBuZWdyYSwgZGlzdHJpYnVpZGEgZW4gdHJlcyBuaXZlbGVzIHkgZWplY3V0YWRhIGVuIHRyZXMgZXN0aWxvcyBkaWZlcmVudGVzLgoKCiMjIyA8Rk9OVCBDT0xPUj0iRkY0RDAwIj5Mb2dvMjwvRk9OVD4KIVtMb2dvMl0oLi9pbWFnZW5lcy9sb2dvMi5qcGcpCjE5NDgtMTk1MzoKRWwgY29uY2VwdG8gZGUgYmFyYmFjb2EgZnVlIHJlZW1wbGF6YWRvIHBvciBsYXMgaGFtYnVyZ3Vlc2FzLCBxdWUgZXN0YWJhbiBnYW5hbmRvIGNhZGEgdmV6IG3DoXMgcG9wdWxhcmlkYWQgZW4gbG9zIEVzdGFkb3MgVW5pZG9zLiBFbCB0w610dWxvIGRlbCByZXN0YXVyYW50ZSBzZSBtb2RpZmljw7MgZW4gMTk0OCB5IHNlIHJlZGlzZcOxw7MgZWwgbG9nb3RpcG8uIFNlIGHDsWFkZSBsYSBlc3BlY2lmaWNhY2nDs24gwqtidXkgZW0gYnkgdGhlIGJhZ8K7LCBwYXJhIGhhY2VyIGhpbmNhcGnDqSBlbiBsYSBwb3NpYmlsaWRhZCBkZSBjb25zdW1pciBsYSBjb21pZGEgdGFtYmnDqW4gcGFyYSBsbGV2YXIuIEVuIG5lZ3JpdGEgKHkgcmVwZXRpZG8gZG9zIHZlY2VzKSBhcGFyZWNlIGVsIHByZWNpbyBzdXBlciBjb21wZXRpdGl2by4gWSB1biBsb2dvdGlwbyByZXBsZXRvIGRlIGRldGFsbGVzLCBjb24gbGEgaW50ZW5jacOzbiBkZSByZXNhbHRhciB0b2RvcyBsb3MgcHVudG9zIGZ1ZXJ0ZXMgZGVsIHJlc3RhdXJhbnRlOiBsYSBvcmlnaW5hbGlkYWQgZGUgbGEgb2ZlcnRhLCBsYSBtb2RhbGlkYWQgZGUgY29uc3VtbyB5IGVsIGFob3Jyby4KCiMjIyA8Rk9OVCBDT0xPUiA9IkZGNEQwMCI+TG9nbzM8L0ZPTlQ+CiFbTG9nbzNdKC4vaW1hZ2VuZXMvbG9nbzMuanBnKQoxOTUzLTE5Njg6CkxhIGNvbXBhw7HDrWEgZmluYWxtZW50ZSBjYW1iacOzIHN1IG5vbWJyZSBhIHNpbXBsZW1lbnRlIE1hY0RvbmFsZOKAmXMgeSBhcXXDrSBlcyBkb25kZSBjb21pZW56YSB0b2RvLiBFbCBsb2dvIGHDum4gZXN0YWJhIGxlam9zIGRlIGxvIHF1ZSB0b2RvcyBjb25vY2Vtb3MgaG95LCBwZXJvIGVsIGNvbG9yIHJvam8gYXBhcmVjacOzIGVuIGxhIHBhbGV0YSBkZSBjb2xvcmVzLCBkYW5kbyBsYSBkaXJlY2Npw7NuIGNvcnJlY3RhIHBhcmEgbGEgbWFyY2EuRXJhIHVuIGxvZ290aXBvIGJhc3RhbnRlIG1lbW9yYWJsZSB5IHJlY29ub2NpYmxlLCBxdWUgcGVybWFuZWNpw7MgZW4gbGEgZW1wcmVzYSBkdXJhbnRlIDE1IGHDsW9zLgoKIyMjIDxGT05UIENPTE9SPSJGRjREMDAiPkxvZ280PC9GT05UPgohW0xvZ280XSguL2ltYWdlbmVzL2xvZ280LmpwZykKMTk2MS0xOTY4OgpFcyAxOTYxIHkgaGVtb3MgbGxlZ2FkbyBhIHVuIG1vbWVudG8gZGVjaXNpdm8gcGFyYSBNY0RvbmFsZOKAmXM6IGVsIG1vbWVudG8gZW4gcXVlIGFwYXJlY2VuIHBvciBwcmltZXJhIHZleiBsb3MgZmFtb3NvcyDCq0dvbGRlbiBBcmNoZXPCuy4gUGFyYSBlbCBwcm95ZWN0byBkZSB1biBwdW50byBkZSB2ZW50YSBlbiBEb3duZXkgKENhbGlmb3JuaWEpLCBsb3MgaGVybWFub3MgTWNEb25hbGQgZW5jYXJnYW4gZG9zIGdpZ2FudGVzY29zIGFyY29zIGRvcmFkb3MgZW4gbG9zIGV4dHJlbW9zIGRlIGxhIGVzdHJ1Y3R1cmEuIExhIGlkZWEgZXJhIHF1ZSBzZSB2aWVzZSBtZWpvciBpbmNsdXNvIGRlc2RlIGxlam9zLiBFbCBsb2dvdGlwbyBkZSAxOTYxLCBkaXNlw7FhZG8gcG9yIGVsIGRpcmVjdG9yIGNyZWF0aXZvIEppbSBTY2hpbmRsZXIsIGVzdMOhIGluc3BpcmFkbyBlbiBlc3RlIGRldGFsbGUgYXJxdWl0ZWN0w7NuaWNvLiBZIGVzbyBubyBlcyB0b2RvOiBhZGVtw6FzIHNlIGludHJvZHVjZSBlbCBhbWFyaWxsbywgdW4gY29sb3IgcXVlIGluZnVuZGUgZWwgYnVlbiBodW1vciB5IHF1ZSBzZWd1aXLDoSBmb3JtYW5kbyBwYXJ0ZSBkZSBsYSBpZGVudGlkYWQgdmlzdWFsIGRlIGxhIGVtcHJlc2EuCgoKCiMjIyA8Rk9OVCBDT0xPUj0iRkY0RDAwIj5Mb2dvNTwvRk9OVD4KIVtMb2dvNV0oLi9pbWFnZW5lcy9sb2dvNS5qcGcpCjE5NzU6CkxhIG51ZXZhIGltYWdlbiBzZSBpbmNvcnBvcsOzIGEgbGEgaWRlbnRpZGFkIHZpc3VhbCBlbiAxOTc1LiBFbCBlbWJsZW1hIGNvbiBsYSBtYXJjYSBkZW5vbWluYXRpdmEgc2UgY29sb2PDsyBkZW50cm8gZGUgdW4gcmVjdMOhbmd1bG8gcm9qbyBjb24gw6FuZ3Vsb3MgcmVkb25kZWFkb3MuIExhcyBsZXRyYXMgc2UgY2FtYmlhcm9uIGRlIG5lZ3JvIGEgYmxhbmNvLCBsbyBxdWUgcGFyZWPDrWEgbcOhcyBhbWlnYWJsZSB5IGFjb2dlZG9yLgpFc3RhIGluc2lnbmlhIGVzIHByb2JhYmxlbWVudGUgbGEgdmVyc2nDs24gbcOhcyByZWNvbm9jaWJsZSBkZSB0b2RvcyBsb3MgbG9nb3RpcG9zIGRlIGxleWVuZGFzIGRlIGNvbWlkYSByw6FwaWRhIHkgbGEgY29tcGHDscOtYSB0b2RhdsOtYSBsYSB1c2EsIHNpZW5kbyByZWNvbm9jaWJsZSBpbnN0YW50w6FuZWFtZW50ZSBlbiB0b2RvIGVsIG11bmRvIHkgZXZvY2FuZG8gdW5hIHNlbnNhY2nDs24gZGUgYWxlZ3LDrWEsIGZlbGljaWRhZCB5IHBhc2nDs24uCgoKCiMjIyA8Rk9OVCBDT0xPUj0iRkY0RDAwIj5Mb2dvNjwvRk9OVD4KIVtMb2dvNl0oLi9pbWFnZW5lcy9sb2dvNi5qcGcpCkEgcGFydGlyIGRlIDE5ODUgIHNlIG1vZGlmaWNhIHkgc2ltcGxpZmljYSB1bmEgdmV6IG3DoXMgZWwgbG9nb3RpcG8gZW4gdmFyaW9zIHB1bnRvcyBkZWwgbXVuZG8gOiBsb3MgYXJjb3Mgc2Ugc29sYXBhbiBwYXJhIGZvcm1hciBsYSBsZXRyYSBNLiBIZW1vcyBsbGVnYWRvIGFsIGFudGVwYXNhZG8gZGlyZWN0byBkZWwgbG9nb3RpcG8gZGUgaG95LgoKCiMjIyA8Rk9OVCBDT0xPUj0iRkY0RDAwIj5Mb2dvNzwvRk9OVD4KIVtMb2dvN10oLi9pbWFnZW5lcy9sb2dvNy5qcGcpCkEgcGFydGlyIGRlIDIwMDksIExhIGNvbXBhw7HDrWEgTWNEb25hbGTigJlzIGNhbWJpYSBzdSB0cmFkaWNpb25hbCBsb2dvIGRlIGNvbG9yIHJvam8gcG9yIHVubyB2ZXJkZSwgc2Vnw7puIGFudW5jacOzIGxhIG1hcmNhLiBFc3RlIGNhbWJpbyBkZSBjb2xvciBzaW1ib2xpemEgdGXDs3JpY2FtZW50ZSB1bmEgaW1hZ2VuIG3DoXMgZWNvbMOzZ2ljYSB5IHVuYSBudWV2YSBlc3RyYXRlZ2lhIHBvciBwYXJ0ZSBkZSBsYSBlbXByZXNhLiBFbCBjYW1iaW8gZGUgbG9nbyBlcyB1bmEgZGUgbGFzIHTDqWNuaWNhc2RlIG1hcmtldGluZyBxdWUgYWRvcHTDsyBsYSBjYWRlbmEgZGUgY29taWRhIHLDoXBpZGEuIENvbiBlbCBvYmpldGl2byBkZSBtb3N0cmFyIHVuIHBlcmZpbCBtw6FzIGNvbXByb21ldGlkbyBjb24gbGEgcHJlc2VydmFjacOzbiBkZSBsb3MgcmVjdXJzb3MgbmF0dXJhbGVzLCBNY0RvbmFsZOKAmXMgbGFuesOzIHN1IG51ZXZhIGNhbXBhw7FhIHF1ZSBjb25zaXN0ZSBlbiBjYW1iaWFyIGVsIHRyYWRpY2lvbmFsIGZvbmRvIHJvam8gZGUgc3UgbG9nbyBwb3IgdW4gY29sb3IgdmVyZGUgaW50ZW5zby4KCgojIyMgPEZPTlQgQ09MT1I9IkZGNEQwMCI+TG9nbzg8L0ZPTlQ+CiFbTG9nbzhdKC4vaW1hZ2VuZXMvbG9nbzguanBnKQoxOTkzLUhveToKRW4gRXN0YWRvcyBVbmlkb3MsIE1jRG9uYWxkJ3MgaW50cm9kdWpvIGEgbml2ZWwgbmFjaW9uYWwgdW5hIGzDrW5lYSBkZSBjYWbDqSBsbGFtYWRhICJNY0NhZsOpIi4gQSBkaWZlcmVuY2lhIGRlIGxvIHF1ZSBvY3VycmUgZW4gb3Ryb3MgcGHDrXNlcywgIk1jQ2Fmw6kiIGVzIHNvbG8gdW5hIGzDrW5lYSBkZSBiZWJpZGFzIGVzcGVjaWFsZXMsIG5vIHVuYSBjYWZldGVyw61hIGNvbXBsZXRhLiBFbCBlc3RpbG8gZGVsIGxvZ290aXBvIGRlIE1jQ2FmZSBubyBjcmVhIG5pbmfDum4gdsOtbmN1bG8gY29uIGVsIGxvZ290aXBvIGRlIGxhIG1hcmNhIG1hdHJpeiwgTWNEb25hbGTigJlzLiBFbiBjYW1iaW8sIGxhcyBmdWVyemFzIGRlbCBkaXNlw7FvIGRldHLDoXMgZGUgTWNDYWZlIGhhbiBjcmVhZG8gdW5hIGlkZW50aWRhZCBkZSBtYXJjYSBkaXN0aW50aXZhIHkgY29tcGxldGFtZW50ZSBpbmRlcGVuZGllbnRlLgoKIyAyLiBDQVJHQU1PUyBEQVRPUyBZIFBBUVVFVEVTIAoKRXN0ZSB0cmFiYWpvIGhhIHNpZG8gcG9zaWJsZSByZWFsaXphcmxvIGNvbiBsYSBheXVkYSBkZSB2YXJpYXMgZnVlbnRlcyBkZSBkb25kZSBoZW1vcyBzYWNhZG8gbG9zIGRhdG9zLiBFbiBsYSBww6FnaW5hIHdlYiBmYWNpbGl0YWRhIHBvciBsYSBhc2lnbmF0dXJhIChrYWdnbGUpLCBoZW1vcyB1dGlsemlhZG8gcHJpbmNpcGFsbWVudGUgNSBkYXRhc2VzdHMsIHF1ZSBsb3MgaW5kaWNhcmVtb3MgZW4gbGEgw7psdGltYSBwYXJ0ZSwgZW4gbGEgYmlibGlvZ3JhZsOtYS4gUG9yIG90cm8gbGFkbywgaGVtb3MgYWNjZWRpZG8gYSBkb2N1bWVudG9zIG9maWNpYWxlcyBkZWwgcmVzdGF1cmFudGUgb2J0ZW5pZG9zIGVuIGZvcm1hdG8gZXhjZWwgeSBsb3MgaGVtb3MgdHJhbnNmb3JtYWRvIHBhcmEgdHJhYmFqYXIgY29uIGVsbG9zIHkgb2J0ZW5lciBtw6FzIGRhdG9zLgoKCmBgYHtyLCBldmFsID0gVFJVRX0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHJlYWN0YWJsZSkKbGlicmFyeShndCkKbGlicmFyeSh0aWJibGUpCmxpYnJhcnkoInBsb3RseSIpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGhyYnJ0aGVtZXMpCmxpYnJhcnkodmlyaWRpcykKbGlicmFyeShwYXRjaHdvcmspCmxpYnJhcnkoZ2dhbmltYXRlKQpsaWJyYXJ5KHdvcmRjbG91ZDIpCmxpYnJhcnkod2Vic2hvdCkKbGlicmFyeShjb3JycGxvdCkKbGlicmFyeShzcWxkZikKbGlicmFyeShSQ29sb3JCcmV3ZXIpIApsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkoZ2dUaGVtZUFzc2lzdCkKCm1lbnUgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvbWVudTEuMS5jc3YiKQpyZXN0YXVyYW50ZXNVUyA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9GYXN0Rm9vZFJlc3RhdXJhbnRzLmNzdiIpCmZhc3Rmb29kcmVzdGF1cmFudHMgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvZmFzdGZvb2RyZXN0YXVyYW50cy5jc3YiKQpydXRhNCA8LSBoZXJlOjpoZXJlKCJkYXRvcyIsICJEYXRhZmluaXRpX0Zhc3RfRm9vZF9SZXN0YXVyYW50c19NYXkxOS5jc3YiKQpmYXN0Zm9vZHJlc3RhdXJhbnRzMTkgPC0gcmlvOjppbXBvcnQocnV0YTQpCmluZ3Jlc29zIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL2luZ3Jlc29zMS5jc3YiKQp2ZW50YXMgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3Mvc2FsZXMuY3N2IikKYGBgCgoKCiMgMy4gUkVTVEFVUkFOVEVTIEZBU1QgRk9PRCBFTiBFU1RBRE9TIFVOSURPUwoKIyMgMy4xIE7Dum1lcm8gZGUgcmVzdGF1cmFudGVzIEZhc3RGb29kCgpFbiBlc3RlIGFwYXJ0YWRvIG9ic2VydmFtb3MgIG1lZGlhbnRlIGVsIHNpZ3VpZW50ZSBncsOhZmljbyBkZSBiYXJyYXMgZWwgbsO6bWVybyBkZSByZXN0YXVyYW50ZXMgZGUgZmFzdCBmb29kIGVuIHRvZG8gZWwgcGHDrXMgZGUgRUVVVS4gSGVtb3MgYWNvdGFkbyBlbnRyZSBsb3MgMTAgbm9tYnJlcyBtw6FzIHBvcHVsYXJlcywgZW50cmUgZWxsb3MgTWNEb25hbGQncywgQnVyZ3VlciBLaW5nIG8gVGFjbyBCZWxsLgpgYGB7cn0KbWFzX3Jlc3RhdXJhbnRlcyA8LSByZXN0YXVyYW50ZXNVUyAlPiUgCiAgZ3JvdXBfYnkobmFtZSkgJT4lIAogIG11dGF0ZShuX3Jlc3RhdXJhbnRlcyA9IHN1bShOTiA9IG4oKSkpICU+JQogIGRpc3RpbmN0KG5hbWUsIG5fcmVzdGF1cmFudGVzKSAlPiUKICBhcnJhbmdlKGRlc2Mobl9yZXN0YXVyYW50ZXMpKSAlPiUKICBmaWx0ZXIobl9yZXN0YXVyYW50ZXMgPj0xOTIpIAoKICBnZ19yZXN0YXVyYW50ZXMgPC0gZ2dwbG90KG1hc19yZXN0YXVyYW50ZXMsIGFlcyhuYW1lLCBuX3Jlc3RhdXJhbnRlcykpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKyB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJncmF5IiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJncmF5IiksCiAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGQzQwQyIsCiAgICAgICAgY29sb3VyID0gImFsaWNlYmx1ZSIpLCBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIikpCiAgCmdnX3Jlc3RhdXJhbnRlcwpgYGAKCkNvbW8gcG9kZW1vcyB2ZXIsIHBvciBjbGFyYSBkaWZlcmVuY2lhLCBsYSBtYXJjYSBjb24gbcOhcyBsb2NhbGVzIGVzIE1jRG9uYWxkJ3MsIHNlZ3VpZGEgZGUgQnVyZ3VlciBLaW5nIHkgbHVlZ28gZGUgVGFjbyBCZWxsLgoKVW5hIGRlIGxhcyBjbGF2ZXMgZGVsIMOpeGl0byBhbGNhbnphZGEgcG9yIGxhIGVtcHJlc2EgeSBxdWUgaGEgcGVybWl0aWRvIHN1IGV4cGFuc2nDs24gbXVuZGlhbCBzb24gbGFzIHNpZ3VpZW50ZXM6IHBvciB1biBsYWRvLCBsYSBjb25zaXN0ZW5jaWEuIEVzdG8gZXMsIGVuIGN1YWxxdWllciBwYcOtcyBlbiBlbCBxdWUgdCBlbmN1ZW50cmVzLCBsYSBleHBlcmllbmNpYSBlbiBlbCByZXN0YXVyYW50ZSB2YSBhIHNlciBtdXkgc2ltaWxhciwgbG9zIGNsaWVudGVzIHlhIHNhYmVuIHF1ZSBlc3BlcmFyIHBvciBsbyBxdWUgaGFjZSBtdWNobyBtw6FzIGbDoWNpbGVzIHN1cyBkZWNpc2lvbmVzIGRlIHF1ZSBjb21lci4gIERlc3B1w6lzIGRlc3RhY2Fyw61hbW9zIGxhIGlubm92YWNpw7NuLCBwYXJhIHF1ZSBlbCBuZWdvY2lvIG5vIHF1ZWRlIGVzdGFuY2Fkby4gTXV5IGZyZWN1ZW50ZW1lbnRlIGxhIGZyYW5xdWljaWEgbGFuemEgbnVldm9zIHByb2R1Y3RvcyBjb21vIHJlc3B1ZXN0YSBkZSBsYXMgZGVtYW5kYXMgZGVsIGNsaWVudGUsIHNlIHBvZHLDrWEgZGVjaXIgcXVlIGV2b2x1Y2lvbmFuIGNvbiBlbCB0aWVtcG8sIGNvbW8gdmVyZW1vcyB1biBwb2NvIG3DoXMgYWRlbGFudGUuCgojIyAzLjIgSW5ncmVzb3MgcmVzdGF1cmFudGVzIEZhc3RGb29kCgpFbiBlbCBzaWd1aWVudGUgYXBhcnRhZG8sIGFuYWxpemFyZW1vcyBsb3MgaW5ncmVzb3MgZW4gbWlsZXMgZGUgbWlsbG9uZXMgZGUgZMOzbGFyZXMgZGUgbG9zIG1pc21vcyAxMCByZXN0YXVyYW50ZXMgbcOhcyBmYW1vc29zIGRlIEVFVVUuCgpgYGB7cn0KIGRmX2luZ3Jlc29zIDwtIGdncGxvdChpbmdyZXNvcywgYWVzKHg9cmVvcmRlcihSZXN0dXJhbnRlcywgVmFsdWUpLCB5PVZhbHVlLCBmaWxsPVJlc3R1cmFudGVzKSkrCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgY29vcmRfcG9sYXIoc3RhcnQgPSAwLjAxKSArCiAgbGFicyAoeD0iUmVzdGF1cmFudGVzIikgKyBsYWJzKHk9Ik1pbGVzIGRlIG1pbGxvbmVzIGRlIGTDs2xhcmVzIikgKyBsYWJzKHRpdGxlID0gIkluZ3Jlc29zIGRlIGxvcyBSZXN0dXJhbnRlcyBGYXN0Rm9vZCIpICsgbGFicyhzdWJ0aXRsZSA9ICJFbiBtaWxlcyBkZSBtaWxsb25lcyBkZSBkw7NsYXJlcyIpICsgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNGRkM0MEMiKSwKICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNGRkM0MEMiKSkKCmRmX2luZ3Jlc29zCmBgYAoKCkNvbW8gc2Ugb2JzZXJ2YSBjbGFyYW1lbnRlLCBlbiBsYSBwcmltZXJhIHBvc2ljacOzbiB2b2x2ZXLDrWFtb3MgYSBlbmNvbnRyYXIgYSBudWVzdHJvIHJlc3RhdXJhbnRlLCBxdWUgbGxlZ2EgYSBsb3MgNDAgbWlsIG1pbGxvbmVzIGRlIGTDs2xhcmVzIGFudWFsZXMuIFN1cyBpbmdyZXNvcyBlc3TDoW4gbXV5IHBvciBlbmNpbWEgZGUgY3VhbHF1aWVyYSBkZSBsYXMgb3RyYXMgbWFyY2FzLgoKIyA0LiBNQyBET05BTEQnUwpFbiBlc3RlIGN1YXJ0byBhcGFydGFkbywgdmFtb3MgYSBoYWJsYXIgc29icmUgZWwgcmVzdGF1cmFudGUgZW4gY3Vlc3Rpw7NuIGVuIHTDqXJtaW5vcyBnZW5lcmFsZXMgeSBkZSBsb3MgYXNwZWN0b3MgbcOhcyByZWxldmFudGVzLgoKCiMjIDQuMSBQcm9kdWN0b3MgTWNEb25hbGRzCgpFbiBsYSBzaWd1aWVudGUgdGFibGEsIHNlIHB1ZWRlbiBjb25zdWx0YXIgdG9kb3MgbG9zIHByb2R1Y3RvcyBkZSBsYSBjYXJ0YSBxdWUgb2ZyZWNlbi4gU2UgbXVlc3RyYW4gdW4gdG90YWwgZGUgMjYwIHByb2R1Y3Rvcy4KYGBge3J9CmRmX21lbnUgPC0gbWVudSAlPiUKc2VsZWN0KEl0ZW0pCgpyZWFjdGFibGUoZGZfbWVudSwgZGVmYXVsdFBhZ2VTaXplID0gIDgsICBwYWdpbmF0aW9uVHlwZSA9ICJqdW1wIiwgc2hvd1BhZ2VTaXplT3B0aW9ucyA9ICBUUlVFICwgcGFnZVNpemVPcHRpb25zID0gIGMgKCAxMCAsIDUwICwgMTAwLCAxNTAsIDIwMCwgMjYwICksZGVmYXVsdENvbERlZiA9IGNvbERlZigKICAgIGFsaWduID0gImNlbnRlciIsCiAgICBtaW5XaWR0aCA9IDcwLAogICAgaGVhZGVyU3R5bGUgPSBsaXN0KGJhY2tncm91bmQgPSAiI0ZGRDcwMCIpLAogICAgZmlsdGVyYWJsZSA9IFRSVUUpLCAgaGlnaGxpZ2h0ID0gVFJVRSwgb3V0bGluZWQgPSBUUlVFLAogICAgY29sdW1ucyA9IGxpc3QoCiAgYEl0ZW1gID0gY29sRGVmKHN0eWxlID0gZnVuY3Rpb24odmFsdWUpIHsKICAgIGlmICh2YWx1ZSA+IDApIHsKICAgICAgY29sb3IgPC0gIiNGNUM3MTAifQogICAgICBlbHNlIHsKICAgICAgY29sb3IgPC0gIiNCMjIyMjIiCiAgICB9CiAgICBsaXN0KGNvbG9yID0gY29sb3IsIGZvbnRXZWlnaHQgPSAiYm9sZCIsYmFja2dyb3VuZCA9ICIjQ0QyNjI2IikKICB9KSkpCmBgYAoKCgoKCiMjIDQuMiBDYXRlZ29yaWFzIGRlIHByb2R1Y3RvcyBlbiBNY0RvbmFsZHMKCkRlIGVudHJlIHRvZG9zIGxvcyBwcm9kdWN0b3MsIGVzdG9zIHNlIHBvZHLDrWFuIGRpZmVyZW5jaWFyIGVuIGxhcyBzaWd1aWVudGVzIGNhdGVnb3LDrWFzOgoKYGBge3J9Cm0gPC0gbGlzdCgKICBsID0gNTAsCiAgciA9IDUwLAogIGIgPSAxMDAsCiAgdCA9IDEwMCwKICBwYWQgPSA0CikKbWFya2VyID0gbGlzdChjb2xvciA9IGJyZXdlci5wYWwoOSwgIlNldDEiKSkKcCA8LSBwbG90X2x5KAogIHggPSBtZW51JENhdGVnb3J5LAogIG1hcmtlciA9IGxpc3QoY29sb3IgPSAnI0NEMEJCQycpLAogICAgdHlwZSA9ICJoaXN0b2dyYW0iCiklPiUKICBsYXlvdXQoICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIiIpLAogICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiIiksCiAgICAgICAgIGF1dG9zaXplID0gVCkKcApgYGAKCgpZIGF1biBxdWUgcGFyZXpjYSBzb3JwcmVuZGVudGUsIGVzdGUgcmVzdGF1cmFudGUgY3VlbnRhIGNvbiBtw6FzIHZhcmllZGFkIGVuIGNhZsOpcyB5IHTDqXMuIEluY2x1c28gYXVucXVlIGEgcHJpbWVyYSB2aXN0YSBsbyBtw6FzIGRlbWFuZGFkbyBzZWEgdW5hIHNpbXBsZSBoYW1idXJndWVzYSBkZSBjYXJuZSwgYWwgbWVub3MgZW4gbnVlc3RybyBwYcOtcy4gRGUgbG8gcXVlIG1lbm9zIHZhcmllZGFkIGhheSBzZXLDrWEgZGUgZW5zYWxhZGFzLiBRdWl6w6EgdGVuZ2Egc2VudGlkbyBwb3JxdWUgZXMgdW5vIGRlIGxvIHByb2R1Y3RvcyBxdWUgc2UgaGEgaW5jb3Jwb3JhZG8gbcOhcyByZWNpZW50ZW1lbnRlLgoKCgoKCgojIDUuVkFMT1JFUyBOVVRSSUNJT05BTEVTCgpBIGNvbnRpbnVhY2nDs24sIHZhbW9zIGEgZGVzdGFjYXIgbG9zIGFzcGVjdG9zIHkgbG9zIHB1bnRvcyBtw6FzIHJlbGV2YW50ZXMgeSBxdWl6w6EgZGVzdGFjYWJsZXMgZGUgbG9zIHByb2R1Y3RvcyBxdWUgb2ZyZWNlIGxhIG1hcmNhIHBlcm8gZW4gdMOpcm1pbm9zIGRlIGxvcyB2YWxvcmVzIG51dHJpY2lvbmFsZXMuCgojIyA1LjEgwr9DdcOhbCBlcyBlbCBwcm9kdWN0byBjb24gbcOhcyBjYWxvcmlhcz8KCkVsIHByb2R1Y3RvIG3DoXMgY2Fsw7NyaWNvIGRlbCByZXN0YXVyYW50ZSwgc29uIGxvcyBudWdndWV0cywgdGFtYmnDqW4gZXMgcG9ycXVlIGN1ZW50YSBjb24gNDAgcGllemFzLgpgYGB7cn0KZGZfY2Fsb3JpYXMgPC0gbWVudSAlPiUKc2VsZWN0KEl0ZW0sIENhbG9yaWVzKSAKCmRmdG9wMSA8LSBkZl9jYWxvcmlhcyAlPiUgc2xpY2VfbWF4KENhbG9yaWVzLCBuPTEpCgpJbWFnZW4gPC0gImh0dHBzOi8vaS5waW5pbWcuY29tL29yaWdpbmFscy9kNS81Zi8wMy9kNTVmMDM1YzM3ZDg0ZWM1NTkzNGJhNmQ0NjliZWRjZS5qcGciCgpkZnRvcDEgPC0gZGZ0b3AxICU+JSBhZGRfY29sdW1uKEltYWdlbikKClRhYmxhX1BtYXNjYWwgPC0gZGZ0b3AxICU+JSBndCgpCgpUYWJsYV9QbWFzY2FsIDwtIFRhYmxhX1BtYXNjYWwgJT4lCiAgICAgICAgICAgICAgICAgICB0YWJfaGVhZGVyKHRpdGxlID0gbWQoIioqUHJvZHVjdG8gY29uIG1hcyBjYWxvcmlhcyoqIikpCiAgICAgICAgICAgICAgICAgICAKVGFibGFfUG1hc2NhbCA8LSBUYWJsYV9QbWFzY2FsICU+JQogICAgICAgICAgICAgICAgdGFiX29wdGlvbnMoaGVhZGluZy5iYWNrZ3JvdW5kLmNvbG9yID0gImNvcmFsIikgJT4lIHRhYl9vcHRpb25zKGhlYWRpbmcudGl0bGUuZm9udC5zaXplID0gMTUsICBjb2x1bW5fbGFiZWxzLmZvbnQud2VpZ2h0ID0gICJib2xkIikKCgpUYWJsYV9QbWFzY2FsIDwtIFRhYmxhX1BtYXNjYWwgICU+JQogIGd0Ojp0ZXh0X3RyYW5zZm9ybShsb2NhdGlvbnMgPSBjZWxsc19ib2R5KGNvbHVtbnMgPSBjKEltYWdlbikpLCBmbiA9IGZ1bmN0aW9uKHgpIHtndDo6d2ViX2ltYWdlKHgsIGhlaWdodCA9IDUwKX0pICU+JSAgY29sc19hbGlnbigKICAgYWxpZ24gPSAiY2VudGVyIikKClRhYmxhX1BtYXNjYWwKYGBgCgoKCgoKCiMjIDUuMiDCv0N1w6FsIGVzIGVsIHByb2R1Y3RvIGNvbiBtZW5vcyBjYWxvcmlhcz8KCkVsIG1lbm9zIGNhbMOzcmljbywgbMOzZ2ljYW1lbnRlIHNlcsOtYSBsYSBib3RlbGxhIGRlIGFndWEKYGBge3J9CmRmbWluMSA8LSBkZl9jYWxvcmlhcyAlPiUgCnNsaWNlX21pbihDYWxvcmllcywgbj0xKSAlPiUKZmlsdGVyIChJdGVtID09ICJEYXNhbmkgV2F0ZXIgQm90dGxlIikgI0Rhc2FuaSBXYXRlciBCb3R0bGUgZXMgdW5vIGRlIGxvcyBwcm9kdWN0b3MgY29uIG1lbm9zIGNhbG9yaWFzIAoKSW1hZ2VuIDwtICJodHRwczovL2kucGluaW1nLmNvbS9vcmlnaW5hbHMvM2MvZGYvYWUvM2NkZmFlYWE1MDRkYjhhYWYxMDA4NDNhMTJhYWNjOTcucG5nIgoKZGZtaW4xIDwtIGRmbWluMSAlPiUgYWRkX2NvbHVtbihJbWFnZW4pCgoKVGFibGFfUG1pbmNhbCA8LSBkZm1pbjEgJT4lIGd0KCkKClRhYmxhX1BtaW5jYWwgPC0gVGFibGFfUG1pbmNhbCAlPiUKICAgICAgICAgICAgICAgICAgIHRhYl9oZWFkZXIodGl0bGUgPSBtZCgiKipQcm9kdWN0byBjb24gbWVub3MgY2Fsb3JpYXMqKiIpKQogICAgICAgICAgICAgICAgICAgClRhYmxhX1BtaW5jYWwgPC0gVGFibGFfUG1pbmNhbCAlPiUKICAgICAgICAgICAgICAgIHRhYl9vcHRpb25zKGhlYWRpbmcuYmFja2dyb3VuZC5jb2xvciA9ICJjb3JhbCIpICU+JSB0YWJfb3B0aW9ucyhoZWFkaW5nLnRpdGxlLmZvbnQuc2l6ZSA9IDE1LCAgY29sdW1uX2xhYmVscy5mb250LndlaWdodCA9ICAiYm9sZCIpCgoKVGFibGFfUG1pbmNhbCA8LSBUYWJsYV9QbWluY2FsICAlPiUKICBndDo6dGV4dF90cmFuc2Zvcm0obG9jYXRpb25zID0gY2VsbHNfYm9keShjb2x1bW5zID0gYyhJbWFnZW4pKSwgZm4gPSBmdW5jdGlvbih4KSB7Z3Q6OndlYl9pbWFnZSh4LCBoZWlnaHQgPSA1MCl9KSAlPiUgIGNvbHNfYWxpZ24oCiAgIGFsaWduID0gImNlbnRlciIpCgpUYWJsYV9QbWluY2FsCmBgYAoKCgoKIyMgNS4zLiAgUHJvZHVjdG9zIGNvbiBtYXlvciBtYWNyb251dHJpZW50ZXM8L0ZPTlQ+LiB7LnRhYnNldH0KCkVuIGVzdGUgYXBhcnRhZG8sIHZhbW9zIGEgbW9zdHJhciBwb3Igc2VwYXJhZG8sIHF1ZSAxMCBwcm9kdWN0b3MsIGVuIHByaW1lciBsdWdhciwgdGllbmVuIG3DoXMgcHJvdGXDrW5hcywgbHVlZ28gY3XDoWxlcyBjdWVudGFuIGNvbiBtw6FzIGdyYXNhcyB5IGN1YWwgZXN0w6EgY29tcHVlc3RvIGNvbiBtw6FzIGNhcmJvaGlkcmF0b3MuCgpFbiBsb3MgZ3LDoWZpY29zIGRlIGNhZGEgbWFjcm9udXRyaWVudGUgcG9kZW1vcyB2ZXJsbywgc29zdGVuaWVuZG8gZWwgY3Vyc29yIHNvYnJlIGVsbG9zLgoKCiMjIyA8Rk9OVCBDT0xPUj0iRkY0RDAwIj5Qcm90ZWluYTwvRk9OVD4KYGBge3J9CmRmMTRwcm9kIDwtIG1lbnUgJT4lCiAgc2VsZWN0KEl0ZW0sIFByb3RlaW4pICU+JQogIGhlYWQoUHJvdGVpbiwgbiA9IDEwTCklPiUKICBncm91cF9ieShJdGVtLCBQcm90ZWluKSAlPiUKICBhcnJhbmdlKGRlc2MoUHJvdGVpbikpCgpkZjE0cHJvZAoKd29yZGNsb3VkMihkYXRhPWRmMTRwcm9kLCBzaXplPTAuMSkKYGBgCgoKIyMjIDxGT05UIENPTE9SPSJGRjREMDAiPkdyYXNhczwvRk9OVD4KYGBge3J9CnRvdGFsZmF0IDwtIG1lbnUgJT4lCiBzZWxlY3QoSXRlbSwgRmF0KSAKCgpkZl9mYXQgPC0gdG90YWxmYXQgJT4lCmhlYWQoRmF0LCBuPSAxMEwpICU+JQpncm91cF9ieShJdGVtLCBGYXQpICU+JQphcnJhbmdlKGRlc2MoRmF0KSkKCmRmX2ZhdAoKCnBsb3RfbHkoeCA9IGRmX2ZhdCRJdGVtLCB5PWRmX2ZhdCRGYXQsY29sb3IgPSBkZl9mYXQkSXRlbSxjb2xvcnMgPSBwYWxldHRlKCJQYXN0ZWwgMiIpLCB0eXBlID0gImJveCIpICU+JSAKICBsYXlvdXQodGl0bGUgPSAiTG9zIDEwIHByb2R1Y3RvcyBjb24gbcOhcyBncmFzYSIsCiAgICAgICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICIiKSwKICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIiIpLAogICAgICAgICBzaG93bGVnZW5kPUZBTFNFLAogICAgICAgICBhdXRvc2l6ZSA9IFQpIApgYGAKIAoKIyMjIDxGT05UIENPTE9SPSJGRjREMDAiPkNhcmJvaGlkcmF0b3M8L0ZPTlQ+CmBgYHtyfSAKY2FyYm9zIDwtIG1lbnUgJT4lCnNlbGVjdChJdGVtLENhcmJvaHlkcmF0ZXMpCgpkZl9jYXJib3MgPC0gY2FyYm9zICU+JQpoZWFkKENhcmJvaHlkcmF0ZXMsIG49IDEwTCkgJT4lCmdyb3VwX2J5KEl0ZW0sIENhcmJvaHlkcmF0ZXMpICU+JQphcnJhbmdlKGRlc2MoQ2FyYm9oeWRyYXRlcykpCgpkZl9jYXJib3MKCnBsb3RfbHkoeCA9IGRmX2NhcmJvcyRJdGVtLCB5PWRmX2NhcmJvcyRDYXJib2h5ZHJhdGVzLGNvbG9yID0gZGZfY2FyYm9zJEl0ZW0sIGNvbG9ycyA9IHBhbGV0dGUoImFscGhhYmV0IiksIHR5cGUgPSAiYm94IikgJT4lIAogICAgICAgICBsYXlvdXQodGl0bGU9IkxvcyAxMCBwcm9kdWN0b3MgY29uIG3DoXMgY2FyYm9oaWRyYXRvcyIsCiAgICAgICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICIiKSwKICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIiIpLAogICAgICAgICBzaG93bGVnZW5kPUZBTFNFLAogICAgICAgICBhdXRvc2l6ZSA9IFQpCmBgYAoKCkVuIGN1YW50byBhbCBwcm9kdWN0byBjb24gbcOhcyBwcm90ZcOtbmFzIHNlIGVuY29udHJhcsOtYSBlbCBTdGVhayAmIEVnZyBNY011ZmZpbiwgcXVlIHNlIGVuY3VlbnRhIGRlbnRybyBkZSBsYSBzZWNjacOzbiBkZSBsb3MgZGVzYXl1bm9zLiBDb24gbcOhcyBncmFzYSB5IGEgbGEgdmV6IGNvbiBtw6FzIGhpZHJhdG9zIHRlbmRyw61hbW9zIGFsIEJhY29uLCBFZ2cgJiBDaGVlc2UgQmlzY3VpdCAoTGFyZ2UgQmlzY3VpdCkuCgoKCgoKIyMgNS40LiAgUHJvZHVjdG9zIGNvbiBtYXlvciBtaWNyb251dHJpZW50ZXMgPC9GT05UPi4gey50YWJzZXR9IAoKIyMjIDxGT05UIENPTE9SPSJGRjREMDAiPlZpdGFtaW5hQTwvRk9OVD4KRW4gZXN0ZSBhcGFydGFkbywgcmVwZXRpbW9zIGxhIG1pc21hIG9wZXJhY2nDs24gcXVlIGVuIGVsIHB1bnRvIGFudGVyaW9yIHBlcm8gYWhvcmEgY29uIGxvcyBtaWNyb251dHJpZW50ZXMsIHNlcGFyYWRvcyBlbjogdml0YW1pbmEgQSB5IEMsIGZpYnJhLCBjYWxjaW8geSBoaWVycm8uIEVuIGxhIHBhcnRlIGluZmVyaW9yIGRlIGNhZGEgbGlzdGEsIGxvIHBvZGVtb3Mgb2JzZXJ2YXIgdGFtYmnDqW4gZ3LDoWZpY2FtZW50ZQoKYGBge3J9CnZpdGFtaW5hQSA8LSBtZW51ICU+JQpzZWxlY3QoSXRlbSxWaXRhbWluQSkKCmRmX3ZpdGFtaW5hMSA8LSB2aXRhbWluYUEgJT4lCmhlYWQoVml0YW1pbkEsIG49IDEwTCklPiUKYXJyYW5nZShkZXNjKFZpdGFtaW5BKSkKCmRmX3ZpdGFtaW5hMQoKZ3JhZmljbyA8LSBkZl92aXRhbWluYTEgJT4lCiAgZ2dwbG90KCBhZXMoSXRlbSwgVml0YW1pbkEsIHNpemUgPSAwLjc1LCBjb2xvcj0gIm9yYW5nZSIpKSArCiAgZ2VvbV9wb2ludCgpICsKICB0aGVtZV9idygpKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICBsYWJzKHggPSBOVUxMKSArIHRoZW1lKGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MueD1lbGVtZW50X2JsYW5rKCkpICsgbGFicyh0aXRsZT0gIkxvcyAxMCBwcm9kdWN0b3MgY29uIG3DoXMgVml0YW1pbmEgQSIpICsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAnd2hlYXQxJywgY29sb3VyID0gJ3JlZCcpKSArIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIiksCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIiwKICAgICAgICBjb2xvdXIgPSAiI0ZGQzQwQyIpKQoKZ2dwbG90bHkoZ3JhZmljbykKYGBgCgoKIyMjIDxGT05UIENPTE9SPSJGRjREMDAiPlZpdGFtaW5hQzwvRk9OVD4KYGBge3J9CnZpdGFtaW5hQyA8LSBtZW51ICU+JQpzZWxlY3QoSXRlbSxWaXRhbWluQykKCmRmX3ZpdGFtaW5hMiA8LSB2aXRhbWluYUMgJT4lCmhlYWQgKFZpdGFtaW5DLCBuID0gMTBMKSU+JQphcnJhbmdlKGRlc2MoVml0YW1pbkMpKQoKZGZfdml0YW1pbmEyCgoKZGZncmFmaWNvMSA8LSBnZ3Bsb3QoZGZfdml0YW1pbmEyLCBhZXMoSXRlbSwgY29sb3I9Vml0YW1pbkMpKSArIAogIGdlb21fYmFyKGZpbGw9TkEpICsgCiAgY29vcmRfZmxpcCgpICsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAnbGlnaHRibHVlMScpKSArIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIiksCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIiksCiAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNGRkM0MEMiKSkKCmdncGxvdGx5KGRmZ3JhZmljbzEpCmBgYAoKCgojIyMgPEZPTlQgQ09MT1I9IkZGNEQwMCI+RmlicmE8L0ZPTlQ+ICAgICAgICAKYGBge3J9ICAgICAgICAKICAgICAgICAKZmlicmEgPC0gbWVudSAlPiUKc2VsZWN0KEl0ZW0sRGlldGFyeUZpYmVyKQoKZGZfZmlicmEgPC0gZmlicmEgJT4lCmhlYWQoRGlldGFyeUZpYmVyLCBuPSAxMEwpICU+JQphcnJhbmdlKGRlc2MoRGlldGFyeUZpYmVyKSkKCmRmX2ZpYnJhCgoKbSA8LSBsaXN0KAogIGwgPSA1MCwKICByID0gNTAsCiAgYiA9IDEwMCwKICB0ID0gMTAwLAogIHBhZCA9IDQKKQptYXJrZXIgPSBsaXN0KGNvbG9yID0gYnJld2VyLnBhbCg5LCAiU2V0MSIpKQpwIDwtIHBsb3RfbHkoCiAgeCA9IG1lbnUkQ2F0ZWdvcnksCiAgbWFya2VyID0gbGlzdChjb2xvciA9ICcjNDUxNzFEJykKKQogICAgICAgICAgICAgICAgCm1lbnUgJT4lICAKcGxvdF9seSggeCA9IGRmX2ZpYnJhJEl0ZW0sIHkgPSBkZl9maWJyYSREaWV0YXJ5RmliZXIsIHR5cGU9InNjYXR0ZXIiLCBtb2RlID0gIm1hcmtlcnMiICwgbWFya2VyPWxpc3QoIGNvbG9yPWNvbG9yUmFtcFBhbGV0dGUoYnJld2VyLnBhbCg4LCJEYXJrMiIpKSgxMDApICwgb3BhY2l0eT0wLjkpICkgJT4lIGxheW91dCh0aXRsZSA9ICJMb3MgMTAgcHJvZHVjdG9zIGNvbiBtw6FzIGZpYnJhIiwKICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIiIpLAogICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiIiksCiAgICAgICAgIHNob3dsZWdlbmQ9RkFMU0UsYXV0b3NpemUgPSBGLCB3aWR0aCA9IDUwMCwgaGVpZ2h0ID0gNDAwLG1hcmdpbj1tKQpgYGAKCgojIyMgPEZPTlQgQ09MT1I9IkZGNEQwMCI+Q2FsY2lvPC9GT05UPgpgYGB7cn0gICAgICAgIApjYWxjaW8gPC0gbWVudSAlPiUKc2VsZWN0KEl0ZW0sQ2FsY2l1bSkKCmRmX2NhbGNpdW0gPC0gY2FsY2lvICU+JQpoZWFkKENhbGNpdW0sIG49IDEwTCkgJT4lCmFycmFuZ2UoZGVzYyhDYWxjaXVtKSkKCmRmX2NhbGNpdW0KCgpwIDwtIGdncGxvdChkZl9jYWxjaXVtLCBhZXMoSXRlbSwgQ2FsY2l1bSkpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgZ2VvbV9zZWdtZW50KGFlcyh4PWZvcmNhdHM6OmZjdF9yZW9yZGVyKEl0ZW0sIENhbGNpdW0sIC5kZXNjID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICB4ZW5kPWZvcmNhdHM6OmZjdF9yZW9yZGVyKEl0ZW0sIENhbGNpdW0sIC5kZXNjID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICB5PTAsCiAgICAgICAgICAgICAgICAgICB5ZW5kPUNhbGNpdW0sIGNvbG9yPXBhbGV0dGUoIlRhYmxlYXUgMTAiKSkpICsgCiAgZ2VvbV9zbW9vdGgoKSArCiAgdGhlbWUoYXhpcy50aXRsZS54PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy54PWVsZW1lbnRfYmxhbmsoKSkgKwogIGxhYnModGl0bGUgPSAiTG9zIDEwIHByb2R1Y3RvcyBjb24gbcOhcyBjYWxjaW8iLAogICAgICAgICAgICAgIHN1YnRpdGxlID0gImFuw7FvIDIwMTkiLCAKICAgICAgICAgICAgICBjYXB0aW9uID0gIkRhdG9zIHByb3ZlbmllbnRlcyBkZSBLYWdnbGUiLAogICAgICAgICAgICAgIHggPSAiUHJvZHVjdG9zIiwKICAgICAgICAgICAgICB5ID0gIkNhbGNpbyIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIiksCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIikpCgoKZ2dwbG90bHkocCkKYGBgCgoKCgojIyMgPEZPTlQgQ09MT1I9IkZGNEQwMCI+SGllcnJvPC9GT05UPgpgYGB7cn0KaGllcnJvIDwtIG1lbnUgJT4lCiBzZWxlY3QoSXRlbSwgSXJvbikgCgpkZl9oaWVycm8gPC0gaGllcnJvICU+JQpoZWFkKElyb24sIG49IDEwTCkgJT4lCmdyb3VwX2J5KEl0ZW0sIElyb24pICU+JQphcnJhbmdlKGRlc2MoSXJvbikpCgpkZl9oaWVycm8KCmRmIDwtIGdncGxvdChkZl9oaWVycm8sIGFlcyh4PUl0ZW0sIHk9SXJvbikpICsKICBnZW9tX3NlZ21lbnQoIGFlcyh4PUl0ZW0sIHhlbmQ9SXRlbSwgeT0wLCB5ZW5kPUlyb24pKSArCiAgZ2VvbV9wb2ludCggc2l6ZT01LCBjb2xvcj0icmVkIiwgZmlsbD1hbHBoYSgib3JhbmdlIiwgMC4zKSwgYWxwaGE9MC43LCBzaGFwZT0yMSwgc3Ryb2tlPTIpICsgdGhlbWUoYXhpcy50aXRsZS54PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy54PWVsZW1lbnRfYmxhbmsoKSkgKyAgbGFicyh0aXRsZSA9ICJMb3MgMTAgcHJvZHVjdG9zIGNvbiBtw6FzIGNhbGNpbyIsCiAgICAgICAgICAgICAgc3VidGl0bGUgPSAiYW7DsW8gMjAxOSIsIAogICAgICAgICAgICAgIGNhcHRpb24gPSAiRGF0b3MgcHJvdmVuaWVudGVzIGRlIEthZ2dsZSIsCiAgICAgICAgICAgICAgeCA9ICJQcm9kdWN0b3MiLAogICAgICAgICAgICAgIHkgPSAiQ2FsY2lvIikgKyAKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGQzQwQyIpLAogICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGQzQwQyIpKQoKZ2dwbG90bHkoZGYpCmBgYAoKCkVsIGRlc2F5dW5vIGRlIFNhdXNhZ2UgTWNNdWZmaW4gd2l0aCBFZ2csIGVzIGVsIHF1ZSBlbmNvbnRyYW1vcyBjb24gbcOhcyB2aXRhbWluYSBBIHkgZWwgQmFjb24sIEVnZyAmIENoZWVzZSBCaXNjdWl0IChSZWd1bGFyIEJpc2N1aXQpLCBjb24gbcOhcyB2aXRhbWluYSBDLgoKRW4gY3VhbnRvIGFsIGFsaW1lbnRvIGNvbiBtw6FzIGZpYnJhLCBkaXLDrWFtb3MgZWwgRWdnIE1jTXVmZmluLCBxdWUgZW4gbHVnYXIgZGUgY2FybmUsIHBvc2VlIHVuIGh1ZXZvIGVuIHN1IGludGVyaW9yLgoKU2F1c2FnZSBNY011ZmZpbiB3aXRoIEVnZyB2dWVsdmUgYSByZXBldGlyc2UgY29tbyBlbCBwcm9kdWN0byBjb24gbcOhcyBjYWxjaW8gZGUgZW50cmUgdG9kb3MgeSBTdGVhayAmIEVnZyBNY011ZmZpbiBlcyBlbCBxdWUgYXBhcmVjZSBjb24gbcOhcyBoaWVycm8uCgoKCgojIyA1LjUgQ29ycmVsYWNpw7NuCgpFbiBlc3RlIGdyw6FmaWNvIHNlIGNvbmNlbnRyYSB5IHNlIG11ZXN0cmEgbGEgY29ycmVsYWNpw7NuIHF1ZSB0aWVuZW4gZW50cmUgc8OtIGxvcyBudXRyaWVudGVzIGRlIGxvcyBwcm9kdWN0b3MgcXVlIHNlIGVuY3VlbnRyYW4gZW4gbGEgY2FydGEgZGUgTWNEb25hbGQncy4KYGBge3J9Cm1lbnUgPC0gbmEub21pdChtZW51KQpzY2FsZWRtZW51IDwtIGRhdGEuZnJhbWUoc2NhbGUobWVudVtjKDQ6MjQpXSkpCm1lbnUxPC1jYmluZChtZW51WzE6M10sc2NhbGVkbWVudSkKCk0gPC0gY29yKHNjYWxlZG1lbnUpCmNleC5iZWZvcmUgPC0gcGFyKCJjZXgiKQpwYXIoY2V4ID0gMC43KQpjb3JycGxvdChNLCBpbnNpZyA9ICJibGFuayIsIG1ldGhvZCA9ICJzcXVhcmUiLCAgdGwuY2V4ID0gLjc1KQpwYXIoY2V4ID0gY2V4LmJlZm9yZSkKYGBgCgoKCiMjIDUuNi4gQ29tYmkgcGVyZmVjdGEKCkVuIGVzdGUgcHVudG8gbGxhbWFtb3MgY29tYmkgcGVyZmVjdGEsIGFsIHByb2R1Y3RvIG1lbm9zIGNhbMOzcmljbyBkZSBjYWRhIGNhdGVnb3LDrWEuCkVzdG8gaGFjZSBwb3NpYmxlIHF1ZSBhdW4gc2llbmRvIE1jIERvbmFsZCdzIHVuIGx1Z2FyIGRlIGNvbWlkYSBwb2NvIHNhbHVkYWJsZSBzZSBwdWVkYSBzYWJlciBxdWUgb3BjaW9uZXMgcHVlZGUgY29nZXIgdW4gY2xpZW50ZSBxdWUgcHJldGVuZGEgY29tZXIgbGFzIG1lbm9zIGNhbG9yw61hcyBwb3NpYmxlcyBwb3IgbG8gcXVlIGFsIHRlbmVyIGxvcyBwcm9kdWN0b3MgbWVub3MgY2Fsw7NyaWNvcyBkZSBjYWRhIGNhdGVnb3JpYSwgZWwgY2xpZW50ZSBwdWVkZSBjb25mb3JtYXJzZSBhc8OtIHN1IHByb3BpbyBtZW7DuiBhdGVuZGllbmRvIGEgbG8gcXVlIGVzdGUgc29saWNpdGEuCmBgYHtyfQpNaW5jYWw8LWFnZ3JlZ2F0ZShtZW51JENhbG9yaWVzLCBieT1saXN0KG1lbnUkQ2F0ZWdvcnkpLCBGVU49bWluKQpjb2xuYW1lcyhNaW5jYWwpWzFdPC0iQ2F0ZWdvcnkiCmNvbG5hbWVzKE1pbmNhbClbMl08LSJDYWxvcmllcyIKTWluY2FsbWVudTwtc3FsZGYoInNlbGVjdCBhLkNhdGVnb3J5LGEuSXRlbSwgYS5DYWxvcmllcyBmcm9tIG1lbnUgYSwgTWluY2FsIGIgd2hlcmUgYS5DYXRlZ29yeT09Yi5DYXRlZ29yeSBhbmQgYS5DYWxvcmllcz09Yi5DYWxvcmllcyIgKQojIyBUaGUgYmVsb3cgdGFibGUgZ2l2ZXMgdGhlIG1pbnVtdW0gQ2Fsb3JpZSBJdGVtIGZyb20gRWFjaCBDYXRlZ29yeQpNaW5jYWxtZW51CgoKCmtuaXRyOjprYWJsZShNaW5jYWxtZW51KSAlPiUKICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBGKSAlPiUKICBjb2x1bW5fc3BlYygxLCBib2xkID0gVCwgYm9yZGVyX3JpZ2h0ID0gVCkgJT4lCiAgcm93X3NwZWMoMSwgYm9sZCA9IFQsIGNvbG9yID0gIndoaXRlIiwgYmFja2dyb3VuZCA9IHBhbGV0dGUoIlBhc3RlbCAyIikpICU+JSAKICByb3dfc3BlYygyOjIsIGJvbGQgPSBULCBjb2xvciA9ICJ3aGl0ZSIsIGJhY2tncm91bmQgPSBwYWxldHRlKCJUYWJsZWF1IDEwIikgKSAlPiUKICByb3dfc3BlYygzOjMsIGJvbGQgPSBULCBjb2xvciA9ICJ3aGl0ZSIsIGJhY2tncm91bmQgPSBwYWxldHRlKCJQb2x5Y2hyb21lIDM2IikgKSAlPiUKICByb3dfc3BlYyg0OjUsIGJvbGQgPSBULCBjb2xvciA9ICJ3aGl0ZSIsIGJhY2tncm91bmQgPSBwYWxldHRlKCJPa2FiZS1JdG8iKSApICU+JQogIHJvd19zcGVjKDY6NiwgYm9sZCA9IFQsIGNvbG9yID0gIndoaXRlIiwgYmFja2dyb3VuZCA9IHBhbGV0dGUoIlBhaXJlZCIpICkgJT4lCiAgcm93X3NwZWMoNzo3LCBib2xkID0gVCwgY29sb3IgPSAid2hpdGUiLCBiYWNrZ3JvdW5kID0gIiMyMjk3RTYiKSAlPiUKICByb3dfc3BlYyg4OjE2LCBib2xkID0gVCwgY29sb3IgPSAid2hpdGUiLCBiYWNrZ3JvdW5kID0gIiMyOEUyRTUiKSAlPiUgCiAgcm93X3NwZWMoMTc6MjMsIGJvbGQgPSBULCBjb2xvciA9ICJ3aGl0ZSIsIGJhY2tncm91bmQgPSAiIzYxRDA0RiIpICU+JQogIHJvd19zcGVjKDI0OjI1LCBib2xkID0gVCwgY29sb3IgPSAid2hpdGUiLCBiYWNrZ3JvdW5kID0gIiNERjUzNkIiKSAlPiUgCiAgcm93X3NwZWMoMCwgYW5nbGUgPSAwKQpgYGAKCgoKIyA2LlRJUE9TIERFIEFMSU1FTlRPUwoKQ29tbyB0b2RvcyBzYWJlbW9zIE1jRG9uYWxkJ3Mgb2ZyZWNlIHVuYSBjYXJ0YSBtdXkgYW1wbGlhIGRlIHByb2R1Y3RvcyBkZSB0b2RvIHRpcG8sIG3DoXMgZ3JhbmRlcyBvIG3DoXMgcGVxdWXDsW9zLCBtw6FzIGNhbMOzcmljbyBvIG1lbm9zLCBtw6FzIHNhbm9zIG8gbWVub3MgbnV0cmljaW9uYWxtZW50ZSBoYWJsYW5kbywgZXRjLiAKRXMgY29ub2NpZG8gc29icmV0b2RvIHBvciBsYXMgY29taWRhcyB5IGNlbmFzIHNpZW5kbyBlc3RhcyBlbiBsYXMgcXVlIHZhbiBtw6FzIGNsaWVudGVzLCBzaW4gZW1iYXJnbyBNYyBkb25hbGQncyBkZXNkZSBxdWUgYWJyaW8gbGEgem9uYSBkZSBNYyBDYWZlIGN1ZW50YSBjb24gdW5hIGdyYW4gdmFyaWVkYWQgZGUgY2Fmw6lzIHBhcmEgY3VhbHF1aWVyIGhvcmEgZGVsIGTDrWEgYXPDrSBjb21vIGRlIGRlc2F5dW5vcyB5IGRlIHNuYWNrcy4gWSBjYWJlIGRlc3RhY2FyIHF1ZSB0YW1iacOpbiBoYSBxdWVyaWRvIGFkYXB0YXJzZSBhIG9wY2lvbmVzIG3DoXMgc2FsdWRhYmxlcyBwYXJhIGFzw60gbGxlZ2FyIGEgdG9kYXMgbGFzIHBlcnNvbmFzLCBvZnJlY2llbmRvIGNvbWlkYSBtw6FzIHNhbmEgeSBtZW5vcyBzYW5hLlBvciBlc28gdmFtb3MgYSBtb3N0cmFyIDMgdGlwb3MgZGUgYWxpbWVudG9zLCBxdWUgcHJvYmFibGVtZW50ZSBubyBzZWFuIGNvbm9jaWRvcyBuaSBhc29jaWFkb3MgYSB1bmEgZnJhbnF1aWNpYSBjb21vIE1jIERvbmFsZCdzIHRhbiBhcnJhaWdhZGEgYSBsYXMgaGFtYnVyZ3Vlc2FzLgoKIyMgNi4xLkJyZWFrZmFzdAoKCmBgYHtyfQpnZ3Bsb3Qoc3Vic2V0KG1lbnUsQ2F0ZWdvcnk9PSJCcmVha2Zhc3QiKSwgYWVzKHJlb3JkZXIoSXRlbSxDYWxvcmllcyksQ2Fsb3JpZXMsZmlsbD1DYWxvcmllcykpICsgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrZ2d0aXRsZSgiQnJlYWtmYXN0IFZzIENhbG9yaWVzIikgKyB4bGFiKCJJdGVtIikgKyB5bGFiKCJDYWxvcmllcyIpICArIGNvb3JkX2ZsaXAoKSArIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIiksCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIikpCmBgYAoKCiMjIDYuMi4gU2FsYWQgTWVudQpgYGB7cn0KZ2dwbG90KHN1YnNldChtZW51LENhdGVnb3J5PT0iU2FsYWRzIiksIGFlcyhyZW9yZGVyKEl0ZW0sQ2Fsb3JpZXMpLENhbG9yaWVzLGZpbGw9Q2Fsb3JpZXMpKSArIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSAgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpK2dndGl0bGUoIlNhbGFkcyBNZW51IFZzIENhbG9yaWVzIikgKyB4bGFiKCJJdGVtIikgKyB5bGFiKCJDYWxvcmllcyIpICArIGNvb3JkX2ZsaXAoKSArIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIiksCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIikpCmBgYAoKCiMjIDYuMy4gU25hY2tzIApgYGB7cn0KZ2dwbG90KHN1YnNldChtZW51LENhdGVnb3J5PT0iU25hY2tzICYgU2lkZXMiKSwgYWVzKHJlb3JkZXIoSXRlbSxDYWxvcmllcyksQ2Fsb3JpZXMsZmlsbD1DYWxvcmllcykpICsgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrZ2d0aXRsZSgiU25hY2tzICYgU2lkZXMgTWVudSBWcyBDYWxvcmllcyIpICsgeGxhYigiSXRlbSIpICsgeWxhYigiQ2Fsb3JpZXMiKSAgKyBjb29yZF9mbGlwKCkgKyB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGQzQwQyIpLAogICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGQzQwQyIpKQpgYGAKCgojIyA2LjQuIENvZmZlZSBhbmQgVGVhCmBgYHtyfQpDb2ZmZWVhbmR0ZWE8LXN1YnNldChtZW51LENhdGVnb3J5PT0iQ29mZmVlICYgVGVhIikKQ29mZmVlYW5kdGVhIDwtIENvZmZlZWFuZHRlYVtvcmRlcigtQ29mZmVlYW5kdGVhJENhbG9yaWVzKSxdCkNvZmZlZWFuZHRlYTwtQ29mZmVlYW5kdGVhWzE6MjAsXQpnZ3Bsb3QoQ29mZmVlYW5kdGVhLCBhZXMocmVvcmRlcihJdGVtLENhbG9yaWVzKSxDYWxvcmllcyxmaWxsPUNhbG9yaWVzKSkgKyBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKStnZ3RpdGxlKCJDb2ZmZWUgJiBUZWEgTWVudSBWcyBDYWxvcmllcyIpICsgeGxhYigiSXRlbSIpICsgeWxhYigiQ2Fsb3JpZXMiKSAgKyBjb29yZF9mbGlwKCkgKyB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGQzQwQyIpLAogICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGQzQwQyIpKQpgYGAKIAoKCiMgNy5QT1BVTEFSSURBRAoKRW4gZXN0ZSBhcGFydGFkbyBhbmFsaXphcm1lb3MgeSBtb3N0cmFyZW1vcyBsYSAicG9wdWxhcmlkYWQiIGRlIG51ZXN0cm8gcmVzdGF1cmFudGUgZW4gYWxndW5hcyBkZSBsYXMgY2l1ZGFkZXMgZGUgRUVVVSwgYSB0cmF2w6lzIGRlIHVuIGdyw6FmaWNvIGRlIGJhcnJhcy4gVmVyZW1vcyBlbCBuw7ptZXJvIGRlIGxvY2FsZXMgZGUgbGEgZnJhbnF1aWNpYSBjb24gbG9zIHF1ZSBjdWVudGFuIGxhcyBjaXVkYWRlcyBxdWUgc2UgbXVlc3RyYW4uCgohW1Jlc3RhdXJhbnRlIE1jIERvbmFsZCdzXSguL2ltYWdlbmVzL3BvcHUuanBlZykKCgoKYGBge3J9IApudW1tYWMgPC0gcmVzdGF1cmFudGVzVVMgJT4lCiAgc2VsZWN0KGNpdHksIG5hbWUpICU+JQogICBncm91cF9ieShjaXR5KSAlPiUgCiAgbXV0YXRlKG5uX21hYyA9IHN1bShOTj1uKCkpKSAlPiUgCiAgZmlsdGVyKG5hbWUgPT0gIk1jRG9uYWxkJ3MiKSAlPiUgCiAgZGlzdGluY3QoY2l0eSwgbm5fbWFjKSAlPiUKICB1bmdyb3VwKCkKCnRvcDEwIDwtIG51bW1hYyAlPiUKICBzbGljZV9tYXgobm5fbWFjICwgbj0xMCkgCgpncmFmaWNvMSA8LSBnZ3Bsb3QgKHRvcDEwLCBhZXMoeD1ubl9tYWMsIHkgPSBjaXR5KSwgYWVzKGZjdF9yZXYobm5fbWFjKSkpICsgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCBmaWxsID0gInJlZCIpICsgY29vcmRfZmxpcCgpICsgbGFicyh4ID0gIk51bWVybyBkZSBNY0RvbmFsZHMiLCB5ID0gIkNpdHkiKStsYWJzKHRpdGxlID0gIkxvY2FsZXMgcG9yIGNpdWRhZCIpICArIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIiksCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIikpCgpncmFmaWNvMQpgYGAKCgoKQ29uIGdyYW4gdmVudGFqYSBzb2JyZSBsb3MgZGVtw6FzLCBsYSBjaXVkYWQgcXVlIGN1ZW50YSBjb24gbcOhcyBsb2NhbGVzIHNlcsOtYSBDaW5jaW5uYXRpLgoKWSBlcyBxdWUgZXN0ZSByZXN0YXVyYW50ZSBlcyBtdW5kaWFsbWVudGUgcmVjb25vY2lkbywgdGFudG8gcG9yIHNlciB1bmEgb3JnYW5pemFjacOzbiBjb21lcmNpYWwgZGUgYWx0YSBjYWxpZGFkLCBjb21vIHBvciBzZXIgdW5hIGRlIGxhcyBtZWpvcmVzIG9wb3J0dW5pZGFkZXMgZGUgb2ZlcnRhIGRlIEZyYW5xdWljaWFzLiBQdWVkZSBwdWVzLCBxdWUgbGEgY2xhdmUgZGUgc3Ugw6l4aXRvIGVzIHRlbmVyIHVuYSBiYXNlIG11eSBmaXJtZSBlbiBzdXMgZnJhbnF1aWNpYXRhcmlvcy4KCiMgOC4gVkVOVEFTCgpQb3Igw7psdGltbywgdmFtb3MgYSBoYWJsYXIgc29icmUgbGFzIHZlbnRhcyBkZWwgcmVzdGF1cmFudGUsIGluZm9ybWFjacOzbiBxdWUgaGVtb3MgY29uc2lkZXJhZG8gaW1wb3J0YW50ZSB0ZW5lciBlbiBjdWVudGEgeSBwb3IgZWxsbyBtb3N0cmFyb3MuIFkgZXMgcXVlIGVzdGEgbWFyY2EgY3VlbnRhIGNvbiAyNiBtaWwgbG9jYWxlcyBlbiB0b2RvIGVsIG11bmRvLCAxNCBtaWwgbWlsbG9uZXMgZGUgY29taWRhcyB2ZW5kaWRhcyBhbCBhw7FvLCA1IGVzdGFibGVjaW1pZW50b3MgbnVldm9zIHNlIGFicmVuIGNhZGEgZMOtYSwgdmVudGEgZGUgMTQ1IGhhbWJ1cmd1ZXNhcyBwb3Igc2VndW5kbyB5IHVuIG1pbGzDs24geSBtZWRpbyBkZSBlbXBsZWFkb3MuCgpgYGB7cn0KdmVudGFzbWMgPC0gdmVudGFzJT4lCiAgc2VsZWN0KEHDsW9zLFZlbnRhcykKCgogZ2dwbG90KCBkYXRhPSB2ZW50YXMsIGFlcyh4PUHDsW9zLCB5PVZlbnRhcykpICsKICAgIGdlb21fbGluZSgpICsKICAgIGdlb21fcG9pbnQoKSArCiAgICBnZ3RpdGxlKCJFdm9sdWNpw7NuIGRlIGxhcyB2ZW50YXMgZGUgTUMgRG9uYWxkJ3MgZGVzZGUgMjAwNS0yMDE5IikgKwogICB0aGVtZV9pcHN1bSgpICsKICAgIHlsYWIoIk7Dum1lcm8gZGUgdmVudGFzIikgKwogICAgdHJhbnNpdGlvbl9yZXZlYWwoQcOxb3MpICsgdGhlbWUocGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAic2FucyIpLAogICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzYW5zIiksCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzYW5zIiksCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzYW5zIiksCiAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGQzQwQyIpLAogICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGQzQwQyIpKQpgYGAKCkVuIGVzdGUgZ3LDoWZpY28gdmVtb3MgbGEgZXZvbHVjacOzbiBkZSBsYXMgdmVudGFzIGRlIE1jRG9uYWxkJ3MgZW50cmUgMjAwNSB5IDIwMTkKCiMjIDguMSBMb2NhbGVzIHkgZW1wbGVhZG9zCgpgYGB7cn0KCmdyYWZsb2MgPC0gZ2dwbG90KCBkYXRhPSB2ZW50YXMsIGFlcyh4PUHDsW9zLCB5PUxvY2FsZXMpKSAKICAKIGdyYWZsb2MgKyAgZ2VvbV9saW5lKCkgKwogICAgZ2VvbV9wb2ludCgpICsKICAgIGdndGl0bGUoIkV2b2x1Y2nDs24gZGUgbG9zIGVzdGFibGVjaW1pZW50b3MgZGUgTUMgRG9uYWxkJ3MgZGVzZGUgMjAwNS0yMDE5IikgKwogICB0aGVtZV9pcHN1bSgpICsKICAgIHlsYWIoIk7Dum1lcm8gZGUgZXN0YWJsZWNpbWllbnRvcyIpICsKICAgIHRyYW5zaXRpb25fcmV2ZWFsKEHDsW9zKSsKICAgICAgbGFicyhzdWJ0aXRsZSA9ICJFbiBtaWxlcyIpICsgdGhlbWUocGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAic2FucyIpLAogICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzYW5zIiksCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzYW5zIiksCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzYW5zIiksCiAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGQzQwQyIpLAogICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZGQzQwQyIpKQpgYGAKCmBgYHtyfQogZW1wbGVhZG9zIDwtIHZlbnRhcyU+JQogIHNlbGVjdChBw7FvcyxFbXBsZWFkb3MpCiAgCiAgZ3JhZmVtcGwgPC0gZ2dwbG90KCBkYXRhPSB2ZW50YXMsIGFlcyh4PUHDsW9zLCB5PUVtcGxlYWRvcykpIAogICBncmFmZW1wbCsgIGdlb21fbGluZSgpICsKICAgIGdlb21fcG9pbnQoKSArCiAgICBnZ3RpdGxlKCJFdm9sdWNpw7NuIGRlbCBuw7ptZXJvIGRlIGVtcGxlYWRvcyBkZSBNQyBEb25hbGQncyBkZXNkZSAyMDEzLTIwMTkiKSArCiAgIHRoZW1lX2lwc3VtKCkgKwogICAgeWxhYigiTsO6bWVybyBkZSBFbXBsZWFkb3MiKSArCiAgICB0cmFuc2l0aW9uX3JldmVhbChBw7FvcykgKyB0aGVtZShwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJzYW5zIiksCiAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gInNhbnMiKSwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gInNhbnMiKSwKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gInNhbnMiKSwKICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIiksCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkZDNDBDIikpCiBlbXBsZWFkb3M8LSBuYS5vbWl0KGVtcGxlYWRvcykKYGBgCiAKIApQYXJ0aWN1bGFybWVudGUgTWNEb25hbGTigJlzIHJlc3VsdGEgdW4gY2FzbyBpbnRlcmVzYW50ZSBhIGNvbnRlbXBsYXIgcHVlc3RvIHF1ZSBhw7FvIGNvbiBhw7FvIGVzIHBvc2libGUgbm90YXIgcXVlIHRpZW5lIG1lbm9zIGVtcGxlYWRvcyBwZXJvIGNyZWNlIGRlIGZvcm1hIGltcG9ydGFudGUuIExhIGZpcm1hIHF1ZSBlbiBzdSBtb21lbnRvIHB1ZG8gbGxlZ2FyIGEgcHJlc3VtaXIgZGUgaGFiZXIgY29udHJhdGFkbyBhIHVubyBkZSBjYWRhIG9jaG8gdHJhYmFqYWRvcmVzIGVuIGxvcyBFc3RhZG9zIFVuaWRvcyBoYSBpZG8gcmVkdWNpZW5kbyBsYSBjYW50aWRhZCBkZSBjb2xhYm9yYWRvcmVzLCBjb3NhIHF1ZSBwb2Ryw61hIHBhcmVjZXIgbmVnYXRpdmEgcHVlcyBlbCBjcmVjaW1pZW50byBtdWNoYXMgdmVjZXMgaW1wbGljYSBxdWUgZXMgbmVjZXNhcmlvIHN1bWFyIGEgbcOhcyBwZXJzb25hcy4KVGFsIGNvbW8gbG8gcHJlc2VudGFtb3MgZW4gbGEgZ3LDoWZpY2EgZGUgZXN0ZSBkw61hLCBkZSAyMDEyIGEgMjAxOCBlcyBwb3NpYmxlIG5vdGFyIGNvbW8gaGEgaWRvIGRpc21pbnV5ZW5kbyBkZSBmb3JtYSBzaWduaWZpY2F0aXZhIGxhIGNhbnRpZGFkIGRlIGVtcGxlYWRvcyBkZSBNY0RvbmFsZOKAmXMgYSBuaXZlbCBnbG9iYWwuIENvbW8gc2UgbG9ncmEgb2JzZXJ2YXIsIGR1cmFudGUgMjAxMiBoYWLDrWEgNDQwIG1pbCB0cmFiYWphZG9yZXMsIHBhcmEgMjAxNSB5YSBlcmFuIDQyMCBtaWwgbWllbnRyYXMgcXVlIHBhcmEgZWwgYcOxbyAyMDE4IGxhIGNhbnRpZGFkIHlhIHNlIGhhYsOtYSByZWR1Y2lkbyBhIGxhIG1pdGFkIGNvbiByZXNwZWN0byBhIGxvIHJlcG9ydGFkbyBlbiAyMDE1LCBlcyBkZWNpciwgc2UgdGllbmUgcmVnaXN0cm8gZGUgc29sbyAyMTAgbWlsIGVtcGxlYWRvcyBoYXN0YSBlbCBhw7FvIHBhc2Fkby4KIArCv1BvciBxdcOpIGhheSBtZW5vcyBlbXBsZWFkb3Mgc2kgaGF5IG3DoXMgcmVzdGF1cmFudGVzPwoKRWwgaGVjaG8gZGUgcXVlIGxhIG1hcmNhIGRlIGxvcyBhcmNvcyBkb3JhZG9zIHRlbmdhIG1lbm9zIHBlcnNvbmFsIHkgbcOhcyByZXN0YXVyYW50ZXMgb2JlZGVjZSBwcmluY2lwYWxtZW50ZSBhIGxhIHZpc2nDs24gYSBmdXR1cm8gZGUgbGEgY29tcGHDscOtYSwgYSBsYSB0ZWNub2xvZ8OtYSB5IGxhIGZvcm1hIGVuIHF1ZSBoYSBkZWNpZGlkbyBnZXN0aW9uYXJzZS4gRXNwZWPDrWZpY2FtZW50ZSBlbiBlbCBjYXNvIGRlIGxvcyBlbXBsZWFkb3MsIGVzIHBvc2libGUgbm90YXIgcXVlIE1jRG9uYWxk4oCZcyBoYSBkZWNpZGlkbyBhcG9zdGFyIGVuIGdyYW4gbWVkaWRhIHBvciBhY2Npb25lcyBjb21vIGxhIG9wY2nDs24gZGUgcXVlIGxhcyBwZXJzb25hcyBwaWRhbiBzdSBjb21pZGEgYSB0cmF2w6lzIGRlIGFwcHMgZGVzZGUgbGFzIGN1YWxlcyBwdWVkZW4gaW5jbHVzbyBwYWdhciB5IG90cmFzIGhlcnJhbWllbnRhcyBkZSBzZWxmLXNlcnZpY2UgZW4gbG9zIHJlc3RhdXJhbnRlcywgY29tbyBraW9zY29zIGRlc2RlIGxvcyBjdWFsZXMgbG9zIGNvbnN1bWlkb3JlcyBzZSBlbmNhcmdhbiBkZSBnZXN0aW9uYXIgc3VzIMOzcmRlbmVzLiBTZSBlc3BlcmEgcXVlIHBhcmEgZmluYWxlcyBkZSBlc3RlIGHDsW8sIGVuIEVzdGFkb3MgVW5pZG9zLCBtw6FzIGRlIDEyIG1pbCB1YmljYWNpb25lcyBkZSBNY0RvbmFsZOKAmXMgY3VlbnRlbiBjb24gbWVuw7pzIGRpZ2l0YWxlcyB5IGtpb3Njb3MgZGUgYXV0b3NlcnZpY2lvLgoKCiMgQ09OQ0xVU0lPTgpEZXNwdcOpcyBkZWwgYW7DoWxpc2lzIHJlYWxpemFkbyBlbiBlbCBwcmVzZW50ZSB0cmFiYWpvIHBvZGVtb3MgbGxlZ2FyIGEgdW5hIHNlcmllIGRlIGNvbmNsdXNpb25lcyByZXNwZWN0byBhbCByZXN0YXVyYW50ZSBlbiBjdWVzdGnDs246IE1jIERvbmFsZOKAmXMuIExhIGZyYW5xdWljaWEgbcOhcyBleGl0b3NhIGEgbml2ZWwgbXVuZGlhbCwgYSBwZXNhciBkZSBoYWJlcnNlIGVuZnJlbnRhZG8gYSBkZXNhZsOtb3MgZGUgY29tcGV0ZW5jaWEgYSBuaXZlbCBtdW5kaWFsLCBzaWd1ZSBlbiBlbCB0b3AgMSBkZSByZXN0YXVyYW50ZXMgZGVsIG11bmRvLgoKQ29tbyB0b2RvIGVsIG11bmRvIHNhYmUsIGVsIG1lbsO6IHNpZW1wcmUgaGEgc2lkbyBtdXkgcGFyZWNpZG8gYSBsbyBsYXJnbyBkZSBsb3MgYcOxb3MsIHN1ZWxlbiBpbmNvcnBvcmFyIG51ZXZvcyBwcm9kdWN0b3MsIHN1cHJpbWlyIG90cm9zLCBlbiBmdW5jacOzbiBkZWwgw6l4aXRvIHF1ZSB0ZW5nYW4sIHBlcm8gY29tbyBoZW1vcyBtZW5jaW9uYWRvIGFudGVyaW9ybWVudGUgc8OtIHF1ZSBlcyB2ZXJkYWQgcXVlIGNvbW8gZGVzdGlubyBwYXJhIGNvbWVyIGFsZ28gZXMgdW5hIGFwdWVzdGEgc2VndXJhIHBvcnF1ZSBzYWJlcyBwZXJmZWN0YW1lbnRlIGxvIHF1ZSB2YXMgYSBjb21lciwgZWwgZW50b3JubyBvIGVsIGxvY2FsIGVuIGVsIHF1ZSB0ZSB2YXMgYSBlbmNvbnRyYXIsIGVsIGFtYmllbnRlLCBldGMuIFlhIHF1ZSB0b2RvcyBsb3MgcmVzdGF1cmFudGVzLCBlc3TDqXMgZW4gbGEgcGFydGUgZGVsIG11bmRvIGVuIGxhIHF1ZSBlc3TDqXMsIHNvbiBtdXkgc2ltaWxhcmVzIGVudHJlIHPDrS4gCgpBIHBlc2FyIGRlIGxhcyBjcsOtdGljYXMgeSBvcGluaW9uZXMgcXVlIHJlY2liZSBlc3RlIHJlc3RhdXJhbnRlIGRlIGNvbWlkYSByw6FwaWRhLCBsYSB2YXJpZWRhZCBkZSBwcm9kdWN0b3MgcXVlIG9mcmVjZSBlcyBtdXkgYW1wbGlhIHkgcGVybWl0ZSBxdWUgZWwgY29uc3VtaWRvciB0ZW5nYSBkaWZlcmVudGVzIG9wY2lvbmVzIGFsIGd1c3RvLgoKT3RybyBhc3BlY3RvIGltcG9ydGFudGUgY29tZW50YWRvIGVuIGVzdGUgdHJhYmFqbywgZXMgcXVlIGHDum4gcXVlIGxhIGdlbnRlIG5vIHNlIHBhcmUgYSBwZW5zYXJsbywgZXN0YSBtYXJjYSBoYWNlIHVuYSBncmFuIGxhYm9yIHNvY2lhbCwgY29uIGltcGFjdG8gcG9zaXRpdm8gYSBsYSBzb2NpZWRhZC4gQ29tbyBwb3IgZWplbXBsbyBlbiB0w6lybWlub3MgZGUgcHVlc3RvcyBkZSB0cmFiYWpvLCBvIGNvbW8gc2UgbWVuY2lvbmEgZW4gbGEgw7psdGltYSBwYXJ0ZSwgbGEgaW52ZXJzacOzbiBlbiBudWV2b3MgbcOpdG9kb3MgdGVjbm9sw7NnaWNvcyB5IGxhIHZpc2nDs24gcGFyYSBlbCBmdXR1cm8gcXVlIHNlIHByZXbDqSBzaWVtcHJlIGFkYXB0w6FuZG9zZSBhIGxvcyBkaXN0aW50b3MgY2FtYmlvcyBxdWUgc3VjZWRlbiBhIG51ZXN0cm8gYWxyZWRlZG9yLgoKTnVlc3RybyBvYmpldGl2byBjb24gZXN0ZSBwcm95ZWN0bywgeSBlc3BlcmFtb3MgcXVlIGNvbnNlZ3VpZG8sIGVzIGRhciBhIGNvbm9jZXIgdW4gcG9jbyBtw6FzIGVsIHJlc3RhdXJhbnRlIGVuIGxvIHF1ZSBzZSB0cmF0YSBkZSBsb3MgcHJvZHVjdG9zIHF1ZSBvZnJlY2UuIEF1bnF1ZSB5YSBiYXN0YW50ZSBjb25vY2lkYSBlcyBsYSBtYXJjYSB5IHN1IG1lbsO6LCBubyBlc3TDoSBkZSBtw6FzIGNvbm9jZXIgY29tcGxldGFtZW50ZSBvIHBvciBsbyBtZW5vcyBkZXRhbGxhZGFtZW50ZSBsb3MgYXNwZWN0b3MgY29tZW50YWRvcyBhcXXDrS4KClBvciDDumx0aW1vLCBtZW5jaW9uYXIgcXVlIGVsIMOpeGl0byBxdWUgdHV2byBsYSBmcmFucXVpY2lhIGVuIHN1cyBpbmljaW9zIGhhIGNvbnRpbnVhZG8gYSBsbyBsYXJnbyBkZSB0b2RvcyBlc3RvcyDDumx0aW1vcyBhw7FvcyB5IHNlIHByZXbDqSBxdWUgY29udGluw7plIGFsIG1lbm9zIGxvcyBtaXNtb3MgYcOxb3MgcXVlIHlhIGxsZXZhIGVuIHBpZS4gUG9ycXVlIGNvbW8geWEgaGVtb3MgbWVuY2lvbmFkbywgZXMgdW4gZGVzdGlubyBhdHJhY3Rpdm8gcGFyYSBlbCBww7pibGljbyBzb2JyZSB0b2RvIGpvdmVuIHkgbWllbnRyYXMgc2lnYSBhc8OtIGxhIGRlbWFuZGEsIGxhIG9mZXJ0YSBubyBzZXLDoSBtZW5vcy4KCgoKCgojIEJJQkxJT0dSQUZJQQoKLSBbZW5sYWNlIGEgbGEgcMOhZ2luYSB3ZWIgZGUgbGEgYXNpZ25hdHVyYV0oaHR0cHM6Ly9wZXJlenA0NC5naXRodWIuaW8vaW50cm8tZHMtMjEtMjItd2ViL2luZGV4Lmh0bWwpCi0gW2VubGFjZSBnYWxlcmlhIGRlIGdyw6FmaWNvcyBkZSBnZ3Bsb3QyXShodHRwczovL3d3dy5yLWdyYXBoLWdhbGxlcnkuY29tLykKLSBbcmVwb3NpdG9yaW8gZGUgbG9zIGRhdG9zIGRlbCB0cmFiYWpvXShodHRwczovL3d3dy5rYWdnbGUuY29tL2plc3lmYXgvbWMtZG9uYWxkLW1lbnUtYW5hbHlzaXMpCi0gW3JlcG9zaXRvcmlvIGRlIGxvcyBkYXRvcyBkZWwgdHJhYmFqb10oaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9tYXJjZGV2ZWF1eC9tY2RvbmFsZC1zLW1lbnUvc2NyaXB0KQotIFtyZXBvc2l0b3JpbyBkZSBsb3MgZGF0b3MgZGVsIHRyYWJham9dKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZGV2aXNhbmdlZXRoYS9jYWxvcmllcy13ZS1lYXQtaW4tbWNkb25hbGQtcy9yZXBvcnQpCi0gW3JlcG9zaXRvcmlvIGRlIGxvcyBkYXRvcyBkZWwgdHJhYmFqb10oaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9tYXJjZGV2ZWF1eC9tY2RvbmFsZC1zLW1lbnUvc2NyaXB0KQotIFtyZXBvc2l0b3JpbyBkZSBsb3MgZGF0b3MgZGVsIHRyYWJham9dKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vYWRob2s5My9udXRyaXRpb24tdmFsdWUtaW4tbWNkb25hbGQtcy1mb29kL3JlcG9ydCkKLSBbZW5sYWNlIGEgbGEgcMOhZ2luYSB3ZWIgZGUgbG9zIGRhdG9zIGVjb27Ds21pY29zIGRlbCB0cmFiYWpvXShodHRwczovL2luZm9ncmFtLmNvbS9pbmdyZXNvcy1hbnVhbGVzLWRlLW1jZG9uYWxkcy1taWxlcy1kZS1taWxsb25lcy1kZS1kb2xhcmVzLTFobnE0MXFsMHczZDYzeikKLSBbZW5sYWNlIGEgbGEgcMOhZ2luYSB3ZWIgZGUgbG9zIGRhdG9zIGVjb27Ds21pY29zIGRlbCB0cmFiYWpvXShodHRwczovL2VzLndpa2lwZWRpYS5vcmcvd2lraS9BbmV4bzpDYWRlbmFzX2RlX2NvbWlkYV9yJUMzJUExcGlkYV9wb3JfaW5ncmVzb19hbnVhbCkKYGBgCgoKPGJyPjxicj4KCjxkaXYgY2xhc3M9InRvY2lmeS1leHRlbmQtcGFnZSIgZGF0YS11bmlxdWU9InRvY2lmeS1leHRlbmQtcGFnZSIgc3R5bGU9ImhlaWdodDogMDsiPjwvZGl2PgoKCgoKCgoKCgoK