1.Introducción
El concepto de análisis de imágenes satelitales antes de 1972 era simplemente visionario, sin embargo, con la llegada del programa Landsat, que ha consistido en una serie de misiones de observación satelital coordinada por la NASA y el Servicio Geológico de los Estados Unidos (USGS) (Ariza, 2013) se han logrado grandes avances en el area de percepción remota y teledetección, las cuales son una herramienta que permite el análisis espacial con gran cantidad de aplicaciones alrededor del mundo.
Tradicionalmente el uso de estas imágenes se da en el empleo de índices de vegetación, coberturas, usos de suelo y las dinámicas que se encuentran alrededor de estos (Gonzaga, 2014), existiendo también funciones emergentes, de las cuales Joyce, Belliss, Samsonov, McNeill, & Glassey (2009) destacan los crecientes programas operacionales de monitoreo de terremotos, fallas, actividad volcánica, deslizamientos de tierra, inundaciones e incendios forestales, así como los daños asociados a cada uno.
En el presente reporte tendremos un acercamiento al pre-procesamiento y obtención de información a partir de imágenes satelitales de nivel 1, tomadas por el satélite Landsat 8 sobre el municipio de Tenjo, Cundinamarca, empleando la herramienta de programación R studio.
2. Datos y Métodos
Metodología
El informe presenta una descripción inicial del área de estudio, y las coberturas determinadas a partir de un análisis manual mediante los software Ggis Desktop y Google Earth Pro, el preprocesamiento y la corrección radiométrica fue desarrollada en función de las ecuaciones ofrecidas por el USGS (2011), con estos resultados se presentan las diferentes combinaciones de imágenes en color verdadero y falso, las estadísticas de las bandas y las metodologías de segmentación con sus respectivos gráficos auxiliares, finalmente se muestra el procesos de clasificación no supervisado, su verificación en una región específica de la escena y la clasificación supervisada con la validación del modelo.
Área de estudio
El municipio de Tenjo se encuentra situado en el departamento de Cundinamarca, con coordenadas 4.871973, -74.145082 (Lat, Long), en el cuadrante Path 8, Row 57 de Landsat 8.
Aproximadamente a 20 kilometros de la ciudad de Bogotá, su casco urbano delimita con el área protegida del “cerro de Churugüaco Alto” y el ”cerro de Juaica”, cuenta con un afluente proveniente de Tabio (río Chicú), que alimenta la quebrada Socha, de la cual se abastecen las grandes áreas cubiertas y tradicionales de cultivo, caracterizadas por ser productoras de flores y hortalizas, para desembocar posteriormente en el río Bogotá a la altura del municipio de Cota.
La imagen satelital comprende una extensión considerable, por lo que será recortada con el fin de detallar únicamente el área de estudio, que se encuentra delimitada por las coordenadas tabuladas a continuación.
| 584052.6,527477.5 |
4º 46’ 18.21’’ N 74º 14’ 31.39’’ O |
4.771725,-74.242053 |
| 584052.6,542423.5 |
4º 54’ 24.93’’ N 74º 14’ 31.39’’ O |
4.906925,-74.242053 |
| 606125.0,542423.5 |
4º 54’ 24.93’’ N 74º 02’ 34.91’’ O |
4.906925,-74.043030 |
| 606125.0,527477.5 |
4º 46’ 18.21’’ N 74º 02’ 34.91’’ O |
4.771725,-74.043030 |
class : Extent
xmin : 584052.6
xmax : 606125
ymin : 527477.5
ymax : 542423.5
Usos de suelo
Según el acuerdo No. 10 de 2014 (Secretaría Municipal de Tenjo, 2014), De la secretaria general del concejo municipal, las 11.056,19 Hectáreas pertenecientes al municipio de Tenjo, cuenta con un 64,14% de área destinada a la actividad agropecuaria intensiva, 6,59% destinado a las reservas forestales de fines protectores – productores de la Cuenca Alta del Río Bogotá, y un total del 17,572% con determinantes ecológicos y de sostenibilidad específicos, con una proporción del 3,29% de suelos urbanos y de expansión urbana.
El área restante se encuentra bajo los términos de vivienda campesina, suelo suburbano, centros poblados rurales, sistema de infraestructura de servicios públicos e interés patrimonial.
[1] "SpatialPolygonsDataFrame"
attr(,"package")
[1] "sp"
[1] "+proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0"
Mapa de uso de suelo
- A continuación, se muestra una rápida caracterización de algunos usos de suelo en el área de estudio. Mediante 89 polígonos es muestreada el área de interés, identificando diferentes tipos de cobertura, facilitado por herramientas como Qgis, Google Earth Pro, y el conocimiento de la región.
| Urban |
Zonas construidas, urbanizadas |
| invernad |
Zonas de cultivo bajo invernadero |
| crop |
Zonas de cultivo tradicional en una fase desarrollada |
| uncovere |
Zonas de cultivo tradicional en fase de preparación |
Propiedades de imagenes
Las imágenes multiespectrales son obtenidas de la plataforma GloVis, ofrecida por el U.S. Geological Survey, del satelite Landsat 8, caracterizadas por dar información en 9 bandas OLI y 2 TIRS y una banda adicional de calidad, descritas a continuación
| Aerosol |
band1 |
| azul |
band2 |
| verde |
band3 |
| rojo |
band4 |
| NIR |
band5 |
| SWIR-1 |
band6 |
| SWIR-2 |
band7 |
| pancromatico |
band8 (omitida) |
| cirrus |
band9 (omitida) |
| TIRS-1 |
band10 (omitida) |
| TIRS-2 |
band11 (omitida) |
| QA |
bandQA (omitida) |
class : RasterLayer
dimensions : 7741, 7581, 58684521 (nrow, ncol, ncell)
resolution : 30, 30 (x, y)
extent : 446685, 674115, 362985, 595215 (xmin, xmax, ymin, ymax)
crs : +proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0
source : C:/Users/Elkin/Documents/R/Reporte 1/tenjo/olitirs/LC08_L1TP_008057_20181230_20190130_01_T1_B1.tif
names : LC08_L1TP_008057_20181230_20190130_01_T1_B1
values : 0, 65535 (min, max)
class : RasterLayer
dimensions : 15481, 15161, 234707441 (nrow, ncol, ncell)
resolution : 15, 15 (x, y)
extent : 446692.5, 674107.5, 362992.5, 595207.5 (xmin, xmax, ymin, ymax)
crs : +proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0
source : C:/Users/Elkin/Documents/R/Reporte 1/tenjo/olitirs/LC08_L1TP_008057_20181230_20190130_01_T1_B8.tif
names : LC08_L1TP_008057_20181230_20190130_01_T1_B8
values : 0, 65535 (min, max)
class : RasterLayer
dimensions : 7741, 7581, 58684521 (nrow, ncol, ncell)
resolution : 30, 30 (x, y)
extent : 446685, 674115, 362985, 595215 (xmin, xmax, ymin, ymax)
crs : +proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0
source : C:/Users/Elkin/Documents/R/Reporte 1/tenjo/olitirs/LC08_L1TP_008057_20181230_20190130_01_T1_B10.tif
names : LC08_L1TP_008057_20181230_20190130_01_T1_B10
values : 0, 65535 (min, max)
las bandas 1 a 7 y 9 contienen la misma información, así mismo las bandas 10 y 11.
De igual forma, la comparación entre las características de las bandas arroja el valor “TRUE” cuando son consistentes, por esta razón, se omite la banda 8.
[1] TRUE
Pre-procesamiento
Las bandas del espectro visible e infrarrojo cercano son detalladas a continuación en una escala de grises que define el Nivel Digital (DN) de los pixeles, a las cuales se les ha aplicado un estiramiento de contraste para incrementar las características de visualización. las bandas 8 a 11 son omitidas, tanto en visualización como en el análisis.
Bandas independientes
Banda 2

Banda 3

Banda 4

Banda 5

Corrección radiométrica
El archivo RasterStack “tenjolist” cuenta con las 7 bandas previamente recortadas, sin embargo, el proceso de corrección radiométrica (Imágenes de Nivel 1 a Nivel 2), mediante el cálculo de la reflectancia TOA, fue desarrollado en la herramienta QGIS.
El proceso consistió en utilizar la herramienta “Calculadora Raster” con las 7 bandas, introduciendo los valores de corrección radiometrica ofrecidos por el proveedor.
\[Reflectancia TOA = ((M_l*DN_b)+A_d) / Sin(Se)\]
Debido a la poca información que se logra obtener de las imágenes expuestas previamente, se puede recurrir a la combinación de varias bandas, ya sea en color verdadero RGB, combinando las bandas 4, 3 y 2 respectivamente en un gráfico, o en color falso, donde múltiples combinaciones arrojaran información adicional.
| Ángulo de elevación solar (Se) |
51.97116822 |
| Parámetro multiplicativo (Ml) |
2.0E-5 |
| Parámetro aditivo (Ad) |
-0.1 |
3. Resultados
Imagen en color verdadero

Imágenes en color falso
Una de las múltiples representaciones en color falso que permite visualizar información importante es la combinación de las bandas 5, 4 y 3 (NIR, verde y rojo), donde es fácilmente apreciable en color rojo la superficie cubierta por vegetación.
Otras importantes combinaciones se detallan a continuación
| Zonas Urbanas |
7 - 6 - 4 |
| Agricultura |
6 - 5 - 2 |
| Masas de Agua |
5 - 6 - 4 |
| Vegetación sana |
5 - 6 - 2 |
Resultados
CCF-Vegetación

CCF-Zonas Urbanas

CCF-Agricultura

CCF-Vegetación sana

Correlación enre bandas
Generar información a partir de combinación de bandas multiespectrales requiere cuidadosas selecciones, debido a que (Jensen, 2016) indica que una alta correlación entre bandas significará una redundancia en los datos, por lo que es posible que el análisis no sea representativo.

Perfiles Espectrales
A partir de los polígonos de caracterización de uso de suelo, se extraen de las 7 bandas los valores medios de reflectancia TOA, tabulados y graficados a continuación.

Métodos de segmentación por respuesta espectral-Índices
Callejo M. (2016) Explica que la finalidad de segmentar una imagen en función de su respuesta espectral, es poder determinar diferentes características de interés con mayor facilidad, el proceso se da a partir de constituciones homogéneas de textura, nivel digital, etc.
Esto simplificará la representación y el análisis en una nueva imagen más significativa, el primero de estos métodos es el desarrollo de índices cromáticos o índices de vegetación.
Estas medidas empíricas son obtenidas mediante la cuantificación y combinación de dos o mas bandas del espectro electromagnético, la aplicación adecuada de estos permitirá discriminar la cantidad, estado, y situación de la vegetación en la escena.
índice de vegetación de Diferencia Normalizada (NDVI)
El índice de vegetación de diferencia normalizada (NDVI) permite determinar cubiertas vegetales, medir el crecimiento y controlar la producción de biomasa (Callejo M., 2016).
\[NDVI = (NIR - RED) / (NIR + RED)\]

Índice Diferencial de Agua Normalizado (NDWI)
Empleando este índice será posible diferenciar las masas de agua y las zonas que tengan altos niveles de saturación de humedad empleando las bandas respectivas ofrecidas por las imágenes multiespectrales Landsat 8 o cualquier otro satélite, la finalidad de este índice es determinar el estrés hídrico de la vegetación, humedad o saturación del suelo y delimitación de embalses o cuerpos de agua
En el área de recursos hídricos, agrología y afines, se requiere la evaluación tanto de calidad como de cantidad de agua, por lo que se encuentran fácilmente múltiples metodologías mediante el análisis de datos con sensores remotos para determinar indicadores que ofrezcan información relevante. Algunas de las diferentes estrategias para determinar el Indice de Agua de Diferencia Normalizada (NDWI) se exponen a continuación
Gao (1996)
Los valores obtenidos oscilarán entre -1 y 1, que representarán las diferentes superficies de agua y vegetación con contenidos de humedad altos, o en caso contrario, la ausencia de esta.
La relación se da a partir de las bandas de Infrarrojo Cercano (NIR) e Infrarrojo de onda corta (SWIR).
Gao (1996) Argumenta que una máxima precisión se alcanzará si se usan dos canales del infrarrojo cercano, centrados en 0.86µm y 1.24µm.
Para el caso de Landsat 8 se empleará la banda SWIR-1 (1.57 µm – 1.65 µm)
\[NDWI = (NIR - SWIR) / (NIR + SWIR)\]

McFeeters (1996)
Con el fin de delinear las características de aguas abiertas y resaltar estas en la imagen satelital, el NDWI usa la banda NIR y la luz verde visible para incrementar la presencia de tales características, eliminando otras como el suelo y la vegetación (McFeeters, 1996).
\[NDWI = (Green - NIR) / (Green + NIR)\]

Xu (2006)
La modificación al NDWI de McFeeters (1996) es modificado al reemplazar la banda infrarroja media, por la banda infrarroja cercana, lo cual puede resultar en una notable mejoría de los espejos de agua y la eliminación del ruido más eficiente que generan diferentes superficies, la vegetación y el suelo. En consecuencia, la posible sobreestimación que se da en el NDWI se reduce en el MDWI (Xu, 2006).
\[NDWI = (Green - SWIR) / (Green + SWIR)\]

Indice normalizado de área constriuda (NDBI)
El inconveniente de la clasificación de áreas urbanas, radica en que estas no ofrecen una única respuesta, sin embargo, imágenes de mejor calidad podrán facilitar la investigación y caracterización de estas zonas, sobre todo para labores de monitoreo de cambios a corto y largo plazo, y con esto, una adecuada planeación (Bouzekri, Lasbet, & Lachehab, 2015).
La ecuación que describe Taufik & Ahmad (2016) para el NDBI se muestra a continuación.
\[ NDBI = (SWIR - NIR) / (NIR + SWIR) \]

Histogramas


Métodos de segmentación por respuesta espectral-Umbralización
La umbralización es uno de los métodos de segmentación más sencillos, ya que a partir de una imagen puede generarse un enfoque binario donde los elementos de ruido pueden adoptar colores blancos, y el fondo o interés color negro (Callejo M., 2016).
Mediante la definición de umbrales se logra separar el fondo, donde se emplean las imágenes desarrolladas por los índices de vegetación, y el valor mínimo y máximo aceptable es dictado por el criterio del analista.
Vegetación
Valores de NDVI mayores a 0.4 han sido identificados potencialmente como cobertura vegetal.

Una umbralización más detalla se puede realizar para identificar los múltiples niveles de cobertura vegetal sobre la escena, en este caso, se podrá visualizar la siguiente escala.
| -inf,0.25 |
1 |
Nula |
| 0.25-0.3 |
2 |
Muy poca |
| 0.3-0.4 |
3 |
Moderada |
| 0.4-0.5 |
4 |
Alta |
| 0.5-+inf |
5 |
Muy alta |

Áreas abiertas
De la misma forma, es posible identificar áreas que se encuentran con poca o sin cobertura vegetal “Áreas abiertas”, que según el NDVI y la distribución de frecuencias del histograma estarán anulados los rangos de (-inf,0.35) y de (0.4,+inf).
Al sobreponer las gráficas de este umbral y una imagen de color falso de las bandas 5,4 y 3, se logra obtener la información complementaria para la vegetación.
Umbrales
Umbral independiente

Umbral + CCF

Umbral + CCV

Agua
Debido a las reducidas zonas con fuentes hídricas o espejos de agua, sumado a la resolución espacial de la escena, no es posible generar polígonos adecuados que permitan la caracterización inicialmente presentada para esta información, sin embargo, la umbralización del NDWI de Mc- Feeters (1996), permite discriminar de forma aproximada estas zonas.

Zonas Urbanas
Las zonas con construcciones identificadas por el NDBI>0 permite realizar la siguiente umbralización.

Clasificación no supervisada
La clasificación no supervisada de una escena consiste en agrupar los pixeles en clases que tengan similitud relativa de reflectancia sin requerir una toma de muestras en campo (Willington et al., 2013), en ocasiones es empleado como una herramienta de aproximación inicial.
Debido a la gran variabilidad de pixeles y dispendioso proceso de verificación, se realiza la clasificación de la zona comprendida entre las siguientes coordenadas.
| 590000 |
600000 |
534000 |
540000 |
A partir de los polígonos descritos inicialmente, se verifica la clasificación no supervisada que fue derivada del análisis del NDVI, con 4 niveles de clasificación, para que fuera consistente con las categorías presentes.
| 1 |
Zonas urbanizadas y predios en fase de preparación para cultivo |
| 2 |
Invernaderos y estructuras de producción agrícola |
| 3 |
Cultivos y vegetación de cobertura moderada |
| 4 |
Cultivos y vegetación de cobertura alta |
Clasificación NS a partir de NDVI
NDVI

Clasificación parcial

con este proceso de verificación, procedemos a realizar la clasificación no supervisada sobre toda el área de interés.
Clasificación completa

Clasificación supervisada
Willington et al., (2013) Definen los métodos de clasificación supervisada como procedimientos que identifican áreas espectralmente homogéneas mediante un muestreo de entrenamiento de la imagen satelital, es decir, el usuario o analista debe conocer las características de cobertura de los polígonos o puntos ingresados.
El algoritmo tendrá con esto la capacidad de extrapolar las características espectrales de los muestreos a todos los pixeles de la escena.
Información de los polígonos de entrenamiento
class : SpatialPolygonsDataFrame
features : 89
extent : 585169.6, 605900.4, 527677.4, 542392.1 (xmin, xmax, ymin, ymax)
crs : +proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0
variables : 2
names : code, value
min values : crop, 1
max values : urban, 4
Polígonos de entrenamiento
Sobreposición de polígonos

Random Forest
Random Forest es el termino genérico para los métodos de clasificación que consisten en un algoritmo de múltiples arboles de decisión tipo CART, donde cada uno de estos es entrenado a partir de los polígonos o puntos de muestreo iniciales (Gislason et al., 2006).
Resumen de datos espectrales
summary is an estimate based on a sample of 1e+05 cells (27.28% of all cells)
ultra.blue blue green red NIR SWIR.1 SWIR.2
Min. 0.07274335 0.05298966 0.02927507 0.01698614 0.003910114 0.001574202 0.0002031228
1st Qu. 0.08785061 0.07142305 0.06867455 0.04915572 0.238637552 0.154094025 0.0724894479
Median 0.09318259 0.07858313 0.08170614 0.06555788 0.315652817 0.190402240 0.0986161157
3rd Qu. 0.10145984 0.08983105 0.09716887 0.08952637 0.388777047 0.228386194 0.1359208934
Max. 1.32948947 1.03983641 0.88058811 1.02907085 1.422138929 1.491556048 1.5370048285
NA's 0.00000000 0.00000000 0.00000000 0.00000000 0.000000000 0.000000000 0.0000000000
Rasterización de polígonos

Polígonos de entrenamiento por bandas

Resultados del entrenamiento del modelo
Call:
randomForest(x = tablavalores[, c(1:7)], y = tablavalores$clase, ntree = 500, importance = TRUE, do.trace = FALSE)
Type of random forest: classification
Number of trees: 500
No. of variables tried at each split: 2
OOB estimate of error rate: 2.69%
Confusion matrix:
Invernaderos suelo desnudo Cobertura vegetal Urbano error de clase
Invernaderos 8226 34 31 122 0.02222751
suelo desnudo 13 3222 24 3 0.01226242
Cobertura vegetal 16 12 2631 0 0.01053027
Urbano 204 10 2 2933 0.06859320


Recordemos que las categorías de clasificación son:
| 1 |
Invernaderos, construcciones agrícolas |
| 2 |
Suelo sin cobertura, preparación de cultivo |
| 3 |
Cultivos y regiones con cobertura vegetal |
| 4 |
Zonas urbanizadas |
Evaluación del modelo
La evaluación del modelo permitirá tener un argumento cuantitativo de precisión para el mapa clasificado, a continuación se usarán dos medidas ampliamente usadas en los sistemas de teledetección; Precisión general y Kappa, que emplean procesos de validación cruzada, dividiendo los datos en 5 grupos diferentes, con el primero se realizará la prueba de este, mientras que los otros 4 grupos realizarán el ajuste o entrenamiento.
Cantidad de datos por grupo:
j
1 2 3 4 5
3497 3497 3495 3497 3497
Matriz de comparación entre datos observados y predecidos para cada grupo de clasificación:
predicted
observed invernaderos suelo desnudo cobertura vegetal urbano
invernaderos 8227 35 31 120
suelo desnudo 17 3218 23 4
cobertura vegetal 19 11 2629 0
urbano 213 12 2 2922
Sumamos la totalidad de casos, resultando:
[1] 17483
Extraemos los valores de la diagonal, lo cual nos permite observar, modificar o generar datos almacenados en la diagonal de una matriz, en este caso, donde las clases observadas coincidirán con las predecidas.
invernaderos suelo desnudo cobertura vegetal urbano
8227 3218 2629 2922
Ecuación - Precisión general del modelo
\[ OA=\frac{\sum_{i,j=1}^{n}X_{i,j}}{\sum_{m,n=1}^{n}X_{m,n}}\]
Donde: \(OA=\) Precisión general del modelo \(i=j\) Imndican los elementos de la diagonal de una matriz
\(\sum_{i,j=1}^{n}X_{i,j}=\) Suma de los valores de la diagonal principal de la matriz de confusión.
\(\sum_{m,n=1}^{n}X_{m,n}=\) Suma de todos los valores de la matriz de confusión
**Ecuación - Corrección de la precisión general del modelo - Kappa*
\[KAPPA= \frac{OA-C_a}{1-C_a}\]
Donde:
\(C_a=\) Suma del producto de los totales de cada fila y columna divididos por el número total de pixeles muestreados para cada clase.
Suma de filas:
invernaderos suelo desnudo cobertura vegetal urbano
8413 3262 2659 3149
Suma de columnas:
invernaderos suelo desnudo cobertura vegetal urbano
8476 3276 2685 3046
\(C_a\):
Tabla de Resultados
4. Discusión
Aunque el perfil espectral del subgrupo que contiene las zonas con vegetación turgente tiene valores que permiten su fácil discriminación, las áreas descubiertas poseen valores de reflectancia en la banda SWIR -1 mayores a las regiones que cuentan con construcciones urbanas, por lo que la identificación de zonas agrícolas se vuelve cuidadosa.
Las construcciones en general poseen niveles de reflectancia en las bandas muy similares a zonas con vegetación en fases iniciales de desarrollo, las vías de acceso a los municipios de Cota, Chía y Tenjo, no tienen grandes dimensiones, por lo que resulta complejo visualizarlas con la resolución espacial ofrecida por el satélite Landsat 8.
por estas razones, los contrastes de las imágenes generadas han sido escogidos cuidadosamente con el fin de poder diferenciar estas categorías.
Tenjo y sus alrededores tienen gran cantidad de invernaderos y estructuras con altos niveles de reflectancia en la banda NIR, pero mediante las metodologías de segmentación se identifican fácilmente.
El grafico de correlación entre bandas permite visualizar el potencial de la banda NIR para realizar los diferentes índices, debido a que cuenta con la menos correlación y con esto, se logra una menor redundancia de datos.
El NDVI emplea la interacción de la reflectancia entre la luz visible y el infrarrojo cercano de la vegetación, los valores entre los que oscila este índice es -1 y +1, donde un valor positivo indicará altas densidades de vegetación, lo que puede presentarse fácilmente en regiones boscosas o cultivos de alta densidad, esta información resalta sobre la escena debido a la gran cantidad de predios destinados a producción agrícola y pastos para ganado, los cuales tienen mayor relevancia en la zona sur-occidental.
El NDWI por la metodología de Gao (1996) no solo tiene la capacidad de identificar áreas con cuerpos de agua, sino también altos niveles de saturación o humedad de la vegetación (turgencia), por ello puede ser viable introducir este indicador para la evaluación temprana de estrés hídrico, discriminando fácilmente las regiones descubiertas, urbanizadas o con coberturas antrópicas.
Los niveles altos de saturación son fácilmente identificables en los cultivos establecidos del valle, aun cuando la escena fue captada en el periodo tradicional de mayor déficit hídrico
Para el caso del índice NDWI por la metodología de McFeeters (1996) los únicos elementos representados con valores mayores son los pequeños cuerpos de agua o zonas con altos niveles de saturación. La generación de polígonos que representen los cuerpos de agua resulta compleja debido a las dimensiones de estos respecto a la escena y la resolución espacial, sin embargo, una adecuada umbralización a partir de la diferencia entre bandas del espectro visible, donde cuentan con mayores niveles de reflectancia, y la banda NIR, permite sobreponer e identificar parte de ellos, resultando, aun así, insuficientes respecto a la realidad.
Lo mismo sucede con el MDWI propuesto por Xu (2006), donde las áreas que cuentan con espejos de agua son fácilmente identificables, ya que estos absorben gran parte de la reflectancia en el espectro del infrarrojo cercano, un aspecto que resulta confuso es la ausencia de respuesta espectral en la totalidad de las bandas para las laderas de pendientes muy pronunciadas “barrancos o abismos”, lo cual debe tenerse muy en cuenta y ser compensado con la caracterización visual del terreno.
Dentro de los valores menores a cero, se encuentran zonas previamente identificadas como cultivos turgentes, o vegetación. Por encima del valor mencionado, empiezan a encontrarse zonas urbanas, predios descubiertos o en fase de preparación para cultivo, y las estructuras de cultivo (invernaderos), que han mostrado grandes niveles de reflectancia en las bandas usadas para este índice.
La clasificación no supervisada de una región más pequeña permite verificar y categorizar adecuadamente los resultados, lo que posteriormente se refleja en la ejecución del código para una imagen de mayor tamaño.
La calasificación supervisada a partir del modelo Random Forest, permite la generación de un mapa de caracteristicas homogeneas, sobre el cual se identifican facilmente las 4 categorías planteadas y cargadas en los 89 polígonos de entrenamiento, la matriz de confusión arroja valores de error de clase menores al 10%.
LS0tDQp0aXRsZTogIlJlcG9ydGUgTjEiDQphdXRob3I6ICJFbGtpbiBBbGJlcnRvIEFwb250ZSBHb21leiINCmRhdGU6ICIyMS80LzIwMjAiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBkZl9wcmludDogcGFnZWQNCi0tLQ0KYGBge3J9DQpsaWJyYXJ5KGtuaXRyKQ0KYGBgDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBGQUxTRSkNCmBgYA0KDQojICoqQ29udGVuaWRvKioNCg0KDQoxLiBJbnRyb2R1Y2Npw7NuDQoyLiBEYXRvcyB5IE3DqXRvZG9zDQogICAgKyBNZXRvZG9sb2fDrWENCiAgICArIMOBcmVhIGRlIEVzdHVkaW8NCiAgICArIFVzb3MgZGUgU3VlbG8NCiAgICArIFByb3BpZWRhZGVzIGRlIGltYWdlbmVzDQogICAgKyBQcmUtcHJvY2VzYW1pZW50bw0KICAgICsgQ29ycmVjY2nDs24gcmFkaW9tw6l0cmljYSANCjMuIFJlc3VsdGFkb3MgICAgDQogICAgKyBJbWFnZW4gZW4gY29sb3IgdmVyZGFkZXJvDQogICAgKyBJbcOhZ2VuZXMgZW4gY29sb3IgZmFsc28NCiAgICArIFJlbGFjacOzbiBlbnRyZSBiYW5kYXMNCiAgICArIFBlcmZpbGVzIGVzcGVjdHJhbGVzDQogICAgKyBNw6l0b2RvcyBkZSBzZWdtZW50YWNpw7NuIHBvciByZXNwdWVzdGEgZXNwZWN0cmFsLcONbmRpY2VzDQogICAgKyBIaXN0b2dyYW1hcw0KICAgICsgTcOpdG9kb3MgZGUgc2VnbWVudGFjacOzbiBwb3IgcmVzcHVlc3RhIGVzcGVjdHJhbC1VbWJyYWxpemFjacOzbg0KICAgICsgQ2xhc2lmaWNhY2nDs24gbm8gc3VwZXJ2aXNhZGENCiAgICArIENsYXNpZmljYWNpw7NuIHN1cGVydmlzYWRhLVJhbmRvbSBGb3Jlc3QNCiAgICArIEV2YWx1YWNpw7NuIGRlbCBtb2RlbG8NCjQuIERpc2N1c2nDs24NCjUuIENvbmNsdXNpb25lcw0KNi4gUmVmZXJlbmNpYXMNCg0KDQoNCiMgKioxLkludHJvZHVjY2nDs24qKg0KDQpFbCBjb25jZXB0byBkZSBhbsOhbGlzaXMgZGUgaW3DoWdlbmVzIHNhdGVsaXRhbGVzIGFudGVzIGRlIDE5NzIgZXJhIHNpbXBsZW1lbnRlIHZpc2lvbmFyaW8sIHNpbiBlbWJhcmdvLCBjb24gbGEgbGxlZ2FkYSBkZWwgcHJvZ3JhbWEgTGFuZHNhdCwgcXVlIGhhIGNvbnNpc3RpZG8gZW4gdW5hIHNlcmllIGRlIG1pc2lvbmVzIGRlIG9ic2VydmFjacOzbiBzYXRlbGl0YWwgY29vcmRpbmFkYSBwb3IgbGEgKipOQVNBKiogeSBlbCBTZXJ2aWNpbyBHZW9sw7NnaWNvIGRlIGxvcyBFc3RhZG9zIFVuaWRvcyAqKihVU0dTKSoqICAqKEFyaXphLCAyMDEzKSogc2UgaGFuIGxvZ3JhZG8gZ3JhbmRlcyBhdmFuY2VzIGVuIGVsIGFyZWEgZGUgcGVyY2VwY2nDs24gcmVtb3RhIHkgdGVsZWRldGVjY2nDs24sIGxhcyBjdWFsZXMgc29uIHVuYSBoZXJyYW1pZW50YSBxdWUgcGVybWl0ZSBlbCBhbsOhbGlzaXMgZXNwYWNpYWwgY29uIGdyYW4gY2FudGlkYWQgZGUgYXBsaWNhY2lvbmVzIGFscmVkZWRvciBkZWwgbXVuZG8uIA0KDQoNClRyYWRpY2lvbmFsbWVudGUgZWwgdXNvIGRlIGVzdGFzIGltw6FnZW5lcyBzZSBkYSBlbiBlbCBlbXBsZW8gZGUgw61uZGljZXMgZGUgdmVnZXRhY2nDs24sIGNvYmVydHVyYXMsIHVzb3MgZGUgc3VlbG8geSBsYXMgZGluw6FtaWNhcyBxdWUgc2UgZW5jdWVudHJhbiBhbHJlZGVkb3IgZGUgZXN0b3MgKihHb256YWdhLCAyMDE0KSosIGV4aXN0aWVuZG8gdGFtYmnDqW4gZnVuY2lvbmVzIGVtZXJnZW50ZXMsIGRlIGxhcyBjdWFsZXMgKkpveWNlLCBCZWxsaXNzLCBTYW1zb25vdiwgTWNOZWlsbCwgJiBHbGFzc2V5ICgyMDA5KSogZGVzdGFjYW4gIGxvcyBjcmVjaWVudGVzIHByb2dyYW1hcyBvcGVyYWNpb25hbGVzIGRlIG1vbml0b3JlbyBkZSB0ZXJyZW1vdG9zLCBmYWxsYXMsIGFjdGl2aWRhZCB2b2xjw6FuaWNhLCBkZXNsaXphbWllbnRvcyBkZSB0aWVycmEsIGludW5kYWNpb25lcyBlIGluY2VuZGlvcyBmb3Jlc3RhbGVzLCBhc8OtIGNvbW8gbG9zIGRhw7FvcyBhc29jaWFkb3MgYSBjYWRhIHVuby4NCg0KDQpFbiBlbCBwcmVzZW50ZSByZXBvcnRlIHRlbmRyZW1vcyB1biBhY2VyY2FtaWVudG8gYWwgcHJlLXByb2Nlc2FtaWVudG8geSBvYnRlbmNpw7NuIGRlIGluZm9ybWFjacOzbiBhIHBhcnRpciBkZSBpbcOhZ2VuZXMgc2F0ZWxpdGFsZXMgZGUgbml2ZWwgMSwgdG9tYWRhcyBwb3IgZWwgc2F0w6lsaXRlIExhbmRzYXQgOCBzb2JyZSBlbCBtdW5pY2lwaW8gZGUgVGVuam8sIEN1bmRpbmFtYXJjYSwgZW1wbGVhbmRvIGxhIGhlcnJhbWllbnRhIGRlIHByb2dyYW1hY2nDs24gUiBzdHVkaW8uIA0KDQoNCiMgKioyLiBEYXRvcyB5IE3DqXRvZG9zKioNCg0KIyMgKipNZXRvZG9sb2fDrWEqKiAgDQogIA0KRWwgaW5mb3JtZSBwcmVzZW50YSB1bmEgZGVzY3JpcGNpw7NuIGluaWNpYWwgZGVsIMOhcmVhIGRlIGVzdHVkaW8sIHkgbGFzIGNvYmVydHVyYXMgZGV0ZXJtaW5hZGFzIGEgcGFydGlyIGRlIHVuIGFuw6FsaXNpcyBtYW51YWwgbWVkaWFudGUgbG9zIHNvZnR3YXJlICpHZ2lzIERlc2t0b3AqIHkgKkdvb2dsZSBFYXJ0aCBQcm8qLCBlbCBwcmVwcm9jZXNhbWllbnRvIHkgbGEgY29ycmVjY2nDs24gIHJhZGlvbcOpdHJpY2EgZnVlIGRlc2Fycm9sbGFkYSBlbiBmdW5jacOzbiBkZSBsYXMgZWN1YWNpb25lcyBvZnJlY2lkYXMgcG9yIGVsICpVU0dTICgyMDExKSosICBjb24gZXN0b3MgcmVzdWx0YWRvcyBzZSBwcmVzZW50YW4gbGFzIGRpZmVyZW50ZXMgY29tYmluYWNpb25lcyBkZSBpbcOhZ2VuZXMgZW4gY29sb3IgdmVyZGFkZXJvIHkgZmFsc28sIGxhcyBlc3RhZMOtc3RpY2FzIGRlIGxhcyBiYW5kYXMgeSBsYXMgbWV0b2RvbG9nw61hcyBkZSBzZWdtZW50YWNpw7NuIGNvbiBzdXMgcmVzcGVjdGl2b3MgZ3LDoWZpY29zIGF1eGlsaWFyZXMsIGZpbmFsbWVudGUgc2UgbXVlc3RyYSBlbCBwcm9jZXNvcyBkZSBjbGFzaWZpY2FjacOzbiBubyBzdXBlcnZpc2Fkbywgc3UgdmVyaWZpY2FjacOzbiBlbiB1bmEgcmVnacOzbiBlc3BlY8OtZmljYSBkZSBsYSBlc2NlbmEgeSBsYSBjbGFzaWZpY2FjacOzbiBzdXBlcnZpc2FkYSBjb24gbGEgdmFsaWRhY2nDs24gZGVsIG1vZGVsby4gICAgIA0KICANCiAgDQojIyAqKsOBcmVhIGRlIGVzdHVkaW8qKiANCg0KRWwgbXVuaWNpcGlvIGRlIFRlbmpvIHNlIGVuY3VlbnRyYSBzaXR1YWRvIGVuIGVsIGRlcGFydGFtZW50byBkZSBDdW5kaW5hbWFyY2EsICBjb24gY29vcmRlbmFkYXMgKio0Ljg3MTk3MywgLTc0LjE0NTA4MiAoTGF0LCBMb25nKSoqLCBlbiBlbCBjdWFkcmFudGUgKipQYXRoIDgsIFJvdyA1NyoqIGRlICoqTGFuZHNhdCA4KiouIA0KDQoNCkFwcm94aW1hZGFtZW50ZSBhIDIwIGtpbG9tZXRyb3MgZGUgbGEgY2l1ZGFkIGRlIEJvZ290w6EsIHN1IGNhc2NvIHVyYmFubyBkZWxpbWl0YSBjb24gZWwgw6FyZWEgcHJvdGVnaWRhIGRlbCAq4oCcY2Vycm8gZGUgQ2h1cnVnw7xhY28gQWx0b+KAnSogeSBlbCAq4oCdY2Vycm8gZGUgSnVhaWNh4oCdKiwgY3VlbnRhIGNvbiB1biBhZmx1ZW50ZSBwcm92ZW5pZW50ZSBkZSBUYWJpbyAqKHLDrW8gQ2hpY8O6KSosIHF1ZSBhbGltZW50YSBsYSAqcXVlYnJhZGEgU29jaGEqLCBkZSBsYSBjdWFsIHNlIGFiYXN0ZWNlbiBsYXMgZ3JhbmRlcyDDoXJlYXMgY3ViaWVydGFzIHkgdHJhZGljaW9uYWxlcyBkZSBjdWx0aXZvLCBjYXJhY3Rlcml6YWRhcyBwb3Igc2VyIHByb2R1Y3RvcmFzIGRlIGZsb3JlcyB5IGhvcnRhbGl6YXMsIHBhcmEgZGVzZW1ib2NhciBwb3N0ZXJpb3JtZW50ZSBlbiBlbCByw61vIEJvZ290w6EgYSBsYSBhbHR1cmEgZGVsIG11bmljaXBpbyBkZSBDb3RhLg0KDQoNCmBgYHtyfQ0KbGlicmFyeShzcCkNCmxpYnJhcnkocmFzdGVyKQ0KbGlicmFyeShyZ2RhbCkNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkobGVhZmxldCkNCnRlbmpvIDwtIGRhdGEuZnJhbWUoDQogICAgbGF0ID0gYyg0Ljg3MTk3Myw0Ljg3NjUxMyw0LjkwNDA0Miw0Ljg5MDE1Miw0LjgxMjM5Myw0Ljg0MTgzMSw0Ljg1NzIyMSw0LjgxNTI4MSw0Ljg3MTM4NSksDQogICAgbG5nID0gYygtNzQuMTQ1MDgyLC03NC4xMjgwOTQsLTc0LjEyODM2NCwtNzQuMTQ3MDM5LC03NC4xNzU0ODMsLTc0LjEzNzEyNCwtNzQuMTI5MDg4LC03NC4xMTk0NDMsLTc0LjA4MzA4MikpDQogDQp0ZW5qb19wb3B1cCA9IHBvcHVwID0gYygiUGFycXVlIFByaW5jaXBhbCIsIkNhc2EiLCJQZcOxYSBkZSBKdWFpY2EiLCJDZXJybyBDaHVydWfDvGFjbyBBbHRvIiwiUXVlYnJhZGEgU29jaGEiLCJRdWVicmFkYSBTb2NoYSIsIlLDrW8gQ2hpY8O6IiwiU2VycmFuw61hIGRlbCBNYWp1eSIsIkFsdG8gZGUgbGEgQ3J1eiIpDQogDQp0ZW5qbyAlPiUgDQogICAgbGVhZmxldCgpICU+JQ0KICAgIGFkZFRpbGVzKCkgJT4lDQogICAgYWRkTWFya2Vycyhwb3B1cCA9IHRlbmpvX3BvcHVwLCBjbHVzdGVyT3B0aW9ucyA9IG1hcmtlckNsdXN0ZXJPcHRpb25zKCkpJT4lDQoJICBhZGRQcm92aWRlclRpbGVzKHByb3ZpZGVycyRFc3JpLldvcmxkU3RyZWV0TWFwKSAlPiUNCgkgIGFkZE1pbmlNYXAoDQoJCXRpbGVzID0gcHJvdmlkZXJzJEVzcmkuV29ybGRTdHJlZXRNYXAsDQoJCXRvZ2dsZURpc3BsYXkgPSBUUlVFKQ0KDQpgYGANCg0KTGEgaW1hZ2VuIHNhdGVsaXRhbCBjb21wcmVuZGUgdW5hIGV4dGVuc2nDs24gY29uc2lkZXJhYmxlLCBwb3IgbG8gcXVlIHNlcsOhIHJlY29ydGFkYSBjb24gZWwgZmluIGRlIGRldGFsbGFyIMO6bmljYW1lbnRlIGVsIMOhcmVhIGRlIGVzdHVkaW8sIHF1ZSBzZSBlbmN1ZW50cmEgZGVsaW1pdGFkYSBwb3IgbGFzIGNvb3JkZW5hZGFzIHRhYnVsYWRhcyBhIGNvbnRpbnVhY2nDs24uIA0KDQoNCnwgVsOpcnRpY2UgVVRNIChYLFkpIHwgVsOpcnRpY2UgR01TICAgICAgICAgICAgICAgICAgICAgICAgfCBWw6lydGljZSBHRCB8IA0KfDotLS0tLS0tLS0tLS0tLS0tOnw6LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tOnw6LS0tLS0tLS0tLS0tLS0tLS0tLTp8DQp8IDU4NDA1Mi42LDUyNzQ3Ny41IHwgNMK6IDQ2JyAxOC4yMScnIE4gNzTCuiAxNCcgMzEuMzknJyBPIHwgNC43NzE3MjUsLTc0LjI0MjA1MyB8DQp8IDU4NDA1Mi42LDU0MjQyMy41IHwgNMK6IDU0JyAyNC45MycnIE4gNzTCuiAxNCcgMzEuMzknJyBPIHwgNC45MDY5MjUsLTc0LjI0MjA1MyB8DQp8IDYwNjEyNS4wLDU0MjQyMy41IHwgNMK6IDU0JyAyNC45MycnIE4gNzTCuiAwMicgMzQuOTEnJyBPIHwgNC45MDY5MjUsLTc0LjA0MzAzMCB8DQp8IDYwNjEyNS4wLDUyNzQ3Ny41IHwgNMK6IDQ2JyAxOC4yMScnIE4gNzTCuiAwMicgMzQuOTEnJyBPIHwgNC43NzE3MjUsLTc0LjA0MzAzMCB8ICANCg0KDQoNCg0KDQpgYGB7cn0NCmxpbSA8LSBleHRlbnQoNTg0MDUyLjYsNjA2MTI1LjAsNTI3NDc3LjUsNTQyNDIzLjUpDQpsaW0NCmBgYA0KDQojIyAqKlVzb3MgZGUgc3VlbG8qKg0KDQpTZWfDum4gZWwgYWN1ZXJkbyBOby4gMTAgZGUgMjAxNCAgKihTZWNyZXRhcsOtYSBNdW5pY2lwYWwgZGUgVGVuam8sIDIwMTQpKiwgRGUgbGEgc2VjcmV0YXJpYSBnZW5lcmFsIGRlbCBjb25jZWpvIG11bmljaXBhbCwgbGFzICoqMTEuMDU2LDE5IEhlY3TDoXJlYXMqKiBwZXJ0ZW5lY2llbnRlcyBhbCBtdW5pY2lwaW8gZGUgVGVuam8sIGN1ZW50YSBjb24gdW4gKjY0LDE0JSogZGUgw6FyZWEgZGVzdGluYWRhIGEgbGEgYWN0aXZpZGFkIGFncm9wZWN1YXJpYSBpbnRlbnNpdmEsICo2LDU5JSogZGVzdGluYWRvIGEgbGFzIHJlc2VydmFzIGZvcmVzdGFsZXMgZGUgZmluZXMgcHJvdGVjdG9yZXMg4oCTIHByb2R1Y3RvcmVzIGRlIGxhIEN1ZW5jYSBBbHRhIGRlbCBSw61vIEJvZ290w6EsIHkgdW4gdG90YWwgZGVsICoxNyw1NzIlKiBjb24gZGV0ZXJtaW5hbnRlcyBlY29sw7NnaWNvcyB5IGRlIHNvc3RlbmliaWxpZGFkIGVzcGVjw61maWNvcywgY29uIHVuYSBwcm9wb3JjacOzbiBkZWwgKjMsMjklKiBkZSBzdWVsb3MgdXJiYW5vcyB5IGRlIGV4cGFuc2nDs24gdXJiYW5hLg0KDQoNCkVsIMOhcmVhIHJlc3RhbnRlIHNlIGVuY3VlbnRyYSBiYWpvIGxvcyB0w6lybWlub3MgZGUgdml2aWVuZGEgY2FtcGVzaW5hLCBzdWVsbyBzdWJ1cmJhbm8sIGNlbnRyb3MgcG9ibGFkb3MgcnVyYWxlcywgc2lzdGVtYSBkZSBpbmZyYWVzdHJ1Y3R1cmEgZGUgc2VydmljaW9zIHDDumJsaWNvcyBlIGludGVyw6lzIHBhdHJpbW9uaWFsLiAgIA0KDQoNCg0KDQpgYGB7cn0NCmxpYnJhcnkocmFzdGVyKQ0KbGNfdGVuam8gPC0gc2hhcGVmaWxlKCJ1c29kZXN1ZWxvLnNocCIpDQpgYGANCg0KYGBge3J9DQpjbGFzcyhsY190ZW5qbykNCmBgYA0KDQoNCmBgYHtyfQ0KcHJvajRzdHJpbmcobGNfdGVuam8pDQpgYGANCg0KYGBge3J9DQpsY19ydGVuam8gPC0gc3BUcmFuc2Zvcm0obGNfdGVuam8sIENSUygiK2luaXQ9ZXBzZzo0MzI2IikpDQoNCmBgYA0KDQoNCioqTWFwYSBkZSB1c28gZGUgc3VlbG8qKg0KDQoqDQpBIGNvbnRpbnVhY2nDs24sIHNlIG11ZXN0cmEgdW5hIHLDoXBpZGEgY2FyYWN0ZXJpemFjacOzbiBkZSBhbGd1bm9zIHVzb3MgZGUgc3VlbG8gZW4gZWwgw6FyZWEgZGUgZXN0dWRpby4gTWVkaWFudGUgKio4OSBwb2zDrWdvbm9zKiogZXMgbXVlc3RyZWFkYSBlbCDDoXJlYSBkZSBpbnRlcsOpcywgaWRlbnRpZmljYW5kbyBkaWZlcmVudGVzIHRpcG9zIGRlIGNvYmVydHVyYSwgZmFjaWxpdGFkbyBwb3IgaGVycmFtaWVudGFzIGNvbW8gUWdpcywgR29vZ2xlIEVhcnRoIFBybywgeSBlbCBjb25vY2ltaWVudG8gZGUgbGEgcmVnacOzbi4NCg0KDQp8TGV5ZW5kYSAgICAgICAgfCBEZXNjcmlwY2nDs258DQp8Oi0tLS0tLS0tLS0tLS06fDotLS0tLS0tOnwNCnxVcmJhbiAgICAgICB8ICBab25hcyBjb25zdHJ1aWRhcywgdXJiYW5pemFkYXN8ICANCnxpbnZlcm5hZCAgICAgICAgICB8ICBab25hcyBkZSBjdWx0aXZvIGJham8gaW52ZXJuYWRlcm8gfA0KfGNyb3AgICAgICAgIHwgIFpvbmFzIGRlIGN1bHRpdm8gdHJhZGljaW9uYWwgZW4gdW5hIGZhc2UgZGVzYXJyb2xsYWRhIHwNCnx1bmNvdmVyZSAgICAgICAgICB8ICBab25hcyBkZSBjdWx0aXZvIHRyYWRpY2lvbmFsIGVuIGZhc2UgZGUgcHJlcGFyYWNpw7NufA0KDQoNCmBgYHtyfQ0KcGFyKG1mcm93ID0gYygxLDIpKQ0KbGVhZmxldCgpICU+JQ0KICBhZGRQcm92aWRlclRpbGVzKHByb3ZpZGVycyRFc3JpLldvcmxkSW1hZ2VyeSwgb3B0aW9ucz0gcHJvdmlkZXJUaWxlT3B0aW9ucyhvcGFjaXR5ID0gMC45OSkpICU+JQ0KICBhZGRQb2x5Z29ucyhkYXRhID0gbGNfcnRlbmpvLCBwb3B1cCA9IGxjX3J0ZW5qbyRjb2RlLA0KICAgIHN0cm9rZSA9IEZBTFNFLCBmaWxsT3BhY2l0eSA9IDAuNSwgc21vb3RoRmFjdG9yID0gMCwNCiAgICkNCmBgYA0KDQoNCiMjICoqUHJvcGllZGFkZXMgZGUgaW1hZ2VuZXMqKg0KDQoNCkxhcyBpbcOhZ2VuZXMgbXVsdGllc3BlY3RyYWxlcyBzb24gb2J0ZW5pZGFzIGRlIGxhIHBsYXRhZm9ybWEgKkdsb1ZpcyosIG9mcmVjaWRhIHBvciBlbCAqVS5TLiBHZW9sb2dpY2FsIFN1cnZleSosICBkZWwgc2F0ZWxpdGUgTGFuZHNhdCA4LCBjYXJhY3Rlcml6YWRhcyBwb3IgZGFyIGluZm9ybWFjacOzbiBlbiA5IGJhbmRhcyBPTEkgeSAyIFRJUlMgeSB1bmEgYmFuZGEgYWRpY2lvbmFsIGRlIGNhbGlkYWQsIGRlc2NyaXRhcyBhIGNvbnRpbnVhY2nDs24NCg0KfEJhbmRhICAgICAgICAgfCBPYmpldG8gZW4gUnwNCnw6LS0tLS0tLS0tLS0tLTp8Oi0tLS0tLTp8DQp8QWVyb3NvbCAgICAgICB8ICBiYW5kMXwNCnxhenVsICAgICAgICAgIHwgIGJhbmQyfA0KfHZlcmRlICAgICAgICAgfCAgYmFuZDN8DQp8cm9qbyAgICAgICAgICB8ICBiYW5kNHwNCnxOSVIgICAgICAgICAgIHwgIGJhbmQ1fA0KfFNXSVItMSAgICAgICAgfCAgYmFuZDZ8DQp8U1dJUi0yICAgICAgICB8ICBiYW5kN3wNCnxwYW5jcm9tYXRpY28gIHwgIGJhbmQ4ICAob21pdGlkYSl8DQp8Y2lycnVzICAgICAgICB8ICBiYW5kOSAgKG9taXRpZGEpfA0KfFRJUlMtMSAgICAgICAgfCAgYmFuZDEwIChvbWl0aWRhKXwNCnxUSVJTLTIgICAgICAgIHwgIGJhbmQxMSAob21pdGlkYSl8DQp8UUEgICAgICAgICAgICB8ICBiYW5kUUEgKG9taXRpZGEpfA0KDQoNCmBgYHtyfQ0KYmFuZDEgPC0gcmFzdGVyKCd0ZW5qby9vbGl0aXJzL0xDMDhfTDFUUF8wMDgwNTdfMjAxODEyMzBfMjAxOTAxMzBfMDFfVDFfQjEudGlmJykNCmJhbmQyIDwtIHJhc3RlcigndGVuam8vb2xpdGlycy9MQzA4X0wxVFBfMDA4MDU3XzIwMTgxMjMwXzIwMTkwMTMwXzAxX1QxX0IyLnRpZicpDQpiYW5kMyA8LSByYXN0ZXIoJ3RlbmpvL29saXRpcnMvTEMwOF9MMVRQXzAwODA1N18yMDE4MTIzMF8yMDE5MDEzMF8wMV9UMV9CMy50aWYnKQ0KYmFuZDQgPC0gcmFzdGVyKCd0ZW5qby9vbGl0aXJzL0xDMDhfTDFUUF8wMDgwNTdfMjAxODEyMzBfMjAxOTAxMzBfMDFfVDFfQjQudGlmJykNCmJhbmQ1IDwtIHJhc3RlcigndGVuam8vb2xpdGlycy9MQzA4X0wxVFBfMDA4MDU3XzIwMTgxMjMwXzIwMTkwMTMwXzAxX1QxX0I1LnRpZicpDQpiYW5kNiA8LSByYXN0ZXIoJ3RlbmpvL29saXRpcnMvTEMwOF9MMVRQXzAwODA1N18yMDE4MTIzMF8yMDE5MDEzMF8wMV9UMV9CNi50aWYnKQ0KYmFuZDcgPC0gcmFzdGVyKCd0ZW5qby9vbGl0aXJzL0xDMDhfTDFUUF8wMDgwNTdfMjAxODEyMzBfMjAxOTAxMzBfMDFfVDFfQjcudGlmJykNCmJhbmQ4IDwtIHJhc3RlcigndGVuam8vb2xpdGlycy9MQzA4X0wxVFBfMDA4MDU3XzIwMTgxMjMwXzIwMTkwMTMwXzAxX1QxX0I4LnRpZicpDQpiYW5kOSA8LSByYXN0ZXIoJ3RlbmpvL29saXRpcnMvTEMwOF9MMVRQXzAwODA1N18yMDE4MTIzMF8yMDE5MDEzMF8wMV9UMV9COS50aWYnKQ0KYmFuZDEwIDwtIHJhc3RlcigndGVuam8vb2xpdGlycy9MQzA4X0wxVFBfMDA4MDU3XzIwMTgxMjMwXzIwMTkwMTMwXzAxX1QxX0IxMC50aWYnKQ0KYmFuZDExIDwtIHJhc3RlcigndGVuam8vb2xpdGlycy9MQzA4X0wxVFBfMDA4MDU3XzIwMTgxMjMwXzIwMTkwMTMwXzAxX1QxX0IxMS50aWYnKQ0KYGBgDQoNCg0KYGBge3J9DQpiYW5kMQ0KYmFuZDgNCmJhbmQxMA0KYGBgDQoNCg0KbGFzIGJhbmRhcyAxIGEgNyB5IDkgY29udGllbmVuIGxhIG1pc21hIGluZm9ybWFjacOzbiwgYXPDrSBtaXNtbyBsYXMgYmFuZGFzIDEwIHkgMTEuDQoNCkRlIGlndWFsIGZvcm1hLCBsYSBjb21wYXJhY2nDs24gZW50cmUgbGFzIGNhcmFjdGVyw61zdGljYXMgZGUgbGFzIGJhbmRhcyBhcnJvamEgZWwgdmFsb3IgIlRSVUUiIGN1YW5kbyBzb24gY29uc2lzdGVudGVzLCBwb3IgZXN0YSByYXrDs24sIHNlIG9taXRlIGxhIGJhbmRhIDguDQpgYGB7cn0NCmNvbXBhcmVSYXN0ZXIoYmFuZDIsYmFuZDMsYmFuZDQsYmFuZDUsYmFuZDYsYmFuZDcsYmFuZDksYmFuZDEwLGJhbmQxMSkNCmBgYA0KDQojIyAqKk1ldGFkYXRvcyoqDQoNCkxhIGltYWdlbiBmdWUgc2VsZWNjaW9uYWRhIGVuIGZ1bmNpw7NuIGRlIGxhIGNhbGlkYWQgZGVzY3JpdGEgZW4gbG9zIE1ldGFEYXRvcyBvZnJlY2lkb3MgcG9yIGxhIHBsYXRhZm9ybWEsIGRvbmRlIHNlIHByaW9yaXphcm9uIGxvcyBpbmRpY2Fkb3JlcyBzZcOxYWxhZG9zIGVuIG5lZ3JpbGxhLg0KDQoNCkdST1VQID0gTDFfTUVUQURBVEFfRklMRSAgDQogIEdST1VQID0gTUVUQURBVEFfRklMRV9JTkZPICANCiIgICAgT1JJR0lOID0gIiJJbWFnZSBjb3VydGVzeSBvZiB0aGUgVS5TLiBHZW9sb2dpY2FsIFN1cnZleSIiIiAgDQoiICAgIFJFUVVFU1RfSUQgPSAiIjA3MDE5MDEyOTU1MDVfMDAwMTYiIiIgIA0KIiAgICAqKkxBTkRTQVRfU0NFTkVfSUQgPSAiIkxDODAwODA1NzIwMTgzNjRMR04wMCoqIiIiICANCiIgICAgTEFORFNBVF9QUk9EVUNUX0lEID0gIiJMQzA4X0wxVFBfMDA4MDU3XzIwMTgxMjMwXzIwMTkwMTMwXzAxX1QxIiIiICANCiAgICBDT0xMRUNUSU9OX05VTUJFUiA9IDAxICANCiAgICAqKkZJTEVfREFURSA9IDIwMTktMDEtMzBUMDI6NDY6MjRaKiogIA0KIiAgICBTVEFUSU9OX0lEID0gIiJMR04iIiIgIA0KIiAgICBQUk9DRVNTSU5HX1NPRlRXQVJFX1ZFUlNJT04gPSAiIkxQR1NfMTMuMS4wIiIiICANCiAgRU5EX0dST1VQID0gTUVUQURBVEFfRklMRV9JTkZPICANCiAgR1JPVVAgPSBQUk9EVUNUX01FVEFEQVRBICANCiIgICAgREFUQV9UWVBFID0gIiJMMVRQIiIiICANCiIgICAgQ09MTEVDVElPTl9DQVRFR09SWSA9ICIiVDEiIiIgIA0KIiAgICBFTEVWQVRJT05fU09VUkNFID0gIiJHTFMyMDAwIiIiICANCiIgICAgT1VUUFVUX0ZPUk1BVCA9ICIiR0VPVElGRiIiIiAgDQoiICAgICoqU1BBQ0VDUkFGVF9JRCA9ICIiTEFORFNBVF84IiIqKiIgIA0KIiAgICBTRU5TT1JfSUQgPSAiIk9MSV9USVJTIiIiICANCiAgICAqKldSU19QQVRIID0gOCoqICANCiAgICAqKldSU19ST1cgPSA1NyoqICANCiAgR1JPVVAgPSBJTUFHRV9BVFRSSUJVVEVTICANCiAgICAqKkNMT1VEX0NPVkVSID0gMTguNTUqKiAgDQogICAgKipDTE9VRF9DT1ZFUl9MQU5EID0gMTguNTUqKiAgDQogICAgKipJTUFHRV9RVUFMSVRZX09MSSA9IDkqKiAgDQogICAgKipJTUFHRV9RVUFMSVRZX1RJUlMgPSA5KiogIA0KIiAgICBUSVJTX1NTTV9NT0RFTCA9ICIiRklOQUwiIiIgIA0KIiAgICBUSVJTX1NTTV9QT1NJVElPTl9TVEFUVVMgPSAiIkVTVElNQVRFRCIiIiAgDQoiICAgIFRJUlNfU1RSQVlfTElHSFRfQ09SUkVDVElPTl9TT1VSQ0UgPSAiIlRJUlMiIiIgIA0KICAgICoqUk9MTF9BTkdMRSA9IC0wLjAwMSoqICANCiAgICAqKlNVTl9BWklNVVRIID0gMTM3LjQ1NDcyMDk1KiogIA0KICAgICoqU1VOX0VMRVZBVElPTiA9IDUxLjk3MTE2ODIyKiogIA0KICAgICoqRUFSVEhfU1VOX0RJU1RBTkNFID0gMC45ODMzMjgyKiogIA0KICAgIEdST1VORF9DT05UUk9MX1BPSU5UU19WRVJTSU9OID0gNCAgDQogICAgKipHUk9VTkRfQ09OVFJPTF9QT0lOVFNfTU9ERUwgPSAxNzMqKiAgDQogICAgKipHRU9NRVRSSUNfUk1TRV9NT0RFTCA9IDkuMzU0KiogIA0KICAgICoqR0VPTUVUUklDX1JNU0VfTU9ERUxfWSA9IDYuNDUwKiogIA0KICAgICoqR0VPTUVUUklDX1JNU0VfTU9ERUxfWCA9IDYuNzc0KiogIA0KICAgICoqR1JPVU5EX0NPTlRST0xfUE9JTlRTX1ZFUklGWSA9IDYyKiogIA0KICAgIEdFT01FVFJJQ19STVNFX1ZFUklGWSA9IDcuMjAzICANCiIgICAgVFJVTkNBVElPTl9PTEkgPSAiIlVQUEVSIiIiICANCiAgRU5EX0dST1VQID0gSU1BR0VfQVRUUklCVVRFUyAgDQogIEdST1VQID0gUFJPSkVDVElPTl9QQVJBTUVURVJTICANCiIgICAgKipNQVBfUFJPSkVDVElPTiA9ICIiVVRNIiIiKiogIA0KIiAgICAqKkRBVFVNID0gIiJXR1M4NCIiIioqICANCiIgICAgKipFTExJUFNPSUQgPSAiIldHUzg0IiIiKiogIA0KICAgICoqVVRNX1pPTkUgPSAxOCoqICANCiAgICAqKkdSSURfQ0VMTF9TSVpFX1BBTkNIUk9NQVRJQyA9IDE1LjAwKiogIA0KICAgICoqR1JJRF9DRUxMX1NJWkVfUkVGTEVDVElWRSA9IDMwLjAwKiogIA0KICAgICoqR1JJRF9DRUxMX1NJWkVfVEhFUk1BTCA9IDMwLjAwKiogIA0KIiANCg0KDQpgYGB7cn0NCmJjcjEgPC0gY3JvcChiYW5kMSxsaW0pDQpiY3IyIDwtIGNyb3AoYmFuZDIsbGltKQ0KYmNyMyA8LSBjcm9wKGJhbmQzLGxpbSkNCmJjcjQgPC0gY3JvcChiYW5kNCxsaW0pDQpiY3I1IDwtIGNyb3AoYmFuZDUsbGltKQ0KYmNyNiA8LSBjcm9wKGJhbmQ2LGxpbSkNCmJjcjcgPC0gY3JvcChiYW5kNyxsaW0pDQpiY3I4IDwtIGNyb3AoYmFuZDgsbGltKQ0KYmNyOSA8LSBjcm9wKGJhbmQ5LGxpbSkNCmJjcjEwIDwtIGNyb3AoYmFuZDEwLGxpbSkNCmJjcjExIDwtIGNyb3AoYmFuZDExLGxpbSkNCg0KY29tcGFyZVJhc3RlcihiY3IyLGJjcjMsYmNyNCxiY3I1LGJjcjYsYmNyNyxiY3I5LGJjcjEwLGJjcjExKQ0KYGBgDQoNCg0KYGBge3J9DQojR3VhcmRhbmRvIGxhcyBiYW5kYXMgcmVjb3J0YWRhcyBkZSBmb3JtYSBpbmRlcGVuZGllbnRlDQp3cml0ZVJhc3RlcihiY3IxLCBmaWxlbmFtZT0iYmNyMS50aWYiLCBvdmVyd3JpdGU9VFJVRSkNCndyaXRlUmFzdGVyKGJjcjIsIGZpbGVuYW1lPSJiY3IyLnRpZiIsIG92ZXJ3cml0ZT1UUlVFKQ0Kd3JpdGVSYXN0ZXIoYmNyMywgZmlsZW5hbWU9ImJjcjMudGlmIiwgb3ZlcndyaXRlPVRSVUUpDQp3cml0ZVJhc3RlcihiY3I0LCBmaWxlbmFtZT0iYmNyNC50aWYiLCBvdmVyd3JpdGU9VFJVRSkNCndyaXRlUmFzdGVyKGJjcjUsIGZpbGVuYW1lPSJiY3I1LnRpZiIsIG92ZXJ3cml0ZT1UUlVFKQ0Kd3JpdGVSYXN0ZXIoYmNyNiwgZmlsZW5hbWU9ImJjcjYudGlmIiwgb3ZlcndyaXRlPVRSVUUpDQp3cml0ZVJhc3RlcihiY3I3LCBmaWxlbmFtZT0iYmNyNy50aWYiLCBvdmVyd3JpdGU9VFJVRSkNCndyaXRlUmFzdGVyKGJjcjgsIGZpbGVuYW1lPSJiY3I4LnRpZiIsIG92ZXJ3cml0ZT1UUlVFKQ0Kd3JpdGVSYXN0ZXIoYmNyOSwgZmlsZW5hbWU9ImJjcjkudGlmIiwgb3ZlcndyaXRlPVRSVUUpDQp3cml0ZVJhc3RlcihiY3IxMCwgZmlsZW5hbWU9ImJjcjEwLnRpZiIsIG92ZXJ3cml0ZT1UUlVFKQ0Kd3JpdGVSYXN0ZXIoYmNyMTEsIGZpbGVuYW1lPSJiY3IxMS50aWYiLCBvdmVyd3JpdGU9VFJVRSkNCmBgYA0KDQojIyAqKlByZS1wcm9jZXNhbWllbnRvKioNCg0KTGFzIGJhbmRhcyBkZWwgZXNwZWN0cm8gdmlzaWJsZSBlIGluZnJhcnJvam8gY2VyY2FubyBzb24gZGV0YWxsYWRhcyBhIGNvbnRpbnVhY2nDs24gZW4gdW5hIGVzY2FsYSBkZSBncmlzZXMgcXVlIGRlZmluZSBlbCBOaXZlbCBEaWdpdGFsICooRE4pKiBkZSBsb3MgcGl4ZWxlcywgYSBsYXMgY3VhbGVzIHNlIGxlcyBoYSBhcGxpY2FkbyB1biBlc3RpcmFtaWVudG8gZGUgY29udHJhc3RlIHBhcmEgaW5jcmVtZW50YXIgbGFzIGNhcmFjdGVyw61zdGljYXMgZGUgdmlzdWFsaXphY2nDs24uIGxhcyBiYW5kYXMgOCBhIDExIHNvbiBvbWl0aWRhcywgdGFudG8gZW4gdmlzdWFsaXphY2nDs24gY29tbyBlbiBlbCBhbsOhbGlzaXMuIA0KDQoNCiMjIEJhbmRhcyBpbmRlcGVuZGllbnRlcyB7LnRhYnNldH0NCg0KIyMjIEJhbmRhIDINCmBgYHtyfQ0KI0JhbmRhcyBpbmRlcGVuZGllbnRlcyBpbHVzdHJhZGFzIGVuIGVzY8OhbGEgZGUgZ3Jpcw0KDQpwbG90KHN0cmV0Y2goYmNyMiwgbWlucT0wLjEsIG1heHE9MC45KSwgbWFpbiA9ICJCYW5kYSAyIChBenVsKSIsIHlsYWI9IkNvb3JkZW5hZGEgWSIsIHhsYWI9IkNvb3JkZW5hZGEgWCIsIGNvbCA9IGdyZXkoMDoxMDAgLyAxMDApKQ0KYGBgDQoNCiMjIyBCYW5kYSAzDQpgYGB7cn0NCnBsb3Qoc3RyZXRjaChiY3IzLCBtaW5xPTAuMSwgbWF4cT0wLjkpLCBtYWluID0gIkJhbmRhIDMgKFZlcmRlKSIsIHlsYWI9IkNvb3JkZW5hZGEgWSIsIHhsYWI9IkNvb3JkZW5hZGEgWCIsIGNvbCA9IGdyZXkoMDoxMDAgLyAxMDApKQ0KYGBgDQoNCiMjIyBCYW5kYSA0DQpgYGB7cn0NCnBsb3Qoc3RyZXRjaChiY3I0LCBtaW5xPTAuMSwgbWF4cT0wLjkpLCBtYWluID0gIkJhbmRhIDQgKFJvam8pIiwgeWxhYj0iQ29vcmRlbmFkYSBZIiwgeGxhYj0iQ29vcmRlbmFkYSBYIiwgY29sID0gZ3JleSgwOjEwMCAvIDEwMCkpDQpgYGANCg0KIyMjIEJhbmRhIDUNCmBgYHtyfQ0KcGxvdChzdHJldGNoKGJjcjUsIG1pbnE9MC4xLCBtYXhxPTAuOSksIG1haW4gPSAiQmFuZGEgNSAoSW5mcmFycm9qbyBDZXJjYW5vIE5JUikiLCB5bGFiPSJDb29yZGVuYWRhIFkiLCB4bGFiPSJDb29yZGVuYWRhIFgiLCBjb2wgPSBncmV5KDA6MTAwIC8gMTAwKSkNCmBgYA0KDQoNCg0KDQojIyAqKkNvcnJlY2Npw7NuIHJhZGlvbcOpdHJpY2EqKg0KDQoNCg0KRWwgYXJjaGl2byBSYXN0ZXJTdGFjayAqInRlbmpvbGlzdCIqIGN1ZW50YSBjb24gbGFzIDcgYmFuZGFzIHByZXZpYW1lbnRlIHJlY29ydGFkYXMsIHNpbiBlbWJhcmdvLCBlbCBwcm9jZXNvIGRlIGNvcnJlY2Npw7NuIHJhZGlvbcOpdHJpY2EgKihJbcOhZ2VuZXMgZGUgTml2ZWwgMSBhIE5pdmVsIDIpKiwgbWVkaWFudGUgZWwgY8OhbGN1bG8gZGUgbGEgKipyZWZsZWN0YW5jaWEgVE9BKiosIGZ1ZSBkZXNhcnJvbGxhZG8gZW4gbGEgaGVycmFtaWVudGEgUUdJUy4gDQoNCkVsIHByb2Nlc28gY29uc2lzdGnDsyBlbiB1dGlsaXphciBsYSBoZXJyYW1pZW50YSAqIkNhbGN1bGFkb3JhIFJhc3RlciIqIGNvbiBsYXMgNyBiYW5kYXMsIGludHJvZHVjaWVuZG8gbG9zIHZhbG9yZXMgZGUgY29ycmVjY2nDs24gcmFkaW9tZXRyaWNhIG9mcmVjaWRvcyBwb3IgZWwgcHJvdmVlZG9yLg0KDQokJFJlZmxlY3RhbmNpYSBUT0EgPSAoKE1fbCpETl9iKStBX2QpIC8gU2luKFNlKSQkIA0KDQpEZWJpZG8gYSBsYSBwb2NhIGluZm9ybWFjacOzbiBxdWUgc2UgbG9ncmEgb2J0ZW5lciBkZSBsYXMgaW3DoWdlbmVzIGV4cHVlc3RhcyBwcmV2aWFtZW50ZSwgc2UgcHVlZGUgcmVjdXJyaXIgYSBsYSBjb21iaW5hY2nDs24gZGUgdmFyaWFzIGJhbmRhcywgeWEgc2VhIGVuIGNvbG9yIHZlcmRhZGVybyBSR0IsIGNvbWJpbmFuZG8gbGFzIGJhbmRhcyA0LCAzIHkgMiByZXNwZWN0aXZhbWVudGUgZW4gdW4gZ3LDoWZpY28sIG8gZW4gY29sb3IgZmFsc28sIGRvbmRlIG3Dumx0aXBsZXMgY29tYmluYWNpb25lcyBhcnJvamFyYW4gaW5mb3JtYWNpw7NuIGFkaWNpb25hbC4gDQoNCg0KfFBhcsOhbWV0cm8gICAgICAgICB8IFZhbG9yfA0KfDotLS0tLS0tLS0tLS0tOnw6LS0tLS0tLTp8DQp8w4FuZ3VsbyBkZSBlbGV2YWNpw7NuIHNvbGFyIChTZSkgICAgICB8ICA1MS45NzExNjgyMnwgIA0KfFBhcsOhbWV0cm8gbXVsdGlwbGljYXRpdm8gKE1sKSAgICAgICAgIHwgIDIuMEUtNSB8DQp8UGFyw6FtZXRybyBhZGl0aXZvIChBZCkgICAgICAgIHwgIC0wLjF8DQoNCiMgKiozLiBSZXN1bHRhZG9zKioNCiANCiMjICoqSW1hZ2VuIGVuIGNvbG9yIHZlcmRhZGVybyoqIA0KYGBge3J9DQojQ29tcG9zaWNpw7NuIGVuIGNvbG9yIHZlcmRhZGVybw0KcmFzbGlzdCA8LSBwYXN0ZTAoJ3RlbmpvL29saXRpcnMvYnAnLDE6NywiLnRpZiIpDQp0ZW5qb2xpc3QgPC0gc3RhY2socmFzbGlzdCkNCiN0ZW5qb2xpc3QgPC0gc3RhY2soYmNyMSxiY3IyLGJjcjMsYmNyNCxiY3I1LGJjcjYsYmNyNyxiY3I5LGJjcjEwLGJjcjExKQ0KDQpsYW5kc2F0VEMgPC0gdGVuam9saXN0W1tjKDQsMywyKV1dDQpwbG90UkdCKGxhbmRzYXRUQywgYXhlcyA9IFRSVUUsIHN0cmV0Y2ggPSAibGluIiwgbWFpbiA9ICJDb21wb3NpY2nDs24gZGUgQ29sb3IgVmVyZGFkZXJvIikNCmBgYA0KDQojIyAqKkltw6FnZW5lcyBlbiBjb2xvciBmYWxzbyoqDQoNClVuYSBkZSBsYXMgbcO6bHRpcGxlcyByZXByZXNlbnRhY2lvbmVzIGVuIGNvbG9yIGZhbHNvIHF1ZSBwZXJtaXRlIHZpc3VhbGl6YXIgaW5mb3JtYWNpw7NuIGltcG9ydGFudGUgZXMgbGEgY29tYmluYWNpw7NuIGRlIGxhcyBiYW5kYXMgNSwgNCB5IDMgKihOSVIsIHZlcmRlIHkgcm9qbykqLCBkb25kZSBlcyBmw6FjaWxtZW50ZSBhcHJlY2lhYmxlIGVuIGNvbG9yIHJvam8gbGEgc3VwZXJmaWNpZSBjdWJpZXJ0YSBwb3IgdmVnZXRhY2nDs24uDQoNCk90cmFzIGltcG9ydGFudGVzIGNvbWJpbmFjaW9uZXMgc2UgZGV0YWxsYW4gYSBjb250aW51YWNpw7NuDQoNCg0KfE9iamV0aXZvICAgICAgICAgfENvbWJpbmFjacOzbiBkZSBiYW5kYXMgZW4gY29sb3IgZmFsc28gUiAtIEcgLSBCICooTGFuZHNhdCA4KSogfA0KfDotLS0tLS0tLS0tLS0tLS0tOnw6LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS06fA0KfFpvbmFzIFVyYmFuYXMgICAgfCA3IC0gNiAtIDR8DQp8QWdyaWN1bHR1cmEgICAgICB8IDYgLSA1IC0gMnwgDQp8TWFzYXMgZGUgQWd1YSAgICB8IDUgLSA2IC0gNHwNCnxWZWdldGFjacOzbiBzYW5hICB8IDUgLSA2IC0gMnwNCg0KYGBge3J9DQojQ29tcG9zaWNpw7NuIGVuIGNvbG9yIGZhbHNvDQoNCmxhbmRzYXRGQ3ZlZyA8LSB0ZW5qb2xpc3RbW2MoNSw0LDMpXV0NCmxhbmRzYXRGQ3VyYiA8LSB0ZW5qb2xpc3RbW2MoNyw2LDQpXV0NCmxhbmRzYXRGQ2FnciA8LSB0ZW5qb2xpc3RbW2MoNiw1LDIpXV0NCmxhbmRzYXRGQ3ZzYSA8LSB0ZW5qb2xpc3RbW2MoNSw2LDIpXV0NCmBgYA0KDQojIyBSZXN1bHRhZG9zIHsudGFic2V0fQ0KDQojIyMgQ0NGLVZlZ2V0YWNpw7NuDQpgYGB7cn0NCnBsb3RSR0IobGFuZHNhdEZDdmVnLCBheGVzID0gVFJVRSwgc3RyZXRjaCA9ICJsaW4iLCBtYWluID0gIkNvbXBvc2ljacOzbiBkZSBDb2xvciBGYWxzbyAtIFZlZ2V0YWNpw7NuIikNCmBgYA0KDQojIyMgQ0NGLVpvbmFzIFVyYmFuYXMNCmBgYHtyfQ0KcGxvdFJHQihsYW5kc2F0RkN1cmIsIGF4ZXMgPSBUUlVFLCBzdHJldGNoID0gImxpbiIsIG1haW4gPSAiQ29tcG9zaWNpw7NuIGRlIENvbG9yIEZhbHNvIC0gWm9uYXMgVXJiYW5hcyIpDQpgYGANCg0KIyMjIENDRi1BZ3JpY3VsdHVyYQ0KYGBge3J9DQpwbG90UkdCKGxhbmRzYXRGQ2FnciwgYXhlcyA9IFRSVUUsIHN0cmV0Y2ggPSAibGluIiwgbWFpbiA9ICJDb21wb3NpY2nDs24gZGUgQ29sb3IgRmFsc28gLSBBZ3JpY3VsdHVyYSIpDQpgYGANCg0KIyMjIENDRi1WZWdldGFjacOzbiBzYW5hDQpgYGB7cn0NCnBsb3RSR0IobGFuZHNhdEZDdnNhLCBheGVzID0gVFJVRSwgc3RyZXRjaCA9ICJsaW4iLCBtYWluID0gIkNvbXBvc2ljacOzbiBkZSBDb2xvciBGYWxzbyAtIFZlZ2V0YWNpw7NuIFNhbmEiKQ0KYGBgDQoNCg0KDQpgYGB7cn0NCg0KI2FyY2hpdm9zIC50aWYNCg0Kd3JpdGVSYXN0ZXIobGFuZHNhdFRDLCBmaWxlbmFtZT0iVGVuam9UQy50aWYiLCBvdmVyd3JpdGU9VFJVRSkNCndyaXRlUmFzdGVyKGxhbmRzYXRGQ2FnciwgZmlsZW5hbWU9IlRlbmpvRkNhZ3IudGlmIiwgb3ZlcndyaXRlPVRSVUUpDQp3cml0ZVJhc3RlcihsYW5kc2F0RkN1cmIsIGZpbGVuYW1lPSJUZW5qb0ZDdXJiLnRpZiIsIG92ZXJ3cml0ZT1UUlVFKQ0Kd3JpdGVSYXN0ZXIobGFuZHNhdEZDdmVnLCBmaWxlbmFtZT0iVGVuam9GQ3ZlZy50aWYiLCBvdmVyd3JpdGU9VFJVRSkNCndyaXRlUmFzdGVyKGxhbmRzYXRGQ3ZzYSwgZmlsZW5hbWU9IlRlbmpvRkN2c2EudGlmIiwgb3ZlcndyaXRlPVRSVUUpDQoNCg0KI2FyY2hpdm9zIC5ncmQNCndyaXRlUmFzdGVyKGxhbmRzYXRUQywgZmlsZW5hbWU9IlRlbmpvVEMudGlmIiwgb3ZlcndyaXRlPVRSVUUpDQp3cml0ZVJhc3RlcihsYW5kc2F0RkNhZ3IsIGZpbGVuYW1lPSJUZW5qb0ZDYWdyLmdyZCIsIG92ZXJ3cml0ZT1UUlVFKQ0Kd3JpdGVSYXN0ZXIobGFuZHNhdEZDdXJiLCBmaWxlbmFtZT0iVGVuam9GQ3VyYi5ncmQiLCBvdmVyd3JpdGU9VFJVRSkNCndyaXRlUmFzdGVyKGxhbmRzYXRGQ3ZlZywgZmlsZW5hbWU9IlRlbmpvRkN2ZWcuZ3JkIiwgb3ZlcndyaXRlPVRSVUUpDQp3cml0ZVJhc3RlcihsYW5kc2F0RkN2c2EsIGZpbGVuYW1lPSJUZW5qb0ZDdnNhLmdyZCIsIG92ZXJ3cml0ZT1UUlVFKQ0KDQpgYGANCg0KYGBge3J9DQpuYW1lcyh0ZW5qb2xpc3QpIDwtIGMoJ3VsdHJhLWJsdWUnLCdibHVlJywnZ3JlZW4nLCdyZWQnLCdOSVInLCdTV0lSLTEnLCdTV0lSLTInKQ0KYGBgDQoNCiMjICoqQ29ycmVsYWNpw7NuIGVucmUgYmFuZGFzKioNCg0KR2VuZXJhciBpbmZvcm1hY2nDs24gYSBwYXJ0aXIgZGUgY29tYmluYWNpw7NuIGRlIGJhbmRhcyBtdWx0aWVzcGVjdHJhbGVzIHJlcXVpZXJlIGN1aWRhZG9zYXMgc2VsZWNjaW9uZXMsIGRlYmlkbyBhIHF1ZSAqKEplbnNlbiwgMjAxNikqIGluZGljYSBxdWUgdW5hIGFsdGEgY29ycmVsYWNpw7NuIGVudHJlIGJhbmRhcyBzaWduaWZpY2Fyw6EgdW5hIHJlZHVuZGFuY2lhIGVuIGxvcyBkYXRvcywgcG9yIGxvIHF1ZSBlcyBwb3NpYmxlIHF1ZSBlbCBhbsOhbGlzaXMgbm8gc2VhIHJlcHJlc2VudGF0aXZvLg0KDQpgYGB7cn0NCnBhaXJzKHRlbmpvbGlzdFtbMTo3XV0sIG1haW4gPSAiQ29ycmVsYWNpw7NuIGVudHJlIGJhbmRhcyIpDQpgYGANCg0KIyMjICoqVmFsb3JlcyBkZSBww614ZWwgZXh0cmFpZG9zKioNCg0KYGBge3J9DQpsY19zYW1wbGVzIDwtc2hhcGVmaWxlKCd1c29kZXN1ZWxvLnNocCcpDQpjbGFzcyhsY19zYW1wbGVzKQ0KcHJvajRzdHJpbmcobGNfc2FtcGxlcykNCnB0c2FtcCA8LSBzcHNhbXBsZShsY19zYW1wbGVzLCAzMDAsIHR5cGU9J3JlZ3VsYXInKQ0KcHRzYW1wJGNvZGUgPC0gb3ZlcihwdHNhbXAsIGxjX3NhbXBsZXMpJGNvZGUNCmRmIDwtIGV4dHJhY3QodGVuam9saXN0LCBwdHNhbXApDQpoZWFkKGRmKQ0KYGBgDQoNCiMjICoqUGVyZmlsZXMgRXNwZWN0cmFsZXMqKg0KDQpBIHBhcnRpciBkZSBsb3MgcG9sw61nb25vcyBkZSBjYXJhY3Rlcml6YWNpw7NuIGRlIHVzbyBkZSBzdWVsbywgc2UgZXh0cmFlbiBkZSBsYXMgNyBiYW5kYXMgbG9zIHZhbG9yZXMgbWVkaW9zIGRlIHJlZmxlY3RhbmNpYSBUT0EsIHRhYnVsYWRvcyB5IGdyYWZpY2Fkb3MgYSBjb250aW51YWNpw7NuLg0KDQpgYGB7cn0NCm1zIDwtIGFnZ3JlZ2F0ZShkZiwgbGlzdChwdHNhbXAkY29kZSksIG1lYW4pDQpyb3duYW1lcyhtcykgPC0gbXNbLDFdDQptcyA8LSBtc1ssLTFdDQptcw0KYGBgDQoNCg0KYGBge3J9DQpteWNvbG9yIDwtIGMoJ2dyZWVuJywgJ3JlZCcsICdidXJseXdvb2QnLCAnY3lhbicpDQptcyA8LSBhcy5tYXRyaXgobXMpDQpwbG90KDAsIHlsaW09YygwLDAuNiksIHhsaW0gPSBjKDEsNyksIHR5cGU9J24nLCB4bGFiPSJCYW5kYXMiLCB5bGFiID0gIlJlZmxlY3RhbmNpYSIpDQpmb3IgKGkgaW4gMTpucm93KG1zKSl7DQogIGxpbmVzKG1zW2ksXSwgdHlwZSA9ICJsIiwgbHdkID0gMywgbHR5ID0gMSwgY29sID0gbXljb2xvcltpXSkNCn0NCnRpdGxlKG1haW49IlBlcmZpbCBFc3BlY3RyYWwgZGUgTGFuZHNhdCA4IC0gVGVuam8iLCBmb250Lm1haW4gPSAyKQ0KbGVnZW5kKCJ0b3BsZWZ0Iiwgcm93bmFtZXMobXMpLA0KICAgICAgIGNleD0wLjgsIGNvbD1teWNvbG9yLCBsdHkgPSAxLCBsd2QgPTMsIGJ0eSA9ICJuIikNCmBgYA0KDQoNCg0KDQojIyAqKk3DqXRvZG9zIGRlIHNlZ21lbnRhY2nDs24gcG9yIHJlc3B1ZXN0YSBlc3BlY3RyYWwtw41uZGljZXMqKg0KDQoqQ2FsbGVqbyBNLiAoMjAxNikqIEV4cGxpY2EgcXVlIGxhIGZpbmFsaWRhZCBkZSBzZWdtZW50YXIgdW5hIGltYWdlbiBlbiBmdW5jacOzbiBkZSBzdSByZXNwdWVzdGEgZXNwZWN0cmFsLCBlcyBwb2RlciBkZXRlcm1pbmFyIGRpZmVyZW50ZXMgY2FyYWN0ZXLDrXN0aWNhcyBkZSBpbnRlcsOpcyBjb24gbWF5b3IgZmFjaWxpZGFkLCBlbCBwcm9jZXNvIHNlIGRhIGEgcGFydGlyIGRlIGNvbnN0aXR1Y2lvbmVzIGhvbW9nw6luZWFzIGRlIHRleHR1cmEsIG5pdmVsIGRpZ2l0YWwsIGV0Yy4gIA0KDQoNCkVzdG8gc2ltcGxpZmljYXLDoSBsYSByZXByZXNlbnRhY2nDs24geSBlbCBhbsOhbGlzaXMgZW4gdW5hIG51ZXZhIGltYWdlbiBtw6FzIHNpZ25pZmljYXRpdmEsIGVsIHByaW1lcm8gZGUgZXN0b3MgbcOpdG9kb3MgZXMgZWwgZGVzYXJyb2xsbyBkZSAqKsOtbmRpY2VzIGNyb23DoXRpY29zKiogbyAqKsOtbmRpY2VzIGRlIHZlZ2V0YWNpw7NuKiouICANCg0KDQpFc3RhcyBtZWRpZGFzIGVtcMOtcmljYXMgc29uIG9idGVuaWRhcyBtZWRpYW50ZSBsYSBjdWFudGlmaWNhY2nDs24geSBjb21iaW5hY2nDs24gZGUgZG9zIG8gbWFzIGJhbmRhcyBkZWwgZXNwZWN0cm8gZWxlY3Ryb21hZ27DqXRpY28sIGxhIGFwbGljYWNpw7NuIGFkZWN1YWRhIGRlIGVzdG9zIHBlcm1pdGlyw6EgZGlzY3JpbWluYXIgbGEgY2FudGlkYWQsIGVzdGFkbywgeSBzaXR1YWNpw7NuIGRlIGxhIHZlZ2V0YWNpw7NuIGVuIGxhIGVzY2VuYS4NCiAgDQoNCg0KIyMjIMOtbmRpY2UgZGUgdmVnZXRhY2nDs24gZGUgRGlmZXJlbmNpYSBOb3JtYWxpemFkYSAqKE5EVkkpKg0KDQpFbCDDrW5kaWNlIGRlIHZlZ2V0YWNpw7NuIGRlIGRpZmVyZW5jaWEgbm9ybWFsaXphZGEgKihORFZJKSogcGVybWl0ZSBkZXRlcm1pbmFyIGN1YmllcnRhcyB2ZWdldGFsZXMsIG1lZGlyIGVsIGNyZWNpbWllbnRvIHkgY29udHJvbGFyIGxhIHByb2R1Y2Npw7NuIGRlIGJpb21hc2EgKihDYWxsZWpvIE0uLCAyMDE2KSouDQoNCiQkTkRWSSA9IChOSVIgLSBSRUQpIC8gKE5JUiArIFJFRCkkJA0KDQpgYGB7cn0NCiNORFZJDQoNCnJhc2xpc3QgPC0gcGFzdGUwKCd0ZW5qby9vbGl0aXJzL2JjcicsMTo3LCIudGlmIikNCnRlbmpvbGlzdCA8LSBzdGFjayhyYXNsaXN0KQ0KDQpuZHZpZnVuYyA8LSBmdW5jdGlvbihpbWcsIGssIGkpew0KICBiY3JrIDwtIGltZ1tba11dDQogIGJjcmkgPC0gaW1nW1tpXV0NCiAgbmR2aWZ1bmMgPC0gKGJjcmsgLSBiY3JpKSAvIChiY3JrICsgYmNyaSkNCiAgcmV0dXJuKG5kdmlmdW5jKQ0KfQ0KDQpuZHZpIDwtIG5kdmlmdW5jKHRlbmpvbGlzdCwgNSwgNCkNCnBsb3QobmR2aSwgY29sID0gcmV2KHRlcnJhaW4uY29sb3JzKDEwMDApKSwgbWFpbiA9ICLDjW5kaWNlIGRlIHZlZ2V0YWNpw7NuIGRlIGRpZmVyZW5jaWEgbm9ybWFsaXphZGEgKE5EVkkpIikNCmBgYA0KDQojIyMgw41uZGljZSBEaWZlcmVuY2lhbCBkZSBBZ3VhIE5vcm1hbGl6YWRvICooTkRXSSkqDQoNCg0KRW1wbGVhbmRvIGVzdGUgw61uZGljZSBzZXLDoSBwb3NpYmxlIGRpZmVyZW5jaWFyIGxhcyBtYXNhcyBkZSBhZ3VhIHkgbGFzIHpvbmFzIHF1ZSB0ZW5nYW4gYWx0b3Mgbml2ZWxlcyBkZSBzYXR1cmFjacOzbiBkZSBodW1lZGFkIGVtcGxlYW5kbyBsYXMgYmFuZGFzIHJlc3BlY3RpdmFzIG9mcmVjaWRhcyBwb3IgbGFzIGltw6FnZW5lcyBtdWx0aWVzcGVjdHJhbGVzIExhbmRzYXQgOCBvIGN1YWxxdWllciBvdHJvIHNhdMOpbGl0ZSwgbGEgZmluYWxpZGFkIGRlIGVzdGUgw61uZGljZSBlcyAqKmRldGVybWluYXIgZWwgZXN0csOpcyBow61kcmljbyBkZSBsYSB2ZWdldGFjacOzbiwgaHVtZWRhZCBvIHNhdHVyYWNpw7NuIGRlbCBzdWVsbyB5IGRlbGltaXRhY2nDs24gZGUgZW1iYWxzZXMgbyBjdWVycG9zIGRlIGFndWEqKg0KDQpFbiBlbCDDoXJlYSBkZSByZWN1cnNvcyBow61kcmljb3MsIGFncm9sb2fDrWEgeSBhZmluZXMsIHNlIHJlcXVpZXJlIGxhIGV2YWx1YWNpw7NuIHRhbnRvIGRlIGNhbGlkYWQgY29tbyBkZSBjYW50aWRhZCBkZSBhZ3VhLCBwb3IgbG8gcXVlIHNlIGVuY3VlbnRyYW4gZsOhY2lsbWVudGUgbcO6bHRpcGxlcyBtZXRvZG9sb2fDrWFzIG1lZGlhbnRlIGVsIGFuw6FsaXNpcyBkZSBkYXRvcyBjb24gc2Vuc29yZXMgcmVtb3RvcyBwYXJhIGRldGVybWluYXIgaW5kaWNhZG9yZXMgcXVlIG9mcmV6Y2FuIGluZm9ybWFjacOzbiByZWxldmFudGUuDQpBbGd1bmFzIGRlIGxhcyBkaWZlcmVudGVzIGVzdHJhdGVnaWFzIHBhcmEgZGV0ZXJtaW5hciBlbCBJbmRpY2UgZGUgQWd1YSBkZSBEaWZlcmVuY2lhIE5vcm1hbGl6YWRhICooTkRXSSkqIHNlIGV4cG9uZW4gYSBjb250aW51YWNpw7NuDQoNCg0KDQoqKkdhbyAoMTk5NikqKg0KDQoNCkxvcyB2YWxvcmVzIG9idGVuaWRvcyBvc2NpbGFyw6FuIGVudHJlIC0xIHkgMSwgcXVlIHJlcHJlc2VudGFyw6FuIGxhcyBkaWZlcmVudGVzIHN1cGVyZmljaWVzIGRlIGFndWEgeSB2ZWdldGFjacOzbiBjb24gY29udGVuaWRvcyBkZSBodW1lZGFkIGFsdG9zLCBvIGVuIGNhc28gY29udHJhcmlvLCBsYSBhdXNlbmNpYSBkZSBlc3RhLg0KDQoNCkxhIHJlbGFjacOzbiBzZSBkYSBhIHBhcnRpciBkZSBsYXMgYmFuZGFzIGRlIEluZnJhcnJvam8gQ2VyY2FubyAqKE5JUikqIGUgSW5mcmFycm9qbyBkZSBvbmRhIGNvcnRhICAqKFNXSVIpKi4NCg0KKkdhbyAoMTk5NikqIEFyZ3VtZW50YSBxdWUgdW5hIG3DoXhpbWEgcHJlY2lzacOzbiBzZSBhbGNhbnphcsOhIHNpIHNlIHVzYW4gZG9zIGNhbmFsZXMgZGVsIGluZnJhcnJvam8gY2VyY2FubywgY2VudHJhZG9zIGVuIDAuODbCtW0geSAxLjI0wrVtLg0KDQpQYXJhIGVsIGNhc28gZGUgTGFuZHNhdCA4ICBzZSBlbXBsZWFyw6EgbGEgYmFuZGEgU1dJUi0xICgxLjU3IMK1bSDigJMgMS42NSDCtW0pIA0KDQokJE5EV0kgPSAoTklSIC0gU1dJUikgLyAoTklSICsgU1dJUikkJA0KDQoNCmBgYHtyfQ0KI05EV0kgLSBHYW8gKDE5OTYpDQpuZHdpZnVuYyA8LSBmdW5jdGlvbihpbWcsIGssIGkpew0KICBiY3JrIDwtIGltZ1tba11dDQogIGJjcmkgPC0gaW1nW1tpXV0NCiAgbmR3aWZ1bmMgPC0gKGJjcmsgLSBiY3JpKSAvIChiY3JrICsgYmNyaSkNCiAgcmV0dXJuKG5kd2lmdW5jKQ0KfQ0KDQpuZHdpZ2FvIDwtIG5kd2lmdW5jKHRlbmpvbGlzdCwgNSwgNikNCnBsb3QobmR3aWdhbywgY29sID0gcmV2KGNtLmNvbG9ycygxMCkpLCBtYWluID0gIk5EV0kgLSBHYW8gKDE5OTYpIikNCmBgYA0KDQoNCg0KKipNY0ZlZXRlcnMgKDE5OTYpKioNCg0KDQpDb24gZWwgZmluIGRlIGRlbGluZWFyIGxhcyBjYXJhY3RlcsOtc3RpY2FzIGRlIGFndWFzIGFiaWVydGFzIHkgcmVzYWx0YXIgZXN0YXMgZW4gbGEgaW1hZ2VuIHNhdGVsaXRhbCwgZWwgTkRXSSB1c2EgbGEgYmFuZGEgTklSIHkgbGEgbHV6IHZlcmRlIHZpc2libGUgcGFyYSBpbmNyZW1lbnRhciBsYSBwcmVzZW5jaWEgZGUgdGFsZXMgY2FyYWN0ZXLDrXN0aWNhcywgZWxpbWluYW5kbyBvdHJhcyBjb21vIGVsIHN1ZWxvIHkgbGEgdmVnZXRhY2nDs24gKihNY0ZlZXRlcnMsIDE5OTYpKi4gDQoNCiQkTkRXSSA9IChHcmVlbiAtIE5JUikgLyAoR3JlZW4gKyBOSVIpJCQgIA0KDQoNCg0KYGBge3J9DQojTkRXSSAtIE1jRmVldGVycyAoMTk5NikNCm5kd2lmdW5jIDwtIGZ1bmN0aW9uKGltZywgaywgaSl7DQogIGJjcmsgPC0gaW1nW1trXV0NCiAgYmNyaSA8LSBpbWdbW2ldXQ0KICBuZHdpZnVuYyA8LSAoYmNyayAtIGJjcmkpIC8gKGJjcmsgKyBiY3JpKQ0KICByZXR1cm4obmR3aWZ1bmMpDQp9DQoNCm5kd2lNQ0YgPC0gbmR3aWZ1bmModGVuam9saXN0LCAzLCA1KQ0KcGxvdChuZHdpTUNGLCBjb2wgPSByZXYodG9wby5jb2xvcnMoNjAwKSksIG1haW4gPSAiTkRXSSAtIE1jRmVldGVycyAoMTk5NikiKQ0KYGBgDQoNCioqWHUgKDIwMDYpKioNCg0KDQpMYSBtb2RpZmljYWNpw7NuIGFsIE5EV0kgZGUgKk1jRmVldGVycyAoMTk5NikqIGVzIG1vZGlmaWNhZG8gYWwgcmVlbXBsYXphciBsYSBiYW5kYSBpbmZyYXJyb2phIG1lZGlhLCBwb3IgbGEgYmFuZGEgaW5mcmFycm9qYSBjZXJjYW5hLCBsbyBjdWFsIHB1ZWRlIHJlc3VsdGFyIGVuIHVuYSBub3RhYmxlIG1lam9yw61hIGRlIGxvcyBlc3Blam9zIGRlIGFndWEgeSBsYSBlbGltaW5hY2nDs24gZGVsIHJ1aWRvIG3DoXMgZWZpY2llbnRlIHF1ZSBnZW5lcmFuIGRpZmVyZW50ZXMgc3VwZXJmaWNpZXMsIGxhIHZlZ2V0YWNpw7NuIHkgZWwgc3VlbG8uIEVuIGNvbnNlY3VlbmNpYSwgbGEgcG9zaWJsZSBzb2JyZWVzdGltYWNpw7NuIHF1ZSBzZSBkYSBlbiBlbCBORFdJIHNlIHJlZHVjZSBlbiBlbCBNRFdJICooWHUsIDIwMDYpKi4NCg0KJCRORFdJID0gKEdyZWVuIC0gU1dJUikgLyAoR3JlZW4gKyBTV0lSKSQkDQoNCg0KYGBge3J9DQojTkRXSSAtIFh1ICgyMDA2KQ0KbmR3aWZ1bmMgPC0gZnVuY3Rpb24oaW1nLCBrLCBpKXsNCiAgYmNyayA8LSBpbWdbW2tdXQ0KICBiY3JpIDwtIGltZ1tbaV1dDQogIG5kd2lmdW5jIDwtIChiY3JrIC0gYmNyaSkgLyAoYmNyayArIGJjcmkpDQogIHJldHVybihuZHdpZnVuYykNCn0NCg0KbW5kd2kgPC0gbmR3aWZ1bmModGVuam9saXN0LCAzLCA2KQ0KcGxvdChtbmR3aSwgY29sID0gcmV2KHRvcG8uY29sb3JzKDEwKSksIG1haW4gPSAiTkRXSSAtIFh1ICgyMDA2KSIpDQpgYGANCg0KDQoNCg0KIyMjIEluZGljZSBub3JtYWxpemFkbyBkZSDDoXJlYSBjb25zdHJpdWRhICooTkRCSSkqIA0KDQpFbCBpbmNvbnZlbmllbnRlIGRlIGxhIGNsYXNpZmljYWNpw7NuIGRlIMOhcmVhcyB1cmJhbmFzLCByYWRpY2EgZW4gcXVlIGVzdGFzIG5vIG9mcmVjZW4gdW5hIMO6bmljYSByZXNwdWVzdGEsIHNpbiBlbWJhcmdvLCBpbcOhZ2VuZXMgZGUgbWVqb3IgY2FsaWRhZCBwb2Ryw6FuIGZhY2lsaXRhciBsYSBpbnZlc3RpZ2FjacOzbiB5IGNhcmFjdGVyaXphY2nDs24gZGUgZXN0YXMgem9uYXMsIHNvYnJlIHRvZG8gcGFyYSBsYWJvcmVzIGRlIG1vbml0b3JlbyBkZSBjYW1iaW9zIGEgY29ydG8geSBsYXJnbyBwbGF6bywgeSBjb24gZXN0bywgdW5hIGFkZWN1YWRhIHBsYW5lYWNpw7NuICooQm91emVrcmksIExhc2JldCwgJiBMYWNoZWhhYiwgMjAxNSkqLg0KDQoNCkxhIGVjdWFjacOzbiBxdWUgZGVzY3JpYmUgKlRhdWZpayAmIEFobWFkICgyMDE2KSogcGFyYSBlbCBOREJJIHNlIG11ZXN0cmEgYSBjb250aW51YWNpw7NuLg0KDQokJCBOREJJID0gKFNXSVIgLSBOSVIpIC8gKE5JUiArIFNXSVIpICQkDQoNCg0KYGBge3J9DQojTkRCSQ0KbmRiaWZ1bmMgPC0gZnVuY3Rpb24oaW1nLCBrLCBpKXsNCiAgYmNyayA8LSBpbWdbW2tdXQ0KICBiY3JpIDwtIGltZ1tbaV1dDQogIG5kYmlmdW5jIDwtIChiY3JrIC0gYmNyaSkgLyAoYmNyaSArIGJjcmspDQogIHJldHVybihuZGJpZnVuYykNCn0NCg0KbmRiaSA8LSBuZGJpZnVuYyh0ZW5qb2xpc3QsIDYsIDUpDQpwbG90KG5kYmksIGNvbCA9IHJldihicHkuY29sb3JzKDEwKSksIG1haW4gPSAiTkRCSSIpDQpgYGANCg0KIyMgSGlzdG9ncmFtYXMNCg0KYGBge3J9DQpwYXIobWZyb3cgPSBjKDIsMSkpDQojTkRWSQ0KaGlzdChuZHZpLA0KICAgICBtYWluID0gIkRpc3RpYnVjacOzbiBkZSBsb3MgdmFsb3JlcyBORFZJIiwNCiAgICAgeGxhYiA9ICJORFZJIiwNCiAgICAgeWxhYiA9ICJGcmVjdWVuY2lhIiwNCiAgICAgY29sID0gIldoZWF0IiwNCiAgICAgeGxpbSA9IGMoLTAuNSwgMSksDQogICAgIGJyZWFrcyA9IDMwLA0KICAgICB4YXh0ID0gJ24nKQ0KYXhpcyhzaWRlPTEsIGF0ID1zZXEoLTAuNSwxLDAuMDUpLGxhYmVscyA9IHNlcSgtMC41LDEsMC4wNSkpDQoNCiNOREJJIA0KaGlzdChuZGJpLA0KICAgICBtYWluID0gIkRpc3RpYnVjacOzbiBkZSBsb3MgdmFsb3JlcyBOREJJIiwNCiAgICAgeGxhYiA9ICJOREJJIiwNCiAgICAgeWxhYiA9ICJGcmVjdWVuY2lhIiwNCiAgICAgY29sID0gICJ3aGVhdCIsDQogICAgIHhsaW0gPSBjKC0wLjUsIDEpLA0KICAgICBicmVha3MgPSAzMCwNCiAgICAgeGF4dCA9ICduJykNCmF4aXMoc2lkZT0xLCBhdCA9c2VxKC0wLjUsMSwwLjA1KSxsYWJlbHMgPSBzZXEoLTAuNSwxLDAuMDUpKQ0KDQojR2FvICgxOTk2KQ0KcGFyKG1mcm93ID0gYygzLDEpKQ0KaGlzdChuZHdpZ2FvLA0KICAgICBtYWluID0gIkRpc3RpYnVjacOzbiBkZSBsb3MgdmFsb3JlcyBORFdJIC0gR0FPICgxOTk2KSIsDQogICAgIHhsYWIgPSAiTkRXSSIsDQogICAgIHlsYWIgPSAiRnJlY3VlbmNpYSIsDQogICAgIGNvbCA9ICJibHVlIiwNCiAgICAgeGxpbSA9IGMoLTAuNSwgMSksDQogICAgIGJyZWFrcyA9IDMwLA0KICAgICB4YXh0ID0gJ24nKQ0KYXhpcyhzaWRlPTEsIGF0ID1zZXEoLTAuNSwxLDAuMDUpLGxhYmVscyA9IHNlcSgtMC41LDEsMC4wNSkpDQoNCiNORFdJIE1jRmVldGVycyAoMTk5NikNCmhpc3QobmR3aU1DRiwNCiAgICAgbWFpbiA9ICJEaXN0aWJ1Y2nDs24gZGUgbG9zIHZhbG9yZXMgTkRXSSAtIE1jRmVldGVycyAoMTk5NikiLA0KICAgICB4bGFiID0gIk5EV0kiLA0KICAgICB5bGFiID0gIkZyZWN1ZW5jaWEiLA0KICAgICBjb2wgPSAiYmx1ZSIsDQogICAgIHhsaW0gPSBjKC0wLjUsIDEpLA0KICAgICBicmVha3MgPSAzMCwNCiAgICAgeGF4dCA9ICduJykNCmF4aXMoc2lkZT0xLCBhdCA9c2VxKC0wLjUsMSwwLjA1KSxsYWJlbHMgPSBzZXEoLTAuNSwxLDAuMDUpKQ0KDQojTU5EV0kgWHUgKDIwMDYpDQpoaXN0KG1uZHdpLA0KICAgICBtYWluID0gIkRpc3RpYnVjacOzbiBkZSBsb3MgdmFsb3JlcyBORFdJIC0gWHUgKDIwMDYpIiwNCiAgICAgeGxhYiA9ICJORFdJIiwNCiAgICAgeWxhYiA9ICJGcmVjdWVuY2lhIiwNCiAgICAgY29sID0gImJsdWUiLA0KICAgICB4bGltID0gYygtMC41LCAxKSwNCiAgICAgYnJlYWtzID0gMzAsDQogICAgIHhheHQgPSAnbicpDQpheGlzKHNpZGU9MSwgYXQgPXNlcSgtMC41LDEsMC4wNSksbGFiZWxzID0gc2VxKC0wLjUsMSwwLjA1KSkNCg0KDQoNCmBgYA0KDQojIyAqKk3DqXRvZG9zIGRlIHNlZ21lbnRhY2nDs24gcG9yIHJlc3B1ZXN0YSBlc3BlY3RyYWwtVW1icmFsaXphY2nDs24qKg0KDQpMYSB1bWJyYWxpemFjacOzbiBlcyB1bm8gZGUgbG9zIG3DqXRvZG9zIGRlIHNlZ21lbnRhY2nDs24gbcOhcyBzZW5jaWxsb3MsIHlhIHF1ZSBhIHBhcnRpciBkZSB1bmEgaW1hZ2VuIHB1ZWRlIGdlbmVyYXJzZSB1biBlbmZvcXVlIGJpbmFyaW8gZG9uZGUgbG9zIGVsZW1lbnRvcyBkZSBydWlkbyBwdWVkZW4gYWRvcHRhciBjb2xvcmVzIGJsYW5jb3MsIHkgZWwgZm9uZG8gbyBpbnRlcsOpcyBjb2xvciBuZWdybyAqKENhbGxlam8gTS4sIDIwMTYpKi4gDQoNCk1lZGlhbnRlIGxhIGRlZmluaWNpw7NuIGRlIHVtYnJhbGVzIHNlIGxvZ3JhIHNlcGFyYXIgZWwgZm9uZG8sIGRvbmRlIHNlIGVtcGxlYW4gbGFzIGltw6FnZW5lcyBkZXNhcnJvbGxhZGFzIHBvciBsb3Mgw61uZGljZXMgZGUgdmVnZXRhY2nDs24sIHkgZWwgdmFsb3IgbcOtbmltbyB5IG3DoXhpbW8gYWNlcHRhYmxlIGVzIGRpY3RhZG8gcG9yIGVsIGNyaXRlcmlvIGRlbCBhbmFsaXN0YS4NCg0KKipWZWdldGFjacOzbioqICANCg0KVmFsb3JlcyBkZSAqTkRWSSogbWF5b3JlcyBhIDAuNCBoYW4gc2lkbyBpZGVudGlmaWNhZG9zIHBvdGVuY2lhbG1lbnRlIGNvbW8gY29iZXJ0dXJhIHZlZ2V0YWwuICANCg0KDQpgYGB7cn0NCnZlZyA8LSByZWNsYXNzaWZ5KG5kdmksIGNiaW5kKC1JbmYsIDAuNCwgTkEpKQ0KcGxvdCh2ZWcsIG1haW49J1ZlZ2V0YWNpw7NuJykNCmBgYA0KDQpVbmEgdW1icmFsaXphY2nDs24gbcOhcyBkZXRhbGxhIHNlIHB1ZWRlIHJlYWxpemFyIHBhcmEgaWRlbnRpZmljYXIgbG9zIG3Dumx0aXBsZXMgbml2ZWxlcyBkZSBjb2JlcnR1cmEgdmVnZXRhbCBzb2JyZSBsYSBlc2NlbmEsIGVuIGVzdGUgY2Fzbywgc2UgcG9kcsOhIHZpc3VhbGl6YXIgbGEgc2lndWllbnRlIGVzY2FsYS4gICAgDQoNCg0KDQp8UmFuZ28gZGUgTkRWSSAgICAgICAgIHwgIFZhbG9yIGFzaWduYWRvICB8IE5pdmVsIGRlIGNvYmVydHVyYSB2ZWdldGFsfCANCnw6LS0tLS0tLS0tLS0tLS0tLTp8Oi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTp8Oi0tLS0tLS0tLS0tLXwgDQp8LWluZiwwLjI1fCAxIHwgTnVsYXwNCnwwLjI1LTAuMyB8IDIgfCBNdXkgcG9jYXwNCnwwLjMtMC40ICB8IDMgfCBNb2RlcmFkYXwNCnwwLjQtMC41ICB8IDQgfCBBbHRhfA0KfDAuNS0raW5mIHwgNSB8IE11eSBhbHRhfA0KDQpgYGB7cn0NCnVtYnJhbE5EVkkgPC0gcmVjbGFzc2lmeShuZHZpLCBjKC1JbmYsMC4yNSwxLCAwLjI1LDAuMywyLCAwLjMsMC40LDMsIDAuNCwwLjUsNCwgMC41LEluZiwgNSkpDQpwbG90KHVtYnJhbE5EVkksIG1haW4gPSAnNSBVbWJyYWxlcyBkZSBjb2JlcnR1cmEgdmVnZXRhbCBkZXJpdmFkb3MgZGUgTkRWSScpDQoNCmBgYA0KDQoqKsOBcmVhcyBhYmllcnRhcyoqICANCg0KDQpEZSBsYSBtaXNtYSBmb3JtYSwgZXMgcG9zaWJsZSBpZGVudGlmaWNhciDDoXJlYXMgcXVlIHNlIGVuY3VlbnRyYW4gY29uIHBvY2EgbyBzaW4gY29iZXJ0dXJhIHZlZ2V0YWwgKioiw4FyZWFzIGFiaWVydGFzIioqLCBxdWUgc2Vnw7puIGVsICpORFZJKiB5IGxhIGRpc3RyaWJ1Y2nDs24gZGUgZnJlY3VlbmNpYXMgZGVsIGhpc3RvZ3JhbWEgZXN0YXLDoW4gYW51bGFkb3MgbG9zIHJhbmdvcyBkZSAoLWluZiwwLjM1KSB5IGRlICgwLjQsK2luZikuICANCg0KQWwgc29icmVwb25lciBsYXMgZ3LDoWZpY2FzIGRlIGVzdGUgdW1icmFsIHkgdW5hIGltYWdlbiBkZSBjb2xvciBmYWxzbyBkZSBsYXMgYmFuZGFzIDUsNCB5IDMsIHNlIGxvZ3JhIG9idGVuZXIgbGEgaW5mb3JtYWNpw7NuIGNvbXBsZW1lbnRhcmlhIHBhcmEgbGEgdmVnZXRhY2nDs24uIA0KDQojIyBVbWJyYWxlcyB7LnRhYnNldH0NCg0KIyMjIFVtYnJhbCBpbmRlcGVuZGllbnRlDQpgYGB7cn0NCiNwYXJhIHJlY2xhc2lmaWNhciBlbiBlc3RlIGNhc28gc2UgZGViZSBsaW1pdGFyIGVsIHJhc3RlciBlbiAzIGdydXBvcyAoLWluZiwwLjM1KSBxdWUgc2Vyw6FuIGFudWxhZG9zLCBbMC4zNSwwLjRdIHF1ZSB0ZW5kcmFuIHVuIHVuaWNvIHZhbG9yICgxKSB5ICgwLjQsK2luZikgc2Vyw6FuIHRhbWJpZW4gYW51bGFkb3MuDQoNCm9wZW5sYW5kIDwtIHJlY2xhc3NpZnkobmR2aSwgYygtSW5mLCAwLjM1LCBOQSwgIDAuMzUsIDAuNCwgMSwgIDAuNCwgSW5mLCBOQSkpDQpwbG90KG9wZW5sYW5kLCBtYWluID0gJ8Kow4FyZWFzIEFiaWVydGFzJykNCmBgYA0KDQojIyMgVW1icmFsICsgQ0NGDQpgYGB7cn0NCnBsb3RSR0IobGFuZHNhdEZDdmVnLCByPTEsIGc9MiwgYj0zLCBheGVzPVRSVUUsIHN0cmV0Y2g9ImxpbiIsIG1haW49IlJlbGV2YW5jaWEgZGUgw6FyZWFzIGFiaWVydGFzKExGQ0MpIikNCnBsb3Qob3BlbmxhbmQsIGFkZD1UUlVFLCBsZWdlbmQ9RkFMU0UpDQpgYGANCg0KDQojIyMgVW1icmFsICsgQ0NWDQpgYGB7cn0NCnBsb3RSR0IobGFuZHNhdFRDLCByPTEsIGc9MiwgYj0zLCBheGVzPVRSVUUsIHN0cmV0Y2g9ImxpbiIsIG1haW49IlJlbGV2YW5jaWEgZGUgw6FyZWFzIGFiaWVydGFzKExUQ0MpIikNCnBsb3Qob3BlbmxhbmQsIGFkZD1UUlVFLCBsZWdlbmQ9RkFMU0UpDQpgYGANCg0KKipBZ3VhKioNCg0KRGViaWRvIGEgbGFzIHJlZHVjaWRhcyB6b25hcyBjb24gZnVlbnRlcyBow61kcmljYXMgbyBlc3Blam9zIGRlIGFndWEsIHN1bWFkbyBhIGxhIHJlc29sdWNpw7NuIGVzcGFjaWFsIGRlIGxhIGVzY2VuYSwgbm8gZXMgcG9zaWJsZSBnZW5lcmFyIHBvbMOtZ29ub3MgYWRlY3VhZG9zIHF1ZSBwZXJtaXRhbiBsYSBjYXJhY3Rlcml6YWNpw7NuIGluaWNpYWxtZW50ZSBwcmVzZW50YWRhIHBhcmEgZXN0YSBpbmZvcm1hY2nDs24sIHNpbiBlbWJhcmdvLCBsYSB1bWJyYWxpemFjacOzbiBkZWwgKk5EV0kqIGRlIE1jLSBGZWV0ZXJzICgxOTk2KSwgcGVybWl0ZSBkaXNjcmltaW5hciBkZSBmb3JtYSBhcHJveGltYWRhIGVzdGFzIHpvbmFzLiANCg0KYGBge3J9DQp3YXRlciA8LSByZWNsYXNzaWZ5KG5kd2lNQ0YsIGMoLUluZiwgLTAuMCwgTkEsIC0wLjAsIEluZiwgMSkpDQojU29sbyBlcyBuZWNlc2FyaW8gYWNvdGFyIGVsIGxpbWl0ZSBpbmZlcmlvciwgeWEgcXVlIHRvZG8gc29icmUgZXN0ZSB2YWxvciAoMC4xKSBzZSBtdWVzdHJhIGNvbiBjbGFzaWZpY2FjacOzbiBkZSBpbnRlcsOpcw0KY29sb3JzIDwtIGNvbG9yUmFtcFBhbGV0dGUoYygid2hlYXQiLCJjeWFuIiwiYmx1ZSIpKQ0KcGxvdFJHQihsYW5kc2F0VEMsIHI9MSwgZz0yLCBiPTMsIGF4ZXM9VFJVRSwgc3RyZXRjaD0ibGluIiwgbWFpbj0iUmVsZXZhbmNpYSBkZSBhZ3VhKExUQ0MpIikNCnBsb3Qod2F0ZXIsIGFkZD1UUlVFLCBsZWdlbmQ9RkFMU0UpDQojcGxvdCh3YXRlcixjb2wgPSByZXYoYnB5LmNvbG9ycygyMDAwKSksIG1haW4gPSAnd2F0ZXInKQ0KYGBgDQoNCg0KKipab25hcyBVcmJhbmFzKioNCg0KTGFzIHpvbmFzIGNvbiBjb25zdHJ1Y2Npb25lcyBpZGVudGlmaWNhZGFzIHBvciBlbCAqTkRCST4wKiBwZXJtaXRlIHJlYWxpemFyIGxhIHNpZ3VpZW50ZSB1bWJyYWxpemFjacOzbi4NCg0KYGBge3J9DQp1cmJhbnJlY2xhc3MgPC0gcmVjbGFzc2lmeShuZGJpLCBjYmluZCgtSW5mLCAwLjAsIE5BKSkNCmNvbG9ycyA8LSBjb2xvclJhbXBQYWxldHRlKGMoIndoZWF0IiwiZ3JleSIsImJsYWNrIikpDQpwbG90KHVyYmFucmVjbGFzcyxjb2wgPSBjb2xvcnMoNTApLCBtYWluID0gJ1pvbmFzIGNvbnN0cnVpZGFzJykNCmBgYA0KDQojIyAqKkNsYXNpZmljYWNpw7NuIG5vIHN1cGVydmlzYWRhKioNCg0KTGEgY2xhc2lmaWNhY2nDs24gbm8gc3VwZXJ2aXNhZGEgZGUgdW5hIGVzY2VuYSBjb25zaXN0ZSBlbiBhZ3J1cGFyIGxvcyBwaXhlbGVzIGVuIGNsYXNlcyBxdWUgdGVuZ2FuIHNpbWlsaXR1ZCByZWxhdGl2YSBkZSByZWZsZWN0YW5jaWEgc2luIHJlcXVlcmlyIHVuYSB0b21hIGRlIG11ZXN0cmFzIGVuIGNhbXBvICooV2lsbGluZ3RvbiBldCBhbC4sIDIwMTMpKiwgZW4gb2Nhc2lvbmVzIGVzIGVtcGxlYWRvIGNvbW8gdW5hIGhlcnJhbWllbnRhIGRlIGFwcm94aW1hY2nDs24gaW5pY2lhbC4NCg0KYGBge3J9DQpyYXNsaXN0IDwtIHBhc3RlMCgndGVuam8vb2xpdGlycy9icCcsMTo3LCIudGlmIikNCnRlbmpvbGlzdCA8LSBzdGFjayhyYXNsaXN0KQ0KbmFtZXModGVuam9saXN0KSA8LSBjKCd1bHRyYS1ibHVlJywnYmx1ZScsJ2dyZWVuJywncmVkJywnTklSJywnU1dJUi0xJywnU1dJUi0yJykNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkocmdlb3MpDQplIDwtIGV4dGVudCg1OTAwMDAsNjAwMDAwLDUzNDAwMCw1NDAwMDApDQoNCm5kdmljcm9wIDwtIGNyb3AobmR2aSxlKQ0KcG9saWdvbiA8LSBjcm9wKGxjX3RlbmpvLGUpDQpuciA8LSBnZXRWYWx1ZXMobmR2aWNyb3ApDQpgYGANCg0KDQpgYGB7cn0NCnNldC5zZWVkKDk5KQ0Ka21uY2x1c3RlciA8LSBrbWVhbnMobmEub21pdChuciksIGNlbnRlcnMgPSA0LCBpdGVyLm1heCA9IDUwMCwgbnN0YXJ0ID0gNSwgYWxnb3JpdGhtPSJMbG95ZCIpDQoNCmBgYA0KDQoNCmBgYHtyfQ0Ka25yIDwtIHNldFZhbHVlcyhuZHZpY3JvcCwga21uY2x1c3RlciRjbHVzdGVyKQ0Ka25yIDwtIHJhc3RlcihuZHZpY3JvcCkNCnZhbHVlcyhrbnIpIDwtIGttbmNsdXN0ZXIkY2x1c3Rlcg0KDQpgYGANCg0KRGViaWRvIGEgbGEgZ3JhbiB2YXJpYWJpbGlkYWQgZGUgcGl4ZWxlcyB5IGRpc3BlbmRpb3NvIHByb2Nlc28gZGUgdmVyaWZpY2FjacOzbiwgc2UgcmVhbGl6YSBsYSBjbGFzaWZpY2FjacOzbiBkZSBsYSB6b25hIGNvbXByZW5kaWRhIGVudHJlIGxhcyBzaWd1aWVudGVzIGNvb3JkZW5hZGFzLg0KDQp8IFggbcOtbmltbyAgICAgICB8ICAgICBYIG3DoXhpbW8gfCBZIG3DrW5pbW8gICAgICAgfCBZIG3DoXhpbW8gICAgIHwNCnw6LS0tLS0tLS0tLS0tLS06fDotLS0tLS0tLS0tLS06fDotLS0tLS0tLS0tLS0tLTp8Oi0tLS0tLS0tLS0tLTp8DQp8NTkwMDAwICAgICAgICAgIHwgICAgICAgIDYwMDAwMHwgICAgICAgICAgNTM0MDAwfCAgICAgIDU0MDAwMCAgfA0KDQoNCg0KQSBwYXJ0aXIgZGUgbG9zIHBvbMOtZ29ub3MgZGVzY3JpdG9zIGluaWNpYWxtZW50ZSwgc2UgdmVyaWZpY2EgbGEgY2xhc2lmaWNhY2nDs24gbm8gc3VwZXJ2aXNhZGEgcXVlIGZ1ZSBkZXJpdmFkYSBkZWwgYW7DoWxpc2lzIGRlbCBORFZJLCBjb24gNCBuaXZlbGVzIGRlIGNsYXNpZmljYWNpw7NuLCBwYXJhIHF1ZSBmdWVyYSBjb25zaXN0ZW50ZSBjb24gbGFzIGNhdGVnb3LDrWFzIHByZXNlbnRlcy4NCg0KDQoNCnxWYWxvciBkZSBDbGFzZSB8IERlc2NyaXBjacOzbiB8DQp8Oi0tLS0tLS0tLS0tLS0tOnw6LS0tLS0tLS0tLS0tOnwNCnwgMSB8IFpvbmFzIHVyYmFuaXphZGFzIHkgcHJlZGlvcyBlbiBmYXNlIGRlIHByZXBhcmFjacOzbiBwYXJhIGN1bHRpdm98DQp8IDIgfCBJbnZlcm5hZGVyb3MgeSBlc3RydWN0dXJhcyBkZSBwcm9kdWNjacOzbiBhZ3LDrWNvbGEgfA0KfCAzIHwgQ3VsdGl2b3MgeSB2ZWdldGFjacOzbiBkZSBjb2JlcnR1cmEgbW9kZXJhZGEgfA0KfCA0IHwgQ3VsdGl2b3MgeSB2ZWdldGFjacOzbiBkZSBjb2JlcnR1cmEgYWx0YSB8DQoNCg0KYGBge3J9DQpteWNvbG9yIDwtIGMoIiNmZWY2NWIiLCIjZmYwMDAwIiwgIiNkYWE1MjAiLCIjMDAwMGZmIiwiIzAwMDBmZiIsIiMwMGZmMDAiLCIjY2JiZWI1IiwNCiAgICAgICAgICAgICAiI2MzZmY1YiIsICIjZmY3MzczIiwgIiMwMGZmMDAiLCAiIzgwODA4MCIpDQpgYGANCg0KIyMgQ2xhc2lmaWNhY2nDs24gTlMgYSBwYXJ0aXIgZGUgTkRWSSB7LnRhYnNldH0NCiMjIyBORFZJDQpgYGB7cn0NCnBsb3QobmR2aWNyb3AsIGNvbCA9IHJldih0ZXJyYWluLmNvbG9ycygxMCkpLCBtYWluID0gJ0xhbmRzYXQtTkRWSScpDQpgYGANCg0KIyMjIENsYXNpZmljYWNpw7NuIHBhcmNpYWwNCmBgYHtyfQ0KcGxvdChrbnIsIG1haW4gPSAnQ2xhc2lmaWNhY2nDs24gbm8gc3VwZXJ2aXNhZGEgLSDDoXJlYSBwYXJjaWFsJywgY29sID0gcmV2KHRvcG8uY29sb3JzKDQpKSApDQpwbG90KGxjX3RlbmpvLCBhZGQ9VFJVRSkNCmBgYA0KDQoNCmNvbiBlc3RlIHByb2Nlc28gZGUgdmVyaWZpY2FjacOzbiwgcHJvY2VkZW1vcyBhIHJlYWxpemFyIGxhIGNsYXNpZmljYWNpw7NuIG5vIHN1cGVydmlzYWRhIHNvYnJlIHRvZGEgZWwgw6FyZWEgZGUgaW50ZXLDqXMuDQoNCmBgYHtyfQ0KbnIgPC0gZ2V0VmFsdWVzKG5kdmkpDQoNCmBgYA0KDQoNCmBgYHtyfSANCnNldC5zZWVkKDk5KQ0Ka21uY2x1c3RlciA8LSBrbWVhbnMobmEub21pdChuciksIGNlbnRlcnMgPSA0LCBpdGVyLm1heCA9IDUwMCwgbnN0YXJ0ID0gNSwgYWxnb3JpdGhtPSJMbG95ZCIpDQpgYGANCg0KDQpgYGB7cn0NCmtuciA8LSBzZXRWYWx1ZXMobmR2aSwga21uY2x1c3RlciRjbHVzdGVyKQ0Ka25yIDwtIHJhc3RlcihuZHZpKQ0KdmFsdWVzKGtucikgPC0ga21uY2x1c3RlciRjbHVzdGVyDQpgYGANCg0KIyMjIENsYXNpZmljYWNpw7NuIGNvbXBsZXRhDQpgYGB7cn0NCm15Y29sb3IgPC0gYygiI2ZlZjY1YiIsIiNmZjAwMDAiLCAiI2RhYTUyMCIsIiMwMDAwZmYiLCIjMDAwMGZmIiwiIzAwZmYwMCIsIiNjYmJlYjUiLA0KICAgICAgICAgICAgICIjYzNmZjViIiwgIiNmZjczNzMiLCAiIzAwZmYwMCIsICIjODA4MDgwIikNCg0KbGNfdGVuam8gPC0gc2hhcGVmaWxlKCJ1c29kZXN1ZWxvLnNocCIpDQoNCnBsb3Qoa25yLCBtYWluID0gJ0NsYXNpZmljYWNpw7NuIG5vIHN1cGVydmlzYWRhIC0gw6FyZWEgY29tcGxldGEnLCBjb2wgPSByZXYodG9wby5jb2xvcnMoNCkpICkNCnBsb3QobGNfdGVuam8sIGFkZD1UUlVFKQ0KYGBgDQoNCiMjICoqQ2xhc2lmaWNhY2nDs24gc3VwZXJ2aXNhZGEqKg0KDQoqV2lsbGluZ3RvbiBldCBhbC4sICgyMDEzKSogRGVmaW5lbiBsb3MgbcOpdG9kb3MgZGUgY2xhc2lmaWNhY2nDs24gc3VwZXJ2aXNhZGEgY29tbyBwcm9jZWRpbWllbnRvcyBxdWUgaWRlbnRpZmljYW4gw6FyZWFzIGVzcGVjdHJhbG1lbnRlIGhvbW9nw6luZWFzIG1lZGlhbnRlIHVuIG11ZXN0cmVvIGRlIGVudHJlbmFtaWVudG8gZGUgbGEgaW1hZ2VuIHNhdGVsaXRhbCwgZXMgZGVjaXIsIGVsIHVzdWFyaW8gbyBhbmFsaXN0YSBkZWJlIGNvbm9jZXIgbGFzIGNhcmFjdGVyw61zdGljYXMgZGUgY29iZXJ0dXJhIGRlIGxvcyBwb2zDrWdvbm9zIG8gcHVudG9zIGluZ3Jlc2Fkb3MuDQoNCkVsIGFsZ29yaXRtbyB0ZW5kcsOhIGNvbiBlc3RvIGxhIGNhcGFjaWRhZCBkZSBleHRyYXBvbGFyIGxhcyBjYXJhY3RlcsOtc3RpY2FzIGVzcGVjdHJhbGVzIGRlIGxvcyBtdWVzdHJlb3MgYSB0b2RvcyBsb3MgcGl4ZWxlcyBkZSBsYSBlc2NlbmEuDQoNCipJbmZvcm1hY2nDs24gZGUgbG9zIHBvbMOtZ29ub3MgZGUgZW50cmVuYW1pZW50byoNCg0KYGBge3J9DQpwb2xpPC0gc2hhcGVmaWxlKCJwb2xpZ29ub3NjbGFzaWYuc2hwIikNCnBvbGkNCmBgYA0KDQoNCiMjIFBvbMOtZ29ub3MgZGUgZW50cmVuYW1pZW50byB7LnRhYnNldH0NCg0KIyMjIFRhYmxhIGRlIHBvbMOtZ29ub3MNCmBgYHtyfQ0KcG9saUBkYXRhDQpgYGANCg0KIyMjIFNvYnJlcG9zaWNpw7NuIGRlIHBvbMOtZ29ub3MNCg0KYGBge3J9DQpwbG90UkdCKHRlbmpvbGlzdCw0LDMsMiwgc3RyZXRjaD0ibGluIikNCnBsb3QocG9saSxhZGQ9VFJVRSxjb2w9IndoZWF0IixwY2ggPSA1LCBsd2Q9MikNCmBgYA0KDQoNCiMjICoqUmFuZG9tIEZvcmVzdCoqDQoNCipSYW5kb20gRm9yZXN0KiBlcyBlbCB0ZXJtaW5vIGdlbsOpcmljbyBwYXJhIGxvcyBtw6l0b2RvcyBkZSBjbGFzaWZpY2FjacOzbiBxdWUgY29uc2lzdGVuIGVuIHVuIGFsZ29yaXRtbyBkZSAqKm3Dumx0aXBsZXMqKiBhcmJvbGVzIGRlIGRlY2lzacOzbiB0aXBvIENBUlQsIGRvbmRlIGNhZGEgdW5vIGRlIGVzdG9zIGVzIGVudHJlbmFkbyBhIHBhcnRpciBkZSBsb3MgcG9sw61nb25vcyBvIHB1bnRvcyBkZSBtdWVzdHJlbyBpbmljaWFsZXMgKEdpc2xhc29uIGV0IGFsLiwgMjAwNikuDQoNCg0KKipSZXN1bWVuIGRlIGRhdG9zIGVzcGVjdHJhbGVzKioNCmBgYHtyfQ0Kc3VtbWFyeSh0ZW5qb2xpc3QpDQpgYGANCg0KDQoNCioqUmFzdGVyaXphY2nDs24gZGUgcG9sw61nb25vcyoqDQpgYGB7cn0NCmNsYXNlIDwtIHJhc3Rlcml6ZShwb2xpLCB0ZW5qb2xpc3QsICd2YWx1ZScpDQpzcHBsb3QoY2xhc2UsIHNjYWxlcz1saXN0KGRyYXc9VCkpDQpgYGANCg0KKipQb2zDrWdvbm9zIGRlIGVudHJlbmFtaWVudG8gcG9yIGJhbmRhcyoqDQpgYGB7cn0NCg0KbWFzY2FyYSA8LSBtYXNrKHRlbmpvbGlzdCxjbGFzZSkNCmVudHJlbmFtaWVudG9fciA8LWFkZExheWVyKG1hc2NhcmEsIGNsYXNlKQ0KcGxvdChlbnRyZW5hbWllbnRvX3IpDQpgYGANCg0KYGBge3J9DQpuYW1lcyhlbnRyZW5hbWllbnRvX3IpPC0gYygidWx0cmEuYmx1ZSIsICJibHVlIiwgImdyZWVuIiwgInJlZCIsICJOSVIiLCJTV0lSLjEiLCJTV0lSLjIiLCJjbGFzZSIpDQoNCnRhYmxhdmFsb3JlcyA8LSBnZXRWYWx1ZXMoZW50cmVuYW1pZW50b19yKQ0KdGFibGF2YWxvcmVzIDwtIG5hLm9taXQodGFibGF2YWxvcmVzKQ0KdGFibGF2YWxvcmVzIDwtIGFzLmRhdGEuZnJhbWUodGFibGF2YWxvcmVzKQ0KdGFibGF2YWxvcmVzJGNsYXNlIDwtIGZhY3Rvcih0YWJsYXZhbG9yZXMkY2xhc2UsIGxldmVscyA9IGMoMTo0KSkNCmBgYA0KDQoNCmBgYHtyfQ0KbGlicmFyeShyYW5kb21Gb3Jlc3QpDQptb2RlbFJGIDwtIHJhbmRvbUZvcmVzdCh4PXRhYmxhdmFsb3Jlc1sgLGMoMTo3KV0sIHk9dGFibGF2YWxvcmVzJGNsYXNlLG50cmVlPTUwMCwgaW1wb3J0YW5jZSA9IFRSVUUsIGRvLnRyYWNlPUZBTFNFKQ0KY29sbmFtZXMobW9kZWxSRiRjb25mdXNpb24pIDwtIGMoIkludmVybmFkZXJvcyIsICJzdWVsbyBkZXNudWRvIiwgIkNvYmVydHVyYSB2ZWdldGFsIiwgIlVyYmFubyIsImVycm9yIGRlIGNsYXNlIikNCnJvd25hbWVzKG1vZGVsUkYkY29uZnVzaW9uKSA8LSBjKCJJbnZlcm5hZGVyb3MiLCAic3VlbG8gZGVzbnVkbyIsICJDb2JlcnR1cmEgdmVnZXRhbCIsICJVcmJhbm8iKQ0KYGBgDQoNCioqUmVzdWx0YWRvcyBkZWwgZW50cmVuYW1pZW50byBkZWwgbW9kZWxvKioNCmBgYHtyfQ0KbW9kZWxSRg0KYGBgDQoNCmBgYHtyfQ0KdmFySW1wUGxvdChtb2RlbFJGKQ0KYGBgDQoNCg0KYGBge3J9DQpwcmVkTEMgPC0gcHJlZGljdCh0ZW5qb2xpc3QsIG1vZGVsPW1vZGVsUkYsIGZpbGVuYW1lPSJwcmVkaWNjY2lvbi50aWYiLCBuYS5ybT1UUlVFLCBvdmVyd3JpdGU9VFJVRSkNCnNhdmUobW9kZWxSRiwgZmlsZT0icHJlZGljdGlvbl9tb2RlbFJGLlJEYXRhIikNCmBgYA0KDQoNCmBgYHtyfQ0Kc3BwbG90KGFzKHByZWRMQywgIlNwYXRpYWxHcmlkRGF0YUZyYW1lIiksIGN1dHM9NCwgYXQ9MDo0LCBjb2wucmVnaW9ucz1jKCJibGFjayIsICJjeWFuIiwgInBpbmsiLCAieWVsbG93IiksIG1haW49IkNsYXNpZmljYWNpw7NuIHN1cGVydmlzYWRhIC0gUmFuZG9tIEZvcmVzdCIpDQoNCmBgYA0KDQpSZWNvcmRlbW9zIHF1ZSBsYXMgY2F0ZWdvcsOtYXMgZGUgY2xhc2lmaWNhY2nDs24gc29uOg0KDQp8VmFsb3IgZGUgQ2xhc2UgfCBEZXNjcmlwY2nDs24gfA0KfDotLS0tLS0tLS0tLS0tLTp8Oi0tLS0tLS0tLS0tLTp8DQp8IDEgfCBJbnZlcm5hZGVyb3MsIGNvbnN0cnVjY2lvbmVzIGFncsOtY29sYXN8DQp8IDIgfCBTdWVsbyBzaW4gY29iZXJ0dXJhLCBwcmVwYXJhY2nDs24gZGUgY3VsdGl2b3wNCnwgMyB8IEN1bHRpdm9zIHkgcmVnaW9uZXMgY29uIGNvYmVydHVyYSB2ZWdldGFsIHwNCnwgNCB8IFpvbmFzIHVyYmFuaXphZGFzIHwNCg0KDQojIyAqKkV2YWx1YWNpw7NuIGRlbCBtb2RlbG8qKg0KDQpMYSBldmFsdWFjacOzbiBkZWwgbW9kZWxvIHBlcm1pdGlyw6EgdGVuZXIgdW4gYXJndW1lbnRvIGN1YW50aXRhdGl2byBkZSBwcmVjaXNpw7NuIHBhcmEgZWwgbWFwYSBjbGFzaWZpY2FkbywgYSBjb250aW51YWNpw7NuIHNlIHVzYXLDoW4gZG9zIG1lZGlkYXMgYW1wbGlhbWVudGUgdXNhZGFzIGVuIGxvcyBzaXN0ZW1hcyBkZSB0ZWxlZGV0ZWNjacOzbjsgKlByZWNpc2nDs24gZ2VuZXJhbCogeSAqS2FwcGEqLCBxdWUgZW1wbGVhbiBwcm9jZXNvcyBkZSB2YWxpZGFjacOzbiBjcnV6YWRhLCBkaXZpZGllbmRvIGxvcyBkYXRvcyBlbiA1IGdydXBvcyBkaWZlcmVudGVzLCBjb24gZWwgcHJpbWVybyBzZSByZWFsaXphcsOhIGxhICBwcnVlYmEgZGUgZXN0ZSwgbWllbnRyYXMgcXVlIGxvcyBvdHJvcyA0IGdydXBvcyByZWFsaXphcsOhbiBlbCBhanVzdGUgbyBlbnRyZW5hbWllbnRvLg0KDQoNCmBgYHtyfQ0KbGlicmFyeShkaXNtbykNCmBgYA0KDQpDYW50aWRhZCBkZSBkYXRvcyBwb3IgZ3J1cG86DQpgYGB7cn0NCnNldC5zZWVkKDk5KQ0KaiA8LSBrZm9sZCh0YWJsYXZhbG9yZXMsIGsgPSA1LCBieT10YWJsYXZhbG9yZXMkY2xhc2UpDQp0YWJsZShqKQ0KYGBgDQoNCmBgYHtyfQ0KeCA8LSBsaXN0KCkNCmZvciAoayBpbiAxOjUpIHsNCiAgICB0cmFpbiA8LSB0YWJsYXZhbG9yZXNbaiE9IGssIF0NCiAgICB0ZXN0IDwtIHRhYmxhdmFsb3Jlc1tqID09IGssIF0NCiAgICBtb2RlbFJGIDwtIHJhbmRvbUZvcmVzdChhcy5mYWN0b3IoY2xhc2Upfi4sIGRhdGE9dHJhaW4sIG1ldGhvZCA9ICdjbGFzcycsIG1pbnNwbGl0ID0gNSkNCiAgICBwY2xhc3MgPC0gcHJlZGljdChtb2RlbFJGLCB0ZXN0LCB0eXBlPSdjbGFzcycpDQogICAgIyBjcmVhdGUgYSBkYXRhLmZyYW1lIHVzaW5nIHRoZSByZWZlcmVuY2UgYW5kIHByZWRpY3Rpb24NCiAgICB4W1trXV0gPC0gY2JpbmQodGVzdCRjbGFzZSwgYXMuaW50ZWdlcihwY2xhc3MpKQ0KfQ0KYGBgDQoNCmBgYHtyfQ0KeSA8LSBkby5jYWxsKHJiaW5kLHgpDQp5IDwtIGRhdGEuZnJhbWUoeSkNCmBgYA0KDQoNCmBgYHtyfQ0KY29sbmFtZXMoeSkgPC0gYygnb2JzZXJ2ZWQnLCdwcmVkaWN0ZWQnKQ0KDQpjb25tYXQgPC10YWJsZSh5KQ0KYGBgDQoNCk1hdHJpeiBkZSBjb21wYXJhY2nDs24gZW50cmUgZGF0b3Mgb2JzZXJ2YWRvcyB5IHByZWRlY2lkb3MgcGFyYSBjYWRhIGdydXBvIGRlIGNsYXNpZmljYWNpw7NuOg0KDQpgYGB7cn0NCm5sY2RjbGFzcyA8LSBjKCJpbnZlcm5hZGVyb3MiLCAic3VlbG8gZGVzbnVkbyIsICJjb2JlcnR1cmEgdmVnZXRhbCIsICJ1cmJhbm8iKQ0KY2xhc3NkZiA8LSBkYXRhLmZyYW1lKGNsYXNzdmFsdWUxID0gYygxLDIsMyw0KSwgY2xhc3NuYW1lczEgPSBubGNkY2xhc3MpDQoNCmNvbG5hbWVzKGNvbm1hdCkgPC0gY2xhc3NkZiRjbGFzc25hbWVzMQ0Kcm93bmFtZXMoY29ubWF0KSA8LSBjbGFzc2RmJGNsYXNzbmFtZXMxDQpoZWFkKGNvbm1hdCkNCmBgYA0KDQoNClN1bWFtb3MgbGEgdG90YWxpZGFkIGRlIGNhc29zLCByZXN1bHRhbmRvOg0KYGBge3J9DQpuIDwtIHN1bShjb25tYXQpDQpuDQpgYGANCg0KRXh0cmFlbW9zIGxvcyB2YWxvcmVzIGRlIGxhIGRpYWdvbmFsLCBsbyBjdWFsIG5vcyBwZXJtaXRlIG9ic2VydmFyLCBtb2RpZmljYXIgbyBnZW5lcmFyIGRhdG9zIGFsbWFjZW5hZG9zIGVuIGxhIGRpYWdvbmFsIGRlIHVuYSBtYXRyaXosIGVuIGVzdGUgY2FzbywgZG9uZGUgbGFzIGNsYXNlcyBvYnNlcnZhZGFzIGNvaW5jaWRpcsOhbiBjb24gbGFzIHByZWRlY2lkYXMuDQoNCmBgYHtyfQ0KZGlhZyA8LWRpYWcoY29ubWF0KQ0KZGlhZw0KYGBgDQoNCg0KICANCioqRWN1YWNpw7NuIC0gUHJlY2lzacOzbiBnZW5lcmFsIGRlbCBtb2RlbG8qKg0KDQokJCBPQT1cZnJhY3tcc3VtX3tpLGo9MX1ee259WF97aSxqfX17XHN1bV97bSxuPTF9XntufVhfe20sbn19JCQgDQoNCkRvbmRlOg0KJE9BPSQgUHJlY2lzacOzbiBnZW5lcmFsIGRlbCBtb2RlbG8NCiRpPWokIEltbmRpY2FuIGxvcyBlbGVtZW50b3MgZGUgbGEgZGlhZ29uYWwgZGUgdW5hIG1hdHJpeg0KDQokXHN1bV97aSxqPTF9XntufVhfe2ksan09JCBTdW1hIGRlIGxvcyB2YWxvcmVzIGRlIGxhIGRpYWdvbmFsIHByaW5jaXBhbCBkZSBsYSBtYXRyaXogZGUgY29uZnVzacOzbi4gIA0KJFxzdW1fe20sbj0xfV57bn1YX3ttLG59PSQgU3VtYSBkZSB0b2RvcyBsb3MgdmFsb3JlcyBkZSBsYSBtYXRyaXogZGUgY29uZnVzacOzbg0KDQpgYGB7cn0NCk9BIDwtc3VtKGRpYWcpL24NCmBgYA0KDQoNCiAgDQoqKkVjdWFjacOzbiAtIENvcnJlY2Npw7NuIGRlIGxhIHByZWNpc2nDs24gZ2VuZXJhbCBkZWwgbW9kZWxvIC0gS2FwcGEqDQogIA0KJCRLQVBQQT0gXGZyYWN7T0EtQ19hfXsxLUNfYX0kJA0KDQogIA0KRG9uZGU6DQogIA0KJENfYT0kIFN1bWEgZGVsIHByb2R1Y3RvIGRlIGxvcyB0b3RhbGVzIGRlIGNhZGEgZmlsYSB5IGNvbHVtbmEgZGl2aWRpZG9zIHBvciBlbCBuw7ptZXJvIHRvdGFsIGRlIHBpeGVsZXMgbXVlc3RyZWFkb3MgcGFyYSBjYWRhIGNsYXNlLg0KDQpTdW1hIGRlIGZpbGFzOg0KDQpgYGB7cn0NCnJvd3N1bXMgPC0gYXBwbHkoY29ubWF0LCAxLCBzdW0pDQpyb3dzdW1zDQpwIDwtIHJvd3N1bXMvbg0KYGBgDQoNClN1bWEgZGUgY29sdW1uYXM6IA0KDQpgYGB7cn0NCmNvbHN1bXMgPC0gYXBwbHkoY29ubWF0LCAyLCBzdW0pDQpxIDwtIGNvbHN1bXMvbg0KY29sc3Vtcw0KYGBgDQoNCiRDX2EkOg0KYGBge3J9DQpleHBBY2N1cmFjeSA8LSBzdW0ocCpxKQ0Ka2FwcGEgPC0gKE9BIC0gZXhwQWNjdXJhY3kpLygxLWV4cEFjY3VyYWN5KQ0KYGBgDQoNCg0KKipUYWJsYSBkZSBSZXN1bHRhZG9zKioNCiAgDQoNCnxQcmVjaXNpw7NuIGdlbmVyYWwgJChPQSkkIHwgQ29ycmVjY2nDs24gZGUgbGEgcHJlY2lzacOzbiBnZW5lcmFsICQoS0FQUEEpJCB8DQp8Oi0tLS0tLS0tLS0tLS0tOnw6LS0tLS0tLS0tLS0tOnwNCnwgMC45NzIxNDQ0IHwgMC45NTg4NTQ0IHwNCg0KDQoNCiMgKio0LiBEaXNjdXNpw7NuKioNCg0KQXVucXVlIGVsIHBlcmZpbCBlc3BlY3RyYWwgZGVsIHN1YmdydXBvIHF1ZSBjb250aWVuZSBsYXMgem9uYXMgY29uIHZlZ2V0YWNpw7NuIHR1cmdlbnRlIHRpZW5lIHZhbG9yZXMgcXVlIHBlcm1pdGVuIHN1IGbDoWNpbCBkaXNjcmltaW5hY2nDs24sIGxhcyDDoXJlYXMgZGVzY3ViaWVydGFzIHBvc2VlbiB2YWxvcmVzIGRlIHJlZmxlY3RhbmNpYSBlbiBsYSBiYW5kYSBTV0lSIC0xIG1heW9yZXMgYSBsYXMgcmVnaW9uZXMgcXVlIGN1ZW50YW4gY29uIGNvbnN0cnVjY2lvbmVzIHVyYmFuYXMsIHBvciBsbyBxdWUgbGEgaWRlbnRpZmljYWNpw7NuIGRlIHpvbmFzIGFncsOtY29sYXMgc2UgdnVlbHZlIGN1aWRhZG9zYS4gDQoNCkxhcyBjb25zdHJ1Y2Npb25lcyBlbiBnZW5lcmFsIHBvc2VlbiBuaXZlbGVzIGRlIHJlZmxlY3RhbmNpYSBlbiBsYXMgYmFuZGFzIG11eSBzaW1pbGFyZXMgYSB6b25hcyBjb24gdmVnZXRhY2nDs24gZW4gZmFzZXMgaW5pY2lhbGVzIGRlIGRlc2Fycm9sbG8sIGxhcyB2w61hcyBkZSBhY2Nlc28gYSBsb3MgbXVuaWNpcGlvcyBkZSBDb3RhLCBDaMOtYSB5IFRlbmpvLCBubyB0aWVuZW4gZ3JhbmRlcyBkaW1lbnNpb25lcywgcG9yIGxvIHF1ZSByZXN1bHRhIGNvbXBsZWpvIHZpc3VhbGl6YXJsYXMgY29uIGxhIHJlc29sdWNpw7NuIGVzcGFjaWFsIG9mcmVjaWRhIHBvciBlbCBzYXTDqWxpdGUgTGFuZHNhdCA4LiANCg0KcG9yIGVzdGFzIHJhem9uZXMsIGxvcyBjb250cmFzdGVzIGRlIGxhcyBpbcOhZ2VuZXMgZ2VuZXJhZGFzIGhhbiBzaWRvIGVzY29naWRvcyBjdWlkYWRvc2FtZW50ZSBjb24gZWwgZmluIGRlIHBvZGVyIGRpZmVyZW5jaWFyIGVzdGFzIGNhdGVnb3LDrWFzLiANCg0KVGVuam8geSBzdXMgYWxyZWRlZG9yZXMgdGllbmVuIGdyYW4gY2FudGlkYWQgZGUgaW52ZXJuYWRlcm9zIHkgZXN0cnVjdHVyYXMgY29uIGFsdG9zIG5pdmVsZXMgZGUgcmVmbGVjdGFuY2lhIGVuIGxhIGJhbmRhIE5JUiwgcGVybyBtZWRpYW50ZSBsYXMgbWV0b2RvbG9nw61hcyBkZSBzZWdtZW50YWNpw7NuIHNlIGlkZW50aWZpY2FuIGbDoWNpbG1lbnRlLg0KDQpFbCBncmFmaWNvIGRlIGNvcnJlbGFjacOzbiBlbnRyZSBiYW5kYXMgcGVybWl0ZSB2aXN1YWxpemFyIGVsIHBvdGVuY2lhbCBkZSBsYSBiYW5kYSBOSVIgcGFyYSByZWFsaXphciBsb3MgZGlmZXJlbnRlcyDDrW5kaWNlcywgZGViaWRvIGEgcXVlIGN1ZW50YSBjb24gbGEgbWVub3MgY29ycmVsYWNpw7NuIHkgY29uIGVzdG8sIHNlIGxvZ3JhIHVuYSBtZW5vciByZWR1bmRhbmNpYSBkZSBkYXRvcy4NCg0KRWwgTkRWSSBlbXBsZWEgbGEgaW50ZXJhY2Npw7NuIGRlIGxhIHJlZmxlY3RhbmNpYSBlbnRyZSBsYSBsdXogdmlzaWJsZSB5IGVsIGluZnJhcnJvam8gY2VyY2FubyBkZSBsYSB2ZWdldGFjacOzbiwgIGxvcyB2YWxvcmVzIGVudHJlIGxvcyBxdWUgb3NjaWxhIGVzdGUgw61uZGljZSBlcyAtMSB5ICsxLCBkb25kZSB1biB2YWxvciBwb3NpdGl2byBpbmRpY2Fyw6EgYWx0YXMgZGVuc2lkYWRlcyBkZSB2ZWdldGFjacOzbiwgbG8gcXVlIHB1ZWRlIHByZXNlbnRhcnNlIGbDoWNpbG1lbnRlIGVuIHJlZ2lvbmVzIGJvc2Nvc2FzIG8gY3VsdGl2b3MgZGUgYWx0YSBkZW5zaWRhZCwgZXN0YSBpbmZvcm1hY2nDs24gcmVzYWx0YSBzb2JyZSBsYSBlc2NlbmEgZGViaWRvIGEgbGEgZ3JhbiBjYW50aWRhZCBkZSBwcmVkaW9zIGRlc3RpbmFkb3MgYSBwcm9kdWNjacOzbiBhZ3LDrWNvbGEgeSBwYXN0b3MgcGFyYSBnYW5hZG8sIGxvcyBjdWFsZXMgdGllbmVuIG1heW9yIHJlbGV2YW5jaWEgZW4gbGEgem9uYSBzdXItb2NjaWRlbnRhbC4NCg0KDQpFbCBORFdJIHBvciBsYSBtZXRvZG9sb2fDrWEgZGUgR2FvICgxOTk2KSBubyBzb2xvIHRpZW5lIGxhIGNhcGFjaWRhZCBkZSBpZGVudGlmaWNhciDDoXJlYXMgY29uIGN1ZXJwb3MgZGUgYWd1YSwgc2lubyB0YW1iacOpbiBhbHRvcyBuaXZlbGVzIGRlIHNhdHVyYWNpw7NuIG8gaHVtZWRhZCBkZSBsYSB2ZWdldGFjacOzbiAodHVyZ2VuY2lhKSwgcG9yIGVsbG8gcHVlZGUgc2VyIHZpYWJsZSBpbnRyb2R1Y2lyIGVzdGUgaW5kaWNhZG9yIHBhcmEgbGEgZXZhbHVhY2nDs24gdGVtcHJhbmEgZGUgZXN0csOpcyBow61kcmljbywgZGlzY3JpbWluYW5kbyBmw6FjaWxtZW50ZSBsYXMgcmVnaW9uZXMgZGVzY3ViaWVydGFzLCB1cmJhbml6YWRhcyBvIGNvbiBjb2JlcnR1cmFzIGFudHLDs3BpY2FzLg0KDQpMb3Mgbml2ZWxlcyBhbHRvcyBkZSBzYXR1cmFjacOzbiBzb24gZsOhY2lsbWVudGUgaWRlbnRpZmljYWJsZXMgZW4gbG9zIGN1bHRpdm9zIGVzdGFibGVjaWRvcyBkZWwgdmFsbGUsIGF1biBjdWFuZG8gbGEgZXNjZW5hIGZ1ZSBjYXB0YWRhIGVuIGVsIHBlcmlvZG8gdHJhZGljaW9uYWwgZGUgbWF5b3IgZMOpZmljaXQgaMOtZHJpY28NCg0KUGFyYSBlbCBjYXNvIGRlbCDDrW5kaWNlIE5EV0kgcG9yIGxhIG1ldG9kb2xvZ8OtYSBkZSBNY0ZlZXRlcnMgKDE5OTYpIGxvcyDDum5pY29zIGVsZW1lbnRvcyByZXByZXNlbnRhZG9zIGNvbiB2YWxvcmVzIG1heW9yZXMgc29uIGxvcyBwZXF1ZcOxb3MgY3VlcnBvcyBkZSBhZ3VhIG8gem9uYXMgY29uIGFsdG9zIG5pdmVsZXMgZGUgc2F0dXJhY2nDs24uIExhIGdlbmVyYWNpw7NuIGRlIHBvbMOtZ29ub3MgcXVlIHJlcHJlc2VudGVuIGxvcyBjdWVycG9zIGRlIGFndWEgcmVzdWx0YSBjb21wbGVqYSBkZWJpZG8gYSBsYXMgZGltZW5zaW9uZXMgZGUgZXN0b3MgcmVzcGVjdG8gYSBsYSBlc2NlbmEgeSBsYSByZXNvbHVjacOzbiBlc3BhY2lhbCwgc2luIGVtYmFyZ28sIHVuYSBhZGVjdWFkYSB1bWJyYWxpemFjacOzbiBhIHBhcnRpciBkZSBsYSBkaWZlcmVuY2lhIGVudHJlIGJhbmRhcyBkZWwgZXNwZWN0cm8gdmlzaWJsZSwgZG9uZGUgY3VlbnRhbiBjb24gbWF5b3JlcyBuaXZlbGVzIGRlIHJlZmxlY3RhbmNpYSwgeSBsYSBiYW5kYSBOSVIsIHBlcm1pdGUgc29icmVwb25lciBlIGlkZW50aWZpY2FyIHBhcnRlIGRlIGVsbG9zLCByZXN1bHRhbmRvLCBhdW4gYXPDrSwgaW5zdWZpY2llbnRlcyByZXNwZWN0byBhIGxhIHJlYWxpZGFkLg0KDQpMbyBtaXNtbyBzdWNlZGUgY29uIGVsIE1EV0kgcHJvcHVlc3RvIHBvciBYdSAoMjAwNiksIGRvbmRlIGxhcyDDoXJlYXMgcXVlIGN1ZW50YW4gY29uIGVzcGVqb3MgZGUgYWd1YSBzb24gZsOhY2lsbWVudGUgaWRlbnRpZmljYWJsZXMsIHlhIHF1ZSBlc3RvcyBhYnNvcmJlbiBncmFuIHBhcnRlIGRlIGxhIHJlZmxlY3RhbmNpYSBlbiBlbCBlc3BlY3RybyBkZWwgaW5mcmFycm9qbyBjZXJjYW5vLCB1biBhc3BlY3RvIHF1ZSByZXN1bHRhIGNvbmZ1c28gZXMgbGEgYXVzZW5jaWEgZGUgcmVzcHVlc3RhIGVzcGVjdHJhbCBlbiBsYSB0b3RhbGlkYWQgZGUgbGFzIGJhbmRhcyBwYXJhIGxhcyBsYWRlcmFzIGRlIHBlbmRpZW50ZXMgbXV5IHByb251bmNpYWRhcyAiYmFycmFuY29zIG8gYWJpc21vcyIsIGxvIGN1YWwgZGViZSB0ZW5lcnNlIG11eSBlbiBjdWVudGEgeSBzZXIgY29tcGVuc2FkbyBjb24gbGEgY2FyYWN0ZXJpemFjacOzbiB2aXN1YWwgZGVsIHRlcnJlbm8uIA0KDQpEZW50cm8gZGUgbG9zIHZhbG9yZXMgbWVub3JlcyBhIGNlcm8sIHNlIGVuY3VlbnRyYW4gem9uYXMgcHJldmlhbWVudGUgaWRlbnRpZmljYWRhcyBjb21vIGN1bHRpdm9zIHR1cmdlbnRlcywgbyB2ZWdldGFjacOzbi4gUG9yIGVuY2ltYSBkZWwgdmFsb3IgbWVuY2lvbmFkbywgZW1waWV6YW4gYSBlbmNvbnRyYXJzZSB6b25hcyB1cmJhbmFzLCBwcmVkaW9zIGRlc2N1YmllcnRvcyBvIGVuIGZhc2UgZGUgcHJlcGFyYWNpw7NuIHBhcmEgY3VsdGl2bywgeSBsYXMgZXN0cnVjdHVyYXMgZGUgY3VsdGl2byAoaW52ZXJuYWRlcm9zKSwgcXVlIGhhbiBtb3N0cmFkbyBncmFuZGVzIG5pdmVsZXMgZGUgcmVmbGVjdGFuY2lhIGVuIGxhcyBiYW5kYXMgdXNhZGFzIHBhcmEgZXN0ZSDDrW5kaWNlLg0KDQpMYSBjbGFzaWZpY2FjacOzbiBubyBzdXBlcnZpc2FkYSBkZSB1bmEgcmVnacOzbiBtw6FzIHBlcXVlw7FhIHBlcm1pdGUgdmVyaWZpY2FyIHkgY2F0ZWdvcml6YXIgYWRlY3VhZGFtZW50ZSBsb3MgcmVzdWx0YWRvcywgbG8gcXVlIHBvc3Rlcmlvcm1lbnRlIHNlIHJlZmxlamEgZW4gbGEgZWplY3VjacOzbiBkZWwgY8OzZGlnbyBwYXJhIHVuYSBpbWFnZW4gZGUgbWF5b3IgdGFtYcOxby4NCg0KTGEgY2FsYXNpZmljYWNpw7NuIHN1cGVydmlzYWRhIGEgcGFydGlyIGRlbCBtb2RlbG8gUmFuZG9tIEZvcmVzdCwgcGVybWl0ZSBsYSBnZW5lcmFjacOzbiBkZSB1biBtYXBhIGRlIGNhcmFjdGVyaXN0aWNhcyBob21vZ2VuZWFzLCBzb2JyZSBlbCBjdWFsIHNlIGlkZW50aWZpY2FuIGZhY2lsbWVudGUgbGFzIDQgY2F0ZWdvcsOtYXMgcGxhbnRlYWRhcyB5IGNhcmdhZGFzIGVuIGxvcyA4OSBwb2zDrWdvbm9zIGRlIGVudHJlbmFtaWVudG8sIGxhIG1hdHJpeiBkZSBjb25mdXNpw7NuIGFycm9qYSB2YWxvcmVzIGRlIGVycm9yIGRlIGNsYXNlIG1lbm9yZXMgYWwgMTAlLiANCg0KDQojICoqNS4gQ29uY2x1c2lvbmVzKioNCg0KMS4gIExhcyBzZW1lamFuemFzIGVudHJlIGxhcyByZXNwdWVzdGFzIGVzcGVjdHJhbGVzIGRlIGxhcyByZWdpb25lcyBkZXNjdWJpZXJ0YXMgeSBsYXMgem9uYXMgdXJiYW5pemFkYXMgbyBjb24gZXN0cnVjdHVyYXMgYWdyw61jb2xhcywgaW1wbGljYSB1bmEgY3VpZGFkb3NhIGlkZW50aWZpY2FjacOzbiBlbiBsYSBzZWdtZW50YWNpw7NuIHBsYW50ZWFkYS4NCg0KMi4JRW50ZW5kZXIgbGFzIHJlc3B1ZXN0YXMgcmFkaW9tw6l0cmljYXMgZGUgbGFzIGRpZmVyZW50ZXMgY29iZXJ0dXJhcyBzZSBmYWNpbGl0YSBlbXBsZWFuZG8gZWwgZGlhZ3JhbWEgZGUgcGVyZmlsIGVzcGVjdHJhbCwgZG9uZGUgZXMgcG9zaWJsZSBhcHJveGltYXJzZSBhIGxhcyBiYW5kYXMgZGUgaW50ZXLDqXMgZW4gZnVuY2nDs24gZGUgbGFzIGNvYmVydHVyYXMgcXVlIHNlIHF1aWVyYW4gcmVzYWx0YXIsIHlhIHNlYSBlbiB1biBncsOhZmljbyBSR0IgZGUgY29sb3IgZmFsc28gbyBlbiBhbGd1bmEgZGUgbGFzIG1ldG9kb2xvZ8OtYXMgZGUgc2VnbWVudGFjacOzbiBwcmVzZW50YWRhcy4NCg0KMy4gIExhIGNsYXNpZmljYWNpw7NuIG5vIHN1cGVydmlzYWRhIHJlcHJlc2VudGEgdW5hIGFwcm94aW1hY2nDs24gYSBsYXMgY2F0ZWdvcsOtYXMgc2VsZWNjaW9uYWRhcywgc2luIGVtYmFyZ28sIGxhIHNpbWlsaXR1ZCBkZSBsYSByZXNwdWVzdGEgZXNwZWN0cmFsIG8gZWwgcnVpZG8sIGdlbmVyYW4gZXJyb3JlcyBlbiBlc3RhIG1ldG9kb2xvZ8OtYS4NCg0KNC4gIFZpc3VhbG1lbnRlLCBsYSBjbGFzaWZpY2FjacOzbiBzdXBlcnZpc2FkYSBtZWRpYW50ZSBsYSBtZXRvZG9sb2fDrWEgZGUgUmFuZG9tIEZvcmVzdCwgYXJyb2phIG1lam9yZXMgcmVzdWx0YWRvcyBxdWUgbGEgY2xhc2lmaWNhY2nDs24gbm8gc3VwZXJ2aXNhZGEsIHRlbmllbmRvIGVuIGN1ZW50YSBxdWUgbG9zIHBvbMOtZ29ub3MgZGUgZW50cmVuYW1pZW50byBkZWJlbiBldml0YXIgbGEgZGlmdXNpdmlkYWQgZXNwZWN0cmFsIGRlIGxvcyBsw61taXRlcywgbG8gY3VhbCByZXN1bHRhcmlhIGVuIHByb2Nlc28gZGUgZW50cmVuYW1pZW50byBkZWwgbW9kZWxvIGNvbiBtYXlvciBlcnJvci4NCg0KNS4gTGEgcHJlY2lzacOzbiBkZWwgbW9kZWxvICRPQSQgeSAkS0FQUEEkLCBtdWVzdHJhbiB2YWxvcmVzIGFjZXB0YWJsZXMgZGUgdmFsaWRhY2nDs24uDQoNCiMgKio2LiBSZWZlcmVuY2lhcyoqIA0KDQoxLglBcml6YSwgQS4gKDIwMTMpLiBEZXNjcmlwY2nDs24geSBDb3JyZWNjacOzbiBkZSBQcm9kdWN0b3MgTGFuZHNhdCA4IExEQ00gKExhbmRzYXQgRGF0YSBDb250aW51aXR5IE1pc3Npb24pLiBJbiBDZW50cm8gZGUgSW52ZXN0aWdhY2nDs24geSBEZXNhcnJvbGxvIGVuIGluZm9ybWFjacOzbiBHZW9ncsOhZmljYSBkZWwgSUdBQyAtQ0lBRi4gQm9nb3TDoSBELiBDLg0KDQoyLglCb3V6ZWtyaSwgUy4sIExhc2JldCwgQS4gQS4sICYgTGFjaGVoYWIsIEEuICgyMDE1KS4gQSBOZXcgU3BlY3RyYWwgSW5kZXggZm9yIEV4dHJhY3Rpb24gb2YgQnVpbHQtVXAgQXJlYSBVc2luZyBMYW5kc2F0LTggRGF0YS4gSm91cm5hbCBvZiB0aGUgSW5kaWFuIFNvY2lldHkgb2YgUmVtb3RlIFNlbnNpbmcsIDQzKDQpLCA4NjfigJM4NzMuIGh0dHBzOi8vZG9pLm9yZy8xMC4xMDA3L3MxMjUyNC0wMTUtMDQ2MC02DQoNCjMuICBDYWxsZWpvIE0uLCBJLiBSLiAoMjAxNikuIFNlZ21lbnRhY2nDs24gYXV0b23DoXRpY2EgZGUgdGV4dHVyYXMgZW4gaW3DoWdlbmVzIGFncsOtY29sYXMuIFVOSVZFUlNJREFEIENPTVBMVVRFTlNFIERFIE1BRFJJRCAuDQoNCjQuCUdhbywgQi4tQy4gKDE5OTYpLiBOYXZhbCBSZXNlYXJjaCBMYWJvcmF0b3J5LCA0NTU1IE92ZXJsb29rIEF2ZS4gUmVtb3RlIFNlbnMuIEVudmlyb24sIDU4LCAyNTfigJMyNjYuDQoNCjUuICBHaXNsYXNvbiwgUC4gTy4sIEJlbmVkaWt0c3NvbiwgSi4gQS4sICYgU3ZlaW5zc29uLCBKLiBSLiAoMjAwNikuIFJhbmRvbSBmb3Jlc3RzIGZvciBsYW5kIGNvdmVyIGNsYXNzaWZpY2F0aW9uLiBQYXR0ZXJuIFJlY29nbml0aW9uIExldHRlcnMsIDI3KDQpLCAyOTTigJMzMDAuIGh0dHBzOi8vZG9pLm9yZy8xMC4xMDE2L2oucGF0cmVjLjIwMDUuMDguMDExDQoNCjYuCUdvbnphZ2EsIEMuICgyMDE0KS4gQXBsaWNhY2nDs24gZGUgw41uZGljZXMgZGUgVmVnZXRhY2nDs24gRGVyaXZhZG9zIGRlIEltw6FnZW5lcyBTYXRlbGl0YWxlcyBMYW5kc2F0IDcgRVRNICsgeSBBU1RFUiBwYXJhIGxhIENhcmFjdGVyaXphY2nDs24gZGUgbGEgQ29iZXJ0dXJhIFZlZ2V0YWwgZW4gbGEgWm9uYSBDZW50cm8gZGUgbGEgUHJvdmluY2lhIERlIExvamEsIEVjdWFkb3IuIFVuaXZlcnNpZGFkIE5hY2lvbmFsIGRlIExhIFBsYXRhLg0KDQoNCjcuCUpveWNlLCBLLiBFLiwgQmVsbGlzcywgUy4gRS4sIFNhbXNvbm92LCBTLiBWLiwgTWNOZWlsbCwgUy4gSi4sICYgR2xhc3NleSwgUC4gSi4gKDIwMDkpLiBBIHJldmlldyBvZiB0aGUgc3RhdHVzIG9mIHNhdGVsbGl0ZSByZW1vdGUgc2Vuc2luZyBhbmQgaW1hZ2UgcHJvY2Vzc2luZyB0ZWNobmlxdWVzIGZvciBtYXBwaW5nIG5hdHVyYWwgaGF6YXJkcyBhbmQgZGlzYXN0ZXJzLiBQcm9ncmVzcyBpbiBQaHlzaWNhbCBHZW9ncmFwaHksIDMzKDIpLCAxODPigJMyMDcuIGh0dHBzOi8vZG9pLm9yZy8xMC4xMTc3LzAzMDkxMzMzMDkzMzk1NjMNCg0KOC4JTWNGZWV0ZXJzLCBTLiBLLiAoMTk5NikuIFRoZSB1c2Ugb2YgdGhlIE5vcm1hbGl6ZWQgRGlmZmVyZW5jZSBXYXRlciBJbmRleCAoTkRXSSkgaW4gdGhlIGRlbGluZWF0aW9uIG9mIG9wZW4gd2F0ZXIgZmVhdHVyZXMuIEludGVybmF0aW9uYWwgSm91cm5hbCBvZiBSZW1vdGUgU2Vuc2luZywgMTcoNyksIDE0MjXigJMxNDMyLiBodHRwczovL2RvaS5vcmcvMTAuMTA4MC8wMTQzMTE2OTYwODk0ODcxNA0KDQoNCjkuCVRhdWZpaywgQS4sICYgQWhtYWQsIFMuIFMuIFMuICgyMDE2KS4gTGFuZCBjb3ZlciBjbGFzc2lmaWNhdGlvbiBvZiBMYW5kc2F0IDggc2F0ZWxsaXRlIGRhdGEgYmFzZWQgb24gRnV6enkgTG9naWMgYXBwcm9hY2guIElPUCBDb25mZXJlbmNlIFNlcmllczogRWFydGggYW5kIEVudmlyb25tZW50YWwgU2NpZW5jZSwgMzcoMSkuIGh0dHBzOi8vZG9pLm9yZy8xMC4xMDg4LzE3NTUtMTMxNS8zNy8xLzAxMjA2Mg0KDQoxMC4JVGVuam8uIFJldmlzacOzbiBnZW5lcmFsIGRlbCBwbGFuIGRlIG9yZGVuYW1pZW50byB0ZXJyaXRvcmlhbCAtIFBPVCBkZWwgbXVuaWNpcGlvIGRlIFRlbmpvLCBDdW5kaW5hbWFyY2EuICwgKDIwMTQpLg0KDQoxMS4gVVNHUy4gKDIwMTEpLiBVU0dTIC0gTGFuZHNhdCBNaXNzaW9ucy4gVXNpbmcgdGhlIFVTR1MgTGFuZHNhdCBMZXZlbC0xIERhdGEgUHJvZHVjdC4gaHR0cHM6Ly93d3cudXNncy5nb3YvbGFuZC1yZXNvdXJjZXMvbmxpL2xhbmRzYXQvdXNpbmctdXNncy1sYW5kc2F0LWxldmVsLTEtZGF0YS1wcm9kdWN0DQoNCjEyLiBXaWxsaW5ndG9uLCBFLiwgTm9sYXNjbywgTS4sICYgQm9jY28sIE0uICgyMDEzKS4gQ2xhc2lmaWNhY2nDs24gc3VwZXJ2aXNhZGEgZGUgc3VlbG9zIGRlIHVzbyBhZ3LDrWNvbGEgZW4gbGEgem9uYSBjZW50cmFsIGRlIEPDs3Jkb2JhICggQXJnZW50aW5hICk6IGNvbXBhcmFjacOzbiBkZSBkaXN0aW50b3MgYWxnb3JpdG1vcyBzb2JyZSBpbcOhZ2VuZXMgTGFuZHNhdC4gQ29uZ3Jlc28gQXJnZW50aW5vIGRlIEFncm9JbmZvcm1hdGljYSwgQ0FJIDIwMTMsIDIwN+KAkzIxNi4NCg0KMTMuCVh1LCBILiAoMjAwNikuIE1vZGlmaWNhdGlvbiBvZiBub3JtYWxpc2VkIGRpZmZlcmVuY2Ugd2F0ZXIgaW5kZXggKE5EV0kpIHRvIGVuaGFuY2Ugb3BlbiB3YXRlciBmZWF0dXJlcyBpbiByZW1vdGVseSBzZW5zZWQgaW1hZ2VyeS4gSW50ZXJuYXRpb25hbCBKb3VybmFsIG9mIFJlbW90ZSBTZW5zaW5nLCAyNygxNCksIDMwMjXigJMzMDMzLiBodHRwczovL2RvaS5vcmcvMTAuMTA4MC8wMTQzMTE2MDYwMDU4OTE3OSAgDQoNCg==