Aprender a convertir una decisión empresarial en un problema que pueda investigarse mediante datos.

En investigación de mercados, el análisis estadístico no comienza cuando abrimos R.

Antes de analizar datos debemos establecer:

  1. qué decisión debe tomarse;
  2. cuál es el problema real;
  3. qué información necesitamos;
  4. qué preguntas podemos responder;
  5. qué variables representan esas preguntas;
  6. qué diseño de investigación es apropiado;
  7. y solamente entonces, qué datos debemos analizar.

Podemos disponer de millones de observaciones y, aun así, no tener claramente identificado qué pregunta debe responder.

Por ejemplo:

  • una aseguradora observa una reducción de renovaciones;
  • una compañía quiere introducir un nuevo seguro;
  • aumenta la frecuencia de reclamaciones;
  • determinados clientes abandonan una póliza;
  • existe poca demanda por un producto de microseguro;
  • una aseguradora considera modificar una prima;
  • una entidad previsional quiere aumentar la participación voluntaria;
  • una compañía quiere identificar nuevos segmentos de mercado.

En todos estos casos existe inicialmente una decisión empresarial.

La investigación permite transformar esa decisión en una pregunta susceptible de ser respondida mediante evidencia.


1 Ruta de aprendizaje

Durante esta clase seguiremos la siguiente secuencia:

Decisión empresarial - Problema de investigación - Objetivos - Preguntas de investigación - Hipótesis - Variables - Información requerida - Diseño de investigación - Datos - Exploración inicial - Evidencia para la decisión -

2 ¿Qué es la investigación de mercados?

La investigación de mercados puede entenderse como un proceso sistemático para generar información que contribuya a la toma de decisiones relacionadas con un mercado.

Lo importante de esta definición no es solamente la palabra mercado.

La investigación no consiste simplemente en recopilar datos.

Tampoco consiste solamente en aplicar encuestas.

Mucho menos consiste únicamente en aplicar técnicas estadísticas.

2.1 Idea fundamental

Tener datos no significa tener información.

Tener información no significa tener conocimiento.

Y tener conocimiento no implica automáticamente una buena decisión.

El trabajo del investigador consiste en construir una conexión lógica entre:

problema → evidencia → interpretación → decisión.

2.2 Investigación y toma de decisiones

Considere el siguiente ejemplo.

Una aseguradora observa que la tasa de renovación de un seguro de automóvil cayó de 82% a 74%.

La administración podría inmediatamente concluir:

“El problema es que la prima es demasiado alta.”

Pero esa afirmación todavía no ha sido demostrada.

Otras explicaciones podrían ser:

  • mala atención;
  • aumento de competencia;
  • modificaciones en las coberturas;
  • mala experiencia durante un siniestro;
  • cambios en el ingreso de los clientes;
  • nuevos productos sustitutos;
  • promociones de competidores;
  • modificaciones en canales digitales;
  • características particulares de determinados segmentos.

La investigación de mercados busca reducir esta incertidumbre.


3 Aplicación en ciencias actuariales

Tradicionalmente, el análisis actuarial se concentra en fenómenos como:

  • mortalidad;
  • morbilidad;
  • frecuencia de siniestros;
  • severidad;
  • reservas;
  • solvencia;
  • primas;
  • supervivencia;
  • abandono;
  • riesgo financiero.

La investigación de mercados complementa esta perspectiva incorporando preguntas como:

  • ¿qué productos desea el consumidor?;
  • ¿qué atributos valora?;
  • ¿qué precio está dispuesto a aceptar?;
  • ¿por qué abandona una póliza?;
  • ¿qué canal prefiere?;
  • ¿qué segmentos tienen mayor intención de compra?;
  • ¿qué percepción tiene sobre una aseguradora?;
  • ¿comprende adecuadamente las coberturas?;
  • ¿qué factores influyen sobre su renovación?;
  • ¿qué combinación de beneficios resulta más atractiva?

3.1 Perspectiva actuarial

Un modelo actuarial puede responder:

¿Cuál debería ser la prima técnica asociada con determinado nivel de riesgo?

La investigación de mercados puede responder:

¿Cómo reaccionará el consumidor frente a esa prima?

Son preguntas distintas.

Para tomar una decisión empresarial completa pueden ser necesarias ambas respuestas.


4 Dos grandes propósitos de la investigación

Podemos distinguir conceptualmente dos grandes propósitos.

4.1 Investigación para identificar problemas

Busca detectar fenómenos que quizá todavía no son evidentes.

Ejemplos:

  • reducción gradual de participación de mercado;
  • cambio en preferencias;
  • deterioro de imagen;
  • aparición de nuevos segmentos;
  • modificación del comportamiento de compra;
  • cambios en percepción del precio;
  • oportunidades para nuevos productos.

4.2 Investigación para resolver problemas

Se realiza cuando el problema ya ha sido identificado.

Ejemplos:

  • determinar qué prima comercial resulta aceptable;
  • elegir entre dos productos;
  • seleccionar un canal de distribución;
  • evaluar una campaña;
  • rediseñar una cobertura;
  • identificar segmentos prioritarios.

5 Demostración: datos versus información

Supongamos que una aseguradora tiene la siguiente información:

clientes <- data.frame(
  Cliente = paste0("C", 1:10),
  Prima = c(1800, 1900, 2200, 2050, 2500,
            2300, 1950, 2700, 2600, 2100),
  Renueva = c("Sí", "Sí", "No", "Sí", "No",
              "No", "Sí", "No", "No", "Sí")
)

clientes

Estos son datos.

Podemos empezar a resumirlos.

aggregate(
  Prima ~ Renueva,
  data = clientes,
  FUN = mean
)

Ahora tenemos una primera pieza de información.

Podemos visualizarla.

ggplot(
  clientes,
  aes(x = Renueva, y = Prima)
) +
  geom_boxplot() +
  labs(
    title = "Prima según decisión de renovación",
    x = "¿Renueva?",
    y = "Prima anual"
  ) +
  theme_minimal()

¿Qué podemos concluir?

Quizá los clientes que no renuevan presentan primas más elevadas.

Pero todavía no podemos afirmar que la prima cause el abandono.

Podría existir una tercera variable:

  • edad;
  • tipo de vehículo;
  • cobertura;
  • experiencia de siniestros;
  • ingreso;
  • competidor;
  • calidad del servicio.

5.0.1 Pregunta

¿Cuál de las siguientes afirmaciones es metodológicamente más correcta?

A. Las primas altas causan abandono.

B. En estos datos parece existir una diferencia en las primas de quienes renuevan y quienes no renuevan.

C. La compañía debe inmediatamente reducir las primas.

Ver respuesta

La respuesta correcta es B.

En esta etapa únicamente observamos una asociación descriptiva.

No tenemos evidencia suficiente para establecer causalidad ni para recomendar una reducción de primas.


6 El proceso de investigación de mercados

Una investigación puede organizarse conceptualmente en seis grandes etapas:

  1. definición del problema;
  2. desarrollo del enfoque;
  3. formulación del diseño;
  4. trabajo de campo o recopilación;
  5. preparación y análisis de datos;
  6. elaboración y presentación del informe.

6.1 Paso 1. Definir el problema

Esta probablemente sea la etapa conceptualmente más importante.

Si definimos mal el problema, podemos realizar:

  • una excelente encuesta;
  • un excelente muestreo;
  • una excelente regresión;
  • un excelente análisis multivariado;

y aun así responder una pregunta equivocada.

6.1.1 Principio metodológico

Una técnica estadística sofisticada no corrige una pregunta mal formulada.


6.2 Paso 2. Desarrollar el enfoque

Una vez definido el problema debemos determinar:

  • qué sabemos;
  • qué teoría puede orientarnos;
  • qué variables podrían intervenir;
  • qué relaciones esperamos;
  • qué preguntas queremos responder;
  • qué hipótesis pueden plantearse;
  • qué información necesitamos.

6.3 Paso 3. Formular el diseño

Debemos decidir cómo obtendremos la evidencia.

El estudio puede ser:

  • exploratorio;
  • descriptivo;
  • causal;

y puede utilizar:

  • información secundaria;
  • entrevistas;
  • grupos focales;
  • observación;
  • encuestas;
  • experimentos;
  • datos administrativos.

6.4 Paso 4. Recolectar información

En esta fase se ejecuta el diseño.

Más adelante estudiaremos:

  • trabajo de campo;
  • cuestionarios;
  • muestreo;
  • controles;
  • calidad.

6.5 Paso 5. Preparar y analizar

Los datos deben:

  • revisarse;
  • codificarse;
  • depurarse;
  • transformarse;
  • resumirse;
  • analizarse.

R será nuestra herramienta principal durante el curso.


6.6 Paso 6. Comunicar resultados

El producto final no es una salida de R.

El producto final es una respuesta fundamentada.

Por ejemplo:

“Los clientes expuestos a incrementos de prima superiores al 10% presentan menor intención de renovación, especialmente cuando su valoración del servicio también es baja.”

Esta afirmación es mucho más útil que mostrar únicamente una tabla de coeficientes.


7 Problema empresarial versus problema de investigación

Esta distinción es fundamental.

7.1 Problema empresarial

Se concentra en:

¿Qué debemos hacer?

Ejemplos:

  • ¿debemos reducir la prima?;
  • ¿debemos lanzar el producto?;
  • ¿debemos cambiar el canal?;
  • ¿debemos modificar la cobertura?;
  • ¿debemos dirigirnos a otro segmento?

7.2 Problema de investigación

Se concentra en:

¿Qué información necesitamos para decidir?

Ejemplo:

7.2.1 Problema empresarial

¿Debemos modificar la prima de renovación del seguro de automóvil?

7.2.2 Problema de investigación

Determinar la relación entre la variación de la prima y la intención de renovación de los asegurados, considerando características del cliente, experiencia de siniestros y percepción del servicio.

Observe el cambio.

La investigación no decide automáticamente si se reduce la prima.

Primero genera información sobre el fenómeno.


8 Demostración actuarial: transformar una decisión en investigación

Consideremos el siguiente caso.

8.1 Caso: Aseguradora Horizonte

Durante los últimos doce meses, la aseguradora ha observado una reducción en la renovación de pólizas de automóvil.

La gerencia comercial propone otorgar un descuento general del 10%.

La gerencia técnica advierte que esa reducción podría deteriorar el resultado técnico.

Antes de tomar la decisión se solicita una investigación.

8.2 Paso A. Decisión empresarial

¿Debe modificarse la estrategia de precios para mejorar la renovación?

8.3 Paso B. Problema de investigación

Analizar los factores asociados con la intención de renovación de los clientes y determinar la importancia relativa de la variación de la prima frente a otros factores de experiencia y servicio.

8.4 Paso C. Variables posibles

  • intención de renovación;
  • porcentaje de incremento de prima;
  • satisfacción;
  • experiencia de siniestros;
  • ingreso;
  • antigüedad;
  • edad;
  • canal;
  • región.

8.5 Paso D. Información requerida

Necesitamos conocer:

  1. cuánto aumentó la prima;
  2. qué tan satisfecho está el cliente;
  3. si tuvo siniestros;
  4. cómo fue atendido;
  5. su intención de renovación;
  6. variables sociodemográficas;
  7. características del producto.

9 El contexto del problema

Una decisión empresarial no ocurre de forma aislada.

Antes de formular la investigación debemos comprender el contexto.

Entre los elementos que pueden analizarse se encuentran:

  • información histórica;
  • pronósticos;
  • objetivos empresariales;
  • comportamiento del consumidor;
  • restricciones;
  • recursos disponibles;
  • ambiente económico;
  • ambiente legal;
  • tecnología;
  • competencia.

10 Ejemplo de contexto actuarial

Supongamos que una aseguradora observa mayor cancelación.

Antes de culpar al precio debemos revisar:

10.0.1 Entorno económico

  • inflación;
  • ingreso disponible;
  • desempleo;
  • tasas de interés.

10.0.2 Entorno competitivo

  • nuevas aseguradoras;
  • promociones;
  • nuevos canales digitales;
  • agregadores de seguros.

10.0.3 Entorno regulatorio

  • modificaciones normativas;
  • coberturas obligatorias;
  • protección al consumidor.

10.0.4 Entorno interno

  • incremento de primas;
  • modificaciones en deducibles;
  • cambios en servicio;
  • procesos de reclamación.

10.0.5 Comportamiento del cliente

  • sensibilidad al precio;
  • experiencia de siniestro;
  • valoración de marca;
  • preferencias digitales.

11 De objetivos a preguntas de investigación

Una vez definido el problema, debemos estructurar el estudio.

11.1 Objetivo general

Describe qué pretende lograr la investigación.

Ejemplo:

Analizar los factores relacionados con la intención de renovación de los clientes de seguros de automóvil.

11.2 Objetivos específicos

Podrían ser:

  1. describir el perfil de los clientes;
  2. determinar la distribución de la intención de renovación;
  3. analizar la relación entre aumento de prima e intención de renovación;
  4. comparar la intención de renovación según experiencia de siniestro;
  5. analizar la relación entre satisfacción e intención de renovación;
  6. identificar variables potencialmente útiles para explicar la renovación.

12 Cómo formular buenas preguntas de investigación

Una buena pregunta debe ser:

  • clara;
  • específica;
  • investigable;
  • vinculada con información observable;
  • relevante para la decisión.

Ejemplos:

12.0.1 Pregunta 1

¿Cuál es el nivel promedio de intención de renovación?

12.0.2 Pregunta 2

¿La intención de renovación difiere entre clientes con y sin siniestros recientes?

12.0.3 Pregunta 3

¿Existe asociación entre el incremento de prima y la intención de renovación?

12.0.4 Pregunta 4

¿La satisfacción con el servicio está relacionada con la renovación?

12.0.5 Pregunta 5

¿Qué características presentan los clientes con baja intención de renovar?


13 Preguntas débiles y preguntas mejoradas

13.1 Ejemplo 1

Pregunta débil:

¿Por qué los seguros son caros?

Problemas:

  • demasiado amplia;
  • utiliza un juicio de valor;
  • no define seguro;
  • no define población;
  • no define qué significa caro.

Pregunta mejorada:

¿Cómo se relaciona la percepción del precio de un seguro de automóvil con la intención de renovación entre clientes actuales?


13.2 Ejemplo 2

Pregunta débil:

¿A las personas les gustan los seguros de vida?

Pregunta mejorada:

¿Qué atributos de un seguro de vida son valorados por adultos de 25 a 45 años que actualmente no poseen cobertura individual?


14 Marco conceptual

Las preguntas de investigación no deberían aparecer de manera arbitraria.

Necesitamos establecer una explicación conceptual.

Por ejemplo:

Incremento de prima  ──────────┐
                               │
Satisfacción ──────────────────┤
                               │
Experiencia de siniestro ──────┤──> Intención de renovación
                               │
Ingreso ───────────────────────┤
                               │
Antigüedad ────────────────────┘

Este esquema representa una hipótesis conceptual.

Todavía no es un modelo estadístico.

Nos ayuda a organizar el problema.


15 Modelo verbal, gráfico y matemático

Una misma idea puede expresarse de diferentes maneras.

15.1 Modelo verbal

La intención de renovación de una póliza puede estar relacionada con la variación de la prima, la satisfacción del cliente, su experiencia de siniestros y características individuales.

15.2 Modelo gráfico

Precio ────────────────┐
                       │
Servicio ──────────────┤
                       ├──> Renovación
Siniestros ────────────┤
                       │
Características ───────┘

15.3 Modelo matemático conceptual

Podemos representarlo como:

\[ Y = f(X_1,X_2,X_3,\ldots,X_k) \]

donde:

\[ Y = \text{intención de renovación} \]

y, por ejemplo,

\[ X_1 = \text{incremento de prima} \]

\[ X_2 = \text{satisfacción} \]

\[ X_3 = \text{experiencia de siniestros} \]

\[ X_4 = \text{ingreso} \]

\[ Y_i = \beta_0 + \beta_1 X_{1i} + \beta_2 X_{2i} + \beta_3 X_{3i} + \varepsilon_i \]

Por ahora lo importante no es estimarlo.

Lo importante es comprender que el modelo estadístico debe originarse en una pregunta y no al revés.


16 Hipótesis de investigación

Una hipótesis establece una relación esperada entre variables.

Por ejemplo:

\[ H_1: \text{a mayor incremento de prima, menor intención de renovación} \]

Otra hipótesis:

\[ H_2: \text{a mayor satisfacción, mayor intención de renovación} \]

También:

\[ H_3: \text{la intención de renovación difiere según la experiencia de siniestros} \]

16.0.1 Importante

En esta etapa estamos formulando hipótesis conceptuales.

Más adelante aprenderemos a convertirlas en hipótesis estadísticas.

No son exactamente lo mismo.


17 Variables

Una variable es una característica que puede presentar variación.

Ejemplos actuariales:

  • edad;
  • prima;
  • suma asegurada;
  • frecuencia de siniestros;
  • severidad;
  • ingreso;
  • satisfacción;
  • intención de renovación;
  • canal;
  • región.

18 Tipos iniciales de variables

Desde una perspectiva práctica podemos comenzar distinguiendo:

18.0.1 Variables numéricas

Ejemplos:

  • edad;
  • ingreso;
  • prima;
  • número de siniestros.

18.0.2 Variables categóricas

Ejemplos:

  • región;
  • canal;
  • producto;
  • sexo;
  • renovación.

18.0.3 Variables ordinales

Ejemplo:

Intención de renovación:

  1. definitivamente no;
  2. probablemente no;
  3. indeciso;
  4. probablemente sí;
  5. definitivamente sí.

19 Especificación de la información requerida

Este paso obliga a traducir nuestras preguntas en información concreta.

Supongamos que queremos responder:

¿Está relacionado el aumento de prima con la intención de renovación?

Necesitamos al menos:

  • prima anterior;
  • prima actual o porcentaje de incremento;
  • intención de renovación.

Pero probablemente también necesitemos:

  • edad;
  • ingreso;
  • tipo de cobertura;
  • experiencia de siniestro;
  • satisfacción;
  • antigüedad.

¿Por qué?

Porque un fenómeno de mercado rara vez depende de una sola variable.


20 Del concepto a los datos

Observe esta secuencia:

Nivel Ejemplo
Decisión ¿Debemos cambiar la estrategia de renovación?
Problema de investigación Factores relacionados con la renovación
Pregunta ¿El aumento de prima está relacionado con la intención de renovar?
Hipótesis A mayor aumento, menor intención
Concepto Sensibilidad al precio
Variable Incremento porcentual de prima
Dato 12.5%
Análisis Comparación/correlación/modelo
Evidencia Relación observada
Decisión Utilizar evidencia junto con criterios técnicos

21 Diseños de investigación

Una vez sabemos qué necesitamos investigar debemos decidir cómo obtener la evidencia.

Los tres diseños principales que utilizaremos son:

  1. exploratorio;
  2. descriptivo;
  3. causal.

22 Investigación exploratoria

Se utiliza cuando:

  • el problema todavía no está claramente definido;
  • necesitamos comprender el fenómeno;
  • existen pocas hipótesis;
  • queremos identificar posibles variables;
  • buscamos generar ideas.

Métodos comunes:

  • entrevistas con expertos;
  • análisis de datos secundarios;
  • grupos focales;
  • entrevistas en profundidad;
  • análisis exploratorio de datos.

22.1 Ejemplo actuarial

Una aseguradora quiere saber por qué los jóvenes no adquieren seguros de vida.

Todavía no sabe si el problema es:

  • precio;
  • falta de conocimiento;
  • baja percepción de riesgo;
  • productos inadecuados;
  • canales;
  • desconfianza.

Una primera investigación exploratoria puede ayudar a identificar explicaciones.


23 Investigación descriptiva

Se utiliza para cuantificar características del mercado.

Responde preguntas como:

  • ¿quién?;
  • ¿qué?;
  • ¿cuánto?;
  • ¿cuándo?;
  • ¿dónde?;
  • ¿con qué frecuencia?

Ejemplos:

  • porcentaje de clientes que desea renovar;
  • edad promedio;
  • nivel promedio de satisfacción;
  • participación de canales;
  • distribución del mercado por región;
  • proporción que conoce determinado producto.

24 Investigación causal

Busca determinar si cambios en una variable producen cambios en otra.

Ejemplo:

Una aseguradora quiere conocer si modificar la forma de presentar una cotización aumenta la aceptación.

Podríamos comparar:

  • grupo A: cotización tradicional;
  • grupo B: nueva presentación.

