Resuelva las situaciones que se le presentan a continuación. Para cada una de las situaciones deberán generar un gráfico en ggplot que acompañe a la resolución.

library(ggplot2)
library(readODS)
library(growthrates)

# Datos (el archivo .ods debe estar en la misma carpeta que este .Rmd)
d1 <- read_ods("Problemas_Modelos.ods", sheet = "Problema1")
d2 <- read_ods("Problemas_Modelos.ods", sheet = "Problema2")
d3 <- read_ods("Problemas_Modelos.ods", sheet = "Problema3")

# Tema para todos los gráficos
tema_pro <- theme_minimal(base_size = 14) +
  theme(
    panel.grid.minor = element_blank(),
    axis.title = element_text(face = "bold")
  )

# Función para saber en qué tiempo la población llega a N individuos
t_alcanza <- function(N, p) {
  with(as.list(p), log(N * (K - y0) / (y0 * (K - N))) / mumax)
}

Problema 1

En un laboratorio de botánica se sembraron plántulas de frijol (Phaseolus vulgaris) bajo condiciones controladas: luz constante, temperatura de 25 °C y riego regular. Cada 2 días se midió la altura de 10 plántulas y se registró el promedio. Su grupo debe estimar la tasa de crecimiento de las plántulas con un modelo lineal. Si ustedes tuvieran a cargo de laboratorio, qué decisiones tomarían para que el crecimiento sea mayor.

Ahora, con ese modelo, haga una predicción de cuál será el tamaño de las plantas en los días 40 y 52.

modelo <- lm(Altura ~ Tiempo, data = d1)
print(summary(modelo))

Call:
lm(formula = Altura ~ Tiempo, data = d1)

Residuals:
     Min       1Q   Median       3Q      Max 
-1.22667 -0.59024  0.04583  0.68690  0.86440 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  2.05417    0.36116   5.688 7.44e-05 ***
Tiempo       1.09089    0.02195  49.694 3.25e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.7347 on 13 degrees of freedom
Multiple R-squared:  0.9948,    Adjusted R-squared:  0.9944 
F-statistic:  2469 on 1 and 13 DF,  p-value: 3.247e-16
nuevos_datos <- data.frame(Tiempo = c(40, 52))
nuevos_datos$Altura <- predict(modelo, nuevos_datos)
print(nuevos_datos)
  Tiempo   Altura
1     40 45.68988
2     52 58.78060
ggplot(d1, aes(Tiempo, Altura)) +
  geom_point(size = 3, color = "#2E7D32") +
  geom_smooth(method = "lm", fullrange = TRUE, color = "#1B5E20", fill = "#A5D6A7") +
  geom_point(data = nuevos_datos, size = 4, shape = 17, color = "#C62828") +
  scale_x_continuous(limits = c(0, 55)) +
  labs(x = "Tiempo (días)", y = "Altura promedio (cm)") +
  tema_pro

Respuesta

El modelo lineal establece que las plántulas de frijol crecen 1.09 cm por día. Con este modelo, la altura de las plantas es de 45.7 cm en el día 40 y de 58.8 cm en el día 52 (triángulos rojos en el gráfico).

Como encargada del laboratorio, tomaría las siguientes decisiones para aumentar el crecimiento: optimizar la cantidad y la duración de la luz, mejorar el sustrato y la fertilización, ajustar el volumen de riego y evaluar temperaturas cercanas a 25 °C. Cada factor se prueba en un experimento controlado, cambiando una sola variable a la vez y comparando las tasas de crecimiento.

El modelo lineal no incorpora un límite de crecimiento, mientras que las plantas reales dejan de crecer al alcanzar su altura máxima. Por eso, la predicción del día 52 sobrestima la altura real.

Problema 2

La lapa roja o guacamaya roja (Ara macao) fue casi eliminada de buena parte del Pacífico de Costa Rica por la pérdida de bosque y la captura de polluelos. Gracias a programas de conservación y reintroducción, algunas poblaciones se han recuperado.

Imaginen que un programa de conservación liberó un grupo pequeño de lapas rojas en un bosque protegido del Pacífico central y las censó cada año durante 20 años. Ustedes deben ajustar un modelo logístico a los datos y estimar los parámetros que describen el crecimiento de esta población. Como tomadores de decisión, especifiquen cuándo deberá de terminar el monitoreo ecológico, según el comportamiento poblacional.

