En el análisis de datos, la limpieza y modificación de bases de datos
son esenciales para garantizar la calidad y precisión de los resultados.
Este documento presenta el código en R utilizado para depurar y
transformar algunas de las bases de datos utilizadas. El objetivo es
proporcionar una visión clara del proceso de limpieza y las
modificaciones realizadas, asegurando la integridad y utilidad de los
datos para su análisis posterior.
Primero, cargaremos las librerías necesarias.
library(readxl)
library(openxlsx)
library(lubridate)
library(dplyr)
library(stringr)
También cargaremos las bases de datos correspondientes.
CASOS <- read_excel("CASOS _SERV_AGR_OP - MAY-JUN-2024.xlsx", + sheet = "CASOS")
AGRESORES <- read_excel("CASOS _SERV_AGR_OP - MAY-JUN-2024.xlsx", + sheet = "AGRESORES")
ORDENES <- read_excel("CASOS _SERV_AGR_OP - MAY-JUN-2024.xlsx", + sheet = "OP")
SERVICIOS <- read_excel("CASOS _SERV_AGR_OP - MAY-JUN-2024.xlsx", + sheet = "SERV")
se agregará a la base de casos y de agresores el día, mes y año
correspondiente a la fecha hecho, se realizará la clasificación de la
edad en un rango para ahora tener una variable categórica y además se
hará reclasificación en los datos relacionados con escolaridad,
situación conyugal y ocupación.
CASOS$dia_semana <- NA
CASOS$mes <- NA
CASOS$año <- NA
CASOS$rangoedad <- "Desconocida"
CASOS$edocivil <- "Desconocida"
CASOS$escolar <- "Desconocida"
CASOS$ocupacion2 <- "Desconocida"
for (x in 1:nrow(CASOS)) {
if(!is.na(CASOS$Edad[i])){
if(CASOS$Edad[i] <= 5){
CASOS$rangoedad[i] <- "5 y menos"
}
if(CASOS$Edad[i] > 5 & CASOS$Edad[i] <= 14){
CASOS$rangoedad[i] <- "6 a 14"
}
if(CASOS$Edad[i] > 14 & CASOS$Edad[i] <= 24){
CASOS$rangoedad[i] <- "15 a 24"
}
if(CASOS$Edad[i] > 24 & CASOS$Edad[i] <= 44){
CASOS$rangoedad[i] <- "25 a 44"
}
if(CASOS$Edad[i] > 44 & CASOS$Edad[i] <= 59){
CASOS$rangoedad[i] <- "45 a 59"
}
if(CASOS$Edad[i] >= 60){
CASOS$rangoedad[i] <- "60 y más"
}
}
if(!is.na(CASOS$`Estado Civil`[i])){
if(CASOS$`Estado Civil`[i] == "Casada" | CASOS$`Estado Civil`[i] == "Unión libre" |
CASOS$`Estado Civil`[i] == "Concubinato" | CASOS$`Estado Civil`[i] == "Sociedad de convivencia"){
CASOS$edocivil[i] <- "Casada o unida"
}
if(CASOS$`Estado Civil`[i] == "Soltera"){
CASOS$edocivil[i] <- "Soltera"
}
if(CASOS$`Estado Civil`[i] == "Divorciada" |
CASOS$`Estado Civil`[i] == "Viuda" |
CASOS$`Estado Civil`[i] == "Separada"){
CASOS$edocivil[i] <- "Separada, divorciada o viuda"
}
if(CASOS$`Estado Civil`[i] == "No identificada" |
CASOS$`Estado Civil`[i] == "Desconocido"){
CASOS$edocivil[i] <- "Desconocida"
}
}
if(!is.na(CASOS$Escolaridad[i])){
if(CASOS$Escolaridad[i] == "Primaria"){
CASOS$escolar[i] <- "Primaria"
}
if(CASOS$Escolaridad[i] == "No identificado" |
CASOS$Escolaridad[i] == "NULL"){
CASOS$escolar[i] <- "Desconocida"
}
if(CASOS$Escolaridad[i] == "Secundaria"){
CASOS$escolar[i] <- "Secundaria"
}
if(CASOS$Escolaridad[i] == "Carrera técnica comercial" |
CASOS$Escolaridad[i] == "Preparatoria"){
CASOS$escolar[i] <- "Preparatoria"
}
if(CASOS$Escolaridad[i] == "Licenciatura" |
CASOS$Escolaridad[i] == "Posgrado" |
CASOS$Escolaridad[i] == "Maestría" |
CASOS$Escolaridad[i] == "Doctorado"){
CASOS$escolar[i] <- "Superior"
}
if(CASOS$Escolaridad[i] == "Preescolar" |
CASOS$Escolaridad[i] == "Estudios que no requieren validéz oficial"|
CASOS$Escolaridad[i] == "Ninguna"){
CASOS$escolar[i] <- "Ninguna"
}
}
if(!is.na(CASOS$VictSeDesconoce[i]) | !is.na(CASOS$VictOtro[i]) |
!is.na(CASOS$VictActIlicita[i]) | !is.na(CASOS$VictNinguna[i])){
if(CASOS$VictSeDesconoce[i] == 1 | CASOS$VictOtro[i]== 1 |
CASOS$VictActIlicita[i] == 1 | CASOS$VictNinguna[i] == 1){
CASOS$ocupacion2[i] <- "Otra"
}
}
if(!is.na(CASOS$VictTrabajaHogar[i]) | !is.na(CASOS$VictTrabajaFHogar[i])){
if(CASOS$VictTrabajaHogar[i] == 1 | CASOS$VictTrabajaFHogar[i] == 1){
CASOS$ocupacion2[i] <- "Trabaja"
}
}
if(!is.na(CASOS$VictEstudia[i])){
if(CASOS$VictEstudia[i] == 1){
CASOS$ocupacion2[i] <- "Estudia"
}
}
if(!is.na(CASOS$VictJubiladaPensionada[i]) | !is.na(CASOS$VictPensionada[i])){
if(CASOS$VictJubiladaPensionada[i] == 1 | CASOS$VictPensionada[i] == 1){
CASOS$ocupacion2[i] <- "Jubilada pensionada"
}
}
fecha_numeros <- as.numeric(CASOS$`Fecha hechos`[x])
base<- as.Date("1899-12-30")
fecha<- base+fecha_numeros
fecha_hora_objeto <- as.POSIXct(fecha, format = "%d-%m-%Y")
# Obtén el día de la semana
CASOS$dia_semana[x] <- weekdays(fecha_hora_objeto)
# Obtén el mes y el año
CASOS$mes[x] <- format(fecha_hora_objeto, "%B") # Obtiene el nombre del mes completo
CASOS$año[x] <- format(fecha_hora_objeto, "%Y")
CASOS$Dia <- NA
dias <- c("2.Lun", "3.Mar", "4.Mie", "5.Jue", "6.Vie", "7.Sab", "1.Dom")
dias_com <- c("lunes", "martes", "miércoles", "jueves", "viernes", "sábado", "domingo")
for (i in 1:nrow(CASOS)) {
for (j in 1:length(dias_com)){
if(!is.na(CASOS$dia_semana[i]) & CASOS$dia_semana[i]==dias_com[j]){
CASOS$Dia[i] <- dias[j]
break
}
}
}
}
AGRESORES$dia_semana <- NA
AGRESORES$mes <- NA
AGRESORES$año <- NA
AGRESORES$rangoedad <- NA
AGRESORES$estadocivil <- "Desconocida"
AGRESORES$escolar <- "Desconocida"
AGRESORES$ocupacion2 <- NA
for (x in 1:nrow(AGRESORES)) {
fecha_numeros <- as.numeric(AGRESORES$fecha_hechos[x])
base<- as.Date("1899-12-30")
fecha<- base+fecha_numeros
fecha_hora_objeto <- as.POSIXct(fecha, format = "%d-%m-%Y")
# Obtén el día de la semana
AGRESORES$dia_semana[x] <- weekdays(fecha_hora_objeto)
# Obtén el mes y el año
AGRESORES$mes[x] <- format(fecha_hora_objeto, "%B") # Obtiene el nombre del mes completo
AGRESORES$año[x] <- format(fecha_hora_objeto, "%Y")
if(!is.na(AGRESORES$`Edad del Agresor`[i])){
if(AGRESORES$`Edad del Agresor`[i] <= 5){
AGRESORES$rangoedad[i] <- "5 y menos"
}
if(AGRESORES$`Edad del Agresor`[i] > 5 & AGRESORES$`Edad del Agresor`[i] <= 14){
AGRESORES$rangoedad[i] <- "6 a 14"
}
if(AGRESORES$`Edad del Agresor`[i] > 14 & AGRESORES$`Edad del Agresor`[i] <= 24){
AGRESORES$rangoedad[i] <- "15 a 24"
}
if(AGRESORES$`Edad del Agresor`[i] > 24 & AGRESORES$`Edad del Agresor`[i] <= 44){
AGRESORES$rangoedad[i] <- "25 a 44"
}
if(AGRESORES$`Edad del Agresor`[i] > 44 & AGRESORES$`Edad del Agresor`[i] <= 59){
AGRESORES$rangoedad[i] <- "45 a 59"
}
if(AGRESORES$`Edad del Agresor`[i] >= 60){
AGRESORES$rangoedad[i] <- "60 y más"
}
}
if(!is.na(AGRESORES$EdoCivil[i])){
if(AGRESORES$EdoCivil[i] == "Casado" | AGRESORES$EdoCivil[i] == "Unión libre" |
AGRESORES$EdoCivil[i] == "Concubinato" | AGRESORES$EdoCivil[i] == "Sociedad de convivencia"){
AGRESORES$estadocivil[i] <- "Casado(a) o unido(a)"
}
if(AGRESORES$EdoCivil[i] == "Soltero"){
AGRESORES$estadocivil[i] <- "Soltero(a)"
}
if(AGRESORES$EdoCivil[i] == "Divorciado" |
AGRESORES$EdoCivil[i] == "Viudo" |
AGRESORES$EdoCivil[i] == "Separado"){
AGRESORES$estadocivil[i] <- "Separado(a), divorciado(a) o viudo(a)"
}
if(AGRESORES$EdoCivil[i] == "No identificado" |
AGRESORES$EdoCivil[i] == "NULL"|
AGRESORES$EdoCivil[i] == "Seleccione"){
AGRESORES$estadocivil[i] <- "Desconocida"
}
}
if(!is.na(AGRESORES$Escolaridad[i])){
if(AGRESORES$Escolaridad[i] == "Primaria"){
AGRESORES$escolar[i] <- "Primaria"
}
if(AGRESORES$Escolaridad[i] == "No identificado" |
AGRESORES$Escolaridad[i] == "NULL"){
AGRESORES$escolar[i] <- "Desconocida"
}
if(AGRESORES$Escolaridad[i] == "Secundaria"){
AGRESORES$escolar[i] <- "Secundaria"
}
if(AGRESORES$Escolaridad[i] == "Carrera técnica comercial" |
AGRESORES$Escolaridad[i] == "Preparatoria"){
AGRESORES$escolar[i] <- "Preparatoria"
}
if(AGRESORES$Escolaridad[i] == "Licenciatura" |
AGRESORES$Escolaridad[i] == "Posgrado" |
AGRESORES$Escolaridad[i] == "Maestría" |
AGRESORES$Escolaridad[i] == "Doctorado"){
AGRESORES$escolar[i] <- "Superior"
}
if(AGRESORES$Escolaridad[i] == "Preescolar" |
AGRESORES$Escolaridad[i] == "Estudios que no requieren validéz oficial"|
AGRESORES$Escolaridad[i] == "Ninguna"){
AGRESORES$escolar[i] <- "Ninguna"
}
}
if(!is.na(AGRESORES$PrinActAgSinDato[i]) | !is.na(AGRESORES$PrinActAgSeDesc[i]) |
!is.na(AGRESORES$PrinActAgOtro[i]) | !is.na(AGRESORES$PrinActAgNing[i])|
!is.na(AGRESORES$PrinActAgActIlicita[i])){
if(AGRESORES$PrinActAgSinDato[i] == 1 | AGRESORES$PrinActAgSeDesc[i] == 1 |
AGRESORES$PrinActAgOtro[i] == 1 | AGRESORES$PrinActAgNing[i] == 1 |
AGRESORES$PrinActAgActIlicita[i] == 1 ){
AGRESORES$ocupacion2[i] <- "Otra"
}
}
if(!is.na(AGRESORES$PrinActAgTrabHogar[i]) | !is.na(AGRESORES$PrinActAgTrabFHogar[i])){
if(AGRESORES$PrinActAgTrabHogar[i] == 1 | AGRESORES$PrinActAgTrabFHogar[i] == 1){
AGRESORES$ocupacion2[i] <- "Trabaja"
}
}
if(!is.na(AGRESORES$PrinActAgEstudia[i])){
if(AGRESORES$PrinActAgEstudia[i] == 1){
AGRESORES$ocupacion2[i] <- "Estudia"
}
}
if(!is.na(AGRESORES$PrinActAgJubPens[i]) | !is.na(AGRESORES$PrinActAgPens[i])){
if(AGRESORES$PrinActAgJubPens[i] == 1 | AGRESORES$PrinActAgPens[i] == 1){
AGRESORES$ocupacion2[i] <- "Jubilado(a) pensionado(a)"
}
}
}
De igual manera se realizó una nueva clasificación a los datos
relacionados con el vínculo con agresor y además se trabajo con
modalidad de violencia, a la cual se realiza limpieza y a partir de
ella, obtenemos una nueva columna de datos, la cual nos indica cuando un
caso llegó a ser feminicidio.
CASOS$Modalidad <- NA
CASOS$feminicidios <- 0
CASOS$"Vínculo(original)" <- CASOS$`Detalle de Vínculo con victima`
CASOS$"Habla lengua indigena" <- 0
familiares <- c("Hijo(a)", "Padrastro o madrastra", "Sobrino(a)", "Abuelo(a)",
"Tío(a)", "Primo(a)", "Hermano(a)", "Suegro(a)", "Nieto(a)")
for(x in 1:nrow(CASOS)){
if(!is.na(CASOS$`Modalidad de la Violencia`[x])){
if(CASOS$`Modalidad de la Violencia`[x] == "1 - Familiar"){
CASOS$Modalidad[x] <- "Familiar"
}
if(CASOS$`Modalidad de la Violencia`[x] == "2 - Laboral"){
CASOS$Modalidad[x] <- "Laboral"
}
if(CASOS$`Modalidad de la Violencia`[x] == "3 - Institucional"){
CASOS$Modalidad[x] <- "Institucional"
}
if(CASOS$`Modalidad de la Violencia`[x] == "4 - En la comunidad" |
CASOS$`Modalidad de la Violencia`[x] == "Enlacomunidad"){
CASOS$Modalidad[x] <- "Comunitaria"
}
if(CASOS$`Modalidad de la Violencia`[x] == "5 - Escolar/Docente"){
CASOS$Modalidad[x] <- "Escolar"
}
if(CASOS$`Modalidad de la Violencia`[x] == "6 - Obstétrica"){
CASOS$Modalidad[x] <- "Obstétrica"
}
if(CASOS$`Modalidad de la Violencia`[x] == "7 - Política"){
CASOS$Modalidad[x] <- "Política"
}
if(CASOS$`Modalidad de la Violencia`[x] == "9 - Feminicida"){
CASOS$Modalidad[x] <- "Feminicida"
}
if(CASOS$`Modalidad de la Violencia`[x] == "8 - Digital/Cibernética"){
CASOS$Modalidad[x] <- "Digital"
}
}
if(CASOS$Modalidad[i] == "Feminicida"){
CASOS$feminicidios[i] <- 1
}
if(CASOS$"Habla Indigena"[i] == "Si"){
CASOS$"Habla lengua indigena"[i] <- 1
}
if(!is.na(CASOS$`Detalle de Vínculo con victima`[i])){
for (j in familiares) {
if(CASOS$`Detalle de Vínculo con victima`[i] == j){
CASOS$`Detalle de Vínculo con victima`[i] <- "Otros familiares"
break
}
}
if(CASOS$`Detalle de Vínculo con victima`[i] == "Otro"){
CASOS$`Detalle de Vínculo con victima`[i] <- "Otra relación"
}
if(CASOS$`Detalle de Vínculo con victima`[i] == "NULL"){
CASOS$`Detalle de Vínculo con victima`[i] <- "Desconocido"
}
if(CASOS$`Detalle de Vínculo con victima`[i] == "Concubina"){
CASOS$`Detalle de Vínculo con victima`[i] <- "Cónyuge o pareja"
}
}
}
Se agrega una nueva columna correspondiente al estado de hecho, la
cual se obtiene a partir de los datos de municipio hecho.
Municipio = c("Abasolo", "Agualeguas", "Los Aldamas", "Allende", "Anáhuac",
"Apodaca", "Aramberri", "Bustamante", "Cadereyta Jiménez",
"El Carmen", "Cerralvo", "Ciénega de Flores", "China",
"Doctor Arroyo", "Doctor Coss", "Doctor González",
"Los Herrera", "Galeana", "García", "General Bravo",
"General Escobedo", "General Terán", "General Treviño",
"General Zaragoza", "General Zuazua", "Guadalupe",
"Hidalgo", "Higueras", "Hualahuises", "Iturbide",
"Juárez", "Lampazos de Naranjo", "Linares", "Marín",
"Melchor Ocampo", "Mier y Noriega", "Mina", "Montemorelos",
"Monterrey", "Paras", "Pesquería", "Los Ramones",
"Rayones", "Sabinas Hidalgo", "Salinas Victoria",
"San Nicolás de los Garza", "San Pedro Garza García",
"Santa Catarina", "Santiago", "Vallecillo", "Villaldama")
CASOS$estado <- NA
for (i in 1:nrow(CASOS)) {
if(!is.na(CASOS$`Municipio Hecho`[i])){
for (j in Municipio) {
if(CASOS$`Municipio Hecho`[i] == j ){
CASOS$estado[i] <- "Nuevo León"
}
}
}
}
LS0tDQp0aXRsZTogIk1lbW9yaWEgZGUgY8OhbGN1bG8iDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBkZl9wcmludDogcGFnZWQNCiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0DQotLS0NCg0KYGBgez1odG1sfQ0KPHN0eWxlPg0KcCB7DQogIHRleHQtYWxpZ246IGp1c3RpZnk7DQp9DQo8L3N0eWxlPg0KYGBgDQpFbiBlbCBhbsOhbGlzaXMgZGUgZGF0b3MsIGxhIGxpbXBpZXphIHkgbW9kaWZpY2FjacOzbiBkZSBiYXNlcyBkZSBkYXRvcyBzb24gZXNlbmNpYWxlcyBwYXJhIGdhcmFudGl6YXIgbGEgY2FsaWRhZCB5IHByZWNpc2nDs24gZGUgbG9zIHJlc3VsdGFkb3MuIEVzdGUgZG9jdW1lbnRvIHByZXNlbnRhIGVsIGPDs2RpZ28gZW4gUiB1dGlsaXphZG8gcGFyYSBkZXB1cmFyIHkgdHJhbnNmb3JtYXIgYWxndW5hcyBkZSBsYXMgYmFzZXMgZGUgZGF0b3MgdXRpbGl6YWRhcy4gRWwgb2JqZXRpdm8gZXMgcHJvcG9yY2lvbmFyIHVuYSB2aXNpw7NuIGNsYXJhIGRlbCBwcm9jZXNvIGRlIGxpbXBpZXphIHkgbGFzIG1vZGlmaWNhY2lvbmVzIHJlYWxpemFkYXMsIGFzZWd1cmFuZG8gbGEgaW50ZWdyaWRhZCB5IHV0aWxpZGFkIGRlIGxvcyBkYXRvcyBwYXJhIHN1IGFuw6FsaXNpcyBwb3N0ZXJpb3IuDQoNClByaW1lcm8sIGNhcmdhcmVtb3MgbGFzIGxpYnJlcsOtYXMgbmVjZXNhcmlhcy4NCg0KYGBge3J9DQpsaWJyYXJ5KHJlYWR4bCkNCmxpYnJhcnkob3Blbnhsc3gpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHN0cmluZ3IpDQpgYGANCg0KVGFtYmnDqW4gY2FyZ2FyZW1vcyBsYXMgYmFzZXMgZGUgZGF0b3MgY29ycmVzcG9uZGllbnRlcy4NCg0KYGBge3J9DQogQ0FTT1MgPC0gcmVhZF9leGNlbCgiQ0FTT1MgX1NFUlZfQUdSX09QIC0gTUFZLUpVTi0yMDI0Lnhsc3giLCArIHNoZWV0ID0gIkNBU09TIikNCiBBR1JFU09SRVMgPC0gcmVhZF9leGNlbCgiQ0FTT1MgX1NFUlZfQUdSX09QIC0gTUFZLUpVTi0yMDI0Lnhsc3giLCArIHNoZWV0ID0gIkFHUkVTT1JFUyIpDQogT1JERU5FUyA8LSByZWFkX2V4Y2VsKCJDQVNPUyBfU0VSVl9BR1JfT1AgLSBNQVktSlVOLTIwMjQueGxzeCIsICsgc2hlZXQgPSAiT1AiKQ0KIFNFUlZJQ0lPUyA8LSByZWFkX2V4Y2VsKCJDQVNPUyBfU0VSVl9BR1JfT1AgLSBNQVktSlVOLTIwMjQueGxzeCIsICsgc2hlZXQgPSAiU0VSViIpDQpgYGANCg0Kc2UgYWdyZWdhcsOhIGEgbGEgYmFzZSBkZSBjYXNvcyB5IGRlIGFncmVzb3JlcyBlbCBkw61hLCBtZXMgeSBhw7FvIGNvcnJlc3BvbmRpZW50ZSBhIGxhIGZlY2hhIGhlY2hvLCBzZSByZWFsaXphcsOhIGxhIGNsYXNpZmljYWNpw7NuIGRlIGxhIGVkYWQgZW4gdW4gcmFuZ28gcGFyYSBhaG9yYSB0ZW5lciB1bmEgdmFyaWFibGUgY2F0ZWfDs3JpY2EgeSBhZGVtw6FzIHNlIGhhcsOhIHJlY2xhc2lmaWNhY2nDs24gZW4gbG9zIGRhdG9zIHJlbGFjaW9uYWRvcyBjb24gZXNjb2xhcmlkYWQsIHNpdHVhY2nDs24gY29ueXVnYWwgeSBvY3VwYWNpw7NuLg0KDQpgYGB7cn0NCkNBU09TJGRpYV9zZW1hbmEgPC0gTkENCkNBU09TJG1lcyA8LSBOQQ0KQ0FTT1MkYcOxbyA8LSBOQQ0KDQoNCg0KQ0FTT1MkcmFuZ29lZGFkIDwtICJEZXNjb25vY2lkYSINCkNBU09TJGVkb2NpdmlsIDwtICJEZXNjb25vY2lkYSINCkNBU09TJGVzY29sYXIgPC0gIkRlc2Nvbm9jaWRhIg0KQ0FTT1Mkb2N1cGFjaW9uMiA8LSAiRGVzY29ub2NpZGEiDQoNCg0KDQpmb3IgKHggaW4gMTpucm93KENBU09TKSkgew0KDQogIA0KICAgaWYoIWlzLm5hKENBU09TJEVkYWRbaV0pKXsNCiAgICBpZihDQVNPUyRFZGFkW2ldIDw9IDUpew0KICAgICAgQ0FTT1MkcmFuZ29lZGFkW2ldIDwtICI1IHkgbWVub3MiDQogICAgfQ0KICAgIGlmKENBU09TJEVkYWRbaV0gPiA1ICYgQ0FTT1MkRWRhZFtpXSA8PSAxNCl7DQogICAgICBDQVNPUyRyYW5nb2VkYWRbaV0gPC0gIjYgYSAxNCINCiAgICB9DQogICAgaWYoQ0FTT1MkRWRhZFtpXSA+IDE0ICYgQ0FTT1MkRWRhZFtpXSA8PSAyNCl7DQogICAgICBDQVNPUyRyYW5nb2VkYWRbaV0gPC0gIjE1IGEgMjQiDQogICAgfQ0KICAgIGlmKENBU09TJEVkYWRbaV0gPiAyNCAmIENBU09TJEVkYWRbaV0gPD0gNDQpew0KICAgICAgQ0FTT1MkcmFuZ29lZGFkW2ldIDwtICIyNSBhIDQ0Ig0KICAgIH0NCiAgICBpZihDQVNPUyRFZGFkW2ldID4gNDQgJiBDQVNPUyRFZGFkW2ldIDw9IDU5KXsNCiAgICAgIENBU09TJHJhbmdvZWRhZFtpXSA8LSAiNDUgYSA1OSINCiAgICB9DQogICAgaWYoQ0FTT1MkRWRhZFtpXSA+PSA2MCl7DQogICAgICBDQVNPUyRyYW5nb2VkYWRbaV0gPC0gIjYwIHkgbcOhcyINCiAgICB9DQogICB9DQogIA0KICANCiAgaWYoIWlzLm5hKENBU09TJGBFc3RhZG8gQ2l2aWxgW2ldKSl7DQogICAgaWYoQ0FTT1MkYEVzdGFkbyBDaXZpbGBbaV0gPT0gIkNhc2FkYSIgfCBDQVNPUyRgRXN0YWRvIENpdmlsYFtpXSA9PSAiVW5pw7NuICAgbGlicmUiIHwNCiAgICAgICBDQVNPUyRgRXN0YWRvIENpdmlsYFtpXSA9PSAiQ29uY3ViaW5hdG8iIHwgQ0FTT1MkYEVzdGFkbyBDaXZpbGBbaV0gPT0gIlNvY2llZGFkIGRlIGNvbnZpdmVuY2lhIil7DQogICAgICBDQVNPUyRlZG9jaXZpbFtpXSA8LSAiQ2FzYWRhIG8gdW5pZGEiDQogICAgfQ0KICAgIGlmKENBU09TJGBFc3RhZG8gQ2l2aWxgW2ldID09ICJTb2x0ZXJhIil7DQogICAgICBDQVNPUyRlZG9jaXZpbFtpXSA8LSAiU29sdGVyYSINCiAgICB9DQogICAgaWYoQ0FTT1MkYEVzdGFkbyBDaXZpbGBbaV0gPT0gIkRpdm9yY2lhZGEiIHwNCiAgICAgICBDQVNPUyRgRXN0YWRvIENpdmlsYFtpXSA9PSAiVml1ZGEiIHwNCiAgICAgICBDQVNPUyRgRXN0YWRvIENpdmlsYFtpXSA9PSAiU2VwYXJhZGEiKXsNCiAgICAgIENBU09TJGVkb2NpdmlsW2ldIDwtICJTZXBhcmFkYSwgZGl2b3JjaWFkYSBvIHZpdWRhIg0KICAgIH0NCiAgICBpZihDQVNPUyRgRXN0YWRvIENpdmlsYFtpXSA9PSAiTm8gaWRlbnRpZmljYWRhIiB8DQogICAgICAgQ0FTT1MkYEVzdGFkbyBDaXZpbGBbaV0gPT0gIkRlc2Nvbm9jaWRvIil7DQogICAgICBDQVNPUyRlZG9jaXZpbFtpXSA8LSAiRGVzY29ub2NpZGEiDQogICAgfQ0KICB9DQogIA0KICANCiAgDQogIGlmKCFpcy5uYShDQVNPUyRFc2NvbGFyaWRhZFtpXSkpew0KICAgIGlmKENBU09TJEVzY29sYXJpZGFkW2ldID09ICJQcmltYXJpYSIpew0KICAgICAgQ0FTT1MkZXNjb2xhcltpXSA8LSAiUHJpbWFyaWEiDQogICAgfQ0KICAgIGlmKENBU09TJEVzY29sYXJpZGFkW2ldID09ICJObyBpZGVudGlmaWNhZG8iIHwNCiAgICAgICBDQVNPUyRFc2NvbGFyaWRhZFtpXSA9PSAiTlVMTCIpew0KICAgICAgQ0FTT1MkZXNjb2xhcltpXSA8LSAiRGVzY29ub2NpZGEiDQogICAgfQ0KICAgIGlmKENBU09TJEVzY29sYXJpZGFkW2ldID09ICJTZWN1bmRhcmlhIil7DQogICAgICBDQVNPUyRlc2NvbGFyW2ldIDwtICJTZWN1bmRhcmlhIg0KICAgIH0NCiAgICBpZihDQVNPUyRFc2NvbGFyaWRhZFtpXSA9PSAiQ2FycmVyYSB0w6ljbmljYSBjb21lcmNpYWwiIHwNCiAgICAgICBDQVNPUyRFc2NvbGFyaWRhZFtpXSA9PSAiUHJlcGFyYXRvcmlhIil7DQogICAgICBDQVNPUyRlc2NvbGFyW2ldIDwtICJQcmVwYXJhdG9yaWEiDQogICAgfQ0KICAgIGlmKENBU09TJEVzY29sYXJpZGFkW2ldID09ICJMaWNlbmNpYXR1cmEiIHwNCiAgICAgICBDQVNPUyRFc2NvbGFyaWRhZFtpXSA9PSAiUG9zZ3JhZG8iIHwNCiAgICAgICBDQVNPUyRFc2NvbGFyaWRhZFtpXSA9PSAiTWFlc3Ryw61hIiB8DQogICAgICAgQ0FTT1MkRXNjb2xhcmlkYWRbaV0gPT0gIkRvY3RvcmFkbyIpew0KICAgICAgQ0FTT1MkZXNjb2xhcltpXSA8LSAiU3VwZXJpb3IiDQogICAgfQ0KICAgIGlmKENBU09TJEVzY29sYXJpZGFkW2ldID09ICJQcmVlc2NvbGFyIiB8DQogICAgICAgQ0FTT1MkRXNjb2xhcmlkYWRbaV0gPT0gIkVzdHVkaW9zIHF1ZSBubyByZXF1aWVyZW4gdmFsaWTDqXogb2ZpY2lhbCJ8DQogICAgICAgQ0FTT1MkRXNjb2xhcmlkYWRbaV0gPT0gIk5pbmd1bmEiKXsNCiAgICAgIENBU09TJGVzY29sYXJbaV0gPC0gIk5pbmd1bmEiDQogICAgfQ0KDQogIH0NCiAgDQogIGlmKCFpcy5uYShDQVNPUyRWaWN0U2VEZXNjb25vY2VbaV0pIHwgIWlzLm5hKENBU09TJFZpY3RPdHJvW2ldKSB8DQogICAgICFpcy5uYShDQVNPUyRWaWN0QWN0SWxpY2l0YVtpXSkgfCAhaXMubmEoQ0FTT1MkVmljdE5pbmd1bmFbaV0pKXsNCiAgICBpZihDQVNPUyRWaWN0U2VEZXNjb25vY2VbaV0gPT0gMSB8IENBU09TJFZpY3RPdHJvW2ldPT0gMSB8DQogICAgICAgQ0FTT1MkVmljdEFjdElsaWNpdGFbaV0gPT0gMSB8IENBU09TJFZpY3ROaW5ndW5hW2ldID09IDEpew0KICAgICAgQ0FTT1Mkb2N1cGFjaW9uMltpXSA8LSAiT3RyYSINCiAgICB9DQogIH0NCiAgaWYoIWlzLm5hKENBU09TJFZpY3RUcmFiYWphSG9nYXJbaV0pIHwgIWlzLm5hKENBU09TJFZpY3RUcmFiYWphRkhvZ2FyW2ldKSl7DQogICAgaWYoQ0FTT1MkVmljdFRyYWJhamFIb2dhcltpXSA9PSAxIHwgQ0FTT1MkVmljdFRyYWJhamFGSG9nYXJbaV0gPT0gMSl7DQogICAgICBDQVNPUyRvY3VwYWNpb24yW2ldIDwtICJUcmFiYWphIg0KICAgIH0NCiAgfQ0KICBpZighaXMubmEoQ0FTT1MkVmljdEVzdHVkaWFbaV0pKXsNCiAgICBpZihDQVNPUyRWaWN0RXN0dWRpYVtpXSA9PSAxKXsNCiAgICAgIENBU09TJG9jdXBhY2lvbjJbaV0gPC0gIkVzdHVkaWEiDQogICAgfQ0KICB9DQogIGlmKCFpcy5uYShDQVNPUyRWaWN0SnViaWxhZGFQZW5zaW9uYWRhW2ldKSB8ICFpcy5uYShDQVNPUyRWaWN0UGVuc2lvbmFkYVtpXSkpew0KICAgIGlmKENBU09TJFZpY3RKdWJpbGFkYVBlbnNpb25hZGFbaV0gPT0gMSB8IENBU09TJFZpY3RQZW5zaW9uYWRhW2ldID09IDEpew0KICAgICAgQ0FTT1Mkb2N1cGFjaW9uMltpXSA8LSAiSnViaWxhZGEgcGVuc2lvbmFkYSINCiAgICB9DQogIH0NCiAgDQogIA0KDQogIGZlY2hhX251bWVyb3MgPC0gYXMubnVtZXJpYyhDQVNPUyRgRmVjaGEgaGVjaG9zYFt4XSkNCiAgYmFzZTwtIGFzLkRhdGUoIjE4OTktMTItMzAiKQ0KICBmZWNoYTwtIGJhc2UrZmVjaGFfbnVtZXJvcw0KDQogIGZlY2hhX2hvcmFfb2JqZXRvIDwtIGFzLlBPU0lYY3QoZmVjaGEsIGZvcm1hdCA9ICIlZC0lbS0lWSIpDQoNCiAgIyBPYnTDqW4gZWwgZMOtYSBkZSBsYSBzZW1hbmENCiAgQ0FTT1MkZGlhX3NlbWFuYVt4XSA8LSB3ZWVrZGF5cyhmZWNoYV9ob3JhX29iamV0bykNCg0KICAjIE9idMOpbiBlbCBtZXMgeSBlbCBhw7FvDQogIENBU09TJG1lc1t4XSA8LSBmb3JtYXQoZmVjaGFfaG9yYV9vYmpldG8sICIlQiIpICMgT2J0aWVuZSBlbCBub21icmUgZGVsIG1lcyBjb21wbGV0bw0KICBDQVNPUyRhw7FvW3hdIDwtIGZvcm1hdChmZWNoYV9ob3JhX29iamV0bywgIiVZIikNCg0KICANCiAgICANCiAgQ0FTT1MkRGlhIDwtIE5BDQogIGRpYXMgPC0gYygiMi5MdW4iLCAiMy5NYXIiLCAiNC5NaWUiLCAiNS5KdWUiLCAiNi5WaWUiLCAiNy5TYWIiLCAiMS5Eb20iKQ0KICBkaWFzX2NvbSA8LSBjKCJsdW5lcyIsICJtYXJ0ZXMiLCAibWnDqXJjb2xlcyIsICJqdWV2ZXMiLCAidmllcm5lcyIsICJzw6FiYWRvIiwgImRvbWluZ28iKQ0KICBmb3IgKGkgaW4gMTpucm93KENBU09TKSkgew0KICAgIGZvciAoaiBpbiAxOmxlbmd0aChkaWFzX2NvbSkpew0KICAgICAgaWYoIWlzLm5hKENBU09TJGRpYV9zZW1hbmFbaV0pICYgQ0FTT1MkZGlhX3NlbWFuYVtpXT09ZGlhc19jb21bal0pew0KICAgICAgICBDQVNPUyREaWFbaV0gPC0gZGlhc1tqXQ0KICAgICAgICBicmVhaw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICANCg0KDQoNCg0KfQ0KYGBgDQoNCmBgYHtyfQ0KDQpBR1JFU09SRVMkZGlhX3NlbWFuYSA8LSBOQQ0KQUdSRVNPUkVTJG1lcyA8LSBOQQ0KQUdSRVNPUkVTJGHDsW8gPC0gTkENCg0KDQoNCg0KQUdSRVNPUkVTJHJhbmdvZWRhZCA8LSBOQQ0KQUdSRVNPUkVTJGVzdGFkb2NpdmlsIDwtICJEZXNjb25vY2lkYSINCkFHUkVTT1JFUyRlc2NvbGFyIDwtICJEZXNjb25vY2lkYSINCkFHUkVTT1JFUyRvY3VwYWNpb24yIDwtIE5BDQoNCmZvciAoeCBpbiAxOm5yb3coQUdSRVNPUkVTKSkgew0KICBmZWNoYV9udW1lcm9zIDwtIGFzLm51bWVyaWMoQUdSRVNPUkVTJGZlY2hhX2hlY2hvc1t4XSkNCiAgYmFzZTwtIGFzLkRhdGUoIjE4OTktMTItMzAiKQ0KICBmZWNoYTwtIGJhc2UrZmVjaGFfbnVtZXJvcw0KDQogIGZlY2hhX2hvcmFfb2JqZXRvIDwtIGFzLlBPU0lYY3QoZmVjaGEsIGZvcm1hdCA9ICIlZC0lbS0lWSIpDQoNCiAgIyBPYnTDqW4gZWwgZMOtYSBkZSBsYSBzZW1hbmENCiAgQUdSRVNPUkVTJGRpYV9zZW1hbmFbeF0gPC0gd2Vla2RheXMoZmVjaGFfaG9yYV9vYmpldG8pDQoNCiAgIyBPYnTDqW4gZWwgbWVzIHkgZWwgYcOxbw0KICBBR1JFU09SRVMkbWVzW3hdIDwtIGZvcm1hdChmZWNoYV9ob3JhX29iamV0bywgIiVCIikgIyBPYnRpZW5lIGVsIG5vbWJyZSBkZWwgbWVzIGNvbXBsZXRvDQogIEFHUkVTT1JFUyRhw7FvW3hdIDwtIGZvcm1hdChmZWNoYV9ob3JhX29iamV0bywgIiVZIikNCiAgDQogIA0KDQogIA0KICBpZighaXMubmEoQUdSRVNPUkVTJGBFZGFkIGRlbCBBZ3Jlc29yYFtpXSkpew0KICAgIGlmKEFHUkVTT1JFUyRgRWRhZCBkZWwgQWdyZXNvcmBbaV0gPD0gNSl7DQogICAgICBBR1JFU09SRVMkcmFuZ29lZGFkW2ldIDwtICI1IHkgbWVub3MiDQogICAgfQ0KICAgIGlmKEFHUkVTT1JFUyRgRWRhZCBkZWwgQWdyZXNvcmBbaV0gPiA1ICYgQUdSRVNPUkVTJGBFZGFkIGRlbCBBZ3Jlc29yYFtpXSA8PSAxNCl7DQogICAgICBBR1JFU09SRVMkcmFuZ29lZGFkW2ldIDwtICI2IGEgMTQiDQogICAgfQ0KICAgIGlmKEFHUkVTT1JFUyRgRWRhZCBkZWwgQWdyZXNvcmBbaV0gPiAxNCAmIEFHUkVTT1JFUyRgRWRhZCBkZWwgQWdyZXNvcmBbaV0gPD0gMjQpew0KICAgICAgQUdSRVNPUkVTJHJhbmdvZWRhZFtpXSA8LSAiMTUgYSAyNCINCiAgICB9DQogICAgaWYoQUdSRVNPUkVTJGBFZGFkIGRlbCBBZ3Jlc29yYFtpXSA+IDI0ICYgQUdSRVNPUkVTJGBFZGFkIGRlbCBBZ3Jlc29yYFtpXSA8PSA0NCl7DQogICAgICBBR1JFU09SRVMkcmFuZ29lZGFkW2ldIDwtICIyNSBhIDQ0Ig0KICAgIH0NCiAgICBpZihBR1JFU09SRVMkYEVkYWQgZGVsIEFncmVzb3JgW2ldID4gNDQgJiBBR1JFU09SRVMkYEVkYWQgZGVsIEFncmVzb3JgW2ldIDw9IDU5KXsNCiAgICAgIEFHUkVTT1JFUyRyYW5nb2VkYWRbaV0gPC0gIjQ1IGEgNTkiDQogICAgfQ0KICAgIGlmKEFHUkVTT1JFUyRgRWRhZCBkZWwgQWdyZXNvcmBbaV0gPj0gNjApew0KICAgICAgQUdSRVNPUkVTJHJhbmdvZWRhZFtpXSA8LSAiNjAgeSBtw6FzIg0KICAgIH0NCiAgfQ0KICANCiAgDQogIGlmKCFpcy5uYShBR1JFU09SRVMkRWRvQ2l2aWxbaV0pKXsNCiAgICBpZihBR1JFU09SRVMkRWRvQ2l2aWxbaV0gPT0gIkNhc2FkbyIgfCBBR1JFU09SRVMkRWRvQ2l2aWxbaV0gPT0gIlVuacOzbiBsaWJyZSIgfA0KICAgICAgIEFHUkVTT1JFUyRFZG9DaXZpbFtpXSA9PSAiQ29uY3ViaW5hdG8iIHwgQUdSRVNPUkVTJEVkb0NpdmlsW2ldID09ICJTb2NpZWRhZCBkZSBjb252aXZlbmNpYSIpew0KICAgICAgQUdSRVNPUkVTJGVzdGFkb2NpdmlsW2ldIDwtICJDYXNhZG8oYSkgbyB1bmlkbyhhKSINCiAgICB9DQogICAgaWYoQUdSRVNPUkVTJEVkb0NpdmlsW2ldID09ICJTb2x0ZXJvIil7DQogICAgICBBR1JFU09SRVMkZXN0YWRvY2l2aWxbaV0gPC0gIlNvbHRlcm8oYSkiDQogICAgfQ0KICAgIGlmKEFHUkVTT1JFUyRFZG9DaXZpbFtpXSA9PSAiRGl2b3JjaWFkbyIgfA0KICAgICAgIEFHUkVTT1JFUyRFZG9DaXZpbFtpXSA9PSAiVml1ZG8iIHwNCiAgICAgICBBR1JFU09SRVMkRWRvQ2l2aWxbaV0gPT0gIlNlcGFyYWRvIil7DQogICAgICBBR1JFU09SRVMkZXN0YWRvY2l2aWxbaV0gPC0gIlNlcGFyYWRvKGEpLCBkaXZvcmNpYWRvKGEpIG8gdml1ZG8oYSkiDQogICAgfQ0KICAgIGlmKEFHUkVTT1JFUyRFZG9DaXZpbFtpXSA9PSAiTm8gaWRlbnRpZmljYWRvIiB8DQogICAgICAgQUdSRVNPUkVTJEVkb0NpdmlsW2ldID09ICJOVUxMInwNCiAgICAgICBBR1JFU09SRVMkRWRvQ2l2aWxbaV0gPT0gIlNlbGVjY2lvbmUiKXsNCiAgICAgIEFHUkVTT1JFUyRlc3RhZG9jaXZpbFtpXSA8LSAiRGVzY29ub2NpZGEiDQogICAgfQ0KICB9DQogIA0KICANCiAgDQogIGlmKCFpcy5uYShBR1JFU09SRVMkRXNjb2xhcmlkYWRbaV0pKXsNCiAgICBpZihBR1JFU09SRVMkRXNjb2xhcmlkYWRbaV0gPT0gIlByaW1hcmlhIil7DQogICAgICBBR1JFU09SRVMkZXNjb2xhcltpXSA8LSAiUHJpbWFyaWEiDQogICAgfQ0KICAgIGlmKEFHUkVTT1JFUyRFc2NvbGFyaWRhZFtpXSA9PSAiTm8gaWRlbnRpZmljYWRvIiB8DQogICAgICAgQUdSRVNPUkVTJEVzY29sYXJpZGFkW2ldID09ICJOVUxMIil7DQogICAgICBBR1JFU09SRVMkZXNjb2xhcltpXSA8LSAiRGVzY29ub2NpZGEiDQogICAgfQ0KICAgIGlmKEFHUkVTT1JFUyRFc2NvbGFyaWRhZFtpXSA9PSAiU2VjdW5kYXJpYSIpew0KICAgICAgQUdSRVNPUkVTJGVzY29sYXJbaV0gPC0gIlNlY3VuZGFyaWEiDQogICAgfQ0KICAgIGlmKEFHUkVTT1JFUyRFc2NvbGFyaWRhZFtpXSA9PSAiQ2FycmVyYSB0w6ljbmljYSBjb21lcmNpYWwiIHwNCiAgICAgICBBR1JFU09SRVMkRXNjb2xhcmlkYWRbaV0gPT0gIlByZXBhcmF0b3JpYSIpew0KICAgICAgQUdSRVNPUkVTJGVzY29sYXJbaV0gPC0gIlByZXBhcmF0b3JpYSINCiAgICB9DQogICAgaWYoQUdSRVNPUkVTJEVzY29sYXJpZGFkW2ldID09ICJMaWNlbmNpYXR1cmEiIHwNCiAgICAgICBBR1JFU09SRVMkRXNjb2xhcmlkYWRbaV0gPT0gIlBvc2dyYWRvIiB8DQogICAgICAgQUdSRVNPUkVTJEVzY29sYXJpZGFkW2ldID09ICJNYWVzdHLDrWEiIHwNCiAgICAgICBBR1JFU09SRVMkRXNjb2xhcmlkYWRbaV0gPT0gIkRvY3RvcmFkbyIpew0KICAgICAgQUdSRVNPUkVTJGVzY29sYXJbaV0gPC0gIlN1cGVyaW9yIg0KICAgIH0NCiAgICBpZihBR1JFU09SRVMkRXNjb2xhcmlkYWRbaV0gPT0gIlByZWVzY29sYXIiIHwNCiAgICAgICBBR1JFU09SRVMkRXNjb2xhcmlkYWRbaV0gPT0gIkVzdHVkaW9zIHF1ZSBubyByZXF1aWVyZW4gdmFsaWTDqXogb2ZpY2lhbCJ8DQogICAgICAgQUdSRVNPUkVTJEVzY29sYXJpZGFkW2ldID09ICJOaW5ndW5hIil7DQogICAgICBBR1JFU09SRVMkZXNjb2xhcltpXSA8LSAiTmluZ3VuYSINCiAgICB9DQoNCiAgfQ0KICANCiAgDQogIGlmKCFpcy5uYShBR1JFU09SRVMkUHJpbkFjdEFnU2luRGF0b1tpXSkgfCAhaXMubmEoQUdSRVNPUkVTJFByaW5BY3RBZ1NlRGVzY1tpXSkgfA0KICAgICAhaXMubmEoQUdSRVNPUkVTJFByaW5BY3RBZ090cm9baV0pIHwgIWlzLm5hKEFHUkVTT1JFUyRQcmluQWN0QWdOaW5nW2ldKXwNCiAgICAgIWlzLm5hKEFHUkVTT1JFUyRQcmluQWN0QWdBY3RJbGljaXRhW2ldKSl7DQogICAgaWYoQUdSRVNPUkVTJFByaW5BY3RBZ1NpbkRhdG9baV0gPT0gMSB8IEFHUkVTT1JFUyRQcmluQWN0QWdTZURlc2NbaV0gPT0gMSB8DQogICAgICAgQUdSRVNPUkVTJFByaW5BY3RBZ090cm9baV0gPT0gMSB8IEFHUkVTT1JFUyRQcmluQWN0QWdOaW5nW2ldID09IDEgfA0KICAgICAgIEFHUkVTT1JFUyRQcmluQWN0QWdBY3RJbGljaXRhW2ldID09IDEgKXsNCiAgICAgIEFHUkVTT1JFUyRvY3VwYWNpb24yW2ldIDwtICJPdHJhIg0KICAgIH0NCiAgfQ0KICBpZighaXMubmEoQUdSRVNPUkVTJFByaW5BY3RBZ1RyYWJIb2dhcltpXSkgfCAhaXMubmEoQUdSRVNPUkVTJFByaW5BY3RBZ1RyYWJGSG9nYXJbaV0pKXsNCiAgICBpZihBR1JFU09SRVMkUHJpbkFjdEFnVHJhYkhvZ2FyW2ldID09IDEgfCBBR1JFU09SRVMkUHJpbkFjdEFnVHJhYkZIb2dhcltpXSA9PSAxKXsNCiAgICAgIEFHUkVTT1JFUyRvY3VwYWNpb24yW2ldIDwtICJUcmFiYWphIg0KICAgIH0NCiAgfQ0KICBpZighaXMubmEoQUdSRVNPUkVTJFByaW5BY3RBZ0VzdHVkaWFbaV0pKXsNCiAgICBpZihBR1JFU09SRVMkUHJpbkFjdEFnRXN0dWRpYVtpXSA9PSAxKXsNCiAgICAgIEFHUkVTT1JFUyRvY3VwYWNpb24yW2ldIDwtICJFc3R1ZGlhIg0KICAgIH0NCiAgfQ0KICBpZighaXMubmEoQUdSRVNPUkVTJFByaW5BY3RBZ0p1YlBlbnNbaV0pIHwgIWlzLm5hKEFHUkVTT1JFUyRQcmluQWN0QWdQZW5zW2ldKSl7DQogICAgaWYoQUdSRVNPUkVTJFByaW5BY3RBZ0p1YlBlbnNbaV0gPT0gMSB8IEFHUkVTT1JFUyRQcmluQWN0QWdQZW5zW2ldID09IDEpew0KICAgICAgQUdSRVNPUkVTJG9jdXBhY2lvbjJbaV0gPC0gIkp1YmlsYWRvKGEpIHBlbnNpb25hZG8oYSkiDQogICAgfQ0KICB9DQogIA0KICANCn0NCg0KDQpgYGANCg0KRGUgaWd1YWwgbWFuZXJhIHNlIHJlYWxpesOzIHVuYSBudWV2YSBjbGFzaWZpY2FjacOzbiBhIGxvcyBkYXRvcyByZWxhY2lvbmFkb3MgY29uIGVsIHbDrW5jdWxvIGNvbiBhZ3Jlc29yIHkgYWRlbcOhcyBzZSB0cmFiYWpvIGNvbiBtb2RhbGlkYWQgZGUgdmlvbGVuY2lhLCBhIGxhIGN1YWwgc2UgcmVhbGl6YSBsaW1waWV6YSB5IGEgcGFydGlyIGRlIGVsbGEsIG9idGVuZW1vcyB1bmEgbnVldmEgY29sdW1uYSBkZSBkYXRvcywgbGEgY3VhbCBub3MgaW5kaWNhIGN1YW5kbyB1biBjYXNvIGxsZWfDsyBhIHNlciBmZW1pbmljaWRpby4NCg0KYGBge3J9DQpDQVNPUyRNb2RhbGlkYWQgPC0gTkENCkNBU09TJGZlbWluaWNpZGlvcyA8LSAwDQpDQVNPUyQiVsOtbmN1bG8ob3JpZ2luYWwpIiA8LSBDQVNPUyRgRGV0YWxsZSBkZSBWw61uY3VsbyBjb24gdmljdGltYWANCkNBU09TJCJIYWJsYSBsZW5ndWEgaW5kaWdlbmEiIDwtIDANCmZhbWlsaWFyZXMgPC0gYygiSGlqbyhhKSIsICJQYWRyYXN0cm8gbyBtYWRyYXN0cmEiLCAiU29icmlubyhhKSIsICJBYnVlbG8oYSkiLA0KICAgICAgICAgICAgICAgICJUw61vKGEpIiwgIlByaW1vKGEpIiwgIkhlcm1hbm8oYSkiLCAiU3VlZ3JvKGEpIiwgIk5pZXRvKGEpIikNCg0KDQoNCmZvcih4IGluIDE6bnJvdyhDQVNPUykpew0KICBpZighaXMubmEoQ0FTT1MkYE1vZGFsaWRhZCBkZSBsYSBWaW9sZW5jaWFgW3hdKSl7DQogICAgaWYoQ0FTT1MkYE1vZGFsaWRhZCBkZSBsYSBWaW9sZW5jaWFgW3hdID09ICIxIC0gRmFtaWxpYXIiKXsNCiAgICAgQ0FTT1MkTW9kYWxpZGFkW3hdIDwtICJGYW1pbGlhciINCiAgICB9DQogICAgaWYoQ0FTT1MkYE1vZGFsaWRhZCBkZSBsYSBWaW9sZW5jaWFgW3hdID09ICIyIC0gTGFib3JhbCIpew0KICAgICBDQVNPUyRNb2RhbGlkYWRbeF0gPC0gIkxhYm9yYWwiDQogICAgfQ0KICAgIGlmKENBU09TJGBNb2RhbGlkYWQgZGUgbGEgVmlvbGVuY2lhYFt4XSA9PSAiMyAtIEluc3RpdHVjaW9uYWwiKXsNCiAgICAgQ0FTT1MkTW9kYWxpZGFkW3hdIDwtICAiSW5zdGl0dWNpb25hbCINCiAgICB9DQogICAgaWYoQ0FTT1MkYE1vZGFsaWRhZCBkZSBsYSBWaW9sZW5jaWFgW3hdID09ICI0IC0gRW4gbGEgY29tdW5pZGFkIiB8DQogICAgICAgQ0FTT1MkYE1vZGFsaWRhZCBkZSBsYSBWaW9sZW5jaWFgW3hdID09ICJFbmxhY29tdW5pZGFkIil7DQogICAgIENBU09TJE1vZGFsaWRhZFt4XSA8LSAiQ29tdW5pdGFyaWEiDQogICAgfQ0KICAgIGlmKENBU09TJGBNb2RhbGlkYWQgZGUgbGEgVmlvbGVuY2lhYFt4XSA9PSAiNSAtIEVzY29sYXIvRG9jZW50ZSIpew0KICAgICBDQVNPUyRNb2RhbGlkYWRbeF0gPC0gIkVzY29sYXIiDQogICAgfQ0KICAgIGlmKENBU09TJGBNb2RhbGlkYWQgZGUgbGEgVmlvbGVuY2lhYFt4XSA9PSAgIjYgLSBPYnN0w6l0cmljYSIpew0KICAgICBDQVNPUyRNb2RhbGlkYWRbeF0gPC0gIk9ic3TDqXRyaWNhIg0KICAgIH0NCiAgICBpZihDQVNPUyRgTW9kYWxpZGFkIGRlIGxhIFZpb2xlbmNpYWBbeF0gPT0gIjcgLSBQb2zDrXRpY2EiKXsNCiAgICAgQ0FTT1MkTW9kYWxpZGFkW3hdIDwtICJQb2zDrXRpY2EiDQogICAgfQ0KICAgIGlmKENBU09TJGBNb2RhbGlkYWQgZGUgbGEgVmlvbGVuY2lhYFt4XSA9PSAiOSAtIEZlbWluaWNpZGEiKXsNCiAgICAgQ0FTT1MkTW9kYWxpZGFkW3hdIDwtICJGZW1pbmljaWRhIg0KICAgIH0NCiAgICBpZihDQVNPUyRgTW9kYWxpZGFkIGRlIGxhIFZpb2xlbmNpYWBbeF0gPT0gIjggLSBEaWdpdGFsL0NpYmVybsOpdGljYSIpew0KICAgICBDQVNPUyRNb2RhbGlkYWRbeF0gPC0gIkRpZ2l0YWwiDQogICAgfQ0KICB9DQogIA0KICANCiAgaWYoQ0FTT1MkTW9kYWxpZGFkW2ldID09ICJGZW1pbmljaWRhIil7DQogICAgQ0FTT1MkZmVtaW5pY2lkaW9zW2ldIDwtIDENCiAgfQ0KICANCiAgaWYoQ0FTT1MkIkhhYmxhIEluZGlnZW5hIltpXSA9PSAiU2kiKXsNCiAgICBDQVNPUyQiSGFibGEgbGVuZ3VhIGluZGlnZW5hIltpXSA8LSAxDQogIH0NCiAgDQogIA0KICBpZighaXMubmEoQ0FTT1MkYERldGFsbGUgZGUgVsOtbmN1bG8gY29uIHZpY3RpbWFgW2ldKSl7DQogICAgZm9yIChqIGluIGZhbWlsaWFyZXMpIHsNCiAgICAgIGlmKENBU09TJGBEZXRhbGxlIGRlIFbDrW5jdWxvIGNvbiB2aWN0aW1hYFtpXSA9PSBqKXsNCiAgICAgICAgQ0FTT1MkYERldGFsbGUgZGUgVsOtbmN1bG8gY29uIHZpY3RpbWFgW2ldIDwtICJPdHJvcyBmYW1pbGlhcmVzIg0KICAgICAgICBicmVhaw0KICAgICAgfQ0KICAgIH0NCiAgICBpZihDQVNPUyRgRGV0YWxsZSBkZSBWw61uY3VsbyBjb24gdmljdGltYWBbaV0gPT0gIk90cm8iKXsNCiAgICAgIENBU09TJGBEZXRhbGxlIGRlIFbDrW5jdWxvIGNvbiB2aWN0aW1hYFtpXSA8LSAiT3RyYSByZWxhY2nDs24iDQogICAgfQ0KICAgIGlmKENBU09TJGBEZXRhbGxlIGRlIFbDrW5jdWxvIGNvbiB2aWN0aW1hYFtpXSA9PSAiTlVMTCIpew0KICAgICAgQ0FTT1MkYERldGFsbGUgZGUgVsOtbmN1bG8gY29uIHZpY3RpbWFgW2ldIDwtICJEZXNjb25vY2lkbyINCiAgICB9DQogICAgaWYoQ0FTT1MkYERldGFsbGUgZGUgVsOtbmN1bG8gY29uIHZpY3RpbWFgW2ldID09ICJDb25jdWJpbmEiKXsNCiAgICAgIENBU09TJGBEZXRhbGxlIGRlIFbDrW5jdWxvIGNvbiB2aWN0aW1hYFtpXSA8LSAiQ8Ozbnl1Z2UgbyBwYXJlamEiDQogICAgfQ0KICB9DQogIA0KICANCiAgDQp9DQpgYGANCg0KU2UgYWdyZWdhIHVuYSBudWV2YSBjb2x1bW5hIGNvcnJlc3BvbmRpZW50ZSBhbCBlc3RhZG8gZGUgaGVjaG8sIGxhIGN1YWwgc2Ugb2J0aWVuZSBhIHBhcnRpciBkZSBsb3MgZGF0b3MgZGUgbXVuaWNpcGlvIGhlY2hvLg0KDQpgYGB7cn0NCg0KDQpNdW5pY2lwaW8gPSBjKCJBYmFzb2xvIiwgIkFndWFsZWd1YXMiLCAiTG9zIEFsZGFtYXMiLCAiQWxsZW5kZSIsICJBbsOhaHVhYyIsDQogICAgICAgICAgICAgICJBcG9kYWNhIiwgIkFyYW1iZXJyaSIsICJCdXN0YW1hbnRlIiwgIkNhZGVyZXl0YSBKaW3DqW5leiIsDQogICAgICAgICAgICAgICJFbCBDYXJtZW4iLCAiQ2VycmFsdm8iLCAiQ2nDqW5lZ2EgZGUgRmxvcmVzIiwgIkNoaW5hIiwNCiAgICAgICAgICAgICAgIkRvY3RvciBBcnJveW8iLCAiRG9jdG9yIENvc3MiLCAiRG9jdG9yIEdvbnrDoWxleiIsDQogICAgICAgICAgICAgICJMb3MgSGVycmVyYSIsICJHYWxlYW5hIiwgIkdhcmPDrWEiLCAiR2VuZXJhbCBCcmF2byIsDQogICAgICAgICAgICAgICJHZW5lcmFsIEVzY29iZWRvIiwgIkdlbmVyYWwgVGVyw6FuIiwgIkdlbmVyYWwgVHJldmnDsW8iLA0KICAgICAgICAgICAgICAiR2VuZXJhbCBaYXJhZ296YSIsICJHZW5lcmFsIFp1YXp1YSIsICJHdWFkYWx1cGUiLA0KICAgICAgICAgICAgICAiSGlkYWxnbyIsICJIaWd1ZXJhcyIsICJIdWFsYWh1aXNlcyIsICJJdHVyYmlkZSIsDQogICAgICAgICAgICAgICJKdcOhcmV6IiwgIkxhbXBhem9zIGRlIE5hcmFuam8iLCAiTGluYXJlcyIsICJNYXLDrW4iLA0KICAgICAgICAgICAgICAiTWVsY2hvciBPY2FtcG8iLCAiTWllciB5IE5vcmllZ2EiLCAiTWluYSIsICJNb250ZW1vcmVsb3MiLA0KICAgICAgICAgICAgICAiTW9udGVycmV5IiwgIlBhcmFzIiwgIlBlc3F1ZXLDrWEiLCAiTG9zIFJhbW9uZXMiLA0KICAgICAgICAgICAgICAiUmF5b25lcyIsICJTYWJpbmFzIEhpZGFsZ28iLCAiU2FsaW5hcyBWaWN0b3JpYSIsDQogICAgICAgICAgICAgICJTYW4gTmljb2zDoXMgZGUgbG9zIEdhcnphIiwgIlNhbiBQZWRybyBHYXJ6YSBHYXJjw61hIiwNCiAgICAgICAgICAgICAgIlNhbnRhIENhdGFyaW5hIiwgIlNhbnRpYWdvIiwgIlZhbGxlY2lsbG8iLCAiVmlsbGFsZGFtYSIpDQoNCkNBU09TJGVzdGFkbyA8LSBOQQ0KDQpmb3IgKGkgaW4gMTpucm93KENBU09TKSkgew0KICBpZighaXMubmEoQ0FTT1MkYE11bmljaXBpbyBIZWNob2BbaV0pKXsNCiAgICBmb3IgKGogaW4gTXVuaWNpcGlvKSB7DQogICAgICBpZihDQVNPUyRgTXVuaWNpcGlvIEhlY2hvYFtpXSA9PSBqICl7DQogICAgICAgIENBU09TJGVzdGFkb1tpXSA8LSAiTnVldm8gTGXDs24iDQogICAgICB9DQogICAgfQ0KICB9DQp9DQpgYGANCg==