1) Introducción

Para realizar este libro se va a utilizar la evaluacion agropecuaria municipal realizada en los años del 2006 al 2018 para realizar una comparación anual de los diferentes cultivos sembrados en el departamento del Magdalena y como pueden cambiar las dinamicas de los diferentes cultivos al paso de los años, demostrando cuales son de mayor importancia economica para el departamento y si se estan aprovechando los suelos destinados a la agricultura.

2) SetUp

Lo primero antes de empezar a manejar los datos es definir las librerias que vamos a utilizar para poder procesarlos y generar los graficos que necesitamos.

library(tidyverse)
library(dplyr)
library(readr)
library(ggplot2)
library(tidyr)

3) Lee el conjunto de datos EVA

Por medio del enlace https://www.datos.gov.co/Agricultura-y-Desarrollo-Rural/Evaluaciones-Agropecuarias-Municipales-EVA/2pnw-mmge/data, econtramos el informe EVA (Evaluaciones Agropecuarias Municipales) del 2006 al 2018, la cual vamos a utilizar para realizar el tratamiento debido de los datos. Lo primero que debemos hacer es filtrar la información del departamento del magdalena en formato csv para poder trabajarla.

list.files("C:\\Users\\brand\\OneDrive\\Escritorio\\GB2\\P4", , pattern=c('csv'))
[1] "Evaluaciones_Agropecuarias_Municipales_EVA_20250603 (1).csv"
[2] "tabla_final_EVA_2023.csv"                                   
(eva = read_csv("C:\\Users\\brand\\OneDrive\\Escritorio\\GB2\\P4\\Evaluaciones_Agropecuarias_Municipales_EVA_20250603 (1).csv", col_names = TRUE,
                show_col_types = FALSE))

al leer los datos del informe podemos evidenciar que son del 2006 al 2018 y que tiene información sobre 32 cultivos diferentes. El siguiente paso es mirar si el programa esta tomando las columnas con los nombres adecuados.

names(eva)
 [1] "CÓD. \nDEP."                                  
 [2] "DEPARTAMENTO"                                 
 [3] "CÓD. MUN."                                    
 [4] "MUNICIPIO"                                    
 [5] "GRUPO \nDE CULTIVO"                           
 [6] "SUBGRUPO \nDE CULTIVO"                        
 [7] "CULTIVO"                                      
 [8] "DESAGREGACIÓN REGIONAL Y/O SISTEMA PRODUCTIVO"
 [9] "AÑO"                                          
[10] "PERIODO"                                      
[11] "Área Sembrada\n(ha)"                          
[12] "Área Cosechada\n(ha)"                         
[13] "Producción\n(t)"                              
[14] "Rendimiento\n(t/ha)"                          
[15] "ESTADO FISICO PRODUCCION"                     
[16] "NOMBRE \nCIENTIFICO"                          
[17] "CICLO DE CULTIVO"                             

4) Limpia el conjunto de datos EVA

eva %>% dplyr::select('CÓD. MUN.':'ESTADO FISICO PRODUCCION') -> eva.tmp
eva.tmp

Ahora cambiamos los nombres de las columnas para que no tengan espacios ni vacios que el programa no pueda leer de manera adecuada.

eva.tmp %>%  dplyr::rename('Cod_Mun' = 'CÓD. MUN.', 
                         'Grupo' = 'GRUPO \nDE CULTIVO',
                         'Subgrupo' = 'SUBGRUPO \nDE CULTIVO', 
                         'Year' = 'AÑO',
                         'AreaSembrada' = 'Área Sembrada\n(ha)',
                         'AreaCosechada' = 'Área Sembrada\n(ha)',
                         'Produccion' = 'Producción\n(t)',                                                                 'Rendimiento' =  'Rendimiento\n(t/ha)',   
                         'Sistema' = 'DESAGREGACIÓN REGIONAL Y/O SISTEMA PRODUCTIVO',
                         'Estado' = 'ESTADO FISICO PRODUCCION') -> new_eva
new_eva

5) analisis de datos

Una técnica ampliamente utilizada en el análisis de datos es el enfoque dividir–aplicar–combinar, que permite explorar patrones y resumir información agrupando datos de forma estructurada. Esta estrategia consiste en tres pasos: primero se agrupan las observaciones con características similares mediante funciones como group_by() en el paquete dplyr; luego se les aplica una operación estadística o de transformación, como una suma, promedio, conteo o cálculo de desviación estándar con summarize(); y finalmente se combinan los resultados en una tabla consolidada. Esta forma de trabajar permite obtener resúmenes claros y compactos de grandes volúmenes de datos sin necesidad de bucles complejos, y es especialmente útil cuando se busca comparar grupos, analizar tendencias por categorías o construir reportes agregados. Gracias a su sintaxis intuitiva, dplyr se ha convertido en una herramienta clave para realizar este tipo de análisis en el entorno de R.

5.1) Los cultivos más importantes entre 2007 y 2018

new_eva %>%
  ##filter(Produccion > 0) %>%
  group_by(Grupo) %>%
  summarize(total_produccion = sum(Produccion)) %>% 
  arrange(desc(total_produccion)) 

Al obervar la tabla se puede evidenciar que el departamento del magdalena no es muy productivo en el sector agricola con excepcion a los cultivos de frutales, tuberculos, platanos y oleaginosas, los cuales tienen un mayor rendimiento de producción.

new_eva %>%
  group_by(Grupo) %>%
  summarize(total_produccion = sum(Produccion)) -> PT
PT %>% 
  filter(total_produccion > 1000000) -> main.groups
(value = sum(main.groups$total_produccion))
[1] 9649841
main.groups$percent = main.groups$total_produccion/value
library(ggplot2)
# Barplot
bp<- ggplot(main.groups, aes(x="", y=percent, fill=Grupo))+
geom_bar(width = 1, stat = "identity")
# Piechart
pie <- bp + coord_polar("y", start=0)
pie

