Sección 7.1 Distribuciones de probabilidad

En un principio habíamos considerado modelos lineales en los que la salida o variable respuesta podía tomar una infinidad de valores dependiendo de los valores asignados a los predictores. Sin embargo ahora sera de interés considerar modelos en donde nos restringimos a que la variable de respuesta toma valores en una escala binaria. A manera de ejemplo, la respuesta puede ser estar “vivo” o “muerto”, “presento” o “no presente”, claramente estas respuesta no son cuantitativas, sin embargo podemos asignarles “éxito” o “fracaso” como términos genéricos de modo que así podamos codificar estas respuestas.

Para realizar esto, empezamos definiendo la variable aleatoria binaria \[ Z=\left\{\begin{array}{cc} 1& \text{si la respuesta es un exito}\\ 0 & \text{si la respuesta es un fracaso} \end{array}\right. \] con probabilidades \(\mathbb{P}(Z=1)=\pi\) y \(\mathbb{P}(Z=0)=1-\pi\). A manera de generalización, si hay contamos con \(n\) variables aleatoria binarias \(Z_1,\ldots,Z_n\) independientes con probabilidades \(\mathbb{P}(Z_i=1)=\pi_i\) y \(\mathbb{P}(Z_i=0)=1-\pi_i\), entonces su función conjunta de probabilidad es \[\prod_{j=1}^n \pi_j^{z_j}(1-\pi_j)^{1-z_j}= \exp\left[\sum_{j=1}^n z_j \log\left(\dfrac{\pi_j}{1-\pi_j}\right)+\sum_{j=1}^n \log(1-\pi_j)\right],\] donde el producto es consecuencia de la independencia de las \(Z_i\) y que \(\mathbb{P}(Z_i=z_i)=\pi_j^{z_j}(1-\pi_j)^{1-z_j}\), puesto que \(z_j\in\{0,1\}\). Adicional podemos notar que la función conjunta de probabilidad es un miembro de la familia exponencial. Notemos que si consideramos el caso en que todas las las \(\pi_j's\) con iguales, podemos definir la variable \[Y=\sum_{j=1}^n Z_j,\] que simplemente cuenta el numero de éxitos en \(n\) realizaciones, la cual como ya sabemos tiene distribución de probabilidad binomial de parámetros \(n\) y \(\pi\).

Por ultimo consideremos el caso de \(N\) variables aleatorias independientes \(Y_1,\ldots,Y_n\) correspondientes al numero de éxitos en \(N\) subgrupos diferentes, tal que \(Y_i\sim Bin(n_i,\pi_i)\), y por lo tanto la función de verosimilitud viene dada por: \[\begin{split} l(\pi_1,\ldots,\pi_n;y_1,\ldots,y_n)=\left[\sum_{j=1}^{N}y_j\log\left(\dfrac{\pi_j}{1-\pi_j}\right)+ n_j\log(1-\pi_j)+\log\binom{n_j}{y_j}\right]. \end{split}\]

Sección 7.2 Modelos Lineales Generalizados

Nuestro interés ahora será determinar la proporción de sucesos \(P_i=Y_i/n_i\) en cada subgrupo en términos de los factores de nivel (todos los posibles valores que toma la variable categórica) y otra variable explicativa que caracteriza al subgrupo en cuestión. Como \(\mathbb{E}(Y_i)=n_i\pi_i\), entonces \(\mathbb{E}(P_i)=\pi_i\), y modelamos las probabilidades \(\pi_i\) como \[g(\pi_i)=\textbf{x}_i^T\beta,\] donde \(\textbf{x}_i\) es un vector de variables explicativas (variables dummy para los factores de nivel), \(\beta\) es un vector de parámetros y \(g\) es una función de enlace (Link function).

Una función de enlace es aquella que transforma las probabilidades de los factores de nivel de de una variable de respuesta categórica en una escala continua. Una vez que se realiza la transformación. la relación entre los predictores y la respuesta puede ser modelada con una regresión lineal.

Un caso sencillo es el modelo lineal \[ \pi=\textbf{x}^T\beta. \] Aunque este modelo suele ser usado en algunas aplicaciones practicas, tiene la desventaja que aunque \(\pi\) es una probabilidad, los valores ajustados \(\textbf{x}^T\beta\), pueden llegar a ser mayores a 1 o menores a 0.

Así para garantizar que \(\pi\) este restringido al intervalo \([0,1]\), lo modelamos usando una función de distribución, de modo que \[\pi=\int_{-\infty}^t f(s)ds,\] donde \(f(s\geq 0)\) y \(\int_{-\infty}^{\infty}f(s)ds=1\). A la función de densidad \(f(s)\) se le llama distribución de tolerancia.

Sección 7.3 Modelos dosis respuesta

Históricamente uno de los primeros usos de modelos similares a la regresión para datos binomiales fue en resultados de bio ensayo. En estos modelos la respuesta era la proporción o porcentaje de éxitos; como por ejemplo, la proporción de animales experimentales asesinados por distintos niveles de dosis de una cierta sustancia toxica. Estos datos a veces se les denominan respuestas cuánticas. El objetivo aquí es describir la probabilidad de “éxito” \(\pi\), como una función de la dosis suministrada, \(x\); por ejemplo \(g(\pi)=\beta_0+\beta_1 x\).

Si la distribución de tolerancia \(f(s)\) es la distribución uniforme sobre el intervalo \([a,b]\), es decir \[ f(s)=\left\{ \begin{array}{cc} \dfrac{1}{b-a} & \text{ si } a\leq x\leq b\\ 0 & \text{ en otro caso} \end{array} \right., \] entonces \[ \pi=\int_{a}^x f(s)ds=\dfrac{x-a}{b-a}\text{ si } a\leq x\leq b.\\ \] Notemos que \[\pi=\dfrac{x-a}{b-a}=-\dfrac{a}{b-a}+x\dfrac{1}{b-a},\] definiendo \(\beta_0=-\dfrac{a}{b-a}\) y \(\beta_1=\dfrac{1}{b-a}\), se tiene que \(\pi=\beta_0+\beta_1 x\).

Así este modelo lineal es equivalente a usar como función enlace \(g(x)=x\) imponiendo restricciones sobre \(x\), \(\beta_0\) y \(\beta_1\) correspondientes a que \(a\leq x\leq b\). Este tipo de restricciones son las que no permiten que podamos aplicar de manera directa los métodos estándares para estimar \(\beta_0\) y \(\beta_1\).

Veremos ahora uno de los modelos mas útiles y mayor mente usados en en datos de bioensayo llamado modelo probit. En este modelo se usa la distribución normal como distribución de tolerancia, con lo cual \(\pi\) viene dado por:

\[ \pi=\dfrac{1}{\sigma\sqrt{2\pi}}\int_{-\infty}^x e^{-\frac{1}{2}\left(\frac{s-\mu}{\sigma}\right)^2} ds=\Phi\left(\dfrac{x-\mu}{\sigma}\right), \] donde \(\Phi\) denota la función de distribución para la distribución normal estándar. Así se sigue que: \[ \Phi^{-1}(\pi)=\beta_0+\beta_1 x, \] donde \(\beta_0=-\mu/\sigma\), \(\beta_1=1/\sigma\) y la función de enlace es la inversa de la función de distribución de la normal.

Nota: Estos modelos probit son usados en muchas áreas de biología y ciencias sociales en las cuales se les da una interpretación natural al modelo; por ejemplo si se está en un contexto biológico, \(x=\mu\) es llamada dosis letal media LD(50), por que esta corresponde da la dosis que puede esperar que acabe con la mita de los animales.

Otro modelo que nos da resultados muy similares al modelo probit, pero que computacionalmente es mas sencillo, es el modelo logístico o modelo logit. En este modelo la distribución de tolerancia es

\[ f(s)=\dfrac{\beta_1{\exp{(\beta_0+\beta_1 s)}}}{(1+\beta_1{\exp{(\beta_0+\beta_1 s)})^2}}, \] así que \[ \pi=\int_{-\infty}^x f(s)ds=\dfrac{\exp{(\beta_0+\beta1 x)}}{1+\exp{(\beta_0+\beta_1 x)}}, \] con lo cual nos la función de enlace \[ \log\left(\dfrac{\pi}{1-\pi}\right)=\beta_0+\beta_1 x. \] El término \(\log(\pi/(1-\pi))\) es llamado función logit. Este modelo logístico es ampliamente usado para datos binomiales

Otras modelos usados para datos respuesta-dosis, son por ejemplo si consideramos como distribución de tolerancia la distribución de valor extremo \[ f(s)=\beta_1\exp{[\beta_0+\beta_1 s-\exp{(\beta_0+\beta_1 s)}]} \] entonces \[ \pi=1-\exp{[-\exp{(\beta_0+\beta_1 x)}]}, \] de donde se sigue \[ \log{[-\log{(1-\pi)}]}=\beta_0+\beta_1 x. \] Aquí la función de enlace es \(g(x)=\log{[-\log{(1-x)}]}\) la cual se le llama función log log complementaria

Ejemplo 1: Mortalidad de escarabajos El siguiente conjunto de datos muestra el numero de escarabajos muertos después de cinco horas de exposición a gas de disulfuro de carbono en varias concentraciones.

Dosis<-c(1.6907,1.7242,1.7552,1.7842,1.8113,1.8369,1.8610,1.8839)
Poblacion<-c(59,60,62,56,63,59,62,60)
Muertes<-c(6,13,18,28,52,53,61,60)
Tabla1<-cbind(Dosis,Poblacion,Muertes)
Tabla1<-data.frame(Tabla1)
names(Tabla1)<-c("Dosis, x_i","Número de escarabajos, n_i", "Número de muertes, y_i")
Tabla1
plot(Dosis,Muertes/Poblacion,pch=20,cex=1.7,ylab="Proporción de muertes",sub=TeX(r'(Proporción de muertes $p_i=y_i/n_i$ vs dosis $x_i$)'))

Comentario: En este ejemplo estamos consideramos \(x_i\) como el logaritmo de la cantidad de disulfuro de carbono.

El propósito en este ejemplo será ajustar un modelo logístico. Como usaremos el modelo logístico, se tiene que las proporciones se expresan como \[ \pi_i=\log\left(\dfrac{\pi_i}{1-\pi_i}\right), \] con lo cual \[ \log\left(\dfrac{\pi_i}{1-\pi_i}\right)=\beta_0+\beta_1 x_i \] y \[ \log{(1-\pi_i)}=\log{[1+\exp{(\beta_0+\beta_1 x_i)}]}. \] Por otro lado, en un inicio habíamos encontrado que la función de log verosimilitud viene dada por \[ l(\pi_1,\ldots,\pi_n;y_1,\ldots,y_n)=\left[\sum_{j=1}^{N}y_j\log\left(\dfrac{\pi_j}{1-\pi_j}\right)+ n_j\log(1-\pi_j)+\log\binom{n_j}{y_j}\right] \] sustituyendo las expresiones ya encontradas, la log verosimilitud se reduce a \[ l(\pi_1,\ldots,\pi_n;y_1,\ldots,y_n)=\left[\sum_{j=1}^{N}y_j(\beta_0+\beta_1 x_j)+ n_j\log{[1+\exp{(\beta_0+\beta_1 x_i)}]}\log\binom{n_j}{y_j}\right]. \]. Derivando la log verosimilitud con respecto a \(\beta_0\) y \(\beta_1\), tenemos que los scores vienen dados por:

\[ \begin{split} U_1=&\dfrac{\partial l}{\partial \beta_0}=\sum_{i=1}^N \left(y_i-n_i\left[\dfrac{\exp{(\beta_0+\beta_1 x_i)}}{1+\exp{(\beta_0+\beta_1 x_i)}}\right]\right)=\sum_{i=1}^N(y_i-n_i\pi_i)\\ U_2=& \dfrac{\partial l}{\partial \beta_1}=\sum_{i=1}^N \left(y_i x_i-n_i x_i\left[\dfrac{\exp{(\beta_0+\beta_1 x_i)}}{1+\exp{(\beta_0+\beta_1 x_i)}}\right]\right)=\sum_{i=1}^N x_i(y_i-n_i\pi_i). \end{split} \] Similarmente realizando las respectivas cuentas, encontramos que la matriz de información es \[ J=\left[ \begin{array}{cc} \sum_{i=1}^N n_i\pi_i (1-\pi_i)&\sum_{i=1}^N n_i x_i\pi_i (1-\pi_i)\\ \sum_{i=1}^N n_i x_i\pi_i (1-\pi_i) & \sum_{i=1}^N n_i x_i^2\pi_i (1-\pi_i) \end{array} \right]. \] Por lo visto en el capitulo de estimación, sabemos que para encontrar los estimadores de máxima verosimilitud los podemos obtener iterativamente solucionando la ecuación \[ J^{(m-1)} \textbf{b}^m =J^{(m-1)}\textbf{b}^{(m-1)}+U^{(m-1)} \] donde el superindice \((m)\) indica la \(m\)-ésima aproximación y \(\textbf{b}\) es el vector de estimaciones.

Con las expresiones ya encontradas, procederemos a encontrar las estimaciones de los parámetros \(\beta_0\) y \(\beta_1\), siguiendo las ideas del capitulo de estimaciones.

Para ello con la siguiente función podremos realizar el numero de simulaciones que deseemos hasta encontrar las estimaciones entre dos iteraciones seguidas no varié mucho.

## Función para realizar estimación de máxima verosimilitud basada en los resultados del capitulo 4, la cual principalmente sigue la idea del algoritmo Newton Raphson.

# Parámetros que requiere esta función 
# num_itera = # de iteraciones que deseamos realizar para estimar los parámetros de Máxima verosimilitud.
# Poblaciones = Vector que contiene el tamaño de cada sub población para cada predictor.
# predictores = Vector de variables predictoras consideradas para cada sub población.
#respuestas = Vector de respuestas asociadas a cada sub población.

estimacion<-function(num_itera,b_inicial,Poblaciones,predictores,respuestas){
  for (i in 1:num_itera) {
      proporcion<-exp(b_inicial[1]+b_inicial[2]*predictores)/(1+exp(b_inicial[1]+b_inicial[2]*predictores)) 
      # Vector de la proporciones para cada sub población
  U0 <- sum(respuestas-Poblaciones*proporcion)
  U1 <- sum(predictores*(respuestas-Poblaciones*proporcion))
  U<-matrix(c(U0,U1),ncol=1,byrow = T)
  J_11 <- sum(Poblaciones*proporcion*(1-proporcion))
  J_12 <- sum(Poblaciones*predictores*proporcion*(1-proporcion))
  J_21 <- sum(Poblaciones*predictores*proporcion*(1-proporcion))
  J_22 <- sum(Poblaciones*predictores^2*proporcion*(1-proporcion))
  J<-matrix(c(J_11,J_12,J_21,J_22),ncol = 2,byrow = T)
  J_inv<-solve(J)
  b_inicial <- b_inicial + J_inv%*%U
  log_vero<-sum(respuestas*(b_inicial[1]+b_inicial[2]*predictores)-Poblaciones*log(1+exp(b_inicial[1]+b_inicial[2]*predictores)))
  y_estim<-Poblaciones*proporcion
  }
  ResumIte<-list(b_inicial,log_vero,J_inv,y_estim)
  return(ResumIte)
}
# los parámetros iniciales
b0<-matrix(c(0,0),ncol=1,byrow=T)
|              | Estimacion inicial| 1ra aprox    | 2da aprox    | 3ra aprox|
|-------------------|-------------|---------------|--------------|--------|
| ß_0               | 0           |-37.856        |-53.853        |-60.717 |
| ß_1               | 0           |21.337         |30.384         |34.270  |
| log-verosimilitud | -333.404    |-200.010       |-187.274       |-186.235|

Sección 7.4 Modelo de Regresión Logística General

El modelo de regresión logística lineal simple presentado antes,

\[ \log\left(\frac{\pi_i}{1-\pi_i}\right)=\beta_1+\beta_2 x_i \]

utilizado en el ejemplo de la mortalidad de los escarabajos es simplemente un caso especial del modelo de de regresión logística general: \[ logit(\pi_i)=\log\left(\frac{\pi_i}{1-\pi_i}\right)= x_{i}^{T}\beta, \] donde \(x_i\) es un vector de mediciones continuas correspondiente a variables regresoras y variables “dummy” correspondientes a niveles de factor, y \(\beta\) es el vector de parámetros. Este modelo es muy utilizado para utilizar datos que involucran variables de respuesta binarias o binomiales, así como varios regresores.

Estimadores de máxima verosimilitud de los parámetros \(\beta\), y en consecuencia, de las probabilidades \[ \pi_i=g(x_{i}^{T}\beta), \] se obtienen maximizando la función de log-verosimilitud dada por: \[ l(\pi;y)=\sum_{i=1}^{N}\left[y_i\log(\pi_i)+(n_i-y_i)\log(1-\pi_i)+\log{\binom{n_i}{y_i}}\right]. \] Dicha maximización se hace utilizando los métodos correspondientes.

El proceso de estimación es esencialmente el mismo siempre que los datos estén agrupados como frecuencias para cada patrón de covarianza (es decir, los datos están agrupados de acuerdo a si son observaciones con los mismos valores de todas las variables regresoras), o bien, si cada observación está codificada como un 0 o un 1, y su patrón de covarianza se enlistó de manera separada.

Si los datos pueden ser agrupados, entonces la respuesta \(Y_i\) representará el número de éxitos para el patrón de covarianza \(i\), y tal respuesta puede ser modelada por la distribución binomial. En cambio, si cada observación tiene un distinto patrón de covarianza, entonces \(n_i=1\) y la respuesta \(Y_i\) es binaria.

La devianza en este caso está dada por: \[ D=2\sum_{i=1}^{N}\left[y_i\log\frac{y_i}{\hat{y_i}}+(n_i-y_i)\log\frac {n-y_i}{n-\hat{y_i}}\right] \] Tal expresión puede ser reescrita como:

\[ D=2\sum o\log\frac{o}{e}, \] donde \(o\) denota las frecuencias observadas \(y_i\) y \((n_i-y_i)\), y \(e\) denota las correspondientes frecuencias estimadas esperadas, o mejor dicho, los valores ajustados del modelo, $=n_i y (n_i-)=(n_i-n_i). La suma es sobre todos los posibles valores de \(i\).

Notamos que la deviance \(D\) no involucra ningún “nuisance parameter”, como el \(\sigma^2\) en los modelos con respuestas normales. Por lo tanto, los test de bondad de ajuste pueden ser evaluados y las hipótesis pueden ser testeadas directamente utilizando la aproximación de la devianza: \[ D\sim\chi^2(N-p), \] donde \(p\) es el número de parámetros estimado y \(N\) el número de patrones de covarianza.

Cabe destacar que los métodos de estimación y las distribuciones muestrales utilizadas para inferencia dependen de resultados asintóticos. Para pequeños estudios donde hay pocas observaciones para cada patrón de covarianza, los resultados asintóticos podrían ser malos.

Ejemplo 2: Embriogénsis de Anteras

Los siguientes datos muestran respuestas \(y_{jk}\) que representan el número de anteras embriogénicas de la especie de planta \(Datura innoxia\) que fueron obtenidas cuando una cantidad \(n_{jk}\) de anteras fueron preparadas bajo varias condiciones diferentes. Hay un factor cualitativo con dos niveles que da origen a 2 grupos \(j\in{1,2}\) de anteras, el primero representa a las anteras del grupo control mientras que el segundo representa a las anteras del grupo tratado. Las primeras fueron tratadas coon un almacenamiento de 3 grados Celsius por 48 horas, mientras que las anteras del grupo control estuvieorn almacenadas con condiciones normales.

Así mismo, los dos grupos de anteras almacenadas en condiciones de control y de tratamiento fueron expuestas a los efectos de una fuerza centrífuga, la cual es una variable aleatoria continua. En este caso, hubieron tres valores de fuerza centrífuga a la que los grupos fueron expuestos. La idea es comparar los efectos del control y del tratamiento en las proporciones después de haber sido ajustadas a una furza centrífuga:

Fuerza Centrífuga (g)
Condicion de Almacenamiento 40 150 350
Grupo Control \(y_{1k}\) 55 52 57
\(n_{1k}\) 102 99 108
Grupo en tratamiento \(y_{2k}\) 55 50 50
\(n_{2k}\) 76 81 90

Las proporciones \(p_{jk}=\frac{y_{jk}}{n_{jk}}\) en los grupos de control y de tratamiento son graficados contra la variable \(x_k\) que representa el logaritmo de la fuerza centrífuga. Las proporciones de respuesta parecen ser más altas en el grupo tratado que en el grupo control, y al menos para el grupo tratado, la respuesta decrece con la fuerza centrífuga.

Compararemos ahora tres modelos logísticos para \(\pi_{ij}\), la probabilidad de las anteras de ser embriogénicas, donde \(j=1\) para el grupo control y \(j=2\) para el grupo tratado, donde \(j=1\) para el grupo control y \(j=2\) para el grupo tratado, y \(x_1=\log40=3.689\), \(x_2=log 150=5.011\), y \(x_3=log 350=5.868\).

LogFC<-log(c(40,150,350))
LogFC

controly<-c(55,52,57)
controln<-c(102,99,108)
p1<-controly/controln
p1
tratamientoy<-c(55,50,50)
tratamienton<-c(76,81,90)
p2<-tratamientoy/tratamienton
p2

plot(LogFC,p2,ylim=c(0.5,0.8),pch=18,cex=1.5, xlab="",ylab="")
par(new=T)
plot(LogFC,p1,ylim=c(0.5,0.8),pch=19,cex=1.3,xlab="Log-Fuerza Centrífuga", ylab="Proporción que germinó")

\[ \begin{split} Modelo1: logit \pi_{jk}=\alpha_j+\beta_j x_k \text{ es decir, diferentes interceptos y pendientes};\\ &Modelo2: logit \pi_{jk}=\alpha_j+\beta x_k \text{ es decir, diferentes interceptos pero misma pendiente};\\ &Modelo3: logit \pi_{jk}=\alpha+\beta x_k \text{ es decir, mismo intercepto y pendiente.}\\ \end{split} \] Estos modelos fueron ajustados utilizando máxima verosimilitud. Los resultados resumidos se pueden ver en la siguiente tabla:

Modelo 1 Modelo 2 Modelo 3
\(a_1\)=0.234 (0.628) \(a_1\)=0.877 (0.487) \(a\)=1.021 (0.481)
\(a_2-a_1\)=1.977 (0.998) \(a_2-a_1\)=0.407 (0.175) \(b\)=-0.148 (0.096)
\(b_1\)=-0.023 (0.127) \(b\)= -0.155
\(b2-b1\)=-0.319 (0.199)
\(D_1\)=0.028 \(D_2\)=2.619 \(D_3\)=3.110

Para probar la hipótesis nula de que la pendiente es la misma para los grupos de tratamiento y control, utilizamos la resta de devianzas \(D_2-D_1=2.591\). Extrayendo los cuantiles necesarios para una distribución \(\chi^2(1)\), el nivel de significancia está entre 0.1 y 0.2, y por lo tanto podríamos concluir que los datos nos dan poca evidencia en contra de que las pendientes sean iguales. Sin embargo, el poder de este test y las estimaciones para el Modelo 1 suguieren que aunque la pendiente para el grupo control puede ser cero, la pendiente para el grupo con el tratamiento es negativa.

Comparación de devianzas de los modelos 2 y 3 nos dan una prueba para la igualdad de los efectos de la fuerza centrífuca del grupo control y del grupo tratado: D_3-D_2=0.491, lo cual es consistente con la hipótesis de que los efectos de almacenamiento no son diferentes. Las proporciones observadas y los correspondientes valores ajustdos para los modelos 1 y 2 se muestran en la tabla siguiente:

Condición de almacenamiento Número del regresor Frecuencia observada Frecuencias esperadas
Modelo 1 Modelo 2 Modelo 3
Control \(x_1\) 55 54.82 58.75 62.91
\(x_2\) 52 52.47 52.03 56.40
\(x_3\) 57 56.72 53.22 58.18
Tratamiento \(x_1\) 55 54.83 51.01 46.88
\(x_2\) 50 50.43 50.59 46.14
\(x_3\) 50 49.74 53.40 48.49

Es claro que el modelo 1 ajusta muy bien los datos, sin embargo, no es de sorprender pues en dicho modelo se utilizaron 4 parámetros para describir seis datos, por lo que se está presentando un sobreajuste considerable.

Sección 7.5 Estadísticos de bondad de ajuste

En lugar de utilizar estimación por máxima verosimilitud, podríamos utilizar los parámetros utilizando mínimos cuadrados ponderados. Es decir, minimizando a siguiente suma de cuadrados ponderada: \[ S_{w}=\sum_{i=1}^N\frac{(y_i-n_i\pi_i)^2}{n_i\pi_i(1-\pi_i)}, \] puesto que \(E(Y_i)=n_i\pi_i\) y \(Var(Y_i)=n_i\pi_i(1-\pi_i)\). Lo anterior es equivalente a minimizar el estadístico Chi-cuadrado de Pearson, dado por: \[ X^{2}=\sum\frac{(o-e)^2}{e}, \] donde \(o\) representa las frecuencias observadas, \(e\) representa las frecuencias esperadas y la suma es sobre todos los posibles valores de \(i\).

Cuando \(X^2\) es evaluado en las frecuencias estimadas esperadas, el estadístico es: \[ X^2=\sum_{i=1}^N \frac{(y_i-n_i\hat{\pi_i})^2}{n_i\hat{\pi_i}(1-\hat{\pi_i})}, \] el cual es asintóticamente equivalente a la devianza descrita en la sección anterior, ajustada a este contexto:

\[ D=2\sum_{i=1}^{N}\left[y_i\log\frac{y_i}{n_i\hat{\pi_i}}+(n_i-y_i)\log\frac {n-y_i}{n-n_i\hat{\pi_i}}\right] \]

La prueba de la relación entre el estadístico \(X^2\) y la devianza \(D\) anterior, usa series de Taylor.

La distribución asintótica de \(D\), bajo la hipótesis de que el modelo es correcto, es \(D\sim \chi^2(N-p)\), y por lo tanto según lo anterior, \(X^2\sim\chi^2(N-p)\). La elección entre \(D\) y \(X^2\) dependerá de la adecuación de la aproximación a la distribución anterior.

Se ha encontrado evidencia de que \(X^2\) es a menudo mejor que \(D\), puesto que \(D\) es indebidamente influído por frecuencias muy pequeñas. Además, es sabido que ambas aproximaciones serán malas si las frecuencias esperadas son demasiado pequeñas.

En particular, si cada observación tiene un patrón de covarianzas de tal forma que \(y_i\) es cero o 1 (binario), entonces ninguno de los estadísticos anteriores nos da una medida útil de ajuste. Esto puede suceder si las variables regresoras son todas continuas, por ejemplo.

En este caso, de acuerdo a Hosmer y Lemeshow, la mejor manera de abordar esta situación es agrupar las observaciones en categorías con base en sus probabilidades predichas. Típicamente 10 grupos son usados con aproximadamente una cantidad igual de observaciones en cada grupo. Los números de éxitos y fracazos observados en cada uno de los, digamos, \(g\) distintos grupos, son resumidos como en la tabla 7.1. Luego, el estadístico chi-cuadrada de Pearson para una tabla como la anterior se puede calcular y usar como una medida de ajuste.

A tal estadístico se le denomina estadístico Hosmer-Lemeshow, y se denota por \(X^2_{HL}\). Se ha encontrado que la distribución muestral de este estadístico es aproximadamente \(\chi^2(g-2)\).

A menudo la función de log-verosimilitud para el modelo ajustado es comparada con la función de log-verosimilitud para un modelo minimal, en el cual los valores \(\pi_i\) son todos iguales (en contraste con el modelo saturado que es usado para definir la devianza). Bajo el modelo minimal, \[ \pi=\frac{\sum y_i}{\sum n_i} \]

Así, si denotamos por \(\hat{\pi_i}\) al valor estimado de la probabilidad para \(Y_i\) bajo el modelo de interés (de tal forma que \(\hat{y_i}=n_i\hat{\pi_{i}}\)), el estadístico definido por \[ C=2[l(\hat{\pi};y)-l(\pi;y)] \] donde \(l\) es la función de log-verosimilitud, se conoce como el estadístico de cociente de verosimilitudes chi-cuadrado.

Se puede ver que la distribución muestral aproximada para \(C\) es \(\chi^2(p-1)\) si todos los \(p\) parámetros, excepto el intercepto, son cero. De otra forma, \(C\) tendrá una distribución no central. Así, \(C\) es un estadístico de prueba para la hipótesis de que ninguna de las variables explicativas es necesaria para un modelo sencillo.

Por último, de manera análoga al coeficiente de determinación \(R^2\) de los modelos de regresión múltiple, otro estadístico a veces utilizado es el “pseudo R^2”: \[ pseudo R^2=\frac{l(\pi;y)-l(\hat{\pi};y)}{l(\pi;y)}, \] el cual representa la mejora proporcional en la función de log-verosimilitud debida a los términos en el modelo de interés, comparado con el modelo minimal. Este es producido por algunos programas estadísticos como un estadístico de bondad de ajuste.

Sección 7.6 Residuales

Existen dos tipos de residuales principales para \(D\) y \(X^2\) en el modelo de regresión logística. Si hay \(m\) patrones de los regresores, entonces se peuden calcular \(m\) residuales. Sea \(Y_k\) la cantidad de éxitos, \(n_k\) la cantidad de realizaciones y \(\hat \pi_k\) la probabilidad estimada de éxito para el \(k\)-ésimo patrón de regresores. Definimos el residual de Pearson o residual ji cuadrada como,

\[ X_k = \frac{(y_k - n_k\hat\pi_k)}{\sqrt{n_k \hat\pi_k(1-\hat\pi_k)}}, \qquad k = 1, \dots, m. \]

Con esto, tenemos, por la definición antoriormente dada del estadístico \(X^2\) de bondad de ajuste de Pearson que

\[ \sum_{k=1}^m X_k^2 = X^2. \]

Los residuales estandarizados de Pearson son,

\[ r_{Pk} = \frac{X_k}{\sqrt{1 - h_k}}, \]

donde \(h_k\) es el apalancamoento que se obtiene de la matriz hat del modelo.

Los residuales de devianza pueden ser definidos de manera similar,

\[ d_k = \text{sign}(y_k - n_k \hat \pi_k) \left\{ 2 \left[ y_k \log \left( \frac{y_k}{n_K\hat\pi_k}\right) + (n_k - y_k)\log \left( \frac{n_k - y_k}{ n_k - n_k \hat \pi_k } \right) \right] \right\}^{1/2}, \] donde los términos $(y_k - n_k _k) $ garantizan que \(d_k\) tenga el mismo que \(X_k\). De la definición de la devianza podemos ver que

\[ D = \sum_{k=1}^m d_k^2. \]

Los residuales de devianza estandarizados son

\[r_{Dk} = \frac{d_k}{\sqrt{1 - h_k}}.\]

Al igual que en el caso de la regresión lineal, los residules de Pearson y de devianza pueden ser usados para verificar el ajuste del modelo y el cumplimiento de los supuestos. Ejemplos de usos son graficarlos contra los regresores, o gráficos de normalidad, ya que cuando la caantidad de datos es lo suficientemente grande, los residuales se comportan aproximadamente normales.

Si los datos son binarios o si hay una cantidad relativamente pequeña de observaciones por cada patrón de los regresores, entonces las gráficas de residuales serán no informativas, y por lo tanto habrá que recurrir a otros diagnósticos.

Sección 7.7 Otros diagnósticos

Existen estadísticos para detectar observaciones influyentes en la regresión logística (los análogos para la regresión lineal múltiple se exponen en la sección 6 del libro). En el caso de regresión lineal múltiple, estso estadísticos llamados delta-beta, delta-devianza y delta-ji cuadrada, es simplemente la diferencia entre el estimador calculador usando todos los puntos observados y el estimador calculado quitando uno de los puntos, similar a los residuales PRESS. Por ejemplo, el estadístico delta-beta es,

\[ \Delta_i \hat \beta_j = b_j - b_{j(i)}, \]

donde \(b_j\) es el estimador de \(\beta_j\) usando todos los datos y \(\beta_{j(i)}\) es el estimador obtenido al quitar la \(i\)-ésima observación. En el caso de la regresión logística es posible encontrar estadísticos similares para medir el nivel de ajuste del modelo.

Cuando tenemos respuestas binarias, hay más cosas que considerar, lo primero es la elección de nuestra función liga. Un enfoque es considerar la familia general de funciones

\[ g(\pi,\alpha) = \log\left[ \frac{(1-\pi)^{-\alpha} -1}{\alpha} \right]. \]

Cuando \(\alpha = 1\), entonces \(g(\pi)= \log[\pi/(1-\pi)]\), la función logit. Cuando \(\alpha\to 0\), \(g(\pi) \to \log[-\log(1-\pi)]\), la función log-log complementaria. En principio, un valor óptimo de \(\alpha\) puede ser estimado de los dartos, pero el proceso requiere varios pasos. Como no existe un software adecuado para encontrar a \(\alpha\), se recomienda experimentar con diversas funciones liga.

El segundo problema al evaluar la adecuación de los modelos para datos binarios es la sobredispersión. Los valores observados \(Y_i\) podrían tener una varianza más grande que la varianza teórica de la distribución binomial propuesta (debido a que en esta distribución, un único parámetro determina la media y la varianza). Esto puede ser un indicaador de que la devianza es más grande que el valor esperado de \(N-p\), y podría ser causado por que el modelo está subespecificado, o porque tiene una estructura más compleja que el modelo propuesto.

Una alternativa para solucionar este problema es incorporar un parámetro extra \(\phi\) en el modelo, de forma que \(Var(Y_i) = n_i\pi_i(1-\pi_i)\theta\), en R, esto se logra al especificar un modelo cuasibinomial en lugar de binomial en la función `glm. Una posible explicación de la sobredispersión de los datos, es que las observaciones en realidad no sean independientes, lo que causa que en ciertos patrones del regresor se tenga una menor cantidad de observaciones efectivas al existir correlación.

Sección 7.8 Ejemplo: Senilidad y WAIS

Se realizó un examen psiquiátrico a una muestra de personas mayores para determinar qué síntomas de senilidad presentaban. Otras medidas tomadas al mismo tiempo incluyeron el puntaje de un subconjunto en la Escala de Inteeligencia Adulta de Wechsler (WAIS). Los valores registrados se encuentran en la siguiente tabla (\(s\) es la presencia de síntomas de senilidad y \(x\) el WAIS). Nos interesa modelar \(s\) como una función de \(x\).

x s x s x s x s x s
9 1 7 1 7 0 17 0 13 0
13 1 5 1 16 0 14 0 13 0
6 1 14 1 9 0 19 0 9 0
8 1 13 0 9 0 9 0 15 0
10 1 16 0 11 0 11 0 10 0
4 1 10 0 13 0 14 0 11 0
14 1 12 0 15 0 10 0 12 0
8 1 11 0 13 0 16 0 4 0
11 1 14 0 10 0 10 0 14 0
7 1 15 0 11 0 16 0 20 0
9 1 18 0 6 0 14 0

En este caso, como hay un solo regresor, los patrones de regresores son simplemente los niveles de \(x\). Estos se resumen en la tabla a continuación.

x y n \(\hat\pi\) X d
4 1 2 0.751 -0.826 -0.766
5 0 1 0.687 0.675 0.866
6 1 2 0.614 -0.33 -0.326
7 1 3 0.535 0.458 0.464
8 0 2 0.454 1.551 1.777
9 4 6 0.376 -0.214 -0.216
10 5 6 0.303 -0.728 -0.771
11 5 6 0.24 -0.419 -0.436
12 2 2 0.186 -0.675 -0.906
13 5 6 0.142 0.176 0.172
14 5 7 0.107 1.535 1.306
15 3 3 0.08 -0.509 -0.705
16 4 4 0.059 -0.5 -0.696
17 1 1 0.043 -0.213 -0.297
18 1 1 0.032 -0.181 -0.254
19 1 1 0.023 -0.154 -0.216
20 1 1 0.017 -0.131 -0.184
Suma 40 54
Suma de cuadrados 8.084* 9.418*

El modelo de regesión ajustado

\[ \log\left( \frac{\pi_i}{1 - \pi_i} \right) = \beta_1 + \beta_2 x_i; \qquad Y_i \sim \text{Bin}(n_i,\pi_i) \quad i = 1, \dots, m, \]

fue ajustado con los siguientes resultados:

\(b_1 = 2.404\), con error estándar se\((b_1) = 1.192\); \(b_2 = -0.3235\), con error estándar se\((b_2) = 0.1140\); \(X^2 = \sum X_i^2 = 8.083\), y \(D = \sum d_i^2 = 9.419\).

Como hay \(m=17\) patrones de covariantes y \(p=2\) parámetros, \(X^2\) y \(D\) pueden ser comparados con \(\chi^2_{15}\).

La siguiente es la gráfica de niveles del regresor vs. frecuencia observada.

library(dplyr)
x <- c(9, 13, 6, 8, 10, 4, 14, 8, 11, 7, 9, 7, 5, 14, 13, 16, 10, 12, 11, 14, 15, 18, 7, 16, 9, 9, 11, 13, 15, 13, 10, 11, 6, 17, 14, 19, 9, 11, 14, 10, 16, 10, 16, 14, 13, 13, 9, 15, 10, 11, 12, 4, 14, 20)
s <- c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

data <- data.frame( cbind(x,s))
colnames(data) <- c("x", "s")

gdata <- group_by(data,x)
resumen <- summarize(gdata, sum=sum(s), n=n(), pi=sum(s)/n)

plot(resumen$x,resumen$pi, xlab="Puntaje WAIS", ylab="Proporción con síntomas")

exito <- as.character(s)

Ajustamos el modelo con la función glm.

res.glm <- glm(data$s ~ data$x, family=binomial(link="logit"))
summary(res.glm)

Gráfica de la curva logística contra los datos observados. Podemos notar que el ajuste es mejor para valores más grandes del regresor.

fit <- (exp( res.glm$coefficients[1] + res.glm$coefficients[2]*resumen$x ) ) / (( 1 + exp( res.glm$coefficients[1] + res.glm$coefficients[2]*resumen$x ) ))

plot(resumen$x,resumen$pi, xlab="Puntaje WAIS", ylab="Proporción con síntomas")
lines(resumen$x, fit )
resumen

Como en cada nivel del regresor hay pocas obervaciones, podríamos usar el enfoque de Hosmer-Lemeshow para evaluar el ajuste. En la siguiente tabla se muestra el resumen del método para \(g=3\) categorías.

Values of \(\hat \pi\) \(\le 0.107\) 0.108 - 0.303 > 0.303
Corresponding values of x 14 - 20 10 - 13 4 - 9
Number of people o 2 3 9
with symptoms e 1.335 4.479 8.186
Number of people o 16 17 7
without symptoms e 16.665 15.521 7.814
Total number of people 18 20 16

El estadístico de Hosmer-lemeshow es obtenido al calcular \(X^2 = \sum \frac{(o-e)^2}{e}\), con esto obtenemos \(X_{HL}^2 = 1.15\), que no es tan siginificativo comparado con una distribución \(\chi^2_1\).

Extra: Ejemplo con base de datos Titanic

setwd("C:\\Users\\Esaúl\\Documents\\Maestría en Probabilidad y Estadística\\2 Segundo semestre\\Modelos estadísticos I\\Presentación final")
titanic <- read.csv("titanic.csv")
head(titanic)

Ajustamos un modelo de regresión logística para explicar la supervivencia en función de la edad.

modelo.titanic <- glm(titanic$Survived ~ titanic$Age, family=binomial(link="logit"))
summary(modelo.titanic)
gtit <- group_by(titanic,Age)
resumen.tit <- summarize(gtit, Exitos=sum(Survived), n=n(), pi=sum(Survived)/n)
resumen.tit
fit.tit <- (exp( res.glm$coefficients[1] + res.glm$coefficients[2]*resumen.tit$Age ) ) / (( 1 + exp( res.glm$coefficients[1] + res.glm$coefficients[2]*resumen.tit$Age ) ))

plot(resumen.tit$Age,resumen.tit$pi, xlab="Edad", ylab="Proporción de supervivientes")
lines(resumen.tit$Age, fit.tit )
LS0tCnRpdGxlOiAiVmFyaWFibGVzIGJpbmFyaWFzIHkgcmVncmVzacOzbiBsb2fDrXN0aWNhIgphdXRob3I6ICJKdWFuIEVzYXVsLCBJcnZpbmcgUm9zYXMgeSBEYW5pZWwgTWFydGluZXoiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCiMjIyMgKipTZWNjacOzbiA3LjEgRGlzdHJpYnVjaW9uZXMgZGUgcHJvYmFiaWxpZGFkKioKCkVuIHVuIHByaW5jaXBpbyBoYWLDrWFtb3MgY29uc2lkZXJhZG8gbW9kZWxvcyBsaW5lYWxlcyBlbiBsb3MgcXVlIGxhCnNhbGlkYSBvIHZhcmlhYmxlIHJlc3B1ZXN0YSBwb2TDrWEgdG9tYXIgdW5hIGluZmluaWRhZCBkZSB2YWxvcmVzCmRlcGVuZGllbmRvIGRlIGxvcyB2YWxvcmVzIGFzaWduYWRvcyBhIGxvcyBwcmVkaWN0b3Jlcy4gU2luIGVtYmFyZ28KYWhvcmEgc2VyYSBkZSBpbnRlcsOpcyBjb25zaWRlcmFyIG1vZGVsb3MgZW4gZG9uZGUgbm9zIHJlc3RyaW5naW1vcyBhIHF1ZQpsYSB2YXJpYWJsZSBkZSByZXNwdWVzdGEgdG9tYSB2YWxvcmVzIGVuIHVuYSBlc2NhbGEgYmluYXJpYS4gQSBtYW5lcmEgZGUKZWplbXBsbywgbGEgcmVzcHVlc3RhIHB1ZWRlIHNlciBlc3RhciAidml2byIgbyAibXVlcnRvIiwgInByZXNlbnRvIiBvCiJubyBwcmVzZW50ZSIsIGNsYXJhbWVudGUgZXN0YXMgcmVzcHVlc3RhIG5vIHNvbiBjdWFudGl0YXRpdmFzLCBzaW4KZW1iYXJnbyBwb2RlbW9zIGFzaWduYXJsZXMgIsOpeGl0byIgbyAiZnJhY2FzbyIgY29tbyB0w6lybWlub3MgZ2Vuw6lyaWNvcwpkZSBtb2RvIHF1ZSBhc8OtIHBvZGFtb3MgY29kaWZpY2FyIGVzdGFzIHJlc3B1ZXN0YXMuCgpQYXJhIHJlYWxpemFyIGVzdG8sIGVtcGV6YW1vcyBkZWZpbmllbmRvICoqbGEgdmFyaWFibGUgYWxlYXRvcmlhCmJpbmFyaWEqKiAkJApaPVxsZWZ0XHtcYmVnaW57YXJyYXl9e2NjfQoxJiBcdGV4dHtzaSBsYSByZXNwdWVzdGEgZXMgdW4gZXhpdG99XFwKMCAmIFx0ZXh0e3NpIGxhIHJlc3B1ZXN0YSBlcyB1biBmcmFjYXNvfQpcZW5ke2FycmF5fVxyaWdodC4KJCQgY29uIHByb2JhYmlsaWRhZGVzICRcbWF0aGJie1B9KFo9MSk9XHBpJCB5ICRcbWF0aGJie1B9KFo9MCk9MS1ccGkkLiBBCm1hbmVyYSBkZSBnZW5lcmFsaXphY2nDs24sIHNpIGhheSBjb250YW1vcyBjb24gJG4kIHZhcmlhYmxlcyBhbGVhdG9yaWEKYmluYXJpYXMgJFpfMSxcbGRvdHMsWl9uJCBpbmRlcGVuZGllbnRlcyBjb24gcHJvYmFiaWxpZGFkZXMKJFxtYXRoYmJ7UH0oWl9pPTEpPVxwaV9pJCB5ICRcbWF0aGJie1B9KFpfaT0wKT0xLVxwaV9pJCwgZW50b25jZXMgc3UKZnVuY2nDs24gY29uanVudGEgZGUgcHJvYmFiaWxpZGFkIGVzCiQkXHByb2Rfe2o9MX1ebiBccGlfal57el9qfSgxLVxwaV9qKV57MS16X2p9PSBcZXhwXGxlZnRbXHN1bV97aj0xfV5uIHpfaiBcbG9nXGxlZnQoXGRmcmFje1xwaV9qfXsxLVxwaV9qfVxyaWdodCkrXHN1bV97aj0xfV5uIFxsb2coMS1ccGlfailccmlnaHRdLCQkCmRvbmRlIGVsIHByb2R1Y3RvIGVzIGNvbnNlY3VlbmNpYSBkZSBsYSBpbmRlcGVuZGVuY2lhIGRlIGxhcyAkWl9pJCB5IHF1ZQokXG1hdGhiYntQfShaX2k9el9pKT1ccGlfal57el9qfSgxLVxwaV9qKV57MS16X2p9JCwgcHVlc3RvIHF1ZQokel9qXGluXHswLDFcfSQuIEFkaWNpb25hbCBwb2RlbW9zIG5vdGFyIHF1ZSBsYSBmdW5jacOzbiBjb25qdW50YSBkZQpwcm9iYWJpbGlkYWQgZXMgdW4gbWllbWJybyBkZSBsYSBmYW1pbGlhIGV4cG9uZW5jaWFsLiBOb3RlbW9zIHF1ZSBzaQpjb25zaWRlcmFtb3MgZWwgY2FzbyBlbiBxdWUgdG9kYXMgbGFzIGxhcyAkXHBpX2oncyQgY29uIGlndWFsZXMsIHBvZGVtb3MKZGVmaW5pciBsYSB2YXJpYWJsZSAkJFk9XHN1bV97aj0xfV5uIFpfaiwkJCBxdWUgc2ltcGxlbWVudGUgY3VlbnRhIGVsCm51bWVybyBkZSDDqXhpdG9zIGVuICRuJCByZWFsaXphY2lvbmVzLCBsYSBjdWFsIGNvbW8geWEgc2FiZW1vcyB0aWVuZQpkaXN0cmlidWNpw7NuIGRlIHByb2JhYmlsaWRhZCBiaW5vbWlhbCBkZSBwYXLDoW1ldHJvcyAkbiQgeSAkXHBpJC4KClBvciB1bHRpbW8gY29uc2lkZXJlbW9zIGVsIGNhc28gZGUgJE4kIHZhcmlhYmxlcyBhbGVhdG9yaWFzCmluZGVwZW5kaWVudGVzICRZXzEsXGxkb3RzLFlfbiQgY29ycmVzcG9uZGllbnRlcyBhbCBudW1lcm8gZGUgw6l4aXRvcyBlbgokTiQgc3ViZ3J1cG9zIGRpZmVyZW50ZXMsIHRhbCBxdWUgJFlfaVxzaW0gQmluKG5faSxccGlfaSkkLCB5IHBvciBsbwp0YW50byBsYSBmdW5jacOzbiBkZSB2ZXJvc2ltaWxpdHVkIHZpZW5lIGRhZGEgcG9yOiAkJFxiZWdpbntzcGxpdH0KbChccGlfMSxcbGRvdHMsXHBpX247eV8xLFxsZG90cyx5X24pPVxsZWZ0W1xzdW1fe2o9MX1ee059eV9qXGxvZ1xsZWZ0KFxkZnJhY3tccGlfan17MS1ccGlfan1ccmlnaHQpKyAgbl9qXGxvZygxLVxwaV9qKStcbG9nXGJpbm9te25fan17eV9qfVxyaWdodF0uClxlbmR7c3BsaXR9JCQKCiMjIyMgKipTZWNjacOzbiA3LjIgTW9kZWxvcyBMaW5lYWxlcyBHZW5lcmFsaXphZG9zKioKCk51ZXN0cm8gaW50ZXLDqXMgYWhvcmEgc2Vyw6EgZGV0ZXJtaW5hciBsYSBwcm9wb3JjacOzbiBkZSBzdWNlc29zCiRQX2k9WV9pL25faSQgZW4gY2FkYSBzdWJncnVwbyBlbiB0w6lybWlub3MgZGUgbG9zIGZhY3RvcmVzIGRlIG5pdmVsCih0b2RvcyBsb3MgcG9zaWJsZXMgdmFsb3JlcyBxdWUgdG9tYSBsYSB2YXJpYWJsZSBjYXRlZ8OzcmljYSkgeSBvdHJhCnZhcmlhYmxlIGV4cGxpY2F0aXZhIHF1ZSBjYXJhY3Rlcml6YSBhbCBzdWJncnVwbyBlbiBjdWVzdGnDs24uIENvbW8KJFxtYXRoYmJ7RX0oWV9pKT1uX2lccGlfaSQsIGVudG9uY2VzICRcbWF0aGJie0V9KFBfaSk9XHBpX2kkLCB5Cm1vZGVsYW1vcyBsYXMgcHJvYmFiaWxpZGFkZXMgJFxwaV9pJCBjb21vCiQkZyhccGlfaSk9XHRleHRiZnt4fV9pXlRcYmV0YSwkJCBkb25kZSAkXHRleHRiZnt4fV9pJCBlcyB1biB2ZWN0b3IgZGUKdmFyaWFibGVzIGV4cGxpY2F0aXZhcyAodmFyaWFibGVzIGR1bW15IHBhcmEgbG9zIGZhY3RvcmVzIGRlIG5pdmVsKSwKJFxiZXRhJCBlcyB1biB2ZWN0b3IgZGUgcGFyw6FtZXRyb3MgeSAkZyQgZXMgdW5hIGZ1bmNpw7NuIGRlIGVubGFjZSAoTGluawpmdW5jdGlvbikuCgpVbmEgKipmdW5jacOzbiBkZSBlbmxhY2UqKiBlcyBhcXVlbGxhIHF1ZSAqdHJhbnNmb3JtYSBsYXMgcHJvYmFiaWxpZGFkZXMKZGUgbG9zIGZhY3RvcmVzIGRlIG5pdmVsIGRlIGRlIHVuYSB2YXJpYWJsZSBkZSByZXNwdWVzdGEgY2F0ZWfDs3JpY2EgZW4KdW5hIGVzY2FsYSBjb250aW51YSouIFVuYSB2ZXogcXVlIHNlIHJlYWxpemEgbGEgdHJhbnNmb3JtYWNpw7NuLiBsYQpyZWxhY2nDs24gZW50cmUgbG9zIHByZWRpY3RvcmVzIHkgbGEgcmVzcHVlc3RhIHB1ZWRlIHNlciBtb2RlbGFkYSBjb24gdW5hCnJlZ3Jlc2nDs24gbGluZWFsLgoKVW4gY2FzbyBzZW5jaWxsbyBlcyBlbCAqKm1vZGVsbyBsaW5lYWwqKiAkJApccGk9XHRleHRiZnt4fV5UXGJldGEuCiQkIEF1bnF1ZSBlc3RlIG1vZGVsbyBzdWVsZSBzZXIgdXNhZG8gZW4gYWxndW5hcyBhcGxpY2FjaW9uZXMgcHJhY3RpY2FzLAp0aWVuZSBsYSBkZXN2ZW50YWphIHF1ZSBhdW5xdWUgJFxwaSQgZXMgdW5hIHByb2JhYmlsaWRhZCwgbG9zIHZhbG9yZXMKYWp1c3RhZG9zICRcdGV4dGJme3h9XlRcYmV0YSQsIHB1ZWRlbiBsbGVnYXIgYSBzZXIgbWF5b3JlcyBhIDEgbyBtZW5vcmVzCmEgMC4KCkFzw60gcGFyYSBnYXJhbnRpemFyIHF1ZSAkXHBpJCBlc3RlIHJlc3RyaW5naWRvIGFsIGludGVydmFsbyAkWzAsMV0kLCBsbwptb2RlbGFtb3MgdXNhbmRvIHVuYSBmdW5jacOzbiBkZSBkaXN0cmlidWNpw7NuLCBkZSBtb2RvIHF1ZQokJFxwaT1caW50X3stXGluZnR5fV50IGYocylkcywkJCBkb25kZSAkZihzXGdlcSAwKSQgeQokXGludF97LVxpbmZ0eX1ee1xpbmZ0eX1mKHMpZHM9MSQuIEEgbGEgZnVuY2nDs24gZGUgZGVuc2lkYWQgJGYocykkIHNlIGxlCmxsYW1hICoqZGlzdHJpYnVjacOzbiBkZSB0b2xlcmFuY2lhKiouCgojIyMjICoqU2VjY2nDs24gNy4zIE1vZGVsb3MgZG9zaXMgcmVzcHVlc3RhKiogCgpIaXN0w7NyaWNhbWVudGUgdW5vIGRlIGxvcyBwcmltZXJvcyB1c29zIGRlIG1vZGVsb3Mgc2ltaWxhcmVzIGEgbGEKcmVncmVzacOzbiBwYXJhIGRhdG9zIGJpbm9taWFsZXMgZnVlIGVuIHJlc3VsdGFkb3MgZGUgYmlvIGVuc2F5by4gRW4KZXN0b3MgbW9kZWxvcyBsYSByZXNwdWVzdGEgZXJhIGxhIHByb3BvcmNpw7NuIG8gcG9yY2VudGFqZSBkZSDDqXhpdG9zOwpjb21vIHBvciBlamVtcGxvLCBsYSBwcm9wb3JjacOzbiBkZSBhbmltYWxlcyBleHBlcmltZW50YWxlcyBhc2VzaW5hZG9zCnBvciBkaXN0aW50b3Mgbml2ZWxlcyBkZSBkb3NpcyBkZSB1bmEgY2llcnRhIHN1c3RhbmNpYSB0b3hpY2EuIEVzdG9zCmRhdG9zIGEgdmVjZXMgc2UgbGVzIGRlbm9taW5hbiAqKnJlc3B1ZXN0YXMgY3XDoW50aWNhcyoqLiBFbCBvYmpldGl2bwphcXXDrSBlcyBkZXNjcmliaXIgbGEgcHJvYmFiaWxpZGFkIGRlICLDqXhpdG8iICRccGkkLCBjb21vIHVuYSBmdW5jacOzbiBkZQpsYSBkb3NpcyBzdW1pbmlzdHJhZGEsICR4JDsgcG9yIGVqZW1wbG8gJGcoXHBpKT1cYmV0YV8wK1xiZXRhXzEgeCQuCgpTaSBsYSBkaXN0cmlidWNpw7NuIGRlIHRvbGVyYW5jaWEgJGYocykkIGVzIGxhIGRpc3RyaWJ1Y2nDs24gdW5pZm9ybWUKc29icmUgZWwgaW50ZXJ2YWxvICRbYSxiXSQsIGVzIGRlY2lyICQkCmYocyk9XGxlZnRcewpcYmVnaW57YXJyYXl9e2NjfQpcZGZyYWN7MX17Yi1hfSAmIFx0ZXh0eyBzaSB9IGFcbGVxIHhcbGVxIGJcXAowICYgXHRleHR7IGVuIG90cm8gY2Fzb30KXGVuZHthcnJheX0KXHJpZ2h0LiwKJCQgZW50b25jZXMgJCQKXHBpPVxpbnRfe2F9XnggZihzKWRzPVxkZnJhY3t4LWF9e2ItYX1cdGV4dHsgICBzaSB9IGFcbGVxIHhcbGVxIGIuXFwKJCQgTm90ZW1vcyBxdWUgJCRccGk9XGRmcmFje3gtYX17Yi1hfT0tXGRmcmFje2F9e2ItYX0reFxkZnJhY3sxfXtiLWF9LCQkCmRlZmluaWVuZG8gJFxiZXRhXzA9LVxkZnJhY3thfXtiLWF9JCB5ICRcYmV0YV8xPVxkZnJhY3sxfXtiLWF9JCwgc2UKdGllbmUgcXVlICRccGk9XGJldGFfMCtcYmV0YV8xIHgkLgoKQXPDrSBlc3RlICoqbW9kZWxvIGxpbmVhbCoqIGVzIGVxdWl2YWxlbnRlIGEgdXNhciBjb21vIGZ1bmNpw7NuIGVubGFjZSAkZyh4KT14JCBpbXBvbmllbmRvIHJlc3RyaWNjaW9uZXMgc29icmUgJHgkLCAkXGJldGFfMCQgIHkgJFxiZXRhXzEkIGNvcnJlc3BvbmRpZW50ZXMgYSBxdWUgJGFcbGVxIHhcbGVxIGIkLiBFc3RlIHRpcG8gZGUgcmVzdHJpY2Npb25lcyBzb24gbGFzIHF1ZSBubyBwZXJtaXRlbiBxdWUgcG9kYW1vcyBhcGxpY2FyIGRlIG1hbmVyYSBkaXJlY3RhIGxvcyBtw6l0b2RvcyBlc3TDoW5kYXJlcyBwYXJhIGVzdGltYXIgJFxiZXRhXzAkIHkgJFxiZXRhXzEkLgoKVmVyZW1vcyBhaG9yYSB1bm8gZGUgbG9zIG1vZGVsb3MgbWFzIMO6dGlsZXMgeSBtYXlvciBtZW50ZSB1c2Fkb3MgZW4gZW4gZGF0b3MgZGUgYmlvZW5zYXlvIGxsYW1hZG8gKiptb2RlbG8gcHJvYml0KiouIEVuIGVzdGUgbW9kZWxvIHNlIHVzYSBsYSBkaXN0cmlidWNpw7NuIG5vcm1hbCBjb21vIGRpc3RyaWJ1Y2nDs24gZGUgdG9sZXJhbmNpYSwgY29uIGxvIGN1YWwgJFxwaSQgdmllbmUgZGFkbyBwb3I6CgpcWwpccGk9XGRmcmFjezF9e1xzaWdtYVxzcXJ0ezJccGl9fVxpbnRfey1caW5mdHl9XnggZV57LVxmcmFjezF9ezJ9XGxlZnQoXGZyYWN7cy1cbXV9e1xzaWdtYX1ccmlnaHQpXjJ9IGRzPVxQaGlcbGVmdChcZGZyYWN7eC1cbXV9e1xzaWdtYX1ccmlnaHQpLApcXQpkb25kZSAkXFBoaSQgZGVub3RhIGxhIGZ1bmNpw7NuIGRlIGRpc3RyaWJ1Y2nDs24gcGFyYSBsYSBkaXN0cmlidWNpw7NuIG5vcm1hbCBlc3TDoW5kYXIuIEFzw60gc2Ugc2lndWUgcXVlOgpcWwpcUGhpXnstMX0oXHBpKT1cYmV0YV8wK1xiZXRhXzEgeCwKXF0KZG9uZGUgJFxiZXRhXzA9LVxtdS9cc2lnbWEkLCAgJFxiZXRhXzE9MS9cc2lnbWEkIHkgbGEgZnVuY2nDs24gZGUgZW5sYWNlIGVzIGxhIGludmVyc2EgZGUgbGEgZnVuY2nDs24gZGUgZGlzdHJpYnVjacOzbiBkZSBsYSBub3JtYWwuCgoqKk5vdGE6KiogRXN0b3MgbW9kZWxvcyBwcm9iaXQgc29uIHVzYWRvcyBlbiBtdWNoYXMgw6FyZWFzIGRlIGJpb2xvZ8OtYSB5IGNpZW5jaWFzIHNvY2lhbGVzIGVuIGxhcyBjdWFsZXMgc2UgbGVzIGRhIHVuYSBpbnRlcnByZXRhY2nDs24gbmF0dXJhbCBhbCBtb2RlbG87IHBvciBlamVtcGxvIHNpIHNlIGVzdMOhIGVuIHVuIGNvbnRleHRvIGJpb2zDs2dpY28sICAkeD1cbXUkIGVzIGxsYW1hZGEgKipkb3NpcyBsZXRhbCBtZWRpYSoqIExEKDUwKSwgcG9yIHF1ZSBlc3RhIGNvcnJlc3BvbmRlIGRhIGxhIGRvc2lzIHF1ZSBwdWVkZSBlc3BlcmFyIHF1ZSBhY2FiZSBjb24gbGEgbWl0YSBkZSBsb3MgYW5pbWFsZXMuCgpPdHJvIG1vZGVsbyBxdWUgbm9zIGRhIHJlc3VsdGFkb3MgbXV5IHNpbWlsYXJlcyBhbCBtb2RlbG8gcHJvYml0LCBwZXJvIHF1ZSBjb21wdXRhY2lvbmFsbWVudGUgZXMgbWFzIHNlbmNpbGxvLCBlcyBlbCAqKm1vZGVsbyBsb2fDrXN0aWNvKiogbyAqKm1vZGVsbyBsb2dpdCoqLiBFbiBlc3RlIG1vZGVsbyBsYSBkaXN0cmlidWNpw7NuIGRlIHRvbGVyYW5jaWEgZXMgCgoKJCQKZihzKT1cZGZyYWN7XGJldGFfMXtcZXhweyhcYmV0YV8wK1xiZXRhXzEgcyl9fX17KDErXGJldGFfMXtcZXhweyhcYmV0YV8wK1xiZXRhXzEgcyl9KV4yfX0sCiQkCmFzw60gcXVlIApcWwpccGk9XGludF97LVxpbmZ0eX1eeCBmKHMpZHM9XGRmcmFje1xleHB7KFxiZXRhXzArXGJldGExIHgpfX17MStcZXhweyhcYmV0YV8wK1xiZXRhXzEgeCl9fSwKXF0KY29uIGxvIGN1YWwgbm9zIGxhIGZ1bmNpw7NuIGRlIGVubGFjZQpcWwpcbG9nXGxlZnQoXGRmcmFje1xwaX17MS1ccGl9XHJpZ2h0KT1cYmV0YV8wK1xiZXRhXzEgeC4KXF0KRWwgdMOpcm1pbm8gJFxsb2coXHBpLygxLVxwaSkpJCBlcyBsbGFtYWRvIGZ1bmNpw7NuIGxvZ2l0LiBFc3RlIG1vZGVsbyBsb2fDrXN0aWNvIGVzIGFtcGxpYW1lbnRlIHVzYWRvIHBhcmEgZGF0b3MgYmlub21pYWxlcwoKT3RyYXMgbW9kZWxvcyB1c2Fkb3MgcGFyYSBkYXRvcyByZXNwdWVzdGEtZG9zaXMsIHNvbiBwb3IgZWplbXBsbyBzaSBjb25zaWRlcmFtb3MgY29tbyBkaXN0cmlidWNpw7NuIGRlIHRvbGVyYW5jaWEgbGEgKipkaXN0cmlidWNpw7NuIGRlIHZhbG9yIGV4dHJlbW8qKgpcWwpmKHMpPVxiZXRhXzFcZXhwe1tcYmV0YV8wK1xiZXRhXzEgcy1cZXhweyhcYmV0YV8wK1xiZXRhXzEgcyl9XX0KXF0KZW50b25jZXMgClxbClxwaT0xLVxleHB7Wy1cZXhweyhcYmV0YV8wK1xiZXRhXzEgeCl9XX0sClxdCmRlIGRvbmRlIHNlIHNpZ3VlClxbClxsb2d7Wy1cbG9neygxLVxwaSl9XX09XGJldGFfMCtcYmV0YV8xIHguClxdCkFxdcOtIGxhIGZ1bmNpw7NuIGRlIGVubGFjZSBlcyAkZyh4KT1cbG9ne1stXGxvZ3soMS14KX1dfSQgbGEgY3VhbCBzZSBsZSBsbGFtYSAqKmZ1bmNpw7NuIGxvZyBsb2cgY29tcGxlbWVudGFyaWEqKgoKKipFamVtcGxvIDE6IE1vcnRhbGlkYWQgZGUgZXNjYXJhYmFqb3MqKgpFbCBzaWd1aWVudGUgY29uanVudG8gZGUgZGF0b3MgIG11ZXN0cmEgZWwgbnVtZXJvIGRlIGVzY2FyYWJham9zIG11ZXJ0b3MgZGVzcHXDqXMgZGUgY2luY28gaG9yYXMgZGUgZXhwb3NpY2nDs24gYSBnYXMgZGUgZGlzdWxmdXJvIGRlIGNhcmJvbm8gZW4gdmFyaWFzIGNvbmNlbnRyYWNpb25lcy4KYGBge3J9CkRvc2lzPC1jKDEuNjkwNywxLjcyNDIsMS43NTUyLDEuNzg0MiwxLjgxMTMsMS44MzY5LDEuODYxMCwxLjg4MzkpClBvYmxhY2lvbjwtYyg1OSw2MCw2Miw1Niw2Myw1OSw2Miw2MCkKTXVlcnRlczwtYyg2LDEzLDE4LDI4LDUyLDUzLDYxLDYwKQpUYWJsYTE8LWNiaW5kKERvc2lzLFBvYmxhY2lvbixNdWVydGVzKQpUYWJsYTE8LWRhdGEuZnJhbWUoVGFibGExKQpuYW1lcyhUYWJsYTEpPC1jKCJEb3NpcywgeF9pIiwiTsO6bWVybyBkZSBlc2NhcmFiYWpvcywgbl9pIiwgIk7Dum1lcm8gZGUgbXVlcnRlcywgeV9pIikKVGFibGExCmBgYApgYGB7cn0KcGxvdChEb3NpcyxNdWVydGVzL1BvYmxhY2lvbixwY2g9MjAsY2V4PTEuNyx5bGFiPSJQcm9wb3JjacOzbiBkZSBtdWVydGVzIixzdWI9VGVYKHInKFByb3BvcmNpw7NuIGRlIG11ZXJ0ZXMgJHBfaT15X2kvbl9pJCB2cyBkb3NpcyAkeF9pJCknKSkKYGBgCkNvbWVudGFyaW86IEVuIGVzdGUgZWplbXBsbyBlc3RhbW9zIGNvbnNpZGVyYW1vcyAkeF9pJCBjb21vIGVsIGxvZ2FyaXRtbyBkZSBsYSBjYW50aWRhZCBkZSBkaXN1bGZ1cm8gZGUgY2FyYm9uby4gCgpFbCBwcm9ww7NzaXRvIGVuIGVzdGUgZWplbXBsbyBzZXLDoSBhanVzdGFyIHVuIG1vZGVsbyBsb2fDrXN0aWNvLiBDb21vIHVzYXJlbW9zIGVsIG1vZGVsbyBsb2fDrXN0aWNvLCBzZSB0aWVuZSBxdWUgbGFzIHByb3BvcmNpb25lcyBzZSBleHByZXNhbiBjb21vClxbClxwaV9pPVxsb2dcbGVmdChcZGZyYWN7XHBpX2l9ezEtXHBpX2l9XHJpZ2h0KSwKXF0KY29uIGxvIGN1YWwKXFsKXGxvZ1xsZWZ0KFxkZnJhY3tccGlfaX17MS1ccGlfaX1ccmlnaHQpPVxiZXRhXzArXGJldGFfMSB4X2kKXF0gCnkgClxbClxsb2d7KDEtXHBpX2kpfT1cbG9ne1sxK1xleHB7KFxiZXRhXzArXGJldGFfMSB4X2kpfV19LgpcXQpQb3Igb3RybyBsYWRvLCBlbiB1biBpbmljaW8gaGFiw61hbW9zIGVuY29udHJhZG8gcXVlIGxhIGZ1bmNpw7NuIGRlIGxvZyB2ZXJvc2ltaWxpdHVkIHZpZW5lIGRhZGEgcG9yClxbCmwoXHBpXzEsXGxkb3RzLFxwaV9uO3lfMSxcbGRvdHMseV9uKT1cbGVmdFtcc3VtX3tqPTF9XntOfXlfalxsb2dcbGVmdChcZGZyYWN7XHBpX2p9ezEtXHBpX2p9XHJpZ2h0KSsgIG5falxsb2coMS1ccGlfaikrXGxvZ1xiaW5vbXtuX2p9e3lfan1ccmlnaHRdClxdCnN1c3RpdHV5ZW5kbyBsYXMgZXhwcmVzaW9uZXMgeWEgZW5jb250cmFkYXMsIGxhIGxvZyB2ZXJvc2ltaWxpdHVkIHNlIHJlZHVjZSBhIApcWwpsKFxwaV8xLFxsZG90cyxccGlfbjt5XzEsXGxkb3RzLHlfbik9XGxlZnRbXHN1bV97aj0xfV57Tn15X2ooXGJldGFfMCtcYmV0YV8xIHhfaikrICBuX2pcbG9ne1sxK1xleHB7KFxiZXRhXzArXGJldGFfMSB4X2kpfV19XGxvZ1xiaW5vbXtuX2p9e3lfan1ccmlnaHRdLgpcXS4KRGVyaXZhbmRvIGxhIGxvZyB2ZXJvc2ltaWxpdHVkIGNvbiByZXNwZWN0byBhICRcYmV0YV8wJCB5ICRcYmV0YV8xJCwgdGVuZW1vcyBxdWUgbG9zIHNjb3JlcyB2aWVuZW4gZGFkb3MgcG9yOgoKXFsKXGJlZ2lue3NwbGl0fQpVXzE9JlxkZnJhY3tccGFydGlhbCBsfXtccGFydGlhbCBcYmV0YV8wfT1cc3VtX3tpPTF9Xk4gXGxlZnQoeV9pLW5faVxsZWZ0W1xkZnJhY3tcZXhweyhcYmV0YV8wK1xiZXRhXzEgeF9pKX19ezErXGV4cHsoXGJldGFfMCtcYmV0YV8xIHhfaSl9fVxyaWdodF1ccmlnaHQpPVxzdW1fe2k9MX1eTih5X2ktbl9pXHBpX2kpXFwKVV8yPSYgXGRmcmFje1xwYXJ0aWFsIGx9e1xwYXJ0aWFsIFxiZXRhXzF9PVxzdW1fe2k9MX1eTiBcbGVmdCh5X2kgeF9pLW5faSB4X2lcbGVmdFtcZGZyYWN7XGV4cHsoXGJldGFfMCtcYmV0YV8xIHhfaSl9fXsxK1xleHB7KFxiZXRhXzArXGJldGFfMSB4X2kpfX1ccmlnaHRdXHJpZ2h0KT1cc3VtX3tpPTF9Xk4geF9pKHlfaS1uX2lccGlfaSkuClxlbmR7c3BsaXR9ClxdClNpbWlsYXJtZW50ZSByZWFsaXphbmRvIGxhcyByZXNwZWN0aXZhcyBjdWVudGFzLCBlbmNvbnRyYW1vcyBxdWUgbGEgbWF0cml6IGRlIGluZm9ybWFjacOzbiBlcyAKXFsKSj1cbGVmdFsKXGJlZ2lue2FycmF5fXtjY30KXHN1bV97aT0xfV5OIG5faVxwaV9pICgxLVxwaV9pKSZcc3VtX3tpPTF9Xk4gbl9pIHhfaVxwaV9pICgxLVxwaV9pKVxcClxzdW1fe2k9MX1eTiBuX2kgeF9pXHBpX2kgKDEtXHBpX2kpICYgXHN1bV97aT0xfV5OIG5faSB4X2leMlxwaV9pICgxLVxwaV9pKQpcZW5ke2FycmF5fQpccmlnaHRdLgpcXQpQb3IgbG8gdmlzdG8gZW4gZWwgY2FwaXR1bG8gZGUgZXN0aW1hY2nDs24sIHNhYmVtb3MgcXVlIHBhcmEgZW5jb250cmFyIGxvcyBlc3RpbWFkb3JlcyBkZSBtw6F4aW1hIHZlcm9zaW1pbGl0dWQgbG9zIHBvZGVtb3Mgb2J0ZW5lciBpdGVyYXRpdmFtZW50ZSBzb2x1Y2lvbmFuZG8gbGEgZWN1YWNpw7NuClxbCkpeeyhtLTEpfSBcdGV4dGJme2J9Xm0gPUpeeyhtLTEpfVx0ZXh0YmZ7Yn1eeyhtLTEpfStVXnsobS0xKX0KXF0KZG9uZGUgZWwgc3VwZXJpbmRpY2UgJChtKSQgaW5kaWNhIGxhICRtJC3DqXNpbWEgYXByb3hpbWFjacOzbiB5ICRcdGV4dGJme2J9JCBlcyBlbCB2ZWN0b3IgZGUgZXN0aW1hY2lvbmVzLgoKQ29uIGxhcyBleHByZXNpb25lcyB5YSBlbmNvbnRyYWRhcywgcHJvY2VkZXJlbW9zIGEgZW5jb250cmFyIGxhcyBlc3RpbWFjaW9uZXMgZGUgbG9zIHBhcsOhbWV0cm9zICRcYmV0YV8wJCB5ICRcYmV0YV8xJCwgc2lndWllbmRvIGxhcyBpZGVhcyBkZWwgY2FwaXR1bG8gZGUgZXN0aW1hY2lvbmVzLgoKUGFyYSBlbGxvIGNvbiBsYSBzaWd1aWVudGUgZnVuY2nDs24gcG9kcmVtb3MgcmVhbGl6YXIgZWwgbnVtZXJvIGRlIHNpbXVsYWNpb25lcyBxdWUgZGVzZWVtb3MgaGFzdGEgZW5jb250cmFyIGxhcyBlc3RpbWFjaW9uZXMgZW50cmUgZG9zIGl0ZXJhY2lvbmVzIHNlZ3VpZGFzIG5vIHZhcmnDqSBtdWNoby4KCmBgYHtyfQojIyBGdW5jacOzbiBwYXJhIHJlYWxpemFyIGVzdGltYWNpw7NuIGRlIG3DoXhpbWEgdmVyb3NpbWlsaXR1ZCBiYXNhZGEgZW4gbG9zIHJlc3VsdGFkb3MgZGVsIGNhcGl0dWxvIDQsIGxhIGN1YWwgcHJpbmNpcGFsbWVudGUgc2lndWUgbGEgaWRlYSBkZWwgYWxnb3JpdG1vIE5ld3RvbiBSYXBoc29uLgoKIyBQYXLDoW1ldHJvcyBxdWUgcmVxdWllcmUgZXN0YSBmdW5jacOzbiAKIyBudW1faXRlcmEgPSAjIGRlIGl0ZXJhY2lvbmVzIHF1ZSBkZXNlYW1vcyByZWFsaXphciBwYXJhIGVzdGltYXIgbG9zIHBhcsOhbWV0cm9zIGRlIE3DoXhpbWEgdmVyb3NpbWlsaXR1ZC4KIyBQb2JsYWNpb25lcyA9IFZlY3RvciBxdWUgY29udGllbmUgZWwgdGFtYcOxbyBkZSBjYWRhIHN1YiBwb2JsYWNpw7NuIHBhcmEgY2FkYSBwcmVkaWN0b3IuCiMgcHJlZGljdG9yZXMgPSBWZWN0b3IgZGUgdmFyaWFibGVzIHByZWRpY3RvcmFzIGNvbnNpZGVyYWRhcyBwYXJhIGNhZGEgc3ViIHBvYmxhY2nDs24uCiNyZXNwdWVzdGFzID0gVmVjdG9yIGRlIHJlc3B1ZXN0YXMgYXNvY2lhZGFzIGEgY2FkYSBzdWIgcG9ibGFjacOzbi4KCmVzdGltYWNpb248LWZ1bmN0aW9uKG51bV9pdGVyYSxiX2luaWNpYWwsUG9ibGFjaW9uZXMscHJlZGljdG9yZXMscmVzcHVlc3Rhcyl7CiAgZm9yIChpIGluIDE6bnVtX2l0ZXJhKSB7CiAgICAgIHByb3BvcmNpb248LWV4cChiX2luaWNpYWxbMV0rYl9pbmljaWFsWzJdKnByZWRpY3RvcmVzKS8oMStleHAoYl9pbmljaWFsWzFdK2JfaW5pY2lhbFsyXSpwcmVkaWN0b3JlcykpIAogICAgICAjIFZlY3RvciBkZSBsYSBwcm9wb3JjaW9uZXMgcGFyYSBjYWRhIHN1YiBwb2JsYWNpw7NuCiAgVTAgPC0gc3VtKHJlc3B1ZXN0YXMtUG9ibGFjaW9uZXMqcHJvcG9yY2lvbikKICBVMSA8LSBzdW0ocHJlZGljdG9yZXMqKHJlc3B1ZXN0YXMtUG9ibGFjaW9uZXMqcHJvcG9yY2lvbikpCiAgVTwtbWF0cml4KGMoVTAsVTEpLG5jb2w9MSxieXJvdyA9IFQpCiAgSl8xMSA8LSBzdW0oUG9ibGFjaW9uZXMqcHJvcG9yY2lvbiooMS1wcm9wb3JjaW9uKSkKICBKXzEyIDwtIHN1bShQb2JsYWNpb25lcypwcmVkaWN0b3Jlcypwcm9wb3JjaW9uKigxLXByb3BvcmNpb24pKQogIEpfMjEgPC0gc3VtKFBvYmxhY2lvbmVzKnByZWRpY3RvcmVzKnByb3BvcmNpb24qKDEtcHJvcG9yY2lvbikpCiAgSl8yMiA8LSBzdW0oUG9ibGFjaW9uZXMqcHJlZGljdG9yZXNeMipwcm9wb3JjaW9uKigxLXByb3BvcmNpb24pKQogIEo8LW1hdHJpeChjKEpfMTEsSl8xMixKXzIxLEpfMjIpLG5jb2wgPSAyLGJ5cm93ID0gVCkKICBKX2ludjwtc29sdmUoSikKICBiX2luaWNpYWwgPC0gYl9pbmljaWFsICsgSl9pbnYlKiVVCiAgbG9nX3Zlcm88LXN1bShyZXNwdWVzdGFzKihiX2luaWNpYWxbMV0rYl9pbmljaWFsWzJdKnByZWRpY3RvcmVzKS1Qb2JsYWNpb25lcypsb2coMStleHAoYl9pbmljaWFsWzFdK2JfaW5pY2lhbFsyXSpwcmVkaWN0b3JlcykpKQogIHlfZXN0aW08LVBvYmxhY2lvbmVzKnByb3BvcmNpb24KICB9CiAgUmVzdW1JdGU8LWxpc3QoYl9pbmljaWFsLGxvZ192ZXJvLEpfaW52LHlfZXN0aW0pCiAgcmV0dXJuKFJlc3VtSXRlKQp9CiMgbG9zIHBhcsOhbWV0cm9zIGluaWNpYWxlcwpiMDwtbWF0cml4KGMoMCwwKSxuY29sPTEsYnlyb3c9VCkKCmBgYApgYGAKfCAgICAgICAgICAgICAgfCBFc3RpbWFjaW9uIGluaWNpYWx8IDFyYSBhcHJveCAgICB8IDJkYSBhcHJveCAgICB8IDNyYSBhcHJveHwKfC0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS18LS0tLS0tLS18Cnwgw59fMCAgICAgICAgICAgICAgIHwgMCAgICAgICAgICAgfC0zNy44NTYgICAgICAgIHwtNTMuODUzICAgICAgICB8LTYwLjcxNyB8Cnwgw59fMSAgICAgICAgICAgICAgIHwgMCAgICAgICAgICAgfDIxLjMzNyAgICAgICAgIHwzMC4zODQgICAgICAgICB8MzQuMjcwICB8CnwgbG9nLXZlcm9zaW1pbGl0dWQgfCAtMzMzLjQwNCAgICB8LTIwMC4wMTAgICAgICAgfC0xODcuMjc0ICAgICAgIHwtMTg2LjIzNXwKCmBgYAoKCjwhLS0gUGFydGUgMi0tPgojIyMjICoqU2VjY2nDs24gNy40IE1vZGVsbyBkZSBSZWdyZXNpw7NuIExvZ8Otc3RpY2EgR2VuZXJhbCoqCgpFbCBtb2RlbG8gZGUgcmVncmVzacOzbiBsb2fDrXN0aWNhIGxpbmVhbCBzaW1wbGUgcHJlc2VudGFkbyBhbnRlcywKClxbClxsb2dcbGVmdChcZnJhY3tccGlfaX17MS1ccGlfaX1ccmlnaHQpPVxiZXRhXzErXGJldGFfMiB4X2kKXF0KCnV0aWxpemFkbyBlbiBlbCBlamVtcGxvIGRlIGxhIG1vcnRhbGlkYWQgZGUgbG9zIGVzY2FyYWJham9zIGVzIHNpbXBsZW1lbnRlIHVuIGNhc28gZXNwZWNpYWwgZGVsIG1vZGVsbyBkZSBkZSByZWdyZXNpw7NuIGxvZ8Otc3RpY2EgZ2VuZXJhbDoKXFsKbG9naXQoXHBpX2kpPVxsb2dcbGVmdChcZnJhY3tccGlfaX17MS1ccGlfaX1ccmlnaHQpPSB4X3tpfV57VH1cYmV0YSwKXF0KZG9uZGUgJHhfaSQgZXMgdW4gdmVjdG9yIGRlIG1lZGljaW9uZXMgY29udGludWFzIGNvcnJlc3BvbmRpZW50ZSBhIHZhcmlhYmxlcyByZWdyZXNvcmFzIHkgdmFyaWFibGVzICJkdW1teSIgY29ycmVzcG9uZGllbnRlcyBhIG5pdmVsZXMgZGUgZmFjdG9yLCB5ICRcYmV0YSQgZXMgZWwgdmVjdG9yIGRlIHBhcsOhbWV0cm9zLiBFc3RlIG1vZGVsbyBlcyBtdXkgdXRpbGl6YWRvIHBhcmEgdXRpbGl6YXIgZGF0b3MgcXVlIGludm9sdWNyYW4gdmFyaWFibGVzIGRlIHJlc3B1ZXN0YSBiaW5hcmlhcyBvIGJpbm9taWFsZXMsIGFzw60gY29tbyB2YXJpb3MgcmVncmVzb3Jlcy4gClxuZXdsaW5lCgpFc3RpbWFkb3JlcyBkZSBtw6F4aW1hIHZlcm9zaW1pbGl0dWQgZGUgbG9zIHBhcsOhbWV0cm9zICRcYmV0YSQsIHkgZW4gY29uc2VjdWVuY2lhLCBkZSBsYXMgcHJvYmFiaWxpZGFkZXMKXFsKXHBpX2k9Zyh4X3tpfV57VH1cYmV0YSksIApcXQpzZSBvYnRpZW5lbiBtYXhpbWl6YW5kbyBsYSBmdW5jacOzbiBkZSBsb2ctdmVyb3NpbWlsaXR1ZCBkYWRhIHBvcjoKXFsKbChccGk7eSk9XHN1bV97aT0xfV57Tn1cbGVmdFt5X2lcbG9nKFxwaV9pKSsobl9pLXlfaSlcbG9nKDEtXHBpX2kpK1xsb2d7XGJpbm9te25faX17eV9pfX1ccmlnaHRdLgpcXQpEaWNoYSBtYXhpbWl6YWNpw7NuIHNlIGhhY2UgdXRpbGl6YW5kbyBsb3MgbcOpdG9kb3MgY29ycmVzcG9uZGllbnRlcy4KXG5ld2xpbmUKCkVsIHByb2Nlc28gZGUgZXN0aW1hY2nDs24gZXMgZXNlbmNpYWxtZW50ZSBlbCBtaXNtbyBzaWVtcHJlIHF1ZSBsb3MgZGF0b3MgZXN0w6luIGFncnVwYWRvcyBjb21vIGZyZWN1ZW5jaWFzIHBhcmEgY2FkYSBwYXRyw7NuIGRlIGNvdmFyaWFuemEgKGVzIGRlY2lyLCBsb3MgZGF0b3MgZXN0w6FuIGFncnVwYWRvcyBkZSBhY3VlcmRvIGEgc2kgc29uIG9ic2VydmFjaW9uZXMgY29uIGxvcyBtaXNtb3MgdmFsb3JlcyBkZSB0b2RhcyBsYXMgdmFyaWFibGVzIHJlZ3Jlc29yYXMpLCBvIGJpZW4sIHNpIGNhZGEgb2JzZXJ2YWNpw7NuIGVzdMOhIGNvZGlmaWNhZGEgY29tbyB1biAwIG8gdW4gMSwgeSBzdSBwYXRyw7NuIGRlIGNvdmFyaWFuemEgc2UgZW5saXN0w7MgZGUgbWFuZXJhIHNlcGFyYWRhLgpcbmV3bGluZQoKU2kgbG9zIGRhdG9zIHB1ZWRlbiBzZXIgYWdydXBhZG9zLCBlbnRvbmNlcyBsYSByZXNwdWVzdGEgJFlfaSQgcmVwcmVzZW50YXLDoSBlbCBuw7ptZXJvIGRlIMOpeGl0b3MgcGFyYSBlbCBwYXRyw7NuIGRlIGNvdmFyaWFuemEgJGkkLCB5IHRhbCByZXNwdWVzdGEgcHVlZGUgc2VyIG1vZGVsYWRhIHBvciBsYSBkaXN0cmlidWNpw7NuIGJpbm9taWFsLiBFbiBjYW1iaW8sIHNpIGNhZGEgb2JzZXJ2YWNpw7NuIHRpZW5lIHVuIGRpc3RpbnRvIHBhdHLDs24gZGUgY292YXJpYW56YSwgZW50b25jZXMgJG5faT0xJCB5IGxhIHJlc3B1ZXN0YSAkWV9pJCBlcyBiaW5hcmlhLgpcbmV3bGluZQoKTGEgZGV2aWFuemEgZW4gZXN0ZSBjYXNvIGVzdMOhIGRhZGEgcG9yOgpcWwpEPTJcc3VtX3tpPTF9XntOfVxsZWZ0W3lfaVxsb2dcZnJhY3t5X2l9e1xoYXR7eV9pfX0rKG5faS15X2kpXGxvZ1xmcmFjCntuLXlfaX17bi1caGF0e3lfaX19XHJpZ2h0XQpcXQpUYWwgZXhwcmVzacOzbiBwdWVkZSBzZXIgcmVlc2NyaXRhIGNvbW86CgpcWwpEPTJcc3VtIG9cbG9nXGZyYWN7b317ZX0sClxdCmRvbmRlICRvJCBkZW5vdGEgbGFzIGZyZWN1ZW5jaWFzIG9ic2VydmFkYXMgJHlfaSQgeSAkKG5faS15X2kpJCwgeSAkZSQgZGVub3RhIGxhcyBjb3JyZXNwb25kaWVudGVzIGZyZWN1ZW5jaWFzIGVzdGltYWRhcyBlc3BlcmFkYXMsIG8gbWVqb3IgZGljaG8sIGxvcyB2YWxvcmVzIGFqdXN0YWRvcyBkZWwgbW9kZWxvLCAkXGhhdHt5X2l9PW5faVxoYXR7XHBpX2l9IHkgKG5faS1caGF0e3lfaX0pPShuX2ktbl9pXGhhdHtccGlfaX0pLiBMYSBzdW1hIGVzIHNvYnJlIHRvZG9zIGxvcyBwb3NpYmxlcyB2YWxvcmVzIGRlICRpJC4KXG5ld2xpbmUKCk5vdGFtb3MgcXVlIGxhIGRldmlhbmNlICREJCBubyBpbnZvbHVjcmEgbmluZ8O6biAibnVpc2FuY2UgcGFyYW1ldGVyIiwgY29tbyBlbCAkXHNpZ21hXjIkIGVuIGxvcyBtb2RlbG9zIGNvbiByZXNwdWVzdGFzIG5vcm1hbGVzLiBQb3IgbG8gdGFudG8sIGxvcyB0ZXN0IGRlIGJvbmRhZCBkZSBhanVzdGUgcHVlZGVuIHNlciBldmFsdWFkb3MgeSBsYXMgaGlww7N0ZXNpcyBwdWVkZW4gc2VyIHRlc3RlYWRhcyBkaXJlY3RhbWVudGUgdXRpbGl6YW5kbyBsYSBhcHJveGltYWNpw7NuIGRlIGxhIGRldmlhbnphOgpcWwpEXHNpbVxjaGleMihOLXApLApcXQpkb25kZSAkcCQgZXMgZWwgbsO6bWVybyBkZSBwYXLDoW1ldHJvcyBlc3RpbWFkbyB5ICROJCBlbCBuw7ptZXJvIGRlIHBhdHJvbmVzIGRlIGNvdmFyaWFuemEuClxuZXdsaW5lCgpDYWJlIGRlc3RhY2FyIHF1ZSBsb3MgbcOpdG9kb3MgZGUgZXN0aW1hY2nDs24geSBsYXMgZGlzdHJpYnVjaW9uZXMgbXVlc3RyYWxlcyB1dGlsaXphZGFzIHBhcmEgaW5mZXJlbmNpYSBkZXBlbmRlbiBkZSByZXN1bHRhZG9zIGFzaW50w7N0aWNvcy4gUGFyYSBwZXF1ZcOxb3MgZXN0dWRpb3MgZG9uZGUgaGF5IHBvY2FzIG9ic2VydmFjaW9uZXMgcGFyYSBjYWRhIHBhdHLDs24gZGUgY292YXJpYW56YSwgbG9zIHJlc3VsdGFkb3MgYXNpbnTDs3RpY29zIHBvZHLDrWFuIHNlciBtYWxvcy4gCgoqKkVqZW1wbG8gMjogRW1icmlvZ8OpbnNpcyBkZSBBbnRlcmFzKioKCkxvcyBzaWd1aWVudGVzIGRhdG9zIG11ZXN0cmFuIHJlc3B1ZXN0YXMgJHlfe2prfSQgcXVlIHJlcHJlc2VudGFuIGVsIG7Dum1lcm8gZGUgYW50ZXJhcyBlbWJyaW9nw6luaWNhcyBkZSBsYSBlc3BlY2llIGRlIHBsYW50YSAkRGF0dXJhIGlubm94aWEkIHF1ZSBmdWVyb24gb2J0ZW5pZGFzIGN1YW5kbyB1bmEgY2FudGlkYWQgJG5fe2prfSQgZGUgYW50ZXJhcyBmdWVyb24gcHJlcGFyYWRhcyBiYWpvIHZhcmlhcyBjb25kaWNpb25lcyBkaWZlcmVudGVzLiBIYXkgdW4gZmFjdG9yIGN1YWxpdGF0aXZvIGNvbiBkb3Mgbml2ZWxlcyBxdWUgZGEgb3JpZ2VuIGEgMiBncnVwb3MgJGpcaW57MSwyfSQgZGUgYW50ZXJhcywgZWwgcHJpbWVybyByZXByZXNlbnRhIGEgbGFzIGFudGVyYXMgZGVsIGdydXBvIGNvbnRyb2wgbWllbnRyYXMgcXVlIGVsIHNlZ3VuZG8gcmVwcmVzZW50YSBhIGxhcyBhbnRlcmFzIGRlbCBncnVwbyB0cmF0YWRvLiBMYXMgcHJpbWVyYXMgZnVlcm9uIHRyYXRhZGFzIGNvb24gdW4gYWxtYWNlbmFtaWVudG8gZGUgMyBncmFkb3MgQ2Vsc2l1cyBwb3IgNDggaG9yYXMsIG1pZW50cmFzIHF1ZSBsYXMgYW50ZXJhcyBkZWwgZ3J1cG8gY29udHJvbCBlc3R1dmllb3JuIGFsbWFjZW5hZGFzIGNvbiBjb25kaWNpb25lcyBub3JtYWxlcy4KXG5ld2xpbmUKCkFzw60gbWlzbW8sIGxvcyBkb3MgZ3J1cG9zIGRlIGFudGVyYXMgYWxtYWNlbmFkYXMgZW4gY29uZGljaW9uZXMgZGUgY29udHJvbCB5IGRlIHRyYXRhbWllbnRvIGZ1ZXJvbiBleHB1ZXN0YXMgYSBsb3MgZWZlY3RvcyBkZSB1bmEgZnVlcnphIGNlbnRyw61mdWdhLCBsYSBjdWFsIGVzIHVuYSB2YXJpYWJsZSBhbGVhdG9yaWEgY29udGludWEuIEVuIGVzdGUgY2FzbywgaHViaWVyb24gdHJlcyB2YWxvcmVzIGRlIGZ1ZXJ6YSBjZW50csOtZnVnYSBhIGxhIHF1ZSBsb3MgZ3J1cG9zIGZ1ZXJvbiBleHB1ZXN0b3MuIExhIGlkZWEgZXMgY29tcGFyYXIgbG9zIGVmZWN0b3MgZGVsIGNvbnRyb2wgeSBkZWwgdHJhdGFtaWVudG8gZW4gbGFzIHByb3BvcmNpb25lcyBkZXNwdcOpcyBkZSBoYWJlciBzaWRvIGFqdXN0YWRhcyBhIHVuYSBmdXJ6YSBjZW50csOtZnVnYToKCnwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgIHwgRnVlcnphIHwgQ2VudHLDrWZ1Z2EgfCAoZykgfAp8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS18LS0tLS0tLS18LS0tLS0tLS0tLS0tfC0tLS0tfAp8IENvbmRpY2lvbiBkZSBBbG1hY2VuYW1pZW50byB8ICAgICAgICB8IDQwICAgICB8IDE1MCAgICAgICAgfCAzNTAgfAp8IEdydXBvIENvbnRyb2wgICAgICAgICAgICAgICB8ICR5X3sxa30kIHwgNTUgICAgIHwgNTIgICAgICAgICB8IDU3ICB8CnwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgJG5fezFrfSQgfCAxMDIgICAgfCA5OSAgICAgICAgIHwgMTA4IHwKfCBHcnVwbyBlbiB0cmF0YW1pZW50byAgICAgICAgfCAkeV97Mmt9JCB8IDU1ICAgICB8IDUwICAgICAgICAgfCA1MCAgfAp8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICRuX3sya30kIHwgNzYgICAgIHwgODEgICAgICAgICB8IDkwICB8CgoKTGFzIHByb3BvcmNpb25lcyAkcF97amt9PVxmcmFje3lfe2prfX17bl97amt9fSQgZW4gbG9zIGdydXBvcyBkZSBjb250cm9sIHkgZGUgdHJhdGFtaWVudG8gc29uIGdyYWZpY2Fkb3MgY29udHJhIGxhIHZhcmlhYmxlICR4X2skIHF1ZSByZXByZXNlbnRhIGVsIGxvZ2FyaXRtbyBkZSBsYSBmdWVyemEgY2VudHLDrWZ1Z2EuIExhcyBwcm9wb3JjaW9uZXMgZGUgcmVzcHVlc3RhIHBhcmVjZW4gc2VyIG3DoXMgYWx0YXMgZW4gZWwgZ3J1cG8gdHJhdGFkbyBxdWUgZW4gZWwgZ3J1cG8gY29udHJvbCwgeSBhbCBtZW5vcyBwYXJhIGVsIGdydXBvIHRyYXRhZG8sIGxhIHJlc3B1ZXN0YSBkZWNyZWNlIGNvbiBsYSBmdWVyemEgY2VudHLDrWZ1Z2EuClxuZXdsaW5lCgpDb21wYXJhcmVtb3MgYWhvcmEgdHJlcyBtb2RlbG9zIGxvZ8Otc3RpY29zIHBhcmEgJFxwaV97aWp9JCwgbGEgcHJvYmFiaWxpZGFkIGRlIGxhcyBhbnRlcmFzIGRlIHNlciBlbWJyaW9nw6luaWNhcywgZG9uZGUgJGo9MSQgcGFyYSBlbCBncnVwbyBjb250cm9sIHkgJGo9MiQgcGFyYSBlbCBncnVwbyB0cmF0YWRvLCBkb25kZSAkaj0xJCBwYXJhIGVsIGdydXBvIGNvbnRyb2wgeSAkaj0yJCBwYXJhIGVsIGdydXBvIHRyYXRhZG8sIHkgJHhfMT1cbG9nNDA9My42ODkkLCAkeF8yPWxvZyAxNTA9NS4wMTEkLCB5ICR4XzM9bG9nIDM1MD01Ljg2OCQuCgoKYGBge3J9CkxvZ0ZDPC1sb2coYyg0MCwxNTAsMzUwKSkKTG9nRkMKCmNvbnRyb2x5PC1jKDU1LDUyLDU3KQpjb250cm9sbjwtYygxMDIsOTksMTA4KQpwMTwtY29udHJvbHkvY29udHJvbG4KcDEKdHJhdGFtaWVudG95PC1jKDU1LDUwLDUwKQp0cmF0YW1pZW50b248LWMoNzYsODEsOTApCnAyPC10cmF0YW1pZW50b3kvdHJhdGFtaWVudG9uCnAyCgpwbG90KExvZ0ZDLHAyLHlsaW09YygwLjUsMC44KSxwY2g9MTgsY2V4PTEuNSwgeGxhYj0iIix5bGFiPSIiKQpwYXIobmV3PVQpCnBsb3QoTG9nRkMscDEseWxpbT1jKDAuNSwwLjgpLHBjaD0xOSxjZXg9MS4zLHhsYWI9IkxvZy1GdWVyemEgQ2VudHLDrWZ1Z2EiLCB5bGFiPSJQcm9wb3JjacOzbiBxdWUgZ2VybWluw7MiKQpgYGAKCgpcWwpcYmVnaW57c3BsaXR9Ck1vZGVsbzE6IGxvZ2l0IFxwaV97amt9PVxhbHBoYV9qK1xiZXRhX2ogeF9rIFx0ZXh0eyBlcyBkZWNpciwgZGlmZXJlbnRlcyBpbnRlcmNlcHRvcyB5IHBlbmRpZW50ZXN9O1xcCiZNb2RlbG8yOiBsb2dpdCBccGlfe2prfT1cYWxwaGFfaitcYmV0YSB4X2sgXHRleHR7IGVzIGRlY2lyLCBkaWZlcmVudGVzIGludGVyY2VwdG9zIHBlcm8gbWlzbWEgcGVuZGllbnRlfTtcXAomTW9kZWxvMzogbG9naXQgXHBpX3tqa309XGFscGhhK1xiZXRhIHhfayBcdGV4dHsgZXMgZGVjaXIsIG1pc21vIGludGVyY2VwdG8geSBwZW5kaWVudGUufVxcClxlbmR7c3BsaXR9ClxdCkVzdG9zIG1vZGVsb3MgZnVlcm9uIGFqdXN0YWRvcyB1dGlsaXphbmRvIG3DoXhpbWEgdmVyb3NpbWlsaXR1ZC4gTG9zIHJlc3VsdGFkb3MgcmVzdW1pZG9zIHNlIHB1ZWRlbiB2ZXIgZW4gbGEgc2lndWllbnRlIHRhYmxhOgoKfCBNb2RlbG8gMSAgICAgICAgICAgICAgICB8IE1vZGVsbyAyICAgICAgICAgICAgICAgIHwgTW9kZWxvIDMgICAgICAgICAgIHwKfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLXwKfCAkYV8xJD0wLjIzNCAoMC42MjgpICAgICB8ICRhXzEkPTAuODc3ICgwLjQ4NykgICAgIHwgJGEkPTEuMDIxICgwLjQ4MSkgIHwKfCAkYV8yLWFfMSQ9MS45NzcgKDAuOTk4KSB8ICRhXzItYV8xJD0wLjQwNyAoMC4xNzUpIHwgJGIkPS0wLjE0OCAoMC4wOTYpIHwKfCAkYl8xJD0tMC4wMjMgKDAuMTI3KSAgICB8ICRiJD0gLTAuMTU1ICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgIHwKfCAkYjItYjEkPS0wLjMxOSAoMC4xOTkpICB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgIHwKfCAkRF8xJD0wLjAyOCAgICAgICAgICAgICB8ICREXzIkPTIuNjE5ICAgICAgICAgICAgIHwgJERfMyQ9My4xMTAgICAgICAgIHwKCgpQYXJhIHByb2JhciBsYSBoaXDDs3Rlc2lzIG51bGEgZGUgcXVlIGxhIHBlbmRpZW50ZSBlcyBsYSBtaXNtYSBwYXJhIGxvcyBncnVwb3MgZGUgdHJhdGFtaWVudG8geSBjb250cm9sLCB1dGlsaXphbW9zIGxhIHJlc3RhIGRlIGRldmlhbnphcyAkRF8yLURfMT0yLjU5MSQuIEV4dHJheWVuZG8gbG9zIGN1YW50aWxlcyBuZWNlc2FyaW9zIHBhcmEgdW5hIGRpc3RyaWJ1Y2nDs24gJFxjaGleMigxKSQsIGVsIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEgZXN0w6EgZW50cmUgMC4xIHkgMC4yLCB5IHBvciBsbyB0YW50byBwb2Ryw61hbW9zIGNvbmNsdWlyIHF1ZSBsb3MgZGF0b3Mgbm9zIGRhbiBwb2NhIGV2aWRlbmNpYSBlbiBjb250cmEgZGUgcXVlIGxhcyBwZW5kaWVudGVzIHNlYW4gaWd1YWxlcy4gU2luIGVtYmFyZ28sIGVsIHBvZGVyIGRlIGVzdGUgdGVzdCB5IGxhcyBlc3RpbWFjaW9uZXMgcGFyYSBlbCBNb2RlbG8gMSBzdWd1aWVyZW4gcXVlIGF1bnF1ZSBsYSBwZW5kaWVudGUgcGFyYSBlbCBncnVwbyBjb250cm9sIHB1ZWRlIHNlciBjZXJvLCBsYSBwZW5kaWVudGUgcGFyYSBlbCBncnVwbyBjb24gZWwgdHJhdGFtaWVudG8gZXMgbmVnYXRpdmEuIApcbmV3bGluZQoKQ29tcGFyYWNpw7NuIGRlIGRldmlhbnphcyBkZSBsb3MgbW9kZWxvcyAyIHkgMyBub3MgZGFuIHVuYSBwcnVlYmEgcGFyYSBsYSBpZ3VhbGRhZCBkZSBsb3MgZWZlY3RvcyBkZSBsYSBmdWVyemEgY2VudHLDrWZ1Y2EgZGVsIGdydXBvIGNvbnRyb2wgeSBkZWwgZ3J1cG8gdHJhdGFkbzogRF8zLURfMj0wLjQ5MSwgbG8gY3VhbCBlcyBjb25zaXN0ZW50ZSBjb24gbGEgaGlww7N0ZXNpcyBkZSBxdWUgbG9zIGVmZWN0b3MgZGUgYWxtYWNlbmFtaWVudG8gbm8gc29uIGRpZmVyZW50ZXMuIExhcyBwcm9wb3JjaW9uZXMgb2JzZXJ2YWRhcyB5IGxvcyBjb3JyZXNwb25kaWVudGVzIHZhbG9yZXMgYWp1c3Rkb3MgcGFyYSBsb3MgbW9kZWxvcyAxIHkgMiBzZSBtdWVzdHJhbiBlbiBsYSB0YWJsYSBzaWd1aWVudGU6Cgp8IENvbmRpY2nDs24gZGUgYWxtYWNlbmFtaWVudG8gfCBOw7ptZXJvIGRlbCByZWdyZXNvciB8IEZyZWN1ZW5jaWEgb2JzZXJ2YWRhIHwgICAgICAgICAgIHwgRnJlY3VlbmNpYXMgZXNwZXJhZGFzIHwgICAgICAgICAgfAp8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLXwKfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgfCBNb2RlbG8gMSAgfCBNb2RlbG8gMiAgICAgICAgICAgICAgfCBNb2RlbG8gMyB8CnwgQ29udHJvbCAgICAgICAgICAgICAgICAgICAgIHwgJHhfMSQgICAgICAgICAgICAgICB8IDU1ICAgICAgICAgICAgICAgICAgIHwgNTQuODIgICAgIHwgNTguNzUgICAgICAgICAgICAgICAgIHwgNjIuOTEgICAgfAp8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICR4XzIkICAgICAgICAgICAgICAgfCA1MiAgICAgICAgICAgICAgICAgICB8IDUyLjQ3ICAgICB8IDUyLjAzICAgICAgICAgICAgICAgICB8IDU2LjQwICAgIHwKfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAkeF8zJCAgICAgICAgICAgICAgIHwgNTcgICAgICAgICAgICAgICAgICAgfCA1Ni43MiAgICAgfCA1My4yMiAgICAgICAgICAgICAgICAgfCA1OC4xOCAgICB8CnwgVHJhdGFtaWVudG8gICAgICAgICAgICAgICAgIHwgJHhfMSQgICAgICAgICAgICAgICB8IDU1ICAgICAgICAgICAgICAgICAgIHwgNTQuODMgICAgIHwgNTEuMDEgICAgICAgICAgICAgICAgIHwgNDYuODggICAgfAp8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICR4XzIkICAgICAgICAgICAgICAgfCA1MCAgICAgICAgICAgICAgICAgICB8IDUwLjQzICAgICB8IDUwLjU5ICAgICAgICAgICAgICAgICB8IDQ2LjE0ICAgIHwKfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAkeF8zJCAgICAgICAgICAgICAgIHwgNTAgICAgICAgICAgICAgICAgICAgfCA0OS43NCAgICAgfCA1My40MCAgICAgICAgICAgICAgICAgfCA0OC40OSAgICB8CgpFcyBjbGFybyBxdWUgZWwgbW9kZWxvIDEgYWp1c3RhIG11eSBiaWVuIGxvcyBkYXRvcywgc2luIGVtYmFyZ28sIG5vIGVzIGRlIHNvcnByZW5kZXIgcHVlcyBlbiBkaWNobyBtb2RlbG8gc2UgdXRpbGl6YXJvbiA0IHBhcsOhbWV0cm9zIHBhcmEgZGVzY3JpYmlyIHNlaXMgZGF0b3MsIHBvciBsbyBxdWUgc2UgZXN0w6EgcHJlc2VudGFuZG8gdW4gc29icmVhanVzdGUgY29uc2lkZXJhYmxlLgoKIyMjIyAqKlNlY2Npw7NuIDcuNSBFc3RhZMOtc3RpY29zIGRlIGJvbmRhZCBkZSBhanVzdGUqKgoKRW4gbHVnYXIgZGUgdXRpbGl6YXIgZXN0aW1hY2nDs24gcG9yIG3DoXhpbWEgdmVyb3NpbWlsaXR1ZCwgcG9kcsOtYW1vcyB1dGlsaXphciBsb3MgcGFyw6FtZXRyb3MgdXRpbGl6YW5kbyBtw61uaW1vcyBjdWFkcmFkb3MgcG9uZGVyYWRvcy4gRXMgZGVjaXIsIG1pbmltaXphbmRvIGEgc2lndWllbnRlIHN1bWEgZGUgY3VhZHJhZG9zIHBvbmRlcmFkYToKXFsKU197d309XHN1bV97aT0xfV5OXGZyYWN7KHlfaS1uX2lccGlfaSleMn17bl9pXHBpX2koMS1ccGlfaSl9LApcXQpwdWVzdG8gcXVlICRFKFlfaSk9bl9pXHBpX2kkIHkgJFZhcihZX2kpPW5faVxwaV9pKDEtXHBpX2kpJC4KTG8gYW50ZXJpb3IgZXMgZXF1aXZhbGVudGUgYSBtaW5pbWl6YXIgZWwgZXN0YWTDrXN0aWNvIENoaS1jdWFkcmFkbyBkZSBQZWFyc29uLCBkYWRvIHBvcjoKXFsKWF57Mn09XHN1bVxmcmFjeyhvLWUpXjJ9e2V9LApcXQpkb25kZSAkbyQgcmVwcmVzZW50YSBsYXMgZnJlY3VlbmNpYXMgb2JzZXJ2YWRhcywgJGUkIHJlcHJlc2VudGEgbGFzIGZyZWN1ZW5jaWFzIGVzcGVyYWRhcyB5IGxhIHN1bWEgZXMgc29icmUgdG9kb3MgbG9zIHBvc2libGVzIHZhbG9yZXMgZGUgJGkkLiAKXG5ld2xpbmUKCkN1YW5kbyAkWF4yJCBlcyBldmFsdWFkbyBlbiBsYXMgZnJlY3VlbmNpYXMgZXN0aW1hZGFzIGVzcGVyYWRhcywgZWwgZXN0YWTDrXN0aWNvIGVzOgpcWwpYXjI9XHN1bV97aT0xfV5OIFxmcmFjeyh5X2ktbl9pXGhhdHtccGlfaX0pXjJ9e25faVxoYXR7XHBpX2l9KDEtXGhhdHtccGlfaX0pfSwKXF0KZWwgY3VhbCBlcyBhc2ludMOzdGljYW1lbnRlIGVxdWl2YWxlbnRlIGEgbGEgZGV2aWFuemEgZGVzY3JpdGEgZW4gbGEgc2VjY2nDs24gYW50ZXJpb3IsIGFqdXN0YWRhIGEgZXN0ZSBjb250ZXh0bzoKClxbCkQ9MlxzdW1fe2k9MX1ee059XGxlZnRbeV9pXGxvZ1xmcmFje3lfaX17bl9pXGhhdHtccGlfaX19KyhuX2kteV9pKVxsb2dcZnJhYwp7bi15X2l9e24tbl9pXGhhdHtccGlfaX19XHJpZ2h0XQpcXQoKTGEgcHJ1ZWJhIGRlIGxhIHJlbGFjacOzbiBlbnRyZSBlbCBlc3RhZMOtc3RpY28gJFheMiQgeSBsYSBkZXZpYW56YSAkRCQgYW50ZXJpb3IsIHVzYSBzZXJpZXMgZGUgVGF5bG9yLgpcbmV3bGluZQoKTGEgZGlzdHJpYnVjacOzbiBhc2ludMOzdGljYSBkZSAkRCQsIGJham8gbGEgaGlww7N0ZXNpcyBkZSBxdWUgZWwgbW9kZWxvIGVzIGNvcnJlY3RvLCBlcyAkRFxzaW0gXGNoaV4yKE4tcCkkLCB5IHBvciBsbyB0YW50byBzZWfDum4gbG8gYW50ZXJpb3IsICRYXjJcc2ltXGNoaV4yKE4tcCkkLiBMYSBlbGVjY2nDs24gZW50cmUgJEQkIHkgJFheMiQgZGVwZW5kZXLDoSBkZSBsYSBhZGVjdWFjacOzbiBkZSBsYSBhcHJveGltYWNpw7NuIGEgbGEgZGlzdHJpYnVjacOzbiBhbnRlcmlvci4gClxuZXdsaW5lCgpTZSBoYSBlbmNvbnRyYWRvIGV2aWRlbmNpYSBkZSBxdWUgJFheMiQgZXMgYSBtZW51ZG8gbWVqb3IgcXVlICREJCwgcHVlc3RvIHF1ZSAkRCQgZXMgaW5kZWJpZGFtZW50ZSBpbmZsdcOtZG8gcG9yIGZyZWN1ZW5jaWFzIG11eSBwZXF1ZcOxYXMuIEFkZW3DoXMsIGVzIHNhYmlkbyBxdWUgYW1iYXMgYXByb3hpbWFjaW9uZXMgc2Vyw6FuIG1hbGFzIHNpIGxhcyBmcmVjdWVuY2lhcyBlc3BlcmFkYXMgc29uIGRlbWFzaWFkbyBwZXF1ZcOxYXMuClxuZXdsaW5lCgpFbiBwYXJ0aWN1bGFyLCBzaSBjYWRhIG9ic2VydmFjacOzbiB0aWVuZSB1biBwYXRyw7NuIGRlIGNvdmFyaWFuemFzIGRlIHRhbCBmb3JtYSBxdWUgJHlfaSQgZXMgY2VybyBvIDEgKGJpbmFyaW8pLCBlbnRvbmNlcyBuaW5ndW5vIGRlIGxvcyBlc3RhZMOtc3RpY29zIGFudGVyaW9yZXMgbm9zIGRhIHVuYSBtZWRpZGEgw7p0aWwgZGUgYWp1c3RlLiBFc3RvIHB1ZWRlIHN1Y2VkZXIgc2kgbGFzIHZhcmlhYmxlcyByZWdyZXNvcmFzIHNvbiB0b2RhcyBjb250aW51YXMsIHBvciBlamVtcGxvLgpcbmV3bGluZQoKRW4gZXN0ZSBjYXNvLCBkZSBhY3VlcmRvIGEgSG9zbWVyIHkgTGVtZXNob3csIGxhIG1lam9yIG1hbmVyYSBkZSBhYm9yZGFyIGVzdGEgc2l0dWFjacOzbiBlcyBhZ3J1cGFyIGxhcyBvYnNlcnZhY2lvbmVzIGVuIGNhdGVnb3LDrWFzIGNvbiBiYXNlIGVuIHN1cyBwcm9iYWJpbGlkYWRlcyBwcmVkaWNoYXMuIFTDrXBpY2FtZW50ZSAxMCBncnVwb3Mgc29uIHVzYWRvcyBjb24gYXByb3hpbWFkYW1lbnRlIHVuYSBjYW50aWRhZCBpZ3VhbCBkZSBvYnNlcnZhY2lvbmVzIGVuIGNhZGEgZ3J1cG8uIExvcyBuw7ptZXJvcyBkZSDDqXhpdG9zIHkgZnJhY2F6b3Mgb2JzZXJ2YWRvcyBlbiBjYWRhIHVubyBkZSBsb3MsIGRpZ2Ftb3MsICRnJCBkaXN0aW50b3MgZ3J1cG9zLCBzb24gcmVzdW1pZG9zIGNvbW8gZW4gbGEgdGFibGEgNy4xLiBMdWVnbywgZWwgZXN0YWTDrXN0aWNvIGNoaS1jdWFkcmFkYSBkZSBQZWFyc29uIHBhcmEgdW5hIHRhYmxhIGNvbW8gbGEgYW50ZXJpb3Igc2UgcHVlZGUgY2FsY3VsYXIgeSB1c2FyIGNvbW8gdW5hIG1lZGlkYSBkZSBhanVzdGUuClxuZXdsaW5lCgpBIHRhbCBlc3RhZMOtc3RpY28gc2UgbGUgZGVub21pbmEgZXN0YWTDrXN0aWNvIEhvc21lci1MZW1lc2hvdywgeSBzZSBkZW5vdGEgcG9yICRYXjJfe0hMfSQuIFNlIGhhIGVuY29udHJhZG8gcXVlIGxhIGRpc3RyaWJ1Y2nDs24gbXVlc3RyYWwgZGUgZXN0ZSBlc3RhZMOtc3RpY28gZXMgYXByb3hpbWFkYW1lbnRlICRcY2hpXjIoZy0yKSQuIApcbmV3bGluZQoKQSBtZW51ZG8gbGEgZnVuY2nDs24gZGUgbG9nLXZlcm9zaW1pbGl0dWQgcGFyYSBlbCBtb2RlbG8gYWp1c3RhZG8gZXMgY29tcGFyYWRhIGNvbiBsYSBmdW5jacOzbiBkZSBsb2ctdmVyb3NpbWlsaXR1ZCBwYXJhIHVuIG1vZGVsbyBtaW5pbWFsLCBlbiBlbCBjdWFsIGxvcyB2YWxvcmVzICRccGlfaSQgc29uIHRvZG9zIGlndWFsZXMgKGVuIGNvbnRyYXN0ZSBjb24gZWwgbW9kZWxvIHNhdHVyYWRvIHF1ZSBlcyB1c2FkbyBwYXJhIGRlZmluaXIgbGEgZGV2aWFuemEpLiBCYWpvIGVsIG1vZGVsbyBtaW5pbWFsLCAKXFsKXHBpPVxmcmFje1xzdW0geV9pfXtcc3VtIG5faX0KXF0KCkFzw60sIHNpIGRlbm90YW1vcyBwb3IgJFxoYXR7XHBpX2l9JCBhbCB2YWxvciBlc3RpbWFkbyBkZSBsYSBwcm9iYWJpbGlkYWQgcGFyYSAkWV9pJCBiYWpvIGVsIG1vZGVsbyBkZSBpbnRlcsOpcyAoZGUgdGFsIGZvcm1hIHF1ZSAkXGhhdHt5X2l9PW5faVxoYXR7XHBpX3tpfX0kKSwgZWwgZXN0YWTDrXN0aWNvIGRlZmluaWRvIHBvcgpcWwpDPTJbbChcaGF0e1xwaX07eSktbChccGk7eSldClxdCmRvbmRlICRsJCBlcyBsYSBmdW5jacOzbiBkZSBsb2ctdmVyb3NpbWlsaXR1ZCwgc2UgY29ub2NlIGNvbW8gZWwgZXN0YWTDrXN0aWNvIGRlIGNvY2llbnRlIGRlIHZlcm9zaW1pbGl0dWRlcyBjaGktY3VhZHJhZG8uClxuZXdsaW5lCgpTZSBwdWVkZSB2ZXIgcXVlIGxhIGRpc3RyaWJ1Y2nDs24gbXVlc3RyYWwgYXByb3hpbWFkYSBwYXJhICRDJCBlcyAkXGNoaV4yKHAtMSkkIHNpIHRvZG9zIGxvcyAkcCQgcGFyw6FtZXRyb3MsIGV4Y2VwdG8gZWwgaW50ZXJjZXB0bywgc29uIGNlcm8uIERlIG90cmEgZm9ybWEsICRDJCB0ZW5kcsOhIHVuYSBkaXN0cmlidWNpw7NuIG5vIGNlbnRyYWwuIEFzw60sICRDJCBlcyB1biBlc3RhZMOtc3RpY28gZGUgcHJ1ZWJhIHBhcmEgbGEgaGlww7N0ZXNpcyBkZSBxdWUgbmluZ3VuYSBkZSBsYXMgdmFyaWFibGVzIGV4cGxpY2F0aXZhcyBlcyBuZWNlc2FyaWEgcGFyYSB1biBtb2RlbG8gc2VuY2lsbG8uClxuZXdsaW5lCgpQb3Igw7psdGltbywgZGUgbWFuZXJhIGFuw6Fsb2dhIGFsIGNvZWZpY2llbnRlIGRlIGRldGVybWluYWNpw7NuICRSXjIkIGRlIGxvcyBtb2RlbG9zIGRlIHJlZ3Jlc2nDs24gbcO6bHRpcGxlLCBvdHJvIGVzdGFkw61zdGljbyBhIHZlY2VzIHV0aWxpemFkbyBlcyBlbCAicHNldWRvIFJeMiI6ClxbCnBzZXVkbyBSXjI9XGZyYWN7bChccGk7eSktbChcaGF0e1xwaX07eSl9e2woXHBpO3kpfSwKXF0KZWwgY3VhbCByZXByZXNlbnRhIGxhIG1lam9yYSBwcm9wb3JjaW9uYWwgZW4gbGEgZnVuY2nDs24gZGUgbG9nLXZlcm9zaW1pbGl0dWQgZGViaWRhIGEgbG9zIHTDqXJtaW5vcyBlbiBlbCBtb2RlbG8gZGUgaW50ZXLDqXMsIGNvbXBhcmFkbyBjb24gZWwgbW9kZWxvIG1pbmltYWwuIEVzdGUgZXMgcHJvZHVjaWRvIHBvciBhbGd1bm9zIHByb2dyYW1hcyBlc3RhZMOtc3RpY29zIGNvbW8gdW4gZXN0YWTDrXN0aWNvIGRlIGJvbmRhZCBkZSBhanVzdGUuCgo8IS0tIFBhcnRlIDMtLT4KCgojIyMjICoqU2VjY2nDs24gNy42IFJlc2lkdWFsZXMqKgoKRXhpc3RlbiBkb3MgdGlwb3MgZGUgcmVzaWR1YWxlcyBwcmluY2lwYWxlcyBwYXJhICREJCB5ICRYXjIkIGVuIGVsIG1vZGVsbyBkZSByZWdyZXNpw7NuIGxvZ8Otc3RpY2EuIFNpIGhheSAkbSQgKipwYXRyb25lcyBkZSBsb3MgcmVncmVzb3JlcyoqLCBlbnRvbmNlcyBzZSBwZXVkZW4gY2FsY3VsYXIgJG0kIHJlc2lkdWFsZXMuIFNlYSAkWV9rJCBsYSBjYW50aWRhZCBkZSDDqXhpdG9zLCAkbl9rJCBsYSBjYW50aWRhZCBkZSByZWFsaXphY2lvbmVzIHkgJFxoYXQgXHBpX2skIGxhIHByb2JhYmlsaWRhZCBlc3RpbWFkYSBkZSDDqXhpdG8gcGFyYSBlbCAkayQtw6lzaW1vIHBhdHLDs24gZGUgcmVncmVzb3Jlcy4gRGVmaW5pbW9zIGVsICoqcmVzaWR1YWwgZGUgUGVhcnNvbioqIG8gKipyZXNpZHVhbCBqaSBjdWFkcmFkYSoqIGNvbW8sCgokJCBYX2sgPSBcZnJhY3soeV9rIC0gbl9rXGhhdFxwaV9rKX17XHNxcnR7bl9rIFxoYXRccGlfaygxLVxoYXRccGlfayl9fSwgXHFxdWFkIGsgPSAxLCBcZG90cywgbS4gJCQKCkNvbiBlc3RvLCB0ZW5lbW9zLCBwb3IgbGEgZGVmaW5pY2nDs24gYW50b3Jpb3JtZW50ZSBkYWRhIGRlbCBlc3RhZMOtc3RpY28gJFheMiQgZGUgYm9uZGFkIGRlIGFqdXN0ZSBkZSBQZWFyc29uIHF1ZQoKJCQgXHN1bV97az0xfV5tIFhfa14yID0gWF4yLiAkJAoKTG9zICoqcmVzaWR1YWxlcyBlc3RhbmRhcml6YWRvcyBkZSBQZWFyc29uKiogc29uLAoKJCQgcl97UGt9ICA9IFxmcmFje1hfa317XHNxcnR7MSAtIGhfa319LCAkJAoKZG9uZGUgJGhfayQgZXMgZWwgYXBhbGFuY2Ftb2VudG8gcXVlIHNlIG9idGllbmUgZGUgbGEgbWF0cml6ICpoYXQqIGRlbCBtb2RlbG8uCgpMb3MgKipyZXNpZHVhbGVzIGRlIGRldmlhbnphKiogcHVlZGVuIHNlciBkZWZpbmlkb3MgZGUgbWFuZXJhIHNpbWlsYXIsCgokJCBkX2sgPSBcdGV4dHtzaWdufSh5X2sgLSBuX2sgXGhhdCBccGlfaykgXGxlZnRceyAyIFxsZWZ0WyB5X2sgXGxvZyBcbGVmdCggXGZyYWN7eV9rfXtuX0tcaGF0XHBpX2t9XHJpZ2h0KSArIChuX2sgLSB5X2spXGxvZyBcbGVmdCggXGZyYWN7bl9rIC0geV9rfXsgbl9rIC0gbl9rIFxoYXQgXHBpX2sgfSBccmlnaHQpICAgXHJpZ2h0XSBccmlnaHRcfV57MS8yfSwgJCQgZG9uZGUgbG9zIHTDqXJtaW5vcyBcJFx0ZXh0e3NpZ259KHlfayAtIG5fayBcaGF0IFxwaVxfaykgXCQgZ2FyYW50aXphbiBxdWUgJGRfayQgdGVuZ2EgZWwgbWlzbW8gcXVlICRYX2skLiBEZSBsYSBkZWZpbmljacOzbiBkZSBsYSBkZXZpYW56YSBwb2RlbW9zIHZlciBxdWUKCiQkIEQgPSBcc3VtX3trPTF9Xm0gZF9rXjIuICQkCgpMb3MgKipyZXNpZHVhbGVzIGRlIGRldmlhbnphIGVzdGFuZGFyaXphZG9zKiogc29uCgokJHJfe0RrfSA9IFxmcmFje2Rfa317XHNxcnR7MSAtIGhfa319LiQkCgpBbCBpZ3VhbCBxdWUgZW4gZWwgY2FzbyBkZSBsYSByZWdyZXNpw7NuIGxpbmVhbCwgbG9zIHJlc2lkdWxlcyBkZSBQZWFyc29uIHkgZGUgZGV2aWFuemEgcHVlZGVuIHNlciB1c2Fkb3MgcGFyYSB2ZXJpZmljYXIgZWwgYWp1c3RlIGRlbCBtb2RlbG8geSBlbCBjdW1wbGltaWVudG8gZGUgbG9zIHN1cHVlc3Rvcy4gRWplbXBsb3MgZGUgdXNvcyBzb24gZ3JhZmljYXJsb3MgY29udHJhIGxvcyByZWdyZXNvcmVzLCBvIGdyw6FmaWNvcyBkZSBub3JtYWxpZGFkLCB5YSBxdWUgY3VhbmRvIGxhIGNhYW50aWRhZCBkZSBkYXRvcyBlcyBsbyBzdWZpY2llbnRlbWVudGUgZ3JhbmRlLCBsb3MgcmVzaWR1YWxlcyBzZSBjb21wb3J0YW4gYXByb3hpbWFkYW1lbnRlIG5vcm1hbGVzLgoKU2kgbG9zIGRhdG9zIHNvbiBiaW5hcmlvcyBvIHNpIGhheSB1bmEgY2FudGlkYWQgcmVsYXRpdmFtZW50ZSBwZXF1ZcOxYSBkZSBvYnNlcnZhY2lvbmVzIHBvciBjYWRhIHBhdHLDs24gZGUgbG9zIHJlZ3Jlc29yZXMsIGVudG9uY2VzIGxhcyBncsOhZmljYXMgZGUgcmVzaWR1YWxlcyBzZXLDoW4gbm8gaW5mb3JtYXRpdmFzLCB5IHBvciBsbyB0YW50byBoYWJyw6EgcXVlIHJlY3VycmlyIGEgb3Ryb3MgZGlhZ27Ds3N0aWNvcy4KCioqU2VjY2nDs24gNy43IE90cm9zIGRpYWduw7NzdGljb3MqKgoKRXhpc3RlbiBlc3RhZMOtc3RpY29zIHBhcmEgZGV0ZWN0YXIgb2JzZXJ2YWNpb25lcyBpbmZsdXllbnRlcyBlbiBsYSByZWdyZXNpw7NuIGxvZ8Otc3RpY2EgKGxvcyBhbsOhbG9nb3MgcGFyYSBsYSByZWdyZXNpw7NuIGxpbmVhbCBtw7psdGlwbGUgc2UgZXhwb25lbiBlbiBsYSBzZWNjacOzbiA2IGRlbCBsaWJybykuIEVuIGVsIGNhc28gZGUgcmVncmVzacOzbiBsaW5lYWwgbcO6bHRpcGxlLCBlc3RzbyBlc3RhZMOtc3RpY29zIGxsYW1hZG9zIGRlbHRhLWJldGEsIGRlbHRhLWRldmlhbnphIHkgZGVsdGEtamkgY3VhZHJhZGEsIGVzIHNpbXBsZW1lbnRlIGxhIGRpZmVyZW5jaWEgZW50cmUgZWwgZXN0aW1hZG9yIGNhbGN1bGFkb3IgdXNhbmRvIHRvZG9zIGxvcyBwdW50b3Mgb2JzZXJ2YWRvcyB5IGVsIGVzdGltYWRvciBjYWxjdWxhZG8gcXVpdGFuZG8gdW5vIGRlIGxvcyBwdW50b3MsIHNpbWlsYXIgYSBsb3MgcmVzaWR1YWxlcyBQUkVTUy4gUG9yIGVqZW1wbG8sIGVsIGVzdGFkw61zdGljbyBkZWx0YS1iZXRhIGVzLAoKJCQgXERlbHRhX2kgXGhhdCBcYmV0YV9qID0gYl9qIC0gYl97aihpKX0sICQkCgpkb25kZSAkYl9qJCBlcyBlbCBlc3RpbWFkb3IgZGUgJFxiZXRhX2okIHVzYW5kbyB0b2RvcyBsb3MgZGF0b3MgeSAkXGJldGFfe2ooaSl9JCBlcyBlbCBlc3RpbWFkb3Igb2J0ZW5pZG8gYWwgcXVpdGFyIGxhICRpJC3DqXNpbWEgb2JzZXJ2YWNpw7NuLiBFbiBlbCBjYXNvIGRlIGxhIHJlZ3Jlc2nDs24gbG9nw61zdGljYSBlcyBwb3NpYmxlIGVuY29udHJhciBlc3RhZMOtc3RpY29zIHNpbWlsYXJlcyBwYXJhIG1lZGlyIGVsIG5pdmVsIGRlIGFqdXN0ZSBkZWwgbW9kZWxvLgoKQ3VhbmRvIHRlbmVtb3MgcmVzcHVlc3RhcyBiaW5hcmlhcywgaGF5IG3DoXMgY29zYXMgcXVlIGNvbnNpZGVyYXIsIGxvIHByaW1lcm8gZXMgbGEgZWxlY2Npw7NuIGRlIG51ZXN0cmEgZnVuY2nDs24gbGlnYS4gVW4gZW5mb3F1ZSBlcyBjb25zaWRlcmFyIGxhIGZhbWlsaWEgZ2VuZXJhbCBkZSBmdW5jaW9uZXMKCiQkIGcoXHBpLFxhbHBoYSkgPSBcbG9nXGxlZnRbIFxmcmFjeygxLVxwaSleey1cYWxwaGF9IC0xfXtcYWxwaGF9IFxyaWdodF0uICQkCgpDdWFuZG8gJFxhbHBoYSA9IDEkLCBlbnRvbmNlcyAkZyhccGkpPSBcbG9nW1xwaS8oMS1ccGkpXSQsIGxhIGZ1bmNpw7NuIGxvZ2l0LiBDdWFuZG8gJFxhbHBoYVx0byAwJCwgJGcoXHBpKSBcdG8gXGxvZ1stXGxvZygxLVxwaSldJCwgbGEgZnVuY2nDs24gbG9nLWxvZyBjb21wbGVtZW50YXJpYS4gRW4gcHJpbmNpcGlvLCB1biB2YWxvciDDs3B0aW1vIGRlICRcYWxwaGEkIHB1ZWRlIHNlciBlc3RpbWFkbyBkZSBsb3MgZGFydG9zLCBwZXJvIGVsIHByb2Nlc28gcmVxdWllcmUgdmFyaW9zIHBhc29zLiBDb21vIG5vIGV4aXN0ZSB1biBzb2Z0d2FyZSBhZGVjdWFkbyBwYXJhIGVuY29udHJhciBhICRcYWxwaGEkLCBzZSByZWNvbWllbmRhIGV4cGVyaW1lbnRhciBjb24gZGl2ZXJzYXMgZnVuY2lvbmVzIGxpZ2EuCgpFbCBzZWd1bmRvIHByb2JsZW1hIGFsIGV2YWx1YXIgbGEgYWRlY3VhY2nDs24gZGUgbG9zIG1vZGVsb3MgcGFyYSBkYXRvcyBiaW5hcmlvcyBlcyBsYSAqKnNvYnJlZGlzcGVyc2nDs24qKi4gTG9zIHZhbG9yZXMgb2JzZXJ2YWRvcyAkWV9pJCBwb2Ryw61hbiB0ZW5lciB1bmEgdmFyaWFuemEgbcOhcyBncmFuZGUgcXVlIGxhIHZhcmlhbnphIHRlw7NyaWNhIGRlIGxhIGRpc3RyaWJ1Y2nDs24gYmlub21pYWwgcHJvcHVlc3RhIChkZWJpZG8gYSBxdWUgZW4gZXN0YSBkaXN0cmlidWNpw7NuLCB1biDDum5pY28gcGFyw6FtZXRybyBkZXRlcm1pbmEgbGEgbWVkaWEgeSBsYSB2YXJpYW56YSkuIEVzdG8gcHVlZGUgc2VyIHVuIGluZGljYWFkb3IgZGUgcXVlIGxhIGRldmlhbnphIGVzIG3DoXMgZ3JhbmRlIHF1ZSBlbCB2YWxvciBlc3BlcmFkbyBkZSAkTi1wJCwgeSBwb2Ryw61hIHNlciBjYXVzYWRvIHBvciBxdWUgZWwgbW9kZWxvIGVzdMOhIHN1YmVzcGVjaWZpY2FkbywgbyBwb3JxdWUgdGllbmUgdW5hIGVzdHJ1Y3R1cmEgbcOhcyBjb21wbGVqYSBxdWUgZWwgbW9kZWxvIHByb3B1ZXN0by4KClVuYSBhbHRlcm5hdGl2YSBwYXJhIHNvbHVjaW9uYXIgZXN0ZSBwcm9ibGVtYSBlcyBpbmNvcnBvcmFyIHVuIHBhcsOhbWV0cm8gZXh0cmEgJFxwaGkkIGVuIGVsIG1vZGVsbywgZGUgZm9ybWEgcXVlICRWYXIoWV9pKSA9IG5faVxwaV9pKDEtXHBpX2kpXHRoZXRhJCwgZW4gYFJgLCBlc3RvIHNlIGxvZ3JhIGFsIGVzcGVjaWZpY2FyIHVuIG1vZGVsbyBjdWFzaWJpbm9taWFsIGVuIGx1Z2FyIGRlIGJpbm9taWFsIGVuIGxhIGZ1bmNpw7NuIFxgYGdsbWAuIFVuYSBwb3NpYmxlIGV4cGxpY2FjacOzbiBkZSBsYSBzb2JyZWRpc3BlcnNpw7NuIGRlIGxvcyBkYXRvcywgZXMgcXVlIGxhcyBvYnNlcnZhY2lvbmVzIGVuIHJlYWxpZGFkIG5vIHNlYW4gaW5kZXBlbmRpZW50ZXMsIGxvIHF1ZSBjYXVzYSBxdWUgZW4gY2llcnRvcyBwYXRyb25lcyBkZWwgcmVncmVzb3Igc2UgdGVuZ2EgdW5hIG1lbm9yIGNhbnRpZGFkIGRlIG9ic2VydmFjaW9uZXMgZWZlY3RpdmFzIGFsIGV4aXN0aXIgY29ycmVsYWNpw7NuLgoKIyMjICoqU2VjY2nDs24gNy44IEVqZW1wbG86IFNlbmlsaWRhZCB5IFdBSVMqKgoKU2UgcmVhbGl6w7MgdW4gZXhhbWVuIHBzaXF1acOhdHJpY28gYSB1bmEgbXVlc3RyYSBkZSBwZXJzb25hcyBtYXlvcmVzIHBhcmEgZGV0ZXJtaW5hciBxdcOpIHPDrW50b21hcyBkZSBzZW5pbGlkYWQgcHJlc2VudGFiYW4uIE90cmFzIG1lZGlkYXMgdG9tYWRhcyBhbCBtaXNtbyB0aWVtcG8gaW5jbHV5ZXJvbiBlbCBwdW50YWplIGRlIHVuIHN1YmNvbmp1bnRvIGVuIGxhIEVzY2FsYSBkZSBJbnRlZWxpZ2VuY2lhIEFkdWx0YSBkZSBXZWNoc2xlciAoV0FJUykuIExvcyB2YWxvcmVzIHJlZ2lzdHJhZG9zIHNlIGVuY3VlbnRyYW4gZW4gbGEgc2lndWllbnRlIHRhYmxhICgkcyQgZXMgbGEgcHJlc2VuY2lhIGRlIHPDrW50b21hcyBkZSBzZW5pbGlkYWQgeSAkeCQgZWwgV0FJUykuIE5vcyBpbnRlcmVzYSBtb2RlbGFyICRzJCBjb21vIHVuYSBmdW5jacOzbiBkZSAkeCQuCgp8IHggICB8IHMgICB8IHggICB8IHMgICB8IHggICB8IHMgICB8IHggICB8IHMgICB8IHggICB8IHMgICB8CnwtLS0tLXwtLS0tLXwtLS0tLXwtLS0tLXwtLS0tLXwtLS0tLXwtLS0tLXwtLS0tLXwtLS0tLXwtLS0tLXwKfCA5ICAgfCAxICAgfCA3ICAgfCAxICAgfCA3ICAgfCAwICAgfCAxNyAgfCAwICAgfCAxMyAgfCAwICAgfAp8IDEzICB8IDEgICB8IDUgICB8IDEgICB8IDE2ICB8IDAgICB8IDE0ICB8IDAgICB8IDEzICB8IDAgICB8CnwgNiAgIHwgMSAgIHwgMTQgIHwgMSAgIHwgOSAgIHwgMCAgIHwgMTkgIHwgMCAgIHwgOSAgIHwgMCAgIHwKfCA4ICAgfCAxICAgfCAxMyAgfCAwICAgfCA5ICAgfCAwICAgfCA5ICAgfCAwICAgfCAxNSAgfCAwICAgfAp8IDEwICB8IDEgICB8IDE2ICB8IDAgICB8IDExICB8IDAgICB8IDExICB8IDAgICB8IDEwICB8IDAgICB8CnwgNCAgIHwgMSAgIHwgMTAgIHwgMCAgIHwgMTMgIHwgMCAgIHwgMTQgIHwgMCAgIHwgMTEgIHwgMCAgIHwKfCAxNCAgfCAxICAgfCAxMiAgfCAwICAgfCAxNSAgfCAwICAgfCAxMCAgfCAwICAgfCAxMiAgfCAwICAgfAp8IDggICB8IDEgICB8IDExICB8IDAgICB8IDEzICB8IDAgICB8IDE2ICB8IDAgICB8IDQgICB8IDAgICB8CnwgMTEgIHwgMSAgIHwgMTQgIHwgMCAgIHwgMTAgIHwgMCAgIHwgMTAgIHwgMCAgIHwgMTQgIHwgMCAgIHwKfCA3ICAgfCAxICAgfCAxNSAgfCAwICAgfCAxMSAgfCAwICAgfCAxNiAgfCAwICAgfCAyMCAgfCAwICAgfAp8IDkgICB8IDEgICB8IDE4ICB8IDAgICB8IDYgICB8IDAgICB8IDE0ICB8IDAgICB8ICAgICB8ICAgICB8CgpFbiBlc3RlIGNhc28sIGNvbW8gaGF5IHVuIHNvbG8gcmVncmVzb3IsIGxvcyBwYXRyb25lcyBkZSByZWdyZXNvcmVzIHNvbiBzaW1wbGVtZW50ZSBsb3Mgbml2ZWxlcyBkZSAkeCQuIEVzdG9zIHNlIHJlc3VtZW4gZW4gbGEgdGFibGEgYSBjb250aW51YWNpw7NuLgoKfCB4ICAgIHwgeSAgIHwgbiAgIHwgJFxoYXRccGkkICAgICAgICAgfCBYICAgICAgIHwgZCAgICAgICB8CnwtLS0tLS18LS0tLS18LS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS18LS0tLS0tLS0tfAp8IDQgICAgfCAxICAgfCAyICAgfCAwLjc1MSAgICAgICAgICAgICB8IC0wLjgyNiAgfCAtMC43NjYgIHwKfCA1ICAgIHwgMCAgIHwgMSAgIHwgMC42ODcgICAgICAgICAgICAgfCAwLjY3NSAgIHwgMC44NjYgICB8CnwgNiAgICB8IDEgICB8IDIgICB8IDAuNjE0ICAgICAgICAgICAgIHwgLTAuMzMgICB8IC0wLjMyNiAgfAp8IDcgICAgfCAxICAgfCAzICAgfCAwLjUzNSAgICAgICAgICAgICB8IDAuNDU4ICAgfCAwLjQ2NCAgIHwKfCA4ICAgIHwgMCAgIHwgMiAgIHwgMC40NTQgICAgICAgICAgICAgfCAxLjU1MSAgIHwgMS43NzcgICB8CnwgOSAgICB8IDQgICB8IDYgICB8IDAuMzc2ICAgICAgICAgICAgIHwgLTAuMjE0ICB8IC0wLjIxNiAgfAp8IDEwICAgfCA1ICAgfCA2ICAgfCAwLjMwMyAgICAgICAgICAgICB8IC0wLjcyOCAgfCAtMC43NzEgIHwKfCAxMSAgIHwgNSAgIHwgNiAgIHwgMC4yNCAgICAgICAgICAgICAgfCAtMC40MTkgIHwgLTAuNDM2ICB8CnwgMTIgICB8IDIgICB8IDIgICB8IDAuMTg2ICAgICAgICAgICAgIHwgLTAuNjc1ICB8IC0wLjkwNiAgfAp8IDEzICAgfCA1ICAgfCA2ICAgfCAwLjE0MiAgICAgICAgICAgICB8IDAuMTc2ICAgfCAwLjE3MiAgIHwKfCAxNCAgIHwgNSAgIHwgNyAgIHwgMC4xMDcgICAgICAgICAgICAgfCAxLjUzNSAgIHwgMS4zMDYgICB8CnwgMTUgICB8IDMgICB8IDMgICB8IDAuMDggICAgICAgICAgICAgIHwgLTAuNTA5ICB8IC0wLjcwNSAgfAp8IDE2ICAgfCA0ICAgfCA0ICAgfCAwLjA1OSAgICAgICAgICAgICB8IC0wLjUgICAgfCAtMC42OTYgIHwKfCAxNyAgIHwgMSAgIHwgMSAgIHwgMC4wNDMgICAgICAgICAgICAgfCAtMC4yMTMgIHwgLTAuMjk3ICB8CnwgMTggICB8IDEgICB8IDEgICB8IDAuMDMyICAgICAgICAgICAgIHwgLTAuMTgxICB8IC0wLjI1NCAgfAp8IDE5ICAgfCAxICAgfCAxICAgfCAwLjAyMyAgICAgICAgICAgICB8IC0wLjE1NCAgfCAtMC4yMTYgIHwKfCAyMCAgIHwgMSAgIHwgMSAgIHwgMC4wMTcgICAgICAgICAgICAgfCAtMC4xMzEgIHwgLTAuMTg0ICB8CnwgU3VtYSB8IDQwICB8IDU0ICB8ICAgICAgICAgICAgICAgICAgIHwgICAgICAgICB8ICAgICAgICAgfAp8ICAgICAgfCAgICAgfCAgICAgfCBTdW1hIGRlIGN1YWRyYWRvcyB8IDguMDg0XCogfCA5LjQxOFwqIHwKCkVsIG1vZGVsbyBkZSByZWdlc2nDs24gYWp1c3RhZG8KCiQkIFxsb2dcbGVmdCggXGZyYWN7XHBpX2l9ezEgLSBccGlfaX0gXHJpZ2h0KSA9IFxiZXRhXzEgKyBcYmV0YV8yIHhfaTsgXHFxdWFkIFlfaSBcc2ltIFx0ZXh0e0Jpbn0obl9pLFxwaV9pKSBccXVhZCBpID0gMSwgXGRvdHMsIG0sICAkJAoKZnVlIGFqdXN0YWRvIGNvbiBsb3Mgc2lndWllbnRlcyByZXN1bHRhZG9zOgoKJGJfMSA9IDIuNDA0JCwgY29uIGVycm9yIGVzdMOhbmRhciBzZSQoYl8xKSA9IDEuMTkyJDsgJGJfMiA9IC0wLjMyMzUkLCBjb24gZXJyb3IgZXN0w6FuZGFyIHNlJChiXzIpID0gMC4xMTQwJDsgJFheMiA9IFxzdW0gWF9pXjIgPSA4LjA4MyQsIHkgJEQgPSBcc3VtIGRfaV4yID0gOS40MTkkLgoKQ29tbyBoYXkgJG09MTckIHBhdHJvbmVzIGRlIGNvdmFyaWFudGVzIHkgJHA9MiQgcGFyw6FtZXRyb3MsICRYXjIkIHkgJEQkIHB1ZWRlbiBzZXIgY29tcGFyYWRvcyBjb24gJFxjaGleMl97MTV9JC4KCkxhIHNpZ3VpZW50ZSBlcyBsYSBncsOhZmljYSBkZSBuaXZlbGVzIGRlbCByZWdyZXNvciB2cy4gZnJlY3VlbmNpYSBvYnNlcnZhZGEuCgpgYGB7cn0KbGlicmFyeShkcGx5cikKeCA8LSBjKDksIDEzLCA2LCA4LCAxMCwgNCwgMTQsIDgsIDExLCA3LCA5LCA3LCA1LCAxNCwgMTMsIDE2LCAxMCwgMTIsIDExLCAxNCwgMTUsIDE4LCA3LCAxNiwgOSwgOSwgMTEsIDEzLCAxNSwgMTMsIDEwLCAxMSwgNiwgMTcsIDE0LCAxOSwgOSwgMTEsIDE0LCAxMCwgMTYsIDEwLCAxNiwgMTQsIDEzLCAxMywgOSwgMTUsIDEwLCAxMSwgMTIsIDQsIDE0LCAyMCkKcyA8LSBjKDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDApCgpkYXRhIDwtIGRhdGEuZnJhbWUoIGNiaW5kKHgscykpCmNvbG5hbWVzKGRhdGEpIDwtIGMoIngiLCAicyIpCgpnZGF0YSA8LSBncm91cF9ieShkYXRhLHgpCnJlc3VtZW4gPC0gc3VtbWFyaXplKGdkYXRhLCBzdW09c3VtKHMpLCBuPW4oKSwgcGk9c3VtKHMpL24pCgpwbG90KHJlc3VtZW4keCxyZXN1bWVuJHBpLCB4bGFiPSJQdW50YWplIFdBSVMiLCB5bGFiPSJQcm9wb3JjacOzbiBjb24gc8OtbnRvbWFzIikKCmV4aXRvIDwtIGFzLmNoYXJhY3RlcihzKQoKYGBgCgpBanVzdGFtb3MgZWwgbW9kZWxvIGNvbiBsYSBmdW5jacOzbiBgZ2xtYC4KCmBgYHtyfQpyZXMuZ2xtIDwtIGdsbShkYXRhJHMgfiBkYXRhJHgsIGZhbWlseT1iaW5vbWlhbChsaW5rPSJsb2dpdCIpKQpzdW1tYXJ5KHJlcy5nbG0pCmBgYAoKR3LDoWZpY2EgZGUgbGEgY3VydmEgbG9nw61zdGljYSBjb250cmEgbG9zIGRhdG9zIG9ic2VydmFkb3MuIFBvZGVtb3Mgbm90YXIgcXVlIGVsIGFqdXN0ZSBlcyBtZWpvciBwYXJhIHZhbG9yZXMgbcOhcyBncmFuZGVzIGRlbCByZWdyZXNvci4KCmBgYHtyfQpmaXQgPC0gKGV4cCggcmVzLmdsbSRjb2VmZmljaWVudHNbMV0gKyByZXMuZ2xtJGNvZWZmaWNpZW50c1syXSpyZXN1bWVuJHggKSApIC8gKCggMSArIGV4cCggcmVzLmdsbSRjb2VmZmljaWVudHNbMV0gKyByZXMuZ2xtJGNvZWZmaWNpZW50c1syXSpyZXN1bWVuJHggKSApKQoKcGxvdChyZXN1bWVuJHgscmVzdW1lbiRwaSwgeGxhYj0iUHVudGFqZSBXQUlTIiwgeWxhYj0iUHJvcG9yY2nDs24gY29uIHPDrW50b21hcyIpCmxpbmVzKHJlc3VtZW4keCwgZml0ICkKYGBgCgpgYGB7cn0KcmVzdW1lbgpgYGAKCkNvbW8gZW4gY2FkYSBuaXZlbCBkZWwgcmVncmVzb3IgaGF5IHBvY2FzIG9iZXJ2YWNpb25lcywgcG9kcsOtYW1vcyB1c2FyIGVsIGVuZm9xdWUgZGUgSG9zbWVyLUxlbWVzaG93IHBhcmEgZXZhbHVhciBlbCBhanVzdGUuIEVuIGxhIHNpZ3VpZW50ZSB0YWJsYSBzZSBtdWVzdHJhIGVsIHJlc3VtZW4gZGVsIG3DqXRvZG8gcGFyYSAkZz0zJCBjYXRlZ29yw61hcy4KCnwgVmFsdWVzIG9mICRcaGF0IFxwaSQgICAgICB8ICAgICB8ICRcbGUgMC4xMDckIHwgMC4xMDggLSAwLjMwMyB8IFw+IDAuMzAzIHwKfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLXwtLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tfAp8IENvcnJlc3BvbmRpbmcgdmFsdWVzIG9mIHggfCAgICAgfCAxNCAtIDIwICAgICB8IDEwIC0gMTMgICAgICAgfCA0IC0gOSAgICB8CnwgTnVtYmVyIG9mIHBlb3BsZSAgICAgICAgICB8IG8gICB8IDIgICAgICAgICAgIHwgMyAgICAgICAgICAgICB8IDkgICAgICAgIHwKfCB3aXRoIHN5bXB0b21zICAgICAgICAgICAgIHwgZSAgIHwgMS4zMzUgICAgICAgfCA0LjQ3OSAgICAgICAgIHwgOC4xODYgICAgfAp8IE51bWJlciBvZiBwZW9wbGUgICAgICAgICAgfCBvICAgfCAxNiAgICAgICAgICB8IDE3ICAgICAgICAgICAgfCA3ICAgICAgICB8Cnwgd2l0aG91dCBzeW1wdG9tcyAgICAgICAgICB8IGUgICB8IDE2LjY2NSAgICAgIHwgMTUuNTIxICAgICAgICB8IDcuODE0ICAgIHwKfCBUb3RhbCBudW1iZXIgb2YgcGVvcGxlICAgIHwgICAgIHwgMTggICAgICAgICAgfCAyMCAgICAgICAgICAgIHwgMTYgICAgICAgfAoKRWwgZXN0YWTDrXN0aWNvIGRlIEhvc21lci1sZW1lc2hvdyBlcyBvYnRlbmlkbyBhbCBjYWxjdWxhciAkWF4yID0gXHN1bSBcZnJhY3soby1lKV4yfXtlfSQsIGNvbiBlc3RvIG9idGVuZW1vcyAkWF97SEx9XjIgPSAxLjE1JCwgcXVlIG5vIGVzIHRhbiBzaWdpbmlmaWNhdGl2byBjb21wYXJhZG8gY29uIHVuYSBkaXN0cmlidWNpw7NuICRcY2hpXjJfMSQuCgojIyMjICoqRXh0cmE6IEVqZW1wbG8gY29uIGJhc2UgZGUgZGF0b3MgVGl0YW5pYyoqCgpgYGB7cn0Kc2V0d2QoIkM6XFxVc2Vyc1xcRXNhw7psXFxEb2N1bWVudHNcXE1hZXN0csOtYSBlbiBQcm9iYWJpbGlkYWQgeSBFc3RhZMOtc3RpY2FcXDIgU2VndW5kbyBzZW1lc3RyZVxcTW9kZWxvcyBlc3RhZMOtc3RpY29zIElcXFByZXNlbnRhY2nDs24gZmluYWwiKQp0aXRhbmljIDwtIHJlYWQuY3N2KCJ0aXRhbmljLmNzdiIpCmhlYWQodGl0YW5pYykKYGBgCgpBanVzdGFtb3MgdW4gbW9kZWxvIGRlIHJlZ3Jlc2nDs24gbG9nw61zdGljYSBwYXJhIGV4cGxpY2FyIGxhIHN1cGVydml2ZW5jaWEgZW4gZnVuY2nDs24gZGUgbGEgZWRhZC4KCmBgYHtyfQptb2RlbG8udGl0YW5pYyA8LSBnbG0odGl0YW5pYyRTdXJ2aXZlZCB+IHRpdGFuaWMkQWdlLCBmYW1pbHk9Ymlub21pYWwobGluaz0ibG9naXQiKSkKc3VtbWFyeShtb2RlbG8udGl0YW5pYykKYGBgCgpgYGB7cn0KZ3RpdCA8LSBncm91cF9ieSh0aXRhbmljLEFnZSkKcmVzdW1lbi50aXQgPC0gc3VtbWFyaXplKGd0aXQsIEV4aXRvcz1zdW0oU3Vydml2ZWQpLCBuPW4oKSwgcGk9c3VtKFN1cnZpdmVkKS9uKQpyZXN1bWVuLnRpdApgYGAKCmBgYHtyfQpmaXQudGl0IDwtIChleHAoIHJlcy5nbG0kY29lZmZpY2llbnRzWzFdICsgcmVzLmdsbSRjb2VmZmljaWVudHNbMl0qcmVzdW1lbi50aXQkQWdlICkgKSAvICgoIDEgKyBleHAoIHJlcy5nbG0kY29lZmZpY2llbnRzWzFdICsgcmVzLmdsbSRjb2VmZmljaWVudHNbMl0qcmVzdW1lbi50aXQkQWdlICkgKSkKCnBsb3QocmVzdW1lbi50aXQkQWdlLHJlc3VtZW4udGl0JHBpLCB4bGFiPSJFZGFkIiwgeWxhYj0iUHJvcG9yY2nDs24gZGUgc3VwZXJ2aXZpZW50ZXMiKQpsaW5lcyhyZXN1bWVuLnRpdCRBZ2UsIGZpdC50aXQgKQpgYGAKCg==