Email             : ElianElian@ciencias.unam.mx🦕

RPubs            : Mis publicaciones

Facultad        : Facultad de Ciencias

                                                                                            

Descripcion.

En este documento se presenta la metodología para realizar un análisis de una serie de tiempo usando la herramienta R, teniendo en cuenta los pasos a realizar y algunos conceptos limitados a dos modelos; ARIMA y SARIMA. Nuestro principal interes sera saber identificar el modelo de una serie de tiempo y ponerlo a prueba, despues, para tener fundamentado realizar una prediccion con el modelo.

                                                                                            


Teoria.

Propiedad Estacionaria (Debilmente Estacionaria).

Definicion.


Una serie de tiempo \(X_t\) se considera débilmente estacionaria o simplemente estacionaria si cumple con las siguientes propiedades:

  • La media \(E(X_t)\) es constante e igual para todos los períodos, es decir, \(E(X_t) = E(X_{t+k}) = \mu\).

  • La varianza \(\text{Var}(X_t)\) es constante e igual para todos los períodos, es decir, \(\text{Var}(X_t) = \text{Var}(X_{t+k}) = \sigma^2\).

  • La covarianza \(\text{Cov}(X_t,X_{t+k})\) entre dos períodos \(t\) y \(t+k\) depende únicamente de la distancia o rezago \(k\) entre ellos, es decir, \(\text{Cov}(X_t,X_{t+k}) = \gamma_k\).

Cuando una serie de tiempo es estacionaria, sus propiedades estadísticas no cambian con el tiempo, lo que simplifica el proceso de modelado y predicción. Los modelos ARIMA, asumen estacionariedad para su aplicación.

Estacionalidad.

Definicion.


Se dice de una serie de tiempo que es estacional cuando está influenciada por factores estacionales de periodo fijo en todo el tiempo; como el dia, mes, trimestre.

La estacionalidad es la repetición de determinadas variaciones en alguna variable cada cierto período, normalmente igual o menor a un año. En períodos más amplios se suele hablar de ciclos, aunque las variaciones cíclicas no son tan frecuentes como las estacionales. Por ejemplo, cada 2 años se celebra la bienal de Venecia, cada 4 años el mundial de fútbol y cada 76 años se observa el cometa Halley. - BBVA ¿Qué es y cómo nos afecta la estacionalidad?

ARIMA.

Definicion.


ARIMA, denominado como Auto-Regresivo Integrado de Media Movil por sus siglas y denotado como ARIMA(p,d,q), es la combinación de los modelos autorregresivo y el de medias móviles, con la particularidad de que debe incluir un proceso de restablecimiento (el cual se denomina integración I) de inestabilidad original presente en una serie de tiempo.

Polinomio:
\[\begin{equation*} (1 - \phi_1 B - \phi_2 B^2 - \ldots - \phi_p B^p) X_t (1 - B)^d = c + (1 + \theta_1 B + \theta_2 B^2 + \ldots + \theta_q B^q) Z_t \end{equation*}\]

                                                                                            