ajuste2 <- fit_growthmodel(
  FUN   = grow_logistic,
  p     = c(y0 = 12, mumax = 0.5, K = 190),
  time  = d2$Muestreo,
  y     = d2$Individuos,
  lower = c(y0 = 1, mumax = 0, K = 1),
  upper = c(y0 = 100, mumax = 3, K = 2000)
)
print(summary(ajuste2))

Parameters:
      Estimate Std. Error t value Pr(>|t|)    
y0     12.0260     0.8352   14.40 2.55e-11 ***
mumax   0.3501     0.0106   33.04  < 2e-16 ***
K     180.4668     1.6627  108.54  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 3.025 on 18 degrees of freedom

Parameter correlation:
           y0   mumax       K
y0     1.0000 -0.9287  0.4966
mumax -0.9287  1.0000 -0.6723
K      0.4966 -0.6723  1.0000
p2 <- coef(ajuste2)
print(p2)
         y0       mumax           K 
 12.0260449   0.3501131 180.4667880 
curva2 <- as.data.frame(grow_logistic(seq(0, 20, 0.1), p2))

ggplot() +
  geom_point(data = d2, aes(Muestreo, Individuos), size = 3, color = "#C62828") +
  geom_line(data = curva2, aes(time, y), linewidth = 1.2, color = "#1565C0") +
  geom_hline(yintercept = p2["K"], linetype = "dashed", color = "grey40") +
  labs(x = "Año de muestreo", y = "Individuos") +
  tema_pro


# Año en que se alcanza 50 %, 90 % y 95 % de K
print(t_alcanza(0.5 * p2["K"], p2))
       K 
7.539018 
print(t_alcanza(0.9 * p2["K"], p2))
       K 
13.81477 
print(t_alcanza(0.95 * p2["K"], p2))
       K 
15.94898 

Respuesta

El modelo logístico ajustado a los censos de lapa roja tiene una población inicial (y0) de 12 lapas, una tasa de crecimiento (mumax) de 0.35 por año y una capacidad de carga (K) de 180 individuos (línea punteada en el gráfico). Los tres parámetros son altamente significativos (p < 0.001) y el error residual es bajo, por lo que el modelo describe correctamente el comportamiento de la población.

La población crece lentamente al inicio, se acelera hasta llegar a la mitad de K (90 lapas) en el año 7.5 y luego se desacelera hasta estabilizarse. Alcanza el 90 % de K en el año 13.8 y el 95 % en el año 15.9.

El monitoreo ecológico debe terminar en el año 16, cuando la población está en su capacidad de carga y su crecimiento es nulo. Después de esa fecha se mantiene un monitoreo espaciado, cada 3 a 5 años, para detectar amenazas como la pérdida de bosque y la captura de polluelos.

Problema 3

En los bosques nubosos de la cordillera de Tilarán, un anfibio endémico (especie ficticia, inspirada en lo ocurrido con el sapo dorado de Monteverde) mantenía una población estable de unos 500 individuos. A partir de cierto momento, la llegada de un hongo patógeno (quitridiomicosis) y el aumento de la temperatura hicieron que las muertes superaran a los nacimientos. Un equipo de biólogos censó la población cada año durante 12 años. (mumax = -0.3, K = 550)

Ustedes deben ajustar un modelo logístico con tasa de crecimiento y usarlo para predecir cuándo desaparecerá la población.

ajuste <- fit_growthmodel(
  FUN   = grow_logistic,
  p     = c(y0 = 480, mumax = -0.3, K = 550),
  time  = d3$Muestreo,
  y     = d3$Individuos,
  lower = c(y0 = 1,    mumax = -3, K = 1),
  upper = c(y0 = 2000, mumax = 0,  K = 5000)
)

print(summary(ajuste))

Parameters:
       Estimate Std. Error t value Pr(>|t|)    
y0    480.12202    3.08418  155.67  < 2e-16 ***
mumax  -0.44727    0.01071  -41.76 1.49e-12 ***
K     500.60471    4.79604  104.38  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 4.775 on 10 degrees of freedom

Parameter correlation:
          y0  mumax      K
