1 Introducción

La economía mundial ha experimentado un período de alta incertidumbre durante los últimos años, caracterizado por la recuperación posterior a la pandemia de COVID-19, episodios inflacionarios persistentes, tensiones geopolíticas y cambios en las condiciones financieras internacionales. Estos acontecimientos han generado efectos significativos sobre el crecimiento económico, el comercio internacional, los mercados laborales y la estabilidad de precios, afectando de manera diferenciada a las economías alrededor del mundo.

De acuerdo con los informes OECD Economic Outlook 2024 y OECD Employment Outlook 2024, aunque la inflación ha mostrado señales de moderación en numerosos países, continúan existiendo desafíos asociados a la desaceleración del crecimiento económico, la evolución de las tasas de interés, la recuperación de la inversión productiva y la capacidad de los mercados laborales para sostener niveles elevados de empleo. Al mismo tiempo, el comercio internacional ha enfrentado cambios importantes derivados de la reorganización de cadenas globales de suministro, las fluctuaciones de los tipos de cambio y la incertidumbre económica global.

En este contexto, resulta relevante analizar de manera conjunta indicadores que reflejen el desempeño económico de los países desde diferentes dimensiones. Variables relacionadas con el crecimiento del producto interno bruto, la inversión, el consumo, la inflación, el empleo y el sector externo permiten evaluar no solo la capacidad de expansión económica de cada país, sino también su estabilidad macroeconómica y su fortaleza frente a choques externos.

La base de datos utilizada en este estudio contiene información económica y laboral de países pertenecientes a la Organización para la Cooperación y el Desarrollo Económicos (OECD). A partir de los lineamientos establecidos en los informes de perspectivas económicas y laborales de la organización, se seleccionaron indicadores asociados a cinco dimensiones fundamentales: crecimiento económico, mercado laboral, estabilidad de precios, demanda interna y sector externo. Estas variables permiten construir una visión integral del desempeño económico de los países y constituyen una base adecuada para la aplicación de técnicas de análisis multivariado orientadas a identificar patrones, similitudes y diferencias entre las economías estudiadas.

A partir de la información, el presente trabajo busca identificar las principales características que diferencian a los países de la OECD desde una perspectiva económica y laboral analizando en conjunto de indicadores relacionados con el crecimiento económico, el mercado laboral, la inflación, la demanda interna y el sector externo, se pretende reconocer patrones de comportamiento para así reducir la complejidad de los datos y obtener una visión más clara de las similitudes y diferencias existentes entre las economías analizadas.

2 Metodología

El presente estudio se desarrolló mediante la aplicación de técnicas de análisis multivariado sobre una base de datos compuesta por indicadores económicos y laborales de países pertenecientes a la OECD. Inicialmente, se realizó un proceso de depuración de la información para garantizar la calidad de los datos utilizados en el análisis. Posteriormente, las variables fueron estandarizadas con el fin de eliminar las diferencias de escala y permitir comparaciones adecuadas entre los distintos indicadores.

Como primera etapa analítica se llevó a cabo un análisis exploratorio de los datos mediante estadísticas descriptivas y el estudio de las correlaciones entre variables, con el propósito de identificar relaciones relevantes y posibles patrones iniciales en la información. Posteriormente, se aplicó un Análisis de Componentes Principales (ACP) para reducir la dimensionalidad de la base de datos y determinar cuáles eran las dimensiones que explicaban una mayor proporción de la variabilidad observada entre los países.

A partir de los resultados obtenidos en el ACP, se implementaron diferentes técnicas de clasificación no supervisada el algoritmo K-Means y el agrupamiento jerárquico aglomerativo, con el objetivo de identificar grupos de países con características económicas similares. Finalmente, se utilizó la metodología FactoClass, la cual combina la reducción de dimensionalidad y la clasificación de individuos, permitiendo obtener una caracterización más detallada de los grupos identificados y de las variables que mejor explican sus diferencias.

2.1 Fuente de datos

La información utilizada en este trabajo proviene de una base de datos proporcionada por el docente, la cual reúne indicadores económicos y laborales de países pertenecientes a la OECD. La selección de esta base permite analizar economías con diferentes características y niveles de desempeño, facilitando la comparación entre países a partir de variables relacionadas con crecimiento económico, mercado laboral, inflación, demanda interna y sector externo.

La elección de estas dimensiones se encuentra alineada con los temas abordados en los informes OECD Economic Outlook 2024 y OECD Employment Outlook 2024, donde se destaca la importancia de estudiar de manera conjunta los factores que influyen en el crecimiento económico, la estabilidad macroeconómica y la generación de empleo. A partir de esta información, el trabajo busca identificar patrones comunes entre los países y comprender cuáles son las características que explican las diferencias observadas en su desempeño económico reciente.

2.2 Definición de las variables

Para el desarrollo del análisis se seleccionaron quince variables cuantitativas: x1 (Cuenta corriente como porcentaje del PIB), x2 (Tipo de cambio de la moneda local frente al dólar estadounidense), x8 (Exportaciones netas como contribución al PIB real), x15 (Crecimiento del volumen de exportaciones), x16 (Crecimiento del volumen de importaciones), x17 (Crecimiento del PIB en volumen), x18 (Crecimiento del PIB nominal), x19 (Crecimiento del deflactor del PIB), x20 (Crecimiento de la formación bruta de capital), x21 (Crecimiento del consumo privado), x22 (Crecimiento del consumo del gobierno), x25 (Deflactor del PIB a precios de mercado), x26 (Tasa de desempleo), x27 (Empleo total según encuesta de fuerza laboral) y x28 (Fuerza laboral).

Estas variables fueron seleccionadas porque permiten representar diferentes aspectos de la economía de cada país. Los indicadores asociados al PIB, la inversión y el consumo reflejan el comportamiento de la actividad económica y de la demanda interna, las variables relacionadas con exportaciones, importaciones, cuenta corriente y tipo de cambio permiten analizar el sector externo, los deflactores del PIB aportan información sobre la evolución de los precios mientras que las variables de empleo, desempleo y fuerza laboral describen la situación del mercado laboral. Este conjunto de indicadores proporciona una visión amplia del desempeño económico de los países analizados y constituye la base para la aplicación de las técnicas estadísticas utilizadas en el estudio.¨

2.3 Modelo

En este estudio se utilizaron técnicas de análisis multivariado con el propósito de identificar patrones económicos entre los países de la OECD y reducir la complejidad de la información contenida en las variables seleccionadas. En primer lugar, se aplicó un Análisis de Componentes Principales (ACP), cuya finalidad fue resumir la información original en un número reducido de dimensiones capaces de explicar la mayor parte de la variabilidad observada entre los países. Esta técnica permitió identificar cuáles variables tenían una mayor influencia en las diferencias económicas presentes en la base de datos y facilitó la representación gráfica de los resultados.

Posteriormente, se empleó el algoritmo K-Means para agrupar países con características económicas similares. Este método busca formar grupos internamente homogéneos y externamente diferenciados, permitiendo identificar perfiles económicos comunes entre los países analizados. La selección del número de grupos se apoyó en criterios de validación como el método del codo y el coeficiente de silueta.

Como complemento, se implementó un procedimiento de agrupamiento jerárquico aglomerativo utilizando distancia euclidiana y el método de Ward.(ESTO NO SE SI VA) Esta técnica construye una estructura de agrupación basada en la similitud entre observaciones, permitiendo visualizar las relaciones existentes entre los países mediante un dendrograma y comparar los resultados obtenidos con el algoritmo K-Means.

De esta manera, el ACP permitió reducir la dimensionalidad de los datos y facilitar su interpretación, mientras que los métodos de agrupamiento hicieron posible identificar conjuntos de países con comportamientos económicos semejantes.

3 Análisis descriptivo

library(readxl)
library(tidyverse)
library(factoextra)
library(reshape2)
library(corrplot)
library(FactoClass)
library(dendextend)
library(gt)
library(dplyr)
library(ggplot2)
library(plotly)
DatosEcon <- read_excel("DatosEcon.xlsx")
paises <- DatosEcon$Pais

variablesnombres <- c(
  "x1" = "Cuenta corriente (% PIB)",
  "x2" = "Tipo de cambio (moneda local/USD)",
  "x8" = "Exportaciones netas (contribución al PIB real)",
  "x15" = "Exportaciones (volumen, crecimiento)",
  "x16" = "Importaciones (volumen, crecimiento)",
  "x17" = "PIB (volumen, crecimiento)",
  "x18" = "PIB (nominal, crecimiento)",
  "x19" = "Deflactor del PIB (crecimiento)",
  "x20" = "Formación bruta de capital (volumen, crecimiento)",
  "x21" = "Consumo privado (volumen, crecimiento)",
  "x22" = "Consumo gobierno (volumen, crecimiento)",
  "x25" = "Deflactor del PIB (precios mercado)",
  "x26" = "Tasa de desempleo",
  "x27" = "Empleo total (encuesta fuerza laboral)",
  "x28" = "Fuerza laboral"
)

variables <- c("x26", "x27", "x28", "x17", "x21", "x22", 
               "x20", "x19", "x15", "x16", "x1", "x8", 
               "x2", "x18", "x25")

vars_porcentaje <- c("x26", "x17", "x21", "x22", "x20", "x19", "x15", "x16", "x1", "x8", "x18", "x25")
vars_miles <- c("x27", "x28", "x2")

datos_tabla <- DatosEcon %>%
  select(Pais, all_of(variables))

datos_tabla <- datos_tabla %>%
  mutate(across(all_of(vars_porcentaje), 
                ~ ifelse(is.na(.), NA, paste0(round(.x * 100, 1), "%")))) %>%
  mutate(across(all_of(vars_miles),
                ~ ifelse(is.na(.), NA, format(round(.x, 0), big.mark = ".", decimal.mark = ","))))

nombres_rename <- setNames(names(variablesnombres), variablesnombres)
datos_tabla <- datos_tabla %>% rename(!!!nombres_rename)

gt(datos_tabla) %>%
  tab_header(
    title = md("**Base de datos económicos**"),
    subtitle = "Variables seleccionadas (primeros 10 países)"
  ) %>%
  cols_label(Pais = "País") %>%
  tab_style(
    style = list(
      cell_fill(color = "#D81B60"),
      cell_text(color = "white", weight = "bold")
    ),
    locations = cells_column_labels(everything())
  ) %>%
  tab_style(
    style = list(
      cell_fill(color = "#FCE4EC"),
      cell_text(color = "black")
    ),
    locations = cells_body(rows = everything())
  ) %>%
  opt_row_striping() %>%
  tab_options(
    table.width = pct(100),
    table.font.size = "small",
    heading.title.font.size = "large",
    row.striping.background_color = "#F8BBD9",
    table.border.top.color = "#D81B60",
    table.border.bottom.color = "#D81B60",
    container.height = px(400),        # <- altura fija del contenedor
    container.overflow.y = "auto"      # <- scroll vertical automático
  ) %>%
  tab_source_note("Fuente: Datos económicos - Elaboración propia")
Base de datos económicos
Variables seleccionadas (primeros 10 países)
País Tasa de desempleo Empleo total (encuesta fuerza laboral) Fuerza laboral PIB (volumen, crecimiento) Consumo privado (volumen, crecimiento) Consumo gobierno (volumen, crecimiento) Formación bruta de capital (volumen, crecimiento) Deflactor del PIB (crecimiento) Exportaciones (volumen, crecimiento) Importaciones (volumen, crecimiento) Cuenta corriente (% PIB) Exportaciones netas (contribución al PIB real) Tipo de cambio (moneda local/USD) PIB (nominal, crecimiento) Deflactor del PIB (precios mercado)
Australia 511.6% 13.065.036 13.769.485 492.2% 503.3% 535.3% 977.4% 540.2% -206.7% 647.9% 309% -1.7% 1 1059% 105.9%
Austria 618.1% 4.305.875 4.589.575 472.6% 337% 788.8% 873.2% 194.3% 1023.5% 1365.1% 35.4% -1.4% 1 676.1% 111.1%
Belgium 625.7% 5.071.000 5.409.482 613.4% 554.7% 483.9% 486.5% 292.6% 1125.9% 1066.6% 43% 0.7% 1 923.9% 112.1%
Canada 743.1% 18.871.842 20.386.733 454.1% 488.1% 582.6% 713.6% 806.9% 139.3% 770% 4.3% -2% 1 1297.7% 119.3%
Chile 884.1% 8.304.011 9.109.354 1185.8% 2050.5% 1042.8% 1804.4% 760.9% -143.8% 3111% -650% -8.9% 1 2036.9% 120%
Colombia 1379.4% 20.391.741 23.654.636 1067.7% 1476.6% 1032.8% 1115.6% 650.2% 1482.6% 2869.9% -563.7% -3.9% 4 1787.3% 129.9%
Czech Republic 282% 5.206.152 5.357.246 348.8% 402.2% 154.1% 61.4% 333% 676.8% 1322.6% -83.6% -3.6% 22 693.4% 117.7%
Denmark 515.4% 2.797.250 2.949.250 485.7% 413.4% 416.3% 624.3% 277.1% 799.7% 797.2% 903.2% 0.5% 6 776.3% 114.9%
Estonia 617.7% 654.225 697.300 809.2% 673.3% 389.9% 695.4% 575.4% 1997.6% 2137.3% -227.5% -0.9% 1 1431.2% 120.5%
Finland 763.6% 2.552.167 2.763.167 297.2% 365.6% 291.9% 146.4% 254.8% 544.2% 596.6% 64.1% -0.2% 1 559.6% 108.7%
France 791.3% 27.727.600 30.110.100 676.6% 527% 640.2% 1139.3% 133.2% 860.7% 783.3% 35.9% 0.1% 1 818.7% 108.9%
Germany 357.5% 41.374.167 42.908.333 258.1% 39.9% 379.1% 104.6% 305.6% 953.6% 887.4% 746.4% 0.8% 1 571.6% 112.4%
Greece 1471.4% 3.928.000 4.605.675 833.6% 779% 373.9% 1961.1% 207.8% 2193.8% 1606.6% -671.1% 0.7% 1 1058.7% 101%
Hungary 404.1% 4.635.275 4.830.475 711.7% 489.9% 198.2% 515.8% 630.3% 1025.1% 909.5% -417.7% 1.1% 3 1386.9% 131%
Iceland 598.6% 195.925 208.400 440.3% 774.1% 219.7% 1229.7% 599.7% 1272.6% 2034.4% -160.4% -2.7% 1 1066.4% 121.6%
Ireland 618.9% 2.388.800 2.546.400 1342.7% 446.7% 605.8% -3907% 44% 1396.8% -828.3% 1424.4% 27.9% 1 1392.5% 100.6%
Israel 494.1% 3.957.702 4.163.427 853.9% 1108% 425.8% 1147.3% 219.7% 1449.5% 2071.3% 427.2% -0.8% 3 1092.4% 106.1%
Italy 948.2% 22.558.686 24.921.751 671.7% 514.7% 153.3% 1652.4% 54.1% 1352% 1484.3% 305.8% 0.1% 1 729.5% 106.2%
Japan 282% 67.123.333 69.070.833 164.1% 130.3% 209.6% -147.4% -86.8% 1175.6% 508.4% 397.5% 1% 11 75.9% 101%
Korea 362.6% 27.270.483 28.296.633 414.5% 370.2% 563.3% 276.4% 249.8% 1084.5% 1006.2% 485.8% 0.7% 11 674.7% 108.1%
Luxembourg 573.4% 281.550 298.677 509.8% 943.1% 545.8% 610.9% 611.9% 972.1% 1186.8% 467.6% -0.2% 1 1152.9% 116.1%
Mexico 413.4% 54.998.526 57.370.318 478.2% 749% 98.5% 948.4% 708.4% 690.7% 1362.6% -37% -2.2% 20 1220.5% 147.5%
Netherlands 422.3% 9.254.000 9.662.000 487.1% 358.4% 522% 320.5% 250.2% 526.2% 401.4% 718.5% 1.4% 1 749.5% 112.2%
New Zealand 376.8% 2.790.000 2.899.250 480.1% 620.6% 992.2% 902.1% 285.9% -358.6% 1494% -587% -4.3% 1 779.7% 128.1%
Norway 444.6% 2.772.750 2.901.750 388.1% 487.3% 376.2% -92.6% 1691.1% 470.9% 228.1% 1491.3% 0.8% 9 2144.9% 112.7%
Poland 336.2% 16.656.000 17.235.500 684.8% 627.8% 496% 205% 505.2% 1245.2% 1612.6% -146.3% -1% 4 1224.6% 116.3%
Portugal 657.7% 4.812.300 5.151.075 548.2% 465.4% 457.6% 868.4% 139.9% 1345.6% 1331.8% -117.1% -0.2% 1 695.8% 108.8%
Slovak Republic 682.6% 2.560.550 2.748.150 301.4% 182% 415.5% 21.6% 238.3% 1056% 1196% -250.2% -0.9% 1 546.9% 110.4%
Slovenia 475.5% 971.500 1.020.000 821.1% 950.6% 577.3% 1368.6% 260.7% 1450% 1758.5% 380.3% -0.8% 1 1103.2% 116.2%
Spain 1478.1% 19.773.600 23.203.150 552% 597.2% 285.8% 92% 230.1% 1437.8% 1392.4% 95.5% 0.3% 1 794.8% 108.1%
Sweden 880.1% 5.057.750 5.545.858 483% 588% 251.3% 598.8% 304.2% 756.5% 926% 536.4% -0.3% 9 801.9% 100%
Switzerland 508.9% 4.684.277 4.935.422 423% 169.3% 346.8% 414.6% 105.7% 1218.3% 487.9% 740.1% 5% 1 533.2% 100%
Türkiye 1202.3% 28.758.583 32.688.917 1135.3% 1572.2% 265.6% 739.9% 2895.1% 2489.4% 238.3% -169.8% 6.4% 9 4359.1% 360.7%
United Kingdom 449.2% 32.406.750 33.931.000 752.5% 623.1% 1263.1% 556.2% 36.9% -30.1% 278.1% -200.4% -0.9% 1 792.2% 106.3%
United States 535.1% 152.578.500 161.204.000 594.7% 829.4% 130.9% 571.9% 449.2% 605.4% 1413.4% -363% -1.2% 1 1070.5% 118.9%
Argentina 927.7% 121.937.875 133.194.875 1039.8% 1002.5% 709.7% 3342.5% 5415.2% 921.8% 2202% 137.3% -1.5% 95 7018.2% 6715.2%
Brazil 1320.4% 91.297.250 105.185.750 494.8% 360.8% 200.1% 1730.7% 1074.9% 642.3% 1302.4% -176.5% -1% 5 1622.8% 468.7%
Croatia 761.1% 1.678.250 1.816.500 980.4% 992.4% 318.3% 747.8% 308% 2782.3% 1442.4% 42% 5% 6 1318.6% 108.4%
India 674.1% 9.295.687 9.892.225 868.1% 791% 257.1% 1580.1% 996.6% 2432.4% 3546.5% -119.7% -2.9% 74 1951.3% 160.6%
Peru 587.1% 16.913.125 17.967.950 1324% 1144% 640.1% 3531.8% 841.4% 1704% 2501.4% -238.9% -2.3% 4 2276.8% 156.9%
Romania 559.6% 7.746.200 8.205.395 510% 707.5% 40.6% 291.1% 541.7% 1253.2% 1462.7% -728.2% -1.4% 4 1079.3% 153.7%
SouthAfrica 3426.7% 14.690.764 22.348.983 491.3% 558.7% 55.8% 22.2% 621.9% 998.7% 949.4% 367.7% 0.1% 15 1143.8% 137.5%
Fuente: Datos económicos - Elaboración propia
datos_pca <- as.data.frame(na.omit(DatosEcon[, variables]))
datos_scaled <- as.data.frame(scale(datos_pca))

3.1 Clasificación dimensiones

3.1.1 Dimensión de Mercado Laboral

tabla_laboral <- data.frame(
  Código = c("x26", "x27", "x28"),
  Variable = c(variablesnombres["x26"], variablesnombres["x27"], variablesnombres["x28"]),
  Descripcion = c(
    "Indicador principal del mercado laboral. Según OECD Employment Outlook 2024, tasas bajas reflejan resiliencia y mercados ajustados.",
    "Refleja la capacidad de generación de puestos de trabajo formales e informales. Base para políticas de empleo.",
    "
    Determina el tamaño de la oferta laboral y la tasa de participación."
  )
)

gt(tabla_laboral) %>%
  tab_header(
    title = "Dimensión 1: Mercado Laboral",
    subtitle = "OECD Employment Outlook 2024"
  ) %>%

  tab_style(
    style = list(
      cell_fill(color = "#D81B60"),
      cell_text(color = "white", weight = "bold")
    ),
    locations = cells_column_labels(everything())
  ) %>%

  tab_style(
    style = cell_fill(color = "white"),
    locations = cells_body(rows = 1)
  ) %>%

  tab_style(
    style = cell_fill(color = "#FCE4EC"),
    locations = cells_body(rows = 2)
  ) %>%

  tab_style(
    style = cell_fill(color = "#F8BBD9"),
    locations = cells_body(rows = 3)
  ) %>%

  tab_options(
    table.width = pct(100),
    table.font.size = "small",
    heading.background.color = "#F48FB1"
  ) %>%

  tab_source_note(
    source_note = "Nota: Interpretaciones basadas en OECD Economic Outlook y Employment Outlook 2024."
  )
Dimensión 1: Mercado Laboral
OECD Employment Outlook 2024
Código Variable Descripcion
x26 Tasa de desempleo Indicador principal del mercado laboral. Según OECD Employment Outlook 2024, tasas bajas reflejan resiliencia y mercados ajustados.
x27 Empleo total (encuesta fuerza laboral) Refleja la capacidad de generación de puestos de trabajo formales e informales. Base para políticas de empleo.
x28 Fuerza laboral Determina el tamaño de la oferta laboral y la tasa de participación.
Nota: Interpretaciones basadas en OECD Economic Outlook y Employment Outlook 2024.
Según la OECD Employment Outlook 2024, la tasa de desempleo, el empleo total y la fuerza laboral constituyen indicadores fundamentales para evaluar el desempeño del mercado laboral. Estas variables permiten analizar la capacidad de las economías para generar empleo, el nivel de participación de la población en actividades productivas y las condiciones generales de inserción laboral. El comportamiento del mercado de trabajo se encuentra estrechamente relacionado con el crecimiento económico, la productividad y el bienestar de la población.

3.1.2 Dimensión de Crecimiento Económico

tabla_crecimiento <- data.frame(
  Código = c("x17", "x18", "x8"),
  Variable = c(variablesnombres["x17"], variablesnombres["x18"], variablesnombres["x8"]),
  Descripcion = c(
    "Mide la expansión real de la economía. OECD Economic Outlook 2024: crecimiento global estable (3.3% en 2025-2026).",
    "Crecimiento en precios corrientes. Refleja la evolución nominal del PIB, incluyendo efectos de precios.",
    "Contribución del sector externo al crecimiento. Exportaciones netas como porcentaje del PIB real.")) 

tabla_crecimiento[] <- lapply(
  tabla_crecimiento,
  function(x) if (is.character(x)) iconv(x, from = "", to = "UTF-8", sub = "") else x)

gt(tabla_crecimiento) %>%
  tab_header(
    title = "Dimensión 2: Crecimiento Económico",
    subtitle = "OECD Economic Outlook 2024"
  ) %>%
  tab_style(
    style = list(
      cell_fill(color = "#D81B60"),
      cell_text(color = "white", weight = "bold")
    ),
    locations = cells_column_labels(everything())
  ) %>%
  tab_style(
    style = cell_fill(color = "white"),
    locations = cells_body(rows = 1)
  ) %>%
  tab_style(
    style = cell_fill(color = "#FCE4EC"),
    locations = cells_body(rows = 2)
  ) %>%
  tab_style(
    style = cell_fill(color = "#F8BBD9"),
    locations = cells_body(rows = 3)
  ) %>%
  tab_options(
    table.width = pct(100),
    table.font.size = "small",
    heading.background.color = "#F48FB1"
  ) %>%
  tab_source_note(
    source_note = "Nota: Interpretaciones basadas en OECD Economic Outlook y Employment Outlook 2024."
  )
Dimensión 2: Crecimiento Económico
OECD Economic Outlook 2024
Código Variable Descripcion
x17 PIB (volumen, crecimiento) Mide la expansión real de la economía. OECD Economic Outlook 2024: crecimiento global estable (3.3% en 2025-2026).
x18 PIB (nominal, crecimiento) Crecimiento en precios corrientes. Refleja la evolución nominal del PIB, incluyendo efectos de precios.
x8 Exportaciones netas (contribución al PIB real) Contribución del sector externo al crecimiento. Exportaciones netas como porcentaje del PIB real.
Nota: Interpretaciones basadas en OECD Economic Outlook y Employment Outlook 2024.
De acuerdo con la OECD Economic Outlook 2024, el crecimiento del PIB real y del PIB nominal son indicadores fundamentales para evaluar el desempeño económico de los países. Mientras que el crecimiento real permite analizar la evolución de la producción descontando el efecto de los precios, el crecimiento nominal incorpora tanto los cambios en la producción como las variaciones de precios identificando diferencias en el ritmo de expansión económica entre los países analizados y comprender una de las dimensiones más relevantes para explicar las disparidades observadas en su desempeño económico.

3.1.3 Dimensión de Precios e Inflación

tabla_precios <- data.frame(
  Código = c("x19", "x25", "x2"),
  Variable = c(variablesnombres["x19"], variablesnombres["x25"], variablesnombres["x2"]),
  Descripcion = c(
    "Variación anual del deflactor del PIB. Indicador amplio de inflación. OECD: inflación en descenso (5.4% en 2024 a 3.3% en 2025).",
    "Deflactor del PIB a precios de mercado. Refleja los cambios en los precios de todos los bienes y servicios producidos.",
    "Precio de la moneda local frente al dólar. Afecta la competitividad y la inflación importada."
  )
)

gt(tabla_precios) %>%
  tab_header(
    title = "Dimensión 3: Precios e Inflación",
    subtitle = "OECD Economic Outlook 2024"
  ) %>%
  tab_style(
    style = list(
      cell_fill(color = "#D81B60"),
      cell_text(color = "white", weight = "bold")
    ),
    locations = cells_column_labels(everything())
  ) %>%
  tab_style(
    style = cell_fill(color = "white"),
    locations = cells_body(rows = 1)
  ) %>%
  tab_style(
    style = cell_fill(color = "#FCE4EC"),
    locations = cells_body(rows = 2)
  ) %>%
  tab_style(
    style = cell_fill(color = "#F8BBD9"),
    locations = cells_body(rows = 3)
  ) %>%
  tab_options(
    table.width = pct(100),
    table.font.size = "small",
    heading.background.color = "#F48FB1"
  ) %>%
  tab_source_note(
    source_note = "Nota: Interpretaciones basadas en OECD Economic Outlook y Employment Outlook 2024."
  )
Dimensión 3: Precios e Inflación
OECD Economic Outlook 2024
Código Variable Descripcion
x19 Deflactor del PIB (crecimiento) Variación anual del deflactor del PIB. Indicador amplio de inflación. OECD: inflación en descenso (5.4% en 2024 a 3.3% en 2025).
x25 Deflactor del PIB (precios mercado) Deflactor del PIB a precios de mercado. Refleja los cambios en los precios de todos los bienes y servicios producidos.
x2 Tipo de cambio (moneda local/USD) Precio de la moneda local frente al dólar. Afecta la competitividad y la inflación importada.
Nota: Interpretaciones basadas en OECD Economic Outlook y Employment Outlook 2024.
El crecimiento del deflactor del PIB, el deflactor del PIB a precios de mercado y el tipo de cambio son indicadores relevantes para analizar la estabilidad macroeconómica y la evolución de los precios dentro de una economía según La OECD Economic Outlook 2024. Estas variables permiten evaluar las presiones inflacionarias, los cambios en los niveles generales de precios y las variaciones en el valor de la moneda frente al dólar estadounidense, factores que influyen directamente sobre el poder adquisitivo, la competitividad internacional y las condiciones de crecimiento económico.

3.1.4 Dimensión de Demanda Interna

tabla_demanda <- data.frame(
  Código = c("x21", "x22", "x20"),
  Variable = c(variablesnombres["x21"], variablesnombres["x22"], variablesnombres["x20"]),
  Descripcion = c(
    "Consumo de los hogares. Motor principal del crecimiento. OECD 2024: respaldado por ingresos reales y mercado laboral resiliente.",
    "Consumo del gobierno. Gasto público en bienes y servicios. Política fiscal y provisión de servicios públicos.",
    "Formación bruta de capital (inversión). Refleja la acumulación de activos fijos. Clave para la capacidad productiva futura."))

tabla_demanda[] <- lapply(
  tabla_crecimiento,
  function(x) if (is.character(x)) iconv(x, from = "", to = "UTF-8", sub = "") else x)

gt(tabla_demanda) %>%
  tab_header(
    title = "Dimensión 4: Demanda Interna",
    subtitle = "OECD Economic Outlook 2024"
  ) %>%
  tab_style(
    style = list(
      cell_fill(color = "#D81B60"),
      cell_text(color = "white", weight = "bold")
    ),
    locations = cells_column_labels(everything())
  ) %>%
  tab_style(
    style = cell_fill(color = "white"),
    locations = cells_body(rows = 1)
  ) %>%
  tab_style(
    style = cell_fill(color = "#FCE4EC"),
    locations = cells_body(rows = 2)
  ) %>%
  tab_style(
    style = cell_fill(color = "#F8BBD9"),
    locations = cells_body(rows = 3)
  ) %>%
  tab_options(
    table.width = pct(100),
    table.font.size = "small",
    heading.background.color = "#F48FB1"
  ) %>%
  tab_source_note(
    source_note = "Nota: Interpretaciones basadas en OECD Economic Outlook y Employment Outlook 2024."
  )
Dimensión 4: Demanda Interna
OECD Economic Outlook 2024
Código Variable Descripcion
x17 PIB (volumen, crecimiento) Mide la expansión real de la economía. OECD Economic Outlook 2024: crecimiento global estable (3.3% en 2025-2026).
x18 PIB (nominal, crecimiento) Crecimiento en precios corrientes. Refleja la evolución nominal del PIB, incluyendo efectos de precios.
x8 Exportaciones netas (contribución al PIB real) Contribución del sector externo al crecimiento. Exportaciones netas como porcentaje del PIB real.
Nota: Interpretaciones basadas en OECD Economic Outlook y Employment Outlook 2024.
La formación bruta de capital fijo, el consumo privado y el consumo público representan algunos de los principales componentes de la demanda interna de una economía. Estas variables permiten analizar la capacidad de inversión, el comportamiento del gasto de los hogares y la participación del sector público en la actividad económica, factores que influyen directamente sobre el crecimiento y la dinámica productiva de los países. Según la OECD Economic Outlook 2024, tanto la inversión como el consumo continúan siendo elementos fundamentales para sostener el crecimiento económico en el mediano plazo

3.1.5 Dimensión de Comercio exterior

tabla_comercio <- data.frame(
  Código = c("x15", "x16", "x1"),
  Variable = c(variablesnombres["x15"], variablesnombres["x16"], variablesnombres["x1"]),
  Descripcion = c(
    "Crecimiento del volumen de exportaciones. Mide la demanda externa de bienes nacionales. OECD: recuperación del comercio global más rápida de lo esperado.",
    "Crecimiento del volumen de importaciones. Refleja la demanda interna de bienes extranjeros y la integración global.",
    "Saldo de la balanza por cuenta corriente (% PIB). Indica si el país es prestamista o deudor neto con el resto del mundo."
  )
)

gt(tabla_comercio) %>%
  tab_header(
    title = "Dimensión 5: Comercio Exterior",
    subtitle = "OECD Economic Outlook 2024"
  ) %>%
  tab_style(
    style = list(
      cell_fill(color = "#D81B60"),
      cell_text(color = "white", weight = "bold")
    ),
    locations = cells_column_labels(everything())
  ) %>%
  tab_style(
    style = cell_fill(color = "white"),
    locations = cells_body(rows = 1)
  ) %>%
  tab_style(
    style = cell_fill(color = "#FCE4EC"),
    locations = cells_body(rows = 2)
  ) %>%
  tab_style(
    style = cell_fill(color = "#F8BBD9"),
    locations = cells_body(rows = 3)
  ) %>%
  tab_options(
    table.width = pct(100),
    table.font.size = "small",
    heading.background.color = "#F48FB1"
  ) %>%
  tab_source_note(
    source_note = "Nota: Interpretaciones basadas en OECD Economic Outlook y Employment Outlook 2024."
  )
Dimensión 5: Comercio Exterior
OECD Economic Outlook 2024
Código Variable Descripcion
x15 Exportaciones (volumen, crecimiento) Crecimiento del volumen de exportaciones. Mide la demanda externa de bienes nacionales. OECD: recuperación del comercio global más rápida de lo esperado.
x16 Importaciones (volumen, crecimiento) Crecimiento del volumen de importaciones. Refleja la demanda interna de bienes extranjeros y la integración global.
x1 Cuenta corriente (% PIB) Saldo de la balanza por cuenta corriente (% PIB). Indica si el país es prestamista o deudor neto con el resto del mundo.
Nota: Interpretaciones basadas en OECD Economic Outlook y Employment Outlook 2024.
Las exportaciones, las importaciones, el saldo de cuenta corriente como porcentaje del PIB y la contribución de las exportaciones netas al PIB real permiten analizar la relación de cada economía con el sector externo y su participación en el comercio internacional. Estos indicadores proporcionan información sobre el grado de apertura comercial, la capacidad de financiamiento frente al resto del mundo y el aporte del comercio exterior al crecimiento económico. Los informes de la OECD destacan que, en un contexto de cambios en las cadenas globales de suministro y de elevada incertidumbre económica internacional, el comportamiento del sector externo es variable.

3.2 Matriz de correlación

nombres_cor <- c(
  "x1" = "Cta. cte. (% PIB)",
  "x2" = "Tipo cambio (mon./USD)",
  "x8" = "Exp. netas (cont. PIB real)",
  "x15" = "Exp. (vol, cr)",
  "x16" = "Imp. (vol, cr)",
  "x17" = "PIB (vol, cr)",
  "x18" = "PIB (nom, cr)",
  "x19" = "Defl. PIB (cr)",
  "x20" = "FBC (vol, cr)",
  "x21" = "Cons. priv. (vol, cr)",
  "x22" = "Cons. gob. (vol, cr)",
  "x25" = "Defl. PIB (prec. mdo)",
  "x26" = "Tasa desempleo",
  "x27" = "Empleo total",
  "x28" = "Fuerza laboral"
)

datos_cor <- datos_pca
names(datos_cor) <- nombres_cor[names(datos_pca)]

cor_matrix <- cor(datos_cor, use = "complete.obs")

# Paleta
mi_paleta <- colorRampPalette(c("white", "#FCE4EC", "#F8BBD9", "#F48FB1", "#D81B60"))(200)

corrplot(cor_matrix,
         method = "color",
         type = "upper",
         order = "hclust",
         col = mi_paleta,
         addCoef.col = "black",
         tl.col = "black",
         tl.srt = 45,
         tl.cex = 0.9,    
         number.cex = 0.7,
         mar = c(0, 0, 2, 0))

title(main = "Matriz de Correlación",
      cex.main = 1.5, font.main = 2, col.main = "#D81B60")

En general, las correlaciones más altas se observan entre variables pertenecientes a una misma dimensión económica, lo que sugiere que estas capturan fenómenos similares y justifica la aplicación posterior de técnicas de reducción de dimensionalidad.

En el mercado laboral se observa una correlación muy alta entre el empleo total y la fuerza laboral. Este resultado era esperado, ya que ambas variables reflejan el tamaño del mercado de trabajo de cada país y tienden a evolucionar en la misma dirección a pesar de esta asociación, se decidió conservar ambas variables debido a que aportan información complementaria sobre las condiciones laborales de las economías analizadas.

Las asociaciones más fuertes se presentan en la dimensión de precios e inflación. El crecimiento del deflactor del PIB muestra una correlación de 0.97 con el crecimiento nominal del PIB, mientras que el deflactor del PIB a precios de mercado presenta correlaciones de 0.85 y 0.82 con estas variables sugiriendo que una parte importante de las diferencias observadas en el crecimiento nominal entre países está asociada a la evolución de los precios y que el tipo de cambio presenta correlaciones positivas cercanas a 0.70 con los indicadores inflacionarios, reflejando la relación existente entre las variaciones cambiarias y el comportamiento de los precios

En cuanto a la actividad económica, el crecimiento del PIB real registra una correlación de 0.74 con el crecimiento del consumo privado, lo que resalta la importancia de la demanda de los hogares como motor del crecimiento. Asimismo, la formación bruta de capital fijo presenta una correlación de 0.68 con el crecimiento de las importaciones, sugiriendo que los procesos de inversión suelen estar acompañados por una mayor demanda de bienes provenientes del exterior.

Finalmente, se observa una correlación positiva entre el saldo de cuenta corriente y la contribución de las exportaciones netas al PIB, lo que evidencia la importancia del sector externo en la diferenciación económica de los países analizados.

3.3 ACP - Porcentaje Varianza

res.pca <- prcomp(datos_pca, scale = TRUE)

fviz_eig(res.pca, addlabels = TRUE,
         barfill = "#FCE4EC",      
         barcolor = "#D81B60",     
         linecolor = "#D81B60",
         xlab = "Componentes",
         ylab = "Porcentaje de varianza explicada")+
  theme_minimal() +
  theme(plot.title = element_text(color = "#D81B60", face = "bold"))

Los resultados sugieren que las diferencias económicas entre los países pueden resumirse en un número reducido de dimensiones, ya que las tres primeras componentes concentran cerca de dos terceras partes de la información original. Esto indica la existencia de factores comunes que explican gran parte de la variabilidad observada, permitiendo simplificar el análisis sin perder una proporción importante de información.
eigen_tabla <- get_eigenvalue(res.pca)

eigen_df <- as.data.frame(eigen_tabla) %>%
  mutate(
    variance.percent = variance.percent * 1,
    cumulative.variance.percent = cumulative.variance.percent * 1
  )

eigen_df %>%
  gt() %>%
  tab_header(
    title = md("**Valores propios del análisis de componentes principales**"),
    subtitle = "Varianza explicada por cada componente"
  ) %>%
  cols_label(
    eigenvalue = "Valor propio",
    variance.percent = "Varianza (%)",
    cumulative.variance.percent = "Varianza acumulada (%)"
  ) %>%
  fmt_number(
    columns = c(eigenvalue, variance.percent, cumulative.variance.percent),
    decimals = 2
  ) %>%
  tab_style(
    style = list(
      cell_fill(color = "#D81B60"),
      cell_text(color = "white", weight = "bold")
    ),
    locations = cells_column_labels(everything())
  ) %>%
  tab_style(
    style = list(
      cell_fill(color = "#FCE4EC"),
      cell_text(color = "black")
    ),
    locations = cells_body(rows = everything())
  ) %>%
  opt_row_striping() %>%
  tab_options(
    table.width = pct(100),
    table.font.size = "small",
    heading.title.font.size = "large",
    row.striping.background_color = "#F8BBD9",
    table.border.top.color = "#D81B60",
    table.border.bottom.color = "#D81B60",
    container.height = px(400),
    container.overflow.y = "auto"
  ) %>%
  tab_source_note("Fuente: Resultados del PCA - Elaboración propia")
