1 Temario para autoestudio avanzado de Estadística Inferencial

1.1 1. Fundamentos de estadística enferencial

1.1.1 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.1.2 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.1.3 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.

1.2 2. Estimación de Parámetros

1.2.1 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.

1.2.2 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.

1.3 3. Pruebas de Hipótesis

1.3.1 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\).

1.3.2 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).

1.3.3 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.

1.4 4. Análisis de Varianza (ANOVA)

1.4.1 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.

1.4.2 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.

1.4.3 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.

1.5 5. Regresión y Modelos Lineales

1.5.1 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\).

1.5.2 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.

1.5.3 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.

1.6 6. Métodos Multivariados

1.6.1 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.

1.6.2 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).

1.6.3 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.

1.7 7. Inferencia Bayesiana

1.7.1 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).

1.7.2 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í”.

1.7.3 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.

1.8 8. Diseño de Experimentos

1.8.1 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.

1.8.2 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.

1.8.3 8.3 Análisis de experimentos

  • Interpretación de interacciones: Efectos combinados no aditivos.
  • Análisis de covarianza (ANCOVA): Ajusta por covariables continuas.

1.9 9. Análisis de Series Temporales

1.9.1 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).

1.9.2 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.

1.9.3 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.

1.10 10. Herramientas Computacionales

1.10.1 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).

1.10.2 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.

1.10.3 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).

1.11 11. Aplicaciones prácticas y estudios de caso

1.11.1 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.

1.11.2 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.11.3 11.3 Redacción de informes

  • Estructura de un informe estadístico: Introducción, métodos, resultados, discusión, conclusiones.

  • Comunicación de resultados inferenciales: Claridad, precisión, evitando malas interpretaciones.

2 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.

2.1 1.1 Conceptos básicos

2.1.1 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.

2.1.2 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\)).

2.1.3 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.

2.2 1.2 Probabilidad Avanzada

2.2.1 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”.

2.2.2 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.

2.2.3 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.

2.3 1.3 Distribuciones de Probabilidad

2.3.1 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}\).

2.3.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.

2.3.3 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})\).

2.4 Recursos para el Autoestudio en Salud

2.4.1 Lecturas:

  • “Statistical Methods in Medical Research” de Armitage, Berry y Matthews.
  • “Biostatistics: A Foundation for Analysis in the Health Sciences” de Daniel.

2.4.2 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).

2.4.3 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.

2.4.4 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.

3 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 &lt; 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.

4 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.

4.1 2.1 Estimación Puntual

4.1.1 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.

4.1.2 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:
    1. Definir la función de verosimilitud según la distribución asumida (e.g., normal, binomial).
    2. Maximizar \(L(\theta)\) (a menudo usando el logaritmo: \(\ln L(\theta)\)).
    3. 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:
    1. Calcular momentos muestrales: \(m_1 = \bar{x}\), \(m_2 = \frac{1}{n} \sum (x_i - \bar{x})^2\).
    2. Igualarlos a momentos poblacionales: \(E(X) = \mu\), \(E(X^2) - [E(X)]^2 = \sigma^2\).
    3. 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.

4.2 2.2 Estimación por Intervalos

4.2.1 Intervalos de Confianza para Medias, Proporciones y Varianzas

Los intervalos de confianza (IC) proporcionan un rango de valores plausibles para un parámetro poblacional, junto con un nivel de confianza (e.g., 95%) que indica la probabilidad de que el intervalo contenga el parámetro verdadero. En salud, los IC son esenciales para cuantificar la incertidumbre en estimaciones como tasas de mortalidad, prevalencias o efectos de tratamientos.

