Capítulo 3: Estimación de la posibilidad por maximización directa

3.1. Introducción

Vimos anteriormente que la posibilidad de un HMM está dada por

\[ L_T = Pr(X^{(T)} = x^{(T)}) = \delta P(x_1) \Gamma P(x_2)... \Gamma P(x_T)1' \] Donde \(δ\) es la distribución inicial y P(x) la matriz diagonal m×m con su i-esimo elemento diagonal siendo la probabilidad estado-dependiente o densidad \(p_i (x)\). En principio, podemos entonces computar \(L_T=α_T 1'\) recursivamente medianteDonde \(δ\) es la distribución inicial y P(x) la matriz diagonal m×m con su i-esimo elemento diagonal siendo la probabilidad estado-dependiente o densidad \(p_i (x)\). En principio, podemos entonces computar \(L_T=α_T 1'\) recursivamente mediante

\[ \alpha_1 = \delta P(x_1) \\ y\\ \alpha_t = \alpha_{t-1} \Gamma P(x_t), para \quad t=2,3,...,T \]

Si se asume que la cadena de Markov es estacionaria (en cuyo caso \(δ=δΓ\), podemos en vez usar

\[ \alpha_0 = \delta \\ y\\ \alpha_t = \alpha_{t-1} \Gamma P(x_t). para\quad t=1,2,...,T \]

Primero consideraremos el caso estacionario.

El número de operaciones involucradas es de orden \(Tm^2\), haciendo la evaluación de la posibilidad bastante factible incluso para un gran T. La estimación de parámetros puede ser entonces realizada por maximización numérica de la posibilidad respecto a los parámetros. Pero existen algunos problemas que necesitan ser abordados cuando los parámetros son estimados de esta manera. Los problemas principales son el desbordamiento numérico, restricciones en los parámetros, y múltiples máximos locales en la función de posibilidad.

3.2. Escalando la computación de la posibilidad

En el caso de distribuciones estado-dependientes discretas, los elementos de \(α_t\), siendo productos de probabilidades, se vuelven progresivamente más pequeño conforme t incremente, y son eventualmente redondeados a cero. De hecho, con una probabilidad de 1, la posibilidad se acerca a 0 (o posiblemente \(∞\) en el caso continuo) exponencialmente rápido. Desde que la posibilidad es un producto de matrices, no escalares, no es posible evitar el desbordamiento numero simplemente al computar el registro de la posibilidad como la suma de los registros de sus factores. En este caso, la computación de la posibilidad de un modelo de mezcla independiente es más fácil que el de un HMM. Para resolver este problema, Durbin (1998, p. 78) sugiere un método de computación que cuenta con la siguiente aproximación. Suponga que deseamos computar \(log(p+q)\), donde\(p>q\). Escriba \(log(p+q)\) como \[ log(p)+log(1+q/p)=log(p)+log(1+exp(q̃-p ̃)) \] , donde \(p ̃=log(p) \quad y \quad q ̃=log(q)\). La función \(log(1+e^x)\) es entonces aproximada por interpolación de una tabla de sus valores; aparentemente tal pequeña tabla dará un grado razonable de exactitud. Preferimos computar el logaritmo de \(L_T\) al usar una estrategia de escalar el vector de probabilidades de avance \(α_t\). Efectivamente escalamos el vector \(α_t\) en cada tiempo t para que sus elementos sumen a 1, llevando récord de la suma de los registros de los factores de escala aplicados. Defina, para \(t=0,1,…,T\) el vector

\[ \phi_t =\alpha_t/w_t\]

Donde \(w_t=\sum_i α_t (i)=α_t 1'\). Primero, notamos ciertas consecuencias inmediatas de las definiciones de \(ϕ_t\) y \(w_t\):

\[ w_o = \alpha_01' = \delta1' = 1 \\ \phi_0 = \delta \\ w_t \phi_t = w_{t-1} \phi_{t-1} \Gamma P(x_t) \\ L_T = \alpha_T 1' = w_T(\phi_T 1') = w_T \]

Por lo tanto \(L_T=w_T=∏_{t=1}^T(w_t/w_{t-1})\). Y de la ecuación anterior tenemos que \(w_t=w_{t-1} (ϕ_{t-1} Γ P(x_t)1')\), y asi concluimos que

\[ logL_T = \sum_{t=1}^T log(w_t/w_{t-1}) = \sum_{t=1}^T log(\phi_{t-1} \Gamma P(x_t) 1') \]

La computación de la posibilidad de registro esta sumarizada a continuación en la forma de un algoritmo. Note que \(Γ\) y \(P(x_t)\) son matrices de m×m, v y \(ϕ_t\) son vectores de longitud m, u es un escalar, y l es el escalar en el cual la posibilidad de registro es acumulada.

\[ \phi_0 \leftarrow \delta; l \leftarrow0 \\ for \quad t=1,2,...,T \\ v \leftarrow \phi_{t-1} \Gamma P(x_t) \\ u \leftarrow v1' \\ l \leftarrow l + log(u) \\ \phi_t \leftarrow v/u \\ return \quad l \]

La posibilidad de registro requerida, \(loga(L_T)\), es entonces dada por el valor final de l. Este procedimiento prevendrá casi siempre desbordamiento. Claramente, variaciones menores de esta técnica son posibles: el factor de escala \(w_t\) podría ser elegido en lugar para ser el elemento más grande del vector siendo escalado, o la media de sus elementos (opuesto a la suma). El algoritmo es fácilmente modificado para computar la posibilidad de registro sin asumir estacionariedad de la cadena de Markov. Con \(δ\) denotando la distribución inicial, el algoritmo más general es

\[ w_1 \leftarrow \delta P(x_1) 1' ;\quad \phi_1 \leftarrow \delta P(x_1)/w_1 ; \quad l \leftarrow log(w_1) \\ for \quad t=2,3,...,T \\ v \leftarrow \phi_{t-1} \Gamma P(x_t) \\ u \leftarrow v1' \\ l \leftarrow l + log(u)\\ \phi_t \leftarrow v/u \\ return \quad l \]

Si la distribución inicial ocurre ser la distribución inicial, este algoritmo todavía aplica. El siguiente código implementa esta ultima versión del algoritmo para asi computar la posibilidad de registro de las observaciones \(x_1,…,x_T\) bajo un HMM de Poisson con al menos dos estados, matriz de probabilidad de transición \(Γ\), vector de medias estado-dependientes \(λ\) y distribución inicial \(δ\).

alpha <- delta*dpois(x[1], lambda)
lscale <- log(sum(alpha))
alpha <- alpha/sum(alpha)
for(i in 2:T){
  alpha <- alpha %*% Gamma*dpois(x[i], lambda)
  lscale <- lscale + log(sum(alpha))
  alpha <- alpha/sum(alpha)
}
lscale

3.3. Maximización de la posibilidad sujeta a restricciones

3.3.1 Re parametrización para evitar restricciones

Los elementos de \(Γ\) y aquellos de \(λ\), el vector de medias estado-dependientes en un HMM de Poisson, están sujetos a no negatividad y otras restricciones. En particular, la suma de las filas de \(Γ\) es igual a 1. Los estimados de los parámetros debería satisfacer también tales restricciones. Por ende, al maximizar la posibilidad, necesitamos resolver un problema de optimización restringida. En general, existen dos grupos de restricciones: aquellas que aplican a los parámetros de las distribuciones estado-dependientes y aquellas que aplican a los parámetros de la cadena de Markov. El primer grupo de restricciones depende en cual(es) distribución(es) estado-dependiente(s) son elegidas.

En el caso de un HMM de Poisson las restricciones relevantes son:

  • Las medias \(λ_i\) de las distribuciones estado-dependientes deben, para \(i=1,…,m\) ser no negativos.
  • Las filas de la matriz de probabilidad de transición \(Γ\) deben sumar a 1, y todos los parámetros \(γ_{ij}\) deben ser no negativos.

Aquí las restricciones pueden ser impuestas al hacer transformaciones. La transformación de los parámetros \(λ_i\) es fácil. Defina \(η_i=loga(λ_i)\), para \(i=1,…,m\). Entonces \(η_i∈R\). Luego que hemos maximizado la posibilidad con respecto a los parámetros no restringidos, los parámetros estimados restringidos pueden ser obtenidos al transformar de vuelta: \((λ_i )=expa(η_i))\).Note que \(Γ \) tiene \(m^2\) entradas pero solo \(m(m-1)\) parametros libres, asi como hay m restricciones suma de filas

\[ \sum_{j=1}^m \gamma_{ij} =1 \quad (i=1,...,m) \]

Mostraremos una posible transformación entre las \(m^2\) probabilidades restringidas \(γ_{ij}\) y \(m(m-1)\) números reales sin restricción \(τ_{ij},i≠j\). Por razones de visibilidad se muestra el caso para m=3. Empezaremos por definir la matriz

\[ \left(\begin{array}{cc} - , \tau_{12},\tau_{13}\\ \tau_{21} , - , \tau_{23}\\ \tau_{31} , \tau_{32} , - \end{array}\right) \]

Una matriz on \(m(m-1)\) entradas \(τ_{ij}∈R\). Ahora que \(g:R→R^+\) sea una función estrictamente incremental, por ejemplo

\[ g(x) = e^x \quad o \quad g(x) = \begin{cases} e^x \quad x \le 0 \\ x+1 \quad x \ge 0 \end{cases} \\ Define \quad que \\ v_{ij} = \begin{cases} g(\tau_{ij}) \quad para \quad i \neq j \\ 1 \quad para \quad i = j \end{cases} \]

Entonces fijamos \(γ_{ij}=v_{ij}/\sum_{k=1}^m v_{ik}\) (para i,j=1,2,…,m) y \(Γ=(γ_{ij})\). Nos referiremos a los parámetros \(η_i\) y \(τ_{ij}\) como parámetros funcionales, y a los parámetros \(λ_i\) y \(γ_{ij}\) como parámetros naturales.

Usando las transformaciones anteriores de \(Γ\) y \(λ\), podemos realizar el calculo de los parámetros maximizantes de la posibilidad en dos pasos

  • Maximizar \(L_T\) con respecto a los parámetros funcionales \(T={τ_{ij}}\) y \(η=(η_1,…,η_m)\). Todos estos son sin restricciones.
  • Transformar los estimados de los parámetros funcionales a estimados de parámetros naturales:

\[ T \rightarrow \Gamma , \eta \rightarrow \lambda \]

Considere \(Γ\) para el caso \(g(x)=e^x\) y m general. Tenemos entonces

\[ \gamma_{ij} = \frac{exp(\tau_{ij})}{1+ \sum_{k \neq i} exp(\tau_{ik})},\quad para \quad i\neq j \] Y los elementos diagonales de \(Γ\) siguen de la suma de filas de 1. La transformación en la dirección opuesta es

\[ \tau_{ij} = log(\frac{\gamma_{ij}}{1-\sum_{k \neq i}\gamma_{ik}}) = log(\gamma_{ij}/\gamma_{ii}),\quad para \quad i \neq j \] Ahora mostramos un código relativamente simple que transformara parámetros naturales a funcionales y viceversa. Este código refiere a un HMM de Poisson con m>2 estados, en el cual la cadena de Markov puede, si es apropiado, ser asumida estacionaria. En ese caso la distribución estacionaria \(δ\) no es dada, pero es computada cuando sea necesitada del t.p.m. \(Γ\) al resolver \(δ(I_m-Γ+U)=1\). De otra manera, \(δ\) es tratada como un parámetro (natural) y transformada para así remover las restricciones \(δ_i≥0\) y \(\sum_iδ_i=1\).

# Transformar los parámetros naturales de Poisson en parámetros de trabajo.
pois.HMM.pn2pw <- function(m,lambda,gamma,delta=NULL,stationary=TRUE)
{
 tlambda <- log(lambda)
 foo     <- log(gamma/diag(gamma))
 tgamma  <- as.vector(foo[!diag(m)])
 if(stationary) {tdelta <-NULL} else {tdelta<-log(delta[-1]/delta[1])}
 parvect <- c(tlambda,tgamma,tdelta)
 return(parvect)
}

# Transformar los parámetros de trabajo de Poisson en parámetros naturales.

pois.HMM.pw2pn <- function(m,parvect,stationary=TRUE)
{
 lambda        <- exp(parvect[1:m])
 gamma         <- diag(m)
 gamma[!gamma] <- exp(parvect[(m+1):(m*m)])
 gamma         <- gamma/apply(gamma,1,sum)
 if(stationary) {delta<-solve(t(diag(m)-gamma+1),rep(1,m))} else
                {foo<-c(1,exp(parvect[(m*m+1):(m*m+m-1)]))
                delta<-foo/sum(foo)}
 return(list(lambda=lambda,gamma=gamma,delta=delta))
}

3.4. Otros problemas

3.4.1. Múltiples máximos en la posibilidad

La posibilidad de un HMM es una función complicada de los parámetros y frecuentemente tiene varios máximos locales. La meta por supuesto es encontrar el máximo global, pero no hay un método simple de determinar en general si un algoritmo de maximización numérica ha alcanzado el máximo global. Dependiendo de los valores iniciales, puede suceder que el algoritmo fácilmente identifique un local, pero no el máximo, global. Esto también aplica al principal método alterno de estimación, el algoritmo EM. Una estrategia sensible entonces es usar un rango de valores iniciales para la maximización, y ver si el mismo máximo es identificado en cada caso.

3.4.2. Valores iniciales para las iteraciones

Es a menudo fácil el encontrar posibles valores iniciales para algunos de los parámetros de un HMM: por ejemplo, si uno busca el fijar un HMM de Poisson con dos estados, y la media de muestra es 10, uno podría probar 8 y 12, o 5 y 15, para los valores de las dos medias estado-dependientes. Estrategias mas sistemáticas basadas en los cuantiles de las observaciones son posibles, sin embargo. Por ejemplo, si el modelo tiene tres estados, use como los valores iniciales de las medias estado-dependientes el cuartil menor, mediano y cuartil superior de las cuentas observadas. Es menos fácil el adivinar valores de las probabilidades de transición \(γ_{ij}\). Una estrategia es el asignar un valor inicial común a todas las posibilidades de transición fuera de la diagonal. Una consecuencia de tal decisión, quizá conveniente, es que la distribución estacionaria correspondiente es uniforme sobre los estados; esto sigue por simetría. Elegir buenos valores iniciales para los parámetros tiende a alejarlo a uno de inestabilidad numérica.

3.4.3. Posibilidad sin limites

En el caso de HMMs con distribuciones continuas estado-dependientes, puede suceder que la posibilidad es sin límites en la proximidad de ciertas combinaciones de parámetros.

Serie de Terremotos - Seccion izquierda: Distribuciones de Poisson - HMM con dos y tres estados. Seccion Derecha: medios dependientes del estado en comparacion con las observaciones

Serie de Terremotos - Seccion izquierda: Distribuciones de Poisson - HMM con dos y tres estados. Seccion Derecha: medios dependientes del estado en comparacion con las observaciones

Como antes, sugerimos que, si esto crea dificultado, se maximize la posibilidad discreta en vez de la densidad conjunta.

3.5. Ejemplo: Terremotos

La figura anterior muestra el resultado de ajustar HMMs de Poisson (estacionarios) con dos a tres estados a la serie de terremotos por medias del optimizador no restringido nlm. El modelo de dos estados es

\[ \Gamma = \left(\begin{array}{cc} 0.9340 , 0.00660\\ 0.1285 , 0.8715 \end{array}\right) \]

Con \(δ=(0.6608,0.3392)\),\(λ=(15.472,26.125)\), y la posibilidad de registro dada por \(l=-342.3183\). Es claro que la mezcla (dependiente de Markov) ajustada de dos distribuciones de Poisson provee un mejor ajuste a la distribución marginal de las observaciones que lo hace una única distribución de Poisson, pero el ajuste puede seguir siendo mejorado al usar una mezcla de 3 o 4 distribuciones de Poisson.

library(HiddenMarkov)
library(readr)
#-----  Poisson Distribution  -----
#leer la data 
x_data<- read.table("/Users/bracruz/Documents/8vo. Trimestre IO/Sist. Expertos y Redes Prob./earthquakes.txt")[,2]
Pi <- matrix(c(0.9340, 0.066,
               0.1285, 0.8715),
             byrow=TRUE, nrow=2)
delta <- c(0.6608, 0.3392)
x <- dthmm(x_data, Pi, delta, "pois", list(lambda=c(15.472, 26.125)),
           discrete = TRUE)
#    use above parameter values as initial values
y <- BaumWelch(x)
iter = 1 
LL = -342.3180692 
diff = Inf 

iter = 2 
LL = -341.8839295 
diff = 0.4341397 

iter = 3 
LL = -341.8808283 
diff = 0.003101278 

iter = 4 
LL = -341.8799367 
diff = 0.0008916081 

iter = 5 
LL = -341.8794228 
diff = 0.0005138536 

iter = 6 
LL = -341.8791236 
diff = 0.0002991765 

iter = 7 
LL = -341.8789489 
diff = 0.0001747594 

iter = 8 
LL = -341.8788465 
diff = 0.000102314 

iter = 9 
LL = -341.8787865 
diff = 5.999939e-05 

iter = 10 
LL = -341.8787513 
diff = 3.522865e-05 

iter = 11 
LL = -341.8787306 
diff = 2.070391e-05 

iter = 12 
LL = -341.8787184 
diff = 1.217641e-05 

iter = 13 
LL = -341.8787113 
diff = 7.165123e-06 
print(summary(y))
$delta
[1] 1.000000e+00 2.259134e-31

$Pi
          [,1]       [,2]
[1,] 0.9284124 0.07158762
[2,] 0.1191548 0.88084524

$nonstat
[1] TRUE

$distn
[1] "pois"

$pm
$pm$lambda
[1] 15.42342 26.02398


$discrete
[1] TRUE

$n
[1] 107
#log-likelihood ideal
print(logLik(y))
[1] -341.8787
{h<-hist(residuals(y))
xfit <- seq(min(residuals(y)), max(residuals(y)), length = 40) 
yfit <- dnorm(xfit, mean = mean(residuals(y)), sd = sd(residuals(y))) 
yfit <- yfit * diff(h$mids[1:2]) * length(residuals(y)) 
lines(xfit, yfit, col = "#0066ff", lwd = 2)}

El modelo de tres estados es:

\[ \Gamma = \left(\begin{array}{cc} 0.9555 , 0.024 , 0.021\\ 0.050 , 0.8899 , 0.051 \\ 0.000 , 0.197 , 0.803 \end{array}\right) \]

Con \(δ=(0.4436,0.4045,0.1519)\),\(λ=(13.146,19.721,29.7144)\) y \(l=-329.4603\).

library(HiddenMarkov)
library(readr)
#-----  Poisson Distribution  -----
#leer la data 
x_data<- read.table("/Users/bracruz/Documents/8vo. Trimestre IO/Sist. Expertos y Redes Prob./earthquakes.txt")[,2]
Pi <- matrix(c(0.9555 , 0.024 , 0.021 ,
0.050 , 0.8899 , 0.051 , 
0.000 , 0.197 ,  0.803),
             byrow=TRUE, nrow=3)
delta <- c(0.4436,0.4045,0.1519)
x <- dthmm(x_data, Pi, delta, "pois", list(lambda=c(13.146,19.721,29.714)),
           discrete = TRUE)
#    use above parameter values as initial values
y <- BaumWelch(x)
iter = 1 
LL = -329.9251807 
diff = Inf 

iter = 2 
LL = -328.5465037 
diff = 1.378677 

iter = 3 
LL = -328.5278471 
diff = 0.01865661 

iter = 4 
LL = -328.5274950 
diff = 0.0003520581 

iter = 5 
LL = -328.5274853 
diff = 9.758334e-06 
print(summary(y))
$delta
[1] 9.999999e-01 9.681354e-08 6.078985e-21

$Pi
           [,1]       [,2]       [,3]
[1,] 0.93930599 0.03207267 0.02862135
[2,] 0.04039751 0.90637871 0.05322378
[3,] 0.00000000 0.19036700 0.80963300

$nonstat
[1] TRUE

$distn
[1] "pois"

$pm
$pm$lambda
[1] 13.13389 19.71215 29.70890


$discrete
[1] TRUE

$n
[1] 107
#log-likelihood ideal
print(logLik(y))
[1] -328.5275
{h<-hist(residuals(y))
xfit <- seq(min(residuals(y)), max(residuals(y)), length = 40) 
yfit <- dnorm(xfit, mean = mean(residuals(y)), sd = sd(residuals(y))) 
yfit <- yfit * diff(h$mids[1:2]) * length(residuals(y)) 
lines(xfit, yfit, col = "#ff0000", lwd = 2)}

El modelo de cuatro estados es: \[ \Gamma = \left(\begin{array}{cc} 0.805, 0.102, 0.093, 0.000 \\ 0.000, 0.976, 0.000, 0.024 \\ 0.050, 0.000, 0.902, 0.048 \\ 0.000, 0.000, 0.188, 0.812 \end{array}\right) \]

Con \(δ=(0.0936,0.3983,0.3643,0.1439)\),\(λ=(11.283,13.853,19.695,29.700)\) y \(l=-327.8316\).

library(HiddenMarkov)
library(readr)
#-----  Poisson Distribution  -----
#leer la data 
x_data<- read.table("/Users/bracruz/Documents/8vo. Trimestre IO/Sist. Expertos y Redes Prob./earthquakes.txt")[,2]
Pi <- matrix(c(0.805, 0.102, 0.093, 0.000,
0.000, 0.976, 0.000, 0.024,
0.050, 0.000, 0.902, 0.048,
0.000, 0.000, 0.188, 0.812),
             byrow=TRUE, nrow=4)
delta <- c(0.0936,0.3983,0.3643,0.1439)
x <- dthmm(x_data, Pi, delta, "pois", list(lambda=c(11.283,13.853,19.695,29.700)),
           discrete = TRUE)
#    use above parameter values as initial values
y <- BaumWelch(x)
iter = 1 
LL = -327.8302182 
diff = Inf 

iter = 2 
LL = -326.9581836 
diff = 0.8720346 

iter = 3 
LL = -326.9289508 
diff = 0.02923274 

iter = 4 
LL = -326.9204573 
diff = 0.008493573 

iter = 5 
LL = -326.9134060 
diff = 0.007051262 

iter = 6 
LL = -326.9074158 
diff = 0.005990187 

iter = 7 
LL = -326.9024761 
diff = 0.004939741 

iter = 8 
LL = -326.8985207 
diff = 0.003955416 

iter = 9 
LL = -326.8954326 
diff = 0.003088091 

iter = 10 
LL = -326.8930709 
diff = 0.002361707 

iter = 11 
LL = -326.8912938 
diff = 0.001777022 

iter = 12 
LL = -326.8899734 
diff = 0.00132043 

iter = 13 
LL = -326.8890015 
diff = 0.0009718974 

iter = 14 
LL = -326.8882912 
diff = 0.0007103225 

iter = 15 
LL = -326.8877747 
diff = 0.0005164488 

iter = 16 
LL = -326.8874007 
diff = 0.0003740631 

iter = 17 
LL = -326.8871305 
diff = 0.0002701856 

iter = 18 
LL = -326.8869357 
diff = 0.0001947661 

iter = 19 
LL = -326.8867955 
diff = 0.0001401981 

iter = 20 
LL = -326.8866947 
diff = 0.000100815 

iter = 21 
LL = -326.8866223 
diff = 7.244193e-05 

iter = 22 
LL = -326.8865702 
diff = 5.202691e-05 

iter = 23 
LL = -326.8865329 
diff = 3.735121e-05 

iter = 24 
LL = -326.8865061 
diff = 2.680813e-05 

iter = 25 
LL = -326.8864868 
diff = 1.923742e-05 

iter = 26 
LL = -326.8864730 
diff = 1.380287e-05 

iter = 27 
LL = -326.8864631 
diff = 9.902635e-06 
print(summary(y))
$delta
[1]  8.887835e-05  9.999111e-01  1.172905e-46 1.444604e-128

$Pi
           [,1]       [,2]      [,3]       [,4]
[1,] 0.80911120 0.08812885 0.1027600 0.00000000
[2,] 0.00000000 0.95349019 0.0000000 0.04650981
[3,] 0.04138593 0.00000000 0.9118154 0.04679867
[4,] 0.00000000 0.00000000 0.1778585 0.82214151

$nonstat
[1] TRUE

$distn
[1] "pois"

$pm
$pm$lambda
[1] 11.25002 13.80970 19.69526 29.66059


$discrete
[1] TRUE

$n
[1] 107
#log-likelihood ideal
print(logLik(y))
[1] -326.8865
{h<-hist(residuals(y))
xfit <- seq(min(residuals(y)), max(residuals(y)), length = 40) 
yfit <- dnorm(xfit, mean = mean(residuals(y)), sd = sd(residuals(y))) 
yfit <- yfit * diff(h$mids[1:2]) * length(residuals(y)) 
lines(xfit, yfit, col = "#00ffff", lwd = 2)}

En todos estos casos el ACF es solo una combinación lineal de las k-esimas potencias de los eigenvalores distintos de 1 de la matriz de probabilidad de transición. Un fenómeno que es notable cuando uno ajusta modelos con tres o mas estados a series relativamente cortas es que los estimados de una o mas de las probabilidades de transición resulta ser muy cercana a cero.

Este fenómeno puede ser explicado como sigue. En una cadena de Markov estacionaria, el número esperado de transiciones del estado i al estado j en una serie de T observaciones es \((T-1) δ_i\) \(γ_{ij}\). Para \(δ_3=0.152\) y T=107 (como en nuestro modelo de tres estados), esta expectativa será menor que 1 si \(γ_{31}<0.062\). En tal serie, por ende, es probable que si \(γ_{31}\) es bastante pequeño no habrá transiciones del estado 3 al estado 1, y entonces cuando busquemos estimar \(γ_{31}\) en un HMM, el estimado es probable a ser efectivamente cero. Como m incremente, las probabilidades \(δ_i\) y \(γ_{ij}\) se vuelve más pequeña en promedio; esto lo hace mas probable que al menos una probabilidad de transición sea efectivamente cero.

3.6. Errores estándares e intervalos de confianza

Relativamente poco es conocido acerca de las propiedades de estimadores de máxima posibilidad de HMMs; solo resultados asintóticos están disponibles. Para explotar estos resultados se requiere estimar la matriz de varianza y covarianza de los estimadores de los parámetros. Se puede estimar los errores estándares del Hessiano de la posibilidad de registro en el máximo, pero este enfoque se encuentra con dificultades cuando algunos de los parámetros están en la frontera del espacio de su parámetro, el cual ocurre bastante a menudo cuando los HMMs son ajustados.

3.6.1. Errores estándares mediante el Hessiano

Aunque los estimados de punto \(\Theta = (\Gamma,\lambda)\) son fáciles de computar, estimados exacto de intervalo no están disponibles. Cappe (2005, Capitulo 12) muestra que, bajo ciertas condiciones de regularidad, los MLEs de parámetros de un HMM son consistentes, asintóticamente normales y eficientes. Por ende, si podemos estimar los errores estándares de los MLEs entonces, usando normalidad asintótica, podemos también computar intervalos aproximados de confianza. Sin embargo, como señala Fruhwirth-Schnatter (2006, p. 53) en el contexto de modelos independientes de mezcla, “Las condiciones de regularidad son a menudo violados, incluyendo casos de gran preocupación práctica, entre ellos sets de datos pequeños, mezclas con pesos de componentes pequeños, y mezclas de excesos con muchos componentes”. Además, McLachlan y Peel (2000, p. 68) advierten: “En particular, para modelos de mezcla, es bien conocido que el tamaño de muestra n tiene que ser muy grande antes que la teoría asintótica de la posibilidad máxima se aplique”. Con las advertencias previas en mente, podemos, en orden para estimar los errores estándares de los MLEs de un HMM, utilizar el Hessiano aproximado de menos la posibilidad de registro en el mínimo. Podemos invertirlo y así estimar la matriz de varianza y covarianza asintótica de los estimadores de los parámetros. Un problema con esta sugerencia es que, si los parámetros han sido transformados, el Hessiano disponible será el cual se refiere a los parámetros funcionales \(ϕ_i\), no los originales, para interpretarlo de mejor manera, parámetros naturales \(\Theta_i\) (\(Γ\) y \(λ\) en el caso de un HMM de Poisson). La situación es entonces que tenemos, en el mínimo de \(-l\), el Hessiano con respecto a los parámetros funcionales

\[ H = -(\frac{\partial^2l}{\partial \phi_i \partial \phi_j}) \]

Pero lo que realmente necesitamos es el Hessiano en respecto a los parámetros naturales

\[ G = -(\frac{\partial^2l}{\partial \theta_i \partial \theta_j}) \]

Existe, sin embargo, la siguiente relación entre los dos Hessianos en el mínimo

\[ H = MGM' \quad y \quad G^{-1} = M'H^{-1}M \]

Donde M es definido por \(m_{ij}=∂θ_j/∂ϕ_i\). En el caso de un HMM de Poisson, los elementos de M son bastante simples. Con M a nuestra disposición, podemos usar la relación anterior para deducir \(G^{-1}\) de \(H^{-1}\), y utilizar \(G^{-1}\) para encontrar errores estándares para los parámetros naturales, tales parámetros provistos no están en la frontera del espacio del parámetro. Una ruta alternativa para los errores estándares con respecto a los parámetros naturales el cual a menudo resulta bien, y es menos laboriosa, es la siguiente. Primero encuentre el MLE al resolver el problema de optimización restringida, luego vuelva a correr la optimización sin restricciones, empezando en o muy cercano al MLE. Si el estimado resultante es el mismo que el MLE ya encontrado, el Hessiano correspondiente entonces provee directamente los errores estándares con respecto a los parámetros naturales. Pero si uno hace la suposición de normalidad y basa un intervalo de confianza en él, tal suposición de normalidad es mas probable, pero no garantizada.

Computación recursiva del Hessiano

Un método alternativo de computar el Hessiano es el de Lystig y Hughes (2002). Ellos presentan el algoritmo de avance \(α_t=α_{t-1} ΓP(x_t)\) de manera en la cual incorporan una escala automática o “natural”, y luego extienden este enfoque para así computar su Hessiano y gradiente con respecto a los parámetros naturales, aquellos que hemos descrito arriba por \(θ_i\). Turner (2008) ha usado este enfoque para así buscar las derivadas analíticas requeridas para maximizar posibilidades de HMMs directamente por el algoritmo Levenberg-Marquardt. Aunque esto puede ser un método mas eficiente y preciso de computar el Hessiano que utilizar la relación descrita anteriormente, no resuelve el problema fundamental que el uso del Hessiano para computar errores estándares (y de allí intervalos de confianza) no es de confianza si algunos de los parámetros están en o cerca de la frontera del espacio del parámetro.

3.6.2. Errores estándares Bootstrap e intervalos de confianza

Como una alternativa a las técnicas descritas en la sección anterior, uno puede usar el Bootstrap paramétrico. Hablando burdamente, la idea del Bootstrap paramétrico es el evaluar las propiedades del modelo con parámetros \(\Theta\)usando aquellos del modelo con parámetros \(\widehat\Theta\). Los siguientes pasos son realizados para estimar la matriz de varianza-covarianza de \(\widehat\Theta\).

  1. Ajuste el modelo, compute \(\widehat\Theta\).
    1. Genere una muestra, llamada muestra Bootstrap, de observaciones del modelo ajustado, el modelo con parámetros \(\widehat\Theta\). La longitud debería ser la misma que el número original de observaciones.
    1. Estime los parámetros \(\Theta\) por \(\widehat\Theta^*\)para la muestra Bootstrap.
    1. Repita los pasos (a) y (b) B veces (con B “grande”) y registre los valores \(\widehat\Theta^*\).

La matriz de varianza-covarianza de \(\widehat\Theta\) es entonces estimada por la matriz de varianza—covarianza muestra de los estimados Bootstrap \(\widehat\Theta^*\) (b), \(b=1,2,…,B\):

\[ Var-Cov(\widehat\Theta) = \frac{1}{B-1} \sum_{b=1}^B (\widehat\Theta^*(b) - \widehat\Theta^*(\cdotp))'(\widehat\Theta^*(b) - \widehat\Theta^*(\cdotp)) \\ donde \\ \widehat\Theta^*(\cdotp) = B^{-1} \sum_{b=1}^B \Theta^*(b) \]

El Bootstrap paramétrico requiere código para generar realizaciones de un modelo ajustado. El método de Bootstrap puede ser usado para estimar intervalos de confianza directamente.

LS0tCnRpdGxlOiAiRXN0aW1hY2nDs24gcG9yIG1heGltaXphY2nDs24gZGlyZWN0YSBkZSBsYSBwcm9iYWJpbGlkYWQuIgphdXRob3I6ICJCcmF5YW4gSXZhbiBDcnV6IENvcm9uYSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKI0NhcMOtdHVsbyAzOiBFc3RpbWFjacOzbiBkZSBsYSBwb3NpYmlsaWRhZCBwb3IgbWF4aW1pemFjacOzbiBkaXJlY3RhCgoKIyMzLjEuIEludHJvZHVjY2nDs24KVmltb3MgYW50ZXJpb3JtZW50ZSBxdWUgbGEgcG9zaWJpbGlkYWQgZGUgdW4gSE1NIGVzdMOhIGRhZGEgcG9yCgokJApMX1QgPSAgUHIoWF57KFQpfSA9IHheeyhUKX0pID0gXGRlbHRhIFAoeF8xKSBcR2FtbWEgUCh4XzIpLi4uIFxHYW1tYSBQKHhfVCkxJwokJApEb25kZSBcKM60XCkgZXMgbGEgZGlzdHJpYnVjacOzbiBpbmljaWFsIHkgUCh4KSBsYSBtYXRyaXogZGlhZ29uYWwgbcOXbSBjb24gc3UgaS1lc2ltbyBlbGVtZW50byBkaWFnb25hbCBzaWVuZG8gbGEgcHJvYmFiaWxpZGFkIGVzdGFkby1kZXBlbmRpZW50ZSBvIGRlbnNpZGFkIFwocF9pICh4KVwpLiBFbiBwcmluY2lwaW8sIHBvZGVtb3MgZW50b25jZXMgY29tcHV0YXIgXChMX1Q9zrFfVCAxJ1wpIHJlY3Vyc2l2YW1lbnRlIG1lZGlhbnRlRG9uZGUgXCjOtFwpIGVzIGxhIGRpc3RyaWJ1Y2nDs24gaW5pY2lhbCB5IFAoeCkgbGEgbWF0cml6IGRpYWdvbmFsIG3Dl20gY29uIHN1IGktZXNpbW8gZWxlbWVudG8gZGlhZ29uYWwgc2llbmRvIGxhIHByb2JhYmlsaWRhZCBlc3RhZG8tZGVwZW5kaWVudGUgbyBkZW5zaWRhZCBcKHBfaSAoeClcKS4gRW4gcHJpbmNpcGlvLCBwb2RlbW9zIGVudG9uY2VzIGNvbXB1dGFyIFwoTF9UPc6xX1QgMSdcKSByZWN1cnNpdmFtZW50ZSBtZWRpYW50ZQoKJCQKXGFscGhhXzEgPSBcZGVsdGEgUCh4XzEpIFxcCnlcXApcYWxwaGFfdCA9IFxhbHBoYV97dC0xfSBcR2FtbWEgUCh4X3QpLCBwYXJhIFxxdWFkIHQ9MiwzLC4uLixUCiQkCgpTaSBzZSBhc3VtZSBxdWUgbGEgY2FkZW5hIGRlIE1hcmtvdiBlcyBlc3RhY2lvbmFyaWEgKGVuIGN1eW8gY2FzbyBcKM60Pc60zpNcKSwgcG9kZW1vcyBlbiB2ZXogdXNhcgoKJCQKXGFscGhhXzAgPSBcZGVsdGEgXFwKeVxcClxhbHBoYV90ID0gXGFscGhhX3t0LTF9IFxHYW1tYSBQKHhfdCkuIHBhcmFccXVhZCB0PTEsMiwuLi4sVAokJAoKUHJpbWVybyBjb25zaWRlcmFyZW1vcyBlbCBjYXNvIGVzdGFjaW9uYXJpby4KCkVsIG7Dum1lcm8gZGUgb3BlcmFjaW9uZXMgaW52b2x1Y3JhZGFzIGVzIGRlIG9yZGVuIFwoVG1eMlwpLCBoYWNpZW5kbyBsYSBldmFsdWFjacOzbiBkZSBsYSBwb3NpYmlsaWRhZCBiYXN0YW50ZSBmYWN0aWJsZSBpbmNsdXNvIHBhcmEgdW4gZ3JhbiBULiBMYSBlc3RpbWFjacOzbiBkZSBwYXLDoW1ldHJvcyBwdWVkZSBzZXIgZW50b25jZXMgcmVhbGl6YWRhIHBvciBtYXhpbWl6YWNpw7NuIG51bcOpcmljYSBkZSBsYSBwb3NpYmlsaWRhZCByZXNwZWN0byBhIGxvcyBwYXLDoW1ldHJvcy4KUGVybyBleGlzdGVuIGFsZ3Vub3MgcHJvYmxlbWFzIHF1ZSBuZWNlc2l0YW4gc2VyIGFib3JkYWRvcyBjdWFuZG8gbG9zIHBhcsOhbWV0cm9zIHNvbiBlc3RpbWFkb3MgZGUgZXN0YSBtYW5lcmEuIExvcyBwcm9ibGVtYXMgcHJpbmNpcGFsZXMgc29uIGVsIGRlc2JvcmRhbWllbnRvIG51bcOpcmljbywgcmVzdHJpY2Npb25lcyBlbiBsb3MgcGFyw6FtZXRyb3MsIHkgbcO6bHRpcGxlcyBtw6F4aW1vcyBsb2NhbGVzIGVuIGxhIGZ1bmNpw7NuIGRlIHBvc2liaWxpZGFkLiAKCiMjMy4yLiBFc2NhbGFuZG8gbGEgY29tcHV0YWNpw7NuIGRlIGxhIHBvc2liaWxpZGFkCgpFbiBlbCBjYXNvIGRlIGRpc3RyaWJ1Y2lvbmVzIGVzdGFkby1kZXBlbmRpZW50ZXMgZGlzY3JldGFzLCBsb3MgZWxlbWVudG9zIGRlIFwozrFfdFwpLCBzaWVuZG8gcHJvZHVjdG9zIGRlIHByb2JhYmlsaWRhZGVzLCBzZSB2dWVsdmVuIHByb2dyZXNpdmFtZW50ZSBtw6FzIHBlcXVlw7FvIGNvbmZvcm1lIHQgaW5jcmVtZW50ZSwgeSBzb24gZXZlbnR1YWxtZW50ZSByZWRvbmRlYWRvcyBhIGNlcm8uIERlIGhlY2hvLCBjb24gdW5hIHByb2JhYmlsaWRhZCBkZSAxLCBsYSBwb3NpYmlsaWRhZCBzZSBhY2VyY2EgYSAwIChvIHBvc2libGVtZW50ZSBcKOKInlwpIGVuIGVsIGNhc28gY29udGludW8pIGV4cG9uZW5jaWFsbWVudGUgcsOhcGlkby4KRGVzZGUgcXVlIGxhIHBvc2liaWxpZGFkIGVzIHVuIHByb2R1Y3RvIGRlIG1hdHJpY2VzLCBubyBlc2NhbGFyZXMsIG5vIGVzIHBvc2libGUgZXZpdGFyIGVsIGRlc2JvcmRhbWllbnRvIG51bWVybyBzaW1wbGVtZW50ZSBhbCBjb21wdXRhciBlbCByZWdpc3RybyBkZSBsYSBwb3NpYmlsaWRhZCBjb21vIGxhIHN1bWEgZGUgbG9zIHJlZ2lzdHJvcyBkZSBzdXMgZmFjdG9yZXMuIEVuIGVzdGUgY2FzbywgbGEgY29tcHV0YWNpw7NuIGRlIGxhIHBvc2liaWxpZGFkIGRlIHVuIG1vZGVsbyBkZSBtZXpjbGEgaW5kZXBlbmRpZW50ZSBlcyBtw6FzIGbDoWNpbCBxdWUgZWwgZGUgdW4gSE1NLgpQYXJhIHJlc29sdmVyIGVzdGUgcHJvYmxlbWEsIER1cmJpbiAoMTk5OCwgcC4gNzgpIHN1Z2llcmUgdW4gbcOpdG9kbyBkZSBjb21wdXRhY2nDs24gcXVlIGN1ZW50YSBjb24gbGEgc2lndWllbnRlIGFwcm94aW1hY2nDs24uIFN1cG9uZ2EgcXVlIGRlc2VhbW9zIGNvbXB1dGFyIFwobG9nKHArcSlcKSwgZG9uZGVcKHA+cVwpLiBFc2NyaWJhIFwobG9nKHArcSlcKSBjb21vCiQkCmxvZyhwKStsb2coMStxL3ApPWxvZyhwKStsb2coMStleHAoccyDLXAgzIMpKQokJAosIGRvbmRlIFwocCDMgz1sb2cocCkgXHF1YWQgeSBccXVhZCBxIMyDPWxvZyhxKVwpLiBMYSBmdW5jacOzbgpcKGxvZygxK2VeeClcKSBlcyBlbnRvbmNlcyBhcHJveGltYWRhIHBvciBpbnRlcnBvbGFjacOzbiBkZSB1bmEgdGFibGEgZGUgc3VzIHZhbG9yZXM7IGFwYXJlbnRlbWVudGUgdGFsIHBlcXVlw7FhIHRhYmxhIGRhcsOhIHVuIGdyYWRvIHJhem9uYWJsZSBkZSBleGFjdGl0dWQuClByZWZlcmltb3MgY29tcHV0YXIgZWwgbG9nYXJpdG1vIGRlIFwoTF9UXCkgYWwgdXNhciB1bmEgZXN0cmF0ZWdpYSBkZSBlc2NhbGFyIGVsIHZlY3RvciBkZSBwcm9iYWJpbGlkYWRlcyBkZSBhdmFuY2UgXCjOsV90XCkuIEVmZWN0aXZhbWVudGUgZXNjYWxhbW9zIGVsIHZlY3RvciBcKM6xX3RcKSBlbiBjYWRhIHRpZW1wbyB0IHBhcmEgcXVlIHN1cyBlbGVtZW50b3Mgc3VtZW4gYSAxLCBsbGV2YW5kbyByw6ljb3JkIGRlIGxhIHN1bWEgZGUgbG9zIHJlZ2lzdHJvcyBkZSBsb3MgZmFjdG9yZXMgZGUgZXNjYWxhIGFwbGljYWRvcy4KRGVmaW5hLCBwYXJhIFwodD0wLDEs4oCmLFRcKSBlbCB2ZWN0b3IKCiQkIFxwaGlfdCA9XGFscGhhX3Qvd190JCQKCkRvbmRlIFwod190PVxzdW1faSDOsV90IChpKT3OsV90IDEnXCkuIFByaW1lcm8sIG5vdGFtb3MgY2llcnRhcyBjb25zZWN1ZW5jaWFzIGlubWVkaWF0YXMgZGUgbGFzIGRlZmluaWNpb25lcyBkZSBcKM+VX3RcKSB5IFwod190XCk6CgokJAp3X28gPSBcYWxwaGFfMDEnID0gXGRlbHRhMScgPSAxIFxcClxwaGlfMCA9IFxkZWx0YSBcXAp3X3QgXHBoaV90ID0gd197dC0xfSBccGhpX3t0LTF9IFxHYW1tYSBQKHhfdCkgXFwKTF9UID0gXGFscGhhX1QgMScgPSB3X1QoXHBoaV9UIDEnKSA9IHdfVAokJAoKUG9yIGxvIHRhbnRvIFwoTF9UPXdfVD3iiI9fe3Q9MX1eVCh3X3Qvd197dC0xfSlcKS4gWSBkZSBsYSBlY3VhY2nDs24gYW50ZXJpb3IgdGVuZW1vcyBxdWUgXCh3X3Q9d197dC0xfSAoz5Vfe3QtMX0gzpMgUCh4X3QpMScpXCksIHkgYXNpIGNvbmNsdWltb3MgcXVlCgokJApsb2dMX1QgPSBcc3VtX3t0PTF9XlQgbG9nKHdfdC93X3t0LTF9KSA9IFxzdW1fe3Q9MX1eVCBsb2coXHBoaV97dC0xfSBcR2FtbWEgUCh4X3QpIDEnKQokJAoKTGEgY29tcHV0YWNpw7NuIGRlIGxhIHBvc2liaWxpZGFkIGRlIHJlZ2lzdHJvIGVzdGEgc3VtYXJpemFkYSBhIGNvbnRpbnVhY2nDs24gZW4gbGEgZm9ybWEgZGUgdW4gYWxnb3JpdG1vLiBOb3RlIHF1ZSBcKM6TXCkgeSBcKFAoeF90KVwpIHNvbiBtYXRyaWNlcyBkZSBtw5dtLCB2IHkgXCjPlV90XCkgc29uIHZlY3RvcmVzIGRlIGxvbmdpdHVkIG0sIHUgZXMgdW4gZXNjYWxhciwgeSBsIGVzIGVsIGVzY2FsYXIgZW4gZWwgY3VhbCBsYSBwb3NpYmlsaWRhZCBkZSByZWdpc3RybyBlcyBhY3VtdWxhZGEuCgokJApccGhpXzAgXGxlZnRhcnJvdyBcZGVsdGE7IGwgXGxlZnRhcnJvdzAgXFwKZm9yIFxxdWFkIHQ9MSwyLC4uLixUIFxcCnYgXGxlZnRhcnJvdyBccGhpX3t0LTF9IFxHYW1tYSBQKHhfdCkgXFwKdSBcbGVmdGFycm93IHYxJyBcXApsIFxsZWZ0YXJyb3cgbCArIGxvZyh1KSBcXApccGhpX3QgXGxlZnRhcnJvdyB2L3UgXFwKcmV0dXJuIFxxdWFkIGwKJCQKCgpMYSBwb3NpYmlsaWRhZCBkZSByZWdpc3RybyByZXF1ZXJpZGEsIFwobG9nYShMX1QpXCksIGVzIGVudG9uY2VzIGRhZGEgcG9yIGVsIHZhbG9yIGZpbmFsIGRlIGwuIEVzdGUgcHJvY2VkaW1pZW50byBwcmV2ZW5kcsOhIGNhc2kgc2llbXByZSBkZXNib3JkYW1pZW50by4gQ2xhcmFtZW50ZSwgdmFyaWFjaW9uZXMgbWVub3JlcyBkZSBlc3RhIHTDqWNuaWNhIHNvbiBwb3NpYmxlczogZWwgZmFjdG9yIGRlIGVzY2FsYSBcKHdfdFwpIHBvZHLDrWEgc2VyIGVsZWdpZG8gZW4gbHVnYXIgcGFyYSBzZXIgZWwgZWxlbWVudG8gbcOhcyBncmFuZGUgZGVsIHZlY3RvciBzaWVuZG8gZXNjYWxhZG8sIG8gbGEgbWVkaWEgZGUgc3VzIGVsZW1lbnRvcyAob3B1ZXN0byBhIGxhIHN1bWEpLgpFbCBhbGdvcml0bW8gZXMgZsOhY2lsbWVudGUgbW9kaWZpY2FkbyBwYXJhIGNvbXB1dGFyIGxhIHBvc2liaWxpZGFkIGRlIHJlZ2lzdHJvIHNpbiBhc3VtaXIgZXN0YWNpb25hcmllZGFkIGRlIGxhIGNhZGVuYSBkZSBNYXJrb3YuIENvbiBcKM60XCkgZGVub3RhbmRvIGxhIGRpc3RyaWJ1Y2nDs24gaW5pY2lhbCwgZWwgYWxnb3JpdG1vIG3DoXMgZ2VuZXJhbCBlcwoKJCQKd18xIFxsZWZ0YXJyb3cgXGRlbHRhIFAoeF8xKSAxJyA7XHF1YWQgXHBoaV8xIFxsZWZ0YXJyb3cgXGRlbHRhIFAoeF8xKS93XzEgOyBccXVhZCBsIFxsZWZ0YXJyb3cgbG9nKHdfMSkgXFwKZm9yIFxxdWFkIHQ9MiwzLC4uLixUIFxcCnYgXGxlZnRhcnJvdyBccGhpX3t0LTF9IFxHYW1tYSBQKHhfdCkgXFwKdSBcbGVmdGFycm93IHYxJyBcXApsIFxsZWZ0YXJyb3cgbCArIGxvZyh1KVxcClxwaGlfdCBcbGVmdGFycm93IHYvdSBcXApyZXR1cm4gXHF1YWQgbAokJAoKU2kgbGEgZGlzdHJpYnVjacOzbiBpbmljaWFsIG9jdXJyZSBzZXIgbGEgZGlzdHJpYnVjacOzbiBpbmljaWFsLCBlc3RlIGFsZ29yaXRtbyB0b2RhdsOtYSBhcGxpY2EuCkVsIHNpZ3VpZW50ZSBjw7NkaWdvIGltcGxlbWVudGEgZXN0YSB1bHRpbWEgdmVyc2nDs24gZGVsIGFsZ29yaXRtbyBwYXJhIGFzaSBjb21wdXRhciBsYSBwb3NpYmlsaWRhZCBkZSByZWdpc3RybyBkZSBsYXMgb2JzZXJ2YWNpb25lcyBcKHhfMSzigKYseF9UXCkgYmFqbyB1biBITU0gZGUgUG9pc3NvbiBjb24gYWwgbWVub3MgZG9zIGVzdGFkb3MsIG1hdHJpeiBkZSBwcm9iYWJpbGlkYWQgZGUgdHJhbnNpY2nDs24gXCjOk1wpLCB2ZWN0b3IgZGUgbWVkaWFzIGVzdGFkby1kZXBlbmRpZW50ZXMgXCjOu1wpIHkgZGlzdHJpYnVjacOzbiBpbmljaWFsIFwozrRcKS4KCmBgYHtyfQphbHBoYSA8LSBkZWx0YSpkcG9pcyh4WzFdLCBsYW1iZGEpCmxzY2FsZSA8LSBsb2coc3VtKGFscGhhKSkKYWxwaGEgPC0gYWxwaGEvc3VtKGFscGhhKQpmb3IoaSBpbiAyOlQpewogIGFscGhhIDwtIGFscGhhICUqJSBHYW1tYSpkcG9pcyh4W2ldLCBsYW1iZGEpCiAgbHNjYWxlIDwtIGxzY2FsZSArIGxvZyhzdW0oYWxwaGEpKQogIGFscGhhIDwtIGFscGhhL3N1bShhbHBoYSkKfQpsc2NhbGUKYGBgCgojIzMuMy4gTWF4aW1pemFjacOzbiBkZSBsYSBwb3NpYmlsaWRhZCBzdWpldGEgYSByZXN0cmljY2lvbmVzCiMjIzMuMy4xIFJlIHBhcmFtZXRyaXphY2nDs24gcGFyYSBldml0YXIgcmVzdHJpY2Npb25lcwoKTG9zIGVsZW1lbnRvcyBkZSBcKM6TXCkgeSBhcXVlbGxvcyBkZSBcKM67XCksIGVsIHZlY3RvciBkZSBtZWRpYXMgZXN0YWRvLWRlcGVuZGllbnRlcyBlbiB1biBITU0gZGUgUG9pc3NvbiwgZXN0w6FuIHN1amV0b3MgYSBubyBuZWdhdGl2aWRhZCB5IG90cmFzIHJlc3RyaWNjaW9uZXMuIEVuIHBhcnRpY3VsYXIsIGxhIHN1bWEgZGUgbGFzIGZpbGFzIGRlIFwozpNcKSBlcyBpZ3VhbCBhIDEuIExvcyBlc3RpbWFkb3MgZGUgbG9zIHBhcsOhbWV0cm9zIGRlYmVyw61hIHNhdGlzZmFjZXIgdGFtYmnDqW4gdGFsZXMgcmVzdHJpY2Npb25lcy4gUG9yIGVuZGUsIGFsIG1heGltaXphciBsYSBwb3NpYmlsaWRhZCwgbmVjZXNpdGFtb3MgcmVzb2x2ZXIgdW4gcHJvYmxlbWEgZGUgb3B0aW1pemFjacOzbiByZXN0cmluZ2lkYS4KRW4gZ2VuZXJhbCwgZXhpc3RlbiBkb3MgZ3J1cG9zIGRlIHJlc3RyaWNjaW9uZXM6IGFxdWVsbGFzIHF1ZSBhcGxpY2FuIGEgbG9zIHBhcsOhbWV0cm9zIGRlIGxhcyBkaXN0cmlidWNpb25lcyBlc3RhZG8tZGVwZW5kaWVudGVzIHkgYXF1ZWxsYXMgcXVlIGFwbGljYW4gYSBsb3MgcGFyw6FtZXRyb3MgZGUgbGEgY2FkZW5hIGRlIE1hcmtvdi4gRWwgcHJpbWVyIGdydXBvIGRlIHJlc3RyaWNjaW9uZXMgZGVwZW5kZSBlbiBjdWFsKGVzKSBkaXN0cmlidWNpw7NuKGVzKSBlc3RhZG8tZGVwZW5kaWVudGUocykgc29uIGVsZWdpZGFzLgoKRW4gZWwgY2FzbyBkZSB1biBITU0gZGUgUG9pc3NvbiBsYXMgcmVzdHJpY2Npb25lcyByZWxldmFudGVzIHNvbjogCgotIExhcyBtZWRpYXMgXCjOu19pXCkgZGUgbGFzIGRpc3RyaWJ1Y2lvbmVzIGVzdGFkby1kZXBlbmRpZW50ZXMgZGViZW4sIHBhcmEgXChpPTEs4oCmLG1cKSBzZXIgbm8gbmVnYXRpdm9zLiAKLSBMYXMgZmlsYXMgZGUgbGEgbWF0cml6IGRlIHByb2JhYmlsaWRhZCBkZSB0cmFuc2ljacOzbiBcKM6TXCkgZGViZW4gc3VtYXIgYSAxLCB5IHRvZG9zIGxvcyBwYXLDoW1ldHJvcyBcKM6zX3tpan1cKSBkZWJlbiBzZXIgbm8gbmVnYXRpdm9zLgoKCkFxdcOtIGxhcyByZXN0cmljY2lvbmVzIHB1ZWRlbiBzZXIgaW1wdWVzdGFzIGFsIGhhY2VyIHRyYW5zZm9ybWFjaW9uZXMuIExhIHRyYW5zZm9ybWFjacOzbiBkZSBsb3MgcGFyw6FtZXRyb3MgXCjOu19pXCkgZXMgZsOhY2lsLiBEZWZpbmEgXCjOt19pPWxvZ2EozrtfaSlcKSwgcGFyYSBcKGk9MSzigKYsbVwpLiBFbnRvbmNlcyBcKM63X2niiIhSXCkuIEx1ZWdvIHF1ZSBoZW1vcyBtYXhpbWl6YWRvIGxhIHBvc2liaWxpZGFkIGNvbiByZXNwZWN0byBhIGxvcyBwYXLDoW1ldHJvcyBubyByZXN0cmluZ2lkb3MsIGxvcyBwYXLDoW1ldHJvcyBlc3RpbWFkb3MgcmVzdHJpbmdpZG9zIHB1ZWRlbiBzZXIgb2J0ZW5pZG9zIGFsIHRyYW5zZm9ybWFyIGRlIHZ1ZWx0YTogXCgozrtfaSApPWV4cGEozrdfaSkpXCkuTm90ZSBxdWUgXCjOkyBcKSB0aWVuZSBcKG1eMlwpIGVudHJhZGFzIHBlcm8gc29sbyBcKG0obS0xKVwpIHBhcmFtZXRyb3MgbGlicmVzLCBhc2kgY29tbyBoYXkgbSByZXN0cmljY2lvbmVzIHN1bWEgZGUgZmlsYXMKCiQkClxzdW1fe2o9MX1ebSBcZ2FtbWFfe2lqfSA9MSBccXVhZCAoaT0xLC4uLixtKQokJAoKTW9zdHJhcmVtb3MgdW5hIHBvc2libGUgdHJhbnNmb3JtYWNpw7NuIGVudHJlIGxhcyBcKG1eMlwpIHByb2JhYmlsaWRhZGVzIHJlc3RyaW5naWRhcyBcKM6zX3tpan1cKSB5IFwobShtLTEpXCkgbsO6bWVyb3MgcmVhbGVzIHNpbiByZXN0cmljY2nDs24gXCjPhF97aWp9LGniiaBqXCkuClBvciByYXpvbmVzIGRlIHZpc2liaWxpZGFkIHNlIG11ZXN0cmEgZWwgY2FzbyBwYXJhIG09My4gRW1wZXphcmVtb3MgcG9yIGRlZmluaXIgbGEgbWF0cml6CgokJApcbGVmdChcYmVnaW57YXJyYXl9e2NjfSAKLSAsIFx0YXVfezEyfSxcdGF1X3sxM31cXCAKXHRhdV97MjF9ICwgLSAsIFx0YXVfezIzfVxcClx0YXVfezMxfSAsIFx0YXVfezMyfSAsIC0KXGVuZHthcnJheX1ccmlnaHQpCiQkCgpVbmEgbWF0cml6IG9uIFwobShtLTEpXCkgZW50cmFkYXMgXCjPhF97aWp94oiIUlwpLiBBaG9yYSBxdWUgXChnOlLihpJSXitcKSBzZWEgdW5hIGZ1bmNpw7NuIGVzdHJpY3RhbWVudGUgaW5jcmVtZW50YWwsIHBvciBlamVtcGxvCgokJApnKHgpID0gZV54IFxxdWFkIG8gXHF1YWQgZyh4KSA9IApcYmVnaW57Y2FzZXN9CiAgZV54IFxxdWFkIHggXGxlIDAgXFwgICAgCiAgeCsxIFxxdWFkIHggXGdlIDAKXGVuZHtjYXNlc30gXFwKRGVmaW5lIFxxdWFkIHF1ZSBcXAp2X3tpan0gPSAKXGJlZ2lue2Nhc2VzfQogIGcoXHRhdV97aWp9KSBccXVhZCBwYXJhIFxxdWFkIGkgXG5lcSBqIFxcCiAgMSBccXVhZCBwYXJhIFxxdWFkIGkgPSBqIApcZW5ke2Nhc2VzfQokJAoKRW50b25jZXMgZmlqYW1vcyBcKM6zX3tpan09dl97aWp9L1xzdW1fe2s9MX1ebSB2X3tpa31cKSAgKHBhcmEgaSxqPTEsMizigKYsbSkgeSBcKM6TPSjOs197aWp9KVwpLiBOb3MgcmVmZXJpcmVtb3MgYSBsb3MgcGFyw6FtZXRyb3MgXCjOt19pXCkgeSBcKM+EX3tpan1cKSBjb21vIHBhcsOhbWV0cm9zIGZ1bmNpb25hbGVzLCB5IGEgbG9zIHBhcsOhbWV0cm9zIFwozrtfaVwpIHkgXCjOs197aWp9XCkgY29tbyBwYXLDoW1ldHJvcyBuYXR1cmFsZXMuCgoKVXNhbmRvIGxhcyB0cmFuc2Zvcm1hY2lvbmVzIGFudGVyaW9yZXMgZGUgXCjOk1wpIHkgXCjOu1wpLCBwb2RlbW9zIHJlYWxpemFyIGVsIGNhbGN1bG8gZGUgbG9zIHBhcsOhbWV0cm9zIG1heGltaXphbnRlcyBkZSBsYSBwb3NpYmlsaWRhZCBlbiBkb3MgcGFzb3MKCi0gTWF4aW1pemFyIFwoTF9UXCkgY29uIHJlc3BlY3RvIGEgbG9zIHBhcsOhbWV0cm9zIGZ1bmNpb25hbGVzIFwoVD17z4Rfe2lqfX1cKSB5IFwozrc9KM63XzEs4oCmLM63X20pXCkuIFRvZG9zIGVzdG9zIHNvbiBzaW4gcmVzdHJpY2Npb25lcy4KLSBUcmFuc2Zvcm1hciBsb3MgZXN0aW1hZG9zIGRlIGxvcyBwYXLDoW1ldHJvcyBmdW5jaW9uYWxlcyBhIGVzdGltYWRvcyBkZSBwYXLDoW1ldHJvcyBuYXR1cmFsZXM6CgokJApUIFxyaWdodGFycm93IFxHYW1tYSAsIFxldGEgXHJpZ2h0YXJyb3cgXGxhbWJkYQokJAoKQ29uc2lkZXJlIFwozpNcKSBwYXJhIGVsIGNhc28gXChnKHgpPWVeeFwpIHkgbSBnZW5lcmFsLiBUZW5lbW9zIGVudG9uY2VzCgokJApcZ2FtbWFfe2lqfSA9IFxmcmFje2V4cChcdGF1X3tpan0pfXsxKyBcc3VtX3trIFxuZXEgaX0gZXhwKFx0YXVfe2lrfSl9LFxxdWFkIHBhcmEgXHF1YWQgaVxuZXEgagokJApZIGxvcyBlbGVtZW50b3MgZGlhZ29uYWxlcyBkZSBcKM6TXCkgc2lndWVuIGRlIGxhIHN1bWEgZGUgZmlsYXMgZGUgMS4gTGEgdHJhbnNmb3JtYWNpw7NuIGVuIGxhIGRpcmVjY2nDs24gb3B1ZXN0YSBlcwoKJCQKXHRhdV97aWp9ID0gbG9nKFxmcmFje1xnYW1tYV97aWp9fXsxLVxzdW1fe2sgXG5lcSBpfVxnYW1tYV97aWt9fSkgPSBsb2coXGdhbW1hX3tpan0vXGdhbW1hX3tpaX0pLFxxdWFkIHBhcmEgXHF1YWQgaSBcbmVxIGoKJCQKQWhvcmEgbW9zdHJhbW9zIHVuIGPDs2RpZ28gcmVsYXRpdmFtZW50ZSBzaW1wbGUgcXVlIHRyYW5zZm9ybWFyYSBwYXLDoW1ldHJvcyBuYXR1cmFsZXMgYSBmdW5jaW9uYWxlcyB5IHZpY2V2ZXJzYS4gRXN0ZSBjw7NkaWdvIHJlZmllcmUgYSB1biBITU0gZGUgUG9pc3NvbiBjb24gbT4yIGVzdGFkb3MsIGVuIGVsIGN1YWwgbGEgY2FkZW5hIGRlIE1hcmtvdiBwdWVkZSwgc2kgZXMgYXByb3BpYWRvLCBzZXIgYXN1bWlkYSBlc3RhY2lvbmFyaWEuIEVuIGVzZSBjYXNvIGxhIGRpc3RyaWJ1Y2nDs24gZXN0YWNpb25hcmlhIFwozrRcKSBubyBlcyBkYWRhLCBwZXJvIGVzIGNvbXB1dGFkYSBjdWFuZG8gc2VhIG5lY2VzaXRhZGEgZGVsIHQucC5tLiBcKM6TXCkgYWwgcmVzb2x2ZXIgXCjOtChJX20tzpMrVSk9MVwpLiBEZSBvdHJhIG1hbmVyYSwgXCjOtFwpIGVzIHRyYXRhZGEgY29tbyB1biBwYXLDoW1ldHJvIChuYXR1cmFsKSB5IHRyYW5zZm9ybWFkYSBwYXJhIGFzw60gcmVtb3ZlciBsYXMgcmVzdHJpY2Npb25lcyBcKM60X2niiaUwXCkgeSBcKFxzdW1fac60X2k9MVwpLgoKCmBgYHtyfQojIFRyYW5zZm9ybWFyIGxvcyBwYXLDoW1ldHJvcyBuYXR1cmFsZXMgZGUgUG9pc3NvbiBlbiBwYXLDoW1ldHJvcyBkZSB0cmFiYWpvLgpwb2lzLkhNTS5wbjJwdyA8LSBmdW5jdGlvbihtLGxhbWJkYSxnYW1tYSxkZWx0YT1OVUxMLHN0YXRpb25hcnk9VFJVRSkKewogdGxhbWJkYSA8LSBsb2cobGFtYmRhKQogZm9vICAgICA8LSBsb2coZ2FtbWEvZGlhZyhnYW1tYSkpCiB0Z2FtbWEgIDwtIGFzLnZlY3Rvcihmb29bIWRpYWcobSldKQogaWYoc3RhdGlvbmFyeSkge3RkZWx0YSA8LU5VTEx9IGVsc2Uge3RkZWx0YTwtbG9nKGRlbHRhWy0xXS9kZWx0YVsxXSl9CiBwYXJ2ZWN0IDwtIGModGxhbWJkYSx0Z2FtbWEsdGRlbHRhKQogcmV0dXJuKHBhcnZlY3QpCn0KCiMgVHJhbnNmb3JtYXIgbG9zIHBhcsOhbWV0cm9zIGRlIHRyYWJham8gZGUgUG9pc3NvbiBlbiBwYXLDoW1ldHJvcyBuYXR1cmFsZXMuCgpwb2lzLkhNTS5wdzJwbiA8LSBmdW5jdGlvbihtLHBhcnZlY3Qsc3RhdGlvbmFyeT1UUlVFKQp7CiBsYW1iZGEgICAgICAgIDwtIGV4cChwYXJ2ZWN0WzE6bV0pCiBnYW1tYSAgICAgICAgIDwtIGRpYWcobSkKIGdhbW1hWyFnYW1tYV0gPC0gZXhwKHBhcnZlY3RbKG0rMSk6KG0qbSldKQogZ2FtbWEgICAgICAgICA8LSBnYW1tYS9hcHBseShnYW1tYSwxLHN1bSkKIGlmKHN0YXRpb25hcnkpIHtkZWx0YTwtc29sdmUodChkaWFnKG0pLWdhbW1hKzEpLHJlcCgxLG0pKX0gZWxzZQogICAgICAgICAgICAgICAge2ZvbzwtYygxLGV4cChwYXJ2ZWN0WyhtKm0rMSk6KG0qbSttLTEpXSkpCiAgICAgICAgICAgICAgICBkZWx0YTwtZm9vL3N1bShmb28pfQogcmV0dXJuKGxpc3QobGFtYmRhPWxhbWJkYSxnYW1tYT1nYW1tYSxkZWx0YT1kZWx0YSkpCn0KYGBgCgoKIyMzLjQuIE90cm9zIHByb2JsZW1hcwojIyMzLjQuMS4gTcO6bHRpcGxlcyBtw6F4aW1vcyBlbiBsYSBwb3NpYmlsaWRhZAoKTGEgcG9zaWJpbGlkYWQgZGUgdW4gSE1NIGVzIHVuYSBmdW5jacOzbiBjb21wbGljYWRhIGRlIGxvcyBwYXLDoW1ldHJvcyB5IGZyZWN1ZW50ZW1lbnRlIHRpZW5lIHZhcmlvcyBtw6F4aW1vcyBsb2NhbGVzLiBMYSBtZXRhIHBvciBzdXB1ZXN0byBlcyBlbmNvbnRyYXIgZWwgbcOheGltbyBnbG9iYWwsIHBlcm8gbm8gaGF5IHVuIG3DqXRvZG8gc2ltcGxlIGRlIGRldGVybWluYXIgZW4gZ2VuZXJhbCBzaSB1biBhbGdvcml0bW8gZGUgbWF4aW1pemFjacOzbiBudW3DqXJpY2EgaGEgYWxjYW56YWRvIGVsIG3DoXhpbW8gZ2xvYmFsLiBEZXBlbmRpZW5kbyBkZSBsb3MgdmFsb3JlcyBpbmljaWFsZXMsIHB1ZWRlIHN1Y2VkZXIgcXVlIGVsIGFsZ29yaXRtbyBmw6FjaWxtZW50ZSBpZGVudGlmaXF1ZSB1biBsb2NhbCwgcGVybyBubyBlbCBtw6F4aW1vLCBnbG9iYWwuIEVzdG8gdGFtYmnDqW4gYXBsaWNhIGFsIHByaW5jaXBhbCBtw6l0b2RvIGFsdGVybm8gZGUgZXN0aW1hY2nDs24sIGVsIGFsZ29yaXRtbyBFTS4gVW5hIGVzdHJhdGVnaWEgc2Vuc2libGUgZW50b25jZXMgZXMgdXNhciB1biByYW5nbyBkZSB2YWxvcmVzIGluaWNpYWxlcyBwYXJhIGxhIG1heGltaXphY2nDs24sIHkgdmVyIHNpIGVsIG1pc21vIG3DoXhpbW8gZXMgaWRlbnRpZmljYWRvIGVuIGNhZGEgY2Fzby4KCiMjIzMuNC4yLiBWYWxvcmVzIGluaWNpYWxlcyBwYXJhIGxhcyBpdGVyYWNpb25lcwoKRXMgYSBtZW51ZG8gZsOhY2lsIGVsIGVuY29udHJhciBwb3NpYmxlcyB2YWxvcmVzIGluaWNpYWxlcyBwYXJhIGFsZ3Vub3MgZGUgbG9zIHBhcsOhbWV0cm9zIGRlIHVuIEhNTTogcG9yIGVqZW1wbG8sIHNpIHVubyBidXNjYSBlbCBmaWphciB1biBITU0gZGUgUG9pc3NvbiBjb24gZG9zIGVzdGFkb3MsIHkgbGEgbWVkaWEgZGUgbXVlc3RyYSBlcyAxMCwgdW5vIHBvZHLDrWEgcHJvYmFyIDggeSAxMiwgbyA1IHkgMTUsIHBhcmEgbG9zIHZhbG9yZXMgZGUgbGFzIGRvcyBtZWRpYXMgZXN0YWRvLWRlcGVuZGllbnRlcy4gRXN0cmF0ZWdpYXMgbWFzIHNpc3RlbcOhdGljYXMgYmFzYWRhcyBlbiBsb3MgY3VhbnRpbGVzIGRlIGxhcyBvYnNlcnZhY2lvbmVzIHNvbiBwb3NpYmxlcywgc2luIGVtYmFyZ28uIFBvciBlamVtcGxvLCBzaSBlbCBtb2RlbG8gdGllbmUgdHJlcyBlc3RhZG9zLCB1c2UgY29tbyBsb3MgdmFsb3JlcyBpbmljaWFsZXMgZGUgbGFzIG1lZGlhcyBlc3RhZG8tZGVwZW5kaWVudGVzIGVsIGN1YXJ0aWwgbWVub3IsIG1lZGlhbm8geSBjdWFydGlsIHN1cGVyaW9yIGRlIGxhcyBjdWVudGFzIG9ic2VydmFkYXMuCkVzIG1lbm9zIGbDoWNpbCBlbCBhZGl2aW5hciB2YWxvcmVzIGRlIGxhcyBwcm9iYWJpbGlkYWRlcyBkZSB0cmFuc2ljacOzbiBcKM6zX3tpan1cKS4gVW5hIGVzdHJhdGVnaWEgZXMgZWwgYXNpZ25hciB1biB2YWxvciBpbmljaWFsIGNvbcO6biBhIHRvZGFzIGxhcyBwb3NpYmlsaWRhZGVzIGRlIHRyYW5zaWNpw7NuIGZ1ZXJhIGRlIGxhIGRpYWdvbmFsLiBVbmEgY29uc2VjdWVuY2lhIGRlIHRhbCBkZWNpc2nDs24sIHF1aXrDoSBjb252ZW5pZW50ZSwgZXMgcXVlIGxhIGRpc3RyaWJ1Y2nDs24gZXN0YWNpb25hcmlhIGNvcnJlc3BvbmRpZW50ZSBlcyB1bmlmb3JtZSBzb2JyZSBsb3MgZXN0YWRvczsgZXN0byBzaWd1ZSBwb3Igc2ltZXRyw61hLiBFbGVnaXIgYnVlbm9zIHZhbG9yZXMgaW5pY2lhbGVzIHBhcmEgbG9zIHBhcsOhbWV0cm9zIHRpZW5kZSBhIGFsZWphcmxvIGEgdW5vIGRlIGluZXN0YWJpbGlkYWQgbnVtw6lyaWNhLgoKIyMjMy40LjMuIFBvc2liaWxpZGFkIHNpbiBsaW1pdGVzCgpFbiBlbCBjYXNvIGRlIEhNTXMgY29uIGRpc3RyaWJ1Y2lvbmVzIGNvbnRpbnVhcyBlc3RhZG8tZGVwZW5kaWVudGVzLCBwdWVkZSBzdWNlZGVyIHF1ZSBsYSBwb3NpYmlsaWRhZCBlcyBzaW4gbMOtbWl0ZXMgZW4gbGEgcHJveGltaWRhZCBkZSBjaWVydGFzIGNvbWJpbmFjaW9uZXMgZGUgcGFyw6FtZXRyb3MuCgohW1NlcmllIGRlIFRlcnJlbW90b3MgLSBTZWNjaW9uIGl6cXVpZXJkYTogRGlzdHJpYnVjaW9uZXMgZGUgUG9pc3NvbiAtIEhNTSBjb24gZG9zIHkgdHJlcyBlc3RhZG9zLiBTZWNjaW9uIERlcmVjaGE6IG1lZGlvcyBkZXBlbmRpZW50ZXMgZGVsIGVzdGFkbyBlbiBjb21wYXJhY2lvbiBjb24gbGFzIG9ic2VydmFjaW9uZXNdKC9Vc2Vycy9icmFjcnV6L0RvY3VtZW50cy84dm8uIFRyaW1lc3RyZSBJTy9TaXN0LiBFeHBlcnRvcyB5IFJlZGVzIFByb2IuL0NIMy9HcmFmaWNhMy0xLnBuZykKCkNvbW8gYW50ZXMsIHN1Z2VyaW1vcyBxdWUsIHNpIGVzdG8gY3JlYSBkaWZpY3VsdGFkbywgc2UgbWF4aW1pemUgbGEgcG9zaWJpbGlkYWQgZGlzY3JldGEgZW4gdmV6IGRlIGxhIGRlbnNpZGFkIGNvbmp1bnRhLgoKIyMjMy41LiBFamVtcGxvOiBUZXJyZW1vdG9zCgpMYSBmaWd1cmEgYW50ZXJpb3IgbXVlc3RyYSBlbCByZXN1bHRhZG8gZGUgYWp1c3RhciBITU1zIGRlIFBvaXNzb24gKGVzdGFjaW9uYXJpb3MpIGNvbiBkb3MgYSB0cmVzIGVzdGFkb3MgYSBsYSBzZXJpZSBkZSB0ZXJyZW1vdG9zIHBvciBtZWRpYXMgZGVsIG9wdGltaXphZG9yIG5vIHJlc3RyaW5naWRvIG5sbS4gRWwgbW9kZWxvIGRlIGRvcyBlc3RhZG9zIGVzCgokJApcR2FtbWEgPSAKXGxlZnQoXGJlZ2lue2FycmF5fXtjY30gCjAuOTM0MCAsIDAuMDA2NjBcXCAKMC4xMjg1ICwgMC44NzE1ClxlbmR7YXJyYXl9XHJpZ2h0KQokJAoKQ29uIFwozrQ9KDAuNjYwOCwwLjMzOTIpXCksXCjOuz0oMTUuNDcyLDI2LjEyNSlcKSwgeSBsYSBwb3NpYmlsaWRhZCBkZSByZWdpc3RybyBkYWRhIHBvciBcKGw9LTM0Mi4zMTgzXCkuIEVzIGNsYXJvIHF1ZSBsYSBtZXpjbGEgKGRlcGVuZGllbnRlIGRlIE1hcmtvdikgYWp1c3RhZGEgZGUgZG9zIGRpc3RyaWJ1Y2lvbmVzIGRlIFBvaXNzb24gcHJvdmVlIHVuIG1lam9yIGFqdXN0ZSBhIGxhIGRpc3RyaWJ1Y2nDs24gbWFyZ2luYWwgZGUgbGFzIG9ic2VydmFjaW9uZXMgcXVlIGxvIGhhY2UgdW5hIMO6bmljYSBkaXN0cmlidWNpw7NuIGRlIFBvaXNzb24sIHBlcm8gZWwgYWp1c3RlIHB1ZWRlIHNlZ3VpciBzaWVuZG8gbWVqb3JhZG8gYWwgdXNhciB1bmEgbWV6Y2xhIGRlIDMgbyA0IGRpc3RyaWJ1Y2lvbmVzIGRlIFBvaXNzb24uCgpgYGB7cn0KbGlicmFyeShIaWRkZW5NYXJrb3YpCmxpYnJhcnkocmVhZHIpCiMtLS0tLSAgUG9pc3NvbiBEaXN0cmlidXRpb24gIC0tLS0tCgojbGVlciBsYSBkYXRhIAp4X2RhdGE8LSByZWFkLnRhYmxlKCIvVXNlcnMvYnJhY3J1ei9Eb2N1bWVudHMvOHZvLiBUcmltZXN0cmUgSU8vU2lzdC4gRXhwZXJ0b3MgeSBSZWRlcyBQcm9iLi9lYXJ0aHF1YWtlcy50eHQiKVssMl0KClBpIDwtIG1hdHJpeChjKDAuOTM0MCwgMC4wNjYsCiAgICAgICAgICAgICAgIDAuMTI4NSwgMC44NzE1KSwKICAgICAgICAgICAgIGJ5cm93PVRSVUUsIG5yb3c9MikKCmRlbHRhIDwtIGMoMC42NjA4LCAwLjMzOTIpCgp4IDwtIGR0aG1tKHhfZGF0YSwgUGksIGRlbHRhLCAicG9pcyIsIGxpc3QobGFtYmRhPWMoMTUuNDcyLCAyNi4xMjUpKSwKICAgICAgICAgICBkaXNjcmV0ZSA9IFRSVUUpCgojICAgIHVzZSBhYm92ZSBwYXJhbWV0ZXIgdmFsdWVzIGFzIGluaXRpYWwgdmFsdWVzCgp5IDwtIEJhdW1XZWxjaCh4KQpwcmludChzdW1tYXJ5KHkpKQojbG9nLWxpa2VsaWhvb2QgaWRlYWwKcHJpbnQobG9nTGlrKHkpKQp7aDwtaGlzdChyZXNpZHVhbHMoeSkpCnhmaXQgPC0gc2VxKG1pbihyZXNpZHVhbHMoeSkpLCBtYXgocmVzaWR1YWxzKHkpKSwgbGVuZ3RoID0gNDApIAp5Zml0IDwtIGRub3JtKHhmaXQsIG1lYW4gPSBtZWFuKHJlc2lkdWFscyh5KSksIHNkID0gc2QocmVzaWR1YWxzKHkpKSkgCnlmaXQgPC0geWZpdCAqIGRpZmYoaCRtaWRzWzE6Ml0pICogbGVuZ3RoKHJlc2lkdWFscyh5KSkgCgpsaW5lcyh4Zml0LCB5Zml0LCBjb2wgPSAiIzAwNjZmZiIsIGx3ZCA9IDIpfQpgYGAKCgoKRWwgbW9kZWxvIGRlIHRyZXMgZXN0YWRvcyBlczoKCiQkClxHYW1tYSA9IApcbGVmdChcYmVnaW57YXJyYXl9e2NjfSAKMC45NTU1ICwgMC4wMjQgLCAwLjAyMVxcIAowLjA1MCAsIDAuODg5OSAsIDAuMDUxIFxcCjAuMDAwICwgMC4xOTcgLCAgMC44MDMKXGVuZHthcnJheX1ccmlnaHQpCiQkCgpDb24gXCjOtD0oMC40NDM2LDAuNDA0NSwwLjE1MTkpXCksXCjOuz0oMTMuMTQ2LDE5LjcyMSwyOS43MTQ0KVwpIHkgXChsPS0zMjkuNDYwM1wpLiAKCgpgYGB7cn0KbGlicmFyeShIaWRkZW5NYXJrb3YpCmxpYnJhcnkocmVhZHIpCiMtLS0tLSAgUG9pc3NvbiBEaXN0cmlidXRpb24gIC0tLS0tCgojbGVlciBsYSBkYXRhIAp4X2RhdGE8LSByZWFkLnRhYmxlKCIvVXNlcnMvYnJhY3J1ei9Eb2N1bWVudHMvOHZvLiBUcmltZXN0cmUgSU8vU2lzdC4gRXhwZXJ0b3MgeSBSZWRlcyBQcm9iLi9lYXJ0aHF1YWtlcy50eHQiKVssMl0KClBpIDwtIG1hdHJpeChjKDAuOTU1NSAsIDAuMDI0ICwgMC4wMjEgLAowLjA1MCAsIDAuODg5OSAsIDAuMDUxICwgCjAuMDAwICwgMC4xOTcgLCAgMC44MDMpLAogICAgICAgICAgICAgYnlyb3c9VFJVRSwgbnJvdz0zKQoKZGVsdGEgPC0gYygwLjQ0MzYsMC40MDQ1LDAuMTUxOSkKCnggPC0gZHRobW0oeF9kYXRhLCBQaSwgZGVsdGEsICJwb2lzIiwgbGlzdChsYW1iZGE9YygxMy4xNDYsMTkuNzIxLDI5LjcxNCkpLAogICAgICAgICAgIGRpc2NyZXRlID0gVFJVRSkKCiMgICAgdXNlIGFib3ZlIHBhcmFtZXRlciB2YWx1ZXMgYXMgaW5pdGlhbCB2YWx1ZXMKCnkgPC0gQmF1bVdlbGNoKHgpCnByaW50KHN1bW1hcnkoeSkpCiNsb2ctbGlrZWxpaG9vZCBpZGVhbApwcmludChsb2dMaWsoeSkpCntoPC1oaXN0KHJlc2lkdWFscyh5KSkKeGZpdCA8LSBzZXEobWluKHJlc2lkdWFscyh5KSksIG1heChyZXNpZHVhbHMoeSkpLCBsZW5ndGggPSA0MCkgCnlmaXQgPC0gZG5vcm0oeGZpdCwgbWVhbiA9IG1lYW4ocmVzaWR1YWxzKHkpKSwgc2QgPSBzZChyZXNpZHVhbHMoeSkpKSAKeWZpdCA8LSB5Zml0ICogZGlmZihoJG1pZHNbMToyXSkgKiBsZW5ndGgocmVzaWR1YWxzKHkpKSAKCmxpbmVzKHhmaXQsIHlmaXQsIGNvbCA9ICIjZmYwMDAwIiwgbHdkID0gMil9CmBgYAoKRWwgbW9kZWxvIGRlIGN1YXRybyBlc3RhZG9zIGVzOiAKJCQKXEdhbW1hID0gClxsZWZ0KFxiZWdpbnthcnJheX17Y2N9IAowLjgwNSwgMC4xMDIsIDAuMDkzLCAwLjAwMCBcXAowLjAwMCwgMC45NzYsIDAuMDAwLCAwLjAyNCBcXAowLjA1MCwgMC4wMDAsIDAuOTAyLCAwLjA0OCBcXAowLjAwMCwgMC4wMDAsIDAuMTg4LCAwLjgxMgpcZW5ke2FycmF5fVxyaWdodCkKJCQKCgpDb24gXCjOtD0oMC4wOTM2LDAuMzk4MywwLjM2NDMsMC4xNDM5KVwpLFwozrs9KDExLjI4MywxMy44NTMsMTkuNjk1LDI5LjcwMClcKSB5IFwobD0tMzI3LjgzMTZcKS4KCgpgYGB7cn0KbGlicmFyeShIaWRkZW5NYXJrb3YpCmxpYnJhcnkocmVhZHIpCiMtLS0tLSAgUG9pc3NvbiBEaXN0cmlidXRpb24gIC0tLS0tCgojbGVlciBsYSBkYXRhIAp4X2RhdGE8LSByZWFkLnRhYmxlKCIvVXNlcnMvYnJhY3J1ei9Eb2N1bWVudHMvOHZvLiBUcmltZXN0cmUgSU8vU2lzdC4gRXhwZXJ0b3MgeSBSZWRlcyBQcm9iLi9lYXJ0aHF1YWtlcy50eHQiKVssMl0KClBpIDwtIG1hdHJpeChjKDAuODA1LCAwLjEwMiwgMC4wOTMsIDAuMDAwLAowLjAwMCwgMC45NzYsIDAuMDAwLCAwLjAyNCwKMC4wNTAsIDAuMDAwLCAwLjkwMiwgMC4wNDgsCjAuMDAwLCAwLjAwMCwgMC4xODgsIDAuODEyKSwKICAgICAgICAgICAgIGJ5cm93PVRSVUUsIG5yb3c9NCkKCmRlbHRhIDwtIGMoMC4wOTM2LDAuMzk4MywwLjM2NDMsMC4xNDM5KQoKeCA8LSBkdGhtbSh4X2RhdGEsIFBpLCBkZWx0YSwgInBvaXMiLCBsaXN0KGxhbWJkYT1jKDExLjI4MywxMy44NTMsMTkuNjk1LDI5LjcwMCkpLAogICAgICAgICAgIGRpc2NyZXRlID0gVFJVRSkKCiMgICAgdXNlIGFib3ZlIHBhcmFtZXRlciB2YWx1ZXMgYXMgaW5pdGlhbCB2YWx1ZXMKCnkgPC0gQmF1bVdlbGNoKHgpCnByaW50KHN1bW1hcnkoeSkpCiNsb2ctbGlrZWxpaG9vZCBpZGVhbApwcmludChsb2dMaWsoeSkpCntoPC1oaXN0KHJlc2lkdWFscyh5KSkKeGZpdCA8LSBzZXEobWluKHJlc2lkdWFscyh5KSksIG1heChyZXNpZHVhbHMoeSkpLCBsZW5ndGggPSA0MCkgCnlmaXQgPC0gZG5vcm0oeGZpdCwgbWVhbiA9IG1lYW4ocmVzaWR1YWxzKHkpKSwgc2QgPSBzZChyZXNpZHVhbHMoeSkpKSAKeWZpdCA8LSB5Zml0ICogZGlmZihoJG1pZHNbMToyXSkgKiBsZW5ndGgocmVzaWR1YWxzKHkpKSAKCmxpbmVzKHhmaXQsIHlmaXQsIGNvbCA9ICIjMDBmZmZmIiwgbHdkID0gMil9CmBgYAoKRW4gdG9kb3MgZXN0b3MgY2Fzb3MgZWwgQUNGIGVzIHNvbG8gdW5hIGNvbWJpbmFjacOzbiBsaW5lYWwgZGUgbGFzIGstZXNpbWFzIHBvdGVuY2lhcyBkZSBsb3MgZWlnZW52YWxvcmVzIGRpc3RpbnRvcyBkZSAxIGRlIGxhIG1hdHJpeiBkZSBwcm9iYWJpbGlkYWQgZGUgdHJhbnNpY2nDs24uClVuIGZlbsOzbWVubyBxdWUgZXMgbm90YWJsZSBjdWFuZG8gdW5vIGFqdXN0YSBtb2RlbG9zIGNvbiB0cmVzIG8gbWFzIGVzdGFkb3MgYSBzZXJpZXMgcmVsYXRpdmFtZW50ZSBjb3J0YXMgZXMgcXVlIGxvcyBlc3RpbWFkb3MgZGUgdW5hIG8gbWFzIGRlIGxhcyBwcm9iYWJpbGlkYWRlcyBkZSB0cmFuc2ljacOzbiByZXN1bHRhIHNlciBtdXkgY2VyY2FuYSBhIGNlcm8uCgpFc3RlIGZlbsOzbWVubyBwdWVkZSBzZXIgZXhwbGljYWRvIGNvbW8gc2lndWUuIEVuIHVuYSBjYWRlbmEgZGUgTWFya292IGVzdGFjaW9uYXJpYSwgZWwgbsO6bWVybyBlc3BlcmFkbyBkZSB0cmFuc2ljaW9uZXMgZGVsIGVzdGFkbyBpIGFsIGVzdGFkbyBqIGVuIHVuYSBzZXJpZSBkZSBUIG9ic2VydmFjaW9uZXMgZXMgXCgoVC0xKSDOtF9pXCkgXCjOs197aWp9XCkuIFBhcmEgXCjOtF8zPTAuMTUyXCkgeSBUPTEwNyAoY29tbyBlbiBudWVzdHJvIG1vZGVsbyBkZSB0cmVzIGVzdGFkb3MpLCBlc3RhIGV4cGVjdGF0aXZhIHNlcsOhIG1lbm9yIHF1ZSAxIHNpIFwozrNfezMxfTwwLjA2MlwpLiBFbiB0YWwgc2VyaWUsIHBvciBlbmRlLCBlcyBwcm9iYWJsZSBxdWUgc2kgXCjOs197MzF9XCkgZXMgYmFzdGFudGUgcGVxdWXDsW8gbm8gaGFicsOhIHRyYW5zaWNpb25lcyBkZWwgZXN0YWRvIDMgYWwgZXN0YWRvIDEsIHkgZW50b25jZXMgY3VhbmRvIGJ1c3F1ZW1vcyBlc3RpbWFyIFwozrNfezMxfVwpIGVuIHVuIEhNTSwgZWwgZXN0aW1hZG8gZXMgcHJvYmFibGUgYSBzZXIgZWZlY3RpdmFtZW50ZSBjZXJvLiBDb21vIG0gaW5jcmVtZW50ZSwgbGFzIHByb2JhYmlsaWRhZGVzIFwozrRfaVwpIHkgXCjOs197aWp9XCkgc2UgdnVlbHZlIG3DoXMgcGVxdWXDsWEgZW4gcHJvbWVkaW87IGVzdG8gbG8gaGFjZSBtYXMgcHJvYmFibGUgcXVlIGFsIG1lbm9zIHVuYSBwcm9iYWJpbGlkYWQgZGUgdHJhbnNpY2nDs24gc2VhIGVmZWN0aXZhbWVudGUgY2Vyby4KCiMjIzMuNi4gRXJyb3JlcyBlc3TDoW5kYXJlcyBlIGludGVydmFsb3MgZGUgY29uZmlhbnphCgpSZWxhdGl2YW1lbnRlIHBvY28gZXMgY29ub2NpZG8gYWNlcmNhIGRlIGxhcyBwcm9waWVkYWRlcyBkZSBlc3RpbWFkb3JlcyBkZSBtw6F4aW1hIHBvc2liaWxpZGFkIGRlIEhNTXM7IHNvbG8gcmVzdWx0YWRvcyBhc2ludMOzdGljb3MgZXN0w6FuIGRpc3BvbmlibGVzLiBQYXJhIGV4cGxvdGFyIGVzdG9zIHJlc3VsdGFkb3Mgc2UgcmVxdWllcmUgZXN0aW1hciBsYSBtYXRyaXogZGUgdmFyaWFuemEgeSBjb3ZhcmlhbnphIGRlIGxvcyBlc3RpbWFkb3JlcyBkZSBsb3MgcGFyw6FtZXRyb3MuIFNlIHB1ZWRlIGVzdGltYXIgbG9zIGVycm9yZXMgZXN0w6FuZGFyZXMgZGVsIEhlc3NpYW5vIGRlIGxhIHBvc2liaWxpZGFkIGRlIHJlZ2lzdHJvIGVuIGVsIG3DoXhpbW8sIHBlcm8gZXN0ZSBlbmZvcXVlIHNlIGVuY3VlbnRyYSBjb24gZGlmaWN1bHRhZGVzIGN1YW5kbyBhbGd1bm9zIGRlIGxvcyBwYXLDoW1ldHJvcyBlc3TDoW4gZW4gbGEgZnJvbnRlcmEgZGVsIGVzcGFjaW8gZGUgc3UgcGFyw6FtZXRybywgZWwgY3VhbCBvY3VycmUgYmFzdGFudGUgYSBtZW51ZG8gY3VhbmRvIGxvcyBITU1zIHNvbiBhanVzdGFkb3MuCgojIyMzLjYuMS4gRXJyb3JlcyBlc3TDoW5kYXJlcyBtZWRpYW50ZSBlbCBIZXNzaWFubwoKQXVucXVlIGxvcyBlc3RpbWFkb3MgZGUgcHVudG8gXChcVGhldGEgPSAoXEdhbW1hLFxsYW1iZGEpXCkgc29uIGbDoWNpbGVzIGRlIGNvbXB1dGFyLCBlc3RpbWFkb3MgZXhhY3RvIGRlIGludGVydmFsbyBubyBlc3TDoW4gZGlzcG9uaWJsZXMuIENhcHBlICgyMDA1LCBDYXBpdHVsbyAxMikgbXVlc3RyYSBxdWUsIGJham8gY2llcnRhcyBjb25kaWNpb25lcyBkZSByZWd1bGFyaWRhZCwgbG9zIE1MRXMgZGUgcGFyw6FtZXRyb3MgZGUgdW4gSE1NIHNvbiBjb25zaXN0ZW50ZXMsIGFzaW50w7N0aWNhbWVudGUgbm9ybWFsZXMgeSBlZmljaWVudGVzLiBQb3IgZW5kZSwgc2kgcG9kZW1vcyBlc3RpbWFyIGxvcyBlcnJvcmVzIGVzdMOhbmRhcmVzIGRlIGxvcyBNTEVzIGVudG9uY2VzLCB1c2FuZG8gbm9ybWFsaWRhZCBhc2ludMOzdGljYSwgcG9kZW1vcyB0YW1iacOpbiBjb21wdXRhciBpbnRlcnZhbG9zIGFwcm94aW1hZG9zIGRlIGNvbmZpYW56YS4gU2luIGVtYmFyZ28sIGNvbW8gc2XDsWFsYSBGcnVod2lydGgtU2NobmF0dGVyICgyMDA2LCBwLiA1MykgZW4gZWwgY29udGV4dG8gZGUgbW9kZWxvcyBpbmRlcGVuZGllbnRlcyBkZSBtZXpjbGEsIOKAnExhcyBjb25kaWNpb25lcyBkZSByZWd1bGFyaWRhZCBzb24gYSBtZW51ZG8gdmlvbGFkb3MsIGluY2x1eWVuZG8gY2Fzb3MgZGUgZ3JhbiBwcmVvY3VwYWNpw7NuIHByw6FjdGljYSwgZW50cmUgZWxsb3Mgc2V0cyBkZSBkYXRvcyBwZXF1ZcOxb3MsIG1lemNsYXMgY29uIHBlc29zIGRlIGNvbXBvbmVudGVzIHBlcXVlw7FvcywgeSBtZXpjbGFzIGRlIGV4Y2Vzb3MgY29uIG11Y2hvcyBjb21wb25lbnRlc+KAnS4gQWRlbcOhcywgTWNMYWNobGFuIHkgUGVlbCAoMjAwMCwgcC4gNjgpIGFkdmllcnRlbjog4oCcRW4gcGFydGljdWxhciwgcGFyYSBtb2RlbG9zIGRlIG1lemNsYSwgZXMgYmllbiBjb25vY2lkbyBxdWUgZWwgdGFtYcOxbyBkZSBtdWVzdHJhIG4gdGllbmUgcXVlIHNlciBtdXkgZ3JhbmRlIGFudGVzIHF1ZSBsYSB0ZW9yw61hIGFzaW50w7N0aWNhIGRlIGxhIHBvc2liaWxpZGFkIG3DoXhpbWEgc2UgYXBsaXF1ZeKAnS4KQ29uIGxhcyBhZHZlcnRlbmNpYXMgcHJldmlhcyBlbiBtZW50ZSwgcG9kZW1vcywgZW4gb3JkZW4gcGFyYSBlc3RpbWFyIGxvcyBlcnJvcmVzIGVzdMOhbmRhcmVzIGRlIGxvcyBNTEVzIGRlIHVuIEhNTSwgdXRpbGl6YXIgZWwgSGVzc2lhbm8gYXByb3hpbWFkbyBkZSBtZW5vcyBsYSBwb3NpYmlsaWRhZCBkZSByZWdpc3RybyBlbiBlbCBtw61uaW1vLiBQb2RlbW9zIGludmVydGlybG8geSBhc8OtIGVzdGltYXIgbGEgbWF0cml6IGRlIHZhcmlhbnphIHkgY292YXJpYW56YSBhc2ludMOzdGljYSBkZSBsb3MgZXN0aW1hZG9yZXMgZGUgbG9zIHBhcsOhbWV0cm9zLiBVbiBwcm9ibGVtYSBjb24gZXN0YSBzdWdlcmVuY2lhIGVzIHF1ZSwgc2kgbG9zIHBhcsOhbWV0cm9zIGhhbiBzaWRvIHRyYW5zZm9ybWFkb3MsIGVsIEhlc3NpYW5vIGRpc3BvbmlibGUgc2Vyw6EgZWwgY3VhbCBzZSByZWZpZXJlIGEgbG9zIHBhcsOhbWV0cm9zIGZ1bmNpb25hbGVzIFwoz5VfaVwpLCBubyBsb3Mgb3JpZ2luYWxlcywgcGFyYSBpbnRlcnByZXRhcmxvIGRlIG1lam9yIG1hbmVyYSwgcGFyw6FtZXRyb3MgbmF0dXJhbGVzIFwoXFRoZXRhX2lcKSAoXCjOk1wpIHkgXCjOu1wpIGVuIGVsIGNhc28gZGUgdW4gSE1NIGRlIFBvaXNzb24pLgpMYSBzaXR1YWNpw7NuIGVzIGVudG9uY2VzIHF1ZSB0ZW5lbW9zLCBlbiBlbCBtw61uaW1vIGRlIFwoLWxcKSwgZWwgSGVzc2lhbm8gY29uIHJlc3BlY3RvIGEgbG9zIHBhcsOhbWV0cm9zIGZ1bmNpb25hbGVzCgokJApIID0gLShcZnJhY3tccGFydGlhbF4ybH17XHBhcnRpYWwgXHBoaV9pIFxwYXJ0aWFsIFxwaGlfan0pCiQkCgpQZXJvIGxvIHF1ZSByZWFsbWVudGUgbmVjZXNpdGFtb3MgZXMgZWwgSGVzc2lhbm8gZW4gcmVzcGVjdG8gYSBsb3MgcGFyw6FtZXRyb3MgbmF0dXJhbGVzCgokJApHID0gLShcZnJhY3tccGFydGlhbF4ybH17XHBhcnRpYWwgXHRoZXRhX2kgXHBhcnRpYWwgXHRoZXRhX2p9KQokJAoKRXhpc3RlLCBzaW4gZW1iYXJnbywgbGEgc2lndWllbnRlIHJlbGFjacOzbiBlbnRyZSBsb3MgZG9zIEhlc3NpYW5vcyBlbiBlbCBtw61uaW1vCgokJApIID0gTUdNJyBccXVhZCB5IFxxdWFkIEdeey0xfSA9IE0nSF57LTF9TQokJAoKRG9uZGUgTSBlcyBkZWZpbmlkbyBwb3IgXChtX3tpan094oiCzrhfai/iiILPlV9pXCkuIEVuIGVsIGNhc28gZGUgdW4gSE1NIGRlIFBvaXNzb24sIGxvcyBlbGVtZW50b3MgZGUgTSBzb24gYmFzdGFudGUgc2ltcGxlcy4KQ29uIE0gYSBudWVzdHJhIGRpc3Bvc2ljacOzbiwgcG9kZW1vcyB1c2FyIGxhIHJlbGFjacOzbiBhbnRlcmlvciBwYXJhIGRlZHVjaXIgXChHXnstMX1cKSBkZSBcKEheey0xfVwpLCB5IHV0aWxpemFyIFwoR157LTF9XCkgcGFyYSBlbmNvbnRyYXIgZXJyb3JlcyBlc3TDoW5kYXJlcyBwYXJhIGxvcyBwYXLDoW1ldHJvcyBuYXR1cmFsZXMsIHRhbGVzIHBhcsOhbWV0cm9zIHByb3Zpc3RvcyBubyBlc3TDoW4gZW4gbGEgZnJvbnRlcmEgZGVsIGVzcGFjaW8gZGVsIHBhcsOhbWV0cm8uIFVuYSBydXRhIGFsdGVybmF0aXZhIHBhcmEgbG9zIGVycm9yZXMgZXN0w6FuZGFyZXMgY29uIHJlc3BlY3RvIGEgbG9zIHBhcsOhbWV0cm9zIG5hdHVyYWxlcyBlbCBjdWFsIGEgbWVudWRvIHJlc3VsdGEgYmllbiwgeSBlcyBtZW5vcyBsYWJvcmlvc2EsIGVzIGxhIHNpZ3VpZW50ZS4gUHJpbWVybyBlbmN1ZW50cmUgZWwgTUxFIGFsIHJlc29sdmVyIGVsIHByb2JsZW1hIGRlIG9wdGltaXphY2nDs24gcmVzdHJpbmdpZGEsIGx1ZWdvIHZ1ZWx2YSBhIGNvcnJlciBsYSBvcHRpbWl6YWNpw7NuIHNpbiByZXN0cmljY2lvbmVzLCBlbXBlemFuZG8gZW4gbyBtdXkgY2VyY2FubyBhbCBNTEUuIFNpIGVsIGVzdGltYWRvIHJlc3VsdGFudGUgZXMgZWwgbWlzbW8gcXVlIGVsIE1MRSB5YSBlbmNvbnRyYWRvLCBlbCBIZXNzaWFubyBjb3JyZXNwb25kaWVudGUgZW50b25jZXMgcHJvdmVlIGRpcmVjdGFtZW50ZSBsb3MgZXJyb3JlcyBlc3TDoW5kYXJlcyBjb24gcmVzcGVjdG8gYSBsb3MgcGFyw6FtZXRyb3MgbmF0dXJhbGVzLiBQZXJvIHNpIHVubyBoYWNlIGxhIHN1cG9zaWNpw7NuIGRlIG5vcm1hbGlkYWQgeSBiYXNhIHVuIGludGVydmFsbyBkZSBjb25maWFuemEgZW4gw6lsLCB0YWwgc3Vwb3NpY2nDs24gZGUgbm9ybWFsaWRhZCBlcyBtYXMgcHJvYmFibGUsIHBlcm8gbm8gZ2FyYW50aXphZGEuCgojIyMjI0NvbXB1dGFjacOzbiByZWN1cnNpdmEgZGVsIEhlc3NpYW5vCgpVbiBtw6l0b2RvIGFsdGVybmF0aXZvIGRlIGNvbXB1dGFyIGVsIEhlc3NpYW5vIGVzIGVsIGRlIEx5c3RpZyB5IEh1Z2hlcyAoMjAwMikuIEVsbG9zIHByZXNlbnRhbiBlbCBhbGdvcml0bW8gZGUgYXZhbmNlIFwozrFfdD3OsV97dC0xfSDOk1AoeF90KVwpIGRlIG1hbmVyYSBlbiBsYSBjdWFsIGluY29ycG9yYW4gdW5hIGVzY2FsYSBhdXRvbcOhdGljYSBvIOKAnG5hdHVyYWzigJ0sIHkgbHVlZ28gZXh0aWVuZGVuIGVzdGUgZW5mb3F1ZSBwYXJhIGFzw60gY29tcHV0YXIgc3UgSGVzc2lhbm8geSBncmFkaWVudGUgY29uIHJlc3BlY3RvIGEgbG9zIHBhcsOhbWV0cm9zIG5hdHVyYWxlcywgYXF1ZWxsb3MgcXVlIGhlbW9zIGRlc2NyaXRvIGFycmliYSBwb3IgXCjOuF9pXCkuIFR1cm5lciAoMjAwOCkgaGEgdXNhZG8gZXN0ZSBlbmZvcXVlIHBhcmEgYXPDrSBidXNjYXIgbGFzIGRlcml2YWRhcyBhbmFsw610aWNhcyByZXF1ZXJpZGFzIHBhcmEgbWF4aW1pemFyIHBvc2liaWxpZGFkZXMgZGUgSE1NcyBkaXJlY3RhbWVudGUgcG9yIGVsIGFsZ29yaXRtbyBMZXZlbmJlcmctTWFycXVhcmR0LgpBdW5xdWUgZXN0byBwdWVkZSBzZXIgdW4gbcOpdG9kbyBtYXMgZWZpY2llbnRlIHkgcHJlY2lzbyBkZSBjb21wdXRhciBlbCBIZXNzaWFubyBxdWUgdXRpbGl6YXIgbGEgcmVsYWNpw7NuIGRlc2NyaXRhIGFudGVyaW9ybWVudGUsIG5vIHJlc3VlbHZlIGVsIHByb2JsZW1hIGZ1bmRhbWVudGFsIHF1ZSBlbCB1c28gZGVsIEhlc3NpYW5vIHBhcmEgY29tcHV0YXIgZXJyb3JlcyBlc3TDoW5kYXJlcyAoeSBkZSBhbGzDrSBpbnRlcnZhbG9zIGRlIGNvbmZpYW56YSkgbm8gZXMgZGUgY29uZmlhbnphIHNpIGFsZ3Vub3MgZGUgbG9zIHBhcsOhbWV0cm9zIGVzdMOhbiBlbiBvIGNlcmNhIGRlIGxhIGZyb250ZXJhIGRlbCBlc3BhY2lvIGRlbCBwYXLDoW1ldHJvLgoKCiMjIzMuNi4yLiBFcnJvcmVzIGVzdMOhbmRhcmVzIEJvb3RzdHJhcCBlIGludGVydmFsb3MgZGUgY29uZmlhbnphCgpDb21vIHVuYSBhbHRlcm5hdGl2YSBhIGxhcyB0w6ljbmljYXMgZGVzY3JpdGFzIGVuIGxhIHNlY2Npw7NuIGFudGVyaW9yLCB1bm8gcHVlZGUgdXNhciBlbCBCb290c3RyYXAgcGFyYW3DqXRyaWNvLiBIYWJsYW5kbyBidXJkYW1lbnRlLCBsYSBpZGVhIGRlbCBCb290c3RyYXAgcGFyYW3DqXRyaWNvIGVzIGVsIGV2YWx1YXIgbGFzIHByb3BpZWRhZGVzIGRlbCBtb2RlbG8gY29uIHBhcsOhbWV0cm9zIFwoXFRoZXRhXCl1c2FuZG8gYXF1ZWxsb3MgZGVsIG1vZGVsbyBjb24gcGFyw6FtZXRyb3MgXChcd2lkZWhhdFxUaGV0YVwpLiBMb3Mgc2lndWllbnRlcyBwYXNvcyBzb24gcmVhbGl6YWRvcyBwYXJhIGVzdGltYXIgbGEgbWF0cml6IGRlIHZhcmlhbnphLWNvdmFyaWFuemEgZGUgXChcd2lkZWhhdFxUaGV0YVwpLgoKMS4gQWp1c3RlIGVsIG1vZGVsbywgY29tcHV0ZSBcKFx3aWRlaGF0XFRoZXRhXCkuCjIuIChhKSBHZW5lcmUgdW5hIG11ZXN0cmEsIGxsYW1hZGEgbXVlc3RyYSBCb290c3RyYXAsIGRlIG9ic2VydmFjaW9uZXMgZGVsIG1vZGVsbyBhanVzdGFkbywgZWwgbW9kZWxvIGNvbiBwYXLDoW1ldHJvcyBcKFx3aWRlaGF0XFRoZXRhXCkuIExhIGxvbmdpdHVkIGRlYmVyw61hIHNlciBsYSBtaXNtYSBxdWUgZWwgbsO6bWVybyBvcmlnaW5hbCBkZSBvYnNlcnZhY2lvbmVzLgotIChiKSBFc3RpbWUgbG9zIHBhcsOhbWV0cm9zIFwoXFRoZXRhXCkgcG9yIFwoXHdpZGVoYXRcVGhldGFeKlwpcGFyYSBsYSBtdWVzdHJhIEJvb3RzdHJhcC4KLSAoYykgUmVwaXRhIGxvcyBwYXNvcyAoYSkgeSAoYikgQiB2ZWNlcyAoY29uIEIg4oCcZ3JhbmRl4oCdKSB5IHJlZ2lzdHJlIGxvcyB2YWxvcmVzIFwoXHdpZGVoYXRcVGhldGFeKlwpLgoKTGEgbWF0cml6IGRlIHZhcmlhbnphLWNvdmFyaWFuemEgZGUgXChcd2lkZWhhdFxUaGV0YVwpIGVzIGVudG9uY2VzIGVzdGltYWRhIHBvciBsYSBtYXRyaXogZGUgdmFyaWFuemHigJRjb3ZhcmlhbnphIG11ZXN0cmEgZGUgbG9zIGVzdGltYWRvcyBCb290c3RyYXAgXChcd2lkZWhhdFxUaGV0YV4qXCkgKGIpLCBcKGI9MSwyLOKApixCXCk6CgokJApWYXItQ292KFx3aWRlaGF0XFRoZXRhKSA9IFxmcmFjezF9e0ItMX0gXHN1bV97Yj0xfV5CIChcd2lkZWhhdFxUaGV0YV4qKGIpIC0gXHdpZGVoYXRcVGhldGFeKihcY2RvdHApKScoXHdpZGVoYXRcVGhldGFeKihiKSAtIFx3aWRlaGF0XFRoZXRhXiooXGNkb3RwKSkgXFwKZG9uZGUgXFwKXHdpZGVoYXRcVGhldGFeKihcY2RvdHApID0gQl57LTF9IFxzdW1fe2I9MX1eQiBcVGhldGFeKihiKQokJAoKRWwgQm9vdHN0cmFwIHBhcmFtw6l0cmljbyByZXF1aWVyZSBjw7NkaWdvIHBhcmEgZ2VuZXJhciByZWFsaXphY2lvbmVzIGRlIHVuIG1vZGVsbyBhanVzdGFkby4gRWwgbcOpdG9kbyBkZSBCb290c3RyYXAgcHVlZGUgc2VyIHVzYWRvIHBhcmEgZXN0aW1hciBpbnRlcnZhbG9zIGRlIGNvbmZpYW56YSBkaXJlY3RhbWVudGUuCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg==