1. Introducción
En este cuaderno utilizaremos como fuente de datos la Evaluaciones
Agropecuarias Municipales - EVA (2007-2018), un conjunto de datos
proporcionado por el Ministerio de Agricultura y Desarrollo Rural para
ilustrar algunos datos estadísticos relacionados al cultivo de yuca en
el municipio de Turbo del departamento de Antioquia.
Para esto, también vamos a utilizar las principales funcionalidades
de la biblioteca dplyr. Las cuales son:
- mutate: añade nuevas variables que son funciones de variables
existentes.
- select: selecciona variables basándose en sus nombres.
- filter: selecciona casos basándose en sus valores.
- summarise: creduce múltiples valores a un único resumen.
- arrange: cambia el orden de las filas.
Todas éstas funciones se combinan de forma natural con group_by, que
permite realizar cualquier operación “por grupo”.
2. Configuración
Primero se deben instalar las librerías requeridas:
- install.packages (“tidyverse”)
- install.packages (“readxl”)
- install.packages (“dplyr”)
- install.packages (“ggplot2”)
4. Leer el conjunto de datos EVA
list.files()
[1] "EVA.nb.html" "EVA.Rmd" "EVA_Antioquia.csv"
(eva = read.csv("./EVA_Antioquia.csv"))
En la tabla se pueden observar datos estadísticos de diferentes años,
cultivos, municipios, entre otros más específicos.
Ahora vamos a revisar los nombres que le da el propio software a las
diferentes características allí expuestas.
names(eva)
[1] "CÓD...DEP."
[2] "DEPARTAMENTO"
[3] "CÓD..MUN."
[4] "MUNICIPIO"
[5] "GRUPO..DE.CULTIVO"
[6] "SUBGRUPO..DE.CULTIVO"
[7] "CULTIVO"
[8] "DESAGREGACIÓN.REGIONAL.Y.O.SISTEMA.PRODUCTIVO"
[9] "AÑO"
[10] "PERIODO"
[11] "Área.Sembrada..ha."
[12] "Área.Cosechada..ha."
[13] "Producción..t."
[14] "Rendimiento..t.ha."
[15] "ESTADO.FISICO.PRODUCCION"
[16] "NOMBRE..CIENTIFICO"
[17] "CICLO.DE.CULTIVO"
5. Limpiar los datos EVA
Vamos a seleccionar aquellos atributos de nuestro interés:
(eva %>% dplyr::select("CÓD..MUN.":"ESTADO.FISICO.PRODUCCION") -> eva.tmp)
eva.tmp
Ahora comprobamos la salida del objeto y verificamos que se hayan
seleccionado los objetos de nuestro interés.
A continuación vamos a cambiar los nombres de algunas de las
columnas, teniendo en cuenta usar los nombres que están en el objeto
eva.tmp:
(eva.tmp %>% dplyr::rename("Cod_Mun" = "CÓD..MUN.",
"Grupo" = "GRUPO..DE.CULTIVO",
"Municipio" = "MUNICIPIO",
"Subgrupo" = "SUBGRUPO..DE.CULTIVO",
"Cultivo" = "CULTIVO",
"Year" = "AÑO",
"Periodo" = "PERIODO",
"Area_Sembrada" = "Área.Sembrada..ha.",
"Area_Cosechada" = "Área.Cosechada..ha.",
"Produccion" = "Producción..t.", "Rendimiento" = "Rendimiento..t.ha.",
"Sistema" = "DESAGREGACIÓN.REGIONAL.Y.O.SISTEMA.PRODUCTIVO",
"Estado" = "ESTADO.FISICO.PRODUCCION")) -> new_eva
new_eva
Ahora, comprobamos que la tabla anterior tenga los atributos
cuantitativos como tipos de datos numéricos (no como tipos de datos de
cadena).
6. Análisis de datos
Los análisis de datos pueden utilizarse de manera:
dividir-aplicar-combinar, así, dividir los datos en grupos, aplicar
algún análisis a cada grupo y combinar los resultados.
De esta manera, como ya fueron mencionadas las funciones de la
biblioteca dplyr, vamos a ponerlas en acción.
6.1 Los cultivos más importantes en el periodo de 2007-2018
- Si queremos conocer la producción total por grupo de cultivos
new_eva %>%
##filter(Produccion > 0) %>%
group_by(Grupo) %>%
summarize(Total_produccion = sum(Produccion)) %>%
arrange(desc(Total_produccion))
Ya con estos datos obtenidos podemos observar que los frutales son el
cultivo de mayor producción en el departamento seguido por los
tubérculos y los plátanos. Por otro lado, los de menor producción en
este periodo (2007-2018) fueron las plantas aromáticas, condimentarias y
medicinales.
Para guardar la producción total en un objeto:
new_eva %>%
group_by(Grupo) %>%
summarize(Total_produccion = sum(Produccion)) -> PT
Para filtrar las producciones más importantes:
PT %>%
filter(Total_produccion > 1000000) -> main.groups
Para conocer la producción total de los principales grupos de
cultivos:
(value = sum(main.groups$Total_produccion))
[1] 36312945
Para añadir un nuevo atributo con el porcentaje de la producción
total:
main.groups$percent = main.groups$Total_produccion/value
Para crear un gráfico circular de la producción total de
main.groups:
bp<- ggplot(main.groups, aes(x="", y=percent, fill=Grupo))+
geom_bar(width = 1, stat = "identity")
pie <- bp + coord_polar("y", start=0)
pie