Valores propios del análisis de componentes principales
Varianza explicada por cada componente
Valor propio Varianza (%) Varianza acumulada (%)
5.00 33.36 33.36
2.71 18.08 51.45
2.16 14.43 65.87
1.49 9.90 75.78
1.12 7.46 83.24
0.88 5.86 89.10
0.46 3.09 92.19
0.42 2.82 95.01
0.36 2.42 97.44
0.17 1.10 98.54
0.12 0.82 99.36
0.07 0.47 99.83
0.02 0.16 100.00
0.00 0.00 100.00
0.00 0.00 100.00
Fuente: Resultados del PCA - Elaboración propia

3.4 Participación variables en dimensiones

3.4.1 Inestabilidad nominal y presión inflacionaria

loadings <- res.pca$rotation
cos2 <- loadings^2

pc1_loadings <- loadings[, 1]
pc1_cos2 <- cos2[, 1]

# === CAMBIO 1: iconv en lugar de enc2utf8 ===
tabla_pc1 <- data.frame(
  Variable = iconv(variablesnombres[rownames(loadings)], to = "UTF-8", sub = " "),
  Loading = pc1_loadings,
  Cos2 = pc1_cos2
)

# Ordenar
tabla_pc1 <- tabla_pc1[order(-tabla_pc1$Cos2), ]

gt(tabla_pc1) %>%
  tab_header(
    # === CAMBIO 2: enc2utf8 en el título ===
    title = enc2utf8(paste0("Contribución de Variables al Componente Principal 1 (", 
                   round(summary(res.pca)$importance[2, 1] * 100, 1), "% de varianza)")),
    subtitle = "Cargas (loadings) y coseno al cuadrado (cos²)"  # este no suele dar problema, pero si falla, ponle enc2utf8 también
  ) %>%
  cols_label(
    Variable = "Variable",
    Loading = "Loading",
    Cos2 = "Cos²"
  ) %>%
  fmt_number(columns = c(Loading, Cos2), decimals = 4) %>%
  tab_style(
    style = list(cell_fill(color = "#D81B60"), cell_text(color = "white", weight = "bold")),
    locations = cells_column_labels(everything())
  ) %>%
  tab_style(
    style = cell_fill(color = "#FFD700"),
    locations = cells_body(rows = 1:3)
  ) %>%
  tab_style(
    style = cell_fill(color = "#FCE4EC"),
    locations = cells_body(rows = seq(4, nrow(tabla_pc1), 2))
  ) %>%
  tab_style(
    style = cell_fill(color = "#F8BBD9"),
    locations = cells_body(rows = seq(5, nrow(tabla_pc1), 2))
  ) %>%
  tab_options(
    table.width = pct(100),
    table.font.size = "small",
    heading.background.color = "#F48FB1"
  ) %>%
  tab_source_note(
    source_note = "Nota: Las filas en dorado corresponden a las 3 variables con mayor contribución al PC1."
  )
Contribución de Variables al Componente Principal 1 (33.4% de varianza)
Cargas (loadings) y coseno al cuadrado (cos²)
Variable Loading Cos²
PIB (nominal, crecimiento) 0.3949 0.1559
Deflactor del PIB (crecimiento) 0.3807 0.1449
Deflactor del PIB (precios mercado) 0.3569 0.1273
Tipo de cambio (moneda local/USD) 0.3264 0.1065
Formación bruta de capital (volumen, crecimiento) 0.3074 0.0945
Consumo privado (volumen, crecimiento) 0.2610 0.0681
Importaciones (volumen, crecimiento) 0.2547 0.0649
Fuerza laboral 0.2516 0.0633
Empleo total (encuesta fuerza laboral) 0.2463 0.0606
PIB (volumen, crecimiento) 0.2212 0.0489
Cuenta corriente (% PIB) −0.1649 0.0272
Exportaciones netas (contribución al PIB real) −0.1448 0.0210
Tasa de desempleo 0.0868 0.0075
Consumo gobierno (volumen, crecimiento) 0.0714 0.0051
Exportaciones (volumen, crecimiento) 0.0643 0.0041
Nota: Las filas en dorado corresponden a las 3 variables con mayor contribución al PC1.
El primer componente está dominado por el crecimiento nominal del PIB, el crecimiento del deflactor del PIB, el deflactor a precios de mercado, sugiriendo que la principal fuente de diferenciación entre los países está asociada a factores nominales, especialmente a la inflación y comportamiento cambiario. Los países con valores altos en esta componente tienden a presentar mayores aumentos de precios y mayor dinamismo nominal en su economía.

3.4.2 Dinamismo de la demanda interna y sector externo

# Para el PC2
pc2_loadings <- loadings[, 2]
pc2_cos2 <- cos2[, 2]

tabla_pc2 <- data.frame(
  Variable = enc2utf8(variablesnombres[rownames(loadings)]),
  Loading = pc2_loadings,
  Cos2 = pc2_cos2
)

# Ordenar de mayor a menor cos²
tabla_pc2 <- tabla_pc2[order(-tabla_pc2$Cos2), ]

gt(tabla_pc2) %>%
  tab_header(
    title = paste0("Contribución de Variables al Componente Principal 2 (", 
                   round(summary(res.pca)$importance[2, 2] * 100, 1), "% de varianza)"),
    subtitle = "Cargas (loadings) y coseno al cuadrado (cos²)"
  ) %>%
  cols_label(
    Variable = "Variable",
    Loading = "Loading",
    Cos2 = "Cos²"
  ) %>%
  fmt_number(columns = c(Loading, Cos2), decimals = 4) %>%
  tab_style(
    style = list(cell_fill(color = "#D81B60"), cell_text(color = "white", weight = "bold")),
    locations = cells_column_labels(everything())
  ) %>%
  tab_style(
    style = cell_fill(color = "#FFD700"),
    locations = cells_body(rows = 1:3)
  ) %>%
  tab_style(
    style = cell_fill(color = "#FCE4EC"),
    locations = cells_body(rows = seq(4, nrow(tabla_pc2), 2))
  ) %>%
  tab_style(
    style = cell_fill(color = "#F8BBD9"),
    locations = cells_body(rows = seq(5, nrow(tabla_pc2), 2))
  ) %>%
  tab_options(
    table.width = pct(100),
    table.font.size = "small",
    heading.background.color = "#F48FB1"
  ) %>%
  tab_source_note(
    source_note = "Nota: Las filas en dorado corresponden a las 3 variables con mayor contribución al PC2."
  )
Contribución de Variables al Componente Principal 2 (18.1% de varianza)
Cargas (loadings) y coseno al cuadrado (cos²)
Variable Loading Cos²
Importaciones (volumen, crecimiento) 0.3980 0.1584
Cuenta corriente (% PIB) −0.3748 0.1405
Exportaciones netas (contribución al PIB real) −0.3267 0.1067
Consumo privado (volumen, crecimiento) 0.3261 0.1063
Empleo total (encuesta fuerza laboral) −0.3076 0.0946
Fuerza laboral −0.3074 0.0945
Formación bruta de capital (volumen, crecimiento) 0.2566 0.0658
Deflactor del PIB (precios mercado) −0.2546 0.0648
Deflactor del PIB (crecimiento) −0.2044 0.0418
Consumo gobierno (volumen, crecimiento) 0.1919 0.0368
Tipo de cambio (moneda local/USD) −0.1826 0.0333
PIB (volumen, crecimiento) 0.1718 0.0295
PIB (nominal, crecimiento) −0.1343 0.0180
Exportaciones (volumen, crecimiento) 0.0896 0.0080
Tasa de desempleo 0.0286 0.0008
Nota: Las filas en dorado corresponden a las 3 variables con mayor contribución al PC2.
Determinada principalmente por el crecimiento de las importaciones, la cuenta corriente y la contribución de las exportaciones netas al PIB. Esta dimensión refleja el grado de apertura y dependencia del sector externo, diferenciando economías más orientadas al comercio internacional de aquellas con una posición externa más débil.

3.4.3 Crecimiento real impulsado por el sector externo

# Para el PC3
pc3_loadings <- loadings[, 3]
pc3_cos2 <- cos2[, 3]

tabla_pc3 <- data.frame(
  Variable = enc2utf8(variablesnombres[rownames(loadings)]),
  Loading = pc3_loadings,
  Cos2 = pc3_cos2
)

# Ordenar de mayor a menor cos²
tabla_pc3 <- tabla_pc3[order(-tabla_pc3$Cos2), ]

gt(tabla_pc3) %>%
  tab_header(
    title = paste0("Contribución de Variables al Componente Principal 3 (", 
                   round(summary(res.pca)$importance[2, 3] * 100, 1), "% de varianza)"),
    subtitle = "Cargas (loadings) y coseno al cuadrado (cos²)"
  ) %>%
  cols_label(
    Variable = "Variable",
    Loading = "Loading",
    Cos2 = "Cos²"
  ) %>%
  fmt_number(columns = c(Loading, Cos2), decimals = 4) %>%
  tab_style(
    style = list(cell_fill(color = "#D81B60"), cell_text(color = "white", weight = "bold")),
    locations = cells_column_labels(everything())
  ) %>%
  tab_style(
    style = cell_fill(color = "#FFD700"),
    locations = cells_body(rows = 1:3)
  ) %>%
  tab_style(
    style = cell_fill(color = "#FCE4EC"),
    locations = cells_body(rows = seq(4, nrow(tabla_pc3), 2))
  ) %>%
  tab_style(
    style = cell_fill(color = "#F8BBD9"),
    locations = cells_body(rows = seq(5, nrow(tabla_pc3), 2))
  ) %>%
  tab_options(
    table.width = pct(100),
    table.font.size = "small",
    heading.background.color = "#F48FB1"
  ) %>%
  tab_source_note(
    source_note = "Nota: Las filas en dorado corresponden a las 3 variables con mayor contribución al PC3."
  )
Contribución de Variables al Componente Principal 3 (14.4% de varianza)
Cargas (loadings) y coseno al cuadrado (cos²)
Variable Loading Cos²
Exportaciones netas (contribución al PIB real) 0.4832 0.2335
PIB (volumen, crecimiento) 0.4720 0.2227
Exportaciones (volumen, crecimiento) 0.4073 0.1659
Empleo total (encuesta fuerza laboral) −0.2835 0.0804
Fuerza laboral −0.2774 0.0769
Consumo privado (volumen, crecimiento) 0.2284 0.0522
Formación bruta de capital (volumen, crecimiento) −0.2175 0.0473
PIB (nominal, crecimiento) 0.2089 0.0436
Cuenta corriente (% PIB) 0.2021 0.0408
Tasa de desempleo 0.1259 0.0158
Deflactor del PIB (crecimiento) 0.0961 0.0092
Importaciones (volumen, crecimiento) −0.0905 0.0082
Consumo gobierno (volumen, crecimiento) 0.0527 0.0028
Tipo de cambio (moneda local/USD) 0.0229 0.0005
Deflactor del PIB (precios mercado) 0.0038 0.0000
Nota: Las filas en dorado corresponden a las 3 variables con mayor contribución al PC3.

Explica principalmente las exportaciones netas, el crecimiento del PIB real y el crecimiento de las exportaciones, capturarndo el vínculo entre crecimiento económico y desempeño exportador, identificando países donde la expansión de la actividad económica está más asociada al dinamismo del sector externo.

A partir del ACP se identificaron tres dimensiones principales que explican cerca del 66% de la variabilidad total de los datos. La primera dimensión, denominada “Inestabilidad nominal y presión inflacionaria”, recoge principalmente información relacionada con el crecimiento nominal del PIB, los deflactores del PIB y el tipo de cambio. Por esta razón, esta dimensión permite diferenciar países con mayores presiones inflacionarias y variaciones nominales de aquellos que presentan una situación más estable en términos de precios.

La segunda dimensión, llamada “Dinamismo de la demanda interna y sector externo”, combina variables asociadas al consumo privado, las importaciones, la cuenta corriente y la contribución de las exportaciones netas al PIB. En este caso, la dimensión parece reflejar la forma en que cada economía combina el comportamiento de su demanda interna con su relación comercial frente al resto del mundo.

Por su parte, la tercera dimensión, denominada “Crecimiento real impulsado por el sector externo”, está explicada principalmente por el crecimiento real del PIB, las exportaciones y la contribución de las exportaciones netas al crecimiento económico. Esto sugiere que algunos países logran una parte importante de su expansión económica a través del desempeño de su sector exportador.
scores_pca <- as.data.frame(res.pca$x[, 1:3])

3.5 Comparativa entre dimensiones

3.5.1 Gráfico individuos Dimensión 1 y 2

ind_coord <- as.data.frame(res.pca$x[, 1:2])
colnames(ind_coord) <- c("PC1", "PC2")
ind_info <- get_pca_ind(res.pca)
ind_coord$cos2 <- ind_info$cos2[, 1]
ind_coord$label <- DatosEcon$Pais  # <-- nombres reales de los paises
plot_ly(
  data = ind_coord,
  x = ~PC1,   
  y = ~PC2,   
  type = 'scatter',
  mode = 'markers',
  marker = list(
    size = 8,
    color = ~cos2,
    colorscale = list(
      c(0, "#FCE4EC"),   
      c(0.5, "#F8BBD9"), 
      c(1, "#D81B60")   
    ),
    showscale = TRUE,
    colorbar = list(title = "cos2")
  ),
  text = ~label,
  hoverinfo = 'text',
  hovertemplate = paste('<b>%{text}</b><br>PC1: %{x:.2f}<br>PC2: %{y:.2f}<br>cos2: %{marker.color:.2f}<extra></extra>')
) %>%
  layout(
    title = "Grafico de individuos Dimension 1 VS 2",
    xaxis = list(title = paste0("Dimension 1 (", round(summary(res.pca)$importance[2,1]*100,1), "%)")),
    yaxis = list(title = paste0("Dimension 2 (", round(summary(res.pca)$importance[2,2]*100,1), "%)"))
  ) %>%
  config(displayModeBar = FALSE)

El gráfico de individuos se encuentra que la mayoría de los países se concentra alrededor del centro del plano factorial, indicando que, aunque existen diferencias entre ellos, gran parte de las economías analizadas comparten características relativamente similares cuando se consideran de manera conjunta las variables económicas y laborales incluidas en el estudio. Este resultado era esperable debido a que la muestra está compuesta principalmente por países pertenecientes a la OECD, los cuales suelen presentar niveles de desarrollo y estructuras económicas comparables. De igual forma, la cercanía observada entre varios países sugiere la existencia de perfiles económicos semejantes, lo que indica que buena parte de las economías analizadas comparten características similares en términos de estabilidad macroeconómica, crecimiento y relación con el sector externo.

Además aparecen algunos países alejados de la concentración principal. Entre ellos destacan Argentina, Irlanda y Chile, que se ubican como las observaciones más dispersas dentro del plano factorial. Esta posición sugiere que presentan comportamientos diferenciados en las dimensiones que explican la mayor parte de la variabilidad de los datos. En particular, podrían estar asociados a diferencias en aspectos relacionados con la estabilidad de precios, el comportamiento del tipo de cambio y el crecimiento nominal de la economía, variables que caracterizan la primera dimensión denominada “Inestabilidad nominal y presión inflacionaria”. Asimismo, parte de esta dispersión también podría estar vinculada con diferencias en el dinamismo de la demanda interna y el sector externo, reflejado en variables como el consumo privado, las importaciones, la cuenta corriente y la contribución de las exportaciones netas al crecimiento económico.

3.5.2 Gráfico individuos Dimensión 2 y 3

ind_coord <- as.data.frame(res.pca$x[, 2:3])
colnames(ind_coord) <- c("PC2", "PC3")
ind_info <- get_pca_ind(res.pca)
ind_coord$cos2 <- ind_info$cos2[, 2] + ind_info$cos2[, 3]  
ind_coord$label <- DatosEcon$Pais  # <-- nombres reales de los paises
plot_ly(
  data = ind_coord,
  x = ~PC2,   
  y = ~PC3,   
  type = 'scatter',
  mode = 'markers',
  marker = list(
    size = 8,
    color = ~cos2,
    colorscale = list(
      c(0, "#FCE4EC"),   
      c(0.5, "#F8BBD9"), 
      c(1, "#D81B60")   
    ),
    showscale = TRUE,
    colorbar = list(title = "cos2 (plano 2-3)")
  ),
  text = ~label,
  hoverinfo = 'text',
  hovertemplate = paste('<b>%{text}</b><br>PC2: %{x:.2f}<br>PC3: %{y:.2f}<br>cos2: %{marker.color:.2f}<extra></extra>')
) %>%
  layout(
    title = "Grafico de individuos Dimension 2 VS 3",
    xaxis = list(title = paste0("Dimension 2 (", round(summary(res.pca)$importance[2,2]*100,1), "%)")),
    yaxis = list(title = paste0("Dimension 3 (", round(summary(res.pca)$importance[2,3]*100,1), "%)"))
  ) %>%
  config(displayModeBar = FALSE)

Se observa una concentración importante de países alrededor del centro, lo que indica que gran parte de las economías presentan comportamientos relativamente similares en términos de demanda interna, comercio exterior y crecimiento económico. Sin embargo, Argentina, Irlanda, Chile y Estados Unidos continúan ubicándose entre las observaciones más alejadas del grupo principal, aunque Argentina se sitúa ahora sobre el lado negativo de la segunda dimensión.

Esta dispersión sugiere que dichos países presentan características particulares en las variables que definen ambas dimensiones. En el caso de la segunda dimensión, las diferencias pueden estar asociadas al comportamiento del consumo privado, las importaciones, la cuenta corriente y la contribución de las exportaciones netas al PIB, lo que refleja distintas formas de combinar la demanda interna con la relación comercial frente al exterior. Por otra parte, la tercera dimensión permite distinguir economías donde el crecimiento real se encuentra más vinculado al desempeño exportador. En este sentido, la posición de Irlanda, Chile y Estados Unidos podría indicar una dinámica de crecimiento y comercio exterior diferente la mayoría de los países de la muestra.

3.5.3 Gráfico variables Dimensión 1 y 2

var_coord <- as.data.frame(res.pca$rotation[, 1:2])
colnames(var_coord) <- c("PC1", "PC2")
var_coord$var <- iconv(variablesnombres[rownames(var_coord)], to = "UTF-8", sub = " ")

var_info <- get_pca_var(res.pca)
var_coord$contrib <- var_info$contrib[, 1]

plot_ly() %>%
  add_segments(
    x = 0, y = 0,
    xend = ~PC1, yend = ~PC2,
    data = var_coord,
    line = list(color = "gray", width = 1.5),
    showlegend = FALSE,
    hoverinfo = 'none'
  ) %>%
  add_markers(
    x = ~PC1, y = ~PC2,
    data = var_coord,
    marker = list(
      size = 10,
      color = ~contrib,
      colorscale = list(
        c(0, "#FCE4EC"),
        c(0.5, "#F8BBD9"),
        c(1, "#D81B60")
      ),
      showscale = TRUE,
      colorbar = list(title = "Contribución")
    ),
    text = ~var,
    hoverinfo = 'text',
    hovertemplate = paste('<b>%{text}</b><br>PC1: %{x:.2f}<br>PC2: %{y:.2f}<br>Contribucion: %{marker.color:.2f}<extra></extra>'),
    name = "Variables"
  ) %>%
  layout(
    title = "Variables Dimensión 1 VS 2",
    xaxis = list(title = paste0("Dimensión 1 (", round(summary(res.pca)$importance[2,1]*100,1), "%)"),
                 range = c(-1.1, 1.1)),
    yaxis = list(title = paste0("Dimensión 2 (", round(summary(res.pca)$importance[2,2]*100,1), "%)"),
                 range = c(-1.1, 1.1))
  ) %>%
  config(displayModeBar = FALSE)

El gráficomuestra patrones claros que definen a las economías de la OCDE.El primer cuadrante, formado por el PIB nominal, los deflactores del PIB y el tipo de cambio, define la Inestabilidad nominal y presión inflacionaria. Estas variables indican que un mayor crecimiento nominal suele estar impulsado por el aumento de precios y no por una expansión real, lo que refleja una mayor exposición a la inestabilidad macroeconómica.

En contraste, el segundo cuadrante se orienta al Dinamismo de la demanda interna y sector externo, compuesto por el consumo privado, las importaciones, la inversión y el PIB real. Al ser perpendicular al primero, sugiere que el crecimiento real y la demanda interna operan con relativa independencia frente a las presiones inflacionarias.

Por otra parte, la cuenta corriente y las exportaciones netas apuntan en sentido opuesto a la inflación sugirienod que los países con mayor inestabilidad nominal tienden a presentar una posición externa más débil, con mayor dependencia de financiamiento o déficits comerciales.

Así indicadores como el consumo gubernamental, las exportaciones y la tasa de desempleo presentan una menor capacidad para diferenciar a los países, mostrando un comportamiento más homogéneo en la muestra. Mostrando que el desempeño económico depende de la interacción entre la estabilidad de precios, la fortaleza de la demanda interna y la posición externa, elementos clave para caracterizar la resiliencia productiva actual.

3.5.4 Gráfico variables Dimensión 2 y 3

var_info <- get_pca_var(res.pca)
var_coord <- as.data.frame(res.pca$rotation[, 2:3])
colnames(var_coord) <- c("PC2", "PC3")
var_coord$var <- iconv(variablesnombres[rownames(var_coord)], to = "UTF-8", sub = " ")

var_coord$contrib <- var_info$contrib[, 2]  

plot_ly() %>%
  add_segments(
    x = 0, y = 0,
    xend = ~PC2, yend = ~PC3,          #
    data = var_coord,
    line = list(color = "gray", width = 1.5),
    showlegend = FALSE,
    hoverinfo = 'none'
  ) %>%
  add_markers(
    x = ~PC2, y = ~PC3,                
    data = var_coord,
    marker = list(
      size = 10,
      color = ~contrib,
      colorscale = list(
        c(0, "#FCE4EC"),
        c(0.5, "#F8BBD9"),
        c(1, "#D81B60")
      ),
      showscale = TRUE,
      colorbar = list(title = "Contribución")
    ),
    text = ~var,
    hoverinfo = 'text',
    hovertemplate = paste('<b>%{text}</b><br>PC2: %{x:.2f}<br>PC3: %{y:.2f}<br>Contribución: %{marker.color:.2f}<extra></extra>'),
    name = "Variables"
  ) %>%
  layout(
    title = "Variables Dimensión 2 VS 3",           
    xaxis = list(title = paste0("Dimensión 2 (", round(summary(res.pca)$importance[2,2]*100,1), "%)"),  
                 range = c(-1.1, 1.1)),
    yaxis = list(title = paste0("Dimensión 3 (", round(summary(res.pca)$importance[2,3]*100,1), "%)"), 
                 range = c(-1.1, 1.1))
  ) %>%
  config(displayModeBar = FALSE)

El gráfico muestra una clara segmentación de los motores económicos. En el cuadrante superior derecho, se observa un bloque sólido formado por el consumo privado y la formación bruta de capital fijo. Al ser prácticamente perpendicular a las variables de exportación, sugiere que el dinamismo basado en la demanda interna —consumo e inversión— opera con relativa independencia frente al impulso que proviene del sector externo.

En contraste, hacia el cuadrante inferior derecho, las exportaciones y la contribución de las exportaciones netas al PIB real se agrupan en una dirección distinta, indiicando que los países que basan su expansión en el sector exportador presentan una lógica de crecimiento diferente a aquellos centrados en el gasto interno, evidenciando una especialización en la integración comercial global.

Por otra parte, variables como el deflactor del PIB y el tipo de cambio se ubican en una dirección que contrasta con el sector exportador, sugiriendo que la competitividad internacional y los precios locales mantienen una relación de tensión en la estructura económica de estos países.

Finalmente, indicadores como la tasa de desempleo, la fuerza laboral y las exportaciones totales muestran una ubicación más cercana al centro. Esto refleja una menor capacidad para diferenciar a los países, lo que indica un comportamiento más homogéneo en la muestra para estas variables. Mostrando que el desempeño económico depende de la interacción entre el impulso de la demanda interna y la competitividad externa, elementos clave para caracterizar la resiliencia productiva actual.

3.5.5 Gráfico BiPlot Dimensión 1 y 2

ind_coord <- as.data.frame(res.pca$x[, 1:2])
colnames(ind_coord) <- c("PC1", "PC2")
ind_coord$label <- DatosEcon$Pais
var_coord <- as.data.frame(res.pca$rotation[, 1:2])
colnames(var_coord) <- c("PC1", "PC2")
nombres_limpios <- variablesnombres[rownames(var_coord)]
nombres_limpios <- iconv(nombres_limpios, from = "latin1", to = "UTF-8", sub = "byte")
nombres_limpios <- gsub("<f1>", "n", nombres_limpios, fixed = TRUE)
nombres_limpios <- gsub("<[0-9a-f]{2}>", "", nombres_limpios)
var_coord$var <- nombres_limpios
var_coord$var <- gsub("[\r\n]", " ", var_coord$var)
var_coord$var <- trimws(var_coord$var)
scale_factor <- 5
var_coord$PC1 <- var_coord$PC1 * scale_factor
var_coord$PC2 <- var_coord$PC2 * scale_factor
plot_ly() %>%
  add_markers(
    x = ~PC1, y = ~PC2,
    data = ind_coord,
    marker = list(size = 8, color = "#696969", opacity = 0.6),
    text = ~label,
    hoverinfo = 'text',
    hovertemplate = paste('<b>Individuo: %{text}</b><br>PC1: %{x:.2f}<br>PC2: %{y:.2f}<extra></extra>'),
    name = "Individuos"
  ) %>%
  add_segments(
    x = 0, y = 0,
    xend = ~PC1, yend = ~PC2,
    data = var_coord,
    line = list(color = "#F8BBD9", width = 2),
    showlegend = FALSE,
    hoverinfo = 'none'
  ) %>%
  add_markers(
    x = ~PC1, y = ~PC2,
    data = var_coord,
    marker = list(size = 10, color = "#D81B60"),
    text = ~var,
    hoverinfo = 'text',
    hovertemplate = paste('<b>%{text}</b><br>PC1: %{x:.2f}<br>PC2: %{y:.2f}<extra></extra>'),
    name = "Variables"
  ) %>%
  layout(
    title = "Biplot Dimension 1 VS 2",
    xaxis = list(title = paste0("Dimension 1 (", round(summary(res.pca)$importance[2,1]*100,1), "%)"),
                 zeroline = TRUE),
    yaxis = list(title = paste0("Dimension 2 (", round(summary(res.pca)$importance[2,2]*100,1), "%)"),
                 zeroline = TRUE)
  ) %>%
  config(displayModeBar = FALSE)

El biplot resume permitiendo identificar patrones clave entre las economías. La mayoría de los países se concentran en el centro, compartiendo comportamientos macroeconómicos similares, mientras que los valores atípicos son los que revelan las diferencias más importantes.

Hacia el cuadrante derecho, Argentina se separa del resto, representando un caso extremo de crisis de estabilidad nominal con inflación desbordada, crecimiento nominal artificial y depreciación cambiaria. En contraste, en el cuadrante superior, países como Colombia, Chile, Perú e India destacan por su dinamismo; estos se alejan del centro debido a una recuperación post-pandemia más intensa, impulsada por un mayor consumo privado e inversión.

En definitiva, este gráfico confirma que el desempeño económico no responde a un único factor. La estructura muestra cómo la interacción entre la estabilidad de precios y el dinamismo de la demanda interna define la resiliencia productiva actual, afectando de manera desigual el crecimiento y la posición comercial de cada país ante la incertidumbre global.

3.5.6 Gráfico BiPlot Dimensión 2 y 3

ind_coord <- as.data.frame(res.pca$x[, 2:3])
colnames(ind_coord) <- c("PC2", "PC3")
ind_coord$label <- DatosEcon$Pais
var_coord <- as.data.frame(res.pca$rotation[, 2:3])
colnames(var_coord) <- c("PC2", "PC3")
nombres_limpios <- variablesnombres[rownames(var_coord)]
nombres_limpios <- iconv(nombres_limpios, from = "latin1", to = "UTF-8", sub = "byte")
nombres_limpios <- gsub("<f1>", "n", nombres_limpios, fixed = TRUE)
nombres_limpios <- gsub("<[0-9a-f]{2}>", "", nombres_limpios)
var_coord$var <- nombres_limpios
var_coord$var <- gsub("[\r\n]", " ", var_coord$var)
var_coord$var <- trimws(var_coord$var)
scale_factor <- 5
var_coord$PC2 <- var_coord$PC2 * scale_factor
var_coord$PC3 <- var_coord$PC3 * scale_factor
plot_ly() %>%
  add_markers(
    x = ~PC2, y = ~PC3,
    data = ind_coord,
    marker = list(size = 8, color = "#696969", opacity = 0.6),
    text = ~label,
    hoverinfo = 'text',
    hovertemplate = paste('<b>Individuo: %{text}</b><br>PC2: %{x:.2f}<br>PC3: %{y:.2f}<extra></extra>'),
    name = "Individuos"
  ) %>%
  add_segments(
    x = 0, y = 0,
    xend = ~PC2, yend = ~PC3,
    data = var_coord,
    line = list(color = "#F8BBD9", width = 2),
    showlegend = FALSE,
    hoverinfo = 'none'
  ) %>%
  add_markers(
    x = ~PC2, y = ~PC3,
    data = var_coord,
    marker = list(size = 10, color = "#D81B60"),
    text = ~var,
    hoverinfo = 'text',
    hovertemplate = paste('<b>%{text}</b><br>PC2: %{x:.2f}<br>PC3: %{y:.2f}<extra></extra>'),
    name = "Variables"
  ) %>%
  layout(
    title = "Biplot Dimension 2 VS 3",
    xaxis = list(title = paste0("Dimension 2 (", round(summary(res.pca)$importance[2,2]*100,1), "%)"),
                 zeroline = TRUE),
    yaxis = list(title = paste0("Dimension 3 (", round(summary(res.pca)$importance[2,3]*100,1), "%)"),
                 zeroline = TRUE)
  ) %>%
  config(displayModeBar = FALSE)

Un hallazgo revelador es el posicionamiento de Argentina, mientras que en los demás gráficos dominaba como un valor atípico extremo, aquí se ubica cerca del centro en todo el eje horizontal confirmando que Agrentina y su divergencia estructural radica casi exclusivamente en su inestabilidad nominal, y no en variaciones anómalas de crecimiento real o dinámica exportadora.

Al evaluar los cuadrantes, el caso más llamativo es el de Irlanda, aislada en el extremo superior izquierdo. Esta posición no refleja una contracción económica, sino el impacto de las multinacionales allí instaladas que generan volúmenes de exportación gigantescos y un alto saldo en cuenta corriente, contrastando con un bajo consumo privado. Es una estructura productiva que la propia OCDE reconoce como estadísticamente atípica dentro de las economías avanzadas.

Pero en el cuadrante superior derecho agrupa a países como Colombia, Perú, India, Croacia y Estonia que estas economías destacan como modelos en expansión activa, logrando apalancar su crecimiento al combinar un fuerte dinamismo de la demanda interna con un sólido desempeño exportador. Por el contrario, en la zona inferior, potencias como Estados Unidos, Japón y Brasil muestran un patrón de crecimiento mucho más moderado tanto en su impulso externo como en su demanda doméstica dentro de este plano.

En definitiva, esta representación gráfica permite descifrar los modelos productivos subyacentes de la muestra, evidenciando si la expansión económica de un país se apalanca en su mercado interno o en su desempeño exportador. Identificar estas diferencias es un factor clave para comprender cómo cada economía se está adaptando a la actual reorganización de las cadenas globales de suministro señalada en los reportes de la OCDE.
if(is.null(rownames(res.pca$x))) rownames(res.pca$x) <- paises

distribvariables <- fviz_contrib(res.pca, choice = "var", axes = 1:3,
                                 fill = "#FCE4EC", color = "#D81B60",
                                 top = 10, orientation = "horizontal") +
  theme_minimal() +
  theme(plot.title = element_text(color = "#D81B60", face = "bold")) +
  labs(title = "Contribución de las variables")



contribindividuos <- fviz_contrib(res.pca, choice = "ind", axes = 1:2,
                                  fill = "#FCE4EC", color = "#D81B60",
                                  top = 47, orientation = "horizontal") +
  theme_minimal() +
  theme(plot.title = element_text(color = "#D81B60", face = "bold")) +
  labs(title = "Contribución de los individuos") +
  scale_y_discrete(labels = function(x) paises[as.numeric(x)]) 


distribvariables

contribindividuos

3.6 Dendograma Jeráquico (Ward)

rownames(scores_pca) <- paises

dist_paises <- dist(scores_pca)
modelo_jerarquico <- hclust(dist_paises, method = "ward.D2")
dend_modelo <- as.dendrogram(modelo_jerarquico)

par(las = 2) 
plot(dend_modelo, 
     cex = 0.6, 
     main = "Dendrograma jerarquico (Ward)", 
     xlab = "", 
     ylab = "Distancia", 
     sub = "",
     col = "#D81B60",  
     edgePar = list(col = "#D81B60", lwd = 2))  

par(las = 0)

La estructura asimétrica y en forma de cascada que presenta el dendrograma refleja de forma clara un panorama económico global que opera a múltiples velocidadesevidenciando un enorme centro de gravedad en la parte derecha del gráfico, donde la gran mayoría de las naciones se agrupan estrechamente. Este bloque apretado representa a las economías desarrolladas y a los mercados fuertemente integrados que, impulsados por la globalización comercial, se enfrentan a los mismos ciclos, reaccionando con políticas monetarias similares y respiran prácticamente al mismo ritmo macroeconómico, al otro lado las ramas más altas que se desprenden progresivamente hacia la zona izquierda agrupan realidades estructurales distintas. Bloques emergentes como el conformado por Colombia, Chile, India y Perú transitan por caminos con dinámicas particulares, demostrando que sus motores de crecimiento dependen de fuerzas diferentes como una fuerte expansión de su demanda interna o una mayor sensibilidad a los precios internacionales. En conjunto el núcleo duro del mundo transita por una misma autopista macroeconómica estandarizada, mientras que una periferia de países avanza impulsada por sus propias condiciones históricas y estructurales.

3.7 Dendogramas clusterizados

colores_cluster <- c("#000000","#696969","#F8BBD9", "#D81B60" )

corte <- 8

dend_modelo %>% 
  color_branches(h = corte, col = colores_cluster) %>% 
  color_labels(h = corte, col = colores_cluster) %>% 
  plot(cex = 0.6, main = "Dendrograma - Clusters de paises", xlab = "", ylab = "Distancia")
abline(h = corte, lty = 2, col = "gray40", lwd = 2)

clusters_deseados <- 3
dend_modelo %>%
  color_branches(k = clusters_deseados, col = c("#696969", "#F8BBD9", "#D81B60")) %>%
  color_labels(k = clusters_deseados, col = c("#696969", "#F8BBD9", "#D81B60")) %>%
  plot(main = "Dendrograma - 3 clusters", xlab = "", ylab = "Distancia")

par(las = 0)

Los dendogramas están revelando tres comportamientos muy marcados al establecer una línea de corte cercana a la distancia de 8. Por un lado, la gran mayoría de la muestra se concentra en un extenso bloque homogéneo a la derecha del gráfico, indicando que economías consolidadas como Estados Unidos, Alemania y Japón, junto con mercados grandes como Brasil y México siendo estos mercados o economias que comparten niveles de estabilidad macroeconómica muy similares. En claro contraste, el algoritmo logra aislar a Colombia, Chile, India y Perú en un clúster intermedio bastante definido, lo que demuestra estadísticamente que estos países comparten un modelo de crecimiento apalancado fuertemente en su demanda interna. Finalmente, el gráfico evidencia de forma contundente las mayores divergencias de los datos al ramificar en solitario a Argentina e Irlanda en el extremo izquierdo, confirmando que ambos conforman clústeres individuales por ser casos atípicos extremos, el primero por su fuerte descontrol inflacionario y el segundo por el volumen desproporcionado de sus exportaciones multinacionales.

3.8 Gráfico de óptimos clusterss

fviz_nbclust(scores_pca, FUN = kmeans, method = "silhouette") +
  labs(
    title = "Numero optimo de clusters (Silueta - K-means)",
    x = "Numero de clusters k",
    y = "Silueta promedio"
  ) +
  theme_minimal() +
  scale_color_manual(values = "#D81B60")

modelo_kmeans <- kmeans(scores_pca, centers = 2)
modelo_kmeans$centers
##          PC1        PC2        PC3
## 1  4.0219844  1.0650078  1.0353045
## 2 -0.6703307 -0.1775013 -0.1725508
set.seed(123)
modelo_kmeans <- kmeans(scores_pca, centers = 2)

cluster_paises <- modelo_kmeans$cluster
DatosEcon_agrupados <- datos_pca %>% 
  mutate(cluster = cluster_paises)
ind_coord <- as.data.frame(res.pca$x[, 1:2])
colnames(ind_coord) <- c("PC1", "PC2")
ind_coord$cluster <- factor(cluster_paises)
ind_coord$label <- rownames(ind_coord)
n_clusters <- length(unique(cluster_paises))
colores_cluster <- switch(as.character(n_clusters),
                          "2" = c("#696969", "#D81B60"),
                          "3" = c("#696969", "#F8BBD9", "#D81B60"),
                          "4" = c("#696969", "#F8BBD9", "#D81B60", "#FCE4EC"),
                          "5" = c("#696969", "#F8BBD9", "#D81B60", "#FCE4EC", "#000000"),
                          rep(c("#696969", "#F8BBD9", "#D81B60", "#FCE4EC", "#000000"), length.out = n_clusters)
)
library(plotly)
plotly_obj <- plot_ly()
for (i in seq_along(levels(ind_coord$cluster))) {
  grupo <- levels(ind_coord$cluster)[i]
  datos_grupo <- ind_coord[ind_coord$cluster == grupo, ]
  
  if (nrow(datos_grupo) >= 3) {
    elipse <- car::ellipse(
      center = colMeans(datos_grupo[, c("PC1", "PC2")]),
      shape = cov(datos_grupo[, c("PC1", "PC2")]),
      radius = sqrt(qchisq(0.95, df = 2)),
      draw = FALSE
    )
    plotly_obj <- plotly_obj %>% add_trace(
      x = elipse[, 1], y = elipse[, 2],
      type = 'scatter', mode = 'lines',
      fill = 'none',
      line = list(color = colores_cluster[i], width = 2),
      showlegend = FALSE,
      hoverinfo = 'none'
    )
  }
}
plotly_obj <- plotly_obj %>% add_trace(
  data = ind_coord,
  x = ~PC1, y = ~PC2,
  type = 'scatter', mode = 'markers',
  color = ~cluster,
  colors = colores_cluster,
  marker = list(size = 10, opacity = 0.8, line = list(width = 1, color = "white")),
  text = ~paste(label, '<br>Cluster:', cluster),
  hoverinfo = 'text',
  hovertemplate = paste('<b>%{text}</b><br>PC1: %{x:.2f}<br>PC2: %{y:.2f}<extra></extra>')
) %>%
  layout(
    title = "Grafico de individuos por cluster (PC1 vs PC2)",
    xaxis = list(title = paste0("Dimension 1 (", round(summary(res.pca)$importance[2,1]*100,1), "%)"),
                 zeroline = TRUE),
    yaxis = list(title = paste0("Dimension 2 (", round(summary(res.pca)$importance[2,2]*100,1), "%)"),
                 zeroline = TRUE),
    legend = list(title = list(text = "Cluster"))
  ) %>%
  config(displayModeBar = FALSE)
plotly_obj

