Cargando las librerias necesarias

library (tidyverse)
library (foreign)
library (ggplot2)
library(dplyr)
library(scales)
library(ggrepel)
library(lubridate)
library(readxl)
library(writexl)
library(psych)
library(opencage)
library(httr)
library(geosphere)
library(leaflet)
library(ggmap)
library(janitor)

Cargando paleta de colores

colores_base <- c("darkorange", "darkgoldenrod", "tan")
generar_variantes <- function(color, n) {
  color_fun <- colorRampPalette(c("ivory", color))
  return(color_fun(n))
}
mi_paleta <- c(colores_base, generar_variantes(colores_base[1], 10), generar_variantes(colores_base[2], 10), generar_variantes(colores_base[3], 10))

Cargando las bases de datos necesarias

Parte I

#Desempeño de la Empresa
Autoparts<-read.csv("C:\\Users\\ca\\Desktop\\R Studio\\Datos Evidencia 1\\US_Auto_Parts_Industry.csv") 
CarProduction<-read.csv("C:\\Users\\ca\\Desktop\\R Studio\\Datos Evidencia 1\\US_Auto_Production_Sales.csv")
ImpCartonBox<-read.csv("C:\\Users\\ca\\Desktop\\R Studio\\Datos Evidencia 1\\Importers of Cartons boxes cases of corrugated paper or board 2020-2021.csv")
ExpCartonBox<-read.csv("C:\\Users\\ca\\Desktop\\R Studio\\Datos Evidencia 1\\Exporters of Carton boxes cases of corrugated paper or board 2020-2021.csv")
RH_info<-read.csv("C:\\Users\\ca\\Desktop\\R Studio\\Datos Evidencia 1\\form_rh_datos.csv")
Data1 <- read.csv("C:\\Users\\ca\\Desktop\\R Studio\\Datos Evidencia 1\\mx_exportacion_autos.csv")
RHB <-read.csv("C:\\Users\\ca\\Desktop\\R Studio\\Datos Evidencia 1\\form_rh_bajas_datosB.csv")
Ndatos<- read.csv ("C:\\Users\\ca\\Desktop\\R Studio\\Datos Evidencia 1\\hybrid_car_units.csv")
mx_exauto <- read.csv("C:\\Users\\ca\\Desktop\\R Studio\\Datos Evidencia 1\\mex_exports_autoparts.csv")
Autopartes <- read.csv("C:\\Users\\ca\\Desktop\\R Studio\\Datos Evidencia 1\\Autopartes.csv")
ventas_carton <- read.csv("C:\\Users\\ca\\Desktop\\R Studio\\Datos Evidencia 1\\ventas.csv")

Parte II

datos_2022 <- read.csv("C:\\Users\\ca\\Desktop\\R Studio\\Datos Evidencia 1\\B_form_rh_bajas_datos_2022.csv")
datos_2023 <- read.csv("C:\\Users\\ca\\Desktop\\R Studio\\Datos Evidencia 1\\B_BDD_FORM_BAJAS_2023.csv")
datos_actuales <- read.csv("C:\\Users\\ca\\Desktop\\R Studio\\Datos Evidencia 1\\form_rh_datos (1).csv")
datos_2023 <- datos_2023[complete.cases(datos_2023),]

#Union de bases de datos
df_bajas <- bind_rows(datos_2022, datos_2023)
df_bajas <- as.data.frame(lapply(df_bajas, toupper))

FORM

La empresa regiomontana FORM desarrolla soluciones de empaque que generan valor agregado en la cadena de suministro de sus clientes, considerando no solo la protección de los productos, sino también las necesidades productivas, operativas y de almacenaje, siempre teniendo al ser humano como centro de sus procesos. “No importa de qué autoparte se trate, nosotros tenemos la solución”. (FORM, 2023).

[Sitio Web de la Empresa] (https://form.com.mx/)

PARTE I - EXPLORAR Y CONOCER LA EMPRESA Y SU CONTEXTO

Resumen Kick Off y visita a la planta

Podrás encontrar esta información en la Parte de ANEXOS situada al final del documento.

Antecedentes de la Empresa

Visión

En 2033 seremos una de las cinco mejores compañías de México que generan valor dentro de la cadena de suministro de las industrias que más valoran la forma en la que se protegen y trasladan las cosas.

Misión

Transformar nuestro entorno y resolver retos industriales de nuestros clientes a través de la colaboración, provocando nuevas oportunidades que potencian nuestro modelo de negocio, para alcanzar nuestros ideales.

Objetivos Estratégicos

  1. Inteligencia comercial.
  2. Sistematizar la producción.
  3. Generar un sentido de pertenencia en los colaboradores.
  4. Diversificación, principalmente en Estados Unidos.
  5. Convertirse en la empresa con mejores remuneraciones en Nuevo León.

Desempeño de la Empresa

  1. Acreedor al Premio Nacional de Envase en 2010, 2014,2015,2016,2017,2019 y 2022, reconociendo la sostenibilidad de los envases y embalajes como producto de la innovación.

  2. Innovación con patente global que permite a las compañías reducir espacio y ahorrar en logística. Se trata de una caja que disminuye el espacio en almacén y aumenta la capacidad de empaque un 10-15% para productos del sector automotriz.

  3. En 2022 Tesla se convirtió en uno de sus nuevos socios, FORM le provee cajas de cartón personalizadas, es una línea personalizada en donde se crean piezas vista, electrónicas o de Clase A.

  4. En los últimos 5 años la empresa a duplicado su crecimiento y en pandemia logró mantener su volumen de ventas.

  5. Gracias a la inversión en años anteriores, hoy en día la empresa cuenta la certificación ISO 9000-2015.

Valor Agregado

  1. Especialización en cartón corrugado.
  2. Versatilidad en retornables.
  3. Consultoría en Ingeniería de empaque.
  4. Software de Administración de empaque.
  5. Visión de adquisición de clientes.
  6. Ahorro en tiempos de producción.
  7. Caben más productos en un empaque.
  8. Control de inventario anticipado a la demanda con mínimos y máximos.

Gráficas de RRHH

# Creando un Data Frame
RH1<-RH_info%>%select(FECHA.DE.NACIMIENTO,GENERO,FECHA.DE.ALTA,Primer.mes,X4to.mes,PUESTO,DEPARTAMENTO,SALARIO.DIARIO.IMSS,ESTADO.CIVIL,TARJETA.CUENTA)
View(RH1)
# Calcular los 6 puestos más altos en función de la variable "PUESTO"
top_5_puestos <- RH1 %>%
  count(PUESTO) %>%
  top_n(5, wt = n)

# Filtrar el conjunto de datos para incluir solo los 5 puestos más altos
RH1_top_5_puestos <- RH1 %>%
  filter(PUESTO %in% top_5_puestos$PUESTO)

# Crear el gráfico con los 5 puestos más altos
g <- ggplot(RH1_top_5_puestos, aes(PUESTO, fill = GENERO)) +
  labs(
    title = "Top 6 de Puestos de Trabajo por Género",
    x = "Puesto (Abreviatura)"
  ) +
  ylab("No. Personas") +
  theme(plot.title = element_text(size = rel(2), colour = "darkgoldenrod3")) +
  geom_bar(position = "dodge") +
  scale_fill_manual(values = mi_paleta) +
  theme(axis.title.x = element_text(face = "bold", size = 10)) +
  theme_minimal()

print(g)

Se muestra la distribución de género de los 6 principales puestos de trabajo, donde se observa una mayor cantidad de mujeres en FORM, especialmente en el puesto de ayudante general.

RHB <- rename (RHB,MOTIVO.DE.BAJA = "MOTIVO.DE.BAJA")
Bajas_por_genero<- select(RHB,GENERO,MOTIVO.DE.BAJA)
ggplot(Bajas_por_genero, aes(GENERO))+geom_bar(aes(fill=MOTIVO.DE.BAJA), width = 0.5)+ggtitle ("Motivos de baja por genero")+ theme_minimal() + scale_fill_manual(values = mi_paleta) + geom_text(
    aes(label = ..count..),
    stat = "count",
    position = position_stack(vjust = 0.5),
    size = 3
  )

Se puede ver una diferencia significativa en el género de los empleados, puesto que existen más mujeres que hombres. De igual forma, la diferencia entre los motivos de baja de los empleados es notoria, pues en ambos sexos el principal motivo es por faltas. Esto es algo alarmante para FORM, ya que significa que los empleados no tienen un compromiso laboral.

ggplot(RHB, aes(GENERO)) +
  geom_bar(aes(fill = GENERO), width = .25) +  # Utiliza GENERO para determinar los colores
  labs(title = "Distribución de Género por Días Laborados ante de Salir",
       x = "Género",
       y = " Promedio de Días  de trabajo") +
  theme_minimal() + scale_fill_manual(values = mi_paleta)

En la gráfica se muestran los días trabajados antes de salir de la empresa por genero; Las mujeres tienen un promedio superior al de los hombres. Se puede observar que los hombres que salieron de la empresa trabajan en un rango de 100 días y las mujeres en aproximadamente 130 días.

rh_m <- RH_info %>%
  slice(-22)
municipios <- rh_m %>%
  filter(ESTADO=="NUEVO LEON") %>%
  group_by(MUNICIPIO, GENERO) %>%
  summarise(total_personas = n_distinct(NOMBRE))
ggplot(municipios, aes(x = MUNICIPIO, y = total_personas, fill = GENERO)) +
  geom_col() +
  labs(title = "Colaboradores por Municipio",
       x = "Municipio",
       y = "Total de Personas",
       fill = "Género") +
  theme_minimal() + scale_fill_manual(values = mi_paleta) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

En este gráfico podemos observar a que municipio pertenece cada uno de los colaboradores, esta información nos permite identificar la distancia o el tiempo que les toma llegar a la planta. Con esta información podemos tomar decisiones en cuanto a transporte para personal o incluso identificar posibles riesgos.

Contexto de la Industria

Industria Automotriz

MÉXICO

De acuerdo con Data México y el DENUE 2022 la fabricación de automóviles y camiones registró 73 unidades económicas; siendo CDMX (9), EDOMEC (9) y Nuevo León (7) los estados con más unidades. Otros estados del norte qué cuentan con un número significante de unidades económicas son Baja California y Coahuila de Zaragoza.

Los estados qué más han recibido Inversión Extranjera Directa en 2022, fueron Guanajuato ($989 millones de USD), CDMX ($515 millones de USD ) y Baja California ($329 Millones de USD); estas inversiones provienen de 3 principales países siendo estos Estados Unidos con $1,327 Millones de USD, Japón con $911 Millones de USD y Corea del Sur con $507 millones de USD.

Esta información es importante contemplarla, ya que permite conocer en que estados se está produciendo e invirtiendo más en el ámbito Automotriz, y por ende, pueden representar zonas de oportunidad en donde la empresa podría ofertar sus productos y servicios de empaque de autopartes; a la vez el hecho de saber qué países están invirtiendo puede ayudar a conocer a qué tipo de cliente se le estará intentando vender, y en caso de que la relación de negocio sea exitosa, a qué países en un futuro podría expandirse.

Por otro lado, Carlier Mathilde (2021), Reserch Expert de Statista, comenta que, las previsiones del mercado de la Industria Automotriz apuntan a un crecimiento constante en los próximos 4 años. Además, gracias al acuerdo USMCA entre USA, México y Canadá, se renovaron las regulaciones de Libre Comercio, por lo que, la expansión de FORM a San Antonio y su exportación a USA, no debería contener inconvenientes legales.

USA

Según datos de Mordor Inteligencie Estados Unidos es una de las principales Industrias Automotrices en el mundo, ya que contribuye con un 3% de PIB en todo el país. En el 2022 la producción de vehículos tuvo un total de 10,060,339 unidades, es decir, un crecimiento de 9.74% respecto al 2021.

De acuerdo con datos de Bankinter Estados Unidos se posiciona en el segundo puesto de fabricación de coches previstos para el 2023.

Además, los principales vendedores de autos durante el 2022 fueron General Motors, Toyota Motor y Ford ubicados en Michigan Ohio, Indiana Kentucky Tennessee, Alabama Texas y California.

En Texas se encuentra una de las Industrias Automotrices más importantes, Toyota General Motors y Tesla. Tesla posee una mega fábrica en el área de Austin y se espera que el proyecto cree 5000 nuevos empleos y más de 1000 millones de dólares en inversión de capital. Además, Texas representó el 20% del total de Estados Unidos en la Industria Automotriz.

Gráficas Industria Automotriz

Exportaciones de Autos en México por Marca
Exportaciones <-Data1 %>% group_by(Marca) %>% summarise(num_exportaciones=n()) %>% arrange (desc(num_exportaciones))
Marca_mas_exportaciones <- Data1 %>% filter(Marca %in% c("Nissan","Volkswagen","General Motors","Chrysler","Mazda","Ford Motor","KIA","Honda","Fiat","Audi"))
ggplot(Marca_mas_exportaciones,aes(Marca,fill=Marca))+geom_bar()+ggtitle ("Top 10 Exportaciones por Marca") + theme_minimal() + scale_fill_manual(values = mi_paleta) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

La marca con más exportaciones por año es Nissan, con casi 24000 unidades, esto es conveniente para FORM ya que, al ser una Marca de origen japones, entra en el mercado de clientes de su interés.

Regiones <- filter(Ndatos,region %in%
c("Centro-Norte","Norte","Norte-Occidente","Centro","Sur"))
ggplot(data=Regiones,
aes(x=region,y=hybrid_car_units,fill=region
)) + geom_boxplot() + ylim(0,1000) +
theme_minimal() + ylab("Unidades de carros hybridos") +
ggtitle("Unidades de carros hybridos por zonas de México") + theme(axis.text.x = element_text(angle = 45, hjust = 1)) + scale_fill_manual(values = mi_paleta)

En esta gráfica vemos la cantidad de carros híbridos por zonas de México en la que la mayor venta se dan en la zona Norte pero el mayor rendimiento es en la zona Norte Occidente. También se puede ver que el peor sector es el del Sur.

Industria Autopartes

MÉXICO

De acuerdo con Data México y el Censo Económico 2019, la Producción Bruta del Comercio al por Menor de Partes y Refacciones para Automóviles, Camionetas y Camiones, fue de un total de $89,695 millones de pesos; los estados con mayor producción fueron CDMX con $8,898 millones de pesos y Jalisco con $8,457 millones de pesos. Este dato es importante a considerar porque permite conocer cuales son los estados que más están produciendo autopartes en México, y por ende, son clientes potenciales para FORM.

Los Estados qué más han recibido Inversión Extranjera Directa en 2022, fueron Querétaro ($14 millones de USD), Coahuila de Zaragoza ($2.71 millones de USD) y CDMX ($2.69 Millones de USD); estas inversiones provienen de 3 principales países: Japón, Corea del Sur y Canadá. Al recibir mayor inversión se convierten en zonas de oportunidad en donde la empresa puede ofertar sus productos y servicios de empaque de autopartes; al mismo tiempo que ayuda a conocer a qué tipo de cliente se le estará intentando vender, y en caso de que la relación de negocio sea exitosa, a qué países en un futuro se puede expandir.

También Statista nos ayuda a corroborar que esta industria seguirá en demanda ya que pronostico qué el ingreso de esta industria pasará de $11,27 Billones de USD en 2022 a $13,98 Billones de USD en México, por lo que los clientes actuales de esta industria seguirán necesitando paquetes y cajas de FORM.

USA

La industria de autopartes en Estados Unidos está estimada en 205.81 miles de millones de dólares, y se espera tener un crecimiento de 4.1% del 2023 al 2030. El mayor mercado en Estados Unidos para las autopartes son los aires acondicionados suspensiones interiores transmisiones sistemas de maniobró radios radiadores tecnología frenos entre otros.

Otra de las medidas tendencias que pueden hacer que el mercado crezca en Estados Unidos es el incremento en la venta de vehículos electrónicos los cuales necesitan varias partes y la venta anual de vehículos eléctricos en Estados Unidos pasó 172.1 miles de unidades en 2021 lo que indica una demanda alta por partes y componentes que necesita el mercado Estados Unidos también es el más grande mercado en este tipo de vehículos con manufactureras como Cadillac GMC Tesla Chrysler las cuales lideran el mercado de vehículos electrónicos.

Texas en el mercado de autopartes aparte de cero un albergue de industrias muy grandes también tiene una mezcla de fabricantes y proveedores que ayudan a su economía automotriz.

Gráficas Industria Autopartes

resultados <- mx_exauto %>%
  filter(year >= 2020) %>%
  group_by(year, State) %>%
  summarise(ventas_totales = sum(trade_value))
  
ggplot(resultados, aes(x = State, y = ventas_totales, fill = factor(year))) +
  geom_bar(stat = "identity", position = "dodge") +
  labs(title = "Ventas Totales por Año y Estado",
       x = "Estado",
       y = "Ventas Totales",
       fill = "Año") +
  theme_minimal() +
  theme(legend.position = "top") + 
  theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
  scale_y_continuous(labels = scales::comma)+scale_fill_manual(values = mi_paleta)

Se observa la participación de los distintos estados de México en las exportaciones de autopartes, esto nos permite visualizar a grandes rasgos en que estados es en donde hay más exportación de autopartes a países extranjeros. Estos hallazgos nos permiten tomar decisiones estratégicas, como por ejemplo elegir alguna ubicación estratégica para un almacén, punto de distribución o incluso una planta.

ggplot(Autopartes, aes(x = year)) +
  geom_bar(aes(y = imports_from_US, fill = "Importaciones desde US"), stat = "identity", position = "dodge") +
  geom_bar(aes(y = total_imports - imports_from_US, fill = "Total de importaciones"), stat = "identity", position = "dodge") +
  labs(title = "Importaciones de Autopartes por Año", 
       subtitle = "Industria Automotriz",
       caption = "Mexico Automotive Industry - International Trade Administration - USD Billions",
       x = "Año",
       y = "Importaciones") +
  scale_fill_manual(values = c("Importaciones desde US" = "ivory2", "Total de importaciones" = "darkorange")) +
  theme_minimal() +
  labs(fill = "Tipo de Importación")

Tanto el total de importaciones como las que provienen de US han incrementado con el paso de los años, solamente en el 2020 hubo una disminución debido a la pandemia de Covid-19, pero después recuperó su comportamiento. Además, es importante mencionar que las importaciones desde US representan más del 50% del total de importaciones.

Industria Cartón

MÉXICO

Según datos de Euromonitor (2022), el mercado de papel corrugado, cartón y contenedores en México ocupa el primer lugar en Latinoamérica, al igual que su crecimiento del tamaño de mercado. El número de empresas presente en esta industria en 2021 fue de 8984 y va en crecimiento; aunque se podría decir qué la industria está fragmentada ya que solo las 5 empresas más grandes representan el 7.2% del valor de producción. Por último, la rentabilidad de la industria creció y logró llegar al 34.5% en 2021, y apunta a seguir creciendo. Estos datos nos indica qué México sigue siendo un país importante en esa industria en Latinoamérica, qué tiene futuro y por ende FORMS puede seguir en ella, pero también es una industria competitiva debido a la gran diversidad de empresas; por lo que FORMS deberá seguir innovando para mantenerse competitiva en el mercado.

De acuerdo a datos del DENUE 2022 en la Industria de la Fabricación de Productos de Cartón y Papel se registraron un total de 6,099 unidades económicas; siendo Estado de México (481), Jalisco(461), Veracruz de Ignacio de la Llave (418) y Nuevo León (329), los estados más relevantes. Esta información nos permite conocer en donde se podrían encontrar los competidores más fuertes de FORM.

Los Estados qué más han recibido Inversión Extranjera Directa en 2022, fueron Estado de México ($54.8 millones de USD), Baja California ($21.3 millones de USD ) y Nuevo León ($19.8 Millones de USD); estas inversiones provienen de 3 principales países siendo estos Irlanda, Estados Unidos y Nueva Zelanda.

Esta información es importante tenerla ya que nos permite conocer en que estados se está produciendo e invirtiendo más en la Fabricación de Productos de Cartón y Papel y por ende pueden ser zonas de oportunidad en donde la empresa puede buscar inversores para poder potenciar al crecimiento de la empresa y en caso de qué las relaciones sean exitosas a qué países en un futuro pueden exportar sus productos.

USA

De acuerdo con datos de Euromonitor International, La rentabilidad de la industria dentro de USA está disminuyendo, esto es debido a que los costes han aumentado un 8.1% en 2021; lo cual fue consecuencia en gran medida por el aumento en costos de las relaciones B2B.

Conforme a las competencias dentro de la industria, en 2021 se portó que 1369 empresas se integraron a la industria de Contenedores de Papel y Cartón corrugado. El sector se encuentra fragmentado debido a que el 43.2% del valor de producción en 2021 fue ocasionado por las 5 principales empresas; la empresa con mayor valor y fuerza en el mercado es WestRock Co, empresa qué generó el 10% del valor de producción total de la industria en 2021. Esta Industria está dominada por proveedores nacionales ya qué las importaciones representan el 5.8% del tamaño total del mercado en 2021.

Ahora bien, de acuerdo con la demanda USA tiene el mercado más grande dentro de los 20 principales países desarrollados, teniendo una demanda en 2021 equivalente a 56.1 billones de dólares. Cabe recalcar que B2B es el principal impulsor del mercado, representando el 92.4% de la demanda en 2021.

Estos datos nos dicen qué si bien la competencia es alta y dura en Estados Unidos, aun así, puede FORM ingresar a esta industria; si la rentabilidad sigue disminuyendo y los costes aumentando, las empresas qué ocupan este producto comenzarán a buscar otros proveedores con precios más accesibles, por lo que si FORM mantiene sus precios una vez instalados en San Antonio o siguen exportando sus productos, podrían tener éxito al expandirse a USA.

Gráficas Industria de Cartón

Importación de Cajas

ICB2<-ImpCartonBox%>%arrange(desc(Trade.Value))
View(ICB2)
ICB3<-ICB2%>%filter(Trade.Value>=123989664)
View(ICB3)

ggplot(ICB3, aes(x=Trade.Value, y=Country, fill=Country)) + geom_bar(stat="identity") + xlab("") + labs(x="Trade Value en 2021",title = "Top 20 países importadores de cajas de cartón", subtitle = "Según su Trade Value en el año 2021") + scale_x_continuous(labels=function(n){format(n, scientific = FALSE)}) + theme_minimal() + scale_fill_manual(values = mi_paleta)

Esta gráfica nos permite visualizar que países importan más y por ende se puede conocer a que países se puede expandir FORM en un futuro o en qué país puede conseguir nueva clientela internacional.

Exportación de Cajas

ECB2<-ExpCartonBox%>%arrange(desc(Trade.Value))
View(ECB2)
ECB3<-ECB2%>%filter(Trade.Value>=101375372)
View(ECB3)

ggplot(ECB3, aes(x=Trade.Value, y=Country, fill=Country)) + geom_bar(stat="identity") + xlab("") + labs(x="Trade Value en 2021",title = "Top 20 países exportadores de cajas de cartón", subtitle = "Según su Trade Value en el año 2021") + scale_x_continuous(labels=function(n){format(n, scientific = FALSE)})+ theme_minimal() + scale_fill_manual(values = mi_paleta)

Esta gráfica nos permite visualizar que países son los que más exportan cajas y empaques de cartón, por ende se puede saber que países pueden tener empresas que puedan ser una amenaza para FORM, además se conoce que países no pueden ser tan convenientes para hacer negocios, debido a la alta competencia.

view(ventas_carton)
ggplot(ventas_carton, aes(x = Mes, y = Carton)) +
  geom_bar(stat = "identity", fill = "darkorange") +
  labs(title = "Ventas de Carton por Mes", subtitle = "2022", x = "Mes", y = "Ventas MDP") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 20, hjust = 1)) + scale_x_discrete(limits = ventas_carton$Mes)

Se puede observar que las ventas de Cartón durante el 2022 incrementaron al final de cada trimestre, es decir, en los meses de Marzo, Junio y Septiembre, sin embargo, el mes de Agosto tuvo incrementos considerables con respecto al mes anterior.

FODA cruzado

PESTLE

ESTRATEGIAS

  1. Analizar las tendencias de consumo internacional para poder incrementar la producción de cartón retornable y así minimizar costos y factores ecológicos de riesgo como la superficie forestal perdida.

  2. Automatizar los procesos de elaboración de los empaques a través de la innovación tecnológica hará que se aceleren los procesos y se reduzcan costos. Esto daría la posibilidad de abastecer a la demanda de forma más rápida.

  3. Una de las tendencias en la industria del embalaje es la preocupación por el packaging sostenible, por lo tanto, FORM podría apostar por materiales alternativos que le ayuden a aumentar su % de producción de retornable, además de la integración de prácticas de diseño y producción más interactivas y sostenibles, y fomentar el reciclaje avanzado.

PARTE II - ANALISIS EXPLORATORIO DE DATOS

Un EDA (Exploratory Data Analysis) es un proceso crucial en la ciencia de datos que implica examinar y visualizar un conjunto de datos para comprender sus características, patrones y estructura.

El objetivo principal del EDA es obtener una visión inicial de los datos antes de realizar análisis más avanzados o modelado estadístico. Durante el EDA, se pueden realizar tareas como la identificación de valores atípicos, la exploración de distribuciones de datos, la búsqueda de correlaciones entre variables y la generación de gráficos informativos. Este proceso ayuda a los científicos de datos a tomar decisiones fundamentadas sobre cómo abordar un conjunto de datos y qué técnicas analíticas son adecuadas para obtener conocimientos valiosos.

SITUACIÓN PROBLEMA 2

Explorar, definir, y describir cuáles son los principales factores del clima organizacional de FORM que propician la satisfacción y/o no satisfacción de trabajar en dicha empresa.

PREGUNTAS DE ANÁLISIS

  1. ¿El darle prioridad a las mujeres en la contratación del puesto de Ayudante General, puede reducir la rotación de personal y aumentar la productividad de la empresa?

  2. ¿El estado civil y el género son factores que afectan la rotación de empleados?

  3. ¿En qué estación del año tienden a suceder más bajas de personal? ¿El clima será un factor determinante en las bajas de personal?

  4. ¿La edad del trabajador puede ser un determinante de por qué se dan de baja, o hay cierta edad en donde es menos probable que se de una baja?

  5. ¿La distancia geográfica desempeña un papel significativo en la determinación del estatus laboral de los empleados? (Activo o Inactivo)

DISEÑO, ORGANIZACIÓN Y LIMPIEZA DE DATOS

Cargando las bases de datos

datos_2022 <- read.csv("C:\\Users\\ca\\Desktop\\R Studio\\Datos Evidencia 1\\B_form_rh_bajas_datos_2022.csv")
datos_2023 <- read.csv("C:\\Users\\ca\\Desktop\\R Studio\\Datos Evidencia 1\\B_BDD_FORM_BAJAS_2023.csv")
datos_actuales <- read.csv("C:\\Users\\ca\\Desktop\\R Studio\\Datos Evidencia 1\\form_rh_datos (1).csv")
datos_2023 <- datos_2023[complete.cases(datos_2023), ]

Unión de las bases de datos

df_bajas <- bind_rows(datos_2022, datos_2023)
df_bajas <- as.data.frame(lapply(df_bajas, toupper))

Limpieza de las bases de datos

df_bajas <- df_bajas %>%
  mutate(ESTADO.CIVIL = ifelse(ESTADO.CIVIL %in% c("SOLTERIA", "SOLTERA"), "SOLTERO", ESTADO.CIVIL)) %>%
  mutate(ESTADO.CIVIL = ifelse(ESTADO.CIVIL %in% c("CASADO", "CASADA", "MATRIOMONIO"), "MATRIMONIO", ESTADO.CIVIL))

datos_actuales <- datos_actuales %>%
  mutate(ESTADO.CIVIL = ifelse(ESTADO.CIVIL %in% c("SOLTERIA", "SOLTERA"), "SOLTERO", ESTADO.CIVIL)) %>%
  mutate(ESTADO.CIVIL = ifelse(ESTADO.CIVIL %in% c("CASADO", "CASADA", "MATRIOMONIO"), "MATRIMONIO", ESTADO.CIVIL))

Nueva columna que da a conocer la edad del personal.

df_bajas$FECHA.DE.NACIMIENTO <- dmy(df_bajas$FECHA.DE.NACIMIENTO)
fecha_actual <- Sys.Date()
df_bajas$EDAD <- round(as.numeric(difftime(fecha_actual, df_bajas$FECHA.DE.NACIMIENTO, units = "days") / 365.25))

datos_actuales$FECHA.DE.NACIMIENTO <- mdy(datos_actuales$FECHA.DE.NACIMIENTO)
datos_actuales$EDAD <- round(as.numeric(difftime(fecha_actual, datos_actuales$FECHA.DE.NACIMIENTO, units = "days") / 365.25))

Nueva columna que da a conocer los días trabajados por empleado.

df_bajas$FECHA.DE.ALTA <- dmy(df_bajas$FECHA.DE.ALTA)
df_bajas$BAJA <- dmy(df_bajas$BAJA)
df_bajas$DIAS.LABORADOS.CALCULADO <- as.numeric(difftime(df_bajas$BAJA, df_bajas$FECHA.DE.ALTA, units = "days"))

datos_actuales$FECHA.DE.ALTA <- mdy(datos_actuales$FECHA.DE.ALTA)
datos_actuales$BAJA <- fecha_actual
datos_actuales$DIAS.LABORADOS.CALCULADO <- as.numeric(difftime(datos_actuales$BAJA, datos_actuales$FECHA.DE.ALTA, units = "days"))

Nueva columna que da a conocer el domicilio por empleado.

df_bajas$DIRECCION <- paste(df_bajas$CALLE, df_bajas$NUMERO.INTERNO, df_bajas$COLONIA, df_bajas$MUNICIPIO, df_bajas$ESTADO, sep = ", ")

datos_actuales$DIRECCION <- paste(datos_actuales$CALLE, datos_actuales$NUMERO.INTERNO, datos_actuales$COLONIA, datos_actuales$MUNICIPIO, datos_actuales$ESTADO, sep = ", ")
datos_actuales<- as.data.frame(lapply(datos_actuales, toupper))

Organización de los datos

Creación de un Data Frame consolidado

datos_actuales$BAJA <- as.Date(datos_actuales$BAJA)
df_bajas$BAJA <- as.Date(df_bajas$BAJA)
datos_actuales$FECHA.DE.NACIMIENTO <- as.Date(datos_actuales$FECHA.DE.NACIMIENTO)   
datos_actuales$FECHA.DE.ALTA <- as.Date(datos_actuales$FECHA.DE.ALTA) 
datos_actuales$SALARIO <- as.numeric(datos_actuales$SALARIO)
df_bajas$SALARIO <- as.numeric(df_bajas$SALARIO)
df_bajas$EDAD <- as.numeric(df_bajas$EDAD)
datos_actuales$EDAD <- as.numeric(datos_actuales$EDAD) 
datos_actuales$DIAS.LABORADOS.CALCULADO <- as.numeric(datos_actuales$DIAS.LABORADOS.CALCULADO)
df_bajas$DIAS.LABORADOS.CALCULADO <- as.numeric(df_bajas$DIAS.LABORADOS.CALCULADO)
df_consolidado <- bind_rows(df_bajas, datos_actuales)

Nueva columna, “PUESTO_ N”. Existe una serie de nomencalturas/abreviaciones relacionadas a la columna Puesto, esto con la finalidad de manejar de manera más sencilla los códigos y permitir que gráficas se visualicen mejor.

df_consolidado <- df_consolidado %>%
  mutate(PUESTO.N = case_when(
    PUESTO %in% c("AYUDANTE GENERAL", "AY.GENERAL") ~ "A.G.",
    PUESTO %in% c("GESTOR") ~ "GT.",
    PUESTO %in% c("SOLDADOR", "AYUDANTE SOLDADOR") ~ "SDR.",
    PUESTO %in% c("AYUDANTE DE EMBARQUES") ~ "A.D.E.",
    PUESTO %in% c("CHOFER GESTOR", "CHOFER") ~ "CHO.",
    PUESTO %in% c("COSTURERA", "COSTURERO", "COSTURA") ~ "COS.",
    PUESTO %in% c("ENFERMERA") ~ "EN.",
    PUESTO %in% c("GUARDIA DE SEGURIDAD", "GUARDIA SEGURIDAD") ~ "G.D.S.",
    PUESTO %in% c("INSPECTOR DE CALIDAD", "CALIDAD") ~ "I.C.",
    PUESTO %in% c("LIMPIEZA") ~ "LPZ.",
    PUESTO %in% c("MATERIALISTA") ~ "MAT.",
    PUESTO %in% c("MONTACARGISTA") ~ "MC.",
    PUESTO %in% c("PINTOR", "AYUDANTE PINTOR") ~ "PI.",
    PUESTO %in% c("RESIDENTE", "RESIDENTE YANFENG CIENEGA") ~ "RDT.",
    PUESTO %in% c("MANTENIMIENTO") ~ "MTO.",
    PUESTO %in% c("ANALISTA DE NOMINAS") ~ "A.D.N.",
    PUESTO %in% c("CUSTOMER SERVICE INF") ~ "C.S.I.",
    PUESTO %in% c("CORTADOR") ~ "COR.",
    PUESTO %in% c("DISEÑO") ~ "DIS.",
    PUESTO %in% c("EXTERNO") ~ "EX.",
    PUESTO %in% c("FACTURACION") ~ "FAC.",
    PUESTO %in% c("JEFE DE SEGURIDAD E HIGIENE") ~ "J.S.H.",
    PUESTO %in% c("LIDER") ~ "LI.",
    PUESTO %in% c("MARCADORA") ~ "MAR.",
    PUESTO %in% c("OPERADOR") ~ "OP.",
    PUESTO %in% c("RECIBO") ~ "RBO.",
    PUESTO %in% c("SERVICIO AL CLIENTE") ~ "S.C.",
    PUESTO %in% c("SUPERVISOR") ~ "SUP.",
    TRUE ~ PUESTO
  ))

Glosario correspondiente a la columna

ANÁLISIS EXPLORATORIO DE DATOS

PREGUNTA 1

¿El darle prioridad a las mujeres en la cuestión de contratación de personal en el puesto de Ayudante General, puedo reducir la rotación de personal y aumentar la productividad de la empresa?

A continuación se muestran los primeros 6 renglones de la base de datos

dataRH<-read.csv("C:\\Users\\ca\\Desktop\\R Studio\\Datos Evidencia 1\\CFORMF.csv")

head(dataRH)
##   FECHA.DE.NACIMIENTO    GENERO FECHA.DE.ALTA BAJA DIAS_LABORADOS
## 1          23/12/1994 MASCULINO    18/08/2022    0             NA
## 2          23/10/2002 MASCULINO    18/02/2022    0             NA
## 3          11/03/1995 MASCULINO    11/01/2017    0             NA
## 4          01/11/1992 MASCULINO    03/11/2020    0             NA
## 5          29/09/1976  FEMENINO    16/02/2022    0             NA
## 6          07/07/1966  FEMENINO    01/06/2022    1             NA
##             PUESTO PUESTO_N DEPARTAMENTO SALARIO.DIARIO.IMSS
## 1    MANTENIMIENTO      MTO                           180.68
## 2 AYUDANTE GENERAL     A.G.     Ay.flexo              180.68
## 3 AYUDANTE GENERAL     A.G.        Cedis              176.72
## 4 AYUDANTE GENERAL     A.G.        Cedis              176.72
## 5 AYUDANTE GENERAL     A.G.       Celdas              180.68
## 6 AYUDANTE GENERAL     A.G.       Celdas              180.68
##   FACTOR.CRED.INFONAVIT    LUGAR.DE.NACIMIENTO          CALLE NUMERO.INTERNO
## 1                     0 EBANO, SAN LUIS POTOSI MIER Y NORIEGA           106B
## 2                     0  MONTERREY, NUEVO LEON PORTAL GALICIA            219
## 3                     0                               OCEANIA               
## 4                     0                             TASAJILLO            220
## 5                     0    HIDALGO, TAMAULIPAS  RIO ESCONDIDO            760
## 6                     0      CANATLAN, DURANGO     HABICHUELA            306
##                     COLONIA    MUNICIPIO     ESTADO ESTADO.CIVIL
## 1    MIRADOR DE SAN ANTONIO       JUAREZ NUEVO LEON   MATRIMONIO
## 2          PORTAL DEL VALLE      APODACA NUEVO LEON     SOLTERIA
## 3 FRACC. OCEANIA BOULEVARES     SALTILLO   COAHUILA   MATRIMONIO
## 4                 EL CACTUS RAMOS ARIZPE   COAHUILA  UNION LIBRE
## 5              PUEBLO NUEVO      APODACA NUEVO LEON     SOLTERIA
## 6          POLICIA AUXILIAR    GUADALUPE NUEVO LEON     SOLTERIA

Se tomó la base de datos “BDD_FORM_BAJAS_2023” para poder conocer sobre las diferentes razones del porque la gente sale de la empresa, para esto se usaron argumentos/funicones como group_by,count,mutate,arrange y round; para conocer porcentajes y como se relacionan los datos

rh_ba<-read.csv("C:\\Users\\ca\\Desktop\\R Studio\\Datos Evidencia 1\\BDD_FORM_BAJAS_2023.csv")
head(rh_ba)
##   No.           Apellidos         Nombre Fecha.de.Nacimiento    Genero
## 1   1     Perez Chavarria Yessica Yazmin          13/02/1985  Femenino
## 2   1       Pecina Aleman  Blanca Idalia          25/05/1966  Femenino
## 3   1         Suarez Romo    Julio Cesar          27/06/1969 Masculino
## 4   1   Ortiz De La Torre        Fermina          07/07/1966  Femenino
## 5   1 Gallegos Manzanares       Veronica          28/11/1973  Femenino
## 6   1        Guzman Reyes  Carlos Benito          25/11/2002 Masculino
##             RFC Fecha.de.Alta Primer.Mes Cuarto.Mes Fecha.de.Baja
## 1 PECY850213QS8    05/09/2022 05/10/2022 05/01/2023    02/01/2023
## 2 PEAB660525QT5    06/10/2022 05/11/2022 05/02/2023    02/01/2023
## 3 SURJ690627TK7    01/12/2017 31/12/2017 31/03/2018    05/01/2023
## 4 OITF660712QD2    01/06/2022 01/07/2022 29/09/2022    05/01/2023
## 5 GAMV731128LZA    22/10/2022 21/11/2022 21/02/2023    05/01/2023
## 6 GURC021125UL8    06/01/2023 05/02/2023 08/05/2023    07/01/2023
##          Motivo.de.Baja                                         Observaciones
## 1 Separacion voluntaria              Se retiro para cuidar de su (s) hije (s)
## 2 Separacion voluntaria No hay observacion registrada sobre el motivo de baja
## 3 Separacion voluntaria                                 Encontro otro empleo 
## 4 Separacion voluntaria            Se encontraba agotad@ por la carga laboral
## 5 Separacion voluntaria                                                      
## 6 Separacion voluntaria                                                      
##             Puesto Puesto_Nom      Dpto         Imss     SD
## 1 AYUDANTE GENERAL       A.G.  Stabilus  43048517130 180.68
## 2 AYUDANTE GENERAL       A.G.            43056601958 180.68
## 3           GESTOR        GT. Embarques  43956909626 176.72
## 4 AYUDANTE GENERAL       A.G.    Celdas  43946623980 180.68
## 5 AYUDANTE GENERAL       A.G.           03 907303238 180.68
## 6         SOLDADOR       SDR.           0 3190285142 180.68
##   Factor.de.Credito.Infonavit No..De.Credito.Infonavit   Lugar.de.Nacimiento
## 1                         N/A                      N/A MONTERREY, NUEVO LEON
## 2                         N/A                      N/A ARAMBERRI, NUEVO LEON
## 3                                                                           
## 4                         N/A                      N/A     CANATLAN, DURANGO
## 5                         N/A                      N/A Guadalupe, Nuevo Leon
## 6                         N/A                      N/A   Tampico, Tamaulipas
##                  CURP             Calle Numero              Colonia Municipio
## 1  PECY850213MNLRHS03          Alemania   1170       Vivienda Digna   Apodaca
## 2  PEAB660525MNLCLL07 Rio Guayalejo Sur    304         Pueblo Nuevo   Apodaca
## 3  SURJ690627HNLRML04          Mar Rojo                  Loma Linda Monterrey
## 4 OITF660712MDGRRR023        Habichuela    306     Policia Auxiliar Guadalupe
## 5  GAMV731128MNLLNR04           Romanos    341 Milenium Residencial   Apodaca
## 6  GURC021125HTSZYRB7       Rio Salinas    122         Pueblo Nuevo   Apodaca
##          Estado    CP Estado.Civil Numero.de.Telefono
## 1 Nuevo Le\xf3n 66647      Soltera         8133726737
## 2    Nuevo Leon 66646       Casada         8115902048
## 3 Nuevo Le\xf3n 64120       Casado         8110206284
## 4 Nuevo Le\xf3n 67114      Soltera         8130933136
## 5    Nuevo Leon 66646       Casada         8184705262
## 6    Nuevo Leon 66646      Soltero                 NA
rh_ba2<-rh_ba%>%group_by(Observaciones)%>%count()%>%ungroup()%>%mutate(pcnt=n/sum(n)*100)%>%arrange(pcnt)

rh_ba2$pcnt<-round(rh_ba2$pcnt,2)

rh_ba3 <- rh_ba2 %>% mutate(csum = rev(cumsum(rev(pcnt))), 
         pos = pcnt/2 + lead(csum, 1),
         pos = if_else(is.na(pos), pcnt/2, pos))


ggplot(rh_ba2,aes(x="",y=pcnt,fill=Observaciones))+geom_bar(stat="identity")+coord_polar(theta="y")+theme(legend.position = "none")+geom_label_repel(data=rh_ba3,aes(x=c(.0003,0.15,0.32,0.5,0.7,0.9,1.1,1.3,1.5,1.7,1.9,2.1,2.3,2.5,2.7,1,0.98,1),y=pos,label=paste0(pcnt,"%")),size=4.5,nudge_x=1,max.overlaps=30,show.legend = FALSE)+theme_void()+  theme(legend.position = "bottom")+labs(title="Razones de las bajas laborales de FORM 2023")+scale_fill_manual(values = mi_paleta)

Esta gráfica nos Ayuda a Visualizar que de 279 personas que fueron dadas de bajas en 2023, el 76.3% no dieron una razon o no se registró el motivo especifico de baja, y de las personas de las cuales si se registró el motivo de bajas las 5 razones más populares fueron:

1.Encontró otro empleo (8.6%) 2. Asilio político en USA (2.87%) 3. Se retiro para cuidar de su (s) hije (s) (2.15%) 4. Tuvo mas de 3 faltas y ella misma decidio irse (1.79%) 5. Cambio de estado/residencia (1.79%)

g = ggplot(rh_ba, aes(Puesto_Nom, fill=Genero) ) + labs(title = "Distribución de Bajas por Género Por puesto de Trabajo",x="Puesto (Abreviado)")+ylab("Número de Personas") + theme(plot.title = element_text(size = rel(2), colour = "darkgoldenrod3"))

g+geom_bar(position="dodge") + theme(axis.title.x = element_text(face="bold", size=10)) + theme_minimal() + theme(axis.text.x = element_text(angle = 90, hjust = 1))+ scale_fill_manual(values = mi_paleta)

Esta gráfica nos permite viusalizar el número de personas que fueron dadas de bajas en 2023 según su puesto y género, en este caso podemos ver que las mayores bajas son en el puesto de Ayudante General, y se han despido a un mayor número de mujeres que de hombres. Esto también se puede relacionar con las razones del porque fueron dadas de bajas. Por ejemplo, se puede obtener el insight de que si se ofreciera una zona para el cuidad de los hijos de las amdres trabajadoras, se podría reducir el número de bajas de las mujeres en el puesto de ayudante general u otros puestos.

dataRH$FECHA.DE.NACIMIENTO<-as.Date(dataRH$FECHA.DE.NACIMIENTO, format = "%d/%m/%Y")
fecha_actual<-Sys.Date()
diferencia_dias<-as.numeric(difftime(fecha_actual,dataRH$FECHA.DE.NACIMIENTO,units = "days"))
dataRH$EDAD<-diferencia_dias/365.25
dataRH$EDAD<-round(dataRH$EDAD,digits=0)

dataRH2<-dataRH%>%filter(BAJA==0)
dataRH2$FECHA.DE.ALTA<-as.Date(dataRH2$FECHA.DE.ALTA, format = "%d/%m/%Y")
dataRH2<-dataRH2%>%mutate(DiasTrabajados=as.numeric(difftime(fecha_actual,dataRH2$FECHA.DE.ALTA,units="days")))
dataRH3<-dataRH2%>%select(DiasTrabajados,FECHA.DE.ALTA,EDAD,GENERO,PUESTO,PUESTO_N)
dataRH3<-dataRH3%>%arrange(desc(DiasTrabajados))

prom_edad<- mean(dataRH$EDAD)
summary(dataRH)
##  FECHA.DE.NACIMIENTO     GENERO          FECHA.DE.ALTA           BAJA       
##  Min.   :1949-11-21   Length:350         Length:350         Min.   :0.0000  
##  1st Qu.:1983-02-12   Class :character   Class :character   1st Qu.:0.0000  
##  Median :1992-11-17   Mode  :character   Mode  :character   Median :1.0000  
##  Mean   :1990-03-04                                         Mean   :0.7143  
##  3rd Qu.:1999-04-12                                         3rd Qu.:1.0000  
##  Max.   :2004-04-02                                         Max.   :1.0000  
##                                                                             
##  DIAS_LABORADOS       PUESTO            PUESTO_N         DEPARTAMENTO      
##  Min.   :   0.00   Length:350         Length:350         Length:350        
##  1st Qu.:   9.00   Class :character   Class :character   Class :character  
##  Median :  19.00   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :  78.43                                                           
##  3rd Qu.:  48.50                                                           
##  Max.   :1966.00                                                           
##  NA's   :127                                                               
##  SALARIO.DIARIO.IMSS FACTOR.CRED.INFONAVIT LUGAR.DE.NACIMIENTO
##  Min.   :1.440e+02   Min.   :0.00000       Length:350         
##  1st Qu.:1.770e+02   1st Qu.:0.00000       Class :character   
##  Median :1.810e+02   Median :0.00000       Mode  :character   
##  Mean   :4.359e+06   Mean   :0.05714                          
##  3rd Qu.:1.810e+02   3rd Qu.:0.00000                          
##  Max.   :1.517e+09   Max.   :1.00000                          
##  NA's   :1                                                    
##     CALLE           NUMERO.INTERNO       COLONIA           MUNICIPIO        
##  Length:350         Length:350         Length:350         Length:350        
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##                                                                             
##     ESTADO          ESTADO.CIVIL            EDAD      
##  Length:350         Length:350         Min.   :19.00  
##  Class :character   Class :character   1st Qu.:24.00  
##  Mode  :character   Mode  :character   Median :31.00  
##                                        Mean   :33.55  
##                                        3rd Qu.:41.00  
##                                        Max.   :74.00  
## 
Rango_edad<- max(dataRH$EDAD)-min(dataRH$EDAD)

N<-length(dataRH$EDAD)
Varianza_edad<- var(dataRH$EDAD)
DesvEs_edad<-sd(dataRH$EDAD)
prom_edad
## [1] 33.54571
Rango_edad
## [1] 55
Varianza_edad
## [1] 122.4091
DesvEs_edad
## [1] 11.06386

Con estas medidas de dispersión con respecto a la edad del personal de FORM, podemos decir que existe una diferencia 55 años entre la persona más joven y con más edad de FORM, es por esto que nuestra Varianza tiene un valor alto (122.6) lo que signfiica que hay diferencias significativas entre las edades de las personas con respecto a la edad media de la personas de la empresa (33.5). El valor de la Desviación Estándar nos indica que la mayoría de nuestras edades estarán a menos o mas de 11 años del promedio de edad del personal (33.5)

dataRH4<-dataRH3%>%filter(PUESTO_N=="A.G.")
dataRH4F<-dataRH4%>%filter(GENERO=="FEMENINO")
dataRH4M<-dataRH4%>%filter(GENERO=="MASCULINO")

head(dataRH4F,10)
##    DiasTrabajados FECHA.DE.ALTA EDAD   GENERO           PUESTO PUESTO_N
## 1            1690    2019-01-28   36 FEMENINO AYUDANTE GENERAL     A.G.
## 2            1596    2019-05-02   39 FEMENINO AYUDANTE GENERAL     A.G.
## 3            1347    2020-01-06   56 FEMENINO AYUDANTE GENERAL     A.G.
## 4             903    2021-03-25   30 FEMENINO AYUDANTE GENERAL     A.G.
## 5             903    2021-03-25   27 FEMENINO AYUDANTE GENERAL     A.G.
## 6             883    2021-04-14   27 FEMENINO AYUDANTE GENERAL     A.G.
## 7             873    2021-04-24   52 FEMENINO AYUDANTE GENERAL     A.G.
## 8             840    2021-05-27   54 FEMENINO AYUDANTE GENERAL     A.G.
## 9             709    2021-10-05   61 FEMENINO AYUDANTE GENERAL     A.G.
## 10            639    2021-12-14   39 FEMENINO AYUDANTE GENERAL     A.G.
head(dataRH4M,10)
##    DiasTrabajados FECHA.DE.ALTA EDAD    GENERO           PUESTO PUESTO_N
## 1            2578    2016-08-23   27 MASCULINO AYUDANTE GENERAL     A.G.
## 2            2437    2017-01-11   29 MASCULINO AYUDANTE GENERAL     A.G.
## 3            2210    2017-08-26   59 MASCULINO AYUDANTE GENERAL     A.G.
## 4            1316    2020-02-06   23 MASCULINO AYUDANTE GENERAL     A.G.
## 5            1132    2020-08-08   54 MASCULINO AYUDANTE GENERAL     A.G.
## 6            1120    2020-08-20   46 MASCULINO AYUDANTE GENERAL     A.G.
## 7            1045    2020-11-03   31 MASCULINO AYUDANTE GENERAL     A.G.
## 8             705    2021-10-09   21 MASCULINO AYUDANTE GENERAL     A.G.
## 9             679    2021-11-04   22 MASCULINO AYUDANTE GENERAL     A.G.
## 10            665    2021-11-18   21 MASCULINO AYUDANTE GENERAL     A.G.
summary(dataRH4F)
##  DiasTrabajados   FECHA.DE.ALTA             EDAD          GENERO         
##  Min.   : 387.0   Min.   :2019-01-28   Min.   :21.00   Length:31         
##  1st Qu.: 416.5   1st Qu.:2021-06-28   1st Qu.:28.00   Class :character  
##  Median : 519.5   Median :2022-04-12   Median :39.00   Mode  :character  
##  Mean   : 652.6   Mean   :2021-11-30   Mean   :38.55                     
##  3rd Qu.: 807.2   3rd Qu.:2022-07-24   3rd Qu.:49.50                     
##  Max.   :1690.0   Max.   :2022-08-23   Max.   :61.00                     
##  NA's   :1        NA's   :1                                              
##     PUESTO            PUESTO_N        
##  Length:31          Length:31         
##  Class :character   Class :character  
##  Mode  :character   Mode  :character  
##                                       
##                                       
##                                       
## 
summary(dataRH4M)
##  DiasTrabajados   FECHA.DE.ALTA             EDAD          GENERO         
##  Min.   : 387.0   Min.   :2016-08-23   Min.   :20.00   Length:24         
##  1st Qu.: 415.2   1st Qu.:2020-10-15   1st Qu.:21.00   Class :character  
##  Median : 584.5   Median :2022-02-06   Median :24.00   Mode  :character  
##  Mean   : 851.0   Mean   :2021-05-16   Mean   :28.46                     
##  3rd Qu.:1063.8   3rd Qu.:2022-07-25   3rd Qu.:31.00                     
##  Max.   :2578.0   Max.   :2022-08-23   Max.   :59.00                     
##     PUESTO            PUESTO_N        
##  Length:24          Length:24         
##  Class :character   Class :character  
##  Mode  :character   Mode  :character  
##                                       
##                                       
## 

En este apartado podemos notar que las personas que más han trabajo en la empresa son del genero/sexo Masculino, a la vez con la visualización de los datas frames podemos ver que en cuestión de edad las mujeres que se han mantenido en la empresa, tienen un promedio de edad de 38.55 años y los hombres un promedio de 28.38.

Respuesta

Como pudimos ver en las gráficas y datos pasados, el ofrecer un servicio de cuidado de infantes, podría provocar que menos mujeres se den de bajas y por ende se reduzca de cierta de manera la rotación de personal, ya que como vimos hay más mujeres dadas de baja que hombre en el puesto de Ayudante General. A la vez no se podría decir a totalidad que las mujeres deberían de ser una prioridad, ya que como se visualizó en la gráfica,los hombres cuentan con mayores días trabajados que las mujeres. La respuesta correcta, sería que para poder reducir la rotación de personal y aumentar la productividad de la empresa se debería de ofrecer mejores prestaciones al personal como zonas de cuidado de infantes y/o un buen programa de capacitaciones que permitan el crecimiento profesional, ya que como se vió en la gráfica la razón número 1 de porque se fueron es debido a que encontraron un nuevo empleo, el cual seguramente les ofrecía mejores condiciones, y el hecho de tener un buen programa de capacitación, junto con una zona de cuidados para infantes y el esquema de ahorro/inversión que FORM ofrece, provocaría que se reduzca la rotación de personal y se aumente la prodcutividad, debido a las nuevas skills que el personal tendría. Por lo que se debería cerciorar en ofrecer mejores prestaciones y en contratar a hombres de 28 años y mujeres de 38 años aproximadamente.

PREGUNTA 2

¿Son el estado civil y el género factores independientes en la rotación de empleados o existe relación entre ambos eventos?

i <- 238
df_bajas_f<- subset(df_bajas, !row.names(df_bajas)==i)

GeneroyEstadocivil <- select(df_bajas_f,GENERO, ESTADO.CIVIL)
ggplot(GeneroyEstadocivil,aes(GENERO))+geom_bar(aes(fill=ESTADO.CIVIL), width= 0.5) + labs(title = "Estado Civil por Género")+ scale_fill_manual(values = mi_paleta) 

Estadísticos Descriptivos

df_bajas_f$ESTADO.CIVIL <- as.factor(df_bajas_f$ESTADO.CIVIL)
summary(df_bajas_f$ESTADO.CIVIL)
##    DIVORCIO  MATRIMONIO     SOLTERO UNION LIBRE 
##           3         137         247         129

Moda: En ambos sexos la moda de estado civil es “Soltero” con casi el 50% de las respuestas. 245 de 514 respuestas se encuentran en esta categoría.

Tablas de Frecuencia

frecuenciagenero <- table(df_bajas_f$GENERO)
frecuenciagenero
## 
##  FEMENINO MASCULINO 
##       289       227
frecuenciaestadocivil <- table(df_bajas_f$ESTADO.CIVIL)
frecuenciaestadocivil
## 
##    DIVORCIO  MATRIMONIO     SOLTERO UNION LIBRE 
##           3         137         247         129

Tablas de Contingencia

tabyl(df_bajas_f,GENERO,ESTADO.CIVIL)
##     GENERO DIVORCIO MATRIMONIO SOLTERO UNION LIBRE
##   FEMENINO        2         76     136          75
##  MASCULINO        1         61     111          54

Respuesta

Si tomamos en cuenta la cantidad de empleados de cada género y la moda obtenida, que en este caso es el estado civil “soltero”, obtenemos porcentajes muy similares. Personas de género femenino solteras: 47% Personas de género masculino solteros: 48% Es por eso que se puede determinar que ambas variables analizadas no representan un factor determminante en la rotación de empleados y son eventos independientes.

PREGUNTA 3

¿En qué estación del año tienden a suceder más bajas? ¿El clima será un factor determinante?

Cargando la base de datos
data<-read.csv("C:\\Users\\ca\\Desktop\\R Studio\\Datos Evidencia 1\\E_form_rh_bajas_datos_2022.csv")
Cambiando el formato de fecha
data$Fecha <- dmy(data$BAJA)
Obtención del mes de cada fecha
data$Mes <- month(data$Fecha)
Mapeo de los meses a las estaciones del año
data$Estacion <- case_when(
  data$Mes %in% c(3, 4, 5) ~ "Primavera",
  data$Mes %in% c(6, 7, 8) ~ "Verano",
  data$Mes %in% c(9, 10, 11) ~ "Otoño",
  data$Mes %in% c(12, 1, 2) ~ "Invierno",
  TRUE ~ NA_character_
)
Conteo de observaciones en cada estación
estacion_frecuencia <- table(data$Estacion)
Descubrimiento de la estación con el recuento más alto
estacion_mas_comun <- names(estacion_frecuencia[which.max(estacion_frecuencia)])
Impresión del resultado
cat("La estación con más bajas es:", estacion_mas_comun)
## La estación con más bajas es: Primavera
Cálculo de la frecuenia de bajas por estación
estacion_frecuencia <- table(data$Estacion)
Conversión de resultados a un dataframe
tabla_bajas_por_estacion <- as.data.frame(estacion_frecuencia)
Se renombra las columnas para mayor claridad
colnames(tabla_bajas_por_estacion) <- c("Estacion", "Cantidad_Bajas")

print(tabla_bajas_por_estacion)
##    Estacion Cantidad_Bajas
## 1  Invierno             58
## 2     Otoño              1
## 3 Primavera             84
## 4    Verano             80
Se crea el gráfico de barras
ggplot(tabla_bajas_por_estacion, aes(x = Estacion, y = Cantidad_Bajas)) +
  geom_bar(stat = "identity", color = "black", width = 0.7, fill = "orange") +
  labs(title = "Cantidad de Bajas por Estación del Año 2022", subtitle = "Recursos Humanos", x = "Estación", y = "Cantidad de Bajas")

Respuesta

Es posible observar que durante el año 2022 el periodo estacional que reportó más bajas de personal fue la primavera y el verano respectivamente, los cuales se encuentran situados entre los meses de Marzo y Septiembre, meses donde se reportan las temperaturas más elevadas en la ciudad de Monterrey, Nuevo León. Por lo tanto, la exposición a condiciones térmicas elevadas puede suponer un factor de estrés e insatisfacción laboral, ya que se relaciona con problemas de salud, comodidad, concentración y con un mayor riesgo de sufrir accidentes de trabajo ocasionando las bajas del personal de Form. Se recomienda apoyarse de la Norma Oficial Mexicana NOM-015-STPS-1993.

Además, con el fin de responder con mayor claridad la pregunta del análisis, a continuación se comparte información de fuentes secundarias sobre la temperatura registrada en Monterrey durante el 2022 tanto por mes como por hora.

Datos Históricos de Tempratura del 2022 en Monterrey

WeatherSpark
WeatherSpark

El intervalo diario de temperaturas reportadas (barras grises) y las máximas (marcas rojas) y mínimas (marcas azules) de 24 horas, colocadas arriba del promedio diario de la máxima (línea rojo claro) y de la mínima (línea azul claro), con las bandas de los percentiles 25 a 75 y 10 a 90.

Temperatura por Hora del 2022 en Monterrey

WeatherSpark La temperatura reportada por hora, codificada por colores en bandas. Las áreas sombreadas superpuestas indican la noche y el crepúsculo civil.

PREGUNTA 4

¿La edad del trabajador puede ser un determinante de por qué se dan de baja?

Cargando de la base de datos
datos_E<- read.csv("C:\\Users\\ca\\Desktop\\R Studio\\Datos Evidencia 1\\E_FORM_Consolidado.csv")
Limpieza de Datos
datos_E$FECHA.DE.NACIMIENTO <- as.Date(datos_E$FECHA.DE.NACIMIENTO, format = "%d/%m/%Y")
Cálculo de la edad en años
datos_E <- datos_E %>%
  mutate(edad = as.integer(difftime(Sys.Date(), FECHA.DE.NACIMIENTO, units = "days") / 365.25))
Cálculo de los días trabajados
datos_E$FECHA.DE.ALTA <- as.Date(datos_E$FECHA.DE.ALTA, format = ("%d/%m/%Y"))

# Obtener la fecha actual
fecha_actual <- Sys.Date()

datos_E <- datos_E %>%
  mutate(dias_trabajados = ifelse(BAJA == 1, 0, difftime(fecha_actual, FECHA.DE.ALTA, units = "days")))
Gráfico de Barras Apiladas
ggplot(datos_E, aes(x = edad, fill = factor(BAJA))) +
  geom_bar() +
  labs(x = "Edad", y = "Cantidad de Personas", fill = "Baja") +
  theme_minimal() + labs(title="Edad de Bajas y No Bajas")+scale_fill_manual(values = mi_paleta)

RESPUESTA

La grafica muestra que pasando la edad de 40 años es menos probable que ocurra una baja. También se muestra que las bajas más constantes están en la edad de los 20-35 se debe también al alto porcentaje de trabajadores de esa edad.

PREGUNTA 5

¿La distancia geográfica desempeña un papel significativo en la determinación del estatus laboral de los empleados? (Activo o Inactivo)

Agrupación de solo Nuevo León
bajas_nl <- df_bajas %>%
  mutate(ESTADO = ifelse(ESTADO %in% c("NUEVO LEON", "NUEVO LEÓN"), "NUEVO LEON", ESTADO)) %>%
  filter(ESTADO == "NUEVO LEON")

actuales_nl <- datos_actuales %>%
  mutate(ESTADO = ifelse(ESTADO %in% c("NUEVO LEON", "NUEVO LEÓN"), "NUEVO LEON", ESTADO)) %>%
  filter(ESTADO == "NUEVO LEON")
Función Ubicación Geográfica
#clave_api <- "ab32e924811c400ba1bcc335980f25a5"
clave_api <- "ab32e924811c400ba1bcc335980f25a5"

geocode_opencage <- function(direccion, clave_api) {
  url <- paste0("https://api.opencagedata.com/geocode/v1/json?q=", URLencode(direccion),
                "&key=", clave_api)
  respuesta <- GET(url)
  contenido <- content(respuesta, "text", encoding = "UTF-8")
  datos <- jsonlite::fromJSON(contenido)
  return(datos)
}
Latitud y Longitud
bajas_nl$GEOCODE_RESULT <- lapply(bajas_nl$DIRECCION, function(x) geocode_opencage(x, clave_api))
bajas_nl$LATITUD <- sapply(bajas_nl$GEOCODE_RESULT, function(x) x$results$geometry$lat)
bajas_nl$LONGITUD <- sapply(bajas_nl$GEOCODE_RESULT, function(x) x$results$geometry$lng)

actuales_nl$GEOCODE_RESULT <- lapply(actuales_nl$DIRECCION, function(x) geocode_opencage(x, clave_api))
actuales_nl$LATITUD <- sapply(actuales_nl$GEOCODE_RESULT, function(x) x$results$geometry$lat)
actuales_nl$LONGITUD <- sapply(actuales_nl$GEOCODE_RESULT, function(x) x$results$geometry$lng)
Función para calcular el promedio de una lista de números
calcular_promedio <- function(valor) {
  if (is.character(valor)) {
    valores <- tryCatch(eval(parse(text = valor)), error = function(e) NA_real_)
  } else {
    valores <- valor
  }
  valores <- valores[!is.na(valores)] 
  if (length(valores) > 0) {
    return(mean(valores))
  } else {
    return(NA_real_)
  }
}
bajas_nl$LONGITUD <- sapply(bajas_nl$LONGITUD, calcular_promedio)
bajas_nl$LATITUD <- sapply(bajas_nl$LATITUD, calcular_promedio)

actuales_nl$LONGITUD <- sapply(actuales_nl$LONGITUD, calcular_promedio)
actuales_nl$LATITUD <- sapply(actuales_nl$LATITUD, calcular_promedio)
Dirección objetivo
direccion_objetivo <- "Parque Industrial el Sabinal, Cam. Al Sabinal 105-No, 66645 Cd Apodaca, N.L."

coordenadas_objetivo <- geocode_opencage(direccion_objetivo, clave_api)

latitud_objetivo <- 25.75419
longitud_objetivo <- -100.17443
Crear una función que calcule la distancia haversine en kilómetros
calcular_distancia_km <- function(lat1, lon1, lat2, lon2) {
  dist_metros <- distHaversine(c(lon1, lat1), c(lon2, lat2))
  dist_km <- dist_metros / 1000  
  return(dist_km)
}

bajas_nl$DISTANCIA.KM <- mapply(calcular_distancia_km, bajas_nl$LATITUD, bajas_nl$LONGITUD, latitud_objetivo, longitud_objetivo)

actuales_nl$DISTANCIA.KM <- mapply(calcular_distancia_km, actuales_nl$LATITUD, actuales_nl$LONGITUD, latitud_objetivo,longitud_objetivo)
copia_actuales_nl <- as.data.frame(lapply(actuales_nl, toupper))
copia_bajas_nl <- as.data.frame(lapply(bajas_nl, toupper))
copia_actuales_nl <- copia_actuales_nl[!is.na(copia_actuales_nl$LATITUD) & !is.na(copia_actuales_nl$LONGITUD), ]
copia_bajas_nl <- copia_bajas_nl[!is.na(copia_bajas_nl$LATITUD) & !is.na(copia_bajas_nl$LONGITUD), ]

copia_actuales_nl$LATITUD <- as.numeric(copia_actuales_nl$LATITUD)
copia_actuales_nl$LONGITUD <- as.numeric(copia_actuales_nl$LONGITUD)
copia_bajas_nl$LATITUD <- as.numeric(copia_bajas_nl$LATITUD)
copia_bajas_nl$LONGITUD <- as.numeric(copia_bajas_nl$LONGITUD)

copia_actuales_nl$DISTANCIA.KM <- as.numeric(copia_actuales_nl$DISTANCIA.KM)
copia_bajas_nl$DISTANCIA.KM <- as.numeric(copia_bajas_nl$DISTANCIA.KM)
copia_actuales_nl <- copia_actuales_nl[copia_actuales_nl$LONGITUD >= -100.5 & copia_actuales_nl$LONGITUD <= -99.9, ]
copia_bajas_nl <- copia_bajas_nl[copia_bajas_nl$LONGITUD >= -100.5 & copia_bajas_nl$LONGITUD <= -99.9, ]

copia_actuales_nl <- copia_actuales_nl[copia_actuales_nl$LATITUD >= 25 & copia_actuales_nl$LATITUD <= 26, ]
copia_bajas_nl <- copia_bajas_nl[copia_bajas_nl$LATITUD >= 25 & copia_bajas_nl$LATITUD <= 26, ]
m <- leaflet() %>%
  addTiles() %>%  # Añade un fondo de mapa real
  addCircleMarkers(
    data = copia_bajas_nl,  # Datos de ubicaciones de registros
    lat = ~LATITUD,  # Nombre de la columna de latitud
    lng = ~LONGITUD,  # Nombre de la columna de longitud
    color = "red",  # Color de los marcadores de registros
    radius = 5,  # Tamaño de los marcadores de registros
    label = "Bajas"  # Etiqueta para los marcadores de registros
  ) %>%
  addCircleMarkers(
    data = copia_actuales_nl,  # Datos de ubicaciones de df_actual
    lat = ~LATITUD,  # Nombre de la columna de latitud en df_actual
    lng = ~LONGITUD,  # Nombre de la columna de longitud en df_actual
    color = "green",  # Color de los marcadores de df_actual
    radius = 5,  # Tamaño de los marcadores de df_actual
    label = "Activos"  # Etiqueta para los marcadores de df_actual
  ) %>%
  addCircleMarkers(
    lat = latitud_objetivo,  # Latitud del destino
    lng = longitud_objetivo,  # Longitud del destino
    color = "blue",  # Color del marcador de destino
    radius = 8,  # Tamaño del marcador de destino
    label = "Destino"  # Etiqueta para el marcador de destino
  )

Visualización del mapa interactivo

m

En este gráfico podemos observar de color rojo la dirección de aquellas personas que ya no forman parte de la empresa, en color verde los colaboradores activos y el punto de color azul es la dirección del socio formador. A simple vista se puede observar que se encuentran mayormente agrupados o conglomerados por zonas, siendo así que la mayoría vive en Apodaca.

hist(copia_bajas_nl$DISTANCIA.KM, 
     main = "Histograma de Distancia (BAJAS)", 
     xlab = "Distancia en km", 
     ylab = "Frecuencia",
     col = "darkorange3",
     border = "black",
     breaks = "Scott")

Este histograma nos permite visualizar que la gran mayoría de personas que renuncioran vivían a una distancia de entre 12 y 15 km con respecto a la dirección del socio formador.

mediana_bajas_nl <- median(copia_bajas_nl$DISTANCIA.KM)

grupo_cerca_nl <- copia_bajas_nl[copia_bajas_nl$DISTANCIA.KM <= mediana_bajas_nl, ]
grupo_lejos_nl <- copia_bajas_nl[copia_bajas_nl$DISTANCIA.KM > mediana_bajas_nl, ]

frecuencia_cerca_nl <- nrow(grupo_cerca_nl)
frecuencia_lejos_nl <- nrow(grupo_lejos_nl)

cat("Frecuencia de datos CERCA de la mediana:", frecuencia_cerca_nl, "\n")
## Frecuencia de datos CERCA de la mediana: 234
cat("Frecuencia de datos LEJOS de la mediana:", frecuencia_lejos_nl, "\n")
## Frecuencia de datos LEJOS de la mediana: 234

Este resultado nos indica que existen más bajas que se encuentran por debajo de la mediana de distancia entre la vivienda del ex-colaborador y la dirrección del socio formador, lo que quiere decir que entre más cerca vive una persona de la ubicación de la empresa mayor es la probabilidad de renunciar.

copia_actuales_nl <- copia_actuales_nl %>%
  mutate(ESTATUS = "ACTIVO")
copia_bajas_nl <- copia_bajas_nl %>%
  mutate(ESTATUS = "INACTIVO")

df_consolidad_nl <- bind_rows(copia_bajas_nl, copia_actuales_nl)
hist(df_consolidad_nl$DISTANCIA.KM, 
     main = "Histograma de Distancia (CONSOLIDADO)", 
     xlab = "Distancia en km", 
     ylab = "Frecuencia",
     col = "orange",
     border = "black",
     breaks = "Scott")

intervalos_distancia <- c(0, 1, 2, 3, 5, 10, Inf)

df_consolidad_nl$INT.DISTANCIA <- cut(df_consolidad_nl$DISTANCIA.KM, 
                                            breaks = intervalos_distancia,
                                            labels = c("0-1", "1-2", "2-3", "3-5", "5-10", "10+"),
                                            include.lowest = TRUE)

tc <- tabyl(df_consolidad_nl, INT.DISTANCIA, ESTATUS)

Tabla de Contingencia

tc <- tc %>%
  mutate(TOTAL = rowSums(across(c("ACTIVO", "INACTIVO"))))

tc <- tc %>%
  mutate(PORCENTAJE.ACTIVO = round(ACTIVO / TOTAL * 100),
         PORCENTAJE.INACTIVO = round(INACTIVO / TOTAL * 100))
tc
##  INT.DISTANCIA ACTIVO INACTIVO TOTAL PORCENTAJE.ACTIVO PORCENTAJE.INACTIVO
##            0-1      5       37    42                12                  88
##            1-2     44      260   304                14                  86
##            2-3     10       25    35                29                  71
##            3-5      9       17    26                35                  65
##           5-10      7       37    44                16                  84
##            10+     22       92   114                19                  81

Esta tabla de contingencia nos muestra lo que anteriormente platicabamos, entre mayor es la distancia hay más probabilidades de que las personas permanezcan trabajando dentro de la empresa. Esto lo podemos determinar gracias a que el porcentaje de personas activas es más alto a partir de 15+ kilómetros de distancia, con un 32% de particpación con respecto a los inactivos.

Respuesta

Si, los resultados obtenidos a partir del análisis es que a menor distancia de la dirección del colaborador con respecto a la dirección del Socio Formador hay una mayor probabilidad de que la persona renuncie, y entre mayor sea la distancia, hay una mayor probabilidad de que la persona permanezca en la empresa.

BÚSQUEDA DE INFORMACIÓN Y DATOS

¿Qué tipo de información / datos solicitarías al socio formador para mejorar EDA?

Sería de utilidad aplicar una encuesta al personal del área de producción, dicha encuesta ya fue diseñada por el de equipo ENIGMA ANALYTICS.

Esta encuesta nos revelará el clima organizacional que perciben los empleados de FORM. De esta manera, se podrá saber con mayor claridad cuáles son los aspectos que ocasionan la rotación de personal, y asi crear estrategias a corto y largo plazo para mejorar el problema.

¿Qué tipo de información / datos de fuentes secundarias buscarías para mejorar EDA?

  1. Cantidad de empleados y empleadas que reciben capacitación en la área de Elaboración de Productos de Papel y Cartón.

  2. Cantidad de empleados que cuentan con Seguros de Gastos Médicos Mayores en la área de Elaboración de Productos de Papel y Cartón.

  3. Cantidad de empleados y empleadas que cuentan con las prestaciones básicas de ley en la área de Elaboración de Productos de Papel y Cartón.

  4. Cantidad de empleados y empleadas qué cuentan con un programa de ahorro/inversión en la área de Elaboración de Productos de Papel y Cartón.

Buscar información / datos de fuentes secundarias

Datos sobre Artesanos y Trabajadores en la Elaboración de Productos de Papel y Cartón.

De acuerdo al Gobierno de México, en el primer trimestre de 2023 la fuerza laboral se dividió de la siguiente manera, 29.7%, y 70.3 % mujeres; cabe recalcar que los hombres recibieron un salario promedio mensual de $4.06 k Mxn y las mujeres $2.6 k Mxn alrededor de la república. Esto nos confirma que en efecto sigue existiendo un tema de desigualdad de paga por cuestiones de género, estos problemas pueden causar inconformidad en las mujeres trbajadoras y que por ende busquen trabajo en otra industria o tengan qué buscar un segundo trabajo, y debido al cancancia acumulado, les cueste dar el 100% en sus trabajos. Hay diferentes disparidad de salarios alrededor de la República, en el caso del estado de Nuevo León, de acuerdo con un análisis realizado por el Centro de Investigaciones Económicas de la UANL, en el ámbito laboral las mujeres ganan 42% menos ingresos en promedio por hora qué los hombres. En este caso se recomienda a FORM revisar si este fenómeno se encuentra presente en la empresa, ya que en caso de qué exista, esto podría ser una de las razones por las cuales tienen bajas laborales.

Según Data México, los mejores salarios promedio mensuales para las personas que trabajan en la Industria de la Elaboración de Productos de Papel y Cartón, fueron encontrados en los estados de Nuevo León con un total de $8.6k Mxn, Tlaxcala con $7.34 k Mxn y CDMX con un total de $5.73 k Mxn. Ahora bien si bien el salario promedio es mayor, eso no significa que las personas sean más fieles a sus empresas pro este motivo, ya qué como vimos en FORM a pesar de tener un salario digno siguen sufriendo de bajas laborales.

Igual Data Mexico comparte qué la edad promedio de la fuerza laboral de esta industria es de alrededor de 41 años, esto es un aproximado, pero también es importante este dato, ya que seguramente esta gente cuenta con familia e hijos, los cuales deben de cuidar y seguramente después del trabajo, llegan a este segundo turno en donde deben de cuidar a alguién más y no descansan de manera apropiada; causando efectos no tan positivos en su desempeño laboral, en alguna persona del personal.

PARTE III - REFLEXIÓN

HALLAZGOS

  1. La temperatura resultó tener más relevancia de la se había previsto, convirtiéndose en uno de los factores de la no satisfacción laboral.
  2. La temporada con más bajas de empleados difiere con la opinión que el CEO había proporcionado.
  3. El puesto de trabajo con más empleados es el de ayudante general, donde lo ocupan principalmente mujeres.
  4. Dentro del actual perfil de empleado se encontró que no hay hombres divorciados trabajando en la planta.
  5. Sin importar el género, la edad o algún otro factor, el motivo más común por el cual un empleado se da de baja es por falta de asistencia.

SUGERENCIAS

Gracias a la charla que se tuvo con los Guest Speakers y después de realizar un primer acercamiento con FORM, sin duda el Utilizar la analítica de datos beneficiaría ampliamente a la empresa para mejorar la satisfacción laboral de sus empleados. Aquí hay algunas estrategias que podrían seguir:

  1. Análisis de clima laboral: Utilizar encuestas para medir el clima laboral y la satisfacción de los empleados. Identificar áreas problemáticas y tomar medidas específicas para abordarlas.

  2. Programas de bienestar: Usar datos para identificar las necesidades de bienestar de los empleados y diseñar programas que promuevan la salud física y mental, como actividades deportivas, asesoramiento psicológico o jornadas de trabajo flexibles.

  3. Gestión del desempeño: Utilizar datos para evaluar y mejorar el proceso de gestión del desempeño. Proporcionar retroalimentación basada en datos y establecer metas realistas para los empleados.

  4. Equilibrio trabajo-vida: Analizar datos de horas de trabajo y ausentismo para garantizar un equilibrio adecuado entre el trabajo y la vida personal. Implementar políticas que fomenten un equilibrio saludable.

PARTE IV - REFERENCIAS

Referencias Parte I

Admin. (2023). Proveedora mexicana de empaques ecológicos apuesta por sector automotriz de Estados Unidos. Form. https://form.com.mx/proveedora-mexicana-de-empaques-ecologicos-apuesta-por-sector-automotriz-de-estados-unidos/

Cepeda, F. (2023, January 12). Prepara FORM plan para competir en EU. El Financiero. https://www.elfinanciero.com.mx/monterrey/2023/01/12/prepara-form-plan-para-competir-en-eu/

Fabricación de Productos de Cartón y Papel: Salarios, producción, inversión, oportunidades y complejidad | Data México. (2023). Data México. Acceso: Agosto 18, 2023, de: https://www.economia.gob.mx/datamexico/es/profile/industry/converted-paper-product-manufacturing?investmentFdiTime=Year

Comercio al por Menor de Partes y Refacciones para Automóviles, Camionetas y Camiones: Salarios, producción, inversión, oportunidades y complejidad | Data México. (2023). Data México. Acceso: Agosto 18, 2023, de:https://www.economia.gob.mx/datamexico/es/profile/industry/retail-trade-of-spare-parts-for-cars-and-trucks?genderOrInformal=totalOption&yearSelectorGdp=timeOption0&investmentFdiTime=Year

Fabricación de Automóviles y Camiones: Salarios, producción, inversión, oportunidades y complejidad | Data México. (2023). Data México. Acceso: Agosto 18, 2023, de: https://www.economia.gob.mx/datamexico/es/profile/industry/motor-vehicle-manufacturing?yearSelectorGdp=timeOption0

Statista Research Department. (2013, Septiembre 30). Industry revenue of “Other automotive vehicle parts manufacturing“ in Mexico from 2012 to 2024. Statista. Acceso: Agosto 18, 2023, de: https://0-www-statista-com.biblioteca-ils.tec.mx/forecasts/1170831/other-automotive-vehicle-parts-manufacturing-revenue-in-mexico

Carlier, M. (2021, Octubre 26). Transportation & Logistics› Vehicles & Road Traffic Automotive industry in Mexico - statistics & facts. Statista. Acceso: Agosto 18, 2023, de: https://0-www-statista-com.biblioteca-ils.tec.mx/topics/7249/automotive-industry-in-mexico/#topicOverview

Euromonitor International. (2022, Diciembre 7). Corrugated Paper, Paperboard and Containers in Mexico: ISIC 2102. Passport Euromonitor. Acceso: Agosto 18, 2023, de: https://www.portal.euromonitor.com/analysis/tab

FORM. (2023). Proveedora mexicana de empaques ecológicos apuesta por sector automotriz de Estados Unidos. Form. Acceso: Agosto 18, 2023, de: https://form.com.mx/proveedora-mexicana-de-empaques-ecologicos-apuesta-por-sector-automotriz-de-estados-unidos/

U.S. automotive aftermarket industry size report, 2030. U.S. Automotive Aftermarket Industry Size Report, 2030. (n.d.-a). https://www.grandviewresearch.com/industry-analysis/us-automotive-aftermarket

Publicado por Abigail Orús, & 2023, 28 feb. (2023a, February 28). Automóviles: Ventas por fabricante Estados Unidos 2021-2022. Statista. https://es.statista.com/estadisticas/634261/estados-unidos-ventas-de-automoviles-por-fabricante-diciembre/

Informe del Mercado Automotriz de América del Norte: Tamaño, Participación, Crecimiento y Tendencias (2022-27). Informe del mercado automotriz de América del Norte | Tamaño, participación, crecimiento y tendencias (2022-27). (n.d.). https://www.mordorintelligence.com/es/industry-reports/north-america-automotive-market#:~:text=Estados%20Unidos%20es%20una%20de,que%20el%20año%20anterior%2C%202019.

Diaz, L. O. (2023, April 11). Texas y su relevancia en la industria automotriz. SPC Pro. https://spcpro.com/2023/04/texas-y-su-relevancia-en-la-industria-automotriz/#:~:text=El%20sector%20automotriz%20en%20Texas,Toyota%2C%20General%20Motors%20y%20Tesla.

Referencias Parte II

Situación Problema 1

Statista Research Department. (2021, September 30). Industry revenue of “aerospace product and parts manufacturing“ in Texas from 2012 to 2024. Statista. Retrieved August 30, 2023, from https://0-www-statista-com.biblioteca-ils.tec.mx/forecasts/1205096/aerospace-product-and-parts-manufacturing-revenue-in-texas

Dun & Bradstreet. (n.d.). Aerospace Product And Parts Manufacturing Companies In San Antonio, Texas, United States Of America. Retrieved August 30, 2023, from https://www.dnb.com/business-directory/company-information.aerospace_product_and_parts_manufacturing.us.texas.san_antonio.html

Statista Research Department. (2021b, September 30). Industry revenue of “motor vehicle and parts dealers“ in Texas from 2012 to 2024. Statista. Retrieved August 30, 2023, from https://0-www-statista-com.biblioteca-ils.tec.mx/forecasts/1205324/motor-vehicle-and-parts-dealers-revenue-in-texas

Dun & Bradstreet. (n.d.-b). Motor Vehicle Parts Manufacturing Companies In San Antonio, Texas, United States Of America. Retrieved August 30, 2023, from https://www.dnb.com/business-directory/company-information.motor_vehicle_parts_manufacturing.us.texas.san_antonio.html

Statista Research Department. (2021b, September 30). Industry revenue of “medical equipment and supplies manufacturing“ in Texas from 2012 to 2024. Statista. Retrieved August 30, 2023, from https://0-www-statista-com.biblioteca-ils.tec.mx/forecasts/1205226/medical-equipment-and-supplies-manufacturing-revenue-in-texas

Dun & Bradstreet. (n.d.-b). Medical Equipment And Supplies Manufacturing Companies In San Antonio, Texas, United States Of America. Retrieved August 30, 2023, from https://www.dnb.com/business-directory/company-information.medical_equipment_and_supplies_manufacturing.us.texas.san_antonio.html

Situación Problema 2

En Nuevo León las mujeres ganan en promedio,42% menos ingresos por hora que los hombres: UANL. (2023, March 8). EL ECONOMISTA. Retrieved September 1, 2023, from https://www.eleconomista.com.mx/estados/En-Nuevo-Leon-las-mujeres-ganan-en-promedio42-menos-ingresos-por-hora-que-los-hombres-UANL-20230308-0084.html

Artesanos y Trabajadores en la Elaboración de Productos de Papel y Cartón. (2023). Data Mexico. Retrieved September 1, 2023, from https://www.economia.gob.mx/datamexico/es/profile/occupation/artesanos-y-trabajadores-en-la-elaboracion-de-productos-de-papel-y-carton

El Tiempo en Monterrey en 2022 (México) - Weather Spark. (s. f.). Weather Spark. https://es.weatherspark.com/h/y/5154/2022/Datos-hist%C3%B3ricos-meteorol%C3%B3gicos-de-2022-en-Monterrey-M%C3%A9xico#Figures-Temperature

ANEXOS

KICK OFF Y VISITA A LA PLANTA

INFORMACION DE LA EMPRESA y HALLAZGOS

FORM es una empresa cuyo diferenciador es brindar soluciones especializadas relacionadas con las necesidades del empaque dentro de la cadena de suministro del cliente. No cuentan con un portafolio de productos sino más bien con una metodología de solución que llaman “La Ruta del Empaque” que a través de 5 pasos aseguran cumplir con los estándares de calidad:

  1. Entender la problemática.
  2. Identificar oportunidades.
  3. Desarrollo de prototipos.
  4. Pruebas piloto y evaluación de resultados.
  5. Producción, suministro y servicio.

Proveen empaques a la industria automotriz, sin embargo, se especializan en partes interiores y eléctricas. Además, ofrecen la opción de un software para administrar dicho empaque.

Por otro lado, parte de su talento humano está integrado por 6 ingenieros, quienes se encargan de desarrollar diseños innovadores y eficaces. En el ámbito administrativo trabajan alrededor de 30 personas mientras que a nivel operativo 100 colaboradores. Además, en Durango cuentan con personas que administran sus redes con el fin de conseguir empleados.

Sus principales competidores en México son:

  1. Empaques retornables: Bradford México, Helsa, Conteyor, Victory Packaging, Versatech y Orbis.
  2. Empaques de carton: Empaques Figueroa, HT y Río Grande.

Las zonas geográficas donde buscan tener presencia son:

  1. Monterrey-Saltillo.
  2. Bajío.
  3. San Antonio, Tx.

Lo que busca FORM de la relación con el ITESM Campus Monterrey, se divide en dos vertientes:

1.Recursos Humanos: encontrar soluciones coherentes y sostenibles para la selección, retención y satisfacción del personal. Además de mejorar su clima organizacional.

  1. Mercado/Comercialización: crear un sistema o modelo operativo de inteligencia comercial que les permita acceder de forma más sencilla con clientes potenciales para la empresa. Asimismo, la diversificación e industrias atractivas para venderles.

Las principales preocupaciones del CEO son:

  1. Alta dependencia sobre ciertos clientes.
  2. La permanencia de los empleados en la empresa.
  3. Incertidumbre de Seguridad, Económica y Política de México con otros países.
  4. La empresa todavía depende de él al 100%.

IDEAS

Recursos Humanos
  1. A partir de los datos identificar características específicas (variables) de los colaboradores, para agruparlos por tiempo en la empresa, área laboral, rangos de edad, sexo, estado civil, ubicación geográfica y otras variables relevantes que nos permitan identificar los perfiles de aquellos colaboradores con una alta tendencia a permanecer por más tiempo en la empresa y aquellos con alta tendencia a rotar rápidamente. Esto permitirá identificar el tipo de perfil que debe contratar FORM para mitigar el riesgo por rotación, además de encontrar las variables más significativas que expliquen el tiempo que permanece un colaborador en la empresa.

  2. Una vez identificada el tipo de cultura organizacional qué tienes y los datos de esta, ofrecer un ambiente de desarrollo profesional, en donde lo qué se busca es capacitar al personal en diferentes áreas de utilidad para la empresa, con la finalidad de qué puedan hacer un mejor trabajo para el beneficio del crecimiento de la empresa; y también para qué el personal tenga un plan de desarrollo. Las capacitaciones se llevarían a cabo en un espacio determinado dentro de la empresa, en donde el personal pueda tomar cursos de la aplicación Masterclass

  3. Crear una cultura de Innovación, esto se puede hacer mediante capacitación y la implementación de una “Idea Box”, en la cual durante 3 semanas estará abierta y la gente podrá poner propuestas e ideas qué consideren qué puedan beneficiar a la empresa y sus colaboradores. En la semana 4 se analizarán las ideas y se seleccionará la mejor idea, a la persona qué haya creado dicha idea se le dará un premio el cual consideré la empresa propia. El efecto de esta “Idea Box”, es qué invita a la gente a innovar, se pueden obtener proyectos los cuales ayudan a mejorar los procesos de la empresa, crea un ambiente competitivo y provoca qué la empresa no pare de generar ideas.

Comercialización
  1. Expandirse a las industrias de muebles y arte, enfocándose principalmente en la oferta de empaques para transportar y salvaguardar sus productos; esto permitiría a la empresa diversificar su clientela y el tipo de productos qué ofrecería.

  2. Crear un modelo de toma de decisiones, para identificar aquellos tratos y/o empresas convenientes y llamativas para FORM. Se requiere una asignación numérica u ordinal a cada una de las existentes, para a partir de ello entrenar el modelo y que posteriormente arroje resultados para ordenar y/o clasificar los negocios y tratos futuros. Esto permitirá que, a partir de ciertas variables, en automático se asigne una “calificación” a una empresa o trato y se pueda tomar una mejor decisión, incluso sin la necesidad de la intervención del CEO.

Nota

Por el momento, FORM no ha tenido el deseo de expandir su planta más allá de TEXAS debido al alto costo en fletes, sin embargo, poseen 3 regiones, El bajío, Monterrey-Saltillo y San Antonio, con algunas áreas de oportunidad.

ANÁLISIS GENERAL SITUACIÓN PROBLEMA 1

SITUACIÓN PROBLEMA 1

Cabe recalacar que este análisis exploratorio es general y no se utilizaron bases de datos en R, sin embargo, la inforamción recabada de fuentes secundarias sobre la Situación Problema 1 es bastante interesante y útil para el CEO.

Explorar, desarrollar, y describir la estrategia de comercialización de FORM en la región de San Antonio, TX. La estrategia de comercialización incluye productos actuales (empaque de cartón para la industria automotriz) y/o diversificación de productos (por ejemplo, industria aeroespacial, médica, alimentos, etc.).

Manufactura, Equipo y Productos Médicos en Texas

Los ingresos de la manufactura equipo y productos médicos en Texas de 2020 a 2024 de acuerdo con datos y estimaciones de Statista, está en incremento, por lo que es una industria llamativa en la que FORM podría expandirse. Cabe recalcar que los ingresos esperados de esta área para 2024 son de 4,337.3 millones de dólares, por lo que, debido a su valor, si se encuentran los clientes correctos sería una nueva área en la que FORM podría ofrecer productos.

Las empresas más relevantes de San Antonio, Texas, que manufacturan estos productos, de acuerdo con Dun & Bradstreet, son Acelity L.P. Inc. (S.R. $1,468M USD), Acelity, Inc. (S.R. $945.31 M USD), Visionworks of America, Inc. (S.R. $520.4 M USD), Kinetic Concepts, Inc. (S.R. $500.33 M USD), Kci Usa, Inc. (S.R. $131.81 M USD), Xenex Desinfection Services Inc. (S.R. $47.1 M USD), Vian San Antonio, Inc. ($43.1 M USD) y Celenova Biosciences, Inc. (S.R. $23.51 M USD). Estas empresas pueden ser clientes potenciales de FORM en caso de que decidan apostar por expandirse en la oferta de sus productos y servicios hacia esta industria.

Manufactura de Productos y Partes Aeroespaciales en Texas

Los ingresos de la manufactura de productos y partes aeroespaciales en Texas de 2020 a 2024 de acuerdo con datos y estimaciones de Statista, está en un incremento ligeramente alto, por lo que es una industria llamativa en la que FORM podría apostar en un inicio, tanto porque uno de sus clientes se encuentra en esa industria, como a que esa industria puede llegar a ser similar a la automotriz en la que FORM tiene experiencia, refiriéndonos al tipo de empaques que hace para partes electrónicas y no electrónicas de autopartes. . Cabe recalcar que los ingresos esperados de esta área para 2024 son de 36.9 billones de dólares, por lo que, debido a su valor, si se encuentran los clientes correctos sería una industria de la que FORM se podría beneficiar considerablemente.

Las empresas más relevantes de San Antonio, Texas, que manufacturan estos productos, de acuerdo con Dun & Bradstreet, son Chromalloy, Component Service, Inc. (S.R. $103.06 M USD), Danbury Aerospace, Inc. (S.R. $29.71 M USD), Jeff Boner R&D, Inc. (S.R. $13.62 M USD), Advanced Integration Technology San Antonio, LP (S.R. $12.36 M USD), Sunbelt Design & Development, Inc. (S.R. $8.68 M USD), Aircraft On Ground, Inc. (S.R. $6.75 M USD), C & F Tool & Die Co., LLC ($6.53 M USD) y Spirit Aerosystems, Inc. (S.R. $6.22 M USD). Estas empresas pueden ser clientes potenciales de FORM en caso de que decidan apostar por expandirse en la oferta de sus productos y servicios hacia esta industria.

Industria de Vehículos de Motor y Autopartes en Texas

Los ingresos de los comerciantes de vehículos de motor y autopartes en Texas de 2020 a 2024 de acuerdo con datos y estimaciones de Statista, está en incremento considerable, por lo que es una industria llamativa en la que FORM podría expandirse. Cabe recalcar que los ingresos esperados de esta área para 2024 son de 138.27 billones de dólares, por lo que, debido a su valor, si se encuentran los clientes correctos sería una nueva área en la que FORM podría ofrecer productos; además es una industria en la que ya tienen experiencia y podrían dar consultoría a la clientela estadounidense en que es lo que necesitan en cuestión de empaques. Es por esto que esta industria sería la principal a considerar, en cuestión de expansión.

Las empresas más relevantes de San Antonio, Texas, que manufacturan estos productos, de acuerdo con Dun & Bradstreet, son Xpel, Inc. (S.R. $323.99 M USD), Tk Holdings, Inc. (S.R. $107.09 M USD), Encontrols, LLC (S.R. $98.73 M USD), Toyoda Gosei Texas, LLC (S.R. $55.99 M USD), Toyotetsu Texas, Inc. (S.R. $48.89 M USD), Reyes Automotive Group, LLC (S.R. $28.74 M USD), Reyes Automotive Group II, LLC ($23.92 M USD) y Vintage Air, LLC (S.R. $21.16 M USD). Estas empresas pueden ser clientes potenciales de FORM en caso de que decidan apostar por expandirse en la oferta de sus productos y servicios hacia esta industria.

Estrategia Recomendada (Primer Acercamiento)

Lo que el equipo recomienda a FORM, es primero hacer un análisis interno de la empresa, para conocer las capacidades y limitaciones que tendrían a la hora de fabricar productos y servicios para las industrias y áreas manufactureras previamente comentadas. Una vez hecho este análisis, podrán realizar un catálogo de productos y servicios para cada industria; además se recomienda añadir en ese catálogo/portafolio, la experiencia y clientes que la empresa hay tenido a lo largo de los años.

Posteriormente se recomienda que con la ayuda del cliente Tesla se puedan adquirir nuevos clientes, a la vez en lo que se crea y termina el centro de distribución en Texas, se recomienda que la clientela potencial, sea en esa área, esto con la finalidad de disminuir costes de traslados y empezar a construir un nombre en USA de menos a más. En la parte anterior se compartieron los clientes potenciales de cada industria, esto con el objetivo de que la empresa conozca a quien le puede vender y el valor que tiene cada empresa en cuestión de ingresos; además en caso de querer buscar más opciones de clientela, en el apartado de referencias están los enlaces de donde se sacaron esa lista de clientela potencial.

Después, al seleccionar a los primeros clientes potenciales, se recomienda que la empresa los contacte y logren agendar una cita de negocios en donde le puedan enseñar a cada cliente por qué FORM es la empresa que necesitan para poder entregar sus productos de la manera más segura y eficiente posible.

Finalmente, una vez adquirida la clientela, se espera que, con una buena atención, servicio y las tecnologías que FORM usa en sus procesos, las empresas vean que FORM es su mejor opción y después de haber sido atendidos, recomienden a la empresa con otras empresas con las que tengan algún tipo de asociación; esto causará una cadena la cual provocará que FORM se pueda expandir no solo de manera exitosa en San Antonio, Texas, sino también en otros estados de USA.

LS0tDQp0aXRsZTogIioqRXZpZGVuY2lhIDE6IENvbnRleHRvIGUgSWRlbnRpZmljYWNpw7NuIGRlIE9wb3J0dW5pZGFkZXMqKiINCmF1dGhvcjogIkF1dG9yOiBFcmlrYSBJc2VsYSBSb2RyaWd1ZXogR29uemFsZXoiDQpkYXRlOiAiRmVjaGE6IDIwMjMtMDktMTQiDQpvdXRwdXQ6DQogaHRtbF9kb2N1bWVudDoNCiAgIHRvYzogdHJ1ZQ0KICAgdG9jX2Zsb2F0OiB0cnVlDQogICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICB0aGVtZTogImNvc21vIg0KLS0tDQoNCiFbXShDOlxcVXNlcnNcXGNhXFxEZXNrdG9wXFxSIFN0dWRpb1xcRGF0b3MgRXZpZGVuY2lhIDFcXEZPUk0gMi5qcGcpe3dpZHRoPTgwJX0NCg0KDQojIyMjIENhcmdhbmRvIGxhcyBsaWJyZXJpYXMgbmVjZXNhcmlhcw0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxpYnJhcnkgKHRpZHl2ZXJzZSkNCmxpYnJhcnkgKGZvcmVpZ24pDQpsaWJyYXJ5IChnZ3Bsb3QyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoc2NhbGVzKQ0KbGlicmFyeShnZ3JlcGVsKQ0KbGlicmFyeShsdWJyaWRhdGUpDQpsaWJyYXJ5KHJlYWR4bCkNCmxpYnJhcnkod3JpdGV4bCkNCmxpYnJhcnkocHN5Y2gpDQpsaWJyYXJ5KG9wZW5jYWdlKQ0KbGlicmFyeShodHRyKQ0KbGlicmFyeShnZW9zcGhlcmUpDQpsaWJyYXJ5KGxlYWZsZXQpDQpsaWJyYXJ5KGdnbWFwKQ0KbGlicmFyeShqYW5pdG9yKQ0KYGBgDQoNCiMjIyMgQ2FyZ2FuZG8gcGFsZXRhIGRlIGNvbG9yZXMNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpjb2xvcmVzX2Jhc2UgPC0gYygiZGFya29yYW5nZSIsICJkYXJrZ29sZGVucm9kIiwgInRhbiIpDQpnZW5lcmFyX3ZhcmlhbnRlcyA8LSBmdW5jdGlvbihjb2xvciwgbikgew0KICBjb2xvcl9mdW4gPC0gY29sb3JSYW1wUGFsZXR0ZShjKCJpdm9yeSIsIGNvbG9yKSkNCiAgcmV0dXJuKGNvbG9yX2Z1bihuKSkNCn0NCm1pX3BhbGV0YSA8LSBjKGNvbG9yZXNfYmFzZSwgZ2VuZXJhcl92YXJpYW50ZXMoY29sb3Jlc19iYXNlWzFdLCAxMCksIGdlbmVyYXJfdmFyaWFudGVzKGNvbG9yZXNfYmFzZVsyXSwgMTApLCBnZW5lcmFyX3ZhcmlhbnRlcyhjb2xvcmVzX2Jhc2VbM10sIDEwKSkNCmBgYA0KDQojIyMjIENhcmdhbmRvIGxhcyBiYXNlcyBkZSBkYXRvcyBuZWNlc2FyaWFzDQpQYXJ0ZSBJDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KI0Rlc2VtcGXDsW8gZGUgbGEgRW1wcmVzYQ0KQXV0b3BhcnRzPC1yZWFkLmNzdigiQzpcXFVzZXJzXFxjYVxcRGVza3RvcFxcUiBTdHVkaW9cXERhdG9zIEV2aWRlbmNpYSAxXFxVU19BdXRvX1BhcnRzX0luZHVzdHJ5LmNzdiIpIA0KQ2FyUHJvZHVjdGlvbjwtcmVhZC5jc3YoIkM6XFxVc2Vyc1xcY2FcXERlc2t0b3BcXFIgU3R1ZGlvXFxEYXRvcyBFdmlkZW5jaWEgMVxcVVNfQXV0b19Qcm9kdWN0aW9uX1NhbGVzLmNzdiIpDQpJbXBDYXJ0b25Cb3g8LXJlYWQuY3N2KCJDOlxcVXNlcnNcXGNhXFxEZXNrdG9wXFxSIFN0dWRpb1xcRGF0b3MgRXZpZGVuY2lhIDFcXEltcG9ydGVycyBvZiBDYXJ0b25zIGJveGVzIGNhc2VzIG9mIGNvcnJ1Z2F0ZWQgcGFwZXIgb3IgYm9hcmQgMjAyMC0yMDIxLmNzdiIpDQpFeHBDYXJ0b25Cb3g8LXJlYWQuY3N2KCJDOlxcVXNlcnNcXGNhXFxEZXNrdG9wXFxSIFN0dWRpb1xcRGF0b3MgRXZpZGVuY2lhIDFcXEV4cG9ydGVycyBvZiBDYXJ0b24gYm94ZXMgY2FzZXMgb2YgY29ycnVnYXRlZCBwYXBlciBvciBib2FyZCAyMDIwLTIwMjEuY3N2IikNClJIX2luZm88LXJlYWQuY3N2KCJDOlxcVXNlcnNcXGNhXFxEZXNrdG9wXFxSIFN0dWRpb1xcRGF0b3MgRXZpZGVuY2lhIDFcXGZvcm1fcmhfZGF0b3MuY3N2IikNCkRhdGExIDwtIHJlYWQuY3N2KCJDOlxcVXNlcnNcXGNhXFxEZXNrdG9wXFxSIFN0dWRpb1xcRGF0b3MgRXZpZGVuY2lhIDFcXG14X2V4cG9ydGFjaW9uX2F1dG9zLmNzdiIpDQpSSEIgPC1yZWFkLmNzdigiQzpcXFVzZXJzXFxjYVxcRGVza3RvcFxcUiBTdHVkaW9cXERhdG9zIEV2aWRlbmNpYSAxXFxmb3JtX3JoX2JhamFzX2RhdG9zQi5jc3YiKQ0KTmRhdG9zPC0gcmVhZC5jc3YgKCJDOlxcVXNlcnNcXGNhXFxEZXNrdG9wXFxSIFN0dWRpb1xcRGF0b3MgRXZpZGVuY2lhIDFcXGh5YnJpZF9jYXJfdW5pdHMuY3N2IikNCm14X2V4YXV0byA8LSByZWFkLmNzdigiQzpcXFVzZXJzXFxjYVxcRGVza3RvcFxcUiBTdHVkaW9cXERhdG9zIEV2aWRlbmNpYSAxXFxtZXhfZXhwb3J0c19hdXRvcGFydHMuY3N2IikNCkF1dG9wYXJ0ZXMgPC0gcmVhZC5jc3YoIkM6XFxVc2Vyc1xcY2FcXERlc2t0b3BcXFIgU3R1ZGlvXFxEYXRvcyBFdmlkZW5jaWEgMVxcQXV0b3BhcnRlcy5jc3YiKQ0KdmVudGFzX2NhcnRvbiA8LSByZWFkLmNzdigiQzpcXFVzZXJzXFxjYVxcRGVza3RvcFxcUiBTdHVkaW9cXERhdG9zIEV2aWRlbmNpYSAxXFx2ZW50YXMuY3N2IikNCmBgYA0KDQpQYXJ0ZSBJSQ0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmRhdG9zXzIwMjIgPC0gcmVhZC5jc3YoIkM6XFxVc2Vyc1xcY2FcXERlc2t0b3BcXFIgU3R1ZGlvXFxEYXRvcyBFdmlkZW5jaWEgMVxcQl9mb3JtX3JoX2JhamFzX2RhdG9zXzIwMjIuY3N2IikNCmRhdG9zXzIwMjMgPC0gcmVhZC5jc3YoIkM6XFxVc2Vyc1xcY2FcXERlc2t0b3BcXFIgU3R1ZGlvXFxEYXRvcyBFdmlkZW5jaWEgMVxcQl9CRERfRk9STV9CQUpBU18yMDIzLmNzdiIpDQpkYXRvc19hY3R1YWxlcyA8LSByZWFkLmNzdigiQzpcXFVzZXJzXFxjYVxcRGVza3RvcFxcUiBTdHVkaW9cXERhdG9zIEV2aWRlbmNpYSAxXFxmb3JtX3JoX2RhdG9zICgxKS5jc3YiKQ0KZGF0b3NfMjAyMyA8LSBkYXRvc18yMDIzW2NvbXBsZXRlLmNhc2VzKGRhdG9zXzIwMjMpLF0NCg0KI1VuaW9uIGRlIGJhc2VzIGRlIGRhdG9zDQpkZl9iYWphcyA8LSBiaW5kX3Jvd3MoZGF0b3NfMjAyMiwgZGF0b3NfMjAyMykNCmRmX2JhamFzIDwtIGFzLmRhdGEuZnJhbWUobGFwcGx5KGRmX2JhamFzLCB0b3VwcGVyKSkNCmBgYA0KDQojICoqRk9STSoqDQoNCkxhIGVtcHJlc2EgcmVnaW9tb250YW5hIEZPUk0gZGVzYXJyb2xsYSBzb2x1Y2lvbmVzIGRlIGVtcGFxdWUgcXVlIGdlbmVyYW4gdmFsb3IgYWdyZWdhZG8gZW4gbGEgY2FkZW5hIGRlIHN1bWluaXN0cm8gZGUgc3VzIGNsaWVudGVzLCBjb25zaWRlcmFuZG8gbm8gc29sbyBsYSBwcm90ZWNjacOzbiBkZSBsb3MgcHJvZHVjdG9zLCBzaW5vIHRhbWJpw6luIGxhcyBuZWNlc2lkYWRlcyBwcm9kdWN0aXZhcywgb3BlcmF0aXZhcyB5IGRlIGFsbWFjZW5hamUsIHNpZW1wcmUgdGVuaWVuZG8gYWwgc2VyIGh1bWFubyBjb21vIGNlbnRybyBkZSBzdXMgcHJvY2Vzb3MuICoiTm8gaW1wb3J0YSBkZSBxdcOpIGF1dG9wYXJ0ZSBzZSB0cmF0ZSwgbm9zb3Ryb3MgdGVuZW1vcyBsYSBzb2x1Y2nDs24iLiogKEZPUk0sIDIwMjMpLg0KDQohW10oQzpcXFVzZXJzXFxjYVxcRGVza3RvcFxcUiBTdHVkaW9cXEltYWdlbiBGb3JtLnBuZykNCg0KW1NpdGlvIFdlYiBkZSBsYSBFbXByZXNhXSAoaHR0cHM6Ly9mb3JtLmNvbS5teC8pDQoNCiMjICoqKlBBUlRFIEkgLSBFWFBMT1JBUiBZIENPTk9DRVIgTEEgRU1QUkVTQSBZIFNVIENPTlRFWFRPKioqDQoNCiMjIyAqKlJlc3VtZW4gS2ljayBPZmYgeSB2aXNpdGEgYSBsYSBwbGFudGEqKg0KDQpQb2Ryw6FzIGVuY29udHJhciBlc3RhIGluZm9ybWFjacOzbiBlbiBsYSBQYXJ0ZSBkZSAqKkFORVhPUyoqIHNpdHVhZGEgYWwgZmluYWwgZGVsIGRvY3VtZW50by4gDQoNCiMjIyAqKkFudGVjZWRlbnRlcyBkZSBsYSBFbXByZXNhKioNCg0KIyMjIyBWaXNpw7NuDQoNCkVuIDIwMzMgc2VyZW1vcyB1bmEgZGUgbGFzIGNpbmNvIG1lam9yZXMgY29tcGHDscOtYXMgZGUgTcOpeGljbyBxdWUgZ2VuZXJhbiB2YWxvciBkZW50cm8gZGUgbGEgY2FkZW5hIGRlIHN1bWluaXN0cm8gZGUgbGFzIGluZHVzdHJpYXMgcXVlIG3DoXMgdmFsb3JhbiBsYSBmb3JtYSBlbiBsYSBxdWUgc2UgcHJvdGVnZW4geSB0cmFzbGFkYW4gbGFzIGNvc2FzLiANCg0KIyMjIyBNaXNpw7NuDQoNClRyYW5zZm9ybWFyIG51ZXN0cm8gZW50b3JubyB5IHJlc29sdmVyIHJldG9zIGluZHVzdHJpYWxlcyBkZSBudWVzdHJvcyBjbGllbnRlcyBhIHRyYXbDqXMgZGUgbGEgY29sYWJvcmFjacOzbiwgcHJvdm9jYW5kbyBudWV2YXMgb3BvcnR1bmlkYWRlcyBxdWUgcG90ZW5jaWFuIG51ZXN0cm8gbW9kZWxvIGRlIG5lZ29jaW8sIHBhcmEgYWxjYW56YXIgbnVlc3Ryb3MgaWRlYWxlcy4NCg0KIyMjIyBPYmpldGl2b3MgRXN0cmF0w6lnaWNvcw0KDQoxLiBJbnRlbGlnZW5jaWEgY29tZXJjaWFsLg0KMi4gU2lzdGVtYXRpemFyIGxhIHByb2R1Y2Npw7NuLiANCjMuIEdlbmVyYXIgdW4gc2VudGlkbyBkZSBwZXJ0ZW5lbmNpYSBlbiBsb3MgY29sYWJvcmFkb3Jlcy4NCjQuIERpdmVyc2lmaWNhY2nDs24sIHByaW5jaXBhbG1lbnRlIGVuIEVzdGFkb3MgVW5pZG9zLg0KNS4gQ29udmVydGlyc2UgZW4gbGEgZW1wcmVzYSBjb24gbWVqb3JlcyByZW11bmVyYWNpb25lcyBlbiBOdWV2byBMZcOzbi4gDQoNCiMjIyMgRGVzZW1wZcOxbyBkZSBsYSBFbXByZXNhDQoNCjEuIEFjcmVlZG9yIGFsIFByZW1pbyBOYWNpb25hbCBkZSBFbnZhc2UgZW4gMjAxMCwgMjAxNCwyMDE1LDIwMTYsMjAxNywyMDE5IHkgMjAyMiwgcmVjb25vY2llbmRvIGxhIHNvc3RlbmliaWxpZGFkIGRlIGxvcyBlbnZhc2VzIHkgZW1iYWxhamVzIGNvbW8gcHJvZHVjdG8gZGUgbGEgaW5ub3ZhY2nDs24uICANCg0KMi4gSW5ub3ZhY2nDs24gY29uIHBhdGVudGUgZ2xvYmFsIHF1ZSBwZXJtaXRlIGEgbGFzIGNvbXBhw7HDrWFzIHJlZHVjaXIgZXNwYWNpbyB5IGFob3JyYXIgZW4gbG9nw61zdGljYS4gU2UgdHJhdGEgZGUgdW5hIGNhamEgcXVlIGRpc21pbnV5ZSBlbCBlc3BhY2lvIGVuIGFsbWFjw6luIHkgYXVtZW50YSBsYSBjYXBhY2lkYWQgZGUgZW1wYXF1ZSB1biAxMC0xNSUgcGFyYSBwcm9kdWN0b3MgZGVsIHNlY3RvciBhdXRvbW90cml6LiANCg0KMy4gRW4gMjAyMiBUZXNsYSBzZSBjb252aXJ0acOzIGVuIHVubyBkZSBzdXMgbnVldm9zIHNvY2lvcywgRk9STSBsZSBwcm92ZWUgY2FqYXMgZGUgY2FydMOzbiBwZXJzb25hbGl6YWRhcywgZXMgdW5hIGzDrW5lYSBwZXJzb25hbGl6YWRhIGVuIGRvbmRlIHNlIGNyZWFuIHBpZXphcyB2aXN0YSwgZWxlY3Ryw7NuaWNhcyBvIGRlIENsYXNlIEEuDQoNCjQuIEVuIGxvcyDDumx0aW1vcyA1IGHDsW9zIGxhIGVtcHJlc2EgYSBkdXBsaWNhZG8gc3UgY3JlY2ltaWVudG8geSBlbiBwYW5kZW1pYSBsb2dyw7MgbWFudGVuZXIgc3Ugdm9sdW1lbiBkZSB2ZW50YXMuDQoNCjUuIEdyYWNpYXMgYSBsYSBpbnZlcnNpw7NuIGVuIGHDsW9zIGFudGVyaW9yZXMsIGhveSBlbiBkw61hIGxhIGVtcHJlc2EgY3VlbnRhIGxhIGNlcnRpZmljYWNpw7NuIElTTyA5MDAwLTIwMTUuDQoNCiMjIyMgVmFsb3IgQWdyZWdhZG8NCg0KMS4gRXNwZWNpYWxpemFjacOzbiBlbiBjYXJ0w7NuIGNvcnJ1Z2Fkby4NCjIuIFZlcnNhdGlsaWRhZCBlbiByZXRvcm5hYmxlcy4NCjMuIENvbnN1bHRvcsOtYSBlbiBJbmdlbmllcsOtYSBkZSBlbXBhcXVlLiANCjQuIFNvZnR3YXJlIGRlIEFkbWluaXN0cmFjacOzbiBkZSBlbXBhcXVlLiANCjUuIFZpc2nDs24gZGUgYWRxdWlzaWNpw7NuIGRlIGNsaWVudGVzLiANCjYuIEFob3JybyBlbiB0aWVtcG9zIGRlIHByb2R1Y2Npw7NuLg0KNy4gQ2FiZW4gbcOhcyBwcm9kdWN0b3MgZW4gdW4gZW1wYXF1ZS4NCjguIENvbnRyb2wgZGUgaW52ZW50YXJpbyBhbnRpY2lwYWRvIGEgbGEgZGVtYW5kYSBjb24gbcOtbmltb3MgeSBtw6F4aW1vcy4NCg0KIyMjIyAqKkdyw6FmaWNhcyBkZSBSUkhIKioNCg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KIyBDcmVhbmRvIHVuIERhdGEgRnJhbWUNClJIMTwtUkhfaW5mbyU+JXNlbGVjdChGRUNIQS5ERS5OQUNJTUlFTlRPLEdFTkVSTyxGRUNIQS5ERS5BTFRBLFByaW1lci5tZXMsWDR0by5tZXMsUFVFU1RPLERFUEFSVEFNRU5UTyxTQUxBUklPLkRJQVJJTy5JTVNTLEVTVEFETy5DSVZJTCxUQVJKRVRBLkNVRU5UQSkNClZpZXcoUkgxKQ0KYGBgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIENhbGN1bGFyIGxvcyA2IHB1ZXN0b3MgbcOhcyBhbHRvcyBlbiBmdW5jacOzbiBkZSBsYSB2YXJpYWJsZSAiUFVFU1RPIg0KdG9wXzVfcHVlc3RvcyA8LSBSSDEgJT4lDQogIGNvdW50KFBVRVNUTykgJT4lDQogIHRvcF9uKDUsIHd0ID0gbikNCg0KIyBGaWx0cmFyIGVsIGNvbmp1bnRvIGRlIGRhdG9zIHBhcmEgaW5jbHVpciBzb2xvIGxvcyA1IHB1ZXN0b3MgbcOhcyBhbHRvcw0KUkgxX3RvcF81X3B1ZXN0b3MgPC0gUkgxICU+JQ0KICBmaWx0ZXIoUFVFU1RPICVpbiUgdG9wXzVfcHVlc3RvcyRQVUVTVE8pDQoNCiMgQ3JlYXIgZWwgZ3LDoWZpY28gY29uIGxvcyA1IHB1ZXN0b3MgbcOhcyBhbHRvcw0KZyA8LSBnZ3Bsb3QoUkgxX3RvcF81X3B1ZXN0b3MsIGFlcyhQVUVTVE8sIGZpbGwgPSBHRU5FUk8pKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiVG9wIDYgZGUgUHVlc3RvcyBkZSBUcmFiYWpvIHBvciBHw6luZXJvIiwNCiAgICB4ID0gIlB1ZXN0byAoQWJyZXZpYXR1cmEpIg0KICApICsNCiAgeWxhYigiTm8uIFBlcnNvbmFzIikgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSByZWwoMiksIGNvbG91ciA9ICJkYXJrZ29sZGVucm9kMyIpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtaV9wYWxldGEpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxMCkpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCnByaW50KGcpDQpgYGANCg0KU2UgbXVlc3RyYSBsYSBkaXN0cmlidWNpw7NuIGRlIGfDqW5lcm8gZGUgbG9zIDYgcHJpbmNpcGFsZXMgcHVlc3RvcyBkZSB0cmFiYWpvLCBkb25kZSBzZSBvYnNlcnZhIHVuYSBtYXlvciBjYW50aWRhZCBkZSBtdWplcmVzIGVuIEZPUk0sIGVzcGVjaWFsbWVudGUgZW4gZWwgcHVlc3RvIGRlIGF5dWRhbnRlIGdlbmVyYWwuDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpSSEIgPC0gcmVuYW1lIChSSEIsTU9USVZPLkRFLkJBSkEgPSAiTU9USVZPLkRFLkJBSkEiKQ0KQmFqYXNfcG9yX2dlbmVybzwtIHNlbGVjdChSSEIsR0VORVJPLE1PVElWTy5ERS5CQUpBKQ0KZ2dwbG90KEJhamFzX3Bvcl9nZW5lcm8sIGFlcyhHRU5FUk8pKStnZW9tX2JhcihhZXMoZmlsbD1NT1RJVk8uREUuQkFKQSksIHdpZHRoID0gMC41KStnZ3RpdGxlICgiTW90aXZvcyBkZSBiYWphIHBvciBnZW5lcm8iKSsgdGhlbWVfbWluaW1hbCgpICsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWlfcGFsZXRhKSArIGdlb21fdGV4dCgNCiAgICBhZXMobGFiZWwgPSAuLmNvdW50Li4pLA0KICAgIHN0YXQgPSAiY291bnQiLA0KICAgIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLA0KICAgIHNpemUgPSAzDQogICkNCmBgYA0KDQpTZSBwdWVkZSB2ZXIgdW5hIGRpZmVyZW5jaWEgc2lnbmlmaWNhdGl2YSBlbiBlbCBnw6luZXJvIGRlIGxvcyBlbXBsZWFkb3MsIHB1ZXN0byBxdWUgZXhpc3RlbiBtw6FzIG11amVyZXMgcXVlIGhvbWJyZXMuIERlIGlndWFsIGZvcm1hLCBsYSBkaWZlcmVuY2lhIGVudHJlIGxvcyBtb3Rpdm9zIGRlIGJhamEgZGUgbG9zIGVtcGxlYWRvcyBlcyBub3RvcmlhLCBwdWVzIGVuIGFtYm9zIHNleG9zIGVsIHByaW5jaXBhbCBtb3Rpdm8gZXMgcG9yIGZhbHRhcy4gRXN0byBlcyBhbGdvIGFsYXJtYW50ZSBwYXJhIEZPUk0sIHlhIHF1ZSBzaWduaWZpY2EgcXVlIGxvcyBlbXBsZWFkb3Mgbm8gdGllbmVuIHVuIGNvbXByb21pc28gbGFib3JhbC4NCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmdncGxvdChSSEIsIGFlcyhHRU5FUk8pKSArDQogIGdlb21fYmFyKGFlcyhmaWxsID0gR0VORVJPKSwgd2lkdGggPSAuMjUpICsgICMgVXRpbGl6YSBHRU5FUk8gcGFyYSBkZXRlcm1pbmFyIGxvcyBjb2xvcmVzDQogIGxhYnModGl0bGUgPSAiRGlzdHJpYnVjacOzbiBkZSBHw6luZXJvIHBvciBEw61hcyBMYWJvcmFkb3MgYW50ZSBkZSBTYWxpciIsDQogICAgICAgeCA9ICJHw6luZXJvIiwNCiAgICAgICB5ID0gIiBQcm9tZWRpbyBkZSBEw61hcyAgZGUgdHJhYmFqbyIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWlfcGFsZXRhKQ0KYGBgDQoNCkVuIGxhIGdyw6FmaWNhIHNlIG11ZXN0cmFuIGxvcyBkw61hcyB0cmFiYWphZG9zIGFudGVzIGRlIHNhbGlyIGRlIGxhIGVtcHJlc2EgcG9yIGdlbmVybzsgTGFzIG11amVyZXMgdGllbmVuIHVuIHByb21lZGlvIHN1cGVyaW9yIGFsIGRlIGxvcyBob21icmVzLiAgU2UgcHVlZGUgb2JzZXJ2YXIgcXVlIGxvcyBob21icmVzIHF1ZSBzYWxpZXJvbiBkZSBsYSBlbXByZXNhIHRyYWJhamFuIGVuIHVuIHJhbmdvIGRlIDEwMCBkw61hcyB5IGxhcyBtdWplcmVzIGVuIGFwcm94aW1hZGFtZW50ZSAxMzAgZMOtYXMuDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpyaF9tIDwtIFJIX2luZm8gJT4lDQogIHNsaWNlKC0yMikNCm11bmljaXBpb3MgPC0gcmhfbSAlPiUNCiAgZmlsdGVyKEVTVEFETz09Ik5VRVZPIExFT04iKSAlPiUNCiAgZ3JvdXBfYnkoTVVOSUNJUElPLCBHRU5FUk8pICU+JQ0KICBzdW1tYXJpc2UodG90YWxfcGVyc29uYXMgPSBuX2Rpc3RpbmN0KE5PTUJSRSkpDQpnZ3Bsb3QobXVuaWNpcGlvcywgYWVzKHggPSBNVU5JQ0lQSU8sIHkgPSB0b3RhbF9wZXJzb25hcywgZmlsbCA9IEdFTkVSTykpICsNCiAgZ2VvbV9jb2woKSArDQogIGxhYnModGl0bGUgPSAiQ29sYWJvcmFkb3JlcyBwb3IgTXVuaWNpcGlvIiwNCiAgICAgICB4ID0gIk11bmljaXBpbyIsDQogICAgICAgeSA9ICJUb3RhbCBkZSBQZXJzb25hcyIsDQogICAgICAgZmlsbCA9ICJHw6luZXJvIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtaV9wYWxldGEpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KDQpFbiBlc3RlIGdyw6FmaWNvIHBvZGVtb3Mgb2JzZXJ2YXIgYSBxdWUgbXVuaWNpcGlvIHBlcnRlbmVjZSBjYWRhIHVubyBkZSBsb3MgY29sYWJvcmFkb3JlcywgZXN0YSBpbmZvcm1hY2nDs24gbm9zIHBlcm1pdGUgaWRlbnRpZmljYXIgbGEgZGlzdGFuY2lhIG8gZWwgdGllbXBvIHF1ZSBsZXMgdG9tYSBsbGVnYXIgYSBsYSBwbGFudGEuIENvbiBlc3RhIGluZm9ybWFjacOzbiBwb2RlbW9zIHRvbWFyIGRlY2lzaW9uZXMgZW4gY3VhbnRvIGEgdHJhbnNwb3J0ZSBwYXJhIHBlcnNvbmFsIG8gaW5jbHVzbyBpZGVudGlmaWNhciBwb3NpYmxlcyByaWVzZ29zLg0KDQojIyMgKipDb250ZXh0byBkZSBsYSBJbmR1c3RyaWEqKg0KDQojIyMjICoqSW5kdXN0cmlhIEF1dG9tb3RyaXoqKg0KDQoqTcOJWElDTyoNCg0KRGUgYWN1ZXJkbyBjb24gRGF0YSBNw6l4aWNvIHkgZWwgREVOVUUgMjAyMiBsYSBmYWJyaWNhY2nDs24gZGUgYXV0b23Ds3ZpbGVzIHkgY2FtaW9uZXMgcmVnaXN0csOzIDczIHVuaWRhZGVzIGVjb27Ds21pY2FzOyBzaWVuZG8gQ0RNWCAoOSksIEVET01FQyAoOSkgeSBOdWV2byBMZcOzbiAoNykgbG9zIGVzdGFkb3MgY29uIG3DoXMgdW5pZGFkZXMuICBPdHJvcyBlc3RhZG9zIGRlbCBub3J0ZSBxdcOpIGN1ZW50YW4gY29uIHVuIG7Dum1lcm8gc2lnbmlmaWNhbnRlIGRlIHVuaWRhZGVzIGVjb27Ds21pY2FzIHNvbiBCYWphIENhbGlmb3JuaWEgeSBDb2FodWlsYSBkZSBaYXJhZ296YS4NCg0KTG9zIGVzdGFkb3MgcXXDqSBtw6FzIGhhbiByZWNpYmlkbyBJbnZlcnNpw7NuIEV4dHJhbmplcmEgRGlyZWN0YSBlbiAyMDIyLCBmdWVyb24gR3VhbmFqdWF0byAoJDk4OSBtaWxsb25lcyBkZSBVU0QpLCBDRE1YICgkNTE1IG1pbGxvbmVzIGRlIFVTRCApIHkgQmFqYSBDYWxpZm9ybmlhICgkMzI5IE1pbGxvbmVzIGRlIFVTRCk7IGVzdGFzIGludmVyc2lvbmVzIHByb3ZpZW5lbiBkZSAzIHByaW5jaXBhbGVzIHBhw61zZXMgc2llbmRvIGVzdG9zIEVzdGFkb3MgVW5pZG9zIGNvbiAkMSwzMjcgTWlsbG9uZXMgZGUgVVNELCBKYXDDs24gY29uICQ5MTEgTWlsbG9uZXMgZGUgVVNEIHkgQ29yZWEgZGVsIFN1ciBjb24gJDUwNyBtaWxsb25lcyBkZSBVU0QuDQoNCkVzdGEgaW5mb3JtYWNpw7NuIGVzIGltcG9ydGFudGUgY29udGVtcGxhcmxhLCB5YSBxdWUgcGVybWl0ZSBjb25vY2VyIGVuIHF1ZSBlc3RhZG9zIHNlIGVzdMOhIHByb2R1Y2llbmRvIGUgaW52aXJ0aWVuZG8gbcOhcyBlbiBlbCDDoW1iaXRvIEF1dG9tb3RyaXosIHkgcG9yIGVuZGUsIHB1ZWRlbiByZXByZXNlbnRhciB6b25hcyBkZSBvcG9ydHVuaWRhZCBlbiBkb25kZSBsYSBlbXByZXNhIHBvZHLDrWEgb2ZlcnRhciBzdXMgcHJvZHVjdG9zIHkgc2VydmljaW9zIGRlIGVtcGFxdWUgZGUgYXV0b3BhcnRlczsgYSBsYSB2ZXogZWwgaGVjaG8gZGUgc2FiZXIgcXXDqSBwYcOtc2VzIGVzdMOhbiBpbnZpcnRpZW5kbyBwdWVkZSBheXVkYXIgYSBjb25vY2VyIGEgcXXDqSB0aXBvIGRlIGNsaWVudGUgc2UgbGUgZXN0YXLDoSBpbnRlbnRhbmRvIHZlbmRlciwgeSBlbiBjYXNvIGRlIHF1ZSBsYSByZWxhY2nDs24gZGUgbmVnb2NpbyBzZWEgZXhpdG9zYSwgYSBxdcOpIHBhw61zZXMgZW4gdW4gZnV0dXJvIHBvZHLDrWEgZXhwYW5kaXJzZS4NCg0KUG9yIG90cm8gbGFkbywgQ2FybGllciBNYXRoaWxkZSAoMjAyMSksIFJlc2VyY2ggRXhwZXJ0IGRlIFN0YXRpc3RhLCBjb21lbnRhIHF1ZSwgbGFzIHByZXZpc2lvbmVzIGRlbCBtZXJjYWRvIGRlIGxhIEluZHVzdHJpYSBBdXRvbW90cml6IGFwdW50YW4gYSB1biBjcmVjaW1pZW50byBjb25zdGFudGUgZW4gbG9zIHByw7N4aW1vcyA0IGHDsW9zLiBBZGVtw6FzLCBncmFjaWFzIGFsIGFjdWVyZG8gVVNNQ0EgZW50cmUgVVNBLCBNw6l4aWNvIHkgQ2FuYWTDoSwgc2UgcmVub3Zhcm9uIGxhcyByZWd1bGFjaW9uZXMgZGUgTGlicmUgQ29tZXJjaW8sIHBvciBsbyBxdWUsIGxhIGV4cGFuc2nDs24gZGUgRk9STSBhIFNhbiBBbnRvbmlvIHkgc3UgZXhwb3J0YWNpw7NuIGEgVVNBLCBubyBkZWJlcsOtYSBjb250ZW5lciBpbmNvbnZlbmllbnRlcyBsZWdhbGVzLg0KDQoqVVNBKg0KDQpTZWfDum4gZGF0b3MgZGUgTW9yZG9yIEludGVsaWdlbmNpZSBFc3RhZG9zIFVuaWRvcyBlcyB1bmEgZGUgbGFzIHByaW5jaXBhbGVzIEluZHVzdHJpYXMgQXV0b21vdHJpY2VzIGVuIGVsIG11bmRvLCB5YSBxdWUgY29udHJpYnV5ZSBjb24gdW4gMyUgZGUgUElCIGVuIHRvZG8gZWwgcGHDrXMuIEVuIGVsIDIwMjIgbGEgcHJvZHVjY2nDs24gZGUgdmVow61jdWxvcyB0dXZvIHVuIHRvdGFsIGRlIDEwLDA2MCwzMzkgdW5pZGFkZXMsIGVzIGRlY2lyLCB1biBjcmVjaW1pZW50byBkZSA5Ljc0JSByZXNwZWN0byBhbCAyMDIxLg0KDQpEZSBhY3VlcmRvIGNvbiBkYXRvcyBkZSBCYW5raW50ZXIgRXN0YWRvcyBVbmlkb3Mgc2UgcG9zaWNpb25hIGVuIGVsIHNlZ3VuZG8gcHVlc3RvIGRlIGZhYnJpY2FjacOzbiBkZSBjb2NoZXMgcHJldmlzdG9zIHBhcmEgZWwgMjAyMy4NCg0KQWRlbcOhcywgbG9zIHByaW5jaXBhbGVzIHZlbmRlZG9yZXMgZGUgYXV0b3MgZHVyYW50ZSBlbCAyMDIyIGZ1ZXJvbiBHZW5lcmFsIE1vdG9ycywgVG95b3RhIE1vdG9yIHkgRm9yZCB1YmljYWRvcyBlbiBNaWNoaWdhbiBPaGlvLCBJbmRpYW5hIEtlbnR1Y2t5IFRlbm5lc3NlZSwgQWxhYmFtYSBUZXhhcyB5IENhbGlmb3JuaWEuDQoNCkVuIFRleGFzIHNlIGVuY3VlbnRyYSB1bmEgZGUgbGFzIEluZHVzdHJpYXMgQXV0b21vdHJpY2VzIG3DoXMgaW1wb3J0YW50ZXMsIFRveW90YSBHZW5lcmFsIE1vdG9ycyB5IFRlc2xhLiBUZXNsYSBwb3NlZSB1bmEgbWVnYSBmw6FicmljYSBlbiBlbCDDoXJlYSBkZSBBdXN0aW4geSBzZSBlc3BlcmEgcXVlIGVsIHByb3llY3RvIGNyZWUgNTAwMCBudWV2b3MgZW1wbGVvcyB5IG3DoXMgZGUgMTAwMCBtaWxsb25lcyBkZSBkw7NsYXJlcyBlbiBpbnZlcnNpw7NuIGRlIGNhcGl0YWwuIEFkZW3DoXMsIFRleGFzIHJlcHJlc2VudMOzIGVsIDIwJSBkZWwgdG90YWwgZGUgRXN0YWRvcyBVbmlkb3MgZW4gbGEgSW5kdXN0cmlhIEF1dG9tb3RyaXouDQoNCiMjIyMgKipHcsOhZmljYXMgSW5kdXN0cmlhIEF1dG9tb3RyaXoqKg0KDQojIyMjIyAqKkV4cG9ydGFjaW9uZXMgZGUgQXV0b3MgZW4gTcOpeGljbyBwb3IgTWFyY2EqKg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KRXhwb3J0YWNpb25lcyA8LURhdGExICU+JSBncm91cF9ieShNYXJjYSkgJT4lIHN1bW1hcmlzZShudW1fZXhwb3J0YWNpb25lcz1uKCkpICU+JSBhcnJhbmdlIChkZXNjKG51bV9leHBvcnRhY2lvbmVzKSkNCk1hcmNhX21hc19leHBvcnRhY2lvbmVzIDwtIERhdGExICU+JSBmaWx0ZXIoTWFyY2EgJWluJSBjKCJOaXNzYW4iLCJWb2xrc3dhZ2VuIiwiR2VuZXJhbCBNb3RvcnMiLCJDaHJ5c2xlciIsIk1hemRhIiwiRm9yZCBNb3RvciIsIktJQSIsIkhvbmRhIiwiRmlhdCIsIkF1ZGkiKSkNCmdncGxvdChNYXJjYV9tYXNfZXhwb3J0YWNpb25lcyxhZXMoTWFyY2EsZmlsbD1NYXJjYSkpK2dlb21fYmFyKCkrZ2d0aXRsZSAoIlRvcCAxMCBFeHBvcnRhY2lvbmVzIHBvciBNYXJjYSIpICsgdGhlbWVfbWluaW1hbCgpICsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWlfcGFsZXRhKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANCg0KTGEgbWFyY2EgY29uIG3DoXMgZXhwb3J0YWNpb25lcyBwb3IgYcOxbyBlcyBOaXNzYW4sIGNvbiBjYXNpIDI0MDAwIHVuaWRhZGVzLCBlc3RvIGVzIGNvbnZlbmllbnRlIHBhcmEgRk9STSB5YSBxdWUsIGFsIHNlciB1bmEgTWFyY2EgZGUgb3JpZ2VuIGphcG9uZXMsIGVudHJhIGVuIGVsIG1lcmNhZG8gZGUgY2xpZW50ZXMgZGUgc3UgaW50ZXLDqXMuDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpSZWdpb25lcyA8LSBmaWx0ZXIoTmRhdG9zLHJlZ2lvbiAlaW4lDQpjKCJDZW50cm8tTm9ydGUiLCJOb3J0ZSIsIk5vcnRlLU9jY2lkZW50ZSIsIkNlbnRybyIsIlN1ciIpKQ0KZ2dwbG90KGRhdGE9UmVnaW9uZXMsDQphZXMoeD1yZWdpb24seT1oeWJyaWRfY2FyX3VuaXRzLGZpbGw9cmVnaW9uDQopKSArIGdlb21fYm94cGxvdCgpICsgeWxpbSgwLDEwMDApICsNCnRoZW1lX21pbmltYWwoKSArIHlsYWIoIlVuaWRhZGVzIGRlIGNhcnJvcyBoeWJyaWRvcyIpICsNCmdndGl0bGUoIlVuaWRhZGVzIGRlIGNhcnJvcyBoeWJyaWRvcyBwb3Igem9uYXMgZGUgTcOpeGljbyIpICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtaV9wYWxldGEpDQpgYGANCg0KRW4gZXN0YSBncsOhZmljYSB2ZW1vcyBsYSBjYW50aWRhZCBkZSBjYXJyb3MgaMOtYnJpZG9zIHBvciB6b25hcyBkZSBNw6l4aWNvIGVuIGxhIHF1ZSBsYSBtYXlvciB2ZW50YSBzZSBkYW4gZW4gbGEgem9uYSBOb3J0ZSBwZXJvIGVsIG1heW9yIHJlbmRpbWllbnRvIGVzIGVuIGxhIHpvbmEgTm9ydGUgT2NjaWRlbnRlLiBUYW1iacOpbiBzZSBwdWVkZSB2ZXIgcXVlIGVsIHBlb3Igc2VjdG9yIGVzIGVsIGRlbCBTdXIuDQoNCiMjIyMgKipJbmR1c3RyaWEgQXV0b3BhcnRlcyoqDQoNCipNw4lYSUNPKg0KDQpEZSBhY3VlcmRvIGNvbiBEYXRhIE3DqXhpY28geSBlbCBDZW5zbyBFY29uw7NtaWNvIDIwMTksIGxhIFByb2R1Y2Npw7NuIEJydXRhIGRlbCBDb21lcmNpbyBhbCBwb3IgTWVub3IgZGUgUGFydGVzIHkgUmVmYWNjaW9uZXMgcGFyYSBBdXRvbcOzdmlsZXMsIENhbWlvbmV0YXMgeSBDYW1pb25lcywgZnVlIGRlIHVuIHRvdGFsIGRlICQ4OSw2OTUgbWlsbG9uZXMgZGUgcGVzb3M7IGxvcyBlc3RhZG9zIGNvbiBtYXlvciBwcm9kdWNjacOzbiBmdWVyb24gQ0RNWCBjb24gJDgsODk4IG1pbGxvbmVzIGRlIHBlc29zIHkgSmFsaXNjbyBjb24gJDgsNDU3IG1pbGxvbmVzIGRlIHBlc29zLiBFc3RlIGRhdG8gZXMgaW1wb3J0YW50ZSBhIGNvbnNpZGVyYXIgcG9ycXVlIHBlcm1pdGUgY29ub2NlciBjdWFsZXMgc29uIGxvcyBlc3RhZG9zIHF1ZSBtw6FzIGVzdMOhbiBwcm9kdWNpZW5kbyBhdXRvcGFydGVzIGVuIE3DqXhpY28sIHkgcG9yIGVuZGUsIHNvbiBjbGllbnRlcyBwb3RlbmNpYWxlcyBwYXJhIEZPUk0uDQoNCkxvcyBFc3RhZG9zIHF1w6kgbcOhcyBoYW4gcmVjaWJpZG8gSW52ZXJzacOzbiBFeHRyYW5qZXJhIERpcmVjdGEgZW4gMjAyMiwgZnVlcm9uIFF1ZXLDqXRhcm8gKCQxNCBtaWxsb25lcyBkZSBVU0QpLCBDb2FodWlsYSBkZSBaYXJhZ296YSAoJDIuNzEgbWlsbG9uZXMgZGUgVVNEKSB5IENETVggKCQyLjY5IE1pbGxvbmVzIGRlIFVTRCk7IGVzdGFzIGludmVyc2lvbmVzIHByb3ZpZW5lbiBkZSAzIHByaW5jaXBhbGVzIHBhw61zZXM6IEphcMOzbiwgQ29yZWEgZGVsIFN1ciB5IENhbmFkw6EuIEFsIHJlY2liaXIgbWF5b3IgaW52ZXJzacOzbiBzZSBjb252aWVydGVuIGVuIHpvbmFzIGRlIG9wb3J0dW5pZGFkIGVuIGRvbmRlIGxhIGVtcHJlc2EgcHVlZGUgb2ZlcnRhciBzdXMgcHJvZHVjdG9zIHkgc2VydmljaW9zIGRlIGVtcGFxdWUgZGUgYXV0b3BhcnRlczsgYWwgbWlzbW8gdGllbXBvIHF1ZSBheXVkYSBhIGNvbm9jZXIgYSBxdcOpIHRpcG8gZGUgY2xpZW50ZSBzZSBsZSBlc3RhcsOhIGludGVudGFuZG8gdmVuZGVyLCB5IGVuIGNhc28gZGUgcXVlIGxhIHJlbGFjacOzbiBkZSBuZWdvY2lvIHNlYSBleGl0b3NhLCBhIHF1w6kgcGHDrXNlcyBlbiB1biBmdXR1cm8gc2UgcHVlZGUgZXhwYW5kaXIuDQoNClRhbWJpw6luIFN0YXRpc3RhIG5vcyBheXVkYSBhIGNvcnJvYm9yYXIgcXVlIGVzdGEgaW5kdXN0cmlhIHNlZ3VpcsOhIGVuIGRlbWFuZGEgeWEgcXVlIHByb25vc3RpY28gcXXDqSBlbCBpbmdyZXNvIGRlIGVzdGEgaW5kdXN0cmlhIHBhc2Fyw6EgZGUgJDExLDI3IEJpbGxvbmVzIGRlIFVTRCBlbiAyMDIyIGEgJDEzLDk4IEJpbGxvbmVzIGRlIFVTRCBlbiBNw6l4aWNvLCBwb3IgbG8gcXVlIGxvcyBjbGllbnRlcyBhY3R1YWxlcyBkZSBlc3RhIGluZHVzdHJpYSBzZWd1aXLDoW4gbmVjZXNpdGFuZG8gcGFxdWV0ZXMgeSBjYWphcyBkZSBGT1JNLg0KDQoqVVNBKg0KDQpMYSBpbmR1c3RyaWEgZGUgYXV0b3BhcnRlcyBlbiBFc3RhZG9zIFVuaWRvcyBlc3TDoSBlc3RpbWFkYSBlbiAyMDUuODEgbWlsZXMgZGUgbWlsbG9uZXMgZGUgZMOzbGFyZXMsIHkgc2UgZXNwZXJhIHRlbmVyIHVuIGNyZWNpbWllbnRvIGRlIDQuMSUgZGVsIDIwMjMgYWwgMjAzMC4gRWwgbWF5b3IgbWVyY2FkbyBlbiBFc3RhZG9zIFVuaWRvcyBwYXJhIGxhcyBhdXRvcGFydGVzIHNvbiBsb3MgYWlyZXMgYWNvbmRpY2lvbmFkb3Mgc3VzcGVuc2lvbmVzIGludGVyaW9yZXMgdHJhbnNtaXNpb25lcyBzaXN0ZW1hcyBkZSBtYW5pb2Jyw7MgcmFkaW9zIHJhZGlhZG9yZXMgdGVjbm9sb2fDrWEgZnJlbm9zIGVudHJlIG90cm9zLg0KDQpPdHJhIGRlIGxhcyBtZWRpZGFzIHRlbmRlbmNpYXMgcXVlIHB1ZWRlbiBoYWNlciBxdWUgZWwgbWVyY2FkbyBjcmV6Y2EgZW4gRXN0YWRvcyBVbmlkb3MgZXMgZWwgaW5jcmVtZW50byBlbiBsYSB2ZW50YSBkZSB2ZWjDrWN1bG9zIGVsZWN0csOzbmljb3MgbG9zIGN1YWxlcyBuZWNlc2l0YW4gdmFyaWFzIHBhcnRlcyB5IGxhIHZlbnRhIGFudWFsIGRlIHZlaMOtY3Vsb3MgZWzDqWN0cmljb3MgZW4gRXN0YWRvcyBVbmlkb3MgcGFzw7MgMTcyLjEgbWlsZXMgZGUgdW5pZGFkZXMgZW4gMjAyMSBsbyBxdWUgaW5kaWNhIHVuYSBkZW1hbmRhIGFsdGEgcG9yIHBhcnRlcyB5IGNvbXBvbmVudGVzIHF1ZSBuZWNlc2l0YSBlbCBtZXJjYWRvIEVzdGFkb3MgVW5pZG9zIHRhbWJpw6luIGVzIGVsIG3DoXMgZ3JhbmRlIG1lcmNhZG8gZW4gZXN0ZSB0aXBvIGRlIHZlaMOtY3Vsb3MgY29uIG1hbnVmYWN0dXJlcmFzIGNvbW8gQ2FkaWxsYWMgR01DIFRlc2xhIENocnlzbGVyIGxhcyBjdWFsZXMgbGlkZXJhbiBlbCBtZXJjYWRvIGRlIHZlaMOtY3Vsb3MgZWxlY3Ryw7NuaWNvcy4NCg0KVGV4YXMgZW4gZWwgbWVyY2FkbyBkZSBhdXRvcGFydGVzIGFwYXJ0ZSBkZSBjZXJvIHVuIGFsYmVyZ3VlIGRlIGluZHVzdHJpYXMgbXV5IGdyYW5kZXMgdGFtYmnDqW4gdGllbmUgdW5hIG1lemNsYSBkZSBmYWJyaWNhbnRlcyB5IHByb3ZlZWRvcmVzIHF1ZSBheXVkYW4gYSBzdSBlY29ub23DrWEgYXV0b21vdHJpei4NCg0KIyMjIyAqKkdyw6FmaWNhcyBJbmR1c3RyaWEgQXV0b3BhcnRlcyoqDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpyZXN1bHRhZG9zIDwtIG14X2V4YXV0byAlPiUNCiAgZmlsdGVyKHllYXIgPj0gMjAyMCkgJT4lDQogIGdyb3VwX2J5KHllYXIsIFN0YXRlKSAlPiUNCiAgc3VtbWFyaXNlKHZlbnRhc190b3RhbGVzID0gc3VtKHRyYWRlX3ZhbHVlKSkNCiAgDQpnZ3Bsb3QocmVzdWx0YWRvcywgYWVzKHggPSBTdGF0ZSwgeSA9IHZlbnRhc190b3RhbGVzLCBmaWxsID0gZmFjdG9yKHllYXIpKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGxhYnModGl0bGUgPSAiVmVudGFzIFRvdGFsZXMgcG9yIEHDsW8geSBFc3RhZG8iLA0KICAgICAgIHggPSAiRXN0YWRvIiwNCiAgICAgICB5ID0gIlZlbnRhcyBUb3RhbGVzIiwNCiAgICAgICBmaWxsID0gIkHDsW8iKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSArIA0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OmNvbW1hKStzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtaV9wYWxldGEpDQpgYGANCg0KU2Ugb2JzZXJ2YSBsYSBwYXJ0aWNpcGFjacOzbiBkZSBsb3MgZGlzdGludG9zIGVzdGFkb3MgZGUgTcOpeGljbyBlbiBsYXMgZXhwb3J0YWNpb25lcyBkZSBhdXRvcGFydGVzLCBlc3RvIG5vcyBwZXJtaXRlIHZpc3VhbGl6YXIgYSBncmFuZGVzIHJhc2dvcyBlbiBxdWUgZXN0YWRvcyBlcyBlbiBkb25kZSBoYXkgbcOhcyBleHBvcnRhY2nDs24gZGUgYXV0b3BhcnRlcyBhIHBhw61zZXMgZXh0cmFuamVyb3MuIEVzdG9zIGhhbGxhemdvcyBub3MgcGVybWl0ZW4gdG9tYXIgZGVjaXNpb25lcyBlc3RyYXTDqWdpY2FzLCBjb21vIHBvciBlamVtcGxvIGVsZWdpciBhbGd1bmEgdWJpY2FjacOzbiBlc3RyYXTDqWdpY2EgcGFyYSB1biBhbG1hY8OpbiwgcHVudG8gZGUgZGlzdHJpYnVjacOzbiBvIGluY2x1c28gdW5hIHBsYW50YS4NCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmdncGxvdChBdXRvcGFydGVzLCBhZXMoeCA9IHllYXIpKSArDQogIGdlb21fYmFyKGFlcyh5ID0gaW1wb3J0c19mcm9tX1VTLCBmaWxsID0gIkltcG9ydGFjaW9uZXMgZGVzZGUgVVMiKSwgc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBnZW9tX2JhcihhZXMoeSA9IHRvdGFsX2ltcG9ydHMgLSBpbXBvcnRzX2Zyb21fVVMsIGZpbGwgPSAiVG90YWwgZGUgaW1wb3J0YWNpb25lcyIpLCBzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGxhYnModGl0bGUgPSAiSW1wb3J0YWNpb25lcyBkZSBBdXRvcGFydGVzIHBvciBBw7FvIiwgDQogICAgICAgc3VidGl0bGUgPSAiSW5kdXN0cmlhIEF1dG9tb3RyaXoiLA0KICAgICAgIGNhcHRpb24gPSAiTWV4aWNvIEF1dG9tb3RpdmUgSW5kdXN0cnkgLSBJbnRlcm5hdGlvbmFsIFRyYWRlIEFkbWluaXN0cmF0aW9uIC0gVVNEIEJpbGxpb25zIiwNCiAgICAgICB4ID0gIkHDsW8iLA0KICAgICAgIHkgPSAiSW1wb3J0YWNpb25lcyIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiSW1wb3J0YWNpb25lcyBkZXNkZSBVUyIgPSAiaXZvcnkyIiwgIlRvdGFsIGRlIGltcG9ydGFjaW9uZXMiID0gImRhcmtvcmFuZ2UiKSkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICBsYWJzKGZpbGwgPSAiVGlwbyBkZSBJbXBvcnRhY2nDs24iKQ0KYGBgDQoNClRhbnRvIGVsIHRvdGFsIGRlIGltcG9ydGFjaW9uZXMgY29tbyBsYXMgcXVlIHByb3ZpZW5lbiBkZSBVUyBoYW4gaW5jcmVtZW50YWRvIGNvbiBlbCBwYXNvIGRlIGxvcyBhw7Fvcywgc29sYW1lbnRlIGVuIGVsIDIwMjAgaHVibyB1bmEgZGlzbWludWNpw7NuIGRlYmlkbyBhIGxhIHBhbmRlbWlhIGRlIENvdmlkLTE5LCBwZXJvIGRlc3B1w6lzIHJlY3VwZXLDsyBzdSBjb21wb3J0YW1pZW50by4gQWRlbcOhcywgZXMgaW1wb3J0YW50ZSBtZW5jaW9uYXIgcXVlIGxhcyBpbXBvcnRhY2lvbmVzIGRlc2RlIFVTIHJlcHJlc2VudGFuIG3DoXMgZGVsIDUwJSBkZWwgdG90YWwgZGUgaW1wb3J0YWNpb25lcy4NCg0KIyMjIyAqKkluZHVzdHJpYSBDYXJ0w7NuKiogDQoNCipNw4lYSUNPKg0KDQpTZWfDum4gZGF0b3MgZGUgRXVyb21vbml0b3IgKDIwMjIpLCBlbCBtZXJjYWRvIGRlIHBhcGVsIGNvcnJ1Z2FkbywgY2FydMOzbiB5IGNvbnRlbmVkb3JlcyBlbiBNw6l4aWNvIG9jdXBhIGVsIHByaW1lciBsdWdhciBlbiBMYXRpbm9hbcOpcmljYSwgYWwgaWd1YWwgcXVlIHN1IGNyZWNpbWllbnRvIGRlbCB0YW1hw7FvIGRlIG1lcmNhZG8uIEVsIG7Dum1lcm8gZGUgZW1wcmVzYXMgcHJlc2VudGUgZW4gZXN0YSBpbmR1c3RyaWEgZW4gMjAyMSBmdWUgZGUgODk4NCB5IHZhIGVuIGNyZWNpbWllbnRvOyBhdW5xdWUgc2UgcG9kcsOtYSBkZWNpciBxdcOpIGxhIGluZHVzdHJpYSBlc3TDoSBmcmFnbWVudGFkYSB5YSBxdWUgc29sbyBsYXMgNSBlbXByZXNhcyBtw6FzIGdyYW5kZXMgcmVwcmVzZW50YW4gZWwgNy4yJSBkZWwgdmFsb3IgZGUgcHJvZHVjY2nDs24uIFBvciDDumx0aW1vLCBsYSByZW50YWJpbGlkYWQgZGUgbGEgaW5kdXN0cmlhIGNyZWNpw7MgeSBsb2dyw7MgbGxlZ2FyIGFsIDM0LjUlIGVuIDIwMjEsIHkgYXB1bnRhIGEgc2VndWlyIGNyZWNpZW5kby4gRXN0b3MgZGF0b3Mgbm9zIGluZGljYSBxdcOpIE3DqXhpY28gc2lndWUgc2llbmRvIHVuIHBhw61zIGltcG9ydGFudGUgZW4gZXNhIGluZHVzdHJpYSBlbiBMYXRpbm9hbcOpcmljYSwgcXXDqSB0aWVuZSBmdXR1cm8geSBwb3IgZW5kZSBGT1JNUyBwdWVkZSBzZWd1aXIgZW4gZWxsYSwgcGVybyB0YW1iacOpbiBlcyB1bmEgaW5kdXN0cmlhIGNvbXBldGl0aXZhIGRlYmlkbyBhIGxhIGdyYW4gZGl2ZXJzaWRhZCBkZSBlbXByZXNhczsgcG9yIGxvIHF1ZSBGT1JNUyBkZWJlcsOhIHNlZ3VpciBpbm5vdmFuZG8gcGFyYSBtYW50ZW5lcnNlIGNvbXBldGl0aXZhIGVuIGVsIG1lcmNhZG8uDQoNCkRlIGFjdWVyZG8gYSBkYXRvcyBkZWwgREVOVUUgMjAyMiBlbiBsYSBJbmR1c3RyaWEgZGUgbGEgRmFicmljYWNpw7NuIGRlIFByb2R1Y3RvcyBkZSBDYXJ0w7NuIHkgUGFwZWwgc2UgcmVnaXN0cmFyb24gdW4gdG90YWwgZGUgNiwwOTkgdW5pZGFkZXMgZWNvbsOzbWljYXM7IHNpZW5kbyBFc3RhZG8gZGUgTcOpeGljbyAoNDgxKSwgSmFsaXNjbyg0NjEpLCBWZXJhY3J1eiBkZSBJZ25hY2lvIGRlIGxhIExsYXZlICg0MTgpIHkgTnVldm8gTGXDs24gKDMyOSksIGxvcyBlc3RhZG9zIG3DoXMgcmVsZXZhbnRlcy4gRXN0YSBpbmZvcm1hY2nDs24gbm9zIHBlcm1pdGUgY29ub2NlciBlbiBkb25kZSBzZSBwb2Ryw61hbiBlbmNvbnRyYXIgbG9zIGNvbXBldGlkb3JlcyBtw6FzIGZ1ZXJ0ZXMgZGUgRk9STS4NCg0KTG9zIEVzdGFkb3MgcXXDqSBtw6FzIGhhbiByZWNpYmlkbyBJbnZlcnNpw7NuIEV4dHJhbmplcmEgRGlyZWN0YSBlbiAyMDIyLCBmdWVyb24gRXN0YWRvIGRlIE3DqXhpY28gKCQ1NC44IG1pbGxvbmVzIGRlIFVTRCksIEJhamEgQ2FsaWZvcm5pYSAoJDIxLjMgbWlsbG9uZXMgZGUgVVNEICkgeSBOdWV2byBMZcOzbiAoJDE5LjggTWlsbG9uZXMgZGUgVVNEKTsgZXN0YXMgaW52ZXJzaW9uZXMgcHJvdmllbmVuIGRlIDMgcHJpbmNpcGFsZXMgcGHDrXNlcyBzaWVuZG8gZXN0b3MgSXJsYW5kYSwgRXN0YWRvcyBVbmlkb3MgeSBOdWV2YSBaZWxhbmRhLg0KDQpFc3RhIGluZm9ybWFjacOzbiBlcyBpbXBvcnRhbnRlIHRlbmVybGEgeWEgcXVlIG5vcyBwZXJtaXRlIGNvbm9jZXIgZW4gcXVlIGVzdGFkb3Mgc2UgZXN0w6EgcHJvZHVjaWVuZG8gZSBpbnZpcnRpZW5kbyBtw6FzIGVuIGxhIEZhYnJpY2FjacOzbiBkZSBQcm9kdWN0b3MgZGUgQ2FydMOzbiB5IFBhcGVsIHkgcG9yIGVuZGUgcHVlZGVuIHNlciB6b25hcyBkZSBvcG9ydHVuaWRhZCBlbiBkb25kZSBsYSBlbXByZXNhIHB1ZWRlIGJ1c2NhciBpbnZlcnNvcmVzIHBhcmEgcG9kZXIgcG90ZW5jaWFyIGFsIGNyZWNpbWllbnRvIGRlIGxhIGVtcHJlc2EgeSBlbiBjYXNvIGRlIHF1w6kgbGFzIHJlbGFjaW9uZXMgc2VhbiBleGl0b3NhcyBhIHF1w6kgcGHDrXNlcyBlbiB1biBmdXR1cm8gcHVlZGVuIGV4cG9ydGFyIHN1cyBwcm9kdWN0b3MuDQoNCipVU0EqDQoNCkRlIGFjdWVyZG8gY29uIGRhdG9zIGRlIEV1cm9tb25pdG9yIEludGVybmF0aW9uYWwsIExhIHJlbnRhYmlsaWRhZCBkZSBsYSBpbmR1c3RyaWEgZGVudHJvIGRlIFVTQSBlc3TDoSBkaXNtaW51eWVuZG8sIGVzdG8gZXMgZGViaWRvIGEgcXVlIGxvcyBjb3N0ZXMgaGFuIGF1bWVudGFkbyB1biA4LjElIGVuIDIwMjE7IGxvIGN1YWwgZnVlIGNvbnNlY3VlbmNpYSBlbiBncmFuIG1lZGlkYSBwb3IgZWwgYXVtZW50byBlbiBjb3N0b3MgZGUgbGFzIHJlbGFjaW9uZXMgQjJCLg0KDQpDb25mb3JtZSBhIGxhcyBjb21wZXRlbmNpYXMgZGVudHJvIGRlIGxhIGluZHVzdHJpYSwgZW4gMjAyMSBzZSBwb3J0w7MgcXVlIDEzNjkgZW1wcmVzYXMgc2UgaW50ZWdyYXJvbiBhIGxhIGluZHVzdHJpYSBkZSBDb250ZW5lZG9yZXMgZGUgUGFwZWwgeSBDYXJ0w7NuIGNvcnJ1Z2Fkby4gRWwgc2VjdG9yIHNlIGVuY3VlbnRyYSBmcmFnbWVudGFkbyBkZWJpZG8gYSBxdWUgZWwgNDMuMiUgZGVsIHZhbG9yIGRlIHByb2R1Y2Npw7NuIGVuIDIwMjEgZnVlIG9jYXNpb25hZG8gcG9yIGxhcyA1IHByaW5jaXBhbGVzIGVtcHJlc2FzOyBsYSBlbXByZXNhIGNvbiBtYXlvciB2YWxvciB5IGZ1ZXJ6YSBlbiBlbCBtZXJjYWRvIGVzIFdlc3RSb2NrIENvLCBlbXByZXNhIHF1w6kgZ2VuZXLDsyBlbCAxMCUgZGVsIHZhbG9yIGRlIHByb2R1Y2Npw7NuIHRvdGFsIGRlIGxhIGluZHVzdHJpYSBlbiAyMDIxLiBFc3RhIEluZHVzdHJpYSBlc3TDoSBkb21pbmFkYSBwb3IgcHJvdmVlZG9yZXMgbmFjaW9uYWxlcyB5YSBxdcOpIGxhcyBpbXBvcnRhY2lvbmVzIHJlcHJlc2VudGFuIGVsIDUuOCUgZGVsIHRhbWHDsW8gdG90YWwgZGVsIG1lcmNhZG8gZW4gMjAyMS4NCg0KQWhvcmEgYmllbiwgZGUgYWN1ZXJkbyBjb24gbGEgZGVtYW5kYSBVU0EgdGllbmUgZWwgbWVyY2FkbyBtw6FzIGdyYW5kZSBkZW50cm8gZGUgbG9zIDIwIHByaW5jaXBhbGVzIHBhw61zZXMgZGVzYXJyb2xsYWRvcywgdGVuaWVuZG8gdW5hIGRlbWFuZGEgZW4gMjAyMSBlcXVpdmFsZW50ZSBhIDU2LjEgYmlsbG9uZXMgZGUgZMOzbGFyZXMuIENhYmUgcmVjYWxjYXIgcXVlIEIyQiBlcyBlbCBwcmluY2lwYWwgaW1wdWxzb3IgZGVsIG1lcmNhZG8sIHJlcHJlc2VudGFuZG8gZWwgOTIuNCUgZGUgbGEgZGVtYW5kYSBlbiAyMDIxLg0KDQpFc3RvcyBkYXRvcyBub3MgZGljZW4gcXXDqSBzaSBiaWVuIGxhIGNvbXBldGVuY2lhIGVzIGFsdGEgeSBkdXJhIGVuIEVzdGFkb3MgVW5pZG9zLCBhdW4gYXPDrSwgcHVlZGUgRk9STSBpbmdyZXNhciBhIGVzdGEgaW5kdXN0cmlhOyBzaSBsYSByZW50YWJpbGlkYWQgc2lndWUgZGlzbWludXllbmRvIHkgbG9zIGNvc3RlcyBhdW1lbnRhbmRvLCBsYXMgZW1wcmVzYXMgcXXDqSBvY3VwYW4gZXN0ZSBwcm9kdWN0byBjb21lbnphcsOhbiBhIGJ1c2NhciBvdHJvcyBwcm92ZWVkb3JlcyBjb24gcHJlY2lvcyBtw6FzIGFjY2VzaWJsZXMsIHBvciBsbyBxdWUgc2kgRk9STSBtYW50aWVuZSBzdXMgcHJlY2lvcyB1bmEgdmV6IGluc3RhbGFkb3MgZW4gU2FuIEFudG9uaW8gbyBzaWd1ZW4gZXhwb3J0YW5kbyBzdXMgcHJvZHVjdG9zLCBwb2Ryw61hbiB0ZW5lciDDqXhpdG8gYWwgZXhwYW5kaXJzZSBhIFVTQS4NCg0KIyMjIyAqKkdyw6FmaWNhcyBJbmR1c3RyaWEgZGUgQ2FydMOzbioqIA0KDQoqKkltcG9ydGFjacOzbiBkZSBDYWphcyoqDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQoNCklDQjI8LUltcENhcnRvbkJveCU+JWFycmFuZ2UoZGVzYyhUcmFkZS5WYWx1ZSkpDQpWaWV3KElDQjIpDQpJQ0IzPC1JQ0IyJT4lZmlsdGVyKFRyYWRlLlZhbHVlPj0xMjM5ODk2NjQpDQpWaWV3KElDQjMpDQoNCmdncGxvdChJQ0IzLCBhZXMoeD1UcmFkZS5WYWx1ZSwgeT1Db3VudHJ5LCBmaWxsPUNvdW50cnkpKSArIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKyB4bGFiKCIiKSArIGxhYnMoeD0iVHJhZGUgVmFsdWUgZW4gMjAyMSIsdGl0bGUgPSAiVG9wIDIwIHBhw61zZXMgaW1wb3J0YWRvcmVzIGRlIGNhamFzIGRlIGNhcnTDs24iLCBzdWJ0aXRsZSA9ICJTZWfDum4gc3UgVHJhZGUgVmFsdWUgZW4gZWwgYcOxbyAyMDIxIikgKyBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzPWZ1bmN0aW9uKG4pe2Zvcm1hdChuLCBzY2llbnRpZmljID0gRkFMU0UpfSkgKyB0aGVtZV9taW5pbWFsKCkgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtaV9wYWxldGEpDQpgYGANCg0KRXN0YSBncsOhZmljYSBub3MgcGVybWl0ZSB2aXN1YWxpemFyIHF1ZSBwYcOtc2VzIGltcG9ydGFuIG3DoXMgeSBwb3IgZW5kZSBzZSBwdWVkZSBjb25vY2VyIGEgcXVlIHBhw61zZXMgc2UgcHVlZGUgZXhwYW5kaXIgRk9STSBlbiB1biBmdXR1cm8gbyBlbiBxdcOpIHBhw61zIHB1ZWRlIGNvbnNlZ3VpciBudWV2YSBjbGllbnRlbGEgaW50ZXJuYWNpb25hbC4gDQoNCg0KKipFeHBvcnRhY2nDs24gZGUgQ2FqYXMqKg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KRUNCMjwtRXhwQ2FydG9uQm94JT4lYXJyYW5nZShkZXNjKFRyYWRlLlZhbHVlKSkNClZpZXcoRUNCMikNCkVDQjM8LUVDQjIlPiVmaWx0ZXIoVHJhZGUuVmFsdWU+PTEwMTM3NTM3MikNClZpZXcoRUNCMykNCg0KZ2dwbG90KEVDQjMsIGFlcyh4PVRyYWRlLlZhbHVlLCB5PUNvdW50cnksIGZpbGw9Q291bnRyeSkpICsgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArIHhsYWIoIiIpICsgbGFicyh4PSJUcmFkZSBWYWx1ZSBlbiAyMDIxIix0aXRsZSA9ICJUb3AgMjAgcGHDrXNlcyBleHBvcnRhZG9yZXMgZGUgY2FqYXMgZGUgY2FydMOzbiIsIHN1YnRpdGxlID0gIlNlZ8O6biBzdSBUcmFkZSBWYWx1ZSBlbiBlbCBhw7FvIDIwMjEiKSArIHNjYWxlX3hfY29udGludW91cyhsYWJlbHM9ZnVuY3Rpb24obil7Zm9ybWF0KG4sIHNjaWVudGlmaWMgPSBGQUxTRSl9KSsgdGhlbWVfbWluaW1hbCgpICsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWlfcGFsZXRhKQ0KYGBgDQoNCkVzdGEgZ3LDoWZpY2Egbm9zIHBlcm1pdGUgdmlzdWFsaXphciBxdWUgcGHDrXNlcyBzb24gbG9zIHF1ZSBtw6FzIGV4cG9ydGFuIGNhamFzIHkgZW1wYXF1ZXMgZGUgY2FydMOzbiwgcG9yIGVuZGUgc2UgcHVlZGUgc2FiZXIgcXVlIHBhw61zZXMgcHVlZGVuIHRlbmVyIGVtcHJlc2FzIHF1ZSBwdWVkYW4gc2VyIHVuYSBhbWVuYXphIHBhcmEgRk9STSwgYWRlbcOhcyBzZSBjb25vY2UgcXVlIHBhw61zZXMgbm8gcHVlZGVuIHNlciB0YW4gY29udmVuaWVudGVzIHBhcmEgaGFjZXIgbmVnb2Npb3MsIGRlYmlkbyBhIGxhIGFsdGEgY29tcGV0ZW5jaWEuDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQp2aWV3KHZlbnRhc19jYXJ0b24pDQpnZ3Bsb3QodmVudGFzX2NhcnRvbiwgYWVzKHggPSBNZXMsIHkgPSBDYXJ0b24pKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gImRhcmtvcmFuZ2UiKSArDQogIGxhYnModGl0bGUgPSAiVmVudGFzIGRlIENhcnRvbiBwb3IgTWVzIiwgc3VidGl0bGUgPSAiMjAyMiIsIHggPSAiTWVzIiwgeSA9ICJWZW50YXMgTURQIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDIwLCBoanVzdCA9IDEpKSArIHNjYWxlX3hfZGlzY3JldGUobGltaXRzID0gdmVudGFzX2NhcnRvbiRNZXMpDQpgYGANCg0KU2UgcHVlZGUgb2JzZXJ2YXIgcXVlIGxhcyB2ZW50YXMgZGUgQ2FydMOzbiBkdXJhbnRlIGVsIDIwMjIgaW5jcmVtZW50YXJvbiBhbCBmaW5hbCBkZSBjYWRhIHRyaW1lc3RyZSwgZXMgZGVjaXIsIGVuIGxvcyBtZXNlcyBkZSBNYXJ6bywgSnVuaW8geSBTZXB0aWVtYnJlLCBzaW4gZW1iYXJnbywgZWwgbWVzIGRlIEFnb3N0byB0dXZvIGluY3JlbWVudG9zIGNvbnNpZGVyYWJsZXMgY29uIHJlc3BlY3RvIGFsIG1lcyBhbnRlcmlvci4NCg0KIyMjICoqRk9EQSBjcnV6YWRvKioNCg0KIVtdKEM6XFxVc2Vyc1xcY2FcXERlc2t0b3BcXFIgU3R1ZGlvXFxEYXRvcyBFdmlkZW5jaWEgMVxcRk9EQS5wbmcpDQoNCiMjIyAqKlBFU1RMRSoqDQohW10oQzpcXFVzZXJzXFxjYVxcRGVza3RvcFxcUiBTdHVkaW9cXERhdG9zIEV2aWRlbmNpYSAxXFxQRVNUTEUuanBlZykNCg0KIyMjIyAqKkVTVFJBVEVHSUFTKioNCg0KMS4gQW5hbGl6YXIgbGFzIHRlbmRlbmNpYXMgZGUgY29uc3VtbyBpbnRlcm5hY2lvbmFsIHBhcmEgcG9kZXIgaW5jcmVtZW50YXIgbGEgcHJvZHVjY2nDs24gZGUgY2FydMOzbiByZXRvcm5hYmxlICB5IGFzw60gbWluaW1pemFyIGNvc3RvcyB5IGZhY3RvcmVzIGVjb2zDs2dpY29zIGRlIHJpZXNnbyBjb21vIGxhIHN1cGVyZmljaWUgZm9yZXN0YWwgcGVyZGlkYS4NCg0KMi4gQXV0b21hdGl6YXIgbG9zIHByb2Nlc29zIGRlIGVsYWJvcmFjacOzbiBkZSBsb3MgZW1wYXF1ZXMgYSB0cmF2w6lzIGRlIGxhIGlubm92YWNpw7NuIHRlY25vbMOzZ2ljYSBoYXLDoSBxdWUgc2UgYWNlbGVyZW4gbG9zIHByb2Nlc29zIHkgc2UgcmVkdXpjYW4gY29zdG9zLiBFc3RvIGRhcsOtYSBsYSBwb3NpYmlsaWRhZCBkZSBhYmFzdGVjZXIgYSBsYSBkZW1hbmRhIGRlIGZvcm1hIG3DoXMgcsOhcGlkYS4gDQoNCjMuIFVuYSBkZSBsYXMgdGVuZGVuY2lhcyBlbiBsYSBpbmR1c3RyaWEgZGVsIGVtYmFsYWplIGVzIGxhIHByZW9jdXBhY2nDs24gcG9yIGVsIHBhY2thZ2luZyBzb3N0ZW5pYmxlLCBwb3IgbG8gdGFudG8sIEZPUk0gcG9kcsOtYSBhcG9zdGFyIHBvciBtYXRlcmlhbGVzIGFsdGVybmF0aXZvcyBxdWUgbGUgYXl1ZGVuIGEgYXVtZW50YXIgc3UgJSBkZSBwcm9kdWNjacOzbiBkZSByZXRvcm5hYmxlLCBhZGVtw6FzIGRlIGxhIGludGVncmFjacOzbiBkZSBwcsOhY3RpY2FzIGRlIGRpc2XDsW8geSBwcm9kdWNjacOzbiBtw6FzIGludGVyYWN0aXZhcyB5IHNvc3RlbmlibGVzLCB5IGZvbWVudGFyIGVsIHJlY2ljbGFqZSBhdmFuemFkby4NCg0KIyMgKioqUEFSVEUgSUkgLSBBTkFMSVNJUyBFWFBMT1JBVE9SSU8gREUgREFUT1MqKiogDQoNCg0KIVtdKEM6XFxVc2Vyc1xcY2FcXERlc2t0b3BcXFIgU3R1ZGlvXFxEYXRvcyBFdmlkZW5jaWEgMVxcRURBLnBuZyl7d2lkdGg9ODAlfQ0KDQpVbiBFREEgKEV4cGxvcmF0b3J5IERhdGEgQW5hbHlzaXMpIGVzIHVuIHByb2Nlc28gY3J1Y2lhbCBlbiBsYSBjaWVuY2lhIGRlIGRhdG9zIHF1ZSBpbXBsaWNhIGV4YW1pbmFyIHkgdmlzdWFsaXphciB1biBjb25qdW50byBkZSBkYXRvcyBwYXJhIGNvbXByZW5kZXIgc3VzIGNhcmFjdGVyw61zdGljYXMsIHBhdHJvbmVzIHkgZXN0cnVjdHVyYS4gDQoNCkVsIG9iamV0aXZvIHByaW5jaXBhbCBkZWwgRURBIGVzIG9idGVuZXIgdW5hIHZpc2nDs24gaW5pY2lhbCBkZSBsb3MgZGF0b3MgYW50ZXMgZGUgcmVhbGl6YXIgYW7DoWxpc2lzIG3DoXMgYXZhbnphZG9zIG8gbW9kZWxhZG8gZXN0YWTDrXN0aWNvLiBEdXJhbnRlIGVsIEVEQSwgc2UgcHVlZGVuIHJlYWxpemFyIHRhcmVhcyBjb21vIGxhIGlkZW50aWZpY2FjacOzbiBkZSB2YWxvcmVzIGF0w61waWNvcywgbGEgZXhwbG9yYWNpw7NuIGRlIGRpc3RyaWJ1Y2lvbmVzIGRlIGRhdG9zLCBsYSBiw7pzcXVlZGEgZGUgY29ycmVsYWNpb25lcyBlbnRyZSB2YXJpYWJsZXMgeSBsYSBnZW5lcmFjacOzbiBkZSBncsOhZmljb3MgaW5mb3JtYXRpdm9zLiBFc3RlIHByb2Nlc28gYXl1ZGEgYSBsb3MgY2llbnTDrWZpY29zIGRlIGRhdG9zIGEgdG9tYXIgZGVjaXNpb25lcyBmdW5kYW1lbnRhZGFzIHNvYnJlIGPDs21vIGFib3JkYXIgdW4gY29uanVudG8gZGUgZGF0b3MgeSBxdcOpIHTDqWNuaWNhcyBhbmFsw610aWNhcyBzb24gYWRlY3VhZGFzIHBhcmEgb2J0ZW5lciBjb25vY2ltaWVudG9zIHZhbGlvc29zLg0KDQojIyMgKipTSVRVQUNJw5NOIFBST0JMRU1BIDIqKg0KDQpFeHBsb3JhciwgZGVmaW5pciwgeSBkZXNjcmliaXIgY3XDoWxlcyBzb24gbG9zIHByaW5jaXBhbGVzIGZhY3RvcmVzIGRlbCBjbGltYSBvcmdhbml6YWNpb25hbCBkZSBGT1JNIHF1ZSBwcm9waWNpYW4gbGEgc2F0aXNmYWNjacOzbiB5L28gbm8gc2F0aXNmYWNjacOzbiBkZSB0cmFiYWphciBlbiBkaWNoYSBlbXByZXNhLg0KDQojIyMgKipQUkVHVU5UQVMgREUgQU7DgUxJU0lTKioNCg0KMS4gwr9FbCBkYXJsZSBwcmlvcmlkYWQgYSBsYXMgbXVqZXJlcyBlbiBsYSBjb250cmF0YWNpw7NuIGRlbCBwdWVzdG8gZGUgQXl1ZGFudGUgR2VuZXJhbCwgcHVlZGUgcmVkdWNpciBsYSByb3RhY2nDs24gZGUgcGVyc29uYWwgeSBhdW1lbnRhciBsYSBwcm9kdWN0aXZpZGFkIGRlIGxhIGVtcHJlc2E/DQoNCjIuIMK/RWwgZXN0YWRvIGNpdmlsIHkgZWwgZ8OpbmVybyBzb24gZmFjdG9yZXMgcXVlIGFmZWN0YW4gbGEgcm90YWNpw7NuIGRlIGVtcGxlYWRvcz8NCg0KMy4gwr9FbiBxdcOpIGVzdGFjacOzbiBkZWwgYcOxbyB0aWVuZGVuIGEgc3VjZWRlciBtw6FzIGJhamFzIGRlIHBlcnNvbmFsPyDCv0VsIGNsaW1hIHNlcsOhIHVuIGZhY3RvciBkZXRlcm1pbmFudGUgZW4gbGFzIGJhamFzIGRlIHBlcnNvbmFsPw0KDQo0LiDCv0xhIGVkYWQgZGVsIHRyYWJhamFkb3IgcHVlZGUgc2VyIHVuIGRldGVybWluYW50ZSBkZSBwb3IgcXXDqSBzZSBkYW4gZGUgYmFqYSwgbyBoYXkgY2llcnRhIGVkYWQgZW4gZG9uZGUgZXMgbWVub3MgcHJvYmFibGUgcXVlIHNlIGRlIHVuYSBiYWphPw0KDQo1LiDCv0xhIGRpc3RhbmNpYSBnZW9ncsOhZmljYSBkZXNlbXBlw7FhIHVuIHBhcGVsIHNpZ25pZmljYXRpdm8gZW4gbGEgZGV0ZXJtaW5hY2nDs24gZGVsIGVzdGF0dXMgbGFib3JhbCBkZSBsb3MgZW1wbGVhZG9zPyAoQWN0aXZvIG8gSW5hY3Rpdm8pDQoNCg0KIyMjICoqRElTRcORTywgT1JHQU5JWkFDScOTTiBZIExJTVBJRVpBIERFIERBVE9TKioNCg0KIyMjIyBDYXJnYW5kbyBsYXMgYmFzZXMgZGUgZGF0b3MNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpkYXRvc18yMDIyIDwtIHJlYWQuY3N2KCJDOlxcVXNlcnNcXGNhXFxEZXNrdG9wXFxSIFN0dWRpb1xcRGF0b3MgRXZpZGVuY2lhIDFcXEJfZm9ybV9yaF9iYWphc19kYXRvc18yMDIyLmNzdiIpDQpkYXRvc18yMDIzIDwtIHJlYWQuY3N2KCJDOlxcVXNlcnNcXGNhXFxEZXNrdG9wXFxSIFN0dWRpb1xcRGF0b3MgRXZpZGVuY2lhIDFcXEJfQkREX0ZPUk1fQkFKQVNfMjAyMy5jc3YiKQ0KZGF0b3NfYWN0dWFsZXMgPC0gcmVhZC5jc3YoIkM6XFxVc2Vyc1xcY2FcXERlc2t0b3BcXFIgU3R1ZGlvXFxEYXRvcyBFdmlkZW5jaWEgMVxcZm9ybV9yaF9kYXRvcyAoMSkuY3N2IikNCmRhdG9zXzIwMjMgPC0gZGF0b3NfMjAyM1tjb21wbGV0ZS5jYXNlcyhkYXRvc18yMDIzKSwgXQ0KDQpgYGANCg0KIyMjIyBVbmnDs24gZGUgbGFzIGJhc2VzIGRlIGRhdG9zDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZGZfYmFqYXMgPC0gYmluZF9yb3dzKGRhdG9zXzIwMjIsIGRhdG9zXzIwMjMpDQpkZl9iYWphcyA8LSBhcy5kYXRhLmZyYW1lKGxhcHBseShkZl9iYWphcywgdG91cHBlcikpDQpgYGANCg0KIyMjIyBMaW1waWV6YSBkZSBsYXMgYmFzZXMgZGUgZGF0b3MNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0KZGZfYmFqYXMgPC0gZGZfYmFqYXMgJT4lDQogIG11dGF0ZShFU1RBRE8uQ0lWSUwgPSBpZmVsc2UoRVNUQURPLkNJVklMICVpbiUgYygiU09MVEVSSUEiLCAiU09MVEVSQSIpLCAiU09MVEVSTyIsIEVTVEFETy5DSVZJTCkpICU+JQ0KICBtdXRhdGUoRVNUQURPLkNJVklMID0gaWZlbHNlKEVTVEFETy5DSVZJTCAlaW4lIGMoIkNBU0FETyIsICJDQVNBREEiLCAiTUFUUklPTU9OSU8iKSwgIk1BVFJJTU9OSU8iLCBFU1RBRE8uQ0lWSUwpKQ0KDQpkYXRvc19hY3R1YWxlcyA8LSBkYXRvc19hY3R1YWxlcyAlPiUNCiAgbXV0YXRlKEVTVEFETy5DSVZJTCA9IGlmZWxzZShFU1RBRE8uQ0lWSUwgJWluJSBjKCJTT0xURVJJQSIsICJTT0xURVJBIiksICJTT0xURVJPIiwgRVNUQURPLkNJVklMKSkgJT4lDQogIG11dGF0ZShFU1RBRE8uQ0lWSUwgPSBpZmVsc2UoRVNUQURPLkNJVklMICVpbiUgYygiQ0FTQURPIiwgIkNBU0FEQSIsICJNQVRSSU9NT05JTyIpLCAiTUFUUklNT05JTyIsIEVTVEFETy5DSVZJTCkpDQoNCmBgYA0KDQpOdWV2YSBjb2x1bW5hIHF1ZSBkYSBhIGNvbm9jZXIgbGEgZWRhZCBkZWwgcGVyc29uYWwuDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQpkZl9iYWphcyRGRUNIQS5ERS5OQUNJTUlFTlRPIDwtIGRteShkZl9iYWphcyRGRUNIQS5ERS5OQUNJTUlFTlRPKQ0KZmVjaGFfYWN0dWFsIDwtIFN5cy5EYXRlKCkNCmRmX2JhamFzJEVEQUQgPC0gcm91bmQoYXMubnVtZXJpYyhkaWZmdGltZShmZWNoYV9hY3R1YWwsIGRmX2JhamFzJEZFQ0hBLkRFLk5BQ0lNSUVOVE8sIHVuaXRzID0gImRheXMiKSAvIDM2NS4yNSkpDQoNCmRhdG9zX2FjdHVhbGVzJEZFQ0hBLkRFLk5BQ0lNSUVOVE8gPC0gbWR5KGRhdG9zX2FjdHVhbGVzJEZFQ0hBLkRFLk5BQ0lNSUVOVE8pDQpkYXRvc19hY3R1YWxlcyRFREFEIDwtIHJvdW5kKGFzLm51bWVyaWMoZGlmZnRpbWUoZmVjaGFfYWN0dWFsLCBkYXRvc19hY3R1YWxlcyRGRUNIQS5ERS5OQUNJTUlFTlRPLCB1bml0cyA9ICJkYXlzIikgLyAzNjUuMjUpKQ0KDQpgYGANCg0KTnVldmEgY29sdW1uYSBxdWUgZGEgYSBjb25vY2VyIGxvcyBkw61hcyB0cmFiYWphZG9zIHBvciBlbXBsZWFkby4NCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpkZl9iYWphcyRGRUNIQS5ERS5BTFRBIDwtIGRteShkZl9iYWphcyRGRUNIQS5ERS5BTFRBKQ0KZGZfYmFqYXMkQkFKQSA8LSBkbXkoZGZfYmFqYXMkQkFKQSkNCmRmX2JhamFzJERJQVMuTEFCT1JBRE9TLkNBTENVTEFETyA8LSBhcy5udW1lcmljKGRpZmZ0aW1lKGRmX2JhamFzJEJBSkEsIGRmX2JhamFzJEZFQ0hBLkRFLkFMVEEsIHVuaXRzID0gImRheXMiKSkNCg0KZGF0b3NfYWN0dWFsZXMkRkVDSEEuREUuQUxUQSA8LSBtZHkoZGF0b3NfYWN0dWFsZXMkRkVDSEEuREUuQUxUQSkNCmRhdG9zX2FjdHVhbGVzJEJBSkEgPC0gZmVjaGFfYWN0dWFsDQpkYXRvc19hY3R1YWxlcyRESUFTLkxBQk9SQURPUy5DQUxDVUxBRE8gPC0gYXMubnVtZXJpYyhkaWZmdGltZShkYXRvc19hY3R1YWxlcyRCQUpBLCBkYXRvc19hY3R1YWxlcyRGRUNIQS5ERS5BTFRBLCB1bml0cyA9ICJkYXlzIikpDQpgYGANCg0KTnVldmEgY29sdW1uYSBxdWUgZGEgYSBjb25vY2VyIGVsIGRvbWljaWxpbyBwb3IgZW1wbGVhZG8uDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZGZfYmFqYXMkRElSRUNDSU9OIDwtIHBhc3RlKGRmX2JhamFzJENBTExFLCBkZl9iYWphcyROVU1FUk8uSU5URVJOTywgZGZfYmFqYXMkQ09MT05JQSwgZGZfYmFqYXMkTVVOSUNJUElPLCBkZl9iYWphcyRFU1RBRE8sIHNlcCA9ICIsICIpDQoNCmRhdG9zX2FjdHVhbGVzJERJUkVDQ0lPTiA8LSBwYXN0ZShkYXRvc19hY3R1YWxlcyRDQUxMRSwgZGF0b3NfYWN0dWFsZXMkTlVNRVJPLklOVEVSTk8sIGRhdG9zX2FjdHVhbGVzJENPTE9OSUEsIGRhdG9zX2FjdHVhbGVzJE1VTklDSVBJTywgZGF0b3NfYWN0dWFsZXMkRVNUQURPLCBzZXAgPSAiLCAiKQ0KYGBgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpkYXRvc19hY3R1YWxlczwtIGFzLmRhdGEuZnJhbWUobGFwcGx5KGRhdG9zX2FjdHVhbGVzLCB0b3VwcGVyKSkNCmBgYA0KDQojIyMjIE9yZ2FuaXphY2nDs24gZGUgbG9zIGRhdG9zDQoNCkNyZWFjacOzbiBkZSB1biBEYXRhIEZyYW1lIGNvbnNvbGlkYWRvDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpkYXRvc19hY3R1YWxlcyRCQUpBIDwtIGFzLkRhdGUoZGF0b3NfYWN0dWFsZXMkQkFKQSkNCmRmX2JhamFzJEJBSkEgPC0gYXMuRGF0ZShkZl9iYWphcyRCQUpBKQ0KZGF0b3NfYWN0dWFsZXMkRkVDSEEuREUuTkFDSU1JRU5UTyA8LSBhcy5EYXRlKGRhdG9zX2FjdHVhbGVzJEZFQ0hBLkRFLk5BQ0lNSUVOVE8pICAgDQpkYXRvc19hY3R1YWxlcyRGRUNIQS5ERS5BTFRBIDwtIGFzLkRhdGUoZGF0b3NfYWN0dWFsZXMkRkVDSEEuREUuQUxUQSkgDQpkYXRvc19hY3R1YWxlcyRTQUxBUklPIDwtIGFzLm51bWVyaWMoZGF0b3NfYWN0dWFsZXMkU0FMQVJJTykNCmRmX2JhamFzJFNBTEFSSU8gPC0gYXMubnVtZXJpYyhkZl9iYWphcyRTQUxBUklPKQ0KZGZfYmFqYXMkRURBRCA8LSBhcy5udW1lcmljKGRmX2JhamFzJEVEQUQpDQpkYXRvc19hY3R1YWxlcyRFREFEIDwtIGFzLm51bWVyaWMoZGF0b3NfYWN0dWFsZXMkRURBRCkgDQpkYXRvc19hY3R1YWxlcyRESUFTLkxBQk9SQURPUy5DQUxDVUxBRE8gPC0gYXMubnVtZXJpYyhkYXRvc19hY3R1YWxlcyRESUFTLkxBQk9SQURPUy5DQUxDVUxBRE8pDQpkZl9iYWphcyRESUFTLkxBQk9SQURPUy5DQUxDVUxBRE8gPC0gYXMubnVtZXJpYyhkZl9iYWphcyRESUFTLkxBQk9SQURPUy5DQUxDVUxBRE8pDQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmRmX2NvbnNvbGlkYWRvIDwtIGJpbmRfcm93cyhkZl9iYWphcywgZGF0b3NfYWN0dWFsZXMpDQpgYGANCg0KTnVldmEgY29sdW1uYSwgIipQVUVTVE9fIE4qIi4NCkV4aXN0ZSB1bmEgc2VyaWUgZGUgbm9tZW5jYWx0dXJhcy9hYnJldmlhY2lvbmVzIHJlbGFjaW9uYWRhcyBhIGxhIGNvbHVtbmEgKlB1ZXN0byosIGVzdG8gY29uIGxhIGZpbmFsaWRhZCBkZSBtYW5lamFyIGRlIG1hbmVyYSBtw6FzIHNlbmNpbGxhIGxvcyBjw7NkaWdvcyB5IHBlcm1pdGlyIHF1ZSBncsOhZmljYXMgc2UgdmlzdWFsaWNlbiBtZWpvci4NCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmRmX2NvbnNvbGlkYWRvIDwtIGRmX2NvbnNvbGlkYWRvICU+JQ0KICBtdXRhdGUoUFVFU1RPLk4gPSBjYXNlX3doZW4oDQogICAgUFVFU1RPICVpbiUgYygiQVlVREFOVEUgR0VORVJBTCIsICJBWS5HRU5FUkFMIikgfiAiQS5HLiIsDQogICAgUFVFU1RPICVpbiUgYygiR0VTVE9SIikgfiAiR1QuIiwNCiAgICBQVUVTVE8gJWluJSBjKCJTT0xEQURPUiIsICJBWVVEQU5URSBTT0xEQURPUiIpIH4gIlNEUi4iLA0KICAgIFBVRVNUTyAlaW4lIGMoIkFZVURBTlRFIERFIEVNQkFSUVVFUyIpIH4gIkEuRC5FLiIsDQogICAgUFVFU1RPICVpbiUgYygiQ0hPRkVSIEdFU1RPUiIsICJDSE9GRVIiKSB+ICJDSE8uIiwNCiAgICBQVUVTVE8gJWluJSBjKCJDT1NUVVJFUkEiLCAiQ09TVFVSRVJPIiwgIkNPU1RVUkEiKSB+ICJDT1MuIiwNCiAgICBQVUVTVE8gJWluJSBjKCJFTkZFUk1FUkEiKSB+ICJFTi4iLA0KICAgIFBVRVNUTyAlaW4lIGMoIkdVQVJESUEgREUgU0VHVVJJREFEIiwgIkdVQVJESUEgU0VHVVJJREFEIikgfiAiRy5ELlMuIiwNCiAgICBQVUVTVE8gJWluJSBjKCJJTlNQRUNUT1IgREUgQ0FMSURBRCIsICJDQUxJREFEIikgfiAiSS5DLiIsDQogICAgUFVFU1RPICVpbiUgYygiTElNUElFWkEiKSB+ICJMUFouIiwNCiAgICBQVUVTVE8gJWluJSBjKCJNQVRFUklBTElTVEEiKSB+ICJNQVQuIiwNCiAgICBQVUVTVE8gJWluJSBjKCJNT05UQUNBUkdJU1RBIikgfiAiTUMuIiwNCiAgICBQVUVTVE8gJWluJSBjKCJQSU5UT1IiLCAiQVlVREFOVEUgUElOVE9SIikgfiAiUEkuIiwNCiAgICBQVUVTVE8gJWluJSBjKCJSRVNJREVOVEUiLCAiUkVTSURFTlRFIFlBTkZFTkcgQ0lFTkVHQSIpIH4gIlJEVC4iLA0KICAgIFBVRVNUTyAlaW4lIGMoIk1BTlRFTklNSUVOVE8iKSB+ICJNVE8uIiwNCiAgICBQVUVTVE8gJWluJSBjKCJBTkFMSVNUQSBERSBOT01JTkFTIikgfiAiQS5ELk4uIiwNCiAgICBQVUVTVE8gJWluJSBjKCJDVVNUT01FUiBTRVJWSUNFIElORiIpIH4gIkMuUy5JLiIsDQogICAgUFVFU1RPICVpbiUgYygiQ09SVEFET1IiKSB+ICJDT1IuIiwNCiAgICBQVUVTVE8gJWluJSBjKCJESVNFw5FPIikgfiAiRElTLiIsDQogICAgUFVFU1RPICVpbiUgYygiRVhURVJOTyIpIH4gIkVYLiIsDQogICAgUFVFU1RPICVpbiUgYygiRkFDVFVSQUNJT04iKSB+ICJGQUMuIiwNCiAgICBQVUVTVE8gJWluJSBjKCJKRUZFIERFIFNFR1VSSURBRCBFIEhJR0lFTkUiKSB+ICJKLlMuSC4iLA0KICAgIFBVRVNUTyAlaW4lIGMoIkxJREVSIikgfiAiTEkuIiwNCiAgICBQVUVTVE8gJWluJSBjKCJNQVJDQURPUkEiKSB+ICJNQVIuIiwNCiAgICBQVUVTVE8gJWluJSBjKCJPUEVSQURPUiIpIH4gIk9QLiIsDQogICAgUFVFU1RPICVpbiUgYygiUkVDSUJPIikgfiAiUkJPLiIsDQogICAgUFVFU1RPICVpbiUgYygiU0VSVklDSU8gQUwgQ0xJRU5URSIpIH4gIlMuQy4iLA0KICAgIFBVRVNUTyAlaW4lIGMoIlNVUEVSVklTT1IiKSB+ICJTVVAuIiwNCiAgICBUUlVFIH4gUFVFU1RPDQogICkpDQpgYGANCg0KIyMjIyBHbG9zYXJpbyBjb3JyZXNwb25kaWVudGUgYSBsYSBjb2x1bW5hDQoNCiFbXShDOlxcVXNlcnNcXGNhXFxEZXNrdG9wXFxSIFN0dWRpb1xcRGF0b3MgRXZpZGVuY2lhIDFcXE5vbWVuY2xhdHVyYSBQdWVzdG9zLnBuZykNCg0KIyMjICoqQU7DgUxJU0lTIEVYUExPUkFUT1JJTyBERSBEQVRPUyoqDQoNCiMjIyMgKipQUkVHVU5UQSAxKioNCg0KKsK/RWwgZGFybGUgcHJpb3JpZGFkIGEgbGFzIG11amVyZXMgZW4gbGEgY3Vlc3Rpw7NuIGRlIGNvbnRyYXRhY2nDs24gZGUgcGVyc29uYWwgZW4gZWwgcHVlc3RvIGRlIEF5dWRhbnRlIEdlbmVyYWwsIHB1ZWRvIHJlZHVjaXIgbGEgcm90YWNpw7NuIGRlIHBlcnNvbmFsIHkgYXVtZW50YXIgbGEgcHJvZHVjdGl2aWRhZCBkZSBsYSBlbXByZXNhPyoNCg0KQSBjb250aW51YWNpw7NuIHNlIG11ZXN0cmFuIGxvcyBwcmltZXJvcyA2IHJlbmdsb25lcyBkZSBsYSAgYmFzZSBkZSBkYXRvcyANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0KZGF0YVJIPC1yZWFkLmNzdigiQzpcXFVzZXJzXFxjYVxcRGVza3RvcFxcUiBTdHVkaW9cXERhdG9zIEV2aWRlbmNpYSAxXFxDRk9STUYuY3N2IikNCg0KaGVhZChkYXRhUkgpDQpgYGANCg0KU2UgdG9tw7MgbGEgYmFzZSBkZSBkYXRvcyAiQkREX0ZPUk1fQkFKQVNfMjAyMyIgcGFyYSBwb2RlciBjb25vY2VyIHNvYnJlIGxhcyBkaWZlcmVudGVzIHJhem9uZXMgZGVsIHBvcnF1ZSBsYSBnZW50ZSBzYWxlIGRlIGxhIGVtcHJlc2EsIHBhcmEgZXN0byBzZSB1c2Fyb24gYXJndW1lbnRvcy9mdW5pY29uZXMgY29tbyBncm91cF9ieSxjb3VudCxtdXRhdGUsYXJyYW5nZSB5IHJvdW5kOyBwYXJhIGNvbm9jZXIgcG9yY2VudGFqZXMgeSBjb21vIHNlIHJlbGFjaW9uYW4gbG9zIGRhdG9zDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpyaF9iYTwtcmVhZC5jc3YoIkM6XFxVc2Vyc1xcY2FcXERlc2t0b3BcXFIgU3R1ZGlvXFxEYXRvcyBFdmlkZW5jaWEgMVxcQkREX0ZPUk1fQkFKQVNfMjAyMy5jc3YiKQ0KaGVhZChyaF9iYSkNCmBgYA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQpyaF9iYTI8LXJoX2JhJT4lZ3JvdXBfYnkoT2JzZXJ2YWNpb25lcyklPiVjb3VudCgpJT4ldW5ncm91cCgpJT4lbXV0YXRlKHBjbnQ9bi9zdW0obikqMTAwKSU+JWFycmFuZ2UocGNudCkNCg0KcmhfYmEyJHBjbnQ8LXJvdW5kKHJoX2JhMiRwY250LDIpDQoNCnJoX2JhMyA8LSByaF9iYTIgJT4lIG11dGF0ZShjc3VtID0gcmV2KGN1bXN1bShyZXYocGNudCkpKSwgDQogICAgICAgICBwb3MgPSBwY250LzIgKyBsZWFkKGNzdW0sIDEpLA0KICAgICAgICAgcG9zID0gaWZfZWxzZShpcy5uYShwb3MpLCBwY250LzIsIHBvcykpDQoNCg0KZ2dwbG90KHJoX2JhMixhZXMoeD0iIix5PXBjbnQsZmlsbD1PYnNlcnZhY2lvbmVzKSkrZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKStjb29yZF9wb2xhcih0aGV0YT0ieSIpK3RoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrZ2VvbV9sYWJlbF9yZXBlbChkYXRhPXJoX2JhMyxhZXMoeD1jKC4wMDAzLDAuMTUsMC4zMiwwLjUsMC43LDAuOSwxLjEsMS4zLDEuNSwxLjcsMS45LDIuMSwyLjMsMi41LDIuNywxLDAuOTgsMSkseT1wb3MsbGFiZWw9cGFzdGUwKHBjbnQsIiUiKSksc2l6ZT00LjUsbnVkZ2VfeD0xLG1heC5vdmVybGFwcz0zMCxzaG93LmxlZ2VuZCA9IEZBTFNFKSt0aGVtZV92b2lkKCkrICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikrbGFicyh0aXRsZT0iUmF6b25lcyBkZSBsYXMgYmFqYXMgbGFib3JhbGVzIGRlIEZPUk0gMjAyMyIpK3NjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IG1pX3BhbGV0YSkNCg0KYGBgDQoNCkVzdGEgZ3LDoWZpY2Egbm9zIEF5dWRhIGEgVmlzdWFsaXphciBxdWUgZGUgMjc5IHBlcnNvbmFzIHF1ZSBmdWVyb24gZGFkYXMgZGUgYmFqYXMgZW4gMjAyMywgZWwgNzYuMyUgbm8gZGllcm9uIHVuYSByYXpvbiBvIG5vIHNlIHJlZ2lzdHLDsyBlbCBtb3Rpdm8gZXNwZWNpZmljbyBkZSBiYWphLCB5IGRlIGxhcyBwZXJzb25hcyBkZSBsYXMgY3VhbGVzIHNpIHNlIHJlZ2lzdHLDsyBlbCBtb3Rpdm8gZGUgYmFqYXMgbGFzIDUgcmF6b25lcyBtw6FzIHBvcHVsYXJlcyBmdWVyb246IA0KDQoxLkVuY29udHLDsyBvdHJvIGVtcGxlbyAoKio4LjYlKiopDQoyLiBBc2lsaW8gcG9sw610aWNvIGVuIFVTQSAoKioyLjg3JSoqKQ0KMy4gU2UgcmV0aXJvIHBhcmEgY3VpZGFyIGRlIHN1IChzKSBoaWplIChzKSAoKioyLjE1JSoqKQ0KNC4gVHV2byBtYXMgZGUgMyBmYWx0YXMgeSBlbGxhIG1pc21hIGRlY2lkaW8gaXJzZSAoKioxLjc5JSoqKQ0KNS4gQ2FtYmlvIGRlIGVzdGFkby9yZXNpZGVuY2lhICgqKjEuNzklKiopDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpnID0gZ2dwbG90KHJoX2JhLCBhZXMoUHVlc3RvX05vbSwgZmlsbD1HZW5lcm8pICkgKyBsYWJzKHRpdGxlID0gIkRpc3RyaWJ1Y2nDs24gZGUgQmFqYXMgcG9yIEfDqW5lcm8gUG9yIHB1ZXN0byBkZSBUcmFiYWpvIix4PSJQdWVzdG8gKEFicmV2aWFkbykiKSt5bGFiKCJOw7ptZXJvIGRlIFBlcnNvbmFzIikgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSByZWwoMiksIGNvbG91ciA9ICJkYXJrZ29sZGVucm9kMyIpKQ0KDQpnK2dlb21fYmFyKHBvc2l0aW9uPSJkb2RnZSIpICsgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGZhY2U9ImJvbGQiLCBzaXplPTEwKSkgKyB0aGVtZV9taW5pbWFsKCkgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKSsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWlfcGFsZXRhKQ0KDQpgYGANCg0KRXN0YSBncsOhZmljYSBub3MgcGVybWl0ZSB2aXVzYWxpemFyIGVsIG7Dum1lcm8gZGUgcGVyc29uYXMgcXVlIGZ1ZXJvbiBkYWRhcyBkZSBiYWphcyBlbiAyMDIzIHNlZ8O6biBzdSBwdWVzdG8geSBnw6luZXJvLCBlbiBlc3RlIGNhc28gcG9kZW1vcyB2ZXIgcXVlIGxhcyBtYXlvcmVzIGJhamFzIHNvbiBlbiBlbCBwdWVzdG8gZGUgQXl1ZGFudGUgR2VuZXJhbCwgeSBzZSBoYW4gZGVzcGlkbyBhIHVuIG1heW9yIG7Dum1lcm8gZGUgbXVqZXJlcyBxdWUgZGUgaG9tYnJlcy4gRXN0byB0YW1iacOpbiBzZSBwdWVkZSByZWxhY2lvbmFyIGNvbiBsYXMgcmF6b25lcyBkZWwgcG9ycXVlIGZ1ZXJvbiBkYWRhcyBkZSBiYWphcy4gUG9yIGVqZW1wbG8sIHNlIHB1ZWRlIG9idGVuZXIgZWwgaW5zaWdodCBkZSBxdWUgc2kgc2Ugb2ZyZWNpZXJhIHVuYSB6b25hIHBhcmEgZWwgY3VpZGFkIGRlIGxvcyBoaWpvcyBkZSBsYXMgYW1kcmVzIHRyYWJhamFkb3Jhcywgc2UgcG9kcsOtYSByZWR1Y2lyIGVsIG7Dum1lcm8gZGUgYmFqYXMgZGUgbGFzIG11amVyZXMgZW4gZWwgcHVlc3RvIGRlIGF5dWRhbnRlIGdlbmVyYWwgdSBvdHJvcyBwdWVzdG9zLg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZGF0YVJIJEZFQ0hBLkRFLk5BQ0lNSUVOVE88LWFzLkRhdGUoZGF0YVJIJEZFQ0hBLkRFLk5BQ0lNSUVOVE8sIGZvcm1hdCA9ICIlZC8lbS8lWSIpDQpmZWNoYV9hY3R1YWw8LVN5cy5EYXRlKCkNCmRpZmVyZW5jaWFfZGlhczwtYXMubnVtZXJpYyhkaWZmdGltZShmZWNoYV9hY3R1YWwsZGF0YVJIJEZFQ0hBLkRFLk5BQ0lNSUVOVE8sdW5pdHMgPSAiZGF5cyIpKQ0KZGF0YVJIJEVEQUQ8LWRpZmVyZW5jaWFfZGlhcy8zNjUuMjUNCmRhdGFSSCRFREFEPC1yb3VuZChkYXRhUkgkRURBRCxkaWdpdHM9MCkNCg0KZGF0YVJIMjwtZGF0YVJIJT4lZmlsdGVyKEJBSkE9PTApDQpkYXRhUkgyJEZFQ0hBLkRFLkFMVEE8LWFzLkRhdGUoZGF0YVJIMiRGRUNIQS5ERS5BTFRBLCBmb3JtYXQgPSAiJWQvJW0vJVkiKQ0KZGF0YVJIMjwtZGF0YVJIMiU+JW11dGF0ZShEaWFzVHJhYmFqYWRvcz1hcy5udW1lcmljKGRpZmZ0aW1lKGZlY2hhX2FjdHVhbCxkYXRhUkgyJEZFQ0hBLkRFLkFMVEEsdW5pdHM9ImRheXMiKSkpDQpkYXRhUkgzPC1kYXRhUkgyJT4lc2VsZWN0KERpYXNUcmFiYWphZG9zLEZFQ0hBLkRFLkFMVEEsRURBRCxHRU5FUk8sUFVFU1RPLFBVRVNUT19OKQ0KZGF0YVJIMzwtZGF0YVJIMyU+JWFycmFuZ2UoZGVzYyhEaWFzVHJhYmFqYWRvcykpDQoNCnByb21fZWRhZDwtIG1lYW4oZGF0YVJIJEVEQUQpDQpzdW1tYXJ5KGRhdGFSSCkNClJhbmdvX2VkYWQ8LSBtYXgoZGF0YVJIJEVEQUQpLW1pbihkYXRhUkgkRURBRCkNCg0KTjwtbGVuZ3RoKGRhdGFSSCRFREFEKQ0KVmFyaWFuemFfZWRhZDwtIHZhcihkYXRhUkgkRURBRCkNCkRlc3ZFc19lZGFkPC1zZChkYXRhUkgkRURBRCkNCnByb21fZWRhZA0KUmFuZ29fZWRhZA0KVmFyaWFuemFfZWRhZA0KRGVzdkVzX2VkYWQNCmBgYA0KDQpDb24gZXN0YXMgbWVkaWRhcyBkZSBkaXNwZXJzacOzbiBjb24gcmVzcGVjdG8gYSBsYSBlZGFkIGRlbCBwZXJzb25hbCBkZSBGT1JNLCBwb2RlbW9zIGRlY2lyIHF1ZSBleGlzdGUgdW5hIGRpZmVyZW5jaWEgNTUgYcOxb3MgZW50cmUgbGEgcGVyc29uYSBtw6FzIGpvdmVuIHkgY29uIG3DoXMgZWRhZCBkZSBGT1JNLCBlcyBwb3IgZXN0byBxdWUgbnVlc3RyYSBWYXJpYW56YSB0aWVuZSB1biB2YWxvciBhbHRvICgxMjIuNikgbG8gcXVlIHNpZ25maWljYSBxdWUgaGF5IGRpZmVyZW5jaWFzIHNpZ25pZmljYXRpdmFzIGVudHJlIGxhcyBlZGFkZXMgZGUgbGFzIHBlcnNvbmFzIGNvbiByZXNwZWN0byBhIGxhIGVkYWQgbWVkaWEgZGUgbGEgcGVyc29uYXMgZGUgbGEgZW1wcmVzYSAoMzMuNSkuIEVsIHZhbG9yIGRlIGxhIERlc3ZpYWNpw7NuIEVzdMOhbmRhciBub3MgaW5kaWNhIHF1ZSBsYSBtYXlvcsOtYSBkZSBudWVzdHJhcyBlZGFkZXMgZXN0YXLDoW4gYSBtZW5vcyBvIG1hcyBkZSAxMSBhw7FvcyBkZWwgcHJvbWVkaW8gZGUgZWRhZCBkZWwgcGVyc29uYWwgKDMzLjUpDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpkYXRhUkg0PC1kYXRhUkgzJT4lZmlsdGVyKFBVRVNUT19OPT0iQS5HLiIpDQpkYXRhUkg0RjwtZGF0YVJINCU+JWZpbHRlcihHRU5FUk89PSJGRU1FTklOTyIpDQpkYXRhUkg0TTwtZGF0YVJINCU+JWZpbHRlcihHRU5FUk89PSJNQVNDVUxJTk8iKQ0KDQpoZWFkKGRhdGFSSDRGLDEwKQ0KDQpoZWFkKGRhdGFSSDRNLDEwKQ0KYGBgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpzdW1tYXJ5KGRhdGFSSDRGKQ0KDQpzdW1tYXJ5KGRhdGFSSDRNKQ0KYGBgDQoNCkVuIGVzdGUgYXBhcnRhZG8gcG9kZW1vcyBub3RhciBxdWUgbGFzIHBlcnNvbmFzIHF1ZSBtw6FzIGhhbiB0cmFiYWpvIGVuIGxhIGVtcHJlc2Egc29uIGRlbCBnZW5lcm8vc2V4byBNYXNjdWxpbm8sIGEgbGEgdmV6IGNvbiBsYSB2aXN1YWxpemFjacOzbiBkZSBsb3MgZGF0YXMgZnJhbWVzIHBvZGVtb3MgdmVyIHF1ZSBlbiBjdWVzdGnDs24gZGUgZWRhZCBsYXMgbXVqZXJlcyBxdWUgc2UgaGFuIG1hbnRlbmlkbyBlbiBsYSBlbXByZXNhLCB0aWVuZW4gdW4gcHJvbWVkaW8gZGUgZWRhZCBkZSAzOC41NSBhw7FvcyB5IGxvcyBob21icmVzIHVuIHByb21lZGlvIGRlIDI4LjM4Lg0KDQoqKlJlc3B1ZXN0YSoqDQoNCkNvbW8gcHVkaW1vcyB2ZXIgZW4gbGFzIGdyw6FmaWNhcyB5IGRhdG9zIHBhc2Fkb3MsIGVsIG9mcmVjZXIgdW4gc2VydmljaW8gZGUgY3VpZGFkbyBkZSBpbmZhbnRlcywgcG9kcsOtYSBwcm92b2NhciBxdWUgbWVub3MgbXVqZXJlcyBzZSBkZW4gZGUgYmFqYXMgeSBwb3IgZW5kZSBzZSByZWR1emNhIGRlIGNpZXJ0YSBkZSBtYW5lcmEgbGEgcm90YWNpw7NuIGRlIHBlcnNvbmFsLCB5YSBxdWUgY29tbyB2aW1vcyBoYXkgbcOhcyBtdWplcmVzIGRhZGFzIGRlIGJhamEgcXVlIGhvbWJyZSBlbiBlbCBwdWVzdG8gZGUgQXl1ZGFudGUgR2VuZXJhbC4gQSBsYSB2ZXogbm8gc2UgcG9kcsOtYSBkZWNpciBhIHRvdGFsaWRhZCBxdWUgbGFzIG11amVyZXMgZGViZXLDrWFuIGRlIHNlciB1bmEgcHJpb3JpZGFkLCB5YSBxdWUgY29tbyBzZSB2aXN1YWxpesOzIGVuIGxhIGdyw6FmaWNhLGxvcyBob21icmVzIGN1ZW50YW4gY29uIG1heW9yZXMgZMOtYXMgdHJhYmFqYWRvcyBxdWUgbGFzIG11amVyZXMuIExhIHJlc3B1ZXN0YSBjb3JyZWN0YSwgc2Vyw61hIHF1ZSBwYXJhIHBvZGVyIHJlZHVjaXIgbGEgcm90YWNpw7NuIGRlIHBlcnNvbmFsIHkgYXVtZW50YXIgbGEgcHJvZHVjdGl2aWRhZCBkZSBsYSBlbXByZXNhIHNlIGRlYmVyw61hIGRlIG9mcmVjZXIgbWVqb3JlcyBwcmVzdGFjaW9uZXMgYWwgcGVyc29uYWwgY29tbyB6b25hcyBkZSBjdWlkYWRvIGRlIGluZmFudGVzIHkvbyB1biBidWVuIHByb2dyYW1hIGRlIGNhcGFjaXRhY2lvbmVzIHF1ZSBwZXJtaXRhbiBlbCBjcmVjaW1pZW50byBwcm9mZXNpb25hbCwgeWEgcXVlIGNvbW8gc2UgdmnDsyBlbiBsYSBncsOhZmljYSBsYSByYXrDs24gbsO6bWVybyAxIGRlIHBvcnF1ZSBzZSBmdWVyb24gZXMgZGViaWRvIGEgcXVlIGVuY29udHJhcm9uIHVuIG51ZXZvIGVtcGxlbywgZWwgY3VhbCBzZWd1cmFtZW50ZSBsZXMgb2ZyZWPDrWEgbWVqb3JlcyBjb25kaWNpb25lcywgeSBlbCBoZWNobyBkZSB0ZW5lciB1biBidWVuIHByb2dyYW1hIGRlIGNhcGFjaXRhY2nDs24sIGp1bnRvIGNvbiB1bmEgem9uYSBkZSBjdWlkYWRvcyBwYXJhIGluZmFudGVzIHkgZWwgZXNxdWVtYSBkZSBhaG9ycm8vaW52ZXJzacOzbiBxdWUgRk9STSBvZnJlY2UsIHByb3ZvY2Fyw61hIHF1ZSBzZSByZWR1emNhIGxhIHJvdGFjacOzbiBkZSBwZXJzb25hbCB5IHNlIGF1bWVudGUgbGEgcHJvZGN1dGl2aWRhZCwgZGViaWRvIGEgbGFzIG51ZXZhcyBza2lsbHMgcXVlIGVsIHBlcnNvbmFsIHRlbmRyw61hLiBQb3IgbG8gcXVlIHNlIGRlYmVyw61hIGNlcmNpb3JhciBlbiBvZnJlY2VyIG1lam9yZXMgcHJlc3RhY2lvbmVzIHkgZW4gY29udHJhdGFyIGEgaG9tYnJlcyBkZSAyOCBhw7FvcyB5IG11amVyZXMgZGUgMzggYcOxb3MgYXByb3hpbWFkYW1lbnRlLg0KDQoNCiMjIyMgKipQUkVHVU5UQSAyKioNCg0Kwr9Tb24gZWwgZXN0YWRvIGNpdmlsIHkgZWwgZ8OpbmVybyBmYWN0b3JlcyBpbmRlcGVuZGllbnRlcyBlbiBsYSByb3RhY2nDs24gZGUgZW1wbGVhZG9zIG8gZXhpc3RlIHJlbGFjacOzbiBlbnRyZSBhbWJvcyBldmVudG9zPw0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQppIDwtIDIzOA0KZGZfYmFqYXNfZjwtIHN1YnNldChkZl9iYWphcywgIXJvdy5uYW1lcyhkZl9iYWphcyk9PWkpDQoNCkdlbmVyb3lFc3RhZG9jaXZpbCA8LSBzZWxlY3QoZGZfYmFqYXNfZixHRU5FUk8sIEVTVEFETy5DSVZJTCkNCmdncGxvdChHZW5lcm95RXN0YWRvY2l2aWwsYWVzKEdFTkVSTykpK2dlb21fYmFyKGFlcyhmaWxsPUVTVEFETy5DSVZJTCksIHdpZHRoPSAwLjUpICsgbGFicyh0aXRsZSA9ICJFc3RhZG8gQ2l2aWwgcG9yIEfDqW5lcm8iKSsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWlfcGFsZXRhKSANCmBgYA0KDQpFc3RhZMOtc3RpY29zIERlc2NyaXB0aXZvcw0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZGZfYmFqYXNfZiRFU1RBRE8uQ0lWSUwgPC0gYXMuZmFjdG9yKGRmX2JhamFzX2YkRVNUQURPLkNJVklMKQ0Kc3VtbWFyeShkZl9iYWphc19mJEVTVEFETy5DSVZJTCkNCmBgYA0KDQpNb2RhOiBFbiBhbWJvcyBzZXhvcyBsYSBtb2RhIGRlIGVzdGFkbyBjaXZpbCBlcyAiU29sdGVybyIgY29uIGNhc2kgZWwgNTAlIGRlIGxhcyByZXNwdWVzdGFzLiAyNDUgZGUgNTE0IHJlc3B1ZXN0YXMgc2UgZW5jdWVudHJhbiBlbiBlc3RhIGNhdGVnb3LDrWEuDQoNClRhYmxhcyBkZSBGcmVjdWVuY2lhDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpmcmVjdWVuY2lhZ2VuZXJvIDwtIHRhYmxlKGRmX2JhamFzX2YkR0VORVJPKQ0KZnJlY3VlbmNpYWdlbmVybw0KDQpmcmVjdWVuY2lhZXN0YWRvY2l2aWwgPC0gdGFibGUoZGZfYmFqYXNfZiRFU1RBRE8uQ0lWSUwpDQpmcmVjdWVuY2lhZXN0YWRvY2l2aWwNCmBgYA0KDQpUYWJsYXMgZGUgQ29udGluZ2VuY2lhDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KdGFieWwoZGZfYmFqYXNfZixHRU5FUk8sRVNUQURPLkNJVklMKQ0KYGBgDQoNCioqUmVzcHVlc3RhKioNCg0KU2kgdG9tYW1vcyBlbiBjdWVudGEgbGEgY2FudGlkYWQgZGUgZW1wbGVhZG9zIGRlIGNhZGEgZ8OpbmVybyB5IGxhIG1vZGEgb2J0ZW5pZGEsIHF1ZSBlbiBlc3RlIGNhc28gZXMgZWwgZXN0YWRvIGNpdmlsICJzb2x0ZXJvIiwgb2J0ZW5lbW9zIHBvcmNlbnRhamVzIG11eSBzaW1pbGFyZXMuDQpQZXJzb25hcyBkZSBnw6luZXJvIGZlbWVuaW5vIHNvbHRlcmFzOiAqKjQ3JSoqDQpQZXJzb25hcyBkZSBnw6luZXJvIG1hc2N1bGlubyBzb2x0ZXJvczogKio0OCUqKg0KRXMgcG9yIGVzbyBxdWUgc2UgcHVlZGUgZGV0ZXJtaW5hciBxdWUgYW1iYXMgdmFyaWFibGVzIGFuYWxpemFkYXMgbm8gcmVwcmVzZW50YW4gdW4gZmFjdG9yIGRldGVybW1pbmFudGUgZW4gbGEgcm90YWNpw7NuIGRlIGVtcGxlYWRvcyB5IHNvbiBldmVudG9zIGluZGVwZW5kaWVudGVzLg0KDQojIyMjICoqUFJFR1VOVEEgMyoqIA0KDQrCv0VuIHF1w6kgZXN0YWNpw7NuIGRlbCBhw7FvIHRpZW5kZW4gYSBzdWNlZGVyIG3DoXMgYmFqYXM/IMK/RWwgY2xpbWEgc2Vyw6EgdW4gZmFjdG9yIGRldGVybWluYW50ZT8NCg0KIyMjIyMgQ2FyZ2FuZG8gbGEgYmFzZSBkZSBkYXRvcw0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmRhdGE8LXJlYWQuY3N2KCJDOlxcVXNlcnNcXGNhXFxEZXNrdG9wXFxSIFN0dWRpb1xcRGF0b3MgRXZpZGVuY2lhIDFcXEVfZm9ybV9yaF9iYWphc19kYXRvc18yMDIyLmNzdiIpDQpgYGANCg0KIyMjIyMgQ2FtYmlhbmRvIGVsIGZvcm1hdG8gZGUgZmVjaGENCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpkYXRhJEZlY2hhIDwtIGRteShkYXRhJEJBSkEpDQpgYGANCg0KIyMjIyMgT2J0ZW5jacOzbiBkZWwgbWVzIGRlIGNhZGEgZmVjaGEgDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZGF0YSRNZXMgPC0gbW9udGgoZGF0YSRGZWNoYSkNCmBgYA0KDQojIyMjIyBNYXBlbyBkZSBsb3MgbWVzZXMgYSBsYXMgZXN0YWNpb25lcyBkZWwgYcOxbw0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmRhdGEkRXN0YWNpb24gPC0gY2FzZV93aGVuKA0KICBkYXRhJE1lcyAlaW4lIGMoMywgNCwgNSkgfiAiUHJpbWF2ZXJhIiwNCiAgZGF0YSRNZXMgJWluJSBjKDYsIDcsIDgpIH4gIlZlcmFubyIsDQogIGRhdGEkTWVzICVpbiUgYyg5LCAxMCwgMTEpIH4gIk90b8OxbyIsDQogIGRhdGEkTWVzICVpbiUgYygxMiwgMSwgMikgfiAiSW52aWVybm8iLA0KICBUUlVFIH4gTkFfY2hhcmFjdGVyXw0KKQ0KYGBgDQoNCiMjIyMjIENvbnRlbyBkZSBvYnNlcnZhY2lvbmVzIGVuIGNhZGEgZXN0YWNpw7NuDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZXN0YWNpb25fZnJlY3VlbmNpYSA8LSB0YWJsZShkYXRhJEVzdGFjaW9uKQ0KYGBgDQoNCiMjIyMjIERlc2N1YnJpbWllbnRvIGRlIGxhIGVzdGFjacOzbiBjb24gZWwgcmVjdWVudG8gbcOhcyBhbHRvDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZXN0YWNpb25fbWFzX2NvbXVuIDwtIG5hbWVzKGVzdGFjaW9uX2ZyZWN1ZW5jaWFbd2hpY2gubWF4KGVzdGFjaW9uX2ZyZWN1ZW5jaWEpXSkNCmBgYA0KDQojIyMjIyBJbXByZXNpw7NuIGRlbCByZXN1bHRhZG8NCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpjYXQoIkxhIGVzdGFjacOzbiBjb24gbcOhcyBiYWphcyBlczoiLCBlc3RhY2lvbl9tYXNfY29tdW4pDQoNCmBgYA0KIyMjIyMgQ8OhbGN1bG8gZGUgbGEgZnJlY3VlbmlhIGRlIGJhamFzIHBvciBlc3RhY2nDs24gDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQplc3RhY2lvbl9mcmVjdWVuY2lhIDwtIHRhYmxlKGRhdGEkRXN0YWNpb24pDQpgYGANCg0KIyMjIyMgQ29udmVyc2nDs24gZGUgcmVzdWx0YWRvcyBhIHVuIGRhdGFmcmFtZQ0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KdGFibGFfYmFqYXNfcG9yX2VzdGFjaW9uIDwtIGFzLmRhdGEuZnJhbWUoZXN0YWNpb25fZnJlY3VlbmNpYSkNCmBgYA0KDQojIyMjIyBTZSByZW5vbWJyYSBsYXMgY29sdW1uYXMgcGFyYSBtYXlvciBjbGFyaWRhZA0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmNvbG5hbWVzKHRhYmxhX2JhamFzX3Bvcl9lc3RhY2lvbikgPC0gYygiRXN0YWNpb24iLCAiQ2FudGlkYWRfQmFqYXMiKQ0KDQpwcmludCh0YWJsYV9iYWphc19wb3JfZXN0YWNpb24pDQoNCmBgYA0KDQojIyMjIyBTZSBjcmVhIGVsIGdyw6FmaWNvIGRlIGJhcnJhcw0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmdncGxvdCh0YWJsYV9iYWphc19wb3JfZXN0YWNpb24sIGFlcyh4ID0gRXN0YWNpb24sIHkgPSBDYW50aWRhZF9CYWphcykpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGNvbG9yID0gImJsYWNrIiwgd2lkdGggPSAwLjcsIGZpbGwgPSAib3JhbmdlIikgKw0KICBsYWJzKHRpdGxlID0gIkNhbnRpZGFkIGRlIEJhamFzIHBvciBFc3RhY2nDs24gZGVsIEHDsW8gMjAyMiIsIHN1YnRpdGxlID0gIlJlY3Vyc29zIEh1bWFub3MiLCB4ID0gIkVzdGFjacOzbiIsIHkgPSAiQ2FudGlkYWQgZGUgQmFqYXMiKQ0KDQpgYGANCg0KKipSZXNwdWVzdGEqKg0KDQpFcyBwb3NpYmxlIG9ic2VydmFyIHF1ZSBkdXJhbnRlIGVsIGHDsW8gMjAyMiBlbCBwZXJpb2RvIGVzdGFjaW9uYWwgcXVlIHJlcG9ydMOzIG3DoXMgYmFqYXMgZGUgcGVyc29uYWwgZnVlIGxhIHByaW1hdmVyYSB5IGVsIHZlcmFubyByZXNwZWN0aXZhbWVudGUsIGxvcyBjdWFsZXMgc2UgZW5jdWVudHJhbiBzaXR1YWRvcyBlbnRyZSBsb3MgbWVzZXMgZGUgTWFyem8geSBTZXB0aWVtYnJlLCBtZXNlcyBkb25kZSBzZSByZXBvcnRhbiBsYXMgdGVtcGVyYXR1cmFzIG3DoXMgZWxldmFkYXMgZW4gbGEgY2l1ZGFkIGRlIE1vbnRlcnJleSwgTnVldm8gTGXDs24uIFBvciBsbyB0YW50bywgbGEgZXhwb3NpY2nDs24gYSBjb25kaWNpb25lcyB0w6lybWljYXMgZWxldmFkYXMgcHVlZGUgc3Vwb25lciB1biBmYWN0b3IgZGUgZXN0csOpcyBlIGluc2F0aXNmYWNjacOzbiBsYWJvcmFsLCB5YSBxdWUgc2UgcmVsYWNpb25hIGNvbiBwcm9ibGVtYXMgZGUgc2FsdWQsIGNvbW9kaWRhZCwgY29uY2VudHJhY2nDs24geSBjb24gdW4gbWF5b3Igcmllc2dvIGRlIHN1ZnJpciBhY2NpZGVudGVzIGRlIHRyYWJham8gb2Nhc2lvbmFuZG8gbGFzIGJhamFzIGRlbCBwZXJzb25hbCBkZSBGb3JtLiBTZSByZWNvbWllbmRhIGFwb3lhcnNlIGRlIGxhIE5vcm1hIE9maWNpYWwgTWV4aWNhbmEgTk9NLTAxNS1TVFBTLTE5OTMuIA0KDQpBZGVtw6FzLCBjb24gZWwgZmluIGRlIHJlc3BvbmRlciBjb24gbWF5b3IgY2xhcmlkYWQgbGEgcHJlZ3VudGEgZGVsIGFuw6FsaXNpcywgYSBjb250aW51YWNpw7NuIHNlIGNvbXBhcnRlIGluZm9ybWFjacOzbiBkZSBmdWVudGVzIHNlY3VuZGFyaWFzIHNvYnJlIGxhIHRlbXBlcmF0dXJhIHJlZ2lzdHJhZGEgZW4gTW9udGVycmV5IGR1cmFudGUgZWwgMjAyMiB0YW50byBwb3IgbWVzIGNvbW8gcG9yIGhvcmEuDQoNCioqKkRhdG9zIEhpc3TDs3JpY29zIGRlIFRlbXByYXR1cmEgZGVsIDIwMjIgZW4gTW9udGVycmV5KioqDQoNCiFbV2VhdGhlclNwYXJrXShDOlxcVXNlcnNcXGNhXFxEZXNrdG9wXFxSIFN0dWRpb1xcRGF0b3MgRXZpZGVuY2lhIDFcXERhdG9zIGhpc3TDs3JpY29zIGRlIHRlbXBlcmF0dXJhIGVuIGVsIHZlcmFubyBkZSAyMDIyIGVuIE1vbnRlcnJleS5wbmcpDQoNCkVsIGludGVydmFsbyBkaWFyaW8gZGUgdGVtcGVyYXR1cmFzIHJlcG9ydGFkYXMgKGJhcnJhcyBncmlzZXMpIHkgbGFzIG3DoXhpbWFzIChtYXJjYXMgcm9qYXMpIHkgbcOtbmltYXMgKG1hcmNhcyBhenVsZXMpIGRlIDI0IGhvcmFzLCBjb2xvY2FkYXMgYXJyaWJhIGRlbCBwcm9tZWRpbyBkaWFyaW8gZGUgbGEgbcOheGltYSAobMOtbmVhIHJvam8gY2xhcm8pIHkgZGUgbGEgbcOtbmltYSAobMOtbmVhIGF6dWwgY2xhcm8pLCBjb24gbGFzIGJhbmRhcyBkZSBsb3MgcGVyY2VudGlsZXMgMjUgYSA3NSB5IDEwIGEgOTAuDQoNCioqKlRlbXBlcmF0dXJhIHBvciBIb3JhIGRlbCAyMDIyIGVuIE1vbnRlcnJleSoqKg0KDQohW1dlYXRoZXJTcGFya10oQzpcXFVzZXJzXFxjYVxcRGVza3RvcFxcUiBTdHVkaW9cXERhdG9zIEV2aWRlbmNpYSAxXFxEYXRvcyBoaXN0b3JpY29zIHBvciBob3JhLnBuZykNCkxhIHRlbXBlcmF0dXJhIHJlcG9ydGFkYSBwb3IgaG9yYSwgY29kaWZpY2FkYSBwb3IgY29sb3JlcyBlbiBiYW5kYXMuIExhcyDDoXJlYXMgc29tYnJlYWRhcyBzdXBlcnB1ZXN0YXMgaW5kaWNhbiBsYSBub2NoZSB5IGVsIGNyZXDDunNjdWxvIGNpdmlsLg0KDQojIyMjICoqUFJFR1VOVEEgNCoqDQoNCsK/TGEgZWRhZCBkZWwgdHJhYmFqYWRvciBwdWVkZSBzZXIgdW4gZGV0ZXJtaW5hbnRlIGRlIHBvciBxdcOpIHNlIGRhbiBkZSBiYWphPw0KDQojIyMjIyBDYXJnYW5kbyBkZSBsYSBiYXNlIGRlIGRhdG9zDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpkYXRvc19FPC0gcmVhZC5jc3YoIkM6XFxVc2Vyc1xcY2FcXERlc2t0b3BcXFIgU3R1ZGlvXFxEYXRvcyBFdmlkZW5jaWEgMVxcRV9GT1JNX0NvbnNvbGlkYWRvLmNzdiIpDQoNCmBgYA0KDQojIyMjIyBMaW1waWV6YSBkZSBEYXRvcw0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmRhdG9zX0UkRkVDSEEuREUuTkFDSU1JRU5UTyA8LSBhcy5EYXRlKGRhdG9zX0UkRkVDSEEuREUuTkFDSU1JRU5UTywgZm9ybWF0ID0gIiVkLyVtLyVZIikNCmBgYA0KDQojIyMjIyBDw6FsY3VsbyBkZSBsYSBlZGFkIGVuIGHDsW9zDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZGF0b3NfRSA8LSBkYXRvc19FICU+JQ0KICBtdXRhdGUoZWRhZCA9IGFzLmludGVnZXIoZGlmZnRpbWUoU3lzLkRhdGUoKSwgRkVDSEEuREUuTkFDSU1JRU5UTywgdW5pdHMgPSAiZGF5cyIpIC8gMzY1LjI1KSkNCmBgYA0KDQojIyMjIyBDw6FsY3VsbyBkZSBsb3MgZMOtYXMgdHJhYmFqYWRvcw0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmRhdG9zX0UkRkVDSEEuREUuQUxUQSA8LSBhcy5EYXRlKGRhdG9zX0UkRkVDSEEuREUuQUxUQSwgZm9ybWF0ID0gKCIlZC8lbS8lWSIpKQ0KDQojIE9idGVuZXIgbGEgZmVjaGEgYWN0dWFsDQpmZWNoYV9hY3R1YWwgPC0gU3lzLkRhdGUoKQ0KDQpkYXRvc19FIDwtIGRhdG9zX0UgJT4lDQogIG11dGF0ZShkaWFzX3RyYWJhamFkb3MgPSBpZmVsc2UoQkFKQSA9PSAxLCAwLCBkaWZmdGltZShmZWNoYV9hY3R1YWwsIEZFQ0hBLkRFLkFMVEEsIHVuaXRzID0gImRheXMiKSkpDQpgYGANCg0KIyMjIyMgR3LDoWZpY28gZGUgQmFycmFzIEFwaWxhZGFzDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZ2dwbG90KGRhdG9zX0UsIGFlcyh4ID0gZWRhZCwgZmlsbCA9IGZhY3RvcihCQUpBKSkpICsNCiAgZ2VvbV9iYXIoKSArDQogIGxhYnMoeCA9ICJFZGFkIiwgeSA9ICJDYW50aWRhZCBkZSBQZXJzb25hcyIsIGZpbGwgPSAiQmFqYSIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsgbGFicyh0aXRsZT0iRWRhZCBkZSBCYWphcyB5IE5vIEJhamFzIikrc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWlfcGFsZXRhKQ0KYGBgDQoNCioqUkVTUFVFU1RBKioNCg0KTGEgZ3JhZmljYSBtdWVzdHJhIHF1ZSBwYXNhbmRvIGxhIGVkYWQgZGUgNDAgYcOxb3MgZXMgbWVub3MgcHJvYmFibGUgcXVlIG9jdXJyYSB1bmEgYmFqYS4gVGFtYmnDqW4gc2UgbXVlc3RyYSBxdWUgbGFzIGJhamFzIG3DoXMgY29uc3RhbnRlcyBlc3TDoW4gZW4gbGEgZWRhZCBkZSBsb3MgMjAtMzUgc2UgZGViZSB0YW1iacOpbiBhbCBhbHRvIHBvcmNlbnRhamUgZGUgdHJhYmFqYWRvcmVzIGRlIGVzYSBlZGFkLg0KDQojIyMjICoqUFJFR1VOVEEgNSoqDQrCv0xhIGRpc3RhbmNpYSBnZW9ncsOhZmljYSBkZXNlbXBlw7FhIHVuIHBhcGVsIHNpZ25pZmljYXRpdm8gZW4gbGEgZGV0ZXJtaW5hY2nDs24gZGVsIGVzdGF0dXMgbGFib3JhbCBkZSBsb3MgZW1wbGVhZG9zPyAoQWN0aXZvIG8gSW5hY3Rpdm8pDQoNCiMjIyMjIEFncnVwYWNpw7NuIGRlIHNvbG8gTnVldm8gTGXDs24NCmBgYHtyfQ0KYmFqYXNfbmwgPC0gZGZfYmFqYXMgJT4lDQogIG11dGF0ZShFU1RBRE8gPSBpZmVsc2UoRVNUQURPICVpbiUgYygiTlVFVk8gTEVPTiIsICJOVUVWTyBMRcOTTiIpLCAiTlVFVk8gTEVPTiIsIEVTVEFETykpICU+JQ0KICBmaWx0ZXIoRVNUQURPID09ICJOVUVWTyBMRU9OIikNCg0KYWN0dWFsZXNfbmwgPC0gZGF0b3NfYWN0dWFsZXMgJT4lDQogIG11dGF0ZShFU1RBRE8gPSBpZmVsc2UoRVNUQURPICVpbiUgYygiTlVFVk8gTEVPTiIsICJOVUVWTyBMRcOTTiIpLCAiTlVFVk8gTEVPTiIsIEVTVEFETykpICU+JQ0KICBmaWx0ZXIoRVNUQURPID09ICJOVUVWTyBMRU9OIikNCmBgYA0KDQojIyMjIyBGdW5jacOzbiBVYmljYWNpw7NuIEdlb2dyw6FmaWNhDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KI2NsYXZlX2FwaSA8LSAiYWIzMmU5MjQ4MTFjNDAwYmExYmNjMzM1OTgwZjI1YTUiDQpjbGF2ZV9hcGkgPC0gImFiMzJlOTI0ODExYzQwMGJhMWJjYzMzNTk4MGYyNWE1Ig0KDQpnZW9jb2RlX29wZW5jYWdlIDwtIGZ1bmN0aW9uKGRpcmVjY2lvbiwgY2xhdmVfYXBpKSB7DQogIHVybCA8LSBwYXN0ZTAoImh0dHBzOi8vYXBpLm9wZW5jYWdlZGF0YS5jb20vZ2VvY29kZS92MS9qc29uP3E9IiwgVVJMZW5jb2RlKGRpcmVjY2lvbiksDQogICAgICAgICAgICAgICAgIiZrZXk9IiwgY2xhdmVfYXBpKQ0KICByZXNwdWVzdGEgPC0gR0VUKHVybCkNCiAgY29udGVuaWRvIDwtIGNvbnRlbnQocmVzcHVlc3RhLCAidGV4dCIsIGVuY29kaW5nID0gIlVURi04IikNCiAgZGF0b3MgPC0ganNvbmxpdGU6OmZyb21KU09OKGNvbnRlbmlkbykNCiAgcmV0dXJuKGRhdG9zKQ0KfQ0KYGBgDQoNCiMjIyMjIExhdGl0dWQgeSBMb25naXR1ZA0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmJhamFzX25sJEdFT0NPREVfUkVTVUxUIDwtIGxhcHBseShiYWphc19ubCRESVJFQ0NJT04sIGZ1bmN0aW9uKHgpIGdlb2NvZGVfb3BlbmNhZ2UoeCwgY2xhdmVfYXBpKSkNCmJhamFzX25sJExBVElUVUQgPC0gc2FwcGx5KGJhamFzX25sJEdFT0NPREVfUkVTVUxULCBmdW5jdGlvbih4KSB4JHJlc3VsdHMkZ2VvbWV0cnkkbGF0KQ0KYmFqYXNfbmwkTE9OR0lUVUQgPC0gc2FwcGx5KGJhamFzX25sJEdFT0NPREVfUkVTVUxULCBmdW5jdGlvbih4KSB4JHJlc3VsdHMkZ2VvbWV0cnkkbG5nKQ0KDQphY3R1YWxlc19ubCRHRU9DT0RFX1JFU1VMVCA8LSBsYXBwbHkoYWN0dWFsZXNfbmwkRElSRUNDSU9OLCBmdW5jdGlvbih4KSBnZW9jb2RlX29wZW5jYWdlKHgsIGNsYXZlX2FwaSkpDQphY3R1YWxlc19ubCRMQVRJVFVEIDwtIHNhcHBseShhY3R1YWxlc19ubCRHRU9DT0RFX1JFU1VMVCwgZnVuY3Rpb24oeCkgeCRyZXN1bHRzJGdlb21ldHJ5JGxhdCkNCmFjdHVhbGVzX25sJExPTkdJVFVEIDwtIHNhcHBseShhY3R1YWxlc19ubCRHRU9DT0RFX1JFU1VMVCwgZnVuY3Rpb24oeCkgeCRyZXN1bHRzJGdlb21ldHJ5JGxuZykNCg0KYGBgDQoNCiMjIyMjIEZ1bmNpw7NuIHBhcmEgY2FsY3VsYXIgZWwgcHJvbWVkaW8gZGUgdW5hIGxpc3RhIGRlIG7Dum1lcm9zDQpgYGB7cn0NCmNhbGN1bGFyX3Byb21lZGlvIDwtIGZ1bmN0aW9uKHZhbG9yKSB7DQogIGlmIChpcy5jaGFyYWN0ZXIodmFsb3IpKSB7DQogICAgdmFsb3JlcyA8LSB0cnlDYXRjaChldmFsKHBhcnNlKHRleHQgPSB2YWxvcikpLCBlcnJvciA9IGZ1bmN0aW9uKGUpIE5BX3JlYWxfKQ0KICB9IGVsc2Ugew0KICAgIHZhbG9yZXMgPC0gdmFsb3INCiAgfQ0KICB2YWxvcmVzIDwtIHZhbG9yZXNbIWlzLm5hKHZhbG9yZXMpXSANCiAgaWYgKGxlbmd0aCh2YWxvcmVzKSA+IDApIHsNCiAgICByZXR1cm4obWVhbih2YWxvcmVzKSkNCiAgfSBlbHNlIHsNCiAgICByZXR1cm4oTkFfcmVhbF8pDQogIH0NCn0NCmBgYA0KDQoNCmBgYHtyfQ0KYmFqYXNfbmwkTE9OR0lUVUQgPC0gc2FwcGx5KGJhamFzX25sJExPTkdJVFVELCBjYWxjdWxhcl9wcm9tZWRpbykNCmJhamFzX25sJExBVElUVUQgPC0gc2FwcGx5KGJhamFzX25sJExBVElUVUQsIGNhbGN1bGFyX3Byb21lZGlvKQ0KDQphY3R1YWxlc19ubCRMT05HSVRVRCA8LSBzYXBwbHkoYWN0dWFsZXNfbmwkTE9OR0lUVUQsIGNhbGN1bGFyX3Byb21lZGlvKQ0KYWN0dWFsZXNfbmwkTEFUSVRVRCA8LSBzYXBwbHkoYWN0dWFsZXNfbmwkTEFUSVRVRCwgY2FsY3VsYXJfcHJvbWVkaW8pDQpgYGANCg0KIyMjIyMgRGlyZWNjacOzbiBvYmpldGl2bw0KYGBge3J9DQpkaXJlY2Npb25fb2JqZXRpdm8gPC0gIlBhcnF1ZSBJbmR1c3RyaWFsIGVsIFNhYmluYWwsIENhbS4gQWwgU2FiaW5hbCAxMDUtTm8sIDY2NjQ1IENkIEFwb2RhY2EsIE4uTC4iDQoNCmNvb3JkZW5hZGFzX29iamV0aXZvIDwtIGdlb2NvZGVfb3BlbmNhZ2UoZGlyZWNjaW9uX29iamV0aXZvLCBjbGF2ZV9hcGkpDQoNCmxhdGl0dWRfb2JqZXRpdm8gPC0gMjUuNzU0MTkNCmxvbmdpdHVkX29iamV0aXZvIDwtIC0xMDAuMTc0NDMNCmBgYA0KDQojIyMjIyBDcmVhciB1bmEgZnVuY2nDs24gcXVlIGNhbGN1bGUgbGEgZGlzdGFuY2lhIGhhdmVyc2luZSBlbiBraWzDs21ldHJvcw0KYGBge3J9DQpjYWxjdWxhcl9kaXN0YW5jaWFfa20gPC0gZnVuY3Rpb24obGF0MSwgbG9uMSwgbGF0MiwgbG9uMikgew0KICBkaXN0X21ldHJvcyA8LSBkaXN0SGF2ZXJzaW5lKGMobG9uMSwgbGF0MSksIGMobG9uMiwgbGF0MikpDQogIGRpc3Rfa20gPC0gZGlzdF9tZXRyb3MgLyAxMDAwICANCiAgcmV0dXJuKGRpc3Rfa20pDQp9DQoNCmJhamFzX25sJERJU1RBTkNJQS5LTSA8LSBtYXBwbHkoY2FsY3VsYXJfZGlzdGFuY2lhX2ttLCBiYWphc19ubCRMQVRJVFVELCBiYWphc19ubCRMT05HSVRVRCwgbGF0aXR1ZF9vYmpldGl2bywgbG9uZ2l0dWRfb2JqZXRpdm8pDQoNCmFjdHVhbGVzX25sJERJU1RBTkNJQS5LTSA8LSBtYXBwbHkoY2FsY3VsYXJfZGlzdGFuY2lhX2ttLCBhY3R1YWxlc19ubCRMQVRJVFVELCBhY3R1YWxlc19ubCRMT05HSVRVRCwgbGF0aXR1ZF9vYmpldGl2byxsb25naXR1ZF9vYmpldGl2bykNCmBgYA0KDQpgYGB7cn0NCmNvcGlhX2FjdHVhbGVzX25sIDwtIGFzLmRhdGEuZnJhbWUobGFwcGx5KGFjdHVhbGVzX25sLCB0b3VwcGVyKSkNCmNvcGlhX2JhamFzX25sIDwtIGFzLmRhdGEuZnJhbWUobGFwcGx5KGJhamFzX25sLCB0b3VwcGVyKSkNCmBgYA0KDQpgYGB7cn0NCmNvcGlhX2FjdHVhbGVzX25sIDwtIGNvcGlhX2FjdHVhbGVzX25sWyFpcy5uYShjb3BpYV9hY3R1YWxlc19ubCRMQVRJVFVEKSAmICFpcy5uYShjb3BpYV9hY3R1YWxlc19ubCRMT05HSVRVRCksIF0NCmNvcGlhX2JhamFzX25sIDwtIGNvcGlhX2JhamFzX25sWyFpcy5uYShjb3BpYV9iYWphc19ubCRMQVRJVFVEKSAmICFpcy5uYShjb3BpYV9iYWphc19ubCRMT05HSVRVRCksIF0NCg0KY29waWFfYWN0dWFsZXNfbmwkTEFUSVRVRCA8LSBhcy5udW1lcmljKGNvcGlhX2FjdHVhbGVzX25sJExBVElUVUQpDQpjb3BpYV9hY3R1YWxlc19ubCRMT05HSVRVRCA8LSBhcy5udW1lcmljKGNvcGlhX2FjdHVhbGVzX25sJExPTkdJVFVEKQ0KY29waWFfYmFqYXNfbmwkTEFUSVRVRCA8LSBhcy5udW1lcmljKGNvcGlhX2JhamFzX25sJExBVElUVUQpDQpjb3BpYV9iYWphc19ubCRMT05HSVRVRCA8LSBhcy5udW1lcmljKGNvcGlhX2JhamFzX25sJExPTkdJVFVEKQ0KDQpjb3BpYV9hY3R1YWxlc19ubCRESVNUQU5DSUEuS00gPC0gYXMubnVtZXJpYyhjb3BpYV9hY3R1YWxlc19ubCRESVNUQU5DSUEuS00pDQpjb3BpYV9iYWphc19ubCRESVNUQU5DSUEuS00gPC0gYXMubnVtZXJpYyhjb3BpYV9iYWphc19ubCRESVNUQU5DSUEuS00pDQpgYGANCg0KYGBge3J9DQpjb3BpYV9hY3R1YWxlc19ubCA8LSBjb3BpYV9hY3R1YWxlc19ubFtjb3BpYV9hY3R1YWxlc19ubCRMT05HSVRVRCA+PSAtMTAwLjUgJiBjb3BpYV9hY3R1YWxlc19ubCRMT05HSVRVRCA8PSAtOTkuOSwgXQ0KY29waWFfYmFqYXNfbmwgPC0gY29waWFfYmFqYXNfbmxbY29waWFfYmFqYXNfbmwkTE9OR0lUVUQgPj0gLTEwMC41ICYgY29waWFfYmFqYXNfbmwkTE9OR0lUVUQgPD0gLTk5LjksIF0NCg0KY29waWFfYWN0dWFsZXNfbmwgPC0gY29waWFfYWN0dWFsZXNfbmxbY29waWFfYWN0dWFsZXNfbmwkTEFUSVRVRCA+PSAyNSAmIGNvcGlhX2FjdHVhbGVzX25sJExBVElUVUQgPD0gMjYsIF0NCmNvcGlhX2JhamFzX25sIDwtIGNvcGlhX2JhamFzX25sW2NvcGlhX2JhamFzX25sJExBVElUVUQgPj0gMjUgJiBjb3BpYV9iYWphc19ubCRMQVRJVFVEIDw9IDI2LCBdDQpgYGANCg0KYGBge3J9DQptIDwtIGxlYWZsZXQoKSAlPiUNCiAgYWRkVGlsZXMoKSAlPiUgICMgQcOxYWRlIHVuIGZvbmRvIGRlIG1hcGEgcmVhbA0KICBhZGRDaXJjbGVNYXJrZXJzKA0KICAgIGRhdGEgPSBjb3BpYV9iYWphc19ubCwgICMgRGF0b3MgZGUgdWJpY2FjaW9uZXMgZGUgcmVnaXN0cm9zDQogICAgbGF0ID0gfkxBVElUVUQsICAjIE5vbWJyZSBkZSBsYSBjb2x1bW5hIGRlIGxhdGl0dWQNCiAgICBsbmcgPSB+TE9OR0lUVUQsICAjIE5vbWJyZSBkZSBsYSBjb2x1bW5hIGRlIGxvbmdpdHVkDQogICAgY29sb3IgPSAicmVkIiwgICMgQ29sb3IgZGUgbG9zIG1hcmNhZG9yZXMgZGUgcmVnaXN0cm9zDQogICAgcmFkaXVzID0gNSwgICMgVGFtYcOxbyBkZSBsb3MgbWFyY2Fkb3JlcyBkZSByZWdpc3Ryb3MNCiAgICBsYWJlbCA9ICJCYWphcyIgICMgRXRpcXVldGEgcGFyYSBsb3MgbWFyY2Fkb3JlcyBkZSByZWdpc3Ryb3MNCiAgKSAlPiUNCiAgYWRkQ2lyY2xlTWFya2VycygNCiAgICBkYXRhID0gY29waWFfYWN0dWFsZXNfbmwsICAjIERhdG9zIGRlIHViaWNhY2lvbmVzIGRlIGRmX2FjdHVhbA0KICAgIGxhdCA9IH5MQVRJVFVELCAgIyBOb21icmUgZGUgbGEgY29sdW1uYSBkZSBsYXRpdHVkIGVuIGRmX2FjdHVhbA0KICAgIGxuZyA9IH5MT05HSVRVRCwgICMgTm9tYnJlIGRlIGxhIGNvbHVtbmEgZGUgbG9uZ2l0dWQgZW4gZGZfYWN0dWFsDQogICAgY29sb3IgPSAiZ3JlZW4iLCAgIyBDb2xvciBkZSBsb3MgbWFyY2Fkb3JlcyBkZSBkZl9hY3R1YWwNCiAgICByYWRpdXMgPSA1LCAgIyBUYW1hw7FvIGRlIGxvcyBtYXJjYWRvcmVzIGRlIGRmX2FjdHVhbA0KICAgIGxhYmVsID0gIkFjdGl2b3MiICAjIEV0aXF1ZXRhIHBhcmEgbG9zIG1hcmNhZG9yZXMgZGUgZGZfYWN0dWFsDQogICkgJT4lDQogIGFkZENpcmNsZU1hcmtlcnMoDQogICAgbGF0ID0gbGF0aXR1ZF9vYmpldGl2bywgICMgTGF0aXR1ZCBkZWwgZGVzdGlubw0KICAgIGxuZyA9IGxvbmdpdHVkX29iamV0aXZvLCAgIyBMb25naXR1ZCBkZWwgZGVzdGlubw0KICAgIGNvbG9yID0gImJsdWUiLCAgIyBDb2xvciBkZWwgbWFyY2Fkb3IgZGUgZGVzdGlubw0KICAgIHJhZGl1cyA9IDgsICAjIFRhbWHDsW8gZGVsIG1hcmNhZG9yIGRlIGRlc3Rpbm8NCiAgICBsYWJlbCA9ICJEZXN0aW5vIiAgIyBFdGlxdWV0YSBwYXJhIGVsIG1hcmNhZG9yIGRlIGRlc3Rpbm8NCiAgKQ0KDQpgYGANCg0KVmlzdWFsaXphY2nDs24gZGVsIG1hcGEgaW50ZXJhY3Rpdm8NCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCm0NCmBgYA0KRW4gZXN0ZSBncsOhZmljbyBwb2RlbW9zIG9ic2VydmFyIGRlIGNvbG9yIHJvam8gbGEgZGlyZWNjacOzbiBkZSBhcXVlbGxhcyBwZXJzb25hcyBxdWUgeWEgbm8gZm9ybWFuIHBhcnRlIGRlIGxhIGVtcHJlc2EsIGVuIGNvbG9yIHZlcmRlIGxvcyBjb2xhYm9yYWRvcmVzIGFjdGl2b3MgeSBlbCBwdW50byBkZSBjb2xvciBhenVsIGVzIGxhIGRpcmVjY2nDs24gZGVsIHNvY2lvIGZvcm1hZG9yLiBBIHNpbXBsZSB2aXN0YSBzZSBwdWVkZSBvYnNlcnZhciBxdWUgc2UgZW5jdWVudHJhbiBtYXlvcm1lbnRlIGFncnVwYWRvcyBvIGNvbmdsb21lcmFkb3MgcG9yIHpvbmFzLCBzaWVuZG8gYXPDrSBxdWUgbGEgbWF5b3LDrWEgdml2ZSBlbiBBcG9kYWNhLg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KaGlzdChjb3BpYV9iYWphc19ubCRESVNUQU5DSUEuS00sIA0KICAgICBtYWluID0gIkhpc3RvZ3JhbWEgZGUgRGlzdGFuY2lhIChCQUpBUykiLCANCiAgICAgeGxhYiA9ICJEaXN0YW5jaWEgZW4ga20iLCANCiAgICAgeWxhYiA9ICJGcmVjdWVuY2lhIiwNCiAgICAgY29sID0gImRhcmtvcmFuZ2UzIiwNCiAgICAgYm9yZGVyID0gImJsYWNrIiwNCiAgICAgYnJlYWtzID0gIlNjb3R0IikNCmBgYA0KDQpFc3RlIGhpc3RvZ3JhbWEgbm9zIHBlcm1pdGUgdmlzdWFsaXphciBxdWUgbGEgZ3JhbiBtYXlvcsOtYSBkZSBwZXJzb25hcyBxdWUgcmVudW5jaW9yYW4gdml2w61hbiBhIHVuYSBkaXN0YW5jaWEgZGUgZW50cmUgMTIgeSAxNSBrbSBjb24gcmVzcGVjdG8gYSBsYSBkaXJlY2Npw7NuIGRlbCBzb2NpbyBmb3JtYWRvci4NCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCm1lZGlhbmFfYmFqYXNfbmwgPC0gbWVkaWFuKGNvcGlhX2JhamFzX25sJERJU1RBTkNJQS5LTSkNCg0KZ3J1cG9fY2VyY2FfbmwgPC0gY29waWFfYmFqYXNfbmxbY29waWFfYmFqYXNfbmwkRElTVEFOQ0lBLktNIDw9IG1lZGlhbmFfYmFqYXNfbmwsIF0NCmdydXBvX2xlam9zX25sIDwtIGNvcGlhX2JhamFzX25sW2NvcGlhX2JhamFzX25sJERJU1RBTkNJQS5LTSA+IG1lZGlhbmFfYmFqYXNfbmwsIF0NCg0KZnJlY3VlbmNpYV9jZXJjYV9ubCA8LSBucm93KGdydXBvX2NlcmNhX25sKQ0KZnJlY3VlbmNpYV9sZWpvc19ubCA8LSBucm93KGdydXBvX2xlam9zX25sKQ0KDQpjYXQoIkZyZWN1ZW5jaWEgZGUgZGF0b3MgQ0VSQ0EgZGUgbGEgbWVkaWFuYToiLCBmcmVjdWVuY2lhX2NlcmNhX25sLCAiXG4iKQ0KY2F0KCJGcmVjdWVuY2lhIGRlIGRhdG9zIExFSk9TIGRlIGxhIG1lZGlhbmE6IiwgZnJlY3VlbmNpYV9sZWpvc19ubCwgIlxuIikNCmBgYA0KRXN0ZSByZXN1bHRhZG8gbm9zIGluZGljYSBxdWUgZXhpc3RlbiBtw6FzIGJhamFzIHF1ZSBzZSBlbmN1ZW50cmFuIHBvciBkZWJham8gZGUgbGEgbWVkaWFuYSBkZSBkaXN0YW5jaWEgZW50cmUgbGEgdml2aWVuZGEgZGVsIGV4LWNvbGFib3JhZG9yIHkgbGEgZGlycmVjY2nDs24gZGVsIHNvY2lvIGZvcm1hZG9yLCBsbyBxdWUgcXVpZXJlIGRlY2lyIHF1ZSBlbnRyZSBtw6FzIGNlcmNhIHZpdmUgdW5hIHBlcnNvbmEgZGUgbGEgdWJpY2FjacOzbiBkZSBsYSBlbXByZXNhIG1heW9yIGVzIGxhIHByb2JhYmlsaWRhZCBkZSByZW51bmNpYXIuDQoNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmNvcGlhX2FjdHVhbGVzX25sIDwtIGNvcGlhX2FjdHVhbGVzX25sICU+JQ0KICBtdXRhdGUoRVNUQVRVUyA9ICJBQ1RJVk8iKQ0KY29waWFfYmFqYXNfbmwgPC0gY29waWFfYmFqYXNfbmwgJT4lDQogIG11dGF0ZShFU1RBVFVTID0gIklOQUNUSVZPIikNCg0KZGZfY29uc29saWRhZF9ubCA8LSBiaW5kX3Jvd3MoY29waWFfYmFqYXNfbmwsIGNvcGlhX2FjdHVhbGVzX25sKQ0KYGBgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpoaXN0KGRmX2NvbnNvbGlkYWRfbmwkRElTVEFOQ0lBLktNLCANCiAgICAgbWFpbiA9ICJIaXN0b2dyYW1hIGRlIERpc3RhbmNpYSAoQ09OU09MSURBRE8pIiwgDQogICAgIHhsYWIgPSAiRGlzdGFuY2lhIGVuIGttIiwgDQogICAgIHlsYWIgPSAiRnJlY3VlbmNpYSIsDQogICAgIGNvbCA9ICJvcmFuZ2UiLA0KICAgICBib3JkZXIgPSAiYmxhY2siLA0KICAgICBicmVha3MgPSAiU2NvdHQiKQ0KYGBgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQppbnRlcnZhbG9zX2Rpc3RhbmNpYSA8LSBjKDAsIDEsIDIsIDMsIDUsIDEwLCBJbmYpDQoNCmRmX2NvbnNvbGlkYWRfbmwkSU5ULkRJU1RBTkNJQSA8LSBjdXQoZGZfY29uc29saWRhZF9ubCRESVNUQU5DSUEuS00sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBpbnRlcnZhbG9zX2Rpc3RhbmNpYSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiMC0xIiwgIjEtMiIsICIyLTMiLCAiMy01IiwgIjUtMTAiLCAiMTArIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluY2x1ZGUubG93ZXN0ID0gVFJVRSkNCg0KdGMgPC0gdGFieWwoZGZfY29uc29saWRhZF9ubCwgSU5ULkRJU1RBTkNJQSwgRVNUQVRVUykNCmBgYA0KDQoNClRhYmxhIGRlIENvbnRpbmdlbmNpYQ0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnRjIDwtIHRjICU+JQ0KICBtdXRhdGUoVE9UQUwgPSByb3dTdW1zKGFjcm9zcyhjKCJBQ1RJVk8iLCAiSU5BQ1RJVk8iKSkpKQ0KDQp0YyA8LSB0YyAlPiUNCiAgbXV0YXRlKFBPUkNFTlRBSkUuQUNUSVZPID0gcm91bmQoQUNUSVZPIC8gVE9UQUwgKiAxMDApLA0KICAgICAgICAgUE9SQ0VOVEFKRS5JTkFDVElWTyA9IHJvdW5kKElOQUNUSVZPIC8gVE9UQUwgKiAxMDApKQ0KdGMNCmBgYA0KRXN0YSB0YWJsYSBkZSBjb250aW5nZW5jaWEgbm9zIG11ZXN0cmEgbG8gcXVlIGFudGVyaW9ybWVudGUgcGxhdGljYWJhbW9zLCBlbnRyZSBtYXlvciBlcyBsYSBkaXN0YW5jaWEgaGF5IG3DoXMgcHJvYmFiaWxpZGFkZXMgZGUgcXVlIGxhcyBwZXJzb25hcyBwZXJtYW5lemNhbiB0cmFiYWphbmRvIGRlbnRybyBkZSBsYSBlbXByZXNhLiBFc3RvIGxvIHBvZGVtb3MgZGV0ZXJtaW5hciBncmFjaWFzIGEgcXVlIGVsIHBvcmNlbnRhamUgZGUgcGVyc29uYXMgYWN0aXZhcyBlcyBtw6FzIGFsdG8gYSBwYXJ0aXIgZGUgMTUrIGtpbMOzbWV0cm9zIGRlIGRpc3RhbmNpYSwgY29uIHVuIDMyJSBkZSBwYXJ0aWNwYWNpw7NuIGNvbiByZXNwZWN0byBhIGxvcyBpbmFjdGl2b3MuDQoNCioqUmVzcHVlc3RhKioNCg0KU2ksIGxvcyByZXN1bHRhZG9zIG9idGVuaWRvcyBhIHBhcnRpciBkZWwgYW7DoWxpc2lzIGVzIHF1ZSBhIG1lbm9yIGRpc3RhbmNpYSBkZSBsYSBkaXJlY2Npw7NuIGRlbCBjb2xhYm9yYWRvciBjb24gcmVzcGVjdG8gYSBsYSBkaXJlY2Npw7NuIGRlbCBTb2NpbyBGb3JtYWRvciBoYXkgdW5hIG1heW9yIHByb2JhYmlsaWRhZCBkZSBxdWUgbGEgcGVyc29uYSByZW51bmNpZSwgeSBlbnRyZSBtYXlvciBzZWEgbGEgZGlzdGFuY2lhLCBoYXkgdW5hIG1heW9yIHByb2JhYmlsaWRhZCBkZSBxdWUgbGEgcGVyc29uYSBwZXJtYW5lemNhIGVuIGxhIGVtcHJlc2EuDQoNCiMjIyAqKkLDmlNRVUVEQSBERSBJTkZPUk1BQ0nDk04gWSBEQVRPUyoqDQoNCiMjIyMgKirCv1F1w6kgdGlwbyBkZSBpbmZvcm1hY2nDs24gLyBkYXRvcyBzb2xpY2l0YXLDrWFzIGFsIHNvY2lvIGZvcm1hZG9yIHBhcmEgbWVqb3JhciBFREE/KioNCg0KU2Vyw61hIGRlIHV0aWxpZGFkIGFwbGljYXIgdW5hIGVuY3Vlc3RhIGFsIHBlcnNvbmFsIGRlbCDDoXJlYSBkZSBwcm9kdWNjacOzbiwgZGljaGEgZW5jdWVzdGEgeWEgZnVlIGRpc2XDsWFkYSBwb3IgZWwgZGUgZXF1aXBvIEVOSUdNQSBBTkFMWVRJQ1MuDQoNCkVzdGEgZW5jdWVzdGEgbm9zIHJldmVsYXLDoSBlbCBjbGltYSBvcmdhbml6YWNpb25hbCBxdWUgcGVyY2liZW4gbG9zIGVtcGxlYWRvcyBkZSBGT1JNLiBEZSBlc3RhIG1hbmVyYSwgc2UgcG9kcsOhIHNhYmVyIGNvbiBtYXlvciBjbGFyaWRhZCBjdcOhbGVzIHNvbiBsb3MgYXNwZWN0b3MgcXVlIG9jYXNpb25hbiBsYSByb3RhY2nDs24gZGUgcGVyc29uYWwsIHkgYXNpIGNyZWFyIGVzdHJhdGVnaWFzIGEgY29ydG8geSBsYXJnbyBwbGF6byBwYXJhIG1lam9yYXIgZWwgcHJvYmxlbWEuIA0KDQojIyMjICoqTGluayBkZWwgY3Vlc3Rpb25hcmlvKioNCmh0dHBzOi8vZG9jcy5nb29nbGUuY29tL2Zvcm1zL2QvZS8xRkFJcFFMU2ZVQnNvMTdsWG41ZjZaY0RheUJKVkpWYjdENDRqMV9PcTFWRElWT3cwNE1Nejlody92aWV3Zm9ybT91c3A9c2hhcmluZw0KDQojIyMjICoqwr9RdcOpIHRpcG8gZGUgaW5mb3JtYWNpw7NuIC8gZGF0b3MgZGUgZnVlbnRlcyBzZWN1bmRhcmlhcyBidXNjYXLDrWFzIHBhcmEgbWVqb3JhciBFREE/KioNCg0KMS4gQ2FudGlkYWQgZGUgZW1wbGVhZG9zIHkgZW1wbGVhZGFzIHF1ZSByZWNpYmVuIGNhcGFjaXRhY2nDs24gZW4gbGEgw6FyZWEgZGUgRWxhYm9yYWNpw7NuIGRlIFByb2R1Y3RvcyBkZSBQYXBlbCB5IENhcnTDs24uDQoNCjIuIENhbnRpZGFkIGRlIGVtcGxlYWRvcyBxdWUgY3VlbnRhbiBjb24gU2VndXJvcyBkZSBHYXN0b3MgTcOpZGljb3MgTWF5b3JlcyBlbiBsYSDDoXJlYSBkZSBFbGFib3JhY2nDs24gZGUgUHJvZHVjdG9zIGRlIFBhcGVsIHkgQ2FydMOzbi4NCg0KMy4gQ2FudGlkYWQgZGUgZW1wbGVhZG9zIHkgZW1wbGVhZGFzIHF1ZSBjdWVudGFuIGNvbiBsYXMgcHJlc3RhY2lvbmVzIGLDoXNpY2FzIGRlIGxleSBlbiBsYSDDoXJlYSBkZSBFbGFib3JhY2nDs24gZGUgUHJvZHVjdG9zIGRlIFBhcGVsIHkgQ2FydMOzbi4NCg0KNC4gQ2FudGlkYWQgZGUgZW1wbGVhZG9zIHkgZW1wbGVhZGFzIHF1w6kgY3VlbnRhbiBjb24gdW4gcHJvZ3JhbWEgZGUgYWhvcnJvL2ludmVyc2nDs24gZW4gbGEgw6FyZWEgZGUgRWxhYm9yYWNpw7NuIGRlIFByb2R1Y3RvcyBkZSBQYXBlbCB5IENhcnTDs24uDQoNCiMjIyMgKipCdXNjYXIgaW5mb3JtYWNpw7NuIC8gZGF0b3MgZGUgZnVlbnRlcyBzZWN1bmRhcmlhcyoqDQoNCiMjIyMjIERhdG9zIHNvYnJlIEFydGVzYW5vcyB5IFRyYWJhamFkb3JlcyBlbiBsYSBFbGFib3JhY2nDs24gZGUgUHJvZHVjdG9zIGRlIFBhcGVsIHkgQ2FydMOzbi4NCg0KRGUgYWN1ZXJkbyBhbCBHb2JpZXJubyBkZSBNw6l4aWNvLCBlbiBlbCBwcmltZXIgdHJpbWVzdHJlIGRlIDIwMjMgbGEgZnVlcnphIGxhYm9yYWwgc2UgZGl2aWRpw7MgZGUgbGEgc2lndWllbnRlIG1hbmVyYSwgMjkuNyUsIHkgNzAuMyAlIG11amVyZXM7IGNhYmUgcmVjYWxjYXIgcXVlIGxvcyBob21icmVzIHJlY2liaWVyb24gdW4gc2FsYXJpbyBwcm9tZWRpbyBtZW5zdWFsIGRlICQ0LjA2IGsgTXhuIHkgbGFzIG11amVyZXMgJDIuNiBrIE14biBhbHJlZGVkb3IgZGUgbGEgcmVww7pibGljYS4gRXN0byBub3MgY29uZmlybWEgcXVlIGVuIGVmZWN0byBzaWd1ZSBleGlzdGllbmRvIHVuIHRlbWEgZGUgZGVzaWd1YWxkYWQgZGUgcGFnYSBwb3IgY3Vlc3Rpb25lcyBkZSBnw6luZXJvLCBlc3RvcyBwcm9ibGVtYXMgcHVlZGVuIGNhdXNhciBpbmNvbmZvcm1pZGFkIGVuIGxhcyBtdWplcmVzIHRyYmFqYWRvcmFzIHkgcXVlIHBvciBlbmRlIGJ1c3F1ZW4gdHJhYmFqbyBlbiBvdHJhIGluZHVzdHJpYSBvIHRlbmdhbiBxdcOpIGJ1c2NhciB1biBzZWd1bmRvIHRyYWJham8sIHkgZGViaWRvIGFsIGNhbmNhbmNpYSBhY3VtdWxhZG8sIGxlcyBjdWVzdGUgZGFyIGVsIDEwMCUgZW4gc3VzIHRyYWJham9zLiBIYXkgZGlmZXJlbnRlcyBkaXNwYXJpZGFkIGRlIHNhbGFyaW9zIGFscmVkZWRvciBkZSBsYSBSZXDDumJsaWNhLCBlbiBlbCBjYXNvIGRlbCBlc3RhZG8gZGUgTnVldm8gTGXDs24sIGRlIGFjdWVyZG8gY29uIHVuIGFuw6FsaXNpcyByZWFsaXphZG8gcG9yIGVsIENlbnRybyBkZSBJbnZlc3RpZ2FjaW9uZXMgRWNvbsOzbWljYXMgZGUgbGEgVUFOTCwgZW4gZWwgw6FtYml0byBsYWJvcmFsIGxhcyBtdWplcmVzIGdhbmFuIDQyJSBtZW5vcyBpbmdyZXNvcyBlbiBwcm9tZWRpbyBwb3IgaG9yYSBxdcOpIGxvcyBob21icmVzLiBFbiBlc3RlIGNhc28gc2UgcmVjb21pZW5kYSBhIEZPUk0gcmV2aXNhciBzaSBlc3RlIGZlbsOzbWVubyBzZSBlbmN1ZW50cmEgcHJlc2VudGUgZW4gbGEgZW1wcmVzYSwgeWEgcXVlIGVuIGNhc28gZGUgcXXDqSBleGlzdGEsIGVzdG8gcG9kcsOtYSBzZXIgdW5hIGRlIGxhcyByYXpvbmVzIHBvciBsYXMgY3VhbGVzIHRpZW5lbiBiYWphcyBsYWJvcmFsZXMuDQoNClNlZ8O6biBEYXRhIE3DqXhpY28sIGxvcyBtZWpvcmVzIHNhbGFyaW9zIHByb21lZGlvIG1lbnN1YWxlcyBwYXJhIGxhcyBwZXJzb25hcyBxdWUgdHJhYmFqYW4gZW4gbGEgSW5kdXN0cmlhIGRlIGxhIEVsYWJvcmFjacOzbiBkZSBQcm9kdWN0b3MgZGUgUGFwZWwgeSBDYXJ0w7NuLCBmdWVyb24gZW5jb250cmFkb3MgZW4gbG9zIGVzdGFkb3MgZGUgTnVldm8gTGXDs24gY29uIHVuIHRvdGFsIGRlICQ4LjZrIE14biwgVGxheGNhbGEgY29uICQ3LjM0IGsgTXhuIHkgQ0RNWCBjb24gdW4gdG90YWwgZGUgJDUuNzMgayBNeG4uIEFob3JhIGJpZW4gc2kgYmllbiBlbCBzYWxhcmlvIHByb21lZGlvIGVzIG1heW9yLCBlc28gbm8gc2lnbmlmaWNhIHF1ZSBsYXMgcGVyc29uYXMgc2VhbiBtw6FzIGZpZWxlcyBhIHN1cyBlbXByZXNhcyBwcm8gZXN0ZSBtb3Rpdm8sIHlhIHF1w6kgY29tbyB2aW1vcyBlbiBGT1JNIGEgcGVzYXIgZGUgdGVuZXIgdW4gc2FsYXJpbyBkaWdubyBzaWd1ZW4gc3VmcmllbmRvIGRlIGJhamFzIGxhYm9yYWxlcy4NCg0KSWd1YWwgRGF0YSBNZXhpY28gY29tcGFydGUgcXXDqSBsYSBlZGFkIHByb21lZGlvIGRlIGxhIGZ1ZXJ6YSBsYWJvcmFsIGRlIGVzdGEgaW5kdXN0cmlhIGVzIGRlIGFscmVkZWRvciBkZSA0MSBhw7FvcywgZXN0byBlcyB1biBhcHJveGltYWRvLCBwZXJvIHRhbWJpw6luIGVzIGltcG9ydGFudGUgZXN0ZSBkYXRvLCB5YSBxdWUgc2VndXJhbWVudGUgZXN0YSBnZW50ZSBjdWVudGEgY29uIGZhbWlsaWEgZSBoaWpvcywgbG9zIGN1YWxlcyBkZWJlbiBkZSBjdWlkYXIgeSBzZWd1cmFtZW50ZSBkZXNwdcOpcyBkZWwgdHJhYmFqbywgbGxlZ2FuIGEgZXN0ZSBzZWd1bmRvIHR1cm5vIGVuIGRvbmRlIGRlYmVuIGRlIGN1aWRhciBhIGFsZ3Vpw6luIG3DoXMgeSBubyBkZXNjYW5zYW4gZGUgbWFuZXJhIGFwcm9waWFkYTsgY2F1c2FuZG8gZWZlY3RvcyBubyB0YW4gcG9zaXRpdm9zIGVuIHN1IGRlc2VtcGXDsW8gbGFib3JhbCwgZW4gYWxndW5hIHBlcnNvbmEgZGVsIHBlcnNvbmFsLg0KDQoNCiMjICoqKlBBUlRFIElJSSAtIFJFRkxFWEnDk04qKioNCg0KIyMjICoqSEFMTEFaR09TKioNCg0KMS4gTGEgKip0ZW1wZXJhdHVyYSoqIHJlc3VsdMOzIHRlbmVyIG3DoXMgcmVsZXZhbmNpYSBkZSBsYSBzZSBoYWLDrWEgcHJldmlzdG8sIGNvbnZpcnRpw6luZG9zZSBlbiB1bm8gZGUgbG9zIGZhY3RvcmVzIGRlIGxhIG5vIHNhdGlzZmFjY2nDs24gbGFib3JhbC4NCjIuIExhICoqdGVtcG9yYWRhKiogY29uIG3DoXMgYmFqYXMgZGUgZW1wbGVhZG9zIGRpZmllcmUgY29uIGxhIG9waW5pw7NuIHF1ZSBlbCBDRU8gaGFiw61hIHByb3BvcmNpb25hZG8uIA0KMy4gRWwgKipwdWVzdG8gZGUgdHJhYmFqbyoqIGNvbiBtw6FzIGVtcGxlYWRvcyBlcyBlbCBkZSBheXVkYW50ZSBnZW5lcmFsLCBkb25kZSBsbyBvY3VwYW4gcHJpbmNpcGFsbWVudGUgbXVqZXJlcy4NCjQuIERlbnRybyBkZWwgYWN0dWFsICoqcGVyZmlsIGRlIGVtcGxlYWRvKiogc2UgZW5jb250csOzIHF1ZSBubyBoYXkgaG9tYnJlcyBkaXZvcmNpYWRvcyB0cmFiYWphbmRvIGVuIGxhIHBsYW50YS4NCjUuIFNpbiBpbXBvcnRhciBlbCBnw6luZXJvLCBsYSBlZGFkIG8gYWxnw7puIG90cm8gZmFjdG9yLCBlbCBtb3Rpdm8gbcOhcyBjb23Dum4gcG9yIGVsIGN1YWwgdW4gZW1wbGVhZG8gc2UgZGEgZGUgYmFqYSBlcyBwb3IgKipmYWx0YSBkZSBhc2lzdGVuY2lhKiouIA0KDQojIyMgKipTVUdFUkVOQ0lBUyoqDQoNCkdyYWNpYXMgYSBsYSBjaGFybGEgcXVlIHNlIHR1dm8gY29uIGxvcyBHdWVzdCBTcGVha2VycyB5IGRlc3B1w6lzIGRlIHJlYWxpemFyIHVuIHByaW1lciBhY2VyY2FtaWVudG8gY29uIEZPUk0sIHNpbiBkdWRhIGVsIFV0aWxpemFyIGxhIGFuYWzDrXRpY2EgZGUgZGF0b3MgYmVuZWZpY2lhcsOtYSBhbXBsaWFtZW50ZSBhIGxhIGVtcHJlc2EgcGFyYSBtZWpvcmFyIGxhIHNhdGlzZmFjY2nDs24gbGFib3JhbCBkZSBzdXMgZW1wbGVhZG9zLiBBcXXDrSBoYXkgYWxndW5hcyBlc3RyYXRlZ2lhcyBxdWUgcG9kcsOtYW4gc2VndWlyOg0KDQoxLiAqKkFuw6FsaXNpcyBkZSBjbGltYSBsYWJvcmFsOioqIFV0aWxpemFyIGVuY3Vlc3RhcyBwYXJhIG1lZGlyIGVsIGNsaW1hIGxhYm9yYWwgeSBsYSBzYXRpc2ZhY2Npw7NuIGRlIGxvcyBlbXBsZWFkb3MuIElkZW50aWZpY2FyIMOhcmVhcyBwcm9ibGVtw6F0aWNhcyB5IHRvbWFyIG1lZGlkYXMgZXNwZWPDrWZpY2FzIHBhcmEgYWJvcmRhcmxhcy4NCg0KMi4gKipQcm9ncmFtYXMgZGUgYmllbmVzdGFyOioqIFVzYXIgZGF0b3MgcGFyYSBpZGVudGlmaWNhciBsYXMgbmVjZXNpZGFkZXMgZGUgYmllbmVzdGFyIGRlIGxvcyBlbXBsZWFkb3MgeSBkaXNlw7FhciBwcm9ncmFtYXMgcXVlIHByb211ZXZhbiBsYSBzYWx1ZCBmw61zaWNhIHkgbWVudGFsLCBjb21vIGFjdGl2aWRhZGVzIGRlcG9ydGl2YXMsIGFzZXNvcmFtaWVudG8gcHNpY29sw7NnaWNvIG8gam9ybmFkYXMgZGUgdHJhYmFqbyBmbGV4aWJsZXMuDQoNCjMuICoqR2VzdGnDs24gZGVsIGRlc2VtcGXDsW86KiogVXRpbGl6YXIgZGF0b3MgcGFyYSBldmFsdWFyIHkgbWVqb3JhciBlbCBwcm9jZXNvIGRlIGdlc3Rpw7NuIGRlbCBkZXNlbXBlw7FvLiBQcm9wb3JjaW9uYXIgcmV0cm9hbGltZW50YWNpw7NuIGJhc2FkYSBlbiBkYXRvcyB5IGVzdGFibGVjZXIgbWV0YXMgcmVhbGlzdGFzIHBhcmEgbG9zIGVtcGxlYWRvcy4NCg0KNC4gKipFcXVpbGlicmlvIHRyYWJham8tdmlkYToqKiBBbmFsaXphciBkYXRvcyBkZSBob3JhcyBkZSB0cmFiYWpvIHkgYXVzZW50aXNtbyBwYXJhIGdhcmFudGl6YXIgdW4gZXF1aWxpYnJpbyBhZGVjdWFkbyBlbnRyZSBlbCB0cmFiYWpvIHkgbGEgdmlkYSBwZXJzb25hbC4gSW1wbGVtZW50YXIgcG9sw610aWNhcyBxdWUgZm9tZW50ZW4gdW4gZXF1aWxpYnJpbyBzYWx1ZGFibGUuDQoNCg0KIyMgKioqUEFSVEUgSVYgLSBSRUZFUkVOQ0lBUyoqKg0KDQojIyMgKipSZWZlcmVuY2lhcyBQYXJ0ZSBJKioNCg0KQWRtaW4uICgyMDIzKS4gUHJvdmVlZG9yYSBtZXhpY2FuYSBkZSBlbXBhcXVlcyBlY29sw7NnaWNvcyBhcHVlc3RhIHBvciBzZWN0b3IgYXV0b21vdHJpeiBkZSBFc3RhZG9zIFVuaWRvcy4gRm9ybS4gaHR0cHM6Ly9mb3JtLmNvbS5teC9wcm92ZWVkb3JhLW1leGljYW5hLWRlLWVtcGFxdWVzLWVjb2xvZ2ljb3MtYXB1ZXN0YS1wb3Itc2VjdG9yLWF1dG9tb3RyaXotZGUtZXN0YWRvcy11bmlkb3MvDQoNCkNlcGVkYSwgRi4gKDIwMjMsIEphbnVhcnkgMTIpLiBQcmVwYXJhIEZPUk0gcGxhbiBwYXJhIGNvbXBldGlyIGVuIEVVLiBFbCBGaW5hbmNpZXJvLiBodHRwczovL3d3dy5lbGZpbmFuY2llcm8uY29tLm14L21vbnRlcnJleS8yMDIzLzAxLzEyL3ByZXBhcmEtZm9ybS1wbGFuLXBhcmEtY29tcGV0aXItZW4tZXUvDQoNCkZhYnJpY2FjacOzbiBkZSBQcm9kdWN0b3MgZGUgQ2FydMOzbiB5IFBhcGVsOiBTYWxhcmlvcywgcHJvZHVjY2nDs24sIGludmVyc2nDs24sIG9wb3J0dW5pZGFkZXMgeSBjb21wbGVqaWRhZCB8IERhdGEgTcOpeGljby4gKDIwMjMpLiBEYXRhIE3DqXhpY28uIEFjY2VzbzogQWdvc3RvIDE4LCAyMDIzLCBkZTogaHR0cHM6Ly93d3cuZWNvbm9taWEuZ29iLm14L2RhdGFtZXhpY28vZXMvcHJvZmlsZS9pbmR1c3RyeS9jb252ZXJ0ZWQtcGFwZXItcHJvZHVjdC1tYW51ZmFjdHVyaW5nP2ludmVzdG1lbnRGZGlUaW1lPVllYXINCg0KQ29tZXJjaW8gYWwgcG9yIE1lbm9yIGRlIFBhcnRlcyB5IFJlZmFjY2lvbmVzIHBhcmEgQXV0b23Ds3ZpbGVzLCBDYW1pb25ldGFzIHkgQ2FtaW9uZXM6IFNhbGFyaW9zLCBwcm9kdWNjacOzbiwgaW52ZXJzacOzbiwgb3BvcnR1bmlkYWRlcyB5IGNvbXBsZWppZGFkIHwgRGF0YSBNw6l4aWNvLiAoMjAyMykuIERhdGEgTcOpeGljby4gQWNjZXNvOiBBZ29zdG8gMTgsIDIwMjMsIGRlOmh0dHBzOi8vd3d3LmVjb25vbWlhLmdvYi5teC9kYXRhbWV4aWNvL2VzL3Byb2ZpbGUvaW5kdXN0cnkvcmV0YWlsLXRyYWRlLW9mLXNwYXJlLXBhcnRzLWZvci1jYXJzLWFuZC10cnVja3M/Z2VuZGVyT3JJbmZvcm1hbD10b3RhbE9wdGlvbiZ5ZWFyU2VsZWN0b3JHZHA9dGltZU9wdGlvbjAmaW52ZXN0bWVudEZkaVRpbWU9WWVhcg0KDQpGYWJyaWNhY2nDs24gZGUgQXV0b23Ds3ZpbGVzIHkgQ2FtaW9uZXM6IFNhbGFyaW9zLCBwcm9kdWNjacOzbiwgaW52ZXJzacOzbiwgb3BvcnR1bmlkYWRlcyB5IGNvbXBsZWppZGFkIHwgRGF0YSBNw6l4aWNvLiAoMjAyMykuIERhdGEgTcOpeGljby4gQWNjZXNvOiBBZ29zdG8gMTgsIDIwMjMsIGRlOiBodHRwczovL3d3dy5lY29ub21pYS5nb2IubXgvZGF0YW1leGljby9lcy9wcm9maWxlL2luZHVzdHJ5L21vdG9yLXZlaGljbGUtbWFudWZhY3R1cmluZz95ZWFyU2VsZWN0b3JHZHA9dGltZU9wdGlvbjANCg0KU3RhdGlzdGEgUmVzZWFyY2ggRGVwYXJ0bWVudC4gKDIwMTMsIFNlcHRpZW1icmUgMzApLiBJbmR1c3RyeSByZXZlbnVlIG9mIOKAnE90aGVyIGF1dG9tb3RpdmUgdmVoaWNsZSBwYXJ0cyBtYW51ZmFjdHVyaW5n4oCcIGluIE1leGljbyBmcm9tIDIwMTIgdG8gMjAyNC4gU3RhdGlzdGEuIEFjY2VzbzogQWdvc3RvIDE4LCAyMDIzLCBkZTogaHR0cHM6Ly8wLXd3dy1zdGF0aXN0YS1jb20uYmlibGlvdGVjYS1pbHMudGVjLm14L2ZvcmVjYXN0cy8xMTcwODMxL290aGVyLWF1dG9tb3RpdmUtdmVoaWNsZS1wYXJ0cy1tYW51ZmFjdHVyaW5nLXJldmVudWUtaW4tbWV4aWNvDQoNCkNhcmxpZXIsIE0uICgyMDIxLCBPY3R1YnJlIDI2KS4gVHJhbnNwb3J0YXRpb24gJiBMb2dpc3RpY3PigLogVmVoaWNsZXMgJiBSb2FkIFRyYWZmaWMgQXV0b21vdGl2ZSBpbmR1c3RyeSBpbiBNZXhpY28gLSBzdGF0aXN0aWNzICYgZmFjdHMuIFN0YXRpc3RhLiBBY2Nlc286IEFnb3N0byAxOCwgMjAyMywgZGU6ICBodHRwczovLzAtd3d3LXN0YXRpc3RhLWNvbS5iaWJsaW90ZWNhLWlscy50ZWMubXgvdG9waWNzLzcyNDkvYXV0b21vdGl2ZS1pbmR1c3RyeS1pbi1tZXhpY28vI3RvcGljT3ZlcnZpZXcNCg0KRXVyb21vbml0b3IgSW50ZXJuYXRpb25hbC4gKDIwMjIsIERpY2llbWJyZSA3KS4gQ29ycnVnYXRlZCBQYXBlciwgUGFwZXJib2FyZCBhbmQgQ29udGFpbmVycyBpbiBNZXhpY286IElTSUMgMjEwMi4gUGFzc3BvcnQgRXVyb21vbml0b3IuIEFjY2VzbzogQWdvc3RvIDE4LCAyMDIzLCBkZTogIGh0dHBzOi8vd3d3LnBvcnRhbC5ldXJvbW9uaXRvci5jb20vYW5hbHlzaXMvdGFiDQoNCkZPUk0uICgyMDIzKS4gUHJvdmVlZG9yYSBtZXhpY2FuYSBkZSBlbXBhcXVlcyBlY29sw7NnaWNvcyBhcHVlc3RhIHBvciBzZWN0b3IgYXV0b21vdHJpeiBkZSBFc3RhZG9zIFVuaWRvcy4gRm9ybS4gQWNjZXNvOiBBZ29zdG8gMTgsIDIwMjMsIGRlOiBodHRwczovL2Zvcm0uY29tLm14L3Byb3ZlZWRvcmEtbWV4aWNhbmEtZGUtZW1wYXF1ZXMtZWNvbG9naWNvcy1hcHVlc3RhLXBvci1zZWN0b3ItYXV0b21vdHJpei1kZS1lc3RhZG9zLXVuaWRvcy8NCg0KVS5TLiBhdXRvbW90aXZlIGFmdGVybWFya2V0IGluZHVzdHJ5IHNpemUgcmVwb3J0LCAyMDMwLiBVLlMuIEF1dG9tb3RpdmUgQWZ0ZXJtYXJrZXQgSW5kdXN0cnkgU2l6ZSBSZXBvcnQsIDIwMzAuIChuLmQuLWEpLiBodHRwczovL3d3dy5ncmFuZHZpZXdyZXNlYXJjaC5jb20vaW5kdXN0cnktYW5hbHlzaXMvdXMtYXV0b21vdGl2ZS1hZnRlcm1hcmtldCANCg0KUHVibGljYWRvIHBvciBBYmlnYWlsIE9yw7pzLCAmIDIwMjMsIDI4IGZlYi4gKDIwMjNhLCBGZWJydWFyeSAyOCkuIEF1dG9tw7N2aWxlczogVmVudGFzIHBvciBmYWJyaWNhbnRlIEVzdGFkb3MgVW5pZG9zIDIwMjEtMjAyMi4gU3RhdGlzdGEuIGh0dHBzOi8vZXMuc3RhdGlzdGEuY29tL2VzdGFkaXN0aWNhcy82MzQyNjEvZXN0YWRvcy11bmlkb3MtdmVudGFzLWRlLWF1dG9tb3ZpbGVzLXBvci1mYWJyaWNhbnRlLWRpY2llbWJyZS8gDQoNCkluZm9ybWUgZGVsIE1lcmNhZG8gQXV0b21vdHJpeiBkZSBBbcOpcmljYSBkZWwgTm9ydGU6IFRhbWHDsW8sIFBhcnRpY2lwYWNpw7NuLCBDcmVjaW1pZW50byB5IFRlbmRlbmNpYXMgKDIwMjItMjcpLiBJbmZvcm1lIGRlbCBtZXJjYWRvIGF1dG9tb3RyaXogZGUgQW3DqXJpY2EgZGVsIE5vcnRlIHwgVGFtYcOxbywgcGFydGljaXBhY2nDs24sIGNyZWNpbWllbnRvIHkgdGVuZGVuY2lhcyAoMjAyMi0yNykuIChuLmQuKS4gaHR0cHM6Ly93d3cubW9yZG9yaW50ZWxsaWdlbmNlLmNvbS9lcy9pbmR1c3RyeS1yZXBvcnRzL25vcnRoLWFtZXJpY2EtYXV0b21vdGl2ZS1tYXJrZXQjOn46dGV4dD1Fc3RhZG9zJTIwVW5pZG9zJTIwZXMlMjB1bmElMjBkZSxxdWUlMjBlbCUyMGHDsW8lMjBhbnRlcmlvciUyQyUyMDIwMTkuIA0KDQpEaWF6LCBMLiBPLiAoMjAyMywgQXByaWwgMTEpLiBUZXhhcyB5IHN1IHJlbGV2YW5jaWEgZW4gbGEgaW5kdXN0cmlhIGF1dG9tb3RyaXouIFNQQyBQcm8uIGh0dHBzOi8vc3BjcHJvLmNvbS8yMDIzLzA0L3RleGFzLXktc3UtcmVsZXZhbmNpYS1lbi1sYS1pbmR1c3RyaWEtYXV0b21vdHJpei8jOn46dGV4dD1FbCUyMHNlY3RvciUyMGF1dG9tb3RyaXolMjBlbiUyMFRleGFzLFRveW90YSUyQyUyMEdlbmVyYWwlMjBNb3RvcnMlMjB5JTIwVGVzbGEuIA0KDQojIyMgKipSZWZlcmVuY2lhcyBQYXJ0ZSBJSSoqDQoNCiMjIyMgKlNpdHVhY2nDs24gUHJvYmxlbWEgMSoNCg0KU3RhdGlzdGEgUmVzZWFyY2ggRGVwYXJ0bWVudC4gKDIwMjEsIFNlcHRlbWJlciAzMCkuIEluZHVzdHJ5IHJldmVudWUgb2Yg4oCcYWVyb3NwYWNlIHByb2R1Y3QgYW5kIHBhcnRzIG1hbnVmYWN0dXJpbmfigJwgaW4gVGV4YXMgZnJvbSAyMDEyIHRvIDIwMjQuIFN0YXRpc3RhLiBSZXRyaWV2ZWQgQXVndXN0IDMwLCAyMDIzLCBmcm9tIGh0dHBzOi8vMC13d3ctc3RhdGlzdGEtY29tLmJpYmxpb3RlY2EtaWxzLnRlYy5teC9mb3JlY2FzdHMvMTIwNTA5Ni9hZXJvc3BhY2UtcHJvZHVjdC1hbmQtcGFydHMtbWFudWZhY3R1cmluZy1yZXZlbnVlLWluLXRleGFzDQoNCkR1biAmIEJyYWRzdHJlZXQuIChuLmQuKS4gQWVyb3NwYWNlIFByb2R1Y3QgQW5kIFBhcnRzIE1hbnVmYWN0dXJpbmcgQ29tcGFuaWVzIEluIFNhbiBBbnRvbmlvLCBUZXhhcywgVW5pdGVkIFN0YXRlcyBPZiBBbWVyaWNhLiBSZXRyaWV2ZWQgQXVndXN0IDMwLCAyMDIzLCBmcm9tIGh0dHBzOi8vd3d3LmRuYi5jb20vYnVzaW5lc3MtZGlyZWN0b3J5L2NvbXBhbnktaW5mb3JtYXRpb24uYWVyb3NwYWNlX3Byb2R1Y3RfYW5kX3BhcnRzX21hbnVmYWN0dXJpbmcudXMudGV4YXMuc2FuX2FudG9uaW8uaHRtbA0KDQpTdGF0aXN0YSBSZXNlYXJjaCBEZXBhcnRtZW50LiAoMjAyMWIsIFNlcHRlbWJlciAzMCkuIEluZHVzdHJ5IHJldmVudWUgb2Yg4oCcbW90b3IgdmVoaWNsZSBhbmQgcGFydHMgZGVhbGVyc+KAnCBpbiBUZXhhcyBmcm9tIDIwMTIgdG8gMjAyNC4gU3RhdGlzdGEuIFJldHJpZXZlZCBBdWd1c3QgMzAsIDIwMjMsIGZyb20gaHR0cHM6Ly8wLXd3dy1zdGF0aXN0YS1jb20uYmlibGlvdGVjYS1pbHMudGVjLm14L2ZvcmVjYXN0cy8xMjA1MzI0L21vdG9yLXZlaGljbGUtYW5kLXBhcnRzLWRlYWxlcnMtcmV2ZW51ZS1pbi10ZXhhcw0KDQpEdW4gJiBCcmFkc3RyZWV0LiAobi5kLi1iKS4gTW90b3IgVmVoaWNsZSBQYXJ0cyBNYW51ZmFjdHVyaW5nIENvbXBhbmllcyBJbiBTYW4gQW50b25pbywgVGV4YXMsIFVuaXRlZCBTdGF0ZXMgT2YgQW1lcmljYS4gUmV0cmlldmVkIEF1Z3VzdCAzMCwgMjAyMywgZnJvbSBodHRwczovL3d3dy5kbmIuY29tL2J1c2luZXNzLWRpcmVjdG9yeS9jb21wYW55LWluZm9ybWF0aW9uLm1vdG9yX3ZlaGljbGVfcGFydHNfbWFudWZhY3R1cmluZy51cy50ZXhhcy5zYW5fYW50b25pby5odG1sDQoNClN0YXRpc3RhIFJlc2VhcmNoIERlcGFydG1lbnQuICgyMDIxYiwgU2VwdGVtYmVyIDMwKS4gSW5kdXN0cnkgcmV2ZW51ZSBvZiDigJxtZWRpY2FsIGVxdWlwbWVudCBhbmQgc3VwcGxpZXMgbWFudWZhY3R1cmluZ+KAnCBpbiBUZXhhcyBmcm9tIDIwMTIgdG8gMjAyNC4gU3RhdGlzdGEuIFJldHJpZXZlZCBBdWd1c3QgMzAsIDIwMjMsIGZyb20gaHR0cHM6Ly8wLXd3dy1zdGF0aXN0YS1jb20uYmlibGlvdGVjYS1pbHMudGVjLm14L2ZvcmVjYXN0cy8xMjA1MjI2L21lZGljYWwtZXF1aXBtZW50LWFuZC1zdXBwbGllcy1tYW51ZmFjdHVyaW5nLXJldmVudWUtaW4tdGV4YXMNCg0KRHVuICYgQnJhZHN0cmVldC4gKG4uZC4tYikuIE1lZGljYWwgRXF1aXBtZW50IEFuZCBTdXBwbGllcyBNYW51ZmFjdHVyaW5nIENvbXBhbmllcyBJbiBTYW4gQW50b25pbywgVGV4YXMsIFVuaXRlZCBTdGF0ZXMgT2YgQW1lcmljYS4gUmV0cmlldmVkIEF1Z3VzdCAzMCwgMjAyMywgZnJvbSBodHRwczovL3d3dy5kbmIuY29tL2J1c2luZXNzLWRpcmVjdG9yeS9jb21wYW55LWluZm9ybWF0aW9uLm1lZGljYWxfZXF1aXBtZW50X2FuZF9zdXBwbGllc19tYW51ZmFjdHVyaW5nLnVzLnRleGFzLnNhbl9hbnRvbmlvLmh0bWwNCg0KIyMjIyAqU2l0dWFjacOzbiBQcm9ibGVtYSAyKg0KDQpFbiBOdWV2byBMZcOzbiBsYXMgbXVqZXJlcyBnYW5hbiBlbiBwcm9tZWRpbyw0MiUgbWVub3MgaW5ncmVzb3MgcG9yIGhvcmEgcXVlIGxvcyBob21icmVzOiBVQU5MLiAoMjAyMywgTWFyY2ggOCkuIEVMIEVDT05PTUlTVEEuIFJldHJpZXZlZCBTZXB0ZW1iZXIgMSwgMjAyMywgZnJvbSBodHRwczovL3d3dy5lbGVjb25vbWlzdGEuY29tLm14L2VzdGFkb3MvRW4tTnVldm8tTGVvbi1sYXMtbXVqZXJlcy1nYW5hbi1lbi1wcm9tZWRpbzQyLW1lbm9zLWluZ3Jlc29zLXBvci1ob3JhLXF1ZS1sb3MtaG9tYnJlcy1VQU5MLTIwMjMwMzA4LTAwODQuaHRtbA0KDQpBcnRlc2Fub3MgeSBUcmFiYWphZG9yZXMgZW4gbGEgRWxhYm9yYWNpw7NuIGRlIFByb2R1Y3RvcyBkZSBQYXBlbCB5IENhcnTDs24uICgyMDIzKS4gRGF0YSBNZXhpY28uIFJldHJpZXZlZCBTZXB0ZW1iZXIgMSwgMjAyMywgZnJvbSBodHRwczovL3d3dy5lY29ub21pYS5nb2IubXgvZGF0YW1leGljby9lcy9wcm9maWxlL29jY3VwYXRpb24vYXJ0ZXNhbm9zLXktdHJhYmFqYWRvcmVzLWVuLWxhLWVsYWJvcmFjaW9uLWRlLXByb2R1Y3Rvcy1kZS1wYXBlbC15LWNhcnRvbg0KDQpFbCBUaWVtcG8gZW4gTW9udGVycmV5IGVuIDIwMjIgKE3DqXhpY28pIC0gV2VhdGhlciBTcGFyay4gKHMuwqBmLikuIFdlYXRoZXIgU3BhcmsuIGh0dHBzOi8vZXMud2VhdGhlcnNwYXJrLmNvbS9oL3kvNTE1NC8yMDIyL0RhdG9zLWhpc3QlQzMlQjNyaWNvcy1tZXRlb3JvbCVDMyVCM2dpY29zLWRlLTIwMjItZW4tTW9udGVycmV5LU0lQzMlQTl4aWNvI0ZpZ3VyZXMtVGVtcGVyYXR1cmUNCg0KIyMgKioqQU5FWE9TKioqDQoNCiMjIyAqKktJQ0sgT0ZGIFkgVklTSVRBIEEgTEEgUExBTlRBKioNCg0KIyMjIyBJTkZPUk1BQ0lPTiBERSBMQSBFTVBSRVNBIHkgSEFMTEFaR09TDQoNCkZPUk0gZXMgdW5hIGVtcHJlc2EgY3V5byBkaWZlcmVuY2lhZG9yIGVzIGJyaW5kYXIgc29sdWNpb25lcyBlc3BlY2lhbGl6YWRhcyByZWxhY2lvbmFkYXMgY29uIGxhcyBuZWNlc2lkYWRlcyBkZWwgZW1wYXF1ZSBkZW50cm8gZGUgbGEgY2FkZW5hIGRlIHN1bWluaXN0cm8gZGVsIGNsaWVudGUuIE5vIGN1ZW50YW4gY29uIHVuIHBvcnRhZm9saW8gZGUgcHJvZHVjdG9zIHNpbm8gbcOhcyBiaWVuIGNvbiB1bmEgbWV0b2RvbG9nw61hIGRlIHNvbHVjacOzbiBxdWUgbGxhbWFuIOKAnExhIFJ1dGEgZGVsIEVtcGFxdWXigJ0gcXVlIGEgdHJhdsOpcyBkZSA1IHBhc29zIGFzZWd1cmFuIGN1bXBsaXIgY29uIGxvcyBlc3TDoW5kYXJlcyBkZSBjYWxpZGFkOg0KDQoxLiBFbnRlbmRlciBsYSBwcm9ibGVtw6F0aWNhLg0KMi4gSWRlbnRpZmljYXIgb3BvcnR1bmlkYWRlcy4NCjMuIERlc2Fycm9sbG8gZGUgcHJvdG90aXBvcy4NCjQuIFBydWViYXMgcGlsb3RvIHkgZXZhbHVhY2nDs24gZGUgcmVzdWx0YWRvcy4NCjUuIFByb2R1Y2Npw7NuLCBzdW1pbmlzdHJvIHkgc2VydmljaW8uDQoNClByb3ZlZW4gZW1wYXF1ZXMgYSBsYSBpbmR1c3RyaWEgYXV0b21vdHJpeiwgc2luIGVtYmFyZ28sIHNlIGVzcGVjaWFsaXphbiBlbiBwYXJ0ZXMgaW50ZXJpb3JlcyB5IGVsw6ljdHJpY2FzLiBBZGVtw6FzLCBvZnJlY2VuIGxhIG9wY2nDs24gZGUgdW4gc29mdHdhcmUgcGFyYSBhZG1pbmlzdHJhciBkaWNobyBlbXBhcXVlLg0KDQpQb3Igb3RybyBsYWRvLCBwYXJ0ZSBkZSBzdSB0YWxlbnRvIGh1bWFubyBlc3TDoSBpbnRlZ3JhZG8gcG9yIDYgaW5nZW5pZXJvcywgcXVpZW5lcyBzZSBlbmNhcmdhbiBkZSBkZXNhcnJvbGxhciBkaXNlw7FvcyBpbm5vdmFkb3JlcyB5IGVmaWNhY2VzLiBFbiBlbCDDoW1iaXRvIGFkbWluaXN0cmF0aXZvIHRyYWJhamFuIGFscmVkZWRvciBkZSAzMCBwZXJzb25hcyBtaWVudHJhcyBxdWUgYSBuaXZlbCBvcGVyYXRpdm8gMTAwIGNvbGFib3JhZG9yZXMuIEFkZW3DoXMsIGVuIER1cmFuZ28gY3VlbnRhbiBjb24gcGVyc29uYXMgcXVlIGFkbWluaXN0cmFuIHN1cyByZWRlcyBjb24gZWwgZmluIGRlIGNvbnNlZ3VpciBlbXBsZWFkb3MuDQoNClN1cyBwcmluY2lwYWxlcyAqKmNvbXBldGlkb3JlcyoqIGVuIE3DqXhpY28gc29uOg0KDQoxLiAqRW1wYXF1ZXMgcmV0b3JuYWJsZXMqOiBCcmFkZm9yZCBNw6l4aWNvLCBIZWxzYSwgQ29udGV5b3IsIFZpY3RvcnkgUGFja2FnaW5nLCBWZXJzYXRlY2ggeSBPcmJpcy4NCjIuICpFbXBhcXVlcyBkZSBjYXJ0b24qOiBFbXBhcXVlcyBGaWd1ZXJvYSwgSFQgeSBSw61vIEdyYW5kZS4NCg0KTGFzIHpvbmFzIGdlb2dyw6FmaWNhcyBkb25kZSBidXNjYW4gdGVuZXIgKipwcmVzZW5jaWEqKiBzb246DQoNCjEuIE1vbnRlcnJleS1TYWx0aWxsby4NCjIuIEJhasOtby4NCjMuIFNhbiBBbnRvbmlvLCBUeC4NCg0KTG8gcXVlIGJ1c2NhIEZPUk0gZGUgbGEgcmVsYWNpw7NuIGNvbiBlbCBJVEVTTSBDYW1wdXMgTW9udGVycmV5LCBzZSBkaXZpZGUgZW4gZG9zIHZlcnRpZW50ZXM6DQoNCjEuKlJlY3Vyc29zIEh1bWFub3M6KiBlbmNvbnRyYXIgc29sdWNpb25lcyBjb2hlcmVudGVzIHkgc29zdGVuaWJsZXMgcGFyYSBsYSBzZWxlY2Npw7NuLCByZXRlbmNpw7NuIHkgc2F0aXNmYWNjacOzbiBkZWwgcGVyc29uYWwuIEFkZW3DoXMgZGUgbWVqb3JhciBzdSBjbGltYSBvcmdhbml6YWNpb25hbC4NCg0KMi4gKk1lcmNhZG8vQ29tZXJjaWFsaXphY2nDs246KiBjcmVhciB1biBzaXN0ZW1hIG8gbW9kZWxvIG9wZXJhdGl2byBkZSBpbnRlbGlnZW5jaWEgY29tZXJjaWFsIHF1ZSBsZXMgcGVybWl0YSBhY2NlZGVyIGRlIGZvcm1hIG3DoXMgc2VuY2lsbGEgY29uIGNsaWVudGVzIHBvdGVuY2lhbGVzIHBhcmEgbGEgZW1wcmVzYS4gQXNpbWlzbW8sIGxhIGRpdmVyc2lmaWNhY2nDs24gZSBpbmR1c3RyaWFzIGF0cmFjdGl2YXMgcGFyYSB2ZW5kZXJsZXMuDQoNCg0KTGFzIHByaW5jaXBhbGVzICoqcHJlb2N1cGFjaW9uZXMqKiBkZWwgQ0VPIHNvbjoNCg0KMS4gQWx0YSBkZXBlbmRlbmNpYSBzb2JyZSBjaWVydG9zIGNsaWVudGVzLg0KMi4gTGEgcGVybWFuZW5jaWEgZGUgbG9zIGVtcGxlYWRvcyBlbiBsYSBlbXByZXNhLiANCjMuIEluY2VydGlkdW1icmUgZGUgU2VndXJpZGFkLCBFY29uw7NtaWNhIHkgUG9sw610aWNhIGRlIE3DqXhpY28gY29uIG90cm9zIHBhw61zZXMuDQo0LiBMYSBlbXByZXNhIHRvZGF2w61hIGRlcGVuZGUgZGUgw6lsIGFsIDEwMCUuDQoNCiMjIyMgSURFQVMNCg0KIyMjIyMgKlJlY3Vyc29zIEh1bWFub3MqDQoNCjEuIEEgcGFydGlyIGRlIGxvcyBkYXRvcyBpZGVudGlmaWNhciBjYXJhY3RlcsOtc3RpY2FzIGVzcGVjw61maWNhcyAodmFyaWFibGVzKSBkZSBsb3MgY29sYWJvcmFkb3JlcywgcGFyYSBhZ3J1cGFybG9zIHBvciB0aWVtcG8gZW4gbGEgZW1wcmVzYSwgw6FyZWEgbGFib3JhbCwgcmFuZ29zIGRlIGVkYWQsIHNleG8sIGVzdGFkbyBjaXZpbCwgdWJpY2FjacOzbiBnZW9ncsOhZmljYSB5IG90cmFzIHZhcmlhYmxlcyByZWxldmFudGVzIHF1ZSBub3MgcGVybWl0YW4gaWRlbnRpZmljYXIgbG9zIHBlcmZpbGVzIGRlIGFxdWVsbG9zIGNvbGFib3JhZG9yZXMgY29uIHVuYSBhbHRhIHRlbmRlbmNpYSBhIHBlcm1hbmVjZXIgcG9yIG3DoXMgdGllbXBvIGVuIGxhIGVtcHJlc2EgeSBhcXVlbGxvcyBjb24gYWx0YSB0ZW5kZW5jaWEgYSByb3RhciByw6FwaWRhbWVudGUuIEVzdG8gcGVybWl0aXLDoSBpZGVudGlmaWNhciBlbCB0aXBvIGRlIHBlcmZpbCBxdWUgZGViZSBjb250cmF0YXIgRk9STSBwYXJhIG1pdGlnYXIgZWwgcmllc2dvIHBvciByb3RhY2nDs24sIGFkZW3DoXMgZGUgZW5jb250cmFyIGxhcyB2YXJpYWJsZXMgbcOhcyBzaWduaWZpY2F0aXZhcyBxdWUgZXhwbGlxdWVuIGVsIHRpZW1wbyBxdWUgcGVybWFuZWNlIHVuIGNvbGFib3JhZG9yIGVuIGxhIGVtcHJlc2EuDQoNCjIuIFVuYSB2ZXogaWRlbnRpZmljYWRhIGVsIHRpcG8gZGUgY3VsdHVyYSBvcmdhbml6YWNpb25hbCBxdcOpIHRpZW5lcyB5IGxvcyBkYXRvcyBkZSBlc3RhLCBvZnJlY2VyIHVuIGFtYmllbnRlIGRlIGRlc2Fycm9sbG8gcHJvZmVzaW9uYWwsIGVuIGRvbmRlIGxvIHF1w6kgc2UgYnVzY2EgZXMgY2FwYWNpdGFyIGFsIHBlcnNvbmFsIGVuIGRpZmVyZW50ZXMgw6FyZWFzIGRlIHV0aWxpZGFkIHBhcmEgbGEgZW1wcmVzYSwgY29uIGxhIGZpbmFsaWRhZCBkZSBxdcOpIHB1ZWRhbiBoYWNlciB1biBtZWpvciB0cmFiYWpvIHBhcmEgZWwgYmVuZWZpY2lvIGRlbCBjcmVjaW1pZW50byBkZSBsYSBlbXByZXNhOyB5IHRhbWJpw6luIHBhcmEgcXXDqSBlbCBwZXJzb25hbCB0ZW5nYSB1biBwbGFuIGRlIGRlc2Fycm9sbG8uIExhcyBjYXBhY2l0YWNpb25lcyBzZSBsbGV2YXLDrWFuIGEgY2FibyBlbiB1biBlc3BhY2lvIGRldGVybWluYWRvIGRlbnRybyBkZSBsYSBlbXByZXNhLCBlbiBkb25kZSBlbCBwZXJzb25hbCBwdWVkYSB0b21hciBjdXJzb3MgZGUgbGEgYXBsaWNhY2nDs24gTWFzdGVyY2xhc3MNCg0KMy4gQ3JlYXIgdW5hIGN1bHR1cmEgZGUgSW5ub3ZhY2nDs24sIGVzdG8gc2UgcHVlZGUgaGFjZXIgbWVkaWFudGUgY2FwYWNpdGFjacOzbiB5IGxhIGltcGxlbWVudGFjacOzbiBkZSB1bmEg4oCcSWRlYSBCb3jigJ0sIGVuIGxhIGN1YWwgZHVyYW50ZSAzIHNlbWFuYXMgZXN0YXLDoSBhYmllcnRhIHkgbGEgZ2VudGUgcG9kcsOhIHBvbmVyIHByb3B1ZXN0YXMgZSBpZGVhcyBxdcOpIGNvbnNpZGVyZW4gcXXDqSBwdWVkYW4gYmVuZWZpY2lhciBhIGxhIGVtcHJlc2EgeSBzdXMgY29sYWJvcmFkb3Jlcy4gRW4gbGEgc2VtYW5hIDQgc2UgYW5hbGl6YXLDoW4gbGFzIGlkZWFzIHkgc2Ugc2VsZWNjaW9uYXLDoSBsYSBtZWpvciBpZGVhLCBhIGxhIHBlcnNvbmEgcXXDqSBoYXlhIGNyZWFkbyBkaWNoYSBpZGVhIHNlIGxlIGRhcsOhIHVuIHByZW1pbyBlbCBjdWFsIGNvbnNpZGVyw6kgbGEgZW1wcmVzYSBwcm9waWEuIEVsIGVmZWN0byBkZSBlc3RhIOKAnElkZWEgQm944oCdLCBlcyBxdcOpIGludml0YSBhIGxhIGdlbnRlIGEgaW5ub3Zhciwgc2UgcHVlZGVuIG9idGVuZXIgcHJveWVjdG9zIGxvcyBjdWFsZXMgYXl1ZGFuIGEgbWVqb3JhciBsb3MgcHJvY2Vzb3MgZGUgbGEgZW1wcmVzYSwgY3JlYSB1biBhbWJpZW50ZSBjb21wZXRpdGl2byB5IHByb3ZvY2EgcXXDqSBsYSBlbXByZXNhIG5vIHBhcmUgZGUgZ2VuZXJhciBpZGVhcy4NCg0KIyMjIyMgKkNvbWVyY2lhbGl6YWNpw7NuKg0KDQoxLiBFeHBhbmRpcnNlIGEgbGFzIGluZHVzdHJpYXMgZGUgbXVlYmxlcyB5IGFydGUsIGVuZm9jw6FuZG9zZSBwcmluY2lwYWxtZW50ZSBlbiBsYSBvZmVydGEgZGUgZW1wYXF1ZXMgcGFyYSB0cmFuc3BvcnRhciB5IHNhbHZhZ3VhcmRhciBzdXMgcHJvZHVjdG9zOyBlc3RvIHBlcm1pdGlyw61hIGEgbGEgZW1wcmVzYSBkaXZlcnNpZmljYXIgc3UgY2xpZW50ZWxhIHkgZWwgdGlwbyBkZSBwcm9kdWN0b3MgcXXDqSBvZnJlY2Vyw61hLiANCg0KMi4gQ3JlYXIgdW4gbW9kZWxvIGRlIHRvbWEgZGUgZGVjaXNpb25lcywgcGFyYSBpZGVudGlmaWNhciBhcXVlbGxvcyB0cmF0b3MgeS9vIGVtcHJlc2FzIGNvbnZlbmllbnRlcyB5IGxsYW1hdGl2YXMgcGFyYSBGT1JNLiBTZSByZXF1aWVyZSB1bmEgYXNpZ25hY2nDs24gbnVtw6lyaWNhIHUgb3JkaW5hbCBhIGNhZGEgdW5hIGRlIGxhcyBleGlzdGVudGVzLCBwYXJhIGEgcGFydGlyIGRlIGVsbG8gZW50cmVuYXIgZWwgbW9kZWxvIHkgcXVlIHBvc3Rlcmlvcm1lbnRlIGFycm9qZSByZXN1bHRhZG9zIHBhcmEgb3JkZW5hciB5L28gY2xhc2lmaWNhciBsb3MgbmVnb2Npb3MgeSB0cmF0b3MgZnV0dXJvcy4gRXN0byBwZXJtaXRpcsOhIHF1ZSwgYSBwYXJ0aXIgZGUgY2llcnRhcyB2YXJpYWJsZXMsIGVuIGF1dG9tw6F0aWNvIHNlIGFzaWduZSB1bmEg4oCcY2FsaWZpY2FjacOzbuKAnSBhIHVuYSBlbXByZXNhIG8gdHJhdG8geSBzZSBwdWVkYSB0b21hciB1bmEgbWVqb3IgZGVjaXNpw7NuLCBpbmNsdXNvIHNpbiBsYSBuZWNlc2lkYWQgZGUgbGEgaW50ZXJ2ZW5jacOzbiBkZWwgQ0VPLg0KDQojIyMjIyAqTm90YSoNCg0KUG9yIGVsIG1vbWVudG8sIEZPUk0gbm8gaGEgdGVuaWRvIGVsIGRlc2VvIGRlIGV4cGFuZGlyIHN1IHBsYW50YSBtw6FzIGFsbMOhIGRlIFRFWEFTIGRlYmlkbyBhbCBhbHRvIGNvc3RvIGVuIGZsZXRlcywgc2luIGVtYmFyZ28sIHBvc2VlbiAzIHJlZ2lvbmVzLCBFbCBiYWrDrW8sIE1vbnRlcnJleS1TYWx0aWxsbyB5IFNhbiBBbnRvbmlvLCBjb24gYWxndW5hcyDDoXJlYXMgZGUgb3BvcnR1bmlkYWQuICANCg0KIyMjICoqQU7DgUxJU0lTIEdFTkVSQUwgU0lUVUFDScOTTiBQUk9CTEVNQSAxKioNCg0KKipTSVRVQUNJw5NOIFBST0JMRU1BIDEqKiANCg0KQ2FiZSByZWNhbGFjYXIgcXVlIGVzdGUgYW7DoWxpc2lzIGV4cGxvcmF0b3JpbyBlcyBnZW5lcmFsIHkgbm8gc2UgdXRpbGl6YXJvbiBiYXNlcyBkZSBkYXRvcyBlbiBSLCBzaW4gZW1iYXJnbywgbGEgaW5mb3JhbWNpw7NuIHJlY2FiYWRhIGRlIGZ1ZW50ZXMgc2VjdW5kYXJpYXMgc29icmUgbGEgU2l0dWFjacOzbiBQcm9ibGVtYSAxIGVzIGJhc3RhbnRlIGludGVyZXNhbnRlIHkgw7p0aWwgcGFyYSBlbCBDRU8uDQoNCkV4cGxvcmFyLCBkZXNhcnJvbGxhciwgeSBkZXNjcmliaXIgbGEgZXN0cmF0ZWdpYSBkZSBjb21lcmNpYWxpemFjacOzbiBkZSBGT1JNIGVuIGxhIHJlZ2nDs24gZGUgU2FuIEFudG9uaW8sIFRYLiBMYSBlc3RyYXRlZ2lhIGRlIGNvbWVyY2lhbGl6YWNpw7NuIGluY2x1eWUgcHJvZHVjdG9zIGFjdHVhbGVzIChlbXBhcXVlIGRlIGNhcnTDs24gcGFyYSBsYSBpbmR1c3RyaWEgYXV0b21vdHJpeikgeS9vIGRpdmVyc2lmaWNhY2nDs24gZGUgcHJvZHVjdG9zIChwb3IgZWplbXBsbywgaW5kdXN0cmlhIGFlcm9lc3BhY2lhbCwgbcOpZGljYSwgYWxpbWVudG9zLCBldGMuKS4NCg0KIyMjIyAqKk1hbnVmYWN0dXJhLCBFcXVpcG8geSBQcm9kdWN0b3MgTcOpZGljb3MgZW4gVGV4YXMqKg0KDQpMb3MgaW5ncmVzb3MgZGUgbGEgbWFudWZhY3R1cmEgZXF1aXBvIHkgcHJvZHVjdG9zIG3DqWRpY29zIGVuIFRleGFzIGRlIDIwMjAgYSAyMDI0IGRlIGFjdWVyZG8gY29uIGRhdG9zIHkgZXN0aW1hY2lvbmVzIGRlIFN0YXRpc3RhLCBlc3TDoSBlbiBpbmNyZW1lbnRvLCBwb3IgbG8gcXVlIGVzIHVuYSBpbmR1c3RyaWEgbGxhbWF0aXZhIGVuIGxhIHF1ZSBGT1JNIHBvZHLDrWEgZXhwYW5kaXJzZS4gQ2FiZSByZWNhbGNhciBxdWUgbG9zIGluZ3Jlc29zIGVzcGVyYWRvcyBkZSBlc3RhIMOhcmVhIHBhcmEgMjAyNCBzb24gZGUgNCwzMzcuMyBtaWxsb25lcyBkZSBkw7NsYXJlcywgcG9yIGxvIHF1ZSwgZGViaWRvIGEgc3UgdmFsb3IsIHNpIHNlIGVuY3VlbnRyYW4gbG9zIGNsaWVudGVzIGNvcnJlY3RvcyBzZXLDrWEgdW5hIG51ZXZhIMOhcmVhIGVuIGxhIHF1ZSBGT1JNIHBvZHLDrWEgb2ZyZWNlciBwcm9kdWN0b3MuDQoNCkxhcyBlbXByZXNhcyBtw6FzIHJlbGV2YW50ZXMgZGUgU2FuIEFudG9uaW8sIFRleGFzLCBxdWUgbWFudWZhY3R1cmFuIGVzdG9zIHByb2R1Y3RvcywgZGUgYWN1ZXJkbyBjb24gRHVuICYgQnJhZHN0cmVldCwgc29uIEFjZWxpdHkgTC5QLiBJbmMuIChTLlIuICQxLDQ2OE0gVVNEKSwgQWNlbGl0eSwgSW5jLiAoUy5SLiAkOTQ1LjMxIE0gVVNEKSwgVmlzaW9ud29ya3Mgb2YgQW1lcmljYSwgSW5jLiAoUy5SLiAkNTIwLjQgTSBVU0QpLCBLaW5ldGljIENvbmNlcHRzLCBJbmMuIChTLlIuICQ1MDAuMzMgTSBVU0QpLCBLY2kgVXNhLCBJbmMuIChTLlIuICQxMzEuODEgTSBVU0QpLCBYZW5leCBEZXNpbmZlY3Rpb24gU2VydmljZXMgSW5jLiAoUy5SLiAkNDcuMSBNIFVTRCksIFZpYW4gU2FuIEFudG9uaW8sIEluYy4gKCQ0My4xIE0gVVNEKSB5IENlbGVub3ZhIEJpb3NjaWVuY2VzLCBJbmMuIChTLlIuICQyMy41MSBNIFVTRCkuIEVzdGFzIGVtcHJlc2FzIHB1ZWRlbiBzZXIgY2xpZW50ZXMgcG90ZW5jaWFsZXMgZGUgRk9STSBlbiBjYXNvIGRlIHF1ZSBkZWNpZGFuIGFwb3N0YXIgcG9yIGV4cGFuZGlyc2UgZW4gbGEgb2ZlcnRhIGRlIHN1cyBwcm9kdWN0b3MgeSBzZXJ2aWNpb3MgaGFjaWEgZXN0YSBpbmR1c3RyaWEuDQoNCiMjIyMgKipNYW51ZmFjdHVyYSBkZSBQcm9kdWN0b3MgeSBQYXJ0ZXMgQWVyb2VzcGFjaWFsZXMgZW4gVGV4YXMqKg0KDQpMb3MgaW5ncmVzb3MgZGUgbGEgbWFudWZhY3R1cmEgZGUgcHJvZHVjdG9zIHkgcGFydGVzIGFlcm9lc3BhY2lhbGVzIGVuIFRleGFzIGRlIDIwMjAgYSAyMDI0IGRlIGFjdWVyZG8gY29uIGRhdG9zIHkgZXN0aW1hY2lvbmVzIGRlIFN0YXRpc3RhLCBlc3TDoSBlbiB1biBpbmNyZW1lbnRvIGxpZ2VyYW1lbnRlIGFsdG8sIHBvciBsbyBxdWUgZXMgdW5hIGluZHVzdHJpYSBsbGFtYXRpdmEgZW4gbGEgcXVlIEZPUk0gcG9kcsOtYSBhcG9zdGFyIGVuIHVuIGluaWNpbywgdGFudG8gcG9ycXVlIHVubyBkZSBzdXMgY2xpZW50ZXMgc2UgZW5jdWVudHJhIGVuIGVzYSBpbmR1c3RyaWEsIGNvbW8gYSBxdWUgZXNhIGluZHVzdHJpYSBwdWVkZSBsbGVnYXIgYSBzZXIgc2ltaWxhciBhIGxhIGF1dG9tb3RyaXogZW4gbGEgcXVlIEZPUk0gdGllbmUgZXhwZXJpZW5jaWEsIHJlZmlyacOpbmRvbm9zIGFsIHRpcG8gZGUgZW1wYXF1ZXMgcXVlIGhhY2UgcGFyYSBwYXJ0ZXMgZWxlY3Ryw7NuaWNhcyB5IG5vIGVsZWN0csOzbmljYXMgZGUgYXV0b3BhcnRlcy4gLiBDYWJlIHJlY2FsY2FyIHF1ZSBsb3MgaW5ncmVzb3MgZXNwZXJhZG9zIGRlIGVzdGEgw6FyZWEgcGFyYSAyMDI0IHNvbiBkZSAzNi45IGJpbGxvbmVzIGRlIGTDs2xhcmVzLCBwb3IgbG8gcXVlLCBkZWJpZG8gYSBzdSB2YWxvciwgc2kgc2UgZW5jdWVudHJhbiBsb3MgY2xpZW50ZXMgY29ycmVjdG9zIHNlcsOtYSB1bmEgaW5kdXN0cmlhIGRlIGxhIHF1ZSBGT1JNIHNlIHBvZHLDrWEgYmVuZWZpY2lhciBjb25zaWRlcmFibGVtZW50ZS4NCg0KTGFzIGVtcHJlc2FzIG3DoXMgcmVsZXZhbnRlcyBkZSBTYW4gQW50b25pbywgVGV4YXMsIHF1ZSBtYW51ZmFjdHVyYW4gZXN0b3MgcHJvZHVjdG9zLCBkZSBhY3VlcmRvIGNvbiBEdW4gJiBCcmFkc3RyZWV0LCBzb24gQ2hyb21hbGxveSwgQ29tcG9uZW50IFNlcnZpY2UsIEluYy4gKFMuUi4gJDEwMy4wNiBNIFVTRCksIERhbmJ1cnkgQWVyb3NwYWNlLCBJbmMuIChTLlIuICQyOS43MSBNIFVTRCksIEplZmYgQm9uZXIgUiZELCBJbmMuIChTLlIuICQxMy42MiBNIFVTRCksIEFkdmFuY2VkIEludGVncmF0aW9uIFRlY2hub2xvZ3kgU2FuIEFudG9uaW8sIExQIChTLlIuICQxMi4zNiBNIFVTRCksIFN1bmJlbHQgRGVzaWduICYgRGV2ZWxvcG1lbnQsIEluYy4gKFMuUi4gJDguNjggTSBVU0QpLCBBaXJjcmFmdCBPbiBHcm91bmQsIEluYy4gKFMuUi4gJDYuNzUgTSBVU0QpLCBDICYgRiBUb29sICYgRGllIENvLiwgTExDICgkNi41MyBNIFVTRCkgeSBTcGlyaXQgQWVyb3N5c3RlbXMsIEluYy4gKFMuUi4gJDYuMjIgTSBVU0QpLiBFc3RhcyBlbXByZXNhcyBwdWVkZW4gc2VyIGNsaWVudGVzIHBvdGVuY2lhbGVzIGRlIEZPUk0gZW4gY2FzbyBkZSBxdWUgZGVjaWRhbiBhcG9zdGFyIHBvciBleHBhbmRpcnNlIGVuIGxhIG9mZXJ0YSBkZSBzdXMgcHJvZHVjdG9zIHkgc2VydmljaW9zIGhhY2lhIGVzdGEgaW5kdXN0cmlhLg0KDQojIyMjICoqSW5kdXN0cmlhIGRlIFZlaMOtY3Vsb3MgZGUgTW90b3IgeSBBdXRvcGFydGVzIGVuIFRleGFzKioNCg0KTG9zIGluZ3Jlc29zIGRlIGxvcyBjb21lcmNpYW50ZXMgZGUgdmVow61jdWxvcyBkZSBtb3RvciB5IGF1dG9wYXJ0ZXMgZW4gVGV4YXMgZGUgMjAyMCBhIDIwMjQgZGUgYWN1ZXJkbyBjb24gZGF0b3MgeSBlc3RpbWFjaW9uZXMgZGUgU3RhdGlzdGEsIGVzdMOhIGVuIGluY3JlbWVudG8gY29uc2lkZXJhYmxlLCBwb3IgbG8gcXVlIGVzIHVuYSBpbmR1c3RyaWEgbGxhbWF0aXZhIGVuIGxhIHF1ZSBGT1JNIHBvZHLDrWEgZXhwYW5kaXJzZS4gQ2FiZSByZWNhbGNhciBxdWUgbG9zIGluZ3Jlc29zIGVzcGVyYWRvcyBkZSBlc3RhIMOhcmVhIHBhcmEgMjAyNCBzb24gZGUgMTM4LjI3IGJpbGxvbmVzIGRlIGTDs2xhcmVzLCBwb3IgbG8gcXVlLCBkZWJpZG8gYSBzdSB2YWxvciwgc2kgc2UgZW5jdWVudHJhbiBsb3MgY2xpZW50ZXMgY29ycmVjdG9zIHNlcsOtYSB1bmEgbnVldmEgw6FyZWEgZW4gbGEgcXVlIEZPUk0gcG9kcsOtYSBvZnJlY2VyIHByb2R1Y3RvczsgYWRlbcOhcyBlcyB1bmEgaW5kdXN0cmlhIGVuIGxhIHF1ZSB5YSB0aWVuZW4gZXhwZXJpZW5jaWEgeSBwb2Ryw61hbiBkYXIgY29uc3VsdG9yw61hIGEgbGEgY2xpZW50ZWxhIGVzdGFkb3VuaWRlbnNlIGVuIHF1ZSBlcyBsbyBxdWUgbmVjZXNpdGFuIGVuIGN1ZXN0acOzbiBkZSBlbXBhcXVlcy4gRXMgcG9yIGVzdG8gcXVlIGVzdGEgaW5kdXN0cmlhIHNlcsOtYSBsYSBwcmluY2lwYWwgYSBjb25zaWRlcmFyLCBlbiBjdWVzdGnDs24gZGUgZXhwYW5zacOzbi4NCg0KTGFzIGVtcHJlc2FzIG3DoXMgcmVsZXZhbnRlcyBkZSBTYW4gQW50b25pbywgVGV4YXMsIHF1ZSBtYW51ZmFjdHVyYW4gZXN0b3MgcHJvZHVjdG9zLCBkZSBhY3VlcmRvIGNvbiBEdW4gJiBCcmFkc3RyZWV0LCBzb24gWHBlbCwgSW5jLiAoUy5SLiAkMzIzLjk5IE0gVVNEKSwgVGsgSG9sZGluZ3MsIEluYy4gKFMuUi4gJDEwNy4wOSBNIFVTRCksIEVuY29udHJvbHMsIExMQyAoUy5SLiAkOTguNzMgTSBVU0QpLCBUb3lvZGEgR29zZWkgVGV4YXMsIExMQyAoUy5SLiAkNTUuOTkgTSBVU0QpLCBUb3lvdGV0c3UgVGV4YXMsIEluYy4gKFMuUi4gJDQ4Ljg5IE0gVVNEKSwgUmV5ZXMgQXV0b21vdGl2ZSBHcm91cCwgTExDIChTLlIuICQyOC43NCBNIFVTRCksIFJleWVzIEF1dG9tb3RpdmUgR3JvdXAgSUksIExMQyAoJDIzLjkyIE0gVVNEKSB5IFZpbnRhZ2UgQWlyLCBMTEMgKFMuUi4gJDIxLjE2IE0gVVNEKS4gRXN0YXMgZW1wcmVzYXMgcHVlZGVuIHNlciBjbGllbnRlcyBwb3RlbmNpYWxlcyBkZSBGT1JNIGVuIGNhc28gZGUgcXVlIGRlY2lkYW4gYXBvc3RhciBwb3IgZXhwYW5kaXJzZSBlbiBsYSBvZmVydGEgZGUgc3VzIHByb2R1Y3RvcyB5IHNlcnZpY2lvcyBoYWNpYSBlc3RhIGluZHVzdHJpYS4NCg0KIyMjIyAqKkVzdHJhdGVnaWEgUmVjb21lbmRhZGEgKFByaW1lciBBY2VyY2FtaWVudG8pKioNCg0KTG8gcXVlIGVsIGVxdWlwbyByZWNvbWllbmRhIGEgRk9STSwgZXMgcHJpbWVybyBoYWNlciB1biBhbsOhbGlzaXMgaW50ZXJubyBkZSBsYSBlbXByZXNhLCBwYXJhIGNvbm9jZXIgbGFzIGNhcGFjaWRhZGVzIHkgbGltaXRhY2lvbmVzIHF1ZSB0ZW5kcsOtYW4gYSBsYSBob3JhIGRlIGZhYnJpY2FyIHByb2R1Y3RvcyB5IHNlcnZpY2lvcyBwYXJhIGxhcyBpbmR1c3RyaWFzIHkgw6FyZWFzIG1hbnVmYWN0dXJlcmFzIHByZXZpYW1lbnRlIGNvbWVudGFkYXMuIFVuYSB2ZXogaGVjaG8gZXN0ZSBhbsOhbGlzaXMsIHBvZHLDoW4gcmVhbGl6YXIgdW4gY2F0w6Fsb2dvIGRlIHByb2R1Y3RvcyB5IHNlcnZpY2lvcyBwYXJhIGNhZGEgaW5kdXN0cmlhOyBhZGVtw6FzIHNlIHJlY29taWVuZGEgYcOxYWRpciBlbiBlc2UgY2F0w6Fsb2dvL3BvcnRhZm9saW8sIGxhIGV4cGVyaWVuY2lhIHkgY2xpZW50ZXMgcXVlIGxhIGVtcHJlc2EgaGF5IHRlbmlkbyBhIGxvIGxhcmdvIGRlIGxvcyBhw7Fvcy4NCg0KUG9zdGVyaW9ybWVudGUgc2UgcmVjb21pZW5kYSBxdWUgY29uIGxhIGF5dWRhIGRlbCBjbGllbnRlIFRlc2xhIHNlIHB1ZWRhbiBhZHF1aXJpciBudWV2b3MgY2xpZW50ZXMsIGEgbGEgdmV6IGVuIGxvIHF1ZSBzZSBjcmVhIHkgdGVybWluYSBlbCBjZW50cm8gZGUgZGlzdHJpYnVjacOzbiBlbiBUZXhhcywgc2UgcmVjb21pZW5kYSBxdWUgbGEgY2xpZW50ZWxhIHBvdGVuY2lhbCwgc2VhIGVuIGVzYSDDoXJlYSwgZXN0byBjb24gbGEgZmluYWxpZGFkIGRlIGRpc21pbnVpciBjb3N0ZXMgZGUgdHJhc2xhZG9zIHkgZW1wZXphciBhIGNvbnN0cnVpciB1biBub21icmUgZW4gVVNBIGRlIG1lbm9zIGEgbcOhcy4gRW4gbGEgcGFydGUgYW50ZXJpb3Igc2UgY29tcGFydGllcm9uIGxvcyBjbGllbnRlcyBwb3RlbmNpYWxlcyBkZSBjYWRhIGluZHVzdHJpYSwgZXN0byBjb24gZWwgb2JqZXRpdm8gZGUgcXVlIGxhIGVtcHJlc2EgY29ub3pjYSBhIHF1aWVuIGxlIHB1ZWRlIHZlbmRlciB5IGVsIHZhbG9yIHF1ZSB0aWVuZSBjYWRhIGVtcHJlc2EgZW4gY3Vlc3Rpw7NuIGRlIGluZ3Jlc29zOyBhZGVtw6FzIGVuIGNhc28gZGUgcXVlcmVyIGJ1c2NhciBtw6FzIG9wY2lvbmVzIGRlIGNsaWVudGVsYSwgZW4gZWwgYXBhcnRhZG8gZGUgcmVmZXJlbmNpYXMgZXN0w6FuIGxvcyBlbmxhY2VzIGRlIGRvbmRlIHNlIHNhY2Fyb24gZXNhIGxpc3RhIGRlIGNsaWVudGVsYSBwb3RlbmNpYWwuDQoNCkRlc3B1w6lzLCBhbCBzZWxlY2Npb25hciBhIGxvcyBwcmltZXJvcyBjbGllbnRlcyBwb3RlbmNpYWxlcywgc2UgcmVjb21pZW5kYSBxdWUgbGEgZW1wcmVzYSBsb3MgY29udGFjdGUgeSBsb2dyZW4gYWdlbmRhciB1bmEgY2l0YSBkZSBuZWdvY2lvcyBlbiBkb25kZSBsZSBwdWVkYW4gZW5zZcOxYXIgYSBjYWRhIGNsaWVudGUgcG9yIHF1w6kgRk9STSBlcyBsYSBlbXByZXNhIHF1ZSBuZWNlc2l0YW4gcGFyYSBwb2RlciBlbnRyZWdhciBzdXMgcHJvZHVjdG9zIGRlIGxhIG1hbmVyYSBtw6FzIHNlZ3VyYSB5IGVmaWNpZW50ZSBwb3NpYmxlLg0KDQpGaW5hbG1lbnRlLCB1bmEgdmV6IGFkcXVpcmlkYSBsYSBjbGllbnRlbGEsIHNlIGVzcGVyYSBxdWUsIGNvbiB1bmEgYnVlbmEgYXRlbmNpw7NuLCBzZXJ2aWNpbyB5IGxhcyB0ZWNub2xvZ8OtYXMgcXVlIEZPUk0gdXNhIGVuIHN1cyBwcm9jZXNvcywgbGFzIGVtcHJlc2FzIHZlYW4gcXVlIEZPUk0gZXMgc3UgbWVqb3Igb3BjacOzbiB5IGRlc3B1w6lzIGRlIGhhYmVyIHNpZG8gYXRlbmRpZG9zLCByZWNvbWllbmRlbiBhIGxhIGVtcHJlc2EgY29uIG90cmFzIGVtcHJlc2FzIGNvbiBsYXMgcXVlIHRlbmdhbiBhbGfDum4gdGlwbyBkZSBhc29jaWFjacOzbjsgZXN0byBjYXVzYXLDoSB1bmEgY2FkZW5hIGxhIGN1YWwgcHJvdm9jYXLDoSBxdWUgRk9STSBzZSBwdWVkYSBleHBhbmRpciBubyBzb2xvIGRlIG1hbmVyYSBleGl0b3NhIGVuIFNhbiBBbnRvbmlvLCBUZXhhcywgc2lubyB0YW1iacOpbiBlbiBvdHJvcyBlc3RhZG9zIGRlIFVTQS4NCg0K