Si la asignación y el diseño son adecuados, podemos aproximarnos a una inferencia causal.


25 Exploratorio, descriptivo o causal

Veamos algunos escenarios.

25.0.1 Situación A

No sabemos por qué los clientes están cancelando.

Diseño principal:

Exploratorio.

25.0.2 Situación B

Queremos conocer qué porcentaje de clientes considera cara la prima.

Diseño principal:

Descriptivo.

25.0.3 Situación C

Queremos conocer si ofrecer un descuento aumenta la renovación.

Diseño principal:

Causal.



26 Diseños transversales y longitudinales

Otra decisión importante es el momento en que observamos a los individuos.

26.1 Estudio transversal

Observamos una población en un punto o periodo específico.

Ejemplo:

Encuesta de satisfacción realizada durante octubre de 2026.

Podemos pensar en una fotografía.

26.2 Estudio longitudinal

Observamos las mismas unidades repetidamente.

Ejemplo:

Seguimos durante 24 meses a los mismos asegurados y registramos:

  • prima;
  • siniestros;
  • satisfacción;
  • renovación.

Podemos pensar en una película.


27 Ejemplo actuarial

Supongamos que queremos estudiar abandono.

27.0.1 Diseño transversal

Cliente       Octubre 2026
A             Renueva
B             No renueva
C             Renueva

27.0.2 Diseño longitudinal

Cliente     2024     2025     2026
A           Sí       Sí       Sí
B           Sí       Sí       No
C           Sí       No       -

El segundo diseño permite estudiar trayectorias.


28 Fuentes de error

Toda investigación contiene error.

El objetivo no es imaginar que podemos eliminarlo por completo.

El objetivo es:

  • identificarlo;
  • minimizarlo;
  • cuantificarlo cuando sea posible;
  • reconocer sus implicaciones.

28.1 Error de muestreo

Surge porque estudiamos una muestra y no necesariamente toda la población.

Supongamos una población con edad promedio conocida.

set.seed(2026)

poblacion_edad <- round(
  rnorm(
    n = 100000,
    mean = 42,
    sd = 13
  )
)

mean(poblacion_edad)
## [1] 42.0142

Tomemos diferentes muestras de 100 personas.

set.seed(2026)

medias_muestrales <- replicate(
  500,
  mean(
    sample(
      poblacion_edad,
      size = 100
    )
  )
)

summary(medias_muestrales)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   37.63   41.15   42.05   42.04   42.89   47.53

Visualicemos.

data.frame(
  media = medias_muestrales
) %>%
  ggplot(
    aes(x = media)
  ) +
  geom_histogram(
    bins = 30,
    color = "white"
  ) +
  geom_vline(
    xintercept = mean(poblacion_edad),
    linetype = "dashed",
    linewidth = 1
  ) +
  labs(
    title = "Variabilidad entre muestras",
    subtitle = "500 muestras aleatorias de tamaño 100",
    x = "Edad promedio de la muestra",
    y = "Frecuencia"
  ) +
  theme_minimal()

Observe que diferentes muestras generan diferentes estimaciones.

Eso es parte de la variabilidad muestral.

Más adelante estudiaremos formalmente:

  • error estándar;
  • intervalos de confianza;
  • tamaño de muestra.

29 Error no atribuible al muestreo

También pueden aparecer errores por:

  • mala definición de población;
  • preguntas ambiguas;
  • falta de respuesta;
  • errores de registro;
  • errores de codificación;
  • fraude;
  • datos faltantes;
  • errores de análisis;
  • instrumentos deficientes.

29.0.1 Punto fundamental

Aumentar el tamaño de la muestra puede reducir el error muestral.

Pero una muestra gigantesca no corrige un cuestionario mal diseñado.


30 Investigación de mercados, SIM y apoyo a decisiones

Las organizaciones producen información continuamente.

Por ejemplo, una aseguradora puede disponer de:

  • pólizas;
  • primas;
  • cancelaciones;
  • reclamaciones;
  • canales;
  • agentes;
  • clientes;
  • campañas;
  • cotizaciones.
Bases internas
      +
Datos externos
      +
Investigaciones específicas
      ↓
Preparación
      ↓
Análisis
      ↓
Visualización
      ↓
Información
      ↓
Decisión

31 Construcción del caso de trabajo del curso

Crearemos una base simulada de clientes de seguros.

set.seed(2026)

n <- 1200

mercado_seguros <- data.frame(
  id = 1:n,
  
  edad = round(
    pmin(
      pmax(
        rnorm(n, 42, 12),
        18
      ),
      75
    )
  ),
  
  ingreso_mensual = round(
    rlnorm(
      n,
      log(9000),
      0.55
    ),
    0
  ),
  
  region = sample(
    c(
      "Metropolitana",
      "Norte",
      "Occidente",
      "Oriente",
      "Sur"
    ),
    n,
    replace = TRUE,
    prob = c(
      0.42,
      0.12,
      0.18,
      0.15,
      0.13
    )
  ),
  
  canal = sample(
    c(
      "Agente",
      "Digital",
      "Sucursal",
      "Bancaseguros"
    ),
    n,
    replace = TRUE,
    prob = c(
      0.35,
      0.30,
      0.20,
      0.15
    )
  ),
  
  antiguedad = pmax(
    1,
    round(
      rgamma(
        n,
        shape = 2.5,
        scale = 2
      )
    )
  ),
  
  siniestros_2a = rpois(
    n,
    lambda = 0.35
  ),
  
  satisfaccion = sample(
    1:10,
    n,
    replace = TRUE,
    prob = c(
      0.02,
      0.03,
      0.04,
      0.06,
      0.10,
      0.13,
      0.18,
      0.19,
      0.15,
      0.10
    )
  ),
  
  incremento_prima = round(
    pmax(
      rnorm(
        n,
        mean = 8,
        sd = 6
      ),
      -5
    ),
    1
  )
)

Ahora construiremos una intención de renovación simulada.

La construiremos de manera que dependa parcialmente de:

  • satisfacción;
  • incremento de prima;
  • antigüedad;
  • experiencia de siniestro.
indice_renovacion <-
  0.45 * mercado_seguros$satisfaccion -
  0.10 * mercado_seguros$incremento_prima +
  0.05 * mercado_seguros$antiguedad -
  0.20 * mercado_seguros$siniestros_2a +
  rnorm(n, 0, 1.5)

mercado_seguros$intencion_renovar <- cut(
  indice_renovacion,
  breaks = quantile(
    indice_renovacion,
    probs = seq(0, 1, 0.2)
  ),
  include.lowest = TRUE,
  labels = 1:5
)

mercado_seguros$intencion_renovar <- as.integer(
  as.character(
    mercado_seguros$intencion_renovar
  )
)

Crearemos también una variable binaria de renovación observada.

prob_renovar <- plogis(
  -0.5 +
  0.35 * mercado_seguros$satisfaccion -
  0.09 * mercado_seguros$incremento_prima +
  0.04 * mercado_seguros$antiguedad -
  0.15 * mercado_seguros$siniestros_2a
)

mercado_seguros$renueva <- rbinom(
  n,
  size = 1,
  prob = prob_renovar
)

mercado_seguros$renueva <- ifelse(
  mercado_seguros$renueva == 1,
  "Sí",
  "No"
)

Guardemos la base para utilizarla posteriormente.

write.csv(
  mercado_seguros,
  "mercado_seguros_clase1.csv",
  row.names = FALSE
)

32 Inspección inicial

Supongamos que recibimos la base y todavía no conocemos su contenido.

La primera instrucción sería:

head(mercado_seguros)

Luego:

str(mercado_seguros)
## 'data.frame':    1200 obs. of  11 variables:
##  $ id               : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ edad             : num  48 29 44 41 34 18 33 30 43 36 ...
##  $ ingreso_mensual  : num  10569 13489 8979 7042 15722 ...
##  $ region           : chr  "Oriente" "Metropolitana" "Metropolitana" "Metropolitana" ...
##  $ canal            : chr  "Agente" "Agente" "Digital" "Digital" ...
##  $ antiguedad       : num  10 4 5 1 5 2 4 3 2 3 ...
##  $ siniestros_2a    : int  0 0 1 0 0 0 1 0 0 0 ...
##  $ satisfaccion     : int  8 9 9 7 8 8 9 9 3 8 ...
##  $ incremento_prima : num  21.2 6.7 1.9 9 13.3 8.3 7.6 9.5 8.6 0.1 ...
##  $ intencion_renovar: int  1 4 5 1 2 4 4 5 2 1 ...
##  $ renueva          : chr  "No" "Sí" "Sí" "No" ...

Dimensiones:

dim(mercado_seguros)
## [1] 1200   11

Nombres:

names(mercado_seguros)
##  [1] "id"                "edad"              "ingreso_mensual"  
##  [4] "region"            "canal"             "antiguedad"       
##  [7] "siniestros_2a"     "satisfaccion"      "incremento_prima" 
## [10] "intencion_renovar" "renueva"

Resumen:

summary(mercado_seguros)
##        id              edad       ingreso_mensual       region    
##  Min.   :   1.0   Min.   :18.00   Min.   : 1193   Length   :1200  
##  1st Qu.: 300.8   1st Qu.:34.00   1st Qu.: 6224   N.unique :   5  
##  Median : 600.5   Median :42.00   Median : 8835   N.blank  :   0  
##  Mean   : 600.5   Mean   :42.32   Mean   :10181   Min.nchar:   3  
##  3rd Qu.: 900.2   3rd Qu.:50.00   3rd Qu.:12664   Max.nchar:  13  
##  Max.   :1200.0   Max.   :75.00   Max.   :38501                   
##        canal        antiguedad     siniestros_2a     satisfaccion   
##  Length   :1200   Min.   : 1.000   Min.   :0.0000   Min.   : 1.000  
##  N.unique :   4   1st Qu.: 3.000   1st Qu.:0.0000   1st Qu.: 5.000  
##  N.blank  :   0   Median : 4.000   Median :0.0000   Median : 7.000  
##  Min.nchar:   6   Mean   : 5.146   Mean   :0.3667   Mean   : 6.808  
##  Max.nchar:  12   3rd Qu.: 7.000   3rd Qu.:1.0000   3rd Qu.: 8.000  
##                   Max.   :23.000   Max.   :4.0000   Max.   :10.000  
##  incremento_prima intencion_renovar      renueva    
##  Min.   :-5.000   Min.   :1         Length   :1200  
##  1st Qu.: 4.500   1st Qu.:2         N.unique :   2  
##  Median : 8.200   Median :3         N.blank  :   0  
##  Mean   : 8.311   Mean   :3         Min.nchar:   2  
##  3rd Qu.:12.200   3rd Qu.:4         Max.nchar:   2  
##  Max.   :29.700   Max.   :5

33 Diccionario inicial de variables

diccionario <- data.frame(
  Variable = names(mercado_seguros),
  Descripcion = c(
    "Identificador",
    "Edad del cliente",
    "Ingreso mensual estimado",
    "Región",
    "Canal principal",
    "Antigüedad como cliente",
    "Número de siniestros en los últimos dos años",
    "Satisfacción de 1 a 10",
    "Incremento porcentual de la prima",
    "Intención de renovación de 1 a 5",
    "Renovación observada"
  )
)

knitr::kable(
  diccionario,
  caption = "Diccionario inicial de variables"
)
Diccionario inicial de variables
Variable Descripcion
id Identificador
edad Edad del cliente
ingreso_mensual Ingreso mensual estimado
region Región
canal Canal principal
antiguedad Antigüedad como cliente
siniestros_2a Número de siniestros en los últimos dos años
satisfaccion Satisfacción de 1 a 10
incremento_prima Incremento porcentual de la prima
intencion_renovar Intención de renovación de 1 a 5
renueva Renovación observada

34 Pregunta exploratoria 1: ¿Quiénes integran el mercado?

Veamos la edad.

summary(
  mercado_seguros$edad
)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   18.00   34.00   42.00   42.32   50.00   75.00

Visualicemos.

ggplot(
  mercado_seguros,
  aes(x = edad)
) +
  geom_histogram(
    bins = 25,
    color = "white"
  ) +
  labs(
    title = "Distribución de edad",
    x = "Edad",
    y = "Número de clientes"
  ) +
  theme_minimal()

Esta gráfica responde una pregunta descriptiva.

No explica por qué ocurre algo.


35 Pregunta exploratoria 2: ¿Dónde están los clientes?

tabla_region <- table(
  mercado_seguros$region
)

tabla_region
## 
## Metropolitana         Norte     Occidente       Oriente           Sur 
##           497           143           228           193           139

Porcentajes:

round(
  prop.table(tabla_region) * 100,
  1
)
## 
## Metropolitana         Norte     Occidente       Oriente           Sur 
##          41.4          11.9          19.0          16.1          11.6

Gráfico:

mercado_seguros %>%
  count(region) %>%
  mutate(
    porcentaje = n / sum(n)
  ) %>%
  ggplot(
    aes(
      x = reorder(region, n),
      y = porcentaje
    )
  ) +
  geom_col() +
  coord_flip() +
  scale_y_continuous(
    labels = scales::percent
  ) +
  labs(
    title = "Distribución territorial de clientes",
    x = NULL,
    y = "Porcentaje"
  ) +
  theme_minimal()


36 Pregunta exploratoria 3: ¿Cómo es la satisfacción?

summary(
  mercado_seguros$satisfaccion
)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.000   5.000   7.000   6.808   8.000  10.000

Distribución:

mercado_seguros %>%
  count(satisfaccion) %>%
  ggplot(
    aes(
      x = factor(satisfaccion),
      y = n
    )
  ) +
  geom_col() +
  labs(
    title = "Satisfacción de los clientes",
    x = "Satisfacción",
    y = "Número de clientes"
  ) +
  theme_minimal()


37 Pregunta exploratoria 4: ¿Qué porcentaje renueva?

table(
  mercado_seguros$renueva
)
## 
##  No  Sí 
## 310 890
round(
  prop.table(
    table(
      mercado_seguros$renueva
    )
  ) * 100,
  1
)
## 
##   No   Sí 
## 25.8 74.2

38 Del análisis descriptivo a nuevas preguntas

Supongamos que observamos una tasa considerable de no renovación.

La siguiente pregunta no debería ser automáticamente:

¿Cómo puedo construir una regresión?

La pregunta correcta es:

¿Qué hipótesis razonables podrían explicar la no renovación?

Podríamos explorar:

  • incremento de prima;
  • satisfacción;
  • siniestros;
  • antigüedad;
  • canal;
  • región.

39 Prima y renovación

Calculemos el incremento promedio según renovación.

mercado_seguros %>%
  group_by(renueva) %>%
  summarise(
    n = n(),
    incremento_promedio = mean(incremento_prima),
    mediana_incremento = median(incremento_prima)
  )

Visualicemos.

ggplot(
  mercado_seguros,
  aes(
    x = renueva,
    y = incremento_prima
  )
) +
  geom_boxplot() +
  labs(
    title = "Incremento de prima según renovación",
    x = "Renovación",
    y = "Incremento de prima (%)"
  ) +
  theme_minimal()

¿Qué podemos decir?

Podemos decir que existen diferencias descriptivas entre los grupos.

Todavía no podemos decir que:

“el incremento de prima causa la no renovación”.

¿Por qué?

Porque no hemos controlado:

  • satisfacción;
  • antigüedad;
  • siniestros;
  • ingreso;
  • posibles variables omitidas.

40 Satisfacción y renovación

mercado_seguros %>%
  group_by(renueva) %>%
  summarise(
    satisfaccion_promedio = mean(satisfaccion),
    mediana = median(satisfaccion),
    n = n()
  )
ggplot(
  mercado_seguros,
  aes(
    x = renueva,
    y = satisfaccion
  )
) +
  geom_boxplot() +
  labs(
    title = "Satisfacción según renovación",
    x = "Renovación",
    y = "Satisfacción"
  ) +
  theme_minimal()

Ahora tenemos otra pista.

Quizá el problema sea más complejo que simplemente el precio.


41 Combinando dos dimensiones

Podemos explorar satisfacción e incremento de prima.

ggplot(
  mercado_seguros,
  aes(
    x = incremento_prima,
    y = satisfaccion
  )
) +
  geom_point(
    alpha = 0.35
  ) +
  facet_wrap(
    ~ renueva
  ) +
  labs(
    title = "Prima y satisfacción según renovación",
    x = "Incremento de prima (%)",
    y = "Satisfacción"
  ) +
  theme_minimal()

Esta gráfica puede generar nuevas hipótesis.

Por ejemplo:

La combinación de incrementos altos y baja satisfacción podría estar asociada con menor renovación.

Observe la dinámica:

DATOS
  ↓
EXPLORACIÓN
  ↓
PATRÓN
  ↓
PREGUNTA
  ↓
HIPÓTESIS
  ↓
ANÁLISIS POSTERIOR

42 Ejemplo: de observación a pregunta formal

Después de la exploración podemos formular:

42.0.1 Observación

Los clientes que no renuevan parecen presentar:

  • mayor incremento de prima;
  • menor satisfacción.

42.0.2 Pregunta

¿Cómo se relacionan el incremento de prima y la satisfacción con la probabilidad de renovación?

42.0.3 Hipótesis 1

A mayor incremento de prima, menor probabilidad de renovación.

42.0.4 Hipótesis 2

A mayor satisfacción, mayor probabilidad de renovación.

42.0.5 Diseño inicial

Descriptivo / explicativo observacional.

Más adelante utilizaremos regresión logística para analizar esta pregunta.


43 Correlación no significa causalidad

Esta distinción será recurrente durante el curso.

Supongamos que observamos:

\[ X \uparrow \quad \text{cuando} \quad Y \uparrow \]

Eso demuestra asociación.

No necesariamente demuestra:

\[ X \rightarrow Y \]

Puede existir:

\[ Z \rightarrow X \]

y simultáneamente:

\[ Z \rightarrow Y \]


44 Ejemplo actuarial de confusión

Imagine que encontramos:

Los clientes con primas más altas tienen más siniestros.

¿Podemos concluir que aumentar la prima causa siniestros?

No.

Probablemente ambas variables están relacionadas con:

  • exposición;
  • tipo de vehículo;
  • edad;
  • suma asegurada;
  • zona;
  • características del riesgo.

La estructura podría ser:

Nivel de riesgo
     ↓
 ┌─────────────┐
 ↓             ↓
Prima      Siniestros

La prima y los siniestros aparecen asociados, pero una variable subyacente puede explicar parte de la relación.


45 Ejemplo de diseño causal

Suponga que la empresa desea saber:

¿Enviar un mensaje personalizado aumenta la renovación?

Podemos imaginar un experimento.

set.seed(100)

experimento <- data.frame(
  grupo = rep(
    c(
      "Mensaje estándar",
      "Mensaje personalizado"
    ),
    each = 500
  )
)

experimento$renueva <- c(
  rbinom(
    500,
    1,
    0.67
  ),
  rbinom(
    500,
    1,
    0.75
  )
)

aggregate(
  renueva ~ grupo,
  data = experimento,
  FUN = mean
)

Visualicemos.

experimento %>%
  group_by(grupo) %>%
  summarise(
    tasa = mean(renueva)
  ) %>%
  ggplot(
    aes(
      x = grupo,
      y = tasa
    )
  ) +
  geom_col() +
  scale_y_continuous(
    labels = scales::percent
  ) +
  labs(
    title = "Tasa de renovación por tratamiento",
    x = NULL,
    y = "Tasa de renovación"
  ) +
  theme_minimal()

La lógica causal requiere mucho más que observar una diferencia.

Necesitamos considerar:

  • asignación;
  • comparabilidad;
  • variables extrañas;
  • tamaño de muestra;
  • azar;
  • validez interna;
  • validez externa.

Lo estudiaremos con mayor detalle posteriormente.


46 Un principio importante

Durante este curso evitaremos la lógica:

Tengo una base
      ↓
¿Qué análisis puedo hacer?

Intentaremos utilizar:

Tengo una decisión
      ↓
¿Qué necesito saber?
      ↓
¿Qué pregunta debo responder?
      ↓
¿Qué datos necesito?
      ↓
¿Qué análisis corresponde?

Primero la pregunta. Después el método.

No utilizaremos una técnica estadística simplemente porque esté disponible.


47 Errores frecuentes al formular investigaciones

47.1 Error 1. Empezar por la técnica

“Quiero hacer una regresión.”

Pregunta correcta:

¿Qué problema requiere un modelo de regresión?


47.2 Error 2. Confundir síntoma con problema