El primer grupo, representado por los puntos verdes, actúa como el gran centro de gravedad del mundo. Se concentra de forma muy compacta en el lado izquierdo del plano (valores bajos o negativos en la Dimensión 1) y muy cerca del origen en la Dimensión 2. Esto nos indica que este clúster agrupa a la inmensa mayoría de las economías avanzadas (como Alemania, México, Sudáfrica, entre otras) que lograron mantener su anclaje y estabilidad nominal. Son países que pudieron contener mejor las presiones inflacionarias post-pandemia y mantuvieron un ritmo de consumo e inversión interno mucho más moderado y tradicional.

En claro contraste, el segundo clúster (los puntos morados) captura a la periferia divergente, dispersándose ampliamente hacia la derecha y hacia arriba del gráfico. Al limitarse a solo dos grupos, el algoritmo se vio obligado a meter en este mismo saco a todos los países que rompieron el molde de la normalidad de la OCDE. Por un lado, engloba hacia arriba a economías como Colombia, Chile e India, que experimentaron un vigoroso dinamismo impulsado por la expansión de su demanda interna. Por otro lado, arrastra hacia la extrema derecha a las economías que sufrieron choques severos de inestabilidad nominal y descontrol inflacionario.

En síntesis, esta clasificación binaria divide el panorama económico actual en dos bloques fundamentales: un bloque hegemónico de economías maduras enfocadas en la estabilidad de precios y el crecimiento conservador, frente a un bloque de economías más volátiles que, ya sea por una fuerte aceleración de su mercado interno o por crisis inflacionarias, transitan por fuera del comportamiento estándar internacional.

cluster_paises <- modelo_kmeans$cluster

DatosEcon_agrupados <- datos_pca %>% 
  mutate(cluster = cluster_paises)

ind_coord <- as.data.frame(res.pca$x[, 2:3])
colnames(ind_coord) <- c("PC2", "PC3")
ind_coord$cluster <- factor(cluster_paises)
ind_coord$label <- rownames(ind_coord)

n_clusters <- length(unique(cluster_paises))
colores_cluster <- switch(as.character(n_clusters),
                          "2" = c("#696969", "#D81B60"),
                          "3" = c("#696969", "#F8BBD9", "#D81B60"),
                          "4" = c("#696969", "#F8BBD9", "#D81B60", "#FCE4EC"),
                          "5" = c("#696969", "#F8BBD9", "#D81B60", "#FCE4EC", "#000000"),
                          rep(c("#696969", "#F8BBD9", "#D81B60", "#FCE4EC", "#000000"), length.out = n_clusters)
)

library(plotly)

plotly_obj <- plot_ly()

for (i in seq_along(levels(ind_coord$cluster))) {
  grupo <- levels(ind_coord$cluster)[i]
  datos_grupo <- ind_coord[ind_coord$cluster == grupo, ]
  
  if (nrow(datos_grupo) >= 3) {
    elipse <- car::ellipse(
      center = colMeans(datos_grupo[, c("PC2", "PC3")]),
      shape = cov(datos_grupo[, c("PC2", "PC3")]),
      radius = sqrt(qchisq(0.95, df = 2)),
      draw = FALSE
    )
    plotly_obj <- plotly_obj %>% add_trace(
      x = elipse[, 1], y = elipse[, 2],
      type = 'scatter', mode = 'lines',
      fill = 'none',
      line = list(color = colores_cluster[i], width = 2),
      showlegend = FALSE,
      hoverinfo = 'none'
    )
  }
}

plotly_obj <- plotly_obj %>% add_trace(
  data = ind_coord,
  x = ~PC2, y = ~PC3,
  type = 'scatter', mode = 'markers',
  color = ~cluster,
  colors = colores_cluster,
  marker = list(size = 10, opacity = 0.8, line = list(width = 1, color = "white")),
  text = ~paste(label, '<br>Cluster:', cluster),
  hoverinfo = 'text',
  hovertemplate = paste('<b>%{text}</b><br>PC2: %{x:.2f}<br>PC3: %{y:.2f}<extra></extra>')
) %>%
  layout(
    title = "Grafico de individuos por cluster (PC2 vs PC3)",
    xaxis = list(title = paste0("Dimension 2 (", round(summary(res.pca)$importance[2,2]*100,1), "%)"),
                 zeroline = TRUE),
    yaxis = list(title = paste0("Dimension 3 (", round(summary(res.pca)$importance[2,3]*100,1), "%)"),
                 zeroline = TRUE),
    legend = list(title = list(text = "Cluster"))
  ) %>%
  config(displayModeBar = FALSE)

plotly_obj

En este segundo plano, el algoritmo clasifica los países bajo una lógica distinta: el clúster verde se mantiene como el núcleo central de economías con un comportamiento más moderado, tanto en su demanda interna como en su proyección externa. Sin embargo, la gran diferencia es que este grupo ahora es mucho más inclusivo, absorbiendo a la mayoría de las naciones desarrolladas y mercados grandes, cuya actividad económica se muestra estable y predecible.

Por otro lado, el clúster morado se dispersa en una dirección que marca una clara divergencia productiva. Aquí se agrupan economías que, durante el periodo, mostraron un desempeño atípico al alejarse de la norma: por un lado, países que impulsaron su crecimiento a través de un dinamismo interno y externo más agresivo, y por otro, casos que presentan una especialización o estructura exportadora que los separa del bloque mayoritario. Esta clasificación pone de manifiesto que, al eliminar el factor de inestabilidad nominal, las diferencias entre países no desaparecen, sino que se reconfiguran para resaltar qué naciones están adoptando modelos de crecimiento más activos frente a aquellas con una trayectoria más consolidada y conservadora.

modelo_kmeans <- kmeans(scores_pca, centers = 3)
cluster_paises <- modelo_kmeans$cluster
DatosEcon_agrupados <- datos_pca %>% 
  mutate(cluster = cluster_paises)

ind_coord <- as.data.frame(res.pca$x[, 1:2])
colnames(ind_coord) <- c("PC1", "PC2")
ind_coord$cluster <- factor(cluster_paises)
ind_coord$label <- rownames(ind_coord)

n_clusters <- length(unique(cluster_paises))
colores_cluster <- switch(as.character(n_clusters),
                          "2" = c("#696969", "#D81B60"),
                          "3" = c("#696969", "#F8BBD9", "#D81B60"),
                          "4" = c("#696969", "#F8BBD9", "#D81B60", "#FCE4EC"),
                          "5" = c("#696969", "#F8BBD9", "#D81B60", "#FCE4EC", "#000000"),
                          rep(c("#696969", "#F8BBD9", "#D81B60", "#FCE4EC", "#000000"), length.out = n_clusters)
)

library(plotly)

plotly_obj <- plot_ly()

for (i in seq_along(levels(ind_coord$cluster))) {
  grupo <- levels(ind_coord$cluster)[i]
  datos_grupo <- ind_coord[ind_coord$cluster == grupo, ]
  
  if (nrow(datos_grupo) >= 3) {
    elipse <- car::ellipse(
      center = colMeans(datos_grupo[, c("PC1", "PC2")]),
      shape = cov(datos_grupo[, c("PC1", "PC2")]),
      radius = sqrt(qchisq(0.95, df = 2)),
      draw = FALSE
    )
    plotly_obj <- plotly_obj %>% add_trace(
      x = elipse[, 1], y = elipse[, 2],
      type = 'scatter', mode = 'lines',
      fill = 'none',
      line = list(color = colores_cluster[i], width = 2),
      showlegend = FALSE,
      hoverinfo = 'none'
    )
  }
}

plotly_obj <- plotly_obj %>% add_trace(
  data = ind_coord,
  x = ~PC1, y = ~PC2,
  type = 'scatter', mode = 'markers',
  color = ~cluster,
  colors = colores_cluster,
  marker = list(size = 10, opacity = 0.8, line = list(width = 1, color = "white")),
  text = ~paste(label, '<br>Cluster:', cluster),
  hoverinfo = 'text',
  hovertemplate = paste('<b>%{text}</b><br>PC1: %{x:.2f}<br>PC2: %{y:.2f}<extra></extra>')
) %>%
  layout(
    title = "Grafico de individuos por cluster (PC1 vs PC2)",
    xaxis = list(title = paste0("Dimension 1 (", round(summary(res.pca)$importance[2,1]*100,1), "%)"),
                 zeroline = TRUE),
    yaxis = list(title = paste0("Dimension 2 (", round(summary(res.pca)$importance[2,2]*100,1), "%)"),
                 zeroline = TRUE),
    legend = list(title = list(text = "Cluster"))
  ) %>%
  config(displayModeBar = FALSE)

plotly_obj
ind_coord <- as.data.frame(res.pca$x[, 2:3])
colnames(ind_coord) <- c("PC2", "PC3")
ind_coord$cluster <- factor(cluster_paises)
ind_coord$label <- rownames(ind_coord)

plotly_obj <- plot_ly()

for (i in seq_along(levels(ind_coord$cluster))) {
  grupo <- levels(ind_coord$cluster)[i]
  datos_grupo <- ind_coord[ind_coord$cluster == grupo, ]
  
  if (nrow(datos_grupo) >= 3) {
    elipse <- car::ellipse(
      center = colMeans(datos_grupo[, c("PC2", "PC3")]),
      shape = cov(datos_grupo[, c("PC2", "PC3")]),
      radius = sqrt(qchisq(0.95, df = 2)),
      draw = FALSE
    )
    plotly_obj <- plotly_obj %>% add_trace(
      x = elipse[, 1], y = elipse[, 2],
      type = 'scatter', mode = 'lines',
      fill = 'none',
      line = list(color = colores_cluster[i], width = 2),
      showlegend = FALSE,
      hoverinfo = 'none'
    )
  }
}

plotly_obj <- plotly_obj %>% add_trace(
  data = ind_coord,
  x = ~PC2, y = ~PC3,
  type = 'scatter', mode = 'markers',
  color = ~cluster,
  colors = colores_cluster,
  marker = list(size = 10, opacity = 0.8, line = list(width = 1, color = "white")),
  text = ~paste(label, '<br>Cluster:', cluster),
  hoverinfo = 'text',
  hovertemplate = paste('<b>%{text}</b><br>PC2: %{x:.2f}<br>PC3: %{y:.2f}<extra></extra>')
) %>%
  layout(
    title = "Grafico de individuos por cluster (PC2 vs PC3)",
    xaxis = list(title = paste0("Dimension 2 (", round(summary(res.pca)$importance[2,2]*100,1), "%)"),
                 zeroline = TRUE),
    yaxis = list(title = paste0("Dimension 3 (", round(summary(res.pca)$importance[2,3]*100,1), "%)"),
                 zeroline = TRUE),
    legend = list(title = list(text = "Cluster"))
  ) %>%
  config(displayModeBar = FALSE)

plotly_obj
library(ggplot2)
library(dplyr)
library(tidyr)

# Calcular medias y desviaciones por cluster
# === TABLA DE MEDIAS POR CLUSTER (corregida) ===
tabla_medias <- DatosEcon_agrupados %>%
  group_by(cluster) %>%
  summarise(across(where(is.numeric), mean))  # solo numéricas

# Mostrar tabla bonita con gt
library(gt)
gt(tabla_medias) %>%
  tab_header(
    title = "Medias de variables por cluster",
    subtitle = "Valores originales (no estandarizados)"
  ) %>%
  fmt_number(columns = -cluster, decimals = 2) %>%
  tab_style(
    style = list(cell_fill(color = "#D81B60"), cell_text(color = "white", weight = "bold")),
    locations = cells_column_labels(everything())
  ) %>%
  tab_options(table.width = pct(100))
Medias de variables por cluster
Valores originales (no estandarizados)
cluster x26 x27 x28 x17 x21 x22 x20 x19 x15 x16 x1 x8 x2 x18 x25
1 8.55 9,485,282.53 10,561,598.34 9.88 11.54 5.32 14.69 7.72 17.84 21.28 −1.79 −0.01 10.33 18.42 1.48
2 6.93 21,532,398.65 23,256,262.68 5.17 4.91 4.10 4.13 4.01 8.40 9.80 1.90 0.00 4.42 9.37 1.27
3 9.28 121,937,875.00 133,194,875.00 10.40 10.02 7.10 33.42 54.15 9.22 22.02 1.37 −0.01 95.08 70.18 67.15

conclusiones

ajsjakjsjaskjas

bibliografia

ioajsas