Intervalo de confianza para la media (\(\mu\)):

  • Fórmula: \[ \bar{x} \pm z_{\alpha/2} \cdot \frac{\sigma}{\sqrt{n}} \quad (\text{varianza conocida}) \] \[ \bar{x} \pm t_{\alpha/2, n-1} \cdot \frac{s}{\sqrt{n}} \quad (\text{varianza desconocida, muestra pequeña}) \] Donde \(z_{\alpha/2}\) es el valor crítico de la normal estándar (e.g., 1.96 para 95%), \(t_{\alpha/2, n-1}\) es el valor crítico de la t de Student, \(\sigma\) o \(s\) es la desviación estándar poblacional o muestral, y \(n\) es el tamaño muestral.
  • Aplicación en salud: Estimar la media de presión arterial sistólica en pacientes hipertensos.
  • Ejemplo práctico: En una muestra de 50 pacientes, la media de glucosa es \(\bar{x} = 130 \, \text{mg/dL}\), con \(s = 15 \, \text{mg/dL}\). El IC al 95% es: \[ 130 \pm t_{0.025, 49} \cdot \frac{15}{\sqrt{50}} \approx 130 \pm 2.01 \cdot 2.12 \approx (125.74, 134.26) \] Esto indica que con 95% de confianza, la media poblacional de glucosa está entre 125.74 y 134.26 mg/dL.

Intervalo de confianza para la proporción (\(p\)):

  • Fórmula (aproximación normal para \(n \hat{p} \geq 5\), \(n(1-\hat{p}) \geq 5\)): \[ \hat{p} \pm z_{\alpha/2} \cdot \sqrt{\frac{\hat{p}(1-\hat{p})}{n}} \] Donde \(\hat{p}\) es la proporción muestral.
  • Aplicación en salud: Estimar la prevalencia de una enfermedad o la tasa de éxito de un tratamiento.
  • Ejemplo práctico: En un estudio de 200 pacientes, 40 responden a un tratamiento (\(\hat{p} = 0.2\)). El IC al 95% es: \[ 0.2 \pm 1.96 \cdot \sqrt{\frac{0.2 \cdot 0.8}{200}} \approx 0.2 \pm 0.055 \approx (0.145, 0.255) \] Esto sugiere que la proporción poblacional de respondedores está entre 14.5% y 25.5% con 95% de confianza.

Intervalo de confianza para la varianza (\(\sigma^2\)):

  • Fórmula (asumiendo normalidad): \[ \left( \frac{(n-1)s^2}{\chi^2_{\alpha/2, n-1}}, \frac{(n-1)s^2}{\chi^2_{1-\alpha/2, n-1}} \right) \] Donde \(\chi^2\) son valores críticos de la distribución Chi-cuadrado.
  • Aplicación en salud: Evaluar la variabilidad en tiempos de recuperación o niveles de biomarcadores.
  • Ejemplo práctico: Para una muestra de 30 pacientes, la varianza muestral de tiempos de recuperación es \(s^2 = 25 \, \text{días}^2\). El IC al 95% para \(\sigma^2\) es: \[ \left( \frac{29 \cdot 25}{45.722}, \frac{29 \cdot 25}{16.047} \right) \approx (15.84, 45.18) \] Esto indica que la varianza poblacional está entre 15.84 y 45.18 días² con 95% de confianza.

4.2.2 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:
    1. Identificar el parámetro de interés (\(\mu\), \(p\), \(\sigma^2\)).
    2. Seleccionar el nivel de confianza (e.g., 95%) y encontrar los valores críticos (\(z\), \(t\), \(\chi^2\)).
    3. Calcular el estadístico muestral (\(\bar{x}\), \(\hat{p}\), \(s^2\)) y el error estándar.
    4. 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.

4.2.3 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.

4.3 Recursos para el Autoestudio en Salud

4.3.1 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).

4.3.2 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.

4.3.3 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.

4.3.4 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.

5 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.

5.1 3.1 Fundamentos

5.1.1 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}}\))”.

5.1.2 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.

5.1.3 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.

5.2 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.

5.2.1 Pruebas para una y dos medias (t-test, z-test)