En este grafico se puede observar mejor que los cultivos anteriormente mencionados son los mas productivos del departamento debido a que superan el millon de toneladas producidas.

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.
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
leaders %>% 
  filter(total_prod > 30000) -> main.leaders
p<-ggplot(data=main.leaders, aes(x=MUNICIPIO, y=total_prod)) +
  geom_bar(stat="identity")
p

por medio de este grafico se puede evidenciar que el municipio de zona bananera es el mas productivo del departamento por una diferencia abismal en comparación a los demas municipios.

6)Dinámica de un cultivo importante entre 2007 y 2018

Vamos a revisar la dinamica del cultivo de banano en el municipio de Zona Bananera para ver como ha cambiado su producción en este perido de tiempo.

new_eva %>% 
  filter(MUNICIPIO=="ZONA BANANERA" & CULTIVO=="BANANO") %>% 
  group_by(Year, CULTIVO) %>%
  select(MUNICIPIO, CULTIVO, Produccion, Year) ->  ZONABNR_BANANO
ZONABNR_BANANO
g <- ggplot(aes(x=Year, y=Produccion/1000), data = ZONABNR_BANANO) + geom_bar(stat='identity') + labs(y='Produccion de banano [Ton x 1000]')
g + ggtitle("Evolucion del cultivo de banano en zona bananera del 2007 al 2018") + labs(caption= "basado en (Minagricultura, 2020)")

7) Análisis adicional y gráficos

Por ultimo vamos a realizar una comparación entre los cultivos de cafe y citricos del municipio de Santa Marta para ver su dinamica en este periodo de tiempo y cual de los dos es mas productivo en la actualidad.

Primero revisamos la dinamica del cafe en el municipio

new_eva %>% 
  filter(MUNICIPIO=="SANTA MARTA" & CULTIVO=="CAFE") %>% 
  group_by(Year, CULTIVO) %>%
  select(MUNICIPIO, CULTIVO, Produccion, Year) ->  SANTAM_CAFE
SANTAM_CAFE
S <- ggplot(aes(x=Year, y=Produccion/1000), data = SANTAM_CAFE) + geom_bar(stat='identity') + labs(y='Produccion de cafe [Ton x 1000]')

Por medio de este grafico se puede ver que el cafe tiene una tendencia muy dinamica con el pasar de los años en donde es notable que la producción ha ido disminuyendo a partir del año 2015.

S + ggtitle("Evolucion del cultivo de cafe en santa marta del 2007 al 2018") + labs(caption= "basado en (Minagricultura, 2020)")

Ahora revisamos las dinamicas del cultivo de citricos en el mismo municipio.

new_eva %>% 
  filter(MUNICIPIO=="SANTA MARTA" & CULTIVO=="CITRICOS") %>% 
  group_by(Year, CULTIVO) %>%
  select(MUNICIPIO, CULTIVO, Produccion, Year) ->  SANTAM_CITRI
SANTAM_CITRI
C <- ggplot(aes(x=Year, y=Produccion/1000), data = SANTAM_CITRI) + geom_bar(stat='identity') + labs(y='Produccion de citricos [Ton x 1000]')

En esta grafica podemos observar como el cultivo de citricos es menos dinamico en relacion al cultivo de cafe y se ha mantenido su producción mas constate en los ultimos años, aunque tambien se puede observar una caida bastante notoria en su producción a partir del año 2015.

C + ggtitle("Evolucion del cultivo de citricos en santa marta del 2007 al 2018") + labs(caption= "basado en (Minagricultura, 2020)")


# Filtrar por municipio y cultivos deseados
comparacion <- new_eva %>%
  filter(MUNICIPIO == "SANTA MARTA", 
         CULTIVO %in% c("CAFE", "CITRICOS")) %>%
  group_by(Year, CULTIVO) %>%
  summarize(Produccion = sum(Produccion, na.rm = TRUE), .groups = "drop")

Por medio de esta grafica comparamos el rendimento de ambos cultivos en el municipio, observando que la producción de citricos ha sido mas constante en ese periodo de tiempo, pero tuvo una caida a parit del año 2015 junto con la producción de cafe, esta caida pudo ser causada por la disminucion del aarea sembrada en el magdalena durante los ultimos años, en donde se ha utilizado gran parte de la tierra dedicada para la agricultura en ganaderia intensiva y ecoturismo.

library(ggplot2)

ggplot(comparacion, aes(x = Year, y = Produccion / 1000, color = CULTIVO)) +
  geom_line(size = 1.2) +
  geom_point(size = 2) +
  labs(
    title = "Producción de Café vs Citricos en Santa Marta (2006–2018)",
    x = "Año",
    y = "Producción [Ton x 1000]",
    color = "Cultivo",
    caption = "Fuente: Minagricultura, 2020"
  ) +
  theme_minimal()

cultivos_magdalena <- new_eva %>%
  group_by(Year, CULTIVO) %>%
  summarize(Produccion = sum(Produccion, na.rm = TRUE), .groups = "drop")

Por medio de este grafico podemos observar el rendimiento de la producción en este periodo de los diferentes cultivos de importancia economica en el magdalena y su dinamica al pasar de los años.

ggplot(cultivos_magdalena, aes(x = Year, y = Produccion / 1000, color = CULTIVO)) +
  geom_line(size = 1) +
  geom_point(size = 1.5) +
  labs(
    title = "Producción de cultivos en el Magdalena 2007–2018",
    x = "Año",
    y = "Producción [Ton x 1000]",
    color = "Cultivo",
    caption = "Fuente: Minagricultura, 2020"
  ) +
  theme_minimal()

8) Bibliografia

[1] Lizarazo, I., 2022. Understanding dynamic productivity of crops. Available at https://rpubs.com/ials2un/production_dyn_v1.

