2. Procesamiento y limpieza de datos
COMENTARIOS: Corrección en vez de calibración
Menos precision
La corrección no está tomando los datos
Que un modelo se ajuste mejor no significa que sea el mejor
No diferencia de 20 o 30 en el blant almant, hay mucho hiperstacidad
aun. Tenemos que ajustar mejor
Corrrelación no es igual a agrimente (concordancia)
Aunto correlación serial – Ver eso.
En ninguna se está tomando en cuenta si hay o no linealidad
Necesitar modelos con Splines Modelos aditivos
Metodología para la limpieza y procesamiento de datos de PM₂.₅ 1.
Revisión inicial de datos cada 2 minutos Se revisaron los datos de PM₂.₅
registrados cada 2 minutos para evaluar la cantidad de mediciones
disponibles por hora. 2. Filtrado por número mínimo de observaciones Se
identificaron 5 horas que no contaban con al menos 22 mediciones (del
total de 30 posibles por hora). Estas observaciones fueron eliminadas
antes de realizar los promedios horarios, siguiendo el criterio del 75%
de datos disponibles por hora. 3. Cálculo del promedio horario de PM₂.₅
A partir de la base de datos filtrada (CampMar1Clean), se construyó una
nueva base con promedios horarios de las variables PM₂.₅ (pm2_5_cf_1 y
pm2_5_cf_1_b), agrupando por fecha y hora.
2. Evaluación de la coherencia entre canales A y B del sensor
Se calculó la diferencia porcentual horaria entre los valores de los
canales A (pm2_5_cf_1) y B (pm2_5_cf_1_b) usando la fórmula: diferencia
horaria = ((A − B) × 2) / (A + B) × 100% • Se calcularon dos indicadores
dicotómicos: • Si la diferencia porcentual superaba el 70%. • Si la
diferencia absoluta entre A y B superaba los 5 µg/m³. 5. Validación de
horas según criterios de calidad Se creó una variable de validación que
clasifica cada hora como “no pasó” si no cumplía al menos uno de los dos
criterios anteriores.
Resultado: 40 observaciones no superaron el control de calidad, lo
que representa un 0.48% del total.
3. Definir los modelos que probare
Se definen 24 modelos
4. Proceso de Leave-One-Week-Out Cross
Este enfoque consiste en dividir el conjunto de datos por semanas. En
cada iteración, se selecciona una semana específica (semana s) como
conjunto de prueba, mientras que todas las demás semanas se utilizan
como conjunto de entrenamiento.
El procedimiento sigue estos pasos: 1. Selección del conjunto de
prueba: Se deja fuera una semana (semana s) del conjunto de datos para
usarla como conjunto de prueba. 2. Entrenamiento del modelo: El modelo
se entrena utilizando los datos de las semanas restantes (todas excepto
la semana s). 3. Predicción y evaluación: El modelo entrenado realiza
predicciones sobre los datos de la semana s (conjunto de prueba), y se
calculan los errores de predicción (como RMSE, MAE, Bias, R²). 4.
Repetición del proceso: Se repite este procedimiento dejando fuera una
semana diferente en cada iteración, hasta que todas las semanas hayan
sido utilizadas una vez como conjunto de prueba.
5. Criterios de evaluación del modelo:
Criterios de evaluación del modelo:
Los resultados obtenidos a partir del proceso de validación cruzada
Leave-One-Week-Out se evaluaron utilizando los siguientes
indicadores:
• Coeficiente de determinación (R²): Se consideró aceptable un R² igual o superior a 0.75, lo cual indica una correlación casi perfecta entre los datos calibrados del sensor PurpleAir y los valores del monitor de referencia.
• Errores de predicción (RMSE, MAE y MAPE): Se buscaron valores lo más bajos posible para estos indicadores, ya que reflejan una mayor precisión del modelo al estimar los niveles reales de PM₂.₅.
• Sesgo (Bias): Se aceptó un sesgo dentro del rango de –5 a 5 μg/m³. Valores fuera de este intervalo indican una sobreestimación o subestimación sistemática que compromete la validez del modelo.
En caso de que varios modelos cumplieran con estos criterios, se
priorizó la selección de aquel que maximizara el R² y minimizara
simultáneamente el RMSE y el MAE.
RESULTADOS: El mejor modelo es el 7 -> pm25_referencia ~
pm25_sensor + temperatura * humedad
6. Criterios de evaluación del modelo:
Una vez seleccionada la mejor ecuación de calibración mediante el
proceso de validación cruzada Leave-One-Week-Out, se procedió a ajustar
el modelo sobre el conjunto completo de datos disponibles. El modelo
seleccionado fue el modelo 7, que incluye como predictores el valor del
sensor PurpleAir, la temperatura, la humedad relativa y la interacción
entre estos dos últimos términos.
A partir de esta ecuación, se estimaron las concentraciones
calibradas de PM₂.₅ para cada observación en el conjunto de datos,
generando una nueva variable llamada pm25_calibrado.
En el gráfico de dispersión muestro la nube de puntos con los valores
emparejados entre el PM₂.₅ calibrado y el valor de referencia. Incluí
dos líneas: una diagonal punteada que representa la concordancia
perfecta (y = x), y una línea de regresión lineal (en azul) que ajusté
sobre los datos. La cercanía de los puntos a estas líneas refleja una
alta concordancia entre ambos valores, lo que me permite confirmar que
el modelo calibrado reproduce de manera precisa las mediciones del
equipo de referencia y que puede aplicarse en condiciones reales.


7. Bland-Altman:
Se elabora un gráfico de Bland-Altman para evaluar la concordancia
entre las concentraciones de PM₂.₅ corregidas mediante el modelo final
de calibración aplicado a los datos del sensor PurpleAir y las
mediciones obtenidas con el monitor de referencia utilizado en Lima
RESULTADOS: El modelo de calibración muestra una alta concordancia
con el equipo de referencia, con un sesgo bajo y la mayoría de las
diferencias esta dentro de los límites aceptables, sin embargo si
muestra mayor variabilidad en los extremos altos.

7. HACERLO PARA MONITOR 2 (Prueba):


LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKLS0tCiMjIDIuIFByb2Nlc2FtaWVudG8geSBsaW1waWV6YSBkZSBkYXRvcwoKQ09NRU5UQVJJT1M6IENvcnJlY2Npw7NuIGVuIHZleiBkZSBjYWxpYnJhY2nDs24gCgpNZW5vcyBwcmVjaXNpb24gCgpMYSBjb3JyZWNjacOzbiBubyBlc3TDoSB0b21hbmRvIGxvcyBkYXRvcyAKClF1ZSB1biBtb2RlbG8gc2UgYWp1c3RlIG1lam9yIG5vIHNpZ25pZmljYSBxdWUgc2VhIGVsIG1lam9yCgpObyBkaWZlcmVuY2lhIGRlIDIwIG8gMzAgZW4gZWwgYmxhbnQgYWxtYW50LCBoYXkgbXVjaG8gaGlwZXJzdGFjaWRhZCBhdW4uIFRlbmVtb3MgcXVlIGFqdXN0YXIgbWVqb3IKCkNvcnJyZWxhY2nDs24gbm8gZXMgaWd1YWwgYSBhZ3JpbWVudGUgKGNvbmNvcmRhbmNpYSkKCkF1bnRvIGNvcnJlbGFjacOzbiBzZXJpYWwg4oCTIFZlciBlc28uIAoKRW4gbmluZ3VuYSBzZSBlc3TDoSB0b21hbmRvIGVuIGN1ZW50YSBzaSBoYXkgbyBubyBsaW5lYWxpZGFkIAoKTmVjZXNpdGFyIG1vZGVsb3MgY29uIFNwbGluZXMgCk1vZGVsb3MgYWRpdGl2b3MgCgoKTWV0b2RvbG9nw61hIHBhcmEgbGEgbGltcGllemEgeSBwcm9jZXNhbWllbnRvIGRlIGRhdG9zIGRlIFBN4oKCLuKChQoJMS4JUmV2aXNpw7NuIGluaWNpYWwgZGUgZGF0b3MgY2FkYSAyIG1pbnV0b3MKU2UgcmV2aXNhcm9uIGxvcyBkYXRvcyBkZSBQTeKCgi7igoUgcmVnaXN0cmFkb3MgY2FkYSAyIG1pbnV0b3MgcGFyYSBldmFsdWFyIGxhIGNhbnRpZGFkIGRlIG1lZGljaW9uZXMgZGlzcG9uaWJsZXMgcG9yIGhvcmEuCgkyLglGaWx0cmFkbyBwb3IgbsO6bWVybyBtw61uaW1vIGRlIG9ic2VydmFjaW9uZXMKU2UgaWRlbnRpZmljYXJvbiA1IGhvcmFzIHF1ZSBubyBjb250YWJhbiBjb24gYWwgbWVub3MgMjIgbWVkaWNpb25lcyAoZGVsIHRvdGFsIGRlIDMwIHBvc2libGVzIHBvciBob3JhKS4gRXN0YXMgb2JzZXJ2YWNpb25lcyBmdWVyb24gZWxpbWluYWRhcyBhbnRlcyBkZSByZWFsaXphciBsb3MgcHJvbWVkaW9zIGhvcmFyaW9zLCBzaWd1aWVuZG8gZWwgY3JpdGVyaW8gZGVsIDc1JSBkZSBkYXRvcyBkaXNwb25pYmxlcyBwb3IgaG9yYS4KCTMuCUPDoWxjdWxvIGRlbCBwcm9tZWRpbyBob3JhcmlvIGRlIFBN4oKCLuKChQpBIHBhcnRpciBkZSBsYSBiYXNlIGRlIGRhdG9zIGZpbHRyYWRhIChDYW1wTWFyMUNsZWFuKSwgc2UgY29uc3RydXnDsyB1bmEgbnVldmEgYmFzZSBjb24gcHJvbWVkaW9zIGhvcmFyaW9zIGRlIGxhcyB2YXJpYWJsZXMgUE3igoIu4oKFIChwbTJfNV9jZl8xIHkgcG0yXzVfY2ZfMV9iKSwgYWdydXBhbmRvIHBvciBmZWNoYSB5IGhvcmEuCgojIyAyLiBFdmFsdWFjacOzbiBkZSBsYSBjb2hlcmVuY2lhIGVudHJlIGNhbmFsZXMgQSB5IEIgZGVsIHNlbnNvcgoKU2UgY2FsY3Vsw7MgbGEgZGlmZXJlbmNpYSBwb3JjZW50dWFsIGhvcmFyaWEgZW50cmUgbG9zIHZhbG9yZXMgZGUgbG9zIGNhbmFsZXMgQSAocG0yXzVfY2ZfMSkgeSBCIChwbTJfNV9jZl8xX2IpIHVzYW5kbyBsYSBmw7NybXVsYToKICBkaWZlcmVuY2lhIGhvcmFyaWEgPSAoKEEg4oiSIEIpIMOXIDIpIC8gKEEgKyBCKSDDlyAxMDAlCgnigKIJU2UgY2FsY3VsYXJvbiBkb3MgaW5kaWNhZG9yZXMgZGljb3TDs21pY29zOgoJ4oCiCVNpIGxhIGRpZmVyZW5jaWEgcG9yY2VudHVhbCBzdXBlcmFiYSBlbCA3MCUuCgnigKIJU2kgbGEgZGlmZXJlbmNpYSBhYnNvbHV0YSBlbnRyZSBBIHkgQiBzdXBlcmFiYSBsb3MgNSDCtWcvbcKzLgoJNS4JVmFsaWRhY2nDs24gZGUgaG9yYXMgc2Vnw7puIGNyaXRlcmlvcyBkZSBjYWxpZGFkClNlIGNyZcOzIHVuYSB2YXJpYWJsZSBkZSB2YWxpZGFjacOzbiBxdWUgY2xhc2lmaWNhIGNhZGEgaG9yYSBjb21vIOKAnG5vIHBhc8Oz4oCdIHNpIG5vIGN1bXBsw61hIGFsIG1lbm9zIHVubyBkZSBsb3MgZG9zIGNyaXRlcmlvcyBhbnRlcmlvcmVzLgoKUmVzdWx0YWRvOiA0MCBvYnNlcnZhY2lvbmVzIG5vIHN1cGVyYXJvbiBlbCBjb250cm9sIGRlIGNhbGlkYWQsIGxvIHF1ZSByZXByZXNlbnRhIHVuIDAuNDglIGRlbCB0b3RhbC4KCiMjIDMuIERlZmluaXIgbG9zIG1vZGVsb3MgcXVlIHByb2JhcmUgClNlIGRlZmluZW4gMjQgbW9kZWxvcyAgCmBgYHtyIG1vZGVsb3MsIGVjaG89VFJVRX0KbGlzdGFfbW9kZWxvcyA8LSBsaXN0KAogIG1vZGVsb18xICA9IHBtMjVfcmVmZXJlbmNpYSB+IHBtMjVfc2Vuc29yLAogIG1vZGVsb18yICA9IHBtMjVfcmVmZXJlbmNpYSB+IHBtMjVfc2Vuc29yICsgdGVtcGVyYXR1cmEsCiAgbW9kZWxvXzMgID0gcG0yNV9yZWZlcmVuY2lhIH4gcG0yNV9zZW5zb3IgKyBodW1lZGFkLAogIG1vZGVsb180ICA9IHBtMjVfcmVmZXJlbmNpYSB+IHBtMjVfc2Vuc29yICsgZGV3X3BvaW50LAogIG1vZGVsb181ICA9IHBtMjVfcmVmZXJlbmNpYSB+IHBtMjVfc2Vuc29yICsgcHJlc2lvbiwKICBtb2RlbG9fNiAgPSBwbTI1X3JlZmVyZW5jaWEgfiBwbTI1X3NlbnNvciArIHRlbXBlcmF0dXJhICsgaHVtZWRhZCwKICBtb2RlbG9fNyAgPSBwbTI1X3JlZmVyZW5jaWEgfiBwbTI1X3NlbnNvciArIHRlbXBlcmF0dXJhICogaHVtZWRhZCwKICBtb2RlbG9fOCAgPSBwbTI1X3JlZmVyZW5jaWEgfiBwbTI1X3NlbnNvciArIHRlbXBlcmF0dXJhICogZGV3X3BvaW50LAogIG1vZGVsb185ICA9IHBtMjVfcmVmZXJlbmNpYSB+IHBtMjVfc2Vuc29yICsgdGVtcGVyYXR1cmEgKiBwcmVzaW9uLAogIG1vZGVsb18xMCA9IHBtMjVfcmVmZXJlbmNpYSB+IHBtMjVfc2Vuc29yICsgaHVtZWRhZCAqIGRld19wb2ludCwKICBtb2RlbG9fMTEgPSBwbTI1X3JlZmVyZW5jaWEgfiBwbTI1X3NlbnNvciArIGh1bWVkYWQgKiBwcmVzaW9uLAogIG1vZGVsb18xMiA9IHBtMjVfcmVmZXJlbmNpYSB+IHBtMjVfc2Vuc29yICsgZGV3X3BvaW50ICogcHJlc2lvbiwKICBtb2RlbG9fMTMgPSBwbTI1X3JlZmVyZW5jaWEgfiBwbTI1X3NlbnNvciAqIHRlbXBlcmF0dXJhLAogIG1vZGVsb18xNCA9IHBtMjVfcmVmZXJlbmNpYSB+IHBtMjVfc2Vuc29yICogaHVtZWRhZCwKICBtb2RlbG9fMTUgPSBwbTI1X3JlZmVyZW5jaWEgfiBwbTI1X3NlbnNvciAqIGRld19wb2ludCwKICBtb2RlbG9fMTYgPSBwbTI1X3JlZmVyZW5jaWEgfiBwbTI1X3NlbnNvciAqIHByZXNpb24sCiAgbW9kZWxvXzE3ID0gcG0yNV9yZWZlcmVuY2lhIH4gcG0yNV9zZW5zb3IgKyB0ZW1wZXJhdHVyYSAqIGh1bWVkYWQgKyB0ZW1wZXJhdHVyYSwKICBtb2RlbG9fMTggPSBwbTI1X3JlZmVyZW5jaWEgfiBwbTI1X3NlbnNvciArIHRlbXBlcmF0dXJhICogZGV3X3BvaW50ICsgdGVtcGVyYXR1cmEsCiAgbW9kZWxvXzE5ID0gcG0yNV9yZWZlcmVuY2lhIH4gcG0yNV9zZW5zb3IgKyB0ZW1wZXJhdHVyYSAqIGh1bWVkYWQgKyBodW1lZGFkLAogIG1vZGVsb18yMCA9IHBtMjVfcmVmZXJlbmNpYSB+IHBtMjVfc2Vuc29yICsgaHVtZWRhZCAqIGRld19wb2ludCArIGh1bWVkYWQsCiAgbW9kZWxvXzIxID0gcG0yNV9yZWZlcmVuY2lhIH4gcG0yNV9zZW5zb3IgKyBkZXdfcG9pbnQgKiBwcmVzaW9uICsgZGV3X3BvaW50LAogIG1vZGVsb18yMiA9IHBtMjVfcmVmZXJlbmNpYSB+IHBtMjVfc2Vuc29yICsgaHVtZWRhZCAqIHRlbXBlcmF0dXJhICsgZGV3X3BvaW50LAogIG1vZGVsb18yMyA9IHBtMjVfcmVmZXJlbmNpYSB+IHBtMjVfc2Vuc29yICsgaHVtZWRhZCAqIHRlbXBlcmF0dXJhICsgcHJlc2lvbiwKICBtb2RlbG9fMjQgPSBwbTI1X3JlZmVyZW5jaWEgfiBwbTI1X3NlbnNvciArIGh1bWVkYWQgKiBkZXdfcG9pbnQgKyBwcmVzaW9uCikKCiMgQ2FyZ2FyIHRpYmJsZQpsaWJyYXJ5KHRpYmJsZSkKCiMgQ3JlYXIgdGFibGEgY29uIG5vbWJyZXMgZGUgbW9kZWxvcyB5IGbDs3JtdWxhcwp0YWJsYV9tb2RlbG9zIDwtIHRpYmJsZSgKICBNb2RlbG8gPSBuYW1lcyhsaXN0YV9tb2RlbG9zKSwKICBGb3JtdWxhID0gc2FwcGx5KGxpc3RhX21vZGVsb3MsIGZ1bmN0aW9uKGYpIGRlcGFyc2UoZikpCikKCiMgTW9zdHJhciBsYSB0YWJsYSBlbiBlbCBub3RlYm9vawp0YWJsYV9tb2RlbG9zCmBgYAoKIyMgNC4gUHJvY2VzbyBkZSBMZWF2ZS1PbmUtV2Vlay1PdXQgQ3Jvc3MgCgpFc3RlIGVuZm9xdWUgY29uc2lzdGUgZW4gZGl2aWRpciBlbCBjb25qdW50byBkZSBkYXRvcyBwb3Igc2VtYW5hcy4gRW4gY2FkYSBpdGVyYWNpw7NuLCBzZSBzZWxlY2Npb25hIHVuYSBzZW1hbmEgZXNwZWPDrWZpY2EgKHNlbWFuYSBzKSBjb21vIGNvbmp1bnRvIGRlIHBydWViYSwgbWllbnRyYXMgcXVlIHRvZGFzIGxhcyBkZW3DoXMgc2VtYW5hcyBzZSB1dGlsaXphbiBjb21vIGNvbmp1bnRvIGRlIGVudHJlbmFtaWVudG8uCgpFbCBwcm9jZWRpbWllbnRvIHNpZ3VlIGVzdG9zIHBhc29zOgoJMS4JU2VsZWNjacOzbiBkZWwgY29uanVudG8gZGUgcHJ1ZWJhOiBTZSBkZWphIGZ1ZXJhIHVuYSBzZW1hbmEgKHNlbWFuYSBzKSBkZWwgY29uanVudG8gZGUgZGF0b3MgcGFyYSB1c2FybGEgY29tbyBjb25qdW50byBkZSBwcnVlYmEuCgkyLglFbnRyZW5hbWllbnRvIGRlbCBtb2RlbG86IEVsIG1vZGVsbyBzZSBlbnRyZW5hIHV0aWxpemFuZG8gbG9zIGRhdG9zIGRlIGxhcyBzZW1hbmFzIHJlc3RhbnRlcyAodG9kYXMgZXhjZXB0byBsYSBzZW1hbmEgcykuCgkzLglQcmVkaWNjacOzbiB5IGV2YWx1YWNpw7NuOiBFbCBtb2RlbG8gZW50cmVuYWRvIHJlYWxpemEgcHJlZGljY2lvbmVzIHNvYnJlIGxvcyBkYXRvcyBkZSBsYSBzZW1hbmEgcyAoY29uanVudG8gZGUgcHJ1ZWJhKSwgeSBzZSBjYWxjdWxhbiBsb3MgZXJyb3JlcyBkZSBwcmVkaWNjacOzbiAoY29tbyBSTVNFLCBNQUUsIEJpYXMsIFLCsikuCgk0LglSZXBldGljacOzbiBkZWwgcHJvY2VzbzogU2UgcmVwaXRlIGVzdGUgcHJvY2VkaW1pZW50byBkZWphbmRvIGZ1ZXJhIHVuYSBzZW1hbmEgZGlmZXJlbnRlIGVuIGNhZGEgaXRlcmFjacOzbiwgaGFzdGEgcXVlIHRvZGFzIGxhcyBzZW1hbmFzIGhheWFuIHNpZG8gdXRpbGl6YWRhcyB1bmEgdmV6IGNvbW8gY29uanVudG8gZGUgcHJ1ZWJhLgoKYGBge3IgTE9XQywgZWNobz1UUlVFfQpsaWJyYXJ5KE1ldHJpY3MpCgpzZW1hbmFzIDwtIHVuaXF1ZShkYXRvcyRpZF9zZW1hbmEpCnJlc3VsdGFkb3MgPC0gZGF0YS5mcmFtZSgpCgpmb3IgKG1vZGVsb19ub21icmUgaW4gbmFtZXMobGlzdGFfbW9kZWxvcykpIHsKICBmb3JtdWxhX2FjdHVhbCA8LSBsaXN0YV9tb2RlbG9zW1ttb2RlbG9fbm9tYnJlXV0KICAKICBmb3IgKHMgaW4gc2VtYW5hcykgewogICAgZGF0b3NfcHJ1ZWJhIDwtIHN1YnNldChkYXRvcywgaWRfc2VtYW5hID09IHMpCiAgICBkYXRvc19lbnRyZW5hbWllbnRvIDwtIHN1YnNldChkYXRvcywgaWRfc2VtYW5hICE9IHMpCiAgICAKICAgIG1vZGVsbyA8LSBsbShmb3JtdWxhX2FjdHVhbCwgZGF0YSA9IGRhdG9zX2VudHJlbmFtaWVudG8pCiAgICBwcmVkIDwtIHByZWRpY3QobW9kZWxvLCBuZXdkYXRhID0gZGF0b3NfcHJ1ZWJhKQogICAgcmVhbCA8LSBkYXRvc19wcnVlYmEkcG0yNV9yZWZlcmVuY2lhCiAgICAKICAgIG1ldHJpY2EgPC0gZGF0YS5mcmFtZSgKICAgICAgbW9kZWxvID0gbW9kZWxvX25vbWJyZSwKICAgICAgc2VtYW5hID0gcywKICAgICAgUk1TRSA9IHJtc2UocmVhbCwgcHJlZCksCiAgICAgIE1BRSA9IG1hZShyZWFsLCBwcmVkKSwKICAgICAgQmlhcyA9IG1lYW4ocHJlZCAtIHJlYWwpLAogICAgICBSMiA9IDEgLSBzdW0oKHByZWQgLSByZWFsKV4yKSAvIHN1bSgocmVhbCAtIG1lYW4ocmVhbCkpXjIpCiAgICApCiAgICAKICAgIHJlc3VsdGFkb3MgPC0gcmJpbmQocmVzdWx0YWRvcywgbWV0cmljYSkKICB9Cn0KICAgIApgYGAKCiMjIDUuIENyaXRlcmlvcyBkZSBldmFsdWFjacOzbiBkZWwgbW9kZWxvOgoKQ3JpdGVyaW9zIGRlIGV2YWx1YWNpw7NuIGRlbCBtb2RlbG86CgpMb3MgcmVzdWx0YWRvcyBvYnRlbmlkb3MgYSBwYXJ0aXIgZGVsIHByb2Nlc28gZGUgdmFsaWRhY2nDs24gY3J1emFkYSBMZWF2ZS1PbmUtV2Vlay1PdXQgc2UgZXZhbHVhcm9uIHV0aWxpemFuZG8gbG9zIHNpZ3VpZW50ZXMgaW5kaWNhZG9yZXM6CgoJ4oCiCUNvZWZpY2llbnRlIGRlIGRldGVybWluYWNpw7NuIChSwrIpOiBTZSBjb25zaWRlcsOzIGFjZXB0YWJsZSB1biBSwrIgaWd1YWwgbyBzdXBlcmlvciBhIDAuNzUsIGxvIGN1YWwgaW5kaWNhIHVuYSBjb3JyZWxhY2nDs24gY2FzaSBwZXJmZWN0YSBlbnRyZSBsb3MgZGF0b3MgY2FsaWJyYWRvcyBkZWwgc2Vuc29yIFB1cnBsZUFpciB5IGxvcyB2YWxvcmVzIGRlbCBtb25pdG9yIGRlIHJlZmVyZW5jaWEuCgkKCeKAoglFcnJvcmVzIGRlIHByZWRpY2Npw7NuIChSTVNFLCBNQUUgeSBNQVBFKTogU2UgYnVzY2Fyb24gdmFsb3JlcyBsbyBtw6FzIGJham9zIHBvc2libGUgcGFyYSBlc3RvcyBpbmRpY2Fkb3JlcywgeWEgcXVlIHJlZmxlamFuIHVuYSBtYXlvciBwcmVjaXNpw7NuIGRlbCBtb2RlbG8gYWwgZXN0aW1hciBsb3Mgbml2ZWxlcyByZWFsZXMgZGUgUE3igoIu4oKFLgoJCgnigKIJU2VzZ28gKEJpYXMpOiBTZSBhY2VwdMOzIHVuIHNlc2dvIGRlbnRybyBkZWwgcmFuZ28gZGUg4oCTNSBhIDUgzrxnL23Csy4gVmFsb3JlcyBmdWVyYSBkZSBlc3RlIGludGVydmFsbyBpbmRpY2FuIHVuYSBzb2JyZWVzdGltYWNpw7NuIG8gc3ViZXN0aW1hY2nDs24gc2lzdGVtw6F0aWNhIHF1ZSBjb21wcm9tZXRlIGxhIHZhbGlkZXogZGVsIG1vZGVsby4KCQoKRW4gY2FzbyBkZSBxdWUgdmFyaW9zIG1vZGVsb3MgY3VtcGxpZXJhbiBjb24gZXN0b3MgY3JpdGVyaW9zLCBzZSBwcmlvcml6w7MgbGEgc2VsZWNjacOzbiBkZSBhcXVlbCBxdWUgbWF4aW1pemFyYSBlbCBSwrIgeSBtaW5pbWl6YXJhIHNpbXVsdMOhbmVhbWVudGUgZWwgUk1TRSB5IGVsIE1BRS4KClJFU1VMVEFET1M6IEVsIG1lam9yIG1vZGVsbyBlcyBlbCA3IC0+IHBtMjVfcmVmZXJlbmNpYSB+IHBtMjVfc2Vuc29yICsgdGVtcGVyYXR1cmEgKiBodW1lZGFkIAoKYGBge3IgcmVzdW1lbiwgZWNobz1UUlVFfQphZ2dyZWdhdGUoY2JpbmQoUk1TRSwgTUFFLCBCaWFzLCBSMikgfiBtb2RlbG8sIGRhdGEgPSByZXN1bHRhZG9zLCBtZWFuKQoKYGBgCiMjIDYuIENyaXRlcmlvcyBkZSBldmFsdWFjacOzbiBkZWwgbW9kZWxvOgpVbmEgdmV6IHNlbGVjY2lvbmFkYSBsYSBtZWpvciBlY3VhY2nDs24gZGUgY2FsaWJyYWNpw7NuIG1lZGlhbnRlIGVsIHByb2Nlc28gZGUgdmFsaWRhY2nDs24gY3J1emFkYSBMZWF2ZS1PbmUtV2Vlay1PdXQsIHNlIHByb2NlZGnDsyBhIGFqdXN0YXIgZWwgbW9kZWxvIHNvYnJlIGVsIGNvbmp1bnRvIGNvbXBsZXRvIGRlIGRhdG9zIGRpc3BvbmlibGVzLiBFbCBtb2RlbG8gc2VsZWNjaW9uYWRvIGZ1ZSBlbCBtb2RlbG8gNywgcXVlIGluY2x1eWUgY29tbyBwcmVkaWN0b3JlcyBlbCB2YWxvciBkZWwgc2Vuc29yIFB1cnBsZUFpciwgbGEgdGVtcGVyYXR1cmEsIGxhIGh1bWVkYWQgcmVsYXRpdmEgeSBsYSBpbnRlcmFjY2nDs24gZW50cmUgZXN0b3MgZG9zIMO6bHRpbW9zIHTDqXJtaW5vcy4gCgpBIHBhcnRpciBkZSBlc3RhIGVjdWFjacOzbiwgc2UgZXN0aW1hcm9uIGxhcyBjb25jZW50cmFjaW9uZXMgY2FsaWJyYWRhcyBkZSBQTeKCgi7igoUgcGFyYSBjYWRhIG9ic2VydmFjacOzbiBlbiBlbCBjb25qdW50byBkZSBkYXRvcywgZ2VuZXJhbmRvIHVuYSBudWV2YSB2YXJpYWJsZSBsbGFtYWRhIHBtMjVfY2FsaWJyYWRvLgoKCkVuIGVsIGdyw6FmaWNvIGRlIGRpc3BlcnNpw7NuIG11ZXN0cm8gbGEgbnViZSBkZSBwdW50b3MgY29uIGxvcyB2YWxvcmVzIGVtcGFyZWphZG9zIGVudHJlIGVsIFBN4oKCLuKChSBjYWxpYnJhZG8geSBlbCB2YWxvciBkZSByZWZlcmVuY2lhLiBJbmNsdcOtIGRvcyBsw61uZWFzOiB1bmEgZGlhZ29uYWwgcHVudGVhZGEgcXVlIHJlcHJlc2VudGEgbGEgY29uY29yZGFuY2lhIHBlcmZlY3RhICh5ID0geCksIHkgdW5hIGzDrW5lYSBkZSByZWdyZXNpw7NuIGxpbmVhbCAoZW4gYXp1bCkgcXVlIGFqdXN0w6kgc29icmUgbG9zIGRhdG9zLiBMYSBjZXJjYW7DrWEgZGUgbG9zIHB1bnRvcyBhIGVzdGFzIGzDrW5lYXMgcmVmbGVqYSB1bmEgYWx0YSBjb25jb3JkYW5jaWEgZW50cmUgYW1ib3MgdmFsb3JlcywgbG8gcXVlIG1lIHBlcm1pdGUgY29uZmlybWFyIHF1ZSBlbCBtb2RlbG8gY2FsaWJyYWRvIHJlcHJvZHVjZSBkZSBtYW5lcmEgcHJlY2lzYSBsYXMgbWVkaWNpb25lcyBkZWwgZXF1aXBvIGRlIHJlZmVyZW5jaWEgeSBxdWUgcHVlZGUgYXBsaWNhcnNlIGVuIGNvbmRpY2lvbmVzIHJlYWxlcy4KCmBgYHtyIG1vZGVsbywgZWNobz1UUlVFfQoKbW9kZWxvX2ZpbmFsIDwtIGxtKHBtMjVfcmVmZXJlbmNpYSB+IHBtMjVfc2Vuc29yICsgdGVtcGVyYXR1cmEgKiBodW1lZGFkLCBkYXRhID0gZGF0b3NfZW50cmVuYW1pZW50bykKc3VtbWFyeShtb2RlbG9fZmluYWwpCgpkYXRvcyA8LSBkYXRvcyAlPiUKICBtdXRhdGUoCiAgICBwbTI1X2NhbGlicmFkbyA9IDMzLjU3NjUxOSArCiAgICAgICAgICAgICAgICAgICAgIDAuNjAyMTA1ICogcG0yNV9zZW5zb3IgKwogICAgICAgICAgICAgICAgICAgICgtMC44MDU5ODEpICogdGVtcGVyYXR1cmEgKwogICAgICAgICAgICAgICAgICAgICgtMC4zNzEzOTYpICogaHVtZWRhZCArCiAgICAgICAgICAgICAgICAgICAgIDAuMDA4OTc2ICogdGVtcGVyYXR1cmEgKiBodW1lZGFkCiAgKQogICAgCgpnZ3Bsb3QoZGF0b3MsIGFlcyh4ID0gcG0yNV9yZWZlcmVuY2lhLCB5ID0gcG0yNV9jYWxpYnJhZG8pKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNCwgY29sb3IgPSAiYmxhY2siKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAiYmx1ZSIsIGxpbmV0eXBlID0gInNvbGlkIikgKwogIGdlb21fYWJsaW5lKHNsb3BlID0gMSwgaW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAicmVkIikgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJDb21wYXJhY2nDs24gZW50cmUgUE0yLjUgY2FsaWJyYWRvIHkgdmFsb3IgZGUgcmVmZXJlbmNpYSAobW9kZWxvIGZpbmFsKSIsCiAgICB4ID0gIlBNMi41IGRlIHJlZmVyZW5jaWEgKMK1Zy9twrMpIiwKICAgIHkgPSAiUE0yLjUgY2FsaWJyYWRvICjCtWcvbcKzKSIKICApICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKQpgYGAKCmBgYHtyIG1vZGVsbzIsIGVjaG89VFJVRX0KIyBHcmFmaWNhIAoKZGF0b3MgJT4lCiAgc2VsZWN0KGZlY2hhX2hvcmEsIHBtMjVfc2Vuc29yLCBwbTI1X3JlZmVyZW5jaWEsIHBtMjVfY2FsaWJyYWRvKSAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IHN0YXJ0c193aXRoKCJwbTI1XyIpLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJ0aXBvIiwKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInBtMjUiKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBmZWNoYV9ob3JhLCB5ID0gcG0yNSwgY29sb3IgPSB0aXBvLCBsaW5ldHlwZSA9IHRpcG8sIHNpemUgPSB0aXBvKSkgKwogIGdlb21fbGluZSgpICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgICB2YWx1ZXMgPSBjKAogICAgICAicG0yNV9zZW5zb3IiID0gImdyYXk4MCIsCiAgICAgICJwbTI1X3JlZmVyZW5jaWEiID0gInN0ZWVsYmx1ZSIsICAgICAgICMgYXp1bCBtw6FzIHN1YXZlCiAgICAgICJwbTI1X2NhbGlicmFkbyIgPSAiZGFya2dyZWVuIgogICAgKQogICkgKwogIHNjYWxlX2xpbmV0eXBlX21hbnVhbCgKICAgIHZhbHVlcyA9IGMoCiAgICAgICJwbTI1X3NlbnNvciIgPSAiZG90dGVkIiwKICAgICAgInBtMjVfcmVmZXJlbmNpYSIgPSAic29saWQiLAogICAgICAicG0yNV9jYWxpYnJhZG8iID0gInNvbGlkIgogICAgKQogICkgKwogIHNjYWxlX3NpemVfbWFudWFsKAogICAgdmFsdWVzID0gYygKICAgICAgInBtMjVfc2Vuc29yIiA9IDAuMywKICAgICAgInBtMjVfcmVmZXJlbmNpYSIgPSAwLjgsCiAgICAgICJwbTI1X2NhbGlicmFkbyIgPSAwLjgKICAgICkKICApICsKICBzY2FsZV94X2RhdGV0aW1lKGRhdGVfYnJlYWtzID0gIjEgbW9udGgiLCBkYXRlX2xhYmVscyA9ICIlYi0lWSIpICsKICBsYWJzKAogICAgdGl0bGUgPSAiU2VyaWUgZGUgdGllbXBvIGRlIFBNMi41OiBTZW5zb3IsIFJlZmVyZW5jaWEgeSBDYWxpYnJhZG8iLAogICAgeCA9ICJGZWNoYSIsCiAgICB5ID0gIlBNMi41ICjCtWcvbcKzKSIsCiAgICBjb2xvciA9ICJUaXBvIGRlIG1lZGljacOzbiIsCiAgICBsaW5ldHlwZSA9ICJUaXBvIGRlIG1lZGljacOzbiIKICApICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpCmBgYAojIyA3LiBCbGFuZC1BbHRtYW46CgpTZSBlbGFib3JhIHVuIGdyw6FmaWNvIGRlIEJsYW5kLUFsdG1hbiBwYXJhIGV2YWx1YXIgbGEgY29uY29yZGFuY2lhIGVudHJlIGxhcyBjb25jZW50cmFjaW9uZXMgZGUgUE3igoIu4oKFIGNvcnJlZ2lkYXMgbWVkaWFudGUgZWwgbW9kZWxvIGZpbmFsIGRlIGNhbGlicmFjacOzbiBhcGxpY2FkbyBhIGxvcyBkYXRvcyBkZWwgc2Vuc29yIFB1cnBsZUFpciB5IGxhcyBtZWRpY2lvbmVzIG9idGVuaWRhcyBjb24gZWwgbW9uaXRvciBkZSByZWZlcmVuY2lhIHV0aWxpemFkbyBlbiBMaW1hICAKClJFU1VMVEFET1M6IEVsIG1vZGVsbyBkZSBjYWxpYnJhY2nDs24gbXVlc3RyYSB1bmEgYWx0YSBjb25jb3JkYW5jaWEgY29uIGVsIGVxdWlwbyBkZSByZWZlcmVuY2lhLCBjb24gdW4gc2VzZ28gYmFqbyB5IGxhIG1heW9yw61hIGRlIGxhcyBkaWZlcmVuY2lhcyBlc3RhIGRlbnRybyBkZSBsb3MgbMOtbWl0ZXMgYWNlcHRhYmxlcywgc2luIGVtYmFyZ28gc2kgbXVlc3RyYSBtYXlvciB2YXJpYWJpbGlkYWQgZW4gbG9zIGV4dHJlbW9zIGFsdG9zLgoKYGBge3IgbW9kZWxvMywgZWNobz1UUlVFfQojIENhbGN1bGFyIGxhIG1lZGlhIHkgbGEgZGlmZXJlbmNpYSBlbnRyZSBtw6l0b2RvcwpibGFuZF9hbHRtYW4gPC0gZGF0b3MgJT4lCiAgbXV0YXRlKAogICAgbWVkaWEgPSAocG0yNV9jYWxpYnJhZG8gKyBwbTI1X3JlZmVyZW5jaWEpIC8gMiwKICAgIGRpZmVyZW5jaWEgPSBwbTI1X2NhbGlicmFkbyAtIHBtMjVfcmVmZXJlbmNpYQogICkKCiMgQ2FsY3VsYXIgbMOtbWl0ZXMgZGUgYWN1ZXJkbwptZWRpYV9kaWZmIDwtIG1lYW4oYmxhbmRfYWx0bWFuJGRpZmVyZW5jaWEsIG5hLnJtID0gVFJVRSkKc2RfZGlmZiA8LSBzZChibGFuZF9hbHRtYW4kZGlmZXJlbmNpYSwgbmEucm0gPSBUUlVFKQpsaW1pdGVfc3VwZXJpb3IgPC0gbWVkaWFfZGlmZiArIDEuOTYgKiBzZF9kaWZmCmxpbWl0ZV9pbmZlcmlvciA8LSBtZWRpYV9kaWZmIC0gMS45NiAqIHNkX2RpZmYKCiMgR3LDoWZpY28gZGUgQmxhbmQtQWx0bWFuCmdncGxvdChibGFuZF9hbHRtYW4sIGFlcyh4ID0gbWVkaWEsIHkgPSBkaWZlcmVuY2lhKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBtZWRpYV9kaWZmLCBjb2xvciA9ICJibHVlIiwgbGluZXR5cGUgPSAic29saWQiLCBsaW5ld2lkdGggPSAxKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gbGltaXRlX3N1cGVyaW9yLCBjb2xvciA9ICJyZWQiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gbGltaXRlX2luZmVyaW9yLCBjb2xvciA9ICJyZWQiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgbGFicygKICAgIHRpdGxlID0gIkdyw6FmaWNvIGRlIEJsYW5kLUFsdG1hbjogUE0yLjUgY2FsaWJyYWRvIHZzLiByZWZlcmVuY2lhIiwKICAgIHggPSAiTWVkaWEgZW50cmUgc2Vuc29yIGNhbGlicmFkbyB5IHJlZmVyZW5jaWEgKMK1Zy9tMykiLAogICAgeSA9ICJEaWZlcmVuY2lhIChDYWxpYnJhZG8gLSBSZWZlcmVuY2lhKSAowrVnL20zKSIKICApICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCiMjIDcuIEhBQ0VSTE8gUEFSQSBNT05JVE9SIDIgKFBydWViYSk6CgoKYGBge3IgbW9kZWxvNCwgZWNobz1UUlVFfQoKIyBDYWxjdWxhciBQTTIuNSBjYWxpYnJhZG8gY29uIGxvcyBjb2VmaWNpZW50ZXMgZGVsIG1vZGVsbwpDYW1wTWFyMl9TZW5hbWhpIDwtIENhbXBNYXIyX1NlbmFtaGkgJT4lCiAgbXV0YXRlKAogICAgcG0yNV9jYWxpYnJhZG8gPSAzMy41NzY1MTkgKwogICAgICAgICAgICAgICAgICAgICAwLjYwMjEwNSAqIHBtMjVfc2Vuc29yICsKICAgICAgICAgICAgICAgICAgICAgKC0wLjgwNTk4MSkgKiB0ZW1wZXJhdHVyYSArCiAgICAgICAgICAgICAgICAgICAgICgtMC4zNzEzOTYpICogaHVtZWRhZCArCiAgICAgICAgICAgICAgICAgICAgIDAuMDA4OTc2ICogdGVtcGVyYXR1cmEgKiBodW1lZGFkCiAgKQoKIyBHcmFmaWNhciBjYWxpYnJhZG8gdnMuIHJlZmVyZW5jaWEKZ2dwbG90KENhbXBNYXIyX1NlbmFtaGksIGFlcyh4ID0gcG0yNV9yZWZlcmVuY2lhLCB5ID0gcG0yNV9jYWxpYnJhZG8pKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNCwgY29sb3IgPSAiYmxhY2siKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAiYmx1ZSIpICsKICBnZW9tX2FibGluZShzbG9wZSA9IDEsIGludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gInJlZCIpICsKICBsYWJzKAogICAgdGl0bGUgPSAiQ29tcGFyYWNpw7NuIGVudHJlIFBNMi41IGNhbGlicmFkbyB5IHZhbG9yIGRlIHJlZmVyZW5jaWEiLAogICAgeCA9ICJQTTIuNSBkZSByZWZlcmVuY2lhICjCtWcvbcKzKSIsCiAgICB5ID0gIlBNMi41IGNhbGlicmFkbyAowrVnL23CsykiCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpCgpgYGAKCmBgYHtyIG1vZGVsbzUsIGVjaG89VFJVRX0KIyBDYWxjdWxhciBsYSBtZWRpYSB5IGxhIGRpZmVyZW5jaWEgZW50cmUgbcOpdG9kb3MKYmxhbmRfYWx0bWFuMiA8LSBDYW1wTWFyMl9TZW5hbWhpICU+JQogIG11dGF0ZSgKICAgIG1lZGlhID0gKHBtMjVfY2FsaWJyYWRvICsgcG0yNV9yZWZlcmVuY2lhKSAvIDIsCiAgICBkaWZlcmVuY2lhMiA9IHBtMjVfY2FsaWJyYWRvIC0gcG0yNV9yZWZlcmVuY2lhCiAgKQoKIyBDYWxjdWxhciBsw61taXRlcyBkZSBhY3VlcmRvCm1lZGlhX2RpZmYyIDwtIG1lYW4oYmxhbmRfYWx0bWFuMiRkaWZlcmVuY2lhMiwgbmEucm0gPSBUUlVFKQpzZF9kaWZmMiA8LSBzZChibGFuZF9hbHRtYW4yJGRpZmVyZW5jaWEyLCBuYS5ybSA9IFRSVUUpCmxpbWl0ZV9zdXBlcmlvciA8LSBtZWRpYV9kaWZmICsgMS45NiAqIHNkX2RpZmYKbGltaXRlX2luZmVyaW9yIDwtIG1lZGlhX2RpZmYgLSAxLjk2ICogc2RfZGlmZgoKIyBHcsOhZmljbyBkZSBCbGFuZC1BbHRtYW4KZ2dwbG90KGJsYW5kX2FsdG1hbjIsIGFlcyh4ID0gbWVkaWEsIHkgPSBkaWZlcmVuY2lhMikpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC41KSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gbWVkaWFfZGlmZiwgY29sb3IgPSAiYmx1ZSIsIGxpbmV0eXBlID0gInNvbGlkIiwgbGluZXdpZHRoID0gMSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGxpbWl0ZV9zdXBlcmlvciwgY29sb3IgPSAicmVkIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGxpbWl0ZV9pbmZlcmlvciwgY29sb3IgPSAicmVkIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJHcsOhZmljbyBkZSBCbGFuZC1BbHRtYW46IFBNMi41IGNhbGlicmFkbyB2cy4gcmVmZXJlbmNpYSIsCiAgICB4ID0gIk1lZGlhIGVudHJlIHNlbnNvciBjYWxpYnJhZG8geSByZWZlcmVuY2lhICjCtWcvbTMpIiwKICAgIHkgPSAiRGlmZXJlbmNpYSAoQ2FsaWJyYWRvIC0gUmVmZXJlbmNpYSkgKMK1Zy9tMykiCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYA==