Ejemplo: Solución (var$contrib
)
var$contrib
(general)
Las contribuciones de las variables a la variabilidad de un componente principal determinado se expresan en porcentaje. En este sentido:
Las variables que están correlacionadas con PC1 (es decir, Dim.1) y PC2 (es decir, Dim.2) son las más importantes para explicar la variabilidad del conjunto de datos.
Las variables que no se correlacionan con ningún PC o se correlacionan con las últimas dimensiones son variables con escasa contribución y pueden eliminarse para simplificar el análisis general.
var$contrib
(en R)
La contribución de las variables puede extraerse de la siguiente manera :
var$contrib
|
Dim.1
|
Dim.2
|
Dim.3
|
Dim.4
|
Dim.5
|
SemAcum
|
1.2499904
|
1.9652166
|
44.5094960
|
2.6970691
|
0.1864002
|
Exam1
|
8.8546321
|
2.7651851
|
0.1467796
|
56.3989472
|
8.9797893
|
Exam2
|
12.9388341
|
0.0912175
|
15.1614053
|
3.1481343
|
32.8938508
|
Exam3
|
0.2625478
|
24.3243861
|
7.0903539
|
11.4773003
|
7.3735463
|
Exam4
|
5.1866485
|
14.6043942
|
15.9309580
|
0.3477698
|
4.3741351
|
ExamAcum
|
21.4233418
|
7.6467496
|
1.5285300
|
0.7880084
|
0.0468019
|
Definitive
|
21.4233418
|
7.6467496
|
1.5285300
|
0.7880084
|
0.0468019
|
Expense
|
9.6722852
|
17.7028490
|
0.0116157
|
16.7041480
|
5.9809625
|
Income
|
8.9362085
|
19.6368851
|
0.0028382
|
7.4031247
|
16.0659323
|
Gas
|
10.0521700
|
3.6163671
|
14.0894932
|
0.2474898
|
24.0517798
|
Cuanto mayor sea el valor de la contribución, más contribuye la variable al componente.
var$contrib
(correlaciones)
Es posible utilizar la función corrplot
del paquete corrplot
para resaltar las variables que más contribuyen para cada dimensión.
corrplot(var$contrib,
is.corr=FALSE,
tl.col = "black",
#addCoef.col = 'grey50', #Agregar valores
#number.cex = 0.7, #Tamaño de los valores
tl.srt = 90,
bg = "lightblue", #Color del fondo
title="Matriz de correlaciones",
#tl.cex=1.5, #Tamaño de las vars y Dims
#cex.main=2.0, #Tamaño del título
#type="lower",
mar=c(0,0,4,0) #Ubicación del título
)

var$contrib
(diagramas de barra de cada variable)
La función fviz_contrib
del paquete factoextra
se puede emplear para dibujar un gráfico de barras de las contribuciones de las variables. Si los datos contienen muchas variables, se puede optar por mostrar solo las variables que más contribuyen. El siguiente código en R muestra las 10 variables principales que contribuyen a los componentes principales.
# Contribuciones de las variables a PC1
p1 <- fviz_contrib(res.pca, choice = "var", axes = 1, top = 10)
# Contribuciones de las variables a PC2
p2 <- fviz_contrib(res.pca, choice = "var", axes = 2, top = 10)

var$contrib
(diagrama de barra para el total)
A continuación, se puede visualizar la contribución total a PC1 y PC2:
fviz_contrib(res.pca, choice = "var", axes = 1:2, top = 10)

var$contrib
(Interpretaciones)
Interpretación No. 1:
La línea roja discontinua en el gráfico anterior indica la contribución promedio esperada.
Interpretación No. 2:
Si la contribución de las variables fuese uniforme, el valor esperado sería
\[\frac{1}{\mbox{longitud(variables)}} \;=\; \frac{1}{10}(100)\;=\; 10\, \%\]
(1/length(dat))*100
## [1] 10
Interpretación No. 3:
Para un componente dado, una variable con una contribución mayor que este umbral podría considerarse importante en la contribución al componente.
Interpretación No. 4:
Se debe tener en cuenta que la contribución total de una variable dada, en la explicación de las variaciones retenidas por dos componentes principales, digamos PC1 y PC2, se calcula como
\[ \mbox{Contrib} = \frac{C_1 \, \lambda_1 \; +\; C_2 \, \lambda_2}{\lambda_1 \;+\; \lambda_2}\]
donde:
\(C_1\) y \(C_2\) son las contribuciones de la variable en PC1 y PC2, respectivamente.
\(\lambda_1\) y \(\lambda_2\) son los eigenvalores de PC1 y PC2, respectivamente.
Interpretación No. 5:
Recordar que los eigenvalores miden la cantidad de variación retenida por cada PC. En este caso, la contribución promedio esperada (umbral) se calcula de la siguiente manera: Como se mencionó anteriormente, si las contribuciones de las 10 variables fueran uniformes, la contribución promedio esperada de una variable para PC1 y PC2 es:
\[ \mbox{Contrib} \; =\; \frac{10 \, \lambda_1 \; +\; 10 \, \lambda_2}{\lambda_1 \;+\; \lambda_2}\; =\; 10\]
Se puede observar que la variable ExamAcum
contribuyen más a las dimensiones 1 y 2.
var$contrib
(círculo de correlaciones)
Las variables más importantes pueden ser resaltadas en el gráfico de correlación de la siguiente manera:
fviz_pca_var(res.pca, col.var = "contrib",
repel= TRUE, # Evita traslapamiento de textos,
)
var$contrib
(argumento gradient.cols
)
Como ya se explicó, gradient.cols = c("green", "brown", "blue")
significa que:
Las variables con valores bajos de cos2
serán coloreadas en verde.
Las variables con valores medios de cos2
serán coloreadas en marrón.
Las variables con valores altos de cos2
serán coloreadas en azul.
fviz_pca_var(res.pca, col.var = "contrib",
repel= TRUE, # Evita traslapamiento de textos,
gradient.cols = c("green", "brown", "blue"),
)

var$contrib
(transpariencias con alpha.var
)
Tenga en cuenta que también es posible cambiar la transparencia de las variables según sus valores de contribución utilizando la opción alpha.var = "contrib"
:
# Cambiar la transpariencia para las contribuciones
fviz_pca_var(res.pca, alpha.var = "contrib",
col.var = "red",
#title="Transpariencia de las variables por contribución",
repel= TRUE # Evita traslapamiento de textos,
)

var$contrib
(círculo por variable continua)
En las secciones anteriores, demostramos cómo colorear variables según sus contribuciones y su coseno al cuadrado. Es importante destacar que también es posible colorear variables según cualquier variable continua personalizada. La variable de coloración debe tener la misma longitud que el número de variables activas en el ACP (aquí, $n=$10. Ejemplo:
# Create a random continuous variable of length 10
set.seed(123)
my.cont.var <- rnorm(10)
# Color variables by the continuous variable
fviz_pca_var(res.pca, col.var = my.cont.var,
gradient.cols = c("green", "brown", "blue"),
repel=TRUE,
title="Correlaciones entre las variables por variable continua",
legend.title = "Continua"
)

var$contrib
(círculo de correlaciones por grupos)
También es factible alterar el color de las variables basándose en grupos definidos por una variable cualitativa o categórica (comúnmente conocida como factor en R). Dado que no disponemos de ninguna variable de agrupación en nuestros conjuntos de datos para clasificar las variables, optaremos por crear una. En el siguiente ejemplo práctico, inicialmente clasificamos las variables en tres grupos mediante el algoritmo de agrupación kmeans (en otros documentos se explica esta teoría). Posteriormente, empleamos los clústeres obtenidos mediante el algoritmo kmeans para asignar colores a las variables. Para más detalles sobre clustering, puede consultarse la bibliografía recomendada.
# Crear una variable grupal con kmeans
# Crear 3 clúster (centers = 3)
set.seed(123)
res.km <- kmeans(var$coord, centers = 3, nstart = 25)
# Extraer etiquetas de los clúster
grp <- as.factor(res.km$cluster)
grp
## SemAcum Exam1 Exam2 Exam3 Exam4 ExamAcum Definitive
## 1 3 2 2 2 2 2
## Expense Income Gas
## 3 3 1
## Levels: 1 2 3
El círculo de correlaciones por grupos es el siguiente:
# Colores de las variables por grupos
fviz_pca_var(res.pca, col.var = grp,
palette = c("blue", "brown", "green"),
legend.title = "Cluster",
title="Correlaciones entre las variables por grupos",
repel= TRUE # Evita traslapamiento de textos
)

Es importante tener en cuenta que:
Si deseamos modificar los colores de los grupos, debemos emplear el parámetro palette
.
Para ajustar los colores de los gradientes, es necesario utilizar el parámetro gradient.cols
. Más adelante, se presenta un ejemplo utilizando este argumento.
var$contrib
(función dimdesc
)
Anteriormente se explicó cómo destacar las variables en función de su contribución a los componentes principales.
La función dimdesc
en FactoMineR
puede ser empleada para identificar las variables más relevantemente vinculadas a un componente principal específico. Este enfoque resulta útil para determinar la asociación significativa entre las variables y un componente principal dado, y puede ser utilizado de la siguiente manera:
res.desc <- dimdesc(res.pca, axes = c(1,2), proba = 0.05)
# Descripción de la dimensión 1
res.desc$Dim.1
##
## Link between the variable and the continuous variables (R-square)
## =================================================================================
## correlation p.value
## Definitive 0.8881031 1.560010e-08
## ExamAcum 0.8881031 1.560010e-08
## Exam2 0.6901879 2.677184e-04
## Expense 0.5967389 2.648620e-03
## Income 0.5735832 4.216409e-03
## Exam1 0.5709592 4.435181e-03
## Exam4 0.4369816 3.707266e-02
## Gas -0.6083446 2.070330e-03
# Descripción de la dimensión 2
res.desc$Dim.2
##
## Link between the variable and the continuous variables (R-square)
## =================================================================================
## correlation p.value
## Exam3 0.7566005 2.944647e-05
## Exam4 0.5862562 3.282977e-03
## Definitive 0.4242131 4.365105e-02
## ExamAcum 0.4242131 4.365105e-02
## Expense -0.6454569 8.807127e-04
## Income -0.6798013 3.593497e-04
En las salida anteriores, cuando sale $quanti
, indica resultados para variables cuantitativas. Es importante destacar que las variables están ordenadas según el \(p\)-valor de la correlación.
Ejemplo: Solución (get_pca_ind
)
ind
(gráficos de resultados)
Los resultados para individuos pueden ser obtenidos utilizando la función get_pca_ind
del paquete factoextra
. De manera similar a get_pca_var
, la función get_pca_ind
proporciona una lista de matrices que contienen todos los resultados para los individuos (coordenadas, correlación entre variables y ejes, cosenos al cuadrado y contribuciones).
ind <- get_pca_ind(res.pca)
ind
## Principal Component Analysis Results for individuals
## ===================================================
## Name Description
## 1 "$coord" "Coordinates for the individuals"
## 2 "$cos2" "Cos2 for the individuals"
## 3 "$contrib" "contributions of the individuals"
Para acceder a las diferentes componentes:
# Coordenadas de los individuos
ind$coord
# Calidad de los individuos
ind$cos2
# Contribuciones de los individuos
ind$contrib
ind
(gráfico simple)
Se utiliza la función fviz_pca_ind
para producir el gráfico de individuos:
fviz_pca_ind(res.pca,
title="Individuos"
)

ind
: gráfico según cos2
Se puede colorear a los individuos según sus valores de cos2
(al igual que se hace con las variables).
fviz_pca_ind(res.pca, col.ind = "cos2",
gradient.cols = c("blue", "brown", "green"),
title="Individuos de acuerdo a cos2",
repel= TRUE # Evita traslapamiento de textos
)
Obsérvese que en el gráfico, las personas similares se agrupan juntas.
ind
(tamaño del punto según cos2
)
Se puede ajustar también el tamaño del punto de acuerdo al cos2 de los individuos correspondientes.
fviz_pca_ind(res.pca, pointsize = "cos2",
pointshape = 21,
fill = "red",
repel = TRUE # Evita traslapamiento de textos
)
ind
(tamaño del punto y gradient según cos2
)
Para cambiar tanto el tamaño dl punto como el color por cos2
:
fviz_pca_ind(res.pca, col.ind = "cos2", pointsize = "cos2",
gradient.cols = c("blue", "brown", "green"),
repel = TRUE # Evita traslapamiento de textos
)

ind
(diagrama de contribución a un componente)
Para generar un gráfico de barras de la calidad de representación (cos2
) de los individuos en el mapa factorial, se puede emplear la función fviz_cos2
como se ha descrito previamente para las variables:
fviz_cos2(res.pca, choice = "ind")
ind
(diagrama de contribución a dos componentes)
Para visualizar la contribución de los individuos a los dos primeros componentes principales, escribe lo siguiente:
fviz_contrib(res.pca, choice = "ind", axes = 1:2)

ind
(colorear por variable continua)
En cuanto a las variables, los individuos pueden ser coloreados según cualquier variable continua personalizada especificando el argumento col.ind
.
#Genera una variable continua aleatoria de longitud 23
#(la misma longitud que el número de individuos activos en el PCA).
set.seed(123)
my.cont.var <- rnorm(23)
# Colorear las variables según la variable continua
fviz_pca_ind(res.pca, col.ind = my.cont.var,
gradient.cols = c("blue", "brown", "green"),
legend.title = "Scale"
)

ind
(colorear por grupos)
Aquí describimos cómo colorear a individuos por grupo. Además, mostramos cómo agregar elipses de concentración y elipses de confianza por grupos. Para esto, para estas secciones, utilizaremos los datos dat2
, construido de tal manera que contenga las variables de dat
y cualquier variable categórica (como, por ejemplo, Gender
, SES
, Economic
, etc, o grupos generados aleatoriamente.
dat1 <- datosCompleto[1:50, ]
dat2 <- datosCompleto[1:50, c(22:25,28:30)]
attach(dat2)
head(dat2,4)
Exam1
|
Exam2
|
Exam3
|
Exam4
|
Expense
|
Income
|
Gas
|
1.5
|
5.0
|
5.0
|
4.5
|
48.9
|
1.61
|
27.45
|
2.3
|
4.9
|
3.7
|
3.3
|
72.1
|
2.07
|
24.17
|
3.4
|
3.6
|
2.0
|
1.9
|
85.2
|
2.84
|
22.27
|
2.5
|
4.2
|
5.0
|
2.5
|
56.6
|
1.55
|
23.08
|
# PCA
dat2.pca <- PCA(dat2, scale.unit = TRUE, graph = FALSE)
Generaremos la variable grupal con kmeans
y la anexaremos a los datos originales.
# Crear 3 clúster (centers = 3)
set.seed(123)
res2.km <- kmeans(dat2, centers = 3, nstart = 25)
# Extraer etiquetas de los clúster
cluster_labels <- res2.km$cluster
# Añadir etiquetas de los clúster a los datos originales
dat1$Cluster <- cluster_labels
gr <- as.factor(dat1$Cluster)
gr_name <- "Clusters"
ind
(elipses de concentración)
En el código R (que se muestra abajo), los argumentos habillage
o col.ind se puede
n utilizar para especificar la variable de factor para colorear a los individuos por grupos. Para agregar una elipse de concentración alrededor de cada grupo, especifique el argumento addEllipses = TRUE
. El argumento pallete
se puede utilizar para cambiar los colores de los grupos.
fviz_pca_ind(dat2.pca,
geom.ind = "point", # mostrar solo puntos (no "texto")
col.ind = gr , # color por grupos
palette = c("blue", "brown", "green", "yellow", "pink"),
addEllipses = TRUE, # concentración de elipses
legend.title = gr_name
)

ind
(elipses de confianza)
Para eliminar el punto medio del grupo, especifique el argumento mean.point = FALSE
. Si desea elipses de confianza en lugar de elipses de concentración, utilice ellipse.type = "confidence"
.
# Añadir elipses de confianza
fviz_pca_ind(dat2.pca,
geom.ind = "point",
col.ind = gr,
palette = c("blue", "brown", "green"),
addEllipses = TRUE,
ellipse.type = "confidence",
legend.title = gr_name
)

ind
(elipses: más paletas de colores)
Téngase en cuenta que los valores permitidos para la paleta incluyen:
"grey"
para paletas de colores grises;
Paletas brewer como "RdBu"
, "Blues"
, …; Para ver todas, escriba esto en R: RColorBrewer::display.brewer.all()
.
Paleta de colores personalizada, por ejemplo c("blue", "red")
;
Ppaletas de revistas científicas del paquete ggsci
. Por ejemplo: "npg"
, "aaas"
, "lancet"
, "jco"
, "ucscgb"
, "uchicago"
, "simpsons"
y "rickandmorty"
.
Por ejemplo, con la paleta simpsons
:
fviz_pca_ind(dat2.pca,
label = "none", # Ocultar las etiquetas delos individuos
col.ind = gr, # Color por grupos
addEllipses = TRUE, # Elipses de concentración
palette = "simpsons",
legend.title = gr_name
)

Ejemplo: Solución (personalizar gráficos)
Dimensiones (axes
)
Por defecto, las variables/individuos se representan en las dimensiones 1 y 2. Si se desea visualizarlos en las dimensiones 2 y 3, por ejemplo, se debe especificar el argumento axes = c(2, 3)
.
# Variables sobre las dimensiones 2 y 3
fviz_pca_var(res.pca,
axes = c(2, 3),
col.var = "red",
repel=TRUE)

# Individuos sobre las dimensiones 2 y 3
fviz_pca_ind(res.pca,
axes = c(2, 3),
col.ind = "darkblue",
repel=TRUE)

Graficar elementos (geom
)
1. Argumento geom
:
El argumento geom
(por geometría) y sus derivados se utilizan para especificar los elementos geométricos o elementos gráficos a utilizar en la representación gráfica.
2. Argumento geom.var
:
Es un texto que especifica la geometría a utilizar para representar las variables. Los valores permitidos son la combinación de c(“point”, “arrow”, “text”)
:
Se usa geom.var = “point”
para mostrar solo puntos.
Se usa geom.var = “text”
para mostrar solo etiquetas de texto.
Se usa geom.var = c(“point”, “text”)
para mostrar tanto puntos como etiquetas de texto.
Se usa geom.var = c(“arrow”, “text”)
para mostrar flechas y etiquetas (predeterminado).
# Mostrar tanto puntos como etiquetas de texto
fviz_pca_var(res.pca,
geom.var = c("point", "text"),
col.var = "red",
repel=TRUE
)

3. Argumento geom.ind
:
Es un texto que especifica la geometría a utilizar para trazar los individuos. Los valores permitidos son la combinación de c("point", "text").
Se usa geom.ind = "point"
para mostrar solo puntos.
Se usa geom.ind = "text"
para mostrar solo etiquetas de texto.
Se usa geom.ind = c("point", "text")
para mostrar tanto puntos como etiquetas de texto (por defecto).
# Mostrar sólo etiquetas de texto individuales
fviz_pca_ind(res.pca,
geom.ind = "text",
col.ind= "darkblue",
repel=TRUE)
Elipses (addEllipses
)
Como describimos en secciones anteriores, al colorear individuos por grupos, se puede agregar elipses de concentración de puntos usando el argumento addEllipses = TRUE
. Obsérvese que el argumento ellipse.type
se puede utilizar para cambiar el tipo de elipses. Los valores posibles son:
"convex"
: traza la envolvente convexa de un conjunto de puntos.
"confidence"
: traza elipses de confianza alrededor de los puntos medios del grupo como la función coord.ellipse
en el paquete FactoMineR
.
"t"
: asume una distribución \(t\)-multivariada.
"norm"
: asume una distribución normal-multivariada.
“euclid”
: dibuja un círculo con el radio igual al nivel, representando la distancia euclidiana desde el centro. Esta elipse probablemente no aparecerá circular a menos que se aplique coord_fixed
.
El argumento ellipse.level
también está disponible para cambiar el tamaño de la elipse de concentración en la probabilidad normal. Por ejemplo, puede especificar ellipse.level = 0.95
o ellipse.level = 0.66
.
# Elipses de confianza
fviz_pca_ind(dat2.pca,
geom.ind = "point",
col.ind = gr, # Color por grupos
palette = c("blue", "brown", "green"),
addEllipses = TRUE,
ellipse.type = "confidence",
legend.title = gr_name
)

# Envolvente convexa
fviz_pca_ind(dat2.pca,
geom.ind = "point",
col.ind = gr, # Color por grupos
palette = c("blue", "brown", "green"),
addEllipses = TRUE,
ellipse.type = "convex",
legend.title = gr_name
)

Puntos medios por grupo (mean.point
)
Cuando se colorean individuos por grupos (ver secciones anteriores), los puntos medios de los grupos (baricentros) también se muestran de forma predeterminada. Para eliminar los puntos medios, se puede utilizar el argumento mean.point = FALSE
.
fviz_pca_ind(dat2.pca,
geom.ind = "point", # Muestra solo puntos (pero no "texto")
col.ind = gr, # Color por grupos
palette = c("blue", "brown", "green", "yellow", "pink"),
legend.title = gr_name,
mean.point = FALSE
)

Tipo de línea (axes.linetype
)
El argumento axes.linetype
se puede utilizar para especificar el tipo de línea de los ejes. El valor predeterminado es "dashed"
(rayado). Los valores permitidos incluyen "blank"
(en blanco), "solid"
(sólido), "dotted" (punteado)
, etc. Para ver todos los valores posibles, escriba ggpubr::show_line_types
. Para eliminar las líneas de los ejes, utilice axes.linetype = "blank"
:
fviz_pca_var(res.pca,
axes.linetype = "blank",
col.var="red",
repel=TRUE)

Apariencia gráfica (ggpar
)
Para cambiar fácilmente la apariencia gráfica de cualquier ggplot, puede utilizar la función ggpar
del paquete ggpubr
. Los parámetros gráficos que se pueden cambiar usando ggpar
incluyen:
Títulos principales, etiquetas de ejes y títulos de leyenda.
Posición de la leyenda. Valores posibles: "top"
(arriba), "bottom"
(abajo), "left"
(izquierda), "right
” (derecha), "none"
(ninguno).
Paleta de colores.
Temas. Los valores permitidos incluyen: theme_gray
, theme_bw
, theme_minimal
, theme_classic
, theme_void
.
ind.p <- fviz_pca_ind(dat2.pca,
geom = "point",
col.ind = gr
)
ggpubr::ggpar(ind.p,
title = "Principal Component Analysis",
subtitle = "Survey data set",
caption = "Source: factoextra",
xlab = "PC1",
ylab = "PC2",
legend.title = gr_name,
legend.position = "top",
ggtheme = theme_gray(),
palette = "jco"
)

Ejercicios
Ejercicio 1
Supongamos que se tienen 6 observaciones \(x_1, \ldots, x_6\) en dos dimensiones, cada observación corresponde
a un rectángulo y las variables son longitud de la base y la altura del rectángulo (véase la figura 13.1).
La matriz de datos es:
\[X\; =\; \begin{pmatrix}
2.0 & 2.0\\
1.5& 0.5 \\
0.7 & 0.5\\
0.5 & 1.5\\
0.5& 0.7\\
0.7 & 0.7
\end{pmatrix}\]
Con estos datos, halle:
La matriz \(Y= \log (X)\) (logaritmo con base 10). Es decir, aplique el logaritmo teniendo en cuenta cada una de las componentes y defina la matriz resultante como \(Y\).
La matriz \(S\) de varianzas-covarianzas de \(Y\).
Los valores \(\lambda_i\) y vectores \(v_i\) propios de \(S\).
Las dos componentes \(F_1\) y \(F_2\) evaluadas en los seis rectángulos. Recuerde que cada componente \(F_i\) será un vector de la misma longitud de \(Y_i\) y se calculará así:
\[F_i \;= \; Y v_i\]
Ejercicio 2
Las cuatro notas parciales de un determinado curso en una prestigiosa universidad se muestran en la tabla de abajo, en el orden
alfabético por apellidos de los estudiantes. El objetivo es saber si existe algún tipo de ordenación de los estudiantes de este grupo, distinto al de promediar las notas de estos estudiantes. Aplique PCA para determinar esto.
Sugerencia:
Halle los valores de las componentes principales para las notas de los 33 estudiantes.
Ordene en forma descendente estos resultados por la primera componente principal.
Compare estos resultados con los obtenidos en la nota definitiva.
id = 1:33
P1 = c(2.30, 3.50, 4.10, 5.00, 2.70, 2.70, 2.90, 2.40, 3.20, 3.80, 4.90, 4.50, 2.70, 2.90, 2.70, 2.70, 2.90, 3.00, 3.10, 3.50, 3.50, 2.70, 2.90, 3.00, 2.70, 3.50, 5.00, 4.90, 3.60, 3.00, 3.10, 4.70, 3.00)
P2 = c(3.40, 3.30, 4.10, 3.00, 2.50, 3.20, 2.80, 2.80, 3.20, 2.80, 4.80, 2.80, 2.80, 2.80, 2.80, 2.60, 3.30, 2.80, 2.80, 2.90, 2.60, 2.80, 2.80, 2.90, 3.40, 3.00, 3.50, 3.20, 2.90, 2.80, 2.80, 5.00, 2.90)
P3 = c(2.90, 3.50, 4.50, 4.00, 2.70, 4.40, 2.80, 2.50, 2.00, 3.00, 5.00, 4.50, 2.50, 2.80, 2.80, 2.60, 3.00, 2.80, 2.80, 3.50, 4.30, 2.00, 2.50, 2.50, 2.00, 4.00, 4.90, 2.80, 2.00, 3.90, 2.00, 3.80, 3.30)
P4 = c(3.30, 3.00, 3.70, 3.00, 3.00, 3.30, 3.50, 3.50, 3.90, 3.50, 3.00, 3.00, 2.90, 3.50, 3.00, 2.80, 2.80, 3.40, 3.30, 3.50, 3.50, 3.60, 3.00, 2.80, 3.00, 3.00, 3.00, 3.50, 4.00, 3.50, 3.60, 3.00, 2.80)
Def = c(2.98, 3.33, 4.10, 3.75, 2.73, 3.40, 3.00, 2.80, 3.08, 3.28, 4.43, 3.70, 2.73, 3.00, 2.83, 2.68, 3.00, 3.00, 3.00, 3.35, 3.48, 2.78, 2.80, 2.80, 2.78, 3.38, 4.10, 3.60, 3.13, 3.30, 2.98, 4.13, 3.00)
datos <- data.frame(id, P1, P2, P3, P4, Def)
print(datos)
## id P1 P2 P3 P4 Def
## 1 1 2.3 3.4 2.9 3.3 2.98
## 2 2 3.5 3.3 3.5 3.0 3.33
## 3 3 4.1 4.1 4.5 3.7 4.10
## 4 4 5.0 3.0 4.0 3.0 3.75
## 5 5 2.7 2.5 2.7 3.0 2.73
## 6 6 2.7 3.2 4.4 3.3 3.40
## 7 7 2.9 2.8 2.8 3.5 3.00
## 8 8 2.4 2.8 2.5 3.5 2.80
## 9 9 3.2 3.2 2.0 3.9 3.08
## 10 10 3.8 2.8 3.0 3.5 3.28
## 11 11 4.9 4.8 5.0 3.0 4.43
## 12 12 4.5 2.8 4.5 3.0 3.70
## 13 13 2.7 2.8 2.5 2.9 2.73
## 14 14 2.9 2.8 2.8 3.5 3.00
## 15 15 2.7 2.8 2.8 3.0 2.83
## 16 16 2.7 2.6 2.6 2.8 2.68
## 17 17 2.9 3.3 3.0 2.8 3.00
## 18 18 3.0 2.8 2.8 3.4 3.00
## 19 19 3.1 2.8 2.8 3.3 3.00
## 20 20 3.5 2.9 3.5 3.5 3.35
## 21 21 3.5 2.6 4.3 3.5 3.48
## 22 22 2.7 2.8 2.0 3.6 2.78
## 23 23 2.9 2.8 2.5 3.0 2.80
## 24 24 3.0 2.9 2.5 2.8 2.80
## 25 25 2.7 3.4 2.0 3.0 2.78
## 26 26 3.5 3.0 4.0 3.0 3.38
## 27 27 5.0 3.5 4.9 3.0 4.10
## 28 28 4.9 3.2 2.8 3.5 3.60
## 29 29 3.6 2.9 2.0 4.0 3.13
## 30 30 3.0 2.8 3.9 3.5 3.30
## 31 31 3.1 2.8 2.0 3.6 2.98
## 32 32 4.7 5.0 3.8 3.0 4.13
## 33 33 3.0 2.9 3.3 2.8 3.00
Ejercicio 3
Considere la recomendación de inversión que aparecen en la tabla de la figura 13.2. Cada empresa de gestión financiera tiene un conjunto de porcentajes recomendados en cada uno de los ocho tipos de inversión diferentes.
Estos suman 100%, por lo que el objetivo del ejerccio es encontrar un resumen de datos de menor dimensión que represente dicha información.
# Crear el data frame con los datos proporcionados
Manager = c("Alliance Bernstein", "Atlantic Trust", "Bank of America", "BNY Mellon", "Bessemer", "Brown Advisory", "Citi Private Bank", "Constellation", "Deutsche Bank", "Fidelity", "Fiduciary Trust", "Fifth Third Bank","GenSpring", "Glenmede", "Harris Private Bank", "Highmount Capital", "Janney Montgomery", "JPMorgan", "Legg Mason", "Northern Trust", "PNC Asset Mgmt", "Charles Schwab", "SunTrust","UBS", "US Bank", "Wells Fargo", "Wilmington Trust")
S_US = c(45, 28, 53, 26, 19, 29, 18, 20, 29, 40, 40, 28, 13, 35, 54, 25, 47, 20, 55, 24, 40, 29, 26, 32, 43, 27, 27)
S_Non_US = c(3, 6, 9, 9, 9, 13, 27, 10, 14, 14, 10, 9, 8, 12, 10, 5, 4, 9, 3, 8, 8, 20, 6, 10, 16, 13, 11)
S_Dev = c(17, 9, 3, 10, 3, 12, 3, 10, 6, 4, 13, 7, 5, 5, 4, 10, 4, 5, 7, 5, 2, 5, 5, 7, 7, 5, 4)
B_US = c(35, 30, 28, 30, 20, 19, 18, 25, 29, 35, 31, 36, 18, 18, 18, 40, 26, 22, 17, 31, 30, 29, 25, 27, 21, 21, 31)
B_Non_US = c(0, 3, 1, 0, 4, 3, 16, 5, 2, 2, 0, 0, 8, 2, 0, 5, 4, 3, 0, 0, 0, 1, 7, 6, 3, 4, 1)
B_Dev = c(0, 0, 1, 0, 5, 0, 1, 0, 4, 0, 0, 0, 0, 3, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0)
Alternative = c(0, 24, 0, 25, 34, 20, 17, 30, 17, 6, 5, 15, 45, 23, 15, 15, 10, 38, 15, 32, 20, 11, 30, 17, 10, 28, 27)
Cash = c(0, 0, 5, 0, 6, 4, 0, 0, 2, 0, 2, 5, 5, 2, 0, 0, 0, 3, 3, 0, 0, 5, 3, 2, 0, 0, 0)
# Crear el data frame
invest <- data.frame(Manager, S_US, S_Non_US, S_Dev, B_US, B_Non_US, B_Dev, Alternative, Cash)
Ejercicio 4
Considere nuevamente los datos del ejercicio anterior.
Haga un biplot de las dos primeras componentes principales de recomendaciones de inversión. Observe que Legg Mason (LM) y
Harris (HPB) aparecen en la parte superior y Highmount (HC) en la inferior abajo (por lo menos a mí me aparece así). ¿A qué se debe? ¿Qué representa el segundo componente principal el eje vertical?
Halle los valores propios y los vectores propios de la matriz de correlación de los datos de recomendación de inversión.
Muestre que los vectores propios representan las varianzas de los componentes componentes principales de la matriz de correlaciones y verifique que son iguales a los valores obtenidos de los componentes principales.
Ejercicio 5
Los siguientes datos describen el rendimiento de los atletas durante dos eventos deportivos (Desctar y OlympicG). Contiene 27 individuos (atletas) descritos mediante 13 variables. Se resalta que sólo algunos de estos individuos y variables se utilizarán para realizar el análisis de componentes principales.
datos <- factoextra::decathlon2
attach(datos)
dat <- datos[1:23, 1:10]
Con estos datos llevar a cabo un PCA.
Comience examinando las desviaciones estándar de cada variable.
Realice un análisis de componentes principales de estos datos y observe el biplot. Interprete las cargas de los dos primeros componentes principales. ¿Están fuertemente ponderados hacia las mayores desviaciones estándar encontradas en la parte (a)?
Repita el análisis de componentes principales en la matriz de correlación escalada de los datos. ¿Cómo interpreta este
biplot?
¿Qué análisis le parece más útil: el análisis de componentes principales escalado o sin escala para estos datos?
Ejercicio 6
Examine los datos de USJudgeRatings
en la librería datasets
. Este conjunto de datos contiene las valoraciones de 43 jueces de tribunales superiores de EE.UU. por parte de abogados. Cada uno de los jueces es evaluado en función de 12 atributos, como
atributos como la conducta, la preparación para el juicio, la solidez de las sentencias y el número de contactos que cada abogado tuvo con el juez. Consulte el archivo de ayuda de R
para más información sobre este conjunto de datos.
library(datasets)
head(USJudgeRatings)
## CONT INTG DMNR DILG CFMG DECI PREP FAMI ORAL WRIT PHYS RTEN
## AARONSON,L.H. 5.7 7.9 7.7 7.3 7.1 7.4 7.1 7.1 7.1 7.0 8.3 7.8
## ALEXANDER,J.M. 6.8 8.9 8.8 8.5 7.8 8.1 8.0 8.0 7.8 7.9 8.5 8.7
## ARMENTANO,A.J. 7.2 8.1 7.8 7.8 7.5 7.6 7.5 7.5 7.3 7.4 7.9 7.8
## BERDON,R.I. 6.8 8.8 8.5 8.8 8.3 8.5 8.7 8.7 8.4 8.5 8.8 8.7
## BRACKEN,J.J. 7.3 6.4 4.3 6.5 6.0 6.2 5.7 5.7 5.1 5.3 5.5 4.8
## BURNS,E.B. 6.2 8.8 8.7 8.5 7.9 8.0 8.1 8.0 8.0 8.0 8.6 8.6
- Examine el diagrama de dispersión por pares de estos datos (con el comando
pairs
) para revelar que algunas variables están muy correlacionadas.
pairs(USJudgeRatings)

- Realice un análisis de componentes principales para estos datos. Los dos primeros componentes de explican el 94% de la variabilidad. El segundo componente es casi totalmente el número de contactos, y el primer componente es esencialmente todas las demás variables, todas con el mismo peso. Interprete este resultado.
Ejercicio 7
Se administraron seis pruebas diferentes de inteligencia y capacidad a 112 personas. La matriz de covarianza (pero no los datos originales) de los resultados de las pruebas se encuentra en ability.cov
en la librería datasets
.
library(datasets)
ability.cov
## $cov
## general picture blocks maze reading vocab
## general 24.641 5.991 33.520 6.023 20.755 29.701
## picture 5.991 6.700 18.137 1.782 4.936 7.204
## blocks 33.520 18.137 149.831 19.424 31.430 50.753
## maze 6.023 1.782 19.424 12.711 4.757 9.075
## reading 20.755 4.936 31.430 4.757 52.604 66.762
## vocab 29.701 7.204 50.753 9.075 66.762 135.292
##
## $center
## [1] 0 0 0 0 0 0
##
## $n.obs
## [1] 112
Las seis pruebas se denominan: general
, picture
, blocks
, maze
(laberinto), reading
y vocabulary
. En el archivo de ayuda de R puede encontrar más información.
Realice un análisis de componentes principales utilizando la matriz de covarianza e identifique las variables que contribuyen en mayor medida a los dos primeros componentes principales. ¿Cómo interpreta estos componentes principales?
Convierta las covarianzas en matrices de correlación, con ayuda de la función cov2cor
.
ability.cor <- cov2cor(ability.cov$cov)
ability.cor
## general picture blocks maze reading vocab
## general 1.0000000 0.4662649 0.5516632 0.3403250 0.5764799 0.5144058
## picture 0.4662649 1.0000000 0.5724364 0.1930992 0.2629229 0.2392766
## blocks 0.5516632 0.5724364 1.0000000 0.4450901 0.3540252 0.3564715
## maze 0.3403250 0.1930992 0.4450901 1.0000000 0.1839645 0.2188370
## reading 0.5764799 0.2629229 0.3540252 0.1839645 1.0000000 0.7913779
## vocab 0.5144058 0.2392766 0.3564715 0.2188370 0.7913779 1.0000000
Realice un análisis de componentes principales utilizando la matriz de correlaciones. Examine las cargas e interprete los dos primeros componentes principales. Compare este resumen de datos con las partes (a) y (b). ¿En qué se diferencian? difieren? ¿En qué se parecen?
¿Cree que es más apropiado examinar la covarianza o la correlación en un análisis de componentes principales de estos datos?
LS0tDQp0aXRsZTogIkFOw4FMSVNJUyBERSBDT01QT05FTlRFUyBQUklOQ0lQQUxFUyINCnN1YnRpdGxlOiA8aDE+KipBcGxpY2FjacOzbioqPC9oMT4NCg0KYXV0aG9yOiANCiAgLSBuYW1lICAgICAgICAgIDogIkRyLiByZXIuIG5hdC4gSHVtYmVydG8gTExpbsOhcyBTb2xhbm8iDQogICAgYWZmaWxpYXRpb24gICA6ICJEZXBhcnRhbWVudG8gZGUgTWF0ZW3DoXRpY2FzIHkgRXN0YWTDrXN0aWNhLCBVbml2ZXJzaWRhZCBkZWwgTm9ydGUgKEJhcnJhbnF1aWxsYSwgQ29sb21iaWEpIg0KICAgICAjY29ycmVzcG9uZGluZyA6IHllcyAgICAjIERlZmluZSBvbmx5IG9uZSBjb3JyZXNwb25kaW5nIGF1dGhvcg0KICAgICAjYWRkcmVzcyAgICAgICA6ICJEZXBhcnRhbWVudG8gZGUgTWF0ZW3DoXRpY2FzIHkgRXN0YWTDrXN0aWNhIg0KICAgIGVtYWlsICAgICAgICAgOiB8DQogICAgICBobGxpbmFzQHVuaW5vcnRlLmVkdS5jbw0KICAgICAgDQogICAgICBbQmlvZ3JhcGhpY2FsIHNrZXRjaF0oaHR0cHM6Ly9ycHVicy5jb20vaGxsaW5hcy9CaW9fU2tldGNoKQ0KICAgICAgDQogICAgICBgciBmb3JtYXQoU3lzLnRpbWUoKSwgIiVkLyVtLyV5IilgIA0KICAgICAgDQogICAgICNyb2xlOiAgICAgICAgICMgQ29udHJpYnV0b3JzaGlwIHJvbGVzIChlLmcuLCBDUmVkaVQsIGh0dHBzOi8vY2FzcmFpLm9yZy9jcmVkaXQvKQ0KICAjICAgIC0gQ29uY2VwdHVhbGl6YXRpb24NCiAgIyAgICAtIFdyaXRpbmcgLSBPcmlnaW5hbCBEcmFmdCBQcmVwYXJhdGlvbg0KICAjICAgIC0gV3JpdGluZyAtIFJldmlldyAmIEVkaXRpbmcNCiAjIC0gbmFtZSAgICAgICAgICA6ICJBdXRvciBudW1lcm8gMiINCiAjICAgYWZmaWxpYXRpb24gICA6ICIxLDIiDQogIyAgIHJvbGU6DQogIyAgICAgLSBXcml0aW5nIC0gUmV2aWV3ICYgRWRpdGluZw0KICAgICAjYWZmaWxpYXRpb246DQogICMtIGlkICAgICAgICAgICAgOiAiMSINCiAgIyAgaW5zdGl0dXRpb24gICA6ICJVbml2ZXJzaWRhZCBkZWwgTm9ydGUgKEJhcnJhbnF1aWxsYSwgQ29sb21iaWEpIg0KICAjIVtdKGhsbGluYXMuanBnKXt3aWR0aD0xaW59IA0KICANCiNkYXRlOiAnYHIgZm9ybWF0KFN5cy50aW1lKCksICIlZC8lbS8leSIpYCcgICMgdmVyIGh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL3JtYXJrZG93bi1jb29rYm9vay91cGRhdGUtZGF0ZS5odG1sDQpvdXRwdXQ6IA0KICAgIGJvb2tkb3duOjpodG1sX2RvY3VtZW50MjogDQogICAgICAgICAgI09KTyBTYWxlbiBjYXBpdHVsb3MsIHNlY2Npb25lcyB5IFRlb3JlbWFzDQogICAgI2Jvb2tkb3duOjpodG1sX2Jvb2s6DQogICAgICAgICAgI09KTyBFUlJPUiBTYWxlbiB0ZW9yZW1hcywgcGVybyBubyBzYWxlbiBsb3MgY2FwaXR1bG9zIA0KICAgICNodG1sX2RvY3VtZW50Og0KICAgICAgICAgIHRvYzogdHJ1ZSAgICAgICMgdGFibGUgb2YgY29udGVudCB0cnVlDQogICAgICAgICAgdG9jX2RlcHRoOiA0ICAgIyB1cHRvIHRocmVlIGRlcHRocyBvZiBoZWFkaW5ncyAoc3BlY2lmaWVkIGJ5ICMsICMjIGFuZCAjIyMpDQogICAgICAgICAgdG9jX2Zsb2F0OiB0cnVlICNDb24gdHJ1ZSwgdG9jIHNhbGUgYWwgbWFyZ2VuIGl6cXVpZXJkbyBkZSBsYSBww6FnaW5hOyBkZSBsbyBjb250cmFyaW8sIGFycmliYQ0KICAgICAgICAgIGNvbGxhcHNlZDogZmFsc2UNCiAgICAgICAgICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQ0KICAgICAgICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZSAgICMgaWYgeW91IHdhbnQgbnVtYmVyIHNlY3Rpb25zIGF0IGVhY2ggdGFibGUgaGVhZGVyDQogICAgICAgICAgI3RoZW1lOiBzYW5kc3RvbmUNCiAgICAgICAgICAjdGhlbWU6IHVuaXRlZCAgIyBtYW55IG9wdGlvbnMgZm9yIHRoZW1lLCB0aGlzIG9uZSBpcyBteSBmYXZvcml0ZS4NCiAgICAgICAgICAjdGhlbWU6IGZsYXRseSAgIyANCiAgICAgICAgICAjdGhlbWU6IGNlcnVsZWFuICAjIA0KICAgICAgICAgICNoaWdobGlnaHQ6IHRhbmdvICAjIHNwZWNpZmllcyB0aGUgc3ludGF4IGhpZ2hsaWdodGluZyBzdHlsZQ0KICAgICAgICAgICNjc3M6IFNjcmlwdHMgYWNjZXNvcmlvcy9lc3RpbG9ib3Rvbi5jc3MNCiAgICAgICAgICAjY3NzOiBteS5jc3MgICAjIHlvdSBjYW4gYWRkIHlvdXIgY3VzdG9tIGNzcywgc2hvdWxkIGJlIGluIHNhbWUgZm9sZGVyDQogICAgICAgICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgICAgICAgICNoaWdobGlnaHQ6IHRhbmdvICAjIGNhbWJpYXIgY29sb3IgZGUgbGlicmFyeSBlbiBhenVsDQogICAgIyBib29rZG93bjo6Z2l0Ym9vazoNCiAgICAjICAgICAgaW5jbHVkZXM6DQogICAgIyAgICAgICAgaW5faGVhZGVyOiBoZWFkZXIuaHRtbA0KICAgICMgYm9va2Rvd246OnBkZl9ib29rOg0KICAgICMgICAgICAga2VlcF90ZXg6IHllcw0KICAgICMgYm9va2Rvd246Omh0bWxfYm9vazoNCiAgICAjICAgICAgIGNzczogdG9jLmNzcw0KICAgICMgYm9va2Rvd246Omh0bWxfYm9vazoNCiAgICAjICAgICAgICAgaW5jbHVkZXM6DQogICAgIyAgICAgICAgICAgaW5faGVhZGVyOiBzdHlsZS5jc3MNCiAgICAjYm9va2Rvd246Omh0bWxfZG9jdW1lbnQyOiBkZWZhdWx0DQogICAgIyBib29rZG93bjo6cGRmX2RvY3VtZW50MjoNCiAgICAjICAgICAga2VlcF90ZXg6IHRydWUNCiAgICAjYmlibGlvZ3JhcGh5OiByZWZlcmVuY2VzLmJpYg0KICAgIG1hdGhqYXg6ICJodHRwOi8vZXhhbXBsZS5jb20vbWF0aGpheC9NYXRoSmF4LmpzP2NvbmZpZz1UZVgtQU1TLU1NTF9IVE1Mb3JNTUwiDQpoZWFkZXItaW5jbHVkZXM6DQogICAgXHVzZXBhY2thZ2VbeDExbmFtZXNde3hjb2xvcn0gDQogICAgDQpjc2w6IHNjaWVuY2UuY3NsDQojT2pvOiBTZSB1dGlsaXphIGxlbmd1YWplIFlBTUwNCg0KYWJzdHJhY3Q6IHwNCiAqKkVuIFtScHViczo6IHRvY10oaHR0cHM6Ly9ycHVicy5jb20vaGxsaW5hcy90b2MpIHNlIHB1ZWRlbiB2ZXIgb3Ryb3MgZG9jdW1lbnRvcyBkZSBwb3NpYmxlIGludGVyw6lzLioqDQogIA0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCBmaWcuYWxpZ249ImNlbnRlciIsICBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFIywNCiAgICAgICAgICAgICAgICAgICAgICAjc3R5bGUgPSAiY29sb3I6ZGFya2JsdWUiDQogICAgICAgICAgICAgICAgICAgICMgY2xhc3Muc291cmNlPSJiZy1kYW5nZXIiLCBjbGFzcy5vdXRwdXQ9ImJnLXdhcm5pbmciICAgI0NvbG9yZXMgZGVudHJvIGRlbCBjaHVuaw0KICAgICAgICAgICAgICAgICAgICAgKQ0KbGlicmFyeShyZ2wpDQprbml0cjo6a25pdF9ob29rcyRzZXQod2ViZ2wgPSBob29rX3dlYmdsKQ0KYGBgDQoNCg0KDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBldmFsPUZBTFNFfQ0KaHR0cHM6Ly9ib29rZG93bi5vcmcveWlodWkvcm1hcmtkb3duL2xhbmd1YWdlLWVuZ2luZXMuaHRtbA0KDQpodHRwczovL2Jvb2tkb3duLm9yZy95aWh1aS9ib29rZG93bi9tYXJrZG93bi1zeW50YXguaHRtbA0KDQpodHRwczovL2Jvb2tkb3duLm9yZy95aWh1aS9ib29rZG93bi9hLXNpbmdsZS1kb2N1bWVudC5odG1sDQoNCmh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL2Jvb2tkb3duL21hcmtkb3duLWV4dGVuc2lvbnMtYnktYm9va2Rvd24uaHRtbA0KDQpodHRwczovL2Jvb2tkb3duLm9yZy95aWh1aS9ybWFya2Rvd24vYm9va2Rvd24tbWFya2Rvd24uaHRtbCAgIyBUZW9yZW1zIGFuZCBwcm9vZnMNCg0KaHR0cHM6Ly9ib29rZG93bi5vcmcveWlodWkvYm9va2Rvd24vbWFya2Rvd24tZXh0ZW5zaW9ucy1ieS1ib29rZG93bi5odG1sI3RoZW9yZW1zDQoNCmh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL2Jvb2tkb3duL2h0bWwuaHRtbA0KDQpodHRwczovL3d3dy5kYXRhLXRvLXZpei5jb20vDQogIA0KW1JwdWJzXShsaW5rKQ0KICANCihcI2VxOmVjLSksICBFY3VhY2lvbiBcQHJlZihlcTplYy0pLCBGaWd1cmEgXEByZWYoZmlnOkZpZy0pLCBUYWJsZSBcQHJlZih0YWI6bXRjYXJzKSwgVGhlb3JlbSBcQHJlZih0aG06Ym9yaW5nKQ0KDQoNCiMgVGl0dWxvIHsjVGl0dWxvU2VjY2lvbn0gICBcQHJlZihUaXR1bG9TZWNjaW9uKQ0KICANCiMgRm9yIEhUTUwsIHdlIGNhbiBzZXQgY29sb3Igd2l0aCBDU1MsIGUuZy4sIDxzcGFuIHN0eWxlPSJjb2xvcjogcmVkOyI+dGV4dDwvc3Bhbj4NCiAgDQojIGh0dHBzOi8vcmFkaWFudC1yc3RhdHMuZ2l0aHViLmlvL2RvY3MvbW9kZWwvbG9naXN0aWMuaHRtbCBTaGlubnkgTG9naXQgIA0KICANCmBgYA0KDQpgYGB7ciwgZXZhbD1GQUxTRSwgZWNobz1GQUxTRX0NCiNMYSBmb3RvIHRhbWHDsW8gY8OpZHVsYQ0KDQpodG1sdG9vbHM6OmltZyhzcmMgPSBrbml0cjo6aW1hZ2VfdXJpKGZpbGUucGF0aChSLmhvbWUoImRvYyIpLCAiaHRtbCIsICJsb2dvLmpwZyIpKSwgDQogICAgICAgICAgICAgICBhbHQgPSAnaGxsaW5hcycsIA0KICAgICAgICAgICAgICAgc3R5bGUgPSAncG9zaXRpb246YWJzb2x1dGU7IHRvcDowOyByaWdodDowOyBwYWRkaW5nOjEwcHg7JyAjLA0KICAgICAgICAgICAgICAgd2lkdGggPSAiMjAwcHgiKSAgIyBBcXXDrSBlc3BlY2lmaWNhcyBlbCBhbmNobyBkZXNlYWRvIGVuIHDDrXhlbGVzIG8gcG9yY2VudGFqZQ0KYGBgDQoNCg0KDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCB9DQojIExhIGZvdG8gZ3JhbmRlDQoNCmh0bWx0b29sczo6aW1nKHNyYyA9IGtuaXRyOjppbWFnZV91cmkoImhsbGluYXMyMDIzLmpwZyIpLCANCiAgICAgICAgICAgICAgIGFsdCA9ICdobGxpbmFzMjAyMycsIA0KICAgICAgICAgICAgICAgc3R5bGUgPSAncG9zaXRpb246YWJzb2x1dGU7IHRvcDowOyByaWdodDowOyBwYWRkaW5nOjFweDsnLA0KICAgICAgICAgICAgICAgd2lkdGg9IjE1JSIpDQpgYGANCg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAgLS0+DQoNCmBgYHtjc3MsIGVjaG89RkFMU0V9DQouY29sdW1ucyB7ZGlzcGxheTogZmxleDt9DQpoMSB7Y29sb3I6IGRhcmtibHVlO30NCmgzIHtjb2xvcjogZGFya2dyZWVuO30NCmg0IHtjb2xvcjogZ3JlZW47fQ0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yICAtLT4NCg0KIyBMaWJyZXLDrWFzDQoNCiMjIyBQYXJhIFBDQQ0KDQoNCmBgYHtyLCBldmFsPUZBTFNFLCBlY2hvPUZBTFNFfQ0KIyAgaHR0cHM6Ly9ycHVicy5jb20vQWxlbWEvMTAwMDU4Mg0KDQojIGh0dHBzOi8vd3d3LmdlZWtzZm9yZ2Vla3Mub3JnL2NvbnRleHR1YWwtb3V0bGllcnMvDQpgYGANCg0KRWwgc29mdHdhcmUgUiBkaXNwb25lIGRlIHZhcmlhcyBmdW5jaW9uZXMgZGUgZGlmZXJlbnRlcyBwYXF1ZXRlcyBwYXJhIGNhbGN1bGFyIFBDQToNCg0KICAgLSBgcHJjb21wYCB5IGBwcmluY29tcGAsIGRlbCBwYXF1ZXRlIGBzdGF0c2AuDQogICAgICAgIA0KICAgLSBgUENBYCBkZWwgcGFxdWV0ZSBgRmFjdG9NaW5lUmAuDQogICAgDQogICAtIGBkdWRpLnBjYWAgZGVsIHBhcXVldGUgYGFkZTRgLg0KICAgIA0KICAgLSBgZXBQQ0FgIGRlbCBwYXF1ZXRlIGBFeFBvc2l0aW9uYC4NCiAgICAgICAgDQoNClNpbiBpbXBvcnRhciBsYSBmdW5jacOzbiBxdWUgZWxpamEgZW1wbGVhciwgZXMgcG9zaWJsZSBleHRyYWVyIHkgcmVwcmVzZW50YXIgZGUgbWFuZXJhIHNlbmNpbGxhIGxvcyByZXN1bHRhZG9zIGRlbCBQQ0EgbWVkaWFudGUgbGFzIGZ1bmNpb25lcyBkZWwgcGFxdWV0ZSBgZmFjdG9leHRyYWAuIEVuIGVzdGUgZG9jdW1lbnRvLCBzZSBoYXLDoSB1c28gZGUgbG9zIHBhcXVldGVzIGBGYWN0b01pbmVSYCB5IGBhZGU0YCAgcGFyYSBsb3MgYW7DoWxpc2lzIHkgYGZhY3RvZXh0cmFgIHBhcmEgbGEgdmlzdWFsaXphY2nDs24gYmFzYWRhIGVuIGBnZ3Bsb3QyYC4NCg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShGYWN0b01pbmVSKQ0KbGlicmFyeShmYWN0b2V4dHJhKQ0KbGlicmFyeShhZGU0KQ0KYGBgDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAgLS0+DQoNCiMjIyBQYXJhIG90cm9zIGFuw6FsaXNpcw0KDQpgYGB7ciwgIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0V9DQpsaWJyYXJ5KGFwbG9yZTMpICAgICAgICNCYXNlIGRlIGRhdG9zIHBhcmEgbG9zIGVqZW1wbG9zDQpsaWJyYXJ5KGxzbSkgICAgICAgICAgICNCYXNlIGRlIGRhdG9zIHBhcmEgZWplbXBsb3MgeSBlc3RpbWFjaW9uZXMgZGVsIExvZy12ZXJvc2ltaWxpdHVkDQpsaWJyYXJ5KGtuaXRyKSAgICAgICAgICNFZGl0YXIgdGFibGFzIGNvbiBrYWJsZSgpDQpsaWJyYXJ5KGthYmxlRXh0cmEpICAgICNFZGl0YXIgdGFibGFzIG3DoXMgZXN0aWxpemFkYXMNCmxpYnJhcnkodGlkeXZlcnNlKSAgICAgI0luY2x1eWUgYSBkcGx5ciB5IGdncGxvdDINCmxpYnJhcnkoc3RyaW5ncikgICAgICAgI1JlZW1wbGF6YXIgY2FyYWN0ZXJlcyBlbiB1biBkYXRhIGZyYW1lDQpsaWJyYXJ5KG91dGxpZXJzKSAgICAgICNvdXRsaWVyczo6Z3J1YmJzLnRlc3QNCmxpYnJhcnkoRW52U3RhdHMpICAgICAgI0VudlN0YXRzOjpyb3NuZXJUZXN0DQpsaWJyYXJ5KERNd1IyKSAgICAgICAgICNMT0YgKExvY2FsIE91dGxpZXIgRmFjdG9yKQ0KbGlicmFyeShyZ2wpICAgICAgICAgICAjcmdsOjpwbG90M2RgDQpsaWJyYXJ5KGNvcnJwbG90KSAgICAgICNNYXRyaXogZGUgY29ycmVsYWNpb25lcw0KbGlicmFyeSh0ZXh0c2hhcGUpICAgICAjY29sdW1uX3RvX3Jvd25hbWVzDQojb3B0c19rbml0JHNldChldmFsLmFmdGVyID0gJ2ZpZy5jYXAnKQ0KYGBgDQoNCmBgYHtjc3MsIGVjaG89RkFMU0UsIGV2YWw9RkFMU0V9DQojaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNDEwMzA0NzcvY2hhbmdpbmctY2h1bmstYmFja2dyb3VuZC1jb2xvci1pbi1ybWFya2Rvd24NCg0KLmJhZENvZGUgew0KYmFja2dyb3VuZC1jb2xvcjogcmVkOw0KfQ0KYGBgDQoNCmBgYHtyLCAgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZXZhbD1GQUxTRX0NCmxpYnJhcnkoYXBsb3JlMykgICAgICAgI0Jhc2UgZGUgZGF0b3MgcGFyYSBsb3MgZWplbXBsb3MNCmxpYnJhcnkobHNtKSAgICAgICAgICAgI0Jhc2UgZGUgZGF0b3MgcGFyYSBlamVtcGxvcyB5IGVzdGltYWNpb25lcyBkZWwgTG9nLXZlcm9zaW1pbGl0dWQNCmxpYnJhcnkodGlkeXZlcnNlKSAgICAgI0luY2x1eWUgYSBkcGx5ciB5IGdncGxvdDINCmxpYnJhcnkoc3RyaW5ncikgICAgICAgI1JlZW1wbGF6YXIgY2FyYWN0ZXJlcyBlbiB1biBkYXRhIGZyYW1lDQpsaWJyYXJ5KG91dGxpZXJzKSAgICAgICNvdXRsaWVyczo6Z3J1YmJzLnRlc3QNCmxpYnJhcnkoRW52U3RhdHMpICAgICAgI0VudlN0YXRzOjpyb3NuZXJUZXN0DQpsaWJyYXJ5KERNd1IyKSAgICAgICAgICNMT0YgKExvY2FsIE91dGxpZXIgRmFjdG9yKQ0KbGlicmFyeShyZ2wpICAgICAgICAgICAjcmdsOjpwbG90M2QNCmxpYnJhcnkoY29ycnBsb3QpICAgICAgI01hdHJpeiBkZSBjb3JyZWxhY2lvbmVzDQpsaWJyYXJ5KHRleHRzaGFwZSkgICAgICNjb2x1bW5fdG9fcm93bmFtZXMNCmBgYA0KDQoNCg0KDQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBFamVtcGxvOiBFbnVuY2lhZG8NCg0KYGBge3IsIGV2YWw9RkFMU0UsIGVjaG89RkFMU0V9DQpMb3MgZGF0b3MgdXRpbGl6YWRvcyBlbiBlc3RlIGVqZW1wbG8gZGVzY3JpYmVuIGVsIHJlbmRpbWllbnRvIGRlIGxvcyBhdGxldGFzIGR1cmFudGUgZG9zIGV2ZW50b3MgZGVwb3J0aXZvcyAoRGVzY3RhciB5IE9seW1waWNHKS4gQ29udGllbmUgMjcgaW5kaXZpZHVvcyAoYXRsZXRhcykgZGVzY3JpdG9zIG1lZGlhbnRlIDEzIHZhcmlhYmxlcy4gQ29uIGVzdG9zIGRhdG9zIGxsZXZhcmVtb3MgYSBjYWJvIHVuIFBDQS4gDQoNCg0KI2BgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZGF0b3NDb21wbGV0byA8LSBmYWN0b2V4dHJhOjpkZWNhdGhsb24yDQphdHRhY2goZGF0b3NDb21wbGV0bykNCiNgYGANCg0KDQojYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpuYW1lcyhkYXRvc0NvbXBsZXRvKQ0KI2BgYA0KDQpTZSByZXNhbHRhIHF1ZSBzw7NsbyBhbGd1bm9zIGRlIGVzdG9zIGluZGl2aWR1b3MgeSB2YXJpYWJsZXMgc2UgdXRpbGl6YXLDoW4gcGFyYSByZWFsaXphciBlbCBhbsOhbGlzaXMgZGUgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMuIA0KDQojYGBge3IgZXZhbD1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmRhdCA8LSBkYXRvc0NvbXBsZXRvWzE6MjMsIDE6MTBdDQphdHRhY2goZGF0KQ0KaGVhZChkYXQsNCkpIA0KI2BgYA0KDQojYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmRhdCA8LSBkYXRvc0NvbXBsZXRvWzE6MjMsIDE6MTBdDQphdHRhY2goZGF0KQ0Ka2FibGUoaGVhZChkYXQsNCksYWxpZ24gPSAiY2NjIikgJT4lIyBTZSBuZWNlc2l0YSBsaWJyYXJ5KGtuaXRyKSANCmthYmxlX3N0eWxpbmcoKSAlPiUgICAgICAgICAgICAgICAgI2xpYnJhcnkoa2FibGVFeHRyYSkuLi4uIFNvbG8gcGFyYSBrbml0IHRvIGh0bWwNCmthYmxlX2NsYXNzaWNfMihmdWxsX3dpZHRoID0gRikgICAjbGlicmFyeShrYWJsZUV4dHJhKS4uLi5Tb2xvIHBhcmEga25pdCB0byBodG1sDQojYGBgDQoNCg0KYGBgDQoNCg0KDQoNCg0KTG9zIGRhdG9zIHNlIHJlY29naWVyb24gYXBsaWNhbmRvIHVuYSBlbmN1ZXN0YSBhIHVuYSBtdWVzdHJhIGRlIGVzdHVkaWFudGVzIHVuaXZlcnNpdGFyaW9zLiBFcyB1biBkYXRhIGZyYW1lIGNvbiA4MDAgb2JzZXJ2YWNpb25lcyB5IDY2IHZhcmlhYmxlcy4gQ29uIGVzdG9zIGRhdG9zIGxsZXZhcmVtb3MgYSBjYWJvIHVuIFBDQS4gDQoNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpkYXRvc0NvbXBsZXRvIDwtIGxzbTo6c3VydmV5DQojZGF0b3NDb21wbGV0byA8LSB0ZXh0c2hhcGU6OmNvbHVtbl90b19yb3duYW1lcyhkYXQsIGxvYz0xKQ0KI2RhdG9zQ29tcGxldG8gJT4lIHJlbW92ZV9yb3duYW1lcyAlPiUgY29sdW1uX3RvX3Jvd25hbWVzKHZhcj0ibmFtZXMiKSAgICNsaWJyYXJ5KHRpZHl2ZXJzZSkNCmF0dGFjaChkYXRvc0NvbXBsZXRvKQ0KYGBgDQoNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpuYW1lcyhkYXRvc0NvbXBsZXRvKQ0KYGBgDQoNClNlIHJlc2FsdGEgcXVlIHPDs2xvIGFsZ3Vub3MgZGUgZXN0b3MgaW5kaXZpZHVvcyB5IHZhcmlhYmxlcyBzZSB1dGlsaXphcsOhbiBwYXJhIHJlYWxpemFyIGVsIGFuw6FsaXNpcyBkZSBjb21wb25lbnRlcyBwcmluY2lwYWxlcy4gDQoNCg0KYGBge3IgZXZhbD1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmRhdCA8LSBkYXRvc0NvbXBsZXRvWzE6MjMsIDIxOjMwXQ0KYXR0YWNoKGRhdCkNCmhlYWQoZGF0LDQpIA0KYGBgDQoNCg0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KI2RhdCA8LSBkYXRvc0NvbXBsZXRvWzE6MjMsIGMoNSw3LDgsOSwxMywxNSwyMSwyNywyOSwzMCldICMgcHJpbWVyIGludGVudG8NCmRhdCA8LSBkYXRvc0NvbXBsZXRvWzE6MjMsIDIxOjMwXQ0KYXR0YWNoKGRhdCkNCmthYmxlKGhlYWQoZGF0LDQpLGFsaWduID0gImNjYyIpICU+JSMgU2UgbmVjZXNpdGEgbGlicmFyeShrbml0cikgDQprYWJsZV9zdHlsaW5nKCkgJT4lICAgICAgICAgICAgICAgICNsaWJyYXJ5KGthYmxlRXh0cmEpLi4uLiBTb2xvIHBhcmEga25pdCB0byBodG1sDQprYWJsZV9jbGFzc2ljXzIoZnVsbF93aWR0aCA9IEYpICAgI2xpYnJhcnkoa2FibGVFeHRyYSkuLi4uU29sbyBwYXJhIGtuaXQgdG8gaHRtbA0KYGBgDQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBFamVtcGxvOiBTb2x1Y2nDs24gKGBmYWN0b01pbmVSOjpQQ0FgKQ0KDQojIyMgRGVzY3JpcGNpw7NuIGRlIGxhIGZ1bmNpw7NuIGBmYWN0b01pbmVSOjpQQ0FgDQoNClVzYXJlbW9zIGxhIGZ1bmNpw7NuIGBQQ0FgIGRlbCBwYXF1ZXRlIGBGYWN0b01pbmVSYC4gVW4gZm9ybWF0byBzaW1wbGUgZXM6IA0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NClBDQShYLCBzY2FsZS51bml0ID0gVFJVRSwgbmNwID0gNSwgZ3JhcGggPSBUUlVFKQ0KYGBgDQoNCkFxdcOtOiANCiAgDQogICsgYFhgOiBlcyB1biBkYXRhIGZyYW1lLiBMYXMgZmlsYXMgc29uIGluZGl2aWR1b3MgeSBsYXMgY29sdW1uYXMgc29uIHZhcmlhYmxlcyBudW3DqXJpY2FzLg0KICANCiAgKyBgc2NhbGUudW5pdGA6IHVuIHZhbG9yIGzDs2dpY28uIFNpIGVzIGBUUlVFYCwgbG9zIGRhdG9zIHNlIGVzY2FsYW4gYSBsYSB2YXJpYW56YSB1bml0YXJpYSBhbnRlcyBkZWwgYW7DoWxpc2lzLiBFc3RhIGVzdGFuZGFyaXphY2nDs24gYSBsYSBtaXNtYSBlc2NhbGEgZXZpdGEgcXVlIGFsZ3VuYXMgdmFyaWFibGVzc2UgdnVlbHZhbiBkb21pbmFudGVzIHPDs2xvIHBvciBzdXMgZ3JhbmRlcyB1bmlkYWRlcyBkZSBtZWRpZGEuIEhhY2UgdmFyaWFibGVzIGNvbXBhcmFibGVzLg0KICANCiAgKyBgbmNwYDogbsO6bWVybyBkZSBkaW1lbnNpb25lcyBjb25zZXJ2YWRhcyBlbiBsb3MgcmVzdWx0YWRvcyBmaW5hbGVzLg0KICANCiAgKyBgZ3JhcGhgOiB2YWxvciBsw7NnaWNvLiBTaSBlcyBgVFJVRWAgc2UgbXVlc3RyYSB1biBncsOhZmljby4NCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIEFwbGljYWNpw7NuIGRlIGxhIGZ1bmNpw7NuIGBmYWN0b01pbmVSOjpQQ0FgDQoNCkVsIGPDs2RpZ28gUiBzaWd1aWVudGUsIGNhbGN1bGEgZWwgYW7DoWxpc2lzIGRlIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzIGVuIGxvcyBpbmRpdmlkdW9zIGFjdGl2b3MvdmFyaWFibGVzOg0KDQpgYGB7cn0NCiNsaWJyYXJ5KEZhY3RvTWluZVIpDQpyZXMucGNhIDwtIFBDQShkYXQsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEZBTFNFKQ0KcmVzLnBjYQ0KYGBgDQoNCkVsIHJlc3VsdGFkbyBvYnRlbmlkbyBhbCB1dGlsaXphciBsYSBmdW5jacOzbiBgUENBYCBhbG1hY2VuYSB1bmEgZ3JhbiBjYW50aWRhZCBkZSBpbmZvcm1hY2nDs24gZGlzdHJpYnVpZGEgZW4gdmFyaWFzIGxpc3RhcyB5IG1hdHJpY2VzIGRpc3RpbnRhcy4gRXN0b3MgZGF0b3Mgc2UgZGV0YWxsYW4gbcOhcyBhZGVsYW50ZS4NCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBFamVtcGxvOiBTb2x1Y2nDs24gKGBmYWN0b2V4dHJhYCkNCg0KIyMjIFZpc3VhbGl6YWNpw7NuIGUgaW50ZXJwcmV0YWNpw7NuDQoNClV0aWxpemFyZW1vcyBlbCBwYXF1ZXRlIGBmYWN0b2V4dHJhYCBwYXJhIGZhY2lsaXRhciBsYSBpbnRlcnByZXRhY2nDs24gZGVsIEFuw6FsaXNpcyBkZSBDb21wb25lbnRlcyBQcmluY2lwYWxlcyAoQUNQKS4gSW5kZXBlbmRpZW50ZW1lbnRlIGRlIGxhIGZ1bmNpw7NuIHF1ZSBlbGlqYSB1dGlsaXphciwgeWEgc2VhIGBzdGF0czo6cHJjb21wYCwgYEZhY3RvTWluZXI6OlBDQWAsIGBhZGU0OjpkdWRpLnBjYWAgIG8gYEV4UG9zaXRpb246OmVwUENBYCwgc2UgcG9kcsOhIGV4dHJhZXIgeSB2aXN1YWxpemFyIGxvcyByZXN1bHRhZG9zIGRlbCBBQ1AgZGUgbWFuZXJhIHNlbmNpbGxhIHV0aWxpemFuZG8gbGFzIGZ1bmNpb25lcyBpbmNsdWlkYXMgZW4gZWwgcGFxdWV0ZSBgZmFjdG9leHRyYWAuDQoNCkVzdGFzIGZ1bmNpb25lcyBhYmFyY2FuOg0KICANCiAgKyBgZ2V0X2VpZ2VudmFsdWUocmVzLnBjYSlgOiBQZXJtaXRlIGV4dHJhZXIgbG9zIHZhbG9yZXMgcHJvcGlvcyBvIGxhcyB2YXJpYW56YXMgZGUgbG9zIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzLg0KICANCiAgKyBgZnZpel9laWcocmVzLnBjYSlgOiBGYWNpbGl0YSBsYSB2aXN1YWxpemFjacOzbiBkZSBsb3MgdmFsb3JlcyBwcm9waW9zLg0KICANCiAgKyBgZ2V0X3BjYV9pbmQocmVzLnBjYSlgLCBgZ2V0X3BjYV92YXIocmVzLnBjYSlgOiBFeHRyYWVuIGxvcyByZXN1bHRhZG9zIHBhcmEgaW5kaXZpZHVvcyB5IHZhcmlhYmxlcywgcmVzcGVjdGl2YW1lbnRlLg0KICANCiAgKyBgZnZpel9wY2FfaW5kKHJlcy5wY2EpYCwgYGZ2aXpfcGNhX3ZhcihyZXMucGNhKWA6IEZhY2lsaXRhbiBsYSB2aXN1YWxpemFjacOzbiBkZSBsb3MgcmVzdWx0YWRvcyBwYXJhIGluZGl2aWR1b3MgeSB2YXJpYWJsZXMsIHJlc3BlY3RpdmFtZW50ZS4NCiAgDQogICsgYGZ2aXpfcGNhX2JpcGxvdChyZXMucGNhKWA6IEdlbmVyYSB1biBiaXBsb3QgZGUgaW5kaXZpZHVvcyB5IHZhcmlhYmxlcy4NCg0KTcOhcyBhZGVsYW50ZSwgc2UgaWx1c3RyYXLDoW4gY2FkYSB1bmEgZGUgZXN0YXMgZnVuY2lvbmVzLg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgRWlnZW52YWxvcmVzIC8gVmFyaWFuemFzDQoNCkNvbW8gaGVtb3MgZXhwbGljYWRvIGVuIHNlY2Npb25lcyBwcmV2aWFzLCBsb3MgdmFsb3JlcyBwcm9waW9zIGN1YW50aWZpY2FuIGxhIGNhbnRpZGFkIGRlIHZhcmlhY2nDs24gcHJlc2VydmFkYSBwb3IgY2FkYSBjb21wb25lbnRlIHByaW5jaXBhbC4gTG9zIHZhbG9yZXMgcHJvcGlvcyB0aWVuZGVuIGEgc2VyIG3DoXMgYWx0b3MgcGFyYSBsb3MgcHJpbWVyb3MgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMgeSBkaXNtaW51eWVuIHBhcmEgbG9zIHNpZ3VpZW50ZXMuIEVuIG90cmFzIHBhbGFicmFzLCBsb3MgcHJpbWVyb3MgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMgcmVwcmVzZW50YW4gbGFzIGRpcmVjY2lvbmVzIGNvbiBsYSBtYXlvciB2YXJpYWJpbGlkYWQgZW4gZWwgY29uanVudG8gZGUgZGF0b3MuIEFuYWxpemFtb3MgbG9zIHZhbG9yZXMgcHJvcGlvcyBwYXJhIGRldGVybWluYXIgY3XDoW50b3MgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMgZGViZW4gY29uc2lkZXJhcnNlLiBFc3RvcyB2YWxvcmVzIHByb3Bpb3MsIGp1bnRvIGNvbiBsYSBwcm9wb3JjacOzbiBkZSB2YXJpYW56YSAoZXMgZGVjaXIsIGxhIGluZm9ybWFjacOzbikgY29uc2VydmFkYSBwb3IgbG9zIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzIChQQyksIHB1ZWRlbiBzZXIgb2J0ZW5pZG9zIHV0aWxpemFuZG8gbGEgZnVuY2nDs24gYGdldF9laWdlbnZhbHVlYCBkZWwgcGFxdWV0ZSBgZmFjdG9leHRyYWAuDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGV2YWw9RkFMU0V9DQojbGlicmFyeShmYWN0b2V4dHJhKQ0KZWlnLnZhbCA8LSBnZXRfZWlnZW52YWx1ZShyZXMucGNhKQ0KZWlnLnZhbA0KYGBgDQoNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRX0NCiNsaWJyYXJ5KGZhY3RvZXh0cmEpDQplaWcudmFsIDwtIGdldF9laWdlbnZhbHVlKHJlcy5wY2EpDQoNCmthYmxlKGVpZy52YWwsIGFsaWduID0gImNjYyIpICU+JSMgU2UgbmVjZXNpdGEgbGlicmFyeShrbml0cikgDQprYWJsZV9zdHlsaW5nKCkgJT4lICAgICAgICAgICAgICAgICNsaWJyYXJ5KGthYmxlRXh0cmEpLi4uLiBTb2xvIHBhcmEga25pdCB0byBodG1sDQprYWJsZV9jbGFzc2ljXzIoZnVsbF93aWR0aCA9IEYpICAgI2xpYnJhcnkoa2FibGVFeHRyYSkuLi4uU29sbyBwYXJhIGtuaXQgdG8gaHRtbA0KYGBgDQoNCg0KDQoqKkludGVycHJldGFjaW9uZXM6ICoqDQoNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGV2YWw9RkFMU0UsIGVjaG89RkFMU0V9DQpuY29sKGRhdCkNCmNsYXNzKGVpZy52YWwpICMgRXMgdW5hIG1hdHJpeCwgYXJyZWdsbw0KZWlnLnZhbFsxLDFdDQplaWcudmFsWzEsMl0NCmVpZy52YWxbMiwyXQ0KZWlnLnZhbFsyLDNdDQplaWcudmFsWzMsM10NCmBgYA0KDQoNCiAgMS4gTGEgc3VtYSBkZSB0b2RvcyBsb3MgdmFsb3JlcyBwcm9waW9zIHJlc3VsdGEgZW4gdW5hIHZhcmlhbnphIHRvdGFsIGRlIGByIG5jb2woZGF0KWAgKHBvcnF1ZSBlc3RhbW9zIHV0aWxpemFuZG8gYHIgbmNvbChkYXQpYCB2YXJpYWJsZXMgeSBsYXMgdmFyaWFibGVzIGVzdMOhbiBlc3RhbmRhcml6YWRhcykuIA0KICANCiAgMi4gTGEgY29udHJpYnVjacOzbiBkZSBjYWRhIHZhbG9yIHByb3BpbyBhIGxhIHZhcmlhY2nDs24gc2UgcHJlc2VudGEgZW4gbGEgc2VndW5kYSBjb2x1bW5hIChgZWlnZW52YWx1ZWApLiANCiAgDQogIDMuIFBvciBlamVtcGxvLCBhbCBkaXZpZGlyIGByIHJvdW5kKGVpZy52YWxbMSwxXSwyKWAgIGVudHJlIGByIG5jb2woZGF0KWAgKHkgbXVsdGlwbGljYW5kbyBwb3IgMTAwKSwgb2J0ZW5lbW9zIGByIHJvdW5kKGVpZy52YWxbMSwyXSwyKWAlLCBsbyBxdWUgZXF1aXZhbGUgYXByb3hpbWFkYW1lbnRlIGFsICBgciByb3VuZChlaWcudmFsWzEsMl0sMilgJSBkZSBsYSB2YXJpYWNpw7NuIGV4cGxpY2FkYSBwb3IgZXN0ZSBwcmltZXIgdmFsb3IgcHJvcGlvICh2ZXIgcHJpbWVyYSBmaWxhLCB0ZXJjZXJhIGNvbHVtbmEgYHZhcmlhbmNlLnBlcmNlbnRgKS4gDQogIA0KICA0LiBFbCBwb3JjZW50YWplIGFjdW11bGFkbyBkZSB2YXJpYWNpw7NuIGV4cGxpY2FkYSBzZSBjYWxjdWxhIHN1bWFuZG8gbGFzIHByb3BvcmNpb25lcyBzdWNlc2l2YXMgZGUgdmFyaWFjacOzbiBleHBsaWNhZGEgcGFyYSBvYnRlbmVyIGVsIHRvdGFsIGFjdW11bGFkby4gDQogIA0KICA1LiBQb3IgZWplbXBsbywgc3VtYW5kbyBlbCBgciByb3VuZChlaWcudmFsWzEsMl0sMilgJSB5IGVsIGByIHJvdW5kKGVpZy52YWxbMiwyXSwyKWAlLCBvYnRlbmVtb3MgYHIgZWlnLnZhbFsyLDNdYCUgKHbDqWFzZSBzZWd1bmRhIGZpbGEgeSDDumx0aW1hIGNvbHVtbmEgYGN1bXVsYXRpdmUudmFyaWFuY2UucGVyY2VudGApLCB5IGFzw60gc3VjZXNpdmFtZW50ZS4gUG9yIGxvIHRhbnRvLCBhcHJveGltYWRhbWVudGUgZWwgYHIgcm91bmQoZWlnLnZhbFsyLDNdLDIpYCUgZGUgbGEgdmFyaWFjacOzbiBzZSBleHBsaWNhIHBvciBsb3MgZG9zIHByaW1lcm9zIHZhbG9yZXMgcHJvcGlvcyBlbiBjb25qdW50by4NCiAgDQogIDYuIEVuIG51ZXN0cm8gYW7DoWxpc2lzLCBsb3MgdHJlcyBwcmltZXJvcyBjb21wb25lbnRlcyBwcmluY2lwYWxlcyBleHBsaWNhbiBlbCBgciByb3VuZChlaWcudmFsWzMsM10sMilgJSBkZSBsYSB2YXJpYWNpw7NuLiBFc3RlIGVzIHVuIHBvcmNlbnRhamUgYWNlcHRhYmxlbWVudGUgYWx0by4NCiAgDQoNCg0KICANCiANCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgU2NyZWUgcGxvdA0KDQpFbCAqKnNjcmVlIHBsb3QqKiBwdWVkZSBnZW5lcmFyc2UgdXRpbGl6YW5kbyBsYSBmdW5jacOzbiBgZnZpel9laWdgIG8gYGZ2aXpfc2NyZWVwbG90YCBkZWwgcGFxdWV0ZSBgZmFjdG9leHRyYWAgKHNlIGdlbmVyYSBleGFjdGFtZW50ZSBsYSBtaXNtYSBncsOhZmljYSkuDQoNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZXZhbD1GQUxTRX0NCiMgUHJpbWVyYSBvcGNpw7NuOiANCmZ2aXpfZWlnKHJlcy5wY2EsIGFkZGxhYmVscyA9IFRSVUUsIHlsaW0gPSBjKDAsIDUwKSkNCg0KIyBTZWd1bmRhIG9wY2nDs246IA0KZnZpel9zY3JlZXBsb3QocmVzLnBjYSwgYWRkbGFiZWxzID0gVFJVRSwgeWxpbSA9IGMoMCwgNTApKQ0KYGBgDQoNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRX0NCmZ2aXpfZWlnKHJlcy5wY2EsIGFkZGxhYmVscyA9IFRSVUUsIHlsaW0gPSBjKDAsIDUwKSkNCiNmdml6X3NjcmVlcGxvdChyZXMucGNhLCBhZGRsYWJlbHMgPSBUUlVFLCB5bGltID0gYygwLCA1MCkpDQpgYGANCg0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZXZhbD1GQUxTRSwgZWNobz1GQUxTRX0NCm5jb2woZGF0KQ0KY2xhc3MoZWlnLnZhbCkgIyBFcyB1bmEgbWF0cml4LCBhcnJlZ2xvDQplaWcudmFsWzEsMV0NCmVpZy52YWxbMSwyXQ0KZWlnLnZhbFsyLDJdDQplaWcudmFsWzIsM10NCmVpZy52YWxbMywzXQ0KZWlnLnZhbFs0LDNdDQpgYGANCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCAgZWNobz1GQUxTRX0NCkNvbXBfc2NyZWUgPC0gNA0KYGBgDQoNCg0KQmFzw6FuZG9ub3MgZW4gZWwgZGlhZ3JhbWEgYW50ZXJpb3IsIHF1aXrDoXMgcG9kcsOtYW1vcyBmb2NhbGl6YXJub3MgZW4gZWwgY29tcG9uZW50ZSBwcmluY2lwYWwgbsO6bWVybyBgciBDb21wX3NjcmVlYC4gRXN0ZSBjb21wb25lbnRlIHJldGllbmUgZWwgYHIgcm91bmQoZWlnLnZhbFs0LDNdLDIpYCUgZGUgbGEgaW5mb3JtYWNpw7NuICh2YXJpYW56YSkgcHJlc2VudGUgZW4gbG9zIGRhdG9zLCBqdW50byBjb24gbG9zIGByIENvbXBfc2NyZWUtMWAgcHJpbWVyb3MgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMuDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRWplbXBsbzogU29sdWNpw7NuIChgZ2V0X3BjYV92YXJgKQ0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBBcmd1bWVudG9zIGRlIGBnZXRfcGNhX3ZhcmANCg0KVW5hIG1hbmVyYSBzaW1wbGUgZGUgb2J0ZW5lciBsb3MgcmVzdWx0YWRvcyBwYXJhIGxhcyB2YXJpYWJsZXMgZGUgdW5hIHNhbGlkYSBkZSBQQ0EgZXMgZW1wbGVhciBsYSBmdW5jacOzbiBgZ2V0X3BjYV92YXJgIGRlbCBwYXF1ZXRlIGBmYWN0b2V4dHJhYC4gRXN0YSBmdW5jacOzbiBnZW5lcmEgdW5hIHNlcmllIGRlIG1hdHJpY2VzIHF1ZSBjb250aWVuZW4gdG9kYSBsYSBpbmZvcm1hY2nDs24gcmVsZXZhbnRlIHBhcmEgbGFzIHZhcmlhYmxlcyBhY3RpdmFzLCBpbmNsdXllbmRvIGxhcyBjb29yZGVuYWRhcywgY29ycmVsYWNpb25lcyBlbnRyZSB2YXJpYWJsZXMgeSBlamVzLCBlbCBjb3Nlbm8gYWwgY3VhZHJhZG8sIHkgbGFzIGNvbnRyaWJ1Y2lvbmVzLg0KDQoNCmBgYHtyfQ0KdmFyIDwtIGdldF9wY2FfdmFyKHJlcy5wY2EpDQp2YXINCmBgYA0KDQpMb3MgYXJndW1lbnRvcyBkZSBsYSBmdW5jacOzbiBgZ2V0X3BjYV92YXJgIHB1ZWRlbiBzZXIgZW1wbGVhZG9zIGVuIGxhIHJlcHJlc2VudGFjacOzbiBncsOhZmljYSBkZSBsYXMgdmFyaWFibGVzIGRlIGxhIHNpZ3VpZW50ZSBtYW5lcmE6DQogIA0KICArIGB2YXIkY29vcmRgOiBQcm9wb3JjaW9uYSBsYXMgY29vcmRlbmFkYXMgZGUgbGFzIHZhcmlhYmxlcyBwYXJhIGxhIGNyZWFjacOzbiBkZSB1biBncsOhZmljbyBkZSBkaXNwZXJzacOzbi4NCiAgDQogICsgYHZhciRjb3MyYDogSW5kaWNhIGxhIGNhbGlkYWQgZGUgbGEgcmVwcmVzZW50YWNpw7NuIGRlIGxhcyB2YXJpYWJsZXMgZW4gZWwgbWFwYSBkZSBmYWN0b3Jlcy4gU2Ugb2J0aWVuZSBjYWxjdWxhbmRvIGVsIGN1YWRyYWRvIGRlIGxhcyBjb29yZGVuYWRhczogYHZhci5jb3MyYCA9IGB2YXIuY29vcmQgKiB2YXIuY29vcmRgLg0KICANCiAgKyBgdmFyJGNvbnRyaWJgOiBDb250aWVuZSBsYXMgY29udHJpYnVjaW9uZXMgKGVuIHBvcmNlbnRhamUpIGRlIGxhcyB2YXJpYWJsZXMgYSBsb3MgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMuIExhIGNvbnRyaWJ1Y2nDs24gZGUgdW5hIHZhcmlhYmxlIChgdmFyYCkgYSB1biBjb21wb25lbnRlIHByaW5jaXBhbCBlc3BlY8OtZmljbyBzZSBjYWxjdWxhIGNvbW86IGAodmFyLmNvczIgKiAxMDApIC8gKGNvczIgdG90YWwgZGVsIGNvbXBvbmVudGUpYC4NCiAgDQoNClNlIHJlc2FsdGEgZWwgaGVjaG8gcXVlIGVzIGZhY3RpYmxlIHJlcHJlc2VudGFyIHZhcmlhYmxlcyB5IGFzaWduYXJsZXMgY29sb3JlcyBiYXNhZG9zIGVuOiANCiAgDQogIGEpIFN1IGdyYWRvIGRlIHJlbGV2YW5jaWEgZW4gZWwgbWFwYSBkZSBmYWN0b3JlcyAoYGNvczJgKS4NCiAgDQogIGIpIFN1IGluZmx1ZW5jaWEgZW4gbG9zIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzLg0KICANCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgVmFsb3JlcyBkZSBgZ2V0X3BjYV92YXJgDQoNCkxhcyBkaWZlcmVudGVzIGNvbXBvbmVudGVzIHNlIHB1ZWRlbiBvYnRlbmVyIGFzw606IA0KDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KIyBDb29yZGVuYWRhcyBkZSBsYXMgdmFyaWFibGVzIChiYXNhZG8gZW4gY29ycmVsYWNpb25lcykNCnZhciRjb29yZA0KDQojIENvczI6IGNhbGlkYWQgZW4gZWwgbWFwYSBkZSBmYWN0b3Jlcw0KdmFyJGNvczINCg0KIyBDb250cmlidWNpb25lcyBwYXJhIGxvcyBjb21wb25lbnRlcyBwcmluY2lwYWxlcw0KdmFyJGNvbnRyaWINCmBgYA0KDQpNw6FzIGFkZWxhbnRlLCBzZSBleHBsaWNhcsOhIGPDs21vIHJlcHJlc2VudGFyIGdyw6FmaWNhbWVudGUgdmFyaWFibGVzIHkgZGVkdWNpciBjb25jbHVzaW9uZXMgc29icmUgbGFzIHJlbGFjaW9uZXMgZW50cmUgZWxsYXMuIEx1ZWdvLCBzZSByZXNhbHRhbiBsYXMgdmFyaWFibGVzIHNlZ8O6bjoNCiAgDQogIGEpIFN1IGVmaWNhY2lhIGVuIGxhIHJlcHJlc2VudGFjacOzbiBlbiBlbCBtYXBhIGZhY3RvcmlhbC4gDQogIA0KICBiKSBTdSBpbmZsdWVuY2lhIGVuIGxvcyBjb21wb25lbnRlcyBwcmluY2lwYWxlcy4NCiAgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRWplbXBsbzogU29sdWNpw7NuIChgdmFyJGNvb3JkYCkNCg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYHZhciRjb29yZGAgKHZhbG9yZXMpDQoNCkxhIHJlbGFjacOzbiBlbnRyZSB1bmEgdmFyaWFibGUgeSB1biBjb21wb25lbnRlIHByaW5jaXBhbCAoQ1ApIHNlIGVtcGxlYSBwYXJhIGV4cHJlc2FyIGxhcyBjb29yZGVuYWRhcyBkZSBsYSB2YXJpYWJsZSBlbiBlbCBDUC4gTGEgZm9ybWEgZGUgcmVwcmVzZW50YXIgbGFzIHZhcmlhYmxlcyBkaWZpZXJlIGRlbCBtb2RvIGVuIHF1ZSBzZSByZXByZXNlbnRhbiBsYXMgb2JzZXJ2YWNpb25lczogbWllbnRyYXMgcXVlIGxhcyBvYnNlcnZhY2lvbmVzIHNlIG11ZXN0cmFuIG1lZGlhbnRlIHN1cyBwcm95ZWNjaW9uZXMsIGxhcyB2YXJpYWJsZXMgc2UgcmVwcmVzZW50YW4gYSB0cmF2w6lzIGRlIHN1cyBjb3JyZWxhY2lvbmVzLg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCiMgQ29vcmRlbmFkYXMgZGUgbGFzIHZhcmlhYmxlcyAoYmFzYWRvIGVuIGNvcnJlbGFjaW9uZXMpDQp2YXIkY29vcmQNCmBgYA0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCiMgQ29vcmRlbmFkYXMgZGUgbGFzIHZhcmlhYmxlcyAoYmFzYWRvIGVuIGNvcnJlbGFjaW9uZXMpDQprYWJsZSh2YXIkY29vcmQsIGFsaWduID0gImNjYyIpICU+JSMgU2UgbmVjZXNpdGEgbGlicmFyeShrbml0cikgDQprYWJsZV9zdHlsaW5nKCkgJT4lICAgICAgICAgICAgICAgICNsaWJyYXJ5KGthYmxlRXh0cmEpLi4uLiBTb2xvIHBhcmEga25pdCB0byBodG1sDQprYWJsZV9jbGFzc2ljXzIoZnVsbF93aWR0aCA9IEYpICAgI2xpYnJhcnkoa2FibGVFeHRyYSkuLi4uU29sbyBwYXJhIGtuaXQgdG8gaHRtbA0KYGBgDQoNCiMjIyBgdmFyJGNvb3JkYCAoY8OtcmN1bG8gZGUgY29ycmVsYWNpb25lcykNCg0KQ29uIGVsIHNpZ3VpZW50ZSBjw7NkaWdvIHNlIGdyYWZpY2FuIGxhcyB2YXJpYWJsZXM6IA0KDQpgYGB7cn0NCmZ2aXpfcGNhX3ZhcihyZXMucGNhLCBjb2wudmFyID0gInJlZCIsIA0KICAgICAgICAgICAgIHJlcGVsPSBUUlVFICMgRXZpdGEgdHJhc2xhcGFtaWVudG8gZGUgdGV4dG9zDQogICAgICAgICAgICAgKQ0KYGBgDQoNCkVsIGRpYWdyYW1hIG1lbmNpb25hZG8gYW50ZXJpb3JtZW50ZSBlcyB0YW1iacOpbiByZWZlcmlkbyBjb21vIHVuICpkaWFncmFtYSBkZSBjb3JyZWxhY2nDs24qIGRlIHZhcmlhYmxlcy4gRXN0ZSBkaWFncmFtYSBpbHVzdHJhIGxhcyByZWxhY2lvbmVzIGVudHJlIHRvZGFzIGxhcyB2YXJpYWJsZXMgeSBwdWVkZSBzZXIgaW50ZXJwcmV0YWRvIGRlIGxhIHNpZ3VpZW50ZSBtYW5lcmE6DQogIA0KICArIExhcyB2YXJpYWJsZXMgcXVlIHRpZW5lbiB1bmEgY29ycmVsYWNpw7NuIHBvc2l0aXZhIHRpZW5kZW4gYSBhZ3J1cGFyc2UgY2VyY2FuYXMgZW50cmUgc8OtIGVuIGVsIGdyw6FmaWNvLg0KICANCiAgKyBMYXMgdmFyaWFibGVzIHF1ZSB0aWVuZW4gdW5hIGNvcnJlbGFjacOzbiBuZWdhdGl2YSB0aWVuZGVuIGEgdWJpY2Fyc2UgZW4gbGFkb3Mgb3B1ZXN0b3MgZGVsIG9yaWdlbiBkZWwgZ3LDoWZpY28gKGVuIGN1YWRyYW50ZXMgb3B1ZXN0b3MpLg0KICANCiAgKyBMYSBkaXN0YW5jaWEgZW50cmUgbGFzIHZhcmlhYmxlcyB5IGVsIG9yaWdlbiBkZWwgZ3LDoWZpY28gaW5kaWNhIGxhIGNhbGlkYWQgZGUgbGFzIHZhcmlhYmxlcyBlbiBlbCBtYXBhIGZhY3RvcmlhbC4gTGFzIHZhcmlhYmxlcyBxdWUgZXN0w6FuIG3DoXMgYWxlamFkYXMgZGVsIG9yaWdlbiBkZWwgZ3LDoWZpY28gZXN0w6FuIG3DoXMgY2xhcmFtZW50ZSByZXByZXNlbnRhZGFzIGVuIGVsIG1hcGEgZmFjdG9yaWFsLg0KICANCiAgDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBFamVtcGxvOiBTb2x1Y2nDs24gKGB2YXIkY29zMmApICANCiAgDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGB2YXIkY29zMmAgKGNhbGlkYWQgZGUgbGEgcmVwcmVzZW50YWNpw7NuKQ0KDQoNCkxhIG1lZGlkYSBkZSBsYSBjYWxpZGFkIGRlIGxhIHJlcHJlc2VudGFjacOzbiwgZXMgZGVjaXIgZGUgY3XDoW4gYmllbiBsYXMgdmFyaWFibGVzIGVzdMOhbiByZXByZXNlbnRhZGFzIGVuIGVsIG1hcGEgZmFjdG9yaWFsIHNlIGNvbm9jZSBjb21vIGBjb3MyYCAoKmN1YWRyYWRvIGRlbCBjb3Nlbm8qLCAqY29vcmRlbmFkYXMgY3VhZHJhZGFzKiksIGVsIGN1YWwgc2UgcHVlZGUgb2J0ZW5lciAgZGUgbGEgc2lndWllbnRlIG1hbmVyYToNCg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCnZhciRjb3MyDQpgYGANCg0KYGBge3IsIGVjaG89RkFMU0V9DQprYWJsZSh2YXIkY29zMiwgYWxpZ24gPSAiY2NjIikgJT4lIyBTZSBuZWNlc2l0YSBsaWJyYXJ5KGtuaXRyKSANCmthYmxlX3N0eWxpbmcoKSAlPiUgICAgICAgICAgICAgICAgI2xpYnJhcnkoa2FibGVFeHRyYSkuLi4uIFNvbG8gcGFyYSBrbml0IHRvIGh0bWwNCmthYmxlX2NsYXNzaWNfMihmdWxsX3dpZHRoID0gRikgICAjbGlicmFyeShrYWJsZUV4dHJhKS4uLi5Tb2xvIHBhcmEga25pdCB0byBodG1sDQpgYGANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGB2YXIkY29zMmAgKG1hdHJpeiBkZSBjb3JyZWxhY2lvbmVzKQ0KDQpTZSBwdWVkZSB2aXN1YWxpemFyIGVsICpjb3Nlbm8gY3VhZHJhZG8qIGRlIGxhcyB2YXJpYWJsZXMgZW4gdG9kYXMgbGFzIGRpbWVuc2lvbmVzIHV0aWxpemFuZG8gbGEgZnVuY2nDs24gYGNvcnJwbG90YCBkZWwgcGFxdWV0ZSBgY29ycnBsb3RgIChlbCBhcmd1bWVudG8gYGlzLmNvcnI9RkFMU0VgKSBub3MgcGVybWl0ZSB2aXN1YWxpemFyIHVuYSBtYXRyaXggZGUgdmFsb3JlcyBxdWUgbm8gc29uIGNvcnJlbGFjaW9uZXM6IA0KICANCmBgYHtyfQ0KY29ycnBsb3QodmFyJGNvczIsIA0KICAgICAgICAgaXMuY29ycj1GQUxTRSwgICANCiAgICAgICAgIHRsLmNvbCA9ICJibGFjayIsIA0KICAgICAgICAgI2FkZENvZWYuY29sID0gJ2dyZXk1MCcsICNBZ3JlZ2FyIHZhbG9yZXMNCiAgICAgICAgICNudW1iZXIuY2V4ID0gMC43LCAgICAgICAjVGFtYcOxbyBkZSBsb3MgdmFsb3Jlcw0KICAgICAgICAgYmcgPSAibGlnaHRibHVlIiwgICAgICAgICNDb2xvciBkZWwgZm9uZG8NCiAgICAgICAgIHRsLnNydCA9IDkwLA0KICAgICAgICAgdGl0bGU9Ik1hdHJpeiBkZSBjb3JyZWxhY2lvbmVzIiwgDQogICAgICAgICAjdGwuY2V4PTEuNSwgICAgICAgICAgICAjVGFtYcOxbyBkZSBsYXMgdmFycyB5IERpbXMNCiAgICAgICAgICNjZXgubWFpbj0yLjAsICAgICAgICAgICNUYW1hw7FvIGRlbCB0w610dWxvDQogICAgICAgICAjdHlwZT0ibG93ZXIiLA0KICAgICAgICAgbWFyPWMoMCwwLDQsMCksICAgICAgICAjVWJpY2FjacOzbiBkZWwgdMOtdHVsbw0KICAgICAgICApDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgdmFyJGNvczJgIChkaWFncmFtYSBkZSBiYXJyYXMpDQoNCkNvbiBsYSBmdW5jacOzbiBgZnZpel9jb3MyYGRlbCBwYXF1ZXRlIGBmYWN0b2V4dHJhYCwgdGFtYmnDqW4sIGVzIHBvc2libGUgY3JlYXIgdW4gZGlhZ3JhbWEgZGUgYmFycmFzIHBhcmEgZWwgYGNvczJgZGUgbGFzIHZhcmlhYmxlczoNCg0KYGBge3J9DQojIGNvczIgdG90YWwgZGUgbGFzIHZhcmlhYmxlcyBzb2JyZSBEaW0uMSB5IERpbS4yDQpmdml6X2NvczIocmVzLnBjYSwgY2hvaWNlID0gInZhciIsIGF4ZXMgPSAxOjIpDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgdmFyJGNvczJgIChpbnRlcnBldGFjaW9uZXMgaW5pY2lhbGVzKQ0KICANCiAgMS4gVW4gY29zZW5vIGN1YWRyYWRvIGFsdG8gaW5kaWNhIHVuYSBidWVuYSByZXByZXNlbnRhY2nDs24gZGUgbGEgdmFyaWFibGUgZW4gZWwgY29tcG9uZW50ZSBwcmluY2lwYWwuIEVuIGVzdGUgY2FzbywgbGEgdmFyaWFibGUgZXN0w6EgcG9zaWNpb25hZGEgY2VyY2EgZGUgbGEgY2lyY3VuZmVyZW5jaWEgZGVsIGPDrXJjdWxvIGRlIGNvcnJlbGFjacOzbi4NCiAgDQogIDIuIFVuIGNvc2VubyBjdWFkcmFkbyBiYWpvIGluZGljYSBxdWUgbGEgdmFyaWFibGUgbm8gZXN0w6EgcGVyZmVjdGFtZW50ZSByZXByZXNlbnRhZGEgcG9yIGxvcyBjb21wb25lbnRlcyBwcmluY2lwYWxlcy4gRW4gZXN0ZSBjYXNvLCBsYSB2YXJpYWJsZSBlc3TDoSBjZXJjYSBkZWwgY2VudHJvIGRlbCBjw61yY3Vsby4NCiAgDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGB2YXIkY29zMmAgKGludGVycGV0YWNpb25lcyBkZSBsYSBzdW1hIHRvdGFsKQ0KICANCjMuIFBhcmEgdW5hIHZhcmlhYmxlIGRhZGEsIGxhIHN1bWEgZGUgbG9zIGNvc2Vub3MgYWwgY3VhZHJhZG8gZW4gdG9kYXMgbGFzIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzIGVzIGlndWFsIGEgdW5vLiANCg0KNC4gU2kgdW5hIHZhcmlhYmxlIGVzdMOhIHBlcmZlY3RhbWVudGUgcmVwcmVzZW50YWRhIHBvciBzb2xvIGRvcyBjb21wb25lbnRlcyBwcmluY2lwYWxlcyAoRGltLjEgeSBEaW0uMiksIGxhIHN1bWEgZGUgbG9zIGNvc2Vub3MgYWwgY3VhZHJhZG8gZW4gZXN0YXMgZG9zIENQcyBlcyBpZ3VhbCBhIHVuby4gRW4gZXN0ZSBjYXNvLCBsYXMgdmFyaWFibGVzIGVzdGFyw6FuIHBvc2ljaW9uYWRhcyBlbiBlbCBjw61yY3VsbyBkZSBjb3JyZWxhY2lvbmVzLiANCg0KNS4gUGFyYSBhbGd1bmFzIHZhcmlhYmxlcywgcHVlZGUgc2VyIG5lY2VzYXJpbyBtw6FzIGRlIDIgY29tcG9uZW50ZXMgcGFyYSByZXByZXNlbnRhciBwZXJmZWN0YW1lbnRlIGxvcyBkYXRvcy4gRW4gZXN0ZSBjYXNvLCBsYXMgdmFyaWFibGVzIGVzdGFyw6FuIHBvc2ljaW9uYWRhcyBkZW50cm8gZGVsIGPDrXJjdWxvIGRlIGNvcnJlbGFjaW9uZXMuIA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYHZhciRjb3MyYCAoaW50ZXJwZXRhY2lvbmVzIHJlc3VtaWRhcykNCg0KRW4gcmVzdW1lbjoNCg0KNi4gTG9zIHZhbG9yZXMgZGUgY29zZW5vcyBhbCBjdWFkcmFkbyBzZSB1dGlsaXphbiBwYXJhIGVzdGltYXIgbGEgY2FsaWRhZCBkZSBsYSByZXByZXNlbnRhY2nDs24uDQoNCjcuIEN1YW50byBtw6FzIGNlcmNhIGVzdMOpIHVuYSB2YXJpYWJsZSBkZWwgY8OtcmN1bG8gZGUgY29ycmVsYWNpb25lcywgbWVqb3Igc2Vyw6Egc3UgcmVwcmVzZW50YWNpw7NuIGVuIGVsIG1hcGEgZmFjdG9yaWFsICh5IG3DoXMgaW1wb3J0YW50ZSBzZXLDoSBpbnRlcnByZXRhciBlc3RhcyBjb21wb25lbnRlcykuDQoNCjguIExhcyB2YXJpYWJsZXMgcXVlIGVzdMOhbiBjZXJjYSBkZWwgY2VudHJvIGRlbCBncsOhZmljbyBzb24gbWVub3MgaW1wb3J0YW50ZXMgcGFyYSBsYXMgcHJpbWVyYXMgY29tcG9uZW50ZXMuDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYHZhciRjb3MyYCAoYXJndW1lbnRvIGBncmFkaWVudC5jb2xzYCkNCg0KRXMgcG9zaWJsZSBjb2xvcmVhciBsYXMgdmFyaWFibGVzIHNlZ8O6biBzdXMgdmFsb3JlcyBgY29zMmAgdXRpbGl6YW5kbyBlbCBhcmd1bWVudG8gYGNvbC52YXIgPSAiY29zMiJgLiBFc3RvIHByb2R1Y2UgY29sb3JlcyBkZWdyYWRhZG9zLiBFbiBlc3RlIGNhc28sIHNlIHB1ZWRlIHV0aWxpemFyIGVsIGFyZ3VtZW50byBgZ3JhZGllbnQuY29sYCBwYXJhIHByb3BvcmNpb25hciB1biBjb2xvciBwZXJzb25hbGl6YWRvLiANCg0KUG9yIGVqZW1wbG8sIGBncmFkaWVudC5jb2xzID0gYygiZ3JlZW4iLCAiYnJvd24iLCAiYmx1ZSIpYCBzaWduaWZpY2EgcXVlOg0KDQoxLiBMYXMgdmFyaWFibGVzIGNvbiB2YWxvcmVzIGJham9zIGRlIGBjb3MyYCBzZXLDoW4gY29sb3JlYWRhcyBlbiAqdmVyZGUqLg0KDQoyLiBMYXMgdmFyaWFibGVzIGNvbiB2YWxvcmVzIG1lZGlvcyBkZSBgY29zMmAgc2Vyw6FuIGNvbG9yZWFkYXMgZW4gKm1hcnLDs24qLg0KDQozLiBMYXMgdmFyaWFibGVzIGNvbiB2YWxvcmVzIGFsdG9zIGRlIGBjb3MyYCBzZXLDoW4gY29sb3JlYWRhcyBlbiAqYXp1bCouDQoNCg0KYGBge3J9DQojQ29sb3IgcG9yIHZhbG9yZXMgY29zMjogY2FsaWRhZCBzb2JyZSBlbCBtYXBhIGZhY3RvcmlhbA0KZnZpel9wY2FfdmFyKHJlcy5wY2EsIGNvbC52YXIgPSAiY29zMiIsDQogICAgICAgICAgICAgZ3JhZGllbnQuY29scyA9IGMoImdyZWVuIiwgImJyb3duIiwgImJsdWUiKSwNCiAgICAgICAgICAgICB0aXRsZT0iR3JhZGllbnRlIGRlIGxhcyB2YXJpYWJsZXMgcG9yIGNvczIiLA0KICAgICAgICAgICAgIHJlcGVsID0gVFJVRSAjIEV2aXRhIHRyYXNsYXBhbWllbnRvIGRlIHRleHRvcw0KICAgICAgICAgICAgICkNCmBgYA0KDQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGB2YXIkY29zMmAgKHRyYW5zcGFyaWVuY2lhcyBjb24gYGFscGhhLnZhcmApDQoNClRhbWJpw6luIGVzIHBvc2libGUgYWp1c3RhciBsYSB0cmFuc3BhcmVuY2lhIGRlIGxhcyB2YXJpYWJsZXMgc2Vnw7puIGxvcyB2YWxvcmVzIGRlIGBjb3MyYCB1dGlsaXphbmRvIGxhIG9wY2nDs24gYGFscGhhLnZhciA9ICJjb3MyImA6IA0KDQpgYGB7cn0NCiMgQ2FtYmlhciBsYSB0cmFuc3BhcmllbmNpYSBwb3IgdmFsb3JlcyBkZSBjb3MyDQpmdml6X3BjYV92YXIocmVzLnBjYSwgYWxwaGEudmFyID0gImNvczIiLA0KICAgICAgICAgICAgIGNvbC52YXIgPSAicmVkIiwNCiAgICAgICAgICAgICB0aXRsZT0iVHJhbnNwYXJpZW5jaWEgZGUgbGFzIHZhcmlhYmxlcyBwb3IgY29zMiIsDQogICAgICAgICAgICAgcmVwZWwgPSBUUlVFICMgRXZpdGEgdHJhc2xhcGFtaWVudG8gZGUgdGV4dG9zDQogICAgICAgICAgICAgKQ0KYGBgDQoNCg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIEVqZW1wbG86IFNvbHVjacOzbiAoYHZhciRjb250cmliYCkgIA0KICANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGB2YXIkY29udHJpYmAgKGdlbmVyYWwpDQoNCkxhcyBjb250cmlidWNpb25lcyBkZSBsYXMgdmFyaWFibGVzIGEgbGEgdmFyaWFiaWxpZGFkIGRlIHVuIGNvbXBvbmVudGUgcHJpbmNpcGFsIGRldGVybWluYWRvIHNlIGV4cHJlc2FuIGVuIHBvcmNlbnRhamUuIEVuIGVzdGUgc2VudGlkbzogDQogIA0KICArIExhcyB2YXJpYWJsZXMgcXVlIGVzdMOhbiBjb3JyZWxhY2lvbmFkYXMgY29uIFBDMSAoZXMgZGVjaXIsIERpbS4xKSB5IFBDMiAoZXMgZGVjaXIsIERpbS4yKSBzb24gbGFzIG3DoXMgaW1wb3J0YW50ZXMgcGFyYSBleHBsaWNhciBsYSB2YXJpYWJpbGlkYWQgZGVsIGNvbmp1bnRvIGRlIGRhdG9zLg0KICANCiAgKyBMYXMgdmFyaWFibGVzIHF1ZSBubyBzZSBjb3JyZWxhY2lvbmFuIGNvbiBuaW5nw7puIFBDIG8gc2UgY29ycmVsYWNpb25hbiBjb24gbGFzIMO6bHRpbWFzIGRpbWVuc2lvbmVzICBzb24gdmFyaWFibGVzIGNvbiBlc2Nhc2EgY29udHJpYnVjacOzbiB5IHB1ZWRlbiBlbGltaW5hcnNlIHBhcmEgc2ltcGxpZmljYXIgZWwgYW7DoWxpc2lzIGdlbmVyYWwuDQogIA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGB2YXIkY29udHJpYmAgKGVuIFIpDQoNCkxhIGNvbnRyaWJ1Y2nDs24gZGUgbGFzIHZhcmlhYmxlcyBwdWVkZSBleHRyYWVyc2UgZGUgbGEgc2lndWllbnRlIG1hbmVyYSA6DQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KdmFyJGNvbnRyaWINCmBgYA0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCmthYmxlKHZhciRjb250cmliLCBhbGlnbiA9ICJjY2MiKSAlPiUjIFNlIG5lY2VzaXRhIGxpYnJhcnkoa25pdHIpIA0Ka2FibGVfc3R5bGluZygpICU+JSAgICAgICAgICAgICAgICAjbGlicmFyeShrYWJsZUV4dHJhKS4uLi4gU29sbyBwYXJhIGtuaXQgdG8gaHRtbA0Ka2FibGVfY2xhc3NpY18yKGZ1bGxfd2lkdGggPSBGKSAgICNsaWJyYXJ5KGthYmxlRXh0cmEpLi4uLlNvbG8gcGFyYSBrbml0IHRvIGh0bWwNCmBgYA0KDQoNCkN1YW50byBtYXlvciBzZWEgZWwgdmFsb3IgZGUgbGEgY29udHJpYnVjacOzbiwgbcOhcyBjb250cmlidXllIGxhIHZhcmlhYmxlIGFsIGNvbXBvbmVudGUuDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYHZhciRjb250cmliYCAoY29ycmVsYWNpb25lcykNCg0KRXMgcG9zaWJsZSB1dGlsaXphciBsYSBmdW5jacOzbiBgY29ycnBsb3RgIGRlbCBwYXF1ZXRlIGBjb3JycGxvdGAgcGFyYSByZXNhbHRhciBsYXMgdmFyaWFibGVzIHF1ZSBtw6FzIGNvbnRyaWJ1eWVuIHBhcmEgY2FkYSBkaW1lbnNpw7NuLg0KDQpgYGB7cn0NCmNvcnJwbG90KHZhciRjb250cmliLCANCiAgICAgICAgIGlzLmNvcnI9RkFMU0UsICAgDQogICAgICAgICB0bC5jb2wgPSAiYmxhY2siLCANCiAgICAgICAgICNhZGRDb2VmLmNvbCA9ICdncmV5NTAnLCAjQWdyZWdhciB2YWxvcmVzDQogICAgICAgICAjbnVtYmVyLmNleCA9IDAuNywgICAgICAgI1RhbWHDsW8gZGUgbG9zIHZhbG9yZXMNCiAgICAgICAgIHRsLnNydCA9IDkwLCANCiAgICAgICAgIGJnID0gImxpZ2h0Ymx1ZSIsICAgICAgICAjQ29sb3IgZGVsIGZvbmRvDQogICAgICAgICB0aXRsZT0iTWF0cml6IGRlIGNvcnJlbGFjaW9uZXMiLCANCiAgICAgICAgICN0bC5jZXg9MS41LCAgICAgICAgICAgICNUYW1hw7FvIGRlIGxhcyB2YXJzIHkgRGltcw0KICAgICAgICAgI2NleC5tYWluPTIuMCwgICAgICAgICAgI1RhbWHDsW8gZGVsIHTDrXR1bG8NCiAgICAgICAgICN0eXBlPSJsb3dlciIsDQogICAgICAgICBtYXI9YygwLDAsNCwwKSAgICAgICAgICAjVWJpY2FjacOzbiBkZWwgdMOtdHVsbw0KICAgICAgICAgKQ0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgdmFyJGNvbnRyaWJgIChkaWFncmFtYXMgZGUgYmFycmEgZGUgY2FkYSB2YXJpYWJsZSkNCg0KDQpMYSBmdW5jacOzbiBgZnZpel9jb250cmliYCBkZWwgcGFxdWV0ZSBgZmFjdG9leHRyYWAgc2UgcHVlZGUgZW1wbGVhciBwYXJhIGRpYnVqYXIgdW4gZ3LDoWZpY28gZGUgYmFycmFzIGRlIGxhcyBjb250cmlidWNpb25lcyBkZSBsYXMgdmFyaWFibGVzLiBTaSBsb3MgZGF0b3MgY29udGllbmVuIG11Y2hhcyB2YXJpYWJsZXMsIHNlIHB1ZWRlIG9wdGFyIHBvciBtb3N0cmFyIHNvbG8gbGFzIHZhcmlhYmxlcyBxdWUgbcOhcyBjb250cmlidXllbi4gRWwgc2lndWllbnRlIGPDs2RpZ28gZW4gUiBtdWVzdHJhIGxhcyAxMCB2YXJpYWJsZXMgcHJpbmNpcGFsZXMgcXVlIGNvbnRyaWJ1eWVuIGEgbG9zIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzLg0KDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KIyBDb250cmlidWNpb25lcyBkZSBsYXMgdmFyaWFibGVzIGEgUEMxDQpwMSA8LSBmdml6X2NvbnRyaWIocmVzLnBjYSwgY2hvaWNlID0gInZhciIsIGF4ZXMgPSAxLCB0b3AgPSAxMCkNCg0KIyBDb250cmlidWNpb25lcyBkZSBsYXMgdmFyaWFibGVzIGEgUEMyDQpwMiA8LSBmdml6X2NvbnRyaWIocmVzLnBjYSwgY2hvaWNlID0gInZhciIsIGF4ZXMgPSAyLCB0b3AgPSAxMCkNCg0KYGBgDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KIyBDb250cmlidWNpb25lcyBkZSBsYXMgdmFyaWFibGVzIGEgUEMxDQpwMSA8LSBmdml6X2NvbnRyaWIocmVzLnBjYSwgY2hvaWNlID0gInZhciIsIGF4ZXMgPSAxLCB0b3AgPSAxMCkgDQoNCiMgQ29udHJpYnVjaW9uZXMgZGUgbGFzIHZhcmlhYmxlcyBhIFBDMg0KcDIgPC0gZnZpel9jb250cmliKHJlcy5wY2EsIGNob2ljZSA9ICJ2YXIiLCBheGVzID0gMiwgdG9wID0gMTApDQoNCmxpYnJhcnkoZ3JpZEV4dHJhKSANCg0KZ3JpZC5hcnJhbmdlKHAxLHAyLCBuY29sPTIsIG5yb3cgPTEpDQpgYGANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGB2YXIkY29udHJpYmAgKGRpYWdyYW1hIGRlIGJhcnJhIHBhcmEgZWwgdG90YWwpDQoNCg0KQSBjb250aW51YWNpw7NuLCBzZSBwdWVkZSB2aXN1YWxpemFyIGxhIGNvbnRyaWJ1Y2nDs24gdG90YWwgYSBQQzEgeSBQQzI6IA0KDQpgYGB7cn0NCmZ2aXpfY29udHJpYihyZXMucGNhLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDE6MiwgdG9wID0gMTApDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgdmFyJGNvbnRyaWJgIChJbnRlcnByZXRhY2lvbmVzKSANCg0KKipJbnRlcnByZXRhY2nDs24gTm8uIDE6ICoqDQoNCkxhIGzDrW5lYSByb2phIGRpc2NvbnRpbnVhIGVuIGVsIGdyw6FmaWNvIGFudGVyaW9yIGluZGljYSBsYSBjb250cmlidWNpw7NuIHByb21lZGlvIGVzcGVyYWRhLiANCg0KKipJbnRlcnByZXRhY2nDs24gTm8uIDI6ICoqDQogIA0KU2kgbGEgY29udHJpYnVjacOzbiBkZSBsYXMgdmFyaWFibGVzIGZ1ZXNlIHVuaWZvcm1lLCBlbCB2YWxvciBlc3BlcmFkbyBzZXLDrWEgDQogIA0KICAkJFxmcmFjezF9e1xtYm94e2xvbmdpdHVkKHZhcmlhYmxlcyl9fSBcOz1cOyBcZnJhY3sxfXsxMH0oMTAwKVw7PVw7IDEwXCwgXCUkJA0KICANCiAgYGBge3J9DQogICgxL2xlbmd0aChkYXQpKSoxMDANCiAgYGBgDQoqKkludGVycHJldGFjacOzbiBOby4gMzogKioNCg0KUGFyYSB1biBjb21wb25lbnRlIGRhZG8sIHVuYSB2YXJpYWJsZSBjb24gdW5hIGNvbnRyaWJ1Y2nDs24gbWF5b3IgcXVlIGVzdGUgdW1icmFsIHBvZHLDrWEgY29uc2lkZXJhcnNlIGltcG9ydGFudGUgZW4gbGEgY29udHJpYnVjacOzbiBhbCBjb21wb25lbnRlLiANCiAgDQogIA0KKipJbnRlcnByZXRhY2nDs24gTm8uIDQ6ICoqDQoNClNlIGRlYmUgdGVuZXIgZW4gY3VlbnRhIHF1ZSBsYSBjb250cmlidWNpw7NuIHRvdGFsIGRlIHVuYSB2YXJpYWJsZSBkYWRhLCBlbiBsYSBleHBsaWNhY2nDs24gZGUgbGFzIHZhcmlhY2lvbmVzIHJldGVuaWRhcyBwb3IgZG9zIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzLCBkaWdhbW9zIFBDMSB5IFBDMiwgc2UgY2FsY3VsYSBjb21vIA0KICANCiAgDQogICQkIFxtYm94e0NvbnRyaWJ9ID0gXGZyYWN7Q18xIFwsIFxsYW1iZGFfMSBcOyArXDsgIENfMiBcLCAgXGxhbWJkYV8yfXtcbGFtYmRhXzEgXDsrXDsgIFxsYW1iZGFfMn0kJA0KICANCiAgZG9uZGU6DQogICAgDQogICArICRDXzEkIHkgJENfMiQgc29uIGxhcyBjb250cmlidWNpb25lcyBkZSBsYSB2YXJpYWJsZSBlbiBQQzEgeSBQQzIsIHJlc3BlY3RpdmFtZW50ZS4NCiAgICANCiAgICsgJFxsYW1iZGFfMSQgeSAkXGxhbWJkYV8yJCBzb24gbG9zIGVpZ2VudmFsb3JlcyBkZSBQQzEgeSBQQzIsIHJlc3BlY3RpdmFtZW50ZS4gDQogICAgDQogIA0KKipJbnRlcnByZXRhY2nDs24gTm8uIDU6ICoqDQoNClJlY29yZGFyIHF1ZSBsb3MgZWlnZW52YWxvcmVzIG1pZGVuIGxhIGNhbnRpZGFkIGRlIHZhcmlhY2nDs24gcmV0ZW5pZGEgcG9yIGNhZGEgUEMuIEVuIGVzdGUgY2FzbywgbGEgY29udHJpYnVjacOzbiBwcm9tZWRpbyBlc3BlcmFkYSAodW1icmFsKSBzZSBjYWxjdWxhIGRlIGxhIHNpZ3VpZW50ZSBtYW5lcmE6IENvbW8gc2UgbWVuY2lvbsOzIGFudGVyaW9ybWVudGUsIHNpIGxhcyBjb250cmlidWNpb25lcyBkZSBsYXMgMTAgdmFyaWFibGVzIGZ1ZXJhbiB1bmlmb3JtZXMsIGxhIGNvbnRyaWJ1Y2nDs24gcHJvbWVkaW8gZXNwZXJhZGEgZGUgdW5hIHZhcmlhYmxlIHBhcmEgUEMxIHkgUEMyIGVzOiANCiAgDQogICQkIFxtYm94e0NvbnRyaWJ9IFw7ID1cOyAgXGZyYWN7MTAgXCwgXGxhbWJkYV8xIFw7ICtcOyAgMTAgXCwgIFxsYW1iZGFfMn17XGxhbWJkYV8xIFw7K1w7ICBcbGFtYmRhXzJ9XDsgPVw7IDEwJCQNCiAgDQogIA0KU2UgcHVlZGUgb2JzZXJ2YXIgcXVlIGxhIHZhcmlhYmxlIGBFeGFtQWN1bWAgY29udHJpYnV5ZW4gbcOhcyBhIGxhcyBkaW1lbnNpb25lcyAxIHkgMi4NCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGB2YXIkY29udHJpYmAgKGPDrXJjdWxvIGRlIGNvcnJlbGFjaW9uZXMpIA0KDQpMYXMgdmFyaWFibGVzIG3DoXMgaW1wb3J0YW50ZXMgcHVlZGVuIHNlciByZXNhbHRhZGFzIGVuIGVsIGdyw6FmaWNvIGRlIGNvcnJlbGFjacOzbiBkZSBsYSBzaWd1aWVudGUgbWFuZXJhOg0KDQpgYGB7cn0NCmZ2aXpfcGNhX3ZhcihyZXMucGNhLCBjb2wudmFyID0gImNvbnRyaWIiLCANCiAgICAgICAgICAgICByZXBlbD0gVFJVRSwgIyBFdml0YSB0cmFzbGFwYW1pZW50byBkZSB0ZXh0b3MsDQogICAgICAgICAgICAgKQ0KDQpgYGANCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYHZhciRjb250cmliYCAoYXJndW1lbnRvIGBncmFkaWVudC5jb2xzYCkNCg0KQ29tbyB5YSBzZSBleHBsaWPDsywgYGdyYWRpZW50LmNvbHMgPSBjKCJncmVlbiIsICJicm93biIsICJibHVlIilgIHNpZ25pZmljYSBxdWU6DQoNCjEuIExhcyB2YXJpYWJsZXMgY29uIHZhbG9yZXMgYmFqb3MgZGUgYGNvczJgIHNlcsOhbiBjb2xvcmVhZGFzIGVuICp2ZXJkZSouDQoNCjIuIExhcyB2YXJpYWJsZXMgY29uIHZhbG9yZXMgbWVkaW9zIGRlIGBjb3MyYCBzZXLDoW4gY29sb3JlYWRhcyBlbiAqbWFycsOzbiouDQoNCjMuIExhcyB2YXJpYWJsZXMgY29uIHZhbG9yZXMgYWx0b3MgZGUgYGNvczJgIHNlcsOhbiBjb2xvcmVhZGFzIGVuICphenVsKi4NCg0KDQpgYGB7cn0NCmZ2aXpfcGNhX3ZhcihyZXMucGNhLCBjb2wudmFyID0gImNvbnRyaWIiLCANCiAgICAgICAgICAgICByZXBlbD0gVFJVRSwgIyBFdml0YSB0cmFzbGFwYW1pZW50byBkZSB0ZXh0b3MsDQogICAgICAgICAgICAgZ3JhZGllbnQuY29scyA9IGMoImdyZWVuIiwgImJyb3duIiwgImJsdWUiKSwNCiAgICAgICAgICAgICApDQoNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGB2YXIkY29udHJpYmAgKHRyYW5zcGFyaWVuY2lhcyBjb24gYGFscGhhLnZhcmApDQoNClRlbmdhIGVuIGN1ZW50YSBxdWUgdGFtYmnDqW4gZXMgcG9zaWJsZSBjYW1iaWFyIGxhIHRyYW5zcGFyZW5jaWEgZGUgbGFzIHZhcmlhYmxlcyBzZWfDum4gc3VzIHZhbG9yZXMgZGUgY29udHJpYnVjacOzbiB1dGlsaXphbmRvIGxhIG9wY2nDs24gYGFscGhhLnZhciA9ICJjb250cmliImA6DQoNCmBgYHtyfQ0KIyBDYW1iaWFyIGxhIHRyYW5zcGFyaWVuY2lhIHBhcmEgbGFzIGNvbnRyaWJ1Y2lvbmVzDQpmdml6X3BjYV92YXIocmVzLnBjYSwgYWxwaGEudmFyID0gImNvbnRyaWIiLA0KICAgICAgICAgICAgIGNvbC52YXIgPSAicmVkIiwNCiAgICAgICAgICAgICAjdGl0bGU9IlRyYW5zcGFyaWVuY2lhIGRlIGxhcyB2YXJpYWJsZXMgcG9yIGNvbnRyaWJ1Y2nDs24iLCANCiAgICAgICAgICAgICByZXBlbD0gVFJVRSAjIEV2aXRhIHRyYXNsYXBhbWllbnRvIGRlIHRleHRvcywNCiAgICAgICAgICAgICApDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgdmFyJGNvbnRyaWJgIChjw61yY3VsbyBwb3IgdmFyaWFibGUgY29udGludWEpDQoNCkVuIGxhcyBzZWNjaW9uZXMgYW50ZXJpb3JlcywgZGVtb3N0cmFtb3MgY8OzbW8gY29sb3JlYXIgdmFyaWFibGVzIHNlZ8O6biBzdXMgY29udHJpYnVjaW9uZXMgeSBzdSBjb3Nlbm8gYWwgY3VhZHJhZG8uIEVzIGltcG9ydGFudGUgZGVzdGFjYXIgcXVlIHRhbWJpw6luIGVzIHBvc2libGUgY29sb3JlYXIgdmFyaWFibGVzIHNlZ8O6biBjdWFscXVpZXIgdmFyaWFibGUgY29udGludWEgcGVyc29uYWxpemFkYS4gTGEgdmFyaWFibGUgZGUgY29sb3JhY2nDs24gZGViZSB0ZW5lciBsYSBtaXNtYSBsb25naXR1ZCBxdWUgZWwgbsO6bWVybyBkZSB2YXJpYWJsZXMgYWN0aXZhcyBlbiBlbCBBQ1AgKGFxdcOtLCAkbj0kYHIgbmNvbChkYXQpYC4gRWplbXBsbzogDQoNCmBgYHtyfQ0KIyBDcmVhdGUgYSByYW5kb20gY29udGludW91cyB2YXJpYWJsZSBvZiBsZW5ndGggMTANCnNldC5zZWVkKDEyMykNCm15LmNvbnQudmFyIDwtIHJub3JtKDEwKQ0KDQojIENvbG9yIHZhcmlhYmxlcyBieSB0aGUgY29udGludW91cyB2YXJpYWJsZQ0KZnZpel9wY2FfdmFyKHJlcy5wY2EsIGNvbC52YXIgPSBteS5jb250LnZhciwNCiAgICAgICAgICAgICBncmFkaWVudC5jb2xzID0gYygiZ3JlZW4iLCAiYnJvd24iLCAiYmx1ZSIpLA0KICAgICAgICAgICAgIHJlcGVsPVRSVUUsIA0KICAgICAgICAgICAgIHRpdGxlPSJDb3JyZWxhY2lvbmVzIGVudHJlIGxhcyB2YXJpYWJsZXMgcG9yIHZhcmlhYmxlIGNvbnRpbnVhIiwgDQogICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gIkNvbnRpbnVhIg0KICAgICAgICAgICAgICkNCmBgYA0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgdmFyJGNvbnRyaWJgIChjw61yY3VsbyBkZSBjb3JyZWxhY2lvbmVzIHBvciBncnVwb3MpDQoNCg0KVGFtYmnDqW4gZXMgZmFjdGlibGUgYWx0ZXJhciBlbCBjb2xvciBkZSBsYXMgdmFyaWFibGVzIGJhc8OhbmRvc2UgZW4gZ3J1cG9zIGRlZmluaWRvcyBwb3IgdW5hIHZhcmlhYmxlICpjdWFsaXRhdGl2YSogbyAqY2F0ZWfDs3JpY2EqIChjb23Dum5tZW50ZSBjb25vY2lkYSBjb21vICpmYWN0b3IqIGVuIFIpLiBEYWRvIHF1ZSBubyBkaXNwb25lbW9zIGRlIG5pbmd1bmEgdmFyaWFibGUgZGUgYWdydXBhY2nDs24gZW4gbnVlc3Ryb3MgY29uanVudG9zIGRlIGRhdG9zIHBhcmEgY2xhc2lmaWNhciBsYXMgdmFyaWFibGVzLCBvcHRhcmVtb3MgcG9yIGNyZWFyIHVuYS4gRW4gZWwgc2lndWllbnRlIGVqZW1wbG8gcHLDoWN0aWNvLCBpbmljaWFsbWVudGUgY2xhc2lmaWNhbW9zIGxhcyB2YXJpYWJsZXMgZW4gdHJlcyBncnVwb3MgbWVkaWFudGUgZWwgKmFsZ29yaXRtbyBkZSBhZ3J1cGFjacOzbiBrbWVhbnMqIChlbiBvdHJvcyBkb2N1bWVudG9zIHNlIGV4cGxpY2EgZXN0YSB0ZW9yw61hKS4gUG9zdGVyaW9ybWVudGUsIGVtcGxlYW1vcyBsb3MgY2zDunN0ZXJlcyBvYnRlbmlkb3MgbWVkaWFudGUgZWwgKmFsZ29yaXRtbyBrbWVhbnMqIHBhcmEgYXNpZ25hciBjb2xvcmVzIGEgbGFzIHZhcmlhYmxlcy4gUGFyYSBtw6FzIGRldGFsbGVzIHNvYnJlIGNsdXN0ZXJpbmcsIHB1ZWRlIGNvbnN1bHRhcnNlICBsYSBiaWJsaW9ncmFmw61hIHJlY29tZW5kYWRhLg0KDQoNCmBgYHtyfQ0KIyBDcmVhciB1bmEgdmFyaWFibGUgZ3J1cGFsIGNvbiBrbWVhbnMNCiMgQ3JlYXIgMyBjbMO6c3RlciAoY2VudGVycyA9IDMpDQpzZXQuc2VlZCgxMjMpDQpyZXMua20gPC0ga21lYW5zKHZhciRjb29yZCwgY2VudGVycyA9IDMsIG5zdGFydCA9IDI1KQ0KDQojIEV4dHJhZXIgZXRpcXVldGFzIGRlIGxvcyBjbMO6c3RlciANCmdycCAgIDwtIGFzLmZhY3RvcihyZXMua20kY2x1c3RlcikNCmdycA0KYGBgDQoNCkVsIGPDrXJjdWxvIGRlIGNvcnJlbGFjaW9uZXMgcG9yIGdydXBvcyBlcyBlbCBzaWd1aWVudGU6IA0KDQoNCmBgYHtyfQ0KIyBDb2xvcmVzIGRlIGxhcyB2YXJpYWJsZXMgcG9yIGdydXBvcw0KZnZpel9wY2FfdmFyKHJlcy5wY2EsIGNvbC52YXIgPSBncnAsIA0KICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCJibHVlIiwgImJyb3duIiwgImdyZWVuIiksDQogICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gIkNsdXN0ZXIiLA0KICAgICAgICAgICAgIHRpdGxlPSJDb3JyZWxhY2lvbmVzIGVudHJlIGxhcyB2YXJpYWJsZXMgcG9yIGdydXBvcyIsIA0KICAgICAgICAgICAgIHJlcGVsPSBUUlVFICMgRXZpdGEgdHJhc2xhcGFtaWVudG8gZGUgdGV4dG9zDQogICAgICAgICAgICAgKQ0KYGBgDQoNCg0KRXMgaW1wb3J0YW50ZSB0ZW5lciBlbiBjdWVudGEgcXVlOiANCiAgDQogIDEuIFNpIGRlc2VhbW9zIG1vZGlmaWNhciBsb3MgY29sb3JlcyBkZSBsb3MgZ3J1cG9zLCBkZWJlbW9zIGVtcGxlYXIgZWwgcGFyw6FtZXRybyBgcGFsZXR0ZWAuIA0KICANCiAgMi4gUGFyYSBhanVzdGFyIGxvcyBjb2xvcmVzIGRlIGxvcyBncmFkaWVudGVzLCBlcyBuZWNlc2FyaW8gdXRpbGl6YXIgZWwgcGFyw6FtZXRybyBgZ3JhZGllbnQuY29sc2AuIE3DoXMgYWRlbGFudGUsIHNlIHByZXNlbnRhIHVuIGVqZW1wbG8gdXRpbGl6YW5kbyBlc3RlIGFyZ3VtZW50by4gDQogIA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGB2YXIkY29udHJpYmAgKGZ1bmNpw7NuIGBkaW1kZXNjYCkgDQoNCkFudGVyaW9ybWVudGUgc2UgZXhwbGljw7MgY8OzbW8gZGVzdGFjYXIgbGFzIHZhcmlhYmxlcyBlbiBmdW5jacOzbiBkZSBzdSBjb250cmlidWNpw7NuIGEgbG9zIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzLiANCg0KTGEgZnVuY2nDs24gYGRpbWRlc2NgIGVuIGBGYWN0b01pbmVSYCBwdWVkZSBzZXIgZW1wbGVhZGEgcGFyYSBpZGVudGlmaWNhciBsYXMgdmFyaWFibGVzIG3DoXMgcmVsZXZhbnRlbWVudGUgdmluY3VsYWRhcyBhIHVuIGNvbXBvbmVudGUgcHJpbmNpcGFsIGVzcGVjw61maWNvLiBFc3RlIGVuZm9xdWUgcmVzdWx0YSDDunRpbCBwYXJhIGRldGVybWluYXIgbGEgYXNvY2lhY2nDs24gc2lnbmlmaWNhdGl2YSBlbnRyZSBsYXMgdmFyaWFibGVzIHkgdW4gY29tcG9uZW50ZSBwcmluY2lwYWwgZGFkbywgeSBwdWVkZSBzZXIgdXRpbGl6YWRvIGRlIGxhIHNpZ3VpZW50ZSBtYW5lcmE6DQoNCmBgYHtyfQ0KcmVzLmRlc2MgPC0gZGltZGVzYyhyZXMucGNhLCBheGVzID0gYygxLDIpLCBwcm9iYSA9IDAuMDUpDQojIERlc2NyaXBjacOzbiBkZSBsYSBkaW1lbnNpw7NuIDENCnJlcy5kZXNjJERpbS4xDQpgYGANCmBgYHtyfQ0KIyBEZXNjcmlwY2nDs24gZGUgbGEgZGltZW5zacOzbiAyDQpyZXMuZGVzYyREaW0uMg0KYGBgDQoNCkVuIGxhcyBzYWxpZGEgYW50ZXJpb3JlcywgY3VhbmRvIHNhbGUgYCRxdWFudGlgLCBpbmRpY2EgcmVzdWx0YWRvcyBwYXJhIHZhcmlhYmxlcyBjdWFudGl0YXRpdmFzLiBFcyBpbXBvcnRhbnRlIGRlc3RhY2FyIHF1ZSBsYXMgdmFyaWFibGVzIGVzdMOhbiBvcmRlbmFkYXMgc2Vnw7puIGVsICRwJC12YWxvciBkZSBsYSBjb3JyZWxhY2nDs24uDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRWplbXBsbzogU29sdWNpw7NuIChgZ2V0X3BjYV9pbmRgKSAgDQogIA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYGluZGAgKGdyw6FmaWNvcyBkZSByZXN1bHRhZG9zKQ0KDQoNCkxvcyByZXN1bHRhZG9zIHBhcmEgaW5kaXZpZHVvcyBwdWVkZW4gc2VyIG9idGVuaWRvcyB1dGlsaXphbmRvIGxhIGZ1bmNpw7NuIGBnZXRfcGNhX2luZGAgZGVsIHBhcXVldGUgYGZhY3RvZXh0cmFgLiBEZSBtYW5lcmEgc2ltaWxhciBhIGBnZXRfcGNhX3ZhcmAsIGxhIGZ1bmNpw7NuIGBnZXRfcGNhX2luZGAgcHJvcG9yY2lvbmEgdW5hIGxpc3RhIGRlIG1hdHJpY2VzIHF1ZSBjb250aWVuZW4gdG9kb3MgbG9zIHJlc3VsdGFkb3MgcGFyYSBsb3MgaW5kaXZpZHVvcyAoY29vcmRlbmFkYXMsIGNvcnJlbGFjacOzbiBlbnRyZSB2YXJpYWJsZXMgeSBlamVzLCBjb3Nlbm9zIGFsIGN1YWRyYWRvIHkgY29udHJpYnVjaW9uZXMpLg0KDQpgYGB7cn0NCmluZCA8LSBnZXRfcGNhX2luZChyZXMucGNhKQ0KaW5kDQpgYGANCg0KUGFyYSBhY2NlZGVyIGEgbGFzIGRpZmVyZW50ZXMgY29tcG9uZW50ZXM6IA0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCiMgQ29vcmRlbmFkYXMgZGUgbG9zIGluZGl2aWR1b3MNCmluZCRjb29yZA0KDQojIENhbGlkYWQgZGUgbG9zIGluZGl2aWR1b3MNCmluZCRjb3MyDQoNCiMgQ29udHJpYnVjaW9uZXMgZGUgbG9zIGluZGl2aWR1b3MNCmluZCRjb250cmliDQpgYGANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBpbmRgIChncsOhZmljbyBzaW1wbGUpDQoNCg0KU2UgdXRpbGl6YSBsYSBmdW5jacOzbiBgZnZpel9wY2FfaW5kYCBwYXJhIHByb2R1Y2lyIGVsIGdyw6FmaWNvIGRlIGluZGl2aWR1b3M6IA0KDQpgYGB7cn0NCmZ2aXpfcGNhX2luZChyZXMucGNhLA0KICAgICAgICAgICAgIHRpdGxlPSJJbmRpdmlkdW9zIg0KICAgICAgICAgICAgICkNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBpbmRgOiBncsOhZmljbyBzZWfDum4gYGNvczJgDQoNCg0KU2UgcHVlZGUgY29sb3JlYXIgYSBsb3MgaW5kaXZpZHVvcyBzZWfDum4gc3VzIHZhbG9yZXMgZGUgYGNvczJgIChhbCBpZ3VhbCBxdWUgc2UgaGFjZSBjb24gbGFzIHZhcmlhYmxlcykuDQoNCg0KYGBge3J9DQpmdml6X3BjYV9pbmQocmVzLnBjYSwgY29sLmluZCA9ICJjb3MyIiwNCiAgICAgICAgICAgICBncmFkaWVudC5jb2xzID0gYygiYmx1ZSIsICJicm93biIsICJncmVlbiIpLA0KICAgICAgICAgICAgIHRpdGxlPSJJbmRpdmlkdW9zIGRlIGFjdWVyZG8gYSBjb3MyIiwgDQogICAgICAgICAgICAgcmVwZWw9IFRSVUUgIyBFdml0YSB0cmFzbGFwYW1pZW50byBkZSB0ZXh0b3MNCiAgICAgICAgICAgICApDQpgYGANCk9ic8OpcnZlc2UgcXVlIGVuIGVsIGdyw6FmaWNvLCBsYXMgcGVyc29uYXMgc2ltaWxhcmVzIHNlIGFncnVwYW4ganVudGFzLg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBpbmRgICh0YW1hw7FvIGRlbCBwdW50byBzZWfDum4gYGNvczJgKQ0KDQpTZSBwdWVkZSBhanVzdGFyIHRhbWJpw6luIGVsIHRhbWHDsW8gZGVsIHB1bnRvIGRlIGFjdWVyZG8gYWwgY29zMiBkZSBsb3MgaW5kaXZpZHVvcyBjb3JyZXNwb25kaWVudGVzLg0KDQpgYGB7cn0NCmZ2aXpfcGNhX2luZChyZXMucGNhLCBwb2ludHNpemUgPSAiY29zMiIsDQogICAgICAgICAgICAgcG9pbnRzaGFwZSA9IDIxLCANCiAgICAgICAgICAgICBmaWxsID0gInJlZCIsDQogICAgICAgICAgICAgcmVwZWwgPSBUUlVFICMgRXZpdGEgdHJhc2xhcGFtaWVudG8gZGUgdGV4dG9zDQogICAgICAgICAgICAgKQ0KYGBgDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBpbmRgICh0YW1hw7FvIGRlbCBwdW50byB5IGdyYWRpZW50IHNlZ8O6biBgY29zMmApDQoNClBhcmEgY2FtYmlhciB0YW50byBlbCB0YW1hw7FvIGRsIHB1bnRvIGNvbW8gZWwgY29sb3IgcG9yIGBjb3MyYDoNCg0KYGBge3J9DQpmdml6X3BjYV9pbmQocmVzLnBjYSwgY29sLmluZCA9ICJjb3MyIiwgcG9pbnRzaXplID0gImNvczIiLA0KICAgICAgICAgICAgIGdyYWRpZW50LmNvbHMgPSBjKCJibHVlIiwgImJyb3duIiwgImdyZWVuIiksDQogICAgICAgICAgICAgcmVwZWwgPSBUUlVFICMgRXZpdGEgdHJhc2xhcGFtaWVudG8gZGUgdGV4dG9zDQogICAgICAgICAgICAgKQ0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgaW5kYCAoZGlhZ3JhbWEgZGUgY29udHJpYnVjacOzbiBhIHVuIGNvbXBvbmVudGUpDQoNClBhcmEgZ2VuZXJhciB1biBncsOhZmljbyBkZSBiYXJyYXMgZGUgbGEgY2FsaWRhZCBkZSByZXByZXNlbnRhY2nDs24gKGBjb3MyYCkgZGUgbG9zIGluZGl2aWR1b3MgZW4gZWwgbWFwYSBmYWN0b3JpYWwsIHNlIHB1ZWRlIGVtcGxlYXIgbGEgZnVuY2nDs24gYGZ2aXpfY29zMmAgY29tbyBzZSBoYSBkZXNjcml0byBwcmV2aWFtZW50ZSBwYXJhIGxhcyB2YXJpYWJsZXM6DQoNCmBgYHtyfQ0KZnZpel9jb3MyKHJlcy5wY2EsIGNob2ljZSA9ICJpbmQiKQ0KYGBgDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBpbmRgIChkaWFncmFtYSBkZSBjb250cmlidWNpw7NuIGEgZG9zIGNvbXBvbmVudGVzKQ0KDQpQYXJhIHZpc3VhbGl6YXIgbGEgY29udHJpYnVjacOzbiBkZSBsb3MgaW5kaXZpZHVvcyBhIGxvcyBkb3MgcHJpbWVyb3MgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMsIGVzY3JpYmUgbG8gc2lndWllbnRlOg0KDQpgYGB7cn0NCmZ2aXpfY29udHJpYihyZXMucGNhLCBjaG9pY2UgPSAiaW5kIiwgYXhlcyA9IDE6MikNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBpbmRgIChjb2xvcmVhciBwb3IgdmFyaWFibGUgY29udGludWEpDQoNCkVuIGN1YW50byBhIGxhcyB2YXJpYWJsZXMsIGxvcyBpbmRpdmlkdW9zIHB1ZWRlbiBzZXIgY29sb3JlYWRvcyBzZWfDum4gY3VhbHF1aWVyIHZhcmlhYmxlIGNvbnRpbnVhIHBlcnNvbmFsaXphZGEgZXNwZWNpZmljYW5kbyBlbCBhcmd1bWVudG8gYGNvbC5pbmRgLg0KDQoNCmBgYHtyfQ0KI0dlbmVyYSB1bmEgdmFyaWFibGUgY29udGludWEgYWxlYXRvcmlhIGRlIGxvbmdpdHVkIDIzIA0KIyhsYSBtaXNtYSBsb25naXR1ZCBxdWUgZWwgbsO6bWVybyBkZSBpbmRpdmlkdW9zIGFjdGl2b3MgZW4gZWwgUENBKS4NCnNldC5zZWVkKDEyMykNCm15LmNvbnQudmFyIDwtIHJub3JtKDIzKQ0KDQojIENvbG9yZWFyIGxhcyB2YXJpYWJsZXMgc2Vnw7puIGxhIHZhcmlhYmxlIGNvbnRpbnVhDQpmdml6X3BjYV9pbmQocmVzLnBjYSwgY29sLmluZCA9IG15LmNvbnQudmFyLA0KICAgICAgICAgICAgIGdyYWRpZW50LmNvbHMgPSBjKCJibHVlIiwgImJyb3duIiwgImdyZWVuIiksDQogICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gIlNjYWxlIg0KICAgICAgICAgICAgICkNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBpbmRgIChjb2xvcmVhciBwb3IgZ3J1cG9zKQ0KDQpBcXXDrSBkZXNjcmliaW1vcyBjw7NtbyBjb2xvcmVhciBhIGluZGl2aWR1b3MgcG9yIGdydXBvLiBBZGVtw6FzLCBtb3N0cmFtb3MgY8OzbW8gYWdyZWdhciBlbGlwc2VzIGRlIGNvbmNlbnRyYWNpw7NuIHkgZWxpcHNlcyBkZSBjb25maWFuemEgcG9yIGdydXBvcy4gUGFyYSBlc3RvLCBwYXJhIGVzdGFzIHNlY2Npb25lcywgdXRpbGl6YXJlbW9zIGxvcyBkYXRvcyBgZGF0MmAsIGNvbnN0cnVpZG8gZGUgdGFsIG1hbmVyYSBxdWUgY29udGVuZ2EgbGFzIHZhcmlhYmxlcyBkZSBgZGF0YCB5IGN1YWxxdWllciB2YXJpYWJsZSBjYXRlZ8OzcmljYSAoY29tbywgcG9yIGVqZW1wbG8sIGBHZW5kZXJgLCAgYFNFU2AsIGBFY29ub21pY2AsIGV0YywgbyBncnVwb3MgZ2VuZXJhZG9zIGFsZWF0b3JpYW1lbnRlLg0KDQoNCg0KYGBge3IgZXZhbD1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmRhdDEgPC0gZGF0b3NDb21wbGV0b1sxOjUwLCBdDQpkYXQyIDwtIGRhdG9zQ29tcGxldG9bMTo1MCwgYygyMjoyNSwyODozMCldDQphdHRhY2goZGF0MikNCmhlYWQoZGF0Miw0KSANCmBgYA0KDQoNCg0KYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiNkYXQgPC0gZGF0b3NDb21wbGV0b1sxOjIzLCBjKDUsNyw4LDksMTMsMTUsMjEsMjcsMjksMzApXSAjIHByaW1lciBpbnRlbnRvDQpkYXQxIDwtIGRhdG9zQ29tcGxldG9bMTo1MCwgXQ0KZGF0MiA8LSBkYXRvc0NvbXBsZXRvWzE6NTAsIGMoMjI6MjUsMjg6MzApXQ0KI2RhdDIgPC0gZGF0b3NDb21wbGV0b1ssIGMoMyw0LDYsMTEsMjcsMjgsMjksMzMpXQ0KYXR0YWNoKGRhdDIpDQprYWJsZShoZWFkKGRhdDIsNCksYWxpZ24gPSAiY2NjIikgJT4lIyBTZSBuZWNlc2l0YSBsaWJyYXJ5KGtuaXRyKSANCmthYmxlX3N0eWxpbmcoKSAlPiUgICAgICAgICAgICAgICAgI2xpYnJhcnkoa2FibGVFeHRyYSkuLi4uIFNvbG8gcGFyYSBrbml0IHRvIGh0bWwNCmthYmxlX2NsYXNzaWNfMihmdWxsX3dpZHRoID0gRikgICAjbGlicmFyeShrYWJsZUV4dHJhKS4uLi5Tb2xvIHBhcmEga25pdCB0byBodG1sDQpgYGANCg0KYGBge3J9DQojIFBDQQ0KZGF0Mi5wY2EgPC0gUENBKGRhdDIsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEZBTFNFKQ0KYGBgDQoNCkdlbmVyYXJlbW9zIGxhIHZhcmlhYmxlIGdydXBhbCBjb24gYGttZWFuc2AgeSBsYSBhbmV4YXJlbW9zIGEgbG9zIGRhdG9zIG9yaWdpbmFsZXMuIA0KDQpgYGB7cn0NCiMgQ3JlYXIgMyBjbMO6c3RlciAoY2VudGVycyA9IDMpDQpzZXQuc2VlZCgxMjMpDQpyZXMyLmttIDwtIGttZWFucyhkYXQyLCBjZW50ZXJzID0gMywgbnN0YXJ0ID0gMjUpDQoNCiMgRXh0cmFlciBldGlxdWV0YXMgZGUgbG9zIGNsw7pzdGVyIA0KY2x1c3Rlcl9sYWJlbHMgPC0gcmVzMi5rbSRjbHVzdGVyDQoNCiMgQcOxYWRpciBldGlxdWV0YXMgZGUgbG9zIGNsw7pzdGVyIGEgbG9zIGRhdG9zIG9yaWdpbmFsZXMNCmRhdDEkQ2x1c3RlciA8LSBjbHVzdGVyX2xhYmVscw0KDQpnciA8LSBhcy5mYWN0b3IoZGF0MSRDbHVzdGVyKQ0KZ3JfbmFtZSA8LSAiQ2x1c3RlcnMiDQpgYGANCg0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgaW5kYCAoZWxpcHNlcyBkZSBjb25jZW50cmFjacOzbikNCg0KDQpFbiBlbCBjw7NkaWdvIFIgKHF1ZSBzZSBtdWVzdHJhIGFiYWpvKSwgbG9zIGFyZ3VtZW50b3MgYGhhYmlsbGFnZWAgbyBgY29sLmluZCBzZSBwdWVkZWBuIHV0aWxpemFyIHBhcmEgZXNwZWNpZmljYXIgbGEgdmFyaWFibGUgZGUgZmFjdG9yIHBhcmEgY29sb3JlYXIgYSBsb3MgaW5kaXZpZHVvcyBwb3IgZ3J1cG9zLiBQYXJhIGFncmVnYXIgdW5hIGVsaXBzZSBkZSBjb25jZW50cmFjacOzbiBhbHJlZGVkb3IgZGUgY2FkYSBncnVwbywgZXNwZWNpZmlxdWUgZWwgYXJndW1lbnRvIGBhZGRFbGxpcHNlcyA9IFRSVUVgLiBFbCBhcmd1bWVudG8gYHBhbGxldGVgIHNlIHB1ZWRlIHV0aWxpemFyIHBhcmEgY2FtYmlhciBsb3MgY29sb3JlcyBkZSBsb3MgZ3J1cG9zLg0KDQoNCg0KYGBge3J9DQpmdml6X3BjYV9pbmQoZGF0Mi5wY2EsDQogICAgICAgICAgICAgZ2VvbS5pbmQgPSAicG9pbnQiLCAjIG1vc3RyYXIgc29sbyBwdW50b3MgKG5vICJ0ZXh0byIpDQogICAgICAgICAgICAgY29sLmluZCA9IGdyICAgLCAgICAjIGNvbG9yIHBvciBncnVwb3MNCiAgICAgICAgICAgICBwYWxldHRlID0gYygiYmx1ZSIsICJicm93biIsICJncmVlbiIsICJ5ZWxsb3ciLCAicGluayIpLA0KICAgICAgICAgICAgIGFkZEVsbGlwc2VzID0gVFJVRSwgIyBjb25jZW50cmFjacOzbiBkZSBlbGlwc2VzDQogICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gZ3JfbmFtZQ0KICAgICAgICAgICAgKQ0KYGBgDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYGluZGAgKGVsaXBzZXMgZGUgY29uZmlhbnphKQ0KDQpQYXJhIGVsaW1pbmFyIGVsIHB1bnRvIG1lZGlvIGRlbCBncnVwbywgZXNwZWNpZmlxdWUgZWwgYXJndW1lbnRvIGBtZWFuLnBvaW50ID0gRkFMU0VgLiBTaSBkZXNlYSBlbGlwc2VzIGRlIGNvbmZpYW56YSBlbiBsdWdhciBkZSBlbGlwc2VzIGRlIGNvbmNlbnRyYWNpw7NuLCB1dGlsaWNlIGBlbGxpcHNlLnR5cGUgPSAiY29uZmlkZW5jZSJgLg0KDQoNCmBgYHtyfQ0KIyBBw7FhZGlyIGVsaXBzZXMgZGUgY29uZmlhbnphDQpmdml6X3BjYV9pbmQoZGF0Mi5wY2EsIA0KICAgICAgICAgICAgIGdlb20uaW5kID0gInBvaW50IiwgDQogICAgICAgICAgICAgY29sLmluZCA9IGdyLA0KICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCJibHVlIiwgImJyb3duIiwgImdyZWVuIiksDQogICAgICAgICAgICAgYWRkRWxsaXBzZXMgPSBUUlVFLCANCiAgICAgICAgICAgICBlbGxpcHNlLnR5cGUgPSAiY29uZmlkZW5jZSIsDQogICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gZ3JfbmFtZQ0KICAgICAgICAgICAgICkNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBpbmRgIChlbGlwc2VzOiBtw6FzIHBhbGV0YXMgZGUgY29sb3JlcykNCg0KVMOpbmdhc2UgZW4gY3VlbnRhIHF1ZSBsb3MgdmFsb3JlcyBwZXJtaXRpZG9zIHBhcmEgbGEgcGFsZXRhIGluY2x1eWVuOg0KICANCiAgKyBgImdyZXkiYCBwYXJhIHBhbGV0YXMgZGUgY29sb3JlcyBncmlzZXM7DQogIA0KICArIFBhbGV0YXMgYnJld2VyIGNvbW8gYCJSZEJ1ImAsIGAiQmx1ZXMiYCwgLi4uOyBQYXJhIHZlciB0b2RhcywgZXNjcmliYSBlc3RvIGVuIFI6IGBSQ29sb3JCcmV3ZXI6OmRpc3BsYXkuYnJld2VyLmFsbCgpYC4NCiAgDQogICsgUGFsZXRhIGRlIGNvbG9yZXMgcGVyc29uYWxpemFkYSwgcG9yIGVqZW1wbG8gYGMoImJsdWUiLCAicmVkIilgOw0KICANCiAgKyBQcGFsZXRhcyBkZSByZXZpc3RhcyBjaWVudMOtZmljYXMgZGVsIHBhcXVldGUgYGdnc2NpYC4gUG9yIGVqZW1wbG86IGAibnBnImAsIGAiYWFhcyJgLCBgImxhbmNldCJgLCBgImpjbyJgLCBgInVjc2NnYiJgLCBgInVjaGljYWdvImAsIGAic2ltcHNvbnMiYCB5IGAicmlja2FuZG1vcnR5ImAuDQogDQpQb3IgZWplbXBsbywgY29uIGxhIHBhbGV0YSBgc2ltcHNvbnNgOiANCiAgDQpgYGB7cn0NCmZ2aXpfcGNhX2luZChkYXQyLnBjYSwNCiAgICAgICAgICAgICBsYWJlbCA9ICJub25lIiwgICAgICAgIyBPY3VsdGFyIGxhcyBldGlxdWV0YXMgZGVsb3MgaW5kaXZpZHVvcw0KICAgICAgICAgICAgIGNvbC5pbmQgPSBnciwgICAgICAgICAjIENvbG9yIHBvciBncnVwb3MNCiAgICAgICAgICAgICBhZGRFbGxpcHNlcyA9IFRSVUUsICAgIyBFbGlwc2VzIGRlIGNvbmNlbnRyYWNpw7NuDQogICAgICAgICAgICAgcGFsZXR0ZSA9ICJzaW1wc29ucyIsDQogICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gZ3JfbmFtZQ0KICAgICAgICAgICAgICkNCmBgYA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIEVqZW1wbG86IFNvbHVjacOzbiAocGVyc29uYWxpemFyIGdyw6FmaWNvcykgIA0KICANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIERpbWVuc2lvbmVzIChgYXhlc2ApDQoNClBvciBkZWZlY3RvLCBsYXMgdmFyaWFibGVzL2luZGl2aWR1b3Mgc2UgcmVwcmVzZW50YW4gZW4gbGFzIGRpbWVuc2lvbmVzIDEgeSAyLiBTaSBzZSBkZXNlYSB2aXN1YWxpemFybG9zIGVuIGxhcyBkaW1lbnNpb25lcyAyIHkgMywgcG9yIGVqZW1wbG8sIHNlIGRlYmUgZXNwZWNpZmljYXIgZWwgYXJndW1lbnRvIGBheGVzID0gYygyLCAzKWAuDQoNCg0KYGBge3J9DQojIFZhcmlhYmxlcyBzb2JyZSBsYXMgZGltZW5zaW9uZXMgMiB5IDMNCmZ2aXpfcGNhX3ZhcihyZXMucGNhLCANCiAgICAgICAgICAgICBheGVzID0gYygyLCAzKSwgDQogICAgICAgICAgICAgY29sLnZhciA9ICJyZWQiLA0KICAgICAgICAgICAgIHJlcGVsPVRSVUUpDQoNCiMgSW5kaXZpZHVvcyBzb2JyZSBsYXMgZGltZW5zaW9uZXMgMiB5IDMNCmZ2aXpfcGNhX2luZChyZXMucGNhLCANCiAgICAgICAgICAgICBheGVzID0gYygyLCAzKSwNCiAgICAgICAgICAgICBjb2wuaW5kID0gImRhcmtibHVlIiwNCiAgICAgICAgICAgICByZXBlbD1UUlVFKQ0KYGBgDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgR3JhZmljYXIgZWxlbWVudG9zIChgZ2VvbWApDQoNCioqMS4gQXJndW1lbnRvIGBnZW9tYDoqKg0KDQpFbCBhcmd1bWVudG8gYGdlb21gIChwb3IgZ2VvbWV0csOtYSkgeSBzdXMgZGVyaXZhZG9zIHNlIHV0aWxpemFuIHBhcmEgZXNwZWNpZmljYXIgbG9zIGVsZW1lbnRvcyBnZW9tw6l0cmljb3MgbyBlbGVtZW50b3MgZ3LDoWZpY29zIGEgdXRpbGl6YXIgZW4gbGEgcmVwcmVzZW50YWNpw7NuIGdyw6FmaWNhLg0KDQoqKjIuIEFyZ3VtZW50byBgZ2VvbS52YXJgOioqDQoNCkVzIHVuIHRleHRvIHF1ZSBlc3BlY2lmaWNhIGxhIGdlb21ldHLDrWEgYSB1dGlsaXphciBwYXJhIHJlcHJlc2VudGFyIGxhcyB2YXJpYWJsZXMuIExvcyB2YWxvcmVzIHBlcm1pdGlkb3Mgc29uIGxhIGNvbWJpbmFjacOzbiBkZSBgYyjigJxwb2ludOKAnSwg4oCcYXJyb3figJ0sIOKAnHRleHTigJ0pYDoNCiAgDQogICsgU2UgdXNhIGBnZW9tLnZhciA9IOKAnHBvaW504oCdYCBwYXJhIG1vc3RyYXIgc29sbyBwdW50b3MuDQogIA0KICArIFNlIHVzYSBgZ2VvbS52YXIgPSDigJx0ZXh04oCdYCBwYXJhIG1vc3RyYXIgc29sbyBldGlxdWV0YXMgZGUgdGV4dG8uDQogIA0KICArIFNlIHVzYSBgZ2VvbS52YXIgPSBjKOKAnHBvaW504oCdLCDigJx0ZXh04oCdKWAgcGFyYSBtb3N0cmFyIHRhbnRvIHB1bnRvcyBjb21vIGV0aXF1ZXRhcyBkZSB0ZXh0by4NCiAgDQogICsgU2UgdXNhIGBnZW9tLnZhciA9IGMo4oCcYXJyb3figJ0sIOKAnHRleHTigJ0pYCBwYXJhIG1vc3RyYXIgZmxlY2hhcyB5IGV0aXF1ZXRhcyAocHJlZGV0ZXJtaW5hZG8pLg0KDQoNCmBgYHtyfQ0KIyBNb3N0cmFyIHRhbnRvIHB1bnRvcyBjb21vIGV0aXF1ZXRhcyBkZSB0ZXh0bw0KZnZpel9wY2FfdmFyKHJlcy5wY2EsIA0KICAgICAgICAgICAgIGdlb20udmFyID0gYygicG9pbnQiLCAidGV4dCIpLCANCiAgICAgICAgICAgICBjb2wudmFyID0gInJlZCIsDQogICAgICAgICAgICAgcmVwZWw9VFJVRQ0KICAgICAgICAgICAgICkNCmBgYA0KDQoNCioqMy4gQXJndW1lbnRvIGBnZW9tLmluZGA6KioNCg0KRXMgdW4gdGV4dG8gcXVlIGVzcGVjaWZpY2EgbGEgZ2VvbWV0csOtYSBhIHV0aWxpemFyIHBhcmEgdHJhemFyIGxvcyBpbmRpdmlkdW9zLiBMb3MgdmFsb3JlcyBwZXJtaXRpZG9zIHNvbiBsYSBjb21iaW5hY2nDs24gZGUgYGMoInBvaW50IiwgInRleHQiKS5gDQogIA0KICArIFNlIHVzYSBgZ2VvbS5pbmQgPSAicG9pbnQiYCBwYXJhIG1vc3RyYXIgc29sbyBwdW50b3MuDQogIA0KICArIFNlIHVzYSBgZ2VvbS5pbmQgPSAidGV4dCJgIHBhcmEgbW9zdHJhciBzb2xvIGV0aXF1ZXRhcyBkZSB0ZXh0by4NCiAgDQogICsgU2UgdXNhIGBnZW9tLmluZCA9IGMoInBvaW50IiwgInRleHQiKWAgcGFyYSBtb3N0cmFyIHRhbnRvIHB1bnRvcyBjb21vIGV0aXF1ZXRhcyBkZSB0ZXh0byAocG9yIGRlZmVjdG8pLg0KICANCg0KYGBge3J9DQojIE1vc3RyYXIgc8OzbG8gZXRpcXVldGFzIGRlIHRleHRvIGluZGl2aWR1YWxlcw0KZnZpel9wY2FfaW5kKHJlcy5wY2EsIA0KICAgICAgICAgICAgIGdlb20uaW5kID0gInRleHQiLA0KICAgICAgICAgICAgIGNvbC5pbmQ9ICJkYXJrYmx1ZSIsDQogICAgICAgICAgICAgcmVwZWw9VFJVRSkNCmBgYA0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBUYW1hw7FvIHkgZm9ybWEgKGBsYWJlbGAsIGBhcnJvd2ApDQoNCjEuICpUYW1hw7FvIGRlIGV0aXF1ZXRhKjogdGFtYcOxbyBkZSBsYSBmdWVudGUgcGFyYSBsYXMgZXRpcXVldGFzIGRlIHRleHRvLCBwb3IgZWplbXBsbzogYGxhYmVsc2l6ZSA9IDQuM2AuDQoNCjIuICpUYW1hw7FvIGRlIGZsZWNoYSo6IGVsIHRhbWHDsW8gZGUgbGFzIGZsZWNoYXMuIENvbnRyb2xhIGVsIGdyb3NvciBkZSBsYXMgZmxlY2hhcywgcG9yIGVqZW1wbG86IGBhcnJvd3NpemUgPSAxLjJgLg0KDQozLiAqVGFtYcOxbyBkZSBwdW50byo6IGVsIHRhbWHDsW8gZGUgbG9zIHB1bnRvcywgcG9yIGVqZW1wbG86IGBwb2ludHNpemUgPSAyLjVgLg0KDQo0LiAqRm9ybWEgZGUgcHVudG8qOiBsYSBmb3JtYSBkZSBsb3MgcHVudG9zLCBgcG9pbnRzaGFwZSA9IDEwYC4gU2UgcHVlZGUgZWplY3V0YXIgYGdncHVicjo6c2hvd19wb2ludF9zaGFwZXNgIHBhcmEgdmVyIGxhcyBmb3JtYXMgZGUgcHVudG8gZGlzcG9uaWJsZXMuDQoNCg0KYGBge3J9DQojIENhbWJpYXIgZWwgdGFtYcOxbyBkZWxhcyBmbGVjaGFzIGVuIGxhcyBldGlxdWV0YXMNCmZ2aXpfcGNhX3ZhcihyZXMucGNhLCANCiAgICAgICAgICAgICBsYWJlbHNpemUgPSA0LjMsDQogICAgICAgICAgICAgYXJyb3dzaXplID0gMS4yLCANCiAgICAgICAgICAgICByZXBlbCA9IFRSVUUNCiAgICAgICAgICAgICApDQoNCiMgQ2FtYmlhciBlbCB0YW1hw7FvIGRlIGxvcyBwdW50b3MsIGxhIGZvcm1hIHkgZWwgY29sb3IgZGUgcmVsbGVubw0KIyBDYW1iaWFyIGVsIHRhbWHDsW8gZGUgbGFzIGV0aXF1ZXRhcw0KZnZpel9wY2FfaW5kKHJlcy5wY2EsDQogICAgICAgICAgICAgcG9pbnRzaXplID0gMy41LCANCiAgICAgICAgICAgICBwb2ludHNoYXBlID0gMjAsIA0KICAgICAgICAgICAgIGZpbGwgPSAiZGFya2dyZWVuIiwNCiAgICAgICAgICAgICBsYWJlbHNpemUgPSA0LjMsIA0KICAgICAgICAgICAgIHJlcGVsID0gVFJVRQ0KICAgICAgICAgICAgICkNCmBgYA0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBFbGlwc2VzIChgYWRkRWxsaXBzZXNgKQ0KDQpDb21vIGRlc2NyaWJpbW9zIGVuIHNlY2Npb25lcyBhbnRlcmlvcmVzLCBhbCBjb2xvcmVhciBpbmRpdmlkdW9zIHBvciBncnVwb3MsIHNlIHB1ZWRlIGFncmVnYXIgZWxpcHNlcyBkZSBjb25jZW50cmFjacOzbiBkZSBwdW50b3MgdXNhbmRvIGVsIGFyZ3VtZW50byBgYWRkRWxsaXBzZXMgPSBUUlVFYC4gT2Jzw6lydmVzZSBxdWUgZWwgYXJndW1lbnRvIGBlbGxpcHNlLnR5cGVgIHNlIHB1ZWRlIHV0aWxpemFyIHBhcmEgY2FtYmlhciBlbCB0aXBvIGRlIGVsaXBzZXMuIExvcyB2YWxvcmVzIHBvc2libGVzIHNvbjoNCiAgDQogICsgYCJjb252ZXgiYDogdHJhemEgbGEgZW52b2x2ZW50ZSBjb252ZXhhIGRlIHVuIGNvbmp1bnRvIGRlIHB1bnRvcy4NCiAgDQogICsgYCJjb25maWRlbmNlImA6IHRyYXphIGVsaXBzZXMgZGUgY29uZmlhbnphIGFscmVkZWRvciBkZSBsb3MgcHVudG9zIG1lZGlvcyBkZWwgZ3J1cG8gY29tbyBsYSBmdW5jacOzbiBgY29vcmQuZWxsaXBzZWAgZW4gZWwgcGFxdWV0ZSBgRmFjdG9NaW5lUmAuDQogIA0KICArIGAidCJgOiBhc3VtZSB1bmEgZGlzdHJpYnVjacOzbiAkdCQtbXVsdGl2YXJpYWRhLg0KICANCiAgKyBgIm5vcm0iYDogYXN1bWUgdW5hIGRpc3RyaWJ1Y2nDs24gbm9ybWFsLW11bHRpdmFyaWFkYS4NCiAgDQogICsgYOKAnGV1Y2xpZOKAnWA6IGRpYnVqYSB1biBjw61yY3VsbyBjb24gZWwgcmFkaW8gaWd1YWwgYWwgbml2ZWwsIHJlcHJlc2VudGFuZG8gbGEgZGlzdGFuY2lhIGV1Y2xpZGlhbmEgZGVzZGUgZWwgY2VudHJvLiBFc3RhIGVsaXBzZSBwcm9iYWJsZW1lbnRlIG5vIGFwYXJlY2Vyw6EgY2lyY3VsYXIgYSBtZW5vcyBxdWUgc2UgYXBsaXF1ZSBgY29vcmRfZml4ZWRgLg0KICANCg0KRWwgYXJndW1lbnRvIGBlbGxpcHNlLmxldmVsYCB0YW1iacOpbiBlc3TDoSBkaXNwb25pYmxlIHBhcmEgY2FtYmlhciBlbCB0YW1hw7FvIGRlIGxhIGVsaXBzZSBkZSBjb25jZW50cmFjacOzbiBlbiBsYSBwcm9iYWJpbGlkYWQgbm9ybWFsLiBQb3IgZWplbXBsbywgcHVlZGUgZXNwZWNpZmljYXIgYGVsbGlwc2UubGV2ZWwgPSAwLjk1YCBvIGBlbGxpcHNlLmxldmVsID0gMC42NmAuDQoNCg0KYGBge3J9DQojIEVsaXBzZXMgZGUgY29uZmlhbnphDQpmdml6X3BjYV9pbmQoZGF0Mi5wY2EsIA0KICAgICAgICAgICAgIGdlb20uaW5kID0gInBvaW50IiwNCiAgICAgICAgICAgICBjb2wuaW5kID0gZ3IsICAgIyBDb2xvciBwb3IgZ3J1cG9zDQogICAgICAgICAgICAgcGFsZXR0ZSA9IGMoImJsdWUiLCAiYnJvd24iLCAiZ3JlZW4iKSwNCiAgICAgICAgICAgICBhZGRFbGxpcHNlcyA9IFRSVUUsIA0KICAgICAgICAgICAgIGVsbGlwc2UudHlwZSA9ICJjb25maWRlbmNlIiwNCiAgICAgICAgICAgICBsZWdlbmQudGl0bGUgPSBncl9uYW1lDQogICAgICAgICAgICAgKQ0KDQojIEVudm9sdmVudGUgY29udmV4YQ0KZnZpel9wY2FfaW5kKGRhdDIucGNhLCANCiAgICAgICAgICAgICBnZW9tLmluZCA9ICJwb2ludCIsDQogICAgICAgICAgICAgY29sLmluZCA9IGdyLCAgICMgQ29sb3IgcG9yIGdydXBvcw0KICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCJibHVlIiwgImJyb3duIiwgImdyZWVuIiksDQogICAgICAgICAgICAgYWRkRWxsaXBzZXMgPSBUUlVFLCANCiAgICAgICAgICAgICBlbGxpcHNlLnR5cGUgPSAiY29udmV4IiwNCiAgICAgICAgICAgICBsZWdlbmQudGl0bGUgPSBncl9uYW1lDQogICAgICAgICAgICAgKQ0KYGBgDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgUHVudG9zIG1lZGlvcyBwb3IgZ3J1cG8gKGBtZWFuLnBvaW50YCkNCg0KQ3VhbmRvIHNlIGNvbG9yZWFuIGluZGl2aWR1b3MgcG9yIGdydXBvcyAodmVyIHNlY2Npb25lcyBhbnRlcmlvcmVzKSwgbG9zIHB1bnRvcyBtZWRpb3MgZGUgbG9zIGdydXBvcyAoYmFyaWNlbnRyb3MpIHRhbWJpw6luIHNlIG11ZXN0cmFuIGRlIGZvcm1hIHByZWRldGVybWluYWRhLiBQYXJhIGVsaW1pbmFyIGxvcyBwdW50b3MgbWVkaW9zLCBzZSBwdWVkZSB1dGlsaXphciBlbCBhcmd1bWVudG8gYG1lYW4ucG9pbnQgPSBGQUxTRWAuDQoNCg0KYGBge3J9DQpmdml6X3BjYV9pbmQoZGF0Mi5wY2EsDQogICAgICAgICAgICAgZ2VvbS5pbmQgPSAicG9pbnQiLCAgICAgIyBNdWVzdHJhIHNvbG8gcHVudG9zIChwZXJvIG5vICJ0ZXh0byIpDQogICAgICAgICAgICAgY29sLmluZCA9IGdyLCAgICAgICAgICAgIyBDb2xvciBwb3IgZ3J1cG9zDQogICAgICAgICAgICAgcGFsZXR0ZSA9IGMoImJsdWUiLCAiYnJvd24iLCAiZ3JlZW4iLCAieWVsbG93IiwgInBpbmsiKSwNCiAgICAgICAgICAgICBsZWdlbmQudGl0bGUgPSBncl9uYW1lLA0KICAgICAgICAgICAgIG1lYW4ucG9pbnQgPSBGQUxTRQ0KICAgICAgICAgICAgICkNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIFRpcG8gZGUgbMOtbmVhIChgYXhlcy5saW5ldHlwZWApDQoNCkVsIGFyZ3VtZW50byBgYXhlcy5saW5ldHlwZWAgc2UgcHVlZGUgdXRpbGl6YXIgcGFyYSBlc3BlY2lmaWNhciBlbCB0aXBvIGRlIGzDrW5lYSBkZSBsb3MgZWplcy4gRWwgdmFsb3IgcHJlZGV0ZXJtaW5hZG8gZXMgYCJkYXNoZWQiYCAocmF5YWRvKS4gTG9zIHZhbG9yZXMgcGVybWl0aWRvcyBpbmNsdXllbiBgImJsYW5rImAgKGVuIGJsYW5jbyksIGAic29saWQiYCAoc8OzbGlkbyksIGAiZG90dGVkIiAocHVudGVhZG8pYCwgZXRjLiBQYXJhIHZlciB0b2RvcyBsb3MgdmFsb3JlcyBwb3NpYmxlcywgZXNjcmliYSBgZ2dwdWJyOjpzaG93X2xpbmVfdHlwZXNgLiBQYXJhIGVsaW1pbmFyIGxhcyBsw61uZWFzIGRlIGxvcyBlamVzLCB1dGlsaWNlIGBheGVzLmxpbmV0eXBlID0gImJsYW5rImA6DQoNCg0KYGBge3J9DQpmdml6X3BjYV92YXIocmVzLnBjYSwNCiAgICAgICAgICAgICBheGVzLmxpbmV0eXBlID0gImJsYW5rIiwNCiAgICAgICAgICAgICBjb2wudmFyPSJyZWQiLCANCiAgICAgICAgICAgICByZXBlbD1UUlVFKQ0KYGBgDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgQXBhcmllbmNpYSBncsOhZmljYSAoYGdncGFyYCkNCg0KUGFyYSBjYW1iaWFyIGbDoWNpbG1lbnRlIGxhIGFwYXJpZW5jaWEgZ3LDoWZpY2EgZGUgY3VhbHF1aWVyIGdncGxvdCwgcHVlZGUgdXRpbGl6YXIgbGEgZnVuY2nDs24gYGdncGFyYCBkZWwgcGFxdWV0ZSBgZ2dwdWJyYC4gTG9zIHBhcsOhbWV0cm9zIGdyw6FmaWNvcyBxdWUgc2UgcHVlZGVuIGNhbWJpYXIgdXNhbmRvIGBnZ3BhcmAgaW5jbHV5ZW46DQogIA0KICArIFTDrXR1bG9zIHByaW5jaXBhbGVzLCBldGlxdWV0YXMgZGUgZWplcyB5IHTDrXR1bG9zIGRlIGxleWVuZGEuDQogIA0KICArIFBvc2ljacOzbiBkZSBsYSBsZXllbmRhLiBWYWxvcmVzIHBvc2libGVzOiBgInRvcCJgIChhcnJpYmEpLCBgImJvdHRvbSJgIChhYmFqbyksIGAibGVmdCJgIChpenF1aWVyZGEpLCBgInJpZ2h0YCIgKGRlcmVjaGEpLCBgIm5vbmUiYCAobmluZ3VubykuDQogIA0KICArIFBhbGV0YSBkZSBjb2xvcmVzLg0KICANCiAgKyBUZW1hcy4gTG9zIHZhbG9yZXMgcGVybWl0aWRvcyBpbmNsdXllbjogYHRoZW1lX2dyYXlgLCBgdGhlbWVfYndgLCBgdGhlbWVfbWluaW1hbGAsIGB0aGVtZV9jbGFzc2ljYCwgYHRoZW1lX3ZvaWRgLg0KICANCmBgYHtyfQ0KaW5kLnAgPC0gZnZpel9wY2FfaW5kKGRhdDIucGNhLCANCiAgICAgICAgICAgICAgICAgICAgICBnZW9tID0gInBvaW50IiwgDQogICAgICAgICAgICAgICAgICAgICAgY29sLmluZCA9IGdyDQogICAgICAgICAgICAgICAgICAgICAgKQ0KZ2dwdWJyOjpnZ3BhcihpbmQucCwNCiAgICAgICAgICAgICAgdGl0bGUgPSAiUHJpbmNpcGFsIENvbXBvbmVudCBBbmFseXNpcyIsDQogICAgICAgICAgICAgIHN1YnRpdGxlID0gIlN1cnZleSBkYXRhIHNldCIsDQogICAgICAgICAgICAgIGNhcHRpb24gPSAiU291cmNlOiBmYWN0b2V4dHJhIiwNCiAgICAgICAgICAgICAgeGxhYiA9ICJQQzEiLCANCiAgICAgICAgICAgICAgeWxhYiA9ICJQQzIiLA0KICAgICAgICAgICAgICBsZWdlbmQudGl0bGUgPSBncl9uYW1lLCANCiAgICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsDQogICAgICAgICAgICAgIGdndGhlbWUgPSB0aGVtZV9ncmF5KCksIA0KICAgICAgICAgICAgICBwYWxldHRlID0gImpjbyINCiAgICAgICAgICAgICAgKQ0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRWplbXBsbzogU29sdWNpw7NuIChgYmlwbG90YCkgIA0KICANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgYmlwbG90YCAoZnVuY2nDs24pDQoNClBhcmEgaGFjZXIgdW4gYmlwbG90IHNpbXBsZSBkZSBpbmRpdmlkdW9zIHkgdmFyaWFibGVzOg0KDQpgYGB7cn0NCmZ2aXpfcGNhX2JpcGxvdChyZXMucGNhLCANCiAgICAgICAgICAgICAgICByZXBlbCA9IFRSVUUsDQogICAgICAgICAgICAgICAgY29sLnZhciA9ICJkYXJrYmx1ZSIsICMgQ29sb3IgZGUgbGFzIHZhcmlhYmxlcw0KICAgICAgICAgICAgICAgIGNvbC5pbmQgPSAiZGFya2dyZWVuIiAjIENvbG9yIGRlIGxvcyBpbmRpdmlkdW9zDQogICAgICAgICAgICAgICAgKQ0KYGBgDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYGJpcGxvdGAgKGludGVycHJldGFjaW9uZXMpDQogIA0KICAxLiBFcyBpbXBvcnRhbnRlIHRlbmVyIGVuIGN1ZW50YSBxdWUgZWwgYmlwbG90IHB1ZWRlIHNlciDDunRpbCBzb2xvIGN1YW5kbyBoYXkgdW4gYmFqbyBuw7ptZXJvIGRlIHZhcmlhYmxlcyBlIGluZGl2aWR1b3MgZW4gZWwgY29uanVudG8gZGUgZGF0b3M7IGRlIGxvIGNvbnRyYXJpbywgZWwgZ3LDoWZpY28gZmluYWwgc2Vyw61hIGlsZWdpYmxlLiANCiAgDQogIDIuIEFkZW3DoXMsIGxhcyBjb29yZGVuYWRhcyBkZSBsb3MgaW5kaXZpZHVvcyB5IGxhcyB2YXJpYWJsZXMgbm8gZXN0w6FuIGNvbnN0cnVpZGFzIGVuIGVsIG1pc21vIGVzcGFjaW8uIA0KICAzLiBQb3IgbG8gdGFudG8sIGVuIHByaW5jaXBpbywgZW4gdW4gYmlwbG90LCBkZWJlcsOtYSBjZW50cmFydGUgcHJpbmNpcGFsbWVudGUgZW4gbGEgZGlyZWNjacOzbiBkZSBsYXMgdmFyaWFibGVzIHkgbm8gZW4gc3VzIHBvc2ljaW9uZXMgYWJzb2x1dGFzIGVuIGVsIGdyw6FmaWNvLiANCiAgDQogIDQuICBjb24gcmVzcGVjdG8gYSBsYXMgb2JzZXJ2YWNpb25lcyBhbnRlcmlvcmVzLCBleGlzdGUgdW5hIHTDqWNuaWNhIG11bHRpdmFyaWFudGUgcXVlIHNlIGxsYW1hIGBISl9iaXBsb3RgIHkgcXVlIHJlc3VlbHZlIGVsIHRlbWEgZGVsIGVzcGFjaW8gZGltZW5zaW9uYWwuIEVuIFIsIHNlIHZpc3VhbGl6YXIgYSB0cmF2w6lzIGRlbCBwYXF1ZXRlIFtMREFCaXBsb3RzOiBCaXBsb3QgR3JhcGhpY2FsIEludGVyZmFjZSBmb3IgTERBIE1vZGVsc10oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL0xEQUJpcGxvdHMvKS4gDQogIA0KRGUgbWFuZXJhIGdlbmVyYWwsIHVuIGJpcGxvdCBzZSBwdWVkZSBpbnRlcnByZXRhciBjb21vIHNlIGV4cGxpY2EgZW4gbG9zIGNvbWVudGFyaW9zIDUgeSA2OiANCiAgDQogIDUuIFVuIGluZGl2aWR1byBxdWUgc2UgZW5jdWVudHJhIGVuIGVsIG1pc21vIGxhZG8gZGUgdW5hIHZhcmlhYmxlIGRhZGEgdGllbmUgdW4gdmFsb3IgYWx0byBwYXJhIGVzdGEgdmFyaWFibGUuDQogICAgDQogIDYuIFVuIGluZGl2aWR1byBxdWUgc2UgZW5jdWVudHJhIGVuIGVsIGxhZG8gb3B1ZXN0byBkZSB1bmEgdmFyaWFibGUgZGFkYSB0aWVuZSB1biB2YWxvciBiYWpvIHBhcmEgZXN0YSB2YXJpYWJsZS4gDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQogIA0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgYmlwbG90YCAoY29tYmluYW5kbyBvcGNpb25lcykNCg0KQWhvcmEsIHV0aWxpemFuZG8gbGEgc2FsaWRhIGRhdDIucGNhLCB2YW1vcyBhOg0KICANCiAgKyBDcmVhciB1biBiaXBsb3QgZGUgaW5kaXZpZHVvcyB5IHZhcmlhYmxlcy4NCiAgDQogICsgQ2FtYmlhciBlbCBjb2xvciBkZSBsb3MgaW5kaXZpZHVvcyBwb3IgZ3J1cG9zIChxdWUgc2Vyw61hIGBncmApOiBgY29sLmluZCA9IGdyYC4NCiAgDQogICsgTW9zdHJhciBzb2xvIGxhcyBldGlxdWV0YXMgcGFyYSB2YXJpYWJsZXM6IGBsYWJlbCA9ICJ2YXIiYCBvIHVzYXIgYGdlb20uaW5kID0gInBvaW50ImAuDQogIA0KDQoNCmBgYHtyfQ0KZnZpel9wY2FfYmlwbG90KGRhdDIucGNhLA0KICAgICAgICAgICAgICAgIGNvbC5pbmQgPSBnciwNCiAgICAgICAgICAgICAgICBwYWxldHRlID0gImpjbyIsDQogICAgICAgICAgICAgICAgYWRkRWxsaXBzZXMgPSBUUlVFLCANCiAgICAgICAgICAgICAgICBsYWJlbCA9ICJ2YXIiLA0KICAgICAgICAgICAgICAgIGNvbC52YXIgPSAiYmxhY2siLCANCiAgICAgICAgICAgICAgICByZXBlbCA9IFRSVUUsDQogICAgICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gIkdlbmRlciINCiAgICAgICAgICAgICAgICApDQpgYGANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBiaXBsb3RgIChpbmRpdmlkdW9zIHkgdmFyaWFibGVzIHBvciBncnVwbykNCg0KRW4gZWwgc2lndWllbnRlIGVqZW1wbG8sIHF1ZXJlbW9zIGNvbG9yZWFyIHRhbnRvIGEgaW5kaXZpZHVvcyBjb21vIHZhcmlhYmxlcyBwb3IgZ3J1cG9zLiBFbCB0cnVjbyBjb25zaXN0ZSBlbiB1dGlsaXphciBgcG9pbnRzaGFwZSA9IDIxYCBwYXJhIGxvcyBwdW50b3MgaW5kaXZpZHVhbGVzLiBFc3RhIGZvcm1hIGRlIHB1bnRvIGVuIHBhcnRpY3VsYXIgcHVlZGUgc2VyIHJlbGxlbmFkYSBwb3IgdW4gY29sb3IgdXNhbmRvIGVsIGFyZ3VtZW50byBgZmlsbC5pbmRgLiBFbCBjb2xvciBkZSBsYSBsw61uZWEgZGUgYm9yZGUgZGUgbG9zIHB1bnRvcyBpbmRpdmlkdWFsZXMgc2UgZXN0YWJsZWNlIGVuIGAiYmxhY2siYCB1c2FuZG8gYGNvbC5pbmRgLiBQYXJhIGNvbG9yZWFyIGxhcyB2YXJpYWJsZXMgcG9yIGdydXBvcywgc2UgdXRpbGl6YXLDoSBlbCBhcmd1bWVudG8gYGNvbC52YXJgLiBQYXJhIHBlcnNvbmFsaXphciBsb3MgY29sb3JlcyBkZSBpbmRpdmlkdW9zIHkgdmFyaWFibGVzLCB1dGlsaXphbW9zIGxhcyBmdW5jaW9uZXMgYXV4aWxpYXJlcyBgZmlsbF9wYWxldHRlYCB5IGBjb2xvcl9wYWxldHRlYCBlbiBlbCBwYXF1ZXRlIGBnZ3B1YnJgLg0KDQoNCg0KYGBge3J9DQojTXlWYXJzIDwtIGZhY3RvcihjKCJTZW1BY3VtIiwiRXhhbTEiLCJFeGFtMiIsIkV4YW0zIiwiRXhhbTQiLCJFeGFtQWN1bSIsIkRlZmluaXRpdmUiLCJFeHBlbnNlIiwiSW5jb21lIiwiR2FzIikpDQpNeVZhcnMgPC0gZmFjdG9yKGMoIkV4YW0iLCJFeGFtIiwiRXhhbSIsIkV4YW0iLCJFeHBlbnNlIiwiSW5jb21lIiwiR2FzIikpDQoNCmZ2aXpfcGNhX2JpcGxvdChkYXQyLnBjYSwNCiMgTExlbmFuZG8gaW5kaXZpZHVvcyBwb3IgZ3J1cG9zDQpnZW9tLmluZCA9ICJwb2ludCIsDQpwb2ludHNoYXBlID0gMjEsDQpwb2ludHNpemUgPSAyLjUsDQpmaWxsLmluZCA9IGdyLA0KY29sLmluZCA9ICJibGFjayIsDQoNCiMgQ29sb3IgZGUgbGFzIHZhcmlhYmxlcyBwb3IgZ3J1cG9zDQpjb2wudmFyID0gTXlWYXJzLA0KbGVnZW5kLnRpdGxlID0gbGlzdChmaWxsID0gZ3JfbmFtZSwgY29sb3IgPSAiVmFyaWFibGVzIiksDQpyZXBlbCA9IFRSVUUgDQopKw0KICANCmdncHVicjo6ZmlsbF9wYWxldHRlKCJqY28iKSsgIyBDb2xvciBkZSBsb3MgaW5kaXZpZHVvcw0KICANCmdncHVicjo6Y29sb3JfcGFsZXR0ZSgibnBnIikgIyBDb2xvciBkZSBsYXMgdmFyaWFibGVzDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgYmlwbG90YCAob3BjaW9uZXMgbcOhcyBjb21wbGVqYXMpDQoNClVuIGVqZW1wbG8gbcOhcyBjb21wbGVqbyBjb25zaXN0ZSBlbiBhc2lnbmFyIGNvbG9yZXMgYSBsb3MgaW5kaXZpZHVvcyBzZWfDum4gbG9zIGdydXBvcyBhIGxvcyBxdWUgcGVydGVuZWNlbiAoY29sb3JlcyBkaXNjcmV0b3MpIHkgYSBsYXMgdmFyaWFibGVzIHNlZ8O6biBzdXMgY29udHJpYnVjaW9uZXMgYSBsb3MgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMgKGNvbG9yZXMgZW4gZGVncmFkYWRvKS4gQWRlbcOhcywgY2FtYmlhcmVtb3MgbGEgdHJhbnNwYXJlbmNpYSBkZSBsYXMgdmFyaWFibGVzIHNlZ8O6biBzdXMgY29udHJpYnVjaW9uZXMgdXRpbGl6YW5kbyBlbCBhcmd1bWVudG8gYWxwaGEudmFyLg0KDQoNCmBgYHtyfQ0KZnZpel9wY2FfYmlwbG90KGRhdDIucGNhLA0KICAgICAgICAgICAgICAgICMgSW5kaXZpZHVvcw0KICAgICAgICAgICAgICAgIGdlb20uaW5kID0gInBvaW50IiwNCiAgICAgICAgICAgICAgICBmaWxsLmluZCA9IGdyLCANCiAgICAgICAgICAgICAgICBjb2wuaW5kID0gImJsYWNrIiwNCiAgICAgICAgICAgICAgICBwb2ludHNoYXBlID0gMjEsIA0KICAgICAgICAgICAgICAgIHBvaW50c2l6ZSA9IDIsDQogICAgICAgICAgICAgICAgcGFsZXR0ZSA9ICJqY28iLA0KICAgICAgICAgICAgICAgIGFkZEVsbGlwc2VzID0gVFJVRSwNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAjIFZhcmlhYmxlcw0KICAgICAgICAgICAgICAgIGFscGhhLnZhciA9ImNvbnRyaWIiLCANCiAgICAgICAgICAgICAgICBjb2wudmFyID0gImNvbnRyaWIiLA0KICAgICAgICAgICAgICAgIHJlcGVsPVRSVUUsDQogICAgICAgICAgICAgICAgZ3JhZGllbnQuY29scyA9ICJhYWFzIiwNCiAgICAgICAgICAgICAgICBsZWdlbmQudGl0bGUgPSBsaXN0KGZpbGwgPSBncl9uYW1lLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gIkNvbnRyaWIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxwaGEgPSAiQ29udHJpYiIpDQogICAgICAgICAgICAgICAgKQ0KYGBgDQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBUw7NwaWNvcyBzdW1wbGVtZW50YXJpb3MgDQoNCg0KDQpbTm8gaGFjZXIgY2xpY2sgYXF1w61dKE9KT0pPSk8pOiBQZW5kaWVudGUNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBDYXDDrXR1bG8gRWplcmNpY2lvcyAtLT4NCg0KIyBFamVyY2ljaW9zDQoNCmBgYHtyIGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0V9DQojIEVuIGVsIGxpYnJvIFIyMDI1IFplbHRlcm1hbiwgcGFnaW5hIDIxNCB5IDIxNywgaGF5IDIgZWplbXBsb3MgcXVlIG5vIGhlIHV0aWxpemFkbw0KDQojIEVuIGVsIGxpYnJvIFIyMDI1IFplbHRlcm1hbiwgIHBhZ2luYSAyMjMsIGhheSBtdWNob3MgZWplcmNpY2lvcyBxdWUgbm8gaGUgdXRpbGl6YWRvDQoNCiMgVmVyIGxpYnJvIGRlIEdpZ2FwZWRpYSAtLT4gTXVsdGl2YXJpYWRvIC0tPiBmYWN0b3JpYWwtLT4gUjIwMTUgUGFnZXMtTXVsdGlwbGUgRmFjdG9yIEFuYWx5c2lzIGJ5IEV4YW1wbGUgVXNpbmcgUjogIA0KICAgICAjZGF0b3MgQmFjY2FsYXVyZWF0ZSBkZSBGYWN0b01pbmVSDQpgYGANCg0KDQpgYGB7ciBldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQ0KbGlicmFyeShGYWN0b01pbmVSKQ0KQmFjY2FsYXVyZWF0ZQ0KYGBgDQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIEVqZXJjaWNpbyAxDQoNCmBgYHtyIGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0V9DQojIEVqZW1wbG8gMi42LjEuIGRlbCBsaWJybyBkZSBNYXJ0w61uIETDrWF6LCBwYWdpbmEgNTENCmBgYA0KDQpTdXBvbmdhbW9zIHF1ZSBzZSB0aWVuZW4gNiBvYnNlcnZhY2lvbmVzICR4XzEsIFxsZG90cywgeF82JCBlbiBkb3MgZGltZW5zaW9uZXMsIGNhZGEgb2JzZXJ2YWNpw7NuIGNvcnJlc3BvbmRlDQphIHVuIHJlY3TDoW5ndWxvIHkgbGFzIHZhcmlhYmxlcyBzb24gbG9uZ2l0dWQgZGUgbGEgYmFzZSB5IGxhIGFsdHVyYSBkZWwgcmVjdMOhbmd1bG8gKHbDqWFzZSBsYSBmaWd1cmEgXEByZWYoZmlnOlJlY3Rhbmd1bG8xKSkuIA0KDQo8Y2VudGVyPg0KYGBge3IgUmVjdGFuZ3VsbzEsIGVjaG89RkFMU0UsIGZpZy5jYXAgPSAiKipSZWN0w6FuZ3VsbyoqIiwgb3V0LndpZHRoID0gIjUwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJSZWN0YW5ndWxvMS5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPg0KDQpMYSBtYXRyaXogZGUgZGF0b3MgZXM6IA0KDQokJFhcOyA9XDsgIFxiZWdpbntwbWF0cml4fQ0KIDIuMCAmIDIuMFxcIA0KIDEuNSYgMC41IFxcIA0KMC43ICYgMC41XFwgDQowLjUgJiAxLjVcXCANCiAwLjUmIDAuN1xcIA0KMC43ICYgMC43DQpcZW5ke3BtYXRyaXh9JCQNCg0KDQpDb24gZXN0b3MgZGF0b3MsIGhhbGxlOiANCg0KKGEpIExhIG1hdHJpeiAkWT0gXGxvZyAoWCkkIChsb2dhcml0bW8gY29uIGJhc2UgMTApLiBFcyBkZWNpciwgYXBsaXF1ZSBlbCBsb2dhcml0bW8gdGVuaWVuZG8gZW4gY3VlbnRhIGNhZGEgdW5hIGRlIGxhcyBjb21wb25lbnRlcyB5IGRlZmluYSBsYSBtYXRyaXogcmVzdWx0YW50ZSBjb21vICRZJC4NCg0KKGIpIExhIG1hdHJpeiAkUyQgZGUgdmFyaWFuemFzLWNvdmFyaWFuemFzIGRlICRZJC4NCg0KKGMpIExvcyB2YWxvcmVzICRcbGFtYmRhX2kkIHkgdmVjdG9yZXMgJHZfaSQgcHJvcGlvcyAgZGUgJFMkLg0KDQooZCkgTGFzIGRvcyBjb21wb25lbnRlcyAkRl8xJCB5ICRGXzIkIGV2YWx1YWRhcyBlbiBsb3Mgc2VpcyByZWN0w6FuZ3Vsb3MuIFJlY3VlcmRlIHF1ZSBjYWRhIGNvbXBvbmVudGUgICRGX2kkIHNlcsOhIHVuIHZlY3RvciBkZSBsYSBtaXNtYSBsb25naXR1ZCBkZSAkWV9pJCB5IHNlIGNhbGN1bGFyw6EgYXPDrTogDQokJEZfaSBcOz0gXDsgWSB2X2kkJA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQojIyMgRWplcmNpY2lvIDINCg0KYGBge3IgZXZhbD1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRX0NCiMgRWplbXBsbyAyLjYuMi4gZGVsIGxpYnJvIGRlIE1hcnTDrW4gRMOtYXosIHBhZ2luYSA1Mw0KYGBgDQoNCg0KTGFzIGN1YXRybyBub3RhcyBwYXJjaWFsZXMgZGUgdW4gZGV0ZXJtaW5hZG8gY3Vyc28gZW4gdW5hIHByZXN0aWdpb3NhICB1bml2ZXJzaWRhZCBzZSBtdWVzdHJhbiBlbiBsYSB0YWJsYSBkZSBhYmFqbywgZW4gZWwgb3JkZW4NCmFsZmFiw6l0aWNvIHBvciBhcGVsbGlkb3MgZGUgbG9zIGVzdHVkaWFudGVzLiBFbCBvYmpldGl2byBlcyBzYWJlciBzaSBleGlzdGUgYWxnw7puIHRpcG8gZGUgb3JkZW5hY2nDs24gZGUgbG9zIGVzdHVkaWFudGVzIGRlIGVzdGUgZ3J1cG8sIGRpc3RpbnRvIGFsIGRlIHByb21lZGlhciBsYXMgbm90YXMgZGUgZXN0b3MgZXN0dWRpYW50ZXMuIEFwbGlxdWUgUENBIHBhcmEgZGV0ZXJtaW5hciBlc3RvLiANCg0KKipTdWdlcmVuY2lhOioqIA0KDQooYSkgSGFsbGUgbG9zIHZhbG9yZXMgZGUgbGFzIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzIHBhcmEgbGFzIG5vdGFzIGRlIGxvcyAzMyBlc3R1ZGlhbnRlcy4gDQoNCihiKSBPcmRlbmUgZW4gZm9ybWEgZGVzY2VuZGVudGUgZXN0b3MgcmVzdWx0YWRvcyBwb3IgbGEgcHJpbWVyYSBjb21wb25lbnRlIHByaW5jaXBhbC4gDQoNCihjKSBDb21wYXJlIGVzdG9zIHJlc3VsdGFkb3MgY29uIGxvcyBvYnRlbmlkb3MgZW4gbGEgbm90YSBkZWZpbml0aXZhLiANCg0KDQpgYGB7cn0NCmlkID0gMTozMw0KUDEgPSBjKDIuMzAsIDMuNTAsIDQuMTAsIDUuMDAsIDIuNzAsIDIuNzAsIDIuOTAsIDIuNDAsIDMuMjAsIDMuODAsIDQuOTAsIDQuNTAsIDIuNzAsIDIuOTAsIDIuNzAsIDIuNzAsIDIuOTAsIDMuMDAsIDMuMTAsIDMuNTAsIDMuNTAsIDIuNzAsIDIuOTAsIDMuMDAsIDIuNzAsIDMuNTAsIDUuMDAsIDQuOTAsIDMuNjAsIDMuMDAsIDMuMTAsIDQuNzAsIDMuMDApDQpQMiA9IGMoMy40MCwgMy4zMCwgNC4xMCwgMy4wMCwgMi41MCwgMy4yMCwgMi44MCwgMi44MCwgMy4yMCwgMi44MCwgNC44MCwgMi44MCwgMi44MCwgMi44MCwgMi44MCwgMi42MCwgMy4zMCwgMi44MCwgMi44MCwgMi45MCwgMi42MCwgMi44MCwgMi44MCwgMi45MCwgMy40MCwgMy4wMCwgMy41MCwgMy4yMCwgMi45MCwgMi44MCwgMi44MCwgNS4wMCwgMi45MCkNClAzID0gYygyLjkwLCAzLjUwLCA0LjUwLCA0LjAwLCAyLjcwLCA0LjQwLCAyLjgwLCAyLjUwLCAyLjAwLCAzLjAwLCA1LjAwLCA0LjUwLCAyLjUwLCAyLjgwLCAyLjgwLCAyLjYwLCAzLjAwLCAyLjgwLCAyLjgwLCAzLjUwLCA0LjMwLCAyLjAwLCAyLjUwLCAyLjUwLCAgMi4wMCwgNC4wMCwgNC45MCwgMi44MCwgMi4wMCwgMy45MCwgMi4wMCwgMy44MCwgMy4zMCkNClA0ID0gYygzLjMwLCAzLjAwLCAzLjcwLCAzLjAwLCAzLjAwLCAzLjMwLCAzLjUwLCAzLjUwLCAzLjkwLCAzLjUwLCAzLjAwLCAzLjAwLCAyLjkwLCAzLjUwLCAzLjAwLCAyLjgwLCAyLjgwLCAzLjQwLCAzLjMwLCAzLjUwLCAzLjUwLCAzLjYwLCAzLjAwLCAyLjgwLCAzLjAwLCAzLjAwLCAzLjAwLCAzLjUwLCA0LjAwLCAzLjUwLCAzLjYwLCAzLjAwLCAyLjgwKQ0KRGVmID0gYygyLjk4LCAzLjMzLCA0LjEwLCAzLjc1LCAyLjczLCAzLjQwLCAzLjAwLCAyLjgwLCAzLjA4LCAzLjI4LCA0LjQzLCAzLjcwLCAyLjczLCAzLjAwLCAyLjgzLCAyLjY4LCAzLjAwLCAzLjAwLCAzLjAwLCAzLjM1LCAzLjQ4LCAyLjc4LCAyLjgwLCAyLjgwLCAyLjc4LCAzLjM4LCA0LjEwLCAzLjYwLCAzLjEzLCAzLjMwLCAyLjk4LCA0LjEzLCAzLjAwKQ0KYGBgDQoNCg0KYGBge3J9DQpkYXRvcyA8LSBkYXRhLmZyYW1lKGlkLCBQMSwgUDIsIFAzLCBQNCwgRGVmKQ0KcHJpbnQoZGF0b3MpDQpgYGANCg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoNCiMjIyBFamVyY2ljaW8gMw0KDQpgYGB7ciBldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQ0KIyBzZWNjacOzbiA4LjIuIGRlbCBsaWJybyBSMjAyNSBaZWx0ZXJtYW4sIHBhZ2luYSAyMTANCmBgYA0KDQpDb25zaWRlcmUgbGEgcmVjb21lbmRhY2nDs24gZGUgaW52ZXJzacOzbiBxdWUgYXBhcmVjZW4gZW4gbGEgdGFibGEgZGUgbGEgZmlndXJhIFxAcmVmKGZpZzpGaWd1cmFFamVyY2ljaW8zKS4gQ2FkYSBlbXByZXNhIGRlIGdlc3Rpw7NuIGZpbmFuY2llcmEgdGllbmUgdW4gY29uanVudG8gZGUgcG9yY2VudGFqZXMgcmVjb21lbmRhZG9zIGVuIGNhZGEgdW5vIGRlIGxvcyBvY2hvIHRpcG9zIGRlIGludmVyc2nDs24gZGlmZXJlbnRlcy4NCkVzdG9zIHN1bWFuIDEwMCUsIHBvciBsbyBxdWUgZWwgb2JqZXRpdm8gZGVsIGVqZXJjY2lvIGVzIGVuY29udHJhciB1biByZXN1bWVuIGRlIGRhdG9zIGRlIG1lbm9yIGRpbWVuc2nDs24gcXVlIHJlcHJlc2VudGUgZGljaGEgaW5mb3JtYWNpw7NuLg0KDQoNCmBgYHtyfQ0KIyBDcmVhciBlbCBkYXRhIGZyYW1lIGNvbiBsb3MgZGF0b3MgcHJvcG9yY2lvbmFkb3MNCg0KTWFuYWdlciA9IGMoIkFsbGlhbmNlIEJlcm5zdGVpbiIsICJBdGxhbnRpYyBUcnVzdCIsICJCYW5rIG9mIEFtZXJpY2EiLCAiQk5ZIE1lbGxvbiIsICJCZXNzZW1lciIsICJCcm93biBBZHZpc29yeSIsICJDaXRpIFByaXZhdGUgQmFuayIsICJDb25zdGVsbGF0aW9uIiwgIkRldXRzY2hlIEJhbmsiLCAiRmlkZWxpdHkiLCAiRmlkdWNpYXJ5IFRydXN0IiwgIkZpZnRoIFRoaXJkIEJhbmsiLCJHZW5TcHJpbmciLCAiR2xlbm1lZGUiLCAiSGFycmlzIFByaXZhdGUgQmFuayIsICJIaWdobW91bnQgQ2FwaXRhbCIsICJKYW5uZXkgTW9udGdvbWVyeSIsICJKUE1vcmdhbiIsICJMZWdnIE1hc29uIiwgIk5vcnRoZXJuIFRydXN0IiwgIlBOQyBBc3NldCBNZ210IiwgIkNoYXJsZXMgU2Nod2FiIiwgIlN1blRydXN0IiwiVUJTIiwgIlVTIEJhbmsiLCAiV2VsbHMgRmFyZ28iLCAiV2lsbWluZ3RvbiBUcnVzdCIpDQpTX1VTID0gYyg0NSwgMjgsIDUzLCAyNiwgMTksIDI5LCAxOCwgMjAsIDI5LCA0MCwgNDAsIDI4LCAxMywgMzUsIDU0LCAyNSwgNDcsIDIwLCA1NSwgMjQsIDQwLCAyOSwgMjYsIDMyLCA0MywgMjcsIDI3KQ0KU19Ob25fVVMgPSBjKDMsIDYsIDksIDksIDksIDEzLCAyNywgMTAsIDE0LCAxNCwgMTAsIDksIDgsIDEyLCAxMCwgNSwgNCwgOSwgMywgOCwgOCwgMjAsIDYsIDEwLCAxNiwgMTMsIDExKQ0KU19EZXYgPSBjKDE3LCA5LCAzLCAxMCwgMywgMTIsIDMsIDEwLCA2LCA0LCAxMywgNywgNSwgNSwgNCwgMTAsIDQsIDUsIDcsIDUsIDIsIDUsIDUsIDcsIDcsIDUsIDQpDQpCX1VTID0gYygzNSwgMzAsIDI4LCAzMCwgMjAsIDE5LCAxOCwgMjUsIDI5LCAzNSwgMzEsIDM2LCAxOCwgMTgsIDE4LCA0MCwgMjYsIDIyLCAxNywgMzEsIDMwLCAyOSwgMjUsIDI3LCAyMSwgMjEsIDMxKQ0KQl9Ob25fVVMgPSBjKDAsIDMsIDEsIDAsIDQsIDMsIDE2LCA1LCAyLCAyLCAwLCAwLCA4LCAyLCAwLCA1LCA0LCAzLCAwLCAwLCAwLCAxLCA3LCA2LCAzLCA0LCAxKQ0KQl9EZXYgPSBjKDAsIDAsIDEsIDAsIDUsIDAsIDEsIDAsIDQsIDAsIDAsIDAsIDAsIDMsIDAsIDAsIDUsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDIsIDApDQpBbHRlcm5hdGl2ZSA9IGMoMCwgMjQsIDAsIDI1LCAzNCwgMjAsIDE3LCAzMCwgMTcsIDYsIDUsIDE1LCA0NSwgMjMsIDE1LCAxNSwgMTAsIDM4LCAxNSwgMzIsIDIwLCAxMSwgMzAsIDE3LCAxMCwgMjgsIDI3KQ0KQ2FzaCA9IGMoMCwgMCwgNSwgMCwgNiwgNCwgMCwgMCwgMiwgMCwgMiwgNSwgNSwgMiwgMCwgMCwgMCwgMywgMywgMCwgMCwgNSwgMywgMiwgMCwgMCwgMCkNCg0KIyBDcmVhciBlbCBkYXRhIGZyYW1lDQppbnZlc3QgPC0gZGF0YS5mcmFtZShNYW5hZ2VyLCBTX1VTLCBTX05vbl9VUywgU19EZXYsIEJfVVMsIEJfTm9uX1VTLCBCX0RldiwgQWx0ZXJuYXRpdmUsIENhc2gpDQoNCmBgYA0KDQo8Y2VudGVyPg0KYGBge3IgRmlndXJhRWplcmNpY2lvMywgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKkFzaWduYWNpb25lcyBkZSBpbnZlcnNpw7NuIHJlY29tZW5kYWRhcyAoZW4gJSkgcG9yIGxhcyBlbXByZXNhcyBkZSBnZXN0acOzbiBmaW5hbmNpZXJhcyBhIHByaW5jaXBpb3MgZGUgMjAxMSoqIiwgb3V0LndpZHRoID0gIjcwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJUYWJsYTFfNV9wMjEwX1IyMDE1X1plbHRlcm1hbi5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPg0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCg0KIyMjIEVqZXJjaWNpbyA0DQoNCmBgYHtyIGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0V9DQojIHNlY2Npw7NuIDguMS4gZGVsIGxpYnJvIFIyMDI1IFplbHRlcm1hbiwgcGFnaW5hIDIyMw0KYGBgDQoNCkNvbnNpZGVyZSBudWV2YW1lbnRlIGxvcyBkYXRvcyBkZWwgZWplcmNpY2lvIGFudGVyaW9yLiANCg0KKGEpIEhhZ2EgdW4gYmlwbG90IGRlIGxhcyBkb3MgcHJpbWVyYXMgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMgZGUgcmVjb21lbmRhY2lvbmVzIGRlIGludmVyc2nDs24uIE9ic2VydmUgcXVlIExlZ2cgTWFzb24gKExNKSB5DQpIYXJyaXMgKEhQQikgYXBhcmVjZW4gZW4gbGEgcGFydGUgc3VwZXJpb3IgeSBIaWdobW91bnQgKEhDKSBlbiBsYSBpbmZlcmlvciBhYmFqbyAocG9yIGxvIG1lbm9zIGEgbcOtIG1lIGFwYXJlY2UgYXPDrSkuIMK/QSBxdcOpIHNlIGRlYmU/IMK/UXXDqSByZXByZXNlbnRhIGVsIHNlZ3VuZG8gY29tcG9uZW50ZSBwcmluY2lwYWwgZWwgZWplIHZlcnRpY2FsPw0KDQooYikgSGFsbGUgbG9zIHZhbG9yZXMgcHJvcGlvcyB5IGxvcyB2ZWN0b3JlcyBwcm9waW9zIGRlIGxhIG1hdHJpeiBkZSBjb3JyZWxhY2nDs24gZGUgbG9zIGRhdG9zIGRlIHJlY29tZW5kYWNpw7NuIGRlIGludmVyc2nDs24uIA0KDQooYykgTXVlc3RyZSBxdWUgbG9zIHZlY3RvcmVzIHByb3Bpb3MgcmVwcmVzZW50YW4gbGFzIHZhcmlhbnphcyBkZSBsb3MgY29tcG9uZW50ZXMgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMgZGUgbGEgbWF0cml6IGRlIGNvcnJlbGFjaW9uZXMgeSB2ZXJpZmlxdWUgcXVlIHNvbiBpZ3VhbGVzIGEgbG9zIHZhbG9yZXMgb2J0ZW5pZG9zIGRlIGxvcyBjb21wb25lbnRlcyBwcmluY2lwYWxlcy4NCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIEVqZXJjaWNpbyA1DQoNCmBgYHtyIGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0V9DQojIHNlY2Npw7NuIDguMy4gZGVsIGxpYnJvIFIyMDI1IFplbHRlcm1hbiwgcGFnaW5hIDIyNQ0KIyBMb3MgZGF0b3Mgc29uIHV0aWxpemFkb3MgZW4gZWwgbGlicm8gZGUgS2Fzc2FtYmFyYQ0KYGBgDQoNCkxvcyBzaWd1aWVudGVzIGRhdG9zIGRlc2NyaWJlbiBlbCByZW5kaW1pZW50byBkZSBsb3MgYXRsZXRhcyBkdXJhbnRlIGRvcyBldmVudG9zIGRlcG9ydGl2b3MgKERlc2N0YXIgeSBPbHltcGljRykuIENvbnRpZW5lIDI3IGluZGl2aWR1b3MgKGF0bGV0YXMpIGRlc2NyaXRvcyBtZWRpYW50ZSAxMyB2YXJpYWJsZXMuIFNlIHJlc2FsdGEgcXVlIHPDs2xvIGFsZ3Vub3MgZGUgZXN0b3MgaW5kaXZpZHVvcyB5IHZhcmlhYmxlcyBzZSB1dGlsaXphcsOhbiBwYXJhIHJlYWxpemFyIGVsIGFuw6FsaXNpcyBkZSBjb21wb25lbnRlcyBwcmluY2lwYWxlcy4gDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZGF0b3MgPC0gZmFjdG9leHRyYTo6ZGVjYXRobG9uMg0KYXR0YWNoKGRhdG9zKQ0KZGF0IDwtIGRhdG9zWzE6MjMsIDE6MTBdDQpgYGANCg0KDQpDb24gZXN0b3MgZGF0b3MgbGxldmFyIGEgY2FibyB1biBQQ0EuIA0KDQooYSkgQ29taWVuY2UgZXhhbWluYW5kbyBsYXMgZGVzdmlhY2lvbmVzIGVzdMOhbmRhciBkZSBjYWRhIHZhcmlhYmxlLg0KDQooYikgUmVhbGljZSB1biBhbsOhbGlzaXMgZGUgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMgZGUgZXN0b3MgZGF0b3MgeSBvYnNlcnZlIGVsIGJpcGxvdC4gSW50ZXJwcmV0ZSBsYXMgY2FyZ2FzIGRlIGxvcyBkb3MgcHJpbWVyb3MgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMuICDCv0VzdMOhbiBmdWVydGVtZW50ZSBwb25kZXJhZG9zIGhhY2lhIGxhcyBtYXlvcmVzIGRlc3ZpYWNpb25lcyBlc3TDoW5kYXIgZW5jb250cmFkYXMgZW4gbGEgcGFydGUgKGEpPw0KDQooYykgUmVwaXRhIGVsIGFuw6FsaXNpcyBkZSBjb21wb25lbnRlcyBwcmluY2lwYWxlcyBlbiBsYSBtYXRyaXogZGUgY29ycmVsYWNpw7NuIGVzY2FsYWRhIGRlIGxvcyBkYXRvcy4gwr9Dw7NtbyBpbnRlcnByZXRhIGVzdGUNCmJpcGxvdD8NCg0KKGQpIMK/UXXDqSBhbsOhbGlzaXMgbGUgcGFyZWNlIG3DoXMgw7p0aWw6IGVsIGFuw6FsaXNpcyBkZSBjb21wb25lbnRlcyBwcmluY2lwYWxlcyBlc2NhbGFkbyBvIHNpbiBlc2NhbGEgcGFyYSBlc3RvcyBkYXRvcz8NCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQojIyMgRWplcmNpY2lvIDYNCg0KYGBge3IgZXZhbD1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRX0NCiMgc2VjY2nDs24gOC41LiBkZWwgbGlicm8gUjIwMjUgWmVsdGVybWFuLCBwYWdpbmEgMjI2DQpgYGANCg0KRXhhbWluZSBsb3MgZGF0b3MgZGUgYFVTSnVkZ2VSYXRpbmdzYCBlbiBsYSBsaWJyZXLDrWEgYGRhdGFzZXRzYC4gRXN0ZSBjb25qdW50byBkZSBkYXRvcyBjb250aWVuZSBsYXMgdmFsb3JhY2lvbmVzIGRlIDQzIGp1ZWNlcyBkZSB0cmlidW5hbGVzIHN1cGVyaW9yZXMgZGUgRUUuVVUuIHBvciBwYXJ0ZSBkZSBhYm9nYWRvcy4gQ2FkYSB1bm8gZGUgbG9zIGp1ZWNlcyBlcyBldmFsdWFkbyBlbiBmdW5jacOzbiBkZSAxMiBhdHJpYnV0b3MsIGNvbW8NCmF0cmlidXRvcyBjb21vIGxhIGNvbmR1Y3RhLCBsYSBwcmVwYXJhY2nDs24gcGFyYSBlbCBqdWljaW8sIGxhIHNvbGlkZXogZGUgbGFzIHNlbnRlbmNpYXMgeSBlbCBuw7ptZXJvIGRlIGNvbnRhY3RvcyBxdWUgY2FkYSBhYm9nYWRvIHR1dm8gY29uIGVsIGp1ZXouIENvbnN1bHRlIGVsIGFyY2hpdm8gZGUgYXl1ZGEgZGUgYFJgIHBhcmEgbcOhcyBpbmZvcm1hY2nDs24gc29icmUgZXN0ZSBjb25qdW50byBkZSBkYXRvcy4NCg0KYGBge3J9DQpsaWJyYXJ5KGRhdGFzZXRzKQ0KaGVhZChVU0p1ZGdlUmF0aW5ncykNCmBgYA0KDQooYSkgRXhhbWluZSBlbCBkaWFncmFtYSBkZSBkaXNwZXJzacOzbiBwb3IgcGFyZXMgZGUgZXN0b3MgZGF0b3MgKGNvbiBlbCBjb21hbmRvIGBwYWlyc2ApIHBhcmEgcmV2ZWxhciBxdWUgYWxndW5hcyB2YXJpYWJsZXMgZXN0w6FuIG11eSBjb3JyZWxhY2lvbmFkYXMuDQoNCmBgYHtyfQ0KcGFpcnMoVVNKdWRnZVJhdGluZ3MpDQpgYGANCg0KDQooYikgUmVhbGljZSB1biBhbsOhbGlzaXMgZGUgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMgcGFyYSBlc3RvcyBkYXRvcy4gTG9zIGRvcyBwcmltZXJvcyBjb21wb25lbnRlcyBkZSBleHBsaWNhbiBlbCA5NCUgZGUgbGEgdmFyaWFiaWxpZGFkLiBFbCBzZWd1bmRvIGNvbXBvbmVudGUgZXMgY2FzaSB0b3RhbG1lbnRlIGVsIG7Dum1lcm8gZGUgY29udGFjdG9zLCB5IGVsIHByaW1lciBjb21wb25lbnRlIGVzIGVzZW5jaWFsbWVudGUgdG9kYXMgbGFzIGRlbcOhcyB2YXJpYWJsZXMsIHRvZGFzIGNvbiBlbCBtaXNtbyBwZXNvLiBJbnRlcnByZXRlIGVzdGUgcmVzdWx0YWRvLg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoNCiMjIyBFamVyY2ljaW8gNw0KDQpgYGB7ciBldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQ0KIyBzZWNjacOzbiA4LjYuIGRlbCBsaWJybyBSMjAyNSBaZWx0ZXJtYW4sIHBhZ2luYSAyMjYNCmBgYA0KDQpTZSBhZG1pbmlzdHJhcm9uIHNlaXMgcHJ1ZWJhcyBkaWZlcmVudGVzIGRlIGludGVsaWdlbmNpYSB5IGNhcGFjaWRhZCBhIDExMiBwZXJzb25hcy4gTGEgbWF0cml6IGRlIGNvdmFyaWFuemEgKHBlcm8gbm8gbG9zIGRhdG9zIG9yaWdpbmFsZXMpIGRlIGxvcyByZXN1bHRhZG9zIGRlIGxhcyBwcnVlYmFzIHNlIGVuY3VlbnRyYSBlbiBgYWJpbGl0eS5jb3ZgIGVuIGxhIGxpYnJlcsOtYSBgZGF0YXNldHNgLiANCg0KYGBge3J9DQpsaWJyYXJ5KGRhdGFzZXRzKQ0KYWJpbGl0eS5jb3YNCmBgYA0KDQpMYXMgc2VpcyBwcnVlYmFzIHNlIGRlbm9taW5hbjogIGBnZW5lcmFsYCwgYHBpY3R1cmVgLCBgYmxvY2tzYCwgYG1hemVgIChsYWJlcmludG8pLCBgcmVhZGluZ2AgeSBgdm9jYWJ1bGFyeWAuIEVuIGVsIGFyY2hpdm8gZGUgYXl1ZGEgZGUgUiBwdWVkZSBlbmNvbnRyYXIgbcOhcyBpbmZvcm1hY2nDs24uDQoNCihhKSBSZWFsaWNlIHVuIGFuw6FsaXNpcyBkZSBjb21wb25lbnRlcyBwcmluY2lwYWxlcyB1dGlsaXphbmRvIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphIGUgaWRlbnRpZmlxdWUgbGFzIHZhcmlhYmxlcyBxdWUgY29udHJpYnV5ZW4gZW4gbWF5b3IgbWVkaWRhIGEgbG9zIGRvcyBwcmltZXJvcyBjb21wb25lbnRlcyBwcmluY2lwYWxlcy4gwr9Dw7NtbyBpbnRlcnByZXRhIGVzdG9zIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzPw0KDQoNCmBgYHtyLCBlY2hvPSBGQUxTRSwgZXZhbD1GQUxTRX0NCiNsaWJyYXJ5KEZhY3RvTWluZVIpDQpyZXMucGNhIDwtIFBDQShhYmlsaXR5LmNvdiwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRkFMU0UpDQpyZXMucGNhDQpgYGANCg0KKGIpIENvbnZpZXJ0YSAgbGFzIGNvdmFyaWFuemFzIGVuIG1hdHJpY2VzIGRlIGNvcnJlbGFjacOzbiwgY29uIGF5dWRhIGRlIGxhIGZ1bmNpw7NuICBgY292MmNvcmAuIA0KDQpgYGB7cn0NCmFiaWxpdHkuY29yIDwtIGNvdjJjb3IoYWJpbGl0eS5jb3YkY292KQ0KYWJpbGl0eS5jb3INCmBgYA0KDQooYykgUmVhbGljZSB1biBhbsOhbGlzaXMgZGUgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMgdXRpbGl6YW5kbyBsYSBtYXRyaXogZGUgY29ycmVsYWNpb25lcy4gRXhhbWluZSBsYXMgY2FyZ2FzIGUgaW50ZXJwcmV0ZSBsb3MgZG9zIHByaW1lcm9zIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzLiBDb21wYXJlIGVzdGUgcmVzdW1lbiBkZSBkYXRvcyBjb24gbGFzIHBhcnRlcyAoYSkgeSAoYikuIMK/RW4gcXXDqSBzZSBkaWZlcmVuY2lhbj8gZGlmaWVyZW4/IMK/RW4gcXXDqSBzZSBwYXJlY2VuPw0KDQpgYGB7ciwgZWNobz0gRkFMU0UsIGV2YWw9RkFMU0V9DQojbGlicmFyeShGYWN0b01pbmVSKQ0KcmVzLnBjYSA8LSBQQ0EoYWJpbGl0eS5jb3YsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEZBTFNFKQ0KcmVzLnBjYQ0KYGBgDQoNCihkKSDCv0NyZWUgcXVlIGVzIG3DoXMgYXByb3BpYWRvIGV4YW1pbmFyIGxhIGNvdmFyaWFuemEgbyBsYSBjb3JyZWxhY2nDs24gZW4gdW4gYW7DoWxpc2lzIGRlIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzIGRlIGVzdG9zIGRhdG9zPw0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQoNCjwhLS0gQ2Fww610dWxvIEJpYmxpb2dyYWbDrWEtLT4NCg0KDQojIEJpYmxpb2dyYWbDrWEgey51bmxpc3RlZCAudW5udW1iZXJlZH0NCiAgDQpDb25zdWx0YXIgZWwgZG9jdW1lbnRvIFtSUHVicyA6OiBBbsOhbGlzaXMgbXVsdGl2YXJpYWRvIChiaWJsaW9ncmFmw61hKV0oaHR0cHM6Ly9ycHVicy5jb20vaGxsaW5hcy9SX011bHRpdmFyaWFkb19CaWJsaW9ncmFmaWEpLg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KDQombmJzcDsNCg0KDQombmJzcDsNCjxjZW50ZXI+DQp+fn4NCklmIHlvdSBmb3VuZCBhbnkgRVJST1JTIG9yIGhhdmUgU1VHR0VTVElPTlMsIHBsZWFzZSByZXBvcnQgdGhlbSB0byBteSBlbWFpbC4gVGhhbmtzLiAgDQp+fn4NCjwvY2VudGVyPg0KDQoNCg==