y0    1.0000 0.5489 0.9490
mumax 0.5489 1.0000 0.7768
K     0.9490 0.7768 1.0000
p3 <- coef(ajuste)
print(p3)
        y0      mumax          K 
480.122018  -0.447271 500.604706 
# Número de individuos en los años 20, 40 y 50
t_pred <- c(20, 40, 50)
N_pred <- grow_logistic(t_pred, p3)[, "y"]
print(data.frame(Anio = t_pred, Individuos = N_pred))
  Anio   Individuos
1   20 1.524714e+00
2   40 1.993271e-04
3   50 2.275587e-06
# Año en que queda menos de 1 individuo
print(t_alcanza(1, p3))
[1] 20.94542
curva3 <- as.data.frame(grow_logistic(seq(0, 30, 0.1), p3))

ggplot() +
  geom_point(data = d3, aes(Muestreo, Individuos), size = 3, color = "#C62828") +
  geom_line(data = curva3, aes(time, y), linewidth = 1.2, color = "#1565C0") +
  labs(x = "Año de muestreo", y = "Individuos") +
  tema_pro

Respuesta

El modelo logístico con tasa negativa ajusta los censos con una población inicial (y0) de 480 individuos, una tasa de crecimiento (mumax) de -0.45 por año, es decir, una disminución de 45 % anual, y una capacidad de carga (K) de 500 individuos.

El modelo predice 1.5 individuos en el año 20 y una población de 0 en los años 40 y 50. La población baja de un individuo en el año 21, y ese es el momento en que desaparece.

Con el hongo patógeno y el aumento de temperatura, la población se extingue en 21 años desde el inicio de los censos. Las acciones de conservación deben ejecutarse antes de ese plazo.

LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IA0KICBodG1sX25vdGVib29rOiANCiAgICB0b2M6IHRydWUNCiAgICB0aGVtZTogdW5pdGVkDQotLS0NCg0KUmVzdWVsdmEgbGFzIHNpdHVhY2lvbmVzIHF1ZSBzZSBsZSBwcmVzZW50YW4gYSBjb250aW51YWNpw7NuLiBQYXJhIGNhZGEgdW5hIGRlIGxhcyBzaXR1YWNpb25lcyBkZWJlcsOhbiBnZW5lcmFyIHVuIGdyw6FmaWNvIGVuIGdncGxvdCBxdWUgYWNvbXBhw7FlIGEgbGEgcmVzb2x1Y2nDs24uDQoNCmBgYHtyIHByZXBhcmFjaW9ufQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShyZWFkT0RTKQ0KbGlicmFyeShncm93dGhyYXRlcykNCg0KIyBEYXRvcyAoZWwgYXJjaGl2byAub2RzIGRlYmUgZXN0YXIgZW4gbGEgbWlzbWEgY2FycGV0YSBxdWUgZXN0ZSAuUm1kKQ0KZDEgPC0gcmVhZF9vZHMoIlByb2JsZW1hc19Nb2RlbG9zLm9kcyIsIHNoZWV0ID0gIlByb2JsZW1hMSIpDQpkMiA8LSByZWFkX29kcygiUHJvYmxlbWFzX01vZGVsb3Mub2RzIiwgc2hlZXQgPSAiUHJvYmxlbWEyIikNCmQzIDwtIHJlYWRfb2RzKCJQcm9ibGVtYXNfTW9kZWxvcy5vZHMiLCBzaGVldCA9ICJQcm9ibGVtYTMiKQ0KDQojIFRlbWEgcGFyYSB0b2RvcyBsb3MgZ3LDoWZpY29zDQp0ZW1hX3BybyA8LSB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDE0KSArDQogIHRoZW1lKA0KICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiKQ0KICApDQoNCiMgRnVuY2nDs24gcGFyYSBzYWJlciBlbiBxdcOpIHRpZW1wbyBsYSBwb2JsYWNpw7NuIGxsZWdhIGEgTiBpbmRpdmlkdW9zDQp0X2FsY2FuemEgPC0gZnVuY3Rpb24oTiwgcCkgew0KICB3aXRoKGFzLmxpc3QocCksIGxvZyhOICogKEsgLSB5MCkgLyAoeTAgKiAoSyAtIE4pKSkgLyBtdW1heCkNCn0NCmBgYA0KDQojIFByb2JsZW1hIDENCg0KRW4gdW4gbGFib3JhdG9yaW8gZGUgYm90w6FuaWNhIHNlIHNlbWJyYXJvbiBwbMOhbnR1bGFzIGRlIGZyaWpvbCAoKlBoYXNlb2x1cyB2dWxnYXJpcyopIGJham8gY29uZGljaW9uZXMgY29udHJvbGFkYXM6IGx1eiBjb25zdGFudGUsIHRlbXBlcmF0dXJhIGRlIDI1IMKwQyB5IHJpZWdvIHJlZ3VsYXIuIENhZGEgMiBkw61hcyBzZSBtaWRpw7MgbGEgYWx0dXJhIGRlIDEwIHBsw6FudHVsYXMgeSBzZSByZWdpc3Ryw7MgZWwgcHJvbWVkaW8uIFN1IGdydXBvIGRlYmUgZXN0aW1hciBsYSAqKnRhc2EgZGUgY3JlY2ltaWVudG8qKiBkZSBsYXMgcGzDoW50dWxhcyBjb24gdW4gbW9kZWxvIGxpbmVhbC4gU2kgdXN0ZWRlcyB0dXZpZXJhbiBhIGNhcmdvIGRlIGxhYm9yYXRvcmlvLCBxdcOpIGRlY2lzaW9uZXMgdG9tYXLDrWFuIHBhcmEgcXVlIGVsIGNyZWNpbWllbnRvIHNlYSBtYXlvci4NCg0KQWhvcmEsIGNvbiBlc2UgbW9kZWxvLCBoYWdhIHVuYSBwcmVkaWNjacOzbiBkZSBjdcOhbCBzZXLDoSBlbCB0YW1hw7FvIGRlIGxhcyBwbGFudGFzIGVuIGxvcyBkw61hcyA0MCB5IDUyLg0KDQpgYGB7ciBwcm9ibGVtYTF9DQptb2RlbG8gPC0gbG0oQWx0dXJhIH4gVGllbXBvLCBkYXRhID0gZDEpDQpwcmludChzdW1tYXJ5KG1vZGVsbykpDQoNCm51ZXZvc19kYXRvcyA8LSBkYXRhLmZyYW1lKFRpZW1wbyA9IGMoNDAsIDUyKSkNCm51ZXZvc19kYXRvcyRBbHR1cmEgPC0gcHJlZGljdChtb2RlbG8sIG51ZXZvc19kYXRvcykNCnByaW50KG51ZXZvc19kYXRvcykNCg0KZ2dwbG90KGQxLCBhZXMoVGllbXBvLCBBbHR1cmEpKSArDQogIGdlb21fcG9pbnQoc2l6ZSA9IDMsIGNvbG9yID0gIiMyRTdEMzIiKSArDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGZ1bGxyYW5nZSA9IFRSVUUsIGNvbG9yID0gIiMxQjVFMjAiLCBmaWxsID0gIiNBNUQ2QTciKSArDQogIGdlb21fcG9pbnQoZGF0YSA9IG51ZXZvc19kYXRvcywgc2l6ZSA9IDQsIHNoYXBlID0gMTcsIGNvbG9yID0gIiNDNjI4MjgiKSArDQogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDU1KSkgKw0KICBsYWJzKHggPSAiVGllbXBvIChkw61hcykiLCB5ID0gIkFsdHVyYSBwcm9tZWRpbyAoY20pIikgKw0KICB0ZW1hX3Bybw0KYGBgDQoNCiMjIFJlc3B1ZXN0YQ0KDQpFbCBtb2RlbG8gbGluZWFsIGVzdGFibGVjZSBxdWUgbGFzIHBsw6FudHVsYXMgZGUgZnJpam9sIGNyZWNlbiAxLjA5IGNtIHBvciBkw61hLiBDb24gZXN0ZSBtb2RlbG8sIGxhIGFsdHVyYSBkZSBsYXMgcGxhbnRhcyBlcyBkZSA0NS43IGNtIGVuIGVsIGTDrWEgNDAgeSBkZSA1OC44IGNtIGVuIGVsIGTDrWEgNTIgKHRyacOhbmd1bG9zIHJvam9zIGVuIGVsIGdyw6FmaWNvKS4NCg0KQ29tbyBlbmNhcmdhZGEgZGVsIGxhYm9yYXRvcmlvLCB0b21hcsOtYSBsYXMgc2lndWllbnRlcyBkZWNpc2lvbmVzIHBhcmEgYXVtZW50YXIgZWwgY3JlY2ltaWVudG86IG9wdGltaXphciBsYSBjYW50aWRhZCB5IGxhIGR1cmFjacOzbiBkZSBsYSBsdXosIG1lam9yYXIgZWwgc3VzdHJhdG8geSBsYSBmZXJ0aWxpemFjacOzbiwgYWp1c3RhciBlbCB2b2x1bWVuIGRlIHJpZWdvIHkgZXZhbHVhciB0ZW1wZXJhdHVyYXMgY2VyY2FuYXMgYSAyNSDCsEMuIENhZGEgZmFjdG9yIHNlIHBydWViYSBlbiB1biBleHBlcmltZW50byBjb250cm9sYWRvLCBjYW1iaWFuZG8gdW5hIHNvbGEgdmFyaWFibGUgYSBsYSB2ZXogeSBjb21wYXJhbmRvIGxhcyB0YXNhcyBkZSBjcmVjaW1pZW50by4NCg0KRWwgbW9kZWxvIGxpbmVhbCBubyBpbmNvcnBvcmEgdW4gbMOtbWl0ZSBkZSBjcmVjaW1pZW50bywgbWllbnRyYXMgcXVlIGxhcyBwbGFudGFzIHJlYWxlcyBkZWphbiBkZSBjcmVjZXIgYWwgYWxjYW56YXIgc3UgYWx0dXJhIG3DoXhpbWEuIFBvciBlc28sIGxhIHByZWRpY2Npw7NuIGRlbCBkw61hIDUyIHNvYnJlc3RpbWEgbGEgYWx0dXJhIHJlYWwuDQoNCiMgUHJvYmxlbWEgMg0KDQpMYSBsYXBhIHJvamEgbyBndWFjYW1heWEgcm9qYSAoKkFyYSBtYWNhbyopIGZ1ZSBjYXNpIGVsaW1pbmFkYSBkZSBidWVuYSBwYXJ0ZSBkZWwgUGFjw61maWNvIGRlIENvc3RhIFJpY2EgcG9yIGxhIHDDqXJkaWRhIGRlIGJvc3F1ZSB5IGxhIGNhcHR1cmEgZGUgcG9sbHVlbG9zLiBHcmFjaWFzIGEgcHJvZ3JhbWFzIGRlIGNvbnNlcnZhY2nDs24geSByZWludHJvZHVjY2nDs24sIGFsZ3VuYXMgcG9ibGFjaW9uZXMgc2UgaGFuIHJlY3VwZXJhZG8uDQoNCkltYWdpbmVuIHF1ZSB1biBwcm9ncmFtYSBkZSBjb25zZXJ2YWNpw7NuIGxpYmVyw7MgdW4gZ3J1cG8gcGVxdWXDsW8gZGUgbGFwYXMgcm9qYXMgZW4gdW4gYm9zcXVlIHByb3RlZ2lkbyBkZWwgUGFjw61maWNvIGNlbnRyYWwgeSBsYXMgY2Vuc8OzICoqY2FkYSBhw7FvIGR1cmFudGUgMjAgYcOxb3MqKi4gVXN0ZWRlcyBkZWJlbiBhanVzdGFyIHVuICoqbW9kZWxvIGxvZ8Otc3RpY28qKiBhIGxvcyBkYXRvcyB5IGVzdGltYXIgbG9zIHBhcsOhbWV0cm9zIHF1ZSBkZXNjcmliZW4gZWwgY3JlY2ltaWVudG8gZGUgZXN0YSBwb2JsYWNpw7NuLiBDb21vIHRvbWFkb3JlcyBkZSBkZWNpc2nDs24sIGVzcGVjaWZpcXVlbiBjdcOhbmRvIGRlYmVyw6EgZGUgdGVybWluYXIgZWwgbW9uaXRvcmVvIGVjb2zDs2dpY28sIHNlZ8O6biBlbCBjb21wb3J0YW1pZW50byBwb2JsYWNpb25hbC4NCg0KYGBge3IgcHJvYmxlbWEyfQ0KYWp1c3RlMiA8LSBmaXRfZ3Jvd3RobW9kZWwoDQogIEZVTiAgID0gZ3Jvd19sb2dpc3RpYywNCiAgcCAgICAgPSBjKHkwID0gMTIsIG11bWF4ID0gMC41LCBLID0gMTkwKSwNCiAgdGltZSAgPSBkMiRNdWVzdHJlbywNCiAgeSAgICAgPSBkMiRJbmRpdmlkdW9zLA0KICBsb3dlciA9IGMoeTAgPSAxLCBtdW1heCA9IDAsIEsgPSAxKSwNCiAgdXBwZXIgPSBjKHkwID0gMTAwLCBtdW1heCA9IDMsIEsgPSAyMDAwKQ0KKQ0KcHJpbnQoc3VtbWFyeShhanVzdGUyKSkNCnAyIDwtIGNvZWYoYWp1c3RlMikNCnByaW50KHAyKQ0KDQpjdXJ2YTIgPC0gYXMuZGF0YS5mcmFtZShncm93X2xvZ2lzdGljKHNlcSgwLCAyMCwgMC4xKSwgcDIpKQ0KDQpnZ3Bsb3QoKSArDQogIGdlb21fcG9pbnQoZGF0YSA9IGQyLCBhZXMoTXVlc3RyZW8sIEluZGl2aWR1b3MpLCBzaXplID0gMywgY29sb3IgPSAiI0M2MjgyOCIpICsNCiAgZ2VvbV9saW5lKGRhdGEgPSBjdXJ2YTIsIGFlcyh0aW1lLCB5KSwgbGluZXdpZHRoID0gMS4yLCBjb2xvciA9ICIjMTU2NUMwIikgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBwMlsiSyJdLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJncmV5NDAiKSArDQogIGxhYnMoeCA9ICJBw7FvIGRlIG11ZXN0cmVvIiwgeSA9ICJJbmRpdmlkdW9zIikgKw0KICB0ZW1hX3Bybw0KDQojIEHDsW8gZW4gcXVlIHNlIGFsY2FuemEgNTAgJSwgOTAgJSB5IDk1ICUgZGUgSw0KcHJpbnQodF9hbGNhbnphKDAuNSAqIHAyWyJLIl0sIHAyKSkNCnByaW50KHRfYWxjYW56YSgwLjkgKiBwMlsiSyJdLCBwMikpDQpwcmludCh0X2FsY2FuemEoMC45NSAqIHAyWyJLIl0sIHAyKSkNCmBgYA0KDQojIyBSZXNwdWVzdGENCg0KRWwgbW9kZWxvIGxvZ8Otc3RpY28gYWp1c3RhZG8gYSBsb3MgY2Vuc29zIGRlIGxhcGEgcm9qYSB0aWVuZSB1bmEgcG9ibGFjacOzbiBpbmljaWFsICh5MCkgZGUgMTIgbGFwYXMsIHVuYSB0YXNhIGRlIGNyZWNpbWllbnRvIChtdW1heCkgZGUgMC4zNSBwb3IgYcOxbyB5IHVuYSBjYXBhY2lkYWQgZGUgY2FyZ2EgKEspIGRlIDE4MCBpbmRpdmlkdW9zIChsw61uZWEgcHVudGVhZGEgZW4gZWwgZ3LDoWZpY28pLiBMb3MgdHJlcyBwYXLDoW1ldHJvcyBzb24gYWx0YW1lbnRlIHNpZ25pZmljYXRpdm9zIChwIDwgMC4wMDEpIHkgZWwgZXJyb3IgcmVzaWR1YWwgZXMgYmFqbywgcG9yIGxvIHF1ZSBlbCBtb2RlbG8gZGVzY3JpYmUgY29ycmVjdGFtZW50ZSBlbCBjb21wb3J0YW1pZW50byBkZSBsYSBwb2JsYWNpw7NuLg0KDQpMYSBwb2JsYWNpw7NuIGNyZWNlIGxlbnRhbWVudGUgYWwgaW5pY2lvLCBzZSBhY2VsZXJhIGhhc3RhIGxsZWdhciBhIGxhIG1pdGFkIGRlIEsgKDkwIGxhcGFzKSBlbiBlbCBhw7FvIDcuNSB5IGx1ZWdvIHNlIGRlc2FjZWxlcmEgaGFzdGEgZXN0YWJpbGl6YXJzZS4gQWxjYW56YSBlbCA5MCAlIGRlIEsgZW4gZWwgYcOxbyAxMy44IHkgZWwgOTUgJSBlbiBlbCBhw7FvIDE1LjkuDQoNCkVsIG1vbml0b3JlbyBlY29sw7NnaWNvIGRlYmUgdGVybWluYXIgZW4gZWwgYcOxbyAxNiwgY3VhbmRvIGxhIHBvYmxhY2nDs24gZXN0w6EgZW4gc3UgY2FwYWNpZGFkIGRlIGNhcmdhIHkgc3UgY3JlY2ltaWVudG8gZXMgbnVsby4gRGVzcHXDqXMgZGUgZXNhIGZlY2hhIHNlIG1hbnRpZW5lIHVuIG1vbml0b3JlbyBlc3BhY2lhZG8sIGNhZGEgMyBhIDUgYcOxb3MsIHBhcmEgZGV0ZWN0YXIgYW1lbmF6YXMgY29tbyBsYSBww6lyZGlkYSBkZSBib3NxdWUgeSBsYSBjYXB0dXJhIGRlIHBvbGx1ZWxvcy4NCg0KIyBQcm9ibGVtYSAzDQoNCkVuIGxvcyBib3NxdWVzIG51Ym9zb3MgZGUgbGEgY29yZGlsbGVyYSBkZSBUaWxhcsOhbiwgdW4gYW5maWJpbyBlbmTDqW1pY28gKGVzcGVjaWUgZmljdGljaWEsIGluc3BpcmFkYSBlbiBsbyBvY3VycmlkbyBjb24gZWwgc2FwbyBkb3JhZG8gZGUgTW9udGV2ZXJkZSkgbWFudGVuw61hIHVuYSBwb2JsYWNpw7NuIGVzdGFibGUgZGUgdW5vcyA1MDAgaW5kaXZpZHVvcy4gQSBwYXJ0aXIgZGUgY2llcnRvIG1vbWVudG8sIGxhIGxsZWdhZGEgZGUgdW4gaG9uZ28gcGF0w7NnZW5vIChxdWl0cmlkaW9taWNvc2lzKSB5IGVsIGF1bWVudG8gZGUgbGEgdGVtcGVyYXR1cmEgaGljaWVyb24gcXVlIGxhcyBtdWVydGVzIHN1cGVyYXJhbiBhIGxvcyBuYWNpbWllbnRvcy4gVW4gZXF1aXBvIGRlIGJpw7Nsb2dvcyBjZW5zw7MgbGEgcG9ibGFjacOzbiAqKmNhZGEgYcOxbyBkdXJhbnRlIDEyIGHDsW9zKiouIChtdW1heCA9IC0wLjMsIEsgPSA1NTApDQoNClVzdGVkZXMgZGViZW4gYWp1c3RhciB1biAqKm1vZGVsbyBsb2fDrXN0aWNvIGNvbiB0YXNhIGRlIGNyZWNpbWllbnRvKiogeSB1c2FybG8gcGFyYSBwcmVkZWNpciAqKmN1w6FuZG8gZGVzYXBhcmVjZXLDoSBsYSBwb2JsYWNpw7NuKiouDQoNCmBgYHtyIHByb2JsZW1hM30NCmFqdXN0ZSA8LSBmaXRfZ3Jvd3RobW9kZWwoDQogIEZVTiAgID0gZ3Jvd19sb2dpc3RpYywNCiAgcCAgICAgPSBjKHkwID0gNDgwLCBtdW1heCA9IC0wLjMsIEsgPSA1NTApLA0KICB0aW1lICA9IGQzJE11ZXN0cmVvLA0KICB5ICAgICA9IGQzJEluZGl2aWR1b3MsDQogIGxvd2VyID0gYyh5MCA9IDEsICAgIG11bWF4ID0gLTMsIEsgPSAxKSwNCiAgdXBwZXIgPSBjKHkwID0gMjAwMCwgbXVtYXggPSAwLCAgSyA9IDUwMDApDQopDQoNCnByaW50KHN1bW1hcnkoYWp1c3RlKSkNCnAzIDwtIGNvZWYoYWp1c3RlKQ0KcHJpbnQocDMpDQoNCiMgTsO6bWVybyBkZSBpbmRpdmlkdW9zIGVuIGxvcyBhw7FvcyAyMCwgNDAgeSA1MA0KdF9wcmVkIDwtIGMoMjAsIDQwLCA1MCkNCk5fcHJlZCA8LSBncm93X2xvZ2lzdGljKHRfcHJlZCwgcDMpWywgInkiXQ0KcHJpbnQoZGF0YS5mcmFtZShBbmlvID0gdF9wcmVkLCBJbmRpdmlkdW9zID0gTl9wcmVkKSkNCg0KIyBBw7FvIGVuIHF1ZSBxdWVkYSBtZW5vcyBkZSAxIGluZGl2aWR1bw0KcHJpbnQodF9hbGNhbnphKDEsIHAzKSkNCg0KY3VydmEzIDwtIGFzLmRhdGEuZnJhbWUoZ3Jvd19sb2dpc3RpYyhzZXEoMCwgMzAsIDAuMSksIHAzKSkNCg0KZ2dwbG90KCkgKw0KICBnZW9tX3BvaW50KGRhdGEgPSBkMywgYWVzKE11ZXN0cmVvLCBJbmRpdmlkdW9zKSwgc2l6ZSA9IDMsIGNvbG9yID0gIiNDNjI4MjgiKSArDQogIGdlb21fbGluZShkYXRhID0gY3VydmEzLCBhZXModGltZSwgeSksIGxpbmV3aWR0aCA9IDEuMiwgY29sb3IgPSAiIzE1NjVDMCIpICsNCiAgbGFicyh4ID0gIkHDsW8gZGUgbXVlc3RyZW8iLCB5ID0gIkluZGl2aWR1b3MiKSArDQogIHRlbWFfcHJvDQpgYGANCg0KIyMgUmVzcHVlc3RhDQoNCkVsIG1vZGVsbyBsb2fDrXN0aWNvIGNvbiB0YXNhIG5lZ2F0aXZhIGFqdXN0YSBsb3MgY2Vuc29zIGNvbiB1bmEgcG9ibGFjacOzbiBpbmljaWFsICh5MCkgZGUgNDgwIGluZGl2aWR1b3MsIHVuYSB0YXNhIGRlIGNyZWNpbWllbnRvIChtdW1heCkgZGUgLTAuNDUgcG9yIGHDsW8sIGVzIGRlY2lyLCB1bmEgZGlzbWludWNpw7NuIGRlIDQ1ICUgYW51YWwsIHkgdW5hIGNhcGFjaWRhZCBkZSBjYXJnYSAoSykgZGUgNTAwIGluZGl2aWR1b3MuDQoNCkVsIG1vZGVsbyBwcmVkaWNlIDEuNSBpbmRpdmlkdW9zIGVuIGVsIGHDsW8gMjAgeSB1bmEgcG9ibGFjacOzbiBkZSAwIGVuIGxvcyBhw7FvcyA0MCB5IDUwLiBMYSBwb2JsYWNpw7NuIGJhamEgZGUgdW4gaW5kaXZpZHVvIGVuIGVsIGHDsW8gMjEsIHkgZXNlIGVzIGVsIG1vbWVudG8gZW4gcXVlIGRlc2FwYXJlY2UuDQoNCkNvbiBlbCBob25nbyBwYXTDs2dlbm8geSBlbCBhdW1lbnRvIGRlIHRlbXBlcmF0dXJhLCBsYSBwb2JsYWNpw7NuIHNlIGV4dGluZ3VlIGVuIDIxIGHDsW9zIGRlc2RlIGVsIGluaWNpbyBkZSBsb3MgY2Vuc29zLiBMYXMgYWNjaW9uZXMgZGUgY29uc2VydmFjacOzbiBkZWJlbiBlamVjdXRhcnNlIGFudGVzIGRlIGVzZSBwbGF6by4NCg==