Sandra Katteryne Rodriguez Hurtado

El presente trabajo no tiene tildes ni la presencia de la letra n debido a que la version de RStudio con la que se realizo el informe no las maneja.

El departamento de Caqueta fue fundado el 02 de Mayo de 1845, se encuentra localizado al Sur de Colombia, tiene una extension de 88.965 km2 aproximadamente, esta dividido en 16 municipios, donde se encuentran muchos caserios y sitios poblados. Este departamento juega un papel importante en la biodiversidad debido a que un porcentaje importante de su territorio pertenece al sistema Amazonico, pie de monte Amazonico, se encuentran hacentamientos humanos, y por ende la dinamica sociopolitica y economica (Gobernacion de Caqueta, s.f).
En el presente cuaderno se hablara sobre el tema de cartografia tematica del departamento de Caqueta, donde se realizaran varios mapas en el programa RStudio, enfocados a dos temas: Las Neceisdades Basicas Insatisfechas (NBI) que presentan los habitantes de cada municipio y produccion en el ano 2018 de algunos cultivos en Caqueta.

Mapa tematico

Acorde con Briney (2019), un mapa tematico se basa en un tema en especifico, es una representacion de una situacion que esta ocurriendo en un lugar determinado y cuya informacion quiere ser divulgada. Son diferentes a los mapas de referencia, pues estos tienen como fin mostrar caracteristicas naturales y artificiales, sin embargo elementos de los mapas de referencia pueden aparecer en los mapas tematicos como puntos de referencia. Briney tambien menciona que es de vital importancia saber a que tipo de publico va dirigido el mapa, debido a que se deben agregar elementos adicionales que faciliten su entendimiento, y estos difieren y se acomodan a cada uno de los grupos. Acorde con lo anterior, es importante acudir a fuentes confiables al recolectar informacion ya que dara como resultado un mapa confiable y preciso.

Acontinuacion se hablara sobre algunos tipos de mapas tematicos, para que sirven, que representan y como se hicieron en RStudio. ### Datos Las fuentes de los datos para la realizacion de los mapas se basaran en el Geoportal del DANE del archivo Neceisdades Basicas Insatisfechas (NBI) del ano 2018. En el portal del DANE se puede obtener informacion util al realizar mapas tematicos de la demografica con variables como nivel educativo, estado civil, salud, setcicios publicos, caracteristicas de vivienda, entre otras. El archivo de NBI fue descargado en formato .xlxs, eliminando y acomodando informacion necesaria para llevar a cabo los mapas del departamento de Caqueta, e importado a RStudio. ### Preparacion de nprograma RStudio Primero se borraran datos de la memoria.

rm(list=ls())

Cargar librerias.

Se instalaran las librerias necesarias: tidiverse (para hacer joins y filtrados), readxl (para leer archivos de excel), rgeos (para entender operaciones espaciales sp), sf (lee y almacena datos como elementos espaciales simples), cartography y SpatialPosition (encargados de la cartografia tematica). En esta ocasion se trabajara con la libreria cartograpgy para realizar los mapas tematicos del departamento de Caqueta, sustituyendo la libreria leaflet.

list.of.packages <- c("tidyverse", "rgeos", "sf", "raster", "cartography", "SpatialPosition")
new.packages <- list.of.packages[!(list.of.packages %in% installed.packages()[,"Package"])]
if(length(new.packages)) install.packages(new.packages)

Se cargaran las librerias necesarias para poder realizar el trabajo.

library(tidyverse)
library(readxl)
library(rgeos)
library(raster) 
library(sf)
library(cartography)
library(SpatialPosition)

Leer los datos de NBI

Es necesario leer los datos del archivo con formato .xlxs, Necesidades Basicas Insatisfechas (NBI), descargado del geoportal del DANE, para tener informacion sobre NBI de los municipios del departamento de Caqueta. Recibira el nombre de nbi.

nbi <- read_excel("C:/Users/Juan/Desktop/NBI_Caqueta.xlsx")

Ahora, se mostraran los primeros datos de nbi:

head(nbi)

La siguiente funcion permitira saber cual es el municipio con mayor porcentaje de NBI, para el caso del departamento de Caqueta es el municipio de Milan, donde aproximadamente el 47% de la poblacion tiene Necesidades Basicas Instatisfechas, y el 25% vive en miseria. Este resultado recibira el nombre de max_nbi.

nbi %>% 
    slice(which.max(NBI)) -> max_nbi
max_nbi

Contrastando la informacion anterior, se puede ejecutar la siguiente funcion para conocer cual es el municipio con menor porcentaje de NBI, siendo el municpio de Florencia, donde 14.5% de su poblacion presenta Necesidades Basicas Instafisfechas.

nbi %>% 
    slice(which.min(NBI)) -> min_nbi
min_nbi

Para poder observar mejor la informacion, se organizaran los datos de NBI que presentan los municipios de Caqueta en orden descendente, cuyo nombre es desc_nbi, a traves de la siguiente instruccion:

nbi %>% 
  arrange(desc(NBI))  -> desc_nbi
desc_nbi

Unir los datos de NBI a los municipios de Caqueta

Para este punto es necesario importar los datos del archivo en el que se encuentran los datos administrativos del departamento de Caqueta con el fin de tener los 16 municipios de este departamento, estos seran leidos con la libreria sf.

munic <- st_read("C:/Users/Juan/Desktop/ADMINISTRATIVO1/MGN_MPIO_POLITICO.shp")
Reading layer `MGN_MPIO_POLITICO' from data source `C:\Users\Juan\Desktop\ADMINISTRATIVO1\MGN_MPIO_POLITICO.shp' using driver `ESRI Shapefile'
Simple feature collection with 16 features and 9 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -76.30622 ymin: -0.70584 xmax: -71.25385 ymax: 2.964148
geographic CRS: WGS 84

Con esta instruccion se puede apreciar el nombre de cada uno de los municipios que conforman el departamento.

head(munic$MPIO_CNMBR)
[1] "FLORENCIA"              "ALBANIA"               
[3] "BELÉN DE LOS ANDAQUÍES" "EL DONCELLO"           
[5] "EL PAUJIL"              "LA MONTAÑITA"          

Ahora con los codigos de cada uno de los municipios.

head(munic$MPIO_CCDGO)
[1] "18001" "18029" "18094" "18247" "18256" "18410"

Para poder fusionar los datos de NBI y los municipios de Caqueta, se puede usar la funcion left_join, donde ambos tipos de datos coincidiran. El codigo de los municipios del departamento se encuentra en los dos archivos importados y recibe el nombre de MPIO_CCDGO y CODIGO.

nbi_munic = left_join(munic, nbi, by=c("MPIO_CCDGO"="CODIGO"))

En este paso se podra confirmar si el join quedo bien al verificar los porcentajes de NBI de los municipios de esta tabla con los datos de el porcentaje de NBI de las anteriores tablas. Por ejemplo la tabla en la aprecio el municipio con menor porcentaje de NBI, siendo el municipio de Florencia cuyo NBI fue de 14.5% aproximadamente.

nbi_munic %>%
  dplyr::select(MUNICIPIO, MPIO_CCDGO, NBI)  ->  check_nbi_munic
head(check_nbi_munic)
Simple feature collection with 6 features and 3 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -76.1027 ymin: 0.9764735 xmax: -74.89527 ymax: 2.326755
geographic CRS: WGS 84
               MUNICIPIO MPIO_CCDGO      NBI
1              FLORENCIA      18001 14.44902
2                ALBANIA      18029 19.80289
3 BELÉN DE LOS ANDAQUIES      18094 28.28503
4            EL DONCELLO      18247 20.37901
5              EL PAUJIL      18256 23.33489
6           LA MONTAÑITA      18410 32.51475
                        geometry
1 POLYGON ((-75.42074 2.19413...
2 POLYGON ((-75.89506 1.36569...
3 POLYGON ((-75.78705 1.74982...
4 POLYGON ((-75.36167 2.32142...
5 POLYGON ((-75.36691 2.21234...
6 POLYGON ((-75.40404 1.76944...

Inicialmente las coordenadas eran geograficas, pero como cartography trabaja en coordenadas planas, estas deben ser transformadas con la funcion st_transform(). Cuando se quiere obtener datos a nivel Colombia, se debe usar el sistema de referencia de coordenadas EPSG3116 y se puede averiguar en la pagina: epsg.io.

nbi_munic_new <- st_transform(nbi_munic, crs = 3116)

Ejemplos de mapas tematicos del departamento de Caqueta

La libreria de Cartography es de alta calidad, permite proyectar mapas de isopletas, coropletas, tipologia, flujos, entre otros; con simbolos proporcionales. Ademas brindan elementos que mejoran el entendimiento de los mapas tales como paletas de mapas, flecha del Norte, escalas, titulos, entre otros (GitHub, s.f). Los datos deben ser leidos con la libreria sf. Para este punto se instalara el paquete osmdata y se cargara su libreria. Este paquete permite descargar y usar datos de OpenStreetMap, asegurando que los datos provienen de una fuente confiable (Paggham y Lovelance, 2020).

install.packages("osmdata")
library(osmdata)
Data (c) OpenStreetMap contributors, ODbL 1.0. https://www.openstreetmap.org/copyright

Tambien se instalara el paquete rgdal.

install.packages("rgdal")
library(rgdal)

Mapas de simbolos proporcionales en base a OpenStreetMap

Este tipo de mapas representan datos asociados con ubicaciones, donde el tamano de los simbolos es putil para mostrar las diferencias en las ocurrencias. Se pueden encontrar figuras circulares, en barras o cuadrados. OpenStreetMap brinda datos gratuitos a sus usuarios, por ejemplo informacion de vias del mundo. Se pueden descargar los datos con la funcion getTiles() y visualizarlos con tilesLyer() (Briney, 2019).

Para poder apreciar los datos de NBI con diferentes figuras geometricas en funcion de una variable, se usara la funcion propSymbolLayer, ofreciendo distintos tipos de simbolos (cuadrados, circulos y barras) y tamanos. Con el argumento inches es posible modificar el tamano de los simbolos.

mun.osm <- getTiles(
x = nbi_munic_new, 
type = "OpenStreetMap", 
zoom = 8,
cachedir = TRUE,
crop = FALSE
)

En el mapa se puede ver una distancia de 100km, no es interactivo, tiene el objetivo de divulgar informacion. Se pueden apreciar 16 circulos marrones de diferente tamano, uno para cada municipio, donde a mayor tamano de los ciruclos, mayor sera el porcentaje de NBI en ese municipio.

#Establece margenes
opar <- par(mar = c(0,0,1.2,0))
tilesLayer(x = mun.osm)
#Trazar fronteras de los municipios
plot(st_geometry(nbi_munic_new), col = NA, border = "grey", add=TRUE)
#Trazar NBI
propSymbolsLayer(
  x = nbi_munic_new, 
  var = "NBI", 
  inches = 0.15, 
  col = "brown4",
  legend.pos = "topright",  
  legend.title.txt = "Total NBI"
)
#Diseno
layoutLayer(title = "Distribucion de NBI en Caqueta",
            sources = "Fuentes: DANE, 2018\n© OpenStreetMap",
            author = "Sandra Katteryne Rodriguez Hurtado",
            frame = TRUE, north = FALSE, tabtitle = TRUE)
#Flecha Norte
north(pos = "topleft")

En este mapa se puede apreciar mejor el departamento debido a que los bordes son de color negro, mas faciles de visualizar. Los circulos de color naranja representan el porcentaje de NBI que tiene Caqueta por departamento, a mayor tamano del circulo, mayor sera el valor de NBI.

opar <- par(mar = c(1,0,2.2,1))
tilesLayer(x = mun.osm)
plot(st_geometry(nbi_munic_new), col = NA, border = "black", add=TRUE)
propSymbolsLayer(
  x = nbi_munic_new, 
  var = "NBI", 
  inches = 0.16, 
  col = "orange1",
  legend.pos = "topright",  
  legend.title.txt = "Total NBI"
)
layoutLayer(title = "Distribucion de NBI en Caqueta",
            sources = "Fuentes: DANE, 2018\n© OpenStreetMap",
            author = "Sandra Katteryne Rodriguez Hurtado",
            frame = TRUE, north = FALSE, tabtitle = TRUE)
north(pos = "topleft")

Mapa de coropletas

Son mapas en los que se ven reflejados colores que representan valores o un rango de valores de una variable cuantitativa especifica, estos varian segun ese valor. Pueden reflejar la densidad, porcentaje, promedio o evento dentro de un espacio determinado. Se pueden encontrar argumentos para personalizar los mapas como el color, tamano, indices, simbolos, entre otros (Briney, 2019).
En el siguiente mapa se observara el porcentaje de NBI en los municipios de Caqueta, donde cada color representa un vlor difderente, entre mas oscuro sea el color, el porcentaje de NBI es mayor. Este mapa tiene una distancia de 80km y se manejo una paleta de color arena.

opar <- par(mar = c(0,0,1.2,0))
#Color de fondo de la figura
par(bg="grey90")
#Trazar municipios
plot(st_geometry(nbi_munic_new), col = NA, border = NA, bg = "#aadaff")
choroLayer(
  x = nbi_munic_new, 
  var = "NBI",
  method = "geom",
  nclass=5,
  col = carto.pal(pal1 = "sand.pal", n1 = 5),
  border = "white", 
  lwd = 0.5,
  legend.pos = "topright", 
  legend.title.txt = "NBI",
  add = TRUE
) 
layoutLayer(title = "Distribucion de NBI en Caqueta", 
            sources = "Fuente: DANE, 2018",
            author = "Sandra Katteryne Rodriguez Hurtado", 
            frame = TRUE, north = TRUE, tabtitle = TRUE, col="black") 
north(pos = "topleft")

En el siguiente mapa se manejo una paleta de color rosado, tiene el mismo comportamiento que el mapa de arriba.

opar <- par(mar = c(0,0,1.2,0))
par(bg="black")
plot(st_geometry(nbi_munic_new), col = NA, border = NA, bg = "#aadaff")
choroLayer(
  x = nbi_munic_new, 
  var = "NBI",
  method = "geom",
  nclass=5,
  col = carto.pal(pal1 = "pink.pal", n1 = 5),
  border = "black", 
  lwd = 1.5,
  legend.pos = "topleft", 
  legend.title.txt = "NBI",
  add = TRUE
) 
layoutLayer(title = "Distribucion de NBI en Caqueta", 
            sources = "Fuente: DANE, 2018",
            author = "Sandra Katteryne Rodriguez Hurtado", 
            frame = TRUE, north = TRUE, tabtitle = TRUE, col="black") 
north(pos = "topright")

Mapa de tipologia y simbolos proporcionales

Este mapa tiene simbolos donde, se manejan dos variables: una cuantitativa, que es el porcentaje de NBI, y una cualitativa que es una clasificacion. La funcion mutate viene del paquete dplyr y permite crear nuevos atributos. En este caso, se clasificara la pobreza teniendo en cuenta la miseria y el hacinamiento, donde la primera es extrema cuando su valor es superior a 20, y la segunda alta su su vaor es mayor a 5, e intermedio si no esta detro de estos valores.

nbi_munic_2 <- dplyr::mutate(nbi_munic_new, Pobreza = ifelse(MISERIA > 20, "Extrema", 
                                                         ifelse(HACINAMIENTO > 5, "Alta", "Intermedia")))

El nuevo atributo se llama pobreza.

head(nbi_munic_2)
Simple feature collection with 6 features and 21 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: 774588.2 ymin: 599751.7 xmax: 908977.8 ymax: 749113.8
projected CRS:  MAGNA-SIRGAS / Colombia Bogota zone
  DPTO_CCDGO MPIO_CCDGO             MPIO_CNMBR
1         18      18001              FLORENCIA
2         18      18029                ALBANIA
3         18      18094 BELÉN DE LOS ANDAQUÍES
4         18      18247            EL DONCELLO
5         18      18256              EL PAUJIL
6         18      18410           LA MONTAÑITA
                             MPIO_CRSLC MPIO_NAREA MPIO_NANO
1       Decreto 642 de Junio 17 de 1912   2547.638      2017
2   Ordenanza 3 de Noviembre 12 de 1985    414.122      2017
3       Decreto 963 de Marzo 14 de 1950   1191.619      2017
4  Decreto 1678 de Septiembre 7 de 1967   1105.803      2017
5 Decreto 1678 de Septiembret 7 de 1967   1234.743      2017
6         Decreto 83 de Julio 6 de 1955   1701.052      2017
  DPTO_CNMBR Shape_Leng Shape_Area COD_DEPTO   DEPTO COD_MUN
1    CAQUETÁ   2.942508 0.20692777        18 CAQUETÁ     001
2    CAQUETÁ   1.112829 0.03361758        18 CAQUETÁ     029
3    CAQUETÁ   2.234657 0.09674460        18 CAQUETÁ     094
4    CAQUETÁ   3.154370 0.08986744        18 CAQUETÁ     247
5    CAQUETÁ   3.529316 0.10030928        18 CAQUETÁ     256
6    CAQUETÁ   3.402939 0.13817351        18 CAQUETÁ     410
               MUNICIPIO      NBI  MISERIA  VIVIENDA SERVICIOS
1              FLORENCIA 14.44902 2.774899  5.224497  1.488778
2                ALBANIA 19.80289 4.400642  9.832684  3.208801
3 BELÉN DE LOS ANDAQUIES 28.28503 7.091305 12.143430  3.906519
4            EL DONCELLO 20.37901 3.898247 10.300478  1.473936
5              EL PAUJIL 23.33489 5.170800 13.718609  2.823273
6           LA MONTAÑITA 32.51475 8.972579 17.086081  7.150295
  HACINAMIENTO INASISTENCIA  ECONOMIA                       geometry
1     4.434199     2.077731  4.529297 POLYGON ((850567.7 734450.4...
2     4.606922     1.260601  6.119642 POLYGON ((797693.6 642855.1...
3     5.602016     4.926108 10.654141 POLYGON ((809754.1 685340, ...
4     3.704758     2.025950  7.608696 POLYGON ((857152.4 748524, ...
5     5.186398     2.737482  5.357978 POLYGON ((856558 736458.9, ...
6     5.128428     2.724748 11.315515 POLYGON ((852387.3 687475.8...
     Pobreza
1 Intermedia
2 Intermedia
3       Alta
4 Intermedia
5       Alta
6       Alta
library(sf)
library(cartography)

Se puede ver que en el mapa hay unos circulos de colores, donde cada color depresenta si el nivel de pobreza es alto, intermedio o bajo; donde cada simbolo y su tamano dependen de los valores de NBI, y de ahi se determina la pobreza del municipio. Para este mapa se utilizaron simbolos cuadrados con paleta multicolor.

opar <- par(mar = c(0,0,1.2,0))
plot(st_geometry(nbi_munic_2), col="#f2efe9", border="#b38e43", bg = "#aad3df", 
     lwd = 0.5)
propSymbolsTypoLayer(
  x = nbi_munic_2, 
  var = "NBI", 
  inches = 0.3,
  symbols = "square",
  border = "white",
  lwd = .5,
  legend.var.pos = c("topright"), 
  legend.var.title.txt = "NBI",
  var2 = "Pobreza",
  legend.var2.values.order = c("Extrema", "Alta", 
                               "Intermedia"),
  col = carto.pal(pal1 = "multi.pal", n1 = 3),
  legend.var2.pos = c("bottomright"), 
  legend.var2.title.txt = "Pobreza"
) 
layoutLayer(title="Distribucion de NBI en Caqueta", 
            author = "Sandra Katteryne Rodriguez Hurtado", 
            sources = "Fuente: DANE, 2018", 
            scale = 1, tabtitle = TRUE, frame = TRUE)
north(pos = "topleft")

En este mapa se pueden apreciar los mismos valores que en el mapa anterior, pero esta vez representados en barras con una paleta de color vinotinto, donde cada color representara el porcentaje de miseria en el que viven los habitantes de cada municipio, y este representa el nivel de pobreza.

opar <- par(mar = c(0,0,1.2,0))
plot(st_geometry(nbi_munic_2), col="#f2efe9", border="#b38e43", bg = "#aad3df", 
     lwd = 0.5)
propSymbolsTypoLayer(
  x = nbi_munic_2, 
  var = "NBI", 
  inches = 0.5,
  symbols = "bar",
  border = "black",
  lwd = .5,
  legend.var.pos = c( "topleft"), 
  legend.var.title.txt = "NBI",
  var2 = "Pobreza",
  legend.var2.values.order = c("Extrema", "Alta", 
                               "Intermedia"),
  col = carto.pal(pal1 = "wine.pal", n1 = 3),
  legend.var2.pos = c("topright"), 
  legend.var2.title.txt = "Pobreza"
) 
layoutLayer(title="Distribucion de NBI en Caqueta", 
            author = "Sandra Katteryne Rodriguez Hurtado", 
            sources = "Fuente: DANE, 2018", 
            scale = 1, tabtitle = TRUE, frame = TRUE)
north(pos = "topleft")

Mapas de etiquetas

El siguidente mapa representa los municipios coloreados con una paleta naranja. Cada municipio lleva la etiqueta de su nombre correspondiente. Cuando el color se torna mas oscuro, sera mayor el porcentade de NBI que presenta esa poblacion.

library(sf)
library(cartography)

Este mapa presenta paleta de color arena, representando el porcentaje de NBI.

opar <- par(mar = c(0,0,1.2,0))
par(bg="grey25")
plot(st_geometry(nbi_munic_2), col = "#e4e9de", border = "darkseagreen4", 
     bg = "grey75", lwd = 0.5)
choroLayer(
  x = nbi_munic_new, 
  var = "NBI",
  method = "geom",
  nclass=5,
  col = carto.pal(pal1 = "sand.pal", n1 = 5),
  border = "white", 
  lwd = 0.5,
  legend.pos = "topright", 
  legend.title.txt = "NBI",
  add = TRUE
) 
labelLayer(
  x = nbi_munic_2, 
  txt = "MUNICIPIO", 
  col= "white", 
  cex = 0.4, 
  font = 4,
  halo = TRUE, 
  bg = "grey25", 
  r = 0.1, 
  overlap = FALSE, 
  show.lines = FALSE
)
layoutLayer(
  title = "Municipios del departamento de Caqueta", 
  sources = "Fuente: DANE, 2018",  
  author = "Sandra Katteryne Rodriguez Hurtado", 
  frame = TRUE,
  north = TRUE, 
  tabtitle = TRUE, 
  theme = "taupe.pal"
) 

Este mapa presenta la paleta color naranja.

opar <- par(mar = c(0,0,1.2,0))
par(bg="white")
plot(st_geometry(nbi_munic_2), col = "#e4e9de", border = "darkseagreen4", 
     bg = "grey85", lwd = 0.5)
choroLayer(
  x = nbi_munic_new, 
  var = "NBI",
  method = "geom",
  nclass=5,
  col = carto.pal(pal1 = "orange.pal", n1 = 5),
  border = "Black", 
  lwd = 0.2,
  legend.pos = "topleft", 
  legend.title.txt = "NBI",
  add = TRUE
) 
labelLayer(
  x = nbi_munic_2, 
  txt = "MUNICIPIO", 
  col= "white", 
  cex = 0.4, 
  font = 4,
  halo = TRUE, 
  bg = "black", 
  r = 0.1, 
  overlap = FALSE, 
  show.lines = FALSE
)
layoutLayer(
  title = "Municipios del departamento de Caqueta", 
  sources = "Fuente: DANE, 2018",  
  author = "Sandra Katteryne Rodriguez Hurtado", 
  frame = TRUE,
  north = TRUE, 
  tabtitle = TRUE, 
  theme = "taupe.pal"
) 

Mapas de isopletas o isolineas

Estos mapas representan un fenomeno que se distribuye de forma continua en el espacio. Tienen un enfoque de modelado de interaccion espacial. Permiten mapas con una representacion espacial del fenomeno o variable, independientemente a la heterogeneidad de la division territorial.Estos datos se recopilan en puntos medibles, como estaciones meteorologicas; o por area (Briney, 2019).

Para los siguientes puntos se hara la representacion grafica de la distribucion espacial en el departamento de Caqueta del cultivo de platano y de yuca. ##### Cultivo de platano Para este punto se deben importar los datos de los cultivos del departamento de Caqueta, donde se dejara solo el del ano de interes, en este caso 2018. El archivo en formato .xlsx.

cultivos2018 <- read_excel("C:/Users/Juan/Desktop/PEVA_Caqueta2.xlsx")
head(cultivos2018)

Se deben filtrar las filas que representan al cultivo que se quiere representar, en este caso sera el platano.

cultivos2018 %>%
  filter(CULTIVO == "PLATANO") -> platano2018

En este punto se cambiara el tipo de dato que tiene COD_MUN, que es el codigo del municipio, donde inicialmente era de tipo numerico, pero con la funcion que se ejecutara a continuacion pasara a ser de tipo caracter. Esto con el objetivo de poder realizar correctamdente el join o la union de datos.

platano2018$TEMP <-  as.character(platano2018$COD_MUN)

En este caso no es necesario anadirle el cero al codigo de los municipios.

platano2018$MPIO_CCDGO <- as.factor(paste(platano2018$TEMP, sep=""))

Se hace uso de la funcion left_join() para poder realizar el join o union de los datos.

platano_munic = left_join(munic, platano2018, by="MPIO_CCDGO")
Column `MPIO_CCDGO` joining character vector and factor, coercing into character vector

Esta funcion para ver los datos que alli se encuentran.

head(platano_munic)
Simple feature collection with 6 features and 24 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -76.1027 ymin: 0.9764735 xmax: -74.89527 ymax: 2.326755
geographic CRS: WGS 84
  DPTO_CCDGO MPIO_CCDGO             MPIO_CNMBR
1         18      18001              FLORENCIA
2         18      18029                ALBANIA
3         18      18094 BELÉN DE LOS ANDAQUÍES
4         18      18247            EL DONCELLO
5         18      18256              EL PAUJIL
6         18      18410           LA MONTAÑITA
                             MPIO_CRSLC MPIO_NAREA MPIO_NANO
1       Decreto 642 de Junio 17 de 1912   2547.638      2017
2   Ordenanza 3 de Noviembre 12 de 1985    414.122      2017
3       Decreto 963 de Marzo 14 de 1950   1191.619      2017
4  Decreto 1678 de Septiembre 7 de 1967   1105.803      2017
5 Decreto 1678 de Septiembret 7 de 1967   1234.743      2017
6         Decreto 83 de Julio 6 de 1955   1701.052      2017
  DPTO_CNMBR Shape_Leng Shape_Area COD_DEP DEPARTAMENTO COD_MUN
1    CAQUETÁ   2.942508 0.20692777      18      CAQUETA   18001
2    CAQUETÁ   1.112829 0.03361758      18      CAQUETA   18029
3    CAQUETÁ   2.234657 0.09674460      18      CAQUETA   18094
4    CAQUETÁ   3.154370 0.08986744      18      CAQUETA   18247
5    CAQUETÁ   3.529316 0.10030928      18      CAQUETA   18256
6    CAQUETÁ   3.402939 0.13817351      18      CAQUETA   18410
               MUNICIPIO                 GRUPO SUBGRUPO CULTIVO YEAR
1              FLORENCIA TUBERCULOS Y PLATANOS  PLATANO PLATANO 2018
2                ALBANIA TUBERCULOS Y PLATANOS  PLATANO PLATANO 2018
3 BELEN DE LOS ANDAQUIES TUBERCULOS Y PLATANOS  PLATANO PLATANO 2018
4            EL DONCELLO TUBERCULOS Y PLATANOS  PLATANO PLATANO 2018
5              EL PAUJIL TUBERCULOS Y PLATANOS  PLATANO PLATANO 2018
6              MONTAÑITA TUBERCULOS Y PLATANOS  PLATANO PLATANO 2018
  Area_Siembra Area_cosechada Produccion Rendimiento       ESTADO
1          780            725       3263         4.5 FRUTO FRESCO
2          818            767       5369         7.0 FRUTO FRESCO
3         2200           2070      14490         7.0 FRUTO FRESCO
4          385            325       1950         6.0 FRUTO FRESCO
5          187            170       1190         7.0 FRUTO FRESCO
6          250            250       1500         6.0 FRUTO FRESCO
       CICLO  TEMP                       geometry
1 PERMANENTE 18001 POLYGON ((-75.42074 2.19413...
2 PERMANENTE 18029 POLYGON ((-75.89506 1.36569...
3 PERMANENTE 18094 POLYGON ((-75.78705 1.74982...
4 PERMANENTE 18247 POLYGON ((-75.36167 2.32142...
5 PERMANENTE 18256 POLYGON ((-75.36691 2.21234...
6 PERMANENTE 18410 POLYGON ((-75.40404 1.76944...

Se reproyectaran los municipios:

rep_platano <- st_transform(platano_munic, crs = 3116)

Es necesario instalar el paquete lwgeom.

library(lwgeom)
Linking to liblwgeom 3.0.0beta1 r16016, GEOS 3.6.1, PROJ 4.9.3
GEOS versions differ: lwgeom has 3.6.1 sf has 3.8.0PROJ versions differ: lwgeom has 4.9.3 sf has 6.3.1

Mapeo

opar <- par(mar = c(0,0,1.2,0))
plot(st_geometry(rep_platano), col = NA, border = "black", bg = "white")
smoothLayer(
  x = rep_platano, 
  var = 'Produccion',
  typefct = "exponential",
  span = 25000,
  beta = 1,
  nclass = 6,
  col = carto.pal(pal1 = 'turquoise.pal', n1 = 6),
  border = "grey",
  lwd = 0.1, 
  mask = rep_platano, 
  legend.values.rnd = -3,
  legend.title.txt = "Produccion",
  legend.pos = "topright", 
  add=TRUE
)
text(x = 2, y = 32000, cex = 0.6, adj = 0, font = 3,  labels = 
       "Distance function:\n- type = exponential\n- beta = 2\n- span = 20 km")
layoutLayer(title = "Distribucion de la produccion de platano en Caqueta",
            sources = "Fuentes: DANE y MADR, 2018",
            author = "Sandra Katteryne Rodriguez Hurtado",
            frame = FALSE, north = FALSE, tabtitle = TRUE, theme = "black.pal")
north(pos = "topleft")

Este mapa tiene una paleta de color turquesa.Se puede apreciar la produccion de platano en el departamento de Caqueta en toneladas, donde los municipios donde se concentra la mayor produccion se ven de color turquesa oscuro, a diferencia de los municipios de menor produccion, con color turquesa claro. #### Guardar los mapas A continuacion se generara un mapa de cloropletas con simbolos proporcionales y etiquetas, que representara la produccion de Yuca en 2018. Este sera guardado en el directorio deseado con formato .png.

png("C:/Users/Juan/Desktop/platano_2018.png", width = 1024, height = 763)

opar <- par(mar = c(2,2,5,5))

plot(st_geometry(rep_platano), col="darkseagreen", border="darkseagreen4",  
     bg = "white", lwd = 0.6)

propSymbolsChoroLayer(x = rep_platano, var = "Produccion", var2 = "Rendimiento",
                      col = carto.pal(pal1 = "turquoise.pal", n1 = 3,
                                      pal2 = "pink.pal", n2 = 3),
                      inches = 0.5, method = "q6",
                      border = "black", lwd = 1,
                      legend.title.cex = 1.3,
                      legend.values.cex = 1.3,
                      legend.var.pos = "topright", 
                      legend.var2.pos = "topleft",
                      legend.var2.values.rnd = 2,
                      legend.var2.title.txt = "Rendimiento\n(in Ton/Ha)",
                      legend.var.title.txt = "Produccion de Platano, 2018",
                      legend.var.style = "e")

labelLayer(
  x = rep_platano, 
  txt = "MPIO_CNMBR", 
  col= "black", 
  cex = 1, 
  font = 18,
  halo = FALSE, 
  bg = "white", 
  r = 0.1, 
  overlap = FALSE, 
  show.lines = FALSE
)

layoutLayer(title="Produccion y rendimiento de Platano en Caqueta, 2018",
            author = "Sandra Katteryne Rodriguez Hurtado", 
            sources = "Fuentes: MADR & DANE, 2018", 
            scale = 50, tabtitle = FALSE, frame = TRUE)

north(pos = "top")

title(main="Produccion y rendimiento de Platano en Caqueta, 2018", cex.main=3,
      sub= "Fuentes: MADR & DANE, 2018", cex.sub=2)

graticule = TRUE

par(opar)

dev.off()

La siguiente imagen fue el resultado del proceso anterior, que representa la produccion de platano en el dpartamento de Caqueta en 2018: Produccion y rendimiento de platano en Caqueta, 2018

Se puede apreciar que los municipios de mayor produccion de platano son Milan, San Vicente del Caguan y Cartagena de Chaira. #### Cultivo de yuca Se representara graficamente la produccion del cultivo de yuca en los municipios de departamento de Caqueta para el ano 2018, esto con los pasos realizados anteriormente para la representacion del cultivo del platano. Primero escoger el cultivo que se representara.

cultivos2018 %>%
  filter(CULTIVO == "YUCA") -> yuca2018
yuca2018$TEMP <-  as.character(yuca2018$COD_MUN)
yuca2018$MPIO_CCDGO <- as.factor(paste(yuca2018$TEMP, sep=""))

Hacer el join.

yuca_munic = left_join(munic, yuca2018, by="MPIO_CCDGO")
Column `MPIO_CCDGO` joining character vector and factor, coercing into character vector
head(yuca_munic)
Simple feature collection with 6 features and 24 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -76.1027 ymin: 0.9764735 xmax: -74.89527 ymax: 2.326755
geographic CRS: WGS 84
  DPTO_CCDGO MPIO_CCDGO             MPIO_CNMBR
1         18      18001              FLORENCIA
2         18      18029                ALBANIA
3         18      18094 BELÉN DE LOS ANDAQUÍES
4         18      18247            EL DONCELLO
5         18      18256              EL PAUJIL
6         18      18410           LA MONTAÑITA
                             MPIO_CRSLC MPIO_NAREA MPIO_NANO
1       Decreto 642 de Junio 17 de 1912   2547.638      2017
2   Ordenanza 3 de Noviembre 12 de 1985    414.122      2017
3       Decreto 963 de Marzo 14 de 1950   1191.619      2017
4  Decreto 1678 de Septiembre 7 de 1967   1105.803      2017
5 Decreto 1678 de Septiembret 7 de 1967   1234.743      2017
6         Decreto 83 de Julio 6 de 1955   1701.052      2017
  DPTO_CNMBR Shape_Leng Shape_Area COD_DEP DEPARTAMENTO COD_MUN
1    CAQUETÁ   2.942508 0.20692777      18      CAQUETA   18001
2    CAQUETÁ   1.112829 0.03361758      18      CAQUETA   18029
3    CAQUETÁ   2.234657 0.09674460      18      CAQUETA   18094
4    CAQUETÁ   3.154370 0.08986744      18      CAQUETA   18247
5    CAQUETÁ   3.529316 0.10030928      18      CAQUETA   18256
6    CAQUETÁ   3.402939 0.13817351      18      CAQUETA   18410
               MUNICIPIO                 GRUPO SUBGRUPO CULTIVO YEAR
1              FLORENCIA TUBERCULOS Y PLATANOS     YUCA    YUCA 2018
2                ALBANIA TUBERCULOS Y PLATANOS     YUCA    YUCA 2018
3 BELEN DE LOS ANDAQUIES TUBERCULOS Y PLATANOS     YUCA    YUCA 2018
4            EL DONCELLO TUBERCULOS Y PLATANOS     YUCA    YUCA 2018
5              EL PAUJIL TUBERCULOS Y PLATANOS     YUCA    YUCA 2018
6              MONTAÑITA TUBERCULOS Y PLATANOS     YUCA    YUCA 2018
  Area_Siembra Area_cosechada Produccion Rendimiento
1          350            350       1400         4.0
2          160            160       1040         6.5
3          260            260       1820         7.0
4          150            150        900         6.0
5          300            300       1800         6.0
6          400            400       2000         5.0
            ESTADO CICLO  TEMP                       geometry
1 TUBERCULO FRESCO ANUAL 18001 POLYGON ((-75.42074 2.19413...
2 TUBERCULO FRESCO ANUAL 18029 POLYGON ((-75.89506 1.36569...
3 TUBERCULO FRESCO ANUAL 18094 POLYGON ((-75.78705 1.74982...
4 TUBERCULO FRESCO ANUAL 18247 POLYGON ((-75.36167 2.32142...
5 TUBERCULO FRESCO ANUAL 18256 POLYGON ((-75.36691 2.21234...
6 TUBERCULO FRESCO ANUAL 18410 POLYGON ((-75.40404 1.76944...

Coordenadas planas.

rep_yuca <- st_transform(yuca_munic, crs = 3116)
library(lwgeom)

Representacion de la produccion de yuca en Caqueta en 2018, distribuida en el espacio con color de paleta vinotinto.

opar <- par(mar = c(0,0,1.2,0))
plot(st_geometry(rep_yuca), col = NA, border = "black", bg = "white")
smoothLayer(
  x = rep_yuca, 
  var = 'Produccion',
  typefct = "exponential",
  span = 31000,
  beta = 1,
  nclass = 5,
  col = carto.pal(pal1 = 'wine.pal', n1 = 5),
  border = "grey",
  lwd = 0.1, 
  mask = rep_yuca, 
  legend.values.rnd = -3,
  legend.title.txt = "Produccion",
  legend.pos = "topright", 
  add=TRUE
)
text(x = 2, y = 32000, cex = 0.6, adj = 0, font = 3,  labels = 
       "Distance function:\n- type = exponential\n- beta = 2\n- span = 20 km")
layoutLayer(title = "Distribucion de la produccion de yuca en Caqueta",
            sources = "Fuentes: DANE y MADR, 2018",
            author = "Sandra Katteryne Rodriguez Hurtado",
            frame = FALSE, north = FALSE, tabtitle = TRUE, theme = "black.pal")
north(pos = "topleft")

Gegerar y descargar en el equipo la imagen de un mapa de cloropletas con simbolos y etiquetas, de la produccion de yuca en Caqueta para el ano 2018.

png("C:/Users/Juan/Desktop/yuca_2018.png", width = 1024, height = 763)

opar <- par(mar = c(2,2,5,5))

plot(st_geometry(rep_yuca), col="darkseagreen", border="darkseagreen4",  
     bg = "white", lwd = 0.6)

propSymbolsChoroLayer(x = rep_yuca, var = "Produccion", var2 = "Rendimiento",
                      col = carto.pal(pal1 = "orange.pal", n1 = 3,
                                      pal2 = "wine.pal", n2 = 3),
                      inches = 0.5, method = "q6",
                      border = "black", lwd = 1,
                      legend.title.cex = 1.3,
                      legend.values.cex = 1.3,
                      legend.var.pos = "topright", 
                      legend.var2.pos = "topleft",
                      legend.var2.values.rnd = 2,
                      legend.var2.title.txt = "Rendimiento\n(in Ton/Ha)",
                      legend.var.title.txt = "Produccion de yuca, 2018",
                      legend.var.style = "e")

labelLayer(
  x = rep_platano, 
  txt = "MPIO_CNMBR", 
  col= "black", 
  cex = 1, 
  font = 18,
  halo = FALSE, 
  bg = "white", 
  r = 0.1, 
  overlap = FALSE, 
  show.lines = FALSE
)

layoutLayer(title="Produccion y rendimiento de yuca en Caqueta, 2018",
            author = "Sandra Katteryne Rodriguez Hurtado", 
            sources = "Fuentes: MADR & DANE, 2018", 
            scale = 50, tabtitle = FALSE, frame = TRUE)

north(pos = "top")

title(main="Produccion y rendimiento de yuca en Caqueta, 2018", cex.main=3,
      sub= "Fuentes: MADR & DANE, 2018", cex.sub=2)

graticule = TRUE

par(opar)

dev.off()

Imagen descargada de la prodiccion y rendimiento de yuca, 2018.

{opar  ="100%"}
library(ggplot2)
library(knitr)
include_graphics("C:/Users/Juan/Desktop/yuca_2018.png")

Se puede ver que los municipios de mayor produccion de yuca en toneladas son Cartagena de Chaira y San Vicente de Caguan.

Informacion del trabajo
sessionInfo()
R version 4.0.0 (2020-04-24)
Platform: i386-w64-mingw32/i386 (32-bit)
Running under: Windows 7 (build 7601) Service Pack 1

Matrix products: default

locale:
[1] LC_COLLATE=Spanish_Colombia.1252 
[2] LC_CTYPE=Spanish_Colombia.1252   
[3] LC_MONETARY=Spanish_Colombia.1252
[4] LC_NUMERIC=C                     
[5] LC_TIME=Spanish_Colombia.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods  
[7] base     

other attached packages:
 [1] knitr_1.28            lwgeom_0.2-3         
 [3] rgdal_1.4-8           osmdata_0.1.3        
 [5] SpatialPosition_2.0.1 cartography_2.4.1    
 [7] sf_0.9-3              rgeos_0.5-3          
 [9] readxl_1.3.1          forcats_0.5.0        
[11] stringr_1.4.0         dplyr_0.8.5          
[13] purrr_0.3.4           readr_1.3.1          
[15] tidyr_1.0.3           tibble_3.0.1         
[17] ggplot2_3.3.0         tidyverse_1.3.0      
[19] raster_3.1-5          sp_1.4-1             

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.4.6       lubridate_1.7.8    lattice_0.20-41   
 [4] png_0.1-7          class_7.3-16       assertthat_0.2.1  
 [7] digest_0.6.25      R6_2.4.1           cellranger_1.1.0  
[10] backports_1.1.6    reprex_0.3.0       evaluate_0.14     
[13] e1071_1.7-3        httr_1.4.1         pillar_1.4.4      
[16] rlang_0.4.6        curl_4.3           rstudioapi_0.11   
[19] rmarkdown_2.1      munsell_0.5.0      broom_0.5.6       
[22] compiler_4.0.0     modelr_0.1.7       xfun_0.13         
[25] pkgconfig_2.0.3    base64enc_0.1-3    htmltools_0.4.0   
[28] tidyselect_1.1.0   codetools_0.2-16   fansi_0.4.1       
[31] crayon_1.3.4       dbplyr_1.4.3       withr_2.2.0       
[34] grid_4.0.0         nlme_3.1-147       jsonlite_1.6.1    
[37] gtable_0.3.0       lifecycle_0.2.0    DBI_1.1.0         
[40] magrittr_1.5       units_0.6-6        scales_1.1.1      
[43] KernSmooth_2.23-16 cli_2.0.2          stringi_1.4.6     
[46] fs_1.4.1           xml2_1.3.2         ellipsis_0.3.0    
[49] generics_0.0.2     vctrs_0.3.0        tools_4.0.0       
[52] glue_1.4.0         hms_0.5.3          slippymath_0.3.1  
[55] rsconnect_0.8.16   yaml_2.2.1         colorspace_1.4-1  
[58] classInt_0.4-3     rvest_0.3.5        isoband_0.2.1     
[61] haven_2.2.0       
REFERENCIAS

Briney, A. (11 de Julio de 2019). Uses of Thematic Maps in Geography. Recuperado el Mayo de 2020, de https://www.thoughtco.com/thematic-maps-overview-1435692

GitHub. (s.f.). Cartography. Recuperado el Mayo de 2020, de https://github.com/riatelab/cartography/

Gobernacion del Caqueta. (s.f.). Historia de Caqueta. Recuperado el Mayo de 2020, de http://www.caqueta.gov.co/departamento/historia-del-caqueta

Padgham, M., & Lovelace, R. (2 de Febrero de 2020). ODM DATA. Recuperado el Mayo de 2020, de https://cran.r-project.org/web/packages/osmdata/vignettes/osmdata.html#5_additional_functionality

LS0tDQp0aXRsZTogIkNhcnRvZ3JhZmlhIHRlbWF0aWNhIGRlbCBkZXBhcnRhbWVudG8gZGUgQ2FxdWV0YSINCmRhdGU6ICIxOC8wNS8yMDIwIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCiMjIyMgU2FuZHJhIEthdHRlcnluZSBSb2RyaWd1ZXogSHVydGFkbw0KRWwgcHJlc2VudGUgdHJhYmFqbyBubyB0aWVuZSB0aWxkZXMgbmkgbGEgcHJlc2VuY2lhIGRlIGxhIGxldHJhIG4gZGViaWRvIGEgcXVlIGxhIHZlcnNpb24gZGUgUlN0dWRpbyBjb24gbGEgcXVlIHNlIHJlYWxpem8gZWwgaW5mb3JtZSBubyBsYXMgbWFuZWphLiANCg0KRWwgZGVwYXJ0YW1lbnRvIGRlIENhcXVldGEgZnVlIGZ1bmRhZG8gZWwgMDIgZGUgTWF5byBkZSAxODQ1LCBzZSBlbmN1ZW50cmEgbG9jYWxpemFkbyBhbCBTdXIgZGUgQ29sb21iaWEsIHRpZW5lIHVuYSBleHRlbnNpb24gZGUgODguOTY1IGttMiBhcHJveGltYWRhbWVudGUsIGVzdGEgZGl2aWRpZG8gZW4gMTYgbXVuaWNpcGlvcywgZG9uZGUgc2UgZW5jdWVudHJhbiBtdWNob3MgY2FzZXJpb3MgeSBzaXRpb3MgcG9ibGFkb3MuIEVzdGUgZGVwYXJ0YW1lbnRvIGp1ZWdhIHVuIHBhcGVsIGltcG9ydGFudGUgZW4gbGEgYmlvZGl2ZXJzaWRhZCBkZWJpZG8gYSBxdWUgIHVuIHBvcmNlbnRhamUgaW1wb3J0YW50ZSBkZSBzdSB0ZXJyaXRvcmlvIHBlcnRlbmVjZSBhbCBzaXN0ZW1hIEFtYXpvbmljbywgcGllIGRlIG1vbnRlIEFtYXpvbmljbywgc2UgZW5jdWVudHJhbiBoYWNlbnRhbWllbnRvcyBodW1hbm9zLCB5IHBvciBlbmRlIGxhIGRpbmFtaWNhIHNvY2lvcG9saXRpY2EgeSBlY29ub21pY2EgKEdvYmVybmFjaW9uIGRlIENhcXVldGEsIHMuZikuICANCkVuIGVsIHByZXNlbnRlIGN1YWRlcm5vIHNlIGhhYmxhcmEgc29icmUgZWwgdGVtYSBkZSBjYXJ0b2dyYWZpYSB0ZW1hdGljYSBkZWwgZGVwYXJ0YW1lbnRvIGRlIENhcXVldGEsIGRvbmRlIHNlIHJlYWxpemFyYW4gdmFyaW9zIG1hcGFzIGVuIGVsIHByb2dyYW1hIFJTdHVkaW8sIGVuZm9jYWRvcyBhIGRvcyB0ZW1hczogTGFzIE5lY2Vpc2RhZGVzIEJhc2ljYXMgSW5zYXRpc2ZlY2hhcyAoTkJJKSBxdWUgcHJlc2VudGFuIGxvcyBoYWJpdGFudGVzIGRlIGNhZGEgbXVuaWNpcGlvIHkgcHJvZHVjY2lvbiBlbiBlbCBhbm8gMjAxOCBkZSBhbGd1bm9zIGN1bHRpdm9zIGVuIENhcXVldGEuIA0KDQojIyMgTWFwYSB0ZW1hdGljbw0KQWNvcmRlIGNvbiBCcmluZXkgKDIwMTkpLCB1biBtYXBhIHRlbWF0aWNvIHNlIGJhc2EgZW4gdW4gdGVtYSBlbiBlc3BlY2lmaWNvLCBlcyB1bmEgcmVwcmVzZW50YWNpb24gZGUgdW5hIHNpdHVhY2lvbiBxdWUgZXN0YSBvY3VycmllbmRvIGVuIHVuIGx1Z2FyIGRldGVybWluYWRvIHkgY3V5YSBpbmZvcm1hY2lvbiBxdWllcmUgc2VyIGRpdnVsZ2FkYS4gU29uIGRpZmVyZW50ZXMgYSBsb3MgbWFwYXMgZGUgcmVmZXJlbmNpYSwgcHVlcyBlc3RvcyB0aWVuZW4gY29tbyBmaW4gbW9zdHJhciBjYXJhY3RlcmlzdGljYXMgbmF0dXJhbGVzIHkgYXJ0aWZpY2lhbGVzLCBzaW4gZW1iYXJnbyBlbGVtZW50b3MgZGUgbG9zIG1hcGFzIGRlIHJlZmVyZW5jaWEgcHVlZGVuIGFwYXJlY2VyIGVuIGxvcyBtYXBhcyB0ZW1hdGljb3MgY29tbyBwdW50b3MgZGUgcmVmZXJlbmNpYS4gDQpCcmluZXkgdGFtYmllbiBtZW5jaW9uYSBxdWUgZXMgZGUgdml0YWwgaW1wb3J0YW5jaWEgc2FiZXIgYSBxdWUgdGlwbyBkZSBwdWJsaWNvIHZhIGRpcmlnaWRvIGVsIG1hcGEsIGRlYmlkbyBhIHF1ZSBzZSBkZWJlbiBhZ3JlZ2FyIGVsZW1lbnRvcyBhZGljaW9uYWxlcyBxdWUgZmFjaWxpdGVuIHN1IGVudGVuZGltaWVudG8sIHkgZXN0b3MgZGlmaWVyZW4geSBzZSBhY29tb2RhbiBhIGNhZGEgdW5vIGRlIGxvcyBncnVwb3MuIEFjb3JkZSBjb24gbG8gYW50ZXJpb3IsIGVzIGltcG9ydGFudGUgYWN1ZGlyIGEgZnVlbnRlcyBjb25maWFibGVzIGFsIHJlY29sZWN0YXIgaW5mb3JtYWNpb24geWEgcXVlIGRhcmEgY29tbyByZXN1bHRhZG8gdW4gbWFwYSBjb25maWFibGUgeSBwcmVjaXNvLg0KDQpBY29udGludWFjaW9uIHNlIGhhYmxhcmEgc29icmUgYWxndW5vcyB0aXBvcyBkZSBtYXBhcyB0ZW1hdGljb3MsIHBhcmEgcXVlIHNpcnZlbiwgcXVlIHJlcHJlc2VudGFuIHkgY29tbyBzZSBoaWNpZXJvbiBlbiBSU3R1ZGlvLg0KIyMjIERhdG9zIA0KTGFzIGZ1ZW50ZXMgZGUgbG9zIGRhdG9zIHBhcmEgbGEgcmVhbGl6YWNpb24gZGUgbG9zIG1hcGFzIHNlIGJhc2FyYW4gZW4gZWwgR2VvcG9ydGFsIGRlbCBEQU5FIGRlbCBhcmNoaXZvIE5lY2Vpc2RhZGVzIEJhc2ljYXMgSW5zYXRpc2ZlY2hhcyAoTkJJKSBkZWwgYW5vIDIwMTguIEVuIGVsIHBvcnRhbCBkZWwgREFORSBzZSBwdWVkZSBvYnRlbmVyIGluZm9ybWFjaW9uIHV0aWwgYWwgcmVhbGl6YXIgbWFwYXMgdGVtYXRpY29zIGRlIGxhIGRlbW9ncmFmaWNhIGNvbiB2YXJpYWJsZXMgY29tbyBuaXZlbCBlZHVjYXRpdm8sIGVzdGFkbyBjaXZpbCwgIHNhbHVkLCBzZXRjaWNpb3MgcHVibGljb3MsIGNhcmFjdGVyaXN0aWNhcyBkZSB2aXZpZW5kYSwgZW50cmUgb3RyYXMuDQpFbCBhcmNoaXZvIGRlIE5CSSBmdWUgZGVzY2FyZ2FkbyBlbiBmb3JtYXRvIC54bHhzLCBlbGltaW5hbmRvIHkgYWNvbW9kYW5kbyBpbmZvcm1hY2lvbiBuZWNlc2FyaWEgcGFyYSBsbGV2YXIgYSBjYWJvIGxvcyBtYXBhcyBkZWwgZGVwYXJ0YW1lbnRvIGRlIENhcXVldGEsIGUgaW1wb3J0YWRvIGEgUlN0dWRpby4NCiMjIyBQcmVwYXJhY2lvbiBkZSBucHJvZ3JhbWEgUlN0dWRpbw0KUHJpbWVybyBzZSBib3JyYXJhbiBkYXRvcyBkZSBsYSBtZW1vcmlhLg0KYGBge3J9DQpybShsaXN0PWxzKCkpDQpgYGANCiMjIyMgQ2FyZ2FyIGxpYnJlcmlhcy4gDQpTZSBpbnN0YWxhcmFuIGxhcyBsaWJyZXJpYXMgbmVjZXNhcmlhczogdGlkaXZlcnNlIChwYXJhIGhhY2VyIGpvaW5zIHkgZmlsdHJhZG9zKSwgcmVhZHhsIChwYXJhIGxlZXIgYXJjaGl2b3MgZGUgZXhjZWwpLCByZ2VvcyAocGFyYSBlbnRlbmRlciBvcGVyYWNpb25lcyBlc3BhY2lhbGVzIHNwKSwgc2YgKGxlZSB5IGFsbWFjZW5hIGRhdG9zIGNvbW8gZWxlbWVudG9zIGVzcGFjaWFsZXMgc2ltcGxlcyksIGNhcnRvZ3JhcGh5IHkgU3BhdGlhbFBvc2l0aW9uIChlbmNhcmdhZG9zIGRlIGxhIGNhcnRvZ3JhZmlhIHRlbWF0aWNhKS4gRW4gZXN0YSBvY2FzaW9uIHNlIHRyYWJhamFyYSBjb24gbGEgbGlicmVyaWEgY2FydG9ncmFwZ3kgcGFyYSByZWFsaXphciBsb3MgbWFwYXMgdGVtYXRpY29zIGRlbCBkZXBhcnRhbWVudG8gZGUgQ2FxdWV0YSwgc3VzdGl0dXllbmRvIGxhIGxpYnJlcmlhIGxlYWZsZXQuDQpgYGB7cn0NCmxpc3Qub2YucGFja2FnZXMgPC0gYygidGlkeXZlcnNlIiwgInJnZW9zIiwgInNmIiwgInJhc3RlciIsICJjYXJ0b2dyYXBoeSIsICJTcGF0aWFsUG9zaXRpb24iKQ0KbmV3LnBhY2thZ2VzIDwtIGxpc3Qub2YucGFja2FnZXNbIShsaXN0Lm9mLnBhY2thZ2VzICVpbiUgaW5zdGFsbGVkLnBhY2thZ2VzKClbLCJQYWNrYWdlIl0pXQ0KaWYobGVuZ3RoKG5ldy5wYWNrYWdlcykpIGluc3RhbGwucGFja2FnZXMobmV3LnBhY2thZ2VzKQ0KYGBgDQpTZSBjYXJnYXJhbiBsYXMgbGlicmVyaWFzIG5lY2VzYXJpYXMgcGFyYSBwb2RlciByZWFsaXphciBlbCB0cmFiYWpvLg0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkocmVhZHhsKQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShyZ2VvcykNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkocmFzdGVyKSANCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkoc2YpDQpgYGANCmBgYHtyfQ0KbGlicmFyeShjYXJ0b2dyYXBoeSkNCmxpYnJhcnkoU3BhdGlhbFBvc2l0aW9uKQ0KYGBgDQojIyMgTGVlciBsb3MgZGF0b3MgZGUgTkJJDQpFcyBuZWNlc2FyaW8gbGVlciBsb3MgZGF0b3MgZGVsIGFyY2hpdm8gY29uIGZvcm1hdG8gLnhseHMsIE5lY2VzaWRhZGVzIEJhc2ljYXMgSW5zYXRpc2ZlY2hhcyAoTkJJKSwgZGVzY2FyZ2FkbyBkZWwgZ2VvcG9ydGFsIGRlbCBEQU5FLCBwYXJhIHRlbmVyIGluZm9ybWFjaW9uIHNvYnJlIE5CSSBkZSBsb3MgbXVuaWNpcGlvcyBkZWwgZGVwYXJ0YW1lbnRvIGRlIENhcXVldGEuIFJlY2liaXJhIGVsIG5vbWJyZSBkZSBuYmkuDQpgYGB7cn0NCm5iaSA8LSByZWFkX2V4Y2VsKCJDOi9Vc2Vycy9KdWFuL0Rlc2t0b3AvTkJJX0NhcXVldGEueGxzeCIpDQpgYGANCkFob3JhLCBzZSBtb3N0cmFyYW4gbG9zIHByaW1lcm9zIGRhdG9zIGRlIG5iaToNCmBgYHtyfQ0KaGVhZChuYmkpDQpgYGANCg0KTGEgc2lndWllbnRlIGZ1bmNpb24gcGVybWl0aXJhIHNhYmVyIGN1YWwgZXMgZWwgbXVuaWNpcGlvIGNvbiBtYXlvciBwb3JjZW50YWplIGRlIE5CSSwgcGFyYSBlbCBjYXNvIGRlbCBkZXBhcnRhbWVudG8gZGUgQ2FxdWV0YSBlcyBlbCBtdW5pY2lwaW8gZGUgTWlsYW4sIGRvbmRlIGFwcm94aW1hZGFtZW50ZSBlbCA0NyUgZGUgbGEgcG9ibGFjaW9uIHRpZW5lIE5lY2VzaWRhZGVzIEJhc2ljYXMgSW5zdGF0aXNmZWNoYXMsIHkgZWwgMjUlIHZpdmUgZW4gbWlzZXJpYS4gRXN0ZSByZXN1bHRhZG8gcmVjaWJpcmEgZWwgbm9tYnJlIGRlIG1heF9uYmkuDQpgYGB7cn0NCm5iaSAlPiUgDQogICAgc2xpY2Uod2hpY2gubWF4KE5CSSkpIC0+IG1heF9uYmkNCg0KbWF4X25iaQ0KYGBgDQpDb250cmFzdGFuZG8gbGEgaW5mb3JtYWNpb24gYW50ZXJpb3IsIHNlIHB1ZWRlIGVqZWN1dGFyIGxhIHNpZ3VpZW50ZSBmdW5jaW9uIHBhcmEgY29ub2NlciBjdWFsIGVzIGVsIG11bmljaXBpbyBjb24gbWVub3IgcG9yY2VudGFqZSBkZSBOQkksIHNpZW5kbyBlbCBtdW5pY3BpbyBkZSBGbG9yZW5jaWEsIGRvbmRlIDE0LjUlIGRlIHN1IHBvYmxhY2lvbiBwcmVzZW50YSBOZWNlc2lkYWRlcyBCYXNpY2FzIEluc3RhZmlzZmVjaGFzLiANCmBgYHtyfQ0KbmJpICU+JSANCiAgICBzbGljZSh3aGljaC5taW4oTkJJKSkgLT4gbWluX25iaQ0KDQptaW5fbmJpDQpgYGANClBhcmEgcG9kZXIgb2JzZXJ2YXIgbWVqb3IgbGEgaW5mb3JtYWNpb24sIHNlIG9yZ2FuaXphcmFuIGxvcyBkYXRvcyBkZSBOQkkgcXVlIHByZXNlbnRhbiBsb3MgbXVuaWNpcGlvcyBkZSBDYXF1ZXRhIGVuIG9yZGVuIGRlc2NlbmRlbnRlLCBjdXlvIG5vbWJyZSBlcyBkZXNjX25iaSwgYSB0cmF2ZXMgZGUgbGEgc2lndWllbnRlIGluc3RydWNjaW9uOg0KYGBge3J9DQpuYmkgJT4lIA0KICBhcnJhbmdlKGRlc2MoTkJJKSkgIC0+IGRlc2NfbmJpDQoNCmRlc2NfbmJpDQpgYGANCiMjIyBVbmlyIGxvcyBkYXRvcyBkZSBOQkkgYSBsb3MgbXVuaWNpcGlvcyBkZSBDYXF1ZXRhDQpQYXJhIGVzdGUgcHVudG8gZXMgbmVjZXNhcmlvIGltcG9ydGFyIGxvcyBkYXRvcyBkZWwgYXJjaGl2byBlbiBlbCBxdWUgc2UgZW5jdWVudHJhbiBsb3MgZGF0b3MgYWRtaW5pc3RyYXRpdm9zIGRlbCBkZXBhcnRhbWVudG8gZGUgQ2FxdWV0YSBjb24gZWwgZmluIGRlIHRlbmVyIGxvcyAxNiBtdW5pY2lwaW9zIGRlIGVzdGUgZGVwYXJ0YW1lbnRvLCBlc3RvcyBzZXJhbiBsZWlkb3MgY29uIGxhIGxpYnJlcmlhIHNmLg0KYGBge3J9DQptdW5pYyA8LSBzdF9yZWFkKCJDOi9Vc2Vycy9KdWFuL0Rlc2t0b3AvQURNSU5JU1RSQVRJVk8xL01HTl9NUElPX1BPTElUSUNPLnNocCIpDQpgYGANCkNvbiBlc3RhIGluc3RydWNjaW9uIHNlIHB1ZWRlIGFwcmVjaWFyIGVsIG5vbWJyZSBkZSBjYWRhIHVubyBkZSBsb3MgbXVuaWNpcGlvcyBxdWUgY29uZm9ybWFuIGVsIGRlcGFydGFtZW50by4NCmBgYHtyfQ0KaGVhZChtdW5pYyRNUElPX0NOTUJSKQ0KYGBgDQpBaG9yYSBjb24gbG9zIGNvZGlnb3MgZGUgY2FkYSB1bm8gZGUgbG9zIG11bmljaXBpb3MuDQpgYGB7cn0NCmhlYWQobXVuaWMkTVBJT19DQ0RHTykNCmBgYA0KUGFyYSBwb2RlciBmdXNpb25hciBsb3MgZGF0b3MgZGUgTkJJIHkgbG9zIG11bmljaXBpb3MgZGUgQ2FxdWV0YSwgc2UgcHVlZGUgdXNhciBsYSBmdW5jaW9uIGxlZnRfam9pbiwgZG9uZGUgYW1ib3MgdGlwb3MgZGUgZGF0b3MgY29pbmNpZGlyYW4uIEVsIGNvZGlnbyBkZSBsb3MgbXVuaWNpcGlvcyBkZWwgZGVwYXJ0YW1lbnRvIHNlIGVuY3VlbnRyYSBlbiBsb3MgZG9zIGFyY2hpdm9zIGltcG9ydGFkb3MgeSByZWNpYmUgZWwgbm9tYnJlIGRlIE1QSU9fQ0NER08geSBDT0RJR08uDQpgYGB7cn0NCm5iaV9tdW5pYyA9IGxlZnRfam9pbihtdW5pYywgbmJpLCBieT1jKCJNUElPX0NDREdPIj0iQ09ESUdPIikpDQpgYGANCkVuIGVzdGUgcGFzbyBzZSBwb2RyYSBjb25maXJtYXIgc2kgZWwgam9pbiBxdWVkbyBiaWVuIGFsIHZlcmlmaWNhciBsb3MgcG9yY2VudGFqZXMgZGUgTkJJIGRlIGxvcyBtdW5pY2lwaW9zIGRlIGVzdGEgdGFibGEgY29uIGxvcyBkYXRvcyBkZSBlbCBwb3JjZW50YWplIGRlIE5CSSBkZSBsYXMgYW50ZXJpb3JlcyB0YWJsYXMuIFBvciBlamVtcGxvIGxhIHRhYmxhIGVuIGxhIGFwcmVjaW8gZWwgbXVuaWNpcGlvIGNvbiBtZW5vciBwb3JjZW50YWplIGRlIE5CSSwgc2llbmRvIGVsIG11bmljaXBpbyBkZSBGbG9yZW5jaWEgY3V5byBOQkkgZnVlIGRlIDE0LjUlIGFwcm94aW1hZGFtZW50ZS4gDQpgYGB7cn0NCm5iaV9tdW5pYyAlPiUNCiAgZHBseXI6OnNlbGVjdChNVU5JQ0lQSU8sIE1QSU9fQ0NER08sIE5CSSkgIC0+ICBjaGVja19uYmlfbXVuaWMNCg0KaGVhZChjaGVja19uYmlfbXVuaWMpDQpgYGANCkluaWNpYWxtZW50ZSBsYXMgY29vcmRlbmFkYXMgZXJhbiBnZW9ncmFmaWNhcywgcGVybyBjb21vIGNhcnRvZ3JhcGh5IHRyYWJhamEgZW4gY29vcmRlbmFkYXMgcGxhbmFzLCBlc3RhcyBkZWJlbiBzZXIgdHJhbnNmb3JtYWRhcyBjb24gbGEgZnVuY2lvbiBzdF90cmFuc2Zvcm0oKS4gQ3VhbmRvIHNlIHF1aWVyZSBvYnRlbmVyIGRhdG9zIGEgbml2ZWwgQ29sb21iaWEsIHNlIGRlYmUgdXNhciBlbCBzaXN0ZW1hIGRlIHJlZmVyZW5jaWEgZGUgY29vcmRlbmFkYXMgRVBTRzMxMTYgeSBzZSBwdWVkZSBhdmVyaWd1YXIgZW4gbGEgcGFnaW5hOiBlcHNnLmlvLg0KYGBge3J9DQpuYmlfbXVuaWNfbmV3IDwtIHN0X3RyYW5zZm9ybShuYmlfbXVuaWMsIGNycyA9IDMxMTYpDQpgYGANCiMjIyBFamVtcGxvcyBkZSBtYXBhcyB0ZW1hdGljb3MgZGVsIGRlcGFydGFtZW50byBkZSBDYXF1ZXRhDQpMYSBsaWJyZXJpYSBkZSBDYXJ0b2dyYXBoeSBlcyBkZSBhbHRhIGNhbGlkYWQsIHBlcm1pdGUgcHJveWVjdGFyIG1hcGFzIGRlIGlzb3BsZXRhcywgY29yb3BsZXRhcywgdGlwb2xvZ2lhLCBmbHVqb3MsIGVudHJlIG90cm9zOyBjb24gc2ltYm9sb3MgcHJvcG9yY2lvbmFsZXMuIEFkZW1hcyBicmluZGFuIGVsZW1lbnRvcyBxdWUgbWVqb3JhbiBlbCBlbnRlbmRpbWllbnRvIGRlIGxvcyBtYXBhcyB0YWxlcyBjb21vIHBhbGV0YXMgZGUgbWFwYXMsIGZsZWNoYSBkZWwgTm9ydGUsIGVzY2FsYXMsIHRpdHVsb3MsIGVudHJlIG90cm9zIChHaXRIdWIsIHMuZikuIExvcyBkYXRvcyBkZWJlbiBzZXIgbGVpZG9zIGNvbiBsYSBsaWJyZXJpYSBzZi4NClBhcmEgZXN0ZSBwdW50byBzZSBpbnN0YWxhcmEgZWwgcGFxdWV0ZSBvc21kYXRhIHkgc2UgY2FyZ2FyYSBzdSBsaWJyZXJpYS4gRXN0ZSBwYXF1ZXRlIHBlcm1pdGUgZGVzY2FyZ2FyIHkgdXNhciBkYXRvcyBkZSBPcGVuU3RyZWV0TWFwLCBhc2VndXJhbmRvIHF1ZSBsb3MgZGF0b3MgcHJvdmllbmVuIGRlIHVuYSBmdWVudGUgY29uZmlhYmxlIChQYWdnaGFtIHkgTG92ZWxhbmNlLCAyMDIwKS4NCmBgYHtyfQ0KaW5zdGFsbC5wYWNrYWdlcygib3NtZGF0YSIpDQpgYGANCmBgYHtyfQ0KbGlicmFyeShvc21kYXRhKQ0KYGBgDQpUYW1iaWVuIHNlIGluc3RhbGFyYSBlbCBwYXF1ZXRlIHJnZGFsLg0KYGBge3J9DQppbnN0YWxsLnBhY2thZ2VzKCJyZ2RhbCIpDQpgYGANCmBgYHtyfQ0KbGlicmFyeShyZ2RhbCkNCmBgYA0KIyMjIyBNYXBhcyBkZSBzaW1ib2xvcyBwcm9wb3JjaW9uYWxlcyBlbiBiYXNlIGEgT3BlblN0cmVldE1hcA0KRXN0ZSB0aXBvIGRlIG1hcGFzIHJlcHJlc2VudGFuIGRhdG9zIGFzb2NpYWRvcyBjb24gdWJpY2FjaW9uZXMsIGRvbmRlIGVsIHRhbWFubyBkZSBsb3Mgc2ltYm9sb3MgZXMgcHV0aWwgcGFyYSBtb3N0cmFyIGxhcyBkaWZlcmVuY2lhcyBlbiBsYXMgb2N1cnJlbmNpYXMuIFNlIHB1ZWRlbiBlbmNvbnRyYXIgZmlndXJhcyBjaXJjdWxhcmVzLCBlbiBiYXJyYXMgbyBjdWFkcmFkb3MuIE9wZW5TdHJlZXRNYXAgYnJpbmRhIGRhdG9zIGdyYXR1aXRvcyBhIHN1cyB1c3VhcmlvcywgcG9yIGVqZW1wbG8gaW5mb3JtYWNpb24gZGUgdmlhcyBkZWwgbXVuZG8uIFNlIHB1ZWRlbiBkZXNjYXJnYXIgbG9zIGRhdG9zIGNvbiBsYSBmdW5jaW9uIGdldFRpbGVzKCkgeSB2aXN1YWxpemFybG9zIGNvbiB0aWxlc0x5ZXIoKSAoQnJpbmV5LCAyMDE5KS4NCg0KUGFyYSBwb2RlciBhcHJlY2lhciBsb3MgZGF0b3MgZGUgTkJJIGNvbiBkaWZlcmVudGVzIGZpZ3VyYXMgZ2VvbWV0cmljYXMgZW4gZnVuY2lvbiBkZSB1bmEgdmFyaWFibGUsIHNlIHVzYXJhIGxhIGZ1bmNpb24gcHJvcFN5bWJvbExheWVyLCBvZnJlY2llbmRvIGRpc3RpbnRvcyB0aXBvcyBkZSBzaW1ib2xvcyAoY3VhZHJhZG9zLCBjaXJjdWxvcyB5IGJhcnJhcykgeSB0YW1hbm9zLiBDb24gZWwgYXJndW1lbnRvIGluY2hlcyBlcyBwb3NpYmxlIG1vZGlmaWNhciBlbCB0YW1hbm8gZGUgbG9zIHNpbWJvbG9zLiANCmBgYHtyfQ0KbXVuLm9zbSA8LSBnZXRUaWxlcygNCnggPSBuYmlfbXVuaWNfbmV3LCANCnR5cGUgPSAiT3BlblN0cmVldE1hcCIsIA0Kem9vbSA9IDgsDQpjYWNoZWRpciA9IFRSVUUsDQpjcm9wID0gRkFMU0UNCikNCmBgYA0KRW4gZWwgbWFwYSBzZSBwdWVkZSB2ZXIgdW5hIGRpc3RhbmNpYSBkZSAxMDBrbSwgbm8gZXMgaW50ZXJhY3Rpdm8sIHRpZW5lIGVsIG9iamV0aXZvIGRlIGRpdnVsZ2FyIGluZm9ybWFjaW9uLiBTZSBwdWVkZW4gYXByZWNpYXIgMTYgY2lyY3Vsb3MgbWFycm9uZXMgZGUgZGlmZXJlbnRlIHRhbWFubywgdW5vIHBhcmEgY2FkYSBtdW5pY2lwaW8sIGRvbmRlIGEgbWF5b3IgdGFtYW5vIGRlIGxvcyBjaXJ1Y2xvcywgbWF5b3Igc2VyYSBlbCBwb3JjZW50YWplIGRlIE5CSSBlbiBlc2UgbXVuaWNpcGlvLg0KYGBge3J9DQojRXN0YWJsZWNlIG1hcmdlbmVzDQpvcGFyIDwtIHBhcihtYXIgPSBjKDAsMCwxLjIsMCkpDQp0aWxlc0xheWVyKHggPSBtdW4ub3NtKQ0KI1RyYXphciBmcm9udGVyYXMgZGUgbG9zIG11bmljaXBpb3MNCnBsb3Qoc3RfZ2VvbWV0cnkobmJpX211bmljX25ldyksIGNvbCA9IE5BLCBib3JkZXIgPSAiZ3JleSIsIGFkZD1UUlVFKQ0KI1RyYXphciBOQkkNCnByb3BTeW1ib2xzTGF5ZXIoDQogIHggPSBuYmlfbXVuaWNfbmV3LCANCiAgdmFyID0gIk5CSSIsIA0KICBpbmNoZXMgPSAwLjE1LCANCiAgY29sID0gImJyb3duNCIsDQogIGxlZ2VuZC5wb3MgPSAidG9wcmlnaHQiLCAgDQogIGxlZ2VuZC50aXRsZS50eHQgPSAiVG90YWwgTkJJIg0KKQ0KI0Rpc2Vubw0KbGF5b3V0TGF5ZXIodGl0bGUgPSAiRGlzdHJpYnVjaW9uIGRlIE5CSSBlbiBDYXF1ZXRhIiwNCiAgICAgICAgICAgIHNvdXJjZXMgPSAiRnVlbnRlczogREFORSwgMjAxOFxuqSBPcGVuU3RyZWV0TWFwIiwNCiAgICAgICAgICAgIGF1dGhvciA9ICJTYW5kcmEgS2F0dGVyeW5lIFJvZHJpZ3VleiBIdXJ0YWRvIiwNCiAgICAgICAgICAgIGZyYW1lID0gVFJVRSwgbm9ydGggPSBGQUxTRSwgdGFidGl0bGUgPSBUUlVFKQ0KI0ZsZWNoYSBOb3J0ZQ0Kbm9ydGgocG9zID0gInRvcGxlZnQiKQ0KYGBgDQpFbiBlc3RlIG1hcGEgc2UgcHVlZGUgYXByZWNpYXIgbWVqb3IgZWwgZGVwYXJ0YW1lbnRvIGRlYmlkbyBhIHF1ZSBsb3MgYm9yZGVzIHNvbiBkZSBjb2xvciBuZWdybywgbWFzIGZhY2lsZXMgZGUgdmlzdWFsaXphci4gTG9zIGNpcmN1bG9zIGRlIGNvbG9yIG5hcmFuamEgcmVwcmVzZW50YW4gZWwgcG9yY2VudGFqZSBkZSBOQkkgcXVlIHRpZW5lIENhcXVldGEgcG9yIGRlcGFydGFtZW50bywgYSBtYXlvciB0YW1hbm8gZGVsIGNpcmN1bG8sIG1heW9yIHNlcmEgZWwgdmFsb3IgZGUgTkJJLiANCmBgYHtyfQ0Kb3BhciA8LSBwYXIobWFyID0gYygxLDAsMi4yLDEpKQ0KdGlsZXNMYXllcih4ID0gbXVuLm9zbSkNCnBsb3Qoc3RfZ2VvbWV0cnkobmJpX211bmljX25ldyksIGNvbCA9IE5BLCBib3JkZXIgPSAiYmxhY2siLCBhZGQ9VFJVRSkNCnByb3BTeW1ib2xzTGF5ZXIoDQogIHggPSBuYmlfbXVuaWNfbmV3LCANCiAgdmFyID0gIk5CSSIsIA0KICBpbmNoZXMgPSAwLjE2LCANCiAgY29sID0gIm9yYW5nZTEiLA0KICBsZWdlbmQucG9zID0gInRvcHJpZ2h0IiwgIA0KICBsZWdlbmQudGl0bGUudHh0ID0gIlRvdGFsIE5CSSINCikNCmxheW91dExheWVyKHRpdGxlID0gIkRpc3RyaWJ1Y2lvbiBkZSBOQkkgZW4gQ2FxdWV0YSIsDQogICAgICAgICAgICBzb3VyY2VzID0gIkZ1ZW50ZXM6IERBTkUsIDIwMThcbqkgT3BlblN0cmVldE1hcCIsDQogICAgICAgICAgICBhdXRob3IgPSAiU2FuZHJhIEthdHRlcnluZSBSb2RyaWd1ZXogSHVydGFkbyIsDQogICAgICAgICAgICBmcmFtZSA9IFRSVUUsIG5vcnRoID0gRkFMU0UsIHRhYnRpdGxlID0gVFJVRSkNCm5vcnRoKHBvcyA9ICJ0b3BsZWZ0IikNCmBgYA0KIyMjIyBNYXBhIGRlIGNvcm9wbGV0YXMNClNvbiBtYXBhcyBlbiBsb3MgcXVlIHNlIHZlbiByZWZsZWphZG9zIGNvbG9yZXMgcXVlIHJlcHJlc2VudGFuIHZhbG9yZXMgbyB1biByYW5nbyBkZSB2YWxvcmVzIGRlIHVuYSB2YXJpYWJsZSBjdWFudGl0YXRpdmEgZXNwZWNpZmljYSwgZXN0b3MgdmFyaWFuIHNlZ3VuIGVzZSB2YWxvci4gUHVlZGVuIHJlZmxlamFyIGxhIGRlbnNpZGFkLCBwb3JjZW50YWplLCBwcm9tZWRpbyBvIGV2ZW50byBkZW50cm8gZGUgdW4gZXNwYWNpbyBkZXRlcm1pbmFkby4gU2UgcHVlZGVuIGVuY29udHJhciBhcmd1bWVudG9zIHBhcmEgcGVyc29uYWxpemFyIGxvcyBtYXBhcyBjb21vIGVsIGNvbG9yLCB0YW1hbm8sIGluZGljZXMsIHNpbWJvbG9zLCBlbnRyZSBvdHJvcyAoQnJpbmV5LCAyMDE5KS4gICANCkVuIGVsIHNpZ3VpZW50ZSBtYXBhIHNlIG9ic2VydmFyYSBlbCBwb3JjZW50YWplIGRlIE5CSSBlbiBsb3MgbXVuaWNpcGlvcyBkZSBDYXF1ZXRhLCBkb25kZSBjYWRhIGNvbG9yIHJlcHJlc2VudGEgdW4gdmxvciBkaWZkZXJlbnRlLCBlbnRyZSBtYXMgb3NjdXJvIHNlYSBlbCBjb2xvciwgZWwgcG9yY2VudGFqZSBkZSBOQkkgZXMgbWF5b3IuIEVzdGUgbWFwYSB0aWVuZSB1bmEgZGlzdGFuY2lhIGRlIDgwa20geSBzZSBtYW5lam8gdW5hIHBhbGV0YSBkZSBjb2xvciBhcmVuYS4gDQpgYGB7cn0NCm9wYXIgPC0gcGFyKG1hciA9IGMoMCwwLDEuMiwwKSkNCiNDb2xvciBkZSBmb25kbyBkZSBsYSBmaWd1cmENCnBhcihiZz0iZ3JleTkwIikNCiNUcmF6YXIgbXVuaWNpcGlvcw0KcGxvdChzdF9nZW9tZXRyeShuYmlfbXVuaWNfbmV3KSwgY29sID0gTkEsIGJvcmRlciA9IE5BLCBiZyA9ICIjYWFkYWZmIikNCmNob3JvTGF5ZXIoDQogIHggPSBuYmlfbXVuaWNfbmV3LCANCiAgdmFyID0gIk5CSSIsDQogIG1ldGhvZCA9ICJnZW9tIiwNCiAgbmNsYXNzPTUsDQogIGNvbCA9IGNhcnRvLnBhbChwYWwxID0gInNhbmQucGFsIiwgbjEgPSA1KSwNCiAgYm9yZGVyID0gIndoaXRlIiwgDQogIGx3ZCA9IDAuNSwNCiAgbGVnZW5kLnBvcyA9ICJ0b3ByaWdodCIsIA0KICBsZWdlbmQudGl0bGUudHh0ID0gIk5CSSIsDQogIGFkZCA9IFRSVUUNCikgDQpsYXlvdXRMYXllcih0aXRsZSA9ICJEaXN0cmlidWNpb24gZGUgTkJJIGVuIENhcXVldGEiLCANCiAgICAgICAgICAgIHNvdXJjZXMgPSAiRnVlbnRlOiBEQU5FLCAyMDE4IiwNCiAgICAgICAgICAgIGF1dGhvciA9ICJTYW5kcmEgS2F0dGVyeW5lIFJvZHJpZ3VleiBIdXJ0YWRvIiwgDQogICAgICAgICAgICBmcmFtZSA9IFRSVUUsIG5vcnRoID0gVFJVRSwgdGFidGl0bGUgPSBUUlVFLCBjb2w9ImJsYWNrIikgDQpub3J0aChwb3MgPSAidG9wbGVmdCIpDQpgYGANCkVuIGVsIHNpZ3VpZW50ZSBtYXBhIHNlIG1hbmVqbyB1bmEgcGFsZXRhIGRlIGNvbG9yIHJvc2FkbywgdGllbmUgZWwgbWlzbW8gY29tcG9ydGFtaWVudG8gcXVlIGVsIG1hcGEgZGUgYXJyaWJhLiANCmBgYHtyfQ0Kb3BhciA8LSBwYXIobWFyID0gYygwLDAsMS4yLDApKQ0KcGFyKGJnPSJibGFjayIpDQpwbG90KHN0X2dlb21ldHJ5KG5iaV9tdW5pY19uZXcpLCBjb2wgPSBOQSwgYm9yZGVyID0gTkEsIGJnID0gIiNhYWRhZmYiKQ0KY2hvcm9MYXllcigNCiAgeCA9IG5iaV9tdW5pY19uZXcsIA0KICB2YXIgPSAiTkJJIiwNCiAgbWV0aG9kID0gImdlb20iLA0KICBuY2xhc3M9NSwNCiAgY29sID0gY2FydG8ucGFsKHBhbDEgPSAicGluay5wYWwiLCBuMSA9IDUpLA0KICBib3JkZXIgPSAiYmxhY2siLCANCiAgbHdkID0gMS41LA0KICBsZWdlbmQucG9zID0gInRvcGxlZnQiLCANCiAgbGVnZW5kLnRpdGxlLnR4dCA9ICJOQkkiLA0KICBhZGQgPSBUUlVFDQopIA0KbGF5b3V0TGF5ZXIodGl0bGUgPSAiRGlzdHJpYnVjaW9uIGRlIE5CSSBlbiBDYXF1ZXRhIiwgDQogICAgICAgICAgICBzb3VyY2VzID0gIkZ1ZW50ZTogREFORSwgMjAxOCIsDQogICAgICAgICAgICBhdXRob3IgPSAiU2FuZHJhIEthdHRlcnluZSBSb2RyaWd1ZXogSHVydGFkbyIsIA0KICAgICAgICAgICAgZnJhbWUgPSBUUlVFLCBub3J0aCA9IFRSVUUsIHRhYnRpdGxlID0gVFJVRSwgY29sPSJibGFjayIpIA0Kbm9ydGgocG9zID0gInRvcHJpZ2h0IikNCmBgYA0KIyMjIyBNYXBhIGRlIHRpcG9sb2dpYSB5IHNpbWJvbG9zIHByb3BvcmNpb25hbGVzDQpFc3RlIG1hcGEgdGllbmUgc2ltYm9sb3MgZG9uZGUsIHNlIG1hbmVqYW4gZG9zIHZhcmlhYmxlczogdW5hIGN1YW50aXRhdGl2YSwgcXVlIGVzIGVsIHBvcmNlbnRhamUgZGUgTkJJLCB5IHVuYSBjdWFsaXRhdGl2YSBxdWUgZXMgdW5hIGNsYXNpZmljYWNpb24uIExhIGZ1bmNpb24gbXV0YXRlIHZpZW5lIGRlbCBwYXF1ZXRlIGRwbHlyIHkgcGVybWl0ZSBjcmVhciBudWV2b3MgYXRyaWJ1dG9zLg0KRW4gZXN0ZSBjYXNvLCBzZSBjbGFzaWZpY2FyYSBsYSBwb2JyZXphIHRlbmllbmRvIGVuIGN1ZW50YSBsYSBtaXNlcmlhIHkgZWwgaGFjaW5hbWllbnRvLCBkb25kZSBsYSBwcmltZXJhIGVzIGV4dHJlbWEgY3VhbmRvIHN1IHZhbG9yIGVzIHN1cGVyaW9yIGEgMjAsIHkgbGEgc2VndW5kYSBhbHRhIHN1IHN1IHZhb3IgZXMgbWF5b3IgYSA1LCBlIGludGVybWVkaW8gc2kgbm8gZXN0YSBkZXRybyBkZSBlc3RvcyB2YWxvcmVzLg0KYGBge3J9DQpuYmlfbXVuaWNfMiA8LSBkcGx5cjo6bXV0YXRlKG5iaV9tdW5pY19uZXcsIFBvYnJlemEgPSBpZmVsc2UoTUlTRVJJQSA+IDIwLCAiRXh0cmVtYSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKEhBQ0lOQU1JRU5UTyA+IDUsICJBbHRhIiwgIkludGVybWVkaWEiKSkpDQpgYGANCkVsIG51ZXZvIGF0cmlidXRvIHNlIGxsYW1hIHBvYnJlemEuDQpgYGB7cn0NCmhlYWQobmJpX211bmljXzIpDQpgYGANCg0KYGBge3J9DQpsaWJyYXJ5KHNmKQ0KbGlicmFyeShjYXJ0b2dyYXBoeSkNCmBgYA0KU2UgcHVlZGUgdmVyIHF1ZSBlbiBlbCBtYXBhIGhheSB1bm9zIGNpcmN1bG9zIGRlIGNvbG9yZXMsIGRvbmRlIGNhZGEgY29sb3IgZGVwcmVzZW50YSBzaSBlbCBuaXZlbCBkZSBwb2JyZXphIGVzIGFsdG8sIGludGVybWVkaW8gbyBiYWpvOyBkb25kZSBjYWRhIHNpbWJvbG8geSBzdSB0YW1hbm8gZGVwZW5kZW4gZGUgbG9zIHZhbG9yZXMgZGUgTkJJLCB5IGRlIGFoaSBzZSBkZXRlcm1pbmEgbGEgcG9icmV6YSBkZWwgbXVuaWNpcGlvLiBQYXJhIGVzdGUgbWFwYSBzZSB1dGlsaXphcm9uIHNpbWJvbG9zIGN1YWRyYWRvcyBjb24gcGFsZXRhIG11bHRpY29sb3IuDQpgYGB7cn0NCm9wYXIgPC0gcGFyKG1hciA9IGMoMCwwLDEuMiwwKSkNCnBsb3Qoc3RfZ2VvbWV0cnkobmJpX211bmljXzIpLCBjb2w9IiNmMmVmZTkiLCBib3JkZXI9IiNiMzhlNDMiLCBiZyA9ICIjYWFkM2RmIiwgDQogICAgIGx3ZCA9IDAuNSkNCnByb3BTeW1ib2xzVHlwb0xheWVyKA0KICB4ID0gbmJpX211bmljXzIsIA0KICB2YXIgPSAiTkJJIiwgDQogIGluY2hlcyA9IDAuMywNCiAgc3ltYm9scyA9ICJzcXVhcmUiLA0KICBib3JkZXIgPSAid2hpdGUiLA0KICBsd2QgPSAuNSwNCiAgbGVnZW5kLnZhci5wb3MgPSBjKCJ0b3ByaWdodCIpLCANCiAgbGVnZW5kLnZhci50aXRsZS50eHQgPSAiTkJJIiwNCiAgdmFyMiA9ICJQb2JyZXphIiwNCiAgbGVnZW5kLnZhcjIudmFsdWVzLm9yZGVyID0gYygiRXh0cmVtYSIsICJBbHRhIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkludGVybWVkaWEiKSwNCiAgY29sID0gY2FydG8ucGFsKHBhbDEgPSAibXVsdGkucGFsIiwgbjEgPSAzKSwNCiAgbGVnZW5kLnZhcjIucG9zID0gYygiYm90dG9tcmlnaHQiKSwgDQogIGxlZ2VuZC52YXIyLnRpdGxlLnR4dCA9ICJQb2JyZXphIg0KKSANCmxheW91dExheWVyKHRpdGxlPSJEaXN0cmlidWNpb24gZGUgTkJJIGVuIENhcXVldGEiLCANCiAgICAgICAgICAgIGF1dGhvciA9ICJTYW5kcmEgS2F0dGVyeW5lIFJvZHJpZ3VleiBIdXJ0YWRvIiwgDQogICAgICAgICAgICBzb3VyY2VzID0gIkZ1ZW50ZTogREFORSwgMjAxOCIsIA0KICAgICAgICAgICAgc2NhbGUgPSAxLCB0YWJ0aXRsZSA9IFRSVUUsIGZyYW1lID0gVFJVRSkNCm5vcnRoKHBvcyA9ICJ0b3BsZWZ0IikNCmBgYA0KRW4gZXN0ZSBtYXBhIHNlIHB1ZWRlbiBhcHJlY2lhciBsb3MgbWlzbW9zIHZhbG9yZXMgcXVlIGVuIGVsIG1hcGEgYW50ZXJpb3IsIHBlcm8gZXN0YSB2ZXogcmVwcmVzZW50YWRvcyBlbiBiYXJyYXMgY29uIHVuYSBwYWxldGEgZGUgY29sb3Igdmlub3RpbnRvLCBkb25kZSBjYWRhIGNvbG9yIHJlcHJlc2VudGFyYSBlbCBwb3JjZW50YWplIGRlIG1pc2VyaWEgZW4gZWwgcXVlIHZpdmVuIGxvcyBoYWJpdGFudGVzIGRlIGNhZGEgbXVuaWNpcGlvLCB5IGVzdGUgcmVwcmVzZW50YSBlbCBuaXZlbCBkZSBwb2JyZXphLg0KYGBge3J9DQpvcGFyIDwtIHBhcihtYXIgPSBjKDAsMCwxLjIsMCkpDQpwbG90KHN0X2dlb21ldHJ5KG5iaV9tdW5pY18yKSwgY29sPSIjZjJlZmU5IiwgYm9yZGVyPSIjYjM4ZTQzIiwgYmcgPSAiI2FhZDNkZiIsIA0KICAgICBsd2QgPSAwLjUpDQpwcm9wU3ltYm9sc1R5cG9MYXllcigNCiAgeCA9IG5iaV9tdW5pY18yLCANCiAgdmFyID0gIk5CSSIsIA0KICBpbmNoZXMgPSAwLjUsDQogIHN5bWJvbHMgPSAiYmFyIiwNCiAgYm9yZGVyID0gImJsYWNrIiwNCiAgbHdkID0gLjUsDQogIGxlZ2VuZC52YXIucG9zID0gYyggInRvcGxlZnQiKSwgDQogIGxlZ2VuZC52YXIudGl0bGUudHh0ID0gIk5CSSIsDQogIHZhcjIgPSAiUG9icmV6YSIsDQogIGxlZ2VuZC52YXIyLnZhbHVlcy5vcmRlciA9IGMoIkV4dHJlbWEiLCAiQWx0YSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJbnRlcm1lZGlhIiksDQogIGNvbCA9IGNhcnRvLnBhbChwYWwxID0gIndpbmUucGFsIiwgbjEgPSAzKSwNCiAgbGVnZW5kLnZhcjIucG9zID0gYygidG9wcmlnaHQiKSwgDQogIGxlZ2VuZC52YXIyLnRpdGxlLnR4dCA9ICJQb2JyZXphIg0KKSANCmxheW91dExheWVyKHRpdGxlPSJEaXN0cmlidWNpb24gZGUgTkJJIGVuIENhcXVldGEiLCANCiAgICAgICAgICAgIGF1dGhvciA9ICJTYW5kcmEgS2F0dGVyeW5lIFJvZHJpZ3VleiBIdXJ0YWRvIiwgDQogICAgICAgICAgICBzb3VyY2VzID0gIkZ1ZW50ZTogREFORSwgMjAxOCIsIA0KICAgICAgICAgICAgc2NhbGUgPSAxLCB0YWJ0aXRsZSA9IFRSVUUsIGZyYW1lID0gVFJVRSkNCm5vcnRoKHBvcyA9ICJ0b3BsZWZ0IikNCmBgYA0KIyMjIyBNYXBhcyBkZSBldGlxdWV0YXMNCkVsIHNpZ3VpZGVudGUgbWFwYSByZXByZXNlbnRhIGxvcyBtdW5pY2lwaW9zIGNvbG9yZWFkb3MgY29uIHVuYSBwYWxldGEgbmFyYW5qYS4gQ2FkYSBtdW5pY2lwaW8gbGxldmEgbGEgZXRpcXVldGEgZGUgc3Ugbm9tYnJlIGNvcnJlc3BvbmRpZW50ZS4gQ3VhbmRvIGVsIGNvbG9yIHNlIHRvcm5hIG1hcyBvc2N1cm8sIHNlcmEgbWF5b3IgZWwgcG9yY2VudGFkZSBkZSBOQkkgcXVlIHByZXNlbnRhIGVzYSBwb2JsYWNpb24uDQpgYGB7cn0NCmxpYnJhcnkoc2YpDQpsaWJyYXJ5KGNhcnRvZ3JhcGh5KQ0KYGBgDQpFc3RlIG1hcGEgcHJlc2VudGEgcGFsZXRhIGRlIGNvbG9yIGFyZW5hLCByZXByZXNlbnRhbmRvIGVsIHBvcmNlbnRhamUgZGUgTkJJLiANCmBgYHtyfQ0Kb3BhciA8LSBwYXIobWFyID0gYygwLDAsMS4yLDApKQ0KcGFyKGJnPSJncmV5MjUiKQ0KcGxvdChzdF9nZW9tZXRyeShuYmlfbXVuaWNfMiksIGNvbCA9ICIjZTRlOWRlIiwgYm9yZGVyID0gImRhcmtzZWFncmVlbjQiLCANCiAgICAgYmcgPSAiZ3JleTc1IiwgbHdkID0gMC41KQ0KY2hvcm9MYXllcigNCiAgeCA9IG5iaV9tdW5pY19uZXcsIA0KICB2YXIgPSAiTkJJIiwNCiAgbWV0aG9kID0gImdlb20iLA0KICBuY2xhc3M9NSwNCiAgY29sID0gY2FydG8ucGFsKHBhbDEgPSAic2FuZC5wYWwiLCBuMSA9IDUpLA0KICBib3JkZXIgPSAid2hpdGUiLCANCiAgbHdkID0gMC41LA0KICBsZWdlbmQucG9zID0gInRvcHJpZ2h0IiwgDQogIGxlZ2VuZC50aXRsZS50eHQgPSAiTkJJIiwNCiAgYWRkID0gVFJVRQ0KKSANCmxhYmVsTGF5ZXIoDQogIHggPSBuYmlfbXVuaWNfMiwgDQogIHR4dCA9ICJNVU5JQ0lQSU8iLCANCiAgY29sPSAid2hpdGUiLCANCiAgY2V4ID0gMC40LCANCiAgZm9udCA9IDQsDQogIGhhbG8gPSBUUlVFLCANCiAgYmcgPSAiZ3JleTI1IiwgDQogIHIgPSAwLjEsIA0KICBvdmVybGFwID0gRkFMU0UsIA0KICBzaG93LmxpbmVzID0gRkFMU0UNCikNCmxheW91dExheWVyKA0KICB0aXRsZSA9ICJNdW5pY2lwaW9zIGRlbCBkZXBhcnRhbWVudG8gZGUgQ2FxdWV0YSIsIA0KICBzb3VyY2VzID0gIkZ1ZW50ZTogREFORSwgMjAxOCIsICANCiAgYXV0aG9yID0gIlNhbmRyYSBLYXR0ZXJ5bmUgUm9kcmlndWV6IEh1cnRhZG8iLCANCiAgZnJhbWUgPSBUUlVFLA0KICBub3J0aCA9IFRSVUUsIA0KICB0YWJ0aXRsZSA9IFRSVUUsIA0KICB0aGVtZSA9ICJ0YXVwZS5wYWwiDQopIA0KYGBgDQpFc3RlIG1hcGEgcHJlc2VudGEgbGEgcGFsZXRhIGNvbG9yIG5hcmFuamEuDQpgYGB7cn0NCm9wYXIgPC0gcGFyKG1hciA9IGMoMCwwLDEuMiwwKSkNCnBhcihiZz0id2hpdGUiKQ0KcGxvdChzdF9nZW9tZXRyeShuYmlfbXVuaWNfMiksIGNvbCA9ICIjZTRlOWRlIiwgYm9yZGVyID0gImRhcmtzZWFncmVlbjQiLCANCiAgICAgYmcgPSAiZ3JleTg1IiwgbHdkID0gMC41KQ0KY2hvcm9MYXllcigNCiAgeCA9IG5iaV9tdW5pY19uZXcsIA0KICB2YXIgPSAiTkJJIiwNCiAgbWV0aG9kID0gImdlb20iLA0KICBuY2xhc3M9NSwNCiAgY29sID0gY2FydG8ucGFsKHBhbDEgPSAib3JhbmdlLnBhbCIsIG4xID0gNSksDQogIGJvcmRlciA9ICJCbGFjayIsIA0KICBsd2QgPSAwLjIsDQogIGxlZ2VuZC5wb3MgPSAidG9wbGVmdCIsIA0KICBsZWdlbmQudGl0bGUudHh0ID0gIk5CSSIsDQogIGFkZCA9IFRSVUUNCikgDQpsYWJlbExheWVyKA0KICB4ID0gbmJpX211bmljXzIsIA0KICB0eHQgPSAiTVVOSUNJUElPIiwgDQogIGNvbD0gIndoaXRlIiwgDQogIGNleCA9IDAuNCwgDQogIGZvbnQgPSA0LA0KICBoYWxvID0gVFJVRSwgDQogIGJnID0gImJsYWNrIiwgDQogIHIgPSAwLjEsIA0KICBvdmVybGFwID0gRkFMU0UsIA0KICBzaG93LmxpbmVzID0gRkFMU0UNCikNCmxheW91dExheWVyKA0KICB0aXRsZSA9ICJNdW5pY2lwaW9zIGRlbCBkZXBhcnRhbWVudG8gZGUgQ2FxdWV0YSIsIA0KICBzb3VyY2VzID0gIkZ1ZW50ZTogREFORSwgMjAxOCIsICANCiAgYXV0aG9yID0gIlNhbmRyYSBLYXR0ZXJ5bmUgUm9kcmlndWV6IEh1cnRhZG8iLCANCiAgZnJhbWUgPSBUUlVFLA0KICBub3J0aCA9IFRSVUUsIA0KICB0YWJ0aXRsZSA9IFRSVUUsIA0KICB0aGVtZSA9ICJ0YXVwZS5wYWwiDQopIA0KYGBgDQojIyMjIE1hcGFzIGRlIGlzb3BsZXRhcyBvIGlzb2xpbmVhcw0KRXN0b3MgbWFwYXMgcmVwcmVzZW50YW4gdW4gZmVub21lbm8gcXVlIHNlIGRpc3RyaWJ1eWUgZGUgZm9ybWEgY29udGludWEgZW4gZWwgZXNwYWNpby4gVGllbmVuIHVuIGVuZm9xdWUgZGUgbW9kZWxhZG8gZGUgaW50ZXJhY2Npb24gZXNwYWNpYWwuIFBlcm1pdGVuIG1hcGFzIGNvbiB1bmEgcmVwcmVzZW50YWNpb24gZXNwYWNpYWwgZGVsIGZlbm9tZW5vIG8gdmFyaWFibGUsIGluZGVwZW5kaWVudGVtZW50ZSBhIGxhIGhldGVyb2dlbmVpZGFkIGRlIGxhIGRpdmlzaW9uIHRlcnJpdG9yaWFsLkVzdG9zIGRhdG9zIHNlIHJlY29waWxhbiBlbiBwdW50b3MgbWVkaWJsZXMsIGNvbW8gZXN0YWNpb25lcyBtZXRlb3JvbG9naWNhczsgbyBwb3IgYXJlYSAoQnJpbmV5LCAyMDE5KS4NCg0KUGFyYSBsb3Mgc2lndWllbnRlcyBwdW50b3Mgc2UgaGFyYSBsYSByZXByZXNlbnRhY2lvbiBncmFmaWNhIGRlIGxhIGRpc3RyaWJ1Y2lvbiBlc3BhY2lhbCBlbiBlbCBkZXBhcnRhbWVudG8gZGUgQ2FxdWV0YSBkZWwgY3VsdGl2byBkZSBwbGF0YW5vIHkgZGUgeXVjYS4NCiMjIyMjIEN1bHRpdm8gZGUgcGxhdGFubw0KUGFyYSBlc3RlIHB1bnRvIHNlIGRlYmVuIGltcG9ydGFyIGxvcyBkYXRvcyBkZSBsb3MgY3VsdGl2b3MgZGVsIGRlcGFydGFtZW50byBkZSBDYXF1ZXRhLCBkb25kZSBzZSBkZWphcmEgc29sbyBlbCBkZWwgYW5vIGRlIGludGVyZXMsIGVuIGVzdGUgY2FzbyAyMDE4LiBFbCBhcmNoaXZvIGVuIGZvcm1hdG8gLnhsc3guDQpgYGB7cn0NCmN1bHRpdm9zMjAxOCA8LSByZWFkX2V4Y2VsKCJDOi9Vc2Vycy9KdWFuL0Rlc2t0b3AvUEVWQV9DYXF1ZXRhMi54bHN4IikNCmBgYA0KYGBge3J9DQpoZWFkKGN1bHRpdm9zMjAxOCkNCmBgYA0KU2UgZGViZW4gZmlsdHJhciBsYXMgZmlsYXMgcXVlIHJlcHJlc2VudGFuIGFsIGN1bHRpdm8gcXVlIHNlIHF1aWVyZSByZXByZXNlbnRhciwgZW4gZXN0ZSBjYXNvIHNlcmEgZWwgcGxhdGFuby4gDQpgYGB7cn0NCmN1bHRpdm9zMjAxOCAlPiUNCiAgZmlsdGVyKENVTFRJVk8gPT0gIlBMQVRBTk8iKSAtPiBwbGF0YW5vMjAxOA0KYGBgDQpFbiBlc3RlIHB1bnRvIHNlIGNhbWJpYXJhIGVsIHRpcG8gZGUgZGF0byBxdWUgdGllbmUgQ09EX01VTiwgcXVlIGVzIGVsIGNvZGlnbyBkZWwgbXVuaWNpcGlvLCBkb25kZSBpbmljaWFsbWVudGUgZXJhIGRlIHRpcG8gbnVtZXJpY28sIHBlcm8gY29uIGxhIGZ1bmNpb24gcXVlIHNlIGVqZWN1dGFyYSBhIGNvbnRpbnVhY2lvbiBwYXNhcmEgYSBzZXIgZGUgdGlwbyBjYXJhY3Rlci4gRXN0byBjb24gZWwgb2JqZXRpdm8gZGUgcG9kZXIgcmVhbGl6YXIgY29ycmVjdGFtZGVudGUgZWwgam9pbiBvIGxhIHVuaW9uIGRlIGRhdG9zLiANCmBgYHtyfQ0KcGxhdGFubzIwMTgkVEVNUCA8LSAgYXMuY2hhcmFjdGVyKHBsYXRhbm8yMDE4JENPRF9NVU4pDQpgYGANCkVuIGVzdGUgY2FzbyBubyBlcyBuZWNlc2FyaW8gYW5hZGlybGUgZWwgY2VybyBhbCBjb2RpZ28gZGUgbG9zIG11bmljaXBpb3MuIA0KYGBge3J9DQpwbGF0YW5vMjAxOCRNUElPX0NDREdPIDwtIGFzLmZhY3RvcihwYXN0ZShwbGF0YW5vMjAxOCRURU1QLCBzZXA9IiIpKQ0KYGBgDQpTZSBoYWNlIHVzbyBkZSBsYSBmdW5jaW9uIGxlZnRfam9pbigpIHBhcmEgcG9kZXIgcmVhbGl6YXIgZWwgam9pbiBvIHVuaW9uIGRlIGxvcyBkYXRvcy4gDQpgYGB7cn0NCnBsYXRhbm9fbXVuaWMgPSBsZWZ0X2pvaW4obXVuaWMsIHBsYXRhbm8yMDE4LCBieT0iTVBJT19DQ0RHTyIpDQpgYGANCkVzdGEgZnVuY2lvbiBwYXJhIHZlciBsb3MgZGF0b3MgcXVlIGFsbGkgc2UgZW5jdWVudHJhbi4gDQpgYGB7cn0NCmhlYWQocGxhdGFub19tdW5pYykNCmBgYA0KU2UgcmVwcm95ZWN0YXJhbiBsb3MgbXVuaWNpcGlvczogDQpgYGB7cn0NCnJlcF9wbGF0YW5vIDwtIHN0X3RyYW5zZm9ybShwbGF0YW5vX211bmljLCBjcnMgPSAzMTE2KQ0KYGBgDQpFcyBuZWNlc2FyaW8gaW5zdGFsYXIgZWwgcGFxdWV0ZSBsd2dlb20uDQpgYGB7cn0NCmxpYnJhcnkobHdnZW9tKQ0KYGBgDQpNYXBlbw0KYGBge3J9DQpvcGFyIDwtIHBhcihtYXIgPSBjKDAsMCwxLjIsMCkpDQpwbG90KHN0X2dlb21ldHJ5KHJlcF9wbGF0YW5vKSwgY29sID0gTkEsIGJvcmRlciA9ICJibGFjayIsIGJnID0gIndoaXRlIikNCnNtb290aExheWVyKA0KICB4ID0gcmVwX3BsYXRhbm8sIA0KICB2YXIgPSAnUHJvZHVjY2lvbicsDQogIHR5cGVmY3QgPSAiZXhwb25lbnRpYWwiLA0KICBzcGFuID0gMjUwMDAsDQogIGJldGEgPSAxLA0KICBuY2xhc3MgPSA2LA0KICBjb2wgPSBjYXJ0by5wYWwocGFsMSA9ICd0dXJxdW9pc2UucGFsJywgbjEgPSA2KSwNCiAgYm9yZGVyID0gImdyZXkiLA0KICBsd2QgPSAwLjEsIA0KICBtYXNrID0gcmVwX3BsYXRhbm8sIA0KICBsZWdlbmQudmFsdWVzLnJuZCA9IC0zLA0KICBsZWdlbmQudGl0bGUudHh0ID0gIlByb2R1Y2Npb24iLA0KICBsZWdlbmQucG9zID0gInRvcHJpZ2h0IiwgDQogIGFkZD1UUlVFDQopDQp0ZXh0KHggPSAyLCB5ID0gMzIwMDAsIGNleCA9IDAuNiwgYWRqID0gMCwgZm9udCA9IDMsICBsYWJlbHMgPSANCiAgICAgICAiRGlzdGFuY2UgZnVuY3Rpb246XG4tIHR5cGUgPSBleHBvbmVudGlhbFxuLSBiZXRhID0gMlxuLSBzcGFuID0gMjAga20iKQ0KbGF5b3V0TGF5ZXIodGl0bGUgPSAiRGlzdHJpYnVjaW9uIGRlIGxhIHByb2R1Y2Npb24gZGUgcGxhdGFubyBlbiBDYXF1ZXRhIiwNCiAgICAgICAgICAgIHNvdXJjZXMgPSAiRnVlbnRlczogREFORSB5IE1BRFIsIDIwMTgiLA0KICAgICAgICAgICAgYXV0aG9yID0gIlNhbmRyYSBLYXR0ZXJ5bmUgUm9kcmlndWV6IEh1cnRhZG8iLA0KICAgICAgICAgICAgZnJhbWUgPSBGQUxTRSwgbm9ydGggPSBGQUxTRSwgdGFidGl0bGUgPSBUUlVFLCB0aGVtZSA9ICJibGFjay5wYWwiKQ0Kbm9ydGgocG9zID0gInRvcGxlZnQiKQ0KYGBgDQpFc3RlIG1hcGEgdGllbmUgdW5hIHBhbGV0YSBkZSBjb2xvciB0dXJxdWVzYS5TZSBwdWVkZSBhcHJlY2lhciBsYSBwcm9kdWNjaW9uIGRlIHBsYXRhbm8gZW4gZWwgZGVwYXJ0YW1lbnRvIGRlIENhcXVldGEgZW4gdG9uZWxhZGFzLCBkb25kZSBsb3MgbXVuaWNpcGlvcyBkb25kZSBzZSBjb25jZW50cmEgbGEgbWF5b3IgcHJvZHVjY2lvbiBzZSB2ZW4gZGUgY29sb3IgdHVycXVlc2Egb3NjdXJvLCBhIGRpZmVyZW5jaWEgZGUgbG9zIG11bmljaXBpb3MgZGUgbWVub3IgcHJvZHVjY2lvbiwgY29uIGNvbG9yIHR1cnF1ZXNhIGNsYXJvLiANCiMjIyMgR3VhcmRhciBsb3MgbWFwYXMgDQpBIGNvbnRpbnVhY2lvbiBzZSBnZW5lcmFyYSB1biBtYXBhIGRlIGNsb3JvcGxldGFzIGNvbiBzaW1ib2xvcyBwcm9wb3JjaW9uYWxlcyB5IGV0aXF1ZXRhcywgcXVlIHJlcHJlc2VudGFyYSBsYSBwcm9kdWNjaW9uIGRlIFl1Y2EgZW4gMjAxOC4gRXN0ZSBzZXJhIGd1YXJkYWRvIGVuIGVsIGRpcmVjdG9yaW8gZGVzZWFkbyBjb24gZm9ybWF0byAucG5nLg0KYGBge3J9DQpwbmcoIkM6L1VzZXJzL0p1YW4vRGVza3RvcC9wbGF0YW5vXzIwMTgucG5nIiwgd2lkdGggPSAxMDI0LCBoZWlnaHQgPSA3NjMpDQoNCm9wYXIgPC0gcGFyKG1hciA9IGMoMiwyLDUsNSkpDQoNCnBsb3Qoc3RfZ2VvbWV0cnkocmVwX3BsYXRhbm8pLCBjb2w9ImRhcmtzZWFncmVlbiIsIGJvcmRlcj0iZGFya3NlYWdyZWVuNCIsICANCiAgICAgYmcgPSAid2hpdGUiLCBsd2QgPSAwLjYpDQoNCnByb3BTeW1ib2xzQ2hvcm9MYXllcih4ID0gcmVwX3BsYXRhbm8sIHZhciA9ICJQcm9kdWNjaW9uIiwgdmFyMiA9ICJSZW5kaW1pZW50byIsDQogICAgICAgICAgICAgICAgICAgICAgY29sID0gY2FydG8ucGFsKHBhbDEgPSAidHVycXVvaXNlLnBhbCIsIG4xID0gMywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFsMiA9ICJwaW5rLnBhbCIsIG4yID0gMyksDQogICAgICAgICAgICAgICAgICAgICAgaW5jaGVzID0gMC41LCBtZXRob2QgPSAicTYiLA0KICAgICAgICAgICAgICAgICAgICAgIGJvcmRlciA9ICJibGFjayIsIGx3ZCA9IDEsDQogICAgICAgICAgICAgICAgICAgICAgbGVnZW5kLnRpdGxlLmNleCA9IDEuMywNCiAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQudmFsdWVzLmNleCA9IDEuMywNCiAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQudmFyLnBvcyA9ICJ0b3ByaWdodCIsIA0KICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZC52YXIyLnBvcyA9ICJ0b3BsZWZ0IiwNCiAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQudmFyMi52YWx1ZXMucm5kID0gMiwNCiAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQudmFyMi50aXRsZS50eHQgPSAiUmVuZGltaWVudG9cbihpbiBUb24vSGEpIiwNCiAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQudmFyLnRpdGxlLnR4dCA9ICJQcm9kdWNjaW9uIGRlIFBsYXRhbm8sIDIwMTgiLA0KICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZC52YXIuc3R5bGUgPSAiZSIpDQoNCmxhYmVsTGF5ZXIoDQogIHggPSByZXBfcGxhdGFubywgDQogIHR4dCA9ICJNUElPX0NOTUJSIiwgDQogIGNvbD0gImJsYWNrIiwgDQogIGNleCA9IDEsIA0KICBmb250ID0gMTgsDQogIGhhbG8gPSBGQUxTRSwgDQogIGJnID0gIndoaXRlIiwgDQogIHIgPSAwLjEsIA0KICBvdmVybGFwID0gRkFMU0UsIA0KICBzaG93LmxpbmVzID0gRkFMU0UNCikNCg0KbGF5b3V0TGF5ZXIodGl0bGU9IlByb2R1Y2Npb24geSByZW5kaW1pZW50byBkZSBQbGF0YW5vIGVuIENhcXVldGEsIDIwMTgiLA0KICAgICAgICAgICAgYXV0aG9yID0gIlNhbmRyYSBLYXR0ZXJ5bmUgUm9kcmlndWV6IEh1cnRhZG8iLCANCiAgICAgICAgICAgIHNvdXJjZXMgPSAiRnVlbnRlczogTUFEUiAmIERBTkUsIDIwMTgiLCANCiAgICAgICAgICAgIHNjYWxlID0gNTAsIHRhYnRpdGxlID0gRkFMU0UsIGZyYW1lID0gVFJVRSkNCg0Kbm9ydGgocG9zID0gInRvcCIpDQoNCnRpdGxlKG1haW49IlByb2R1Y2Npb24geSByZW5kaW1pZW50byBkZSBQbGF0YW5vIGVuIENhcXVldGEsIDIwMTgiLCBjZXgubWFpbj0zLA0KICAgICAgc3ViPSAiRnVlbnRlczogTUFEUiAmIERBTkUsIDIwMTgiLCBjZXguc3ViPTIpDQoNCmdyYXRpY3VsZSA9IFRSVUUNCg0KcGFyKG9wYXIpDQoNCmRldi5vZmYoKQ0KYGBgDQpMYSBzaWd1aWVudGUgaW1hZ2VuIGZ1ZSBlbCByZXN1bHRhZG8gZGVsIHByb2Nlc28gYW50ZXJpb3IsIHF1ZSByZXByZXNlbnRhIGxhIHByb2R1Y2Npb24gZGUgcGxhdGFubyBlbiBlbCBkcGFydGFtZW50byBkZSBDYXF1ZXRhIGVuIDIwMTg6DQohW1Byb2R1Y2Npb24geSByZW5kaW1pZW50byBkZSBwbGF0YW5vIGVuIENhcXVldGEsIDIwMThdKEM6L1VzZXJzL0p1YW4vRGVza3RvcC9wbGF0YW5vXzIwMTgucG5nKQ0KDQoNClNlIHB1ZWRlIGFwcmVjaWFyIHF1ZSBsb3MgbXVuaWNpcGlvcyBkZSBtYXlvciBwcm9kdWNjaW9uIGRlIHBsYXRhbm8gc29uIE1pbGFuLCBTYW4gVmljZW50ZSBkZWwgQ2FndWFuIHkgQ2FydGFnZW5hIGRlIENoYWlyYS4gDQojIyMjIEN1bHRpdm8gZGUgeXVjYQ0KU2UgcmVwcmVzZW50YXJhIGdyYWZpY2FtZW50ZSBsYSBwcm9kdWNjaW9uIGRlbCBjdWx0aXZvIGRlIHl1Y2EgZW4gbG9zIG11bmljaXBpb3MgZGUgZGVwYXJ0YW1lbnRvIGRlIENhcXVldGEgcGFyYSBlbCBhbm8gMjAxOCwgZXN0byBjb24gbG9zIHBhc29zIHJlYWxpemFkb3MgYW50ZXJpb3JtZW50ZSBwYXJhIGxhIHJlcHJlc2VudGFjaW9uIGRlbCBjdWx0aXZvIGRlbCBwbGF0YW5vLiBQcmltZXJvIGVzY29nZXIgZWwgY3VsdGl2byBxdWUgc2UgcmVwcmVzZW50YXJhLg0KYGBge3J9DQpjdWx0aXZvczIwMTggJT4lDQogIGZpbHRlcihDVUxUSVZPID09ICJZVUNBIikgLT4geXVjYTIwMTgNCg0KYGBgDQpgYGB7cn0NCnl1Y2EyMDE4JFRFTVAgPC0gIGFzLmNoYXJhY3Rlcih5dWNhMjAxOCRDT0RfTVVOKQ0KYGBgDQpgYGB7cn0NCnl1Y2EyMDE4JE1QSU9fQ0NER08gPC0gYXMuZmFjdG9yKHBhc3RlKHl1Y2EyMDE4JFRFTVAsIHNlcD0iIikpDQpgYGANCkhhY2VyIGVsIGpvaW4uDQpgYGB7cn0NCnl1Y2FfbXVuaWMgPSBsZWZ0X2pvaW4obXVuaWMsIHl1Y2EyMDE4LCBieT0iTVBJT19DQ0RHTyIpDQpgYGANCmBgYHtyfQ0KaGVhZCh5dWNhX211bmljKQ0KYGBgDQpDb29yZGVuYWRhcyBwbGFuYXMuDQpgYGB7cn0NCnJlcF95dWNhIDwtIHN0X3RyYW5zZm9ybSh5dWNhX211bmljLCBjcnMgPSAzMTE2KQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShsd2dlb20pDQpgYGANClJlcHJlc2VudGFjaW9uIGRlIGxhIHByb2R1Y2Npb24gZGUgeXVjYSBlbiBDYXF1ZXRhIGVuIDIwMTgsIGRpc3RyaWJ1aWRhIGVuIGVsIGVzcGFjaW8gY29uIGNvbG9yIGRlIHBhbGV0YSB2aW5vdGludG8uIA0KYGBge3J9DQpvcGFyIDwtIHBhcihtYXIgPSBjKDAsMCwxLjIsMCkpDQpwbG90KHN0X2dlb21ldHJ5KHJlcF95dWNhKSwgY29sID0gTkEsIGJvcmRlciA9ICJibGFjayIsIGJnID0gIndoaXRlIikNCnNtb290aExheWVyKA0KICB4ID0gcmVwX3l1Y2EsIA0KICB2YXIgPSAnUHJvZHVjY2lvbicsDQogIHR5cGVmY3QgPSAiZXhwb25lbnRpYWwiLA0KICBzcGFuID0gMzEwMDAsDQogIGJldGEgPSAxLA0KICBuY2xhc3MgPSA1LA0KICBjb2wgPSBjYXJ0by5wYWwocGFsMSA9ICd3aW5lLnBhbCcsIG4xID0gNSksDQogIGJvcmRlciA9ICJncmV5IiwNCiAgbHdkID0gMC4xLCANCiAgbWFzayA9IHJlcF95dWNhLCANCiAgbGVnZW5kLnZhbHVlcy5ybmQgPSAtMywNCiAgbGVnZW5kLnRpdGxlLnR4dCA9ICJQcm9kdWNjaW9uIiwNCiAgbGVnZW5kLnBvcyA9ICJ0b3ByaWdodCIsIA0KICBhZGQ9VFJVRQ0KKQ0KdGV4dCh4ID0gMiwgeSA9IDMyMDAwLCBjZXggPSAwLjYsIGFkaiA9IDAsIGZvbnQgPSAzLCAgbGFiZWxzID0gDQogICAgICAgIkRpc3RhbmNlIGZ1bmN0aW9uOlxuLSB0eXBlID0gZXhwb25lbnRpYWxcbi0gYmV0YSA9IDJcbi0gc3BhbiA9IDIwIGttIikNCmxheW91dExheWVyKHRpdGxlID0gIkRpc3RyaWJ1Y2lvbiBkZSBsYSBwcm9kdWNjaW9uIGRlIHl1Y2EgZW4gQ2FxdWV0YSIsDQogICAgICAgICAgICBzb3VyY2VzID0gIkZ1ZW50ZXM6IERBTkUgeSBNQURSLCAyMDE4IiwNCiAgICAgICAgICAgIGF1dGhvciA9ICJTYW5kcmEgS2F0dGVyeW5lIFJvZHJpZ3VleiBIdXJ0YWRvIiwNCiAgICAgICAgICAgIGZyYW1lID0gRkFMU0UsIG5vcnRoID0gRkFMU0UsIHRhYnRpdGxlID0gVFJVRSwgdGhlbWUgPSAiYmxhY2sucGFsIikNCm5vcnRoKHBvcyA9ICJ0b3BsZWZ0IikNCmBgYA0KR2VnZXJhciB5IGRlc2NhcmdhciBlbiBlbCBlcXVpcG8gbGEgaW1hZ2VuIGRlIHVuIG1hcGEgZGUgY2xvcm9wbGV0YXMgY29uIHNpbWJvbG9zIHkgZXRpcXVldGFzLCBkZSBsYSBwcm9kdWNjaW9uIGRlIHl1Y2EgZW4gQ2FxdWV0YSBwYXJhIGVsIGFubyAyMDE4Lg0KYGBge3J9DQpwbmcoIkM6L1VzZXJzL0p1YW4vRGVza3RvcC95dWNhXzIwMTgucG5nIiwgd2lkdGggPSAxMDI0LCBoZWlnaHQgPSA3NjMpDQoNCm9wYXIgPC0gcGFyKG1hciA9IGMoMiwyLDUsNSkpDQoNCnBsb3Qoc3RfZ2VvbWV0cnkocmVwX3l1Y2EpLCBjb2w9ImRhcmtzZWFncmVlbiIsIGJvcmRlcj0iZGFya3NlYWdyZWVuNCIsICANCiAgICAgYmcgPSAid2hpdGUiLCBsd2QgPSAwLjYpDQoNCnByb3BTeW1ib2xzQ2hvcm9MYXllcih4ID0gcmVwX3l1Y2EsIHZhciA9ICJQcm9kdWNjaW9uIiwgdmFyMiA9ICJSZW5kaW1pZW50byIsDQogICAgICAgICAgICAgICAgICAgICAgY29sID0gY2FydG8ucGFsKHBhbDEgPSAib3JhbmdlLnBhbCIsIG4xID0gMywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFsMiA9ICJ3aW5lLnBhbCIsIG4yID0gMyksDQogICAgICAgICAgICAgICAgICAgICAgaW5jaGVzID0gMC41LCBtZXRob2QgPSAicTYiLA0KICAgICAgICAgICAgICAgICAgICAgIGJvcmRlciA9ICJibGFjayIsIGx3ZCA9IDEsDQogICAgICAgICAgICAgICAgICAgICAgbGVnZW5kLnRpdGxlLmNleCA9IDEuMywNCiAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQudmFsdWVzLmNleCA9IDEuMywNCiAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQudmFyLnBvcyA9ICJ0b3ByaWdodCIsIA0KICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZC52YXIyLnBvcyA9ICJ0b3BsZWZ0IiwNCiAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQudmFyMi52YWx1ZXMucm5kID0gMiwNCiAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQudmFyMi50aXRsZS50eHQgPSAiUmVuZGltaWVudG9cbihpbiBUb24vSGEpIiwNCiAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQudmFyLnRpdGxlLnR4dCA9ICJQcm9kdWNjaW9uIGRlIHl1Y2EsIDIwMTgiLA0KICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZC52YXIuc3R5bGUgPSAiZSIpDQoNCmxhYmVsTGF5ZXIoDQogIHggPSByZXBfcGxhdGFubywgDQogIHR4dCA9ICJNUElPX0NOTUJSIiwgDQogIGNvbD0gImJsYWNrIiwgDQogIGNleCA9IDEsIA0KICBmb250ID0gMTgsDQogIGhhbG8gPSBGQUxTRSwgDQogIGJnID0gIndoaXRlIiwgDQogIHIgPSAwLjEsIA0KICBvdmVybGFwID0gRkFMU0UsIA0KICBzaG93LmxpbmVzID0gRkFMU0UNCikNCg0KbGF5b3V0TGF5ZXIodGl0bGU9IlByb2R1Y2Npb24geSByZW5kaW1pZW50byBkZSB5dWNhIGVuIENhcXVldGEsIDIwMTgiLA0KICAgICAgICAgICAgYXV0aG9yID0gIlNhbmRyYSBLYXR0ZXJ5bmUgUm9kcmlndWV6IEh1cnRhZG8iLCANCiAgICAgICAgICAgIHNvdXJjZXMgPSAiRnVlbnRlczogTUFEUiAmIERBTkUsIDIwMTgiLCANCiAgICAgICAgICAgIHNjYWxlID0gNTAsIHRhYnRpdGxlID0gRkFMU0UsIGZyYW1lID0gVFJVRSkNCg0Kbm9ydGgocG9zID0gInRvcCIpDQoNCnRpdGxlKG1haW49IlByb2R1Y2Npb24geSByZW5kaW1pZW50byBkZSB5dWNhIGVuIENhcXVldGEsIDIwMTgiLCBjZXgubWFpbj0zLA0KICAgICAgc3ViPSAiRnVlbnRlczogTUFEUiAmIERBTkUsIDIwMTgiLCBjZXguc3ViPTIpDQoNCmdyYXRpY3VsZSA9IFRSVUUNCg0KcGFyKG9wYXIpDQoNCmRldi5vZmYoKQ0KYGBgDQpJbWFnZW4gZGVzY2FyZ2FkYSBkZSBsYSBwcm9kaWNjaW9uIHkgcmVuZGltaWVudG8gZGUgeXVjYSwgMjAxOC4NCmBgYHtyfQ0Ke29wYXIgID0iMTAwJSJ9DQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGtuaXRyKQ0KaW5jbHVkZV9ncmFwaGljcygiQzovVXNlcnMvSnVhbi9EZXNrdG9wL3l1Y2FfMjAxOC5wbmciKQ0KYGBgDQpTZSBwdWVkZSB2ZXIgcXVlIGxvcyBtdW5pY2lwaW9zIGRlIG1heW9yIHByb2R1Y2Npb24gZGUgeXVjYSBlbiB0b25lbGFkYXMgc29uIENhcnRhZ2VuYSBkZSBDaGFpcmEgeSBTYW4gVmljZW50ZSBkZSBDYWd1YW4uIA0KDQojIyMjIyBJbmZvcm1hY2lvbiBkZWwgdHJhYmFqbw0KYGBge3J9DQpzZXNzaW9uSW5mbygpDQpgYGANCiMjIyMjIFJFRkVSRU5DSUFTDQpCcmluZXksIEEuICgxMSBkZSBKdWxpbyBkZSAyMDE5KS4gVXNlcyBvZiBUaGVtYXRpYyBNYXBzIGluIEdlb2dyYXBoeS4gUmVjdXBlcmFkbyBlbCBNYXlvIGRlIDIwMjAsIGRlIGh0dHBzOi8vd3d3LnRob3VnaHRjby5jb20vdGhlbWF0aWMtbWFwcy1vdmVydmlldy0xNDM1NjkyDQoNCkdpdEh1Yi4gKHMuZi4pLiBDYXJ0b2dyYXBoeS4gUmVjdXBlcmFkbyBlbCBNYXlvIGRlIDIwMjAsIGRlIGh0dHBzOi8vZ2l0aHViLmNvbS9yaWF0ZWxhYi9jYXJ0b2dyYXBoeS8NCg0KR29iZXJuYWNpb24gZGVsIENhcXVldGEuIChzLmYuKS4gSGlzdG9yaWEgZGUgQ2FxdWV0YS4gUmVjdXBlcmFkbyBlbCBNYXlvIGRlIDIwMjAsIGRlIGh0dHA6Ly93d3cuY2FxdWV0YS5nb3YuY28vZGVwYXJ0YW1lbnRvL2hpc3RvcmlhLWRlbC1jYXF1ZXRhDQoNClBhZGdoYW0sIE0uLCAmIExvdmVsYWNlLCBSLiAoMiBkZSBGZWJyZXJvIGRlIDIwMjApLiBPRE0gREFUQS4gUmVjdXBlcmFkbyBlbCBNYXlvIGRlIDIwMjAsIGRlIGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9vc21kYXRhL3ZpZ25ldHRlcy9vc21kYXRhLmh0bWwjNV9hZGRpdGlvbmFsX2Z1bmN0aW9uYWxpdHkNCg0K