INSTALAMOS LOS PAQUETES NECEASARIOS

install.packages("rgdal")
install.packages("raster")
install.packages("elevatr")
install.packages("rasterVis")
install.packages("rgl")

LLAMAMOS LIBRERIAS

library(rasterVis)
library(raster)
library(rgl)
library(rgdal)
library(elevatr)

REVISAMOS EL CONTENIO DE LA CARPETA

list.files("C:/Users/sebas/OneDrive/Documentos/R/R ARTURO/ARAUCA/81_ARAUCA/ADMINISTRATIVO")
 [1] "MGN_DPTO_POLITICO.cpg"     "MGN_DPTO_POLITICO.dbf"    
 [3] "MGN_DPTO_POLITICO.prj"     "MGN_DPTO_POLITICO.sbn"    
 [5] "MGN_DPTO_POLITICO.sbx"     "MGN_DPTO_POLITICO.shp"    
 [7] "MGN_DPTO_POLITICO.shp.xml" "MGN_DPTO_POLITICO.shx"    
 [9] "MGN_MPIO_POLITICO.cpg"     "MGN_MPIO_POLITICO.dbf"    
[11] "MGN_MPIO_POLITICO.prj"     "MGN_MPIO_POLITICO.sbn"    
[13] "MGN_MPIO_POLITICO.sbx"     "MGN_MPIO_POLITICO.shp"    
[15] "MGN_MPIO_POLITICO.shp.xml" "MGN_MPIO_POLITICO.shx"    

LEEMOS EL ARCHIVO DE FORMA PARA EL RASTER

(munic <- shapefile("C:/Users/sebas/OneDrive/Documentos/R/R ARTURO/ARAUCA/81_ARAUCA/ADMINISTRATIVO/MGN_MPIO_POLITICO.shp"))
class       : SpatialPolygonsDataFrame 
features    : 7 
extent      : -72.36662, -69.42756, 6.036228, 7.104381  (xmin, xmax, ymin, ymax)
crs         : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0 
variables   : 9
names       : DPTO_CCDGO, MPIO_CCDGO, MPIO_CNMBR,                           MPIO_CRSLC,    MPIO_NAREA, MPIO_NANO, DPTO_CNMBR,    Shape_Leng,      Shape_Area 
min values  :         81,      81001,     ARAUCA,                                 1959,  945.13540708,      2017,     ARAUCA, 1.29412603421, 0.0772141267598 
max values  :         81,      81794,       TAME, Decreto Nal 677 de Abril 13 de  1987, 5787.94213047,      2017,     ARAUCA, 4.66801606458,  0.471626116664 

LE PEDIMOS LOS ATRIBUTOS DEL MUNICIPIO

head(munic)

SELECCIONAMOS EL MUNICIPIO DE INTERES

Saravena <- munic[munic$MPIO_CNMBR=="SARAVENA",]
plot(Saravena, main="SARAVENA", axes=TRUE)
plot(munic, add=TRUE)
invisible(text(coordinates(munic), labels=as.character(munic$MPIO_CNMBR), cex=0.8))

elevation <- get_elev_raster(Saravena, z = 9)

VERIFIQUEMOS QUE HAY DENTRO DEL OBJETO

elevation
class      : RasterLayer 
dimensions : 1550, 1550, 2402500  (nrow, ncol, ncell)
resolution : 0.00137, 0.00136  (x, y)
extent     : -72.42872, -70.30522, 5.609792, 7.717792  (xmin, xmax, ymin, ymax)
crs        : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0 
source     : memory
names      : layer 
values     : -369.7594, 5313.876  (min, max)

GRAFICAMOS LA ELEVACION DEL DEPARTAMENTO

plot(elevation, main="DEM DESCARGADO (METROS)")
plot(Saravena, add=TRUE)

RECORTAR AHORA LOS DATOS CORRESPONDIENTES A SARAVENA

elev_crop = crop(elevation, Saravena)
plot(elev_crop, main="DEM RECORTADO")
plot(Saravena, add=TRUE)

VERIFIQUEMOS QUE TIENE EL NUEVO OBJETO

elev_crop
class      : RasterLayer 
dimensions : 235, 314, 73790  (nrow, ncol, ncell)
resolution : 0.00137, 0.00136  (x, y)
extent     : -72.09992, -71.66974, 6.746752, 7.066352  (xmin, xmax, ymin, ymax)
crs        : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0 
source     : memory
names      : layer 
values     : 159.8875, 2746.603  (min, max)

QUEREMOS QUE AHORA REPROYECTAR EL MUNICIPIO TENIENDO EN CUENTA OTRO SISTEMA DE CORDENADAS QUE TOMA COMO REFERENCIA BOGOTA

spatialref <- "+proj=tmerc +lat_0=4.596200416666666 +lon_0=-74.07750791666666 +k=1 +x_0=1000000 +y_0=1000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs" 
pr3 <- projectExtent(elev_crop, spatialref)
res(pr3) <- 100
rep_elev <- projectRaster(elev_crop, pr3)

LO QUE HAY ALLI

rep_elev
class      : RasterLayer 
dimensions : 356, 477, 169812  (nrow, ncol, ncell)
resolution : 100, 100  (x, y)
extent     : 1218525, 1266225, 1238252, 1273852  (xmin, xmax, ymin, ymax)
crs        : +proj=tmerc +lat_0=4.596200416666666 +lon_0=-74.07750791666666 +k=1 +x_0=1000000 +y_0=1000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 
source     : memory
names      : layer 
values     : 165.2396, 2766.869  (min, max)

REPROYECCION DEL MUNICIPIO

(rep_Saravena = spTransform(Saravena,spatialref))
class       : SpatialPolygonsDataFrame 
features    : 1 
extent      : 1218645, 1266131, 1238210, 1273788  (xmin, xmax, ymin, ymax)
crs         : +proj=tmerc +lat_0=4.596200416666666 +lon_0=-74.07750791666666 +k=1 +x_0=1000000 +y_0=1000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 
variables   : 9
names       : DPTO_CCDGO, MPIO_CCDGO, MPIO_CNMBR,                       MPIO_CRSLC,   MPIO_NAREA, MPIO_NANO, DPTO_CNMBR,    Shape_Leng,      Shape_Area 
value       :         81,      81736,   SARAVENA, Decreto Nal 204 de Feb 3 de 1976, 945.13540708,      2017,     ARAUCA, 1.29412603421, 0.0772141267598 
plot(rep_elev, main="DEM REPROYECTADO")
plot(rep_Saravena, add=TRUE)

GUARDAMOS EL DEM

writeRaster(rep_elev, filename="C:/Users/sebas/OneDrive/Documentos/R/R ARTURO/ARAUCA/rep_Saravena_elev.tif", datatype='INT4S', overwrite=TRUE)

SACAMOS LAS ESTADISTICAS DEL DEM

hist(rep_elev)

promedio <- cellStats(rep_elev, 'mean')
minimo <- cellStats(rep_elev, 'min')
maximo <- cellStats(rep_elev, 'max')
desviacion  <- cellStats(rep_elev, 'sd')

CREAMOS UN VECTOR UNIDIMENCIONAL

metricas <- c('mean', 'min', 'max', 'std')
valores <- c(promedio, minimo, maximo, desviacion)
(df_estadisticas <- data.frame(metricas, valores))

OBTENCION DE VARIABLES GEOMORFOMETRICAS: Pemdiente, Aspecto y sombreado.

slope = terrain(rep_elev,opt='slope', unit='degrees')
aspect = terrain(rep_elev,opt='aspect',unit='degrees')
hill = hillShade(slope,aspect,40,315)

GRAFICA ELEVACION

plot(rep_elev,main="DEM PARA SARAVENA (METROS)", col=terrain.colors(25,alpha=0.7))

GRAFICAMOS LA PENDIENTE

plot(slope,main="PENDIENTE PARA SARAVENA (GRADOS)", col=topo.colors(25,alpha=0.7))

GRAFICAMOS ASPECTO

plot(aspect,main="ASPECTO PARA SARAVENA (GRADOS)", col=rainbow(25,alpha=0.7))

PALETA COMBINADA

plot(hill,
        col=grey(1:100/100), 
        legend=FALSE,         
        main="DEM PARA SARAVENA",
        axes=FALSE)         
plot(rep_elev, 
        axes=FALSE,
        col=terrain.colors(12, alpha=0.35), add=TRUE)

MAPAS DE DATOS DE ELEVACION CON SOMBREADO DE RAYOS

install.packages("rayshader")
library(rayshader)

COMVERTIR EL DEM EN UNA MATRIZ

elmat = raster_to_matrix(rep_elev)
[1] "Dimensions of matrix are: 477x356."
elmat %>%
  sphere_shade(texture = "imhof2") %>%
  plot_map()

AGREGAR CAPA DE AGUAL

elmat %>%
  sphere_shade(texture = "desert") %>%
  add_water(detect_water(elmat), color = "desert") %>%
  plot_map()

TRAZADO DE RAYOS DESDE LA DIRECCION DEL SOL

elmat %>%
  sphere_shade(texture = "desert") %>%
  add_water(detect_water(elmat), color = "desert") %>%
  add_shadow(ray_shade(elmat), 0.5) %>%
  plot_map()

OTRA FORMA DE VISUALIZACION

install.packages("jpeg")
library(jpeg)

Función de sombreado de mapeo de entorno esférico

getv=function(i,a,s){
  ct = dim(i)[1:2]/2
  sx = values(s)/90 * ct[1]
  sy = values(s)/90 * ct[2]
  a = values(a) * 0.01745
  px = floor(ct[1] + sx * -sin(a))
  py = floor(ct[2] + sy * cos(a))
  
  
  template = brick(s,s,s)
  values(template)=NA
   
  cellr = px + py * ct[1]*2
  cellg = px + py * ct[1]*2 + (ct[1]*2*ct[2]*2)
  cellb = px + py * ct[1]*2 + 2*(ct[1]*2*ct[2]*2)
  
  template[[1]] = i[cellr]
  template[[2]] = i[cellg]
  template[[3]] = i[cellb]
  
  template = template * 256
  
  template
}
map = readJPEG("C:/Users/sebas/OneDrive/Documentos/R/R ARTURO/ARAUCA/9pvbHjN.jpg")
out = getv(map, aspect, slope)
ning昼㹡n argumento finito para min; retornando Infningun argumento finito para max; retornando -Infning昼㹡n argumento finito para min; retornando Infningun argumento finito para max; retornando -Infning昼㹡n argumento finito para min; retornando Infningun argumento finito para max; retornando -Infning昼㹡n argumento finito para min; retornando Infningun argumento finito para max; retornando -Infning昼㹡n argumento finito para min; retornando Infningun argumento finito para max; retornando -Infning昼㹡n argumento finito para min; retornando Infningun argumento finito para max; retornando -Inf
plotRGB(out, main = "ELEVACION EN SARAVENA")