6.2 El municipio y cultivo con mayor producción en el periodo de
2007-2018
- Producción de cada grupo de cultivos: municipios que lideran la
producción en cada uno de los cultivos del departamento.
new_eva %>%
group_by(Grupo, Municipio) %>%
summarize(Total_Prod = sum(Produccion, na.rm = TRUE)) %>%
slice(which.max(Total_Prod)) %>%
arrange(desc(Total_Prod))
`summarise()` has grouped output by 'Grupo'. You can override using the `.groups` argument.
Para guardar el objeto:
new_eva %>%
group_by(Grupo, Municipio) %>%
summarize(Total_Prod = sum(Produccion, na.rm = TRUE)) %>%
slice(which.max(Total_Prod)) -> leaders
`summarise()` has grouped output by 'Grupo'. You can override using the `.groups` argument.
leaders
Aquí vamos a filtrar los municipios más importantes desde el punto de
vista agrícola:
leaders %>%
filter(Total_Prod > 100000) -> main.leaders
Vamos a trazar los líderes filtrados:
p<-ggplot(data=main.leaders, aes(x=Municipio, y=Total_Prod)) +
geom_bar(stat="identity")
p

6.3 Dinámica de un cultivo importante entre 2007 y 2018
new_eva %>%
filter(Municipio=="TURBO" & CULTIVO=="YUCA") %>%
group_by(Year, Cultivo) %>%
select(Municipio, Cultivo, Produccion, Year) -> Turbo_Yuca
Comprobamos:
Turbo_Yuca
En seguida haremos un gráfico de la producción de yuca en el
municipio de Turbo durante todo el periodo cubierto por el conjunto de
datos EVA:
g <- ggplot(aes(x=Year, y=Produccion/1000), data = Turbo_Yuca) + geom_bar(stat='identity') + labs(y='Produccion de Yuca [Ton x 1000]')
Añadimos un título y visualizamos:
g + ggtitle("Producción de yuca en el municipio de Turbo en el periodo de 2007-2018") + labs(caption= "Basado en datos de EVA (Minagricultura, 2023)")

