Este Documento final consta de la recopilación de los capitulos: \[ * Preliminaries: \quad Mixtures\quad and \quad Markov \quad Chains;\\ * Hidden \quad Markov \quad Models:\quad definition \quad and \quad properties;\\ * Estimation \quad by \quad direct \quad maximization \quad of \quad the \quad likelihood; \]

Capitulo 1: Preliminaries: Mixtures and Markov Chains

1.1Introducción

Los modelos ocultos de Markov (HMM) son modelos en los cuales se tiene la atribución de que el sistema que se está trabajando es un proceso de Markov, cuyos parametros no se conocen. Esto permite que el proceso se vuelva de proposito general y sirva para series de tiempo: univariadas y multivariadas.

Para ilustrar al lector sobre las aplicaciones que tienen las HMM, se usará un archivo llamado “EarthQuakeDataCH1.csv”; este archivo contiene informacion de terremotos de magnitud mayor a 7 desde 1900 al 2007.

Para ello se procede a leer el CSV con la librería “readr”:

library(readr)
library(htmltools)
data_terremotos <- data.frame(read_csv('EarthQuakeDataCH1.csv'))
Parsed with column specification:
cols(
  Anio = col_integer(),
  cantidadTerremotos = col_integer()
)
#graficacion de datos
plot(x = data_terremotos[,1],y = data_terremotos[,2], type = "b", col = "#33d6ff", lwd = 4, xlab = "Años", ylab = "Magnitud")

Figura 1.1

Para darnos una idea sobre que distrubucion puede seguir la data, utilizamos un histograma que se muestra a continuación:

#se utiliza la columna 2 debido a que alli se encuentran las magnitudes
magnitudes <- data_terremotos[,2]
#creacion del histograma
h <- hist(magnitudes, breaks = 10, density = 10,
          col = "#0099cc", xlab = "Accuracy", main = "Terremotos - Distribucion") 
#definicion de limites X y Y
xfit <- seq(min(magnitudes), max(magnitudes), length = 40) 
yfit <- dnorm(xfit, mean = mean(magnitudes), sd = sd(magnitudes)) 
yfit <- yfit * diff(h$mids[1:2]) * length(magnitudes) 
lines(xfit, yfit, col = "#ff4775", lwd = 2)

Tal como se puede observar la dispersión corresponde a un podelo de Poisson. Las cadenas ocultas de Markov(HMM) se han usado desde hace mas de tres decadas, el mayor campo de operación ha sido el analisis de señales, tales como:

  • Reconocimiento: voz, facial, gestos, firmas.
  • Ambiente: terremotos, direccion del viento, lluvia.
  • Finanzas
  • Biofisica: modelacion de canales de iones.

Una de las grandes caracteristicas del HMM es que es simple se realizar y debido a su trasfondo matematico tambien es adecuado para tener una respuesta computacional rapida.

1.2 Modelos de mezcla independientes

1.2.1 Definicion y propiedades

Considere nuevamente la serie de cuentas de terremotos ilustrada en la Figura 1.1. Un modelo estándar para cuentas ilimitadas es la distribución de Poisson, con su función de probabilidad \[p(x)=e^{-λ}*λ^x/x!\] y la propiedad que indica que la varianza equivale a la media. Sin embargo, para la serie de terremotos, la muestra de varianza, \(s^2≈52\), es mucho mas grande que la muestra de la media, \[\bar{x} ≈19\], lo cual indica una fuerte sobre dispersión relativa a la distribución de Poisson. La falta de semejanza es confirmada por la Figura 1.2, la cual ilustra la distribución de Poisson ajustada y un diagrama de barras de las frecuencias relativas de las cuentas. Un método para resolver observaciones sobre dispersas con una distribución binodo o (más generalmente) distribución multimodo es usar un modelo de mezcla. Los modelos de mezcla son diseñados para acomodar heterogeneidad inobservada en la población; eso es, la población puede consistir de grupos inobservados, cada uno teniendo una distribución distinta para la variable observada. Considérese el ejemplo, la distribución del número, X, de paquetes de cigarrillos comprados por los consumidores de un supermercado. Los consumidores pueden ser divididos en grupos, por ejemplo, no fumadores, fumadores ocasionales, y fumadores regulares. Ahora aun si el numero de paquetes comprado por los consumidores entre cada grupo fuera distribuible por Poisson, la distribución X no seria Poisson; seria sobre dispersa relativa a Poisson, y talvez aun multimodo. Análogamente, supóngase que cada cuenta en la serie de terremotos es generada por una de dos distribuciones de Poisson, con medias \(λ_1\) y \(λ_2\), donde la elección de media es determinada por otros mecanismos aleatorios que llamaremos el proceso de parámetro. Supóngase también que \(λ_1\) es seleccionado con probabilidad \(δ_1\) y \(λ_2\) con probabilidad \(δ_2=1-δ_1\). Veremos mas adelante en este capitulo que la varianza de la distribución resultante excede la media por \(δ_1 δ_2 (λ_1-λ_2 )^2\). Si el proceso de parámetro es una serie de variables aleatorias independientes, las cuentas también son independientes, de ahí el término “mezcla independiente”. En general, una distribución de mezcla independiente consiste de un numero finito, dígase \(m\), de distribuciones de componente y una “distribución de mezcla” la cual selecciona de estas componentes. Las distribuciones de componente pueden ser tanto discretas como continuas. En el caso de dos componentes, la mezcla de distribución depende de dos probabilidades o funciones de densidad:

\[ Componente \qquad \qquad\qquad\qquad\qquad1 \qquad\qquad 2 \\ Probabilidad o función de densidad \qquad p_1(x) \qquad p_2(x) \]

Para especificar la componente, una necesita una variable aleatoria discreta C la cual realiza la mezcla:

\[ C= \begin{cases} 1 \quad con \quad probabilidad \quad\delta_1\\ 2 \quad con \quad probabilidad \quad\delta_2 = 1-\delta_1 \end{cases} \]

La estructura de ese proceso para el caso de dos distribuciones de componentes continuas es ilustrada en la Figura 1.3. En ese ejemplo uno puede pensar de C como el resultado de lanzar una moneda con probabilidad 0.75 de “cara”: si el resultado es “cara”, entonces C = 1 y una observación es tomada de p_1: si es “cruz”, entonces C = 2 y una observación es tomada de \(p_2\). Suponemos que no sabemos el valor de C, eso es, cual de \(p_1\) o \(p_2\) estaba activo cuando la observación fue generada.

Figura 1.3

Figura 1.3

La extensión de m componentes es sencilla. Que \(δ_1,…,δ_m\) denote las probabilidades asignadas a las diferentes componentes, y que \(p_1,…,p_m\) denote sus probabilidades o funciones de densidad. Que X denote la variable aleatoria la cual tiene la distribución de mezcla. En el caso discreto, la función de probabilidad de X es dada por:

\[ p(x) = \sum_{i=1}^{m} Pr(X=x|C=i)Pr(C=i)\\ =\sum_{i=1}^{m}\delta_ip_i(x) \] El caso continuo es análogo. La expectativa de la mezcla puede ser dada en términos de las expectaciones de las distribuciones de componentes. Dejando que Y, denote la variable aleatoria con función de probabilidad \(p_i\), tenemos:

\[ E(X) = \sum_{i=1}^{m} Pr(C=i) E(X|C=i) = \sum_{i=1}^{m} \delta_iE(Y_i) \]

El mismo resultado aguarda para una mezcla de distribuciones continuas. Mas generalmente, para una mezcla del k-esimo momento del origen es simplemente una combinación lineal de los k-esimos momentos de sus componentes \(Y_i\):

\[ E(X^k) = \sum_{i=1}^{m} \delta_iE(Y_i^k), k=1,2,... \]

Nótese que el resultado análogo no cuenta para momentos centrales. En particular, la varianza X no es una combinación linear de las varianzas de sus componentes \(Yi\). El Ejercicio 1 le pide al lector probar eso, en el caso de dos componentes, la varianza de la mezcla está dada por:

\[ Var(X) = \delta_1Var(Y_1)+\delta_2Var(Y_2)+\delta_1\delta_2(E(Y_1)-E(Y_2))^2 \]

1.2.2 Estimación de parámetros

La estimación de parámetros de una distribución de mezclas es a menudo realizada por una probabilidad máxima (ML). La probabilidad de un modelo de mezcla con m componentes esta dada, para tanto casos discretos como continuos, por:

\[ L(\theta_1,...,\theta_m,\delta_1,...,\delta_m|x_1,...,x_n) = \prod_{j=1}^{n}\sum_{i=1}^{m}\delta_ip_i(x_j,\theta_i) \]

Aquí \(θ_1,…,θ_m\) son los vectores de parametros de las distribuciones de componentes, \(δ_1,…,δ_m\) son los parametros de mezcla, totalizando 1, y \(x_1,…,x_n\) son las n observaciones. Entonces, en el caso de distribuciones de componentes cada una especificada por un parámetro, \(2m-1\) parametros independientes tienen que ser estimados. Excepto talvez en casos especiales, maximización analítica de tal probabilidad no es posible, pero es generalmente sencillo de evaluarlo rápidamente; ver Ejercicio 3. Maximización numérica será ilustrada aquí al considerar el caso de una mezcla de distribuciones de Poisson. Supongase que m=2 y las dos componentes son distribuibles por Poisson con medias \(λ_1\) y \(λ_2\). Que \(δ_1\) y \(δ_2\) sean los parámetros de mezcla (con \(δ_1 + δ_2 = 1\). La distribución de mezcla p esta dada por:

\[ p(x) = \delta_1 \frac{\lambda_1^xe^{-\lambda_1}}{x!}+\delta_2 \frac{\lambda_2^xe^{-\lambda_2}}{x!} \] Desde que \(δ_2=1-δ_1\), hay solamente tres parámetros a estimar: \(λ_1\), \(λ_2\) y \(δ_1\). La probabilidad es:

\[ L(\lambda_1,\lambda_2,\delta_1|x_1,...,x_n) = \prod_{i=1}^n(\delta_1\frac{\lambda_1^{x_i}e^{-\lambda_1}}{x_i!}+(1-\delta_1)\frac{\lambda_2^{x_i}e^{-\lambda_2}}{x_i!}) \] La maximización analítica de L con respecto a \(λ_1\), \(λ_2\) y \(δ_1\) seria rara, ya que L es el producto de n factores, del cual cada uno es una suma. Primero tomar el logaritmo y luego la diferenciación no simplifica mucho las cosas tampoco. Por lo tanto, la estimación de parámetros es mas convenientemente llevada a cabo por maximización numérica directa de la probabilidad (o su logaritmo), aunque el logaritmo EM es comúnmente usado como alternativa; véase, por ejemplo, McLachlan y Peel (2000) o Fruhwirth-Schnatter (2006). Un paquete útil de R para estimación en modelos de mezcla es \(flexmix\) (Leisch, 2004). Sin embargo, es sencillo escribir nuestro propio código de R para evaluar, y luego maximizar, probabilidades de mezcla en casos sencillos. Esta probabilidad puede ser luego maximizada al usar (por ejemplo) la función de R nlm. Sin embargo, los parámetros \(\delta\) y \(\lambda\) son sujetos por (ecuación rara) y (para \(i = 1, …, m\)) \(δ_i > 0\) y \(λ_i>0\). Es entonces necesario Re parametrizar si uno así lo desea para utilizar un optimizador sin restricciones tal como nlm. Una posibilidad para maximizar la probabilidad con respecto a los 2m-1 “parámetros funcionales” sin restricción.

\[ \eta_i = log\lambda_i (i=1,...m) \] y

\[ \tau_i = log(\frac{\delta_i}{1-\sum_{j=2}^m \delta_j}) (i=2,...,m) \]

Se recuperan los “parámetros naturales” originales por medio de:

\[ \lambda_i = e^{\eta_i} \quad (i=1,...,m) \\ \delta_i = \frac{e^{\tau_i}}{1+\sum_{j=2}^me^{\eta_j}} \quad (i=2,...,m) \]

Y \(δ_1=1-\sum_{j=2}^{m}δ_i\) . El siguiente código implementa las ideas anteriores en orden para que encajen un modelo de cuatro distribuciones de Poisson a las cuentas de terremotos. Los resultados están dados por m = 1,2,3,4 en la Tabla 1.2

mllk <- function(wpar,x){ zzz <- w2n(wpar)
        -sum(log(outer(x,zzz$lambda,dpois)%*%zzz$delta)) }
n2w  <- function(lambda,delta)log(c(lambda,delta[-1]/(1-sum(delta[-1]))))
w2n  <- function(wpar){m <- (length(wpar)+1)/2
        lambda <- exp(wpar[1:m])
        delta  <- exp(c(0,wpar[(m+1):(2*m-1)]))
return(list(lambda=lambda,delta=delta/sum(delta))) }
x        <- read.table("/Users/bracruz/Documents/8vo. Trimestre IO/Sist. Expertos y Redes Prob./earthquakes.txt")[,2]
wpar     <- n2w(c(10,20,25,30),c(1,1,1,1)/4)
w2n(nlm(mllk,wpar,x)$estimate)
NA/Inf replaced by maximum positive value
$lambda
[1] 15.52750 10.58416 20.96911 32.07922

$delta
[1] 0.35429030 0.09302729 0.43662984 0.11605257

Notese como, en este código, el uso de la función outer hace posible el evaluar la probabilidad de mezcla de Poisson en una simple y compacta expresión en vez de en un ciclo. Pero si la distribución siendo mezclada fueran distribuciones con mas de un parámetro (dígase, normal), un enfoque un poco distinto seria necesario.

Los resultados anteriores pueden ser verificados en la siguiente tabla:

Tabla 1.2

Tabla 1.2

1.2.3 Probabilidad ilimitada en mezclas

Hay un aspecto en mezclas de distribuciones continuas que difieren del caso discreto y vale la pena resaltarlo. Es el siguiente: puede pasar que: en la vecinidad de ciertas combinaciones de parámetros, la probabilidad es ilimitada. Por ejemplo, en el caso de una mezcla de distribuciones normales, la probabilidad se vuelve arbitrariamente grande si uno asigna la media componente igual a una de las observaciones y permite que la varianza correspondiente tienda a cero. El problema ha sido ampliamente discutido en la literatura de modelos de mezcla, y hay aquellos que sugieren que si la probabilidad es entonces ilimitada, la ML estima simplemente que “no existe”.

La fuente del problema, sin embargo, es solamente el uso de densidades en vez de probabilidades en la posibilidad; no surgiría si se remplazara cada valor de densidad en una posibilidad por la probabilidad del intervalo correspondiente al valor registrado. (Por ejemplo, una observación registrada como “12.4” esta asociada con el intervalo [12.35, 12.45]). En el contexto de mezclas independientes se remplaza la expresión:

\[ \prod_{j=1}^n\sum_{i=1}^m\delta_i p_i(x_j,\theta_i) \]

de la posibilidad (véase ecuación anterior) por la posibilidad dicreta:

\[ L = \prod_{j=1}^n\sum_{i=1}^m\delta_i \int_{a_j}^{b_j} p_i(x,\theta_i)dx \]

Donde el intervalo \((a_j, b_j)\) consiste de aquellos valores los cuales, si son observados, serian registrados como \(x_j\). Esto simplemente equivale a reconocer explícitamente la naturaleza del intervalo de todas las supuestas observaciones continuas. Mas generalmente, la posibilidad discreta de observaciones en un conjunto de variables aleatorias \(X_1, X_2,…, X_n\) es la probabilidad de la forma \(Pr(a_i < X_i < b_i \quad para\quad toda \quad i)\). Utilizaremos el termino posibilidad continua para la densidad conjunta evaluada en la observación. Otra manera de evitar este problema es el imponer un limite inferior en las varianzas y buscar el mejor sujeto máximo local para ese límite. Puede suceder, sin embargo, que se puede ser tan afortunado para evitar los “picos” de posibilidad al buscar por un máximo local; en este aspecto, valores buenos de inicio pueden ayudar. El fenómeno de posibilidades ilimitadas no surge para observaciones de valores discretos porque la posibilidad en ese caso es una probabilidad y por ende, limitada a valores entre 0 y 1.

1.2.4. Ejemplos de modelos de mezcla ajustados

Mezcla de distribuciones de Poisson

Si uno utiliza nlm para ajustar una mezcla de m distribuciones de Poisson (m=1,2,3,4) a los datos del terremoto, uno obtiene los resultados desplegados en la Tabla 1.2. Notese que hay una clara mejora en la posibilidad resultante de la adicion de una segunda componente, y muy poca mejora de la adicion de una cuarta – aparentemente insuficiente para justificar los dos parámetros adicionales. La Figura 1.4 presenta un histograma de las cuentas observadas y los cuatro modelos ajustados. Es claro que las mezclas encajan las observaciones mucho mejor a como lo hace una sola distribución de Poisson, y visualmente los modelos de tres y cuatro estados parecen adecuados. El mejor ajuste para las mezclas es también evidente de las varianzas de los cuatro modelos como esta presentada en la Tabla 1.2. Al computar las medias y varianzas de los modelos hemos usado \(E(X)=\sum_iδ_i λ_i\) y \(Var(X)=E(X^2 )-(E(X))^2\), con \(E(X^2 )=\sum_iδ_i (λ_i+λ_i^2)\). Para comparación también hemos usado el paquete de R flexmix para ajustar los cuatro modelos. Los resultados correspondieron mucho a excepción de laso del modelo de cuatro componentes, donde el valor de posibilidad mas grande que encontramos por flexmix fue 356.7759 y las medias de los componentes difirieron un poco. Notese también, que la discusión superior ignora la posibilidad de dependencia serial en los datos del terremoto, un punto el cual se retomara en el Capítulo 2.

Figura 1.4

Figura 1.4

1.3 Cadenas de Markov

Ahora introduciremos las cadenas de Markov. Nuestro análisis se restringe a aquellos aspectos de cadenas de Markov discretas los cuales necesitaremos. Asi, sin embargo haremos referencia a propiedades tales como la irreductibilidad y aperiodicidad, no lidiaremos con cuestiones técnicas. 1.3.1 Definiciones y ejemplos Una secuencia de variables aleatorias discretas \({C_t:t ∈ N} \)se dice que es una (tiempo discreto) Cadena de Markov (CM) si, para todo t ∈N, satisface la propiedad de Markov:

\[ Pr(C_{t+1} | C_t,...,C_1) = Pr((C_{t+1}|C_t) \] Eso es, condicionando a la historia del proceso hasta el tiempo t es equivalente a condicionar solo el valor mas reciente \(C_t\). Para hacerlo más compacto, definimos \(C^t\) como la historia \((C_1,C_2,…,C_t )\), en cual caso, la propiedad de Markov se puede escribir como:

\[ Pr(C_{t+1} | C^{(t)} = Pr(C_{t+1} | C_t) \] La propiedad de Markov puede ser interpretada como la primera relajación de la suposicion de independencia. Las variables aleatorias \({C_t}\) son dependientes de una manera que es matemáticamente conveniente, como es mostrado en el siguiente grafico en el cual el pasado y el futuro son dependientes solo a través del presente.

Cantidades importantes asociadas con una cadena de Markov son las probabilidades conditionales, también llamadas probabilidades de transición:

\[ Pr(C_{s+t}=j | C_s = i) \] Si estas probabilidades no dependen de s, la cadena de Markov es llamada homogénea, de otra manera seria no-homogenea. A no ser que haya una indicación explicita al contrario, asumiremos que la cadena de Markov en discusión es homogénea, en cual caso las probabilidades de transición serán denotadas por:

\[ \gamma_{ij}(t)= Pr(C_{s+t}|C_s=i) \] Notese que la notación \(γ_{ij} (t)\) no involucra a s. La matriz \(Γ(t)\) esta definida como la matriz con elementos \(γ_{ij} (t)\).

Una importante propiedad de todas las cadenas de Markov homogéneas y de estado y espacio finito es la que satisface las ecuaciones Chapman-Kolmogorov:

\[ \Gamma(t+u) = \Gamma(t) \Gamma(u) \] La solución requiere solamente la definición de probabilidad condicional y la aplicación de la propiedad de Markov. Las ecuaciónes Chapman-Kolmogorov implican que, para todo \(t ∈N\):

\[\Gamma(t)=\Gamma(1)^t\] Esto es, la matriz de probabilidades de transición con paso-t es la t-esima potencia de \(Γ(1)\), la matriz de probabilidades de transición de un paso. La matriz \(Γ(1)\), la cual será abreviada como \(Γ\), es una matriz cuadrada de probabilidades con la suma de sus filas igual a 1:

\[ \quad \] Donde m denota el numero de estados de la cadena de Markov. La declaración de que la suma de las filas es igual a 1 puede ser escrito como \(Γ1'=1'\); eso es, el vector columna \(1’\) es un eigenvector derecho de \(Γ\) y corresponde al eigenvalor 1. Nos referiremos a \(Γ\) como la matriz de transición de probabilidad (t.p.m). Muchos autores utilizan en vez del termino “matriz de transición”; evitaremos este termino debido a posibles confusiones con cuentas de matriz de transición, o intensidades de una matriz de transición.

Las probabilidades incondicionales \(Pra(C_t=j)\) de una cadena de Markov siendo en un estado dado en un tiempo dado t son a menudo de interés. Denotamos estos por el vector fila:

\[u(t) = (Pr(C_t=1),...,Pr(C_t=m)), t∈N\]

Nos referimos a u(1) como la distribución inicial de una cadena de Markov Para deducir la distribución en el tiempo t+1 desde el cual en t post multiplicamos por la matriz de transición de probabilidad \(Γ\):

\[u(t+1)=u(t)\Gamma \] Ejemplo. Imaginese que la declaración de días soleados y lluviosos es tal que el clima del dia depende solamente en el del dia anterior, y las probabilidades de transición están dadas por la siguiente tabla:

\[ \quad \]

Esto es, si hoy fue un dia lluvioso, la probabilidad que mañana sea lluvioso es de 0.9; si hoy estuvo soleado, la probabilidad de es 0.6. El clima es entonces una cadena de Markov homogénea de dos estados, con t.p.m. \(Γ\) dado por

\[ \Gamma = 0.9 \quad 0.1\\ \qquad0.6 \quad 0.4 \]

Ahora suponga que hoy (tiempo 1) es un dia soleado. Esto significa que la distribución del clima del dia de hoy es:

\[u(1) = (Pr(C_1 = 1),Pr(C_1 = 2)) = (0,1)\]

La distribución del clima de mañana, del pasado mañana, y asi, puede ser calculada post multiplicando repetidamente \(u(1)\) por
\(Γ\), el t.p.m:

\[ u(2) = (Pr(C_2 = 1),Pr(C_2 = 2)) = u(1)\Gamma = (0.6,0.4)\\ u(3) = (Pr(C_3 = 1),Pr(C_3 = 2)) = u(2)\Gamma = (0.78,0.22) \]

1.3.2. Distribuciones estacionarias

Una cadena de Markov con matriz de transición de probabilidad Γ se dice que tiene una distribución estacionaria δ (un vector fila con elementos no negativos) si δΓ=δ y δ1’ = 1. El primero de estos requerimientos expresa la estacionariedad, la segunda es el requerimiento que δ es una distribución de probabilidad. Por ejemplo, la cadena de Markov con t.p.m dado por

\[ \Gamma = 1/3 | \quad 1/3| \quad 1/3\\ \quad 2/3| \quad 0| \quad 1/3 \\ \quad 1/2| \quad 1/2| \quad 0 \] Tiene una distribución estacionaria \(δ=1/32 (15,9,8)\).

Desde que \(u(t+1) = u(t)Γ\), una cadena de Markov iniciada desde su distribución estacionaria continuara teniendo esa distribución en todos lo puntos de tiempo subsecuente, y nos referiremos a tal proceso como una cadena de Markov estacionaria. Es talvez valioso resaltar que esto asume mas que solamente homogeneidad. Solo la homogeneidad no seria suficiente para volver la cadena de Markov un proceso estacionario, y preferimos reservar el adjetivo “estacionario” para cadenas de Markov estacionarias que tienen la propiedad adicional que la distribución inicial \(u(1)\) es la distribución estacionaria y por ende procesos estacionarios.

Una cadena de Markov irreducible (homogénea, tiempo discreto, estado-espacio finito) tiene una distribución estacionaria, única y estrictamente positiva. Nótese sin embargo la suposición de irreductibilidad es necesaria para esta conclusión, la aperiodicidad no. Si, sin embargo, uno añade la suposición de aperiodicidad, una única distribución limitante existe, y es precisamente la distribución estacionaria. Desde que siempre debemos asumir aperiodicidad e irreductibilidad, los términos “distribución limitante” y “distribución estacionaria” son sinónimos para nuestros propósitos.

Un resultado general que puede ser convenientemente usado para computar una distribución estacionaria. El vector \(δ\) con elementos no negativos es una distribución estacionaria de la cadena de Markov con t.p.m Γ si y solo si:

\[\delta(I_m - \Gamma + U) = 1\]

Donde 1 es un vector fila de unos, \(I_m\) es la matriz identidad m x m, y U es la matriz m x m de unos. Alternativamente, una distribución estacionaria puede ser encontrada al borrar una de las ecuaciones en el sistema \(δΓ=δ\) y reemplazándola por \(\sum_iδ_i=1\).

1.3.3 Función de autocorrelación

Tendremos una oportunidad, por ejemplo en la Seccion 2.2.3 y en el Ejercicio 4(f) en el Capitulo 2, para comparar las funciones de autocorrelación (ACF) de uno modelo oculto de Markov con su cadena de Markov subyacente \({C_t}\), en los estados \(1, 2, …, m\). Asumiremos que estos estados son cuantitativos y no solamente categóricos. La ACF de \({C_t}\), asumida estacionaria e irreducible, puede ser obtenida de la siguiente manera. Primero, definiendo \(v = (1, 2, …, m)\) y \(V = diag(1, 2, …, m)\), tenemos, para todos los enteros k no negativos, \[ Cov(C_t,C_{t+k}) = \delta V\Gamma^kv' - (\delta v')^2 \] Segundo, si Γ es diagonizable, y sus eigenvalores (otro de 1) son denotados por w_2, w_3, …, w_m, entonces Γ puede ser escrito como:

\[\Gamma = U \Omega U^{-1} \] Donde \(Ω\) es \(diag(1, w_2, w_3, …, w_m)\) y las columnas de U son eigenvectores derechos correspondientes de \(Γ\). Entonces tenemos, para enteros no negativos k,

\[ Cov(C_t,C_{t+k}) = \delta V U \Omega^k U^{-1} v' - (\delta v')^2 \\ = a\Omega^k b' - a_1b_1 \\ =\sum_{i=2}^m a_ib_iw_i^k \] donde a = \(\delta VU\) y b’ = \(U^{-1}\). Por lo tanto \(Var(C_t )=\sum_{i=2}^m a_i b_i\) y, para enteros no negativos k:

\[ \rho(k) = Corr(C_t,C_{t+k}) = \sum_{i=2}^m a_ib_iw_i^k / \sum_{i=2}^m a_ib_i \]

Esto es un peso promedio de las k-esimas potencias de los eigenvalores \(w_2, w_3, …, w_m\), y de alguna manera similares a la ACF de un proceso auto regresivo Gaussiano de orden m-1. Nótese que la ecuación anterior implica en el caso m=2 que \(ρ(k)=ρ(1)^k\) para todos los enteros no negativos k, y que \(ρ(1)\) es el eigenvalor distinto a 1 de \(Γ\).

1.3.4. Estimando probabilidades de transición

Si nos dan una realización de una cadena de Markov, y deseamos estimar las probabilidades de transición, un enfoque – pero no solo el único – es el encontrar las cuentas de transición y estimar las probabilidades de transición como frecuencias relativas. Por ejemplo, si la CM tiene tres estados y la secuencia observada es:

( 2332111112 3132332122 3232332222 3132332212 3232132232 3132332223 3232331232 3232331222 3232132123 3132332121 )

Entonces la matriz de cuentas de transición es:

\[ (f_{ij}) = 4 \quad 7 \quad 6 \\ \qquad\qquad8 \quad 10 \quad 24 \\ \qquad\qquad 6 \quad 24 \quad 10 \]

Donde \(f_ij\) denota el numero de transiciones observadas del estado i al estado j. Desde que el numero de transiciones del estado 2 al estado 3 es 24, y el numero total de transiciones del estado 2 es 8+10+24, un estimado de frecuencia relativa de \(γ_23\) es 24/42. El t.p.m \(Γ\) es entonces estimado por:

\[ (f_{ij}) = 4/17 \quad 7/17 \quad 6/17 \\ \qquad\qquad8/42 \quad 10/42 \quad 24/42 \\ \qquad\qquad 6/40 \quad 24/40 \quad 10/40 \]

Ahora mostraremos que esto es de hecho el estimado condicional ML de \(Γ\), condicionada en la primera observación. Supongamos entonces que deseamos estimar los \(m^2-m\) parámetros \(γ_{ij} (i≠j)\) de una cadena e Markov de estado m \({C_t}\) de una realización c_1, c_2, …, c_T. La posibilidad condicionada en la primera observación es:

\[ L = \prod_{i=1}^m\prod_{j=1}^m \gamma_{ij}^{f_{ij}} \] El registro de probabilidad es entonces:

\[ l = \sum_{i=1}^m(\sum_{j=1}^m f_{ij} log \gamma_{ij}) = \sum_{i=1}^m l_i() \]

Y podemos maximizar l al maximizar cada \(l_i\) por separado. Sustituyendo \(1-\sum_{(k≠i)}γ_{ik}\) para \(γ_ii\) diferenciando \(l_i\) con respecto a una posibilidad de transición fuera de la diagonal \(γ_ij\) e igualando la derivada a cero rendimientos

\[ 0 = \frac{-f_{ii}}{1-\sum_{k≠i}\gamma_{ik} +\frac{f_{ij}}{\gamma_{ij}} = -\frac{f_{ii}}{\gamma_{ii}}+\frac{f_{ij}}{\gamma_{ij}}} \]

Entonces, a menos que un denominador sea cero en la ecuación superior,( f_{ij} γ_{ii}=f_{ii} γ_{ij} )y entonces \(γ_{ii} \sum_{(j=1)}^mf_{ij}=f_{ii}\). Esto implica que, en un máximo de la posibilidad,

\[ \gamma_{ii} = f_{ii}/\sum_{j=1}^m f_{ij} \quad y \quad \gamma_{ij} = f_{ij}/\sum_{j=1}^m f_{ij} \]

(Podríamos utilizar multiplicadores de Lagrange para expresar las restricciones \(\sum_{j=1}^mγ_{ij}=1\) sujeto al cual buscamos maximizar los términos \(l_i\) y por ende la posibilidad; es solo la probabilidad de transición empírica – es entonces visto a ser un estimador condicional ML de \(γ_ij\). El estimador \(Γ\) satisface el requerimiento que la suma de las filas es igual a 1.

La suposicion de estacionariedad de la cadena de Markov no fue usada en la derivación superior. Si deseamos asumir la estacionariedad, podemos usar la posibilidad incondicional. Esta es la posibilidad condicional mostrada anteriormente, multiplicada por la probabilidad estacionaria δ_c1. La posibilidad incondicional o su logaritmo pueden ser entonces maximizados numéricamente, sujeto a restricciones no negativas y suma de filas, en orden para estimar las probabilidades de transición \(γ_{ij}\). Bisgaard y Travis (1991) muestran en el caso de una cadena de Markov de dos estados que, excepto en algunos casos extremos, ecuaciones de posibilidad incondicional tienen una única solución. Para algunos casos especiales no triviales de la cadena de dos estados, también derivan expresiones explicitas para los estimados incondicionales de posibilidad máxima (MLEs) de las probabilidades de transición. Desde que usamos tal resultado luego, lo declaramos aquí. Suponga que la cadena de Markov \({C_t}\) toma los valores 0 y 1, y que deseamos estimar las probabilidades de transición \(γ_{ij}\) de una secuencia de observaciones en el cual hay \(f_{ij}\)transiciones del estado i al estado j (i,j=0,1), y \(f_{11}>0\) pero \(f_{00}=0\). Asi que en las observaciones un cero siempre es seguido por un uno. Definase \(c=f_{10}+(1-c_1)\) y \(d=f_{11}\). Entonces las MLEs incondicionales de las probabilidades de transición están dadas por:

\[ \gamma_{01} = 1 \quad y \quad \gamma_{10} = \frac{-(1+d)+((1+d))^2 + 4c(c+d-1))^{1/2}}{2(c+d+1)} \]

1.3.5. Cadenas de Markov de orden superior

En casos donde observaciones en un proceso con espacio y estado finito aparecen no satisfacer la propiedad de Markov, una posibilidad que sugiere a si misma es el utilizar una cadena de Markov de orden superior, esto es, un modelo \({C_t}\) satisfaciendo la siguiente generalización de la propiedad de Markov para algunos l≥2:

\[ Pr(C_t | C_{t-1} = j_1,...,C_{t-l}=j_l) = \sum_{i=1}^l \lambda_i q(j_i,j_o) \] Un registro de tal orden de cadenas de Markov puede ser encontrado, por ejemplo, el Lloyd (1980, Sección 19.9). Aunque tal modelo no es en un sentido usual una cadena de Markov, podemos redefinir el modelo de tal manera como para producir un proceso equivalente. Si permitimos que \(Y_t=(C_{(t-l+1)},C_{(t-l+2)},…,C_t)\), entonces {Y_t} es una cadena de Markov de primer orden en M^l, donde M es el espacio de estado de {C_t}. Aunque algunas propiedades pueden ser raras de establecer, ninguna nueva teoría es involucrada en analizar una cadena de Markov de orden superior mas que una de primer orden. Una cadena de Markov de segundo orden, si es estacionaria, esta caracterizada por las probabilidades de transición:

\[ \gamma(i,j,k) = Pr(C_t=k | C_{t-1} = j, C_{t-2} = i) \]

Y tiene una distribución estacionaria de variable doble \(u(j,k)=Pra(C_{t-1}=j,C_t=k)\) que satisface

\[ u(j,k) = \sum_{i=1}^m u(i,j)\gamma(i,j,k) \quad y \quad \sum_{j=1}^m\sum_{k=1}^m u(j,k) =1 \]

Por ejemplo, la cadena de Markov estacionaria de segundo orden mas general \({C_t}\), en los dos estados 1 y 2, esta caracterizada por las siguientes cuatro probabilidades de transición:

\[ a = Pr(C_t=2 | C_{t-1}=1, C_{t-2} = 1) \\ b = Pr(C_t=1 | C_{t-1}=2, C_{t-2} = 2) \\ c = Pr(C_t=1 | C_{t-1}=2, C_{t-2} = 1) \\ d = Pr(C_t=2 | C_{t-1}=1, C_{t-2} = 2) \\ \] El proceso \({Y_t }={(C_{t-1},C_t )}\) es entonces una cadena de Markov de primer orden, con los cuatro estados (1,1), (1,2), (2,1), (2,2), con matriz de transición de probabilidades

\[ \left(\begin{array}{cc} 1-a & a & 0 & 0\\ 0 & 0 & c & 1-c \\ 1-d & d & 0 & 0 \\ 0 & 0 & b & 1-b \end{array}\right) \]

Note los ceros estructurales que aparecen en la matriz. No es posible, por ejemplo, hacer una transición directa de (2,1) a (2,2); por lo tanto, el cero en la fila 3 y columna 4 en el t.p.m. Los parámetros a, b, c y d están limitados a 0 y 1 pero son sin restricciones en otro caso. La distribución estacionaria de \({Y_t}\) es proporcional al vector

\[(b(1-d),ab,ab,a(1-c))\]

Del cual se dice que la matriz \(u(j,k)\) de probabilidades bi-variable estacionaria para \({C_t }\) es:

\[ \frac{1}{b(1-d)+2ab+a(1-c)} \left(\begin{array}{cc} b(1-d) & ab\\ ab & a(1-c) \end{array}\right) \]

El uso de una cadena de Markov general de orden superior incrementa el número de parámetros del modelo; una cadena de Markov general de orden l en m estados tiene \(m^l (m-1)\) probabilidades de transicion independientes. Pegram (1980) y Raftery (1985) han por lo tanto propuesto ciertas clases de modelos para cadenas de orden superior. El modelo de Pegram tiene m+l-1 parametros, y aquellos de Raftery m(m-1)+l-1. Para m=2 los modelos son equivalentes, pero para m>2 aquellos de Raftery son mas generales y pueden representar un rango mas amplio de patrones de dependencia y estructuras de autocorrelación. En ambos casos un incremento de uno en el orden de la cadena de Markov requiere solamente de un parámetro adicional. Modelos de Raftery, a los cuales el se refiere como modelos de “distribución de transición de la mezcla” (MTD), son definidos como sigue. El proceso \({C_t}\) toma valores \(M={1,2,…,m}\) y satisface

\[Pr(C_t = j_0 | C_{t-1} = j_1,..., C_{t-l} = j_l) = \sum_{i-1}^l \lambda_i q(j_i,j_0)\] Donde \(\sum_{i=1}^l λ_i=1\), y \(Q=(q(j,k))\) es una matriz m×m con entradas no negativas y la suma de sus filas equivale a uno, tal que el lado derecho de la ecuación anterior esta limitada por cero y uno para todo \(j_o,j_1,…,j_l∈M\). Este último requerimiento, el cual general m^(l+1) pares de restricciones no lineares en los parámetros, asegura que las probabilidades condicionales en la ecuación anterior son en efecto probabilidades, y la condición en la suma de filas de Q asegura que la suma sobre \(j_0\) de estas probabilidades condicionales es uno. Note que Raftery no asume que los parámetros \(λ_i\), son no negativos.


Capítulo 2: Modelos de Markov ocultos: definición y propiedades

2.1. Un modelo de Markov oculto simple

Considérese nuevamente la serie de terremotos mostrada en el capitulo anterior. Las observaciones son cuentas ilimitadas, haciendo la distribución de Poisson una elección natural para describirlas, pero su distribución es claramente relativa sobre dispersa a la de Poisson. Observamos en el capítulo anterior que este hecho puede ser acomodado al usar una mezcla de distribuciones de Poisson con medias \(λ_1,λ_2,…,λ_m\). La elección de la media esta hecha por un segundo proceso aleatorio, el proceso de parámetro. La media \(λ_i\) es seleccionada con probabilidad \(δ_i\), donde \(i=1,2,…,m\) y \(\sum_{i=1}^mδ_i=1\).

Un modelo de mezcla independiente no resultara con la serie de terremotos porque, por definición, no permite la dependencia serial en las observaciones. La muestra de función de autocorrelación (ACF), desplegada en la Figura 2.1, claramente indica que las observaciones son dependientes en serie. Una manera de permitir la dependencia serial en las observaciones es relajar la suposición que el proceso de parámetro es independiente en serie. Una manera simple y matemáticamente conveniente para hacer esto es asumir que es una cadena de Markov. El modelo resultante para las observaciones es llamado un modelo de Markov oculto de Poisson.

library(forecast)
library(readr)
#leer la data 
data_terremotos_ch2 <- read.table("/Users/bracruz/Documents/8vo. Trimestre IO/Sist. Expertos y Redes Prob./earthquakes.txt")
#Obtener la ACF de la data anterior
ACF_ch2 <- acf(data_terremotos_ch2, plot=TRUE)

Figura 2.1

2.2 Lo básico

2.2.1 Definición y notación

Figura 2.2

Figura 2.2

Un modelo de Markov oculto \({X_t:t ∈N}\) es un tipo particular de mezcla dependiente. Con \(X^t\) y \(C^t\) representando las historias del tiempo 1 al tiempo t, uno puede resumir el modelo más simple de este tipo por:

\[ Pr(C_t | C^{t-1}) = Pr(C_t | C_{t-1}), t=2,3,... \\ Pr(X_t | X^{t-1},C^t) = Pr(X_t | C_t), t ∈ N \] El modelo consiste de dos partes: primero, un “proceso de parámetro” no observado \({C_t:t=1,2,…}\) satisfaciendo la propiedad de Markov; y como segundo, el “proceso estado-dependiente” \({X_t:t=1,2,…}\), en el cual la distribución de \(X_t\) depende solamente en el estado actual \(C_t\) y no de estados u observaciones previas. La estructura se representa en la Figura 2.2

Si la cadena de Markov \({C_t}\) tiene m estados, llamamos \({X_t}\) una HMM de m-estados. Aunque es la terminología usual en aplicaciones de procesamiento del habla, el nombre “modelo de Markov oculto” es por ningún medio el único usado para tales o similares.

Figura 2.3 - Proceso gerenando las observaciones en un estado doble de HMM. Siguiendo la cadena 2,1,1,1,2,1

Figura 2.3 - Proceso gerenando las observaciones en un estado doble de HMM. Siguiendo la cadena 2,1,1,1,2,1

El proceso generando las observaciones es nuevamente demostrado en la Figura anterior, para distribuciones estado-dependientes \(p_1\) y \(p_2\), distribución estacionaria \(δ=(0.75,0.25)\), y t.p.m. \(\Gamma= \left(\begin{array}{cc} 0.9 & 0.1\\ 0.3 & 0.7 \end{array}\right)\). En contraste al caso de una mezcla independiente, aquí la distribución de \(C_t\), el estado en tiempo t, sí depende de \(C_(t-1)\). También es cierto de las mezclas independientes, hay para cada estado una distribución diferente, discreta o continua. Ahora introduciremos una notación la cual cubrirá tanto observaciones valuadas discretas como continuas. En el caso de observaciones discretas, definimos, para \(i=1,2,…,m\)

\[p_i(x) = Pr(X_t = x | C_t = i)\] Esto es, \(p_i\), es la función de probabilidad en masa de \(X_t\) si la cadena de Markov está en el estado i en el tiempo t. El caso continuo es tratado de manera similar: aquí definimos \(p_i\) como la función de densidad de probabilidad de \(X_t\) asociada con el estado i. Nos referimos a las m distribuciones \(p_i\) como la distribución estado-dependiente del modelo.

2.2.2 Distribuciones marginales

A menudo necesitamos las distribuciones marginales de \(X_t\) y también distribuciones marginales de orden superior, tales como \((X_t,X_{t+k})\). Derivaremos los resultados para el caso en el cual la cadena de Markov es homogénea pero no necesariamente estacionaria, y luego veremos para el caso especial en donde la cadena de Markov es estacionaria. Por conveniencia la derivación es dada solo para las distribuciones estado-dependientes discretas; el caso continuo puede ser derivado análogamente.

Distribuciones de una variable

Para observaciones de valores discretos \(X_t\), definimos \(u_i(t)=Pra(C_t=i)\quad para\quad t=1,…,T\), tenemos

\[ Pr(X_t = x) = \sum_{i=1}^m Pr(C_t = i) Pr(X_t = x |C_t = i) \\ = \sum_{i=1}^m u_i(t)p_i(x) \] La expresión puede ser convenientemente rescrita en notacion de matriz

\[ Pr(X_t = x) = (u_1(t),...,u_m(t)) \left(\begin{array}{cc} p_1(x) & 0\\ 0 & p_m(x) \end{array}\right) \left(\begin{array}{cc} 1\\ 1 \end{array}\right) \\ =u(t) P(x)1' \] Donde \(P(x)\) es definida como la matriz diagonal con su i-esimo elemento diagonal \(p_i (x)\). Tomando en cuenta la ecuación del capítulo anterior que dicta que \(u(t)=u(1) Γ^{t-1}\), y por lo tanto

\[Pr(X_t = x) = u(1)\Gamma^{t-1} P(x)1'\] Esta ecuación funciona solamente si la cadena de Markov es puramente homogénea, y no necesariamente estacionaria. Si, como lo asumiremos usualmente, la cadena de Markov es estacionaria, con distribución estacionaria \(δ\), el resultado es aún más simple: en ese caso \(δΓ^{(t-1)}=δ\) para todo \(t∈N\), y entonces

\[Pr(X_t = x) = \delta P(x)1'\]

Distribuciones de dos variables

El cálculo de muchas de las distribuciones relacionadas a un HMM es realizado más fácilmente al notar de primero que, para un modelo grafico dirigido, la distribución conjunta de un set de variables aleatorias \(V_i\) esta dada por

\[Pr(V_1,V_2,...,V_n) = \prod_{i=1}^n Pr(V_i |pa(V_i))\]

Donde \(pa(V_i )\) denota el set de todos los “parientes” de \(V_i\) en el set \(V_1,V_2,…,V_n\). En el grafico dirigido de las cuatro variables aleatorias \(X_t,X_{(t+k)},C_t,C_{(t+k)}\) (para enteros positivos k), \(C_t\) no tiene parientes, \(pa(X_t )={C_t },pa(C_{(t+k)} )={C_t}\) y \(pa(X_{(t+k)} )={C_{(t+k)}}\). Y por tanto sigue que

\[ Pr(X_t,X_{t+k},C_t,C_{t+k}) = Pr(C_t)Pr(X_t|C_t) Pr(C_{t+k}|C_t) Pr(X_{t+k}|C_{t+k}) \] Y por lo tanto dicta que:

\[ Pr(X_t = v, X_{t+k}=w) = \sum_{i=1}^m \sum_{j=1}^m u_i(t)p_i(v)\gamma_{ij}(k)p_j(w) \]

(Aquí y en cualquier otro lado, \(γ_{ij} (k)\) denota los (i,j) elementos de \(Γ^k\).) Escribiendo la suma doble superior como el productor de matrices obtenemos

\[ Pr(X_t = v, X_{t+k}=w) = u(t) P(v)\Gamma^k P(w)1' \] Si la cadena de Markov es estacionaria, esto se reduce a

\[ Pr(X_t = v, X_{t+k}=w) = \delta P(v) \Gamma^k P(w)1' \]

Similarmente, uno puede obtener expresiones para las distribuciones marginales de orden superior; en el caso estacionario, la formula para una distribución de tres variables es, para enteros positivos k y l

\[ Pr(X_t=v, X_{t+k}=w, X_{t+k+l} =z) = \delta P(v) \Gamma^k P(w) \Gamma^l P(z)1' \]

2.2.3 Momentos

Primero notemos que

\[ E(X_t) = \sum_{i=1}^m E(X_t | C_t=i ) Pr(C_t = i) = \sum_{i=1}^m u_i(t) E(X_t|C_t = i) \] En el cual, el caso estacionario se reduce a

\[ E(X_t) = \sum_{i=1}^m \delta_i E(X_t| C_t = i) \] Mas generalmente, resultados analogos aguardan para \(E(g(X_t ))\) y \(E(g(X_t,X_{t+k} ))\), para cualquier función \(g\) para las cuales expectativas estado-dependientes relevantes existen. En el caso estacionario

\[ E(g(X_t)) = \sum_{i=1}^m \delta_i E(g(X_t) | C_t =i) \] y además

\[ E(g(X_t,X_{t+k})) = \sum_{i,j=1}^m E(g(X_t,X_{t+k})|C_t = i, C_{t+k} = j) \delta_i \gamma_{ij}(k) \] A menudo también estaremos interesados en una función g la cual factoriza a

\[g(X_t, X_{t+k}) = g_1(X_t) g_2(X_{t+k})\] En cual caso la ecuación resultante termina siendo

\[ E(g(X_t,X_{t+k})) = \sum_{i,j=1}^m E(g_1(X_t)| C_t = i) E(g_2(X_{t+k})|C_{t+k}=j) \delta_i \gamma_{ij}(k) \] Estas expresiones nos permiten encontrar covarianzas y correlaciones; expresiones explicitas convenientes existen para muchos casos. Para el caso de un HMM de Poisson estacionario de dos estados:

\[ E(X_t) = \delta_1 \lambda_1 + \delta_2 \lambda_2 \\ Var(X_t) = E(X_t) + \delta_1 \delta_2(\lambda_2 - \lambda_1)^2 \geq E(X_t) \\ Cov(X_t, X_{t+k}) = \delta_1 \delta_2(\lambda_2 - \lambda_1)^2 (1 - \gamma_{12} - \gamma_{21})^k, para \quad k \in N \]

Notese que la formula resultante para la correlación de \(X_t\) y \(X_{t+k}\) es de la forma \(ρ(k)=A(1-γ_{12}-γ_{21} )^k\) con \(A∈[0,1)\), y que A=0 si \(λ_1=λ_2\).

2.3. La Posibilidad

El objetivo de esta sección es desarrollar una formula conveniente para la posibilidad de \(L_T\) de T observaciones continuas \(x_1,x_2,…,x_T\) asumida a ser generada por un HMM de m-estados. Veremos que la computación de la posibilidad, consiste de la suma de \(m^T\) términos, cada cual es un producto de 2T factores, parece requerir O(Tm^T) operaciones. Nuestro propósito aquí es demostrar que \(L^T\) puede ser en general computado simplemente relacionado en \(O(Tm^2 )\) operaciones. La manera luego será ampliada para estimar parámetros por maximización numéricas de la posibilidad. Primero, la posibilidad de modelos de dos estados será explorada, y entonces la formula general será presentada.

2.3.1. La posibilidad de un HMM de Bernoulli de dos estados

Considere el HMM estacionario de dos estados con t.p.m.

\[ \Gamma = \left(\begin{array}{cc} 1/2 & 1/2\\ 1/4 & 3/4 \end{array}\right) \quad y \quad \delta = \left(\begin{array}{cc} 1/3, 2/3 \end{array}\right) \]

Y distribuciones estado-dependientes dadas por

\[ Pr(X-t =x | C_t = 1) = 1/2 \quad(para\quad x =0,1) \\ Pr(X-t =1 | C_t = 2) = 1 \]

Llamaremos un modelo de este tipo un HMM de Bernoulli. . Considere la probabilidad \(Pra(X_1=X_2=X_3=1\). Primero, note que, por ecuaciones anteriores,

\[ Pra(X_1,X_2,X_3,C_1,C_2,C_3 )=Pra(C_1 ) Pra(X_1│C_1 ) Pra(C_2│C_1 ) Pra(X_2│C_2 ) Pra(C_3│C_2 ) Pra(X_3 |C_3); \] luego sumarmos los valores asumidos por \(C_1,C_2,C_3\). El resultado es:

\[ Pr(X_1=1, X_2 = 1, X3=1) \\ = \sum_{i=1}^2 \sum_{j=1}^2 \sum_{k=1}^2 Pr(X_1 = 1,X_2=1,X_3=1, C_1 =i, C_2=j, C_3=k) \\ = \sum_{i=1}^2 \sum_{j=1}^2 \sum_{k=1}^2 \delta_i p_i(1) \gamma_{ij} p_j(1) \gamma_{jk} p_k(1) \] Note que la triple suma de la ecuación anterior tiene \(m^T=2^3\) términos, cada del cual es producto de \(2T=2 x 3 \)factores. Para evaluar la probabilidad requerida, las diferentes posibilidades para los valores de i,j y k pueden ser listados y la suma calculada como en la siguiente tabla

Probabilidad de la probabilidad de una HMM Bernoulli

Probabilidad de la probabilidad de una HMM Bernoulli

La suma de la última columna de la tabla anterior nos dice que \(Pra(X_1=1,X_2=1,X_3=1)=29/48\) . Al observar notamos que el elemento más grande en esa columna es 3/8; la secuencia de estados que maximiza la probabilidad conjunta

\[Pr(X_1 = 1,X_2=1,X_3=1, C_1 =i, C_2=j, C_3=k)\] Es entonces la secuencia \(i=2,j=2,k=2\). Equivalentemente, maximiza la probabilidad condicional \(Pra(C_1=i,C_2=j,C_3=k| X_1=1,X_2=1,X_3=1)\). Pero una manera mas conveniente de presentar la sumar es utilizar notación de matriz. Definamos P(u) como \(diag(p_1 (u),p_2 (u))\). Entonces

\[ P(0) = \left(\begin{array}{cc} 1/2 & 0\\ 0 & 0 \end{array}\right) \quad y \quad P(1)= \left(\begin{array}{cc} 1/2 & 0\\ 0 & 1 \end{array}\right) \] Y la triple suma anterior puede ser escrita como el producto de una matriz

\[ δP(1)ΓP(1)ΓP(1)1' \]

2.3.2. La posibilidad en general

Aquí consideramos la posibilidad de un HMM en general. Suponemos hay una secuencia de observación \(x_1,x_2,…,x_T \)generada por tal modelo. Buscamos la probabilidad \(L_T\) de observar esa secuencia, según lo calculado bajo un HMM de m-estados el cual tiene una distribución inicial \(δ\) y t.p.m. \(Γ\) para la cadena de Markov, funciones de probabilidad estado-dependientes \(p_i\).

Proposicion 1: La probabilidad es dada por

\[ L_T = \delta P(x_1)\Gamma P(x_2) \Gamma P(x_3) \quad ... \quad \Gamma P(x_T)1' \] si \(\delta\), la distribucioón de \(C_1\), si es una distribucion estacionaria de la cadena de Markov, entonces:

\[ L_T = \delta \Gamma P(x_1)\Gamma P(x_2) \Gamma P(x_3) \quad ... \quad \Gamma P(x_T)1' \]

Una simple pero crucial consecuencia de la expresión matricial para la posibilidad es el “algoritmo de avance” para computación recursiva de la posibilidad. Tal computación recursiva juega un rol clave, no solo en evaluación de la posibilidad y por tanto estimación de parámetros, pero también en predecir, decodificar y revisar modelos. La naturaleza recursiva de tal evaluación de posibilidad vía la Proposición 1 es computacionalmente mucho mas efectivo que suma de fuerza bruta sobre todas las secuencias de estado posible. El hecho que tales esquemas computacionales recursivos no costosos pueden ser utilizados para abordar varias preguntas de interés es una característica clave de los HMMs. Para definir el algoritmo de avance, definimos el vector \(α_t\) para \(t=1,2,…,T\), por

\[ \alpha_t = \delta P(x_1)\Gamma P(x_2) \Gamma P(x_3) \quad ... \quad \Gamma P(x_t) = \delta P(x_1) \prod_{s=2}^t \Gamma P(x_s) \] Con la convención que un producto vacío es la matriz identidad. Sigue inmediatamente de esta definición que

\[ L_T = \alpha_T 1' \quad y \quad \alpha_t = \alpha_{t-1} \Gamma P(x_t) \quad para \quad t \ge 2 \] Acordemente, podemos convenientemente fijar como sigue las computaciones involucradas en la fórmula de posibilidad

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

El número de operaciones involucradas es de orden \(Tm^2\) puede ser deducido así. Para cada uno de los valores de t en el ciclo, hay m elementos de \(α_t\) por ser computados, y cada uno de esos elementos es una suma de m productos de tres cantidades: un elemento de \(α_{t-1}\), una probabilidad de transición \(γ_{ij}\), y una probabilidad (o densidad) estado-dependiente \(p_j (x_t)\).

El esquema de correspondiente para la computación de la Propuesta 1 es

\[ \alpha_0 = \delta \\ \alpha_t = \alpha_{t-1} \Gamma P(x_t) \quad para \quad t =1,2,...,T \\ L_T = \alpha_T 1' \] Los elementos del vector \(α_t\) son usualmente referidos como probabilidades de avance; donde mostramos que el j-esimo elemento de \(α_t\) es \(Pra(X^{(t)}=x^{(t)},C_t=j\). A continuación, mostramos código de R que utiliza el algoritmo de avance para evaluar la posibilidad de observaciones \(x_1,…x_T\) bajo un HMM de Poisson con por lo menos dos estados, t.p.m. \(Γ\), vector de medias estado-dependientes \(λ\), y distribución inicial \(δ\).

alpha <- delta*dpois(x[1], lambda)
for(i in 2:T) 
  alpha <- %*% Gamma*dpois(x[i],lambda)
sum(alpha)

En la discusión superior hemos utilizado la expresión de múltiples sumas para la posibilidad para así llegar a la expresión matricial, y luego utilizado la expresión matricial para llegar a la recursión de avance. Una ruta alternativa es definir el vector de avance de probabilidades \(α_t\) por

\[ \alpha_t(j) = Pr(X^{(t)} = x^{(t)}, C_t = j), j=1,2,...,m \] Y luego deducir la recursión de avance

\[ \alpha_t = \alpha_{t-1} \Gamma P(x_t) \] La expresión matricial es entonces una simple consecuencia de la recursión de avance.

2.3.3 HMMs no son procesos de Markov

HMMs no satisfacen en general la propiedad de Markov. Esto lo podemos demostrar mediante un simple contrajemplo. Basado en la seccion 2.3.1 sabemos que:

\[ Pr(X_1=1,X_2=1,X_3=1) = \frac{29}{48} \\ Pr(X_2=1) = \frac{5}{6} \\ entonces \\ Pr(X_1,X_2=1) = Pr(X_2=1,X_3=1) = \frac{17}{24} \\ por \quad tanto \quad se\quad deduce\quad que \\ Pr(X_3=1 | X_1=1,X_2=1) = \frac{Pr(X_1=1,X_2=1,X_3=1)}{Pr(X_1=1,X_2=1)} = \frac{29/48}{17/24} \\ y \quad eso \\ Pr(X_3=1|X_2=1) = \frac{Pr(X_2=1,X_3=1)}{Pr(X_2=1)} = \frac{17/24}{5/6} = 17/20 \]

Por lo tanto \(Pra(X_3=1|X_2=1)≠Pra(X_3=1|X_1=1,X_2=1\); este HMM no satisface la propiedad de Markov. Para las condiciones bajo las cuales un HMM si satisface la propiedad de Markov.

2.3.4. La posibilidad cuando hay datos faltantes

En el contexto de una serie de tiempo es potencialmente raro si algunos de los datos faltan. En el caso de series de tiempo de modelos ocultos de Markov, sin embargo, el ajuste que se necesita ser realizado para la computación de la posibilidad si hay datos faltantes resulta ser uno fácil. Suponga, por ejemplo, que uno tiene disponible las observaciones \(x_1,x_2,x_4,x_7,x_8,…,x_T\) de un HMM pero \(x_3,x_5 \quad y \quad x_6 \)hacen falta. Entonces la posibilidad de las observaciones esta dada por

\[ Pr(X_1=x1,X_2=x2,X_4=x_4,X_7=x_7,X_8=x_8,...,,X_T=x_T) = \\ \sum \delta_{c_1}\gamma_{c1,c2}\gamma_{c2,c4}(2) \gamma_{c4,c7} (3) \gamma_{c7,c8} \quad ... \quad \gamma_{c_{T-1},c_T} \\ \times p_{c_1} (x_1) p_{c2}(x_2) p_{c4}(x_4) p_{c7}(x_7)\quad ... \quad p_{c_T}(x_T) \]

Donde (como antes) \(γ_{ij} (k)\) denota una probabilidad de transición de paso k, y la suma se toma sobre todos los índices \(c_t\) diferentes de \(c_3,c_5 y c_6\). Pero esto es solamente

\[ \sum \delta_{c_1} p_{c_1} (x_1) \gamma_{c_1},c_2p_{c_2} (x_2) \gamma_{c_2},c_4(2)p_{c_4} (x_4) \gamma_{c_4},c_7(3)p_{c_7} (x_7) \gamma_{c_7} \quad \times...\times \quad \gamma_{c_T-1}, c_T p_{c_T}(x_T)= \\ \delta P(x_1) \Gamma P(x_2)\Gamma^2 P(x_4) \Gamma^3 P(x_7)...\Gamma P(x_T)1' \]

Con \(L_T^{-(3,5,6)}\) denotando la posibilidad de las observaciones (diferentes de las faltantes), se declara que

\[ L_T^{-(3,5,6)} = P(x_1) \Gamma P(x_2)\Gamma^2 P(x_4) \Gamma^3 P(x_7)...\Gamma P(x_T)1' \]

En general, la expresión para la posibilidad de matrices diagonales \(P(x_t)\) correspondiente a las observaciones faltantes \(x_t\) son remplazadas por la matriz identidad; eso es, las probabilidades estado-dependientes correspondientes \(p_i (x_t )\) son remplazadas por 1 para todos los estados i.

2.3.5. La posibilidad cuando las observaciones son censoradas por intervalo

Suponga que deseamos ajustar un HMM de Poisson a una serie de cuentas, algunas de las cuales son censoradas por intervalo. Por ejemplo, el valor de \(x_t\) puede ser conocido para \(4≤t≤T\), con la información \(x_1≤5,2≤x_2≤3\) y \(x_3>10\) disponible acerca de las observaciones restantes. Para simplificar, asumamos de primero que la cadena de Markov solo tiene dos estados. En ese caso, uno remplaza las matrices diagonales \(P(x_i )(i=1,2,3)\) en la expresión de posibilidad por las matrices

\[ diag(Pr(X_1 \le |C_1 =1), Pr(X_1 \le 5| C_1=2)), \\ diag(Pr(2 \le X_2 \le 3 | C_2=1),Pr(2 \le X_2 \le 3 | C_2=2)) \\ diag(Pr(X_3 \gt 10 | C_3 = 1), Pr(X_3 \gt 10 | C_3 = 2)) \]

Mas generalmente, suponga que \(a≤x_t≤b\) donde a puede ser \(-∞\) (aunque eso no es relevante para el caso de Poisson), b puede ser \(∞\), y la cadena de Markov tiene m estados. Uno remplaza \(P(x_t)\) en la posibilidad por la matriz diagonal \(m×m\) de la cual el elemento diagonal i-esimo es \(Pra(a≤X_t≤b|C_t=i)\)


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.

LS0tCnRpdGxlOiAnRG9jdW1lbnRvIEZpbmFsJwphdXRob3I6ICdCcmF5YW4gSXZhbiBDcnV6IENvcm9uYScKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKRXN0ZSBEb2N1bWVudG8gZmluYWwgY29uc3RhIGRlIGxhIHJlY29waWxhY2nDs24gZGUgbG9zIGNhcGl0dWxvczogCiQkCiogUHJlbGltaW5hcmllczogXHF1YWQgTWl4dHVyZXNccXVhZCBhbmQgXHF1YWQgTWFya292IFxxdWFkIENoYWlucztcXAoqIEhpZGRlbiBccXVhZCBNYXJrb3YgXHF1YWQgTW9kZWxzOlxxdWFkIGRlZmluaXRpb24gXHF1YWQgYW5kIFxxdWFkIHByb3BlcnRpZXM7XFwKKiBFc3RpbWF0aW9uIFxxdWFkIGJ5IFxxdWFkIGRpcmVjdCBccXVhZCBtYXhpbWl6YXRpb24gXHF1YWQgb2YgXHF1YWQgdGhlIFxxdWFkIGxpa2VsaWhvb2Q7CiQkCgojQ2FwaXR1bG8gMTogUHJlbGltaW5hcmllczogTWl4dHVyZXMgYW5kIE1hcmtvdiBDaGFpbnMKCiMjMS4xSW50cm9kdWNjacOzbgoKTG9zIG1vZGVsb3Mgb2N1bHRvcyBkZSBNYXJrb3YgKEhNTSkgc29uIG1vZGVsb3MgZW4gbG9zIGN1YWxlcyBzZSB0aWVuZSBsYSBhdHJpYnVjacOzbiBkZSBxdWUgZWwgc2lzdGVtYSBxdWUgc2UgZXN0w6EgdHJhYmFqYW5kbyBlcyB1biBwcm9jZXNvIGRlIE1hcmtvdiwgY3V5b3MgcGFyYW1ldHJvcyBubyBzZSBjb25vY2VuLiBFc3RvIHBlcm1pdGUgcXVlIGVsIHByb2Nlc28gc2UgdnVlbHZhIGRlIHByb3Bvc2l0byBnZW5lcmFsIHkgc2lydmEgcGFyYSBzZXJpZXMgZGUgdGllbXBvOiB1bml2YXJpYWRhcyB5IG11bHRpdmFyaWFkYXMuIAoKUGFyYSBpbHVzdHJhciBhbCBsZWN0b3Igc29icmUgbGFzIGFwbGljYWNpb25lcyBxdWUgdGllbmVuIGxhcyBITU0sIHNlIHVzYXLDoSB1biBhcmNoaXZvIGxsYW1hZG8gIkVhcnRoUXVha2VEYXRhQ0gxLmNzdiI7IGVzdGUgYXJjaGl2byBjb250aWVuZSBpbmZvcm1hY2lvbiBkZSB0ZXJyZW1vdG9zIGRlIG1hZ25pdHVkIG1heW9yIGEgNyBkZXNkZSAxOTAwIGFsIDIwMDcuCgpQYXJhIGVsbG8gc2UgcHJvY2VkZSBhIGxlZXIgZWwgQ1NWIGNvbiBsYSBsaWJyZXLDrWEgInJlYWRyIjoKCmBgYHtyfQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KGh0bWx0b29scykKZGF0YV90ZXJyZW1vdG9zIDwtIGRhdGEuZnJhbWUocmVhZF9jc3YoJ0VhcnRoUXVha2VEYXRhQ0gxLmNzdicpKQoKI2dyYWZpY2FjaW9uIGRlIGRhdG9zCnBsb3QoeCA9IGRhdGFfdGVycmVtb3Rvc1ssMV0seSA9IGRhdGFfdGVycmVtb3Rvc1ssMl0sIHR5cGUgPSAiYiIsIGNvbCA9ICIjMzNkNmZmIiwgbHdkID0gNCwgeGxhYiA9ICJBw7FvcyIsIHlsYWIgPSAiTWFnbml0dWQiKQpgYGAKRmlndXJhIDEuMQoKUGFyYSBkYXJub3MgdW5hIGlkZWEgc29icmUgcXVlIGRpc3RydWJ1Y2lvbiBwdWVkZSBzZWd1aXIgbGEgZGF0YSwgdXRpbGl6YW1vcyB1biBoaXN0b2dyYW1hIHF1ZSBzZSBtdWVzdHJhIGEgY29udGludWFjacOzbjoKCmBgYHtyfQojc2UgdXRpbGl6YSBsYSBjb2x1bW5hIDIgZGViaWRvIGEgcXVlIGFsbGkgc2UgZW5jdWVudHJhbiBsYXMgbWFnbml0dWRlcwptYWduaXR1ZGVzIDwtIGRhdGFfdGVycmVtb3Rvc1ssMl0KCiNjcmVhY2lvbiBkZWwgaGlzdG9ncmFtYQpoIDwtIGhpc3QobWFnbml0dWRlcywgYnJlYWtzID0gMTAsIGRlbnNpdHkgPSAxMCwKICAgICAgICAgIGNvbCA9ICIjMDA5OWNjIiwgeGxhYiA9ICJBY2N1cmFjeSIsIG1haW4gPSAiVGVycmVtb3RvcyAtIERpc3RyaWJ1Y2lvbiIpIAoKI2RlZmluaWNpb24gZGUgbGltaXRlcyBYIHkgWQoKeGZpdCA8LSBzZXEobWluKG1hZ25pdHVkZXMpLCBtYXgobWFnbml0dWRlcyksIGxlbmd0aCA9IDQwKSAKeWZpdCA8LSBkbm9ybSh4Zml0LCBtZWFuID0gbWVhbihtYWduaXR1ZGVzKSwgc2QgPSBzZChtYWduaXR1ZGVzKSkgCnlmaXQgPC0geWZpdCAqIGRpZmYoaCRtaWRzWzE6Ml0pICogbGVuZ3RoKG1hZ25pdHVkZXMpIAoKbGluZXMoeGZpdCwgeWZpdCwgY29sID0gIiNmZjQ3NzUiLCBsd2QgPSAyKQpgYGAKCgpUYWwgY29tbyBzZSBwdWVkZSBvYnNlcnZhciBsYSBkaXNwZXJzacOzbiBjb3JyZXNwb25kZSBhIHVuIHBvZGVsbyBkZSBQb2lzc29uLiBMYXMgY2FkZW5hcyBvY3VsdGFzIGRlIE1hcmtvdihITU0pIHNlIGhhbiB1c2FkbyBkZXNkZSBoYWNlIG1hcyBkZSB0cmVzIGRlY2FkYXMsIGVsIG1heW9yIGNhbXBvIGRlIG9wZXJhY2nDs24gaGEgc2lkbyBlbCBhbmFsaXNpcyBkZSBzZcOxYWxlcywgdGFsZXMgY29tbzogCgoqIFJlY29ub2NpbWllbnRvOiB2b3osIGZhY2lhbCwgZ2VzdG9zLCBmaXJtYXMuCiogQW1iaWVudGU6IHRlcnJlbW90b3MsIGRpcmVjY2lvbiBkZWwgdmllbnRvLCBsbHV2aWEuCiogRmluYW56YXMKKiBCaW9maXNpY2E6IG1vZGVsYWNpb24gZGUgY2FuYWxlcyBkZSBpb25lcy4gCgpVbmEgZGUgbGFzIGdyYW5kZXMgY2FyYWN0ZXJpc3RpY2FzIGRlbCBITU0gZXMgcXVlIGVzIHNpbXBsZSBzZSByZWFsaXphciB5IGRlYmlkbyBhIHN1IHRyYXNmb25kbyBtYXRlbWF0aWNvIHRhbWJpZW4gZXMgYWRlY3VhZG8gcGFyYSB0ZW5lciB1bmEgcmVzcHVlc3RhIGNvbXB1dGFjaW9uYWwgcmFwaWRhLiAKCiMjMS4yIE1vZGVsb3MgZGUgbWV6Y2xhIGluZGVwZW5kaWVudGVzCgoKIyMjMS4yLjEgRGVmaW5pY2lvbiB5IHByb3BpZWRhZGVzCgpDb25zaWRlcmUgbnVldmFtZW50ZSBsYSBzZXJpZSBkZSBjdWVudGFzIGRlIHRlcnJlbW90b3MgaWx1c3RyYWRhIGVuIGxhIEZpZ3VyYSAxLjEuIFVuIG1vZGVsbyBlc3TDoW5kYXIgcGFyYSBjdWVudGFzIGlsaW1pdGFkYXMgZXMgbGEgZGlzdHJpYnVjacOzbiBkZSBQb2lzc29uLCBjb24gc3UgZnVuY2nDs24gZGUgcHJvYmFiaWxpZGFkICQkcCh4KT1lXnstzrt9Ks67XngveCEkJCAgIHkgbGEgcHJvcGllZGFkIHF1ZSBpbmRpY2EgcXVlIGxhIHZhcmlhbnphIGVxdWl2YWxlIGEgbGEgbWVkaWEuIFNpbiBlbWJhcmdvLCBwYXJhIGxhIHNlcmllIGRlIHRlcnJlbW90b3MsIGxhIG11ZXN0cmEgZGUgdmFyaWFuemEsIFwoc14y4omINTJcKSwgZXMgbXVjaG8gbWFzIGdyYW5kZSBxdWUgbGEgbXVlc3RyYSBkZSBsYSBtZWRpYSwgJCRcYmFye3h9IOKJiDE5JCQsIGxvIGN1YWwgaW5kaWNhIHVuYSBmdWVydGUgc29icmUgZGlzcGVyc2nDs24gcmVsYXRpdmEgYSBsYSBkaXN0cmlidWNpw7NuIGRlIFBvaXNzb24uIExhIGZhbHRhIGRlIHNlbWVqYW56YSBlcyBjb25maXJtYWRhIHBvciBsYSBGaWd1cmEgMS4yLCBsYSBjdWFsIGlsdXN0cmEgbGEgZGlzdHJpYnVjacOzbiBkZSBQb2lzc29uIGFqdXN0YWRhIHkgdW4gZGlhZ3JhbWEgZGUgYmFycmFzIGRlIGxhcyBmcmVjdWVuY2lhcyByZWxhdGl2YXMgZGUgbGFzIGN1ZW50YXMuClVuIG3DqXRvZG8gcGFyYSByZXNvbHZlciBvYnNlcnZhY2lvbmVzIHNvYnJlIGRpc3BlcnNhcyBjb24gdW5hIGRpc3RyaWJ1Y2nDs24gYmlub2RvIG8gKG3DoXMgZ2VuZXJhbG1lbnRlKSBkaXN0cmlidWNpw7NuIG11bHRpbW9kbyBlcyB1c2FyIHVuIG1vZGVsbyBkZSBtZXpjbGEuIExvcyBtb2RlbG9zIGRlIG1lemNsYSBzb24gZGlzZcOxYWRvcyBwYXJhIGFjb21vZGFyIGhldGVyb2dlbmVpZGFkIGlub2JzZXJ2YWRhIGVuIGxhIHBvYmxhY2nDs247IGVzbyBlcywgbGEgcG9ibGFjacOzbiBwdWVkZSBjb25zaXN0aXIgZGUgZ3J1cG9zIGlub2JzZXJ2YWRvcywgY2FkYSB1bm8gdGVuaWVuZG8gdW5hIGRpc3RyaWJ1Y2nDs24gZGlzdGludGEgcGFyYSBsYSB2YXJpYWJsZSBvYnNlcnZhZGEuCkNvbnNpZMOpcmVzZSBlbCBlamVtcGxvLCBsYSBkaXN0cmlidWNpw7NuIGRlbCBuw7ptZXJvLCBYLCBkZSBwYXF1ZXRlcyBkZSBjaWdhcnJpbGxvcyBjb21wcmFkb3MgcG9yIGxvcyBjb25zdW1pZG9yZXMgZGUgdW4gc3VwZXJtZXJjYWRvLiBMb3MgY29uc3VtaWRvcmVzIHB1ZWRlbiBzZXIgZGl2aWRpZG9zIGVuIGdydXBvcywgcG9yIGVqZW1wbG8sIG5vIGZ1bWFkb3JlcywgZnVtYWRvcmVzIG9jYXNpb25hbGVzLCB5IGZ1bWFkb3JlcyByZWd1bGFyZXMuIEFob3JhIGF1biBzaSBlbCBudW1lcm8gZGUgcGFxdWV0ZXMgY29tcHJhZG8gcG9yIGxvcyBjb25zdW1pZG9yZXMgZW50cmUgY2FkYSBncnVwbyBmdWVyYSBkaXN0cmlidWlibGUgcG9yIFBvaXNzb24sIGxhIGRpc3RyaWJ1Y2nDs24gWCBubyBzZXJpYSBQb2lzc29uOyBzZXJpYSBzb2JyZSBkaXNwZXJzYSByZWxhdGl2YSBhIFBvaXNzb24sIHkgdGFsdmV6IGF1biBtdWx0aW1vZG8uCkFuw6Fsb2dhbWVudGUsIHN1cMOzbmdhc2UgcXVlIGNhZGEgY3VlbnRhIGVuIGxhIHNlcmllIGRlIHRlcnJlbW90b3MgZXMgZ2VuZXJhZGEgcG9yIHVuYSBkZSBkb3MgZGlzdHJpYnVjaW9uZXMgZGUgUG9pc3NvbiwgY29uIG1lZGlhcyBcKM67XzFcKSB5IFwozrtfMlwpLCBkb25kZSBsYSBlbGVjY2nDs24gZGUgbWVkaWEgZXMgZGV0ZXJtaW5hZGEgcG9yIG90cm9zIG1lY2FuaXNtb3MgYWxlYXRvcmlvcyBxdWUgbGxhbWFyZW1vcyBlbCBwcm9jZXNvIGRlIHBhcsOhbWV0cm8uIFN1cMOzbmdhc2UgdGFtYmnDqW4gcXVlIFwozrtfMVwpIGVzIHNlbGVjY2lvbmFkbyBjb24gcHJvYmFiaWxpZGFkIFwozrRfMVwpIHkgXCjOu18yXCkgY29uIHByb2JhYmlsaWRhZCBcKM60XzI9MS3OtF8xXCkuIFZlcmVtb3MgbWFzIGFkZWxhbnRlIGVuIGVzdGUgY2FwaXR1bG8gcXVlIGxhIHZhcmlhbnphIGRlIGxhIGRpc3RyaWJ1Y2nDs24gcmVzdWx0YW50ZSBleGNlZGUgbGEgbWVkaWEgcG9yIFwozrRfMSDOtF8yICjOu18xLc67XzIgKV4yXCkuIFNpIGVsIHByb2Nlc28gZGUgcGFyw6FtZXRybyBlcyB1bmEgc2VyaWUgZGUgdmFyaWFibGVzIGFsZWF0b3JpYXMgaW5kZXBlbmRpZW50ZXMsIGxhcyBjdWVudGFzIHRhbWJpw6luIHNvbiBpbmRlcGVuZGllbnRlcywgZGUgYWjDrSBlbCB0w6lybWlubyDigJxtZXpjbGEgaW5kZXBlbmRpZW50ZeKAnS4KRW4gZ2VuZXJhbCwgdW5hIGRpc3RyaWJ1Y2nDs24gZGUgbWV6Y2xhIGluZGVwZW5kaWVudGUgY29uc2lzdGUgZGUgdW4gbnVtZXJvIGZpbml0bywgZMOtZ2FzZSBcKG1cKSwgZGUgZGlzdHJpYnVjaW9uZXMgZGUgY29tcG9uZW50ZSB5IHVuYSDigJxkaXN0cmlidWNpw7NuIGRlIG1lemNsYeKAnSBsYSBjdWFsIHNlbGVjY2lvbmEgZGUgZXN0YXMgY29tcG9uZW50ZXMuIExhcyBkaXN0cmlidWNpb25lcyBkZSBjb21wb25lbnRlIHB1ZWRlbiBzZXIgdGFudG8gZGlzY3JldGFzIGNvbW8gY29udGludWFzLiBFbiBlbCBjYXNvIGRlIGRvcyBjb21wb25lbnRlcywgbGEgbWV6Y2xhIGRlIGRpc3RyaWJ1Y2nDs24gZGVwZW5kZSBkZSBkb3MgcHJvYmFiaWxpZGFkZXMgbyBmdW5jaW9uZXMgZGUgZGVuc2lkYWQ6CgokJApDb21wb25lbnRlIFxxcXVhZCBccXF1YWRccXF1YWRccXF1YWRccXF1YWQxIFxxcXVhZFxxcXVhZCAyIFxcClByb2JhYmlsaWRhZCBvIGZ1bmNpw7NuIGRlIGRlbnNpZGFkIFxxcXVhZCBwXzEoeCkgXHFxdWFkIHBfMih4KSAKJCQKCgpQYXJhIGVzcGVjaWZpY2FyIGxhIGNvbXBvbmVudGUsIHVuYSBuZWNlc2l0YSB1bmEgdmFyaWFibGUgYWxlYXRvcmlhIGRpc2NyZXRhIEMgbGEgY3VhbCByZWFsaXphIGxhIG1lemNsYToKCiQkCkM9ClxiZWdpbntjYXNlc30KICAxIFxxdWFkIGNvbiBccXVhZCBwcm9iYWJpbGlkYWQgXHF1YWRcZGVsdGFfMVxcICAgIAogIDIgXHF1YWQgY29uIFxxdWFkIHByb2JhYmlsaWRhZCBccXVhZFxkZWx0YV8yID0gMS1cZGVsdGFfMQpcZW5ke2Nhc2VzfQokJAoKCkxhIGVzdHJ1Y3R1cmEgZGUgZXNlIHByb2Nlc28gcGFyYSBlbCBjYXNvIGRlIGRvcyBkaXN0cmlidWNpb25lcyBkZSBjb21wb25lbnRlcyBjb250aW51YXMgZXMgaWx1c3RyYWRhIGVuIGxhIEZpZ3VyYSAxLjMuIEVuIGVzZSBlamVtcGxvIHVubyBwdWVkZSBwZW5zYXIgZGUgQyBjb21vIGVsIHJlc3VsdGFkbyBkZSBsYW56YXIgdW5hIG1vbmVkYSBjb24gcHJvYmFiaWxpZGFkIDAuNzUgZGUg4oCcY2FyYeKAnTogc2kgZWwgcmVzdWx0YWRvIGVzIOKAnGNhcmHigJ0sIGVudG9uY2VzIEMgPSAxIHkgdW5hIG9ic2VydmFjacOzbiBlcyB0b21hZGEgZGUgcF8xOiBzaSBlcyDigJxjcnV64oCdLCBlbnRvbmNlcyBDID0gMiB5IHVuYSBvYnNlcnZhY2nDs24gZXMgdG9tYWRhIGRlIFwocF8yXCkuIFN1cG9uZW1vcyBxdWUgbm8gc2FiZW1vcyBlbCB2YWxvciBkZSBDLCBlc28gZXMsIGN1YWwgZGUgXChwXzFcKSBvIFwocF8yXCkgZXN0YWJhIGFjdGl2byBjdWFuZG8gbGEgb2JzZXJ2YWNpw7NuIGZ1ZSBnZW5lcmFkYS4KCiFbRmlndXJhIDEuM10oL1VzZXJzL2JyYWNydXovRG9jdW1lbnRzLzh2by4gVHJpbWVzdHJlIElPL1Npc3QuIEV4cGVydG9zIHkgUmVkZXMgUHJvYi4vQ0gxL0ZpZ3VyYTEtMy5wbmcpCgoKTGEgZXh0ZW5zacOzbiBkZSBtIGNvbXBvbmVudGVzIGVzIHNlbmNpbGxhLiBRdWUgXCjOtF8xLOKApizOtF9tXCkgZGVub3RlIGxhcyBwcm9iYWJpbGlkYWRlcyBhc2lnbmFkYXMgYSBsYXMgZGlmZXJlbnRlcyBjb21wb25lbnRlcywgeSBxdWUgXChwXzEs4oCmLHBfbVwpIGRlbm90ZSBzdXMgcHJvYmFiaWxpZGFkZXMgbyBmdW5jaW9uZXMgZGUgZGVuc2lkYWQuIFF1ZSBYIGRlbm90ZSBsYSB2YXJpYWJsZSBhbGVhdG9yaWEgbGEgY3VhbCB0aWVuZSBsYSBkaXN0cmlidWNpw7NuIGRlIG1lemNsYS4gRW4gZWwgY2FzbyBkaXNjcmV0bywgbGEgZnVuY2nDs24gZGUgcHJvYmFiaWxpZGFkIGRlIFggZXMgZGFkYSBwb3I6CgokJApwKHgpID0gXHN1bV97aT0xfV57bX0gUHIoWD14fEM9aSlQcihDPWkpXFwKPVxzdW1fe2k9MX1ee219XGRlbHRhX2lwX2koeCkKJCQKRWwgY2FzbyBjb250aW51byBlcyBhbsOhbG9nby4gTGEgZXhwZWN0YXRpdmEgZGUgbGEgbWV6Y2xhIHB1ZWRlIHNlciBkYWRhIGVuIHTDqXJtaW5vcyBkZSBsYXMgZXhwZWN0YWNpb25lcyBkZSBsYXMgZGlzdHJpYnVjaW9uZXMgZGUgY29tcG9uZW50ZXMuIERlamFuZG8gcXVlIFksIGRlbm90ZSBsYSB2YXJpYWJsZSBhbGVhdG9yaWEgY29uIGZ1bmNpw7NuIGRlIHByb2JhYmlsaWRhZCBcKHBfaVwpLCB0ZW5lbW9zOgoKJCQKRShYKSA9IFxzdW1fe2k9MX1ee219IFByKEM9aSkgRShYfEM9aSkgPSBcc3VtX3tpPTF9XnttfSBcZGVsdGFfaUUoWV9pKQokJAoKRWwgbWlzbW8gcmVzdWx0YWRvIGFndWFyZGEgcGFyYSB1bmEgbWV6Y2xhIGRlIGRpc3RyaWJ1Y2lvbmVzIGNvbnRpbnVhcy4gTWFzIGdlbmVyYWxtZW50ZSwgcGFyYSB1bmEgbWV6Y2xhIGRlbCBrLWVzaW1vIG1vbWVudG8gZGVsIG9yaWdlbiBlcyBzaW1wbGVtZW50ZSB1bmEgY29tYmluYWNpw7NuIGxpbmVhbCBkZSBsb3Mgay1lc2ltb3MgbW9tZW50b3MgZGUgc3VzIGNvbXBvbmVudGVzIFwoWV9pXCk6CgokJApFKFheaykgPSBcc3VtX3tpPTF9XnttfSBcZGVsdGFfaUUoWV9pXmspLCBrPTEsMiwuLi4KJCQKCk7Ds3Rlc2UgcXVlIGVsIHJlc3VsdGFkbyBhbsOhbG9nbyBubyBjdWVudGEgcGFyYSBtb21lbnRvcyBjZW50cmFsZXMuIEVuIHBhcnRpY3VsYXIsIGxhIHZhcmlhbnphIFggbm8gZXMgdW5hIGNvbWJpbmFjacOzbiBsaW5lYXIgZGUgbGFzIHZhcmlhbnphcyBkZSBzdXMgY29tcG9uZW50ZXMgXChZaVwpLiBFbCBFamVyY2ljaW8gMSBsZSBwaWRlIGFsIGxlY3RvciBwcm9iYXIgZXNvLCBlbiBlbCBjYXNvIGRlIGRvcyBjb21wb25lbnRlcywgbGEgdmFyaWFuemEgZGUgbGEgbWV6Y2xhIGVzdMOhIGRhZGEgcG9yOgoKJCQKVmFyKFgpID0gXGRlbHRhXzFWYXIoWV8xKStcZGVsdGFfMlZhcihZXzIpK1xkZWx0YV8xXGRlbHRhXzIoRShZXzEpLUUoWV8yKSleMgokJAoKCiMjIzEuMi4yIEVzdGltYWNpw7NuIGRlIHBhcsOhbWV0cm9zCgpMYSBlc3RpbWFjacOzbiBkZSBwYXLDoW1ldHJvcyBkZSB1bmEgZGlzdHJpYnVjacOzbiBkZSBtZXpjbGFzIGVzIGEgbWVudWRvIHJlYWxpemFkYSBwb3IgdW5hIHByb2JhYmlsaWRhZCBtw6F4aW1hIChNTCkuIExhIHByb2JhYmlsaWRhZCBkZSB1biBtb2RlbG8gZGUgbWV6Y2xhIGNvbiBtIGNvbXBvbmVudGVzIGVzdGEgZGFkYSwgcGFyYSB0YW50byBjYXNvcyBkaXNjcmV0b3MgY29tbyBjb250aW51b3MsIHBvcjoKCiQkCkwoXHRoZXRhXzEsLi4uLFx0aGV0YV9tLFxkZWx0YV8xLC4uLixcZGVsdGFfbXx4XzEsLi4uLHhfbikgPSBccHJvZF97aj0xfV57bn1cc3VtX3tpPTF9XnttfVxkZWx0YV9pcF9pKHhfaixcdGhldGFfaSkKJCQKCkFxdcOtIFwozrhfMSzigKYszrhfbVwpIHNvbiBsb3MgdmVjdG9yZXMgZGUgcGFyYW1ldHJvcyBkZSBsYXMgZGlzdHJpYnVjaW9uZXMgZGUgY29tcG9uZW50ZXMsIFwozrRfMSzigKYszrRfbVwpIHNvbiBsb3MgcGFyYW1ldHJvcyBkZSBtZXpjbGEsIHRvdGFsaXphbmRvIDEsIHkgXCh4XzEs4oCmLHhfblwpIHNvbiBsYXMgbiBvYnNlcnZhY2lvbmVzLiBFbnRvbmNlcywgZW4gZWwgY2FzbyBkZSBkaXN0cmlidWNpb25lcyBkZSBjb21wb25lbnRlcyBjYWRhIHVuYSBlc3BlY2lmaWNhZGEgcG9yIHVuIHBhcsOhbWV0cm8sIFwoMm0tMVwpIHBhcmFtZXRyb3MgaW5kZXBlbmRpZW50ZXMgdGllbmVuIHF1ZSBzZXIgZXN0aW1hZG9zLiBFeGNlcHRvIHRhbHZleiBlbiBjYXNvcyBlc3BlY2lhbGVzLCBtYXhpbWl6YWNpw7NuIGFuYWzDrXRpY2EgZGUgdGFsIHByb2JhYmlsaWRhZCBubyBlcyBwb3NpYmxlLCBwZXJvIGVzIGdlbmVyYWxtZW50ZSBzZW5jaWxsbyBkZSBldmFsdWFybG8gcsOhcGlkYW1lbnRlOyB2ZXIgRWplcmNpY2lvIDMuIE1heGltaXphY2nDs24gbnVtw6lyaWNhIHNlcsOhIGlsdXN0cmFkYSBhcXXDrSBhbCBjb25zaWRlcmFyIGVsIGNhc28gZGUgdW5hIG1lemNsYSBkZSBkaXN0cmlidWNpb25lcyBkZSBQb2lzc29uLiBTdXBvbmdhc2UgcXVlIG09MiB5IGxhcyBkb3MgY29tcG9uZW50ZXMgc29uIGRpc3RyaWJ1aWJsZXMgcG9yIFBvaXNzb24gY29uIG1lZGlhcyBcKM67XzFcKSB5IFwozrtfMlwpLiBRdWUgXCjOtF8xXCkgeSBcKM60XzJcKSBzZWFuIGxvcyBwYXLDoW1ldHJvcyBkZSBtZXpjbGEgKGNvbiBcKM60XzEgKyDOtF8yID0gMVwpLiBMYSBkaXN0cmlidWNpw7NuIGRlIG1lemNsYSBwIGVzdGEgZGFkYSBwb3I6CgokJApwKHgpID0gXGRlbHRhXzEgXGZyYWN7XGxhbWJkYV8xXnhlXnstXGxhbWJkYV8xfX17eCF9K1xkZWx0YV8yIFxmcmFje1xsYW1iZGFfMl54ZV57LVxsYW1iZGFfMn19e3ghfQokJApEZXNkZSBxdWUgXCjOtF8yPTEtzrRfMVwpLCBoYXkgc29sYW1lbnRlIHRyZXMgcGFyw6FtZXRyb3MgYSBlc3RpbWFyOiBcKM67XzFcKSwgXCjOu18yXCkgeSBcKM60XzFcKS4gTGEgcHJvYmFiaWxpZGFkIGVzOgoKJCQKTChcbGFtYmRhXzEsXGxhbWJkYV8yLFxkZWx0YV8xfHhfMSwuLi4seF9uKSA9IFxwcm9kX3tpPTF9Xm4oXGRlbHRhXzFcZnJhY3tcbGFtYmRhXzFee3hfaX1lXnstXGxhbWJkYV8xfX17eF9pIX0rKDEtXGRlbHRhXzEpXGZyYWN7XGxhbWJkYV8yXnt4X2l9ZV57LVxsYW1iZGFfMn19e3hfaSF9KQokJApMYSBtYXhpbWl6YWNpw7NuIGFuYWzDrXRpY2EgZGUgTCBjb24gcmVzcGVjdG8gYSBcKM67XzFcKSwgXCjOu18yXCkgeSBcKM60XzFcKSBzZXJpYSByYXJhLCB5YSBxdWUgTCBlcyBlbCBwcm9kdWN0byBkZSBuIGZhY3RvcmVzLCBkZWwgY3VhbCBjYWRhIHVubyBlcyB1bmEgc3VtYS4gUHJpbWVybyB0b21hciBlbCBsb2dhcml0bW8geSBsdWVnbyBsYSBkaWZlcmVuY2lhY2nDs24gbm8gc2ltcGxpZmljYSBtdWNobyBsYXMgY29zYXMgdGFtcG9jby4gUG9yIGxvIHRhbnRvLCBsYSBlc3RpbWFjacOzbiBkZSBwYXLDoW1ldHJvcyBlcyBtYXMgY29udmVuaWVudGVtZW50ZSBsbGV2YWRhIGEgY2FibyBwb3IgbWF4aW1pemFjacOzbiBudW3DqXJpY2EgZGlyZWN0YSBkZSBsYSBwcm9iYWJpbGlkYWQgKG8gc3UgbG9nYXJpdG1vKSwgYXVucXVlIGVsIGxvZ2FyaXRtbyBFTSBlcyBjb23Dum5tZW50ZSB1c2FkbyBjb21vIGFsdGVybmF0aXZhOyB2w6lhc2UsIHBvciBlamVtcGxvLCBNY0xhY2hsYW4geSBQZWVsICgyMDAwKSBvIEZydWh3aXJ0aC1TY2huYXR0ZXIgKDIwMDYpLiBVbiBwYXF1ZXRlIMO6dGlsIGRlIFIgcGFyYSBlc3RpbWFjacOzbiBlbiBtb2RlbG9zIGRlIG1lemNsYSBlcyBcKGZsZXhtaXhcKSAoTGVpc2NoLCAyMDA0KS4gU2luIGVtYmFyZ28sIGVzIHNlbmNpbGxvIGVzY3JpYmlyIG51ZXN0cm8gcHJvcGlvIGPDs2RpZ28gZGUgUiBwYXJhIGV2YWx1YXIsIHkgbHVlZ28gbWF4aW1pemFyLCBwcm9iYWJpbGlkYWRlcyBkZSBtZXpjbGEgZW4gY2Fzb3Mgc2VuY2lsbG9zLgpFc3RhIHByb2JhYmlsaWRhZCBwdWVkZSBzZXIgbHVlZ28gbWF4aW1pemFkYSBhbCB1c2FyIChwb3IgZWplbXBsbykgbGEgZnVuY2nDs24gZGUgUiBubG0uIFNpbiBlbWJhcmdvLCBsb3MgcGFyw6FtZXRyb3MgXChcZGVsdGFcKSB5IFwoXGxhbWJkYVwpIHNvbiBzdWpldG9zIHBvciAoZWN1YWNpw7NuIHJhcmEpIHkgKHBhcmEgXChpID0gMSwg4oCmLCBtXCkpIFwozrRfaSA+IDBcKSB5IFwozrtfaT4wXCkuIEVzIGVudG9uY2VzIG5lY2VzYXJpbyBSZSBwYXJhbWV0cml6YXIgc2kgdW5vIGFzw60gbG8gZGVzZWEgcGFyYSB1dGlsaXphciB1biBvcHRpbWl6YWRvciBzaW4gcmVzdHJpY2Npb25lcyB0YWwgY29tbyBubG0uIFVuYSBwb3NpYmlsaWRhZCBwYXJhIG1heGltaXphciBsYSBwcm9iYWJpbGlkYWQgY29uIHJlc3BlY3RvIGEgbG9zIDJtLTEg4oCccGFyw6FtZXRyb3MgZnVuY2lvbmFsZXPigJ0gc2luIHJlc3RyaWNjacOzbi4KCiQkClxldGFfaSA9IGxvZ1xsYW1iZGFfaSAoaT0xLC4uLm0pCiQkCnkKCiQkClx0YXVfaSA9IGxvZyhcZnJhY3tcZGVsdGFfaX17MS1cc3VtX3tqPTJ9Xm0gXGRlbHRhX2p9KSAoaT0yLC4uLixtKQokJAoKU2UgcmVjdXBlcmFuIGxvcyDigJxwYXLDoW1ldHJvcyBuYXR1cmFsZXPigJ0gb3JpZ2luYWxlcyBwb3IgbWVkaW8gZGU6CgokJApcbGFtYmRhX2kgPSBlXntcZXRhX2l9IFxxdWFkIChpPTEsLi4uLG0pIFxcClxkZWx0YV9pID0gXGZyYWN7ZV57XHRhdV9pfX17MStcc3VtX3tqPTJ9Xm1lXntcZXRhX2p9fSBccXVhZCAoaT0yLC4uLixtKQokJAoKWSBcKM60XzE9MS1cc3VtX3tqPTJ9Xnttfc60X2lcKSAuIEVsIHNpZ3VpZW50ZSBjw7NkaWdvIGltcGxlbWVudGEgbGFzIGlkZWFzIGFudGVyaW9yZXMgZW4gb3JkZW4gcGFyYSBxdWUgZW5jYWplbiB1biBtb2RlbG8gZGUgY3VhdHJvIGRpc3RyaWJ1Y2lvbmVzIGRlIFBvaXNzb24gYSBsYXMgY3VlbnRhcyBkZSB0ZXJyZW1vdG9zLiBMb3MgcmVzdWx0YWRvcyBlc3TDoW4gZGFkb3MgcG9yIG0gPSAxLDIsMyw0IGVuIGxhIFRhYmxhIDEuMgoKYGBge3IgaW5jbHVkZT1UUlVFLCBlY2hvPVRSVUV9Cm1sbGsgPC0gZnVuY3Rpb24od3Bhcix4KXsgenp6IDwtIHcybih3cGFyKQogICAgICAgIC1zdW0obG9nKG91dGVyKHgsenp6JGxhbWJkYSxkcG9pcyklKiV6enokZGVsdGEpKSB9CgpuMncgIDwtIGZ1bmN0aW9uKGxhbWJkYSxkZWx0YSlsb2coYyhsYW1iZGEsZGVsdGFbLTFdLygxLXN1bShkZWx0YVstMV0pKSkpCgp3Mm4gIDwtIGZ1bmN0aW9uKHdwYXIpe20gPC0gKGxlbmd0aCh3cGFyKSsxKS8yCiAgICAgICAgbGFtYmRhIDwtIGV4cCh3cGFyWzE6bV0pCiAgICAgICAgZGVsdGEgIDwtIGV4cChjKDAsd3BhclsobSsxKTooMiptLTEpXSkpCnJldHVybihsaXN0KGxhbWJkYT1sYW1iZGEsZGVsdGE9ZGVsdGEvc3VtKGRlbHRhKSkpIH0KCnggICAgICAgIDwtIHJlYWQudGFibGUoIi9Vc2Vycy9icmFjcnV6L0RvY3VtZW50cy84dm8uIFRyaW1lc3RyZSBJTy9TaXN0LiBFeHBlcnRvcyB5IFJlZGVzIFByb2IuL2VhcnRocXVha2VzLnR4dCIpWywyXQp3cGFyICAgICA8LSBuMncoYygxMCwyMCwyNSwzMCksYygxLDEsMSwxKS80KQp3Mm4obmxtKG1sbGssd3Bhcix4KSRlc3RpbWF0ZSkKYGBgCgpOb3Rlc2UgY29tbywgZW4gZXN0ZSBjw7NkaWdvLCBlbCB1c28gZGUgbGEgZnVuY2nDs24gb3V0ZXIgaGFjZSBwb3NpYmxlIGVsIGV2YWx1YXIgbGEgcHJvYmFiaWxpZGFkIGRlIG1lemNsYSBkZSBQb2lzc29uIGVuIHVuYSBzaW1wbGUgeSBjb21wYWN0YSBleHByZXNpw7NuIGVuIHZleiBkZSBlbiB1biBjaWNsby4gUGVybyBzaSBsYSBkaXN0cmlidWNpw7NuIHNpZW5kbyBtZXpjbGFkYSBmdWVyYW4gZGlzdHJpYnVjaW9uZXMgY29uIG1hcyBkZSB1biBwYXLDoW1ldHJvIChkw61nYXNlLCBub3JtYWwpLCB1biBlbmZvcXVlIHVuIHBvY28gZGlzdGludG8gc2VyaWEgbmVjZXNhcmlvLgoKTG9zIHJlc3VsdGFkb3MgYW50ZXJpb3JlcyBwdWVkZW4gc2VyIHZlcmlmaWNhZG9zIGVuIGxhIHNpZ3VpZW50ZSB0YWJsYToKCgohW1RhYmxhIDEuMl0oL1VzZXJzL2JyYWNydXovRG9jdW1lbnRzLzh2by4gVHJpbWVzdHJlIElPL1Npc3QuIEV4cGVydG9zIHkgUmVkZXMgUHJvYi4vQ0gxL1RhYmxhMS0yLnBuZykKCgojIyMgMS4yLjMgUHJvYmFiaWxpZGFkIGlsaW1pdGFkYSBlbiBtZXpjbGFzCgpIYXkgdW4gYXNwZWN0byBlbiBtZXpjbGFzIGRlIGRpc3RyaWJ1Y2lvbmVzIGNvbnRpbnVhcyBxdWUgZGlmaWVyZW4gZGVsIGNhc28gZGlzY3JldG8geSB2YWxlIGxhIHBlbmEgcmVzYWx0YXJsby4gRXMgZWwgc2lndWllbnRlOiBwdWVkZSBwYXNhciBxdWU6IGVuIGxhIHZlY2luaWRhZCBkZSBjaWVydGFzIGNvbWJpbmFjaW9uZXMgZGUgcGFyw6FtZXRyb3MsIGxhIHByb2JhYmlsaWRhZCBlcyBpbGltaXRhZGEuIFBvciBlamVtcGxvLCBlbiBlbCBjYXNvIGRlIHVuYSBtZXpjbGEgZGUgZGlzdHJpYnVjaW9uZXMgbm9ybWFsZXMsIGxhIHByb2JhYmlsaWRhZCBzZSB2dWVsdmUgYXJiaXRyYXJpYW1lbnRlIGdyYW5kZSBzaSB1bm8gYXNpZ25hIGxhIG1lZGlhIGNvbXBvbmVudGUgaWd1YWwgYSB1bmEgZGUgbGFzIG9ic2VydmFjaW9uZXMgeSBwZXJtaXRlIHF1ZSBsYSB2YXJpYW56YSBjb3JyZXNwb25kaWVudGUgdGllbmRhIGEgY2Vyby4gRWwgcHJvYmxlbWEgaGEgc2lkbyBhbXBsaWFtZW50ZSBkaXNjdXRpZG8gZW4gbGEgbGl0ZXJhdHVyYSBkZSBtb2RlbG9zIGRlIG1lemNsYSwgeSBoYXkgYXF1ZWxsb3MgcXVlIHN1Z2llcmVuIHF1ZSBzaSBsYSBwcm9iYWJpbGlkYWQgZXMgZW50b25jZXMgaWxpbWl0YWRhLCBsYSBNTCBlc3RpbWEgc2ltcGxlbWVudGUgcXVlIOKAnG5vIGV4aXN0ZeKAnS4KCkxhIGZ1ZW50ZSBkZWwgcHJvYmxlbWEsIHNpbiBlbWJhcmdvLCBlcyBzb2xhbWVudGUgZWwgdXNvIGRlIGRlbnNpZGFkZXMgZW4gdmV6IGRlIHByb2JhYmlsaWRhZGVzIGVuIGxhIHBvc2liaWxpZGFkOyBubyBzdXJnaXLDrWEgc2kgc2UgcmVtcGxhemFyYSBjYWRhIHZhbG9yIGRlIGRlbnNpZGFkIGVuIHVuYSBwb3NpYmlsaWRhZCBwb3IgbGEgcHJvYmFiaWxpZGFkIGRlbCBpbnRlcnZhbG8gY29ycmVzcG9uZGllbnRlIGFsIHZhbG9yIHJlZ2lzdHJhZG8uIChQb3IgZWplbXBsbywgdW5hIG9ic2VydmFjacOzbiByZWdpc3RyYWRhIGNvbW8g4oCcMTIuNOKAnSBlc3RhIGFzb2NpYWRhIGNvbiBlbCBpbnRlcnZhbG8gWzEyLjM1LCAxMi40NV0pLiBFbiBlbCBjb250ZXh0byBkZSBtZXpjbGFzIGluZGVwZW5kaWVudGVzIHNlIHJlbXBsYXphIGxhIGV4cHJlc2nDs246CgokJApccHJvZF97aj0xfV5uXHN1bV97aT0xfV5tXGRlbHRhX2kgcF9pKHhfaixcdGhldGFfaSkKJCQKCmRlIGxhIHBvc2liaWxpZGFkICh2w6lhc2UgZWN1YWNpw7NuIGFudGVyaW9yKSBwb3IgbGEgcG9zaWJpbGlkYWQgZGljcmV0YToKCiQkCkwgPSBccHJvZF97aj0xfV5uXHN1bV97aT0xfV5tXGRlbHRhX2kgXGludF97YV9qfV57Yl9qfSBwX2koeCxcdGhldGFfaSlkeAokJAoKRG9uZGUgZWwgaW50ZXJ2YWxvIFwoKGFfaiwgYl9qKVwpIGNvbnNpc3RlIGRlIGFxdWVsbG9zIHZhbG9yZXMgbG9zIGN1YWxlcywgc2kgc29uIG9ic2VydmFkb3MsIHNlcmlhbiByZWdpc3RyYWRvcyBjb21vIFwoeF9qXCkuIEVzdG8gc2ltcGxlbWVudGUgZXF1aXZhbGUgYSByZWNvbm9jZXIgZXhwbMOtY2l0YW1lbnRlIGxhIG5hdHVyYWxlemEgZGVsIGludGVydmFsbyBkZSB0b2RhcyBsYXMgc3VwdWVzdGFzIG9ic2VydmFjaW9uZXMgY29udGludWFzLiBNYXMgZ2VuZXJhbG1lbnRlLCBsYSBwb3NpYmlsaWRhZCBkaXNjcmV0YSBkZSBvYnNlcnZhY2lvbmVzIGVuIHVuIGNvbmp1bnRvIGRlIHZhcmlhYmxlcyBhbGVhdG9yaWFzIFwoWF8xLCBYXzIs4oCmLCBYX25cKSBlcyBsYSBwcm9iYWJpbGlkYWQgZGUgbGEgZm9ybWEgXChQcihhX2kgPCBYX2kgPCBiX2kgXHF1YWQgcGFyYVxxdWFkIHRvZGEgXHF1YWQgaSlcKS4gVXRpbGl6YXJlbW9zIGVsIHRlcm1pbm8gcG9zaWJpbGlkYWQgY29udGludWEgcGFyYSBsYSBkZW5zaWRhZCBjb25qdW50YSBldmFsdWFkYSBlbiBsYSBvYnNlcnZhY2nDs24uCk90cmEgbWFuZXJhIGRlIGV2aXRhciBlc3RlIHByb2JsZW1hIGVzIGVsIGltcG9uZXIgdW4gbGltaXRlIGluZmVyaW9yIGVuIGxhcyB2YXJpYW56YXMgeSBidXNjYXIgZWwgbWVqb3Igc3VqZXRvIG3DoXhpbW8gbG9jYWwgcGFyYSBlc2UgbMOtbWl0ZS4gUHVlZGUgc3VjZWRlciwgc2luIGVtYmFyZ28sIHF1ZSBzZSBwdWVkZSBzZXIgdGFuIGFmb3J0dW5hZG8gcGFyYSBldml0YXIgbG9zIOKAnHBpY29z4oCdIGRlIHBvc2liaWxpZGFkIGFsIGJ1c2NhciBwb3IgdW4gbcOheGltbyBsb2NhbDsgZW4gZXN0ZSBhc3BlY3RvLCB2YWxvcmVzIGJ1ZW5vcyBkZSBpbmljaW8gcHVlZGVuIGF5dWRhci4gRWwgZmVuw7NtZW5vIGRlIHBvc2liaWxpZGFkZXMgaWxpbWl0YWRhcyBubyBzdXJnZSBwYXJhIG9ic2VydmFjaW9uZXMgZGUgdmFsb3JlcyBkaXNjcmV0b3MgcG9ycXVlIGxhIHBvc2liaWxpZGFkIGVuIGVzZSBjYXNvIGVzIHVuYSBwcm9iYWJpbGlkYWQgeSBwb3IgZW5kZSwgbGltaXRhZGEgYSB2YWxvcmVzIGVudHJlIDAgeSAxLgoKCiMjIzEuMi40LiBFamVtcGxvcyBkZSBtb2RlbG9zIGRlIG1lemNsYSBhanVzdGFkb3MKCiMjIyNNZXpjbGEgZGUgZGlzdHJpYnVjaW9uZXMgZGUgUG9pc3NvbgoKU2kgdW5vIHV0aWxpemEgbmxtIHBhcmEgYWp1c3RhciB1bmEgbWV6Y2xhIGRlIG0gZGlzdHJpYnVjaW9uZXMgZGUgUG9pc3NvbiAobT0xLDIsMyw0KSBhIGxvcyBkYXRvcyBkZWwgdGVycmVtb3RvLCB1bm8gb2J0aWVuZSBsb3MgcmVzdWx0YWRvcyBkZXNwbGVnYWRvcyBlbiBsYSBUYWJsYSAxLjIuIE5vdGVzZSBxdWUgaGF5IHVuYSBjbGFyYSBtZWpvcmEgZW4gbGEgcG9zaWJpbGlkYWQgcmVzdWx0YW50ZSBkZSBsYSBhZGljaW9uIGRlIHVuYSBzZWd1bmRhIGNvbXBvbmVudGUsIHkgbXV5IHBvY2EgbWVqb3JhIGRlIGxhIGFkaWNpb24gZGUgdW5hIGN1YXJ0YSDigJMgYXBhcmVudGVtZW50ZSBpbnN1ZmljaWVudGUgcGFyYSBqdXN0aWZpY2FyIGxvcyBkb3MgcGFyw6FtZXRyb3MgYWRpY2lvbmFsZXMuICBMYSBGaWd1cmEgMS40IHByZXNlbnRhIHVuIGhpc3RvZ3JhbWEgZGUgbGFzIGN1ZW50YXMgb2JzZXJ2YWRhcyB5IGxvcyBjdWF0cm8gbW9kZWxvcyBhanVzdGFkb3MuIEVzIGNsYXJvIHF1ZSBsYXMgbWV6Y2xhcyBlbmNhamFuIGxhcyBvYnNlcnZhY2lvbmVzIG11Y2hvIG1lam9yIGEgY29tbyBsbyBoYWNlIHVuYSBzb2xhIGRpc3RyaWJ1Y2nDs24gZGUgUG9pc3NvbiwgeSB2aXN1YWxtZW50ZSBsb3MgbW9kZWxvcyBkZSB0cmVzIHkgY3VhdHJvIGVzdGFkb3MgcGFyZWNlbiBhZGVjdWFkb3MuIEVsIG1lam9yIGFqdXN0ZSBwYXJhIGxhcyBtZXpjbGFzIGVzIHRhbWJpw6luIGV2aWRlbnRlIGRlIGxhcyB2YXJpYW56YXMgZGUgbG9zIGN1YXRybyBtb2RlbG9zIGNvbW8gZXN0YSBwcmVzZW50YWRhIGVuIGxhIFRhYmxhIDEuMi4gQWwgY29tcHV0YXIgbGFzIG1lZGlhcyB5IHZhcmlhbnphcyBkZSBsb3MgbW9kZWxvcyBoZW1vcyB1c2FkbyBcKEUoWCk9XHN1bV9pzrRfaSDOu19pXCkgeSBcKFZhcihYKT1FKFheMiApLShFKFgpKV4yXCksIGNvbiBcKEUoWF4yICk9XHN1bV9pzrRfaSAozrtfaSvOu19pXjIpXCkuIFBhcmEgY29tcGFyYWNpw7NuIHRhbWJpw6luIGhlbW9zIHVzYWRvIGVsIHBhcXVldGUgZGUgUiBmbGV4bWl4IHBhcmEgYWp1c3RhciBsb3MgY3VhdHJvIG1vZGVsb3MuIExvcyByZXN1bHRhZG9zIGNvcnJlc3BvbmRpZXJvbiBtdWNobyBhIGV4Y2VwY2nDs24gZGUgbGFzbyBkZWwgbW9kZWxvIGRlIGN1YXRybyBjb21wb25lbnRlcywgZG9uZGUgZWwgdmFsb3IgZGUgcG9zaWJpbGlkYWQgbWFzIGdyYW5kZSBxdWUgZW5jb250cmFtb3MgcG9yIGZsZXhtaXggZnVlIDM1Ni43NzU5IHkgbGFzIG1lZGlhcyBkZSBsb3MgY29tcG9uZW50ZXMgZGlmaXJpZXJvbiB1biBwb2NvLgpOb3Rlc2UgdGFtYmnDqW4sIHF1ZSBsYSBkaXNjdXNpw7NuIHN1cGVyaW9yIGlnbm9yYSBsYSBwb3NpYmlsaWRhZCBkZSBkZXBlbmRlbmNpYSBzZXJpYWwgZW4gbG9zIGRhdG9zIGRlbCB0ZXJyZW1vdG8sIHVuIHB1bnRvIGVsIGN1YWwgc2UgcmV0b21hcmEgZW4gZWwgQ2Fww610dWxvIDIuCgohW0ZpZ3VyYSAxLjRdKC9Vc2Vycy9icmFjcnV6L0RvY3VtZW50cy84dm8uIFRyaW1lc3RyZSBJTy9TaXN0LiBFeHBlcnRvcyB5IFJlZGVzIFByb2IuL0NIMS9GaWd1cmExLTQucG5nKQoKIyMxLjMgQ2FkZW5hcyBkZSBNYXJrb3YKQWhvcmEgaW50cm9kdWNpcmVtb3MgbGFzIGNhZGVuYXMgZGUgTWFya292LiBOdWVzdHJvIGFuw6FsaXNpcyBzZSByZXN0cmluZ2UgYSBhcXVlbGxvcyBhc3BlY3RvcyBkZSBjYWRlbmFzIGRlIE1hcmtvdiBkaXNjcmV0YXMgbG9zIGN1YWxlcyBuZWNlc2l0YXJlbW9zLiBBc2ksIHNpbiBlbWJhcmdvIGhhcmVtb3MgcmVmZXJlbmNpYSBhIHByb3BpZWRhZGVzIHRhbGVzIGNvbW8gbGEgaXJyZWR1Y3RpYmlsaWRhZCB5IGFwZXJpb2RpY2lkYWQsIG5vIGxpZGlhcmVtb3MgY29uIGN1ZXN0aW9uZXMgdMOpY25pY2FzLgoxLjMuMSBEZWZpbmljaW9uZXMgeSBlamVtcGxvcwpVbmEgc2VjdWVuY2lhIGRlIHZhcmlhYmxlcyBhbGVhdG9yaWFzIGRpc2NyZXRhcyBcKHtDX3Q6dCDiiIggTn0gXClzZSBkaWNlIHF1ZSBlcyB1bmEgKHRpZW1wbyBkaXNjcmV0bykgQ2FkZW5hIGRlIE1hcmtvdiAoQ00pIHNpLCBwYXJhIHRvZG8gdCDiiIhOLCBzYXRpc2ZhY2UgbGEgcHJvcGllZGFkIGRlIE1hcmtvdjoKCiQkClByKENfe3QrMX0gfCBDX3QsLi4uLENfMSkgPSBQcigoQ197dCsxfXxDX3QpCiQkCkVzbyBlcywgY29uZGljaW9uYW5kbyBhIGxhIGhpc3RvcmlhIGRlbCBwcm9jZXNvIGhhc3RhIGVsIHRpZW1wbyB0IGVzIGVxdWl2YWxlbnRlIGEgY29uZGljaW9uYXIgc29sbyBlbCB2YWxvciBtYXMgcmVjaWVudGUgXChDX3RcKS4gUGFyYSBoYWNlcmxvIG3DoXMgY29tcGFjdG8sIGRlZmluaW1vcyBcKENedFwpIGNvbW8gbGEgaGlzdG9yaWEgXCgoQ18xLENfMizigKYsQ190IClcKSwgZW4gY3VhbCBjYXNvLCBsYSBwcm9waWVkYWQgZGUgTWFya292IHNlIHB1ZWRlIGVzY3JpYmlyIGNvbW86CgokJApQcihDX3t0KzF9IHwgQ157KHQpfSA9IFByKENfe3QrMX0gfCBDX3QpCiQkCkxhIHByb3BpZWRhZCBkZSBNYXJrb3YgcHVlZGUgc2VyIGludGVycHJldGFkYSBjb21vIGxhIHByaW1lcmEgcmVsYWphY2nDs24gZGUgbGEgc3Vwb3NpY2lvbiBkZSBpbmRlcGVuZGVuY2lhLiBMYXMgdmFyaWFibGVzIGFsZWF0b3JpYXMgXCh7Q190fVwpIHNvbiBkZXBlbmRpZW50ZXMgZGUgdW5hIG1hbmVyYSBxdWUgZXMgbWF0ZW3DoXRpY2FtZW50ZSBjb252ZW5pZW50ZSwgY29tbyBlcyBtb3N0cmFkbyBlbiBlbCBzaWd1aWVudGUgZ3JhZmljbyBlbiBlbCBjdWFsIGVsIHBhc2FkbyB5IGVsIGZ1dHVybyBzb24gZGVwZW5kaWVudGVzIHNvbG8gYSB0cmF2w6lzIGRlbCBwcmVzZW50ZS4KCiFbXSgvVXNlcnMvYnJhY3J1ei9Eb2N1bWVudHMvOHZvLiBUcmltZXN0cmUgSU8vU2lzdC4gRXhwZXJ0b3MgeSBSZWRlcyBQcm9iLi9DSDEvR3JhZmljYTEucG5nKQoKCkNhbnRpZGFkZXMgaW1wb3J0YW50ZXMgYXNvY2lhZGFzIGNvbiB1bmEgY2FkZW5hIGRlIE1hcmtvdiBzb24gbGFzIHByb2JhYmlsaWRhZGVzIGNvbmRpdGlvbmFsZXMsIHRhbWJpw6luIGxsYW1hZGFzIHByb2JhYmlsaWRhZGVzIGRlIHRyYW5zaWNpw7NuOgoKJCQKUHIoQ197cyt0fT1qIHwgQ19zID0gaSkKJCQKU2kgZXN0YXMgcHJvYmFiaWxpZGFkZXMgbm8gZGVwZW5kZW4gZGUgcywgbGEgY2FkZW5hIGRlIE1hcmtvdiBlcyBsbGFtYWRhIGhvbW9nw6luZWEsIGRlIG90cmEgbWFuZXJhIHNlcmlhIG5vLWhvbW9nZW5lYS4gQSBubyBzZXIgcXVlIGhheWEgdW5hIGluZGljYWNpw7NuIGV4cGxpY2l0YSBhbCBjb250cmFyaW8sIGFzdW1pcmVtb3MgcXVlIGxhIGNhZGVuYSBkZSBNYXJrb3YgZW4gZGlzY3VzacOzbiBlcyBob21vZ8OpbmVhLCBlbiBjdWFsIGNhc28gbGFzIHByb2JhYmlsaWRhZGVzIGRlIHRyYW5zaWNpw7NuIHNlcsOhbiBkZW5vdGFkYXMgcG9yOgoKJCQKXGdhbW1hX3tpan0odCk9IFByKENfe3MrdH18Q19zPWkpCiQkCk5vdGVzZSBxdWUgbGEgbm90YWNpw7NuIFwozrNfe2lqfSAodClcKSBubyBpbnZvbHVjcmEgYSBzLiBMYSBtYXRyaXogXCjOkyh0KVwpICBlc3RhIGRlZmluaWRhIGNvbW8gbGEgbWF0cml6IGNvbiBlbGVtZW50b3MgXCjOs197aWp9ICh0KVwpLgoKVW5hIGltcG9ydGFudGUgcHJvcGllZGFkIGRlIHRvZGFzIGxhcyBjYWRlbmFzIGRlIE1hcmtvdiBob21vZ8OpbmVhcyB5IGRlIGVzdGFkbyB5IGVzcGFjaW8gZmluaXRvIGVzIGxhIHF1ZSBzYXRpc2ZhY2UgbGFzIGVjdWFjaW9uZXMgQ2hhcG1hbi1Lb2xtb2dvcm92OgoKJCQKXEdhbW1hKHQrdSkgPSBcR2FtbWEodCkgXEdhbW1hKHUpCiQkCkxhIHNvbHVjacOzbiByZXF1aWVyZSBzb2xhbWVudGUgbGEgZGVmaW5pY2nDs24gZGUgcHJvYmFiaWxpZGFkIGNvbmRpY2lvbmFsIHkgbGEgYXBsaWNhY2nDs24gZGUgbGEgcHJvcGllZGFkIGRlIE1hcmtvdi4gTGFzIGVjdWFjacOzbmVzIENoYXBtYW4tS29sbW9nb3JvdiBpbXBsaWNhbiBxdWUsIHBhcmEgdG9kbyBcKHQg4oiITlwpOgoKJCRcR2FtbWEodCk9XEdhbW1hKDEpXnQkJApFc3RvIGVzLCBsYSBtYXRyaXogZGUgcHJvYmFiaWxpZGFkZXMgZGUgdHJhbnNpY2nDs24gY29uIHBhc28tdCBlcyBsYSB0LWVzaW1hIHBvdGVuY2lhIGRlIFwozpMoMSlcKSwgbGEgbWF0cml6IGRlIHByb2JhYmlsaWRhZGVzIGRlIHRyYW5zaWNpw7NuIGRlIHVuIHBhc28uIExhIG1hdHJpeiBcKM6TKDEpXCksIGxhIGN1YWwgc2Vyw6EgYWJyZXZpYWRhIGNvbW8gXCjOk1wpLCBlcyB1bmEgbWF0cml6IGN1YWRyYWRhIGRlIHByb2JhYmlsaWRhZGVzIGNvbiBsYSBzdW1hIGRlIHN1cyBmaWxhcyBpZ3VhbCBhIDE6CgohW10oL1VzZXJzL2JyYWNydXovRG9jdW1lbnRzLzh2by4gVHJpbWVzdHJlIElPL1Npc3QuIEV4cGVydG9zIHkgUmVkZXMgUHJvYi4vQ0gxL01hdHJpejEucG5nKQokJApccXVhZAokJApEb25kZSBtIGRlbm90YSBlbCBudW1lcm8gZGUgZXN0YWRvcyBkZSBsYSBjYWRlbmEgZGUgTWFya292LiBMYSBkZWNsYXJhY2nDs24gZGUgcXVlIGxhIHN1bWEgZGUgbGFzIGZpbGFzIGVzIGlndWFsIGEgMSBwdWVkZSBzZXIgZXNjcml0byBjb21vIFwozpMxJz0xJ1wpOyBlc28gZXMsIGVsIHZlY3RvciBjb2x1bW5hIFwoMeKAmVwpIGVzIHVuIGVpZ2VudmVjdG9yIGRlcmVjaG8gZGUgXCjOk1wpIHkgY29ycmVzcG9uZGUgYWwgZWlnZW52YWxvciAxLiBOb3MgcmVmZXJpcmVtb3MgYSBcKM6TXCkgY29tbyBsYSBtYXRyaXogZGUgdHJhbnNpY2nDs24gZGUgcHJvYmFiaWxpZGFkICh0LnAubSkuIE11Y2hvcyBhdXRvcmVzIHV0aWxpemFuIGVuIHZleiBkZWwgdGVybWlubyDigJxtYXRyaXogZGUgdHJhbnNpY2nDs27igJ07IGV2aXRhcmVtb3MgZXN0ZSB0ZXJtaW5vIGRlYmlkbyBhIHBvc2libGVzIGNvbmZ1c2lvbmVzIGNvbiBjdWVudGFzIGRlIG1hdHJpeiBkZSB0cmFuc2ljacOzbiwgbyBpbnRlbnNpZGFkZXMgZGUgdW5hIG1hdHJpeiBkZSB0cmFuc2ljacOzbi4KCkxhcyBwcm9iYWJpbGlkYWRlcyBpbmNvbmRpY2lvbmFsZXMgXChQcmEoQ190PWopXCkgZGUgdW5hIGNhZGVuYSBkZSBNYXJrb3Ygc2llbmRvIGVuIHVuIGVzdGFkbyBkYWRvIGVuIHVuIHRpZW1wbyBkYWRvIHQgc29uIGEgbWVudWRvIGRlIGludGVyw6lzLiBEZW5vdGFtb3MgZXN0b3MgcG9yIGVsIHZlY3RvciBmaWxhOgoKJCR1KHQpID0gKFByKENfdD0xKSwuLi4sUHIoQ190PW0pKSwgdOKIiE4kJAoKTm9zIHJlZmVyaW1vcyBhIHUoMSkgY29tbyBsYSBkaXN0cmlidWNpw7NuIGluaWNpYWwgZGUgdW5hIGNhZGVuYSBkZSBNYXJrb3YgUGFyYSBkZWR1Y2lyIGxhIGRpc3RyaWJ1Y2nDs24gZW4gZWwgdGllbXBvIHQrMSBkZXNkZSBlbCBjdWFsIGVuIHQgcG9zdCBtdWx0aXBsaWNhbW9zIHBvciBsYSBtYXRyaXogZGUgdHJhbnNpY2nDs24gZGUgcHJvYmFiaWxpZGFkIFwozpNcKToKCiQkdSh0KzEpPXUodClcR2FtbWEgJCQKRWplbXBsby4gSW1hZ2luZXNlIHF1ZSBsYSBkZWNsYXJhY2nDs24gZGUgZMOtYXMgc29sZWFkb3MgeSBsbHV2aW9zb3MgZXMgdGFsIHF1ZSBlbCBjbGltYSBkZWwgZGlhIGRlcGVuZGUgc29sYW1lbnRlIGVuIGVsIGRlbCBkaWEgYW50ZXJpb3IsIHkgbGFzIHByb2JhYmlsaWRhZGVzIGRlIHRyYW5zaWNpw7NuIGVzdMOhbiBkYWRhcyBwb3IgbGEgc2lndWllbnRlIHRhYmxhOgoKIVtdKC9Vc2Vycy9icmFjcnV6L0RvY3VtZW50cy84dm8uIFRyaW1lc3RyZSBJTy9TaXN0LiBFeHBlcnRvcyB5IFJlZGVzIFByb2IuL0NIMS9FamVtcGxvMVRhYmxhLnBuZykKJCQKXHF1YWQKJCQKCkVzdG8gZXMsIHNpIGhveSBmdWUgdW4gZGlhIGxsdXZpb3NvLCBsYSBwcm9iYWJpbGlkYWQgcXVlIG1hw7FhbmEgc2VhIGxsdXZpb3NvIGVzIGRlIDAuOTsgc2kgaG95IGVzdHV2byBzb2xlYWRvLCBsYSBwcm9iYWJpbGlkYWQgZGUgZXMgMC42LiBFbCBjbGltYSBlcyBlbnRvbmNlcyB1bmEgY2FkZW5hIGRlIE1hcmtvdiBob21vZ8OpbmVhIGRlIGRvcyBlc3RhZG9zLCBjb24gdC5wLm0uIFwozpNcKSBkYWRvIHBvcgoKJCQKXEdhbW1hID0gCjAuOSAgXHF1YWQgMC4xXFwKXHFxdWFkMC42ICBccXVhZCAwLjQgCiQkCgpBaG9yYSBzdXBvbmdhIHF1ZSBob3kgKHRpZW1wbyAxKSBlcyB1biBkaWEgc29sZWFkby4gRXN0byBzaWduaWZpY2EgcXVlIGxhIGRpc3RyaWJ1Y2nDs24gZGVsIGNsaW1hIGRlbCBkaWEgZGUgaG95IGVzOgoKJCR1KDEpID0gKFByKENfMSA9IDEpLFByKENfMSA9IDIpKSA9ICgwLDEpJCQKCkxhIGRpc3RyaWJ1Y2nDs24gZGVsIGNsaW1hIGRlIG1hw7FhbmEsIGRlbCBwYXNhZG8gbWHDsWFuYSwgeSBhc2ksIHB1ZWRlIHNlciBjYWxjdWxhZGEgcG9zdCBtdWx0aXBsaWNhbmRvIHJlcGV0aWRhbWVudGUgXCh1KDEpXCkgcG9yICAKXCjOk1wpLCBlbCB0LnAubToKCiQkCnUoMikgPSAoUHIoQ18yID0gMSksUHIoQ18yID0gMikpID0gdSgxKVxHYW1tYSA9ICgwLjYsMC40KVxcCnUoMykgPSAoUHIoQ18zID0gMSksUHIoQ18zID0gMikpID0gdSgyKVxHYW1tYSA9ICgwLjc4LDAuMjIpCiQkCgojIyMxLjMuMi4gRGlzdHJpYnVjaW9uZXMgZXN0YWNpb25hcmlhcwoKVW5hIGNhZGVuYSBkZSBNYXJrb3YgY29uIG1hdHJpeiBkZSB0cmFuc2ljacOzbiBkZSBwcm9iYWJpbGlkYWQgzpMgc2UgZGljZSBxdWUgdGllbmUgdW5hIGRpc3RyaWJ1Y2nDs24gZXN0YWNpb25hcmlhIM60ICh1biB2ZWN0b3IgZmlsYSBjb24gZWxlbWVudG9zIG5vIG5lZ2F0aXZvcykgc2kgzrTOkz3OtCB5IM60MeKAmSA9IDEuIEVsIHByaW1lcm8gZGUgZXN0b3MgcmVxdWVyaW1pZW50b3MgZXhwcmVzYSBsYSBlc3RhY2lvbmFyaWVkYWQsIGxhIHNlZ3VuZGEgZXMgZWwgcmVxdWVyaW1pZW50byBxdWUgzrQgZXMgdW5hIGRpc3RyaWJ1Y2nDs24gZGUgcHJvYmFiaWxpZGFkLiBQb3IgZWplbXBsbywgbGEgY2FkZW5hIGRlIE1hcmtvdiBjb24gdC5wLm0gZGFkbyBwb3IKCiQkClxHYW1tYSA9IDEvMyB8IFxxdWFkIDEvM3wgXHF1YWQgMS8zXFwKXHF1YWQgMi8zfCBccXVhZCAwfCBccXVhZCAxLzMgXFwKXHF1YWQgMS8yfCBccXVhZCAxLzJ8IFxxdWFkIDAKJCQKVGllbmUgdW5hIGRpc3RyaWJ1Y2nDs24gZXN0YWNpb25hcmlhIFwozrQ9MS8zMiAoMTUsOSw4KVwpLgoKRGVzZGUgcXVlIFwodSh0KzEpID0gdSh0Kc6TXCksIHVuYSBjYWRlbmEgZGUgTWFya292IGluaWNpYWRhIGRlc2RlIHN1IGRpc3RyaWJ1Y2nDs24gZXN0YWNpb25hcmlhIGNvbnRpbnVhcmEgdGVuaWVuZG8gZXNhIGRpc3RyaWJ1Y2nDs24gZW4gdG9kb3MgbG8gcHVudG9zIGRlIHRpZW1wbyBzdWJzZWN1ZW50ZSwgeSBub3MgcmVmZXJpcmVtb3MgYSB0YWwgcHJvY2VzbyBjb21vIHVuYSBjYWRlbmEgZGUgTWFya292IGVzdGFjaW9uYXJpYS4gRXMgdGFsdmV6IHZhbGlvc28gcmVzYWx0YXIgcXVlIGVzdG8gYXN1bWUgbWFzIHF1ZSBzb2xhbWVudGUgaG9tb2dlbmVpZGFkLiBTb2xvIGxhIGhvbW9nZW5laWRhZCBubyBzZXJpYSBzdWZpY2llbnRlIHBhcmEgdm9sdmVyIGxhIGNhZGVuYSBkZSBNYXJrb3YgdW4gcHJvY2VzbyBlc3RhY2lvbmFyaW8sIHkgcHJlZmVyaW1vcyByZXNlcnZhciBlbCBhZGpldGl2byDigJxlc3RhY2lvbmFyaW/igJ0gcGFyYSBjYWRlbmFzIGRlIE1hcmtvdiBlc3RhY2lvbmFyaWFzIHF1ZSB0aWVuZW4gbGEgcHJvcGllZGFkIGFkaWNpb25hbCBxdWUgbGEgZGlzdHJpYnVjacOzbiBpbmljaWFsIFwodSgxKVwpIGVzIGxhIGRpc3RyaWJ1Y2nDs24gZXN0YWNpb25hcmlhIHkgcG9yIGVuZGUgcHJvY2Vzb3MgZXN0YWNpb25hcmlvcy4gCgpVbmEgY2FkZW5hIGRlIE1hcmtvdiBpcnJlZHVjaWJsZSAoaG9tb2fDqW5lYSwgdGllbXBvIGRpc2NyZXRvLCBlc3RhZG8tZXNwYWNpbyBmaW5pdG8pIHRpZW5lIHVuYSBkaXN0cmlidWNpw7NuIGVzdGFjaW9uYXJpYSwgw7puaWNhIHkgZXN0cmljdGFtZW50ZSBwb3NpdGl2YS4gTsOzdGVzZSBzaW4gZW1iYXJnbyBsYSBzdXBvc2ljacOzbiBkZSBpcnJlZHVjdGliaWxpZGFkIGVzIG5lY2VzYXJpYSBwYXJhIGVzdGEgY29uY2x1c2nDs24sIGxhIGFwZXJpb2RpY2lkYWQgbm8uClNpLCBzaW4gZW1iYXJnbywgdW5vIGHDsWFkZSBsYSBzdXBvc2ljacOzbiBkZSBhcGVyaW9kaWNpZGFkLCB1bmEgw7puaWNhIGRpc3RyaWJ1Y2nDs24gbGltaXRhbnRlIGV4aXN0ZSwgeSBlcyBwcmVjaXNhbWVudGUgbGEgZGlzdHJpYnVjacOzbiBlc3RhY2lvbmFyaWEuIERlc2RlIHF1ZSBzaWVtcHJlIGRlYmVtb3MgYXN1bWlyIGFwZXJpb2RpY2lkYWQgZSBpcnJlZHVjdGliaWxpZGFkLCBsb3MgdMOpcm1pbm9zIOKAnGRpc3RyaWJ1Y2nDs24gbGltaXRhbnRl4oCdIHkg4oCcZGlzdHJpYnVjacOzbiBlc3RhY2lvbmFyaWHigJ0gc29uIHNpbsOzbmltb3MgcGFyYSBudWVzdHJvcyBwcm9ww7NzaXRvcy4KClVuIHJlc3VsdGFkbyBnZW5lcmFsIHF1ZSBwdWVkZSBzZXIgY29udmVuaWVudGVtZW50ZSB1c2FkbyBwYXJhIGNvbXB1dGFyIHVuYSBkaXN0cmlidWNpw7NuIGVzdGFjaW9uYXJpYS4gRWwgdmVjdG9yIFwozrRcKSBjb24gZWxlbWVudG9zIG5vIG5lZ2F0aXZvcyBlcyB1bmEgZGlzdHJpYnVjacOzbiBlc3RhY2lvbmFyaWEgZGUgbGEgY2FkZW5hIGRlIE1hcmtvdiBjb24gdC5wLm0gzpMgc2kgeSBzb2xvIHNpOgoKJCRcZGVsdGEoSV9tIC0gXEdhbW1hICsgVSkgPSAxJCQKCkRvbmRlIDEgZXMgdW4gdmVjdG9yIGZpbGEgZGUgdW5vcywgXChJX21cKSBlcyBsYSBtYXRyaXogaWRlbnRpZGFkIG0geCBtLCB5IFUgZXMgbGEgbWF0cml6IG0geCBtIGRlIHVub3MuIEFsdGVybmF0aXZhbWVudGUsIHVuYSBkaXN0cmlidWNpw7NuIGVzdGFjaW9uYXJpYSBwdWVkZSBzZXIgZW5jb250cmFkYSBhbCBib3JyYXIgdW5hIGRlIGxhcyBlY3VhY2lvbmVzIGVuIGVsIHNpc3RlbWEgXCjOtM6TPc60XCkgeSByZWVtcGxhesOhbmRvbGEgcG9yIFwoXHN1bV9pzrRfaT0xXCkuCgojIyMxLjMuMyBGdW5jacOzbiBkZSBhdXRvY29ycmVsYWNpw7NuCgpUZW5kcmVtb3MgdW5hIG9wb3J0dW5pZGFkLCBwb3IgZWplbXBsbyBlbiBsYSBTZWNjaW9uIDIuMi4zIHkgZW4gZWwgRWplcmNpY2lvIDQoZikgZW4gZWwgQ2FwaXR1bG8gMiwgcGFyYSBjb21wYXJhciBsYXMgZnVuY2lvbmVzIGRlIGF1dG9jb3JyZWxhY2nDs24gKEFDRikgZGUgdW5vIG1vZGVsbyBvY3VsdG8gZGUgTWFya292IGNvbiBzdSBjYWRlbmEgZGUgTWFya292IHN1YnlhY2VudGUgXCh7Q190fVwpLCBlbiBsb3MgZXN0YWRvcyBcKDEsIDIsIOKApiwgbVwpLiBBc3VtaXJlbW9zIHF1ZSBlc3RvcyBlc3RhZG9zIHNvbiBjdWFudGl0YXRpdm9zIHkgbm8gc29sYW1lbnRlIGNhdGVnw7NyaWNvcy4gTGEgQUNGIGRlIFwoe0NfdH1cKSwgYXN1bWlkYSBlc3RhY2lvbmFyaWEgZSBpcnJlZHVjaWJsZSwgcHVlZGUgc2VyIG9idGVuaWRhIGRlIGxhIHNpZ3VpZW50ZSBtYW5lcmEuClByaW1lcm8sIGRlZmluaWVuZG8gXCh2ID0gKDEsIDIsIOKApiwgbSlcKSB5IFwoViA9IGRpYWcoMSwgMiwg4oCmLCBtKVwpLCB0ZW5lbW9zLCBwYXJhIHRvZG9zIGxvcyBlbnRlcm9zIGsgbm8gbmVnYXRpdm9zLAokJApDb3YoQ190LENfe3Qra30pID0gXGRlbHRhIFZcR2FtbWFea3YnIC0gKFxkZWx0YSB2JyleMgokJApTZWd1bmRvLCBzaSDOkyBlcyBkaWFnb25pemFibGUsIHkgc3VzIGVpZ2VudmFsb3JlcyAob3RybyBkZSAxKSBzb24gZGVub3RhZG9zIHBvciB3XzIsIHdfMywg4oCmLCB3X20sIGVudG9uY2VzIM6TIHB1ZWRlIHNlciBlc2NyaXRvIGNvbW86CgokJFxHYW1tYSA9IFUgXE9tZWdhIFVeey0xfSAgJCQKRG9uZGUgXCjOqVwpIGVzIFwoZGlhZygxLCB3XzIsIHdfMywg4oCmLCB3X20pXCkgeSBsYXMgY29sdW1uYXMgZGUgVSBzb24gZWlnZW52ZWN0b3JlcyBkZXJlY2hvcyBjb3JyZXNwb25kaWVudGVzIGRlIFwozpNcKS4gRW50b25jZXMgdGVuZW1vcywgcGFyYSBlbnRlcm9zIG5vIG5lZ2F0aXZvcyBrLAoKJCQKQ292KENfdCxDX3t0K2t9KSA9IFxkZWx0YSBWIFUgXE9tZWdhXmsgVV57LTF9IHYnIC0gKFxkZWx0YSB2JyleMiBcXAo9IGFcT21lZ2FeayBiJyAtIGFfMWJfMSBcXAo9XHN1bV97aT0yfV5tIGFfaWJfaXdfaV5rCiQkCmRvbmRlIGEgPSBcKFxkZWx0YSBWVVwpIHkgYicgPSBcKFVeey0xfVwpLiBQb3IgbG8gdGFudG8gXChWYXIoQ190ICk9XHN1bV97aT0yfV5tIGFfaSBiX2lcKSB5LCBwYXJhIGVudGVyb3Mgbm8gbmVnYXRpdm9zIGs6CgokJApccmhvKGspID0gQ29ycihDX3QsQ197dCtrfSkgPSBcc3VtX3tpPTJ9Xm0gYV9pYl9pd19pXmsgLyBcc3VtX3tpPTJ9Xm0gYV9pYl9pCiQkCgpFc3RvIGVzIHVuIHBlc28gcHJvbWVkaW8gZGUgbGFzIGstZXNpbWFzIHBvdGVuY2lhcyBkZSBsb3MgZWlnZW52YWxvcmVzIFwod18yLCB3XzMsIOKApiwgd19tXCksIHkgZGUgYWxndW5hIG1hbmVyYSBzaW1pbGFyZXMgYSBsYSBBQ0YgZGUgdW4gcHJvY2VzbyBhdXRvIHJlZ3Jlc2l2byBHYXVzc2lhbm8gZGUgb3JkZW4gbS0xLiBOw7N0ZXNlIHF1ZSBsYSBlY3VhY2nDs24gYW50ZXJpb3IgaW1wbGljYSBlbiBlbCBjYXNvIG09MiBxdWUgXCjPgShrKT3PgSgxKV5rXCkgcGFyYSB0b2RvcyBsb3MgZW50ZXJvcyBubyBuZWdhdGl2b3MgaywgeSBxdWUgXCjPgSgxKVwpIGVzIGVsIGVpZ2VudmFsb3IgZGlzdGludG8gYSAxIGRlIFwozpNcKS4KCiMjIzEuMy40LiBFc3RpbWFuZG8gcHJvYmFiaWxpZGFkZXMgZGUgdHJhbnNpY2nDs24KClNpIG5vcyBkYW4gdW5hIHJlYWxpemFjacOzbiBkZSB1bmEgY2FkZW5hIGRlIE1hcmtvdiwgeSBkZXNlYW1vcyBlc3RpbWFyIGxhcyBwcm9iYWJpbGlkYWRlcyBkZSB0cmFuc2ljacOzbiwgdW4gZW5mb3F1ZSDigJMgcGVybyBubyBzb2xvIGVsIMO6bmljbyDigJMgZXMgZWwgZW5jb250cmFyIGxhcyBjdWVudGFzIGRlIHRyYW5zaWNpw7NuIHkgZXN0aW1hciBsYXMgcHJvYmFiaWxpZGFkZXMgZGUgdHJhbnNpY2nDs24gY29tbyBmcmVjdWVuY2lhcyByZWxhdGl2YXMuIFBvciBlamVtcGxvLCBzaSBsYSBDTSB0aWVuZSB0cmVzIGVzdGFkb3MgeSBsYSBzZWN1ZW5jaWEgb2JzZXJ2YWRhIGVzOgoKXCgKMjMzMjExMTExMiAzMTMyMzMyMTIyIDMyMzIzMzIyMjIgMzEzMjMzMjIxMiAzMjMyMTMyMjMyIDMxMzIzMzIyMjMgMzIzMjMzMTIzMiAzMjMyMzMxMjIyIDMyMzIxMzIxMjMgMzEzMjMzMjEyMQpcKQoKRW50b25jZXMgbGEgbWF0cml6IGRlIGN1ZW50YXMgZGUgdHJhbnNpY2nDs24gZXM6CgokJAooZl97aWp9KSA9IDQgXHF1YWQgNyBccXVhZCA2IFxcClxxcXVhZFxxcXVhZDggXHF1YWQgMTAgXHF1YWQgMjQgXFwKXHFxdWFkXHFxdWFkIDYgXHF1YWQgMjQgXHF1YWQgMTAKJCQKCkRvbmRlIFwoZl9palwpIGRlbm90YSBlbCBudW1lcm8gZGUgdHJhbnNpY2lvbmVzIG9ic2VydmFkYXMgZGVsIGVzdGFkbyBpIGFsIGVzdGFkbyBqLiBEZXNkZSBxdWUgZWwgbnVtZXJvIGRlIHRyYW5zaWNpb25lcyBkZWwgZXN0YWRvIDIgYWwgZXN0YWRvIDMgZXMgMjQsIHkgZWwgbnVtZXJvIHRvdGFsIGRlIHRyYW5zaWNpb25lcyBkZWwgZXN0YWRvIDIgZXMgOCsxMCsyNCwgdW4gZXN0aW1hZG8gZGUgZnJlY3VlbmNpYSByZWxhdGl2YSBkZSBcKM6zXzIzXCkgZXMgMjQvNDIuIEVsIHQucC5tIFwozpNcKSBlcyBlbnRvbmNlcyBlc3RpbWFkbyBwb3I6CgokJAooZl97aWp9KSA9IDQvMTcgXHF1YWQgNy8xNyBccXVhZCA2LzE3IFxcClxxcXVhZFxxcXVhZDgvNDIgXHF1YWQgMTAvNDIgXHF1YWQgMjQvNDIgXFwKXHFxdWFkXHFxdWFkIDYvNDAgXHF1YWQgMjQvNDAgXHF1YWQgMTAvNDAKJCQKCkFob3JhIG1vc3RyYXJlbW9zIHF1ZSBlc3RvIGVzIGRlIGhlY2hvIGVsIGVzdGltYWRvIGNvbmRpY2lvbmFsIE1MIGRlIFwozpNcKSwgY29uZGljaW9uYWRhIGVuIGxhIHByaW1lcmEgb2JzZXJ2YWNpw7NuLgpTdXBvbmdhbW9zIGVudG9uY2VzIHF1ZSBkZXNlYW1vcyBlc3RpbWFyIGxvcyBcKG1eMi1tXCkgcGFyw6FtZXRyb3MgXCjOs197aWp9IChp4omgailcKSBkZSB1bmEgY2FkZW5hIGUgTWFya292IGRlIGVzdGFkbyBtIFwoe0NfdH1cKSBkZSB1bmEgcmVhbGl6YWNpw7NuIGNfMSwgY18yLCDigKYsIGNfVC4gTGEgcG9zaWJpbGlkYWQgY29uZGljaW9uYWRhIGVuIGxhIHByaW1lcmEgb2JzZXJ2YWNpw7NuIGVzOgoKJCQKTCA9IFxwcm9kX3tpPTF9Xm1ccHJvZF97aj0xfV5tIFxnYW1tYV97aWp9XntmX3tpan19CiQkCkVsIHJlZ2lzdHJvIGRlIHByb2JhYmlsaWRhZCBlcyBlbnRvbmNlczoKCiQkCmwgPSBcc3VtX3tpPTF9Xm0oXHN1bV97aj0xfV5tIGZfe2lqfSBsb2cgXGdhbW1hX3tpan0pID0gXHN1bV97aT0xfV5tIGxfaSgpCiQkCgpZIHBvZGVtb3MgbWF4aW1pemFyIGwgYWwgbWF4aW1pemFyIGNhZGEgXChsX2lcKSBwb3Igc2VwYXJhZG8uIFN1c3RpdHV5ZW5kbyBcKDEtXHN1bV97KGviiaBpKX3Os197aWt9XCkgICBwYXJhIFwozrNfaWlcKSBkaWZlcmVuY2lhbmRvIFwobF9pXCkgY29uIHJlc3BlY3RvIGEgdW5hIHBvc2liaWxpZGFkIGRlIHRyYW5zaWNpw7NuIGZ1ZXJhIGRlIGxhIGRpYWdvbmFsIFwozrNfaWpcKSBlIGlndWFsYW5kbyBsYSBkZXJpdmFkYSBhIGNlcm8gcmVuZGltaWVudG9zCgokJAowID0gXGZyYWN7LWZfe2lpfX17MS1cc3VtX3tr4omgaX1cZ2FtbWFfe2lrfSArXGZyYWN7Zl97aWp9fXtcZ2FtbWFfe2lqfX0gPSAgLVxmcmFje2Zfe2lpfX17XGdhbW1hX3tpaX19K1xmcmFje2Zfe2lqfX17XGdhbW1hX3tpan19fQokJAoKRW50b25jZXMsIGEgbWVub3MgcXVlIHVuIGRlbm9taW5hZG9yIHNlYSBjZXJvIGVuIGxhIGVjdWFjacOzbiBzdXBlcmlvcixcKCBmX3tpan0gzrNfe2lpfT1mX3tpaX0gzrNfe2lqfSBcKXkgZW50b25jZXMgXCjOs197aWl9IFxzdW1feyhqPTEpfV5tZl97aWp9PWZfe2lpfVwpLiBFc3RvIGltcGxpY2EgcXVlLCBlbiB1biBtw6F4aW1vIGRlIGxhIHBvc2liaWxpZGFkLAoKJCQKXGdhbW1hX3tpaX0gPSBmX3tpaX0vXHN1bV97aj0xfV5tIGZfe2lqfSBccXVhZCB5IFxxdWFkIFxnYW1tYV97aWp9ID0gZl97aWp9L1xzdW1fe2o9MX1ebSBmX3tpan0KJCQKCihQb2Ryw61hbW9zIHV0aWxpemFyIG11bHRpcGxpY2Fkb3JlcyBkZSBMYWdyYW5nZSBwYXJhIGV4cHJlc2FyIGxhcyByZXN0cmljY2lvbmVzIFwoXHN1bV97aj0xfV5tzrNfe2lqfT0xXCkgc3VqZXRvIGFsIGN1YWwgYnVzY2Ftb3MgbWF4aW1pemFyIGxvcyB0w6lybWlub3MgXChsX2lcKSB5IHBvciBlbmRlIGxhIHBvc2liaWxpZGFkOyBlcyBzb2xvIGxhIHByb2JhYmlsaWRhZCBkZSB0cmFuc2ljacOzbiBlbXDDrXJpY2Eg4oCTIGVzIGVudG9uY2VzIHZpc3RvIGEgc2VyIHVuIGVzdGltYWRvciBjb25kaWNpb25hbCBNTCBkZSBcKM6zX2lqXCkuIEVsIGVzdGltYWRvciBcKM6TXCkgc2F0aXNmYWNlIGVsIHJlcXVlcmltaWVudG8gcXVlIGxhIHN1bWEgZGUgbGFzIGZpbGFzIGVzIGlndWFsIGEgMS4KCkxhIHN1cG9zaWNpb24gZGUgZXN0YWNpb25hcmllZGFkIGRlIGxhIGNhZGVuYSBkZSBNYXJrb3Ygbm8gZnVlIHVzYWRhIGVuIGxhIGRlcml2YWNpw7NuIHN1cGVyaW9yLiBTaSBkZXNlYW1vcyBhc3VtaXIgbGEgZXN0YWNpb25hcmllZGFkLCBwb2RlbW9zIHVzYXIgbGEgcG9zaWJpbGlkYWQgaW5jb25kaWNpb25hbC4gRXN0YSBlcyBsYSBwb3NpYmlsaWRhZCBjb25kaWNpb25hbCBtb3N0cmFkYSBhbnRlcmlvcm1lbnRlLCBtdWx0aXBsaWNhZGEgcG9yIGxhIHByb2JhYmlsaWRhZCBlc3RhY2lvbmFyaWEgzrRfYzEuIExhIHBvc2liaWxpZGFkIGluY29uZGljaW9uYWwgbyBzdSBsb2dhcml0bW8gcHVlZGVuIHNlciBlbnRvbmNlcyBtYXhpbWl6YWRvcyBudW3DqXJpY2FtZW50ZSwgc3VqZXRvIGEgcmVzdHJpY2Npb25lcyBubyBuZWdhdGl2YXMgeSBzdW1hIGRlIGZpbGFzLCBlbiBvcmRlbiBwYXJhIGVzdGltYXIgbGFzIHByb2JhYmlsaWRhZGVzIGRlIHRyYW5zaWNpw7NuIFwozrNfe2lqfVwpLiBCaXNnYWFyZCB5IFRyYXZpcyAoMTk5MSkgbXVlc3RyYW4gZW4gZWwgY2FzbyBkZSB1bmEgY2FkZW5hIGRlIE1hcmtvdiBkZSBkb3MgZXN0YWRvcyBxdWUsIGV4Y2VwdG8gZW4gYWxndW5vcyBjYXNvcyBleHRyZW1vcywgZWN1YWNpb25lcyBkZSBwb3NpYmlsaWRhZCBpbmNvbmRpY2lvbmFsIHRpZW5lbiB1bmEgw7puaWNhIHNvbHVjacOzbi4gUGFyYSBhbGd1bm9zIGNhc29zIGVzcGVjaWFsZXMgbm8gdHJpdmlhbGVzIGRlIGxhIGNhZGVuYSBkZSBkb3MgZXN0YWRvcywgdGFtYmnDqW4gZGVyaXZhbiBleHByZXNpb25lcyBleHBsaWNpdGFzIHBhcmEgbG9zIGVzdGltYWRvcyBpbmNvbmRpY2lvbmFsZXMgZGUgcG9zaWJpbGlkYWQgbcOheGltYSAoTUxFcykgZGUgbGFzIHByb2JhYmlsaWRhZGVzIGRlIHRyYW5zaWNpw7NuLiBEZXNkZSBxdWUgdXNhbW9zIHRhbCByZXN1bHRhZG8gbHVlZ28sIGxvIGRlY2xhcmFtb3MgYXF1w60uClN1cG9uZ2EgcXVlIGxhIGNhZGVuYSBkZSBNYXJrb3YgXCh7Q190fVwpIHRvbWEgbG9zIHZhbG9yZXMgMCB5IDEsIHkgcXVlIGRlc2VhbW9zIGVzdGltYXIgbGFzIHByb2JhYmlsaWRhZGVzIGRlIHRyYW5zaWNpw7NuIFwozrNfe2lqfVwpIGRlIHVuYSBzZWN1ZW5jaWEgZGUgb2JzZXJ2YWNpb25lcyBlbiBlbCBjdWFsIGhheSBcKGZfe2lqfVwpdHJhbnNpY2lvbmVzIGRlbCBlc3RhZG8gaSBhbCBlc3RhZG8gaiAoaSxqPTAsMSksIHkgXChmX3sxMX0+MFwpIHBlcm8gXChmX3swMH09MFwpLiBBc2kgcXVlIGVuIGxhcyBvYnNlcnZhY2lvbmVzIHVuIGNlcm8gc2llbXByZSBlcyBzZWd1aWRvIHBvciB1biB1bm8uIERlZmluYXNlIFwoYz1mX3sxMH0rKDEtY18xKVwpIHkgXChkPWZfezExfVwpLiBFbnRvbmNlcyBsYXMgTUxFcyBpbmNvbmRpY2lvbmFsZXMgZGUgbGFzIHByb2JhYmlsaWRhZGVzIGRlIHRyYW5zaWNpw7NuIGVzdMOhbiBkYWRhcyBwb3I6CgokJApcZ2FtbWFfezAxfSA9IDEgXHF1YWQgeSBccXVhZCBcZ2FtbWFfezEwfSA9IFxmcmFjey0oMStkKSsoKDErZCkpXjIgKyA0YyhjK2QtMSkpXnsxLzJ9fXsyKGMrZCsxKX0KJCQKCiMjIzEuMy41LiBDYWRlbmFzIGRlIE1hcmtvdiBkZSBvcmRlbiBzdXBlcmlvcgoKCkVuIGNhc29zIGRvbmRlIG9ic2VydmFjaW9uZXMgZW4gdW4gcHJvY2VzbyBjb24gZXNwYWNpbyB5IGVzdGFkbyBmaW5pdG8gYXBhcmVjZW4gbm8gc2F0aXNmYWNlciBsYSBwcm9waWVkYWQgZGUgTWFya292LCB1bmEgcG9zaWJpbGlkYWQgcXVlIHN1Z2llcmUgYSBzaSBtaXNtYSBlcyBlbCB1dGlsaXphciB1bmEgY2FkZW5hIGRlIE1hcmtvdiBkZSBvcmRlbiBzdXBlcmlvciwgZXN0byBlcywgdW4gbW9kZWxvIFwoe0NfdH1cKSBzYXRpc2ZhY2llbmRvIGxhIHNpZ3VpZW50ZSBnZW5lcmFsaXphY2nDs24gZGUgbGEgcHJvcGllZGFkIGRlIE1hcmtvdiBwYXJhIGFsZ3Vub3MgbOKJpTI6IAoKJCQKUHIoQ190IHwgQ197dC0xfSA9IGpfMSwuLi4sQ197dC1sfT1qX2wpID0gXHN1bV97aT0xfV5sIFxsYW1iZGFfaSBxKGpfaSxqX28pCiQkClVuIHJlZ2lzdHJvIGRlIHRhbCBvcmRlbiBkZSBjYWRlbmFzIGRlIE1hcmtvdiBwdWVkZSBzZXIgZW5jb250cmFkbywgcG9yIGVqZW1wbG8sIGVsIExsb3lkICgxOTgwLCBTZWNjacOzbiAxOS45KS4gQXVucXVlIHRhbCBtb2RlbG8gbm8gZXMgZW4gdW4gc2VudGlkbyB1c3VhbCB1bmEgY2FkZW5hIGRlIE1hcmtvdiwgcG9kZW1vcyByZWRlZmluaXIgZWwgbW9kZWxvIGRlIHRhbCBtYW5lcmEgY29tbyBwYXJhIHByb2R1Y2lyIHVuIHByb2Nlc28gZXF1aXZhbGVudGUuIFNpIHBlcm1pdGltb3MgcXVlIFwoWV90PShDX3sodC1sKzEpfSxDX3sodC1sKzIpfSzigKYsQ190KVwpLCBlbnRvbmNlcyB7WV90fSBlcyB1bmEgY2FkZW5hIGRlIE1hcmtvdiBkZSBwcmltZXIgb3JkZW4gZW4gTV5sLCBkb25kZSBNIGVzIGVsIGVzcGFjaW8gZGUgZXN0YWRvIGRlIHtDX3R9LgpBdW5xdWUgYWxndW5hcyBwcm9waWVkYWRlcyBwdWVkZW4gc2VyIHJhcmFzIGRlIGVzdGFibGVjZXIsIG5pbmd1bmEgbnVldmEgdGVvcsOtYSBlcyBpbnZvbHVjcmFkYSBlbiBhbmFsaXphciB1bmEgY2FkZW5hIGRlIE1hcmtvdiBkZSBvcmRlbiBzdXBlcmlvciBtYXMgcXVlIHVuYSBkZSBwcmltZXIgb3JkZW4uClVuYSBjYWRlbmEgZGUgTWFya292IGRlIHNlZ3VuZG8gb3JkZW4sIHNpIGVzIGVzdGFjaW9uYXJpYSwgZXN0YSBjYXJhY3Rlcml6YWRhIHBvciBsYXMgcHJvYmFiaWxpZGFkZXMgZGUgdHJhbnNpY2nDs246CgokJApcZ2FtbWEoaSxqLGspID0gUHIoQ190PWsgfCBDX3t0LTF9ID0gaiwgQ197dC0yfSA9IGkpCiQkCgpZIHRpZW5lIHVuYSBkaXN0cmlidWNpw7NuIGVzdGFjaW9uYXJpYSBkZSB2YXJpYWJsZSBkb2JsZSBcKHUoaixrKT1QcmEoQ197dC0xfT1qLENfdD1rKVwpIHF1ZSBzYXRpc2ZhY2UKCiQkCnUoaixrKSA9IFxzdW1fe2k9MX1ebSB1KGksailcZ2FtbWEoaSxqLGspIFxxdWFkIHkgXHF1YWQgXHN1bV97aj0xfV5tXHN1bV97az0xfV5tIHUoaixrKSA9MQokJAoKUG9yIGVqZW1wbG8sIGxhIGNhZGVuYSBkZSBNYXJrb3YgZXN0YWNpb25hcmlhIGRlIHNlZ3VuZG8gb3JkZW4gbWFzIGdlbmVyYWwgXCh7Q190fVwpLCBlbiBsb3MgZG9zIGVzdGFkb3MgMSB5IDIsIGVzdGEgY2FyYWN0ZXJpemFkYSBwb3IgbGFzIHNpZ3VpZW50ZXMgY3VhdHJvIHByb2JhYmlsaWRhZGVzIGRlIHRyYW5zaWNpw7NuOgoKJCQKYSA9IFByKENfdD0yIHwgQ197dC0xfT0xLCBDX3t0LTJ9ID0gMSkgXFwKYiA9IFByKENfdD0xIHwgQ197dC0xfT0yLCBDX3t0LTJ9ID0gMikgXFwKYyA9IFByKENfdD0xIHwgQ197dC0xfT0yLCBDX3t0LTJ9ID0gMSkgXFwKZCA9IFByKENfdD0yIHwgQ197dC0xfT0xLCBDX3t0LTJ9ID0gMikgXFwKJCQKRWwgcHJvY2VzbyBcKHtZX3QgfT17KENfe3QtMX0sQ190ICl9XCkgZXMgZW50b25jZXMgdW5hIGNhZGVuYSBkZSBNYXJrb3YgZGUgcHJpbWVyIG9yZGVuLCBjb24gbG9zIGN1YXRybyBlc3RhZG9zICgxLDEpLCAoMSwyKSwgKDIsMSksICgyLDIpLCBjb24gbWF0cml6IGRlIHRyYW5zaWNpw7NuIGRlIHByb2JhYmlsaWRhZGVzCgokJApcbGVmdChcYmVnaW57YXJyYXl9e2NjfSAKMS1hICYgYSAmIDAgJiAwXFwgCjAgJiAwICYgYyAmIDEtYyBcXAoxLWQgJiBkICYgMCAmIDAgXFwKMCAmIDAgJiBiICYgMS1iClxlbmR7YXJyYXl9XHJpZ2h0KQokJAoKTm90ZSBsb3MgY2Vyb3MgZXN0cnVjdHVyYWxlcyBxdWUgYXBhcmVjZW4gZW4gbGEgbWF0cml6LiBObyBlcyBwb3NpYmxlLCBwb3IgZWplbXBsbywgaGFjZXIgdW5hIHRyYW5zaWNpw7NuIGRpcmVjdGEgZGUgKDIsMSkgYSAoMiwyKTsgcG9yIGxvIHRhbnRvLCBlbCBjZXJvIGVuIGxhIGZpbGEgMyB5IGNvbHVtbmEgNCBlbiBlbCB0LnAubS4gTG9zIHBhcsOhbWV0cm9zIGEsIGIsIGMgeSBkIGVzdMOhbiBsaW1pdGFkb3MgYSAwIHkgMSBwZXJvIHNvbiBzaW4gcmVzdHJpY2Npb25lcyBlbiBvdHJvIGNhc28uIExhIGRpc3RyaWJ1Y2nDs24gZXN0YWNpb25hcmlhIGRlIFwoe1lfdH1cKSBlcyBwcm9wb3JjaW9uYWwgYWwgdmVjdG9yCgokJChiKDEtZCksYWIsYWIsYSgxLWMpKSQkCgpEZWwgY3VhbCBzZSBkaWNlIHF1ZSBsYSBtYXRyaXogXCh1KGosaylcKSBkZSBwcm9iYWJpbGlkYWRlcyBiaS12YXJpYWJsZSBlc3RhY2lvbmFyaWEgcGFyYSBcKHtDX3QgfVwpIGVzOgoKJCQKXGZyYWN7MX17YigxLWQpKzJhYithKDEtYyl9ClxsZWZ0KFxiZWdpbnthcnJheX17Y2N9IApiKDEtZCkgJiBhYlxcIAphYiAmIGEoMS1jKQpcZW5ke2FycmF5fVxyaWdodCkKJCQKCgpFbCB1c28gZGUgdW5hIGNhZGVuYSBkZSBNYXJrb3YgZ2VuZXJhbCBkZSBvcmRlbiBzdXBlcmlvciBpbmNyZW1lbnRhIGVsIG7Dum1lcm8gZGUgcGFyw6FtZXRyb3MgZGVsIG1vZGVsbzsgdW5hIGNhZGVuYSBkZSBNYXJrb3YgZ2VuZXJhbCBkZSBvcmRlbiBsIGVuIG0gZXN0YWRvcyB0aWVuZSBcKG1ebCAobS0xKVwpIHByb2JhYmlsaWRhZGVzIGRlIHRyYW5zaWNpb24gaW5kZXBlbmRpZW50ZXMuIFBlZ3JhbSAoMTk4MCkgeSBSYWZ0ZXJ5ICgxOTg1KSBoYW4gcG9yIGxvIHRhbnRvIHByb3B1ZXN0byBjaWVydGFzIGNsYXNlcyBkZSBtb2RlbG9zIHBhcmEgY2FkZW5hcyBkZSBvcmRlbiBzdXBlcmlvci4gRWwgbW9kZWxvIGRlIFBlZ3JhbSB0aWVuZSBtK2wtMSBwYXJhbWV0cm9zLCB5IGFxdWVsbG9zIGRlIFJhZnRlcnkgbShtLTEpK2wtMS4gUGFyYSBtPTIgbG9zIG1vZGVsb3Mgc29uIGVxdWl2YWxlbnRlcywgcGVybyBwYXJhIG0+MiBhcXVlbGxvcyBkZSBSYWZ0ZXJ5IHNvbiBtYXMgZ2VuZXJhbGVzIHkgcHVlZGVuIHJlcHJlc2VudGFyIHVuIHJhbmdvIG1hcyBhbXBsaW8gZGUgcGF0cm9uZXMgZGUgZGVwZW5kZW5jaWEgeSBlc3RydWN0dXJhcyBkZSBhdXRvY29ycmVsYWNpw7NuLiBFbiBhbWJvcyBjYXNvcyB1biBpbmNyZW1lbnRvIGRlIHVubyBlbiBlbCBvcmRlbiBkZSBsYSBjYWRlbmEgZGUgTWFya292IHJlcXVpZXJlIHNvbGFtZW50ZSBkZSB1biBwYXLDoW1ldHJvIGFkaWNpb25hbC4KTW9kZWxvcyBkZSBSYWZ0ZXJ5LCBhIGxvcyBjdWFsZXMgZWwgc2UgcmVmaWVyZSBjb21vIG1vZGVsb3MgZGUg4oCcZGlzdHJpYnVjacOzbiBkZSB0cmFuc2ljacOzbiBkZSBsYSBtZXpjbGHigJ0gKE1URCksIHNvbiBkZWZpbmlkb3MgY29tbyBzaWd1ZS4gRWwgcHJvY2VzbyBcKHtDX3R9XCkgdG9tYSB2YWxvcmVzIFwoTT17MSwyLOKApixtfVwpIHkgc2F0aXNmYWNlCgokJFByKENfdCA9IGpfMCB8IENfe3QtMX0gPSBqXzEsLi4uLCBDX3t0LWx9ID0gal9sKSA9IFxzdW1fe2ktMX1ebCBcbGFtYmRhX2kgcShqX2ksal8wKSQkCkRvbmRlIFwoXHN1bV97aT0xfV5sIM67X2k9MVwpLCB5IFwoUT0ocShqLGspKVwpIGVzIHVuYSBtYXRyaXogbcOXbSBjb24gZW50cmFkYXMgbm8gbmVnYXRpdmFzIHkgbGEgc3VtYSBkZSBzdXMgZmlsYXMgZXF1aXZhbGUgYSB1bm8sIHRhbCBxdWUgZWwgbGFkbyBkZXJlY2hvIGRlIGxhIGVjdWFjacOzbiBhbnRlcmlvciBlc3RhIGxpbWl0YWRhIHBvciBjZXJvIHkgdW5vIHBhcmEgdG9kbyBcKGpfbyxqXzEs4oCmLGpfbOKIiE1cKS4gRXN0ZSDDumx0aW1vIHJlcXVlcmltaWVudG8sIGVsIGN1YWwgZ2VuZXJhbCBtXihsKzEpIHBhcmVzIGRlIHJlc3RyaWNjaW9uZXMgbm8gbGluZWFyZXMgZW4gbG9zIHBhcsOhbWV0cm9zLCBhc2VndXJhIHF1ZSBsYXMgcHJvYmFiaWxpZGFkZXMgY29uZGljaW9uYWxlcyBlbiBsYSBlY3VhY2nDs24gYW50ZXJpb3Igc29uIGVuIGVmZWN0byBwcm9iYWJpbGlkYWRlcywgeSBsYSBjb25kaWNpw7NuIGVuIGxhIHN1bWEgZGUgZmlsYXMgZGUgUSBhc2VndXJhIHF1ZSBsYSBzdW1hIHNvYnJlIFwoal8wXCkgZGUgZXN0YXMgcHJvYmFiaWxpZGFkZXMgY29uZGljaW9uYWxlcyBlcyB1bm8uIE5vdGUgcXVlIFJhZnRlcnkgbm8gYXN1bWUgcXVlIGxvcyBwYXLDoW1ldHJvcyBcKM67X2lcKSwgc29uIG5vIG5lZ2F0aXZvcy4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoKIyNDYXDDrXR1bG8gMjogTW9kZWxvcyBkZSBNYXJrb3Ygb2N1bHRvczogZGVmaW5pY2nDs24geSBwcm9waWVkYWRlcwoKIyMjMi4xLiBVbiBtb2RlbG8gZGUgTWFya292IG9jdWx0byBzaW1wbGUKCgpDb25zaWTDqXJlc2UgbnVldmFtZW50ZSBsYSBzZXJpZSBkZSB0ZXJyZW1vdG9zIG1vc3RyYWRhIGVuIGVsIGNhcGl0dWxvIGFudGVyaW9yLiBMYXMgb2JzZXJ2YWNpb25lcyBzb24gY3VlbnRhcyBpbGltaXRhZGFzLCBoYWNpZW5kbyBsYSBkaXN0cmlidWNpw7NuIGRlIFBvaXNzb24gdW5hIGVsZWNjacOzbiBuYXR1cmFsIHBhcmEgZGVzY3JpYmlybGFzLCBwZXJvIHN1IGRpc3RyaWJ1Y2nDs24gZXMgY2xhcmFtZW50ZSByZWxhdGl2YSBzb2JyZSBkaXNwZXJzYSBhIGxhIGRlIFBvaXNzb24uIE9ic2VydmFtb3MgZW4gZWwgY2Fww610dWxvIGFudGVyaW9yIHF1ZSBlc3RlIGhlY2hvIHB1ZWRlIHNlciBhY29tb2RhZG8gYWwgdXNhciB1bmEgbWV6Y2xhIGRlIGRpc3RyaWJ1Y2lvbmVzIGRlIFBvaXNzb24gY29uIG1lZGlhcyBcKM67XzEszrtfMizigKYszrtfbVwpLiBMYSBlbGVjY2nDs24gZGUgbGEgbWVkaWEgZXN0YSBoZWNoYSBwb3IgdW4gc2VndW5kbyBwcm9jZXNvIGFsZWF0b3JpbywgZWwgcHJvY2VzbyBkZSBwYXLDoW1ldHJvLiBMYSBtZWRpYSBcKM67X2lcKSBlcyBzZWxlY2Npb25hZGEgY29uIHByb2JhYmlsaWRhZCBcKM60X2lcKSwgZG9uZGUgXChpPTEsMizigKYsbVwpIHkgXChcc3VtX3tpPTF9Xm3OtF9pPTFcKS4KClVuIG1vZGVsbyBkZSBtZXpjbGEgaW5kZXBlbmRpZW50ZSBubyByZXN1bHRhcmEgY29uIGxhIHNlcmllIGRlIHRlcnJlbW90b3MgcG9ycXVlLCBwb3IgZGVmaW5pY2nDs24sIG5vIHBlcm1pdGUgbGEgZGVwZW5kZW5jaWEgc2VyaWFsIGVuIGxhcyBvYnNlcnZhY2lvbmVzLiBMYSBtdWVzdHJhIGRlIGZ1bmNpw7NuIGRlIGF1dG9jb3JyZWxhY2nDs24gKEFDRiksIGRlc3BsZWdhZGEgZW4gbGEgRmlndXJhIDIuMSwgY2xhcmFtZW50ZSBpbmRpY2EgcXVlIGxhcyBvYnNlcnZhY2lvbmVzIHNvbiBkZXBlbmRpZW50ZXMgZW4gc2VyaWUuIFVuYSBtYW5lcmEgZGUgcGVybWl0aXIgbGEgZGVwZW5kZW5jaWEgc2VyaWFsIGVuIGxhcyBvYnNlcnZhY2lvbmVzIGVzIHJlbGFqYXIgbGEgc3Vwb3NpY2nDs24gcXVlIGVsIHByb2Nlc28gZGUgcGFyw6FtZXRybyBlcyBpbmRlcGVuZGllbnRlIGVuIHNlcmllLiBVbmEgbWFuZXJhIHNpbXBsZSB5IG1hdGVtw6F0aWNhbWVudGUgY29udmVuaWVudGUgcGFyYSBoYWNlciBlc3RvIGVzIGFzdW1pciBxdWUgZXMgdW5hIGNhZGVuYSBkZSBNYXJrb3YuIEVsIG1vZGVsbyByZXN1bHRhbnRlIHBhcmEgbGFzIG9ic2VydmFjaW9uZXMgZXMgbGxhbWFkbyB1biBtb2RlbG8gZGUgTWFya292IG9jdWx0byBkZSBQb2lzc29uLgoKYGBge3J9CmxpYnJhcnkoZm9yZWNhc3QpCmxpYnJhcnkocmVhZHIpCiNsZWVyIGxhIGRhdGEgCmRhdGFfdGVycmVtb3Rvc19jaDIgPC0gcmVhZC50YWJsZSgiL1VzZXJzL2JyYWNydXovRG9jdW1lbnRzLzh2by4gVHJpbWVzdHJlIElPL1Npc3QuIEV4cGVydG9zIHkgUmVkZXMgUHJvYi4vZWFydGhxdWFrZXMudHh0IikKI09idGVuZXIgbGEgQUNGIGRlIGxhIGRhdGEgYW50ZXJpb3IKQUNGX2NoMiA8LSBhY2YoZGF0YV90ZXJyZW1vdG9zX2NoMiwgcGxvdD1UUlVFKQoKYGBgCkZpZ3VyYSAyLjEKCgoKIyMjMi4yIExvIGLDoXNpY28KIyMjIzIuMi4xIERlZmluaWNpw7NuIHkgbm90YWNpw7NuCgohW0ZpZ3VyYSAyLjJdKC9Vc2Vycy9icmFjcnV6L0RvY3VtZW50cy84dm8uIFRyaW1lc3RyZSBJTy9TaXN0LiBFeHBlcnRvcyB5IFJlZGVzIFByb2IuL0NIMi9GaWd1cmEyLTIucG5nKQoKVW4gbW9kZWxvIGRlIE1hcmtvdiBvY3VsdG8gXCh7WF90OnQg4oiITn1cKSBlcyB1biB0aXBvIHBhcnRpY3VsYXIgZGUgbWV6Y2xhIGRlcGVuZGllbnRlLiBDb24gXChYXnRcKSB5IFwoQ150XCkgcmVwcmVzZW50YW5kbyBsYXMgaGlzdG9yaWFzIGRlbCB0aWVtcG8gMSBhbCB0aWVtcG8gdCwgdW5vIHB1ZWRlIHJlc3VtaXIgZWwgbW9kZWxvIG3DoXMgc2ltcGxlIGRlIGVzdGUgdGlwbyBwb3I6CgokJApQcihDX3QgfCBDXnt0LTF9KSA9IFByKENfdCB8IENfe3QtMX0pLCB0PTIsMywuLi4gXFwKUHIoWF90IHwgWF57dC0xfSxDXnQpID0gUHIoWF90IHwgQ190KSwgdCDiiIggTgokJApFbCBtb2RlbG8gY29uc2lzdGUgZGUgZG9zIHBhcnRlczogcHJpbWVybywgdW4g4oCccHJvY2VzbyBkZSBwYXLDoW1ldHJv4oCdIG5vIG9ic2VydmFkbyBcKHtDX3Q6dD0xLDIs4oCmfVwpIHNhdGlzZmFjaWVuZG8gbGEgcHJvcGllZGFkIGRlIE1hcmtvdjsgeSBjb21vIHNlZ3VuZG8sIGVsIOKAnHByb2Nlc28gZXN0YWRvLWRlcGVuZGllbnRl4oCdIFwoe1hfdDp0PTEsMizigKZ9XCksIGVuIGVsIGN1YWwgbGEgZGlzdHJpYnVjacOzbiBkZSBcKFhfdFwpIGRlcGVuZGUgc29sYW1lbnRlIGVuIGVsIGVzdGFkbyBhY3R1YWwgXChDX3RcKSB5IG5vIGRlIGVzdGFkb3MgdSBvYnNlcnZhY2lvbmVzIHByZXZpYXMuIExhIGVzdHJ1Y3R1cmEgc2UgcmVwcmVzZW50YSBlbiBsYSBGaWd1cmEgMi4yCgoKU2kgbGEgY2FkZW5hIGRlIE1hcmtvdiBcKHtDX3R9XCkgdGllbmUgbSBlc3RhZG9zLCBsbGFtYW1vcyBcKHtYX3R9XCkgdW5hIEhNTSBkZSBtLWVzdGFkb3MuIEF1bnF1ZSBlcyBsYSB0ZXJtaW5vbG9nw61hIHVzdWFsIGVuIGFwbGljYWNpb25lcyBkZSBwcm9jZXNhbWllbnRvIGRlbCBoYWJsYSwgZWwgbm9tYnJlIOKAnG1vZGVsbyBkZSBNYXJrb3Ygb2N1bHRv4oCdIGVzIHBvciBuaW5nw7puIG1lZGlvIGVsIMO6bmljbyB1c2FkbyBwYXJhIHRhbGVzIG8gc2ltaWxhcmVzLgoKIVtGaWd1cmEgMi4zIC0gUHJvY2VzbyBnZXJlbmFuZG8gbGFzIG9ic2VydmFjaW9uZXMgZW4gdW4gZXN0YWRvIGRvYmxlIGRlIEhNTS4gU2lndWllbmRvIGxhIGNhZGVuYSAyLDEsMSwxLDIsMV0oL1VzZXJzL2JyYWNydXovRG9jdW1lbnRzLzh2by4gVHJpbWVzdHJlIElPL1Npc3QuIEV4cGVydG9zIHkgUmVkZXMgUHJvYi4vQ0gyL0ZpZ3VyYTItMy5wbmcpCgpFbCBwcm9jZXNvIGdlbmVyYW5kbyBsYXMgb2JzZXJ2YWNpb25lcyBlcyBudWV2YW1lbnRlIGRlbW9zdHJhZG8gZW4gbGEgRmlndXJhIGFudGVyaW9yLCBwYXJhIGRpc3RyaWJ1Y2lvbmVzIGVzdGFkby1kZXBlbmRpZW50ZXMgXChwXzFcKSB5IFwocF8yXCksIGRpc3RyaWJ1Y2nDs24gZXN0YWNpb25hcmlhIFwozrQ9KDAuNzUsMC4yNSlcKSwgeSB0LnAubS4gXChcR2FtbWE9IFxsZWZ0KFxiZWdpbnthcnJheX17Y2N9IAowLjkgJiAwLjFcXCAKMC4zICYgMC43ClxlbmR7YXJyYXl9XHJpZ2h0KVwpLiBFbiBjb250cmFzdGUgYWwgY2FzbyBkZSB1bmEgbWV6Y2xhIGluZGVwZW5kaWVudGUsIGFxdcOtIGxhIGRpc3RyaWJ1Y2nDs24gZGUgXChDX3RcKSwgZWwgZXN0YWRvIGVuIHRpZW1wbyB0LCBzw60gZGVwZW5kZSBkZSBcKENfKHQtMSlcKS4gVGFtYmnDqW4gZXMgY2llcnRvIGRlIGxhcyBtZXpjbGFzIGluZGVwZW5kaWVudGVzLCBoYXkgcGFyYSBjYWRhIGVzdGFkbyB1bmEgZGlzdHJpYnVjacOzbiBkaWZlcmVudGUsIGRpc2NyZXRhIG8gY29udGludWEuCkFob3JhIGludHJvZHVjaXJlbW9zIHVuYSBub3RhY2nDs24gbGEgY3VhbCBjdWJyaXLDoSB0YW50byBvYnNlcnZhY2lvbmVzIHZhbHVhZGFzIGRpc2NyZXRhcyBjb21vIGNvbnRpbnVhcy4gRW4gZWwgY2FzbyBkZSBvYnNlcnZhY2lvbmVzIGRpc2NyZXRhcywgZGVmaW5pbW9zLCBwYXJhIFwoaT0xLDIs4oCmLG1cKQoKJCRwX2koeCkgPSBQcihYX3QgPSB4IHwgQ190ID0gaSkkJApFc3RvIGVzLCBcKHBfaVwpLCBlcyBsYSBmdW5jacOzbiBkZSBwcm9iYWJpbGlkYWQgZW4gbWFzYSBkZSBcKFhfdFwpIHNpIGxhIGNhZGVuYSBkZSBNYXJrb3YgZXN0w6EgZW4gZWwgZXN0YWRvIGkgZW4gZWwgdGllbXBvIHQuIEVsIGNhc28gY29udGludW8gZXMgdHJhdGFkbyBkZSBtYW5lcmEgc2ltaWxhcjogYXF1w60gZGVmaW5pbW9zIFwocF9pXCkgY29tbyBsYSBmdW5jacOzbiBkZSBkZW5zaWRhZCBkZSBwcm9iYWJpbGlkYWQgZGUgXChYX3RcKSBhc29jaWFkYSBjb24gZWwgZXN0YWRvIGkuIE5vcyByZWZlcmltb3MgYSBsYXMgbSBkaXN0cmlidWNpb25lcyBcKHBfaVwpIGNvbW8gbGEgZGlzdHJpYnVjacOzbiBlc3RhZG8tZGVwZW5kaWVudGUgZGVsIG1vZGVsby4KCgojIyMjMi4yLjIgRGlzdHJpYnVjaW9uZXMgbWFyZ2luYWxlcwoKQSBtZW51ZG8gbmVjZXNpdGFtb3MgbGFzIGRpc3RyaWJ1Y2lvbmVzIG1hcmdpbmFsZXMgZGUgXChYX3RcKSB5IHRhbWJpw6luIGRpc3RyaWJ1Y2lvbmVzIG1hcmdpbmFsZXMgZGUgb3JkZW4gc3VwZXJpb3IsIHRhbGVzIGNvbW8gXCgoWF90LFhfe3Qra30pXCkuIERlcml2YXJlbW9zIGxvcyByZXN1bHRhZG9zIHBhcmEgZWwgY2FzbyBlbiBlbCBjdWFsIGxhIGNhZGVuYSBkZSBNYXJrb3YgZXMgaG9tb2fDqW5lYSBwZXJvIG5vIG5lY2VzYXJpYW1lbnRlIGVzdGFjaW9uYXJpYSwgeSBsdWVnbyB2ZXJlbW9zIHBhcmEgZWwgY2FzbyBlc3BlY2lhbCBlbiBkb25kZSBsYSBjYWRlbmEgZGUgTWFya292IGVzIGVzdGFjaW9uYXJpYS4gUG9yIGNvbnZlbmllbmNpYSBsYSBkZXJpdmFjacOzbiBlcyBkYWRhIHNvbG8gcGFyYSBsYXMgZGlzdHJpYnVjaW9uZXMgZXN0YWRvLWRlcGVuZGllbnRlcyBkaXNjcmV0YXM7IGVsIGNhc28gY29udGludW8gcHVlZGUgc2VyIGRlcml2YWRvIGFuw6Fsb2dhbWVudGUuCgojIyMjI0Rpc3RyaWJ1Y2lvbmVzIGRlIHVuYSB2YXJpYWJsZQpQYXJhIG9ic2VydmFjaW9uZXMgZGUgdmFsb3JlcyBkaXNjcmV0b3MgXChYX3RcKSwgZGVmaW5pbW9zIFwodV9pKHQpPVByYShDX3Q9aSlccXVhZCBwYXJhXHF1YWQgdD0xLOKApixUXCksIHRlbmVtb3MKCiQkClByKFhfdCA9IHgpID0gXHN1bV97aT0xfV5tIFByKENfdCA9IGkpIFByKFhfdCA9IHggfENfdCA9IGkpIFxcCj0gXHN1bV97aT0xfV5tIHVfaSh0KXBfaSh4KQokJApMYSBleHByZXNpw7NuIHB1ZWRlIHNlciBjb252ZW5pZW50ZW1lbnRlIHJlc2NyaXRhIGVuIG5vdGFjaW9uIGRlIG1hdHJpegoKJCQKUHIoWF90ID0geCkgPSAodV8xKHQpLC4uLix1X20odCkpIApcbGVmdChcYmVnaW57YXJyYXl9e2NjfSAKcF8xKHgpICYgMFxcIAowICYgcF9tKHgpClxlbmR7YXJyYXl9XHJpZ2h0KQpcbGVmdChcYmVnaW57YXJyYXl9e2NjfSAKMVxcIAoxIApcZW5ke2FycmF5fVxyaWdodCkgXFwKPXUodCkgUCh4KTEnCiQkCkRvbmRlIFwoUCh4KVwpIGVzIGRlZmluaWRhIGNvbW8gbGEgbWF0cml6IGRpYWdvbmFsIGNvbiBzdSBpLWVzaW1vIGVsZW1lbnRvIGRpYWdvbmFsIFwocF9pICh4KVwpLiBUb21hbmRvIGVuIGN1ZW50YSBsYSBlY3VhY2nDs24gZGVsIGNhcMOtdHVsbyBhbnRlcmlvciBxdWUgZGljdGEgcXVlIFwodSh0KT11KDEpIM6TXnt0LTF9XCksIHkgcG9yIGxvIHRhbnRvCgoKJCRQcihYX3QgPSB4KSA9IHUoMSlcR2FtbWFee3QtMX0gUCh4KTEnJCQKRXN0YSBlY3VhY2nDs24gZnVuY2lvbmEgc29sYW1lbnRlIHNpIGxhIGNhZGVuYSBkZSBNYXJrb3YgZXMgcHVyYW1lbnRlIGhvbW9nw6luZWEsIHkgbm8gbmVjZXNhcmlhbWVudGUgZXN0YWNpb25hcmlhLiBTaSwgY29tbyBsbyBhc3VtaXJlbW9zIHVzdWFsbWVudGUsIGxhIGNhZGVuYSBkZSBNYXJrb3YgZXMgZXN0YWNpb25hcmlhLCBjb24gZGlzdHJpYnVjacOzbiBlc3RhY2lvbmFyaWEgXCjOtFwpLCBlbCByZXN1bHRhZG8gZXMgYcO6biBtw6FzIHNpbXBsZTogZW4gZXNlIGNhc28gXCjOtM6TXnsodC0xKX09zrRcKSBwYXJhIHRvZG8gXCh04oiITlwpLCB5IGVudG9uY2VzIAoKJCRQcihYX3QgPSB4KSA9IFxkZWx0YSBQKHgpMSckJAoKIyMjIyNEaXN0cmlidWNpb25lcyBkZSBkb3MgdmFyaWFibGVzCgpFbCBjw6FsY3VsbyBkZSBtdWNoYXMgZGUgbGFzIGRpc3RyaWJ1Y2lvbmVzIHJlbGFjaW9uYWRhcyBhIHVuIEhNTSBlcyByZWFsaXphZG8gbcOhcyBmw6FjaWxtZW50ZSBhbCBub3RhciBkZSBwcmltZXJvIHF1ZSwgcGFyYSB1biBtb2RlbG8gZ3JhZmljbyBkaXJpZ2lkbywgbGEgZGlzdHJpYnVjacOzbiBjb25qdW50YSBkZSB1biBzZXQgZGUgdmFyaWFibGVzIGFsZWF0b3JpYXMgXChWX2lcKSBlc3RhIGRhZGEgcG9yCgokJFByKFZfMSxWXzIsLi4uLFZfbikgPSBccHJvZF97aT0xfV5uIFByKFZfaSB8cGEoVl9pKSkkJAoKRG9uZGUgXChwYShWX2kgKVwpIGRlbm90YSBlbCBzZXQgZGUgdG9kb3MgbG9zIOKAnHBhcmllbnRlc+KAnSBkZSBcKFZfaVwpIGVuIGVsIHNldCBcKFZfMSxWXzIs4oCmLFZfblwpLgpFbiBlbCBncmFmaWNvIGRpcmlnaWRvIGRlIGxhcyBjdWF0cm8gdmFyaWFibGVzIGFsZWF0b3JpYXMgXChYX3QsWF97KHQrayl9LENfdCxDX3sodCtrKX1cKSAocGFyYSBlbnRlcm9zIHBvc2l0aXZvcyBrKSwgXChDX3RcKSBubyB0aWVuZSBwYXJpZW50ZXMsIFwocGEoWF90ICk9e0NfdCB9LHBhKENfeyh0K2spfSApPXtDX3R9XCkgeSBcKHBhKFhfeyh0K2spfSApPXtDX3sodCtrKX19XCkuIFkgcG9yIHRhbnRvIHNpZ3VlIHF1ZQoKJCQKUHIoWF90LFhfe3Qra30sQ190LENfe3Qra30pID0gUHIoQ190KVByKFhfdHxDX3QpIFByKENfe3Qra318Q190KSBQcihYX3t0K2t9fENfe3Qra30pCiQkClkgcG9yIGxvIHRhbnRvIGRpY3RhIHF1ZToKCiQkClByKFhfdCA9IHYsIFhfe3Qra309dykgPSBcc3VtX3tpPTF9Xm0gXHN1bV97aj0xfV5tIHVfaSh0KXBfaSh2KVxnYW1tYV97aWp9KGspcF9qKHcpCiQkCgooQXF1w60geSBlbiBjdWFscXVpZXIgb3RybyBsYWRvLCBcKM6zX3tpan0gKGspXCkgZGVub3RhIGxvcyAoaSxqKSBlbGVtZW50b3MgZGUgXCjOk15rXCkuKSBFc2NyaWJpZW5kbyBsYSBzdW1hIGRvYmxlIHN1cGVyaW9yIGNvbW8gZWwgcHJvZHVjdG9yIGRlIG1hdHJpY2VzIG9idGVuZW1vcwoKCiQkClByKFhfdCA9IHYsIFhfe3Qra309dykgPSB1KHQpIFAodilcR2FtbWFeayBQKHcpMScKJCQKU2kgbGEgY2FkZW5hIGRlIE1hcmtvdiBlcyBlc3RhY2lvbmFyaWEsIGVzdG8gc2UgcmVkdWNlIGEKCiQkClByKFhfdCA9IHYsIFhfe3Qra309dykgPSBcZGVsdGEgUCh2KSBcR2FtbWFeayBQKHcpMScKJCQKClNpbWlsYXJtZW50ZSwgdW5vIHB1ZWRlIG9idGVuZXIgZXhwcmVzaW9uZXMgcGFyYSBsYXMgZGlzdHJpYnVjaW9uZXMgbWFyZ2luYWxlcyBkZSBvcmRlbiBzdXBlcmlvcjsgZW4gZWwgY2FzbyBlc3RhY2lvbmFyaW8sIGxhIGZvcm11bGEgcGFyYSB1bmEgZGlzdHJpYnVjacOzbiBkZSB0cmVzIHZhcmlhYmxlcyBlcywgcGFyYSBlbnRlcm9zIHBvc2l0aXZvcyBrIHkgIGwKCiQkClByKFhfdD12LCBYX3t0K2t9PXcsIFhfe3QraytsfSA9eikgPSBcZGVsdGEgUCh2KSBcR2FtbWFeayBQKHcpIFxHYW1tYV5sIFAoeikxJwokJAoKIyMjIzIuMi4zIE1vbWVudG9zCgpQcmltZXJvIG5vdGVtb3MgcXVlCgokJApFKFhfdCkgPSBcc3VtX3tpPTF9Xm0gRShYX3QgfCBDX3Q9aSApIFByKENfdCA9IGkpICA9IFxzdW1fe2k9MX1ebSB1X2kodCkgRShYX3R8Q190ID0gaSkKJCQKRW4gZWwgY3VhbCwgZWwgY2FzbyBlc3RhY2lvbmFyaW8gc2UgcmVkdWNlIGEKCiQkCkUoWF90KSA9IFxzdW1fe2k9MX1ebSBcZGVsdGFfaSBFKFhfdHwgQ190ID0gaSkKJCQKTWFzIGdlbmVyYWxtZW50ZSwgcmVzdWx0YWRvcyBhbmFsb2dvcyBhZ3VhcmRhbiBwYXJhIFwoRShnKFhfdCApKVwpIHkgXChFKGcoWF90LFhfe3Qra30gKSlcKSwgcGFyYSBjdWFscXVpZXIgZnVuY2nDs24gXChnXCkgcGFyYSBsYXMgY3VhbGVzIGV4cGVjdGF0aXZhcyBlc3RhZG8tZGVwZW5kaWVudGVzIHJlbGV2YW50ZXMgZXhpc3Rlbi4gRW4gZWwgY2FzbyBlc3RhY2lvbmFyaW8KCiQkCkUoZyhYX3QpKSA9IFxzdW1fe2k9MX1ebSBcZGVsdGFfaSBFKGcoWF90KSB8IENfdCA9aSkKJCQKeSBhZGVtw6FzCgokJApFKGcoWF90LFhfe3Qra30pKSA9IFxzdW1fe2ksaj0xfV5tIEUoZyhYX3QsWF97dCtrfSl8Q190ID0gaSwgQ197dCtrfSA9IGopIFxkZWx0YV9pIFxnYW1tYV97aWp9KGspCiQkCkEgbWVudWRvIHRhbWJpw6luIGVzdGFyZW1vcyBpbnRlcmVzYWRvcyBlbiB1bmEgZnVuY2nDs24gZyBsYSBjdWFsIGZhY3Rvcml6YSBhCgokJGcoWF90LCBYX3t0K2t9KSA9IGdfMShYX3QpIGdfMihYX3t0K2t9KSQkCkVuIGN1YWwgY2FzbyBsYSBlY3VhY2nDs24gcmVzdWx0YW50ZSB0ZXJtaW5hIHNpZW5kbwoKJCQKRShnKFhfdCxYX3t0K2t9KSkgPSBcc3VtX3tpLGo9MX1ebSBFKGdfMShYX3QpfCBDX3QgPSBpKSBFKGdfMihYX3t0K2t9KXxDX3t0K2t9PWopIFxkZWx0YV9pIFxnYW1tYV97aWp9KGspCiQkCkVzdGFzIGV4cHJlc2lvbmVzIG5vcyBwZXJtaXRlbiBlbmNvbnRyYXIgY292YXJpYW56YXMgeSBjb3JyZWxhY2lvbmVzOyBleHByZXNpb25lcyBleHBsaWNpdGFzIGNvbnZlbmllbnRlcyBleGlzdGVuIHBhcmEgbXVjaG9zIGNhc29zLiBQYXJhIGVsIGNhc28gZGUgdW4gSE1NIGRlIFBvaXNzb24gZXN0YWNpb25hcmlvIGRlIGRvcyBlc3RhZG9zOgoKJCQKRShYX3QpID0gXGRlbHRhXzEgXGxhbWJkYV8xICsgXGRlbHRhXzIgXGxhbWJkYV8yIFxcClZhcihYX3QpID0gRShYX3QpICsgXGRlbHRhXzEgXGRlbHRhXzIoXGxhbWJkYV8yIC0gXGxhbWJkYV8xKV4yIFxnZXEgRShYX3QpIFxcCkNvdihYX3QsIFhfe3Qra30pID0gIFxkZWx0YV8xIFxkZWx0YV8yKFxsYW1iZGFfMiAtIFxsYW1iZGFfMSleMiAoMSAtIFxnYW1tYV97MTJ9IC0gXGdhbW1hX3syMX0pXmssIHBhcmEgXHF1YWQgayBcaW4gTgokJAoKTm90ZXNlIHF1ZSBsYSBmb3JtdWxhIHJlc3VsdGFudGUgcGFyYSBsYSBjb3JyZWxhY2nDs24gZGUgXChYX3RcKSB5IFwoWF97dCtrfVwpIGVzIGRlIGxhIGZvcm1hIFwoz4Eoayk9QSgxLc6zX3sxMn0tzrNfezIxfSApXmtcKSBjb24gXChB4oiIWzAsMSlcKSwgeSBxdWUgQT0wIHNpIFwozrtfMT3Ou18yXCkuCgojIyMjMi4zLiBMYSBQb3NpYmlsaWRhZAoKRWwgb2JqZXRpdm8gZGUgZXN0YSBzZWNjacOzbiBlcyBkZXNhcnJvbGxhciB1bmEgZm9ybXVsYSBjb252ZW5pZW50ZSBwYXJhIGxhIHBvc2liaWxpZGFkIGRlIFwoTF9UXCkgZGUgVCBvYnNlcnZhY2lvbmVzIGNvbnRpbnVhcyBcKHhfMSx4XzIs4oCmLHhfVFwpIGFzdW1pZGEgYSBzZXIgZ2VuZXJhZGEgcG9yIHVuIEhNTSBkZSBtLWVzdGFkb3MuIFZlcmVtb3MgcXVlIGxhIGNvbXB1dGFjacOzbiBkZSBsYSBwb3NpYmlsaWRhZCwgY29uc2lzdGUgZGUgbGEgc3VtYSBkZSBcKG1eVFwpIHTDqXJtaW5vcywgY2FkYSBjdWFsIGVzIHVuIHByb2R1Y3RvIGRlIDJUIGZhY3RvcmVzLCBwYXJlY2UgcmVxdWVyaXIgTyhUbV5UKSBvcGVyYWNpb25lcy4KTnVlc3RybyBwcm9ww7NzaXRvIGFxdcOtIGVzIGRlbW9zdHJhciBxdWUgXChMXlRcKSBwdWVkZSBzZXIgZW4gZ2VuZXJhbCBjb21wdXRhZG8gc2ltcGxlbWVudGUgcmVsYWNpb25hZG8gZW4gXChPKFRtXjIgKVwpIG9wZXJhY2lvbmVzLiBMYSBtYW5lcmEgbHVlZ28gc2Vyw6EgYW1wbGlhZGEgcGFyYSBlc3RpbWFyIHBhcsOhbWV0cm9zIHBvciBtYXhpbWl6YWNpw7NuIG51bcOpcmljYXMgZGUgbGEgcG9zaWJpbGlkYWQuIFByaW1lcm8sIGxhIHBvc2liaWxpZGFkIGRlIG1vZGVsb3MgZGUgZG9zIGVzdGFkb3Mgc2Vyw6EgZXhwbG9yYWRhLCB5IGVudG9uY2VzIGxhIGZvcm11bGEgZ2VuZXJhbCBzZXLDoSBwcmVzZW50YWRhLgoKIyMjIyMyLjMuMS4gTGEgcG9zaWJpbGlkYWQgZGUgdW4gSE1NIGRlIEJlcm5vdWxsaSBkZSBkb3MgZXN0YWRvcwoKQ29uc2lkZXJlIGVsIEhNTSBlc3RhY2lvbmFyaW8gZGUgZG9zIGVzdGFkb3MgY29uIHQucC5tLgoKJCQKXEdhbW1hID0gClxsZWZ0KFxiZWdpbnthcnJheX17Y2N9IAoxLzIgJiAxLzJcXCAKMS80ICYgMy80ClxlbmR7YXJyYXl9XHJpZ2h0KQpccXVhZCB5IFxxdWFkClxkZWx0YSA9ClxsZWZ0KFxiZWdpbnthcnJheX17Y2N9IAoxLzMsIAoyLzMgClxlbmR7YXJyYXl9XHJpZ2h0KQokJAoKWSBkaXN0cmlidWNpb25lcyBlc3RhZG8tZGVwZW5kaWVudGVzIGRhZGFzIHBvcgoKJCQKUHIoWC10ID14IHwgQ190ID0gMSkgPSAxLzIgXHF1YWQocGFyYVxxdWFkIHggPTAsMSkgXFwKUHIoWC10ID0xIHwgQ190ID0gMikgPSAxCiQkCgpMbGFtYXJlbW9zIHVuIG1vZGVsbyBkZSBlc3RlIHRpcG8gdW4gSE1NIGRlIEJlcm5vdWxsaS4gLiBDb25zaWRlcmUgbGEgcHJvYmFiaWxpZGFkIFwoUHJhKFhfMT1YXzI9WF8zPTFcKS4gUHJpbWVybywgbm90ZSBxdWUsIHBvciBlY3VhY2lvbmVzIGFudGVyaW9yZXMsCgokJApQcmEoWF8xLFhfMixYXzMsQ18xLENfMixDXzMgKT1QcmEoQ18xICkgIFByYShYXzHilIJDXzEgKSAgUHJhKENfMuKUgkNfMSApICBQcmEoWF8y4pSCQ18yICkgIFByYShDXzPilIJDXzIgKSBQcmEoWF8zIHxDXzMpOwokJApsdWVnbyBzdW1hcm1vcyBsb3MgdmFsb3JlcyBhc3VtaWRvcyBwb3IgXChDXzEsQ18yLENfM1wpLiBFbCByZXN1bHRhZG8gZXM6CgokJApQcihYXzE9MSwgWF8yID0gMSwgWDM9MSkgXFwKPSBcc3VtX3tpPTF9XjIgXHN1bV97aj0xfV4yIFxzdW1fe2s9MX1eMiBQcihYXzEgPSAxLFhfMj0xLFhfMz0xLCBDXzEgPWksIENfMj1qLCBDXzM9aykgXFwKPSBcc3VtX3tpPTF9XjIgXHN1bV97aj0xfV4yIFxzdW1fe2s9MX1eMiBcZGVsdGFfaSBwX2koMSkgXGdhbW1hX3tpan0gcF9qKDEpIFxnYW1tYV97amt9IHBfaygxKQokJApOb3RlIHF1ZSBsYSB0cmlwbGUgc3VtYSBkZSBsYSBlY3VhY2nDs24gYW50ZXJpb3IgdGllbmUgXChtXlQ9Ml4zXCkgdMOpcm1pbm9zLCBjYWRhIGRlbCBjdWFsIGVzIHByb2R1Y3RvIGRlIFwoMlQ9MiB4IDMgXClmYWN0b3Jlcy4gUGFyYSBldmFsdWFyIGxhIHByb2JhYmlsaWRhZCByZXF1ZXJpZGEsIGxhcyBkaWZlcmVudGVzIHBvc2liaWxpZGFkZXMgcGFyYSBsb3MgdmFsb3JlcyBkZSBpLGogeSBrIHB1ZWRlbiBzZXIgbGlzdGFkb3MgeSBsYSBzdW1hIGNhbGN1bGFkYSBjb21vIGVuIGxhIHNpZ3VpZW50ZSB0YWJsYQoKCiFbUHJvYmFiaWxpZGFkIGRlIGxhIHByb2JhYmlsaWRhZCBkZSB1bmEgSE1NIEJlcm5vdWxsaV0oL1VzZXJzL2JyYWNydXovRG9jdW1lbnRzLzh2by4gVHJpbWVzdHJlIElPL1Npc3QuIEV4cGVydG9zIHkgUmVkZXMgUHJvYi4vQ0gyL1RhYmxhMi0xLnBuZykKCkxhIHN1bWEgZGUgbGEgw7psdGltYSBjb2x1bW5hIGRlIGxhIHRhYmxhIGFudGVyaW9yIG5vcyBkaWNlIHF1ZSBcKFByYShYXzE9MSxYXzI9MSxYXzM9MSk9MjkvNDhcKSAgLiBBbCBvYnNlcnZhciBub3RhbW9zIHF1ZSBlbCBlbGVtZW50byBtw6FzIGdyYW5kZSBlbiBlc2EgY29sdW1uYSBlcyAzLzg7IGxhIHNlY3VlbmNpYSBkZSBlc3RhZG9zIHF1ZSBtYXhpbWl6YSBsYSBwcm9iYWJpbGlkYWQgY29uanVudGEKCiQkUHIoWF8xID0gMSxYXzI9MSxYXzM9MSwgQ18xID1pLCBDXzI9aiwgQ18zPWspJCQKRXMgZW50b25jZXMgbGEgc2VjdWVuY2lhIFwoaT0yLGo9MixrPTJcKS4gRXF1aXZhbGVudGVtZW50ZSwgbWF4aW1pemEgbGEgcHJvYmFiaWxpZGFkIGNvbmRpY2lvbmFsIFwoUHJhKENfMT1pLENfMj1qLENfMz1rfCBYXzE9MSxYXzI9MSxYXzM9MSlcKS4KUGVybyB1bmEgbWFuZXJhIG1hcyBjb252ZW5pZW50ZSBkZSBwcmVzZW50YXIgbGEgc3VtYXIgZXMgdXRpbGl6YXIgbm90YWNpw7NuIGRlIG1hdHJpei4gRGVmaW5hbW9zIFAodSkgY29tbyBcKGRpYWcocF8xICh1KSxwXzIgKHUpKVwpLiBFbnRvbmNlcwoKJCQKUCgwKSA9IApcbGVmdChcYmVnaW57YXJyYXl9e2NjfSAKMS8yICYgMFxcIAowICYgMApcZW5ke2FycmF5fVxyaWdodCkKXHF1YWQgeSBccXVhZApQKDEpPQpcbGVmdChcYmVnaW57YXJyYXl9e2NjfSAKMS8yICYgMFxcIAowICYgMQpcZW5ke2FycmF5fVxyaWdodCkKJCQKWSBsYSB0cmlwbGUgc3VtYSBhbnRlcmlvciBwdWVkZSBzZXIgZXNjcml0YSBjb21vIGVsIHByb2R1Y3RvIGRlIHVuYSBtYXRyaXoKCiQkCs60UCgxKc6TUCgxKc6TUCgxKTEnCiQkCgojIyMjIzIuMy4yLiBMYSBwb3NpYmlsaWRhZCBlbiBnZW5lcmFsCgpBcXXDrSBjb25zaWRlcmFtb3MgbGEgcG9zaWJpbGlkYWQgZGUgdW4gSE1NIGVuIGdlbmVyYWwuIFN1cG9uZW1vcyBoYXkgdW5hIHNlY3VlbmNpYSBkZSBvYnNlcnZhY2nDs24gXCh4XzEseF8yLOKApix4X1QgXClnZW5lcmFkYSBwb3IgdGFsIG1vZGVsby4gQnVzY2Ftb3MgbGEgcHJvYmFiaWxpZGFkIFwoTF9UXCkgZGUgb2JzZXJ2YXIgZXNhIHNlY3VlbmNpYSwgc2Vnw7puIGxvIGNhbGN1bGFkbyBiYWpvIHVuIEhNTSBkZSBtLWVzdGFkb3MgZWwgY3VhbCB0aWVuZSB1bmEgZGlzdHJpYnVjacOzbiBpbmljaWFsIFwozrRcKSB5IHQucC5tLiBcKM6TXCkgcGFyYSBsYSBjYWRlbmEgZGUgTWFya292LCBmdW5jaW9uZXMgZGUgcHJvYmFiaWxpZGFkIGVzdGFkby1kZXBlbmRpZW50ZXMgXChwX2lcKS4KCiMjIyMjI1Byb3Bvc2ljaW9uIDE6IExhIHByb2JhYmlsaWRhZCBlcyBkYWRhIHBvcgokJApMX1QgPSBcZGVsdGEgUCh4XzEpXEdhbW1hIFAoeF8yKSBcR2FtbWEgUCh4XzMpIFxxdWFkIC4uLiBccXVhZCBcR2FtbWEgUCh4X1QpMScKJCQKc2kgXChcZGVsdGFcKSwgbGEgZGlzdHJpYnVjaW/Ds24gZGUgXChDXzFcKSwgc2kgZXMgdW5hIGRpc3RyaWJ1Y2lvbiBlc3RhY2lvbmFyaWEgZGUgbGEgY2FkZW5hIGRlIE1hcmtvdiwgZW50b25jZXM6CgokJApMX1QgPSBcZGVsdGEgXEdhbW1hIFAoeF8xKVxHYW1tYSBQKHhfMikgXEdhbW1hIFAoeF8zKSBccXVhZCAuLi4gXHF1YWQgXEdhbW1hIFAoeF9UKTEnCiQkCgoKVW5hIHNpbXBsZSBwZXJvIGNydWNpYWwgY29uc2VjdWVuY2lhIGRlIGxhIGV4cHJlc2nDs24gbWF0cmljaWFsIHBhcmEgbGEgcG9zaWJpbGlkYWQgZXMgZWwg4oCcYWxnb3JpdG1vIGRlIGF2YW5jZeKAnSBwYXJhIGNvbXB1dGFjacOzbiByZWN1cnNpdmEgZGUgbGEgcG9zaWJpbGlkYWQuIFRhbCBjb21wdXRhY2nDs24gcmVjdXJzaXZhIGp1ZWdhIHVuIHJvbCBjbGF2ZSwgbm8gc29sbyBlbiBldmFsdWFjacOzbiBkZSBsYSBwb3NpYmlsaWRhZCB5IHBvciB0YW50byBlc3RpbWFjacOzbiBkZSBwYXLDoW1ldHJvcywgcGVybyB0YW1iacOpbiBlbiBwcmVkZWNpciwgZGVjb2RpZmljYXIgeSByZXZpc2FyIG1vZGVsb3MuIExhIG5hdHVyYWxlemEgcmVjdXJzaXZhIGRlIHRhbCBldmFsdWFjacOzbiBkZSBwb3NpYmlsaWRhZCB2w61hIGxhIFByb3Bvc2ljacOzbiAxIGVzIGNvbXB1dGFjaW9uYWxtZW50ZSBtdWNobyBtYXMgZWZlY3Rpdm8gcXVlIHN1bWEgZGUgZnVlcnphIGJydXRhIHNvYnJlIHRvZGFzIGxhcyBzZWN1ZW5jaWFzIGRlIGVzdGFkbyBwb3NpYmxlLiBFbCBoZWNobyBxdWUgdGFsZXMgZXNxdWVtYXMgY29tcHV0YWNpb25hbGVzIHJlY3Vyc2l2b3Mgbm8gY29zdG9zb3MgcHVlZGVuIHNlciB1dGlsaXphZG9zIHBhcmEgYWJvcmRhciB2YXJpYXMgcHJlZ3VudGFzIGRlIGludGVyw6lzIGVzIHVuYSBjYXJhY3RlcsOtc3RpY2EgY2xhdmUgZGUgbG9zIEhNTXMuClBhcmEgZGVmaW5pciBlbCBhbGdvcml0bW8gZGUgYXZhbmNlLCBkZWZpbmltb3MgZWwgdmVjdG9yIFwozrFfdFwpIHBhcmEgXCh0PTEsMizigKYsVFwpLCBwb3IKCiQkClxhbHBoYV90ID0gXGRlbHRhIFAoeF8xKVxHYW1tYSBQKHhfMikgXEdhbW1hIFAoeF8zKSBccXVhZCAuLi4gXHF1YWQgXEdhbW1hIFAoeF90KSA9IFxkZWx0YSBQKHhfMSkgXHByb2Rfe3M9Mn1edCBcR2FtbWEgUCh4X3MpCiQkCkNvbiBsYSBjb252ZW5jacOzbiBxdWUgdW4gcHJvZHVjdG8gdmFjw61vIGVzIGxhIG1hdHJpeiBpZGVudGlkYWQuIFNpZ3VlIGlubWVkaWF0YW1lbnRlIGRlIGVzdGEgZGVmaW5pY2nDs24gcXVlCgokJApMX1QgPSBcYWxwaGFfVCAxJyBccXVhZCB5IFxxdWFkIFxhbHBoYV90ID0gXGFscGhhX3t0LTF9IFxHYW1tYSBQKHhfdCkgXHF1YWQgcGFyYSBccXVhZCB0IFxnZSAyCiQkCkFjb3JkZW1lbnRlLCBwb2RlbW9zIGNvbnZlbmllbnRlbWVudGUgZmlqYXIgY29tbyBzaWd1ZSBsYXMgY29tcHV0YWNpb25lcyBpbnZvbHVjcmFkYXMgZW4gbGEgZsOzcm11bGEgZGUgcG9zaWJpbGlkYWQKCiQkClxhbHBoYV8xID0gXGRlbHRhIFAoeF8xKSBcXApcYWxwaGFfdCA9IFxhbHBoYV97dC0xfSBcR2FtbWEgUCh4X3QpIFxxdWFkIHBhcmEgXHF1YWQgdCA9MiwzLC4uLixUIFxcCkxfVCA9IFxhbHBoYV9UIDEnCiQkCgpFbCBuw7ptZXJvIGRlIG9wZXJhY2lvbmVzIGludm9sdWNyYWRhcyBlcyBkZSBvcmRlbiBcKFRtXjJcKSBwdWVkZSBzZXIgZGVkdWNpZG8gYXPDrS4gUGFyYSBjYWRhIHVubyBkZSBsb3MgdmFsb3JlcyBkZSB0IGVuIGVsIGNpY2xvLCBoYXkgbSBlbGVtZW50b3MgZGUgXCjOsV90XCkgcG9yIHNlciBjb21wdXRhZG9zLCB5IGNhZGEgdW5vIGRlIGVzb3MgZWxlbWVudG9zIGVzIHVuYSBzdW1hIGRlIG0gcHJvZHVjdG9zIGRlIHRyZXMgY2FudGlkYWRlczogdW4gZWxlbWVudG8gZGUgXCjOsV97dC0xfVwpLCB1bmEgcHJvYmFiaWxpZGFkIGRlIHRyYW5zaWNpw7NuIFwozrNfe2lqfVwpLCB5IHVuYSBwcm9iYWJpbGlkYWQgKG8gZGVuc2lkYWQpIGVzdGFkby1kZXBlbmRpZW50ZSBcKHBfaiAoeF90KVwpLgoKRWwgZXNxdWVtYSBkZSBjb3JyZXNwb25kaWVudGUgcGFyYSBsYSBjb21wdXRhY2nDs24gZGUgbGEgUHJvcHVlc3RhIDEgZXMKCiQkClxhbHBoYV8wID0gXGRlbHRhIFxcClxhbHBoYV90ID0gXGFscGhhX3t0LTF9IFxHYW1tYSBQKHhfdCkgXHF1YWQgcGFyYSBccXVhZCB0ID0xLDIsLi4uLFQgXFwKTF9UID0gXGFscGhhX1QgMScKJCQKTG9zIGVsZW1lbnRvcyBkZWwgdmVjdG9yIFwozrFfdFwpIHNvbiB1c3VhbG1lbnRlIHJlZmVyaWRvcyBjb21vIHByb2JhYmlsaWRhZGVzIGRlIGF2YW5jZTsgZG9uZGUgbW9zdHJhbW9zIHF1ZSBlbCBqLWVzaW1vIGVsZW1lbnRvIGRlIFwozrFfdFwpIGVzIFwoUHJhKFheeyh0KX09eF57KHQpfSxDX3Q9alwpLgpBIGNvbnRpbnVhY2nDs24sIG1vc3RyYW1vcyBjw7NkaWdvIGRlIFIgcXVlIHV0aWxpemEgZWwgYWxnb3JpdG1vIGRlIGF2YW5jZSBwYXJhIGV2YWx1YXIgbGEgcG9zaWJpbGlkYWQgZGUgb2JzZXJ2YWNpb25lcyBcKHhfMSzigKZ4X1RcKSBiYWpvIHVuIEhNTSBkZSBQb2lzc29uIGNvbiBwb3IgbG8gbWVub3MgZG9zIGVzdGFkb3MsIHQucC5tLiBcKM6TXCksIHZlY3RvciBkZSBtZWRpYXMgZXN0YWRvLWRlcGVuZGllbnRlcyBcKM67XCksIHkgZGlzdHJpYnVjacOzbiBpbmljaWFsIFwozrRcKS4KCgpgYGB7cn0KYWxwaGEgPC0gZGVsdGEqZHBvaXMoeFsxXSwgbGFtYmRhKQpmb3IoaSBpbiAyOlQpIAogIGFscGhhIDwtICUqJSBHYW1tYSpkcG9pcyh4W2ldLGxhbWJkYSkKc3VtKGFscGhhKQpgYGAKCgpFbiBsYSBkaXNjdXNpw7NuIHN1cGVyaW9yIGhlbW9zIHV0aWxpemFkbyBsYSBleHByZXNpw7NuIGRlIG3Dumx0aXBsZXMgc3VtYXMgcGFyYSBsYSBwb3NpYmlsaWRhZCBwYXJhIGFzw60gbGxlZ2FyIGEgbGEgZXhwcmVzacOzbiBtYXRyaWNpYWwsIHkgbHVlZ28gdXRpbGl6YWRvIGxhIGV4cHJlc2nDs24gbWF0cmljaWFsIHBhcmEgbGxlZ2FyIGEgbGEgcmVjdXJzacOzbiBkZSBhdmFuY2UuIFVuYSBydXRhIGFsdGVybmF0aXZhIGVzIGRlZmluaXIgZWwgdmVjdG9yIGRlIGF2YW5jZSBkZSBwcm9iYWJpbGlkYWRlcyBcKM6xX3RcKSBwb3IKCiQkClxhbHBoYV90KGopID0gUHIoWF57KHQpfSA9IHheeyh0KX0sIENfdCA9IGopLCBqPTEsMiwuLi4sbQokJApZIGx1ZWdvIGRlZHVjaXIgbGEgcmVjdXJzacOzbiBkZSBhdmFuY2UKCiQkClxhbHBoYV90ID0gXGFscGhhX3t0LTF9IFxHYW1tYSBQKHhfdCkKJCQKTGEgZXhwcmVzacOzbiBtYXRyaWNpYWwgZXMgZW50b25jZXMgdW5hIHNpbXBsZSBjb25zZWN1ZW5jaWEgZGUgbGEgcmVjdXJzacOzbiBkZSBhdmFuY2UuCgojIyMjIzIuMy4zIEhNTXMgbm8gc29uIHByb2Nlc29zIGRlIE1hcmtvdgpITU1zIG5vIHNhdGlzZmFjZW4gZW4gZ2VuZXJhbCBsYSBwcm9waWVkYWQgZGUgTWFya292LiBFc3RvIGxvIHBvZGVtb3MgZGVtb3N0cmFyIG1lZGlhbnRlIHVuIHNpbXBsZSBjb250cmFqZW1wbG8uCkJhc2FkbyBlbiBsYSBzZWNjaW9uIDIuMy4xIHNhYmVtb3MgcXVlOgoKJCQKUHIoWF8xPTEsWF8yPTEsWF8zPTEpID0gXGZyYWN7Mjl9ezQ4fSBcXApQcihYXzI9MSkgPSBcZnJhY3s1fXs2fSBcXCBlbnRvbmNlcyBcXApQcihYXzEsWF8yPTEpID0gUHIoWF8yPTEsWF8zPTEpID0gXGZyYWN7MTd9ezI0fSBcXApwb3IgXHF1YWQgdGFudG8gXHF1YWQgc2VccXVhZCAgZGVkdWNlXHF1YWQgIHF1ZSBcXApQcihYXzM9MSB8IFhfMT0xLFhfMj0xKSA9IFxmcmFje1ByKFhfMT0xLFhfMj0xLFhfMz0xKX17UHIoWF8xPTEsWF8yPTEpfSA9IFxmcmFjezI5LzQ4fXsxNy8yNH0gXFwgCnkgXHF1YWQgZXNvIFxcClByKFhfMz0xfFhfMj0xKSA9IFxmcmFje1ByKFhfMj0xLFhfMz0xKX17UHIoWF8yPTEpfSA9IFxmcmFjezE3LzI0fXs1LzZ9ID0gMTcvMjAKJCQKClBvciBsbyB0YW50byBcKFByYShYXzM9MXxYXzI9MSniiaBQcmEoWF8zPTF8WF8xPTEsWF8yPTFcKTsgZXN0ZSBITU0gbm8gc2F0aXNmYWNlIGxhIHByb3BpZWRhZCBkZSBNYXJrb3YuIFBhcmEgbGFzIGNvbmRpY2lvbmVzIGJham8gbGFzIGN1YWxlcyB1biBITU0gc2kgc2F0aXNmYWNlIGxhIHByb3BpZWRhZCBkZSBNYXJrb3YuCgoKIyMjIyMyLjMuNC4gTGEgcG9zaWJpbGlkYWQgY3VhbmRvIGhheSBkYXRvcyBmYWx0YW50ZXMKCkVuIGVsIGNvbnRleHRvIGRlIHVuYSBzZXJpZSBkZSB0aWVtcG8gZXMgcG90ZW5jaWFsbWVudGUgcmFybyBzaSBhbGd1bm9zIGRlIGxvcyBkYXRvcyBmYWx0YW4uIEVuIGVsIGNhc28gZGUgc2VyaWVzIGRlIHRpZW1wbyBkZSBtb2RlbG9zIG9jdWx0b3MgZGUgTWFya292LCBzaW4gZW1iYXJnbywgZWwgYWp1c3RlIHF1ZSBzZSBuZWNlc2l0YSBzZXIgcmVhbGl6YWRvIHBhcmEgbGEgY29tcHV0YWNpw7NuIGRlIGxhIHBvc2liaWxpZGFkIHNpIGhheSBkYXRvcyBmYWx0YW50ZXMgcmVzdWx0YSBzZXIgdW5vIGbDoWNpbC4KU3Vwb25nYSwgcG9yIGVqZW1wbG8sIHF1ZSB1bm8gdGllbmUgZGlzcG9uaWJsZSBsYXMgb2JzZXJ2YWNpb25lcyBcKHhfMSx4XzIseF80LHhfNyx4Xzgs4oCmLHhfVFwpIGRlIHVuIEhNTSBwZXJvIFwoeF8zLHhfNSBccXVhZCB5IFxxdWFkIHhfNiBcKWhhY2VuIGZhbHRhLiBFbnRvbmNlcyBsYSBwb3NpYmlsaWRhZCBkZSBsYXMgb2JzZXJ2YWNpb25lcyBlc3RhIGRhZGEgcG9yCgokJApQcihYXzE9eDEsWF8yPXgyLFhfND14XzQsWF83PXhfNyxYXzg9eF84LC4uLiwsWF9UPXhfVCkgPSBcXApcc3VtIFxkZWx0YV97Y18xfVxnYW1tYV97YzEsYzJ9XGdhbW1hX3tjMixjNH0oMikgIFxnYW1tYV97YzQsYzd9ICgzKSBcZ2FtbWFfe2M3LGM4fSBccXVhZCAuLi4gXHF1YWQgXGdhbW1hX3tjX3tULTF9LGNfVH0gXFwKXHRpbWVzIHBfe2NfMX0gKHhfMSkgcF97YzJ9KHhfMikgcF97YzR9KHhfNCkgcF97Yzd9KHhfNylccXVhZCAuLi4gXHF1YWQgIHBfe2NfVH0oeF9UKQokJAoKRG9uZGUgKGNvbW8gYW50ZXMpICBcKM6zX3tpan0gKGspXCkgZGVub3RhIHVuYSBwcm9iYWJpbGlkYWQgZGUgdHJhbnNpY2nDs24gZGUgcGFzbyBrLCB5IGxhIHN1bWEgc2UgdG9tYSBzb2JyZSB0b2RvcyBsb3Mgw61uZGljZXMgXChjX3RcKSBkaWZlcmVudGVzIGRlIFwoY18zLGNfNSB5IGNfNlwpLiBQZXJvIGVzdG8gZXMgc29sYW1lbnRlCgokJApcc3VtIFxkZWx0YV97Y18xfSBwX3tjXzF9ICh4XzEpIFxnYW1tYV97Y18xfSxjXzJwX3tjXzJ9ICh4XzIpIFxnYW1tYV97Y18yfSxjXzQoMilwX3tjXzR9ICh4XzQpIFxnYW1tYV97Y180fSxjXzcoMylwX3tjXzd9ICh4XzcpIFxnYW1tYV97Y183fSBccXVhZCBcdGltZXMuLi5cdGltZXMgXHF1YWQgXGdhbW1hX3tjX1QtMX0sIGNfVCBwX3tjX1R9KHhfVCk9IFxcClxkZWx0YSBQKHhfMSkgXEdhbW1hIFAoeF8yKVxHYW1tYV4yIFAoeF80KSBcR2FtbWFeMyBQKHhfNykuLi5cR2FtbWEgUCh4X1QpMScKJCQKCkNvbiBcKExfVF57LSgzLDUsNil9XCkgZGVub3RhbmRvIGxhIHBvc2liaWxpZGFkIGRlIGxhcyBvYnNlcnZhY2lvbmVzIChkaWZlcmVudGVzIGRlIGxhcyBmYWx0YW50ZXMpLCBzZSBkZWNsYXJhIHF1ZQoKJCQKTF9UXnstKDMsNSw2KX0gPSBQKHhfMSkgXEdhbW1hIFAoeF8yKVxHYW1tYV4yIFAoeF80KSBcR2FtbWFeMyBQKHhfNykuLi5cR2FtbWEgUCh4X1QpMScKJCQKCkVuIGdlbmVyYWwsIGxhIGV4cHJlc2nDs24gcGFyYSBsYSBwb3NpYmlsaWRhZCBkZSBtYXRyaWNlcyBkaWFnb25hbGVzIFwoUCh4X3QpXCkgY29ycmVzcG9uZGllbnRlIGEgbGFzIG9ic2VydmFjaW9uZXMgZmFsdGFudGVzIFwoeF90XCkgc29uIHJlbXBsYXphZGFzIHBvciBsYSBtYXRyaXogaWRlbnRpZGFkOyBlc28gZXMsIGxhcyBwcm9iYWJpbGlkYWRlcyBlc3RhZG8tZGVwZW5kaWVudGVzIGNvcnJlc3BvbmRpZW50ZXMgXChwX2kgKHhfdCApXCkgc29uIHJlbXBsYXphZGFzIHBvciAxIHBhcmEgdG9kb3MgbG9zIGVzdGFkb3MgaS4KCgojIyMjIzIuMy41LiBMYSBwb3NpYmlsaWRhZCBjdWFuZG8gbGFzIG9ic2VydmFjaW9uZXMgc29uIGNlbnNvcmFkYXMgcG9yIGludGVydmFsbwoKU3Vwb25nYSBxdWUgZGVzZWFtb3MgYWp1c3RhciB1biBITU0gZGUgUG9pc3NvbiBhIHVuYSBzZXJpZSBkZSBjdWVudGFzLCBhbGd1bmFzIGRlIGxhcyBjdWFsZXMgc29uIGNlbnNvcmFkYXMgcG9yIGludGVydmFsby4gUG9yIGVqZW1wbG8sIGVsIHZhbG9yIGRlIFwoeF90XCkgcHVlZGUgc2VyIGNvbm9jaWRvIHBhcmEgXCg04omkdOKJpFRcKSwgY29uIGxhIGluZm9ybWFjacOzbiBcKHhfMeKJpDUsMuKJpHhfMuKJpDNcKSB5IFwoeF8zPjEwXCkgZGlzcG9uaWJsZSBhY2VyY2EgZGUgbGFzIG9ic2VydmFjaW9uZXMgcmVzdGFudGVzLiBQYXJhIHNpbXBsaWZpY2FyLCBhc3VtYW1vcyBkZSBwcmltZXJvIHF1ZSBsYSBjYWRlbmEgZGUgTWFya292IHNvbG8gdGllbmUgZG9zIGVzdGFkb3MuIEVuIGVzZSBjYXNvLCB1bm8gcmVtcGxhemEgbGFzIG1hdHJpY2VzIGRpYWdvbmFsZXMgXChQKHhfaSApKGk9MSwyLDMpXCkgZW4gbGEgZXhwcmVzacOzbiBkZSBwb3NpYmlsaWRhZCBwb3IgbGFzIG1hdHJpY2VzCgokJApkaWFnKFByKFhfMSBcbGUgfENfMSA9MSksIFByKFhfMSBcbGUgNXwgQ18xPTIpKSwgXFwKZGlhZyhQcigyIFxsZSBYXzIgXGxlIDMgfCBDXzI9MSksUHIoMiBcbGUgWF8yIFxsZSAzIHwgQ18yPTIpKSBcXApkaWFnKFByKFhfMyBcZ3QgMTAgfCBDXzMgPSAxKSwgUHIoWF8zIFxndCAxMCB8IENfMyA9IDIpKQokJAoKCk1hcyBnZW5lcmFsbWVudGUsIHN1cG9uZ2EgcXVlIFwoYeKJpHhfdOKJpGJcKSBkb25kZSBhIHB1ZWRlIHNlciBcKC3iiJ5cKSAoYXVucXVlIGVzbyBubyBlcyByZWxldmFudGUgcGFyYSBlbCBjYXNvIGRlIFBvaXNzb24pLCBiIHB1ZWRlIHNlciBcKOKInlwpLCB5IGxhIGNhZGVuYSBkZSBNYXJrb3YgdGllbmUgbSBlc3RhZG9zLiBVbm8gcmVtcGxhemEgXChQKHhfdClcKSBlbiBsYSBwb3NpYmlsaWRhZCBwb3IgbGEgbWF0cml6IGRpYWdvbmFsIFwobcOXbVwpIGRlIGxhIGN1YWwgZWwgZWxlbWVudG8gZGlhZ29uYWwgaS1lc2ltbyBlcyBcKFByYShh4omkWF904omkYnxDX3Q9aSlcKQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyNDYXDDrXR1bG8gMzogRXN0aW1hY2nDs24gZGUgbGEgcG9zaWJpbGlkYWQgcG9yIG1heGltaXphY2nDs24gZGlyZWN0YQoKCiMjIzMuMS4gSW50cm9kdWNjacOzbgpWaW1vcyBhbnRlcmlvcm1lbnRlIHF1ZSBsYSBwb3NpYmlsaWRhZCBkZSB1biBITU0gZXN0w6EgZGFkYSBwb3IKCiQkCkxfVCA9ICBQcihYXnsoVCl9ID0geF57KFQpfSkgPSBcZGVsdGEgUCh4XzEpIFxHYW1tYSBQKHhfMikuLi4gXEdhbW1hIFAoeF9UKTEnCiQkCkRvbmRlIFwozrRcKSBlcyBsYSBkaXN0cmlidWNpw7NuIGluaWNpYWwgeSBQKHgpIGxhIG1hdHJpeiBkaWFnb25hbCBtw5dtIGNvbiBzdSBpLWVzaW1vIGVsZW1lbnRvIGRpYWdvbmFsIHNpZW5kbyBsYSBwcm9iYWJpbGlkYWQgZXN0YWRvLWRlcGVuZGllbnRlIG8gZGVuc2lkYWQgXChwX2kgKHgpXCkuIEVuIHByaW5jaXBpbywgcG9kZW1vcyBlbnRvbmNlcyBjb21wdXRhciBcKExfVD3OsV9UIDEnXCkgcmVjdXJzaXZhbWVudGUgbWVkaWFudGVEb25kZSBcKM60XCkgZXMgbGEgZGlzdHJpYnVjacOzbiBpbmljaWFsIHkgUCh4KSBsYSBtYXRyaXogZGlhZ29uYWwgbcOXbSBjb24gc3UgaS1lc2ltbyBlbGVtZW50byBkaWFnb25hbCBzaWVuZG8gbGEgcHJvYmFiaWxpZGFkIGVzdGFkby1kZXBlbmRpZW50ZSBvIGRlbnNpZGFkIFwocF9pICh4KVwpLiBFbiBwcmluY2lwaW8sIHBvZGVtb3MgZW50b25jZXMgY29tcHV0YXIgXChMX1Q9zrFfVCAxJ1wpIHJlY3Vyc2l2YW1lbnRlIG1lZGlhbnRlCgokJApcYWxwaGFfMSA9IFxkZWx0YSBQKHhfMSkgXFwKeVxcClxhbHBoYV90ID0gXGFscGhhX3t0LTF9IFxHYW1tYSBQKHhfdCksIHBhcmEgXHF1YWQgdD0yLDMsLi4uLFQKJCQKClNpIHNlIGFzdW1lIHF1ZSBsYSBjYWRlbmEgZGUgTWFya292IGVzIGVzdGFjaW9uYXJpYSAoZW4gY3V5byBjYXNvIFwozrQ9zrTOk1wpLCBwb2RlbW9zIGVuIHZleiB1c2FyCgokJApcYWxwaGFfMCA9IFxkZWx0YSBcXAp5XFwKXGFscGhhX3QgPSBcYWxwaGFfe3QtMX0gXEdhbW1hIFAoeF90KS4gcGFyYVxxdWFkIHQ9MSwyLC4uLixUCiQkCgpQcmltZXJvIGNvbnNpZGVyYXJlbW9zIGVsIGNhc28gZXN0YWNpb25hcmlvLgoKRWwgbsO6bWVybyBkZSBvcGVyYWNpb25lcyBpbnZvbHVjcmFkYXMgZXMgZGUgb3JkZW4gXChUbV4yXCksIGhhY2llbmRvIGxhIGV2YWx1YWNpw7NuIGRlIGxhIHBvc2liaWxpZGFkIGJhc3RhbnRlIGZhY3RpYmxlIGluY2x1c28gcGFyYSB1biBncmFuIFQuIExhIGVzdGltYWNpw7NuIGRlIHBhcsOhbWV0cm9zIHB1ZWRlIHNlciBlbnRvbmNlcyByZWFsaXphZGEgcG9yIG1heGltaXphY2nDs24gbnVtw6lyaWNhIGRlIGxhIHBvc2liaWxpZGFkIHJlc3BlY3RvIGEgbG9zIHBhcsOhbWV0cm9zLgpQZXJvIGV4aXN0ZW4gYWxndW5vcyBwcm9ibGVtYXMgcXVlIG5lY2VzaXRhbiBzZXIgYWJvcmRhZG9zIGN1YW5kbyBsb3MgcGFyw6FtZXRyb3Mgc29uIGVzdGltYWRvcyBkZSBlc3RhIG1hbmVyYS4gTG9zIHByb2JsZW1hcyBwcmluY2lwYWxlcyBzb24gZWwgZGVzYm9yZGFtaWVudG8gbnVtw6lyaWNvLCByZXN0cmljY2lvbmVzIGVuIGxvcyBwYXLDoW1ldHJvcywgeSBtw7psdGlwbGVzIG3DoXhpbW9zIGxvY2FsZXMgZW4gbGEgZnVuY2nDs24gZGUgcG9zaWJpbGlkYWQuIAoKIyMjMy4yLiBFc2NhbGFuZG8gbGEgY29tcHV0YWNpw7NuIGRlIGxhIHBvc2liaWxpZGFkCgpFbiBlbCBjYXNvIGRlIGRpc3RyaWJ1Y2lvbmVzIGVzdGFkby1kZXBlbmRpZW50ZXMgZGlzY3JldGFzLCBsb3MgZWxlbWVudG9zIGRlIFwozrFfdFwpLCBzaWVuZG8gcHJvZHVjdG9zIGRlIHByb2JhYmlsaWRhZGVzLCBzZSB2dWVsdmVuIHByb2dyZXNpdmFtZW50ZSBtw6FzIHBlcXVlw7FvIGNvbmZvcm1lIHQgaW5jcmVtZW50ZSwgeSBzb24gZXZlbnR1YWxtZW50ZSByZWRvbmRlYWRvcyBhIGNlcm8uIERlIGhlY2hvLCBjb24gdW5hIHByb2JhYmlsaWRhZCBkZSAxLCBsYSBwb3NpYmlsaWRhZCBzZSBhY2VyY2EgYSAwIChvIHBvc2libGVtZW50ZSBcKOKInlwpIGVuIGVsIGNhc28gY29udGludW8pIGV4cG9uZW5jaWFsbWVudGUgcsOhcGlkby4KRGVzZGUgcXVlIGxhIHBvc2liaWxpZGFkIGVzIHVuIHByb2R1Y3RvIGRlIG1hdHJpY2VzLCBubyBlc2NhbGFyZXMsIG5vIGVzIHBvc2libGUgZXZpdGFyIGVsIGRlc2JvcmRhbWllbnRvIG51bWVybyBzaW1wbGVtZW50ZSBhbCBjb21wdXRhciBlbCByZWdpc3RybyBkZSBsYSBwb3NpYmlsaWRhZCBjb21vIGxhIHN1bWEgZGUgbG9zIHJlZ2lzdHJvcyBkZSBzdXMgZmFjdG9yZXMuIEVuIGVzdGUgY2FzbywgbGEgY29tcHV0YWNpw7NuIGRlIGxhIHBvc2liaWxpZGFkIGRlIHVuIG1vZGVsbyBkZSBtZXpjbGEgaW5kZXBlbmRpZW50ZSBlcyBtw6FzIGbDoWNpbCBxdWUgZWwgZGUgdW4gSE1NLgpQYXJhIHJlc29sdmVyIGVzdGUgcHJvYmxlbWEsIER1cmJpbiAoMTk5OCwgcC4gNzgpIHN1Z2llcmUgdW4gbcOpdG9kbyBkZSBjb21wdXRhY2nDs24gcXVlIGN1ZW50YSBjb24gbGEgc2lndWllbnRlIGFwcm94aW1hY2nDs24uIFN1cG9uZ2EgcXVlIGRlc2VhbW9zIGNvbXB1dGFyIFwobG9nKHArcSlcKSwgZG9uZGVcKHA+cVwpLiBFc2NyaWJhIFwobG9nKHArcSlcKSBjb21vCiQkCmxvZyhwKStsb2coMStxL3ApPWxvZyhwKStsb2coMStleHAoccyDLXAgzIMpKQokJAosIGRvbmRlIFwocCDMgz1sb2cocCkgXHF1YWQgeSBccXVhZCBxIMyDPWxvZyhxKVwpLiBMYSBmdW5jacOzbgpcKGxvZygxK2VeeClcKSBlcyBlbnRvbmNlcyBhcHJveGltYWRhIHBvciBpbnRlcnBvbGFjacOzbiBkZSB1bmEgdGFibGEgZGUgc3VzIHZhbG9yZXM7IGFwYXJlbnRlbWVudGUgdGFsIHBlcXVlw7FhIHRhYmxhIGRhcsOhIHVuIGdyYWRvIHJhem9uYWJsZSBkZSBleGFjdGl0dWQuClByZWZlcmltb3MgY29tcHV0YXIgZWwgbG9nYXJpdG1vIGRlIFwoTF9UXCkgYWwgdXNhciB1bmEgZXN0cmF0ZWdpYSBkZSBlc2NhbGFyIGVsIHZlY3RvciBkZSBwcm9iYWJpbGlkYWRlcyBkZSBhdmFuY2UgXCjOsV90XCkuIEVmZWN0aXZhbWVudGUgZXNjYWxhbW9zIGVsIHZlY3RvciBcKM6xX3RcKSBlbiBjYWRhIHRpZW1wbyB0IHBhcmEgcXVlIHN1cyBlbGVtZW50b3Mgc3VtZW4gYSAxLCBsbGV2YW5kbyByw6ljb3JkIGRlIGxhIHN1bWEgZGUgbG9zIHJlZ2lzdHJvcyBkZSBsb3MgZmFjdG9yZXMgZGUgZXNjYWxhIGFwbGljYWRvcy4KRGVmaW5hLCBwYXJhIFwodD0wLDEs4oCmLFRcKSBlbCB2ZWN0b3IKCiQkIFxwaGlfdCA9XGFscGhhX3Qvd190JCQKCkRvbmRlIFwod190PVxzdW1faSDOsV90IChpKT3OsV90IDEnXCkuIFByaW1lcm8sIG5vdGFtb3MgY2llcnRhcyBjb25zZWN1ZW5jaWFzIGlubWVkaWF0YXMgZGUgbGFzIGRlZmluaWNpb25lcyBkZSBcKM+VX3RcKSB5IFwod190XCk6CgokJAp3X28gPSBcYWxwaGFfMDEnID0gXGRlbHRhMScgPSAxIFxcClxwaGlfMCA9IFxkZWx0YSBcXAp3X3QgXHBoaV90ID0gd197dC0xfSBccGhpX3t0LTF9IFxHYW1tYSBQKHhfdCkgXFwKTF9UID0gXGFscGhhX1QgMScgPSB3X1QoXHBoaV9UIDEnKSA9IHdfVAokJAoKUG9yIGxvIHRhbnRvIFwoTF9UPXdfVD3iiI9fe3Q9MX1eVCh3X3Qvd197dC0xfSlcKS4gWSBkZSBsYSBlY3VhY2nDs24gYW50ZXJpb3IgdGVuZW1vcyBxdWUgXCh3X3Q9d197dC0xfSAoz5Vfe3QtMX0gzpMgUCh4X3QpMScpXCksIHkgYXNpIGNvbmNsdWltb3MgcXVlCgokJApsb2dMX1QgPSBcc3VtX3t0PTF9XlQgbG9nKHdfdC93X3t0LTF9KSA9IFxzdW1fe3Q9MX1eVCBsb2coXHBoaV97dC0xfSBcR2FtbWEgUCh4X3QpIDEnKQokJAoKTGEgY29tcHV0YWNpw7NuIGRlIGxhIHBvc2liaWxpZGFkIGRlIHJlZ2lzdHJvIGVzdGEgc3VtYXJpemFkYSBhIGNvbnRpbnVhY2nDs24gZW4gbGEgZm9ybWEgZGUgdW4gYWxnb3JpdG1vLiBOb3RlIHF1ZSBcKM6TXCkgeSBcKFAoeF90KVwpIHNvbiBtYXRyaWNlcyBkZSBtw5dtLCB2IHkgXCjPlV90XCkgc29uIHZlY3RvcmVzIGRlIGxvbmdpdHVkIG0sIHUgZXMgdW4gZXNjYWxhciwgeSBsIGVzIGVsIGVzY2FsYXIgZW4gZWwgY3VhbCBsYSBwb3NpYmlsaWRhZCBkZSByZWdpc3RybyBlcyBhY3VtdWxhZGEuCgokJApccGhpXzAgXGxlZnRhcnJvdyBcZGVsdGE7IGwgXGxlZnRhcnJvdzAgXFwKZm9yIFxxdWFkIHQ9MSwyLC4uLixUIFxcCnYgXGxlZnRhcnJvdyBccGhpX3t0LTF9IFxHYW1tYSBQKHhfdCkgXFwKdSBcbGVmdGFycm93IHYxJyBcXApsIFxsZWZ0YXJyb3cgbCArIGxvZyh1KSBcXApccGhpX3QgXGxlZnRhcnJvdyB2L3UgXFwKcmV0dXJuIFxxdWFkIGwKJCQKCgpMYSBwb3NpYmlsaWRhZCBkZSByZWdpc3RybyByZXF1ZXJpZGEsIFwobG9nYShMX1QpXCksIGVzIGVudG9uY2VzIGRhZGEgcG9yIGVsIHZhbG9yIGZpbmFsIGRlIGwuIEVzdGUgcHJvY2VkaW1pZW50byBwcmV2ZW5kcsOhIGNhc2kgc2llbXByZSBkZXNib3JkYW1pZW50by4gQ2xhcmFtZW50ZSwgdmFyaWFjaW9uZXMgbWVub3JlcyBkZSBlc3RhIHTDqWNuaWNhIHNvbiBwb3NpYmxlczogZWwgZmFjdG9yIGRlIGVzY2FsYSBcKHdfdFwpIHBvZHLDrWEgc2VyIGVsZWdpZG8gZW4gbHVnYXIgcGFyYSBzZXIgZWwgZWxlbWVudG8gbcOhcyBncmFuZGUgZGVsIHZlY3RvciBzaWVuZG8gZXNjYWxhZG8sIG8gbGEgbWVkaWEgZGUgc3VzIGVsZW1lbnRvcyAob3B1ZXN0byBhIGxhIHN1bWEpLgpFbCBhbGdvcml0bW8gZXMgZsOhY2lsbWVudGUgbW9kaWZpY2FkbyBwYXJhIGNvbXB1dGFyIGxhIHBvc2liaWxpZGFkIGRlIHJlZ2lzdHJvIHNpbiBhc3VtaXIgZXN0YWNpb25hcmllZGFkIGRlIGxhIGNhZGVuYSBkZSBNYXJrb3YuIENvbiBcKM60XCkgZGVub3RhbmRvIGxhIGRpc3RyaWJ1Y2nDs24gaW5pY2lhbCwgZWwgYWxnb3JpdG1vIG3DoXMgZ2VuZXJhbCBlcwoKJCQKd18xIFxsZWZ0YXJyb3cgXGRlbHRhIFAoeF8xKSAxJyA7XHF1YWQgXHBoaV8xIFxsZWZ0YXJyb3cgXGRlbHRhIFAoeF8xKS93XzEgOyBccXVhZCBsIFxsZWZ0YXJyb3cgbG9nKHdfMSkgXFwKZm9yIFxxdWFkIHQ9MiwzLC4uLixUIFxcCnYgXGxlZnRhcnJvdyBccGhpX3t0LTF9IFxHYW1tYSBQKHhfdCkgXFwKdSBcbGVmdGFycm93IHYxJyBcXApsIFxsZWZ0YXJyb3cgbCArIGxvZyh1KVxcClxwaGlfdCBcbGVmdGFycm93IHYvdSBcXApyZXR1cm4gXHF1YWQgbAokJAoKU2kgbGEgZGlzdHJpYnVjacOzbiBpbmljaWFsIG9jdXJyZSBzZXIgbGEgZGlzdHJpYnVjacOzbiBpbmljaWFsLCBlc3RlIGFsZ29yaXRtbyB0b2RhdsOtYSBhcGxpY2EuCkVsIHNpZ3VpZW50ZSBjw7NkaWdvIGltcGxlbWVudGEgZXN0YSB1bHRpbWEgdmVyc2nDs24gZGVsIGFsZ29yaXRtbyBwYXJhIGFzaSBjb21wdXRhciBsYSBwb3NpYmlsaWRhZCBkZSByZWdpc3RybyBkZSBsYXMgb2JzZXJ2YWNpb25lcyBcKHhfMSzigKYseF9UXCkgYmFqbyB1biBITU0gZGUgUG9pc3NvbiBjb24gYWwgbWVub3MgZG9zIGVzdGFkb3MsIG1hdHJpeiBkZSBwcm9iYWJpbGlkYWQgZGUgdHJhbnNpY2nDs24gXCjOk1wpLCB2ZWN0b3IgZGUgbWVkaWFzIGVzdGFkby1kZXBlbmRpZW50ZXMgXCjOu1wpIHkgZGlzdHJpYnVjacOzbiBpbmljaWFsIFwozrRcKS4KCmBgYHtyfQphbHBoYSA8LSBkZWx0YSpkcG9pcyh4WzFdLCBsYW1iZGEpCmxzY2FsZSA8LSBsb2coc3VtKGFscGhhKSkKYWxwaGEgPC0gYWxwaGEvc3VtKGFscGhhKQpmb3IoaSBpbiAyOlQpewogIGFscGhhIDwtIGFscGhhICUqJSBHYW1tYSpkcG9pcyh4W2ldLCBsYW1iZGEpCiAgbHNjYWxlIDwtIGxzY2FsZSArIGxvZyhzdW0oYWxwaGEpKQogIGFscGhhIDwtIGFscGhhL3N1bShhbHBoYSkKfQpsc2NhbGUKYGBgCgojIyMzLjMuIE1heGltaXphY2nDs24gZGUgbGEgcG9zaWJpbGlkYWQgc3VqZXRhIGEgcmVzdHJpY2Npb25lcwojIyMjMy4zLjEgUmUgcGFyYW1ldHJpemFjacOzbiBwYXJhIGV2aXRhciByZXN0cmljY2lvbmVzCgpMb3MgZWxlbWVudG9zIGRlIFwozpNcKSB5IGFxdWVsbG9zIGRlIFwozrtcKSwgZWwgdmVjdG9yIGRlIG1lZGlhcyBlc3RhZG8tZGVwZW5kaWVudGVzIGVuIHVuIEhNTSBkZSBQb2lzc29uLCBlc3TDoW4gc3VqZXRvcyBhIG5vIG5lZ2F0aXZpZGFkIHkgb3RyYXMgcmVzdHJpY2Npb25lcy4gRW4gcGFydGljdWxhciwgbGEgc3VtYSBkZSBsYXMgZmlsYXMgZGUgXCjOk1wpIGVzIGlndWFsIGEgMS4gTG9zIGVzdGltYWRvcyBkZSBsb3MgcGFyw6FtZXRyb3MgZGViZXLDrWEgc2F0aXNmYWNlciB0YW1iacOpbiB0YWxlcyByZXN0cmljY2lvbmVzLiBQb3IgZW5kZSwgYWwgbWF4aW1pemFyIGxhIHBvc2liaWxpZGFkLCBuZWNlc2l0YW1vcyByZXNvbHZlciB1biBwcm9ibGVtYSBkZSBvcHRpbWl6YWNpw7NuIHJlc3RyaW5naWRhLgpFbiBnZW5lcmFsLCBleGlzdGVuIGRvcyBncnVwb3MgZGUgcmVzdHJpY2Npb25lczogYXF1ZWxsYXMgcXVlIGFwbGljYW4gYSBsb3MgcGFyw6FtZXRyb3MgZGUgbGFzIGRpc3RyaWJ1Y2lvbmVzIGVzdGFkby1kZXBlbmRpZW50ZXMgeSBhcXVlbGxhcyBxdWUgYXBsaWNhbiBhIGxvcyBwYXLDoW1ldHJvcyBkZSBsYSBjYWRlbmEgZGUgTWFya292LiBFbCBwcmltZXIgZ3J1cG8gZGUgcmVzdHJpY2Npb25lcyBkZXBlbmRlIGVuIGN1YWwoZXMpIGRpc3RyaWJ1Y2nDs24oZXMpIGVzdGFkby1kZXBlbmRpZW50ZShzKSBzb24gZWxlZ2lkYXMuCgpFbiBlbCBjYXNvIGRlIHVuIEhNTSBkZSBQb2lzc29uIGxhcyByZXN0cmljY2lvbmVzIHJlbGV2YW50ZXMgc29uOiAKCi0gTGFzIG1lZGlhcyBcKM67X2lcKSBkZSBsYXMgZGlzdHJpYnVjaW9uZXMgZXN0YWRvLWRlcGVuZGllbnRlcyBkZWJlbiwgcGFyYSBcKGk9MSzigKYsbVwpIHNlciBubyBuZWdhdGl2b3MuIAotIExhcyBmaWxhcyBkZSBsYSBtYXRyaXogZGUgcHJvYmFiaWxpZGFkIGRlIHRyYW5zaWNpw7NuIFwozpNcKSBkZWJlbiBzdW1hciBhIDEsIHkgdG9kb3MgbG9zIHBhcsOhbWV0cm9zIFwozrNfe2lqfVwpIGRlYmVuIHNlciBubyBuZWdhdGl2b3MuCgoKQXF1w60gbGFzIHJlc3RyaWNjaW9uZXMgcHVlZGVuIHNlciBpbXB1ZXN0YXMgYWwgaGFjZXIgdHJhbnNmb3JtYWNpb25lcy4gTGEgdHJhbnNmb3JtYWNpw7NuIGRlIGxvcyBwYXLDoW1ldHJvcyBcKM67X2lcKSBlcyBmw6FjaWwuIERlZmluYSBcKM63X2k9bG9nYSjOu19pKVwpLCBwYXJhIFwoaT0xLOKApixtXCkuIEVudG9uY2VzIFwozrdfaeKIiFJcKS4gTHVlZ28gcXVlIGhlbW9zIG1heGltaXphZG8gbGEgcG9zaWJpbGlkYWQgY29uIHJlc3BlY3RvIGEgbG9zIHBhcsOhbWV0cm9zIG5vIHJlc3RyaW5naWRvcywgbG9zIHBhcsOhbWV0cm9zIGVzdGltYWRvcyByZXN0cmluZ2lkb3MgcHVlZGVuIHNlciBvYnRlbmlkb3MgYWwgdHJhbnNmb3JtYXIgZGUgdnVlbHRhOiBcKCjOu19pICk9ZXhwYSjOt19pKSlcKS5Ob3RlIHF1ZSBcKM6TIFwpIHRpZW5lIFwobV4yXCkgZW50cmFkYXMgcGVybyBzb2xvIFwobShtLTEpXCkgcGFyYW1ldHJvcyBsaWJyZXMsIGFzaSBjb21vIGhheSBtIHJlc3RyaWNjaW9uZXMgc3VtYSBkZSBmaWxhcwoKJCQKXHN1bV97aj0xfV5tIFxnYW1tYV97aWp9ID0xIFxxdWFkIChpPTEsLi4uLG0pCiQkCgpNb3N0cmFyZW1vcyB1bmEgcG9zaWJsZSB0cmFuc2Zvcm1hY2nDs24gZW50cmUgbGFzIFwobV4yXCkgcHJvYmFiaWxpZGFkZXMgcmVzdHJpbmdpZGFzIFwozrNfe2lqfVwpIHkgXChtKG0tMSlcKSBuw7ptZXJvcyByZWFsZXMgc2luIHJlc3RyaWNjacOzbiBcKM+EX3tpan0saeKJoGpcKS4KUG9yIHJhem9uZXMgZGUgdmlzaWJpbGlkYWQgc2UgbXVlc3RyYSBlbCBjYXNvIHBhcmEgbT0zLiBFbXBlemFyZW1vcyBwb3IgZGVmaW5pciBsYSBtYXRyaXoKCiQkClxsZWZ0KFxiZWdpbnthcnJheX17Y2N9IAotICwgXHRhdV97MTJ9LFx0YXVfezEzfVxcIApcdGF1X3syMX0gLCAtICwgXHRhdV97MjN9XFwKXHRhdV97MzF9ICwgXHRhdV97MzJ9ICwgLQpcZW5ke2FycmF5fVxyaWdodCkKJCQKClVuYSBtYXRyaXogb24gXChtKG0tMSlcKSBlbnRyYWRhcyBcKM+EX3tpan3iiIhSXCkuIEFob3JhIHF1ZSBcKGc6UuKGklJeK1wpIHNlYSB1bmEgZnVuY2nDs24gZXN0cmljdGFtZW50ZSBpbmNyZW1lbnRhbCwgcG9yIGVqZW1wbG8KCiQkCmcoeCkgPSBlXnggXHF1YWQgbyBccXVhZCBnKHgpID0gClxiZWdpbntjYXNlc30KICBlXnggXHF1YWQgeCBcbGUgMCBcXCAgICAKICB4KzEgXHF1YWQgeCBcZ2UgMApcZW5ke2Nhc2VzfSBcXApEZWZpbmUgXHF1YWQgcXVlIFxcCnZfe2lqfSA9IApcYmVnaW57Y2FzZXN9CiAgZyhcdGF1X3tpan0pIFxxdWFkIHBhcmEgXHF1YWQgaSBcbmVxIGogXFwKICAxIFxxdWFkIHBhcmEgXHF1YWQgaSA9IGogClxlbmR7Y2FzZXN9CiQkCgpFbnRvbmNlcyBmaWphbW9zIFwozrNfe2lqfT12X3tpan0vXHN1bV97az0xfV5tIHZfe2lrfVwpICAocGFyYSBpLGo9MSwyLOKApixtKSB5IFwozpM9KM6zX3tpan0pXCkuIE5vcyByZWZlcmlyZW1vcyBhIGxvcyBwYXLDoW1ldHJvcyBcKM63X2lcKSB5IFwoz4Rfe2lqfVwpIGNvbW8gcGFyw6FtZXRyb3MgZnVuY2lvbmFsZXMsIHkgYSBsb3MgcGFyw6FtZXRyb3MgXCjOu19pXCkgeSBcKM6zX3tpan1cKSBjb21vIHBhcsOhbWV0cm9zIG5hdHVyYWxlcy4KCgpVc2FuZG8gbGFzIHRyYW5zZm9ybWFjaW9uZXMgYW50ZXJpb3JlcyBkZSBcKM6TXCkgeSBcKM67XCksIHBvZGVtb3MgcmVhbGl6YXIgZWwgY2FsY3VsbyBkZSBsb3MgcGFyw6FtZXRyb3MgbWF4aW1pemFudGVzIGRlIGxhIHBvc2liaWxpZGFkIGVuIGRvcyBwYXNvcwoKLSBNYXhpbWl6YXIgXChMX1RcKSBjb24gcmVzcGVjdG8gYSBsb3MgcGFyw6FtZXRyb3MgZnVuY2lvbmFsZXMgXChUPXvPhF97aWp9fVwpIHkgXCjOtz0ozrdfMSzigKYszrdfbSlcKS4gVG9kb3MgZXN0b3Mgc29uIHNpbiByZXN0cmljY2lvbmVzLgotIFRyYW5zZm9ybWFyIGxvcyBlc3RpbWFkb3MgZGUgbG9zIHBhcsOhbWV0cm9zIGZ1bmNpb25hbGVzIGEgZXN0aW1hZG9zIGRlIHBhcsOhbWV0cm9zIG5hdHVyYWxlczoKCiQkClQgXHJpZ2h0YXJyb3cgXEdhbW1hICwgXGV0YSBccmlnaHRhcnJvdyBcbGFtYmRhCiQkCgpDb25zaWRlcmUgXCjOk1wpIHBhcmEgZWwgY2FzbyBcKGcoeCk9ZV54XCkgeSBtIGdlbmVyYWwuIFRlbmVtb3MgZW50b25jZXMKCiQkClxnYW1tYV97aWp9ID0gXGZyYWN7ZXhwKFx0YXVfe2lqfSl9ezErIFxzdW1fe2sgXG5lcSBpfSBleHAoXHRhdV97aWt9KX0sXHF1YWQgcGFyYSBccXVhZCBpXG5lcSBqCiQkClkgbG9zIGVsZW1lbnRvcyBkaWFnb25hbGVzIGRlIFwozpNcKSBzaWd1ZW4gZGUgbGEgc3VtYSBkZSBmaWxhcyBkZSAxLiBMYSB0cmFuc2Zvcm1hY2nDs24gZW4gbGEgZGlyZWNjacOzbiBvcHVlc3RhIGVzCgokJApcdGF1X3tpan0gPSBsb2coXGZyYWN7XGdhbW1hX3tpan19ezEtXHN1bV97ayBcbmVxIGl9XGdhbW1hX3tpa319KSA9IGxvZyhcZ2FtbWFfe2lqfS9cZ2FtbWFfe2lpfSksXHF1YWQgcGFyYSBccXVhZCBpIFxuZXEgagokJApBaG9yYSBtb3N0cmFtb3MgdW4gY8OzZGlnbyByZWxhdGl2YW1lbnRlIHNpbXBsZSBxdWUgdHJhbnNmb3JtYXJhIHBhcsOhbWV0cm9zIG5hdHVyYWxlcyBhIGZ1bmNpb25hbGVzIHkgdmljZXZlcnNhLiBFc3RlIGPDs2RpZ28gcmVmaWVyZSBhIHVuIEhNTSBkZSBQb2lzc29uIGNvbiBtPjIgZXN0YWRvcywgZW4gZWwgY3VhbCBsYSBjYWRlbmEgZGUgTWFya292IHB1ZWRlLCBzaSBlcyBhcHJvcGlhZG8sIHNlciBhc3VtaWRhIGVzdGFjaW9uYXJpYS4gRW4gZXNlIGNhc28gbGEgZGlzdHJpYnVjacOzbiBlc3RhY2lvbmFyaWEgXCjOtFwpIG5vIGVzIGRhZGEsIHBlcm8gZXMgY29tcHV0YWRhIGN1YW5kbyBzZWEgbmVjZXNpdGFkYSBkZWwgdC5wLm0uIFwozpNcKSBhbCByZXNvbHZlciBcKM60KElfbS3OkytVKT0xXCkuIERlIG90cmEgbWFuZXJhLCBcKM60XCkgZXMgdHJhdGFkYSBjb21vIHVuIHBhcsOhbWV0cm8gKG5hdHVyYWwpIHkgdHJhbnNmb3JtYWRhIHBhcmEgYXPDrSByZW1vdmVyIGxhcyByZXN0cmljY2lvbmVzIFwozrRfaeKJpTBcKSB5IFwoXHN1bV9pzrRfaT0xXCkuCgoKYGBge3J9CiMgVHJhbnNmb3JtYXIgbG9zIHBhcsOhbWV0cm9zIG5hdHVyYWxlcyBkZSBQb2lzc29uIGVuIHBhcsOhbWV0cm9zIGRlIHRyYWJham8uCnBvaXMuSE1NLnBuMnB3IDwtIGZ1bmN0aW9uKG0sbGFtYmRhLGdhbW1hLGRlbHRhPU5VTEwsc3RhdGlvbmFyeT1UUlVFKQp7CiB0bGFtYmRhIDwtIGxvZyhsYW1iZGEpCiBmb28gICAgIDwtIGxvZyhnYW1tYS9kaWFnKGdhbW1hKSkKIHRnYW1tYSAgPC0gYXMudmVjdG9yKGZvb1shZGlhZyhtKV0pCiBpZihzdGF0aW9uYXJ5KSB7dGRlbHRhIDwtTlVMTH0gZWxzZSB7dGRlbHRhPC1sb2coZGVsdGFbLTFdL2RlbHRhWzFdKX0KIHBhcnZlY3QgPC0gYyh0bGFtYmRhLHRnYW1tYSx0ZGVsdGEpCiByZXR1cm4ocGFydmVjdCkKfQoKIyBUcmFuc2Zvcm1hciBsb3MgcGFyw6FtZXRyb3MgZGUgdHJhYmFqbyBkZSBQb2lzc29uIGVuIHBhcsOhbWV0cm9zIG5hdHVyYWxlcy4KCnBvaXMuSE1NLnB3MnBuIDwtIGZ1bmN0aW9uKG0scGFydmVjdCxzdGF0aW9uYXJ5PVRSVUUpCnsKIGxhbWJkYSAgICAgICAgPC0gZXhwKHBhcnZlY3RbMTptXSkKIGdhbW1hICAgICAgICAgPC0gZGlhZyhtKQogZ2FtbWFbIWdhbW1hXSA8LSBleHAocGFydmVjdFsobSsxKToobSptKV0pCiBnYW1tYSAgICAgICAgIDwtIGdhbW1hL2FwcGx5KGdhbW1hLDEsc3VtKQogaWYoc3RhdGlvbmFyeSkge2RlbHRhPC1zb2x2ZSh0KGRpYWcobSktZ2FtbWErMSkscmVwKDEsbSkpfSBlbHNlCiAgICAgICAgICAgICAgICB7Zm9vPC1jKDEsZXhwKHBhcnZlY3RbKG0qbSsxKToobSptK20tMSldKSkKICAgICAgICAgICAgICAgIGRlbHRhPC1mb28vc3VtKGZvbyl9CiByZXR1cm4obGlzdChsYW1iZGE9bGFtYmRhLGdhbW1hPWdhbW1hLGRlbHRhPWRlbHRhKSkKfQpgYGAKCgojIyMzLjQuIE90cm9zIHByb2JsZW1hcwojIyMjMy40LjEuIE3Dumx0aXBsZXMgbcOheGltb3MgZW4gbGEgcG9zaWJpbGlkYWQKCkxhIHBvc2liaWxpZGFkIGRlIHVuIEhNTSBlcyB1bmEgZnVuY2nDs24gY29tcGxpY2FkYSBkZSBsb3MgcGFyw6FtZXRyb3MgeSBmcmVjdWVudGVtZW50ZSB0aWVuZSB2YXJpb3MgbcOheGltb3MgbG9jYWxlcy4gTGEgbWV0YSBwb3Igc3VwdWVzdG8gZXMgZW5jb250cmFyIGVsIG3DoXhpbW8gZ2xvYmFsLCBwZXJvIG5vIGhheSB1biBtw6l0b2RvIHNpbXBsZSBkZSBkZXRlcm1pbmFyIGVuIGdlbmVyYWwgc2kgdW4gYWxnb3JpdG1vIGRlIG1heGltaXphY2nDs24gbnVtw6lyaWNhIGhhIGFsY2FuemFkbyBlbCBtw6F4aW1vIGdsb2JhbC4gRGVwZW5kaWVuZG8gZGUgbG9zIHZhbG9yZXMgaW5pY2lhbGVzLCBwdWVkZSBzdWNlZGVyIHF1ZSBlbCBhbGdvcml0bW8gZsOhY2lsbWVudGUgaWRlbnRpZmlxdWUgdW4gbG9jYWwsIHBlcm8gbm8gZWwgbcOheGltbywgZ2xvYmFsLiBFc3RvIHRhbWJpw6luIGFwbGljYSBhbCBwcmluY2lwYWwgbcOpdG9kbyBhbHRlcm5vIGRlIGVzdGltYWNpw7NuLCBlbCBhbGdvcml0bW8gRU0uIFVuYSBlc3RyYXRlZ2lhIHNlbnNpYmxlIGVudG9uY2VzIGVzIHVzYXIgdW4gcmFuZ28gZGUgdmFsb3JlcyBpbmljaWFsZXMgcGFyYSBsYSBtYXhpbWl6YWNpw7NuLCB5IHZlciBzaSBlbCBtaXNtbyBtw6F4aW1vIGVzIGlkZW50aWZpY2FkbyBlbiBjYWRhIGNhc28uCgojIyMjMy40LjIuIFZhbG9yZXMgaW5pY2lhbGVzIHBhcmEgbGFzIGl0ZXJhY2lvbmVzCgpFcyBhIG1lbnVkbyBmw6FjaWwgZWwgZW5jb250cmFyIHBvc2libGVzIHZhbG9yZXMgaW5pY2lhbGVzIHBhcmEgYWxndW5vcyBkZSBsb3MgcGFyw6FtZXRyb3MgZGUgdW4gSE1NOiBwb3IgZWplbXBsbywgc2kgdW5vIGJ1c2NhIGVsIGZpamFyIHVuIEhNTSBkZSBQb2lzc29uIGNvbiBkb3MgZXN0YWRvcywgeSBsYSBtZWRpYSBkZSBtdWVzdHJhIGVzIDEwLCB1bm8gcG9kcsOtYSBwcm9iYXIgOCB5IDEyLCBvIDUgeSAxNSwgcGFyYSBsb3MgdmFsb3JlcyBkZSBsYXMgZG9zIG1lZGlhcyBlc3RhZG8tZGVwZW5kaWVudGVzLiBFc3RyYXRlZ2lhcyBtYXMgc2lzdGVtw6F0aWNhcyBiYXNhZGFzIGVuIGxvcyBjdWFudGlsZXMgZGUgbGFzIG9ic2VydmFjaW9uZXMgc29uIHBvc2libGVzLCBzaW4gZW1iYXJnby4gUG9yIGVqZW1wbG8sIHNpIGVsIG1vZGVsbyB0aWVuZSB0cmVzIGVzdGFkb3MsIHVzZSBjb21vIGxvcyB2YWxvcmVzIGluaWNpYWxlcyBkZSBsYXMgbWVkaWFzIGVzdGFkby1kZXBlbmRpZW50ZXMgZWwgY3VhcnRpbCBtZW5vciwgbWVkaWFubyB5IGN1YXJ0aWwgc3VwZXJpb3IgZGUgbGFzIGN1ZW50YXMgb2JzZXJ2YWRhcy4KRXMgbWVub3MgZsOhY2lsIGVsIGFkaXZpbmFyIHZhbG9yZXMgZGUgbGFzIHByb2JhYmlsaWRhZGVzIGRlIHRyYW5zaWNpw7NuIFwozrNfe2lqfVwpLiBVbmEgZXN0cmF0ZWdpYSBlcyBlbCBhc2lnbmFyIHVuIHZhbG9yIGluaWNpYWwgY29tw7puIGEgdG9kYXMgbGFzIHBvc2liaWxpZGFkZXMgZGUgdHJhbnNpY2nDs24gZnVlcmEgZGUgbGEgZGlhZ29uYWwuIFVuYSBjb25zZWN1ZW5jaWEgZGUgdGFsIGRlY2lzacOzbiwgcXVpesOhIGNvbnZlbmllbnRlLCBlcyBxdWUgbGEgZGlzdHJpYnVjacOzbiBlc3RhY2lvbmFyaWEgY29ycmVzcG9uZGllbnRlIGVzIHVuaWZvcm1lIHNvYnJlIGxvcyBlc3RhZG9zOyBlc3RvIHNpZ3VlIHBvciBzaW1ldHLDrWEuIEVsZWdpciBidWVub3MgdmFsb3JlcyBpbmljaWFsZXMgcGFyYSBsb3MgcGFyw6FtZXRyb3MgdGllbmRlIGEgYWxlamFybG8gYSB1bm8gZGUgaW5lc3RhYmlsaWRhZCBudW3DqXJpY2EuCgojIyMjMy40LjMuIFBvc2liaWxpZGFkIHNpbiBsaW1pdGVzCgpFbiBlbCBjYXNvIGRlIEhNTXMgY29uIGRpc3RyaWJ1Y2lvbmVzIGNvbnRpbnVhcyBlc3RhZG8tZGVwZW5kaWVudGVzLCBwdWVkZSBzdWNlZGVyIHF1ZSBsYSBwb3NpYmlsaWRhZCBlcyBzaW4gbMOtbWl0ZXMgZW4gbGEgcHJveGltaWRhZCBkZSBjaWVydGFzIGNvbWJpbmFjaW9uZXMgZGUgcGFyw6FtZXRyb3MuCgohW1NlcmllIGRlIFRlcnJlbW90b3MgLSBTZWNjaW9uIGl6cXVpZXJkYTogRGlzdHJpYnVjaW9uZXMgZGUgUG9pc3NvbiAtIEhNTSBjb24gZG9zIHkgdHJlcyBlc3RhZG9zLiBTZWNjaW9uIERlcmVjaGE6IG1lZGlvcyBkZXBlbmRpZW50ZXMgZGVsIGVzdGFkbyBlbiBjb21wYXJhY2lvbiBjb24gbGFzIG9ic2VydmFjaW9uZXNdKC9Vc2Vycy9icmFjcnV6L0RvY3VtZW50cy84dm8uIFRyaW1lc3RyZSBJTy9TaXN0LiBFeHBlcnRvcyB5IFJlZGVzIFByb2IuL0NIMy9HcmFmaWNhMy0xLnBuZykKCkNvbW8gYW50ZXMsIHN1Z2VyaW1vcyBxdWUsIHNpIGVzdG8gY3JlYSBkaWZpY3VsdGFkbywgc2UgbWF4aW1pemUgbGEgcG9zaWJpbGlkYWQgZGlzY3JldGEgZW4gdmV6IGRlIGxhIGRlbnNpZGFkIGNvbmp1bnRhLgoKIyMjIzMuNS4gRWplbXBsbzogVGVycmVtb3RvcwoKTGEgZmlndXJhIGFudGVyaW9yIG11ZXN0cmEgZWwgcmVzdWx0YWRvIGRlIGFqdXN0YXIgSE1NcyBkZSBQb2lzc29uIChlc3RhY2lvbmFyaW9zKSBjb24gZG9zIGEgdHJlcyBlc3RhZG9zIGEgbGEgc2VyaWUgZGUgdGVycmVtb3RvcyBwb3IgbWVkaWFzIGRlbCBvcHRpbWl6YWRvciBubyByZXN0cmluZ2lkbyBubG0uIEVsIG1vZGVsbyBkZSBkb3MgZXN0YWRvcyBlcwoKJCQKXEdhbW1hID0gClxsZWZ0KFxiZWdpbnthcnJheX17Y2N9IAowLjkzNDAgLCAwLjAwNjYwXFwgCjAuMTI4NSAsIDAuODcxNQpcZW5ke2FycmF5fVxyaWdodCkKJCQKCkNvbiBcKM60PSgwLjY2MDgsMC4zMzkyKVwpLFwozrs9KDE1LjQ3MiwyNi4xMjUpXCksIHkgbGEgcG9zaWJpbGlkYWQgZGUgcmVnaXN0cm8gZGFkYSBwb3IgXChsPS0zNDIuMzE4M1wpLiBFcyBjbGFybyBxdWUgbGEgbWV6Y2xhIChkZXBlbmRpZW50ZSBkZSBNYXJrb3YpIGFqdXN0YWRhIGRlIGRvcyBkaXN0cmlidWNpb25lcyBkZSBQb2lzc29uIHByb3ZlZSB1biBtZWpvciBhanVzdGUgYSBsYSBkaXN0cmlidWNpw7NuIG1hcmdpbmFsIGRlIGxhcyBvYnNlcnZhY2lvbmVzIHF1ZSBsbyBoYWNlIHVuYSDDum5pY2EgZGlzdHJpYnVjacOzbiBkZSBQb2lzc29uLCBwZXJvIGVsIGFqdXN0ZSBwdWVkZSBzZWd1aXIgc2llbmRvIG1lam9yYWRvIGFsIHVzYXIgdW5hIG1lemNsYSBkZSAzIG8gNCBkaXN0cmlidWNpb25lcyBkZSBQb2lzc29uLgoKYGBge3J9CmxpYnJhcnkoSGlkZGVuTWFya292KQpsaWJyYXJ5KHJlYWRyKQojLS0tLS0gIFBvaXNzb24gRGlzdHJpYnV0aW9uICAtLS0tLQoKI2xlZXIgbGEgZGF0YSAKeF9kYXRhPC0gcmVhZC50YWJsZSgiL1VzZXJzL2JyYWNydXovRG9jdW1lbnRzLzh2by4gVHJpbWVzdHJlIElPL1Npc3QuIEV4cGVydG9zIHkgUmVkZXMgUHJvYi4vZWFydGhxdWFrZXMudHh0IilbLDJdCgpQaSA8LSBtYXRyaXgoYygwLjkzNDAsIDAuMDY2LAogICAgICAgICAgICAgICAwLjEyODUsIDAuODcxNSksCiAgICAgICAgICAgICBieXJvdz1UUlVFLCBucm93PTIpCgpkZWx0YSA8LSBjKDAuNjYwOCwgMC4zMzkyKQoKeCA8LSBkdGhtbSh4X2RhdGEsIFBpLCBkZWx0YSwgInBvaXMiLCBsaXN0KGxhbWJkYT1jKDE1LjQ3MiwgMjYuMTI1KSksCiAgICAgICAgICAgZGlzY3JldGUgPSBUUlVFKQoKIyAgICB1c2UgYWJvdmUgcGFyYW1ldGVyIHZhbHVlcyBhcyBpbml0aWFsIHZhbHVlcwoKeSA8LSBCYXVtV2VsY2goeCkKcHJpbnQoc3VtbWFyeSh5KSkKI2xvZy1saWtlbGlob29kIGlkZWFsCnByaW50KGxvZ0xpayh5KSkKe2g8LWhpc3QocmVzaWR1YWxzKHkpKQp4Zml0IDwtIHNlcShtaW4ocmVzaWR1YWxzKHkpKSwgbWF4KHJlc2lkdWFscyh5KSksIGxlbmd0aCA9IDQwKSAKeWZpdCA8LSBkbm9ybSh4Zml0LCBtZWFuID0gbWVhbihyZXNpZHVhbHMoeSkpLCBzZCA9IHNkKHJlc2lkdWFscyh5KSkpIAp5Zml0IDwtIHlmaXQgKiBkaWZmKGgkbWlkc1sxOjJdKSAqIGxlbmd0aChyZXNpZHVhbHMoeSkpIAoKbGluZXMoeGZpdCwgeWZpdCwgY29sID0gIiMwMDY2ZmYiLCBsd2QgPSAyKX0KYGBgCgoKCkVsIG1vZGVsbyBkZSB0cmVzIGVzdGFkb3MgZXM6CgokJApcR2FtbWEgPSAKXGxlZnQoXGJlZ2lue2FycmF5fXtjY30gCjAuOTU1NSAsIDAuMDI0ICwgMC4wMjFcXCAKMC4wNTAgLCAwLjg4OTkgLCAwLjA1MSBcXAowLjAwMCAsIDAuMTk3ICwgIDAuODAzClxlbmR7YXJyYXl9XHJpZ2h0KQokJAoKQ29uIFwozrQ9KDAuNDQzNiwwLjQwNDUsMC4xNTE5KVwpLFwozrs9KDEzLjE0NiwxOS43MjEsMjkuNzE0NClcKSB5IFwobD0tMzI5LjQ2MDNcKS4gCgoKYGBge3J9CmxpYnJhcnkoSGlkZGVuTWFya292KQpsaWJyYXJ5KHJlYWRyKQojLS0tLS0gIFBvaXNzb24gRGlzdHJpYnV0aW9uICAtLS0tLQoKI2xlZXIgbGEgZGF0YSAKeF9kYXRhPC0gcmVhZC50YWJsZSgiL1VzZXJzL2JyYWNydXovRG9jdW1lbnRzLzh2by4gVHJpbWVzdHJlIElPL1Npc3QuIEV4cGVydG9zIHkgUmVkZXMgUHJvYi4vZWFydGhxdWFrZXMudHh0IilbLDJdCgpQaSA8LSBtYXRyaXgoYygwLjk1NTUgLCAwLjAyNCAsIDAuMDIxICwKMC4wNTAgLCAwLjg4OTkgLCAwLjA1MSAsIAowLjAwMCAsIDAuMTk3ICwgIDAuODAzKSwKICAgICAgICAgICAgIGJ5cm93PVRSVUUsIG5yb3c9MykKCmRlbHRhIDwtIGMoMC40NDM2LDAuNDA0NSwwLjE1MTkpCgp4IDwtIGR0aG1tKHhfZGF0YSwgUGksIGRlbHRhLCAicG9pcyIsIGxpc3QobGFtYmRhPWMoMTMuMTQ2LDE5LjcyMSwyOS43MTQpKSwKICAgICAgICAgICBkaXNjcmV0ZSA9IFRSVUUpCgojICAgIHVzZSBhYm92ZSBwYXJhbWV0ZXIgdmFsdWVzIGFzIGluaXRpYWwgdmFsdWVzCgp5IDwtIEJhdW1XZWxjaCh4KQpwcmludChzdW1tYXJ5KHkpKQojbG9nLWxpa2VsaWhvb2QgaWRlYWwKcHJpbnQobG9nTGlrKHkpKQp7aDwtaGlzdChyZXNpZHVhbHMoeSkpCnhmaXQgPC0gc2VxKG1pbihyZXNpZHVhbHMoeSkpLCBtYXgocmVzaWR1YWxzKHkpKSwgbGVuZ3RoID0gNDApIAp5Zml0IDwtIGRub3JtKHhmaXQsIG1lYW4gPSBtZWFuKHJlc2lkdWFscyh5KSksIHNkID0gc2QocmVzaWR1YWxzKHkpKSkgCnlmaXQgPC0geWZpdCAqIGRpZmYoaCRtaWRzWzE6Ml0pICogbGVuZ3RoKHJlc2lkdWFscyh5KSkgCgpsaW5lcyh4Zml0LCB5Zml0LCBjb2wgPSAiI2ZmMDAwMCIsIGx3ZCA9IDIpfQpgYGAKCkVsIG1vZGVsbyBkZSBjdWF0cm8gZXN0YWRvcyBlczogCiQkClxHYW1tYSA9IApcbGVmdChcYmVnaW57YXJyYXl9e2NjfSAKMC44MDUsIDAuMTAyLCAwLjA5MywgMC4wMDAgXFwKMC4wMDAsIDAuOTc2LCAwLjAwMCwgMC4wMjQgXFwKMC4wNTAsIDAuMDAwLCAwLjkwMiwgMC4wNDggXFwKMC4wMDAsIDAuMDAwLCAwLjE4OCwgMC44MTIKXGVuZHthcnJheX1ccmlnaHQpCiQkCgoKQ29uIFwozrQ9KDAuMDkzNiwwLjM5ODMsMC4zNjQzLDAuMTQzOSlcKSxcKM67PSgxMS4yODMsMTMuODUzLDE5LjY5NSwyOS43MDApXCkgeSBcKGw9LTMyNy44MzE2XCkuCgoKYGBge3J9CmxpYnJhcnkoSGlkZGVuTWFya292KQpsaWJyYXJ5KHJlYWRyKQojLS0tLS0gIFBvaXNzb24gRGlzdHJpYnV0aW9uICAtLS0tLQoKI2xlZXIgbGEgZGF0YSAKeF9kYXRhPC0gcmVhZC50YWJsZSgiL1VzZXJzL2JyYWNydXovRG9jdW1lbnRzLzh2by4gVHJpbWVzdHJlIElPL1Npc3QuIEV4cGVydG9zIHkgUmVkZXMgUHJvYi4vZWFydGhxdWFrZXMudHh0IilbLDJdCgpQaSA8LSBtYXRyaXgoYygwLjgwNSwgMC4xMDIsIDAuMDkzLCAwLjAwMCwKMC4wMDAsIDAuOTc2LCAwLjAwMCwgMC4wMjQsCjAuMDUwLCAwLjAwMCwgMC45MDIsIDAuMDQ4LAowLjAwMCwgMC4wMDAsIDAuMTg4LCAwLjgxMiksCiAgICAgICAgICAgICBieXJvdz1UUlVFLCBucm93PTQpCgpkZWx0YSA8LSBjKDAuMDkzNiwwLjM5ODMsMC4zNjQzLDAuMTQzOSkKCnggPC0gZHRobW0oeF9kYXRhLCBQaSwgZGVsdGEsICJwb2lzIiwgbGlzdChsYW1iZGE9YygxMS4yODMsMTMuODUzLDE5LjY5NSwyOS43MDApKSwKICAgICAgICAgICBkaXNjcmV0ZSA9IFRSVUUpCgojICAgIHVzZSBhYm92ZSBwYXJhbWV0ZXIgdmFsdWVzIGFzIGluaXRpYWwgdmFsdWVzCgp5IDwtIEJhdW1XZWxjaCh4KQpwcmludChzdW1tYXJ5KHkpKQojbG9nLWxpa2VsaWhvb2QgaWRlYWwKcHJpbnQobG9nTGlrKHkpKQp7aDwtaGlzdChyZXNpZHVhbHMoeSkpCnhmaXQgPC0gc2VxKG1pbihyZXNpZHVhbHMoeSkpLCBtYXgocmVzaWR1YWxzKHkpKSwgbGVuZ3RoID0gNDApIAp5Zml0IDwtIGRub3JtKHhmaXQsIG1lYW4gPSBtZWFuKHJlc2lkdWFscyh5KSksIHNkID0gc2QocmVzaWR1YWxzKHkpKSkgCnlmaXQgPC0geWZpdCAqIGRpZmYoaCRtaWRzWzE6Ml0pICogbGVuZ3RoKHJlc2lkdWFscyh5KSkgCgpsaW5lcyh4Zml0LCB5Zml0LCBjb2wgPSAiIzAwZmZmZiIsIGx3ZCA9IDIpfQpgYGAKCkVuIHRvZG9zIGVzdG9zIGNhc29zIGVsIEFDRiBlcyBzb2xvIHVuYSBjb21iaW5hY2nDs24gbGluZWFsIGRlIGxhcyBrLWVzaW1hcyBwb3RlbmNpYXMgZGUgbG9zIGVpZ2VudmFsb3JlcyBkaXN0aW50b3MgZGUgMSBkZSBsYSBtYXRyaXogZGUgcHJvYmFiaWxpZGFkIGRlIHRyYW5zaWNpw7NuLgpVbiBmZW7Ds21lbm8gcXVlIGVzIG5vdGFibGUgY3VhbmRvIHVubyBhanVzdGEgbW9kZWxvcyBjb24gdHJlcyBvIG1hcyBlc3RhZG9zIGEgc2VyaWVzIHJlbGF0aXZhbWVudGUgY29ydGFzIGVzIHF1ZSBsb3MgZXN0aW1hZG9zIGRlIHVuYSBvIG1hcyBkZSBsYXMgcHJvYmFiaWxpZGFkZXMgZGUgdHJhbnNpY2nDs24gcmVzdWx0YSBzZXIgbXV5IGNlcmNhbmEgYSBjZXJvLgoKRXN0ZSBmZW7Ds21lbm8gcHVlZGUgc2VyIGV4cGxpY2FkbyBjb21vIHNpZ3VlLiBFbiB1bmEgY2FkZW5hIGRlIE1hcmtvdiBlc3RhY2lvbmFyaWEsIGVsIG7Dum1lcm8gZXNwZXJhZG8gZGUgdHJhbnNpY2lvbmVzIGRlbCBlc3RhZG8gaSBhbCBlc3RhZG8gaiBlbiB1bmEgc2VyaWUgZGUgVCBvYnNlcnZhY2lvbmVzIGVzIFwoKFQtMSkgzrRfaVwpIFwozrNfe2lqfVwpLiBQYXJhIFwozrRfMz0wLjE1MlwpIHkgVD0xMDcgKGNvbW8gZW4gbnVlc3RybyBtb2RlbG8gZGUgdHJlcyBlc3RhZG9zKSwgZXN0YSBleHBlY3RhdGl2YSBzZXLDoSBtZW5vciBxdWUgMSBzaSBcKM6zX3szMX08MC4wNjJcKS4gRW4gdGFsIHNlcmllLCBwb3IgZW5kZSwgZXMgcHJvYmFibGUgcXVlIHNpIFwozrNfezMxfVwpIGVzIGJhc3RhbnRlIHBlcXVlw7FvIG5vIGhhYnLDoSB0cmFuc2ljaW9uZXMgZGVsIGVzdGFkbyAzIGFsIGVzdGFkbyAxLCB5IGVudG9uY2VzIGN1YW5kbyBidXNxdWVtb3MgZXN0aW1hciBcKM6zX3szMX1cKSBlbiB1biBITU0sIGVsIGVzdGltYWRvIGVzIHByb2JhYmxlIGEgc2VyIGVmZWN0aXZhbWVudGUgY2Vyby4gQ29tbyBtIGluY3JlbWVudGUsIGxhcyBwcm9iYWJpbGlkYWRlcyBcKM60X2lcKSB5IFwozrNfe2lqfVwpIHNlIHZ1ZWx2ZSBtw6FzIHBlcXVlw7FhIGVuIHByb21lZGlvOyBlc3RvIGxvIGhhY2UgbWFzIHByb2JhYmxlIHF1ZSBhbCBtZW5vcyB1bmEgcHJvYmFiaWxpZGFkIGRlIHRyYW5zaWNpw7NuIHNlYSBlZmVjdGl2YW1lbnRlIGNlcm8uCgojIyMjMy42LiBFcnJvcmVzIGVzdMOhbmRhcmVzIGUgaW50ZXJ2YWxvcyBkZSBjb25maWFuemEKClJlbGF0aXZhbWVudGUgcG9jbyBlcyBjb25vY2lkbyBhY2VyY2EgZGUgbGFzIHByb3BpZWRhZGVzIGRlIGVzdGltYWRvcmVzIGRlIG3DoXhpbWEgcG9zaWJpbGlkYWQgZGUgSE1Nczsgc29sbyByZXN1bHRhZG9zIGFzaW50w7N0aWNvcyBlc3TDoW4gZGlzcG9uaWJsZXMuIFBhcmEgZXhwbG90YXIgZXN0b3MgcmVzdWx0YWRvcyBzZSByZXF1aWVyZSBlc3RpbWFyIGxhIG1hdHJpeiBkZSB2YXJpYW56YSB5IGNvdmFyaWFuemEgZGUgbG9zIGVzdGltYWRvcmVzIGRlIGxvcyBwYXLDoW1ldHJvcy4gU2UgcHVlZGUgZXN0aW1hciBsb3MgZXJyb3JlcyBlc3TDoW5kYXJlcyBkZWwgSGVzc2lhbm8gZGUgbGEgcG9zaWJpbGlkYWQgZGUgcmVnaXN0cm8gZW4gZWwgbcOheGltbywgcGVybyBlc3RlIGVuZm9xdWUgc2UgZW5jdWVudHJhIGNvbiBkaWZpY3VsdGFkZXMgY3VhbmRvIGFsZ3Vub3MgZGUgbG9zIHBhcsOhbWV0cm9zIGVzdMOhbiBlbiBsYSBmcm9udGVyYSBkZWwgZXNwYWNpbyBkZSBzdSBwYXLDoW1ldHJvLCBlbCBjdWFsIG9jdXJyZSBiYXN0YW50ZSBhIG1lbnVkbyBjdWFuZG8gbG9zIEhNTXMgc29uIGFqdXN0YWRvcy4KCiMjIyMjMy42LjEuIEVycm9yZXMgZXN0w6FuZGFyZXMgbWVkaWFudGUgZWwgSGVzc2lhbm8KCkF1bnF1ZSBsb3MgZXN0aW1hZG9zIGRlIHB1bnRvIFwoXFRoZXRhID0gKFxHYW1tYSxcbGFtYmRhKVwpIHNvbiBmw6FjaWxlcyBkZSBjb21wdXRhciwgZXN0aW1hZG9zIGV4YWN0byBkZSBpbnRlcnZhbG8gbm8gZXN0w6FuIGRpc3BvbmlibGVzLiBDYXBwZSAoMjAwNSwgQ2FwaXR1bG8gMTIpIG11ZXN0cmEgcXVlLCBiYWpvIGNpZXJ0YXMgY29uZGljaW9uZXMgZGUgcmVndWxhcmlkYWQsIGxvcyBNTEVzIGRlIHBhcsOhbWV0cm9zIGRlIHVuIEhNTSBzb24gY29uc2lzdGVudGVzLCBhc2ludMOzdGljYW1lbnRlIG5vcm1hbGVzIHkgZWZpY2llbnRlcy4gUG9yIGVuZGUsIHNpIHBvZGVtb3MgZXN0aW1hciBsb3MgZXJyb3JlcyBlc3TDoW5kYXJlcyBkZSBsb3MgTUxFcyBlbnRvbmNlcywgdXNhbmRvIG5vcm1hbGlkYWQgYXNpbnTDs3RpY2EsIHBvZGVtb3MgdGFtYmnDqW4gY29tcHV0YXIgaW50ZXJ2YWxvcyBhcHJveGltYWRvcyBkZSBjb25maWFuemEuIFNpbiBlbWJhcmdvLCBjb21vIHNlw7FhbGEgRnJ1aHdpcnRoLVNjaG5hdHRlciAoMjAwNiwgcC4gNTMpIGVuIGVsIGNvbnRleHRvIGRlIG1vZGVsb3MgaW5kZXBlbmRpZW50ZXMgZGUgbWV6Y2xhLCDigJxMYXMgY29uZGljaW9uZXMgZGUgcmVndWxhcmlkYWQgc29uIGEgbWVudWRvIHZpb2xhZG9zLCBpbmNsdXllbmRvIGNhc29zIGRlIGdyYW4gcHJlb2N1cGFjacOzbiBwcsOhY3RpY2EsIGVudHJlIGVsbG9zIHNldHMgZGUgZGF0b3MgcGVxdWXDsW9zLCBtZXpjbGFzIGNvbiBwZXNvcyBkZSBjb21wb25lbnRlcyBwZXF1ZcOxb3MsIHkgbWV6Y2xhcyBkZSBleGNlc29zIGNvbiBtdWNob3MgY29tcG9uZW50ZXPigJ0uIEFkZW3DoXMsIE1jTGFjaGxhbiB5IFBlZWwgKDIwMDAsIHAuIDY4KSBhZHZpZXJ0ZW46IOKAnEVuIHBhcnRpY3VsYXIsIHBhcmEgbW9kZWxvcyBkZSBtZXpjbGEsIGVzIGJpZW4gY29ub2NpZG8gcXVlIGVsIHRhbWHDsW8gZGUgbXVlc3RyYSBuIHRpZW5lIHF1ZSBzZXIgbXV5IGdyYW5kZSBhbnRlcyBxdWUgbGEgdGVvcsOtYSBhc2ludMOzdGljYSBkZSBsYSBwb3NpYmlsaWRhZCBtw6F4aW1hIHNlIGFwbGlxdWXigJ0uCkNvbiBsYXMgYWR2ZXJ0ZW5jaWFzIHByZXZpYXMgZW4gbWVudGUsIHBvZGVtb3MsIGVuIG9yZGVuIHBhcmEgZXN0aW1hciBsb3MgZXJyb3JlcyBlc3TDoW5kYXJlcyBkZSBsb3MgTUxFcyBkZSB1biBITU0sIHV0aWxpemFyIGVsIEhlc3NpYW5vIGFwcm94aW1hZG8gZGUgbWVub3MgbGEgcG9zaWJpbGlkYWQgZGUgcmVnaXN0cm8gZW4gZWwgbcOtbmltby4gUG9kZW1vcyBpbnZlcnRpcmxvIHkgYXPDrSBlc3RpbWFyIGxhIG1hdHJpeiBkZSB2YXJpYW56YSB5IGNvdmFyaWFuemEgYXNpbnTDs3RpY2EgZGUgbG9zIGVzdGltYWRvcmVzIGRlIGxvcyBwYXLDoW1ldHJvcy4gVW4gcHJvYmxlbWEgY29uIGVzdGEgc3VnZXJlbmNpYSBlcyBxdWUsIHNpIGxvcyBwYXLDoW1ldHJvcyBoYW4gc2lkbyB0cmFuc2Zvcm1hZG9zLCBlbCBIZXNzaWFubyBkaXNwb25pYmxlIHNlcsOhIGVsIGN1YWwgc2UgcmVmaWVyZSBhIGxvcyBwYXLDoW1ldHJvcyBmdW5jaW9uYWxlcyBcKM+VX2lcKSwgbm8gbG9zIG9yaWdpbmFsZXMsIHBhcmEgaW50ZXJwcmV0YXJsbyBkZSBtZWpvciBtYW5lcmEsIHBhcsOhbWV0cm9zIG5hdHVyYWxlcyBcKFxUaGV0YV9pXCkgKFwozpNcKSB5IFwozrtcKSBlbiBlbCBjYXNvIGRlIHVuIEhNTSBkZSBQb2lzc29uKS4KTGEgc2l0dWFjacOzbiBlcyBlbnRvbmNlcyBxdWUgdGVuZW1vcywgZW4gZWwgbcOtbmltbyBkZSBcKC1sXCksIGVsIEhlc3NpYW5vIGNvbiByZXNwZWN0byBhIGxvcyBwYXLDoW1ldHJvcyBmdW5jaW9uYWxlcwoKJCQKSCA9IC0oXGZyYWN7XHBhcnRpYWxeMmx9e1xwYXJ0aWFsIFxwaGlfaSBccGFydGlhbCBccGhpX2p9KQokJAoKUGVybyBsbyBxdWUgcmVhbG1lbnRlIG5lY2VzaXRhbW9zIGVzIGVsIEhlc3NpYW5vIGVuIHJlc3BlY3RvIGEgbG9zIHBhcsOhbWV0cm9zIG5hdHVyYWxlcwoKJCQKRyA9IC0oXGZyYWN7XHBhcnRpYWxeMmx9e1xwYXJ0aWFsIFx0aGV0YV9pIFxwYXJ0aWFsIFx0aGV0YV9qfSkKJCQKCkV4aXN0ZSwgc2luIGVtYmFyZ28sIGxhIHNpZ3VpZW50ZSByZWxhY2nDs24gZW50cmUgbG9zIGRvcyBIZXNzaWFub3MgZW4gZWwgbcOtbmltbwoKJCQKSCA9IE1HTScgXHF1YWQgeSBccXVhZCBHXnstMX0gPSBNJ0heey0xfU0KJCQKCkRvbmRlIE0gZXMgZGVmaW5pZG8gcG9yIFwobV97aWp9PeKIgs64X2ov4oiCz5VfaVwpLiBFbiBlbCBjYXNvIGRlIHVuIEhNTSBkZSBQb2lzc29uLCBsb3MgZWxlbWVudG9zIGRlIE0gc29uIGJhc3RhbnRlIHNpbXBsZXMuCkNvbiBNIGEgbnVlc3RyYSBkaXNwb3NpY2nDs24sIHBvZGVtb3MgdXNhciBsYSByZWxhY2nDs24gYW50ZXJpb3IgcGFyYSBkZWR1Y2lyIFwoR157LTF9XCkgZGUgXChIXnstMX1cKSwgeSB1dGlsaXphciBcKEdeey0xfVwpIHBhcmEgZW5jb250cmFyIGVycm9yZXMgZXN0w6FuZGFyZXMgcGFyYSBsb3MgcGFyw6FtZXRyb3MgbmF0dXJhbGVzLCB0YWxlcyBwYXLDoW1ldHJvcyBwcm92aXN0b3Mgbm8gZXN0w6FuIGVuIGxhIGZyb250ZXJhIGRlbCBlc3BhY2lvIGRlbCBwYXLDoW1ldHJvLiBVbmEgcnV0YSBhbHRlcm5hdGl2YSBwYXJhIGxvcyBlcnJvcmVzIGVzdMOhbmRhcmVzIGNvbiByZXNwZWN0byBhIGxvcyBwYXLDoW1ldHJvcyBuYXR1cmFsZXMgZWwgY3VhbCBhIG1lbnVkbyByZXN1bHRhIGJpZW4sIHkgZXMgbWVub3MgbGFib3Jpb3NhLCBlcyBsYSBzaWd1aWVudGUuIFByaW1lcm8gZW5jdWVudHJlIGVsIE1MRSBhbCByZXNvbHZlciBlbCBwcm9ibGVtYSBkZSBvcHRpbWl6YWNpw7NuIHJlc3RyaW5naWRhLCBsdWVnbyB2dWVsdmEgYSBjb3JyZXIgbGEgb3B0aW1pemFjacOzbiBzaW4gcmVzdHJpY2Npb25lcywgZW1wZXphbmRvIGVuIG8gbXV5IGNlcmNhbm8gYWwgTUxFLiBTaSBlbCBlc3RpbWFkbyByZXN1bHRhbnRlIGVzIGVsIG1pc21vIHF1ZSBlbCBNTEUgeWEgZW5jb250cmFkbywgZWwgSGVzc2lhbm8gY29ycmVzcG9uZGllbnRlIGVudG9uY2VzIHByb3ZlZSBkaXJlY3RhbWVudGUgbG9zIGVycm9yZXMgZXN0w6FuZGFyZXMgY29uIHJlc3BlY3RvIGEgbG9zIHBhcsOhbWV0cm9zIG5hdHVyYWxlcy4gUGVybyBzaSB1bm8gaGFjZSBsYSBzdXBvc2ljacOzbiBkZSBub3JtYWxpZGFkIHkgYmFzYSB1biBpbnRlcnZhbG8gZGUgY29uZmlhbnphIGVuIMOpbCwgdGFsIHN1cG9zaWNpw7NuIGRlIG5vcm1hbGlkYWQgZXMgbWFzIHByb2JhYmxlLCBwZXJvIG5vIGdhcmFudGl6YWRhLgoKIyMjIyNDb21wdXRhY2nDs24gcmVjdXJzaXZhIGRlbCBIZXNzaWFubwoKVW4gbcOpdG9kbyBhbHRlcm5hdGl2byBkZSBjb21wdXRhciBlbCBIZXNzaWFubyBlcyBlbCBkZSBMeXN0aWcgeSBIdWdoZXMgKDIwMDIpLiBFbGxvcyBwcmVzZW50YW4gZWwgYWxnb3JpdG1vIGRlIGF2YW5jZSBcKM6xX3Q9zrFfe3QtMX0gzpNQKHhfdClcKSBkZSBtYW5lcmEgZW4gbGEgY3VhbCBpbmNvcnBvcmFuIHVuYSBlc2NhbGEgYXV0b23DoXRpY2EgbyDigJxuYXR1cmFs4oCdLCB5IGx1ZWdvIGV4dGllbmRlbiBlc3RlIGVuZm9xdWUgcGFyYSBhc8OtIGNvbXB1dGFyIHN1IEhlc3NpYW5vIHkgZ3JhZGllbnRlIGNvbiByZXNwZWN0byBhIGxvcyBwYXLDoW1ldHJvcyBuYXR1cmFsZXMsIGFxdWVsbG9zIHF1ZSBoZW1vcyBkZXNjcml0byBhcnJpYmEgcG9yIFwozrhfaVwpLiBUdXJuZXIgKDIwMDgpIGhhIHVzYWRvIGVzdGUgZW5mb3F1ZSBwYXJhIGFzw60gYnVzY2FyIGxhcyBkZXJpdmFkYXMgYW5hbMOtdGljYXMgcmVxdWVyaWRhcyBwYXJhIG1heGltaXphciBwb3NpYmlsaWRhZGVzIGRlIEhNTXMgZGlyZWN0YW1lbnRlIHBvciBlbCBhbGdvcml0bW8gTGV2ZW5iZXJnLU1hcnF1YXJkdC4KQXVucXVlIGVzdG8gcHVlZGUgc2VyIHVuIG3DqXRvZG8gbWFzIGVmaWNpZW50ZSB5IHByZWNpc28gZGUgY29tcHV0YXIgZWwgSGVzc2lhbm8gcXVlIHV0aWxpemFyIGxhIHJlbGFjacOzbiBkZXNjcml0YSBhbnRlcmlvcm1lbnRlLCBubyByZXN1ZWx2ZSBlbCBwcm9ibGVtYSBmdW5kYW1lbnRhbCBxdWUgZWwgdXNvIGRlbCBIZXNzaWFubyBwYXJhIGNvbXB1dGFyIGVycm9yZXMgZXN0w6FuZGFyZXMgKHkgZGUgYWxsw60gaW50ZXJ2YWxvcyBkZSBjb25maWFuemEpIG5vIGVzIGRlIGNvbmZpYW56YSBzaSBhbGd1bm9zIGRlIGxvcyBwYXLDoW1ldHJvcyBlc3TDoW4gZW4gbyBjZXJjYSBkZSBsYSBmcm9udGVyYSBkZWwgZXNwYWNpbyBkZWwgcGFyw6FtZXRyby4KCgojIyMjMy42LjIuIEVycm9yZXMgZXN0w6FuZGFyZXMgQm9vdHN0cmFwIGUgaW50ZXJ2YWxvcyBkZSBjb25maWFuemEKCkNvbW8gdW5hIGFsdGVybmF0aXZhIGEgbGFzIHTDqWNuaWNhcyBkZXNjcml0YXMgZW4gbGEgc2VjY2nDs24gYW50ZXJpb3IsIHVubyBwdWVkZSB1c2FyIGVsIEJvb3RzdHJhcCBwYXJhbcOpdHJpY28uIEhhYmxhbmRvIGJ1cmRhbWVudGUsIGxhIGlkZWEgZGVsIEJvb3RzdHJhcCBwYXJhbcOpdHJpY28gZXMgZWwgZXZhbHVhciBsYXMgcHJvcGllZGFkZXMgZGVsIG1vZGVsbyBjb24gcGFyw6FtZXRyb3MgXChcVGhldGFcKXVzYW5kbyBhcXVlbGxvcyBkZWwgbW9kZWxvIGNvbiBwYXLDoW1ldHJvcyBcKFx3aWRlaGF0XFRoZXRhXCkuIExvcyBzaWd1aWVudGVzIHBhc29zIHNvbiByZWFsaXphZG9zIHBhcmEgZXN0aW1hciBsYSBtYXRyaXogZGUgdmFyaWFuemEtY292YXJpYW56YSBkZSBcKFx3aWRlaGF0XFRoZXRhXCkuCgoxLiBBanVzdGUgZWwgbW9kZWxvLCBjb21wdXRlIFwoXHdpZGVoYXRcVGhldGFcKS4KMi4gKGEpIEdlbmVyZSB1bmEgbXVlc3RyYSwgbGxhbWFkYSBtdWVzdHJhIEJvb3RzdHJhcCwgZGUgb2JzZXJ2YWNpb25lcyBkZWwgbW9kZWxvIGFqdXN0YWRvLCBlbCBtb2RlbG8gY29uIHBhcsOhbWV0cm9zIFwoXHdpZGVoYXRcVGhldGFcKS4gTGEgbG9uZ2l0dWQgZGViZXLDrWEgc2VyIGxhIG1pc21hIHF1ZSBlbCBuw7ptZXJvIG9yaWdpbmFsIGRlIG9ic2VydmFjaW9uZXMuCi0gKGIpIEVzdGltZSBsb3MgcGFyw6FtZXRyb3MgXChcVGhldGFcKSBwb3IgXChcd2lkZWhhdFxUaGV0YV4qXClwYXJhIGxhIG11ZXN0cmEgQm9vdHN0cmFwLgotIChjKSBSZXBpdGEgbG9zIHBhc29zIChhKSB5IChiKSBCIHZlY2VzIChjb24gQiDigJxncmFuZGXigJ0pIHkgcmVnaXN0cmUgbG9zIHZhbG9yZXMgXChcd2lkZWhhdFxUaGV0YV4qXCkuCgpMYSBtYXRyaXogZGUgdmFyaWFuemEtY292YXJpYW56YSBkZSBcKFx3aWRlaGF0XFRoZXRhXCkgZXMgZW50b25jZXMgZXN0aW1hZGEgcG9yIGxhIG1hdHJpeiBkZSB2YXJpYW56YeKAlGNvdmFyaWFuemEgbXVlc3RyYSBkZSBsb3MgZXN0aW1hZG9zIEJvb3RzdHJhcCBcKFx3aWRlaGF0XFRoZXRhXipcKSAoYiksIFwoYj0xLDIs4oCmLEJcKToKCiQkClZhci1Db3YoXHdpZGVoYXRcVGhldGEpID0gXGZyYWN7MX17Qi0xfSBcc3VtX3tiPTF9XkIgKFx3aWRlaGF0XFRoZXRhXiooYikgLSBcd2lkZWhhdFxUaGV0YV4qKFxjZG90cCkpJyhcd2lkZWhhdFxUaGV0YV4qKGIpIC0gXHdpZGVoYXRcVGhldGFeKihcY2RvdHApKSBcXApkb25kZSBcXApcd2lkZWhhdFxUaGV0YV4qKFxjZG90cCkgPSBCXnstMX0gXHN1bV97Yj0xfV5CIFxUaGV0YV4qKGIpCiQkCgpFbCBCb290c3RyYXAgcGFyYW3DqXRyaWNvIHJlcXVpZXJlIGPDs2RpZ28gcGFyYSBnZW5lcmFyIHJlYWxpemFjaW9uZXMgZGUgdW4gbW9kZWxvIGFqdXN0YWRvLiBFbCBtw6l0b2RvIGRlIEJvb3RzdHJhcCBwdWVkZSBzZXIgdXNhZG8gcGFyYSBlc3RpbWFyIGludGVydmFsb3MgZGUgY29uZmlhbnphIGRpcmVjdGFtZW50ZS4KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK