Analisis
1.Reconocer los departamentos y municipios mas vulnerables por los Delitos dentro de Guatemala
dataset%>%
group_by(Departmento) %>%
summarise(cantidad=n())%>%
arrange(-cantidad)
Grafica de Cantidad de Delitos por Departamento
dataset%>%
group_by(Departmento) %>%
summarise(cantidad=n())%>%
arrange(-cantidad)%>%
ggplot(aes(x=reorder(Departmento,cantidad), y=cantidad))+
geom_bar(stat="identity",color = 'darkslategray', fill = 'steelblue') +
ggtitle ("Cantidad de Delitos por Departamento") + # Título del gráfico
theme (plot.title = element_text(size=rel(2), #Tamaño relativo de la letra del título
vjust=2, #Justificación vertical, para separarlo del gráfico
face="bold",
color="blue", #Color del texto
lineheight=1.5))+
geom_text(aes(label=cantidad), position=position_dodge(width=0.5), vjust=0.5)+
coord_flip()

Analisis Descriptivo
dataset %>%
group_by(Departmento) %>%
summarise(cantidad=n())%>%
summary()
Departmento cantidad
Length:22 Min. : 223.0
Class :character 1st Qu.: 682.5
Mode :character Median : 768.0
Mean : 1565.9
3rd Qu.: 991.8
Max. :15744.0
Municipios mas peligrosos de Guatemala
dataset%>%
group_by(Municipio) %>%
summarise(cantidad=n())%>%
arrange(-cantidad)
Grafica de Cantidad de Delitos por Municipio
dataset%>%
group_by(Municipio) %>%
summarise(cantidad=n())%>%
arrange(-cantidad)%>%
head(10) %>%
ggplot(aes(x=reorder(Municipio,cantidad), y=cantidad))+
geom_bar(stat="identity",color = 'darkslategray', fill = 'steelblue') +
ggtitle ("Cantidad de Delitos por Municipio") + # Título del gráfico
theme (plot.title = element_text(size=rel(2), #Tamaño relativo de la letra del título
vjust=2, #Justificación vertical, para separarlo del gráfico
face="bold",
color="blue", #Color del texto
lineheight=1.5))+
geom_text(aes(label=cantidad), position=position_dodge(width=0.5), vjust=0.5)+
coord_flip()

NA
NA
NA
NA
NA
Analisis Descriptivo
dataset %>%
group_by(Municipio) %>%
summarise(cantidad=n())%>%
summary()
Municipio cantidad
Length:333 Min. : 1.0
Class :character 1st Qu.: 13.0
Mode :character Median : 29.0
Mean : 103.5
3rd Qu.: 59.0
Max. :7535.0
*Conclusion 1: El departamento y Municipio de Guatemala son los lugares mas peligrosos, estando en el ranking como el 1er lugar en ambas evaluaciones. En la poblacion a nivel Departamental tenemos una mediana de 768 delitos por departamento y de 29 por municipio, tomamos la mediana dado que los datos son muy dispersos por la diferencia que tenemos respecto al departamento/Municipio de Guatemala y el resto de areas.
2.Reconocer cual es el departamento/municipio con menor cantidad de Delitos
dataset%>%
group_by(Departmento) %>%
summarise(cantidad=n())%>%
arrange(cantidad)
Grafica de Cantidad de Delitos por Departamento
dataset%>%
group_by(Departmento) %>%
summarise(cantidad=n())%>%
arrange(cantidad)%>%
head(10) %>%
ggplot(aes(x=reorder(Departmento,-cantidad), y=cantidad))+
geom_bar(stat="identity",color = 'darkslategray', fill = 'steelblue') +
ggtitle ("Cantidad de Delitos por Departamento") + # Título del gráfico
theme (plot.title = element_text(size=rel(2), #Tamaño relativo de la letra del título
vjust=2, #Justificación vertical, para separarlo del gráfico
face="bold",
color="blue", #Color del texto
lineheight=1.5))+
geom_text(aes(label=cantidad), position=position_dodge(width=0.2), vjust=0.5)+
coord_flip()

dataset%>%
group_by(Municipio) %>%
summarise(cantidad=n())%>%
arrange(cantidad)
Grafica de Cantidad de Delitos por Municipio
dataset%>%
group_by(Municipio) %>%
summarise(cantidad=n())%>%
arrange(cantidad)%>%
head(10) %>%
ggplot(aes(x=reorder(Municipio,-cantidad), y=cantidad))+
geom_bar(stat="identity",color = 'darkslategray', fill = 'steelblue') +
ggtitle ("Cantidad de Delitos por Municipio") + # Título del gráfico
theme (plot.title = element_text(size=rel(2), #Tamaño relativo de la letra del título
vjust=2, #Justificación vertical, para separarlo del gráfico
face="bold",
color="blue", #Color del texto
lineheight=1.5))+
geom_text(aes(label=cantidad), position=position_dodge(width=0.2), vjust=0.5)+
coord_flip()

Conclusion 2: El departamento mas seguro es Totonicapan y el Municipio mas seguro es Tectitan, municipio de Huehuetenango
3. Estadistica por edad
mean (dataset$edad_per,trim = 0.1)
[1] 44.47179
median(dataset$edad_per)
[1] 34
Moda= table(dataset$G_Edad_Quincenal)[which.max(table(dataset$G_Edad_Quincenal))]
Moda
25-29
4908
Conclusion 3: La edad promedio de las personas victimas de hechos delectivos durante el 2019 es de 44 años, y el rango de edades de las personal mas afectadas oscila entre los 25 y 29 años de edad.
4. Reconocer si los delitos suceden con mayores de edad o menores de edad
Mayor=dataset %>%
filter (MayorOMenordeEdad=="Mayor de edad") %>%
summarise(Mayor_de_edad=n()) %>%
arrange (-Mayor_de_edad)
Mayor
PorcentajeMenor=(Menor)/(Mayor+Menor)
PorcentajeMenor
Conclusion 4: Al agrupar los menores de 18 años y los mayores de 18 años, se concluye que los mas afectados son los mayores de edad, es importante mencionar que el 8% de los afectados son Menores de edad
5. Reconocer los delitos por sexo
VictimaH=
dataset %>%
filter(Sexo =="Hombre")
Error in dataset %>% filter(Sexo == "Hombre") :
no se pudo encontrar la función "%>%"
*Conclusion 5: La probabilidad de las deVictimas de Hechos Delictivos por sexo, en general se muestra con la siguiente proporcion: 68.8% Hombres, 30% mujeres y en 1.2% de los casos el genero es omitido. Segun la grafica, en los tipo de delito: Contra y Libertad y otras causas, no se cumple la proporcion general.
6. La probabilidad de ocurrencia según sexo, edad se comete los delitos
VicHombreMy=
dataset %>%
filter (MayorOMenordeEdad == "Mayor de edad", Sexo == "Hombre")
nrow(VicHombreMy)/nrow(VictimaH)
[1] 0.8677264
VicMujerMy=
dataset %>%
filter (MayorOMenordeEdad == "Mayor de edad" , Sexo == "Mujer")
nrow(VicMujerMy)/nrow(VictimaM)
[1] 0.7524781
VicHombreME=
dataset %>%
filter (Sexo == "Hombre" , MayorOMenordeEdad == "Menor de edad")
nrow(VicHombreME)/nrow(VictimaH)
[1] 0.04667735
VicMujerME=
dataset %>%
filter (Sexo == "Mujer" , MayorOMenordeEdad == "Menor de edad")
nrow(VicMujerME)/nrow(VictimaM)
[1] 0.1562891
DiaVictima =
dataset %>%
group_by(NombredelDia, Sexo) %>%
summarise(Cantidad = n()) %>%
arrange(-Cantidad)
ggplot(DiaVictima, aes(x=NombredelDia, y=Cantidad, group = Sexo, colour =Sexo )) +
geom_line() +
geom_point( size=1, shape=10, fill="blue") +
theme_gray()