6.4 Área sembrada y cosechada de yuca en Turbo (2007 y 2018)
new_eva %>%
filter(Municipio=="TURBO" & Cultivo=="YUCA") %>%
group_by(Year, Cultivo) %>%
select(Municipio, Cultivo, Area_Sembrada, Area_Cosechada, Year) -> Turbo_Yuca_SemyCos
Turbo_Yuca_SemyCos
7. Datos adicionales de los cultivos producidos en Turbo
Por último, se muestran algunos datos de relevancia en el municipio
de Turbo Antioquia como lo son los cultivos producidos allí y aquellos
de mayor y menor producción.
7.1 Cultivos producidos en el municipio de Turbo (Antioquia)
new_eva %>%
filter(Municipio=="TURBO") %>%
group_by(Cultivo) %>%
select(Municipio, Cultivo, Produccion, Rendimiento) -> Turbo_Cultivos
Turbo_Cultivos
7.2 Cultivos de mayor y menor producción en el municipio de Turbo
(Antioquia)
p<-ggplot(data=main.leaders, aes(x=Cultivo, y=Total_Prod)) +
geom_bar(stat="identity")
new_eva %>%
group_by(Cultivo) %>%
summarize(Total_Prod = sum(Produccion, na.rm = TRUE)) %>%
slice(which.max(Total_Prod)) -> Cultivo_Max
Cultivo_Max
new_eva %>%
group_by(Cultivo) %>%
summarize(Total_Prod = sum(Produccion, na.rm = TRUE)) %>%
slice(which.min(Total_Prod)) -> Cultivo_Min
Cultivo_Min
8. BIBLIOGRAFÍA
sessionInfo()
R version 4.3.1 (2023-06-16 ucrt)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19045)
Matrix products: default
locale:
[1] LC_COLLATE=Spanish_Colombia.utf8 LC_CTYPE=Spanish_Colombia.utf8
[3] LC_MONETARY=Spanish_Colombia.utf8 LC_NUMERIC=C
[5] 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] readxl_1.4.3 lubridate_1.9.2 forcats_1.0.0 stringr_1.5.0 dplyr_1.1.3
[6] purrr_1.0.2 readr_2.1.4 tidyr_1.3.0 tibble_3.2.1 ggplot2_3.4.3
[11] tidyverse_2.0.0
loaded via a namespace (and not attached):
[1] sass_0.4.7 utf8_1.2.3 generics_0.1.3 stringi_1.7.12
[5] hms_1.1.3 digest_0.6.33 magrittr_2.0.3 evaluate_0.21
[9] grid_4.3.1 timechange_0.2.0 fastmap_1.1.1 cellranger_1.1.0
[13] jsonlite_1.8.7 fansi_1.0.4 scales_1.2.1 jquerylib_0.1.4
[17] cli_3.6.1 crayon_1.5.2 rlang_1.1.1 bit64_4.0.5
[21] munsell_0.5.0 withr_2.5.0 cachem_1.0.8 yaml_2.3.7
[25] parallel_4.3.1 tools_4.3.1 tzdb_0.4.0 colorspace_2.1-0
[29] vctrs_0.6.3 R6_2.5.1 lifecycle_1.0.3 bit_4.0.5
[33] vroom_1.6.3 pkgconfig_2.0.3 pillar_1.9.0 bslib_0.5.1
[37] gtable_0.3.4 glue_1.6.2 xfun_0.40 tidyselect_1.2.0
[41] rstudioapi_0.15.0 knitr_1.44 farver_2.1.1 htmltools_0.5.6
[45] labeling_0.4.3 rmarkdown_2.25 compiler_4.3.1
LS0tDQp0aXRsZTogIlByb2R1Y2Npw7NuIGRlbCBjdWx0aXZvIGRlIHl1Y2EgZW4gZWwgbXVuaWNpcGlvIGRlIFR1cmJvLUFudGlvcXVpYSINCmF1dGhvcjogIk5hdGFsaWEgQWxmb25zbyBNYXJ0w61uZXoiDQpkYXRlOiAiMTkvMDkvMjAyMyINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KICBodG1sX2RvY3VtZW50Og0KICAgIGRmX3ByaW50OiBwYWdlZA0KICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQNCi0tLQ0KDQojIyAxLiBJbnRyb2R1Y2Npw7NuIA0KDQpFbiBlc3RlIGN1YWRlcm5vIHV0aWxpemFyZW1vcyBjb21vIGZ1ZW50ZSBkZSBkYXRvcyBsYSBFdmFsdWFjaW9uZXMgQWdyb3BlY3VhcmlhcyBNdW5pY2lwYWxlcyAtIEVWQSAoMjAwNy0yMDE4KSwgdW4gY29uanVudG8gZGUgZGF0b3MgcHJvcG9yY2lvbmFkbyBwb3IgZWwgTWluaXN0ZXJpbyBkZSBBZ3JpY3VsdHVyYSB5IERlc2Fycm9sbG8gUnVyYWwgcGFyYSBpbHVzdHJhciBhbGd1bm9zIGRhdG9zIGVzdGFkw61zdGljb3MgcmVsYWNpb25hZG9zIGFsIGN1bHRpdm8gZGUgeXVjYSBlbiBlbCBtdW5pY2lwaW8gZGUgVHVyYm8gZGVsIGRlcGFydGFtZW50byBkZSBBbnRpb3F1aWEuDQoNClBhcmEgZXN0bywgdGFtYmnDqW4gdmFtb3MgYSB1dGlsaXphciBsYXMgcHJpbmNpcGFsZXMgZnVuY2lvbmFsaWRhZGVzIGRlIGxhIGJpYmxpb3RlY2EgZHBseXIuIExhcyBjdWFsZXMgc29uOg0KDQotIG11dGF0ZTogYcOxYWRlIG51ZXZhcyB2YXJpYWJsZXMgcXVlIHNvbiBmdW5jaW9uZXMgZGUgdmFyaWFibGVzIGV4aXN0ZW50ZXMuDQotIHNlbGVjdDogc2VsZWNjaW9uYSB2YXJpYWJsZXMgYmFzw6FuZG9zZSBlbiBzdXMgbm9tYnJlcy4NCi0gZmlsdGVyOiBzZWxlY2Npb25hIGNhc29zIGJhc8OhbmRvc2UgZW4gc3VzIHZhbG9yZXMuDQotIHN1bW1hcmlzZTogY3JlZHVjZSBtw7psdGlwbGVzIHZhbG9yZXMgYSB1biDDum5pY28gcmVzdW1lbi4NCi0gYXJyYW5nZTogY2FtYmlhIGVsIG9yZGVuIGRlIGxhcyBmaWxhcy4NCg0KVG9kYXMgw6lzdGFzIGZ1bmNpb25lcyBzZSBjb21iaW5hbiBkZSBmb3JtYSBuYXR1cmFsIGNvbiBncm91cF9ieSwgcXVlIHBlcm1pdGUgcmVhbGl6YXIgY3VhbHF1aWVyIG9wZXJhY2nDs24gInBvciBncnVwbyIuDQoNCg0KIyMgMi4gQ29uZmlndXJhY2nDs24NCg0KUHJpbWVybyBzZSBkZWJlbiBpbnN0YWxhciBsYXMgbGlicmVyw61hcyByZXF1ZXJpZGFzOg0KDQotIGluc3RhbGwucGFja2FnZXMgKCJ0aWR5dmVyc2UiKQ0KLSBpbnN0YWxsLnBhY2thZ2VzICgicmVhZHhsIikNCi0gaW5zdGFsbC5wYWNrYWdlcyAoImRwbHlyIikNCi0gaW5zdGFsbC5wYWNrYWdlcyAoImdncGxvdDIiKQ0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KYGBgDQpgYGB7cn0NCmxpYnJhcnkoZHBseXIpDQpgYGANCmBgYHtyfQ0KbGlicmFyeShyZWFkcikNCmBgYA0KYGBge3J9DQpsaWJyYXJ5KHJlYWR4bCkNCmBgYA0KYGBge3J9DQpsaWJyYXJ5KGdncGxvdDIpDQpgYGANCg0KDQojIyAzLiBEZXNjYXJnYXIgZWwgY29uanVudG8gZGUgZGF0b3MgRVZBIHBhcmEgZWwgZGVwYXJ0YW1lbnRvIHNlbGVjY2lvbmFkbyAoQW50aW9xdWlhKQ0KDQpJciBhbCBzaWd1aWVudGUgZW5sYWNlOiBodHRwczovL3d3dy5kYXRvcy5nb3YuY28vQWdyaWN1bHR1cmEteS1EZXNhcnJvbGxvLVJ1cmFsL0V2YWx1YWNpb25lcy1BZ3JvcGVjdWFyaWFzLU11bmljaXBhbGVzLUVWQS8ycG53LW1tZ2UvZGF0YQ0KDQpFbiBlbCBzaXRpbyB3ZWIgZmlsdHJhciB5IGRlc2NhcmdhciBsb3MgZGF0b3MgZGVsIGRlcGFydGFtZW50by4gQnVzY2FyIGVsIGFyY2hpdm8gZW4gZWwgZXF1aXBvIHkgbW92ZXJsbyBhbCBkaXJlY3RvcmlvIGVuIGRvbmRlIHNlIGVuY3VlbnRyYSBlbCB0cmFiYWpvIGVuIHByb2Nlc28uDQoNCg0KIyMgNC4gTGVlciBlbCBjb25qdW50byBkZSBkYXRvcyBFVkEgDQoNCmBgYHtyfQ0KbGlzdC5maWxlcygpDQpgYGANCmBgYHtyfQ0KKGV2YSA9IHJlYWQuY3N2KCIuL0VWQV9BbnRpb3F1aWEuY3N2IikpDQpgYGANCg0KRW4gbGEgdGFibGEgc2UgcHVlZGVuIG9ic2VydmFyIGRhdG9zIGVzdGFkw61zdGljb3MgZGUgZGlmZXJlbnRlcyBhw7FvcywgY3VsdGl2b3MsIG11bmljaXBpb3MsIGVudHJlIG90cm9zIG3DoXMgZXNwZWPDrWZpY29zLg0KDQpBaG9yYSB2YW1vcyBhIHJldmlzYXIgbG9zIG5vbWJyZXMgcXVlIGxlIGRhIGVsIHByb3BpbyBzb2Z0d2FyZSBhIGxhcyBkaWZlcmVudGVzIGNhcmFjdGVyw61zdGljYXMgYWxsw60gZXhwdWVzdGFzLg0KDQpgYGB7cn0NCm5hbWVzKGV2YSkNCmBgYA0KDQojIyA1LiBMaW1waWFyIGxvcyBkYXRvcyBFVkENCg0KVmFtb3MgYSBzZWxlY2Npb25hciBhcXVlbGxvcyBhdHJpYnV0b3MgZGUgbnVlc3RybyBpbnRlcsOpczoNCg0KYGBge3J9DQooZXZhICU+JSBkcGx5cjo6c2VsZWN0KCJDw5NELi5NVU4uIjoiRVNUQURPLkZJU0lDTy5QUk9EVUNDSU9OIikgLT4gZXZhLnRtcCkNCmBgYA0KYGBge3J9DQpldmEudG1wDQpgYGANCg0KQWhvcmEgY29tcHJvYmFtb3MgbGEgc2FsaWRhIGRlbCBvYmpldG8geSB2ZXJpZmljYW1vcyBxdWUgc2UgaGF5YW4gc2VsZWNjaW9uYWRvIGxvcyBvYmpldG9zIGRlIG51ZXN0cm8gaW50ZXLDqXMuDQoNCkEgY29udGludWFjacOzbiB2YW1vcyBhIGNhbWJpYXIgbG9zIG5vbWJyZXMgZGUgYWxndW5hcyBkZSBsYXMgY29sdW1uYXMsIHRlbmllbmRvIGVuIGN1ZW50YSB1c2FyIGxvcyBub21icmVzIHF1ZSBlc3TDoW4gZW4gZWwgb2JqZXRvIGV2YS50bXA6DQoNCmBgYHtyfQ0KKGV2YS50bXAgJT4lICBkcGx5cjo6cmVuYW1lKCJDb2RfTXVuIiA9ICJDw5NELi5NVU4uIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIkdydXBvIiA9ICJHUlVQTy4uREUuQ1VMVElWTyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIk11bmljaXBpbyIgPSAiTVVOSUNJUElPIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAiU3ViZ3J1cG8iID0gIlNVQkdSVVBPLi5ERS5DVUxUSVZPIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAiQ3VsdGl2byIgPSAiQ1VMVElWTyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIlllYXIiID0gIkHDkU8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICJQZXJpb2RvIiA9ICJQRVJJT0RPIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAiQXJlYV9TZW1icmFkYSIgPSAiw4FyZWEuU2VtYnJhZGEuLmhhLiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIkFyZWFfQ29zZWNoYWRhIiA9ICLDgXJlYS5Db3NlY2hhZGEuLmhhLiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIlByb2R1Y2Npb24iID0gIlByb2R1Y2Npw7NuLi50LiIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZW5kaW1pZW50byIgPSAiUmVuZGltaWVudG8uLnQuaGEuIiwgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAiU2lzdGVtYSIgPSAiREVTQUdSRUdBQ0nDk04uUkVHSU9OQUwuWS5PLlNJU1RFTUEuUFJPRFVDVElWTyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIkVzdGFkbyIgPSAiRVNUQURPLkZJU0lDTy5QUk9EVUNDSU9OIikpIC0+IG5ld19ldmENCmBgYA0KDQpgYGB7cn0NCm5ld19ldmENCmBgYA0KQWhvcmEsIGNvbXByb2JhbW9zIHF1ZSBsYSB0YWJsYSBhbnRlcmlvciB0ZW5nYSBsb3MgYXRyaWJ1dG9zIGN1YW50aXRhdGl2b3MgY29tbyB0aXBvcyBkZSBkYXRvcyBudW3DqXJpY29zIChubyBjb21vIHRpcG9zIGRlIGRhdG9zIGRlIGNhZGVuYSkuDQoNCg0KIyMgNi4gQW7DoWxpc2lzIGRlIGRhdG9zDQoNCkxvcyBhbsOhbGlzaXMgZGUgZGF0b3MgcHVlZGVuIHV0aWxpemFyc2UgZGUgbWFuZXJhOiBkaXZpZGlyLWFwbGljYXItY29tYmluYXIsIGFzw60sIGRpdmlkaXIgbG9zIGRhdG9zIGVuIGdydXBvcywgYXBsaWNhciBhbGfDum4gYW7DoWxpc2lzIGEgY2FkYSBncnVwbyB5IGNvbWJpbmFyIGxvcyByZXN1bHRhZG9zLg0KDQpEZSBlc3RhIG1hbmVyYSwgY29tbyB5YSBmdWVyb24gbWVuY2lvbmFkYXMgbGFzIGZ1bmNpb25lcyBkZSBsYSBiaWJsaW90ZWNhIGRwbHlyLCB2YW1vcyBhIHBvbmVybGFzIGVuIGFjY2nDs24uDQoNCiMjIyA2LjEgTG9zIGN1bHRpdm9zIG3DoXMgaW1wb3J0YW50ZXMgZW4gZWwgcGVyaW9kbyBkZSAyMDA3LTIwMTgNCg0KLSBTaSBxdWVyZW1vcyBjb25vY2VyIGxhIHByb2R1Y2Npw7NuIHRvdGFsIHBvciBncnVwbyBkZSBjdWx0aXZvcw0KDQpgYGB7cn0NCm5ld19ldmEgJT4lDQogICMjZmlsdGVyKFByb2R1Y2Npb24gPiAwKSAlPiUNCiAgZ3JvdXBfYnkoR3J1cG8pICU+JQ0KICBzdW1tYXJpemUoVG90YWxfcHJvZHVjY2lvbiA9IHN1bShQcm9kdWNjaW9uKSkgJT4lIA0KICBhcnJhbmdlKGRlc2MoVG90YWxfcHJvZHVjY2lvbikpIA0KYGBgDQoNCllhIGNvbiBlc3RvcyBkYXRvcyBvYnRlbmlkb3MgcG9kZW1vcyBvYnNlcnZhciBxdWUgbG9zIGZydXRhbGVzIHNvbiBlbCBjdWx0aXZvIGRlIG1heW9yIHByb2R1Y2Npw7NuIGVuIGVsIGRlcGFydGFtZW50byBzZWd1aWRvIHBvciBsb3MgdHViw6lyY3Vsb3MgeSBsb3MgcGzDoXRhbm9zLiBQb3Igb3RybyBsYWRvLCBsb3MgZGUgbWVub3IgcHJvZHVjY2nDs24gZW4gZXN0ZSBwZXJpb2RvICgyMDA3LTIwMTgpIGZ1ZXJvbiBsYXMgcGxhbnRhcyBhcm9tw6F0aWNhcywgY29uZGltZW50YXJpYXMgeSBtZWRpY2luYWxlcy4NCg0KUGFyYSBndWFyZGFyIGxhIHByb2R1Y2Npw7NuIHRvdGFsIGVuIHVuIG9iamV0bzoNCg0KYGBge3J9DQpuZXdfZXZhICU+JQ0KICBncm91cF9ieShHcnVwbykgJT4lDQogIHN1bW1hcml6ZShUb3RhbF9wcm9kdWNjaW9uID0gc3VtKFByb2R1Y2Npb24pKSAtPiBQVCANCmBgYA0KDQpQYXJhIGZpbHRyYXIgbGFzIHByb2R1Y2Npb25lcyBtw6FzIGltcG9ydGFudGVzOg0KDQpgYGB7cn0NClBUICU+JSANCiAgZmlsdGVyKFRvdGFsX3Byb2R1Y2Npb24gPiAxMDAwMDAwKSAtPiBtYWluLmdyb3Vwcw0KYGBgDQoNClBhcmEgY29ub2NlciBsYSBwcm9kdWNjacOzbiB0b3RhbCBkZSBsb3MgcHJpbmNpcGFsZXMgZ3J1cG9zIGRlIGN1bHRpdm9zOg0KDQpgYGB7cn0NCih2YWx1ZSA9IHN1bShtYWluLmdyb3VwcyRUb3RhbF9wcm9kdWNjaW9uKSkNCmBgYA0KUGFyYSBhw7FhZGlyIHVuIG51ZXZvIGF0cmlidXRvIGNvbiBlbCBwb3JjZW50YWplIGRlIGxhIHByb2R1Y2Npw7NuIHRvdGFsOg0KDQpgYGB7cn0NCm1haW4uZ3JvdXBzJHBlcmNlbnQgPSBtYWluLmdyb3VwcyRUb3RhbF9wcm9kdWNjaW9uL3ZhbHVlDQpgYGANCg0KUGFyYSBjcmVhciB1biBncsOhZmljbyBjaXJjdWxhciBkZSBsYSBwcm9kdWNjacOzbiB0b3RhbCBkZSBtYWluLmdyb3VwczoNCg0KLSAqI2JhcnBsb3QqDQpgYGB7cn0NCmJwPC0gZ2dwbG90KG1haW4uZ3JvdXBzLCBhZXMoeD0iIiwgeT1wZXJjZW50LCBmaWxsPUdydXBvKSkrDQpnZW9tX2Jhcih3aWR0aCA9IDEsIHN0YXQgPSAiaWRlbnRpdHkiKQ0KYGBgDQoNCi0gKiNQaWVjaGFydCoNCmBgYHtyfQ0KcGllIDwtIGJwICsgY29vcmRfcG9sYXIoInkiLCBzdGFydD0wKQ0KcGllDQpgYGANCg0KIyMjIDYuMiBFbCBtdW5pY2lwaW8geSBjdWx0aXZvIGNvbiBtYXlvciBwcm9kdWNjacOzbiBlbiBlbCBwZXJpb2RvIGRlIDIwMDctMjAxOA0KDQotIFByb2R1Y2Npw7NuIGRlIGNhZGEgZ3J1cG8gZGUgY3VsdGl2b3M6IG11bmljaXBpb3MgcXVlIGxpZGVyYW4gbGEgcHJvZHVjY2nDs24gZW4gY2FkYSB1bm8gZGUgbG9zIGN1bHRpdm9zIGRlbCBkZXBhcnRhbWVudG8uDQoNCmBgYHtyfQ0KbmV3X2V2YSAlPiUNCiAgZ3JvdXBfYnkoR3J1cG8sIE11bmljaXBpbykgJT4lDQogIHN1bW1hcml6ZShUb3RhbF9Qcm9kID0gc3VtKFByb2R1Y2Npb24sIG5hLnJtID0gVFJVRSkpICU+JQ0KICBzbGljZSh3aGljaC5tYXgoVG90YWxfUHJvZCkpICAlPiUNCiAgYXJyYW5nZShkZXNjKFRvdGFsX1Byb2QpKQ0KYGBgDQpQYXJhIGd1YXJkYXIgZWwgb2JqZXRvOg0KDQpgYGB7cn0NCm5ld19ldmEgJT4lDQogIGdyb3VwX2J5KEdydXBvLCBNdW5pY2lwaW8pICU+JQ0KICBzdW1tYXJpemUoVG90YWxfUHJvZCA9IHN1bShQcm9kdWNjaW9uLCBuYS5ybSA9IFRSVUUpKSAlPiUNCiAgc2xpY2Uod2hpY2gubWF4KFRvdGFsX1Byb2QpKSAgLT4gbGVhZGVycw0KYGBgDQpgYGB7cn0NCmxlYWRlcnMNCmBgYA0KDQpBcXXDrSB2YW1vcyBhIGZpbHRyYXIgbG9zIG11bmljaXBpb3MgbcOhcyBpbXBvcnRhbnRlcyBkZXNkZSBlbCBwdW50byBkZSB2aXN0YSBhZ3LDrWNvbGE6DQoNCmBgYHtyfQ0KbGVhZGVycyAlPiUgDQogIGZpbHRlcihUb3RhbF9Qcm9kID4gMTAwMDAwKSAtPiBtYWluLmxlYWRlcnMNCmBgYA0KDQpWYW1vcyBhIHRyYXphciBsb3MgbMOtZGVyZXMgZmlsdHJhZG9zOg0KDQpgYGB7cn0NCnA8LWdncGxvdChkYXRhPW1haW4ubGVhZGVycywgYWVzKHg9TXVuaWNpcGlvLCB5PVRvdGFsX1Byb2QpKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikNCnANCmBgYA0KDQojIyMgNi4zIERpbsOhbWljYSBkZSB1biBjdWx0aXZvIGltcG9ydGFudGUgZW50cmUgMjAwNyB5IDIwMTgNCg0KYGBge3J9DQpuZXdfZXZhICU+JSANCiAgZmlsdGVyKE11bmljaXBpbz09IlRVUkJPIiAmIENVTFRJVk89PSJZVUNBIikgJT4lIA0KICBncm91cF9ieShZZWFyLCBDdWx0aXZvKSAlPiUNCiAgc2VsZWN0KE11bmljaXBpbywgQ3VsdGl2bywgUHJvZHVjY2lvbiwgWWVhcikgLT4gIFR1cmJvX1l1Y2ENCmBgYA0KDQpDb21wcm9iYW1vczoNCg0KYGBge3J9DQpUdXJib19ZdWNhDQpgYGANCg0KRW4gc2VndWlkYSBoYXJlbW9zIHVuIGdyw6FmaWNvIGRlIGxhIHByb2R1Y2Npw7NuIGRlIHl1Y2EgZW4gZWwgbXVuaWNpcGlvIGRlIFR1cmJvIGR1cmFudGUgdG9kbyBlbCBwZXJpb2RvIGN1YmllcnRvIHBvciBlbCBjb25qdW50byBkZSBkYXRvcyBFVkE6DQoNCmBgYHtyfQ0KZyA8LSBnZ3Bsb3QoYWVzKHg9WWVhciwgeT1Qcm9kdWNjaW9uLzEwMDApLCBkYXRhID0gVHVyYm9fWXVjYSkgKyBnZW9tX2JhcihzdGF0PSdpZGVudGl0eScpICsgbGFicyh5PSdQcm9kdWNjaW9uIGRlIFl1Y2EgW1RvbiB4IDEwMDBdJykNCmBgYA0KDQpBw7FhZGltb3MgdW4gdMOtdHVsbyB5IHZpc3VhbGl6YW1vczoNCg0KYGBge3J9DQpnICsgZ2d0aXRsZSgiUHJvZHVjY2nDs24gZGUgeXVjYSBlbiBlbCBtdW5pY2lwaW8gZGUgVHVyYm8gZW4gZWwgcGVyaW9kbyBkZSAyMDA3LTIwMTgiKSArIGxhYnMoY2FwdGlvbj0gIkJhc2FkbyBlbiBkYXRvcyBkZSBFVkEgIChNaW5hZ3JpY3VsdHVyYSwgMjAyMykiKQ0KYGBgDQojIyMgNi40IMOBcmVhIHNlbWJyYWRhIHkgY29zZWNoYWRhIGRlIHl1Y2EgZW4gVHVyYm8gKDIwMDcgeSAyMDE4KQ0KDQpgYGB7cn0NCm5ld19ldmEgJT4lIA0KICBmaWx0ZXIoTXVuaWNpcGlvPT0iVFVSQk8iICYgQ3VsdGl2bz09IllVQ0EiKSAlPiUgDQogIGdyb3VwX2J5KFllYXIsIEN1bHRpdm8pICU+JQ0KICBzZWxlY3QoTXVuaWNpcGlvLCBDdWx0aXZvLCBBcmVhX1NlbWJyYWRhLCBBcmVhX0Nvc2VjaGFkYSwgWWVhcikgLT4gIFR1cmJvX1l1Y2FfU2VteUNvcw0KYGBgDQoNCmBgYHtyfQ0KVHVyYm9fWXVjYV9TZW15Q29zDQpgYGANCg0KDQojIyA3LiBEYXRvcyBhZGljaW9uYWxlcyBkZSBsb3MgY3VsdGl2b3MgcHJvZHVjaWRvcyBlbiBUdXJibw0KDQpQb3Igw7psdGltbywgc2UgbXVlc3RyYW4gYWxndW5vcyBkYXRvcyBkZSByZWxldmFuY2lhIGVuIGVsIG11bmljaXBpbyBkZSBUdXJibyBBbnRpb3F1aWEgY29tbyBsbyBzb24gbG9zIGN1bHRpdm9zIHByb2R1Y2lkb3MgYWxsw60geSBhcXVlbGxvcyBkZSBtYXlvciB5IG1lbm9yIHByb2R1Y2Npw7NuLg0KDQojIyMgNy4xIEN1bHRpdm9zIHByb2R1Y2lkb3MgZW4gZWwgbXVuaWNpcGlvIGRlIFR1cmJvIChBbnRpb3F1aWEpDQoNCmBgYHtyfQ0KbmV3X2V2YSAlPiUgDQogIGZpbHRlcihNdW5pY2lwaW89PSJUVVJCTyIpICU+JSANCiAgZ3JvdXBfYnkoQ3VsdGl2bykgJT4lDQogIHNlbGVjdChNdW5pY2lwaW8sIEN1bHRpdm8sIFByb2R1Y2Npb24sIFJlbmRpbWllbnRvKSAtPiAgVHVyYm9fQ3VsdGl2b3MNCmBgYA0KDQpgYGB7cn0NClR1cmJvX0N1bHRpdm9zDQpgYGANCg0KIyMjIDcuMiBDdWx0aXZvcyBkZSBtYXlvciB5IG1lbm9yIHByb2R1Y2Npw7NuIGVuIGVsIG11bmljaXBpbyBkZSBUdXJibyAoQW50aW9xdWlhKQ0KDQpgYGB7cn0NCnA8LWdncGxvdChkYXRhPW1haW4ubGVhZGVycywgYWVzKHg9Q3VsdGl2bywgeT1Ub3RhbF9Qcm9kKSkgKw0KICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpDQpgYGANCg0KYGBge3J9DQpuZXdfZXZhICU+JQ0KICBncm91cF9ieShDdWx0aXZvKSAlPiUNCiAgc3VtbWFyaXplKFRvdGFsX1Byb2QgPSBzdW0oUHJvZHVjY2lvbiwgbmEucm0gPSBUUlVFKSkgJT4lDQogIHNsaWNlKHdoaWNoLm1heChUb3RhbF9Qcm9kKSkgIC0+IEN1bHRpdm9fTWF4DQpgYGANCg0KYGBge3J9DQpDdWx0aXZvX01heA0KYGBgDQpgYGB7cn0NCm5ld19ldmEgJT4lDQogIGdyb3VwX2J5KEN1bHRpdm8pICU+JQ0KICBzdW1tYXJpemUoVG90YWxfUHJvZCA9IHN1bShQcm9kdWNjaW9uLCBuYS5ybSA9IFRSVUUpKSAlPiUNCiAgc2xpY2Uod2hpY2gubWluKFRvdGFsX1Byb2QpKSAgLT4gQ3VsdGl2b19NaW4NCmBgYA0KDQpgYGB7cn0NCkN1bHRpdm9fTWluDQpgYGANCg0KDQoNCiMjIDguIEJJQkxJT0dSQUbDjUENCg0KYGBge3J9DQpzZXNzaW9uSW5mbygpDQpgYGANCg0KDQo=