package 㤼㸱tidyverse㤼㸲 was built under R version 3.5.3-- Attaching packages --------------------------------------- tidyverse 1.2.1 --
v ggplot2 3.1.1       v purrr   0.3.2  
v tibble  2.1.1       v dplyr   0.8.0.1
v tidyr   0.8.3       v stringr 1.4.0  
v readr   1.3.1       v forcats 0.4.0  
package 㤼㸱ggplot2㤼㸲 was built under R version 3.5.3-- Conflicts ------------------------------------------ tidyverse_conflicts() --
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()

1 Preparacion de los datos (I)

1.1 Leer el archivo ar_properties.csv y mostrar su estructura.

Parsed with column specification:
cols(
  .default = col_character(),
  start_date = col_date(format = ""),
  end_date = col_date(format = ""),
  created_on = col_date(format = ""),
  lat = col_double(),
  lon = col_double(),
  l6 = col_logical(),
  rooms = col_double(),
  bedrooms = col_double(),
  bathrooms = col_double(),
  surface_total = col_double(),
  surface_covered = col_double(),
  price = col_double()
)
See spec(...) for full column specifications.

Muestro la estructura correspondiente en 24 variables y 388.891 observaciones

Observations: 388,891
Variables: 24
$ id              <chr> "S0we3z3V2JpHUJreqQ2t/w==", "kMxcmAS...
$ ad_type         <chr> "Propiedad", "Propiedad", "Propiedad...
$ start_date      <date> 2019-04-14, 2019-04-14, 2019-04-14,...
$ end_date        <date> 2019-06-14, 2019-04-16, 9999-12-31,...
$ created_on      <date> 2019-04-14, 2019-04-14, 2019-04-14,...
$ lat             <dbl> -34.94331, -34.63181, NA, -34.65471,...
$ lon             <dbl> -54.92966, -58.42060, NA, -58.79089,...
$ l1              <chr> "Uruguay", "Argentina", "Argentina",...
$ l2              <chr> "Maldonado", "Capital Federal", "Bs....
$ l3              <chr> "Punta del Este", "Boedo", NA, "More...
$ l4              <chr> NA, NA, NA, "Moreno", "Moreno", NA, ...
$ l5              <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
$ l6              <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
$ rooms           <dbl> 2, NA, 2, 2, 2, 4, NA, 6, NA, NA, NA...
$ bedrooms        <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
$ bathrooms       <dbl> 1, NA, 1, 2, 3, 1, 3, 3, NA, NA, NA,...
$ surface_total   <dbl> 45, NA, 200, 460, 660, NA, 70, NA, 1...
$ surface_covered <dbl> 40, NA, NA, 100, 148, 89, 122, NA, N...
$ price           <dbl> 13000, 0, NA, NA, NA, NA, NA, NA, 0,...
$ currency        <chr> "UYU", NA, NA, NA, NA, NA, NA, NA, N...
$ price_period    <chr> "Mensual", "Mensual", NA, "Mensual",...
$ title           <chr> "Departamento - Roosevelt", "PH - Bo...
$ property_type   <chr> "Departamento", "PH", "Casa", "Casa"...
$ operation_type  <chr> "Alquiler", "Venta", "Alquiler", "Ve...

1.2 Quedarse con aquellos registros que:

1.2.1 -Pertenecen a Argentina y Capital Federal

1.2.2 - Cuyo precio esta en dolares (USD)

1.2.3 - El tipo de propiedad sea: ### Departamento, PH o Casa

1.3 Seleccionar las variables id, l3, rooms, bedrooms, bathrooms, surface_total, surface_covered, price y property_type.

Deberian llegar a un dataset con 61905 observaciones y 9 variables.️

Observations: 61,905
Variables: 9
$ id              <chr> "oyj+f764ALCYodIqBvWAww==", "HdjpKrq...
$ l3              <chr> "Barracas", "Boedo", "Palermo", "Bel...
$ rooms           <dbl> NA, 6, NA, 3, NA, 3, 1, 1, 1, 1, 1, ...
$ bedrooms        <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
$ bathrooms       <dbl> NA, 2, 2, 4, 1, 2, 1, 1, 1, 1, 1, 1,...
$ surface_total   <dbl> 300, 178, 240, 157, 140, 95, 44, 40,...
$ surface_covered <dbl> 180, 240, 157, NA, 110, 69, 38, 37, ...
$ price           <dbl> 320000, 500000, 350000, 470000, 1550...
$ property_type   <chr> "PH", "Casa", "Casa", "Casa", "Casa"...

2 Analisis exploratorios (I)

2.1 Obtener la cantidad de valores unicos y de valores faltantes (NAs) para cada una de estas variables.

package 㤼㸱kableExtra㤼㸲 was built under R version 3.5.3
Attaching package: 㤼㸱kableExtra㤼㸲

The following object is masked from 㤼㸱package:dplyr㤼㸲:

    group_rows
Cantidad de valores únicos
id_funcion_unicos 61905
l3_funcion_unicos 58
rooms_funcion_unicos 24
bedrooms_funcion_unicos 25
bathrooms_funcion_unicos 15
surface_total_funcion_unicos 671
surface_covered_funcion_unicos 573
price_funcion_unicos 4095
property_type_funcion_unicos 3

Cantidad de valores Faltantes

cantidad porcentaje
id 0 0.0%
l3 355 0.6%
rooms 5314 8.6%
bedrooms 25298 40.9%
bathrooms 3196 5.2%
surface_total 3671 5.9%
surface_covered 2975 4.8%
price 0 0.0%
property_type 0 0.0%

La variable bedrooms presenta una alta proporción de valores faltantes 40.9% , dado que tiene un alta correlacion con la variale rooms, considero eliminar la variable con mayor faltantes no elimina información significativa.

2.2 Obtener la matriz de correlacion para las variables numericas. Pista: usen ‘complete.obs’ para poder omitir los valores faltantes.

rooms bedrooms bathrooms surface_total surface_covered price
rooms 1.0000000 0.9213872 0.6133503 0.0682824 0.0746833 0.4874875
bedrooms 0.9213872 1.0000000 0.6157802 0.0674690 0.0720683 0.4322175
bathrooms 0.6133503 0.6157802 1.0000000 0.0623426 0.0677701 0.5990425
surface_total 0.0682824 0.0674690 0.0623426 1.0000000 0.6965623 0.0509526
surface_covered 0.0746833 0.0720683 0.0677701 0.6965623 1.0000000 0.0625796
price 0.4874875 0.4322175 0.5990425 0.0509526 0.0625796 1.0000000
package 㤼㸱corrplot㤼㸲 was built under R version 3.5.3corrplot 0.84 loaded