sessionInfo()
R version 4.4.3 (2025-02-28 ucrt)
Platform: x86_64-w64-mingw32/x64
Running under: Windows 11 x64 (build 26100)

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] lubridate_1.9.4 forcats_1.0.0   stringr_1.5.1   purrr_1.0.4     readr_2.1.5    
 [6] tidyr_1.3.1     tibble_3.2.1    tidyverse_2.0.0 ggplot2_3.5.2   ggspatial_1.1.9
[11] dplyr_1.1.4     sf_1.0-20      

loaded via a namespace (and not attached):
 [1] gtable_0.3.6       xfun_0.52          bslib_0.9.0        lattice_0.22-6    
 [5] tzdb_0.5.0         vctrs_0.6.5        tools_4.4.3        generics_0.1.4    
 [9] parallel_4.4.3     proxy_0.4-27       pkgconfig_2.0.3    Matrix_1.7-2      
[13] KernSmooth_2.23-26 RColorBrewer_1.1-3 lifecycle_1.0.4    compiler_4.4.3    
[17] farver_2.1.2       htmltools_0.5.8.1  class_7.3-23       sass_0.4.10       
[21] yaml_2.3.10        pillar_1.10.2      crayon_1.5.3       jquerylib_0.1.4   
[25] rsconnect_1.3.4    classInt_0.4-11    cachem_1.1.0       nlme_3.1-167      
[29] tidyselect_1.2.1   digest_0.6.37      stringi_1.8.7      labeling_0.4.3    
[33] splines_4.4.3      fastmap_1.2.0      grid_4.4.3         cli_3.6.5         
[37] magrittr_2.0.3     e1071_1.7-16       withr_3.0.2        scales_1.4.0      
[41] bit64_4.6.0-1      timechange_0.3.0   rmarkdown_2.29     bit_4.6.0         
[45] hms_1.1.3          evaluate_1.0.3     knitr_1.50         mgcv_1.9-1        
[49] rlang_1.1.6        Rcpp_1.0.14        glue_1.8.0         DBI_1.2.3         
[53] rstudioapi_0.17.1  vroom_1.6.5        jsonlite_2.0.0     R6_2.6.1          
[57] units_0.8-7       
LS0tDQp0aXRsZTogIkRpbsOhbWljYXMgZGUgcHJvZHVjY2nDs24gZGUgY3VsdGl2b3MgZW4gZWwgTWFnZGFsZW5hIg0KYXV0aG9yOiAiQnJhbmRvbiBBbGVqYW5kcm8gU2FsZ2FkbyBHYXJ6w7NuIg0KZGF0ZTogIjQvMDYvMjAyNSINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KZGZfcHJpbnQ6IHBhZ2VkDQotLS0NCiMjICoqMSkgSW50cm9kdWNjacOzbioqDQoNClBhcmEgcmVhbGl6YXIgZXN0ZSBsaWJybyBzZSB2YSBhIHV0aWxpemFyIGxhIGV2YWx1YWNpb24gYWdyb3BlY3VhcmlhIG11bmljaXBhbCByZWFsaXphZGEgZW4gbG9zIGHDsW9zIGRlbCAyMDA2IGFsIDIwMTggcGFyYSByZWFsaXphciB1bmEgY29tcGFyYWNpw7NuIGFudWFsIGRlIGxvcyBkaWZlcmVudGVzIGN1bHRpdm9zIHNlbWJyYWRvcyBlbiBlbCBkZXBhcnRhbWVudG8gZGVsIE1hZ2RhbGVuYSB5IGNvbW8gcHVlZGVuIGNhbWJpYXIgbGFzIGRpbmFtaWNhcyBkZSBsb3MgZGlmZXJlbnRlcyBjdWx0aXZvcyBhbCBwYXNvIGRlIGxvcyBhw7FvcywgZGVtb3N0cmFuZG8gY3VhbGVzIHNvbiBkZSBtYXlvciBpbXBvcnRhbmNpYSBlY29ub21pY2EgcGFyYSBlbCBkZXBhcnRhbWVudG8geSBzaSBzZSBlc3RhbiBhcHJvdmVjaGFuZG8gbG9zIHN1ZWxvcyBkZXN0aW5hZG9zIGEgbGEgYWdyaWN1bHR1cmEuDQoNCiMjICoqMikgU2V0VXAqKg0KDQpMbyBwcmltZXJvIGFudGVzIGRlIGVtcGV6YXIgYSBtYW5lamFyIGxvcyBkYXRvcyBlcyBkZWZpbmlyIGxhcyBsaWJyZXJpYXMgcXVlIHZhbW9zIGEgdXRpbGl6YXIgcGFyYSBwb2RlciBwcm9jZXNhcmxvcyB5IGdlbmVyYXIgbG9zIGdyYWZpY29zIHF1ZSBuZWNlc2l0YW1vcy4NCg0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkoZHBseXIpDQpgYGANCg0KYGBge3J9DQpsaWJyYXJ5KHJlYWRyKQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeSh0aWR5cikNCmBgYA0KDQoNCiMjICoqMykgTGVlIGVsIGNvbmp1bnRvIGRlIGRhdG9zIEVWQSoqDQoNClBvciBtZWRpbyBkZWwgZW5sYWNlIGh0dHBzOi8vd3d3LmRhdG9zLmdvdi5jby9BZ3JpY3VsdHVyYS15LURlc2Fycm9sbG8tUnVyYWwvRXZhbHVhY2lvbmVzLUFncm9wZWN1YXJpYXMtTXVuaWNpcGFsZXMtRVZBLzJwbnctbW1nZS9kYXRhLCBlY29udHJhbW9zIGVsIGluZm9ybWUgRVZBIChFdmFsdWFjaW9uZXMgQWdyb3BlY3VhcmlhcyBNdW5pY2lwYWxlcykgZGVsIDIwMDYgYWwgMjAxOCwgbGEgY3VhbCB2YW1vcyBhIHV0aWxpemFyIHBhcmEgcmVhbGl6YXIgZWwgdHJhdGFtaWVudG8gZGViaWRvIGRlIGxvcyBkYXRvcy4gTG8gcHJpbWVybyBxdWUgZGViZW1vcyBoYWNlciBlcyBmaWx0cmFyIGxhIGluZm9ybWFjacOzbiBkZWwgZGVwYXJ0YW1lbnRvIGRlbCBtYWdkYWxlbmEgZW4gZm9ybWF0byBjc3YgcGFyYSBwb2RlciB0cmFiYWphcmxhLg0KDQpgYGB7cn0NCmxpc3QuZmlsZXMoIkM6XFxVc2Vyc1xcYnJhbmRcXE9uZURyaXZlXFxFc2NyaXRvcmlvXFxHQjJcXFA0IiwgLCBwYXR0ZXJuPWMoJ2NzdicpKQ0KYGBgDQpgYGB7cn0NCihldmEgPSByZWFkX2NzdigiQzpcXFVzZXJzXFxicmFuZFxcT25lRHJpdmVcXEVzY3JpdG9yaW9cXEdCMlxcUDRcXEV2YWx1YWNpb25lc19BZ3JvcGVjdWFyaWFzX011bmljaXBhbGVzX0VWQV8yMDI1MDYwMyAoMSkuY3N2IiwgY29sX25hbWVzID0gVFJVRSwNCiAgICAgICAgICAgICAgICBzaG93X2NvbF90eXBlcyA9IEZBTFNFKSkNCmBgYA0KDQphbCBsZWVyIGxvcyBkYXRvcyBkZWwgaW5mb3JtZSBwb2RlbW9zIGV2aWRlbmNpYXIgcXVlIHNvbiBkZWwgMjAwNiBhbCAyMDE4IHkgcXVlIHRpZW5lIGluZm9ybWFjacOzbiBzb2JyZSAzMiBjdWx0aXZvcyBkaWZlcmVudGVzLiBFbCBzaWd1aWVudGUgcGFzbyBlcyBtaXJhciBzaSBlbCBwcm9ncmFtYSBlc3RhIHRvbWFuZG8gbGFzIGNvbHVtbmFzIGNvbiBsb3Mgbm9tYnJlcyBhZGVjdWFkb3MuDQoNCmBgYHtyfQ0KbmFtZXMoZXZhKQ0KYGBgDQoNCiMjICoqNCkgTGltcGlhIGVsIGNvbmp1bnRvIGRlIGRhdG9zIEVWQSoqDQoNCg0KDQpgYGB7cn0NCmV2YSAlPiUgZHBseXI6OnNlbGVjdCgnQ8OTRC4gTVVOLic6J0VTVEFETyBGSVNJQ08gUFJPRFVDQ0lPTicpIC0+IGV2YS50bXANCmBgYA0KDQpgYGB7cn0NCmV2YS50bXANCmBgYA0KDQpBaG9yYSBjYW1iaWFtb3MgbG9zIG5vbWJyZXMgZGUgbGFzIGNvbHVtbmFzIHBhcmEgcXVlIG5vIHRlbmdhbiBlc3BhY2lvcyBuaSB2YWNpb3MgcXVlIGVsIHByb2dyYW1hIG5vIHB1ZWRhIGxlZXIgZGUgbWFuZXJhIGFkZWN1YWRhLg0KDQpgYGB7cn0NCmV2YS50bXAgJT4lICBkcGx5cjo6cmVuYW1lKCdDb2RfTXVuJyA9ICdDw5NELiBNVU4uJywgDQogICAgICAgICAgICAgICAgICAgICAgICAgJ0dydXBvJyA9ICdHUlVQTyBcbkRFIENVTFRJVk8nLA0KICAgICAgICAgICAgICAgICAgICAgICAgICdTdWJncnVwbycgPSAnU1VCR1JVUE8gXG5ERSBDVUxUSVZPJywgDQogICAgICAgICAgICAgICAgICAgICAgICAgJ1llYXInID0gJ0HDkU8nLA0KICAgICAgICAgICAgICAgICAgICAgICAgICdBcmVhU2VtYnJhZGEnID0gJ8OBcmVhIFNlbWJyYWRhXG4oaGEpJywNCiAgICAgICAgICAgICAgICAgICAgICAgICAnQXJlYUNvc2VjaGFkYScgPSAnw4FyZWEgU2VtYnJhZGFcbihoYSknLA0KICAgICAgICAgICAgICAgICAgICAgICAgICdQcm9kdWNjaW9uJyA9ICdQcm9kdWNjacOzblxuKHQpJywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdSZW5kaW1pZW50bycgPSAgJ1JlbmRpbWllbnRvXG4odC9oYSknLCAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICdTaXN0ZW1hJyA9ICdERVNBR1JFR0FDScOTTiBSRUdJT05BTCBZL08gU0lTVEVNQSBQUk9EVUNUSVZPJywNCiAgICAgICAgICAgICAgICAgICAgICAgICAnRXN0YWRvJyA9ICdFU1RBRE8gRklTSUNPIFBST0RVQ0NJT04nKSAtPiBuZXdfZXZhDQpgYGANCg0KYGBge3J9DQpuZXdfZXZhDQpgYGANCg0KLS0tDQojIyAqKjUpIGFuYWxpc2lzIGRlIGRhdG9zKioNCg0KVW5hIHTDqWNuaWNhIGFtcGxpYW1lbnRlIHV0aWxpemFkYSBlbiBlbCBhbsOhbGlzaXMgZGUgZGF0b3MgZXMgZWwgZW5mb3F1ZSAqKmRpdmlkaXLigJNhcGxpY2Fy4oCTY29tYmluYXIqKiwgcXVlIHBlcm1pdGUgZXhwbG9yYXIgcGF0cm9uZXMgeSByZXN1bWlyIGluZm9ybWFjacOzbiBhZ3J1cGFuZG8gZGF0b3MgZGUgZm9ybWEgZXN0cnVjdHVyYWRhLiBFc3RhIGVzdHJhdGVnaWEgY29uc2lzdGUgZW4gdHJlcyBwYXNvczogcHJpbWVybyBzZSBhZ3J1cGFuIGxhcyBvYnNlcnZhY2lvbmVzIGNvbiBjYXJhY3RlcsOtc3RpY2FzIHNpbWlsYXJlcyBtZWRpYW50ZSBmdW5jaW9uZXMgY29tbyBgZ3JvdXBfYnkoKWAgZW4gZWwgcGFxdWV0ZSBgZHBseXJgOyBsdWVnbyBzZSBsZXMgYXBsaWNhIHVuYSBvcGVyYWNpw7NuIGVzdGFkw61zdGljYSBvIGRlIHRyYW5zZm9ybWFjacOzbiwgY29tbyB1bmEgc3VtYSwgcHJvbWVkaW8sIGNvbnRlbyBvIGPDoWxjdWxvIGRlIGRlc3ZpYWNpw7NuIGVzdMOhbmRhciBjb24gYHN1bW1hcml6ZSgpYDsgeSBmaW5hbG1lbnRlIHNlIGNvbWJpbmFuIGxvcyByZXN1bHRhZG9zIGVuIHVuYSB0YWJsYSBjb25zb2xpZGFkYS4gRXN0YSBmb3JtYSBkZSB0cmFiYWphciBwZXJtaXRlIG9idGVuZXIgcmVzw7ptZW5lcyBjbGFyb3MgeSBjb21wYWN0b3MgZGUgZ3JhbmRlcyB2b2zDum1lbmVzIGRlIGRhdG9zIHNpbiBuZWNlc2lkYWQgZGUgYnVjbGVzIGNvbXBsZWpvcywgeSBlcyBlc3BlY2lhbG1lbnRlIMO6dGlsIGN1YW5kbyBzZSBidXNjYSBjb21wYXJhciBncnVwb3MsIGFuYWxpemFyIHRlbmRlbmNpYXMgcG9yIGNhdGVnb3LDrWFzIG8gY29uc3RydWlyIHJlcG9ydGVzIGFncmVnYWRvcy4gR3JhY2lhcyBhIHN1IHNpbnRheGlzIGludHVpdGl2YSwgYGRwbHlyYCBzZSBoYSBjb252ZXJ0aWRvIGVuIHVuYSBoZXJyYW1pZW50YSBjbGF2ZSBwYXJhIHJlYWxpemFyIGVzdGUgdGlwbyBkZSBhbsOhbGlzaXMgZW4gZWwgZW50b3JubyBkZSBSLg0KDQoNCiMjIyAqNS4xKSBMb3MgY3VsdGl2b3MgbcOhcyBpbXBvcnRhbnRlcyBlbnRyZSAyMDA3IHkgMjAxOCoNCg0KDQpgYGB7cn0NCm5ld19ldmEgJT4lDQogIGdyb3VwX2J5KEdydXBvKSAlPiUNCiAgc3VtbWFyaXplKHRvdGFsX3Byb2R1Y2Npb24gPSBzdW0oUHJvZHVjY2lvbikpICU+JSANCiAgYXJyYW5nZShkZXNjKHRvdGFsX3Byb2R1Y2Npb24pKSANCmBgYA0KDQpBbCBvYmVydmFyIGxhIHRhYmxhIHNlIHB1ZWRlIGV2aWRlbmNpYXIgcXVlIGVsIGRlcGFydGFtZW50byBkZWwgbWFnZGFsZW5hIG5vIGVzIG11eSBwcm9kdWN0aXZvIGVuIGVsIHNlY3RvciBhZ3JpY29sYSBjb24gZXhjZXBjaW9uIGEgbG9zIGN1bHRpdm9zIGRlIGZydXRhbGVzLCB0dWJlcmN1bG9zLCBwbGF0YW5vcyB5IG9sZWFnaW5vc2FzLCBsb3MgY3VhbGVzIHRpZW5lbiB1biBtYXlvciByZW5kaW1pZW50byBkZSBwcm9kdWNjacOzbi4NCg0KYGBge3J9DQpuZXdfZXZhICU+JQ0KICBncm91cF9ieShHcnVwbykgJT4lDQogIHN1bW1hcml6ZSh0b3RhbF9wcm9kdWNjaW9uID0gc3VtKFByb2R1Y2Npb24pKSAtPiBQVA0KYGBgDQoNCmBgYHtyfQ0KUFQgJT4lIA0KICBmaWx0ZXIodG90YWxfcHJvZHVjY2lvbiA+IDEwMDAwMDApIC0+IG1haW4uZ3JvdXBzDQpgYGANCg0KYGBge3J9DQoodmFsdWUgPSBzdW0obWFpbi5ncm91cHMkdG90YWxfcHJvZHVjY2lvbikpDQpgYGANCg0KYGBge3J9DQptYWluLmdyb3VwcyRwZXJjZW50ID0gbWFpbi5ncm91cHMkdG90YWxfcHJvZHVjY2lvbi92YWx1ZQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KYnA8LSBnZ3Bsb3QobWFpbi5ncm91cHMsIGFlcyh4PSIiLCB5PXBlcmNlbnQsIGZpbGw9R3J1cG8pKSsNCmdlb21fYmFyKHdpZHRoID0gMSwgc3RhdCA9ICJpZGVudGl0eSIpDQpwaWUgPC0gYnAgKyBjb29yZF9wb2xhcigieSIsIHN0YXJ0PTApDQpwaWUNCmBgYA0KRW4gZXN0ZSBncmFmaWNvIHNlIHB1ZWRlIG9ic2VydmFyIG1lam9yIHF1ZSBsb3MgY3VsdGl2b3MgYW50ZXJpb3JtZW50ZSBtZW5jaW9uYWRvcyBzb24gbG9zIG1hcyBwcm9kdWN0aXZvcyBkZWwgZGVwYXJ0YW1lbnRvIGRlYmlkbyBhIHF1ZSBzdXBlcmFuIGVsIG1pbGxvbiBkZSB0b25lbGFkYXMgcHJvZHVjaWRhcy4NCg0KYGBge3J9DQpuZXdfZXZhICU+JQ0KICBncm91cF9ieShHcnVwbywgTVVOSUNJUElPKSAlPiUNCiAgc3VtbWFyaXplKHRvdGFsX3Byb2QgPSBzdW0oUHJvZHVjY2lvbiwgbmEucm0gPSBUUlVFKSkgJT4lDQogIHNsaWNlKHdoaWNoLm1heCh0b3RhbF9wcm9kKSkgICU+JQ0KICBhcnJhbmdlKGRlc2ModG90YWxfcHJvZCkpDQpgYGANCg0KYGBge3J9DQpuZXdfZXZhICU+JQ0KICBncm91cF9ieShHcnVwbyAsIE1VTklDSVBJTykgJT4lDQogIHN1bW1hcml6ZSh0b3RhbF9wcm9kID0gc3VtKFByb2R1Y2Npb24sIG5hLnJtID0gVFJVRSkpICU+JQ0KICBzbGljZSh3aGljaC5tYXgodG90YWxfcHJvZCkpICAtPiBsZWFkZXJzDQpgYGANCg0KDQpgYGB7cn0NCmxlYWRlcnMNCmBgYA0KDQpgYGB7cn0NCmxlYWRlcnMgJT4lIA0KICBmaWx0ZXIodG90YWxfcHJvZCA+IDMwMDAwKSAtPiBtYWluLmxlYWRlcnMNCmBgYA0KDQpgYGB7cn0NCnA8LWdncGxvdChkYXRhPW1haW4ubGVhZGVycywgYWVzKHg9TVVOSUNJUElPLCB5PXRvdGFsX3Byb2QpKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikNCnANCmBgYA0KcG9yIG1lZGlvIGRlIGVzdGUgZ3JhZmljbyBzZSBwdWVkZSBldmlkZW5jaWFyIHF1ZSBlbCBtdW5pY2lwaW8gZGUgem9uYSBiYW5hbmVyYSBlcyBlbCBtYXMgcHJvZHVjdGl2byBkZWwgZGVwYXJ0YW1lbnRvIHBvciB1bmEgZGlmZXJlbmNpYSBhYmlzbWFsIGVuIGNvbXBhcmFjacOzbiBhIGxvcyBkZW1hcyBtdW5pY2lwaW9zLg0KDQojIyAqKjYpRGluw6FtaWNhIGRlIHVuIGN1bHRpdm8gaW1wb3J0YW50ZSBlbnRyZSAyMDA3IHkgMjAxOCoqDQoNClZhbW9zIGEgcmV2aXNhciBsYSBkaW5hbWljYSBkZWwgY3VsdGl2byBkZSBiYW5hbm8gZW4gZWwgbXVuaWNpcGlvIGRlIFpvbmEgQmFuYW5lcmEgcGFyYSB2ZXIgY29tbyBoYSBjYW1iaWFkbyBzdSBwcm9kdWNjacOzbiBlbiBlc3RlIHBlcmlkbyBkZSB0aWVtcG8uIA0KDQpgYGB7cn0NCm5ld19ldmEgJT4lIA0KICBmaWx0ZXIoTVVOSUNJUElPPT0iWk9OQSBCQU5BTkVSQSIgJiBDVUxUSVZPPT0iQkFOQU5PIikgJT4lIA0KICBncm91cF9ieShZZWFyLCBDVUxUSVZPKSAlPiUNCiAgc2VsZWN0KE1VTklDSVBJTywgQ1VMVElWTywgUHJvZHVjY2lvbiwgWWVhcikgLT4gIFpPTkFCTlJfQkFOQU5PDQpgYGANCg0KYGBge3J9DQpaT05BQk5SX0JBTkFOTw0KYGBgDQoNCmBgYHtyfQ0KZyA8LSBnZ3Bsb3QoYWVzKHg9eWVhciwgeT1Qcm9kdWNjaW9uLzEwMDApLCBkYXRhID0gWk9OQUJOUl9CQU5BTk8pICsgZ2VvbV9iYXIoc3RhdD0naWRlbnRpdHknKSArIGxhYnMoeT0nUHJvZHVjY2lvbiBkZSBiYW5hbm8gW1RvbiB4IDEwMDBdJykNCmBgYA0KDQpgYGB7cn0NCmcgKyBnZ3RpdGxlKCJFdm9sdWNpb24gZGVsIGN1bHRpdm8gZGUgYmFuYW5vIGVuIHpvbmEgYmFuYW5lcmEgZGVsIDIwMDcgYWwgMjAxOCIpICsgbGFicyhjYXB0aW9uPSAiYmFzYWRvIGVuIChNaW5hZ3JpY3VsdHVyYSwgMjAyMCkiKQ0KYGBgDQoNCiMjICoqNykgQW7DoWxpc2lzIGFkaWNpb25hbCB5IGdyw6FmaWNvcyoqDQoNClBvciB1bHRpbW8gdmFtb3MgYSByZWFsaXphciB1bmEgY29tcGFyYWNpw7NuIGVudHJlIGxvcyBjdWx0aXZvcyBkZSBjYWZlIHkgY2l0cmljb3MgZGVsIG11bmljaXBpbyBkZSBTYW50YSBNYXJ0YSBwYXJhIHZlciBzdSBkaW5hbWljYSBlbiBlc3RlIHBlcmlvZG8gZGUgdGllbXBvIHkgY3VhbCBkZSBsb3MgZG9zIGVzIG1hcyBwcm9kdWN0aXZvIGVuIGxhIGFjdHVhbGlkYWQuDQoNClByaW1lcm8gcmV2aXNhbW9zIGxhIGRpbmFtaWNhIGRlbCBjYWZlIGVuIGVsIG11bmljaXBpbw0KDQpgYGB7cn0NCm5ld19ldmEgJT4lIA0KICBmaWx0ZXIoTVVOSUNJUElPPT0iU0FOVEEgTUFSVEEiICYgQ1VMVElWTz09IkNBRkUiKSAlPiUgDQogIGdyb3VwX2J5KFllYXIsIENVTFRJVk8pICU+JQ0KICBzZWxlY3QoTVVOSUNJUElPLCBDVUxUSVZPLCBQcm9kdWNjaW9uLCBZZWFyKSAtPiAgU0FOVEFNX0NBRkUNCmBgYA0KDQpgYGB7cn0NClNBTlRBTV9DQUZFDQpgYGANCg0KYGBge3J9DQpTIDwtIGdncGxvdChhZXMoeD1ZZWFyLCB5PVByb2R1Y2Npb24vMTAwMCksIGRhdGEgPSBTQU5UQU1fQ0FGRSkgKyBnZW9tX2JhcihzdGF0PSdpZGVudGl0eScpICsgbGFicyh5PSdQcm9kdWNjaW9uIGRlIGNhZmUgW1RvbiB4IDEwMDBdJykNCmBgYA0KDQpQb3IgbWVkaW8gZGUgZXN0ZSBncmFmaWNvIHNlIHB1ZWRlIHZlciBxdWUgZWwgY2FmZSB0aWVuZSB1bmEgdGVuZGVuY2lhIG11eSBkaW5hbWljYSBjb24gZWwgcGFzYXIgZGUgbG9zIGHDsW9zIGVuIGRvbmRlIGVzIG5vdGFibGUgcXVlIGxhIHByb2R1Y2Npw7NuIGhhIGlkbyBkaXNtaW51eWVuZG8gYSBwYXJ0aXIgZGVsIGHDsW8gMjAxNS4NCg0KYGBge3J9DQpTICsgZ2d0aXRsZSgiRXZvbHVjaW9uIGRlbCBjdWx0aXZvIGRlIGNhZmUgZW4gc2FudGEgbWFydGEgZGVsIDIwMDcgYWwgMjAxOCIpICsgbGFicyhjYXB0aW9uPSAiYmFzYWRvIGVuIChNaW5hZ3JpY3VsdHVyYSwgMjAyMCkiKQ0KYGBgDQoNCkFob3JhIHJldmlzYW1vcyBsYXMgZGluYW1pY2FzIGRlbCBjdWx0aXZvIGRlIGNpdHJpY29zIGVuIGVsIG1pc21vIG11bmljaXBpby4NCg0KYGBge3J9DQpuZXdfZXZhICU+JSANCiAgZmlsdGVyKE1VTklDSVBJTz09IlNBTlRBIE1BUlRBIiAmIENVTFRJVk89PSJDSVRSSUNPUyIpICU+JSANCiAgZ3JvdXBfYnkoWWVhciwgQ1VMVElWTykgJT4lDQogIHNlbGVjdChNVU5JQ0lQSU8sIENVTFRJVk8sIFByb2R1Y2Npb24sIFllYXIpIC0+ICBTQU5UQU1fQ0lUUkkNCmBgYA0KDQpgYGB7cn0NClNBTlRBTV9DSVRSSQ0KYGBgDQoNCg0KYGBge3J9DQpDIDwtIGdncGxvdChhZXMoeD1ZZWFyLCB5PVByb2R1Y2Npb24vMTAwMCksIGRhdGEgPSBTQU5UQU1fQ0lUUkkpICsgZ2VvbV9iYXIoc3RhdD0naWRlbnRpdHknKSArIGxhYnMoeT0nUHJvZHVjY2lvbiBkZSBjaXRyaWNvcyBbVG9uIHggMTAwMF0nKQ0KYGBgDQoNCkVuIGVzdGEgZ3JhZmljYSBwb2RlbW9zIG9ic2VydmFyIGNvbW8gZWwgY3VsdGl2byBkZSBjaXRyaWNvcyBlcyBtZW5vcyBkaW5hbWljbyBlbiByZWxhY2lvbiBhbCBjdWx0aXZvIGRlIGNhZmUgeSBzZSBoYSBtYW50ZW5pZG8gc3UgcHJvZHVjY2nDs24gbWFzIGNvbnN0YXRlIGVuIGxvcyB1bHRpbW9zIGHDsW9zLCBhdW5xdWUgdGFtYmllbiBzZSBwdWVkZSBvYnNlcnZhciB1bmEgY2FpZGEgYmFzdGFudGUgbm90b3JpYSBlbiBzdSBwcm9kdWNjacOzbiBhIHBhcnRpciBkZWwgYcOxbyAyMDE1Lg0KDQpgYGB7cn0NCkMgKyBnZ3RpdGxlKCJFdm9sdWNpb24gZGVsIGN1bHRpdm8gZGUgY2l0cmljb3MgZW4gc2FudGEgbWFydGEgZGVsIDIwMDcgYWwgMjAxOCIpICsgbGFicyhjYXB0aW9uPSAiYmFzYWRvIGVuIChNaW5hZ3JpY3VsdHVyYSwgMjAyMCkiKQ0KYGBgDQoNCg0KDQpgYGB7cn0NCg0KIyBGaWx0cmFyIHBvciBtdW5pY2lwaW8geSBjdWx0aXZvcyBkZXNlYWRvcw0KY29tcGFyYWNpb24gPC0gbmV3X2V2YSAlPiUNCiAgZmlsdGVyKE1VTklDSVBJTyA9PSAiU0FOVEEgTUFSVEEiLCANCiAgICAgICAgIENVTFRJVk8gJWluJSBjKCJDQUZFIiwgIkNJVFJJQ09TIikpICU+JQ0KICBncm91cF9ieShZZWFyLCBDVUxUSVZPKSAlPiUNCiAgc3VtbWFyaXplKFByb2R1Y2Npb24gPSBzdW0oUHJvZHVjY2lvbiwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikNCg0KDQpgYGANCg0KDQpQb3IgbWVkaW8gZGUgZXN0YSBncmFmaWNhIGNvbXBhcmFtb3MgZWwgcmVuZGltZW50byBkZSBhbWJvcyBjdWx0aXZvcyBlbiBlbCBtdW5pY2lwaW8sIG9ic2VydmFuZG8gcXVlIGxhIHByb2R1Y2Npw7NuIGRlIGNpdHJpY29zIGhhIHNpZG8gbWFzIGNvbnN0YW50ZSBlbiBlc2UgcGVyaW9kbyBkZSB0aWVtcG8sIHBlcm8gdHV2byB1bmEgY2FpZGEgYSBwYXJpdCBkZWwgYcOxbyAyMDE1IGp1bnRvIGNvbiBsYSBwcm9kdWNjacOzbiBkZSBjYWZlLCBlc3RhIGNhaWRhIHB1ZG8gc2VyIGNhdXNhZGEgcG9yIGxhIGRpc21pbnVjaW9uIGRlbCBhYXJlYSBzZW1icmFkYSBlbiBlbCBtYWdkYWxlbmEgZHVyYW50ZSBsb3MgdWx0aW1vcyBhw7FvcywgZW4gZG9uZGUgc2UgaGEgdXRpbGl6YWRvIGdyYW4gcGFydGUgZGUgbGEgdGllcnJhIGRlZGljYWRhIHBhcmEgbGEgYWdyaWN1bHR1cmEgZW4gZ2FuYWRlcmlhIGludGVuc2l2YSB5IGVjb3R1cmlzbW8uDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KDQpnZ3Bsb3QoY29tcGFyYWNpb24sIGFlcyh4ID0gWWVhciwgeSA9IFByb2R1Y2Npb24gLyAxMDAwLCBjb2xvciA9IENVTFRJVk8pKSArDQogIGdlb21fbGluZShzaXplID0gMS4yKSArDQogIGdlb21fcG9pbnQoc2l6ZSA9IDIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJQcm9kdWNjacOzbiBkZSBDYWbDqSB2cyBDaXRyaWNvcyBlbiBTYW50YSBNYXJ0YSAoMjAwNuKAkzIwMTgpIiwNCiAgICB4ID0gIkHDsW8iLA0KICAgIHkgPSAiUHJvZHVjY2nDs24gW1RvbiB4IDEwMDBdIiwNCiAgICBjb2xvciA9ICJDdWx0aXZvIiwNCiAgICBjYXB0aW9uID0gIkZ1ZW50ZTogTWluYWdyaWN1bHR1cmEsIDIwMjAiDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQoNCmBgYHtyfQ0KY3VsdGl2b3NfbWFnZGFsZW5hIDwtIG5ld19ldmEgJT4lDQogIGdyb3VwX2J5KFllYXIsIENVTFRJVk8pICU+JQ0KICBzdW1tYXJpemUoUHJvZHVjY2lvbiA9IHN1bShQcm9kdWNjaW9uLCBuYS5ybSA9IFRSVUUpLCAuZ3JvdXBzID0gImRyb3AiKQ0KYGBgDQoNClBvciBtZWRpbyBkZSBlc3RlIGdyYWZpY28gcG9kZW1vcyBvYnNlcnZhciBlbCByZW5kaW1pZW50byBkZSBsYSBwcm9kdWNjacOzbiBlbiBlc3RlIHBlcmlvZG8gZGUgbG9zIGRpZmVyZW50ZXMgY3VsdGl2b3MgZGUgaW1wb3J0YW5jaWEgZWNvbm9taWNhIGVuIGVsIG1hZ2RhbGVuYSB5IHN1IGRpbmFtaWNhIGFsIHBhc2FyIGRlIGxvcyBhw7Fvcy4NCg0KYGBge3J9DQpnZ3Bsb3QoY3VsdGl2b3NfbWFnZGFsZW5hLCBhZXMoeCA9IFllYXIsIHkgPSBQcm9kdWNjaW9uIC8gMTAwMCwgY29sb3IgPSBDVUxUSVZPKSkgKw0KICBnZW9tX2xpbmUoc2l6ZSA9IDEpICsNCiAgZ2VvbV9wb2ludChzaXplID0gMS41KSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiUHJvZHVjY2nDs24gZGUgY3VsdGl2b3MgZW4gZWwgTWFnZGFsZW5hIDIwMDfigJMyMDE4IiwNCiAgICB4ID0gIkHDsW8iLA0KICAgIHkgPSAiUHJvZHVjY2nDs24gW1RvbiB4IDEwMDBdIiwNCiAgICBjb2xvciA9ICJDdWx0aXZvIiwNCiAgICBjYXB0aW9uID0gIkZ1ZW50ZTogTWluYWdyaWN1bHR1cmEsIDIwMjAiDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQoNCiMjICoqOCkgQmlibGlvZ3JhZmlhKioNCg0KWzFdIExpemFyYXpvLCBJLiwgMjAyMi4gVW5kZXJzdGFuZGluZyBkeW5hbWljIHByb2R1Y3Rpdml0eSBvZiBjcm9wcy4gQXZhaWxhYmxlIGF0IGh0dHBzOi8vcnB1YnMuY29tL2lhbHMydW4vcHJvZHVjdGlvbl9keW5fdjEuDQpgYGB7cn0NCnNlc3Npb25JbmZvKCkNCmBgYA0KDQo=