1. Introducción
El paquete sf (Simple Features) es una
herramienta para trabajar con datos espaciales, ya que cuenta con
diferentes funciones básicas para leer, visualizar y manipular archivos
shapefile, integrando librerías como dplyr y ggplot2 para el
análisis y la representación gráfica. En este caso, la base será el
shapefile MGN2023_MPIO_POLITICO del DANE (2023).
El objetivo de este cuaderno es representar espacialmente los
municipios y ciudades del departamento de Boyacá mediante un mapa
temático elaborado con sf, ggplot2 y ggspatial.
2. Configuración
Se cargan las librerías necesarias para el análisis
sf, dplyr, ggplot2 y
ggspatial, instaladas previamente.
library(sf)
library(dplyr)
library(ggplot2)
library(ggspatial)
3. Lectura y Escritura de Datos Espaciales
3.1. Lectura de datos espaciales con st_read
Primero se utiliza la función list.files() para visualizar los
archivos de la carpeta donde está ubicado el shapefile.
list.files("D:/GB2/P3/Notebook/Municipios")
[1] "MGN_ADM_MPIO_GRAFICO.cpg" "MGN_ADM_MPIO_GRAFICO.dbf" "MGN_ADM_MPIO_GRAFICO.prj" "MGN_ADM_MPIO_GRAFICO.shp" "MGN_ADM_MPIO_GRAFICO.shp.xml"
[6] "MGN_ADM_MPIO_GRAFICO.shx"
Después se visualiza el encabezado de los datos de la variable
colombia, utilizando las funciones head() y paged_table().
rmarkdown::paged_table(head(colombia))
3.2. Escritura de datos espaciales con st_write
4. Seleccionar departamento
4.1. Seleccionar por atributo
Para realizar la selección por atributo, se utiliza la función
filter(), especificando los criterios ncesarios para seleccionar
únicamente los municipios de Boyacá.
rmarkdown::paged_table((boyaca <- dplyr::filter(colombia, dpto_cnmbr=="BOYACÁ")))
Por último, los polígonos seleccionados se guardan en un nuevo
archivo geopackage.
st_write(boyaca, "boyaca_munic.gpkg", driver = "GPKG", append = F)
Deleting layer `boyaca_munic' using driver `GPKG'
Writing layer `boyaca_munic' to data source `boyaca_munic.gpkg' using driver `GPKG'
Writing 123 features with 12 fields and geometry type Multi Polygon.
5. Seleccionar por ubicación
Se utiliza la función de selección por ubicación con un archivo CSV
que contiene los datos de las ciudades del mundo. Primero, se lee el
archivo y se convierte en un objeto espacial con st_as_sf()
especificando las columnas de longitud y
latitud, junto al sistema de referencia EPSG:4326.
cities = read.csv('D:/GB2/P3/Notebook/simplemaps_worldcities_basicv1.77/worldcities.csv') %>%
st_as_sf(coords=c("lng","lat"), crs=4326)
A continuación, se visualiza el contenido de la variable
cities.
rmarkdown::paged_table(cities)
Se verifica que los CRS de ambos conjuntos de datos (cities y
boyaca) coincidan.
st_crs(cities)$epsg
[1] 4326
st_crs(boyaca)$epsg
[1] 4686
Luego, se crea la variable boyaca_cities para
guardar únicamente las ciudades del departamento de Boyacá. Para la
selección se usa st_within.
boyaca_cities <- ncities[boyaca, , op = st_within]
6. Gráfica detallada
6.1. usando ggplot
Ahora, se utiliza ggplot para generar un gráfico
más estético de los municipios del departamento de Boyacá y de sus
ciudades.
7. Detalles del entorno computacional
sessionInfo()
R version 4.3.2 (2023-10-31 ucrt)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 11 x64 (build 22631)
Matrix products: default
locale:
[1] LC_COLLATE=Spanish_Colombia.utf8 LC_CTYPE=Spanish_Colombia.utf8 LC_MONETARY=Spanish_Colombia.utf8
[4] LC_NUMERIC=C LC_TIME=Spanish_Colombia.utf8
time zone: America/Bogota
tzcode source: internal
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] ggspatial_1.1.9 ggplot2_3.4.4 dplyr_1.1.4 sf_1.0-20
loaded via a namespace (and not attached):
[1] gtable_0.3.4 jsonlite_1.8.8 compiler_4.3.2 tidyselect_1.2.1 Rcpp_1.0.12 jquerylib_0.1.4
[7] scales_1.3.0 yaml_2.3.8 fastmap_1.1.1 R6_2.5.1 generics_0.1.3 classInt_0.4-11
[13] s2_1.1.7 knitr_1.45 tibble_3.2.1 units_0.8-7 munsell_0.5.0 DBI_1.2.3
[19] bslib_0.6.1 pillar_1.9.0 rlang_1.1.3 utf8_1.2.4 cachem_1.0.8 xfun_0.52
[25] sass_0.4.8 cli_3.6.2 withr_3.0.0 magrittr_2.0.3 wk_0.9.4 class_7.3-22
[31] digest_0.6.34 grid_4.3.2 rstudioapi_0.17.1 lifecycle_1.0.4 vctrs_0.6.5 KernSmooth_2.23-22
[37] proxy_0.4-27 evaluate_0.23 glue_1.7.0 farver_2.1.1 rsconnect_1.4.1 colorspace_2.1-0
[43] fansi_1.0.6 e1071_1.7-16 rmarkdown_2.25 tools_4.3.2 pkgconfig_2.0.3 htmltools_0.5.7
LS0tDQp0aXRsZTogIkludHJvZHVjY2nDs24gYSBlbGVtZW50b3Mgc2ltcGxlcyBlbiBSIg0KYXV0aG9yOiAiWWFuZXRoIEFsZXhhbmRyYSBBcmVuYXMgR2FycmlkbyINCmRhdGU6ICIyMS8wNS8yMDI1Ig0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCiMgMS4gSW50cm9kdWNjacOzbg0KIyMjIyMgRWwgcGFxdWV0ZSAqKnNmICgqU2ltcGxlIEZlYXR1cmVzKikqKiBlcyB1bmEgaGVycmFtaWVudGEgcGFyYSB0cmFiYWphciBjb24gZGF0b3MgZXNwYWNpYWxlcywgeWEgcXVlIGN1ZW50YSBjb24gZGlmZXJlbnRlcyBmdW5jaW9uZXMgYsOhc2ljYXMgcGFyYSBsZWVyLCB2aXN1YWxpemFyIHkgbWFuaXB1bGFyIGFyY2hpdm9zICpzaGFwZWZpbGUqLCBpbnRlZ3JhbmRvIGxpYnJlcsOtYXMgY29tbyBkcGx5ciB5IGdncGxvdDIgcGFyYSBlbCBhbsOhbGlzaXMgeSBsYSByZXByZXNlbnRhY2nDs24gZ3LDoWZpY2EuIEVuIGVzdGUgY2FzbywgbGEgYmFzZSBzZXLDoSBlbCAqc2hhcGVmaWxlKiBNR04yMDIzX01QSU9fUE9MSVRJQ08gZGVsIERBTkUgKDIwMjMpLg0KDQojIyMjIyBFbCBvYmpldGl2byBkZSBlc3RlIGN1YWRlcm5vIGVzIHJlcHJlc2VudGFyIGVzcGFjaWFsbWVudGUgbG9zIG11bmljaXBpb3MgeSBjaXVkYWRlcyBkZWwgZGVwYXJ0YW1lbnRvIGRlIEJveWFjw6EgbWVkaWFudGUgdW4gbWFwYSB0ZW3DoXRpY28gZWxhYm9yYWRvIGNvbiBzZiwgZ2dwbG90MiB5IGdnc3BhdGlhbC4NCg0KIyAyLiBDb25maWd1cmFjacOzbg0KIyMjIyMgU2UgY2FyZ2FuIGxhcyBsaWJyZXLDrWFzIG5lY2VzYXJpYXMgcGFyYSBlbCBhbsOhbGlzaXMgKipzZioqLCAqKmRwbHlyKiosICoqZ2dwbG90MioqIHkgKipnZ3NwYXRpYWwqKiwgaW5zdGFsYWRhcyBwcmV2aWFtZW50ZS4NCg0KYGBge3IgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0V9DQpsaWJyYXJ5KHNmKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZ2dzcGF0aWFsKQ0KYGBgDQoNCiMgMy4gTGVjdHVyYSB5IEVzY3JpdHVyYSBkZSBEYXRvcyBFc3BhY2lhbGVzDQojIyMgMy4xLiBMZWN0dXJhIGRlIGRhdG9zIGVzcGFjaWFsZXMgY29uIHN0X3JlYWQNCiMjIyMjIFByaW1lcm8gc2UgdXRpbGl6YSBsYSBmdW5jacOzbiBsaXN0LmZpbGVzKCkgcGFyYSB2aXN1YWxpemFyIGxvcyBhcmNoaXZvcyBkZSBsYSBjYXJwZXRhIGRvbmRlIGVzdMOhIHViaWNhZG8gZWwgc2hhcGVmaWxlLiANCg0KYGBge3J9DQpsaXN0LmZpbGVzKCJEOi9HQjIvUDMvTm90ZWJvb2svTXVuaWNpcGlvcyIpDQpgYGANCg0KIyMjIyMgQWhvcmEsIHNlIGVzcGVjaWZpY2EgbGEgcnV0YSBkZWwgYXJjaGl2byBzaGFwZWZpbGUgKipNdW5pY2lwaW9zKiogeSBzZSBsZWUgY29uIGxhIGZ1bmNpw7NuIHN0X3JlYWQuIExhIGluZm9ybWFjacOzbiBzZSBndWFyZGEgZW4gbGEgdmFyaWFibGUgKipjb2xvbWJpYSoqLg0KDQpgYGB7cn0NCmNvbG9tYmlhIDwtIHN0X3JlYWQoIkQ6L0dCMi9QMy9Ob3RlYm9vay9NdW5pY2lwaW9zL01HTl9BRE1fTVBJT19HUkFGSUNPLnNocCIpDQpgYGANCg0KIyMjIyMgRGVzcHXDqXMgc2UgdmlzdWFsaXphIGVsIGVuY2FiZXphZG8gZGUgbG9zIGRhdG9zIGRlIGxhIHZhcmlhYmxlIGNvbG9tYmlhLCB1dGlsaXphbmRvIGxhcyBmdW5jaW9uZXMgaGVhZCgpIHkgcGFnZWRfdGFibGUoKS4NCg0KYGBge3J9DQpybWFya2Rvd246OnBhZ2VkX3RhYmxlKGhlYWQoY29sb21iaWEpKQ0KYGBgDQoNCg0KIyMjIDMuMi4gRXNjcml0dXJhIGRlIGRhdG9zIGVzcGFjaWFsZXMgY29uIHN0X3dyaXRlDQojIyMjIyBTZSB1c2EgbGEgZnVuY2nDs24gc3Rfd3JpdGUoKSBwYXJhIGd1YXJkYXIgZWwgb2JqZXRvICoqY29sb21iaWEqKiBlbiBmb3JtYXRvICoqZ3BrZyoqLiBMdWVnbywgc2UgdmVyaWZpY2EgcXVlIGVsIG51ZXZvIGFyY2hpdm8gZ2VvcGFja2FnZSBzZSBoYXlhIGNyZWFkbyBjb3JyZWN0YW1lbnRlLCBwYXJhIGRlc3B1w6lzIHJlbGl6YXIgdW5hIG51ZXZhIGxlY3R1cmEuDQoNCmBgYHtyfQ0Kc3Rfd3JpdGUoY29sb21iaWEsICJtdW5pY2lwaW9zLmdwa2ciLCBkcml2ZXIgPSAiR1BLRyIsIGFwcGVuZCA9IEYpDQpgYGANCg0KYGBge3J9DQpsaXN0LmZpbGVzKHBhdHRlcm49Imdwa2ciKQ0KYGBgDQoNCmBgYHtyfQ0KY29sb21iaWEyIDwtIHN0X3JlYWQoIi4vbXVuaWNpcGlvcy5ncGtnIikNCmBgYA0KDQojIDQuIFNlbGVjY2lvbmFyIGRlcGFydGFtZW50bw0KIyMjIDQuMS4gU2VsZWNjaW9uYXIgcG9yIGF0cmlidXRvDQojIyMjIyBQYXJhIHJlYWxpemFyIGxhIHNlbGVjY2nDs24gcG9yIGF0cmlidXRvLCBzZSB1dGlsaXphIGxhIGZ1bmNpw7NuIGZpbHRlcigpLCBlc3BlY2lmaWNhbmRvIGxvcyBjcml0ZXJpb3MgbmNlc2FyaW9zIHBhcmEgc2VsZWNjaW9uYXIgw7puaWNhbWVudGUgbG9zIG11bmljaXBpb3MgZGUgQm95YWPDoS4NCg0KYGBge3J9DQpybWFya2Rvd246OnBhZ2VkX3RhYmxlKChib3lhY2EgPC0gZHBseXI6OmZpbHRlcihjb2xvbWJpYSwgZHB0b19jbm1icj09IkJPWUFDw4EiKSkpDQpgYGANCg0KIyMjIyMgRGVzcHXDqXMgZGUgdmVyaWZpY2FyIHF1ZSBsYSBpbmZvcm1jYWnDs24gY29pbmNpZGUgY29uIGxhIGluZm9ybWFjacOzbiBkZWwgZGVwYXJ0YW1lbnRvIGRlIEJveWFjw6EsIHNlIGNvbnN0cnV5ZSB1biBncsOhZmljbyBzZW5jaWxsbyBjb24gbG9zIHBvbMOtZ29ub3MgZGUgc3VzIG11bmljaXBpb3MuDQoNCmBgYHtyIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFfQ0KcGxvdChzdF9nZW9tZXRyeShib3lhY2EpLCBjb2wgPSBzZi5jb2xvcnMoMTIsIGNhdGVnb3JpY2FsID0gVFJVRSksIGJvcmRlciA9ICdncmV5JywgDQogICAgIGF4ZXMgPSBUUlVFKQ0KcGxvdChzdF9nZW9tZXRyeShzdF9jZW50cm9pZChib3lhY2EpKSwgcGNoID0gMywgY29sID0gJ3JlZCcsIGFkZCA9IFRSVUUpDQpgYGANCg0KIyMjIyMgUG9yIMO6bHRpbW8sIGxvcyBwb2zDrWdvbm9zIHNlbGVjY2lvbmFkb3Mgc2UgZ3VhcmRhbiBlbiB1biBudWV2byBhcmNoaXZvIGdlb3BhY2thZ2UuDQoNCmBgYHtyfQ0Kc3Rfd3JpdGUoYm95YWNhLCAiYm95YWNhX211bmljLmdwa2ciLCBkcml2ZXIgPSAiR1BLRyIsIGFwcGVuZCA9IEYpDQpgYGANCg0KIyA1LiBTZWxlY2Npb25hciBwb3IgdWJpY2FjacOzbg0KIyMjIyMgU2UgdXRpbGl6YSBsYSBmdW5jacOzbiBkZSBzZWxlY2Npw7NuIHBvciB1YmljYWNpw7NuIGNvbiB1biBhcmNoaXZvIENTViBxdWUgY29udGllbmUgbG9zIGRhdG9zIGRlIGxhcyBjaXVkYWRlcyBkZWwgbXVuZG8uIFByaW1lcm8sIHNlIGxlZSBlbCBhcmNoaXZvIHkgc2UgY29udmllcnRlIGVuIHVuIG9iamV0byBlc3BhY2lhbCBjb24gYHN0X2FzX3NmKClgIGVzcGVjaWZpY2FuZG8gbGFzIGNvbHVtbmFzIGRlICoqbG9uZ2l0dWQqKiB5ICoqbGF0aXR1ZCoqLCBqdW50byBhbCBzaXN0ZW1hIGRlIHJlZmVyZW5jaWEgRVBTRzo0MzI2Lg0KDQpgYGB7cn0NCmNpdGllcyA9IHJlYWQuY3N2KCdEOi9HQjIvUDMvTm90ZWJvb2svc2ltcGxlbWFwc193b3JsZGNpdGllc19iYXNpY3YxLjc3L3dvcmxkY2l0aWVzLmNzdicpICU+JQ0KICBzdF9hc19zZihjb29yZHM9YygibG5nIiwibGF0IiksIGNycz00MzI2KQ0KYGBgDQoNCiMjIyMjIEEgY29udGludWFjacOzbiwgc2UgdmlzdWFsaXphIGVsIGNvbnRlbmlkbyBkZSBsYSB2YXJpYWJsZSAqKmNpdGllcyoqLg0KDQpgYGB7cn0NCnJtYXJrZG93bjo6cGFnZWRfdGFibGUoY2l0aWVzKQ0KYGBgDQoNCiMjIyMjIFNlIHZlcmlmaWNhIHF1ZSBsb3MgQ1JTIGRlIGFtYm9zIGNvbmp1bnRvcyBkZSBkYXRvcyAoY2l0aWVzIHkgYm95YWNhKSBjb2luY2lkYW4uDQoNCmBgYHtyfQ0Kc3RfY3JzKGNpdGllcykkZXBzZw0KYGBgDQoNCmBgYHtyfQ0Kc3RfY3JzKGJveWFjYSkkZXBzZw0KYGBgDQoNCiMjIyMjIERlIG5vIHNlciBhc8OtLCBzZSBkZWJlIHRyYW5zZm9ybWFyIGVsIENSUyBkZSAqY2l0aWVzKiBwYXJhIHF1ZSBjb2luY2lkYSBjb24gZWwgQ1JTIGRlIGJveWFjYSwgdXRpbGl6YW5kbyBsYSBmdW5jacOzbiBzdF90cmFuc2Zvcm0oKS4NCg0KYGBge3J9DQpuY2l0aWVzIDwtIHN0X3RyYW5zZm9ybShjaXRpZXMsIGNycz0gc3RfY3JzKGJveWFjYSkpDQpgYGANCg0KIyMjIyMgTHVlZ28sIHNlIGNyZWEgbGEgdmFyaWFibGUgKipib3lhY2FfY2l0aWVzKiogcGFyYSBndWFyZGFyIMO6bmljYW1lbnRlIGxhcyBjaXVkYWRlcyBkZWwgZGVwYXJ0YW1lbnRvIGRlIEJveWFjw6EuIFBhcmEgbGEgc2VsZWNjacOzbiBzZSB1c2Egc3Rfd2l0aGluLg0KDQpgYGB7cn0NCmJveWFjYV9jaXRpZXMgPC0gbmNpdGllc1tib3lhY2EsICwgb3AgPSBzdF93aXRoaW5dDQpgYGANCg0KIyMjIyMgVW5hIHZleiBoZWNoYSBsYSB0cmFuc2Zvcm1hY2nDs24sIHNlIGNvbnN0cnV5ZSB1biBncsOhZmljbyBtw6FzIGRldGFsbGFkbyBxdWUgZWwgYW50ZXJpb3IsIGRvbmRlIHNlIG11ZXN0cmEgbG9zIG11bmljaXBpb3MgZGVsIGRlcGFydGFtZW50bywgeSBjb24gcHVudG9zLCBzdXMgY2l1ZGFkZXMuDQoNCmBgYHtyfQ0KcGxvdChzdF9nZW9tZXRyeShib3lhY2EpLCBjb2wgPSBzZi5jb2xvcnMoMTIsIGNhdGVnb3JpY2FsID0gVFJVRSksIGJvcmRlciA9ICdncmV5JywgYXhlcyA9IFRSVUUpDQpwbG90KHN0X2dlb21ldHJ5KGJveWFjYV9jaXRpZXMpLCBwY2ggPSAyMCwgY29sID0gJ3JlZCcsIGFkZCA9IFRSVUUpDQpgYGANCg0KIyA2LiBHcsOhZmljYSBkZXRhbGxhZGENCiMjIyA2LjEuIHVzYW5kbyBnZ3Bsb3QNCiMjIyMjIEFob3JhLCBzZSB1dGlsaXphICoqZ2dwbG90KiogcGFyYSBnZW5lcmFyIHVuIGdyw6FmaWNvIG3DoXMgZXN0w6l0aWNvIGRlIGxvcyBtdW5pY2lwaW9zIGRlbCBkZXBhcnRhbWVudG8gZGUgQm95YWPDoSB5IGRlIHN1cyBjaXVkYWRlcy4NCg0KIyMjIyMgU2UgcmVwcmVzZW50YSBlbCBjb250b3JubyBkZSBsb3MgbXVuaWNpcGlvcyBjb24gKipnZW9tX3NmKCkqKiwgeSBzZSBhw7FhZGVuIGxhcyBjaXVkYWRlcyBtZWRpYW50ZSB1bmEgY2FwYSBhZGljaW9uYWwgY29uIHB1bnRvcyBxdWUgdmFyw61hbiBzZWfDum4gZWwgbm9tYnJlIGRlIGxhIGNpdWRhZC4NCg0KYGBge3IgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0V9DQpnZ3Bsb3QoKSArDQogICNBZGQgIG11bmljaXBhbGl0aWVzDQogIGdlb21fc2YoZGF0YSA9IGJveWFjYSkgKw0KICAjQWRkIGNpdGllcyBsYXllcg0KICBnZW9tX3NmKGRhdGEgPSBib3lhY2FfY2l0aWVzLCBhZXMoY29sb3IgPSBjaXR5LCBsYWJlbCA9IGNpdHkpLCBzaXplID0gMykgKw0KICAjQWRkIHRpdGxlcw0KICBsYWJzKHggPSAiTG9uZ2l0dWQiLCB5ID0gIkxhdGl0dWQiLCB0aXRsZSA9ICJDaXVkYWRlcyBkZSBCb3lhY8OhIikgKw0KICAjQWRkIHRoZW1lDQogIHRoZW1lX2J3KCkNCmBgYA0KDQojIyMjIyBGaW5hbG1lbnRlLCBzZSBtZWpvcmEgbGEgcHJlc2VudGFjacOzbiBkZWwgbWFwYSBhZ3JlZ2FuZG8gdW5hIGJhcnJhIGRlIGVzY2FsYSB5IHVuYSBmbGVjaGEgZGUgbm9ydGUgbWVkaWFudGUgZWwgcGFxdWV0ZSBnZ3NwYXRpYWwuIERlIGVzdGEgbWFuZXJhIHNlIG9idGllbmUgZWwgbWFwYSBmaW5hbCBjb24gbG9zIG11bmljaXBpb3MgeSBsYXMgY2l1ZGFkZXMgZGVsIGRlcGFydGFtZW50byBkZSBCb3lhY8OhIHJlcHJlc2VudGFkb3MgZGUgZm9ybWEgY2xhcmEgeSBlc3TDqXRpY2EuDQoNCmBgYHtyIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFfQ0KZ2dwbG90KCkgKw0KICAjQ3JvcCBWaXJnaW5pYSBib3VuZGFyeSB0byBzcGF0aWFsIGV4dGVudCBvZiBjaXRpZXMgYW5kIGFkZCBWaXJnaW5pYSBsYXllcg0KICBnZW9tX3NmKGRhdGEgPSBib3lhY2EpICsNCiAgI0FkZCBjaXRpZXMgbGF5ZXINCiAgZ2VvbV9zZihkYXRhID0gYm95YWNhX2NpdGllcywgYWVzKGNvbG9yID0gY2l0eSwgbGFiZWwgPSBjaXR5KSwgc2l6ZSA9IDMpICsNCiAgI0FkZCBzY2FsZSBiYXIgdG8gYm90dG9tIGxlZnQgZnJvbSBnZ3NwYXRpYWwNCiAgYW5ub3RhdGlvbl9zY2FsZShsb2NhdGlvbiA9ICJ0bCIsIGhlaWdodCA9IHVuaXQoLjI1LCAiY20iKSwgDQogICAgICAgICAgICAgICAgICAgd2lkdGggPSB1bml0KDEsICJjbSIpLCBwYWRfeCA9IHVuaXQoMC4zLCAiaW4iKSwgDQogICAgICAgICAgICAgICAgICAgcGFkX3kgPSB1bml0KDAuNSwgImluIikpICsNCiAgI0FkZCBub3J0aCBhcnJvdyB0byBib3R0b20gbGVmdCBmcm9tIGdnc3BhdGlhbA0KICBhbm5vdGF0aW9uX25vcnRoX2Fycm93KGhlaWdodCA9IHVuaXQoMSwgImNtIiksIHdpZHRoID0gdW5pdCgxLCAiY20iKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICB3aGljaF9ub3J0aCA9ICJ0cnVlIiwgbG9jYXRpb24gPSAidGwiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICBwYWRfeCA9IHVuaXQoMC41LCAiaW4iKSwgcGFkX3kgPSB1bml0KDAuMDUsICJpbiIpKSArDQogICNBZGQgdGl0bGVzDQogIGxhYnMoeCA9ICJMb25naXR1ZCIsIHkgPSAiTGF0aXR1ZCIsIHRpdGxlID0gIkNpdWRhZGVzIGRlIEJveWFjw6EiKSArDQogICNBZGQgdGhlbWUNCiAgdGhlbWVfYncoKQ0KYGBgDQoNCiMgNy4gRGV0YWxsZXMgZGVsIGVudG9ybm8gY29tcHV0YWNpb25hbA0KDQpgYGB7cn0NCnNlc3Npb25JbmZvKCkNCmBgYA0KDQo=