Temario para
autoestudio avanzado de Estadística Inferencial
1. Fundamentos de
estadística enferencial
1.1 Conceptos
básicos
- Definición de inferencia estadística: Proceso de
generalizar resultados de una muestra a una población.
- Población, muestra y parámetros: Diferencia entre
estadísticos (muestra) y parámetros (población).
- Tipos de datos y escalas de medición: Nominal,
ordinal, de intervalo y de razón.
1.2 Probabilidad
avanzada
- Espacios muestrales y eventos: Conjunto de todos
los resultados posibles y subconjuntos de interés.
- Reglas de probabilidad: Regla de la suma, regla del
producto, probabilidad condicional, teorema de Bayes.
- Variables aleatorias discretas y continuas:
Funciones de masa (PMF) y densidad (PDF).
1.3 Distribuciones
de probabilidad
- Distribuciones discretas: Binomial (éxitos en n
ensayos), Poisson (eventos en intervalo), Geométrica (primer
éxito).
- Distribuciones continuas: Normal (gaussiana), t de
Student (muestras pequeñas), Chi-cuadrado (varianzas), F (razón de
varianzas).
- Teorema del Límite Central: La distribución de la
media muestral tiende a ser normal, independientemente de la
distribución original.
2. Estimación de
Parámetros
2.1 Estimación
puntual
- Propiedades de los estimadores: Sesgo (exactitud),
eficiencia (varianza baja), consistencia (converge al valor real).
- Métodos de estimación: Máxima verosimilitud (MLE),
método de momentos.
2.2 Estimación por
intervalos
- Intervalos de confianza: Para medias (z, t),
proporciones (normal approximation), varianzas (Chi-cuadrado).
- Interpretación y cálculo: “Estamos 95% seguros de
que el parámetro está en este rango”.
- Tamaño muestral y precisión: Relación entre n,
margen de error y nivel de confianza.
3. Pruebas de
Hipótesis
3.1
Fundamentos
- Hipótesis nula y alternativa: \(H_0\) vs \(H_1\); lo que se prueba vs. lo que se
sospecha.
- Errores tipo I y tipo II: Rechazar \(H_0\) cuando es verdadera (α), no rechazar
\(H_0\) cuando es falsa (β).
- Nivel de significancia y potencia: \(\alpha = P(\text{error tipo I})\), potencia
= \(1 - \beta\).
3.2 Pruebas
paramétricas
- Pruebas para una y dos medias: z-test (varianza
conocida), t-test (independientes, pareados).
- Pruebas para proporciones: Una y dos proporciones
con aproximación normal.
- Pruebas para varianzas: Chi-cuadrado (una
varianza), F-test (dos varianzas).
3.3 Pruebas no
paramétricas
- Prueba de Wilcoxon, Mann-Whitney, Kruskal-Wallis:
Alternativas a t-test y ANOVA cuando no hay normalidad.
- Prueba de signos y rangos con signo: Para datos
pareados no normales.
- Ventajas y limitaciones: Robustas, pero menos
potentes que sus contrapartes paramétricas.
4. Análisis de
Varianza (ANOVA)
4.1 ANOVA de un
factor
- Supuestos y modelo: Normalidad, homocedasticidad,
independencia.
- Suma de cuadrados y tabla ANOVA: SST = SSB + SSW;
F-statistic.
- Pruebas post-hoc: Tukey HSD, Bonferroni, Scheffé
para comparaciones múltiples.
4.2 ANOVA de dos
factores
- Interacciones y efectos principales: Efecto
combinado no aditivo entre factores.
- Diseños factoriales: Todos los niveles de cada
factor se combinan.
4.3 ANOVA
multifactorial y modelos mixtos
- Diseños anidados y de medidas repetidas:
Estructuras de datos dependientes.
- Supuestos y verificaciones: Esfericidad (Mauchly’s
test), correlación intra-sujeto.
5. Regresión y
Modelos Lineales
5.1 Regresión
lineal simple
- Modelo y supuestos: \(Y =
\beta_0 + \beta_1 X + \epsilon\); linealidad, independencia,
homocedasticidad, normalidad.
- Estimación por mínimos cuadrados: Minimiza la suma
de errores al cuadrado.
- Inferencia sobre parámetros: Pruebas t para \(\beta_0\) y \(\beta_1\).
5.2 Regresión
lineal múltiple
- Selección de variables: Métodos forward, backward,
stepwise.
- Multicolinealidad y diagnóstico: VIF > 10 indica
problema; residuales, influencia (Cook’s D).
- Interpretación de coeficientes: Efecto parcial
ajustado por otras variables.
5.3 Modelos
lineales generalizados (GLM)
- Regresión logística y Poisson: Para variables
binarias (logito) y de conteo (log link).
- Modelos para datos categóricos y de conteo: Familia
binomial, Poisson, enlace logito, log.
6. Métodos
Multivariados
6.1 Análisis de
componentes principales (PCA)
- Reducción de dimensionalidad: Transforma variables
correlacionadas en componentes no correlacionados.
- Interpretación de componentes: Cargas, varianza
explicada acumulada.
6.2 Análisis
factorial
- Modelos exploratorios y confirmatorios: EFA para
descubrir estructura; CFA para validar teoría.
- Rotación de factores: Varimax (ortogonal), promax
(oblicua).
6.3 Análisis
discriminante y clúster
- Clasificación supervisada y no supervisada: LDA
(lineal), QDA (cuadrático), K-means, jerárquico.
- Evaluación de resultados: Silhouette, matriz de
confusión, AUC.
7. Inferencia
Bayesiana
7.1
Fundamentos
- Teorema de Bayes y probabilidad a posteriori: \(P(\theta|D) \propto P(D|\theta)
P(\theta)\).
- Priors: Informativos (basados en conocimiento
previo), no informativos (uniformes, Jeffreys).
7.2 Métodos
bayesianos
- Estimación bayesiana de parámetros: Distribución a
posteriori en lugar de punto estimado.
- Intervalos de credibilidad: “Hay 95% de
probabilidad de que el parámetro esté aquí”.
7.3 Aplicaciones
prácticas
- Modelos jerárquicos: Estructuras anidadas (ej.
pacientes → hospitales).
- MCMC (Monte Carlo por Cadenas de Markov):
Algoritmos como Metropolis-Hastings, Gibbs sampling.
8. Diseño de
Experimentos
8.1 Principios
básicos
- Aleatorización, replicación y bloqueo: Control de
sesgos, precisión, variabilidad.
- Diseños completamente aleatorizados: Asignación
aleatoria de tratamientos.
8.2 Diseños
avanzados
- Diseños de bloques incompletos: Cuando no se pueden
probar todos los tratamientos por bloque.
- Diseños factoriales fraccionados: Estudia muchos
factores con menos corridas.
8.3 Análisis de
experimentos
- Interpretación de interacciones: Efectos combinados
no aditivos.
- Análisis de covarianza (ANCOVA): Ajusta por
covariables continuas.
9. Análisis de Series
Temporales
9.1 Componentes de
series temporales
- Tendencia, estacionalidad y ruido: Descomposición
aditiva o multiplicativa.
- Descomposición de series: STL (Seasonal and Trend
decomposition using Loess).
9.2 Modelos
ARIMA
- Identificación, estimación y diagnóstico: ACF,
PACF; Box-Jenkins.
- Predicción y validación: Backtesting, intervalos de
predicción.
9.3 Modelos
avanzados
- Modelos GARCH para volatilidad: Modelan varianza
cambiante en el tiempo (finanzas).
- Series temporales no estacionarias: Pruebas de raíz
unitaria (ADF), diferenciación.
10. Herramientas
Computacionales
10.1 Software
estadístico
- R y Python para análisis inferencial: Entornos más
usados en ciencia de datos.
- Paquetes relevantes:
stats,
lme4, brms (R); statsmodels,
scipy, sklearn (Python).
10.2 Simulación y
bootstrap
- Métodos de remuestreo: Bootstrap para estimar
errores estándar sin supuestos.
- Aplicaciones: Intervalos de confianza no
paramétricos, pruebas de permutación.
10.3 Visualización
de datos
- Gráficos para inferencia: Boxplots (outliers), Q-Q
plots (normalidad), histogramas, residuales.
- Herramientas:
ggplot2,
patchwork, plotly (R); seaborn,
matplotlib (Python).
11. Aplicaciones
prácticas y estudios de caso
11.1 Análisis de
datos reales
- Estudios de caso: Aplicaciones en salud, economía,
biología, ciencias sociales.
- Interpretación de resultados en contexto: Más allá
del p-valor: magnitud, relevancia práctica.
11.2 Validación de
supuestos
- Diagnósticos: Normalidad (Shapiro-Wilk),
homocedasticidad (Breusch-Pagan), independencia (Durbin-Watson).
- Transformaciones de datos: Log, raíz cuadrada,
Box-Cox para cumplir supuestos.
1. Fundamentos de
Estadística Inferencial para el Sector Salud
Este temario desarrolla los fundamentos de estadística inferencial
con un enfoque en aplicaciones prácticas en el sector salud,
proporcionando explicaciones detalladas y ejemplos específicos para
profesionales médicos, investigadores clínicos y epidemiólogos. La
inferencia estadística permite tomar decisiones basadas en datos
muestrales, esenciales para evaluar tratamientos, analizar prevalencias
de enfermedades y diseñar estudios clínicos.
1.1 Conceptos
básicos
Definición de
Inferencia Estadística
La inferencia estadística es el proceso de usar datos de una muestra
para hacer generalizaciones o predicciones sobre una población más
grande, manejando la incertidumbre inherente a los datos. En salud, esto
significa extraer conclusiones sobre una población (e.g., pacientes con
diabetes en un país) basándose en una muestra (e.g., pacientes de un
hospital). Por ejemplo, un estudio puede estimar la efectividad promedio
de una vacuna a partir de un ensayo clínico o determinar si un nuevo
medicamento reduce significativamente la presión arterial.
Importancia en salud:
- Permite evaluar la eficacia de tratamientos sin estudiar a toda la
población.
- Ayuda a identificar factores de riesgo (e.g., relación entre
tabaquismo y cáncer de pulmón).
- Fundamenta decisiones clínicas y políticas de salud pública con
evidencia estadística.
Ejemplo práctico: Un ensayo clínico con 500
pacientes prueba un nuevo fármaco para la hipertensión. La inferencia
estadística permite estimar si el fármaco reduce la presión arterial en
la población general de hipertensos y si los resultados son
estadísticamente significativos.
Población, muestra
y parámetros
Población: Conjunto total de individuos u objetos de
interés. En salud, podría ser todos los pacientes con una enfermedad
específica (e.g., todos los diabéticos tipo 2 en un país).
Parámetro: Característica numérica de la población,
como la prevalencia de una enfermedad (proporción \(p\)), la media de glucosa en sangre (\(\mu\)), o la varianza de la presión
arterial (\(\sigma^2\)).
Muestra: Subgrupo seleccionado de la población para
estudio. Debe ser representativa para evitar sesgos. Por ejemplo, una
muestra de 1000 pacientes de clínicas urbanas y rurales para estudiar
hipertensión.
Estadístico: Medida calculada a partir de la
muestra, como la media muestral (\(\bar{x}\)) o la proporción muestral (\(\hat{p}\)).
Muestreo en salud:
- Aleatorio simple: Cada paciente tiene la misma
probabilidad de ser seleccionado (e.g., seleccionar pacientes al azar de
un registro hospitalario).
- Estratificado: Divide la población en grupos (e.g.,
por edad o género) y toma muestras de cada uno para garantizar
representatividad.
- Sesgos comunes: Muestras no representativas (e.g.,
solo pacientes de un hospital de élite) pueden llevar a conclusiones
erróneas.
Ejemplo práctico: Para estimar la prevalencia de
obesidad en adultos, se selecciona una muestra aleatoria de 2000
personas. La proporción muestral de obesos (\(\hat{p} = 0.25\)) estima la prevalencia
poblacional (\(p\)).
Tipos de Datos y
Escalas de Medición
Tipos de datos en salud:
- Cuantitativos:
- Discretos: Valores contables, como el número de
hospitalizaciones por año o el número de casos de COVID-19 en un
mes.
- Continuos: Valores en un rango continuo, como el
nivel de glucosa en sangre (mg/dL) o el índice de masa corporal
(IMC).
- Cualitativos:
- Nominales: Categorías sin orden, como el tipo de
sangre (A, B, AB, O) o el diagnóstico (benigno, maligno).
- Ordinales: Categorías con orden, como el estadio
del cáncer (I, II, III, IV) o la gravedad de una enfermedad (leve,
moderada, severa).
Escalas de medición:
- Nominal: Usada para clasificaciones sin orden
inherente (e.g., grupos sanguíneos).
- Ordinal: Para datos con orden pero sin distancias
uniformes (e.g., escala de dolor de 1 a 10, donde la diferencia entre 2
y 3 no es necesariamente igual a la entre 8 y 9).
- Intervalo: Distancias iguales, sin cero absoluto
(e.g., temperatura corporal en °C; 0°C no indica ausencia de
temperatura).
- Razón: Distancias iguales con cero absoluto (e.g.,
peso, frecuencia cardíaca; 0 kg indica ausencia de peso).
Aplicación en salud: La elección de la escala afecta
el análisis. Por ejemplo, comparar promedios de glucosa (razón) requiere
pruebas paramétricas, mientras que clasificar pacientes por estadio de
enfermedad (ordinal) puede necesitar pruebas no paramétricas.
Ejemplo práctico: En un estudio sobre diabetes, los
niveles de HbA1c (razón) se analizan para calcular medias, mientras que
la categoría de control glucémico (controlado, no controlado) es
nominal.
1.2 Probabilidad
Avanzada
Espacios Muestrales
y Eventos
Espacio muestral (S): Conjunto de todos los
resultados posibles de un experimento. En salud, podría ser los
resultados de un test diagnóstico (positivo, negativo) o los posibles
desenlaces de un tratamiento (mejoría, sin cambio, empeoramiento).
Evento: Subconjunto del espacio muestral. Por
ejemplo, en un test de COVID-19, un evento podría ser “resultado
positivo” o “paciente con fiebre y resultado positivo”.
- Eventos simples: Un solo resultado (e.g., un
paciente tiene un test positivo).
- Eventos compuestos: Combinación de resultados
(e.g., paciente con fiebre o tos).
Operaciones:
- Unión: Probabilidad de que ocurra al menos un
evento (e.g., fiebre o tos).
- Intersección: Probabilidad de que ocurran ambos
eventos (e.g., fiebre y tos).
- Complemento: Probabilidad de que no ocurra un
evento (e.g., no tener fiebre).
Ejemplo práctico: En un estudio de detección de
cáncer, el espacio muestral incluye todos los resultados de una
mamografía (normal, anormal). Un evento compuesto podría ser “mamografía
anormal y confirmación de cáncer por biopsia”.
Reglas de
Probabilidad
- Regla de la suma: Para eventos mutuamente
excluyentes (no pueden ocurrir simultáneamente), \(P(A \cup B) = P(A) + P(B)\). Ejemplo: La
probabilidad de que un paciente tenga diabetes tipo 1 o tipo 2
(excluyentes) es la suma de sus probabilidades individuales.
- Regla del producto: Para eventos independientes,
\(P(A \cap B) = P(A) \cdot P(B)\). Si
no son independientes, \(P(A \cap B) = P(A)
\cdot P(B|A)\). Ejemplo: La probabilidad de que un paciente tenga
hipertensión y diabetes (no independientes) requiere considerar la
probabilidad condicional.
- Teorema de Bayes: Actualiza probabilidades basadas
en nueva evidencia: \[
P(A|B) = \frac{P(B|A) \cdot P(A)}{P(B)}
\]
Aplicación en salud: Diagnósticos médicos. Por
ejemplo, para un test de COVID-19:
- \(P(A)\): Probabilidad de tener
COVID-19 (prevalencia).
- \(P(B|A)\): Sensibilidad del test
(probabilidad de un resultado positivo dado que el paciente tiene
COVID-19).
- \(P(A|B)\): Probabilidad de tener
COVID-19 dado un resultado positivo.
Ejemplo práctico: Si la prevalencia de una
enfermedad es 1% (\(P(A) = 0.01\)), la
sensibilidad del test es 95% (\(P(B|A) =
0.95\)), y la especificidad es 90% (\(P(B^c|A^c) = 0.90\)), el teorema de Bayes
calcula la probabilidad de tener la enfermedad dado un resultado
positivo.
Variables
Aleatorias Discretas y Continuas
Variable aleatoria: Asigna valores numéricos a
resultados de un experimento.
- Discretas: Valores contables, como el número de
casos de influenza en una semana o el número de consultas médicas por
paciente.
- Función de masa de probabilidad (PMF): \(P(X = x)\), indica la probabilidad de un
valor específico.
- Continuas: Valores en un rango continuo, como el
tiempo hasta la recuperación o el nivel de colesterol.
- Función de densidad de probabilidad (PDF): \(f(x)\), donde \(P(a \leq X \leq b) = \int_a^b f(x) \,
dx\).
Momentos:
- Esperanza (\(E(X)\)): Valor promedio esperado. Para
discretas: \(\sum x \cdot P(X = x)\);
para continuas: \(\int x \cdot f(x) \,
dx\). Ejemplo: Media de días de hospitalización.
- Varianza (\(Var(X)\)): Mide la dispersión: \(E[(X - E(X))^2]\). Ejemplo: Variabilidad en
los niveles de glucosa entre pacientes.
Ejemplo práctico: En un hospital, el número de
admisiones diarias por infarto (discreta) o el tiempo de espera en
urgencias (continua) son variables aleatorias analizadas para optimizar
recursos.
1.3 Distribuciones de
Probabilidad
Distribuciones
Discretas
Binomial:
- Modela el número de éxitos en \(n\)
ensayos independientes con probabilidad de éxito \(p\).
- PMF: \(P(X = k) = \binom{n}{k} p^k
(1-p)^{n-k}\).
- Aplicación en salud: Número de pacientes que
responden a un tratamiento en un ensayo clínico de \(n\) participantes.
- Ejemplo práctico: En un ensayo con 100 pacientes,
si la probabilidad de respuesta a un fármaco es 0.7, la probabilidad de
que exactamente 70 pacientes respondan es \(P(X = 70) = \binom{100}{70} (0.7)^{70}
(0.3)^{30}\).
- Media: \(E(X) = np\), Varianza:
\(Var(X) = np(1-p)\).
Poisson:
- Modela eventos raros en un intervalo fijo (tiempo, espacio) con tasa
promedio \(\lambda\).
- PMF: \(P(X = k) = \frac{\lambda^k
e^{-\lambda}}{k!}\).
- Aplicación en salud: Número de casos de una
enfermedad rara en un hospital por mes.
- Ejemplo práctico: Si un hospital registra en
promedio 2 casos de meningitis por mes (\(\lambda = 2\)), la probabilidad de observar
3 casos es \(P(X = 3) = \frac{2^3
e^{-2}}{3!}\).
- Media y Varianza: \(E(X) =
\lambda\), \(Var(X) =
\lambda\).
Geométrica:
- Modela el número de ensayos hasta el primer éxito.
- PMF: \(P(X = k) = (1-p)^{k-1}
p\).
- Aplicación en salud: Número de pruebas diagnósticas
hasta detectar un caso positivo.
- Ejemplo práctico: Si la probabilidad de detectar un
caso de tuberculosis en una prueba es 0.05, la probabilidad de encontrar
el primer caso en la tercera prueba es \(P(X =
3) = (0.95)^2 \cdot 0.05\).
- Media: \(E(X) = \frac{1}{p}\),
Varianza: \(Var(X) =
\frac{1-p}{p^2}\).
Distribuciones
Continuas
Normal:
- Distribución simétrica en forma de campana, definida por \(\mu\) (media) y \(\sigma\) (desviación estándar).
- PDF: \(f(x) =
\frac{1}{\sqrt{2\pi\sigma^2}}
e^{-\frac{(x-\mu)^2}{2\sigma^2}}\).
- Aplicación en salud: Variables biológicas como
presión arterial, niveles de colesterol o IMC suelen seguir una
distribución normal.
- Ejemplo práctico: Si la presión arterial sistólica
en adultos tiene \(\mu = 120\) mmHg y
\(\sigma = 15\) mmHg, la probabilidad
de que un paciente tenga una presión entre 110 y 130 mmHg se calcula
integrando la PDF normal.
- Propiedades: ~68% de los datos están dentro de
\(\mu \pm \sigma\), ~95% dentro de
\(\mu \pm 2\sigma\).
t de Student:
- Usada para muestras pequeñas (\(n <
30\)) con varianza desconocida.
- Depende de los grados de libertad (df); con df altos, se asemeja a
la normal.
- Aplicación en salud: Comparar medias de grupos
pequeños, como el efecto de un fármaco en 20 pacientes.
- Ejemplo práctico: Comparar el nivel de glucosa
antes y después de un tratamiento en 15 pacientes usando una prueba
t.
Chi-cuadrado (\(\chi^2\)):
- Suma de cuadrados de variables normales estándar, con \(k\) grados de libertad.
- PDF: \(f(x) = \frac{1}{2^{k/2}
\Gamma(k/2)} x^{k/2-1} e^{-x/2}\), para \(x \geq 0\).
- Aplicación en salud: Pruebas de bondad de ajuste
(e.g., ajustar datos a una distribución esperada) o pruebas de
independencia en tablas de contingencia (e.g., relación entre tabaquismo
y cáncer).
- Ejemplo práctico: Evaluar si la distribución de
casos de diabetes por género coincide con la distribución poblacional
esperada.
F:
- Cociente de dos variables Chi-cuadrado divididas por sus grados de
libertad.
- Aplicación en salud: Comparar varianzas en ANOVA,
como la variabilidad en la respuesta a un tratamiento entre diferentes
hospitales.
- Ejemplo práctico: Comparar la varianza en los
tiempos de recuperación entre dos grupos de pacientes tratados con
diferentes protocolos.
Teorema del Límite
Central y Aproximaciones
Teorema del Límite Central (TLC): La suma (o media)
de un gran número de variables aleatorias independientes, con media
\(\mu\) y varianza \(\sigma^2\), se distribuye aproximadamente
como una normal \(N(\mu, \sigma^2/n)\),
donde \(n\) es el tamaño muestral.
- Aplicación en salud: Permite asumir normalidad en
medias muestrales, como el promedio de presión arterial en una muestra
de 50 pacientes, incluso si los datos individuales no son normales.
- Ejemplo práctico: La media de glucosa en sangre de
40 pacientes se aproxima a una distribución normal, permitiendo pruebas
paramétricas.
Aproximaciones:
- Normal a Binomial: Para \(n\) grande y \(p\) no extremo (\(np \geq 5\), \(n(1-p) \geq 5\)), una binomial se aproxima
a \(N(np, \sqrt{np(1-p)})\). Ejemplo:
Aproximar la probabilidad de que más de 60 de 100 pacientes respondan a
un tratamiento con \(p = 0.7\).
- Normal a Poisson: Para \(\lambda\) grande (\(\lambda > 10\)), una Poisson se aproxima
a \(N(\lambda, \sqrt{\lambda})\).
Ejemplo: Aproximar el número de casos de influenza en un hospital
grande.
- Ejemplo práctico: En un estudio de vacunación, si
1000 personas reciben una vacuna con 80% de efectividad, el número de
protegidos se aproxima a \(N(800, \sqrt{1000
\cdot 0.8 \cdot 0.2})\).
Recursos para el
Autoestudio en Salud
Lecturas:
- “Statistical Methods in Medical Research” de Armitage, Berry y
Matthews.
- “Biostatistics: A Foundation for Analysis in the Health Sciences” de
Daniel.
Ejercicios
prácticos:
- Calcular probabilidades de eventos clínicos (e.g., probabilidad de
un falso positivo en un test diagnóstico).
- Simular datos en R o Python para analizar distribuciones de
variables como presión arterial o tiempo de recuperación.
- Aplicar el teorema de Bayes a problemas diagnósticos (e.g., calcular
la probabilidad de enfermedad dado un test positivo).
Herramientas
computacionales:
- R: Paquetes stats, epiR (para epidemiología), pwr
(cálculo de potencia).
- Python: Librerías scipy.stats, statsmodels, pandas
para análisis de datos clínicos.
Bases de
datos:
- Datasets públicos como los de la OMS, CDC o Kaggle (e.g., datos de
diabetes, COVID-19).
- Ejemplo: Analizar la base de datos NHANES para estudiar factores de
riesgo cardiovascular.
Tabla resumen:
Fundamentos de estadística inferencial en Salud
Tabla 1: Resumen de conceptos clave de estadística inferencial aplicados
al sector salud
|
Concepto
|
Definición
|
Ejemplo.en.Salud
|
|
Inferencia Estadística
|
Proceso de generalizar resultados de una muestra a una población,
considerando la incertidumbre.
|
Estimar la efectividad de una vacuna a partir de un ensayo clínico con
1000 participantes.
|
|
Población
|
Conjunto total de individuos u objetos de interés (e.g., todos los
pacientes con diabetes tipo 2).
|
Todos los adultos hipertensos en Colombia.
|
|
Muestra
|
Subconjunto representativo de la población seleccionado para estudio.
|
Una muestra de 500 pacientes hipertensos de clínicas urbanas y rurales.
|
|
Parámetro
|
Característica numérica de la población (e.g., media poblacional \(\mu\), proporción \(p\)).
|
Prevalencia real de hipertensión en adultos colombianos (\(p = 0.25\)).
|
|
Estadístico
|
Medida calculada a partir de la muestra (e.g., media muestral \(\bar{x}\), proporción \(\hat{p}\)).
|
Prevalencia estimada a partir de la muestra (\(\hat{p} = 0.23\)).
|
|
Variable Aleatoria
|
Función que asigna valores numéricos a resultados de un experimento
(discreta o continua).
|
Número de pacientes que responden a un tratamiento (discreta) o nivel de
colesterol (continua).
|
|
Distribución Binomial
|
Modela el número de éxitos en \(n\)
ensayos independientes con probabilidad constante \(p\).
|
Probabilidad de que 70 de 100 pacientes respondan a un fármaco con \(p = 0.7\).
|
|
Distribución Poisson
|
Modela eventos raros en un intervalo fijo con tasa promedio \(\lambda\).
|
Número de casos de meningitis por mes en un hospital, con \(\lambda = 2\).
|
|
Distribución Normal
|
Distribución continua simétrica, definida por \(\mu\) y \(\sigma\), común en variables biológicas.
|
Distribución de la presión arterial sistólica en adultos (\(\mu = 120\), \(\sigma = 15\)).
|
|
t de Student
|
Distribución para medias muestrales con varianza desconocida y \(n < 30\).
|
Comparar niveles de glucosa antes y después de un tratamiento en 20
pacientes.
|
|
Chi-cuadrado (χ²)
|
Distribución para sumas de cuadrados de normales estándar; usada en
pruebas de independencia.
|
Evaluar si existe asociación entre tabaquismo y cáncer de pulmón en una
tabla de contingencia.
|
|
Teorema de Bayes
|
Actualiza la probabilidad de un evento dado nueva evidencia: \(P(A|B) = \frac{P(B|A)P(A)}{P(B)}\).
|
Calcular la probabilidad de tener COVID-19 dado un test positivo, usando
sensibilidad y prevalencia.
|
|
Teorema del Límite Central
|
La media muestral se distribuye aproximadamente como \(N(\mu, \sigma^2/n)\) para \(n\) grande.
|
La media de glucosa en sangre de 40 pacientes se comporta normalmente,
aunque los datos individuales no lo sean.
|
2. Estimación de
Parámetros para el Sector Salud
Este temario profundiza en la estimación de parámetros con un enfoque
en el sector salud, proporcionando explicaciones detalladas, ejemplos
prácticos y aplicaciones relevantes para profesionales médicos,
investigadores clínicos y epidemiólogos. La estimación de parámetros es
fundamental en estadística inferencial para inferir características
poblacionales (como la prevalencia de una enfermedad o la media de una
variable clínica) a partir de datos muestrales, manejando la
incertidumbre inherente a las muestras.
2.1 Estimación
Puntual
Propiedades de los
Estimadores: Sesgo, Eficiencia, Consistencia
La estimación puntual consiste en utilizar un estadístico calculado a
partir de una muestra para estimar un parámetro poblacional. Por
ejemplo, la media muestral (\(\bar{x}\)) estima la media poblacional
(\(\mu\)). En salud, esto es crucial
para estimar parámetros como la tasa de incidencia de una enfermedad o
la efectividad promedio de un tratamiento. Los estimadores deben cumplir
ciertas propiedades para ser confiables:
Sesgo:
- Un estimador es insesgado si su valor esperado es igual al parámetro
que estima: \(E(\hat{\theta}) =
\theta\).
- Ejemplo: La media muestral \(\bar{x}\) es un estimador insesgado de
\(\mu\) porque \(E(\bar{x}) = \mu\).
- Aplicación en salud: Si se mide la glucosa en sangre de 50 pacientes
diabéticos, la media muestral \(\bar{x}\) proporciona una estimación
insesgada de la media poblacional de glucosa.
- Sesgo en la práctica: Un estimador sesgado, como
usar la varianza muestral sin corrección (\(\sum (x_i - \bar{x})^2 / n\)), subestima la
varianza poblacional (\(\sigma^2\)). La
corrección de Bessel (\(\sum (x_i - \bar{x})^2
/ (n-1)\)) elimina este sesgo.
Eficiencia:
- Un estimador es más eficiente si tiene menor varianza entre todos
los estimadores insesgados para el mismo parámetro.
- Matemáticamente: Si \(\hat{\theta}_1\) y \(\hat{\theta}_2\) son insesgados, \(\hat{\theta}_1\) es más eficiente si \(\text{Var}(\hat{\theta}_1) <
\text{Var}(\hat{\theta}_2)\).
- Aplicación en salud: En un estudio para estimar la prevalencia de
hipertensión, la proporción muestral \(\hat{p}\) es más eficiente que otros
estimadores insesgados porque minimiza la varianza para muestras
grandes.
- Ejemplo práctico: Comparar dos métodos para estimar la proporción de
pacientes con respuesta positiva a un fármaco; el método con menor
varianza es preferido.
Consistencia:
- Un estimador es consistente si, al aumentar el tamaño muestral
(\(n \to \infty\)), converge en
probabilidad al parámetro verdadero: \(\hat{\theta} \xrightarrow{p} \theta\).
- Aplicación en salud: La media muestral \(\bar{x}\) es consistente para \(\mu\); con muestras más grandes (e.g., más
pacientes en un ensayo clínico), la estimación se acerca al valor
real.
- Ejemplo práctico: En un estudio longitudinal de presión arterial, a
medida que se incluyen más pacientes, la media muestral se aproxima cada
vez más a la media poblacional.
Otros criterios:
- Suficiencia: Un estimador es suficiente si captura
toda la información relevante de la muestra sobre el parámetro.
- Robustez: Capacidad del estimador para mantenerse
válido bajo violaciones de supuestos (e.g., no normalidad en datos de
salud).
- Ejemplo en salud: En estudios con datos no normales
(e.g., tiempos de recuperación sesgados), un estimador robusto como la
mediana puede ser más adecuado que la media.
Métodos de
Estimación: Máxima Verosimilitud, Momentos
Existen varios métodos para obtener estimadores puntuales, pero los
más comunes en salud son la máxima verosimilitud y el método de los
momentos.
Máxima Verosimilitud (MLE):
- Definición: Selecciona el valor del parámetro que
maximiza la probabilidad (verosimilitud) de observar los datos
muestrales. La función de verosimilitud es \(L(\theta) = \prod_{i=1}^n f(x_i |
\theta)\), donde \(f(x_i |
\theta)\) es la densidad o masa de probabilidad.
- Procedimiento:
- Definir la función de verosimilitud según la distribución asumida
(e.g., normal, binomial).
- Maximizar \(L(\theta)\) (a menudo
usando el logaritmo: \(\ln
L(\theta)\)).
- Resolver derivando e igualando a cero o usando métodos
numéricos.
- Propiedades: Los estimadores MLE son consistentes,
asintóticamente eficientes y, bajo ciertas condiciones, insesgados para
muestras grandes.
- Aplicación en salud: Estimar la tasa de incidencia
(\(\lambda\)) de una enfermedad rara
modelada con una distribución Poisson. Por ejemplo, si un hospital
registra 5 casos de meningitis en un mes, el MLE de \(\lambda\) es 5.
- Ejemplo práctico: En un ensayo clínico, se usa MLE
para estimar la probabilidad de éxito (\(p\)) de un tratamiento binomial,
maximizando \(L(p) = \binom{n}{k} p^k
(1-p)^{n-k}\).
Método de los Momentos:
- Definición: Igualar los momentos muestrales (e.g.,
media, varianza) a los momentos teóricos de la población y resolver para
el parámetro.
- Procedimiento:
- Calcular momentos muestrales: \(m_1 =
\bar{x}\), \(m_2 = \frac{1}{n} \sum
(x_i - \bar{x})^2\).
- Igualarlos a momentos poblacionales: \(E(X) = \mu\), \(E(X^2) - [E(X)]^2 = \sigma^2\).
- Resolver el sistema de ecuaciones.
- Propiedades: Fácil de calcular, pero puede ser
menos eficiente que MLE, especialmente para distribuciones
complejas.
- Aplicación en salud: Estimar la media y varianza de
niveles de colesterol en una población asumiendo normalidad.
- Ejemplo práctico: Para una muestra de 100 pacientes
con niveles de glucosa, la media muestral (\(\bar{x} = 120 \, \text{mg/dL}\)) y la
varianza muestral (\(s^2 = 225\)) son
estimadores de momentos para \(\mu\) y
\(\sigma^2\).
Comparación en salud:
- MLE: Preferido en modelos complejos (e.g.,
regresión logística para predecir riesgo de infarto) debido a su
eficiencia y propiedades asintóticas.
- Momentos: Útil para estimaciones rápidas en
estudios exploratorios o cuando los datos no se ajustan a distribuciones
estándar.
- Ejemplo combinado: En un estudio de prevalencia de
diabetes, MLE estima la proporción \(p\) de una distribución binomial, mientras
que el método de los momentos podría usarse para una estimación inicial
basada en la proporción muestral.
2.2 Estimación por
Intervalos
Interpretación y
Cálculo de Intervalos
Interpretación:
- Un IC al 95% significa que, si se repite el experimento muchas
veces, aproximadamente el 95% de los intervalos contendrán el parámetro
verdadero.
- Error común: No significa que hay un 95% de
probabilidad de que el parámetro esté en el intervalo, ya que el
parámetro es fijo (no aleatorio).
- En salud, los IC reflejan la precisión de la estimación. Un
intervalo más estrecho indica mayor precisión, mientras que uno más
amplio sugiere mayor incertidumbre.
Cálculo:
- Pasos generales:
- Identificar el parámetro de interés (\(\mu\), \(p\), \(\sigma^2\)).
- Seleccionar el nivel de confianza (e.g., 95%) y encontrar los
valores críticos (\(z\), \(t\), \(\chi^2\)).
- Calcular el estadístico muestral (\(\bar{x}\), \(\hat{p}\), \(s^2\)) y el error estándar.
- Construir el intervalo usando las fórmulas correspondientes.
- Consideraciones en salud:
- Verificar supuestos: Normalidad para medias y varianzas, tamaño
muestral suficiente para proporciones.
- Usar métodos robustos (e.g., bootstrap) si los supuestos no se
cumplen, como en datos no normales de tiempos de recuperación.
- Ejemplo práctico: En un estudio de prevalencia de
COVID-19, un IC al 95% de (0.03, 0.07) para la proporción de casos
positivos indica que la prevalencia poblacional está entre 3% y 7%, con
alta confianza en la estimación.
Tamaño Muestral y
Precisión
El tamaño muestral (\(n\)) afecta la
precisión de los intervalos de confianza: muestras más grandes producen
intervalos más estrechos, reduciendo la incertidumbre.
Fórmulas para el tamaño muestral:
Para la media: \[
n = \left( \frac{z_{\alpha/2} \cdot \sigma}{E} \right)^2
\] Donde \(E\) es el margen de
error (mitad del ancho del IC), \(\sigma\) es la desviación estándar
(estimada de estudios previos).
Para la proporción: \[
n = \frac{z_{\alpha/2}^2 \cdot p(1-p)}{E^2}
\] Donde \(p\) es una estimación
previa de la proporción (o 0.5 si no hay datos previos).
Para la varianza: Más complejo, requiere tablas
de Chi-cuadrado o software estadístico.
Aplicación en salud:
- Determinar cuántos pacientes incluir en un ensayo clínico para
estimar la efectividad de un tratamiento con un margen de error
específico.
- Ejemplo: Para estimar la media de glucosa con un
margen de error de 5 mg/dL, \(\sigma = 20 \,
\text{mg/dL}\), y 95% de confianza (\(z
= 1.96\)): \[
n = \left( \frac{1.96 \cdot 20}{5} \right)^2 = 61.47 \approx 62
\] Se necesitan al menos 62 pacientes.
Factores que afectan la precisión:
- Nivel de confianza: Un IC al 99% es más amplio que
uno al 95%, requiriendo mayor \(n\).
- Variabilidad: Mayor varianza (\(\sigma^2\)) requiere muestras más
grandes.
- Margen de error: Un \(E\) más pequeño aumenta \(n\).
Ejemplo práctico: Para estimar la prevalencia de
obesidad con un margen de error de 0.02 y \(p
\approx 0.3\): \[
n = \frac{1.96^2 \cdot 0.3 \cdot 0.7}{0.02^2} \approx 2017
\] Se necesitan aproximadamente 2017 sujetos para un IC al 95%
con alta precisión.
Recursos para el
Autoestudio en Salud
Lecturas:
- “Statistical Methods in Medical Research” de Armitage, Berry y
Matthews (Capítulos sobre estimación).
- “Biostatistics: A Foundation for Analysis in the Health Sciences” de
Daniel (Capítulos 6-7).
Ejercicios
prácticos:
- Calcular estimadores puntuales (MLE y momentos) para tasas de
incidencia o medias de biomarcadores.
- Construir IC para medias y proporciones usando datos de ensayos
clínicos (e.g., bases de datos de la OMS o CDC).
- Determinar tamaños muestrales para estudios de prevalencia o ensayos
clínicos.
Herramientas
computacionales:
- R: Paquetes stats (para IC), pwr (tamaño muestral),
MASS (MLE).
- Python: Librerías scipy.stats, statsmodels para
cálculos de IC y estimación.
- Ejemplo en R:
confint(lm(y ~ 1)) para
IC de medias; en Python:
statsmodels.stats.proportion.proportion_confint.
Bases de
datos:
- NHANES (National Health and Nutrition Examination Survey) para datos
de biomarcadores.
- Ensayos clínicos en ClinicalTrials.gov para practicar
estimaciones.
Tabla 2: Resumen de métodos de estimación de parámetros en salud
|
Concepto
|
Definición
|
Ejemplo.en.Salud
|
|
Estimación Puntual
|
Usar un estadístico muestral para estimar un parámetro poblacional
(e.g., \(\bar{x}\) estima \(\mu\)).
|
Estimar la prevalencia de diabetes usando la proporción muestral \(\hat{p}\).
|
|
Estimador Insesgado
|
Un estimador con \(E(\hat{\theta}) =
\theta\). Ej: \(\bar{x}\) es
insesgado para \(\mu\).
|
La media de glucosa en 50 pacientes diabéticos estima la media
poblacional sin sesgo.
|
|
Eficiencia
|
Un estimador es más eficiente si tiene menor varianza entre todos los
insesgados.
|
En un estudio de hipertensión, \(\hat{p}\) es más eficiente que otros
estimadores.
|
|
Consistencia
|
El estimador converge al valor verdadero cuando \(n \to \infty\).
|
A medida que se incluyen más pacientes, \(\bar{x}\) se acerca a \(\mu\).
|
|
Máxima Verosimilitud (MLE)
|
Estimador que maximiza la probabilidad de observar los datos: \(L(\theta) = \prod f(x_i|\theta)\).
|
Estimar la tasa de incidencia de meningitis (\(\lambda\)) con Poisson: MLE = 5 casos/mes.
|
|
Método de los Momentos
|
Iguala momentos muestrales a teóricos (e.g., \(\bar{x} = \mu\), \(s^2 = \sigma^2\)).
|
Estimar \(\mu\) y \(\sigma^2\) de colesterol usando \(\bar{x} = 190\) mg/dL y \(s^2 = 400\).
|
|
Intervalo de Confianza (IC)
|
Rango de valores plausibles para un parámetro, con un nivel de confianza
(e.g., 95%).
|
IC del 95% para la media de presión arterial: (125.7, 134.3) mmHg.
|
|
IC para la Media (σ desconocida)
|
Usa t de Student: \(\bar{x} \pm
t_{\alpha/2,n-1} \cdot \frac{s}{\sqrt{n}}\).
|
En 50 pacientes, \(\bar{x} = 130\),
\(s = 15\): IC ≈ (125.7, 134.3) mg/dL.
|
|
IC para la Proporción
|
Aproximación normal: \(\hat{p} \pm
z_{\alpha/2} \cdot \sqrt{\frac{\hat{p}(1-\hat{p})}{n}}\).
|
En 200 pacientes, \(\hat{p} = 0.2\): IC
95% ≈ (0.145, 0.255).
|
|
IC para la Varianza
|
Basado en \(\chi^2\): \(\left( \frac{(n-1)s^2}{\chi^2_{\alpha/2}},
\frac{(n-1)s^2}{\chi^2_{1-\alpha/2}} \right)\).
|
Para \(s^2 = 25\), \(n = 30\): IC 95% para \(\sigma^2\) ≈ (15.8, 45.2) días².
|
|
Tamaño Muestral (Media)
|
\(n = \left( \frac{z_{\alpha/2} \cdot
\sigma}{E} \right)^2\)
|
Con \(\sigma = 20\), \(E = 5\), \(z =
1.96\): \(n \approx 62\)
pacientes.
|
|
Tamaño Muestral (Proporción)
|
\(n = \frac{z_{\alpha/2}^2 \cdot
p(1-p)}{E^2}\)
|
Con \(p = 0.3\), \(E = 0.02\): \(n
\approx 2017\) sujetos.
|
3. Pruebas de Hipótesis
para el Sector Salud
Este temario desarrolla los conceptos de pruebas de hipótesis con un
enfoque en aplicaciones en el sector salud, proporcionando explicaciones
detalladas, ejemplos prácticos y aplicaciones relevantes para
profesionales médicos, investigadores clínicos y epidemiólogos. Las
pruebas de hipótesis son herramientas fundamentales en estadística
inferencial para tomar decisiones basadas en datos muestrales, evaluando
afirmaciones sobre parámetros poblacionales (e.g., efectividad de
tratamientos, prevalencia de enfermedades) y manejando la incertidumbre
inherente a las muestras.
3.1 Fundamentos
Hipótesis Nula y
Alternativa
Las pruebas de hipótesis evalúan afirmaciones sobre parámetros
poblacionales comparando datos muestrales con una hipótesis específica.
En el sector salud, estas pruebas son esenciales para determinar, por
ejemplo, si un nuevo medicamento mejora los resultados clínicos o si una
intervención reduce la incidencia de una enfermedad.
Hipótesis nula (\(H_0\)): Afirmación de que no hay efecto o
diferencia en la población. Representa el statu quo o la ausencia de
cambio. Por ejemplo, \(H_0: \mu = 120 \,
\text{mmHg}\) (la media de presión arterial no cambia con un
tratamiento).
- En salud, \(H_0\) suele asumir que
un tratamiento no es efectivo o que no hay diferencias entre
grupos.
Hipótesis alternativa (\(H_1\) o \(H_a\)): Afirmación opuesta a \(H_0\), que sugiere un efecto o diferencia.
Puede ser:
- Unilateral: \(H_1: \mu
> 120\) o \(H_1: \mu <
120\) (e.g., el tratamiento reduce la presión arterial).
- Bilateral: \(H_1: \mu
\neq 120\) (e.g., el tratamiento afecta la presión arterial, sin
especificar la dirección).
Ejemplo práctico: En un ensayo clínico, \(H_0\): “El nuevo fármaco no reduce la
glucosa en sangre (\(\mu_{\text{tratamiento}}
= \mu_{\text{placebo}}\))”, frente a \(H_1\): “El fármaco reduce la glucosa (\(\mu_{\text{tratamiento}} <
\mu_{\text{placebo}}\))”.
Errores Tipo I y
Tipo II
Las pruebas de hipótesis implican riesgos de tomar decisiones
incorrectas debido a la variabilidad muestral.
Error Tipo I (\(\alpha\)): Rechazar \(H_0\) cuando es verdadera (falso
positivo).
- Probabilidad: \(\alpha\), conocida como nivel de
significancia.
- En salud: Diagnosticar erróneamente que un
tratamiento es efectivo cuando no lo es (e.g., aprobar un fármaco
ineficaz).
- Ejemplo práctico: Concluir que una vacuna previene
el COVID-19 (\(H_0\) rechazada) cuando
en realidad no lo hace, con probabilidad \(\alpha = 0.05\).
Error Tipo II (\(\beta\)): No rechazar \(H_0\) cuando es falsa (falso negativo).
- Probabilidad: \(\beta\), relacionada con la potencia de la
prueba (\(1 - \beta\)).
- En salud: No detectar un efecto real de un
tratamiento (e.g., descartar un fármaco efectivo).
- Ejemplo práctico: No detectar que un nuevo
tratamiento reduce significativamente los niveles de colesterol,
perdiendo una oportunidad terapéutica.
Relación entre errores: Reducir \(\alpha\) (e.g., de 0.05 a 0.01) aumenta
\(\beta\), y viceversa, a menos que se
aumente el tamaño muestral.
Nivel de
Significancia y Potencia de la Prueba
Nivel de significancia (\(\alpha\)): Probabilidad de cometer un error
Tipo I, típicamente 0.05 (5%) o 0.01 (1%) en estudios clínicos.
- Representa el umbral para rechazar \(H_0\). Un valor p menor que \(\alpha\) indica evidencia suficiente para
rechazar \(H_0\).
- En salud: Un \(\alpha =
0.05\) implica que hay un 5% de probabilidad de rechazar
erróneamente \(H_0\), un estándar común
en ensayos clínicos.
Potencia de la prueba (\(1
- \beta\)): Probabilidad de rechazar \(H_0\) cuando \(H_1\) es verdadera, es decir, detectar un
efecto real.
- Depende de:
- Tamaño del efecto (diferencia entre \(H_0\) y \(H_1\)).
- Tamaño muestral (\(n\)).
- Varianza de los datos.
- Nivel de significancia (\(\alpha\)).
- En salud: Una potencia de 0.8 (80%) o mayor es
deseable para garantizar que los ensayos clínicos detecten efectos
clínicamente relevantes.
- Ejemplo práctico: En un ensayo para evaluar un
fármaco antihipertensivo, una potencia de 0.9 asegura un 90% de
probabilidad de detectar una reducción de 10 mmHg en la presión arterial
si esta existe.
Cálculo de la potencia:
- Usa software como R (pwr) o fórmulas específicas basadas en la
distribución (e.g., normal, t).
- Ejemplo: Para una prueba t de una media con tamaño
del efecto \(d = \frac{\mu_1 - \mu_0}{\sigma}
= 0.5\), \(\alpha = 0.05\), y
\(n = 50\), la potencia se calcula
numéricamente.
3.2 Pruebas
Paramétricas
Las pruebas paramétricas asumen que los datos siguen una distribución
específica (generalmente normal) y son adecuadas para variables
continuas o discretas con muestras grandes.
Pruebas para
Proporciones
Prueba z para una proporción:
- Uso: Comparar una proporción muestral (\(\hat{p}\)) con una proporción poblacional
(\(p_0\)), asumiendo \(n \hat{p} \geq 5\), \(n(1-\hat{p}) \geq 5\).
- Estadístico: \[
z = \frac{\hat{p} - p_0}{\sqrt{\frac{p_0 (1-p_0)}{n}}}
\]
- Aplicación en salud: Evaluar si la prevalencia de
una enfermedad difiere de un valor esperado.
- Ejemplo práctico: Si \(p_0 = 0.1\) (prevalencia esperada de
diabetes), y en 200 pacientes \(\hat{p} =
0.14\), el estadístico es: \[
z = \frac{0.14 - 0.1}{\sqrt{\frac{0.1 \cdot 0.9}{200}}} \approx 1.89
\] Con \(z_{0.025} = 1.96\), no
se rechaza \(H_0\) (\(p > 0.05\)).
Prueba z para dos proporciones:
- Uso: Comparar proporciones entre dos grupos (\(p_1 \neq p_2\)).
- Estadístico: \[
z = \frac{\hat{p}_1 - \hat{p}_2}{\sqrt{\hat{p}(1-\hat{p}) \left(
\frac{1}{n_1} + \frac{1}{n_2} \right)}}
\] Donde \(\hat{p} = \frac{x_1 +
x_2}{n_1 + n_2}\) es la proporción combinada.
- Aplicación en salud: Comparar tasas de respuesta
entre dos tratamientos.
- Ejemplo práctico: En un ensayo, 30 de 100 pacientes
tratados responden (\(\hat{p}_1 =
0.3\)), y 20 de 100 en placebo (\(\hat{p}_2 = 0.2\)). Con \(\hat{p} = \frac{30+20}{100+100} = 0.25\):
\[
z = \frac{0.3 - 0.2}{\sqrt{0.25 \cdot 0.75 \left( \frac{1}{100} +
\frac{1}{100} \right)}} \approx 1.63
\] No se rechaza \(H_0\) (\(p > 0.05\)).
Pruebas para
Varianzas (Chi-cuadrado, F)
Prueba Chi-cuadrado para una varianza:
- Uso: Comparar la varianza muestral (\(s^2\)) con una varianza poblacional (\(\sigma_0^2\)), asumiendo normalidad.
- Estadístico: \[
\chi^2 = \frac{(n-1)s^2}{\sigma_0^2}
\] Con \(n-1\) grados de
libertad.
- Aplicación en salud: Evaluar la variabilidad en
tiempos de recuperación.
- Ejemplo práctico: Para \(n = 30\), \(s^2 =
25 \, \text{días}^2\), y \(\sigma_0^2 =
20\): \[
\chi^2 = \frac{29 \cdot 25}{20} = 36.25
\] Comparado con \(\chi^2_{0.025, 29}
\approx 45.72\) y \(\chi^2_{0.975, 29}
\approx 16.05\), no se rechaza \(H_0\).
Prueba F para dos varianzas:
- Uso: Comparar varianzas de dos grupos (\(\sigma_1^2 \neq \sigma_2^2\)).
- Estadístico: \[
F = \frac{s_1^2}{s_2^2}
\] Con grados de libertad \(n_1-1\) y \(n_2-1\).
- Aplicación en salud: Comparar la variabilidad en
niveles de colesterol entre dos grupos de tratamiento.
- Ejemplo práctico: Para grupo 1 (\(n_1 = 40\), \(s_1^2 = 100\)) y grupo 2 (\(n_2 = 50\), \(s_2^2 = 80\)): \[
F = \frac{100}{80} = 1.25
\] Comparado con valores críticos de la distribución F, no se
rechaza \(H_0\).
3.3 Pruebas No
Paramétricas
Las pruebas no paramétricas no asumen normalidad y son útiles para
datos ordinales, no normales o con muestras pequeñas.
Prueba de Wilcoxon,
Mann-Whitney, Kruskal-Wallis
Prueba de Wilcoxon (pareada):
- Uso: Comparar dos muestras pareadas (e.g., antes y
después de un tratamiento) cuando los datos no son normales.
- Método: Calcula diferencias, ordena por rangos
absolutos y compara la suma de rangos positivos y negativos.
- Aplicación en salud: Evaluar si un tratamiento
reduce el dolor (escala ordinal) en los mismos pacientes.
- Ejemplo práctico: En 10 pacientes, las diferencias
en puntajes de dolor antes y después son ordenadas, y el estadístico de
Wilcoxon determina si hay un cambio significativo.
Prueba de Mann-Whitney U:
- Uso: Comparar dos grupos independientes cuando los
datos no son normales.
- Método: Combina las observaciones, asigna rangos y
calcula el estadístico \(U\).
- Aplicación en salud: Comparar tiempos de
recuperación entre dos grupos de pacientes.
- Ejemplo práctico: Comparar el tiempo de
recuperación entre pacientes con dos tratamientos diferentes, usando
rangos para evitar supuestos de normalidad.
Prueba de Kruskal-Wallis:
- Uso: Comparar más de dos grupos independientes
(extensión de Mann-Whitney).
- Método: Asigna rangos a todas las observaciones y
compara las sumas de rangos entre grupos.
- Aplicación en salud: Comparar la severidad de
síntomas entre tres grupos de tratamiento.
- Ejemplo práctico: Evaluar si tres medicamentos
producen diferencias en la escala de dolor en pacientes con
artritis.
Prueba de Signos y
Rangos
Prueba de signos:
- Uso: Comparar muestras pareadas contando signos de
diferencias (positivas o negativas).
- Aplicación en salud: Evaluar si un tratamiento
mejora un síntoma (e.g., más pacientes mejoran que empeoran).
- Ejemplo práctico: En 20 pacientes, 15 mejoran y 5
empeoran tras un tratamiento. La prueba de signos evalúa si la
proporción de mejoras es significativa.
Prueba de rangos con signo de Wilcoxon: Combina
signos y magnitudes (rangos) para mayor sensibilidad que la prueba de
signos.
- Ejemplo práctico: Comparar niveles de glucosa antes
y después de un tratamiento en 15 pacientes con datos no normales.
Ventajas y
Limitaciones
Ventajas de pruebas no paramétricas:
- No requieren supuestos de normalidad o varianzas iguales, ideales
para datos ordinales o no normales (e.g., escalas de dolor, tiempos de
recuperación sesgados).
- Robustas frente a valores atípicos.
- Útiles en muestras pequeñas o datos categóricos.
Limitaciones:
- Menos potencia que las pruebas paramétricas cuando los supuestos de
estas se cumplen.
- Menos precisas para detectar diferencias pequeñas.
- Interpretación menos directa en términos de parámetros
poblacionales.
Aplicación en salud: Las pruebas no paramétricas son
preferidas en estudios con escalas ordinales (e.g., satisfacción del
paciente) o datos no normales (e.g., tiempos de espera en
urgencias).
Recursos para el
Autoestudio en Salud
Lecturas:
- “Statistical Methods in Medical Research” de Armitage, Berry y
Matthews (Capítulos sobre pruebas de hipótesis).
- “Nonparametric Statistics for Health Care Research” de Pett.
Ejercicios
prácticos:
- Realizar pruebas z y t para comparar medias de biomarcadores (e.g.,
glucosa, colesterol).
- Aplicar pruebas no paramétricas a datos de escalas ordinales (e.g.,
severidad de síntomas).
- Calcular potencia y tamaño muestral para ensayos clínicos usando R o
Python.
Herramientas
computacionales:
- R: Paquetes stats (t.test, wilcox.test), pwr
(cálculo de potencia).
- Python: Librerías scipy.stats (mannwhitneyu,
kruskal), statsmodels.
- Ejemplo en R:
t.test(x, y, paired=TRUE) para prueba t pareada;
wilcox.test(x, y) para Wilcoxon.
Bases de
datos:
- NHANES para datos de salud poblacional.
- Ensayos clínicos en ClinicalTrials.gov para practicar pruebas de
hipótesis.
Tabla Resumen: Pruebas
de Hipótesis en el Sector Salud
Tabla 3: Resumen de pruebas de hipótesis aplicadas al sector salud
|
Prueba
|
Supuestos
|
Estadístico
|
Aplicación.en.Salud
|
Ejemplo.Práctico
|
|
z-test (una media)
|
Normalidad o n ≥ 30; varianza poblacional conocida
|
\(z = \frac{\bar{x} - \mu_0}{\sigma /
\sqrt{n}}\)
|
Comparar media de glucosa con un estándar clínico
|
¿La glucosa media (125 mg/dL) en 100 pacientes difiere de 120?
|
|
t-test (una media)
|
Normalidad (especialmente si n < 30); varianza desconocida
|
\(t = \frac{\bar{x} - \mu_0}{s /
\sqrt{n}}\)
|
Evaluar cambio en presión arterial tras tratamiento
|
¿El tiempo de recuperación (10 días, s=2) difiere de 9 días?
|
|
t-test (dos medias, independientes)
|
Normalidad, varianzas iguales (o Welch), muestras independientes
|
\(t = \frac{\bar{x}_1 -
\bar{x}_2}{\sqrt{\frac{s_1^2}{n_1} + \frac{s_2^2}{n_2}}}\)
|
Comparar niveles de colesterol entre tratados y placebo
|
Grupo tratado: 115 mmHg vs. placebo: 120 mmHg
|
|
t-test (pareado)
|
Diferencias normalmente distribuidas (n pequeñas)
|
\(t = \frac{\bar{d}}{s_d / \sqrt{n}}\)
|
Comparar dolor antes y después de un tratamiento
|
Puntaje de dolor disminuye de 7 a 5 en 15 pacientes
|
|
z-test (una proporción)
|
n·p̂ ≥ 5, n·(1−p̂) ≥ 5
|
\(z = \frac{\hat{p} -
p_0}{\sqrt{\frac{p_0(1-p_0)}{n}}}\)
|
Prevalencia de diabetes vs. valor esperado
|
En 200 pacientes, ¿p = 0.14 difiere de p₀ = 0.10?
|
|
z-test (dos proporciones)
|
Muestras independientes, n·p̂ ≥ 5 en ambos grupos
|
\(z = \frac{\hat{p}_1 -
\hat{p}_2}{\sqrt{\hat{p}(1-\hat{p})\left(\frac{1}{n_1} +
\frac{1}{n_2}\right)}}}\)
|
Comparar tasas de respuesta entre dos tratamientos
|
30% respondedores vs. 20% en placebo (n=100 cada grupo)
|
|
Chi-cuadrado (una varianza)
|
Normalidad, datos continuos
|
\(\chi^2 =
\frac{(n-1)s^2}{\sigma_0^2}\)
|
Evaluar variabilidad en tiempos de recuperación
|
s² = 25 días² vs. σ₀² = 20: ¿varianza mayor?
|
|
F-test (dos varianzas)
|
Normalidad en ambos grupos, muestras independientes
|
\(F = \frac{s_1^2}{s_2^2}\)
|
Comparar dispersión de biomarcadores entre hospitales
|
s₁² = 100 vs. s₂² = 80: ¿diferencia en variabilidad?
|
|
Wilcoxon (pareado)
|
Datos pareados, no necesariamente normales
|
Suma de rangos con signo
|
Efecto de un fármaco en pacientes pareados
|
Diferencias en glucosa antes/después: signos y rangos
|
|
Mann-Whitney U
|
Datos independientes, no normales u ordinales
|
\(U = n_1 n_2 + \frac{n_1(n_1+1)}{2} -
R_1\)
|
Comparar tiempos de recuperación entre tratamientos
|
Tiempos de recuperación: tratamiento A vs. B
|
|
Kruskal-Wallis
|
Más de dos grupos, independientes, no normales
|
\(H = \frac{12}{N(N+1)} \sum \frac{R_i^2}{n_i}
- 3(N+1)\)
|
Comparar severidad de síntomas en tres grupos
|
Escalas de dolor: medicamento A, B, C
|
4. Análisis de Varianza
(ANOVA) para el Sector Salud
Este temario desarrolla los conceptos de análisis de varianza (ANOVA)
con un enfoque en aplicaciones en el sector salud, proporcionando
explicaciones detalladas, ejemplos prácticos y aplicaciones relevantes
para profesionales médicos, investigadores clínicos y epidemiólogos.
ANOVA es una herramienta estadística clave para comparar medias entre
múltiples grupos, evaluando si las diferencias observadas son
estadísticamente significativas, lo cual es fundamental en ensayos
clínicos, estudios epidemiológicos y evaluaciones de intervenciones en
salud.
4.1 ANOVA de un
factor
Supuestos y
Modelo
El ANOVA de un factor (o unidireccional) se utiliza para comparar las
medias de tres o más grupos independientes basados en un solo factor
(variable independiente). En salud, esto podría implicar comparar el
efecto de diferentes tratamientos sobre una variable como la presión
arterial o el nivel de glucosa.
Supuestos:
- Normalidad: Los datos de cada grupo deben seguir
una distribución aproximadamente normal. En salud, esto puede
verificarse con gráficos Q-Q o pruebas como Shapiro-Wilk.
- Homogeneidad de varianzas (homocedasticidad): Las
varianzas de los grupos deben ser iguales, verificable con pruebas como
Levene o Bartlett.
- Independencia: Las observaciones entre y dentro de
los grupos deben ser independientes. En ensayos clínicos, esto se
asegura mediante aleatorización.
- Escala de medición: La variable dependiente debe
ser continua (e.g., niveles de colesterol, tiempo de recuperación).
Modelo:
El modelo matemático para ANOVA de un factor es: \[
Y_{ij} = \mu + \tau_i + \epsilon_{ij}
\] Donde \(Y_{ij}\) es la
observación \(j\) en el grupo \(i\), \(\mu\) es la media general, \(\tau_i\) es el efecto del grupo \(i\), y \(\epsilon_{ij}\) es el error aleatorio
(\(\epsilon_{ij} \sim N(0,
\sigma^2)\)).
Hipótesis:
- \(H_0\): Las medias de todos los
grupos son iguales (\(\mu_1 = \mu_2 = \dots =
\mu_k\)).
- \(H_1\): Al menos una media
difiere.
Aplicación en salud: Comparar la media de presión
arterial sistólica entre tres grupos de pacientes tratados con
diferentes antihipertensivos.
Ejemplo práctico: En un estudio, se compara el nivel
de glucosa en sangre (mg/dL) entre tres grupos de pacientes diabéticos
tratados con insulina, metformina, o placebo. Los supuestos se verifican
antes de proceder con el ANOVA.
Suma de Cuadrados y
Tabla ANOVA
El ANOVA descompone la variabilidad total de los datos en componentes
atribuibles al factor (entre grupos) y al error (dentro de grupos).
Suma de cuadrados (SC):
Total (SCT): Variabilidad total de los datos:
\[
SCT = \sum_{i=1}^k \sum_{j=1}^{n_i} (Y_{ij} - \bar{Y})^2
\] Donde \(\bar{Y}\) es la media
general.
Entre grupos (SCE): Variabilidad debido al
factor: \[
SCE = \sum_{i=1}^k n_i (\bar{Y}_i - \bar{Y})^2
\] Donde \(\bar{Y}_i\) es la
media del grupo \(i\), y \(n_i\) es el tamaño del grupo.
Dentro de grupos (SCR): Variabilidad residual
(error): \[
SCR = \sum_{i=1}^k \sum_{j=1}^{n_i} (Y_{ij} - \bar{Y}_i)^2
\] Relación: \(SCT = SCE +
SCR\).
Estadístico F:
Compara la varianza entre grupos con la varianza dentro de grupos:
\[
F = \frac{\text{CME}}{\text{CMR}}
\] Donde \(\text{CME} =
\frac{SCE}{k-1}\) (cuadrado medio entre grupos), \(\text{CMR} = \frac{SCR}{N-k}\) (cuadrado
medio residual), \(k\) es el número de
grupos, y \(N\) es el número total de
observaciones.
Se compara con valores críticos de la distribución F con \(k-1\) y \(N-k\) grados de libertad.
Tabla ANOVA:
| Entre grupos |
\(k-1\) |
\(SCE\) |
\(\text{CME}\) |
\(F\) |
\(p\) |
| Dentro de grupos |
\(N-k\) |
\(SCR\) |
\(\text{CMR}\) |
|
|
| Total |
\(N-1\) |
\(SCT\) |
|
|
|
Aplicación en salud: Evaluar si tres dosis de un
fármaco producen diferencias significativas en la reducción de
colesterol LDL.
Ejemplo práctico: En un estudio con tres grupos
(\(n_1 = n_2 = n_3 = 30\)) tratados con
diferentes dosis de un antihipertensivo, las medias de presión arterial
son 120, 115, y 118 mmHg. La tabla ANOVA muestra \(F = 4.5\), con \(p = 0.015\), indicando que se rechaza \(H_0\) (\(p <
0.05\)), sugiriendo diferencias entre al menos dos grupos.
Pruebas Post-hoc
(Tukey, Bonferroni)
Cuando ANOVA rechaza \(H_0\), las
pruebas post-hoc identifican qué pares de grupos difieren.
Prueba de Tukey (HSD):
- Compara todas las combinaciones de pares de medias, ajustando por
comparaciones múltiples.
- Estadístico: \[
q = \frac{\bar{Y}_i - \bar{Y}_j}{\sqrt{\text{CMR} / n}}
\] Comparado con valores críticos de la distribución de rango
estudentizado.
- Aplicación en salud: Identificar cuál de tres
tratamientos antihipertensivos es más efectivo.
- Ejemplo práctico: Tras un ANOVA significativo,
Tukey muestra que la dosis media (115 mmHg) difiere significativamente
de la dosis baja (120 mmHg), pero no de la dosis alta (118 mmHg).
Corrección de Bonferroni:
- Ajusta el nivel de significancia para múltiples comparaciones: \(\alpha' = \frac{\alpha}{m}\), donde
\(m\) es el número de
comparaciones.
- Ventaja: Simple, pero conservador (puede reducir la
potencia).
- Aplicación en salud: Comparar tasas de recuperación
entre cuatro grupos de tratamiento, ajustando \(\alpha = 0.05/6 = 0.0083\) para 6
comparaciones.
- Ejemplo práctico: En un estudio con cuatro
tratamientos, Bonferroni identifica diferencias significativas solo
entre el tratamiento más efectivo y el placebo.
Consideraciones: Tukey es preferido para
comparaciones múltiples en ANOVA balanceado, mientras que Bonferroni es
útil cuando se realizan pocas comparaciones o en contextos
exploratorios.
4.2 ANOVA de dos
factores
El ANOVA de dos factores analiza el efecto de dos variables
categóricas (factores) sobre una variable dependiente continua,
permitiendo evaluar efectos principales e interacciones.
Interacciones y
Efectos Principales
Efectos principales: Impacto de cada factor sobre la
variable dependiente, ignorando el otro factor.
- Ejemplo: Efecto del tipo de tratamiento (fármaco A
vs. B) y del sexo (hombre vs. mujer) sobre la presión arterial.
Interacción: Cuando el efecto de un factor depende
del nivel del otro factor.
- Ejemplo: Un fármaco puede ser más efectivo en
hombres que en mujeres, indicando una interacción entre tratamiento y
sexo.
Modelo: \[
Y_{ijk} = \mu + \alpha_i + \beta_j + (\alpha\beta)_{ij} + \epsilon_{ijk}
\] Donde \(\alpha_i\) es el
efecto del factor A, \(\beta_j\) es el
efecto del factor B, \((\alpha\beta)_{ij}\) es la interacción, y
\(\epsilon_{ijk}\) es el error.
Hipótesis:
- \(H_0\): No hay efecto principal de
A (\(\alpha_i = 0\)).
- \(H_0\): No hay efecto principal de
B (\(\beta_j = 0\)).
- \(H_0\): No hay interacción (\((\alpha\beta)_{ij} = 0\)).
Aplicación en salud: Evaluar si el efecto de un
tratamiento (fármaco vs. placebo) sobre el colesterol varía según el
grupo de edad (jóvenes vs. adultos mayores).
Ejemplo práctico: En un estudio, el ANOVA de dos
factores muestra una interacción significativa (\(p = 0.01\)) entre tratamiento y edad,
indicando que el fármaco reduce el colesterol más en adultos mayores que
en jóvenes.
Diseños
Factoriales
Diseño factorial completo: Todos los niveles de un
factor se combinan con todos los niveles del otro factor (e.g., 2x3: dos
tratamientos y tres grupos de edad).
- Ventaja: Permite evaluar efectos principales e
interacciones de manera eficiente.
- Aplicación en salud: Comparar el efecto de dos
tipos de insulina (rápida, lenta) y tres dosis (baja, media, alta) sobre
los niveles de glucosa.
Diseño balanceado vs. no balanceado:
- Balanceado: Igual número de observaciones por
combinación.
- No balanceado: Diferentes tamaños de grupo,
requiere ajustes en el cálculo.
Ejemplo práctico: Un diseño 2x2 evalúa el efecto de
tratamiento (fármaco vs. placebo) y dieta (baja en carbohidratos
vs. estándar) sobre el peso en pacientes obesos. La tabla ANOVA muestra
efectos principales significativos para el tratamiento (\(p = 0.002\)) y la dieta (\(p = 0.01\)), pero no interacción (\(p = 0.15\)).
4.3 ANOVA
Multifactorial y Modelos Mixtos
Diseños Anidados y
de Medidas Repetidas
Diseños anidados:
- Un factor está subordinado a otro (e.g., pacientes anidados dentro
de hospitales, hospitales anidados dentro de regiones).
- Modelo: \[
Y_{ijk} = \mu + \alpha_i + \beta_{j(i)} + \epsilon_{ijk}
\] Donde \(\beta_{j(i)}\) es el
efecto del nivel \(j\) del factor B
anidado en el nivel \(i\) del factor
A.
- Aplicación en salud: Comparar la variabilidad en
tiempos de recuperación entre pacientes tratados en diferentes
hospitales, donde los médicos están anidados dentro de cada
hospital.
- Ejemplo práctico: En un estudio, se evalúa la
calidad de atención (medida por tiempo de espera) en tres hospitales,
con varios médicos por hospital. El ANOVA anidado muestra diferencias
significativas entre hospitales (\(p =
0.03\)), pero no entre médicos dentro de hospitales (\(p = 0.12\)).
Diseños de medidas repetidas:
- Mide la misma variable en los mismos sujetos en múltiples ocasiones
(e.g., niveles de glucosa antes, durante y después de un
tratamiento).
- Modelo: \[
Y_{ij} = \mu + \alpha_i + \pi_j + \epsilon_{ij}
\] Donde \(\pi_j\) es el efecto
del sujeto (j), y \(\alpha_i\) es el
efecto del tiempo o tratamiento.
- Supuesto adicional: Esfericidad (varianzas de las
diferencias entre pares de medidas son iguales), verificable con la
prueba de Mauchly.
- Aplicación en salud: Evaluar el cambio en la
presión arterial a lo largo de un mes en pacientes bajo un nuevo
tratamiento.
- Ejemplo práctico: En 20 pacientes, se miden los
niveles de HbA1c en tres momentos (basal, 3 meses, 6 meses). El ANOVA de
medidas repetidas muestra un efecto significativo del tiempo (\(p = 0.001\)), indicando una reducción
progresiva.
Supuestos y
Verificaciones
Supuestos comunes:
- Normalidad: Verificar con gráficos Q-Q, histogramas
o pruebas como Shapiro-Wilk. En salud, datos como tiempos de
recuperación pueden ser no normales, requiriendo transformaciones (e.g.,
logaritmo).
- Homocedasticidad: Usar pruebas de Levene o
Bartlett. Si se viola, considerar ANOVA robusto (e.g., Welch
ANOVA).
- Independencia: Asegurada por diseño experimental
(aleatorización). En medidas repetidas, la correlación entre medidas
debe modelarse.
- Esfericidad (medidas repetidas): Verificar con
Mauchly; si se viola, usar correcciones como Greenhouse-Geisser o
Huynh-Feldt.
Verificaciones en salud:
- Gráficos diagnósticos: Boxplots para detectar
valores atípicos, gráficos de residuos para evaluar normalidad y
homocedasticidad.
- Pruebas estadísticas: Shapiro-Wilk para normalidad,
Levene para homocedasticidad.
- Transformaciones: Aplicar transformaciones
logarítmicas o de raíz cuadrada si los datos son sesgados (común en
tiempos de espera o conteos de eventos).
Ejemplo práctico: En un ANOVA de medidas repetidas
para evaluar el efecto de un fármaco en el colesterol a lo largo de 6
meses, la prueba de Mauchly indica violación de esfericidad (\(p = 0.02\)). Se aplica la corrección de
Greenhouse-Geisser, y el ANOVA ajustado muestra un efecto significativo
del tiempo (\(p = 0.005\)).
Recursos para el
Autoestudio en Salud
Lecturas:
- “Statistical Methods in Medical Research” de Armitage, Berry y
Matthews (Capítulos sobre ANOVA).
- “Biostatistics: A Foundation for Analysis in the Health Sciences” de
Daniel (Capítulos 8-9).
Ejercicios
prácticos:
- Realizar ANOVA de un factor para comparar tratamientos en datos de
ensayos clínicos (e.g., presión arterial, glucosa).
- Aplicar ANOVA de dos factores a estudios con interacciones (e.g.,
tratamiento y grupo de edad).
- Analizar datos de medidas repetidas (e.g., niveles de biomarcadores
en el tiempo) y verificar supuestos.
Herramientas
computacionales:
- R: Paquetes stats (aov, anova), car (pruebas de
supuestos), ez (ANOVA de medidas repetidas).
- Ejemplo:
aov(y ~ tratamiento, data=datos) para ANOVA de un factor;
ezANOVA para medidas repetidas.
- Python: Librerías statsmodels
(statsmodels.stats.anova.anova_lm), pingouin (pg.anova, pg.rm_anova).
- Ejemplo:
pg.anova(data=datos, dv='glucosa', between='tratamiento').
Bases de
datos:
- NHANES para datos de biomarcadores (e.g., colesterol, presión
arterial).
- ClinicalTrials.gov para datos de ensayos clínicos.
Tabla Resumen: Análisis
de Varianza (ANOVA) en el Sector Salud
Tabla 4: Resumen de diseños ANOVA aplicados al sector salud
|
Tipo.de.ANOVA
|
Supuestos.Clave
|
Modelo.Matemático
|
Hipótesis.Nula..H..
|
Aplicación.en.Salud
|
Ejemplo.Práctico
|
|
ANOVA de un factor
|
Normalidad, homocedasticidad, independencia
|
\(Y_{ij} = \mu + \tau_i +
\epsilon_{ij}\)
|
Todas las medias grupales son iguales (\(\mu_1
= \mu_2 = \dots = \mu_k\))
|
Comparar efecto de tres tratamientos sobre glucosa
|
Insulina vs. metformina vs. placebo en pacientes diabéticos
|
|
ANOVA de dos factores
|
Normalidad, homocedasticidad, independencia
|
\(Y_{ijk} = \mu + \alpha_i + \beta_j +
(\alpha\beta)_{ij} + \epsilon_{ijk}\)
|
No hay efecto principal de A, ni de B, ni interacción
|
Evaluar tratamiento y edad sobre colesterol
|
Fármaco más efectivo en adultos mayores que en jóvenes
|
|
ANOVA de medidas repetidas
|
Normalidad, esfericidad, independencia entre sujetos
|
\(Y_{ij} = \mu + \alpha_i + \pi_j +
\epsilon_{ij}\)
|
No hay efecto del tiempo/tratamiento sobre la media
|
Medir cambios en HbA1c antes/durante/después de tratamiento
|
Reducción progresiva de HbA1c en 20 pacientes a los 3 y 6 meses
|
|
ANOVA anidado (nested)
|
Normalidad, homocedasticidad, estructura jerárquica
|
\(Y_{ijk} = \mu + \alpha_i + \beta_{j(i)} +
\epsilon_{ijk}\)
|
No hay diferencia entre niveles superiores (e.g., hospitales)
|
Comparar tiempos de espera entre hospitales (médicos anidados)
|
Diferencias entre hospitales, pero no entre médicos dentro de ellos
|
|
ANOVA multifactorial con interacción
|
Normalidad, homocedasticidad, independencia, esfericidad (si aplica)
|
Extensión del modelo de dos factores con múltiples interacciones
|
No hay efecto significativo de los factores ni sus interacciones
|
Estudiar combinaciones de fármacos, dosis y género
|
Interacción significativa entre dieta, ejercicio y edad en pérdida de
peso
|
5. Regresión y Modelos
Lineales para el Sector Salud
Este temario desarrolla los conceptos de regresión y modelos lineales
con un enfoque en aplicaciones en el sector salud, proporcionando
explicaciones detalladas, ejemplos prácticos y aplicaciones relevantes
para profesionales médicos, investigadores clínicos y epidemiólogos. La
regresión es una herramienta estadística esencial para modelar
relaciones entre variables, predecir resultados y evaluar factores de
riesgo en estudios de salud, como la relación entre el índice de masa
corporal (IMC) y el riesgo de diabetes o el impacto de un tratamiento en
la presión arterial.
5.1 Regresión Lineal
Simple
Modelo y
Supuestos
La regresión lineal simple modela la relación entre una variable
dependiente continua ($ Y \() y una variable
independiente (\) X $) mediante una línea recta.
Modelo: \[
Y_i = \beta_0 + \beta_1 X_i + \epsilon_i
\] Donde:
- $ Y_i $: Variable dependiente (e.g., presión arterial).
- $ X_i $: Variable independiente (e.g., dosis de un
medicamento).
- $ _0 $: Intercepto (valor de $ Y $ cuando $ X = 0 $).
- $ _1 $: Pendiente (cambio en $ Y $ por unidad de cambio en $ X
$).
- $ _i $: Error aleatorio, asumido $ _i N(0, ^2) $.
Supuestos:
- Linealidad: La relación entre $ X $ y $ Y $ es
lineal.
- Independencia: Los errores $ _i $ son
independientes entre sí.
- Homocedasticidad: La varianza de los errores es
constante ($ (_i) = ^2 $).
- Normalidad: Los errores siguen una distribución
normal, verificable con gráficos Q-Q o pruebas como Shapiro-Wilk.
- Ausencia de valores atípicos extremos: Los valores
atípicos pueden distorsionar los resultados.
Aplicación en salud: Modelar la relación entre el
IMC ($ X \() y el nivel de glucosa en sangre
(\) Y $) para evaluar el riesgo de diabetes.
Ejemplo práctico: En un estudio, se modela la
presión arterial sistólica ($ Y \() en función
de la dosis diaria de un antihipertensivo (\) X $). Se verifica
la linealidad con un gráfico de dispersión y la normalidad de los
residuos con un gráfico Q-Q.
Estimación por
Mínimos Cuadrados
La estimación por mínimos cuadrados (OLS) busca los valores de $ _0 $
y $ _1 $ que minimizan la suma de los cuadrados de los errores: \[
\text{SCE} = \sum_{i=1}^n (Y_i - \hat{Y}_i)^2 = \sum_{i=1}^n (Y_i -
\beta_0 - \beta_1 X_i)^2
\]
Fórmulas:
- Pendiente: \[
\hat{\beta}_1 = \frac{\sum (X_i - \bar{X})(Y_i - \bar{Y})}{\sum (X_i -
\bar{X})^2}
\]
- Intercepto: \[
\hat{\beta}_0 = \bar{Y} - \hat{\beta}_1 \bar{X}
\]
- Predicción: $ _i = _0 + _1 X_i $.
- Varianza del error: \[
\hat{\sigma}^2 = \frac{\sum (Y_i - \hat{Y}_i)^2}{n-2}
\]
Aplicación en salud: Estimar cómo el tiempo de
ejercicio semanal ($ X \() afecta el
colesterol LDL (\) Y $).
Ejemplo práctico: En 50 pacientes, con $ X $ (horas
de ejercicio) y $ Y $ (colesterol LDL, mg/dL), se calcula $ _1 = -2.5 $,
indicando que cada hora adicional de ejercicio reduce el colesterol en
2.5 mg/dL, y $ _0 = 150 $. La ecuación es: \[
\hat{Y} = 150 - 2.5X
\]
Inferencia sobre
Parámetros (Pendiente, Intercepto)
La inferencia evalúa si los parámetros $ _0 $ y $ _1 $ son
estadísticamente significativos.
Pruebas de hipótesis:
- **Para $ _1 $:**
- $ H_0: _1 = 0 $ (no hay relación lineal).
- $ H_1: _1 $.
- Estadístico: \[
t = \frac{\hat{\beta}_1}{\text{SE}(\hat{\beta}_1)}
\] Donde $ (_1) = $, con $ n-2 $ grados de libertad.
- Similar para $ _0 $.
Intervalos de confianza:
- Para $ _1 $: \[
\hat{\beta}_1 \pm t_{\alpha/2, n-2} \cdot \text{SE}(\hat{\beta}_1)
\]
Aplicación en salud: Determinar si el IMC afecta
significativamente el riesgo de hipertensión.
Ejemplo práctico: En el modelo anterior, $ _1 = -2.5
$, $ (1) = 0.8 $, $ t = -2.5 / 0.8 = -3.125 $. Con $ t{0.025,
48} $, se rechaza $ H_0 $ ($ p < 0.05 $), indicando que el ejercicio
reduce significativamente el colesterol. El IC al 95% para $ _1 $ es:
\[
-2.5 \pm 2.01 \cdot 0.8 \approx (-4.11, -0.89)
\]
Bondad de ajuste:
- R²: Proporción de la varianza de $ Y $ explicada
por $ X $. $ R^2 = 1 - $, donde $ = (Y_i - _i)^2 $ y $ = (Y_i - {Y})^2
$.
- Ejemplo: Si $ R^2 = 0.65 $, el 65% de la
variabilidad en el colesterol se explica por el ejercicio.
5.2 Regresión Lineal
Múltiple
La regresión lineal múltiple extiende el modelo simple para incluir
varias variables independientes ($ X_1, X_2, , X_p $).
Modelo: \[
Y_i = \beta_0 + \beta_1 X_{i1} + \beta_2 X_{i2} + \dots + \beta_p X_{ip}
+ \epsilon_i
\] Donde $ _i N(0, ^2) $.
Supuestos: Igual que en la regresión simple, más la
ausencia de multicolinealidad severa entre las $ X $.
Aplicación en salud: Predecir el nivel de glucosa en
sangre ($ Y \() usando IMC (\) X_1
\(), edad (\) X_2 \(), y actividad física (\) X_3 $).
Ejemplo práctico: Modelar el riesgo cardiovascular
($ Y \() en función de presión arterial
(\) X_1 \(), colesterol (\) X_2
\(), y tabaquismo (\) X_3 $).
Selección de
Variables (Forward, Backward, Stepwise)
La selección de variables identifica el subconjunto de predictores
más relevantes para evitar modelos sobreajustados o redundantes.
Forward Selection:
- Comienza con un modelo nulo (sin predictores) y añade variables una
por una, seleccionando la que más mejora el ajuste (e.g., menor $ p
$-valor o mayor $ R^2 $).
- Aplicación en salud: Construir un modelo para
predecir el riesgo de diabetes empezando con el IMC y añadiendo edad,
glucosa basal, etc.
Backward Elimination:
- Comienza con todas las variables y elimina las menos significativas
(mayor $ p $-valor) una por una.
- Aplicación en salud: Simplificar un modelo con
múltiples factores de riesgo cardiovascular, eliminando variables no
significativas como el consumo de cafeína.
Stepwise Selection:
- Combina forward y backward, añadiendo o eliminando variables en cada
paso según criterios como el Criterio de Información de Akaike (AIC) o
el $ p $-valor.
- Ejemplo práctico: En un estudio con 10 predictores
(IMC, edad, colesterol, etc.), el stepwise selecciona un modelo con IMC,
edad y glucosa, minimizando el AIC.
Consideraciones:
- Riesgo de sobreajuste con demasiadas variables.
- Usar criterios como AIC, BIC o validación cruzada para evaluar
modelos.
- En salud, priorizar variables clínicamente relevantes (e.g., presión
arterial sobre variables menos relevantes como horas de sueño).
Multicolinealidad y
Diagnóstico
Multicolinealidad: Ocurre cuando las variables
independientes están altamente correlacionadas, lo que puede inflar la
varianza de los coeficientes y dificultar la interpretación.
Diagnóstico:
- Factor de Inflación de la Varianza (VIF): VIF >
5 o 10 indica multicolinealidad problemática.
- Matriz de correlación: Correlaciones altas ($ |r|
> 0.8 $) entre predictores.
Soluciones:
- Eliminar una variable correlacionada.
- Usar técnicas como análisis de componentes principales (PCA).
- Combinar variables correlacionadas (e.g., crear un índice de
riesgo).
Aplicación en salud: En un modelo para predecir el
riesgo de infarto, el colesterol total y el colesterol LDL pueden estar
correlacionados (VIF > 10), sugiriendo eliminar uno.
Diagnósticos adicionales:
- Residuos: Verificar normalidad (Q-Q plot),
homocedasticidad (gráfico de residuos vs. predichos), y ausencia de
patrones.
- Valores atípicos: Usar medidas como la distancia de
Cook para identificar observaciones influyentes.
Ejemplo práctico: En un modelo para predecir
glucosa, un VIF de 8 para IMC y peso sugiere multicolinealidad. Se
elimina el peso, y los residuos confirman normalidad y
homocedasticidad.
Interpretación de
Coeficientes
Interpretación:
- $ _j $: Cambio en $ Y $ por unidad de cambio en $ X_j $, manteniendo
las demás $ X $ constantes.
- Ejemplo: Si $ _1 = 0.5 $ para el IMC en un modelo
de glucosa, un aumento de 1 unidad en el IMC incrementa la glucosa en
0.5 mg/dL, controlando por otras variables.
Significancia: Pruebas t para cada $ _j $ ($ H_0: _j
= 0 $).
Aplicación en salud: En un modelo con $ Y = $ riesgo
cardiovascular, $ X_1 = $ presión arterial, $ X_2 = $ colesterol, $ _1 =
0.3 $, $ _2 = 0.2 $, indica que la presión arterial tiene un mayor
impacto por unidad.
Ejemplo práctico: Un modelo con $ = 50 + 0.4X_1 +
2X_2 - 1.5X_3 $ (donde $ X_1 $: IMC, $ X_2 $: edad, $ X_3 $: ejercicio)
predice el colesterol. Si $ p < 0.05 $ para $ _2 $, la edad es un
predictor significativo.
5.3 Modelos Lineales
Generalizados (GLM)
Los modelos lineales generalizados (GLM) extienden la regresión
lineal para manejar variables dependientes no normales, como datos
binarios o de conteo, comunes en salud.
Estructura del GLM:
- Componente aleatorio: Distribución de $ Y $ (e.g.,
binomial, Poisson).
- Componente sistemático: Combinación lineal de
predictores ($ = _0 + _1 X_1 + $).
- Función de enlace: Relaciona la media de $ Y $ ($
\() con el predictor lineal (\) g() =
$).
Aplicación en salud: Modelar resultados binarios
(e.g., presencia/ausencia de diabetes) o conteos (e.g., número de
hospitalizaciones).
Regresión Logística
y Poisson
Regresión logística:
- Uso: Modelar una variable dependiente binaria
(e.g., 0 = no enfermedad, 1 = enfermedad).
- Modelo: \[
\log\left(\frac{p}{1-p}\right) = \beta_0 + \beta_1 X_1 + \dots + \beta_p
X_p
\] Donde $ p = P(Y=1) $, y la función de enlace es el logit.
- Interpretación:
- $ (_j) $: Razón de odds (odds ratio) por unidad de cambio en $ X_j
$.
- Ejemplo: Si $ _1 = 0.4 $ para el IMC, $ (0.4) $, un
aumento de 1 unidad en el IMC aumenta los odds de diabetes en 49%.
- Estimación: Máxima verosimilitud (MLE).
- Aplicación en salud: Predecir la probabilidad de
infarto en función de edad, IMC y tabaquismo.
- Ejemplo práctico: En un estudio, la regresión
logística predice la presencia de hipertensión ($ Y = 1 $) con $ X_1 $:
edad, $ X_2 $: IMC. Si $ _1 = 0.05 $, $ (0.05) $, cada año de edad
aumenta los odds de hipertensión en 5%.
Regresión Poisson:
- Uso: Modelar conteos o tasas (e.g., número de
hospitalizaciones por paciente).
- Modelo: \[
\log(\mu) = \beta_0 + \beta_1 X_1 + \dots + \beta_p X_p
\] Donde $ $ es la media de la distribución Poisson.
- Interpretación:
- $ (_j) $: Razón de tasas (rate ratio) por unidad de cambio en $ X_j
$.
- Ejemplo: Si $ _1 = 0.2 $ para el tabaquismo, $
(0.2) $, los fumadores tienen 22% más hospitalizaciones.
- Aplicación en salud: Modelar el número de casos de
asma en función de la exposición a contaminantes.
- Ejemplo práctico: En un estudio, la regresión
Poisson predice el número de visitas a urgencias por asma ($ Y $) con $
X_1 $: nivel de contaminación, $ X_2 $: edad. Si $ _1 = 0.3 \(, un aumento en la contaminación incrementa la
tasa de visitas en 35% (\) (0.3) $).
Modelos para Datos
Categóricos y de Conteo
Regresión logística multinomial:
- Uso: Variable dependiente categórica con más de dos
niveles (e.g., estadio de cáncer: I, II, III, IV).
- Modelo: Extiende la regresión logística, usando una
categoría como referencia y modelando los logits para las demás.
- Aplicación en salud: Predecir el estadio del cáncer
en función de biomarcadores y factores de riesgo.
- Ejemplo práctico: Modelar el estadio del cáncer de
mama (I, II,
- con predictores como edad y tamaño del tumor. Los odds ratios
indican cómo cada predictor afecta la probabilidad de cada estadio.
Regresión para datos ordinales:
- Uso: Variable dependiente ordinal (e.g., gravedad
de una enfermedad: leve, moderada, severa).
- Modelo: Modelos como la regresión logística ordinal
(proporcional odds model).
- Aplicación en salud: Evaluar la gravedad de los
síntomas de COVID-19 en función de la edad y comorbilidades.
- Ejemplo práctico: Un modelo ordinal predice la
gravedad de la artritis (leve, moderada, severa) con predictores como
edad y nivel de inflamación.
Regresión para conteos con sobredispersión:
- Uso: Cuando los datos de conteo tienen mayor
varianza que la esperada en una Poisson (sobredispersión).
- Modelos: Regresión binomial negativa o modelos de
Poisson con sobredispersión.
- Aplicación en salud: Modelar el número de
infecciones respiratorias en pacientes con variabilidad alta debido a
factores no medidos.
- Ejemplo práctico: Un modelo binomial negativo
predice el número de hospitalizaciones por infecciones respiratorias,
ajustando por edad y exposición ambiental.
Recursos para el
Autoestudio en Salud
Lecturas:
- “Applied Linear Statistical Models” de Kutner et al. (Capítulos
sobre regresión lineal).
- “Generalized Linear Models” de McCullagh y Nelder (Capítulos sobre
GLM).
- “Biostatistics: A Foundation for Analysis in the Health Sciences” de
Daniel (Capítulos 10-11).
Ejercicios
prácticos:
- Realizar regresión lineal simple para modelar relaciones entre
biomarcadores (e.g., IMC y glucosa).
- Construir modelos de regresión múltiple para predecir riesgos
cardiovasculares, verificando multicolinealidad y residuos.
- Aplicar regresión logística y Poisson a datos de salud (e.g.,
predicción de diabetes, conteo de hospitalizaciones).
Herramientas
computacionales:
- R: Paquetes stats (lm, glm), car (VIF,
diagnósticos), MASS (regresión binomial negativa).
- Ejemplo:
lm(glucosa ~ IMC, data=datos)
para regresión simple;
glm(diabetes ~ IMC + edad, family=binomial) para
logística.
- Python: Librerías statsmodels
(statsmodels.formula.api.ols, glm), scikit-learn (para selección de
variables).
- Ejemplo:
smf.ols('glucosa ~ IMC + edad', data=datos).fit();
smf.glm('hospitalizaciones ~ contaminacion', family=sm.families.Poisson()).
Bases de
datos:
- NHANES para datos de biomarcadores (e.g., glucosa, colesterol).
- ClinicalTrials.gov para datos de ensayos clínicos.
- Datasets de la OMS para estudios epidemiológicos (e.g., prevalencia
de diabetes).
Tabla Resumen:
Regresión y Modelos Lineales en el Sector Salud
Tabla 5: Resumen de modelos de regresión aplicados al sector salud
|
Tipo.de.Modelo
|
Supuestos.Clave
|
Ecuación.del.Modelo
|
Función.de.Enlace
|
Aplicación.en.Salud
|
Ejemplo.Práctico
|
|
Regresión Lineal Simple
|
Linealidad, independencia, homocedasticidad, normalidad de errores
|
\(Y_i = \beta_0 + \beta_1 X_i +
\epsilon_i\)
|
Identidad
|
Relación entre IMC y glucosa en sangre
|
Cada hora adicional de ejercicio reduce el colesterol en 2.5 mg/dL
|
|
Regresión Lineal Múltiple
|
Igual que regresión simple, más ausencia de multicolinealidad
|
\(Y_i = \beta_0 + \beta_1 X_{i1} + \dots +
\beta_p X_{ip} + \epsilon_i\)
|
Identidad
|
Predicción del riesgo cardiovascular con múltiples factores
|
Modelo con IMC, edad y tabaquismo predice riesgo de infarto
|
|
Regresión Logística
|
Independencia, validez del modelo logístico, ausencia de separación
|
\(\log\left(\frac{p}{1-p}\right) = \beta_0 +
\beta_1 X_1 + \dots + \beta_p X_p\)
|
Logit
|
Predicción de enfermedad (sí/no), e.g., diabetes, infarto
|
Cada año de edad aumenta los odds de hipertensión en 5% (OR = 1.05)
|
|
Regresión Poisson
|
Independencia, media = varianza (equidispersión)
|
\(\log(\mu) = \beta_0 + \beta_1 X_1 + \dots +
\beta_p X_p\)
|
Log
|
Modelar número de hospitalizaciones o casos de enfermedad
|
Mayor exposición a contaminación incrementa visitas a urgencias en 35%
|
|
Regresión Logística Multinomial
|
Independencia, proporciones paralelas (proportional odds)
|
Logits múltiples vs. categoría de referencia
|
Logit (multinomial)
|
Predecir estadio de cáncer (I, II, III, IV)
|
Tamaño del tumor y edad predicen estadio del cáncer de mama
|
|
Regresión Ordinal
|
Independencia, relación logística entre categorías
|
\(\log\left(\frac{P(Y \leq j)}{P(Y >
j)}\right) = \alpha_j + \beta_1 X_1 + \dots + \beta_p X_p\)
|
Logit (proporcional odds)
|
Evaluar gravedad de síntomas (leve, moderada, severa)
|
Nivel de inflamación y edad predicen severidad de artritis
|
|
Regresión Binomial Negativa
|
Independencia, sobredispersión (varianza > media)
|
\(\log(\mu) = \beta_0 + \beta_1 X_1 + \dots +
\beta_p X_p\) (distribución binomial negativa)
|
Log
|
Modelar conteos con alta variabilidad (e.g., infecciones respiratorias)
|
Número de hospitalizaciones por infecciones ajustado por edad y
exposición
|
6. Métodos
Multivariados para el Sector Salud
Este temario desarrolla los métodos multivariados con un enfoque en
aplicaciones en el sector salud, proporcionando explicaciones
detalladas, ejemplos prácticos y aplicaciones relevantes para
profesionales médicos, investigadores clínicos y epidemiólogos. Los
métodos multivariados analizan múltiples variables simultáneamente para
descubrir patrones, reducir dimensionalidad o clasificar observaciones,
siendo esenciales en estudios complejos como la identificación de
factores de riesgo, análisis de biomarcadores o segmentación de
pacientes. Se incluye el análisis de correspondencias múltiples (ACM)
para complementar el análisis multivariado en datos categóricos.
6.1 Análisis de
Componentes Principales (PCA)
Reducción de
Dimensionalidad
El análisis de componentes principales (PCA) es una técnica de
reducción de dimensionalidad que transforma un conjunto de variables
correlacionadas en un conjunto más pequeño de variables no
correlacionadas llamadas componentes principales, preservando la mayor
cantidad posible de la variabilidad de los datos.
- Objetivo: Reducir el número de variables
manteniendo la mayor parte de la información (varianza). En salud, esto
es útil para analizar múltiples biomarcadores (e.g., glucosa,
colesterol, presión arterial) en un espacio de menor dimensión.
- Método:
- Estandarización: Escalar las variables a media 0 y
varianza 1, especialmente si tienen diferentes unidades (e.g., mg/dL
para glucosa, mmHg para presión arterial).
- Matriz de covarianza o correlación: Calcular la
matriz para capturar las relaciones entre variables.
- Autovalores y autovectores: Los autovectores
definen las direcciones de los componentes principales, y los
autovalores indican la varianza explicada por cada componente.
- Selección de componentes: Elegir los componentes
con autovalores altos (e.g., > 1) o que expliquen un porcentaje
significativo de la varianza (e.g., 70-90%).
- Algoritmo:
- Estandarizar las variables: \(Z = \frac{X
- \mu}{\sigma}\).
- Calcular la matriz de correlación \(R\).
- Obtener autovalores (\(\lambda_i\))
y autovectores (\(v_i\)).
- Proyectar los datos en los componentes principales: \(Y = Z \cdot V\), donde \(V\) es la matriz de autovectores.
- Aplicación en salud: Reducir un conjunto de
biomarcadores (e.g., lípidos, glucosa, inflamación) a unos pocos
componentes para identificar patrones de riesgo cardiovascular.
- Ejemplo práctico: En un estudio con 200 pacientes,
se analizan 10 biomarcadores (colesterol total, LDL, HDL, triglicéridos,
glucosa, etc.). PCA identifica dos componentes principales que explican
el 80% de la varianza, representando perfiles de riesgo metabólico y
lipídico.
Interpretación de
Componentes
Componentes principales: Cada componente es una
combinación lineal de las variables originales: \[
PC_1 = a_{11}X_1 + a_{12}X_2 + \dots + a_{1p}X_p
\] Donde \(a_{1j}\) son las
cargas (loadings) que indican la contribución de cada variable
\(X_j\).
Cargas: Valores cercanos a 1 o -1 indican una
fuerte contribución; valores cerca de 0 indican poca
influencia.
Varianza explicada: La proporción de varianza
total explicada por cada componente es \(\frac{\lambda_i}{\sum
\lambda_i}\).
Gráficos:
- Scree plot: Muestra los autovalores para decidir
cuántos componentes retener.
- Biplot: Visualiza las observaciones y las variables
en el espacio de los componentes principales.
Aplicación en salud: Interpretar componentes
como combinaciones de factores de riesgo. Por ejemplo, PC1 puede
representar un “perfil metabólico” (alta carga en glucosa y HbA1c), y
PC2 un “perfil lipídico” (alta carga en colesterol y
triglicéridos).
Ejemplo práctico: En el estudio anterior, PC1
tiene cargas altas para glucosa (0.6) y HbA1c (0.5), sugiriendo un
componente relacionado con el control glucémico. PC2 tiene cargas altas
para colesterol LDL (0.7) y triglicéridos (0.6), relacionado con
lípidos. Los pacientes con puntuaciones altas en PC1 tienen mayor riesgo
de diabetes.
6.2 Análisis
Factorial
El análisis factorial identifica factores latentes (no observados)
que explican las correlaciones entre variables observadas, útil para
explorar estructuras subyacentes en datos de salud.
Modelos
Exploratorios y Confirmatorios
Análisis factorial exploratorio (EFA):
- Objetivo: Identificar factores latentes sin
hipótesis previas.
- Modelo: \[
X_j = \mu_j + \sum_{m=1}^k \lambda_{jm} F_m + \epsilon_j
\] Donde \(X_j\) es la variable
observada, \(\lambda_{jm}\) son las
cargas factoriales, \(F_m\) son los
factores, y \(\epsilon_j\) es el error
específico.
- Aplicación en salud: Identificar factores
subyacentes en síntomas psicológicos (e.g., ansiedad, depresión) a
partir de respuestas a cuestionarios.
- Ejemplo práctico: En un estudio de salud mental,
EFA agrupa ítems de un cuestionario (fatiga, tristeza, insomnio) en
factores como “depresión” y “ansiedad”.
Análisis factorial confirmatorio (CFA):
- Objetivo: Validar una estructura factorial
predefinida.
- Método: Especificar un modelo donde cada variable
carga en factores específicos, estimando parámetros con máxima
verosimilitud.
- Aplicación en salud: Confirmar que un cuestionario
de calidad de vida mide dimensiones específicas (e.g., física,
emocional).
- Ejemplo práctico: Un CFA valida que un cuestionario
de calidad de vida en pacientes con cáncer mide tres factores (físico,
emocional, social), con cargas significativas (\(p < 0.05\)).
Diferencias:
- EFA es exploratorio, sin hipótesis previas; CFA prueba un modelo
teórico.
- En salud, EFA se usa en fases iniciales (e.g., desarrollo de
escalas); CFA en validación (e.g., ensayos clínicos).
Rotación de
Factores
- Propósito: Simplificar la interpretación de los
factores haciendo que las cargas sean más extremas (cercanas a 0 o
1).
- Tipos:
- Ortogonal (e.g., Varimax): Asume factores no
correlacionados, útil para estructuras claras.
- Oblicua (e.g., Promax): Permite correlación entre
factores, común en salud donde factores como síntomas físicos y
psicológicos pueden estar relacionados.
- Aplicación en salud: En un EFA de síntomas de
diabetes, la rotación Varimax agrupa variables en factores como
“síntomas metabólicos” (glucosa alta, sed) y “síntomas neurológicos”
(neuropatía, hormigueo).
- Ejemplo práctico: En un estudio con 300 pacientes,
un EFA con rotación Varimax identifica dos factores: uno con altas
cargas en glucosa y HbA1c, otro en neuropatía y fatiga. La rotación
facilita interpretar el primer factor como control glucémico y el
segundo como complicaciones.
6.3 Análisis
Discriminante y Clúster
Clasificación
Supervisada y No Supervisada
Análisis discriminante (supervisado):
- Objetivo: Clasificar observaciones en grupos
predefinidos (e.g., enfermo vs. sano) basándose en variables
predictoras.
- Tipos:
- Lineal (LDA): Asume normalidad y varianzas iguales
entre grupos.
- Cuadrático (QDA): Permite varianzas
diferentes.
- Modelo:
- En LDA, se maximiza la separación entre grupos proyectando los datos
en funciones discriminantes: \[
D_k(X) = \beta_0 + \beta_1 X_1 + \dots + \beta_p X_p
\]
- Clasifica una observación en el grupo con mayor \(D_k\).
- Aplicación en salud: Clasificar pacientes como
diabéticos o no diabéticos basándose en glucosa, IMC y edad.
- Ejemplo práctico: En un estudio con 500 pacientes,
LDA usa glucosa, HbA1c e IMC para clasificar diabetes tipo 2 vs. no
diabetes, logrando un 85% de precisión.
Análisis de clúster (no supervisado):
- Objetivo: Agrupar observaciones en clústeres
basándose en similitudes, sin etiquetas previas.
- Métodos:
- K-means: Minimiza la varianza dentro de los
clústeres, asignando observaciones al centroide más cercano.
- Jerárquico: Construye un dendrograma fusionando o
dividiendo clústeres.
- Aplicación en salud: Identificar subgrupos de
pacientes con perfiles de riesgo similares (e.g., pacientes con
enfermedades cardiovasculares).
- Ejemplo práctico: K-means agrupa 1000 pacientes en
tres clústeres según biomarcadores (colesterol, presión arterial): alto
riesgo, riesgo moderado y bajo riesgo.
Evaluación de
Resultados
Análisis discriminante:
- Métricas: Tasa de clasificación correcta,
sensibilidad, especificidad, matriz de confusión.
- Validación: Validación cruzada (e.g., k-fold) para
evaluar la generalización.
- Ejemplo práctico: En el estudio de diabetes, LDA
logra 90% de sensibilidad (detecta diabéticos correctamente) y 80% de
especificidad (identifica no diabéticos).
Análisis de clúster:
- Métricas:
- Índice de silueta: Mide la cohesión dentro de
clústeres y separación entre clústeres (valores cercanos a 1 indican
buena calidad).
- Suma de cuadrados dentro de clústeres (WCSS) para
K-means.
- Validación: Comparar clústeres con variables
clínicas externas (e.g., tasas de hospitalización).
- Ejemplo práctico: En el estudio de K-means, un
índice de silueta de 0.75 sugiere clústeres bien definidos. Los
clústeres se validan comparando tasas de eventos cardiovasculares.
6.4 Análisis de
Correspondencias Múltiples (ACM)
El análisis de correspondencias múltiples (ACM) es una técnica
multivariada para analizar relaciones entre múltiples variables
categóricas, extendiendo el análisis de correspondencias simple (CA) a
más de dos variables.
Fundamentos y
Modelo
- Objetivo: Explorar y visualizar asociaciones entre
categorías de variables cualitativas, reduciendo la dimensionalidad de
los datos categóricos.
- Modelo:
- Los datos se organizan en una matriz de indicadores (0/1 para cada
categoría) o una tabla de Burt (matriz de contingencia cruzada de todas
las variables).
- ACM descompone esta matriz usando descomposición en valores
singulares (SVD), proyectando categorías y observaciones en un espacio
de baja dimensión.
- Los ejes principales (dimensiones) explican la inercia (análogo a la
varianza en PCA).
- Aplicación en salud: Analizar relaciones entre
variables categóricas como diagnóstico (diabetes, hipertensión,
ninguna), estilo de vida (fumador, no fumador), y grupo de edad (joven,
adulto, anciano).
- Ejemplo práctico: En un estudio de 1000 pacientes,
ACM explora asociaciones entre diagnóstico, tabaquismo y nivel
educativo. Las categorías “diabetes” y “fumador” aparecen cercanas en el
mapa de ACM, sugiriendo una fuerte asociación.
Interpretación y
Visualización
- Inercia: Similar a la varianza en PCA, mide la
dispersión de las categorías. La inercia total se descompone en
contribuciones por eje.
- Mapas bidimensionales: Las categorías y
observaciones se proyectan en un plano (ejes principales), donde la
proximidad indica asociación.
- Interpretación: Categorías cercanas están más
asociadas; categorías opuestas tienen asociaciones inversas.
- Contribuciones y calidad:
- Contribución: Proporción de la inercia explicada
por cada categoría en un eje.
- Calidad de representación: Indica cómo de bien una
categoría es representada en el plano (valores cercanos a 1 son
ideales).
- Aplicación en salud: Identificar patrones en datos
categóricos, como la relación entre comorbilidades y factores de
riesgo.
- Ejemplo práctico: En el estudio anterior, el eje 1
(40% de inercia) separa pacientes con diabetes y tabaquismo de aquellos
sin comorbilidades. El eje 2 (25% de inercia) distingue por nivel
educativo. Las categorías “diabetes” y “bajo nivel educativo” están
cercanas, sugiriendo una asociación.
Ventajas y
Limitaciones
- Ventajas:
- Ideal para datos categóricos, comunes en encuestas de salud (e.g.,
cuestionarios de calidad de vida).
- Visualización intuitiva de asociaciones complejas.
- No requiere supuestos de normalidad.
- Limitaciones:
- Sensible a categorías con frecuencias bajas.
- Interpretación subjetiva de los mapas.
- No modela relaciones causales.
- Ejemplo práctico: En un estudio de calidad de vida
en pacientes oncológicos, ACM revela que los pacientes con cáncer
avanzado y baja calidad de vida están asociados con mayor edad y menor
soporte social.
Recursos para el
Autoestudio en Salud
Lecturas:
- “Multivariate Data Analysis” de Hair et al. (Capítulos sobre PCA,
factorial, clúster).
- “An Introduction to Correspondence Analysis” de Greenacre (para CA y
ACM).
- “Biostatistics: A Foundation for Analysis in the Health Sciences” de
Daniel (Capítulos sobre métodos multivariados).
Ejercicios
prácticos:
- Realizar PCA en biomarcadores (e.g., glucosa, colesterol) para
identificar patrones de riesgo.
- Aplicar EFA y CFA a cuestionarios de salud mental, verificando
estructuras factoriales.
- Usar análisis discriminante para clasificar pacientes (e.g.,
diabéticos vs. no diabéticos) y clúster para segmentar poblaciones.
- Implementar ACM en datos categóricos (e.g., comorbilidades y
factores de riesgo).
Herramientas
computacionales:
- R:
- Paquetes
FactoMineR (PCA, ACM), psych
(EFA, CFA), MASS (LDA), cluster (K-means,
jerárquico).
- Ejemplo:
PCA(datos, scale=TRUE) para PCA;
MCA(datos) para ACM; kmeans(datos, centers=3)
para clúster.
- Python:
- Librerías
sklearn (PCA, LDA, K-means),
prince (MCA), factor_analyzer (EFA, CFA).
- Ejemplo:
sklearn.decomposition.PCA(n_components=2);
prince.MCA(n_components=2).
Bases de
datos:
- NHANES para biomarcadores (e.g., lípidos, glucosa).
- ClinicalTrials.gov para datos de ensayos clínicos.
- Encuestas de salud (e.g., WHO World Health Survey) para datos
categóricos.
Tabla Resumen: Métodos
Multivariados en el Sector Salud
Tabla 6: Resumen de métodos multivariados aplicados al sector salud
|
Técnica
|
Tipo.de.Análisis
|
Supuestos.Clave
|
Aplicación.en.Salud
|
Ejemplo.Práctico
|
|
Análisis de Componentes Principales (PCA)
|
Reducción de dimensionalidad
|
Linealidad, normalidad (preferible), alta correlación entre variables
|
Reducir múltiples biomarcadores a componentes interpretables
|
PCA reduce 10 biomarcadores a 2 componentes: metabólico y lipídico
|
|
Análisis Factorial Exploratorio (EFA)
|
Reducción de dimensionalidad (factores latentes)
|
Factorabilidad (KMO > 0.6), adecuada muestra (>5 por variable)
|
Identificar factores subyacentes en síntomas o cuestionarios
|
EFA identifica factores de ‘depresión’ y ‘ansiedad’ en un cuestionario
|
|
Análisis Factorial Confirmatorio (CFA)
|
Validación de estructura factorial
|
Modelo teórico predefinido, normalidad multivariada
|
Validar escalas de calidad de vida o diagnóstico
|
CFA valida que un cuestionario mide 3 dimensiones en pacientes
oncológicos
|
|
Análisis Discriminante Lineal (LDA)
|
Clasificación supervisada
|
Normalidad multivariada, homocedasticidad entre grupos
|
Clasificar pacientes (e.g., diabéticos vs. no diabéticos)
|
LDA clasifica diabetes con 85% de precisión usando glucosa e IMC
|
|
Análisis de Clúster (K-means)
|
Agrupamiento no supervisado
|
Número de clústeres conocido, variables continuas
|
Segmentar pacientes por perfil de riesgo (e.g., cardiovascular)
|
K-means agrupa 1000 pacientes en alto, moderado y bajo riesgo
|
|
Análisis de Clúster Jerárquico
|
Agrupamiento no supervisado
|
No requiere número fijo de clústeres, distancia euclidiana
|
Explorar jerarquía de similitud entre pacientes o condiciones
|
Dendrograma muestra similitud entre pacientes con enfermedades crónicas
|
|
Análisis de Correspondencias Múltiples (ACM)
|
Análisis de asociación categórica
|
Datos categóricos, frecuencias suficientes por categoría
|
Analizar asociaciones entre comorbilidades, estilo de vida y demografía
|
ACM revela asociación entre diabetes, tabaquismo y bajo nivel educativo
|
7. Inferencia
Bayesiana para el Sector Salud
La inferencia bayesiana es un enfoque estadístico que utiliza el
teorema de Bayes para actualizar creencias sobre parámetros
poblacionales a partir de datos observados, siendo especialmente útil en
el sector salud para manejar incertidumbre en ensayos clínicos, estudios
epidemiológicos y decisiones clínicas. Este temario desarrolla los
fundamentos, métodos y aplicaciones de la inferencia bayesiana, con
ejemplos prácticos relevantes para profesionales médicos, investigadores
clínicos y epidemiólogos.
7.1 Fundamentos
Teorema de Bayes y
Probabilidad a Posteriori
La inferencia bayesiana se basa en el teorema de Bayes, que combina
información previa (prior) con datos observados para obtener una
distribución a posteriori que refleja la incertidumbre actualizada sobre
un parámetro.
Teorema de Bayes: \[
P(\theta | D) = \frac{P(D | \theta) \cdot P(\theta)}{P(D)}
\] Donde:
- \(P(\theta | D)\): Distribución a
posteriori del parámetro \(\theta\)
dado los datos \(D\).
- \(P(D | \theta)\): Verosimilitud,
probabilidad de los datos dado \(\theta\).
- \(P(\theta)\): Distribución a
priori, refleja el conocimiento previo sobre \(\theta\).
- \(P(D)\): Evidencia, normaliza la
posteriori (\(P(D) = \int P(D | \theta)
P(\theta) d\theta\)).
Aplicación en salud: En un ensayo clínico, \(\theta\) puede ser la efectividad de un
tratamiento (e.g., reducción en la presión arterial), \(P(\theta)\) refleja estudios previos, \(P(D | \theta)\) es la probabilidad de los
datos del ensayo, y \(P(\theta | D)\)
estima la efectividad actualizada.
Ejemplo práctico: Para estimar la prevalencia de
diabetes (\(\theta\)) en una población,
se usa un prior basado en datos nacionales (\(P(\theta) \sim \text{Beta}(5, 95)\)),
prevalencia ~5%. Con una muestra de 200 pacientes donde 15 tienen
diabetes, la verosimilitud es binomial, y la posteriori actualiza la
estimación a \(\theta \sim \text{Beta}(20,
280)\), con una prevalencia media de \(\frac{20}{20+280} \approx 6.67\%\).
7.2 Métodos
Bayesianos
Estimación
Bayesiana de Parámetros
La estimación bayesiana proporciona distribuciones a posteriori
completas para los parámetros, en lugar de estimaciones puntuales como
en la estadística frecuentista.
Estimación puntual:
- Media a posteriori: \(E(\theta | D)\), útil para resumir la
distribución.
- Moda a posteriori (MAP): Valor que maximiza \(P(\theta | D)\).
Ejemplo práctico: En un ensayo clínico, la media a
posteriori de la reducción de glucosa por un fármaco es 15 mg/dL, basada
en una posteriori \(\theta \sim N(15,
2^2)\).
Estimación por intervalos: Ver sección
siguiente.
Métodos de cálculo:
- Analíticos: Usar priors conjugados para obtener
postrioris cerradas (e.g., Beta para binomial, Normal para normal).
- Numéricos: Métodos como Monte Carlo por Cadenas de
Markov (MCMC) para distribuciones complejas.
Aplicación en salud: Estimar la tasa de infección
hospitalaria (\(\theta\)) combinando
datos de un hospital con un prior basado en estudios nacionales.
Intervalos de
Credibilidad
Los intervalos de credibilidad (ICr) son el equivalente bayesiano de
los intervalos de confianza frecuentistas, proporcionando un rango que
contiene el parámetro con una probabilidad dada.
Definición: Un ICr al 95% es un intervalo \([a, b]\) tal que \(P(a \leq \theta \leq b | D) = 0.95\).
- Puede ser simétrico (percentiles 2.5% y 97.5%) o de mayor densidad a
posteriori (HPD, highest posterior density).
- Cálculo:
- Para distribuciones analíticas (e.g., Beta, Normal), usar
percentiles de la posteriori.
- Para distribuciones complejas, usar muestras MCMC.
- Interpretación: A diferencia de los intervalos de
confianza, un ICr al 95% indica que hay un 95% de probabilidad de que
\(\theta\) esté en el intervalo, dado
los datos y el prior.
Aplicación en salud: Estimar la probabilidad de
éxito de un tratamiento con un ICr.
Ejemplo práctico: En un estudio de un nuevo fármaco,
la posteriori para la proporción de respondedores es \(\theta \sim \text{Beta}(30, 70)\). El ICr
al 95% es aproximadamente [0.21, 0.40], indicando que la probabilidad de
respuesta está entre 21% y 40% con 95% de probabilidad.
7.3 Aplicaciones
Prácticas
Modelos
Jerárquicos
Los modelos jerárquicos bayesianos modelan parámetros que varían
entre grupos (e.g., hospitales, regiones) con un prior común,
permitiendo compartir información entre grupos.
Modelo: \[
Y_{ij} \sim \text{Normal}(\theta_i, \sigma^2)
\] \[
\theta_i \sim \text{Normal}(\mu, \tau^2)
\] Donde \(\theta_i\) es el
parámetro del grupo \(i\) (e.g., tasa
de infección en el hospital \(i\)), y
\(\mu, \tau^2\) son
hiperparámetros.
Ventajas:
- Maneja heterogeneidad entre grupos.
- Mejora estimaciones en grupos con pocos datos (shrinkage).
Aplicación en salud: Estimar tasas de mortalidad por
COVID-19 en diferentes hospitales, usando un modelo jerárquico para
compartir información entre hospitales con tamaños muestrales
dispares.
Ejemplo práctico: En un estudio de 10 hospitales,
las tasas de infección varían. Un modelo jerárquico estima tasas
individuales (\(\theta_i\)) con un
prior común \(\mu \sim N(0.05,
0.01^2)\), mejorando la precisión en hospitales con pocos
datos.
MCMC (Monte Carlo
por Cadenas de Markov)
MCMC es un método computacional para muestrear distribuciones a
posteriori complejas, especialmente en modelos no conjugados o
jerárquicos.
Método:
- Genera una cadena de muestras que convergen a la distribución a
posteriori.
- Algoritmos comunes: Metropolis-Hastings, Gibbs
sampling.
Pasos:
- Definir el modelo (prior y verosimilitud).
- Ejecutar MCMC para generar muestras de la posteriori.
- Resumir resultados (media, ICr, etc.) usando las muestras.
Aplicación en salud: Modelar la efectividad de un
tratamiento en un ensayo clínico con datos faltantes o estructuras
complejas.
Ejemplo práctico: En un ensayo clínico, se usa MCMC
para estimar la probabilidad de respuesta a un tratamiento (\(\theta\)) con un prior no informativo y
datos binomiales. Usando el paquete rstan en R, se generan 10,000
muestras, dando una media a posteriori de 0.75 y un ICr al 95% de [0.68,
0.82].
Herramientas: R (rstan, brms), Python (pymc, stan),
software como BUGS o JAGS.
8. Diseño de
Experimentos
El diseño de experimentos (DOE) es crucial para garantizar que los
estudios clínicos y epidemiológicos produzcan resultados válidos y
reproducibles. En el sector salud, el DOE optimiza la asignación de
tratamientos, controla sesgos y maximiza la potencia estadística.
8.1 Principios
Básicos
Aleatorización: Asignar sujetos a grupos (e.g.,
tratamiento vs. placebo) al azar para minimizar sesgos y garantizar
comparabilidad.
- Ejemplo: En un ensayo clínico, pacientes son
asignados aleatoriamente a un nuevo fármaco o placebo para evitar sesgos
de selección.
Replicación: Realizar múltiples observaciones por
grupo para estimar la variabilidad y aumentar la precisión.
- Ejemplo: Incluir 50 pacientes por grupo en un
ensayo para estimar la varianza de la presión arterial.
Control: Usar grupos control (e.g., placebo) o
condiciones estándar para comparar efectos.
- Ejemplo: Comparar un nuevo antihipertensivo con un
placebo para medir su efecto neto.
Bloqueo: Agrupar sujetos por características
relevantes (e.g., edad, sexo) para reducir la variabilidad no
explicada.
- Ejemplo: Estratificar pacientes por edad en un
estudio de diabetes para controlar su efecto.
8.2 Diseños
Comunes en Salud
Diseño completamente aleatorizado:
- Asigna sujetos a tratamientos de forma aleatoria sin
restricciones.
- Aplicación: Ensayos clínicos simples comparando un
fármaco vs. placebo.
- Ejemplo: 100 pacientes asignados aleatoriamente a
dos grupos (fármaco A vs. placebo) para evaluar la reducción de
glucosa.
Diseño en bloques aleatorizados:
- Divide sujetos en bloques (e.g., por sexo o gravedad de la
enfermedad) y aleatoriza dentro de cada bloque.
- Aplicación: Controlar factores de confusión como la
edad en ensayos clínicos.
- Ejemplo: En un estudio de hipertensión, pacientes
se dividen en bloques por edad (<50, ≥50) y se asignan aleatoriamente
a tratamientos dentro de cada bloque.
Diseño factorial:
Evalúa múltiples factores simultáneamente (e.g., tratamiento y
dosis).
Modelo: \[
Y_{ijk} = \mu + \alpha_i + \beta_j + (\alpha\beta)_{ij} + \epsilon_{ijk}
\]
Aplicación: Estudiar el efecto combinado de un
fármaco y una dieta en el colesterol.
Ejemplo: Un diseño 2x3 evalúa dos fármacos (A,
B) y tres dosis (baja, media, alta), analizando efectos principales e
interacciones.
Diseño cruzado:
- Cada sujeto recibe todos los tratamientos en un orden aleatorio, con
períodos de lavado para evitar efectos residuales.
- Aplicación: Comparar la efectividad de dos
antihipertensivos en los mismos pacientes.
- Ejemplo: Pacientes reciben fármaco A por 4 semanas,
luego un período de lavado, y luego fármaco B, midiendo la presión
arterial.
Diseño de medidas repetidas:
- Mide la misma variable en múltiples puntos temporales.
- Aplicación: Evaluar el cambio en HbA1c a lo largo
de 6 meses en pacientes tratados.
- Ejemplo: Medir glucosa basal, a 3 y 6 meses en un
ensayo de insulina.
8.3
Consideraciones en Salud
Tamaño muestral:
- Calcular usando fórmulas basadas en la potencia (\(1-\beta\)), nivel de significancia (\(\alpha\)), y tamaño del efecto
esperado.
- Ejemplo: Para detectar una reducción de 10 mmHg en
presión arterial (\(\sigma = 15\)),
\(\alpha = 0.05\), potencia = 0.8), se
necesitan aproximadamente 47 pacientes por grupo.
Ética:
- Garantizar consentimiento informado, minimizar riesgos y maximizar
beneficios.
- Usar controles éticos (e.g., tratamiento estándar en lugar de
placebo si es necesario).
Sesgos:
- Sesgo de selección: Mitigar con
aleatorización.
- Sesgo de medición: Usar instrumentos validados y
cegar a investigadores.
Análisis:
- Usar ANOVA para diseños factoriales, modelos mixtos para medidas
repetidas, o métodos bayesianos para incorporar información previa.
- Ejemplo práctico: En un ensayo factorial 2x2
(fármaco vs. placebo, dieta baja en sal vs. estándar), se usa ANOVA para
analizar efectos principales e interacciones, con aleatorización por
bloques para controlar la edad.
Recursos para el
Autoestudio en Salud
Lecturas:
- “Bayesian Data Analysis” de Gelman et al. (Capítulos sobre
fundamentos y MCMC).
- “Design and Analysis of Experiments” de Montgomery (Capítulos sobre
DOE).
- “Biostatistics: A Foundation for Analysis in the Health Sciences” de
Daniel (Capítulos sobre bayesiana y DOE).
Ejercicios
prácticos:
- Calcular postrioris para tasas de enfermedad usando priors
conjugados.
- Implementar modelos jerárquicos en R o Python para datos de
hospitales.
- Diseñar un ensayo clínico factorial y analizarlo con ANOVA.
- Usar MCMC para estimar parámetros en un modelo logístico
bayesiano.
Herramientas
computacionales:
- R: Paquetes
rstan, brms
(bayesiana), pwr (tamaño muestral), agricolae
(DOE).
- Ejemplo:
stan_glm(y ~ x, family=binomial, prior=normal(0, 1)) para
regresión logística bayesiana.
- Python: Librerías
pymc,
stan (bayesiana), statsmodels (DOE).
- Ejemplo:
pm.GLM.from_formula('y ~ x', data, family=pm.glm.families.Binomial()).
Bases de
datos:
- NHANES para datos de biomarcadores.
- ClinicalTrials.gov para datos de ensayos clínicos.
- WHO datasets para tasas de enfermedad.
Tabla Resumen:
Inferencia Bayesiana y Diseño de Experimentos en el Sector Salud
Tabla 7: Resumen de inferencia bayesiana y diseño de experimentos en
salud
|
Técnica
|
Tipo.de.Análisis
|
Supuestos.Clave
|
Modelo.o.Enfoque
|
Aplicación.en.Salud
|
Ejemplo.Práctico
|
|
Inferencia Bayesiana
|
Estimación paramétrica bayesiana
|
Verosimilitud bien especificada, prior razonable
|
\(P(\theta | D) \propto P(D | \theta)
P(\theta)\)
|
Actualizar estimaciones de prevalencia o efectividad con nuevos datos
|
Estimar prevalencia de diabetes actualizada: \(\theta \sim \text{Beta}(20, 280)\)
|
|
Prior informativo
|
Incorporación de conocimiento previo
|
Información previa confiable (literatura, estudios)
|
Prior basado en datos previos (e.g., \(\theta
\sim \text{Beta}(80,20)\))
|
Usar datos históricos en ensayos clínicos
|
Prior \(\text{Beta}(80,20)\) para
eficacia de vacuna
|
|
Prior no informativo
|
Estimación sin información previa fuerte
|
Ausencia de sesgo fuerte en creencias iniciales
|
Prior débil (e.g., \(\theta \sim
\text{Uniform}(0,1)\))
|
Análisis exploratorio sin sesgo previo
|
Prior \(\text{Beta}(1,1)\) para tasa de
hipertensión
|
|
Intervalo de credibilidad (ICr)
|
Intervalo de estimación bayesiano
|
Posteriori bien convergida (MCMC), o forma analítica
|
\(P(a \leq \theta \leq b | D) = 0.95\)
|
Reportar incertidumbre con interpretación directa de probabilidad
|
ICr 95%: [0.21, 0.40] para proporción de respondedores
|
|
Modelos jerárquicos bayesianos
|
Modelado de efectos entre grupos
|
Homogeneidad de varianza entre grupos, normalidad
|
\(\theta_i \sim N(\mu, \tau^2)\), \(Y_{ij} \sim N(\theta_i, \sigma^2)\)
|
Estimar tasas de infección por hospital con datos limitados
|
Modelo jerárquico mejora estimación en hospitales con pocos datos
|
|
MCMC (Monte Carlo por Cadenas de Markov)
|
Muestreo de distribuciones posteriores
|
Convergencia de la cadena, mezcla adecuada
|
Metropolis-Hastings, Gibbs sampling
|
Modelar efectividad de tratamientos con estructuras complejas
|
MCMC estima \(\theta = 0.75\) con ICr
[0.68, 0.82]
|
|
Diseño completamente aleatorizado
|
Comparación de tratamientos
|
Aleatorización completa, independencia de errores
|
ANOVA de un factor con aleatorización completa
|
Ensayos clínicos simples (fármaco vs. placebo)
|
100 pacientes aleatorizados a fármaco A vs. placebo
|
|
Diseño en bloques aleatorizados
|
Control de confusores
|
Bloques homogéneos, aleatorización dentro de bloques
|
ANOVA con efectos de bloque
|
Controlar edad, sexo u otras covariables
|
Bloques por edad (<50, ≥50) en estudio de hipertensión
|
|
Diseño factorial
|
Evaluación de múltiples factores e interacciones
|
Normalidad, homocedasticidad, independencia
|
\(Y_{ijk} = \mu + \alpha_i + \beta_j +
(\alpha\beta)_{ij} + \epsilon_{ijk}\)
|
Evaluar combinaciones de fármacos y dosis
|
Diseño 2x3: fármaco (A,B) y dosis (baja, media, alta)
|
|
Diseño cruzado
|
Comparación intra-sujeto de tratamientos
|
Períodos de lavado suficientes, ausencia de efecto residual
|
Cada sujeto recibe todos los tratamientos en orden aleatorio
|
Comparar tratamientos en los mismos pacientes
|
Pacientes reciben A, luego B, con 2 semanas de lavado
|
|
Diseño de medidas repetidas
|
Seguimiento longitudinal
|
Esfericidad (o corrección), normalidad de residuos
|
Medidas en múltiples tiempos: \(Y_{ij} = \mu +
\alpha_i + \pi_j + \epsilon_{ij}\)
|
Monitorear biomarcadores en el tiempo (HbA1c, presión arterial)
|
Glucosa medida a 0, 3 y 6 meses en pacientes diabéticos
|
8. Diseño de
Experimentos para el Sector Salud
El diseño de experimentos (DOE) es una herramienta esencial en
estadística inferencial para estructurar estudios clínicos y
epidemiológicos que generen resultados válidos, reproducibles y
éticamente sólidos en el sector salud. Este temario desarrolla los
principios, diseños avanzados y métodos de análisis de experimentos, con
un enfoque en aplicaciones prácticas para profesionales médicos,
investigadores clínicos y epidemiólogos. El DOE permite optimizar la
asignación de tratamientos, controlar sesgos y maximizar la potencia
estadística en investigaciones como ensayos clínicos, estudios de
intervención y evaluaciones de políticas de salud pública.
8.1 Principios
Básicos
Aleatorización,
Replicación y Bloqueo
Los principios fundamentales del DOE aseguran la validez interna y
externa de los experimentos, minimizando sesgos y aumentando la
precisión de las estimaciones.
Aleatorización:
- Definición: Asignar sujetos a tratamientos de forma
aleatoria para eliminar sesgos de selección y garantizar que los grupos
sean comparables en factores no controlados.
- Propósito: Distribuir equitativamente las
características no medidas (e.g., genética, estilo de vida) entre
grupos.
- Aplicación en salud: En un ensayo clínico para
evaluar un nuevo antihipertensivo, los pacientes se asignan
aleatoriamente a fármaco o placebo para evitar que factores como la edad
o el sexo sesguen los resultados.
- Ejemplo práctico: En un estudio con 200 pacientes,
se usa un generador de números aleatorios para asignar 100 al grupo de
tratamiento y 100 al placebo, asegurando que las diferencias en presión
arterial se deban al fármaco.
Replicación:
- Definición: Repetir el experimento en múltiples
sujetos o unidades por tratamiento para estimar la variabilidad y
aumentar la precisión.
- Propósito: Proporcionar estimaciones robustas de
los efectos del tratamiento y permitir pruebas de hipótesis
estadísticamente potentes.
- Aplicación en salud: Incluir suficientes pacientes
por grupo en un ensayo clínico para detectar diferencias clínicamente
relevantes en biomarcadores (e.g., glucosa en sangre).
- Ejemplo práctico: En un ensayo para evaluar un
tratamiento de diabetes, se incluyen 50 pacientes por grupo (tratamiento
vs. control) para estimar la varianza de HbA1c y detectar una reducción
de 0.5% con una potencia del 80%.
Bloqueo:
- Definición: Agrupar sujetos en bloques homogéneos
según una variable de confusión (e.g., edad, sexo) y aleatorizar dentro
de cada bloque.
- Propósito: Reducir la variabilidad no explicada y
aumentar la sensibilidad para detectar efectos del tratamiento.
- Aplicación en salud: En un estudio de obesidad, los
pacientes se dividen en bloques por género (hombres, mujeres) y se
aleatorizan a dieta o control dentro de cada bloque.
- Ejemplo práctico: En un ensayo clínico de un
fármaco para el colesterol, se forman bloques por rango de edad (<50,
≥50 años). Dentro de cada bloque, los pacientes se asignan
aleatoriamente a tres dosis del fármaco, reduciendo la variabilidad
debida a la edad.
Diseños
Completamente Aleatorizados
Definición: Un diseño completamente aleatorizado
(DCA) asigna sujetos a tratamientos de forma aleatoria sin restricciones
adicionales, asumiendo que no hay factores de confusión importantes que
requieran bloqueo.
Modelo: \[
Y_{ij} = \mu + \tau_i + \epsilon_{ij}
\] Donde \(Y_{ij}\) es la
respuesta del sujeto \(j\) en el
tratamiento \(i\), \(\mu\) es la media general, \(\tau_i\) es el efecto del tratamiento \(i\), y \(\epsilon_{ij} \sim N(0, \sigma^2)\) es el
error.
Supuestos:
- Normalidad de los errores.
- Homogeneidad de varianzas entre grupos.
- Independencia de las observaciones.
Aplicación en salud: Comparar la eficacia de dos
tratamientos (e.g., insulina vs. metformina) en pacientes diabéticos
asignados aleatoriamente.
Ejemplo práctico: En un ensayo con 150 pacientes, 50
se asignan aleatoriamente a metformina, 50 a insulina y 50 a placebo. La
variable respuesta es el nivel de HbA1c. Un ANOVA de un factor analiza
las diferencias entre las medias de los grupos, mostrando un valor p
< 0.05, lo que indica diferencias significativas.
8.2 Diseños
Avanzados
Diseños de Bloques
Incompletos
Los diseños de bloques incompletos (DBI) se utilizan cuando no es
posible incluir todos los tratamientos en cada bloque debido a
limitaciones prácticas (e.g., recursos, número de pacientes).
Definición: Cada bloque contiene un subconjunto de
los tratamientos, y la asignación es aleatoria dentro de los bloques.
Los diseños balanceados (BIBD, balanced incomplete block designs)
aseguran que cada tratamiento aparezca el mismo número de veces y cada
par de tratamientos se compare en el mismo número de bloques.
Ventajas:
- Reducen el tamaño de los bloques, facilitando estudios con muchos
tratamientos.
- Controlan la variabilidad de factores de confusión (e.g., hospital,
severidad de la enfermedad).
Modelo: \[
Y_{ijk} = \mu + \tau_i + \beta_j + \epsilon_{ijk}
\] Donde \(\tau_i\) es el efecto
del tratamiento \(i\), \(\beta_j\) es el efecto del bloque \(j\), y \(\epsilon_{ijk}\) es el error.
Aplicación en salud: Comparar cinco tratamientos
para la hipertensión en hospitales con capacidad limitada, asignando
solo tres tratamientos por hospital (bloque).
Ejemplo práctico: En un estudio con cinco
tratamientos antihipertensivos (A, B, C, D, E) y cuatro hospitales como
bloques, cada hospital prueba tres tratamientos. Un BIBD asegura que
cada tratamiento se evalúa en dos hospitales, y un ANOVA ajustado
analiza las diferencias en la presión arterial, controlando el efecto
del hospital.
Diseños
Factoriales Fraccionados
Los diseños factoriales fraccionados evalúan múltiples factores
(e.g., tratamiento, dosis, dieta) usando un subconjunto de todas las
combinaciones posibles, reduciendo el número de corridas
experimentales.
Definición: En un diseño factorial completo \(2^k\), se evalúan todas las combinaciones
de \(k\) factores con dos niveles
(e.g., alto/bajo). Un diseño fraccionado (e.g., \(2^{k-p}\)) usa \(2^{k-p}\) combinaciones, sacrificando
información sobre interacciones de orden superior para reducir
costos.
Ventajas:
- Eficiente para estudios con muchos factores.
- Permite evaluar efectos principales e interacciones de bajo
orden.
Resolución: Indica qué interacciones se
confunden:
- Resolución III: Efectos principales confundidos con
interacciones de dos vías.
- Resolución IV: Efectos principales no confundidos
con interacciones de dos vías, pero estas se confunden entre sí.
- Resolución V: Efectos principales y de dos vías no
confundidos.
Aplicación en salud: Evaluar el efecto de un fármaco
(sí/no), dosis (baja/alta) y dieta (baja en sal/estándar) en la presión
arterial, usando un diseño fraccionado \(2^{3-1}\) (4 combinaciones en lugar de
8).
Ejemplo práctico: En un estudio factorial
fraccionado \(2^{3-1}\), se evalúan
tres factores: fármaco (A: sí/no), dosis (B: baja/alta), y ejercicio (C:
sí/no). Se seleccionan 4 combinaciones (e.g., A-no/B-baja/C-no,
A-sí/B-baja/C-sí, etc.). El ANOVA muestra un efecto principal
significativo para el fármaco (\(p =
0.01\)) y una interacción fármaco-dosis (\(p = 0.03\)).
8.3 Análisis de
Experimentos
Interpretación de
Interacciones
Las interacciones ocurren cuando el efecto de un factor depende del
nivel de otro factor, siendo cruciales en estudios de salud para
entender efectos combinados.
Definición: En un diseño factorial, una interacción
\(AB\) indica que el efecto del factor
A (e.g., tratamiento) varía según los niveles del factor B (e.g.,
edad).
Visualización:
- Gráficos de interacción: Líneas no paralelas en un
gráfico de medias indican interacción.
- Tabla ANOVA: El término de interacción (\(AB\)) se evalúa con un estadístico F.
Aplicación en salud: Evaluar si el efecto de un
tratamiento para la diabetes varía según el grupo de edad (jóvenes
vs. adultos mayores).
Ejemplo práctico: En un diseño factorial 2x2
(tratamiento: fármaco vs. placebo; edad: <50 vs. ≥50 años), el ANOVA
muestra una interacción significativa (\(p =
0.02\)). Un gráfico de interacción revela que el fármaco reduce
la glucosa más en pacientes ≥50 años (diferencia de 20 mg/dL) que en
<50 años (10 mg/dL). Esto sugiere ajustar las recomendaciones
clínicas por edad.
Análisis de
Covarianza (ANCOVA)
El análisis de covarianza (ANCOVA) combina ANOVA con regresión para
ajustar el efecto de una variable continua (covariable) que influye en
la variable dependiente.
Modelo: \[
Y_{ij} = \mu + \tau_i + \beta (X_{ij} - \bar{X}) + \epsilon_{ij}
\] Donde \(\tau_i\) es el efecto
del tratamiento \(i\), \(X_{ij}\) es la covariable (e.g., IMC
basal), \(\beta\) es la pendiente de la
covariable, y \(\epsilon_{ij}\) es el
error.
Supuestos:
- Linealidad entre la covariable y la variable dependiente.
- Homogeneidad de pendientes: El efecto de la covariable es el mismo
en todos los grupos.
- Normalidad y homocedasticidad de los errores.
Ventajas:
- Aumenta la precisión al reducir la variabilidad no explicada.
- Controla factores de confusión continuos.
Aplicación en salud: Comparar la eficacia de dos
tratamientos en la reducción de colesterol, ajustando por el colesterol
basal (covariable).
Ejemplo práctico: En un ensayo con dos tratamientos
(fármaco A vs. B) y colesterol basal como covariable, ANCOVA muestra un
efecto significativo del tratamiento (\(p =
0.01\)) tras ajustar por colesterol basal (\(\beta = 0.8\), \(p < 0.001\)). El fármaco A reduce el
colesterol 5 mg/dL más que B, ajustado por la covariable.
Recursos para el
Autoestudio en Salud
Lecturas:
- “Design and Analysis of Experiments” de Montgomery (Capítulos sobre
DOE, bloques incompletos, factoriales fraccionados).
- “Biostatistics: A Foundation for Analysis in the Health Sciences” de
Daniel (Capítulos sobre DOE y ANCOVA).
- “Design of Experiments for the Health Sciences” de Lawson (enfoque
en aplicaciones médicas).
Ejercicios
prácticos:
- Diseñar un ensayo completamente aleatorizado para comparar tres
tratamientos antihipertensivos, analizando con ANOVA.
- Implementar un diseño de bloques incompletos para evaluar cinco
intervenciones en cuatro hospitales.
- Realizar un diseño factorial fraccionado \(2^{3-1}\) para estudiar tratamiento, dosis
y dieta, interpretando interacciones.
- Aplicar ANCOVA a datos de ensayos clínicos, ajustando por
covariables como edad o biomarcadores basales.
Herramientas
computacionales:
- R: Paquetes
stats (aov, lm para
ANCOVA), agricolae (diseños de bloques), FrF2
(factoriales fraccionados).
- Ejemplo:
aov(y ~ tratamiento * edad, data=datos) para ANOVA con
interacción;
lm(y ~ tratamiento + colesterol_basal, data=datos) para
ANCOVA.
- Python: Librerías
statsmodels
(statsmodels.formula.api.ols para ANOVA/ANCOVA),
pyDOE2 (diseños factoriales).
- Ejemplo:
smf.ols('colesterol ~ tratamiento + colesterol_basal', data=datos).fit()
para ANCOVA.
Bases de
datos:
- NHANES para datos de biomarcadores (e.g., colesterol, glucosa).
- ClinicalTrials.gov para datos de ensayos clínicos.
- Datasets de la OMS para estudios epidemiológicos (e.g., tasas de
hipertensión).
Tabla Resumen: Diseño
de Experimentos en el Sector Salud
Tabla 8: Resumen de diseños de experimentos aplicados al sector salud
|
Diseño.o.Técnica
|
Tipo.de.Análisis
|
Supuestos.Clave
|
Modelo.Estadístico
|
Aplicación.en.Salud
|
Ejemplo.Práctico
|
|
Diseño Completamente Aleatorizado (DCA)
|
Comparación de tratamientos
|
Normalidad, homocedasticidad, independencia
|
\(Y_{ij} = \mu + \tau_i +
\epsilon_{ij}\)
|
Comparar eficacia de tratamientos (e.g., fármacos vs. placebo)
|
150 pacientes asignados a metformina, insulina o placebo; ANOVA muestra
diferencias en HbA1c
|
|
Diseño de Bloques Aleatorizados
|
Control de confusores por bloqueo
|
Homogeneidad dentro de bloques, normalidad
|
\(Y_{ij} = \mu + \tau_i + \beta_j +
\epsilon_{ij}\)
|
Controlar edad, sexo o hospital en estudios clínicos
|
Bloques por edad (<50, ≥50); aleatorización dentro de bloques para
controlar confusión
|
|
Diseño de Bloques Incompletos (BIBD)
|
Evaluación de múltiples tratamientos con bloques limitados
|
Balanceo parcial, normalidad, independencia
|
\(Y_{ijk} = \mu + \tau_i + \beta_j +
\epsilon_{ijk}\)
|
Evaluar múltiples tratamientos en hospitales con capacidad limitada
|
5 tratamientos antihipertensivos evaluados en 4 hospitales; 3 por
hospital; ANOVA ajustado
|
|
Diseño Factorial Completo (2^k)
|
Evaluación de efectos principales e interacciones
|
Normalidad, homocedasticidad, independencia
|
\(Y_{ijk} = \mu + \alpha_i + \beta_j +
(\alpha\beta)_{ij} + \epsilon_{ijk}\)
|
Estudiar efectos combinados de fármaco, dosis y dieta
|
Factorial 2x2x2: fármaco, dosis, dieta; se analizan efectos e
interacciones
|
|
Diseño Factorial Fraccionado (2^{k-p})
|
Reducción de corridas experimentales
|
Resolución adecuada, linealidad, bajo orden de interacciones
|
\(Y = \mu + \text{efectos principales} +
\text{interacciones de bajo orden}\)
|
Reducir costos en estudios con muchos factores (e.g., intervenciones
múltiples)
|
Diseño \(2^{3-1}\): 4 combinaciones
para 3 factores; se detecta interacción fármaco-dosis
|
|
Análisis de Covarianza (ANCOVA)
|
Ajuste por covariables continuas
|
Linealidad, homogeneidad de pendientes, normalidad
|
\(Y_{ij} = \mu + \tau_i + \beta (X_{ij} -
\bar{X}) + \epsilon_{ij}\)
|
Ajustar por biomarcadores basales (e.g., colesterol, IMC)
|
ANCOVA ajusta reducción de colesterol por tratamiento, controlando
colesterol basal
|
9. Análisis de Series
Temporales para el Sector Salud
El análisis de series temporales es una herramienta clave en
estadística inferencial para modelar y predecir datos secuenciales en el
tiempo, siendo especialmente relevante en el sector salud para
monitorear tendencias epidemiológicas, predecir brotes de enfermedades,
evaluar intervenciones clínicas y gestionar recursos hospitalarios. Este
temario desarrolla los componentes de las series temporales, los modelos
ARIMA y los modelos avanzados, con un enfoque en aplicaciones prácticas
para profesionales médicos, investigadores clínicos y epidemiólogos.
9.1 Componentes de
Series Temporales
Tendencia,
Estacionalidad y Ruido
Las series temporales en salud, como los casos diarios de una
enfermedad o las admisiones hospitalarias, se componen de patrones
sistemáticos y aleatorios que deben identificarse para modelar y
predecir con precisión.
Tendencia:
- Definición: Movimiento a largo plazo en los datos,
que puede ser ascendente, descendente o constante.
- Ejemplo en salud: Aumento gradual en la prevalencia
de diabetes tipo 2 debido a cambios en el estilo de vida o
envejecimiento poblacional.
- Identificación: Visualización con gráficos de
líneas o suavizado (e.g., media móvil) para detectar patrones a largo
plazo.
- Aplicación práctica: Analizar la tendencia en los
niveles promedio de glucosa en sangre en una población durante una
década para evaluar el impacto de políticas de salud pública.
Estacionalidad:
- Definición: Patrones repetitivos en intervalos
regulares (e.g., diarios, semanales, anuales) debido a factores
cíclicos.
- Ejemplo en salud: Incremento de casos de influenza
durante el invierno o picos semanales en admisiones hospitalarias los
lunes.
- Identificación: Gráficos de autocorrelación (ACF) o
descomposición estacional para detectar ciclos periódicos.
- Aplicación práctica: Identificar patrones
estacionales en los casos de dengue para planificar campañas de
prevención durante los meses de lluvia.
Ruido (componente aleatoria):
- Definición: Variaciones aleatorias no explicadas
por la tendencia o la estacionalidad, modeladas como error
estocástico.
- Ejemplo en salud: Fluctuaciones diarias en el
número de consultas de urgencia debido a eventos impredecibles.
- Identificación: Residuos tras eliminar tendencia y
estacionalidad, asumidos como ruido blanco (\(\epsilon_t \sim N(0, \sigma^2)\)).
- Aplicación práctica: Modelar el ruido en las tasas
de hospitalización para evaluar la estabilidad de los datos tras
intervenciones.
Modelo general: \[
Y_t = T_t + S_t + \epsilon_t
\] Donde \(Y_t\) es la serie
observada, \(T_t\) es la tendencia,
\(S_t\) es la estacionalidad, y \(\epsilon_t\) es el ruido.
Descomposición de
Series
La descomposición separa la serie temporal en sus componentes para
facilitar el análisis y modelado.
Tipos de descomposición:
- Aditiva: \(Y_t = T_t +
S_t + \epsilon_t\), adecuada cuando la amplitud de la
estacionalidad es constante.
- Multiplicativa: \(Y_t =
T_t \cdot S_t \cdot \epsilon_t\), útil cuando la estacionalidad
varía con la tendencia (e.g., mayor variación en picos epidémicos).
Métodos:
- Clásico: Usa medias móviles para estimar \(T_t\), resta la tendencia para obtener
\(S_t\), y calcula \(\epsilon_t\) como residuo.
- STL (Seasonal and Trend decomposition using LOESS):
Ajusta tendencia y estacionalidad con suavizado local, robusto a valores
atípicos.
- X-13-ARIMA-SEATS: Método avanzado para series con
estacionalidad compleja, usado en datos oficiales de salud.
Aplicación en salud: Descomponer series de
admisiones hospitalarias por insuficiencia cardíaca para identificar
tendencias a largo plazo (e.g., aumento por envejecimiento) y picos
estacionales (e.g., invierno).
Ejemplo práctico: En una serie de casos semanales de
influenza (2015-2025), la descomposición STL en R (stl())
muestra una tendencia ascendente (aumento de casos por cambios
demográficos), estacionalidad anual (picos en invierno) y ruido
aleatorio. Esto guía la planificación de campañas de vacunación.
9.2 Modelos
ARIMA
Los modelos ARIMA (AutoRegressive Integrated Moving Average) son
ampliamente utilizados para modelar series temporales estacionarias o
transformadas a estacionarias, siendo ideales para predecir variables
como tasas de incidencia o biomarcadores en salud.
Identificación,
Estimación y Diagnóstico
Definición:
- ARIMA(p,d,q):
- AR(p): Componente autorregresivo, modela la
dependencia de \(Y_t\) con valores
pasados (\(Y_{t-1}, \dots,
Y_{t-p}\)).
- I(d): Diferenciación de orden \(d\) para lograr estacionariedad.
- MA(q): Componente de media móvil, modela la
dependencia de \(Y_t\) con errores
pasados (\(\epsilon_{t-1}, \dots,
\epsilon_{t-q}\)).
Modelo: \[
\phi(B)(1-B)^d Y_t = \theta(B) \epsilon_t
\] Donde \(B\) es el operador de
rezago (\(BY_t = Y_{t-1}\)), \(\phi(B) = 1 - \phi_1 B - \dots - \phi_p
B^p\), y \(\theta(B) = 1 + \theta_1 B +
\dots + \theta_q B^q\).
Identificación:
- Estacionariedad: Verificar con gráficos de la
serie, ACF (decaimiento lento indica no estacionariedad) o pruebas como
Dickey-Fuller.
- Si no estacionaria, aplicar diferenciación (\(d=1\) o \(d=2\)) hasta lograr estacionariedad.
- Orden \(p, q\):
Usar ACF y PACF (Partial Autocorrelation Function):
- ACF: Corta en lag \(q\) para MA(q).
- PACF: Corta en lag \(p\) para AR(p).
- Estacionalidad: Usar ARIMA estacional (SARIMA:
\((p,d,q) \times (P,D,Q)_s\)) si hay
patrones periódicos (e.g., \(s=12\)
para datos mensuales).
Estimación:
- Máxima verosimilitud (MLE) para ajustar parámetros (\(\phi_i, \theta_j\)).
- Herramientas:
auto.arima() en R o
pmdarima en Python para seleccionar automáticamente \(p, d, q\).
Diagnóstico:
- Residuos: Deben ser ruido blanco (sin
autocorrelación, media 0, varianza constante).
- Verificar con ACF de residuos, prueba de Ljung-Box (\(p > 0.05\)).
- Ajuste: Comparar métricas como AIC o BIC para
seleccionar el mejor modelo.
Aplicación en salud: Modelar la incidencia semanal
de COVID-19 para predecir futuros brotes.
Ejemplo práctico: En una serie de casos semanales de
COVID-19 (2020-2025), la prueba Dickey-Fuller indica no estacionariedad
(\(p = 0.1\)). Tras una diferenciación
(\(d=1\)), ACF y PACF sugieren un
ARIMA(1,1,1). El modelo ajustado (auto.arima() en R) tiene
residuos sin autocorrelación (\(p =
0.8\) en Ljung-Box) y un AIC de 1250.
Predicción y
Validación
Predicción:
- Usar el modelo ARIMA para generar predicciones puntuales y
intervalos de predicción (95%).
- Fórmula: Para ARIMA(1,1,1), la predicción a un paso
es: \[
\hat{Y}_{t+1} = Y_t + \phi_1 (Y_t - Y_{t-1}) + \theta_1 \epsilon_t
\]
- Predicciones a largo plazo pierden precisión debido a la acumulación
de incertidumbre.
Validación:
- División de datos: Entrenar en 70-80% de los datos,
validar en el resto.
- Métricas: Error cuadrático medio (RMSE), error
absoluto medio (MAE), o error porcentual absoluto medio (MAPE).
- Validación cruzada temporal: Predecir un horizonte
futuro iterativamente (e.g., rolling forecast).
Aplicación en salud: Predecir admisiones
hospitalarias por insuficiencia cardíaca para optimizar recursos.
Ejemplo práctico: Un modelo ARIMA(1,1,1) predice
casos de COVID-19 para las próximas 4 semanas, con un RMSE de 50 casos
en datos de validación. Los intervalos de predicción al 95% capturan el
90% de los casos observados, validando el modelo.
9.3 Modelos
Avanzados
Modelos GARCH para
Volatilidad
Los modelos GARCH (Generalized Autoregressive Conditional
Heteroskedasticity) modelan la volatilidad variable en el tiempo, útil
para series con varianza no constante (e.g., tasas de eventos raros en
salud).
Definición:
- GARCH(p,q): \[
\sigma_t^2 = \omega + \sum_{i=1}^p \alpha_i \epsilon_{t-i}^2 +
\sum_{j=1}^q \beta_j \sigma_{t-j}^2
\] Donde \(\sigma_t^2\) es la
varianza condicional en \(t\), \(\epsilon_{t-i}^2\) son errores al cuadrado,
y \(\omega, \alpha_i, \beta_j\) son
parámetros.
- Combina con ARIMA para modelar la media y la volatilidad
simultáneamente (ARIMA-GARCH).
Identificación:
- Detectar heteroscedasticidad con ACF de residuos al cuadrado o
pruebas ARCH-LM.
- Seleccionar \(p, q\) usando AIC/BIC
o inspección de ACF/PACF de residuos al cuadrado.
Aplicación en salud: Modelar la volatilidad en tasas
de eventos adversos (e.g., infecciones hospitalarias) para predecir
períodos de alta variabilidad.
Ejemplo práctico: En una serie de tasas diarias de
infecciones nosocomiales, los residuos de un ARIMA(1,1,0) muestran
heteroscedasticidad (\(p < 0.05\) en
ARCH-LM). Un modelo GARCH(1,1) ajustado en R (rugarch)
reduce el AIC en 20 unidades y predice períodos de alta volatilidad,
ayudando a planificar recursos.
Series Temporales
No Estacionarias
Las series no estacionarias presentan tendencias o varianzas
cambiantes, requiriendo transformaciones o modelos específicos.
Pruebas de estacionariedad:
- Dickey-Fuller aumentado (ADF): \(H_0\): Serie tiene raíz unitaria (no
estacionaria).
- KPSS: \(H_0\):
Serie es estacionaria.
Transformaciones:
- Diferenciación: \(\Delta
Y_t = Y_t - Y_{t-1}\) para eliminar tendencia.
- Logaritmo o Box-Cox: Estabilizar varianza en series
con crecimiento exponencial (e.g., casos epidémicos).
Modelos para no estacionariedad:
- Modelos de tendencia determinista: \[
Y_t = \beta_0 + \beta_1 t + \epsilon_t
\]
- Modelos de raíz unitaria: ARIMA con \(d \geq 1\).
- Modelos estructurales: Representan tendencia y
estacionalidad explícitamente (e.g.,
StructTS en R).
Aplicación en salud: Modelar el aumento no
estacionario en casos de obesidad para proyectar necesidades de atención
médica.
Ejemplo práctico: Una serie de prevalencia anual de
obesidad (2000-2025) es no estacionaria (ADF: \(p = 0.15\)). Tras una diferenciación (\(d=1\)), un ARIMA(0,1,1) ajusta bien (AIC =
300). Alternativamente, un modelo estructural con tendencia lineal
predice un aumento de 2% anual, con intervalos de predicción al 95%.
Recursos para el
Autoestudio en Salud
Lecturas:
- “Time Series Analysis and Its Applications” de Shumway y Stoffer
(Capítulos sobre ARIMA, descomposición).
- “Forecasting: Principles and Practice” de Hyndman y Athanasopoulos
(Capítulos sobre ARIMA, STL, GARCH).
- “Biostatistics: A Foundation for Analysis in the Health Sciences” de
Daniel (Capítulos sobre series temporales).
Ejercicios
prácticos:
- Descomponer series de casos de influenza usando STL y analizar
tendencia/estacionalidad.
- Ajustar modelos ARIMA a datos de admisiones hospitalarias, validando
predicciones con RMSE.
- Implementar modelos GARCH para tasas de eventos adversos, evaluando
volatilidad.
- Modelar series no estacionarias (e.g., prevalencia de diabetes) con
ARIMA o modelos estructurales.
Herramientas
computacionales:
- R: Paquetes
forecast (auto.arima,
stl), tseries (ADF, GARCH), rugarch (GARCH).
- Ejemplo:
auto.arima(casos, seasonal=TRUE) para SARIMA;
ugarchfit(spec=ugarchspec(), data=retornos) para
GARCH.
- Python: Librerías
statsmodels (ARIMA,
STL), pmdarima (auto_arima), arch (GARCH).
- Ejemplo:
pmdarima.auto_arima(casos, seasonal=True);
arch_model(residuos, p=1, q=1).fit().
Bases de
datos:
- WHO Global Health Observatory para series de enfermedades (e.g.,
malaria, tuberculosis).
- CDC FluView para datos de influenza.
- Hospital Episode Statistics (HES) para admisiones
hospitalarias.
Tabla Resumen:
Análisis de Series Temporales en el Sector Salud
Tabla 9: Resumen de modelos de series temporales aplicados al sector
salud
|
Modelo.o.Técnica
|
Tipo.de.Análisis
|
Supuestos.Clave
|
Ecuación.del.Modelo
|
Aplicación.en.Salud
|
Ejemplo.Práctico
|
|
Descomposición STL
|
Descomposición de componentes
|
Tendencia suave, estacionalidad estable, ruido blanco
|
Ajuste no paramétrico mediante LOESS
|
Identificar tendencias y patrones estacionales en casos de enfermedades
|
STL descompone casos semanales de influenza: tendencia ascendente, pico
invernal
|
|
ARIMA(p,d,q)
|
Modelado de series estacionarias
|
Estacionariedad tras diferenciación, residuos normales
|
\(\phi(B)(1-B)^d Y_t = \theta(B)
\epsilon_t\)
|
Predecir incidencia de enfermedades (e.g., COVID-19, diabetes)
|
ARIMA(1,1,1) predice casos de COVID-19 con RMSE = 50
|
|
SARIMA (ARIMA Estacional)
|
Modelado con estacionalidad
|
Estacionalidad fija, estacionariedad estacional
|
\((p,d,q) \times (P,D,Q)_s\) con
estacionalidad de período \(s\)
|
Modelar brotes anuales (e.g., influenza, dengue)
|
SARIMA(1,1,1)(1,1,1)_52 modela picos semanales de urgencias
|
|
Modelo GARCH
|
Modelado de volatilidad
|
Heteroscedasticidad condicional, errores al cuadrado autocorrelacionados
|
\(\sigma_t^2 = \omega + \sum \alpha_i
\epsilon_{t-i}^2 + \sum \beta_j \sigma_{t-j}^2\)
|
Evaluar volatilidad en eventos adversos (e.g., infecciones
hospitalarias)
|
GARCH(1,1) detecta períodos de alta volatilidad en infecciones
nosocomiales
|
|
ARIMA-GARCH
|
Modelado de media y varianza
|
Media modelada por ARIMA, varianza por GARCH
|
ARIMA para \(Y_t\), GARCH para \(\sigma_t^2\)
|
Predecir tasas de eventos con riesgo variable (e.g., complicaciones
postoperatorias)
|
ARIMA(1,1,0)-GARCH(1,1) modela media y varianza de admisiones diarias
|
|
Modelo de Tendencia Determinista
|
Modelado de tendencia
|
Tendencia lineal o polinómica, errores i.i.d.
|
\(Y_t = \beta_0 + \beta_1 t +
\epsilon_t\)
|
Proyectar crecimiento de enfermedades crónicas (e.g., obesidad)
|
Tendencia lineal predice aumento del 2% anual en obesidad
|
|
Modelo Estructural (e.g., StructTS)
|
Descomposición explícita de tendencia y estacionalidad
|
Componentes observables: tendencia, estacionalidad, ruido
|
Ej: Nivel + Pendiente + Estacionalidad (modelo de espacio de estados)
|
Monitorear series complejas con múltiples componentes (e.g., admisiones
hospitalarias)
|
StructTS descompone admisiones por insuficiencia cardíaca en tendencia +
estacionalidad
|
10. Herramientas
Computacionales para Estadística Inferencial en Salud
Las herramientas computacionales son fundamentales en estadística
inferencial para analizar datos, realizar simulaciones y visualizar
resultados en el sector salud. Este temario desarrolla el uso de
software estadístico, métodos de remuestreo como bootstrap, y técnicas
de visualización de datos, con un enfoque en aplicaciones prácticas para
profesionales médicos, investigadores clínicos y epidemiólogos. Estas
herramientas permiten manejar datos complejos, realizar inferencias
robustas y comunicar resultados de manera efectiva en estudios de salud,
como ensayos clínicos, análisis epidemiológicos y modelado de
biomarcadores.
10.1 Software
Estadístico
R y Python para
Análisis Inferencial
R y Python son lenguajes de programación ampliamente utilizados en
estadística inferencial debido a su flexibilidad, comunidad activa y
paquetes especializados. En el sector salud, son ideales para analizar
datos clínicos, realizar pruebas de hipótesis, modelar regresiones y
gestionar grandes bases de datos.
R:
- Características: Lenguaje diseñado para estadística
y visualización, con una sintaxis clara para análisis inferencial y una
amplia comunidad en bioestadística.
- Ventajas:
- Paquetes especializados para salud (e.g., survival, epiR).
- Visualización avanzada con ggplot2.
- Integración con R Markdown para informes reproducibles.
- Aplicación en salud: Realizar ANOVA para comparar
tratamientos, ajustar modelos de regresión logística para predecir
resultados clínicos o analizar series temporales de casos de
enfermedades.
- Ejemplo práctico: En un ensayo clínico con 100
pacientes, se usa R para realizar una prueba t pareada
(
t.test(datos$antes, datos$despues, paired=TRUE)) para
evaluar el cambio en presión arterial tras un tratamiento, obteniendo un
valor p de 0.03, indicando significancia.
Python:
- Características: Lenguaje versátil con bibliotecas
robustas para estadística, aprendizaje automático y manejo de
datos.
- Ventajas:
- Integración con bases de datos y herramientas de big data.
- Sintaxis intuitiva para programadores no estadísticos.
- Comunidad en expansión en salud (e.g., análisis de datos
genómicos).
- Aplicación en salud: Ajustar modelos lineales para
predecir biomarcadores, realizar pruebas no paramétricas o simular
escenarios clínicos.
- Ejemplo práctico: En un estudio de diabetes, se usa
Python (
statsmodels.api.OLS) para ajustar una regresión
lineal que predice glucosa en sangre a partir del IMC y la edad, con un
\(R^2 = 0.65\).
Comparación:
- R es preferido para análisis estadísticos puros y visualización
avanzada en salud.
- Python es ideal para pipelines de datos complejos y aplicaciones
integradas con machine learning.
- Ambos son complementarios y pueden usarse juntos (e.g., rpy2 para
ejecutar R desde Python).
Paquetes
Relevantes: statsmodels, scipy, tidyverse
R: tidyverse:
- Descripción: Colección de paquetes (e.g., dplyr,
tidyr, ggplot2) para manipulación, limpieza y visualización de
datos.
- Funciones clave:
dplyr: Manipulación de datos (filter,
group_by, summarise).
tidyr: Reestructuración de datos
(pivot_longer, pivot_wider).
ggplot2: Visualización avanzada (ver sección
10.3).
- Aplicación en salud: Resumir datos de ensayos
clínicos, calcular medias por grupo de tratamiento y generar gráficos de
boxplots.
- Ejemplo práctico: En un estudio de hipertensión, se
usa dplyr para calcular la media de presión arterial por grupo
(
datos %>% group_by(tratamiento) %>% summarise(mean_pa = mean(presion))),
revelando diferencias significativas entre fármaco y placebo.
Python: statsmodels:
- Descripción: Biblioteca para modelos estadísticos,
incluyendo regresión lineal, logística, ANOVA y pruebas de
hipótesis.
- Funciones clave:
statsmodels.formula.api.ols: Regresión lineal.
statsmodels.stats.anova_lm: ANOVA.
statsmodels.glm: Modelos lineales generalizados.
- Aplicación en salud: Ajustar un modelo logístico
para predecir la presencia de diabetes basándose en IMC y glucosa
basal.
- Ejemplo práctico: En un dataset de 500 pacientes,
smf.glm('diabetes ~ IMC + glucosa', family=sm.families.Binomial()).fit()
estima odds ratios significativos para ambos predictores (\(p < 0.01\)).
Python: scipy:
- Descripción: Biblioteca para cálculos estadísticos
y científicos, con funciones para pruebas de hipótesis, distribuciones y
optimización.
- Funciones clave:
scipy.stats.ttest_ind: Prueba t para dos grupos.
scipy.stats.mannwhitneyu: Prueba no paramétrica de
Mann-Whitney.
scipy.stats.norm: Distribuciones para
simulaciones.
- Aplicación en salud: Realizar pruebas no
paramétricas para comparar tiempos de recuperación entre
tratamientos.
- Ejemplo práctico: En un estudio de recuperación
postquirúrgica,
scipy.stats.mannwhitneyu(grupo1, grupo2) da
un valor p de 0.04, indicando diferencias entre dos tratamientos.
Integración: Combinar tidyverse para limpieza de
datos, statsmodels para modelado y scipy para pruebas específicas en
pipelines de análisis.
10.2 Simulación y
Bootstrap
Métodos de
Remuestreo
Los métodos de remuestreo, como el bootstrap, generan distribuciones
empíricas de estadísticos sin asumir distribuciones teóricas, siendo
útiles en salud para datos con distribuciones no normales o muestras
pequeñas.
Bootstrap:
- Definición: Remuestreo con reemplazo de los datos
originales para estimar la distribución de un estadístico (e.g., media,
diferencia de medias).
- Algoritmo:
- Tomar \(B\) muestras con reemplazo
del tamaño original (\(n\)).
- Calcular el estadístico de interés en cada muestra (e.g., media,
mediana).
- Usar la distribución de los estadísticos para estimaciones o
intervalos.
- Tipos:
- No paramétrico: Remuestrea directamente los datos
observados.
- Paramétrico: Ajusta un modelo y simula datos a
partir de él.
- Aplicación en salud: Estimar la incertidumbre en la
tasa de respuesta a un tratamiento cuando la muestra es pequeña.
- Ejemplo práctico: En un ensayo con 30 pacientes, se
calcula la diferencia media en presión arterial (tratamiento
vs. placebo) usando 1000 muestras bootstrap. La media bootstrap es 5
mmHg, con un intervalo de confianza del 95% de [2, 8] mmHg.
Simulación:
- Definición: Generar datos sintéticos basados en un
modelo probabilístico para evaluar escenarios o propiedades
estadísticas.
- Aplicación en salud: Simular tasas de infección
bajo diferentes intervenciones para planificar recursos
hospitalarios.
- Ejemplo práctico: Simular 1000 ensayos clínicos con
una tasa de éxito del 70% (
numpy.random.binomial) para
estimar la potencia de un diseño experimental.
Aplicaciones en
Intervalos de Confianza y Pruebas
Intervalos de confianza (IC):
- Bootstrap percentil: Usar los percentiles 2.5% y
97.5% de la distribución bootstrap para un IC al 95%.
- Bootstrap BCa (Bias-Corrected and Accelerated):
Corrige sesgos y asimetrías, ideal para datos no normales.
- Aplicación en salud: Estimar un IC para la
diferencia en tasas de recuperación entre dos tratamientos.
- Ejemplo práctico: En un estudio de 50 pacientes por
grupo, el bootstrap no paramétrico calcula un IC al 95% para la
diferencia en tasas de recuperación ([0.05, 0.25]), indicando un efecto
significativo del tratamiento.
Pruebas de hipótesis:
- Bootstrap para pruebas: Comparar un estadístico
observado con su distribución bootstrap bajo \(H_0\).
- Aplicación en salud: Probar si la diferencia en
medias de glucosa entre dos grupos es significativa sin asumir
normalidad.
- Ejemplo práctico: En un estudio de diabetes, se usa
bootstrap para comparar medias de HbA1c entre grupos, generando 5000
muestras bajo \(H_0: \mu_1 = \mu_2\).
El valor p bootstrap es 0.02, rechazando \(H_0\).
Ventajas:
- No requiere supuestos de normalidad.
- Útil para muestras pequeñas o distribuciones desconocidas.
Limitaciones:
- Computacionalmente intensivo.
- Depende de la representatividad de la muestra original.
10.3 Visualización
de Datos
Gráficos para
Inferencia: Boxplots, Q-Q Plots, Histogramas
La visualización de datos es crucial para explorar distribuciones,
detectar anomalías y comunicar resultados inferenciales en salud. Los
gráficos específicos apoyan la validación de supuestos y la
interpretación de resultados.
Boxplots:
- Propósito: Mostrar distribución, mediana, cuartiles
y valores atípicos.
- Aplicación en salud: Comparar niveles de colesterol
entre grupos de tratamiento.
- Ejemplo práctico: Un boxplot
(
ggplot2::geom_boxplot) muestra que el grupo tratado tiene
una mediana de colesterol de 150 mg/dL frente a 180 mg/dL en el placebo,
con valores atípicos en ambos grupos, sugiriendo la necesidad de pruebas
no paramétricas.
Q-Q Plots:
- Propósito: Evaluar si los datos siguen una
distribución normal comparando cuantiles observados con cuantiles
teóricos.
- Aplicación en salud: Verificar la normalidad de
residuos en un modelo de regresión para glucosa.
- Ejemplo práctico: Un Q-Q plot
(
statsmodels.graphics.gofplots.qqplot) de residuos de un
modelo lineal muestra puntos alineados con la línea de 45°, confirmando
normalidad (\(p = 0.7\) en
Shapiro-Wilk).
Histogramas:
- Propósito: Visualizar la distribución de una
variable continua, detectando sesgos o multimodalidad.
- Aplicación en salud: Analizar la distribución de
tiempos de recuperación postquirúrgica.
- Ejemplo práctico: Un histograma
(
seaborn.histplot) de tiempos de recuperación muestra un
sesgo positivo, sugiriendo una transformación logarítmica antes de un
análisis paramétrico.
Herramientas como
ggplot2 y seaborn
ggplot2 (R):
- Descripción: Paquete basado en la gramática de
gráficos para crear visualizaciones personalizables y estéticas.
- Funciones clave:
geom_boxplot(): Boxplots para comparar grupos.
geom_histogram(): Histogramas para distribuciones.
geom_point() + geom_smooth(): Gráficos de dispersión
con líneas de regresión.
- Aplicación en salud: Visualizar la relación entre
IMC y glucosa con un gráfico de dispersión y curva de regresión.
- Ejemplo práctico: En un estudio de diabetes,
ggplot(datos, aes(x=IMC, y=glucosa)) + geom_point() + geom_smooth(method="lm")
muestra una relación positiva (\(\beta_1 =
2.5\), \(p < 0.01\)).
seaborn (Python):
- Descripción: Biblioteca basada en Matplotlib,
optimizada para visualizaciones estadísticas con sintaxis simple.
- Funciones clave:
seaborn.boxplot(): Boxplots para comparaciones
grupales.
seaborn.histplot(): Histogramas con estimación de
densidad.
seaborn.regplot(): Gráficos de regresión.
- Aplicación en salud: Comparar distribuciones de
presión arterial entre grupos con boxplots o visualizar correlaciones
entre biomarcadores.
- Ejemplo práctico: En un estudio cardiovascular,
seaborn.boxplot(x="tratamiento", y="presion", data=datos)
muestra diferencias claras entre grupos, confirmadas por ANOVA (\(p = 0.01\)).
Otras herramientas:
- Matplotlib (Python): Para gráficos personalizados,
útil en pipelines complejos.
- Plotly (R/Python): Gráficos interactivos para
presentaciones o dashboards en salud.
- Ejemplo práctico: Un dashboard interactivo con
plotly muestra tasas de hospitalización por COVID-19, permitiendo
explorar tendencias por región.
Recursos para el
Autoestudio en Salud
Lecturas:
- “R for Data Science” de Wickham y Grolemund (Capítulos sobre
tidyverse, ggplot2).
- “Python for Data Analysis” de McKinney (Capítulos sobre statsmodels,
scipy).
- “The Visual Display of Quantitative Information” de Tufte
(principios de visualización).
- “Biostatistics: A Foundation for Analysis in the Health Sciences” de
Daniel (Capítulos sobre software y visualización).
Ejercicios
prácticos:
- Usar R (tidyverse) para limpiar y analizar datos de ensayos
clínicos, aplicando pruebas t y ANOVA.
- Implementar bootstrap en Python (
numpy.random.choice)
para estimar IC de tasas de respuesta.
- Crear boxplots y Q-Q plots con ggplot2 o seaborn para verificar
supuestos en modelos de regresión.
- Simular datos clínicos con distribuciones binomiales o normales para
evaluar diseños experimentales.
Herramientas
computacionales:
- R: Paquetes
tidyverse (dplyr,
ggplot2), boot (bootstrap), stats (pruebas
inferenciales).
- Ejemplo:
boot(data, statistic=mean, R=1000) para bootstrap de la
media;
ggplot(datos, aes(x=tratamiento, y=colesterol)) + geom_boxplot().
- Python: Bibliotecas
statsmodels,
scipy, seaborn, numpy
(simulación).
- Ejemplo:
numpy.random.choice(datos, size=(1000, len(datos)), replace=True)
para bootstrap;
seaborn.histplot(datos['glucosa'], kde=True).
Bases de
datos:
- NHANES para datos de biomarcadores (e.g., colesterol, glucosa).
- ClinicalTrials.gov para datos de ensayos clínicos.
- WHO Global Health Observatory para datos epidemiológicos (e.g.,
tasas de diabetes).
Tabla Resumen:
Herramientas Computacionales en Estadística Inferencial en Salud
Tabla 10: Resumen de herramientas computacionales en estadística
inferencial para salud
|
Herramienta.o.Técnica
|
Tipo.de.Análisis
|
Función.Principal
|
Aplicación.en.Salud
|
Ejemplo.Práctico
|
|
R
|
Análisis estadístico y visualización
|
Realizar pruebas inferenciales, modelos y gráficos
|
ANOVA, regresión logística, análisis de supervivencia
|
t.test(antes, despues, paired=TRUE) da p = 0.03
|
|
Python
|
Análisis de datos y modelado
|
Integrar análisis con big data y machine learning
|
Modelado predictivo, análisis genómico, pipelines clínicos
|
smf.OLS(glucosa ~ IMC + edad).fit() con \(R^2 = 0.65\)
|
|
tidyverse (R)
|
Manipulación y visualización de datos
|
Limpiar, transformar y visualizar datos
|
Resumir datos de ensayos, calcular medias por grupo
|
datos %>% group_by(tratamiento) %>% summarise(mean_pa = mean(presion))
|
|
statsmodels (Python)
|
Modelado estadístico (regresión, ANOVA)
|
Ajustar modelos lineales y GLM
|
Modelar riesgo de diabetes con regresión logística
|
glm('diabetes ~ IMC + glucosa', family=Binomial()) con
\(p < 0.01\)
|
|
scipy (Python)
|
Pruebas estadísticas y distribuciones
|
Realizar pruebas de hipótesis
|
Comparar tiempos de recuperación con Mann-Whitney
|
mannwhitneyu(grupo1, grupo2) da p = 0.04
|
|
Bootstrap (remuestreo)
|
Estimación de incertidumbre
|
Estimar IC sin supuestos paramétricos
|
Estimar IC para tasa de respuesta en muestra pequeña
|
IC bootstrap [2, 8] mmHg para diferencia de presión arterial
|
|
Simulación Monte Carlo
|
Evaluación de escenarios y potencia
|
Generar datos sintéticos para evaluación
|
Simular poder de un ensayo con tasa de éxito del 70%
|
Simular 1000 ensayos con numpy.random.binomial
|
|
Boxplot
|
Comparación de grupos
|
Mostrar mediana, cuartiles y atípicos
|
Comparar niveles de colesterol entre tratamientos
|
Boxplot muestra mediana de 150 vs. 180 mg/dL
|
|
Q-Q Plot
|
Evaluación de normalidad
|
Evaluar normalidad comparando cuantiles
|
Verificar normalidad de residuos en regresión
|
Q-Q plot confirma normalidad (\(p =
0.7\) en Shapiro-Wilk)
|
|
Histograma
|
Análisis de distribución
|
Visualizar forma de la distribución
|
Analizar sesgo en tiempos de recuperación
|
Histograma muestra sesgo positivo en tiempos
|
|
ggplot2 (R)
|
Visualización avanzada
|
Crear gráficos personalizables con gramática de gráficos
|
Visualizar relación entre IMC y glucosa
|
ggplot() + geom_point() + geom_smooth(method="lm") muestra
una relación positiva (\(\beta_1 =
2.5\), \(p < 0.01\))
|
|
seaborn (Python)
|
Visualización estadística
|
Gráficos estadísticos simples y elegantes
|
Comparar presión arterial entre grupos
|
seaborn.boxplot(x="tratamiento", y="presion", data=datos)
muestra diferencias claras (\(p =
0.01\))
|
|
Plotly (R/Python)
|
Visualización interactiva
|
Gráficos interactivos para dashboards
|
Dashboard interactivo de hospitalizaciones por COVID-19
|
Dashboard con tendencias por región
|
11. Aplicaciones
Prácticas y Estudios de Caso en Salud
Este temario desarrolla aplicaciones prácticas de la estadística
inferencial en el sector salud, enfocándose en el análisis de datos
reales, la validación de supuestos estadísticos y la redacción de
informes. Con un enfoque orientado a profesionales médicos,
investigadores clínicos y epidemiólogos, se presentan estudios de caso,
técnicas de diagnóstico y directrices para comunicar resultados de
manera clara y rigurosa. Las aplicaciones en salud incluyen ensayos
clínicos, estudios epidemiológicos y evaluaciones de intervenciones,
integrando métodos como pruebas de hipótesis, ANOVA, regresión, series
temporales y métodos multivariados.
11.1 Análisis de
Datos Reales
Estudios de Caso
en Ciencias Sociales, Biología, Economía, etc.
El análisis de datos reales en salud implica aplicar métodos
estadísticos inferenciales a conjuntos de datos reales para responder
preguntas clínicas o epidemiológicas, interpretar resultados en contexto
y tomar decisiones basadas en evidencia.
Estudio de caso 1: Ensayo clínico
(Biología/Salud)
- Contexto: Evaluar la eficacia de un nuevo fármaco
antihipertensivo frente a un placebo en pacientes con hipertensión leve
a moderada.
- Datos: 200 pacientes asignados aleatoriamente (100
fármaco, 100 placebo), con mediciones de presión arterial sistólica
(PAS) al inicio y tras 12 semanas. Variable dependiente: cambio en PAS
(mmHg).
- Método: Prueba t de dos muestras para comparar el
cambio medio en PAS entre grupos.
- Resultados: Media del cambio en PAS: -15 mmHg
(fármaco), -5 mmHg (placebo). Estadístico \(t
= -4.2\), \(p < 0.001\),
rechazando \(H_0: \mu_{\text{fármaco}} =
\mu_{\text{placebo}}\). Intervalo de confianza (IC) al 95% para
la diferencia: [-13.5, -6.5] mmHg.
- Interpretación en contexto: El fármaco reduce
significativamente la PAS en comparación con el placebo, con un efecto
clínico relevante (10 mmHg mayor reducción). Esto sugiere que el fármaco
podría ser una opción terapéutica viable, pendiente de estudios
adicionales sobre seguridad.
- Aplicación práctica: Los resultados apoyan la
aprobación del fármaco en ensayos de fase III, informando guías
clínicas.
Estudio de caso 2: Epidemiología (Ciencias
Sociales/Salud)
- Contexto: Analizar la relación entre el índice de
masa corporal (IMC) y el riesgo de diabetes tipo 2 en una población
urbana.
- Datos: Encuesta transversal de 500 adultos, con IMC
(kg/m²) y diagnóstico de diabetes (sí/no).
- Método: Regresión logística para modelar la
probabilidad de diabetes en función del IMC, ajustando por edad y
sexo.
- Resultados: Coeficiente para IMC: \(\beta_1 = 0.12\), \(p = 0.002\); odds ratio \(\exp(0.12) \approx 1.13\). IC al 95% para
el odds ratio: [1.05, 1.22]. Por cada unidad de aumento en IMC, los odds
de diabetes aumentan un 13%.
- Interpretación en contexto: El IMC es un predictor
significativo del riesgo de diabetes, con un impacto moderado pero
clínicamente relevante. Esto resalta la importancia de intervenciones
para reducir la obesidad en la prevención de diabetes.
- Aplicación práctica: Los resultados pueden guiar
campañas de salud pública enfocadas en la reducción de peso en
poblaciones urbanas.
Estudio de caso 3: Series temporales
(Salud/Epidemiología)
- Contexto: Predecir casos semanales de influenza
para planificar recursos hospitalarios.
- Datos: Casos semanales de influenza (2018-2025) de
un sistema de vigilancia epidemiológica.
- Método: Modelo SARIMA \((1,1,1) \times (1,1,1)_{52}\) para capturar
tendencia y estacionalidad anual.
- Resultados: Predicciones para las próximas 12
semanas muestran un pico estacional en invierno, con un RMSE de 45 casos
en datos de validación. Intervalos de predicción al 95% cubren el 90% de
los casos observados.
- Interpretación en contexto: El modelo predice con
precisión los picos de influenza, permitiendo a los hospitales
prepararse para aumentos en la demanda de camas y personal.
- Aplicación práctica: Los resultados informan la
planificación de campañas de vacunación y la asignación de recursos en
temporadas de alta incidencia.
Interpretación de
Resultados en Contexto
- Enfoque clínico: Los resultados deben interpretarse
considerando su relevancia clínica, no solo su significancia
estadística. Por ejemplo, una diferencia de 2 mmHg en PAS puede ser
estadísticamente significativa pero clínicamente irrelevante.
- Limitaciones: Reconocer sesgos (e.g., selección,
medición), tamaños muestrales pequeños o supuestos no cumplidos que
puedan afectar las conclusiones.
- Impacto práctico: Traducir hallazgos en
recomendaciones accionables, como ajustar tratamientos, diseñar
intervenciones o informar políticas de salud.
- Ejemplo práctico: En el estudio de hipertensión, el
IC al 95% [-13.5, -6.5] sugiere que el fármaco es consistentemente más
efectivo que el placebo, pero se debe considerar el costo y los efectos
secundarios antes de recomendar su uso generalizado.
11.2 Validación de
Supuestos
La validez de los métodos inferenciales depende del cumplimiento de
supuestos estadísticos. En salud, donde los datos suelen ser complejos
(e.g., no normales, heterocedásticos), es crucial diagnosticar y, si es
necesario, corregir violaciones.
Diagnósticos de
Normalidad, Homocedasticidad, Independencia
Normalidad:
- Propósito: Verificar si los datos o residuos siguen
una distribución normal, asumida en pruebas paramétricas (e.g., t-test,
ANOVA).
- Métodos de diagnóstico:
- Gráficos: Histogramas, gráficos Q-Q de
residuos.
- Pruebas: Shapiro-Wilk (\(H_0\): normalidad),
Kolmogorov-Smirnov.
- Aplicación en salud: Comprobar si los cambios en
PAS tras un tratamiento son normales para aplicar una prueba t.
- Ejemplo práctico: En el ensayo antihipertensivo, un
gráfico Q-Q de los residuos de un modelo ANOVA muestra desviaciones en
las colas, y Shapiro-Wilk da \(p =
0.03\), sugiriendo no normalidad. Esto indica la necesidad de una
transformación o un método no paramétrico.
Homocedasticidad:
- Propósito: Verificar que la varianza de los
residuos es constante entre grupos o a lo largo de una covariable,
asumido en ANOVA y regresión.
- Métodos de diagnóstico:
- Gráficos: Residuos vs. valores predichos
(dispersión constante indica homocedasticidad).
- Pruebas: Levene (\(H_0\): varianzas iguales), Breusch-Pagan
(en regresión).
- Aplicación en salud: Asegurar que la varianza en
los niveles de glucosa es similar entre grupos tratados y placebo.
- Ejemplo práctico: En un estudio de diabetes, la
prueba de Levene para los residuos de un ANOVA da \(p = 0.01\), indicando heterocedasticidad.
Esto sugiere usar un ANOVA robusto (e.g., Welch) o transformar los
datos.
Independencia:
- Propósito: Asegurar que las observaciones o
residuos no están correlacionados, especialmente en series temporales o
datos agrupados.
- Métodos de diagnóstico:
- Gráficos: ACF (autocorrelación) de residuos.
- Pruebas: Durbin-Watson (\(H_0\): no autocorrelación) para regresión;
Ljung-Box para series temporales.
- Aplicación en salud: Verificar que las mediciones
de presión arterial de pacientes en un ensayo clínico no estén
correlacionadas debido a efectos de clúster (e.g., mismo hospital).
- Ejemplo práctico: En una serie temporal de casos de
influenza, el ACF de los residuos de un modelo ARIMA muestra
autocorrelación significativa en lag 1 (\(p =
0.02\), Ljung-Box), sugiriendo un modelo SARIMA para capturar
estacionalidad.
Recursos para el
Autoestudio en Salud
Lecturas:
- “Biostatistics: A Foundation for Analysis in the Health Sciences” de
Daniel (Capítulos sobre aplicaciones prácticas).
- “Medical Statistics: A Textbook for the Health Sciences” de Campbell
et al. (Capítulos sobre análisis y redacción).
- “The Elements of Statistical Learning” de Hastie et al. (Capítulos
sobre diagnóstico de supuestos).
Ejercicios
prácticos:
- Analizar un conjunto de datos de NHANES (e.g., glucosa, colesterol)
con regresión logística, verificando supuestos.
- Realizar un análisis de series temporales en datos de influenza (CDC
FluView), ajustando un modelo SARIMA.
- Redactar un informe completo para un ensayo clínico simulado,
incluyendo gráficos y diagnósticos de supuestos.
Herramientas
computacionales:
- R: Paquetes
stats (t.test, lm),
car (diagnósticos: shapiro.test, leveneTest),
ggplot2 (visualización).
- Ejemplo:
shapiro.test(resid(model))
para normalidad;
ggplot(data, aes(x=tratamiento, y=pas)) + geom_boxplot()
para visualización.
- Python: Librerías
statsmodels
(regresión, ANCOVA), scipy.stats (pruebas de normalidad),
seaborn (visualización).
- Ejemplo:
statsmodels.stats.diagnostic.het_breuschpagan(resid, X)
para homocedasticidad;
sns.boxplot(x='tratamiento', y='pas', data=datos).
Bases de
datos:
- NHANES para biomarcadores (e.g., glucosa, presión arterial).
- ClinicalTrials.gov para datos de ensayos clínicos.
- WHO Global Health Observatory para datos epidemiológicos (e.g.,
incidencia de enfermedades).
Tabla Resumen:
Aplicaciones Prácticas y Estudios de Caso en Salud
Tabla 11: Resumen de aplicaciones prácticas de la estadística
inferencial en salud
|
Área.de.Aplicación
|
Método.Estadístico
|
Validación.de.Supuestos
|
Interpretación.Clínica
|
Ejemplo.Práctico
|
|
Ensayo Clínico
|
Prueba t de dos muestras
|
Normalidad (Q-Q plot, Shapiro-Wilk)
|
Diferencia de 10 mmHg en PAS: clínicamente relevante
|
Fármaco reduce PAS en 10 mmHg más que placebo (IC 95%: [6.5, 13.5], p
< 0.001)
|
|
Epidemiología
|
Regresión logística
|
Independencia, linealidad, sin multicolinealidad
|
Aumento del 13% en odds de diabetes por cada unidad de IMC
|
IMC asociado a diabetes: OR = 1.13 (IC 95%: [1.05, 1.22], p = 0.002)
|
|
Series Temporales
|
Modelo SARIMA
|
Estacionariedad, normalidad de residuos, autocorrelación (ACF)
|
Predicción precisa de picos de influenza en invierno
|
SARIMA(1,1,1)x(1,1,1)₅₂ predice casos de influenza con RMSE = 45
|
|
Validación de Supuestos
|
Transformación de datos (logaritmo)
|
Normalidad y homocedasticidad tras transformación
|
Datos transformados permiten usar métodos paramétricos válidos
|
ln(PAS) corrige no normalidad (Shapiro-Wilk p = 0.15 tras
transformación)
|
|
Validación de Supuestos
|
Pruebas no paramétricas
|
No requiere normalidad ni homocedasticidad
|
Uso de métodos robustos cuando los supuestos fallan
|
Prueba de Wilcoxon usada cuando datos no normales persisten
|
|
Validación de Supuestos
|
Diagnósticos gráficos y estadísticos
|
Shapiro-Wilk, Levene, Durbin-Watson, ACF
|
Garantiza validez y reproducibilidad del análisis
|
Levene (p = 0.01) detecta heterocedasticidad; se aplica corrección
|
|
Redacción de Informes
|
Estructura estandarizada de informe
|
Reporte explícito de diagnósticos y pruebas
|
Comunicación clara y ética de resultados para toma de decisiones
|
Informe incluye metodología, resultados, discusión y apéndices con
código
|
Conclusión:
Estadística Inferencial para el Sector Salud
La estadística inferencial es una herramienta fundamental en el
sector salud para transformar datos en evidencia científica, guiar
decisiones clínicas, evaluar intervenciones y predecir tendencias
epidemiológicas. A lo largo de este temario, se han desarrollado de
forma progresiva y aplicada los principales métodos inferenciales —desde
la estimación de parámetros hasta el análisis de series temporales—,
siempre con un enfoque centrado en el profesional de la salud: médico,
investigador clínico, epidemiólogo o gestor sanitario.
Se ha demostrado cómo técnicas como las pruebas de hipótesis, ANOVA,
regresión, métodos multivariados y modelos bayesianos permiten responder
preguntas críticas en salud: ¿Es efectivo un nuevo tratamiento? ¿Qué
factores predicen la diabetes? ¿Cómo evoluciona una epidemia? Además, se
ha enfatizado la importancia de validar supuestos estadísticos, utilizar
herramientas computacionales como R y Python, y comunicar resultados con
rigor y claridad, evitando errores comunes como la sobreinterpretación
del valor p o el descuido de la relevancia clínica.
Los estudios de caso y aplicaciones prácticas han mostrado que la
estadística no es solo una herramienta técnica, sino una competencia
esencial para la toma de decisiones basada en evidencia. Con el apoyo de
software moderno, simulaciones, bootstrap y visualización efectiva, los
profesionales de la salud pueden no solo entender, sino también aplicar
y comunicar hallazgos estadísticos con confianza.
En un mundo donde los datos clínicos y epidemiológicos crecen
exponencialmente, dominar la estadística inferencial ya no es opcional:
es una responsabilidad profesional y ética para garantizar la calidad,
eficacia y equidad en la atención sanitaria.
Tabla Resumen Final:
Temarios de Estadística Inferencial en Salud
Tabla 12: Resumen completo de los temas de estadística inferencial en
salud
|
Tema
|
Objetivo.Principal
|
Métodos.Clave
|
Aplicación.en.Salud
|
Ejemplo.Práctico
|
- Estimación de Parámetros
|
Estimar parámetros poblacionales (media, proporción, varianza) a partir
de muestras
|
Estimación puntual y por intervalos, tamaño muestral
|
Estimar prevalencia de diabetes, niveles promedio de colesterol
|
IC del 95% para la media de glucosa: [115, 125] mg/dL
|
- Pruebas de Hipótesis
|
Evaluar afirmaciones sobre parámetros mediante pruebas estadísticas
|
Pruebas t, z, chi-cuadrado, errores Tipo I/II, potencia
|
Determinar si un fármaco reduce la presión arterial
|
t-test muestra que el fármaco reduce PAS (p < 0.01)
|
- Análisis de Varianza (ANOVA)
|
Comparar medias entre múltiples grupos (e.g., tratamientos)
|
ANOVA de uno y dos factores, post-hoc (Tukey, Bonferroni)
|
Comparar efecto de tres dosis de un antihipertensivo
|
ANOVA detecta diferencias entre tres tratamientos (p = 0.015)
|
- Regresión y Modelos Lineales
|
Modelar relaciones entre variables (e.g., IMC y glucosa)
|
Regresión lineal simple y múltiple, GLM (logística, Poisson)
|
Predecir riesgo de infarto usando múltiples factores
|
Regresión logística: IMC incrementa odds de diabetes en 13%
|
- Métodos Multivariados
|
Reducir dimensionalidad, clasificar o descubrir patrones en datos
multivariantes
|
PCA, análisis factorial, clúster, análisis discriminante, ACM
|
Identificar perfiles de pacientes o factores subyacentes en síntomas
|
PCA reduce 10 biomarcadores a 2 componentes principales
|
- Inferencia Bayesiana
|
Actualizar creencias sobre parámetros usando datos y conocimiento previo
|
Teorema de Bayes, priors, MCMC, intervalos de credibilidad
|
Actualizar eficacia de una vacuna con datos de nuevos ensayos
|
Posteriori: probabilidad de respuesta al fármaco = 75% (ICr 95%: [68%,
82%])
|
- Diseño de Experimentos (DOE)
|
Diseñar estudios clínicos con aleatorización, bloqueo y control de
sesgos
|
Diseño completamente aleatorizado, bloques, factorial, medidas repetidas
|
Diseñar un ensayo clínico con aleatorización y control
|
Bloques por edad en ensayo para controlar confusión
|
- Análisis de Series Temporales
|
Predecir tendencias y patrones en datos secuenciales (e.g., brotes de
enfermedades)
|
ARIMA, SARIMA, descomposición STL, GARCH
|
Predecir casos de influenza para planificar recursos hospitalarios
|
SARIMA predice pico de influenza con RMSE = 45 casos
|
- Herramientas Computacionales
|
Aplicar software, simulación y visualización para análisis inferencial
|
R, Python, bootstrap, ggplot2, seaborn
|
Analizar datos clínicos con R/Python y visualizar resultados
|
Bootstrap estima IC para mediana sin asumir normalidad
|
- Aplicaciones Prácticas y Estudios de Caso
|
Integrar métodos en contextos reales, validar supuestos y comunicar
resultados
|
Estudios de caso, diagnóstico de supuestos, redacción de informes
|
Validar supuestos, interpretar resultados clínicamente, redactar
informes
|
Informe final comunica resultados clínicamente relevantes con gráficos y
código
|
Recursos
Bibliográficos: Estadística Inferencial en el Sector Salud
A continuación, se presenta una lista de libros y recursos esenciales
sobre estadística inferencial, con enfoque en aplicaciones en salud,
epidemiología y ciencias clínicas. Todos los enlaces han sido
verificados y son accesibles (junio 2025).
📘 Libros de Texto y
Referencia
Daniel, W. W., & Cross, C. L. (2018).
Biostatistics: A Foundation for Analysis in the Health Sciences
(11th ed.).
Libro de referencia clásica para estudiantes y profesionales en salud.
Cubre desde pruebas de hipótesis hasta regresión y ANOVA.
🔗 https://www.wiley.com/en-us/Biostatistics%3A+A+Foundation+for+Analysis+in+the+Health+Sciences%2C+11th+Edition-p-9781119435973
Rosner, B. (2015). Fundamentals of Biostatistics
(8th ed.).
Enfoque claro y aplicado a métodos inferenciales, con ejemplos clínicos
detallados. Ideal para autoestudio.
🔗 https://www.cengage.com/c/fundamentals-of-biostatistics-8e-rosner/9781305268920/
Moore, D. S., Notz, W., & Fligner, M. A. (2021).
The Basic Practice of Statistics (9th ed.).
Excelente para principiantes. Enfatiza la comprensión conceptual y la
interpretación clínica.
🔗 https://www.macmillanlearning.com/college/us/product/The-Basic-Practice-of-Statistics/p/131934378X
Gelman, A., Carlin, J. B., Stern, H. S., Dunson, D. B.,
Vehtari, A., & Rubin, D. B. (2013). Bayesian Data Analysis
(3rd ed.).
Referencia definitiva sobre inferencia bayesiana, con aplicaciones en
salud pública y ensayos clínicos.
🔗 https://www.routledge.com/Bayesian-Data-Analysis-Third-Edition/Gelman-Carlin-Stern-Dunson-Vehtari-Rubin/p/book/9781439840955
Shumway, R. H., & Stoffer, D. S. (2017). Time
Series Analysis and Its Applications: With R Examples (4th
ed.).
Guía práctica para análisis de series temporales en salud, con código R
incluido.
🔗 https://www.springer.com/gp/book/9783319524511
Hair, J. F., Black, W. C., Babin, B. J., & Anderson,
R. E. (2019). Multivariate Data Analysis (8th
ed.).
Estándar en métodos multivariados como PCA, factores, clúster y
discriminante.
🔗 https://www.pearson.com/us/higher-education/program/Hair-Multivariate-Data-Analysis-8th-Edition/PGM334920.html
🌐 Recursos
Gratuitos y Open Access
Hyndman, R. J., & Athanasopoulos, G. (2021).
Forecasting: Principles and Practice (3rd ed.).
Libro gratuito con enfoque práctico en series temporales, ampliamente
usado en salud pública.
🔗 https://otexts.com/fpp3/
✅ Versión interactiva con código R (tidyverts)
Illowsky, B., Dean, S., et al. Introductory
Statistics. OpenStax.
Recurso gratuito con cobertura completa de estadística inferencial.
Ideal para repaso.
🔗 https://openstax.org/details/books/introductory-statistics
✅ Descarga gratuita en PDF, EPUB y online
Szabó, A. (2023). Statistics for Health, Life and
Social Sciences. Bookboon.
Enfoque aplicado a salud y ciencias sociales, con ejemplos reales y
software.
🔗 https://bookboon.com/en/statistics-for-health-life-and-social-sciences-ebook
✅ Gratis con registro (PDF)
🖥️ Documentación y
Herramientas de Software
🏛️ Bases de Datos y
Repositorios Públicos
LS0tCnRpdGxlOiAiRXN0YWTDrXN0aWNhIHBhcmEgY2llbmNpYSBkZSBkYXRvcyIKc3VidGl0bGU6ICJFc3RhZMOtc3RpY2EgaW5mZXJlbmNpYWwiCmF1dGhvcjogIkFsZm9uc28gRWR1YXJkbyBHZXJhbGRpbm8gRXBpZXl1IgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdGhlbWU6IGNvc21vCiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICBjc3M6IGVzdGlsb3MvcGVyc29uYWxpemFkby5jc3MKICAgIGluY2x1ZGVzOgogICAgICBpbl9oZWFkZXI6IHJlY3Vyc29zL2hlYWRlci5odG1sCiAgICAgIGFmdGVyX2JvZHk6IHJlY3Vyc29zL2FuYWx5dGljcy5odG1sCiAgICBtYXRoamF4OiBkZWZhdWx0CiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDMKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgZGZfcHJpbnQ6IGthYmxlCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIHNlbGZfY29udGFpbmVkOiBmYWxzZQogICAgc21hcnQ6IHRydWUKICAgIHBhbmRvY19hcmdzOgogICAgICAtICItLW1ldGFkYXRhIgogICAgICAtICJkZXNjcmlwdGlvbj1HdcOtYSBhdmFuemFkYSBkZSBFc3RhZMOtc3RpY2EgSW5mZXJlbmNpYWwgcGFyYSBDaWVuY2lhIGRlIERhdG9zIgogICAgICAtICItLW1ldGFkYXRhIgogICAgICAtICJrZXl3b3Jkcz1lc3RhZGlzdGljYSBpbmZlcmVuY2lhbCwgciwgcm1hcmtkb3duLCBjaWVuY2lhIGRlIGRhdG9zLCBhbm92YSwgcmVncmVzaW9uLCBiYXllcyIKICAgICAgLSAiLS1tZXRhZGF0YSIKICAgICAgLSAibGFuZz1lcyIKYWJzdHJhY3Q6IHwKICBFc3RlIGRvY3VtZW50byBwcmVzZW50YSB1biBwcm9ncmFtYSBpbnRlZ3JhbCB5IGVzdHJ1Y3R1cmFkbyBwYXJhIGVsIGF1dG9lc3R1ZGlvIGF2YW56YWRvIGRlIEVzdGFkw61zdGljYSBJbmZlcmVuY2lhbCwgZGlzZcOxYWRvIGVzcGVjw61maWNhbWVudGUgcGFyYSBjaWVudMOtZmljb3MgZGUgZGF0b3MsIGludmVzdGlnYWRvcmVzIGNsw61uaWNvcyB5IHByb2Zlc2lvbmFsZXMgZGUgbGEgc2FsdWQgcXVlIHRyYWJhamFuIGNvbiBpbmZvcm1hY2nDs24gYmlvbcOpZGljYSB5IGVwaWRlbWlvbMOzZ2ljYS4gRWwgdGVtYXJpbyBjb21iaW5hIGZ1bmRhbWVudG9zIHRlw7NyaWNvcyBzw7NsaWRvcyBjb24gYXBsaWNhY2lvbmVzIHByw6FjdGljYXMgZW4gbWVkaWNpbmEsIGludGVncmFuZG8gbcOpdG9kb3MgZXN0YWTDrXN0aWNvcyBjb24gaGVycmFtaWVudGFzIGNvbXB1dGFjaW9uYWxlcyBlbiBSIHBhcmEgZWwgYW7DoWxpc2lzIHkgbGEgaW50ZXJwcmV0YWNpw7NuIGRlIGRhdG9zIGRlIHNhbHVkLgprZXl3b3JkczogW2VzdGFkw61zdGljYSBpbmZlcmVuY2lhbCwgY2llbmNpYSBkZSBkYXRvcywgUiwgaW5mZXJlbmNpYSBiYXllc2lhbmEsIEFOT1ZBLCByZWdyZXNpw7NuLCBHTE1dCmxhbmc6IGVzCmVkaXRvcl9vcHRpb25zOiAKICBtYXJrZG93bjogCiAgICB3cmFwOiA3MgotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgZWNobyA9IEZBTFNFLAogIHdhcm5pbmcgPSBGQUxTRSwKICBtZXNzYWdlID0gRkFMU0UsCiAgZmlnLmFsaWduID0gJ2NlbnRlcicKKQpgYGAKCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShrYWJsZUV4dHJhKQpgYGAKCiMgVGVtYXJpbyBwYXJhIGF1dG9lc3R1ZGlvIGF2YW56YWRvIGRlIEVzdGFkw61zdGljYSBJbmZlcmVuY2lhbAoKIyMgMS4gRnVuZGFtZW50b3MgZGUgZXN0YWTDrXN0aWNhIGVuZmVyZW5jaWFsCgojIyMgMS4xIENvbmNlcHRvcyBiw6FzaWNvcwoKLSAgICoqRGVmaW5pY2nDs24gZGUgaW5mZXJlbmNpYSBlc3RhZMOtc3RpY2EqKjogUHJvY2VzbyBkZSBnZW5lcmFsaXphcgogICAgcmVzdWx0YWRvcyBkZSB1bmEgbXVlc3RyYSBhIHVuYSBwb2JsYWNpw7NuLgotICAgKipQb2JsYWNpw7NuLCBtdWVzdHJhIHkgcGFyw6FtZXRyb3MqKjogRGlmZXJlbmNpYSBlbnRyZSBlc3RhZMOtc3RpY29zCiAgICAobXVlc3RyYSkgeSBwYXLDoW1ldHJvcyAocG9ibGFjacOzbikuCi0gICAqKlRpcG9zIGRlIGRhdG9zIHkgZXNjYWxhcyBkZSBtZWRpY2nDs24qKjogTm9taW5hbCwgb3JkaW5hbCwgZGUKICAgIGludGVydmFsbyB5IGRlIHJhesOzbi4KCiMjIyAxLjIgUHJvYmFiaWxpZGFkIGF2YW56YWRhCgotICAgKipFc3BhY2lvcyBtdWVzdHJhbGVzIHkgZXZlbnRvcyoqOiBDb25qdW50byBkZSB0b2RvcyBsb3MgcmVzdWx0YWRvcwogICAgcG9zaWJsZXMgeSBzdWJjb25qdW50b3MgZGUgaW50ZXLDqXMuCi0gICAqKlJlZ2xhcyBkZSBwcm9iYWJpbGlkYWQqKjogUmVnbGEgZGUgbGEgc3VtYSwgcmVnbGEgZGVsIHByb2R1Y3RvLAogICAgcHJvYmFiaWxpZGFkIGNvbmRpY2lvbmFsLCB0ZW9yZW1hIGRlIEJheWVzLgotICAgKipWYXJpYWJsZXMgYWxlYXRvcmlhcyBkaXNjcmV0YXMgeSBjb250aW51YXMqKjogRnVuY2lvbmVzIGRlIG1hc2EKICAgIChQTUYpIHkgZGVuc2lkYWQgKFBERikuCgojIyMgMS4zIERpc3RyaWJ1Y2lvbmVzIGRlIHByb2JhYmlsaWRhZAoKLSAgICoqRGlzdHJpYnVjaW9uZXMgZGlzY3JldGFzKio6IEJpbm9taWFsICjDqXhpdG9zIGVuIG4gZW5zYXlvcyksCiAgICBQb2lzc29uIChldmVudG9zIGVuIGludGVydmFsbyksIEdlb23DqXRyaWNhIChwcmltZXIgw6l4aXRvKS4KLSAgICoqRGlzdHJpYnVjaW9uZXMgY29udGludWFzKio6IE5vcm1hbCAoZ2F1c3NpYW5hKSwgdCBkZSBTdHVkZW50CiAgICAobXVlc3RyYXMgcGVxdWXDsWFzKSwgQ2hpLWN1YWRyYWRvICh2YXJpYW56YXMpLCBGIChyYXrDs24gZGUKICAgIHZhcmlhbnphcykuCi0gICAqKlRlb3JlbWEgZGVsIEzDrW1pdGUgQ2VudHJhbCoqOiBMYSBkaXN0cmlidWNpw7NuIGRlIGxhIG1lZGlhIG11ZXN0cmFsCiAgICB0aWVuZGUgYSBzZXIgbm9ybWFsLCBpbmRlcGVuZGllbnRlbWVudGUgZGUgbGEgZGlzdHJpYnVjacOzbiBvcmlnaW5hbC4KCiMjIDIuIEVzdGltYWNpw7NuIGRlIFBhcsOhbWV0cm9zCgojIyMgMi4xIEVzdGltYWNpw7NuIHB1bnR1YWwKCi0gICAqKlByb3BpZWRhZGVzIGRlIGxvcyBlc3RpbWFkb3JlcyoqOiBTZXNnbyAoZXhhY3RpdHVkKSwgZWZpY2llbmNpYQogICAgKHZhcmlhbnphIGJhamEpLCBjb25zaXN0ZW5jaWEgKGNvbnZlcmdlIGFsIHZhbG9yIHJlYWwpLgotICAgKipNw6l0b2RvcyBkZSBlc3RpbWFjacOzbioqOiBNw6F4aW1hIHZlcm9zaW1pbGl0dWQgKE1MRSksIG3DqXRvZG8gZGUKICAgIG1vbWVudG9zLgoKIyMjIDIuMiBFc3RpbWFjacOzbiBwb3IgaW50ZXJ2YWxvcwoKLSAgICoqSW50ZXJ2YWxvcyBkZSBjb25maWFuemEqKjogUGFyYSBtZWRpYXMgKHosIHQpLCBwcm9wb3JjaW9uZXMKICAgIChub3JtYWwgYXBwcm94aW1hdGlvbiksIHZhcmlhbnphcyAoQ2hpLWN1YWRyYWRvKS4KLSAgICoqSW50ZXJwcmV0YWNpw7NuIHkgY8OhbGN1bG8qKjogIkVzdGFtb3MgOTUlIHNlZ3Vyb3MgZGUgcXVlIGVsCiAgICBwYXLDoW1ldHJvIGVzdMOhIGVuIGVzdGUgcmFuZ28iLgotICAgKipUYW1hw7FvIG11ZXN0cmFsIHkgcHJlY2lzacOzbioqOiBSZWxhY2nDs24gZW50cmUgbiwgbWFyZ2VuIGRlIGVycm9yIHkKICAgIG5pdmVsIGRlIGNvbmZpYW56YS4KCiMjIDMuIFBydWViYXMgZGUgSGlww7N0ZXNpcwoKIyMjIDMuMSBGdW5kYW1lbnRvcwoKLSAgICoqSGlww7N0ZXNpcyBudWxhIHkgYWx0ZXJuYXRpdmEqKjogJEhfMCQgdnMgJEhfMSQ7IGxvIHF1ZSBzZSBwcnVlYmEKICAgIHZzLiBsbyBxdWUgc2Ugc29zcGVjaGEuCi0gICAqKkVycm9yZXMgdGlwbyBJIHkgdGlwbyBJSSoqOiBSZWNoYXphciAkSF8wJCBjdWFuZG8gZXMgdmVyZGFkZXJhCiAgICAozrEpLCBubyByZWNoYXphciAkSF8wJCBjdWFuZG8gZXMgZmFsc2EgKM6yKS4KLSAgICoqTml2ZWwgZGUgc2lnbmlmaWNhbmNpYSB5IHBvdGVuY2lhKio6CiAgICAkXGFscGhhID0gUChcdGV4dHtlcnJvciB0aXBvIEl9KSQsIHBvdGVuY2lhID0gJDEgLSBcYmV0YSQuCgojIyMgMy4yIFBydWViYXMgcGFyYW3DqXRyaWNhcwoKLSAgICoqUHJ1ZWJhcyBwYXJhIHVuYSB5IGRvcyBtZWRpYXMqKjogei10ZXN0ICh2YXJpYW56YSBjb25vY2lkYSksCiAgICB0LXRlc3QgKGluZGVwZW5kaWVudGVzLCBwYXJlYWRvcykuCi0gICAqKlBydWViYXMgcGFyYSBwcm9wb3JjaW9uZXMqKjogVW5hIHkgZG9zIHByb3BvcmNpb25lcyBjb24KICAgIGFwcm94aW1hY2nDs24gbm9ybWFsLgotICAgKipQcnVlYmFzIHBhcmEgdmFyaWFuemFzKio6IENoaS1jdWFkcmFkbyAodW5hIHZhcmlhbnphKSwgRi10ZXN0IChkb3MKICAgIHZhcmlhbnphcykuCgojIyMgMy4zIFBydWViYXMgbm8gcGFyYW3DqXRyaWNhcwoKLSAgICoqUHJ1ZWJhIGRlIFdpbGNveG9uLCBNYW5uLVdoaXRuZXksIEtydXNrYWwtV2FsbGlzKio6IEFsdGVybmF0aXZhcyBhCiAgICB0LXRlc3QgeSBBTk9WQSBjdWFuZG8gbm8gaGF5IG5vcm1hbGlkYWQuCi0gICAqKlBydWViYSBkZSBzaWdub3MgeSByYW5nb3MgY29uIHNpZ25vKio6IFBhcmEgZGF0b3MgcGFyZWFkb3Mgbm8KICAgIG5vcm1hbGVzLgotICAgKipWZW50YWphcyB5IGxpbWl0YWNpb25lcyoqOiBSb2J1c3RhcywgcGVybyBtZW5vcyBwb3RlbnRlcyBxdWUgc3VzCiAgICBjb250cmFwYXJ0ZXMgcGFyYW3DqXRyaWNhcy4KCiMjIDQuIEFuw6FsaXNpcyBkZSBWYXJpYW56YSAoQU5PVkEpCgojIyMgNC4xIEFOT1ZBIGRlIHVuIGZhY3RvcgoKLSAgICoqU3VwdWVzdG9zIHkgbW9kZWxvKio6IE5vcm1hbGlkYWQsIGhvbW9jZWRhc3RpY2lkYWQsIGluZGVwZW5kZW5jaWEuCi0gICAqKlN1bWEgZGUgY3VhZHJhZG9zIHkgdGFibGEgQU5PVkEqKjogU1NUID0gU1NCICsgU1NXOyBGLXN0YXRpc3RpYy4KLSAgICoqUHJ1ZWJhcyBwb3N0LWhvYyoqOiBUdWtleSBIU0QsIEJvbmZlcnJvbmksIFNjaGVmZsOpIHBhcmEKICAgIGNvbXBhcmFjaW9uZXMgbcO6bHRpcGxlcy4KCiMjIyA0LjIgQU5PVkEgZGUgZG9zIGZhY3RvcmVzCgotICAgKipJbnRlcmFjY2lvbmVzIHkgZWZlY3RvcyBwcmluY2lwYWxlcyoqOiBFZmVjdG8gY29tYmluYWRvIG5vIGFkaXRpdm8KICAgIGVudHJlIGZhY3RvcmVzLgotICAgKipEaXNlw7FvcyBmYWN0b3JpYWxlcyoqOiBUb2RvcyBsb3Mgbml2ZWxlcyBkZSBjYWRhIGZhY3RvciBzZQogICAgY29tYmluYW4uCgojIyMgNC4zIEFOT1ZBIG11bHRpZmFjdG9yaWFsIHkgbW9kZWxvcyBtaXh0b3MKCi0gICAqKkRpc2XDsW9zIGFuaWRhZG9zIHkgZGUgbWVkaWRhcyByZXBldGlkYXMqKjogRXN0cnVjdHVyYXMgZGUgZGF0b3MKICAgIGRlcGVuZGllbnRlcy4KLSAgICoqU3VwdWVzdG9zIHkgdmVyaWZpY2FjaW9uZXMqKjogRXNmZXJpY2lkYWQgKE1hdWNobHnigJlzIHRlc3QpLAogICAgY29ycmVsYWNpw7NuIGludHJhLXN1amV0by4KCiMjIDUuIFJlZ3Jlc2nDs24geSBNb2RlbG9zIExpbmVhbGVzCgojIyMgNS4xIFJlZ3Jlc2nDs24gbGluZWFsIHNpbXBsZQoKLSAgICoqTW9kZWxvIHkgc3VwdWVzdG9zKio6ICRZID0gXGJldGFfMCArIFxiZXRhXzEgWCArIFxlcHNpbG9uJDsKICAgIGxpbmVhbGlkYWQsIGluZGVwZW5kZW5jaWEsIGhvbW9jZWRhc3RpY2lkYWQsIG5vcm1hbGlkYWQuCi0gICAqKkVzdGltYWNpw7NuIHBvciBtw61uaW1vcyBjdWFkcmFkb3MqKjogTWluaW1pemEgbGEgc3VtYSBkZSBlcnJvcmVzIGFsCiAgICBjdWFkcmFkby4KLSAgICoqSW5mZXJlbmNpYSBzb2JyZSBwYXLDoW1ldHJvcyoqOiBQcnVlYmFzIHQgcGFyYSAkXGJldGFfMCQgeQogICAgJFxiZXRhXzEkLgoKIyMjIDUuMiBSZWdyZXNpw7NuIGxpbmVhbCBtw7psdGlwbGUKCi0gICAqKlNlbGVjY2nDs24gZGUgdmFyaWFibGVzKio6IE3DqXRvZG9zIGZvcndhcmQsIGJhY2t3YXJkLCBzdGVwd2lzZS4KLSAgICoqTXVsdGljb2xpbmVhbGlkYWQgeSBkaWFnbsOzc3RpY28qKjogVklGIFw+IDEwIGluZGljYSBwcm9ibGVtYTsKICAgIHJlc2lkdWFsZXMsIGluZmx1ZW5jaWEgKENvb2vigJlzIEQpLgotICAgKipJbnRlcnByZXRhY2nDs24gZGUgY29lZmljaWVudGVzKio6IEVmZWN0byBwYXJjaWFsIGFqdXN0YWRvIHBvcgogICAgb3RyYXMgdmFyaWFibGVzLgoKIyMjIDUuMyBNb2RlbG9zIGxpbmVhbGVzIGdlbmVyYWxpemFkb3MgKEdMTSkKCi0gICAqKlJlZ3Jlc2nDs24gbG9nw61zdGljYSB5IFBvaXNzb24qKjogUGFyYSB2YXJpYWJsZXMgYmluYXJpYXMgKGxvZ2l0bykKICAgIHkgZGUgY29udGVvIChsb2cgbGluaykuCi0gICAqKk1vZGVsb3MgcGFyYSBkYXRvcyBjYXRlZ8Ozcmljb3MgeSBkZSBjb250ZW8qKjogRmFtaWxpYSBiaW5vbWlhbCwKICAgIFBvaXNzb24sIGVubGFjZSBsb2dpdG8sIGxvZy4KCiMjIDYuIE3DqXRvZG9zIE11bHRpdmFyaWFkb3MKCiMjIyA2LjEgQW7DoWxpc2lzIGRlIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzIChQQ0EpCgotICAgKipSZWR1Y2Npw7NuIGRlIGRpbWVuc2lvbmFsaWRhZCoqOiBUcmFuc2Zvcm1hIHZhcmlhYmxlcwogICAgY29ycmVsYWNpb25hZGFzIGVuIGNvbXBvbmVudGVzIG5vIGNvcnJlbGFjaW9uYWRvcy4KLSAgICoqSW50ZXJwcmV0YWNpw7NuIGRlIGNvbXBvbmVudGVzKio6IENhcmdhcywgdmFyaWFuemEgZXhwbGljYWRhCiAgICBhY3VtdWxhZGEuCgojIyMgNi4yIEFuw6FsaXNpcyBmYWN0b3JpYWwKCi0gICAqKk1vZGVsb3MgZXhwbG9yYXRvcmlvcyB5IGNvbmZpcm1hdG9yaW9zKio6IEVGQSBwYXJhIGRlc2N1YnJpcgogICAgZXN0cnVjdHVyYTsgQ0ZBIHBhcmEgdmFsaWRhciB0ZW9yw61hLgotICAgKipSb3RhY2nDs24gZGUgZmFjdG9yZXMqKjogVmFyaW1heCAob3J0b2dvbmFsKSwgcHJvbWF4IChvYmxpY3VhKS4KCiMjIyA2LjMgQW7DoWxpc2lzIGRpc2NyaW1pbmFudGUgeSBjbMO6c3RlcgoKLSAgICoqQ2xhc2lmaWNhY2nDs24gc3VwZXJ2aXNhZGEgeSBubyBzdXBlcnZpc2FkYSoqOiBMREEgKGxpbmVhbCksIFFEQQogICAgKGN1YWRyw6F0aWNvKSwgSy1tZWFucywgamVyw6FycXVpY28uCi0gICAqKkV2YWx1YWNpw7NuIGRlIHJlc3VsdGFkb3MqKjogU2lsaG91ZXR0ZSwgbWF0cml6IGRlIGNvbmZ1c2nDs24sIEFVQy4KCiMjIDcuIEluZmVyZW5jaWEgQmF5ZXNpYW5hCgojIyMgNy4xIEZ1bmRhbWVudG9zCgotICAgKipUZW9yZW1hIGRlIEJheWVzIHkgcHJvYmFiaWxpZGFkIGEgcG9zdGVyaW9yaSoqOgogICAgJFAoXHRoZXRhfEQpIFxwcm9wdG8gUChEfFx0aGV0YSkgUChcdGhldGEpJC4KLSAgICoqUHJpb3JzKio6IEluZm9ybWF0aXZvcyAoYmFzYWRvcyBlbiBjb25vY2ltaWVudG8gcHJldmlvKSwgbm8KICAgIGluZm9ybWF0aXZvcyAodW5pZm9ybWVzLCBKZWZmcmV5cykuCgojIyMgNy4yIE3DqXRvZG9zIGJheWVzaWFub3MKCi0gICAqKkVzdGltYWNpw7NuIGJheWVzaWFuYSBkZSBwYXLDoW1ldHJvcyoqOiBEaXN0cmlidWNpw7NuIGEgcG9zdGVyaW9yaSBlbgogICAgbHVnYXIgZGUgcHVudG8gZXN0aW1hZG8uCi0gICAqKkludGVydmFsb3MgZGUgY3JlZGliaWxpZGFkKio6ICJIYXkgOTUlIGRlIHByb2JhYmlsaWRhZCBkZSBxdWUgZWwKICAgIHBhcsOhbWV0cm8gZXN0w6kgYXF1w60iLgoKIyMjIDcuMyBBcGxpY2FjaW9uZXMgcHLDoWN0aWNhcwoKLSAgICoqTW9kZWxvcyBqZXLDoXJxdWljb3MqKjogRXN0cnVjdHVyYXMgYW5pZGFkYXMgKGVqLiBwYWNpZW50ZXMg4oaSCiAgICBob3NwaXRhbGVzKS4KLSAgICoqTUNNQyAoTW9udGUgQ2FybG8gcG9yIENhZGVuYXMgZGUgTWFya292KSoqOiBBbGdvcml0bW9zIGNvbW8KICAgIE1ldHJvcG9saXMtSGFzdGluZ3MsIEdpYmJzIHNhbXBsaW5nLgoKIyMgOC4gRGlzZcOxbyBkZSBFeHBlcmltZW50b3MKCiMjIyA4LjEgUHJpbmNpcGlvcyBiw6FzaWNvcwoKLSAgICoqQWxlYXRvcml6YWNpw7NuLCByZXBsaWNhY2nDs24geSBibG9xdWVvKio6IENvbnRyb2wgZGUgc2VzZ29zLAogICAgcHJlY2lzacOzbiwgdmFyaWFiaWxpZGFkLgotICAgKipEaXNlw7FvcyBjb21wbGV0YW1lbnRlIGFsZWF0b3JpemFkb3MqKjogQXNpZ25hY2nDs24gYWxlYXRvcmlhIGRlCiAgICB0cmF0YW1pZW50b3MuCgojIyMgOC4yIERpc2XDsW9zIGF2YW56YWRvcwoKLSAgICoqRGlzZcOxb3MgZGUgYmxvcXVlcyBpbmNvbXBsZXRvcyoqOiBDdWFuZG8gbm8gc2UgcHVlZGVuIHByb2JhciB0b2RvcwogICAgbG9zIHRyYXRhbWllbnRvcyBwb3IgYmxvcXVlLgotICAgKipEaXNlw7FvcyBmYWN0b3JpYWxlcyBmcmFjY2lvbmFkb3MqKjogRXN0dWRpYSBtdWNob3MgZmFjdG9yZXMgY29uCiAgICBtZW5vcyBjb3JyaWRhcy4KCiMjIyA4LjMgQW7DoWxpc2lzIGRlIGV4cGVyaW1lbnRvcwoKLSAgICoqSW50ZXJwcmV0YWNpw7NuIGRlIGludGVyYWNjaW9uZXMqKjogRWZlY3RvcyBjb21iaW5hZG9zIG5vIGFkaXRpdm9zLgotICAgKipBbsOhbGlzaXMgZGUgY292YXJpYW56YSAoQU5DT1ZBKSoqOiBBanVzdGEgcG9yIGNvdmFyaWFibGVzCiAgICBjb250aW51YXMuCgojIyA5LiBBbsOhbGlzaXMgZGUgU2VyaWVzIFRlbXBvcmFsZXMKCiMjIyA5LjEgQ29tcG9uZW50ZXMgZGUgc2VyaWVzIHRlbXBvcmFsZXMKCi0gICAqKlRlbmRlbmNpYSwgZXN0YWNpb25hbGlkYWQgeSBydWlkbyoqOiBEZXNjb21wb3NpY2nDs24gYWRpdGl2YSBvCiAgICBtdWx0aXBsaWNhdGl2YS4KLSAgICoqRGVzY29tcG9zaWNpw7NuIGRlIHNlcmllcyoqOiBTVEwgKFNlYXNvbmFsIGFuZCBUcmVuZCBkZWNvbXBvc2l0aW9uCiAgICB1c2luZyBMb2VzcykuCgojIyMgOS4yIE1vZGVsb3MgQVJJTUEKCi0gICAqKklkZW50aWZpY2FjacOzbiwgZXN0aW1hY2nDs24geSBkaWFnbsOzc3RpY28qKjogQUNGLCBQQUNGOwogICAgQm94LUplbmtpbnMuCi0gICAqKlByZWRpY2Npw7NuIHkgdmFsaWRhY2nDs24qKjogQmFja3Rlc3RpbmcsIGludGVydmFsb3MgZGUgcHJlZGljY2nDs24uCgojIyMgOS4zIE1vZGVsb3MgYXZhbnphZG9zCgotICAgKipNb2RlbG9zIEdBUkNIIHBhcmEgdm9sYXRpbGlkYWQqKjogTW9kZWxhbiB2YXJpYW56YSBjYW1iaWFudGUgZW4gZWwKICAgIHRpZW1wbyAoZmluYW56YXMpLgotICAgKipTZXJpZXMgdGVtcG9yYWxlcyBubyBlc3RhY2lvbmFyaWFzKio6IFBydWViYXMgZGUgcmHDrXogdW5pdGFyaWEKICAgIChBREYpLCBkaWZlcmVuY2lhY2nDs24uCgojIyAxMC4gSGVycmFtaWVudGFzIENvbXB1dGFjaW9uYWxlcwoKIyMjIDEwLjEgU29mdHdhcmUgZXN0YWTDrXN0aWNvCgotICAgKipSIHkgUHl0aG9uIHBhcmEgYW7DoWxpc2lzIGluZmVyZW5jaWFsKio6IEVudG9ybm9zIG3DoXMgdXNhZG9zIGVuCiAgICBjaWVuY2lhIGRlIGRhdG9zLgotICAgKipQYXF1ZXRlcyByZWxldmFudGVzKio6IGBzdGF0c2AsIGBsbWU0YCwgYGJybXNgIChSKTsgYHN0YXRzbW9kZWxzYCwKICAgIGBzY2lweWAsIGBza2xlYXJuYCAoUHl0aG9uKS4KCiMjIyAxMC4yIFNpbXVsYWNpw7NuIHkgYm9vdHN0cmFwCgotICAgKipNw6l0b2RvcyBkZSByZW11ZXN0cmVvKio6IEJvb3RzdHJhcCBwYXJhIGVzdGltYXIgZXJyb3JlcyBlc3TDoW5kYXIKICAgIHNpbiBzdXB1ZXN0b3MuCi0gICAqKkFwbGljYWNpb25lcyoqOiBJbnRlcnZhbG9zIGRlIGNvbmZpYW56YSBubyBwYXJhbcOpdHJpY29zLCBwcnVlYmFzCiAgICBkZSBwZXJtdXRhY2nDs24uCgojIyMgMTAuMyBWaXN1YWxpemFjacOzbiBkZSBkYXRvcwoKLSAgICoqR3LDoWZpY29zIHBhcmEgaW5mZXJlbmNpYSoqOiBCb3hwbG90cyAob3V0bGllcnMpLCBRLVEgcGxvdHMKICAgIChub3JtYWxpZGFkKSwgaGlzdG9ncmFtYXMsIHJlc2lkdWFsZXMuCi0gICAqKkhlcnJhbWllbnRhcyoqOiBgZ2dwbG90MmAsIGBwYXRjaHdvcmtgLCBgcGxvdGx5YCAoUik7IGBzZWFib3JuYCwKICAgIGBtYXRwbG90bGliYCAoUHl0aG9uKS4KCiMjIDExLiBBcGxpY2FjaW9uZXMgcHLDoWN0aWNhcyB5IGVzdHVkaW9zIGRlIGNhc28KCiMjIyAxMS4xIEFuw6FsaXNpcyBkZSBkYXRvcyByZWFsZXMKCi0gICAqKkVzdHVkaW9zIGRlIGNhc28qKjogQXBsaWNhY2lvbmVzIGVuIHNhbHVkLCBlY29ub23DrWEsIGJpb2xvZ8OtYSwKICAgIGNpZW5jaWFzIHNvY2lhbGVzLgotICAgKipJbnRlcnByZXRhY2nDs24gZGUgcmVzdWx0YWRvcyBlbiBjb250ZXh0byoqOiBNw6FzIGFsbMOhIGRlbCBwLXZhbG9yOgogICAgbWFnbml0dWQsIHJlbGV2YW5jaWEgcHLDoWN0aWNhLgoKIyMjIDExLjIgVmFsaWRhY2nDs24gZGUgc3VwdWVzdG9zCgotICAgKipEaWFnbsOzc3RpY29zKio6IE5vcm1hbGlkYWQgKFNoYXBpcm8tV2lsayksIGhvbW9jZWRhc3RpY2lkYWQKICAgIChCcmV1c2NoLVBhZ2FuKSwgaW5kZXBlbmRlbmNpYSAoRHVyYmluLVdhdHNvbikuCi0gICAqKlRyYW5zZm9ybWFjaW9uZXMgZGUgZGF0b3MqKjogTG9nLCByYcOteiBjdWFkcmFkYSwgQm94LUNveCBwYXJhCiAgICBjdW1wbGlyIHN1cHVlc3Rvcy4KCiMjIyAxMS4zIFJlZGFjY2nDs24gZGUgaW5mb3JtZXMKCi0gICAqKkVzdHJ1Y3R1cmEgZGUgdW4gaW5mb3JtZSBlc3RhZMOtc3RpY28qKjogSW50cm9kdWNjacOzbiwgbcOpdG9kb3MsCiAgICByZXN1bHRhZG9zLCBkaXNjdXNpw7NuLCBjb25jbHVzaW9uZXMuCgotICAgKipDb211bmljYWNpw7NuIGRlIHJlc3VsdGFkb3MgaW5mZXJlbmNpYWxlcyoqOiBDbGFyaWRhZCwgcHJlY2lzacOzbiwKICAgIGV2aXRhbmRvIG1hbGFzIGludGVycHJldGFjaW9uZXMuCgojIDEuIEZ1bmRhbWVudG9zIGRlIEVzdGFkw61zdGljYSBJbmZlcmVuY2lhbCBwYXJhIGVsIFNlY3RvciBTYWx1ZAoKRXN0ZSB0ZW1hcmlvIGRlc2Fycm9sbGEgbG9zIGZ1bmRhbWVudG9zIGRlIGVzdGFkw61zdGljYSBpbmZlcmVuY2lhbCBjb24KdW4gZW5mb3F1ZSBlbiBhcGxpY2FjaW9uZXMgcHLDoWN0aWNhcyBlbiBlbCBzZWN0b3Igc2FsdWQsIHByb3BvcmNpb25hbmRvCmV4cGxpY2FjaW9uZXMgZGV0YWxsYWRhcyB5IGVqZW1wbG9zIGVzcGVjw61maWNvcyBwYXJhIHByb2Zlc2lvbmFsZXMKbcOpZGljb3MsIGludmVzdGlnYWRvcmVzIGNsw61uaWNvcyB5IGVwaWRlbWnDs2xvZ29zLiBMYSBpbmZlcmVuY2lhCmVzdGFkw61zdGljYSBwZXJtaXRlIHRvbWFyIGRlY2lzaW9uZXMgYmFzYWRhcyBlbiBkYXRvcyBtdWVzdHJhbGVzLAplc2VuY2lhbGVzIHBhcmEgZXZhbHVhciB0cmF0YW1pZW50b3MsIGFuYWxpemFyIHByZXZhbGVuY2lhcyBkZQplbmZlcm1lZGFkZXMgeSBkaXNlw7FhciBlc3R1ZGlvcyBjbMOtbmljb3MuCgojIyAxLjEgQ29uY2VwdG9zIGLDoXNpY29zCgojIyMgRGVmaW5pY2nDs24gZGUgSW5mZXJlbmNpYSBFc3RhZMOtc3RpY2EKCkxhIGluZmVyZW5jaWEgZXN0YWTDrXN0aWNhIGVzIGVsIHByb2Nlc28gZGUgdXNhciBkYXRvcyBkZSB1bmEgbXVlc3RyYQpwYXJhIGhhY2VyIGdlbmVyYWxpemFjaW9uZXMgbyBwcmVkaWNjaW9uZXMgc29icmUgdW5hIHBvYmxhY2nDs24gbcOhcwpncmFuZGUsIG1hbmVqYW5kbyBsYSBpbmNlcnRpZHVtYnJlIGluaGVyZW50ZSBhIGxvcyBkYXRvcy4gRW4gc2FsdWQsIGVzdG8Kc2lnbmlmaWNhIGV4dHJhZXIgY29uY2x1c2lvbmVzIHNvYnJlIHVuYSBwb2JsYWNpw7NuIChlLmcuLCBwYWNpZW50ZXMgY29uCmRpYWJldGVzIGVuIHVuIHBhw61zKSBiYXPDoW5kb3NlIGVuIHVuYSBtdWVzdHJhIChlLmcuLCBwYWNpZW50ZXMgZGUgdW4KaG9zcGl0YWwpLiBQb3IgZWplbXBsbywgdW4gZXN0dWRpbyBwdWVkZSBlc3RpbWFyIGxhIGVmZWN0aXZpZGFkIHByb21lZGlvCmRlIHVuYSB2YWN1bmEgYSBwYXJ0aXIgZGUgdW4gZW5zYXlvIGNsw61uaWNvIG8gZGV0ZXJtaW5hciBzaSB1biBudWV2bwptZWRpY2FtZW50byByZWR1Y2Ugc2lnbmlmaWNhdGl2YW1lbnRlIGxhIHByZXNpw7NuIGFydGVyaWFsLgoKKipJbXBvcnRhbmNpYSBlbiBzYWx1ZDoqKgoKLSAgIFBlcm1pdGUgZXZhbHVhciBsYSBlZmljYWNpYSBkZSB0cmF0YW1pZW50b3Mgc2luIGVzdHVkaWFyIGEgdG9kYSBsYQogICAgcG9ibGFjacOzbi4KLSAgIEF5dWRhIGEgaWRlbnRpZmljYXIgZmFjdG9yZXMgZGUgcmllc2dvIChlLmcuLCByZWxhY2nDs24gZW50cmUKICAgIHRhYmFxdWlzbW8geSBjw6FuY2VyIGRlIHB1bG3Ds24pLgotICAgRnVuZGFtZW50YSBkZWNpc2lvbmVzIGNsw61uaWNhcyB5IHBvbMOtdGljYXMgZGUgc2FsdWQgcMO6YmxpY2EgY29uCiAgICBldmlkZW5jaWEgZXN0YWTDrXN0aWNhLgoKKipFamVtcGxvIHByw6FjdGljbzoqKiBVbiBlbnNheW8gY2zDrW5pY28gY29uIDUwMCBwYWNpZW50ZXMgcHJ1ZWJhIHVuCm51ZXZvIGbDoXJtYWNvIHBhcmEgbGEgaGlwZXJ0ZW5zacOzbi4gTGEgaW5mZXJlbmNpYSBlc3RhZMOtc3RpY2EgcGVybWl0ZQplc3RpbWFyIHNpIGVsIGbDoXJtYWNvIHJlZHVjZSBsYSBwcmVzacOzbiBhcnRlcmlhbCBlbiBsYSBwb2JsYWNpw7NuIGdlbmVyYWwKZGUgaGlwZXJ0ZW5zb3MgeSBzaSBsb3MgcmVzdWx0YWRvcyBzb24gZXN0YWTDrXN0aWNhbWVudGUgc2lnbmlmaWNhdGl2b3MuCgojIyMgUG9ibGFjacOzbiwgbXVlc3RyYSB5IHBhcsOhbWV0cm9zCgoqKlBvYmxhY2nDs246KiogQ29uanVudG8gdG90YWwgZGUgaW5kaXZpZHVvcyB1IG9iamV0b3MgZGUgaW50ZXLDqXMuIEVuCnNhbHVkLCBwb2Ryw61hIHNlciB0b2RvcyBsb3MgcGFjaWVudGVzIGNvbiB1bmEgZW5mZXJtZWRhZCBlc3BlY8OtZmljYQooZS5nLiwgdG9kb3MgbG9zIGRpYWLDqXRpY29zIHRpcG8gMiBlbiB1biBwYcOtcykuCgoqKlBhcsOhbWV0cm86KiogQ2FyYWN0ZXLDrXN0aWNhIG51bcOpcmljYSBkZSBsYSBwb2JsYWNpw7NuLCBjb21vIGxhCnByZXZhbGVuY2lhIGRlIHVuYSBlbmZlcm1lZGFkIChwcm9wb3JjacOzbiAkcCQpLCBsYSBtZWRpYSBkZSBnbHVjb3NhIGVuCnNhbmdyZSAoJFxtdSQpLCBvIGxhIHZhcmlhbnphIGRlIGxhIHByZXNpw7NuIGFydGVyaWFsICgkXHNpZ21hXjIkKS4KCioqTXVlc3RyYToqKiBTdWJncnVwbyBzZWxlY2Npb25hZG8gZGUgbGEgcG9ibGFjacOzbiBwYXJhIGVzdHVkaW8uIERlYmUKc2VyIHJlcHJlc2VudGF0aXZhIHBhcmEgZXZpdGFyIHNlc2dvcy4gUG9yIGVqZW1wbG8sIHVuYSBtdWVzdHJhIGRlIDEwMDAKcGFjaWVudGVzIGRlIGNsw61uaWNhcyB1cmJhbmFzIHkgcnVyYWxlcyBwYXJhIGVzdHVkaWFyIGhpcGVydGVuc2nDs24uCgoqKkVzdGFkw61zdGljbzoqKiBNZWRpZGEgY2FsY3VsYWRhIGEgcGFydGlyIGRlIGxhIG11ZXN0cmEsIGNvbW8gbGEgbWVkaWEKbXVlc3RyYWwgKCRcYmFye3h9JCkgbyBsYSBwcm9wb3JjacOzbiBtdWVzdHJhbCAoJFxoYXR7cH0kKS4KCioqTXVlc3RyZW8gZW4gc2FsdWQ6KioKCi0gICAqKkFsZWF0b3JpbyBzaW1wbGU6KiogQ2FkYSBwYWNpZW50ZSB0aWVuZSBsYSBtaXNtYSBwcm9iYWJpbGlkYWQgZGUKICAgIHNlciBzZWxlY2Npb25hZG8gKGUuZy4sIHNlbGVjY2lvbmFyIHBhY2llbnRlcyBhbCBhemFyIGRlIHVuIHJlZ2lzdHJvCiAgICBob3NwaXRhbGFyaW8pLgotICAgKipFc3RyYXRpZmljYWRvOioqIERpdmlkZSBsYSBwb2JsYWNpw7NuIGVuIGdydXBvcyAoZS5nLiwgcG9yIGVkYWQgbwogICAgZ8OpbmVybykgeSB0b21hIG11ZXN0cmFzIGRlIGNhZGEgdW5vIHBhcmEgZ2FyYW50aXphcgogICAgcmVwcmVzZW50YXRpdmlkYWQuCi0gICAqKlNlc2dvcyBjb211bmVzOioqIE11ZXN0cmFzIG5vIHJlcHJlc2VudGF0aXZhcyAoZS5nLiwgc29sbwogICAgcGFjaWVudGVzIGRlIHVuIGhvc3BpdGFsIGRlIMOpbGl0ZSkgcHVlZGVuIGxsZXZhciBhIGNvbmNsdXNpb25lcwogICAgZXJyw7NuZWFzLgoKKipFamVtcGxvIHByw6FjdGljbzoqKiBQYXJhIGVzdGltYXIgbGEgcHJldmFsZW5jaWEgZGUgb2Jlc2lkYWQgZW4KYWR1bHRvcywgc2Ugc2VsZWNjaW9uYSB1bmEgbXVlc3RyYSBhbGVhdG9yaWEgZGUgMjAwMCBwZXJzb25hcy4gTGEKcHJvcG9yY2nDs24gbXVlc3RyYWwgZGUgb2Jlc29zICgkXGhhdHtwfSA9IDAuMjUkKSBlc3RpbWEgbGEgcHJldmFsZW5jaWEKcG9ibGFjaW9uYWwgKCRwJCkuCgojIyMgVGlwb3MgZGUgRGF0b3MgeSBFc2NhbGFzIGRlIE1lZGljacOzbgoKKipUaXBvcyBkZSBkYXRvcyBlbiBzYWx1ZDoqKgoKLSAgICoqQ3VhbnRpdGF0aXZvczoqKgogICAgLSAgICoqRGlzY3JldG9zOioqIFZhbG9yZXMgY29udGFibGVzLCBjb21vIGVsIG7Dum1lcm8gZGUKICAgICAgICBob3NwaXRhbGl6YWNpb25lcyBwb3IgYcOxbyBvIGVsIG7Dum1lcm8gZGUgY2Fzb3MgZGUgQ09WSUQtMTkgZW4gdW4KICAgICAgICBtZXMuCiAgICAtICAgKipDb250aW51b3M6KiogVmFsb3JlcyBlbiB1biByYW5nbyBjb250aW51bywgY29tbyBlbCBuaXZlbCBkZQogICAgICAgIGdsdWNvc2EgZW4gc2FuZ3JlIChtZy9kTCkgbyBlbCDDrW5kaWNlIGRlIG1hc2EgY29ycG9yYWwgKElNQykuCi0gICAqKkN1YWxpdGF0aXZvczoqKgogICAgLSAgICoqTm9taW5hbGVzOioqIENhdGVnb3LDrWFzIHNpbiBvcmRlbiwgY29tbyBlbCB0aXBvIGRlIHNhbmdyZSAoQSwKICAgICAgICBCLCBBQiwgTykgbyBlbCBkaWFnbsOzc3RpY28gKGJlbmlnbm8sIG1hbGlnbm8pLgogICAgLSAgICoqT3JkaW5hbGVzOioqIENhdGVnb3LDrWFzIGNvbiBvcmRlbiwgY29tbyBlbCBlc3RhZGlvIGRlbCBjw6FuY2VyCiAgICAgICAgKEksIElJLCBJSUksIElWKSBvIGxhIGdyYXZlZGFkIGRlIHVuYSBlbmZlcm1lZGFkIChsZXZlLAogICAgICAgIG1vZGVyYWRhLCBzZXZlcmEpLgoKKipFc2NhbGFzIGRlIG1lZGljacOzbjoqKgoKLSAgICoqTm9taW5hbDoqKiBVc2FkYSBwYXJhIGNsYXNpZmljYWNpb25lcyBzaW4gb3JkZW4gaW5oZXJlbnRlIChlLmcuLAogICAgZ3J1cG9zIHNhbmd1w61uZW9zKS4KLSAgICoqT3JkaW5hbDoqKiBQYXJhIGRhdG9zIGNvbiBvcmRlbiBwZXJvIHNpbiBkaXN0YW5jaWFzIHVuaWZvcm1lcwogICAgKGUuZy4sIGVzY2FsYSBkZSBkb2xvciBkZSAxIGEgMTAsIGRvbmRlIGxhIGRpZmVyZW5jaWEgZW50cmUgMiB5IDMgbm8KICAgIGVzIG5lY2VzYXJpYW1lbnRlIGlndWFsIGEgbGEgZW50cmUgOCB5IDkpLgotICAgKipJbnRlcnZhbG86KiogRGlzdGFuY2lhcyBpZ3VhbGVzLCBzaW4gY2VybyBhYnNvbHV0byAoZS5nLiwKICAgIHRlbXBlcmF0dXJhIGNvcnBvcmFsIGVuIMKwQzsgMMKwQyBubyBpbmRpY2EgYXVzZW5jaWEgZGUgdGVtcGVyYXR1cmEpLgotICAgKipSYXrDs246KiogRGlzdGFuY2lhcyBpZ3VhbGVzIGNvbiBjZXJvIGFic29sdXRvIChlLmcuLCBwZXNvLAogICAgZnJlY3VlbmNpYSBjYXJkw61hY2E7IDAga2cgaW5kaWNhIGF1c2VuY2lhIGRlIHBlc28pLgoKKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBMYSBlbGVjY2nDs24gZGUgbGEgZXNjYWxhIGFmZWN0YSBlbCBhbsOhbGlzaXMuClBvciBlamVtcGxvLCBjb21wYXJhciBwcm9tZWRpb3MgZGUgZ2x1Y29zYSAocmF6w7NuKSByZXF1aWVyZSBwcnVlYmFzCnBhcmFtw6l0cmljYXMsIG1pZW50cmFzIHF1ZSBjbGFzaWZpY2FyIHBhY2llbnRlcyBwb3IgZXN0YWRpbyBkZQplbmZlcm1lZGFkIChvcmRpbmFsKSBwdWVkZSBuZWNlc2l0YXIgcHJ1ZWJhcyBubyBwYXJhbcOpdHJpY2FzLgoKKipFamVtcGxvIHByw6FjdGljbzoqKiBFbiB1biBlc3R1ZGlvIHNvYnJlIGRpYWJldGVzLCBsb3Mgbml2ZWxlcyBkZSBIYkExYwoocmF6w7NuKSBzZSBhbmFsaXphbiBwYXJhIGNhbGN1bGFyIG1lZGlhcywgbWllbnRyYXMgcXVlIGxhIGNhdGVnb3LDrWEgZGUKY29udHJvbCBnbHVjw6ltaWNvIChjb250cm9sYWRvLCBubyBjb250cm9sYWRvKSBlcyBub21pbmFsLgoKIyMgMS4yIFByb2JhYmlsaWRhZCBBdmFuemFkYQoKIyMjIEVzcGFjaW9zIE11ZXN0cmFsZXMgeSBFdmVudG9zCgoqKkVzcGFjaW8gbXVlc3RyYWwgKFMpOioqIENvbmp1bnRvIGRlIHRvZG9zIGxvcyByZXN1bHRhZG9zIHBvc2libGVzIGRlCnVuIGV4cGVyaW1lbnRvLiBFbiBzYWx1ZCwgcG9kcsOtYSBzZXIgbG9zIHJlc3VsdGFkb3MgZGUgdW4gdGVzdApkaWFnbsOzc3RpY28gKHBvc2l0aXZvLCBuZWdhdGl2bykgbyBsb3MgcG9zaWJsZXMgZGVzZW5sYWNlcyBkZSB1bgp0cmF0YW1pZW50byAobWVqb3LDrWEsIHNpbiBjYW1iaW8sIGVtcGVvcmFtaWVudG8pLgoKKipFdmVudG86KiogU3ViY29uanVudG8gZGVsIGVzcGFjaW8gbXVlc3RyYWwuIFBvciBlamVtcGxvLCBlbiB1biB0ZXN0IGRlCkNPVklELTE5LCB1biBldmVudG8gcG9kcsOtYSBzZXIgInJlc3VsdGFkbyBwb3NpdGl2byIgbyAicGFjaWVudGUgY29uCmZpZWJyZSB5IHJlc3VsdGFkbyBwb3NpdGl2byIuCgotICAgKipFdmVudG9zIHNpbXBsZXM6KiogVW4gc29sbyByZXN1bHRhZG8gKGUuZy4sIHVuIHBhY2llbnRlIHRpZW5lIHVuCiAgICB0ZXN0IHBvc2l0aXZvKS4KLSAgICoqRXZlbnRvcyBjb21wdWVzdG9zOioqIENvbWJpbmFjacOzbiBkZSByZXN1bHRhZG9zIChlLmcuLCBwYWNpZW50ZQogICAgY29uIGZpZWJyZSBvIHRvcykuCgoqKk9wZXJhY2lvbmVzOioqCgotICAgKipVbmnDs246KiogUHJvYmFiaWxpZGFkIGRlIHF1ZSBvY3VycmEgYWwgbWVub3MgdW4gZXZlbnRvIChlLmcuLAogICAgZmllYnJlIG8gdG9zKS4KLSAgICoqSW50ZXJzZWNjacOzbjoqKiBQcm9iYWJpbGlkYWQgZGUgcXVlIG9jdXJyYW4gYW1ib3MgZXZlbnRvcyAoZS5nLiwKICAgIGZpZWJyZSB5IHRvcykuCi0gICAqKkNvbXBsZW1lbnRvOioqIFByb2JhYmlsaWRhZCBkZSBxdWUgbm8gb2N1cnJhIHVuIGV2ZW50byAoZS5nLiwgbm8KICAgIHRlbmVyIGZpZWJyZSkuCgoqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuIGVzdHVkaW8gZGUgZGV0ZWNjacOzbiBkZSBjw6FuY2VyLCBlbCBlc3BhY2lvCm11ZXN0cmFsIGluY2x1eWUgdG9kb3MgbG9zIHJlc3VsdGFkb3MgZGUgdW5hIG1hbW9ncmFmw61hIChub3JtYWwsCmFub3JtYWwpLiBVbiBldmVudG8gY29tcHVlc3RvIHBvZHLDrWEgc2VyICJtYW1vZ3JhZsOtYSBhbm9ybWFsIHkKY29uZmlybWFjacOzbiBkZSBjw6FuY2VyIHBvciBiaW9wc2lhIi4KCiMjIyBSZWdsYXMgZGUgUHJvYmFiaWxpZGFkCgotICAgKipSZWdsYSBkZSBsYSBzdW1hOioqIFBhcmEgZXZlbnRvcyBtdXR1YW1lbnRlIGV4Y2x1eWVudGVzIChubyBwdWVkZW4KICAgIG9jdXJyaXIgc2ltdWx0w6FuZWFtZW50ZSksICRQKEEgXGN1cCBCKSA9IFAoQSkgKyBQKEIpJC4gRWplbXBsbzogTGEKICAgIHByb2JhYmlsaWRhZCBkZSBxdWUgdW4gcGFjaWVudGUgdGVuZ2EgZGlhYmV0ZXMgdGlwbyAxIG8gdGlwbyAyCiAgICAoZXhjbHV5ZW50ZXMpIGVzIGxhIHN1bWEgZGUgc3VzIHByb2JhYmlsaWRhZGVzIGluZGl2aWR1YWxlcy4KLSAgICoqUmVnbGEgZGVsIHByb2R1Y3RvOioqIFBhcmEgZXZlbnRvcyBpbmRlcGVuZGllbnRlcywKICAgICRQKEEgXGNhcCBCKSA9IFAoQSkgXGNkb3QgUChCKSQuIFNpIG5vIHNvbiBpbmRlcGVuZGllbnRlcywKICAgICRQKEEgXGNhcCBCKSA9IFAoQSkgXGNkb3QgUChCfEEpJC4gRWplbXBsbzogTGEgcHJvYmFiaWxpZGFkIGRlIHF1ZQogICAgdW4gcGFjaWVudGUgdGVuZ2EgaGlwZXJ0ZW5zacOzbiB5IGRpYWJldGVzIChubyBpbmRlcGVuZGllbnRlcykKICAgIHJlcXVpZXJlIGNvbnNpZGVyYXIgbGEgcHJvYmFiaWxpZGFkIGNvbmRpY2lvbmFsLgotICAgKipUZW9yZW1hIGRlIEJheWVzOioqIEFjdHVhbGl6YSBwcm9iYWJpbGlkYWRlcyBiYXNhZGFzIGVuIG51ZXZhCiAgICBldmlkZW5jaWE6ICQkCiAgICBQKEF8QikgPSBcZnJhY3tQKEJ8QSkgXGNkb3QgUChBKX17UChCKX0KICAgICQkCgoqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIERpYWduw7NzdGljb3MgbcOpZGljb3MuIFBvciBlamVtcGxvLCBwYXJhIHVuIHRlc3QKZGUgQ09WSUQtMTk6CgotICAgJFAoQSkkOiBQcm9iYWJpbGlkYWQgZGUgdGVuZXIgQ09WSUQtMTkgKHByZXZhbGVuY2lhKS4KLSAgICRQKEJ8QSkkOiBTZW5zaWJpbGlkYWQgZGVsIHRlc3QgKHByb2JhYmlsaWRhZCBkZSB1biByZXN1bHRhZG8KICAgIHBvc2l0aXZvIGRhZG8gcXVlIGVsIHBhY2llbnRlIHRpZW5lIENPVklELTE5KS4KLSAgICRQKEF8QikkOiBQcm9iYWJpbGlkYWQgZGUgdGVuZXIgQ09WSUQtMTkgZGFkbyB1biByZXN1bHRhZG8gcG9zaXRpdm8uCgoqKkVqZW1wbG8gcHLDoWN0aWNvOioqIFNpIGxhIHByZXZhbGVuY2lhIGRlIHVuYSBlbmZlcm1lZGFkIGVzIDElCigkUChBKSA9IDAuMDEkKSwgbGEgc2Vuc2liaWxpZGFkIGRlbCB0ZXN0IGVzIDk1JSAoJFAoQnxBKSA9IDAuOTUkKSwgeSBsYQplc3BlY2lmaWNpZGFkIGVzIDkwJSAoJFAoQl5jfEFeYykgPSAwLjkwJCksIGVsIHRlb3JlbWEgZGUgQmF5ZXMgY2FsY3VsYQpsYSBwcm9iYWJpbGlkYWQgZGUgdGVuZXIgbGEgZW5mZXJtZWRhZCBkYWRvIHVuIHJlc3VsdGFkbyBwb3NpdGl2by4KCiMjIyBWYXJpYWJsZXMgQWxlYXRvcmlhcyBEaXNjcmV0YXMgeSBDb250aW51YXMKCioqVmFyaWFibGUgYWxlYXRvcmlhOioqIEFzaWduYSB2YWxvcmVzIG51bcOpcmljb3MgYSByZXN1bHRhZG9zIGRlIHVuCmV4cGVyaW1lbnRvLgoKLSAgICoqRGlzY3JldGFzOioqIFZhbG9yZXMgY29udGFibGVzLCBjb21vIGVsIG7Dum1lcm8gZGUgY2Fzb3MgZGUKICAgIGluZmx1ZW56YSBlbiB1bmEgc2VtYW5hIG8gZWwgbsO6bWVybyBkZSBjb25zdWx0YXMgbcOpZGljYXMgcG9yCiAgICBwYWNpZW50ZS4KICAgIC0gICAqKkZ1bmNpw7NuIGRlIG1hc2EgZGUgcHJvYmFiaWxpZGFkIChQTUYpOioqICRQKFggPSB4KSQsIGluZGljYSBsYQogICAgICAgIHByb2JhYmlsaWRhZCBkZSB1biB2YWxvciBlc3BlY8OtZmljby4KLSAgICoqQ29udGludWFzOioqIFZhbG9yZXMgZW4gdW4gcmFuZ28gY29udGludW8sIGNvbW8gZWwgdGllbXBvIGhhc3RhIGxhCiAgICByZWN1cGVyYWNpw7NuIG8gZWwgbml2ZWwgZGUgY29sZXN0ZXJvbC4KICAgIC0gICAqKkZ1bmNpw7NuIGRlIGRlbnNpZGFkIGRlIHByb2JhYmlsaWRhZCAoUERGKToqKiAkZih4KSQsIGRvbmRlCiAgICAgICAgJFAoYSBcbGVxIFggXGxlcSBiKSA9IFxpbnRfYV5iIGYoeCkgXCwgZHgkLgoKKipNb21lbnRvczoqKgoKLSAgICoqRXNwZXJhbnphICgqKiRFKFgpJCk6IFZhbG9yIHByb21lZGlvIGVzcGVyYWRvLiBQYXJhIGRpc2NyZXRhczoKICAgICRcc3VtIHggXGNkb3QgUChYID0geCkkOyBwYXJhIGNvbnRpbnVhczogJFxpbnQgeCBcY2RvdCBmKHgpIFwsIGR4JC4KICAgIEVqZW1wbG86IE1lZGlhIGRlIGTDrWFzIGRlIGhvc3BpdGFsaXphY2nDs24uCi0gICAqKlZhcmlhbnphICgqKiRWYXIoWCkkKTogTWlkZSBsYSBkaXNwZXJzacOzbjogJEVbKFggLSBFKFgpKV4yXSQuCiAgICBFamVtcGxvOiBWYXJpYWJpbGlkYWQgZW4gbG9zIG5pdmVsZXMgZGUgZ2x1Y29zYSBlbnRyZSBwYWNpZW50ZXMuCgoqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuIGhvc3BpdGFsLCBlbCBuw7ptZXJvIGRlIGFkbWlzaW9uZXMgZGlhcmlhcwpwb3IgaW5mYXJ0byAoZGlzY3JldGEpIG8gZWwgdGllbXBvIGRlIGVzcGVyYSBlbiB1cmdlbmNpYXMgKGNvbnRpbnVhKSBzb24KdmFyaWFibGVzIGFsZWF0b3JpYXMgYW5hbGl6YWRhcyBwYXJhIG9wdGltaXphciByZWN1cnNvcy4KCiMjIDEuMyBEaXN0cmlidWNpb25lcyBkZSBQcm9iYWJpbGlkYWQKCiMjIyBEaXN0cmlidWNpb25lcyBEaXNjcmV0YXMKCioqQmlub21pYWw6KioKCi0gICBNb2RlbGEgZWwgbsO6bWVybyBkZSDDqXhpdG9zIGVuICRuJCBlbnNheW9zIGluZGVwZW5kaWVudGVzIGNvbgogICAgcHJvYmFiaWxpZGFkIGRlIMOpeGl0byAkcCQuCi0gICBQTUY6ICRQKFggPSBrKSA9IFxiaW5vbXtufXtrfSBwXmsgKDEtcClee24ta30kLgotICAgKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBOw7ptZXJvIGRlIHBhY2llbnRlcyBxdWUgcmVzcG9uZGVuIGEgdW4KICAgIHRyYXRhbWllbnRvIGVuIHVuIGVuc2F5byBjbMOtbmljbyBkZSAkbiQgcGFydGljaXBhbnRlcy4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogRW4gdW4gZW5zYXlvIGNvbiAxMDAgcGFjaWVudGVzLCBzaSBsYQogICAgcHJvYmFiaWxpZGFkIGRlIHJlc3B1ZXN0YSBhIHVuIGbDoXJtYWNvIGVzIDAuNywgbGEgcHJvYmFiaWxpZGFkIGRlCiAgICBxdWUgZXhhY3RhbWVudGUgNzAgcGFjaWVudGVzIHJlc3BvbmRhbiBlcwogICAgJFAoWCA9IDcwKSA9IFxiaW5vbXsxMDB9ezcwfSAoMC43KV57NzB9ICgwLjMpXnszMH0kLgotICAgTWVkaWE6ICRFKFgpID0gbnAkLCBWYXJpYW56YTogJFZhcihYKSA9IG5wKDEtcCkkLgoKKipQb2lzc29uOioqCgotICAgTW9kZWxhIGV2ZW50b3MgcmFyb3MgZW4gdW4gaW50ZXJ2YWxvIGZpam8gKHRpZW1wbywgZXNwYWNpbykgY29uIHRhc2EKICAgIHByb21lZGlvICRcbGFtYmRhJC4KLSAgIFBNRjogJFAoWCA9IGspID0gXGZyYWN7XGxhbWJkYV5rIGVeey1cbGFtYmRhfX17ayF9JC4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogTsO6bWVybyBkZSBjYXNvcyBkZSB1bmEgZW5mZXJtZWRhZCByYXJhIGVuCiAgICB1biBob3NwaXRhbCBwb3IgbWVzLgotICAgKipFamVtcGxvIHByw6FjdGljbzoqKiBTaSB1biBob3NwaXRhbCByZWdpc3RyYSBlbiBwcm9tZWRpbyAyIGNhc29zIGRlCiAgICBtZW5pbmdpdGlzIHBvciBtZXMgKCRcbGFtYmRhID0gMiQpLCBsYSBwcm9iYWJpbGlkYWQgZGUgb2JzZXJ2YXIgMwogICAgY2Fzb3MgZXMgJFAoWCA9IDMpID0gXGZyYWN7Ml4zIGVeey0yfX17MyF9JC4KLSAgIE1lZGlhIHkgVmFyaWFuemE6ICRFKFgpID0gXGxhbWJkYSQsICRWYXIoWCkgPSBcbGFtYmRhJC4KCioqR2VvbcOpdHJpY2E6KioKCi0gICBNb2RlbGEgZWwgbsO6bWVybyBkZSBlbnNheW9zIGhhc3RhIGVsIHByaW1lciDDqXhpdG8uCi0gICBQTUY6ICRQKFggPSBrKSA9ICgxLXApXntrLTF9IHAkLgotICAgKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBOw7ptZXJvIGRlIHBydWViYXMgZGlhZ27Ds3N0aWNhcyBoYXN0YQogICAgZGV0ZWN0YXIgdW4gY2FzbyBwb3NpdGl2by4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogU2kgbGEgcHJvYmFiaWxpZGFkIGRlIGRldGVjdGFyIHVuIGNhc28gZGUKICAgIHR1YmVyY3Vsb3NpcyBlbiB1bmEgcHJ1ZWJhIGVzIDAuMDUsIGxhIHByb2JhYmlsaWRhZCBkZSBlbmNvbnRyYXIgZWwKICAgIHByaW1lciBjYXNvIGVuIGxhIHRlcmNlcmEgcHJ1ZWJhIGVzCiAgICAkUChYID0gMykgPSAoMC45NSleMiBcY2RvdCAwLjA1JC4KLSAgIE1lZGlhOiAkRShYKSA9IFxmcmFjezF9e3B9JCwgVmFyaWFuemE6ICRWYXIoWCkgPSBcZnJhY3sxLXB9e3BeMn0kLgoKIyMjIERpc3RyaWJ1Y2lvbmVzIENvbnRpbnVhcwoKKipOb3JtYWw6KioKCi0gICBEaXN0cmlidWNpw7NuIHNpbcOpdHJpY2EgZW4gZm9ybWEgZGUgY2FtcGFuYSwgZGVmaW5pZGEgcG9yICRcbXUkCiAgICAobWVkaWEpIHkgJFxzaWdtYSQgKGRlc3ZpYWNpw7NuIGVzdMOhbmRhcikuCi0gICBQREY6CiAgICAkZih4KSA9IFxmcmFjezF9e1xzcXJ0ezJccGlcc2lnbWFeMn19IGVeey1cZnJhY3soeC1cbXUpXjJ9ezJcc2lnbWFeMn19JC4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogVmFyaWFibGVzIGJpb2zDs2dpY2FzIGNvbW8gcHJlc2nDs24gYXJ0ZXJpYWwsCiAgICBuaXZlbGVzIGRlIGNvbGVzdGVyb2wgbyBJTUMgc3VlbGVuIHNlZ3VpciB1bmEgZGlzdHJpYnVjacOzbiBub3JtYWwuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIFNpIGxhIHByZXNpw7NuIGFydGVyaWFsIHNpc3TDs2xpY2EgZW4gYWR1bHRvcwogICAgdGllbmUgJFxtdSA9IDEyMCQgbW1IZyB5ICRcc2lnbWEgPSAxNSQgbW1IZywgbGEgcHJvYmFiaWxpZGFkIGRlIHF1ZQogICAgdW4gcGFjaWVudGUgdGVuZ2EgdW5hIHByZXNpw7NuIGVudHJlIDExMCB5IDEzMCBtbUhnIHNlIGNhbGN1bGEKICAgIGludGVncmFuZG8gbGEgUERGIG5vcm1hbC4KLSAgICoqUHJvcGllZGFkZXM6KiogXH42OCUgZGUgbG9zIGRhdG9zIGVzdMOhbiBkZW50cm8gZGUKICAgICRcbXUgXHBtIFxzaWdtYSQsIFx+OTUlIGRlbnRybyBkZSAkXG11IFxwbSAyXHNpZ21hJC4KCioqdCBkZSBTdHVkZW50OioqCgotICAgVXNhZGEgcGFyYSBtdWVzdHJhcyBwZXF1ZcOxYXMgKCRuIDwgMzAkKSBjb24gdmFyaWFuemEgZGVzY29ub2NpZGEuCi0gICBEZXBlbmRlIGRlIGxvcyBncmFkb3MgZGUgbGliZXJ0YWQgKGRmKTsgY29uIGRmIGFsdG9zLCBzZSBhc2VtZWphIGEKICAgIGxhIG5vcm1hbC4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogQ29tcGFyYXIgbWVkaWFzIGRlIGdydXBvcyBwZXF1ZcOxb3MsIGNvbW8gZWwKICAgIGVmZWN0byBkZSB1biBmw6FybWFjbyBlbiAyMCBwYWNpZW50ZXMuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIENvbXBhcmFyIGVsIG5pdmVsIGRlIGdsdWNvc2EgYW50ZXMgeSBkZXNwdcOpcwogICAgZGUgdW4gdHJhdGFtaWVudG8gZW4gMTUgcGFjaWVudGVzIHVzYW5kbyB1bmEgcHJ1ZWJhIHQuCgoqKkNoaS1jdWFkcmFkbyAoKiokXGNoaV4yJCk6CgotICAgU3VtYSBkZSBjdWFkcmFkb3MgZGUgdmFyaWFibGVzIG5vcm1hbGVzIGVzdMOhbmRhciwgY29uICRrJCBncmFkb3MgZGUKICAgIGxpYmVydGFkLgotICAgUERGOiAkZih4KSA9IFxmcmFjezF9ezJee2svMn0gXEdhbW1hKGsvMil9IHhee2svMi0xfSBlXnsteC8yfSQsIHBhcmEKICAgICR4IFxnZXEgMCQuCi0gICAqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIFBydWViYXMgZGUgYm9uZGFkIGRlIGFqdXN0ZSAoZS5nLiwgYWp1c3RhcgogICAgZGF0b3MgYSB1bmEgZGlzdHJpYnVjacOzbiBlc3BlcmFkYSkgbyBwcnVlYmFzIGRlIGluZGVwZW5kZW5jaWEgZW4KICAgIHRhYmxhcyBkZSBjb250aW5nZW5jaWEgKGUuZy4sIHJlbGFjacOzbiBlbnRyZSB0YWJhcXVpc21vIHkgY8OhbmNlcikuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEV2YWx1YXIgc2kgbGEgZGlzdHJpYnVjacOzbiBkZSBjYXNvcyBkZQogICAgZGlhYmV0ZXMgcG9yIGfDqW5lcm8gY29pbmNpZGUgY29uIGxhIGRpc3RyaWJ1Y2nDs24gcG9ibGFjaW9uYWwKICAgIGVzcGVyYWRhLgoKKipGOioqCgotICAgQ29jaWVudGUgZGUgZG9zIHZhcmlhYmxlcyBDaGktY3VhZHJhZG8gZGl2aWRpZGFzIHBvciBzdXMgZ3JhZG9zIGRlCiAgICBsaWJlcnRhZC4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogQ29tcGFyYXIgdmFyaWFuemFzIGVuIEFOT1ZBLCBjb21vIGxhCiAgICB2YXJpYWJpbGlkYWQgZW4gbGEgcmVzcHVlc3RhIGEgdW4gdHJhdGFtaWVudG8gZW50cmUgZGlmZXJlbnRlcwogICAgaG9zcGl0YWxlcy4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogQ29tcGFyYXIgbGEgdmFyaWFuemEgZW4gbG9zIHRpZW1wb3MgZGUKICAgIHJlY3VwZXJhY2nDs24gZW50cmUgZG9zIGdydXBvcyBkZSBwYWNpZW50ZXMgdHJhdGFkb3MgY29uIGRpZmVyZW50ZXMKICAgIHByb3RvY29sb3MuCgojIyMgVGVvcmVtYSBkZWwgTMOtbWl0ZSBDZW50cmFsIHkgQXByb3hpbWFjaW9uZXMKCioqVGVvcmVtYSBkZWwgTMOtbWl0ZSBDZW50cmFsIChUTEMpOioqIExhIHN1bWEgKG8gbWVkaWEpIGRlIHVuIGdyYW4KbsO6bWVybyBkZSB2YXJpYWJsZXMgYWxlYXRvcmlhcyBpbmRlcGVuZGllbnRlcywgY29uIG1lZGlhICRcbXUkIHkKdmFyaWFuemEgJFxzaWdtYV4yJCwgc2UgZGlzdHJpYnV5ZSBhcHJveGltYWRhbWVudGUgY29tbyB1bmEgbm9ybWFsCiROKFxtdSwgXHNpZ21hXjIvbikkLCBkb25kZSAkbiQgZXMgZWwgdGFtYcOxbyBtdWVzdHJhbC4KCi0gICAqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIFBlcm1pdGUgYXN1bWlyIG5vcm1hbGlkYWQgZW4gbWVkaWFzCiAgICBtdWVzdHJhbGVzLCBjb21vIGVsIHByb21lZGlvIGRlIHByZXNpw7NuIGFydGVyaWFsIGVuIHVuYSBtdWVzdHJhIGRlCiAgICA1MCBwYWNpZW50ZXMsIGluY2x1c28gc2kgbG9zIGRhdG9zIGluZGl2aWR1YWxlcyBubyBzb24gbm9ybWFsZXMuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIExhIG1lZGlhIGRlIGdsdWNvc2EgZW4gc2FuZ3JlIGRlIDQwIHBhY2llbnRlcwogICAgc2UgYXByb3hpbWEgYSB1bmEgZGlzdHJpYnVjacOzbiBub3JtYWwsIHBlcm1pdGllbmRvIHBydWViYXMKICAgIHBhcmFtw6l0cmljYXMuCgoqKkFwcm94aW1hY2lvbmVzOioqCgotICAgKipOb3JtYWwgYSBCaW5vbWlhbDoqKiBQYXJhICRuJCBncmFuZGUgeSAkcCQgbm8gZXh0cmVtbwogICAgKCRucCBcZ2VxIDUkLCAkbigxLXApIFxnZXEgNSQpLCB1bmEgYmlub21pYWwgc2UgYXByb3hpbWEgYQogICAgJE4obnAsIFxzcXJ0e25wKDEtcCl9KSQuIEVqZW1wbG86IEFwcm94aW1hciBsYSBwcm9iYWJpbGlkYWQgZGUgcXVlCiAgICBtw6FzIGRlIDYwIGRlIDEwMCBwYWNpZW50ZXMgcmVzcG9uZGFuIGEgdW4gdHJhdGFtaWVudG8gY29uICRwID0gMC43JC4KLSAgICoqTm9ybWFsIGEgUG9pc3NvbjoqKiBQYXJhICRcbGFtYmRhJCBncmFuZGUgKCRcbGFtYmRhID4gMTAkKSwgdW5hCiAgICBQb2lzc29uIHNlIGFwcm94aW1hIGEgJE4oXGxhbWJkYSwgXHNxcnR7XGxhbWJkYX0pJC4gRWplbXBsbzoKICAgIEFwcm94aW1hciBlbCBuw7ptZXJvIGRlIGNhc29zIGRlIGluZmx1ZW56YSBlbiB1biBob3NwaXRhbCBncmFuZGUuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuIGVzdHVkaW8gZGUgdmFjdW5hY2nDs24sIHNpIDEwMDAgcGVyc29uYXMKICAgIHJlY2liZW4gdW5hIHZhY3VuYSBjb24gODAlIGRlIGVmZWN0aXZpZGFkLCBlbCBuw7ptZXJvIGRlIHByb3RlZ2lkb3MKICAgIHNlIGFwcm94aW1hIGEgJE4oODAwLCBcc3FydHsxMDAwIFxjZG90IDAuOCBcY2RvdCAwLjJ9KSQuCgojIyBSZWN1cnNvcyBwYXJhIGVsIEF1dG9lc3R1ZGlvIGVuIFNhbHVkCgojIyMgTGVjdHVyYXM6CgotICAgIlN0YXRpc3RpY2FsIE1ldGhvZHMgaW4gTWVkaWNhbCBSZXNlYXJjaCIgZGUgQXJtaXRhZ2UsIEJlcnJ5IHkKICAgIE1hdHRoZXdzLgotICAgIkJpb3N0YXRpc3RpY3M6IEEgRm91bmRhdGlvbiBmb3IgQW5hbHlzaXMgaW4gdGhlIEhlYWx0aCBTY2llbmNlcyIgZGUKICAgIERhbmllbC4KCiMjIyBFamVyY2ljaW9zIHByw6FjdGljb3M6CgotICAgQ2FsY3VsYXIgcHJvYmFiaWxpZGFkZXMgZGUgZXZlbnRvcyBjbMOtbmljb3MgKGUuZy4sIHByb2JhYmlsaWRhZCBkZQogICAgdW4gZmFsc28gcG9zaXRpdm8gZW4gdW4gdGVzdCBkaWFnbsOzc3RpY28pLgotICAgU2ltdWxhciBkYXRvcyBlbiBSIG8gUHl0aG9uIHBhcmEgYW5hbGl6YXIgZGlzdHJpYnVjaW9uZXMgZGUKICAgIHZhcmlhYmxlcyBjb21vIHByZXNpw7NuIGFydGVyaWFsIG8gdGllbXBvIGRlIHJlY3VwZXJhY2nDs24uCi0gICBBcGxpY2FyIGVsIHRlb3JlbWEgZGUgQmF5ZXMgYSBwcm9ibGVtYXMgZGlhZ27Ds3N0aWNvcyAoZS5nLiwgY2FsY3VsYXIKICAgIGxhIHByb2JhYmlsaWRhZCBkZSBlbmZlcm1lZGFkIGRhZG8gdW4gdGVzdCBwb3NpdGl2bykuCgojIyMgSGVycmFtaWVudGFzIGNvbXB1dGFjaW9uYWxlczoKCi0gICAqKlI6KiogUGFxdWV0ZXMgc3RhdHMsIGVwaVIgKHBhcmEgZXBpZGVtaW9sb2fDrWEpLCBwd3IgKGPDoWxjdWxvIGRlCiAgICBwb3RlbmNpYSkuCi0gICAqKlB5dGhvbjoqKiBMaWJyZXLDrWFzIHNjaXB5LnN0YXRzLCBzdGF0c21vZGVscywgcGFuZGFzIHBhcmEgYW7DoWxpc2lzCiAgICBkZSBkYXRvcyBjbMOtbmljb3MuCgojIyMgQmFzZXMgZGUgZGF0b3M6CgotICAgRGF0YXNldHMgcMO6YmxpY29zIGNvbW8gbG9zIGRlIGxhIE9NUywgQ0RDIG8gS2FnZ2xlIChlLmcuLCBkYXRvcyBkZQogICAgZGlhYmV0ZXMsIENPVklELTE5KS4KLSAgIEVqZW1wbG86IEFuYWxpemFyIGxhIGJhc2UgZGUgZGF0b3MgTkhBTkVTIHBhcmEgZXN0dWRpYXIgZmFjdG9yZXMgZGUKICAgIHJpZXNnbyBjYXJkaW92YXNjdWxhci4KCiMgVGFibGEgcmVzdW1lbjogRnVuZGFtZW50b3MgZGUgZXN0YWTDrXN0aWNhIGluZmVyZW5jaWFsIGVuIFNhbHVkCgpgYGB7ciBzdW1tYXJ5LXRhYmxlLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdhc2lzJ30KIyBDcmVhciBsYSB0YWJsYQp0YWJsYSA8LSBkYXRhLmZyYW1lKAogICJDb25jZXB0byIgPSBjKAogICAgIkluZmVyZW5jaWEgRXN0YWTDrXN0aWNhIiwKICAgICJQb2JsYWNpw7NuIiwKICAgICJNdWVzdHJhIiwKICAgICJQYXLDoW1ldHJvIiwKICAgICJFc3RhZMOtc3RpY28iLAogICAgIlZhcmlhYmxlIEFsZWF0b3JpYSIsCiAgICAiRGlzdHJpYnVjacOzbiBCaW5vbWlhbCIsCiAgICAiRGlzdHJpYnVjacOzbiBQb2lzc29uIiwKICAgICJEaXN0cmlidWNpw7NuIE5vcm1hbCIsCiAgICAidCBkZSBTdHVkZW50IiwKICAgICJDaGktY3VhZHJhZG8gKM+HwrIpIiwKICAgICJUZW9yZW1hIGRlIEJheWVzIiwKICAgICJUZW9yZW1hIGRlbCBMw61taXRlIENlbnRyYWwiCiAgKSwKICAiRGVmaW5pY2nDs24iID0gYygKICAgICJQcm9jZXNvIGRlIGdlbmVyYWxpemFyIHJlc3VsdGFkb3MgZGUgdW5hIG11ZXN0cmEgYSB1bmEgcG9ibGFjacOzbiwgY29uc2lkZXJhbmRvIGxhIGluY2VydGlkdW1icmUuIiwKICAgICJDb25qdW50byB0b3RhbCBkZSBpbmRpdmlkdW9zIHUgb2JqZXRvcyBkZSBpbnRlcsOpcyAoZS5nLiwgdG9kb3MgbG9zIHBhY2llbnRlcyBjb24gZGlhYmV0ZXMgdGlwbyAyKS4iLAogICAgIlN1YmNvbmp1bnRvIHJlcHJlc2VudGF0aXZvIGRlIGxhIHBvYmxhY2nDs24gc2VsZWNjaW9uYWRvIHBhcmEgZXN0dWRpby4iLAogICAgIkNhcmFjdGVyw61zdGljYSBudW3DqXJpY2EgZGUgbGEgcG9ibGFjacOzbiAoZS5nLiwgbWVkaWEgcG9ibGFjaW9uYWwgJFxcbXUkLCBwcm9wb3JjacOzbiAkcCQpLiIsCiAgICAiTWVkaWRhIGNhbGN1bGFkYSBhIHBhcnRpciBkZSBsYSBtdWVzdHJhIChlLmcuLCBtZWRpYSBtdWVzdHJhbCAkXFxiYXJ7eH0kLCBwcm9wb3JjacOzbiAkXFxoYXR7cH0kKS4iLAogICAgIkZ1bmNpw7NuIHF1ZSBhc2lnbmEgdmFsb3JlcyBudW3DqXJpY29zIGEgcmVzdWx0YWRvcyBkZSB1biBleHBlcmltZW50byAoZGlzY3JldGEgbyBjb250aW51YSkuIiwKICAgICJNb2RlbGEgZWwgbsO6bWVybyBkZSDDqXhpdG9zIGVuICRuJCBlbnNheW9zIGluZGVwZW5kaWVudGVzIGNvbiBwcm9iYWJpbGlkYWQgY29uc3RhbnRlICRwJC4iLAogICAgIk1vZGVsYSBldmVudG9zIHJhcm9zIGVuIHVuIGludGVydmFsbyBmaWpvIGNvbiB0YXNhIHByb21lZGlvICRcXGxhbWJkYSQuIiwKICAgICJEaXN0cmlidWNpw7NuIGNvbnRpbnVhIHNpbcOpdHJpY2EsIGRlZmluaWRhIHBvciAkXFxtdSQgeSAkXFxzaWdtYSQsIGNvbcO6biBlbiB2YXJpYWJsZXMgYmlvbMOzZ2ljYXMuIiwKICAgICJEaXN0cmlidWNpw7NuIHBhcmEgbWVkaWFzIG11ZXN0cmFsZXMgY29uIHZhcmlhbnphIGRlc2Nvbm9jaWRhIHkgJG4gPCAzMCQuIiwKICAgICJEaXN0cmlidWNpw7NuIHBhcmEgc3VtYXMgZGUgY3VhZHJhZG9zIGRlIG5vcm1hbGVzIGVzdMOhbmRhcjsgdXNhZGEgZW4gcHJ1ZWJhcyBkZSBpbmRlcGVuZGVuY2lhLiIsCiAgICAiQWN0dWFsaXphIGxhIHByb2JhYmlsaWRhZCBkZSB1biBldmVudG8gZGFkbyBudWV2YSBldmlkZW5jaWE6ICRQKEF8QikgPSBcXGZyYWN7UChCfEEpUChBKX17UChCKX0kLiIsCiAgICAiTGEgbWVkaWEgbXVlc3RyYWwgc2UgZGlzdHJpYnV5ZSBhcHJveGltYWRhbWVudGUgY29tbyAkTihcXG11LCBcXHNpZ21hXjIvbikkIHBhcmEgJG4kIGdyYW5kZS4iCiAgKSwKICAiRWplbXBsbyBlbiBTYWx1ZCIgPSBjKAogICAgIkVzdGltYXIgbGEgZWZlY3RpdmlkYWQgZGUgdW5hIHZhY3VuYSBhIHBhcnRpciBkZSB1biBlbnNheW8gY2zDrW5pY28gY29uIDEwMDAgcGFydGljaXBhbnRlcy4iLAogICAgIlRvZG9zIGxvcyBhZHVsdG9zIGhpcGVydGVuc29zIGVuIENvbG9tYmlhLiIsCiAgICAiVW5hIG11ZXN0cmEgZGUgNTAwIHBhY2llbnRlcyBoaXBlcnRlbnNvcyBkZSBjbMOtbmljYXMgdXJiYW5hcyB5IHJ1cmFsZXMuIiwKICAgICJQcmV2YWxlbmNpYSByZWFsIGRlIGhpcGVydGVuc2nDs24gZW4gYWR1bHRvcyBjb2xvbWJpYW5vcyAoJHAgPSAwLjI1JCkuIiwKICAgICJQcmV2YWxlbmNpYSBlc3RpbWFkYSBhIHBhcnRpciBkZSBsYSBtdWVzdHJhICgkXFxoYXR7cH0gPSAwLjIzJCkuIiwKICAgICJOw7ptZXJvIGRlIHBhY2llbnRlcyBxdWUgcmVzcG9uZGVuIGEgdW4gdHJhdGFtaWVudG8gKGRpc2NyZXRhKSBvIG5pdmVsIGRlIGNvbGVzdGVyb2wgKGNvbnRpbnVhKS4iLAogICAgIlByb2JhYmlsaWRhZCBkZSBxdWUgNzAgZGUgMTAwIHBhY2llbnRlcyByZXNwb25kYW4gYSB1biBmw6FybWFjbyBjb24gJHAgPSAwLjckLiIsCiAgICAiTsO6bWVybyBkZSBjYXNvcyBkZSBtZW5pbmdpdGlzIHBvciBtZXMgZW4gdW4gaG9zcGl0YWwsIGNvbiAkXFxsYW1iZGEgPSAyJC4iLAogICAgIkRpc3RyaWJ1Y2nDs24gZGUgbGEgcHJlc2nDs24gYXJ0ZXJpYWwgc2lzdMOzbGljYSBlbiBhZHVsdG9zICgkXFxtdSA9IDEyMCQsICRcXHNpZ21hID0gMTUkKS4iLAogICAgIkNvbXBhcmFyIG5pdmVsZXMgZGUgZ2x1Y29zYSBhbnRlcyB5IGRlc3B1w6lzIGRlIHVuIHRyYXRhbWllbnRvIGVuIDIwIHBhY2llbnRlcy4iLAogICAgIkV2YWx1YXIgc2kgZXhpc3RlIGFzb2NpYWNpw7NuIGVudHJlIHRhYmFxdWlzbW8geSBjw6FuY2VyIGRlIHB1bG3Ds24gZW4gdW5hIHRhYmxhIGRlIGNvbnRpbmdlbmNpYS4iLAogICAgIkNhbGN1bGFyIGxhIHByb2JhYmlsaWRhZCBkZSB0ZW5lciBDT1ZJRC0xOSBkYWRvIHVuIHRlc3QgcG9zaXRpdm8sIHVzYW5kbyBzZW5zaWJpbGlkYWQgeSBwcmV2YWxlbmNpYS4iLAogICAgIkxhIG1lZGlhIGRlIGdsdWNvc2EgZW4gc2FuZ3JlIGRlIDQwIHBhY2llbnRlcyBzZSBjb21wb3J0YSBub3JtYWxtZW50ZSwgYXVucXVlIGxvcyBkYXRvcyBpbmRpdmlkdWFsZXMgbm8gbG8gc2Vhbi4iCiAgKSwKICBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UKKQoKIyBNb3N0cmFyIHRhYmxhIGNvbiBmb3JtYXRvCmthYmxlKHRhYmxhLCAiaHRtbCIsIGNhcHRpb24gPSAiVGFibGEgMTogUmVzdW1lbiBkZSBjb25jZXB0b3MgY2xhdmUgZGUgZXN0YWTDrXN0aWNhIGluZmVyZW5jaWFsIGFwbGljYWRvcyBhbCBzZWN0b3Igc2FsdWQiKSAlPiUKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJyZXNwb25zaXZlIiksIGZ1bGxfd2lkdGggPSBGQUxTRSkgJT4lCiAgc2Nyb2xsX2JveCh3aWR0aCA9ICIxMDAlIiwgaGVpZ2h0ID0gIjUwMHB4IikgICAgICAgCgpgYGAKCiMgMi4gRXN0aW1hY2nDs24gZGUgUGFyw6FtZXRyb3MgcGFyYSBlbCBTZWN0b3IgU2FsdWQKCkVzdGUgdGVtYXJpbyBwcm9mdW5kaXphIGVuIGxhIGVzdGltYWNpw7NuIGRlIHBhcsOhbWV0cm9zIGNvbiB1biBlbmZvcXVlIGVuCmVsIHNlY3RvciBzYWx1ZCwgcHJvcG9yY2lvbmFuZG8gZXhwbGljYWNpb25lcyBkZXRhbGxhZGFzLCBlamVtcGxvcwpwcsOhY3RpY29zIHkgYXBsaWNhY2lvbmVzIHJlbGV2YW50ZXMgcGFyYSBwcm9mZXNpb25hbGVzIG3DqWRpY29zLAppbnZlc3RpZ2Fkb3JlcyBjbMOtbmljb3MgeSBlcGlkZW1pw7Nsb2dvcy4gTGEgZXN0aW1hY2nDs24gZGUgcGFyw6FtZXRyb3MgZXMKZnVuZGFtZW50YWwgZW4gZXN0YWTDrXN0aWNhIGluZmVyZW5jaWFsIHBhcmEgaW5mZXJpciBjYXJhY3RlcsOtc3RpY2FzCnBvYmxhY2lvbmFsZXMgKGNvbW8gbGEgcHJldmFsZW5jaWEgZGUgdW5hIGVuZmVybWVkYWQgbyBsYSBtZWRpYSBkZSB1bmEKdmFyaWFibGUgY2zDrW5pY2EpIGEgcGFydGlyIGRlIGRhdG9zIG11ZXN0cmFsZXMsIG1hbmVqYW5kbyBsYQppbmNlcnRpZHVtYnJlIGluaGVyZW50ZSBhIGxhcyBtdWVzdHJhcy4KCiMjIDIuMSBFc3RpbWFjacOzbiBQdW50dWFsCgojIyMgUHJvcGllZGFkZXMgZGUgbG9zIEVzdGltYWRvcmVzOiBTZXNnbywgRWZpY2llbmNpYSwgQ29uc2lzdGVuY2lhCgpMYSBlc3RpbWFjacOzbiBwdW50dWFsIGNvbnNpc3RlIGVuIHV0aWxpemFyIHVuIGVzdGFkw61zdGljbyBjYWxjdWxhZG8gYQpwYXJ0aXIgZGUgdW5hIG11ZXN0cmEgcGFyYSBlc3RpbWFyIHVuIHBhcsOhbWV0cm8gcG9ibGFjaW9uYWwuIFBvcgplamVtcGxvLCBsYSBtZWRpYSBtdWVzdHJhbCAoJFxiYXJ7eH0kKSBlc3RpbWEgbGEgbWVkaWEgcG9ibGFjaW9uYWwKKCRcbXUkKS4gRW4gc2FsdWQsIGVzdG8gZXMgY3J1Y2lhbCBwYXJhIGVzdGltYXIgcGFyw6FtZXRyb3MgY29tbyBsYSB0YXNhCmRlIGluY2lkZW5jaWEgZGUgdW5hIGVuZmVybWVkYWQgbyBsYSBlZmVjdGl2aWRhZCBwcm9tZWRpbyBkZSB1bgp0cmF0YW1pZW50by4gTG9zIGVzdGltYWRvcmVzIGRlYmVuIGN1bXBsaXIgY2llcnRhcyBwcm9waWVkYWRlcyBwYXJhIHNlcgpjb25maWFibGVzOgoKKipTZXNnbzoqKgoKLSAgIFVuIGVzdGltYWRvciBlcyBpbnNlc2dhZG8gc2kgc3UgdmFsb3IgZXNwZXJhZG8gZXMgaWd1YWwgYWwgcGFyw6FtZXRybwogICAgcXVlIGVzdGltYTogJEUoXGhhdHtcdGhldGF9KSA9IFx0aGV0YSQuCi0gICBFamVtcGxvOiBMYSBtZWRpYSBtdWVzdHJhbCAkXGJhcnt4fSQgZXMgdW4gZXN0aW1hZG9yIGluc2VzZ2FkbyBkZQogICAgJFxtdSQgcG9ycXVlICRFKFxiYXJ7eH0pID0gXG11JC4KLSAgIEFwbGljYWNpw7NuIGVuIHNhbHVkOiBTaSBzZSBtaWRlIGxhIGdsdWNvc2EgZW4gc2FuZ3JlIGRlIDUwIHBhY2llbnRlcwogICAgZGlhYsOpdGljb3MsIGxhIG1lZGlhIG11ZXN0cmFsICRcYmFye3h9JCBwcm9wb3JjaW9uYSB1bmEgZXN0aW1hY2nDs24KICAgIGluc2VzZ2FkYSBkZSBsYSBtZWRpYSBwb2JsYWNpb25hbCBkZSBnbHVjb3NhLgotICAgKipTZXNnbyBlbiBsYSBwcsOhY3RpY2E6KiogVW4gZXN0aW1hZG9yIHNlc2dhZG8sIGNvbW8gdXNhciBsYQogICAgdmFyaWFuemEgbXVlc3RyYWwgc2luIGNvcnJlY2Npw7NuICgkXHN1bSAoeF9pIC0gXGJhcnt4fSleMiAvIG4kKSwKICAgIHN1YmVzdGltYSBsYSB2YXJpYW56YSBwb2JsYWNpb25hbCAoJFxzaWdtYV4yJCkuIExhIGNvcnJlY2Npw7NuIGRlCiAgICBCZXNzZWwgKCRcc3VtICh4X2kgLSBcYmFye3h9KV4yIC8gKG4tMSkkKSBlbGltaW5hIGVzdGUgc2VzZ28uCgoqKkVmaWNpZW5jaWE6KioKCi0gICBVbiBlc3RpbWFkb3IgZXMgbcOhcyBlZmljaWVudGUgc2kgdGllbmUgbWVub3IgdmFyaWFuemEgZW50cmUgdG9kb3MKICAgIGxvcyBlc3RpbWFkb3JlcyBpbnNlc2dhZG9zIHBhcmEgZWwgbWlzbW8gcGFyw6FtZXRyby4KLSAgIE1hdGVtw6F0aWNhbWVudGU6IFNpICRcaGF0e1x0aGV0YX1fMSQgeSAkXGhhdHtcdGhldGF9XzIkIHNvbgogICAgaW5zZXNnYWRvcywgJFxoYXR7XHRoZXRhfV8xJCBlcyBtw6FzIGVmaWNpZW50ZSBzaQogICAgJFx0ZXh0e1Zhcn0oXGhhdHtcdGhldGF9XzEpIDwgXHRleHR7VmFyfShcaGF0e1x0aGV0YX1fMikkLgotICAgQXBsaWNhY2nDs24gZW4gc2FsdWQ6IEVuIHVuIGVzdHVkaW8gcGFyYSBlc3RpbWFyIGxhIHByZXZhbGVuY2lhIGRlCiAgICBoaXBlcnRlbnNpw7NuLCBsYSBwcm9wb3JjacOzbiBtdWVzdHJhbCAkXGhhdHtwfSQgZXMgbcOhcyBlZmljaWVudGUgcXVlCiAgICBvdHJvcyBlc3RpbWFkb3JlcyBpbnNlc2dhZG9zIHBvcnF1ZSBtaW5pbWl6YSBsYSB2YXJpYW56YSBwYXJhCiAgICBtdWVzdHJhcyBncmFuZGVzLgotICAgRWplbXBsbyBwcsOhY3RpY286IENvbXBhcmFyIGRvcyBtw6l0b2RvcyBwYXJhIGVzdGltYXIgbGEgcHJvcG9yY2nDs24gZGUKICAgIHBhY2llbnRlcyBjb24gcmVzcHVlc3RhIHBvc2l0aXZhIGEgdW4gZsOhcm1hY287IGVsIG3DqXRvZG8gY29uIG1lbm9yCiAgICB2YXJpYW56YSBlcyBwcmVmZXJpZG8uCgoqKkNvbnNpc3RlbmNpYToqKgoKLSAgIFVuIGVzdGltYWRvciBlcyBjb25zaXN0ZW50ZSBzaSwgYWwgYXVtZW50YXIgZWwgdGFtYcOxbyBtdWVzdHJhbAogICAgKCRuIFx0byBcaW5mdHkkKSwgY29udmVyZ2UgZW4gcHJvYmFiaWxpZGFkIGFsIHBhcsOhbWV0cm8gdmVyZGFkZXJvOgogICAgJFxoYXR7XHRoZXRhfSBceHJpZ2h0YXJyb3d7cH0gXHRoZXRhJC4KLSAgIEFwbGljYWNpw7NuIGVuIHNhbHVkOiBMYSBtZWRpYSBtdWVzdHJhbCAkXGJhcnt4fSQgZXMgY29uc2lzdGVudGUgcGFyYQogICAgJFxtdSQ7IGNvbiBtdWVzdHJhcyBtw6FzIGdyYW5kZXMgKGUuZy4sIG3DoXMgcGFjaWVudGVzIGVuIHVuIGVuc2F5bwogICAgY2zDrW5pY28pLCBsYSBlc3RpbWFjacOzbiBzZSBhY2VyY2EgYWwgdmFsb3IgcmVhbC4KLSAgIEVqZW1wbG8gcHLDoWN0aWNvOiBFbiB1biBlc3R1ZGlvIGxvbmdpdHVkaW5hbCBkZSBwcmVzacOzbiBhcnRlcmlhbCwgYQogICAgbWVkaWRhIHF1ZSBzZSBpbmNsdXllbiBtw6FzIHBhY2llbnRlcywgbGEgbWVkaWEgbXVlc3RyYWwgc2UgYXByb3hpbWEKICAgIGNhZGEgdmV6IG3DoXMgYSBsYSBtZWRpYSBwb2JsYWNpb25hbC4KCioqT3Ryb3MgY3JpdGVyaW9zOioqCgotICAgKipTdWZpY2llbmNpYToqKiBVbiBlc3RpbWFkb3IgZXMgc3VmaWNpZW50ZSBzaSBjYXB0dXJhIHRvZGEgbGEKICAgIGluZm9ybWFjacOzbiByZWxldmFudGUgZGUgbGEgbXVlc3RyYSBzb2JyZSBlbCBwYXLDoW1ldHJvLgotICAgKipSb2J1c3RlejoqKiBDYXBhY2lkYWQgZGVsIGVzdGltYWRvciBwYXJhIG1hbnRlbmVyc2UgdsOhbGlkbyBiYWpvCiAgICB2aW9sYWNpb25lcyBkZSBzdXB1ZXN0b3MgKGUuZy4sIG5vIG5vcm1hbGlkYWQgZW4gZGF0b3MgZGUgc2FsdWQpLgotICAgKipFamVtcGxvIGVuIHNhbHVkOioqIEVuIGVzdHVkaW9zIGNvbiBkYXRvcyBubyBub3JtYWxlcyAoZS5nLiwKICAgIHRpZW1wb3MgZGUgcmVjdXBlcmFjacOzbiBzZXNnYWRvcyksIHVuIGVzdGltYWRvciByb2J1c3RvIGNvbW8gbGEKICAgIG1lZGlhbmEgcHVlZGUgc2VyIG3DoXMgYWRlY3VhZG8gcXVlIGxhIG1lZGlhLgoKIyMjIE3DqXRvZG9zIGRlIEVzdGltYWNpw7NuOiBNw6F4aW1hIFZlcm9zaW1pbGl0dWQsIE1vbWVudG9zCgpFeGlzdGVuIHZhcmlvcyBtw6l0b2RvcyBwYXJhIG9idGVuZXIgZXN0aW1hZG9yZXMgcHVudHVhbGVzLCBwZXJvIGxvcyBtw6FzCmNvbXVuZXMgZW4gc2FsdWQgc29uIGxhIG3DoXhpbWEgdmVyb3NpbWlsaXR1ZCB5IGVsIG3DqXRvZG8gZGUgbG9zCm1vbWVudG9zLgoKKipNw6F4aW1hIFZlcm9zaW1pbGl0dWQgKE1MRSk6KioKCi0gICAqKkRlZmluaWNpw7NuOioqIFNlbGVjY2lvbmEgZWwgdmFsb3IgZGVsIHBhcsOhbWV0cm8gcXVlIG1heGltaXphIGxhCiAgICBwcm9iYWJpbGlkYWQgKHZlcm9zaW1pbGl0dWQpIGRlIG9ic2VydmFyIGxvcyBkYXRvcyBtdWVzdHJhbGVzLiBMYQogICAgZnVuY2nDs24gZGUgdmVyb3NpbWlsaXR1ZCBlcwogICAgJEwoXHRoZXRhKSA9IFxwcm9kX3tpPTF9Xm4gZih4X2kgfCBcdGhldGEpJCwgZG9uZGUgJGYoeF9pIHwgXHRoZXRhKSQKICAgIGVzIGxhIGRlbnNpZGFkIG8gbWFzYSBkZSBwcm9iYWJpbGlkYWQuCi0gICAqKlByb2NlZGltaWVudG86KioKICAgIDEuICBEZWZpbmlyIGxhIGZ1bmNpw7NuIGRlIHZlcm9zaW1pbGl0dWQgc2Vnw7puIGxhIGRpc3RyaWJ1Y2nDs24KICAgICAgICBhc3VtaWRhIChlLmcuLCBub3JtYWwsIGJpbm9taWFsKS4KICAgIDIuICBNYXhpbWl6YXIgJEwoXHRoZXRhKSQgKGEgbWVudWRvIHVzYW5kbyBlbCBsb2dhcml0bW86CiAgICAgICAgJFxsbiBMKFx0aGV0YSkkKS4KICAgIDMuICBSZXNvbHZlciBkZXJpdmFuZG8gZSBpZ3VhbGFuZG8gYSBjZXJvIG8gdXNhbmRvIG3DqXRvZG9zCiAgICAgICAgbnVtw6lyaWNvcy4KLSAgICoqUHJvcGllZGFkZXM6KiogTG9zIGVzdGltYWRvcmVzIE1MRSBzb24gY29uc2lzdGVudGVzLAogICAgYXNpbnTDs3RpY2FtZW50ZSBlZmljaWVudGVzIHksIGJham8gY2llcnRhcyBjb25kaWNpb25lcywgaW5zZXNnYWRvcwogICAgcGFyYSBtdWVzdHJhcyBncmFuZGVzLgotICAgKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBFc3RpbWFyIGxhIHRhc2EgZGUgaW5jaWRlbmNpYSAoJFxsYW1iZGEkKQogICAgZGUgdW5hIGVuZmVybWVkYWQgcmFyYSBtb2RlbGFkYSBjb24gdW5hIGRpc3RyaWJ1Y2nDs24gUG9pc3Nvbi4gUG9yCiAgICBlamVtcGxvLCBzaSB1biBob3NwaXRhbCByZWdpc3RyYSA1IGNhc29zIGRlIG1lbmluZ2l0aXMgZW4gdW4gbWVzLCBlbAogICAgTUxFIGRlICRcbGFtYmRhJCBlcyA1LgotICAgKipFamVtcGxvIHByw6FjdGljbzoqKiBFbiB1biBlbnNheW8gY2zDrW5pY28sIHNlIHVzYSBNTEUgcGFyYSBlc3RpbWFyCiAgICBsYSBwcm9iYWJpbGlkYWQgZGUgw6l4aXRvICgkcCQpIGRlIHVuIHRyYXRhbWllbnRvIGJpbm9taWFsLAogICAgbWF4aW1pemFuZG8gJEwocCkgPSBcYmlub217bn17a30gcF5rICgxLXApXntuLWt9JC4KCioqTcOpdG9kbyBkZSBsb3MgTW9tZW50b3M6KioKCi0gICAqKkRlZmluaWNpw7NuOioqIElndWFsYXIgbG9zIG1vbWVudG9zIG11ZXN0cmFsZXMgKGUuZy4sIG1lZGlhLAogICAgdmFyaWFuemEpIGEgbG9zIG1vbWVudG9zIHRlw7NyaWNvcyBkZSBsYSBwb2JsYWNpw7NuIHkgcmVzb2x2ZXIgcGFyYSBlbAogICAgcGFyw6FtZXRyby4KLSAgICoqUHJvY2VkaW1pZW50bzoqKgogICAgMS4gIENhbGN1bGFyIG1vbWVudG9zIG11ZXN0cmFsZXM6ICRtXzEgPSBcYmFye3h9JCwKICAgICAgICAkbV8yID0gXGZyYWN7MX17bn0gXHN1bSAoeF9pIC0gXGJhcnt4fSleMiQuCiAgICAyLiAgSWd1YWxhcmxvcyBhIG1vbWVudG9zIHBvYmxhY2lvbmFsZXM6ICRFKFgpID0gXG11JCwKICAgICAgICAkRShYXjIpIC0gW0UoWCldXjIgPSBcc2lnbWFeMiQuCiAgICAzLiAgUmVzb2x2ZXIgZWwgc2lzdGVtYSBkZSBlY3VhY2lvbmVzLgotICAgKipQcm9waWVkYWRlczoqKiBGw6FjaWwgZGUgY2FsY3VsYXIsIHBlcm8gcHVlZGUgc2VyIG1lbm9zIGVmaWNpZW50ZQogICAgcXVlIE1MRSwgZXNwZWNpYWxtZW50ZSBwYXJhIGRpc3RyaWJ1Y2lvbmVzIGNvbXBsZWphcy4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogRXN0aW1hciBsYSBtZWRpYSB5IHZhcmlhbnphIGRlIG5pdmVsZXMgZGUKICAgIGNvbGVzdGVyb2wgZW4gdW5hIHBvYmxhY2nDs24gYXN1bWllbmRvIG5vcm1hbGlkYWQuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIFBhcmEgdW5hIG11ZXN0cmEgZGUgMTAwIHBhY2llbnRlcyBjb24gbml2ZWxlcwogICAgZGUgZ2x1Y29zYSwgbGEgbWVkaWEgbXVlc3RyYWwgKCRcYmFye3h9ID0gMTIwIFwsIFx0ZXh0e21nL2RMfSQpIHkgbGEKICAgIHZhcmlhbnphIG11ZXN0cmFsICgkc14yID0gMjI1JCkgc29uIGVzdGltYWRvcmVzIGRlIG1vbWVudG9zIHBhcmEKICAgICRcbXUkIHkgJFxzaWdtYV4yJC4KCioqQ29tcGFyYWNpw7NuIGVuIHNhbHVkOioqCgotICAgKipNTEU6KiogUHJlZmVyaWRvIGVuIG1vZGVsb3MgY29tcGxlam9zIChlLmcuLCByZWdyZXNpw7NuIGxvZ8Otc3RpY2EKICAgIHBhcmEgcHJlZGVjaXIgcmllc2dvIGRlIGluZmFydG8pIGRlYmlkbyBhIHN1IGVmaWNpZW5jaWEgeQogICAgcHJvcGllZGFkZXMgYXNpbnTDs3RpY2FzLgotICAgKipNb21lbnRvczoqKiDDmnRpbCBwYXJhIGVzdGltYWNpb25lcyByw6FwaWRhcyBlbiBlc3R1ZGlvcwogICAgZXhwbG9yYXRvcmlvcyBvIGN1YW5kbyBsb3MgZGF0b3Mgbm8gc2UgYWp1c3RhbiBhIGRpc3RyaWJ1Y2lvbmVzCiAgICBlc3TDoW5kYXIuCi0gICAqKkVqZW1wbG8gY29tYmluYWRvOioqIEVuIHVuIGVzdHVkaW8gZGUgcHJldmFsZW5jaWEgZGUgZGlhYmV0ZXMsIE1MRQogICAgZXN0aW1hIGxhIHByb3BvcmNpw7NuICRwJCBkZSB1bmEgZGlzdHJpYnVjacOzbiBiaW5vbWlhbCwgbWllbnRyYXMgcXVlCiAgICBlbCBtw6l0b2RvIGRlIGxvcyBtb21lbnRvcyBwb2Ryw61hIHVzYXJzZSBwYXJhIHVuYSBlc3RpbWFjacOzbiBpbmljaWFsCiAgICBiYXNhZGEgZW4gbGEgcHJvcG9yY2nDs24gbXVlc3RyYWwuCgojIyAyLjIgRXN0aW1hY2nDs24gcG9yIEludGVydmFsb3MKCiMjIyBJbnRlcnZhbG9zIGRlIENvbmZpYW56YSBwYXJhIE1lZGlhcywgUHJvcG9yY2lvbmVzIHkgVmFyaWFuemFzCgpMb3MgaW50ZXJ2YWxvcyBkZSBjb25maWFuemEgKElDKSBwcm9wb3JjaW9uYW4gdW4gcmFuZ28gZGUgdmFsb3JlcwpwbGF1c2libGVzIHBhcmEgdW4gcGFyw6FtZXRybyBwb2JsYWNpb25hbCwganVudG8gY29uIHVuIG5pdmVsIGRlCmNvbmZpYW56YSAoZS5nLiwgOTUlKSBxdWUgaW5kaWNhIGxhIHByb2JhYmlsaWRhZCBkZSBxdWUgZWwgaW50ZXJ2YWxvCmNvbnRlbmdhIGVsIHBhcsOhbWV0cm8gdmVyZGFkZXJvLiBFbiBzYWx1ZCwgbG9zIElDIHNvbiBlc2VuY2lhbGVzIHBhcmEKY3VhbnRpZmljYXIgbGEgaW5jZXJ0aWR1bWJyZSBlbiBlc3RpbWFjaW9uZXMgY29tbyB0YXNhcyBkZSBtb3J0YWxpZGFkLApwcmV2YWxlbmNpYXMgbyBlZmVjdG9zIGRlIHRyYXRhbWllbnRvcy4KCioqSW50ZXJ2YWxvIGRlIGNvbmZpYW56YSBwYXJhIGxhIG1lZGlhICgqKiRcbXUkKToKCi0gICAqKkbDs3JtdWxhOioqICQkCiAgICBcYmFye3h9IFxwbSB6X3tcYWxwaGEvMn0gXGNkb3QgXGZyYWN7XHNpZ21hfXtcc3FydHtufX0gXHF1YWQgKFx0ZXh0e3ZhcmlhbnphIGNvbm9jaWRhfSkKICAgICQkICQkCiAgICBcYmFye3h9IFxwbSB0X3tcYWxwaGEvMiwgbi0xfSBcY2RvdCBcZnJhY3tzfXtcc3FydHtufX0gXHF1YWQgKFx0ZXh0e3ZhcmlhbnphIGRlc2Nvbm9jaWRhLCBtdWVzdHJhIHBlcXVlw7FhfSkKICAgICQkIERvbmRlICR6X3tcYWxwaGEvMn0kIGVzIGVsIHZhbG9yIGNyw610aWNvIGRlIGxhIG5vcm1hbCBlc3TDoW5kYXIKICAgIChlLmcuLCAxLjk2IHBhcmEgOTUlKSwgJHRfe1xhbHBoYS8yLCBuLTF9JCBlcyBlbCB2YWxvciBjcsOtdGljbyBkZSBsYQogICAgdCBkZSBTdHVkZW50LCAkXHNpZ21hJCBvICRzJCBlcyBsYSBkZXN2aWFjacOzbiBlc3TDoW5kYXIgcG9ibGFjaW9uYWwgbwogICAgbXVlc3RyYWwsIHkgJG4kIGVzIGVsIHRhbWHDsW8gbXVlc3RyYWwuCi0gICAqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIEVzdGltYXIgbGEgbWVkaWEgZGUgcHJlc2nDs24gYXJ0ZXJpYWwKICAgIHNpc3TDs2xpY2EgZW4gcGFjaWVudGVzIGhpcGVydGVuc29zLgotICAgKipFamVtcGxvIHByw6FjdGljbzoqKiBFbiB1bmEgbXVlc3RyYSBkZSA1MCBwYWNpZW50ZXMsIGxhIG1lZGlhIGRlCiAgICBnbHVjb3NhIGVzICRcYmFye3h9ID0gMTMwIFwsIFx0ZXh0e21nL2RMfSQsIGNvbgogICAgJHMgPSAxNSBcLCBcdGV4dHttZy9kTH0kLiBFbCBJQyBhbCA5NSUgZXM6ICQkCiAgICAxMzAgXHBtIHRfezAuMDI1LCA0OX0gXGNkb3QgXGZyYWN7MTV9e1xzcXJ0ezUwfX0gXGFwcHJveCAxMzAgXHBtIDIuMDEgXGNkb3QgMi4xMiBcYXBwcm94ICgxMjUuNzQsIDEzNC4yNikKICAgICQkIEVzdG8gaW5kaWNhIHF1ZSBjb24gOTUlIGRlIGNvbmZpYW56YSwgbGEgbWVkaWEgcG9ibGFjaW9uYWwgZGUKICAgIGdsdWNvc2EgZXN0w6EgZW50cmUgMTI1Ljc0IHkgMTM0LjI2IG1nL2RMLgoKKipJbnRlcnZhbG8gZGUgY29uZmlhbnphIHBhcmEgbGEgcHJvcG9yY2nDs24gKCoqJHAkKToKCi0gICAqKkbDs3JtdWxhKiogKGFwcm94aW1hY2nDs24gbm9ybWFsIHBhcmEgJG4gXGhhdHtwfSBcZ2VxIDUkLAogICAgJG4oMS1caGF0e3B9KSBcZ2VxIDUkKTogJCQKICAgIFxoYXR7cH0gXHBtIHpfe1xhbHBoYS8yfSBcY2RvdCBcc3FydHtcZnJhY3tcaGF0e3B9KDEtXGhhdHtwfSl9e259fQogICAgJCQgRG9uZGUgJFxoYXR7cH0kIGVzIGxhIHByb3BvcmNpw7NuIG11ZXN0cmFsLgotICAgKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBFc3RpbWFyIGxhIHByZXZhbGVuY2lhIGRlIHVuYSBlbmZlcm1lZGFkIG8KICAgIGxhIHRhc2EgZGUgw6l4aXRvIGRlIHVuIHRyYXRhbWllbnRvLgotICAgKipFamVtcGxvIHByw6FjdGljbzoqKiBFbiB1biBlc3R1ZGlvIGRlIDIwMCBwYWNpZW50ZXMsIDQwIHJlc3BvbmRlbiBhCiAgICB1biB0cmF0YW1pZW50byAoJFxoYXR7cH0gPSAwLjIkKS4gRWwgSUMgYWwgOTUlIGVzOiAkJAogICAgMC4yIFxwbSAxLjk2IFxjZG90IFxzcXJ0e1xmcmFjezAuMiBcY2RvdCAwLjh9ezIwMH19IFxhcHByb3ggMC4yIFxwbSAwLjA1NSBcYXBwcm94ICgwLjE0NSwgMC4yNTUpCiAgICAkJCBFc3RvIHN1Z2llcmUgcXVlIGxhIHByb3BvcmNpw7NuIHBvYmxhY2lvbmFsIGRlIHJlc3BvbmRlZG9yZXMgZXN0w6EKICAgIGVudHJlIDE0LjUlIHkgMjUuNSUgY29uIDk1JSBkZSBjb25maWFuemEuCgoqKkludGVydmFsbyBkZSBjb25maWFuemEgcGFyYSBsYSB2YXJpYW56YSAoKiokXHNpZ21hXjIkKToKCi0gICAqKkbDs3JtdWxhKiogKGFzdW1pZW5kbyBub3JtYWxpZGFkKTogJCQKICAgIFxsZWZ0KCBcZnJhY3sobi0xKXNeMn17XGNoaV4yX3tcYWxwaGEvMiwgbi0xfX0sIFxmcmFjeyhuLTEpc14yfXtcY2hpXjJfezEtXGFscGhhLzIsIG4tMX19IFxyaWdodCkKICAgICQkIERvbmRlICRcY2hpXjIkIHNvbiB2YWxvcmVzIGNyw610aWNvcyBkZSBsYSBkaXN0cmlidWNpw7NuCiAgICBDaGktY3VhZHJhZG8uCi0gICAqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIEV2YWx1YXIgbGEgdmFyaWFiaWxpZGFkIGVuIHRpZW1wb3MgZGUKICAgIHJlY3VwZXJhY2nDs24gbyBuaXZlbGVzIGRlIGJpb21hcmNhZG9yZXMuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIFBhcmEgdW5hIG11ZXN0cmEgZGUgMzAgcGFjaWVudGVzLCBsYSB2YXJpYW56YQogICAgbXVlc3RyYWwgZGUgdGllbXBvcyBkZSByZWN1cGVyYWNpw7NuIGVzICRzXjIgPSAyNSBcLCBcdGV4dHtkw61hc31eMiQuCiAgICBFbCBJQyBhbCA5NSUgcGFyYSAkXHNpZ21hXjIkIGVzOiAkJAogICAgXGxlZnQoIFxmcmFjezI5IFxjZG90IDI1fXs0NS43MjJ9LCBcZnJhY3syOSBcY2RvdCAyNX17MTYuMDQ3fSBccmlnaHQpIFxhcHByb3ggKDE1Ljg0LCA0NS4xOCkKICAgICQkIEVzdG8gaW5kaWNhIHF1ZSBsYSB2YXJpYW56YSBwb2JsYWNpb25hbCBlc3TDoSBlbnRyZSAxNS44NCB5IDQ1LjE4CiAgICBkw61hc8KyIGNvbiA5NSUgZGUgY29uZmlhbnphLgoKIyMjIEludGVycHJldGFjacOzbiB5IEPDoWxjdWxvIGRlIEludGVydmFsb3MKCioqSW50ZXJwcmV0YWNpw7NuOioqCgotICAgVW4gSUMgYWwgOTUlIHNpZ25pZmljYSBxdWUsIHNpIHNlIHJlcGl0ZSBlbCBleHBlcmltZW50byBtdWNoYXMKICAgIHZlY2VzLCBhcHJveGltYWRhbWVudGUgZWwgOTUlIGRlIGxvcyBpbnRlcnZhbG9zIGNvbnRlbmRyw6FuIGVsCiAgICBwYXLDoW1ldHJvIHZlcmRhZGVyby4KLSAgICoqRXJyb3IgY29tw7puOioqIE5vIHNpZ25pZmljYSBxdWUgaGF5IHVuIDk1JSBkZSBwcm9iYWJpbGlkYWQgZGUgcXVlCiAgICBlbCBwYXLDoW1ldHJvIGVzdMOpIGVuIGVsIGludGVydmFsbywgeWEgcXVlIGVsIHBhcsOhbWV0cm8gZXMgZmlqbyAobm8KICAgIGFsZWF0b3JpbykuCi0gICBFbiBzYWx1ZCwgbG9zIElDIHJlZmxlamFuIGxhIHByZWNpc2nDs24gZGUgbGEgZXN0aW1hY2nDs24uIFVuCiAgICBpbnRlcnZhbG8gbcOhcyBlc3RyZWNobyBpbmRpY2EgbWF5b3IgcHJlY2lzacOzbiwgbWllbnRyYXMgcXVlIHVubyBtw6FzCiAgICBhbXBsaW8gc3VnaWVyZSBtYXlvciBpbmNlcnRpZHVtYnJlLgoKKipDw6FsY3VsbzoqKgoKLSAgICoqUGFzb3MgZ2VuZXJhbGVzOioqCiAgICAxLiAgSWRlbnRpZmljYXIgZWwgcGFyw6FtZXRybyBkZSBpbnRlcsOpcyAoJFxtdSQsICRwJCwgJFxzaWdtYV4yJCkuCiAgICAyLiAgU2VsZWNjaW9uYXIgZWwgbml2ZWwgZGUgY29uZmlhbnphIChlLmcuLCA5NSUpIHkgZW5jb250cmFyIGxvcwogICAgICAgIHZhbG9yZXMgY3LDrXRpY29zICgkeiQsICR0JCwgJFxjaGleMiQpLgogICAgMy4gIENhbGN1bGFyIGVsIGVzdGFkw61zdGljbyBtdWVzdHJhbCAoJFxiYXJ7eH0kLCAkXGhhdHtwfSQsICRzXjIkKSB5CiAgICAgICAgZWwgZXJyb3IgZXN0w6FuZGFyLgogICAgNC4gIENvbnN0cnVpciBlbCBpbnRlcnZhbG8gdXNhbmRvIGxhcyBmw7NybXVsYXMgY29ycmVzcG9uZGllbnRlcy4KLSAgICoqQ29uc2lkZXJhY2lvbmVzIGVuIHNhbHVkOioqCiAgICAtICAgVmVyaWZpY2FyIHN1cHVlc3RvczogTm9ybWFsaWRhZCBwYXJhIG1lZGlhcyB5IHZhcmlhbnphcywgdGFtYcOxbwogICAgICAgIG11ZXN0cmFsIHN1ZmljaWVudGUgcGFyYSBwcm9wb3JjaW9uZXMuCiAgICAtICAgVXNhciBtw6l0b2RvcyByb2J1c3RvcyAoZS5nLiwgYm9vdHN0cmFwKSBzaSBsb3Mgc3VwdWVzdG9zIG5vIHNlCiAgICAgICAgY3VtcGxlbiwgY29tbyBlbiBkYXRvcyBubyBub3JtYWxlcyBkZSB0aWVtcG9zIGRlIHJlY3VwZXJhY2nDs24uCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuIGVzdHVkaW8gZGUgcHJldmFsZW5jaWEgZGUgQ09WSUQtMTksIHVuCiAgICBJQyBhbCA5NSUgZGUgKDAuMDMsIDAuMDcpIHBhcmEgbGEgcHJvcG9yY2nDs24gZGUgY2Fzb3MgcG9zaXRpdm9zCiAgICBpbmRpY2EgcXVlIGxhIHByZXZhbGVuY2lhIHBvYmxhY2lvbmFsIGVzdMOhIGVudHJlIDMlIHkgNyUsIGNvbiBhbHRhCiAgICBjb25maWFuemEgZW4gbGEgZXN0aW1hY2nDs24uCgojIyMgVGFtYcOxbyBNdWVzdHJhbCB5IFByZWNpc2nDs24KCkVsIHRhbWHDsW8gbXVlc3RyYWwgKCRuJCkgYWZlY3RhIGxhIHByZWNpc2nDs24gZGUgbG9zIGludGVydmFsb3MgZGUKY29uZmlhbnphOiBtdWVzdHJhcyBtw6FzIGdyYW5kZXMgcHJvZHVjZW4gaW50ZXJ2YWxvcyBtw6FzIGVzdHJlY2hvcywKcmVkdWNpZW5kbyBsYSBpbmNlcnRpZHVtYnJlLgoKKipGw7NybXVsYXMgcGFyYSBlbCB0YW1hw7FvIG11ZXN0cmFsOioqCgotICAgKipQYXJhIGxhIG1lZGlhOioqICQkCiAgICBuID0gXGxlZnQoIFxmcmFje3pfe1xhbHBoYS8yfSBcY2RvdCBcc2lnbWF9e0V9IFxyaWdodCleMgogICAgJCQgRG9uZGUgJEUkIGVzIGVsIG1hcmdlbiBkZSBlcnJvciAobWl0YWQgZGVsIGFuY2hvIGRlbCBJQyksCiAgICAkXHNpZ21hJCBlcyBsYSBkZXN2aWFjacOzbiBlc3TDoW5kYXIgKGVzdGltYWRhIGRlIGVzdHVkaW9zIHByZXZpb3MpLgoKLSAgICoqUGFyYSBsYSBwcm9wb3JjacOzbjoqKiAkJAogICAgbiA9IFxmcmFje3pfe1xhbHBoYS8yfV4yIFxjZG90IHAoMS1wKX17RV4yfQogICAgJCQgRG9uZGUgJHAkIGVzIHVuYSBlc3RpbWFjacOzbiBwcmV2aWEgZGUgbGEgcHJvcG9yY2nDs24gKG8gMC41IHNpIG5vCiAgICBoYXkgZGF0b3MgcHJldmlvcykuCgotICAgKipQYXJhIGxhIHZhcmlhbnphOioqIE3DoXMgY29tcGxlam8sIHJlcXVpZXJlIHRhYmxhcyBkZSBDaGktY3VhZHJhZG8KICAgIG8gc29mdHdhcmUgZXN0YWTDrXN0aWNvLgoKKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKgoKLSAgIERldGVybWluYXIgY3XDoW50b3MgcGFjaWVudGVzIGluY2x1aXIgZW4gdW4gZW5zYXlvIGNsw61uaWNvIHBhcmEKICAgIGVzdGltYXIgbGEgZWZlY3RpdmlkYWQgZGUgdW4gdHJhdGFtaWVudG8gY29uIHVuIG1hcmdlbiBkZSBlcnJvcgogICAgZXNwZWPDrWZpY28uCi0gICAqKkVqZW1wbG86KiogUGFyYSBlc3RpbWFyIGxhIG1lZGlhIGRlIGdsdWNvc2EgY29uIHVuIG1hcmdlbiBkZSBlcnJvcgogICAgZGUgNSBtZy9kTCwgJFxzaWdtYSA9IDIwIFwsIFx0ZXh0e21nL2RMfSQsIHkgOTUlIGRlIGNvbmZpYW56YQogICAgKCR6ID0gMS45NiQpOiAkJAogICAgbiA9IFxsZWZ0KCBcZnJhY3sxLjk2IFxjZG90IDIwfXs1fSBccmlnaHQpXjIgPSA2MS40NyBcYXBwcm94IDYyCiAgICAkJCBTZSBuZWNlc2l0YW4gYWwgbWVub3MgNjIgcGFjaWVudGVzLgoKKipGYWN0b3JlcyBxdWUgYWZlY3RhbiBsYSBwcmVjaXNpw7NuOioqCgotICAgKipOaXZlbCBkZSBjb25maWFuemE6KiogVW4gSUMgYWwgOTklIGVzIG3DoXMgYW1wbGlvIHF1ZSB1bm8gYWwgOTUlLAogICAgcmVxdWlyaWVuZG8gbWF5b3IgJG4kLgotICAgKipWYXJpYWJpbGlkYWQ6KiogTWF5b3IgdmFyaWFuemEgKCRcc2lnbWFeMiQpIHJlcXVpZXJlIG11ZXN0cmFzIG3DoXMKICAgIGdyYW5kZXMuCi0gICAqKk1hcmdlbiBkZSBlcnJvcjoqKiBVbiAkRSQgbcOhcyBwZXF1ZcOxbyBhdW1lbnRhICRuJC4KCioqRWplbXBsbyBwcsOhY3RpY286KiogUGFyYSBlc3RpbWFyIGxhIHByZXZhbGVuY2lhIGRlIG9iZXNpZGFkIGNvbiB1bgptYXJnZW4gZGUgZXJyb3IgZGUgMC4wMiB5ICRwIFxhcHByb3ggMC4zJDogJCQKbiA9IFxmcmFjezEuOTZeMiBcY2RvdCAwLjMgXGNkb3QgMC43fXswLjAyXjJ9IFxhcHByb3ggMjAxNwokJCBTZSBuZWNlc2l0YW4gYXByb3hpbWFkYW1lbnRlIDIwMTcgc3VqZXRvcyBwYXJhIHVuIElDIGFsIDk1JSBjb24gYWx0YQpwcmVjaXNpw7NuLgoKIyMgUmVjdXJzb3MgcGFyYSBlbCBBdXRvZXN0dWRpbyBlbiBTYWx1ZAoKIyMjIExlY3R1cmFzOgoKLSAgICJTdGF0aXN0aWNhbCBNZXRob2RzIGluIE1lZGljYWwgUmVzZWFyY2giIGRlIEFybWl0YWdlLCBCZXJyeSB5CiAgICBNYXR0aGV3cyAoQ2Fww610dWxvcyBzb2JyZSBlc3RpbWFjacOzbikuCi0gICAiQmlvc3RhdGlzdGljczogQSBGb3VuZGF0aW9uIGZvciBBbmFseXNpcyBpbiB0aGUgSGVhbHRoIFNjaWVuY2VzIiBkZQogICAgRGFuaWVsIChDYXDDrXR1bG9zIDYtNykuCgojIyMgRWplcmNpY2lvcyBwcsOhY3RpY29zOgoKLSAgIENhbGN1bGFyIGVzdGltYWRvcmVzIHB1bnR1YWxlcyAoTUxFIHkgbW9tZW50b3MpIHBhcmEgdGFzYXMgZGUKICAgIGluY2lkZW5jaWEgbyBtZWRpYXMgZGUgYmlvbWFyY2Fkb3Jlcy4KLSAgIENvbnN0cnVpciBJQyBwYXJhIG1lZGlhcyB5IHByb3BvcmNpb25lcyB1c2FuZG8gZGF0b3MgZGUgZW5zYXlvcwogICAgY2zDrW5pY29zIChlLmcuLCBiYXNlcyBkZSBkYXRvcyBkZSBsYSBPTVMgbyBDREMpLgotICAgRGV0ZXJtaW5hciB0YW1hw7FvcyBtdWVzdHJhbGVzIHBhcmEgZXN0dWRpb3MgZGUgcHJldmFsZW5jaWEgbyBlbnNheW9zCiAgICBjbMOtbmljb3MuCgojIyMgSGVycmFtaWVudGFzIGNvbXB1dGFjaW9uYWxlczoKCi0gICAqKlI6KiogUGFxdWV0ZXMgc3RhdHMgKHBhcmEgSUMpLCBwd3IgKHRhbWHDsW8gbXVlc3RyYWwpLCBNQVNTIChNTEUpLgotICAgKipQeXRob246KiogTGlicmVyw61hcyBzY2lweS5zdGF0cywgc3RhdHNtb2RlbHMgcGFyYSBjw6FsY3Vsb3MgZGUgSUMgeQogICAgZXN0aW1hY2nDs24uCi0gICAqKkVqZW1wbG8gZW4gUjoqKiBgY29uZmludChsbSh5IH4gMSkpYCBwYXJhIElDIGRlIG1lZGlhczsgZW4gUHl0aG9uOgogICAgYHN0YXRzbW9kZWxzLnN0YXRzLnByb3BvcnRpb24ucHJvcG9ydGlvbl9jb25maW50YC4KCiMjIyBCYXNlcyBkZSBkYXRvczoKCi0gICBOSEFORVMgKE5hdGlvbmFsIEhlYWx0aCBhbmQgTnV0cml0aW9uIEV4YW1pbmF0aW9uIFN1cnZleSkgcGFyYSBkYXRvcwogICAgZGUgYmlvbWFyY2Fkb3Jlcy4KLSAgIEVuc2F5b3MgY2zDrW5pY29zIGVuIENsaW5pY2FsVHJpYWxzLmdvdiBwYXJhIHByYWN0aWNhciBlc3RpbWFjaW9uZXMuCgpgYGB7ciBlc3RpbWFjaW9uLXRhYmxlLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdhc2lzJywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShrbml0cikKbGlicmFyeShrYWJsZUV4dHJhKQoKIyBDcmVhciBsYSB0YWJsYQp0YWJsYV9lc3RpbWFjaW9uIDwtIGRhdGEuZnJhbWUoCiAgIkNvbmNlcHRvIiA9IGMoCiAgICAiRXN0aW1hY2nDs24gUHVudHVhbCIsCiAgICAiRXN0aW1hZG9yIEluc2VzZ2FkbyIsCiAgICAiRWZpY2llbmNpYSIsCiAgICAiQ29uc2lzdGVuY2lhIiwKICAgICJNw6F4aW1hIFZlcm9zaW1pbGl0dWQgKE1MRSkiLAogICAgIk3DqXRvZG8gZGUgbG9zIE1vbWVudG9zIiwKICAgICJJbnRlcnZhbG8gZGUgQ29uZmlhbnphIChJQykiLAogICAgIklDIHBhcmEgbGEgTWVkaWEgKM+DIGRlc2Nvbm9jaWRhKSIsCiAgICAiSUMgcGFyYSBsYSBQcm9wb3JjacOzbiIsCiAgICAiSUMgcGFyYSBsYSBWYXJpYW56YSIsCiAgICAiVGFtYcOxbyBNdWVzdHJhbCAoTWVkaWEpIiwKICAgICJUYW1hw7FvIE11ZXN0cmFsIChQcm9wb3JjacOzbikiCiAgKSwKICAiRGVmaW5pY2nDs24iID0gYygKICAgICJVc2FyIHVuIGVzdGFkw61zdGljbyBtdWVzdHJhbCBwYXJhIGVzdGltYXIgdW4gcGFyw6FtZXRybyBwb2JsYWNpb25hbCAoZS5nLiwgJFxcYmFye3h9JCBlc3RpbWEgJFxcbXUkKS4iLAogICAgIlVuIGVzdGltYWRvciBjb24gJEUoXFxoYXR7XFx0aGV0YX0pID0gXFx0aGV0YSQuIEVqOiAkXFxiYXJ7eH0kIGVzIGluc2VzZ2FkbyBwYXJhICRcXG11JC4iLAogICAgIlVuIGVzdGltYWRvciBlcyBtw6FzIGVmaWNpZW50ZSBzaSB0aWVuZSBtZW5vciB2YXJpYW56YSBlbnRyZSB0b2RvcyBsb3MgaW5zZXNnYWRvcy4iLAogICAgIkVsIGVzdGltYWRvciBjb252ZXJnZSBhbCB2YWxvciB2ZXJkYWRlcm8gY3VhbmRvICRuIFxcdG8gXFxpbmZ0eSQuIiwKICAgICJFc3RpbWFkb3IgcXVlIG1heGltaXphIGxhIHByb2JhYmlsaWRhZCBkZSBvYnNlcnZhciBsb3MgZGF0b3M6ICRMKFxcdGhldGEpID0gXFxwcm9kIGYoeF9pfFxcdGhldGEpJC4iLAogICAgIklndWFsYSBtb21lbnRvcyBtdWVzdHJhbGVzIGEgdGXDs3JpY29zIChlLmcuLCAkXFxiYXJ7eH0gPSBcXG11JCwgJHNeMiA9IFxcc2lnbWFeMiQpLiIsCiAgICAiUmFuZ28gZGUgdmFsb3JlcyBwbGF1c2libGVzIHBhcmEgdW4gcGFyw6FtZXRybywgY29uIHVuIG5pdmVsIGRlIGNvbmZpYW56YSAoZS5nLiwgOTUlKS4iLAogICAgIlVzYSB0IGRlIFN0dWRlbnQ6ICRcXGJhcnt4fSBcXHBtIHRfe1xcYWxwaGEvMixuLTF9IFxcY2RvdCBcXGZyYWN7c317XFxzcXJ0e259fSQuIiwKICAgICJBcHJveGltYWNpw7NuIG5vcm1hbDogJFxcaGF0e3B9IFxccG0gel97XFxhbHBoYS8yfSBcXGNkb3QgXFxzcXJ0e1xcZnJhY3tcXGhhdHtwfSgxLVxcaGF0e3B9KX17bn19JC4iLAogICAgIkJhc2FkbyBlbiAkXFxjaGleMiQ6ICRcXGxlZnQoIFxcZnJhY3sobi0xKXNeMn17XFxjaGleMl97XFxhbHBoYS8yfX0sIFxcZnJhY3sobi0xKXNeMn17XFxjaGleMl97MS1cXGFscGhhLzJ9fSBcXHJpZ2h0KSQuIiwKICAgICIkbiA9IFxcbGVmdCggXFxmcmFje3pfe1xcYWxwaGEvMn0gXFxjZG90IFxcc2lnbWF9e0V9IFxccmlnaHQpXjIkIiwKICAgICIkbiA9IFxcZnJhY3t6X3tcXGFscGhhLzJ9XjIgXFxjZG90IHAoMS1wKX17RV4yfSQiCiAgKSwKICAiRWplbXBsbyBlbiBTYWx1ZCIgPSBjKAogICAgIkVzdGltYXIgbGEgcHJldmFsZW5jaWEgZGUgZGlhYmV0ZXMgdXNhbmRvIGxhIHByb3BvcmNpw7NuIG11ZXN0cmFsICRcXGhhdHtwfSQuIiwKICAgICJMYSBtZWRpYSBkZSBnbHVjb3NhIGVuIDUwIHBhY2llbnRlcyBkaWFiw6l0aWNvcyBlc3RpbWEgbGEgbWVkaWEgcG9ibGFjaW9uYWwgc2luIHNlc2dvLiIsCiAgICAiRW4gdW4gZXN0dWRpbyBkZSBoaXBlcnRlbnNpw7NuLCAkXFxoYXR7cH0kIGVzIG3DoXMgZWZpY2llbnRlIHF1ZSBvdHJvcyBlc3RpbWFkb3Jlcy4iLAogICAgIkEgbWVkaWRhIHF1ZSBzZSBpbmNsdXllbiBtw6FzIHBhY2llbnRlcywgJFxcYmFye3h9JCBzZSBhY2VyY2EgYSAkXFxtdSQuIiwKICAgICJFc3RpbWFyIGxhIHRhc2EgZGUgaW5jaWRlbmNpYSBkZSBtZW5pbmdpdGlzICgkXFxsYW1iZGEkKSBjb24gUG9pc3NvbjogTUxFID0gNSBjYXNvcy9tZXMuIiwKICAgICJFc3RpbWFyICRcXG11JCB5ICRcXHNpZ21hXjIkIGRlIGNvbGVzdGVyb2wgdXNhbmRvICRcXGJhcnt4fSA9IDE5MCQgbWcvZEwgeSAkc14yID0gNDAwJC4iLAogICAgIklDIGRlbCA5NSUgcGFyYSBsYSBtZWRpYSBkZSBwcmVzacOzbiBhcnRlcmlhbDogKDEyNS43LCAxMzQuMykgbW1IZy4iLAogICAgIkVuIDUwIHBhY2llbnRlcywgJFxcYmFye3h9ID0gMTMwJCwgJHMgPSAxNSQ6IElDIOKJiCAoMTI1LjcsIDEzNC4zKSBtZy9kTC4iLAogICAgIkVuIDIwMCBwYWNpZW50ZXMsICRcXGhhdHtwfSA9IDAuMiQ6IElDIDk1JSDiiYggKDAuMTQ1LCAwLjI1NSkuIiwKICAgICJQYXJhICRzXjIgPSAyNSQsICRuID0gMzAkOiBJQyA5NSUgcGFyYSAkXFxzaWdtYV4yJCDiiYggKDE1LjgsIDQ1LjIpIGTDrWFzwrIuIiwKICAgICJDb24gJFxcc2lnbWEgPSAyMCQsICRFID0gNSQsICR6ID0gMS45NiQ6ICRuIFxcYXBwcm94IDYyJCBwYWNpZW50ZXMuIiwKICAgICJDb24gJHAgPSAwLjMkLCAkRSA9IDAuMDIkOiAkbiBcXGFwcHJveCAyMDE3JCBzdWpldG9zLiIKICApLAogIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRQopCgojIE1vc3RyYXIgdGFibGEKa2FibGUodGFibGFfZXN0aW1hY2lvbiwgImh0bWwiLCAKICAgICAgY2FwdGlvbiA9ICJUYWJsYSAyOiBSZXN1bWVuIGRlIG3DqXRvZG9zIGRlIGVzdGltYWNpw7NuIGRlIHBhcsOhbWV0cm9zIGVuIHNhbHVkIikgJT4lCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiLCAicmVzcG9uc2l2ZSIpLCBmdWxsX3dpZHRoID0gRkFMU0UpICU+JQogIHNjcm9sbF9ib3god2lkdGggPSAiMTAwJSIsIGhlaWdodCA9ICI1MDBweCIpCmBgYAoKIyAzLiBQcnVlYmFzIGRlIEhpcMOzdGVzaXMgcGFyYSBlbCBTZWN0b3IgU2FsdWQKCkVzdGUgdGVtYXJpbyBkZXNhcnJvbGxhIGxvcyBjb25jZXB0b3MgZGUgcHJ1ZWJhcyBkZSBoaXDDs3Rlc2lzIGNvbiB1bgplbmZvcXVlIGVuIGFwbGljYWNpb25lcyBlbiBlbCBzZWN0b3Igc2FsdWQsIHByb3BvcmNpb25hbmRvIGV4cGxpY2FjaW9uZXMKZGV0YWxsYWRhcywgZWplbXBsb3MgcHLDoWN0aWNvcyB5IGFwbGljYWNpb25lcyByZWxldmFudGVzIHBhcmEKcHJvZmVzaW9uYWxlcyBtw6lkaWNvcywgaW52ZXN0aWdhZG9yZXMgY2zDrW5pY29zIHkgZXBpZGVtacOzbG9nb3MuIExhcwpwcnVlYmFzIGRlIGhpcMOzdGVzaXMgc29uIGhlcnJhbWllbnRhcyBmdW5kYW1lbnRhbGVzIGVuIGVzdGFkw61zdGljYQppbmZlcmVuY2lhbCBwYXJhIHRvbWFyIGRlY2lzaW9uZXMgYmFzYWRhcyBlbiBkYXRvcyBtdWVzdHJhbGVzLCBldmFsdWFuZG8KYWZpcm1hY2lvbmVzIHNvYnJlIHBhcsOhbWV0cm9zIHBvYmxhY2lvbmFsZXMgKGUuZy4sIGVmZWN0aXZpZGFkIGRlCnRyYXRhbWllbnRvcywgcHJldmFsZW5jaWEgZGUgZW5mZXJtZWRhZGVzKSB5IG1hbmVqYW5kbyBsYSBpbmNlcnRpZHVtYnJlCmluaGVyZW50ZSBhIGxhcyBtdWVzdHJhcy4KCiMjIDMuMSBGdW5kYW1lbnRvcwoKIyMjIEhpcMOzdGVzaXMgTnVsYSB5IEFsdGVybmF0aXZhCgpMYXMgcHJ1ZWJhcyBkZSBoaXDDs3Rlc2lzIGV2YWzDumFuIGFmaXJtYWNpb25lcyBzb2JyZSBwYXLDoW1ldHJvcwpwb2JsYWNpb25hbGVzIGNvbXBhcmFuZG8gZGF0b3MgbXVlc3RyYWxlcyBjb24gdW5hIGhpcMOzdGVzaXMgZXNwZWPDrWZpY2EuCkVuIGVsIHNlY3RvciBzYWx1ZCwgZXN0YXMgcHJ1ZWJhcyBzb24gZXNlbmNpYWxlcyBwYXJhIGRldGVybWluYXIsIHBvcgplamVtcGxvLCBzaSB1biBudWV2byBtZWRpY2FtZW50byBtZWpvcmEgbG9zIHJlc3VsdGFkb3MgY2zDrW5pY29zIG8gc2kgdW5hCmludGVydmVuY2nDs24gcmVkdWNlIGxhIGluY2lkZW5jaWEgZGUgdW5hIGVuZmVybWVkYWQuCgoqKkhpcMOzdGVzaXMgbnVsYSAoKiokSF8wJCk6IEFmaXJtYWNpw7NuIGRlIHF1ZSBubyBoYXkgZWZlY3RvIG8gZGlmZXJlbmNpYQplbiBsYSBwb2JsYWNpw7NuLiBSZXByZXNlbnRhIGVsIHN0YXR1IHF1byBvIGxhIGF1c2VuY2lhIGRlIGNhbWJpby4gUG9yCmVqZW1wbG8sICRIXzA6IFxtdSA9IDEyMCBcLCBcdGV4dHttbUhnfSQgKGxhIG1lZGlhIGRlIHByZXNpw7NuIGFydGVyaWFsCm5vIGNhbWJpYSBjb24gdW4gdHJhdGFtaWVudG8pLgoKLSAgIEVuIHNhbHVkLCAkSF8wJCBzdWVsZSBhc3VtaXIgcXVlIHVuIHRyYXRhbWllbnRvIG5vIGVzIGVmZWN0aXZvIG8gcXVlCiAgICBubyBoYXkgZGlmZXJlbmNpYXMgZW50cmUgZ3J1cG9zLgoKKipIaXDDs3Rlc2lzIGFsdGVybmF0aXZhICgqKiRIXzEkIG8gJEhfYSQpOiBBZmlybWFjacOzbiBvcHVlc3RhIGEgJEhfMCQsCnF1ZSBzdWdpZXJlIHVuIGVmZWN0byBvIGRpZmVyZW5jaWEuIFB1ZWRlIHNlcjoKCi0gICAqKlVuaWxhdGVyYWw6KiogJEhfMTogXG11ID4gMTIwJCBvICRIXzE6IFxtdSA8IDEyMCQgKGUuZy4sIGVsCiAgICB0cmF0YW1pZW50byByZWR1Y2UgbGEgcHJlc2nDs24gYXJ0ZXJpYWwpLgotICAgKipCaWxhdGVyYWw6KiogJEhfMTogXG11IFxuZXEgMTIwJCAoZS5nLiwgZWwgdHJhdGFtaWVudG8gYWZlY3RhIGxhCiAgICBwcmVzacOzbiBhcnRlcmlhbCwgc2luIGVzcGVjaWZpY2FyIGxhIGRpcmVjY2nDs24pLgoKKipFamVtcGxvIHByw6FjdGljbzoqKiBFbiB1biBlbnNheW8gY2zDrW5pY28sICRIXzAkOiAiRWwgbnVldm8gZsOhcm1hY28gbm8KcmVkdWNlIGxhIGdsdWNvc2EgZW4gc2FuZ3JlCigkXG11X3tcdGV4dHt0cmF0YW1pZW50b319ID0gXG11X3tcdGV4dHtwbGFjZWJvfX0kKSIsIGZyZW50ZSBhICRIXzEkOgoiRWwgZsOhcm1hY28gcmVkdWNlIGxhIGdsdWNvc2EKKCRcbXVfe1x0ZXh0e3RyYXRhbWllbnRvfX0gPCBcbXVfe1x0ZXh0e3BsYWNlYm99fSQpIi4KCiMjIyBFcnJvcmVzIFRpcG8gSSB5IFRpcG8gSUkKCkxhcyBwcnVlYmFzIGRlIGhpcMOzdGVzaXMgaW1wbGljYW4gcmllc2dvcyBkZSB0b21hciBkZWNpc2lvbmVzCmluY29ycmVjdGFzIGRlYmlkbyBhIGxhIHZhcmlhYmlsaWRhZCBtdWVzdHJhbC4KCioqRXJyb3IgVGlwbyBJICgqKiRcYWxwaGEkKTogUmVjaGF6YXIgJEhfMCQgY3VhbmRvIGVzIHZlcmRhZGVyYSAoZmFsc28KcG9zaXRpdm8pLgoKLSAgICoqUHJvYmFiaWxpZGFkOioqICRcYWxwaGEkLCBjb25vY2lkYSBjb21vIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEuCi0gICAqKkVuIHNhbHVkOioqIERpYWdub3N0aWNhciBlcnLDs25lYW1lbnRlIHF1ZSB1biB0cmF0YW1pZW50byBlcwogICAgZWZlY3Rpdm8gY3VhbmRvIG5vIGxvIGVzIChlLmcuLCBhcHJvYmFyIHVuIGbDoXJtYWNvIGluZWZpY2F6KS4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogQ29uY2x1aXIgcXVlIHVuYSB2YWN1bmEgcHJldmllbmUgZWwgQ09WSUQtMTkKICAgICgkSF8wJCByZWNoYXphZGEpIGN1YW5kbyBlbiByZWFsaWRhZCBubyBsbyBoYWNlLCBjb24gcHJvYmFiaWxpZGFkCiAgICAkXGFscGhhID0gMC4wNSQuCgoqKkVycm9yIFRpcG8gSUkgKCoqJFxiZXRhJCk6IE5vIHJlY2hhemFyICRIXzAkIGN1YW5kbyBlcyBmYWxzYSAoZmFsc28KbmVnYXRpdm8pLgoKLSAgICoqUHJvYmFiaWxpZGFkOioqICRcYmV0YSQsIHJlbGFjaW9uYWRhIGNvbiBsYSBwb3RlbmNpYSBkZSBsYSBwcnVlYmEKICAgICgkMSAtIFxiZXRhJCkuCi0gICAqKkVuIHNhbHVkOioqIE5vIGRldGVjdGFyIHVuIGVmZWN0byByZWFsIGRlIHVuIHRyYXRhbWllbnRvIChlLmcuLAogICAgZGVzY2FydGFyIHVuIGbDoXJtYWNvIGVmZWN0aXZvKS4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogTm8gZGV0ZWN0YXIgcXVlIHVuIG51ZXZvIHRyYXRhbWllbnRvIHJlZHVjZQogICAgc2lnbmlmaWNhdGl2YW1lbnRlIGxvcyBuaXZlbGVzIGRlIGNvbGVzdGVyb2wsIHBlcmRpZW5kbyB1bmEKICAgIG9wb3J0dW5pZGFkIHRlcmFww6l1dGljYS4KCioqUmVsYWNpw7NuIGVudHJlIGVycm9yZXM6KiogUmVkdWNpciAkXGFscGhhJCAoZS5nLiwgZGUgMC4wNSBhIDAuMDEpCmF1bWVudGEgJFxiZXRhJCwgeSB2aWNldmVyc2EsIGEgbWVub3MgcXVlIHNlIGF1bWVudGUgZWwgdGFtYcOxbyBtdWVzdHJhbC4KCiMjIyBOaXZlbCBkZSBTaWduaWZpY2FuY2lhIHkgUG90ZW5jaWEgZGUgbGEgUHJ1ZWJhCgoqKk5pdmVsIGRlIHNpZ25pZmljYW5jaWEgKCoqJFxhbHBoYSQpOiBQcm9iYWJpbGlkYWQgZGUgY29tZXRlciB1biBlcnJvcgpUaXBvIEksIHTDrXBpY2FtZW50ZSAwLjA1ICg1JSkgbyAwLjAxICgxJSkgZW4gZXN0dWRpb3MgY2zDrW5pY29zLgoKLSAgIFJlcHJlc2VudGEgZWwgdW1icmFsIHBhcmEgcmVjaGF6YXIgJEhfMCQuIFVuIHZhbG9yIHAgbWVub3IgcXVlCiAgICAkXGFscGhhJCBpbmRpY2EgZXZpZGVuY2lhIHN1ZmljaWVudGUgcGFyYSByZWNoYXphciAkSF8wJC4KLSAgICoqRW4gc2FsdWQ6KiogVW4gJFxhbHBoYSA9IDAuMDUkIGltcGxpY2EgcXVlIGhheSB1biA1JSBkZQogICAgcHJvYmFiaWxpZGFkIGRlIHJlY2hhemFyIGVycsOzbmVhbWVudGUgJEhfMCQsIHVuIGVzdMOhbmRhciBjb23Dum4gZW4KICAgIGVuc2F5b3MgY2zDrW5pY29zLgoKKipQb3RlbmNpYSBkZSBsYSBwcnVlYmEgKCoqJDEgLSBcYmV0YSQpOiBQcm9iYWJpbGlkYWQgZGUgcmVjaGF6YXIgJEhfMCQKY3VhbmRvICRIXzEkIGVzIHZlcmRhZGVyYSwgZXMgZGVjaXIsIGRldGVjdGFyIHVuIGVmZWN0byByZWFsLgoKLSAgICoqRGVwZW5kZSBkZToqKgogICAgLSAgIFRhbWHDsW8gZGVsIGVmZWN0byAoZGlmZXJlbmNpYSBlbnRyZSAkSF8wJCB5ICRIXzEkKS4KICAgIC0gICBUYW1hw7FvIG11ZXN0cmFsICgkbiQpLgogICAgLSAgIFZhcmlhbnphIGRlIGxvcyBkYXRvcy4KICAgIC0gICBOaXZlbCBkZSBzaWduaWZpY2FuY2lhICgkXGFscGhhJCkuCi0gICAqKkVuIHNhbHVkOioqIFVuYSBwb3RlbmNpYSBkZSAwLjggKDgwJSkgbyBtYXlvciBlcyBkZXNlYWJsZSBwYXJhCiAgICBnYXJhbnRpemFyIHF1ZSBsb3MgZW5zYXlvcyBjbMOtbmljb3MgZGV0ZWN0ZW4gZWZlY3RvcyBjbMOtbmljYW1lbnRlCiAgICByZWxldmFudGVzLgotICAgKipFamVtcGxvIHByw6FjdGljbzoqKiBFbiB1biBlbnNheW8gcGFyYSBldmFsdWFyIHVuIGbDoXJtYWNvCiAgICBhbnRpaGlwZXJ0ZW5zaXZvLCB1bmEgcG90ZW5jaWEgZGUgMC45IGFzZWd1cmEgdW4gOTAlIGRlIHByb2JhYmlsaWRhZAogICAgZGUgZGV0ZWN0YXIgdW5hIHJlZHVjY2nDs24gZGUgMTAgbW1IZyBlbiBsYSBwcmVzacOzbiBhcnRlcmlhbCBzaSBlc3RhCiAgICBleGlzdGUuCgoqKkPDoWxjdWxvIGRlIGxhIHBvdGVuY2lhOioqCgotICAgVXNhIHNvZnR3YXJlIGNvbW8gUiAocHdyKSBvIGbDs3JtdWxhcyBlc3BlY8OtZmljYXMgYmFzYWRhcyBlbiBsYQogICAgZGlzdHJpYnVjacOzbiAoZS5nLiwgbm9ybWFsLCB0KS4KLSAgICoqRWplbXBsbzoqKiBQYXJhIHVuYSBwcnVlYmEgdCBkZSB1bmEgbWVkaWEgY29uIHRhbWHDsW8gZGVsIGVmZWN0bwogICAgJGQgPSBcZnJhY3tcbXVfMSAtIFxtdV8wfXtcc2lnbWF9ID0gMC41JCwgJFxhbHBoYSA9IDAuMDUkLCB5CiAgICAkbiA9IDUwJCwgbGEgcG90ZW5jaWEgc2UgY2FsY3VsYSBudW3DqXJpY2FtZW50ZS4KCiMjIDMuMiBQcnVlYmFzIFBhcmFtw6l0cmljYXMKCkxhcyBwcnVlYmFzIHBhcmFtw6l0cmljYXMgYXN1bWVuIHF1ZSBsb3MgZGF0b3Mgc2lndWVuIHVuYSBkaXN0cmlidWNpw7NuCmVzcGVjw61maWNhIChnZW5lcmFsbWVudGUgbm9ybWFsKSB5IHNvbiBhZGVjdWFkYXMgcGFyYSB2YXJpYWJsZXMKY29udGludWFzIG8gZGlzY3JldGFzIGNvbiBtdWVzdHJhcyBncmFuZGVzLgoKIyMjIFBydWViYXMgcGFyYSB1bmEgeSBkb3MgbWVkaWFzICh0LXRlc3QsIHotdGVzdCkKCioqUHJ1ZWJhIHogcGFyYSB1bmEgbWVkaWE6KioKCi0gICAqKlVzbzoqKiBDb21wYXJhciBsYSBtZWRpYSBtdWVzdHJhbCAoJFxiYXJ7eH0kKSBjb24gdW5hIG1lZGlhCiAgICBwb2JsYWNpb25hbCBjb25vY2lkYSAoJFxtdV8wJCkgY3VhbmRvIGxhIHZhcmlhbnphIHBvYmxhY2lvbmFsCiAgICAoJFxzaWdtYV4yJCkgZXMgY29ub2NpZGEgeSAkbiBcZ2VxIDMwJC4KLSAgICoqRXN0YWTDrXN0aWNvOioqICQkCiAgICB6ID0gXGZyYWN7XGJhcnt4fSAtIFxtdV8wfXtcc2lnbWEgLyBcc3FydHtufX0KICAgICQkIENvbXBhcmFkbyBjb24gdmFsb3JlcyBjcsOtdGljb3MgZGUgbGEgbm9ybWFsIGVzdMOhbmRhciAoZS5nLiwKICAgICRccG0gMS45NiQgcGFyYSAkXGFscGhhID0gMC4wNSQsIGJpbGF0ZXJhbCkuCi0gICAqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIEV2YWx1YXIgc2kgbGEgbWVkaWEgZGUgZ2x1Y29zYSBlbiBzYW5ncmUgZGUKICAgIHVuIGdydXBvIGRlIHBhY2llbnRlcyAoJFxiYXJ7eH0gPSAxMjUgXCwgXHRleHR7bWcvZEx9JCkgZGlmaWVyZSBkZQogICAgdW4gZXN0w6FuZGFyIGNsw61uaWNvICgkXG11XzAgPSAxMjAgXCwgXHRleHR7bWcvZEx9JCkuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuYSBtdWVzdHJhIGRlIDEwMCBwYWNpZW50ZXMsIGNvbgogICAgJFxzaWdtYSA9IDE1JCwgJFxiYXJ7eH0gPSAxMjUkLCB5ICRcbXVfMCA9IDEyMCQsIGVsIGVzdGFkw61zdGljbyBlczoKICAgICQkCiAgICB6ID0gXGZyYWN7MTI1IC0gMTIwfXsxNSAvIFxzcXJ0ezEwMH19ID0gMy4zMwogICAgJCQgQ29tbyAkeiA+IDEuOTYkLCBzZSByZWNoYXphICRIXzAkICgkcCA8IDAuMDUkKS4KCioqUHJ1ZWJhIHQgcGFyYSB1bmEgbWVkaWE6KioKCi0gICAqKlVzbzoqKiBJZ3VhbCBxdWUgbGEgei10ZXN0LCBwZXJvIGN1YW5kbyAkXHNpZ21hXjIkIGVzIGRlc2Nvbm9jaWRhCiAgICBvICRuIDwgMzAkLCBhc3VtaWVuZG8gbm9ybWFsaWRhZC4KLSAgICoqRXN0YWTDrXN0aWNvOioqICQkCiAgICB0ID0gXGZyYWN7XGJhcnt4fSAtIFxtdV8wfXtzIC8gXHNxcnR7bn19CiAgICAkJCBEb25kZSAkcyQgZXMgbGEgZGVzdmlhY2nDs24gZXN0w6FuZGFyIG11ZXN0cmFsLCB5IHNlIHVzYSBsYQogICAgZGlzdHJpYnVjacOzbiB0IGNvbiAkbi0xJCBncmFkb3MgZGUgbGliZXJ0YWQuCi0gICAqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIENvbXBhcmFyIGVsIHRpZW1wbyBwcm9tZWRpbyBkZSByZWN1cGVyYWNpw7NuCiAgICB0cmFzIHVuYSBjaXJ1Z8OtYSBjb24gdW4gZXN0w6FuZGFyLgotICAgKipFamVtcGxvIHByw6FjdGljbzoqKiBFbiAyMCBwYWNpZW50ZXMsIGVsIHRpZW1wbyBkZSByZWN1cGVyYWNpw7NuIGVzCiAgICAkXGJhcnt4fSA9IDEwIFwsIFx0ZXh0e2TDrWFzfSQsICRzID0gMiBcLCBcdGV4dHtkw61hc30kLCB5IHNlIGNvbXBhcmEKICAgIGNvbiAkXG11XzAgPSA5IFwsIFx0ZXh0e2TDrWFzfSQuIEVsIGVzdGFkw61zdGljbyBlczogJCQKICAgIHQgPSBcZnJhY3sxMCAtIDl9ezIgLyBcc3FydHsyMH19ID0gMi4yNAogICAgJCQgQ29uICR0X3swLjAyNSwgMTl9IFxhcHByb3ggMi4wOTMkLCBzZSByZWNoYXphICRIXzAkIHNpCiAgICAkcCA8IDAuMDUkLgoKKipQcnVlYmEgdCBwYXJhIGRvcyBtZWRpYXM6KioKCi0gICAqKlVzbzoqKiBDb21wYXJhciBsYXMgbWVkaWFzIGRlIGRvcyBncnVwb3MgaW5kZXBlbmRpZW50ZXMKICAgICgkXG11XzEgXG5lcSBcbXVfMiQpIG8gcGFyZWFkb3MuCi0gICAqKkVzdGFkw61zdGljbyAoaW5kZXBlbmRpZW50ZXMpOioqICQkCiAgICB0ID0gXGZyYWN7XGJhcnt4fV8xIC0gXGJhcnt4fV8yfXtcc3FydHtcZnJhY3tzXzFeMn17bl8xfSArIFxmcmFje3NfMl4yfXtuXzJ9fX0KICAgICQkIEFzdW1pZW5kbyB2YXJpYW56YXMgaWd1YWxlcyAobyB1c2FuZG8gbGEgY29ycmVjY2nDs24gZGUgV2VsY2ggc2kKICAgIG5vKS4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogQ29tcGFyYXIgbGEgcHJlc2nDs24gYXJ0ZXJpYWwgZW50cmUgdW4gZ3J1cG8KICAgIHRyYXRhZG8geSB1biBncnVwbyBwbGFjZWJvLgotICAgKipFamVtcGxvIHByw6FjdGljbzoqKiBFbiB1biBlbnNheW8gY2zDrW5pY28sIGVsIGdydXBvIHRyYXRhZG8KICAgICgkbl8xID0gNTAkLCAkXGJhcnt4fV8xID0gMTE1IFwsIFx0ZXh0e21tSGd9JCwgJHNfMSA9IDEwJCkgeSBlbAogICAgZ3J1cG8gcGxhY2VibyAoJG5fMiA9IDUwJCwgJFxiYXJ7eH1fMiA9IDEyMCBcLCBcdGV4dHttbUhnfSQsCiAgICAkc18yID0gMTIkKSB0aWVuZW46ICQkCiAgICB0ID0gXGZyYWN7MTE1IC0gMTIwfXtcc3FydHtcZnJhY3sxMF4yfXs1MH0gKyBcZnJhY3sxMl4yfXs1MH19fSBcYXBwcm94IC0yLjE0CiAgICAkJCBDb21wYXJhZG8gY29uICR0X3swLjAyNSwgOTh9IFxhcHByb3ggMS45OCQsIHNlIHJlY2hhemEgJEhfMCQuCgojIyMgUHJ1ZWJhcyBwYXJhIFByb3BvcmNpb25lcwoKKipQcnVlYmEgeiBwYXJhIHVuYSBwcm9wb3JjacOzbjoqKgoKLSAgICoqVXNvOioqIENvbXBhcmFyIHVuYSBwcm9wb3JjacOzbiBtdWVzdHJhbCAoJFxoYXR7cH0kKSBjb24gdW5hCiAgICBwcm9wb3JjacOzbiBwb2JsYWNpb25hbCAoJHBfMCQpLCBhc3VtaWVuZG8gJG4gXGhhdHtwfSBcZ2VxIDUkLAogICAgJG4oMS1caGF0e3B9KSBcZ2VxIDUkLgotICAgKipFc3RhZMOtc3RpY286KiogJCQKICAgIHogPSBcZnJhY3tcaGF0e3B9IC0gcF8wfXtcc3FydHtcZnJhY3twXzAgKDEtcF8wKX17bn19fQogICAgJCQKLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogRXZhbHVhciBzaSBsYSBwcmV2YWxlbmNpYSBkZSB1bmEgZW5mZXJtZWRhZAogICAgZGlmaWVyZSBkZSB1biB2YWxvciBlc3BlcmFkby4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogU2kgJHBfMCA9IDAuMSQgKHByZXZhbGVuY2lhIGVzcGVyYWRhIGRlCiAgICBkaWFiZXRlcyksIHkgZW4gMjAwIHBhY2llbnRlcyAkXGhhdHtwfSA9IDAuMTQkLCBlbCBlc3RhZMOtc3RpY28gZXM6CiAgICAkJAogICAgeiA9IFxmcmFjezAuMTQgLSAwLjF9e1xzcXJ0e1xmcmFjezAuMSBcY2RvdCAwLjl9ezIwMH19fSBcYXBwcm94IDEuODkKICAgICQkIENvbiAkel97MC4wMjV9ID0gMS45NiQsIG5vIHNlIHJlY2hhemEgJEhfMCQgKCRwID4gMC4wNSQpLgoKKipQcnVlYmEgeiBwYXJhIGRvcyBwcm9wb3JjaW9uZXM6KioKCi0gICAqKlVzbzoqKiBDb21wYXJhciBwcm9wb3JjaW9uZXMgZW50cmUgZG9zIGdydXBvcyAoJHBfMSBcbmVxIHBfMiQpLgotICAgKipFc3RhZMOtc3RpY286KiogJCQKICAgIHogPSBcZnJhY3tcaGF0e3B9XzEgLSBcaGF0e3B9XzJ9e1xzcXJ0e1xoYXR7cH0oMS1caGF0e3B9KSBcbGVmdCggXGZyYWN7MX17bl8xfSArIFxmcmFjezF9e25fMn0gXHJpZ2h0KX19CiAgICAkJCBEb25kZSAkXGhhdHtwfSA9IFxmcmFje3hfMSArIHhfMn17bl8xICsgbl8yfSQgZXMgbGEgcHJvcG9yY2nDs24KICAgIGNvbWJpbmFkYS4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogQ29tcGFyYXIgdGFzYXMgZGUgcmVzcHVlc3RhIGVudHJlIGRvcwogICAgdHJhdGFtaWVudG9zLgotICAgKipFamVtcGxvIHByw6FjdGljbzoqKiBFbiB1biBlbnNheW8sIDMwIGRlIDEwMCBwYWNpZW50ZXMgdHJhdGFkb3MKICAgIHJlc3BvbmRlbiAoJFxoYXR7cH1fMSA9IDAuMyQpLCB5IDIwIGRlIDEwMCBlbiBwbGFjZWJvCiAgICAoJFxoYXR7cH1fMiA9IDAuMiQpLiBDb24gJFxoYXR7cH0gPSBcZnJhY3szMCsyMH17MTAwKzEwMH0gPSAwLjI1JDoKICAgICQkCiAgICB6ID0gXGZyYWN7MC4zIC0gMC4yfXtcc3FydHswLjI1IFxjZG90IDAuNzUgXGxlZnQoIFxmcmFjezF9ezEwMH0gKyBcZnJhY3sxfXsxMDB9IFxyaWdodCl9fSBcYXBwcm94IDEuNjMKICAgICQkIE5vIHNlIHJlY2hhemEgJEhfMCQgKCRwID4gMC4wNSQpLgoKIyMjIFBydWViYXMgcGFyYSBWYXJpYW56YXMgKENoaS1jdWFkcmFkbywgRikKCioqUHJ1ZWJhIENoaS1jdWFkcmFkbyBwYXJhIHVuYSB2YXJpYW56YToqKgoKLSAgICoqVXNvOioqIENvbXBhcmFyIGxhIHZhcmlhbnphIG11ZXN0cmFsICgkc14yJCkgY29uIHVuYSB2YXJpYW56YQogICAgcG9ibGFjaW9uYWwgKCRcc2lnbWFfMF4yJCksIGFzdW1pZW5kbyBub3JtYWxpZGFkLgotICAgKipFc3RhZMOtc3RpY286KiogJCQKICAgIFxjaGleMiA9IFxmcmFjeyhuLTEpc14yfXtcc2lnbWFfMF4yfQogICAgJCQgQ29uICRuLTEkIGdyYWRvcyBkZSBsaWJlcnRhZC4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogRXZhbHVhciBsYSB2YXJpYWJpbGlkYWQgZW4gdGllbXBvcyBkZQogICAgcmVjdXBlcmFjacOzbi4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogUGFyYSAkbiA9IDMwJCwgJHNeMiA9IDI1IFwsIFx0ZXh0e2TDrWFzfV4yJCwgeQogICAgJFxzaWdtYV8wXjIgPSAyMCQ6ICQkCiAgICBcY2hpXjIgPSBcZnJhY3syOSBcY2RvdCAyNX17MjB9ID0gMzYuMjUKICAgICQkIENvbXBhcmFkbyBjb24gJFxjaGleMl97MC4wMjUsIDI5fSBcYXBwcm94IDQ1LjcyJCB5CiAgICAkXGNoaV4yX3swLjk3NSwgMjl9IFxhcHByb3ggMTYuMDUkLCBubyBzZSByZWNoYXphICRIXzAkLgoKKipQcnVlYmEgRiBwYXJhIGRvcyB2YXJpYW56YXM6KioKCi0gICAqKlVzbzoqKiBDb21wYXJhciB2YXJpYW56YXMgZGUgZG9zIGdydXBvcwogICAgKCRcc2lnbWFfMV4yIFxuZXEgXHNpZ21hXzJeMiQpLgotICAgKipFc3RhZMOtc3RpY286KiogJCQKICAgIEYgPSBcZnJhY3tzXzFeMn17c18yXjJ9CiAgICAkJCBDb24gZ3JhZG9zIGRlIGxpYmVydGFkICRuXzEtMSQgeSAkbl8yLTEkLgotICAgKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBDb21wYXJhciBsYSB2YXJpYWJpbGlkYWQgZW4gbml2ZWxlcyBkZQogICAgY29sZXN0ZXJvbCBlbnRyZSBkb3MgZ3J1cG9zIGRlIHRyYXRhbWllbnRvLgotICAgKipFamVtcGxvIHByw6FjdGljbzoqKiBQYXJhIGdydXBvIDEgKCRuXzEgPSA0MCQsICRzXzFeMiA9IDEwMCQpIHkKICAgIGdydXBvIDIgKCRuXzIgPSA1MCQsICRzXzJeMiA9IDgwJCk6ICQkCiAgICBGID0gXGZyYWN7MTAwfXs4MH0gPSAxLjI1CiAgICAkJCBDb21wYXJhZG8gY29uIHZhbG9yZXMgY3LDrXRpY29zIGRlIGxhIGRpc3RyaWJ1Y2nDs24gRiwgbm8gc2UKICAgIHJlY2hhemEgJEhfMCQuCgojIyAzLjMgUHJ1ZWJhcyBObyBQYXJhbcOpdHJpY2FzCgpMYXMgcHJ1ZWJhcyBubyBwYXJhbcOpdHJpY2FzIG5vIGFzdW1lbiBub3JtYWxpZGFkIHkgc29uIMO6dGlsZXMgcGFyYSBkYXRvcwpvcmRpbmFsZXMsIG5vIG5vcm1hbGVzIG8gY29uIG11ZXN0cmFzIHBlcXVlw7Fhcy4KCiMjIyBQcnVlYmEgZGUgV2lsY294b24sIE1hbm4tV2hpdG5leSwgS3J1c2thbC1XYWxsaXMKCioqUHJ1ZWJhIGRlIFdpbGNveG9uIChwYXJlYWRhKToqKgoKLSAgICoqVXNvOioqIENvbXBhcmFyIGRvcyBtdWVzdHJhcyBwYXJlYWRhcyAoZS5nLiwgYW50ZXMgeSBkZXNwdcOpcyBkZSB1bgogICAgdHJhdGFtaWVudG8pIGN1YW5kbyBsb3MgZGF0b3Mgbm8gc29uIG5vcm1hbGVzLgotICAgKipNw6l0b2RvOioqIENhbGN1bGEgZGlmZXJlbmNpYXMsIG9yZGVuYSBwb3IgcmFuZ29zIGFic29sdXRvcyB5CiAgICBjb21wYXJhIGxhIHN1bWEgZGUgcmFuZ29zIHBvc2l0aXZvcyB5IG5lZ2F0aXZvcy4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogRXZhbHVhciBzaSB1biB0cmF0YW1pZW50byByZWR1Y2UgZWwgZG9sb3IKICAgIChlc2NhbGEgb3JkaW5hbCkgZW4gbG9zIG1pc21vcyBwYWNpZW50ZXMuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIDEwIHBhY2llbnRlcywgbGFzIGRpZmVyZW5jaWFzIGVuIHB1bnRhamVzCiAgICBkZSBkb2xvciBhbnRlcyB5IGRlc3B1w6lzIHNvbiBvcmRlbmFkYXMsIHkgZWwgZXN0YWTDrXN0aWNvIGRlIFdpbGNveG9uCiAgICBkZXRlcm1pbmEgc2kgaGF5IHVuIGNhbWJpbyBzaWduaWZpY2F0aXZvLgoKKipQcnVlYmEgZGUgTWFubi1XaGl0bmV5IFU6KioKCi0gICAqKlVzbzoqKiBDb21wYXJhciBkb3MgZ3J1cG9zIGluZGVwZW5kaWVudGVzIGN1YW5kbyBsb3MgZGF0b3Mgbm8gc29uCiAgICBub3JtYWxlcy4KLSAgICoqTcOpdG9kbzoqKiBDb21iaW5hIGxhcyBvYnNlcnZhY2lvbmVzLCBhc2lnbmEgcmFuZ29zIHkgY2FsY3VsYSBlbAogICAgZXN0YWTDrXN0aWNvICRVJC4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogQ29tcGFyYXIgdGllbXBvcyBkZSByZWN1cGVyYWNpw7NuIGVudHJlIGRvcwogICAgZ3J1cG9zIGRlIHBhY2llbnRlcy4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogQ29tcGFyYXIgZWwgdGllbXBvIGRlIHJlY3VwZXJhY2nDs24gZW50cmUKICAgIHBhY2llbnRlcyBjb24gZG9zIHRyYXRhbWllbnRvcyBkaWZlcmVudGVzLCB1c2FuZG8gcmFuZ29zIHBhcmEgZXZpdGFyCiAgICBzdXB1ZXN0b3MgZGUgbm9ybWFsaWRhZC4KCioqUHJ1ZWJhIGRlIEtydXNrYWwtV2FsbGlzOioqCgotICAgKipVc286KiogQ29tcGFyYXIgbcOhcyBkZSBkb3MgZ3J1cG9zIGluZGVwZW5kaWVudGVzIChleHRlbnNpw7NuIGRlCiAgICBNYW5uLVdoaXRuZXkpLgotICAgKipNw6l0b2RvOioqIEFzaWduYSByYW5nb3MgYSB0b2RhcyBsYXMgb2JzZXJ2YWNpb25lcyB5IGNvbXBhcmEgbGFzCiAgICBzdW1hcyBkZSByYW5nb3MgZW50cmUgZ3J1cG9zLgotICAgKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBDb21wYXJhciBsYSBzZXZlcmlkYWQgZGUgc8OtbnRvbWFzIGVudHJlCiAgICB0cmVzIGdydXBvcyBkZSB0cmF0YW1pZW50by4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogRXZhbHVhciBzaSB0cmVzIG1lZGljYW1lbnRvcyBwcm9kdWNlbgogICAgZGlmZXJlbmNpYXMgZW4gbGEgZXNjYWxhIGRlIGRvbG9yIGVuIHBhY2llbnRlcyBjb24gYXJ0cml0aXMuCgojIyMgUHJ1ZWJhIGRlIFNpZ25vcyB5IFJhbmdvcwoKKipQcnVlYmEgZGUgc2lnbm9zOioqCgotICAgKipVc286KiogQ29tcGFyYXIgbXVlc3RyYXMgcGFyZWFkYXMgY29udGFuZG8gc2lnbm9zIGRlIGRpZmVyZW5jaWFzCiAgICAocG9zaXRpdmFzIG8gbmVnYXRpdmFzKS4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogRXZhbHVhciBzaSB1biB0cmF0YW1pZW50byBtZWpvcmEgdW4gc8OtbnRvbWEKICAgIChlLmcuLCBtw6FzIHBhY2llbnRlcyBtZWpvcmFuIHF1ZSBlbXBlb3JhbikuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIDIwIHBhY2llbnRlcywgMTUgbWVqb3JhbiB5IDUgZW1wZW9yYW4gdHJhcwogICAgdW4gdHJhdGFtaWVudG8uIExhIHBydWViYSBkZSBzaWdub3MgZXZhbMO6YSBzaSBsYSBwcm9wb3JjacOzbiBkZQogICAgbWVqb3JhcyBlcyBzaWduaWZpY2F0aXZhLgoKKipQcnVlYmEgZGUgcmFuZ29zIGNvbiBzaWdubyBkZSBXaWxjb3hvbjoqKiBDb21iaW5hIHNpZ25vcyB5IG1hZ25pdHVkZXMKKHJhbmdvcykgcGFyYSBtYXlvciBzZW5zaWJpbGlkYWQgcXVlIGxhIHBydWViYSBkZSBzaWdub3MuCgotICAgKipFamVtcGxvIHByw6FjdGljbzoqKiBDb21wYXJhciBuaXZlbGVzIGRlIGdsdWNvc2EgYW50ZXMgeSBkZXNwdcOpcyBkZQogICAgdW4gdHJhdGFtaWVudG8gZW4gMTUgcGFjaWVudGVzIGNvbiBkYXRvcyBubyBub3JtYWxlcy4KCiMjIyBWZW50YWphcyB5IExpbWl0YWNpb25lcwoKKipWZW50YWphcyBkZSBwcnVlYmFzIG5vIHBhcmFtw6l0cmljYXM6KioKCi0gICBObyByZXF1aWVyZW4gc3VwdWVzdG9zIGRlIG5vcm1hbGlkYWQgbyB2YXJpYW56YXMgaWd1YWxlcywgaWRlYWxlcwogICAgcGFyYSBkYXRvcyBvcmRpbmFsZXMgbyBubyBub3JtYWxlcyAoZS5nLiwgZXNjYWxhcyBkZSBkb2xvciwgdGllbXBvcwogICAgZGUgcmVjdXBlcmFjacOzbiBzZXNnYWRvcykuCi0gICBSb2J1c3RhcyBmcmVudGUgYSB2YWxvcmVzIGF0w61waWNvcy4KLSAgIMOadGlsZXMgZW4gbXVlc3RyYXMgcGVxdWXDsWFzIG8gZGF0b3MgY2F0ZWfDs3JpY29zLgoKKipMaW1pdGFjaW9uZXM6KioKCi0gICBNZW5vcyBwb3RlbmNpYSBxdWUgbGFzIHBydWViYXMgcGFyYW3DqXRyaWNhcyBjdWFuZG8gbG9zIHN1cHVlc3RvcyBkZQogICAgZXN0YXMgc2UgY3VtcGxlbi4KLSAgIE1lbm9zIHByZWNpc2FzIHBhcmEgZGV0ZWN0YXIgZGlmZXJlbmNpYXMgcGVxdWXDsWFzLgotICAgSW50ZXJwcmV0YWNpw7NuIG1lbm9zIGRpcmVjdGEgZW4gdMOpcm1pbm9zIGRlIHBhcsOhbWV0cm9zCiAgICBwb2JsYWNpb25hbGVzLgoKKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBMYXMgcHJ1ZWJhcyBubyBwYXJhbcOpdHJpY2FzIHNvbiBwcmVmZXJpZGFzIGVuCmVzdHVkaW9zIGNvbiBlc2NhbGFzIG9yZGluYWxlcyAoZS5nLiwgc2F0aXNmYWNjacOzbiBkZWwgcGFjaWVudGUpIG8gZGF0b3MKbm8gbm9ybWFsZXMgKGUuZy4sIHRpZW1wb3MgZGUgZXNwZXJhIGVuIHVyZ2VuY2lhcykuCgojIyBSZWN1cnNvcyBwYXJhIGVsIEF1dG9lc3R1ZGlvIGVuIFNhbHVkCgojIyMgTGVjdHVyYXM6CgotICAgIlN0YXRpc3RpY2FsIE1ldGhvZHMgaW4gTWVkaWNhbCBSZXNlYXJjaCIgZGUgQXJtaXRhZ2UsIEJlcnJ5IHkKICAgIE1hdHRoZXdzIChDYXDDrXR1bG9zIHNvYnJlIHBydWViYXMgZGUgaGlww7N0ZXNpcykuCi0gICAiTm9ucGFyYW1ldHJpYyBTdGF0aXN0aWNzIGZvciBIZWFsdGggQ2FyZSBSZXNlYXJjaCIgZGUgUGV0dC4KCiMjIyBFamVyY2ljaW9zIHByw6FjdGljb3M6CgotICAgUmVhbGl6YXIgcHJ1ZWJhcyB6IHkgdCBwYXJhIGNvbXBhcmFyIG1lZGlhcyBkZSBiaW9tYXJjYWRvcmVzIChlLmcuLAogICAgZ2x1Y29zYSwgY29sZXN0ZXJvbCkuCi0gICBBcGxpY2FyIHBydWViYXMgbm8gcGFyYW3DqXRyaWNhcyBhIGRhdG9zIGRlIGVzY2FsYXMgb3JkaW5hbGVzIChlLmcuLAogICAgc2V2ZXJpZGFkIGRlIHPDrW50b21hcykuCi0gICBDYWxjdWxhciBwb3RlbmNpYSB5IHRhbWHDsW8gbXVlc3RyYWwgcGFyYSBlbnNheW9zIGNsw61uaWNvcyB1c2FuZG8gUiBvCiAgICBQeXRob24uCgojIyMgSGVycmFtaWVudGFzIGNvbXB1dGFjaW9uYWxlczoKCi0gICAqKlI6KiogUGFxdWV0ZXMgc3RhdHMgKHQudGVzdCwgd2lsY294LnRlc3QpLCBwd3IgKGPDoWxjdWxvIGRlCiAgICBwb3RlbmNpYSkuCi0gICAqKlB5dGhvbjoqKiBMaWJyZXLDrWFzIHNjaXB5LnN0YXRzIChtYW5ud2hpdG5leXUsIGtydXNrYWwpLAogICAgc3RhdHNtb2RlbHMuCi0gICAqKkVqZW1wbG8gZW4gUjoqKiBgdC50ZXN0KHgsIHksIHBhaXJlZD1UUlVFKWAgcGFyYSBwcnVlYmEgdCBwYXJlYWRhOwogICAgYHdpbGNveC50ZXN0KHgsIHkpYCBwYXJhIFdpbGNveG9uLgoKIyMjIEJhc2VzIGRlIGRhdG9zOgoKLSAgIE5IQU5FUyBwYXJhIGRhdG9zIGRlIHNhbHVkIHBvYmxhY2lvbmFsLgotICAgRW5zYXlvcyBjbMOtbmljb3MgZW4gQ2xpbmljYWxUcmlhbHMuZ292IHBhcmEgcHJhY3RpY2FyIHBydWViYXMgZGUKICAgIGhpcMOzdGVzaXMuCgojIFRhYmxhIFJlc3VtZW46IFBydWViYXMgZGUgSGlww7N0ZXNpcyBlbiBlbCBTZWN0b3IgU2FsdWQKCmBgYHtyIGhpcG90ZXNpcy10YWJsZSwgZWNobz1GQUxTRSwgcmVzdWx0cz0nYXNpcycsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkoa25pdHIpCmxpYnJhcnkoa2FibGVFeHRyYSkKCiMgQ3JlYXIgbGEgdGFibGEKdGFibGFfaGlwb3Rlc2lzIDwtIGRhdGEuZnJhbWUoCiAgIlBydWViYSIgPSBjKAogICAgInotdGVzdCAodW5hIG1lZGlhKSIsCiAgICAidC10ZXN0ICh1bmEgbWVkaWEpIiwKICAgICJ0LXRlc3QgKGRvcyBtZWRpYXMsIGluZGVwZW5kaWVudGVzKSIsCiAgICAidC10ZXN0IChwYXJlYWRvKSIsCiAgICAiei10ZXN0ICh1bmEgcHJvcG9yY2nDs24pIiwKICAgICJ6LXRlc3QgKGRvcyBwcm9wb3JjaW9uZXMpIiwKICAgICJDaGktY3VhZHJhZG8gKHVuYSB2YXJpYW56YSkiLAogICAgIkYtdGVzdCAoZG9zIHZhcmlhbnphcykiLAogICAgIldpbGNveG9uIChwYXJlYWRvKSIsCiAgICAiTWFubi1XaGl0bmV5IFUiLAogICAgIktydXNrYWwtV2FsbGlzIgogICksCiAgIlN1cHVlc3RvcyIgPSBjKAogICAgIk5vcm1hbGlkYWQgbyBuIOKJpSAzMDsgdmFyaWFuemEgcG9ibGFjaW9uYWwgY29ub2NpZGEiLAogICAgIk5vcm1hbGlkYWQgKGVzcGVjaWFsbWVudGUgc2kgbiA8IDMwKTsgdmFyaWFuemEgZGVzY29ub2NpZGEiLAogICAgIk5vcm1hbGlkYWQsIHZhcmlhbnphcyBpZ3VhbGVzIChvIFdlbGNoKSwgbXVlc3RyYXMgaW5kZXBlbmRpZW50ZXMiLAogICAgIkRpZmVyZW5jaWFzIG5vcm1hbG1lbnRlIGRpc3RyaWJ1aWRhcyAobiBwZXF1ZcOxYXMpIiwKICAgICJuwrdwzIIg4omlIDUsIG7Ctygx4oiScMyCKSDiiaUgNSIsCiAgICAiTXVlc3RyYXMgaW5kZXBlbmRpZW50ZXMsIG7Ct3DMgiDiiaUgNSBlbiBhbWJvcyBncnVwb3MiLAogICAgIk5vcm1hbGlkYWQsIGRhdG9zIGNvbnRpbnVvcyIsCiAgICAiTm9ybWFsaWRhZCBlbiBhbWJvcyBncnVwb3MsIG11ZXN0cmFzIGluZGVwZW5kaWVudGVzIiwKICAgICJEYXRvcyBwYXJlYWRvcywgbm8gbmVjZXNhcmlhbWVudGUgbm9ybWFsZXMiLAogICAgIkRhdG9zIGluZGVwZW5kaWVudGVzLCBubyBub3JtYWxlcyB1IG9yZGluYWxlcyIsCiAgICAiTcOhcyBkZSBkb3MgZ3J1cG9zLCBpbmRlcGVuZGllbnRlcywgbm8gbm9ybWFsZXMiCiAgKSwKICAiRXN0YWTDrXN0aWNvIiA9IGMoCiAgICAiJHogPSBcXGZyYWN7XFxiYXJ7eH0gLSBcXG11XzB9e1xcc2lnbWEgLyBcXHNxcnR7bn19JCIsCiAgICAiJHQgPSBcXGZyYWN7XFxiYXJ7eH0gLSBcXG11XzB9e3MgLyBcXHNxcnR7bn19JCIsCiAgICAiJHQgPSBcXGZyYWN7XFxiYXJ7eH1fMSAtIFxcYmFye3h9XzJ9e1xcc3FydHtcXGZyYWN7c18xXjJ9e25fMX0gKyBcXGZyYWN7c18yXjJ9e25fMn19fSQiLAogICAgIiR0ID0gXFxmcmFje1xcYmFye2R9fXtzX2QgLyBcXHNxcnR7bn19JCIsCiAgICAiJHogPSBcXGZyYWN7XFxoYXR7cH0gLSBwXzB9e1xcc3FydHtcXGZyYWN7cF8wKDEtcF8wKX17bn19fSQiLAogICAgIiR6ID0gXFxmcmFje1xcaGF0e3B9XzEgLSBcXGhhdHtwfV8yfXtcXHNxcnR7XFxoYXR7cH0oMS1cXGhhdHtwfSlcXGxlZnQoXFxmcmFjezF9e25fMX0gKyBcXGZyYWN7MX17bl8yfVxccmlnaHQpfX19JCIsCiAgICAiJFxcY2hpXjIgPSBcXGZyYWN7KG4tMSlzXjJ9e1xcc2lnbWFfMF4yfSQiLAogICAgIiRGID0gXFxmcmFje3NfMV4yfXtzXzJeMn0kIiwKICAgICJTdW1hIGRlIHJhbmdvcyBjb24gc2lnbm8iLAogICAgIiRVID0gbl8xIG5fMiArIFxcZnJhY3tuXzEobl8xKzEpfXsyfSAtIFJfMSQiLAogICAgIiRIID0gXFxmcmFjezEyfXtOKE4rMSl9IFxcc3VtIFxcZnJhY3tSX2leMn17bl9pfSAtIDMoTisxKSQiCiAgKSwKICAiQXBsaWNhY2nDs24gZW4gU2FsdWQiID0gYygKICAgICJDb21wYXJhciBtZWRpYSBkZSBnbHVjb3NhIGNvbiB1biBlc3TDoW5kYXIgY2zDrW5pY28iLAogICAgIkV2YWx1YXIgY2FtYmlvIGVuIHByZXNpw7NuIGFydGVyaWFsIHRyYXMgdHJhdGFtaWVudG8iLAogICAgIkNvbXBhcmFyIG5pdmVsZXMgZGUgY29sZXN0ZXJvbCBlbnRyZSB0cmF0YWRvcyB5IHBsYWNlYm8iLAogICAgIkNvbXBhcmFyIGRvbG9yIGFudGVzIHkgZGVzcHXDqXMgZGUgdW4gdHJhdGFtaWVudG8iLAogICAgIlByZXZhbGVuY2lhIGRlIGRpYWJldGVzIHZzLiB2YWxvciBlc3BlcmFkbyIsCiAgICAiQ29tcGFyYXIgdGFzYXMgZGUgcmVzcHVlc3RhIGVudHJlIGRvcyB0cmF0YW1pZW50b3MiLAogICAgIkV2YWx1YXIgdmFyaWFiaWxpZGFkIGVuIHRpZW1wb3MgZGUgcmVjdXBlcmFjacOzbiIsCiAgICAiQ29tcGFyYXIgZGlzcGVyc2nDs24gZGUgYmlvbWFyY2Fkb3JlcyBlbnRyZSBob3NwaXRhbGVzIiwKICAgICJFZmVjdG8gZGUgdW4gZsOhcm1hY28gZW4gcGFjaWVudGVzIHBhcmVhZG9zIiwKICAgICJDb21wYXJhciB0aWVtcG9zIGRlIHJlY3VwZXJhY2nDs24gZW50cmUgdHJhdGFtaWVudG9zIiwKICAgICJDb21wYXJhciBzZXZlcmlkYWQgZGUgc8OtbnRvbWFzIGVuIHRyZXMgZ3J1cG9zIgogICksCiAgIkVqZW1wbG8gUHLDoWN0aWNvIiA9IGMoCiAgICAiwr9MYSBnbHVjb3NhIG1lZGlhICgxMjUgbWcvZEwpIGVuIDEwMCBwYWNpZW50ZXMgZGlmaWVyZSBkZSAxMjA/IiwKICAgICLCv0VsIHRpZW1wbyBkZSByZWN1cGVyYWNpw7NuICgxMCBkw61hcywgcz0yKSBkaWZpZXJlIGRlIDkgZMOtYXM/IiwKICAgICJHcnVwbyB0cmF0YWRvOiAxMTUgbW1IZyB2cy4gcGxhY2VibzogMTIwIG1tSGciLAogICAgIlB1bnRhamUgZGUgZG9sb3IgZGlzbWludXllIGRlIDcgYSA1IGVuIDE1IHBhY2llbnRlcyIsCiAgICAiRW4gMjAwIHBhY2llbnRlcywgwr9wID0gMC4xNCBkaWZpZXJlIGRlIHDigoAgPSAwLjEwPyIsCiAgICAiMzAlIHJlc3BvbmRlZG9yZXMgdnMuIDIwJSBlbiBwbGFjZWJvIChuPTEwMCBjYWRhIGdydXBvKSIsCiAgICAic8KyID0gMjUgZMOtYXPCsiB2cy4gz4PigoDCsiA9IDIwOiDCv3ZhcmlhbnphIG1heW9yPyIsCiAgICAic+KCgcKyID0gMTAwIHZzLiBz4oKCwrIgPSA4MDogwr9kaWZlcmVuY2lhIGVuIHZhcmlhYmlsaWRhZD8iLAogICAgIkRpZmVyZW5jaWFzIGVuIGdsdWNvc2EgYW50ZXMvZGVzcHXDqXM6IHNpZ25vcyB5IHJhbmdvcyIsCiAgICAiVGllbXBvcyBkZSByZWN1cGVyYWNpw7NuOiB0cmF0YW1pZW50byBBIHZzLiBCIiwKICAgICJFc2NhbGFzIGRlIGRvbG9yOiBtZWRpY2FtZW50byBBLCBCLCBDIgogICksCiAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFCikKCiMgTW9zdHJhciB0YWJsYQprYWJsZSh0YWJsYV9oaXBvdGVzaXMsICJodG1sIiwgCiAgICAgIGNhcHRpb24gPSAiVGFibGEgMzogUmVzdW1lbiBkZSBwcnVlYmFzIGRlIGhpcMOzdGVzaXMgYXBsaWNhZGFzIGFsIHNlY3RvciBzYWx1ZCIpICU+JQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgInJlc3BvbnNpdmUiKSwgZnVsbF93aWR0aCA9IEZBTFNFKSAlPiUKICBzY3JvbGxfYm94KHdpZHRoID0gIjEwMCUiLCBoZWlnaHQgPSAiNTAwcHgiKQoKYGBgCgojIDQuIEFuw6FsaXNpcyBkZSBWYXJpYW56YSAoQU5PVkEpIHBhcmEgZWwgU2VjdG9yIFNhbHVkCgpFc3RlIHRlbWFyaW8gZGVzYXJyb2xsYSBsb3MgY29uY2VwdG9zIGRlIGFuw6FsaXNpcyBkZSB2YXJpYW56YSAoQU5PVkEpCmNvbiB1biBlbmZvcXVlIGVuIGFwbGljYWNpb25lcyBlbiBlbCBzZWN0b3Igc2FsdWQsIHByb3BvcmNpb25hbmRvCmV4cGxpY2FjaW9uZXMgZGV0YWxsYWRhcywgZWplbXBsb3MgcHLDoWN0aWNvcyB5IGFwbGljYWNpb25lcyByZWxldmFudGVzCnBhcmEgcHJvZmVzaW9uYWxlcyBtw6lkaWNvcywgaW52ZXN0aWdhZG9yZXMgY2zDrW5pY29zIHkgZXBpZGVtacOzbG9nb3MuCkFOT1ZBIGVzIHVuYSBoZXJyYW1pZW50YSBlc3RhZMOtc3RpY2EgY2xhdmUgcGFyYSBjb21wYXJhciBtZWRpYXMgZW50cmUKbcO6bHRpcGxlcyBncnVwb3MsIGV2YWx1YW5kbyBzaSBsYXMgZGlmZXJlbmNpYXMgb2JzZXJ2YWRhcyBzb24KZXN0YWTDrXN0aWNhbWVudGUgc2lnbmlmaWNhdGl2YXMsIGxvIGN1YWwgZXMgZnVuZGFtZW50YWwgZW4gZW5zYXlvcwpjbMOtbmljb3MsIGVzdHVkaW9zIGVwaWRlbWlvbMOzZ2ljb3MgeSBldmFsdWFjaW9uZXMgZGUgaW50ZXJ2ZW5jaW9uZXMgZW4Kc2FsdWQuCgojIyA0LjEgQU5PVkEgZGUgdW4gZmFjdG9yCgojIyMgU3VwdWVzdG9zIHkgTW9kZWxvCgpFbCBBTk9WQSBkZSB1biBmYWN0b3IgKG8gdW5pZGlyZWNjaW9uYWwpIHNlIHV0aWxpemEgcGFyYSBjb21wYXJhciBsYXMKbWVkaWFzIGRlIHRyZXMgbyBtw6FzIGdydXBvcyBpbmRlcGVuZGllbnRlcyBiYXNhZG9zIGVuIHVuIHNvbG8gZmFjdG9yCih2YXJpYWJsZSBpbmRlcGVuZGllbnRlKS4gRW4gc2FsdWQsIGVzdG8gcG9kcsOtYSBpbXBsaWNhciBjb21wYXJhciBlbAplZmVjdG8gZGUgZGlmZXJlbnRlcyB0cmF0YW1pZW50b3Mgc29icmUgdW5hIHZhcmlhYmxlIGNvbW8gbGEgcHJlc2nDs24KYXJ0ZXJpYWwgbyBlbCBuaXZlbCBkZSBnbHVjb3NhLgoKKipTdXB1ZXN0b3M6KioKCi0gICAqKk5vcm1hbGlkYWQ6KiogTG9zIGRhdG9zIGRlIGNhZGEgZ3J1cG8gZGViZW4gc2VndWlyIHVuYQogICAgZGlzdHJpYnVjacOzbiBhcHJveGltYWRhbWVudGUgbm9ybWFsLiBFbiBzYWx1ZCwgZXN0byBwdWVkZQogICAgdmVyaWZpY2Fyc2UgY29uIGdyw6FmaWNvcyBRLVEgbyBwcnVlYmFzIGNvbW8gU2hhcGlyby1XaWxrLgotICAgKipIb21vZ2VuZWlkYWQgZGUgdmFyaWFuemFzIChob21vY2VkYXN0aWNpZGFkKToqKiBMYXMgdmFyaWFuemFzIGRlCiAgICBsb3MgZ3J1cG9zIGRlYmVuIHNlciBpZ3VhbGVzLCB2ZXJpZmljYWJsZSBjb24gcHJ1ZWJhcyBjb21vIExldmVuZSBvCiAgICBCYXJ0bGV0dC4KLSAgICoqSW5kZXBlbmRlbmNpYToqKiBMYXMgb2JzZXJ2YWNpb25lcyBlbnRyZSB5IGRlbnRybyBkZSBsb3MgZ3J1cG9zCiAgICBkZWJlbiBzZXIgaW5kZXBlbmRpZW50ZXMuIEVuIGVuc2F5b3MgY2zDrW5pY29zLCBlc3RvIHNlIGFzZWd1cmEKICAgIG1lZGlhbnRlIGFsZWF0b3JpemFjacOzbi4KLSAgICoqRXNjYWxhIGRlIG1lZGljacOzbjoqKiBMYSB2YXJpYWJsZSBkZXBlbmRpZW50ZSBkZWJlIHNlciBjb250aW51YQogICAgKGUuZy4sIG5pdmVsZXMgZGUgY29sZXN0ZXJvbCwgdGllbXBvIGRlIHJlY3VwZXJhY2nDs24pLgoKKipNb2RlbG86KioKCkVsIG1vZGVsbyBtYXRlbcOhdGljbyBwYXJhIEFOT1ZBIGRlIHVuIGZhY3RvciBlczogJCQKWV97aWp9ID0gXG11ICsgXHRhdV9pICsgXGVwc2lsb25fe2lqfQokJCBEb25kZSAkWV97aWp9JCBlcyBsYSBvYnNlcnZhY2nDs24gJGokIGVuIGVsIGdydXBvICRpJCwgJFxtdSQgZXMgbGEKbWVkaWEgZ2VuZXJhbCwgJFx0YXVfaSQgZXMgZWwgZWZlY3RvIGRlbCBncnVwbyAkaSQsIHkgJFxlcHNpbG9uX3tpan0kIGVzCmVsIGVycm9yIGFsZWF0b3JpbyAoJFxlcHNpbG9uX3tpan0gXHNpbSBOKDAsIFxzaWdtYV4yKSQpLgoKKipIaXDDs3Rlc2lzOioqCgotICAgJEhfMCQ6IExhcyBtZWRpYXMgZGUgdG9kb3MgbG9zIGdydXBvcyBzb24gaWd1YWxlcwogICAgKCRcbXVfMSA9IFxtdV8yID0gXGRvdHMgPSBcbXVfayQpLgotICAgJEhfMSQ6IEFsIG1lbm9zIHVuYSBtZWRpYSBkaWZpZXJlLgoKKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBDb21wYXJhciBsYSBtZWRpYSBkZSBwcmVzacOzbiBhcnRlcmlhbCBzaXN0w7NsaWNhCmVudHJlIHRyZXMgZ3J1cG9zIGRlIHBhY2llbnRlcyB0cmF0YWRvcyBjb24gZGlmZXJlbnRlcwphbnRpaGlwZXJ0ZW5zaXZvcy4KCioqRWplbXBsbyBwcsOhY3RpY286KiogRW4gdW4gZXN0dWRpbywgc2UgY29tcGFyYSBlbCBuaXZlbCBkZSBnbHVjb3NhIGVuCnNhbmdyZSAobWcvZEwpIGVudHJlIHRyZXMgZ3J1cG9zIGRlIHBhY2llbnRlcyBkaWFiw6l0aWNvcyB0cmF0YWRvcyBjb24KaW5zdWxpbmEsIG1ldGZvcm1pbmEsIG8gcGxhY2Viby4gTG9zIHN1cHVlc3RvcyBzZSB2ZXJpZmljYW4gYW50ZXMgZGUKcHJvY2VkZXIgY29uIGVsIEFOT1ZBLgoKIyMjIFN1bWEgZGUgQ3VhZHJhZG9zIHkgVGFibGEgQU5PVkEKCkVsIEFOT1ZBIGRlc2NvbXBvbmUgbGEgdmFyaWFiaWxpZGFkIHRvdGFsIGRlIGxvcyBkYXRvcyBlbiBjb21wb25lbnRlcwphdHJpYnVpYmxlcyBhbCBmYWN0b3IgKGVudHJlIGdydXBvcykgeSBhbCBlcnJvciAoZGVudHJvIGRlIGdydXBvcykuCgoqKlN1bWEgZGUgY3VhZHJhZG9zIChTQyk6KioKCi0gICAqKlRvdGFsIChTQ1QpOioqIFZhcmlhYmlsaWRhZCB0b3RhbCBkZSBsb3MgZGF0b3M6ICQkCiAgICBTQ1QgPSBcc3VtX3tpPTF9XmsgXHN1bV97aj0xfV57bl9pfSAoWV97aWp9IC0gXGJhcntZfSleMgogICAgJCQgRG9uZGUgJFxiYXJ7WX0kIGVzIGxhIG1lZGlhIGdlbmVyYWwuCgotICAgKipFbnRyZSBncnVwb3MgKFNDRSk6KiogVmFyaWFiaWxpZGFkIGRlYmlkbyBhbCBmYWN0b3I6ICQkCiAgICBTQ0UgPSBcc3VtX3tpPTF9Xmsgbl9pIChcYmFye1l9X2kgLSBcYmFye1l9KV4yCiAgICAkJCBEb25kZSAkXGJhcntZfV9pJCBlcyBsYSBtZWRpYSBkZWwgZ3J1cG8gJGkkLCB5ICRuX2kkIGVzIGVsIHRhbWHDsW8KICAgIGRlbCBncnVwby4KCi0gICAqKkRlbnRybyBkZSBncnVwb3MgKFNDUik6KiogVmFyaWFiaWxpZGFkIHJlc2lkdWFsIChlcnJvcik6ICQkCiAgICBTQ1IgPSBcc3VtX3tpPTF9XmsgXHN1bV97aj0xfV57bl9pfSAoWV97aWp9IC0gXGJhcntZfV9pKV4yCiAgICAkJCBSZWxhY2nDs246ICRTQ1QgPSBTQ0UgKyBTQ1IkLgoKKipFc3RhZMOtc3RpY28gRjoqKgoKQ29tcGFyYSBsYSB2YXJpYW56YSBlbnRyZSBncnVwb3MgY29uIGxhIHZhcmlhbnphIGRlbnRybyBkZSBncnVwb3M6ICQkCkYgPSBcZnJhY3tcdGV4dHtDTUV9fXtcdGV4dHtDTVJ9fQokJCBEb25kZSAkXHRleHR7Q01FfSA9IFxmcmFje1NDRX17ay0xfSQgKGN1YWRyYWRvIG1lZGlvIGVudHJlIGdydXBvcyksCiRcdGV4dHtDTVJ9ID0gXGZyYWN7U0NSfXtOLWt9JCAoY3VhZHJhZG8gbWVkaW8gcmVzaWR1YWwpLCAkayQgZXMgZWwKbsO6bWVybyBkZSBncnVwb3MsIHkgJE4kIGVzIGVsIG7Dum1lcm8gdG90YWwgZGUgb2JzZXJ2YWNpb25lcy4KClNlIGNvbXBhcmEgY29uIHZhbG9yZXMgY3LDrXRpY29zIGRlIGxhIGRpc3RyaWJ1Y2nDs24gRiBjb24gJGstMSQgeSAkTi1rJApncmFkb3MgZGUgbGliZXJ0YWQuCgoqKlRhYmxhIEFOT1ZBOioqCgp8IEZ1ZW50ZSB8IEdyYWRvcyBkZSBMaWJlcnRhZCB8IFN1bWEgZGUgQ3VhZHJhZG9zIHwgQ3VhZHJhZG8gTWVkaW8gfCBGIHwgVmFsb3IgcCB8CnwtLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS18CnwgRW50cmUgZ3J1cG9zIHwgJGstMSQgfCAkU0NFJCB8ICRcdGV4dHtDTUV9JCB8ICRGJCB8ICRwJCB8CnwgRGVudHJvIGRlIGdydXBvcyB8ICROLWskIHwgJFNDUiQgfCAkXHRleHR7Q01SfSQgfCAgfCAgfAp8IFRvdGFsIHwgJE4tMSQgfCAkU0NUJCB8ICB8ICB8ICB8CgoqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIEV2YWx1YXIgc2kgdHJlcyBkb3NpcyBkZSB1biBmw6FybWFjbyBwcm9kdWNlbgpkaWZlcmVuY2lhcyBzaWduaWZpY2F0aXZhcyBlbiBsYSByZWR1Y2Npw7NuIGRlIGNvbGVzdGVyb2wgTERMLgoKKipFamVtcGxvIHByw6FjdGljbzoqKiBFbiB1biBlc3R1ZGlvIGNvbiB0cmVzIGdydXBvcwooJG5fMSA9IG5fMiA9IG5fMyA9IDMwJCkgdHJhdGFkb3MgY29uIGRpZmVyZW50ZXMgZG9zaXMgZGUgdW4KYW50aWhpcGVydGVuc2l2bywgbGFzIG1lZGlhcyBkZSBwcmVzacOzbiBhcnRlcmlhbCBzb24gMTIwLCAxMTUsIHkgMTE4Cm1tSGcuIExhIHRhYmxhIEFOT1ZBIG11ZXN0cmEgJEYgPSA0LjUkLCBjb24gJHAgPSAwLjAxNSQsIGluZGljYW5kbyBxdWUKc2UgcmVjaGF6YSAkSF8wJCAoJHAgPCAwLjA1JCksIHN1Z2lyaWVuZG8gZGlmZXJlbmNpYXMgZW50cmUgYWwgbWVub3MgZG9zCmdydXBvcy4KCiMjIyBQcnVlYmFzIFBvc3QtaG9jIChUdWtleSwgQm9uZmVycm9uaSkKCkN1YW5kbyBBTk9WQSByZWNoYXphICRIXzAkLCBsYXMgcHJ1ZWJhcyBwb3N0LWhvYyBpZGVudGlmaWNhbiBxdcOpIHBhcmVzCmRlIGdydXBvcyBkaWZpZXJlbi4KCioqUHJ1ZWJhIGRlIFR1a2V5IChIU0QpOioqCgotICAgQ29tcGFyYSB0b2RhcyBsYXMgY29tYmluYWNpb25lcyBkZSBwYXJlcyBkZSBtZWRpYXMsIGFqdXN0YW5kbyBwb3IKICAgIGNvbXBhcmFjaW9uZXMgbcO6bHRpcGxlcy4KLSAgIEVzdGFkw61zdGljbzogJCQKICAgIHEgPSBcZnJhY3tcYmFye1l9X2kgLSBcYmFye1l9X2p9e1xzcXJ0e1x0ZXh0e0NNUn0gLyBufX0KICAgICQkIENvbXBhcmFkbyBjb24gdmFsb3JlcyBjcsOtdGljb3MgZGUgbGEgZGlzdHJpYnVjacOzbiBkZSByYW5nbwogICAgZXN0dWRlbnRpemFkby4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogSWRlbnRpZmljYXIgY3XDoWwgZGUgdHJlcyB0cmF0YW1pZW50b3MKICAgIGFudGloaXBlcnRlbnNpdm9zIGVzIG3DoXMgZWZlY3Rpdm8uCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIFRyYXMgdW4gQU5PVkEgc2lnbmlmaWNhdGl2bywgVHVrZXkgbXVlc3RyYSBxdWUKICAgIGxhIGRvc2lzIG1lZGlhICgxMTUgbW1IZykgZGlmaWVyZSBzaWduaWZpY2F0aXZhbWVudGUgZGUgbGEgZG9zaXMKICAgIGJhamEgKDEyMCBtbUhnKSwgcGVybyBubyBkZSBsYSBkb3NpcyBhbHRhICgxMTggbW1IZykuCgoqKkNvcnJlY2Npw7NuIGRlIEJvbmZlcnJvbmk6KioKCi0gICBBanVzdGEgZWwgbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSBwYXJhIG3Dumx0aXBsZXMgY29tcGFyYWNpb25lczoKICAgICRcYWxwaGEnID0gXGZyYWN7XGFscGhhfXttfSQsIGRvbmRlICRtJCBlcyBlbCBuw7ptZXJvIGRlCiAgICBjb21wYXJhY2lvbmVzLgotICAgKipWZW50YWphOioqIFNpbXBsZSwgcGVybyBjb25zZXJ2YWRvciAocHVlZGUgcmVkdWNpciBsYSBwb3RlbmNpYSkuCi0gICAqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIENvbXBhcmFyIHRhc2FzIGRlIHJlY3VwZXJhY2nDs24gZW50cmUgY3VhdHJvCiAgICBncnVwb3MgZGUgdHJhdGFtaWVudG8sIGFqdXN0YW5kbyAkXGFscGhhID0gMC4wNS82ID0gMC4wMDgzJCBwYXJhIDYKICAgIGNvbXBhcmFjaW9uZXMuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuIGVzdHVkaW8gY29uIGN1YXRybyB0cmF0YW1pZW50b3MsCiAgICBCb25mZXJyb25pIGlkZW50aWZpY2EgZGlmZXJlbmNpYXMgc2lnbmlmaWNhdGl2YXMgc29sbyBlbnRyZSBlbAogICAgdHJhdGFtaWVudG8gbcOhcyBlZmVjdGl2byB5IGVsIHBsYWNlYm8uCgoqKkNvbnNpZGVyYWNpb25lczoqKiBUdWtleSBlcyBwcmVmZXJpZG8gcGFyYSBjb21wYXJhY2lvbmVzIG3Dumx0aXBsZXMgZW4KQU5PVkEgYmFsYW5jZWFkbywgbWllbnRyYXMgcXVlIEJvbmZlcnJvbmkgZXMgw7p0aWwgY3VhbmRvIHNlIHJlYWxpemFuCnBvY2FzIGNvbXBhcmFjaW9uZXMgbyBlbiBjb250ZXh0b3MgZXhwbG9yYXRvcmlvcy4KCiMjIDQuMiBBTk9WQSBkZSBkb3MgZmFjdG9yZXMKCkVsIEFOT1ZBIGRlIGRvcyBmYWN0b3JlcyBhbmFsaXphIGVsIGVmZWN0byBkZSBkb3MgdmFyaWFibGVzIGNhdGVnw7NyaWNhcwooZmFjdG9yZXMpIHNvYnJlIHVuYSB2YXJpYWJsZSBkZXBlbmRpZW50ZSBjb250aW51YSwgcGVybWl0aWVuZG8gZXZhbHVhcgplZmVjdG9zIHByaW5jaXBhbGVzIGUgaW50ZXJhY2Npb25lcy4KCiMjIyBJbnRlcmFjY2lvbmVzIHkgRWZlY3RvcyBQcmluY2lwYWxlcwoKKipFZmVjdG9zIHByaW5jaXBhbGVzOioqIEltcGFjdG8gZGUgY2FkYSBmYWN0b3Igc29icmUgbGEgdmFyaWFibGUKZGVwZW5kaWVudGUsIGlnbm9yYW5kbyBlbCBvdHJvIGZhY3Rvci4KCi0gICAqKkVqZW1wbG86KiogRWZlY3RvIGRlbCB0aXBvIGRlIHRyYXRhbWllbnRvIChmw6FybWFjbyBBIHZzLiBCKSB5IGRlbAogICAgc2V4byAoaG9tYnJlIHZzLiBtdWplcikgc29icmUgbGEgcHJlc2nDs24gYXJ0ZXJpYWwuCgoqKkludGVyYWNjacOzbjoqKiBDdWFuZG8gZWwgZWZlY3RvIGRlIHVuIGZhY3RvciBkZXBlbmRlIGRlbCBuaXZlbCBkZWwKb3RybyBmYWN0b3IuCgotICAgKipFamVtcGxvOioqIFVuIGbDoXJtYWNvIHB1ZWRlIHNlciBtw6FzIGVmZWN0aXZvIGVuIGhvbWJyZXMgcXVlIGVuCiAgICBtdWplcmVzLCBpbmRpY2FuZG8gdW5hIGludGVyYWNjacOzbiBlbnRyZSB0cmF0YW1pZW50byB5IHNleG8uCgoqKk1vZGVsbzoqKiAkJApZX3tpamt9ID0gXG11ICsgXGFscGhhX2kgKyBcYmV0YV9qICsgKFxhbHBoYVxiZXRhKV97aWp9ICsgXGVwc2lsb25fe2lqa30KJCQgRG9uZGUgJFxhbHBoYV9pJCBlcyBlbCBlZmVjdG8gZGVsIGZhY3RvciBBLCAkXGJldGFfaiQgZXMgZWwgZWZlY3RvCmRlbCBmYWN0b3IgQiwgJChcYWxwaGFcYmV0YSlfe2lqfSQgZXMgbGEgaW50ZXJhY2Npw7NuLCB5ICRcZXBzaWxvbl97aWprfSQKZXMgZWwgZXJyb3IuCgoqKkhpcMOzdGVzaXM6KioKCi0gICAkSF8wJDogTm8gaGF5IGVmZWN0byBwcmluY2lwYWwgZGUgQSAoJFxhbHBoYV9pID0gMCQpLgotICAgJEhfMCQ6IE5vIGhheSBlZmVjdG8gcHJpbmNpcGFsIGRlIEIgKCRcYmV0YV9qID0gMCQpLgotICAgJEhfMCQ6IE5vIGhheSBpbnRlcmFjY2nDs24gKCQoXGFscGhhXGJldGEpX3tpan0gPSAwJCkuCgoqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIEV2YWx1YXIgc2kgZWwgZWZlY3RvIGRlIHVuIHRyYXRhbWllbnRvIChmw6FybWFjbwp2cy4gcGxhY2Vibykgc29icmUgZWwgY29sZXN0ZXJvbCB2YXLDrWEgc2Vnw7puIGVsIGdydXBvIGRlIGVkYWQgKGrDs3ZlbmVzCnZzLiBhZHVsdG9zIG1heW9yZXMpLgoKKipFamVtcGxvIHByw6FjdGljbzoqKiBFbiB1biBlc3R1ZGlvLCBlbCBBTk9WQSBkZSBkb3MgZmFjdG9yZXMgbXVlc3RyYQp1bmEgaW50ZXJhY2Npw7NuIHNpZ25pZmljYXRpdmEgKCRwID0gMC4wMSQpIGVudHJlIHRyYXRhbWllbnRvIHkgZWRhZCwKaW5kaWNhbmRvIHF1ZSBlbCBmw6FybWFjbyByZWR1Y2UgZWwgY29sZXN0ZXJvbCBtw6FzIGVuIGFkdWx0b3MgbWF5b3JlcyBxdWUKZW4gasOzdmVuZXMuCgojIyMgRGlzZcOxb3MgRmFjdG9yaWFsZXMKCioqRGlzZcOxbyBmYWN0b3JpYWwgY29tcGxldG86KiogVG9kb3MgbG9zIG5pdmVsZXMgZGUgdW4gZmFjdG9yIHNlCmNvbWJpbmFuIGNvbiB0b2RvcyBsb3Mgbml2ZWxlcyBkZWwgb3RybyBmYWN0b3IgKGUuZy4sIDJ4MzogZG9zCnRyYXRhbWllbnRvcyB5IHRyZXMgZ3J1cG9zIGRlIGVkYWQpLgoKLSAgICoqVmVudGFqYToqKiBQZXJtaXRlIGV2YWx1YXIgZWZlY3RvcyBwcmluY2lwYWxlcyBlIGludGVyYWNjaW9uZXMgZGUKICAgIG1hbmVyYSBlZmljaWVudGUuCi0gICAqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIENvbXBhcmFyIGVsIGVmZWN0byBkZSBkb3MgdGlwb3MgZGUgaW5zdWxpbmEKICAgIChyw6FwaWRhLCBsZW50YSkgeSB0cmVzIGRvc2lzIChiYWphLCBtZWRpYSwgYWx0YSkgc29icmUgbG9zIG5pdmVsZXMKICAgIGRlIGdsdWNvc2EuCgoqKkRpc2XDsW8gYmFsYW5jZWFkbyB2cy4gbm8gYmFsYW5jZWFkbzoqKgoKLSAgICoqQmFsYW5jZWFkbzoqKiBJZ3VhbCBuw7ptZXJvIGRlIG9ic2VydmFjaW9uZXMgcG9yIGNvbWJpbmFjacOzbi4KLSAgICoqTm8gYmFsYW5jZWFkbzoqKiBEaWZlcmVudGVzIHRhbWHDsW9zIGRlIGdydXBvLCByZXF1aWVyZSBhanVzdGVzIGVuCiAgICBlbCBjw6FsY3Vsby4KCioqRWplbXBsbyBwcsOhY3RpY286KiogVW4gZGlzZcOxbyAyeDIgZXZhbMO6YSBlbCBlZmVjdG8gZGUgdHJhdGFtaWVudG8KKGbDoXJtYWNvIHZzLiBwbGFjZWJvKSB5IGRpZXRhIChiYWphIGVuIGNhcmJvaGlkcmF0b3MgdnMuIGVzdMOhbmRhcikgc29icmUKZWwgcGVzbyBlbiBwYWNpZW50ZXMgb2Jlc29zLiBMYSB0YWJsYSBBTk9WQSBtdWVzdHJhIGVmZWN0b3MgcHJpbmNpcGFsZXMKc2lnbmlmaWNhdGl2b3MgcGFyYSBlbCB0cmF0YW1pZW50byAoJHAgPSAwLjAwMiQpIHkgbGEgZGlldGEKKCRwID0gMC4wMSQpLCBwZXJvIG5vIGludGVyYWNjacOzbiAoJHAgPSAwLjE1JCkuCgojIyA0LjMgQU5PVkEgTXVsdGlmYWN0b3JpYWwgeSBNb2RlbG9zIE1peHRvcwoKIyMjIERpc2XDsW9zIEFuaWRhZG9zIHkgZGUgTWVkaWRhcyBSZXBldGlkYXMKCioqRGlzZcOxb3MgYW5pZGFkb3M6KioKCi0gICBVbiBmYWN0b3IgZXN0w6Egc3Vib3JkaW5hZG8gYSBvdHJvIChlLmcuLCBwYWNpZW50ZXMgYW5pZGFkb3MgZGVudHJvCiAgICBkZSBob3NwaXRhbGVzLCBob3NwaXRhbGVzIGFuaWRhZG9zIGRlbnRybyBkZSByZWdpb25lcykuCi0gICAqKk1vZGVsbzoqKiAkJAogICAgWV97aWprfSA9IFxtdSArIFxhbHBoYV9pICsgXGJldGFfe2ooaSl9ICsgXGVwc2lsb25fe2lqa30KICAgICQkIERvbmRlICRcYmV0YV97aihpKX0kIGVzIGVsIGVmZWN0byBkZWwgbml2ZWwgJGokIGRlbCBmYWN0b3IgQgogICAgYW5pZGFkbyBlbiBlbCBuaXZlbCAkaSQgZGVsIGZhY3RvciBBLgotICAgKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBDb21wYXJhciBsYSB2YXJpYWJpbGlkYWQgZW4gdGllbXBvcyBkZQogICAgcmVjdXBlcmFjacOzbiBlbnRyZSBwYWNpZW50ZXMgdHJhdGFkb3MgZW4gZGlmZXJlbnRlcyBob3NwaXRhbGVzLAogICAgZG9uZGUgbG9zIG3DqWRpY29zIGVzdMOhbiBhbmlkYWRvcyBkZW50cm8gZGUgY2FkYSBob3NwaXRhbC4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogRW4gdW4gZXN0dWRpbywgc2UgZXZhbMO6YSBsYSBjYWxpZGFkIGRlCiAgICBhdGVuY2nDs24gKG1lZGlkYSBwb3IgdGllbXBvIGRlIGVzcGVyYSkgZW4gdHJlcyBob3NwaXRhbGVzLCBjb24KICAgIHZhcmlvcyBtw6lkaWNvcyBwb3IgaG9zcGl0YWwuIEVsIEFOT1ZBIGFuaWRhZG8gbXVlc3RyYSBkaWZlcmVuY2lhcwogICAgc2lnbmlmaWNhdGl2YXMgZW50cmUgaG9zcGl0YWxlcyAoJHAgPSAwLjAzJCksIHBlcm8gbm8gZW50cmUgbcOpZGljb3MKICAgIGRlbnRybyBkZSBob3NwaXRhbGVzICgkcCA9IDAuMTIkKS4KCioqRGlzZcOxb3MgZGUgbWVkaWRhcyByZXBldGlkYXM6KioKCi0gICBNaWRlIGxhIG1pc21hIHZhcmlhYmxlIGVuIGxvcyBtaXNtb3Mgc3VqZXRvcyBlbiBtw7psdGlwbGVzIG9jYXNpb25lcwogICAgKGUuZy4sIG5pdmVsZXMgZGUgZ2x1Y29zYSBhbnRlcywgZHVyYW50ZSB5IGRlc3B1w6lzIGRlIHVuCiAgICB0cmF0YW1pZW50bykuCi0gICAqKk1vZGVsbzoqKiAkJAogICAgWV97aWp9ID0gXG11ICsgXGFscGhhX2kgKyBccGlfaiArIFxlcHNpbG9uX3tpan0KICAgICQkIERvbmRlICRccGlfaiQgZXMgZWwgZWZlY3RvIGRlbCBzdWpldG8gKGopLCB5ICRcYWxwaGFfaSQgZXMgZWwKICAgIGVmZWN0byBkZWwgdGllbXBvIG8gdHJhdGFtaWVudG8uCi0gICAqKlN1cHVlc3RvIGFkaWNpb25hbDoqKiBFc2ZlcmljaWRhZCAodmFyaWFuemFzIGRlIGxhcyBkaWZlcmVuY2lhcwogICAgZW50cmUgcGFyZXMgZGUgbWVkaWRhcyBzb24gaWd1YWxlcyksIHZlcmlmaWNhYmxlIGNvbiBsYSBwcnVlYmEgZGUKICAgIE1hdWNobHkuCi0gICAqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIEV2YWx1YXIgZWwgY2FtYmlvIGVuIGxhIHByZXNpw7NuIGFydGVyaWFsIGEKICAgIGxvIGxhcmdvIGRlIHVuIG1lcyBlbiBwYWNpZW50ZXMgYmFqbyB1biBudWV2byB0cmF0YW1pZW50by4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogRW4gMjAgcGFjaWVudGVzLCBzZSBtaWRlbiBsb3Mgbml2ZWxlcyBkZSBIYkExYwogICAgZW4gdHJlcyBtb21lbnRvcyAoYmFzYWwsIDMgbWVzZXMsIDYgbWVzZXMpLiBFbCBBTk9WQSBkZSBtZWRpZGFzCiAgICByZXBldGlkYXMgbXVlc3RyYSB1biBlZmVjdG8gc2lnbmlmaWNhdGl2byBkZWwgdGllbXBvICgkcCA9IDAuMDAxJCksCiAgICBpbmRpY2FuZG8gdW5hIHJlZHVjY2nDs24gcHJvZ3Jlc2l2YS4KCiMjIyBTdXB1ZXN0b3MgeSBWZXJpZmljYWNpb25lcwoKKipTdXB1ZXN0b3MgY29tdW5lczoqKgoKLSAgICoqTm9ybWFsaWRhZDoqKiBWZXJpZmljYXIgY29uIGdyw6FmaWNvcyBRLVEsIGhpc3RvZ3JhbWFzIG8gcHJ1ZWJhcwogICAgY29tbyBTaGFwaXJvLVdpbGsuIEVuIHNhbHVkLCBkYXRvcyBjb21vIHRpZW1wb3MgZGUgcmVjdXBlcmFjacOzbgogICAgcHVlZGVuIHNlciBubyBub3JtYWxlcywgcmVxdWlyaWVuZG8gdHJhbnNmb3JtYWNpb25lcyAoZS5nLiwKICAgIGxvZ2FyaXRtbykuCi0gICAqKkhvbW9jZWRhc3RpY2lkYWQ6KiogVXNhciBwcnVlYmFzIGRlIExldmVuZSBvIEJhcnRsZXR0LiBTaSBzZQogICAgdmlvbGEsIGNvbnNpZGVyYXIgQU5PVkEgcm9idXN0byAoZS5nLiwgV2VsY2ggQU5PVkEpLgotICAgKipJbmRlcGVuZGVuY2lhOioqIEFzZWd1cmFkYSBwb3IgZGlzZcOxbyBleHBlcmltZW50YWwKICAgIChhbGVhdG9yaXphY2nDs24pLiBFbiBtZWRpZGFzIHJlcGV0aWRhcywgbGEgY29ycmVsYWNpw7NuIGVudHJlIG1lZGlkYXMKICAgIGRlYmUgbW9kZWxhcnNlLgotICAgKipFc2ZlcmljaWRhZCAobWVkaWRhcyByZXBldGlkYXMpOioqIFZlcmlmaWNhciBjb24gTWF1Y2hseTsgc2kgc2UKICAgIHZpb2xhLCB1c2FyIGNvcnJlY2Npb25lcyBjb21vIEdyZWVuaG91c2UtR2Vpc3NlciBvIEh1eW5oLUZlbGR0LgoKKipWZXJpZmljYWNpb25lcyBlbiBzYWx1ZDoqKgoKLSAgICoqR3LDoWZpY29zIGRpYWduw7NzdGljb3M6KiogQm94cGxvdHMgcGFyYSBkZXRlY3RhciB2YWxvcmVzIGF0w61waWNvcywKICAgIGdyw6FmaWNvcyBkZSByZXNpZHVvcyBwYXJhIGV2YWx1YXIgbm9ybWFsaWRhZCB5IGhvbW9jZWRhc3RpY2lkYWQuCi0gICAqKlBydWViYXMgZXN0YWTDrXN0aWNhczoqKiBTaGFwaXJvLVdpbGsgcGFyYSBub3JtYWxpZGFkLCBMZXZlbmUgcGFyYQogICAgaG9tb2NlZGFzdGljaWRhZC4KLSAgICoqVHJhbnNmb3JtYWNpb25lczoqKiBBcGxpY2FyIHRyYW5zZm9ybWFjaW9uZXMgbG9nYXLDrXRtaWNhcyBvIGRlCiAgICByYcOteiBjdWFkcmFkYSBzaSBsb3MgZGF0b3Mgc29uIHNlc2dhZG9zIChjb23Dum4gZW4gdGllbXBvcyBkZSBlc3BlcmEKICAgIG8gY29udGVvcyBkZSBldmVudG9zKS4KCioqRWplbXBsbyBwcsOhY3RpY286KiogRW4gdW4gQU5PVkEgZGUgbWVkaWRhcyByZXBldGlkYXMgcGFyYSBldmFsdWFyIGVsCmVmZWN0byBkZSB1biBmw6FybWFjbyBlbiBlbCBjb2xlc3Rlcm9sIGEgbG8gbGFyZ28gZGUgNiBtZXNlcywgbGEgcHJ1ZWJhCmRlIE1hdWNobHkgaW5kaWNhIHZpb2xhY2nDs24gZGUgZXNmZXJpY2lkYWQgKCRwID0gMC4wMiQpLiBTZSBhcGxpY2EgbGEKY29ycmVjY2nDs24gZGUgR3JlZW5ob3VzZS1HZWlzc2VyLCB5IGVsIEFOT1ZBIGFqdXN0YWRvIG11ZXN0cmEgdW4gZWZlY3RvCnNpZ25pZmljYXRpdm8gZGVsIHRpZW1wbyAoJHAgPSAwLjAwNSQpLgoKIyMgUmVjdXJzb3MgcGFyYSBlbCBBdXRvZXN0dWRpbyBlbiBTYWx1ZAoKIyMjIExlY3R1cmFzOgoKLSAgICJTdGF0aXN0aWNhbCBNZXRob2RzIGluIE1lZGljYWwgUmVzZWFyY2giIGRlIEFybWl0YWdlLCBCZXJyeSB5CiAgICBNYXR0aGV3cyAoQ2Fww610dWxvcyBzb2JyZSBBTk9WQSkuCi0gICAiQmlvc3RhdGlzdGljczogQSBGb3VuZGF0aW9uIGZvciBBbmFseXNpcyBpbiB0aGUgSGVhbHRoIFNjaWVuY2VzIiBkZQogICAgRGFuaWVsIChDYXDDrXR1bG9zIDgtOSkuCgojIyMgRWplcmNpY2lvcyBwcsOhY3RpY29zOgoKLSAgIFJlYWxpemFyIEFOT1ZBIGRlIHVuIGZhY3RvciBwYXJhIGNvbXBhcmFyIHRyYXRhbWllbnRvcyBlbiBkYXRvcyBkZQogICAgZW5zYXlvcyBjbMOtbmljb3MgKGUuZy4sIHByZXNpw7NuIGFydGVyaWFsLCBnbHVjb3NhKS4KLSAgIEFwbGljYXIgQU5PVkEgZGUgZG9zIGZhY3RvcmVzIGEgZXN0dWRpb3MgY29uIGludGVyYWNjaW9uZXMgKGUuZy4sCiAgICB0cmF0YW1pZW50byB5IGdydXBvIGRlIGVkYWQpLgotICAgQW5hbGl6YXIgZGF0b3MgZGUgbWVkaWRhcyByZXBldGlkYXMgKGUuZy4sIG5pdmVsZXMgZGUgYmlvbWFyY2Fkb3JlcwogICAgZW4gZWwgdGllbXBvKSB5IHZlcmlmaWNhciBzdXB1ZXN0b3MuCgojIyMgSGVycmFtaWVudGFzIGNvbXB1dGFjaW9uYWxlczoKCi0gICAqKlI6KiogUGFxdWV0ZXMgc3RhdHMgKGFvdiwgYW5vdmEpLCBjYXIgKHBydWViYXMgZGUgc3VwdWVzdG9zKSwgZXoKICAgIChBTk9WQSBkZSBtZWRpZGFzIHJlcGV0aWRhcykuCiAgICAtICAgKipFamVtcGxvOioqIGBhb3YoeSB+IHRyYXRhbWllbnRvLCBkYXRhPWRhdG9zKWAgcGFyYSBBTk9WQSBkZSB1bgogICAgICAgIGZhY3RvcjsgYGV6QU5PVkFgIHBhcmEgbWVkaWRhcyByZXBldGlkYXMuCi0gICAqKlB5dGhvbjoqKiBMaWJyZXLDrWFzIHN0YXRzbW9kZWxzCiAgICAoc3RhdHNtb2RlbHMuc3RhdHMuYW5vdmEuYW5vdmFfbG0pLCBwaW5nb3VpbiAocGcuYW5vdmEsCiAgICBwZy5ybV9hbm92YSkuCiAgICAtICAgKipFamVtcGxvOioqCiAgICAgICAgYHBnLmFub3ZhKGRhdGE9ZGF0b3MsIGR2PSdnbHVjb3NhJywgYmV0d2Vlbj0ndHJhdGFtaWVudG8nKWAuCgojIyMgQmFzZXMgZGUgZGF0b3M6CgotICAgTkhBTkVTIHBhcmEgZGF0b3MgZGUgYmlvbWFyY2Fkb3JlcyAoZS5nLiwgY29sZXN0ZXJvbCwgcHJlc2nDs24KICAgIGFydGVyaWFsKS4KLSAgIENsaW5pY2FsVHJpYWxzLmdvdiBwYXJhIGRhdG9zIGRlIGVuc2F5b3MgY2zDrW5pY29zLgoKIyBUYWJsYSBSZXN1bWVuOiBBbsOhbGlzaXMgZGUgVmFyaWFuemEgKEFOT1ZBKSBlbiBlbCBTZWN0b3IgU2FsdWQKCmBgYHtyIGFub3ZhLXRhYmxlLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdhc2lzJywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShrbml0cikKbGlicmFyeShrYWJsZUV4dHJhKQoKIyBDcmVhciBsYSB0YWJsYQp0YWJsYV9hbm92YSA8LSBkYXRhLmZyYW1lKAogICJUaXBvIGRlIEFOT1ZBIiA9IGMoCiAgICAiQU5PVkEgZGUgdW4gZmFjdG9yIiwKICAgICJBTk9WQSBkZSBkb3MgZmFjdG9yZXMiLAogICAgIkFOT1ZBIGRlIG1lZGlkYXMgcmVwZXRpZGFzIiwKICAgICJBTk9WQSBhbmlkYWRvIChuZXN0ZWQpIiwKICAgICJBTk9WQSBtdWx0aWZhY3RvcmlhbCBjb24gaW50ZXJhY2Npw7NuIgogICksCiAgIlN1cHVlc3RvcyBDbGF2ZSIgPSBjKAogICAgIk5vcm1hbGlkYWQsIGhvbW9jZWRhc3RpY2lkYWQsIGluZGVwZW5kZW5jaWEiLAogICAgIk5vcm1hbGlkYWQsIGhvbW9jZWRhc3RpY2lkYWQsIGluZGVwZW5kZW5jaWEiLAogICAgIk5vcm1hbGlkYWQsIGVzZmVyaWNpZGFkLCBpbmRlcGVuZGVuY2lhIGVudHJlIHN1amV0b3MiLAogICAgIk5vcm1hbGlkYWQsIGhvbW9jZWRhc3RpY2lkYWQsIGVzdHJ1Y3R1cmEgamVyw6FycXVpY2EiLAogICAgIk5vcm1hbGlkYWQsIGhvbW9jZWRhc3RpY2lkYWQsIGluZGVwZW5kZW5jaWEsIGVzZmVyaWNpZGFkIChzaSBhcGxpY2EpIgogICksCiAgIk1vZGVsbyBNYXRlbcOhdGljbyIgPSBjKAogICAgIiRZX3tpan0gPSBcXG11ICsgXFx0YXVfaSArIFxcZXBzaWxvbl97aWp9JCIsCiAgICAiJFlfe2lqa30gPSBcXG11ICsgXFxhbHBoYV9pICsgXFxiZXRhX2ogKyAoXFxhbHBoYVxcYmV0YSlfe2lqfSArIFxcZXBzaWxvbl97aWprfSQiLAogICAgIiRZX3tpan0gPSBcXG11ICsgXFxhbHBoYV9pICsgXFxwaV9qICsgXFxlcHNpbG9uX3tpan0kIiwKICAgICIkWV97aWprfSA9IFxcbXUgKyBcXGFscGhhX2kgKyBcXGJldGFfe2ooaSl9ICsgXFxlcHNpbG9uX3tpamt9JCIsCiAgICAiRXh0ZW5zacOzbiBkZWwgbW9kZWxvIGRlIGRvcyBmYWN0b3JlcyBjb24gbcO6bHRpcGxlcyBpbnRlcmFjY2lvbmVzIgogICksCiAgIkhpcMOzdGVzaXMgTnVsYSAoSOKCgCkiID0gYygKICAgICJUb2RhcyBsYXMgbWVkaWFzIGdydXBhbGVzIHNvbiBpZ3VhbGVzICgkXFxtdV8xID0gXFxtdV8yID0gXFxkb3RzID0gXFxtdV9rJCkiLAogICAgIk5vIGhheSBlZmVjdG8gcHJpbmNpcGFsIGRlIEEsIG5pIGRlIEIsIG5pIGludGVyYWNjacOzbiIsCiAgICAiTm8gaGF5IGVmZWN0byBkZWwgdGllbXBvL3RyYXRhbWllbnRvIHNvYnJlIGxhIG1lZGlhIiwKICAgICJObyBoYXkgZGlmZXJlbmNpYSBlbnRyZSBuaXZlbGVzIHN1cGVyaW9yZXMgKGUuZy4sIGhvc3BpdGFsZXMpIiwKICAgICJObyBoYXkgZWZlY3RvIHNpZ25pZmljYXRpdm8gZGUgbG9zIGZhY3RvcmVzIG5pIHN1cyBpbnRlcmFjY2lvbmVzIgogICksCiAgIkFwbGljYWNpw7NuIGVuIFNhbHVkIiA9IGMoCiAgICAiQ29tcGFyYXIgZWZlY3RvIGRlIHRyZXMgdHJhdGFtaWVudG9zIHNvYnJlIGdsdWNvc2EiLAogICAgIkV2YWx1YXIgdHJhdGFtaWVudG8geSBlZGFkIHNvYnJlIGNvbGVzdGVyb2wiLAogICAgIk1lZGlyIGNhbWJpb3MgZW4gSGJBMWMgYW50ZXMvZHVyYW50ZS9kZXNwdcOpcyBkZSB0cmF0YW1pZW50byIsCiAgICAiQ29tcGFyYXIgdGllbXBvcyBkZSBlc3BlcmEgZW50cmUgaG9zcGl0YWxlcyAobcOpZGljb3MgYW5pZGFkb3MpIiwKICAgICJFc3R1ZGlhciBjb21iaW5hY2lvbmVzIGRlIGbDoXJtYWNvcywgZG9zaXMgeSBnw6luZXJvIgogICksCiAgIkVqZW1wbG8gUHLDoWN0aWNvIiA9IGMoCiAgICAiSW5zdWxpbmEgdnMuIG1ldGZvcm1pbmEgdnMuIHBsYWNlYm8gZW4gcGFjaWVudGVzIGRpYWLDqXRpY29zIiwKICAgICJGw6FybWFjbyBtw6FzIGVmZWN0aXZvIGVuIGFkdWx0b3MgbWF5b3JlcyBxdWUgZW4gasOzdmVuZXMiLAogICAgIlJlZHVjY2nDs24gcHJvZ3Jlc2l2YSBkZSBIYkExYyBlbiAyMCBwYWNpZW50ZXMgYSBsb3MgMyB5IDYgbWVzZXMiLAogICAgIkRpZmVyZW5jaWFzIGVudHJlIGhvc3BpdGFsZXMsIHBlcm8gbm8gZW50cmUgbcOpZGljb3MgZGVudHJvIGRlIGVsbG9zIiwKICAgICJJbnRlcmFjY2nDs24gc2lnbmlmaWNhdGl2YSBlbnRyZSBkaWV0YSwgZWplcmNpY2lvIHkgZWRhZCBlbiBww6lyZGlkYSBkZSBwZXNvIgogICksCiAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFCikKCiMgTW9zdHJhciB0YWJsYQprYWJsZSh0YWJsYV9hbm92YSwgImh0bWwiLCAKICAgICAgY2FwdGlvbiA9ICJUYWJsYSA0OiBSZXN1bWVuIGRlIGRpc2XDsW9zIEFOT1ZBIGFwbGljYWRvcyBhbCBzZWN0b3Igc2FsdWQiKSAlPiUKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJyZXNwb25zaXZlIiksIGZ1bGxfd2lkdGggPSBGQUxTRSkgJT4lCiAgc2Nyb2xsX2JveCh3aWR0aCA9ICIxMDAlIiwgaGVpZ2h0ID0gIjUwMHB4IikKCmBgYAoKIyA1LiBSZWdyZXNpw7NuIHkgTW9kZWxvcyBMaW5lYWxlcyBwYXJhIGVsIFNlY3RvciBTYWx1ZAoKRXN0ZSB0ZW1hcmlvIGRlc2Fycm9sbGEgbG9zIGNvbmNlcHRvcyBkZSByZWdyZXNpw7NuIHkgbW9kZWxvcyBsaW5lYWxlcwpjb24gdW4gZW5mb3F1ZSBlbiBhcGxpY2FjaW9uZXMgZW4gZWwgc2VjdG9yIHNhbHVkLCBwcm9wb3JjaW9uYW5kbwpleHBsaWNhY2lvbmVzIGRldGFsbGFkYXMsIGVqZW1wbG9zIHByw6FjdGljb3MgeSBhcGxpY2FjaW9uZXMgcmVsZXZhbnRlcwpwYXJhIHByb2Zlc2lvbmFsZXMgbcOpZGljb3MsIGludmVzdGlnYWRvcmVzIGNsw61uaWNvcyB5IGVwaWRlbWnDs2xvZ29zLiBMYQpyZWdyZXNpw7NuIGVzIHVuYSBoZXJyYW1pZW50YSBlc3RhZMOtc3RpY2EgZXNlbmNpYWwgcGFyYSBtb2RlbGFyCnJlbGFjaW9uZXMgZW50cmUgdmFyaWFibGVzLCBwcmVkZWNpciByZXN1bHRhZG9zIHkgZXZhbHVhciBmYWN0b3JlcyBkZQpyaWVzZ28gZW4gZXN0dWRpb3MgZGUgc2FsdWQsIGNvbW8gbGEgcmVsYWNpw7NuIGVudHJlIGVsIMOtbmRpY2UgZGUgbWFzYQpjb3Jwb3JhbCAoSU1DKSB5IGVsIHJpZXNnbyBkZSBkaWFiZXRlcyBvIGVsIGltcGFjdG8gZGUgdW4gdHJhdGFtaWVudG8gZW4KbGEgcHJlc2nDs24gYXJ0ZXJpYWwuCgojIyA1LjEgUmVncmVzacOzbiBMaW5lYWwgU2ltcGxlCgojIyMgTW9kZWxvIHkgU3VwdWVzdG9zCgpMYSByZWdyZXNpw7NuIGxpbmVhbCBzaW1wbGUgbW9kZWxhIGxhIHJlbGFjacOzbiBlbnRyZSB1bmEgdmFyaWFibGUKZGVwZW5kaWVudGUgY29udGludWEgKFwkIFkgJCkgeSB1bmEgdmFyaWFibGUgaW5kZXBlbmRpZW50ZSAoJCBYIFwkKQptZWRpYW50ZSB1bmEgbMOtbmVhIHJlY3RhLgoKKipNb2RlbG86KiogJCQKWV9pID0gXGJldGFfMCArIFxiZXRhXzEgWF9pICsgXGVwc2lsb25faQokJCBEb25kZToKCi0gICBcJCBZX2kgXCQ6IFZhcmlhYmxlIGRlcGVuZGllbnRlIChlLmcuLCBwcmVzacOzbiBhcnRlcmlhbCkuCi0gICBcJCBYX2kgXCQ6IFZhcmlhYmxlIGluZGVwZW5kaWVudGUgKGUuZy4sIGRvc2lzIGRlIHVuIG1lZGljYW1lbnRvKS4KLSAgIFwkIFxiZXRhXF8wIFwkOiBJbnRlcmNlcHRvICh2YWxvciBkZSBcJCBZIFwkIGN1YW5kbyBcJCBYID0gMCBcJCkuCi0gICBcJCBcYmV0YVxfMSBcJDogUGVuZGllbnRlIChjYW1iaW8gZW4gXCQgWSBcJCBwb3IgdW5pZGFkIGRlIGNhbWJpbyBlbgogICAgXCQgWCBcJCkuCi0gICBcJCBcZXBzaWxvblxfaSBcJDogRXJyb3IgYWxlYXRvcmlvLCBhc3VtaWRvIFwkIFxlcHNpbG9uXF9pIFxzaW0gTigwLAogICAgXHNpZ21hXF4yKSBcJC4KCioqU3VwdWVzdG9zOioqCgotICAgKipMaW5lYWxpZGFkOioqIExhIHJlbGFjacOzbiBlbnRyZSBcJCBYIFwkIHkgXCQgWSBcJCBlcyBsaW5lYWwuCi0gICAqKkluZGVwZW5kZW5jaWE6KiogTG9zIGVycm9yZXMgXCQgXGVwc2lsb25cX2kgXCQgc29uIGluZGVwZW5kaWVudGVzCiAgICBlbnRyZSBzw60uCi0gICAqKkhvbW9jZWRhc3RpY2lkYWQ6KiogTGEgdmFyaWFuemEgZGUgbG9zIGVycm9yZXMgZXMgY29uc3RhbnRlIChcJAogICAgXHRleHR7VmFyfShcZXBzaWxvblxfaSkgPSBcc2lnbWFcXjIgXCQpLgotICAgKipOb3JtYWxpZGFkOioqIExvcyBlcnJvcmVzIHNpZ3VlbiB1bmEgZGlzdHJpYnVjacOzbiBub3JtYWwsCiAgICB2ZXJpZmljYWJsZSBjb24gZ3LDoWZpY29zIFEtUSBvIHBydWViYXMgY29tbyBTaGFwaXJvLVdpbGsuCi0gICAqKkF1c2VuY2lhIGRlIHZhbG9yZXMgYXTDrXBpY29zIGV4dHJlbW9zOioqIExvcyB2YWxvcmVzIGF0w61waWNvcwogICAgcHVlZGVuIGRpc3RvcnNpb25hciBsb3MgcmVzdWx0YWRvcy4KCioqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogTW9kZWxhciBsYSByZWxhY2nDs24gZW50cmUgZWwgSU1DIChcJCBYCiQpIHkgZWwgbml2ZWwgZGUgZ2x1Y29zYSBlbiBzYW5ncmUgKCQgWSBcJCkgcGFyYSBldmFsdWFyIGVsIHJpZXNnbyBkZQpkaWFiZXRlcy4KCioqRWplbXBsbyBwcsOhY3RpY286KiogRW4gdW4gZXN0dWRpbywgc2UgbW9kZWxhIGxhIHByZXNpw7NuIGFydGVyaWFsCnNpc3TDs2xpY2EgKFwkIFkKJCkgZW4gZnVuY2nDs24gZGUgbGEgZG9zaXMgZGlhcmlhIGRlIHVuIGFudGloaXBlcnRlbnNpdm8gKCQgWCBcJCkuIFNlCnZlcmlmaWNhIGxhIGxpbmVhbGlkYWQgY29uIHVuIGdyw6FmaWNvIGRlIGRpc3BlcnNpw7NuIHkgbGEgbm9ybWFsaWRhZCBkZQpsb3MgcmVzaWR1b3MgY29uIHVuIGdyw6FmaWNvIFEtUS4KCiMjIyBFc3RpbWFjacOzbiBwb3IgTcOtbmltb3MgQ3VhZHJhZG9zCgpMYSBlc3RpbWFjacOzbiBwb3IgbcOtbmltb3MgY3VhZHJhZG9zIChPTFMpIGJ1c2NhIGxvcyB2YWxvcmVzIGRlIFwkClxiZXRhXF8wIFwkIHkgXCQgXGJldGFcXzEgXCQgcXVlIG1pbmltaXphbiBsYSBzdW1hIGRlIGxvcyBjdWFkcmFkb3MgZGUKbG9zIGVycm9yZXM6ICQkClx0ZXh0e1NDRX0gPSBcc3VtX3tpPTF9Xm4gKFlfaSAtIFxoYXR7WX1faSleMiA9IFxzdW1fe2k9MX1ebiAoWV9pIC0gXGJldGFfMCAtIFxiZXRhXzEgWF9pKV4yCiQkCgoqKkbDs3JtdWxhczoqKgoKLSAgICoqUGVuZGllbnRlOioqICQkCiAgICBcaGF0e1xiZXRhfV8xID0gXGZyYWN7XHN1bSAoWF9pIC0gXGJhcntYfSkoWV9pIC0gXGJhcntZfSl9e1xzdW0gKFhfaSAtIFxiYXJ7WH0pXjJ9CiAgICAkJAotICAgKipJbnRlcmNlcHRvOioqICQkCiAgICBcaGF0e1xiZXRhfV8wID0gXGJhcntZfSAtIFxoYXR7XGJldGF9XzEgXGJhcntYfQogICAgJCQKLSAgICoqUHJlZGljY2nDs246KiogXCQgXGhhdHtZfVxfaSA9IFxoYXR7XGJldGF9XF8wICsgXGhhdHtcYmV0YX1cXzEgWF9pCiAgICBcJC4KLSAgICoqVmFyaWFuemEgZGVsIGVycm9yOioqICQkCiAgICBcaGF0e1xzaWdtYX1eMiA9IFxmcmFje1xzdW0gKFlfaSAtIFxoYXR7WX1faSleMn17bi0yfQogICAgJCQKCioqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogRXN0aW1hciBjw7NtbyBlbCB0aWVtcG8gZGUgZWplcmNpY2lvIHNlbWFuYWwgKFwkClggJCkgYWZlY3RhIGVsIGNvbGVzdGVyb2wgTERMICgkIFkgXCQpLgoKKipFamVtcGxvIHByw6FjdGljbzoqKiBFbiA1MCBwYWNpZW50ZXMsIGNvbiBcJCBYIFwkIChob3JhcyBkZSBlamVyY2ljaW8pCnkgXCQgWSBcJCAoY29sZXN0ZXJvbCBMREwsIG1nL2RMKSwgc2UgY2FsY3VsYSBcJCBcaGF0e1xiZXRhfVxfMSA9IC0yLjUKXCQsIGluZGljYW5kbyBxdWUgY2FkYSBob3JhIGFkaWNpb25hbCBkZSBlamVyY2ljaW8gcmVkdWNlIGVsIGNvbGVzdGVyb2wKZW4gMi41IG1nL2RMLCB5IFwkIFxoYXR7XGJldGF9XF8wID0gMTUwIFwkLiBMYSBlY3VhY2nDs24gZXM6ICQkClxoYXR7WX0gPSAxNTAgLSAyLjVYCiQkCgojIyMgSW5mZXJlbmNpYSBzb2JyZSBQYXLDoW1ldHJvcyAoUGVuZGllbnRlLCBJbnRlcmNlcHRvKQoKTGEgaW5mZXJlbmNpYSBldmFsw7phIHNpIGxvcyBwYXLDoW1ldHJvcyBcJCBcYmV0YVxfMCBcJCB5IFwkIFxiZXRhXF8xIFwkCnNvbiBlc3RhZMOtc3RpY2FtZW50ZSBzaWduaWZpY2F0aXZvcy4KCioqUHJ1ZWJhcyBkZSBoaXDDs3Rlc2lzOioqCgotICAgXCpcKlBhcmEgXCQgXGJldGFcXzEgXCQ6XCpcKgogICAgLSAgIFwkIEhfMDogXGJldGFcXzEgPSAwIFwkIChubyBoYXkgcmVsYWNpw7NuIGxpbmVhbCkuCiAgICAtICAgXCQgSF8xOiBcYmV0YVxfMSBcbmVxIDAgXCQuCiAgICAtICAgKipFc3RhZMOtc3RpY286KiogJCQKICAgICAgICB0ID0gXGZyYWN7XGhhdHtcYmV0YX1fMX17XHRleHR7U0V9KFxoYXR7XGJldGF9XzEpfQogICAgICAgICQkIERvbmRlIFwkIFx0ZXh0e1NFfShcaGF0e1xiZXRhfVxfMSkgPQogICAgICAgIFxzcXJ0e1xmcmFje1xoYXR7XHNpZ21hfV4yfXtcc3VtIChYX2kgLSBcYmFye1h9KV4yfX0gXCQsIGNvbiBcJAogICAgICAgIG4tMiBcJCBncmFkb3MgZGUgbGliZXJ0YWQuCi0gICBTaW1pbGFyIHBhcmEgXCQgXGJldGFcXzAgXCQuCgoqKkludGVydmFsb3MgZGUgY29uZmlhbnphOioqCgotICAgUGFyYSBcJCBcYmV0YVxfMSBcJDogJCQKICAgIFxoYXR7XGJldGF9XzEgXHBtIHRfe1xhbHBoYS8yLCBuLTJ9IFxjZG90IFx0ZXh0e1NFfShcaGF0e1xiZXRhfV8xKQogICAgJCQKCioqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogRGV0ZXJtaW5hciBzaSBlbCBJTUMgYWZlY3RhIHNpZ25pZmljYXRpdmFtZW50ZQplbCByaWVzZ28gZGUgaGlwZXJ0ZW5zacOzbi4KCioqRWplbXBsbyBwcsOhY3RpY286KiogRW4gZWwgbW9kZWxvIGFudGVyaW9yLCBcJCBcaGF0e1xiZXRhfVxfMSA9IC0yLjUKXCQsIFwkIFx0ZXh0e1NFfShcaGF0e1xiZXRhfSoxKSA9IDAuOCBcJCwgXCQgdCA9IC0yLjUgLyAwLjggPSAtMy4xMjUgXCQuCkNvbiBcJCB0KnswLjAyNSwgNDh9IFxhcHByb3ggMi4wMSBcJCwgc2UgcmVjaGF6YSBcJCBIXzAgXCQgKFwkIHAgXDwgMC4wNQpcJCksIGluZGljYW5kbyBxdWUgZWwgZWplcmNpY2lvIHJlZHVjZSBzaWduaWZpY2F0aXZhbWVudGUgZWwgY29sZXN0ZXJvbC4KRWwgSUMgYWwgOTUlIHBhcmEgXCQgXGJldGFcXzEgXCQgZXM6ICQkCi0yLjUgXHBtIDIuMDEgXGNkb3QgMC44IFxhcHByb3ggKC00LjExLCAtMC44OSkKJCQKCioqQm9uZGFkIGRlIGFqdXN0ZToqKgoKLSAgICoqUsKyOioqIFByb3BvcmNpw7NuIGRlIGxhIHZhcmlhbnphIGRlIFwkIFkgXCQgZXhwbGljYWRhIHBvciBcJCBYIFwkLgogICAgXCQgUlxeMiA9IDEgLSBcZnJhY3tcdGV4dHtTQ1J9fXtcdGV4dHtTQ1R9fSBcJCwgZG9uZGUgXCQgXHRleHR7U0NSfQogICAgPSBcc3VtIChZX2kgLSBcaGF0e1l9XF9pKVxeMiBcJCB5IFwkIFx0ZXh0e1NDVH0gPSBcc3VtIChZX2kgLQogICAgXGJhcntZfSlcXjIgXCQuCi0gICAqKkVqZW1wbG86KiogU2kgXCQgUlxeMiA9IDAuNjUgXCQsIGVsIDY1JSBkZSBsYSB2YXJpYWJpbGlkYWQgZW4gZWwKICAgIGNvbGVzdGVyb2wgc2UgZXhwbGljYSBwb3IgZWwgZWplcmNpY2lvLgoKIyMgNS4yIFJlZ3Jlc2nDs24gTGluZWFsIE3Dumx0aXBsZQoKTGEgcmVncmVzacOzbiBsaW5lYWwgbcO6bHRpcGxlIGV4dGllbmRlIGVsIG1vZGVsbyBzaW1wbGUgcGFyYSBpbmNsdWlyCnZhcmlhcyB2YXJpYWJsZXMgaW5kZXBlbmRpZW50ZXMgKFwkIFhfMSwgWF8yLCBcZG90cywgWF9wIFwkKS4KCioqTW9kZWxvOioqICQkCllfaSA9IFxiZXRhXzAgKyBcYmV0YV8xIFhfe2kxfSArIFxiZXRhXzIgWF97aTJ9ICsgXGRvdHMgKyBcYmV0YV9wIFhfe2lwfSArIFxlcHNpbG9uX2kKJCQgRG9uZGUgXCQgXGVwc2lsb25cX2kgXHNpbSBOKDAsIFxzaWdtYVxeMikgXCQuCgoqKlN1cHVlc3RvczoqKiBJZ3VhbCBxdWUgZW4gbGEgcmVncmVzacOzbiBzaW1wbGUsIG3DoXMgbGEgYXVzZW5jaWEgZGUKbXVsdGljb2xpbmVhbGlkYWQgc2V2ZXJhIGVudHJlIGxhcyBcJCBYIFwkLgoKKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBQcmVkZWNpciBlbCBuaXZlbCBkZSBnbHVjb3NhIGVuIHNhbmdyZSAoXCQgWQokKSB1c2FuZG8gSU1DICgkIFhfMSAkKSwgZWRhZCAoJCBYXzIgJCksIHkgYWN0aXZpZGFkIGbDrXNpY2EgKCQgWF8zIFwkKS4KCioqRWplbXBsbyBwcsOhY3RpY286KiogTW9kZWxhciBlbCByaWVzZ28gY2FyZGlvdmFzY3VsYXIgKFwkIFkKJCkgZW4gZnVuY2nDs24gZGUgcHJlc2nDs24gYXJ0ZXJpYWwgKCQgWF8xICQpLCBjb2xlc3Rlcm9sICgkIFhfMgokKSwgeSB0YWJhcXVpc21vICgkIFhfMyBcJCkuCgojIyMgU2VsZWNjacOzbiBkZSBWYXJpYWJsZXMgKEZvcndhcmQsIEJhY2t3YXJkLCBTdGVwd2lzZSkKCkxhIHNlbGVjY2nDs24gZGUgdmFyaWFibGVzIGlkZW50aWZpY2EgZWwgc3ViY29uanVudG8gZGUgcHJlZGljdG9yZXMgbcOhcwpyZWxldmFudGVzIHBhcmEgZXZpdGFyIG1vZGVsb3Mgc29icmVhanVzdGFkb3MgbyByZWR1bmRhbnRlcy4KCioqRm9yd2FyZCBTZWxlY3Rpb246KioKCi0gICBDb21pZW56YSBjb24gdW4gbW9kZWxvIG51bG8gKHNpbiBwcmVkaWN0b3JlcykgeSBhw7FhZGUgdmFyaWFibGVzIHVuYQogICAgcG9yIHVuYSwgc2VsZWNjaW9uYW5kbyBsYSBxdWUgbcOhcyBtZWpvcmEgZWwgYWp1c3RlIChlLmcuLCBtZW5vciBcJCBwCiAgICBcJC12YWxvciBvIG1heW9yIFwkIFJcXjIgXCQpLgotICAgKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBDb25zdHJ1aXIgdW4gbW9kZWxvIHBhcmEgcHJlZGVjaXIgZWwgcmllc2dvCiAgICBkZSBkaWFiZXRlcyBlbXBlemFuZG8gY29uIGVsIElNQyB5IGHDsWFkaWVuZG8gZWRhZCwgZ2x1Y29zYSBiYXNhbCwKICAgIGV0Yy4KCioqQmFja3dhcmQgRWxpbWluYXRpb246KioKCi0gICBDb21pZW56YSBjb24gdG9kYXMgbGFzIHZhcmlhYmxlcyB5IGVsaW1pbmEgbGFzIG1lbm9zIHNpZ25pZmljYXRpdmFzCiAgICAobWF5b3IgXCQgcCBcJC12YWxvcikgdW5hIHBvciB1bmEuCi0gICAqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIFNpbXBsaWZpY2FyIHVuIG1vZGVsbyBjb24gbcO6bHRpcGxlcwogICAgZmFjdG9yZXMgZGUgcmllc2dvIGNhcmRpb3Zhc2N1bGFyLCBlbGltaW5hbmRvIHZhcmlhYmxlcyBubwogICAgc2lnbmlmaWNhdGl2YXMgY29tbyBlbCBjb25zdW1vIGRlIGNhZmXDrW5hLgoKKipTdGVwd2lzZSBTZWxlY3Rpb246KioKCi0gICBDb21iaW5hIGZvcndhcmQgeSBiYWNrd2FyZCwgYcOxYWRpZW5kbyBvIGVsaW1pbmFuZG8gdmFyaWFibGVzIGVuIGNhZGEKICAgIHBhc28gc2Vnw7puIGNyaXRlcmlvcyBjb21vIGVsIENyaXRlcmlvIGRlIEluZm9ybWFjacOzbiBkZSBBa2Fpa2UgKEFJQykKICAgIG8gZWwgXCQgcCBcJC12YWxvci4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogRW4gdW4gZXN0dWRpbyBjb24gMTAgcHJlZGljdG9yZXMgKElNQywgZWRhZCwKICAgIGNvbGVzdGVyb2wsIGV0Yy4pLCBlbCBzdGVwd2lzZSBzZWxlY2Npb25hIHVuIG1vZGVsbyBjb24gSU1DLCBlZGFkIHkKICAgIGdsdWNvc2EsIG1pbmltaXphbmRvIGVsIEFJQy4KCioqQ29uc2lkZXJhY2lvbmVzOioqCgotICAgUmllc2dvIGRlIHNvYnJlYWp1c3RlIGNvbiBkZW1hc2lhZGFzIHZhcmlhYmxlcy4KLSAgIFVzYXIgY3JpdGVyaW9zIGNvbW8gQUlDLCBCSUMgbyB2YWxpZGFjacOzbiBjcnV6YWRhIHBhcmEgZXZhbHVhcgogICAgbW9kZWxvcy4KLSAgIEVuIHNhbHVkLCBwcmlvcml6YXIgdmFyaWFibGVzIGNsw61uaWNhbWVudGUgcmVsZXZhbnRlcyAoZS5nLiwgcHJlc2nDs24KICAgIGFydGVyaWFsIHNvYnJlIHZhcmlhYmxlcyBtZW5vcyByZWxldmFudGVzIGNvbW8gaG9yYXMgZGUgc3Vlw7FvKS4KCiMjIyBNdWx0aWNvbGluZWFsaWRhZCB5IERpYWduw7NzdGljbwoKKipNdWx0aWNvbGluZWFsaWRhZDoqKiBPY3VycmUgY3VhbmRvIGxhcyB2YXJpYWJsZXMgaW5kZXBlbmRpZW50ZXMgZXN0w6FuCmFsdGFtZW50ZSBjb3JyZWxhY2lvbmFkYXMsIGxvIHF1ZSBwdWVkZSBpbmZsYXIgbGEgdmFyaWFuemEgZGUgbG9zCmNvZWZpY2llbnRlcyB5IGRpZmljdWx0YXIgbGEgaW50ZXJwcmV0YWNpw7NuLgoKKipEaWFnbsOzc3RpY286KioKCi0gICAqKkZhY3RvciBkZSBJbmZsYWNpw7NuIGRlIGxhIFZhcmlhbnphIChWSUYpOioqIFZJRiBcPiA1IG8gMTAgaW5kaWNhCiAgICBtdWx0aWNvbGluZWFsaWRhZCBwcm9ibGVtw6F0aWNhLgotICAgKipNYXRyaXogZGUgY29ycmVsYWNpw7NuOioqIENvcnJlbGFjaW9uZXMgYWx0YXMgKFwkIFx8clx8IFw+IDAuOCBcJCkKICAgIGVudHJlIHByZWRpY3RvcmVzLgoKKipTb2x1Y2lvbmVzOioqCgotICAgRWxpbWluYXIgdW5hIHZhcmlhYmxlIGNvcnJlbGFjaW9uYWRhLgotICAgVXNhciB0w6ljbmljYXMgY29tbyBhbsOhbGlzaXMgZGUgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMgKFBDQSkuCi0gICBDb21iaW5hciB2YXJpYWJsZXMgY29ycmVsYWNpb25hZGFzIChlLmcuLCBjcmVhciB1biDDrW5kaWNlIGRlCiAgICByaWVzZ28pLgoKKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBFbiB1biBtb2RlbG8gcGFyYSBwcmVkZWNpciBlbCByaWVzZ28gZGUKaW5mYXJ0bywgZWwgY29sZXN0ZXJvbCB0b3RhbCB5IGVsIGNvbGVzdGVyb2wgTERMIHB1ZWRlbiBlc3Rhcgpjb3JyZWxhY2lvbmFkb3MgKFZJRiBcPiAxMCksIHN1Z2lyaWVuZG8gZWxpbWluYXIgdW5vLgoKKipEaWFnbsOzc3RpY29zIGFkaWNpb25hbGVzOioqCgotICAgKipSZXNpZHVvczoqKiBWZXJpZmljYXIgbm9ybWFsaWRhZCAoUS1RIHBsb3QpLCBob21vY2VkYXN0aWNpZGFkCiAgICAoZ3LDoWZpY28gZGUgcmVzaWR1b3MgdnMuIHByZWRpY2hvcyksIHkgYXVzZW5jaWEgZGUgcGF0cm9uZXMuCi0gICAqKlZhbG9yZXMgYXTDrXBpY29zOioqIFVzYXIgbWVkaWRhcyBjb21vIGxhIGRpc3RhbmNpYSBkZSBDb29rIHBhcmEKICAgIGlkZW50aWZpY2FyIG9ic2VydmFjaW9uZXMgaW5mbHV5ZW50ZXMuCgoqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuIG1vZGVsbyBwYXJhIHByZWRlY2lyIGdsdWNvc2EsIHVuIFZJRiBkZSA4CnBhcmEgSU1DIHkgcGVzbyBzdWdpZXJlIG11bHRpY29saW5lYWxpZGFkLiBTZSBlbGltaW5hIGVsIHBlc28sIHkgbG9zCnJlc2lkdW9zIGNvbmZpcm1hbiBub3JtYWxpZGFkIHkgaG9tb2NlZGFzdGljaWRhZC4KCiMjIyBJbnRlcnByZXRhY2nDs24gZGUgQ29lZmljaWVudGVzCgoqKkludGVycHJldGFjacOzbjoqKgoKLSAgIFwkIFxiZXRhXF9qIFwkOiBDYW1iaW8gZW4gXCQgWSBcJCBwb3IgdW5pZGFkIGRlIGNhbWJpbyBlbiBcJCBYX2ogXCQsCiAgICBtYW50ZW5pZW5kbyBsYXMgZGVtw6FzIFwkIFggXCQgY29uc3RhbnRlcy4KLSAgICoqRWplbXBsbzoqKiBTaSBcJCBcYmV0YVxfMSA9IDAuNSBcJCBwYXJhIGVsIElNQyBlbiB1biBtb2RlbG8gZGUKICAgIGdsdWNvc2EsIHVuIGF1bWVudG8gZGUgMSB1bmlkYWQgZW4gZWwgSU1DIGluY3JlbWVudGEgbGEgZ2x1Y29zYSBlbgogICAgMC41IG1nL2RMLCBjb250cm9sYW5kbyBwb3Igb3RyYXMgdmFyaWFibGVzLgoKKipTaWduaWZpY2FuY2lhOioqIFBydWViYXMgdCBwYXJhIGNhZGEgXCQgXGJldGFcX2ogXCQgKFwkIEhfMDogXGJldGFcX2oKPSAwIFwkKS4KCioqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogRW4gdW4gbW9kZWxvIGNvbiBcJCBZID0gXCQgcmllc2dvCmNhcmRpb3Zhc2N1bGFyLCBcJCBYXzEgPSBcJCBwcmVzacOzbiBhcnRlcmlhbCwgXCQgWF8yID0gXCQgY29sZXN0ZXJvbCwgXCQKXGJldGFcXzEgPSAwLjMgXCQsIFwkIFxiZXRhXF8yID0gMC4yIFwkLCBpbmRpY2EgcXVlIGxhIHByZXNpw7NuIGFydGVyaWFsCnRpZW5lIHVuIG1heW9yIGltcGFjdG8gcG9yIHVuaWRhZC4KCioqRWplbXBsbyBwcsOhY3RpY286KiogVW4gbW9kZWxvIGNvbiBcJCBcaGF0e1l9ID0gNTAgKyAwLjRYXzEgKyAyWF8yIC0KMS41WF8zIFwkIChkb25kZSBcJCBYXzEgXCQ6IElNQywgXCQgWF8yIFwkOiBlZGFkLCBcJCBYXzMgXCQ6IGVqZXJjaWNpbykKcHJlZGljZSBlbCBjb2xlc3Rlcm9sLiBTaSBcJCBwIFw8IDAuMDUgXCQgcGFyYSBcJCBcYmV0YVxfMiBcJCwgbGEgZWRhZAplcyB1biBwcmVkaWN0b3Igc2lnbmlmaWNhdGl2by4KCiMjIDUuMyBNb2RlbG9zIExpbmVhbGVzIEdlbmVyYWxpemFkb3MgKEdMTSkKCkxvcyBtb2RlbG9zIGxpbmVhbGVzIGdlbmVyYWxpemFkb3MgKEdMTSkgZXh0aWVuZGVuIGxhIHJlZ3Jlc2nDs24gbGluZWFsCnBhcmEgbWFuZWphciB2YXJpYWJsZXMgZGVwZW5kaWVudGVzIG5vIG5vcm1hbGVzLCBjb21vIGRhdG9zIGJpbmFyaW9zIG8KZGUgY29udGVvLCBjb211bmVzIGVuIHNhbHVkLgoKKipFc3RydWN0dXJhIGRlbCBHTE06KioKCi0gICAqKkNvbXBvbmVudGUgYWxlYXRvcmlvOioqIERpc3RyaWJ1Y2nDs24gZGUgXCQgWSBcJCAoZS5nLiwgYmlub21pYWwsCiAgICBQb2lzc29uKS4KLSAgICoqQ29tcG9uZW50ZSBzaXN0ZW3DoXRpY286KiogQ29tYmluYWNpw7NuIGxpbmVhbCBkZSBwcmVkaWN0b3JlcyAoXCQKICAgIFxldGEgPSBcYmV0YVxfMCArIFxiZXRhXF8xIFhfMSArIFxkb3RzIFwkKS4KLSAgICoqRnVuY2nDs24gZGUgZW5sYWNlOioqIFJlbGFjaW9uYSBsYSBtZWRpYSBkZSBcJCBZIFwkIChcJAogICAgXG11ICQpIGNvbiBlbCBwcmVkaWN0b3IgbGluZWFsICgkIGcoXG11KSA9IFxldGEgXCQpLgoKKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBNb2RlbGFyIHJlc3VsdGFkb3MgYmluYXJpb3MgKGUuZy4sCnByZXNlbmNpYS9hdXNlbmNpYSBkZSBkaWFiZXRlcykgbyBjb250ZW9zIChlLmcuLCBuw7ptZXJvIGRlCmhvc3BpdGFsaXphY2lvbmVzKS4KCiMjIyBSZWdyZXNpw7NuIExvZ8Otc3RpY2EgeSBQb2lzc29uCgoqKlJlZ3Jlc2nDs24gbG9nw61zdGljYToqKgoKLSAgICoqVXNvOioqIE1vZGVsYXIgdW5hIHZhcmlhYmxlIGRlcGVuZGllbnRlIGJpbmFyaWEgKGUuZy4sIDAgPSBubwogICAgZW5mZXJtZWRhZCwgMSA9IGVuZmVybWVkYWQpLgotICAgKipNb2RlbG86KiogJCQKICAgIFxsb2dcbGVmdChcZnJhY3twfXsxLXB9XHJpZ2h0KSA9IFxiZXRhXzAgKyBcYmV0YV8xIFhfMSArIFxkb3RzICsgXGJldGFfcCBYX3AKICAgICQkIERvbmRlIFwkIHAgPSBQKFk9MSkgXCQsIHkgbGEgZnVuY2nDs24gZGUgZW5sYWNlIGVzIGVsIGxvZ2l0LgotICAgKipJbnRlcnByZXRhY2nDs246KioKICAgIC0gICBcJCBcZXhwKFxiZXRhXF9qKSBcJDogUmF6w7NuIGRlIG9kZHMgKG9kZHMgcmF0aW8pIHBvciB1bmlkYWQgZGUKICAgICAgICBjYW1iaW8gZW4gXCQgWF9qIFwkLgogICAgLSAgICoqRWplbXBsbzoqKiBTaSBcJCBcYmV0YVxfMSA9IDAuNCBcJCBwYXJhIGVsIElNQywgXCQgXGV4cCgwLjQpCiAgICAgICAgXGFwcHJveCAxLjQ5IFwkLCB1biBhdW1lbnRvIGRlIDEgdW5pZGFkIGVuIGVsIElNQyBhdW1lbnRhIGxvcwogICAgICAgIG9kZHMgZGUgZGlhYmV0ZXMgZW4gNDklLgotICAgKipFc3RpbWFjacOzbjoqKiBNw6F4aW1hIHZlcm9zaW1pbGl0dWQgKE1MRSkuCi0gICAqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIFByZWRlY2lyIGxhIHByb2JhYmlsaWRhZCBkZSBpbmZhcnRvIGVuCiAgICBmdW5jacOzbiBkZSBlZGFkLCBJTUMgeSB0YWJhcXVpc21vLgotICAgKipFamVtcGxvIHByw6FjdGljbzoqKiBFbiB1biBlc3R1ZGlvLCBsYSByZWdyZXNpw7NuIGxvZ8Otc3RpY2EgcHJlZGljZQogICAgbGEgcHJlc2VuY2lhIGRlIGhpcGVydGVuc2nDs24gKFwkIFkgPSAxIFwkKSBjb24gXCQgWF8xIFwkOiBlZGFkLCBcJAogICAgWF8yIFwkOiBJTUMuIFNpIFwkIFxiZXRhXF8xID0gMC4wNSBcJCwgXCQgXGV4cCgwLjA1KSBcYXBwcm94IDEuMDUKICAgIFwkLCBjYWRhIGHDsW8gZGUgZWRhZCBhdW1lbnRhIGxvcyBvZGRzIGRlIGhpcGVydGVuc2nDs24gZW4gNSUuCgoqKlJlZ3Jlc2nDs24gUG9pc3NvbjoqKgoKLSAgICoqVXNvOioqIE1vZGVsYXIgY29udGVvcyBvIHRhc2FzIChlLmcuLCBuw7ptZXJvIGRlIGhvc3BpdGFsaXphY2lvbmVzCiAgICBwb3IgcGFjaWVudGUpLgotICAgKipNb2RlbG86KiogJCQKICAgIFxsb2coXG11KSA9IFxiZXRhXzAgKyBcYmV0YV8xIFhfMSArIFxkb3RzICsgXGJldGFfcCBYX3AKICAgICQkIERvbmRlIFwkIFxtdSBcJCBlcyBsYSBtZWRpYSBkZSBsYSBkaXN0cmlidWNpw7NuIFBvaXNzb24uCi0gICAqKkludGVycHJldGFjacOzbjoqKgogICAgLSAgIFwkIFxleHAoXGJldGFcX2opIFwkOiBSYXrDs24gZGUgdGFzYXMgKHJhdGUgcmF0aW8pIHBvciB1bmlkYWQgZGUKICAgICAgICBjYW1iaW8gZW4gXCQgWF9qIFwkLgogICAgLSAgICoqRWplbXBsbzoqKiBTaSBcJCBcYmV0YVxfMSA9IDAuMiBcJCBwYXJhIGVsIHRhYmFxdWlzbW8sIFwkCiAgICAgICAgXGV4cCgwLjIpIFxhcHByb3ggMS4yMiBcJCwgbG9zIGZ1bWFkb3JlcyB0aWVuZW4gMjIlIG3DoXMKICAgICAgICBob3NwaXRhbGl6YWNpb25lcy4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogTW9kZWxhciBlbCBuw7ptZXJvIGRlIGNhc29zIGRlIGFzbWEgZW4KICAgIGZ1bmNpw7NuIGRlIGxhIGV4cG9zaWNpw7NuIGEgY29udGFtaW5hbnRlcy4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogRW4gdW4gZXN0dWRpbywgbGEgcmVncmVzacOzbiBQb2lzc29uIHByZWRpY2UgZWwKICAgIG7Dum1lcm8gZGUgdmlzaXRhcyBhIHVyZ2VuY2lhcyBwb3IgYXNtYSAoXCQgWSBcJCkgY29uIFwkIFhfMSBcJDoKICAgIG5pdmVsIGRlIGNvbnRhbWluYWNpw7NuLCBcJCBYXzIgXCQ6IGVkYWQuIFNpIFwkIFxiZXRhXF8xID0gMC4zCiAgICAkLCB1biBhdW1lbnRvIGVuIGxhIGNvbnRhbWluYWNpw7NuIGluY3JlbWVudGEgbGEgdGFzYSBkZSB2aXNpdGFzIGVuIDM1JSAoJAogICAgXGV4cCgwLjMpIFxhcHByb3ggMS4zNSBcJCkuCgojIyMgTW9kZWxvcyBwYXJhIERhdG9zIENhdGVnw7NyaWNvcyB5IGRlIENvbnRlbwoKKipSZWdyZXNpw7NuIGxvZ8Otc3RpY2EgbXVsdGlub21pYWw6KioKCi0gICAqKlVzbzoqKiBWYXJpYWJsZSBkZXBlbmRpZW50ZSBjYXRlZ8OzcmljYSBjb24gbcOhcyBkZSBkb3Mgbml2ZWxlcwogICAgKGUuZy4sIGVzdGFkaW8gZGUgY8OhbmNlcjogSSwgSUksIElJSSwgSVYpLgotICAgKipNb2RlbG86KiogRXh0aWVuZGUgbGEgcmVncmVzacOzbiBsb2fDrXN0aWNhLCB1c2FuZG8gdW5hIGNhdGVnb3LDrWEKICAgIGNvbW8gcmVmZXJlbmNpYSB5IG1vZGVsYW5kbyBsb3MgbG9naXRzIHBhcmEgbGFzIGRlbcOhcy4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogUHJlZGVjaXIgZWwgZXN0YWRpbyBkZWwgY8OhbmNlciBlbiBmdW5jacOzbgogICAgZGUgYmlvbWFyY2Fkb3JlcyB5IGZhY3RvcmVzIGRlIHJpZXNnby4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogTW9kZWxhciBlbCBlc3RhZGlvIGRlbCBjw6FuY2VyIGRlIG1hbWEgKEksIElJLAogICAgSUlJKSBjb24gcHJlZGljdG9yZXMgY29tbyBlZGFkIHkgdGFtYcOxbyBkZWwgdHVtb3IuIExvcyBvZGRzIHJhdGlvcwogICAgaW5kaWNhbiBjw7NtbyBjYWRhIHByZWRpY3RvciBhZmVjdGEgbGEgcHJvYmFiaWxpZGFkIGRlIGNhZGEgZXN0YWRpby4KCioqUmVncmVzacOzbiBwYXJhIGRhdG9zIG9yZGluYWxlczoqKgoKLSAgICoqVXNvOioqIFZhcmlhYmxlIGRlcGVuZGllbnRlIG9yZGluYWwgKGUuZy4sIGdyYXZlZGFkIGRlIHVuYQogICAgZW5mZXJtZWRhZDogbGV2ZSwgbW9kZXJhZGEsIHNldmVyYSkuCi0gICAqKk1vZGVsbzoqKiBNb2RlbG9zIGNvbW8gbGEgcmVncmVzacOzbiBsb2fDrXN0aWNhIG9yZGluYWwKICAgIChwcm9wb3JjaW9uYWwgb2RkcyBtb2RlbCkuCi0gICAqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIEV2YWx1YXIgbGEgZ3JhdmVkYWQgZGUgbG9zIHPDrW50b21hcyBkZQogICAgQ09WSUQtMTkgZW4gZnVuY2nDs24gZGUgbGEgZWRhZCB5IGNvbW9yYmlsaWRhZGVzLgotICAgKipFamVtcGxvIHByw6FjdGljbzoqKiBVbiBtb2RlbG8gb3JkaW5hbCBwcmVkaWNlIGxhIGdyYXZlZGFkIGRlIGxhCiAgICBhcnRyaXRpcyAobGV2ZSwgbW9kZXJhZGEsIHNldmVyYSkgY29uIHByZWRpY3RvcmVzIGNvbW8gZWRhZCB5IG5pdmVsCiAgICBkZSBpbmZsYW1hY2nDs24uCgoqKlJlZ3Jlc2nDs24gcGFyYSBjb250ZW9zIGNvbiBzb2JyZWRpc3BlcnNpw7NuOioqCgotICAgKipVc286KiogQ3VhbmRvIGxvcyBkYXRvcyBkZSBjb250ZW8gdGllbmVuIG1heW9yIHZhcmlhbnphIHF1ZSBsYQogICAgZXNwZXJhZGEgZW4gdW5hIFBvaXNzb24gKHNvYnJlZGlzcGVyc2nDs24pLgotICAgKipNb2RlbG9zOioqIFJlZ3Jlc2nDs24gYmlub21pYWwgbmVnYXRpdmEgbyBtb2RlbG9zIGRlIFBvaXNzb24gY29uCiAgICBzb2JyZWRpc3BlcnNpw7NuLgotICAgKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBNb2RlbGFyIGVsIG7Dum1lcm8gZGUgaW5mZWNjaW9uZXMKICAgIHJlc3BpcmF0b3JpYXMgZW4gcGFjaWVudGVzIGNvbiB2YXJpYWJpbGlkYWQgYWx0YSBkZWJpZG8gYSBmYWN0b3JlcwogICAgbm8gbWVkaWRvcy4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogVW4gbW9kZWxvIGJpbm9taWFsIG5lZ2F0aXZvIHByZWRpY2UgZWwgbsO6bWVybwogICAgZGUgaG9zcGl0YWxpemFjaW9uZXMgcG9yIGluZmVjY2lvbmVzIHJlc3BpcmF0b3JpYXMsIGFqdXN0YW5kbyBwb3IKICAgIGVkYWQgeSBleHBvc2ljacOzbiBhbWJpZW50YWwuCgojIyBSZWN1cnNvcyBwYXJhIGVsIEF1dG9lc3R1ZGlvIGVuIFNhbHVkCgojIyMgTGVjdHVyYXM6CgotICAgIkFwcGxpZWQgTGluZWFyIFN0YXRpc3RpY2FsIE1vZGVscyIgZGUgS3V0bmVyIGV0IGFsLiAoQ2Fww610dWxvcwogICAgc29icmUgcmVncmVzacOzbiBsaW5lYWwpLgotICAgIkdlbmVyYWxpemVkIExpbmVhciBNb2RlbHMiIGRlIE1jQ3VsbGFnaCB5IE5lbGRlciAoQ2Fww610dWxvcyBzb2JyZQogICAgR0xNKS4KLSAgICJCaW9zdGF0aXN0aWNzOiBBIEZvdW5kYXRpb24gZm9yIEFuYWx5c2lzIGluIHRoZSBIZWFsdGggU2NpZW5jZXMiIGRlCiAgICBEYW5pZWwgKENhcMOtdHVsb3MgMTAtMTEpLgoKIyMjIEVqZXJjaWNpb3MgcHLDoWN0aWNvczoKCi0gICBSZWFsaXphciByZWdyZXNpw7NuIGxpbmVhbCBzaW1wbGUgcGFyYSBtb2RlbGFyIHJlbGFjaW9uZXMgZW50cmUKICAgIGJpb21hcmNhZG9yZXMgKGUuZy4sIElNQyB5IGdsdWNvc2EpLgotICAgQ29uc3RydWlyIG1vZGVsb3MgZGUgcmVncmVzacOzbiBtw7psdGlwbGUgcGFyYSBwcmVkZWNpciByaWVzZ29zCiAgICBjYXJkaW92YXNjdWxhcmVzLCB2ZXJpZmljYW5kbyBtdWx0aWNvbGluZWFsaWRhZCB5IHJlc2lkdW9zLgotICAgQXBsaWNhciByZWdyZXNpw7NuIGxvZ8Otc3RpY2EgeSBQb2lzc29uIGEgZGF0b3MgZGUgc2FsdWQgKGUuZy4sCiAgICBwcmVkaWNjacOzbiBkZSBkaWFiZXRlcywgY29udGVvIGRlIGhvc3BpdGFsaXphY2lvbmVzKS4KCiMjIyBIZXJyYW1pZW50YXMgY29tcHV0YWNpb25hbGVzOgoKLSAgICoqUjoqKiBQYXF1ZXRlcyBzdGF0cyAobG0sIGdsbSksIGNhciAoVklGLCBkaWFnbsOzc3RpY29zKSwgTUFTUwogICAgKHJlZ3Jlc2nDs24gYmlub21pYWwgbmVnYXRpdmEpLgogICAgLSAgICoqRWplbXBsbzoqKiBgbG0oZ2x1Y29zYSB+IElNQywgZGF0YT1kYXRvcylgIHBhcmEgcmVncmVzacOzbgogICAgICAgIHNpbXBsZTsgYGdsbShkaWFiZXRlcyB+IElNQyArIGVkYWQsIGZhbWlseT1iaW5vbWlhbClgIHBhcmEKICAgICAgICBsb2fDrXN0aWNhLgotICAgKipQeXRob246KiogTGlicmVyw61hcyBzdGF0c21vZGVscyAoc3RhdHNtb2RlbHMuZm9ybXVsYS5hcGkub2xzLAogICAgZ2xtKSwgc2Npa2l0LWxlYXJuIChwYXJhIHNlbGVjY2nDs24gZGUgdmFyaWFibGVzKS4KICAgIC0gICAqKkVqZW1wbG86KioKICAgICAgICBgc21mLm9scygnZ2x1Y29zYSB+IElNQyArIGVkYWQnLCBkYXRhPWRhdG9zKS5maXQoKWA7CiAgICAgICAgYHNtZi5nbG0oJ2hvc3BpdGFsaXphY2lvbmVzIH4gY29udGFtaW5hY2lvbicsIGZhbWlseT1zbS5mYW1pbGllcy5Qb2lzc29uKCkpYC4KCiMjIyBCYXNlcyBkZSBkYXRvczoKCi0gICBOSEFORVMgcGFyYSBkYXRvcyBkZSBiaW9tYXJjYWRvcmVzIChlLmcuLCBnbHVjb3NhLCBjb2xlc3Rlcm9sKS4KLSAgIENsaW5pY2FsVHJpYWxzLmdvdiBwYXJhIGRhdG9zIGRlIGVuc2F5b3MgY2zDrW5pY29zLgotICAgRGF0YXNldHMgZGUgbGEgT01TIHBhcmEgZXN0dWRpb3MgZXBpZGVtaW9sw7NnaWNvcyAoZS5nLiwgcHJldmFsZW5jaWEKICAgIGRlIGRpYWJldGVzKS4KCiMgVGFibGEgUmVzdW1lbjogUmVncmVzacOzbiB5IE1vZGVsb3MgTGluZWFsZXMgZW4gZWwgU2VjdG9yIFNhbHVkCgpgYGB7ciByZWdyZXNpb24tdGFibGUsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2FzaXMnLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCgojIENyZWFyIGxhIHRhYmxhCnRhYmxhX3JlZ3Jlc2lvbiA8LSBkYXRhLmZyYW1lKAogICJUaXBvIGRlIE1vZGVsbyIgPSBjKAogICAgIlJlZ3Jlc2nDs24gTGluZWFsIFNpbXBsZSIsCiAgICAiUmVncmVzacOzbiBMaW5lYWwgTcO6bHRpcGxlIiwKICAgICJSZWdyZXNpw7NuIExvZ8Otc3RpY2EiLAogICAgIlJlZ3Jlc2nDs24gUG9pc3NvbiIsCiAgICAiUmVncmVzacOzbiBMb2fDrXN0aWNhIE11bHRpbm9taWFsIiwKICAgICJSZWdyZXNpw7NuIE9yZGluYWwiLAogICAgIlJlZ3Jlc2nDs24gQmlub21pYWwgTmVnYXRpdmEiCiAgKSwKICAiU3VwdWVzdG9zIENsYXZlIiA9IGMoCiAgICAiTGluZWFsaWRhZCwgaW5kZXBlbmRlbmNpYSwgaG9tb2NlZGFzdGljaWRhZCwgbm9ybWFsaWRhZCBkZSBlcnJvcmVzIiwKICAgICJJZ3VhbCBxdWUgcmVncmVzacOzbiBzaW1wbGUsIG3DoXMgYXVzZW5jaWEgZGUgbXVsdGljb2xpbmVhbGlkYWQiLAogICAgIkluZGVwZW5kZW5jaWEsIHZhbGlkZXogZGVsIG1vZGVsbyBsb2fDrXN0aWNvLCBhdXNlbmNpYSBkZSBzZXBhcmFjacOzbiIsCiAgICAiSW5kZXBlbmRlbmNpYSwgbWVkaWEgPSB2YXJpYW56YSAoZXF1aWRpc3BlcnNpw7NuKSIsCiAgICAiSW5kZXBlbmRlbmNpYSwgcHJvcG9yY2lvbmVzIHBhcmFsZWxhcyAocHJvcG9ydGlvbmFsIG9kZHMpIiwKICAgICJJbmRlcGVuZGVuY2lhLCByZWxhY2nDs24gbG9nw61zdGljYSBlbnRyZSBjYXRlZ29yw61hcyIsCiAgICAiSW5kZXBlbmRlbmNpYSwgc29icmVkaXNwZXJzacOzbiAodmFyaWFuemEgPiBtZWRpYSkiCiAgKSwKICAiRWN1YWNpw7NuIGRlbCBNb2RlbG8iID0gYygKICAgICIkWV9pID0gXFxiZXRhXzAgKyBcXGJldGFfMSBYX2kgKyBcXGVwc2lsb25faSQiLAogICAgIiRZX2kgPSBcXGJldGFfMCArIFxcYmV0YV8xIFhfe2kxfSArIFxcZG90cyArIFxcYmV0YV9wIFhfe2lwfSArIFxcZXBzaWxvbl9pJCIsCiAgICAiJFxcbG9nXFxsZWZ0KFxcZnJhY3twfXsxLXB9XFxyaWdodCkgPSBcXGJldGFfMCArIFxcYmV0YV8xIFhfMSArIFxcZG90cyArIFxcYmV0YV9wIFhfcCQiLAogICAgIiRcXGxvZyhcXG11KSA9IFxcYmV0YV8wICsgXFxiZXRhXzEgWF8xICsgXFxkb3RzICsgXFxiZXRhX3AgWF9wJCIsCiAgICAiTG9naXRzIG3Dumx0aXBsZXMgdnMuIGNhdGVnb3LDrWEgZGUgcmVmZXJlbmNpYSIsCiAgICAiJFxcbG9nXFxsZWZ0KFxcZnJhY3tQKFkgXFxsZXEgail9e1AoWSA+IGopfVxccmlnaHQpID0gXFxhbHBoYV9qICsgXFxiZXRhXzEgWF8xICsgXFxkb3RzICsgXFxiZXRhX3AgWF9wJCIsCiAgICAiJFxcbG9nKFxcbXUpID0gXFxiZXRhXzAgKyBcXGJldGFfMSBYXzEgKyBcXGRvdHMgKyBcXGJldGFfcCBYX3AkIChkaXN0cmlidWNpw7NuIGJpbm9taWFsIG5lZ2F0aXZhKSIKICApLAogICJGdW5jacOzbiBkZSBFbmxhY2UiID0gYygKICAgICJJZGVudGlkYWQiLAogICAgIklkZW50aWRhZCIsCiAgICAiTG9naXQiLAogICAgIkxvZyIsCiAgICAiTG9naXQgKG11bHRpbm9taWFsKSIsCiAgICAiTG9naXQgKHByb3BvcmNpb25hbCBvZGRzKSIsCiAgICAiTG9nIgogICksCiAgIkFwbGljYWNpw7NuIGVuIFNhbHVkIiA9IGMoCiAgICAiUmVsYWNpw7NuIGVudHJlIElNQyB5IGdsdWNvc2EgZW4gc2FuZ3JlIiwKICAgICJQcmVkaWNjacOzbiBkZWwgcmllc2dvIGNhcmRpb3Zhc2N1bGFyIGNvbiBtw7psdGlwbGVzIGZhY3RvcmVzIiwKICAgICJQcmVkaWNjacOzbiBkZSBlbmZlcm1lZGFkIChzw60vbm8pLCBlLmcuLCBkaWFiZXRlcywgaW5mYXJ0byIsCiAgICAiTW9kZWxhciBuw7ptZXJvIGRlIGhvc3BpdGFsaXphY2lvbmVzIG8gY2Fzb3MgZGUgZW5mZXJtZWRhZCIsCiAgICAiUHJlZGVjaXIgZXN0YWRpbyBkZSBjw6FuY2VyIChJLCBJSSwgSUlJLCBJVikiLAogICAgIkV2YWx1YXIgZ3JhdmVkYWQgZGUgc8OtbnRvbWFzIChsZXZlLCBtb2RlcmFkYSwgc2V2ZXJhKSIsCiAgICAiTW9kZWxhciBjb250ZW9zIGNvbiBhbHRhIHZhcmlhYmlsaWRhZCAoZS5nLiwgaW5mZWNjaW9uZXMgcmVzcGlyYXRvcmlhcykiCiAgKSwKICAiRWplbXBsbyBQcsOhY3RpY28iID0gYygKICAgICJDYWRhIGhvcmEgYWRpY2lvbmFsIGRlIGVqZXJjaWNpbyByZWR1Y2UgZWwgY29sZXN0ZXJvbCBlbiAyLjUgbWcvZEwiLAogICAgIk1vZGVsbyBjb24gSU1DLCBlZGFkIHkgdGFiYXF1aXNtbyBwcmVkaWNlIHJpZXNnbyBkZSBpbmZhcnRvIiwKICAgICJDYWRhIGHDsW8gZGUgZWRhZCBhdW1lbnRhIGxvcyBvZGRzIGRlIGhpcGVydGVuc2nDs24gZW4gNSUgKE9SID0gMS4wNSkiLAogICAgIk1heW9yIGV4cG9zaWNpw7NuIGEgY29udGFtaW5hY2nDs24gaW5jcmVtZW50YSB2aXNpdGFzIGEgdXJnZW5jaWFzIGVuIDM1JSIsCiAgICAiVGFtYcOxbyBkZWwgdHVtb3IgeSBlZGFkIHByZWRpY2VuIGVzdGFkaW8gZGVsIGPDoW5jZXIgZGUgbWFtYSIsCiAgICAiTml2ZWwgZGUgaW5mbGFtYWNpw7NuIHkgZWRhZCBwcmVkaWNlbiBzZXZlcmlkYWQgZGUgYXJ0cml0aXMiLAogICAgIk7Dum1lcm8gZGUgaG9zcGl0YWxpemFjaW9uZXMgcG9yIGluZmVjY2lvbmVzIGFqdXN0YWRvIHBvciBlZGFkIHkgZXhwb3NpY2nDs24iCiAgKSwKICBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UKKQoKIyBNb3N0cmFyIHRhYmxhCmthYmxlKHRhYmxhX3JlZ3Jlc2lvbiwgImh0bWwiLCAKICAgICAgY2FwdGlvbiA9ICJUYWJsYSA1OiBSZXN1bWVuIGRlIG1vZGVsb3MgZGUgcmVncmVzacOzbiBhcGxpY2Fkb3MgYWwgc2VjdG9yIHNhbHVkIikgJT4lCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiLCAicmVzcG9uc2l2ZSIpLCBmdWxsX3dpZHRoID0gRkFMU0UpICU+JQogIHNjcm9sbF9ib3god2lkdGggPSAiMTAwJSIsIGhlaWdodCA9ICI1MDBweCIpCgpgYGAKCiMgNi4gTcOpdG9kb3MgTXVsdGl2YXJpYWRvcyBwYXJhIGVsIFNlY3RvciBTYWx1ZAoKRXN0ZSB0ZW1hcmlvIGRlc2Fycm9sbGEgbG9zIG3DqXRvZG9zIG11bHRpdmFyaWFkb3MgY29uIHVuIGVuZm9xdWUgZW4KYXBsaWNhY2lvbmVzIGVuIGVsIHNlY3RvciBzYWx1ZCwgcHJvcG9yY2lvbmFuZG8gZXhwbGljYWNpb25lcwpkZXRhbGxhZGFzLCBlamVtcGxvcyBwcsOhY3RpY29zIHkgYXBsaWNhY2lvbmVzIHJlbGV2YW50ZXMgcGFyYQpwcm9mZXNpb25hbGVzIG3DqWRpY29zLCBpbnZlc3RpZ2Fkb3JlcyBjbMOtbmljb3MgeSBlcGlkZW1pw7Nsb2dvcy4gTG9zCm3DqXRvZG9zIG11bHRpdmFyaWFkb3MgYW5hbGl6YW4gbcO6bHRpcGxlcyB2YXJpYWJsZXMgc2ltdWx0w6FuZWFtZW50ZSBwYXJhCmRlc2N1YnJpciBwYXRyb25lcywgcmVkdWNpciBkaW1lbnNpb25hbGlkYWQgbyBjbGFzaWZpY2FyIG9ic2VydmFjaW9uZXMsCnNpZW5kbyBlc2VuY2lhbGVzIGVuIGVzdHVkaW9zIGNvbXBsZWpvcyBjb21vIGxhIGlkZW50aWZpY2FjacOzbiBkZQpmYWN0b3JlcyBkZSByaWVzZ28sIGFuw6FsaXNpcyBkZSBiaW9tYXJjYWRvcmVzIG8gc2VnbWVudGFjacOzbiBkZQpwYWNpZW50ZXMuIFNlIGluY2x1eWUgZWwgYW7DoWxpc2lzIGRlIGNvcnJlc3BvbmRlbmNpYXMgbcO6bHRpcGxlcyAoQUNNKQpwYXJhIGNvbXBsZW1lbnRhciBlbCBhbsOhbGlzaXMgbXVsdGl2YXJpYWRvIGVuIGRhdG9zIGNhdGVnw7NyaWNvcy4KCiMjIDYuMSBBbsOhbGlzaXMgZGUgQ29tcG9uZW50ZXMgUHJpbmNpcGFsZXMgKFBDQSkKCiMjIyBSZWR1Y2Npw7NuIGRlIERpbWVuc2lvbmFsaWRhZAoKRWwgYW7DoWxpc2lzIGRlIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzIChQQ0EpIGVzIHVuYSB0w6ljbmljYSBkZSByZWR1Y2Npw7NuCmRlIGRpbWVuc2lvbmFsaWRhZCBxdWUgdHJhbnNmb3JtYSB1biBjb25qdW50byBkZSB2YXJpYWJsZXMKY29ycmVsYWNpb25hZGFzIGVuIHVuIGNvbmp1bnRvIG3DoXMgcGVxdWXDsW8gZGUgdmFyaWFibGVzIG5vCmNvcnJlbGFjaW9uYWRhcyBsbGFtYWRhcyBjb21wb25lbnRlcyBwcmluY2lwYWxlcywgcHJlc2VydmFuZG8gbGEgbWF5b3IKY2FudGlkYWQgcG9zaWJsZSBkZSBsYSB2YXJpYWJpbGlkYWQgZGUgbG9zIGRhdG9zLgoKLSAgICoqT2JqZXRpdm86KiogUmVkdWNpciBlbCBuw7ptZXJvIGRlIHZhcmlhYmxlcyBtYW50ZW5pZW5kbyBsYSBtYXlvcgogICAgcGFydGUgZGUgbGEgaW5mb3JtYWNpw7NuICh2YXJpYW56YSkuIEVuIHNhbHVkLCBlc3RvIGVzIMO6dGlsIHBhcmEKICAgIGFuYWxpemFyIG3Dumx0aXBsZXMgYmlvbWFyY2Fkb3JlcyAoZS5nLiwgZ2x1Y29zYSwgY29sZXN0ZXJvbCwgcHJlc2nDs24KICAgIGFydGVyaWFsKSBlbiB1biBlc3BhY2lvIGRlIG1lbm9yIGRpbWVuc2nDs24uCi0gICAqKk3DqXRvZG86KioKICAgIC0gICAqKkVzdGFuZGFyaXphY2nDs246KiogRXNjYWxhciBsYXMgdmFyaWFibGVzIGEgbWVkaWEgMCB5IHZhcmlhbnphCiAgICAgICAgMSwgZXNwZWNpYWxtZW50ZSBzaSB0aWVuZW4gZGlmZXJlbnRlcyB1bmlkYWRlcyAoZS5nLiwgbWcvZEwgcGFyYQogICAgICAgIGdsdWNvc2EsIG1tSGcgcGFyYSBwcmVzacOzbiBhcnRlcmlhbCkuCiAgICAtICAgKipNYXRyaXogZGUgY292YXJpYW56YSBvIGNvcnJlbGFjacOzbjoqKiBDYWxjdWxhciBsYSBtYXRyaXogcGFyYQogICAgICAgIGNhcHR1cmFyIGxhcyByZWxhY2lvbmVzIGVudHJlIHZhcmlhYmxlcy4KICAgIC0gICAqKkF1dG92YWxvcmVzIHkgYXV0b3ZlY3RvcmVzOioqIExvcyBhdXRvdmVjdG9yZXMgZGVmaW5lbiBsYXMKICAgICAgICBkaXJlY2Npb25lcyBkZSBsb3MgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMsIHkgbG9zIGF1dG92YWxvcmVzCiAgICAgICAgaW5kaWNhbiBsYSB2YXJpYW56YSBleHBsaWNhZGEgcG9yIGNhZGEgY29tcG9uZW50ZS4KICAgIC0gICAqKlNlbGVjY2nDs24gZGUgY29tcG9uZW50ZXM6KiogRWxlZ2lyIGxvcyBjb21wb25lbnRlcyBjb24KICAgICAgICBhdXRvdmFsb3JlcyBhbHRvcyAoZS5nLiwgXD4gMSkgbyBxdWUgZXhwbGlxdWVuIHVuIHBvcmNlbnRhamUKICAgICAgICBzaWduaWZpY2F0aXZvIGRlIGxhIHZhcmlhbnphIChlLmcuLCA3MC05MCUpLgotICAgKipBbGdvcml0bW86KioKICAgIDEuICBFc3RhbmRhcml6YXIgbGFzIHZhcmlhYmxlczogJFogPSBcZnJhY3tYIC0gXG11fXtcc2lnbWF9JC4KICAgIDIuICBDYWxjdWxhciBsYSBtYXRyaXogZGUgY29ycmVsYWNpw7NuICRSJC4KICAgIDMuICBPYnRlbmVyIGF1dG92YWxvcmVzICgkXGxhbWJkYV9pJCkgeSBhdXRvdmVjdG9yZXMgKCR2X2kkKS4KICAgIDQuICBQcm95ZWN0YXIgbG9zIGRhdG9zIGVuIGxvcyBjb21wb25lbnRlcyBwcmluY2lwYWxlczoKICAgICAgICAkWSA9IFogXGNkb3QgViQsIGRvbmRlICRWJCBlcyBsYSBtYXRyaXogZGUgYXV0b3ZlY3RvcmVzLgotICAgKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBSZWR1Y2lyIHVuIGNvbmp1bnRvIGRlIGJpb21hcmNhZG9yZXMgKGUuZy4sCiAgICBsw61waWRvcywgZ2x1Y29zYSwgaW5mbGFtYWNpw7NuKSBhIHVub3MgcG9jb3MgY29tcG9uZW50ZXMgcGFyYQogICAgaWRlbnRpZmljYXIgcGF0cm9uZXMgZGUgcmllc2dvIGNhcmRpb3Zhc2N1bGFyLgotICAgKipFamVtcGxvIHByw6FjdGljbzoqKiBFbiB1biBlc3R1ZGlvIGNvbiAyMDAgcGFjaWVudGVzLCBzZSBhbmFsaXphbgogICAgMTAgYmlvbWFyY2Fkb3JlcyAoY29sZXN0ZXJvbCB0b3RhbCwgTERMLCBIREwsIHRyaWdsaWPDqXJpZG9zLAogICAgZ2x1Y29zYSwgZXRjLikuIFBDQSBpZGVudGlmaWNhIGRvcyBjb21wb25lbnRlcyBwcmluY2lwYWxlcyBxdWUKICAgIGV4cGxpY2FuIGVsIDgwJSBkZSBsYSB2YXJpYW56YSwgcmVwcmVzZW50YW5kbyBwZXJmaWxlcyBkZSByaWVzZ28KICAgIG1ldGFiw7NsaWNvIHkgbGlww61kaWNvLgoKIyMjIEludGVycHJldGFjacOzbiBkZSBDb21wb25lbnRlcwoKLSAgICoqQ29tcG9uZW50ZXMgcHJpbmNpcGFsZXM6KiogQ2FkYSBjb21wb25lbnRlIGVzIHVuYSBjb21iaW5hY2nDs24KICAgIGxpbmVhbCBkZSBsYXMgdmFyaWFibGVzIG9yaWdpbmFsZXM6ICQkCiAgICBQQ18xID0gYV97MTF9WF8xICsgYV97MTJ9WF8yICsgXGRvdHMgKyBhX3sxcH1YX3AKICAgICQkIERvbmRlICRhX3sxan0kIHNvbiBsYXMgY2FyZ2FzICgqbG9hZGluZ3MqKSBxdWUgaW5kaWNhbiBsYQogICAgY29udHJpYnVjacOzbiBkZSBjYWRhIHZhcmlhYmxlICRYX2okLgoKLSAgICoqQ2FyZ2FzOioqIFZhbG9yZXMgY2VyY2Fub3MgYSAxIG8gLTEgaW5kaWNhbiB1bmEgZnVlcnRlCiAgICBjb250cmlidWNpw7NuOyB2YWxvcmVzIGNlcmNhIGRlIDAgaW5kaWNhbiBwb2NhIGluZmx1ZW5jaWEuCgotICAgKipWYXJpYW56YSBleHBsaWNhZGE6KiogTGEgcHJvcG9yY2nDs24gZGUgdmFyaWFuemEgdG90YWwgZXhwbGljYWRhCiAgICBwb3IgY2FkYSBjb21wb25lbnRlIGVzICRcZnJhY3tcbGFtYmRhX2l9e1xzdW0gXGxhbWJkYV9pfSQuCgotICAgKipHcsOhZmljb3M6KioKCiAgICAtICAgKipTY3JlZSBwbG90OioqIE11ZXN0cmEgbG9zIGF1dG92YWxvcmVzIHBhcmEgZGVjaWRpciBjdcOhbnRvcwogICAgICAgIGNvbXBvbmVudGVzIHJldGVuZXIuCiAgICAtICAgKipCaXBsb3Q6KiogVmlzdWFsaXphIGxhcyBvYnNlcnZhY2lvbmVzIHkgbGFzIHZhcmlhYmxlcyBlbiBlbAogICAgICAgIGVzcGFjaW8gZGUgbG9zIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzLgoKLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogSW50ZXJwcmV0YXIgY29tcG9uZW50ZXMgY29tbyBjb21iaW5hY2lvbmVzCiAgICBkZSBmYWN0b3JlcyBkZSByaWVzZ28uIFBvciBlamVtcGxvLCBQQzEgcHVlZGUgcmVwcmVzZW50YXIgdW4gInBlcmZpbAogICAgbWV0YWLDs2xpY28iIChhbHRhIGNhcmdhIGVuIGdsdWNvc2EgeSBIYkExYyksIHkgUEMyIHVuICJwZXJmaWwKICAgIGxpcMOtZGljbyIgKGFsdGEgY2FyZ2EgZW4gY29sZXN0ZXJvbCB5IHRyaWdsaWPDqXJpZG9zKS4KCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIGVsIGVzdHVkaW8gYW50ZXJpb3IsIFBDMSB0aWVuZSBjYXJnYXMgYWx0YXMKICAgIHBhcmEgZ2x1Y29zYSAoMC42KSB5IEhiQTFjICgwLjUpLCBzdWdpcmllbmRvIHVuIGNvbXBvbmVudGUKICAgIHJlbGFjaW9uYWRvIGNvbiBlbCBjb250cm9sIGdsdWPDqW1pY28uIFBDMiB0aWVuZSBjYXJnYXMgYWx0YXMgcGFyYQogICAgY29sZXN0ZXJvbCBMREwgKDAuNykgeSB0cmlnbGljw6lyaWRvcyAoMC42KSwgcmVsYWNpb25hZG8gY29uIGzDrXBpZG9zLgogICAgTG9zIHBhY2llbnRlcyBjb24gcHVudHVhY2lvbmVzIGFsdGFzIGVuIFBDMSB0aWVuZW4gbWF5b3Igcmllc2dvIGRlCiAgICBkaWFiZXRlcy4KCiMjIDYuMiBBbsOhbGlzaXMgRmFjdG9yaWFsCgpFbCBhbsOhbGlzaXMgZmFjdG9yaWFsIGlkZW50aWZpY2EgZmFjdG9yZXMgbGF0ZW50ZXMgKG5vIG9ic2VydmFkb3MpIHF1ZQpleHBsaWNhbiBsYXMgY29ycmVsYWNpb25lcyBlbnRyZSB2YXJpYWJsZXMgb2JzZXJ2YWRhcywgw7p0aWwgcGFyYQpleHBsb3JhciBlc3RydWN0dXJhcyBzdWJ5YWNlbnRlcyBlbiBkYXRvcyBkZSBzYWx1ZC4KCiMjIyBNb2RlbG9zIEV4cGxvcmF0b3Jpb3MgeSBDb25maXJtYXRvcmlvcwoKKipBbsOhbGlzaXMgZmFjdG9yaWFsIGV4cGxvcmF0b3JpbyAoRUZBKToqKgoKLSAgICoqT2JqZXRpdm86KiogSWRlbnRpZmljYXIgZmFjdG9yZXMgbGF0ZW50ZXMgc2luIGhpcMOzdGVzaXMgcHJldmlhcy4KLSAgICoqTW9kZWxvOioqICQkCiAgICBYX2ogPSBcbXVfaiArIFxzdW1fe209MX1eayBcbGFtYmRhX3tqbX0gRl9tICsgXGVwc2lsb25fagogICAgJCQgRG9uZGUgJFhfaiQgZXMgbGEgdmFyaWFibGUgb2JzZXJ2YWRhLCAkXGxhbWJkYV97am19JCBzb24gbGFzCiAgICBjYXJnYXMgZmFjdG9yaWFsZXMsICRGX20kIHNvbiBsb3MgZmFjdG9yZXMsIHkgJFxlcHNpbG9uX2okIGVzIGVsCiAgICBlcnJvciBlc3BlY8OtZmljby4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogSWRlbnRpZmljYXIgZmFjdG9yZXMgc3VieWFjZW50ZXMgZW4KICAgIHPDrW50b21hcyBwc2ljb2zDs2dpY29zIChlLmcuLCBhbnNpZWRhZCwgZGVwcmVzacOzbikgYSBwYXJ0aXIgZGUKICAgIHJlc3B1ZXN0YXMgYSBjdWVzdGlvbmFyaW9zLgotICAgKipFamVtcGxvIHByw6FjdGljbzoqKiBFbiB1biBlc3R1ZGlvIGRlIHNhbHVkIG1lbnRhbCwgRUZBIGFncnVwYQogICAgw610ZW1zIGRlIHVuIGN1ZXN0aW9uYXJpbyAoZmF0aWdhLCB0cmlzdGV6YSwgaW5zb21uaW8pIGVuIGZhY3RvcmVzCiAgICBjb21vICJkZXByZXNpw7NuIiB5ICJhbnNpZWRhZCIuCgoqKkFuw6FsaXNpcyBmYWN0b3JpYWwgY29uZmlybWF0b3JpbyAoQ0ZBKToqKgoKLSAgICoqT2JqZXRpdm86KiogVmFsaWRhciB1bmEgZXN0cnVjdHVyYSBmYWN0b3JpYWwgcHJlZGVmaW5pZGEuCi0gICAqKk3DqXRvZG86KiogRXNwZWNpZmljYXIgdW4gbW9kZWxvIGRvbmRlIGNhZGEgdmFyaWFibGUgY2FyZ2EgZW4KICAgIGZhY3RvcmVzIGVzcGVjw61maWNvcywgZXN0aW1hbmRvIHBhcsOhbWV0cm9zIGNvbiBtw6F4aW1hIHZlcm9zaW1pbGl0dWQuCi0gICAqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIENvbmZpcm1hciBxdWUgdW4gY3Vlc3Rpb25hcmlvIGRlIGNhbGlkYWQgZGUKICAgIHZpZGEgbWlkZSBkaW1lbnNpb25lcyBlc3BlY8OtZmljYXMgKGUuZy4sIGbDrXNpY2EsIGVtb2Npb25hbCkuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIFVuIENGQSB2YWxpZGEgcXVlIHVuIGN1ZXN0aW9uYXJpbyBkZSBjYWxpZGFkCiAgICBkZSB2aWRhIGVuIHBhY2llbnRlcyBjb24gY8OhbmNlciBtaWRlIHRyZXMgZmFjdG9yZXMgKGbDrXNpY28sCiAgICBlbW9jaW9uYWwsIHNvY2lhbCksIGNvbiBjYXJnYXMgc2lnbmlmaWNhdGl2YXMgKCRwIDwgMC4wNSQpLgoKKipEaWZlcmVuY2lhczoqKgoKLSAgIEVGQSBlcyBleHBsb3JhdG9yaW8sIHNpbiBoaXDDs3Rlc2lzIHByZXZpYXM7IENGQSBwcnVlYmEgdW4gbW9kZWxvCiAgICB0ZcOzcmljby4KLSAgIEVuIHNhbHVkLCBFRkEgc2UgdXNhIGVuIGZhc2VzIGluaWNpYWxlcyAoZS5nLiwgZGVzYXJyb2xsbyBkZQogICAgZXNjYWxhcyk7IENGQSBlbiB2YWxpZGFjacOzbiAoZS5nLiwgZW5zYXlvcyBjbMOtbmljb3MpLgoKIyMjIFJvdGFjacOzbiBkZSBGYWN0b3JlcwoKLSAgICoqUHJvcMOzc2l0bzoqKiBTaW1wbGlmaWNhciBsYSBpbnRlcnByZXRhY2nDs24gZGUgbG9zIGZhY3RvcmVzCiAgICBoYWNpZW5kbyBxdWUgbGFzIGNhcmdhcyBzZWFuIG3DoXMgZXh0cmVtYXMgKGNlcmNhbmFzIGEgMCBvIDEpLgotICAgKipUaXBvczoqKgogICAgLSAgICoqT3J0b2dvbmFsIChlLmcuLCBWYXJpbWF4KToqKiBBc3VtZSBmYWN0b3JlcyBubwogICAgICAgIGNvcnJlbGFjaW9uYWRvcywgw7p0aWwgcGFyYSBlc3RydWN0dXJhcyBjbGFyYXMuCiAgICAtICAgKipPYmxpY3VhIChlLmcuLCBQcm9tYXgpOioqIFBlcm1pdGUgY29ycmVsYWNpw7NuIGVudHJlIGZhY3RvcmVzLAogICAgICAgIGNvbcO6biBlbiBzYWx1ZCBkb25kZSBmYWN0b3JlcyBjb21vIHPDrW50b21hcyBmw61zaWNvcyB5CiAgICAgICAgcHNpY29sw7NnaWNvcyBwdWVkZW4gZXN0YXIgcmVsYWNpb25hZG9zLgotICAgKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBFbiB1biBFRkEgZGUgc8OtbnRvbWFzIGRlIGRpYWJldGVzLCBsYQogICAgcm90YWNpw7NuIFZhcmltYXggYWdydXBhIHZhcmlhYmxlcyBlbiBmYWN0b3JlcyBjb21vICJzw61udG9tYXMKICAgIG1ldGFiw7NsaWNvcyIgKGdsdWNvc2EgYWx0YSwgc2VkKSB5ICJzw61udG9tYXMgbmV1cm9sw7NnaWNvcyIKICAgIChuZXVyb3BhdMOtYSwgaG9ybWlndWVvKS4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogRW4gdW4gZXN0dWRpbyBjb24gMzAwIHBhY2llbnRlcywgdW4gRUZBIGNvbgogICAgcm90YWNpw7NuIFZhcmltYXggaWRlbnRpZmljYSBkb3MgZmFjdG9yZXM6IHVubyBjb24gYWx0YXMgY2FyZ2FzIGVuCiAgICBnbHVjb3NhIHkgSGJBMWMsIG90cm8gZW4gbmV1cm9wYXTDrWEgeSBmYXRpZ2EuIExhIHJvdGFjacOzbiBmYWNpbGl0YQogICAgaW50ZXJwcmV0YXIgZWwgcHJpbWVyIGZhY3RvciBjb21vIGNvbnRyb2wgZ2x1Y8OpbWljbyB5IGVsIHNlZ3VuZG8KICAgIGNvbW8gY29tcGxpY2FjaW9uZXMuCgojIyA2LjMgQW7DoWxpc2lzIERpc2NyaW1pbmFudGUgeSBDbMO6c3RlcgoKIyMjIENsYXNpZmljYWNpw7NuIFN1cGVydmlzYWRhIHkgTm8gU3VwZXJ2aXNhZGEKCioqQW7DoWxpc2lzIGRpc2NyaW1pbmFudGUgKHN1cGVydmlzYWRvKToqKgoKLSAgICoqT2JqZXRpdm86KiogQ2xhc2lmaWNhciBvYnNlcnZhY2lvbmVzIGVuIGdydXBvcyBwcmVkZWZpbmlkb3MgKGUuZy4sCiAgICBlbmZlcm1vIHZzLiBzYW5vKSBiYXPDoW5kb3NlIGVuIHZhcmlhYmxlcyBwcmVkaWN0b3Jhcy4KLSAgICoqVGlwb3M6KioKICAgIC0gICAqKkxpbmVhbCAoTERBKToqKiBBc3VtZSBub3JtYWxpZGFkIHkgdmFyaWFuemFzIGlndWFsZXMgZW50cmUKICAgICAgICBncnVwb3MuCiAgICAtICAgKipDdWFkcsOhdGljbyAoUURBKToqKiBQZXJtaXRlIHZhcmlhbnphcyBkaWZlcmVudGVzLgotICAgKipNb2RlbG86KioKICAgIC0gICBFbiBMREEsIHNlIG1heGltaXphIGxhIHNlcGFyYWNpw7NuIGVudHJlIGdydXBvcyBwcm95ZWN0YW5kbyBsb3MKICAgICAgICBkYXRvcyBlbiBmdW5jaW9uZXMgZGlzY3JpbWluYW50ZXM6ICQkCiAgICAgICAgRF9rKFgpID0gXGJldGFfMCArIFxiZXRhXzEgWF8xICsgXGRvdHMgKyBcYmV0YV9wIFhfcAogICAgICAgICQkCiAgICAtICAgQ2xhc2lmaWNhIHVuYSBvYnNlcnZhY2nDs24gZW4gZWwgZ3J1cG8gY29uIG1heW9yICREX2skLgotICAgKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBDbGFzaWZpY2FyIHBhY2llbnRlcyBjb21vIGRpYWLDqXRpY29zIG8gbm8KICAgIGRpYWLDqXRpY29zIGJhc8OhbmRvc2UgZW4gZ2x1Y29zYSwgSU1DIHkgZWRhZC4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogRW4gdW4gZXN0dWRpbyBjb24gNTAwIHBhY2llbnRlcywgTERBIHVzYQogICAgZ2x1Y29zYSwgSGJBMWMgZSBJTUMgcGFyYSBjbGFzaWZpY2FyIGRpYWJldGVzIHRpcG8gMiB2cy4gbm8KICAgIGRpYWJldGVzLCBsb2dyYW5kbyB1biA4NSUgZGUgcHJlY2lzacOzbi4KCioqQW7DoWxpc2lzIGRlIGNsw7pzdGVyIChubyBzdXBlcnZpc2Fkbyk6KioKCi0gICAqKk9iamV0aXZvOioqIEFncnVwYXIgb2JzZXJ2YWNpb25lcyBlbiBjbMO6c3RlcmVzIGJhc8OhbmRvc2UgZW4KICAgIHNpbWlsaXR1ZGVzLCBzaW4gZXRpcXVldGFzIHByZXZpYXMuCi0gICAqKk3DqXRvZG9zOioqCiAgICAtICAgKipLLW1lYW5zOioqIE1pbmltaXphIGxhIHZhcmlhbnphIGRlbnRybyBkZSBsb3MgY2zDunN0ZXJlcywKICAgICAgICBhc2lnbmFuZG8gb2JzZXJ2YWNpb25lcyBhbCBjZW50cm9pZGUgbcOhcyBjZXJjYW5vLgogICAgLSAgICoqSmVyw6FycXVpY286KiogQ29uc3RydXllIHVuIGRlbmRyb2dyYW1hIGZ1c2lvbmFuZG8gbyBkaXZpZGllbmRvCiAgICAgICAgY2zDunN0ZXJlcy4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogSWRlbnRpZmljYXIgc3ViZ3J1cG9zIGRlIHBhY2llbnRlcyBjb24KICAgIHBlcmZpbGVzIGRlIHJpZXNnbyBzaW1pbGFyZXMgKGUuZy4sIHBhY2llbnRlcyBjb24gZW5mZXJtZWRhZGVzCiAgICBjYXJkaW92YXNjdWxhcmVzKS4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogSy1tZWFucyBhZ3J1cGEgMTAwMCBwYWNpZW50ZXMgZW4gdHJlcwogICAgY2zDunN0ZXJlcyBzZWfDum4gYmlvbWFyY2Fkb3JlcyAoY29sZXN0ZXJvbCwgcHJlc2nDs24gYXJ0ZXJpYWwpOiBhbHRvCiAgICByaWVzZ28sIHJpZXNnbyBtb2RlcmFkbyB5IGJham8gcmllc2dvLgoKIyMjIEV2YWx1YWNpw7NuIGRlIFJlc3VsdGFkb3MKCioqQW7DoWxpc2lzIGRpc2NyaW1pbmFudGU6KioKCi0gICAqKk3DqXRyaWNhczoqKiBUYXNhIGRlIGNsYXNpZmljYWNpw7NuIGNvcnJlY3RhLCBzZW5zaWJpbGlkYWQsCiAgICBlc3BlY2lmaWNpZGFkLCBtYXRyaXogZGUgY29uZnVzacOzbi4KLSAgICoqVmFsaWRhY2nDs246KiogVmFsaWRhY2nDs24gY3J1emFkYSAoZS5nLiwgay1mb2xkKSBwYXJhIGV2YWx1YXIgbGEKICAgIGdlbmVyYWxpemFjacOzbi4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogRW4gZWwgZXN0dWRpbyBkZSBkaWFiZXRlcywgTERBIGxvZ3JhIDkwJSBkZQogICAgc2Vuc2liaWxpZGFkIChkZXRlY3RhIGRpYWLDqXRpY29zIGNvcnJlY3RhbWVudGUpIHkgODAlIGRlCiAgICBlc3BlY2lmaWNpZGFkIChpZGVudGlmaWNhIG5vIGRpYWLDqXRpY29zKS4KCioqQW7DoWxpc2lzIGRlIGNsw7pzdGVyOioqCgotICAgKipNw6l0cmljYXM6KioKICAgIC0gICAqKsONbmRpY2UgZGUgc2lsdWV0YToqKiBNaWRlIGxhIGNvaGVzacOzbiBkZW50cm8gZGUgY2zDunN0ZXJlcyB5CiAgICAgICAgc2VwYXJhY2nDs24gZW50cmUgY2zDunN0ZXJlcyAodmFsb3JlcyBjZXJjYW5vcyBhIDEgaW5kaWNhbiBidWVuYQogICAgICAgIGNhbGlkYWQpLgogICAgLSAgICoqU3VtYSBkZSBjdWFkcmFkb3MgZGVudHJvIGRlIGNsw7pzdGVyZXMgKFdDU1MpKiogcGFyYSBLLW1lYW5zLgotICAgKipWYWxpZGFjacOzbjoqKiBDb21wYXJhciBjbMO6c3RlcmVzIGNvbiB2YXJpYWJsZXMgY2zDrW5pY2FzIGV4dGVybmFzCiAgICAoZS5nLiwgdGFzYXMgZGUgaG9zcGl0YWxpemFjacOzbikuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIGVsIGVzdHVkaW8gZGUgSy1tZWFucywgdW4gw61uZGljZSBkZSBzaWx1ZXRhCiAgICBkZSAwLjc1IHN1Z2llcmUgY2zDunN0ZXJlcyBiaWVuIGRlZmluaWRvcy4gTG9zIGNsw7pzdGVyZXMgc2UgdmFsaWRhbgogICAgY29tcGFyYW5kbyB0YXNhcyBkZSBldmVudG9zIGNhcmRpb3Zhc2N1bGFyZXMuCgojIyA2LjQgQW7DoWxpc2lzIGRlIENvcnJlc3BvbmRlbmNpYXMgTcO6bHRpcGxlcyAoQUNNKQoKRWwgYW7DoWxpc2lzIGRlIGNvcnJlc3BvbmRlbmNpYXMgbcO6bHRpcGxlcyAoQUNNKSBlcyB1bmEgdMOpY25pY2EKbXVsdGl2YXJpYWRhIHBhcmEgYW5hbGl6YXIgcmVsYWNpb25lcyBlbnRyZSBtw7psdGlwbGVzIHZhcmlhYmxlcwpjYXRlZ8OzcmljYXMsIGV4dGVuZGllbmRvIGVsIGFuw6FsaXNpcyBkZSBjb3JyZXNwb25kZW5jaWFzIHNpbXBsZSAoQ0EpIGEKbcOhcyBkZSBkb3MgdmFyaWFibGVzLgoKIyMjIEZ1bmRhbWVudG9zIHkgTW9kZWxvCgotICAgKipPYmpldGl2bzoqKiBFeHBsb3JhciB5IHZpc3VhbGl6YXIgYXNvY2lhY2lvbmVzIGVudHJlIGNhdGVnb3LDrWFzIGRlCiAgICB2YXJpYWJsZXMgY3VhbGl0YXRpdmFzLCByZWR1Y2llbmRvIGxhIGRpbWVuc2lvbmFsaWRhZCBkZSBsb3MgZGF0b3MKICAgIGNhdGVnw7NyaWNvcy4KLSAgICoqTW9kZWxvOioqCiAgICAtICAgTG9zIGRhdG9zIHNlIG9yZ2FuaXphbiBlbiB1bmEgbWF0cml6IGRlIGluZGljYWRvcmVzICgwLzEgcGFyYQogICAgICAgIGNhZGEgY2F0ZWdvcsOtYSkgbyB1bmEgdGFibGEgZGUgQnVydCAobWF0cml6IGRlIGNvbnRpbmdlbmNpYQogICAgICAgIGNydXphZGEgZGUgdG9kYXMgbGFzIHZhcmlhYmxlcykuCiAgICAtICAgQUNNIGRlc2NvbXBvbmUgZXN0YSBtYXRyaXogdXNhbmRvIGRlc2NvbXBvc2ljacOzbiBlbiB2YWxvcmVzCiAgICAgICAgc2luZ3VsYXJlcyAoU1ZEKSwgcHJveWVjdGFuZG8gY2F0ZWdvcsOtYXMgeSBvYnNlcnZhY2lvbmVzIGVuIHVuCiAgICAgICAgZXNwYWNpbyBkZSBiYWphIGRpbWVuc2nDs24uCiAgICAtICAgTG9zIGVqZXMgcHJpbmNpcGFsZXMgKGRpbWVuc2lvbmVzKSBleHBsaWNhbiBsYSBpbmVyY2lhIChhbsOhbG9nbwogICAgICAgIGEgbGEgdmFyaWFuemEgZW4gUENBKS4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogQW5hbGl6YXIgcmVsYWNpb25lcyBlbnRyZSB2YXJpYWJsZXMKICAgIGNhdGVnw7NyaWNhcyBjb21vIGRpYWduw7NzdGljbyAoZGlhYmV0ZXMsIGhpcGVydGVuc2nDs24sIG5pbmd1bmEpLAogICAgZXN0aWxvIGRlIHZpZGEgKGZ1bWFkb3IsIG5vIGZ1bWFkb3IpLCB5IGdydXBvIGRlIGVkYWQgKGpvdmVuLAogICAgYWR1bHRvLCBhbmNpYW5vKS4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogRW4gdW4gZXN0dWRpbyBkZSAxMDAwIHBhY2llbnRlcywgQUNNIGV4cGxvcmEKICAgIGFzb2NpYWNpb25lcyBlbnRyZSBkaWFnbsOzc3RpY28sIHRhYmFxdWlzbW8geSBuaXZlbCBlZHVjYXRpdm8uIExhcwogICAgY2F0ZWdvcsOtYXMgImRpYWJldGVzIiB5ICJmdW1hZG9yIiBhcGFyZWNlbiBjZXJjYW5hcyBlbiBlbCBtYXBhIGRlCiAgICBBQ00sIHN1Z2lyaWVuZG8gdW5hIGZ1ZXJ0ZSBhc29jaWFjacOzbi4KCiMjIyBJbnRlcnByZXRhY2nDs24geSBWaXN1YWxpemFjacOzbgoKLSAgICoqSW5lcmNpYToqKiBTaW1pbGFyIGEgbGEgdmFyaWFuemEgZW4gUENBLCBtaWRlIGxhIGRpc3BlcnNpw7NuIGRlIGxhcwogICAgY2F0ZWdvcsOtYXMuIExhIGluZXJjaWEgdG90YWwgc2UgZGVzY29tcG9uZSBlbiBjb250cmlidWNpb25lcyBwb3IKICAgIGVqZS4KLSAgICoqTWFwYXMgYmlkaW1lbnNpb25hbGVzOioqIExhcyBjYXRlZ29yw61hcyB5IG9ic2VydmFjaW9uZXMgc2UKICAgIHByb3llY3RhbiBlbiB1biBwbGFubyAoZWplcyBwcmluY2lwYWxlcyksIGRvbmRlIGxhIHByb3hpbWlkYWQgaW5kaWNhCiAgICBhc29jaWFjacOzbi4KICAgIC0gICAqKkludGVycHJldGFjacOzbjoqKiBDYXRlZ29yw61hcyBjZXJjYW5hcyBlc3TDoW4gbcOhcyBhc29jaWFkYXM7CiAgICAgICAgY2F0ZWdvcsOtYXMgb3B1ZXN0YXMgdGllbmVuIGFzb2NpYWNpb25lcyBpbnZlcnNhcy4KLSAgICoqQ29udHJpYnVjaW9uZXMgeSBjYWxpZGFkOioqCiAgICAtICAgKipDb250cmlidWNpw7NuOioqIFByb3BvcmNpw7NuIGRlIGxhIGluZXJjaWEgZXhwbGljYWRhIHBvciBjYWRhCiAgICAgICAgY2F0ZWdvcsOtYSBlbiB1biBlamUuCiAgICAtICAgKipDYWxpZGFkIGRlIHJlcHJlc2VudGFjacOzbjoqKiBJbmRpY2EgY8OzbW8gZGUgYmllbiB1bmEgY2F0ZWdvcsOtYQogICAgICAgIGVzIHJlcHJlc2VudGFkYSBlbiBlbCBwbGFubyAodmFsb3JlcyBjZXJjYW5vcyBhIDEgc29uIGlkZWFsZXMpLgotICAgKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBJZGVudGlmaWNhciBwYXRyb25lcyBlbiBkYXRvcyBjYXRlZ8Ozcmljb3MsCiAgICBjb21vIGxhIHJlbGFjacOzbiBlbnRyZSBjb21vcmJpbGlkYWRlcyB5IGZhY3RvcmVzIGRlIHJpZXNnby4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogRW4gZWwgZXN0dWRpbyBhbnRlcmlvciwgZWwgZWplIDEgKDQwJSBkZQogICAgaW5lcmNpYSkgc2VwYXJhIHBhY2llbnRlcyBjb24gZGlhYmV0ZXMgeSB0YWJhcXVpc21vIGRlIGFxdWVsbG9zIHNpbgogICAgY29tb3JiaWxpZGFkZXMuIEVsIGVqZSAyICgyNSUgZGUgaW5lcmNpYSkgZGlzdGluZ3VlIHBvciBuaXZlbAogICAgZWR1Y2F0aXZvLiBMYXMgY2F0ZWdvcsOtYXMgImRpYWJldGVzIiB5ICJiYWpvIG5pdmVsIGVkdWNhdGl2byIgZXN0w6FuCiAgICBjZXJjYW5hcywgc3VnaXJpZW5kbyB1bmEgYXNvY2lhY2nDs24uCgojIyMgVmVudGFqYXMgeSBMaW1pdGFjaW9uZXMKCi0gICAqKlZlbnRhamFzOioqCiAgICAtICAgSWRlYWwgcGFyYSBkYXRvcyBjYXRlZ8Ozcmljb3MsIGNvbXVuZXMgZW4gZW5jdWVzdGFzIGRlIHNhbHVkCiAgICAgICAgKGUuZy4sIGN1ZXN0aW9uYXJpb3MgZGUgY2FsaWRhZCBkZSB2aWRhKS4KICAgIC0gICBWaXN1YWxpemFjacOzbiBpbnR1aXRpdmEgZGUgYXNvY2lhY2lvbmVzIGNvbXBsZWphcy4KICAgIC0gICBObyByZXF1aWVyZSBzdXB1ZXN0b3MgZGUgbm9ybWFsaWRhZC4KLSAgICoqTGltaXRhY2lvbmVzOioqCiAgICAtICAgU2Vuc2libGUgYSBjYXRlZ29yw61hcyBjb24gZnJlY3VlbmNpYXMgYmFqYXMuCiAgICAtICAgSW50ZXJwcmV0YWNpw7NuIHN1YmpldGl2YSBkZSBsb3MgbWFwYXMuCiAgICAtICAgTm8gbW9kZWxhIHJlbGFjaW9uZXMgY2F1c2FsZXMuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuIGVzdHVkaW8gZGUgY2FsaWRhZCBkZSB2aWRhIGVuIHBhY2llbnRlcwogICAgb25jb2zDs2dpY29zLCBBQ00gcmV2ZWxhIHF1ZSBsb3MgcGFjaWVudGVzIGNvbiBjw6FuY2VyIGF2YW56YWRvIHkgYmFqYQogICAgY2FsaWRhZCBkZSB2aWRhIGVzdMOhbiBhc29jaWFkb3MgY29uIG1heW9yIGVkYWQgeSBtZW5vciBzb3BvcnRlCiAgICBzb2NpYWwuCgojIyBSZWN1cnNvcyBwYXJhIGVsIEF1dG9lc3R1ZGlvIGVuIFNhbHVkCgojIyMgTGVjdHVyYXM6CgotICAgIk11bHRpdmFyaWF0ZSBEYXRhIEFuYWx5c2lzIiBkZSBIYWlyIGV0IGFsLiAoQ2Fww610dWxvcyBzb2JyZSBQQ0EsCiAgICBmYWN0b3JpYWwsIGNsw7pzdGVyKS4KLSAgICJBbiBJbnRyb2R1Y3Rpb24gdG8gQ29ycmVzcG9uZGVuY2UgQW5hbHlzaXMiIGRlIEdyZWVuYWNyZSAocGFyYSBDQSB5CiAgICBBQ00pLgotICAgIkJpb3N0YXRpc3RpY3M6IEEgRm91bmRhdGlvbiBmb3IgQW5hbHlzaXMgaW4gdGhlIEhlYWx0aCBTY2llbmNlcyIgZGUKICAgIERhbmllbCAoQ2Fww610dWxvcyBzb2JyZSBtw6l0b2RvcyBtdWx0aXZhcmlhZG9zKS4KCiMjIyBFamVyY2ljaW9zIHByw6FjdGljb3M6CgotICAgUmVhbGl6YXIgUENBIGVuIGJpb21hcmNhZG9yZXMgKGUuZy4sIGdsdWNvc2EsIGNvbGVzdGVyb2wpIHBhcmEKICAgIGlkZW50aWZpY2FyIHBhdHJvbmVzIGRlIHJpZXNnby4KLSAgIEFwbGljYXIgRUZBIHkgQ0ZBIGEgY3Vlc3Rpb25hcmlvcyBkZSBzYWx1ZCBtZW50YWwsIHZlcmlmaWNhbmRvCiAgICBlc3RydWN0dXJhcyBmYWN0b3JpYWxlcy4KLSAgIFVzYXIgYW7DoWxpc2lzIGRpc2NyaW1pbmFudGUgcGFyYSBjbGFzaWZpY2FyIHBhY2llbnRlcyAoZS5nLiwKICAgIGRpYWLDqXRpY29zIHZzLiBubyBkaWFiw6l0aWNvcykgeSBjbMO6c3RlciBwYXJhIHNlZ21lbnRhciBwb2JsYWNpb25lcy4KLSAgIEltcGxlbWVudGFyIEFDTSBlbiBkYXRvcyBjYXRlZ8Ozcmljb3MgKGUuZy4sIGNvbW9yYmlsaWRhZGVzIHkKICAgIGZhY3RvcmVzIGRlIHJpZXNnbykuCgojIyMgSGVycmFtaWVudGFzIGNvbXB1dGFjaW9uYWxlczoKCi0gICAqKlI6KioKICAgIC0gICBQYXF1ZXRlcyBgRmFjdG9NaW5lUmAgKFBDQSwgQUNNKSwgYHBzeWNoYCAoRUZBLCBDRkEpLCBgTUFTU2AKICAgICAgICAoTERBKSwgYGNsdXN0ZXJgIChLLW1lYW5zLCBqZXLDoXJxdWljbykuCiAgICAtICAgRWplbXBsbzogYFBDQShkYXRvcywgc2NhbGU9VFJVRSlgIHBhcmEgUENBOyBgTUNBKGRhdG9zKWAgcGFyYQogICAgICAgIEFDTTsgYGttZWFucyhkYXRvcywgY2VudGVycz0zKWAgcGFyYSBjbMO6c3Rlci4KLSAgICoqUHl0aG9uOioqCiAgICAtICAgTGlicmVyw61hcyBgc2tsZWFybmAgKFBDQSwgTERBLCBLLW1lYW5zKSwgYHByaW5jZWAgKE1DQSksCiAgICAgICAgYGZhY3Rvcl9hbmFseXplcmAgKEVGQSwgQ0ZBKS4KICAgIC0gICBFamVtcGxvOiBgc2tsZWFybi5kZWNvbXBvc2l0aW9uLlBDQShuX2NvbXBvbmVudHM9MilgOwogICAgICAgIGBwcmluY2UuTUNBKG5fY29tcG9uZW50cz0yKWAuCgojIyMgQmFzZXMgZGUgZGF0b3M6CgotICAgTkhBTkVTIHBhcmEgYmlvbWFyY2Fkb3JlcyAoZS5nLiwgbMOtcGlkb3MsIGdsdWNvc2EpLgotICAgQ2xpbmljYWxUcmlhbHMuZ292IHBhcmEgZGF0b3MgZGUgZW5zYXlvcyBjbMOtbmljb3MuCi0gICBFbmN1ZXN0YXMgZGUgc2FsdWQgKGUuZy4sIFdITyBXb3JsZCBIZWFsdGggU3VydmV5KSBwYXJhIGRhdG9zCiAgICBjYXRlZ8Ozcmljb3MuCgojIFRhYmxhIFJlc3VtZW46IE3DqXRvZG9zIE11bHRpdmFyaWFkb3MgZW4gZWwgU2VjdG9yIFNhbHVkCgpgYGB7ciBtdWx0aXZhcmlhZG8tdGFibGUsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2FzaXMnLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCgojIENyZWFyIGxhIHRhYmxhCnRhYmxhX211bHRpdmFyaWFkbyA8LSBkYXRhLmZyYW1lKAogICJUw6ljbmljYSIgPSBjKAogICAgIkFuw6FsaXNpcyBkZSBDb21wb25lbnRlcyBQcmluY2lwYWxlcyAoUENBKSIsCiAgICAiQW7DoWxpc2lzIEZhY3RvcmlhbCBFeHBsb3JhdG9yaW8gKEVGQSkiLAogICAgIkFuw6FsaXNpcyBGYWN0b3JpYWwgQ29uZmlybWF0b3JpbyAoQ0ZBKSIsCiAgICAiQW7DoWxpc2lzIERpc2NyaW1pbmFudGUgTGluZWFsIChMREEpIiwKICAgICJBbsOhbGlzaXMgZGUgQ2zDunN0ZXIgKEstbWVhbnMpIiwKICAgICJBbsOhbGlzaXMgZGUgQ2zDunN0ZXIgSmVyw6FycXVpY28iLAogICAgIkFuw6FsaXNpcyBkZSBDb3JyZXNwb25kZW5jaWFzIE3Dumx0aXBsZXMgKEFDTSkiCiAgKSwKICAiVGlwbyBkZSBBbsOhbGlzaXMiID0gYygKICAgICJSZWR1Y2Npw7NuIGRlIGRpbWVuc2lvbmFsaWRhZCIsCiAgICAiUmVkdWNjacOzbiBkZSBkaW1lbnNpb25hbGlkYWQgKGZhY3RvcmVzIGxhdGVudGVzKSIsCiAgICAiVmFsaWRhY2nDs24gZGUgZXN0cnVjdHVyYSBmYWN0b3JpYWwiLAogICAgIkNsYXNpZmljYWNpw7NuIHN1cGVydmlzYWRhIiwKICAgICJBZ3J1cGFtaWVudG8gbm8gc3VwZXJ2aXNhZG8iLAogICAgIkFncnVwYW1pZW50byBubyBzdXBlcnZpc2FkbyIsCiAgICAiQW7DoWxpc2lzIGRlIGFzb2NpYWNpw7NuIGNhdGVnw7NyaWNhIgogICksCiAgIlN1cHVlc3RvcyBDbGF2ZSIgPSBjKAogICAgIkxpbmVhbGlkYWQsIG5vcm1hbGlkYWQgKHByZWZlcmlibGUpLCBhbHRhIGNvcnJlbGFjacOzbiBlbnRyZSB2YXJpYWJsZXMiLAogICAgIkZhY3RvcmFiaWxpZGFkIChLTU8gPiAwLjYpLCBhZGVjdWFkYSBtdWVzdHJhICg+NSBwb3IgdmFyaWFibGUpIiwKICAgICJNb2RlbG8gdGXDs3JpY28gcHJlZGVmaW5pZG8sIG5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhIiwKICAgICJOb3JtYWxpZGFkIG11bHRpdmFyaWFkYSwgaG9tb2NlZGFzdGljaWRhZCBlbnRyZSBncnVwb3MiLAogICAgIk7Dum1lcm8gZGUgY2zDunN0ZXJlcyBjb25vY2lkbywgdmFyaWFibGVzIGNvbnRpbnVhcyIsCiAgICAiTm8gcmVxdWllcmUgbsO6bWVybyBmaWpvIGRlIGNsw7pzdGVyZXMsIGRpc3RhbmNpYSBldWNsaWRpYW5hIiwKICAgICJEYXRvcyBjYXRlZ8Ozcmljb3MsIGZyZWN1ZW5jaWFzIHN1ZmljaWVudGVzIHBvciBjYXRlZ29yw61hIgogICksCiAgIkFwbGljYWNpw7NuIGVuIFNhbHVkIiA9IGMoCiAgICAiUmVkdWNpciBtw7psdGlwbGVzIGJpb21hcmNhZG9yZXMgYSBjb21wb25lbnRlcyBpbnRlcnByZXRhYmxlcyIsCiAgICAiSWRlbnRpZmljYXIgZmFjdG9yZXMgc3VieWFjZW50ZXMgZW4gc8OtbnRvbWFzIG8gY3Vlc3Rpb25hcmlvcyIsCiAgICAiVmFsaWRhciBlc2NhbGFzIGRlIGNhbGlkYWQgZGUgdmlkYSBvIGRpYWduw7NzdGljbyIsCiAgICAiQ2xhc2lmaWNhciBwYWNpZW50ZXMgKGUuZy4sIGRpYWLDqXRpY29zIHZzLiBubyBkaWFiw6l0aWNvcykiLAogICAgIlNlZ21lbnRhciBwYWNpZW50ZXMgcG9yIHBlcmZpbCBkZSByaWVzZ28gKGUuZy4sIGNhcmRpb3Zhc2N1bGFyKSIsCiAgICAiRXhwbG9yYXIgamVyYXJxdcOtYSBkZSBzaW1pbGl0dWQgZW50cmUgcGFjaWVudGVzIG8gY29uZGljaW9uZXMiLAogICAgIkFuYWxpemFyIGFzb2NpYWNpb25lcyBlbnRyZSBjb21vcmJpbGlkYWRlcywgZXN0aWxvIGRlIHZpZGEgeSBkZW1vZ3JhZsOtYSIKICApLAogICJFamVtcGxvIFByw6FjdGljbyIgPSBjKAogICAgIlBDQSByZWR1Y2UgMTAgYmlvbWFyY2Fkb3JlcyBhIDIgY29tcG9uZW50ZXM6IG1ldGFiw7NsaWNvIHkgbGlww61kaWNvIiwKICAgICJFRkEgaWRlbnRpZmljYSBmYWN0b3JlcyBkZSAnZGVwcmVzacOzbicgeSAnYW5zaWVkYWQnIGVuIHVuIGN1ZXN0aW9uYXJpbyIsCiAgICAiQ0ZBIHZhbGlkYSBxdWUgdW4gY3Vlc3Rpb25hcmlvIG1pZGUgMyBkaW1lbnNpb25lcyBlbiBwYWNpZW50ZXMgb25jb2zDs2dpY29zIiwKICAgICJMREEgY2xhc2lmaWNhIGRpYWJldGVzIGNvbiA4NSUgZGUgcHJlY2lzacOzbiB1c2FuZG8gZ2x1Y29zYSBlIElNQyIsCiAgICAiSy1tZWFucyBhZ3J1cGEgMTAwMCBwYWNpZW50ZXMgZW4gYWx0bywgbW9kZXJhZG8geSBiYWpvIHJpZXNnbyIsCiAgICAiRGVuZHJvZ3JhbWEgbXVlc3RyYSBzaW1pbGl0dWQgZW50cmUgcGFjaWVudGVzIGNvbiBlbmZlcm1lZGFkZXMgY3LDs25pY2FzIiwKICAgICJBQ00gcmV2ZWxhIGFzb2NpYWNpw7NuIGVudHJlIGRpYWJldGVzLCB0YWJhcXVpc21vIHkgYmFqbyBuaXZlbCBlZHVjYXRpdm8iCiAgKSwKICBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UKKQoKIyBNb3N0cmFyIHRhYmxhCmthYmxlKHRhYmxhX211bHRpdmFyaWFkbywgImh0bWwiLCAKICAgICAgY2FwdGlvbiA9ICJUYWJsYSA2OiBSZXN1bWVuIGRlIG3DqXRvZG9zIG11bHRpdmFyaWFkb3MgYXBsaWNhZG9zIGFsIHNlY3RvciBzYWx1ZCIpICU+JQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgInJlc3BvbnNpdmUiKSwgZnVsbF93aWR0aCA9IEZBTFNFKSAlPiUKICBzY3JvbGxfYm94KHdpZHRoID0gIjEwMCUiLCBoZWlnaHQgPSAiNTAwcHgiKQoKCmBgYAoKIyA3LiBJbmZlcmVuY2lhIEJheWVzaWFuYSBwYXJhIGVsIFNlY3RvciBTYWx1ZAoKTGEgaW5mZXJlbmNpYSBiYXllc2lhbmEgZXMgdW4gZW5mb3F1ZSBlc3RhZMOtc3RpY28gcXVlIHV0aWxpemEgZWwgdGVvcmVtYQpkZSBCYXllcyBwYXJhIGFjdHVhbGl6YXIgY3JlZW5jaWFzIHNvYnJlIHBhcsOhbWV0cm9zIHBvYmxhY2lvbmFsZXMgYQpwYXJ0aXIgZGUgZGF0b3Mgb2JzZXJ2YWRvcywgc2llbmRvIGVzcGVjaWFsbWVudGUgw7p0aWwgZW4gZWwgc2VjdG9yIHNhbHVkCnBhcmEgbWFuZWphciBpbmNlcnRpZHVtYnJlIGVuIGVuc2F5b3MgY2zDrW5pY29zLCBlc3R1ZGlvcyBlcGlkZW1pb2zDs2dpY29zCnkgZGVjaXNpb25lcyBjbMOtbmljYXMuIEVzdGUgdGVtYXJpbyBkZXNhcnJvbGxhIGxvcyBmdW5kYW1lbnRvcywgbcOpdG9kb3MKeSBhcGxpY2FjaW9uZXMgZGUgbGEgaW5mZXJlbmNpYSBiYXllc2lhbmEsIGNvbiBlamVtcGxvcyBwcsOhY3RpY29zCnJlbGV2YW50ZXMgcGFyYSBwcm9mZXNpb25hbGVzIG3DqWRpY29zLCBpbnZlc3RpZ2Fkb3JlcyBjbMOtbmljb3MgeQplcGlkZW1pw7Nsb2dvcy4KCiMjIDcuMSBGdW5kYW1lbnRvcwoKIyMjIFRlb3JlbWEgZGUgQmF5ZXMgeSBQcm9iYWJpbGlkYWQgYSBQb3N0ZXJpb3JpCgpMYSBpbmZlcmVuY2lhIGJheWVzaWFuYSBzZSBiYXNhIGVuIGVsIHRlb3JlbWEgZGUgQmF5ZXMsIHF1ZSBjb21iaW5hCmluZm9ybWFjacOzbiBwcmV2aWEgKHByaW9yKSBjb24gZGF0b3Mgb2JzZXJ2YWRvcyBwYXJhIG9idGVuZXIgdW5hCmRpc3RyaWJ1Y2nDs24gYSBwb3N0ZXJpb3JpIHF1ZSByZWZsZWphIGxhIGluY2VydGlkdW1icmUgYWN0dWFsaXphZGEgc29icmUKdW4gcGFyw6FtZXRyby4KCioqVGVvcmVtYSBkZSBCYXllczoqKiAkJApQKFx0aGV0YSB8IEQpID0gXGZyYWN7UChEIHwgXHRoZXRhKSBcY2RvdCBQKFx0aGV0YSl9e1AoRCl9CiQkIERvbmRlOgoKLSAgICRQKFx0aGV0YSB8IEQpJDogRGlzdHJpYnVjacOzbiBhIHBvc3RlcmlvcmkgZGVsIHBhcsOhbWV0cm8gJFx0aGV0YSQKICAgIGRhZG8gbG9zIGRhdG9zICREJC4KLSAgICRQKEQgfCBcdGhldGEpJDogVmVyb3NpbWlsaXR1ZCwgcHJvYmFiaWxpZGFkIGRlIGxvcyBkYXRvcyBkYWRvCiAgICAkXHRoZXRhJC4KLSAgICRQKFx0aGV0YSkkOiBEaXN0cmlidWNpw7NuIGEgcHJpb3JpLCByZWZsZWphIGVsIGNvbm9jaW1pZW50byBwcmV2aW8KICAgIHNvYnJlICRcdGhldGEkLgotICAgJFAoRCkkOiBFdmlkZW5jaWEsIG5vcm1hbGl6YSBsYSBwb3N0ZXJpb3JpCiAgICAoJFAoRCkgPSBcaW50IFAoRCB8IFx0aGV0YSkgUChcdGhldGEpIGRcdGhldGEkKS4KCioqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogRW4gdW4gZW5zYXlvIGNsw61uaWNvLCAkXHRoZXRhJCBwdWVkZSBzZXIgbGEKZWZlY3RpdmlkYWQgZGUgdW4gdHJhdGFtaWVudG8gKGUuZy4sIHJlZHVjY2nDs24gZW4gbGEgcHJlc2nDs24gYXJ0ZXJpYWwpLAokUChcdGhldGEpJCByZWZsZWphIGVzdHVkaW9zIHByZXZpb3MsICRQKEQgfCBcdGhldGEpJCBlcyBsYSBwcm9iYWJpbGlkYWQKZGUgbG9zIGRhdG9zIGRlbCBlbnNheW8sIHkgJFAoXHRoZXRhIHwgRCkkIGVzdGltYSBsYSBlZmVjdGl2aWRhZAphY3R1YWxpemFkYS4KCioqRWplbXBsbyBwcsOhY3RpY286KiogUGFyYSBlc3RpbWFyIGxhIHByZXZhbGVuY2lhIGRlIGRpYWJldGVzICgkXHRoZXRhJCkKZW4gdW5hIHBvYmxhY2nDs24sIHNlIHVzYSB1biBwcmlvciBiYXNhZG8gZW4gZGF0b3MgbmFjaW9uYWxlcwooJFAoXHRoZXRhKSBcc2ltIFx0ZXh0e0JldGF9KDUsIDk1KSQpLCBwcmV2YWxlbmNpYSBcfjUlLiBDb24gdW5hIG11ZXN0cmEKZGUgMjAwIHBhY2llbnRlcyBkb25kZSAxNSB0aWVuZW4gZGlhYmV0ZXMsIGxhIHZlcm9zaW1pbGl0dWQgZXMgYmlub21pYWwsCnkgbGEgcG9zdGVyaW9yaSBhY3R1YWxpemEgbGEgZXN0aW1hY2nDs24gYQokXHRoZXRhIFxzaW0gXHRleHR7QmV0YX0oMjAsIDI4MCkkLCBjb24gdW5hIHByZXZhbGVuY2lhIG1lZGlhIGRlCiRcZnJhY3syMH17MjArMjgwfSBcYXBwcm94IDYuNjdcJSQuCgojIyMgUHJpb3JzOiBJbmZvcm1hdGl2b3MgeSBObyBJbmZvcm1hdGl2b3MKCkVsIHByaW9yICRQKFx0aGV0YSkkIHJlZmxlamEgZWwgY29ub2NpbWllbnRvIHByZXZpbyBzb2JyZSBlbCBwYXLDoW1ldHJvIHkKcHVlZGUgaW5mbHVpciBlbiBsYSBwb3N0ZXJpb3JpLCBlc3BlY2lhbG1lbnRlIGNvbiBtdWVzdHJhcyBwZXF1ZcOxYXMuCgoqKlByaW9ycyBpbmZvcm1hdGl2b3M6KioKCi0gICBCYXNhZG9zIGVuIGRhdG9zIHByZXZpb3MsIGxpdGVyYXR1cmEgbyBjb25vY2ltaWVudG8gZXhwZXJ0by4KLSAgICoqVmVudGFqYToqKiBJbmNvcnBvcmFuIGluZm9ybWFjacOzbiByZWxldmFudGUsIMO6dGlsIGVuIGVuc2F5b3MKICAgIGNsw61uaWNvcyBjb24gZGF0b3MgaGlzdMOzcmljb3MuCi0gICAqKkVqZW1wbG86KiogUGFyYSBsYSBlZmVjdGl2aWRhZCBkZSB1bmEgdmFjdW5hICgkXHRoZXRhJCksIHVuIHByaW9yCiAgICBpbmZvcm1hdGl2byBwb2Ryw61hIHNlciAkXHRoZXRhIFxzaW0gXHRleHR7QmV0YX0oODAsIDIwKSQsIGJhc2FkbyBlbgogICAgZW5zYXlvcyBwcmV2aW9zIHF1ZSBzdWdpZXJlbiB1biA4MCUgZGUgZWZpY2FjaWEuCi0gICAqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIFVzYXIgZGF0b3MgZGUgZW5zYXlvcyBwcmV2aW9zIHBhcmEgZGVmaW5pcgogICAgdW4gcHJpb3Igc29icmUgbGEgdGFzYSBkZSByZXNwdWVzdGEgYSB1biBmw6FybWFjby4KCioqUHJpb3JzIG5vIGluZm9ybWF0aXZvczoqKgoKLSAgIFJlZmxlamFuIG3DrW5pbWEgaW5mb3JtYWNpw7NuIHByZXZpYSwgcGVybWl0aWVuZG8gcXVlIGxvcyBkYXRvcwogICAgZG9taW5lbiBsYSBwb3N0ZXJpb3JpLgotICAgKipFamVtcGxvczoqKiBVbmlmb3JtZSAoJFx0aGV0YSBcc2ltIFx0ZXh0e1VuaWZvcm19KDAsIDEpJCkgcGFyYQogICAgcHJvcG9yY2lvbmVzLCBvIEplZmZyZXlzIHByaW9yIHBhcmEgcGFyw6FtZXRyb3MgY29udGludW9zLgotICAgKipWZW50YWphOioqIFJlZHVjZW4gbGEgc3ViamV0aXZpZGFkIGN1YW5kbyBubyBoYXkgaW5mb3JtYWNpw7NuCiAgICBwcmV2aWEgZmlhYmxlLgotICAgKipFamVtcGxvOioqIFBhcmEgbGEgbWVkaWEgZGUgcHJlc2nDs24gYXJ0ZXJpYWwgKCRcbXUkKSwgdW4gcHJpb3Igbm8KICAgIGluZm9ybWF0aXZvIHBvZHLDrWEgc2VyICRcbXUgXHNpbSBOKDAsIDEwXjYpJCwgY29uIGdyYW4gdmFyaWFuemEuCgoqKlByaW9ycyBjb25qdWdhZG9zOioqIFNpbXBsaWZpY2FuIGPDoWxjdWxvcyBhbmFsw610aWNvcy4gRWplbXBsbzogVW4KcHJpb3IgQmV0YSBwYXJhIHVuYSBwcm9wb3JjacOzbiBiaW5vbWlhbCBwcm9kdWNlIHVuYSBwb3N0ZXJpb3JpIEJldGEuCgoqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuIGVzdHVkaW8gZGUgcHJldmFsZW5jaWEgZGUgaGlwZXJ0ZW5zacOzbiwgdW4KcHJpb3Igbm8gaW5mb3JtYXRpdm8gKCRcdGhldGEgXHNpbSBcdGV4dHtCZXRhfSgxLCAxKSQpIHNlIGFjdHVhbGl6YSBjb24KZGF0b3MgZGUgNTAgcGFjaWVudGVzICgxMCBoaXBlcnRlbnNvcyksIGRhbmRvIHVuYSBwb3N0ZXJpb3JpCiRcdGhldGEgXHNpbSBcdGV4dHtCZXRhfSgxMSwgNDEpJCwgY29uIG1lZGlhCiRcZnJhY3sxMX17MTErNDF9IFxhcHByb3ggMC4yMTIkLgoKIyMgNy4yIE3DqXRvZG9zIEJheWVzaWFub3MKCiMjIyBFc3RpbWFjacOzbiBCYXllc2lhbmEgZGUgUGFyw6FtZXRyb3MKCkxhIGVzdGltYWNpw7NuIGJheWVzaWFuYSBwcm9wb3JjaW9uYSBkaXN0cmlidWNpb25lcyBhIHBvc3RlcmlvcmkKY29tcGxldGFzIHBhcmEgbG9zIHBhcsOhbWV0cm9zLCBlbiBsdWdhciBkZSBlc3RpbWFjaW9uZXMgcHVudHVhbGVzIGNvbW8KZW4gbGEgZXN0YWTDrXN0aWNhIGZyZWN1ZW50aXN0YS4KCioqRXN0aW1hY2nDs24gcHVudHVhbDoqKgoKLSAgICoqTWVkaWEgYSBwb3N0ZXJpb3JpOioqICRFKFx0aGV0YSB8IEQpJCwgw7p0aWwgcGFyYSByZXN1bWlyIGxhCiAgICBkaXN0cmlidWNpw7NuLgotICAgKipNb2RhIGEgcG9zdGVyaW9yaSAoTUFQKToqKiBWYWxvciBxdWUgbWF4aW1pemEgJFAoXHRoZXRhIHwgRCkkLgoKKipFamVtcGxvIHByw6FjdGljbzoqKiBFbiB1biBlbnNheW8gY2zDrW5pY28sIGxhIG1lZGlhIGEgcG9zdGVyaW9yaSBkZSBsYQpyZWR1Y2Npw7NuIGRlIGdsdWNvc2EgcG9yIHVuIGbDoXJtYWNvIGVzIDE1IG1nL2RMLCBiYXNhZGEgZW4gdW5hCnBvc3RlcmlvcmkgJFx0aGV0YSBcc2ltIE4oMTUsIDJeMikkLgoKKipFc3RpbWFjacOzbiBwb3IgaW50ZXJ2YWxvczoqKiBWZXIgc2VjY2nDs24gc2lndWllbnRlLgoKKipNw6l0b2RvcyBkZSBjw6FsY3VsbzoqKgoKLSAgICoqQW5hbMOtdGljb3M6KiogVXNhciBwcmlvcnMgY29uanVnYWRvcyBwYXJhIG9idGVuZXIgcG9zdHJpb3JpcwogICAgY2VycmFkYXMgKGUuZy4sIEJldGEgcGFyYSBiaW5vbWlhbCwgTm9ybWFsIHBhcmEgbm9ybWFsKS4KLSAgICoqTnVtw6lyaWNvczoqKiBNw6l0b2RvcyBjb21vIE1vbnRlIENhcmxvIHBvciBDYWRlbmFzIGRlIE1hcmtvdiAoTUNNQykKICAgIHBhcmEgZGlzdHJpYnVjaW9uZXMgY29tcGxlamFzLgoKKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBFc3RpbWFyIGxhIHRhc2EgZGUgaW5mZWNjacOzbiBob3NwaXRhbGFyaWEKKCRcdGhldGEkKSBjb21iaW5hbmRvIGRhdG9zIGRlIHVuIGhvc3BpdGFsIGNvbiB1biBwcmlvciBiYXNhZG8gZW4KZXN0dWRpb3MgbmFjaW9uYWxlcy4KCiMjIyBJbnRlcnZhbG9zIGRlIENyZWRpYmlsaWRhZAoKTG9zIGludGVydmFsb3MgZGUgY3JlZGliaWxpZGFkIChJQ3IpIHNvbiBlbCBlcXVpdmFsZW50ZSBiYXllc2lhbm8gZGUgbG9zCmludGVydmFsb3MgZGUgY29uZmlhbnphIGZyZWN1ZW50aXN0YXMsIHByb3BvcmNpb25hbmRvIHVuIHJhbmdvIHF1ZQpjb250aWVuZSBlbCBwYXLDoW1ldHJvIGNvbiB1bmEgcHJvYmFiaWxpZGFkIGRhZGEuCgoqKkRlZmluaWNpw7NuOioqIFVuIElDciBhbCA5NSUgZXMgdW4gaW50ZXJ2YWxvICRbYSwgYl0kIHRhbCBxdWUKJFAoYSBcbGVxIFx0aGV0YSBcbGVxIGIgfCBEKSA9IDAuOTUkLgoKLSAgIFB1ZWRlIHNlciBzaW3DqXRyaWNvIChwZXJjZW50aWxlcyAyLjUlIHkgOTcuNSUpIG8gZGUgbWF5b3IgZGVuc2lkYWQgYQogICAgcG9zdGVyaW9yaSAoSFBELCBoaWdoZXN0IHBvc3RlcmlvciBkZW5zaXR5KS4KLSAgICoqQ8OhbGN1bG86KioKICAgIC0gICBQYXJhIGRpc3RyaWJ1Y2lvbmVzIGFuYWzDrXRpY2FzIChlLmcuLCBCZXRhLCBOb3JtYWwpLCB1c2FyCiAgICAgICAgcGVyY2VudGlsZXMgZGUgbGEgcG9zdGVyaW9yaS4KICAgIC0gICBQYXJhIGRpc3RyaWJ1Y2lvbmVzIGNvbXBsZWphcywgdXNhciBtdWVzdHJhcyBNQ01DLgotICAgKipJbnRlcnByZXRhY2nDs246KiogQSBkaWZlcmVuY2lhIGRlIGxvcyBpbnRlcnZhbG9zIGRlIGNvbmZpYW56YSwgdW4KICAgIElDciBhbCA5NSUgaW5kaWNhIHF1ZSBoYXkgdW4gOTUlIGRlIHByb2JhYmlsaWRhZCBkZSBxdWUgJFx0aGV0YSQKICAgIGVzdMOpIGVuIGVsIGludGVydmFsbywgZGFkbyBsb3MgZGF0b3MgeSBlbCBwcmlvci4KCioqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogRXN0aW1hciBsYSBwcm9iYWJpbGlkYWQgZGUgw6l4aXRvIGRlIHVuCnRyYXRhbWllbnRvIGNvbiB1biBJQ3IuCgoqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuIGVzdHVkaW8gZGUgdW4gbnVldm8gZsOhcm1hY28sIGxhIHBvc3RlcmlvcmkKcGFyYSBsYSBwcm9wb3JjacOzbiBkZSByZXNwb25kZWRvcmVzIGVzCiRcdGhldGEgXHNpbSBcdGV4dHtCZXRhfSgzMCwgNzApJC4gRWwgSUNyIGFsIDk1JSBlcyBhcHJveGltYWRhbWVudGUKWzAuMjEsIDAuNDBdLCBpbmRpY2FuZG8gcXVlIGxhIHByb2JhYmlsaWRhZCBkZSByZXNwdWVzdGEgZXN0w6EgZW50cmUgMjElCnkgNDAlIGNvbiA5NSUgZGUgcHJvYmFiaWxpZGFkLgoKIyMgNy4zIEFwbGljYWNpb25lcyBQcsOhY3RpY2FzCgojIyMgTW9kZWxvcyBKZXLDoXJxdWljb3MKCkxvcyBtb2RlbG9zIGplcsOhcnF1aWNvcyBiYXllc2lhbm9zIG1vZGVsYW4gcGFyw6FtZXRyb3MgcXVlIHZhcsOtYW4gZW50cmUKZ3J1cG9zIChlLmcuLCBob3NwaXRhbGVzLCByZWdpb25lcykgY29uIHVuIHByaW9yIGNvbcO6biwgcGVybWl0aWVuZG8KY29tcGFydGlyIGluZm9ybWFjacOzbiBlbnRyZSBncnVwb3MuCgoqKk1vZGVsbzoqKiAkJApZX3tpan0gXHNpbSBcdGV4dHtOb3JtYWx9KFx0aGV0YV9pLCBcc2lnbWFeMikKJCQgJCQKXHRoZXRhX2kgXHNpbSBcdGV4dHtOb3JtYWx9KFxtdSwgXHRhdV4yKQokJCBEb25kZSAkXHRoZXRhX2kkIGVzIGVsIHBhcsOhbWV0cm8gZGVsIGdydXBvICRpJCAoZS5nLiwgdGFzYSBkZQppbmZlY2Npw7NuIGVuIGVsIGhvc3BpdGFsICRpJCksIHkgJFxtdSwgXHRhdV4yJCBzb24gaGlwZXJwYXLDoW1ldHJvcy4KCioqVmVudGFqYXM6KioKCi0gICBNYW5lamEgaGV0ZXJvZ2VuZWlkYWQgZW50cmUgZ3J1cG9zLgotICAgTWVqb3JhIGVzdGltYWNpb25lcyBlbiBncnVwb3MgY29uIHBvY29zIGRhdG9zIChzaHJpbmthZ2UpLgoKKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBFc3RpbWFyIHRhc2FzIGRlIG1vcnRhbGlkYWQgcG9yIENPVklELTE5IGVuCmRpZmVyZW50ZXMgaG9zcGl0YWxlcywgdXNhbmRvIHVuIG1vZGVsbyBqZXLDoXJxdWljbyBwYXJhIGNvbXBhcnRpcgppbmZvcm1hY2nDs24gZW50cmUgaG9zcGl0YWxlcyBjb24gdGFtYcOxb3MgbXVlc3RyYWxlcyBkaXNwYXJlcy4KCioqRWplbXBsbyBwcsOhY3RpY286KiogRW4gdW4gZXN0dWRpbyBkZSAxMCBob3NwaXRhbGVzLCBsYXMgdGFzYXMgZGUKaW5mZWNjacOzbiB2YXLDrWFuLiBVbiBtb2RlbG8gamVyw6FycXVpY28gZXN0aW1hIHRhc2FzIGluZGl2aWR1YWxlcwooJFx0aGV0YV9pJCkgY29uIHVuIHByaW9yIGNvbcO6biAkXG11IFxzaW0gTigwLjA1LCAwLjAxXjIpJCwgbWVqb3JhbmRvIGxhCnByZWNpc2nDs24gZW4gaG9zcGl0YWxlcyBjb24gcG9jb3MgZGF0b3MuCgojIyMgTUNNQyAoTW9udGUgQ2FybG8gcG9yIENhZGVuYXMgZGUgTWFya292KQoKTUNNQyBlcyB1biBtw6l0b2RvIGNvbXB1dGFjaW9uYWwgcGFyYSBtdWVzdHJlYXIgZGlzdHJpYnVjaW9uZXMgYQpwb3N0ZXJpb3JpIGNvbXBsZWphcywgZXNwZWNpYWxtZW50ZSBlbiBtb2RlbG9zIG5vIGNvbmp1Z2Fkb3MgbwpqZXLDoXJxdWljb3MuCgoqKk3DqXRvZG86KioKCi0gICBHZW5lcmEgdW5hIGNhZGVuYSBkZSBtdWVzdHJhcyBxdWUgY29udmVyZ2VuIGEgbGEgZGlzdHJpYnVjacOzbiBhCiAgICBwb3N0ZXJpb3JpLgotICAgKipBbGdvcml0bW9zIGNvbXVuZXM6KiogTWV0cm9wb2xpcy1IYXN0aW5ncywgR2liYnMgc2FtcGxpbmcuCgoqKlBhc29zOioqCgoxLiAgRGVmaW5pciBlbCBtb2RlbG8gKHByaW9yIHkgdmVyb3NpbWlsaXR1ZCkuCjIuICBFamVjdXRhciBNQ01DIHBhcmEgZ2VuZXJhciBtdWVzdHJhcyBkZSBsYSBwb3N0ZXJpb3JpLgozLiAgUmVzdW1pciByZXN1bHRhZG9zIChtZWRpYSwgSUNyLCBldGMuKSB1c2FuZG8gbGFzIG11ZXN0cmFzLgoKKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBNb2RlbGFyIGxhIGVmZWN0aXZpZGFkIGRlIHVuIHRyYXRhbWllbnRvIGVuIHVuCmVuc2F5byBjbMOtbmljbyBjb24gZGF0b3MgZmFsdGFudGVzIG8gZXN0cnVjdHVyYXMgY29tcGxlamFzLgoKKipFamVtcGxvIHByw6FjdGljbzoqKiBFbiB1biBlbnNheW8gY2zDrW5pY28sIHNlIHVzYSBNQ01DIHBhcmEgZXN0aW1hciBsYQpwcm9iYWJpbGlkYWQgZGUgcmVzcHVlc3RhIGEgdW4gdHJhdGFtaWVudG8gKCRcdGhldGEkKSBjb24gdW4gcHJpb3Igbm8KaW5mb3JtYXRpdm8geSBkYXRvcyBiaW5vbWlhbGVzLiBVc2FuZG8gZWwgcGFxdWV0ZSByc3RhbiBlbiBSLCBzZSBnZW5lcmFuCjEwLDAwMCBtdWVzdHJhcywgZGFuZG8gdW5hIG1lZGlhIGEgcG9zdGVyaW9yaSBkZSAwLjc1IHkgdW4gSUNyIGFsIDk1JSBkZQpbMC42OCwgMC44Ml0uCgoqKkhlcnJhbWllbnRhczoqKiBSIChyc3RhbiwgYnJtcyksIFB5dGhvbiAocHltYywgc3RhbiksIHNvZnR3YXJlIGNvbW8KQlVHUyBvIEpBR1MuCgojIyA4LiBEaXNlw7FvIGRlIEV4cGVyaW1lbnRvcwoKRWwgZGlzZcOxbyBkZSBleHBlcmltZW50b3MgKERPRSkgZXMgY3J1Y2lhbCBwYXJhIGdhcmFudGl6YXIgcXVlIGxvcwplc3R1ZGlvcyBjbMOtbmljb3MgeSBlcGlkZW1pb2zDs2dpY29zIHByb2R1emNhbiByZXN1bHRhZG9zIHbDoWxpZG9zIHkKcmVwcm9kdWNpYmxlcy4gRW4gZWwgc2VjdG9yIHNhbHVkLCBlbCBET0Ugb3B0aW1pemEgbGEgYXNpZ25hY2nDs24gZGUKdHJhdGFtaWVudG9zLCBjb250cm9sYSBzZXNnb3MgeSBtYXhpbWl6YSBsYSBwb3RlbmNpYSBlc3RhZMOtc3RpY2EuCgojIyMgOC4xIFByaW5jaXBpb3MgQsOhc2ljb3MKCioqQWxlYXRvcml6YWNpw7NuOioqIEFzaWduYXIgc3VqZXRvcyBhIGdydXBvcyAoZS5nLiwgdHJhdGFtaWVudG8gdnMuCnBsYWNlYm8pIGFsIGF6YXIgcGFyYSBtaW5pbWl6YXIgc2VzZ29zIHkgZ2FyYW50aXphciBjb21wYXJhYmlsaWRhZC4KCi0gICAqKkVqZW1wbG86KiogRW4gdW4gZW5zYXlvIGNsw61uaWNvLCBwYWNpZW50ZXMgc29uIGFzaWduYWRvcwogICAgYWxlYXRvcmlhbWVudGUgYSB1biBudWV2byBmw6FybWFjbyBvIHBsYWNlYm8gcGFyYSBldml0YXIgc2VzZ29zIGRlCiAgICBzZWxlY2Npw7NuLgoKKipSZXBsaWNhY2nDs246KiogUmVhbGl6YXIgbcO6bHRpcGxlcyBvYnNlcnZhY2lvbmVzIHBvciBncnVwbyBwYXJhIGVzdGltYXIKbGEgdmFyaWFiaWxpZGFkIHkgYXVtZW50YXIgbGEgcHJlY2lzacOzbi4KCi0gICAqKkVqZW1wbG86KiogSW5jbHVpciA1MCBwYWNpZW50ZXMgcG9yIGdydXBvIGVuIHVuIGVuc2F5byBwYXJhCiAgICBlc3RpbWFyIGxhIHZhcmlhbnphIGRlIGxhIHByZXNpw7NuIGFydGVyaWFsLgoKKipDb250cm9sOioqIFVzYXIgZ3J1cG9zIGNvbnRyb2wgKGUuZy4sIHBsYWNlYm8pIG8gY29uZGljaW9uZXMgZXN0w6FuZGFyCnBhcmEgY29tcGFyYXIgZWZlY3Rvcy4KCi0gICAqKkVqZW1wbG86KiogQ29tcGFyYXIgdW4gbnVldm8gYW50aWhpcGVydGVuc2l2byBjb24gdW4gcGxhY2VibyBwYXJhCiAgICBtZWRpciBzdSBlZmVjdG8gbmV0by4KCioqQmxvcXVlbzoqKiBBZ3J1cGFyIHN1amV0b3MgcG9yIGNhcmFjdGVyw61zdGljYXMgcmVsZXZhbnRlcyAoZS5nLiwgZWRhZCwKc2V4bykgcGFyYSByZWR1Y2lyIGxhIHZhcmlhYmlsaWRhZCBubyBleHBsaWNhZGEuCgotICAgKipFamVtcGxvOioqIEVzdHJhdGlmaWNhciBwYWNpZW50ZXMgcG9yIGVkYWQgZW4gdW4gZXN0dWRpbyBkZQogICAgZGlhYmV0ZXMgcGFyYSBjb250cm9sYXIgc3UgZWZlY3RvLgoKIyMjIDguMiBEaXNlw7FvcyBDb211bmVzIGVuIFNhbHVkCgoqKkRpc2XDsW8gY29tcGxldGFtZW50ZSBhbGVhdG9yaXphZG86KioKCi0gICBBc2lnbmEgc3VqZXRvcyBhIHRyYXRhbWllbnRvcyBkZSBmb3JtYSBhbGVhdG9yaWEgc2luIHJlc3RyaWNjaW9uZXMuCi0gICAqKkFwbGljYWNpw7NuOioqIEVuc2F5b3MgY2zDrW5pY29zIHNpbXBsZXMgY29tcGFyYW5kbyB1biBmw6FybWFjbyB2cy4KICAgIHBsYWNlYm8uCi0gICAqKkVqZW1wbG86KiogMTAwIHBhY2llbnRlcyBhc2lnbmFkb3MgYWxlYXRvcmlhbWVudGUgYSBkb3MgZ3J1cG9zCiAgICAoZsOhcm1hY28gQSB2cy4gcGxhY2VibykgcGFyYSBldmFsdWFyIGxhIHJlZHVjY2nDs24gZGUgZ2x1Y29zYS4KCioqRGlzZcOxbyBlbiBibG9xdWVzIGFsZWF0b3JpemFkb3M6KioKCi0gICBEaXZpZGUgc3VqZXRvcyBlbiBibG9xdWVzIChlLmcuLCBwb3Igc2V4byBvIGdyYXZlZGFkIGRlIGxhCiAgICBlbmZlcm1lZGFkKSB5IGFsZWF0b3JpemEgZGVudHJvIGRlIGNhZGEgYmxvcXVlLgotICAgKipBcGxpY2FjacOzbjoqKiBDb250cm9sYXIgZmFjdG9yZXMgZGUgY29uZnVzacOzbiBjb21vIGxhIGVkYWQgZW4KICAgIGVuc2F5b3MgY2zDrW5pY29zLgotICAgKipFamVtcGxvOioqIEVuIHVuIGVzdHVkaW8gZGUgaGlwZXJ0ZW5zacOzbiwgcGFjaWVudGVzIHNlIGRpdmlkZW4gZW4KICAgIGJsb3F1ZXMgcG9yIGVkYWQgKFw8NTAsIOKJpTUwKSB5IHNlIGFzaWduYW4gYWxlYXRvcmlhbWVudGUgYQogICAgdHJhdGFtaWVudG9zIGRlbnRybyBkZSBjYWRhIGJsb3F1ZS4KCioqRGlzZcOxbyBmYWN0b3JpYWw6KioKCi0gICBFdmFsw7phIG3Dumx0aXBsZXMgZmFjdG9yZXMgc2ltdWx0w6FuZWFtZW50ZSAoZS5nLiwgdHJhdGFtaWVudG8geQogICAgZG9zaXMpLgoKLSAgICoqTW9kZWxvOioqICQkCiAgICBZX3tpamt9ID0gXG11ICsgXGFscGhhX2kgKyBcYmV0YV9qICsgKFxhbHBoYVxiZXRhKV97aWp9ICsgXGVwc2lsb25fe2lqa30KICAgICQkCgotICAgKipBcGxpY2FjacOzbjoqKiBFc3R1ZGlhciBlbCBlZmVjdG8gY29tYmluYWRvIGRlIHVuIGbDoXJtYWNvIHkgdW5hCiAgICBkaWV0YSBlbiBlbCBjb2xlc3Rlcm9sLgoKLSAgICoqRWplbXBsbzoqKiBVbiBkaXNlw7FvIDJ4MyBldmFsw7phIGRvcyBmw6FybWFjb3MgKEEsIEIpIHkgdHJlcyBkb3NpcwogICAgKGJhamEsIG1lZGlhLCBhbHRhKSwgYW5hbGl6YW5kbyBlZmVjdG9zIHByaW5jaXBhbGVzIGUgaW50ZXJhY2Npb25lcy4KCioqRGlzZcOxbyBjcnV6YWRvOioqCgotICAgQ2FkYSBzdWpldG8gcmVjaWJlIHRvZG9zIGxvcyB0cmF0YW1pZW50b3MgZW4gdW4gb3JkZW4gYWxlYXRvcmlvLCBjb24KICAgIHBlcsOtb2RvcyBkZSBsYXZhZG8gcGFyYSBldml0YXIgZWZlY3RvcyByZXNpZHVhbGVzLgotICAgKipBcGxpY2FjacOzbjoqKiBDb21wYXJhciBsYSBlZmVjdGl2aWRhZCBkZSBkb3MgYW50aWhpcGVydGVuc2l2b3MgZW4KICAgIGxvcyBtaXNtb3MgcGFjaWVudGVzLgotICAgKipFamVtcGxvOioqIFBhY2llbnRlcyByZWNpYmVuIGbDoXJtYWNvIEEgcG9yIDQgc2VtYW5hcywgbHVlZ28gdW4KICAgIHBlcsOtb2RvIGRlIGxhdmFkbywgeSBsdWVnbyBmw6FybWFjbyBCLCBtaWRpZW5kbyBsYSBwcmVzacOzbiBhcnRlcmlhbC4KCioqRGlzZcOxbyBkZSBtZWRpZGFzIHJlcGV0aWRhczoqKgoKLSAgIE1pZGUgbGEgbWlzbWEgdmFyaWFibGUgZW4gbcO6bHRpcGxlcyBwdW50b3MgdGVtcG9yYWxlcy4KLSAgICoqQXBsaWNhY2nDs246KiogRXZhbHVhciBlbCBjYW1iaW8gZW4gSGJBMWMgYSBsbyBsYXJnbyBkZSA2IG1lc2VzIGVuCiAgICBwYWNpZW50ZXMgdHJhdGFkb3MuCi0gICAqKkVqZW1wbG86KiogTWVkaXIgZ2x1Y29zYSBiYXNhbCwgYSAzIHkgNiBtZXNlcyBlbiB1biBlbnNheW8gZGUKICAgIGluc3VsaW5hLgoKIyMjIDguMyBDb25zaWRlcmFjaW9uZXMgZW4gU2FsdWQKCioqVGFtYcOxbyBtdWVzdHJhbDoqKgoKLSAgIENhbGN1bGFyIHVzYW5kbyBmw7NybXVsYXMgYmFzYWRhcyBlbiBsYSBwb3RlbmNpYSAoJDEtXGJldGEkKSwgbml2ZWwKICAgIGRlIHNpZ25pZmljYW5jaWEgKCRcYWxwaGEkKSwgeSB0YW1hw7FvIGRlbCBlZmVjdG8gZXNwZXJhZG8uCi0gICAqKkVqZW1wbG86KiogUGFyYSBkZXRlY3RhciB1bmEgcmVkdWNjacOzbiBkZSAxMCBtbUhnIGVuIHByZXNpw7NuCiAgICBhcnRlcmlhbCAoJFxzaWdtYSA9IDE1JCksICRcYWxwaGEgPSAwLjA1JCwgcG90ZW5jaWEgPSAwLjgpLCBzZQogICAgbmVjZXNpdGFuIGFwcm94aW1hZGFtZW50ZSA0NyBwYWNpZW50ZXMgcG9yIGdydXBvLgoKKirDiXRpY2E6KioKCi0gICBHYXJhbnRpemFyIGNvbnNlbnRpbWllbnRvIGluZm9ybWFkbywgbWluaW1pemFyIHJpZXNnb3MgeSBtYXhpbWl6YXIKICAgIGJlbmVmaWNpb3MuCi0gICBVc2FyIGNvbnRyb2xlcyDDqXRpY29zIChlLmcuLCB0cmF0YW1pZW50byBlc3TDoW5kYXIgZW4gbHVnYXIgZGUKICAgIHBsYWNlYm8gc2kgZXMgbmVjZXNhcmlvKS4KCioqU2VzZ29zOioqCgotICAgKipTZXNnbyBkZSBzZWxlY2Npw7NuOioqIE1pdGlnYXIgY29uIGFsZWF0b3JpemFjacOzbi4KLSAgICoqU2VzZ28gZGUgbWVkaWNpw7NuOioqIFVzYXIgaW5zdHJ1bWVudG9zIHZhbGlkYWRvcyB5IGNlZ2FyIGEKICAgIGludmVzdGlnYWRvcmVzLgoKKipBbsOhbGlzaXM6KioKCi0gICBVc2FyIEFOT1ZBIHBhcmEgZGlzZcOxb3MgZmFjdG9yaWFsZXMsIG1vZGVsb3MgbWl4dG9zIHBhcmEgbWVkaWRhcwogICAgcmVwZXRpZGFzLCBvIG3DqXRvZG9zIGJheWVzaWFub3MgcGFyYSBpbmNvcnBvcmFyIGluZm9ybWFjacOzbiBwcmV2aWEuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuIGVuc2F5byBmYWN0b3JpYWwgMngyIChmw6FybWFjbyB2cy4KICAgIHBsYWNlYm8sIGRpZXRhIGJhamEgZW4gc2FsIHZzLiBlc3TDoW5kYXIpLCBzZSB1c2EgQU5PVkEgcGFyYSBhbmFsaXphcgogICAgZWZlY3RvcyBwcmluY2lwYWxlcyBlIGludGVyYWNjaW9uZXMsIGNvbiBhbGVhdG9yaXphY2nDs24gcG9yIGJsb3F1ZXMKICAgIHBhcmEgY29udHJvbGFyIGxhIGVkYWQuCgojIyBSZWN1cnNvcyBwYXJhIGVsIEF1dG9lc3R1ZGlvIGVuIFNhbHVkCgojIyMgTGVjdHVyYXM6CgotICAgIkJheWVzaWFuIERhdGEgQW5hbHlzaXMiIGRlIEdlbG1hbiBldCBhbC4gKENhcMOtdHVsb3Mgc29icmUKICAgIGZ1bmRhbWVudG9zIHkgTUNNQykuCi0gICAiRGVzaWduIGFuZCBBbmFseXNpcyBvZiBFeHBlcmltZW50cyIgZGUgTW9udGdvbWVyeSAoQ2Fww610dWxvcyBzb2JyZQogICAgRE9FKS4KLSAgICJCaW9zdGF0aXN0aWNzOiBBIEZvdW5kYXRpb24gZm9yIEFuYWx5c2lzIGluIHRoZSBIZWFsdGggU2NpZW5jZXMiIGRlCiAgICBEYW5pZWwgKENhcMOtdHVsb3Mgc29icmUgYmF5ZXNpYW5hIHkgRE9FKS4KCiMjIyBFamVyY2ljaW9zIHByw6FjdGljb3M6CgotICAgQ2FsY3VsYXIgcG9zdHJpb3JpcyBwYXJhIHRhc2FzIGRlIGVuZmVybWVkYWQgdXNhbmRvIHByaW9ycwogICAgY29uanVnYWRvcy4KLSAgIEltcGxlbWVudGFyIG1vZGVsb3MgamVyw6FycXVpY29zIGVuIFIgbyBQeXRob24gcGFyYSBkYXRvcyBkZQogICAgaG9zcGl0YWxlcy4KLSAgIERpc2XDsWFyIHVuIGVuc2F5byBjbMOtbmljbyBmYWN0b3JpYWwgeSBhbmFsaXphcmxvIGNvbiBBTk9WQS4KLSAgIFVzYXIgTUNNQyBwYXJhIGVzdGltYXIgcGFyw6FtZXRyb3MgZW4gdW4gbW9kZWxvIGxvZ8Otc3RpY28gYmF5ZXNpYW5vLgoKIyMjIEhlcnJhbWllbnRhcyBjb21wdXRhY2lvbmFsZXM6CgotICAgKipSOioqIFBhcXVldGVzIGByc3RhbmAsIGBicm1zYCAoYmF5ZXNpYW5hKSwgYHB3cmAgKHRhbWHDsW8KICAgIG11ZXN0cmFsKSwgYGFncmljb2xhZWAgKERPRSkuCiAgICAtICAgKipFamVtcGxvOioqCiAgICAgICAgYHN0YW5fZ2xtKHkgfiB4LCBmYW1pbHk9Ymlub21pYWwsIHByaW9yPW5vcm1hbCgwLCAxKSlgIHBhcmEKICAgICAgICByZWdyZXNpw7NuIGxvZ8Otc3RpY2EgYmF5ZXNpYW5hLgotICAgKipQeXRob246KiogTGlicmVyw61hcyBgcHltY2AsIGBzdGFuYCAoYmF5ZXNpYW5hKSwgYHN0YXRzbW9kZWxzYAogICAgKERPRSkuCiAgICAtICAgKipFamVtcGxvOioqCiAgICAgICAgYHBtLkdMTS5mcm9tX2Zvcm11bGEoJ3kgfiB4JywgZGF0YSwgZmFtaWx5PXBtLmdsbS5mYW1pbGllcy5CaW5vbWlhbCgpKWAuCgojIyMgQmFzZXMgZGUgZGF0b3M6CgotICAgTkhBTkVTIHBhcmEgZGF0b3MgZGUgYmlvbWFyY2Fkb3Jlcy4KLSAgIENsaW5pY2FsVHJpYWxzLmdvdiBwYXJhIGRhdG9zIGRlIGVuc2F5b3MgY2zDrW5pY29zLgotICAgV0hPIGRhdGFzZXRzIHBhcmEgdGFzYXMgZGUgZW5mZXJtZWRhZC4KCiMgVGFibGEgUmVzdW1lbjogSW5mZXJlbmNpYSBCYXllc2lhbmEgeSBEaXNlw7FvIGRlIEV4cGVyaW1lbnRvcyBlbiBlbCBTZWN0b3IgU2FsdWQKCmBgYHtyIGJheWVzLWRvZS10YWJsZSwgZWNobz1GQUxTRSwgcmVzdWx0cz0nYXNpcycsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkoa25pdHIpCmxpYnJhcnkoa2FibGVFeHRyYSkKCiMgQ3JlYXIgbGEgdGFibGEKdGFibGFfYmF5ZXNfZG9lIDwtIGRhdGEuZnJhbWUoCiAgIlTDqWNuaWNhIiA9IGMoCiAgICAiSW5mZXJlbmNpYSBCYXllc2lhbmEiLAogICAgIlByaW9yIGluZm9ybWF0aXZvIiwKICAgICJQcmlvciBubyBpbmZvcm1hdGl2byIsCiAgICAiSW50ZXJ2YWxvIGRlIGNyZWRpYmlsaWRhZCAoSUNyKSIsCiAgICAiTW9kZWxvcyBqZXLDoXJxdWljb3MgYmF5ZXNpYW5vcyIsCiAgICAiTUNNQyAoTW9udGUgQ2FybG8gcG9yIENhZGVuYXMgZGUgTWFya292KSIsCiAgICAiRGlzZcOxbyBjb21wbGV0YW1lbnRlIGFsZWF0b3JpemFkbyIsCiAgICAiRGlzZcOxbyBlbiBibG9xdWVzIGFsZWF0b3JpemFkb3MiLAogICAgIkRpc2XDsW8gZmFjdG9yaWFsIiwKICAgICJEaXNlw7FvIGNydXphZG8iLAogICAgIkRpc2XDsW8gZGUgbWVkaWRhcyByZXBldGlkYXMiCiAgKSwKICAiVGlwbyBkZSBBbsOhbGlzaXMiID0gYygKICAgICJFc3RpbWFjacOzbiBwYXJhbcOpdHJpY2EgYmF5ZXNpYW5hIiwKICAgICJJbmNvcnBvcmFjacOzbiBkZSBjb25vY2ltaWVudG8gcHJldmlvIiwKICAgICJFc3RpbWFjacOzbiBzaW4gaW5mb3JtYWNpw7NuIHByZXZpYSBmdWVydGUiLAogICAgIkludGVydmFsbyBkZSBlc3RpbWFjacOzbiBiYXllc2lhbm8iLAogICAgIk1vZGVsYWRvIGRlIGVmZWN0b3MgZW50cmUgZ3J1cG9zIiwKICAgICJNdWVzdHJlbyBkZSBkaXN0cmlidWNpb25lcyBwb3N0ZXJpb3JlcyIsCiAgICAiQ29tcGFyYWNpw7NuIGRlIHRyYXRhbWllbnRvcyIsCiAgICAiQ29udHJvbCBkZSBjb25mdXNvcmVzIiwKICAgICJFdmFsdWFjacOzbiBkZSBtw7psdGlwbGVzIGZhY3RvcmVzIGUgaW50ZXJhY2Npb25lcyIsCiAgICAiQ29tcGFyYWNpw7NuIGludHJhLXN1amV0byBkZSB0cmF0YW1pZW50b3MiLAogICAgIlNlZ3VpbWllbnRvIGxvbmdpdHVkaW5hbCIKICApLAogICJTdXB1ZXN0b3MgQ2xhdmUiID0gYygKICAgICJWZXJvc2ltaWxpdHVkIGJpZW4gZXNwZWNpZmljYWRhLCBwcmlvciByYXpvbmFibGUiLAogICAgIkluZm9ybWFjacOzbiBwcmV2aWEgY29uZmlhYmxlIChsaXRlcmF0dXJhLCBlc3R1ZGlvcykiLAogICAgIkF1c2VuY2lhIGRlIHNlc2dvIGZ1ZXJ0ZSBlbiBjcmVlbmNpYXMgaW5pY2lhbGVzIiwKICAgICJQb3N0ZXJpb3JpIGJpZW4gY29udmVyZ2lkYSAoTUNNQyksIG8gZm9ybWEgYW5hbMOtdGljYSIsCiAgICAiSG9tb2dlbmVpZGFkIGRlIHZhcmlhbnphIGVudHJlIGdydXBvcywgbm9ybWFsaWRhZCIsCiAgICAiQ29udmVyZ2VuY2lhIGRlIGxhIGNhZGVuYSwgbWV6Y2xhIGFkZWN1YWRhIiwKICAgICJBbGVhdG9yaXphY2nDs24gY29tcGxldGEsIGluZGVwZW5kZW5jaWEgZGUgZXJyb3JlcyIsCiAgICAiQmxvcXVlcyBob21vZ8OpbmVvcywgYWxlYXRvcml6YWNpw7NuIGRlbnRybyBkZSBibG9xdWVzIiwKICAgICJOb3JtYWxpZGFkLCBob21vY2VkYXN0aWNpZGFkLCBpbmRlcGVuZGVuY2lhIiwKICAgICJQZXLDrW9kb3MgZGUgbGF2YWRvIHN1ZmljaWVudGVzLCBhdXNlbmNpYSBkZSBlZmVjdG8gcmVzaWR1YWwiLAogICAgIkVzZmVyaWNpZGFkIChvIGNvcnJlY2Npw7NuKSwgbm9ybWFsaWRhZCBkZSByZXNpZHVvcyIKICApLAogICJNb2RlbG8gbyBFbmZvcXVlIiA9IGMoCiAgICAiJFAoXFx0aGV0YSB8IEQpIFxccHJvcHRvIFAoRCB8IFxcdGhldGEpIFAoXFx0aGV0YSkkIiwKICAgICJQcmlvciBiYXNhZG8gZW4gZGF0b3MgcHJldmlvcyAoZS5nLiwgJFxcdGhldGEgXFxzaW0gXFx0ZXh0e0JldGF9KDgwLDIwKSQpIiwKICAgICJQcmlvciBkw6liaWwgKGUuZy4sICRcXHRoZXRhIFxcc2ltIFxcdGV4dHtVbmlmb3JtfSgwLDEpJCkiLAogICAgIiRQKGEgXFxsZXEgXFx0aGV0YSBcXGxlcSBiIHwgRCkgPSAwLjk1JCIsCiAgICAiJFxcdGhldGFfaSBcXHNpbSBOKFxcbXUsIFxcdGF1XjIpJCwgJFlfe2lqfSBcXHNpbSBOKFxcdGhldGFfaSwgXFxzaWdtYV4yKSQiLAogICAgIk1ldHJvcG9saXMtSGFzdGluZ3MsIEdpYmJzIHNhbXBsaW5nIiwKICAgICJBTk9WQSBkZSB1biBmYWN0b3IgY29uIGFsZWF0b3JpemFjacOzbiBjb21wbGV0YSIsCiAgICAiQU5PVkEgY29uIGVmZWN0b3MgZGUgYmxvcXVlIiwKICAgICIkWV97aWprfSA9IFxcbXUgKyBcXGFscGhhX2kgKyBcXGJldGFfaiArIChcXGFscGhhXFxiZXRhKV97aWp9ICsgXFxlcHNpbG9uX3tpamt9JCIsCiAgICAiQ2FkYSBzdWpldG8gcmVjaWJlIHRvZG9zIGxvcyB0cmF0YW1pZW50b3MgZW4gb3JkZW4gYWxlYXRvcmlvIiwKICAgICJNZWRpZGFzIGVuIG3Dumx0aXBsZXMgdGllbXBvczogJFlfe2lqfSA9IFxcbXUgKyBcXGFscGhhX2kgKyBcXHBpX2ogKyBcXGVwc2lsb25fe2lqfSQiCiAgKSwKICAiQXBsaWNhY2nDs24gZW4gU2FsdWQiID0gYygKICAgICJBY3R1YWxpemFyIGVzdGltYWNpb25lcyBkZSBwcmV2YWxlbmNpYSBvIGVmZWN0aXZpZGFkIGNvbiBudWV2b3MgZGF0b3MiLAogICAgIlVzYXIgZGF0b3MgaGlzdMOzcmljb3MgZW4gZW5zYXlvcyBjbMOtbmljb3MiLAogICAgIkFuw6FsaXNpcyBleHBsb3JhdG9yaW8gc2luIHNlc2dvIHByZXZpbyIsCiAgICAiUmVwb3J0YXIgaW5jZXJ0aWR1bWJyZSBjb24gaW50ZXJwcmV0YWNpw7NuIGRpcmVjdGEgZGUgcHJvYmFiaWxpZGFkIiwKICAgICJFc3RpbWFyIHRhc2FzIGRlIGluZmVjY2nDs24gcG9yIGhvc3BpdGFsIGNvbiBkYXRvcyBsaW1pdGFkb3MiLAogICAgIk1vZGVsYXIgZWZlY3RpdmlkYWQgZGUgdHJhdGFtaWVudG9zIGNvbiBlc3RydWN0dXJhcyBjb21wbGVqYXMiLAogICAgIkVuc2F5b3MgY2zDrW5pY29zIHNpbXBsZXMgKGbDoXJtYWNvIHZzLiBwbGFjZWJvKSIsCiAgICAiQ29udHJvbGFyIGVkYWQsIHNleG8gdSBvdHJhcyBjb3ZhcmlhYmxlcyIsCiAgICAiRXZhbHVhciBjb21iaW5hY2lvbmVzIGRlIGbDoXJtYWNvcyB5IGRvc2lzIiwKICAgICJDb21wYXJhciB0cmF0YW1pZW50b3MgZW4gbG9zIG1pc21vcyBwYWNpZW50ZXMiLAogICAgIk1vbml0b3JlYXIgYmlvbWFyY2Fkb3JlcyBlbiBlbCB0aWVtcG8gKEhiQTFjLCBwcmVzacOzbiBhcnRlcmlhbCkiCiAgKSwKICAiRWplbXBsbyBQcsOhY3RpY28iID0gYygKICAgICJFc3RpbWFyIHByZXZhbGVuY2lhIGRlIGRpYWJldGVzIGFjdHVhbGl6YWRhOiAkXFx0aGV0YSBcXHNpbSBcXHRleHR7QmV0YX0oMjAsIDI4MCkkIiwKICAgICJQcmlvciAkXFx0ZXh0e0JldGF9KDgwLDIwKSQgcGFyYSBlZmljYWNpYSBkZSB2YWN1bmEiLAogICAgIlByaW9yICRcXHRleHR7QmV0YX0oMSwxKSQgcGFyYSB0YXNhIGRlIGhpcGVydGVuc2nDs24iLAogICAgIklDciA5NSU6IFswLjIxLCAwLjQwXSBwYXJhIHByb3BvcmNpw7NuIGRlIHJlc3BvbmRlZG9yZXMiLAogICAgIk1vZGVsbyBqZXLDoXJxdWljbyBtZWpvcmEgZXN0aW1hY2nDs24gZW4gaG9zcGl0YWxlcyBjb24gcG9jb3MgZGF0b3MiLAogICAgIk1DTUMgZXN0aW1hICRcXHRoZXRhID0gMC43NSQgY29uIElDciBbMC42OCwgMC44Ml0iLAogICAgIjEwMCBwYWNpZW50ZXMgYWxlYXRvcml6YWRvcyBhIGbDoXJtYWNvIEEgdnMuIHBsYWNlYm8iLAogICAgIkJsb3F1ZXMgcG9yIGVkYWQgKDw1MCwg4omlNTApIGVuIGVzdHVkaW8gZGUgaGlwZXJ0ZW5zacOzbiIsCiAgICAiRGlzZcOxbyAyeDM6IGbDoXJtYWNvIChBLEIpIHkgZG9zaXMgKGJhamEsIG1lZGlhLCBhbHRhKSIsCiAgICAiUGFjaWVudGVzIHJlY2liZW4gQSwgbHVlZ28gQiwgY29uIDIgc2VtYW5hcyBkZSBsYXZhZG8iLAogICAgIkdsdWNvc2EgbWVkaWRhIGEgMCwgMyB5IDYgbWVzZXMgZW4gcGFjaWVudGVzIGRpYWLDqXRpY29zIgogICksCiAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFCikKCiMgTW9zdHJhciB0YWJsYQprYWJsZSh0YWJsYV9iYXllc19kb2UsICJodG1sIiwgCiAgICAgIGNhcHRpb24gPSAiVGFibGEgNzogUmVzdW1lbiBkZSBpbmZlcmVuY2lhIGJheWVzaWFuYSB5IGRpc2XDsW8gZGUgZXhwZXJpbWVudG9zIGVuIHNhbHVkIikgJT4lCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiLCAicmVzcG9uc2l2ZSIpLCBmdWxsX3dpZHRoID0gRkFMU0UpICU+JQogIHNjcm9sbF9ib3god2lkdGggPSAiMTAwJSIsIGhlaWdodCA9ICI1MDBweCIpCmBgYAoKIyA4LiBEaXNlw7FvIGRlIEV4cGVyaW1lbnRvcyBwYXJhIGVsIFNlY3RvciBTYWx1ZAoKRWwgZGlzZcOxbyBkZSBleHBlcmltZW50b3MgKERPRSkgZXMgdW5hIGhlcnJhbWllbnRhIGVzZW5jaWFsIGVuCmVzdGFkw61zdGljYSBpbmZlcmVuY2lhbCBwYXJhIGVzdHJ1Y3R1cmFyIGVzdHVkaW9zIGNsw61uaWNvcyB5CmVwaWRlbWlvbMOzZ2ljb3MgcXVlIGdlbmVyZW4gcmVzdWx0YWRvcyB2w6FsaWRvcywgcmVwcm9kdWNpYmxlcyB5CsOpdGljYW1lbnRlIHPDs2xpZG9zIGVuIGVsIHNlY3RvciBzYWx1ZC4gRXN0ZSB0ZW1hcmlvIGRlc2Fycm9sbGEgbG9zCnByaW5jaXBpb3MsIGRpc2XDsW9zIGF2YW56YWRvcyB5IG3DqXRvZG9zIGRlIGFuw6FsaXNpcyBkZSBleHBlcmltZW50b3MsIGNvbgp1biBlbmZvcXVlIGVuIGFwbGljYWNpb25lcyBwcsOhY3RpY2FzIHBhcmEgcHJvZmVzaW9uYWxlcyBtw6lkaWNvcywKaW52ZXN0aWdhZG9yZXMgY2zDrW5pY29zIHkgZXBpZGVtacOzbG9nb3MuIEVsIERPRSBwZXJtaXRlIG9wdGltaXphciBsYQphc2lnbmFjacOzbiBkZSB0cmF0YW1pZW50b3MsIGNvbnRyb2xhciBzZXNnb3MgeSBtYXhpbWl6YXIgbGEgcG90ZW5jaWEKZXN0YWTDrXN0aWNhIGVuIGludmVzdGlnYWNpb25lcyBjb21vIGVuc2F5b3MgY2zDrW5pY29zLCBlc3R1ZGlvcyBkZQppbnRlcnZlbmNpw7NuIHkgZXZhbHVhY2lvbmVzIGRlIHBvbMOtdGljYXMgZGUgc2FsdWQgcMO6YmxpY2EuCgojIyA4LjEgUHJpbmNpcGlvcyBCw6FzaWNvcwoKIyMjIEFsZWF0b3JpemFjacOzbiwgUmVwbGljYWNpw7NuIHkgQmxvcXVlbwoKTG9zIHByaW5jaXBpb3MgZnVuZGFtZW50YWxlcyBkZWwgRE9FIGFzZWd1cmFuIGxhIHZhbGlkZXogaW50ZXJuYSB5CmV4dGVybmEgZGUgbG9zIGV4cGVyaW1lbnRvcywgbWluaW1pemFuZG8gc2VzZ29zIHkgYXVtZW50YW5kbyBsYQpwcmVjaXNpw7NuIGRlIGxhcyBlc3RpbWFjaW9uZXMuCgoqKkFsZWF0b3JpemFjacOzbjoqKgoKLSAgICoqRGVmaW5pY2nDs246KiogQXNpZ25hciBzdWpldG9zIGEgdHJhdGFtaWVudG9zIGRlIGZvcm1hIGFsZWF0b3JpYQogICAgcGFyYSBlbGltaW5hciBzZXNnb3MgZGUgc2VsZWNjacOzbiB5IGdhcmFudGl6YXIgcXVlIGxvcyBncnVwb3Mgc2VhbgogICAgY29tcGFyYWJsZXMgZW4gZmFjdG9yZXMgbm8gY29udHJvbGFkb3MuCi0gICAqKlByb3DDs3NpdG86KiogRGlzdHJpYnVpciBlcXVpdGF0aXZhbWVudGUgbGFzIGNhcmFjdGVyw61zdGljYXMgbm8KICAgIG1lZGlkYXMgKGUuZy4sIGdlbsOpdGljYSwgZXN0aWxvIGRlIHZpZGEpIGVudHJlIGdydXBvcy4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogRW4gdW4gZW5zYXlvIGNsw61uaWNvIHBhcmEgZXZhbHVhciB1biBudWV2bwogICAgYW50aWhpcGVydGVuc2l2bywgbG9zIHBhY2llbnRlcyBzZSBhc2lnbmFuIGFsZWF0b3JpYW1lbnRlIGEgZsOhcm1hY28KICAgIG8gcGxhY2VibyBwYXJhIGV2aXRhciBxdWUgZmFjdG9yZXMgY29tbyBsYSBlZGFkIG8gZWwgc2V4byBzZXNndWVuCiAgICBsb3MgcmVzdWx0YWRvcy4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogRW4gdW4gZXN0dWRpbyBjb24gMjAwIHBhY2llbnRlcywgc2UgdXNhIHVuCiAgICBnZW5lcmFkb3IgZGUgbsO6bWVyb3MgYWxlYXRvcmlvcyBwYXJhIGFzaWduYXIgMTAwIGFsIGdydXBvIGRlCiAgICB0cmF0YW1pZW50byB5IDEwMCBhbCBwbGFjZWJvLCBhc2VndXJhbmRvIHF1ZSBsYXMgZGlmZXJlbmNpYXMgZW4KICAgIHByZXNpw7NuIGFydGVyaWFsIHNlIGRlYmFuIGFsIGbDoXJtYWNvLgoKKipSZXBsaWNhY2nDs246KioKCi0gICAqKkRlZmluaWNpw7NuOioqIFJlcGV0aXIgZWwgZXhwZXJpbWVudG8gZW4gbcO6bHRpcGxlcyBzdWpldG9zIG8KICAgIHVuaWRhZGVzIHBvciB0cmF0YW1pZW50byBwYXJhIGVzdGltYXIgbGEgdmFyaWFiaWxpZGFkIHkgYXVtZW50YXIgbGEKICAgIHByZWNpc2nDs24uCi0gICAqKlByb3DDs3NpdG86KiogUHJvcG9yY2lvbmFyIGVzdGltYWNpb25lcyByb2J1c3RhcyBkZSBsb3MgZWZlY3RvcyBkZWwKICAgIHRyYXRhbWllbnRvIHkgcGVybWl0aXIgcHJ1ZWJhcyBkZSBoaXDDs3Rlc2lzIGVzdGFkw61zdGljYW1lbnRlCiAgICBwb3RlbnRlcy4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogSW5jbHVpciBzdWZpY2llbnRlcyBwYWNpZW50ZXMgcG9yIGdydXBvIGVuCiAgICB1biBlbnNheW8gY2zDrW5pY28gcGFyYSBkZXRlY3RhciBkaWZlcmVuY2lhcyBjbMOtbmljYW1lbnRlIHJlbGV2YW50ZXMKICAgIGVuIGJpb21hcmNhZG9yZXMgKGUuZy4sIGdsdWNvc2EgZW4gc2FuZ3JlKS4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogRW4gdW4gZW5zYXlvIHBhcmEgZXZhbHVhciB1biB0cmF0YW1pZW50byBkZQogICAgZGlhYmV0ZXMsIHNlIGluY2x1eWVuIDUwIHBhY2llbnRlcyBwb3IgZ3J1cG8gKHRyYXRhbWllbnRvIHZzLgogICAgY29udHJvbCkgcGFyYSBlc3RpbWFyIGxhIHZhcmlhbnphIGRlIEhiQTFjIHkgZGV0ZWN0YXIgdW5hIHJlZHVjY2nDs24KICAgIGRlIDAuNSUgY29uIHVuYSBwb3RlbmNpYSBkZWwgODAlLgoKKipCbG9xdWVvOioqCgotICAgKipEZWZpbmljacOzbjoqKiBBZ3J1cGFyIHN1amV0b3MgZW4gYmxvcXVlcyBob21vZ8OpbmVvcyBzZWfDum4gdW5hCiAgICB2YXJpYWJsZSBkZSBjb25mdXNpw7NuIChlLmcuLCBlZGFkLCBzZXhvKSB5IGFsZWF0b3JpemFyIGRlbnRybyBkZQogICAgY2FkYSBibG9xdWUuCi0gICAqKlByb3DDs3NpdG86KiogUmVkdWNpciBsYSB2YXJpYWJpbGlkYWQgbm8gZXhwbGljYWRhIHkgYXVtZW50YXIgbGEKICAgIHNlbnNpYmlsaWRhZCBwYXJhIGRldGVjdGFyIGVmZWN0b3MgZGVsIHRyYXRhbWllbnRvLgotICAgKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBFbiB1biBlc3R1ZGlvIGRlIG9iZXNpZGFkLCBsb3MgcGFjaWVudGVzIHNlCiAgICBkaXZpZGVuIGVuIGJsb3F1ZXMgcG9yIGfDqW5lcm8gKGhvbWJyZXMsIG11amVyZXMpIHkgc2UgYWxlYXRvcml6YW4gYQogICAgZGlldGEgbyBjb250cm9sIGRlbnRybyBkZSBjYWRhIGJsb3F1ZS4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogRW4gdW4gZW5zYXlvIGNsw61uaWNvIGRlIHVuIGbDoXJtYWNvIHBhcmEgZWwKICAgIGNvbGVzdGVyb2wsIHNlIGZvcm1hbiBibG9xdWVzIHBvciByYW5nbyBkZSBlZGFkIChcPDUwLCDiiaU1MCBhw7FvcykuCiAgICBEZW50cm8gZGUgY2FkYSBibG9xdWUsIGxvcyBwYWNpZW50ZXMgc2UgYXNpZ25hbiBhbGVhdG9yaWFtZW50ZSBhCiAgICB0cmVzIGRvc2lzIGRlbCBmw6FybWFjbywgcmVkdWNpZW5kbyBsYSB2YXJpYWJpbGlkYWQgZGViaWRhIGEgbGEgZWRhZC4KCiMjIyBEaXNlw7FvcyBDb21wbGV0YW1lbnRlIEFsZWF0b3JpemFkb3MKCioqRGVmaW5pY2nDs246KiogVW4gZGlzZcOxbyBjb21wbGV0YW1lbnRlIGFsZWF0b3JpemFkbyAoRENBKSBhc2lnbmEKc3VqZXRvcyBhIHRyYXRhbWllbnRvcyBkZSBmb3JtYSBhbGVhdG9yaWEgc2luIHJlc3RyaWNjaW9uZXMgYWRpY2lvbmFsZXMsCmFzdW1pZW5kbyBxdWUgbm8gaGF5IGZhY3RvcmVzIGRlIGNvbmZ1c2nDs24gaW1wb3J0YW50ZXMgcXVlIHJlcXVpZXJhbgpibG9xdWVvLgoKKipNb2RlbG86KiogJCQKWV97aWp9ID0gXG11ICsgXHRhdV9pICsgXGVwc2lsb25fe2lqfQokJCBEb25kZSAkWV97aWp9JCBlcyBsYSByZXNwdWVzdGEgZGVsIHN1amV0byAkaiQgZW4gZWwgdHJhdGFtaWVudG8gJGkkLAokXG11JCBlcyBsYSBtZWRpYSBnZW5lcmFsLCAkXHRhdV9pJCBlcyBlbCBlZmVjdG8gZGVsIHRyYXRhbWllbnRvICRpJCwgeQokXGVwc2lsb25fe2lqfSBcc2ltIE4oMCwgXHNpZ21hXjIpJCBlcyBlbCBlcnJvci4KCioqU3VwdWVzdG9zOioqCgotICAgTm9ybWFsaWRhZCBkZSBsb3MgZXJyb3Jlcy4KLSAgIEhvbW9nZW5laWRhZCBkZSB2YXJpYW56YXMgZW50cmUgZ3J1cG9zLgotICAgSW5kZXBlbmRlbmNpYSBkZSBsYXMgb2JzZXJ2YWNpb25lcy4KCioqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogQ29tcGFyYXIgbGEgZWZpY2FjaWEgZGUgZG9zIHRyYXRhbWllbnRvcyAoZS5nLiwKaW5zdWxpbmEgdnMuIG1ldGZvcm1pbmEpIGVuIHBhY2llbnRlcyBkaWFiw6l0aWNvcyBhc2lnbmFkb3MKYWxlYXRvcmlhbWVudGUuCgoqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuIGVuc2F5byBjb24gMTUwIHBhY2llbnRlcywgNTAgc2UgYXNpZ25hbgphbGVhdG9yaWFtZW50ZSBhIG1ldGZvcm1pbmEsIDUwIGEgaW5zdWxpbmEgeSA1MCBhIHBsYWNlYm8uIExhIHZhcmlhYmxlCnJlc3B1ZXN0YSBlcyBlbCBuaXZlbCBkZSBIYkExYy4gVW4gQU5PVkEgZGUgdW4gZmFjdG9yIGFuYWxpemEgbGFzCmRpZmVyZW5jaWFzIGVudHJlIGxhcyBtZWRpYXMgZGUgbG9zIGdydXBvcywgbW9zdHJhbmRvIHVuIHZhbG9yIHAgXDwKMC4wNSwgbG8gcXVlIGluZGljYSBkaWZlcmVuY2lhcyBzaWduaWZpY2F0aXZhcy4KCiMjIDguMiBEaXNlw7FvcyBBdmFuemFkb3MKCiMjIyBEaXNlw7FvcyBkZSBCbG9xdWVzIEluY29tcGxldG9zCgpMb3MgZGlzZcOxb3MgZGUgYmxvcXVlcyBpbmNvbXBsZXRvcyAoREJJKSBzZSB1dGlsaXphbiBjdWFuZG8gbm8gZXMKcG9zaWJsZSBpbmNsdWlyIHRvZG9zIGxvcyB0cmF0YW1pZW50b3MgZW4gY2FkYSBibG9xdWUgZGViaWRvIGEKbGltaXRhY2lvbmVzIHByw6FjdGljYXMgKGUuZy4sIHJlY3Vyc29zLCBuw7ptZXJvIGRlIHBhY2llbnRlcykuCgoqKkRlZmluaWNpw7NuOioqIENhZGEgYmxvcXVlIGNvbnRpZW5lIHVuIHN1YmNvbmp1bnRvIGRlIGxvcyB0cmF0YW1pZW50b3MsCnkgbGEgYXNpZ25hY2nDs24gZXMgYWxlYXRvcmlhIGRlbnRybyBkZSBsb3MgYmxvcXVlcy4gTG9zIGRpc2XDsW9zCmJhbGFuY2VhZG9zIChCSUJELCBiYWxhbmNlZCBpbmNvbXBsZXRlIGJsb2NrIGRlc2lnbnMpIGFzZWd1cmFuIHF1ZSBjYWRhCnRyYXRhbWllbnRvIGFwYXJlemNhIGVsIG1pc21vIG7Dum1lcm8gZGUgdmVjZXMgeSBjYWRhIHBhciBkZSB0cmF0YW1pZW50b3MKc2UgY29tcGFyZSBlbiBlbCBtaXNtbyBuw7ptZXJvIGRlIGJsb3F1ZXMuCgoqKlZlbnRhamFzOioqCgotICAgUmVkdWNlbiBlbCB0YW1hw7FvIGRlIGxvcyBibG9xdWVzLCBmYWNpbGl0YW5kbyBlc3R1ZGlvcyBjb24gbXVjaG9zCiAgICB0cmF0YW1pZW50b3MuCi0gICBDb250cm9sYW4gbGEgdmFyaWFiaWxpZGFkIGRlIGZhY3RvcmVzIGRlIGNvbmZ1c2nDs24gKGUuZy4sIGhvc3BpdGFsLAogICAgc2V2ZXJpZGFkIGRlIGxhIGVuZmVybWVkYWQpLgoKKipNb2RlbG86KiogJCQKWV97aWprfSA9IFxtdSArIFx0YXVfaSArIFxiZXRhX2ogKyBcZXBzaWxvbl97aWprfQokJCBEb25kZSAkXHRhdV9pJCBlcyBlbCBlZmVjdG8gZGVsIHRyYXRhbWllbnRvICRpJCwgJFxiZXRhX2okIGVzIGVsCmVmZWN0byBkZWwgYmxvcXVlICRqJCwgeSAkXGVwc2lsb25fe2lqa30kIGVzIGVsIGVycm9yLgoKKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBDb21wYXJhciBjaW5jbyB0cmF0YW1pZW50b3MgcGFyYSBsYQpoaXBlcnRlbnNpw7NuIGVuIGhvc3BpdGFsZXMgY29uIGNhcGFjaWRhZCBsaW1pdGFkYSwgYXNpZ25hbmRvIHNvbG8gdHJlcwp0cmF0YW1pZW50b3MgcG9yIGhvc3BpdGFsIChibG9xdWUpLgoKKipFamVtcGxvIHByw6FjdGljbzoqKiBFbiB1biBlc3R1ZGlvIGNvbiBjaW5jbyB0cmF0YW1pZW50b3MKYW50aWhpcGVydGVuc2l2b3MgKEEsIEIsIEMsIEQsIEUpIHkgY3VhdHJvIGhvc3BpdGFsZXMgY29tbyBibG9xdWVzLCBjYWRhCmhvc3BpdGFsIHBydWViYSB0cmVzIHRyYXRhbWllbnRvcy4gVW4gQklCRCBhc2VndXJhIHF1ZSBjYWRhIHRyYXRhbWllbnRvCnNlIGV2YWzDumEgZW4gZG9zIGhvc3BpdGFsZXMsIHkgdW4gQU5PVkEgYWp1c3RhZG8gYW5hbGl6YSBsYXMgZGlmZXJlbmNpYXMKZW4gbGEgcHJlc2nDs24gYXJ0ZXJpYWwsIGNvbnRyb2xhbmRvIGVsIGVmZWN0byBkZWwgaG9zcGl0YWwuCgojIyMgRGlzZcOxb3MgRmFjdG9yaWFsZXMgRnJhY2Npb25hZG9zCgpMb3MgZGlzZcOxb3MgZmFjdG9yaWFsZXMgZnJhY2Npb25hZG9zIGV2YWzDumFuIG3Dumx0aXBsZXMgZmFjdG9yZXMgKGUuZy4sCnRyYXRhbWllbnRvLCBkb3NpcywgZGlldGEpIHVzYW5kbyB1biBzdWJjb25qdW50byBkZSB0b2RhcyBsYXMKY29tYmluYWNpb25lcyBwb3NpYmxlcywgcmVkdWNpZW5kbyBlbCBuw7ptZXJvIGRlIGNvcnJpZGFzIGV4cGVyaW1lbnRhbGVzLgoKKipEZWZpbmljacOzbjoqKiBFbiB1biBkaXNlw7FvIGZhY3RvcmlhbCBjb21wbGV0byAkMl5rJCwgc2UgZXZhbMO6YW4gdG9kYXMKbGFzIGNvbWJpbmFjaW9uZXMgZGUgJGskIGZhY3RvcmVzIGNvbiBkb3Mgbml2ZWxlcyAoZS5nLiwgYWx0by9iYWpvKS4gVW4KZGlzZcOxbyBmcmFjY2lvbmFkbyAoZS5nLiwgJDJee2stcH0kKSB1c2EgJDJee2stcH0kIGNvbWJpbmFjaW9uZXMsCnNhY3JpZmljYW5kbyBpbmZvcm1hY2nDs24gc29icmUgaW50ZXJhY2Npb25lcyBkZSBvcmRlbiBzdXBlcmlvciBwYXJhCnJlZHVjaXIgY29zdG9zLgoKKipWZW50YWphczoqKgoKLSAgIEVmaWNpZW50ZSBwYXJhIGVzdHVkaW9zIGNvbiBtdWNob3MgZmFjdG9yZXMuCi0gICBQZXJtaXRlIGV2YWx1YXIgZWZlY3RvcyBwcmluY2lwYWxlcyBlIGludGVyYWNjaW9uZXMgZGUgYmFqbyBvcmRlbi4KCioqUmVzb2x1Y2nDs246KiogSW5kaWNhIHF1w6kgaW50ZXJhY2Npb25lcyBzZSBjb25mdW5kZW46CgotICAgKipSZXNvbHVjacOzbiBJSUk6KiogRWZlY3RvcyBwcmluY2lwYWxlcyBjb25mdW5kaWRvcyBjb24KICAgIGludGVyYWNjaW9uZXMgZGUgZG9zIHbDrWFzLgotICAgKipSZXNvbHVjacOzbiBJVjoqKiBFZmVjdG9zIHByaW5jaXBhbGVzIG5vIGNvbmZ1bmRpZG9zIGNvbgogICAgaW50ZXJhY2Npb25lcyBkZSBkb3MgdsOtYXMsIHBlcm8gZXN0YXMgc2UgY29uZnVuZGVuIGVudHJlIHPDrS4KLSAgICoqUmVzb2x1Y2nDs24gVjoqKiBFZmVjdG9zIHByaW5jaXBhbGVzIHkgZGUgZG9zIHbDrWFzIG5vIGNvbmZ1bmRpZG9zLgoKKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBFdmFsdWFyIGVsIGVmZWN0byBkZSB1biBmw6FybWFjbyAoc8OtL25vKSwgZG9zaXMKKGJhamEvYWx0YSkgeSBkaWV0YSAoYmFqYSBlbiBzYWwvZXN0w6FuZGFyKSBlbiBsYSBwcmVzacOzbiBhcnRlcmlhbCwKdXNhbmRvIHVuIGRpc2XDsW8gZnJhY2Npb25hZG8gJDJeezMtMX0kICg0IGNvbWJpbmFjaW9uZXMgZW4gbHVnYXIgZGUgOCkuCgoqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuIGVzdHVkaW8gZmFjdG9yaWFsIGZyYWNjaW9uYWRvICQyXnszLTF9JCwgc2UKZXZhbMO6YW4gdHJlcyBmYWN0b3JlczogZsOhcm1hY28gKEE6IHPDrS9ubyksIGRvc2lzIChCOiBiYWphL2FsdGEpLCB5CmVqZXJjaWNpbyAoQzogc8OtL25vKS4gU2Ugc2VsZWNjaW9uYW4gNCBjb21iaW5hY2lvbmVzIChlLmcuLApBLW5vL0ItYmFqYS9DLW5vLCBBLXPDrS9CLWJhamEvQy1zw60sIGV0Yy4pLiBFbCBBTk9WQSBtdWVzdHJhIHVuIGVmZWN0bwpwcmluY2lwYWwgc2lnbmlmaWNhdGl2byBwYXJhIGVsIGbDoXJtYWNvICgkcCA9IDAuMDEkKSB5IHVuYSBpbnRlcmFjY2nDs24KZsOhcm1hY28tZG9zaXMgKCRwID0gMC4wMyQpLgoKIyMgOC4zIEFuw6FsaXNpcyBkZSBFeHBlcmltZW50b3MKCiMjIyBJbnRlcnByZXRhY2nDs24gZGUgSW50ZXJhY2Npb25lcwoKTGFzIGludGVyYWNjaW9uZXMgb2N1cnJlbiBjdWFuZG8gZWwgZWZlY3RvIGRlIHVuIGZhY3RvciBkZXBlbmRlIGRlbApuaXZlbCBkZSBvdHJvIGZhY3Rvciwgc2llbmRvIGNydWNpYWxlcyBlbiBlc3R1ZGlvcyBkZSBzYWx1ZCBwYXJhCmVudGVuZGVyIGVmZWN0b3MgY29tYmluYWRvcy4KCioqRGVmaW5pY2nDs246KiogRW4gdW4gZGlzZcOxbyBmYWN0b3JpYWwsIHVuYSBpbnRlcmFjY2nDs24gJEFCJCBpbmRpY2EgcXVlCmVsIGVmZWN0byBkZWwgZmFjdG9yIEEgKGUuZy4sIHRyYXRhbWllbnRvKSB2YXLDrWEgc2Vnw7puIGxvcyBuaXZlbGVzIGRlbApmYWN0b3IgQiAoZS5nLiwgZWRhZCkuCgoqKlZpc3VhbGl6YWNpw7NuOioqCgotICAgKipHcsOhZmljb3MgZGUgaW50ZXJhY2Npw7NuOioqIEzDrW5lYXMgbm8gcGFyYWxlbGFzIGVuIHVuIGdyw6FmaWNvIGRlCiAgICBtZWRpYXMgaW5kaWNhbiBpbnRlcmFjY2nDs24uCi0gICAqKlRhYmxhIEFOT1ZBOioqIEVsIHTDqXJtaW5vIGRlIGludGVyYWNjacOzbiAoJEFCJCkgc2UgZXZhbMO6YSBjb24gdW4KICAgIGVzdGFkw61zdGljbyBGLgoKKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBFdmFsdWFyIHNpIGVsIGVmZWN0byBkZSB1biB0cmF0YW1pZW50byBwYXJhIGxhCmRpYWJldGVzIHZhcsOtYSBzZWfDum4gZWwgZ3J1cG8gZGUgZWRhZCAoasOzdmVuZXMgdnMuIGFkdWx0b3MgbWF5b3JlcykuCgoqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuIGRpc2XDsW8gZmFjdG9yaWFsIDJ4MiAodHJhdGFtaWVudG86IGbDoXJtYWNvCnZzLiBwbGFjZWJvOyBlZGFkOiBcPDUwIHZzLiDiiaU1MCBhw7FvcyksIGVsIEFOT1ZBIG11ZXN0cmEgdW5hIGludGVyYWNjacOzbgpzaWduaWZpY2F0aXZhICgkcCA9IDAuMDIkKS4gVW4gZ3LDoWZpY28gZGUgaW50ZXJhY2Npw7NuIHJldmVsYSBxdWUgZWwKZsOhcm1hY28gcmVkdWNlIGxhIGdsdWNvc2EgbcOhcyBlbiBwYWNpZW50ZXMg4omlNTAgYcOxb3MgKGRpZmVyZW5jaWEgZGUgMjAKbWcvZEwpIHF1ZSBlbiBcPDUwIGHDsW9zICgxMCBtZy9kTCkuIEVzdG8gc3VnaWVyZSBhanVzdGFyIGxhcwpyZWNvbWVuZGFjaW9uZXMgY2zDrW5pY2FzIHBvciBlZGFkLgoKIyMjIEFuw6FsaXNpcyBkZSBDb3ZhcmlhbnphIChBTkNPVkEpCgpFbCBhbsOhbGlzaXMgZGUgY292YXJpYW56YSAoQU5DT1ZBKSBjb21iaW5hIEFOT1ZBIGNvbiByZWdyZXNpw7NuIHBhcmEKYWp1c3RhciBlbCBlZmVjdG8gZGUgdW5hIHZhcmlhYmxlIGNvbnRpbnVhIChjb3ZhcmlhYmxlKSBxdWUgaW5mbHV5ZSBlbgpsYSB2YXJpYWJsZSBkZXBlbmRpZW50ZS4KCioqTW9kZWxvOioqICQkCllfe2lqfSA9IFxtdSArIFx0YXVfaSArIFxiZXRhIChYX3tpan0gLSBcYmFye1h9KSArIFxlcHNpbG9uX3tpan0KJCQgRG9uZGUgJFx0YXVfaSQgZXMgZWwgZWZlY3RvIGRlbCB0cmF0YW1pZW50byAkaSQsICRYX3tpan0kIGVzIGxhCmNvdmFyaWFibGUgKGUuZy4sIElNQyBiYXNhbCksICRcYmV0YSQgZXMgbGEgcGVuZGllbnRlIGRlIGxhIGNvdmFyaWFibGUsCnkgJFxlcHNpbG9uX3tpan0kIGVzIGVsIGVycm9yLgoKKipTdXB1ZXN0b3M6KioKCi0gICBMaW5lYWxpZGFkIGVudHJlIGxhIGNvdmFyaWFibGUgeSBsYSB2YXJpYWJsZSBkZXBlbmRpZW50ZS4KLSAgIEhvbW9nZW5laWRhZCBkZSBwZW5kaWVudGVzOiBFbCBlZmVjdG8gZGUgbGEgY292YXJpYWJsZSBlcyBlbCBtaXNtbwogICAgZW4gdG9kb3MgbG9zIGdydXBvcy4KLSAgIE5vcm1hbGlkYWQgeSBob21vY2VkYXN0aWNpZGFkIGRlIGxvcyBlcnJvcmVzLgoKKipWZW50YWphczoqKgoKLSAgIEF1bWVudGEgbGEgcHJlY2lzacOzbiBhbCByZWR1Y2lyIGxhIHZhcmlhYmlsaWRhZCBubyBleHBsaWNhZGEuCi0gICBDb250cm9sYSBmYWN0b3JlcyBkZSBjb25mdXNpw7NuIGNvbnRpbnVvcy4KCioqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogQ29tcGFyYXIgbGEgZWZpY2FjaWEgZGUgZG9zIHRyYXRhbWllbnRvcyBlbiBsYQpyZWR1Y2Npw7NuIGRlIGNvbGVzdGVyb2wsIGFqdXN0YW5kbyBwb3IgZWwgY29sZXN0ZXJvbCBiYXNhbCAoY292YXJpYWJsZSkuCgoqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuIGVuc2F5byBjb24gZG9zIHRyYXRhbWllbnRvcyAoZsOhcm1hY28gQSB2cy4KQikgeSBjb2xlc3Rlcm9sIGJhc2FsIGNvbW8gY292YXJpYWJsZSwgQU5DT1ZBIG11ZXN0cmEgdW4gZWZlY3RvCnNpZ25pZmljYXRpdm8gZGVsIHRyYXRhbWllbnRvICgkcCA9IDAuMDEkKSB0cmFzIGFqdXN0YXIgcG9yIGNvbGVzdGVyb2wKYmFzYWwgKCRcYmV0YSA9IDAuOCQsICRwIDwgMC4wMDEkKS4gRWwgZsOhcm1hY28gQSByZWR1Y2UgZWwgY29sZXN0ZXJvbCA1Cm1nL2RMIG3DoXMgcXVlIEIsIGFqdXN0YWRvIHBvciBsYSBjb3ZhcmlhYmxlLgoKIyMgUmVjdXJzb3MgcGFyYSBlbCBBdXRvZXN0dWRpbyBlbiBTYWx1ZAoKIyMjIExlY3R1cmFzOgoKLSAgICJEZXNpZ24gYW5kIEFuYWx5c2lzIG9mIEV4cGVyaW1lbnRzIiBkZSBNb250Z29tZXJ5IChDYXDDrXR1bG9zIHNvYnJlCiAgICBET0UsIGJsb3F1ZXMgaW5jb21wbGV0b3MsIGZhY3RvcmlhbGVzIGZyYWNjaW9uYWRvcykuCi0gICAiQmlvc3RhdGlzdGljczogQSBGb3VuZGF0aW9uIGZvciBBbmFseXNpcyBpbiB0aGUgSGVhbHRoIFNjaWVuY2VzIiBkZQogICAgRGFuaWVsIChDYXDDrXR1bG9zIHNvYnJlIERPRSB5IEFOQ09WQSkuCi0gICAiRGVzaWduIG9mIEV4cGVyaW1lbnRzIGZvciB0aGUgSGVhbHRoIFNjaWVuY2VzIiBkZSBMYXdzb24gKGVuZm9xdWUKICAgIGVuIGFwbGljYWNpb25lcyBtw6lkaWNhcykuCgojIyMgRWplcmNpY2lvcyBwcsOhY3RpY29zOgoKLSAgIERpc2XDsWFyIHVuIGVuc2F5byBjb21wbGV0YW1lbnRlIGFsZWF0b3JpemFkbyBwYXJhIGNvbXBhcmFyIHRyZXMKICAgIHRyYXRhbWllbnRvcyBhbnRpaGlwZXJ0ZW5zaXZvcywgYW5hbGl6YW5kbyBjb24gQU5PVkEuCi0gICBJbXBsZW1lbnRhciB1biBkaXNlw7FvIGRlIGJsb3F1ZXMgaW5jb21wbGV0b3MgcGFyYSBldmFsdWFyIGNpbmNvCiAgICBpbnRlcnZlbmNpb25lcyBlbiBjdWF0cm8gaG9zcGl0YWxlcy4KLSAgIFJlYWxpemFyIHVuIGRpc2XDsW8gZmFjdG9yaWFsIGZyYWNjaW9uYWRvICQyXnszLTF9JCBwYXJhIGVzdHVkaWFyCiAgICB0cmF0YW1pZW50bywgZG9zaXMgeSBkaWV0YSwgaW50ZXJwcmV0YW5kbyBpbnRlcmFjY2lvbmVzLgotICAgQXBsaWNhciBBTkNPVkEgYSBkYXRvcyBkZSBlbnNheW9zIGNsw61uaWNvcywgYWp1c3RhbmRvIHBvcgogICAgY292YXJpYWJsZXMgY29tbyBlZGFkIG8gYmlvbWFyY2Fkb3JlcyBiYXNhbGVzLgoKIyMjIEhlcnJhbWllbnRhcyBjb21wdXRhY2lvbmFsZXM6CgotICAgKipSOioqIFBhcXVldGVzIGBzdGF0c2AgKGFvdiwgbG0gcGFyYSBBTkNPVkEpLCBgYWdyaWNvbGFlYCAoZGlzZcOxb3MKICAgIGRlIGJsb3F1ZXMpLCBgRnJGMmAgKGZhY3RvcmlhbGVzIGZyYWNjaW9uYWRvcykuCiAgICAtICAgKipFamVtcGxvOioqIGBhb3YoeSB+IHRyYXRhbWllbnRvICogZWRhZCwgZGF0YT1kYXRvcylgIHBhcmEKICAgICAgICBBTk9WQSBjb24gaW50ZXJhY2Npw7NuOwogICAgICAgIGBsbSh5IH4gdHJhdGFtaWVudG8gKyBjb2xlc3Rlcm9sX2Jhc2FsLCBkYXRhPWRhdG9zKWAgcGFyYQogICAgICAgIEFOQ09WQS4KLSAgICoqUHl0aG9uOioqIExpYnJlcsOtYXMgYHN0YXRzbW9kZWxzYCAoYHN0YXRzbW9kZWxzLmZvcm11bGEuYXBpLm9sc2AKICAgIHBhcmEgQU5PVkEvQU5DT1ZBKSwgYHB5RE9FMmAgKGRpc2XDsW9zIGZhY3RvcmlhbGVzKS4KICAgIC0gICAqKkVqZW1wbG86KioKICAgICAgICBgc21mLm9scygnY29sZXN0ZXJvbCB+IHRyYXRhbWllbnRvICsgY29sZXN0ZXJvbF9iYXNhbCcsIGRhdGE9ZGF0b3MpLmZpdCgpYAogICAgICAgIHBhcmEgQU5DT1ZBLgoKIyMjIEJhc2VzIGRlIGRhdG9zOgoKLSAgIE5IQU5FUyBwYXJhIGRhdG9zIGRlIGJpb21hcmNhZG9yZXMgKGUuZy4sIGNvbGVzdGVyb2wsIGdsdWNvc2EpLgotICAgQ2xpbmljYWxUcmlhbHMuZ292IHBhcmEgZGF0b3MgZGUgZW5zYXlvcyBjbMOtbmljb3MuCi0gICBEYXRhc2V0cyBkZSBsYSBPTVMgcGFyYSBlc3R1ZGlvcyBlcGlkZW1pb2zDs2dpY29zIChlLmcuLCB0YXNhcyBkZQogICAgaGlwZXJ0ZW5zacOzbikuCgojIFRhYmxhIFJlc3VtZW46IERpc2XDsW8gZGUgRXhwZXJpbWVudG9zIGVuIGVsIFNlY3RvciBTYWx1ZAoKYGBge3IgZG9lLXRhYmxlLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdhc2lzJywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShrbml0cikKbGlicmFyeShrYWJsZUV4dHJhKQoKIyBDcmVhciBsYSB0YWJsYSBjb24gZG9ibGUgYmFycmEgaW52ZXJ0aWRhIChcXCkgcGFyYSBmw7NybXVsYXMgTGFUZVgKdGFibGFfZG9lIDwtIGRhdGEuZnJhbWUoCiAgIkRpc2XDsW8gbyBUw6ljbmljYSIgPSBjKAogICAgIkRpc2XDsW8gQ29tcGxldGFtZW50ZSBBbGVhdG9yaXphZG8gKERDQSkiLAogICAgIkRpc2XDsW8gZGUgQmxvcXVlcyBBbGVhdG9yaXphZG9zIiwKICAgICJEaXNlw7FvIGRlIEJsb3F1ZXMgSW5jb21wbGV0b3MgKEJJQkQpIiwKICAgICJEaXNlw7FvIEZhY3RvcmlhbCBDb21wbGV0byAoMl5rKSIsCiAgICAiRGlzZcOxbyBGYWN0b3JpYWwgRnJhY2Npb25hZG8gKDJee2stcH0pIiwKICAgICJBbsOhbGlzaXMgZGUgQ292YXJpYW56YSAoQU5DT1ZBKSIKICApLAogICJUaXBvIGRlIEFuw6FsaXNpcyIgPSBjKAogICAgIkNvbXBhcmFjacOzbiBkZSB0cmF0YW1pZW50b3MiLAogICAgIkNvbnRyb2wgZGUgY29uZnVzb3JlcyBwb3IgYmxvcXVlbyIsCiAgICAiRXZhbHVhY2nDs24gZGUgbcO6bHRpcGxlcyB0cmF0YW1pZW50b3MgY29uIGJsb3F1ZXMgbGltaXRhZG9zIiwKICAgICJFdmFsdWFjacOzbiBkZSBlZmVjdG9zIHByaW5jaXBhbGVzIGUgaW50ZXJhY2Npb25lcyIsCiAgICAiUmVkdWNjacOzbiBkZSBjb3JyaWRhcyBleHBlcmltZW50YWxlcyIsCiAgICAiQWp1c3RlIHBvciBjb3ZhcmlhYmxlcyBjb250aW51YXMiCiAgKSwKICAiU3VwdWVzdG9zIENsYXZlIiA9IGMoCiAgICAiTm9ybWFsaWRhZCwgaG9tb2NlZGFzdGljaWRhZCwgaW5kZXBlbmRlbmNpYSIsCiAgICAiSG9tb2dlbmVpZGFkIGRlbnRybyBkZSBibG9xdWVzLCBub3JtYWxpZGFkIiwKICAgICJCYWxhbmNlbyBwYXJjaWFsLCBub3JtYWxpZGFkLCBpbmRlcGVuZGVuY2lhIiwKICAgICJOb3JtYWxpZGFkLCBob21vY2VkYXN0aWNpZGFkLCBpbmRlcGVuZGVuY2lhIiwKICAgICJSZXNvbHVjacOzbiBhZGVjdWFkYSwgbGluZWFsaWRhZCwgYmFqbyBvcmRlbiBkZSBpbnRlcmFjY2lvbmVzIiwKICAgICJMaW5lYWxpZGFkLCBob21vZ2VuZWlkYWQgZGUgcGVuZGllbnRlcywgbm9ybWFsaWRhZCIKICApLAogICJNb2RlbG8gRXN0YWTDrXN0aWNvIiA9IGMoCiAgICAiJFlfe2lqfSA9IFxcbXUgKyBcXHRhdV9pICsgXFxlcHNpbG9uX3tpan0kIiwKICAgICIkWV97aWp9ID0gXFxtdSArIFxcdGF1X2kgKyBcXGJldGFfaiArIFxcZXBzaWxvbl97aWp9JCIsCiAgICAiJFlfe2lqa30gPSBcXG11ICsgXFx0YXVfaSArIFxcYmV0YV9qICsgXFxlcHNpbG9uX3tpamt9JCIsCiAgICAiJFlfe2lqa30gPSBcXG11ICsgXFxhbHBoYV9pICsgXFxiZXRhX2ogKyAoXFxhbHBoYVxcYmV0YSlfe2lqfSArIFxcZXBzaWxvbl97aWprfSQiLAogICAgIiRZID0gXFxtdSArIFxcdGV4dHtlZmVjdG9zIHByaW5jaXBhbGVzfSArIFxcdGV4dHtpbnRlcmFjY2lvbmVzIGRlIGJham8gb3JkZW59JCIsCiAgICAiJFlfe2lqfSA9IFxcbXUgKyBcXHRhdV9pICsgXFxiZXRhIChYX3tpan0gLSBcXGJhcntYfSkgKyBcXGVwc2lsb25fe2lqfSQiCiAgKSwKICAiQXBsaWNhY2nDs24gZW4gU2FsdWQiID0gYygKICAgICJDb21wYXJhciBlZmljYWNpYSBkZSB0cmF0YW1pZW50b3MgKGUuZy4sIGbDoXJtYWNvcyB2cy4gcGxhY2VibykiLAogICAgIkNvbnRyb2xhciBlZGFkLCBzZXhvIG8gaG9zcGl0YWwgZW4gZXN0dWRpb3MgY2zDrW5pY29zIiwKICAgICJFdmFsdWFyIG3Dumx0aXBsZXMgdHJhdGFtaWVudG9zIGVuIGhvc3BpdGFsZXMgY29uIGNhcGFjaWRhZCBsaW1pdGFkYSIsCiAgICAiRXN0dWRpYXIgZWZlY3RvcyBjb21iaW5hZG9zIGRlIGbDoXJtYWNvLCBkb3NpcyB5IGRpZXRhIiwKICAgICJSZWR1Y2lyIGNvc3RvcyBlbiBlc3R1ZGlvcyBjb24gbXVjaG9zIGZhY3RvcmVzIChlLmcuLCBpbnRlcnZlbmNpb25lcyBtw7psdGlwbGVzKSIsCiAgICAiQWp1c3RhciBwb3IgYmlvbWFyY2Fkb3JlcyBiYXNhbGVzIChlLmcuLCBjb2xlc3Rlcm9sLCBJTUMpIgogICksCiAgIkVqZW1wbG8gUHLDoWN0aWNvIiA9IGMoCiAgICAiMTUwIHBhY2llbnRlcyBhc2lnbmFkb3MgYSBtZXRmb3JtaW5hLCBpbnN1bGluYSBvIHBsYWNlYm87IEFOT1ZBIG11ZXN0cmEgZGlmZXJlbmNpYXMgZW4gSGJBMWMiLAogICAgIkJsb3F1ZXMgcG9yIGVkYWQgKDw1MCwg4omlNTApOyBhbGVhdG9yaXphY2nDs24gZGVudHJvIGRlIGJsb3F1ZXMgcGFyYSBjb250cm9sYXIgY29uZnVzacOzbiIsCiAgICAiNSB0cmF0YW1pZW50b3MgYW50aWhpcGVydGVuc2l2b3MgZXZhbHVhZG9zIGVuIDQgaG9zcGl0YWxlczsgMyBwb3IgaG9zcGl0YWw7IEFOT1ZBIGFqdXN0YWRvIiwKICAgICJGYWN0b3JpYWwgMngyeDI6IGbDoXJtYWNvLCBkb3NpcywgZGlldGE7IHNlIGFuYWxpemFuIGVmZWN0b3MgZSBpbnRlcmFjY2lvbmVzIiwKICAgICJEaXNlw7FvICQyXnszLTF9JDogNCBjb21iaW5hY2lvbmVzIHBhcmEgMyBmYWN0b3Jlczsgc2UgZGV0ZWN0YSBpbnRlcmFjY2nDs24gZsOhcm1hY28tZG9zaXMiLAogICAgIkFOQ09WQSBhanVzdGEgcmVkdWNjacOzbiBkZSBjb2xlc3Rlcm9sIHBvciB0cmF0YW1pZW50bywgY29udHJvbGFuZG8gY29sZXN0ZXJvbCBiYXNhbCIKICApLAogIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRQopCgojIE1vc3RyYXIgdGFibGEKa2FibGUodGFibGFfZG9lLCAiaHRtbCIsIAogICAgICBjYXB0aW9uID0gIlRhYmxhIDg6IFJlc3VtZW4gZGUgZGlzZcOxb3MgZGUgZXhwZXJpbWVudG9zIGFwbGljYWRvcyBhbCBzZWN0b3Igc2FsdWQiKSAlPiUKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJyZXNwb25zaXZlIiksIGZ1bGxfd2lkdGggPSBGQUxTRSkgJT4lCiAgc2Nyb2xsX2JveCh3aWR0aCA9ICIxMDAlIiwgaGVpZ2h0ID0gIjUwMHB4IikKCmBgYAoKIyA5LiBBbsOhbGlzaXMgZGUgU2VyaWVzIFRlbXBvcmFsZXMgcGFyYSBlbCBTZWN0b3IgU2FsdWQKCkVsIGFuw6FsaXNpcyBkZSBzZXJpZXMgdGVtcG9yYWxlcyBlcyB1bmEgaGVycmFtaWVudGEgY2xhdmUgZW4gZXN0YWTDrXN0aWNhCmluZmVyZW5jaWFsIHBhcmEgbW9kZWxhciB5IHByZWRlY2lyIGRhdG9zIHNlY3VlbmNpYWxlcyBlbiBlbCB0aWVtcG8sCnNpZW5kbyBlc3BlY2lhbG1lbnRlIHJlbGV2YW50ZSBlbiBlbCBzZWN0b3Igc2FsdWQgcGFyYSBtb25pdG9yZWFyCnRlbmRlbmNpYXMgZXBpZGVtaW9sw7NnaWNhcywgcHJlZGVjaXIgYnJvdGVzIGRlIGVuZmVybWVkYWRlcywgZXZhbHVhcgppbnRlcnZlbmNpb25lcyBjbMOtbmljYXMgeSBnZXN0aW9uYXIgcmVjdXJzb3MgaG9zcGl0YWxhcmlvcy4gRXN0ZSB0ZW1hcmlvCmRlc2Fycm9sbGEgbG9zIGNvbXBvbmVudGVzIGRlIGxhcyBzZXJpZXMgdGVtcG9yYWxlcywgbG9zIG1vZGVsb3MgQVJJTUEgeQpsb3MgbW9kZWxvcyBhdmFuemFkb3MsIGNvbiB1biBlbmZvcXVlIGVuIGFwbGljYWNpb25lcyBwcsOhY3RpY2FzIHBhcmEKcHJvZmVzaW9uYWxlcyBtw6lkaWNvcywgaW52ZXN0aWdhZG9yZXMgY2zDrW5pY29zIHkgZXBpZGVtacOzbG9nb3MuCgojIyA5LjEgQ29tcG9uZW50ZXMgZGUgU2VyaWVzIFRlbXBvcmFsZXMKCiMjIyBUZW5kZW5jaWEsIEVzdGFjaW9uYWxpZGFkIHkgUnVpZG8KCkxhcyBzZXJpZXMgdGVtcG9yYWxlcyBlbiBzYWx1ZCwgY29tbyBsb3MgY2Fzb3MgZGlhcmlvcyBkZSB1bmEgZW5mZXJtZWRhZApvIGxhcyBhZG1pc2lvbmVzIGhvc3BpdGFsYXJpYXMsIHNlIGNvbXBvbmVuIGRlIHBhdHJvbmVzIHNpc3RlbcOhdGljb3MgeQphbGVhdG9yaW9zIHF1ZSBkZWJlbiBpZGVudGlmaWNhcnNlIHBhcmEgbW9kZWxhciB5IHByZWRlY2lyIGNvbgpwcmVjaXNpw7NuLgoKKipUZW5kZW5jaWE6KioKCi0gICAqKkRlZmluaWNpw7NuOioqIE1vdmltaWVudG8gYSBsYXJnbyBwbGF6byBlbiBsb3MgZGF0b3MsIHF1ZSBwdWVkZSBzZXIKICAgIGFzY2VuZGVudGUsIGRlc2NlbmRlbnRlIG8gY29uc3RhbnRlLgotICAgKipFamVtcGxvIGVuIHNhbHVkOioqIEF1bWVudG8gZ3JhZHVhbCBlbiBsYSBwcmV2YWxlbmNpYSBkZSBkaWFiZXRlcwogICAgdGlwbyAyIGRlYmlkbyBhIGNhbWJpb3MgZW4gZWwgZXN0aWxvIGRlIHZpZGEgbyBlbnZlamVjaW1pZW50bwogICAgcG9ibGFjaW9uYWwuCi0gICAqKklkZW50aWZpY2FjacOzbjoqKiBWaXN1YWxpemFjacOzbiBjb24gZ3LDoWZpY29zIGRlIGzDrW5lYXMgbyBzdWF2aXphZG8KICAgIChlLmcuLCBtZWRpYSBtw7N2aWwpIHBhcmEgZGV0ZWN0YXIgcGF0cm9uZXMgYSBsYXJnbyBwbGF6by4KLSAgICoqQXBsaWNhY2nDs24gcHLDoWN0aWNhOioqIEFuYWxpemFyIGxhIHRlbmRlbmNpYSBlbiBsb3Mgbml2ZWxlcwogICAgcHJvbWVkaW8gZGUgZ2x1Y29zYSBlbiBzYW5ncmUgZW4gdW5hIHBvYmxhY2nDs24gZHVyYW50ZSB1bmEgZMOpY2FkYQogICAgcGFyYSBldmFsdWFyIGVsIGltcGFjdG8gZGUgcG9sw610aWNhcyBkZSBzYWx1ZCBww7pibGljYS4KCioqRXN0YWNpb25hbGlkYWQ6KioKCi0gICAqKkRlZmluaWNpw7NuOioqIFBhdHJvbmVzIHJlcGV0aXRpdm9zIGVuIGludGVydmFsb3MgcmVndWxhcmVzIChlLmcuLAogICAgZGlhcmlvcywgc2VtYW5hbGVzLCBhbnVhbGVzKSBkZWJpZG8gYSBmYWN0b3JlcyBjw61jbGljb3MuCi0gICAqKkVqZW1wbG8gZW4gc2FsdWQ6KiogSW5jcmVtZW50byBkZSBjYXNvcyBkZSBpbmZsdWVuemEgZHVyYW50ZSBlbAogICAgaW52aWVybm8gbyBwaWNvcyBzZW1hbmFsZXMgZW4gYWRtaXNpb25lcyBob3NwaXRhbGFyaWFzIGxvcyBsdW5lcy4KLSAgICoqSWRlbnRpZmljYWNpw7NuOioqIEdyw6FmaWNvcyBkZSBhdXRvY29ycmVsYWNpw7NuIChBQ0YpIG8KICAgIGRlc2NvbXBvc2ljacOzbiBlc3RhY2lvbmFsIHBhcmEgZGV0ZWN0YXIgY2ljbG9zIHBlcmnDs2RpY29zLgotICAgKipBcGxpY2FjacOzbiBwcsOhY3RpY2E6KiogSWRlbnRpZmljYXIgcGF0cm9uZXMgZXN0YWNpb25hbGVzIGVuIGxvcwogICAgY2Fzb3MgZGUgZGVuZ3VlIHBhcmEgcGxhbmlmaWNhciBjYW1wYcOxYXMgZGUgcHJldmVuY2nDs24gZHVyYW50ZSBsb3MKICAgIG1lc2VzIGRlIGxsdXZpYS4KCioqUnVpZG8gKGNvbXBvbmVudGUgYWxlYXRvcmlhKToqKgoKLSAgICoqRGVmaW5pY2nDs246KiogVmFyaWFjaW9uZXMgYWxlYXRvcmlhcyBubyBleHBsaWNhZGFzIHBvciBsYQogICAgdGVuZGVuY2lhIG8gbGEgZXN0YWNpb25hbGlkYWQsIG1vZGVsYWRhcyBjb21vIGVycm9yIGVzdG9jw6FzdGljby4KLSAgICoqRWplbXBsbyBlbiBzYWx1ZDoqKiBGbHVjdHVhY2lvbmVzIGRpYXJpYXMgZW4gZWwgbsO6bWVybyBkZQogICAgY29uc3VsdGFzIGRlIHVyZ2VuY2lhIGRlYmlkbyBhIGV2ZW50b3MgaW1wcmVkZWNpYmxlcy4KLSAgICoqSWRlbnRpZmljYWNpw7NuOioqIFJlc2lkdW9zIHRyYXMgZWxpbWluYXIgdGVuZGVuY2lhIHkKICAgIGVzdGFjaW9uYWxpZGFkLCBhc3VtaWRvcyBjb21vIHJ1aWRvIGJsYW5jbwogICAgKCRcZXBzaWxvbl90IFxzaW0gTigwLCBcc2lnbWFeMikkKS4KLSAgICoqQXBsaWNhY2nDs24gcHLDoWN0aWNhOioqIE1vZGVsYXIgZWwgcnVpZG8gZW4gbGFzIHRhc2FzIGRlCiAgICBob3NwaXRhbGl6YWNpw7NuIHBhcmEgZXZhbHVhciBsYSBlc3RhYmlsaWRhZCBkZSBsb3MgZGF0b3MgdHJhcwogICAgaW50ZXJ2ZW5jaW9uZXMuCgoqKk1vZGVsbyBnZW5lcmFsOioqICQkCllfdCA9IFRfdCArIFNfdCArIFxlcHNpbG9uX3QKJCQgRG9uZGUgJFlfdCQgZXMgbGEgc2VyaWUgb2JzZXJ2YWRhLCAkVF90JCBlcyBsYSB0ZW5kZW5jaWEsICRTX3QkIGVzIGxhCmVzdGFjaW9uYWxpZGFkLCB5ICRcZXBzaWxvbl90JCBlcyBlbCBydWlkby4KCiMjIyBEZXNjb21wb3NpY2nDs24gZGUgU2VyaWVzCgpMYSBkZXNjb21wb3NpY2nDs24gc2VwYXJhIGxhIHNlcmllIHRlbXBvcmFsIGVuIHN1cyBjb21wb25lbnRlcyBwYXJhCmZhY2lsaXRhciBlbCBhbsOhbGlzaXMgeSBtb2RlbGFkby4KCioqVGlwb3MgZGUgZGVzY29tcG9zaWNpw7NuOioqCgotICAgKipBZGl0aXZhOioqICRZX3QgPSBUX3QgKyBTX3QgKyBcZXBzaWxvbl90JCwgYWRlY3VhZGEgY3VhbmRvIGxhCiAgICBhbXBsaXR1ZCBkZSBsYSBlc3RhY2lvbmFsaWRhZCBlcyBjb25zdGFudGUuCi0gICAqKk11bHRpcGxpY2F0aXZhOioqICRZX3QgPSBUX3QgXGNkb3QgU190IFxjZG90IFxlcHNpbG9uX3QkLCDDunRpbAogICAgY3VhbmRvIGxhIGVzdGFjaW9uYWxpZGFkIHZhcsOtYSBjb24gbGEgdGVuZGVuY2lhIChlLmcuLCBtYXlvcgogICAgdmFyaWFjacOzbiBlbiBwaWNvcyBlcGlkw6ltaWNvcykuCgoqKk3DqXRvZG9zOioqCgotICAgKipDbMOhc2ljbzoqKiBVc2EgbWVkaWFzIG3Ds3ZpbGVzIHBhcmEgZXN0aW1hciAkVF90JCwgcmVzdGEgbGEKICAgIHRlbmRlbmNpYSBwYXJhIG9idGVuZXIgJFNfdCQsIHkgY2FsY3VsYSAkXGVwc2lsb25fdCQgY29tbyByZXNpZHVvLgotICAgKipTVEwgKFNlYXNvbmFsIGFuZCBUcmVuZCBkZWNvbXBvc2l0aW9uIHVzaW5nIExPRVNTKToqKiBBanVzdGEKICAgIHRlbmRlbmNpYSB5IGVzdGFjaW9uYWxpZGFkIGNvbiBzdWF2aXphZG8gbG9jYWwsIHJvYnVzdG8gYSB2YWxvcmVzCiAgICBhdMOtcGljb3MuCi0gICAqKlgtMTMtQVJJTUEtU0VBVFM6KiogTcOpdG9kbyBhdmFuemFkbyBwYXJhIHNlcmllcyBjb24gZXN0YWNpb25hbGlkYWQKICAgIGNvbXBsZWphLCB1c2FkbyBlbiBkYXRvcyBvZmljaWFsZXMgZGUgc2FsdWQuCgoqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIERlc2NvbXBvbmVyIHNlcmllcyBkZSBhZG1pc2lvbmVzIGhvc3BpdGFsYXJpYXMKcG9yIGluc3VmaWNpZW5jaWEgY2FyZMOtYWNhIHBhcmEgaWRlbnRpZmljYXIgdGVuZGVuY2lhcyBhIGxhcmdvIHBsYXpvCihlLmcuLCBhdW1lbnRvIHBvciBlbnZlamVjaW1pZW50bykgeSBwaWNvcyBlc3RhY2lvbmFsZXMgKGUuZy4sCmludmllcm5vKS4KCioqRWplbXBsbyBwcsOhY3RpY286KiogRW4gdW5hIHNlcmllIGRlIGNhc29zIHNlbWFuYWxlcyBkZSBpbmZsdWVuemEKKDIwMTUtMjAyNSksIGxhIGRlc2NvbXBvc2ljacOzbiBTVEwgZW4gUiAoYHN0bCgpYCkgbXVlc3RyYSB1bmEgdGVuZGVuY2lhCmFzY2VuZGVudGUgKGF1bWVudG8gZGUgY2Fzb3MgcG9yIGNhbWJpb3MgZGVtb2dyw6FmaWNvcyksIGVzdGFjaW9uYWxpZGFkCmFudWFsIChwaWNvcyBlbiBpbnZpZXJubykgeSBydWlkbyBhbGVhdG9yaW8uIEVzdG8gZ3XDrWEgbGEgcGxhbmlmaWNhY2nDs24KZGUgY2FtcGHDsWFzIGRlIHZhY3VuYWNpw7NuLgoKIyMgOS4yIE1vZGVsb3MgQVJJTUEKCkxvcyBtb2RlbG9zIEFSSU1BIChBdXRvUmVncmVzc2l2ZSBJbnRlZ3JhdGVkIE1vdmluZyBBdmVyYWdlKSBzb24KYW1wbGlhbWVudGUgdXRpbGl6YWRvcyBwYXJhIG1vZGVsYXIgc2VyaWVzIHRlbXBvcmFsZXMgZXN0YWNpb25hcmlhcyBvCnRyYW5zZm9ybWFkYXMgYSBlc3RhY2lvbmFyaWFzLCBzaWVuZG8gaWRlYWxlcyBwYXJhIHByZWRlY2lyIHZhcmlhYmxlcwpjb21vIHRhc2FzIGRlIGluY2lkZW5jaWEgbyBiaW9tYXJjYWRvcmVzIGVuIHNhbHVkLgoKIyMjIElkZW50aWZpY2FjacOzbiwgRXN0aW1hY2nDs24geSBEaWFnbsOzc3RpY28KCioqRGVmaW5pY2nDs246KioKCi0gICAqKkFSSU1BKHAsZCxxKToqKgogICAgLSAgICoqQVIocCk6KiogQ29tcG9uZW50ZSBhdXRvcnJlZ3Jlc2l2bywgbW9kZWxhIGxhIGRlcGVuZGVuY2lhIGRlCiAgICAgICAgJFlfdCQgY29uIHZhbG9yZXMgcGFzYWRvcyAoJFlfe3QtMX0sIFxkb3RzLCBZX3t0LXB9JCkuCiAgICAtICAgKipJKGQpOioqIERpZmVyZW5jaWFjacOzbiBkZSBvcmRlbiAkZCQgcGFyYSBsb2dyYXIKICAgICAgICBlc3RhY2lvbmFyaWVkYWQuCiAgICAtICAgKipNQShxKToqKiBDb21wb25lbnRlIGRlIG1lZGlhIG3Ds3ZpbCwgbW9kZWxhIGxhIGRlcGVuZGVuY2lhIGRlCiAgICAgICAgJFlfdCQgY29uIGVycm9yZXMgcGFzYWRvcwogICAgICAgICgkXGVwc2lsb25fe3QtMX0sIFxkb3RzLCBcZXBzaWxvbl97dC1xfSQpLgoKKipNb2RlbG86KiogJCQKXHBoaShCKSgxLUIpXmQgWV90ID0gXHRoZXRhKEIpIFxlcHNpbG9uX3QKJCQgRG9uZGUgJEIkIGVzIGVsIG9wZXJhZG9yIGRlIHJlemFnbyAoJEJZX3QgPSBZX3t0LTF9JCksCiRccGhpKEIpID0gMSAtIFxwaGlfMSBCIC0gXGRvdHMgLSBccGhpX3AgQl5wJCwgeQokXHRoZXRhKEIpID0gMSArIFx0aGV0YV8xIEIgKyBcZG90cyArIFx0aGV0YV9xIEJecSQuCgoqKklkZW50aWZpY2FjacOzbjoqKgoKLSAgICoqRXN0YWNpb25hcmllZGFkOioqIFZlcmlmaWNhciBjb24gZ3LDoWZpY29zIGRlIGxhIHNlcmllLCBBQ0YKICAgIChkZWNhaW1pZW50byBsZW50byBpbmRpY2Egbm8gZXN0YWNpb25hcmllZGFkKSBvIHBydWViYXMgY29tbwogICAgRGlja2V5LUZ1bGxlci4KICAgIC0gICBTaSBubyBlc3RhY2lvbmFyaWEsIGFwbGljYXIgZGlmZXJlbmNpYWNpw7NuICgkZD0xJCBvICRkPTIkKSBoYXN0YQogICAgICAgIGxvZ3JhciBlc3RhY2lvbmFyaWVkYWQuCi0gICAqKk9yZGVuKiogJHAsIHEkOiBVc2FyIEFDRiB5IFBBQ0YgKFBhcnRpYWwgQXV0b2NvcnJlbGF0aW9uCiAgICBGdW5jdGlvbik6CiAgICAtICAgKipBQ0Y6KiogQ29ydGEgZW4gbGFnICRxJCBwYXJhIE1BKHEpLgogICAgLSAgICoqUEFDRjoqKiBDb3J0YSBlbiBsYWcgJHAkIHBhcmEgQVIocCkuCi0gICAqKkVzdGFjaW9uYWxpZGFkOioqIFVzYXIgQVJJTUEgZXN0YWNpb25hbCAoU0FSSU1BOgogICAgJChwLGQscSkgXHRpbWVzIChQLEQsUSlfcyQpIHNpIGhheSBwYXRyb25lcyBwZXJpw7NkaWNvcyAoZS5nLiwgJHM9MTIkCiAgICBwYXJhIGRhdG9zIG1lbnN1YWxlcykuCgoqKkVzdGltYWNpw7NuOioqCgotICAgTcOheGltYSB2ZXJvc2ltaWxpdHVkIChNTEUpIHBhcmEgYWp1c3RhciBwYXLDoW1ldHJvcwogICAgKCRccGhpX2ksIFx0aGV0YV9qJCkuCi0gICAqKkhlcnJhbWllbnRhczoqKiBgYXV0by5hcmltYSgpYCBlbiBSIG8gYHBtZGFyaW1hYCBlbiBQeXRob24gcGFyYQogICAgc2VsZWNjaW9uYXIgYXV0b23DoXRpY2FtZW50ZSAkcCwgZCwgcSQuCgoqKkRpYWduw7NzdGljbzoqKgoKLSAgICoqUmVzaWR1b3M6KiogRGViZW4gc2VyIHJ1aWRvIGJsYW5jbyAoc2luIGF1dG9jb3JyZWxhY2nDs24sIG1lZGlhIDAsCiAgICB2YXJpYW56YSBjb25zdGFudGUpLgogICAgLSAgIFZlcmlmaWNhciBjb24gQUNGIGRlIHJlc2lkdW9zLCBwcnVlYmEgZGUgTGp1bmctQm94ICgkcCA+IDAuMDUkKS4KLSAgICoqQWp1c3RlOioqIENvbXBhcmFyIG3DqXRyaWNhcyBjb21vIEFJQyBvIEJJQyBwYXJhIHNlbGVjY2lvbmFyIGVsCiAgICBtZWpvciBtb2RlbG8uCgoqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIE1vZGVsYXIgbGEgaW5jaWRlbmNpYSBzZW1hbmFsIGRlIENPVklELTE5IHBhcmEKcHJlZGVjaXIgZnV0dXJvcyBicm90ZXMuCgoqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuYSBzZXJpZSBkZSBjYXNvcyBzZW1hbmFsZXMgZGUgQ09WSUQtMTkKKDIwMjAtMjAyNSksIGxhIHBydWViYSBEaWNrZXktRnVsbGVyIGluZGljYSBubyBlc3RhY2lvbmFyaWVkYWQKKCRwID0gMC4xJCkuIFRyYXMgdW5hIGRpZmVyZW5jaWFjacOzbiAoJGQ9MSQpLCBBQ0YgeSBQQUNGIHN1Z2llcmVuIHVuCkFSSU1BKDEsMSwxKS4gRWwgbW9kZWxvIGFqdXN0YWRvIChgYXV0by5hcmltYSgpYCBlbiBSKSB0aWVuZSByZXNpZHVvcwpzaW4gYXV0b2NvcnJlbGFjacOzbiAoJHAgPSAwLjgkIGVuIExqdW5nLUJveCkgeSB1biBBSUMgZGUgMTI1MC4KCiMjIyBQcmVkaWNjacOzbiB5IFZhbGlkYWNpw7NuCgoqKlByZWRpY2Npw7NuOioqCgotICAgVXNhciBlbCBtb2RlbG8gQVJJTUEgcGFyYSBnZW5lcmFyIHByZWRpY2Npb25lcyBwdW50dWFsZXMgeQogICAgaW50ZXJ2YWxvcyBkZSBwcmVkaWNjacOzbiAoOTUlKS4KLSAgICoqRsOzcm11bGE6KiogUGFyYSBBUklNQSgxLDEsMSksIGxhIHByZWRpY2Npw7NuIGEgdW4gcGFzbyBlczogJCQKICAgIFxoYXR7WX1fe3QrMX0gPSBZX3QgKyBccGhpXzEgKFlfdCAtIFlfe3QtMX0pICsgXHRoZXRhXzEgXGVwc2lsb25fdAogICAgJCQKLSAgIFByZWRpY2Npb25lcyBhIGxhcmdvIHBsYXpvIHBpZXJkZW4gcHJlY2lzacOzbiBkZWJpZG8gYSBsYSBhY3VtdWxhY2nDs24KICAgIGRlIGluY2VydGlkdW1icmUuCgoqKlZhbGlkYWNpw7NuOioqCgotICAgKipEaXZpc2nDs24gZGUgZGF0b3M6KiogRW50cmVuYXIgZW4gNzAtODAlIGRlIGxvcyBkYXRvcywgdmFsaWRhciBlbgogICAgZWwgcmVzdG8uCi0gICAqKk3DqXRyaWNhczoqKiBFcnJvciBjdWFkcsOhdGljbyBtZWRpbyAoUk1TRSksIGVycm9yIGFic29sdXRvIG1lZGlvCiAgICAoTUFFKSwgbyBlcnJvciBwb3JjZW50dWFsIGFic29sdXRvIG1lZGlvIChNQVBFKS4KLSAgICoqVmFsaWRhY2nDs24gY3J1emFkYSB0ZW1wb3JhbDoqKiBQcmVkZWNpciB1biBob3Jpem9udGUgZnV0dXJvCiAgICBpdGVyYXRpdmFtZW50ZSAoZS5nLiwgcm9sbGluZyBmb3JlY2FzdCkuCgoqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIFByZWRlY2lyIGFkbWlzaW9uZXMgaG9zcGl0YWxhcmlhcyBwb3IKaW5zdWZpY2llbmNpYSBjYXJkw61hY2EgcGFyYSBvcHRpbWl6YXIgcmVjdXJzb3MuCgoqKkVqZW1wbG8gcHLDoWN0aWNvOioqIFVuIG1vZGVsbyBBUklNQSgxLDEsMSkgcHJlZGljZSBjYXNvcyBkZSBDT1ZJRC0xOQpwYXJhIGxhcyBwcsOzeGltYXMgNCBzZW1hbmFzLCBjb24gdW4gUk1TRSBkZSA1MCBjYXNvcyBlbiBkYXRvcyBkZQp2YWxpZGFjacOzbi4gTG9zIGludGVydmFsb3MgZGUgcHJlZGljY2nDs24gYWwgOTUlIGNhcHR1cmFuIGVsIDkwJSBkZSBsb3MKY2Fzb3Mgb2JzZXJ2YWRvcywgdmFsaWRhbmRvIGVsIG1vZGVsby4KCiMjIDkuMyBNb2RlbG9zIEF2YW56YWRvcwoKIyMjIE1vZGVsb3MgR0FSQ0ggcGFyYSBWb2xhdGlsaWRhZAoKTG9zIG1vZGVsb3MgR0FSQ0ggKEdlbmVyYWxpemVkIEF1dG9yZWdyZXNzaXZlIENvbmRpdGlvbmFsCkhldGVyb3NrZWRhc3RpY2l0eSkgbW9kZWxhbiBsYSB2b2xhdGlsaWRhZCB2YXJpYWJsZSBlbiBlbCB0aWVtcG8sIMO6dGlsCnBhcmEgc2VyaWVzIGNvbiB2YXJpYW56YSBubyBjb25zdGFudGUgKGUuZy4sIHRhc2FzIGRlIGV2ZW50b3MgcmFyb3MgZW4Kc2FsdWQpLgoKKipEZWZpbmljacOzbjoqKgoKLSAgICoqR0FSQ0gocCxxKToqKiAkJAogICAgXHNpZ21hX3ReMiA9IFxvbWVnYSArIFxzdW1fe2k9MX1ecCBcYWxwaGFfaSBcZXBzaWxvbl97dC1pfV4yICsgXHN1bV97aj0xfV5xIFxiZXRhX2ogXHNpZ21hX3t0LWp9XjIKICAgICQkIERvbmRlICRcc2lnbWFfdF4yJCBlcyBsYSB2YXJpYW56YSBjb25kaWNpb25hbCBlbiAkdCQsCiAgICAkXGVwc2lsb25fe3QtaX1eMiQgc29uIGVycm9yZXMgYWwgY3VhZHJhZG8sIHkKICAgICRcb21lZ2EsIFxhbHBoYV9pLCBcYmV0YV9qJCBzb24gcGFyw6FtZXRyb3MuCi0gICBDb21iaW5hIGNvbiBBUklNQSBwYXJhIG1vZGVsYXIgbGEgbWVkaWEgeSBsYSB2b2xhdGlsaWRhZAogICAgc2ltdWx0w6FuZWFtZW50ZSAoQVJJTUEtR0FSQ0gpLgoKKipJZGVudGlmaWNhY2nDs246KioKCi0gICBEZXRlY3RhciBoZXRlcm9zY2VkYXN0aWNpZGFkIGNvbiBBQ0YgZGUgcmVzaWR1b3MgYWwgY3VhZHJhZG8gbwogICAgcHJ1ZWJhcyBBUkNILUxNLgotICAgU2VsZWNjaW9uYXIgJHAsIHEkIHVzYW5kbyBBSUMvQklDIG8gaW5zcGVjY2nDs24gZGUgQUNGL1BBQ0YgZGUKICAgIHJlc2lkdW9zIGFsIGN1YWRyYWRvLgoKKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBNb2RlbGFyIGxhIHZvbGF0aWxpZGFkIGVuIHRhc2FzIGRlIGV2ZW50b3MKYWR2ZXJzb3MgKGUuZy4sIGluZmVjY2lvbmVzIGhvc3BpdGFsYXJpYXMpIHBhcmEgcHJlZGVjaXIgcGVyw61vZG9zIGRlCmFsdGEgdmFyaWFiaWxpZGFkLgoKKipFamVtcGxvIHByw6FjdGljbzoqKiBFbiB1bmEgc2VyaWUgZGUgdGFzYXMgZGlhcmlhcyBkZSBpbmZlY2Npb25lcwpub3NvY29taWFsZXMsIGxvcyByZXNpZHVvcyBkZSB1biBBUklNQSgxLDEsMCkgbXVlc3RyYW4KaGV0ZXJvc2NlZGFzdGljaWRhZCAoJHAgPCAwLjA1JCBlbiBBUkNILUxNKS4gVW4gbW9kZWxvIEdBUkNIKDEsMSkKYWp1c3RhZG8gZW4gUiAoYHJ1Z2FyY2hgKSByZWR1Y2UgZWwgQUlDIGVuIDIwIHVuaWRhZGVzIHkgcHJlZGljZQpwZXLDrW9kb3MgZGUgYWx0YSB2b2xhdGlsaWRhZCwgYXl1ZGFuZG8gYSBwbGFuaWZpY2FyIHJlY3Vyc29zLgoKIyMjIFNlcmllcyBUZW1wb3JhbGVzIE5vIEVzdGFjaW9uYXJpYXMKCkxhcyBzZXJpZXMgbm8gZXN0YWNpb25hcmlhcyBwcmVzZW50YW4gdGVuZGVuY2lhcyBvIHZhcmlhbnphcyBjYW1iaWFudGVzLApyZXF1aXJpZW5kbyB0cmFuc2Zvcm1hY2lvbmVzIG8gbW9kZWxvcyBlc3BlY8OtZmljb3MuCgoqKlBydWViYXMgZGUgZXN0YWNpb25hcmllZGFkOioqCgotICAgKipEaWNrZXktRnVsbGVyIGF1bWVudGFkbyAoQURGKToqKiAkSF8wJDogU2VyaWUgdGllbmUgcmHDrXogdW5pdGFyaWEKICAgIChubyBlc3RhY2lvbmFyaWEpLgotICAgKipLUFNTOioqICRIXzAkOiBTZXJpZSBlcyBlc3RhY2lvbmFyaWEuCgoqKlRyYW5zZm9ybWFjaW9uZXM6KioKCi0gICAqKkRpZmVyZW5jaWFjacOzbjoqKiAkXERlbHRhIFlfdCA9IFlfdCAtIFlfe3QtMX0kIHBhcmEgZWxpbWluYXIKICAgIHRlbmRlbmNpYS4KLSAgICoqTG9nYXJpdG1vIG8gQm94LUNveDoqKiBFc3RhYmlsaXphciB2YXJpYW56YSBlbiBzZXJpZXMgY29uCiAgICBjcmVjaW1pZW50byBleHBvbmVuY2lhbCAoZS5nLiwgY2Fzb3MgZXBpZMOpbWljb3MpLgoKKipNb2RlbG9zIHBhcmEgbm8gZXN0YWNpb25hcmllZGFkOioqCgotICAgKipNb2RlbG9zIGRlIHRlbmRlbmNpYSBkZXRlcm1pbmlzdGE6KiogJCQKICAgIFlfdCA9IFxiZXRhXzAgKyBcYmV0YV8xIHQgKyBcZXBzaWxvbl90CiAgICAkJAotICAgKipNb2RlbG9zIGRlIHJhw616IHVuaXRhcmlhOioqIEFSSU1BIGNvbiAkZCBcZ2VxIDEkLgotICAgKipNb2RlbG9zIGVzdHJ1Y3R1cmFsZXM6KiogUmVwcmVzZW50YW4gdGVuZGVuY2lhIHkgZXN0YWNpb25hbGlkYWQKICAgIGV4cGzDrWNpdGFtZW50ZSAoZS5nLiwgYFN0cnVjdFRTYCBlbiBSKS4KCioqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogTW9kZWxhciBlbCBhdW1lbnRvIG5vIGVzdGFjaW9uYXJpbyBlbiBjYXNvcyBkZQpvYmVzaWRhZCBwYXJhIHByb3llY3RhciBuZWNlc2lkYWRlcyBkZSBhdGVuY2nDs24gbcOpZGljYS4KCioqRWplbXBsbyBwcsOhY3RpY286KiogVW5hIHNlcmllIGRlIHByZXZhbGVuY2lhIGFudWFsIGRlIG9iZXNpZGFkCigyMDAwLTIwMjUpIGVzIG5vIGVzdGFjaW9uYXJpYSAoQURGOiAkcCA9IDAuMTUkKS4gVHJhcyB1bmEKZGlmZXJlbmNpYWNpw7NuICgkZD0xJCksIHVuIEFSSU1BKDAsMSwxKSBhanVzdGEgYmllbiAoQUlDID0gMzAwKS4KQWx0ZXJuYXRpdmFtZW50ZSwgdW4gbW9kZWxvIGVzdHJ1Y3R1cmFsIGNvbiB0ZW5kZW5jaWEgbGluZWFsIHByZWRpY2UgdW4KYXVtZW50byBkZSAyJSBhbnVhbCwgY29uIGludGVydmFsb3MgZGUgcHJlZGljY2nDs24gYWwgOTUlLgoKIyMgUmVjdXJzb3MgcGFyYSBlbCBBdXRvZXN0dWRpbyBlbiBTYWx1ZAoKIyMjIExlY3R1cmFzOgoKLSAgICJUaW1lIFNlcmllcyBBbmFseXNpcyBhbmQgSXRzIEFwcGxpY2F0aW9ucyIgZGUgU2h1bXdheSB5IFN0b2ZmZXIKICAgIChDYXDDrXR1bG9zIHNvYnJlIEFSSU1BLCBkZXNjb21wb3NpY2nDs24pLgotICAgIkZvcmVjYXN0aW5nOiBQcmluY2lwbGVzIGFuZCBQcmFjdGljZSIgZGUgSHluZG1hbiB5IEF0aGFuYXNvcG91bG9zCiAgICAoQ2Fww610dWxvcyBzb2JyZSBBUklNQSwgU1RMLCBHQVJDSCkuCi0gICAiQmlvc3RhdGlzdGljczogQSBGb3VuZGF0aW9uIGZvciBBbmFseXNpcyBpbiB0aGUgSGVhbHRoIFNjaWVuY2VzIiBkZQogICAgRGFuaWVsIChDYXDDrXR1bG9zIHNvYnJlIHNlcmllcyB0ZW1wb3JhbGVzKS4KCiMjIyBFamVyY2ljaW9zIHByw6FjdGljb3M6CgotICAgRGVzY29tcG9uZXIgc2VyaWVzIGRlIGNhc29zIGRlIGluZmx1ZW56YSB1c2FuZG8gU1RMIHkgYW5hbGl6YXIKICAgIHRlbmRlbmNpYS9lc3RhY2lvbmFsaWRhZC4KLSAgIEFqdXN0YXIgbW9kZWxvcyBBUklNQSBhIGRhdG9zIGRlIGFkbWlzaW9uZXMgaG9zcGl0YWxhcmlhcywgdmFsaWRhbmRvCiAgICBwcmVkaWNjaW9uZXMgY29uIFJNU0UuCi0gICBJbXBsZW1lbnRhciBtb2RlbG9zIEdBUkNIIHBhcmEgdGFzYXMgZGUgZXZlbnRvcyBhZHZlcnNvcywgZXZhbHVhbmRvCiAgICB2b2xhdGlsaWRhZC4KLSAgIE1vZGVsYXIgc2VyaWVzIG5vIGVzdGFjaW9uYXJpYXMgKGUuZy4sIHByZXZhbGVuY2lhIGRlIGRpYWJldGVzKSBjb24KICAgIEFSSU1BIG8gbW9kZWxvcyBlc3RydWN0dXJhbGVzLgoKIyMjIEhlcnJhbWllbnRhcyBjb21wdXRhY2lvbmFsZXM6CgotICAgKipSOioqIFBhcXVldGVzIGBmb3JlY2FzdGAgKGF1dG8uYXJpbWEsIHN0bCksIGB0c2VyaWVzYCAoQURGLAogICAgR0FSQ0gpLCBgcnVnYXJjaGAgKEdBUkNIKS4KICAgIC0gICAqKkVqZW1wbG86KiogYGF1dG8uYXJpbWEoY2Fzb3MsIHNlYXNvbmFsPVRSVUUpYCBwYXJhIFNBUklNQTsKICAgICAgICBgdWdhcmNoZml0KHNwZWM9dWdhcmNoc3BlYygpLCBkYXRhPXJldG9ybm9zKWAgcGFyYSBHQVJDSC4KLSAgICoqUHl0aG9uOioqIExpYnJlcsOtYXMgYHN0YXRzbW9kZWxzYCAoQVJJTUEsIFNUTCksIGBwbWRhcmltYWAKICAgIChhdXRvX2FyaW1hKSwgYGFyY2hgIChHQVJDSCkuCiAgICAtICAgKipFamVtcGxvOioqIGBwbWRhcmltYS5hdXRvX2FyaW1hKGNhc29zLCBzZWFzb25hbD1UcnVlKWA7CiAgICAgICAgYGFyY2hfbW9kZWwocmVzaWR1b3MsIHA9MSwgcT0xKS5maXQoKWAuCgojIyMgQmFzZXMgZGUgZGF0b3M6CgotICAgV0hPIEdsb2JhbCBIZWFsdGggT2JzZXJ2YXRvcnkgcGFyYSBzZXJpZXMgZGUgZW5mZXJtZWRhZGVzIChlLmcuLAogICAgbWFsYXJpYSwgdHViZXJjdWxvc2lzKS4KLSAgIENEQyBGbHVWaWV3IHBhcmEgZGF0b3MgZGUgaW5mbHVlbnphLgotICAgSG9zcGl0YWwgRXBpc29kZSBTdGF0aXN0aWNzIChIRVMpIHBhcmEgYWRtaXNpb25lcyBob3NwaXRhbGFyaWFzLgoKIyBUYWJsYSBSZXN1bWVuOiBBbsOhbGlzaXMgZGUgU2VyaWVzIFRlbXBvcmFsZXMgZW4gZWwgU2VjdG9yIFNhbHVkCgpgYGB7ciBzZXJpZXMtdGFibGUsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2FzaXMnLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCgojIENyZWFyIGxhIHRhYmxhCnRhYmxhX3NlcmllcyA8LSBkYXRhLmZyYW1lKAogICJNb2RlbG8gbyBUw6ljbmljYSIgPSBjKAogICAgIkRlc2NvbXBvc2ljacOzbiBTVEwiLAogICAgIkFSSU1BKHAsZCxxKSIsCiAgICAiU0FSSU1BIChBUklNQSBFc3RhY2lvbmFsKSIsCiAgICAiTW9kZWxvIEdBUkNIIiwKICAgICJBUklNQS1HQVJDSCIsCiAgICAiTW9kZWxvIGRlIFRlbmRlbmNpYSBEZXRlcm1pbmlzdGEiLAogICAgIk1vZGVsbyBFc3RydWN0dXJhbCAoZS5nLiwgU3RydWN0VFMpIgogICksCiAgIlRpcG8gZGUgQW7DoWxpc2lzIiA9IGMoCiAgICAiRGVzY29tcG9zaWNpw7NuIGRlIGNvbXBvbmVudGVzIiwKICAgICJNb2RlbGFkbyBkZSBzZXJpZXMgZXN0YWNpb25hcmlhcyIsCiAgICAiTW9kZWxhZG8gY29uIGVzdGFjaW9uYWxpZGFkIiwKICAgICJNb2RlbGFkbyBkZSB2b2xhdGlsaWRhZCIsCiAgICAiTW9kZWxhZG8gZGUgbWVkaWEgeSB2YXJpYW56YSIsCiAgICAiTW9kZWxhZG8gZGUgdGVuZGVuY2lhIiwKICAgICJEZXNjb21wb3NpY2nDs24gZXhwbMOtY2l0YSBkZSB0ZW5kZW5jaWEgeSBlc3RhY2lvbmFsaWRhZCIKICApLAogICJTdXB1ZXN0b3MgQ2xhdmUiID0gYygKICAgICJUZW5kZW5jaWEgc3VhdmUsIGVzdGFjaW9uYWxpZGFkIGVzdGFibGUsIHJ1aWRvIGJsYW5jbyIsCiAgICAiRXN0YWNpb25hcmllZGFkIHRyYXMgZGlmZXJlbmNpYWNpw7NuLCByZXNpZHVvcyBub3JtYWxlcyIsCiAgICAiRXN0YWNpb25hbGlkYWQgZmlqYSwgZXN0YWNpb25hcmllZGFkIGVzdGFjaW9uYWwiLAogICAgIkhldGVyb3NjZWRhc3RpY2lkYWQgY29uZGljaW9uYWwsIGVycm9yZXMgYWwgY3VhZHJhZG8gYXV0b2NvcnJlbGFjaW9uYWRvcyIsCiAgICAiTWVkaWEgbW9kZWxhZGEgcG9yIEFSSU1BLCB2YXJpYW56YSBwb3IgR0FSQ0giLAogICAgIlRlbmRlbmNpYSBsaW5lYWwgbyBwb2xpbsOzbWljYSwgZXJyb3JlcyBpLmkuZC4iLAogICAgIkNvbXBvbmVudGVzIG9ic2VydmFibGVzOiB0ZW5kZW5jaWEsIGVzdGFjaW9uYWxpZGFkLCBydWlkbyIKICApLAogICJFY3VhY2nDs24gZGVsIE1vZGVsbyIgPSBjKAogICAgIkFqdXN0ZSBubyBwYXJhbcOpdHJpY28gbWVkaWFudGUgTE9FU1MiLAogICAgIiRcXHBoaShCKSgxLUIpXmQgWV90ID0gXFx0aGV0YShCKSBcXGVwc2lsb25fdCQiLAogICAgIiQocCxkLHEpIFxcdGltZXMgKFAsRCxRKV9zJCBjb24gZXN0YWNpb25hbGlkYWQgZGUgcGVyw61vZG8gJHMkIiwKICAgICIkXFxzaWdtYV90XjIgPSBcXG9tZWdhICsgXFxzdW0gXFxhbHBoYV9pIFxcZXBzaWxvbl97dC1pfV4yICsgXFxzdW0gXFxiZXRhX2ogXFxzaWdtYV97dC1qfV4yJCIsCiAgICAiQVJJTUEgcGFyYSAkWV90JCwgR0FSQ0ggcGFyYSAkXFxzaWdtYV90XjIkIiwKICAgICIkWV90ID0gXFxiZXRhXzAgKyBcXGJldGFfMSB0ICsgXFxlcHNpbG9uX3QkIiwKICAgICJFajogTml2ZWwgKyBQZW5kaWVudGUgKyBFc3RhY2lvbmFsaWRhZCAobW9kZWxvIGRlIGVzcGFjaW8gZGUgZXN0YWRvcykiCiAgKSwKICAiQXBsaWNhY2nDs24gZW4gU2FsdWQiID0gYygKICAgICJJZGVudGlmaWNhciB0ZW5kZW5jaWFzIHkgcGF0cm9uZXMgZXN0YWNpb25hbGVzIGVuIGNhc29zIGRlIGVuZmVybWVkYWRlcyIsCiAgICAiUHJlZGVjaXIgaW5jaWRlbmNpYSBkZSBlbmZlcm1lZGFkZXMgKGUuZy4sIENPVklELTE5LCBkaWFiZXRlcykiLAogICAgIk1vZGVsYXIgYnJvdGVzIGFudWFsZXMgKGUuZy4sIGluZmx1ZW56YSwgZGVuZ3VlKSIsCiAgICAiRXZhbHVhciB2b2xhdGlsaWRhZCBlbiBldmVudG9zIGFkdmVyc29zIChlLmcuLCBpbmZlY2Npb25lcyBob3NwaXRhbGFyaWFzKSIsCiAgICAiUHJlZGVjaXIgdGFzYXMgZGUgZXZlbnRvcyBjb24gcmllc2dvIHZhcmlhYmxlIChlLmcuLCBjb21wbGljYWNpb25lcyBwb3N0b3BlcmF0b3JpYXMpIiwKICAgICJQcm95ZWN0YXIgY3JlY2ltaWVudG8gZGUgZW5mZXJtZWRhZGVzIGNyw7NuaWNhcyAoZS5nLiwgb2Jlc2lkYWQpIiwKICAgICJNb25pdG9yZWFyIHNlcmllcyBjb21wbGVqYXMgY29uIG3Dumx0aXBsZXMgY29tcG9uZW50ZXMgKGUuZy4sIGFkbWlzaW9uZXMgaG9zcGl0YWxhcmlhcykiCiAgKSwKICAiRWplbXBsbyBQcsOhY3RpY28iID0gYygKICAgICJTVEwgZGVzY29tcG9uZSBjYXNvcyBzZW1hbmFsZXMgZGUgaW5mbHVlbnphOiB0ZW5kZW5jaWEgYXNjZW5kZW50ZSwgcGljbyBpbnZlcm5hbCIsCiAgICAiQVJJTUEoMSwxLDEpIHByZWRpY2UgY2Fzb3MgZGUgQ09WSUQtMTkgY29uIFJNU0UgPSA1MCIsCiAgICAiU0FSSU1BKDEsMSwxKSgxLDEsMSlfNTIgbW9kZWxhIHBpY29zIHNlbWFuYWxlcyBkZSB1cmdlbmNpYXMiLAogICAgIkdBUkNIKDEsMSkgZGV0ZWN0YSBwZXLDrW9kb3MgZGUgYWx0YSB2b2xhdGlsaWRhZCBlbiBpbmZlY2Npb25lcyBub3NvY29taWFsZXMiLAogICAgIkFSSU1BKDEsMSwwKS1HQVJDSCgxLDEpIG1vZGVsYSBtZWRpYSB5IHZhcmlhbnphIGRlIGFkbWlzaW9uZXMgZGlhcmlhcyIsCiAgICAiVGVuZGVuY2lhIGxpbmVhbCBwcmVkaWNlIGF1bWVudG8gZGVsIDIlIGFudWFsIGVuIG9iZXNpZGFkIiwKICAgICJTdHJ1Y3RUUyBkZXNjb21wb25lIGFkbWlzaW9uZXMgcG9yIGluc3VmaWNpZW5jaWEgY2FyZMOtYWNhIGVuIHRlbmRlbmNpYSArIGVzdGFjaW9uYWxpZGFkIgogICksCiAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFCikKCiMgTW9zdHJhciB0YWJsYQprYWJsZSh0YWJsYV9zZXJpZXMsICJodG1sIiwgCiAgICAgIGNhcHRpb24gPSAiVGFibGEgOTogUmVzdW1lbiBkZSBtb2RlbG9zIGRlIHNlcmllcyB0ZW1wb3JhbGVzIGFwbGljYWRvcyBhbCBzZWN0b3Igc2FsdWQiKSAlPiUKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJyZXNwb25zaXZlIiksIGZ1bGxfd2lkdGggPSBGQUxTRSkgJT4lCiAgc2Nyb2xsX2JveCh3aWR0aCA9ICIxMDAlIiwgaGVpZ2h0ID0gIjUwMHB4IikKYGBgCgojIDEwLiBIZXJyYW1pZW50YXMgQ29tcHV0YWNpb25hbGVzIHBhcmEgRXN0YWTDrXN0aWNhIEluZmVyZW5jaWFsIGVuIFNhbHVkCgpMYXMgaGVycmFtaWVudGFzIGNvbXB1dGFjaW9uYWxlcyBzb24gZnVuZGFtZW50YWxlcyBlbiBlc3RhZMOtc3RpY2EKaW5mZXJlbmNpYWwgcGFyYSBhbmFsaXphciBkYXRvcywgcmVhbGl6YXIgc2ltdWxhY2lvbmVzIHkgdmlzdWFsaXphcgpyZXN1bHRhZG9zIGVuIGVsIHNlY3RvciBzYWx1ZC4gRXN0ZSB0ZW1hcmlvIGRlc2Fycm9sbGEgZWwgdXNvIGRlCnNvZnR3YXJlIGVzdGFkw61zdGljbywgbcOpdG9kb3MgZGUgcmVtdWVzdHJlbyBjb21vIGJvb3RzdHJhcCwgeSB0w6ljbmljYXMKZGUgdmlzdWFsaXphY2nDs24gZGUgZGF0b3MsIGNvbiB1biBlbmZvcXVlIGVuIGFwbGljYWNpb25lcyBwcsOhY3RpY2FzIHBhcmEKcHJvZmVzaW9uYWxlcyBtw6lkaWNvcywgaW52ZXN0aWdhZG9yZXMgY2zDrW5pY29zIHkgZXBpZGVtacOzbG9nb3MuIEVzdGFzCmhlcnJhbWllbnRhcyBwZXJtaXRlbiBtYW5lamFyIGRhdG9zIGNvbXBsZWpvcywgcmVhbGl6YXIgaW5mZXJlbmNpYXMKcm9idXN0YXMgeSBjb211bmljYXIgcmVzdWx0YWRvcyBkZSBtYW5lcmEgZWZlY3RpdmEgZW4gZXN0dWRpb3MgZGUgc2FsdWQsCmNvbW8gZW5zYXlvcyBjbMOtbmljb3MsIGFuw6FsaXNpcyBlcGlkZW1pb2zDs2dpY29zIHkgbW9kZWxhZG8gZGUKYmlvbWFyY2Fkb3Jlcy4KCiMjIDEwLjEgU29mdHdhcmUgRXN0YWTDrXN0aWNvCgojIyMgUiB5IFB5dGhvbiBwYXJhIEFuw6FsaXNpcyBJbmZlcmVuY2lhbAoKUiB5IFB5dGhvbiBzb24gbGVuZ3VhamVzIGRlIHByb2dyYW1hY2nDs24gYW1wbGlhbWVudGUgdXRpbGl6YWRvcyBlbgplc3RhZMOtc3RpY2EgaW5mZXJlbmNpYWwgZGViaWRvIGEgc3UgZmxleGliaWxpZGFkLCBjb211bmlkYWQgYWN0aXZhIHkKcGFxdWV0ZXMgZXNwZWNpYWxpemFkb3MuIEVuIGVsIHNlY3RvciBzYWx1ZCwgc29uIGlkZWFsZXMgcGFyYSBhbmFsaXphcgpkYXRvcyBjbMOtbmljb3MsIHJlYWxpemFyIHBydWViYXMgZGUgaGlww7N0ZXNpcywgbW9kZWxhciByZWdyZXNpb25lcyB5Cmdlc3Rpb25hciBncmFuZGVzIGJhc2VzIGRlIGRhdG9zLgoKKipSOioqCgotICAgKipDYXJhY3RlcsOtc3RpY2FzOioqIExlbmd1YWplIGRpc2XDsWFkbyBwYXJhIGVzdGFkw61zdGljYSB5CiAgICB2aXN1YWxpemFjacOzbiwgY29uIHVuYSBzaW50YXhpcyBjbGFyYSBwYXJhIGFuw6FsaXNpcyBpbmZlcmVuY2lhbCB5CiAgICB1bmEgYW1wbGlhIGNvbXVuaWRhZCBlbiBiaW9lc3RhZMOtc3RpY2EuCi0gICAqKlZlbnRhamFzOioqCiAgICAtICAgUGFxdWV0ZXMgZXNwZWNpYWxpemFkb3MgcGFyYSBzYWx1ZCAoZS5nLiwgc3Vydml2YWwsIGVwaVIpLgogICAgLSAgIFZpc3VhbGl6YWNpw7NuIGF2YW56YWRhIGNvbiBnZ3Bsb3QyLgogICAgLSAgIEludGVncmFjacOzbiBjb24gUiBNYXJrZG93biBwYXJhIGluZm9ybWVzIHJlcHJvZHVjaWJsZXMuCi0gICAqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIFJlYWxpemFyIEFOT1ZBIHBhcmEgY29tcGFyYXIgdHJhdGFtaWVudG9zLAogICAgYWp1c3RhciBtb2RlbG9zIGRlIHJlZ3Jlc2nDs24gbG9nw61zdGljYSBwYXJhIHByZWRlY2lyIHJlc3VsdGFkb3MKICAgIGNsw61uaWNvcyBvIGFuYWxpemFyIHNlcmllcyB0ZW1wb3JhbGVzIGRlIGNhc29zIGRlIGVuZmVybWVkYWRlcy4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogRW4gdW4gZW5zYXlvIGNsw61uaWNvIGNvbiAxMDAgcGFjaWVudGVzLCBzZSB1c2EKICAgIFIgcGFyYSByZWFsaXphciB1bmEgcHJ1ZWJhIHQgcGFyZWFkYQogICAgKGB0LnRlc3QoZGF0b3MkYW50ZXMsIGRhdG9zJGRlc3B1ZXMsIHBhaXJlZD1UUlVFKWApIHBhcmEgZXZhbHVhciBlbAogICAgY2FtYmlvIGVuIHByZXNpw7NuIGFydGVyaWFsIHRyYXMgdW4gdHJhdGFtaWVudG8sIG9idGVuaWVuZG8gdW4gdmFsb3IKICAgIHAgZGUgMC4wMywgaW5kaWNhbmRvIHNpZ25pZmljYW5jaWEuCgoqKlB5dGhvbjoqKgoKLSAgICoqQ2FyYWN0ZXLDrXN0aWNhczoqKiBMZW5ndWFqZSB2ZXJzw6F0aWwgY29uIGJpYmxpb3RlY2FzIHJvYnVzdGFzIHBhcmEKICAgIGVzdGFkw61zdGljYSwgYXByZW5kaXphamUgYXV0b23DoXRpY28geSBtYW5lam8gZGUgZGF0b3MuCi0gICAqKlZlbnRhamFzOioqCiAgICAtICAgSW50ZWdyYWNpw7NuIGNvbiBiYXNlcyBkZSBkYXRvcyB5IGhlcnJhbWllbnRhcyBkZSBiaWcgZGF0YS4KICAgIC0gICBTaW50YXhpcyBpbnR1aXRpdmEgcGFyYSBwcm9ncmFtYWRvcmVzIG5vIGVzdGFkw61zdGljb3MuCiAgICAtICAgQ29tdW5pZGFkIGVuIGV4cGFuc2nDs24gZW4gc2FsdWQgKGUuZy4sIGFuw6FsaXNpcyBkZSBkYXRvcwogICAgICAgIGdlbsOzbWljb3MpLgotICAgKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBBanVzdGFyIG1vZGVsb3MgbGluZWFsZXMgcGFyYSBwcmVkZWNpcgogICAgYmlvbWFyY2Fkb3JlcywgcmVhbGl6YXIgcHJ1ZWJhcyBubyBwYXJhbcOpdHJpY2FzIG8gc2ltdWxhciBlc2NlbmFyaW9zCiAgICBjbMOtbmljb3MuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuIGVzdHVkaW8gZGUgZGlhYmV0ZXMsIHNlIHVzYSBQeXRob24KICAgIChgc3RhdHNtb2RlbHMuYXBpLk9MU2ApIHBhcmEgYWp1c3RhciB1bmEgcmVncmVzacOzbiBsaW5lYWwgcXVlCiAgICBwcmVkaWNlIGdsdWNvc2EgZW4gc2FuZ3JlIGEgcGFydGlyIGRlbCBJTUMgeSBsYSBlZGFkLCBjb24gdW4KICAgICRSXjIgPSAwLjY1JC4KCioqQ29tcGFyYWNpw7NuOioqCgotICAgUiBlcyBwcmVmZXJpZG8gcGFyYSBhbsOhbGlzaXMgZXN0YWTDrXN0aWNvcyBwdXJvcyB5IHZpc3VhbGl6YWNpw7NuCiAgICBhdmFuemFkYSBlbiBzYWx1ZC4KLSAgIFB5dGhvbiBlcyBpZGVhbCBwYXJhIHBpcGVsaW5lcyBkZSBkYXRvcyBjb21wbGVqb3MgeSBhcGxpY2FjaW9uZXMKICAgIGludGVncmFkYXMgY29uIG1hY2hpbmUgbGVhcm5pbmcuCi0gICBBbWJvcyBzb24gY29tcGxlbWVudGFyaW9zIHkgcHVlZGVuIHVzYXJzZSBqdW50b3MgKGUuZy4sIHJweTIgcGFyYQogICAgZWplY3V0YXIgUiBkZXNkZSBQeXRob24pLgoKIyMjIFBhcXVldGVzIFJlbGV2YW50ZXM6IHN0YXRzbW9kZWxzLCBzY2lweSwgdGlkeXZlcnNlCgoqKlI6IHRpZHl2ZXJzZToqKgoKLSAgICoqRGVzY3JpcGNpw7NuOioqIENvbGVjY2nDs24gZGUgcGFxdWV0ZXMgKGUuZy4sIGRwbHlyLCB0aWR5ciwgZ2dwbG90MikKICAgIHBhcmEgbWFuaXB1bGFjacOzbiwgbGltcGllemEgeSB2aXN1YWxpemFjacOzbiBkZSBkYXRvcy4KLSAgICoqRnVuY2lvbmVzIGNsYXZlOioqCiAgICAtICAgYGRwbHlyYDogTWFuaXB1bGFjacOzbiBkZSBkYXRvcyAoYGZpbHRlcmAsIGBncm91cF9ieWAsCiAgICAgICAgYHN1bW1hcmlzZWApLgogICAgLSAgIGB0aWR5cmA6IFJlZXN0cnVjdHVyYWNpw7NuIGRlIGRhdG9zIChgcGl2b3RfbG9uZ2VyYCwKICAgICAgICBgcGl2b3Rfd2lkZXJgKS4KICAgIC0gICBgZ2dwbG90MmA6IFZpc3VhbGl6YWNpw7NuIGF2YW56YWRhICh2ZXIgc2VjY2nDs24gMTAuMykuCi0gICAqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIFJlc3VtaXIgZGF0b3MgZGUgZW5zYXlvcyBjbMOtbmljb3MsIGNhbGN1bGFyCiAgICBtZWRpYXMgcG9yIGdydXBvIGRlIHRyYXRhbWllbnRvIHkgZ2VuZXJhciBncsOhZmljb3MgZGUgYm94cGxvdHMuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuIGVzdHVkaW8gZGUgaGlwZXJ0ZW5zacOzbiwgc2UgdXNhIGRwbHlyCiAgICBwYXJhIGNhbGN1bGFyIGxhIG1lZGlhIGRlIHByZXNpw7NuIGFydGVyaWFsIHBvciBncnVwbwogICAgKGBkYXRvcyAlPiUgZ3JvdXBfYnkodHJhdGFtaWVudG8pICU+JSBzdW1tYXJpc2UobWVhbl9wYSA9IG1lYW4ocHJlc2lvbikpYCksCiAgICByZXZlbGFuZG8gZGlmZXJlbmNpYXMgc2lnbmlmaWNhdGl2YXMgZW50cmUgZsOhcm1hY28geSBwbGFjZWJvLgoKKipQeXRob246IHN0YXRzbW9kZWxzOioqCgotICAgKipEZXNjcmlwY2nDs246KiogQmlibGlvdGVjYSBwYXJhIG1vZGVsb3MgZXN0YWTDrXN0aWNvcywgaW5jbHV5ZW5kbwogICAgcmVncmVzacOzbiBsaW5lYWwsIGxvZ8Otc3RpY2EsIEFOT1ZBIHkgcHJ1ZWJhcyBkZSBoaXDDs3Rlc2lzLgotICAgKipGdW5jaW9uZXMgY2xhdmU6KioKICAgIC0gICBgc3RhdHNtb2RlbHMuZm9ybXVsYS5hcGkub2xzYDogUmVncmVzacOzbiBsaW5lYWwuCiAgICAtICAgYHN0YXRzbW9kZWxzLnN0YXRzLmFub3ZhX2xtYDogQU5PVkEuCiAgICAtICAgYHN0YXRzbW9kZWxzLmdsbWA6IE1vZGVsb3MgbGluZWFsZXMgZ2VuZXJhbGl6YWRvcy4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogQWp1c3RhciB1biBtb2RlbG8gbG9nw61zdGljbyBwYXJhIHByZWRlY2lyCiAgICBsYSBwcmVzZW5jaWEgZGUgZGlhYmV0ZXMgYmFzw6FuZG9zZSBlbiBJTUMgeSBnbHVjb3NhIGJhc2FsLgotICAgKipFamVtcGxvIHByw6FjdGljbzoqKiBFbiB1biBkYXRhc2V0IGRlIDUwMCBwYWNpZW50ZXMsCiAgICBgc21mLmdsbSgnZGlhYmV0ZXMgfiBJTUMgKyBnbHVjb3NhJywgZmFtaWx5PXNtLmZhbWlsaWVzLkJpbm9taWFsKCkpLmZpdCgpYAogICAgZXN0aW1hIG9kZHMgcmF0aW9zIHNpZ25pZmljYXRpdm9zIHBhcmEgYW1ib3MgcHJlZGljdG9yZXMKICAgICgkcCA8IDAuMDEkKS4KCioqUHl0aG9uOiBzY2lweToqKgoKLSAgICoqRGVzY3JpcGNpw7NuOioqIEJpYmxpb3RlY2EgcGFyYSBjw6FsY3Vsb3MgZXN0YWTDrXN0aWNvcyB5CiAgICBjaWVudMOtZmljb3MsIGNvbiBmdW5jaW9uZXMgcGFyYSBwcnVlYmFzIGRlIGhpcMOzdGVzaXMsIGRpc3RyaWJ1Y2lvbmVzCiAgICB5IG9wdGltaXphY2nDs24uCi0gICAqKkZ1bmNpb25lcyBjbGF2ZToqKgogICAgLSAgIGBzY2lweS5zdGF0cy50dGVzdF9pbmRgOiBQcnVlYmEgdCBwYXJhIGRvcyBncnVwb3MuCiAgICAtICAgYHNjaXB5LnN0YXRzLm1hbm53aGl0bmV5dWA6IFBydWViYSBubyBwYXJhbcOpdHJpY2EgZGUKICAgICAgICBNYW5uLVdoaXRuZXkuCiAgICAtICAgYHNjaXB5LnN0YXRzLm5vcm1gOiBEaXN0cmlidWNpb25lcyBwYXJhIHNpbXVsYWNpb25lcy4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogUmVhbGl6YXIgcHJ1ZWJhcyBubyBwYXJhbcOpdHJpY2FzIHBhcmEKICAgIGNvbXBhcmFyIHRpZW1wb3MgZGUgcmVjdXBlcmFjacOzbiBlbnRyZSB0cmF0YW1pZW50b3MuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuIGVzdHVkaW8gZGUgcmVjdXBlcmFjacOzbiBwb3N0cXVpcsO6cmdpY2EsCiAgICBgc2NpcHkuc3RhdHMubWFubndoaXRuZXl1KGdydXBvMSwgZ3J1cG8yKWAgZGEgdW4gdmFsb3IgcCBkZSAwLjA0LAogICAgaW5kaWNhbmRvIGRpZmVyZW5jaWFzIGVudHJlIGRvcyB0cmF0YW1pZW50b3MuCgoqKkludGVncmFjacOzbjoqKiBDb21iaW5hciB0aWR5dmVyc2UgcGFyYSBsaW1waWV6YSBkZSBkYXRvcywgc3RhdHNtb2RlbHMKcGFyYSBtb2RlbGFkbyB5IHNjaXB5IHBhcmEgcHJ1ZWJhcyBlc3BlY8OtZmljYXMgZW4gcGlwZWxpbmVzIGRlIGFuw6FsaXNpcy4KCiMjIDEwLjIgU2ltdWxhY2nDs24geSBCb290c3RyYXAKCiMjIyBNw6l0b2RvcyBkZSBSZW11ZXN0cmVvCgpMb3MgbcOpdG9kb3MgZGUgcmVtdWVzdHJlbywgY29tbyBlbCBib290c3RyYXAsIGdlbmVyYW4gZGlzdHJpYnVjaW9uZXMKZW1ww61yaWNhcyBkZSBlc3RhZMOtc3RpY29zIHNpbiBhc3VtaXIgZGlzdHJpYnVjaW9uZXMgdGXDs3JpY2FzLCBzaWVuZG8Kw7p0aWxlcyBlbiBzYWx1ZCBwYXJhIGRhdG9zIGNvbiBkaXN0cmlidWNpb25lcyBubyBub3JtYWxlcyBvIG11ZXN0cmFzCnBlcXVlw7Fhcy4KCioqQm9vdHN0cmFwOioqCgotICAgKipEZWZpbmljacOzbjoqKiBSZW11ZXN0cmVvIGNvbiByZWVtcGxhem8gZGUgbG9zIGRhdG9zIG9yaWdpbmFsZXMKICAgIHBhcmEgZXN0aW1hciBsYSBkaXN0cmlidWNpw7NuIGRlIHVuIGVzdGFkw61zdGljbyAoZS5nLiwgbWVkaWEsCiAgICBkaWZlcmVuY2lhIGRlIG1lZGlhcykuCi0gICAqKkFsZ29yaXRtbzoqKgogICAgMS4gIFRvbWFyICRCJCBtdWVzdHJhcyBjb24gcmVlbXBsYXpvIGRlbCB0YW1hw7FvIG9yaWdpbmFsICgkbiQpLgogICAgMi4gIENhbGN1bGFyIGVsIGVzdGFkw61zdGljbyBkZSBpbnRlcsOpcyBlbiBjYWRhIG11ZXN0cmEgKGUuZy4sIG1lZGlhLAogICAgICAgIG1lZGlhbmEpLgogICAgMy4gIFVzYXIgbGEgZGlzdHJpYnVjacOzbiBkZSBsb3MgZXN0YWTDrXN0aWNvcyBwYXJhIGVzdGltYWNpb25lcyBvCiAgICAgICAgaW50ZXJ2YWxvcy4KLSAgICoqVGlwb3M6KioKICAgIC0gICAqKk5vIHBhcmFtw6l0cmljbzoqKiBSZW11ZXN0cmVhIGRpcmVjdGFtZW50ZSBsb3MgZGF0b3MKICAgICAgICBvYnNlcnZhZG9zLgogICAgLSAgICoqUGFyYW3DqXRyaWNvOioqIEFqdXN0YSB1biBtb2RlbG8geSBzaW11bGEgZGF0b3MgYSBwYXJ0aXIgZGUgw6lsLgotICAgKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBFc3RpbWFyIGxhIGluY2VydGlkdW1icmUgZW4gbGEgdGFzYSBkZQogICAgcmVzcHVlc3RhIGEgdW4gdHJhdGFtaWVudG8gY3VhbmRvIGxhIG11ZXN0cmEgZXMgcGVxdWXDsWEuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuIGVuc2F5byBjb24gMzAgcGFjaWVudGVzLCBzZSBjYWxjdWxhIGxhCiAgICBkaWZlcmVuY2lhIG1lZGlhIGVuIHByZXNpw7NuIGFydGVyaWFsICh0cmF0YW1pZW50byB2cy4gcGxhY2VibykKICAgIHVzYW5kbyAxMDAwIG11ZXN0cmFzIGJvb3RzdHJhcC4gTGEgbWVkaWEgYm9vdHN0cmFwIGVzIDUgbW1IZywgY29uIHVuCiAgICBpbnRlcnZhbG8gZGUgY29uZmlhbnphIGRlbCA5NSUgZGUgWzIsIDhdIG1tSGcuCgoqKlNpbXVsYWNpw7NuOioqCgotICAgKipEZWZpbmljacOzbjoqKiBHZW5lcmFyIGRhdG9zIHNpbnTDqXRpY29zIGJhc2Fkb3MgZW4gdW4gbW9kZWxvCiAgICBwcm9iYWJpbMOtc3RpY28gcGFyYSBldmFsdWFyIGVzY2VuYXJpb3MgbyBwcm9waWVkYWRlcyBlc3RhZMOtc3RpY2FzLgotICAgKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBTaW11bGFyIHRhc2FzIGRlIGluZmVjY2nDs24gYmFqbyBkaWZlcmVudGVzCiAgICBpbnRlcnZlbmNpb25lcyBwYXJhIHBsYW5pZmljYXIgcmVjdXJzb3MgaG9zcGl0YWxhcmlvcy4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogU2ltdWxhciAxMDAwIGVuc2F5b3MgY2zDrW5pY29zIGNvbiB1bmEgdGFzYSBkZQogICAgw6l4aXRvIGRlbCA3MCUgKGBudW1weS5yYW5kb20uYmlub21pYWxgKSBwYXJhIGVzdGltYXIgbGEgcG90ZW5jaWEgZGUKICAgIHVuIGRpc2XDsW8gZXhwZXJpbWVudGFsLgoKIyMjIEFwbGljYWNpb25lcyBlbiBJbnRlcnZhbG9zIGRlIENvbmZpYW56YSB5IFBydWViYXMKCioqSW50ZXJ2YWxvcyBkZSBjb25maWFuemEgKElDKToqKgoKLSAgICoqQm9vdHN0cmFwIHBlcmNlbnRpbDoqKiBVc2FyIGxvcyBwZXJjZW50aWxlcyAyLjUlIHkgOTcuNSUgZGUgbGEKICAgIGRpc3RyaWJ1Y2nDs24gYm9vdHN0cmFwIHBhcmEgdW4gSUMgYWwgOTUlLgotICAgKipCb290c3RyYXAgQkNhIChCaWFzLUNvcnJlY3RlZCBhbmQgQWNjZWxlcmF0ZWQpOioqIENvcnJpZ2Ugc2VzZ29zIHkKICAgIGFzaW1ldHLDrWFzLCBpZGVhbCBwYXJhIGRhdG9zIG5vIG5vcm1hbGVzLgotICAgKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBFc3RpbWFyIHVuIElDIHBhcmEgbGEgZGlmZXJlbmNpYSBlbiB0YXNhcwogICAgZGUgcmVjdXBlcmFjacOzbiBlbnRyZSBkb3MgdHJhdGFtaWVudG9zLgotICAgKipFamVtcGxvIHByw6FjdGljbzoqKiBFbiB1biBlc3R1ZGlvIGRlIDUwIHBhY2llbnRlcyBwb3IgZ3J1cG8sIGVsCiAgICBib290c3RyYXAgbm8gcGFyYW3DqXRyaWNvIGNhbGN1bGEgdW4gSUMgYWwgOTUlIHBhcmEgbGEgZGlmZXJlbmNpYSBlbgogICAgdGFzYXMgZGUgcmVjdXBlcmFjacOzbiAoWzAuMDUsIDAuMjVdKSwgaW5kaWNhbmRvIHVuIGVmZWN0bwogICAgc2lnbmlmaWNhdGl2byBkZWwgdHJhdGFtaWVudG8uCgoqKlBydWViYXMgZGUgaGlww7N0ZXNpczoqKgoKLSAgICoqQm9vdHN0cmFwIHBhcmEgcHJ1ZWJhczoqKiBDb21wYXJhciB1biBlc3RhZMOtc3RpY28gb2JzZXJ2YWRvIGNvbiBzdQogICAgZGlzdHJpYnVjacOzbiBib290c3RyYXAgYmFqbyAkSF8wJC4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogUHJvYmFyIHNpIGxhIGRpZmVyZW5jaWEgZW4gbWVkaWFzIGRlCiAgICBnbHVjb3NhIGVudHJlIGRvcyBncnVwb3MgZXMgc2lnbmlmaWNhdGl2YSBzaW4gYXN1bWlyIG5vcm1hbGlkYWQuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuIGVzdHVkaW8gZGUgZGlhYmV0ZXMsIHNlIHVzYSBib290c3RyYXAKICAgIHBhcmEgY29tcGFyYXIgbWVkaWFzIGRlIEhiQTFjIGVudHJlIGdydXBvcywgZ2VuZXJhbmRvIDUwMDAgbXVlc3RyYXMKICAgIGJham8gJEhfMDogXG11XzEgPSBcbXVfMiQuIEVsIHZhbG9yIHAgYm9vdHN0cmFwIGVzIDAuMDIsIHJlY2hhemFuZG8KICAgICRIXzAkLgoKKipWZW50YWphczoqKgoKLSAgIE5vIHJlcXVpZXJlIHN1cHVlc3RvcyBkZSBub3JtYWxpZGFkLgotICAgw5p0aWwgcGFyYSBtdWVzdHJhcyBwZXF1ZcOxYXMgbyBkaXN0cmlidWNpb25lcyBkZXNjb25vY2lkYXMuCgoqKkxpbWl0YWNpb25lczoqKgoKLSAgIENvbXB1dGFjaW9uYWxtZW50ZSBpbnRlbnNpdm8uCi0gICBEZXBlbmRlIGRlIGxhIHJlcHJlc2VudGF0aXZpZGFkIGRlIGxhIG11ZXN0cmEgb3JpZ2luYWwuCgojIyAxMC4zIFZpc3VhbGl6YWNpw7NuIGRlIERhdG9zCgojIyMgR3LDoWZpY29zIHBhcmEgSW5mZXJlbmNpYTogQm94cGxvdHMsIFEtUSBQbG90cywgSGlzdG9ncmFtYXMKCkxhIHZpc3VhbGl6YWNpw7NuIGRlIGRhdG9zIGVzIGNydWNpYWwgcGFyYSBleHBsb3JhciBkaXN0cmlidWNpb25lcywKZGV0ZWN0YXIgYW5vbWFsw61hcyB5IGNvbXVuaWNhciByZXN1bHRhZG9zIGluZmVyZW5jaWFsZXMgZW4gc2FsdWQuIExvcwpncsOhZmljb3MgZXNwZWPDrWZpY29zIGFwb3lhbiBsYSB2YWxpZGFjacOzbiBkZSBzdXB1ZXN0b3MgeSBsYQppbnRlcnByZXRhY2nDs24gZGUgcmVzdWx0YWRvcy4KCioqQm94cGxvdHM6KioKCi0gICAqKlByb3DDs3NpdG86KiogTW9zdHJhciBkaXN0cmlidWNpw7NuLCBtZWRpYW5hLCBjdWFydGlsZXMgeSB2YWxvcmVzCiAgICBhdMOtcGljb3MuCi0gICAqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIENvbXBhcmFyIG5pdmVsZXMgZGUgY29sZXN0ZXJvbCBlbnRyZSBncnVwb3MKICAgIGRlIHRyYXRhbWllbnRvLgotICAgKipFamVtcGxvIHByw6FjdGljbzoqKiBVbiBib3hwbG90IChgZ2dwbG90Mjo6Z2VvbV9ib3hwbG90YCkgbXVlc3RyYQogICAgcXVlIGVsIGdydXBvIHRyYXRhZG8gdGllbmUgdW5hIG1lZGlhbmEgZGUgY29sZXN0ZXJvbCBkZSAxNTAgbWcvZEwKICAgIGZyZW50ZSBhIDE4MCBtZy9kTCBlbiBlbCBwbGFjZWJvLCBjb24gdmFsb3JlcyBhdMOtcGljb3MgZW4gYW1ib3MKICAgIGdydXBvcywgc3VnaXJpZW5kbyBsYSBuZWNlc2lkYWQgZGUgcHJ1ZWJhcyBubyBwYXJhbcOpdHJpY2FzLgoKKipRLVEgUGxvdHM6KioKCi0gICAqKlByb3DDs3NpdG86KiogRXZhbHVhciBzaSBsb3MgZGF0b3Mgc2lndWVuIHVuYSBkaXN0cmlidWNpw7NuIG5vcm1hbAogICAgY29tcGFyYW5kbyBjdWFudGlsZXMgb2JzZXJ2YWRvcyBjb24gY3VhbnRpbGVzIHRlw7NyaWNvcy4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogVmVyaWZpY2FyIGxhIG5vcm1hbGlkYWQgZGUgcmVzaWR1b3MgZW4gdW4KICAgIG1vZGVsbyBkZSByZWdyZXNpw7NuIHBhcmEgZ2x1Y29zYS4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogVW4gUS1RIHBsb3QKICAgIChgc3RhdHNtb2RlbHMuZ3JhcGhpY3MuZ29mcGxvdHMucXFwbG90YCkgZGUgcmVzaWR1b3MgZGUgdW4gbW9kZWxvCiAgICBsaW5lYWwgbXVlc3RyYSBwdW50b3MgYWxpbmVhZG9zIGNvbiBsYSBsw61uZWEgZGUgNDXCsCwgY29uZmlybWFuZG8KICAgIG5vcm1hbGlkYWQgKCRwID0gMC43JCBlbiBTaGFwaXJvLVdpbGspLgoKKipIaXN0b2dyYW1hczoqKgoKLSAgICoqUHJvcMOzc2l0bzoqKiBWaXN1YWxpemFyIGxhIGRpc3RyaWJ1Y2nDs24gZGUgdW5hIHZhcmlhYmxlIGNvbnRpbnVhLAogICAgZGV0ZWN0YW5kbyBzZXNnb3MgbyBtdWx0aW1vZGFsaWRhZC4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogQW5hbGl6YXIgbGEgZGlzdHJpYnVjacOzbiBkZSB0aWVtcG9zIGRlCiAgICByZWN1cGVyYWNpw7NuIHBvc3RxdWlyw7pyZ2ljYS4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogVW4gaGlzdG9ncmFtYSAoYHNlYWJvcm4uaGlzdHBsb3RgKSBkZSB0aWVtcG9zCiAgICBkZSByZWN1cGVyYWNpw7NuIG11ZXN0cmEgdW4gc2VzZ28gcG9zaXRpdm8sIHN1Z2lyaWVuZG8gdW5hCiAgICB0cmFuc2Zvcm1hY2nDs24gbG9nYXLDrXRtaWNhIGFudGVzIGRlIHVuIGFuw6FsaXNpcyBwYXJhbcOpdHJpY28uCgojIyMgSGVycmFtaWVudGFzIGNvbW8gZ2dwbG90MiB5IHNlYWJvcm4KCioqZ2dwbG90MiAoUik6KioKCi0gICAqKkRlc2NyaXBjacOzbjoqKiBQYXF1ZXRlIGJhc2FkbyBlbiBsYSBncmFtw6F0aWNhIGRlIGdyw6FmaWNvcyBwYXJhCiAgICBjcmVhciB2aXN1YWxpemFjaW9uZXMgcGVyc29uYWxpemFibGVzIHkgZXN0w6l0aWNhcy4KLSAgICoqRnVuY2lvbmVzIGNsYXZlOioqCiAgICAtICAgYGdlb21fYm94cGxvdCgpYDogQm94cGxvdHMgcGFyYSBjb21wYXJhciBncnVwb3MuCiAgICAtICAgYGdlb21faGlzdG9ncmFtKClgOiBIaXN0b2dyYW1hcyBwYXJhIGRpc3RyaWJ1Y2lvbmVzLgogICAgLSAgIGBnZW9tX3BvaW50KCkgKyBnZW9tX3Ntb290aCgpYDogR3LDoWZpY29zIGRlIGRpc3BlcnNpw7NuIGNvbgogICAgICAgIGzDrW5lYXMgZGUgcmVncmVzacOzbi4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogVmlzdWFsaXphciBsYSByZWxhY2nDs24gZW50cmUgSU1DIHkgZ2x1Y29zYQogICAgY29uIHVuIGdyw6FmaWNvIGRlIGRpc3BlcnNpw7NuIHkgY3VydmEgZGUgcmVncmVzacOzbi4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogRW4gdW4gZXN0dWRpbyBkZSBkaWFiZXRlcywKICAgIGBnZ3Bsb3QoZGF0b3MsIGFlcyh4PUlNQywgeT1nbHVjb3NhKSkgKyBnZW9tX3BvaW50KCkgKyBnZW9tX3Ntb290aChtZXRob2Q9ImxtIilgCiAgICBtdWVzdHJhIHVuYSByZWxhY2nDs24gcG9zaXRpdmEgKCRcYmV0YV8xID0gMi41JCwgJHAgPCAwLjAxJCkuCgoqKnNlYWJvcm4gKFB5dGhvbik6KioKCi0gICAqKkRlc2NyaXBjacOzbjoqKiBCaWJsaW90ZWNhIGJhc2FkYSBlbiBNYXRwbG90bGliLCBvcHRpbWl6YWRhIHBhcmEKICAgIHZpc3VhbGl6YWNpb25lcyBlc3RhZMOtc3RpY2FzIGNvbiBzaW50YXhpcyBzaW1wbGUuCi0gICAqKkZ1bmNpb25lcyBjbGF2ZToqKgogICAgLSAgIGBzZWFib3JuLmJveHBsb3QoKWA6IEJveHBsb3RzIHBhcmEgY29tcGFyYWNpb25lcyBncnVwYWxlcy4KICAgIC0gICBgc2VhYm9ybi5oaXN0cGxvdCgpYDogSGlzdG9ncmFtYXMgY29uIGVzdGltYWNpw7NuIGRlIGRlbnNpZGFkLgogICAgLSAgIGBzZWFib3JuLnJlZ3Bsb3QoKWA6IEdyw6FmaWNvcyBkZSByZWdyZXNpw7NuLgotICAgKipBcGxpY2FjacOzbiBlbiBzYWx1ZDoqKiBDb21wYXJhciBkaXN0cmlidWNpb25lcyBkZSBwcmVzacOzbiBhcnRlcmlhbAogICAgZW50cmUgZ3J1cG9zIGNvbiBib3hwbG90cyBvIHZpc3VhbGl6YXIgY29ycmVsYWNpb25lcyBlbnRyZQogICAgYmlvbWFyY2Fkb3Jlcy4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogRW4gdW4gZXN0dWRpbyBjYXJkaW92YXNjdWxhciwKICAgIGBzZWFib3JuLmJveHBsb3QoeD0idHJhdGFtaWVudG8iLCB5PSJwcmVzaW9uIiwgZGF0YT1kYXRvcylgIG11ZXN0cmEKICAgIGRpZmVyZW5jaWFzIGNsYXJhcyBlbnRyZSBncnVwb3MsIGNvbmZpcm1hZGFzIHBvciBBTk9WQSAoJHAgPSAwLjAxJCkuCgoqKk90cmFzIGhlcnJhbWllbnRhczoqKgoKLSAgICoqTWF0cGxvdGxpYiAoUHl0aG9uKToqKiBQYXJhIGdyw6FmaWNvcyBwZXJzb25hbGl6YWRvcywgw7p0aWwgZW4KICAgIHBpcGVsaW5lcyBjb21wbGVqb3MuCi0gICAqKlBsb3RseSAoUi9QeXRob24pOioqIEdyw6FmaWNvcyBpbnRlcmFjdGl2b3MgcGFyYSBwcmVzZW50YWNpb25lcyBvCiAgICBkYXNoYm9hcmRzIGVuIHNhbHVkLgotICAgKipFamVtcGxvIHByw6FjdGljbzoqKiBVbiBkYXNoYm9hcmQgaW50ZXJhY3Rpdm8gY29uIHBsb3RseSBtdWVzdHJhCiAgICB0YXNhcyBkZSBob3NwaXRhbGl6YWNpw7NuIHBvciBDT1ZJRC0xOSwgcGVybWl0aWVuZG8gZXhwbG9yYXIKICAgIHRlbmRlbmNpYXMgcG9yIHJlZ2nDs24uCgojIyBSZWN1cnNvcyBwYXJhIGVsIEF1dG9lc3R1ZGlvIGVuIFNhbHVkCgojIyMgTGVjdHVyYXM6CgotICAgIlIgZm9yIERhdGEgU2NpZW5jZSIgZGUgV2lja2hhbSB5IEdyb2xlbXVuZCAoQ2Fww610dWxvcyBzb2JyZQogICAgdGlkeXZlcnNlLCBnZ3Bsb3QyKS4KLSAgICJQeXRob24gZm9yIERhdGEgQW5hbHlzaXMiIGRlIE1jS2lubmV5IChDYXDDrXR1bG9zIHNvYnJlIHN0YXRzbW9kZWxzLAogICAgc2NpcHkpLgotICAgIlRoZSBWaXN1YWwgRGlzcGxheSBvZiBRdWFudGl0YXRpdmUgSW5mb3JtYXRpb24iIGRlIFR1ZnRlCiAgICAocHJpbmNpcGlvcyBkZSB2aXN1YWxpemFjacOzbikuCi0gICAiQmlvc3RhdGlzdGljczogQSBGb3VuZGF0aW9uIGZvciBBbmFseXNpcyBpbiB0aGUgSGVhbHRoIFNjaWVuY2VzIiBkZQogICAgRGFuaWVsIChDYXDDrXR1bG9zIHNvYnJlIHNvZnR3YXJlIHkgdmlzdWFsaXphY2nDs24pLgoKIyMjIEVqZXJjaWNpb3MgcHLDoWN0aWNvczoKCi0gICBVc2FyIFIgKHRpZHl2ZXJzZSkgcGFyYSBsaW1waWFyIHkgYW5hbGl6YXIgZGF0b3MgZGUgZW5zYXlvcwogICAgY2zDrW5pY29zLCBhcGxpY2FuZG8gcHJ1ZWJhcyB0IHkgQU5PVkEuCi0gICBJbXBsZW1lbnRhciBib290c3RyYXAgZW4gUHl0aG9uIChgbnVtcHkucmFuZG9tLmNob2ljZWApIHBhcmEgZXN0aW1hcgogICAgSUMgZGUgdGFzYXMgZGUgcmVzcHVlc3RhLgotICAgQ3JlYXIgYm94cGxvdHMgeSBRLVEgcGxvdHMgY29uIGdncGxvdDIgbyBzZWFib3JuIHBhcmEgdmVyaWZpY2FyCiAgICBzdXB1ZXN0b3MgZW4gbW9kZWxvcyBkZSByZWdyZXNpw7NuLgotICAgU2ltdWxhciBkYXRvcyBjbMOtbmljb3MgY29uIGRpc3RyaWJ1Y2lvbmVzIGJpbm9taWFsZXMgbyBub3JtYWxlcyBwYXJhCiAgICBldmFsdWFyIGRpc2XDsW9zIGV4cGVyaW1lbnRhbGVzLgoKIyMjIEhlcnJhbWllbnRhcyBjb21wdXRhY2lvbmFsZXM6CgotICAgKipSOioqIFBhcXVldGVzIGB0aWR5dmVyc2VgIChkcGx5ciwgZ2dwbG90MiksIGBib290YCAoYm9vdHN0cmFwKSwKICAgIGBzdGF0c2AgKHBydWViYXMgaW5mZXJlbmNpYWxlcykuCiAgICAtICAgKipFamVtcGxvOioqIGBib290KGRhdGEsIHN0YXRpc3RpYz1tZWFuLCBSPTEwMDApYCBwYXJhIGJvb3RzdHJhcAogICAgICAgIGRlIGxhIG1lZGlhOwogICAgICAgIGBnZ3Bsb3QoZGF0b3MsIGFlcyh4PXRyYXRhbWllbnRvLCB5PWNvbGVzdGVyb2wpKSArIGdlb21fYm94cGxvdCgpYC4KLSAgICoqUHl0aG9uOioqIEJpYmxpb3RlY2FzIGBzdGF0c21vZGVsc2AsIGBzY2lweWAsIGBzZWFib3JuYCwgYG51bXB5YAogICAgKHNpbXVsYWNpw7NuKS4KICAgIC0gICAqKkVqZW1wbG86KioKICAgICAgICBgbnVtcHkucmFuZG9tLmNob2ljZShkYXRvcywgc2l6ZT0oMTAwMCwgbGVuKGRhdG9zKSksIHJlcGxhY2U9VHJ1ZSlgCiAgICAgICAgcGFyYSBib290c3RyYXA7IGBzZWFib3JuLmhpc3RwbG90KGRhdG9zWydnbHVjb3NhJ10sIGtkZT1UcnVlKWAuCgojIyMgQmFzZXMgZGUgZGF0b3M6CgotICAgTkhBTkVTIHBhcmEgZGF0b3MgZGUgYmlvbWFyY2Fkb3JlcyAoZS5nLiwgY29sZXN0ZXJvbCwgZ2x1Y29zYSkuCi0gICBDbGluaWNhbFRyaWFscy5nb3YgcGFyYSBkYXRvcyBkZSBlbnNheW9zIGNsw61uaWNvcy4KLSAgIFdITyBHbG9iYWwgSGVhbHRoIE9ic2VydmF0b3J5IHBhcmEgZGF0b3MgZXBpZGVtaW9sw7NnaWNvcyAoZS5nLiwKICAgIHRhc2FzIGRlIGRpYWJldGVzKS4KCiMgVGFibGEgUmVzdW1lbjogSGVycmFtaWVudGFzIENvbXB1dGFjaW9uYWxlcyBlbiBFc3RhZMOtc3RpY2EgSW5mZXJlbmNpYWwgZW4gU2FsdWQKCmBgYHtyIHRvb2xzLXRhYmxlLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdhc2lzJywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShrbml0cikKbGlicmFyeShrYWJsZUV4dHJhKQoKIyBDcmVhciBsYSB0YWJsYQp0YWJsYV90b29scyA8LSBkYXRhLmZyYW1lKAogICJIZXJyYW1pZW50YSBvIFTDqWNuaWNhIiA9IGMoCiAgICAiUiIsCiAgICAiUHl0aG9uIiwKICAgICJ0aWR5dmVyc2UgKFIpIiwKICAgICJzdGF0c21vZGVscyAoUHl0aG9uKSIsCiAgICAic2NpcHkgKFB5dGhvbikiLAogICAgIkJvb3RzdHJhcCAocmVtdWVzdHJlbykiLAogICAgIlNpbXVsYWNpw7NuIE1vbnRlIENhcmxvIiwKICAgICJCb3hwbG90IiwKICAgICJRLVEgUGxvdCIsCiAgICAiSGlzdG9ncmFtYSIsCiAgICAiZ2dwbG90MiAoUikiLAogICAgInNlYWJvcm4gKFB5dGhvbikiLAogICAgIlBsb3RseSAoUi9QeXRob24pIgogICksCiAgIlRpcG8gZGUgQW7DoWxpc2lzIiA9IGMoCiAgICAiQW7DoWxpc2lzIGVzdGFkw61zdGljbyB5IHZpc3VhbGl6YWNpw7NuIiwKICAgICJBbsOhbGlzaXMgZGUgZGF0b3MgeSBtb2RlbGFkbyIsCiAgICAiTWFuaXB1bGFjacOzbiB5IHZpc3VhbGl6YWNpw7NuIGRlIGRhdG9zIiwKICAgICJNb2RlbGFkbyBlc3RhZMOtc3RpY28gKHJlZ3Jlc2nDs24sIEFOT1ZBKSIsCiAgICAiUHJ1ZWJhcyBlc3RhZMOtc3RpY2FzIHkgZGlzdHJpYnVjaW9uZXMiLAogICAgIkVzdGltYWNpw7NuIGRlIGluY2VydGlkdW1icmUiLAogICAgIkV2YWx1YWNpw7NuIGRlIGVzY2VuYXJpb3MgeSBwb3RlbmNpYSIsCiAgICAiQ29tcGFyYWNpw7NuIGRlIGdydXBvcyIsCiAgICAiRXZhbHVhY2nDs24gZGUgbm9ybWFsaWRhZCIsCiAgICAiQW7DoWxpc2lzIGRlIGRpc3RyaWJ1Y2nDs24iLAogICAgIlZpc3VhbGl6YWNpw7NuIGF2YW56YWRhIiwKICAgICJWaXN1YWxpemFjacOzbiBlc3RhZMOtc3RpY2EiLAogICAgIlZpc3VhbGl6YWNpw7NuIGludGVyYWN0aXZhIgogICksCiAgIkZ1bmNpw7NuIFByaW5jaXBhbCIgPSBjKAogICAgIlJlYWxpemFyIHBydWViYXMgaW5mZXJlbmNpYWxlcywgbW9kZWxvcyB5IGdyw6FmaWNvcyIsCiAgICAiSW50ZWdyYXIgYW7DoWxpc2lzIGNvbiBiaWcgZGF0YSB5IG1hY2hpbmUgbGVhcm5pbmciLAogICAgIkxpbXBpYXIsIHRyYW5zZm9ybWFyIHkgdmlzdWFsaXphciBkYXRvcyIsCiAgICAiQWp1c3RhciBtb2RlbG9zIGxpbmVhbGVzIHkgR0xNIiwKICAgICJSZWFsaXphciBwcnVlYmFzIGRlIGhpcMOzdGVzaXMiLAogICAgIkVzdGltYXIgSUMgc2luIHN1cHVlc3RvcyBwYXJhbcOpdHJpY29zIiwKICAgICJHZW5lcmFyIGRhdG9zIHNpbnTDqXRpY29zIHBhcmEgZXZhbHVhY2nDs24iLAogICAgIk1vc3RyYXIgbWVkaWFuYSwgY3VhcnRpbGVzIHkgYXTDrXBpY29zIiwKICAgICJFdmFsdWFyIG5vcm1hbGlkYWQgY29tcGFyYW5kbyBjdWFudGlsZXMiLAogICAgIlZpc3VhbGl6YXIgZm9ybWEgZGUgbGEgZGlzdHJpYnVjacOzbiIsCiAgICAiQ3JlYXIgZ3LDoWZpY29zIHBlcnNvbmFsaXphYmxlcyBjb24gZ3JhbcOhdGljYSBkZSBncsOhZmljb3MiLAogICAgIkdyw6FmaWNvcyBlc3RhZMOtc3RpY29zIHNpbXBsZXMgeSBlbGVnYW50ZXMiLAogICAgIkdyw6FmaWNvcyBpbnRlcmFjdGl2b3MgcGFyYSBkYXNoYm9hcmRzIgogICksCiAgIkFwbGljYWNpw7NuIGVuIFNhbHVkIiA9IGMoCiAgICAiQU5PVkEsIHJlZ3Jlc2nDs24gbG9nw61zdGljYSwgYW7DoWxpc2lzIGRlIHN1cGVydml2ZW5jaWEiLAogICAgIk1vZGVsYWRvIHByZWRpY3Rpdm8sIGFuw6FsaXNpcyBnZW7Ds21pY28sIHBpcGVsaW5lcyBjbMOtbmljb3MiLAogICAgIlJlc3VtaXIgZGF0b3MgZGUgZW5zYXlvcywgY2FsY3VsYXIgbWVkaWFzIHBvciBncnVwbyIsCiAgICAiTW9kZWxhciByaWVzZ28gZGUgZGlhYmV0ZXMgY29uIHJlZ3Jlc2nDs24gbG9nw61zdGljYSIsCiAgICAiQ29tcGFyYXIgdGllbXBvcyBkZSByZWN1cGVyYWNpw7NuIGNvbiBNYW5uLVdoaXRuZXkiLAogICAgIkVzdGltYXIgSUMgcGFyYSB0YXNhIGRlIHJlc3B1ZXN0YSBlbiBtdWVzdHJhIHBlcXVlw7FhIiwKICAgICJTaW11bGFyIHBvZGVyIGRlIHVuIGVuc2F5byBjb24gdGFzYSBkZSDDqXhpdG8gZGVsIDcwJSIsCiAgICAiQ29tcGFyYXIgbml2ZWxlcyBkZSBjb2xlc3Rlcm9sIGVudHJlIHRyYXRhbWllbnRvcyIsCiAgICAiVmVyaWZpY2FyIG5vcm1hbGlkYWQgZGUgcmVzaWR1b3MgZW4gcmVncmVzacOzbiIsCiAgICAiQW5hbGl6YXIgc2VzZ28gZW4gdGllbXBvcyBkZSByZWN1cGVyYWNpw7NuIiwKICAgICJWaXN1YWxpemFyIHJlbGFjacOzbiBlbnRyZSBJTUMgeSBnbHVjb3NhIiwKICAgICJDb21wYXJhciBwcmVzacOzbiBhcnRlcmlhbCBlbnRyZSBncnVwb3MiLAogICAgIkRhc2hib2FyZCBpbnRlcmFjdGl2byBkZSBob3NwaXRhbGl6YWNpb25lcyBwb3IgQ09WSUQtMTkiCiAgKSwKICAiRWplbXBsbyBQcsOhY3RpY28iID0gYygKICAgICJgdC50ZXN0KGFudGVzLCBkZXNwdWVzLCBwYWlyZWQ9VFJVRSlgIGRhIHAgPSAwLjAzIiwKICAgICJgc21mLk9MUyhnbHVjb3NhIH4gSU1DICsgZWRhZCkuZml0KClgIGNvbiAkUl4yID0gMC42NSQiLAogICAgImBkYXRvcyAlPiUgZ3JvdXBfYnkodHJhdGFtaWVudG8pICU+JSBzdW1tYXJpc2UobWVhbl9wYSA9IG1lYW4ocHJlc2lvbikpYCIsCiAgICAiYGdsbSgnZGlhYmV0ZXMgfiBJTUMgKyBnbHVjb3NhJywgZmFtaWx5PUJpbm9taWFsKCkpYCBjb24gJHAgPCAwLjAxJCIsCiAgICAiYG1hbm53aGl0bmV5dShncnVwbzEsIGdydXBvMilgIGRhIHAgPSAwLjA0IiwKICAgICJJQyBib290c3RyYXAgWzIsIDhdIG1tSGcgcGFyYSBkaWZlcmVuY2lhIGRlIHByZXNpw7NuIGFydGVyaWFsIiwKICAgICJTaW11bGFyIDEwMDAgZW5zYXlvcyBjb24gYG51bXB5LnJhbmRvbS5iaW5vbWlhbGAiLAogICAgIkJveHBsb3QgbXVlc3RyYSBtZWRpYW5hIGRlIDE1MCB2cy4gMTgwIG1nL2RMIiwKICAgICJRLVEgcGxvdCBjb25maXJtYSBub3JtYWxpZGFkICgkcCA9IDAuNyQgZW4gU2hhcGlyby1XaWxrKSIsCiAgICAiSGlzdG9ncmFtYSBtdWVzdHJhIHNlc2dvIHBvc2l0aXZvIGVuIHRpZW1wb3MiLAogICAgImBnZ3Bsb3QoKSArIGdlb21fcG9pbnQoKSArIGdlb21fc21vb3RoKG1ldGhvZD1cImxtXCIpYCBtdWVzdHJhIHVuYSByZWxhY2nDs24gcG9zaXRpdmEgKCRcXGJldGFfMSA9IDIuNSQsICRwIDwgMC4wMSQpIiwKICAgICJgc2VhYm9ybi5ib3hwbG90KHg9XCJ0cmF0YW1pZW50b1wiLCB5PVwicHJlc2lvblwiLCBkYXRhPWRhdG9zKWAgbXVlc3RyYSBkaWZlcmVuY2lhcyBjbGFyYXMgKCRwID0gMC4wMSQpIiwKICAgICJEYXNoYm9hcmQgY29uIHRlbmRlbmNpYXMgcG9yIHJlZ2nDs24iCiAgKSwKICBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UKKQoKIyBNb3N0cmFyIHRhYmxhCmthYmxlKHRhYmxhX3Rvb2xzLCAiaHRtbCIsIAogICAgICBjYXB0aW9uID0gIlRhYmxhIDEwOiBSZXN1bWVuIGRlIGhlcnJhbWllbnRhcyBjb21wdXRhY2lvbmFsZXMgZW4gZXN0YWTDrXN0aWNhIGluZmVyZW5jaWFsIHBhcmEgc2FsdWQiKSAlPiUKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJyZXNwb25zaXZlIiksIGZ1bGxfd2lkdGggPSBGQUxTRSkgJT4lCiAgc2Nyb2xsX2JveCh3aWR0aCA9ICIxMDAlIiwgaGVpZ2h0ID0gIjUwMHB4IikKYGBgCgojIDExLiBBcGxpY2FjaW9uZXMgUHLDoWN0aWNhcyB5IEVzdHVkaW9zIGRlIENhc28gZW4gU2FsdWQKCkVzdGUgdGVtYXJpbyBkZXNhcnJvbGxhIGFwbGljYWNpb25lcyBwcsOhY3RpY2FzIGRlIGxhIGVzdGFkw61zdGljYQppbmZlcmVuY2lhbCBlbiBlbCBzZWN0b3Igc2FsdWQsIGVuZm9jw6FuZG9zZSBlbiBlbCBhbsOhbGlzaXMgZGUgZGF0b3MKcmVhbGVzLCBsYSB2YWxpZGFjacOzbiBkZSBzdXB1ZXN0b3MgZXN0YWTDrXN0aWNvcyB5IGxhIHJlZGFjY2nDs24gZGUKaW5mb3JtZXMuIENvbiB1biBlbmZvcXVlIG9yaWVudGFkbyBhIHByb2Zlc2lvbmFsZXMgbcOpZGljb3MsCmludmVzdGlnYWRvcmVzIGNsw61uaWNvcyB5IGVwaWRlbWnDs2xvZ29zLCBzZSBwcmVzZW50YW4gZXN0dWRpb3MgZGUgY2FzbywKdMOpY25pY2FzIGRlIGRpYWduw7NzdGljbyB5IGRpcmVjdHJpY2VzIHBhcmEgY29tdW5pY2FyIHJlc3VsdGFkb3MgZGUKbWFuZXJhIGNsYXJhIHkgcmlndXJvc2EuIExhcyBhcGxpY2FjaW9uZXMgZW4gc2FsdWQgaW5jbHV5ZW4gZW5zYXlvcwpjbMOtbmljb3MsIGVzdHVkaW9zIGVwaWRlbWlvbMOzZ2ljb3MgeSBldmFsdWFjaW9uZXMgZGUgaW50ZXJ2ZW5jaW9uZXMsCmludGVncmFuZG8gbcOpdG9kb3MgY29tbyBwcnVlYmFzIGRlIGhpcMOzdGVzaXMsIEFOT1ZBLCByZWdyZXNpw7NuLCBzZXJpZXMKdGVtcG9yYWxlcyB5IG3DqXRvZG9zIG11bHRpdmFyaWFkb3MuCgojIyAxMS4xIEFuw6FsaXNpcyBkZSBEYXRvcyBSZWFsZXMKCiMjIyBFc3R1ZGlvcyBkZSBDYXNvIGVuIENpZW5jaWFzIFNvY2lhbGVzLCBCaW9sb2fDrWEsIEVjb25vbcOtYSwgZXRjLgoKRWwgYW7DoWxpc2lzIGRlIGRhdG9zIHJlYWxlcyBlbiBzYWx1ZCBpbXBsaWNhIGFwbGljYXIgbcOpdG9kb3MKZXN0YWTDrXN0aWNvcyBpbmZlcmVuY2lhbGVzIGEgY29uanVudG9zIGRlIGRhdG9zIHJlYWxlcyBwYXJhIHJlc3BvbmRlcgpwcmVndW50YXMgY2zDrW5pY2FzIG8gZXBpZGVtaW9sw7NnaWNhcywgaW50ZXJwcmV0YXIgcmVzdWx0YWRvcyBlbiBjb250ZXh0bwp5IHRvbWFyIGRlY2lzaW9uZXMgYmFzYWRhcyBlbiBldmlkZW5jaWEuCgoqKkVzdHVkaW8gZGUgY2FzbyAxOiBFbnNheW8gY2zDrW5pY28gKEJpb2xvZ8OtYS9TYWx1ZCkqKgoKLSAgICoqQ29udGV4dG86KiogRXZhbHVhciBsYSBlZmljYWNpYSBkZSB1biBudWV2byBmw6FybWFjbwogICAgYW50aWhpcGVydGVuc2l2byBmcmVudGUgYSB1biBwbGFjZWJvIGVuIHBhY2llbnRlcyBjb24gaGlwZXJ0ZW5zacOzbgogICAgbGV2ZSBhIG1vZGVyYWRhLgotICAgKipEYXRvczoqKiAyMDAgcGFjaWVudGVzIGFzaWduYWRvcyBhbGVhdG9yaWFtZW50ZSAoMTAwIGbDoXJtYWNvLCAxMDAKICAgIHBsYWNlYm8pLCBjb24gbWVkaWNpb25lcyBkZSBwcmVzacOzbiBhcnRlcmlhbCBzaXN0w7NsaWNhIChQQVMpIGFsCiAgICBpbmljaW8geSB0cmFzIDEyIHNlbWFuYXMuIFZhcmlhYmxlIGRlcGVuZGllbnRlOiBjYW1iaW8gZW4gUEFTCiAgICAobW1IZykuCi0gICAqKk3DqXRvZG86KiogUHJ1ZWJhIHQgZGUgZG9zIG11ZXN0cmFzIHBhcmEgY29tcGFyYXIgZWwgY2FtYmlvIG1lZGlvCiAgICBlbiBQQVMgZW50cmUgZ3J1cG9zLgotICAgKipSZXN1bHRhZG9zOioqIE1lZGlhIGRlbCBjYW1iaW8gZW4gUEFTOiAtMTUgbW1IZyAoZsOhcm1hY28pLCAtNSBtbUhnCiAgICAocGxhY2VibykuIEVzdGFkw61zdGljbyAkdCA9IC00LjIkLCAkcCA8IDAuMDAxJCwgcmVjaGF6YW5kbwogICAgJEhfMDogXG11X3tcdGV4dHtmw6FybWFjb319ID0gXG11X3tcdGV4dHtwbGFjZWJvfX0kLiBJbnRlcnZhbG8gZGUKICAgIGNvbmZpYW56YSAoSUMpIGFsIDk1JSBwYXJhIGxhIGRpZmVyZW5jaWE6IFstMTMuNSwgLTYuNV0gbW1IZy4KLSAgICoqSW50ZXJwcmV0YWNpw7NuIGVuIGNvbnRleHRvOioqIEVsIGbDoXJtYWNvIHJlZHVjZSBzaWduaWZpY2F0aXZhbWVudGUKICAgIGxhIFBBUyBlbiBjb21wYXJhY2nDs24gY29uIGVsIHBsYWNlYm8sIGNvbiB1biBlZmVjdG8gY2zDrW5pY28KICAgIHJlbGV2YW50ZSAoMTAgbW1IZyBtYXlvciByZWR1Y2Npw7NuKS4gRXN0byBzdWdpZXJlIHF1ZSBlbCBmw6FybWFjbwogICAgcG9kcsOtYSBzZXIgdW5hIG9wY2nDs24gdGVyYXDDqXV0aWNhIHZpYWJsZSwgcGVuZGllbnRlIGRlIGVzdHVkaW9zCiAgICBhZGljaW9uYWxlcyBzb2JyZSBzZWd1cmlkYWQuCi0gICAqKkFwbGljYWNpw7NuIHByw6FjdGljYToqKiBMb3MgcmVzdWx0YWRvcyBhcG95YW4gbGEgYXByb2JhY2nDs24gZGVsCiAgICBmw6FybWFjbyBlbiBlbnNheW9zIGRlIGZhc2UgSUlJLCBpbmZvcm1hbmRvIGd1w61hcyBjbMOtbmljYXMuCgoqKkVzdHVkaW8gZGUgY2FzbyAyOiBFcGlkZW1pb2xvZ8OtYSAoQ2llbmNpYXMgU29jaWFsZXMvU2FsdWQpKioKCi0gICAqKkNvbnRleHRvOioqIEFuYWxpemFyIGxhIHJlbGFjacOzbiBlbnRyZSBlbCDDrW5kaWNlIGRlIG1hc2EgY29ycG9yYWwKICAgIChJTUMpIHkgZWwgcmllc2dvIGRlIGRpYWJldGVzIHRpcG8gMiBlbiB1bmEgcG9ibGFjacOzbiB1cmJhbmEuCi0gICAqKkRhdG9zOioqIEVuY3Vlc3RhIHRyYW5zdmVyc2FsIGRlIDUwMCBhZHVsdG9zLCBjb24gSU1DIChrZy9twrIpIHkKICAgIGRpYWduw7NzdGljbyBkZSBkaWFiZXRlcyAoc8OtL25vKS4KLSAgICoqTcOpdG9kbzoqKiBSZWdyZXNpw7NuIGxvZ8Otc3RpY2EgcGFyYSBtb2RlbGFyIGxhIHByb2JhYmlsaWRhZCBkZQogICAgZGlhYmV0ZXMgZW4gZnVuY2nDs24gZGVsIElNQywgYWp1c3RhbmRvIHBvciBlZGFkIHkgc2V4by4KLSAgICoqUmVzdWx0YWRvczoqKiBDb2VmaWNpZW50ZSBwYXJhIElNQzogJFxiZXRhXzEgPSAwLjEyJCwgJHAgPSAwLjAwMiQ7CiAgICBvZGRzIHJhdGlvICRcZXhwKDAuMTIpIFxhcHByb3ggMS4xMyQuIElDIGFsIDk1JSBwYXJhIGVsIG9kZHMgcmF0aW86CiAgICBbMS4wNSwgMS4yMl0uIFBvciBjYWRhIHVuaWRhZCBkZSBhdW1lbnRvIGVuIElNQywgbG9zIG9kZHMgZGUKICAgIGRpYWJldGVzIGF1bWVudGFuIHVuIDEzJS4KLSAgICoqSW50ZXJwcmV0YWNpw7NuIGVuIGNvbnRleHRvOioqIEVsIElNQyBlcyB1biBwcmVkaWN0b3Igc2lnbmlmaWNhdGl2bwogICAgZGVsIHJpZXNnbyBkZSBkaWFiZXRlcywgY29uIHVuIGltcGFjdG8gbW9kZXJhZG8gcGVybyBjbMOtbmljYW1lbnRlCiAgICByZWxldmFudGUuIEVzdG8gcmVzYWx0YSBsYSBpbXBvcnRhbmNpYSBkZSBpbnRlcnZlbmNpb25lcyBwYXJhCiAgICByZWR1Y2lyIGxhIG9iZXNpZGFkIGVuIGxhIHByZXZlbmNpw7NuIGRlIGRpYWJldGVzLgotICAgKipBcGxpY2FjacOzbiBwcsOhY3RpY2E6KiogTG9zIHJlc3VsdGFkb3MgcHVlZGVuIGd1aWFyIGNhbXBhw7FhcyBkZQogICAgc2FsdWQgcMO6YmxpY2EgZW5mb2NhZGFzIGVuIGxhIHJlZHVjY2nDs24gZGUgcGVzbyBlbiBwb2JsYWNpb25lcwogICAgdXJiYW5hcy4KCioqRXN0dWRpbyBkZSBjYXNvIDM6IFNlcmllcyB0ZW1wb3JhbGVzIChTYWx1ZC9FcGlkZW1pb2xvZ8OtYSkqKgoKLSAgICoqQ29udGV4dG86KiogUHJlZGVjaXIgY2Fzb3Mgc2VtYW5hbGVzIGRlIGluZmx1ZW56YSBwYXJhIHBsYW5pZmljYXIKICAgIHJlY3Vyc29zIGhvc3BpdGFsYXJpb3MuCi0gICAqKkRhdG9zOioqIENhc29zIHNlbWFuYWxlcyBkZSBpbmZsdWVuemEgKDIwMTgtMjAyNSkgZGUgdW4gc2lzdGVtYSBkZQogICAgdmlnaWxhbmNpYSBlcGlkZW1pb2zDs2dpY2EuCi0gICAqKk3DqXRvZG86KiogTW9kZWxvIFNBUklNQSAkKDEsMSwxKSBcdGltZXMgKDEsMSwxKV97NTJ9JCBwYXJhCiAgICBjYXB0dXJhciB0ZW5kZW5jaWEgeSBlc3RhY2lvbmFsaWRhZCBhbnVhbC4KLSAgICoqUmVzdWx0YWRvczoqKiBQcmVkaWNjaW9uZXMgcGFyYSBsYXMgcHLDs3hpbWFzIDEyIHNlbWFuYXMgbXVlc3RyYW4KICAgIHVuIHBpY28gZXN0YWNpb25hbCBlbiBpbnZpZXJubywgY29uIHVuIFJNU0UgZGUgNDUgY2Fzb3MgZW4gZGF0b3MgZGUKICAgIHZhbGlkYWNpw7NuLiBJbnRlcnZhbG9zIGRlIHByZWRpY2Npw7NuIGFsIDk1JSBjdWJyZW4gZWwgOTAlIGRlIGxvcwogICAgY2Fzb3Mgb2JzZXJ2YWRvcy4KLSAgICoqSW50ZXJwcmV0YWNpw7NuIGVuIGNvbnRleHRvOioqIEVsIG1vZGVsbyBwcmVkaWNlIGNvbiBwcmVjaXNpw7NuIGxvcwogICAgcGljb3MgZGUgaW5mbHVlbnphLCBwZXJtaXRpZW5kbyBhIGxvcyBob3NwaXRhbGVzIHByZXBhcmFyc2UgcGFyYQogICAgYXVtZW50b3MgZW4gbGEgZGVtYW5kYSBkZSBjYW1hcyB5IHBlcnNvbmFsLgotICAgKipBcGxpY2FjacOzbiBwcsOhY3RpY2E6KiogTG9zIHJlc3VsdGFkb3MgaW5mb3JtYW4gbGEgcGxhbmlmaWNhY2nDs24gZGUKICAgIGNhbXBhw7FhcyBkZSB2YWN1bmFjacOzbiB5IGxhIGFzaWduYWNpw7NuIGRlIHJlY3Vyc29zIGVuIHRlbXBvcmFkYXMgZGUKICAgIGFsdGEgaW5jaWRlbmNpYS4KCiMjIyBJbnRlcnByZXRhY2nDs24gZGUgUmVzdWx0YWRvcyBlbiBDb250ZXh0bwoKLSAgICoqRW5mb3F1ZSBjbMOtbmljbzoqKiBMb3MgcmVzdWx0YWRvcyBkZWJlbiBpbnRlcnByZXRhcnNlIGNvbnNpZGVyYW5kbwogICAgc3UgcmVsZXZhbmNpYSBjbMOtbmljYSwgbm8gc29sbyBzdSBzaWduaWZpY2FuY2lhIGVzdGFkw61zdGljYS4gUG9yCiAgICBlamVtcGxvLCB1bmEgZGlmZXJlbmNpYSBkZSAyIG1tSGcgZW4gUEFTIHB1ZWRlIHNlciBlc3RhZMOtc3RpY2FtZW50ZQogICAgc2lnbmlmaWNhdGl2YSBwZXJvIGNsw61uaWNhbWVudGUgaXJyZWxldmFudGUuCi0gICAqKkxpbWl0YWNpb25lczoqKiBSZWNvbm9jZXIgc2VzZ29zIChlLmcuLCBzZWxlY2Npw7NuLCBtZWRpY2nDs24pLAogICAgdGFtYcOxb3MgbXVlc3RyYWxlcyBwZXF1ZcOxb3MgbyBzdXB1ZXN0b3Mgbm8gY3VtcGxpZG9zIHF1ZSBwdWVkYW4KICAgIGFmZWN0YXIgbGFzIGNvbmNsdXNpb25lcy4KLSAgICoqSW1wYWN0byBwcsOhY3RpY286KiogVHJhZHVjaXIgaGFsbGF6Z29zIGVuIHJlY29tZW5kYWNpb25lcwogICAgYWNjaW9uYWJsZXMsIGNvbW8gYWp1c3RhciB0cmF0YW1pZW50b3MsIGRpc2XDsWFyIGludGVydmVuY2lvbmVzIG8KICAgIGluZm9ybWFyIHBvbMOtdGljYXMgZGUgc2FsdWQuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIGVsIGVzdHVkaW8gZGUgaGlwZXJ0ZW5zacOzbiwgZWwgSUMgYWwgOTUlCiAgICBbLTEzLjUsIC02LjVdIHN1Z2llcmUgcXVlIGVsIGbDoXJtYWNvIGVzIGNvbnNpc3RlbnRlbWVudGUgbcOhcwogICAgZWZlY3Rpdm8gcXVlIGVsIHBsYWNlYm8sIHBlcm8gc2UgZGViZSBjb25zaWRlcmFyIGVsIGNvc3RvIHkgbG9zCiAgICBlZmVjdG9zIHNlY3VuZGFyaW9zIGFudGVzIGRlIHJlY29tZW5kYXIgc3UgdXNvIGdlbmVyYWxpemFkby4KCiMjIDExLjIgVmFsaWRhY2nDs24gZGUgU3VwdWVzdG9zCgpMYSB2YWxpZGV6IGRlIGxvcyBtw6l0b2RvcyBpbmZlcmVuY2lhbGVzIGRlcGVuZGUgZGVsIGN1bXBsaW1pZW50byBkZQpzdXB1ZXN0b3MgZXN0YWTDrXN0aWNvcy4gRW4gc2FsdWQsIGRvbmRlIGxvcyBkYXRvcyBzdWVsZW4gc2VyIGNvbXBsZWpvcwooZS5nLiwgbm8gbm9ybWFsZXMsIGhldGVyb2NlZMOhc3RpY29zKSwgZXMgY3J1Y2lhbCBkaWFnbm9zdGljYXIgeSwgc2kgZXMKbmVjZXNhcmlvLCBjb3JyZWdpciB2aW9sYWNpb25lcy4KCiMjIyBEaWFnbsOzc3RpY29zIGRlIE5vcm1hbGlkYWQsIEhvbW9jZWRhc3RpY2lkYWQsIEluZGVwZW5kZW5jaWEKCioqTm9ybWFsaWRhZDoqKgoKLSAgICoqUHJvcMOzc2l0bzoqKiBWZXJpZmljYXIgc2kgbG9zIGRhdG9zIG8gcmVzaWR1b3Mgc2lndWVuIHVuYQogICAgZGlzdHJpYnVjacOzbiBub3JtYWwsIGFzdW1pZGEgZW4gcHJ1ZWJhcyBwYXJhbcOpdHJpY2FzIChlLmcuLCB0LXRlc3QsCiAgICBBTk9WQSkuCi0gICAqKk3DqXRvZG9zIGRlIGRpYWduw7NzdGljbzoqKgogICAgLSAgICoqR3LDoWZpY29zOioqIEhpc3RvZ3JhbWFzLCBncsOhZmljb3MgUS1RIGRlIHJlc2lkdW9zLgogICAgLSAgICoqUHJ1ZWJhczoqKiBTaGFwaXJvLVdpbGsgKCRIXzAkOiBub3JtYWxpZGFkKSwKICAgICAgICBLb2xtb2dvcm92LVNtaXJub3YuCi0gICAqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIENvbXByb2JhciBzaSBsb3MgY2FtYmlvcyBlbiBQQVMgdHJhcyB1bgogICAgdHJhdGFtaWVudG8gc29uIG5vcm1hbGVzIHBhcmEgYXBsaWNhciB1bmEgcHJ1ZWJhIHQuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIGVsIGVuc2F5byBhbnRpaGlwZXJ0ZW5zaXZvLCB1biBncsOhZmljbyBRLVEKICAgIGRlIGxvcyByZXNpZHVvcyBkZSB1biBtb2RlbG8gQU5PVkEgbXVlc3RyYSBkZXN2aWFjaW9uZXMgZW4gbGFzCiAgICBjb2xhcywgeSBTaGFwaXJvLVdpbGsgZGEgJHAgPSAwLjAzJCwgc3VnaXJpZW5kbyBubyBub3JtYWxpZGFkLiBFc3RvCiAgICBpbmRpY2EgbGEgbmVjZXNpZGFkIGRlIHVuYSB0cmFuc2Zvcm1hY2nDs24gbyB1biBtw6l0b2RvIG5vCiAgICBwYXJhbcOpdHJpY28uCgoqKkhvbW9jZWRhc3RpY2lkYWQ6KioKCi0gICAqKlByb3DDs3NpdG86KiogVmVyaWZpY2FyIHF1ZSBsYSB2YXJpYW56YSBkZSBsb3MgcmVzaWR1b3MgZXMKICAgIGNvbnN0YW50ZSBlbnRyZSBncnVwb3MgbyBhIGxvIGxhcmdvIGRlIHVuYSBjb3ZhcmlhYmxlLCBhc3VtaWRvIGVuCiAgICBBTk9WQSB5IHJlZ3Jlc2nDs24uCi0gICAqKk3DqXRvZG9zIGRlIGRpYWduw7NzdGljbzoqKgogICAgLSAgICoqR3LDoWZpY29zOioqIFJlc2lkdW9zIHZzLiB2YWxvcmVzIHByZWRpY2hvcyAoZGlzcGVyc2nDs24KICAgICAgICBjb25zdGFudGUgaW5kaWNhIGhvbW9jZWRhc3RpY2lkYWQpLgogICAgLSAgICoqUHJ1ZWJhczoqKiBMZXZlbmUgKCRIXzAkOiB2YXJpYW56YXMgaWd1YWxlcyksIEJyZXVzY2gtUGFnYW4KICAgICAgICAoZW4gcmVncmVzacOzbikuCi0gICAqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIEFzZWd1cmFyIHF1ZSBsYSB2YXJpYW56YSBlbiBsb3Mgbml2ZWxlcyBkZQogICAgZ2x1Y29zYSBlcyBzaW1pbGFyIGVudHJlIGdydXBvcyB0cmF0YWRvcyB5IHBsYWNlYm8uCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuIGVzdHVkaW8gZGUgZGlhYmV0ZXMsIGxhIHBydWViYSBkZSBMZXZlbmUKICAgIHBhcmEgbG9zIHJlc2lkdW9zIGRlIHVuIEFOT1ZBIGRhICRwID0gMC4wMSQsIGluZGljYW5kbwogICAgaGV0ZXJvY2VkYXN0aWNpZGFkLiBFc3RvIHN1Z2llcmUgdXNhciB1biBBTk9WQSByb2J1c3RvIChlLmcuLCBXZWxjaCkKICAgIG8gdHJhbnNmb3JtYXIgbG9zIGRhdG9zLgoKKipJbmRlcGVuZGVuY2lhOioqCgotICAgKipQcm9ww7NzaXRvOioqIEFzZWd1cmFyIHF1ZSBsYXMgb2JzZXJ2YWNpb25lcyBvIHJlc2lkdW9zIG5vIGVzdMOhbgogICAgY29ycmVsYWNpb25hZG9zLCBlc3BlY2lhbG1lbnRlIGVuIHNlcmllcyB0ZW1wb3JhbGVzIG8gZGF0b3MKICAgIGFncnVwYWRvcy4KLSAgICoqTcOpdG9kb3MgZGUgZGlhZ27Ds3N0aWNvOioqCiAgICAtICAgKipHcsOhZmljb3M6KiogQUNGIChhdXRvY29ycmVsYWNpw7NuKSBkZSByZXNpZHVvcy4KICAgIC0gICAqKlBydWViYXM6KiogRHVyYmluLVdhdHNvbiAoJEhfMCQ6IG5vIGF1dG9jb3JyZWxhY2nDs24pIHBhcmEKICAgICAgICByZWdyZXNpw7NuOyBManVuZy1Cb3ggcGFyYSBzZXJpZXMgdGVtcG9yYWxlcy4KLSAgICoqQXBsaWNhY2nDs24gZW4gc2FsdWQ6KiogVmVyaWZpY2FyIHF1ZSBsYXMgbWVkaWNpb25lcyBkZSBwcmVzacOzbgogICAgYXJ0ZXJpYWwgZGUgcGFjaWVudGVzIGVuIHVuIGVuc2F5byBjbMOtbmljbyBubyBlc3TDqW4gY29ycmVsYWNpb25hZGFzCiAgICBkZWJpZG8gYSBlZmVjdG9zIGRlIGNsw7pzdGVyIChlLmcuLCBtaXNtbyBob3NwaXRhbCkuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIHVuYSBzZXJpZSB0ZW1wb3JhbCBkZSBjYXNvcyBkZSBpbmZsdWVuemEsCiAgICBlbCBBQ0YgZGUgbG9zIHJlc2lkdW9zIGRlIHVuIG1vZGVsbyBBUklNQSBtdWVzdHJhIGF1dG9jb3JyZWxhY2nDs24KICAgIHNpZ25pZmljYXRpdmEgZW4gbGFnIDEgKCRwID0gMC4wMiQsIExqdW5nLUJveCksIHN1Z2lyaWVuZG8gdW4gbW9kZWxvCiAgICBTQVJJTUEgcGFyYSBjYXB0dXJhciBlc3RhY2lvbmFsaWRhZC4KCiMjIyBUcmFuc2Zvcm1hY2lvbmVzIGRlIERhdG9zCgpDdWFuZG8gbG9zIHN1cHVlc3RvcyBubyBzZSBjdW1wbGVuLCBsYXMgdHJhbnNmb3JtYWNpb25lcyBkZSBkYXRvcyBwdWVkZW4KY29ycmVnaXIgdmlvbGFjaW9uZXMsIHBlcm1pdGllbmRvIGVsIHVzbyBkZSBtw6l0b2RvcyBwYXJhbcOpdHJpY29zLgoKKipUcmFuc2Zvcm1hY2lvbmVzIHBhcmEgbm9ybWFsaWRhZDoqKgoKLSAgICoqTG9nYXJpdG1vOioqIMOadGlsIHBhcmEgZGF0b3Mgc2VzZ2Fkb3MgYSBsYSBkZXJlY2hhIChlLmcuLCB0aWVtcG9zCiAgICBkZSBob3NwaXRhbGl6YWNpw7NuLCBjb250ZW9zIGRlIGV2ZW50b3MpLgogICAgLSAgIEVqZW1wbG86ICRZJyA9IFxsbihZICsgMSkkIHBhcmEgdGllbXBvcyBkZSByZWN1cGVyYWNpw7NuIG5vCiAgICAgICAgbm9ybWFsZXMuCi0gICAqKlJhw616IGN1YWRyYWRhOioqIEVzdGFiaWxpemEgdmFyaWFuemEgZW4gZGF0b3MgZGUgY29udGVvIChlLmcuLAogICAgbsO6bWVybyBkZSBpbmZlY2Npb25lcykuCi0gICAqKkJveC1Db3g6KiogVHJhbnNmb3JtYWNpw7NuIGdlbmVyYWwgcGFyYSBub3JtYWxpZGFkIHkKICAgIGhvbW9jZWRhc3RpY2lkYWQsIHNlbGVjY2lvbmFuZG8gdW4gcGFyw6FtZXRybyAkXGxhbWJkYSQuCi0gICAqKkFwbGljYWNpw7NuIGVuIHNhbHVkOioqIFRyYW5zZm9ybWFyIGxvcyBuaXZlbGVzIGRlIHRyaWdsaWPDqXJpZG9zCiAgICAoc2VzZ2Fkb3MpIGNvbiB1biBsb2dhcml0bW8gYW50ZXMgZGUgdW4gQU5PVkEuCi0gICAqKkVqZW1wbG8gcHLDoWN0aWNvOioqIEVuIGVsIGVzdHVkaW8gZGUgaGlwZXJ0ZW5zacOzbiwgbG9zIHJlc2lkdW9zIG5vCiAgICBub3JtYWxlcyAoJHAgPSAwLjAzJCkgc2UgY29ycmlnZW4gYXBsaWNhbmRvICRcbG4oXHRleHR7UEFTfSkkLiBVbgogICAgbnVldm8gU2hhcGlyby1XaWxrIGRhICRwID0gMC4xNSQsIHBlcm1pdGllbmRvIGVsIHVzbyBkZSBBTk9WQS4KCioqVHJhbnNmb3JtYWNpb25lcyBwYXJhIGhvbW9jZWRhc3RpY2lkYWQ6KioKCi0gICAqKkxvZ2FyaXRtbyBvIHJhw616IGN1YWRyYWRhOioqIFJlZHVjZW4gbGEgdmFyaWFuemEgZW4gZ3J1cG9zIGNvbgogICAgaGV0ZXJvY2VkYXN0aWNpZGFkLgotICAgKipQb25kZXJhY2nDs246KiogVXNhciBtb2RlbG9zIGNvbiB2YXJpYW56YXMgcG9uZGVyYWRhcyAoZS5nLiwgV0xTIGVuCiAgICByZWdyZXNpw7NuKS4KLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogRW4gdW4gZXN0dWRpbyBkZSBnbHVjb3NhLCBsYQogICAgaGV0ZXJvY2VkYXN0aWNpZGFkICgkcCA9IDAuMDEkLCBMZXZlbmUpIHNlIGNvcnJpZ2UgY29uIHVuYQogICAgdHJhbnNmb3JtYWNpw7NuIGxvZ2Fyw610bWljYSwgZGFuZG8gJHAgPSAwLjIwJCBlbiBMZXZlbmUuCgoqKkFsdGVybmF0aXZhcyBubyBwYXJhbcOpdHJpY2FzOioqIFNpIGxhcyB0cmFuc2Zvcm1hY2lvbmVzIG5vIGZ1bmNpb25hbiwKdXNhciBwcnVlYmFzIGNvbW8gTWFubi1XaGl0bmV5LCBLcnVza2FsLVdhbGxpcyBvIG1vZGVsb3Mgcm9idXN0b3MuCgotICAgKipFamVtcGxvOioqIEVuIHVuIGVzdHVkaW8gY29uIGRhdG9zIG5vIG5vcm1hbGVzIHBlcnNpc3RlbnRlcywgc2UKICAgIHVzYSB1bmEgcHJ1ZWJhIGRlIFdpbGNveG9uIHBhcmEgY29tcGFyYXIgZ2x1Y29zYSBlbnRyZSBkb3MgZ3J1cG9zLgoKIyMgMTEuMyBSZWRhY2Npw7NuIGRlIEluZm9ybWVzCgpMYSByZWRhY2Npw7NuIGRlIGluZm9ybWVzIGVzdGFkw61zdGljb3MgZXMgY3J1Y2lhbCBwYXJhIGNvbXVuaWNhcgpyZXN1bHRhZG9zIGluZmVyZW5jaWFsZXMgZGUgbWFuZXJhIGNsYXJhLCBwcmVjaXNhIHkgcmVwcm9kdWNpYmxlLAplc3BlY2lhbG1lbnRlIGVuIHNhbHVkLCBkb25kZSBsYXMgZGVjaXNpb25lcyBpbXBhY3RhbiB2aWRhcy4KCiMjIyBFc3RydWN0dXJhIGRlIHVuIEluZm9ybWUgRXN0YWTDrXN0aWNvCgpVbiBpbmZvcm1lIGJpZW4gZXN0cnVjdHVyYWRvIGRlYmUgc2VndWlyIHVuIGZvcm1hdG8gZXN0w6FuZGFyIHF1ZQpmYWNpbGl0ZSBsYSBjb21wcmVuc2nDs24geSByZXBsaWNhY2nDs24gZGVsIGFuw6FsaXNpcy4KCioqSW50cm9kdWNjacOzbjoqKgoKLSAgIERlc2NyaWJpciBlbCBjb250ZXh0byBjbMOtbmljbyBvIGVwaWRlbWlvbMOzZ2ljbywgbGEgcHJlZ3VudGEgZGUKICAgIGludmVzdGlnYWNpw7NuIHkgbG9zIG9iamV0aXZvcy4KLSAgICoqRWplbXBsbzoqKiAiRXZhbHVhciBsYSBlZmljYWNpYSBkZSB1biBudWV2byBmw6FybWFjbwogICAgYW50aWhpcGVydGVuc2l2byBlbiBsYSByZWR1Y2Npw7NuIGRlIGxhIHByZXNpw7NuIGFydGVyaWFsIHNpc3TDs2xpY2EgZW4KICAgIHBhY2llbnRlcyBjb24gaGlwZXJ0ZW5zacOzbiBsZXZlLiIKCioqTWV0b2RvbG9nw61hOioqCgotICAgKipEaXNlw7FvIGRlbCBlc3R1ZGlvOioqIEVzcGVjaWZpY2FyIGVsIHRpcG8gZGUgZGlzZcOxbyAoZS5nLiwgZW5zYXlvCiAgICBjbMOtbmljbyBhbGVhdG9yaXphZG8sIHRyYW5zdmVyc2FsKS4KLSAgICoqRGF0b3M6KiogRGVzY3JpYmlyIGxhIGZ1ZW50ZSwgdGFtYcOxbyBtdWVzdHJhbCwgdmFyaWFibGVzCiAgICAoZGVwZW5kaWVudGUsIGluZGVwZW5kaWVudGVzLCBjb3ZhcmlhYmxlcykuCi0gICAqKk3DqXRvZG9zIGVzdGFkw61zdGljb3M6KiogRGV0YWxsYXIgbGFzIHBydWViYXMgbyBtb2RlbG9zIHV0aWxpemFkb3MKICAgIChlLmcuLCB0LXRlc3QsIHJlZ3Jlc2nDs24gbG9nw61zdGljYSwgQVJJTUEpLCBpbmNsdXllbmRvIHNvZnR3YXJlIHkKICAgIHBhcXVldGVzIChlLmcuLCBSLCBQeXRob24pLgotICAgKipTdXB1ZXN0b3M6KiogSW5kaWNhciBjw7NtbyBzZSB2ZXJpZmljYXJvbiAoZS5nLiwgbm9ybWFsaWRhZCBjb24KICAgIFNoYXBpcm8tV2lsaywgaG9tb2NlZGFzdGljaWRhZCBjb24gTGV2ZW5lKS4KLSAgICoqRWplbXBsbzoqKiAiU2UgcmVhbGl6w7MgdW4gZW5zYXlvIGNsw61uaWNvIGFsZWF0b3JpemFkbyBjb24gMjAwCiAgICBwYWNpZW50ZXMsIGNvbXBhcmFuZG8gZWwgY2FtYmlvIGVuIFBBUyB1c2FuZG8gdW5hIHBydWViYSB0IGRlIGRvcwogICAgbXVlc3RyYXMuIExhIG5vcm1hbGlkYWQgc2UgdmVyaWZpY8OzIGNvbiB1biBncsOhZmljbyBRLVEgeQogICAgU2hhcGlyby1XaWxrICgkcCA+IDAuMDUkKS4iCgoqKlJlc3VsdGFkb3M6KioKCi0gICBQcmVzZW50YXIgaGFsbGF6Z29zIGNsYXZlIGNvbiBlc3RhZMOtc3RpY29zLCB2YWxvcmVzIHAsIGludGVydmFsb3MgZGUKICAgIGNvbmZpYW56YS9jcmVkaWJpbGlkYWQgeSBncsOhZmljb3MuCi0gICBFdml0YXIgaW50ZXJwcmV0YXIgZW4gZXN0YSBzZWNjacOzbjsgc29sbyByZXBvcnRhciBkYXRvcy4KLSAgICoqRWplbXBsbzoqKiAiRWwgY2FtYmlvIG1lZGlvIGVuIFBBUyBmdWUgLTE1IG1tSGcgKGbDoXJtYWNvKSB2cy4gLTUKICAgIG1tSGcgKHBsYWNlYm8pLCAkdCA9IC00LjIkLCAkcCA8IDAuMDAxJCwgSUMgOTUlOiBbLTEzLjUsIC02LjVdLiIKCioqRGlzY3VzacOzbjoqKgoKLSAgIEludGVycHJldGFyIHJlc3VsdGFkb3MgZW4gZWwgY29udGV4dG8gY2zDrW5pY28sIGNvbXBhcmFuZG8gY29uCiAgICBsaXRlcmF0dXJhIHByZXZpYS4KLSAgIERpc2N1dGlyIGxpbWl0YWNpb25lcyAoZS5nLiwgdGFtYcOxbyBtdWVzdHJhbCwgc2VzZ29zKSB5IGFwbGljYWNpb25lcwogICAgcHLDoWN0aWNhcy4KLSAgICoqRWplbXBsbzoqKiAiTGEgcmVkdWNjacOzbiBkZSAxMCBtbUhnIGVuIFBBUyBlcyBjbMOtbmljYW1lbnRlCiAgICByZWxldmFudGUsIHBlcm8gc2UgbmVjZXNpdGFuIGVzdHVkaW9zIHNvYnJlIGVmZWN0b3Mgc2VjdW5kYXJpb3MuIgoKKipDb25jbHVzaW9uZXMgeSBSZWNvbWVuZGFjaW9uZXM6KioKCi0gICBSZXN1bWlyIGhhbGxhemdvcyB5IHN1Z2VyaXIgYWNjaW9uZXMgKGUuZy4sIGFwcm9iYXIgZWwgZsOhcm1hY28sCiAgICBpbXBsZW1lbnRhciBpbnRlcnZlbmNpb25lcykuCi0gICAqKkVqZW1wbG86KiogIkVsIGbDoXJtYWNvIGVzIGVmaWNheiBwYXJhIHJlZHVjaXIgbGEgUEFTOyBzZQogICAgcmVjb21pZW5kYSB1biBlbnNheW8gZGUgZmFzZSBJSUkuIgoKKipBcMOpbmRpY2VzOioqCgotICAgSW5jbHVpciBjw7NkaWdvLCB0YWJsYXMgYWRpY2lvbmFsZXMgbyBncsOhZmljb3MgZGUgZGlhZ27Ds3N0aWNvLgotICAgKipFamVtcGxvOioqIEPDs2RpZ28gUiBwYXJhIGVsIGFuw6FsaXNpczoKICAgIGB0LnRlc3QocGFzX2Zhcm1hY28sIHBhc19wbGFjZWJvLCBwYWlyZWQ9RkFMU0UpYC4KCiMjIyBDb211bmljYWNpw7NuIGRlIFJlc3VsdGFkb3MgSW5mZXJlbmNpYWxlcwoKLSAgICoqQ2xhcmlkYWQ6KiogVXNhciBsZW5ndWFqZSBhY2Nlc2libGUgcGFyYSBjbMOtbmljb3Mgbm8gZXhwZXJ0b3MgZW4KICAgIGVzdGFkw61zdGljYSwgZXZpdGFuZG8gamVyZ2EgdMOpY25pY2EgaW5uZWNlc2FyaWEuCiAgICAtICAgKipFamVtcGxvOioqIEVuIGx1Z2FyIGRlICJyZWNoYXphbW9zICRIXzAkIGNvbiAkcCA8IDAuMDUkIiwKICAgICAgICBkZWNpciAiZWwgZsOhcm1hY28gcmVkdWpvIHNpZ25pZmljYXRpdmFtZW50ZSBsYSBwcmVzacOzbiBhcnRlcmlhbAogICAgICAgIGVuIGNvbXBhcmFjacOzbiBjb24gZWwgcGxhY2Viby4iCi0gICAqKlZpc3VhbGl6YWNpw7NuOioqIFVzYXIgZ3LDoWZpY29zIChlLmcuLCBib3hwbG90cywgY3VydmFzIGRlIHNlcmllcwogICAgdGVtcG9yYWxlcykgcGFyYSBjb21wbGVtZW50YXIgbG9zIHJlc3VsdGFkb3MgbnVtw6lyaWNvcy4KICAgIC0gICAqKkVqZW1wbG86KiogVW4gYm94cGxvdCBtb3N0cmFuZG8gbGEgZGlzdHJpYnVjacOzbiBkZWwgY2FtYmlvIGVuCiAgICAgICAgUEFTIHBvciBncnVwbyByZXNhbHRhIGxhIGRpZmVyZW5jaWEgZW50cmUgZsOhcm1hY28geSBwbGFjZWJvLgotICAgKipSaWdvciBlc3RhZMOtc3RpY286KiogUmVwb3J0YXIgdmFsb3JlcyBwLCBpbnRlcnZhbG9zIGRlIGNvbmZpYW56YSB5CiAgICB0YW1hw7FvcyBkZWwgZWZlY3RvLiBFdml0YXIgc29icmVpbnRlcnByZXRhciAkcCQtdmFsb3JlczsgZW5mYXRpemFyCiAgICBsYSByZWxldmFuY2lhIGNsw61uaWNhLgogICAgLSAgICoqRWplbXBsbzoqKiAiTGEgZGlmZXJlbmNpYSBkZSAxMCBtbUhnIChJQyA5NSU6IFs2LjUsIDEzLjVdKSBlcwogICAgICAgIGVzdGFkw61zdGljYW1lbnRlIHNpZ25pZmljYXRpdmEgKCRwIDwgMC4wMDEkKSB5IGNsw61uaWNhbWVudGUKICAgICAgICByZWxldmFudGUsIHN1cGVyYW5kbyBlbCB1bWJyYWwgZGUgNSBtbUhnIHJlY29tZW5kYWRvLiIKLSAgICoqw4l0aWNhOioqIFJlcG9ydGFyIGxpbWl0YWNpb25lcyB5IGV2aXRhciBjb25jbHVzaW9uZXMgZXhhZ2VyYWRhcy4KICAgIFBvciBlamVtcGxvLCBubyBnZW5lcmFsaXphciByZXN1bHRhZG9zIGRlIHVuYSBwb2JsYWNpw7NuIGVzcGVjw61maWNhIGEKICAgIG90cmFzIHNpbiBldmlkZW5jaWEuCi0gICAqKkF1ZGllbmNpYToqKiBBZGFwdGFyIGVsIGluZm9ybWUgYWwgcMO6YmxpY28gKGUuZy4sIGNsw61uaWNvcywKICAgIHJlZ3VsYWRvcmVzLCBwYWNpZW50ZXMpLiBQYXJhIHBhY2llbnRlcywgdXNhciB0w6lybWlub3Mgc2ltcGxlcyBjb21vCiAgICAiZWwgbWVkaWNhbWVudG8gYmFqw7MgbGEgcHJlc2nDs24gYXJ0ZXJpYWwgZW4gcHJvbWVkaW8gMTAgcHVudG9zIG3DoXMKICAgIHF1ZSBlbCBwbGFjZWJvLiIKLSAgICoqRWplbXBsbyBwcsOhY3RpY286KiogRW4gZWwgZXN0dWRpbyBkZSBkaWFiZXRlcywgZWwgaW5mb3JtZQogICAgY29tdW5pY2E6ICJVbiBhdW1lbnRvIGRlIDEgdW5pZGFkIGVuIGVsIElNQyBpbmNyZW1lbnRhIGVsIHJpZXNnbyBkZQogICAgZGlhYmV0ZXMgZW4gMTMlIChJQyA5NSU6IFs1JSwgMjIlXSwgJHAgPSAwLjAwMiQpLiBFc3RvIHN1Z2llcmUgcXVlCiAgICByZWR1Y2lyIGVsIElNQyBtZWRpYW50ZSBpbnRlcnZlbmNpb25lcyBkZSBlc3RpbG8gZGUgdmlkYSBwb2Ryw61hCiAgICBkaXNtaW51aXIgbGEgaW5jaWRlbmNpYSBkZSBkaWFiZXRlcy4iCgojIyBSZWN1cnNvcyBwYXJhIGVsIEF1dG9lc3R1ZGlvIGVuIFNhbHVkCgojIyMgTGVjdHVyYXM6CgotICAgIkJpb3N0YXRpc3RpY3M6IEEgRm91bmRhdGlvbiBmb3IgQW5hbHlzaXMgaW4gdGhlIEhlYWx0aCBTY2llbmNlcyIgZGUKICAgIERhbmllbCAoQ2Fww610dWxvcyBzb2JyZSBhcGxpY2FjaW9uZXMgcHLDoWN0aWNhcykuCi0gICAiTWVkaWNhbCBTdGF0aXN0aWNzOiBBIFRleHRib29rIGZvciB0aGUgSGVhbHRoIFNjaWVuY2VzIiBkZSBDYW1wYmVsbAogICAgZXQgYWwuIChDYXDDrXR1bG9zIHNvYnJlIGFuw6FsaXNpcyB5IHJlZGFjY2nDs24pLgotICAgIlRoZSBFbGVtZW50cyBvZiBTdGF0aXN0aWNhbCBMZWFybmluZyIgZGUgSGFzdGllIGV0IGFsLiAoQ2Fww610dWxvcwogICAgc29icmUgZGlhZ27Ds3N0aWNvIGRlIHN1cHVlc3RvcykuCgojIyMgRWplcmNpY2lvcyBwcsOhY3RpY29zOgoKLSAgIEFuYWxpemFyIHVuIGNvbmp1bnRvIGRlIGRhdG9zIGRlIE5IQU5FUyAoZS5nLiwgZ2x1Y29zYSwgY29sZXN0ZXJvbCkKICAgIGNvbiByZWdyZXNpw7NuIGxvZ8Otc3RpY2EsIHZlcmlmaWNhbmRvIHN1cHVlc3Rvcy4KLSAgIFJlYWxpemFyIHVuIGFuw6FsaXNpcyBkZSBzZXJpZXMgdGVtcG9yYWxlcyBlbiBkYXRvcyBkZSBpbmZsdWVuemEgKENEQwogICAgRmx1VmlldyksIGFqdXN0YW5kbyB1biBtb2RlbG8gU0FSSU1BLgotICAgUmVkYWN0YXIgdW4gaW5mb3JtZSBjb21wbGV0byBwYXJhIHVuIGVuc2F5byBjbMOtbmljbyBzaW11bGFkbywKICAgIGluY2x1eWVuZG8gZ3LDoWZpY29zIHkgZGlhZ27Ds3N0aWNvcyBkZSBzdXB1ZXN0b3MuCgojIyMgSGVycmFtaWVudGFzIGNvbXB1dGFjaW9uYWxlczoKCi0gICAqKlI6KiogUGFxdWV0ZXMgYHN0YXRzYCAodC50ZXN0LCBsbSksIGBjYXJgIChkaWFnbsOzc3RpY29zOgogICAgc2hhcGlyby50ZXN0LCBsZXZlbmVUZXN0KSwgYGdncGxvdDJgICh2aXN1YWxpemFjacOzbikuCiAgICAtICAgKipFamVtcGxvOioqIGBzaGFwaXJvLnRlc3QocmVzaWQobW9kZWwpKWAgcGFyYSBub3JtYWxpZGFkOwogICAgICAgIGBnZ3Bsb3QoZGF0YSwgYWVzKHg9dHJhdGFtaWVudG8sIHk9cGFzKSkgKyBnZW9tX2JveHBsb3QoKWAgcGFyYQogICAgICAgIHZpc3VhbGl6YWNpw7NuLgotICAgKipQeXRob246KiogTGlicmVyw61hcyBgc3RhdHNtb2RlbHNgIChyZWdyZXNpw7NuLCBBTkNPVkEpLAogICAgYHNjaXB5LnN0YXRzYCAocHJ1ZWJhcyBkZSBub3JtYWxpZGFkKSwgYHNlYWJvcm5gICh2aXN1YWxpemFjacOzbikuCiAgICAtICAgKipFamVtcGxvOioqCiAgICAgICAgYHN0YXRzbW9kZWxzLnN0YXRzLmRpYWdub3N0aWMuaGV0X2JyZXVzY2hwYWdhbihyZXNpZCwgWClgIHBhcmEKICAgICAgICBob21vY2VkYXN0aWNpZGFkOwogICAgICAgIGBzbnMuYm94cGxvdCh4PSd0cmF0YW1pZW50bycsIHk9J3BhcycsIGRhdGE9ZGF0b3MpYC4KCiMjIyBCYXNlcyBkZSBkYXRvczoKCi0gICBOSEFORVMgcGFyYSBiaW9tYXJjYWRvcmVzIChlLmcuLCBnbHVjb3NhLCBwcmVzacOzbiBhcnRlcmlhbCkuCi0gICBDbGluaWNhbFRyaWFscy5nb3YgcGFyYSBkYXRvcyBkZSBlbnNheW9zIGNsw61uaWNvcy4KLSAgIFdITyBHbG9iYWwgSGVhbHRoIE9ic2VydmF0b3J5IHBhcmEgZGF0b3MgZXBpZGVtaW9sw7NnaWNvcyAoZS5nLiwKICAgIGluY2lkZW5jaWEgZGUgZW5mZXJtZWRhZGVzKS4KCiMgVGFibGEgUmVzdW1lbjogQXBsaWNhY2lvbmVzIFByw6FjdGljYXMgeSBFc3R1ZGlvcyBkZSBDYXNvIGVuIFNhbHVkCgpgYGB7ciBhcGxpY2FjaW9uZXMtdGFibGUsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2FzaXMnLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCgojIENyZWFyIGxhIHRhYmxhCnRhYmxhX2FwbGljYWNpb25lcyA8LSBkYXRhLmZyYW1lKAogICLDgXJlYSBkZSBBcGxpY2FjacOzbiIgPSBjKAogICAgIkVuc2F5byBDbMOtbmljbyIsCiAgICAiRXBpZGVtaW9sb2fDrWEiLAogICAgIlNlcmllcyBUZW1wb3JhbGVzIiwKICAgICJWYWxpZGFjacOzbiBkZSBTdXB1ZXN0b3MiLAogICAgIlZhbGlkYWNpw7NuIGRlIFN1cHVlc3RvcyIsCiAgICAiVmFsaWRhY2nDs24gZGUgU3VwdWVzdG9zIiwKICAgICJSZWRhY2Npw7NuIGRlIEluZm9ybWVzIgogICksCiAgIk3DqXRvZG8gRXN0YWTDrXN0aWNvIiA9IGMoCiAgICAiUHJ1ZWJhIHQgZGUgZG9zIG11ZXN0cmFzIiwKICAgICJSZWdyZXNpw7NuIGxvZ8Otc3RpY2EiLAogICAgIk1vZGVsbyBTQVJJTUEiLAogICAgIlRyYW5zZm9ybWFjacOzbiBkZSBkYXRvcyAobG9nYXJpdG1vKSIsCiAgICAiUHJ1ZWJhcyBubyBwYXJhbcOpdHJpY2FzIiwKICAgICJEaWFnbsOzc3RpY29zIGdyw6FmaWNvcyB5IGVzdGFkw61zdGljb3MiLAogICAgIkVzdHJ1Y3R1cmEgZXN0YW5kYXJpemFkYSBkZSBpbmZvcm1lIgogICksCiAgIlZhbGlkYWNpw7NuIGRlIFN1cHVlc3RvcyIgPSBjKAogICAgIk5vcm1hbGlkYWQgKFEtUSBwbG90LCBTaGFwaXJvLVdpbGspIiwKICAgICJJbmRlcGVuZGVuY2lhLCBsaW5lYWxpZGFkLCBzaW4gbXVsdGljb2xpbmVhbGlkYWQiLAogICAgIkVzdGFjaW9uYXJpZWRhZCwgbm9ybWFsaWRhZCBkZSByZXNpZHVvcywgYXV0b2NvcnJlbGFjacOzbiAoQUNGKSIsCiAgICAiTm9ybWFsaWRhZCB5IGhvbW9jZWRhc3RpY2lkYWQgdHJhcyB0cmFuc2Zvcm1hY2nDs24iLAogICAgIk5vIHJlcXVpZXJlIG5vcm1hbGlkYWQgbmkgaG9tb2NlZGFzdGljaWRhZCIsCiAgICAiU2hhcGlyby1XaWxrLCBMZXZlbmUsIER1cmJpbi1XYXRzb24sIEFDRiIsCiAgICAiUmVwb3J0ZSBleHBsw61jaXRvIGRlIGRpYWduw7NzdGljb3MgeSBwcnVlYmFzIgogICksCiAgIkludGVycHJldGFjacOzbiBDbMOtbmljYSIgPSBjKAogICAgIkRpZmVyZW5jaWEgZGUgMTAgbW1IZyBlbiBQQVM6IGNsw61uaWNhbWVudGUgcmVsZXZhbnRlIiwKICAgICJBdW1lbnRvIGRlbCAxMyUgZW4gb2RkcyBkZSBkaWFiZXRlcyBwb3IgY2FkYSB1bmlkYWQgZGUgSU1DIiwKICAgICJQcmVkaWNjacOzbiBwcmVjaXNhIGRlIHBpY29zIGRlIGluZmx1ZW56YSBlbiBpbnZpZXJubyIsCiAgICAiRGF0b3MgdHJhbnNmb3JtYWRvcyBwZXJtaXRlbiB1c2FyIG3DqXRvZG9zIHBhcmFtw6l0cmljb3MgdsOhbGlkb3MiLAogICAgIlVzbyBkZSBtw6l0b2RvcyByb2J1c3RvcyBjdWFuZG8gbG9zIHN1cHVlc3RvcyBmYWxsYW4iLAogICAgIkdhcmFudGl6YSB2YWxpZGV6IHkgcmVwcm9kdWNpYmlsaWRhZCBkZWwgYW7DoWxpc2lzIiwKICAgICJDb211bmljYWNpw7NuIGNsYXJhIHkgw6l0aWNhIGRlIHJlc3VsdGFkb3MgcGFyYSB0b21hIGRlIGRlY2lzaW9uZXMiCiAgKSwKICAiRWplbXBsbyBQcsOhY3RpY28iID0gYygKICAgICJGw6FybWFjbyByZWR1Y2UgUEFTIGVuIDEwIG1tSGcgbcOhcyBxdWUgcGxhY2VibyAoSUMgOTUlOiBbNi41LCAxMy41XSwgcCA8IDAuMDAxKSIsCiAgICAiSU1DIGFzb2NpYWRvIGEgZGlhYmV0ZXM6IE9SID0gMS4xMyAoSUMgOTUlOiBbMS4wNSwgMS4yMl0sIHAgPSAwLjAwMikiLAogICAgIlNBUklNQSgxLDEsMSl4KDEsMSwxKeKCheKCgiBwcmVkaWNlIGNhc29zIGRlIGluZmx1ZW56YSBjb24gUk1TRSA9IDQ1IiwKICAgICJsbihQQVMpIGNvcnJpZ2Ugbm8gbm9ybWFsaWRhZCAoU2hhcGlyby1XaWxrIHAgPSAwLjE1IHRyYXMgdHJhbnNmb3JtYWNpw7NuKSIsCiAgICAiUHJ1ZWJhIGRlIFdpbGNveG9uIHVzYWRhIGN1YW5kbyBkYXRvcyBubyBub3JtYWxlcyBwZXJzaXN0ZW4iLAogICAgIkxldmVuZSAocCA9IDAuMDEpIGRldGVjdGEgaGV0ZXJvY2VkYXN0aWNpZGFkOyBzZSBhcGxpY2EgY29ycmVjY2nDs24iLAogICAgIkluZm9ybWUgaW5jbHV5ZSBtZXRvZG9sb2fDrWEsIHJlc3VsdGFkb3MsIGRpc2N1c2nDs24geSBhcMOpbmRpY2VzIGNvbiBjw7NkaWdvIgogICksCiAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFCikKCiMgTW9zdHJhciB0YWJsYQprYWJsZSh0YWJsYV9hcGxpY2FjaW9uZXMsICJodG1sIiwgCiAgICAgIGNhcHRpb24gPSAiVGFibGEgMTE6IFJlc3VtZW4gZGUgYXBsaWNhY2lvbmVzIHByw6FjdGljYXMgZGUgbGEgZXN0YWTDrXN0aWNhIGluZmVyZW5jaWFsIGVuIHNhbHVkIikgJT4lCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiLCAicmVzcG9uc2l2ZSIpLCBmdWxsX3dpZHRoID0gRkFMU0UpICU+JQogIHNjcm9sbF9ib3god2lkdGggPSAiMTAwJSIsIGhlaWdodCA9ICI1MDBweCIpCgpgYGAKCiMgQ29uY2x1c2nDs246IEVzdGFkw61zdGljYSBJbmZlcmVuY2lhbCBwYXJhIGVsIFNlY3RvciBTYWx1ZAoKTGEgZXN0YWTDrXN0aWNhIGluZmVyZW5jaWFsIGVzIHVuYSBoZXJyYW1pZW50YSBmdW5kYW1lbnRhbCBlbiBlbCBzZWN0b3IKc2FsdWQgcGFyYSB0cmFuc2Zvcm1hciBkYXRvcyBlbiBldmlkZW5jaWEgY2llbnTDrWZpY2EsIGd1aWFyIGRlY2lzaW9uZXMKY2zDrW5pY2FzLCBldmFsdWFyIGludGVydmVuY2lvbmVzIHkgcHJlZGVjaXIgdGVuZGVuY2lhcyBlcGlkZW1pb2zDs2dpY2FzLgpBIGxvIGxhcmdvIGRlIGVzdGUgdGVtYXJpbywgc2UgaGFuIGRlc2Fycm9sbGFkbyBkZSBmb3JtYSBwcm9ncmVzaXZhIHkKYXBsaWNhZGEgbG9zIHByaW5jaXBhbGVzIG3DqXRvZG9zIGluZmVyZW5jaWFsZXMg4oCUZGVzZGUgbGEgZXN0aW1hY2nDs24gZGUKcGFyw6FtZXRyb3MgaGFzdGEgZWwgYW7DoWxpc2lzIGRlIHNlcmllcyB0ZW1wb3JhbGVz4oCULCBzaWVtcHJlIGNvbiB1bgplbmZvcXVlIGNlbnRyYWRvIGVuIGVsIHByb2Zlc2lvbmFsIGRlIGxhIHNhbHVkOiBtw6lkaWNvLCBpbnZlc3RpZ2Fkb3IKY2zDrW5pY28sIGVwaWRlbWnDs2xvZ28gbyBnZXN0b3Igc2FuaXRhcmlvLgoKU2UgaGEgZGVtb3N0cmFkbyBjw7NtbyB0w6ljbmljYXMgY29tbyBsYXMgcHJ1ZWJhcyBkZSBoaXDDs3Rlc2lzLCBBTk9WQSwKcmVncmVzacOzbiwgbcOpdG9kb3MgbXVsdGl2YXJpYWRvcyB5IG1vZGVsb3MgYmF5ZXNpYW5vcyBwZXJtaXRlbiByZXNwb25kZXIKcHJlZ3VudGFzIGNyw610aWNhcyBlbiBzYWx1ZDogwr9FcyBlZmVjdGl2byB1biBudWV2byB0cmF0YW1pZW50bz8gwr9RdcOpCmZhY3RvcmVzIHByZWRpY2VuIGxhIGRpYWJldGVzPyDCv0PDs21vIGV2b2x1Y2lvbmEgdW5hIGVwaWRlbWlhPyBBZGVtw6FzLCBzZQpoYSBlbmZhdGl6YWRvIGxhIGltcG9ydGFuY2lhIGRlIHZhbGlkYXIgc3VwdWVzdG9zIGVzdGFkw61zdGljb3MsIHV0aWxpemFyCmhlcnJhbWllbnRhcyBjb21wdXRhY2lvbmFsZXMgY29tbyBSIHkgUHl0aG9uLCB5IGNvbXVuaWNhciByZXN1bHRhZG9zIGNvbgpyaWdvciB5IGNsYXJpZGFkLCBldml0YW5kbyBlcnJvcmVzIGNvbXVuZXMgY29tbyBsYSBzb2JyZWludGVycHJldGFjacOzbgpkZWwgdmFsb3IgKnAqIG8gZWwgZGVzY3VpZG8gZGUgbGEgcmVsZXZhbmNpYSBjbMOtbmljYS4KCkxvcyBlc3R1ZGlvcyBkZSBjYXNvIHkgYXBsaWNhY2lvbmVzIHByw6FjdGljYXMgaGFuIG1vc3RyYWRvIHF1ZSBsYQplc3RhZMOtc3RpY2Egbm8gZXMgc29sbyB1bmEgaGVycmFtaWVudGEgdMOpY25pY2EsIHNpbm8gdW5hIGNvbXBldGVuY2lhCmVzZW5jaWFsIHBhcmEgbGEgdG9tYSBkZSBkZWNpc2lvbmVzIGJhc2FkYSBlbiBldmlkZW5jaWEuIENvbiBlbCBhcG95byBkZQpzb2Z0d2FyZSBtb2Rlcm5vLCBzaW11bGFjaW9uZXMsIGJvb3RzdHJhcCB5IHZpc3VhbGl6YWNpw7NuIGVmZWN0aXZhLCBsb3MKcHJvZmVzaW9uYWxlcyBkZSBsYSBzYWx1ZCBwdWVkZW4gbm8gc29sbyBlbnRlbmRlciwgc2lubyB0YW1iacOpbiBhcGxpY2FyCnkgY29tdW5pY2FyIGhhbGxhemdvcyBlc3RhZMOtc3RpY29zIGNvbiBjb25maWFuemEuCgpFbiB1biBtdW5kbyBkb25kZSBsb3MgZGF0b3MgY2zDrW5pY29zIHkgZXBpZGVtaW9sw7NnaWNvcyBjcmVjZW4KZXhwb25lbmNpYWxtZW50ZSwgZG9taW5hciBsYSBlc3RhZMOtc3RpY2EgaW5mZXJlbmNpYWwgeWEgbm8gZXMgb3BjaW9uYWw6CmVzIHVuYSByZXNwb25zYWJpbGlkYWQgcHJvZmVzaW9uYWwgeSDDqXRpY2EgcGFyYSBnYXJhbnRpemFyIGxhIGNhbGlkYWQsCmVmaWNhY2lhIHkgZXF1aWRhZCBlbiBsYSBhdGVuY2nDs24gc2FuaXRhcmlhLgoKIyBUYWJsYSBSZXN1bWVuIEZpbmFsOiBUZW1hcmlvcyBkZSBFc3RhZMOtc3RpY2EgSW5mZXJlbmNpYWwgZW4gU2FsdWQKCmBgYHtyIHJlc3VtZW4tZmluYWwtdGFibGUsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2FzaXMnLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCgojIENyZWFyIGxhIHRhYmxhIGNvbiB0b2RvcyBsb3MgdGVtYXMKdGFibGFfZmluYWwgPC0gZGF0YS5mcmFtZSgKICAiVGVtYSIgPSBjKAogICAgIjEuIEVzdGltYWNpw7NuIGRlIFBhcsOhbWV0cm9zIiwKICAgICIyLiBQcnVlYmFzIGRlIEhpcMOzdGVzaXMiLAogICAgIjMuIEFuw6FsaXNpcyBkZSBWYXJpYW56YSAoQU5PVkEpIiwKICAgICI0LiBSZWdyZXNpw7NuIHkgTW9kZWxvcyBMaW5lYWxlcyIsCiAgICAiNS4gTcOpdG9kb3MgTXVsdGl2YXJpYWRvcyIsCiAgICAiNi4gSW5mZXJlbmNpYSBCYXllc2lhbmEiLAogICAgIjcuIERpc2XDsW8gZGUgRXhwZXJpbWVudG9zIChET0UpIiwKICAgICI4LiBBbsOhbGlzaXMgZGUgU2VyaWVzIFRlbXBvcmFsZXMiLAogICAgIjkuIEhlcnJhbWllbnRhcyBDb21wdXRhY2lvbmFsZXMiLAogICAgIjEwLiBBcGxpY2FjaW9uZXMgUHLDoWN0aWNhcyB5IEVzdHVkaW9zIGRlIENhc28iCiAgKSwKICAiT2JqZXRpdm8gUHJpbmNpcGFsIiA9IGMoCiAgICAiRXN0aW1hciBwYXLDoW1ldHJvcyBwb2JsYWNpb25hbGVzIChtZWRpYSwgcHJvcG9yY2nDs24sIHZhcmlhbnphKSBhIHBhcnRpciBkZSBtdWVzdHJhcyIsCiAgICAiRXZhbHVhciBhZmlybWFjaW9uZXMgc29icmUgcGFyw6FtZXRyb3MgbWVkaWFudGUgcHJ1ZWJhcyBlc3RhZMOtc3RpY2FzIiwKICAgICJDb21wYXJhciBtZWRpYXMgZW50cmUgbcO6bHRpcGxlcyBncnVwb3MgKGUuZy4sIHRyYXRhbWllbnRvcykiLAogICAgIk1vZGVsYXIgcmVsYWNpb25lcyBlbnRyZSB2YXJpYWJsZXMgKGUuZy4sIElNQyB5IGdsdWNvc2EpIiwKICAgICJSZWR1Y2lyIGRpbWVuc2lvbmFsaWRhZCwgY2xhc2lmaWNhciBvIGRlc2N1YnJpciBwYXRyb25lcyBlbiBkYXRvcyBtdWx0aXZhcmlhbnRlcyIsCiAgICAiQWN0dWFsaXphciBjcmVlbmNpYXMgc29icmUgcGFyw6FtZXRyb3MgdXNhbmRvIGRhdG9zIHkgY29ub2NpbWllbnRvIHByZXZpbyIsCiAgICAiRGlzZcOxYXIgZXN0dWRpb3MgY2zDrW5pY29zIGNvbiBhbGVhdG9yaXphY2nDs24sIGJsb3F1ZW8geSBjb250cm9sIGRlIHNlc2dvcyIsCiAgICAiUHJlZGVjaXIgdGVuZGVuY2lhcyB5IHBhdHJvbmVzIGVuIGRhdG9zIHNlY3VlbmNpYWxlcyAoZS5nLiwgYnJvdGVzIGRlIGVuZmVybWVkYWRlcykiLAogICAgIkFwbGljYXIgc29mdHdhcmUsIHNpbXVsYWNpw7NuIHkgdmlzdWFsaXphY2nDs24gcGFyYSBhbsOhbGlzaXMgaW5mZXJlbmNpYWwiLAogICAgIkludGVncmFyIG3DqXRvZG9zIGVuIGNvbnRleHRvcyByZWFsZXMsIHZhbGlkYXIgc3VwdWVzdG9zIHkgY29tdW5pY2FyIHJlc3VsdGFkb3MiCiAgKSwKICAiTcOpdG9kb3MgQ2xhdmUiID0gYygKICAgICJFc3RpbWFjacOzbiBwdW50dWFsIHkgcG9yIGludGVydmFsb3MsIHRhbWHDsW8gbXVlc3RyYWwiLAogICAgIlBydWViYXMgdCwgeiwgY2hpLWN1YWRyYWRvLCBlcnJvcmVzIFRpcG8gSS9JSSwgcG90ZW5jaWEiLAogICAgIkFOT1ZBIGRlIHVubyB5IGRvcyBmYWN0b3JlcywgcG9zdC1ob2MgKFR1a2V5LCBCb25mZXJyb25pKSIsCiAgICAiUmVncmVzacOzbiBsaW5lYWwgc2ltcGxlIHkgbcO6bHRpcGxlLCBHTE0gKGxvZ8Otc3RpY2EsIFBvaXNzb24pIiwKICAgICJQQ0EsIGFuw6FsaXNpcyBmYWN0b3JpYWwsIGNsw7pzdGVyLCBhbsOhbGlzaXMgZGlzY3JpbWluYW50ZSwgQUNNIiwKICAgICJUZW9yZW1hIGRlIEJheWVzLCBwcmlvcnMsIE1DTUMsIGludGVydmFsb3MgZGUgY3JlZGliaWxpZGFkIiwKICAgICJEaXNlw7FvIGNvbXBsZXRhbWVudGUgYWxlYXRvcml6YWRvLCBibG9xdWVzLCBmYWN0b3JpYWwsIG1lZGlkYXMgcmVwZXRpZGFzIiwKICAgICJBUklNQSwgU0FSSU1BLCBkZXNjb21wb3NpY2nDs24gU1RMLCBHQVJDSCIsCiAgICAiUiwgUHl0aG9uLCBib290c3RyYXAsIGdncGxvdDIsIHNlYWJvcm4iLAogICAgIkVzdHVkaW9zIGRlIGNhc28sIGRpYWduw7NzdGljbyBkZSBzdXB1ZXN0b3MsIHJlZGFjY2nDs24gZGUgaW5mb3JtZXMiCiAgKSwKICAiQXBsaWNhY2nDs24gZW4gU2FsdWQiID0gYygKICAgICJFc3RpbWFyIHByZXZhbGVuY2lhIGRlIGRpYWJldGVzLCBuaXZlbGVzIHByb21lZGlvIGRlIGNvbGVzdGVyb2wiLAogICAgIkRldGVybWluYXIgc2kgdW4gZsOhcm1hY28gcmVkdWNlIGxhIHByZXNpw7NuIGFydGVyaWFsIiwKICAgICJDb21wYXJhciBlZmVjdG8gZGUgdHJlcyBkb3NpcyBkZSB1biBhbnRpaGlwZXJ0ZW5zaXZvIiwKICAgICJQcmVkZWNpciByaWVzZ28gZGUgaW5mYXJ0byB1c2FuZG8gbcO6bHRpcGxlcyBmYWN0b3JlcyIsCiAgICAiSWRlbnRpZmljYXIgcGVyZmlsZXMgZGUgcGFjaWVudGVzIG8gZmFjdG9yZXMgc3VieWFjZW50ZXMgZW4gc8OtbnRvbWFzIiwKICAgICJBY3R1YWxpemFyIGVmaWNhY2lhIGRlIHVuYSB2YWN1bmEgY29uIGRhdG9zIGRlIG51ZXZvcyBlbnNheW9zIiwKICAgICJEaXNlw7FhciB1biBlbnNheW8gY2zDrW5pY28gY29uIGFsZWF0b3JpemFjacOzbiB5IGNvbnRyb2wiLAogICAgIlByZWRlY2lyIGNhc29zIGRlIGluZmx1ZW56YSBwYXJhIHBsYW5pZmljYXIgcmVjdXJzb3MgaG9zcGl0YWxhcmlvcyIsCiAgICAiQW5hbGl6YXIgZGF0b3MgY2zDrW5pY29zIGNvbiBSL1B5dGhvbiB5IHZpc3VhbGl6YXIgcmVzdWx0YWRvcyIsCiAgICAiVmFsaWRhciBzdXB1ZXN0b3MsIGludGVycHJldGFyIHJlc3VsdGFkb3MgY2zDrW5pY2FtZW50ZSwgcmVkYWN0YXIgaW5mb3JtZXMiCiAgKSwKICAiRWplbXBsbyBQcsOhY3RpY28iID0gYygKICAgICJJQyBkZWwgOTUlIHBhcmEgbGEgbWVkaWEgZGUgZ2x1Y29zYTogWzExNSwgMTI1XSBtZy9kTCIsCiAgICAidC10ZXN0IG11ZXN0cmEgcXVlIGVsIGbDoXJtYWNvIHJlZHVjZSBQQVMgKHAgPCAwLjAxKSIsCiAgICAiQU5PVkEgZGV0ZWN0YSBkaWZlcmVuY2lhcyBlbnRyZSB0cmVzIHRyYXRhbWllbnRvcyAocCA9IDAuMDE1KSIsCiAgICAiUmVncmVzacOzbiBsb2fDrXN0aWNhOiBJTUMgaW5jcmVtZW50YSBvZGRzIGRlIGRpYWJldGVzIGVuIDEzJSIsCiAgICAiUENBIHJlZHVjZSAxMCBiaW9tYXJjYWRvcmVzIGEgMiBjb21wb25lbnRlcyBwcmluY2lwYWxlcyIsCiAgICAiUG9zdGVyaW9yaTogcHJvYmFiaWxpZGFkIGRlIHJlc3B1ZXN0YSBhbCBmw6FybWFjbyA9IDc1JSAoSUNyIDk1JTogWzY4JSwgODIlXSkiLAogICAgIkJsb3F1ZXMgcG9yIGVkYWQgZW4gZW5zYXlvIHBhcmEgY29udHJvbGFyIGNvbmZ1c2nDs24iLAogICAgIlNBUklNQSBwcmVkaWNlIHBpY28gZGUgaW5mbHVlbnphIGNvbiBSTVNFID0gNDUgY2Fzb3MiLAogICAgIkJvb3RzdHJhcCBlc3RpbWEgSUMgcGFyYSBtZWRpYW5hIHNpbiBhc3VtaXIgbm9ybWFsaWRhZCIsCiAgICAiSW5mb3JtZSBmaW5hbCBjb211bmljYSByZXN1bHRhZG9zIGNsw61uaWNhbWVudGUgcmVsZXZhbnRlcyBjb24gZ3LDoWZpY29zIHkgY8OzZGlnbyIKICApLAogIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRQopCgojIE1vc3RyYXIgdGFibGEKa2FibGUodGFibGFfZmluYWwsICJodG1sIiwgCiAgICAgIGNhcHRpb24gPSAiVGFibGEgMTI6IFJlc3VtZW4gY29tcGxldG8gZGUgbG9zIHRlbWFzIGRlIGVzdGFkw61zdGljYSBpbmZlcmVuY2lhbCBlbiBzYWx1ZCIpICU+JQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgInJlc3BvbnNpdmUiKSwgZnVsbF93aWR0aCA9IEZBTFNFKSAlPiUKICBzY3JvbGxfYm94KHdpZHRoID0gIjEwMCUiLCBoZWlnaHQgPSAiNjAwcHgiKQoKCmBgYAoKIyBSZWN1cnNvcyBCaWJsaW9ncsOhZmljb3M6IEVzdGFkw61zdGljYSBJbmZlcmVuY2lhbCBlbiBlbCBTZWN0b3IgU2FsdWQKCkEgY29udGludWFjacOzbiwgc2UgcHJlc2VudGEgdW5hIGxpc3RhIGRlIGxpYnJvcyB5IHJlY3Vyc29zIGVzZW5jaWFsZXMKc29icmUgZXN0YWTDrXN0aWNhIGluZmVyZW5jaWFsLCBjb24gZW5mb3F1ZSBlbiBhcGxpY2FjaW9uZXMgZW4gc2FsdWQsCmVwaWRlbWlvbG9nw61hIHkgY2llbmNpYXMgY2zDrW5pY2FzLiBUb2RvcyBsb3MgZW5sYWNlcyBoYW4gc2lkbwp2ZXJpZmljYWRvcyB5IHNvbiBhY2Nlc2libGVzIChqdW5pbyAyMDI1KS4KCiMjIPCfk5ggTGlicm9zIGRlIFRleHRvIHkgUmVmZXJlbmNpYQoKLSAgICoqRGFuaWVsLCBXLiBXLiwgJiBDcm9zcywgQy4gTC4gKDIwMTgpLiAqQmlvc3RhdGlzdGljczogQSBGb3VuZGF0aW9uCiAgICBmb3IgQW5hbHlzaXMgaW4gdGhlIEhlYWx0aCBTY2llbmNlcyogKDExdGggZWQuKS4qKlwKICAgIExpYnJvIGRlIHJlZmVyZW5jaWEgY2zDoXNpY2EgcGFyYSBlc3R1ZGlhbnRlcyB5IHByb2Zlc2lvbmFsZXMgZW4KICAgIHNhbHVkLiBDdWJyZSBkZXNkZSBwcnVlYmFzIGRlIGhpcMOzdGVzaXMgaGFzdGEgcmVncmVzacOzbiB5IEFOT1ZBLlwKICAgIPCflJcKICAgIDxodHRwczovL3d3dy53aWxleS5jb20vZW4tdXMvQmlvc3RhdGlzdGljcyUzQStBK0ZvdW5kYXRpb24rZm9yK0FuYWx5c2lzK2luK3RoZStIZWFsdGgrU2NpZW5jZXMlMkMrMTF0aCtFZGl0aW9uLXAtOTc4MTExOTQzNTk3Mz4KCi0gICAqKlJvc25lciwgQi4gKDIwMTUpLiAqRnVuZGFtZW50YWxzIG9mIEJpb3N0YXRpc3RpY3MqICg4dGggZWQuKS4qKlwKICAgIEVuZm9xdWUgY2xhcm8geSBhcGxpY2FkbyBhIG3DqXRvZG9zIGluZmVyZW5jaWFsZXMsIGNvbiBlamVtcGxvcwogICAgY2zDrW5pY29zIGRldGFsbGFkb3MuIElkZWFsIHBhcmEgYXV0b2VzdHVkaW8uXAogICAg8J+UlwogICAgPGh0dHBzOi8vd3d3LmNlbmdhZ2UuY29tL2MvZnVuZGFtZW50YWxzLW9mLWJpb3N0YXRpc3RpY3MtOGUtcm9zbmVyLzk3ODEzMDUyNjg5MjAvPgoKLSAgICoqTW9vcmUsIEQuIFMuLCBOb3R6LCBXLiwgJiBGbGlnbmVyLCBNLiBBLiAoMjAyMSkuICpUaGUgQmFzaWMKICAgIFByYWN0aWNlIG9mIFN0YXRpc3RpY3MqICg5dGggZWQuKS4qKlwKICAgIEV4Y2VsZW50ZSBwYXJhIHByaW5jaXBpYW50ZXMuIEVuZmF0aXphIGxhIGNvbXByZW5zacOzbiBjb25jZXB0dWFsIHkKICAgIGxhIGludGVycHJldGFjacOzbiBjbMOtbmljYS5cCiAgICDwn5SXCiAgICA8aHR0cHM6Ly93d3cubWFjbWlsbGFubGVhcm5pbmcuY29tL2NvbGxlZ2UvdXMvcHJvZHVjdC9UaGUtQmFzaWMtUHJhY3RpY2Utb2YtU3RhdGlzdGljcy9wLzEzMTkzNDM3OFg+CgotICAgKipHZWxtYW4sIEEuLCBDYXJsaW4sIEouIEIuLCBTdGVybiwgSC4gUy4sIER1bnNvbiwgRC4gQi4sIFZlaHRhcmksCiAgICBBLiwgJiBSdWJpbiwgRC4gQi4gKDIwMTMpLiAqQmF5ZXNpYW4gRGF0YSBBbmFseXNpcyogKDNyZCBlZC4pLioqXAogICAgUmVmZXJlbmNpYSBkZWZpbml0aXZhIHNvYnJlIGluZmVyZW5jaWEgYmF5ZXNpYW5hLCBjb24gYXBsaWNhY2lvbmVzCiAgICBlbiBzYWx1ZCBww7pibGljYSB5IGVuc2F5b3MgY2zDrW5pY29zLlwKICAgIPCflJcKICAgIDxodHRwczovL3d3dy5yb3V0bGVkZ2UuY29tL0JheWVzaWFuLURhdGEtQW5hbHlzaXMtVGhpcmQtRWRpdGlvbi9HZWxtYW4tQ2FybGluLVN0ZXJuLUR1bnNvbi1WZWh0YXJpLVJ1YmluL3AvYm9vay85NzgxNDM5ODQwOTU1PgoKLSAgICoqU2h1bXdheSwgUi4gSC4sICYgU3RvZmZlciwgRC4gUy4gKDIwMTcpLiAqVGltZSBTZXJpZXMgQW5hbHlzaXMgYW5kCiAgICBJdHMgQXBwbGljYXRpb25zOiBXaXRoIFIgRXhhbXBsZXMqICg0dGggZWQuKS4qKlwKICAgIEd1w61hIHByw6FjdGljYSBwYXJhIGFuw6FsaXNpcyBkZSBzZXJpZXMgdGVtcG9yYWxlcyBlbiBzYWx1ZCwgY29uCiAgICBjw7NkaWdvIFIgaW5jbHVpZG8uXAogICAg8J+UlyA8aHR0cHM6Ly93d3cuc3ByaW5nZXIuY29tL2dwL2Jvb2svOTc4MzMxOTUyNDUxMT4KCi0gICAqKkhhaXIsIEouIEYuLCBCbGFjaywgVy4gQy4sIEJhYmluLCBCLiBKLiwgJiBBbmRlcnNvbiwgUi4gRS4gKDIwMTkpLgogICAgKk11bHRpdmFyaWF0ZSBEYXRhIEFuYWx5c2lzKiAoOHRoIGVkLikuKipcCiAgICBFc3TDoW5kYXIgZW4gbcOpdG9kb3MgbXVsdGl2YXJpYWRvcyBjb21vIFBDQSwgZmFjdG9yZXMsIGNsw7pzdGVyIHkKICAgIGRpc2NyaW1pbmFudGUuXAogICAg8J+UlwogICAgPGh0dHBzOi8vd3d3LnBlYXJzb24uY29tL3VzL2hpZ2hlci1lZHVjYXRpb24vcHJvZ3JhbS9IYWlyLU11bHRpdmFyaWF0ZS1EYXRhLUFuYWx5c2lzLTh0aC1FZGl0aW9uL1BHTTMzNDkyMC5odG1sPgoKIyMg8J+MkCBSZWN1cnNvcyBHcmF0dWl0b3MgeSBPcGVuIEFjY2VzcwoKLSAgICoqSHluZG1hbiwgUi4gSi4sICYgQXRoYW5hc29wb3Vsb3MsIEcuICgyMDIxKS4gKkZvcmVjYXN0aW5nOgogICAgUHJpbmNpcGxlcyBhbmQgUHJhY3RpY2UqICgzcmQgZWQuKS4qKlwKICAgIExpYnJvIGdyYXR1aXRvIGNvbiBlbmZvcXVlIHByw6FjdGljbyBlbiBzZXJpZXMgdGVtcG9yYWxlcywKICAgIGFtcGxpYW1lbnRlIHVzYWRvIGVuIHNhbHVkIHDDumJsaWNhLlwKICAgIPCflJcgPGh0dHBzOi8vb3RleHRzLmNvbS9mcHAzLz5cCiAgICDinIUgVmVyc2nDs24gaW50ZXJhY3RpdmEgY29uIGPDs2RpZ28gUiAodGlkeXZlcnRzKQoKLSAgICoqSWxsb3dza3ksIEIuLCBEZWFuLCBTLiwgZXQgYWwuICpJbnRyb2R1Y3RvcnkgU3RhdGlzdGljcyouCiAgICBPcGVuU3RheC4qKlwKICAgIFJlY3Vyc28gZ3JhdHVpdG8gY29uIGNvYmVydHVyYSBjb21wbGV0YSBkZSBlc3RhZMOtc3RpY2EgaW5mZXJlbmNpYWwuCiAgICBJZGVhbCBwYXJhIHJlcGFzby5cCiAgICDwn5SXIDxodHRwczovL29wZW5zdGF4Lm9yZy9kZXRhaWxzL2Jvb2tzL2ludHJvZHVjdG9yeS1zdGF0aXN0aWNzPlwKICAgIOKchSBEZXNjYXJnYSBncmF0dWl0YSBlbiBQREYsIEVQVUIgeSBvbmxpbmUKCi0gICAqKlN6YWLDsywgQS4gKDIwMjMpLiAqU3RhdGlzdGljcyBmb3IgSGVhbHRoLCBMaWZlIGFuZCBTb2NpYWwKICAgIFNjaWVuY2VzKi4gQm9va2Jvb24uKipcCiAgICBFbmZvcXVlIGFwbGljYWRvIGEgc2FsdWQgeSBjaWVuY2lhcyBzb2NpYWxlcywgY29uIGVqZW1wbG9zIHJlYWxlcyB5CiAgICBzb2Z0d2FyZS5cCiAgICDwn5SXCiAgICA8aHR0cHM6Ly9ib29rYm9vbi5jb20vZW4vc3RhdGlzdGljcy1mb3ItaGVhbHRoLWxpZmUtYW5kLXNvY2lhbC1zY2llbmNlcy1lYm9vaz5cCiAgICDinIUgR3JhdGlzIGNvbiByZWdpc3RybyAoUERGKQoKIyMg8J+Wpe+4jyBEb2N1bWVudGFjacOzbiB5IEhlcnJhbWllbnRhcyBkZSBTb2Z0d2FyZQoKLSAgICoqUiBDb3JlIFRlYW0gKDIwMjMpLiAqQW4gSW50cm9kdWN0aW9uIHRvIFIqLioqXAogICAgTWFudWFsIG9maWNpYWwgZGUgUiwgaWRlYWwgcGFyYSBhcHJlbmRlciBlc3RhZMOtc3RpY2EgaW5mZXJlbmNpYWwgY29uCiAgICBjw7NkaWdvLlwKICAgIPCflJcgPGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL2RvYy9tYW51YWxzL3ItcmVsZWFzZS9SLWludHJvLmh0bWw+CgotICAgKipXaWNraGFtLCBILiwgJiBHcm9sZW11bmQsIEcuICgyMDE3KS4gKlIgZm9yIERhdGEgU2NpZW5jZSouKipcCiAgICBHdcOtYSBlc2VuY2lhbCBwYXJhIHVzYXIgYHRpZHl2ZXJzZWAsIHZpc3VhbGl6YWNpw7NuIHkgbW9kZWxhZG8gZW4KICAgIHNhbHVkLlwKICAgIPCflJcgPGh0dHBzOi8vcjRkcy5oYWRsZXkubnovPlwKICAgIOKchSBHcmF0aXMgb25saW5lLCBhY3R1YWxpemFkbyBwYXJhIDIwMjMKCi0gICAqKlN0YXRzbW9kZWxzIERvY3VtZW50YXRpb24gKFB5dGhvbikuKipcCiAgICBEb2N1bWVudGFjacOzbiB0w6ljbmljYSBwYXJhIHJlZ3Jlc2nDs24sIEFOT1ZBLCBzZXJpZXMgdGVtcG9yYWxlcyB5CiAgICBtw6FzLlwKICAgIPCflJcgPGh0dHBzOi8vd3d3LnN0YXRzbW9kZWxzLm9yZy9zdGFibGUvaW5kZXguaHRtbD4KCi0gICAqKnNjaWtpdC1sZWFybiBVc2VyIEd1aWRlLioqXAogICAgUGFyYSBtw6l0b2RvcyBhdmFuemFkb3MgY29tbyBib290c3RyYXAsIHZhbGlkYWNpw7NuIGNydXphZGEgeSBtb2RlbG9zCiAgICBwcmVkaWN0aXZvcy5cCiAgICDwn5SXIDxodHRwczovL3NjaWtpdC1sZWFybi5vcmcvc3RhYmxlL3VzZXJfZ3VpZGUuaHRtbD4KCiMjIPCfj5vvuI8gQmFzZXMgZGUgRGF0b3MgeSBSZXBvc2l0b3Jpb3MgUMO6YmxpY29zCgotICAgKipOSEFORVMgKE5hdGlvbmFsIEhlYWx0aCBhbmQgTnV0cml0aW9uIEV4YW1pbmF0aW9uIFN1cnZleSkuKipcCiAgICBCYXNlIGRlIGRhdG9zIHJlYWxpc3RhIHBhcmEgcHJhY3RpY2FyIGFuw6FsaXNpcyBpbmZlcmVuY2lhbCBlbgogICAgc2FsdWQuXAogICAg8J+UlyA8aHR0cHM6Ly93d3duLmNkYy5nb3YvbmNocy9uaGFuZXMvPgoKLSAgICoqQ2xpbmljYWxUcmlhbHMuZ292LioqXAogICAgUmVnaXN0cm8gcMO6YmxpY28gZGUgZW5zYXlvcyBjbMOtbmljb3MuIElkZWFsIHBhcmEgZXN0dWRpb3MgZGUgY2Fzby5cCiAgICDwn5SXIDxodHRwczovL2NsaW5pY2FsdHJpYWxzLmdvdi8+CgotICAgKipXSE8gR2xvYmFsIEhlYWx0aCBPYnNlcnZhdG9yeSAoR0hPKS4qKlwKICAgIERhdG9zIGVwaWRlbWlvbMOzZ2ljb3MgZ2xvYmFsZXMgKGRpYWJldGVzLCBoaXBlcnRlbnNpw7NuLAogICAgdHViZXJjdWxvc2lzLCBldGMuKS5cCiAgICDwn5SXIDxodHRwczovL3d3dy53aG8uaW50L2RhdGEvZ2hvPgoKLSAgICoqS2FnZ2xlIERhdGFzZXRzIChIZWFsdGgpLioqXAogICAgUGxhdGFmb3JtYSBjb24gZGF0YXNldHMgcmVhbGVzIGV0aXF1ZXRhZG9zIHBhcmEgYW7DoWxpc2lzIChlLmcuLAogICAgZGlhYmV0ZXMsIGPDoW5jZXIpLlwKICAgIPCflJcgPGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZGF0YXNldHM/dGFncz0xMzIwMi1oZWFsdGg+CgojIyDwn46TIEN1cnNvcyB5IFBsYXRhZm9ybWFzIEludGVyYWN0aXZhcwoKLSAgICoqQ291cnNlcmE6ICpEYXRhIFNjaWVuY2UgZm9yIEhlYWx0aGNhcmUqIChVbml2ZXJzaWRhZCBkZQogICAgQ2FsaWZvcm5pYSwgRGF2aXMpLioqXAogICAgRW5mb3F1ZSBlbiBhbsOhbGlzaXMgZGUgZGF0b3MgY2zDrW5pY29zIHkgdG9tYSBkZSBkZWNpc2lvbmVzLlwKICAgIPCflJcKICAgIDxodHRwczovL3d3dy5jb3Vyc2VyYS5vcmcvc3BlY2lhbGl6YXRpb25zL2RhdGEtc2NpZW5jZS1oZWFsdGhjYXJlPgoKLSAgICoqZWRYOiAqU3RhdGlzdGljcyBhbmQgUiBmb3IgdGhlIExpZmUgU2NpZW5jZXMqIChIYXJ2YXJkCiAgICBVbml2ZXJzaXR5KS4qKlwKICAgIEN1cnNvIGdyYXR1aXRvIGNvbiBjZXJ0aWZpY2FkbyBvcGNpb25hbC4gSWRlYWwgcGFyYSBwcmluY2lwaWFudGVzLlwKICAgIPCflJcKICAgIDxodHRwczovL3d3dy5lZHgub3JnL2NvdXJzZS9zdGF0aXN0aWNzLWFuZC1yLWZvci10aGUtbGlmZS1zY2llbmNlcz4KCi0gICAqKktoYW4gQWNhZGVteTogKkluZmVyZW50aWFsIFN0YXRpc3RpY3MqLioqXAogICAgRXhwbGljYWNpb25lcyBjbGFyYXMgeSB2aXN1YWxlcyBkZSBjb25jZXB0b3MgY2xhdmUgKElDLCBwcnVlYmFzLAogICAgZXJyb3JlcykuXAogICAg8J+UlwogICAgPGh0dHBzOi8vd3d3LmtoYW5hY2FkZW15Lm9yZy9tYXRoL3N0YXRpc3RpY3MtcHJvYmFiaWxpdHkvc2lnbmlmaWNhbmNlLXRlc3RzPgo=