Objetivo del recurso

Este recurso se hace con el fin de estudiar el comportamiento de la pandemia generada por el virus Covid-19 y como a afectado a el pais de Colombia. A pesar de que se realizan y construyen modelos se da a entender que en ningun momento pretendemos realizar predicciones ya que los comportamientos pueden ir cambiando dependiendo de las desiciones e intervenciones realizadas por el gobierno Colombiano, por lo cual, estas pueden ir cambiando y tambien se debe tener en cuenta que para una modelación adecuada hace falta más información de la que se recolecta para este recurso. Algunos gráficos son propios otros fueron tomados y modificados como los realizados por el profesor Giovanny Babativa quien compartio los codigos (https://github.com/jgbabativam/COVID-19) y de Daniel Peña Chaves (https://medium.com/@daniel.pena.chaves/simple-coronavirus-model-using-r-cf6b1bc93949).

Fuente de los datos

Los datos fuerse tomados de Github de la Jhons Hopkins (https://systems.jhu.edu/).

Como lo indica la fuente, estos datos se obtuvieron de la Organización Mundial de la Salud y de varias instituciones estatales de salud. Los datos son propiedad de la Universidad John Hopkins y están disponibles para fines de investigación académica o de enseñanza. Dado que los datos provienen de diferentes fuentes, no hay garantía de la precisión de los mismos, por lo que es incorrecto utilizarlos con fines médicos o comerciales. Si se desea realizar un análisis de ese tipo por favor use las fuentes oficiales de cada país (https://github.com/CSSEGISandData/COVID-19).

En el caso de los datos para Colombia, la información se toma del reporte del Instituto Nacional de Salud con corte a las 20:00 hrs de cada día, el cual se encuentra en https://www.ins.gov.co/Noticias/Paginas/Coronavirus.aspx.

Recuerde que este es un recurso académico, los análisis epidemiológicos son más complejos y dependen de diversos factores.

Comportamiento con otros paises similares a Colombia

Paises similares al comportamiento de Colombia en los primeros 16 dias

Inicialmente se estudia el comportamiento de como ha evolucionado la curva de crecimiento de casos con respecto a otros paises que llevan más tiempo lidiando con el coronavirus. Inicialmente se realiza se identifica que paises han tenido un comportamiento similar en los primeros 16 dias que es cuando cuando el gobierno colombiano anuncia que se debe realizar el aislamiento social.

Revisando la gráfica anterior tenemos que los paises con un comportamiento similar a Colombia en los primeros 16 son los siguientes:

 [1] "Austria"                            "Bulgaria"                          
 [3] "Canada...Alberta"                   "Canada...Newfoundland.and.Labrador"
 [5] "Canada...Nova.Scotia"               "China...Guangxi"                   
 [7] "China...Hebei"                      "China...Shaanxi"                   
 [9] "China...Yunnan"                     "Colombia"                          
[11] "Ghana"                              "Indonesia"                         
[13] "Kazakhstan"                         "Mauritius"                         
[15] "Saudi.Arabia"                       "Serbia"                            
[17] "Slovakia"                           "South.Africa"                      
[19] "Venezuela"                         

Notese que algunos paises a está altura ya han comenzado a bajar su comportamiento. Sin embargo, hay ciertos paises que son muy preocupantes ya que la cantidad de infectados en la actualidad es muy alto.

Paises similares según el comportamiento de los primeros 258 dias

Se hace el mismo ejercicio para detallar como está la curva actualmente.

De la gráfica anterior, notamos que el comportamiento de los casos de infectados son diferentes en la mayoria a los que inicialmente se tenia en los primeros 16 días. Las curvas ya comienzan a estabilizarsen en otros paises como Noruega, Serbia entre otros. Sin embargo, esto nos debe generar una alerta indicandonos que debe seguir aplanando la curva.

Distribución de nuevos casos en Colombia

Se obseva que los casos nuevos los casos han venido en aumento de forma diaria, sin embargo, se intenta identificar que despues de ciertas fechas el cambio de casos infectados es más fuerte que en otras fechas, por lo cual se intenta identificar que fechas el cambio es más importante.

y is    14 when
    tiempo < 18

y is    89 when
    tiempo is 18 to 33

y is   175 when
    tiempo is 33 to 50

y is   278 when
    tiempo is 50 to 57

y is   443 when
    tiempo is 57 to 66

y is   653 when
    tiempo is 66 to 78

y is  1005 when
    tiempo is 78 to 85

y is  1433 when
    tiempo is 85 to 100

y is  2429 when
    tiempo is 100 to 111

y is  3671 when
    tiempo is 111 to 126

y is  5999 when
    tiempo is 207 to 214

y is  6761 when
    tiempo is 126 to 145

y is  6910 when
    tiempo is 193 to 207

y is  7233 when
    tiempo is 185 to 193

y is  7389 when
    tiempo is 214 to 229

y is  7414 when
    tiempo >= 248

y is  8493 when
    tiempo is 176 to 185

y is  8977 when
    tiempo is 229 to 248

y is  9735 when
    tiempo is 145 to 153

y is  9758 when
    tiempo is 169 to 176

y is 11171 when
    tiempo is 153 to 169

Notamos que hay dos fechas en el que el promedio de casos cambia considerablemente, antes de los primeros 16 el promedios de casos era de 8.5, entre los primeros 16 a los 24 días el promedio aumenta a 60 casos diarios y despues de los 24 días el promedio es de 140 casos diarios. Estas fechas son las siguientes

 [1] "2020-03-06" "2020-03-23" "2020-04-06" "2020-04-24" "2020-04-30" "2020-05-10" "2020-05-22"
 [8] "2020-05-28" "2020-06-13" "2020-06-23" "2020-07-09" "2020-07-27" "2020-08-04" "2020-08-20"
[15] "2020-08-28" "2020-09-05" "2020-09-13" "2020-09-27" "2020-10-05" "2020-10-19" "2020-11-08"
[22] "2020-11-18"

Revisando las diferencias fechas teniendo en cuenta el inicio de la cuarentena notamos que el promedio de las fechas importantes anteriores es de 12.2380952 por lo cual se propone crear una variable factor que tenga en cuenta los cortes cada 14 dias, a excepción de los últimos dias los cuales se quieren pronosticar. Esta información se tiene en cuenta para mejorar las predicciones en el modelo que se construye a continuación.

Construcción del modelo para predecir el número de casos acumulados de Coronavirus en Colombia

Se desea construir un modelo que permita estimar el número de casos confirmados acumulados. Para ellos se construye un modelo quasipoisson el que se tiene en cuenta el número de casos confirmados acumulados como variable dependiente (valores) y como variables independientes se tiene en cuenta las siguientes:

Para determinar que tan bueno es el modelo se excluyen los últimos 5 datos para tratar de predecir con el modelo.

los resultados son los siguientes


Call:
glm(formula = valores ~ tiempo + cortes, family = quasipoisson(link = "log"), 
    data = colombia)

Deviance Residuals: 
   Min      1Q  Median      3Q     Max  
-67.10  -14.87    0.00   12.99   67.26  

Coefficients:
             Estimate Std. Error t value             Pr(>|t|)    
(Intercept) 3.4274887  1.0936175   3.134             0.001945 ** 
tiempo      0.0135433  0.0006353  21.318 < 0.0000000000000002 ***
cortes1     2.6405257  1.1254450   2.346             0.019805 *  
cortes2     3.8221959  1.1019082   3.469             0.000623 ***
cortes3     4.3823564  1.0977929   3.992      0.0000878373627 ***
cortes4     4.9141499  1.0960630   4.483      0.0000115267310 ***
cortes5     5.3845007  1.0954811   4.915      0.0000016730161 ***
cortes6     5.8165056  1.0954291   5.310      0.0000002557625 ***
cortes7     6.1814922  1.0956766   5.642      0.0000000486124 ***
cortes8     6.5432756  1.0960912   5.970      0.0000000087962 ***
cortes9     6.8633424  1.0966357   6.259      0.0000000018474 ***
cortes10    7.1597168  1.0972810   6.525      0.0000000004195 ***
cortes11    7.3763174  1.0980165   6.718      0.0000000001399 ***
cortes12    7.4719521  1.0988342   6.800      0.0000000000871 ***
cortes13    7.4599283  1.0997286   6.783      0.0000000000959 ***
cortes14    7.4003077  1.1006960   6.723      0.0000000001356 ***
cortes15    7.3242671  1.1017351   6.648      0.0000000002088 ***
cortes16    7.2473303  1.1028453   6.571      0.0000000003225 ***
cortes17    7.1757752  1.1040261   6.500      0.0000000004838 ***
cortes18    7.1293616  1.1048713   6.453      0.0000000006298 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for quasipoisson family taken to be 571.7043)

    Null deviance: 117943624  on 252  degrees of freedom
Residual deviance:    133628  on 233  degrees of freedom
AIC: NA

Number of Fisher Scoring iterations: 5

Analysis of Deviance Table

Model: quasipoisson, link: log

Response: valores

Terms added sequentially (first to last)

       Df  Deviance Resid. Df Resid. Dev              Pr(>Chi)    
NULL                      252  117943624                          
tiempo  1 108668854       251    9274770 < 0.00000000000000022 ***
cortes 18   9141142       233     133628 < 0.00000000000000022 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Según los resultados la variable planteadas son significativas, por lo que se utilizan para realizar las estimaciones.

Estimación la tasa de contagio por día

Estimate    2.5 %   97.5 % 
1.013635 1.012374 1.014898 

Según el valor anterior, tenemos que la tasa de contagio es del 1.0136354. Por lo que por cada día que pasa el tiempo la tasa de infección aumenta en un 1.4%, con intervalo entre el 1.2% y 1.5%.

Ajuste del modelo

Se determina que tan bueno es el ajuste del modelo. Calculando la función envelope para determinar que tan bueno se ajusta el modelo.

Quasi-Poisson model 

Observando el modelo, que algunos datos no se ajustan bien. Esto se debe a las observaciones iniciales. Para el resto de las observaciones notamos que el ajuste es bueno, ya que la mayoría de los residuales se encuentra dentro de los límites de la gráfica envelope.

Predicciones del modelo

Realizando las predicciones respectivas para determinar el número de casos acumulados encontramos que las predicciones son buenas. Los valores que se se encuentran por encima de la linea vertical, son valores que se están prediciendo.

En la siguiente tabla se puede observar las predicciones (pred_cum) los valores del intervalo al 95% (lower_cum, upper_cum), los valores de confirmados (valores) y las fechas actuales.

Estimación del número de días que puede llegar durar la cuarentena en Colombia

Para estimar el número de días, se tiene en cuenta el modelo SIR (Susceptible-Infectado-Recuperado), este modelo consiste en solucionar un sistema de ecuaciones diferenciales que relaciona el número de personas susceptible a ser infectadas de una población, el número de personas infectadas el cual y el número de personas recuperadas. El sistema de ecuaciones el el siguiente: \[ \begin{align*} \frac{dS}{dt} &= -\frac{\beta IS}{N}\\ \frac{dI}{dt} &= \frac{\beta IS}{N}-\gamma I\\ \frac{dR}{dt} &= \gamma I\\ \end{align*} \] Donde \(\beta\) es el parámetro de que controla la transición de entre los suceptibles (S) e infectados (I) y \(\gamma\) que controla la transición entre los infectados (I) y recuperados (R).

Para realizar la estimación en el caso colombiano, se tiene en cuenta la información tomada en el blog de Learning Machines (https://blog.ephorie.de/epidemiology-how-contagious-is-novel-coronavirus-2019-ncov).

La base para Colombia se decarga de (https://github.com/CSSEGISandData/COVID-19) y es la siguiente:

Simulación para Colombia para los primeros 16 dias

Para nuestro caso tenemos una población de personas de 50372424 según el DANE. Las simulaciones se realizaran con los primeros 16 dias teniendo en cuenta que fue cuando comenzo la cuarentena. Tenga presente que esta es una simulación de los resultados.

A continuación se tiene los valores de \(\beta\) y \(\gamma\).

     beta     gamma 
0.6821477 0.3178523 

Estimación de \(R_0\)

Algo importante a tener en cuenta es el \(R_0\), que es la tasa de contagio por cada persona infectada. Este calculo se realiza dividiendo \(\beta\) sobre \(\gamma\) al realizar esto se tiene lo siguiente:

      R0 
2.146115 

Según el resultado anterior, por cada persona infectada, está esta en la capacidad de infectar 2.15 personas.

A continuación se calcula el númer de días que se pueden dar para alcanzar el máximo número de personas infectadas desde que se dio el primer contagio que fue el día 2020-03-06.

[1] 49

Al día de hoy 2020-11-19, se tienen 258 por lo que ya han pasado 209 días.

Según las simulaciones el total de infectados sería de

[1] 7175048

Gráfico del comportamiento

Simulación para Colombia a la fecha

A continuación se actualiza la información a dia de hoy. Tengamos presente que los datos han cambiado debido a las diferentes intervenciones que realizó el gobierno de Colombia.

A continuación los nuevos valores de \(\beta\) y \(\gamma\) son los siguientes:.

     beta     gamma 
0.2844249 0.2164376 

La nueva estimación de \(R_0\) es la siguiente:

     R0 
1.31412 

Según el resultado anterior, por cada persona infectada, está esta en la capacidad de infectar 1.31 personas. Lo que indica que las medidas tomadas de la cuarentena si han funcionado

El número de dias para llegar al máximo a la fecha de hoy es de:

[1] 230

Por lo que el máximo se alcanzaría a los 230 dias. A fecha de hoy 2020-11-19 han pasado 258 días por lo que ya hemos alcanzado el máximo según el modelo ajustado.

LS0tDQp0aXRsZTogJ0NPVklELTE5OiBEZXNjcmlwY2nDs24gZ3LDoWZpY2EgZGUgbG9zIHJlc3VsdGFkb3MgZW4gQ29sb21iaWEnDQphdXRob3I6ICJBbGV4IFphbWJyYW5vIGFsZXhqemNAZ21haWwuY29tIg0KZGF0ZTogIkluZm9ybWUgYWN0dWFsaXphZG8gYWw6IGByIGRhdGUoKWAiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCmBgYA0KDQojIyBPYmpldGl2byBkZWwgcmVjdXJzbw0KDQpFc3RlIHJlY3Vyc28gc2UgaGFjZSBjb24gZWwgZmluIGRlIGVzdHVkaWFyIGVsIGNvbXBvcnRhbWllbnRvIGRlIGxhIHBhbmRlbWlhIGdlbmVyYWRhIHBvciBlbCB2aXJ1cyBDb3ZpZC0xOSB5IGNvbW8gYSBhZmVjdGFkbyBhIGVsIHBhaXMgZGUgQ29sb21iaWEuIEEgcGVzYXIgZGUgcXVlIHNlIHJlYWxpemFuIHkgY29uc3RydXllbiBtb2RlbG9zIHNlIGRhIGEgZW50ZW5kZXIgcXVlIGVuIG5pbmd1biBtb21lbnRvIHByZXRlbmRlbW9zIHJlYWxpemFyIHByZWRpY2Npb25lcyB5YSBxdWUgbG9zIGNvbXBvcnRhbWllbnRvcyBwdWVkZW4gaXIgY2FtYmlhbmRvIGRlcGVuZGllbmRvIGRlIGxhcyBkZXNpY2lvbmVzIGUgaW50ZXJ2ZW5jaW9uZXMgcmVhbGl6YWRhcyBwb3IgZWwgZ29iaWVybm8gQ29sb21iaWFubywgcG9yIGxvIGN1YWwsIGVzdGFzIHB1ZWRlbiBpciBjYW1iaWFuZG8geSB0YW1iaWVuIHNlIGRlYmUgdGVuZXIgZW4gY3VlbnRhIHF1ZSBwYXJhIHVuYSBtb2RlbGFjacOzbiBhZGVjdWFkYSBoYWNlIGZhbHRhIG3DoXMgaW5mb3JtYWNpw7NuIGRlIGxhIHF1ZSBzZSByZWNvbGVjdGEgcGFyYSBlc3RlIHJlY3Vyc28uIEFsZ3Vub3MgZ3LDoWZpY29zIHNvbiBwcm9waW9zIG90cm9zIGZ1ZXJvbiB0b21hZG9zIHkgbW9kaWZpY2Fkb3MgY29tbyBsb3MgcmVhbGl6YWRvcyBwb3IgZWwgcHJvZmVzb3IgR2lvdmFubnkgQmFiYXRpdmEgcXVpZW4gY29tcGFydGlvIGxvcyBjb2RpZ29zIChodHRwczovL2dpdGh1Yi5jb20vamdiYWJhdGl2YW0vQ09WSUQtMTkpIHkgZGUgRGFuaWVsIFBlw7FhIENoYXZlcyAoaHR0cHM6Ly9tZWRpdW0uY29tL0BkYW5pZWwucGVuYS5jaGF2ZXMvc2ltcGxlLWNvcm9uYXZpcnVzLW1vZGVsLXVzaW5nLXItY2Y2YjFiYzkzOTQ5KS4NCg0KIyMgRnVlbnRlIGRlIGxvcyBkYXRvcw0KDQpMb3MgZGF0b3MgZnVlcnNlIHRvbWFkb3MgZGUgR2l0aHViIGRlIGxhIEpob25zIEhvcGtpbnMgKGh0dHBzOi8vc3lzdGVtcy5qaHUuZWR1LykuDQoNCkNvbW8gbG8gaW5kaWNhIGxhIGZ1ZW50ZSwgZXN0b3MgZGF0b3Mgc2Ugb2J0dXZpZXJvbiBkZSBsYSBPcmdhbml6YWNpw7NuIE11bmRpYWwgZGUgbGEgU2FsdWQgeSBkZSB2YXJpYXMgaW5zdGl0dWNpb25lcyBlc3RhdGFsZXMgZGUgc2FsdWQuIExvcyBkYXRvcyBzb24gcHJvcGllZGFkIGRlIGxhIFVuaXZlcnNpZGFkIEpvaG4gSG9wa2lucyB5IGVzdMOhbiBkaXNwb25pYmxlcyBwYXJhIGZpbmVzIGRlIGludmVzdGlnYWNpw7NuIGFjYWTDqW1pY2EgbyBkZSBlbnNlw7FhbnphLiBEYWRvIHF1ZSBsb3MgZGF0b3MgcHJvdmllbmVuIGRlIGRpZmVyZW50ZXMgZnVlbnRlcywgbm8gaGF5IGdhcmFudMOtYSBkZSBsYSBwcmVjaXNpw7NuIGRlIGxvcyBtaXNtb3MsIHBvciBsbyBxdWUgZXMgaW5jb3JyZWN0byB1dGlsaXphcmxvcyBjb24gZmluZXMgbcOpZGljb3MgbyBjb21lcmNpYWxlcy4gU2kgc2UgZGVzZWEgcmVhbGl6YXIgdW4gYW7DoWxpc2lzIGRlIGVzZSB0aXBvIHBvciBmYXZvciB1c2UgbGFzIGZ1ZW50ZXMgb2ZpY2lhbGVzIGRlIGNhZGEgcGHDrXMgKGh0dHBzOi8vZ2l0aHViLmNvbS9DU1NFR0lTYW5kRGF0YS9DT1ZJRC0xOSkuIA0KDQpFbiBlbCBjYXNvIGRlIGxvcyBkYXRvcyBwYXJhIENvbG9tYmlhLCBsYSBpbmZvcm1hY2nDs24gc2UgdG9tYSBkZWwgcmVwb3J0ZSBkZWwgSW5zdGl0dXRvIE5hY2lvbmFsIGRlIFNhbHVkIGNvbiBjb3J0ZSBhIGxhcyAyMDowMCBocnMgZGUgY2FkYSBkw61hLCBlbCBjdWFsIHNlIGVuY3VlbnRyYSBlbiBodHRwczovL3d3dy5pbnMuZ292LmNvL05vdGljaWFzL1BhZ2luYXMvQ29yb25hdmlydXMuYXNweC4NCg0KUmVjdWVyZGUgcXVlIGVzdGUgZXMgdW4gcmVjdXJzbyBhY2Fkw6ltaWNvLCBsb3MgYW7DoWxpc2lzIGVwaWRlbWlvbMOzZ2ljb3Mgc29uIG3DoXMgY29tcGxlam9zIHkgZGVwZW5kZW4gZGUgZGl2ZXJzb3MgZmFjdG9yZXMuDQoNCiMgQ29tcG9ydGFtaWVudG8gY29uIG90cm9zIHBhaXNlcyBzaW1pbGFyZXMgYSBDb2xvbWJpYQ0KDQpgYGB7ciBsZWN0dXJhLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShjaVRvb2xzKQ0KbGlicmFyeShnZ3JlcGVsKQ0KI2xpbnRyOjpsaW50KCJDb3ZpZC0xOS5SbWQiKQ0KDQpvcHRpb25zKHNjaXBlbiA9IDExMTEpDQoNCiAjIExlY3R1cmEgZGUgbG9zIGRhdG9zICMjIyMNCmRiIDwtIHJlYWRfY3N2KCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vQ1NTRUdJU2FuZERhdGEvQ09WSUQtMTkvbWFzdGVyL2Nzc2VfY292aWRfMTlfZGF0YS9jc3NlX2NvdmlkXzE5X3RpbWVfc2VyaWVzL3RpbWVfc2VyaWVzX2NvdmlkMTlfY29uZmlybWVkX2dsb2JhbC5jc3YiKQ0KDQpkaWFzIDwtIG5jb2woZGIpDQoNCmlmIChhbGwoaXMubmEoZGJbLCBkaWFzXSkgPT0gRikpIGRiIDwtIHNlbGVjdChkYiwgMTpkaWFzKSBlbHNlIGRiIDwtIHNlbGVjdChkYiwgMTooZGlhcyAtIA0KICAxKSkNCg0KIyBBcnJlZ2xhbmRvIGxvcyBkYXRvcyAjIyMjDQpkYiRuYW1lIDwtIGlmZWxzZShpcy5uYShkYiRgUHJvdmluY2UvU3RhdGVgKSwgZGIkYENvdW50cnkvUmVnaW9uYCwgcGFzdGUoZGIkYENvdW50cnkvUmVnaW9uYCwgDQogIGRiJGBQcm92aW5jZS9TdGF0ZWAsIHNlcCA9ICIgLSAiKSkNCmRiJGBQcm92aW5jZS9TdGF0ZWAgPC0gTlVMTA0KZGIkYENvdW50cnkvUmVnaW9uYCA8LSBOVUxMDQpub21icmVzIDwtIGRiJG5hbWUNCmRiJG5hbWUgPC0gTlVMTA0KDQpjb29yZGVuYWRhcyA8LSBkYiAlPiUgZHBseXI6OnNlbGVjdChMYXQsIExvbmcpDQpkYiRMYXQgPC0gTlVMTA0KZGIkTG9uZyA8LSBOVUxMDQoNCnJvd25hbWVzKGRiKSA8LSBub21icmVzDQoNCmRiIDwtIGRhdGEuZnJhbWUodChkYikpDQoNCnBhaXNlcyA8LSBkYlssIGNvbFN1bXMoZGIsIG5hLnJtID0gVCkgIT0gMF0NCg0KZGF0b3MgPC0gbWF0cml4KE5BLCBucm93ID0gbnJvdyhwYWlzZXMpLCBuY29sID0gbmNvbChwYWlzZXMpKQ0KZGF0b3MgPC0gZGF0YS5mcmFtZShkYXRvcykNCg0KIyBTZSBxdWl0YW4gbG9zIGNlcm9zIGluaWNpYWxlcyBkZSB0b2RvcyBsb3MgcGFpc2VzICMjIyMNCmZvciAoaSBpbiAxOm5jb2wocGFpc2VzKSkNCnsNCiAgYmxvcXVlIDwtIHBhaXNlc1twYWlzZXNbLCBpXSAhPSAwLCBpXQ0KICBkYXRvc1sxOmxlbmd0aChibG9xdWUpLCBpXSA8LSBibG9xdWUNCn0NCg0KZGIuY29sb21iaWEgPC0gcmVhZF9jc3YoImh0dHBzOi8vb3BlbmRhdGEuYXJjZ2lzLmNvbS9kYXRhc2V0cy83ODIxMjI2MjRmMzY0ZmJkYmQ3ZTI4N2I5NmM0YTM1OF82LmNzdiIpDQoNCg0KZGIuY29sb21iaWEkRkVDSEFfQUNUVUFMSVpBQ0lPTiA8LSBhcy5EYXRlKGRiLmNvbG9tYmlhJEZFQ0hBX0FDVFVBTElaQUNJT04sICIlWS8lbS8lZCIpDQoNCmRiLmNvbG9tYmlhW2RiLmNvbG9tYmlhJEZFQ0hBX0FDVFVBTElaQUNJT04gPT0gIjIwMjAtMDQtMDQiLF0kTlVFVk9TX0NBU09TIDwtIDE0MDYgLSAxMjY3DQpkYi5jb2xvbWJpYVtkYi5jb2xvbWJpYSRGRUNIQV9BQ1RVQUxJWkFDSU9OID09ICIyMDIwLTA0LTA0IixdJFRPVEFMX0NBU09TIDwtIDE0MDYNCmRiLmNvbG9tYmlhW2RiLmNvbG9tYmlhJEZFQ0hBX0FDVFVBTElaQUNJT04gPT0gIjIwMjAtMDQtMDQiLF0kVE9UQUxfTVVFUlRFUyA8LSAzMg0KZGIuY29sb21iaWFbZGIuY29sb21iaWEkRkVDSEFfQUNUVUFMSVpBQ0lPTiA9PSAiMjAyMC0wNC0wNCIsXSRUT1RBTF9SRUNVUEVSQURPUyA8LSA4NQ0KDQpuYW1lcyhkYXRvcykgPC0gbmFtZXMocGFpc2VzKQ0KDQpkYXRvcyRDb2xvbWJpYVsxOmxlbmd0aChkYi5jb2xvbWJpYSRUT1RBTF9DQVNPUyldIDwtIGRiLmNvbG9tYmlhJFRPVEFMX0NBU09TDQpgYGANCg0KDQojIyBQYWlzZXMgc2ltaWxhcmVzIGFsIGNvbXBvcnRhbWllbnRvIGRlIENvbG9tYmlhIGVuIGxvcyBwcmltZXJvcyAxNiBkaWFzDQoNCkluaWNpYWxtZW50ZSBzZSBlc3R1ZGlhIGVsIGNvbXBvcnRhbWllbnRvIGRlIGNvbW8gaGEgZXZvbHVjaW9uYWRvIGxhIGN1cnZhIGRlIGNyZWNpbWllbnRvIGRlIGNhc29zIGNvbiByZXNwZWN0byBhIG90cm9zIHBhaXNlcyBxdWUgbGxldmFuIG3DoXMgdGllbXBvIGxpZGlhbmRvIGNvbiBlbCBjb3JvbmF2aXJ1cy4gSW5pY2lhbG1lbnRlIHNlIHJlYWxpemEgc2UgaWRlbnRpZmljYSBxdWUgcGFpc2VzIGhhbiB0ZW5pZG8gdW4gY29tcG9ydGFtaWVudG8gc2ltaWxhciBlbiBsb3MgcHJpbWVyb3MgMTYgZGlhcyBxdWUgZXMgY3VhbmRvIGN1YW5kbyBlbCBnb2JpZXJubyBjb2xvbWJpYW5vIGFudW5jaWEgcXVlIHNlIGRlYmUgcmVhbGl6YXIgZWwgYWlzbGFtaWVudG8gc29jaWFsLg0KYGBge3IgYWdydXBhMTYsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpuMSA8LSBzdW0oaXMubmEoZGF0b3NbLCBuYW1lcyhkYXRvcykgPT0gIkNvbG9tYmlhIl0pID09IEYpICAjIE7Dum1lcm8gZGUgZGlhcyBhY3R1YWxlcw0KDQpuIDwtIDE2ICAjIFNlIHNlbGVjY2lvbmFuIGVsIG7Dum1lcm8gZGUgZGlhcyBxdWUgZW1wZXpvIGxhIGN1YXJlbnRlbmENCg0KZGF0b3MxIDwtIGRhdG9zWzE6biwgXSAgIyBTZSBmaWx0cmEgdG9kb3MgbG9zIHBhaXNlcyBwb3IgZWwgbWlzbW8gbsO6bWVybyBkZSBkaWFzDQoNCmRhdG9zMSA8LSBkYXRvczFbLCBpcy5uYShjb2xTdW1zKGRhdG9zMSkpID09IEZdDQoNCmRiMiA8LSBkYXRhLmZyYW1lKHQoZGF0b3MxKSkNCg0KIyBTZSBhZ3J1cGFuIGxvcyBwYWlzZXMgc2ltaWxhcmVzIGFsIGNvbXBvcnRhbWllbnRvIGRlIENvbG9tYmlhIGVuIGxvcyBuIGRpYXMNCiMgIyMjIw0KSENsdXN0LjEgPC0gaGNsdXN0KGRpc3QoZGIyKSwgbWV0aG9kID0gIndhcmQuRCIpDQpkYjIkaGNsdXMubGFiZWwgPC0gUmNtZHJNaXNjOjphc3NpZ25DbHVzdGVyKGRiMiwgZGIyLCBjdXRyZWUoSENsdXN0LjEsIGsgPSAxNSkpICAjIDE1IGdydXBvcw0KDQpncnVwbyA8LSBkYjJbcm93bmFtZXMoZGIyKSA9PSAiQ29sb21iaWEiLCBdJGhjbHVzLmxhYmVsDQoNCnBhaXNlcy5zaW1pbGFyZXMgPC0gcm93Lm5hbWVzKGRiMltkYjIkaGNsdXMubGFiZWwgPT0gZ3J1cG8sIF0pDQoNCnBhaXNlcy5lamVtcGxvcyA8LSBkYlssIG5hbWVzKGRiKSAlaW4lIHBhaXNlcy5zaW1pbGFyZXNdDQpwYWlzZXMuZWplbXBsb3MkZmVjaGFzIDwtIHJvdy5uYW1lcyhwYWlzZXMuZWplbXBsb3MpDQpwYWlzZXMuZWplbXBsb3MkZmVjaGFzIDwtIHBhc3RlMChwYWlzZXMuZWplbXBsb3MkZmVjaGFzLCAiMjAiKQ0KcGFpc2VzLmVqZW1wbG9zJGZlY2hhcyA8LSBhcy5EYXRlKHBhaXNlcy5lamVtcGxvcyRmZWNoYXMsICIlbS8lZC8lWSIpDQoNCnBhaXNlcy5lamVtcGxvczIgPC0gcGFpc2VzLmVqZW1wbG9zICU+JSBnYXRoZXIocGFpc2VzLCB2YWxvcmVzLCAtZmVjaGFzKSAlPiUgdHlwZS5jb252ZXJ0KCkNCnBhaXNlcy5lamVtcGxvczIkZmVjaGFzIDwtIGFzLkRhdGUocGFpc2VzLmVqZW1wbG9zMiRmZWNoYXMsICIlWS0lbS0lZCIpDQoNCnBhaXNlcy5lamVtcGxvczIgJT4lIGdncGxvdChhZXMoZmVjaGFzLCB2YWxvcmVzLCBncm91cCA9IHBhaXNlcykpICsgZ2VvbV9saW5lKCkgKyANCiAgZmFjZXRfd3JhcCh2YXJzKHBhaXNlcykpICsgc2NhbGVfeF9kYXRlKCkgKyB0aGVtZV9idygpDQpgYGANCg0KUmV2aXNhbmRvIGxhIGdyw6FmaWNhIGFudGVyaW9yIHRlbmVtb3MgcXVlIGxvcyBwYWlzZXMgY29uIHVuIGNvbXBvcnRhbWllbnRvIHNpbWlsYXIgYSBDb2xvbWJpYSBlbiBsb3MgcHJpbWVyb3MgMTYgc29uIGxvcyBzaWd1aWVudGVzOg0KYGBge3IgZWNobz1GQUxTRX0NCnBhaXNlcy5zaW1pbGFyZXMNCmBgYA0KDQpOb3Rlc2UgcXVlIGFsZ3Vub3MgcGFpc2VzIGEgZXN0w6EgYWx0dXJhIHlhIGhhbiBjb21lbnphZG8gYSBiYWphciBzdSBjb21wb3J0YW1pZW50by4gU2luIGVtYmFyZ28sIGhheSBjaWVydG9zIHBhaXNlcyBxdWUgc29uIG11eSBwcmVvY3VwYW50ZXMgeWEgcXVlIGxhIGNhbnRpZGFkIGRlIGluZmVjdGFkb3MgZW4gbGEgYWN0dWFsaWRhZCBlcyBtdXkgYWx0by4NCg0KIyMgUGFpc2VzIHNpbWlsYXJlcyBzZWfDum4gZWwgY29tcG9ydGFtaWVudG8gZGUgbG9zIHByaW1lcm9zIGByIG4xYCBkaWFzDQoNClNlIGhhY2UgZWwgbWlzbW8gZWplcmNpY2lvIHBhcmEgZGV0YWxsYXIgY29tbyBlc3TDoSBsYSBjdXJ2YSBhY3R1YWxtZW50ZS4NCg0KYGBge3IgYWdydXBhX24sIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpuIDwtIG4xICMgU2Ugc2VsZWNjaW9uYW4gZWwgbsO6bWVybyBkZSBkaWFzIGFjdHVhbA0KDQpkYXRvcyA8LSBkYXRvc1sxOm4sXSAjIFNlIGZpbHRyYSB0b2RvcyBsb3MgcGFpc2VzIHBvciBlbCBtaXNtbyBuw7ptZXJvIGRlIGRpYXMNCg0KZGF0b3MgPC0gZGF0b3NbLGlzLm5hKGNvbFN1bXMoZGF0b3MpKSA9PSBGXQ0KDQpkYjIgPC0gZGF0YS5mcmFtZSh0KGRhdG9zKSkNCg0KIyBTZSBhZ3J1cGFuIGxvcyBwYWlzZXMgc2ltaWxhcmVzIGFsIGNvbXBvcnRhbWllbnRvIGRlIENvbG9tYmlhIGVuIGxvcyBuIGRpYXMgIyMjIw0KSENsdXN0LjEgPC0gaGNsdXN0KGRpc3QoZGIyKSwgbWV0aG9kPSAid2FyZC5EIikNCmRiMiRoY2x1cy5sYWJlbCA8LSBSY21kck1pc2M6OmFzc2lnbkNsdXN0ZXIoZGIyLCBkYjIsIGN1dHJlZShIQ2x1c3QuMSwgaz0gMTApKSAjIDE1IGdydXBvcw0KDQpncnVwbyA8LSBkYjJbcm93bmFtZXMoZGIyKSA9PSAiQ29sb21iaWEiLF0kaGNsdXMubGFiZWwNCg0KcGFpc2VzLnNpbWlsYXJlcyA8LSByb3cubmFtZXMoZGIyW2RiMiRoY2x1cy5sYWJlbCA9PSBncnVwbyxdKQ0KDQpwYWlzZXMuZWplbXBsb3MgPC0gZGJbLG5hbWVzKGRiKSAlaW4lIHBhaXNlcy5zaW1pbGFyZXNdDQpwYWlzZXMuZWplbXBsb3MkZmVjaGFzIDwtIHJvdy5uYW1lcyhwYWlzZXMuZWplbXBsb3MpDQpwYWlzZXMuZWplbXBsb3MkZmVjaGFzIDwtIHBhc3RlMChwYWlzZXMuZWplbXBsb3MkZmVjaGFzLCIyMCIpDQpwYWlzZXMuZWplbXBsb3MkZmVjaGFzIDwtIGFzLkRhdGUocGFpc2VzLmVqZW1wbG9zJGZlY2hhcywgIiVtLyVkLyVZIikNCg0KcGFpc2VzLmVqZW1wbG9zMiA8LSBwYWlzZXMuZWplbXBsb3MgJT4lIGdhdGhlcihwYWlzZXMsdmFsb3JlcywtZmVjaGFzKSAlPiUgdHlwZS5jb252ZXJ0KCkNCnBhaXNlcy5lamVtcGxvczIkZmVjaGFzIDwtIGFzLkRhdGUocGFpc2VzLmVqZW1wbG9zMiRmZWNoYXMsICIlWS0lbS0lZCIpDQoNCiMgU2UgZ3LDoWZpY2FuIGNvbXBvcnRhbWllbnRvcyBzaW1pbGFyZXMgIyMjIw0KcGFpc2VzLmVqZW1wbG9zMiAlPiUgIGdncGxvdChhZXMoZmVjaGFzLHZhbG9yZXMsZ3JvdXA9cGFpc2VzKSkgKyBnZW9tX2xpbmUoKSArDQogIGZhY2V0X3dyYXAodmFycyhwYWlzZXMpKSArIHNjYWxlX3hfZGF0ZSgpICsgdGhlbWVfYncoKQ0KYGBgDQoNCkRlIGxhIGdyw6FmaWNhIGFudGVyaW9yLCBub3RhbW9zIHF1ZSBlbCBjb21wb3J0YW1pZW50byBkZSBsb3MgY2Fzb3MgZGUgaW5mZWN0YWRvcyBzb24gZGlmZXJlbnRlcyBlbiBsYSBtYXlvcmlhIGEgbG9zIHF1ZSBpbmljaWFsbWVudGUgc2UgdGVuaWEgZW4gbG9zIHByaW1lcm9zIDE2IGTDrWFzLiBMYXMgY3VydmFzIHlhIGNvbWllbnphbiBhIGVzdGFiaWxpemFyc2VuIGVuIG90cm9zIHBhaXNlcyBjb21vIE5vcnVlZ2EsIFNlcmJpYSBlbnRyZSBvdHJvcy4gU2luIGVtYmFyZ28sIGVzdG8gbm9zIGRlYmUgZ2VuZXJhciB1bmEgYWxlcnRhIGluZGljYW5kb25vcyBxdWUgZGViZSBzZWd1aXIgYXBsYW5hbmRvIGxhIGN1cnZhLg0KDQojIERpc3RyaWJ1Y2nDs24gZGUgbnVldm9zIGNhc29zIGVuIENvbG9tYmlhDQoNCmBgYHtyICBjYXNvc19udWV2b3MsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpjb2xvbWJpYSA8LSBwYWlzZXMuZWplbXBsb3MyICU+JSAgZmlsdGVyKHBhaXNlcyA9PSAiQ29sb21iaWEiKSAlPiUgZHBseXI6OnNlbGVjdChmZWNoYXMsdmFsb3JlcykNCmNvbG9tYmlhIDwtIGNvbG9tYmlhICU+JSBmaWx0ZXIodmFsb3JlcyAhPTApDQppZihucm93KGNvbG9tYmlhKSA9PSBucm93KGRhdG9zKSl7DQogIGNvbG9tYmlhJHZhbG9yZXMgPC0gZGF0b3MkQ29sb21iaWENCn0gZWxzZXsNCiAgZGF0b3MgPC0gZGF0b3NbMTpucm93KGNvbG9tYmlhKSxdDQogIGNvbG9tYmlhJHZhbG9yZXMgPC0gZGF0b3MkQ29sb21iaWENCn0NCg0KeSA8LSBjKDEsZGlmZihjb2xvbWJpYVssMl0sMSkpIA0KDQp0aWVtcG8gPC0gMTpucm93KGNvbG9tYmlhKQ0KDQpjb2xvbWJpYSAlPiUgZ2dwbG90KGFlcyhmZWNoYXMseSkpICsgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsNCiAgc2NhbGVfeF9kYXRlKGJyZWFrcyA9IGNvbG9tYmlhJGZlY2hhcywgZGF0ZV9sYWJlbHMgPSAiJWIgJWQiLCBleHBhbmQgPSBjKDAsMCkpICsNCiAgI2dlb21fdGV4dF9yZXBlbChhZXMoZmVjaGFzLCB5LCBsYWJlbCA9IHkpLCBzaXplPTIsIGhqdXN0PTAuNSkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT05MCxzaXplPTcsIHZqdXN0ID0gMC41KSkgKyB5bGFiKCJDYXNvcyBudWV2b3MiKSAjIGdyw6FmaWNhIGRlbCBuw7ptZXJvIGRlIGRpYXMgc2luIGFjdW11bGFyDQpgYGANCg0KU2Ugb2JzZXZhIHF1ZSBsb3MgY2Fzb3MgbnVldm9zIGxvcyBjYXNvcyBoYW4gdmVuaWRvIGVuIGF1bWVudG8gZGUgZm9ybWEgZGlhcmlhLCBzaW4gZW1iYXJnbywgc2UgaW50ZW50YSBpZGVudGlmaWNhciBxdWUgZGVzcHVlcyBkZSBjaWVydGFzIGZlY2hhcyBlbCBjYW1iaW8gZGUgY2Fzb3MgaW5mZWN0YWRvcyBlcyBtw6FzIGZ1ZXJ0ZSBxdWUgZW4gb3RyYXMgZmVjaGFzLCBwb3IgbG8gY3VhbCBzZSBpbnRlbnRhIGlkZW50aWZpY2FyIHF1ZSBmZWNoYXMgZWwgY2FtYmlvIGVzIG3DoXMgaW1wb3J0YW50ZS4NCmBgYHtyIGZlY2hhc19pbXBvcnRhbnRlcywgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmZpdCA8LSBycGFydDo6cnBhcnQoeX50aWVtcG8sIGNvbnRyb2wgPSBycGFydDo6cnBhcnQuY29udHJvbChjcCA9IC0xKSkNCiNycGFydDo6cGxvdGNwKGZpdCkNCiNycGFydDo6cHJpbnRjcChmaXQpDQpycGFydC5wbG90OjpycGFydC5wbG90KGZpdCx0eXBlID0gNSkNCnJwYXJ0LnBsb3Q6OnJwYXJ0LnJ1bGVzKGZpdCxzdHlsZSA9ICJ0YWxsIikNCmRpZmVyZW5jaWEgPC0gc29ydChyb3VuZChmaXQkc3BsaXRzWywiaW5kZXgiXSkpDQpgYGANCg0KTm90YW1vcyBxdWUgaGF5IGRvcyBmZWNoYXMgZW4gZWwgcXVlIGVsIHByb21lZGlvIGRlIGNhc29zIGNhbWJpYSBjb25zaWRlcmFibGVtZW50ZSwgYW50ZXMgZGUgbG9zIHByaW1lcm9zIDE2IGVsIHByb21lZGlvcyBkZSBjYXNvcyBlcmEgZGUgOC41LCBlbnRyZSBsb3MgcHJpbWVyb3MgMTYgYSBsb3MgMjQgZMOtYXMgZWwgcHJvbWVkaW8gYXVtZW50YSBhIDYwIGNhc29zIGRpYXJpb3MgeSBkZXNwdWVzIGRlIGxvcyAyNCBkw61hcyBlbCBwcm9tZWRpbyBlcyBkZSAxNDAgY2Fzb3MgZGlhcmlvcy4gRXN0YXMgZmVjaGFzIHNvbiBsYXMgc2lndWllbnRlcw0KYGBge3IgaWRlbnRpZmljYV9mZWNoYXNfaW1wb3J0YW50ZXMsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpmZWNoYXNfaW1wb3J0YW50ZXMgPC0gYyhjb2xvbWJpYSRmZWNoYXNbMV0sIGNvbG9tYmlhJGZlY2hhc1tkaWZlcmVuY2lhXSwgY29sb21iaWEkZmVjaGFzW2xlbmd0aChjb2xvbWJpYSRmZWNoYXMpXSkNCmZlY2hhc19pbXBvcnRhbnRlcw0KYGBgDQoNClJldmlzYW5kbyBsYXMgZGlmZXJlbmNpYXMgZmVjaGFzIHRlbmllbmRvIGVuIGN1ZW50YSBlbCBpbmljaW8gZGUgbGEgY3VhcmVudGVuYSBub3RhbW9zIHF1ZSBlbCBwcm9tZWRpbyBkZSBsYXMgZmVjaGFzIGltcG9ydGFudGVzIGFudGVyaW9yZXMgZXMgZGUgYHIgYXMubnVtZXJpYyhtZWFuKGRpZmYoZmVjaGFzX2ltcG9ydGFudGVzKSkpYCBwb3IgbG8gY3VhbCBzZSBwcm9wb25lIGNyZWFyIHVuYSB2YXJpYWJsZSBmYWN0b3IgcXVlIHRlbmdhIGVuIGN1ZW50YSBsb3MgY29ydGVzIGNhZGEgMTQgZGlhcywgYSBleGNlcGNpw7NuIGRlIGxvcyDDumx0aW1vcyBkaWFzIGxvcyBjdWFsZXMgc2UgcXVpZXJlbiBwcm9ub3N0aWNhci4gRXN0YSBpbmZvcm1hY2nDs24gc2UgdGllbmUgZW4gY3VlbnRhIHBhcmEgbWVqb3JhciBsYXMgcHJlZGljY2lvbmVzIGVuIGVsIG1vZGVsbyBxdWUgc2UgY29uc3RydXllIGEgY29udGludWFjacOzbi4NCg0KIyBDb25zdHJ1Y2Npw7NuIGRlbCBtb2RlbG8gcGFyYSBwcmVkZWNpciBlbCBuw7ptZXJvIGRlIGNhc29zIGFjdW11bGFkb3MgZGUgQ29yb25hdmlydXMgZW4gQ29sb21iaWENCg0KU2UgZGVzZWEgY29uc3RydWlyIHVuIG1vZGVsbyBxdWUgcGVybWl0YSBlc3RpbWFyIGVsIG7Dum1lcm8gZGUgY2Fzb3MgY29uZmlybWFkb3MgYWN1bXVsYWRvcy4gUGFyYSBlbGxvcyBzZSBjb25zdHJ1eWUgdW4gbW9kZWxvIHF1YXNpcG9pc3NvbiBlbCBxdWUgc2UgdGllbmUgZW4gY3VlbnRhIGVsIG7Dum1lcm8gZGUgY2Fzb3MgY29uZmlybWFkb3MgYWN1bXVsYWRvcyBjb21vIHZhcmlhYmxlIGRlcGVuZGllbnRlICh2YWxvcmVzKSB5IGNvbW8gdmFyaWFibGVzIGluZGVwZW5kaWVudGVzIHNlIHRpZW5lIGVuIGN1ZW50YSBsYXMgc2lndWllbnRlczoNCg0KKiBUaWVtcG8gcXVlIGhhIHRyYW5zY3VycmlkbyBkZXNwdWVzIGRlbCBwcmltZXIgY2FzbyAodGllbXBvKS4NCiogVmFyaWFibGUgZGUgY29ydGVzIGRlIGNhZGEgMTQgZMOtYXMgdGVuaWVuZG8gZW4gY3VlbnRhIGxhcyBmZWNoYXMgaW1wb3J0YW50ZXMgKGNvcnRlcykuDQoNClBhcmEgZGV0ZXJtaW5hciBxdWUgdGFuIGJ1ZW5vIGVzIGVsIG1vZGVsbyBzZSBleGNsdXllbiBsb3Mgw7psdGltb3MgNSBkYXRvcyBwYXJhIHRyYXRhciBkZSBwcmVkZWNpciBjb24gZWwgbW9kZWxvLg0KDQoNCmxvcyByZXN1bHRhZG9zIHNvbiBsb3Mgc2lndWllbnRlcw0KYGBge3IgY29ycmlkYV9tb2RlbG8sIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpjb2xvbWJpYSR5IDwtIHkNCiNjb2xvbWJpYSR5IDwtIGNvbG9tYmlhJHZhbG9yZXMNCmRpZmZfY29ydGVzIDwtIHJlcCgwOnRydW5jKGxlbmd0aChjb2xvbWJpYSR5KS8xNCksZWFjaD0xNCkNCmNvbG9tYmlhJGNvcnRlcyA8LSBkaWZmX2NvcnRlc1sxOmxlbmd0aChjb2xvbWJpYSR5KV0NCmNvbG9tYmlhJGNvcnRlcyA8LSBhcy5mYWN0b3IoY29sb21iaWEkY29ydGVzKQ0KY29sb21iaWFfdGVzdCA8LSBjb2xvbWJpYVsobi00KTpuLF0NCmNvbG9tYmlhIDwtIGNvbG9tYmlhWzE6KG4tNSksXQ0Kbml2ZWxlcyA8LSBsZXZlbHMoY29sb21iaWEkY29ydGVzKQ0KY29sb21iaWFfdGVzdCRjb3J0ZXMgPC0gcmVwbGFjZSgNCiAgY29sb21iaWFfdGVzdCRjb3J0ZXMsIGNvbG9tYmlhX3Rlc3QkY29ydGVzICE9IGFzLmNoYXJhY3Rlcih0YWlsKGNvbG9tYmlhLDEpJGNvcnRlcyksDQogIGFzLmNoYXJhY3Rlcih0YWlsKGNvbG9tYmlhLDEpJGNvcnRlcykpDQpjb2xvbWJpYV90ZXN0JGNvcnRlcyA8LSBmYWN0b3IoY29sb21iaWFfdGVzdCRjb3J0ZXMsbGV2ZWxzID0gbml2ZWxlcykNCmNvbG9tYmlhJHRpZW1wbyA8LSAxOm5yb3coY29sb21iaWEpDQoNCm1vZGVsbyA8LSBnbG0odmFsb3JlcyB+IHRpZW1wbyArIGNvcnRlcywgY29sb21iaWEsZmFtaWx5ID0gcXVhc2lwb2lzc29uKGxpbmsgPSAibG9nIikpDQojbW9kZWxvIDwtIE1BU1M6OmdsbS5uYih2YWxvcmVzIH4gdGllbXBvICsgY29ydGVzLCBjb2xvbWJpYSkNCnN1bW1hcnkobW9kZWxvKQ0KYW5vdmEobW9kZWxvLHRlc3QgPSAiQ2hpc3EiKQ0KYGBgDQoNClNlZ8O6biBsb3MgcmVzdWx0YWRvcyBsYSB2YXJpYWJsZSBwbGFudGVhZGFzIHNvbiBzaWduaWZpY2F0aXZhcywgcG9yIGxvIHF1ZSBzZSB1dGlsaXphbiBwYXJhIHJlYWxpemFyIGxhcyBlc3RpbWFjaW9uZXMuDQoNCiMjIEVzdGltYWNpw7NuIGxhIHRhc2EgZGUgY29udGFnaW8gcG9yIGTDrWENCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQplc3QgPC0gY2JpbmQoRXN0aW1hdGUgPSBjb2VmKG1vZGVsbyksIGNvbmZpbnQobW9kZWxvKSkNCmV4cChlc3RbMixdKQ0KYGBgDQpTZWfDum4gZWwgdmFsb3IgYW50ZXJpb3IsIHRlbmVtb3MgcXVlIGxhIHRhc2EgZGUgY29udGFnaW8gZXMgZGVsIGByIGV4cChlc3RbMiwxXSlgLiBQb3IgbG8gcXVlIHBvciBjYWRhIGTDrWEgcXVlIHBhc2EgZWwgdGllbXBvIGxhIHRhc2EgZGUgaW5mZWNjacOzbiBhdW1lbnRhIGVuIHVuIGByIHJvdW5kKGV4cChlc3RbMiwxXSktMSwzKSoxMDBgJSwgY29uIGludGVydmFsbyBlbnRyZSBlbCBgciByb3VuZChleHAoZXN0WzIsMl0pLTEsMykqMTAwYCUgeSBgciByb3VuZChleHAoZXN0WzIsM10pLTEsMykqMTAwYCUuDQoNCiMjIEFqdXN0ZSBkZWwgbW9kZWxvDQoNClNlIGRldGVybWluYSBxdWUgdGFuIGJ1ZW5vIGVzIGVsIGFqdXN0ZSBkZWwgbW9kZWxvLiBDYWxjdWxhbmRvIGxhIGZ1bmNpw7NuIGVudmVsb3BlIHBhcmEgZGV0ZXJtaW5hciBxdWUgdGFuIGJ1ZW5vIHNlIGFqdXN0YSBlbCBtb2RlbG8uDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KIyBSZXZpc2FuZG8gcXVlIHRhbiBidWVubyBlcyBlbCBtb2RlbG8gIyMjIw0KaG5wOjpobnAobW9kZWxvKQ0KI3NvdXJjZSgnaHR0cDovL3d3dy5wb2xldG8uY29tL2Z1bmNvZXMvZW52ZWwubmIudHh0JykNCiNlbnZlbC5uYihtb2RlbG8sY29uZj0wLjk1KQ0KYGBgDQoNCk9ic2VydmFuZG8gZWwgbW9kZWxvLCBxdWUgYWxndW5vcyBkYXRvcyBubyBzZSBhanVzdGFuIGJpZW4uIEVzdG8gc2UgZGViZSBhIGxhcyBvYnNlcnZhY2lvbmVzIGluaWNpYWxlcy4gUGFyYSBlbCByZXN0byBkZSBsYXMgb2JzZXJ2YWNpb25lcyBub3RhbW9zIHF1ZSBlbCBhanVzdGUgZXMgYnVlbm8sIHlhIHF1ZSBsYSBtYXlvcsOtYSBkZSBsb3MgcmVzaWR1YWxlcyBzZSBlbmN1ZW50cmEgZGVudHJvIGRlIGxvcyBsw61taXRlcyBkZSBsYSBncsOhZmljYSBlbnZlbG9wZS4NCg0KIyMgUHJlZGljY2lvbmVzIGRlbCBtb2RlbG8NCg0KUmVhbGl6YW5kbyBsYXMgcHJlZGljY2lvbmVzIHJlc3BlY3RpdmFzIHBhcmEgZGV0ZXJtaW5hciBlbCBuw7ptZXJvIGRlIGNhc29zIGFjdW11bGFkb3MgZW5jb250cmFtb3MgcXVlIGxhcyBwcmVkaWNjaW9uZXMgc29uIGJ1ZW5hcy4gTG9zIHZhbG9yZXMgcXVlIHNlIHNlIGVuY3VlbnRyYW4gcG9yIGVuY2ltYSBkZSBsYSBsaW5lYSB2ZXJ0aWNhbCwgc29uIHZhbG9yZXMgcXVlIHNlIGVzdMOhbiBwcmVkaWNpZW5kby4NCg0KYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnRpZW1wbzIgPC0gMToobnJvdyhjb2xvbWJpYSkrbnJvdyhjb2xvbWJpYV90ZXN0KSs1KQ0KY29ydGVzMiA8LSANCiAgYyhhcy5udW1lcmljKGxldmVscyhjb2xvbWJpYSRjb3J0ZXMpKVtjb2xvbWJpYSRjb3J0ZXNdLA0KICAgIGFzLm51bWVyaWMobGV2ZWxzKGNvbG9tYmlhX3Rlc3QkY29ydGVzKSlbY29sb21iaWFfdGVzdCRjb3J0ZXNdLA0KICAgIGFzLm51bWVyaWMobGV2ZWxzKGNvbG9tYmlhX3Rlc3QkY29ydGVzKSlbY29sb21iaWFfdGVzdCRjb3J0ZXNdKQ0KY29ydGVzMiA8LSBmYWN0b3IoY29ydGVzMiwgbGV2ZWxzID0gbGV2ZWxzKGNvbG9tYmlhJGNvcnRlcykpDQogICAgICAgICAgICAgICAgICAgICAgIA0KDQojIENvbnN0cnV5ZW5kbyBwcmVkaWNjaW9uZXMgIyMjIw0KY29sb21iaWFfcHJlZGljdGl2ZSA8LSBhZGRfY2koZGF0YS5mcmFtZSh0aWVtcG8gPSB0aWVtcG8yLCBjb3J0ZXMgPSBjb3J0ZXMyKSxmaXQgPSBtb2RlbG8sIGFscGhhID0gMC4wNSwgbmFtZXMgPSBjKCJsb3dlciIsICJ1cHBlciIpKQ0KDQojIFBlZ2FuZG8gYmFzZXMgIyMjIw0KY29sb21iaWEgPC0gY29sb21iaWEgJT4lIGZ1bGxfam9pbihjb2xvbWJpYV9wcmVkaWN0aXZlKQ0KY29sb21iaWFbYXMubnVtZXJpYyhyb3cubmFtZXMoY29sb21iaWFfdGVzdCkpLGMoImZlY2hhcyIsICJ2YWxvcmVzIiwgInkiLCAiY29ydGVzIildIDwtIGNvbG9tYmlhX3Rlc3QNCg0KDQojY29sb21iaWEkcHJlZF9jdW0gPC0gY3Vtc3VtKGNvbG9tYmlhJHByZWQpDQojY29sb21iaWEkbG93ZXJfY3VtIDwtIGN1bXN1bShjb2xvbWJpYSRsb3dlcikNCiNjb2xvbWJpYSR1cHBlcl9jdW0gPC0gY3Vtc3VtKGNvbG9tYmlhJHVwcGVyKQ0KDQpjb2xvbWJpYSRwcmVkX2N1bSA8LSBjb2xvbWJpYSRwcmVkDQpjb2xvbWJpYSRsb3dlcl9jdW0gPC0gY29sb21iaWEkbG93ZXINCmNvbG9tYmlhJHVwcGVyX2N1bSA8LSBjb2xvbWJpYSR1cHBlcg0KDQojIFByZWRpY2Npw7NuIDUgZMOtYXMgIyMjIw0KY29sb21iaWEgJT4lIGdncGxvdChhZXMoeCA9IHRpZW1wbykpICsgZ2VvbV9saW5lKGFlcyh5ID0gcHJlZF9jdW0pKSArIGdlb21fbGluZShhZXMoeSA9IGxvd2VyX2N1bSxjb2xvdXIgPSAiUmVkIikpICsNCiAgZ2VvbV9saW5lKGFlcyh5ID0gdXBwZXJfY3VtLGNvbG91ciA9ICJSZWQiKSkgKyBnZW9tX3BvaW50KGFlcyh5ID0gdmFsb3JlcykpICsNCiAgI2dlb21fdGV4dF9yZXBlbChhZXModGllbXBvLCB2YWxvcmVzLCBsYWJlbCA9IHZhbG9yZXMpLCBzaXplPTIsIGhqdXN0PTAuNSkgKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBucm93KGNvbG9tYmlhKS0xMCkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCBucm93KGNvbG9tYmlhKSksIGJyZWFrcyA9IHNlcSgwLCAzMDAsIGJ5ID0gMikpICsNCiAgdGhlbWVfY2xhc3NpYygpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIixheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT05MCxzaXplPTcsIHZqdXN0ID0gMC41KSkgKyB5bGFiKCJQcmVkaWNjaW9uZXMgZGUgY2Fzb3MiKQ0KYGBgDQoNCkVuIGxhIHNpZ3VpZW50ZSB0YWJsYSBzZSBwdWVkZSBvYnNlcnZhciBsYXMgcHJlZGljY2lvbmVzIChwcmVkX2N1bSkgbG9zIHZhbG9yZXMgZGVsIGludGVydmFsbyBhbCA5NSUgKGxvd2VyX2N1bSwgdXBwZXJfY3VtKSwgbG9zIHZhbG9yZXMgZGUgY29uZmlybWFkb3MgKHZhbG9yZXMpIHkgbGFzIGZlY2hhcyBhY3R1YWxlcy4NCg0KYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmNvbG9tYmlhICU+JSBzZWxlY3QoZmVjaGFzLHRpZW1wbywgIHksIHZhbG9yZXMsIGxvd2VyX2N1bSwgcHJlZF9jdW0sIHVwcGVyX2N1bSkNCmBgYA0KDQojIEVzdGltYWNpw7NuIGRlbCBuw7ptZXJvIGRlIGTDrWFzIHF1ZSBwdWVkZSBsbGVnYXIgZHVyYXIgbGEgY3VhcmVudGVuYSBlbiBDb2xvbWJpYQ0KDQpQYXJhIGVzdGltYXIgZWwgbsO6bWVybyBkZSBkw61hcywgc2UgdGllbmUgZW4gY3VlbnRhIGVsIG1vZGVsbyBTSVIgKFN1c2NlcHRpYmxlLUluZmVjdGFkby1SZWN1cGVyYWRvKSwgZXN0ZSBtb2RlbG8gY29uc2lzdGUgZW4gc29sdWNpb25hciB1biBzaXN0ZW1hIGRlIGVjdWFjaW9uZXMgZGlmZXJlbmNpYWxlcyBxdWUgcmVsYWNpb25hIGVsIG7Dum1lcm8gZGUgcGVyc29uYXMgc3VzY2VwdGlibGUgYSBzZXIgaW5mZWN0YWRhcyBkZSB1bmEgcG9ibGFjacOzbiwgZWwgbsO6bWVybyBkZSBwZXJzb25hcyBpbmZlY3RhZGFzIGVsIGN1YWwgeSBlbCBuw7ptZXJvIGRlIHBlcnNvbmFzIHJlY3VwZXJhZGFzLiBFbCBzaXN0ZW1hIGRlIGVjdWFjaW9uZXMgZWwgZWwgc2lndWllbnRlOg0KJCQNClxiZWdpbnthbGlnbip9DQpcZnJhY3tkU317ZHR9ICY9IC1cZnJhY3tcYmV0YSBJU317Tn1cXA0KXGZyYWN7ZEl9e2R0fSAmPSBcZnJhY3tcYmV0YSBJU317Tn0tXGdhbW1hIElcXA0KXGZyYWN7ZFJ9e2R0fSAmPSBcZ2FtbWEgSVxcDQpcZW5ke2FsaWduKn0NCiQkDQpEb25kZSAkXGJldGEkIGVzIGVsIHBhcsOhbWV0cm8gZGUgcXVlIGNvbnRyb2xhIGxhIHRyYW5zaWNpw7NuIGRlIGVudHJlIGxvcyBzdWNlcHRpYmxlcyAoUykgZSBpbmZlY3RhZG9zIChJKSB5ICRcZ2FtbWEkIHF1ZSBjb250cm9sYSBsYSB0cmFuc2ljacOzbiBlbnRyZSBsb3MgaW5mZWN0YWRvcyAoSSkgeSByZWN1cGVyYWRvcyAoUikuDQoNClBhcmEgcmVhbGl6YXIgbGEgZXN0aW1hY2nDs24gZW4gZWwgY2FzbyBjb2xvbWJpYW5vLCBzZSB0aWVuZSBlbiBjdWVudGEgbGEgaW5mb3JtYWNpw7NuIHRvbWFkYSBlbiBlbCBibG9nIGRlIExlYXJuaW5nIE1hY2hpbmVzIChodHRwczovL2Jsb2cuZXBob3JpZS5kZS9lcGlkZW1pb2xvZ3ktaG93LWNvbnRhZ2lvdXMtaXMtbm92ZWwtY29yb25hdmlydXMtMjAxOS1uY292KS4NCg0KYGBge3IgbGVjdHVyYTIsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQpjb2xvbWJpYSA8LSBOVUxMDQpjb2xvbWJpYSRmZWNoYXMgPC0gZGIuY29sb21iaWEkRkVDSEFfQUNUVUFMSVpBQ0lPTg0KY29sb21iaWEkaW5mZWN0YWRvcyA8LSBkYi5jb2xvbWJpYSRUT1RBTF9DQVNPUw0KY29sb21iaWEkbXVlcnRlcyA8LSBkYi5jb2xvbWJpYSRUT1RBTF9NVUVSVEVTDQpjb2xvbWJpYSRyZWN1cGVyYWRvcyA8LSBkYi5jb2xvbWJpYSRUT1RBTF9SRUNVUEVSQURPUw0KY29sb21iaWEgPC0gZGF0YS5mcmFtZShjb2xvbWJpYSkNCmBgYA0KDQpMYSBiYXNlIHBhcmEgQ29sb21iaWEgc2UgZGVjYXJnYSBkZSAoaHR0cHM6Ly9naXRodWIuY29tL0NTU0VHSVNhbmREYXRhL0NPVklELTE5KSB5IGVzIGxhIHNpZ3VpZW50ZToNCmBgYHtyIGVjaG89RkFMU0V9DQpjb2xvbWJpYQ0KYGBgDQoNCiMjIFNpbXVsYWNpw7NuIHBhcmEgQ29sb21iaWEgcGFyYSBsb3MgcHJpbWVyb3MgMTYgZGlhcw0KDQpQYXJhIG51ZXN0cm8gY2FzbyB0ZW5lbW9zIHVuYSBwb2JsYWNpw7NuIGRlIHBlcnNvbmFzIGRlIDUwMzcyNDI0IHNlZ8O6biBlbCBEQU5FLiBMYXMgc2ltdWxhY2lvbmVzIHNlIHJlYWxpemFyYW4gY29uIGxvcyBwcmltZXJvcyAxNiBkaWFzIHRlbmllbmRvIGVuIGN1ZW50YSBxdWUgZnVlIGN1YW5kbyBjb21lbnpvIGxhIGN1YXJlbnRlbmEuIFRlbmdhIHByZXNlbnRlIHF1ZSBlc3RhIGVzIHVuYSBzaW11bGFjacOzbiBkZSBsb3MgcmVzdWx0YWRvcy4NCg0KQSBjb250aW51YWNpw7NuIHNlIHRpZW5lIGxvcyB2YWxvcmVzIGRlICRcYmV0YSQgeSAkXGdhbW1hJC4NCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpjb2xvbWJpYTEgPC0gY29sb21iaWENCmNvbG9tYmlhIDwtIGNvbG9tYmlhWzE6MTYsXQ0KbGlicmFyeShkZVNvbHZlKQ0KDQpjb2xvbWJpYSRkaWFzIDwtIDE6bnJvdyhjb2xvbWJpYSkNCk4gPC0gNTAzNzI0MjQqMC44ICMgcG9ibGFjacOzbiBkZWwgREFORSBlbiBDb2xvbWJpYQ0KDQpJbmZlY3RlZCA8LSBjb2xvbWJpYSRpbmZlY3RhZG8NCg0KUiA8LSBjb2xvbWJpYSRyZWN1cGVyYWRvcw0KRGF5IDwtIGNvbG9tYmlhJGRpYXMNCg0KIw0KIyBPREUgZXF1YXRpb24gdXNlZCBmb3IgZml0dGluZw0KIw0KU0lSIDwtIGZ1bmN0aW9uKHRpbWUsIHN0YXRlLCBwYXJhbWV0ZXJzKSB7DQogIHBhciA8LSBhcy5saXN0KGMoc3RhdGUsIHBhcmFtZXRlcnMpKQ0KICB3aXRoKHBhciwgew0KICAgIGRTIDwtIC1iZXRhL04gKiBJICogUw0KICAgIGRJIDwtIGJldGEvTiAqIEkgKiBTIC0gZ2FtbWEgKiBJDQogICAgZFIgPC0gZ2FtbWEgKiBJDQogICAgbGlzdChjKGRTLCBkSSwgZFIpKQ0KICB9KQ0KfQ0KDQojDQojIGNvc3QgZnVuY3Rpb24gdG8gYmUgb3B0aW1pemVkIGluIHRoZSBmaXR0aW5nDQojDQpSU1MgPC0gZnVuY3Rpb24ocGFyYW1ldGVycykgew0KICBuYW1lcyhwYXJhbWV0ZXJzKSA8LSBjKCJiZXRhIiwgImdhbW1hIikNCiAgb3V0IDwtIG9kZSh5ID0gaW5pdCwgdGltZXMgPSBEYXksIGZ1bmMgPSBTSVIsIHBhcm1zID0gcGFyYW1ldGVycykNCiAgZml0SW5mZWN0ZWQgPC0gb3V0WywzXQ0KICBzdW0oKEluZmVjdGVkIC0gZml0SW5mZWN0ZWQpXjIpDQp9DQoNCiMgc3RhcnRpbmcgY29uZGl0aW9uDQppbml0IDwtIGMoUyA9IE4tSW5mZWN0ZWRbMV0sIEkgPSBJbmZlY3RlZFsxXSwgUiA9IFJbMV0pDQojaW5pdCA8LSBjKFMgPSBOLUluZmVjdGVkWzFdLCBJID0gSW5mZWN0ZWRbMV0tUlsxXS1EWzFdKSAgdXNlIHRoaXMgc3RhcnRpbmcgY29uZGl0aW9uIHdoZW4gYXBwbHlpbmcgdGhlIGRpZmZlcmVudCBsaW5lIGluIHRoZSBSU1MgZnVuY3Rpb24NCg0KIyBwZXJmb3JtaW5nIHRoZSBmaXQNCk9wdCA8LSBvcHRpbShjKDAuNSwgMC41KSwgUlNTLCBtZXRob2QgPSAiTC1CRkdTLUIiLCBsb3dlciA9IGMoMCwgMCksIHVwcGVyID0gYygxLCAxKSkgIyBvcHRpbWl6ZSB3aXRoIHNvbWUgc2Vuc2libGUgY29uZGl0aW9ucw0KDQpPcHRfcGFyIDwtIHNldE5hbWVzKE9wdCRwYXIsIGMoImJldGEiLCAiZ2FtbWEiKSkNCk9wdF9wYXINCmBgYA0KDQojIyBFc3RpbWFjacOzbiBkZSAkUl8wJA0KDQpBbGdvIGltcG9ydGFudGUgYSB0ZW5lciBlbiBjdWVudGEgZXMgZWwgJFJfMCQsIHF1ZSBlcyBsYSB0YXNhIGRlIGNvbnRhZ2lvIHBvciBjYWRhIHBlcnNvbmEgaW5mZWN0YWRhLiBFc3RlIGNhbGN1bG8gc2UgcmVhbGl6YSBkaXZpZGllbmRvICRcYmV0YSQgc29icmUgJFxnYW1tYSQgYWwgcmVhbGl6YXIgZXN0byBzZSB0aWVuZSBsbyBzaWd1aWVudGU6DQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KUjAgPC0gc2V0TmFtZXMoT3B0X3BhclsiYmV0YSJdIC8gT3B0X3BhclsiZ2FtbWEiXSwgIlIwIikNClIwDQpgYGANClNlZ8O6biBlbCByZXN1bHRhZG8gYW50ZXJpb3IsIHBvciBjYWRhIHBlcnNvbmEgaW5mZWN0YWRhLCBlc3TDoSBlc3RhIGVuIGxhIGNhcGFjaWRhZCBkZSBpbmZlY3RhciBgciByb3VuZChSMCwyKWAgcGVyc29uYXMuDQoNCkEgY29udGludWFjacOzbiBzZSBjYWxjdWxhIGVsIG7Dum1lciBkZSBkw61hcyBxdWUgc2UgcHVlZGVuIGRhciBwYXJhIGFsY2FuemFyIGVsIG3DoXhpbW8gbsO6bWVybyBkZSBwZXJzb25hcyBpbmZlY3RhZGFzIGRlc2RlIHF1ZSBzZSBkaW8gZWwgcHJpbWVyIGNvbnRhZ2lvIHF1ZSBmdWUgZWwgZMOtYSBgciBjb2xvbWJpYSRmZWNoYXNbMV1gLg0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KdCA8LSAxOjEwMCAjIHRpbWUgaW4gZGF5cw0KZml0IDwtIGRhdGEuZnJhbWUob2RlKHkgPSBpbml0LCB0aW1lcyA9IHQsIGZ1bmMgPSBTSVIsIHBhcm1zID0gT3B0X3BhcikpDQoNCm1heGltbyA8LSBmaXRbZml0JEkgPT0gbWF4KGZpdCRJKSwgIkkiLCBkcm9wID0gRkFMU0VdICMgaGVpZ2h0IG9mIHBhbmRlbWljDQpkaWFzX21heCA8LSBhcy5udW1lcmljKHJvdy5uYW1lcyhtYXhpbW8pKQ0KZGlhc19tYXgNCmBgYA0KDQpBbCBkw61hIGRlIGhveSBgciBTeXMuRGF0ZSgpYCwgc2UgdGllbmVuIGByIG5yb3coY29sb21iaWExKWAgcG9yIGxvIHF1ZSB5YSBoYW4gcGFzYWRvIGByIG5yb3coY29sb21iaWExKSAtIGRpYXNfbWF4YCBkw61hcy4NCg0KU2Vnw7puIGxhcyBzaW11bGFjaW9uZXMgZWwgdG90YWwgZGUgaW5mZWN0YWRvcyBzZXLDrWEgZGUNCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpuX21heCA8LSBhcy5udW1lcmljKG1heGltbykNCm5fbWF4DQpgYGANCg0KDQojIyBHcsOhZmljbyBkZWwgY29tcG9ydGFtaWVudG8gDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZ3JhcGgxMSA8LSBmaXQgJT4lIGdhdGhlcihrZXksIHZhbHVlLCAtdGltZSkNCg0KZ3JhcGgxMSAlPiUgZ2dwbG90KG1hcHBpbmcgPSBhZXMoeCA9IHRpbWUsIHkgPSB2YWx1ZSwgY29sb3IgPSBrZXkpICkgKyBnZW9tX2xpbmUoc2l6ZSA9MS4yNSkgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwoIHZhbHVlcyA9ICBjKCJyZWQxIiwgImdyZWVuMyIsImdyYXkxIikpICsNCiAgdGhlbWUoDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGZhY2UgPSAiYm9sZCIsaGp1c3QgPSAwLjUpLA0KICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgZmFjZSA9ICJpdGFsaWMiKSwNCiAgICBsZWdlbmQucG9zaXRpb249InRvcCIsDQogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGxlZ2VuZC5ib3ggPSAiaG9yaXpvbnRhbCIgLA0KICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTguNSksDQogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwgDQogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJncmF5NTAiLCBzaXplID0gMC41KSwNCiAgICBwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBsaW5lID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MubGVuZ3RoID0gdW5pdCguMTUsICJjbSIpLA0KICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemU9MTIpLA0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplPTEwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNlPSJpdGFsaWMiKSkrDQogICAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCksDQogICAgICAgICAgICAgICAgICAgICBsaW1pdHM9YygwLjAsNTAwMDAwMDApLA0KICAgICAgICAgICAgICAgICAgICAgYnJlYWtzPXNlcSgwLjAsNTAwMDAwMDAsMTAwMDAwMDApLCANCiAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiTsO6bWVybyBkZSBjYXNvcyIpKw0KICANCiAgc2NhbGVfeF9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCksDQogICAgICAgICAgICAgICAgICAgICBuYW1lID0gIlRpZW1wbyIpKw0KICANCiAgbGFicyh0aXRsZSA9ICJTSVIgTW9kZWwgMjAxOS1uQ292IENvbG9tYmlhIikNCmBgYA0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZ3JhcGgxMSAlPiUgZmlsdGVyKGtleSA9PSAiSSIpICU+JSBnZ3Bsb3QobWFwcGluZyA9IGFlcyh4ID0gdGltZSwgeSA9IHZhbHVlKSApICsgZ2VvbV9saW5lKHNpemUgPTEuMjUsY29sID0gInJlZDEiKSArDQogIGdlb21fcG9pbnQoZGF0YS5mcmFtZShEYXksSW5mZWN0ZWQpLG1hcHBpbmcgPSBhZXMoeCA9IERheSx5ID0gSW5mZWN0ZWQpKSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGRpYXNfbWF4KSArIA0KICB0aGVtZSgNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgZmFjZSA9ICJib2xkIixoanVzdCA9IDAuNSksDQogICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBmYWNlID0gIml0YWxpYyIpLA0KICAgIGxlZ2VuZC5wb3NpdGlvbj0idG9wIiwNCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksDQogICAgbGVnZW5kLmJveCA9ICJob3Jpem9udGFsIiAsDQogICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9OC41KSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLCANCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGNvbG9yID0gImdyYXk1MCIsIHNpemUgPSAwLjUpLA0KICAgIHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGxpbmUgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aWNrcy5sZW5ndGggPSB1bml0KC4xNSwgImNtIiksDQogICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZT0xMiksDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemU9MTAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY2U9Iml0YWxpYyIpKSsNCiAgc2NhbGVfeF9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCksDQogICAgICAgICAgICAgICAgICAgICBuYW1lID0gIlRpZW1wbyIsDQogICAgICAgICAgICAgICAgICAgICBicmVha3M9c2VxKDAsMTAwLDUpKSsNCiAgc2NhbGVfeV9sb2cxMChuYW1lID0gIk7Dum1lcm8gZGUgY2Fzb3MiKSArDQogIGxhYnModGl0bGUgPSAiU0lSIE1vZGVsIDIwMTktbkNvdiBDb2xvbWJpYSIpDQpgYGANCg0KIyMgU2ltdWxhY2nDs24gcGFyYSBDb2xvbWJpYSBhIGxhIGZlY2hhDQoNCkEgY29udGludWFjacOzbiBzZSBhY3R1YWxpemEgbGEgaW5mb3JtYWNpw7NuIGEgZGlhIGRlIGhveS4gVGVuZ2Ftb3MgcHJlc2VudGUgcXVlIGxvcyBkYXRvcyBoYW4gY2FtYmlhZG8gZGViaWRvIGEgbGFzIGRpZmVyZW50ZXMgaW50ZXJ2ZW5jaW9uZXMgcXVlIHJlYWxpesOzIGVsIGdvYmllcm5vIGRlIENvbG9tYmlhLg0KDQpBIGNvbnRpbnVhY2nDs24gbG9zIG51ZXZvcyB2YWxvcmVzIGRlICRcYmV0YSQgeSAkXGdhbW1hJCBzb24gbG9zIHNpZ3VpZW50ZXM6Lg0KYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmNvbG9tYmlhIDwtIGNvbG9tYmlhMQ0KY29sb21iaWEkZGlhcyA8LSAxOm5yb3coY29sb21iaWEpDQoNCkluZmVjdGVkIDwtIGNvbG9tYmlhJGluZmVjdGFkbw0KDQpSIDwtIGNvbG9tYmlhJHJlY3VwZXJhZG9zDQpEYXkgPC0gY29sb21iaWEkZGlhcw0KDQojDQojIE9ERSBlcXVhdGlvbiB1c2VkIGZvciBmaXR0aW5nDQojDQpTSVIgPC0gZnVuY3Rpb24odGltZSwgc3RhdGUsIHBhcmFtZXRlcnMpIHsNCiAgcGFyIDwtIGFzLmxpc3QoYyhzdGF0ZSwgcGFyYW1ldGVycykpDQogIHdpdGgocGFyLCB7DQogICAgZFMgPC0gLWJldGEvTiAqIEkgKiBTDQogICAgZEkgPC0gYmV0YS9OICogSSAqIFMgLSBnYW1tYSAqIEkNCiAgICBkUiA8LSBnYW1tYSAqIEkNCiAgICBsaXN0KGMoZFMsIGRJLCBkUikpDQogIH0pDQp9DQoNCiMNCiMgY29zdCBmdW5jdGlvbiB0byBiZSBvcHRpbWl6ZWQgaW4gdGhlIGZpdHRpbmcNCiMNClJTUyA8LSBmdW5jdGlvbihwYXJhbWV0ZXJzKSB7DQogIG5hbWVzKHBhcmFtZXRlcnMpIDwtIGMoImJldGEiLCAiZ2FtbWEiKQ0KICBvdXQgPC0gb2RlKHkgPSBpbml0LCB0aW1lcyA9IERheSwgZnVuYyA9IFNJUiwgcGFybXMgPSBwYXJhbWV0ZXJzKQ0KICBmaXRJbmZlY3RlZCA8LSBvdXRbLDNdDQogIHN1bSgoSW5mZWN0ZWQgLSBmaXRJbmZlY3RlZCleMikNCn0NCg0KIyBzdGFydGluZyBjb25kaXRpb24NCmluaXQgPC0gYyhTID0gTi1JbmZlY3RlZFsxXSwgSSA9IEluZmVjdGVkWzFdLCBSID0gUlsxXSkNCiNpbml0IDwtIGMoUyA9IE4tSW5mZWN0ZWRbMV0sIEkgPSBJbmZlY3RlZFsxXS1SWzFdLURbMV0pICB1c2UgdGhpcyBzdGFydGluZyBjb25kaXRpb24gd2hlbiBhcHBseWluZyB0aGUgZGlmZmVyZW50IGxpbmUgaW4gdGhlIFJTUyBmdW5jdGlvbg0KDQojIHBlcmZvcm1pbmcgdGhlIGZpdA0KT3B0IDwtIG9wdGltKGMoMC41LCAwLjUpLCBSU1MsIG1ldGhvZCA9ICJMLUJGR1MtQiIsIGxvd2VyID0gYygwLCAwKSwgdXBwZXIgPSBjKDEsIDEpKSAjIG9wdGltaXplIHdpdGggc29tZSBzZW5zaWJsZSBjb25kaXRpb25zDQoNCk9wdF9wYXJfbmV3IDwtIHNldE5hbWVzKE9wdCRwYXIsIGMoImJldGEiLCAiZ2FtbWEiKSkNCk9wdF9wYXJfbmV3DQpgYGANCg0KTGEgbnVldmEgZXN0aW1hY2nDs24gZGUgJFJfMCQgZXMgbGEgc2lndWllbnRlOg0KYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NClIwX25ldyA8LSBzZXROYW1lcyhPcHRfcGFyX25ld1siYmV0YSJdIC8gT3B0X3Bhcl9uZXdbImdhbW1hIl0sICJSMCIpDQpSMF9uZXcNCmBgYA0KU2Vnw7puIGVsIHJlc3VsdGFkbyBhbnRlcmlvciwgcG9yIGNhZGEgcGVyc29uYSBpbmZlY3RhZGEsIGVzdMOhIGVzdGEgZW4gbGEgY2FwYWNpZGFkIGRlIGluZmVjdGFyIGByIHJvdW5kKFIwX25ldywyKWAgcGVyc29uYXMuIExvIHF1ZSBpbmRpY2EgcXVlIGxhcyBtZWRpZGFzIHRvbWFkYXMgZGUgbGEgY3VhcmVudGVuYSBzaSBoYW4gZnVuY2lvbmFkbw0KDQpFbCBuw7ptZXJvIGRlIGRpYXMgcGFyYSBsbGVnYXIgYWwgbcOheGltbyBhIGxhIGZlY2hhIGRlIGhveSBlcyBkZToNCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQp0IDwtIDE6NjAwICMgdGltZSBpbiBkYXlzDQpmaXQgPC0gZGF0YS5mcmFtZShvZGUoeSA9IGluaXQsIHRpbWVzID0gdCwgZnVuYyA9IFNJUiwgcGFybXMgPSBPcHRfcGFyX25ldykpDQoNCm1heGltbyA8LSBmaXRbZml0JEkgPT0gbWF4KGZpdCRJKSwgIkkiLCBkcm9wID0gRkFMU0VdICMgaGVpZ2h0IG9mIHBhbmRlbWljDQpkaWFzX21heF9uZXcgPC0gYXMubnVtZXJpYyhyb3cubmFtZXMobWF4aW1vKSkNCmRpYXNfbWF4X25ldw0KYGBgDQoNClBvciBsbyBxdWUgZWwgbcOheGltbyBzZSBhbGNhbnphcsOtYSBhIGxvcyBgciBkaWFzX21heF9uZXdgIGRpYXMuIEEgZmVjaGEgZGUgaG95IGByIFN5cy5EYXRlKClgIGhhbiBwYXNhZG8gYHIgbnJvdyhjb2xvbWJpYSlgICBkw61hcyBwb3IgbG8gcXVlIHlhIGhlbW9zIGFsY2FuemFkbyBlbCBtw6F4aW1vIHNlZ8O6biBlbCBtb2RlbG8gYWp1c3RhZG8uDQo=