White paper: Aplicación de random-forest al mantenimiento crítico

Autores: Ricardo R. Palma[1] , Victoria I. P. Cieri [2]

Filiación: [1]Instituto de Ingeniería Industrial [2] YPF Dirección de Mantenimiento Destilería Lujan de Cuyo

Contacto: ricardo.rpalma[1] , victoria.cieri[2] [1,2]@gmail.com

Correspondig author: [1]

DOI: 10.5281/zenodo.17663214

Modelo Evaluación final

Este es un modelo ejemplo de hipótesis de mínima del trabajo presentado para aprobar el curso.

Lo ideal sería tener un trabajo tipo artículo científico (paper) en el que emplees algunos de los métodos desarrollados en el curso, pero si no es posible conseguirlo en el tiempo estipulado te pido que lo publiques aquí.

Si me das tu autorización los mejores trabajos puedo subirlos a la biblioteca y otorgarles in DOI. En ese caso la universidad me pide que algún profesor de la UNCuyo aparezca como co-autor (ultimo autor)

Todos los trabajos deberán tener además una copia del código fuente (Rmd) conjunto de datos y versiones anterióres del código en GitHub.

Utiliza el preambulo de Rmd que tiene este trabajo para que aparezca el índice de contenidos.

Creación del Dataset

Crearemos un dataset ficticio utilizando distribuciones de probabilidad que ya tiene R

# Cargar librerías necesarias (instalar si no están)
# install.packages("randomForest")
# install.packages("dplyr")

library(randomForest)
## randomForest 4.7-1.1
## Type rfNews() to see new features/changes/bug fixes.
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following object is masked from 'package:randomForest':
## 
##     combine
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
# Fijar una semilla para reproducibilidad
#set.seed(123)

# Número de observaciones
n <- 200

# Generar datos sintéticos
datos_mantenimiento <- data.frame(
  Tiempo_Funcionamiento_Horas = round(rnorm(n, mean = 1500, sd = 500)),
  Operario = sample(c("Operario_A", "Operario_B", "Operario_C"), n, replace = TRUE),
  Piezas_Producidas = round(rnorm(n, mean = 25000, sd = 10000)),
  Pronostico_Fecha_Prox_Mant = as.Date("2026-01-01") + sample(1:100, n, replace = TRUE),
  Falla_Presentada = sample(c("Desgaste_natural", "Fallo_electronico", "Fallo_mecanico", "Error_operativo"), n, replace = TRUE),
  Costo_Reparacion_USD = round(rnorm(n, mean = 500, sd = 200)),
  Vibracion_mm_s = rnorm(n, mean = 3.5, sd = 1.5), # Columna adicional interesante
  Temperatura_C = rnorm(n, mean = 65, sd = 10),    # Columna adicional interesante
  Familia_Equipo = sample(c("Bomba", "Ventilador", "Motor_Electrico", "Compresor"), n, replace = TRUE) # Variable objetivo
)

# Asegurar que las variables categóricas sean factores
datos_mantenimiento$Operario <- as.factor(datos_mantenimiento$Operario)
datos_mantenimiento$Falla_Presentada <- as.factor(datos_mantenimiento$Falla_Presentada)
datos_mantenimiento$Familia_Equipo <- as.factor(datos_mantenimiento$Familia_Equipo)

# Mostrar las primeras filas del dataset
head(datos_mantenimiento)
##   Tiempo_Funcionamiento_Horas   Operario Piezas_Producidas
## 1                        2090 Operario_C             37902
## 2                        1652 Operario_A             26709
## 3                        1402 Operario_C             37588
## 4                        1268 Operario_A             22084
## 5                         999 Operario_B             32368
## 6                         975 Operario_A              3089
##   Pronostico_Fecha_Prox_Mant  Falla_Presentada Costo_Reparacion_USD
## 1                 2026-03-20   Error_operativo                  237
## 2                 2026-01-27  Desgaste_natural                  638
## 3                 2026-02-19   Error_operativo                  843
## 4                 2026-01-26  Desgaste_natural                  174
## 5                 2026-02-18 Fallo_electronico                  378
## 6                 2026-01-06   Error_operativo                  763
##   Vibracion_mm_s Temperatura_C  Familia_Equipo
## 1       2.600083      66.71456 Motor_Electrico
## 2       3.241373      70.71830      Ventilador
## 3       1.064169      63.45398           Bomba
## 4       5.230549      61.50585       Compresor
## 5       3.398048      77.14854           Bomba
## 6       4.748960      71.49551 Motor_Electrico

División de Datos Entrenamiento y Prueba

# División de datos
indices_entrenamiento <- sample(1:nrow(datos_mantenimiento), 0.7 * nrow(datos_mantenimiento))
datos_entrenamiento <- datos_mantenimiento[indices_entrenamiento, ]
datos_prueba <- datos_mantenimiento[-indices_entrenamiento, ]
indices_entrenamiento
##   [1]  67  25 184 116  53 140  93 153  43  59 102 190 111  48 191  31 149 178
##  [19] 189 108  74  56  45  38  23   6 174 124 135 180  36 141 103  16 152  20
##  [37]   8  66 109   1 147   2 134  52 166 117  60  55  61 185 192  32 154  71
##  [55]  34 173  62  29 195  49  80  88 183 119  22  28 165 179  86  21  96  70
##  [73]  12  57  64 198  40  44  13 157  77 182 105 160 194  42 139 113  69   7
##  [91]  81 122 155 132 188 114 129 200 171  19  26 177 150 168 106  95 110 138
## [109]  14 158 118 136 169  82  35 156  54 126 131  72 167  24 148  87 172 170
## [127]  33 159  73  17  91 128 115 199 186 142  11 133   5   4

Entrenamiento del Modelo Random Forest

Se utiliza la función randomForest() del paquete randomForest. Por defecto, construye 500 árboles de decisión. Nota Importante: La columna Pronostico_Fecha_Prox_Mant se excluye del entrenamiento ya que es un valor de fecha que no aporta información de clasificación directa a menos que se extraigan características como el mes, día de la semana, etc.

# Entrenar el modelo
# La sintaxis es Familia_Equipo ~ . (predecir Familia_Equipo usando todas las demás variables)
# Se excluye la columna de fecha por simplicidad en este ejemplo
modelo_rf <- randomForest(Falla_Presentada ~ Tiempo_Funcionamiento_Horas + Operario + 
                          Piezas_Producidas + Familia_Equipo + Costo_Reparacion_USD + 
                          Vibracion_mm_s + Temperatura_C, 
                          data = datos_entrenamiento, 
                          ntree = 500,       # Número de árboles
                          importance = TRUE) # Calcular importancia de variables

# Ver un resumen del modelo
print(modelo_rf)
## 
## Call:
##  randomForest(formula = Falla_Presentada ~ Tiempo_Funcionamiento_Horas +      Operario + Piezas_Producidas + Familia_Equipo + Costo_Reparacion_USD +      Vibracion_mm_s + Temperatura_C, data = datos_entrenamiento,      ntree = 500, importance = TRUE) 
##                Type of random forest: classification
##                      Number of trees: 500
## No. of variables tried at each split: 2
## 
##         OOB estimate of  error rate: 71.43%
## Confusion matrix:
##                   Desgaste_natural Error_operativo Fallo_electronico
## Desgaste_natural                 4               9                 4
## Error_operativo                  3              13                10
## Fallo_electronico                2               9                 5
## Fallo_mecanico                   1              13                12
##                   Fallo_mecanico class.error
## Desgaste_natural              10   0.8518519
## Error_operativo               11   0.6486486
## Fallo_electronico             16   0.8437500
## Fallo_mecanico                18   0.5909091

Predicción y Evaluación del Modelo

Se utiliza el modelo entrenado para predecir la familia de equipo en los datos de prueba y se evalúa su rendimiento.

# Realizar predicciones en el conjunto de prueba
predicciones <- predict(modelo_rf, newdata = datos_prueba)

# Crear una matriz de confusión para evaluar la precisión
matriz_confusion <- table(Datos_Reales = datos_prueba$Familia_Equipo, Predicciones = predicciones)
print(matriz_confusion)
##                  Predicciones
## Datos_Reales      Desgaste_natural Error_operativo Fallo_electronico
##   Bomba                          1               6                 4
##   Compresor                      1               3                 1
##   Motor_Electrico                0               2                 4
##   Ventilador                     3               0                 3
##                  Predicciones
## Datos_Reales      Fallo_mecanico
##   Bomba                       10
##   Compresor                    9
##   Motor_Electrico              7
##   Ventilador                   6
# Calcular la precisión general
precision <- sum(diag(matriz_confusion)) / sum(matriz_confusion)
cat("Precisión del modelo:", precision, "\n")
## Precisión del modelo: 0.2333333

Análisis de Importancia de Variables

Random Forest permite ver qué variables fueron más importantes para tomar las decisiones de clasificación.

# Mostrar la importancia de las variables
importancia <- importance(modelo_rf)
print(importancia)
##                             Desgaste_natural Error_operativo Fallo_electronico
## Tiempo_Funcionamiento_Horas        2.6374377      -0.5539971       -1.93286919
## Operario                           0.2388746       1.6387342        0.02594127
## Piezas_Producidas                  2.4078019      -1.2029312       -1.32847188
## Familia_Equipo                     0.6453040       2.6076976       -3.05438766
## Costo_Reparacion_USD               4.5535025       0.7634015        0.62503094
## Vibracion_mm_s                    -0.8482376       1.8281170        0.65169975
## Temperatura_C                     -5.3697048      -0.1318688        1.64066296
##                             Fallo_mecanico MeanDecreaseAccuracy
## Tiempo_Funcionamiento_Horas     -1.5361375           -1.1376786
## Operario                        -3.0678862           -0.9531902
## Piezas_Producidas                2.5762136            1.1970604
## Familia_Equipo                   3.2760023            2.3084396
## Costo_Reparacion_USD             0.1896795            2.6347503
## Vibracion_mm_s                   4.2385872            3.5022211
## Temperatura_C                   -0.1430643           -1.8089785
##                             MeanDecreaseGini
## Tiempo_Funcionamiento_Horas        17.540200
## Operario                            5.954963
## Piezas_Producidas                  17.490875
## Familia_Equipo                      9.200833
## Costo_Reparacion_USD               17.920656
## Vibracion_mm_s                     17.960408
## Temperatura_C                      16.944842
# Visualizar la importancia de las variables
varImpPlot(modelo_rf)

Mejora del gráfico de importancia de variables

# Instalar si es necesario
# install.packages("ggplot2")
# install.packages("tibble") # útil para convertir la matriz a dataframe fácilmente

library(ggplot2)
## 
## Attaching package: 'ggplot2'
## The following object is masked from 'package:randomForest':
## 
##     margin
library(tibble)
library(dplyr)

Paso 1: Preparar los datos de importancia para ggplot2

La función importance() devuelve una matriz. Debemos convertirla en un data.frame manejable y extraer la métrica que nos interesa visualizar (comúnmente %IncMSE para regresión o MeanDecreaseGini para clasificación). En este caso, usaremos MeanDecreaseGini que mide cuánto reduce el Gini la variable en promedio.

# Extraer la importancia y convertirla en un data frame
df_importancia <- as.data.frame(importance(modelo_rf, scale = TRUE)) %>%
  rownames_to_column(var = "Variable") %>%
  arrange(desc(MeanDecreaseGini)) # Ordenar por importancia descendente

# Mostrar los datos de importancia preparados
print(df_importancia)
##                      Variable Desgaste_natural Error_operativo
## 1              Vibracion_mm_s       -0.8482376       1.8281170
## 2        Costo_Reparacion_USD        4.5535025       0.7634015
## 3 Tiempo_Funcionamiento_Horas        2.6374377      -0.5539971
## 4           Piezas_Producidas        2.4078019      -1.2029312
## 5               Temperatura_C       -5.3697048      -0.1318688
## 6              Familia_Equipo        0.6453040       2.6076976
## 7                    Operario        0.2388746       1.6387342
##   Fallo_electronico Fallo_mecanico MeanDecreaseAccuracy MeanDecreaseGini
## 1        0.65169975      4.2385872            3.5022211        17.960408
## 2        0.62503094      0.1896795            2.6347503        17.920656
## 3       -1.93286919     -1.5361375           -1.1376786        17.540200
## 4       -1.32847188      2.5762136            1.1970604        17.490875
## 5        1.64066296     -0.1430643           -1.8089785        16.944842
## 6       -3.05438766      3.2760023            2.3084396         9.200833
## 7        0.02594127     -3.0678862           -0.9531902         5.954963

Paso 2: Crear el gráfico con ggplot2

Usaremos un gráfico de barras (geom_bar) ordenado para mostrar claramente qué variables tienen el mayor impacto.

# Graficar la importancia de las variables con ggplot2
ggplot(df_importancia, aes(x = reorder(Variable, MeanDecreaseGini), y = MeanDecreaseGini, fill = MeanDecreaseGini)) +
  geom_bar(stat = "identity") +
  coord_flip() + # Voltear las coordenadas para una mejor lectura de las etiquetas largas
  labs(
    title = "Importancia de las Variables en el Modelo Random Forest",
    subtitle = "Medida por Mean Decrease Gini",
    x = "Variable",
    y = "Mean Decrease Gini (Importancia Relativa)",
    fill = "Importancia"
  ) +
  theme_minimal() +
  scale_fill_viridis_c(option = "plasma") + # Usar una paleta de colores moderna
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    plot.subtitle = element_text(hjust = 0.5),
    axis.text.y = element_text(size = 10)
  )

Explicación del Gráfico Mejorado

  • reorder(Variable, MeanDecreaseGini): Ordena automáticamente las barras de menor a mayor importancia, haciendo que el gráfico sea mucho más fácil de interpretar de un vistazo.

  • coord_flip(): Convierte el gráfico de barras vertical tradicional en uno horizontal, lo cual es ideal para etiquetas de variables largas como las que tenemos.

  • theme_minimal(): Aplica un tema limpio y minimalista que es estéticamente superior al gráfico base de R.

  • scale_fill_viridis_c(option = “plasma”): Aplica una paleta de colores perceptualmente uniforme y apta para daltónicos (del paquete viridis, que ggplot2 puede usar por defecto).

Este gráfico proporciona una visualización clara y profesional de cuáles son los factores más críticos para determinar la familia de equipo que requiere mantenimiento, según tu modelo de Random Forest.

Scheduling de mantenimiento

Para crear un gráfico de Gantt cronológicamente ordenado utilizando la columna Pronostico_Fecha_Prox_Mant y ggplot2, primero debemos decidir qué representa el “rango de tiempo” para cada elemento, ya que un gráfico de Gantt requiere una fecha de inicio y una fecha de finalización. En este ejemplo, asumiremos que el punto de inicio de la tarea de mantenimiento es la fecha del pronóstico (Pronostico_Fecha_Prox_Mant), y definiremos una duración fija para la tarea de mantenimiento (por ejemplo, 2 días) para simular el rango. Agruparemos las tareas por Familia_Equipo o por Operario para visualizarlas.

library(ggplot2)
library(dplyr)
library(lubridate) # Para manejar fechas fácilmente
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
# Asumimos que 'datos_mantenimiento' del ejemplo anterior está disponible.

# 1. Preparar los datos para el Gantt
# Creamos una fecha de inicio (la fecha pronosticada) y una fecha de fin (inicio + 2 días de duración)
datos_gantt <- datos_mantenimiento %>%
  mutate(
    Fecha_Inicio = Pronostico_Fecha_Prox_Mant,
    Fecha_Fin = Fecha_Inicio + days(2), # Asumimos 2 días para el mantenimiento
    # Crear una etiqueta única para cada tarea para el eje Y
    Tarea_Equipo = paste(Familia_Equipo, Operario, row_number()) 
  ) %>%
  # Ordenar cronológicamente por fecha de inicio para asegurar el orden
  arrange(Fecha_Inicio) %>%
  # Convertir Tarea_Equipo a factor con el orden actual para que ggplot lo respete
  mutate(Tarea_Equipo = factor(Tarea_Equipo, levels = unique(Tarea_Equipo)))

# 2. Crear el gráfico de Gantt con ggplot2
ggplot(datos_gantt, aes(x = Fecha_Inicio, xend = Fecha_Fin, y = Tarea_Equipo, yend = Tarea_Equipo, color = Familia_Equipo)) +
  geom_segment(size = 5) + # geom_segment crea las barras del Gantt
  labs(
    title = "Cronograma de Próximos Mantenimientos (Gantt)",
    subtitle = "Tareas ordenadas cronológicamente",
    x = "Fecha de Mantenimiento",
    y = "Tarea / Equipo Individual",
    color = "Familia de Equipo"
  ) +
  scale_x_date(date_labels = "%Y-%m-%d", date_breaks = "week") + # Formatear el eje X para fechas legibles
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    axis.text.x = element_text(angle = 45, hjust = 1), # Rotar etiquetas X para evitar solapamiento
    axis.text.y = element_blank(), # Ocultar etiquetas del eje Y si hay muchas tareas individuales
    axis.ticks.y = element_blank(),
    panel.grid.major.y = element_blank() # Eliminar líneas de cuadrícula Y para un aspecto más limpio
  )
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Prueba interactivo

Este gráfico es semejante al anterior, pero tocando el color del tipo de equipo nos permite filtrar las fechas.

library(ggplot2)
library(dplyr)
library(lubridate)
library(plotly) # Cargar la librería plotly
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
# Asumimos que 'datos_mantenimiento' está disponible. 
# Si no lo está, asegúrate de ejecutar el código de creación del dataset original.

# 1. Preparar los datos para el Gantt (con adición de texto para tooltip)
datos_gantt_interactivo <- datos_mantenimiento %>%
  mutate(
    Fecha_Inicio = Pronostico_Fecha_Prox_Mant,
    Fecha_Fin = Fecha_Inicio + days(2), # Asumimos 2 días para el mantenimiento
    # Crear una etiqueta única para cada tarea para el eje Y
    Tarea_Equipo = paste(Familia_Equipo, Operario, row_number()),
    # >>>>>>>> AÑADIMOS EL TEXTO DEL TOOLTIP AQUÍ <<<<<<<<<
    tooltip_text = paste(
      "Equipo:", Familia_Equipo, 
      "| Fecha:", as.character(Fecha_Inicio)
    )
  ) %>%
  # Ordenar cronológicamente por fecha de inicio para asegurar el orden
  arrange(Fecha_Inicio) %>%
  # Convertir Tarea_Equipo a factor con el orden actual para que ggplot lo respete
  mutate(Tarea_Equipo = factor(Tarea_Equipo, levels = unique(Tarea_Equipo)))

# 2. Crear el gráfico de Gantt con ggplot2
# Mapeamos la variable 'tooltip_text' a la estética 'text'
gantt_plot_base <- ggplot(datos_gantt_interactivo, 
                          aes(x = Fecha_Inicio, xend = Fecha_Fin, y = Tarea_Equipo, yend = Tarea_Equipo, 
                              color = Familia_Equipo,
                              text = tooltip_text)) + # <--- Añadimos 'text' aquí
  geom_segment(size = 5) +
  labs(
    title = "Cronograma de Próximos Mantenimientos (Gantt Interactivo)",
    subtitle = "Tareas ordenadas cronológicamente",
    x = "Fecha de Mantenimiento",
    y = "Tarea / Equipo Individual",
    color = "Familia de Equipo"
  ) +
  scale_x_date(date_labels = "%Y-%m-%d", date_breaks = "week") + 
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    axis.text.x = element_text(angle = 45, hjust = 1), 
    axis.text.y = element_blank(), 
    axis.ticks.y = element_blank(),
    panel.grid.major.y = element_blank() 
  )

# 3. Convertir el gráfico ggplot en un gráfico interactivo con plotly
# Usamos tooltip = "text" para que solo se muestre nuestro texto personalizado al pasar el ratón.
gantt_interactivo <- ggplotly(gantt_plot_base, tooltip = "text")

# 4. Mostrar el gráfico interactivo
gantt_interactivo

Anexo:

Conjunto de datos raw

““,”Tecnologia”,“Normas”,“Capital”,“Equipo”,“Empresa” “1”,5.1,3.5,1.4,0.2,“CNB-Cerveza” “2”,4.9,3,1.4,0.2,“CNB-Cerveza” “3”,4.7,3.2,1.3,0.2,“CNB-Cerveza” “4”,4.6,3.1,1.5,0.2,“CNB-Cerveza” “5”,5,3.6,1.4,0.2,“CNB-Cerveza” “6”,5.4,3.9,1.7,0.4,“CNB-Cerveza” “7”,4.6,3.4,1.4,0.3,“CNB-Cerveza” “8”,5,3.4,1.5,0.2,“CNB-Cerveza” “9”,4.4,2.9,1.4,0.2,“CNB-Cerveza” “10”,4.9,3.1,1.5,0.1,“CNB-Cerveza” “11”,5.4,3.7,1.5,0.2,“CNB-Cerveza” “12”,4.8,3.4,1.6,0.2,“CNB-Cerveza” “13”,4.8,3,1.4,0.1,“CNB-Cerveza” “14”,4.3,3,1.1,0.1,“CNB-Cerveza” “15”,5.8,4,1.2,0.2,“CNB-Cerveza” “16”,5.7,4.4,1.5,0.4,“CNB-Cerveza” “17”,5.4,3.9,1.3,0.4,“CNB-Cerveza” “18”,5.1,3.5,1.4,0.3,“CNB-Cerveza” “19”,5.7,3.8,1.7,0.3,“CNB-Cerveza” “20”,5.1,3.8,1.5,0.3,“CNB-Cerveza” “21”,5.4,3.4,1.7,0.2,“CNB-Cerveza” “22”,5.1,3.7,1.5,0.4,“CNB-Cerveza” “23”,4.6,3.6,1,0.2,“CNB-Cerveza” “24”,5.1,3.3,1.7,0.5,“CNB-Cerveza” “25”,4.8,3.4,1.9,0.2,“CNB-Cerveza” “26”,5,3,1.6,0.2,“CNB-Cerveza” “27”,5,3.4,1.6,0.4,“CNB-Cerveza” “28”,5.2,3.5,1.5,0.2,“CNB-Cerveza” “29”,5.2,3.4,1.4,0.2,“CNB-Cerveza” “30”,4.7,3.2,1.6,0.2,“CNB-Cerveza” “31”,4.8,3.1,1.6,0.2,“CNB-Cerveza” “32”,5.4,3.4,1.5,0.4,“CNB-Cerveza” “33”,5.2,4.1,1.5,0.1,“CNB-Cerveza” “34”,5.5,4.2,1.4,0.2,“CNB-Cerveza” “35”,4.9,3.1,1.5,0.2,“CNB-Cerveza” “36”,5,3.2,1.2,0.2,“CNB-Cerveza” “37”,5.5,3.5,1.3,0.2,“CNB-Cerveza” “38”,4.9,3.6,1.4,0.1,“CNB-Cerveza” “39”,4.4,3,1.3,0.2,“CNB-Cerveza” “40”,5.1,3.4,1.5,0.2,“CNB-Cerveza” “41”,5,3.5,1.3,0.3,“CNB-Cerveza” “42”,4.5,2.3,1.3,0.3,“CNB-Cerveza” “43”,4.4,3.2,1.3,0.2,“CNB-Cerveza” “44”,5,3.5,1.6,0.6,“CNB-Cerveza” “45”,5.1,3.8,1.9,0.4,“CNB-Cerveza” “46”,4.8,3,1.4,0.3,“CNB-Cerveza” “47”,5.1,3.8,1.6,0.2,“CNB-Cerveza” “48”,4.6,3.2,1.4,0.2,“CNB-Cerveza” “49”,5.3,3.7,1.5,0.2,“CNB-Cerveza” “50”,5,3.3,1.4,0.2,“CNB-Cerveza” “51”,7,3.2,4.7,1.4,“FARMACORP” “52”,6.4,3.2,4.5,1.5,“FARMACORP” “53”,6.9,3.1,4.9,1.5,“FARMACORP” “54”,5.5,2.3,4,1.3,“FARMACORP” “55”,6.5,2.8,4.6,1.5,“FARMACORP” “56”,5.7,2.8,4.5,1.3,“FARMACORP” “57”,6.3,3.3,4.7,1.6,“FARMACORP” “58”,4.9,2.4,3.3,1,“FARMACORP” “59”,6.6,2.9,4.6,1.3,“FARMACORP” “60”,5.2,2.7,3.9,1.4,“FARMACORP” “61”,5,2,3.5,1,“FARMACORP” “62”,5.9,3,4.2,1.5,“FARMACORP” “63”,6,2.2,4,1,“FARMACORP” “64”,6.1,2.9,4.7,1.4,“FARMACORP” “65”,5.6,2.9,3.6,1.3,“FARMACORP” “66”,6.7,3.1,4.4,1.4,“FARMACORP” “67”,5.6,3,4.5,1.5,“FARMACORP” “68”,5.8,2.7,4.1,1,“FARMACORP” “69”,6.2,2.2,4.5,1.5,“FARMACORP” “70”,5.6,2.5,3.9,1.1,“FARMACORP” “71”,5.9,3.2,4.8,1.8,“FARMACORP” “72”,6.1,2.8,4,1.3,“FARMACORP” “73”,6.3,2.5,4.9,1.5,“FARMACORP” “74”,6.1,2.8,4.7,1.2,“FARMACORP” “75”,6.4,2.9,4.3,1.3,“FARMACORP” “76”,6.6,3,4.4,1.4,“FARMACORP” “77”,6.8,2.8,4.8,1.4,“FARMACORP” “78”,6.7,3,5,1.7,“FARMACORP” “79”,6,2.9,4.5,1.5,“FARMACORP” “80”,5.7,2.6,3.5,1,“FARMACORP” “81”,5.5,2.4,3.8,1.1,“FARMACORP” “82”,5.5,2.4,3.7,1,“FARMACORP” “83”,5.8,2.7,3.9,1.2,“FARMACORP” “84”,6,2.7,5.1,1.6,“FARMACORP” “85”,5.4,3,4.5,1.5,“FARMACORP” “86”,6,3.4,4.5,1.6,“FARMACORP” “87”,6.7,3.1,4.7,1.5,“FARMACORP” “88”,6.3,2.3,4.4,1.3,“FARMACORP” “89”,5.6,3,4.1,1.3,“FARMACORP” “90”,5.5,2.5,4,1.3,“FARMACORP” “91”,5.5,2.6,4.4,1.2,“FARMACORP” “92”,6.1,3,4.6,1.4,“FARMACORP” “93”,5.8,2.6,4,1.2,“FARMACORP” “94”,5,2.3,3.3,1,“FARMACORP” “95”,5.6,2.7,4.2,1.3,“FARMACORP” “96”,5.7,3,4.2,1.2,“FARMACORP” “97”,5.7,2.9,4.2,1.3,“FARMACORP” “98”,6.2,2.9,4.3,1.3,“FARMACORP” “99”,5.1,2.5,3,1.1,“FARMACORP” “100”,5.7,2.8,4.1,1.3,“FARMACORP” “101”,6.3,3.3,6,2.5,“SOFIA-Avicola” “102”,5.8,2.7,5.1,1.9,“SOFIA-Avicola” “103”,7.1,3,5.9,2.1,“SOFIA-Avicola” “104”,6.3,2.9,5.6,1.8,“SOFIA-Avicola” “105”,6.5,3,5.8,2.2,“SOFIA-Avicola” “106”,7.6,3,6.6,2.1,“SOFIA-Avicola” “107”,4.9,2.5,4.5,1.7,“SOFIA-Avicola” “108”,7.3,2.9,6.3,1.8,“SOFIA-Avicola” “109”,6.7,2.5,5.8,1.8,“SOFIA-Avicola” “110”,7.2,3.6,6.1,2.5,“SOFIA-Avicola” “111”,6.5,3.2,5.1,2,“SOFIA-Avicola” “112”,6.4,2.7,5.3,1.9,“SOFIA-Avicola” “113”,6.8,3,5.5,2.1,“SOFIA-Avicola” “114”,5.7,2.5,5,2,“SOFIA-Avicola” “115”,5.8,2.8,5.1,2.4,“SOFIA-Avicola” “116”,6.4,3.2,5.3,2.3,“SOFIA-Avicola” “117”,6.5,3,5.5,1.8,“SOFIA-Avicola” “118”,7.7,3.8,6.7,2.2,“SOFIA-Avicola” “119”,7.7,2.6,6.9,2.3,“SOFIA-Avicola” “120”,6,2.2,5,1.5,“SOFIA-Avicola” “121”,6.9,3.2,5.7,2.3,“SOFIA-Avicola” “122”,5.6,2.8,4.9,2,“SOFIA-Avicola” “123”,7.7,2.8,6.7,2,“SOFIA-Avicola” “124”,6.3,2.7,4.9,1.8,“SOFIA-Avicola” “125”,6.7,3.3,5.7,2.1,“SOFIA-Avicola” “126”,7.2,3.2,6,1.8,“SOFIA-Avicola” “127”,6.2,2.8,4.8,1.8,“SOFIA-Avicola” “128”,6.1,3,4.9,1.8,“SOFIA-Avicola” “129”,6.4,2.8,5.6,2.1,“SOFIA-Avicola” “130”,7.2,3,5.8,1.6,“SOFIA-Avicola” “131”,7.4,2.8,6.1,1.9,“SOFIA-Avicola” “132”,7.9,3.8,6.4,2,“SOFIA-Avicola” “133”,6.4,2.8,5.6,2.2,“SOFIA-Avicola” “134”,6.3,2.8,5.1,1.5,“SOFIA-Avicola” “135”,6.1,2.6,5.6,1.4,“SOFIA-Avicola” “136”,7.7,3,6.1,2.3,“SOFIA-Avicola” “137”,6.3,3.4,5.6,2.4,“SOFIA-Avicola” “138”,6.4,3.1,5.5,1.8,“SOFIA-Avicola” “139”,6,3,4.8,1.8,“SOFIA-Avicola” “140”,6.9,3.1,5.4,2.1,“SOFIA-Avicola” “141”,6.7,3.1,5.6,2.4,“SOFIA-Avicola” “142”,6.9,3.1,5.1,2.3,“SOFIA-Avicola” “143”,5.8,2.7,5.1,1.9,“SOFIA-Avicola” “144”,6.8,3.2,5.9,2.3,“SOFIA-Avicola” “145”,6.7,3.3,5.7,2.5,“SOFIA-Avicola” “146”,6.7,3,5.2,2.3,“SOFIA-Avicola” “147”,6.3,2.5,5,1.9,“SOFIA-Avicola” “148”,6.5,3,5.2,2,“SOFIA-Avicola” “149”,6.2,3.4,5.4,2.3,“SOFIA-Avicola” “150”,5.9,3,5.1,1.8,“SOFIA-Avicola”

LS0tCnRpdGxlOiAiUmFuZG9tIEZvcmVzdCBlbiBNYW50ZW5pbWllbnRvIENyw610aWNvIgphdXRob3I6ICJDb3JyZXNwb25kaW5nX0F1dGhvciBSLlBhbG1hIDxyaWNhcmRvLnJwYWxtYUBnbWFpbC5jb20+IgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiNjbHM6IC4vSUVFRXRyYW4uY2xzCiNiaWJsaW9ncmFwaHk6IC4vYmlibGlvLmJpYgojY3NsOiAuL2llZWUuY3NsCiNsaW5rLWNpdGF0aW9uczogdHJ1ZQotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAoKIyMgV2hpdGUgcGFwZXI6IEFwbGljYWNpw7NuIGRlIHJhbmRvbS1mb3Jlc3QgYWwgbWFudGVuaW1pZW50byBjcsOtdGljbwojIyMgQXV0b3JlczogICBSaWNhcmRvIFIuIFBhbG1hWzFdICwgVmljdG9yaWEgSS4gUC4gQ2llcmkgWzJdCiMjIyBGaWxpYWNpw7NuOiBbMV1JbnN0aXR1dG8gZGUgSW5nZW5pZXLDrWEgSW5kdXN0cmlhbCBbMl0gWVBGIERpcmVjY2nDs24gZGUgTWFudGVuaW1pZW50byBEZXN0aWxlcsOtYSBMdWphbiBkZSBDdXlvCiMjIyBDb250YWN0bzogcmljYXJkby5ycGFsbWFbMV0gLCB2aWN0b3JpYS5jaWVyaVsyXSAgWzEsMl1AZ21haWwuY29tCiMjIyBDb3JyZXNwb25kaWcgYXV0aG9yOiBbMV0KIyMjIERPSTogMTAuNTI4MS96ZW5vZG8uMTc2NjMyMTQKCgojIyBNb2RlbG8gRXZhbHVhY2nDs24gZmluYWwKCkVzdGUgZXMgdW4gbW9kZWxvIGVqZW1wbG8gZGUgaGlww7N0ZXNpcyBkZSBtw61uaW1hIGRlbCB0cmFiYWpvIHByZXNlbnRhZG8gcGFyYSBhcHJvYmFyIGVsIGN1cnNvLgoKTG8gaWRlYWwgc2Vyw61hIHRlbmVyIHVuIHRyYWJham8gdGlwbyBhcnTDrWN1bG8gY2llbnTDrWZpY28gKHBhcGVyKSBlbiBlbCBxdWUgZW1wbGVlcyBhbGd1bm9zIGRlIGxvcyBtw6l0b2RvcyBkZXNhcnJvbGxhZG9zIGVuIGVsIGN1cnNvLCBwZXJvIHNpIG5vIGVzIHBvc2libGUgY29uc2VndWlybG8gZW4gZWwgdGllbXBvIGVzdGlwdWxhZG8gdGUgcGlkbyBxdWUgbG8gcHVibGlxdWVzIGFxdcOtLgoKU2kgbWUgZGFzIHR1IGF1dG9yaXphY2nDs24gbG9zIG1lam9yZXMgdHJhYmFqb3MgcHVlZG8gc3ViaXJsb3MgYSBsYSBiaWJsaW90ZWNhIHkgb3RvcmdhcmxlcyBpbiBET0kuIEVuIGVzZSBjYXNvIGxhIHVuaXZlcnNpZGFkIG1lIHBpZGUgcXVlIGFsZ8O6biBwcm9mZXNvciBkZSBsYSBVTkN1eW8gYXBhcmV6Y2EgY29tbyBjby1hdXRvciAodWx0aW1vIGF1dG9yKQoKVG9kb3MgbG9zIHRyYWJham9zIGRlYmVyw6FuIHRlbmVyIGFkZW3DoXMgdW5hIGNvcGlhIGRlbCBjw7NkaWdvIGZ1ZW50ZSAoUm1kKSBjb25qdW50byBkZSBkYXRvcyB5IHZlcnNpb25lcyBhbnRlcmnDs3JlcyBkZWwgY8OzZGlnbyBlbiBHaXRIdWIuCgpVdGlsaXphIGVsIHByZWFtYnVsbyBkZSBSbWQgcXVlIHRpZW5lIGVzdGUgdHJhYmFqbyBwYXJhIHF1ZSBhcGFyZXpjYSBlbCDDrW5kaWNlIGRlIGNvbnRlbmlkb3MuCgoKCgoKCgojIyBDcmVhY2nDs24gZGVsIERhdGFzZXQKCkNyZWFyZW1vcyB1biBkYXRhc2V0IGZpY3RpY2lvIHV0aWxpemFuZG8gZGlzdHJpYnVjaW9uZXMgZGUgcHJvYmFiaWxpZGFkIHF1ZSB5YSB0aWVuZSBSCgpgYGB7cn0KIyBDYXJnYXIgbGlicmVyw61hcyBuZWNlc2FyaWFzIChpbnN0YWxhciBzaSBubyBlc3TDoW4pCiMgaW5zdGFsbC5wYWNrYWdlcygicmFuZG9tRm9yZXN0IikKIyBpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpCgpsaWJyYXJ5KHJhbmRvbUZvcmVzdCkKbGlicmFyeShkcGx5cikKCiMgRmlqYXIgdW5hIHNlbWlsbGEgcGFyYSByZXByb2R1Y2liaWxpZGFkCiNzZXQuc2VlZCgxMjMpCgojIE7Dum1lcm8gZGUgb2JzZXJ2YWNpb25lcwpuIDwtIDIwMAoKIyBHZW5lcmFyIGRhdG9zIHNpbnTDqXRpY29zCmRhdG9zX21hbnRlbmltaWVudG8gPC0gZGF0YS5mcmFtZSgKICBUaWVtcG9fRnVuY2lvbmFtaWVudG9fSG9yYXMgPSByb3VuZChybm9ybShuLCBtZWFuID0gMTUwMCwgc2QgPSA1MDApKSwKICBPcGVyYXJpbyA9IHNhbXBsZShjKCJPcGVyYXJpb19BIiwgIk9wZXJhcmlvX0IiLCAiT3BlcmFyaW9fQyIpLCBuLCByZXBsYWNlID0gVFJVRSksCiAgUGllemFzX1Byb2R1Y2lkYXMgPSByb3VuZChybm9ybShuLCBtZWFuID0gMjUwMDAsIHNkID0gMTAwMDApKSwKICBQcm9ub3N0aWNvX0ZlY2hhX1Byb3hfTWFudCA9IGFzLkRhdGUoIjIwMjYtMDEtMDEiKSArIHNhbXBsZSgxOjEwMCwgbiwgcmVwbGFjZSA9IFRSVUUpLAogIEZhbGxhX1ByZXNlbnRhZGEgPSBzYW1wbGUoYygiRGVzZ2FzdGVfbmF0dXJhbCIsICJGYWxsb19lbGVjdHJvbmljbyIsICJGYWxsb19tZWNhbmljbyIsICJFcnJvcl9vcGVyYXRpdm8iKSwgbiwgcmVwbGFjZSA9IFRSVUUpLAogIENvc3RvX1JlcGFyYWNpb25fVVNEID0gcm91bmQocm5vcm0obiwgbWVhbiA9IDUwMCwgc2QgPSAyMDApKSwKICBWaWJyYWNpb25fbW1fcyA9IHJub3JtKG4sIG1lYW4gPSAzLjUsIHNkID0gMS41KSwgIyBDb2x1bW5hIGFkaWNpb25hbCBpbnRlcmVzYW50ZQogIFRlbXBlcmF0dXJhX0MgPSBybm9ybShuLCBtZWFuID0gNjUsIHNkID0gMTApLCAgICAjIENvbHVtbmEgYWRpY2lvbmFsIGludGVyZXNhbnRlCiAgRmFtaWxpYV9FcXVpcG8gPSBzYW1wbGUoYygiQm9tYmEiLCAiVmVudGlsYWRvciIsICJNb3Rvcl9FbGVjdHJpY28iLCAiQ29tcHJlc29yIiksIG4sIHJlcGxhY2UgPSBUUlVFKSAjIFZhcmlhYmxlIG9iamV0aXZvCikKCiMgQXNlZ3VyYXIgcXVlIGxhcyB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzIHNlYW4gZmFjdG9yZXMKZGF0b3NfbWFudGVuaW1pZW50byRPcGVyYXJpbyA8LSBhcy5mYWN0b3IoZGF0b3NfbWFudGVuaW1pZW50byRPcGVyYXJpbykKZGF0b3NfbWFudGVuaW1pZW50byRGYWxsYV9QcmVzZW50YWRhIDwtIGFzLmZhY3RvcihkYXRvc19tYW50ZW5pbWllbnRvJEZhbGxhX1ByZXNlbnRhZGEpCmRhdG9zX21hbnRlbmltaWVudG8kRmFtaWxpYV9FcXVpcG8gPC0gYXMuZmFjdG9yKGRhdG9zX21hbnRlbmltaWVudG8kRmFtaWxpYV9FcXVpcG8pCgojIE1vc3RyYXIgbGFzIHByaW1lcmFzIGZpbGFzIGRlbCBkYXRhc2V0CmhlYWQoZGF0b3NfbWFudGVuaW1pZW50bykKCmBgYAoKIyMgRGl2aXNpw7NuIGRlIERhdG9zIEVudHJlbmFtaWVudG8geSBQcnVlYmEKCmBgYHtyfQojIERpdmlzacOzbiBkZSBkYXRvcwppbmRpY2VzX2VudHJlbmFtaWVudG8gPC0gc2FtcGxlKDE6bnJvdyhkYXRvc19tYW50ZW5pbWllbnRvKSwgMC43ICogbnJvdyhkYXRvc19tYW50ZW5pbWllbnRvKSkKZGF0b3NfZW50cmVuYW1pZW50byA8LSBkYXRvc19tYW50ZW5pbWllbnRvW2luZGljZXNfZW50cmVuYW1pZW50bywgXQpkYXRvc19wcnVlYmEgPC0gZGF0b3NfbWFudGVuaW1pZW50b1staW5kaWNlc19lbnRyZW5hbWllbnRvLCBdCmluZGljZXNfZW50cmVuYW1pZW50bwpgYGAKCiMjIEVudHJlbmFtaWVudG8gZGVsIE1vZGVsbyBSYW5kb20gRm9yZXN0CgpTZSB1dGlsaXphIGxhIGZ1bmNpw7NuIHJhbmRvbUZvcmVzdCgpIGRlbCBwYXF1ZXRlIHJhbmRvbUZvcmVzdC4gUG9yIGRlZmVjdG8sIGNvbnN0cnV5ZSA1MDAgw6FyYm9sZXMgZGUgZGVjaXNpw7NuLgpOb3RhIEltcG9ydGFudGU6IExhIGNvbHVtbmEgUHJvbm9zdGljb19GZWNoYV9Qcm94X01hbnQgc2UgZXhjbHV5ZSBkZWwgZW50cmVuYW1pZW50byB5YSBxdWUgZXMgdW4gdmFsb3IgZGUgZmVjaGEgcXVlIG5vIGFwb3J0YSBpbmZvcm1hY2nDs24gZGUgY2xhc2lmaWNhY2nDs24gZGlyZWN0YSBhIG1lbm9zIHF1ZSBzZSBleHRyYWlnYW4gY2FyYWN0ZXLDrXN0aWNhcyBjb21vIGVsIG1lcywgZMOtYSBkZSBsYSBzZW1hbmEsIGV0Yy4KCmBgYHtyfQojIEVudHJlbmFyIGVsIG1vZGVsbwojIExhIHNpbnRheGlzIGVzIEZhbWlsaWFfRXF1aXBvIH4gLiAocHJlZGVjaXIgRmFtaWxpYV9FcXVpcG8gdXNhbmRvIHRvZGFzIGxhcyBkZW3DoXMgdmFyaWFibGVzKQojIFNlIGV4Y2x1eWUgbGEgY29sdW1uYSBkZSBmZWNoYSBwb3Igc2ltcGxpY2lkYWQgZW4gZXN0ZSBlamVtcGxvCm1vZGVsb19yZiA8LSByYW5kb21Gb3Jlc3QoRmFsbGFfUHJlc2VudGFkYSB+IFRpZW1wb19GdW5jaW9uYW1pZW50b19Ib3JhcyArIE9wZXJhcmlvICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgUGllemFzX1Byb2R1Y2lkYXMgKyBGYW1pbGlhX0VxdWlwbyArIENvc3RvX1JlcGFyYWNpb25fVVNEICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgVmlicmFjaW9uX21tX3MgKyBUZW1wZXJhdHVyYV9DLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0b3NfZW50cmVuYW1pZW50bywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgbnRyZWUgPSA1MDAsICAgICAgICMgTsO6bWVybyBkZSDDoXJib2xlcwogICAgICAgICAgICAgICAgICAgICAgICAgIGltcG9ydGFuY2UgPSBUUlVFKSAjIENhbGN1bGFyIGltcG9ydGFuY2lhIGRlIHZhcmlhYmxlcwoKIyBWZXIgdW4gcmVzdW1lbiBkZWwgbW9kZWxvCnByaW50KG1vZGVsb19yZikKCmBgYAoKIyMgUHJlZGljY2nDs24geSBFdmFsdWFjacOzbiBkZWwgTW9kZWxvClNlIHV0aWxpemEgZWwgbW9kZWxvIGVudHJlbmFkbyBwYXJhIHByZWRlY2lyIGxhIGZhbWlsaWEgZGUgZXF1aXBvIGVuIGxvcyBkYXRvcyBkZSBwcnVlYmEgeSBzZSBldmFsw7phIHN1IHJlbmRpbWllbnRvLgoKYGBge3J9CiMgUmVhbGl6YXIgcHJlZGljY2lvbmVzIGVuIGVsIGNvbmp1bnRvIGRlIHBydWViYQpwcmVkaWNjaW9uZXMgPC0gcHJlZGljdChtb2RlbG9fcmYsIG5ld2RhdGEgPSBkYXRvc19wcnVlYmEpCgojIENyZWFyIHVuYSBtYXRyaXogZGUgY29uZnVzacOzbiBwYXJhIGV2YWx1YXIgbGEgcHJlY2lzacOzbgptYXRyaXpfY29uZnVzaW9uIDwtIHRhYmxlKERhdG9zX1JlYWxlcyA9IGRhdG9zX3BydWViYSRGYW1pbGlhX0VxdWlwbywgUHJlZGljY2lvbmVzID0gcHJlZGljY2lvbmVzKQpwcmludChtYXRyaXpfY29uZnVzaW9uKQoKIyBDYWxjdWxhciBsYSBwcmVjaXNpw7NuIGdlbmVyYWwKcHJlY2lzaW9uIDwtIHN1bShkaWFnKG1hdHJpel9jb25mdXNpb24pKSAvIHN1bShtYXRyaXpfY29uZnVzaW9uKQpjYXQoIlByZWNpc2nDs24gZGVsIG1vZGVsbzoiLCBwcmVjaXNpb24sICJcbiIpCgpgYGAKCiMjICBBbsOhbGlzaXMgZGUgSW1wb3J0YW5jaWEgZGUgVmFyaWFibGVzClJhbmRvbSBGb3Jlc3QgcGVybWl0ZSB2ZXIgcXXDqSB2YXJpYWJsZXMgZnVlcm9uIG3DoXMgaW1wb3J0YW50ZXMgcGFyYSB0b21hciBsYXMgZGVjaXNpb25lcyBkZSBjbGFzaWZpY2FjacOzbi4KCmBgYHtyfQojIE1vc3RyYXIgbGEgaW1wb3J0YW5jaWEgZGUgbGFzIHZhcmlhYmxlcwppbXBvcnRhbmNpYSA8LSBpbXBvcnRhbmNlKG1vZGVsb19yZikKcHJpbnQoaW1wb3J0YW5jaWEpCgojIFZpc3VhbGl6YXIgbGEgaW1wb3J0YW5jaWEgZGUgbGFzIHZhcmlhYmxlcwp2YXJJbXBQbG90KG1vZGVsb19yZikKCmBgYAoKIyMgTWVqb3JhIGRlbCBncsOhZmljbyBkZSBpbXBvcnRhbmNpYSBkZSB2YXJpYWJsZXMKCgpgYGB7cn0KIyBJbnN0YWxhciBzaSBlcyBuZWNlc2FyaW8KIyBpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikKIyBpbnN0YWxsLnBhY2thZ2VzKCJ0aWJibGUiKSAjIMO6dGlsIHBhcmEgY29udmVydGlyIGxhIG1hdHJpeiBhIGRhdGFmcmFtZSBmw6FjaWxtZW50ZQoKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHRpYmJsZSkKbGlicmFyeShkcGx5cikKCmBgYAoKIyMgUGFzbyAxOiBQcmVwYXJhciBsb3MgZGF0b3MgZGUgaW1wb3J0YW5jaWEgcGFyYSBnZ3Bsb3QyCkxhIGZ1bmNpw7NuIGltcG9ydGFuY2UoKSBkZXZ1ZWx2ZSB1bmEgbWF0cml6LiBEZWJlbW9zIGNvbnZlcnRpcmxhIGVuIHVuIGRhdGEuZnJhbWUgbWFuZWphYmxlIHkgZXh0cmFlciBsYSBtw6l0cmljYSBxdWUgbm9zIGludGVyZXNhIHZpc3VhbGl6YXIgKGNvbcO6bm1lbnRlICVJbmNNU0UgcGFyYSByZWdyZXNpw7NuIG8gTWVhbkRlY3JlYXNlR2luaSBwYXJhIGNsYXNpZmljYWNpw7NuKS4gRW4gZXN0ZSBjYXNvLCB1c2FyZW1vcyBNZWFuRGVjcmVhc2VHaW5pIHF1ZSBtaWRlIGN1w6FudG8gcmVkdWNlIGVsIEdpbmkgbGEgdmFyaWFibGUgZW4gcHJvbWVkaW8uCgoKYGBge3J9CiMgRXh0cmFlciBsYSBpbXBvcnRhbmNpYSB5IGNvbnZlcnRpcmxhIGVuIHVuIGRhdGEgZnJhbWUKZGZfaW1wb3J0YW5jaWEgPC0gYXMuZGF0YS5mcmFtZShpbXBvcnRhbmNlKG1vZGVsb19yZiwgc2NhbGUgPSBUUlVFKSkgJT4lCiAgcm93bmFtZXNfdG9fY29sdW1uKHZhciA9ICJWYXJpYWJsZSIpICU+JQogIGFycmFuZ2UoZGVzYyhNZWFuRGVjcmVhc2VHaW5pKSkgIyBPcmRlbmFyIHBvciBpbXBvcnRhbmNpYSBkZXNjZW5kZW50ZQoKIyBNb3N0cmFyIGxvcyBkYXRvcyBkZSBpbXBvcnRhbmNpYSBwcmVwYXJhZG9zCnByaW50KGRmX2ltcG9ydGFuY2lhKQoKYGBgCgojIyBQYXNvIDI6IENyZWFyIGVsIGdyw6FmaWNvIGNvbiBnZ3Bsb3QyClVzYXJlbW9zIHVuIGdyw6FmaWNvIGRlIGJhcnJhcyAoZ2VvbV9iYXIpIG9yZGVuYWRvIHBhcmEgbW9zdHJhciBjbGFyYW1lbnRlIHF1w6kgdmFyaWFibGVzIHRpZW5lbiBlbCBtYXlvciBpbXBhY3RvLgoKYGBge3J9CiMgR3JhZmljYXIgbGEgaW1wb3J0YW5jaWEgZGUgbGFzIHZhcmlhYmxlcyBjb24gZ2dwbG90MgpnZ3Bsb3QoZGZfaW1wb3J0YW5jaWEsIGFlcyh4ID0gcmVvcmRlcihWYXJpYWJsZSwgTWVhbkRlY3JlYXNlR2luaSksIHkgPSBNZWFuRGVjcmVhc2VHaW5pLCBmaWxsID0gTWVhbkRlY3JlYXNlR2luaSkpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKwogIGNvb3JkX2ZsaXAoKSArICMgVm9sdGVhciBsYXMgY29vcmRlbmFkYXMgcGFyYSB1bmEgbWVqb3IgbGVjdHVyYSBkZSBsYXMgZXRpcXVldGFzIGxhcmdhcwogIGxhYnMoCiAgICB0aXRsZSA9ICJJbXBvcnRhbmNpYSBkZSBsYXMgVmFyaWFibGVzIGVuIGVsIE1vZGVsbyBSYW5kb20gRm9yZXN0IiwKICAgIHN1YnRpdGxlID0gIk1lZGlkYSBwb3IgTWVhbiBEZWNyZWFzZSBHaW5pIiwKICAgIHggPSAiVmFyaWFibGUiLAogICAgeSA9ICJNZWFuIERlY3JlYXNlIEdpbmkgKEltcG9ydGFuY2lhIFJlbGF0aXZhKSIsCiAgICBmaWxsID0gIkltcG9ydGFuY2lhIgogICkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgc2NhbGVfZmlsbF92aXJpZGlzX2Mob3B0aW9uID0gInBsYXNtYSIpICsgIyBVc2FyIHVuYSBwYWxldGEgZGUgY29sb3JlcyBtb2Rlcm5hCiAgdGhlbWUoCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiKSwKICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLAogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKQogICkKCmBgYAoKIyMgRXhwbGljYWNpw7NuIGRlbCBHcsOhZmljbyBNZWpvcmFkbwoKKiByZW9yZGVyKFZhcmlhYmxlLCBNZWFuRGVjcmVhc2VHaW5pKTogT3JkZW5hIGF1dG9tw6F0aWNhbWVudGUgbGFzIGJhcnJhcyBkZSBtZW5vciBhIG1heW9yIGltcG9ydGFuY2lhLCBoYWNpZW5kbyBxdWUgZWwgZ3LDoWZpY28gc2VhIG11Y2hvIG3DoXMgZsOhY2lsIGRlIGludGVycHJldGFyIGRlIHVuIHZpc3Rhem8uCgoqIGNvb3JkX2ZsaXAoKTogQ29udmllcnRlIGVsIGdyw6FmaWNvIGRlIGJhcnJhcyB2ZXJ0aWNhbCB0cmFkaWNpb25hbCBlbiB1bm8gaG9yaXpvbnRhbCwgbG8gY3VhbCBlcyBpZGVhbCBwYXJhIGV0aXF1ZXRhcyBkZSB2YXJpYWJsZXMgbGFyZ2FzIGNvbW8gbGFzIHF1ZSB0ZW5lbW9zLgoKKiB0aGVtZV9taW5pbWFsKCk6IEFwbGljYSB1biB0ZW1hIGxpbXBpbyB5IG1pbmltYWxpc3RhIHF1ZSBlcyBlc3TDqXRpY2FtZW50ZSBzdXBlcmlvciBhbCBncsOhZmljbyBiYXNlIGRlIFIuCgoqIHNjYWxlX2ZpbGxfdmlyaWRpc19jKG9wdGlvbiA9ICJwbGFzbWEiKTogQXBsaWNhIHVuYSBwYWxldGEgZGUgY29sb3JlcyBwZXJjZXB0dWFsbWVudGUgdW5pZm9ybWUgeSBhcHRhIHBhcmEgZGFsdMOzbmljb3MgKGRlbCBwYXF1ZXRlIHZpcmlkaXMsIHF1ZSBnZ3Bsb3QyIHB1ZWRlIHVzYXIgcG9yIGRlZmVjdG8pLgoKRXN0ZSBncsOhZmljbyBwcm9wb3JjaW9uYSB1bmEgdmlzdWFsaXphY2nDs24gY2xhcmEgeSBwcm9mZXNpb25hbCBkZSBjdcOhbGVzIHNvbiBsb3MgZmFjdG9yZXMgbcOhcyBjcsOtdGljb3MgcGFyYSBkZXRlcm1pbmFyIGxhIGZhbWlsaWEgZGUgZXF1aXBvIHF1ZSByZXF1aWVyZSBtYW50ZW5pbWllbnRvLCBzZWfDum4gdHUgbW9kZWxvIGRlIFJhbmRvbSBGb3Jlc3QuCgoKIyMgU2NoZWR1bGluZyBkZSBtYW50ZW5pbWllbnRvCgpQYXJhIGNyZWFyIHVuIGdyw6FmaWNvIGRlIEdhbnR0IGNyb25vbMOzZ2ljYW1lbnRlIG9yZGVuYWRvIHV0aWxpemFuZG8gbGEgY29sdW1uYSBQcm9ub3N0aWNvX0ZlY2hhX1Byb3hfTWFudCB5IGdncGxvdDIsIHByaW1lcm8gZGViZW1vcyBkZWNpZGlyIHF1w6kgcmVwcmVzZW50YSBlbCAicmFuZ28gZGUgdGllbXBvIiBwYXJhIGNhZGEgZWxlbWVudG8sIHlhIHF1ZSB1biBncsOhZmljbyBkZSBHYW50dCByZXF1aWVyZSB1bmEgZmVjaGEgZGUgaW5pY2lvIHkgdW5hIGZlY2hhIGRlIGZpbmFsaXphY2nDs24uIApFbiBlc3RlIGVqZW1wbG8sIGFzdW1pcmVtb3MgcXVlIGVsIHB1bnRvIGRlIGluaWNpbyBkZSBsYSB0YXJlYSBkZSBtYW50ZW5pbWllbnRvIGVzIGxhIGZlY2hhIGRlbCBwcm9uw7NzdGljbyAoUHJvbm9zdGljb19GZWNoYV9Qcm94X01hbnQpLCB5IGRlZmluaXJlbW9zIHVuYSBkdXJhY2nDs24gZmlqYSBwYXJhIGxhIHRhcmVhIGRlIG1hbnRlbmltaWVudG8gKHBvciBlamVtcGxvLCAyIGTDrWFzKSBwYXJhIHNpbXVsYXIgZWwgcmFuZ28uIEFncnVwYXJlbW9zIGxhcyB0YXJlYXMgcG9yIEZhbWlsaWFfRXF1aXBvIG8gcG9yIE9wZXJhcmlvIHBhcmEgdmlzdWFsaXphcmxhcy4KCgpgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGx1YnJpZGF0ZSkgIyBQYXJhIG1hbmVqYXIgZmVjaGFzIGbDoWNpbG1lbnRlCgojIEFzdW1pbW9zIHF1ZSAnZGF0b3NfbWFudGVuaW1pZW50bycgZGVsIGVqZW1wbG8gYW50ZXJpb3IgZXN0w6EgZGlzcG9uaWJsZS4KCiMgMS4gUHJlcGFyYXIgbG9zIGRhdG9zIHBhcmEgZWwgR2FudHQKIyBDcmVhbW9zIHVuYSBmZWNoYSBkZSBpbmljaW8gKGxhIGZlY2hhIHByb25vc3RpY2FkYSkgeSB1bmEgZmVjaGEgZGUgZmluIChpbmljaW8gKyAyIGTDrWFzIGRlIGR1cmFjacOzbikKZGF0b3NfZ2FudHQgPC0gZGF0b3NfbWFudGVuaW1pZW50byAlPiUKICBtdXRhdGUoCiAgICBGZWNoYV9JbmljaW8gPSBQcm9ub3N0aWNvX0ZlY2hhX1Byb3hfTWFudCwKICAgIEZlY2hhX0ZpbiA9IEZlY2hhX0luaWNpbyArIGRheXMoMiksICMgQXN1bWltb3MgMiBkw61hcyBwYXJhIGVsIG1hbnRlbmltaWVudG8KICAgICMgQ3JlYXIgdW5hIGV0aXF1ZXRhIMO6bmljYSBwYXJhIGNhZGEgdGFyZWEgcGFyYSBlbCBlamUgWQogICAgVGFyZWFfRXF1aXBvID0gcGFzdGUoRmFtaWxpYV9FcXVpcG8sIE9wZXJhcmlvLCByb3dfbnVtYmVyKCkpIAogICkgJT4lCiAgIyBPcmRlbmFyIGNyb25vbMOzZ2ljYW1lbnRlIHBvciBmZWNoYSBkZSBpbmljaW8gcGFyYSBhc2VndXJhciBlbCBvcmRlbgogIGFycmFuZ2UoRmVjaGFfSW5pY2lvKSAlPiUKICAjIENvbnZlcnRpciBUYXJlYV9FcXVpcG8gYSBmYWN0b3IgY29uIGVsIG9yZGVuIGFjdHVhbCBwYXJhIHF1ZSBnZ3Bsb3QgbG8gcmVzcGV0ZQogIG11dGF0ZShUYXJlYV9FcXVpcG8gPSBmYWN0b3IoVGFyZWFfRXF1aXBvLCBsZXZlbHMgPSB1bmlxdWUoVGFyZWFfRXF1aXBvKSkpCgojIDIuIENyZWFyIGVsIGdyw6FmaWNvIGRlIEdhbnR0IGNvbiBnZ3Bsb3QyCmdncGxvdChkYXRvc19nYW50dCwgYWVzKHggPSBGZWNoYV9JbmljaW8sIHhlbmQgPSBGZWNoYV9GaW4sIHkgPSBUYXJlYV9FcXVpcG8sIHllbmQgPSBUYXJlYV9FcXVpcG8sIGNvbG9yID0gRmFtaWxpYV9FcXVpcG8pKSArCiAgZ2VvbV9zZWdtZW50KHNpemUgPSA1KSArICMgZ2VvbV9zZWdtZW50IGNyZWEgbGFzIGJhcnJhcyBkZWwgR2FudHQKICBsYWJzKAogICAgdGl0bGUgPSAiQ3Jvbm9ncmFtYSBkZSBQcsOzeGltb3MgTWFudGVuaW1pZW50b3MgKEdhbnR0KSIsCiAgICBzdWJ0aXRsZSA9ICJUYXJlYXMgb3JkZW5hZGFzIGNyb25vbMOzZ2ljYW1lbnRlIiwKICAgIHggPSAiRmVjaGEgZGUgTWFudGVuaW1pZW50byIsCiAgICB5ID0gIlRhcmVhIC8gRXF1aXBvIEluZGl2aWR1YWwiLAogICAgY29sb3IgPSAiRmFtaWxpYSBkZSBFcXVpcG8iCiAgKSArCiAgc2NhbGVfeF9kYXRlKGRhdGVfbGFiZWxzID0gIiVZLSVtLSVkIiwgZGF0ZV9icmVha3MgPSAid2VlayIpICsgIyBGb3JtYXRlYXIgZWwgZWplIFggcGFyYSBmZWNoYXMgbGVnaWJsZXMKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIiksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpLCAjIFJvdGFyIGV0aXF1ZXRhcyBYIHBhcmEgZXZpdGFyIHNvbGFwYW1pZW50bwogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksICMgT2N1bHRhciBldGlxdWV0YXMgZGVsIGVqZSBZIHNpIGhheSBtdWNoYXMgdGFyZWFzIGluZGl2aWR1YWxlcwogICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLAogICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpICMgRWxpbWluYXIgbMOtbmVhcyBkZSBjdWFkcsOtY3VsYSBZIHBhcmEgdW4gYXNwZWN0byBtw6FzIGxpbXBpbwogICkKCmBgYAoKCiMjIFBydWViYSBpbnRlcmFjdGl2bwoKRXN0ZSBncsOhZmljbyBlcyBzZW1lamFudGUgYWwgYW50ZXJpb3IsIHBlcm8gdG9jYW5kbyBlbCBjb2xvciBkZWwgdGlwbyBkZSBlcXVpcG8gbm9zIHBlcm1pdGUgZmlsdHJhciBsYXMgZmVjaGFzLgoKYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShkcGx5cikKbGlicmFyeShsdWJyaWRhdGUpCmxpYnJhcnkocGxvdGx5KSAjIENhcmdhciBsYSBsaWJyZXLDrWEgcGxvdGx5CgojIEFzdW1pbW9zIHF1ZSAnZGF0b3NfbWFudGVuaW1pZW50bycgZXN0w6EgZGlzcG9uaWJsZS4gCiMgU2kgbm8gbG8gZXN0w6EsIGFzZWfDunJhdGUgZGUgZWplY3V0YXIgZWwgY8OzZGlnbyBkZSBjcmVhY2nDs24gZGVsIGRhdGFzZXQgb3JpZ2luYWwuCgojIDEuIFByZXBhcmFyIGxvcyBkYXRvcyBwYXJhIGVsIEdhbnR0IChjb24gYWRpY2nDs24gZGUgdGV4dG8gcGFyYSB0b29sdGlwKQpkYXRvc19nYW50dF9pbnRlcmFjdGl2byA8LSBkYXRvc19tYW50ZW5pbWllbnRvICU+JQogIG11dGF0ZSgKICAgIEZlY2hhX0luaWNpbyA9IFByb25vc3RpY29fRmVjaGFfUHJveF9NYW50LAogICAgRmVjaGFfRmluID0gRmVjaGFfSW5pY2lvICsgZGF5cygyKSwgIyBBc3VtaW1vcyAyIGTDrWFzIHBhcmEgZWwgbWFudGVuaW1pZW50bwogICAgIyBDcmVhciB1bmEgZXRpcXVldGEgw7puaWNhIHBhcmEgY2FkYSB0YXJlYSBwYXJhIGVsIGVqZSBZCiAgICBUYXJlYV9FcXVpcG8gPSBwYXN0ZShGYW1pbGlhX0VxdWlwbywgT3BlcmFyaW8sIHJvd19udW1iZXIoKSksCiAgICAjID4+Pj4+Pj4+IEHDkUFESU1PUyBFTCBURVhUTyBERUwgVE9PTFRJUCBBUVXDjSA8PDw8PDw8PDwKICAgIHRvb2x0aXBfdGV4dCA9IHBhc3RlKAogICAgICAiRXF1aXBvOiIsIEZhbWlsaWFfRXF1aXBvLCAKICAgICAgInwgRmVjaGE6IiwgYXMuY2hhcmFjdGVyKEZlY2hhX0luaWNpbykKICAgICkKICApICU+JQogICMgT3JkZW5hciBjcm9ub2zDs2dpY2FtZW50ZSBwb3IgZmVjaGEgZGUgaW5pY2lvIHBhcmEgYXNlZ3VyYXIgZWwgb3JkZW4KICBhcnJhbmdlKEZlY2hhX0luaWNpbykgJT4lCiAgIyBDb252ZXJ0aXIgVGFyZWFfRXF1aXBvIGEgZmFjdG9yIGNvbiBlbCBvcmRlbiBhY3R1YWwgcGFyYSBxdWUgZ2dwbG90IGxvIHJlc3BldGUKICBtdXRhdGUoVGFyZWFfRXF1aXBvID0gZmFjdG9yKFRhcmVhX0VxdWlwbywgbGV2ZWxzID0gdW5pcXVlKFRhcmVhX0VxdWlwbykpKQoKIyAyLiBDcmVhciBlbCBncsOhZmljbyBkZSBHYW50dCBjb24gZ2dwbG90MgojIE1hcGVhbW9zIGxhIHZhcmlhYmxlICd0b29sdGlwX3RleHQnIGEgbGEgZXN0w6l0aWNhICd0ZXh0JwpnYW50dF9wbG90X2Jhc2UgPC0gZ2dwbG90KGRhdG9zX2dhbnR0X2ludGVyYWN0aXZvLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IEZlY2hhX0luaWNpbywgeGVuZCA9IEZlY2hhX0ZpbiwgeSA9IFRhcmVhX0VxdWlwbywgeWVuZCA9IFRhcmVhX0VxdWlwbywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gRmFtaWxpYV9FcXVpcG8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQgPSB0b29sdGlwX3RleHQpKSArICMgPC0tLSBBw7FhZGltb3MgJ3RleHQnIGFxdcOtCiAgZ2VvbV9zZWdtZW50KHNpemUgPSA1KSArCiAgbGFicygKICAgIHRpdGxlID0gIkNyb25vZ3JhbWEgZGUgUHLDs3hpbW9zIE1hbnRlbmltaWVudG9zIChHYW50dCBJbnRlcmFjdGl2bykiLAogICAgc3VidGl0bGUgPSAiVGFyZWFzIG9yZGVuYWRhcyBjcm9ub2zDs2dpY2FtZW50ZSIsCiAgICB4ID0gIkZlY2hhIGRlIE1hbnRlbmltaWVudG8iLAogICAgeSA9ICJUYXJlYSAvIEVxdWlwbyBJbmRpdmlkdWFsIiwKICAgIGNvbG9yID0gIkZhbWlsaWEgZGUgRXF1aXBvIgogICkgKwogIHNjYWxlX3hfZGF0ZShkYXRlX2xhYmVscyA9ICIlWS0lbS0lZCIsIGRhdGVfYnJlYWtzID0gIndlZWsiKSArIAogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksIAogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksIAogICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLAogICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpIAogICkKCiMgMy4gQ29udmVydGlyIGVsIGdyw6FmaWNvIGdncGxvdCBlbiB1biBncsOhZmljbyBpbnRlcmFjdGl2byBjb24gcGxvdGx5CiMgVXNhbW9zIHRvb2x0aXAgPSAidGV4dCIgcGFyYSBxdWUgc29sbyBzZSBtdWVzdHJlIG51ZXN0cm8gdGV4dG8gcGVyc29uYWxpemFkbyBhbCBwYXNhciBlbCByYXTDs24uCmdhbnR0X2ludGVyYWN0aXZvIDwtIGdncGxvdGx5KGdhbnR0X3Bsb3RfYmFzZSwgdG9vbHRpcCA9ICJ0ZXh0IikKCiMgNC4gTW9zdHJhciBlbCBncsOhZmljbyBpbnRlcmFjdGl2bwpnYW50dF9pbnRlcmFjdGl2bwoKCmBgYAoKCiMjIEFuZXhvOgoKIyMjIENvbmp1bnRvIGRlIGRhdG9zIHJhdwoKIiIsIlRlY25vbG9naWEiLCJOb3JtYXMiLCJDYXBpdGFsIiwiRXF1aXBvIiwiRW1wcmVzYSIKIjEiLDUuMSwzLjUsMS40LDAuMiwiQ05CLUNlcnZlemEiCiIyIiw0LjksMywxLjQsMC4yLCJDTkItQ2VydmV6YSIKIjMiLDQuNywzLjIsMS4zLDAuMiwiQ05CLUNlcnZlemEiCiI0Iiw0LjYsMy4xLDEuNSwwLjIsIkNOQi1DZXJ2ZXphIgoiNSIsNSwzLjYsMS40LDAuMiwiQ05CLUNlcnZlemEiCiI2Iiw1LjQsMy45LDEuNywwLjQsIkNOQi1DZXJ2ZXphIgoiNyIsNC42LDMuNCwxLjQsMC4zLCJDTkItQ2VydmV6YSIKIjgiLDUsMy40LDEuNSwwLjIsIkNOQi1DZXJ2ZXphIgoiOSIsNC40LDIuOSwxLjQsMC4yLCJDTkItQ2VydmV6YSIKIjEwIiw0LjksMy4xLDEuNSwwLjEsIkNOQi1DZXJ2ZXphIgoiMTEiLDUuNCwzLjcsMS41LDAuMiwiQ05CLUNlcnZlemEiCiIxMiIsNC44LDMuNCwxLjYsMC4yLCJDTkItQ2VydmV6YSIKIjEzIiw0LjgsMywxLjQsMC4xLCJDTkItQ2VydmV6YSIKIjE0Iiw0LjMsMywxLjEsMC4xLCJDTkItQ2VydmV6YSIKIjE1Iiw1LjgsNCwxLjIsMC4yLCJDTkItQ2VydmV6YSIKIjE2Iiw1LjcsNC40LDEuNSwwLjQsIkNOQi1DZXJ2ZXphIgoiMTciLDUuNCwzLjksMS4zLDAuNCwiQ05CLUNlcnZlemEiCiIxOCIsNS4xLDMuNSwxLjQsMC4zLCJDTkItQ2VydmV6YSIKIjE5Iiw1LjcsMy44LDEuNywwLjMsIkNOQi1DZXJ2ZXphIgoiMjAiLDUuMSwzLjgsMS41LDAuMywiQ05CLUNlcnZlemEiCiIyMSIsNS40LDMuNCwxLjcsMC4yLCJDTkItQ2VydmV6YSIKIjIyIiw1LjEsMy43LDEuNSwwLjQsIkNOQi1DZXJ2ZXphIgoiMjMiLDQuNiwzLjYsMSwwLjIsIkNOQi1DZXJ2ZXphIgoiMjQiLDUuMSwzLjMsMS43LDAuNSwiQ05CLUNlcnZlemEiCiIyNSIsNC44LDMuNCwxLjksMC4yLCJDTkItQ2VydmV6YSIKIjI2Iiw1LDMsMS42LDAuMiwiQ05CLUNlcnZlemEiCiIyNyIsNSwzLjQsMS42LDAuNCwiQ05CLUNlcnZlemEiCiIyOCIsNS4yLDMuNSwxLjUsMC4yLCJDTkItQ2VydmV6YSIKIjI5Iiw1LjIsMy40LDEuNCwwLjIsIkNOQi1DZXJ2ZXphIgoiMzAiLDQuNywzLjIsMS42LDAuMiwiQ05CLUNlcnZlemEiCiIzMSIsNC44LDMuMSwxLjYsMC4yLCJDTkItQ2VydmV6YSIKIjMyIiw1LjQsMy40LDEuNSwwLjQsIkNOQi1DZXJ2ZXphIgoiMzMiLDUuMiw0LjEsMS41LDAuMSwiQ05CLUNlcnZlemEiCiIzNCIsNS41LDQuMiwxLjQsMC4yLCJDTkItQ2VydmV6YSIKIjM1Iiw0LjksMy4xLDEuNSwwLjIsIkNOQi1DZXJ2ZXphIgoiMzYiLDUsMy4yLDEuMiwwLjIsIkNOQi1DZXJ2ZXphIgoiMzciLDUuNSwzLjUsMS4zLDAuMiwiQ05CLUNlcnZlemEiCiIzOCIsNC45LDMuNiwxLjQsMC4xLCJDTkItQ2VydmV6YSIKIjM5Iiw0LjQsMywxLjMsMC4yLCJDTkItQ2VydmV6YSIKIjQwIiw1LjEsMy40LDEuNSwwLjIsIkNOQi1DZXJ2ZXphIgoiNDEiLDUsMy41LDEuMywwLjMsIkNOQi1DZXJ2ZXphIgoiNDIiLDQuNSwyLjMsMS4zLDAuMywiQ05CLUNlcnZlemEiCiI0MyIsNC40LDMuMiwxLjMsMC4yLCJDTkItQ2VydmV6YSIKIjQ0Iiw1LDMuNSwxLjYsMC42LCJDTkItQ2VydmV6YSIKIjQ1Iiw1LjEsMy44LDEuOSwwLjQsIkNOQi1DZXJ2ZXphIgoiNDYiLDQuOCwzLDEuNCwwLjMsIkNOQi1DZXJ2ZXphIgoiNDciLDUuMSwzLjgsMS42LDAuMiwiQ05CLUNlcnZlemEiCiI0OCIsNC42LDMuMiwxLjQsMC4yLCJDTkItQ2VydmV6YSIKIjQ5Iiw1LjMsMy43LDEuNSwwLjIsIkNOQi1DZXJ2ZXphIgoiNTAiLDUsMy4zLDEuNCwwLjIsIkNOQi1DZXJ2ZXphIgoiNTEiLDcsMy4yLDQuNywxLjQsIkZBUk1BQ09SUCIKIjUyIiw2LjQsMy4yLDQuNSwxLjUsIkZBUk1BQ09SUCIKIjUzIiw2LjksMy4xLDQuOSwxLjUsIkZBUk1BQ09SUCIKIjU0Iiw1LjUsMi4zLDQsMS4zLCJGQVJNQUNPUlAiCiI1NSIsNi41LDIuOCw0LjYsMS41LCJGQVJNQUNPUlAiCiI1NiIsNS43LDIuOCw0LjUsMS4zLCJGQVJNQUNPUlAiCiI1NyIsNi4zLDMuMyw0LjcsMS42LCJGQVJNQUNPUlAiCiI1OCIsNC45LDIuNCwzLjMsMSwiRkFSTUFDT1JQIgoiNTkiLDYuNiwyLjksNC42LDEuMywiRkFSTUFDT1JQIgoiNjAiLDUuMiwyLjcsMy45LDEuNCwiRkFSTUFDT1JQIgoiNjEiLDUsMiwzLjUsMSwiRkFSTUFDT1JQIgoiNjIiLDUuOSwzLDQuMiwxLjUsIkZBUk1BQ09SUCIKIjYzIiw2LDIuMiw0LDEsIkZBUk1BQ09SUCIKIjY0Iiw2LjEsMi45LDQuNywxLjQsIkZBUk1BQ09SUCIKIjY1Iiw1LjYsMi45LDMuNiwxLjMsIkZBUk1BQ09SUCIKIjY2Iiw2LjcsMy4xLDQuNCwxLjQsIkZBUk1BQ09SUCIKIjY3Iiw1LjYsMyw0LjUsMS41LCJGQVJNQUNPUlAiCiI2OCIsNS44LDIuNyw0LjEsMSwiRkFSTUFDT1JQIgoiNjkiLDYuMiwyLjIsNC41LDEuNSwiRkFSTUFDT1JQIgoiNzAiLDUuNiwyLjUsMy45LDEuMSwiRkFSTUFDT1JQIgoiNzEiLDUuOSwzLjIsNC44LDEuOCwiRkFSTUFDT1JQIgoiNzIiLDYuMSwyLjgsNCwxLjMsIkZBUk1BQ09SUCIKIjczIiw2LjMsMi41LDQuOSwxLjUsIkZBUk1BQ09SUCIKIjc0Iiw2LjEsMi44LDQuNywxLjIsIkZBUk1BQ09SUCIKIjc1Iiw2LjQsMi45LDQuMywxLjMsIkZBUk1BQ09SUCIKIjc2Iiw2LjYsMyw0LjQsMS40LCJGQVJNQUNPUlAiCiI3NyIsNi44LDIuOCw0LjgsMS40LCJGQVJNQUNPUlAiCiI3OCIsNi43LDMsNSwxLjcsIkZBUk1BQ09SUCIKIjc5Iiw2LDIuOSw0LjUsMS41LCJGQVJNQUNPUlAiCiI4MCIsNS43LDIuNiwzLjUsMSwiRkFSTUFDT1JQIgoiODEiLDUuNSwyLjQsMy44LDEuMSwiRkFSTUFDT1JQIgoiODIiLDUuNSwyLjQsMy43LDEsIkZBUk1BQ09SUCIKIjgzIiw1LjgsMi43LDMuOSwxLjIsIkZBUk1BQ09SUCIKIjg0Iiw2LDIuNyw1LjEsMS42LCJGQVJNQUNPUlAiCiI4NSIsNS40LDMsNC41LDEuNSwiRkFSTUFDT1JQIgoiODYiLDYsMy40LDQuNSwxLjYsIkZBUk1BQ09SUCIKIjg3Iiw2LjcsMy4xLDQuNywxLjUsIkZBUk1BQ09SUCIKIjg4Iiw2LjMsMi4zLDQuNCwxLjMsIkZBUk1BQ09SUCIKIjg5Iiw1LjYsMyw0LjEsMS4zLCJGQVJNQUNPUlAiCiI5MCIsNS41LDIuNSw0LDEuMywiRkFSTUFDT1JQIgoiOTEiLDUuNSwyLjYsNC40LDEuMiwiRkFSTUFDT1JQIgoiOTIiLDYuMSwzLDQuNiwxLjQsIkZBUk1BQ09SUCIKIjkzIiw1LjgsMi42LDQsMS4yLCJGQVJNQUNPUlAiCiI5NCIsNSwyLjMsMy4zLDEsIkZBUk1BQ09SUCIKIjk1Iiw1LjYsMi43LDQuMiwxLjMsIkZBUk1BQ09SUCIKIjk2Iiw1LjcsMyw0LjIsMS4yLCJGQVJNQUNPUlAiCiI5NyIsNS43LDIuOSw0LjIsMS4zLCJGQVJNQUNPUlAiCiI5OCIsNi4yLDIuOSw0LjMsMS4zLCJGQVJNQUNPUlAiCiI5OSIsNS4xLDIuNSwzLDEuMSwiRkFSTUFDT1JQIgoiMTAwIiw1LjcsMi44LDQuMSwxLjMsIkZBUk1BQ09SUCIKIjEwMSIsNi4zLDMuMyw2LDIuNSwiU09GSUEtQXZpY29sYSIKIjEwMiIsNS44LDIuNyw1LjEsMS45LCJTT0ZJQS1Bdmljb2xhIgoiMTAzIiw3LjEsMyw1LjksMi4xLCJTT0ZJQS1Bdmljb2xhIgoiMTA0Iiw2LjMsMi45LDUuNiwxLjgsIlNPRklBLUF2aWNvbGEiCiIxMDUiLDYuNSwzLDUuOCwyLjIsIlNPRklBLUF2aWNvbGEiCiIxMDYiLDcuNiwzLDYuNiwyLjEsIlNPRklBLUF2aWNvbGEiCiIxMDciLDQuOSwyLjUsNC41LDEuNywiU09GSUEtQXZpY29sYSIKIjEwOCIsNy4zLDIuOSw2LjMsMS44LCJTT0ZJQS1Bdmljb2xhIgoiMTA5Iiw2LjcsMi41LDUuOCwxLjgsIlNPRklBLUF2aWNvbGEiCiIxMTAiLDcuMiwzLjYsNi4xLDIuNSwiU09GSUEtQXZpY29sYSIKIjExMSIsNi41LDMuMiw1LjEsMiwiU09GSUEtQXZpY29sYSIKIjExMiIsNi40LDIuNyw1LjMsMS45LCJTT0ZJQS1Bdmljb2xhIgoiMTEzIiw2LjgsMyw1LjUsMi4xLCJTT0ZJQS1Bdmljb2xhIgoiMTE0Iiw1LjcsMi41LDUsMiwiU09GSUEtQXZpY29sYSIKIjExNSIsNS44LDIuOCw1LjEsMi40LCJTT0ZJQS1Bdmljb2xhIgoiMTE2Iiw2LjQsMy4yLDUuMywyLjMsIlNPRklBLUF2aWNvbGEiCiIxMTciLDYuNSwzLDUuNSwxLjgsIlNPRklBLUF2aWNvbGEiCiIxMTgiLDcuNywzLjgsNi43LDIuMiwiU09GSUEtQXZpY29sYSIKIjExOSIsNy43LDIuNiw2LjksMi4zLCJTT0ZJQS1Bdmljb2xhIgoiMTIwIiw2LDIuMiw1LDEuNSwiU09GSUEtQXZpY29sYSIKIjEyMSIsNi45LDMuMiw1LjcsMi4zLCJTT0ZJQS1Bdmljb2xhIgoiMTIyIiw1LjYsMi44LDQuOSwyLCJTT0ZJQS1Bdmljb2xhIgoiMTIzIiw3LjcsMi44LDYuNywyLCJTT0ZJQS1Bdmljb2xhIgoiMTI0Iiw2LjMsMi43LDQuOSwxLjgsIlNPRklBLUF2aWNvbGEiCiIxMjUiLDYuNywzLjMsNS43LDIuMSwiU09GSUEtQXZpY29sYSIKIjEyNiIsNy4yLDMuMiw2LDEuOCwiU09GSUEtQXZpY29sYSIKIjEyNyIsNi4yLDIuOCw0LjgsMS44LCJTT0ZJQS1Bdmljb2xhIgoiMTI4Iiw2LjEsMyw0LjksMS44LCJTT0ZJQS1Bdmljb2xhIgoiMTI5Iiw2LjQsMi44LDUuNiwyLjEsIlNPRklBLUF2aWNvbGEiCiIxMzAiLDcuMiwzLDUuOCwxLjYsIlNPRklBLUF2aWNvbGEiCiIxMzEiLDcuNCwyLjgsNi4xLDEuOSwiU09GSUEtQXZpY29sYSIKIjEzMiIsNy45LDMuOCw2LjQsMiwiU09GSUEtQXZpY29sYSIKIjEzMyIsNi40LDIuOCw1LjYsMi4yLCJTT0ZJQS1Bdmljb2xhIgoiMTM0Iiw2LjMsMi44LDUuMSwxLjUsIlNPRklBLUF2aWNvbGEiCiIxMzUiLDYuMSwyLjYsNS42LDEuNCwiU09GSUEtQXZpY29sYSIKIjEzNiIsNy43LDMsNi4xLDIuMywiU09GSUEtQXZpY29sYSIKIjEzNyIsNi4zLDMuNCw1LjYsMi40LCJTT0ZJQS1Bdmljb2xhIgoiMTM4Iiw2LjQsMy4xLDUuNSwxLjgsIlNPRklBLUF2aWNvbGEiCiIxMzkiLDYsMyw0LjgsMS44LCJTT0ZJQS1Bdmljb2xhIgoiMTQwIiw2LjksMy4xLDUuNCwyLjEsIlNPRklBLUF2aWNvbGEiCiIxNDEiLDYuNywzLjEsNS42LDIuNCwiU09GSUEtQXZpY29sYSIKIjE0MiIsNi45LDMuMSw1LjEsMi4zLCJTT0ZJQS1Bdmljb2xhIgoiMTQzIiw1LjgsMi43LDUuMSwxLjksIlNPRklBLUF2aWNvbGEiCiIxNDQiLDYuOCwzLjIsNS45LDIuMywiU09GSUEtQXZpY29sYSIKIjE0NSIsNi43LDMuMyw1LjcsMi41LCJTT0ZJQS1Bdmljb2xhIgoiMTQ2Iiw2LjcsMyw1LjIsMi4zLCJTT0ZJQS1Bdmljb2xhIgoiMTQ3Iiw2LjMsMi41LDUsMS45LCJTT0ZJQS1Bdmljb2xhIgoiMTQ4Iiw2LjUsMyw1LjIsMiwiU09GSUEtQXZpY29sYSIKIjE0OSIsNi4yLDMuNCw1LjQsMi4zLCJTT0ZJQS1Bdmljb2xhIgoiMTUwIiw1LjksMyw1LjEsMS44LCJTT0ZJQS1Bdmljb2xhIgoK