*Conclusion 6: La probabilidad de ocurrencia de hechos delictivos para para victimas mayores de edad es: Hombre 86.77% y Mujeres 75.24%. Para victimas Menores de Edad: Hombre 4.66% y Mujeres 15.63%. Los dias de la semana en que ocurren los hechos delictivos gruardan relacion segun el sexo, como se observa en la grafica.
7. Obtener si existe un patron en la hora en que suceden los delitos
Hora=dataset[(dataset$HoraOcurrencia<99), 7]
Warning messages:
1: In readChar(file, size, TRUE) : truncating string with embedded nuls
2: In readChar(file, size, TRUE) : truncating string with embedded nuls
3: In readChar(file, size, TRUE) : truncating string with embedded nuls
4: In readChar(file, size, TRUE) : truncating string with embedded nuls
hist(Hora,
col=blues9,
xlab= "Hora",
ylab= "Cantidad",
main= "Grafica de delitos cometidos por X hora",
las=2)

Conclusion 7: Segun muestra la grafica, la mayor parte de los hechos delictivos son cometidos entre las 9 y las 21 horas de dia
8. Que dia es el que mas delitos hay
dataset%>%
group_by(NombredelDia) %>%
summarise(cantidad=n())%>%
arrange(-cantidad)%>%
ggplot(aes(y=reorder(NombredelDia,cantidad), x=cantidad))+
geom_point(color = 'red', fill = 'red', size = 4, shape = 18, alpha = 0.5) +
xlab('Delito') +
ylab('Dias de la semana') +
ggtitle ("Cantidad total por Dia") + # Título del gráfico
theme (plot.title = element_text(size=rel(2), #Tamaño relativo de la letra del título
vjust=2, #Justificación vertical, para separarlo del gráfico
face="bold",
color="blue", #Color del texto
lineheight=1.5))+
geom_text(aes(label=cantidad), position=position_dodge(width=0.5), vjust=-.5)+
coord_flip()

Conclusion 8: El dia con mas delitos son los dias Lunes y Martes, y el dia con menos delitos son los dias Domingo
9. Evaluar si existe un incremento de delitos en los meses de bono 14 y Aguinaldo
Hechosxmes= as.data.frame(prop.table(table(dataset$Mes, dataset$GrupoDelito), 2)*100)
colnames(Hechosxmes)<-c("MES", "Delito","PCT")
gr4 <- ggplot(Hechosxmes, aes(x=MES, y=PCT)) + geom_bar(stat="identity", fill = 'steelblue')
gr4

gr4 + coord_flip() + facet_wrap(~ Delito)

*Conclusion 9: ### La siguiente grafica muestra la ocurrencia de hechos delictivos por mes, evidenciando que apartir del Mes de julio (bono 14) se incrementan: Las extorsiones y los Homicidios. Mientras que durante el mes de diciembre solo se denota un incremento en los los Hechos delictivos en contra el patrimonio.
% de Delitos que son Extorsiones a buses urbanos
(buses/TotalDelitos)
[1] 0.0129757
pdf=sapply(x, FUN=PMF1)
pdf
[1] 0.8287462 0.1712538
datos=data.frame(x=x,px=pdf)
datos
Conclusion PDF: La densidad de probabilidad que una mujer sea victima de homicidio en el municipio de Guatemala es el 17.12%
Obtener el CDF
cdf=cumsum(pdf)
cdf
datos=data.frame(datos,Fx=cdf)
datos
valor_esperado=function(df){
x=df[ ,1]
px=df [ ,2]
VE=sum(x*px)
return(VE)}
valor_esperado(datos) #media ponderada
Obtener la Varianza
varianza=function(df){
media=valor_esperado(df)
x=df [ ,1]
px=df [ ,2]
varX=sum(((x-media)^2)*(px))
return(varX)
}
varianza(datos)
Conclusion CDF Podemos observar la variabilidad de los datos a un 0.14, la cual indica la distancia que hay hacia la media
Best Fit, tomando en cuenta la Edad
dataset$edad_per
EdadCorrecta=dataset[(dataset$edad_per<999), 20]
TablaEdad=data_frame(table(EdadCorrecta))
TablaEdad
descdist(EdadCorrecta, discrete = FALSE)
hist(EdadCorrecta,
col=blues9,
xlab= "Edad",
ylab= "Cantidad de Delitos",
main= "Grafica de delitos por edad",
las=2)
Conclusion BEST FIT: Al analizar la cantidad de Delitos por edad podemos concluir que se apega a una distribucion normal, misma se valido realizando un histograma de frecuencia por edad el cual se puede ver un leve sesgo hacia la derecha, siendo las edades mas vulnerables entre los 20 y 40 años.
LS0tDQp0aXRsZTogIkVzdGFkaXN0aWNhIC0gRGVsaXRvcyBlbiBHdWF0ZW1hbGEgMjAxOSINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQpgYGB7cn0NCmRhdGFzZXQ9cmVhZC5jc3YoIkRhdGFiYXNlX1BGLmNzdiIpDQpsaWJyYXJ5KGdncGxvdDIpDQoNCmBgYA0KIyMjIyAqKlVuaXZlcnNpZGFkIEdhbGlsZW8qKiByZWQNCiMjIyMgKipQb3N0Z3JhZG8gZW4gaW50ZWxpZ2VuY2lhIGRlIG5lZ29jaW9zKioNCiMjIyMgKipQcm95ZWN0byBGaW5hbCBFc3RhZMOtc3RpY2EqKg0KIyMjIyAqKk1pZ3VlbCBBbmdlbCBKb2xvbiAgMjAwMDM0MTEgfCBDcmlzdGhlbGxhIFNhbnRpem8gMjAwMzIzNjUqKg0KDQojICoqSW50cm9kdWNjaW9uKioNCkd1YXRlbWFsYSBlcyB1biBwYWlzIGNvbiB2YXJpZWRhZCBjbGltYXRpY2EsIHZvbGNhbmVzIHkgbW9udGHDsWFzLCBzaWVuZG8gY29uc2lkZXJhZG8gZWwgcGFpcyBkZSBsYSBldGVybmEgcHJpbWF2ZXJhLCB1biBmb2NvIHBvdGVuY2lhbCBwYXJhIGVsIHR1cmlzbW8geSBjYWxpZGFkIGRlIHZpZGEgYWx0YSwgc2luIGVtYmFyZ28gZXN0byBzZSB2ZSBhZmVjdGFkbyBwb3IgaW5kaWNlIGRlIGNyaW1pbmFsaWRhZCwgZ3J1cG9zIG9yZ2FuaXphZG9zIHkgbm8gb3JnYW5pemFkb3Mgc2UgaGFuIGFwb2RlcmFkbyBjYWRhIHZleiBkZWwgcGFpcyBzaWVuZG8gY29uc2lkZXJhZG8gdW5vIGRlIGxvcyBwYWlzZXMgYSBldml0YXIgc2Vnw7puIEFCQywgb2N1cGFuZG8gZWwgcHVlc3RvIDQ5IGRlIGxvcyBwYWlzZXMgbWFzIHBlbGlncm9zb3MgZGVsIG11bmRvLiBFbCBwcmVzZW50ZSBkb2N1bWVudG8gbXVlc3RyYSBsb3MgaW5kaWNhZG9yZXMgbWFzIGltcG9ydGFudGVzIHBhcmEgY29ub2NlciBsYXMgcmVnaW9uZXMgeSBzZWN0b3JlcyBtYXMgYWZlY3RhZGFzIHBvciBsYSBjcmltaW5hbGlkYWQNCg0KIyAqKkRlZmluaWNpb24gZGVsIHByb2JsZW1hKioNCjEuIFJlY29ub2NlciBsb3MgZGVwYXJ0YW1lbnRvcyB5IG11bmljaXBpb3MgbWFzIHZ1bG5lcmFibGVzIHBvciBsb3MgRGVsaXRvcyBkZW50cm8gZGUgR3VhdGVtYWxhIA0KMi4gUmVjb25vY2VyIGN1YWwgZXMgZWwgZGVwYXJ0YW1lbnRvL211bmljaXBpbyBjb24gbWVub3IgY2FudGlkYWQgZGUgRGVsaXRvcw0KMy4gRXN0YWRpc3RpY2EgcG9yIGVkYWQNCjQuIFJlY29ub2NlciBzaSBsb3MgZGVsaXRvcyBzdWNlZGVuIGNvbiBtYXlvcmVzIGRlIGVkYWQgbyBtZW5vcmVzIGRlIGVkYWQNCjUuIFJlY29ub2NlciBsb3MgZGVsaXRvcyBwb3Igc2V4bw0KNi4gTGEgcHJvYmFiaWxpZGFkIGRlIG9jdXJyZW5jaWEgc2Vnw7puIHNleG8sIGVkYWQgeSBkaWEgZW4gcXVlIHNlIGNvbWV0ZSBsb3MgZGVsaXRvcw0KNy4gT2J0ZW5lciBzaSBleGlzdGUgdW4gcGF0cm9uIGVuIGxhIGhvcmEgZW4gcXVlIHN1Y2VkZW4gbG9zIGRlbGl0b3MNCjguIFF1ZSBkaWEgZXMgZWwgcXVlIG1hcyBkZWxpdG9zIGhheQ0KOS4gRXZhbHVhciBzaSBleGlzdGUgdW4gaW5jcmVtZW50byBkZSBkZWxpdG9zIGVuIGxvcyBtZXNlcyBkZSBib25vIDE0IHkgQWd1aW5hbGRvDQoxMC4JQ3VhbnRvIGRlIGxvcyBkZWxpdG9zIHNvbiBwb3IgdGVtYSBkZSBleHRvcnNpb25lcyBlbiBidXNlcyAodXJiYW5vcyB5IGV4dHJhdXJiYW5vcyApDQoxMS4JQW5hbGlzaXMgcHJvYmFiaWxpc3RpY28gWFhYWFhYWFhYWFhYWFhYDQoNCiMgKipBbmFsaXNpcyoqDQojIyMgMS5SZWNvbm9jZXIgbG9zIGRlcGFydGFtZW50b3MgeSBtdW5pY2lwaW9zIG1hcyB2dWxuZXJhYmxlcyBwb3IgbG9zIERlbGl0b3MgZGVudHJvIGRlIEd1YXRlbWFsYSANCmBgYHtyfQ0KZGF0YXNldCU+JQ0KICBncm91cF9ieShEZXBhcnRtZW50bykgJT4lDQogIHN1bW1hcmlzZShjYW50aWRhZD1uKCkpJT4lDQogIGFycmFuZ2UoLWNhbnRpZGFkKQ0KYGBgDQojIyMgR3JhZmljYSBkZSBDYW50aWRhZCBkZSBEZWxpdG9zIHBvciBEZXBhcnRhbWVudG8NCg0KYGBge3J9DQpkYXRhc2V0JT4lDQogIGdyb3VwX2J5KERlcGFydG1lbnRvKSAlPiUNCiAgc3VtbWFyaXNlKGNhbnRpZGFkPW4oKSklPiUNCiAgYXJyYW5nZSgtY2FudGlkYWQpJT4lDQogIGdncGxvdChhZXMoeD1yZW9yZGVyKERlcGFydG1lbnRvLGNhbnRpZGFkKSwgeT1jYW50aWRhZCkpKw0KICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsY29sb3IgPSAnZGFya3NsYXRlZ3JheScsIGZpbGwgPSAnc3RlZWxibHVlJykgKyANCiAgZ2d0aXRsZSAoIkNhbnRpZGFkIGRlIERlbGl0b3MgcG9yIERlcGFydGFtZW50byIpICsgIyBUw610dWxvIGRlbCBncsOhZmljbw0KICB0aGVtZSAocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPXJlbCgyKSwgI1RhbWHDsW8gcmVsYXRpdm8gZGUgbGEgbGV0cmEgZGVsIHTDrXR1bG8NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2anVzdD0yLCAjSnVzdGlmaWNhY2nDs24gdmVydGljYWwsIHBhcmEgc2VwYXJhcmxvIGRlbCBncsOhZmljbw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY2U9ImJvbGQiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj0iYmx1ZSIsICNDb2xvciBkZWwgdGV4dG8NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5laGVpZ2h0PTEuNSkpKw0KIGdlb21fdGV4dChhZXMobGFiZWw9Y2FudGlkYWQpLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpLCB2anVzdD0wLjUpKw0KICBjb29yZF9mbGlwKCkNCg0KYGBgDQojIyMgQW5hbGlzaXMgRGVzY3JpcHRpdm8NCg0KYGBge3J9DQpkYXRhc2V0ICU+JQ0KICAgIGdyb3VwX2J5KERlcGFydG1lbnRvKSAlPiUNCiAgc3VtbWFyaXNlKGNhbnRpZGFkPW4oKSklPiUNCiAgc3VtbWFyeSgpDQoNCmBgYA0KDQojIyMgTXVuaWNpcGlvcyBtYXMgcGVsaWdyb3NvcyBkZSBHdWF0ZW1hbGEgIA0KYGBge3J9DQpkYXRhc2V0JT4lDQogIGdyb3VwX2J5KE11bmljaXBpbykgJT4lDQogIHN1bW1hcmlzZShjYW50aWRhZD1uKCkpJT4lDQogIGFycmFuZ2UoLWNhbnRpZGFkKQ0KYGBgDQojIyMgR3JhZmljYSBkZSBDYW50aWRhZCBkZSBEZWxpdG9zIHBvciBNdW5pY2lwaW8NCg0KYGBge3J9DQpkYXRhc2V0JT4lDQogIGdyb3VwX2J5KE11bmljaXBpbykgJT4lDQogIHN1bW1hcmlzZShjYW50aWRhZD1uKCkpJT4lDQogIGFycmFuZ2UoLWNhbnRpZGFkKSU+JQ0KICBoZWFkKDEwKSAlPiUNCiAgZ2dwbG90KGFlcyh4PXJlb3JkZXIoTXVuaWNpcGlvLGNhbnRpZGFkKSwgeT1jYW50aWRhZCkpKw0KICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsY29sb3IgPSAnZGFya3NsYXRlZ3JheScsIGZpbGwgPSAnc3RlZWxibHVlJykgKyANCiAgZ2d0aXRsZSAoIkNhbnRpZGFkIGRlIERlbGl0b3MgcG9yIE11bmljaXBpbyIpICsgIyBUw610dWxvIGRlbCBncsOhZmljbw0KICB0aGVtZSAocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPXJlbCgyKSwgI1RhbWHDsW8gcmVsYXRpdm8gZGUgbGEgbGV0cmEgZGVsIHTDrXR1bG8NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2anVzdD0yLCAjSnVzdGlmaWNhY2nDs24gdmVydGljYWwsIHBhcmEgc2VwYXJhcmxvIGRlbCBncsOhZmljbw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY2U9ImJvbGQiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj0iYmx1ZSIsICNDb2xvciBkZWwgdGV4dG8NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5laGVpZ2h0PTEuNSkpKw0KIGdlb21fdGV4dChhZXMobGFiZWw9Y2FudGlkYWQpLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpLCB2anVzdD0wLjUpKw0KICBjb29yZF9mbGlwKCkNCg0KDQogDQogIA0KDQpgYGANCiMjIyBBbmFsaXNpcyBEZXNjcmlwdGl2bw0KDQpgYGB7cn0NCmRhdGFzZXQgJT4lDQogICAgZ3JvdXBfYnkoTXVuaWNpcGlvKSAlPiUNCiAgc3VtbWFyaXNlKGNhbnRpZGFkPW4oKSklPiUNCiAgc3VtbWFyeSgpDQoNCmBgYA0KIyMjICpDb25jbHVzaW9uIDE6IEVsIGRlcGFydGFtZW50byB5IE11bmljaXBpbyBkZSBHdWF0ZW1hbGEgc29uIGxvcyBsdWdhcmVzIG1hcyBwZWxpZ3Jvc29zLCBlc3RhbmRvIGVuIGVsIHJhbmtpbmcgY29tbyBlbCAxZXIgbHVnYXIgZW4gYW1iYXMgZXZhbHVhY2lvbmVzLiBFbiBsYSBwb2JsYWNpb24gYSBuaXZlbCBEZXBhcnRhbWVudGFsIHRlbmVtb3MgdW5hIG1lZGlhbmEgZGUgNzY4IGRlbGl0b3MgcG9yIGRlcGFydGFtZW50byB5IGRlIDI5IHBvciBtdW5pY2lwaW8sIHRvbWFtb3MgbGEgbWVkaWFuYSBkYWRvIHF1ZSBsb3MgZGF0b3Mgc29uIG11eSBkaXNwZXJzb3MgcG9yIGxhIGRpZmVyZW5jaWEgcXVlIHRlbmVtb3MgcmVzcGVjdG8gYWwgZGVwYXJ0YW1lbnRvL011bmljaXBpbyBkZSBHdWF0ZW1hbGEgeSBlbCByZXN0byBkZSBhcmVhcy4NCg0KDQoNCiMjIyAyLlJlY29ub2NlciBjdWFsIGVzIGVsIGRlcGFydGFtZW50by9tdW5pY2lwaW8gY29uIG1lbm9yIGNhbnRpZGFkIGRlIERlbGl0b3MNCg0KYGBge3J9DQpkYXRhc2V0JT4lDQogIGdyb3VwX2J5KERlcGFydG1lbnRvKSAlPiUNCiAgc3VtbWFyaXNlKGNhbnRpZGFkPW4oKSklPiUNCiAgYXJyYW5nZShjYW50aWRhZCkNCmBgYA0KDQojIyMgR3JhZmljYSBkZSBDYW50aWRhZCBkZSBEZWxpdG9zIHBvciBEZXBhcnRhbWVudG8NCg0KYGBge3J9DQpkYXRhc2V0JT4lDQogIGdyb3VwX2J5KERlcGFydG1lbnRvKSAlPiUNCiAgc3VtbWFyaXNlKGNhbnRpZGFkPW4oKSklPiUNCiAgYXJyYW5nZShjYW50aWRhZCklPiUNCiAgaGVhZCgxMCkgJT4lDQogIGdncGxvdChhZXMoeD1yZW9yZGVyKERlcGFydG1lbnRvLC1jYW50aWRhZCksIHk9Y2FudGlkYWQpKSsNCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLGNvbG9yID0gJ2RhcmtzbGF0ZWdyYXknLCBmaWxsID0gJ3N0ZWVsYmx1ZScpICsgDQogIGdndGl0bGUgKCJDYW50aWRhZCBkZSBEZWxpdG9zIHBvciBEZXBhcnRhbWVudG8iKSArICMgVMOtdHVsbyBkZWwgZ3LDoWZpY28NCiAgdGhlbWUgKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT1yZWwoMiksICNUYW1hw7FvIHJlbGF0aXZvIGRlIGxhIGxldHJhIGRlbCB0w610dWxvDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmp1c3Q9MiwgI0p1c3RpZmljYWNpw7NuIHZlcnRpY2FsLCBwYXJhIHNlcGFyYXJsbyBkZWwgZ3LDoWZpY28NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNlPSJib2xkIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9ImJsdWUiLCAjQ29sb3IgZGVsIHRleHRvDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZWhlaWdodD0xLjUpKSsNCiBnZW9tX3RleHQoYWVzKGxhYmVsPWNhbnRpZGFkKSwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC4yKSwgdmp1c3Q9MC41KSsNCiAgY29vcmRfZmxpcCgpDQoNCmBgYA0KDQpgYGB7cn0NCmRhdGFzZXQlPiUNCiAgZ3JvdXBfYnkoTXVuaWNpcGlvKSAlPiUNCiAgc3VtbWFyaXNlKGNhbnRpZGFkPW4oKSklPiUNCiAgYXJyYW5nZShjYW50aWRhZCkNCmBgYA0KIyMjIEdyYWZpY2EgZGUgQ2FudGlkYWQgZGUgRGVsaXRvcyBwb3IgTXVuaWNpcGlvDQoNCmBgYHtyfQ0KZGF0YXNldCU+JQ0KICBncm91cF9ieShNdW5pY2lwaW8pICU+JQ0KICBzdW1tYXJpc2UoY2FudGlkYWQ9bigpKSU+JQ0KICBhcnJhbmdlKGNhbnRpZGFkKSU+JQ0KICBoZWFkKDEwKSAlPiUNCiAgZ2dwbG90KGFlcyh4PXJlb3JkZXIoTXVuaWNpcGlvLC1jYW50aWRhZCksIHk9Y2FudGlkYWQpKSsNCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLGNvbG9yID0gJ2RhcmtzbGF0ZWdyYXknLCBmaWxsID0gJ3N0ZWVsYmx1ZScpICsgDQogIGdndGl0bGUgKCJDYW50aWRhZCBkZSBEZWxpdG9zIHBvciBNdW5pY2lwaW8iKSArICMgVMOtdHVsbyBkZWwgZ3LDoWZpY28NCiAgdGhlbWUgKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT1yZWwoMiksICNUYW1hw7FvIHJlbGF0aXZvIGRlIGxhIGxldHJhIGRlbCB0w610dWxvDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmp1c3Q9MiwgI0p1c3RpZmljYWNpw7NuIHZlcnRpY2FsLCBwYXJhIHNlcGFyYXJsbyBkZWwgZ3LDoWZpY28NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNlPSJib2xkIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9ImJsdWUiLCAjQ29sb3IgZGVsIHRleHRvDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZWhlaWdodD0xLjUpKSsNCiBnZW9tX3RleHQoYWVzKGxhYmVsPWNhbnRpZGFkKSwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC4yKSwgdmp1c3Q9MC41KSsNCiAgY29vcmRfZmxpcCgpDQoNCmBgYA0KDQojIyMgKkNvbmNsdXNpb24gMjogRWwgZGVwYXJ0YW1lbnRvIG1hcyBzZWd1cm8gZXMgVG90b25pY2FwYW4geSBlbCBNdW5pY2lwaW8gbWFzIHNlZ3VybyBlcyBUZWN0aXRhbiwgbXVuaWNpcGlvIGRlIEh1ZWh1ZXRlbmFuZ28gKg0KDQoNCiMjIyAzLiBFc3RhZGlzdGljYSBwb3IgZWRhZA0KDQpgYGB7cn0NCm1lYW4gKGRhdGFzZXQkZWRhZF9wZXIsdHJpbSA9IDAuMSkNCm1lZGlhbihkYXRhc2V0JGVkYWRfcGVyKQ0KTW9kYT0gdGFibGUoZGF0YXNldCRHX0VkYWRfUXVpbmNlbmFsKVt3aGljaC5tYXgodGFibGUoZGF0YXNldCRHX0VkYWRfUXVpbmNlbmFsKSldDQpNb2RhDQpgYGANCiMjIyAqQ29uY2x1c2lvbiAzOiBMYSBlZGFkIHByb21lZGlvIGRlIGxhcyBwZXJzb25hcyB2aWN0aW1hcyBkZSBoZWNob3MgZGVsZWN0aXZvcyBkdXJhbnRlIGVsIDIwMTkgZXMgZGUgNDQgYcOxb3MsIHkgZWwgcmFuZ28gZGUgZWRhZGVzIGRlIGxhcyBwZXJzb25hbCBtYXMgYWZlY3RhZGFzIG9zY2lsYSBlbnRyZSBsb3MgMjUgeSAyOSBhw7FvcyBkZSBlZGFkLioNCg0KDQojIyMgNC4gUmVjb25vY2VyIHNpIGxvcyBkZWxpdG9zIHN1Y2VkZW4gY29uIG1heW9yZXMgZGUgZWRhZCBvIG1lbm9yZXMgZGUgZWRhZA0KDQpgYGB7cn0NCk1heW9yPWRhdGFzZXQgJT4lDQpmaWx0ZXIgKE1heW9yT01lbm9yZGVFZGFkPT0iTWF5b3IgZGUgZWRhZCIpICU+JQ0Kc3VtbWFyaXNlKE1heW9yX2RlX2VkYWQ9bigpKSAlPiUNCmFycmFuZ2UgKC1NYXlvcl9kZV9lZGFkKQ0KTWF5b3INCg0KYGBgDQoNCmBgYHtyfQ0KTWVub3I9ZGF0YXNldCAlPiUNCmZpbHRlciAoTWF5b3JPTWVub3JkZUVkYWQ9PSJNZW5vciBkZSBlZGFkIikgJT4lDQpzdW1tYXJpc2UoTWVub3JfZGVfZWRhZD1uKCkpICU+JQ0KYXJyYW5nZSAoLU1lbm9yX2RlX2VkYWQpDQpNZW5vcg0KYGBgDQoNCmBgYHtyfQ0KUG9yY2VudGFqZU1lbm9yPShNZW5vcikvKE1heW9yK01lbm9yKQ0KUG9yY2VudGFqZU1lbm9yDQpgYGANCg0KIyMjICpDb25jbHVzaW9uIDQ6IEFsIGFncnVwYXIgbG9zIG1lbm9yZXMgZGUgMTggYcOxb3MgeSBsb3MgbWF5b3JlcyBkZSAxOCBhw7Fvcywgc2UgY29uY2x1eWUgcXVlIGxvcyBtYXMgYWZlY3RhZG9zIHNvbiBsb3MgbWF5b3JlcyBkZSBlZGFkLCBlcyBpbXBvcnRhbnRlIG1lbmNpb25hciBxdWUgZWwgOCUgZGUgbG9zIGFmZWN0YWRvcyBzb24gTWVub3JlcyBkZSBlZGFkKg0KDQoNCiMjIyA1LiBSZWNvbm9jZXIgbG9zIGRlbGl0b3MgcG9yIHNleG8NCmBgYHtyfQ0KVmljdGltYUg9DQogIGRhdGFzZXQgJT4lDQogIGZpbHRlcihTZXhvID09IkhvbWJyZSIpDQpucm93KFZpY3RpbWFIKS9ucm93KGRhdGFzZXQpDQoNClZpY3RpbWFNPQ0KICBkYXRhc2V0ICU+JQ0KICBmaWx0ZXIoU2V4byA9PSJNdWplciIpDQpucm93KFZpY3RpbWFNKS9ucm93KERhdGFzZXQpDQoNCkRlbGl0b3NYU2V4bz0gDQogIGRhdGFzZXQgJT4lDQogIGdyb3VwX2J5KFNleG8sIEdydXBvRGVsaXRvKSAlPiUNCiAgc3VtbWFyaXNlKENhbnRpZGFkID0gbigpKSAlPiUNCiAgYXJyYW5nZSgtQ2FudGlkYWQpDQpjb2xuYW1lcyhEZWxpdG9zWFNleG8pPC1jKCJTZXhvIiwgIkRlbGl0byIsIkNhbnRpZGFkIikNCkRlbGl0b3NYU2V4bw0KZ3IyIDwtIGdncGxvdChEZWxpdG9zWFNleG8sIGFlcyh4PVNleG8sIHk9Q2FudGlkYWQpKSArIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IiwgY29sb3IgPSAnZGFya3NsYXRlZ3JheScsIGZpbGwgPSAnc3RlZWxibHVlJykgKw0KICBnZ3RpdGxlKCJWaWN0aW1hcyBkZSBIZWNob3MgRGVsaWNpdGl2b3MgYWdydXBhZG9zIHBvciBTZXhvIikgKyB0aGVtZV9idygpDQpncjIgKyBmYWNldF93cmFwKH4gRGVsaXRvKQ0KYGBgDQojIyMgKkNvbmNsdXNpb24gNTogTGEgcHJvYmFiaWxpZGFkIGRlIGxhcyBkZVZpY3RpbWFzIGRlIEhlY2hvcyBEZWxpY3Rpdm9zIHBvciBzZXhvLCBlbiBnZW5lcmFsIHNlIG11ZXN0cmEgY29uIGxhIHNpZ3VpZW50ZSBwcm9wb3JjaW9uOiA2OC44JSBIb21icmVzLCAzMCUgbXVqZXJlcyB5IGVuIDEuMiUgZGUgbG9zIGNhc29zIGVsIGdlbmVybyBlcyBvbWl0aWRvLiAgU2VndW4gbGEgZ3JhZmljYSwgZW4gbG9zIHRpcG8gZGUgZGVsaXRvOiBDb250cmEgeSBMaWJlcnRhZCB5IG90cmFzIGNhdXNhcywgbm8gc2UgY3VtcGxlIGxhIHByb3BvcmNpb24gZ2VuZXJhbC4gDQoNCg0KIyMjIDYuIExhIHByb2JhYmlsaWRhZCBkZSBvY3VycmVuY2lhIHNlZ8O6biBzZXhvLCBlZGFkIHNlIGNvbWV0ZSBsb3MgZGVsaXRvcw0KDQpgYGB7cn0NClZpY0hvbWJyZU15PQ0KICBkYXRhc2V0ICU+JQ0KICBmaWx0ZXIgKE1heW9yT01lbm9yZGVFZGFkID09ICJNYXlvciBkZSBlZGFkIiwgU2V4byA9PSAiSG9tYnJlIikNCm5yb3coVmljSG9tYnJlTXkpL25yb3coVmljdGltYUgpDQoNClZpY011amVyTXk9DQogIGRhdGFzZXQgJT4lDQogIGZpbHRlciAoTWF5b3JPTWVub3JkZUVkYWQgPT0gIk1heW9yIGRlIGVkYWQiICwgU2V4byA9PSAiTXVqZXIiKQ0KbnJvdyhWaWNNdWplck15KS9ucm93KFZpY3RpbWFNKQ0KDQpWaWNIb21icmVNRT0NCiAgZGF0YXNldCAlPiUNCiAgZmlsdGVyIChTZXhvID09ICJIb21icmUiICwgTWF5b3JPTWVub3JkZUVkYWQgPT0gIk1lbm9yIGRlIGVkYWQiKQ0KbnJvdyhWaWNIb21icmVNRSkvbnJvdyhWaWN0aW1hSCkNCg0KVmljTXVqZXJNRT0NCiAgZGF0YXNldCAlPiUNCiAgZmlsdGVyIChTZXhvID09ICJNdWplciIgLCBNYXlvck9NZW5vcmRlRWRhZCA9PSAiTWVub3IgZGUgZWRhZCIpDQogIG5yb3coVmljTXVqZXJNRSkvbnJvdyhWaWN0aW1hTSkNCiAgDQpEaWFWaWN0aW1hID0NCmRhdGFzZXQgJT4lDQogIGdyb3VwX2J5KE5vbWJyZWRlbERpYSwgU2V4bykgJT4lDQogIHN1bW1hcmlzZShDYW50aWRhZCA9IG4oKSkgJT4lDQogIGFycmFuZ2UoLUNhbnRpZGFkKQ0KZ2dwbG90KERpYVZpY3RpbWEsIGFlcyh4PU5vbWJyZWRlbERpYSwgeT1DYW50aWRhZCwgZ3JvdXAgPSBTZXhvLCBjb2xvdXIgPVNleG8gKSkgKyANCiAgZ2VvbV9saW5lKCkgICsgDQogIGdlb21fcG9pbnQoIHNpemU9MSwgc2hhcGU9MTAsIGZpbGw9ImJsdWUiKSArIA0KICB0aGVtZV9ncmF5KCkNCg0KYGBgDQojIyMgKkNvbmNsdXNpb24gNjogTGEgcHJvYmFiaWxpZGFkIGRlIG9jdXJyZW5jaWEgZGUgaGVjaG9zIGRlbGljdGl2b3MgcGFyYSBwYXJhIHZpY3RpbWFzIG1heW9yZXMgZGUgZWRhZCBlczogSG9tYnJlIDg2Ljc3JSB5IE11amVyZXMgNzUuMjQlLiAgIFBhcmEgdmljdGltYXMgTWVub3JlcyBkZSBFZGFkOiBIb21icmUgNC42NiUgeSBNdWplcmVzIDE1LjYzJS4gTG9zIGRpYXMgZGUgbGEgc2VtYW5hIGVuIHF1ZSBvY3VycmVuIGxvcyBoZWNob3MgZGVsaWN0aXZvcyBncnVhcmRhbiByZWxhY2lvbiBzZWd1biBlbCBzZXhvLCBjb21vIHNlIG9ic2VydmEgZW4gbGEgZ3JhZmljYS4NCg0KDQojIyMgNy4gT2J0ZW5lciBzaSBleGlzdGUgdW4gcGF0cm9uIGVuIGxhIGhvcmEgZW4gcXVlIHN1Y2VkZW4gbG9zIGRlbGl0b3MNCmBgYHtyfQ0KSG9yYT1kYXRhc2V0WyhkYXRhc2V0JEhvcmFPY3VycmVuY2lhPDk5KSwgN10NCmhpc3QoSG9yYSwNCiAgICAgICAgY29sPWJsdWVzOSwNCiAgICAgICAgeGxhYj0gIkhvcmEiLA0KICAgICAgICB5bGFiPSAiQ2FudGlkYWQiLA0KICAgICAgICBtYWluPSAiR3JhZmljYSBkZSBkZWxpdG9zIGNvbWV0aWRvcyBwb3IgWCBob3JhIiwNCiAgICAgICAgbGFzPTIpDQpgYGANCiMjIyAqQ29uY2x1c2lvbiA3OiBTZWd1biBtdWVzdHJhIGxhIGdyYWZpY2EsIGxhIG1heW9yIHBhcnRlIGRlIGxvcyBoZWNob3MgZGVsaWN0aXZvcyBzb24gY29tZXRpZG9zIGVudHJlIGxhcyA5IHkgbGFzIDIxIGhvcmFzIGRlIGRpYSoNCg0KDQojIyMgOC4gUXVlIGRpYSBlcyBlbCBxdWUgbWFzIGRlbGl0b3MgaGF5DQpgYGB7cn0NCmRhdGFzZXQlPiUNCiAgZ3JvdXBfYnkoTm9tYnJlZGVsRGlhKSAlPiUNCiAgc3VtbWFyaXNlKGNhbnRpZGFkPW4oKSklPiUNCiAgYXJyYW5nZSgtY2FudGlkYWQpJT4lDQogICAgZ2dwbG90KGFlcyh5PXJlb3JkZXIoTm9tYnJlZGVsRGlhLGNhbnRpZGFkKSwgeD1jYW50aWRhZCkpKw0KICBnZW9tX3BvaW50KGNvbG9yID0gJ3JlZCcsIGZpbGwgPSAncmVkJywgc2l6ZSA9IDQsIHNoYXBlID0gMTgsIGFscGhhID0gMC41KSArDQogIHhsYWIoJ0RlbGl0bycpICsgDQogIHlsYWIoJ0RpYXMgZGUgbGEgc2VtYW5hJykgKw0KICBnZ3RpdGxlICgiQ2FudGlkYWQgdG90YWwgcG9yIERpYSIpICsgIyBUw610dWxvIGRlbCBncsOhZmljbw0KICB0aGVtZSAocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPXJlbCgyKSwgI1RhbWHDsW8gcmVsYXRpdm8gZGUgbGEgbGV0cmEgZGVsIHTDrXR1bG8NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2anVzdD0yLCAjSnVzdGlmaWNhY2nDs24gdmVydGljYWwsIHBhcmEgc2VwYXJhcmxvIGRlbCBncsOhZmljbw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY2U9ImJvbGQiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj0iYmx1ZSIsICNDb2xvciBkZWwgdGV4dG8NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5laGVpZ2h0PTEuNSkpKw0KIGdlb21fdGV4dChhZXMobGFiZWw9Y2FudGlkYWQpLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpLCB2anVzdD0tLjUpKw0KICBjb29yZF9mbGlwKCkNCmBgYA0KDQoNCiMjIyAqQ29uY2x1c2lvbiA4OiBFbCBkaWEgY29uIG1hcyBkZWxpdG9zIHNvbiBsb3MgZGlhcyBMdW5lcyB5IE1hcnRlcywgeSBlbCBkaWEgY29uIG1lbm9zIGRlbGl0b3Mgc29uIGxvcyBkaWFzIERvbWluZ28qDQoNCg0KDQojIyMgOS4gRXZhbHVhciBzaSBleGlzdGUgdW4gaW5jcmVtZW50byBkZSBkZWxpdG9zIGVuIGxvcyBtZXNlcyBkZSBib25vIDE0IHkgQWd1aW5hbGRvDQoNCmBgYHtyfQ0KSGVjaG9zeG1lcz0gYXMuZGF0YS5mcmFtZShwcm9wLnRhYmxlKHRhYmxlKGRhdGFzZXQkTWVzLCBkYXRhc2V0JEdydXBvRGVsaXRvKSwgMikqMTAwKQ0KY29sbmFtZXMoSGVjaG9zeG1lcyk8LWMoIk1FUyIsICJEZWxpdG8iLCJQQ1QiKQ0KZ3I0IDwtIGdncGxvdChIZWNob3N4bWVzLCBhZXMoeD1NRVMsIHk9UENUKSkgKyBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsIGZpbGwgPSAnc3RlZWxibHVlJykNCmdyNA0KZ3I0ICsgY29vcmRfZmxpcCgpICsgZmFjZXRfd3JhcCh+IERlbGl0bykNCmBgYA0KDQoNCiMjIyAqQ29uY2x1c2lvbiA5OiAjIyMgTGEgc2lndWllbnRlIGdyYWZpY2EgbXVlc3RyYSBsYSBvY3VycmVuY2lhIGRlIGhlY2hvcyBkZWxpY3Rpdm9zIHBvciBtZXMsIGV2aWRlbmNpYW5kbyBxdWUgYXBhcnRpciBkZWwgTWVzIGRlIGp1bGlvIChib25vIDE0KSBzZSBpbmNyZW1lbnRhbjogTGFzIGV4dG9yc2lvbmVzIHkgbG9zIEhvbWljaWRpb3MuICBNaWVudHJhcyBxdWUgZHVyYW50ZSBlbCBtZXMgZGUgZGljaWVtYnJlIHNvbG8gc2UgZGVub3RhIHVuIGluY3JlbWVudG8gZW4gbG9zIGxvcyBIZWNob3MgZGVsaWN0aXZvcyBlbiBjb250cmEgZWwgcGF0cmltb25pby4NCg0KDQoNCiMjIyAxMC4JQ3VhbnRvIGRlIGxvcyBkZWxpdG9zIHNvbiBwb3IgdGVtYSBkZSBleHRvcnNpb25lcyBlbiBidXNlcyAodXJiYW5vcyB5IGV4dHJhdXJiYW5vcyApDQoNCmBgYHtyfQ0KYnVzZXM9IGRhdGFzZXQlPiUNCiAgZmlsdGVyKChEZWxpdG89PSJFeHRvcnNpw7NuIGEgYnVzZXMgdXJiYW5vcyIpIHwgKERlbGl0bz09IkV4dG9yc2nDs24gYSBidXNlcyBleHRyYXVyYmFub3MiKSklPiUNCiAgbnJvdygpDQogIGJ1c2VzDQogIA0KYGBgDQoNCmBgYHtyfQ0KVG90YWxEZWxpdG9zPWRhdGFzZXQlPiUNCiAgZ3JvdXBfYnkoRGVsaXRvKSU+JQ0KICBucm93KCkNCiAgVG90YWxEZWxpdG9zDQpgYGANCg0KIyMjICUgZGUgRGVsaXRvcyBxdWUgc29uIEV4dG9yc2lvbmVzIGEgYnVzZXMgdXJiYW5vcw0KYGBge3J9DQooYnVzZXMvVG90YWxEZWxpdG9zKQ0KYGBgDQoNCiMjIyAqQ29uY2x1c2lvbiAxMDogRWwgMSUgZGUgbG9zIGRlbGl0b3Mgc2UgZGViZW4gYSBleHRvcnNpb25lcyBhIGJ1c2VzIHVyYmFub3MgeSBleHRyYXVyYmFub3MqDQoNCg0KIyAqKkFuYWxpc2lzIFBERioqDQojICoqRGVmaW5pY2lvbiBkZWwgcHJvYmxlbWEqKg0KIyMjICpBQ0FBQUFBQUFBQUEgZGVmaW5pciBlbCBwcm9ibGVtYTogVGVuZW1vcyB1biByZWdpc3RybyBkZSA2NTQgSG9taWNpZGlvcyBkZSBsb3MgY3VhbGVzIDExMiBzb24gZGUgTXVqZXJlcyB5IDU0MiBzb24gZGUgaG9tYnJlcywgY3VhbCBlcyBsYSBmdW5jaW9uIGRlIGRlbnNpZGFkIGRlIHF1ZSBzZWFuIE11amVyZXMgeSBjdWFsIGVzIGxhIGRlbnNpZGFkIHF1ZSBzZWFuIEhvbWJyZSAoc2llbmRvIDEgSG9tYnJlcyB5IDAgTXVqZXJlcykqDQoNCg0KYGBge3J9DQp4PWMoMCwxKQ0KbmNvbCgoY29tYm4oNTQyLDEpKSkNCg0KYGBgDQoNCmBgYHtyfQ0KUE1GMT1mdW5jdGlvbih4KXsNCiAgbnVtMT1uY29sKGNvbWJuKDExMix4KSkNCiAgbnVtMj1uY29sKGNvbWJuKDU0MiwxLXgpKQ0KICBkZW5vbT1uY29sKGNvbWJuKDY1NCwxKSkNCiAgc2FsaWRhPShudW0xKm51bTIpLyhkZW5vbSkNCiAgcmV0dXJuKHNhbGlkYSkNCn0NClBNRjEgKDApDQpgYGANCg0KYGBge3J9DQpQTUYxICgxKQ0KYGBgDQojDQoNCmBgYHtyfQ0KcGRmPXNhcHBseSh4LCBGVU49UE1GMSkNCnBkZg0KYGBgDQoNCmBgYHtyfQ0KZGF0b3M9ZGF0YS5mcmFtZSh4PXgscHg9cGRmKQ0KZGF0b3MNCmBgYA0KIyMjICpDb25jbHVzaW9uIFBERjogTGEgZGVuc2lkYWQgZGUgcHJvYmFiaWxpZGFkIHF1ZSB1bmEgbXVqZXIgc2VhIHZpY3RpbWEgZGUgaG9taWNpZGlvIGVuIGVsIG11bmljaXBpbyBkZSBHdWF0ZW1hbGEgZXMgZWwgMTcuMTIlKg0KDQoNCiMjIyBPYnRlbmVyIGVsIENERg0KDQpgYGB7cn0NCmNkZj1jdW1zdW0ocGRmKQ0KY2RmDQpgYGANCmBgYHtyfQ0KZGF0b3M9ZGF0YS5mcmFtZShkYXRvcyxGeD1jZGYpDQpkYXRvcw0KYGBgDQpgYGB7cn0NCnZhbG9yX2VzcGVyYWRvPWZ1bmN0aW9uKGRmKXsNCng9ZGZbICwxXQ0KcHg9ZGYgWyAsMl0NClZFPXN1bSh4KnB4KQ0KcmV0dXJuKFZFKX0NCmBgYA0KYGBge3J9DQp2YWxvcl9lc3BlcmFkbyhkYXRvcykgI21lZGlhIHBvbmRlcmFkYQ0KYGBgDQojIyMgT2J0ZW5lciBsYSBWYXJpYW56YQ0KYGBge3J9DQp2YXJpYW56YT1mdW5jdGlvbihkZil7DQogIG1lZGlhPXZhbG9yX2VzcGVyYWRvKGRmKQ0KICB4PWRmIFsgLDFdDQogIHB4PWRmIFsgLDJdDQogIHZhclg9c3VtKCgoeC1tZWRpYSleMikqKHB4KSkNCiAgcmV0dXJuKHZhclgpDQogIA0KfQ0KYGBgDQoNCmBgYHtyfQ0KdmFyaWFuemEoZGF0b3MpDQpgYGANCg0KIyMjICpDb25jbHVzaW9uIENERiBQb2RlbW9zIG9ic2VydmFyIGxhIHZhcmlhYmlsaWRhZCBkZSBsb3MgZGF0b3MgYSB1biAwLjE0LCBsYSBjdWFsIGluZGljYSBsYSBkaXN0YW5jaWEgcXVlIGhheSBoYWNpYSBsYSBtZWRpYSoNCg0KDQojIyMgKipCZXN0IEZpdCwgdG9tYW5kbyBlbiBjdWVudGEgbGEgRWRhZCoqDQoNCmBgYHtyfQ0KZGF0YXNldCRlZGFkX3Blcg0KYGBgDQoNCg0KYGBge3J9DQpFZGFkQ29ycmVjdGE9ZGF0YXNldFsoZGF0YXNldCRlZGFkX3Blcjw5OTkpLCAyMF0NCmBgYA0KDQpgYGB7cn0NClRhYmxhRWRhZD1kYXRhX2ZyYW1lKHRhYmxlKEVkYWRDb3JyZWN0YSkpDQpgYGANCmBgYHtyfQ0KVGFibGFFZGFkDQpgYGANCg0KYGBge3J9DQpkZXNjZGlzdChFZGFkQ29ycmVjdGEsIGRpc2NyZXRlID0gRkFMU0UpDQpgYGANCg0KYGBge3J9DQpoaXN0KEVkYWRDb3JyZWN0YSwNCiAgICAgICAgY29sPWJsdWVzOSwNCiAgICAgICAgeGxhYj0gIkVkYWQiLA0KICAgICAgICB5bGFiPSAiQ2FudGlkYWQgZGUgRGVsaXRvcyIsDQogICAgICAgIG1haW49ICJHcmFmaWNhIGRlIGRlbGl0b3MgcG9yIGVkYWQiLA0KICAgICAgICBsYXM9MikNCmBgYA0KDQojIyMgKkNvbmNsdXNpb24gQkVTVCBGSVQ6IEFsIGFuYWxpemFyIGxhIGNhbnRpZGFkIGRlIERlbGl0b3MgcG9yIGVkYWQgIHBvZGVtb3MgY29uY2x1aXIgcXVlIHNlIGFwZWdhIGEgdW5hIGRpc3RyaWJ1Y2lvbiBub3JtYWwsIG1pc21hIHNlIHZhbGlkbyByZWFsaXphbmRvIHVuIGhpc3RvZ3JhbWEgZGUgZnJlY3VlbmNpYSBwb3IgZWRhZCBlbCBjdWFsIHNlIHB1ZWRlIHZlciB1biBsZXZlIHNlc2dvIGhhY2lhIGxhIGRlcmVjaGEsIHNpZW5kbyBsYXMgZWRhZGVzIG1hcyB2dWxuZXJhYmxlcyBlbnRyZSBsb3MgMjAgeSA0MCBhw7Fvcy4gICoNCg0K