3 Preparacion de los datos (II)

3.1 En el punto 2 deberian haber encontrado que la variable bedrooms presenta una alta proporción de valores faltantes y que presenta una fuerte correlacion con la variable rooms. Por lo tanto, vamos a eliminarla.

3.2 Eliminar todos los registros que presentan valores faltantes.

Eliminamos Rooms y variables con missing values

Observations: 51,210
Variables: 8
$ id              <chr> "HdjpKrqdwYfH9YU1DKjltg==", "AfdcsqU...
$ l3              <chr> "Boedo", "Velez Sarsfield", "Nuñez",...
$ rooms           <dbl> 6, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
$ bathrooms       <dbl> 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
$ surface_total   <dbl> 178, 95, 44, 40, 49, 40, 40, 40, 49,...
$ surface_covered <dbl> 240, 69, 38, 37, 44, 37, 37, 37, 44,...
$ price           <dbl> 500000, 199900, 147000, 92294, 11500...
$ property_type   <chr> "Casa", "Casa", "Departamento", "Dep...

4 Análisis exploratorios (II)

4.2 Obtener estadisticas descriptivas para la variable precio (cuartiles, promedio, minimo y maximo) por cada tipo de propiedad.

4.4 Realizar un correlagrama usando GGAlly.

package 㤼㸱GGally㤼㸲 was built under R version 3.5.3
Attaching package: 㤼㸱GGally㤼㸲

The following object is masked from 㤼㸱package:dplyr㤼㸲:

    nasa

De la Figura 4: Correlograma. Se puede observar relación poisitiva entre baños y ambientes. En cuanto superficies (cubierta y total) no puedo observar de este gráfico y por lo tanto lo amplio en la siguiente figura.

5 Outliers

5.0.1 Eliminar los outliers de la variable precio con algún criterio que elijan: puede ser por valores de corte, eliminar el x% a izquierda y derecha,etc.

Tanto en la “Figura 3: Boxplot precio por tipo de propiedad” como en la Figura 1: Histograma de la variable Precio" encuentro que la menor cantidad de datos se encuentra por debajo de 2e+06. Si bien esos datos son validos, comprenden aquellas viviendas de gran tamaño y barrios más caro de la ciudad. Mi analisis es dentro de las propiedades de mayor oferta y por lo tanto decido eliminar los valor por encima de 2e+06.

En “Figura 4: Correlograma” podemos observar en el grafico de precio en funcion de superficie totalse observan dos puntos alejados del resto, esto es con poco precio y gran superficie cubierta. Por otro lado en “Figura 5: Precio en función de la superficie total” también aparece un punto atipico, un PH inusualmente grande, de 32 habitaciones y un precio muy bajo. Considero que debe corresponder a un error de carga. Por lo tanto estos puntos decido eliminarlos también cómo outliers.

6 Analisis exploratorios (III)

6.1 Repetir los 4 análisis exploratorios realizados en el punto 4 y realizar unos breves comentarios sobre los cambios que encontraron.

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   6000  118635  169900  238923  270000 2000000 

Histograma

Medidas de resumen por tipo de propiedad

Boxplot

El correlograma sin outliers muestra una distribución más homogénea en todas las variables.

7 Modelo lineal

7.1 Realizar un modelo lineal simple para explicar el precio en función de las habitaciones (rooms) y otro modelo que explique el precio en función de la superficie total (surface_total).

7.2 Usar la función summary() para obtener informacion de ambos modelos. Explicar los valores de los coeficientes estimados.


Call:
lm(formula = price ~ rooms, data = datasinout)

Residuals:
     Min       1Q   Median       3Q      Max 
-1380571   -84407   -27407    33354  1741833 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -14114.0     1819.6  -7.757 8.88e-15 ***
rooms        90760.3      585.4 155.027  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 181600 on 50967 degrees of freedom
Multiple R-squared:  0.3204,    Adjusted R-squared:  0.3204 
F-statistic: 2.403e+04 on 1 and 50967 DF,  p-value: < 2.2e-16

El coeficiente de ordenada al origen es de -14.114 por lo cual el intercept no es realista para el analisis en cambio la pendiente determina que para un aumento en la cantidad de habitaciones se obtendrá un aumento medio de 90760.3 USD en el precio Ambas mediciones tienen p-value altamente significativos. Es decir, que valor estimado por el modelo para una vivienda de 1 ambiente sería un precio de aproximadamente 76 mil USD, lo cual me parece logico. El r2, o variabilidad explicada por el modelo, es de casi 32%.


Call:
lm(formula = price ~ surface_total, data = datasinout)

Residuals:
     Min       1Q   Median       3Q      Max 
-3366708  -107570   -62810    26782  1715024 

Coefficients:
               Estimate Std. Error t value Pr(>|t|)    
(Intercept)   2.103e+05  1.048e+03  200.73   <2e-16 ***
surface_total 3.009e+02  4.859e+00   61.93   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 212400 on 50967 degrees of freedom
Multiple R-squared:  0.06999,   Adjusted R-squared:  0.06997 
F-statistic:  3836 on 1 and 50967 DF,  p-value: < 2.2e-16

En el modelo 2, el r2 da 6%, el p valor es significativo. Se muestra que para un aumento en la unidad de superficie total el precio tendrá, en este modelo, un aumento medio de 300.9 USD

7.3 ¿Cuál modelo usarían para predecir el precio? ¿Por qué?

El modelo que utiliza las habitaciones como variable me da mayor R cuadrado por lo tanto elegiría ese modelo. Sin embargo si analizo la variable superifice total observo que la mayor cantidad de datos se encuentra por debajo de 1500m2 y un rango de valores que llega hasta aproximadamente 12000 m2, puede considerarse que el modelo lineal no es lo más adecuado para este tipo de distribución.

Gráfico de la regresión lineal de precio en función de la superficie total