Prueba z para una media:

  • Uso: Comparar la media muestral (\(\bar{x}\)) con una media poblacional conocida (\(\mu_0\)) cuando la varianza poblacional (\(\sigma^2\)) es conocida y \(n \geq 30\).
  • Estadístico: \[ z = \frac{\bar{x} - \mu_0}{\sigma / \sqrt{n}} \] Comparado con valores críticos de la normal estándar (e.g., \(\pm 1.96\) para \(\alpha = 0.05\), bilateral).
  • Aplicación en salud: Evaluar si la media de glucosa en sangre de un grupo de pacientes (\(\bar{x} = 125 \, \text{mg/dL}\)) difiere de un estándar clínico (\(\mu_0 = 120 \, \text{mg/dL}\)).
  • Ejemplo práctico: En una muestra de 100 pacientes, con \(\sigma = 15\), \(\bar{x} = 125\), y \(\mu_0 = 120\), el estadístico es: \[ z = \frac{125 - 120}{15 / \sqrt{100}} = 3.33 \] Como \(z > 1.96\), se rechaza \(H_0\) (\(p < 0.05\)).

Prueba t para una media:

  • Uso: Igual que la z-test, pero cuando \(\sigma^2\) es desconocida o \(n < 30\), asumiendo normalidad.
  • Estadístico: \[ t = \frac{\bar{x} - \mu_0}{s / \sqrt{n}} \] Donde \(s\) es la desviación estándar muestral, y se usa la distribución t con \(n-1\) grados de libertad.
  • Aplicación en salud: Comparar el tiempo promedio de recuperación tras una cirugía con un estándar.
  • Ejemplo práctico: En 20 pacientes, el tiempo de recuperación es \(\bar{x} = 10 \, \text{días}\), \(s = 2 \, \text{días}\), y se compara con \(\mu_0 = 9 \, \text{días}\). El estadístico es: \[ t = \frac{10 - 9}{2 / \sqrt{20}} = 2.24 \] Con \(t_{0.025, 19} \approx 2.093\), se rechaza \(H_0\) si \(p < 0.05\).

Prueba t para dos medias:

  • Uso: Comparar las medias de dos grupos independientes (\(\mu_1 \neq \mu_2\)) o pareados.
  • Estadístico (independientes): \[ t = \frac{\bar{x}_1 - \bar{x}_2}{\sqrt{\frac{s_1^2}{n_1} + \frac{s_2^2}{n_2}}} \] Asumiendo varianzas iguales (o usando la corrección de Welch si no).
  • Aplicación en salud: Comparar la presión arterial entre un grupo tratado y un grupo placebo.
  • Ejemplo práctico: En un ensayo clínico, el grupo tratado (\(n_1 = 50\), \(\bar{x}_1 = 115 \, \text{mmHg}\), \(s_1 = 10\)) y el grupo placebo (\(n_2 = 50\), \(\bar{x}_2 = 120 \, \text{mmHg}\), \(s_2 = 12\)) tienen: \[ t = \frac{115 - 120}{\sqrt{\frac{10^2}{50} + \frac{12^2}{50}}} \approx -2.14 \] Comparado con \(t_{0.025, 98} \approx 1.98\), se rechaza \(H_0\).

5.2.2 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\)).

5.2.3 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\).

5.3 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.

5.3.1 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.

5.3.2 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.

5.3.3 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).

5.4 Recursos para el Autoestudio en Salud

5.4.1 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.

5.4.2 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.

5.4.3 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.

5.4.4 Bases de datos:

  • NHANES para datos de salud poblacional.
  • Ensayos clínicos en ClinicalTrials.gov para practicar pruebas de hipótesis.

6 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

7 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.

7.1 4.1 ANOVA de un factor

7.1.1 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.

7.1.2 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:

Fuente Grados de Libertad Suma de Cuadrados Cuadrado Medio F Valor p
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.

7.1.3 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.

7.2 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.

7.2.1 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.

7.2.2 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\)).

7.3 4.3 ANOVA Multifactorial y Modelos Mixtos

7.3.1 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.

7.3.2 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\)).

7.4 Recursos para el Autoestudio en Salud

7.4.1 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).

7.4.2 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.

7.4.3 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').

7.4.4 Bases de datos:

  • NHANES para datos de biomarcadores (e.g., colesterol, presión arterial).
  • ClinicalTrials.gov para datos de ensayos clínicos.

8 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

9 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.

9.1 5.1 Regresión Lineal Simple

9.1.1 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.

9.1.2 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 \]

9.1.3 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.

9.2 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 $).

