Agradecimientos
- Agradezco enormemente a Ivan Lizarazo por su documento guía publicado en Rpubs. Sus documentos son muy valiosos para todos aquellos que como yo queremos aprender un poco acerca de Sistemas de Información Geográfica con R.
SoilGrids
Bibliotecas
library(rgdal)
library(gdalUtils)
library(raster)
library(sf)
library(tidyverse)
library(ggspatial)
Raster Nitrógeno
nitro <- raster("https://files.isric.org/soilgrids/latest/data/nitrogen/nitrogen_15-30cm_mean.vrt")
class : RasterLayer
dimensions : 58034, 159246, 9241682364 (nrow, ncol, ncell)
resolution : 250, 250 (x, y)
extent : -19949750, 19861750, -6147500, 8361000 (xmin, xmax, ymin, ymax)
crs : +proj=igh +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs
source : https://files.isric.org/soilgrids/latest/data/nitrogen/nitrogen_15-30cm_mean.vrt
names : nitrogen_15.30cm_mean
values : -32768, 32767 (min, max)
Shape Colombia
deptos <- st_read("data_shapes/MGN_DPTO_POLITICO.shp")
Reading layer `MGN_DPTO_POLITICO' from data source `D:\DocumentosEdimer\Github\Spatial-Data-Science\SoilGrids\data_shapes\MGN_DPTO_POLITICO.shp' using driver `ESRI Shapefile'
Simple feature collection with 33 features and 9 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -81.73562 ymin: -4.229406 xmax: -66.84722 ymax: 13.39473
Geodetic CRS: WGS 84
igh <- '+proj=igh +lat_0=0 +lon_0=0 +datum=WGS84 +units=m +no_defs'
colombia_igh <- st_transform(deptos, igh)
Simple feature collection with 33 features and 9 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -9147200 ymin: -470815.4 xmax: -7442381 ymax: 1491094
CRS: +proj=igh +lat_0=0 +lon_0=0 +datum=WGS84 +units=m +no_defs
First 10 features:
DPTO_CCDGO DPTO_CNMBR DPTO_ANO_C DPTO_ACT_A DPTO_NAREA
1 05 ANTIOQUIA 1886 Constitucion Politica de 1886 62804.71
2 23 CÓRDOBA 1951 Ley 9 del 18 de Diciembre de 1951 25086.55
3 27 CHOCÓ 1947 Ley 13 del 3 de Noviembre de 1947 48353.22
4 70 SUCRE 1966 Ley 47 del 8 de Agosto de 1966 10591.85
5 08 ATLÁNTICO 1910 Ley 21 de 1910 3313.81
6 13 BOLÍVAR 1886 Constitucion Politica de 1886 26719.21
7 47 MAGDALENA 1964 1964 23135.94
8 20 CESAR 1967 Ley 25 21 de junio de 1967 22565.31
9 44 LA GUAJIRA 1964 Acto Legislativo No. 1 de Diciembre 28 de 1964 20619.01
10 19 CAUCA 1857 15 de junio de 1857 31242.91
DPTO_CSMBL DPTO_VGNC Shape_Leng Shape_Area geometry
1 3 2020 2397127.4 64104708675 MULTIPOLYGON (((-8537745 98...
2 3 2020 1084739.0 25771851296 MULTIPOLYGON (((-8487485 10...
3 3 2020 2305005.9 49095252907 MULTIPOLYGON (((-8641428 96...
4 3 2020 960645.8 10927904055 MULTIPOLYGON (((-8449360 11...
5 3 2020 286201.3 3452348633 MULTIPOLYGON (((-8384559 12...
6 3 2020 1820039.5 27531715587 MULTIPOLYGON (((-8426196 12...
7 3 2020 1213551.0 24044561103 MULTIPOLYGON (((-8298708 12...
8 3 2020 1410287.8 23352037403 MULTIPOLYGON (((-8229790 12...
9 3 2020 1211484.9 21584067313 MULTIPOLYGON (((-8050536 13...
10 3 2020 1553621.4 31435492565 MULTIPOLYGON (((-8515823 37...
- Área de interés (Colombia):
area <- st_bbox(colombia_igh)
area
xmin ymin xmax ymax
-9147200.3 -470815.4 -7442381.4 1491094.3
- Límites: formato numérico necesario para
rgdal
ulx <- area$xmin
uly <- area$ymax
lrx <- area$xmax
lry <- area$ymin
limites <- c(ulx, uly, lrx, lry)
limites
xmin ymax xmax ymin
-9147200.3 1491094.3 -7442381.4 -470815.4
Nitrógeno Colombia (.tif)
- Obtención de datos con GDAL: este proceso se demora algunos minutos. Dará como resultado un archivo con formato .tif en la ruta especificada. Importante: es necesario tener instalado GDAL en nuestro computador (ver anexos para más información).
sg_url <- "/vsicurl/https://files.isric.org/soilgrids/latest/data/nitrogen/nitrogen_15-30cm_mean.vrt"
lfile <- "data_shapes/nitrogeno_colombia.tif"
gdal_translate(sg_url, lfile ,
tr = c(250,250),
projwin = limites,
projwin_srs = igh,
verbose = TRUE)
Checking gdal_installation...
Scanning for GDAL installations...
Checking Sys.which...
GDAL version 3.2.2
GDAL command being used: "C:\Program Files\GDAL\gdal_translate.exe" -tr 250 250 -projwin -9147200.27432083 1491094.27369704 -7442381.38468577 -470815.374159958 -of "GTiff" -projwin_srs "+proj=igh +lat_0=0 +lon_0=0 +datum=WGS84 +units=m +no_defs" "/vsicurl/https://files.isric.org/soilgrids/latest/data/nitrogen/nitrogen_15-30cm_mean.vrt" "data_shapes/nitrogeno_colombia.tif"
Input file size is 159246, 580340...10...20...30ERROR 1: Request for 390313-406512 failed...40...50...60...70...80...90...100 - done.
NULL
Raster Nitrógeno Colombia
- Dividimos por 100 para tener las unidades originales (cg/kg)
nitro_colombia <- raster("data_shapes/nitrogeno_colombia.tif") / 100

Corte Colombia
- Corte con el shape de Colombia que tiene el mismo tipo de coordenadas:
corte_colombia <- nitro_colombia %>%
crop(colombia_igh) %>%
mask(colombia_igh)

- Corte con shape obtenido con biblioteca
raster
:
# Mapa Colombia
ejemplo <- getData(name = "GADM", country = "COL", level = 0)
probando la URL 'https://biogeo.ucdavis.edu/data/gadm3.6/Rsp/gadm36_COL_0_sp.rds'
Content type 'à|ˆqþ' length 541789 bytes (529 KB)
downloaded 529 KB
ejemplo_sf <- st_as_sf(ejemplo)
# Reproyección
ejemplo_igh <- st_transform(ejemplo_sf, igh)
# Corte
corte_ejemplo <- nitro_colombia %>%
crop(ejemplo_igh) %>%
mask(ejemplo_igh)

- Corte cambiando sistema de coordenadas:
nuevo_sistema <- "+proj=longlat +datum=WGS84 +no_defs"
prueba <- projectRaster(nitro_colombia, crs = nuevo_sistema)
# Corte
prueba_ejemplo <- prueba %>%
crop(ejemplo_sf) %>%
mask(ejemplo_sf)

Valle del Cauca
Filtro
valle <- colombia_igh %>%
filter(DPTO_CNMBR == "VALLE DEL CAUCA")
Corte
corte_valle <- nitro_colombia %>%
crop(valle) %>%
mask(valle)
plot(corte_valle, colNA = "black")

Mapa ggplot2
- Conversión a tibble: esta base de datos queda con 323589 observaciones.
valle_df <- corte_valle %>%
as("SpatialPixelsDataFrame") %>%
as_tibble()
valle_df %>% head()
ggplot() +
geom_raster(data = valle_df, aes(x = x, y = y, fill = nitrogeno_colombia)) +
geom_sf(data = valle, alpha = 0, fill = "transparent") +
labs(fill = "Nitrógeno (cg/kg)",
x = "Longitud", y = "Latitud") +
annotation_north_arrow(location = "tl") +
scale_fill_viridis_c(direction = -1) +
theme_bw()

Antioquia
Filtro
antioquia <- colombia_igh %>%
filter(DPTO_CNMBR == "ANTIOQUIA")
Corte
corte_antioquia <- nitro_colombia %>%
crop(antioquia) %>%
mask(antioquia)
plot(corte_antioquia, colNA = "black")

Mapa ggplot2
- Conversión a tibble: esta base de datos queda con 995651 observaciones.
antioquia_df <- corte_antioquia %>%
as("SpatialPixelsDataFrame") %>%
as_tibble()
antioquia_df %>% head()
ggplot() +
geom_raster(data = antioquia_df, aes(x = x, y = y, fill = nitrogeno_colombia)) +
geom_sf(data = antioquia, alpha = 0) +
labs(fill = "Nitrógeno (cg/kg)",
x = "Longitud", y = "Latitud") +
annotation_north_arrow(location = "tr") +
scale_fill_gradientn(colours = rainbow(30)) +
theme_bw()

LS0tDQp0aXRsZTogIkV4dHJhY2Npw7NuIGRlIGRhdG9zIFNvaWxHcmlkcyINCnN1YnRpdGxlOiAiRWplbXBsbyBOaXRyw7NnZW5vICgxNS0zMCBjbSkgQ29sb21iaWEiDQphdXRob3I6ICJbRWRpbWVyIChTaWRlcmV1cyldKGh0dHBzOi8vZWRpbWVyLmdpdGh1Yi5pby8pIg0KZGF0ZTogIkFicmlsIGRlIDIwMjEiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0Og0KICAgICAgc21vb3RoX3Njcm9sbDogZmFsc2UNCiAgICAgIGNvbGxhcHNlZDogZmFsc2UNCiAgICB0aGVtZTogY29zbW8NCiAgICBkZl9wcmludDogcGFnZWQNCiAgICBjc3M6IGVzdGlsby5jc3MNCiAgICBoaWdobGlnaHQ6IHB5Z21lbnRzDQogICAgY29kZV9mb2xkaW5nOiBzaG93DQogICAgDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgIGZpZy53aWR0aCA9IDgsIGZpZy5hbGlnbiA9ICJjZW50ZXIiKQ0KYGBgDQoNCiMgQWdyYWRlY2ltaWVudG9zDQoNCi0gQWdyYWRlemNvIGVub3JtZW1lbnRlIGEgW0l2YW4gTGl6YXJhem9dKGh0dHBzOi8vcnB1YnMuY29tL2lhbHMydW4pIHBvciBzdSBbZG9jdW1lbnRvIGd1w61hXShodHRwczovL3JwdWJzLmNvbS9pYWxzMnVuL3NvaWxncmlkc193ZWJkYXYpIHB1YmxpY2FkbyBlbiBbUnB1YnMuXShodHRwczovL3JwdWJzLmNvbS8pIFN1cyBkb2N1bWVudG9zIHNvbiBtdXkgdmFsaW9zb3MgcGFyYSB0b2RvcyBhcXVlbGxvcyBxdWUgY29tbyB5byBxdWVyZW1vcyBhcHJlbmRlciB1biBwb2NvIGFjZXJjYSBkZSBTaXN0ZW1hcyBkZSBJbmZvcm1hY2nDs24gR2VvZ3LDoWZpY2EgY29uIFIuDQoNCiMgU29pbEdyaWRzDQoNCi0gW1NvaWxHcmlkc10oaHR0cHM6Ly9zb2lsZ3JpZHMub3JnLykNCg0KPGNlbnRlcj4NCjxpbWcgc3JjID0gImh0dHBzOi8vd3d3LmlzcmljLm9yZy9zaXRlcy9kZWZhdWx0L2ZpbGVzL3N0eWxlcy9nYWxsZXJ5X2JpZ19pbWFnZV85MDB4NzAwL3B1YmxpYy9Tb2lsR3JpZHNfYmFubmVyX3dlYi5wbmciIC8+DQo8L2NlbnRlcj4NCg0KIyBCaWJsaW90ZWNhcw0KDQpgYGB7cn0NCmxpYnJhcnkocmdkYWwpDQpsaWJyYXJ5KGdkYWxVdGlscykNCmxpYnJhcnkocmFzdGVyKQ0KbGlicmFyeShzZikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShnZ3NwYXRpYWwpDQpgYGANCg0KIyBSYXN0ZXIgTml0csOzZ2Vubw0KDQotIFtEYXRvcyBTb2lsR3JpZHNdKGh0dHBzOi8vZmlsZXMuaXNyaWMub3JnL3NvaWxncmlkcy9sYXRlc3QvZGF0YS8pDQotIFtJU1JJQ10oaHR0cHM6Ly93d3cuaXNyaWMub3JnL2V4cGxvcmUpDQotIFtBcnTDrWN1bG8gU29pbEdyaWRzXShodHRwczovL2pvdXJuYWxzLnBsb3Mub3JnL3Bsb3NvbmUvYXJ0aWNsZT9pZD0xMC4xMzcxL2pvdXJuYWwucG9uZS4wMTY5NzQ4KQ0KDQpgYGB7cn0NCm5pdHJvIDwtIHJhc3RlcigiaHR0cHM6Ly9maWxlcy5pc3JpYy5vcmcvc29pbGdyaWRzL2xhdGVzdC9kYXRhL25pdHJvZ2VuL25pdHJvZ2VuXzE1LTMwY21fbWVhbi52cnQiKQ0KYGBgDQoNCmBgYHtyfQ0Kbml0cm8NCmBgYA0KDQoNCiMgU2hhcGUgQ29sb21iaWENCg0KLSBbQ29sb21iaWEgU2hhcGUgLSBOaXZlbCBnZW9ncsOhZmljbyBkZXBhcnRhbWVudG9zXShodHRwczovL2dlb3BvcnRhbC5kYW5lLmdvdi5jby9zZXJ2aWNpb3MvZGVzY2FyZ2EteS1tZXRhZGF0b3MvZGVzY2FyZ2EtbWduLW1hcmNvLWdlb2VzdGFkaXN0aWNvLW5hY2lvbmFsLykNCg0KYGBge3J9DQpkZXB0b3MgPC0gc3RfcmVhZCgiZGF0YV9zaGFwZXMvTUdOX0RQVE9fUE9MSVRJQ08uc2hwIikNCmBgYA0KDQotIFByb3llY2Npw7NuIGRlIGNvb3JkZW5hZGFzOiB0cmFuc2Zvcm1hY2nDs24gYSBbcHJveWVjY2nDs24gaG9tb2xvc2VuYSBkZSBHb29kZV0oaHR0cHM6Ly9lcy53aWtpcGVkaWEub3JnL3dpa2kvUHJveWVjY2klQzMlQjNuX2RlX0dvb2RlKSANCg0KYGBge3J9DQppZ2ggPC0gJytwcm9qPWlnaCArbGF0XzA9MCArbG9uXzA9MCArZGF0dW09V0dTODQgK3VuaXRzPW0gK25vX2RlZnMnDQpjb2xvbWJpYV9pZ2ggPC0gc3RfdHJhbnNmb3JtKGRlcHRvcywgaWdoKQ0KYGBgDQoNCmBgYHtyfQ0KY29sb21iaWFfaWdoDQpgYGANCg0KLSDDgXJlYSBkZSBpbnRlcsOpcyAoQ29sb21iaWEpOg0KDQpgYGB7cn0NCmFyZWEgPC0gc3RfYmJveChjb2xvbWJpYV9pZ2gpDQphcmVhDQpgYGANCg0KLSBMw61taXRlczogZm9ybWF0byBudW3DqXJpY28gbmVjZXNhcmlvIHBhcmEgYHJnZGFsYA0KDQpgYGB7cn0NCnVseCA8LSBhcmVhJHhtaW4NCnVseSA8LSBhcmVhJHltYXgNCmxyeCA8LSBhcmVhJHhtYXgNCmxyeSA8LSBhcmVhJHltaW4NCmxpbWl0ZXMgPC0gYyh1bHgsIHVseSwgbHJ4LCBscnkpDQpsaW1pdGVzDQpgYGANCg0KDQojIE5pdHLDs2dlbm8gQ29sb21iaWEgKC50aWYpDQoNCi0gT2J0ZW5jacOzbiBkZSBkYXRvcyBjb24gKipHREFMKio6IGVzdGUgcHJvY2VzbyBzZSBkZW1vcmEgYWxndW5vcyBtaW51dG9zLiBEYXLDoSBjb21vIHJlc3VsdGFkbyB1biBhcmNoaXZvIGNvbiBmb3JtYXRvICoudGlmKiBlbiBsYSBydXRhIGVzcGVjaWZpY2FkYS4gKipJbXBvcnRhbnRlOioqIGVzIG5lY2VzYXJpbyB0ZW5lciBpbnN0YWxhZG8gR0RBTCBlbiBudWVzdHJvIGNvbXB1dGFkb3IgKHZlciBhbmV4b3MgcGFyYSBtw6FzIGluZm9ybWFjacOzbikuDQoNCmBgYHtyfQ0Kc2dfdXJsIDwtICIvdnNpY3VybC9odHRwczovL2ZpbGVzLmlzcmljLm9yZy9zb2lsZ3JpZHMvbGF0ZXN0L2RhdGEvbml0cm9nZW4vbml0cm9nZW5fMTUtMzBjbV9tZWFuLnZydCINCmxmaWxlIDwtICJkYXRhX3NoYXBlcy9uaXRyb2dlbm9fY29sb21iaWEudGlmIg0KDQpnZGFsX3RyYW5zbGF0ZShzZ191cmwsIGxmaWxlICwNCiAgICAgICAgICAgICAgIHRyID0gYygyNTAsMjUwKSwNCiAgICAgICAgICAgICAgIHByb2p3aW4gPSBsaW1pdGVzLA0KICAgICAgICAgICAgICAgcHJvandpbl9zcnMgPSBpZ2gsDQogICAgICAgICAgICAgICB2ZXJib3NlID0gVFJVRSkNCmBgYA0KDQojIFJhc3RlciBOaXRyw7NnZW5vIENvbG9tYmlhDQoNCi0gW0NvbnN1bHRhciB1bmlkYWRlcyBkZWwgbml0csOzZ2Vub10oaHR0cHM6Ly93d3cuaXNyaWMub3JnL2V4cGxvcmUvc29pbGdyaWRzL2ZhcS1zb2lsZ3JpZHMjV2hhdF9pc19Tb2lsR3JpZHMpDQoNCjxjZW50ZXI+DQo8aW1nIHNyYyA9ICJpbWcvdmFyaWFibGVzX3NvaWxncmlkcy5QTkciIC8+DQo8L2NlbnRlcj4NCg0KPGJyPg0KDQotIERpdmlkaW1vcyBwb3IgMTAwIHBhcmEgdGVuZXIgbGFzIHVuaWRhZGVzIG9yaWdpbmFsZXMgKGNnL2tnKQ0KDQpgYGB7cn0NCm5pdHJvX2NvbG9tYmlhIDwtIHJhc3RlcigiZGF0YV9zaGFwZXMvbml0cm9nZW5vX2NvbG9tYmlhLnRpZiIpIC8gMTAwDQpgYGANCg0KYGBge3J9DQpwbG90KG5pdHJvX2NvbG9tYmlhKQ0KYGBgDQoNCiMgQ29ydGUgQ29sb21iaWENCg0KLSBDb3J0ZSBjb24gZWwgc2hhcGUgZGUgQ29sb21iaWEgcXVlIHRpZW5lIGVsIG1pc21vIHRpcG8gZGUgY29vcmRlbmFkYXM6DQoNCmBgYHtyfQ0KY29ydGVfY29sb21iaWEgPC0gbml0cm9fY29sb21iaWEgJT4lIA0KICBjcm9wKGNvbG9tYmlhX2lnaCkgJT4lIA0KICBtYXNrKGNvbG9tYmlhX2lnaCkNCmBgYA0KDQpgYGB7cn0NCnBsb3QoY29ydGVfY29sb21iaWEpDQpgYGANCg0KLSBDb3J0ZSBjb24gc2hhcGUgb2J0ZW5pZG8gY29uIGJpYmxpb3RlY2EgYHJhc3RlcmA6DQoNCmBgYHtyfQ0KIyBNYXBhIENvbG9tYmlhDQplamVtcGxvIDwtIGdldERhdGEobmFtZSA9ICJHQURNIiwgY291bnRyeSA9ICJDT0wiLCBsZXZlbCA9IDApDQplamVtcGxvX3NmIDwtIHN0X2FzX3NmKGVqZW1wbG8pDQoNCiMgUmVwcm95ZWNjacOzbg0KZWplbXBsb19pZ2ggPC0gc3RfdHJhbnNmb3JtKGVqZW1wbG9fc2YsIGlnaCkNCg0KIyBDb3J0ZQ0KY29ydGVfZWplbXBsbyA8LSBuaXRyb19jb2xvbWJpYSAlPiUgDQogIGNyb3AoZWplbXBsb19pZ2gpICU+JSANCiAgbWFzayhlamVtcGxvX2lnaCkNCmBgYA0KDQpgYGB7cn0NCnBsb3QoY29ydGVfZWplbXBsbykNCmBgYA0KDQotIENvcnRlIGNhbWJpYW5kbyBzaXN0ZW1hIGRlIGNvb3JkZW5hZGFzOg0KDQpgYGB7cn0NCm51ZXZvX3Npc3RlbWEgPC0gIitwcm9qPWxvbmdsYXQgK2RhdHVtPVdHUzg0ICtub19kZWZzIg0KcHJ1ZWJhIDwtIHByb2plY3RSYXN0ZXIobml0cm9fY29sb21iaWEsIGNycyA9IG51ZXZvX3Npc3RlbWEpDQoNCiMgQ29ydGUNCnBydWViYV9lamVtcGxvIDwtIHBydWViYSAlPiUgDQogIGNyb3AoZWplbXBsb19zZikgJT4lIA0KICBtYXNrKGVqZW1wbG9fc2YpDQpgYGANCg0KYGBge3J9DQpwbG90KHBydWViYV9lamVtcGxvKQ0KYGBgDQoNCiMgVmFsbGUgZGVsIENhdWNhDQoNCiMjIEZpbHRybw0KDQpgYGB7cn0NCnZhbGxlIDwtIGNvbG9tYmlhX2lnaCAlPiUgDQogIGZpbHRlcihEUFRPX0NOTUJSID09ICJWQUxMRSBERUwgQ0FVQ0EiKQ0KYGBgDQoNCiMjIENvcnRlDQoNCmBgYHtyfQ0KY29ydGVfdmFsbGUgPC0gbml0cm9fY29sb21iaWEgJT4lIA0KICBjcm9wKHZhbGxlKSAlPiUgDQogIG1hc2sodmFsbGUpDQpgYGANCg0KYGBge3J9DQpwbG90KGNvcnRlX3ZhbGxlLCBjb2xOQSA9ICJibGFjayIpDQpgYGANCg0KIyMgTWFwYSBgZ2dwbG90MmANCg0KLSBDb252ZXJzacOzbiBhIHRpYmJsZTogZXN0YSBiYXNlIGRlIGRhdG9zIHF1ZWRhIGNvbiAzMjM1ODkgb2JzZXJ2YWNpb25lcy4NCg0KYGBge3J9DQp2YWxsZV9kZiA8LSBjb3J0ZV92YWxsZSAlPiUgDQogIGFzKCJTcGF0aWFsUGl4ZWxzRGF0YUZyYW1lIikgJT4lIA0KICBhc190aWJibGUoKQ0KDQp2YWxsZV9kZiAlPiUgaGVhZCgpDQpgYGANCg0KDQpgYGB7cn0NCmdncGxvdCgpICsNCiAgZ2VvbV9yYXN0ZXIoZGF0YSA9IHZhbGxlX2RmLCBhZXMoeCA9IHgsIHkgPSB5LCBmaWxsID0gbml0cm9nZW5vX2NvbG9tYmlhKSkgKw0KICBnZW9tX3NmKGRhdGEgPSB2YWxsZSwgYWxwaGEgPSAwLCBmaWxsID0gInRyYW5zcGFyZW50IikgKw0KICBsYWJzKGZpbGwgPSAiTml0csOzZ2VubyAoY2cva2cpIiwNCiAgICAgICB4ID0gIkxvbmdpdHVkIiwgeSA9ICJMYXRpdHVkIikgKw0KICBhbm5vdGF0aW9uX25vcnRoX2Fycm93KGxvY2F0aW9uID0gInRsIikgKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfYyhkaXJlY3Rpb24gPSAtMSkgKw0KICB0aGVtZV9idygpDQpgYGANCg0KIyBBbnRpb3F1aWENCg0KIyMgRmlsdHJvDQoNCmBgYHtyfQ0KYW50aW9xdWlhIDwtIGNvbG9tYmlhX2lnaCAlPiUgDQogIGZpbHRlcihEUFRPX0NOTUJSID09ICJBTlRJT1FVSUEiKQ0KYGBgDQoNCiMjIENvcnRlDQoNCmBgYHtyfQ0KY29ydGVfYW50aW9xdWlhIDwtIG5pdHJvX2NvbG9tYmlhICU+JSANCiAgY3JvcChhbnRpb3F1aWEpICU+JSANCiAgbWFzayhhbnRpb3F1aWEpDQpgYGANCg0KYGBge3J9DQpwbG90KGNvcnRlX2FudGlvcXVpYSwgY29sTkEgPSAiYmxhY2siKQ0KYGBgDQoNCiMjIE1hcGEgYGdncGxvdDJgDQoNCi0gQ29udmVyc2nDs24gYSB0aWJibGU6IGVzdGEgYmFzZSBkZSBkYXRvcyBxdWVkYSBjb24gOTk1NjUxIG9ic2VydmFjaW9uZXMuDQoNCmBgYHtyfQ0KYW50aW9xdWlhX2RmIDwtIGNvcnRlX2FudGlvcXVpYSAlPiUgDQogIGFzKCJTcGF0aWFsUGl4ZWxzRGF0YUZyYW1lIikgJT4lIA0KICBhc190aWJibGUoKQ0KDQphbnRpb3F1aWFfZGYgJT4lIGhlYWQoKQ0KYGBgDQoNCg0KYGBge3J9DQpnZ3Bsb3QoKSArDQogIGdlb21fcmFzdGVyKGRhdGEgPSBhbnRpb3F1aWFfZGYsIGFlcyh4ID0geCwgeSA9IHksIGZpbGwgPSBuaXRyb2dlbm9fY29sb21iaWEpKSArDQogIGdlb21fc2YoZGF0YSA9IGFudGlvcXVpYSwgYWxwaGEgPSAwKSArDQogIGxhYnMoZmlsbCA9ICJOaXRyw7NnZW5vIChjZy9rZykiLA0KICAgICAgIHggPSAiTG9uZ2l0dWQiLCB5ID0gIkxhdGl0dWQiKSArDQogIGFubm90YXRpb25fbm9ydGhfYXJyb3cobG9jYXRpb24gPSAidHIiKSArDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGNvbG91cnMgPSByYWluYm93KDMwKSkgKw0KICB0aGVtZV9idygpDQpgYGANCg0KIyBBbmV4b3MNCg0KIyMgUmVjdXJzb3MgZGUgaW5mb3JtYWNpw7NuDQoNCi0gW2dkYWwub3JnXShodHRwczovL2dkYWwub3JnLykNCi0gW2dpc2ludGVybmFscy5jb21dKGh0dHBzOi8vd3d3Lmdpc2ludGVybmFscy5jb20vcmVsZWFzZS5waHApDQotIFtUdXRvcmlhbCBpbnN0YWxhY2nDs24gZ2RhbCBXaW5kb3dzIChpbmdsw6lzKV0oaHR0cHM6Ly9zYW5kYm94LmlkcmUudWNsYS5lZHUvc2FuZGJveC90dXRvcmlhbHMvaW5zdGFsbGluZy1nZGFsLWZvci13aW5kb3dzKQ0KLSBbVHV0b3JpYWwgaW5zdGFsYWNpw7NuIGdkYWwgV2luZG93cyAoZXNwYcOxb2wpXShodHRwOi8vc2lnZGVsZXRyYXMuY29tLzIwMTYvaW5zdGFsYWNpb24tZGUtcHl0aG9uLXktZ2RhbC1lbi13aW5kb3dzLykNCg==