LS0tDQp0aXRsZTogIkVFQUEgVHAxIg0KYXV0aG9yOiAiRmVkZXJpY28gTW9yZW5vIg0KZGF0ZTogIjE5IGRlIG9jdHVicmUgZGUgMjAxOSINCmZvbnRzaXplOiAxNnB0DQpvdXRwdXQ6IA0KICBodG1sX25vdGVib29rOg0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KICAgIHRvY19jb2xsYXBzZWQ6IHRydWUgDQogICAgdG9jX2RlcHRoOiA0DQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgdGhlbWU6IHNhbmRzdG9uZQ0KICAgIGhpZ2hsaWdodDogdGFuZ28gDQotLS0NCg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCg0KYm9keXsgLyogTm9ybWFsICAqLw0KICAgICAgZm9udC1zaXplOiAxNHB4Ow0KICB9DQp0ZCB7ICAvKiBUYWJsZSAgKi8NCiAgZm9udC1zaXplOiAxMnB4Ow0KfQ0KaDEudGl0bGUgew0KICBmb250LXNpemU6IDE4cHg7DQogIGNvbG9yOiBEYXJrUmVkOw0KfQ0KaDEgeyAvKiBIZWFkZXIgMSAqLw0KICBmb250LXNpemU6IDE4cHg7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCn0NCmgyIHsgLyogSGVhZGVyIDIgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCn0NCmgzIHsgLyogSGVhZGVyIDMgKi8NCiAgZm9udC1zaXplOiAxNnB4Ow0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgY29sb3I6IERhcmtCbHVlOw0KfQ0KY29kZS5yeyAvKiBDb2RlIGJsb2NrICovDQogICAgZm9udC1zaXplOiAxNHB4Ow0KfQ0KcHJlIHsgLyogQ29kZSBibG9jayAtIGRldGVybWluZXMgY29kZSBzcGFjaW5nIGJldHdlZW4gbGluZXMgKi8NCiAgICBmb250LXNpemU6IDE0cHg7DQp9DQo8L3N0eWxlPg0KDQpgYGB7cn0NCiNDYXJnbyBMaWJyZXLDrWFzDQpsaWJyYXJ5KHJzY29ubmVjdCkNCmxpYnJhcnkodGlkeXZlcnNlKQ0KYGBgDQoNCiMgICAgUHJlcGFyYWNpb24gZGUgbG9zIGRhdG9zIChJKQ0KIyMgICAgICAgIExlZXIgZWwgYXJjaGl2byBhcl9wcm9wZXJ0aWVzLmNzdiB5IG1vc3RyYXIgc3UgZXN0cnVjdHVyYS4NCmBgYHtyIGVjaG89VFJVRSwgbWVzc2FnZT1UUlVFLCB3YXJuaW5nPVRSVUUsIHBhZ2VkLnByaW50PVRSVUV9DQphcl9wcm9wZXJ0aWVzIDwtIHJlYWRfY3N2KCJDOi9Vc2Vycy9mZWRlXy9EZXNrdG9wL01hZXN0cmlhLzYtIEVuZm9xdWUgRXN0YWRpc3RpY28gZGVsIGFwcmVuZGl6YWplL2FyX3Byb3BlcnRpZXMuY3N2IiwgcHJvZ3Jlc3MgPSBGQUxTRSkNCmBgYA0KTXVlc3RybyBsYSBlc3RydWN0dXJhIGNvcnJlc3BvbmRpZW50ZSBlbiAyNCB2YXJpYWJsZXMgeSAzODguODkxIG9ic2VydmFjaW9uZXMNCmBgYHtyfQ0KZ2xpbXBzZShhcl9wcm9wZXJ0aWVzKQ0KYGBgDQojIyAgICAgUXVlZGFyc2UgY29uIGFxdWVsbG9zIHJlZ2lzdHJvcyBxdWU6DQojIyMgICAgIC1QZXJ0ZW5lY2VuIGEgQXJnZW50aW5hIHkgQ2FwaXRhbCBGZWRlcmFsDQojIyMgICAgIC0gQ3V5byBwcmVjaW8gZXN0YSBlbiBkb2xhcmVzIChVU0QpDQojIyMgICAgIC0gRWwgdGlwbyBkZSBwcm9waWVkYWQgc2VhOiAjIyMgRGVwYXJ0YW1lbnRvLCBQSCBvIENhc2ENCiMjIyAgICAgLSBFbCB0aXBvIGRlIG9wZXJhY2lvbiBzZWEgVmVudGENCmBgYHtyfQ0KbGlicmFyeShkcGx5cikNCmZpbHRybzEgPC0gYXJfcHJvcGVydGllcyAlPiUgZmlsdGVyKA0KICAobDE9PSJBcmdlbnRpbmEiICYgbDI9PSJDYXBpdGFsIEZlZGVyYWwiKSAmICNQZXJ0ZW5lY2UgYSBDYXBpdGFsIHkgQXJnZW50aW5hDQogIChjdXJyZW5jeT09IlVTRCIpICYgI1ByZWNpbyBlbiBkb2xhcmVzDQogIChwcm9wZXJ0eV90eXBlPT0iUEgiIHwgcHJvcGVydHlfdHlwZT09IkRlcGFydGFtZW50byIgfHByb3BlcnR5X3R5cGU9PSJDYXNhIikgJiAjVGlwbyBkZSBwcm9waWVkYWQgRGVwYXJ0YW1lbnRvLCBQSCBvIENhc2ENCiAgKG9wZXJhdGlvbl90eXBlPT0iVmVudGEiKSAjIE9wZXJhY2lvbiBkZSB2ZW50YQ0KICApDQpgYGANCiMjICAgICAgU2VsZWNjaW9uYXIgbGFzIHZhcmlhYmxlcyBpZCwgbDMsIHJvb21zLCBiZWRyb29tcywgYmF0aHJvb21zLCBzdXJmYWNlX3RvdGFsLCBzdXJmYWNlX2NvdmVyZWQsIHByaWNlIHkgcHJvcGVydHlfdHlwZS4NCkRlYmVyaWFuIGxsZWdhciBhIHVuIGRhdGFzZXQgY29uIDYxOTA1IG9ic2VydmFjaW9uZXMgeSA5IHZhcmlhYmxlcy7vuI8NCmBgYHtyfQ0KZGF0YXNldCA9IGZpbHRybzEgJT4lDQogIHNlbGVjdChpZCwgbDMsIHJvb21zLCBiZWRyb29tcywgYmF0aHJvb21zLCBzdXJmYWNlX3RvdGFsLCBzdXJmYWNlX2NvdmVyZWQsIHByaWNlICwgcHJvcGVydHlfdHlwZSkNCg0KZ2xpbXBzZShkYXRhc2V0KQ0KYGBgDQojIEFuYWxpc2lzIGV4cGxvcmF0b3Jpb3MgKEkpDQojIyAgICAgIE9idGVuZXIgbGEgY2FudGlkYWQgZGUgdmFsb3JlcyB1bmljb3MgeSBkZSB2YWxvcmVzIGZhbHRhbnRlcyAoTkFzKSBwYXJhIGNhZGEgdW5hIGRlIGVzdGFzIHZhcmlhYmxlcy4NCg0KYGBge3J9DQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpmdW5jaW9uX3VuaWNvcyA8LSBmdW5jdGlvbih4KWxlbmd0aCh1bmlxdWUoeCkpDQojIGxpc3RhIGRlIHVuaWNvcyBwb3IgdmFyaWFibGUsIHRyYXNwdWVzdGEgcGFyYSB2aXN1YWxpemFybG8uDQoNCnVuaWNvcyA8LSBkYXRhc2V0ICU+JQ0KICAgICAgICBkcGx5cjo6c3VtbWFyaXNlX2FsbChsaXN0KGZ1bmNpb25fdW5pY29zID0gZnVuY2lvbl91bmljb3MpKSAlPiUNCiAgICAgICAgICAgICB0KCkNCiNrYWJsZV9zdHlsaW5nIHBhcmEgZm9ybWF0ZWFyDQprbml0cjo6a2FibGUoeCA9dW5pY29zLCBjb2wubmFtZXMgPSAiQ2FudGlkYWQgZGUgdmFsb3JlcyDDum5pY29zIixmb3JtYXQgPSAiaHRtbCIpICU+JQ0KICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRikNCmBgYA0KDQpDYW50aWRhZCBkZSB2YWxvcmVzIEZhbHRhbnRlcw0KYGBge3J9DQpjYW50aWRhZCA8LXNhcHBseShkYXRhc2V0LCBmdW5jdGlvbih5KSBzdW0obGVuZ3RoKHdoaWNoKGlzLm5hKHkpKSkpKQ0KcG9yY2VudGFqZSA9IHNhcHBseShkYXRhc2V0LCBmdW5jdGlvbih5KSAgc3VtKGxlbmd0aCh3aGljaChpcy5uYSh5KSkpKS9zdW0obGVuZ3RoKCh5KSkpKQ0KcG9yY2VudGFqZSA9c2NhbGVzOjpwZXJjZW50KHBvcmNlbnRhamUpDQpkZjMgPC0gcmJpbmQoY2FudGlkYWQsIHBvcmNlbnRhamUpDQpkZjMgPSBkYXRhLmZyYW1lKHQoZGYzKSkNCg0KI290cmEgb3BjaW9uIGRlIEthYmxlIFN0eWxpbmcuDQprYWJsZShkZjMpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIpKQ0KDQpgYGANCkxhIHZhcmlhYmxlIGJlZHJvb21zIHByZXNlbnRhIHVuYSBhbHRhIHByb3BvcmNpw7NuIGRlIHZhbG9yZXMgZmFsdGFudGVzIDQwLjklICwgZGFkbyBxdWUgdGllbmUgdW4gYWx0YSBjb3JyZWxhY2lvbiBjb24gbGEgdmFyaWFsZSByb29tcywgY29uc2lkZXJvIGVsaW1pbmFyIGxhIHZhcmlhYmxlIGNvbiBtYXlvciBmYWx0YW50ZXMgbm8gZWxpbWluYSBpbmZvcm1hY2nDs24gc2lnbmlmaWNhdGl2YS4NCg0KDQojIyAgICAgIE9idGVuZXIgbGEgbWF0cml6IGRlIGNvcnJlbGFjaW9uIHBhcmEgbGFzIHZhcmlhYmxlcyBudW1lcmljYXMuIFBpc3RhOiB1c2VuIOKAmGNvbXBsZXRlLm9ic+KAmSBwYXJhIHBvZGVyIG9taXRpciBsb3MgdmFsb3JlcyBmYWx0YW50ZXMuDQpgYGB7cn0NCmNvcnJlbGFjaW9uIDwtIGNvcihkYXRhc2V0ICU+JSBzZWxlY3RfaWYoaXMubnVtZXJpYykgLCB1c2U9J2NvbXBsZXRlLm9icycpDQprYWJsZShjb3JyZWxhY2lvbikgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIikpDQpgYGANCg0KYGBge3IsIGZpZy5hbGlnbj0iY2VudGVyIiwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NiwgZmlnLmNhcD0iQ29ycmVsYWNpb24uIn0NCg0KbGlicmFyeShjb3JycGxvdCkNCmNvcnJwbG90KGNvcnJlbGFjaW9uLGFkZENvZWYuY29sID0iYmxhY2siLGRpYWc9Rix0eXBlID0gInVwcGVyIikNCg0KYGBgDQojIFByZXBhcmFjaW9uIGRlIGxvcyBkYXRvcyAoSUkpDQojIyAgICAgIEVuIGVsIHB1bnRvIDIgZGViZXJpYW4gaGFiZXIgZW5jb250cmFkbyBxdWUgbGEgdmFyaWFibGUgYmVkcm9vbXMgcHJlc2VudGEgdW5hIGFsdGEgcHJvcG9yY2nDs24gZGUgdmFsb3JlcyBmYWx0YW50ZXMgeSBxdWUgcHJlc2VudGEgdW5hIGZ1ZXJ0ZSBjb3JyZWxhY2lvbiBjb24gbGEgdmFyaWFibGUgcm9vbXMuIFBvciBsbyB0YW50bywgdmFtb3MgYSBlbGltaW5hcmxhLg0KIyMgIEVsaW1pbmFyIHRvZG9zIGxvcyByZWdpc3Ryb3MgcXVlIHByZXNlbnRhbiB2YWxvcmVzIGZhbHRhbnRlcy4NCg0KRWxpbWluYW1vcyBSb29tcyB5IHZhcmlhYmxlcyBjb24gbWlzc2luZyB2YWx1ZXMNCg0KYGBge3J9DQpkYXRhMiA9IGRhdGFzZXQgJTw+JQ0KICBzZWxlY3QoLWJlZHJvb21zKSAlPiUgDQogIGRyb3BfbmEoKQ0KDQpnbGltcHNlKGRhdGEyKQ0KYGBgDQoNCiMgIEFuw6FsaXNpcyBleHBsb3JhdG9yaW9zIChJSSkNCiMjICAgICAgT2J0ZW5lciBlc3RhZGlzdGljYXMgZGVzY3JpcHRpdmFzIHBhcmEgbGEgdmFyaWFibGUgcHJlY2lvIChjdWFydGlsZXMsIHByb21lZGlvLCBtaW5pbW8geSBtYXhpbW8pIHkgcmVhbGl6YXIgdW4gaGlzdG9ncmFtYSBkZSBsYSB2YXJpYWJsZS4NCmBgYHtyfQ0KcHJlY2lvID0gZGF0YTIkcHJpY2UNCnN1bW1hcnkocHJlY2lvKQ0KYGBgDQoNCmBgYHtyLCBmaWcuYWxpZ249ImNlbnRlciIsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTYsIGZpZy5jYXA9J0ZpZ3VyYSAxOiBIaXN0b2dyYW1hIGRlIGxhIHZhcmlhYmxlIFByZWNpbyd9DQpsaWJyYXJ5KGdncGxvdDIpDQpnZ3Bsb3QoZGF0YTIsIGFlcyh4PXByaWNlKSkgKw0KICBnZ3RpdGxlKCdGaWd1cmEgMTogSGlzdG9ncmFtYSBkZSBsYSB2YXJpYWJsZSBQcmVjaW8nKSArDQogIHhsYWIoJ1ByZWNpbyAoVVNEKScpICsNCiAgeWxhYignRnJlY3VlbmNpYScpICsNCiAgZ2VvbV9oaXN0b2dyYW0oZmlsbD0nYmx1ZScsIGNvbG91cj0iZ3JleSIsIGJpbnM9MjUgKQ0KYGBgDQpBcGxpY28gbG9nYXJpdG1vIHBhcmEgc3Vhdml6YXIgbGEgZXNjYWxhDQpgYGB7ciwgZmlnLmFsaWduPSJjZW50ZXIiLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD02LCBmaWcuY2FwPSJGaWd1cmEgMjpIaXN0b2dyYW1hIGRlIGxhIHZhcmlhYmxlIHByZWNpbyBlbiBlc2NhbGEgbG9nYXLDrXRtaWNhIn0NCmdncGxvdChkYXRhMiwgYWVzKHg9cHJpY2UpKSArIGdlb21faGlzdG9ncmFtKGZpbGw9J2JsdWUnLCBjb2xvdXI9ImdyZXkiLCBiaW5zPTI1ICkgKyBzY2FsZV94X2xvZzEwKCkgKw0KICAgICAgbGFicyh0aXRsZT0iRmlndXJhIDI6SGlzdG9ncmFtYSBkZSBsYSB2YXJpYWJsZSBwcmVjaW8gZW4gZXNjYWxhIGxvZ2Fyw610bWljYSIsIHg9InByZWNpbyAoVVNEKSIsIHkgPSAiRnJlY3VlbmNpYSIpDQpgYGANCiMjICAgICAgT2J0ZW5lciBlc3RhZGlzdGljYXMgZGVzY3JpcHRpdmFzIHBhcmEgbGEgdmFyaWFibGUgcHJlY2lvIChjdWFydGlsZXMsIHByb21lZGlvLCBtaW5pbW8geSBtYXhpbW8pIHBvciBjYWRhIHRpcG8gZGUgcHJvcGllZGFkLg0KYGBge3J9DQpwcmVjaW9feF90aXBvIDwtIHRhcHBseShkYXRhMiRwcmljZSxkYXRhMiRwcm9wZXJ0eV90eXBlLHN1bW1hcnkpDQpwcmVjaW9feF90aXBvICA9IGFzLmRhdGEuZnJhbWUoZG8uY2FsbCgncmJpbmQnLHByZWNpb194X3RpcG8gKSkNCnByZWNpb194X3RpcG8NCmBgYA0KIyMgICAgICBSZWFsaXphciB1biBncmFmaWNvIGRlIGJveHBsb3QgZGUgbGEgdmFyaWFibGUgcHJlY2lvIHBvciB0aXBvIGRlIHByb3BpZWRhZC4NCmBgYHtyLCBmaWcuYWxpZ249ImNlbnRlciIsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTYsIGZpZy5jYXA9J0ZpZ3VyYSAzOiBCb3hwbG90IHByZWNpbyBwb3IgdGlwbyBkZSBwcm9waWVkYWQnfQ0KZ2dwbG90KGRhdGEyLCBhZXMoeCA9IHByb3BlcnR5X3R5cGUsIHkgPSBwcmljZSwgZ3JvdXAgPSBwcm9wZXJ0eV90eXBlLCBmaWxsID0gcHJvcGVydHlfdHlwZSApKSArDQogIGdndGl0bGUoJ0ZpZ3VyYSAzOiBCb3hwbG90IHByZWNpbyBwb3IgdGlwbyBkZSBwcm9waWVkYWQnKSArDQogIHhsYWIoJ3RpcG8gZGUgcHJvcGllZGFkJykgKyAgIHN0YXRfYm94cGxvdChnZW9tID0nZXJyb3JiYXInLCB3aWR0aCA9IDAuNikgKw0KICB5bGFiKCdwcmVjaW8nKSArDQogIGdlb21fYm94cGxvdChhbHBoYT0wLjUwKQ0KYGBgDQojIyAgICAgIFJlYWxpemFyIHVuIGNvcnJlbGFncmFtYSB1c2FuZG8gR0dBbGx5Lg0KYGBge3IsIGZpZy5hbGlnbj0iY2VudGVyIiwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NiwgZmlnLmNhcD0iRmlndXJhIDQ6IENvcnJlbG9ncmFtYSJ9DQoNCmxpYnJhcnkoR0dhbGx5KQ0KZmlnNCA9IGdncGFpcnMoZGF0YTIsIGNvbHVtbnM9Mzo3LCBwcm9ncmVzcz1GQUxTRSwgdGl0bGUgPSAiRmlndXJhIDQ6IENvcnJlbG9ncmFtYSIsIG1hcHBpbmcgPSBhZXMoY29sb3VyPSBwcm9wZXJ0eV90eXBlKSkNCg0KZmlnNA0KYGBgDQpEZSBsYSBGaWd1cmEgNDogQ29ycmVsb2dyYW1hLiBTZSBwdWVkZSBvYnNlcnZhciByZWxhY2nDs24gcG9pc2l0aXZhIGVudHJlIGJhw7FvcyB5IGFtYmllbnRlcy4gRW4gY3VhbnRvIHN1cGVyZmljaWVzIChjdWJpZXJ0YSB5IHRvdGFsKSBubyBwdWVkbyBvYnNlcnZhciBkZSBlc3RlIGdyw6FmaWNvIHkgcG9yIGxvIHRhbnRvIGxvIGFtcGxpbyBlbiBsYSBzaWd1aWVudGUgZmlndXJhLg0KDQpgYGB7ciwgZmlnLmFsaWduPSJjZW50ZXIiLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD02LCBmaWcuY2FwPSJGaWd1cmEgNTogUHJlY2lvIGVuIGZ1bmNpw7NuIGRlIGxhIHN1cGVyZmljaWUgdG90YWwifQ0KZ2dwbG90Mjo6Z2dwbG90KGRhdGEyLCBnZ3Bsb3QyOjphZXMoeD1zdXJmYWNlX3RvdGFsLCB5PXByaWNlKSkgKw0KICAgICAgICAgICAgICAgICAgICAgICAgIGdncGxvdDI6Omdlb21fcG9pbnQoZ2dwbG90Mjo6YWVzKGNvbG9yID0gcHJvcGVydHlfdHlwZSkpKw0KICAgICAgICAgICAgICAgICAgICAgICAgIGdncGxvdDI6OmxhYnMoeCA9ICJTdXBlcmZpY2llIFRvdGFsIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gIlByZWNpbyAoVVNEKSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIkZpZ3VyYSA1OiBQcmVjaW8gZW4gZnVuY2nDs24gZGUgbGEgc3VwZXJmaWNpZSB0b3RhbCIpDQpgYGANCiMgIE91dGxpZXJzDQojIyMgICAgIEVsaW1pbmFyIGxvcyBvdXRsaWVycyBkZSBsYSB2YXJpYWJsZSBwcmVjaW8gY29uIGFsZ8O6biBjcml0ZXJpbyBxdWUgZWxpamFuOiBwdWVkZSBzZXIgcG9yIHZhbG9yZXMgZGUgY29ydGUsIGVsaW1pbmFyIGVsIHglIGEgaXpxdWllcmRhIHkgZGVyZWNoYSxldGMuDQoNClRhbnRvIGVuIGxhICJGaWd1cmEgMzogQm94cGxvdCBwcmVjaW8gcG9yIHRpcG8gZGUgcHJvcGllZGFkIiBjb21vIGVuIGxhIEZpZ3VyYSAxOiBIaXN0b2dyYW1hIGRlIGxhIHZhcmlhYmxlIFByZWNpbyIgZW5jdWVudHJvIHF1ZSBsYSBtZW5vciBjYW50aWRhZCBkZSBkYXRvcyBzZSBlbmN1ZW50cmEgcG9yIGRlYmFqbyBkZSAyZSswNi4gU2kgYmllbiBlc29zIGRhdG9zIHNvbiB2YWxpZG9zLCBjb21wcmVuZGVuIGFxdWVsbGFzIHZpdmllbmRhcyBkZSBncmFuIHRhbWHDsW8geSBiYXJyaW9zIG3DoXMgY2FybyBkZSBsYSBjaXVkYWQuIE1pIGFuYWxpc2lzIGVzIGRlbnRybyBkZSBsYXMgcHJvcGllZGFkZXMgZGUgbWF5b3Igb2ZlcnRhIHkgcG9yIGxvIHRhbnRvIGRlY2lkbyBlbGltaW5hciBsb3MgdmFsb3IgcG9yIGVuY2ltYSBkZSAyZSswNi4gDQoNCkVuICJGaWd1cmEgNDogQ29ycmVsb2dyYW1hIiBwb2RlbW9zIG9ic2VydmFyIGVuIGVsIGdyYWZpY28gZGUgcHJlY2lvIGVuIGZ1bmNpb24gZGUgc3VwZXJmaWNpZSB0b3RhbHNlIG9ic2VydmFuIGRvcyBwdW50b3MgYWxlamFkb3MgZGVsIHJlc3RvLCBlc3RvIGVzIGNvbiBwb2NvIHByZWNpbyB5IGdyYW4gc3VwZXJmaWNpZSBjdWJpZXJ0YS4gUG9yIG90cm8gbGFkbyBlbiAiRmlndXJhIDU6IFByZWNpbyBlbiBmdW5jacOzbiBkZSBsYSBzdXBlcmZpY2llIHRvdGFsIiB0YW1iacOpbiBhcGFyZWNlIHVuIHB1bnRvIGF0aXBpY28sIHVuIFBIIGludXN1YWxtZW50ZSBncmFuZGUsIGRlIDMyIGhhYml0YWNpb25lcyB5IHVuIHByZWNpbyBtdXkgYmFqby4gQ29uc2lkZXJvIHF1ZSBkZWJlIGNvcnJlc3BvbmRlciBhIHVuIGVycm9yIGRlIGNhcmdhLiBQb3IgbG8gdGFudG8gZXN0b3MgcHVudG9zIGRlY2lkbyBlbGltaW5hcmxvcyB0YW1iacOpbiBjw7NtbyBvdXRsaWVycy4NCg0KYGBge3J9DQpkYXRhc2lub3V0ID0gZGF0YTIgJT4lIGZpbHRlcihwcmljZSA8PSAyMDAwMDAwICYgc3VyZmFjZV90b3RhbCA8IDE1MDAwICYgcm9vbXMgPCAzMCkNCmBgYA0KIyAgQW5hbGlzaXMgZXhwbG9yYXRvcmlvcyAoSUlJKQ0KIyMgICAgICBSZXBldGlyIGxvcyA0IGFuw6FsaXNpcyBleHBsb3JhdG9yaW9zIHJlYWxpemFkb3MgZW4gZWwgcHVudG8gNCB5IHJlYWxpemFyIHVub3MgYnJldmVzIGNvbWVudGFyaW9zIHNvYnJlIGxvcyBjYW1iaW9zIHF1ZSBlbmNvbnRyYXJvbi4NCmBgYHtyfQ0Kc3VtbWFyeShkYXRhc2lub3V0JHByaWNlKQ0KYGBgDQpIaXN0b2dyYW1hDQpgYGB7ciwgZmlnLmFsaWduPSJjZW50ZXIiLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD02LCBmaWcuY2FwPSJGaWd1cmEgNjogSGlzdG9ncmFtYSBkZSBsYSB2YXJpYWJsZSBwcmVjaW8gKHNpbiBvdXRsaWVycykifSANCmdncGxvdChkYXRhc2lub3V0LCBhZXMoeD1wcmljZSkpICsgZ2VvbV9oaXN0b2dyYW0oZmlsbD0nYmx1ZScsIGNvbG91cj0iZ3JleSIsIGJpbnM9MjUgKSArDQogICAgICBsYWJzKHRpdGxlPSJGaWd1cmEgNjogSGlzdG9ncmFtYSBkZSBsYSB2YXJpYWJsZSBwcmVjaW8gKHNpbiBvdXRsaWVycykiLCB4PSJwcmVjaW8gKFVTRCkiLCB5ID0gIkZyZWN1ZW5jaWEiKQ0KYGBgDQpNZWRpZGFzIGRlIHJlc3VtZW4gcG9yIHRpcG8gZGUgcHJvcGllZGFkDQpgYGB7cn0NCmRhdGFzaW5vdXQgJT4lIGdyb3VwX2J5KHByb3BlcnR5X3R5cGUpICU+JSANCiAgICAgICAgICBzdW1tYXJpc2UoUTEgPSBxdWFudGlsZShwcmljZSwgcHJvYnMgPSAwLjI1KSwgDQogICAgICAgICAgICAgICAgICAgIE1lZGlhbmEgPSBxdWFudGlsZShwcmljZSwgcHJvYnMgPSAwLjUpLCANCiAgICAgICAgICAgICAgICAgICAgUTMgPSBxdWFudGlsZShwcmljZSwgcHJvYnMgPSAwLjc1KSwNCiAgICAgICAgICAgICAgICAgICAgTWVkaWEgPSBtZWFuKHByaWNlKSwNCiAgICAgICAgICAgICAgICAgICAgTWluaW1vID0gbWluKHByaWNlKSwNCiAgICAgICAgICAgICAgICAgICAgTWF4aW1vID0gbWF4KHByaWNlKSkNCmBgYA0KQm94cGxvdA0KYGBge3IsIGZpZy5hbGlnbj0iY2VudGVyIiwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NiwgZmlnLmNhcD0iRmlndXJhIDc6IFByZWNpbyBwb3IgdGlwbyBkZSBwcm9waWVkYWQgKHNpbiBvdXRsaWVycykifQ0KZ2dwbG90KGRhdGFzaW5vdXQsIGFlcyhmaWxsPXByb3BlcnR5X3R5cGUsIHk9cHJpY2UpKSsgZ2VvbV9ib3hwbG90KCkgKyANCiAgICAgICBsYWJzKHkgPSAiUHJlY2lvIChVU0QpIiwNCiAgICAgICAgICAgIHRpdGxlID0gIkZpZ3VyYSA3OiBQcmVjaW8gcG9yIHRpcG8gZGUgcHJvcGllZGFkIChzaW4gb3V0bGllcnMpIiwNCiAgICAgICAgICAgIGZpbGwgPSAiVGlwbyBkZSBwcm9waWVkYWQiKQ0KYGBgDQpgYGB7ciwgZmlnLmFsaWduPSJjZW50ZXIiLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD02LCBmaWcuY2FwPSJGaWd1cmEgODogQ29ycmVsb2dyYW1hIHNpbiBvdXRsaWVycyJ9DQpmaWc4ID0gZ2dwYWlycyhkYXRhc2lub3V0LCBjb2x1bW5zPTM6NywgcHJvZ3Jlc3M9RkFMU0UsIHRpdGxlID0gIkZpZ3VyYSA4OiBDb3JyZWxvZ3JhbWEgc2luIG91dGxpZXJzIiwgbWFwcGluZyA9IGFlcyhjb2xvdXI9IHByb3BlcnR5X3R5cGUpKQ0KZmlnOA0KYGBgDQpFbCBjb3JyZWxvZ3JhbWEgc2luIG91dGxpZXJzIG11ZXN0cmEgdW5hIGRpc3RyaWJ1Y2nDs24gbcOhcyBob21vZ8OpbmVhIGVuIHRvZGFzIGxhcyB2YXJpYWJsZXMuDQoNCiMgIE1vZGVsbyBsaW5lYWwNCiMjICAgICAgUmVhbGl6YXIgdW4gbW9kZWxvIGxpbmVhbCBzaW1wbGUgcGFyYSBleHBsaWNhciBlbCBwcmVjaW8gZW4gZnVuY2nDs24gZGUgbGFzIGhhYml0YWNpb25lcyAocm9vbXMpIHkgb3RybyBtb2RlbG8gcXVlIGV4cGxpcXVlIGVsIHByZWNpbyBlbiBmdW5jacOzbiBkZSBsYSBzdXBlcmZpY2llIHRvdGFsIChzdXJmYWNlX3RvdGFsKS4NCmBgYHtyfQ0KIyBNb2RlbG8gZGUgcHJlY2lvIGVuIGZ1bmNpw7NuIGRlIGxhcyBoYWJpdGFjaW9uZXMNCmRsbTEgPSBsbShwcmljZSB+IHJvb21zLCBkYXRhID0gZGF0YXNpbm91dCkNCg0KIyBNb2RlbG8gZGUgcHJlY2lvIGVuIGZ1bmNpw7NuIGRlIGxhIHN1cGVyZmljaWUgdG90YWwNCmRsbTIgPSBsbShwcmljZSB+IHN1cmZhY2VfdG90YWwsIGRhdGEgPSBkYXRhc2lub3V0KQ0KYGBgDQojIyAgICAgIFVzYXIgbGEgZnVuY2nDs24gc3VtbWFyeSgpIHBhcmEgb2J0ZW5lciBpbmZvcm1hY2lvbiBkZSBhbWJvcyBtb2RlbG9zLiBFeHBsaWNhciBsb3MgdmFsb3JlcyBkZSBsb3MgY29lZmljaWVudGVzIGVzdGltYWRvcy4NCmBgYHtyfQ0KIyBNb2RlbG8gZGUgcHJlY2lvIGVuIGZ1bmNpw7NuIGRlIGxhcyBoYWJpdGFjaW9uZXMNCnN1bW1hcnkoZGxtMSkNCmBgYA0KRWwgY29lZmljaWVudGUgZGUgb3JkZW5hZGEgYWwgb3JpZ2VuIGVzIGRlIC0xNC4xMTQgcG9yIGxvIGN1YWwgZWwgaW50ZXJjZXB0IG5vIGVzIHJlYWxpc3RhIHBhcmEgZWwgYW5hbGlzaXMgZW4gY2FtYmlvIGxhIHBlbmRpZW50ZSBkZXRlcm1pbmEgcXVlIHBhcmEgdW4gYXVtZW50byBlbiBsYSBjYW50aWRhZCBkZSBoYWJpdGFjaW9uZXMgc2Ugb2J0ZW5kcsOhIHVuIGF1bWVudG8gbWVkaW8gZGUgOTA3NjAuMyBVU0QgZW4gZWwgcHJlY2lvIEFtYmFzIG1lZGljaW9uZXMgdGllbmVuIHAtdmFsdWUgYWx0YW1lbnRlIHNpZ25pZmljYXRpdm9zLiBFcyBkZWNpciwgcXVlIHZhbG9yIGVzdGltYWRvIHBvciBlbCBtb2RlbG8gcGFyYSB1bmEgdml2aWVuZGEgZGUgMSBhbWJpZW50ZSBzZXLDrWEgdW4gcHJlY2lvIGRlIGFwcm94aW1hZGFtZW50ZSA3NiBtaWwgVVNELCBsbyBjdWFsIG1lIHBhcmVjZSBsb2dpY28uIEVsIHIyLCBvIHZhcmlhYmlsaWRhZCBleHBsaWNhZGEgcG9yIGVsIG1vZGVsbywgZXMgZGUgY2FzaSAzMiUuDQoNCg0KDQpgYGB7cn0NCiMgTW9kZWxvIGRlIHByZWNpbyBlbiBmdW5jacOzbiBkZSBsYSBzdXBlcmZpY2llIHRvdGFsDQpzdW1tYXJ5KGRsbTIpDQpgYGANCg0KRW4gZWwgbW9kZWxvIDIsIGVsIHIyIGRhIDYlLCBlbCBwIHZhbG9yIGVzIHNpZ25pZmljYXRpdm8uIFNlIG11ZXN0cmEgcXVlIHBhcmEgdW4gYXVtZW50byBlbiBsYSB1bmlkYWQgZGUgc3VwZXJmaWNpZSB0b3RhbCBlbCBwcmVjaW8gdGVuZHLDoSwgZW4gZXN0ZSBtb2RlbG8sIHVuIGF1bWVudG8gbWVkaW8gZGUgMzAwLjkgVVNEDQoNCiMjICAgICAgwr9DdcOhbCBtb2RlbG8gdXNhcsOtYW4gcGFyYSBwcmVkZWNpciBlbCBwcmVjaW8/IMK/UG9yIHF1w6k/DQoNCkVsIG1vZGVsbyBxdWUgdXRpbGl6YSBsYXMgaGFiaXRhY2lvbmVzIGNvbW8gdmFyaWFibGUgbWUgZGEgbWF5b3IgUiBjdWFkcmFkbyBwb3IgbG8gdGFudG8gZWxlZ2lyw61hIGVzZSBtb2RlbG8uIFNpbiBlbWJhcmdvIHNpIGFuYWxpem8gbGEgdmFyaWFibGUgc3VwZXJpZmljZSB0b3RhbCBvYnNlcnZvIHF1ZSBsYSBtYXlvciBjYW50aWRhZCBkZSBkYXRvcyBzZSBlbmN1ZW50cmEgcG9yIGRlYmFqbyBkZSAxNTAwbTIgeSB1biByYW5nbyBkZSB2YWxvcmVzIHF1ZSBsbGVnYSBoYXN0YSBhcHJveGltYWRhbWVudGUgMTIwMDAgbTIsIHB1ZWRlIGNvbnNpZGVyYXJzZSBxdWUgZWwgbW9kZWxvIGxpbmVhbCBubyBlcyBsbyBtw6FzIGFkZWN1YWRvIHBhcmEgZXN0ZSB0aXBvIGRlIGRpc3RyaWJ1Y2nDs24uDQoNCmBgYHtyLCBmaWcuYWxpZ249ImNlbnRlciIsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTYsIGZpZy5jYXA9IkZpZ3VyYSA5OiBNb2RlbG8gbGluZWFsIHBhcmEgZWwgcHJlY2lvIGVuIGZ1bmNpw7NuIGRlIGNhbnRpZGFkIGRlIGhhYml0YWNpb25lcyJ9DQpnZ3Bsb3QyOjpnZ3Bsb3QoZGF0YXNpbm91dCwgZ2dwbG90Mjo6YWVzKHg9cm9vbXMsIHk9cHJpY2UpKSArDQogICAgICAgICAgICAgICAgICAgICAgICAgZ2dwbG90Mjo6Z2VvbV9wb2ludChnZ3Bsb3QyOjphZXMoY29sb3IgPSBwcm9wZXJ0eV90eXBlKSkgKw0KICAgICAgICAgICAgICAgICAgICAgICAgIGdncGxvdDI6Omdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIpICsNCiAgICAgICAgICAgICAgICAgICAgICAgICBnZ3Bsb3QyOjpsYWJzKHggPSAiQ2FudGlkYWQgZGUgaGFiaXRhY2lvbmVzIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gIlByZWNpbyAoVVNEKSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJGaWd1cmEgOTogTW9kZWxvIGxpbmVhbCBwYXJhIGVsIHByZWNpbyBlbiBmdW5jacOzbiBkZSBjYW50aWRhZCBkZSBoYWJpdGFjaW9uZXMiKSArDQogICAgICAgICAgICAgICAgICAgICAgICAgZ2dwbG90Mjo6bGFicyhmaWxsID0gIlRpcG8gZGUgcHJvcGllZGFkIikNCmBgYA0KDQpHcsOhZmljbyBkZSBsYSByZWdyZXNpw7NuIGxpbmVhbCBkZSBwcmVjaW8gZW4gZnVuY2nDs24gZGUgbGEgc3VwZXJmaWNpZSB0b3RhbA0KYGBge3IsZmlnLmFsaWduPSJjZW50ZXIiLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD02LCBmaWcuY2FwPSJGaWd1cmEgMTA6IE1vZGVsbyBsaW5lYWwgcGFyYSBlbCBwcmVjaW8gZW4gZnVuY2nDs24gZGUgbGEgc3VwZXJmaWNpZSB0b3RhbCJ9IA0KDQpnZ3Bsb3QyOjpnZ3Bsb3QoZGF0YXNpbm91dCwgZ2dwbG90Mjo6YWVzKHg9c3VyZmFjZV90b3RhbCx5PXByaWNlKSkgKyBnZ3Bsb3QyOjpnZW9tX3BvaW50KGdncGxvdDI6OmFlcyhjb2xvciA9IHByb3BlcnR5X3R5cGUpKSArICBnZ3Bsb3QyOjpnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKSArICAgICAgICAgICBnZ3Bsb3QyOjpsYWJzKHggPSAiU3VwZXJmaWNpZSB0b3RhbCAobTIpIix5ID0gIlByZWNpbyAoVVNEKSIsdGl0bGUgPSAiRmlndXJhIDEwOiBNb2RlbG8gbGluZWFsIHBhcmEgZWwgcHJlY2lvIGVuIGZ1bmNpw7NuIGRlIGxhIHN1cGVyZmljaWUgdG90YWwiKQ0KYGBgDQoNCg0KDQoNCg==