LS0tDQp0aXRsZTogIklkZW50aWZpY2FjacOzbiBkZSBwZXJmaWxlcyBlY29uw7NtaWNvcyBlbiBwYcOtc2VzIGRlIGxhIE9FQ0QgbWVkaWFudGUgYW7DoWxpc2lzIGRlIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzIHkgdMOpY25pY2FzIGRlIGNsYXNpZmljYWNpw7NuIG5vIHN1cGVydmlzYWRhIg0KYXV0aG9yOiAiTWVsaXNhIEJldGFuY291cnQgRXNwYcOxYSwga2FyZW4gUnVlZGEgUGxhemEsIENyaXN0aWFuIERhdmlkIFNhbnRhIEl0dXJyZXMsICBGYWJpw6FuIFVyYmFubyBDcnV6LCINCmRhdGU6ICJKdW5pbyBkZSAyMDI2Ig0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZGVwdGg6IDMNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICBjb2xsYXBzZWQ6IHRydWUNCiAgICBzbW9vdGhfc2Nyb2xsOiB0cnVlDQogICAgdGhlbWU6IGZsYXRseQ0KICAgIGhpZ2hsaWdodDoga2F0ZQ0KICAgIGRmX3ByaW50OiBwYWdlZA0KICAgIGNvZGVfZm9sZGluZzogInNob3ciICANCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlICAgICANCiAgICBjb2RlX21lbnU6IHRydWUgICANCi0tLQ0KIyAxIEludHJvZHVjY2nDs24NCg0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeTsiPkxhIGVjb25vbcOtYSBtdW5kaWFsIGhhIGV4cGVyaW1lbnRhZG8gdW4gcGVyw61vZG8gZGUgYWx0YSBpbmNlcnRpZHVtYnJlIGR1cmFudGUgbG9zIMO6bHRpbW9zIGHDsW9zLCBjYXJhY3Rlcml6YWRvIHBvciBsYSByZWN1cGVyYWNpw7NuIHBvc3RlcmlvciBhIGxhIHBhbmRlbWlhIGRlIENPVklELTE5LCBlcGlzb2Rpb3MgaW5mbGFjaW9uYXJpb3MgcGVyc2lzdGVudGVzLCB0ZW5zaW9uZXMgZ2VvcG9sw610aWNhcyB5IGNhbWJpb3MgZW4gbGFzIGNvbmRpY2lvbmVzIGZpbmFuY2llcmFzIGludGVybmFjaW9uYWxlcy4gRXN0b3MgYWNvbnRlY2ltaWVudG9zIGhhbiBnZW5lcmFkbyBlZmVjdG9zIHNpZ25pZmljYXRpdm9zIHNvYnJlIGVsIGNyZWNpbWllbnRvIGVjb27Ds21pY28sIGVsIGNvbWVyY2lvIGludGVybmFjaW9uYWwsIGxvcyBtZXJjYWRvcyBsYWJvcmFsZXMgeSBsYSBlc3RhYmlsaWRhZCBkZSBwcmVjaW9zLCBhZmVjdGFuZG8gZGUgbWFuZXJhIGRpZmVyZW5jaWFkYSBhIGxhcyBlY29ub23DrWFzIGFscmVkZWRvciBkZWwgbXVuZG8uDQoNCkRlIGFjdWVyZG8gY29uIGxvcyBpbmZvcm1lcyAqKk9FQ0QgRWNvbm9taWMgT3V0bG9vayAyMDI0IHkgT0VDRCBFbXBsb3ltZW50IE91dGxvb2sgMjAyNCoqLCBhdW5xdWUgKipsYSBpbmZsYWNpw7NuIGhhIG1vc3RyYWRvIHNlw7FhbGVzIGRlIG1vZGVyYWNpw7NuIGVuIG51bWVyb3NvcyBwYcOtc2VzLCBjb250aW7DumFuIGV4aXN0aWVuZG8gZGVzYWbDrW9zIGFzb2NpYWRvcyBhIGxhIGRlc2FjZWxlcmFjacOzbiBkZWwgY3JlY2ltaWVudG8gZWNvbsOzbWljbyoqLCBsYSBldm9sdWNpw7NuIGRlIGxhcyB0YXNhcyBkZSBpbnRlcsOpcywgbGEgcmVjdXBlcmFjacOzbiBkZSBsYSBpbnZlcnNpw7NuIHByb2R1Y3RpdmEgeSBsYSBjYXBhY2lkYWQgZGUgbG9zIG1lcmNhZG9zIGxhYm9yYWxlcyBwYXJhIHNvc3RlbmVyIG5pdmVsZXMgZWxldmFkb3MgZGUgZW1wbGVvLiBBbCBtaXNtbyB0aWVtcG8sIGVsIGNvbWVyY2lvIGludGVybmFjaW9uYWwgaGEgZW5mcmVudGFkbyBjYW1iaW9zIGltcG9ydGFudGVzIGRlcml2YWRvcyBkZSBsYSByZW9yZ2FuaXphY2nDs24gZGUgY2FkZW5hcyBnbG9iYWxlcyBkZSBzdW1pbmlzdHJvLCBsYXMgZmx1Y3R1YWNpb25lcyBkZSBsb3MgdGlwb3MgZGUgY2FtYmlvIHkgbGEgaW5jZXJ0aWR1bWJyZSBlY29uw7NtaWNhIGdsb2JhbC4NCg0KRW4gZXN0ZSBjb250ZXh0bywgcmVzdWx0YSAqKnJlbGV2YW50ZSBhbmFsaXphciBkZSBtYW5lcmEgY29uanVudGEgaW5kaWNhZG9yZXMgcXVlIHJlZmxlamVuIGVsIGRlc2VtcGXDsW8gZWNvbsOzbWljbyBkZSBsb3MgcGHDrXNlcyBkZXNkZSBkaWZlcmVudGVzIGRpbWVuc2lvbmVzKiouIFZhcmlhYmxlcyByZWxhY2lvbmFkYXMgY29uIGVsIGNyZWNpbWllbnRvIGRlbCBwcm9kdWN0byBpbnRlcm5vIGJydXRvLCBsYSBpbnZlcnNpw7NuLCBlbCBjb25zdW1vLCBsYSBpbmZsYWNpw7NuLCBlbCBlbXBsZW8geSBlbCBzZWN0b3IgZXh0ZXJubyBwZXJtaXRlbiBldmFsdWFyIG5vIHNvbG8gbGEgY2FwYWNpZGFkIGRlIGV4cGFuc2nDs24gZWNvbsOzbWljYSBkZSBjYWRhIHBhw61zLCBzaW5vIHRhbWJpw6luIHN1IGVzdGFiaWxpZGFkIG1hY3JvZWNvbsOzbWljYSB5IHN1IGZvcnRhbGV6YSBmcmVudGUgYSBjaG9xdWVzIGV4dGVybm9zLg0KDQpMYSBiYXNlIGRlIGRhdG9zIHV0aWxpemFkYSBlbiBlc3RlIGVzdHVkaW8gY29udGllbmUgaW5mb3JtYWNpw7NuIGVjb27Ds21pY2EgeSBsYWJvcmFsIGRlIHBhw61zZXMgcGVydGVuZWNpZW50ZXMgYSBsYSBPcmdhbml6YWNpw7NuIHBhcmEgbGEgQ29vcGVyYWNpw7NuIHkgZWwgRGVzYXJyb2xsbyBFY29uw7NtaWNvcyAoT0VDRCkuIEEgcGFydGlyIGRlIGxvcyBsaW5lYW1pZW50b3MgZXN0YWJsZWNpZG9zIGVuIGxvcyBpbmZvcm1lcyBkZSBwZXJzcGVjdGl2YXMgZWNvbsOzbWljYXMgeSBsYWJvcmFsZXMgZGUgbGEgb3JnYW5pemFjacOzbiwgc2Ugc2VsZWNjaW9uYXJvbiBpbmRpY2Fkb3JlcyBhc29jaWFkb3MgYSBjaW5jbyBkaW1lbnNpb25lcyBmdW5kYW1lbnRhbGVzOiBjcmVjaW1pZW50byBlY29uw7NtaWNvLCBtZXJjYWRvIGxhYm9yYWwsIGVzdGFiaWxpZGFkIGRlIHByZWNpb3MsIGRlbWFuZGEgaW50ZXJuYSB5IHNlY3RvciBleHRlcm5vLiAqKkVzdGFzIHZhcmlhYmxlcyBwZXJtaXRlbiBjb25zdHJ1aXIgdW5hIHZpc2nDs24gaW50ZWdyYWwgZGVsIGRlc2VtcGXDsW8gZWNvbsOzbWljbyBkZSBsb3MgcGHDrXNlcyB5IGNvbnN0aXR1eWVuIHVuYSBiYXNlIGFkZWN1YWRhIHBhcmEgbGEgYXBsaWNhY2nDs24gZGUgdMOpY25pY2FzIGRlIGFuw6FsaXNpcyBtdWx0aXZhcmlhZG8gb3JpZW50YWRhcyBhIGlkZW50aWZpY2FyIHBhdHJvbmVzLCBzaW1pbGl0dWRlcyB5IGRpZmVyZW5jaWFzIGVudHJlIGxhcyBlY29ub23DrWFzIGVzdHVkaWFkYXMqKi4NCg0KQSBwYXJ0aXIgZGUgbGEgaW5mb3JtYWNpw7NuLCBlbCBwcmVzZW50ZSB0cmFiYWpvIGJ1c2NhIGlkZW50aWZpY2FyIGxhcyBwcmluY2lwYWxlcyBjYXJhY3RlcsOtc3RpY2FzIHF1ZSBkaWZlcmVuY2lhbiBhIGxvcyBwYcOtc2VzIGRlIGxhIE9FQ0QgZGVzZGUgdW5hIHBlcnNwZWN0aXZhIGVjb27Ds21pY2EgeSBsYWJvcmFsIGFuYWxpemFuZG8gZW4gY29uanVudG8gZGUgaW5kaWNhZG9yZXMgcmVsYWNpb25hZG9zIGNvbiBlbCBjcmVjaW1pZW50byBlY29uw7NtaWNvLCBlbCBtZXJjYWRvIGxhYm9yYWwsIGxhIGluZmxhY2nDs24sIGxhIGRlbWFuZGEgaW50ZXJuYSB5IGVsIHNlY3RvciBleHRlcm5vLCBzZSBwcmV0ZW5kZSByZWNvbm9jZXIgcGF0cm9uZXMgZGUgY29tcG9ydGFtaWVudG8gcGFyYSBhc8OtIHJlZHVjaXIgbGEgY29tcGxlamlkYWQgZGUgbG9zIGRhdG9zIHkgb2J0ZW5lciB1bmEgdmlzacOzbiBtw6FzIGNsYXJhIGRlIGxhcyBzaW1pbGl0dWRlcyB5IGRpZmVyZW5jaWFzIGV4aXN0ZW50ZXMgZW50cmUgbGFzIGVjb25vbcOtYXMgYW5hbGl6YWRhcy48L2Rpdj4NCg0KIyAyIE1ldG9kb2xvZ8OtYSANCg0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeTsiPkVsIHByZXNlbnRlIGVzdHVkaW8gc2UgZGVzYXJyb2xsw7MgbWVkaWFudGUgbGEgYXBsaWNhY2nDs24gZGUgdMOpY25pY2FzIGRlIGFuw6FsaXNpcyBtdWx0aXZhcmlhZG8gc29icmUgdW5hIGJhc2UgZGUgZGF0b3MgY29tcHVlc3RhIHBvciBpbmRpY2Fkb3JlcyBlY29uw7NtaWNvcyB5IGxhYm9yYWxlcyBkZSBwYcOtc2VzIHBlcnRlbmVjaWVudGVzIGEgbGEgT0VDRC4gSW5pY2lhbG1lbnRlLCBzZSByZWFsaXrDsyB1biBwcm9jZXNvIGRlIGRlcHVyYWNpw7NuIGRlIGxhIGluZm9ybWFjacOzbiBwYXJhIGdhcmFudGl6YXIgbGEgY2FsaWRhZCBkZSBsb3MgZGF0b3MgdXRpbGl6YWRvcyBlbiBlbCBhbsOhbGlzaXMuIFBvc3Rlcmlvcm1lbnRlLCBsYXMgdmFyaWFibGVzIGZ1ZXJvbiBlc3RhbmRhcml6YWRhcyBjb24gZWwgZmluIGRlIGVsaW1pbmFyIGxhcyBkaWZlcmVuY2lhcyBkZSBlc2NhbGEgeSBwZXJtaXRpciBjb21wYXJhY2lvbmVzIGFkZWN1YWRhcyBlbnRyZSBsb3MgZGlzdGludG9zIGluZGljYWRvcmVzLg0KDQpDb21vIHByaW1lcmEgZXRhcGEgYW5hbMOtdGljYSBzZSBsbGV2w7MgYSBjYWJvIHVuIGFuw6FsaXNpcyBleHBsb3JhdG9yaW8gZGUgbG9zIGRhdG9zIG1lZGlhbnRlIGVzdGFkw61zdGljYXMgZGVzY3JpcHRpdmFzIHkgZWwgZXN0dWRpbyBkZSBsYXMgY29ycmVsYWNpb25lcyBlbnRyZSB2YXJpYWJsZXMsIGNvbiBlbCBwcm9ww7NzaXRvIGRlIGlkZW50aWZpY2FyIHJlbGFjaW9uZXMgcmVsZXZhbnRlcyB5IHBvc2libGVzIHBhdHJvbmVzIGluaWNpYWxlcyBlbiBsYSBpbmZvcm1hY2nDs24uIFBvc3Rlcmlvcm1lbnRlLCBzZSBhcGxpY8OzIHVuIEFuw6FsaXNpcyBkZSBDb21wb25lbnRlcyBQcmluY2lwYWxlcyAoQUNQKSBwYXJhIHJlZHVjaXIgbGEgZGltZW5zaW9uYWxpZGFkIGRlIGxhIGJhc2UgZGUgZGF0b3MgeSBkZXRlcm1pbmFyIGN1w6FsZXMgZXJhbiBsYXMgZGltZW5zaW9uZXMgcXVlIGV4cGxpY2FiYW4gdW5hIG1heW9yIHByb3BvcmNpw7NuIGRlIGxhIHZhcmlhYmlsaWRhZCBvYnNlcnZhZGEgZW50cmUgbG9zIHBhw61zZXMuDQoNCkEgcGFydGlyIGRlIGxvcyByZXN1bHRhZG9zIG9idGVuaWRvcyBlbiBlbCBBQ1AsICoqc2UgaW1wbGVtZW50YXJvbiBkaWZlcmVudGVzIHTDqWNuaWNhcyBkZSBjbGFzaWZpY2FjacOzbiBubyBzdXBlcnZpc2FkYSBlbCBhbGdvcml0bW8gSy1NZWFucyB5IGVsIGFncnVwYW1pZW50byBqZXLDoXJxdWljbyBhZ2xvbWVyYXRpdm8qKiwgY29uIGVsIG9iamV0aXZvIGRlIGlkZW50aWZpY2FyIGdydXBvcyBkZSBwYcOtc2VzIGNvbiBjYXJhY3RlcsOtc3RpY2FzIGVjb27Ds21pY2FzIHNpbWlsYXJlcy4gRmluYWxtZW50ZSwgc2UgdXRpbGl6w7MgbGEgbWV0b2RvbG9nw61hIEZhY3RvQ2xhc3MsIGxhIGN1YWwgY29tYmluYSBsYSByZWR1Y2Npw7NuIGRlIGRpbWVuc2lvbmFsaWRhZCB5IGxhIGNsYXNpZmljYWNpw7NuIGRlIGluZGl2aWR1b3MsIHBlcm1pdGllbmRvIG9idGVuZXIgdW5hIGNhcmFjdGVyaXphY2nDs24gbcOhcyBkZXRhbGxhZGEgZGUgbG9zIGdydXBvcyBpZGVudGlmaWNhZG9zIHkgZGUgbGFzIHZhcmlhYmxlcyBxdWUgbWVqb3IgZXhwbGljYW4gc3VzIGRpZmVyZW5jaWFzLjwvZGl2Pg0KDQoNCiMjIDIuMSBGdWVudGUgZGUgZGF0b3MNCg0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeTsiPkxhIGluZm9ybWFjacOzbiB1dGlsaXphZGEgZW4gZXN0ZSB0cmFiYWpvIHByb3ZpZW5lIGRlIHVuYSBiYXNlIGRlIGRhdG9zIHByb3BvcmNpb25hZGEgcG9yIGVsIGRvY2VudGUsIGxhIGN1YWwgcmXDum5lIGluZGljYWRvcmVzIGVjb27Ds21pY29zIHkgbGFib3JhbGVzIGRlIHBhw61zZXMgcGVydGVuZWNpZW50ZXMgYSBsYSBPRUNELiBMYSBzZWxlY2Npw7NuIGRlIGVzdGEgYmFzZSBwZXJtaXRlIGFuYWxpemFyIGVjb25vbcOtYXMgY29uIGRpZmVyZW50ZXMgY2FyYWN0ZXLDrXN0aWNhcyB5IG5pdmVsZXMgZGUgZGVzZW1wZcOxbywgKipmYWNpbGl0YW5kbyBsYSBjb21wYXJhY2nDs24gZW50cmUgcGHDrXNlcyBhIHBhcnRpciBkZSB2YXJpYWJsZXMgcmVsYWNpb25hZGFzIGNvbiBjcmVjaW1pZW50byBlY29uw7NtaWNvLCBtZXJjYWRvIGxhYm9yYWwsIGluZmxhY2nDs24sIGRlbWFuZGEgaW50ZXJuYSB5IHNlY3RvciBleHRlcm5vLioqDQoNCkxhIGVsZWNjacOzbiBkZSBlc3RhcyBkaW1lbnNpb25lcyBzZSBlbmN1ZW50cmEgYWxpbmVhZGEgY29uIGxvcyB0ZW1hcyBhYm9yZGFkb3MgZW4gbG9zIGluZm9ybWVzIE9FQ0QgRWNvbm9taWMgT3V0bG9vayAyMDI0IHkgT0VDRCBFbXBsb3ltZW50IE91dGxvb2sgMjAyNCwgZG9uZGUgKipzZSBkZXN0YWNhIGxhIGltcG9ydGFuY2lhIGRlIGVzdHVkaWFyIGRlIG1hbmVyYSBjb25qdW50YSBsb3MgZmFjdG9yZXMgcXVlIGluZmx1eWVuIGVuIGVsIGNyZWNpbWllbnRvIGVjb27Ds21pY28sIGxhIGVzdGFiaWxpZGFkIG1hY3JvZWNvbsOzbWljYSB5IGxhIGdlbmVyYWNpw7NuIGRlIGVtcGxlby4gQSBwYXJ0aXIgZGUgZXN0YSBpbmZvcm1hY2nDs24qKiwgZWwgdHJhYmFqbyBidXNjYSBpZGVudGlmaWNhciBwYXRyb25lcyBjb211bmVzIGVudHJlIGxvcyBwYcOtc2VzIHkgY29tcHJlbmRlciBjdcOhbGVzIHNvbiBsYXMgY2FyYWN0ZXLDrXN0aWNhcyBxdWUgZXhwbGljYW4gbGFzIGRpZmVyZW5jaWFzIG9ic2VydmFkYXMgZW4gc3UgZGVzZW1wZcOxbyBlY29uw7NtaWNvIHJlY2llbnRlLjwvZGl2Pg0KDQojIyAyLjIgRGVmaW5pY2nDs24gZGUgbGFzIHZhcmlhYmxlcw0KDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5OyI+UGFyYSBlbCBkZXNhcnJvbGxvIGRlbCBhbsOhbGlzaXMgc2Ugc2VsZWNjaW9uYXJvbiBxdWluY2UgdmFyaWFibGVzIGN1YW50aXRhdGl2YXM6IHgxIChDdWVudGEgY29ycmllbnRlIGNvbW8gcG9yY2VudGFqZSBkZWwgUElCKSwgeDIgKFRpcG8gZGUgY2FtYmlvIGRlIGxhIG1vbmVkYSBsb2NhbCBmcmVudGUgYWwgZMOzbGFyIGVzdGFkb3VuaWRlbnNlKSwgeDggKEV4cG9ydGFjaW9uZXMgbmV0YXMgY29tbyBjb250cmlidWNpw7NuIGFsIFBJQiByZWFsKSwgeDE1IChDcmVjaW1pZW50byBkZWwgdm9sdW1lbiBkZSBleHBvcnRhY2lvbmVzKSwgeDE2IChDcmVjaW1pZW50byBkZWwgdm9sdW1lbiBkZSBpbXBvcnRhY2lvbmVzKSwgeDE3IChDcmVjaW1pZW50byBkZWwgUElCIGVuIHZvbHVtZW4pLCB4MTggKENyZWNpbWllbnRvIGRlbCBQSUIgbm9taW5hbCksIHgxOSAoQ3JlY2ltaWVudG8gZGVsIGRlZmxhY3RvciBkZWwgUElCKSwgeDIwIChDcmVjaW1pZW50byBkZSBsYSBmb3JtYWNpw7NuIGJydXRhIGRlIGNhcGl0YWwpLCB4MjEgKENyZWNpbWllbnRvIGRlbCBjb25zdW1vIHByaXZhZG8pLCB4MjIgKENyZWNpbWllbnRvIGRlbCBjb25zdW1vIGRlbCBnb2JpZXJubyksIHgyNSAoRGVmbGFjdG9yIGRlbCBQSUIgYSBwcmVjaW9zIGRlIG1lcmNhZG8pLCB4MjYgKFRhc2EgZGUgZGVzZW1wbGVvKSwgeDI3IChFbXBsZW8gdG90YWwgc2Vnw7puIGVuY3Vlc3RhIGRlIGZ1ZXJ6YSBsYWJvcmFsKSB5IHgyOCAoRnVlcnphIGxhYm9yYWwpLg0KDQpFc3RhcyB2YXJpYWJsZXMgZnVlcm9uIHNlbGVjY2lvbmFkYXMgcG9ycXVlIHBlcm1pdGVuIHJlcHJlc2VudGFyIGRpZmVyZW50ZXMgYXNwZWN0b3MgZGUgbGEgZWNvbm9tw61hIGRlIGNhZGEgcGHDrXMuICoqTG9zIGluZGljYWRvcmVzIGFzb2NpYWRvcyBhbCBQSUIsIGxhIGludmVyc2nDs24geSBlbCBjb25zdW1vIHJlZmxlamFuIGVsIGNvbXBvcnRhbWllbnRvIGRlIGxhIGFjdGl2aWRhZCBlY29uw7NtaWNhIHkgZGUgbGEgZGVtYW5kYSBpbnRlcm5hLCoqIGxhcyB2YXJpYWJsZXMgcmVsYWNpb25hZGFzIGNvbiBleHBvcnRhY2lvbmVzLCBpbXBvcnRhY2lvbmVzLCBjdWVudGEgY29ycmllbnRlIHkgdGlwbyBkZSBjYW1iaW8gcGVybWl0ZW4gYW5hbGl6YXIgZWwgc2VjdG9yIGV4dGVybm8sIGxvcyBkZWZsYWN0b3JlcyBkZWwgUElCIGFwb3J0YW4gaW5mb3JtYWNpw7NuIHNvYnJlIGxhIGV2b2x1Y2nDs24gZGUgbG9zIHByZWNpb3MgbWllbnRyYXMgcXVlIGxhcyB2YXJpYWJsZXMgZGUgZW1wbGVvLCBkZXNlbXBsZW8geSBmdWVyemEgbGFib3JhbCBkZXNjcmliZW4gbGEgc2l0dWFjacOzbiBkZWwgbWVyY2FkbyBsYWJvcmFsLiAqKkVzdGUgY29uanVudG8gZGUgaW5kaWNhZG9yZXMgcHJvcG9yY2lvbmEgdW5hIHZpc2nDs24gYW1wbGlhIGRlbCBkZXNlbXBlw7FvIGVjb27Ds21pY28gZGUgbG9zIHBhw61zZXMgYW5hbGl6YWRvcyB5IGNvbnN0aXR1eWUgbGEgYmFzZSBwYXJhIGxhIGFwbGljYWNpw7NuIGRlIGxhcyB0w6ljbmljYXMgZXN0YWTDrXN0aWNhcyB1dGlsaXphZGFzIGVuIGVsIGVzdHVkaW8uwqgqKjwvZGl2Pg0KDQojIyAyLjMgTW9kZWxvDQoNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnk7Ij5FbiBlc3RlIGVzdHVkaW8gc2UgdXRpbGl6YXJvbiB0w6ljbmljYXMgZGUgYW7DoWxpc2lzIG11bHRpdmFyaWFkbyBjb24gZWwgcHJvcMOzc2l0byBkZSBpZGVudGlmaWNhciBwYXRyb25lcyBlY29uw7NtaWNvcyBlbnRyZSBsb3MgcGHDrXNlcyBkZSBsYSBPRUNEIHkgcmVkdWNpciBsYSBjb21wbGVqaWRhZCBkZSBsYSBpbmZvcm1hY2nDs24gY29udGVuaWRhIGVuIGxhcyB2YXJpYWJsZXMgc2VsZWNjaW9uYWRhcy4gRW4gcHJpbWVyIGx1Z2FyLCBzZSBhcGxpY8OzIHVuIEFuw6FsaXNpcyBkZSBDb21wb25lbnRlcyBQcmluY2lwYWxlcyAoQUNQKSwgY3V5YSBmaW5hbGlkYWQgZnVlIHJlc3VtaXIgbGEgaW5mb3JtYWNpw7NuIG9yaWdpbmFsIGVuIHVuIG7Dum1lcm8gcmVkdWNpZG8gZGUgZGltZW5zaW9uZXMgY2FwYWNlcyBkZSBleHBsaWNhciBsYSBtYXlvciBwYXJ0ZSBkZSBsYSB2YXJpYWJpbGlkYWQgb2JzZXJ2YWRhIGVudHJlIGxvcyBwYcOtc2VzLiBFc3RhIHTDqWNuaWNhIHBlcm1pdGnDsyBpZGVudGlmaWNhciBjdcOhbGVzIHZhcmlhYmxlcyB0ZW7DrWFuIHVuYSBtYXlvciBpbmZsdWVuY2lhIGVuIGxhcyBkaWZlcmVuY2lhcyBlY29uw7NtaWNhcyBwcmVzZW50ZXMgZW4gbGEgYmFzZSBkZSBkYXRvcyB5IGZhY2lsaXTDsyBsYSByZXByZXNlbnRhY2nDs24gZ3LDoWZpY2EgZGUgbG9zIHJlc3VsdGFkb3MuDQoNClBvc3Rlcmlvcm1lbnRlLCBzZSBlbXBsZcOzIGVsIGFsZ29yaXRtbyBLLU1lYW5zIHBhcmEgYWdydXBhciBwYcOtc2VzIGNvbiBjYXJhY3RlcsOtc3RpY2FzIGVjb27Ds21pY2FzIHNpbWlsYXJlcy4gRXN0ZSBtw6l0b2RvIGJ1c2NhIGZvcm1hciBncnVwb3MgaW50ZXJuYW1lbnRlIGhvbW9nw6luZW9zIHkgZXh0ZXJuYW1lbnRlIGRpZmVyZW5jaWFkb3MsIHBlcm1pdGllbmRvIGlkZW50aWZpY2FyIHBlcmZpbGVzIGVjb27Ds21pY29zIGNvbXVuZXMgZW50cmUgbG9zIHBhw61zZXMgYW5hbGl6YWRvcy4gTGEgc2VsZWNjacOzbiBkZWwgbsO6bWVybyBkZSBncnVwb3Mgc2UgYXBvecOzIGVuIGNyaXRlcmlvcyBkZSB2YWxpZGFjacOzbiBjb21vIGVsIG3DqXRvZG8gZGVsIGNvZG8geSBlbCBjb2VmaWNpZW50ZSBkZSBzaWx1ZXRhLg0KDQoqKkNvbW8gY29tcGxlbWVudG8sIHNlIGltcGxlbWVudMOzIHVuIHByb2NlZGltaWVudG8gZGUgYWdydXBhbWllbnRvIGplcsOhcnF1aWNvIGFnbG9tZXJhdGl2byB1dGlsaXphbmRvIGRpc3RhbmNpYSBldWNsaWRpYW5hIHkgZWwgbcOpdG9kbyBkZSBXYXJkLihFU1RPIE5PIFNFIFNJIFZBKSoqIEVzdGEgdMOpY25pY2EgY29uc3RydXllIHVuYSBlc3RydWN0dXJhIGRlIGFncnVwYWNpw7NuIGJhc2FkYSBlbiBsYSBzaW1pbGl0dWQgZW50cmUgb2JzZXJ2YWNpb25lcywgcGVybWl0aWVuZG8gdmlzdWFsaXphciBsYXMgcmVsYWNpb25lcyBleGlzdGVudGVzIGVudHJlIGxvcyBwYcOtc2VzIG1lZGlhbnRlIHVuIGRlbmRyb2dyYW1hIHkgY29tcGFyYXIgbG9zIHJlc3VsdGFkb3Mgb2J0ZW5pZG9zIGNvbiBlbCBhbGdvcml0bW8gSy1NZWFucy4NCg0KRGUgZXN0YSBtYW5lcmEsIGVsIEFDUCBwZXJtaXRpw7MgcmVkdWNpciBsYSBkaW1lbnNpb25hbGlkYWQgZGUgbG9zIGRhdG9zIHkgZmFjaWxpdGFyIHN1IGludGVycHJldGFjacOzbiwgbWllbnRyYXMgcXVlIGxvcyBtw6l0b2RvcyBkZSBhZ3J1cGFtaWVudG8gaGljaWVyb24gcG9zaWJsZSBpZGVudGlmaWNhciBjb25qdW50b3MgZGUgcGHDrXNlcyBjb24gY29tcG9ydGFtaWVudG9zIGVjb27Ds21pY29zIHNlbWVqYW50ZXMuPC9kaXY+DQoNCiMgMyBBbsOhbGlzaXMgZGVzY3JpcHRpdm8NCg0KYGBge3IgbGlicmVyaWFzLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZmFjdG9leHRyYSkNCmxpYnJhcnkocmVzaGFwZTIpDQpsaWJyYXJ5KGNvcnJwbG90KQ0KbGlicmFyeShGYWN0b0NsYXNzKQ0KbGlicmFyeShkZW5kZXh0ZW5kKQ0KbGlicmFyeShndCkNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHBsb3RseSkNCmBgYA0KDQpgYGB7ciB2YXJpYWJsZXMgeSBiYXNlIGRlIGRhdG9zLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KRGF0b3NFY29uIDwtIHJlYWRfZXhjZWwoIkRhdG9zRWNvbi54bHN4IikNCnBhaXNlcyA8LSBEYXRvc0Vjb24kUGFpcw0KDQp2YXJpYWJsZXNub21icmVzIDwtIGMoDQogICJ4MSIgPSAiQ3VlbnRhIGNvcnJpZW50ZSAoJSBQSUIpIiwNCiAgIngyIiA9ICJUaXBvIGRlIGNhbWJpbyAobW9uZWRhIGxvY2FsL1VTRCkiLA0KICAieDgiID0gIkV4cG9ydGFjaW9uZXMgbmV0YXMgKGNvbnRyaWJ1Y2nDs24gYWwgUElCIHJlYWwpIiwNCiAgIngxNSIgPSAiRXhwb3J0YWNpb25lcyAodm9sdW1lbiwgY3JlY2ltaWVudG8pIiwNCiAgIngxNiIgPSAiSW1wb3J0YWNpb25lcyAodm9sdW1lbiwgY3JlY2ltaWVudG8pIiwNCiAgIngxNyIgPSAiUElCICh2b2x1bWVuLCBjcmVjaW1pZW50bykiLA0KICAieDE4IiA9ICJQSUIgKG5vbWluYWwsIGNyZWNpbWllbnRvKSIsDQogICJ4MTkiID0gIkRlZmxhY3RvciBkZWwgUElCIChjcmVjaW1pZW50bykiLA0KICAieDIwIiA9ICJGb3JtYWNpw7NuIGJydXRhIGRlIGNhcGl0YWwgKHZvbHVtZW4sIGNyZWNpbWllbnRvKSIsDQogICJ4MjEiID0gIkNvbnN1bW8gcHJpdmFkbyAodm9sdW1lbiwgY3JlY2ltaWVudG8pIiwNCiAgIngyMiIgPSAiQ29uc3VtbyBnb2JpZXJubyAodm9sdW1lbiwgY3JlY2ltaWVudG8pIiwNCiAgIngyNSIgPSAiRGVmbGFjdG9yIGRlbCBQSUIgKHByZWNpb3MgbWVyY2FkbykiLA0KICAieDI2IiA9ICJUYXNhIGRlIGRlc2VtcGxlbyIsDQogICJ4MjciID0gIkVtcGxlbyB0b3RhbCAoZW5jdWVzdGEgZnVlcnphIGxhYm9yYWwpIiwNCiAgIngyOCIgPSAiRnVlcnphIGxhYm9yYWwiDQopDQoNCnZhcmlhYmxlcyA8LSBjKCJ4MjYiLCAieDI3IiwgIngyOCIsICJ4MTciLCAieDIxIiwgIngyMiIsIA0KICAgICAgICAgICAgICAgIngyMCIsICJ4MTkiLCAieDE1IiwgIngxNiIsICJ4MSIsICJ4OCIsIA0KICAgICAgICAgICAgICAgIngyIiwgIngxOCIsICJ4MjUiKQ0KDQp2YXJzX3BvcmNlbnRhamUgPC0gYygieDI2IiwgIngxNyIsICJ4MjEiLCAieDIyIiwgIngyMCIsICJ4MTkiLCAieDE1IiwgIngxNiIsICJ4MSIsICJ4OCIsICJ4MTgiLCAieDI1IikNCnZhcnNfbWlsZXMgPC0gYygieDI3IiwgIngyOCIsICJ4MiIpDQoNCmRhdG9zX3RhYmxhIDwtIERhdG9zRWNvbiAlPiUNCiAgc2VsZWN0KFBhaXMsIGFsbF9vZih2YXJpYWJsZXMpKQ0KDQpkYXRvc190YWJsYSA8LSBkYXRvc190YWJsYSAlPiUNCiAgbXV0YXRlKGFjcm9zcyhhbGxfb2YodmFyc19wb3JjZW50YWplKSwgDQogICAgICAgICAgICAgICAgfiBpZmVsc2UoaXMubmEoLiksIE5BLCBwYXN0ZTAocm91bmQoLnggKiAxMDAsIDEpLCAiJSIpKSkpICU+JQ0KICBtdXRhdGUoYWNyb3NzKGFsbF9vZih2YXJzX21pbGVzKSwNCiAgICAgICAgICAgICAgICB+IGlmZWxzZShpcy5uYSguKSwgTkEsIGZvcm1hdChyb3VuZCgueCwgMCksIGJpZy5tYXJrID0gIi4iLCBkZWNpbWFsLm1hcmsgPSAiLCIpKSkpDQoNCm5vbWJyZXNfcmVuYW1lIDwtIHNldE5hbWVzKG5hbWVzKHZhcmlhYmxlc25vbWJyZXMpLCB2YXJpYWJsZXNub21icmVzKQ0KZGF0b3NfdGFibGEgPC0gZGF0b3NfdGFibGEgJT4lIHJlbmFtZSghISFub21icmVzX3JlbmFtZSkNCg0KZ3QoZGF0b3NfdGFibGEpICU+JQ0KICB0YWJfaGVhZGVyKA0KICAgIHRpdGxlID0gbWQoIioqQmFzZSBkZSBkYXRvcyBlY29uw7NtaWNvcyoqIiksDQogICAgc3VidGl0bGUgPSAiVmFyaWFibGVzIHNlbGVjY2lvbmFkYXMgKHByaW1lcm9zIDEwIHBhw61zZXMpIg0KICApICU+JQ0KICBjb2xzX2xhYmVsKFBhaXMgPSAiUGHDrXMiKSAlPiUNCiAgdGFiX3N0eWxlKA0KICAgIHN0eWxlID0gbGlzdCgNCiAgICAgIGNlbGxfZmlsbChjb2xvciA9ICIjRDgxQjYwIiksDQogICAgICBjZWxsX3RleHQoY29sb3IgPSAid2hpdGUiLCB3ZWlnaHQgPSAiYm9sZCIpDQogICAgKSwNCiAgICBsb2NhdGlvbnMgPSBjZWxsc19jb2x1bW5fbGFiZWxzKGV2ZXJ5dGhpbmcoKSkNCiAgKSAlPiUNCiAgdGFiX3N0eWxlKA0KICAgIHN0eWxlID0gbGlzdCgNCiAgICAgIGNlbGxfZmlsbChjb2xvciA9ICIjRkNFNEVDIiksDQogICAgICBjZWxsX3RleHQoY29sb3IgPSAiYmxhY2siKQ0KICAgICksDQogICAgbG9jYXRpb25zID0gY2VsbHNfYm9keShyb3dzID0gZXZlcnl0aGluZygpKQ0KICApICU+JQ0KICBvcHRfcm93X3N0cmlwaW5nKCkgJT4lDQogIHRhYl9vcHRpb25zKA0KICAgIHRhYmxlLndpZHRoID0gcGN0KDEwMCksDQogICAgdGFibGUuZm9udC5zaXplID0gInNtYWxsIiwNCiAgICBoZWFkaW5nLnRpdGxlLmZvbnQuc2l6ZSA9ICJsYXJnZSIsDQogICAgcm93LnN0cmlwaW5nLmJhY2tncm91bmRfY29sb3IgPSAiI0Y4QkJEOSIsDQogICAgdGFibGUuYm9yZGVyLnRvcC5jb2xvciA9ICIjRDgxQjYwIiwNCiAgICB0YWJsZS5ib3JkZXIuYm90dG9tLmNvbG9yID0gIiNEODFCNjAiLA0KICAgIGNvbnRhaW5lci5oZWlnaHQgPSBweCg0MDApLCAgICAgICAgIyA8LSBhbHR1cmEgZmlqYSBkZWwgY29udGVuZWRvcg0KICAgIGNvbnRhaW5lci5vdmVyZmxvdy55ID0gImF1dG8iICAgICAgIyA8LSBzY3JvbGwgdmVydGljYWwgYXV0b23DoXRpY28NCiAgKSAlPiUNCiAgdGFiX3NvdXJjZV9ub3RlKCJGdWVudGU6IERhdG9zIGVjb27Ds21pY29zIC0gRWxhYm9yYWNpw7NuIHByb3BpYSIpDQoNCmRhdG9zX3BjYSA8LSBhcy5kYXRhLmZyYW1lKG5hLm9taXQoRGF0b3NFY29uWywgdmFyaWFibGVzXSkpDQpkYXRvc19zY2FsZWQgPC0gYXMuZGF0YS5mcmFtZShzY2FsZShkYXRvc19wY2EpKQ0KYGBgDQoNCiMjIDMuMSBDbGFzaWZpY2FjacOzbiBkaW1lbnNpb25lcw0KDQoNCiMjIyAzLjEuMSBEaW1lbnNpw7NuIGRlIE1lcmNhZG8gTGFib3JhbA0KDQpgYGB7ciBkaW1lbnNpb24gbyB0YWJsYSAxLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KdGFibGFfbGFib3JhbCA8LSBkYXRhLmZyYW1lKA0KICBDw7NkaWdvID0gYygieDI2IiwgIngyNyIsICJ4MjgiKSwNCiAgVmFyaWFibGUgPSBjKHZhcmlhYmxlc25vbWJyZXNbIngyNiJdLCB2YXJpYWJsZXNub21icmVzWyJ4MjciXSwgdmFyaWFibGVzbm9tYnJlc1sieDI4Il0pLA0KICBEZXNjcmlwY2lvbiA9IGMoDQogICAgIkluZGljYWRvciBwcmluY2lwYWwgZGVsIG1lcmNhZG8gbGFib3JhbC4gU2Vnw7puIE9FQ0QgRW1wbG95bWVudCBPdXRsb29rIDIwMjQsIHRhc2FzIGJhamFzIHJlZmxlamFuIHJlc2lsaWVuY2lhIHkgbWVyY2Fkb3MgYWp1c3RhZG9zLiIsDQogICAgIlJlZmxlamEgbGEgY2FwYWNpZGFkIGRlIGdlbmVyYWNpw7NuIGRlIHB1ZXN0b3MgZGUgdHJhYmFqbyBmb3JtYWxlcyBlIGluZm9ybWFsZXMuIEJhc2UgcGFyYSBwb2zDrXRpY2FzIGRlIGVtcGxlby4iLA0KICAgICINCiAgICBEZXRlcm1pbmEgZWwgdGFtYcOxbyBkZSBsYSBvZmVydGEgbGFib3JhbCB5IGxhIHRhc2EgZGUgcGFydGljaXBhY2nDs24uIg0KICApDQopDQoNCmd0KHRhYmxhX2xhYm9yYWwpICU+JQ0KICB0YWJfaGVhZGVyKA0KICAgIHRpdGxlID0gIkRpbWVuc2nDs24gMTogTWVyY2FkbyBMYWJvcmFsIiwNCiAgICBzdWJ0aXRsZSA9ICJPRUNEIEVtcGxveW1lbnQgT3V0bG9vayAyMDI0Ig0KICApICU+JQ0KDQogIHRhYl9zdHlsZSgNCiAgICBzdHlsZSA9IGxpc3QoDQogICAgICBjZWxsX2ZpbGwoY29sb3IgPSAiI0Q4MUI2MCIpLA0KICAgICAgY2VsbF90ZXh0KGNvbG9yID0gIndoaXRlIiwgd2VpZ2h0ID0gImJvbGQiKQ0KICAgICksDQogICAgbG9jYXRpb25zID0gY2VsbHNfY29sdW1uX2xhYmVscyhldmVyeXRoaW5nKCkpDQogICkgJT4lDQoNCiAgdGFiX3N0eWxlKA0KICAgIHN0eWxlID0gY2VsbF9maWxsKGNvbG9yID0gIndoaXRlIiksDQogICAgbG9jYXRpb25zID0gY2VsbHNfYm9keShyb3dzID0gMSkNCiAgKSAlPiUNCg0KICB0YWJfc3R5bGUoDQogICAgc3R5bGUgPSBjZWxsX2ZpbGwoY29sb3IgPSAiI0ZDRTRFQyIpLA0KICAgIGxvY2F0aW9ucyA9IGNlbGxzX2JvZHkocm93cyA9IDIpDQogICkgJT4lDQoNCiAgdGFiX3N0eWxlKA0KICAgIHN0eWxlID0gY2VsbF9maWxsKGNvbG9yID0gIiNGOEJCRDkiKSwNCiAgICBsb2NhdGlvbnMgPSBjZWxsc19ib2R5KHJvd3MgPSAzKQ0KICApICU+JQ0KDQogIHRhYl9vcHRpb25zKA0KICAgIHRhYmxlLndpZHRoID0gcGN0KDEwMCksDQogICAgdGFibGUuZm9udC5zaXplID0gInNtYWxsIiwNCiAgICBoZWFkaW5nLmJhY2tncm91bmQuY29sb3IgPSAiI0Y0OEZCMSINCiAgKSAlPiUNCg0KICB0YWJfc291cmNlX25vdGUoDQogICAgc291cmNlX25vdGUgPSAiTm90YTogSW50ZXJwcmV0YWNpb25lcyBiYXNhZGFzIGVuIE9FQ0QgRWNvbm9taWMgT3V0bG9vayB5IEVtcGxveW1lbnQgT3V0bG9vayAyMDI0LiINCiAgKQ0KYGBgDQoNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnk7Ij5TZWfDum4gbGEgT0VDRCBFbXBsb3ltZW50IE91dGxvb2sgMjAyNCwgbGEgdGFzYSBkZSBkZXNlbXBsZW8sIGVsIGVtcGxlbyB0b3RhbCB5IGxhIGZ1ZXJ6YSBsYWJvcmFsIGNvbnN0aXR1eWVuIGluZGljYWRvcmVzIGZ1bmRhbWVudGFsZXMgcGFyYSBldmFsdWFyIGVsIGRlc2VtcGXDsW8gZGVsIG1lcmNhZG8gbGFib3JhbC4gRXN0YXMgdmFyaWFibGVzICoqcGVybWl0ZW4gYW5hbGl6YXIgbGEgY2FwYWNpZGFkIGRlIGxhcyBlY29ub23DrWFzIHBhcmEgZ2VuZXJhciBlbXBsZW8sIGVsIG5pdmVsIGRlIHBhcnRpY2lwYWNpw7NuIGRlIGxhIHBvYmxhY2nDs24gZW4gYWN0aXZpZGFkZXMgcHJvZHVjdGl2YXMgeSBsYXMgY29uZGljaW9uZXMgZ2VuZXJhbGVzIGRlIGluc2VyY2nDs24gbGFib3JhbCoqLiBFbCBjb21wb3J0YW1pZW50byBkZWwgbWVyY2FkbyBkZSB0cmFiYWpvIHNlIGVuY3VlbnRyYSBlc3RyZWNoYW1lbnRlIHJlbGFjaW9uYWRvIGNvbiBlbCBjcmVjaW1pZW50byBlY29uw7NtaWNvLCBsYSBwcm9kdWN0aXZpZGFkIHkgZWwgYmllbmVzdGFyIGRlIGxhIHBvYmxhY2nDs24uPC9kaXY+DQoNCiMjIyAzLjEuMiBEaW1lbnNpw7NuIGRlIENyZWNpbWllbnRvIEVjb27Ds21pY28NCg0KYGBge3IgZGltZW5zaW9uIG8gdGFibGEgMiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnRhYmxhX2NyZWNpbWllbnRvIDwtIGRhdGEuZnJhbWUoDQogIEPDs2RpZ28gPSBjKCJ4MTciLCAieDE4IiwgIng4IiksDQogIFZhcmlhYmxlID0gYyh2YXJpYWJsZXNub21icmVzWyJ4MTciXSwgdmFyaWFibGVzbm9tYnJlc1sieDE4Il0sIHZhcmlhYmxlc25vbWJyZXNbIng4Il0pLA0KICBEZXNjcmlwY2lvbiA9IGMoDQogICAgIk1pZGUgbGEgZXhwYW5zacOzbiByZWFsIGRlIGxhIGVjb25vbcOtYS4gT0VDRCBFY29ub21pYyBPdXRsb29rIDIwMjQ6IGNyZWNpbWllbnRvIGdsb2JhbCBlc3RhYmxlICgzLjMlIGVuIDIwMjUtMjAyNikuIiwNCiAgICAiQ3JlY2ltaWVudG8gZW4gcHJlY2lvcyBjb3JyaWVudGVzLiBSZWZsZWphIGxhIGV2b2x1Y2nDs24gbm9taW5hbCBkZWwgUElCLCBpbmNsdXllbmRvIGVmZWN0b3MgZGUgcHJlY2lvcy4iLA0KICAgICJDb250cmlidWNpw7NuIGRlbCBzZWN0b3IgZXh0ZXJubyBhbCBjcmVjaW1pZW50by4gRXhwb3J0YWNpb25lcyBuZXRhcyBjb21vIHBvcmNlbnRhamUgZGVsIFBJQiByZWFsLiIpKSANCg0KdGFibGFfY3JlY2ltaWVudG9bXSA8LSBsYXBwbHkoDQogIHRhYmxhX2NyZWNpbWllbnRvLA0KICBmdW5jdGlvbih4KSBpZiAoaXMuY2hhcmFjdGVyKHgpKSBpY29udih4LCBmcm9tID0gIiIsIHRvID0gIlVURi04Iiwgc3ViID0gIiIpIGVsc2UgeCkNCg0KZ3QodGFibGFfY3JlY2ltaWVudG8pICU+JQ0KICB0YWJfaGVhZGVyKA0KICAgIHRpdGxlID0gIkRpbWVuc2nDs24gMjogQ3JlY2ltaWVudG8gRWNvbsOzbWljbyIsDQogICAgc3VidGl0bGUgPSAiT0VDRCBFY29ub21pYyBPdXRsb29rIDIwMjQiDQogICkgJT4lDQogIHRhYl9zdHlsZSgNCiAgICBzdHlsZSA9IGxpc3QoDQogICAgICBjZWxsX2ZpbGwoY29sb3IgPSAiI0Q4MUI2MCIpLA0KICAgICAgY2VsbF90ZXh0KGNvbG9yID0gIndoaXRlIiwgd2VpZ2h0ID0gImJvbGQiKQ0KICAgICksDQogICAgbG9jYXRpb25zID0gY2VsbHNfY29sdW1uX2xhYmVscyhldmVyeXRoaW5nKCkpDQogICkgJT4lDQogIHRhYl9zdHlsZSgNCiAgICBzdHlsZSA9IGNlbGxfZmlsbChjb2xvciA9ICJ3aGl0ZSIpLA0KICAgIGxvY2F0aW9ucyA9IGNlbGxzX2JvZHkocm93cyA9IDEpDQogICkgJT4lDQogIHRhYl9zdHlsZSgNCiAgICBzdHlsZSA9IGNlbGxfZmlsbChjb2xvciA9ICIjRkNFNEVDIiksDQogICAgbG9jYXRpb25zID0gY2VsbHNfYm9keShyb3dzID0gMikNCiAgKSAlPiUNCiAgdGFiX3N0eWxlKA0KICAgIHN0eWxlID0gY2VsbF9maWxsKGNvbG9yID0gIiNGOEJCRDkiKSwNCiAgICBsb2NhdGlvbnMgPSBjZWxsc19ib2R5KHJvd3MgPSAzKQ0KICApICU+JQ0KICB0YWJfb3B0aW9ucygNCiAgICB0YWJsZS53aWR0aCA9IHBjdCgxMDApLA0KICAgIHRhYmxlLmZvbnQuc2l6ZSA9ICJzbWFsbCIsDQogICAgaGVhZGluZy5iYWNrZ3JvdW5kLmNvbG9yID0gIiNGNDhGQjEiDQogICkgJT4lDQogIHRhYl9zb3VyY2Vfbm90ZSgNCiAgICBzb3VyY2Vfbm90ZSA9ICJOb3RhOiBJbnRlcnByZXRhY2lvbmVzIGJhc2FkYXMgZW4gT0VDRCBFY29ub21pYyBPdXRsb29rIHkgRW1wbG95bWVudCBPdXRsb29rIDIwMjQuIg0KICApDQpgYGANCg0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeTsiPkRlIGFjdWVyZG8gY29uIGxhIE9FQ0QgRWNvbm9taWMgT3V0bG9vayAyMDI0LCBlbCBjcmVjaW1pZW50byBkZWwgUElCIHJlYWwgeSBkZWwgUElCIG5vbWluYWwgc29uIGluZGljYWRvcmVzIGZ1bmRhbWVudGFsZXMgcGFyYSBldmFsdWFyIGVsIGRlc2VtcGXDsW8gZWNvbsOzbWljbyBkZSBsb3MgcGHDrXNlcy4gTWllbnRyYXMgcXVlIGVsIGNyZWNpbWllbnRvIHJlYWwgcGVybWl0ZSBhbmFsaXphciBsYSBldm9sdWNpw7NuIGRlIGxhIHByb2R1Y2Npw7NuIGRlc2NvbnRhbmRvIGVsIGVmZWN0byBkZSBsb3MgcHJlY2lvcywgZWwgY3JlY2ltaWVudG8gbm9taW5hbCBpbmNvcnBvcmEgdGFudG8gbG9zIGNhbWJpb3MgZW4gbGEgcHJvZHVjY2nDs24gY29tbyBsYXMgdmFyaWFjaW9uZXMgZGUgcHJlY2lvcyBpZGVudGlmaWNhbmRvIGRpZmVyZW5jaWFzIGVuIGVsIHJpdG1vIGRlIGV4cGFuc2nDs24gZWNvbsOzbWljYSBlbnRyZSBsb3MgcGHDrXNlcyBhbmFsaXphZG9zIHkgY29tcHJlbmRlciB1bmEgZGUgbGFzIGRpbWVuc2lvbmVzIG3DoXMgcmVsZXZhbnRlcyBwYXJhIGV4cGxpY2FyIGxhcyBkaXNwYXJpZGFkZXMgb2JzZXJ2YWRhcyBlbiBzdSBkZXNlbXBlw7FvIGVjb27Ds21pY28uPC9kaXY+DQoNCiMjIyAzLjEuMyBEaW1lbnNpw7NuIGRlIFByZWNpb3MgZSBJbmZsYWNpw7NuDQoNCmBgYHtyIGRpbWVuc2lvbiBvIHRhYmxhIDMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQp0YWJsYV9wcmVjaW9zIDwtIGRhdGEuZnJhbWUoDQogIEPDs2RpZ28gPSBjKCJ4MTkiLCAieDI1IiwgIngyIiksDQogIFZhcmlhYmxlID0gYyh2YXJpYWJsZXNub21icmVzWyJ4MTkiXSwgdmFyaWFibGVzbm9tYnJlc1sieDI1Il0sIHZhcmlhYmxlc25vbWJyZXNbIngyIl0pLA0KICBEZXNjcmlwY2lvbiA9IGMoDQogICAgIlZhcmlhY2nDs24gYW51YWwgZGVsIGRlZmxhY3RvciBkZWwgUElCLiBJbmRpY2Fkb3IgYW1wbGlvIGRlIGluZmxhY2nDs24uIE9FQ0Q6IGluZmxhY2nDs24gZW4gZGVzY2Vuc28gKDUuNCUgZW4gMjAyNCBhIDMuMyUgZW4gMjAyNSkuIiwNCiAgICAiRGVmbGFjdG9yIGRlbCBQSUIgYSBwcmVjaW9zIGRlIG1lcmNhZG8uIFJlZmxlamEgbG9zIGNhbWJpb3MgZW4gbG9zIHByZWNpb3MgZGUgdG9kb3MgbG9zIGJpZW5lcyB5IHNlcnZpY2lvcyBwcm9kdWNpZG9zLiIsDQogICAgIlByZWNpbyBkZSBsYSBtb25lZGEgbG9jYWwgZnJlbnRlIGFsIGTDs2xhci4gQWZlY3RhIGxhIGNvbXBldGl0aXZpZGFkIHkgbGEgaW5mbGFjacOzbiBpbXBvcnRhZGEuIg0KICApDQopDQoNCmd0KHRhYmxhX3ByZWNpb3MpICU+JQ0KICB0YWJfaGVhZGVyKA0KICAgIHRpdGxlID0gIkRpbWVuc2nDs24gMzogUHJlY2lvcyBlIEluZmxhY2nDs24iLA0KICAgIHN1YnRpdGxlID0gIk9FQ0QgRWNvbm9taWMgT3V0bG9vayAyMDI0Ig0KICApICU+JQ0KICB0YWJfc3R5bGUoDQogICAgc3R5bGUgPSBsaXN0KA0KICAgICAgY2VsbF9maWxsKGNvbG9yID0gIiNEODFCNjAiKSwNCiAgICAgIGNlbGxfdGV4dChjb2xvciA9ICJ3aGl0ZSIsIHdlaWdodCA9ICJib2xkIikNCiAgICApLA0KICAgIGxvY2F0aW9ucyA9IGNlbGxzX2NvbHVtbl9sYWJlbHMoZXZlcnl0aGluZygpKQ0KICApICU+JQ0KICB0YWJfc3R5bGUoDQogICAgc3R5bGUgPSBjZWxsX2ZpbGwoY29sb3IgPSAid2hpdGUiKSwNCiAgICBsb2NhdGlvbnMgPSBjZWxsc19ib2R5KHJvd3MgPSAxKQ0KICApICU+JQ0KICB0YWJfc3R5bGUoDQogICAgc3R5bGUgPSBjZWxsX2ZpbGwoY29sb3IgPSAiI0ZDRTRFQyIpLA0KICAgIGxvY2F0aW9ucyA9IGNlbGxzX2JvZHkocm93cyA9IDIpDQogICkgJT4lDQogIHRhYl9zdHlsZSgNCiAgICBzdHlsZSA9IGNlbGxfZmlsbChjb2xvciA9ICIjRjhCQkQ5IiksDQogICAgbG9jYXRpb25zID0gY2VsbHNfYm9keShyb3dzID0gMykNCiAgKSAlPiUNCiAgdGFiX29wdGlvbnMoDQogICAgdGFibGUud2lkdGggPSBwY3QoMTAwKSwNCiAgICB0YWJsZS5mb250LnNpemUgPSAic21hbGwiLA0KICAgIGhlYWRpbmcuYmFja2dyb3VuZC5jb2xvciA9ICIjRjQ4RkIxIg0KICApICU+JQ0KICB0YWJfc291cmNlX25vdGUoDQogICAgc291cmNlX25vdGUgPSAiTm90YTogSW50ZXJwcmV0YWNpb25lcyBiYXNhZGFzIGVuIE9FQ0QgRWNvbm9taWMgT3V0bG9vayB5IEVtcGxveW1lbnQgT3V0bG9vayAyMDI0LiINCiAgKQ0KYGBgDQoNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnk7Ij5FbCBjcmVjaW1pZW50byBkZWwgZGVmbGFjdG9yIGRlbCBQSUIsIGVsIGRlZmxhY3RvciBkZWwgUElCIGEgcHJlY2lvcyBkZSBtZXJjYWRvIHkgZWwgdGlwbyBkZSBjYW1iaW8gc29uIGluZGljYWRvcmVzIHJlbGV2YW50ZXMgcGFyYSBhbmFsaXphciBsYSBlc3RhYmlsaWRhZCBtYWNyb2Vjb27Ds21pY2EgeSBsYSBldm9sdWNpw7NuIGRlIGxvcyBwcmVjaW9zIGRlbnRybyBkZSB1bmEgZWNvbm9tw61hIHNlZ8O6biBMYSBPRUNEIEVjb25vbWljIE91dGxvb2sgMjAyNC4gRXN0YXMgdmFyaWFibGVzIHBlcm1pdGVuIGV2YWx1YXIgbGFzIHByZXNpb25lcyBpbmZsYWNpb25hcmlhcywgbG9zIGNhbWJpb3MgZW4gbG9zIG5pdmVsZXMgZ2VuZXJhbGVzIGRlIHByZWNpb3MgeSBsYXMgdmFyaWFjaW9uZXMgZW4gZWwgdmFsb3IgZGUgbGEgbW9uZWRhIGZyZW50ZSBhbCBkw7NsYXIgZXN0YWRvdW5pZGVuc2UsIGZhY3RvcmVzIHF1ZSBpbmZsdXllbiBkaXJlY3RhbWVudGUgc29icmUgZWwgcG9kZXIgYWRxdWlzaXRpdm8sIGxhIGNvbXBldGl0aXZpZGFkIGludGVybmFjaW9uYWwgeSBsYXMgY29uZGljaW9uZXMgZGUgY3JlY2ltaWVudG8gZWNvbsOzbWljby48L2Rpdj4NCg0KIyMjIDMuMS40IERpbWVuc2nDs24gZGUgRGVtYW5kYSBJbnRlcm5hDQoNCmBgYHtyIGRpbWVuc2lvbiBvIHRhYmxhIDQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQp0YWJsYV9kZW1hbmRhIDwtIGRhdGEuZnJhbWUoDQogIEPDs2RpZ28gPSBjKCJ4MjEiLCAieDIyIiwgIngyMCIpLA0KICBWYXJpYWJsZSA9IGModmFyaWFibGVzbm9tYnJlc1sieDIxIl0sIHZhcmlhYmxlc25vbWJyZXNbIngyMiJdLCB2YXJpYWJsZXNub21icmVzWyJ4MjAiXSksDQogIERlc2NyaXBjaW9uID0gYygNCiAgICAiQ29uc3VtbyBkZSBsb3MgaG9nYXJlcy4gTW90b3IgcHJpbmNpcGFsIGRlbCBjcmVjaW1pZW50by4gT0VDRCAyMDI0OiByZXNwYWxkYWRvIHBvciBpbmdyZXNvcyByZWFsZXMgeSBtZXJjYWRvIGxhYm9yYWwgcmVzaWxpZW50ZS4iLA0KICAgICJDb25zdW1vIGRlbCBnb2JpZXJuby4gR2FzdG8gcMO6YmxpY28gZW4gYmllbmVzIHkgc2VydmljaW9zLiBQb2zDrXRpY2EgZmlzY2FsIHkgcHJvdmlzacOzbiBkZSBzZXJ2aWNpb3MgcMO6YmxpY29zLiIsDQogICAgIkZvcm1hY2nDs24gYnJ1dGEgZGUgY2FwaXRhbCAoaW52ZXJzacOzbikuIFJlZmxlamEgbGEgYWN1bXVsYWNpw7NuIGRlIGFjdGl2b3MgZmlqb3MuIENsYXZlIHBhcmEgbGEgY2FwYWNpZGFkIHByb2R1Y3RpdmEgZnV0dXJhLiIpKQ0KDQp0YWJsYV9kZW1hbmRhW10gPC0gbGFwcGx5KA0KICB0YWJsYV9jcmVjaW1pZW50bywNCiAgZnVuY3Rpb24oeCkgaWYgKGlzLmNoYXJhY3Rlcih4KSkgaWNvbnYoeCwgZnJvbSA9ICIiLCB0byA9ICJVVEYtOCIsIHN1YiA9ICIiKSBlbHNlIHgpDQoNCmd0KHRhYmxhX2RlbWFuZGEpICU+JQ0KICB0YWJfaGVhZGVyKA0KICAgIHRpdGxlID0gIkRpbWVuc2nDs24gNDogRGVtYW5kYSBJbnRlcm5hIiwNCiAgICBzdWJ0aXRsZSA9ICJPRUNEIEVjb25vbWljIE91dGxvb2sgMjAyNCINCiAgKSAlPiUNCiAgdGFiX3N0eWxlKA0KICAgIHN0eWxlID0gbGlzdCgNCiAgICAgIGNlbGxfZmlsbChjb2xvciA9ICIjRDgxQjYwIiksDQogICAgICBjZWxsX3RleHQoY29sb3IgPSAid2hpdGUiLCB3ZWlnaHQgPSAiYm9sZCIpDQogICAgKSwNCiAgICBsb2NhdGlvbnMgPSBjZWxsc19jb2x1bW5fbGFiZWxzKGV2ZXJ5dGhpbmcoKSkNCiAgKSAlPiUNCiAgdGFiX3N0eWxlKA0KICAgIHN0eWxlID0gY2VsbF9maWxsKGNvbG9yID0gIndoaXRlIiksDQogICAgbG9jYXRpb25zID0gY2VsbHNfYm9keShyb3dzID0gMSkNCiAgKSAlPiUNCiAgdGFiX3N0eWxlKA0KICAgIHN0eWxlID0gY2VsbF9maWxsKGNvbG9yID0gIiNGQ0U0RUMiKSwNCiAgICBsb2NhdGlvbnMgPSBjZWxsc19ib2R5KHJvd3MgPSAyKQ0KICApICU+JQ0KICB0YWJfc3R5bGUoDQogICAgc3R5bGUgPSBjZWxsX2ZpbGwoY29sb3IgPSAiI0Y4QkJEOSIpLA0KICAgIGxvY2F0aW9ucyA9IGNlbGxzX2JvZHkocm93cyA9IDMpDQogICkgJT4lDQogIHRhYl9vcHRpb25zKA0KICAgIHRhYmxlLndpZHRoID0gcGN0KDEwMCksDQogICAgdGFibGUuZm9udC5zaXplID0gInNtYWxsIiwNCiAgICBoZWFkaW5nLmJhY2tncm91bmQuY29sb3IgPSAiI0Y0OEZCMSINCiAgKSAlPiUNCiAgdGFiX3NvdXJjZV9ub3RlKA0KICAgIHNvdXJjZV9ub3RlID0gIk5vdGE6IEludGVycHJldGFjaW9uZXMgYmFzYWRhcyBlbiBPRUNEIEVjb25vbWljIE91dGxvb2sgeSBFbXBsb3ltZW50IE91dGxvb2sgMjAyNC4iDQogICkNCmBgYA0KDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5OyI+TGEgZm9ybWFjacOzbiBicnV0YSBkZSBjYXBpdGFsIGZpam8sIGVsIGNvbnN1bW8gcHJpdmFkbyB5IGVsIGNvbnN1bW8gcMO6YmxpY28gcmVwcmVzZW50YW4gYWxndW5vcyBkZSBsb3MgcHJpbmNpcGFsZXMgY29tcG9uZW50ZXMgZGUgbGEgZGVtYW5kYSBpbnRlcm5hIGRlIHVuYSBlY29ub23DrWEuIEVzdGFzIHZhcmlhYmxlcyBwZXJtaXRlbiBhbmFsaXphciBsYSBjYXBhY2lkYWQgZGUgaW52ZXJzacOzbiwgZWwgY29tcG9ydGFtaWVudG8gZGVsIGdhc3RvIGRlIGxvcyBob2dhcmVzIHkgbGEgcGFydGljaXBhY2nDs24gZGVsIHNlY3RvciBww7pibGljbyBlbiBsYSBhY3RpdmlkYWQgZWNvbsOzbWljYSwgZmFjdG9yZXMgcXVlIGluZmx1eWVuIGRpcmVjdGFtZW50ZSBzb2JyZSBlbCBjcmVjaW1pZW50byB5IGxhIGRpbsOhbWljYSBwcm9kdWN0aXZhIGRlIGxvcyBwYcOtc2VzLiBTZWfDum4gbGEgT0VDRCBFY29ub21pYyBPdXRsb29rIDIwMjQsICoqdGFudG8gbGEgaW52ZXJzacOzbiBjb21vIGVsIGNvbnN1bW8gY29udGluw7phbiBzaWVuZG8gZWxlbWVudG9zIGZ1bmRhbWVudGFsZXMgcGFyYSBzb3N0ZW5lciBlbCBjcmVjaW1pZW50byBlY29uw7NtaWNvIGVuIGVsIG1lZGlhbm8gcGxhem8qKjwvZGl2Pg0KDQojIyMgMy4xLjUgRGltZW5zacOzbiBkZSBDb21lcmNpbyBleHRlcmlvcg0KDQpgYGB7ciBkaW1lbnNpb24gbyB0YWJsYSA1LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KdGFibGFfY29tZXJjaW8gPC0gZGF0YS5mcmFtZSgNCiAgQ8OzZGlnbyA9IGMoIngxNSIsICJ4MTYiLCAieDEiKSwNCiAgVmFyaWFibGUgPSBjKHZhcmlhYmxlc25vbWJyZXNbIngxNSJdLCB2YXJpYWJsZXNub21icmVzWyJ4MTYiXSwgdmFyaWFibGVzbm9tYnJlc1sieDEiXSksDQogIERlc2NyaXBjaW9uID0gYygNCiAgICAiQ3JlY2ltaWVudG8gZGVsIHZvbHVtZW4gZGUgZXhwb3J0YWNpb25lcy4gTWlkZSBsYSBkZW1hbmRhIGV4dGVybmEgZGUgYmllbmVzIG5hY2lvbmFsZXMuIE9FQ0Q6IHJlY3VwZXJhY2nDs24gZGVsIGNvbWVyY2lvIGdsb2JhbCBtw6FzIHLDoXBpZGEgZGUgbG8gZXNwZXJhZG8uIiwNCiAgICAiQ3JlY2ltaWVudG8gZGVsIHZvbHVtZW4gZGUgaW1wb3J0YWNpb25lcy4gUmVmbGVqYSBsYSBkZW1hbmRhIGludGVybmEgZGUgYmllbmVzIGV4dHJhbmplcm9zIHkgbGEgaW50ZWdyYWNpw7NuIGdsb2JhbC4iLA0KICAgICJTYWxkbyBkZSBsYSBiYWxhbnphIHBvciBjdWVudGEgY29ycmllbnRlICglIFBJQikuIEluZGljYSBzaSBlbCBwYcOtcyBlcyBwcmVzdGFtaXN0YSBvIGRldWRvciBuZXRvIGNvbiBlbCByZXN0byBkZWwgbXVuZG8uIg0KICApDQopDQoNCmd0KHRhYmxhX2NvbWVyY2lvKSAlPiUNCiAgdGFiX2hlYWRlcigNCiAgICB0aXRsZSA9ICJEaW1lbnNpw7NuIDU6IENvbWVyY2lvIEV4dGVyaW9yIiwNCiAgICBzdWJ0aXRsZSA9ICJPRUNEIEVjb25vbWljIE91dGxvb2sgMjAyNCINCiAgKSAlPiUNCiAgdGFiX3N0eWxlKA0KICAgIHN0eWxlID0gbGlzdCgNCiAgICAgIGNlbGxfZmlsbChjb2xvciA9ICIjRDgxQjYwIiksDQogICAgICBjZWxsX3RleHQoY29sb3IgPSAid2hpdGUiLCB3ZWlnaHQgPSAiYm9sZCIpDQogICAgKSwNCiAgICBsb2NhdGlvbnMgPSBjZWxsc19jb2x1bW5fbGFiZWxzKGV2ZXJ5dGhpbmcoKSkNCiAgKSAlPiUNCiAgdGFiX3N0eWxlKA0KICAgIHN0eWxlID0gY2VsbF9maWxsKGNvbG9yID0gIndoaXRlIiksDQogICAgbG9jYXRpb25zID0gY2VsbHNfYm9keShyb3dzID0gMSkNCiAgKSAlPiUNCiAgdGFiX3N0eWxlKA0KICAgIHN0eWxlID0gY2VsbF9maWxsKGNvbG9yID0gIiNGQ0U0RUMiKSwNCiAgICBsb2NhdGlvbnMgPSBjZWxsc19ib2R5KHJvd3MgPSAyKQ0KICApICU+JQ0KICB0YWJfc3R5bGUoDQogICAgc3R5bGUgPSBjZWxsX2ZpbGwoY29sb3IgPSAiI0Y4QkJEOSIpLA0KICAgIGxvY2F0aW9ucyA9IGNlbGxzX2JvZHkocm93cyA9IDMpDQogICkgJT4lDQogIHRhYl9vcHRpb25zKA0KICAgIHRhYmxlLndpZHRoID0gcGN0KDEwMCksDQogICAgdGFibGUuZm9udC5zaXplID0gInNtYWxsIiwNCiAgICBoZWFkaW5nLmJhY2tncm91bmQuY29sb3IgPSAiI0Y0OEZCMSINCiAgKSAlPiUNCiAgdGFiX3NvdXJjZV9ub3RlKA0KICAgIHNvdXJjZV9ub3RlID0gIk5vdGE6IEludGVycHJldGFjaW9uZXMgYmFzYWRhcyBlbiBPRUNEIEVjb25vbWljIE91dGxvb2sgeSBFbXBsb3ltZW50IE91dGxvb2sgMjAyNC4iDQogICkNCmBgYA0KDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5OyI+TGFzIGV4cG9ydGFjaW9uZXMsIGxhcyBpbXBvcnRhY2lvbmVzLCBlbCBzYWxkbyBkZSBjdWVudGEgY29ycmllbnRlIGNvbW8gcG9yY2VudGFqZSBkZWwgUElCIHkgbGEgY29udHJpYnVjacOzbiBkZSBsYXMgZXhwb3J0YWNpb25lcyBuZXRhcyBhbCBQSUIgcmVhbCBwZXJtaXRlbiBhbmFsaXphciBsYSByZWxhY2nDs24gZGUgY2FkYSBlY29ub23DrWEgY29uIGVsIHNlY3RvciBleHRlcm5vIHkgc3UgcGFydGljaXBhY2nDs24gZW4gZWwgY29tZXJjaW8gaW50ZXJuYWNpb25hbC4gRXN0b3MgaW5kaWNhZG9yZXMgcHJvcG9yY2lvbmFuIGluZm9ybWFjacOzbiBzb2JyZSBlbCBncmFkbyBkZSBhcGVydHVyYSBjb21lcmNpYWwsIGxhIGNhcGFjaWRhZCBkZSBmaW5hbmNpYW1pZW50byBmcmVudGUgYWwgcmVzdG8gZGVsIG11bmRvIHkgZWwgYXBvcnRlIGRlbCBjb21lcmNpbyBleHRlcmlvciBhbCBjcmVjaW1pZW50byBlY29uw7NtaWNvLiBMb3MgaW5mb3JtZXMgZGUgbGEgT0VDRCBkZXN0YWNhbiBxdWUsIGVuIHVuIGNvbnRleHRvIGRlIGNhbWJpb3MgZW4gbGFzIGNhZGVuYXMgZ2xvYmFsZXMgZGUgc3VtaW5pc3RybyB5IGRlIGVsZXZhZGEgaW5jZXJ0aWR1bWJyZSBlY29uw7NtaWNhIGludGVybmFjaW9uYWwsIGVsIGNvbXBvcnRhbWllbnRvIGRlbCBzZWN0b3IgZXh0ZXJubyBlcyB2YXJpYWJsZS48L2Rpdj4NCg0KIyMgMy4yIE1hdHJpeiBkZSBjb3JyZWxhY2nDs24NCg0KYGBge3IgbWF0cml6IGRlIGNvcnJlbGFjaW9uLCBmaWcuaGVpZ2h0PTksZmlnLndpZHRoPTEwLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0Kbm9tYnJlc19jb3IgPC0gYygNCiAgIngxIiA9ICJDdGEuIGN0ZS4gKCUgUElCKSIsDQogICJ4MiIgPSAiVGlwbyBjYW1iaW8gKG1vbi4vVVNEKSIsDQogICJ4OCIgPSAiRXhwLiBuZXRhcyAoY29udC4gUElCIHJlYWwpIiwNCiAgIngxNSIgPSAiRXhwLiAodm9sLCBjcikiLA0KICAieDE2IiA9ICJJbXAuICh2b2wsIGNyKSIsDQogICJ4MTciID0gIlBJQiAodm9sLCBjcikiLA0KICAieDE4IiA9ICJQSUIgKG5vbSwgY3IpIiwNCiAgIngxOSIgPSAiRGVmbC4gUElCIChjcikiLA0KICAieDIwIiA9ICJGQkMgKHZvbCwgY3IpIiwNCiAgIngyMSIgPSAiQ29ucy4gcHJpdi4gKHZvbCwgY3IpIiwNCiAgIngyMiIgPSAiQ29ucy4gZ29iLiAodm9sLCBjcikiLA0KICAieDI1IiA9ICJEZWZsLiBQSUIgKHByZWMuIG1kbykiLA0KICAieDI2IiA9ICJUYXNhIGRlc2VtcGxlbyIsDQogICJ4MjciID0gIkVtcGxlbyB0b3RhbCIsDQogICJ4MjgiID0gIkZ1ZXJ6YSBsYWJvcmFsIg0KKQ0KDQpkYXRvc19jb3IgPC0gZGF0b3NfcGNhDQpuYW1lcyhkYXRvc19jb3IpIDwtIG5vbWJyZXNfY29yW25hbWVzKGRhdG9zX3BjYSldDQoNCmNvcl9tYXRyaXggPC0gY29yKGRhdG9zX2NvciwgdXNlID0gImNvbXBsZXRlLm9icyIpDQoNCiMgUGFsZXRhDQptaV9wYWxldGEgPC0gY29sb3JSYW1wUGFsZXR0ZShjKCJ3aGl0ZSIsICIjRkNFNEVDIiwgIiNGOEJCRDkiLCAiI0Y0OEZCMSIsICIjRDgxQjYwIikpKDIwMCkNCg0KY29ycnBsb3QoY29yX21hdHJpeCwNCiAgICAgICAgIG1ldGhvZCA9ICJjb2xvciIsDQogICAgICAgICB0eXBlID0gInVwcGVyIiwNCiAgICAgICAgIG9yZGVyID0gImhjbHVzdCIsDQogICAgICAgICBjb2wgPSBtaV9wYWxldGEsDQogICAgICAgICBhZGRDb2VmLmNvbCA9ICJibGFjayIsDQogICAgICAgICB0bC5jb2wgPSAiYmxhY2siLA0KICAgICAgICAgdGwuc3J0ID0gNDUsDQogICAgICAgICB0bC5jZXggPSAwLjksICAgIA0KICAgICAgICAgbnVtYmVyLmNleCA9IDAuNywNCiAgICAgICAgIG1hciA9IGMoMCwgMCwgMiwgMCkpDQoNCnRpdGxlKG1haW4gPSAiTWF0cml6IGRlIENvcnJlbGFjacOzbiIsDQogICAgICBjZXgubWFpbiA9IDEuNSwgZm9udC5tYWluID0gMiwgY29sLm1haW4gPSAiI0Q4MUI2MCIpDQpgYGANCg0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeTsiPkVuIGdlbmVyYWwsIGxhcyBjb3JyZWxhY2lvbmVzIG3DoXMgYWx0YXMgc2Ugb2JzZXJ2YW4gZW50cmUgdmFyaWFibGVzIHBlcnRlbmVjaWVudGVzIGEgdW5hIG1pc21hIGRpbWVuc2nDs24gZWNvbsOzbWljYSwgbG8gcXVlIHN1Z2llcmUgcXVlIGVzdGFzIGNhcHR1cmFuIGZlbsOzbWVub3Mgc2ltaWxhcmVzIHkganVzdGlmaWNhIGxhIGFwbGljYWNpw7NuIHBvc3RlcmlvciBkZSB0w6ljbmljYXMgZGUgcmVkdWNjacOzbiBkZSBkaW1lbnNpb25hbGlkYWQuDQoNCkVuIGVsIG1lcmNhZG8gbGFib3JhbCBzZSBvYnNlcnZhIHVuYSBjb3JyZWxhY2nDs24gbXV5IGFsdGEgZW50cmUgZWwgZW1wbGVvIHRvdGFsIHkgbGEgZnVlcnphIGxhYm9yYWwuIEVzdGUgcmVzdWx0YWRvIGVyYSBlc3BlcmFkbywgeWEgcXVlIGFtYmFzIHZhcmlhYmxlcyByZWZsZWphbiBlbCB0YW1hw7FvIGRlbCBtZXJjYWRvIGRlIHRyYWJham8gZGUgY2FkYSBwYcOtcyB5IHRpZW5kZW4gYSBldm9sdWNpb25hciBlbiBsYSBtaXNtYSBkaXJlY2Npw7NuIGEgcGVzYXIgZGUgZXN0YSBhc29jaWFjacOzbiwgc2UgZGVjaWRpw7MgY29uc2VydmFyIGFtYmFzIHZhcmlhYmxlcyBkZWJpZG8gYSBxdWUgYXBvcnRhbiBpbmZvcm1hY2nDs24gY29tcGxlbWVudGFyaWEgc29icmUgbGFzIGNvbmRpY2lvbmVzIGxhYm9yYWxlcyBkZSBsYXMgZWNvbm9tw61hcyBhbmFsaXphZGFzLg0KDQpMYXMgYXNvY2lhY2lvbmVzIG3DoXMgZnVlcnRlcyBzZSBwcmVzZW50YW4gZW4gbGEgZGltZW5zacOzbiBkZSBwcmVjaW9zIGUgaW5mbGFjacOzbi4gRWwgY3JlY2ltaWVudG8gZGVsIGRlZmxhY3RvciBkZWwgUElCIG11ZXN0cmEgdW5hIGNvcnJlbGFjacOzbiBkZSAwLjk3IGNvbiBlbCBjcmVjaW1pZW50byBub21pbmFsIGRlbCBQSUIsIG1pZW50cmFzIHF1ZSBlbCBkZWZsYWN0b3IgZGVsIFBJQiBhIHByZWNpb3MgZGUgbWVyY2FkbyBwcmVzZW50YSBjb3JyZWxhY2lvbmVzIGRlIDAuODUgeSAwLjgyIGNvbiBlc3RhcyB2YXJpYWJsZXMgc3VnaXJpZW5kbyBxdWUgdW5hIHBhcnRlIGltcG9ydGFudGUgZGUgbGFzIGRpZmVyZW5jaWFzIG9ic2VydmFkYXMgZW4gKiplbCBjcmVjaW1pZW50byBub21pbmFsIGVudHJlIHBhw61zZXMgZXN0w6EgYXNvY2lhZGEgYSBsYSBldm9sdWNpw7NuIGRlIGxvcyBwcmVjaW9zKiogeSBxdWUgZWwgdGlwbyBkZSBjYW1iaW8gcHJlc2VudGEgY29ycmVsYWNpb25lcyBwb3NpdGl2YXMgY2VyY2FuYXMgYSAwLjcwIGNvbiBsb3MgaW5kaWNhZG9yZXMgaW5mbGFjaW9uYXJpb3MsIHJlZmxlamFuZG8gbGEgcmVsYWNpw7NuIGV4aXN0ZW50ZSBlbnRyZSBsYXMgdmFyaWFjaW9uZXMgY2FtYmlhcmlhcyB5IGVsIGNvbXBvcnRhbWllbnRvIGRlIGxvcyBwcmVjaW9zIA0KDQpFbiBjdWFudG8gYSBsYSBhY3RpdmlkYWQgZWNvbsOzbWljYSwgZWwgY3JlY2ltaWVudG8gZGVsIFBJQiByZWFsIHJlZ2lzdHJhIHVuYSBjb3JyZWxhY2nDs24gZGUgMC43NCBjb24gZWwgY3JlY2ltaWVudG8gZGVsIGNvbnN1bW8gcHJpdmFkbywgbG8gcXVlIHJlc2FsdGEgKipsYSBpbXBvcnRhbmNpYSBkZSBsYSBkZW1hbmRhIGRlIGxvcyBob2dhcmVzIGNvbW8gbW90b3IgZGVsIGNyZWNpbWllbnRvKiouIEFzaW1pc21vLCBsYSBmb3JtYWNpw7NuIGJydXRhIGRlIGNhcGl0YWwgZmlqbyBwcmVzZW50YSB1bmEgY29ycmVsYWNpw7NuIGRlIDAuNjggY29uIGVsIGNyZWNpbWllbnRvIGRlIGxhcyBpbXBvcnRhY2lvbmVzLCBzdWdpcmllbmRvIHF1ZSBsb3MgcHJvY2Vzb3MgZGUgaW52ZXJzacOzbiBzdWVsZW4gZXN0YXIgYWNvbXBhw7FhZG9zIHBvciB1bmEgbWF5b3IgZGVtYW5kYSBkZSBiaWVuZXMgcHJvdmVuaWVudGVzIGRlbCBleHRlcmlvci4NCg0KRmluYWxtZW50ZSwgc2Ugb2JzZXJ2YSB1bmEgY29ycmVsYWNpw7NuIHBvc2l0aXZhIGVudHJlIGVsIHNhbGRvIGRlIGN1ZW50YSBjb3JyaWVudGUgeSBsYSBjb250cmlidWNpw7NuIGRlIGxhcyBleHBvcnRhY2lvbmVzIG5ldGFzIGFsIFBJQiwgbG8gcXVlIGV2aWRlbmNpYSBsYSBpbXBvcnRhbmNpYSBkZWwgc2VjdG9yIGV4dGVybm8gZW4gbGEgZGlmZXJlbmNpYWNpw7NuIGVjb27Ds21pY2EgZGUgbG9zIHBhw61zZXMgYW5hbGl6YWRvcy48L2Rpdj4NCg0KIyMgMy4zIEFDUCAtIFBvcmNlbnRhamUgVmFyaWFuemEgDQoNCmBgYHtyIGFjcCBiYXNpY28sIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpyZXMucGNhIDwtIHByY29tcChkYXRvc19wY2EsIHNjYWxlID0gVFJVRSkNCg0KZnZpel9laWcocmVzLnBjYSwgYWRkbGFiZWxzID0gVFJVRSwNCiAgICAgICAgIGJhcmZpbGwgPSAiI0ZDRTRFQyIsICAgICAgDQogICAgICAgICBiYXJjb2xvciA9ICIjRDgxQjYwIiwgICAgIA0KICAgICAgICAgbGluZWNvbG9yID0gIiNEODFCNjAiLA0KICAgICAgICAgeGxhYiA9ICJDb21wb25lbnRlcyIsDQogICAgICAgICB5bGFiID0gIlBvcmNlbnRhamUgZGUgdmFyaWFuemEgZXhwbGljYWRhIikrDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiI0Q4MUI2MCIsIGZhY2UgPSAiYm9sZCIpKQ0KDQpgYGANCg0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeTsiPkxvcyByZXN1bHRhZG9zIHN1Z2llcmVuIHF1ZSBsYXMgZGlmZXJlbmNpYXMgZWNvbsOzbWljYXMgZW50cmUgbG9zIHBhw61zZXMgcHVlZGVuIHJlc3VtaXJzZSBlbiB1biBuw7ptZXJvIHJlZHVjaWRvIGRlIGRpbWVuc2lvbmVzLCB5YSBxdWUgbGFzIHRyZXMgcHJpbWVyYXMgY29tcG9uZW50ZXMgY29uY2VudHJhbiBjZXJjYSBkZSBkb3MgdGVyY2VyYXMgcGFydGVzIGRlIGxhIGluZm9ybWFjacOzbiBvcmlnaW5hbC4gRXN0byBpbmRpY2EgKipsYSBleGlzdGVuY2lhIGRlIGZhY3RvcmVzIGNvbXVuZXMgcXVlIGV4cGxpY2FuIGdyYW4gcGFydGUgZGUgbGEgdmFyaWFiaWxpZGFkIG9ic2VydmFkYSwgcGVybWl0aWVuZG8gc2ltcGxpZmljYXIgZWwgYW7DoWxpc2lzIHNpbiBwZXJkZXIgdW5hIHByb3BvcmNpw7NuIGltcG9ydGFudGUgZGUgaW5mb3JtYWNpw7NuKiouPC9kaXY+DQoNCmBgYHtyIHRhYmxhIGVpZ2VuLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZWlnZW5fdGFibGEgPC0gZ2V0X2VpZ2VudmFsdWUocmVzLnBjYSkNCg0KZWlnZW5fZGYgPC0gYXMuZGF0YS5mcmFtZShlaWdlbl90YWJsYSkgJT4lDQogIG11dGF0ZSgNCiAgICB2YXJpYW5jZS5wZXJjZW50ID0gdmFyaWFuY2UucGVyY2VudCAqIDEsDQogICAgY3VtdWxhdGl2ZS52YXJpYW5jZS5wZXJjZW50ID0gY3VtdWxhdGl2ZS52YXJpYW5jZS5wZXJjZW50ICogMQ0KICApDQoNCmVpZ2VuX2RmICU+JQ0KICBndCgpICU+JQ0KICB0YWJfaGVhZGVyKA0KICAgIHRpdGxlID0gbWQoIioqVmFsb3JlcyBwcm9waW9zIGRlbCBhbsOhbGlzaXMgZGUgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMqKiIpLA0KICAgIHN1YnRpdGxlID0gIlZhcmlhbnphIGV4cGxpY2FkYSBwb3IgY2FkYSBjb21wb25lbnRlIg0KICApICU+JQ0KICBjb2xzX2xhYmVsKA0KICAgIGVpZ2VudmFsdWUgPSAiVmFsb3IgcHJvcGlvIiwNCiAgICB2YXJpYW5jZS5wZXJjZW50ID0gIlZhcmlhbnphICglKSIsDQogICAgY3VtdWxhdGl2ZS52YXJpYW5jZS5wZXJjZW50ID0gIlZhcmlhbnphIGFjdW11bGFkYSAoJSkiDQogICkgJT4lDQogIGZtdF9udW1iZXIoDQogICAgY29sdW1ucyA9IGMoZWlnZW52YWx1ZSwgdmFyaWFuY2UucGVyY2VudCwgY3VtdWxhdGl2ZS52YXJpYW5jZS5wZXJjZW50KSwNCiAgICBkZWNpbWFscyA9IDINCiAgKSAlPiUNCiAgdGFiX3N0eWxlKA0KICAgIHN0eWxlID0gbGlzdCgNCiAgICAgIGNlbGxfZmlsbChjb2xvciA9ICIjRDgxQjYwIiksDQogICAgICBjZWxsX3RleHQoY29sb3IgPSAid2hpdGUiLCB3ZWlnaHQgPSAiYm9sZCIpDQogICAgKSwNCiAgICBsb2NhdGlvbnMgPSBjZWxsc19jb2x1bW5fbGFiZWxzKGV2ZXJ5dGhpbmcoKSkNCiAgKSAlPiUNCiAgdGFiX3N0eWxlKA0KICAgIHN0eWxlID0gbGlzdCgNCiAgICAgIGNlbGxfZmlsbChjb2xvciA9ICIjRkNFNEVDIiksDQogICAgICBjZWxsX3RleHQoY29sb3IgPSAiYmxhY2siKQ0KICAgICksDQogICAgbG9jYXRpb25zID0gY2VsbHNfYm9keShyb3dzID0gZXZlcnl0aGluZygpKQ0KICApICU+JQ0KICBvcHRfcm93X3N0cmlwaW5nKCkgJT4lDQogIHRhYl9vcHRpb25zKA0KICAgIHRhYmxlLndpZHRoID0gcGN0KDEwMCksDQogICAgdGFibGUuZm9udC5zaXplID0gInNtYWxsIiwNCiAgICBoZWFkaW5nLnRpdGxlLmZvbnQuc2l6ZSA9ICJsYXJnZSIsDQogICAgcm93LnN0cmlwaW5nLmJhY2tncm91bmRfY29sb3IgPSAiI0Y4QkJEOSIsDQogICAgdGFibGUuYm9yZGVyLnRvcC5jb2xvciA9ICIjRDgxQjYwIiwNCiAgICB0YWJsZS5ib3JkZXIuYm90dG9tLmNvbG9yID0gIiNEODFCNjAiLA0KICAgIGNvbnRhaW5lci5oZWlnaHQgPSBweCg0MDApLA0KICAgIGNvbnRhaW5lci5vdmVyZmxvdy55ID0gImF1dG8iDQogICkgJT4lDQogIHRhYl9zb3VyY2Vfbm90ZSgiRnVlbnRlOiBSZXN1bHRhZG9zIGRlbCBQQ0EgLSBFbGFib3JhY2nDs24gcHJvcGlhIikNCmBgYA0KDQojIyAzLjQgUGFydGljaXBhY2nDs24gdmFyaWFibGVzIGVuIGRpbWVuc2lvbmVzDQoNCiMjIyAzLjQuMSBJbmVzdGFiaWxpZGFkIG5vbWluYWwgeSBwcmVzacOzbiBpbmZsYWNpb25hcmlhDQoNCmBgYHtyIHZhcmlhYmxlcyBxdWUgYXBvcnRhbiBhbCBjcDF9DQpsb2FkaW5ncyA8LSByZXMucGNhJHJvdGF0aW9uDQpjb3MyIDwtIGxvYWRpbmdzXjINCg0KcGMxX2xvYWRpbmdzIDwtIGxvYWRpbmdzWywgMV0NCnBjMV9jb3MyIDwtIGNvczJbLCAxXQ0KDQojID09PSBDQU1CSU8gMTogaWNvbnYgZW4gbHVnYXIgZGUgZW5jMnV0ZjggPT09DQp0YWJsYV9wYzEgPC0gZGF0YS5mcmFtZSgNCiAgVmFyaWFibGUgPSBpY29udih2YXJpYWJsZXNub21icmVzW3Jvd25hbWVzKGxvYWRpbmdzKV0sIHRvID0gIlVURi04Iiwgc3ViID0gIiAiKSwNCiAgTG9hZGluZyA9IHBjMV9sb2FkaW5ncywNCiAgQ29zMiA9IHBjMV9jb3MyDQopDQoNCiMgT3JkZW5hcg0KdGFibGFfcGMxIDwtIHRhYmxhX3BjMVtvcmRlcigtdGFibGFfcGMxJENvczIpLCBdDQoNCmd0KHRhYmxhX3BjMSkgJT4lDQogIHRhYl9oZWFkZXIoDQogICAgIyA9PT0gQ0FNQklPIDI6IGVuYzJ1dGY4IGVuIGVsIHTDrXR1bG8gPT09DQogICAgdGl0bGUgPSBlbmMydXRmOChwYXN0ZTAoIkNvbnRyaWJ1Y2nDs24gZGUgVmFyaWFibGVzIGFsIENvbXBvbmVudGUgUHJpbmNpcGFsIDEgKCIsIA0KICAgICAgICAgICAgICAgICAgIHJvdW5kKHN1bW1hcnkocmVzLnBjYSkkaW1wb3J0YW5jZVsyLCAxXSAqIDEwMCwgMSksICIlIGRlIHZhcmlhbnphKSIpKSwNCiAgICBzdWJ0aXRsZSA9ICJDYXJnYXMgKGxvYWRpbmdzKSB5IGNvc2VubyBhbCBjdWFkcmFkbyAoY29zwrIpIiAgIyBlc3RlIG5vIHN1ZWxlIGRhciBwcm9ibGVtYSwgcGVybyBzaSBmYWxsYSwgcG9ubGUgZW5jMnV0ZjggdGFtYmnDqW4NCiAgKSAlPiUNCiAgY29sc19sYWJlbCgNCiAgICBWYXJpYWJsZSA9ICJWYXJpYWJsZSIsDQogICAgTG9hZGluZyA9ICJMb2FkaW5nIiwNCiAgICBDb3MyID0gIkNvc8KyIg0KICApICU+JQ0KICBmbXRfbnVtYmVyKGNvbHVtbnMgPSBjKExvYWRpbmcsIENvczIpLCBkZWNpbWFscyA9IDQpICU+JQ0KICB0YWJfc3R5bGUoDQogICAgc3R5bGUgPSBsaXN0KGNlbGxfZmlsbChjb2xvciA9ICIjRDgxQjYwIiksIGNlbGxfdGV4dChjb2xvciA9ICJ3aGl0ZSIsIHdlaWdodCA9ICJib2xkIikpLA0KICAgIGxvY2F0aW9ucyA9IGNlbGxzX2NvbHVtbl9sYWJlbHMoZXZlcnl0aGluZygpKQ0KICApICU+JQ0KICB0YWJfc3R5bGUoDQogICAgc3R5bGUgPSBjZWxsX2ZpbGwoY29sb3IgPSAiI0ZGRDcwMCIpLA0KICAgIGxvY2F0aW9ucyA9IGNlbGxzX2JvZHkocm93cyA9IDE6MykNCiAgKSAlPiUNCiAgdGFiX3N0eWxlKA0KICAgIHN0eWxlID0gY2VsbF9maWxsKGNvbG9yID0gIiNGQ0U0RUMiKSwNCiAgICBsb2NhdGlvbnMgPSBjZWxsc19ib2R5KHJvd3MgPSBzZXEoNCwgbnJvdyh0YWJsYV9wYzEpLCAyKSkNCiAgKSAlPiUNCiAgdGFiX3N0eWxlKA0KICAgIHN0eWxlID0gY2VsbF9maWxsKGNvbG9yID0gIiNGOEJCRDkiKSwNCiAgICBsb2NhdGlvbnMgPSBjZWxsc19ib2R5KHJvd3MgPSBzZXEoNSwgbnJvdyh0YWJsYV9wYzEpLCAyKSkNCiAgKSAlPiUNCiAgdGFiX29wdGlvbnMoDQogICAgdGFibGUud2lkdGggPSBwY3QoMTAwKSwNCiAgICB0YWJsZS5mb250LnNpemUgPSAic21hbGwiLA0KICAgIGhlYWRpbmcuYmFja2dyb3VuZC5jb2xvciA9ICIjRjQ4RkIxIg0KICApICU+JQ0KICB0YWJfc291cmNlX25vdGUoDQogICAgc291cmNlX25vdGUgPSAiTm90YTogTGFzIGZpbGFzIGVuIGRvcmFkbyBjb3JyZXNwb25kZW4gYSBsYXMgMyB2YXJpYWJsZXMgY29uIG1heW9yIGNvbnRyaWJ1Y2nDs24gYWwgUEMxLiINCiAgKQ0KYGBgDQoNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnk7Ij5FbCBwcmltZXIgY29tcG9uZW50ZSBlc3TDoSBkb21pbmFkbyBwb3IgZWwgY3JlY2ltaWVudG8gbm9taW5hbCBkZWwgUElCLCBlbCBjcmVjaW1pZW50byBkZWwgZGVmbGFjdG9yIGRlbCBQSUIsIGVsIGRlZmxhY3RvciBhIHByZWNpb3MgZGUgbWVyY2Fkbywgc3VnaXJpZW5kbyBxdWUgbGEgcHJpbmNpcGFsIGZ1ZW50ZSBkZSBkaWZlcmVuY2lhY2nDs24gZW50cmUgbG9zIHBhw61zZXMgZXN0w6EgYXNvY2lhZGEgYSBmYWN0b3JlcyBub21pbmFsZXMsIGVzcGVjaWFsbWVudGUgYSBsYSBpbmZsYWNpw7NuIHkgY29tcG9ydGFtaWVudG8gY2FtYmlhcmlvLiBMb3MgcGHDrXNlcyBjb24gdmFsb3JlcyBhbHRvcyBlbiBlc3RhIGNvbXBvbmVudGUgdGllbmRlbiBhIHByZXNlbnRhciBtYXlvcmVzIGF1bWVudG9zIGRlIHByZWNpb3MgeSBtYXlvciBkaW5hbWlzbW8gbm9taW5hbCBlbiBzdSBlY29ub23DrWEuPC9kaXY+DQoNCiMjIyAzLjQuMiBEaW5hbWlzbW8gZGUgbGEgZGVtYW5kYSBpbnRlcm5hIHkgc2VjdG9yIGV4dGVybm8NCg0KYGBge3IgdmFyaWFibGVzIHF1ZSBhcG9ydGFuIGFsIHBjMn0NCiMgUGFyYSBlbCBQQzINCnBjMl9sb2FkaW5ncyA8LSBsb2FkaW5nc1ssIDJdDQpwYzJfY29zMiA8LSBjb3MyWywgMl0NCg0KdGFibGFfcGMyIDwtIGRhdGEuZnJhbWUoDQogIFZhcmlhYmxlID0gZW5jMnV0ZjgodmFyaWFibGVzbm9tYnJlc1tyb3duYW1lcyhsb2FkaW5ncyldKSwNCiAgTG9hZGluZyA9IHBjMl9sb2FkaW5ncywNCiAgQ29zMiA9IHBjMl9jb3MyDQopDQoNCiMgT3JkZW5hciBkZSBtYXlvciBhIG1lbm9yIGNvc8KyDQp0YWJsYV9wYzIgPC0gdGFibGFfcGMyW29yZGVyKC10YWJsYV9wYzIkQ29zMiksIF0NCg0KZ3QodGFibGFfcGMyKSAlPiUNCiAgdGFiX2hlYWRlcigNCiAgICB0aXRsZSA9IHBhc3RlMCgiQ29udHJpYnVjacOzbiBkZSBWYXJpYWJsZXMgYWwgQ29tcG9uZW50ZSBQcmluY2lwYWwgMiAoIiwgDQogICAgICAgICAgICAgICAgICAgcm91bmQoc3VtbWFyeShyZXMucGNhKSRpbXBvcnRhbmNlWzIsIDJdICogMTAwLCAxKSwgIiUgZGUgdmFyaWFuemEpIiksDQogICAgc3VidGl0bGUgPSAiQ2FyZ2FzIChsb2FkaW5ncykgeSBjb3Nlbm8gYWwgY3VhZHJhZG8gKGNvc8KyKSINCiAgKSAlPiUNCiAgY29sc19sYWJlbCgNCiAgICBWYXJpYWJsZSA9ICJWYXJpYWJsZSIsDQogICAgTG9hZGluZyA9ICJMb2FkaW5nIiwNCiAgICBDb3MyID0gIkNvc8KyIg0KICApICU+JQ0KICBmbXRfbnVtYmVyKGNvbHVtbnMgPSBjKExvYWRpbmcsIENvczIpLCBkZWNpbWFscyA9IDQpICU+JQ0KICB0YWJfc3R5bGUoDQogICAgc3R5bGUgPSBsaXN0KGNlbGxfZmlsbChjb2xvciA9ICIjRDgxQjYwIiksIGNlbGxfdGV4dChjb2xvciA9ICJ3aGl0ZSIsIHdlaWdodCA9ICJib2xkIikpLA0KICAgIGxvY2F0aW9ucyA9IGNlbGxzX2NvbHVtbl9sYWJlbHMoZXZlcnl0aGluZygpKQ0KICApICU+JQ0KICB0YWJfc3R5bGUoDQogICAgc3R5bGUgPSBjZWxsX2ZpbGwoY29sb3IgPSAiI0ZGRDcwMCIpLA0KICAgIGxvY2F0aW9ucyA9IGNlbGxzX2JvZHkocm93cyA9IDE6MykNCiAgKSAlPiUNCiAgdGFiX3N0eWxlKA0KICAgIHN0eWxlID0gY2VsbF9maWxsKGNvbG9yID0gIiNGQ0U0RUMiKSwNCiAgICBsb2NhdGlvbnMgPSBjZWxsc19ib2R5KHJvd3MgPSBzZXEoNCwgbnJvdyh0YWJsYV9wYzIpLCAyKSkNCiAgKSAlPiUNCiAgdGFiX3N0eWxlKA0KICAgIHN0eWxlID0gY2VsbF9maWxsKGNvbG9yID0gIiNGOEJCRDkiKSwNCiAgICBsb2NhdGlvbnMgPSBjZWxsc19ib2R5KHJvd3MgPSBzZXEoNSwgbnJvdyh0YWJsYV9wYzIpLCAyKSkNCiAgKSAlPiUNCiAgdGFiX29wdGlvbnMoDQogICAgdGFibGUud2lkdGggPSBwY3QoMTAwKSwNCiAgICB0YWJsZS5mb250LnNpemUgPSAic21hbGwiLA0KICAgIGhlYWRpbmcuYmFja2dyb3VuZC5jb2xvciA9ICIjRjQ4RkIxIg0KICApICU+JQ0KICB0YWJfc291cmNlX25vdGUoDQogICAgc291cmNlX25vdGUgPSAiTm90YTogTGFzIGZpbGFzIGVuIGRvcmFkbyBjb3JyZXNwb25kZW4gYSBsYXMgMyB2YXJpYWJsZXMgY29uIG1heW9yIGNvbnRyaWJ1Y2nDs24gYWwgUEMyLiINCiAgKQ0KYGBgDQoNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnk7Ij5EZXRlcm1pbmFkYSBwcmluY2lwYWxtZW50ZSBwb3IgZWwgY3JlY2ltaWVudG8gZGUgbGFzIGltcG9ydGFjaW9uZXMsIGxhIGN1ZW50YSBjb3JyaWVudGUgeSBsYSBjb250cmlidWNpw7NuIGRlIGxhcyBleHBvcnRhY2lvbmVzIG5ldGFzIGFsIFBJQi4gRXN0YSBkaW1lbnNpw7NuIHJlZmxlamEgZWwgZ3JhZG8gZGUgYXBlcnR1cmEgeSBkZXBlbmRlbmNpYSBkZWwgc2VjdG9yIGV4dGVybm8sIGRpZmVyZW5jaWFuZG8gZWNvbm9tw61hcyBtw6FzIG9yaWVudGFkYXMgYWwgY29tZXJjaW8gaW50ZXJuYWNpb25hbCBkZSBhcXVlbGxhcyBjb24gdW5hIHBvc2ljacOzbiBleHRlcm5hIG3DoXMgZMOpYmlsLjwvZGl2Pg0KDQojIyMgMy40LjMgQ3JlY2ltaWVudG8gcmVhbCBpbXB1bHNhZG8gcG9yIGVsIHNlY3RvciBleHRlcm5vDQoNCmBgYHtyIHZhcmlhYmxlcyBxdWUgYXBvcnRhbCBhbCBwYzN9DQojIFBhcmEgZWwgUEMzDQpwYzNfbG9hZGluZ3MgPC0gbG9hZGluZ3NbLCAzXQ0KcGMzX2NvczIgPC0gY29zMlssIDNdDQoNCnRhYmxhX3BjMyA8LSBkYXRhLmZyYW1lKA0KICBWYXJpYWJsZSA9IGVuYzJ1dGY4KHZhcmlhYmxlc25vbWJyZXNbcm93bmFtZXMobG9hZGluZ3MpXSksDQogIExvYWRpbmcgPSBwYzNfbG9hZGluZ3MsDQogIENvczIgPSBwYzNfY29zMg0KKQ0KDQojIE9yZGVuYXIgZGUgbWF5b3IgYSBtZW5vciBjb3PCsg0KdGFibGFfcGMzIDwtIHRhYmxhX3BjM1tvcmRlcigtdGFibGFfcGMzJENvczIpLCBdDQoNCmd0KHRhYmxhX3BjMykgJT4lDQogIHRhYl9oZWFkZXIoDQogICAgdGl0bGUgPSBwYXN0ZTAoIkNvbnRyaWJ1Y2nDs24gZGUgVmFyaWFibGVzIGFsIENvbXBvbmVudGUgUHJpbmNpcGFsIDMgKCIsIA0KICAgICAgICAgICAgICAgICAgIHJvdW5kKHN1bW1hcnkocmVzLnBjYSkkaW1wb3J0YW5jZVsyLCAzXSAqIDEwMCwgMSksICIlIGRlIHZhcmlhbnphKSIpLA0KICAgIHN1YnRpdGxlID0gIkNhcmdhcyAobG9hZGluZ3MpIHkgY29zZW5vIGFsIGN1YWRyYWRvIChjb3PCsikiDQogICkgJT4lDQogIGNvbHNfbGFiZWwoDQogICAgVmFyaWFibGUgPSAiVmFyaWFibGUiLA0KICAgIExvYWRpbmcgPSAiTG9hZGluZyIsDQogICAgQ29zMiA9ICJDb3PCsiINCiAgKSAlPiUNCiAgZm10X251bWJlcihjb2x1bW5zID0gYyhMb2FkaW5nLCBDb3MyKSwgZGVjaW1hbHMgPSA0KSAlPiUNCiAgdGFiX3N0eWxlKA0KICAgIHN0eWxlID0gbGlzdChjZWxsX2ZpbGwoY29sb3IgPSAiI0Q4MUI2MCIpLCBjZWxsX3RleHQoY29sb3IgPSAid2hpdGUiLCB3ZWlnaHQgPSAiYm9sZCIpKSwNCiAgICBsb2NhdGlvbnMgPSBjZWxsc19jb2x1bW5fbGFiZWxzKGV2ZXJ5dGhpbmcoKSkNCiAgKSAlPiUNCiAgdGFiX3N0eWxlKA0KICAgIHN0eWxlID0gY2VsbF9maWxsKGNvbG9yID0gIiNGRkQ3MDAiKSwNCiAgICBsb2NhdGlvbnMgPSBjZWxsc19ib2R5KHJvd3MgPSAxOjMpDQogICkgJT4lDQogIHRhYl9zdHlsZSgNCiAgICBzdHlsZSA9IGNlbGxfZmlsbChjb2xvciA9ICIjRkNFNEVDIiksDQogICAgbG9jYXRpb25zID0gY2VsbHNfYm9keShyb3dzID0gc2VxKDQsIG5yb3codGFibGFfcGMzKSwgMikpDQogICkgJT4lDQogIHRhYl9zdHlsZSgNCiAgICBzdHlsZSA9IGNlbGxfZmlsbChjb2xvciA9ICIjRjhCQkQ5IiksDQogICAgbG9jYXRpb25zID0gY2VsbHNfYm9keShyb3dzID0gc2VxKDUsIG5yb3codGFibGFfcGMzKSwgMikpDQogICkgJT4lDQogIHRhYl9vcHRpb25zKA0KICAgIHRhYmxlLndpZHRoID0gcGN0KDEwMCksDQogICAgdGFibGUuZm9udC5zaXplID0gInNtYWxsIiwNCiAgICBoZWFkaW5nLmJhY2tncm91bmQuY29sb3IgPSAiI0Y0OEZCMSINCiAgKSAlPiUNCiAgdGFiX3NvdXJjZV9ub3RlKA0KICAgIHNvdXJjZV9ub3RlID0gIk5vdGE6IExhcyBmaWxhcyBlbiBkb3JhZG8gY29ycmVzcG9uZGVuIGEgbGFzIDMgdmFyaWFibGVzIGNvbiBtYXlvciBjb250cmlidWNpw7NuIGFsIFBDMy4iDQogICkNCmBgYA0KDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5OyI+RXhwbGljYSBwcmluY2lwYWxtZW50ZSBsYXMgZXhwb3J0YWNpb25lcyBuZXRhcywgZWwgY3JlY2ltaWVudG8gZGVsIFBJQiByZWFsIHkgZWwgY3JlY2ltaWVudG8gZGUgbGFzIGV4cG9ydGFjaW9uZXMsIGNhcHR1cmFybmRvIGVsIHbDrW5jdWxvIGVudHJlIGNyZWNpbWllbnRvIGVjb27Ds21pY28geSBkZXNlbXBlw7FvIGV4cG9ydGFkb3IsIGlkZW50aWZpY2FuZG8gcGHDrXNlcyBkb25kZSBsYSBleHBhbnNpw7NuIGRlIGxhIGFjdGl2aWRhZCBlY29uw7NtaWNhIGVzdMOhIG3DoXMgYXNvY2lhZGEgYWwgZGluYW1pc21vIGRlbCBzZWN0b3IgZXh0ZXJuby4NCg0KDQpBIHBhcnRpciBkZWwgQUNQIHNlIGlkZW50aWZpY2Fyb24gdHJlcyBkaW1lbnNpb25lcyBwcmluY2lwYWxlcyBxdWUgZXhwbGljYW4gY2VyY2EgZGVsIDY2JSBkZSBsYSB2YXJpYWJpbGlkYWQgdG90YWwgZGUgbG9zIGRhdG9zLiBMYSBwcmltZXJhIGRpbWVuc2nDs24sIGRlbm9taW5hZGEgIkluZXN0YWJpbGlkYWQgbm9taW5hbCB5IHByZXNpw7NuIGluZmxhY2lvbmFyaWEiLCByZWNvZ2UgcHJpbmNpcGFsbWVudGUgaW5mb3JtYWNpw7NuIHJlbGFjaW9uYWRhIGNvbiBlbCBjcmVjaW1pZW50byBub21pbmFsIGRlbCBQSUIsIGxvcyBkZWZsYWN0b3JlcyBkZWwgUElCIHkgZWwgdGlwbyBkZSBjYW1iaW8uIFBvciBlc3RhIHJhesOzbiwgZXN0YSBkaW1lbnNpw7NuIHBlcm1pdGUgZGlmZXJlbmNpYXIgcGHDrXNlcyBjb24gbWF5b3JlcyBwcmVzaW9uZXMgaW5mbGFjaW9uYXJpYXMgeSB2YXJpYWNpb25lcyBub21pbmFsZXMgZGUgYXF1ZWxsb3MgcXVlIHByZXNlbnRhbiB1bmEgc2l0dWFjacOzbiBtw6FzIGVzdGFibGUgZW4gdMOpcm1pbm9zIGRlIHByZWNpb3MuDQoNCkxhIHNlZ3VuZGEgZGltZW5zacOzbiwgbGxhbWFkYSAiRGluYW1pc21vIGRlIGxhIGRlbWFuZGEgaW50ZXJuYSB5IHNlY3RvciBleHRlcm5vIiwgY29tYmluYSB2YXJpYWJsZXMgYXNvY2lhZGFzIGFsIGNvbnN1bW8gcHJpdmFkbywgbGFzIGltcG9ydGFjaW9uZXMsIGxhIGN1ZW50YSBjb3JyaWVudGUgeSBsYSBjb250cmlidWNpw7NuIGRlIGxhcyBleHBvcnRhY2lvbmVzIG5ldGFzIGFsIFBJQi4gRW4gZXN0ZSBjYXNvLCBsYSBkaW1lbnNpw7NuIHBhcmVjZSByZWZsZWphciBsYSBmb3JtYSBlbiBxdWUgY2FkYSBlY29ub23DrWEgY29tYmluYSBlbCBjb21wb3J0YW1pZW50byBkZSBzdSBkZW1hbmRhIGludGVybmEgY29uIHN1IHJlbGFjacOzbiBjb21lcmNpYWwgZnJlbnRlIGFsIHJlc3RvIGRlbCBtdW5kby4NCg0KUG9yIHN1IHBhcnRlLCBsYSB0ZXJjZXJhIGRpbWVuc2nDs24sIGRlbm9taW5hZGEgIkNyZWNpbWllbnRvIHJlYWwgaW1wdWxzYWRvIHBvciBlbCBzZWN0b3IgZXh0ZXJubyIsIGVzdMOhIGV4cGxpY2FkYSBwcmluY2lwYWxtZW50ZSBwb3IgZWwgY3JlY2ltaWVudG8gcmVhbCBkZWwgUElCLCBsYXMgZXhwb3J0YWNpb25lcyB5IGxhIGNvbnRyaWJ1Y2nDs24gZGUgbGFzIGV4cG9ydGFjaW9uZXMgbmV0YXMgYWwgY3JlY2ltaWVudG8gZWNvbsOzbWljby4gRXN0byBzdWdpZXJlIHF1ZSBhbGd1bm9zIHBhw61zZXMgbG9ncmFuIHVuYSBwYXJ0ZSBpbXBvcnRhbnRlIGRlIHN1IGV4cGFuc2nDs24gZWNvbsOzbWljYSBhIHRyYXbDqXMgZGVsIGRlc2VtcGXDsW8gZGUgc3Ugc2VjdG9yIGV4cG9ydGFkb3IuPC9kaXY+DQoNCmBgYHtyIGV4dHJhY2Npb24gZGUgZmFjdG9yZXMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpzY29yZXNfcGNhIDwtIGFzLmRhdGEuZnJhbWUocmVzLnBjYSR4WywgMTozXSkNCmBgYA0KDQojIyAzLjUgQ29tcGFyYXRpdmEgZW50cmUgZGltZW5zaW9uZXMgDQoNCiMjIyAzLjUuMSBHcsOhZmljbyBpbmRpdmlkdW9zIERpbWVuc2nDs24gMSB5IDINCg0KYGBge3IgQUNQIGluZGl2aWR1b3MgMSB5IDIsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQppbmRfY29vcmQgPC0gYXMuZGF0YS5mcmFtZShyZXMucGNhJHhbLCAxOjJdKQ0KY29sbmFtZXMoaW5kX2Nvb3JkKSA8LSBjKCJQQzEiLCAiUEMyIikNCmluZF9pbmZvIDwtIGdldF9wY2FfaW5kKHJlcy5wY2EpDQppbmRfY29vcmQkY29zMiA8LSBpbmRfaW5mbyRjb3MyWywgMV0NCmluZF9jb29yZCRsYWJlbCA8LSBEYXRvc0Vjb24kUGFpcyAgIyA8LS0gbm9tYnJlcyByZWFsZXMgZGUgbG9zIHBhaXNlcw0KcGxvdF9seSgNCiAgZGF0YSA9IGluZF9jb29yZCwNCiAgeCA9IH5QQzEsICAgDQogIHkgPSB+UEMyLCAgIA0KICB0eXBlID0gJ3NjYXR0ZXInLA0KICBtb2RlID0gJ21hcmtlcnMnLA0KICBtYXJrZXIgPSBsaXN0KA0KICAgIHNpemUgPSA4LA0KICAgIGNvbG9yID0gfmNvczIsDQogICAgY29sb3JzY2FsZSA9IGxpc3QoDQogICAgICBjKDAsICIjRkNFNEVDIiksICAgDQogICAgICBjKDAuNSwgIiNGOEJCRDkiKSwgDQogICAgICBjKDEsICIjRDgxQjYwIikgICANCiAgICApLA0KICAgIHNob3dzY2FsZSA9IFRSVUUsDQogICAgY29sb3JiYXIgPSBsaXN0KHRpdGxlID0gImNvczIiKQ0KICApLA0KICB0ZXh0ID0gfmxhYmVsLA0KICBob3ZlcmluZm8gPSAndGV4dCcsDQogIGhvdmVydGVtcGxhdGUgPSBwYXN0ZSgnPGI+JXt0ZXh0fTwvYj48YnI+UEMxOiAle3g6LjJmfTxicj5QQzI6ICV7eTouMmZ9PGJyPmNvczI6ICV7bWFya2VyLmNvbG9yOi4yZn08ZXh0cmE+PC9leHRyYT4nKQ0KKSAlPiUNCiAgbGF5b3V0KA0KICAgIHRpdGxlID0gIkdyYWZpY28gZGUgaW5kaXZpZHVvcyBEaW1lbnNpb24gMSBWUyAyIiwNCiAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSBwYXN0ZTAoIkRpbWVuc2lvbiAxICgiLCByb3VuZChzdW1tYXJ5KHJlcy5wY2EpJGltcG9ydGFuY2VbMiwxXSoxMDAsMSksICIlKSIpKSwNCiAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSBwYXN0ZTAoIkRpbWVuc2lvbiAyICgiLCByb3VuZChzdW1tYXJ5KHJlcy5wY2EpJGltcG9ydGFuY2VbMiwyXSoxMDAsMSksICIlKSIpKQ0KICApICU+JQ0KICBjb25maWcoZGlzcGxheU1vZGVCYXIgPSBGQUxTRSkNCmBgYA0KDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5OyI+RWwgZ3LDoWZpY28gZGUgaW5kaXZpZHVvcyBzZSBlbmN1ZW50cmEgcXVlIGxhIG1heW9yw61hIGRlIGxvcyBwYcOtc2VzIHNlIGNvbmNlbnRyYSBhbHJlZGVkb3IgZGVsIGNlbnRybyBkZWwgcGxhbm8gZmFjdG9yaWFsLCBpbmRpY2FuZG8gcXVlLCAqKmF1bnF1ZSBleGlzdGVuIGRpZmVyZW5jaWFzIGVudHJlIGVsbG9zLCBncmFuIHBhcnRlIGRlIGxhcyBlY29ub23DrWFzIGFuYWxpemFkYXMgY29tcGFydGVuIGNhcmFjdGVyw61zdGljYXMgcmVsYXRpdmFtZW50ZSBzaW1pbGFyZXMgY3VhbmRvIHNlIGNvbnNpZGVyYW4gZGUgbWFuZXJhIGNvbmp1bnRhIGxhcyB2YXJpYWJsZXMgZWNvbsOzbWljYXMgeSBsYWJvcmFsZXMgaW5jbHVpZGFzIGVuIGVsIGVzdHVkaW8qKi4gRXN0ZSByZXN1bHRhZG8gZXJhIGVzcGVyYWJsZSBkZWJpZG8gYSBxdWUgbGEgbXVlc3RyYSBlc3TDoSBjb21wdWVzdGEgcHJpbmNpcGFsbWVudGUgcG9yIHBhw61zZXMgcGVydGVuZWNpZW50ZXMgYSBsYSBPRUNELCBsb3MgY3VhbGVzIHN1ZWxlbiBwcmVzZW50YXIgbml2ZWxlcyBkZSBkZXNhcnJvbGxvIHkgZXN0cnVjdHVyYXMgZWNvbsOzbWljYXMgY29tcGFyYWJsZXMuIERlIGlndWFsIGZvcm1hLCBsYSBjZXJjYW7DrWEgb2JzZXJ2YWRhIGVudHJlIHZhcmlvcyBwYcOtc2VzIHN1Z2llcmUgbGEgZXhpc3RlbmNpYSBkZSBwZXJmaWxlcyBlY29uw7NtaWNvcyBzZW1lamFudGVzLCBsbyBxdWUgaW5kaWNhIHF1ZSBidWVuYSBwYXJ0ZSBkZSBsYXMgZWNvbm9tw61hcyBhbmFsaXphZGFzIGNvbXBhcnRlbiBjYXJhY3RlcsOtc3RpY2FzIHNpbWlsYXJlcyBlbiB0w6lybWlub3MgZGUgZXN0YWJpbGlkYWQgbWFjcm9lY29uw7NtaWNhLCBjcmVjaW1pZW50byB5IHJlbGFjacOzbiBjb24gZWwgc2VjdG9yIGV4dGVybm8uDQoNCkFkZW3DoXMgYXBhcmVjZW4gYWxndW5vcyBwYcOtc2VzIGFsZWphZG9zIGRlIGxhIGNvbmNlbnRyYWNpw7NuIHByaW5jaXBhbC4gRW50cmUgZWxsb3MgZGVzdGFjYW4gQXJnZW50aW5hLCBJcmxhbmRhIHkgQ2hpbGUsIHF1ZSBzZSB1YmljYW4gY29tbyBsYXMgb2JzZXJ2YWNpb25lcyBtw6FzIGRpc3BlcnNhcyBkZW50cm8gZGVsIHBsYW5vIGZhY3RvcmlhbC4gRXN0YSBwb3NpY2nDs24gc3VnaWVyZSBxdWUgcHJlc2VudGFuIGNvbXBvcnRhbWllbnRvcyBkaWZlcmVuY2lhZG9zIGVuIGxhcyBkaW1lbnNpb25lcyBxdWUgZXhwbGljYW4gbGEgbWF5b3IgcGFydGUgZGUgbGEgdmFyaWFiaWxpZGFkIGRlIGxvcyBkYXRvcy4gRW4gcGFydGljdWxhciwgcG9kcsOtYW4gZXN0YXIgYXNvY2lhZG9zIGEgZGlmZXJlbmNpYXMgZW4gYXNwZWN0b3MgcmVsYWNpb25hZG9zIGNvbiBsYSBlc3RhYmlsaWRhZCBkZSBwcmVjaW9zLCBlbCBjb21wb3J0YW1pZW50byBkZWwgdGlwbyBkZSBjYW1iaW8geSBlbCBjcmVjaW1pZW50byBub21pbmFsIGRlIGxhIGVjb25vbcOtYSwgdmFyaWFibGVzIHF1ZSBjYXJhY3Rlcml6YW4gbGEgcHJpbWVyYSBkaW1lbnNpw7NuIGRlbm9taW5hZGEgIkluZXN0YWJpbGlkYWQgbm9taW5hbCB5IHByZXNpw7NuIGluZmxhY2lvbmFyaWEiLiBBc2ltaXNtbywgKipwYXJ0ZSBkZSBlc3RhIGRpc3BlcnNpw7NuIHRhbWJpw6luIHBvZHLDrWEgZXN0YXIgdmluY3VsYWRhIGNvbiBkaWZlcmVuY2lhcyBlbiBlbCBkaW5hbWlzbW8gZGUgbGEgZGVtYW5kYSBpbnRlcm5hIHkgZWwgc2VjdG9yIGV4dGVybm8qKiwgcmVmbGVqYWRvIGVuIHZhcmlhYmxlcyBjb21vIGVsIGNvbnN1bW8gcHJpdmFkbywgbGFzIGltcG9ydGFjaW9uZXMsIGxhIGN1ZW50YSBjb3JyaWVudGUgeSBsYSBjb250cmlidWNpw7NuIGRlIGxhcyBleHBvcnRhY2lvbmVzIG5ldGFzIGFsIGNyZWNpbWllbnRvIGVjb27Ds21pY28uPC9kaXY+DQoNCiMjIyAzLjUuMiBHcsOhZmljbyBpbmRpdmlkdW9zIERpbWVuc2nDs24gMiB5IDMNCg0KYGBge3IgQUNQIGluZGl2aWR1b3MgMiB5IDMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQppbmRfY29vcmQgPC0gYXMuZGF0YS5mcmFtZShyZXMucGNhJHhbLCAyOjNdKQ0KY29sbmFtZXMoaW5kX2Nvb3JkKSA8LSBjKCJQQzIiLCAiUEMzIikNCmluZF9pbmZvIDwtIGdldF9wY2FfaW5kKHJlcy5wY2EpDQppbmRfY29vcmQkY29zMiA8LSBpbmRfaW5mbyRjb3MyWywgMl0gKyBpbmRfaW5mbyRjb3MyWywgM10gIA0KaW5kX2Nvb3JkJGxhYmVsIDwtIERhdG9zRWNvbiRQYWlzICAjIDwtLSBub21icmVzIHJlYWxlcyBkZSBsb3MgcGFpc2VzDQpwbG90X2x5KA0KICBkYXRhID0gaW5kX2Nvb3JkLA0KICB4ID0gflBDMiwgICANCiAgeSA9IH5QQzMsICAgDQogIHR5cGUgPSAnc2NhdHRlcicsDQogIG1vZGUgPSAnbWFya2VycycsDQogIG1hcmtlciA9IGxpc3QoDQogICAgc2l6ZSA9IDgsDQogICAgY29sb3IgPSB+Y29zMiwNCiAgICBjb2xvcnNjYWxlID0gbGlzdCgNCiAgICAgIGMoMCwgIiNGQ0U0RUMiKSwgICANCiAgICAgIGMoMC41LCAiI0Y4QkJEOSIpLCANCiAgICAgIGMoMSwgIiNEODFCNjAiKSAgIA0KICAgICksDQogICAgc2hvd3NjYWxlID0gVFJVRSwNCiAgICBjb2xvcmJhciA9IGxpc3QodGl0bGUgPSAiY29zMiAocGxhbm8gMi0zKSIpDQogICksDQogIHRleHQgPSB+bGFiZWwsDQogIGhvdmVyaW5mbyA9ICd0ZXh0JywNCiAgaG92ZXJ0ZW1wbGF0ZSA9IHBhc3RlKCc8Yj4le3RleHR9PC9iPjxicj5QQzI6ICV7eDouMmZ9PGJyPlBDMzogJXt5Oi4yZn08YnI+Y29zMjogJXttYXJrZXIuY29sb3I6LjJmfTxleHRyYT48L2V4dHJhPicpDQopICU+JQ0KICBsYXlvdXQoDQogICAgdGl0bGUgPSAiR3JhZmljbyBkZSBpbmRpdmlkdW9zIERpbWVuc2lvbiAyIFZTIDMiLA0KICAgIHhheGlzID0gbGlzdCh0aXRsZSA9IHBhc3RlMCgiRGltZW5zaW9uIDIgKCIsIHJvdW5kKHN1bW1hcnkocmVzLnBjYSkkaW1wb3J0YW5jZVsyLDJdKjEwMCwxKSwgIiUpIikpLA0KICAgIHlheGlzID0gbGlzdCh0aXRsZSA9IHBhc3RlMCgiRGltZW5zaW9uIDMgKCIsIHJvdW5kKHN1bW1hcnkocmVzLnBjYSkkaW1wb3J0YW5jZVsyLDNdKjEwMCwxKSwgIiUpIikpDQogICkgJT4lDQogIGNvbmZpZyhkaXNwbGF5TW9kZUJhciA9IEZBTFNFKQ0KYGBgDQoNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnk7Ij5TZSBvYnNlcnZhIHVuYSBjb25jZW50cmFjacOzbiBpbXBvcnRhbnRlIGRlIHBhw61zZXMgYWxyZWRlZG9yIGRlbCBjZW50cm8sIGxvIHF1ZSBpbmRpY2EgcXVlIGdyYW4gcGFydGUgZGUgbGFzIGVjb25vbcOtYXMgcHJlc2VudGFuIGNvbXBvcnRhbWllbnRvcyByZWxhdGl2YW1lbnRlIHNpbWlsYXJlcyBlbiB0w6lybWlub3MgZGUgZGVtYW5kYSBpbnRlcm5hLCBjb21lcmNpbyBleHRlcmlvciB5IGNyZWNpbWllbnRvIGVjb27Ds21pY28uIFNpbiBlbWJhcmdvLCBBcmdlbnRpbmEsIElybGFuZGEsIENoaWxlIHkgRXN0YWRvcyBVbmlkb3MgY29udGluw7phbiB1Ymljw6FuZG9zZSBlbnRyZSBsYXMgb2JzZXJ2YWNpb25lcyBtw6FzIGFsZWphZGFzIGRlbCBncnVwbyBwcmluY2lwYWwsIGF1bnF1ZSBBcmdlbnRpbmEgc2Ugc2l0w7phIGFob3JhIHNvYnJlIGVsIGxhZG8gbmVnYXRpdm8gZGUgbGEgc2VndW5kYSBkaW1lbnNpw7NuLg0KDQpFc3RhIGRpc3BlcnNpw7NuIHN1Z2llcmUgcXVlIGRpY2hvcyBwYcOtc2VzIHByZXNlbnRhbiBjYXJhY3RlcsOtc3RpY2FzIHBhcnRpY3VsYXJlcyBlbiBsYXMgdmFyaWFibGVzIHF1ZSBkZWZpbmVuIGFtYmFzIGRpbWVuc2lvbmVzLiBFbiBlbCBjYXNvIGRlIGxhIHNlZ3VuZGEgZGltZW5zacOzbiwgbGFzIGRpZmVyZW5jaWFzIHB1ZWRlbiBlc3RhciBhc29jaWFkYXMgYWwgY29tcG9ydGFtaWVudG8gZGVsIGNvbnN1bW8gcHJpdmFkbywgbGFzIGltcG9ydGFjaW9uZXMsIGxhIGN1ZW50YSBjb3JyaWVudGUgeSBsYSBjb250cmlidWNpw7NuIGRlIGxhcyBleHBvcnRhY2lvbmVzIG5ldGFzIGFsIFBJQiwgbG8gcXVlIHJlZmxlamEgZGlzdGludGFzIGZvcm1hcyBkZSBjb21iaW5hciBsYSBkZW1hbmRhIGludGVybmEgY29uIGxhIHJlbGFjacOzbiBjb21lcmNpYWwgZnJlbnRlIGFsIGV4dGVyaW9yLiBQb3Igb3RyYSBwYXJ0ZSwgKipsYSB0ZXJjZXJhIGRpbWVuc2nDs24gcGVybWl0ZSBkaXN0aW5ndWlyIGVjb25vbcOtYXMgZG9uZGUgZWwgY3JlY2ltaWVudG8gcmVhbCBzZSBlbmN1ZW50cmEgbcOhcyB2aW5jdWxhZG8gYWwgZGVzZW1wZcOxbyBleHBvcnRhZG9yLiBFbiBlc3RlIHNlbnRpZG8qKiwgbGEgcG9zaWNpw7NuIGRlIElybGFuZGEsIENoaWxlIHkgRXN0YWRvcyBVbmlkb3MgcG9kcsOtYSBpbmRpY2FyIHVuYSBkaW7DoW1pY2EgZGUgY3JlY2ltaWVudG8geSBjb21lcmNpbyBleHRlcmlvciBkaWZlcmVudGUgbGEgbWF5b3LDrWEgZGUgbG9zIHBhw61zZXMgZGUgbGEgbXVlc3RyYS48L2Rpdj4NCg0KIyMjIDMuNS4zIEdyw6FmaWNvIHZhcmlhYmxlcyBEaW1lbnNpw7NuIDEgeSAyDQoNCmBgYHtyIEFDUCBWQVJJQUJMRVMgMSB5IDIsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQp2YXJfY29vcmQgPC0gYXMuZGF0YS5mcmFtZShyZXMucGNhJHJvdGF0aW9uWywgMToyXSkNCmNvbG5hbWVzKHZhcl9jb29yZCkgPC0gYygiUEMxIiwgIlBDMiIpDQp2YXJfY29vcmQkdmFyIDwtIGljb252KHZhcmlhYmxlc25vbWJyZXNbcm93bmFtZXModmFyX2Nvb3JkKV0sIHRvID0gIlVURi04Iiwgc3ViID0gIiAiKQ0KDQp2YXJfaW5mbyA8LSBnZXRfcGNhX3ZhcihyZXMucGNhKQ0KdmFyX2Nvb3JkJGNvbnRyaWIgPC0gdmFyX2luZm8kY29udHJpYlssIDFdDQoNCnBsb3RfbHkoKSAlPiUNCiAgYWRkX3NlZ21lbnRzKA0KICAgIHggPSAwLCB5ID0gMCwNCiAgICB4ZW5kID0gflBDMSwgeWVuZCA9IH5QQzIsDQogICAgZGF0YSA9IHZhcl9jb29yZCwNCiAgICBsaW5lID0gbGlzdChjb2xvciA9ICJncmF5Iiwgd2lkdGggPSAxLjUpLA0KICAgIHNob3dsZWdlbmQgPSBGQUxTRSwNCiAgICBob3ZlcmluZm8gPSAnbm9uZScNCiAgKSAlPiUNCiAgYWRkX21hcmtlcnMoDQogICAgeCA9IH5QQzEsIHkgPSB+UEMyLA0KICAgIGRhdGEgPSB2YXJfY29vcmQsDQogICAgbWFya2VyID0gbGlzdCgNCiAgICAgIHNpemUgPSAxMCwNCiAgICAgIGNvbG9yID0gfmNvbnRyaWIsDQogICAgICBjb2xvcnNjYWxlID0gbGlzdCgNCiAgICAgICAgYygwLCAiI0ZDRTRFQyIpLA0KICAgICAgICBjKDAuNSwgIiNGOEJCRDkiKSwNCiAgICAgICAgYygxLCAiI0Q4MUI2MCIpDQogICAgICApLA0KICAgICAgc2hvd3NjYWxlID0gVFJVRSwNCiAgICAgIGNvbG9yYmFyID0gbGlzdCh0aXRsZSA9ICJDb250cmlidWNpw7NuIikNCiAgICApLA0KICAgIHRleHQgPSB+dmFyLA0KICAgIGhvdmVyaW5mbyA9ICd0ZXh0JywNCiAgICBob3ZlcnRlbXBsYXRlID0gcGFzdGUoJzxiPiV7dGV4dH08L2I+PGJyPlBDMTogJXt4Oi4yZn08YnI+UEMyOiAle3k6LjJmfTxicj5Db250cmlidWNpb246ICV7bWFya2VyLmNvbG9yOi4yZn08ZXh0cmE+PC9leHRyYT4nKSwNCiAgICBuYW1lID0gIlZhcmlhYmxlcyINCiAgKSAlPiUNCiAgbGF5b3V0KA0KICAgIHRpdGxlID0gIlZhcmlhYmxlcyBEaW1lbnNpw7NuIDEgVlMgMiIsDQogICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gcGFzdGUwKCJEaW1lbnNpw7NuIDEgKCIsIHJvdW5kKHN1bW1hcnkocmVzLnBjYSkkaW1wb3J0YW5jZVsyLDFdKjEwMCwxKSwgIiUpIiksDQogICAgICAgICAgICAgICAgIHJhbmdlID0gYygtMS4xLCAxLjEpKSwNCiAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSBwYXN0ZTAoIkRpbWVuc2nDs24gMiAoIiwgcm91bmQoc3VtbWFyeShyZXMucGNhKSRpbXBvcnRhbmNlWzIsMl0qMTAwLDEpLCAiJSkiKSwNCiAgICAgICAgICAgICAgICAgcmFuZ2UgPSBjKC0xLjEsIDEuMSkpDQogICkgJT4lDQogIGNvbmZpZyhkaXNwbGF5TW9kZUJhciA9IEZBTFNFKQ0KYGBgDQoNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnk7Ij5FbCBncsOhZmljb211ZXN0cmEgcGF0cm9uZXMgY2xhcm9zIHF1ZSBkZWZpbmVuIGEgbGFzIGVjb25vbcOtYXMgZGUgbGEgT0NERS5FbCBwcmltZXIgY3VhZHJhbnRlLCBmb3JtYWRvIHBvciBlbCBQSUIgbm9taW5hbCwgbG9zIGRlZmxhY3RvcmVzIGRlbCBQSUIgeSBlbCB0aXBvIGRlIGNhbWJpbywgZGVmaW5lIGxhIEluZXN0YWJpbGlkYWQgbm9taW5hbCB5IHByZXNpw7NuIGluZmxhY2lvbmFyaWEuIEVzdGFzIHZhcmlhYmxlcyBpbmRpY2FuIHF1ZSB1biBtYXlvciBjcmVjaW1pZW50byBub21pbmFsIHN1ZWxlIGVzdGFyIGltcHVsc2FkbyBwb3IgZWwgYXVtZW50byBkZSBwcmVjaW9zIHkgbm8gcG9yIHVuYSBleHBhbnNpw7NuIHJlYWwsIGxvIHF1ZSByZWZsZWphIHVuYSBtYXlvciBleHBvc2ljacOzbiBhIGxhIGluZXN0YWJpbGlkYWQgbWFjcm9lY29uw7NtaWNhLg0KDQpFbiBjb250cmFzdGUsIGVsIHNlZ3VuZG8gY3VhZHJhbnRlIHNlIG9yaWVudGEgYWwgRGluYW1pc21vIGRlIGxhIGRlbWFuZGEgaW50ZXJuYSB5IHNlY3RvciBleHRlcm5vLCBjb21wdWVzdG8gcG9yIGVsIGNvbnN1bW8gcHJpdmFkbywgbGFzIGltcG9ydGFjaW9uZXMsIGxhIGludmVyc2nDs24geSBlbCBQSUIgcmVhbC4gKipBbCBzZXIgcGVycGVuZGljdWxhciBhbCBwcmltZXJvLCBzdWdpZXJlIHF1ZSBlbCBjcmVjaW1pZW50byByZWFsIHkgbGEgZGVtYW5kYSBpbnRlcm5hIG9wZXJhbiBjb24gcmVsYXRpdmEgaW5kZXBlbmRlbmNpYSBmcmVudGUgYSBsYXMgcHJlc2lvbmVzIGluZmxhY2lvbmFyaWFzLioqDQoNClBvciBvdHJhIHBhcnRlLCBsYSBjdWVudGEgY29ycmllbnRlIHkgbGFzIGV4cG9ydGFjaW9uZXMgbmV0YXMgYXB1bnRhbiBlbiBzZW50aWRvIG9wdWVzdG8gYSBsYSBpbmZsYWNpw7NuIHN1Z2lyaWVub2QgcXVlIGxvcyBwYcOtc2VzIGNvbiBtYXlvciBpbmVzdGFiaWxpZGFkIG5vbWluYWwgdGllbmRlbiBhIHByZXNlbnRhciB1bmEgcG9zaWNpw7NuIGV4dGVybmEgbcOhcyBkw6liaWwsIGNvbiBtYXlvciBkZXBlbmRlbmNpYSBkZSBmaW5hbmNpYW1pZW50byBvIGTDqWZpY2l0cyBjb21lcmNpYWxlcy4NCg0KQXPDrSBpbmRpY2Fkb3JlcyBjb21vIGVsIGNvbnN1bW8gZ3ViZXJuYW1lbnRhbCwgbGFzIGV4cG9ydGFjaW9uZXMgeSBsYSB0YXNhIGRlIGRlc2VtcGxlbyBwcmVzZW50YW4gdW5hIG1lbm9yIGNhcGFjaWRhZCBwYXJhIGRpZmVyZW5jaWFyIGEgbG9zIHBhw61zZXMsIG1vc3RyYW5kbyB1biBjb21wb3J0YW1pZW50byBtw6FzIGhvbW9nw6luZW8gZW4gbGEgbXVlc3RyYS4NCk1vc3RyYW5kbyBxdWUgKiplbCBkZXNlbXBlw7FvIGVjb27Ds21pY28gZGVwZW5kZSBkZSBsYSBpbnRlcmFjY2nDs24gZW50cmUgbGEgZXN0YWJpbGlkYWQgZGUgcHJlY2lvcywgbGEgZm9ydGFsZXphIGRlIGxhIGRlbWFuZGEgaW50ZXJuYSB5IGxhIHBvc2ljacOzbiBleHRlcm5hLCBlbGVtZW50b3MgY2xhdmUgcGFyYSBjYXJhY3Rlcml6YXIgbGEgcmVzaWxpZW5jaWEgcHJvZHVjdGl2YSBhY3R1YWwqKi48L2Rpdj4NCg0KIyMjIDMuNS40IEdyw6FmaWNvIHZhcmlhYmxlcyBEaW1lbnNpw7NuIDIgeSAzDQoNCg0KYGBge3IgIEFDUCBWYXJpYWJsZXMgMiB5IDMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQp2YXJfaW5mbyA8LSBnZXRfcGNhX3ZhcihyZXMucGNhKQ0KdmFyX2Nvb3JkIDwtIGFzLmRhdGEuZnJhbWUocmVzLnBjYSRyb3RhdGlvblssIDI6M10pDQpjb2xuYW1lcyh2YXJfY29vcmQpIDwtIGMoIlBDMiIsICJQQzMiKQ0KdmFyX2Nvb3JkJHZhciA8LSBpY29udih2YXJpYWJsZXNub21icmVzW3Jvd25hbWVzKHZhcl9jb29yZCldLCB0byA9ICJVVEYtOCIsIHN1YiA9ICIgIikNCg0KdmFyX2Nvb3JkJGNvbnRyaWIgPC0gdmFyX2luZm8kY29udHJpYlssIDJdICANCg0KcGxvdF9seSgpICU+JQ0KICBhZGRfc2VnbWVudHMoDQogICAgeCA9IDAsIHkgPSAwLA0KICAgIHhlbmQgPSB+UEMyLCB5ZW5kID0gflBDMywgICAgICAgICAgIw0KICAgIGRhdGEgPSB2YXJfY29vcmQsDQogICAgbGluZSA9IGxpc3QoY29sb3IgPSAiZ3JheSIsIHdpZHRoID0gMS41KSwNCiAgICBzaG93bGVnZW5kID0gRkFMU0UsDQogICAgaG92ZXJpbmZvID0gJ25vbmUnDQogICkgJT4lDQogIGFkZF9tYXJrZXJzKA0KICAgIHggPSB+UEMyLCB5ID0gflBDMywgICAgICAgICAgICAgICAgDQogICAgZGF0YSA9IHZhcl9jb29yZCwNCiAgICBtYXJrZXIgPSBsaXN0KA0KICAgICAgc2l6ZSA9IDEwLA0KICAgICAgY29sb3IgPSB+Y29udHJpYiwNCiAgICAgIGNvbG9yc2NhbGUgPSBsaXN0KA0KICAgICAgICBjKDAsICIjRkNFNEVDIiksDQogICAgICAgIGMoMC41LCAiI0Y4QkJEOSIpLA0KICAgICAgICBjKDEsICIjRDgxQjYwIikNCiAgICAgICksDQogICAgICBzaG93c2NhbGUgPSBUUlVFLA0KICAgICAgY29sb3JiYXIgPSBsaXN0KHRpdGxlID0gIkNvbnRyaWJ1Y2nDs24iKQ0KICAgICksDQogICAgdGV4dCA9IH52YXIsDQogICAgaG92ZXJpbmZvID0gJ3RleHQnLA0KICAgIGhvdmVydGVtcGxhdGUgPSBwYXN0ZSgnPGI+JXt0ZXh0fTwvYj48YnI+UEMyOiAle3g6LjJmfTxicj5QQzM6ICV7eTouMmZ9PGJyPkNvbnRyaWJ1Y2nDs246ICV7bWFya2VyLmNvbG9yOi4yZn08ZXh0cmE+PC9leHRyYT4nKSwNCiAgICBuYW1lID0gIlZhcmlhYmxlcyINCiAgKSAlPiUNCiAgbGF5b3V0KA0KICAgIHRpdGxlID0gIlZhcmlhYmxlcyBEaW1lbnNpw7NuIDIgVlMgMyIsICAgICAgICAgICANCiAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSBwYXN0ZTAoIkRpbWVuc2nDs24gMiAoIiwgcm91bmQoc3VtbWFyeShyZXMucGNhKSRpbXBvcnRhbmNlWzIsMl0qMTAwLDEpLCAiJSkiKSwgIA0KICAgICAgICAgICAgICAgICByYW5nZSA9IGMoLTEuMSwgMS4xKSksDQogICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gcGFzdGUwKCJEaW1lbnNpw7NuIDMgKCIsIHJvdW5kKHN1bW1hcnkocmVzLnBjYSkkaW1wb3J0YW5jZVsyLDNdKjEwMCwxKSwgIiUpIiksIA0KICAgICAgICAgICAgICAgICByYW5nZSA9IGMoLTEuMSwgMS4xKSkNCiAgKSAlPiUNCiAgY29uZmlnKGRpc3BsYXlNb2RlQmFyID0gRkFMU0UpDQpgYGANCg0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeTsiPkVsIGdyw6FmaWNvIG11ZXN0cmEgdW5hIGNsYXJhIHNlZ21lbnRhY2nDs24gZGUgbG9zIG1vdG9yZXMgZWNvbsOzbWljb3MuIEVuIGVsIGN1YWRyYW50ZSBzdXBlcmlvciBkZXJlY2hvLCBzZSBvYnNlcnZhIHVuIGJsb3F1ZSBzw7NsaWRvIGZvcm1hZG8gcG9yIGVsIGNvbnN1bW8gcHJpdmFkbyB5IGxhIGZvcm1hY2nDs24gYnJ1dGEgZGUgY2FwaXRhbCBmaWpvLiBBbCBzZXIgcHLDoWN0aWNhbWVudGUgcGVycGVuZGljdWxhciBhIGxhcyB2YXJpYWJsZXMgZGUgZXhwb3J0YWNpw7NuLCBzdWdpZXJlIHF1ZSBlbCBkaW5hbWlzbW8gYmFzYWRvIGVuIGxhIGRlbWFuZGEgaW50ZXJuYSDigJRjb25zdW1vIGUgaW52ZXJzacOzbuKAlCBvcGVyYSBjb24gcmVsYXRpdmEgaW5kZXBlbmRlbmNpYSBmcmVudGUgYWwgaW1wdWxzbyBxdWUgcHJvdmllbmUgZGVsIHNlY3RvciBleHRlcm5vLg0KDQpFbiBjb250cmFzdGUsIGhhY2lhIGVsIGN1YWRyYW50ZSBpbmZlcmlvciBkZXJlY2hvLCBsYXMgZXhwb3J0YWNpb25lcyB5IGxhIGNvbnRyaWJ1Y2nDs24gZGUgbGFzIGV4cG9ydGFjaW9uZXMgbmV0YXMgYWwgUElCIHJlYWwgc2UgYWdydXBhbiBlbiB1bmEgZGlyZWNjacOzbiBkaXN0aW50YSwgKippbmRpaWNhbmRvICBxdWUgbG9zIHBhw61zZXMgcXVlIGJhc2FuIHN1IGV4cGFuc2nDs24gZW4gZWwgc2VjdG9yIGV4cG9ydGFkb3IgcHJlc2VudGFuIHVuYSBsw7NnaWNhIGRlIGNyZWNpbWllbnRvIGRpZmVyZW50ZSBhIGFxdWVsbG9zIGNlbnRyYWRvcyBlbiBlbCBnYXN0byBpbnRlcm5vLCBldmlkZW5jaWFuZG8gdW5hIGVzcGVjaWFsaXphY2nDs24gZW4gbGEgaW50ZWdyYWNpw7NuIGNvbWVyY2lhbCBnbG9iYWwqKi4NCg0KUG9yIG90cmEgcGFydGUsIHZhcmlhYmxlcyBjb21vIGVsIGRlZmxhY3RvciBkZWwgUElCIHkgZWwgdGlwbyBkZSBjYW1iaW8gc2UgdWJpY2FuIGVuIHVuYSBkaXJlY2Npw7NuIHF1ZSBjb250cmFzdGEgY29uIGVsIHNlY3RvciBleHBvcnRhZG9yLCBzdWdpcmllbmRvIHF1ZSBsYSBjb21wZXRpdGl2aWRhZCBpbnRlcm5hY2lvbmFsIHkgbG9zIHByZWNpb3MgbG9jYWxlcyBtYW50aWVuZW4gdW5hIHJlbGFjacOzbiBkZSB0ZW5zacOzbiBlbiBsYSBlc3RydWN0dXJhIGVjb27Ds21pY2EgZGUgZXN0b3MgcGHDrXNlcy4NCg0KRmluYWxtZW50ZSwgaW5kaWNhZG9yZXMgY29tbyBsYSB0YXNhIGRlIGRlc2VtcGxlbywgbGEgZnVlcnphIGxhYm9yYWwgeSBsYXMgZXhwb3J0YWNpb25lcyB0b3RhbGVzIG11ZXN0cmFuIHVuYSB1YmljYWNpw7NuIG3DoXMgY2VyY2FuYSBhbCBjZW50cm8uIEVzdG8gcmVmbGVqYSB1bmEgbWVub3IgY2FwYWNpZGFkIHBhcmEgZGlmZXJlbmNpYXIgYSBsb3MgcGHDrXNlcywgbG8gcXVlIGluZGljYSB1biBjb21wb3J0YW1pZW50byBtw6FzIGhvbW9nw6luZW8gZW4gbGEgbXVlc3RyYSBwYXJhIGVzdGFzIHZhcmlhYmxlcy4gTW9zdHJhbmRvIHF1ZSBlbCBkZXNlbXBlw7FvIGVjb27Ds21pY28gZGVwZW5kZSBkZSBsYSBpbnRlcmFjY2nDs24gZW50cmUgZWwgaW1wdWxzbyBkZSBsYSBkZW1hbmRhIGludGVybmEgeSBsYSBjb21wZXRpdGl2aWRhZCBleHRlcm5hLCBlbGVtZW50b3MgY2xhdmUgcGFyYSBjYXJhY3Rlcml6YXIgbGEgcmVzaWxpZW5jaWEgcHJvZHVjdGl2YSBhY3R1YWwuPC9kaXY+DQoNCiMjIyAzLjUuNSBHcsOhZmljbyBCaVBsb3QgRGltZW5zacOzbiAxIHkgMg0KDQpgYGB7ciBBQ1AgYmlwbG90IDEgeSAyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KaW5kX2Nvb3JkIDwtIGFzLmRhdGEuZnJhbWUocmVzLnBjYSR4WywgMToyXSkNCmNvbG5hbWVzKGluZF9jb29yZCkgPC0gYygiUEMxIiwgIlBDMiIpDQppbmRfY29vcmQkbGFiZWwgPC0gRGF0b3NFY29uJFBhaXMNCnZhcl9jb29yZCA8LSBhcy5kYXRhLmZyYW1lKHJlcy5wY2Ekcm90YXRpb25bLCAxOjJdKQ0KY29sbmFtZXModmFyX2Nvb3JkKSA8LSBjKCJQQzEiLCAiUEMyIikNCm5vbWJyZXNfbGltcGlvcyA8LSB2YXJpYWJsZXNub21icmVzW3Jvd25hbWVzKHZhcl9jb29yZCldDQpub21icmVzX2xpbXBpb3MgPC0gaWNvbnYobm9tYnJlc19saW1waW9zLCBmcm9tID0gImxhdGluMSIsIHRvID0gIlVURi04Iiwgc3ViID0gImJ5dGUiKQ0Kbm9tYnJlc19saW1waW9zIDwtIGdzdWIoIjxmMT4iLCAibiIsIG5vbWJyZXNfbGltcGlvcywgZml4ZWQgPSBUUlVFKQ0Kbm9tYnJlc19saW1waW9zIDwtIGdzdWIoIjxbMC05YS1mXXsyfT4iLCAiIiwgbm9tYnJlc19saW1waW9zKQ0KdmFyX2Nvb3JkJHZhciA8LSBub21icmVzX2xpbXBpb3MNCnZhcl9jb29yZCR2YXIgPC0gZ3N1YigiW1xyXG5dIiwgIiAiLCB2YXJfY29vcmQkdmFyKQ0KdmFyX2Nvb3JkJHZhciA8LSB0cmltd3ModmFyX2Nvb3JkJHZhcikNCnNjYWxlX2ZhY3RvciA8LSA1DQp2YXJfY29vcmQkUEMxIDwtIHZhcl9jb29yZCRQQzEgKiBzY2FsZV9mYWN0b3INCnZhcl9jb29yZCRQQzIgPC0gdmFyX2Nvb3JkJFBDMiAqIHNjYWxlX2ZhY3Rvcg0KcGxvdF9seSgpICU+JQ0KICBhZGRfbWFya2VycygNCiAgICB4ID0gflBDMSwgeSA9IH5QQzIsDQogICAgZGF0YSA9IGluZF9jb29yZCwNCiAgICBtYXJrZXIgPSBsaXN0KHNpemUgPSA4LCBjb2xvciA9ICIjNjk2OTY5Iiwgb3BhY2l0eSA9IDAuNiksDQogICAgdGV4dCA9IH5sYWJlbCwNCiAgICBob3ZlcmluZm8gPSAndGV4dCcsDQogICAgaG92ZXJ0ZW1wbGF0ZSA9IHBhc3RlKCc8Yj5JbmRpdmlkdW86ICV7dGV4dH08L2I+PGJyPlBDMTogJXt4Oi4yZn08YnI+UEMyOiAle3k6LjJmfTxleHRyYT48L2V4dHJhPicpLA0KICAgIG5hbWUgPSAiSW5kaXZpZHVvcyINCiAgKSAlPiUNCiAgYWRkX3NlZ21lbnRzKA0KICAgIHggPSAwLCB5ID0gMCwNCiAgICB4ZW5kID0gflBDMSwgeWVuZCA9IH5QQzIsDQogICAgZGF0YSA9IHZhcl9jb29yZCwNCiAgICBsaW5lID0gbGlzdChjb2xvciA9ICIjRjhCQkQ5Iiwgd2lkdGggPSAyKSwNCiAgICBzaG93bGVnZW5kID0gRkFMU0UsDQogICAgaG92ZXJpbmZvID0gJ25vbmUnDQogICkgJT4lDQogIGFkZF9tYXJrZXJzKA0KICAgIHggPSB+UEMxLCB5ID0gflBDMiwNCiAgICBkYXRhID0gdmFyX2Nvb3JkLA0KICAgIG1hcmtlciA9IGxpc3Qoc2l6ZSA9IDEwLCBjb2xvciA9ICIjRDgxQjYwIiksDQogICAgdGV4dCA9IH52YXIsDQogICAgaG92ZXJpbmZvID0gJ3RleHQnLA0KICAgIGhvdmVydGVtcGxhdGUgPSBwYXN0ZSgnPGI+JXt0ZXh0fTwvYj48YnI+UEMxOiAle3g6LjJmfTxicj5QQzI6ICV7eTouMmZ9PGV4dHJhPjwvZXh0cmE+JyksDQogICAgbmFtZSA9ICJWYXJpYWJsZXMiDQogICkgJT4lDQogIGxheW91dCgNCiAgICB0aXRsZSA9ICJCaXBsb3QgRGltZW5zaW9uIDEgVlMgMiIsDQogICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gcGFzdGUwKCJEaW1lbnNpb24gMSAoIiwgcm91bmQoc3VtbWFyeShyZXMucGNhKSRpbXBvcnRhbmNlWzIsMV0qMTAwLDEpLCAiJSkiKSwNCiAgICAgICAgICAgICAgICAgemVyb2xpbmUgPSBUUlVFKSwNCiAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSBwYXN0ZTAoIkRpbWVuc2lvbiAyICgiLCByb3VuZChzdW1tYXJ5KHJlcy5wY2EpJGltcG9ydGFuY2VbMiwyXSoxMDAsMSksICIlKSIpLA0KICAgICAgICAgICAgICAgICB6ZXJvbGluZSA9IFRSVUUpDQogICkgJT4lDQogIGNvbmZpZyhkaXNwbGF5TW9kZUJhciA9IEZBTFNFKQ0KYGBgDQoNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnk7Ij5FbCBiaXBsb3QgcmVzdW1lIHBlcm1pdGllbmRvIGlkZW50aWZpY2FyIHBhdHJvbmVzIGNsYXZlIGVudHJlIGxhcyBlY29ub23DrWFzLiBMYSBtYXlvcsOtYSBkZSBsb3MgcGHDrXNlcyBzZSBjb25jZW50cmFuIGVuIGVsIGNlbnRybywgY29tcGFydGllbmRvIGNvbXBvcnRhbWllbnRvcyBtYWNyb2Vjb27Ds21pY29zIHNpbWlsYXJlcywgbWllbnRyYXMgcXVlIGxvcyB2YWxvcmVzIGF0w61waWNvcyBzb24gbG9zIHF1ZSByZXZlbGFuIGxhcyBkaWZlcmVuY2lhcyBtw6FzIGltcG9ydGFudGVzLg0KDQpIYWNpYSBlbCBjdWFkcmFudGUgZGVyZWNobywgQXJnZW50aW5hIHNlIHNlcGFyYSBkZWwgcmVzdG8sIHJlcHJlc2VudGFuZG8gdW4gY2FzbyBleHRyZW1vIGRlIGNyaXNpcyBkZSBlc3RhYmlsaWRhZCBub21pbmFsIGNvbiBpbmZsYWNpw7NuIGRlc2JvcmRhZGEsIGNyZWNpbWllbnRvIG5vbWluYWwgYXJ0aWZpY2lhbCB5IGRlcHJlY2lhY2nDs24gY2FtYmlhcmlhLiBFbiBjb250cmFzdGUsIGVuIGVsIGN1YWRyYW50ZSBzdXBlcmlvciwgKipwYcOtc2VzIGNvbW8gQ29sb21iaWEsIENoaWxlLCBQZXLDuiBlIEluZGlhIGRlc3RhY2FuIHBvciBzdSBkaW5hbWlzbW87IGVzdG9zIHNlIGFsZWphbiBkZWwgY2VudHJvIGRlYmlkbyBhIHVuYSByZWN1cGVyYWNpw7NuIHBvc3QtcGFuZGVtaWEgbcOhcyBpbnRlbnNhLCBpbXB1bHNhZGEgcG9yIHVuIG1heW9yIGNvbnN1bW8gcHJpdmFkbyBlIGludmVyc2nDs24uKioNCg0KRW4gZGVmaW5pdGl2YSwgZXN0ZSBncsOhZmljbyBjb25maXJtYSBxdWUgKiplbCBkZXNlbXBlw7FvIGVjb27Ds21pY28gbm8gcmVzcG9uZGUgYSB1biDDum5pY28gZmFjdG9yKiouIExhIGVzdHJ1Y3R1cmEgbXVlc3RyYSBjw7NtbyBsYSBpbnRlcmFjY2nDs24gZW50cmUgbGEgZXN0YWJpbGlkYWQgZGUgcHJlY2lvcyB5IGVsIGRpbmFtaXNtbyBkZSBsYSBkZW1hbmRhIGludGVybmEgZGVmaW5lIGxhIHJlc2lsaWVuY2lhIHByb2R1Y3RpdmEgYWN0dWFsLCBhZmVjdGFuZG8gZGUgbWFuZXJhIGRlc2lndWFsIGVsIGNyZWNpbWllbnRvIHkgbGEgcG9zaWNpw7NuIGNvbWVyY2lhbCBkZSBjYWRhIHBhw61zIGFudGUgbGEgaW5jZXJ0aWR1bWJyZSBnbG9iYWwuPC9kaXY+DQoNCiMjIyAzLjUuNiBHcsOhZmljbyBCaVBsb3QgRGltZW5zacOzbiAyIHkgMw0KDQpgYGB7ciAgQUNQIGJpcGxvdCAyIHkgMywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmluZF9jb29yZCA8LSBhcy5kYXRhLmZyYW1lKHJlcy5wY2EkeFssIDI6M10pDQpjb2xuYW1lcyhpbmRfY29vcmQpIDwtIGMoIlBDMiIsICJQQzMiKQ0KaW5kX2Nvb3JkJGxhYmVsIDwtIERhdG9zRWNvbiRQYWlzDQp2YXJfY29vcmQgPC0gYXMuZGF0YS5mcmFtZShyZXMucGNhJHJvdGF0aW9uWywgMjozXSkNCmNvbG5hbWVzKHZhcl9jb29yZCkgPC0gYygiUEMyIiwgIlBDMyIpDQpub21icmVzX2xpbXBpb3MgPC0gdmFyaWFibGVzbm9tYnJlc1tyb3duYW1lcyh2YXJfY29vcmQpXQ0Kbm9tYnJlc19saW1waW9zIDwtIGljb252KG5vbWJyZXNfbGltcGlvcywgZnJvbSA9ICJsYXRpbjEiLCB0byA9ICJVVEYtOCIsIHN1YiA9ICJieXRlIikNCm5vbWJyZXNfbGltcGlvcyA8LSBnc3ViKCI8ZjE+IiwgIm4iLCBub21icmVzX2xpbXBpb3MsIGZpeGVkID0gVFJVRSkNCm5vbWJyZXNfbGltcGlvcyA8LSBnc3ViKCI8WzAtOWEtZl17Mn0+IiwgIiIsIG5vbWJyZXNfbGltcGlvcykNCnZhcl9jb29yZCR2YXIgPC0gbm9tYnJlc19saW1waW9zDQp2YXJfY29vcmQkdmFyIDwtIGdzdWIoIltcclxuXSIsICIgIiwgdmFyX2Nvb3JkJHZhcikNCnZhcl9jb29yZCR2YXIgPC0gdHJpbXdzKHZhcl9jb29yZCR2YXIpDQpzY2FsZV9mYWN0b3IgPC0gNQ0KdmFyX2Nvb3JkJFBDMiA8LSB2YXJfY29vcmQkUEMyICogc2NhbGVfZmFjdG9yDQp2YXJfY29vcmQkUEMzIDwtIHZhcl9jb29yZCRQQzMgKiBzY2FsZV9mYWN0b3INCnBsb3RfbHkoKSAlPiUNCiAgYWRkX21hcmtlcnMoDQogICAgeCA9IH5QQzIsIHkgPSB+UEMzLA0KICAgIGRhdGEgPSBpbmRfY29vcmQsDQogICAgbWFya2VyID0gbGlzdChzaXplID0gOCwgY29sb3IgPSAiIzY5Njk2OSIsIG9wYWNpdHkgPSAwLjYpLA0KICAgIHRleHQgPSB+bGFiZWwsDQogICAgaG92ZXJpbmZvID0gJ3RleHQnLA0KICAgIGhvdmVydGVtcGxhdGUgPSBwYXN0ZSgnPGI+SW5kaXZpZHVvOiAle3RleHR9PC9iPjxicj5QQzI6ICV7eDouMmZ9PGJyPlBDMzogJXt5Oi4yZn08ZXh0cmE+PC9leHRyYT4nKSwNCiAgICBuYW1lID0gIkluZGl2aWR1b3MiDQogICkgJT4lDQogIGFkZF9zZWdtZW50cygNCiAgICB4ID0gMCwgeSA9IDAsDQogICAgeGVuZCA9IH5QQzIsIHllbmQgPSB+UEMzLA0KICAgIGRhdGEgPSB2YXJfY29vcmQsDQogICAgbGluZSA9IGxpc3QoY29sb3IgPSAiI0Y4QkJEOSIsIHdpZHRoID0gMiksDQogICAgc2hvd2xlZ2VuZCA9IEZBTFNFLA0KICAgIGhvdmVyaW5mbyA9ICdub25lJw0KICApICU+JQ0KICBhZGRfbWFya2VycygNCiAgICB4ID0gflBDMiwgeSA9IH5QQzMsDQogICAgZGF0YSA9IHZhcl9jb29yZCwNCiAgICBtYXJrZXIgPSBsaXN0KHNpemUgPSAxMCwgY29sb3IgPSAiI0Q4MUI2MCIpLA0KICAgIHRleHQgPSB+dmFyLA0KICAgIGhvdmVyaW5mbyA9ICd0ZXh0JywNCiAgICBob3ZlcnRlbXBsYXRlID0gcGFzdGUoJzxiPiV7dGV4dH08L2I+PGJyPlBDMjogJXt4Oi4yZn08YnI+UEMzOiAle3k6LjJmfTxleHRyYT48L2V4dHJhPicpLA0KICAgIG5hbWUgPSAiVmFyaWFibGVzIg0KICApICU+JQ0KICBsYXlvdXQoDQogICAgdGl0bGUgPSAiQmlwbG90IERpbWVuc2lvbiAyIFZTIDMiLA0KICAgIHhheGlzID0gbGlzdCh0aXRsZSA9IHBhc3RlMCgiRGltZW5zaW9uIDIgKCIsIHJvdW5kKHN1bW1hcnkocmVzLnBjYSkkaW1wb3J0YW5jZVsyLDJdKjEwMCwxKSwgIiUpIiksDQogICAgICAgICAgICAgICAgIHplcm9saW5lID0gVFJVRSksDQogICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gcGFzdGUwKCJEaW1lbnNpb24gMyAoIiwgcm91bmQoc3VtbWFyeShyZXMucGNhKSRpbXBvcnRhbmNlWzIsM10qMTAwLDEpLCAiJSkiKSwNCiAgICAgICAgICAgICAgICAgemVyb2xpbmUgPSBUUlVFKQ0KICApICU+JQ0KICBjb25maWcoZGlzcGxheU1vZGVCYXIgPSBGQUxTRSkNCmBgYA0KDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5OyI+VW4gaGFsbGF6Z28gcmV2ZWxhZG9yIGVzIGVsIHBvc2ljaW9uYW1pZW50byBkZSBBcmdlbnRpbmEsIG1pZW50cmFzIHF1ZSBlbiBsb3MgZGVtw6FzIGdyw6FmaWNvcyBkb21pbmFiYSBjb21vIHVuIHZhbG9yIGF0w61waWNvIGV4dHJlbW8sIGFxdcOtIHNlIHViaWNhIGNlcmNhIGRlbCBjZW50cm8gZW4gdG9kbyBlbCBlamUgaG9yaXpvbnRhbCBjb25maXJtYW5kbyBxdWUgICoqQWdyZW50aW5hIHkgc3UgZGl2ZXJnZW5jaWEgZXN0cnVjdHVyYWwgcmFkaWNhIGNhc2kgZXhjbHVzaXZhbWVudGUgZW4gc3UgaW5lc3RhYmlsaWRhZCBub21pbmFsLCB5IG5vIGVuIHZhcmlhY2lvbmVzIGFuw7NtYWxhcyBkZSBjcmVjaW1pZW50byByZWFsIG8gZGluw6FtaWNhIGV4cG9ydGFkb3JhKiouDQoNCkFsIGV2YWx1YXIgbG9zIGN1YWRyYW50ZXMsIGVsIGNhc28gbcOhcyBsbGFtYXRpdm8gZXMgZWwgZGUgSXJsYW5kYSwgYWlzbGFkYSBlbiBlbCBleHRyZW1vIHN1cGVyaW9yIGl6cXVpZXJkby4gRXN0YSBwb3NpY2nDs24gbm8gcmVmbGVqYSB1bmEgY29udHJhY2Npw7NuIGVjb27Ds21pY2EsIHNpbm8gZWwgaW1wYWN0byBkZSBsYXMgbXVsdGluYWNpb25hbGVzIGFsbMOtIGluc3RhbGFkYXMgcXVlIGdlbmVyYW4gdm9sw7ptZW5lcyBkZSBleHBvcnRhY2nDs24gZ2lnYW50ZXNjb3MgeSB1biBhbHRvIHNhbGRvIGVuIGN1ZW50YSBjb3JyaWVudGUsIGNvbnRyYXN0YW5kbyBjb24gdW4gYmFqbyBjb25zdW1vIHByaXZhZG8uICoqRXMgdW5hIGVzdHJ1Y3R1cmEgcHJvZHVjdGl2YSBxdWUgbGEgcHJvcGlhIE9DREUgcmVjb25vY2UgY29tbyBlc3RhZMOtc3RpY2FtZW50ZSBhdMOtcGljYSBkZW50cm8gZGUgbGFzIGVjb25vbcOtYXMgYXZhbnphZGFzKiouDQoNClBlcm8gZW4gZWwgY3VhZHJhbnRlIHN1cGVyaW9yIGRlcmVjaG8gYWdydXBhIGEgcGHDrXNlcyBjb21vICoqQ29sb21iaWEsIFBlcsO6LCBJbmRpYSwgQ3JvYWNpYSB5IEVzdG9uaWEgcXVlIGVzdGFzIGVjb25vbcOtYXMgZGVzdGFjYW4gY29tbyBtb2RlbG9zIGVuIGV4cGFuc2nDs24gYWN0aXZhLCBsb2dyYW5kbyBhcGFsYW5jYXIgc3UgY3JlY2ltaWVudG8gYWwgY29tYmluYXIgdW4gZnVlcnRlIGRpbmFtaXNtbyBkZSBsYSBkZW1hbmRhIGludGVybmEgY29uIHVuIHPDs2xpZG8gZGVzZW1wZcOxbyBleHBvcnRhZG9yKiouIFBvciBlbCBjb250cmFyaW8sIGVuIGxhIHpvbmEgaW5mZXJpb3IsIHBvdGVuY2lhcyBjb21vIEVzdGFkb3MgVW5pZG9zLCBKYXDDs24geSBCcmFzaWwgbXVlc3RyYW4gdW4gcGF0csOzbiBkZSBjcmVjaW1pZW50byBtdWNobyBtw6FzIG1vZGVyYWRvIHRhbnRvIGVuIHN1IGltcHVsc28gZXh0ZXJubyBjb21vIGVuIHN1IGRlbWFuZGEgZG9tw6lzdGljYSBkZW50cm8gZGUgZXN0ZSBwbGFuby4NCg0KRW4gZGVmaW5pdGl2YSwgZXN0YSByZXByZXNlbnRhY2nDs24gZ3LDoWZpY2EgcGVybWl0ZSBkZXNjaWZyYXIgbG9zIG1vZGVsb3MgcHJvZHVjdGl2b3Mgc3VieWFjZW50ZXMgZGUgbGEgbXVlc3RyYSwgZXZpZGVuY2lhbmRvIHNpIGxhIGV4cGFuc2nDs24gZWNvbsOzbWljYSBkZSB1biBwYcOtcyBzZSBhcGFsYW5jYSBlbiBzdSBtZXJjYWRvIGludGVybm8gbyBlbiBzdSBkZXNlbXBlw7FvIGV4cG9ydGFkb3IuIElkZW50aWZpY2FyIGVzdGFzIGRpZmVyZW5jaWFzIGVzIHVuIGZhY3RvciBjbGF2ZSBwYXJhIGNvbXByZW5kZXIgY8OzbW8gY2FkYSBlY29ub23DrWEgc2UgZXN0w6EgYWRhcHRhbmRvIGEgbGEgYWN0dWFsIHJlb3JnYW5pemFjacOzbiBkZSBsYXMgY2FkZW5hcyBnbG9iYWxlcyBkZSBzdW1pbmlzdHJvIHNlw7FhbGFkYSBlbiBsb3MgcmVwb3J0ZXMgZGUgbGEgT0NERS48L2Rpdj4NCg0KYGBge3IgZ3JhZmljb3MgZGUgbG9zIGNvc29zIGVzb3N9DQppZihpcy5udWxsKHJvd25hbWVzKHJlcy5wY2EkeCkpKSByb3duYW1lcyhyZXMucGNhJHgpIDwtIHBhaXNlcw0KDQpkaXN0cmlidmFyaWFibGVzIDwtIGZ2aXpfY29udHJpYihyZXMucGNhLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDE6MywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGwgPSAiI0ZDRTRFQyIsIGNvbG9yID0gIiNEODFCNjAiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9wID0gMTAsIG9yaWVudGF0aW9uID0gImhvcml6b250YWwiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiI0Q4MUI2MCIsIGZhY2UgPSAiYm9sZCIpKSArDQogIGxhYnModGl0bGUgPSAiQ29udHJpYnVjacOzbiBkZSBsYXMgdmFyaWFibGVzIikNCg0KDQoNCmNvbnRyaWJpbmRpdmlkdW9zIDwtIGZ2aXpfY29udHJpYihyZXMucGNhLCBjaG9pY2UgPSAiaW5kIiwgYXhlcyA9IDE6MiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsID0gIiNGQ0U0RUMiLCBjb2xvciA9ICIjRDgxQjYwIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3AgPSA0Nywgb3JpZW50YXRpb24gPSAiaG9yaXpvbnRhbCIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICIjRDgxQjYwIiwgZmFjZSA9ICJib2xkIikpICsNCiAgbGFicyh0aXRsZSA9ICJDb250cmlidWNpw7NuIGRlIGxvcyBpbmRpdmlkdW9zIikgKw0KICBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9IGZ1bmN0aW9uKHgpIHBhaXNlc1thcy5udW1lcmljKHgpXSkgDQoNCg0KZGlzdHJpYnZhcmlhYmxlcw0KY29udHJpYmluZGl2aWR1b3MNCmBgYA0KDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5OyI+DQoNCmBgYHtyIGV4dHJhY2Npb24gZGUgcmVzdWx0YWRvcywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCmVpZy52YWwgPC0gZ2V0X2VpZ2VudmFsdWUocmVzLnBjYSkNCg0KcmVzLnZhciA8LSBnZXRfcGNhX3ZhcihyZXMucGNhKQ0KcmVzLnZhciRjb29yZA0KcmVzLnZhciRjb250cmliDQpyZXMudmFyJGNvczINCg0KVmlldyhyZXMudmFyJGNvbnRyaWJbLCAxOjNdKQ0KY29sU3VtcyhyZXMudmFyJGNvbnRyaWJbLCAxOjNdKQ0KDQpyZXMuaW5kIDwtIGdldF9wY2FfaW5kKHJlcy5wY2EpDQpyZXMuaW5kJGNvb3JkDQpyZXMuaW5kJGNvbnRyaWINCnJlcy5pbmQkY29zMg0KDQpWaWV3KHJlcy5pbmQkY29udHJpYlssIDE6M10pDQpyZXMuaW5kJGNvbnRyaWJbLCAxOjNdDQpgYGANCg0KIyMgMy42IERlbmRvZ3JhbWEgSmVyw6FxdWljbyAoV2FyZCkNCg0KYGBge3IgY2x1c3RlciBqZXJhcnF1aWNvLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLGZpZy5oZWlnaHQ9NixmaWcud2lkdGg9OX0NCnJvd25hbWVzKHNjb3Jlc19wY2EpIDwtIHBhaXNlcw0KDQpkaXN0X3BhaXNlcyA8LSBkaXN0KHNjb3Jlc19wY2EpDQptb2RlbG9famVyYXJxdWljbyA8LSBoY2x1c3QoZGlzdF9wYWlzZXMsIG1ldGhvZCA9ICJ3YXJkLkQyIikNCmRlbmRfbW9kZWxvIDwtIGFzLmRlbmRyb2dyYW0obW9kZWxvX2plcmFycXVpY28pDQoNCnBhcihsYXMgPSAyKSANCnBsb3QoZGVuZF9tb2RlbG8sIA0KICAgICBjZXggPSAwLjYsIA0KICAgICBtYWluID0gIkRlbmRyb2dyYW1hIGplcmFycXVpY28gKFdhcmQpIiwgDQogICAgIHhsYWIgPSAiIiwgDQogICAgIHlsYWIgPSAiRGlzdGFuY2lhIiwgDQogICAgIHN1YiA9ICIiLA0KICAgICBjb2wgPSAiI0Q4MUI2MCIsICANCiAgICAgZWRnZVBhciA9IGxpc3QoY29sID0gIiNEODFCNjAiLCBsd2QgPSAyKSkgIA0KcGFyKGxhcyA9IDApDQpgYGANCg0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeTsiPkxhIGVzdHJ1Y3R1cmEgYXNpbcOpdHJpY2EgeSBlbiBmb3JtYSBkZSBjYXNjYWRhIHF1ZSBwcmVzZW50YSBlbCBkZW5kcm9ncmFtYSByZWZsZWphIGRlIGZvcm1hIGNsYXJhIHVuIHBhbm9yYW1hIGVjb27Ds21pY28gZ2xvYmFsIHF1ZSBvcGVyYSBhIG3Dumx0aXBsZXMgdmVsb2NpZGFkZXNldmlkZW5jaWFuZG8gdW4gZW5vcm1lIGNlbnRybyBkZSBncmF2ZWRhZCBlbiBsYSBwYXJ0ZSBkZXJlY2hhIGRlbCBncsOhZmljbywgZG9uZGUgbGEgZ3JhbiBtYXlvcsOtYSBkZSBsYXMgbmFjaW9uZXMgc2UgYWdydXBhbiBlc3RyZWNoYW1lbnRlLiBFc3RlIGJsb3F1ZSBhcHJldGFkbyByZXByZXNlbnRhIGEgbGFzIGVjb25vbcOtYXMgZGVzYXJyb2xsYWRhcyB5IGEgbG9zIG1lcmNhZG9zIGZ1ZXJ0ZW1lbnRlIGludGVncmFkb3MgcXVlLCBpbXB1bHNhZG9zIHBvciBsYSBnbG9iYWxpemFjacOzbiBjb21lcmNpYWwsIHNlIGVuZnJlbnRhbiBhIGxvcyBtaXNtb3MgY2ljbG9zLCByZWFjY2lvbmFuZG8gY29uIHBvbMOtdGljYXMgbW9uZXRhcmlhcyBzaW1pbGFyZXMgeSByZXNwaXJhbiBwcsOhY3RpY2FtZW50ZSBhbCBtaXNtbyByaXRtbyBtYWNyb2Vjb27Ds21pY28sIGFsIG90cm8gbGFkbyBsYXMgcmFtYXMgbcOhcyBhbHRhcyBxdWUgc2UgZGVzcHJlbmRlbiBwcm9ncmVzaXZhbWVudGUgaGFjaWEgKipsYSB6b25hIGl6cXVpZXJkYSBhZ3J1cGFuIHJlYWxpZGFkZXMgZXN0cnVjdHVyYWxlcyBkaXN0aW50YXMuIEJsb3F1ZXMgZW1lcmdlbnRlcyBjb21vIGVsIGNvbmZvcm1hZG8gcG9yIENvbG9tYmlhLCBDaGlsZSwgSW5kaWEgeSBQZXLDuiB0cmFuc2l0YW4gcG9yIGNhbWlub3MgY29uIGRpbsOhbWljYXMgcGFydGljdWxhcmVzLCBkZW1vc3RyYW5kbyBxdWUgc3VzIG1vdG9yZXMgZGUgY3JlY2ltaWVudG8gZGVwZW5kZW4gZGUgZnVlcnphcyBkaWZlcmVudGVzIGNvbW8gdW5hIGZ1ZXJ0ZSBleHBhbnNpw7NuIGRlIHN1IGRlbWFuZGEgaW50ZXJuYSBvIHVuYSBtYXlvciBzZW5zaWJpbGlkYWQgYSBsb3MgcHJlY2lvcyBpbnRlcm5hY2lvbmFsZXMqKi4gRW4gY29uanVudG8gIGVsIG7DumNsZW8gZHVybyBkZWwgbXVuZG8gdHJhbnNpdGEgcG9yIHVuYSBtaXNtYSBhdXRvcGlzdGEgbWFjcm9lY29uw7NtaWNhIGVzdGFuZGFyaXphZGEsIG1pZW50cmFzIHF1ZSB1bmEgcGVyaWZlcmlhIGRlIHBhw61zZXMgYXZhbnphIGltcHVsc2FkYSBwb3Igc3VzIHByb3BpYXMgY29uZGljaW9uZXMgaGlzdMOzcmljYXMgeSBlc3RydWN0dXJhbGVzLg0KDQojIyAzLjcgRGVuZG9ncmFtYXMgY2x1c3Rlcml6YWRvcw0KDQpgYGB7ciBkZW5kb2dyYW1hIGFsdHVyYSA4LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLGZpZy5oZWlnaHQ9NixmaWcud2lkdGg9OX0NCmNvbG9yZXNfY2x1c3RlciA8LSBjKCIjMDAwMDAwIiwiIzY5Njk2OSIsIiNGOEJCRDkiLCAiI0Q4MUI2MCIgKQ0KDQpjb3J0ZSA8LSA4DQoNCmRlbmRfbW9kZWxvICU+JSANCiAgY29sb3JfYnJhbmNoZXMoaCA9IGNvcnRlLCBjb2wgPSBjb2xvcmVzX2NsdXN0ZXIpICU+JSANCiAgY29sb3JfbGFiZWxzKGggPSBjb3J0ZSwgY29sID0gY29sb3Jlc19jbHVzdGVyKSAlPiUgDQogIHBsb3QoY2V4ID0gMC42LCBtYWluID0gIkRlbmRyb2dyYW1hIC0gQ2x1c3RlcnMgZGUgcGFpc2VzIiwgeGxhYiA9ICIiLCB5bGFiID0gIkRpc3RhbmNpYSIpDQphYmxpbmUoaCA9IGNvcnRlLCBsdHkgPSAyLCBjb2wgPSAiZ3JheTQwIiwgbHdkID0gMikNCg0KYGBgDQoNCmBgYHtyIGRlbmRvZ3JhbWEgY29uIGNvcnRlIGRlIGsgMywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmNsdXN0ZXJzX2Rlc2VhZG9zIDwtIDMNCmRlbmRfbW9kZWxvICU+JQ0KICBjb2xvcl9icmFuY2hlcyhrID0gY2x1c3RlcnNfZGVzZWFkb3MsIGNvbCA9IGMoIiM2OTY5NjkiLCAiI0Y4QkJEOSIsICIjRDgxQjYwIikpICU+JQ0KICBjb2xvcl9sYWJlbHMoayA9IGNsdXN0ZXJzX2Rlc2VhZG9zLCBjb2wgPSBjKCIjNjk2OTY5IiwgIiNGOEJCRDkiLCAiI0Q4MUI2MCIpKSAlPiUNCiAgcGxvdChtYWluID0gIkRlbmRyb2dyYW1hIC0gMyBjbHVzdGVycyIsIHhsYWIgPSAiIiwgeWxhYiA9ICJEaXN0YW5jaWEiKQ0KcGFyKGxhcyA9IDApDQpgYGANCg0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeTsiPkxvcyBkZW5kb2dyYW1hcyBlc3TDoW4gcmV2ZWxhbmRvIHRyZXMgY29tcG9ydGFtaWVudG9zIG11eSBtYXJjYWRvcyBhbCBlc3RhYmxlY2VyIHVuYSBsw61uZWEgZGUgY29ydGUgY2VyY2FuYSBhIGxhIGRpc3RhbmNpYSBkZSA4LiBQb3IgdW4gbGFkbywgbGEgZ3JhbiBtYXlvcsOtYSBkZSBsYSBtdWVzdHJhIHNlIGNvbmNlbnRyYSBlbiB1biBleHRlbnNvIGJsb3F1ZSBob21vZ8OpbmVvIGEgbGEgZGVyZWNoYSBkZWwgZ3LDoWZpY28sIGluZGljYW5kbyBxdWUgZWNvbm9tw61hcyBjb25zb2xpZGFkYXMgY29tbyBFc3RhZG9zIFVuaWRvcywgQWxlbWFuaWEgeSBKYXDDs24sIGp1bnRvIGNvbiBtZXJjYWRvcyBncmFuZGVzIGNvbW8gQnJhc2lsIHkgTcOpeGljbyBzaWVuZG8gZXN0b3MgbWVyY2Fkb3MgbyBlY29ub21pYXMgcXVlIGNvbXBhcnRlbiBuaXZlbGVzIGRlIGVzdGFiaWxpZGFkIG1hY3JvZWNvbsOzbWljYSBtdXkgc2ltaWxhcmVzLiBFbiBjbGFybyBjb250cmFzdGUsIGVsIGFsZ29yaXRtbyBsb2dyYSBhaXNsYXIgYSBDb2xvbWJpYSwgQ2hpbGUsIEluZGlhIHkgUGVyw7ogZW4gdW4gY2zDunN0ZXIgaW50ZXJtZWRpbyBiYXN0YW50ZSBkZWZpbmlkbywgbG8gcXVlIGRlbXVlc3RyYSBlc3RhZMOtc3RpY2FtZW50ZSBxdWUgZXN0b3MgcGHDrXNlcyBjb21wYXJ0ZW4gdW4gbW9kZWxvIGRlIGNyZWNpbWllbnRvIGFwYWxhbmNhZG8gZnVlcnRlbWVudGUgZW4gc3UgZGVtYW5kYSBpbnRlcm5hLiBGaW5hbG1lbnRlLCBlbCBncsOhZmljbyBldmlkZW5jaWEgZGUgZm9ybWEgY29udHVuZGVudGUgbGFzIG1heW9yZXMgZGl2ZXJnZW5jaWFzIGRlIGxvcyBkYXRvcyBhbCAqKnJhbWlmaWNhciBlbiBzb2xpdGFyaW8gYSBBcmdlbnRpbmEgZSBJcmxhbmRhIGVuIGVsIGV4dHJlbW8gaXpxdWllcmRvLCBjb25maXJtYW5kbyBxdWUgYW1ib3MgY29uZm9ybWFuIGNsw7pzdGVyZXMgaW5kaXZpZHVhbGVzIHBvciBzZXIgY2Fzb3MgYXTDrXBpY29zIGV4dHJlbW9zLCBlbCBwcmltZXJvIHBvciBzdSBmdWVydGUgZGVzY29udHJvbCBpbmZsYWNpb25hcmlvIHkgZWwgc2VndW5kbyBwb3IgZWwgdm9sdW1lbiBkZXNwcm9wb3JjaW9uYWRvIGRlIHN1cyBleHBvcnRhY2lvbmVzIG11bHRpbmFjaW9uYWxlcyoqLg0KDQojIyAzLjggR3LDoWZpY28gZGUgw7NwdGltb3MgY2x1c3RlcnNzDQoNCmBgYHtyIGttZWFucywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmZ2aXpfbmJjbHVzdChzY29yZXNfcGNhLCBGVU4gPSBrbWVhbnMsIG1ldGhvZCA9ICJzaWxob3VldHRlIikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIk51bWVybyBvcHRpbW8gZGUgY2x1c3RlcnMgKFNpbHVldGEgLSBLLW1lYW5zKSIsDQogICAgeCA9ICJOdW1lcm8gZGUgY2x1c3RlcnMgayIsDQogICAgeSA9ICJTaWx1ZXRhIHByb21lZGlvIg0KICApICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9ICIjRDgxQjYwIikNCmBgYA0KDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5OyI+DQoNCmBgYHtyIHRhYmxhIHJhcmEsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQptb2RlbG9fa21lYW5zIDwtIGttZWFucyhzY29yZXNfcGNhLCBjZW50ZXJzID0gMikNCm1vZGVsb19rbWVhbnMkY2VudGVycw0KDQpgYGANCg0KDQpgYGB7ciBjbHVzdGVyIDEgeSAyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0Kc2V0LnNlZWQoMTIzKQ0KbW9kZWxvX2ttZWFucyA8LSBrbWVhbnMoc2NvcmVzX3BjYSwgY2VudGVycyA9IDIpDQoNCmNsdXN0ZXJfcGFpc2VzIDwtIG1vZGVsb19rbWVhbnMkY2x1c3Rlcg0KRGF0b3NFY29uX2FncnVwYWRvcyA8LSBkYXRvc19wY2EgJT4lIA0KICBtdXRhdGUoY2x1c3RlciA9IGNsdXN0ZXJfcGFpc2VzKQ0KaW5kX2Nvb3JkIDwtIGFzLmRhdGEuZnJhbWUocmVzLnBjYSR4WywgMToyXSkNCmNvbG5hbWVzKGluZF9jb29yZCkgPC0gYygiUEMxIiwgIlBDMiIpDQppbmRfY29vcmQkY2x1c3RlciA8LSBmYWN0b3IoY2x1c3Rlcl9wYWlzZXMpDQppbmRfY29vcmQkbGFiZWwgPC0gcm93bmFtZXMoaW5kX2Nvb3JkKQ0Kbl9jbHVzdGVycyA8LSBsZW5ndGgodW5pcXVlKGNsdXN0ZXJfcGFpc2VzKSkNCmNvbG9yZXNfY2x1c3RlciA8LSBzd2l0Y2goYXMuY2hhcmFjdGVyKG5fY2x1c3RlcnMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAiMiIgPSBjKCIjNjk2OTY5IiwgIiNEODFCNjAiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIjMiID0gYygiIzY5Njk2OSIsICIjRjhCQkQ5IiwgIiNEODFCNjAiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIjQiID0gYygiIzY5Njk2OSIsICIjRjhCQkQ5IiwgIiNEODFCNjAiLCAiI0ZDRTRFQyIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAiNSIgPSBjKCIjNjk2OTY5IiwgIiNGOEJCRDkiLCAiI0Q4MUI2MCIsICIjRkNFNEVDIiwgIiMwMDAwMDAiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwKGMoIiM2OTY5NjkiLCAiI0Y4QkJEOSIsICIjRDgxQjYwIiwgIiNGQ0U0RUMiLCAiIzAwMDAwMCIpLCBsZW5ndGgub3V0ID0gbl9jbHVzdGVycykNCikNCmxpYnJhcnkocGxvdGx5KQ0KcGxvdGx5X29iaiA8LSBwbG90X2x5KCkNCmZvciAoaSBpbiBzZXFfYWxvbmcobGV2ZWxzKGluZF9jb29yZCRjbHVzdGVyKSkpIHsNCiAgZ3J1cG8gPC0gbGV2ZWxzKGluZF9jb29yZCRjbHVzdGVyKVtpXQ0KICBkYXRvc19ncnVwbyA8LSBpbmRfY29vcmRbaW5kX2Nvb3JkJGNsdXN0ZXIgPT0gZ3J1cG8sIF0NCiAgDQogIGlmIChucm93KGRhdG9zX2dydXBvKSA+PSAzKSB7DQogICAgZWxpcHNlIDwtIGNhcjo6ZWxsaXBzZSgNCiAgICAgIGNlbnRlciA9IGNvbE1lYW5zKGRhdG9zX2dydXBvWywgYygiUEMxIiwgIlBDMiIpXSksDQogICAgICBzaGFwZSA9IGNvdihkYXRvc19ncnVwb1ssIGMoIlBDMSIsICJQQzIiKV0pLA0KICAgICAgcmFkaXVzID0gc3FydChxY2hpc3EoMC45NSwgZGYgPSAyKSksDQogICAgICBkcmF3ID0gRkFMU0UNCiAgICApDQogICAgcGxvdGx5X29iaiA8LSBwbG90bHlfb2JqICU+JSBhZGRfdHJhY2UoDQogICAgICB4ID0gZWxpcHNlWywgMV0sIHkgPSBlbGlwc2VbLCAyXSwNCiAgICAgIHR5cGUgPSAnc2NhdHRlcicsIG1vZGUgPSAnbGluZXMnLA0KICAgICAgZmlsbCA9ICdub25lJywNCiAgICAgIGxpbmUgPSBsaXN0KGNvbG9yID0gY29sb3Jlc19jbHVzdGVyW2ldLCB3aWR0aCA9IDIpLA0KICAgICAgc2hvd2xlZ2VuZCA9IEZBTFNFLA0KICAgICAgaG92ZXJpbmZvID0gJ25vbmUnDQogICAgKQ0KICB9DQp9DQpwbG90bHlfb2JqIDwtIHBsb3RseV9vYmogJT4lIGFkZF90cmFjZSgNCiAgZGF0YSA9IGluZF9jb29yZCwNCiAgeCA9IH5QQzEsIHkgPSB+UEMyLA0KICB0eXBlID0gJ3NjYXR0ZXInLCBtb2RlID0gJ21hcmtlcnMnLA0KICBjb2xvciA9IH5jbHVzdGVyLA0KICBjb2xvcnMgPSBjb2xvcmVzX2NsdXN0ZXIsDQogIG1hcmtlciA9IGxpc3Qoc2l6ZSA9IDEwLCBvcGFjaXR5ID0gMC44LCBsaW5lID0gbGlzdCh3aWR0aCA9IDEsIGNvbG9yID0gIndoaXRlIikpLA0KICB0ZXh0ID0gfnBhc3RlKGxhYmVsLCAnPGJyPkNsdXN0ZXI6JywgY2x1c3RlciksDQogIGhvdmVyaW5mbyA9ICd0ZXh0JywNCiAgaG92ZXJ0ZW1wbGF0ZSA9IHBhc3RlKCc8Yj4le3RleHR9PC9iPjxicj5QQzE6ICV7eDouMmZ9PGJyPlBDMjogJXt5Oi4yZn08ZXh0cmE+PC9leHRyYT4nKQ0KKSAlPiUNCiAgbGF5b3V0KA0KICAgIHRpdGxlID0gIkdyYWZpY28gZGUgaW5kaXZpZHVvcyBwb3IgY2x1c3RlciAoUEMxIHZzIFBDMikiLA0KICAgIHhheGlzID0gbGlzdCh0aXRsZSA9IHBhc3RlMCgiRGltZW5zaW9uIDEgKCIsIHJvdW5kKHN1bW1hcnkocmVzLnBjYSkkaW1wb3J0YW5jZVsyLDFdKjEwMCwxKSwgIiUpIiksDQogICAgICAgICAgICAgICAgIHplcm9saW5lID0gVFJVRSksDQogICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gcGFzdGUwKCJEaW1lbnNpb24gMiAoIiwgcm91bmQoc3VtbWFyeShyZXMucGNhKSRpbXBvcnRhbmNlWzIsMl0qMTAwLDEpLCAiJSkiKSwNCiAgICAgICAgICAgICAgICAgemVyb2xpbmUgPSBUUlVFKSwNCiAgICBsZWdlbmQgPSBsaXN0KHRpdGxlID0gbGlzdCh0ZXh0ID0gIkNsdXN0ZXIiKSkNCiAgKSAlPiUNCiAgY29uZmlnKGRpc3BsYXlNb2RlQmFyID0gRkFMU0UpDQpwbG90bHlfb2JqDQpgYGANCg0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeTsiPkVsIHByaW1lciBncnVwbywgcmVwcmVzZW50YWRvIHBvciBsb3MgcHVudG9zIHZlcmRlcywgYWN0w7phIGNvbW8gZWwgZ3JhbiBjZW50cm8gZGUgZ3JhdmVkYWQgZGVsIG11bmRvLiBTZSBjb25jZW50cmEgZGUgZm9ybWEgbXV5IGNvbXBhY3RhIGVuIGVsIGxhZG8gaXpxdWllcmRvIGRlbCBwbGFubyAodmFsb3JlcyBiYWpvcyBvIG5lZ2F0aXZvcyBlbiBsYSBEaW1lbnNpw7NuIDEpIHkgbXV5IGNlcmNhIGRlbCBvcmlnZW4gZW4gbGEgRGltZW5zacOzbiAyLiBFc3RvIG5vcyBpbmRpY2EgcXVlIGVzdGUgY2zDunN0ZXIgYWdydXBhIGEgbGEgaW5tZW5zYSBtYXlvcsOtYSBkZSBsYXMgZWNvbm9tw61hcyBhdmFuemFkYXMgKGNvbW8gQWxlbWFuaWEsIE3DqXhpY28sIFN1ZMOhZnJpY2EsIGVudHJlIG90cmFzKSBxdWUgbG9ncmFyb24gbWFudGVuZXIgc3UgYW5jbGFqZSB5IGVzdGFiaWxpZGFkIG5vbWluYWwuIFNvbiBwYcOtc2VzIHF1ZSBwdWRpZXJvbiBjb250ZW5lciBtZWpvciBsYXMgcHJlc2lvbmVzIGluZmxhY2lvbmFyaWFzIHBvc3QtcGFuZGVtaWEgeSBtYW50dXZpZXJvbiB1biByaXRtbyBkZSBjb25zdW1vIGUgaW52ZXJzacOzbiBpbnRlcm5vIG11Y2hvIG3DoXMgbW9kZXJhZG8geSB0cmFkaWNpb25hbC4NCg0KRW4gY2xhcm8gY29udHJhc3RlLCBlbCBzZWd1bmRvIGNsw7pzdGVyIChsb3MgcHVudG9zIG1vcmFkb3MpIGNhcHR1cmEgYSBsYSBwZXJpZmVyaWEgZGl2ZXJnZW50ZSwgZGlzcGVyc8OhbmRvc2UgYW1wbGlhbWVudGUgaGFjaWEgbGEgZGVyZWNoYSB5IGhhY2lhIGFycmliYSBkZWwgZ3LDoWZpY28uIEFsIGxpbWl0YXJzZSBhIHNvbG8gZG9zIGdydXBvcywgZWwgYWxnb3JpdG1vIHNlIHZpbyBvYmxpZ2FkbyBhIG1ldGVyIGVuIGVzdGUgbWlzbW8gc2FjbyBhIHRvZG9zIGxvcyBwYcOtc2VzIHF1ZSByb21waWVyb24gZWwgbW9sZGUgZGUgbGEgbm9ybWFsaWRhZCBkZSBsYSBPQ0RFLiBQb3IgdW4gbGFkbywgZW5nbG9iYSBoYWNpYSBhcnJpYmEgYSBlY29ub23DrWFzIGNvbW8gQ29sb21iaWEsIENoaWxlIGUgSW5kaWEsIHF1ZSBleHBlcmltZW50YXJvbiB1biB2aWdvcm9zbyBkaW5hbWlzbW8gaW1wdWxzYWRvIHBvciBsYSBleHBhbnNpw7NuIGRlIHN1IGRlbWFuZGEgaW50ZXJuYS4gUG9yIG90cm8gbGFkbywgYXJyYXN0cmEgaGFjaWEgbGEgZXh0cmVtYSBkZXJlY2hhIGEgbGFzIGVjb25vbcOtYXMgcXVlIHN1ZnJpZXJvbiBjaG9xdWVzIHNldmVyb3MgZGUgaW5lc3RhYmlsaWRhZCBub21pbmFsIHkgZGVzY29udHJvbCBpbmZsYWNpb25hcmlvLg0KDQpFbiBzw61udGVzaXMsIGVzdGEgY2xhc2lmaWNhY2nDs24gYmluYXJpYSBkaXZpZGUgZWwgcGFub3JhbWEgZWNvbsOzbWljbyBhY3R1YWwgZW4gZG9zIGJsb3F1ZXMgZnVuZGFtZW50YWxlczogdW4gYmxvcXVlIGhlZ2Vtw7NuaWNvIGRlIGVjb25vbcOtYXMgbWFkdXJhcyBlbmZvY2FkYXMgZW4gbGEgZXN0YWJpbGlkYWQgZGUgcHJlY2lvcyB5IGVsIGNyZWNpbWllbnRvIGNvbnNlcnZhZG9yLCBmcmVudGUgYSB1biBibG9xdWUgZGUgZWNvbm9tw61hcyBtw6FzIHZvbMOhdGlsZXMgcXVlLCB5YSBzZWEgcG9yIHVuYSBmdWVydGUgYWNlbGVyYWNpw7NuIGRlIHN1IG1lcmNhZG8gaW50ZXJubyBvIHBvciBjcmlzaXMgaW5mbGFjaW9uYXJpYXMsIHRyYW5zaXRhbiBwb3IgZnVlcmEgZGVsIGNvbXBvcnRhbWllbnRvIGVzdMOhbmRhciBpbnRlcm5hY2lvbmFsLg0KDQpgYGB7ciBkaW1lbnNpb24gMiB5IDMgY2x1c3RlcnMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpjbHVzdGVyX3BhaXNlcyA8LSBtb2RlbG9fa21lYW5zJGNsdXN0ZXINCg0KRGF0b3NFY29uX2FncnVwYWRvcyA8LSBkYXRvc19wY2EgJT4lIA0KICBtdXRhdGUoY2x1c3RlciA9IGNsdXN0ZXJfcGFpc2VzKQ0KDQppbmRfY29vcmQgPC0gYXMuZGF0YS5mcmFtZShyZXMucGNhJHhbLCAyOjNdKQ0KY29sbmFtZXMoaW5kX2Nvb3JkKSA8LSBjKCJQQzIiLCAiUEMzIikNCmluZF9jb29yZCRjbHVzdGVyIDwtIGZhY3RvcihjbHVzdGVyX3BhaXNlcykNCmluZF9jb29yZCRsYWJlbCA8LSByb3duYW1lcyhpbmRfY29vcmQpDQoNCm5fY2x1c3RlcnMgPC0gbGVuZ3RoKHVuaXF1ZShjbHVzdGVyX3BhaXNlcykpDQpjb2xvcmVzX2NsdXN0ZXIgPC0gc3dpdGNoKGFzLmNoYXJhY3RlcihuX2NsdXN0ZXJzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIjIiID0gYygiIzY5Njk2OSIsICIjRDgxQjYwIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICIzIiA9IGMoIiM2OTY5NjkiLCAiI0Y4QkJEOSIsICIjRDgxQjYwIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICI0IiA9IGMoIiM2OTY5NjkiLCAiI0Y4QkJEOSIsICIjRDgxQjYwIiwgIiNGQ0U0RUMiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIjUiID0gYygiIzY5Njk2OSIsICIjRjhCQkQ5IiwgIiNEODFCNjAiLCAiI0ZDRTRFQyIsICIjMDAwMDAwIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlcChjKCIjNjk2OTY5IiwgIiNGOEJCRDkiLCAiI0Q4MUI2MCIsICIjRkNFNEVDIiwgIiMwMDAwMDAiKSwgbGVuZ3RoLm91dCA9IG5fY2x1c3RlcnMpDQopDQoNCmxpYnJhcnkocGxvdGx5KQ0KDQpwbG90bHlfb2JqIDwtIHBsb3RfbHkoKQ0KDQpmb3IgKGkgaW4gc2VxX2Fsb25nKGxldmVscyhpbmRfY29vcmQkY2x1c3RlcikpKSB7DQogIGdydXBvIDwtIGxldmVscyhpbmRfY29vcmQkY2x1c3RlcilbaV0NCiAgZGF0b3NfZ3J1cG8gPC0gaW5kX2Nvb3JkW2luZF9jb29yZCRjbHVzdGVyID09IGdydXBvLCBdDQogIA0KICBpZiAobnJvdyhkYXRvc19ncnVwbykgPj0gMykgew0KICAgIGVsaXBzZSA8LSBjYXI6OmVsbGlwc2UoDQogICAgICBjZW50ZXIgPSBjb2xNZWFucyhkYXRvc19ncnVwb1ssIGMoIlBDMiIsICJQQzMiKV0pLA0KICAgICAgc2hhcGUgPSBjb3YoZGF0b3NfZ3J1cG9bLCBjKCJQQzIiLCAiUEMzIildKSwNCiAgICAgIHJhZGl1cyA9IHNxcnQocWNoaXNxKDAuOTUsIGRmID0gMikpLA0KICAgICAgZHJhdyA9IEZBTFNFDQogICAgKQ0KICAgIHBsb3RseV9vYmogPC0gcGxvdGx5X29iaiAlPiUgYWRkX3RyYWNlKA0KICAgICAgeCA9IGVsaXBzZVssIDFdLCB5ID0gZWxpcHNlWywgMl0sDQogICAgICB0eXBlID0gJ3NjYXR0ZXInLCBtb2RlID0gJ2xpbmVzJywNCiAgICAgIGZpbGwgPSAnbm9uZScsDQogICAgICBsaW5lID0gbGlzdChjb2xvciA9IGNvbG9yZXNfY2x1c3RlcltpXSwgd2lkdGggPSAyKSwNCiAgICAgIHNob3dsZWdlbmQgPSBGQUxTRSwNCiAgICAgIGhvdmVyaW5mbyA9ICdub25lJw0KICAgICkNCiAgfQ0KfQ0KDQpwbG90bHlfb2JqIDwtIHBsb3RseV9vYmogJT4lIGFkZF90cmFjZSgNCiAgZGF0YSA9IGluZF9jb29yZCwNCiAgeCA9IH5QQzIsIHkgPSB+UEMzLA0KICB0eXBlID0gJ3NjYXR0ZXInLCBtb2RlID0gJ21hcmtlcnMnLA0KICBjb2xvciA9IH5jbHVzdGVyLA0KICBjb2xvcnMgPSBjb2xvcmVzX2NsdXN0ZXIsDQogIG1hcmtlciA9IGxpc3Qoc2l6ZSA9IDEwLCBvcGFjaXR5ID0gMC44LCBsaW5lID0gbGlzdCh3aWR0aCA9IDEsIGNvbG9yID0gIndoaXRlIikpLA0KICB0ZXh0ID0gfnBhc3RlKGxhYmVsLCAnPGJyPkNsdXN0ZXI6JywgY2x1c3RlciksDQogIGhvdmVyaW5mbyA9ICd0ZXh0JywNCiAgaG92ZXJ0ZW1wbGF0ZSA9IHBhc3RlKCc8Yj4le3RleHR9PC9iPjxicj5QQzI6ICV7eDouMmZ9PGJyPlBDMzogJXt5Oi4yZn08ZXh0cmE+PC9leHRyYT4nKQ0KKSAlPiUNCiAgbGF5b3V0KA0KICAgIHRpdGxlID0gIkdyYWZpY28gZGUgaW5kaXZpZHVvcyBwb3IgY2x1c3RlciAoUEMyIHZzIFBDMykiLA0KICAgIHhheGlzID0gbGlzdCh0aXRsZSA9IHBhc3RlMCgiRGltZW5zaW9uIDIgKCIsIHJvdW5kKHN1bW1hcnkocmVzLnBjYSkkaW1wb3J0YW5jZVsyLDJdKjEwMCwxKSwgIiUpIiksDQogICAgICAgICAgICAgICAgIHplcm9saW5lID0gVFJVRSksDQogICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gcGFzdGUwKCJEaW1lbnNpb24gMyAoIiwgcm91bmQoc3VtbWFyeShyZXMucGNhKSRpbXBvcnRhbmNlWzIsM10qMTAwLDEpLCAiJSkiKSwNCiAgICAgICAgICAgICAgICAgemVyb2xpbmUgPSBUUlVFKSwNCiAgICBsZWdlbmQgPSBsaXN0KHRpdGxlID0gbGlzdCh0ZXh0ID0gIkNsdXN0ZXIiKSkNCiAgKSAlPiUNCiAgY29uZmlnKGRpc3BsYXlNb2RlQmFyID0gRkFMU0UpDQoNCnBsb3RseV9vYmoNCmBgYA0KDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5OyI+RW4gZXN0ZSBzZWd1bmRvIHBsYW5vLCBlbCBhbGdvcml0bW8gY2xhc2lmaWNhIGxvcyBwYcOtc2VzIGJham8gdW5hIGzDs2dpY2EgZGlzdGludGE6IGVsIGNsw7pzdGVyIHZlcmRlIHNlIG1hbnRpZW5lIGNvbW8gZWwgbsO6Y2xlbyBjZW50cmFsIGRlIGVjb25vbcOtYXMgY29uIHVuIGNvbXBvcnRhbWllbnRvIG3DoXMgbW9kZXJhZG8sIHRhbnRvIGVuIHN1IGRlbWFuZGEgaW50ZXJuYSBjb21vIGVuIHN1IHByb3llY2Npw7NuIGV4dGVybmEuIFNpbiBlbWJhcmdvLCBsYSBncmFuIGRpZmVyZW5jaWEgZXMgcXVlIGVzdGUgZ3J1cG8gYWhvcmEgZXMgbXVjaG8gbcOhcyBpbmNsdXNpdm8sIGFic29yYmllbmRvIGEgbGEgbWF5b3LDrWEgZGUgbGFzIG5hY2lvbmVzIGRlc2Fycm9sbGFkYXMgeSBtZXJjYWRvcyBncmFuZGVzLCBjdXlhIGFjdGl2aWRhZCBlY29uw7NtaWNhIHNlIG11ZXN0cmEgZXN0YWJsZSB5IHByZWRlY2libGUuDQoNClBvciBvdHJvIGxhZG8sIGVsIGNsw7pzdGVyIG1vcmFkbyBzZSBkaXNwZXJzYSBlbiB1bmEgZGlyZWNjacOzbiBxdWUgbWFyY2EgdW5hIGNsYXJhIGRpdmVyZ2VuY2lhIHByb2R1Y3RpdmEuIEFxdcOtIHNlIGFncnVwYW4gZWNvbm9tw61hcyBxdWUsIGR1cmFudGUgZWwgcGVyaW9kbywgbW9zdHJhcm9uIHVuIGRlc2VtcGXDsW8gYXTDrXBpY28gYWwgYWxlamFyc2UgZGUgbGEgbm9ybWE6IHBvciB1biBsYWRvLCBwYcOtc2VzIHF1ZSBpbXB1bHNhcm9uIHN1IGNyZWNpbWllbnRvIGEgdHJhdsOpcyBkZSB1biBkaW5hbWlzbW8gaW50ZXJubyB5IGV4dGVybm8gbcOhcyBhZ3Jlc2l2bywgeSBwb3Igb3RybywgY2Fzb3MgcXVlIHByZXNlbnRhbiB1bmEgZXNwZWNpYWxpemFjacOzbiBvIGVzdHJ1Y3R1cmEgZXhwb3J0YWRvcmEgcXVlIGxvcyBzZXBhcmEgZGVsIGJsb3F1ZSBtYXlvcml0YXJpby4gRXN0YSBjbGFzaWZpY2FjacOzbiBwb25lIGRlIG1hbmlmaWVzdG8gcXVlLCBhbCBlbGltaW5hciBlbCBmYWN0b3IgZGUgaW5lc3RhYmlsaWRhZCBub21pbmFsLCBsYXMgZGlmZXJlbmNpYXMgZW50cmUgcGHDrXNlcyBubyBkZXNhcGFyZWNlbiwgc2lubyBxdWUgc2UgcmVjb25maWd1cmFuIHBhcmEgcmVzYWx0YXIgcXXDqSBuYWNpb25lcyBlc3TDoW4gYWRvcHRhbmRvIG1vZGVsb3MgZGUgY3JlY2ltaWVudG8gbcOhcyBhY3Rpdm9zIGZyZW50ZSBhIGFxdWVsbGFzIGNvbiB1bmEgdHJheWVjdG9yaWEgbcOhcyBjb25zb2xpZGFkYSB5IGNvbnNlcnZhZG9yYS4NCg0KYGBge3IgazMgMXkgMiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCm1vZGVsb19rbWVhbnMgPC0ga21lYW5zKHNjb3Jlc19wY2EsIGNlbnRlcnMgPSAzKQ0KY2x1c3Rlcl9wYWlzZXMgPC0gbW9kZWxvX2ttZWFucyRjbHVzdGVyDQpEYXRvc0Vjb25fYWdydXBhZG9zIDwtIGRhdG9zX3BjYSAlPiUgDQogIG11dGF0ZShjbHVzdGVyID0gY2x1c3Rlcl9wYWlzZXMpDQoNCmluZF9jb29yZCA8LSBhcy5kYXRhLmZyYW1lKHJlcy5wY2EkeFssIDE6Ml0pDQpjb2xuYW1lcyhpbmRfY29vcmQpIDwtIGMoIlBDMSIsICJQQzIiKQ0KaW5kX2Nvb3JkJGNsdXN0ZXIgPC0gZmFjdG9yKGNsdXN0ZXJfcGFpc2VzKQ0KaW5kX2Nvb3JkJGxhYmVsIDwtIHJvd25hbWVzKGluZF9jb29yZCkNCg0Kbl9jbHVzdGVycyA8LSBsZW5ndGgodW5pcXVlKGNsdXN0ZXJfcGFpc2VzKSkNCmNvbG9yZXNfY2x1c3RlciA8LSBzd2l0Y2goYXMuY2hhcmFjdGVyKG5fY2x1c3RlcnMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAiMiIgPSBjKCIjNjk2OTY5IiwgIiNEODFCNjAiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIjMiID0gYygiIzY5Njk2OSIsICIjRjhCQkQ5IiwgIiNEODFCNjAiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIjQiID0gYygiIzY5Njk2OSIsICIjRjhCQkQ5IiwgIiNEODFCNjAiLCAiI0ZDRTRFQyIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAiNSIgPSBjKCIjNjk2OTY5IiwgIiNGOEJCRDkiLCAiI0Q4MUI2MCIsICIjRkNFNEVDIiwgIiMwMDAwMDAiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwKGMoIiM2OTY5NjkiLCAiI0Y4QkJEOSIsICIjRDgxQjYwIiwgIiNGQ0U0RUMiLCAiIzAwMDAwMCIpLCBsZW5ndGgub3V0ID0gbl9jbHVzdGVycykNCikNCg0KbGlicmFyeShwbG90bHkpDQoNCnBsb3RseV9vYmogPC0gcGxvdF9seSgpDQoNCmZvciAoaSBpbiBzZXFfYWxvbmcobGV2ZWxzKGluZF9jb29yZCRjbHVzdGVyKSkpIHsNCiAgZ3J1cG8gPC0gbGV2ZWxzKGluZF9jb29yZCRjbHVzdGVyKVtpXQ0KICBkYXRvc19ncnVwbyA8LSBpbmRfY29vcmRbaW5kX2Nvb3JkJGNsdXN0ZXIgPT0gZ3J1cG8sIF0NCiAgDQogIGlmIChucm93KGRhdG9zX2dydXBvKSA+PSAzKSB7DQogICAgZWxpcHNlIDwtIGNhcjo6ZWxsaXBzZSgNCiAgICAgIGNlbnRlciA9IGNvbE1lYW5zKGRhdG9zX2dydXBvWywgYygiUEMxIiwgIlBDMiIpXSksDQogICAgICBzaGFwZSA9IGNvdihkYXRvc19ncnVwb1ssIGMoIlBDMSIsICJQQzIiKV0pLA0KICAgICAgcmFkaXVzID0gc3FydChxY2hpc3EoMC45NSwgZGYgPSAyKSksDQogICAgICBkcmF3ID0gRkFMU0UNCiAgICApDQogICAgcGxvdGx5X29iaiA8LSBwbG90bHlfb2JqICU+JSBhZGRfdHJhY2UoDQogICAgICB4ID0gZWxpcHNlWywgMV0sIHkgPSBlbGlwc2VbLCAyXSwNCiAgICAgIHR5cGUgPSAnc2NhdHRlcicsIG1vZGUgPSAnbGluZXMnLA0KICAgICAgZmlsbCA9ICdub25lJywNCiAgICAgIGxpbmUgPSBsaXN0KGNvbG9yID0gY29sb3Jlc19jbHVzdGVyW2ldLCB3aWR0aCA9IDIpLA0KICAgICAgc2hvd2xlZ2VuZCA9IEZBTFNFLA0KICAgICAgaG92ZXJpbmZvID0gJ25vbmUnDQogICAgKQ0KICB9DQp9DQoNCnBsb3RseV9vYmogPC0gcGxvdGx5X29iaiAlPiUgYWRkX3RyYWNlKA0KICBkYXRhID0gaW5kX2Nvb3JkLA0KICB4ID0gflBDMSwgeSA9IH5QQzIsDQogIHR5cGUgPSAnc2NhdHRlcicsIG1vZGUgPSAnbWFya2VycycsDQogIGNvbG9yID0gfmNsdXN0ZXIsDQogIGNvbG9ycyA9IGNvbG9yZXNfY2x1c3RlciwNCiAgbWFya2VyID0gbGlzdChzaXplID0gMTAsIG9wYWNpdHkgPSAwLjgsIGxpbmUgPSBsaXN0KHdpZHRoID0gMSwgY29sb3IgPSAid2hpdGUiKSksDQogIHRleHQgPSB+cGFzdGUobGFiZWwsICc8YnI+Q2x1c3RlcjonLCBjbHVzdGVyKSwNCiAgaG92ZXJpbmZvID0gJ3RleHQnLA0KICBob3ZlcnRlbXBsYXRlID0gcGFzdGUoJzxiPiV7dGV4dH08L2I+PGJyPlBDMTogJXt4Oi4yZn08YnI+UEMyOiAle3k6LjJmfTxleHRyYT48L2V4dHJhPicpDQopICU+JQ0KICBsYXlvdXQoDQogICAgdGl0bGUgPSAiR3JhZmljbyBkZSBpbmRpdmlkdW9zIHBvciBjbHVzdGVyIChQQzEgdnMgUEMyKSIsDQogICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gcGFzdGUwKCJEaW1lbnNpb24gMSAoIiwgcm91bmQoc3VtbWFyeShyZXMucGNhKSRpbXBvcnRhbmNlWzIsMV0qMTAwLDEpLCAiJSkiKSwNCiAgICAgICAgICAgICAgICAgemVyb2xpbmUgPSBUUlVFKSwNCiAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSBwYXN0ZTAoIkRpbWVuc2lvbiAyICgiLCByb3VuZChzdW1tYXJ5KHJlcy5wY2EpJGltcG9ydGFuY2VbMiwyXSoxMDAsMSksICIlKSIpLA0KICAgICAgICAgICAgICAgICB6ZXJvbGluZSA9IFRSVUUpLA0KICAgIGxlZ2VuZCA9IGxpc3QodGl0bGUgPSBsaXN0KHRleHQgPSAiQ2x1c3RlciIpKQ0KICApICU+JQ0KICBjb25maWcoZGlzcGxheU1vZGVCYXIgPSBGQUxTRSkNCg0KcGxvdGx5X29iag0KYGBgDQoNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnk7Ij4NCg0KYGBge3IgMiB5IDMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQppbmRfY29vcmQgPC0gYXMuZGF0YS5mcmFtZShyZXMucGNhJHhbLCAyOjNdKQ0KY29sbmFtZXMoaW5kX2Nvb3JkKSA8LSBjKCJQQzIiLCAiUEMzIikNCmluZF9jb29yZCRjbHVzdGVyIDwtIGZhY3RvcihjbHVzdGVyX3BhaXNlcykNCmluZF9jb29yZCRsYWJlbCA8LSByb3duYW1lcyhpbmRfY29vcmQpDQoNCnBsb3RseV9vYmogPC0gcGxvdF9seSgpDQoNCmZvciAoaSBpbiBzZXFfYWxvbmcobGV2ZWxzKGluZF9jb29yZCRjbHVzdGVyKSkpIHsNCiAgZ3J1cG8gPC0gbGV2ZWxzKGluZF9jb29yZCRjbHVzdGVyKVtpXQ0KICBkYXRvc19ncnVwbyA8LSBpbmRfY29vcmRbaW5kX2Nvb3JkJGNsdXN0ZXIgPT0gZ3J1cG8sIF0NCiAgDQogIGlmIChucm93KGRhdG9zX2dydXBvKSA+PSAzKSB7DQogICAgZWxpcHNlIDwtIGNhcjo6ZWxsaXBzZSgNCiAgICAgIGNlbnRlciA9IGNvbE1lYW5zKGRhdG9zX2dydXBvWywgYygiUEMyIiwgIlBDMyIpXSksDQogICAgICBzaGFwZSA9IGNvdihkYXRvc19ncnVwb1ssIGMoIlBDMiIsICJQQzMiKV0pLA0KICAgICAgcmFkaXVzID0gc3FydChxY2hpc3EoMC45NSwgZGYgPSAyKSksDQogICAgICBkcmF3ID0gRkFMU0UNCiAgICApDQogICAgcGxvdGx5X29iaiA8LSBwbG90bHlfb2JqICU+JSBhZGRfdHJhY2UoDQogICAgICB4ID0gZWxpcHNlWywgMV0sIHkgPSBlbGlwc2VbLCAyXSwNCiAgICAgIHR5cGUgPSAnc2NhdHRlcicsIG1vZGUgPSAnbGluZXMnLA0KICAgICAgZmlsbCA9ICdub25lJywNCiAgICAgIGxpbmUgPSBsaXN0KGNvbG9yID0gY29sb3Jlc19jbHVzdGVyW2ldLCB3aWR0aCA9IDIpLA0KICAgICAgc2hvd2xlZ2VuZCA9IEZBTFNFLA0KICAgICAgaG92ZXJpbmZvID0gJ25vbmUnDQogICAgKQ0KICB9DQp9DQoNCnBsb3RseV9vYmogPC0gcGxvdGx5X29iaiAlPiUgYWRkX3RyYWNlKA0KICBkYXRhID0gaW5kX2Nvb3JkLA0KICB4ID0gflBDMiwgeSA9IH5QQzMsDQogIHR5cGUgPSAnc2NhdHRlcicsIG1vZGUgPSAnbWFya2VycycsDQogIGNvbG9yID0gfmNsdXN0ZXIsDQogIGNvbG9ycyA9IGNvbG9yZXNfY2x1c3RlciwNCiAgbWFya2VyID0gbGlzdChzaXplID0gMTAsIG9wYWNpdHkgPSAwLjgsIGxpbmUgPSBsaXN0KHdpZHRoID0gMSwgY29sb3IgPSAid2hpdGUiKSksDQogIHRleHQgPSB+cGFzdGUobGFiZWwsICc8YnI+Q2x1c3RlcjonLCBjbHVzdGVyKSwNCiAgaG92ZXJpbmZvID0gJ3RleHQnLA0KICBob3ZlcnRlbXBsYXRlID0gcGFzdGUoJzxiPiV7dGV4dH08L2I+PGJyPlBDMjogJXt4Oi4yZn08YnI+UEMzOiAle3k6LjJmfTxleHRyYT48L2V4dHJhPicpDQopICU+JQ0KICBsYXlvdXQoDQogICAgdGl0bGUgPSAiR3JhZmljbyBkZSBpbmRpdmlkdW9zIHBvciBjbHVzdGVyIChQQzIgdnMgUEMzKSIsDQogICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gcGFzdGUwKCJEaW1lbnNpb24gMiAoIiwgcm91bmQoc3VtbWFyeShyZXMucGNhKSRpbXBvcnRhbmNlWzIsMl0qMTAwLDEpLCAiJSkiKSwNCiAgICAgICAgICAgICAgICAgemVyb2xpbmUgPSBUUlVFKSwNCiAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSBwYXN0ZTAoIkRpbWVuc2lvbiAzICgiLCByb3VuZChzdW1tYXJ5KHJlcy5wY2EpJGltcG9ydGFuY2VbMiwzXSoxMDAsMSksICIlKSIpLA0KICAgICAgICAgICAgICAgICB6ZXJvbGluZSA9IFRSVUUpLA0KICAgIGxlZ2VuZCA9IGxpc3QodGl0bGUgPSBsaXN0KHRleHQgPSAiQ2x1c3RlciIpKQ0KICApICU+JQ0KICBjb25maWcoZGlzcGxheU1vZGVCYXIgPSBGQUxTRSkNCg0KcGxvdGx5X29iag0KYGBgDQoNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnk7Ij4NCg0KDQpgYGB7ciBib3hwbG90MiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSxmaWcuaGVpZ2h0PTksZmlnLndpZHRoPTl9DQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeSh0aWR5cikNCg0KIyBDYWxjdWxhciBtZWRpYXMgeSBkZXN2aWFjaW9uZXMgcG9yIGNsdXN0ZXINCiMgPT09IFRBQkxBIERFIE1FRElBUyBQT1IgQ0xVU1RFUiAoY29ycmVnaWRhKSA9PT0NCnRhYmxhX21lZGlhcyA8LSBEYXRvc0Vjb25fYWdydXBhZG9zICU+JQ0KICBncm91cF9ieShjbHVzdGVyKSAlPiUNCiAgc3VtbWFyaXNlKGFjcm9zcyh3aGVyZShpcy5udW1lcmljKSwgbWVhbikpICAjIHNvbG8gbnVtw6lyaWNhcw0KDQojIE1vc3RyYXIgdGFibGEgYm9uaXRhIGNvbiBndA0KbGlicmFyeShndCkNCmd0KHRhYmxhX21lZGlhcykgJT4lDQogIHRhYl9oZWFkZXIoDQogICAgdGl0bGUgPSAiTWVkaWFzIGRlIHZhcmlhYmxlcyBwb3IgY2x1c3RlciIsDQogICAgc3VidGl0bGUgPSAiVmFsb3JlcyBvcmlnaW5hbGVzIChubyBlc3RhbmRhcml6YWRvcykiDQogICkgJT4lDQogIGZtdF9udW1iZXIoY29sdW1ucyA9IC1jbHVzdGVyLCBkZWNpbWFscyA9IDIpICU+JQ0KICB0YWJfc3R5bGUoDQogICAgc3R5bGUgPSBsaXN0KGNlbGxfZmlsbChjb2xvciA9ICIjRDgxQjYwIiksIGNlbGxfdGV4dChjb2xvciA9ICJ3aGl0ZSIsIHdlaWdodCA9ICJib2xkIikpLA0KICAgIGxvY2F0aW9ucyA9IGNlbGxzX2NvbHVtbl9sYWJlbHMoZXZlcnl0aGluZygpKQ0KICApICU+JQ0KICB0YWJfb3B0aW9ucyh0YWJsZS53aWR0aCA9IHBjdCgxMDApKQ0KYGBgDQoNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnk7Ij4NCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KIyBjb25jbHVzaW9uZXMgDQoNCmFqc2pha2pzamFza2phcw0KDQojIGJpYmxpb2dyYWZpYSANCmlvYWpzYXMNCg0K