Síntoma:

Las ventas disminuyeron.

Problema:

Podría ser:

  • precio;
  • producto;
  • competencia;
  • canal;
  • mercado;
  • percepción.

47.3 Error 3. Pregunta demasiado amplia

¿Qué piensa la gente de los seguros?

Debe delimitarse:

  • qué personas;
  • qué seguros;
  • qué dimensión;
  • qué territorio;
  • qué periodo.

47.4 Error 4. Asumir causalidad

Los clientes que pagan más cancelan más, por lo tanto el precio causa cancelación.

Una asociación observada no demuestra causalidad.


47.5 Error 5. Diseñar primero la encuesta

No deberíamos preguntar:

“¿Qué preguntas pongo en el cuestionario?”

antes de responder:

“¿Qué información necesito?”


48 Mapa conceptual final

                         DECISIÓN EMPRESARIAL
                                  │
                                  ▼
                         DEFINIR EL PROBLEMA
                                  │
             ┌────────────────────┴─────────────────────┐
             │                                          │
             ▼                                          ▼
      CONTEXTO DEL PROBLEMA                    INFORMACIÓN EXISTENTE
             │                                          │
             └────────────────────┬─────────────────────┘
                                  ▼
                       PROBLEMA DE INVESTIGACIÓN
                                  │
                                  ▼
                              OBJETIVOS
                                  │
                                  ▼
                     PREGUNTAS DE INVESTIGACIÓN
                                  │
                                  ▼
                              HIPÓTESIS
                                  │
                                  ▼
                              VARIABLES
                                  │
                                  ▼
                    INFORMACIÓN REQUERIDA
                                  │
                                  ▼
                     DISEÑO DE INVESTIGACIÓN
                       /          |          \
                      /           |           \
             EXPLORATORIO   DESCRIPTIVO     CAUSAL
                      \           |           /
                       \          |          /
                                  ▼
                                DATOS
                                  │
                                  ▼
                                  R
                                  │
                                  ▼
                             EVIDENCIA
                                  │
                                  ▼
                         TOMA DE DECISIONES

49 Referencia base

Malhotra, N. K. (2008). Investigación de mercados. Un enfoque aplicado. Quinta edición. Pearson Educación.


LS0tCnRpdGxlOiAiRGUgbGEgZGVjaXNpw7NuIGVtcHJlc2FyaWFsIGEgbGEgcHJlZ3VudGEgZGUgaW52ZXN0aWdhY2nDs24iCnN1YnRpdGxlOiAiTWFlc3RyaWEgZW4gY2llbmNpYXMgYWN0dWFyaWFsZXMgYXBsaWNhZGFzIgphdXRob3I6ICJDdXJzbyBkZSBBbsOhbGlzaXMgZGUgTWVyY2FkbyIKZGF0ZTogImByIGZvcm1hdChTeXMuRGF0ZSgpLCAnJWQvJW0vJVknKWAiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogZmFsc2UKICAgICAgc21vb3RoX3Njcm9sbDogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIHRoZW1lOiBmbGF0bHkKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIGRmX3ByaW50OiBwYWdlZAogICAgc2VsZl9jb250YWluZWQ6IHRydWUKLS0tCgo8c3R5bGU+CmJvZHkgewogIGZvbnQtc2l6ZTogMTdweDsKICBsaW5lLWhlaWdodDogMS42NTsKfQoKaDEsIGgyLCBoMyB7CiAgZm9udC13ZWlnaHQ6IDYwMDsKfQoKYmxvY2txdW90ZSB7CiAgYm9yZGVyLWxlZnQ6IDVweCBzb2xpZCAjMmMzZTUwOwogIHBhZGRpbmc6IDEwcHggMjBweDsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjdmN2Y3Owp9CgouY2FqYSB7CiAgcGFkZGluZzogMThweDsKICBtYXJnaW46IDE4cHggMDsKICBib3JkZXItcmFkaXVzOiA3cHg7CiAgYmFja2dyb3VuZC1jb2xvcjogI2Y1ZjdmOTsKICBib3JkZXItbGVmdDogNnB4IHNvbGlkICMzNDQ5NWU7Cn0KCi5jYWphLWVqZW1wbG8gewogIHBhZGRpbmc6IDE4cHg7CiAgbWFyZ2luOiAxOHB4IDA7CiAgYm9yZGVyLXJhZGl1czogN3B4OwogIGJhY2tncm91bmQtY29sb3I6ICNmM2Y4ZmM7CiAgYm9yZGVyLWxlZnQ6IDZweCBzb2xpZCAjMzQ5OGRiOwp9CgouY2FqYS1hY3R1YXJpYWwgewogIHBhZGRpbmc6IDE4cHg7CiAgbWFyZ2luOiAxOHB4IDA7CiAgYm9yZGVyLXJhZGl1czogN3B4OwogIGJhY2tncm91bmQtY29sb3I6ICNmNGZhZjY7CiAgYm9yZGVyLWxlZnQ6IDZweCBzb2xpZCAjMjdhZTYwOwp9CgouY2FqYS1hbGVydGEgewogIHBhZGRpbmc6IDE4cHg7CiAgbWFyZ2luOiAxOHB4IDA7CiAgYm9yZGVyLXJhZGl1czogN3B4OwogIGJhY2tncm91bmQtY29sb3I6ICNmZmY4ZjI7CiAgYm9yZGVyLWxlZnQ6IDZweCBzb2xpZCAjZTY3ZTIyOwp9CgouY2FqYS1wcmVndW50YSB7CiAgcGFkZGluZzogMThweDsKICBtYXJnaW46IDE4cHggMDsKICBib3JkZXItcmFkaXVzOiA3cHg7CiAgYmFja2dyb3VuZC1jb2xvcjogI2ZhZjVmYzsKICBib3JkZXItbGVmdDogNnB4IHNvbGlkICM4ZTQ0YWQ7Cn0KCi5jYWphLXJlc3VtZW4gewogIHBhZGRpbmc6IDIwcHg7CiAgbWFyZ2luOiAyMHB4IDA7CiAgYm9yZGVyLXJhZGl1czogN3B4OwogIGJhY2tncm91bmQtY29sb3I6ICNlZWY1Zjk7CiAgYm9yZGVyOiAxcHggc29saWQgI2NjZDZkZDsKfQoKdGFibGUgewogIGZvbnQtc2l6ZTogMTVweDsKfQoKZGV0YWlscyB7CiAgbWFyZ2luOiAxMnB4IDA7CiAgcGFkZGluZzogMTJweDsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjhmOWZhOwogIGJvcmRlci1yYWRpdXM6IDVweDsKfQoKc3VtbWFyeSB7CiAgY3Vyc29yOiBwb2ludGVyOwogIGZvbnQtd2VpZ2h0OiBib2xkOwp9Cjwvc3R5bGU+CgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVjaG8gPSBUUlVFLAogIHdhcm5pbmcgPSBGQUxTRSwKICBtZXNzYWdlID0gRkFMU0UsCiAgZmlnLmFsaWduID0gImNlbnRlciIsCiAgZmlnLndpZHRoID0gOCwKICBmaWcuaGVpZ2h0ID0gNQopCgpzZXQuc2VlZCgyMDI2KQoKcGFxdWV0ZXMgPC0gYygKICAiZ2dwbG90MiIsCiAgImRwbHlyIiwKICAidGlkeXIiLAogICJrbml0ciIsCiAgInNjYWxlcyIKKQoKZmFsdGFudGVzIDwtIHBhcXVldGVzWwogICFwYXF1ZXRlcyAlaW4lIHJvd25hbWVzKGluc3RhbGxlZC5wYWNrYWdlcygpKQpdCgppZihsZW5ndGgoZmFsdGFudGVzKSA+IDApewogIGluc3RhbGwucGFja2FnZXMoZmFsdGFudGVzKQp9CgppbnZpc2libGUoCiAgbGFwcGx5KAogICAgcGFxdWV0ZXMsCiAgICBsaWJyYXJ5LAogICAgY2hhcmFjdGVyLm9ubHkgPSBUUlVFCiAgKQopCmBgYAoKPiAqKkFwcmVuZGVyIGEgY29udmVydGlyIHVuYSBkZWNpc2nDs24gZW1wcmVzYXJpYWwgZW4gdW4gcHJvYmxlbWEgcXVlIHB1ZWRhIGludmVzdGlnYXJzZSBtZWRpYW50ZSBkYXRvcy4qKgoKRW4gaW52ZXN0aWdhY2nDs24gZGUgbWVyY2Fkb3MsIGVsIGFuw6FsaXNpcyBlc3RhZMOtc3RpY28gbm8gY29taWVuemEgY3VhbmRvIGFicmltb3MgUi4KCkFudGVzIGRlIGFuYWxpemFyIGRhdG9zIGRlYmVtb3MgZXN0YWJsZWNlcjoKCjEuIHF1w6kgZGVjaXNpw7NuIGRlYmUgdG9tYXJzZTsKMi4gY3XDoWwgZXMgZWwgcHJvYmxlbWEgcmVhbDsKMy4gcXXDqSBpbmZvcm1hY2nDs24gbmVjZXNpdGFtb3M7CjQuIHF1w6kgcHJlZ3VudGFzIHBvZGVtb3MgcmVzcG9uZGVyOwo1LiBxdcOpIHZhcmlhYmxlcyByZXByZXNlbnRhbiBlc2FzIHByZWd1bnRhczsKNi4gcXXDqSBkaXNlw7FvIGRlIGludmVzdGlnYWNpw7NuIGVzIGFwcm9waWFkbzsKNy4geSBzb2xhbWVudGUgZW50b25jZXMsIHF1w6kgZGF0b3MgZGViZW1vcyBhbmFsaXphci4KCgpQb2RlbW9zIGRpc3BvbmVyIGRlIG1pbGxvbmVzIGRlIG9ic2VydmFjaW9uZXMgeSwgYXVuIGFzw60sIG5vIHRlbmVyIGNsYXJhbWVudGUgaWRlbnRpZmljYWRvIHF1w6kgcHJlZ3VudGEgZGViZSByZXNwb25kZXIuCgpQb3IgZWplbXBsbzoKCi0gdW5hIGFzZWd1cmFkb3JhIG9ic2VydmEgdW5hIHJlZHVjY2nDs24gZGUgcmVub3ZhY2lvbmVzOwotIHVuYSBjb21wYcOxw61hIHF1aWVyZSBpbnRyb2R1Y2lyIHVuIG51ZXZvIHNlZ3VybzsKLSBhdW1lbnRhIGxhIGZyZWN1ZW5jaWEgZGUgcmVjbGFtYWNpb25lczsKLSBkZXRlcm1pbmFkb3MgY2xpZW50ZXMgYWJhbmRvbmFuIHVuYSBww7NsaXphOwotIGV4aXN0ZSBwb2NhIGRlbWFuZGEgcG9yIHVuIHByb2R1Y3RvIGRlIG1pY3Jvc2VndXJvOwotIHVuYSBhc2VndXJhZG9yYSBjb25zaWRlcmEgbW9kaWZpY2FyIHVuYSBwcmltYTsKLSB1bmEgZW50aWRhZCBwcmV2aXNpb25hbCBxdWllcmUgYXVtZW50YXIgbGEgcGFydGljaXBhY2nDs24gdm9sdW50YXJpYTsKLSB1bmEgY29tcGHDscOtYSBxdWllcmUgaWRlbnRpZmljYXIgbnVldm9zIHNlZ21lbnRvcyBkZSBtZXJjYWRvLgoKRW4gdG9kb3MgZXN0b3MgY2Fzb3MgZXhpc3RlIGluaWNpYWxtZW50ZSB1bmEgKipkZWNpc2nDs24gZW1wcmVzYXJpYWwqKi4KCkxhIGludmVzdGlnYWNpw7NuIHBlcm1pdGUgdHJhbnNmb3JtYXIgZXNhIGRlY2lzacOzbiBlbiB1bmEgKipwcmVndW50YSBzdXNjZXB0aWJsZSBkZSBzZXIgcmVzcG9uZGlkYSBtZWRpYW50ZSBldmlkZW5jaWEqKi4KCi0tLQoKIyBSdXRhIGRlIGFwcmVuZGl6YWplCgpEdXJhbnRlIGVzdGEgY2xhc2Ugc2VndWlyZW1vcyBsYSBzaWd1aWVudGUgc2VjdWVuY2lhOgo8ZGl2IGNsYXNzPSJjYWphIj4KKipEZWNpc2nDs24gZW1wcmVzYXJpYWwqKiAtCioqUHJvYmxlbWEgZGUgaW52ZXN0aWdhY2nDs24qKiAtCioqT2JqZXRpdm9zKiogLQoqKlByZWd1bnRhcyBkZSBpbnZlc3RpZ2FjacOzbioqIC0KKipIaXDDs3Rlc2lzKiogLQoqKlZhcmlhYmxlcyoqIC0KKipJbmZvcm1hY2nDs24gcmVxdWVyaWRhKiogLQoqKkRpc2XDsW8gZGUgaW52ZXN0aWdhY2nDs24qKiAtCioqRGF0b3MqKiAtCioqRXhwbG9yYWNpw7NuIGluaWNpYWwqKiAtCioqRXZpZGVuY2lhIHBhcmEgbGEgZGVjaXNpw7NuKiogLQo8L2Rpdj4KCiMgwr9RdcOpIGVzIGxhIGludmVzdGlnYWNpw7NuIGRlIG1lcmNhZG9zPwoKTGEgaW52ZXN0aWdhY2nDs24gZGUgbWVyY2Fkb3MgcHVlZGUgZW50ZW5kZXJzZSBjb21vIHVuICoqcHJvY2VzbyBzaXN0ZW3DoXRpY28gcGFyYSBnZW5lcmFyIGluZm9ybWFjacOzbiBxdWUgY29udHJpYnV5YSBhIGxhIHRvbWEgZGUgZGVjaXNpb25lcyByZWxhY2lvbmFkYXMgY29uIHVuIG1lcmNhZG8qKi4KCkxvIGltcG9ydGFudGUgZGUgZXN0YSBkZWZpbmljacOzbiBubyBlcyBzb2xhbWVudGUgbGEgcGFsYWJyYSAqbWVyY2FkbyouCgpMYSBpbnZlc3RpZ2FjacOzbiBubyBjb25zaXN0ZSBzaW1wbGVtZW50ZSBlbiByZWNvcGlsYXIgZGF0b3MuCgpUYW1wb2NvIGNvbnNpc3RlIHNvbGFtZW50ZSBlbiBhcGxpY2FyIGVuY3Vlc3Rhcy4KCk11Y2hvIG1lbm9zIGNvbnNpc3RlIMO6bmljYW1lbnRlIGVuIGFwbGljYXIgdMOpY25pY2FzIGVzdGFkw61zdGljYXMuCgo8ZGl2IGNsYXNzPSJjYWphLWFsZXJ0YSI+CgojIyBJZGVhIGZ1bmRhbWVudGFsCgpUZW5lciBkYXRvcyBubyBzaWduaWZpY2EgdGVuZXIgaW5mb3JtYWNpw7NuLgoKVGVuZXIgaW5mb3JtYWNpw7NuIG5vIHNpZ25pZmljYSB0ZW5lciBjb25vY2ltaWVudG8uCgpZIHRlbmVyIGNvbm9jaW1pZW50byBubyBpbXBsaWNhIGF1dG9tw6F0aWNhbWVudGUgdW5hIGJ1ZW5hIGRlY2lzacOzbi4KCkVsIHRyYWJham8gZGVsIGludmVzdGlnYWRvciBjb25zaXN0ZSBlbiBjb25zdHJ1aXIgdW5hIGNvbmV4acOzbiBsw7NnaWNhIGVudHJlOgoKKipwcm9ibGVtYSDihpIgZXZpZGVuY2lhIOKGkiBpbnRlcnByZXRhY2nDs24g4oaSIGRlY2lzacOzbi4qKgoKPC9kaXY+CgojIyBJbnZlc3RpZ2FjacOzbiB5IHRvbWEgZGUgZGVjaXNpb25lcwoKQ29uc2lkZXJlIGVsIHNpZ3VpZW50ZSBlamVtcGxvLgoKVW5hIGFzZWd1cmFkb3JhIG9ic2VydmEgcXVlIGxhIHRhc2EgZGUgcmVub3ZhY2nDs24gZGUgdW4gc2VndXJvIGRlIGF1dG9tw7N2aWwgY2F5w7MgZGUgODIlIGEgNzQlLgoKTGEgYWRtaW5pc3RyYWNpw7NuIHBvZHLDrWEgaW5tZWRpYXRhbWVudGUgY29uY2x1aXI6Cgo+IOKAnEVsIHByb2JsZW1hIGVzIHF1ZSBsYSBwcmltYSBlcyBkZW1hc2lhZG8gYWx0YS7igJ0KClBlcm8gZXNhIGFmaXJtYWNpw7NuIHRvZGF2w61hIG5vIGhhIHNpZG8gZGVtb3N0cmFkYS4KCk90cmFzIGV4cGxpY2FjaW9uZXMgcG9kcsOtYW4gc2VyOgoKLSBtYWxhIGF0ZW5jacOzbjsKLSBhdW1lbnRvIGRlIGNvbXBldGVuY2lhOwotIG1vZGlmaWNhY2lvbmVzIGVuIGxhcyBjb2JlcnR1cmFzOwotIG1hbGEgZXhwZXJpZW5jaWEgZHVyYW50ZSB1biBzaW5pZXN0cm87Ci0gY2FtYmlvcyBlbiBlbCBpbmdyZXNvIGRlIGxvcyBjbGllbnRlczsKLSBudWV2b3MgcHJvZHVjdG9zIHN1c3RpdHV0b3M7Ci0gcHJvbW9jaW9uZXMgZGUgY29tcGV0aWRvcmVzOwotIG1vZGlmaWNhY2lvbmVzIGVuIGNhbmFsZXMgZGlnaXRhbGVzOwotIGNhcmFjdGVyw61zdGljYXMgcGFydGljdWxhcmVzIGRlIGRldGVybWluYWRvcyBzZWdtZW50b3MuCgpMYSBpbnZlc3RpZ2FjacOzbiBkZSBtZXJjYWRvcyBidXNjYSByZWR1Y2lyIGVzdGEgaW5jZXJ0aWR1bWJyZS4KCi0tLQoKIyBBcGxpY2FjacOzbiBlbiBjaWVuY2lhcyBhY3R1YXJpYWxlcwoKVHJhZGljaW9uYWxtZW50ZSwgZWwgYW7DoWxpc2lzIGFjdHVhcmlhbCBzZSBjb25jZW50cmEgZW4gZmVuw7NtZW5vcyBjb21vOgoKLSBtb3J0YWxpZGFkOwotIG1vcmJpbGlkYWQ7Ci0gZnJlY3VlbmNpYSBkZSBzaW5pZXN0cm9zOwotIHNldmVyaWRhZDsKLSByZXNlcnZhczsKLSBzb2x2ZW5jaWE7Ci0gcHJpbWFzOwotIHN1cGVydml2ZW5jaWE7Ci0gYWJhbmRvbm87Ci0gcmllc2dvIGZpbmFuY2llcm8uCgpMYSBpbnZlc3RpZ2FjacOzbiBkZSBtZXJjYWRvcyBjb21wbGVtZW50YSBlc3RhIHBlcnNwZWN0aXZhIGluY29ycG9yYW5kbyBwcmVndW50YXMgY29tbzoKCi0gwr9xdcOpIHByb2R1Y3RvcyBkZXNlYSBlbCBjb25zdW1pZG9yPzsKLSDCv3F1w6kgYXRyaWJ1dG9zIHZhbG9yYT87Ci0gwr9xdcOpIHByZWNpbyBlc3TDoSBkaXNwdWVzdG8gYSBhY2VwdGFyPzsKLSDCv3BvciBxdcOpIGFiYW5kb25hIHVuYSBww7NsaXphPzsKLSDCv3F1w6kgY2FuYWwgcHJlZmllcmU/OwotIMK/cXXDqSBzZWdtZW50b3MgdGllbmVuIG1heW9yIGludGVuY2nDs24gZGUgY29tcHJhPzsKLSDCv3F1w6kgcGVyY2VwY2nDs24gdGllbmUgc29icmUgdW5hIGFzZWd1cmFkb3JhPzsKLSDCv2NvbXByZW5kZSBhZGVjdWFkYW1lbnRlIGxhcyBjb2JlcnR1cmFzPzsKLSDCv3F1w6kgZmFjdG9yZXMgaW5mbHV5ZW4gc29icmUgc3UgcmVub3ZhY2nDs24/OwotIMK/cXXDqSBjb21iaW5hY2nDs24gZGUgYmVuZWZpY2lvcyByZXN1bHRhIG3DoXMgYXRyYWN0aXZhPwoKPGRpdiBjbGFzcz0iY2FqYS1hY3R1YXJpYWwiPgoKIyMgUGVyc3BlY3RpdmEgYWN0dWFyaWFsCgpVbiBtb2RlbG8gYWN0dWFyaWFsIHB1ZWRlIHJlc3BvbmRlcjoKCj4gwr9DdcOhbCBkZWJlcsOtYSBzZXIgbGEgcHJpbWEgdMOpY25pY2EgYXNvY2lhZGEgY29uIGRldGVybWluYWRvIG5pdmVsIGRlIHJpZXNnbz8KCkxhIGludmVzdGlnYWNpw7NuIGRlIG1lcmNhZG9zIHB1ZWRlIHJlc3BvbmRlcjoKCj4gwr9Dw7NtbyByZWFjY2lvbmFyw6EgZWwgY29uc3VtaWRvciBmcmVudGUgYSBlc2EgcHJpbWE/CgpTb24gcHJlZ3VudGFzIGRpc3RpbnRhcy4KClBhcmEgdG9tYXIgdW5hIGRlY2lzacOzbiBlbXByZXNhcmlhbCBjb21wbGV0YSBwdWVkZW4gc2VyIG5lY2VzYXJpYXMgYW1iYXMgcmVzcHVlc3Rhcy4KCjwvZGl2PgoKLS0tCgojIERvcyBncmFuZGVzIHByb3DDs3NpdG9zIGRlIGxhIGludmVzdGlnYWNpw7NuCgpQb2RlbW9zIGRpc3Rpbmd1aXIgY29uY2VwdHVhbG1lbnRlIGRvcyBncmFuZGVzIHByb3DDs3NpdG9zLgoKIyMgSW52ZXN0aWdhY2nDs24gcGFyYSBpZGVudGlmaWNhciBwcm9ibGVtYXMKCkJ1c2NhIGRldGVjdGFyIGZlbsOzbWVub3MgcXVlIHF1aXrDoSB0b2RhdsOtYSBubyBzb24gZXZpZGVudGVzLgoKRWplbXBsb3M6CgotIHJlZHVjY2nDs24gZ3JhZHVhbCBkZSBwYXJ0aWNpcGFjacOzbiBkZSBtZXJjYWRvOwotIGNhbWJpbyBlbiBwcmVmZXJlbmNpYXM7Ci0gZGV0ZXJpb3JvIGRlIGltYWdlbjsKLSBhcGFyaWNpw7NuIGRlIG51ZXZvcyBzZWdtZW50b3M7Ci0gbW9kaWZpY2FjacOzbiBkZWwgY29tcG9ydGFtaWVudG8gZGUgY29tcHJhOwotIGNhbWJpb3MgZW4gcGVyY2VwY2nDs24gZGVsIHByZWNpbzsKLSBvcG9ydHVuaWRhZGVzIHBhcmEgbnVldm9zIHByb2R1Y3Rvcy4KCiMjIEludmVzdGlnYWNpw7NuIHBhcmEgcmVzb2x2ZXIgcHJvYmxlbWFzCgpTZSByZWFsaXphIGN1YW5kbyBlbCBwcm9ibGVtYSB5YSBoYSBzaWRvIGlkZW50aWZpY2Fkby4KCkVqZW1wbG9zOgoKLSBkZXRlcm1pbmFyIHF1w6kgcHJpbWEgY29tZXJjaWFsIHJlc3VsdGEgYWNlcHRhYmxlOwotIGVsZWdpciBlbnRyZSBkb3MgcHJvZHVjdG9zOwotIHNlbGVjY2lvbmFyIHVuIGNhbmFsIGRlIGRpc3RyaWJ1Y2nDs247Ci0gZXZhbHVhciB1bmEgY2FtcGHDsWE7Ci0gcmVkaXNlw7FhciB1bmEgY29iZXJ0dXJhOwotIGlkZW50aWZpY2FyIHNlZ21lbnRvcyBwcmlvcml0YXJpb3MuCgotLS0KCiMgRGVtb3N0cmFjacOzbjogZGF0b3MgdmVyc3VzIGluZm9ybWFjacOzbgoKU3Vwb25nYW1vcyBxdWUgdW5hIGFzZWd1cmFkb3JhIHRpZW5lIGxhIHNpZ3VpZW50ZSBpbmZvcm1hY2nDs246CgpgYGB7cn0KY2xpZW50ZXMgPC0gZGF0YS5mcmFtZSgKICBDbGllbnRlID0gcGFzdGUwKCJDIiwgMToxMCksCiAgUHJpbWEgPSBjKDE4MDAsIDE5MDAsIDIyMDAsIDIwNTAsIDI1MDAsCiAgICAgICAgICAgIDIzMDAsIDE5NTAsIDI3MDAsIDI2MDAsIDIxMDApLAogIFJlbnVldmEgPSBjKCJTw60iLCAiU8OtIiwgIk5vIiwgIlPDrSIsICJObyIsCiAgICAgICAgICAgICAgIk5vIiwgIlPDrSIsICJObyIsICJObyIsICJTw60iKQopCgpjbGllbnRlcwpgYGAKCkVzdG9zIHNvbiAqKmRhdG9zKiouCgpQb2RlbW9zIGVtcGV6YXIgYSByZXN1bWlybG9zLgoKYGBge3J9CmFnZ3JlZ2F0ZSgKICBQcmltYSB+IFJlbnVldmEsCiAgZGF0YSA9IGNsaWVudGVzLAogIEZVTiA9IG1lYW4KKQpgYGAKCkFob3JhIHRlbmVtb3MgdW5hIHByaW1lcmEgcGllemEgZGUgKippbmZvcm1hY2nDs24qKi4KClBvZGVtb3MgdmlzdWFsaXphcmxhLgoKYGBge3J9CmdncGxvdCgKICBjbGllbnRlcywKICBhZXMoeCA9IFJlbnVldmEsIHkgPSBQcmltYSkKKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJQcmltYSBzZWfDum4gZGVjaXNpw7NuIGRlIHJlbm92YWNpw7NuIiwKICAgIHggPSAiwr9SZW51ZXZhPyIsCiAgICB5ID0gIlByaW1hIGFudWFsIgogICkgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCsK/UXXDqSBwb2RlbW9zIGNvbmNsdWlyPwoKUXVpesOhIGxvcyBjbGllbnRlcyBxdWUgbm8gcmVudWV2YW4gcHJlc2VudGFuIHByaW1hcyBtw6FzIGVsZXZhZGFzLgoKUGVybyB0b2RhdsOtYSAqKm5vIHBvZGVtb3MgYWZpcm1hciBxdWUgbGEgcHJpbWEgY2F1c2UgZWwgYWJhbmRvbm8qKi4KClBvZHLDrWEgZXhpc3RpciB1bmEgdGVyY2VyYSB2YXJpYWJsZToKCi0gZWRhZDsKLSB0aXBvIGRlIHZlaMOtY3VsbzsKLSBjb2JlcnR1cmE7Ci0gZXhwZXJpZW5jaWEgZGUgc2luaWVzdHJvczsKLSBpbmdyZXNvOwotIGNvbXBldGlkb3I7Ci0gY2FsaWRhZCBkZWwgc2VydmljaW8uCgo8ZGl2IGNsYXNzPSJjYWphLXByZWd1bnRhIj4KCiMjIyBQcmVndW50YQoKwr9DdcOhbCBkZSBsYXMgc2lndWllbnRlcyBhZmlybWFjaW9uZXMgZXMgbWV0b2RvbMOzZ2ljYW1lbnRlIG3DoXMgY29ycmVjdGE/CgpBLiBMYXMgcHJpbWFzIGFsdGFzIGNhdXNhbiBhYmFuZG9uby4KCkIuIEVuIGVzdG9zIGRhdG9zIHBhcmVjZSBleGlzdGlyIHVuYSBkaWZlcmVuY2lhIGVuIGxhcyBwcmltYXMgZGUgcXVpZW5lcyByZW51ZXZhbiB5IHF1aWVuZXMgbm8gcmVudWV2YW4uCgpDLiBMYSBjb21wYcOxw61hIGRlYmUgaW5tZWRpYXRhbWVudGUgcmVkdWNpciBsYXMgcHJpbWFzLgoKPC9kaXY+Cgo8ZGV0YWlscz4KPHN1bW1hcnk+VmVyIHJlc3B1ZXN0YTwvc3VtbWFyeT4KCkxhIHJlc3B1ZXN0YSBjb3JyZWN0YSBlcyAqKkIqKi4KCkVuIGVzdGEgZXRhcGEgw7puaWNhbWVudGUgb2JzZXJ2YW1vcyB1bmEgYXNvY2lhY2nDs24gZGVzY3JpcHRpdmEuCgpObyB0ZW5lbW9zIGV2aWRlbmNpYSBzdWZpY2llbnRlIHBhcmEgZXN0YWJsZWNlciBjYXVzYWxpZGFkIG5pIHBhcmEgcmVjb21lbmRhciB1bmEgcmVkdWNjacOzbiBkZSBwcmltYXMuCgo8L2RldGFpbHM+CgotLS0KCiMgRWwgcHJvY2VzbyBkZSBpbnZlc3RpZ2FjacOzbiBkZSBtZXJjYWRvcwoKVW5hIGludmVzdGlnYWNpw7NuIHB1ZWRlIG9yZ2FuaXphcnNlIGNvbmNlcHR1YWxtZW50ZSBlbiBzZWlzIGdyYW5kZXMgZXRhcGFzOgoKMS4gZGVmaW5pY2nDs24gZGVsIHByb2JsZW1hOwoyLiBkZXNhcnJvbGxvIGRlbCBlbmZvcXVlOwozLiBmb3JtdWxhY2nDs24gZGVsIGRpc2XDsW87CjQuIHRyYWJham8gZGUgY2FtcG8gbyByZWNvcGlsYWNpw7NuOwo1LiBwcmVwYXJhY2nDs24geSBhbsOhbGlzaXMgZGUgZGF0b3M7CjYuIGVsYWJvcmFjacOzbiB5IHByZXNlbnRhY2nDs24gZGVsIGluZm9ybWUuCgotLS0KCiMjIFBhc28gMS4gRGVmaW5pciBlbCBwcm9ibGVtYQoKRXN0YSBwcm9iYWJsZW1lbnRlIHNlYSBsYSBldGFwYSBjb25jZXB0dWFsbWVudGUgbcOhcyBpbXBvcnRhbnRlLgoKU2kgZGVmaW5pbW9zIG1hbCBlbCBwcm9ibGVtYSwgcG9kZW1vcyByZWFsaXphcjoKCi0gdW5hIGV4Y2VsZW50ZSBlbmN1ZXN0YTsKLSB1biBleGNlbGVudGUgbXVlc3RyZW87Ci0gdW5hIGV4Y2VsZW50ZSByZWdyZXNpw7NuOwotIHVuIGV4Y2VsZW50ZSBhbsOhbGlzaXMgbXVsdGl2YXJpYWRvOwoKeSBhdW4gYXPDrSByZXNwb25kZXIgdW5hIHByZWd1bnRhIGVxdWl2b2NhZGEuCgo8ZGl2IGNsYXNzPSJjYWphLWFsZXJ0YSI+CgojIyMgUHJpbmNpcGlvIG1ldG9kb2zDs2dpY28KClVuYSB0w6ljbmljYSBlc3RhZMOtc3RpY2Egc29maXN0aWNhZGEgbm8gY29ycmlnZSB1bmEgcHJlZ3VudGEgbWFsIGZvcm11bGFkYS4KCjwvZGl2PgoKLS0tCgojIyBQYXNvIDIuIERlc2Fycm9sbGFyIGVsIGVuZm9xdWUKClVuYSB2ZXogZGVmaW5pZG8gZWwgcHJvYmxlbWEgZGViZW1vcyBkZXRlcm1pbmFyOgoKLSBxdcOpIHNhYmVtb3M7Ci0gcXXDqSB0ZW9yw61hIHB1ZWRlIG9yaWVudGFybm9zOwotIHF1w6kgdmFyaWFibGVzIHBvZHLDrWFuIGludGVydmVuaXI7Ci0gcXXDqSByZWxhY2lvbmVzIGVzcGVyYW1vczsKLSBxdcOpIHByZWd1bnRhcyBxdWVyZW1vcyByZXNwb25kZXI7Ci0gcXXDqSBoaXDDs3Rlc2lzIHB1ZWRlbiBwbGFudGVhcnNlOwotIHF1w6kgaW5mb3JtYWNpw7NuIG5lY2VzaXRhbW9zLgoKLS0tCgojIyBQYXNvIDMuIEZvcm11bGFyIGVsIGRpc2XDsW8KCkRlYmVtb3MgZGVjaWRpciBjw7NtbyBvYnRlbmRyZW1vcyBsYSBldmlkZW5jaWEuCgpFbCBlc3R1ZGlvIHB1ZWRlIHNlcjoKCi0gZXhwbG9yYXRvcmlvOwotIGRlc2NyaXB0aXZvOwotIGNhdXNhbDsKCnkgcHVlZGUgdXRpbGl6YXI6CgotIGluZm9ybWFjacOzbiBzZWN1bmRhcmlhOwotIGVudHJldmlzdGFzOwotIGdydXBvcyBmb2NhbGVzOwotIG9ic2VydmFjacOzbjsKLSBlbmN1ZXN0YXM7Ci0gZXhwZXJpbWVudG9zOwotIGRhdG9zIGFkbWluaXN0cmF0aXZvcy4KCi0tLQoKIyMgUGFzbyA0LiBSZWNvbGVjdGFyIGluZm9ybWFjacOzbgoKRW4gZXN0YSBmYXNlIHNlIGVqZWN1dGEgZWwgZGlzZcOxby4KCk3DoXMgYWRlbGFudGUgZXN0dWRpYXJlbW9zOgoKLSB0cmFiYWpvIGRlIGNhbXBvOwotIGN1ZXN0aW9uYXJpb3M7Ci0gbXVlc3RyZW87Ci0gY29udHJvbGVzOwotIGNhbGlkYWQuCgotLS0KCiMjIFBhc28gNS4gUHJlcGFyYXIgeSBhbmFsaXphcgoKTG9zIGRhdG9zIGRlYmVuOgoKLSByZXZpc2Fyc2U7Ci0gY29kaWZpY2Fyc2U7Ci0gZGVwdXJhcnNlOwotIHRyYW5zZm9ybWFyc2U7Ci0gcmVzdW1pcnNlOwotIGFuYWxpemFyc2UuCgpSIHNlcsOhIG51ZXN0cmEgaGVycmFtaWVudGEgcHJpbmNpcGFsIGR1cmFudGUgZWwgY3Vyc28uCgotLS0KCiMjIFBhc28gNi4gQ29tdW5pY2FyIHJlc3VsdGFkb3MKCkVsIHByb2R1Y3RvIGZpbmFsIG5vIGVzIHVuYSBzYWxpZGEgZGUgUi4KCkVsIHByb2R1Y3RvIGZpbmFsIGVzIHVuYSByZXNwdWVzdGEgZnVuZGFtZW50YWRhLgoKUG9yIGVqZW1wbG86Cgo+IOKAnExvcyBjbGllbnRlcyBleHB1ZXN0b3MgYSBpbmNyZW1lbnRvcyBkZSBwcmltYSBzdXBlcmlvcmVzIGFsIDEwJSBwcmVzZW50YW4gbWVub3IgaW50ZW5jacOzbiBkZSByZW5vdmFjacOzbiwgZXNwZWNpYWxtZW50ZSBjdWFuZG8gc3UgdmFsb3JhY2nDs24gZGVsIHNlcnZpY2lvIHRhbWJpw6luIGVzIGJhamEu4oCdCgpFc3RhIGFmaXJtYWNpw7NuIGVzIG11Y2hvIG3DoXMgw7p0aWwgcXVlIG1vc3RyYXIgw7puaWNhbWVudGUgdW5hIHRhYmxhIGRlIGNvZWZpY2llbnRlcy4KCi0tLQoKIyBQcm9ibGVtYSBlbXByZXNhcmlhbCB2ZXJzdXMgcHJvYmxlbWEgZGUgaW52ZXN0aWdhY2nDs24KCkVzdGEgZGlzdGluY2nDs24gZXMgZnVuZGFtZW50YWwuCgojIyBQcm9ibGVtYSBlbXByZXNhcmlhbAoKU2UgY29uY2VudHJhIGVuOgoKPiAqKsK/UXXDqSBkZWJlbW9zIGhhY2VyPyoqCgpFamVtcGxvczoKCi0gwr9kZWJlbW9zIHJlZHVjaXIgbGEgcHJpbWE/OwotIMK/ZGViZW1vcyBsYW56YXIgZWwgcHJvZHVjdG8/OwotIMK/ZGViZW1vcyBjYW1iaWFyIGVsIGNhbmFsPzsKLSDCv2RlYmVtb3MgbW9kaWZpY2FyIGxhIGNvYmVydHVyYT87Ci0gwr9kZWJlbW9zIGRpcmlnaXJub3MgYSBvdHJvIHNlZ21lbnRvPwoKIyMgUHJvYmxlbWEgZGUgaW52ZXN0aWdhY2nDs24KClNlIGNvbmNlbnRyYSBlbjoKCj4gKirCv1F1w6kgaW5mb3JtYWNpw7NuIG5lY2VzaXRhbW9zIHBhcmEgZGVjaWRpcj8qKgoKRWplbXBsbzoKCiMjIyBQcm9ibGVtYSBlbXByZXNhcmlhbAoKPiDCv0RlYmVtb3MgbW9kaWZpY2FyIGxhIHByaW1hIGRlIHJlbm92YWNpw7NuIGRlbCBzZWd1cm8gZGUgYXV0b23Ds3ZpbD8KCiMjIyBQcm9ibGVtYSBkZSBpbnZlc3RpZ2FjacOzbgoKPiBEZXRlcm1pbmFyIGxhIHJlbGFjacOzbiBlbnRyZSBsYSB2YXJpYWNpw7NuIGRlIGxhIHByaW1hIHkgbGEgaW50ZW5jacOzbiBkZSByZW5vdmFjacOzbiBkZSBsb3MgYXNlZ3VyYWRvcywgY29uc2lkZXJhbmRvIGNhcmFjdGVyw61zdGljYXMgZGVsIGNsaWVudGUsIGV4cGVyaWVuY2lhIGRlIHNpbmllc3Ryb3MgeSBwZXJjZXBjacOzbiBkZWwgc2VydmljaW8uCgpPYnNlcnZlIGVsIGNhbWJpby4KCkxhIGludmVzdGlnYWNpw7NuIG5vIGRlY2lkZSBhdXRvbcOhdGljYW1lbnRlIHNpIHNlIHJlZHVjZSBsYSBwcmltYS4KClByaW1lcm8gZ2VuZXJhIGluZm9ybWFjacOzbiBzb2JyZSBlbCBmZW7Ds21lbm8uCgotLS0KCiMgRGVtb3N0cmFjacOzbiBhY3R1YXJpYWw6IHRyYW5zZm9ybWFyIHVuYSBkZWNpc2nDs24gZW4gaW52ZXN0aWdhY2nDs24KCkNvbnNpZGVyZW1vcyBlbCBzaWd1aWVudGUgY2Fzby4KCjxkaXYgY2xhc3M9ImNhamEtYWN0dWFyaWFsIj4KCiMjIENhc286IEFzZWd1cmFkb3JhIEhvcml6b250ZQoKRHVyYW50ZSBsb3Mgw7psdGltb3MgZG9jZSBtZXNlcywgbGEgYXNlZ3VyYWRvcmEgaGEgb2JzZXJ2YWRvIHVuYSByZWR1Y2Npw7NuIGVuIGxhIHJlbm92YWNpw7NuIGRlIHDDs2xpemFzIGRlIGF1dG9tw7N2aWwuCgpMYSBnZXJlbmNpYSBjb21lcmNpYWwgcHJvcG9uZSBvdG9yZ2FyIHVuIGRlc2N1ZW50byBnZW5lcmFsIGRlbCAxMCUuCgpMYSBnZXJlbmNpYSB0w6ljbmljYSBhZHZpZXJ0ZSBxdWUgZXNhIHJlZHVjY2nDs24gcG9kcsOtYSBkZXRlcmlvcmFyIGVsIHJlc3VsdGFkbyB0w6ljbmljby4KCkFudGVzIGRlIHRvbWFyIGxhIGRlY2lzacOzbiBzZSBzb2xpY2l0YSB1bmEgaW52ZXN0aWdhY2nDs24uCgo8L2Rpdj4KCiMjIFBhc28gQS4gRGVjaXNpw7NuIGVtcHJlc2FyaWFsCgo+IMK/RGViZSBtb2RpZmljYXJzZSBsYSBlc3RyYXRlZ2lhIGRlIHByZWNpb3MgcGFyYSBtZWpvcmFyIGxhIHJlbm92YWNpw7NuPwoKIyMgUGFzbyBCLiBQcm9ibGVtYSBkZSBpbnZlc3RpZ2FjacOzbgoKPiBBbmFsaXphciBsb3MgZmFjdG9yZXMgYXNvY2lhZG9zIGNvbiBsYSBpbnRlbmNpw7NuIGRlIHJlbm92YWNpw7NuIGRlIGxvcyBjbGllbnRlcyB5IGRldGVybWluYXIgbGEgaW1wb3J0YW5jaWEgcmVsYXRpdmEgZGUgbGEgdmFyaWFjacOzbiBkZSBsYSBwcmltYSBmcmVudGUgYSBvdHJvcyBmYWN0b3JlcyBkZSBleHBlcmllbmNpYSB5IHNlcnZpY2lvLgoKIyMgUGFzbyBDLiBWYXJpYWJsZXMgcG9zaWJsZXMKCi0gaW50ZW5jacOzbiBkZSByZW5vdmFjacOzbjsKLSBwb3JjZW50YWplIGRlIGluY3JlbWVudG8gZGUgcHJpbWE7Ci0gc2F0aXNmYWNjacOzbjsKLSBleHBlcmllbmNpYSBkZSBzaW5pZXN0cm9zOwotIGluZ3Jlc287Ci0gYW50aWfDvGVkYWQ7Ci0gZWRhZDsKLSBjYW5hbDsKLSByZWdpw7NuLgoKIyMgUGFzbyBELiBJbmZvcm1hY2nDs24gcmVxdWVyaWRhCgpOZWNlc2l0YW1vcyBjb25vY2VyOgoKMS4gY3XDoW50byBhdW1lbnTDsyBsYSBwcmltYTsKMi4gcXXDqSB0YW4gc2F0aXNmZWNobyBlc3TDoSBlbCBjbGllbnRlOwozLiBzaSB0dXZvIHNpbmllc3Ryb3M7CjQuIGPDs21vIGZ1ZSBhdGVuZGlkbzsKNS4gc3UgaW50ZW5jacOzbiBkZSByZW5vdmFjacOzbjsKNi4gdmFyaWFibGVzIHNvY2lvZGVtb2dyw6FmaWNhczsKNy4gY2FyYWN0ZXLDrXN0aWNhcyBkZWwgcHJvZHVjdG8uCgotLS0KCiMgRWwgY29udGV4dG8gZGVsIHByb2JsZW1hCgpVbmEgZGVjaXNpw7NuIGVtcHJlc2FyaWFsIG5vIG9jdXJyZSBkZSBmb3JtYSBhaXNsYWRhLgoKQW50ZXMgZGUgZm9ybXVsYXIgbGEgaW52ZXN0aWdhY2nDs24gZGViZW1vcyBjb21wcmVuZGVyIGVsIGNvbnRleHRvLgoKRW50cmUgbG9zIGVsZW1lbnRvcyBxdWUgcHVlZGVuIGFuYWxpemFyc2Ugc2UgZW5jdWVudHJhbjoKCi0gaW5mb3JtYWNpw7NuIGhpc3TDs3JpY2E7Ci0gcHJvbsOzc3RpY29zOwotIG9iamV0aXZvcyBlbXByZXNhcmlhbGVzOwotIGNvbXBvcnRhbWllbnRvIGRlbCBjb25zdW1pZG9yOwotIHJlc3RyaWNjaW9uZXM7Ci0gcmVjdXJzb3MgZGlzcG9uaWJsZXM7Ci0gYW1iaWVudGUgZWNvbsOzbWljbzsKLSBhbWJpZW50ZSBsZWdhbDsKLSB0ZWNub2xvZ8OtYTsKLSBjb21wZXRlbmNpYS4KCi0tLQoKIyBFamVtcGxvIGRlIGNvbnRleHRvIGFjdHVhcmlhbAoKU3Vwb25nYW1vcyBxdWUgdW5hIGFzZWd1cmFkb3JhIG9ic2VydmEgbWF5b3IgY2FuY2VsYWNpw7NuLgoKQW50ZXMgZGUgY3VscGFyIGFsIHByZWNpbyBkZWJlbW9zIHJldmlzYXI6CgojIyMgRW50b3JubyBlY29uw7NtaWNvCgotIGluZmxhY2nDs247Ci0gaW5ncmVzbyBkaXNwb25pYmxlOwotIGRlc2VtcGxlbzsKLSB0YXNhcyBkZSBpbnRlcsOpcy4KCiMjIyBFbnRvcm5vIGNvbXBldGl0aXZvCgotIG51ZXZhcyBhc2VndXJhZG9yYXM7Ci0gcHJvbW9jaW9uZXM7Ci0gbnVldm9zIGNhbmFsZXMgZGlnaXRhbGVzOwotIGFncmVnYWRvcmVzIGRlIHNlZ3Vyb3MuCgojIyMgRW50b3JubyByZWd1bGF0b3JpbwoKLSBtb2RpZmljYWNpb25lcyBub3JtYXRpdmFzOwotIGNvYmVydHVyYXMgb2JsaWdhdG9yaWFzOwotIHByb3RlY2Npw7NuIGFsIGNvbnN1bWlkb3IuCgojIyMgRW50b3JubyBpbnRlcm5vCgotIGluY3JlbWVudG8gZGUgcHJpbWFzOwotIG1vZGlmaWNhY2lvbmVzIGVuIGRlZHVjaWJsZXM7Ci0gY2FtYmlvcyBlbiBzZXJ2aWNpbzsKLSBwcm9jZXNvcyBkZSByZWNsYW1hY2nDs24uCgojIyMgQ29tcG9ydGFtaWVudG8gZGVsIGNsaWVudGUKCi0gc2Vuc2liaWxpZGFkIGFsIHByZWNpbzsKLSBleHBlcmllbmNpYSBkZSBzaW5pZXN0cm87Ci0gdmFsb3JhY2nDs24gZGUgbWFyY2E7Ci0gcHJlZmVyZW5jaWFzIGRpZ2l0YWxlcy4KCi0tLQoKIyBEZSBvYmpldGl2b3MgYSBwcmVndW50YXMgZGUgaW52ZXN0aWdhY2nDs24KClVuYSB2ZXogZGVmaW5pZG8gZWwgcHJvYmxlbWEsIGRlYmVtb3MgZXN0cnVjdHVyYXIgZWwgZXN0dWRpby4KCiMjIE9iamV0aXZvIGdlbmVyYWwKCkRlc2NyaWJlIHF1w6kgcHJldGVuZGUgbG9ncmFyIGxhIGludmVzdGlnYWNpw7NuLgoKRWplbXBsbzoKCj4gQW5hbGl6YXIgbG9zIGZhY3RvcmVzIHJlbGFjaW9uYWRvcyBjb24gbGEgaW50ZW5jacOzbiBkZSByZW5vdmFjacOzbiBkZSBsb3MgY2xpZW50ZXMgZGUgc2VndXJvcyBkZSBhdXRvbcOzdmlsLgoKIyMgT2JqZXRpdm9zIGVzcGVjw61maWNvcwoKUG9kcsOtYW4gc2VyOgoKMS4gZGVzY3JpYmlyIGVsIHBlcmZpbCBkZSBsb3MgY2xpZW50ZXM7CjIuIGRldGVybWluYXIgbGEgZGlzdHJpYnVjacOzbiBkZSBsYSBpbnRlbmNpw7NuIGRlIHJlbm92YWNpw7NuOwozLiBhbmFsaXphciBsYSByZWxhY2nDs24gZW50cmUgYXVtZW50byBkZSBwcmltYSBlIGludGVuY2nDs24gZGUgcmVub3ZhY2nDs247CjQuIGNvbXBhcmFyIGxhIGludGVuY2nDs24gZGUgcmVub3ZhY2nDs24gc2Vnw7puIGV4cGVyaWVuY2lhIGRlIHNpbmllc3RybzsKNS4gYW5hbGl6YXIgbGEgcmVsYWNpw7NuIGVudHJlIHNhdGlzZmFjY2nDs24gZSBpbnRlbmNpw7NuIGRlIHJlbm92YWNpw7NuOwo2LiBpZGVudGlmaWNhciB2YXJpYWJsZXMgcG90ZW5jaWFsbWVudGUgw7p0aWxlcyBwYXJhIGV4cGxpY2FyIGxhIHJlbm92YWNpw7NuLgoKLS0tCgojIEPDs21vIGZvcm11bGFyIGJ1ZW5hcyBwcmVndW50YXMgZGUgaW52ZXN0aWdhY2nDs24KClVuYSBidWVuYSBwcmVndW50YSBkZWJlIHNlcjoKCi0gY2xhcmE7Ci0gZXNwZWPDrWZpY2E7Ci0gaW52ZXN0aWdhYmxlOwotIHZpbmN1bGFkYSBjb24gaW5mb3JtYWNpw7NuIG9ic2VydmFibGU7Ci0gcmVsZXZhbnRlIHBhcmEgbGEgZGVjaXNpw7NuLgoKRWplbXBsb3M6CgojIyMgUHJlZ3VudGEgMQoKPiDCv0N1w6FsIGVzIGVsIG5pdmVsIHByb21lZGlvIGRlIGludGVuY2nDs24gZGUgcmVub3ZhY2nDs24/CgojIyMgUHJlZ3VudGEgMgoKPiDCv0xhIGludGVuY2nDs24gZGUgcmVub3ZhY2nDs24gZGlmaWVyZSBlbnRyZSBjbGllbnRlcyBjb24geSBzaW4gc2luaWVzdHJvcyByZWNpZW50ZXM/CgojIyMgUHJlZ3VudGEgMwoKPiDCv0V4aXN0ZSBhc29jaWFjacOzbiBlbnRyZSBlbCBpbmNyZW1lbnRvIGRlIHByaW1hIHkgbGEgaW50ZW5jacOzbiBkZSByZW5vdmFjacOzbj8KCiMjIyBQcmVndW50YSA0Cgo+IMK/TGEgc2F0aXNmYWNjacOzbiBjb24gZWwgc2VydmljaW8gZXN0w6EgcmVsYWNpb25hZGEgY29uIGxhIHJlbm92YWNpw7NuPwoKIyMjIFByZWd1bnRhIDUKCj4gwr9RdcOpIGNhcmFjdGVyw61zdGljYXMgcHJlc2VudGFuIGxvcyBjbGllbnRlcyBjb24gYmFqYSBpbnRlbmNpw7NuIGRlIHJlbm92YXI/CgotLS0KCiMgUHJlZ3VudGFzIGTDqWJpbGVzIHkgcHJlZ3VudGFzIG1lam9yYWRhcwoKIyMgRWplbXBsbyAxCgpQcmVndW50YSBkw6liaWw6Cgo+IMK/UG9yIHF1w6kgbG9zIHNlZ3Vyb3Mgc29uIGNhcm9zPwoKUHJvYmxlbWFzOgoKLSBkZW1hc2lhZG8gYW1wbGlhOwotIHV0aWxpemEgdW4ganVpY2lvIGRlIHZhbG9yOwotIG5vIGRlZmluZSBzZWd1cm87Ci0gbm8gZGVmaW5lIHBvYmxhY2nDs247Ci0gbm8gZGVmaW5lIHF1w6kgc2lnbmlmaWNhIGNhcm8uCgpQcmVndW50YSBtZWpvcmFkYToKCj4gwr9Dw7NtbyBzZSByZWxhY2lvbmEgbGEgcGVyY2VwY2nDs24gZGVsIHByZWNpbyBkZSB1biBzZWd1cm8gZGUgYXV0b23Ds3ZpbCBjb24gbGEgaW50ZW5jacOzbiBkZSByZW5vdmFjacOzbiBlbnRyZSBjbGllbnRlcyBhY3R1YWxlcz8KCi0tLQoKIyMgRWplbXBsbyAyCgpQcmVndW50YSBkw6liaWw6Cgo+IMK/QSBsYXMgcGVyc29uYXMgbGVzIGd1c3RhbiBsb3Mgc2VndXJvcyBkZSB2aWRhPwoKUHJlZ3VudGEgbWVqb3JhZGE6Cgo+IMK/UXXDqSBhdHJpYnV0b3MgZGUgdW4gc2VndXJvIGRlIHZpZGEgc29uIHZhbG9yYWRvcyBwb3IgYWR1bHRvcyBkZSAyNSBhIDQ1IGHDsW9zIHF1ZSBhY3R1YWxtZW50ZSBubyBwb3NlZW4gY29iZXJ0dXJhIGluZGl2aWR1YWw/CgotLS0KCiMgTWFyY28gY29uY2VwdHVhbAoKTGFzIHByZWd1bnRhcyBkZSBpbnZlc3RpZ2FjacOzbiBubyBkZWJlcsOtYW4gYXBhcmVjZXIgZGUgbWFuZXJhIGFyYml0cmFyaWEuCgpOZWNlc2l0YW1vcyBlc3RhYmxlY2VyIHVuYSBleHBsaWNhY2nDs24gY29uY2VwdHVhbC4KClBvciBlamVtcGxvOgoKYGBgdGV4dApJbmNyZW1lbnRvIGRlIHByaW1hICDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUggpTYXRpc2ZhY2Npw7NuIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUpAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCCkV4cGVyaWVuY2lhIGRlIHNpbmllc3RybyDilIDilIDilIDilIDilIDilIDilKTilIDilIA+IEludGVuY2nDs24gZGUgcmVub3ZhY2nDs24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUggpJbmdyZXNvIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUpAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCCkFudGlnw7xlZGFkIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUmApgYGAKCkVzdGUgZXNxdWVtYSByZXByZXNlbnRhIHVuYSBoaXDDs3Rlc2lzIGNvbmNlcHR1YWwuCgpUb2RhdsOtYSBubyBlcyB1biBtb2RlbG8gZXN0YWTDrXN0aWNvLgoKTm9zIGF5dWRhIGEgb3JnYW5pemFyIGVsIHByb2JsZW1hLgoKLS0tCgojIE1vZGVsbyB2ZXJiYWwsIGdyw6FmaWNvIHkgbWF0ZW3DoXRpY28KClVuYSBtaXNtYSBpZGVhIHB1ZWRlIGV4cHJlc2Fyc2UgZGUgZGlmZXJlbnRlcyBtYW5lcmFzLgoKIyMgTW9kZWxvIHZlcmJhbAoKPiBMYSBpbnRlbmNpw7NuIGRlIHJlbm92YWNpw7NuIGRlIHVuYSBww7NsaXphIHB1ZWRlIGVzdGFyIHJlbGFjaW9uYWRhIGNvbiBsYSB2YXJpYWNpw7NuIGRlIGxhIHByaW1hLCBsYSBzYXRpc2ZhY2Npw7NuIGRlbCBjbGllbnRlLCBzdSBleHBlcmllbmNpYSBkZSBzaW5pZXN0cm9zIHkgY2FyYWN0ZXLDrXN0aWNhcyBpbmRpdmlkdWFsZXMuCgojIyBNb2RlbG8gZ3LDoWZpY28KCmBgYHRleHQKUHJlY2lvIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUkAogICAgICAgICAgICAgICAgICAgICAgIOKUggpTZXJ2aWNpbyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilKQKICAgICAgICAgICAgICAgICAgICAgICDilJzilIDilIA+IFJlbm92YWNpw7NuClNpbmllc3Ryb3Mg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSkCiAgICAgICAgICAgICAgICAgICAgICAg4pSCCkNhcmFjdGVyw61zdGljYXMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSYCmBgYAoKIyMgTW9kZWxvIG1hdGVtw6F0aWNvIGNvbmNlcHR1YWwKClBvZGVtb3MgcmVwcmVzZW50YXJsbyBjb21vOgoKXFsKWSA9IGYoWF8xLFhfMixYXzMsXGxkb3RzLFhfaykKXF0KCmRvbmRlOgoKXFsKWSA9IFx0ZXh0e2ludGVuY2nDs24gZGUgcmVub3ZhY2nDs259ClxdCgp5LCBwb3IgZWplbXBsbywKClxbClhfMSA9IFx0ZXh0e2luY3JlbWVudG8gZGUgcHJpbWF9ClxdCgpcWwpYXzIgPSBcdGV4dHtzYXRpc2ZhY2Npw7NufQpcXQoKXFsKWF8zID0gXHRleHR7ZXhwZXJpZW5jaWEgZGUgc2luaWVzdHJvc30KXF0KClxbClhfNCA9IFx0ZXh0e2luZ3Jlc299ClxdCgoKClxbCllfaSA9ClxiZXRhXzAgKwpcYmV0YV8xIFhfezFpfSArClxiZXRhXzIgWF97Mml9ICsKXGJldGFfMyBYX3szaX0gKwpcdmFyZXBzaWxvbl9pClxdCgpQb3IgYWhvcmEgbG8gaW1wb3J0YW50ZSBubyBlcyBlc3RpbWFybG8uCgpMbyBpbXBvcnRhbnRlIGVzIGNvbXByZW5kZXIgcXVlIGVsIG1vZGVsbyBlc3RhZMOtc3RpY28gZGViZSBvcmlnaW5hcnNlIGVuIHVuYSBwcmVndW50YSB5IG5vIGFsIHJldsOpcy4KCi0tLQoKIyBIaXDDs3Rlc2lzIGRlIGludmVzdGlnYWNpw7NuCgpVbmEgaGlww7N0ZXNpcyBlc3RhYmxlY2UgdW5hIHJlbGFjacOzbiBlc3BlcmFkYSBlbnRyZSB2YXJpYWJsZXMuCgpQb3IgZWplbXBsbzoKClxbCkhfMToKXHRleHR7YSBtYXlvciBpbmNyZW1lbnRvIGRlIHByaW1hLCBtZW5vciBpbnRlbmNpw7NuIGRlIHJlbm92YWNpw7NufQpcXQoKT3RyYSBoaXDDs3Rlc2lzOgoKXFsKSF8yOgpcdGV4dHthIG1heW9yIHNhdGlzZmFjY2nDs24sIG1heW9yIGludGVuY2nDs24gZGUgcmVub3ZhY2nDs259ClxdCgpUYW1iacOpbjoKClxbCkhfMzoKXHRleHR7bGEgaW50ZW5jacOzbiBkZSByZW5vdmFjacOzbiBkaWZpZXJlIHNlZ8O6biBsYSBleHBlcmllbmNpYSBkZSBzaW5pZXN0cm9zfQpcXQoKPGRpdiBjbGFzcz0iY2FqYS1hbGVydGEiPgoKIyMjIEltcG9ydGFudGUKCkVuIGVzdGEgZXRhcGEgZXN0YW1vcyBmb3JtdWxhbmRvICoqaGlww7N0ZXNpcyBjb25jZXB0dWFsZXMqKi4KCk3DoXMgYWRlbGFudGUgYXByZW5kZXJlbW9zIGEgY29udmVydGlybGFzIGVuIGhpcMOzdGVzaXMgZXN0YWTDrXN0aWNhcy4KCk5vIHNvbiBleGFjdGFtZW50ZSBsbyBtaXNtby4KCjwvZGl2PgoKLS0tCgojIFZhcmlhYmxlcwoKVW5hIHZhcmlhYmxlIGVzIHVuYSBjYXJhY3RlcsOtc3RpY2EgcXVlIHB1ZWRlIHByZXNlbnRhciB2YXJpYWNpw7NuLgoKRWplbXBsb3MgYWN0dWFyaWFsZXM6CgotIGVkYWQ7Ci0gcHJpbWE7Ci0gc3VtYSBhc2VndXJhZGE7Ci0gZnJlY3VlbmNpYSBkZSBzaW5pZXN0cm9zOwotIHNldmVyaWRhZDsKLSBpbmdyZXNvOwotIHNhdGlzZmFjY2nDs247Ci0gaW50ZW5jacOzbiBkZSByZW5vdmFjacOzbjsKLSBjYW5hbDsKLSByZWdpw7NuLgoKLS0tCgojIFRpcG9zIGluaWNpYWxlcyBkZSB2YXJpYWJsZXMKCkRlc2RlIHVuYSBwZXJzcGVjdGl2YSBwcsOhY3RpY2EgcG9kZW1vcyBjb21lbnphciBkaXN0aW5ndWllbmRvOgoKIyMjIFZhcmlhYmxlcyBudW3DqXJpY2FzCgpFamVtcGxvczoKCi0gZWRhZDsKLSBpbmdyZXNvOwotIHByaW1hOwotIG7Dum1lcm8gZGUgc2luaWVzdHJvcy4KCiMjIyBWYXJpYWJsZXMgY2F0ZWfDs3JpY2FzCgpFamVtcGxvczoKCi0gcmVnacOzbjsKLSBjYW5hbDsKLSBwcm9kdWN0bzsKLSBzZXhvOwotIHJlbm92YWNpw7NuLgoKIyMjIFZhcmlhYmxlcyBvcmRpbmFsZXMKCkVqZW1wbG86CgpJbnRlbmNpw7NuIGRlIHJlbm92YWNpw7NuOgoKMS4gZGVmaW5pdGl2YW1lbnRlIG5vOwoyLiBwcm9iYWJsZW1lbnRlIG5vOwozLiBpbmRlY2lzbzsKNC4gcHJvYmFibGVtZW50ZSBzw607CjUuIGRlZmluaXRpdmFtZW50ZSBzw60uCgotLS0KCiMgRXNwZWNpZmljYWNpw7NuIGRlIGxhIGluZm9ybWFjacOzbiByZXF1ZXJpZGEKCkVzdGUgcGFzbyBvYmxpZ2EgYSB0cmFkdWNpciBudWVzdHJhcyBwcmVndW50YXMgZW4gaW5mb3JtYWNpw7NuIGNvbmNyZXRhLgoKU3Vwb25nYW1vcyBxdWUgcXVlcmVtb3MgcmVzcG9uZGVyOgoKPiDCv0VzdMOhIHJlbGFjaW9uYWRvIGVsIGF1bWVudG8gZGUgcHJpbWEgY29uIGxhIGludGVuY2nDs24gZGUgcmVub3ZhY2nDs24/CgpOZWNlc2l0YW1vcyBhbCBtZW5vczoKCi0gcHJpbWEgYW50ZXJpb3I7Ci0gcHJpbWEgYWN0dWFsIG8gcG9yY2VudGFqZSBkZSBpbmNyZW1lbnRvOwotIGludGVuY2nDs24gZGUgcmVub3ZhY2nDs24uCgpQZXJvIHByb2JhYmxlbWVudGUgdGFtYmnDqW4gbmVjZXNpdGVtb3M6CgotIGVkYWQ7Ci0gaW5ncmVzbzsKLSB0aXBvIGRlIGNvYmVydHVyYTsKLSBleHBlcmllbmNpYSBkZSBzaW5pZXN0cm87Ci0gc2F0aXNmYWNjacOzbjsKLSBhbnRpZ8O8ZWRhZC4KCsK/UG9yIHF1w6k/CgpQb3JxdWUgdW4gZmVuw7NtZW5vIGRlIG1lcmNhZG8gcmFyYSB2ZXogZGVwZW5kZSBkZSB1bmEgc29sYSB2YXJpYWJsZS4KCi0tLQoKIyBEZWwgY29uY2VwdG8gYSBsb3MgZGF0b3MKCk9ic2VydmUgZXN0YSBzZWN1ZW5jaWE6Cgp8IE5pdmVsIHwgRWplbXBsbyB8CnwtLS18LS0tfAp8IERlY2lzacOzbiB8IMK/RGViZW1vcyBjYW1iaWFyIGxhIGVzdHJhdGVnaWEgZGUgcmVub3ZhY2nDs24/IHwKfCBQcm9ibGVtYSBkZSBpbnZlc3RpZ2FjacOzbiB8IEZhY3RvcmVzIHJlbGFjaW9uYWRvcyBjb24gbGEgcmVub3ZhY2nDs24gfAp8IFByZWd1bnRhIHwgwr9FbCBhdW1lbnRvIGRlIHByaW1hIGVzdMOhIHJlbGFjaW9uYWRvIGNvbiBsYSBpbnRlbmNpw7NuIGRlIHJlbm92YXI/IHwKfCBIaXDDs3Rlc2lzIHwgQSBtYXlvciBhdW1lbnRvLCBtZW5vciBpbnRlbmNpw7NuIHwKfCBDb25jZXB0byB8IFNlbnNpYmlsaWRhZCBhbCBwcmVjaW8gfAp8IFZhcmlhYmxlIHwgSW5jcmVtZW50byBwb3JjZW50dWFsIGRlIHByaW1hIHwKfCBEYXRvIHwgMTIuNSUgfAp8IEFuw6FsaXNpcyB8IENvbXBhcmFjacOzbi9jb3JyZWxhY2nDs24vbW9kZWxvIHwKfCBFdmlkZW5jaWEgfCBSZWxhY2nDs24gb2JzZXJ2YWRhIHwKfCBEZWNpc2nDs24gfCBVdGlsaXphciBldmlkZW5jaWEganVudG8gY29uIGNyaXRlcmlvcyB0w6ljbmljb3MgfAoKLS0tCgojIERpc2XDsW9zIGRlIGludmVzdGlnYWNpw7NuCgpVbmEgdmV6IHNhYmVtb3MgcXXDqSBuZWNlc2l0YW1vcyBpbnZlc3RpZ2FyIGRlYmVtb3MgZGVjaWRpciAqKmPDs21vIG9idGVuZXIgbGEgZXZpZGVuY2lhKiouCgpMb3MgdHJlcyBkaXNlw7FvcyBwcmluY2lwYWxlcyBxdWUgdXRpbGl6YXJlbW9zIHNvbjoKCjEuIGV4cGxvcmF0b3JpbzsKMi4gZGVzY3JpcHRpdm87CjMuIGNhdXNhbC4KCi0tLQoKIyBJbnZlc3RpZ2FjacOzbiBleHBsb3JhdG9yaWEKClNlIHV0aWxpemEgY3VhbmRvOgoKLSBlbCBwcm9ibGVtYSB0b2RhdsOtYSBubyBlc3TDoSBjbGFyYW1lbnRlIGRlZmluaWRvOwotIG5lY2VzaXRhbW9zIGNvbXByZW5kZXIgZWwgZmVuw7NtZW5vOwotIGV4aXN0ZW4gcG9jYXMgaGlww7N0ZXNpczsKLSBxdWVyZW1vcyBpZGVudGlmaWNhciBwb3NpYmxlcyB2YXJpYWJsZXM7Ci0gYnVzY2Ftb3MgZ2VuZXJhciBpZGVhcy4KCk3DqXRvZG9zIGNvbXVuZXM6CgotIGVudHJldmlzdGFzIGNvbiBleHBlcnRvczsKLSBhbsOhbGlzaXMgZGUgZGF0b3Mgc2VjdW5kYXJpb3M7Ci0gZ3J1cG9zIGZvY2FsZXM7Ci0gZW50cmV2aXN0YXMgZW4gcHJvZnVuZGlkYWQ7Ci0gYW7DoWxpc2lzIGV4cGxvcmF0b3JpbyBkZSBkYXRvcy4KCi0tLQoKIyMgRWplbXBsbyBhY3R1YXJpYWwKClVuYSBhc2VndXJhZG9yYSBxdWllcmUgc2FiZXIgcG9yIHF1w6kgbG9zIGrDs3ZlbmVzIG5vIGFkcXVpZXJlbiBzZWd1cm9zIGRlIHZpZGEuCgpUb2RhdsOtYSBubyBzYWJlIHNpIGVsIHByb2JsZW1hIGVzOgoKLSBwcmVjaW87Ci0gZmFsdGEgZGUgY29ub2NpbWllbnRvOwotIGJhamEgcGVyY2VwY2nDs24gZGUgcmllc2dvOwotIHByb2R1Y3RvcyBpbmFkZWN1YWRvczsKLSBjYW5hbGVzOwotIGRlc2NvbmZpYW56YS4KClVuYSBwcmltZXJhIGludmVzdGlnYWNpw7NuIGV4cGxvcmF0b3JpYSBwdWVkZSBheXVkYXIgYSBpZGVudGlmaWNhciBleHBsaWNhY2lvbmVzLgoKLS0tCgojIEludmVzdGlnYWNpw7NuIGRlc2NyaXB0aXZhCgpTZSB1dGlsaXphIHBhcmEgY3VhbnRpZmljYXIgY2FyYWN0ZXLDrXN0aWNhcyBkZWwgbWVyY2Fkby4KClJlc3BvbmRlIHByZWd1bnRhcyBjb21vOgoKLSDCv3F1acOpbj87Ci0gwr9xdcOpPzsKLSDCv2N1w6FudG8/OwotIMK/Y3XDoW5kbz87Ci0gwr9kw7NuZGU/OwotIMK/Y29uIHF1w6kgZnJlY3VlbmNpYT8KCkVqZW1wbG9zOgoKLSBwb3JjZW50YWplIGRlIGNsaWVudGVzIHF1ZSBkZXNlYSByZW5vdmFyOwotIGVkYWQgcHJvbWVkaW87Ci0gbml2ZWwgcHJvbWVkaW8gZGUgc2F0aXNmYWNjacOzbjsKLSBwYXJ0aWNpcGFjacOzbiBkZSBjYW5hbGVzOwotIGRpc3RyaWJ1Y2nDs24gZGVsIG1lcmNhZG8gcG9yIHJlZ2nDs247Ci0gcHJvcG9yY2nDs24gcXVlIGNvbm9jZSBkZXRlcm1pbmFkbyBwcm9kdWN0by4KCi0tLQoKIyBJbnZlc3RpZ2FjacOzbiBjYXVzYWwKCkJ1c2NhIGRldGVybWluYXIgc2kgY2FtYmlvcyBlbiB1bmEgdmFyaWFibGUgcHJvZHVjZW4gY2FtYmlvcyBlbiBvdHJhLgoKRWplbXBsbzoKClVuYSBhc2VndXJhZG9yYSBxdWllcmUgY29ub2NlciBzaSBtb2RpZmljYXIgbGEgZm9ybWEgZGUgcHJlc2VudGFyIHVuYSBjb3RpemFjacOzbiBhdW1lbnRhIGxhIGFjZXB0YWNpw7NuLgoKUG9kcsOtYW1vcyBjb21wYXJhcjoKCi0gZ3J1cG8gQTogY290aXphY2nDs24gdHJhZGljaW9uYWw7Ci0gZ3J1cG8gQjogbnVldmEgcHJlc2VudGFjacOzbi4KClNpIGxhIGFzaWduYWNpw7NuIHkgZWwgZGlzZcOxbyBzb24gYWRlY3VhZG9zLCBwb2RlbW9zIGFwcm94aW1hcm5vcyBhIHVuYSBpbmZlcmVuY2lhIGNhdXNhbC4KCi0tLQoKIyBFeHBsb3JhdG9yaW8sIGRlc2NyaXB0aXZvIG8gY2F1c2FsCgpWZWFtb3MgYWxndW5vcyBlc2NlbmFyaW9zLgoKIyMjIFNpdHVhY2nDs24gQQoKPiBObyBzYWJlbW9zIHBvciBxdcOpIGxvcyBjbGllbnRlcyBlc3TDoW4gY2FuY2VsYW5kby4KCkRpc2XDsW8gcHJpbmNpcGFsOgoKKipFeHBsb3JhdG9yaW8uKioKCiMjIyBTaXR1YWNpw7NuIEIKCj4gUXVlcmVtb3MgY29ub2NlciBxdcOpIHBvcmNlbnRhamUgZGUgY2xpZW50ZXMgY29uc2lkZXJhIGNhcmEgbGEgcHJpbWEuCgpEaXNlw7FvIHByaW5jaXBhbDoKCioqRGVzY3JpcHRpdm8uKioKCiMjIyBTaXR1YWNpw7NuIEMKCj4gUXVlcmVtb3MgY29ub2NlciBzaSBvZnJlY2VyIHVuIGRlc2N1ZW50byBhdW1lbnRhIGxhIHJlbm92YWNpw7NuLgoKRGlzZcOxbyBwcmluY2lwYWw6CgoqKkNhdXNhbC4qKgoKLS0tCgotLS0KCiMgRGlzZcOxb3MgdHJhbnN2ZXJzYWxlcyB5IGxvbmdpdHVkaW5hbGVzCgpPdHJhIGRlY2lzacOzbiBpbXBvcnRhbnRlIGVzIGVsIG1vbWVudG8gZW4gcXVlIG9ic2VydmFtb3MgYSBsb3MgaW5kaXZpZHVvcy4KCiMjIEVzdHVkaW8gdHJhbnN2ZXJzYWwKCk9ic2VydmFtb3MgdW5hIHBvYmxhY2nDs24gZW4gdW4gcHVudG8gbyBwZXJpb2RvIGVzcGVjw61maWNvLgoKRWplbXBsbzoKCkVuY3Vlc3RhIGRlIHNhdGlzZmFjY2nDs24gcmVhbGl6YWRhIGR1cmFudGUgb2N0dWJyZSBkZSAyMDI2LgoKUG9kZW1vcyBwZW5zYXIgZW4gdW5hIGZvdG9ncmFmw61hLgoKIyMgRXN0dWRpbyBsb25naXR1ZGluYWwKCk9ic2VydmFtb3MgbGFzIG1pc21hcyB1bmlkYWRlcyByZXBldGlkYW1lbnRlLgoKRWplbXBsbzoKClNlZ3VpbW9zIGR1cmFudGUgMjQgbWVzZXMgYSBsb3MgbWlzbW9zIGFzZWd1cmFkb3MgeSByZWdpc3RyYW1vczoKCi0gcHJpbWE7Ci0gc2luaWVzdHJvczsKLSBzYXRpc2ZhY2Npw7NuOwotIHJlbm92YWNpw7NuLgoKUG9kZW1vcyBwZW5zYXIgZW4gdW5hIHBlbMOtY3VsYS4KCi0tLQoKIyBFamVtcGxvIGFjdHVhcmlhbAoKU3Vwb25nYW1vcyBxdWUgcXVlcmVtb3MgZXN0dWRpYXIgYWJhbmRvbm8uCgojIyMgRGlzZcOxbyB0cmFuc3ZlcnNhbAoKYGBgdGV4dApDbGllbnRlICAgICAgIE9jdHVicmUgMjAyNgpBICAgICAgICAgICAgIFJlbnVldmEKQiAgICAgICAgICAgICBObyByZW51ZXZhCkMgICAgICAgICAgICAgUmVudWV2YQpgYGAKCiMjIyBEaXNlw7FvIGxvbmdpdHVkaW5hbAoKYGBgdGV4dApDbGllbnRlICAgICAyMDI0ICAgICAyMDI1ICAgICAyMDI2CkEgICAgICAgICAgIFPDrSAgICAgICBTw60gICAgICAgU8OtCkIgICAgICAgICAgIFPDrSAgICAgICBTw60gICAgICAgTm8KQyAgICAgICAgICAgU8OtICAgICAgIE5vICAgICAgIC0KYGBgCgpFbCBzZWd1bmRvIGRpc2XDsW8gcGVybWl0ZSBlc3R1ZGlhciB0cmF5ZWN0b3JpYXMuCgotLS0KCiMgRnVlbnRlcyBkZSBlcnJvcgoKVG9kYSBpbnZlc3RpZ2FjacOzbiBjb250aWVuZSBlcnJvci4KCkVsIG9iamV0aXZvIG5vIGVzIGltYWdpbmFyIHF1ZSBwb2RlbW9zIGVsaW1pbmFybG8gcG9yIGNvbXBsZXRvLgoKRWwgb2JqZXRpdm8gZXM6CgotIGlkZW50aWZpY2FybG87Ci0gbWluaW1pemFybG87Ci0gY3VhbnRpZmljYXJsbyBjdWFuZG8gc2VhIHBvc2libGU7Ci0gcmVjb25vY2VyIHN1cyBpbXBsaWNhY2lvbmVzLgoKLS0tCgojIyBFcnJvciBkZSBtdWVzdHJlbwoKU3VyZ2UgcG9ycXVlIGVzdHVkaWFtb3MgdW5hIG11ZXN0cmEgeSBubyBuZWNlc2FyaWFtZW50ZSB0b2RhIGxhIHBvYmxhY2nDs24uCgpTdXBvbmdhbW9zIHVuYSBwb2JsYWNpw7NuIGNvbiBlZGFkIHByb21lZGlvIGNvbm9jaWRhLgoKYGBge3J9CnNldC5zZWVkKDIwMjYpCgpwb2JsYWNpb25fZWRhZCA8LSByb3VuZCgKICBybm9ybSgKICAgIG4gPSAxMDAwMDAsCiAgICBtZWFuID0gNDIsCiAgICBzZCA9IDEzCiAgKQopCgptZWFuKHBvYmxhY2lvbl9lZGFkKQpgYGAKClRvbWVtb3MgZGlmZXJlbnRlcyBtdWVzdHJhcyBkZSAxMDAgcGVyc29uYXMuCgpgYGB7cn0Kc2V0LnNlZWQoMjAyNikKCm1lZGlhc19tdWVzdHJhbGVzIDwtIHJlcGxpY2F0ZSgKICA1MDAsCiAgbWVhbigKICAgIHNhbXBsZSgKICAgICAgcG9ibGFjaW9uX2VkYWQsCiAgICAgIHNpemUgPSAxMDAKICAgICkKICApCikKCnN1bW1hcnkobWVkaWFzX211ZXN0cmFsZXMpCmBgYAoKVmlzdWFsaWNlbW9zLgoKYGBge3J9CmRhdGEuZnJhbWUoCiAgbWVkaWEgPSBtZWRpYXNfbXVlc3RyYWxlcwopICU+JQogIGdncGxvdCgKICAgIGFlcyh4ID0gbWVkaWEpCiAgKSArCiAgZ2VvbV9oaXN0b2dyYW0oCiAgICBiaW5zID0gMzAsCiAgICBjb2xvciA9ICJ3aGl0ZSIKICApICsKICBnZW9tX3ZsaW5lKAogICAgeGludGVyY2VwdCA9IG1lYW4ocG9ibGFjaW9uX2VkYWQpLAogICAgbGluZXR5cGUgPSAiZGFzaGVkIiwKICAgIGxpbmV3aWR0aCA9IDEKICApICsKICBsYWJzKAogICAgdGl0bGUgPSAiVmFyaWFiaWxpZGFkIGVudHJlIG11ZXN0cmFzIiwKICAgIHN1YnRpdGxlID0gIjUwMCBtdWVzdHJhcyBhbGVhdG9yaWFzIGRlIHRhbWHDsW8gMTAwIiwKICAgIHggPSAiRWRhZCBwcm9tZWRpbyBkZSBsYSBtdWVzdHJhIiwKICAgIHkgPSAiRnJlY3VlbmNpYSIKICApICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgpPYnNlcnZlIHF1ZSBkaWZlcmVudGVzIG11ZXN0cmFzIGdlbmVyYW4gZGlmZXJlbnRlcyBlc3RpbWFjaW9uZXMuCgpFc28gZXMgcGFydGUgZGUgbGEgdmFyaWFiaWxpZGFkIG11ZXN0cmFsLgoKTcOhcyBhZGVsYW50ZSBlc3R1ZGlhcmVtb3MgZm9ybWFsbWVudGU6CgotIGVycm9yIGVzdMOhbmRhcjsKLSBpbnRlcnZhbG9zIGRlIGNvbmZpYW56YTsKLSB0YW1hw7FvIGRlIG11ZXN0cmEuCgotLS0KCiMgRXJyb3Igbm8gYXRyaWJ1aWJsZSBhbCBtdWVzdHJlbwoKVGFtYmnDqW4gcHVlZGVuIGFwYXJlY2VyIGVycm9yZXMgcG9yOgoKLSBtYWxhIGRlZmluaWNpw7NuIGRlIHBvYmxhY2nDs247Ci0gcHJlZ3VudGFzIGFtYmlndWFzOwotIGZhbHRhIGRlIHJlc3B1ZXN0YTsKLSBlcnJvcmVzIGRlIHJlZ2lzdHJvOwotIGVycm9yZXMgZGUgY29kaWZpY2FjacOzbjsKLSBmcmF1ZGU7Ci0gZGF0b3MgZmFsdGFudGVzOwotIGVycm9yZXMgZGUgYW7DoWxpc2lzOwotIGluc3RydW1lbnRvcyBkZWZpY2llbnRlcy4KCjxkaXYgY2xhc3M9ImNhamEtYWxlcnRhIj4KCiMjIyBQdW50byBmdW5kYW1lbnRhbAoKQXVtZW50YXIgZWwgdGFtYcOxbyBkZSBsYSBtdWVzdHJhIHB1ZWRlIHJlZHVjaXIgZWwgZXJyb3IgbXVlc3RyYWwuCgpQZXJvIHVuYSBtdWVzdHJhIGdpZ2FudGVzY2EgKipubyBjb3JyaWdlIHVuIGN1ZXN0aW9uYXJpbyBtYWwgZGlzZcOxYWRvKiouCgo8L2Rpdj4KCi0tLQoKIyBJbnZlc3RpZ2FjacOzbiBkZSBtZXJjYWRvcywgU0lNIHkgYXBveW8gYSBkZWNpc2lvbmVzCgpMYXMgb3JnYW5pemFjaW9uZXMgcHJvZHVjZW4gaW5mb3JtYWNpw7NuIGNvbnRpbnVhbWVudGUuCgpQb3IgZWplbXBsbywgdW5hIGFzZWd1cmFkb3JhIHB1ZWRlIGRpc3BvbmVyIGRlOgoKLSBww7NsaXphczsKLSBwcmltYXM7Ci0gY2FuY2VsYWNpb25lczsKLSByZWNsYW1hY2lvbmVzOwotIGNhbmFsZXM7Ci0gYWdlbnRlczsKLSBjbGllbnRlczsKLSBjYW1wYcOxYXM7Ci0gY290aXphY2lvbmVzLgoKCmBgYHRleHQKQmFzZXMgaW50ZXJuYXMKICAgICAgKwpEYXRvcyBleHRlcm5vcwogICAgICArCkludmVzdGlnYWNpb25lcyBlc3BlY8OtZmljYXMKICAgICAg4oaTClByZXBhcmFjacOzbgogICAgICDihpMKQW7DoWxpc2lzCiAgICAgIOKGkwpWaXN1YWxpemFjacOzbgogICAgICDihpMKSW5mb3JtYWNpw7NuCiAgICAgIOKGkwpEZWNpc2nDs24KYGBgCgotLS0KCiMgQ29uc3RydWNjacOzbiBkZWwgY2FzbyBkZSB0cmFiYWpvIGRlbCBjdXJzbwoKQ3JlYXJlbW9zIHVuYSBiYXNlIHNpbXVsYWRhIGRlIGNsaWVudGVzIGRlIHNlZ3Vyb3MuCgpgYGB7cn0Kc2V0LnNlZWQoMjAyNikKCm4gPC0gMTIwMAoKbWVyY2Fkb19zZWd1cm9zIDwtIGRhdGEuZnJhbWUoCiAgaWQgPSAxOm4sCiAgCiAgZWRhZCA9IHJvdW5kKAogICAgcG1pbigKICAgICAgcG1heCgKICAgICAgICBybm9ybShuLCA0MiwgMTIpLAogICAgICAgIDE4CiAgICAgICksCiAgICAgIDc1CiAgICApCiAgKSwKICAKICBpbmdyZXNvX21lbnN1YWwgPSByb3VuZCgKICAgIHJsbm9ybSgKICAgICAgbiwKICAgICAgbG9nKDkwMDApLAogICAgICAwLjU1CiAgICApLAogICAgMAogICksCiAgCiAgcmVnaW9uID0gc2FtcGxlKAogICAgYygKICAgICAgIk1ldHJvcG9saXRhbmEiLAogICAgICAiTm9ydGUiLAogICAgICAiT2NjaWRlbnRlIiwKICAgICAgIk9yaWVudGUiLAogICAgICAiU3VyIgogICAgKSwKICAgIG4sCiAgICByZXBsYWNlID0gVFJVRSwKICAgIHByb2IgPSBjKAogICAgICAwLjQyLAogICAgICAwLjEyLAogICAgICAwLjE4LAogICAgICAwLjE1LAogICAgICAwLjEzCiAgICApCiAgKSwKICAKICBjYW5hbCA9IHNhbXBsZSgKICAgIGMoCiAgICAgICJBZ2VudGUiLAogICAgICAiRGlnaXRhbCIsCiAgICAgICJTdWN1cnNhbCIsCiAgICAgICJCYW5jYXNlZ3Vyb3MiCiAgICApLAogICAgbiwKICAgIHJlcGxhY2UgPSBUUlVFLAogICAgcHJvYiA9IGMoCiAgICAgIDAuMzUsCiAgICAgIDAuMzAsCiAgICAgIDAuMjAsCiAgICAgIDAuMTUKICAgICkKICApLAogIAogIGFudGlndWVkYWQgPSBwbWF4KAogICAgMSwKICAgIHJvdW5kKAogICAgICByZ2FtbWEoCiAgICAgICAgbiwKICAgICAgICBzaGFwZSA9IDIuNSwKICAgICAgICBzY2FsZSA9IDIKICAgICAgKQogICAgKQogICksCiAgCiAgc2luaWVzdHJvc18yYSA9IHJwb2lzKAogICAgbiwKICAgIGxhbWJkYSA9IDAuMzUKICApLAogIAogIHNhdGlzZmFjY2lvbiA9IHNhbXBsZSgKICAgIDE6MTAsCiAgICBuLAogICAgcmVwbGFjZSA9IFRSVUUsCiAgICBwcm9iID0gYygKICAgICAgMC4wMiwKICAgICAgMC4wMywKICAgICAgMC4wNCwKICAgICAgMC4wNiwKICAgICAgMC4xMCwKICAgICAgMC4xMywKICAgICAgMC4xOCwKICAgICAgMC4xOSwKICAgICAgMC4xNSwKICAgICAgMC4xMAogICAgKQogICksCiAgCiAgaW5jcmVtZW50b19wcmltYSA9IHJvdW5kKAogICAgcG1heCgKICAgICAgcm5vcm0oCiAgICAgICAgbiwKICAgICAgICBtZWFuID0gOCwKICAgICAgICBzZCA9IDYKICAgICAgKSwKICAgICAgLTUKICAgICksCiAgICAxCiAgKQopCmBgYAoKQWhvcmEgY29uc3RydWlyZW1vcyB1bmEgaW50ZW5jacOzbiBkZSByZW5vdmFjacOzbiBzaW11bGFkYS4KCkxhIGNvbnN0cnVpcmVtb3MgZGUgbWFuZXJhIHF1ZSBkZXBlbmRhIHBhcmNpYWxtZW50ZSBkZToKCi0gc2F0aXNmYWNjacOzbjsKLSBpbmNyZW1lbnRvIGRlIHByaW1hOwotIGFudGlnw7xlZGFkOwotIGV4cGVyaWVuY2lhIGRlIHNpbmllc3Ryby4KCmBgYHtyfQppbmRpY2VfcmVub3ZhY2lvbiA8LQogIDAuNDUgKiBtZXJjYWRvX3NlZ3Vyb3Mkc2F0aXNmYWNjaW9uIC0KICAwLjEwICogbWVyY2Fkb19zZWd1cm9zJGluY3JlbWVudG9fcHJpbWEgKwogIDAuMDUgKiBtZXJjYWRvX3NlZ3Vyb3MkYW50aWd1ZWRhZCAtCiAgMC4yMCAqIG1lcmNhZG9fc2VndXJvcyRzaW5pZXN0cm9zXzJhICsKICBybm9ybShuLCAwLCAxLjUpCgptZXJjYWRvX3NlZ3Vyb3MkaW50ZW5jaW9uX3Jlbm92YXIgPC0gY3V0KAogIGluZGljZV9yZW5vdmFjaW9uLAogIGJyZWFrcyA9IHF1YW50aWxlKAogICAgaW5kaWNlX3Jlbm92YWNpb24sCiAgICBwcm9icyA9IHNlcSgwLCAxLCAwLjIpCiAgKSwKICBpbmNsdWRlLmxvd2VzdCA9IFRSVUUsCiAgbGFiZWxzID0gMTo1CikKCm1lcmNhZG9fc2VndXJvcyRpbnRlbmNpb25fcmVub3ZhciA8LSBhcy5pbnRlZ2VyKAogIGFzLmNoYXJhY3RlcigKICAgIG1lcmNhZG9fc2VndXJvcyRpbnRlbmNpb25fcmVub3ZhcgogICkKKQpgYGAKCkNyZWFyZW1vcyB0YW1iacOpbiB1bmEgdmFyaWFibGUgYmluYXJpYSBkZSByZW5vdmFjacOzbiBvYnNlcnZhZGEuCgpgYGB7cn0KcHJvYl9yZW5vdmFyIDwtIHBsb2dpcygKICAtMC41ICsKICAwLjM1ICogbWVyY2Fkb19zZWd1cm9zJHNhdGlzZmFjY2lvbiAtCiAgMC4wOSAqIG1lcmNhZG9fc2VndXJvcyRpbmNyZW1lbnRvX3ByaW1hICsKICAwLjA0ICogbWVyY2Fkb19zZWd1cm9zJGFudGlndWVkYWQgLQogIDAuMTUgKiBtZXJjYWRvX3NlZ3Vyb3Mkc2luaWVzdHJvc18yYQopCgptZXJjYWRvX3NlZ3Vyb3MkcmVudWV2YSA8LSByYmlub20oCiAgbiwKICBzaXplID0gMSwKICBwcm9iID0gcHJvYl9yZW5vdmFyCikKCm1lcmNhZG9fc2VndXJvcyRyZW51ZXZhIDwtIGlmZWxzZSgKICBtZXJjYWRvX3NlZ3Vyb3MkcmVudWV2YSA9PSAxLAogICJTw60iLAogICJObyIKKQpgYGAKCkd1YXJkZW1vcyBsYSBiYXNlIHBhcmEgdXRpbGl6YXJsYSBwb3N0ZXJpb3JtZW50ZS4KCmBgYHtyfQp3cml0ZS5jc3YoCiAgbWVyY2Fkb19zZWd1cm9zLAogICJtZXJjYWRvX3NlZ3Vyb3NfY2xhc2UxLmNzdiIsCiAgcm93Lm5hbWVzID0gRkFMU0UKKQpgYGAKCi0tLQoKIyBJbnNwZWNjacOzbiBpbmljaWFsCgpTdXBvbmdhbW9zIHF1ZSByZWNpYmltb3MgbGEgYmFzZSB5IHRvZGF2w61hIG5vIGNvbm9jZW1vcyBzdSBjb250ZW5pZG8uCgpMYSBwcmltZXJhIGluc3RydWNjacOzbiBzZXLDrWE6CgpgYGB7cn0KaGVhZChtZXJjYWRvX3NlZ3Vyb3MpCmBgYAoKTHVlZ286CgpgYGB7cn0Kc3RyKG1lcmNhZG9fc2VndXJvcykKYGBgCgpEaW1lbnNpb25lczoKCmBgYHtyfQpkaW0obWVyY2Fkb19zZWd1cm9zKQpgYGAKCk5vbWJyZXM6CgpgYGB7cn0KbmFtZXMobWVyY2Fkb19zZWd1cm9zKQpgYGAKClJlc3VtZW46CgpgYGB7cn0Kc3VtbWFyeShtZXJjYWRvX3NlZ3Vyb3MpCmBgYAoKLS0tCgojIERpY2Npb25hcmlvIGluaWNpYWwgZGUgdmFyaWFibGVzCgpgYGB7cn0KZGljY2lvbmFyaW8gPC0gZGF0YS5mcmFtZSgKICBWYXJpYWJsZSA9IG5hbWVzKG1lcmNhZG9fc2VndXJvcyksCiAgRGVzY3JpcGNpb24gPSBjKAogICAgIklkZW50aWZpY2Fkb3IiLAogICAgIkVkYWQgZGVsIGNsaWVudGUiLAogICAgIkluZ3Jlc28gbWVuc3VhbCBlc3RpbWFkbyIsCiAgICAiUmVnacOzbiIsCiAgICAiQ2FuYWwgcHJpbmNpcGFsIiwKICAgICJBbnRpZ8O8ZWRhZCBjb21vIGNsaWVudGUiLAogICAgIk7Dum1lcm8gZGUgc2luaWVzdHJvcyBlbiBsb3Mgw7psdGltb3MgZG9zIGHDsW9zIiwKICAgICJTYXRpc2ZhY2Npw7NuIGRlIDEgYSAxMCIsCiAgICAiSW5jcmVtZW50byBwb3JjZW50dWFsIGRlIGxhIHByaW1hIiwKICAgICJJbnRlbmNpw7NuIGRlIHJlbm92YWNpw7NuIGRlIDEgYSA1IiwKICAgICJSZW5vdmFjacOzbiBvYnNlcnZhZGEiCiAgKQopCgprbml0cjo6a2FibGUoCiAgZGljY2lvbmFyaW8sCiAgY2FwdGlvbiA9ICJEaWNjaW9uYXJpbyBpbmljaWFsIGRlIHZhcmlhYmxlcyIKKQpgYGAKCi0tLQoKIyBQcmVndW50YSBleHBsb3JhdG9yaWEgMTogwr9RdWnDqW5lcyBpbnRlZ3JhbiBlbCBtZXJjYWRvPwoKVmVhbW9zIGxhIGVkYWQuCgpgYGB7cn0Kc3VtbWFyeSgKICBtZXJjYWRvX3NlZ3Vyb3MkZWRhZAopCmBgYAoKVmlzdWFsaWNlbW9zLgoKYGBge3J9CmdncGxvdCgKICBtZXJjYWRvX3NlZ3Vyb3MsCiAgYWVzKHggPSBlZGFkKQopICsKICBnZW9tX2hpc3RvZ3JhbSgKICAgIGJpbnMgPSAyNSwKICAgIGNvbG9yID0gIndoaXRlIgogICkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJEaXN0cmlidWNpw7NuIGRlIGVkYWQiLAogICAgeCA9ICJFZGFkIiwKICAgIHkgPSAiTsO6bWVybyBkZSBjbGllbnRlcyIKICApICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgpFc3RhIGdyw6FmaWNhIHJlc3BvbmRlIHVuYSBwcmVndW50YSAqKmRlc2NyaXB0aXZhKiouCgpObyBleHBsaWNhIHBvciBxdcOpIG9jdXJyZSBhbGdvLgoKLS0tCgojIFByZWd1bnRhIGV4cGxvcmF0b3JpYSAyOiDCv0TDs25kZSBlc3TDoW4gbG9zIGNsaWVudGVzPwoKYGBge3J9CnRhYmxhX3JlZ2lvbiA8LSB0YWJsZSgKICBtZXJjYWRvX3NlZ3Vyb3MkcmVnaW9uCikKCnRhYmxhX3JlZ2lvbgpgYGAKClBvcmNlbnRhamVzOgoKYGBge3J9CnJvdW5kKAogIHByb3AudGFibGUodGFibGFfcmVnaW9uKSAqIDEwMCwKICAxCikKYGBgCgpHcsOhZmljbzoKCmBgYHtyfQptZXJjYWRvX3NlZ3Vyb3MgJT4lCiAgY291bnQocmVnaW9uKSAlPiUKICBtdXRhdGUoCiAgICBwb3JjZW50YWplID0gbiAvIHN1bShuKQogICkgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gcmVvcmRlcihyZWdpb24sIG4pLAogICAgICB5ID0gcG9yY2VudGFqZQogICAgKQogICkgKwogIGdlb21fY29sKCkgKwogIGNvb3JkX2ZsaXAoKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50CiAgKSArCiAgbGFicygKICAgIHRpdGxlID0gIkRpc3RyaWJ1Y2nDs24gdGVycml0b3JpYWwgZGUgY2xpZW50ZXMiLAogICAgeCA9IE5VTEwsCiAgICB5ID0gIlBvcmNlbnRhamUiCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKLS0tCgojIFByZWd1bnRhIGV4cGxvcmF0b3JpYSAzOiDCv0PDs21vIGVzIGxhIHNhdGlzZmFjY2nDs24/CgpgYGB7cn0Kc3VtbWFyeSgKICBtZXJjYWRvX3NlZ3Vyb3Mkc2F0aXNmYWNjaW9uCikKYGBgCgpEaXN0cmlidWNpw7NuOgoKYGBge3J9Cm1lcmNhZG9fc2VndXJvcyAlPiUKICBjb3VudChzYXRpc2ZhY2Npb24pICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGZhY3RvcihzYXRpc2ZhY2Npb24pLAogICAgICB5ID0gbgogICAgKQogICkgKwogIGdlb21fY29sKCkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJTYXRpc2ZhY2Npw7NuIGRlIGxvcyBjbGllbnRlcyIsCiAgICB4ID0gIlNhdGlzZmFjY2nDs24iLAogICAgeSA9ICJOw7ptZXJvIGRlIGNsaWVudGVzIgogICkgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCi0tLQoKIyBQcmVndW50YSBleHBsb3JhdG9yaWEgNDogwr9RdcOpIHBvcmNlbnRhamUgcmVudWV2YT8KCmBgYHtyfQp0YWJsZSgKICBtZXJjYWRvX3NlZ3Vyb3MkcmVudWV2YQopCmBgYAoKYGBge3J9CnJvdW5kKAogIHByb3AudGFibGUoCiAgICB0YWJsZSgKICAgICAgbWVyY2Fkb19zZWd1cm9zJHJlbnVldmEKICAgICkKICApICogMTAwLAogIDEKKQpgYGAKCi0tLQoKIyBEZWwgYW7DoWxpc2lzIGRlc2NyaXB0aXZvIGEgbnVldmFzIHByZWd1bnRhcwoKU3Vwb25nYW1vcyBxdWUgb2JzZXJ2YW1vcyB1bmEgdGFzYSBjb25zaWRlcmFibGUgZGUgbm8gcmVub3ZhY2nDs24uCgpMYSBzaWd1aWVudGUgcHJlZ3VudGEgbm8gZGViZXLDrWEgc2VyIGF1dG9tw6F0aWNhbWVudGU6Cgo+IMK/Q8OzbW8gcHVlZG8gY29uc3RydWlyIHVuYSByZWdyZXNpw7NuPwoKTGEgcHJlZ3VudGEgY29ycmVjdGEgZXM6Cgo+IMK/UXXDqSBoaXDDs3Rlc2lzIHJhem9uYWJsZXMgcG9kcsOtYW4gZXhwbGljYXIgbGEgbm8gcmVub3ZhY2nDs24/CgpQb2Ryw61hbW9zIGV4cGxvcmFyOgoKLSBpbmNyZW1lbnRvIGRlIHByaW1hOwotIHNhdGlzZmFjY2nDs247Ci0gc2luaWVzdHJvczsKLSBhbnRpZ8O8ZWRhZDsKLSBjYW5hbDsKLSByZWdpw7NuLgoKLS0tCgojIFByaW1hIHkgcmVub3ZhY2nDs24KCkNhbGN1bGVtb3MgZWwgaW5jcmVtZW50byBwcm9tZWRpbyBzZWfDum4gcmVub3ZhY2nDs24uCgpgYGB7cn0KbWVyY2Fkb19zZWd1cm9zICU+JQogIGdyb3VwX2J5KHJlbnVldmEpICU+JQogIHN1bW1hcmlzZSgKICAgIG4gPSBuKCksCiAgICBpbmNyZW1lbnRvX3Byb21lZGlvID0gbWVhbihpbmNyZW1lbnRvX3ByaW1hKSwKICAgIG1lZGlhbmFfaW5jcmVtZW50byA9IG1lZGlhbihpbmNyZW1lbnRvX3ByaW1hKQogICkKYGBgCgpWaXN1YWxpY2Vtb3MuCgpgYGB7cn0KZ2dwbG90KAogIG1lcmNhZG9fc2VndXJvcywKICBhZXMoCiAgICB4ID0gcmVudWV2YSwKICAgIHkgPSBpbmNyZW1lbnRvX3ByaW1hCiAgKQopICsKICBnZW9tX2JveHBsb3QoKSArCiAgbGFicygKICAgIHRpdGxlID0gIkluY3JlbWVudG8gZGUgcHJpbWEgc2Vnw7puIHJlbm92YWNpw7NuIiwKICAgIHggPSAiUmVub3ZhY2nDs24iLAogICAgeSA9ICJJbmNyZW1lbnRvIGRlIHByaW1hICglKSIKICApICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgo8ZGl2IGNsYXNzPSJjYWphLXByZWd1bnRhIj4KCsK/UXXDqSBwb2RlbW9zIGRlY2lyPwoKUG9kZW1vcyBkZWNpciBxdWUgZXhpc3RlbiBkaWZlcmVuY2lhcyBkZXNjcmlwdGl2YXMgZW50cmUgbG9zIGdydXBvcy4KClRvZGF2w61hIG5vIHBvZGVtb3MgZGVjaXIgcXVlOgoKPiDigJxlbCBpbmNyZW1lbnRvIGRlIHByaW1hIGNhdXNhIGxhIG5vIHJlbm92YWNpw7Nu4oCdLgoKwr9Qb3IgcXXDqT8KClBvcnF1ZSBubyBoZW1vcyBjb250cm9sYWRvOgoKLSBzYXRpc2ZhY2Npw7NuOwotIGFudGlnw7xlZGFkOwotIHNpbmllc3Ryb3M7Ci0gaW5ncmVzbzsKLSBwb3NpYmxlcyB2YXJpYWJsZXMgb21pdGlkYXMuCgo8L2Rpdj4KCi0tLQoKIyBTYXRpc2ZhY2Npw7NuIHkgcmVub3ZhY2nDs24KCmBgYHtyfQptZXJjYWRvX3NlZ3Vyb3MgJT4lCiAgZ3JvdXBfYnkocmVudWV2YSkgJT4lCiAgc3VtbWFyaXNlKAogICAgc2F0aXNmYWNjaW9uX3Byb21lZGlvID0gbWVhbihzYXRpc2ZhY2Npb24pLAogICAgbWVkaWFuYSA9IG1lZGlhbihzYXRpc2ZhY2Npb24pLAogICAgbiA9IG4oKQogICkKYGBgCgpgYGB7cn0KZ2dwbG90KAogIG1lcmNhZG9fc2VndXJvcywKICBhZXMoCiAgICB4ID0gcmVudWV2YSwKICAgIHkgPSBzYXRpc2ZhY2Npb24KICApCikgKwogIGdlb21fYm94cGxvdCgpICsKICBsYWJzKAogICAgdGl0bGUgPSAiU2F0aXNmYWNjacOzbiBzZWfDum4gcmVub3ZhY2nDs24iLAogICAgeCA9ICJSZW5vdmFjacOzbiIsCiAgICB5ID0gIlNhdGlzZmFjY2nDs24iCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKQWhvcmEgdGVuZW1vcyBvdHJhIHBpc3RhLgoKUXVpesOhIGVsIHByb2JsZW1hIHNlYSBtw6FzIGNvbXBsZWpvIHF1ZSBzaW1wbGVtZW50ZSBlbCBwcmVjaW8uCgotLS0KCiMgQ29tYmluYW5kbyBkb3MgZGltZW5zaW9uZXMKClBvZGVtb3MgZXhwbG9yYXIgc2F0aXNmYWNjacOzbiBlIGluY3JlbWVudG8gZGUgcHJpbWEuCgpgYGB7cn0KZ2dwbG90KAogIG1lcmNhZG9fc2VndXJvcywKICBhZXMoCiAgICB4ID0gaW5jcmVtZW50b19wcmltYSwKICAgIHkgPSBzYXRpc2ZhY2Npb24KICApCikgKwogIGdlb21fcG9pbnQoCiAgICBhbHBoYSA9IDAuMzUKICApICsKICBmYWNldF93cmFwKAogICAgfiByZW51ZXZhCiAgKSArCiAgbGFicygKICAgIHRpdGxlID0gIlByaW1hIHkgc2F0aXNmYWNjacOzbiBzZWfDum4gcmVub3ZhY2nDs24iLAogICAgeCA9ICJJbmNyZW1lbnRvIGRlIHByaW1hICglKSIsCiAgICB5ID0gIlNhdGlzZmFjY2nDs24iCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKRXN0YSBncsOhZmljYSBwdWVkZSBnZW5lcmFyIG51ZXZhcyBoaXDDs3Rlc2lzLgoKUG9yIGVqZW1wbG86Cgo+IExhIGNvbWJpbmFjacOzbiBkZSBpbmNyZW1lbnRvcyBhbHRvcyB5IGJhamEgc2F0aXNmYWNjacOzbiBwb2Ryw61hIGVzdGFyIGFzb2NpYWRhIGNvbiBtZW5vciByZW5vdmFjacOzbi4KCk9ic2VydmUgbGEgZGluw6FtaWNhOgoKYGBgdGV4dApEQVRPUwogIOKGkwpFWFBMT1JBQ0nDk04KICDihpMKUEFUUsOTTgogIOKGkwpQUkVHVU5UQQogIOKGkwpISVDDk1RFU0lTCiAg4oaTCkFOw4FMSVNJUyBQT1NURVJJT1IKYGBgCgotLS0KCiMgRWplbXBsbzogZGUgb2JzZXJ2YWNpw7NuIGEgcHJlZ3VudGEgZm9ybWFsCgpEZXNwdcOpcyBkZSBsYSBleHBsb3JhY2nDs24gcG9kZW1vcyBmb3JtdWxhcjoKCiMjIyBPYnNlcnZhY2nDs24KCkxvcyBjbGllbnRlcyBxdWUgbm8gcmVudWV2YW4gcGFyZWNlbiBwcmVzZW50YXI6CgotIG1heW9yIGluY3JlbWVudG8gZGUgcHJpbWE7Ci0gbWVub3Igc2F0aXNmYWNjacOzbi4KCiMjIyBQcmVndW50YQoKPiDCv0PDs21vIHNlIHJlbGFjaW9uYW4gZWwgaW5jcmVtZW50byBkZSBwcmltYSB5IGxhIHNhdGlzZmFjY2nDs24gY29uIGxhIHByb2JhYmlsaWRhZCBkZSByZW5vdmFjacOzbj8KCiMjIyBIaXDDs3Rlc2lzIDEKCj4gQSBtYXlvciBpbmNyZW1lbnRvIGRlIHByaW1hLCBtZW5vciBwcm9iYWJpbGlkYWQgZGUgcmVub3ZhY2nDs24uCgojIyMgSGlww7N0ZXNpcyAyCgo+IEEgbWF5b3Igc2F0aXNmYWNjacOzbiwgbWF5b3IgcHJvYmFiaWxpZGFkIGRlIHJlbm92YWNpw7NuLgoKIyMjIERpc2XDsW8gaW5pY2lhbAoKKipEZXNjcmlwdGl2byAvIGV4cGxpY2F0aXZvIG9ic2VydmFjaW9uYWwuKioKCk3DoXMgYWRlbGFudGUgdXRpbGl6YXJlbW9zIHJlZ3Jlc2nDs24gbG9nw61zdGljYSBwYXJhIGFuYWxpemFyIGVzdGEgcHJlZ3VudGEuCgotLS0KCiMgQ29ycmVsYWNpw7NuIG5vIHNpZ25pZmljYSBjYXVzYWxpZGFkCgpFc3RhIGRpc3RpbmNpw7NuIHNlcsOhIHJlY3VycmVudGUgZHVyYW50ZSBlbCBjdXJzby4KClN1cG9uZ2Ftb3MgcXVlIG9ic2VydmFtb3M6CgpcWwpYIFx1cGFycm93IFxxdWFkIFx0ZXh0e2N1YW5kb30gXHF1YWQgWSBcdXBhcnJvdwpcXQoKRXNvIGRlbXVlc3RyYSBhc29jaWFjacOzbi4KCk5vIG5lY2VzYXJpYW1lbnRlIGRlbXVlc3RyYToKClxbClggXHJpZ2h0YXJyb3cgWQpcXQoKUHVlZGUgZXhpc3RpcjoKClxbClogXHJpZ2h0YXJyb3cgWApcXQoKeSBzaW11bHTDoW5lYW1lbnRlOgoKXFsKWiBccmlnaHRhcnJvdyBZClxdCgotLS0KCiMgRWplbXBsbyBhY3R1YXJpYWwgZGUgY29uZnVzacOzbgoKSW1hZ2luZSBxdWUgZW5jb250cmFtb3M6Cgo+IExvcyBjbGllbnRlcyBjb24gcHJpbWFzIG3DoXMgYWx0YXMgdGllbmVuIG3DoXMgc2luaWVzdHJvcy4KCsK/UG9kZW1vcyBjb25jbHVpciBxdWUgYXVtZW50YXIgbGEgcHJpbWEgY2F1c2Egc2luaWVzdHJvcz8KCk5vLgoKUHJvYmFibGVtZW50ZSBhbWJhcyB2YXJpYWJsZXMgZXN0w6FuIHJlbGFjaW9uYWRhcyBjb246CgotIGV4cG9zaWNpw7NuOwotIHRpcG8gZGUgdmVow61jdWxvOwotIGVkYWQ7Ci0gc3VtYSBhc2VndXJhZGE7Ci0gem9uYTsKLSBjYXJhY3RlcsOtc3RpY2FzIGRlbCByaWVzZ28uCgpMYSBlc3RydWN0dXJhIHBvZHLDrWEgc2VyOgoKYGBgdGV4dApOaXZlbCBkZSByaWVzZ28KICAgICDihpMKIOKUjOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUkAog4oaTICAgICAgICAgICAgIOKGkwpQcmltYSAgICAgIFNpbmllc3Ryb3MKYGBgCgpMYSBwcmltYSB5IGxvcyBzaW5pZXN0cm9zIGFwYXJlY2VuIGFzb2NpYWRvcywgcGVybyB1bmEgdmFyaWFibGUgc3VieWFjZW50ZSBwdWVkZSBleHBsaWNhciBwYXJ0ZSBkZSBsYSByZWxhY2nDs24uCgotLS0KCiMgRWplbXBsbyBkZSBkaXNlw7FvIGNhdXNhbAoKU3Vwb25nYSBxdWUgbGEgZW1wcmVzYSBkZXNlYSBzYWJlcjoKCj4gwr9FbnZpYXIgdW4gbWVuc2FqZSBwZXJzb25hbGl6YWRvIGF1bWVudGEgbGEgcmVub3ZhY2nDs24/CgpQb2RlbW9zIGltYWdpbmFyIHVuIGV4cGVyaW1lbnRvLgoKYGBge3J9CnNldC5zZWVkKDEwMCkKCmV4cGVyaW1lbnRvIDwtIGRhdGEuZnJhbWUoCiAgZ3J1cG8gPSByZXAoCiAgICBjKAogICAgICAiTWVuc2FqZSBlc3TDoW5kYXIiLAogICAgICAiTWVuc2FqZSBwZXJzb25hbGl6YWRvIgogICAgKSwKICAgIGVhY2ggPSA1MDAKICApCikKCmV4cGVyaW1lbnRvJHJlbnVldmEgPC0gYygKICByYmlub20oCiAgICA1MDAsCiAgICAxLAogICAgMC42NwogICksCiAgcmJpbm9tKAogICAgNTAwLAogICAgMSwKICAgIDAuNzUKICApCikKCmFnZ3JlZ2F0ZSgKICByZW51ZXZhIH4gZ3J1cG8sCiAgZGF0YSA9IGV4cGVyaW1lbnRvLAogIEZVTiA9IG1lYW4KKQpgYGAKClZpc3VhbGljZW1vcy4KCmBgYHtyfQpleHBlcmltZW50byAlPiUKICBncm91cF9ieShncnVwbykgJT4lCiAgc3VtbWFyaXNlKAogICAgdGFzYSA9IG1lYW4ocmVudWV2YSkKICApICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGdydXBvLAogICAgICB5ID0gdGFzYQogICAgKQogICkgKwogIGdlb21fY29sKCkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudAogICkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJUYXNhIGRlIHJlbm92YWNpw7NuIHBvciB0cmF0YW1pZW50byIsCiAgICB4ID0gTlVMTCwKICAgIHkgPSAiVGFzYSBkZSByZW5vdmFjacOzbiIKICApICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgpMYSBsw7NnaWNhIGNhdXNhbCByZXF1aWVyZSBtdWNobyBtw6FzIHF1ZSBvYnNlcnZhciB1bmEgZGlmZXJlbmNpYS4KCk5lY2VzaXRhbW9zIGNvbnNpZGVyYXI6CgotIGFzaWduYWNpw7NuOwotIGNvbXBhcmFiaWxpZGFkOwotIHZhcmlhYmxlcyBleHRyYcOxYXM7Ci0gdGFtYcOxbyBkZSBtdWVzdHJhOwotIGF6YXI7Ci0gdmFsaWRleiBpbnRlcm5hOwotIHZhbGlkZXogZXh0ZXJuYS4KCkxvIGVzdHVkaWFyZW1vcyBjb24gbWF5b3IgZGV0YWxsZSBwb3N0ZXJpb3JtZW50ZS4KCi0tLQoKIyBVbiBwcmluY2lwaW8gaW1wb3J0YW50ZQoKRHVyYW50ZSBlc3RlIGN1cnNvIGV2aXRhcmVtb3MgbGEgbMOzZ2ljYToKCmBgYHRleHQKVGVuZ28gdW5hIGJhc2UKICAgICAg4oaTCsK/UXXDqSBhbsOhbGlzaXMgcHVlZG8gaGFjZXI/CmBgYAoKSW50ZW50YXJlbW9zIHV0aWxpemFyOgoKYGBgdGV4dApUZW5nbyB1bmEgZGVjaXNpw7NuCiAgICAgIOKGkwrCv1F1w6kgbmVjZXNpdG8gc2FiZXI/CiAgICAgIOKGkwrCv1F1w6kgcHJlZ3VudGEgZGVibyByZXNwb25kZXI/CiAgICAgIOKGkwrCv1F1w6kgZGF0b3MgbmVjZXNpdG8/CiAgICAgIOKGkwrCv1F1w6kgYW7DoWxpc2lzIGNvcnJlc3BvbmRlPwpgYGAKCjxkaXYgY2xhc3M9ImNhamEtYWN0dWFyaWFsIj4KCgoqKlByaW1lcm8gbGEgcHJlZ3VudGEuIERlc3B1w6lzIGVsIG3DqXRvZG8uKioKCk5vIHV0aWxpemFyZW1vcyB1bmEgdMOpY25pY2EgZXN0YWTDrXN0aWNhIHNpbXBsZW1lbnRlIHBvcnF1ZSBlc3TDqSBkaXNwb25pYmxlLgoKPC9kaXY+CgotLS0KCiMgRXJyb3JlcyBmcmVjdWVudGVzIGFsIGZvcm11bGFyIGludmVzdGlnYWNpb25lcwoKIyMgRXJyb3IgMS4gRW1wZXphciBwb3IgbGEgdMOpY25pY2EKCj4g4oCcUXVpZXJvIGhhY2VyIHVuYSByZWdyZXNpw7NuLuKAnQoKUHJlZ3VudGEgY29ycmVjdGE6Cgo+IMK/UXXDqSBwcm9ibGVtYSByZXF1aWVyZSB1biBtb2RlbG8gZGUgcmVncmVzacOzbj8KCi0tLQoKIyMgRXJyb3IgMi4gQ29uZnVuZGlyIHPDrW50b21hIGNvbiBwcm9ibGVtYQoKU8OtbnRvbWE6Cgo+IExhcyB2ZW50YXMgZGlzbWludXllcm9uLgoKUHJvYmxlbWE6CgpQb2Ryw61hIHNlcjoKCi0gcHJlY2lvOwotIHByb2R1Y3RvOwotIGNvbXBldGVuY2lhOwotIGNhbmFsOwotIG1lcmNhZG87Ci0gcGVyY2VwY2nDs24uCgotLS0KCiMjIEVycm9yIDMuIFByZWd1bnRhIGRlbWFzaWFkbyBhbXBsaWEKCj4gwr9RdcOpIHBpZW5zYSBsYSBnZW50ZSBkZSBsb3Mgc2VndXJvcz8KCkRlYmUgZGVsaW1pdGFyc2U6CgotIHF1w6kgcGVyc29uYXM7Ci0gcXXDqSBzZWd1cm9zOwotIHF1w6kgZGltZW5zacOzbjsKLSBxdcOpIHRlcnJpdG9yaW87Ci0gcXXDqSBwZXJpb2RvLgoKLS0tCgojIyBFcnJvciA0LiBBc3VtaXIgY2F1c2FsaWRhZAoKPiBMb3MgY2xpZW50ZXMgcXVlIHBhZ2FuIG3DoXMgY2FuY2VsYW4gbcOhcywgcG9yIGxvIHRhbnRvIGVsIHByZWNpbyBjYXVzYSBjYW5jZWxhY2nDs24uCgpVbmEgYXNvY2lhY2nDs24gb2JzZXJ2YWRhIG5vIGRlbXVlc3RyYSBjYXVzYWxpZGFkLgoKLS0tCgojIyBFcnJvciA1LiBEaXNlw7FhciBwcmltZXJvIGxhIGVuY3Vlc3RhCgpObyBkZWJlcsOtYW1vcyBwcmVndW50YXI6Cgo+IOKAnMK/UXXDqSBwcmVndW50YXMgcG9uZ28gZW4gZWwgY3Vlc3Rpb25hcmlvP+KAnQoKYW50ZXMgZGUgcmVzcG9uZGVyOgoKPiDigJzCv1F1w6kgaW5mb3JtYWNpw7NuIG5lY2VzaXRvP+KAnQoKLS0tCgojIE1hcGEgY29uY2VwdHVhbCBmaW5hbAoKYGBgdGV4dAogICAgICAgICAgICAgICAgICAgICAgICAgREVDSVNJw5NOIEVNUFJFU0FSSUFMCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKWvAogICAgICAgICAgICAgICAgICAgICAgICAgREVGSU5JUiBFTCBQUk9CTEVNQQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCCiAgICAgICAgICAgICDilIzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilLTilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJAKICAgICAgICAgICAgIOKUgiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUggogICAgICAgICAgICAg4pa8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pa8CiAgICAgIENPTlRFWFRPIERFTCBQUk9CTEVNQSAgICAgICAgICAgICAgICAgICAgSU5GT1JNQUNJw5NOIEVYSVNURU5URQogICAgICAgICAgICAg4pSCICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCCiAgICAgICAgICAgICDilJTilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilKzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKWvAogICAgICAgICAgICAgICAgICAgICAgIFBST0JMRU1BIERFIElOVkVTVElHQUNJw5NOCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKWvAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQkpFVElWT1MKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUggogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pa8CiAgICAgICAgICAgICAgICAgICAgIFBSRUdVTlRBUyBERSBJTlZFU1RJR0FDScOTTgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilrwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSElQw5NURVNJUwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilrwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVkFSSUFCTEVTCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKWvAogICAgICAgICAgICAgICAgICAgIElORk9STUFDScOTTiBSRVFVRVJJREEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUggogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pa8CiAgICAgICAgICAgICAgICAgICAgIERJU0XDkU8gREUgSU5WRVNUSUdBQ0nDk04KICAgICAgICAgICAgICAgICAgICAgICAvICAgICAgICAgIHwgICAgICAgICAgXAogICAgICAgICAgICAgICAgICAgICAgLyAgICAgICAgICAgfCAgICAgICAgICAgXAogICAgICAgICAgICAgRVhQTE9SQVRPUklPICAgREVTQ1JJUFRJVk8gICAgIENBVVNBTAogICAgICAgICAgICAgICAgICAgICAgXCAgICAgICAgICAgfCAgICAgICAgICAgLwogICAgICAgICAgICAgICAgICAgICAgIFwgICAgICAgICAgfCAgICAgICAgICAvCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilrwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEQVRPUwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilrwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUggogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pa8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRVZJREVOQ0lBCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKWvAogICAgICAgICAgICAgICAgICAgICAgICAgVE9NQSBERSBERUNJU0lPTkVTCmBgYAoKCiMgUmVmZXJlbmNpYSBiYXNlCgpNYWxob3RyYSwgTi4gSy4gKDIwMDgpLiAqSW52ZXN0aWdhY2nDs24gZGUgbWVyY2Fkb3MuIFVuIGVuZm9xdWUgYXBsaWNhZG8qLiBRdWludGEgZWRpY2nDs24uIFBlYXJzb24gRWR1Y2FjacOzbi4KCi0tLQo=