9.2.1 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).

9.2.2 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.

9.2.3 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.

9.3 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).

9.3.1 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) $).

9.3.2 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,
    1. 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.

9.4 Recursos para el Autoestudio en Salud

9.4.1 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).

9.4.2 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).

9.4.3 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()).

9.4.4 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).

10 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 &gt; 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

11 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.

11.1 6.1 Análisis de Componentes Principales (PCA)

11.1.1 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:
    1. Estandarizar las variables: \(Z = \frac{X - \mu}{\sigma}\).
    2. Calcular la matriz de correlación \(R\).
    3. Obtener autovalores (\(\lambda_i\)) y autovectores (\(v_i\)).
    4. 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.

11.1.2 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.

11.2 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.

11.2.1 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).

11.2.2 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.

11.3 6.3 Análisis Discriminante y Clúster

11.3.1 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.

11.3.2 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.

11.4 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.

11.4.1 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.

11.4.2 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.

11.4.3 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.

11.5 Recursos para el Autoestudio en Salud

11.5.1 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).

11.5.2 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).

11.5.3 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).

11.5.4 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.

12 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

13 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.

13.1 7.1 Fundamentos

13.1.1 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\%\).

13.1.2 Priors: Informativos y No Informativos

El prior \(P(\theta)\) refleja el conocimiento previo sobre el parámetro y puede influir en la posteriori, especialmente con muestras pequeñas.

Priors informativos:

  • Basados en datos previos, literatura o conocimiento experto.
  • Ventaja: Incorporan información relevante, útil en ensayos clínicos con datos históricos.
  • Ejemplo: Para la efectividad de una vacuna (\(\theta\)), un prior informativo podría ser \(\theta \sim \text{Beta}(80, 20)\), basado en ensayos previos que sugieren un 80% de eficacia.
  • Aplicación en salud: Usar datos de ensayos previos para definir un prior sobre la tasa de respuesta a un fármaco.

Priors no informativos:

  • Reflejan mínima información previa, permitiendo que los datos dominen la posteriori.
  • Ejemplos: Uniforme (\(\theta \sim \text{Uniform}(0, 1)\)) para proporciones, o Jeffreys prior para parámetros continuos.
  • Ventaja: Reducen la subjetividad cuando no hay información previa fiable.
  • Ejemplo: Para la media de presión arterial (\(\mu\)), un prior no informativo podría ser \(\mu \sim N(0, 10^6)\), con gran varianza.

Priors conjugados: Simplifican cálculos analíticos. Ejemplo: Un prior Beta para una proporción binomial produce una posteriori Beta.

Ejemplo práctico: En un estudio de prevalencia de hipertensión, un prior no informativo (\(\theta \sim \text{Beta}(1, 1)\)) se actualiza con datos de 50 pacientes (10 hipertensos), dando una posteriori \(\theta \sim \text{Beta}(11, 41)\), con media \(\frac{11}{11+41} \approx 0.212\).

13.2 7.2 Métodos Bayesianos

13.2.1 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.

13.2.2 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.

13.3 7.3 Aplicaciones Prácticas

13.3.1 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.

13.3.2 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:

  1. Definir el modelo (prior y verosimilitud).
  2. Ejecutar MCMC para generar muestras de la posteriori.
  3. 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.

13.4 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.

13.4.1 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.

13.4.2 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.

13.4.3 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.

13.5 Recursos para el Autoestudio en Salud

13.5.1 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).

13.5.2 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.

13.5.3 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()).

13.5.4 Bases de datos:

  • NHANES para datos de biomarcadores.
  • ClinicalTrials.gov para datos de ensayos clínicos.
  • WHO datasets para tasas de enfermedad.

14 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

15 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.

15.1 8.1 Principios Básicos

15.1.1 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.

15.1.2 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.

15.2 8.2 Diseños Avanzados

15.2.1 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.

15.2.2 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\)).

15.3 8.3 Análisis de Experimentos

15.3.1 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.

15.3.2 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.

15.4 Recursos para el Autoestudio en Salud

15.4.1 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).

15.4.2 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.

15.4.3 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.

15.4.4 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).