\[\begin{equation*} x_t' = \phi_1 x'_{t-1} + \ldots + \phi_p x'_{t-p} + Z_t - \theta Z_{t-1} - \ldots - \theta_q Z_{t-q} \end{equation*}\]

                                                                                            

\[\begin{equation*} AR(p)I(d) = MA(q) \end{equation*}\]

                                                                               

Donde:
  • \(B^d X_t = X_{t-d}\) es el operador de retrasi;

  • \((1 - B)^d X_t = \Delta^d X_t\) es el operador diferencia, denota la serie temporal diferenciada \(d\) veces;

  • y la \(X'_t\) denota la serie de tiempo inducida a la estabilidad o estacionariedad.


Desglose:
  • (AR) Parametro p. Autroregresion p

Auto Regressive Son modelos donde el valor de una variable en un periodo se relaciona con los valores de periodos previos. Se refiere a los lags p de las diferencias de los valores entre las series. Esta parte del modelo captura la relación lineal entre una observación y un número lineal de observaciones retrasadas (lagged observations). La notación AR(p) representa esta parte, donde “p” es el número de retrasos incluidos en el modelo.

Basicamente este parametro indica que tantos retrasos (lags p) tomamos en cuenta determinan el valor actual, es decir, p retrasos, p datos previos se relacionan con el valor actual.

  • (I) Parametro d. Diferenciacion d (Random Walk, etc. suma acumulativa de ruidos blancos (0,0,0))

Se refiere al orden del número diferencial que se usan para hacer las series de tiempo estacionarias.

Esta parte del modelo indica el número de diferenciaciones necesarias para volver estacionaria a la serie temporal, es decir, hacer que la media y la varianza sean constantes en el tiempo. La notación I(d) representa esta parte, donde “d” es el número de diferenciaciones.

  • (MA) Parametro q. Error de Regresion q

Consideran la posibilidad de una relación entre la variable y los residuales de periodos previos. Se refiere a los lags q de los errores. Tiene sentido el nombre de media movil ya que

Esta parte del modelo representa la relación lineal entre una observación y los errores residuales de predicciones pasadas en un número lineal de períodos de tiempo. La notación MA(q) representa esta parte, donde “q” es el número de términos de errores residuales incluidos en el modelo.

Basicamente es lo analogo al AR(p), solo que en este caso considera a los q errores o residuales (lags) de la regresion para definir una relacion en el periodo actual con los previos, es decir, q periodos previos de residuos tienen relacion con nuestro periodo actual.


Supuestos del ARIMA.
  • Los datos deben ser estacionarios, o si no, deben sufrir una transformacion (Box-Cox, log, raiz, 1/x, etc.): las propiedades de la serie no dependen del momento en que se capturan. Un proceso estacionario tiene una media y una variación que no cambian con el tiempo y no tiene una tendencia (media o pendiente cambiante).

  • Los datos deben ser univariados: ARIMA trabaja con una sola variable. La regresión automática tiene que ver con la regresión con los valores pasados.

  • Linealidad: Se asume que la relación entre las observaciones pasadas y presentes es lineal. Esto significa que las relaciones entre las variables en el modelo pueden ser representadas por una combinación lineal de los parámetros del modelo.

  • Independencia de los Errores: Se asume que los errores de predicción son independientes entre sí y no muestran autocorrelación significativa. En otras palabras, los residuos del modelo ARIMA deben comportarse como ruido blanco.

  • Normalidad de los Errores: Se asume que los errores de predicción siguen una distribución normal con una media de cero (Ruido blanco con media cero). Aunque este supuesto puede ser relajado en algunos casos, es útil para interpretar los intervalos de confianza y realizar pruebas estadísticas.

  • Homocedasticidad: Los errores de predicción deben tener una varianza constante a lo largo del tiempo. Esto significa que la dispersión de los errores no debe cambiar a medida que avanza la serie temporal.

    - Rojas Jimenez, K. 2022. Ciencia de Datos para Ciencias Naturales fragmentos del texto usados.

    - Ptolomeo UNAM, Modelacion ARIMA fragmentos del texto usados.

SARIMA.

Definicion.


El modelo SARIMA (Seasonal AutoRegressive Integrated Moving Average) es una extensión del modelo ARIMA que también tiene en cuenta la estacionalidad (Seasonal). La notación general para un modelo SARIMA es SARIMA(p, d, q) (P, D, Q) (s);

                                                                               

Donde:
  • \(p\): Orden del componente autoregresivo no estacional (AR).

  • \(d\): Orden de diferenciación no estacional, es decir, antes de ser estacional que orden de diferenciacion tenia, analogamente los demas.

  • \(q\): Orden del componente de media móvil no estacional (MA).

  • \(P\): Orden del componente autoregresivo estacional.

  • \(D\): Orden de diferenciación estacional.

  • \(Q\): Orden del componente de media móvil estacional.

  • \(s\): Longitud del período estacional.

Polinomio:

                                                                               

\[ (1 - \phi_1 B - \phi_2 B^2 - \ldots - \phi_p B^p)(1 - B)^d(1 - \Phi_1 B^s - \Phi_2 B^{2s} - \ldots - \Phi_P B^{Ps})(1 - B^s)^D X_t = c + (1 + \theta_1 B + \theta_2 B^2 + \ldots + \theta_q B^q)(1 + \Theta_1 B^s + \Theta_2 B^{2s} + \ldots + \Theta_Q B^{Qs})Z_t \]

                                                                               

Donde:
  • \(X_t\) es la serie temporal en el tiempo “t”.

  • \(B\) es el operador de retraso.

  • \(\phi_1, \phi_2, \ldots, \phi_p\) son los parámetros de autoregresión.

  • \(\Phi_1, \Phi_2, \ldots, \Phi_P\) son los parámetros de autoregresión estacionales.

  • \(\theta_1, \theta_2, \ldots, \theta_q\) son los parámetros de la parte de media móvil.

  • \(\Theta_1, \Theta_2, \ldots, \Theta_Q\) son los parámetros de la parte de media móvil estacional.

  • \(c\) es una constante.

  • \(Z_t\) es un ruido blanco. \end{itemize}


Supuestos del SARIMA:

Analogo a los supuestos del ARIMA.

  • Estacionariedad.

  • Linealidad.

  • Independencia de los errores.

  • Normalidad de los errores.

  • Homocedasticidad.

  • Estacionalidad: Verificacion de los ciclos, y que estos sean estacionales.

  • Estacionalidad estacionaria: El componente estacional del modelo SARIMA debe ser estacionario. Esto implica que la estacionalidad debe ser modelada adecuadamente y no debe haber patrones sistemáticos en los residuos estacionales.

Practica.

Metodologia.

La metodologia usada en este tipo de analisis, es la siguiente mostrada en un diagrama:

  1. Primero se identifica el modelo analizando la serie de tiempo a secas (lo que creemos que es, viendo sus ACF y PACF, etc).

  2. Despues estimas los parametros en consecuencia de tu analisis, antes de este paso, es recomendable primero verificar que en efecto tu serie de tiempo cumpla con los supuestos de tu modelo, asi que en este paso tambien veras que tu serie de tiempo cumpla con ser estacionaria, homocedastica, univariada, etc. En este paso tambien se pueden probar diversos modelos, modelos con outliers (valores atipicos) y modelos que no tengan, esto para poder ver de manera mas representativa sus diferencias; y para su descarte o aceptacion, se puede ver un analisis adicional opcional ademas de los supuestos; AIC y BIC. *Deben de ser los minimos de todos ambos*.

  3. Verificas los supuestos del modelo a traves de Pruebas Parametricas, verificas los mismos supuestos que se pretendian ver en la serie de tiempo a traves de un Analisis Residual, pero si es que no se cumplen, podemos optar por realizar tranformaciones o cambios a nuestro modelo o serie de tiempo.

  4. Al final de hacer todo lo anterior, despues se usa el modelo para predecir, esto junto a un analisis de lo que representan estas predicciones en el contexto dado (buenas predicciones para el tema). Si aun con esto las Predicciones no son adecuadas, eso quiere decir que debemos cambiar nuestro enfoque de modelo, y probar otras alternativas (Modelos de Suavizado Exponencial SE, GARCH, Redes Neuronales RNN, INAR, Espacio de Estados SSM, Change Point.)


Diagrama de Decision.
Diagrama de Decision.

Una especial mencion al analisis de los autocorrelogramas o correlogramas o grafico de correlacion de datos.

  • Si en una FACP las primeras p correlaciones son significativas (distintas de cero o muy por arriba de cero), muy probablemente hablemos de un AR(p) y en su ACF decae a cero.

  • Si en una ACF las primeras q correlaciones son significativas (distintas de cero o muy por arriba de cero), quizas se trate de un MA(q), y PACF decae a cero.

  • Si en la ACF se de una convergencia a cero como se dice en la grafica, quizas se trate de un ARMA(p,q)

  • Juntando estos datos, con el factor de diferenciacion I(d) para volver estacionaria a tu serie de tiempo, y el factor S de estacionalidad, se obtiene el SARIMA por completo.


Identificacion de Modelo
Identificacion de Modelo
Funciones de autocorrelación simple y parcial - Todo Econometria.

Supuestos.

Antes de modelar, solo tomaremos en cuenta el modelo SARIMA, primero debemos ver que la serie de tiempo original cumple con los supuestos SARIMA, es decir, cumple la Homocedasticidad, cumple la Estacionariedad, cumple con tener Ciclos Estacionales (Estacionalidad), y cumple con que su ruido blanco es gaussiano de media cero y sus errores son independientes (Normalidad e Independencia de los errores). Basicamente el supuesto de univariado, linealidad y multicolinealidad son menos explorados o se dan por hecho (triviales?).

Una vez la serie de tiempo cumple los supuestos en teoria, podemos modelarla estimando los parametros que deseemos (analizando que significa cada uno), y a este modelo SARIMA, le haremos pruebas parametricas, en general pruebas, para ver que tan robusto o aceptable es.


Pruebas de los Supuestos.

Ejemplo. Se cargaran datos, se aplicara un modelo y se le haran Pruebas, se analizara sus ACF y PACF y se hara un Analisis de Residuos.

ts_70 <- tsdl[[70]]
SARIMA <- auto.arima(ts_70, seasonal = TRUE) #, trace = TRUE si se quieren ver todos los modelos. 

Analisis de Residuos.

Primero hay que decir que se le puede ver a los residuos como los errores de la regresion, como los residuales precisamente o como el ruido blanco \(Z_t\) de la serie de tiempo/proceso \(X_t\).


ACF y PACF.

Primero vamos a interpretar los ACF y PACF.

El modelo anterior se dice que es un SARIMA (1,0,2)(2,1,0)[12], analizando sus ACF y PACF iniciales veremos de donde sale esto, vemos que el p no estacional nos indica que ciertamente en la PACF segun las bandas de confianza, el parametro p de lag igual a 1 es el significativo, q es algo mas incierto pero el ACF indica que ciertamente los primeros dos lags son considerablemente mas significativos que los demas dadas las bandas de confianza. Ahora para el analisis de las ACF y PACF residuales (las que nos interesan aqui), esperamos que la mayoria de las correlaciones se encuentren dentro de la banda de confianza para brindar un modelo fuerte, si hay diferencias muy grandes entre las correlaciones, podria indicar que el modelo no es lo suficientemente adecuado; Si los residuos parecen ser ruido blanco (es decir, no hay autocorrelación significativa). En este caso, es lo suficientemente aceptable.

acf(ts_70, main = "ACF de ts_70")

pacf(ts_70, main = "PACF de ts_70")

acf(residuals(SARIMA), main = "ACF residuales SARIMA")

pacf(residuals(SARIMA), main = "PACF residuales SARIMA")

Pruebas/Test de Supuestos.

Independencia.

Verificar si los residuos son mutuamente independientes: Utilizamos el estadístico Q de Ljung-Box para realizar una prueba conjunta sobre la significancia de las correlaciones de los residuos hasta un cierto lag. Si el valor p de la prueba es mayor que un nivel de significancia predefinido, entonces no hay evidencia suficiente para rechazar la hipótesis nula de que los residuos son independientes.

residuos <- residuals(SARIMA)
Box.test(residuos,lag = 20, type = "Ljung-Box")
## 
##  Box-Ljung test
## 
## data:  residuos
## X-squared = 18.132, df = 20, p-value = 0.5787

Aprobado.

No hay suficiente evidencia para rechazar la hipótesis nula de independencia de los residuos. Por lo tanto, según los resultados de la prueba de Box-Ljung, los residuos del modelo SARIMA parecen ser independientes en los primeros 20 rezagos/lags. Si NO cumple el supuesto, entonces, modificar parametros. Como persiste dependencia en los residuales, quiere decir que falto modelar dependencia en el modelo. Tambien se puede intentar agregando mas lags/rezagos, asi saldria mayor el p-value, pero ver hasta que punte es permisible.

Homocedasticidad.

Verificar si la varianza de los residuos es constante o no constante (heterocedasticidad): Se puede graficar los residuos contra el tiempo y observar si la dispersión de los residuos parece constante a lo largo del tiempo. O hacer pruebas, como la de Breusch-Pagan.

n <- length(residuos)
regresor <- 1:n
lmtest::bptest(residuos~regresor)
## 
##  studentized Breusch-Pagan test
## 
## data:  residuos ~ regresor
## BP = 1.1217, df = 1, p-value = 0.2895

Aprobado.

No hay suficiente evidencia para rechazar la hipótesis nula de homocedasticidad. Esto sugiere que la varianza de los residuos es constante a lo largo del tiempo, osease, sugiere que si se cumple homocedasticidad y rechazamos heterocedasticidad. Si NO se cumple entonces realizar una transformación Box-Cox, sobre la serie original.

Estacionariedad.

Verificar si los residuos cumplen la propiedad estacionaria: que la varianza sea constante, que la media constante, y que la correlacion solo dependa de la distancia del rezago/lag: Se considerara que si se cumple este supuesto entonces no hay presencia de tendencia/media/pendiente (es constante o se suele decir que es cero como la media del ruido blanco igual a cero).

Se pueden verificar que la media es constante a lo largo del tiempo, mediante el calculo de la media, la homocedasticidad se comprueba anteriormente y se puede probar la correlacion y la independencia de los errores para este supuesto, mediante los ACF y PACF; o se pueden hacer pruebas como Dickey-Fuller aumentada (ADF) o la prueba de Kwiatkowski-Phillips-Schmidt-Shin (KPSS). Estas pruebas evalúan si una serie temporal tiene raíces unitarias (ADF) o si la serie es estacionaria en tendencia (KPSS).

tseries::adf.test(residuos)
## 
##  Augmented Dickey-Fuller Test
## 
## data:  residuos
## Dickey-Fuller = -6.5685, Lag order = 7, p-value = 0.01
## alternative hypothesis: stationary
tseries::kpss.test(residuos)
## 
##  KPSS Test for Level Stationarity
## 
## data:  residuos
## KPSS Level = 0.056614, Truncation lag parameter = 5, p-value = 0.1

Aprobado.

Prueba de Dickey-Fuller Aumentada (ADF): segun el warning: p-value smaller than printed p-value; el valor-p obtenido es menor que 0.01. Esto indica que hay suficiente evidencia para rechazar la hipótesis nula de presencia de una raíz unitaria en los residuos, lo que sugiere que los residuos son estacionarios.

Prueba KPSS para Estacionariedad en Nivel (Level Stationarity): - segun el warning: p-value greater than printed p-value; el valor-p obtenido es mayor que 0.1. No hay suficiente evidencia para rechazar la hipótesis nula de estacionariedad en tendencia, lo que sugiere que los residuos son estacionarios.

Si NO se cumplen estos supuestos, se pueden hacer transformaciones a la serie original, haciendola estacionaria desde un principio, etc, aunque esto simplifica los modelos.

Normalidad.

Verificar si los residuos tienen distribución normal (gaussiana): Se puede graficar un qq-plot de los residuos con una línea diagonal para verificar si los residuos siguen una distribución normal visualmente, deben estar pegados a la linea, graficar su histograma y darse idea visual de sus frecuencias y si su densidad añadida al histograma parece ser normal; o se pueden hacer pruebas de normalidad de bondad de ajuste como shapiro de normalidad que tiene buena potencia o Anderson-Darling o Lilliefors.

shapiro.test(residuos)
## 
##  Shapiro-Wilk normality test
## 
## data:  residuos
## W = 0.82639, p-value < 2.2e-16
lillie.test(residuos)
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  residuos
## D = 0.14942, p-value < 2.2e-16
ad.test(residuos)
## 
##  Anderson-Darling normality test
## 
## data:  residuos
## A = 19.77, p-value < 2.2e-16

Reprobado.

En todas las pruebas, el valor-p obtenido es significativamente menor que cualquier nivel de significancia comúnmente utilizado (por ejemplo, 0.05). Por lo tanto, hay suficiente evidencia para rechazar la hipótesis nula de normalidad en todos los casos. Esto sugiere que los residuos no siguen una distribución normal y que hay desviaciones significativas de la normalidad.

En este caso, NO pasa la normalidad, asi que podemos hacer intervalos de predicción distintos a los de la distribución normal, los intervalos de predicción basados en la distribución normal pueden no ser apropiados en este caso. Algunas opciones para construir intervalos de predicción en presencia de residuos no normales son Bootstrap como metodo de remuestreo, o transformaciones para mejorar los residuos; por ejemplo podriamos ajustar transformaciones antes de modelar el SARIMA o en los residuos transformados con la funcion boxcox de la libreria MASS.

AIC y BIC.

Extra. Criterio de Información de Akaike (AIC) y el Criterio de Información Bayesiano (BIC): Trataremos de buscar el modelo que tenga los mas bajos de estos en conjunto, estos criterios, el primero penaliza menos la complejidad y el segundo lo hace mas.

Forecast.

Digamos que ya tenemos un modelo que cumple con todo, ahora sigue hacer predicciones, es decir usar el modelo, hay diferentes formas de predecir, pero en este caso usaremos las siguientes paqueterias.

pronostico<-forecast(SARIMA, h = 12)
plot(pronostico, main = "Pronóstico SARIMA", xlab = "Tiempo", ylab = "Valores")
legend("topright", legend = c("Pronóstico", "Area de confianza"), col = c("blue", "grey"), lty = 1:2)

LS0tDQp0aXRsZTogIk1ldG9kb2xvZ2lhIGRlIEFuYWxpc2lzIGRlIFNlcmllcyBkZSBUaWVtcG8iDQphdXRob3I6ICJFbGlhbiBHb256YWxleiBNYXJlcyINCmRhdGU6ICJgciBmb3JtYXQoU3lzLkRhdGUoKSwgJyVkIGRlICVCIGRlICVZJylgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZm9sZGluZzogc2hvdw0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZGVwdGg6IDUNCiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlDQogICAgY3NzOiBjaGlsbC5jc3MNCiAgICB0aGVtZToNCiAgICAgIGJnOiAnI0ZGRkZGRicNCiAgICAgIGZnOiAnIzAwMDAwMCcNCiAgICAgIHByaW1hcnk6ICcjQjE5Q0Q5Jw0KICAgICAgc2Vjb25kYXJ5OiAnIzkzNzBEQicNCiAgICBiYXNlX2ZvbnQ6DQogICAgICBnb29nbGU6IFByb21wdA0KICAgIGhlYWRpbmdfZm9udDoNCiAgICAgIA0KICAgICAgZ29vZ2xlOiBQcm96YSBMaWJyZQ0KICBwcmV0dHlkb2M6Omh0bWxfcHJldHR5Og0KICAgIA0KICAgIHRoZW1lOiBhcmNoaXRlY3QNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZGVwdGg6IDUNCiAgICBjc3M6IG5ld2NoaWxsLmNzcw0KICBwZGZfZG9jdW1lbnQ6DQogICAgDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2RlcHRoOiA1DQpmb250c2l6ZTogMTJwdA0KbGFuZzogImVzLU1YIg0Kc3VidGl0bGU6IEZvcmVjYXN0IFNBUklNQS4NCmFsd2F5c19hbGxvd19odG1sOiB0cnVlDQotLS0NCg0KYGBge3IgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldCh3YXJuaW5nID0gRikNCmBgYA0KDQo8Y2VudGVyPiFbXShDSUVOQ0lBUy5wbmcpwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCFbXShVTkFNLnBuZyl7d2lkdGg9IjE5MyJ9PC9jZW50ZXI+DQoNCjxocj4NCg0KwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoA0KDQpFbWFpbCDCoMKgwqDCoMKgIMKgIMKgIMKgwqA6wqA8YSBocmVmPSJtYWlsdG86RWxpYW5FbGlhbkBjaWVuY2lhcy51bmFtLm14IiBzdHlsZT0iY29sb3I6ICNjNmEyZWU7Ij5FbGlhbkVsaWFuXEBjaWVuY2lhcy51bmFtLm14PC9hPvCfppU8YnI+XA0KUlB1YnMgwqDCoMKgwqDCoCDCoCDCoCDCoDrCoFtNaXMgcHVibGljYWNpb25lc10oaHR0cHM6Ly9ycHVicy5jb20vRWxpYW5FbGlhbiAiUlB1YnMgRWxpYW4iKXtzdHlsZT0iY29sb3I6ICNjNmEyZWUifSA8YnI+XA0KRmFjdWx0YWQgwqDCoMKgwqDCoMKgwqA6wqBbRmFjdWx0YWQgZGUgQ2llbmNpYXNdKGh0dHBzOi8vd3d3LmZjaWVuY2lhcy51bmFtLm14LyAiRmFjdWx0YWQgZGUgQ2llbmNpYXMiKXtzdHlsZT0iY29sb3I6ICNjNmEyZWUifSA8YnI+DQoNCsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqANCg0KWyoqRGVzY3JpcGNpb24uKipdey5zbWFsbGNhcHN9DQoNCkVuIGVzdGUgZG9jdW1lbnRvIHNlIHByZXNlbnRhIGxhIG1ldG9kb2xvZ8OtYSBwYXJhIHJlYWxpemFyIHVuIGFuw6FsaXNpcyBkZSB1bmEgc2VyaWUgZGUgdGllbXBvIHVzYW5kbyBsYSBoZXJyYW1pZW50YSBSLCB0ZW5pZW5kbyBlbiBjdWVudGEgbG9zIHBhc29zIGEgcmVhbGl6YXIgeSBhbGd1bm9zIGNvbmNlcHRvcyBsaW1pdGFkb3MgYSBkb3MgbW9kZWxvczsgQVJJTUEgeSBTQVJJTUEuIE51ZXN0cm8gcHJpbmNpcGFsIGludGVyZXMgc2VyYSBzYWJlciBpZGVudGlmaWNhciBlbCBtb2RlbG8gZGUgdW5hIHNlcmllIGRlIHRpZW1wbyB5IHBvbmVybG8gYSBwcnVlYmEsIGRlc3B1ZXMsIHBhcmEgdGVuZXIgZnVuZGFtZW50YWRvIHJlYWxpemFyIHVuYSBwcmVkaWNjaW9uIGNvbiBlbCBtb2RlbG8uDQoNCsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqANCg0KPGhyPg0KDQojIFRlb3JpYS4gey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KIyMgUHJvcGllZGFkIEVzdGFjaW9uYXJpYSAoRGViaWxtZW50ZSBFc3RhY2lvbmFyaWEpLg0KDQpbKipEZWZpbmljaW9uLioqXXsuc21hbGxjYXBzfQ0KDQo8aHI+DQoNClVuYSBzZXJpZSBkZSB0aWVtcG8gJFhfdCQgc2UgY29uc2lkZXJhIGTDqWJpbG1lbnRlIGVzdGFjaW9uYXJpYSBvIHNpbXBsZW1lbnRlIGVzdGFjaW9uYXJpYSBzaSBjdW1wbGUgY29uIGxhcyBzaWd1aWVudGVzIHByb3BpZWRhZGVzOg0KDQotICAgTGEgbWVkaWEgJEUoWF90KSQgZXMgY29uc3RhbnRlIGUgaWd1YWwgcGFyYSB0b2RvcyBsb3MgcGVyw61vZG9zLCBlcyBkZWNpciwgJEUoWF90KSA9IEUoWF97dCtrfSkgPSBcbXUkLg0KDQotICAgTGEgdmFyaWFuemEgJFx0ZXh0e1Zhcn0oWF90KSQgZXMgY29uc3RhbnRlIGUgaWd1YWwgcGFyYSB0b2RvcyBsb3MgcGVyw61vZG9zLCBlcyBkZWNpciwgJFx0ZXh0e1Zhcn0oWF90KSA9IFx0ZXh0e1Zhcn0oWF97dCtrfSkgPSBcc2lnbWFeMiQuDQoNCi0gICBMYSBjb3ZhcmlhbnphICRcdGV4dHtDb3Z9KFhfdCxYX3t0K2t9KSQgZW50cmUgZG9zIHBlcsOtb2RvcyAkdCQgeSAkdCtrJCBkZXBlbmRlIMO6bmljYW1lbnRlIGRlIGxhIGRpc3RhbmNpYSBvIHJlemFnbyAkayQgZW50cmUgZWxsb3MsIGVzIGRlY2lyLCAkXHRleHR7Q292fShYX3QsWF97dCtrfSkgPSBcZ2FtbWFfayQuDQoNCkN1YW5kbyB1bmEgKipzZXJpZSBkZSB0aWVtcG8gZXMgZXN0YWNpb25hcmlhLCBzdXMgcHJvcGllZGFkZXMgZXN0YWTDrXN0aWNhcyBubyBjYW1iaWFuIGNvbiBlbCB0aWVtcG8sIGxvIHF1ZSBzaW1wbGlmaWNhIGVsIHByb2Nlc28gZGUgbW9kZWxhZG8geSBwcmVkaWNjacOzbi4qKiBMb3MgbW9kZWxvcyBBUklNQSwgKiphc3VtZW4qKiBlc3RhY2lvbmFyaWVkYWQgcGFyYSBzdSBhcGxpY2FjacOzbi4NCg0KIyMgRXN0YWNpb25hbGlkYWQuDQoNClsqKkRlZmluaWNpb24uKipdey5zbWFsbGNhcHN9DQoNCjxocj4NCg0KU2UgZGljZSBkZSB1bmEgc2VyaWUgZGUgdGllbXBvIHF1ZSBlcyBlc3RhY2lvbmFsIGN1YW5kbyBlc3TDoSBpbmZsdWVuY2lhZGEgcG9yIGZhY3RvcmVzIGVzdGFjaW9uYWxlcyBkZSAqKnBlcmlvZG8gZmlqbyoqIGVuIHRvZG8gZWwgdGllbXBvOyBjb21vIGVsIGRpYSwgbWVzLCB0cmltZXN0cmUuDQoNCj4gTGEgZXN0YWNpb25hbGlkYWQgZXMgbGEgcmVwZXRpY2nDs24gZGUgZGV0ZXJtaW5hZGFzIHZhcmlhY2lvbmVzIGVuIGFsZ3VuYSB2YXJpYWJsZSBjYWRhIGNpZXJ0byBwZXLDrW9kbywgbm9ybWFsbWVudGUgaWd1YWwgbyBtZW5vciBhIHVuIGHDsW8uIEVuIHBlcsOtb2RvcyBtw6FzIGFtcGxpb3Mgc2Ugc3VlbGUgaGFibGFyIGRlIGNpY2xvcywgYXVucXVlIGxhcyB2YXJpYWNpb25lcyBjw61jbGljYXMgbm8gc29uIHRhbiBmcmVjdWVudGVzIGNvbW8gbGFzIGVzdGFjaW9uYWxlcy4gUG9yIGVqZW1wbG8sIGNhZGEgMiBhw7FvcyBzZSBjZWxlYnJhIGxhIGJpZW5hbCBkZSBWZW5lY2lhLCBjYWRhIDQgYcOxb3MgZWwgbXVuZGlhbCBkZSBmw7p0Ym9sIHkgY2FkYSA3NiBhw7FvcyBzZSBvYnNlcnZhIGVsIGNvbWV0YSBIYWxsZXkuIFsqLSBbQkJWQSDCv1F1w6kgZXMgeSBjw7NtbyBub3MgYWZlY3RhIGxhIGVzdGFjaW9uYWxpZGFkP10oaHR0cHM6Ly93d3cuYmJ2YS5jb20vZXMvZWNvbm9taWEteS1maW5hbnphcy9xdWUtZXMteS1jb21vLW5vcy1hZmVjdGEtbGEtZXN0YWNpb25hbGlkYWQvKSpdey5zbWFsbGNhcHN9DQoNCiMjIEFSSU1BLg0KDQpbKipEZWZpbmljaW9uLioqXXsuc21hbGxjYXBzfQ0KDQo8aHI+DQoNCkFSSU1BLCBkZW5vbWluYWRvIGNvbW8gKipBdXRvLVJlZ3Jlc2l2byBJbnRlZ3JhZG8gZGUgTWVkaWEgTW92aWwqKiBwb3Igc3VzIHNpZ2xhcyB5IGRlbm90YWRvIGNvbW8gKipBUklNQSgqcCosKmQqLCpxKiksKiogZXMgbGEgY29tYmluYWNpw7NuIGRlIGxvcyBtb2RlbG9zIGF1dG9ycmVncmVzaXZvIHkgZWwgZGUgbWVkaWFzIG3Ds3ZpbGVzLCBjb24gbGEgcGFydGljdWxhcmlkYWQgZGUgcXVlIGRlYmUgaW5jbHVpciB1biBwcm9jZXNvIGRlIHJlc3RhYmxlY2ltaWVudG8gKGVsIGN1YWwgc2UgZGVub21pbmEgaW50ZWdyYWNpw7NuIEkpIGRlIGluZXN0YWJpbGlkYWQgb3JpZ2luYWwgcHJlc2VudGUgZW4gdW5hIHNlcmllIGRlIHRpZW1wby4NCg0KPGNlbnRlcj4qKlBvbGlub21pbzoqKjwvY2VudGVyPg0KDQpgYGB7PXRleH0NClxiZWdpbntlcXVhdGlvbip9DQooMSAtIFxwaGlfMSBCIC0gXHBoaV8yIEJeMiAtIFxsZG90cyAtIFxwaGlfcCBCXnApIFhfdCAoMSAtIEIpXmQgPSBjICsgKDEgKyBcdGhldGFfMSBCICsgXHRoZXRhXzIgQl4yICsgXGxkb3RzICsgXHRoZXRhX3EgQl5xKSBaX3QNClxlbmR7ZXF1YXRpb24qfQ0KYGBgDQrCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgDQoNCmBgYHs9dGV4fQ0KXGJlZ2lue2VxdWF0aW9uKn0NCnhfdCcgPSBccGhpXzEgeCdfe3QtMX0gKyBcbGRvdHMgKyBccGhpX3AgeCdfe3QtcH0gKyBaX3QgLSBcdGhldGEgWl97dC0xfSAtIFxsZG90cyAtIFx0aGV0YV9xIFpfe3QtcX0NClxlbmR7ZXF1YXRpb24qfQ0KYGBgDQrCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgDQoNCmBgYHs9dGV4fQ0KXGJlZ2lue2VxdWF0aW9uKn0NCkFSKHApSShkKSA9IE1BKHEpDQpcZW5ke2VxdWF0aW9uKn0NCmBgYA0KwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqANCg0KPGNlbnRlcj4qKkRvbmRlOioqPC9jZW50ZXI+DQoNCi0gICAkQl5kIFhfdCA9IFhfe3QtZH0kIGVzIGVsIG9wZXJhZG9yIGRlIHJldHJhc2k7DQoNCi0gICAkKDEgLSBCKV5kIFhfdCA9IFxEZWx0YV5kIFhfdCQgZXMgZWwgb3BlcmFkb3IgZGlmZXJlbmNpYSwgZGVub3RhIGxhIHNlcmllIHRlbXBvcmFsIGRpZmVyZW5jaWFkYSAkZCQgdmVjZXM7DQoNCi0gICB5IGxhICRYJ190JCBkZW5vdGEgbGEgc2VyaWUgZGUgdGllbXBvIGluZHVjaWRhIGEgbGEgZXN0YWJpbGlkYWQgbyBlc3RhY2lvbmFyaWVkYWQuDQoNCjxocj4NCg0KPGNlbnRlcj4qKkRlc2dsb3NlOioqPC9jZW50ZXI+DQoNCi0gICAqKihBUikgUGFyYW1ldHJvIHAuIEF1dHJvcmVncmVzaW9uIHAqKg0KDQoqKkF1dG8gUmVncmVzc2l2ZSoqIFNvbiBtb2RlbG9zIGRvbmRlICoqZWwgdmFsb3IgZGUgdW5hIHZhcmlhYmxlIGVuIHVuIHBlcmlvZG8gc2UgcmVsYWNpb25hIGNvbiBsb3MgdmFsb3JlcyBkZSBwZXJpb2RvcyBwcmV2aW9zKiouIFNlIHJlZmllcmUgYSBsb3MgbGFncyAqKipwKioqIGRlIGxhcyBkaWZlcmVuY2lhcyBkZSBsb3MgdmFsb3JlcyBlbnRyZSBsYXMgc2VyaWVzLiBFc3RhIHBhcnRlIGRlbCBtb2RlbG8gY2FwdHVyYSBsYSByZWxhY2nDs24gbGluZWFsIGVudHJlIHVuYSBvYnNlcnZhY2nDs24geSB1biBuw7ptZXJvIGxpbmVhbCBkZSBvYnNlcnZhY2lvbmVzIHJldHJhc2FkYXMgKGxhZ2dlZCBvYnNlcnZhdGlvbnMpLiBMYSBub3RhY2nDs24gQVIocCkgcmVwcmVzZW50YSBlc3RhIHBhcnRlLCBkb25kZSAicCIgZXMgZWwgbsO6bWVybyBkZSByZXRyYXNvcyBpbmNsdWlkb3MgZW4gZWwgbW9kZWxvLg0KDQpbQmFzaWNhbWVudGUgZXN0ZSBwYXJhbWV0cm8gaW5kaWNhIHF1ZSB0YW50b3MgcmV0cmFzb3MgKGxhZ3MgKioqcCoqKikgdG9tYW1vcyBlbiBjdWVudGEgZGV0ZXJtaW5hbiBlbCB2YWxvciBhY3R1YWwsIGVzIGRlY2lyLCBwIHJldHJhc29zLCBwIGRhdG9zIHByZXZpb3Mgc2UgcmVsYWNpb25hbiBjb24gZWwgdmFsb3IgYWN0dWFsLl17LnVuZGVybGluZX0NCg0KLSAgICoqKEkpKiogKipQYXJhbWV0cm8gZC4gRGlmZXJlbmNpYWNpb24gZCAoUmFuZG9tIFdhbGssIGV0Yy4gc3VtYSBhY3VtdWxhdGl2YSBkZSBydWlkb3MgYmxhbmNvcyAoMCwwLDApKSoqDQoNClNlIHJlZmllcmUgYWwgb3JkZW4gZGVsIG7Dum1lcm8gZGlmZXJlbmNpYWwgcXVlIHNlIHVzYW4gcGFyYSBoYWNlciBsYXMgc2VyaWVzIGRlIHRpZW1wbyBlc3RhY2lvbmFyaWFzLg0KDQoqRXN0YSBwYXJ0ZSBkZWwgbW9kZWxvIGluZGljYSBlbCBuw7ptZXJvIGRlIGRpZmVyZW5jaWFjaW9uZXMgbmVjZXNhcmlhcyBwYXJhIHZvbHZlciBlc3RhY2lvbmFyaWEgYSBsYSBzZXJpZSB0ZW1wb3JhbCwgZXMgZGVjaXIsIGhhY2VyIHF1ZSBsYSBtZWRpYSB5IGxhIHZhcmlhbnphIHNlYW4gY29uc3RhbnRlcyBlbiBlbCB0aWVtcG8uIExhIG5vdGFjacOzbiBJKGQpIHJlcHJlc2VudGEgZXN0YSBwYXJ0ZSwgZG9uZGUgImQiIGVzIGVsIG7Dum1lcm8gZGUgZGlmZXJlbmNpYWNpb25lcy4qDQoNCi0gICAqKihNQSkgUGFyYW1ldHJvIHEuIEVycm9yIGRlIFJlZ3Jlc2lvbiBxKioNCg0KQ29uc2lkZXJhbiBsYSBwb3NpYmlsaWRhZCBkZSB1bmEgcmVsYWNpw7NuIGVudHJlIGxhIHZhcmlhYmxlIHkgbG9zIHJlc2lkdWFsZXMgZGUgcGVyaW9kb3MgcHJldmlvcy4gU2UgcmVmaWVyZSBhIGxvcyBsYWdzICpxKiBkZSBsb3MgZXJyb3Jlcy4gVGllbmUgc2VudGlkbyBlbCBub21icmUgZGUgbWVkaWEgbW92aWwgeWEgcXVlDQoNCipFc3RhIHBhcnRlIGRlbCBtb2RlbG8gcmVwcmVzZW50YSBsYSByZWxhY2nDs24gbGluZWFsIGVudHJlIHVuYSBvYnNlcnZhY2nDs24geSBsb3MgZXJyb3JlcyByZXNpZHVhbGVzIGRlIHByZWRpY2Npb25lcyBwYXNhZGFzIGVuIHVuIG7Dum1lcm8gbGluZWFsIGRlIHBlcsOtb2RvcyBkZSB0aWVtcG8uIExhIG5vdGFjacOzbiBNQShxKSByZXByZXNlbnRhIGVzdGEgcGFydGUsIGRvbmRlICJxIiBlcyBlbCBuw7ptZXJvIGRlIHTDqXJtaW5vcyBkZSBlcnJvcmVzIHJlc2lkdWFsZXMgaW5jbHVpZG9zIGVuIGVsIG1vZGVsby4qDQoNCltCYXNpY2FtZW50ZSBlcyBsbyBhbmFsb2dvIGFsIEFSKHApLCBzb2xvIHF1ZSBlbiBlc3RlIGNhc28gY29uc2lkZXJhIGEgbG9zICoqcSoqIGVycm9yZXMgbyByZXNpZHVhbGVzIChsYWdzKSBkZSBsYSByZWdyZXNpb24gcGFyYSBkZWZpbmlyIHVuYSByZWxhY2lvbiBlbiBlbCBwZXJpb2RvIGFjdHVhbCBjb24gbG9zIHByZXZpb3MsIGVzIGRlY2lyLCBxIHBlcmlvZG9zIHByZXZpb3MgZGUgcmVzaWR1b3MgdGllbmVuIHJlbGFjaW9uIGNvbiBudWVzdHJvIHBlcmlvZG8gYWN0dWFsLl17LnVuZGVybGluZX0NCg0KPGhyPg0KDQo8Y2VudGVyPioqU3VwdWVzdG9zIGRlbCBBUklNQS4qKjwvY2VudGVyPg0KDQotICAgKipMb3MgZGF0b3MgZGViZW4gc2VyIGVzdGFjaW9uYXJpb3MsIG8gc2kgbm8sIGRlYmVuIHN1ZnJpciB1bmEgdHJhbnNmb3JtYWNpb24gKEJveC1Db3gsIGxvZywgcmFpeiwgMS94LCBldGMuKSoqOiBsYXMgcHJvcGllZGFkZXMgZGUgbGEgc2VyaWUgbm8gZGVwZW5kZW4gZGVsIG1vbWVudG8gZW4gcXVlIHNlIGNhcHR1cmFuLiBVbiBwcm9jZXNvIGVzdGFjaW9uYXJpbyB0aWVuZSB1bmEgbWVkaWEgeSB1bmEgdmFyaWFjacOzbiBxdWUgbm8gY2FtYmlhbiBjb24gZWwgdGllbXBvIHkgbm8gdGllbmUgdW5hIHRlbmRlbmNpYSAobWVkaWEgbyBwZW5kaWVudGUgY2FtYmlhbnRlKS4NCg0KLSAgICoqTG9zIGRhdG9zIGRlYmVuIHNlciB1bml2YXJpYWRvcyoqOiBBUklNQSB0cmFiYWphIGNvbiB1bmEgc29sYSB2YXJpYWJsZS4gTGEgcmVncmVzacOzbiBhdXRvbcOhdGljYSB0aWVuZSBxdWUgdmVyIGNvbiBsYSByZWdyZXNpw7NuIGNvbiBsb3MgdmFsb3JlcyBwYXNhZG9zLg0KDQotICAgKipMaW5lYWxpZGFkOioqIFNlIGFzdW1lIHF1ZSBsYSByZWxhY2nDs24gZW50cmUgbGFzIG9ic2VydmFjaW9uZXMgcGFzYWRhcyB5IHByZXNlbnRlcyBlcyBsaW5lYWwuIEVzdG8gc2lnbmlmaWNhIHF1ZSBsYXMgcmVsYWNpb25lcyBlbnRyZSBsYXMgdmFyaWFibGVzIGVuIGVsIG1vZGVsbyBwdWVkZW4gc2VyIHJlcHJlc2VudGFkYXMgcG9yIHVuYSBjb21iaW5hY2nDs24gbGluZWFsIGRlIGxvcyBwYXLDoW1ldHJvcyBkZWwgbW9kZWxvLg0KDQotICAgKipJbmRlcGVuZGVuY2lhIGRlIGxvcyBFcnJvcmVzOioqIFNlIGFzdW1lIHF1ZSBsb3MgZXJyb3JlcyBkZSBwcmVkaWNjacOzbiBzb24gaW5kZXBlbmRpZW50ZXMgZW50cmUgc8OtIHkgbm8gbXVlc3RyYW4gYXV0b2NvcnJlbGFjacOzbiBzaWduaWZpY2F0aXZhLiBFbiBvdHJhcyBwYWxhYnJhcywgbG9zIHJlc2lkdW9zIGRlbCBtb2RlbG8gQVJJTUEgZGViZW4gY29tcG9ydGFyc2UgY29tbyBydWlkbyBibGFuY28uDQoNCi0gICAqKk5vcm1hbGlkYWQgZGUgbG9zIEVycm9yZXM6KiogU2UgYXN1bWUgcXVlIGxvcyBlcnJvcmVzIGRlIHByZWRpY2Npw7NuIHNpZ3VlbiB1bmEgZGlzdHJpYnVjacOzbiBub3JtYWwgY29uIHVuYSBtZWRpYSBkZSBjZXJvIChSdWlkbyBibGFuY28gY29uIG1lZGlhIGNlcm8pLiBBdW5xdWUgZXN0ZSBzdXB1ZXN0byBwdWVkZSBzZXIgcmVsYWphZG8gZW4gYWxndW5vcyBjYXNvcywgZXMgw7p0aWwgcGFyYSBpbnRlcnByZXRhciBsb3MgaW50ZXJ2YWxvcyBkZSBjb25maWFuemEgeSByZWFsaXphciBwcnVlYmFzIGVzdGFkw61zdGljYXMuDQoNCi0gICAqKkhvbW9jZWRhc3RpY2lkYWQ6KiogTG9zIGVycm9yZXMgZGUgcHJlZGljY2nDs24gZGViZW4gdGVuZXIgdW5hIHZhcmlhbnphIGNvbnN0YW50ZSBhIGxvIGxhcmdvIGRlbCB0aWVtcG8uIEVzdG8gc2lnbmlmaWNhIHF1ZSBsYSBkaXNwZXJzacOzbiBkZSBsb3MgZXJyb3JlcyBubyBkZWJlIGNhbWJpYXIgYSBtZWRpZGEgcXVlIGF2YW56YSBsYSBzZXJpZSB0ZW1wb3JhbC4NCg0KICAgIFwtIFtbKlJvamFzIEppbWVuZXosIEsuIDIwMjIuIENpZW5jaWEgZGUgRGF0b3MgcGFyYSBDaWVuY2lhcyBOYXR1cmFsZXMqXXsuc21hbGxjYXBzfV0oaHR0cHM6Ly9ib29rZG93bi5vcmcva2VpbG9yX3JvamFzL0NpZW5jaWFEYXRvcy9hbiVDMyVBMWxpc2lzLWRlLXNlcmllcy1kZS10aWVtcG8uaHRtbCNjb3JyZWNjaSVDMyVCM24tZGUtbGEtZXN0YWNpb25hcmllZGFkLXN0YXRpb25hcml0eS15LWVzdGFjaW9uYWxpZGFkLXNlYXNvbmFsaXR5KSB+KmZyYWdtZW50b3PCoGRlbMKgdGV4dG/CoHVzYWRvcy4qfg0KDQogICAgXC0gW1sqUHRvbG9tZW8gVU5BTSwgTW9kZWxhY2lvbiBBUklNQSpdey5zbWFsbGNhcHN9XShodHRwOi8vd3d3LnB0b2xvbWVvLnVuYW0ubXg6ODA4MC9qc3B1aS9iaXRzdHJlYW0vMTMyLjI0OC41Mi4xMDAvMzYzLzcvQTcucGRmKSB+KmZyYWdtZW50b3PCoGRlbMKgdGV4dG/CoHVzYWRvcy4qfg0KDQojIyBTQVJJTUEuDQoNClsqKkRlZmluaWNpb24uKipdey5zbWFsbGNhcHN9DQoNCjxocj4NCg0KRWwgbW9kZWxvIFNBUklNQSAoKipTZWFzb25hbCBBdXRvUmVncmVzc2l2ZSBJbnRlZ3JhdGVkIE1vdmluZyBBdmVyYWdlKiopIGVzIHVuYSBleHRlbnNpw7NuIGRlbCBtb2RlbG8gQVJJTUEgcXVlIHRhbWJpw6luIHRpZW5lIGVuIGN1ZW50YSBsYSAqKmVzdGFjaW9uYWxpZGFkIChTZWFzb25hbCkqKi4gTGEgbm90YWNpw7NuIGdlbmVyYWwgcGFyYSB1biBtb2RlbG8gU0FSSU1BIGVzICoqU0FSSU1BKihwLCBkLCBxKSAoUCwgRCwgUSkgKHMpKioqOw0KDQrCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoA0KDQo8Y2VudGVyPioqRG9uZGU6Kio8L2NlbnRlcj4NCg0KLSAgICRwJDogT3JkZW4gZGVsIGNvbXBvbmVudGUgYXV0b3JlZ3Jlc2l2byBubyBlc3RhY2lvbmFsIChBUikuDQoNCi0gICAkZCQ6IE9yZGVuIGRlIGRpZmVyZW5jaWFjacOzbiBubyBlc3RhY2lvbmFsLCBlcyBkZWNpciwgYW50ZXMgZGUgc2VyIGVzdGFjaW9uYWwgcXVlIG9yZGVuIGRlIGRpZmVyZW5jaWFjaW9uIHRlbmlhLCBhbmFsb2dhbWVudGUgbG9zIGRlbWFzLg0KDQotICAgJHEkOiBPcmRlbiBkZWwgY29tcG9uZW50ZSBkZSBtZWRpYSBtw7N2aWwgbm8gZXN0YWNpb25hbCAoTUEpLg0KDQotICAgJFAkOiBPcmRlbiBkZWwgY29tcG9uZW50ZSBhdXRvcmVncmVzaXZvIGVzdGFjaW9uYWwuDQoNCi0gICAkRCQ6IE9yZGVuIGRlIGRpZmVyZW5jaWFjacOzbiBlc3RhY2lvbmFsLg0KDQotICAgJFEkOiBPcmRlbiBkZWwgY29tcG9uZW50ZSBkZSBtZWRpYSBtw7N2aWwgZXN0YWNpb25hbC4NCg0KLSAgICRzJDogTG9uZ2l0dWQgZGVsIHBlcsOtb2RvIGVzdGFjaW9uYWwuDQoNCjxjZW50ZXI+KipQb2xpbm9taW86Kio8L2NlbnRlcj4NCg0KwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqANCg0KJCQNCigxIC0gXHBoaV8xIEIgLSBccGhpXzIgQl4yIC0gXGxkb3RzIC0gXHBoaV9wIEJecCkoMSAtIEIpXmQoMSAtIFxQaGlfMSBCXnMgLSBcUGhpXzIgQl57MnN9IC0gXGxkb3RzIC0gXFBoaV9QIEJee1BzfSkoMSAtIEJecyleRCBYX3QgPSBjICsgKDEgKyBcdGhldGFfMSBCICsgXHRoZXRhXzIgQl4yICsgXGxkb3RzICsgXHRoZXRhX3EgQl5xKSgxICsgXFRoZXRhXzEgQl5zICsgXFRoZXRhXzIgQl57MnN9ICsgXGxkb3RzICsgXFRoZXRhX1EgQl57UXN9KVpfdA0KJCQNCg0KwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqANCg0KPGNlbnRlcj4qKkRvbmRlOioqPC9jZW50ZXI+DQoNCi0gICAkWF90JCBlcyBsYSBzZXJpZSB0ZW1wb3JhbCBlbiBlbCB0aWVtcG8gInQiLg0KDQotICAgJEIkIGVzIGVsIG9wZXJhZG9yIGRlIHJldHJhc28uDQoNCi0gICAkXHBoaV8xLCBccGhpXzIsIFxsZG90cywgXHBoaV9wJCBzb24gbG9zIHBhcsOhbWV0cm9zIGRlIGF1dG9yZWdyZXNpw7NuLg0KDQotICAgJFxQaGlfMSwgXFBoaV8yLCBcbGRvdHMsIFxQaGlfUCQgc29uIGxvcyBwYXLDoW1ldHJvcyBkZSBhdXRvcmVncmVzacOzbiBlc3RhY2lvbmFsZXMuDQoNCi0gICAkXHRoZXRhXzEsIFx0aGV0YV8yLCBcbGRvdHMsIFx0aGV0YV9xJCBzb24gbG9zIHBhcsOhbWV0cm9zIGRlIGxhIHBhcnRlIGRlIG1lZGlhIG3Ds3ZpbC4NCg0KLSAgICRcVGhldGFfMSwgXFRoZXRhXzIsIFxsZG90cywgXFRoZXRhX1EkIHNvbiBsb3MgcGFyw6FtZXRyb3MgZGUgbGEgcGFydGUgZGUgbWVkaWEgbcOzdmlsIGVzdGFjaW9uYWwuDQoNCi0gICAkYyQgZXMgdW5hIGNvbnN0YW50ZS4NCg0KLSAgICRaX3QkIGVzIHVuIHJ1aWRvIGJsYW5jby4gXFxlbmR7aXRlbWl6ZX0NCg0KPGhyPg0KDQo8Y2VudGVyPioqU3VwdWVzdG9zIGRlbCBTQVJJTUE6Kio8L2NlbnRlcj4NCg0KQW5hbG9nbyBhIGxvcyBzdXB1ZXN0b3MgZGVsIEFSSU1BLg0KDQotICAgKipFc3RhY2lvbmFyaWVkYWQuKioNCg0KLSAgICoqTGluZWFsaWRhZC4qKg0KDQotICAgKipJbmRlcGVuZGVuY2lhIGRlIGxvcyBlcnJvcmVzLioqDQoNCi0gICAqKk5vcm1hbGlkYWQgZGUgbG9zIGVycm9yZXMuKioNCg0KLSAgICoqSG9tb2NlZGFzdGljaWRhZC4qKg0KDQotICAgKipFc3RhY2lvbmFsaWRhZCoqOiBWZXJpZmljYWNpb24gZGUgbG9zIGNpY2xvcywgeSBxdWUgZXN0b3Mgc2VhbiBlc3RhY2lvbmFsZXMuDQoNCi0gICAqKkVzdGFjaW9uYWxpZGFkIGVzdGFjaW9uYXJpYToqKiBFbCBjb21wb25lbnRlIGVzdGFjaW9uYWwgZGVsIG1vZGVsbyBTQVJJTUEgZGViZSBzZXIgZXN0YWNpb25hcmlvLiBFc3RvIGltcGxpY2EgcXVlIGxhIGVzdGFjaW9uYWxpZGFkIGRlYmUgc2VyIG1vZGVsYWRhIGFkZWN1YWRhbWVudGUgeSBubyBkZWJlIGhhYmVyIHBhdHJvbmVzIHNpc3RlbcOhdGljb3MgZW4gbG9zIHJlc2lkdW9zIGVzdGFjaW9uYWxlcy4NCg0KIyBQcmFjdGljYS4gey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KIyMgTWV0b2RvbG9naWEuDQoNCkxhIG1ldG9kb2xvZ2lhIHVzYWRhIGVuIGVzdGUgdGlwbyBkZSBhbmFsaXNpcywgZXMgbGEgc2lndWllbnRlIG1vc3RyYWRhIGVuIHVuIGRpYWdyYW1hOg0KDQoxLiAgUHJpbWVybyBzZSAqKmlkZW50aWZpY2EqKiBlbCBtb2RlbG8gYW5hbGl6YW5kbyBsYSBzZXJpZSBkZSB0aWVtcG8gYSBzZWNhcyAobG8gcXVlIGNyZWVtb3MgcXVlIGVzLCB2aWVuZG8gc3VzIEFDRiB5IFBBQ0YsIGV0YykuDQoNCjIuICBEZXNwdWVzICoqZXN0aW1hcyBsb3MgcGFyYW1ldHJvcyoqIGVuIGNvbnNlY3VlbmNpYSBkZSB0dSBhbmFsaXNpcywgYW50ZXMgZGUgZXN0ZSBwYXNvLCBlcyByZWNvbWVuZGFibGUgcHJpbWVybyAqKnZlcmlmaWNhciBxdWUgZW4gZWZlY3RvIHR1IHNlcmllIGRlIHRpZW1wbyBjdW1wbGEgY29uIGxvcyBzdXB1ZXN0b3MqKiBkZSB0dSBtb2RlbG8sIGFzaSBxdWUgZW4gZXN0ZSBwYXNvIHRhbWJpZW4gdmVyYXMgcXVlIHR1IHNlcmllIGRlIHRpZW1wbyBjdW1wbGEgY29uIHNlciBlc3RhY2lvbmFyaWEsIGhvbW9jZWRhc3RpY2EsIHVuaXZhcmlhZGEsIGV0Yy4gRW4gZXN0ZSBwYXNvIHRhbWJpZW4gc2UgcHVlZGVuIHByb2JhciBkaXZlcnNvcyBtb2RlbG9zLCBtb2RlbG9zIGNvbiAqb3V0bGllcnMqICh2YWxvcmVzIGF0aXBpY29zKSB5IG1vZGVsb3MgcXVlIG5vIHRlbmdhbiwgZXN0byBwYXJhIHBvZGVyIHZlciBkZSBtYW5lcmEgbWFzIHJlcHJlc2VudGF0aXZhIHN1cyBkaWZlcmVuY2lhczsgeSBwYXJhIHN1IGRlc2NhcnRlIG8gYWNlcHRhY2lvbiwgc2UgcHVlZGUgdmVyIHVuIGFuYWxpc2lzIGFkaWNpb25hbCBvcGNpb25hbCBhZGVtYXMgZGUgbG9zIHN1cHVlc3RvczsgQUlDIHkgQklDLiBcKkRlYmVuIGRlIHNlciBsb3MgbWluaW1vcyBkZSB0b2RvcyBhbWJvc1wqLg0KDQozLiAgKipWZXJpZmljYXMgbG9zIHN1cHVlc3RvcyoqIGRlbCBtb2RlbG8gYSB0cmF2ZXMgZGUgKipQcnVlYmFzIFBhcmFtZXRyaWNhcywqKiB2ZXJpZmljYXMgbG9zIG1pc21vcyBzdXB1ZXN0b3MgcXVlIHNlIHByZXRlbmRpYW4gdmVyIGVuIGxhIHNlcmllIGRlIHRpZW1wbyBhIHRyYXZlcyBkZSB1biAqKkFuYWxpc2lzIFJlc2lkdWFsKiosIHBlcm8gc2kgZXMgcXVlIG5vIHNlIGN1bXBsZW4sIHBvZGVtb3Mgb3B0YXIgcG9yIHJlYWxpemFyIHRyYW5mb3JtYWNpb25lcyBvIGNhbWJpb3MgYSBudWVzdHJvIG1vZGVsbyBvIHNlcmllIGRlIHRpZW1wby4NCg0KNC4gIEFsIGZpbmFsIGRlIGhhY2VyIHRvZG8gbG8gYW50ZXJpb3IsIGRlc3B1ZXMgc2UgdXNhIGVsICoqbW9kZWxvIHBhcmEgcHJlZGVjaXIsKiogZXN0byBqdW50byBhIHVuIGFuYWxpc2lzIGRlIGxvIHF1ZSByZXByZXNlbnRhbiBlc3RhcyBwcmVkaWNjaW9uZXMgZW4gZWwgY29udGV4dG8gZGFkbyAoYnVlbmFzIHByZWRpY2Npb25lcyBwYXJhIGVsIHRlbWEpLiBTaSBhdW4gY29uIGVzdG8gbGFzICoqUHJlZGljY2lvbmVzKiogbm8gc29uIGFkZWN1YWRhcywgZXNvIHF1aWVyZSBkZWNpciBxdWUgZGViZW1vcyBjYW1iaWFyIG51ZXN0cm8gZW5mb3F1ZSBkZSBtb2RlbG8sIHkgcHJvYmFyIG90cmFzIGFsdGVybmF0aXZhcyAoTW9kZWxvcyBkZSBTdWF2aXphZG8gRXhwb25lbmNpYWwgU0UsIEdBUkNILCBSZWRlcyBOZXVyb25hbGVzIFJOTiwgSU5BUiwgRXNwYWNpbyBkZSBFc3RhZG9zIFNTTSwgQ2hhbmdlIFBvaW50LikNCg0KPGhyPg0KDQo8Y2VudGVyPg0KDQohWypEaWFncmFtYSBkZSBEZWNpc2lvbi4qXShpbWFnZXMvZGlhZ3JhbWEyLTAxLnBuZyl7LmlsbHVzdHJhdGlvbiBzdHlsZT0iYm9yZGVyOiA0cHggc29saWQgI0Q4QkZEOCJ9DQoNCjwvY2VudGVyPg0KDQo8aHI+DQoNClVuYSBlc3BlY2lhbCBtZW5jaW9uIGFsIGFuYWxpc2lzIGRlIGxvcyAqYXV0b2NvcnJlbG9ncmFtYXMgbyAqKmNvcnJlbG9ncmFtYXMqKiBvICoqZ3JhZmljbyBkZSBjb3JyZWxhY2lvbioqIGRlIGRhdG9zLioNCg0KLSAgIFNpIGVuIHVuYSBGQUNQIGxhcyBwcmltZXJhcyBwIGNvcnJlbGFjaW9uZXMgc29uIHNpZ25pZmljYXRpdmFzIChkaXN0aW50YXMgZGUgY2VybyBvIG11eSBwb3IgYXJyaWJhIGRlIGNlcm8pLCBtdXkgcHJvYmFibGVtZW50ZSBoYWJsZW1vcyBkZSB1biBBUihwKSB5IGVuIHN1IEFDRiBkZWNhZSBhIGNlcm8uDQoNCi0gICBTaSBlbiB1bmEgQUNGIGxhcyBwcmltZXJhcyBxIGNvcnJlbGFjaW9uZXMgc29uIHNpZ25pZmljYXRpdmFzIChkaXN0aW50YXMgZGUgY2VybyBvIG11eSBwb3IgYXJyaWJhIGRlIGNlcm8pLCBxdWl6YXMgc2UgdHJhdGUgZGUgdW4gTUEocSksIHkgUEFDRiBkZWNhZSBhIGNlcm8uDQoNCi0gICBTaSBlbiBsYSBBQ0Ygc2UgZGUgdW5hIGNvbnZlcmdlbmNpYSBhIGNlcm8gY29tbyBzZSBkaWNlIGVuIGxhIGdyYWZpY2EsIHF1aXphcyBzZSB0cmF0ZSBkZSB1biBBUk1BKHAscSkNCg0KLSAgIEp1bnRhbmRvIGVzdG9zIGRhdG9zLCBjb24gZWwgZmFjdG9yIGRlIGRpZmVyZW5jaWFjaW9uIEkoZCkgcGFyYSB2b2x2ZXIgZXN0YWNpb25hcmlhIGEgdHUgc2VyaWUgZGUgdGllbXBvLCB5IGVsIGZhY3RvciBTIGRlIGVzdGFjaW9uYWxpZGFkLCBzZSBvYnRpZW5lIGVsIFNBUklNQSBwb3IgY29tcGxldG8uDQoNCjxocj4NCg0KPGNlbnRlcj4NCg0KIVsqSWRlbnRpZmljYWNpb24gZGUgTW9kZWxvKl0oaW1hZ2VzL0lkZW50aWZpY2FyX0FSX01BX0FSTUEtMDEucG5nKXsuaWxsdXN0cmF0aW9uIHN0eWxlPSJib3JkZXI6IDRweCBzb2xpZCAjRDhCRkQ4In0NCg0KPC9jZW50ZXI+DQoNCjxjZW50ZXI+WyFbRnVuY2lvbmVzIGRlIGF1dG9jb3JyZWxhY2nDs24gc2ltcGxlIHkgcGFyY2lhbCAtIFRvZG8gRWNvbm9tZXRyaWEuXShBQ0ZQQUNGLnBuZyl7LmlsbHVzdHJhdGlvbiBzdHlsZT0iYm9yZGVyOiA0cHggc29saWQgI0Q4QkZEOCJ9XShodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD9hcHA9ZGVza3RvcCZ2PUhzMDlLMUloNVc4KTwvY2VudGVyPg0KDQojIyBTdXB1ZXN0b3MuDQoNCkFudGVzIGRlIG1vZGVsYXIsIHNvbG8gdG9tYXJlbW9zIGVuIGN1ZW50YSBlbCBtb2RlbG8gKipTQVJJTUEqKiwgcHJpbWVybyBkZWJlbW9zIHZlciBxdWUgbGEgc2VyaWUgZGUgdGllbXBvIG9yaWdpbmFsIGN1bXBsZSBjb24gbG9zIHN1cHVlc3RvcyBTQVJJTUEsIGVzIGRlY2lyLCBjdW1wbGUgbGEgKipIb21vY2VkYXN0aWNpZGFkKiosIGN1bXBsZSBsYSAqKkVzdGFjaW9uYXJpZWRhZCoqLCBjdW1wbGUgY29uIHRlbmVyICoqQ2ljbG9zIEVzdGFjaW9uYWxlcyAoRXN0YWNpb25hbGlkYWQpKiosIHkgY3VtcGxlIGNvbiBxdWUgc3UgcnVpZG8gYmxhbmNvIGVzIGdhdXNzaWFubyBkZSBtZWRpYSBjZXJvIHkgc3VzIGVycm9yZXMgc29uIGluZGVwZW5kaWVudGVzICoqKE5vcm1hbGlkYWQgZSBJbmRlcGVuZGVuY2lhIGRlIGxvcyBlcnJvcmVzKS4qKiBCYXNpY2FtZW50ZSBlbCBzdXB1ZXN0byBkZSB1bml2YXJpYWRvLCBsaW5lYWxpZGFkIHkgbXVsdGljb2xpbmVhbGlkYWQgc29uIG1lbm9zIGV4cGxvcmFkb3MgbyBzZSBkYW4gcG9yIGhlY2hvICh0cml2aWFsZXM/KS4NCg0KVW5hIHZleiBsYSBzZXJpZSBkZSB0aWVtcG8gY3VtcGxlIGxvcyBzdXB1ZXN0b3MgKmVuIHRlb3JpYSosIHBvZGVtb3MgbW9kZWxhcmxhIGVzdGltYW5kbyBsb3MgcGFyYW1ldHJvcyBxdWUgZGVzZWVtb3MgKGFuYWxpemFuZG8gcXVlIHNpZ25pZmljYSBjYWRhIHVubyksIHkgYSBlc3RlIG1vZGVsbyBTQVJJTUEsIGxlIGhhcmVtb3MgKipwcnVlYmFzKiogcGFyYW1ldHJpY2FzLCBlbiBnZW5lcmFsIHBydWViYXMsIHBhcmEgdmVyIHF1ZSB0YW4gcm9idXN0byBvIGFjZXB0YWJsZSBlcy4NCg0KPGhyPg0KDQojIyAqKlBydWViYXMgZGUgbG9zIFN1cHVlc3Rvcy4qKiB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpFamVtcGxvLiBTZSBjYXJnYXJhbiBkYXRvcywgc2UgYXBsaWNhcmEgdW4gbW9kZWxvIHkgc2UgbGUgaGFyYW4gKipQcnVlYmFzKiosIHNlIGFuYWxpemFyYSBzdXMgKipBQ0YgeSBQQUNGKiogeSBzZSBoYXJhIHVuICoqQW5hbGlzaXMgZGUgUmVzaWR1b3MqKi4NCg0KYGBge3IgaW5jbHVkZT1GQUxTRX0NCmRldnRvb2xzOjppbnN0YWxsX2dpdGh1YigiRmluWWFuZy90c2RsIikNCmxpYnJhcnkodHNkbCkgIyBDYXJnYSBkZSBkYXRvcw0KbGlicmFyeShsdWJyaWRhdGUpICMgRGF0YWZyYW1lIGRlIHRlbXBlcmF0dXJhIG1heGltYSBkaWFyaWEgYXNpZ25hZG8gYSBzdSBmZWNoYQ0KbGlicmFyeShzdGF0cykNCmxpYnJhcnkoZ3JhcGhpY3MpDQpsaWJyYXJ5KGZvcmVjYXN0KQ0KbGlicmFyeSh6b28pDQpsaWJyYXJ5KGxtdGVzdCkNCmxpYnJhcnkoY2FyKQ0KbGlicmFyeShzZWFzdGVzdHMpDQpsaWJyYXJ5KCJmVW5pdFJvb3RzIikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoIlRUUiIpDQpsaWJyYXJ5KHRzZXJpZXMpDQpsaWJyYXJ5KHN0YXRzKSAgIyBBbmRlcnNvbiBkYXJsaW5nIGFkLnRlc3QNCmxpYnJhcnkoZ29mdGVzdCkgIyBjcmFtZXIgdm9uIG1pc2VzDQpsaWJyYXJ5KG5vcnRlc3QpDQpsaWJyYXJ5KE1BU1MpDQpgYGANCg0KYGBge3J9DQp0c183MCA8LSB0c2RsW1s3MF1dDQpTQVJJTUEgPC0gYXV0by5hcmltYSh0c183MCwgc2Vhc29uYWwgPSBUUlVFKSAjLCB0cmFjZSA9IFRSVUUgc2kgc2UgcXVpZXJlbiB2ZXIgdG9kb3MgbG9zIG1vZGVsb3MuIA0KYGBgDQoNCjxocj4NCg0KIyMjIEFuYWxpc2lzIGRlIFJlc2lkdW9zLiB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpQcmltZXJvIGhheSBxdWUgZGVjaXIgcXVlIHNlIGxlIHB1ZWRlIHZlciBhIGxvcyByZXNpZHVvcyBjb21vIGxvcyBlcnJvcmVzIGRlIGxhIHJlZ3Jlc2lvbiwgY29tbyBsb3MgcmVzaWR1YWxlcyBwcmVjaXNhbWVudGUgbyBjb21vIGVsIHJ1aWRvIGJsYW5jbyAkWl90JCBkZSBsYSBzZXJpZSBkZSB0aWVtcG8vcHJvY2VzbyAkWF90JC4NCg0KPGhyPg0KDQojIyMjIEFDRiB5IFBBQ0YuDQoNClByaW1lcm8gdmFtb3MgYSBpbnRlcnByZXRhciBsb3MgQUNGIHkgUEFDRi4NCg0KRWwgbW9kZWxvIGFudGVyaW9yIHNlIGRpY2UgcXVlIGVzIHVuICoqU0FSSU1BICgxLDAsMikoMiwxLDApWzEyXSwqKiBhbmFsaXphbmRvIHN1cyAqKkFDRiB5IFBBQ0YgaW5pY2lhbGVzKiogdmVyZW1vcyBkZSBkb25kZSBzYWxlIGVzdG8sIHZlbW9zIHF1ZSBlbCBwIG5vIGVzdGFjaW9uYWwgbm9zIGluZGljYSBxdWUgY2llcnRhbWVudGUgZW4gbGEgUEFDRiBzZWd1biBsYXMgYmFuZGFzIGRlIGNvbmZpYW56YSwgZWwgcGFyYW1ldHJvIHAgZGUgbGFnIGlndWFsIGEgMSBlcyBlbCBzaWduaWZpY2F0aXZvLCBxIGVzIGFsZ28gbWFzIGluY2llcnRvIHBlcm8gZWwgQUNGIGluZGljYSBxdWUgY2llcnRhbWVudGUgbG9zIHByaW1lcm9zIGRvcyBsYWdzIHNvbiBjb25zaWRlcmFibGVtZW50ZSBtYXMgc2lnbmlmaWNhdGl2b3MgcXVlIGxvcyBkZW1hcyBkYWRhcyBsYXMgYmFuZGFzIGRlIGNvbmZpYW56YS4gQWhvcmEgcGFyYSBlbCBhbmFsaXNpcyBkZSBsYXMgKipBQ0YgeSBQQUNGIHJlc2lkdWFsZXMgKGxhcyBxdWUgbm9zIGludGVyZXNhbiBhcXVpKSoqLCBlc3BlcmFtb3MgcXVlIGxhIG1heW9yaWEgZGUgbGFzIGNvcnJlbGFjaW9uZXMgc2UgZW5jdWVudHJlbiBkZW50cm8gZGUgbGEgYmFuZGEgZGUgY29uZmlhbnphIHBhcmEgYnJpbmRhciB1biBtb2RlbG8gZnVlcnRlLCBzaSBoYXkgZGlmZXJlbmNpYXMgbXV5IGdyYW5kZXMgZW50cmUgbGFzIGNvcnJlbGFjaW9uZXMsIHBvZHJpYSBpbmRpY2FyIHF1ZSBlbCBtb2RlbG8gbm8gZXMgbG8gc3VmaWNpZW50ZW1lbnRlIGFkZWN1YWRvOyBTaSBsb3MgcmVzaWR1b3MgcGFyZWNlbiBzZXIgcnVpZG8gYmxhbmNvIChlcyBkZWNpciwgKm5vIGhheSBhdXRvY29ycmVsYWNpw7NuIHNpZ25pZmljYXRpdmEqKS4gRW4gZXN0ZSBjYXNvLCBlcyBsbyBzdWZpY2llbnRlbWVudGUgYWNlcHRhYmxlLg0KDQpgYGB7cn0NCmFjZih0c183MCwgbWFpbiA9ICJBQ0YgZGUgdHNfNzAiKQ0KcGFjZih0c183MCwgbWFpbiA9ICJQQUNGIGRlIHRzXzcwIikNCmFjZihyZXNpZHVhbHMoU0FSSU1BKSwgbWFpbiA9ICJBQ0YgcmVzaWR1YWxlcyBTQVJJTUEiKQ0KcGFjZihyZXNpZHVhbHMoU0FSSU1BKSwgbWFpbiA9ICJQQUNGIHJlc2lkdWFsZXMgU0FSSU1BIikNCmBgYA0KDQojIyMjIFBydWViYXMvVGVzdCBkZSBTdXB1ZXN0b3MuIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCiMjIyMjICoqSW5kZXBlbmRlbmNpYS4qKg0KDQoqKlZlcmlmaWNhciBzaSBsb3MgcmVzaWR1b3Mgc29uIG11dHVhbWVudGUgaW5kZXBlbmRpZW50ZXM6KiogVXRpbGl6YW1vcyBlbCBlc3RhZMOtc3RpY28gUSBkZSAqKipManVuZy1Cb3gqKiogcGFyYSByZWFsaXphciB1bmEgcHJ1ZWJhIGNvbmp1bnRhIHNvYnJlIGxhIHNpZ25pZmljYW5jaWEgZGUgbGFzIGNvcnJlbGFjaW9uZXMgZGUgbG9zIHJlc2lkdW9zIGhhc3RhIHVuIGNpZXJ0byBsYWcuIFNpIGVsIHZhbG9yIHAgZGUgbGEgcHJ1ZWJhIGVzIG1heW9yIHF1ZSB1biBuaXZlbCBkZSBzaWduaWZpY2FuY2lhIHByZWRlZmluaWRvLCBlbnRvbmNlcyBubyBoYXkgZXZpZGVuY2lhIHN1ZmljaWVudGUgcGFyYSByZWNoYXphciBsYSBoaXDDs3Rlc2lzIG51bGEgZGUgcXVlIGxvcyByZXNpZHVvcyBzb24gaW5kZXBlbmRpZW50ZXMuDQoNCmBgYHtyfQ0KcmVzaWR1b3MgPC0gcmVzaWR1YWxzKFNBUklNQSkNCkJveC50ZXN0KHJlc2lkdW9zLGxhZyA9IDIwLCB0eXBlID0gIkxqdW5nLUJveCIpDQoNCmBgYA0KDQoqKkFwcm9iYWRvLioqDQoNCk5vIGhheSBzdWZpY2llbnRlIGV2aWRlbmNpYSBwYXJhIHJlY2hhemFyIGxhIGhpcMOzdGVzaXMgbnVsYSBkZSBpbmRlcGVuZGVuY2lhIGRlIGxvcyByZXNpZHVvcy4gUG9yIGxvIHRhbnRvLCAqKnNlZ8O6biBsb3MgcmVzdWx0YWRvcyBkZSBsYSBwcnVlYmEgZGUgQm94LUxqdW5nLCBsb3MgcmVzaWR1b3MgZGVsIG1vZGVsbyBTQVJJTUEgcGFyZWNlbiBzZXIgaW5kZXBlbmRpZW50ZXMqKiBlbiBsb3MgcHJpbWVyb3MgMjAgcmV6YWdvcy9sYWdzLiBTaSAqKk5PKiogY3VtcGxlIGVsIHN1cHVlc3RvLCBlbnRvbmNlcywgbW9kaWZpY2FyIHBhcmFtZXRyb3MuIENvbW8gcGVyc2lzdGUgZGVwZW5kZW5jaWEgZW4gbG9zIHJlc2lkdWFsZXMsIHF1aWVyZSBkZWNpciBxdWUgZmFsdG8gbW9kZWxhciBkZXBlbmRlbmNpYSBlbiBlbCBtb2RlbG8uIFRhbWJpZW4gc2UgcHVlZGUgaW50ZW50YXIgYWdyZWdhbmRvIG1hcyBsYWdzL3JlemFnb3MsIGFzaSBzYWxkcmlhIG1heW9yIGVsIHAtdmFsdWUsIHBlcm8gdmVyIGhhc3RhIHF1ZSBwdW50ZSBlcyBwZXJtaXNpYmxlLg0KDQojIyMjIyBIb21vY2VkYXN0aWNpZGFkLg0KDQoqKlZlcmlmaWNhciBzaSBsYSB2YXJpYW56YSBkZSBsb3MgcmVzaWR1b3MgZXMgY29uc3RhbnRlIG8gbm8gY29uc3RhbnRlIChoZXRlcm9jZWRhc3RpY2lkYWQpOioqIFNlIHB1ZWRlIGdyYWZpY2FyIGxvcyByZXNpZHVvcyBjb250cmEgZWwgdGllbXBvIHkgb2JzZXJ2YXIgc2kgbGEgZGlzcGVyc2nDs24gZGUgbG9zIHJlc2lkdW9zIHBhcmVjZSBjb25zdGFudGUgYSBsbyBsYXJnbyBkZWwgdGllbXBvLiBPIGhhY2VyIHBydWViYXMsIGNvbW8gbGEgZGUgKioqQnJldXNjaC1QYWdhbi4qKioNCg0KYGBge3J9DQpuIDwtIGxlbmd0aChyZXNpZHVvcykNCnJlZ3Jlc29yIDwtIDE6bg0KbG10ZXN0OjpicHRlc3QocmVzaWR1b3N+cmVncmVzb3IpDQpgYGANCg0KKipBcHJvYmFkby4qKg0KDQpObyBoYXkgc3VmaWNpZW50ZSBldmlkZW5jaWEgcGFyYSByZWNoYXphciBsYSBoaXDDs3Rlc2lzIG51bGEgZGUgaG9tb2NlZGFzdGljaWRhZC4gRXN0byBzdWdpZXJlIHF1ZSBsYSB2YXJpYW56YSBkZSBsb3MgcmVzaWR1b3MgZXMgY29uc3RhbnRlIGEgbG8gbGFyZ28gZGVsIHRpZW1wbywgb3NlYXNlLCBzdWdpZXJlIHF1ZSBzaSBzZSBjdW1wbGUgaG9tb2NlZGFzdGljaWRhZCB5IHJlY2hhemFtb3MgaGV0ZXJvY2VkYXN0aWNpZGFkLiBTaSAqKk5PKiogc2UgY3VtcGxlIGVudG9uY2VzIHJlYWxpemFyIHVuYSB0cmFuc2Zvcm1hY2nDs24gQm94LUNveCwgc29icmUgbGEgc2VyaWUgb3JpZ2luYWwuDQoNCiMjIyMjIEVzdGFjaW9uYXJpZWRhZC4NCg0KKipWZXJpZmljYXIgc2kgbG9zIHJlc2lkdW9zIGN1bXBsZW4gbGEgcHJvcGllZGFkIGVzdGFjaW9uYXJpYTogcXVlIGxhIHZhcmlhbnphIHNlYSBjb25zdGFudGUsIHF1ZSBsYSBtZWRpYSBjb25zdGFudGUsIHkgcXVlIGxhIGNvcnJlbGFjaW9uIHNvbG8gZGVwZW5kYSBkZSBsYSBkaXN0YW5jaWEgZGVsIHJlemFnby9sYWc6KiogU2UgY29uc2lkZXJhcmEgcXVlIHNpIHNlIGN1bXBsZSBlc3RlIHN1cHVlc3RvIGVudG9uY2VzIG5vIGhheSBwcmVzZW5jaWEgZGUgdGVuZGVuY2lhL21lZGlhL3BlbmRpZW50ZSAoZXMgY29uc3RhbnRlIG8gc2Ugc3VlbGUgZGVjaXIgcXVlIGVzIGNlcm8gY29tbyBsYSBtZWRpYSBkZWwgcnVpZG8gYmxhbmNvIGlndWFsIGEgY2VybykuDQoNClNlIHB1ZWRlbiB2ZXJpZmljYXIgcXVlIGxhIG1lZGlhIGVzIGNvbnN0YW50ZSBhIGxvIGxhcmdvIGRlbCB0aWVtcG8sIG1lZGlhbnRlIGVsIGNhbGN1bG8gZGUgbGEgbWVkaWEsIGxhIGhvbW9jZWRhc3RpY2lkYWQgc2UgY29tcHJ1ZWJhIGFudGVyaW9ybWVudGUgeSBzZSBwdWVkZSBwcm9iYXIgbGEgY29ycmVsYWNpb24geSBsYSBpbmRlcGVuZGVuY2lhIGRlIGxvcyBlcnJvcmVzIHBhcmEgZXN0ZSBzdXB1ZXN0bywgbWVkaWFudGUgbG9zIEFDRiB5IFBBQ0Y7IG8gc2UgcHVlZGVuIGhhY2VyIHBydWViYXMgY29tbyAqKkRpY2tleS1GdWxsZXIgYXVtZW50YWRhIChBREYpKiogbyBsYSBwcnVlYmEgZGUgKipLd2lhdGtvd3NraS1QaGlsbGlwcy1TY2htaWR0LVNoaW4gKEtQU1MpKiouIEVzdGFzIHBydWViYXMgZXZhbMO6YW4gc2kgdW5hIHNlcmllIHRlbXBvcmFsIHRpZW5lIHJhw61jZXMgdW5pdGFyaWFzIChBREYpIG8gc2kgbGEgc2VyaWUgZXMgZXN0YWNpb25hcmlhIGVuIHRlbmRlbmNpYSAoS1BTUykuDQoNCmBgYHtyfQ0KdHNlcmllczo6YWRmLnRlc3QocmVzaWR1b3MpDQp0c2VyaWVzOjprcHNzLnRlc3QocmVzaWR1b3MpDQpgYGANCg0KKipBcHJvYmFkby4qKg0KDQoqKlBydWViYSBkZSBEaWNrZXktRnVsbGVyIEF1bWVudGFkYSAoQURGKToqKiBzZWd1biBlbCB3YXJuaW5nOiBwLXZhbHVlIHNtYWxsZXIgdGhhbiBwcmludGVkIHAtdmFsdWU7ICoqZWwgdmFsb3ItcCBvYnRlbmlkbyBlcyBtZW5vciBxdWUgMC4wMS4qKiBFc3RvIGluZGljYSBxdWUgaGF5IHN1ZmljaWVudGUgZXZpZGVuY2lhIHBhcmEgcmVjaGF6YXIgbGEgaGlww7N0ZXNpcyBudWxhIGRlIHByZXNlbmNpYSBkZSB1bmEgcmHDrXogdW5pdGFyaWEgZW4gbG9zIHJlc2lkdW9zLCBsbyBxdWUgc3VnaWVyZSBxdWUgbG9zIHJlc2lkdW9zIHNvbiBlc3RhY2lvbmFyaW9zLg0KDQoqKlBydWViYSBLUFNTIHBhcmEgRXN0YWNpb25hcmllZGFkIGVuIE5pdmVsIChMZXZlbCBTdGF0aW9uYXJpdHkpOioqIC0gc2VndW4gZWwgd2FybmluZzogcC12YWx1ZSBncmVhdGVyIHRoYW4gcHJpbnRlZCBwLXZhbHVlOyAqKmVsIHZhbG9yLXAgb2J0ZW5pZG8gZXMgbWF5b3IgcXVlIDAuMS4qKiBObyBoYXkgc3VmaWNpZW50ZSBldmlkZW5jaWEgcGFyYSByZWNoYXphciBsYSBoaXDDs3Rlc2lzIG51bGEgZGUgZXN0YWNpb25hcmllZGFkIGVuIHRlbmRlbmNpYSwgbG8gcXVlIHN1Z2llcmUgcXVlIGxvcyByZXNpZHVvcyBzb24gZXN0YWNpb25hcmlvcy4NCg0KU2kgKipOTyoqIHNlIGN1bXBsZW4gZXN0b3Mgc3VwdWVzdG9zLCBzZSBwdWVkZW4gaGFjZXIgdHJhbnNmb3JtYWNpb25lcyBhIGxhIHNlcmllIG9yaWdpbmFsLCBoYWNpZW5kb2xhIGVzdGFjaW9uYXJpYSBkZXNkZSB1biBwcmluY2lwaW8sIGV0YywgYXVucXVlIGVzdG8gc2ltcGxpZmljYSBsb3MgbW9kZWxvcy4NCg0KIyMjIyMgTm9ybWFsaWRhZC4NCg0KKipWZXJpZmljYXIgc2kgbG9zIHJlc2lkdW9zIHRpZW5lbiBkaXN0cmlidWNpw7NuIG5vcm1hbCAoZ2F1c3NpYW5hKToqKiBTZSBwdWVkZSBncmFmaWNhciB1biBxcS1wbG90IGRlIGxvcyByZXNpZHVvcyBjb24gdW5hIGzDrW5lYSBkaWFnb25hbCBwYXJhIHZlcmlmaWNhciBzaSBsb3MgcmVzaWR1b3Mgc2lndWVuIHVuYSBkaXN0cmlidWNpw7NuIG5vcm1hbCB2aXN1YWxtZW50ZSwgZGViZW4gZXN0YXIgcGVnYWRvcyBhIGxhIGxpbmVhLCBncmFmaWNhciBzdSBoaXN0b2dyYW1hIHkgZGFyc2UgaWRlYSB2aXN1YWwgZGUgc3VzIGZyZWN1ZW5jaWFzIHkgc2kgc3UgZGVuc2lkYWQgYcOxYWRpZGEgYWwgaGlzdG9ncmFtYSBwYXJlY2Ugc2VyIG5vcm1hbDsgbyBzZSBwdWVkZW4gaGFjZXIgKipwcnVlYmFzIGRlIG5vcm1hbGlkYWQgZGUgYm9uZGFkIGRlIGFqdXN0ZSBjb21vIHNoYXBpcm8qKiBkZSBub3JtYWxpZGFkIHF1ZSB0aWVuZSBidWVuYSBwb3RlbmNpYSBvIEFuZGVyc29uLURhcmxpbmcgbyBMaWxsaWVmb3JzLg0KDQpgYGB7cn0NCnNoYXBpcm8udGVzdChyZXNpZHVvcykNCmxpbGxpZS50ZXN0KHJlc2lkdW9zKQ0KYWQudGVzdChyZXNpZHVvcykNCmBgYA0KDQoqKlJlcHJvYmFkby4qKg0KDQpFbiB0b2RhcyBsYXMgcHJ1ZWJhcywgZWwgdmFsb3ItcCBvYnRlbmlkbyBlcyBzaWduaWZpY2F0aXZhbWVudGUgbWVub3IgcXVlIGN1YWxxdWllciBuaXZlbCBkZSBzaWduaWZpY2FuY2lhIGNvbcO6bm1lbnRlIHV0aWxpemFkbyAocG9yIGVqZW1wbG8sIDAuMDUpLiBQb3IgbG8gdGFudG8sICoqaGF5IHN1ZmljaWVudGUgZXZpZGVuY2lhIHBhcmEgcmVjaGF6YXIgbGEgaGlww7N0ZXNpcyBudWxhIGRlIG5vcm1hbGlkYWQgZW4gdG9kb3MgbG9zIGNhc29zLioqIEVzdG8gc3VnaWVyZSBxdWUgKipsb3MgcmVzaWR1b3Mgbm8gc2lndWVuIHVuYSBkaXN0cmlidWNpw7NuIG5vcm1hbCB5IHF1ZSBoYXkgZGVzdmlhY2lvbmVzIHNpZ25pZmljYXRpdmFzIGRlIGxhIG5vcm1hbGlkYWQuKioNCg0KRW4gZXN0ZSBjYXNvLCAqKk5PKiogcGFzYSBsYSBub3JtYWxpZGFkLCBhc2kgcXVlIHBvZGVtb3MgaGFjZXIgaW50ZXJ2YWxvcyBkZSBwcmVkaWNjacOzbiBkaXN0aW50b3MgYSBsb3MgZGUgbGEgZGlzdHJpYnVjacOzbiBub3JtYWwsIGxvcyBpbnRlcnZhbG9zIGRlIHByZWRpY2Npw7NuIGJhc2Fkb3MgZW4gbGEgZGlzdHJpYnVjacOzbiBub3JtYWwgcHVlZGVuIG5vIHNlciBhcHJvcGlhZG9zIGVuIGVzdGUgY2Fzby4gQWxndW5hcyBvcGNpb25lcyBwYXJhIGNvbnN0cnVpciBpbnRlcnZhbG9zIGRlIHByZWRpY2Npw7NuIGVuIHByZXNlbmNpYSBkZSByZXNpZHVvcyBubyBub3JtYWxlcyBzb24gKipCb290c3RyYXAqKiBjb21vIG1ldG9kbyBkZSByZW11ZXN0cmVvKiosIG8gdHJhbnNmb3JtYWNpb25lcyBwYXJhIG1lam9yYXIgbG9zIHJlc2lkdW9zOyoqIHBvciBlamVtcGxvIHBvZHJpYW1vcyBhanVzdGFyIHRyYW5zZm9ybWFjaW9uZXMgYW50ZXMgZGUgbW9kZWxhciBlbCBTQVJJTUEgbyBlbiBsb3MgcmVzaWR1b3MgdHJhbnNmb3JtYWRvcyBjb24gbGEgZnVuY2lvbiBib3hjb3ggZGUgbGEgbGlicmVyaWEgTUFTUy4NCg0KIyMjIyMgQUlDIHkgQklDLg0KDQpFeHRyYS4gKipDcml0ZXJpbyBkZSBJbmZvcm1hY2nDs24gZGUgQWthaWtlIChBSUMpIHkgZWwgQ3JpdGVyaW8gZGUgSW5mb3JtYWNpw7NuIEJheWVzaWFubyAoQklDKToqKiBUcmF0YXJlbW9zIGRlIGJ1c2NhciBlbCBtb2RlbG8gcXVlIHRlbmdhIGxvcyBtYXMgYmFqb3MgZGUgZXN0b3MgZW4gY29uanVudG8sIGVzdG9zIGNyaXRlcmlvcywgZWwgcHJpbWVybyBwZW5hbGl6YSBtZW5vcyBsYSBjb21wbGVqaWRhZCB5IGVsIHNlZ3VuZG8gbG8gaGFjZSBtYXMuDQoNCiMjIyMjIEZvcmVjYXN0Lg0KDQpEaWdhbW9zIHF1ZSB5YSB0ZW5lbW9zIHVuIG1vZGVsbyBxdWUgY3VtcGxlIGNvbiB0b2RvLCBhaG9yYSBzaWd1ZSBoYWNlciBwcmVkaWNjaW9uZXMsIGVzIGRlY2lyIHVzYXIgZWwgbW9kZWxvLCBoYXkgZGlmZXJlbnRlcyBmb3JtYXMgZGUgcHJlZGVjaXIsIHBlcm8gZW4gZXN0ZSBjYXNvIHVzYXJlbW9zIGxhcyBzaWd1aWVudGVzIHBhcXVldGVyaWFzLg0KDQpgYGB7cn0NCnByb25vc3RpY288LWZvcmVjYXN0KFNBUklNQSwgaCA9IDEyKQ0KcGxvdChwcm9ub3N0aWNvLCBtYWluID0gIlByb27Ds3N0aWNvIFNBUklNQSIsIHhsYWIgPSAiVGllbXBvIiwgeWxhYiA9ICJWYWxvcmVzIikNCmxlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBjKCJQcm9uw7NzdGljbyIsICJBcmVhIGRlIGNvbmZpYW56YSIpLCBjb2wgPSBjKCJibHVlIiwgImdyZXkiKSwgbHR5ID0gMToyKQ0KDQpgYGANCg==