LS0tDQp0aXRsZTogIkVMRVZBQ0lPTiBTQVJBVkVOQSINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQpJTlNUQUxBTU9TIExPUyBQQVFVRVRFUyBORUNFQVNBUklPUw0KYGBge3J9DQppbnN0YWxsLnBhY2thZ2VzKCJyZ2RhbCIpDQpgYGANCmBgYHtyfQ0KaW5zdGFsbC5wYWNrYWdlcygicmFzdGVyIikNCg0KYGBgDQpgYGB7cn0NCmluc3RhbGwucGFja2FnZXMoImVsZXZhdHIiKQ0KDQpgYGANCmBgYHtyfQ0KaW5zdGFsbC5wYWNrYWdlcygicmFzdGVyVmlzIikNCmBgYA0KYGBge3J9DQppbnN0YWxsLnBhY2thZ2VzKCJyZ2wiKQ0KYGBgDQpMTEFNQU1PUyBMSUJSRVJJQVMgDQpgYGB7cn0NCmxpYnJhcnkocmFzdGVyVmlzKQ0KYGBgDQpgYGB7cn0NCmxpYnJhcnkocmFzdGVyKQ0KbGlicmFyeShyZ2wpDQpsaWJyYXJ5KHJnZGFsKQ0KYGBgDQpgYGB7cn0NCmxpYnJhcnkoZWxldmF0cikNCmBgYA0KUkVWSVNBTU9TIEVMIENPTlRFTklPIERFIExBIENBUlBFVEENCmBgYHtyfQ0KbGlzdC5maWxlcygiQzovVXNlcnMvc2ViYXMvT25lRHJpdmUvRG9jdW1lbnRvcy9SL1IgQVJUVVJPL0FSQVVDQS84MV9BUkFVQ0EvQURNSU5JU1RSQVRJVk8iKQ0KYGBgDQpMRUVNT1MgRUwgQVJDSElWTyBERSBGT1JNQSBQQVJBIEVMIFJBU1RFUg0KYGBge3J9DQoobXVuaWMgPC0gc2hhcGVmaWxlKCJDOi9Vc2Vycy9zZWJhcy9PbmVEcml2ZS9Eb2N1bWVudG9zL1IvUiBBUlRVUk8vQVJBVUNBLzgxX0FSQVVDQS9BRE1JTklTVFJBVElWTy9NR05fTVBJT19QT0xJVElDTy5zaHAiKSkNCmBgYA0KTEUgUEVESU1PUyBMT1MgQVRSSUJVVE9TIERFTCBNVU5JQ0lQSU8NCmBgYHtyfQ0KaGVhZChtdW5pYykNCmBgYA0KU0VMRUNDSU9OQU1PUyBFTCBNVU5JQ0lQSU8gREUgSU5URVJFUw0KYGBge3J9DQpTYXJhdmVuYSA8LSBtdW5pY1ttdW5pYyRNUElPX0NOTUJSPT0iU0FSQVZFTkEiLF0NCnBsb3QoU2FyYXZlbmEsIG1haW49IlNBUkFWRU5BIiwgYXhlcz1UUlVFKQ0KcGxvdChtdW5pYywgYWRkPVRSVUUpDQppbnZpc2libGUodGV4dChjb29yZGluYXRlcyhtdW5pYyksIGxhYmVscz1hcy5jaGFyYWN0ZXIobXVuaWMkTVBJT19DTk1CUiksIGNleD0wLjgpKQ0KYGBgDQpgYGB7cn0NCmVsZXZhdGlvbiA8LSBnZXRfZWxldl9yYXN0ZXIoU2FyYXZlbmEsIHogPSA5KQ0KYGBgDQpWRVJJRklRVUVNT1MgUVVFIEhBWSBERU5UUk8gREVMIE9CSkVUTw0KYGBge3J9DQplbGV2YXRpb24NCmBgYA0KR1JBRklDQU1PUyBMQSBFTEVWQUNJT04gREVMIERFUEFSVEFNRU5UTw0KYGBge3J9DQpwbG90KGVsZXZhdGlvbiwgbWFpbj0iREVNIERFU0NBUkdBRE8gKE1FVFJPUykiKQ0KcGxvdChTYXJhdmVuYSwgYWRkPVRSVUUpDQpgYGANClJFQ09SVEFSIEFIT1JBIExPUyBEQVRPUyBDT1JSRVNQT05ESUVOVEVTIEEgU0FSQVZFTkENCmBgYHtyfQ0KZWxldl9jcm9wID0gY3JvcChlbGV2YXRpb24sIFNhcmF2ZW5hKQ0KcGxvdChlbGV2X2Nyb3AsIG1haW49IkRFTSBSRUNPUlRBRE8iKQ0KcGxvdChTYXJhdmVuYSwgYWRkPVRSVUUpDQpgYGANClZFUklGSVFVRU1PUyBRVUUgVElFTkUgRUwgTlVFVk8gT0JKRVRPDQpgYGB7cn0NCmVsZXZfY3JvcA0KYGBgDQpRVUVSRU1PUyBRVUUgQUhPUkEgUkVQUk9ZRUNUQVIgRUwgTVVOSUNJUElPIFRFTklFTkRPIEVOIENVRU5UQSBPVFJPIFNJU1RFTUEgREUgQ09SREVOQURBUyBRVUUgVE9NQSBDT01PIFJFRkVSRU5DSUEgQk9HT1RBDQpgYGB7cn0NCnNwYXRpYWxyZWYgPC0gIitwcm9qPXRtZXJjICtsYXRfMD00LjU5NjIwMDQxNjY2NjY2NiArbG9uXzA9LTc0LjA3NzUwNzkxNjY2NjY2ICtrPTEgK3hfMD0xMDAwMDAwICt5XzA9MTAwMDAwMCArZWxscHM9R1JTODAgK3Rvd2dzODQ9MCwwLDAsMCwwLDAsMCArdW5pdHM9bSArbm9fZGVmcyIgDQpgYGANCg0KYGBge3J9DQpwcjMgPC0gcHJvamVjdEV4dGVudChlbGV2X2Nyb3AsIHNwYXRpYWxyZWYpDQpyZXMocHIzKSA8LSAxMDANCnJlcF9lbGV2IDwtIHByb2plY3RSYXN0ZXIoZWxldl9jcm9wLCBwcjMpDQpgYGANCkxPIFFVRSBIQVkgQUxMSQ0KYGBge3J9DQpyZXBfZWxldg0KYGBgDQpSRVBST1lFQ0NJT04gREVMIE1VTklDSVBJTw0KYGBge3J9DQoocmVwX1NhcmF2ZW5hID0gc3BUcmFuc2Zvcm0oU2FyYXZlbmEsc3BhdGlhbHJlZikpDQpgYGANCg0KYGBge3J9DQpwbG90KHJlcF9lbGV2LCBtYWluPSJERU0gUkVQUk9ZRUNUQURPIikNCnBsb3QocmVwX1NhcmF2ZW5hLCBhZGQ9VFJVRSkNCmBgYA0KR1VBUkRBTU9TIEVMIERFTSANCmBgYHtyfQ0Kd3JpdGVSYXN0ZXIocmVwX2VsZXYsIGZpbGVuYW1lPSJDOi9Vc2Vycy9zZWJhcy9PbmVEcml2ZS9Eb2N1bWVudG9zL1IvUiBBUlRVUk8vQVJBVUNBL3JlcF9TYXJhdmVuYV9lbGV2LnRpZiIsIGRhdGF0eXBlPSdJTlQ0UycsIG92ZXJ3cml0ZT1UUlVFKQ0KYGBgDQpTQUNBTU9TIExBUyBFU1RBRElTVElDQVMgREVMIERFTQ0KYGBge3J9DQpoaXN0KHJlcF9lbGV2KQ0KYGBgDQoNCmBgYHtyfQ0KcHJvbWVkaW8gPC0gY2VsbFN0YXRzKHJlcF9lbGV2LCAnbWVhbicpDQptaW5pbW8gPC0gY2VsbFN0YXRzKHJlcF9lbGV2LCAnbWluJykNCm1heGltbyA8LSBjZWxsU3RhdHMocmVwX2VsZXYsICdtYXgnKQ0KZGVzdmlhY2lvbiAgPC0gY2VsbFN0YXRzKHJlcF9lbGV2LCAnc2QnKQ0KYGBgDQpDUkVBTU9TIFVOIFZFQ1RPUiBVTklESU1FTkNJT05BTA0KYGBge3J9DQptZXRyaWNhcyA8LSBjKCdtZWFuJywgJ21pbicsICdtYXgnLCAnc3RkJykNCnZhbG9yZXMgPC0gYyhwcm9tZWRpbywgbWluaW1vLCBtYXhpbW8sIGRlc3ZpYWNpb24pDQpgYGANCg0KYGBge3J9DQooZGZfZXN0YWRpc3RpY2FzIDwtIGRhdGEuZnJhbWUobWV0cmljYXMsIHZhbG9yZXMpKQ0KYGBgDQpPQlRFTkNJT04gREUgVkFSSUFCTEVTIEdFT01PUkZPTUVUUklDQVM6IFBlbWRpZW50ZSwgQXNwZWN0byB5IHNvbWJyZWFkby4NCmBgYHtyfQ0Kc2xvcGUgPSB0ZXJyYWluKHJlcF9lbGV2LG9wdD0nc2xvcGUnLCB1bml0PSdkZWdyZWVzJykNCmFzcGVjdCA9IHRlcnJhaW4ocmVwX2VsZXYsb3B0PSdhc3BlY3QnLHVuaXQ9J2RlZ3JlZXMnKQ0KaGlsbCA9IGhpbGxTaGFkZShzbG9wZSxhc3BlY3QsNDAsMzE1KQ0KYGBgDQpHUkFGSUNBIEVMRVZBQ0lPTg0KYGBge3J9DQpwbG90KHJlcF9lbGV2LG1haW49IkRFTSBQQVJBIFNBUkFWRU5BIChNRVRST1MpIiwgY29sPXRlcnJhaW4uY29sb3JzKDI1LGFscGhhPTAuNykpDQoNCmBgYA0KR1JBRklDQU1PUyBMQSBQRU5ESUVOVEUNCmBgYHtyfQ0KcGxvdChzbG9wZSxtYWluPSJQRU5ESUVOVEUgUEFSQSBTQVJBVkVOQSAoR1JBRE9TKSIsIGNvbD10b3BvLmNvbG9ycygyNSxhbHBoYT0wLjcpKQ0KYGBgDQpHUkFGSUNBTU9TIEFTUEVDVE8NCmBgYHtyfQ0KcGxvdChhc3BlY3QsbWFpbj0iQVNQRUNUTyBQQVJBIFNBUkFWRU5BIChHUkFET1MpIiwgY29sPXJhaW5ib3coMjUsYWxwaGE9MC43KSkNCmBgYA0KUEFMRVRBIENPTUJJTkFEQQ0KYGBge3J9DQpwbG90KGhpbGwsDQogICAgICAgIGNvbD1ncmV5KDE6MTAwLzEwMCksIA0KICAgICAgICBsZWdlbmQ9RkFMU0UsICAgICAgICAgDQogICAgICAgIG1haW49IkRFTSBQQVJBIFNBUkFWRU5BIiwNCiAgICAgICAgYXhlcz1GQUxTRSkgICAgICAgICANCnBsb3QocmVwX2VsZXYsIA0KICAgICAgICBheGVzPUZBTFNFLA0KICAgICAgICBjb2w9dGVycmFpbi5jb2xvcnMoMTIsIGFscGhhPTAuMzUpLCBhZGQ9VFJVRSkNCmBgYA0KTUFQQVMgREUgREFUT1MgREUgRUxFVkFDSU9OIENPTiBTT01CUkVBRE8gREUgUkFZT1MgDQpgYGB7cn0NCmluc3RhbGwucGFja2FnZXMoInJheXNoYWRlciIpDQpgYGANCmBgYHtyfQ0KbGlicmFyeShyYXlzaGFkZXIpDQpgYGANCkNPTVZFUlRJUiBFTCBERU0gRU4gVU5BIE1BVFJJWg0KYGBge3J9DQplbG1hdCA9IHJhc3Rlcl90b19tYXRyaXgocmVwX2VsZXYpDQpgYGANCmBgYHtyfQ0KZWxtYXQgJT4lDQogIHNwaGVyZV9zaGFkZSh0ZXh0dXJlID0gImltaG9mMiIpICU+JQ0KICBwbG90X21hcCgpDQpgYGANCkFHUkVHQVIgQ0FQQSBERSBBR1VBTA0KYGBge3J9DQplbG1hdCAlPiUNCiAgc3BoZXJlX3NoYWRlKHRleHR1cmUgPSAiZGVzZXJ0IikgJT4lDQogIGFkZF93YXRlcihkZXRlY3Rfd2F0ZXIoZWxtYXQpLCBjb2xvciA9ICJkZXNlcnQiKSAlPiUNCiAgcGxvdF9tYXAoKQ0KYGBgDQpUUkFaQURPIERFIFJBWU9TIERFU0RFIExBIERJUkVDQ0lPTiBERUwgU09MDQpgYGB7cn0NCmVsbWF0ICU+JQ0KICBzcGhlcmVfc2hhZGUodGV4dHVyZSA9ICJkZXNlcnQiKSAlPiUNCiAgYWRkX3dhdGVyKGRldGVjdF93YXRlcihlbG1hdCksIGNvbG9yID0gImRlc2VydCIpICU+JQ0KICBhZGRfc2hhZG93KHJheV9zaGFkZShlbG1hdCksIDAuNSkgJT4lDQogIHBsb3RfbWFwKCkNCmBgYA0KT1RSQSBGT1JNQSBERSBWSVNVQUxJWkFDSU9ODQpgYGB7cn0NCmluc3RhbGwucGFja2FnZXMoImpwZWciKQ0KYGBgDQpgYGB7cn0NCmxpYnJhcnkoanBlZykNCmBgYA0KRnVuY2nDs24gZGUgc29tYnJlYWRvIGRlIG1hcGVvIGRlIGVudG9ybm8gZXNmw6lyaWNvDQpgYGB7cn0NCmdldHY9ZnVuY3Rpb24oaSxhLHMpew0KICBjdCA9IGRpbShpKVsxOjJdLzINCiAgc3ggPSB2YWx1ZXMocykvOTAgKiBjdFsxXQ0KICBzeSA9IHZhbHVlcyhzKS85MCAqIGN0WzJdDQogIGEgPSB2YWx1ZXMoYSkgKiAwLjAxNzQ1DQogIHB4ID0gZmxvb3IoY3RbMV0gKyBzeCAqIC1zaW4oYSkpDQogIHB5ID0gZmxvb3IoY3RbMl0gKyBzeSAqIGNvcyhhKSkNCiAgDQogIA0KICB0ZW1wbGF0ZSA9IGJyaWNrKHMscyxzKQ0KICB2YWx1ZXModGVtcGxhdGUpPU5BDQogICANCiAgY2VsbHIgPSBweCArIHB5ICogY3RbMV0qMg0KICBjZWxsZyA9IHB4ICsgcHkgKiBjdFsxXSoyICsgKGN0WzFdKjIqY3RbMl0qMikNCiAgY2VsbGIgPSBweCArIHB5ICogY3RbMV0qMiArIDIqKGN0WzFdKjIqY3RbMl0qMikNCiAgDQogIHRlbXBsYXRlW1sxXV0gPSBpW2NlbGxyXQ0KICB0ZW1wbGF0ZVtbMl1dID0gaVtjZWxsZ10NCiAgdGVtcGxhdGVbWzNdXSA9IGlbY2VsbGJdDQogIA0KICB0ZW1wbGF0ZSA9IHRlbXBsYXRlICogMjU2DQogIA0KICB0ZW1wbGF0ZQ0KfQ0KYGBgDQoNCmBgYHtyfQ0KbWFwID0gcmVhZEpQRUcoIkM6L1VzZXJzL3NlYmFzL09uZURyaXZlL0RvY3VtZW50b3MvUi9SIEFSVFVSTy9BUkFVQ0EvOXB2YkhqTi5qcGciKQ0Kb3V0ID0gZ2V0dihtYXAsIGFzcGVjdCwgc2xvcGUpDQpwbG90UkdCKG91dCwgbWFpbiA9ICJFTEVWQUNJT04gRU4gU0FSQVZFTkEiKQ0KYGBgDQo=