16 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

17 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.

17.1 9.1 Componentes de Series Temporales

17.1.1 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.

17.1.2 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.

17.2 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.

17.2.1 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.

17.2.2 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.

17.3 9.3 Modelos Avanzados

17.3.1 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.

17.3.2 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%.

17.4 Recursos para el Autoestudio en Salud

17.4.1 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).

17.4.2 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.

17.4.3 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().

17.4.4 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.

18 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

19 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.

19.1 10.1 Software Estadístico

19.1.1 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).

19.1.2 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.

19.2 10.2 Simulación y Bootstrap

19.2.1 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:
    1. Tomar \(B\) muestras con reemplazo del tamaño original (\(n\)).
    2. Calcular el estadístico de interés en cada muestra (e.g., media, mediana).
    3. 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.

19.2.2 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.

19.3 10.3 Visualización de Datos

19.3.1 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.

19.3.2 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.

19.4 Recursos para el Autoestudio en Salud

19.4.1 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).

19.4.2 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.

19.4.3 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).

19.4.4 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).

20 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 %&gt;% group_by(tratamiento) %&gt;% 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 &lt; 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 &lt; 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

21 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.

21.1 11.1 Análisis de Datos Reales

21.1.1 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.

21.1.2 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.

21.2 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.

21.2.1 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.

21.2.2 Transformaciones de Datos

Cuando los supuestos no se cumplen, las transformaciones de datos pueden corregir violaciones, permitiendo el uso de métodos paramétricos.

Transformaciones para normalidad:

  • Logaritmo: Útil para datos sesgados a la derecha (e.g., tiempos de hospitalización, conteos de eventos).
    • Ejemplo: \(Y' = \ln(Y + 1)\) para tiempos de recuperación no normales.
  • Raíz cuadrada: Estabiliza varianza en datos de conteo (e.g., número de infecciones).
  • Box-Cox: Transformación general para normalidad y homocedasticidad, seleccionando un parámetro \(\lambda\).
  • Aplicación en salud: Transformar los niveles de triglicéridos (sesgados) con un logaritmo antes de un ANOVA.
  • Ejemplo práctico: En el estudio de hipertensión, los residuos no normales (\(p = 0.03\)) se corrigen aplicando \(\ln(\text{PAS})\). Un nuevo Shapiro-Wilk da \(p = 0.15\), permitiendo el uso de ANOVA.

Transformaciones para homocedasticidad:

  • Logaritmo o raíz cuadrada: Reducen la varianza en grupos con heterocedasticidad.
  • Ponderación: Usar modelos con varianzas ponderadas (e.g., WLS en regresión).
  • Ejemplo práctico: En un estudio de glucosa, la heterocedasticidad (\(p = 0.01\), Levene) se corrige con una transformación logarítmica, dando \(p = 0.20\) en Levene.

Alternativas no paramétricas: Si las transformaciones no funcionan, usar pruebas como Mann-Whitney, Kruskal-Wallis o modelos robustos.

  • Ejemplo: En un estudio con datos no normales persistentes, se usa una prueba de Wilcoxon para comparar glucosa entre dos grupos.

21.3 11.3 Redacción de Informes

La redacción de informes estadísticos es crucial para comunicar resultados inferenciales de manera clara, precisa y reproducible, especialmente en salud, donde las decisiones impactan vidas.

21.3.1 Estructura de un Informe Estadístico

Un informe bien estructurado debe seguir un formato estándar que facilite la comprensión y replicación del análisis.

Introducción:

  • Describir el contexto clínico o epidemiológico, la pregunta de investigación y los objetivos.
  • Ejemplo: “Evaluar la eficacia de un nuevo fármaco antihipertensivo en la reducción de la presión arterial sistólica en pacientes con hipertensión leve.”

Metodología:

  • Diseño del estudio: Especificar el tipo de diseño (e.g., ensayo clínico aleatorizado, transversal).
  • Datos: Describir la fuente, tamaño muestral, variables (dependiente, independientes, covariables).
  • Métodos estadísticos: Detallar las pruebas o modelos utilizados (e.g., t-test, regresión logística, ARIMA), incluyendo software y paquetes (e.g., R, Python).
  • Supuestos: Indicar cómo se verificaron (e.g., normalidad con Shapiro-Wilk, homocedasticidad con Levene).
  • Ejemplo: “Se realizó un ensayo clínico aleatorizado con 200 pacientes, comparando el cambio en PAS usando una prueba t de dos muestras. La normalidad se verificó con un gráfico Q-Q y Shapiro-Wilk (\(p > 0.05\)).”

Resultados:

  • Presentar hallazgos clave con estadísticos, valores p, intervalos de confianza/credibilidad y gráficos.
  • Evitar interpretar en esta sección; solo reportar datos.
  • Ejemplo: “El cambio medio en PAS fue -15 mmHg (fármaco) vs. -5 mmHg (placebo), \(t = -4.2\), \(p < 0.001\), IC 95%: [-13.5, -6.5].”

Discusión:

  • Interpretar resultados en el contexto clínico, comparando con literatura previa.
  • Discutir limitaciones (e.g., tamaño muestral, sesgos) y aplicaciones prácticas.
  • Ejemplo: “La reducción de 10 mmHg en PAS es clínicamente relevante, pero se necesitan estudios sobre efectos secundarios.”

Conclusiones y Recomendaciones:

  • Resumir hallazgos y sugerir acciones (e.g., aprobar el fármaco, implementar intervenciones).
  • Ejemplo: “El fármaco es eficaz para reducir la PAS; se recomienda un ensayo de fase III.”

Apéndices:

  • Incluir código, tablas adicionales o gráficos de diagnóstico.
  • Ejemplo: Código R para el análisis: t.test(pas_farmaco, pas_placebo, paired=FALSE).

21.3.2 Comunicación de Resultados Inferenciales

  • Claridad: Usar lenguaje accesible para clínicos no expertos en estadística, evitando jerga técnica innecesaria.
    • Ejemplo: En lugar de “rechazamos \(H_0\) con \(p < 0.05\)”, decir “el fármaco redujo significativamente la presión arterial en comparación con el placebo.”
  • Visualización: Usar gráficos (e.g., boxplots, curvas de series temporales) para complementar los resultados numéricos.
    • Ejemplo: Un boxplot mostrando la distribución del cambio en PAS por grupo resalta la diferencia entre fármaco y placebo.
  • Rigor estadístico: Reportar valores p, intervalos de confianza y tamaños del efecto. Evitar sobreinterpretar \(p\)-valores; enfatizar la relevancia clínica.
    • Ejemplo: “La diferencia de 10 mmHg (IC 95%: [6.5, 13.5]) es estadísticamente significativa (\(p < 0.001\)) y clínicamente relevante, superando el umbral de 5 mmHg recomendado.”
  • Ética: Reportar limitaciones y evitar conclusiones exageradas. Por ejemplo, no generalizar resultados de una población específica a otras sin evidencia.
  • Audiencia: Adaptar el informe al público (e.g., clínicos, reguladores, pacientes). Para pacientes, usar términos simples como “el medicamento bajó la presión arterial en promedio 10 puntos más que el placebo.”
  • Ejemplo práctico: En el estudio de diabetes, el informe comunica: “Un aumento de 1 unidad en el IMC incrementa el riesgo de diabetes en 13% (IC 95%: [5%, 22%], \(p = 0.002\)). Esto sugiere que reducir el IMC mediante intervenciones de estilo de vida podría disminuir la incidencia de diabetes.”

21.4 Recursos para el Autoestudio en Salud

21.4.1 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).

21.4.2 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.

21.4.3 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).

21.4.4 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).

22 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

23 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.

24 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
  1. 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
  1. 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)
  1. 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)
  1. 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%
  1. 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
  1. 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%])
  1. 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
  1. 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
  1. 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
  1. 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

25 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).

25.1 📘 Libros de Texto y Referencia

25.2 🌐 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)

25.3 🖥️ Documentación y Herramientas de Software

25.4 🏛️ Bases de Datos y Repositorios Públicos

25.5 🎓 Cursos y Plataformas Interactivas

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=