Analise exploratória de
dados sobre Abandono e Evasão Escolar
Introdução
A busca ativa, o abandono e a evasão escolar são questões de grande
relevância e impacto social, não apenas no contexto nacional, mas também
globalmente. A compreensão desses fenômenos é crucial para o
desenvolvimento de estratégias eficazes de intervenção e políticas
públicas direcionadas à promoção da educação e redução das
desigualdades.
A busca ativa refere-se aos esforços das instituições educacionais e
de outras entidades para identificar e acompanhar alunos em situação de
risco de abandono ou evasão escolar. Essa prática tem como objetivo
fundamental garantir que todos os estudantes tenham acesso à educação de
qualidade e permaneçam engajados no processo educacional.
Por outro lado, o abandono escolar ocorre quando um aluno deixa de
frequentar a escola sem concluir seus estudos, muitas vezes devido a uma
variedade de fatores socioeconômicos, familiares ou individuais. Essa
situação não apenas afeta negativamente o próprio aluno, privando-o das
oportunidades de desenvolvimento pessoal e profissional, mas também tem
implicações significativas para a sociedade como um todo, incluindo o
aumento do desemprego e da criminalidade.
A evasão escolar, por sua vez, refere-se à saída prematura de alunos
matriculados no sistema educacional, antes de concluírem sua formação
básica ou secundária. Esse fenômeno está frequentemente associado a
problemas estruturais dentro do sistema educacional, bem como a fatores
externos, como pobreza, violência e falta de apoio familiar.
Neste contexto, a análise exploratória de dados desempenha um papel
fundamental na compreensão desses problemas complexos, fornecendo
insights valiosos sobre os padrões, tendências e correlações presentes
nos dados relacionados à busca ativa, abandono e evasão escolar. Ao
explorar e visualizar os dados disponíveis, podemos identificar padrões
emergentes, áreas de preocupação e oportunidades para intervenção,
informando assim o desenvolvimento de estratégias mais eficazes e
direcionadas.
Neste notebook, realizaremos uma análise exploratória de dados de
diversas fontes sobre abandono e evasão escolar, utilizando técnicas de
estatística descritiva e inferencial para examinar os padrões e
tendências presentes nos dados. Através dessa análise, buscamos obter
uma compreensão mais profunda das evidencias relacionads a esses
fenômenos e contribuir para o aprimoramento de políticas, projetos,
ações e processos que promovam a inclusão e a equidade na educação.
# pacotes utilizados nessa analise:
# tidyverse: O tidyverse é um conjunto de pacotes do R que compartilham uma filosofia comum de manipulação e visualização de dados. Inclui pacotes como ggplot2 para visualização de dados, dplyr para manipulação de dados e tidyr para reformulação de dados.
library(tidyverse)
── Attaching core tidyverse packages ───────────────────────────────────────────────────────────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.1.4 ✔ readr 2.1.4
✔ forcats 1.0.0 ✔ stringr 1.5.1
✔ ggplot2 3.4.4 ✔ tibble 3.2.1
✔ lubridate 1.9.3 ✔ tidyr 1.3.0
✔ purrr 1.0.2 ── Conflicts ─────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
# caret: O pacote caret (Classificação e Regressão Treinadas) fornece uma interface unificada para a construção de modelos de aprendizado de máquina supervisionados e não supervisionados. Ele simplifica o processo de ajuste, avaliação e sintonia de modelos, oferecendo várias funções e métodos.
library(caret)
Warning: package ‘caret’ was built under R version 4.3.3Carregando pacotes exigidos: lattice
Attaching package: ‘caret’
The following object is masked from ‘package:purrr’:
lift
# sidrar: O pacote sidrar oferece uma interface para acessar dados do SIDRA (Sistema IBGE de Recuperação Automática), que é uma plataforma do Instituto Brasileiro de Geografia e Estatística (IBGE) para acesso a dados estatísticos.
library(sidrar)
Warning: package ‘sidrar’ was built under R version 4.3.3
# randomForest: O pacote randomForest implementa o algoritmo de florestas aleatórias para aprendizado de máquina. É uma técnica de conjunto que combina múltiplas árvores de decisão para realizar classificação e regressão.
library(randomForest)
Warning: package ‘randomForest’ was built under R version 4.3.3randomForest 4.7-1.1
Type rfNews() to see new features/changes/bug fixes.
Attaching package: ‘randomForest’
The following object is masked from ‘package:dplyr’:
combine
The following object is masked from ‘package:ggplot2’:
margin
# rpart: O pacote rpart é usado para ajustar árvores de decisão recursivas. Ele é comumente usado em análise de dados para classificação e regressão.
library(rpart)
# rpart.plot: O pacote rpart.plot fornece funções para visualizar árvores de decisão criadas com o pacote rpart. Ele permite criar gráficos visualmente atraentes das árvores de decisão, facilitando a interpretação dos resultados.
library(rpart.plot)
Warning: package ‘rpart.plot’ was built under R version 4.3.3
IBGE -
MICRODADOS
Introdução
Os microdados da Pesquisa Nacional por Amostra de Domicílios Contínua
(PNADC), disponibilizados pelo Instituto Brasileiro de Geografia e
Estatística (IBGE), são uma fonte valiosa de informações sobre a
situação socioeconômica da população brasileira. A PNADC é uma pesquisa
realizada em todo o país, que investiga uma ampla gama de temas,
incluindo mercado de trabalho, rendimento, educação, saúde e outras
questões relevantes para a compreensão da realidade brasileira.
Referencias: https://doi.org/10.5281/zenodo.8111841 - MOTIVOS DE
ABANDONO ESCOLAR NO BRASIL: ANÁLISE DE DADOS DA PNAD CONTÍNUA DE 2019
Tabela 7217

Tabela 7219

- 7138 - Taxa de escolarização, por sexo e grupo de idade

```r
ary(sidrar)
sc<-get_sidra(7139, geo = c("State"),format = 2,period = "all")
```
```
Considering all categories once 'classific' was set to 'all' (default)
```
```r
sc$`Grupo de idade`<-as.factor(tx_esc$`Grupo de idade`)
sc$`Grupo de idade` <- ordered(tx_esc$`Grupo de idade`, levels = c("0 a 3 anos",
"0 a 5 anos",
"4 a 5 anos",
"6 a 14 anos",
"15 a 17 anos",
"18 a 24 anos",
"25 anos ou mais",
"Total" ))
```
tx_esc %>% filter(`Unidade da Federação`=="Distrito Federal",Variável=="Taxa de escolarização")%>% select(-`Nível Territorial`) %>%
ggplot(aes(as.numeric(Ano),col=`Cor ou raça`,Valor))+geom_line()+
facet_wrap(~`Grupo de idade`,scales="free")+
geom_text(aes(label=Valor))+
labs(title = "Taxa de Escolarização por Faixa de idade e Raça",caption = "Fonte: IBGE/PNADC/A")+
theme_minimal()

- 7142 Taxa ajustada de frequência escolar líquida, por cor ou raça e
faixa etária ideal por curso frequentado

IPDF -
MICRODADOS
Avaliação da Amostra:
PDAD_2021_Moradores <- read_delim("//10.221.37.241/dinfe/Documentos/2023/Tratamento/THIAGO PROJETO/GETED/PCF/PDAD_2021-Moradores.csv",
delim = ";", escape_double = FALSE, trim_ws = TRUE)
Warning: One or more parsing issues, call `problems()` on your data frame for details, e.g.:
dat <- vroom(...)
problems(dat)Rows: 83481 Columns: 151── Column specification ────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ";"
chr (2): PESO_MOR, infla_ipcadf
dbl (147): A01nficha, A01ra, A01setor, morador_id, idade, E02_1, E02_2, E02_3, E03, E04, E04_1, E04_1_1, E04_2, E04_2_1, E05, E05_1,...
num (2): renda_ind, renda_ind_r
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# Criar o dataframe com dicionario de RA's
dic_RA <- data.frame(A01ra = 1:33, RA = c("Plano Piloto", "Gama", "Taguatinga", "Brazlândia", "Sobradinho", "Planaltina", "Paranoá",
"Núcleo Bandeirante", "Ceilândia", "Guará", "Cruzeiro", "Samambaia", "Santa Maria", "São Sebastião",
"Recanto Das Emas", "Lago Sul", "Riacho Fundo", "Lago Norte", "Candangolândia", "Águas Claras",
"Riacho Fundo II", "Sudoeste e Octogonal", "Varjão", "Park Way", "SCIA", "Sobradinho II",
"Jardim Botânico", "Itapoã", "SIA", "Vicente Pires", "Fercal", "Sol Nascente / Pôr do Sol",
"Arniqueira"))
PDAD_2021_Mor_RA<-left_join(PDAD_2021_Moradores,dic_RA,by="A01ra")
#nº de residencias e moradores identificados:
PDAD_2021_Mor_RA %>% summarise("nºde moradores"=n(),"nº de Residencia"=n_distinct(A01nficha))
#nº de residencias e moradores identificados por RA
PDAD_2021_Mor_RA %>% group_by(RA) %>% summarise("nºde moradores"=n(),"nº de Residencia"=n_distinct(A01nficha))
NA
NA
H02 Frequenta creche, escola ou faculdade/universidade 1 Sim, pública
2 Sim, particular 3 Não, mas já frequentou 4 Não, nunca frequentou
PDAD_2021_Moradores %>% mutate(Escolarizacao=if_else(H02==4,"nunca_frequentou_escola","frequentou_escola")) %>% group_by(idade,Escolarizacao) %>% summarise(n=n()) %>% spread(Escolarizacao,n) %>% mutate(percentual=nunca_frequentou_escola/(frequentou_escola+nunca_frequentou_escola)) %>%
ggplot(aes(idade,percentual))+geom_col(alpha=0.5)+
xlim(3.2,17.9)+ ylim(-0,0.5)+
geom_text(aes(label=paste(round(percentual*100,2),"%")),nudge_y = .05)+
#scale_x_continuous(breaks=seq(4,17))+
coord_flip()+
labs(title = "Evasão Escolar por Idade",subtitle = "Percentual de Residente do DF que nunca frequentou Escola",caption = "Fonte:Microdados PEDAD_2021_Moradores")
`summarise()` has grouped output by 'idade'. You can override using the `.groups` argument.

Analise por RA
PDAD_2021_Mor_RA %>% mutate(Escolarizacao=if_else(H02==4,"nunca_frequentou_escola","frequentou_escola")) %>% group_by(idade,Escolarizacao,RA) %>% summarise(n=n()) %>% spread(Escolarizacao,n) %>%
mutate(percentual=nunca_frequentou_escola/(frequentou_escola+nunca_frequentou_escola)) %>%
mutate(percentual=ifelse(is.na(percentual),0,percentual)) %>%
ggplot(aes(idade,percentual))+geom_col(alpha=0.5)+xlim(3.9,17.9)+
geom_text(aes(y=0.25,label=paste(round(percentual*100,2),"%")))+coord_flip()+labs(title = "Evasão Escolar por Idade",subtitle = "Percentual de Residente do DF que nunca frequentou Escola",caption = "Fonte:Microdados PEDAD_2021_Moradores")+facet_wrap(~RA,scales = "free")
`summarise()` has grouped output by 'idade', 'Escolarizacao'. You can override using the `.groups` argument.

Caracteristicas dos que nunca_frequentou_escola
PDAD_2021_Mor_RA %>% mutate(Escolarizacao=if_else(H02==4,"nunca_frequentou_escola","frequentou_escola")) %>%
group_by(idade,Escolarizacao,E04) %>% summarise(n=n()) %>% spread(Escolarizacao,n) %>%
mutate(percentual=nunca_frequentou_escola/(frequentou_escola+nunca_frequentou_escola),
percentual=ifelse(is.na(percentual),0,percentual),
sexo=ifelse(E04==1,"Masculino","Feminino")) %>%
mutate(percentual2=ifelse(E04==1,percentual,-percentual)) %>%
ggplot(aes(idade,percentual2,fill=sexo))+geom_col(alpha=0.5)+xlim(3.9,17.9)+ylim(-0.1,0.15)+
geom_text(aes(y=percentual2,hjust =ifelse(percentual2>0,-1,1),label=paste(round(percentual*100,2),"%")))+coord_flip()+labs(title = "Evasão Escolar por Idade e Sexo",subtitle = "Percentual de Residente do DF que nunca frequentou Escola por Sexo",caption = "Fonte:Microdados PEDAD_2021_Moradores")#+facet_wrap(~RA,scales = "free")
`summarise()` has grouped output by 'idade', 'Escolarizacao'. You can override using the `.groups` argument.


Nasceu no DF 1 Sim 2 Não 88888 Não sabe

H01 Sabe ler e escrever 1 Sim 2 Não 88888 Não sabe 99999 Não se
aplica

modelo de arvore de decisão

rpart.plot(model$finalModel,fallen.leaves = T)
# View the importance
print(importance)
rpart variable importance
INEP
Abandono
Matriculas_por_situação_2007a2022 <- read_csv("//10.221.37.241/dinfe/Documentos/2023/Tratamento/THIAGO PROJETO/GETED/Matriculas por situação,2007a2022.csv")
New names:Rows: 1526209 Columns: 13── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (3): NO_ETAPA_AGREGADA, NO_ETAPA_INDICADOR, NO_SITUACAO
dbl (10): ...1, NU_ANO_CENSO, CO_ENTIDADE, TP_ETAPA_ENSINO, TP_SEXO, TP_LOCALIZACAO, NU_IDADE_REFERENCIA, TP_DEPENDENCIA, TP_SITU...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
Matriculas_por_situação_2007a2022 <- read_csv("//10.221.37.241/dinfe/Documentos/2023/Tratamento/THIAGO PROJETO/GETED/Matriculas por situação,2007a2022.csv")
New names:Rows: 1526209 Columns: 13── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (3): NO_ETAPA_AGREGADA, NO_ETAPA_INDICADOR, NO_SITUACAO
dbl (10): ...1, NU_ANO_CENSO, CO_ENTIDADE, TP_ETAPA_ENSINO, TP_SEXO, TP_LOCALIZACAO, NU_IDADE_REFERENCIA, TP_DEPENDENCIA, TP_SITU...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
Matriculas_por_situação_2007a2022$NO_ETAPA_AGREGADA %>% unique()
[1] "Educação Infantil" "Ensino Fundamental - Anos Iniciais" "EJA - Ensino Fundamental"
[4] "Educação Profissional - Conc/Sub" "Ensino Médio - Propedêutico" "EJA - Ensino Médio"
[7] "Ensino Fundamental - Anos Finais" "Ensino Médio - Integrado" "Ensino Médio - Normal/Magistério"
a<-Matriculas_por_situação_2007a2022 %>% group_by(NO_SITUACAO,TP_SEXO,NO_ETAPA_AGREGADA) %>%
summarise(n=sum(n)) %>% spread(NO_SITUACAO,n,fill = 0) %>% mutate(total=Abandono+Aprovado+Falecido+Reprovado+SIR,
Abandono_per=Abandono/total)
`summarise()` has grouped output by 'NO_SITUACAO', 'TP_SEXO'. You can override using the `.groups` argument.
a %>% mutate(Abandono_per2=if_else(TP_SEXO==1,Abandono_per,-Abandono_per)) %>% filter(!Abandono==0) %>%
ggplot(aes(NO_ETAPA_AGREGADA,Abandono_per2,fill=as.factor(TP_SEXO)))+geom_col(alpha=0.3)+
geom_text(position = position_dodge(width = 1),aes(label=paste(round(Abandono_per*100,2),"%"),col=as.factor(TP_SEXO)))+
coord_flip()+
labs(title = "Abandono por Modalidade e Sexo",subtitle = "Matriculas abandonadas de 2007 a 2022")

Qual tipo de rede estão as matriculas com abandono? “1 - Federal 2 -
Estadual 3 - Municipal 4 - Privada”



Serie Histórica
Matriculas_por_situação_2007a2022$NO_SITUACAO %>% unique()
a<-Matriculas_por_situação_2007a2022 %>% group_by(NU_ANO_CENSO,NO_SITUACAO,NO_ETAPA_AGREGADA) %>%filter(TP_DEPENDENCIA==2) %>%
summarise(n=sum(n)) %>% spread(NO_SITUACAO,n,fill = 0) %>% mutate(total=Abandono+Aprovado+Falecido+Reprovado+SIR,
Abandono_per=Abandono/total)
a %>%# mutate(Abandono_per2=if_else(TP_SEXO==1,Abandono_per,-Abandono_per)) %>%
ggplot(aes(NU_ANO_CENSO,Abandono_per,col=NO_ETAPA_AGREGADA))+geom_line(alpha=0.5)+geom_text(position = position_dodge(width = 1),aes(label=paste(round(Abandono_per*100,2),"%")))+ labs(title = "Abandono por Modalidade e Sexo")+
facet_grid(NO_ETAPA_AGREGADA~1,scales = "free")+
theme_minimal()
LS0tDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IA0KICAgIHRoZW1lOiB5ZXRpDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgZmlnX2NhcHRpb246IHRydWUNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgaHRtbF9kb2N1bWVudDogZGVmYXVsdA0KICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQNCi0tLQ0KDQohW10oTG9nb19TRUVERl9Ib3Jpem9udGFsLTIwMjMucG5nKXt3aWR0aD0iNDAwIn0NCg0KR0RGIC0gU0VDUkVUQVJJQSBERSBFU1RBRE8gREUgRURVQ0HDh8ODTyBETyBESVNUUklUTyBGRURFUkFMDQoNClNVQlNFQ1JFVEFSSUEgREUgUExBTkVKQU1FTlRPLCBBQ09NUEFOSEFNRU5UTyBFIEFWQUxJQcOHw4NPDQoNClVuaWRhZGUgZGUgSW5mb3JtYcOnw6NvIGUgU3VwZXJ2aXPDo28NCg0KVU5JREFERSBERSBJTkZPUk1Bw4fDg08gRSBTVVBFUlZJU8ODTw0KDQpESVJFVE9SSUEgREUgSU5GT1JNQcOHw5VFUyBFRFVDQUNJT05BSVMNCg0KR0VSRU5DSUEgREUgRVNUVURPUyBFIFRSQVRBTUVOVE8gREFTIElORk9STUHDh8OVRVMgRSBFU1RBVMONU1RJQ0FTIEVEVUNBQ0lPTkFJUw0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIEFuYWxpc2UgZXhwbG9yYXTDs3JpYSBkZSBkYWRvcyBzb2JyZSBBYmFuZG9ubyBlIEV2YXPDo28gRXNjb2xhcg0KDQojIyBJbnRyb2R1w6fDo28NCkEgYnVzY2EgYXRpdmEsIG8gYWJhbmRvbm8gZSBhIGV2YXPDo28gZXNjb2xhciBzw6NvIHF1ZXN0w7VlcyBkZSBncmFuZGUgcmVsZXbDom5jaWEgZSBpbXBhY3RvIHNvY2lhbCwgbsOjbyBhcGVuYXMgbm8gY29udGV4dG8gbmFjaW9uYWwsIG1hcyB0YW1iw6ltIGdsb2JhbG1lbnRlLiBBIGNvbXByZWVuc8OjbyBkZXNzZXMgZmVuw7RtZW5vcyDDqSBjcnVjaWFsIHBhcmEgbyBkZXNlbnZvbHZpbWVudG8gZGUgZXN0cmF0w6lnaWFzIGVmaWNhemVzIGRlIGludGVydmVuw6fDo28gZSBwb2zDrXRpY2FzIHDDumJsaWNhcyBkaXJlY2lvbmFkYXMgw6AgcHJvbW/Dp8OjbyBkYSBlZHVjYcOnw6NvIGUgcmVkdcOnw6NvIGRhcyBkZXNpZ3VhbGRhZGVzLg0KDQpBIGJ1c2NhIGF0aXZhIHJlZmVyZS1zZSBhb3MgZXNmb3LDp29zIGRhcyBpbnN0aXR1acOnw7VlcyBlZHVjYWNpb25haXMgZSBkZSBvdXRyYXMgZW50aWRhZGVzIHBhcmEgaWRlbnRpZmljYXIgZSBhY29tcGFuaGFyIGFsdW5vcyBlbSBzaXR1YcOnw6NvIGRlIHJpc2NvIGRlIGFiYW5kb25vIG91IGV2YXPDo28gZXNjb2xhci4gRXNzYSBwcsOhdGljYSB0ZW0gY29tbyBvYmpldGl2byBmdW5kYW1lbnRhbCBnYXJhbnRpciBxdWUgdG9kb3Mgb3MgZXN0dWRhbnRlcyB0ZW5oYW0gYWNlc3NvIMOgIGVkdWNhw6fDo28gZGUgcXVhbGlkYWRlIGUgcGVybWFuZcOnYW0gZW5nYWphZG9zIG5vIHByb2Nlc3NvIGVkdWNhY2lvbmFsLg0KDQpQb3Igb3V0cm8gbGFkbywgbyBhYmFuZG9ubyBlc2NvbGFyIG9jb3JyZSBxdWFuZG8gdW0gYWx1bm8gZGVpeGEgZGUgZnJlcXVlbnRhciBhIGVzY29sYSBzZW0gY29uY2x1aXIgc2V1cyBlc3R1ZG9zLCBtdWl0YXMgdmV6ZXMgZGV2aWRvIGEgdW1hIHZhcmllZGFkZSBkZSBmYXRvcmVzIHNvY2lvZWNvbsO0bWljb3MsIGZhbWlsaWFyZXMgb3UgaW5kaXZpZHVhaXMuIEVzc2Egc2l0dWHDp8OjbyBuw6NvIGFwZW5hcyBhZmV0YSBuZWdhdGl2YW1lbnRlIG8gcHLDs3ByaW8gYWx1bm8sIHByaXZhbmRvLW8gZGFzIG9wb3J0dW5pZGFkZXMgZGUgZGVzZW52b2x2aW1lbnRvIHBlc3NvYWwgZSBwcm9maXNzaW9uYWwsIG1hcyB0YW1iw6ltIHRlbSBpbXBsaWNhw6fDtWVzIHNpZ25pZmljYXRpdmFzIHBhcmEgYSBzb2NpZWRhZGUgY29tbyB1bSB0b2RvLCBpbmNsdWluZG8gbyBhdW1lbnRvIGRvIGRlc2VtcHJlZ28gZSBkYSBjcmltaW5hbGlkYWRlLg0KDQpBIGV2YXPDo28gZXNjb2xhciwgcG9yIHN1YSB2ZXosIHJlZmVyZS1zZSDDoCBzYcOtZGEgcHJlbWF0dXJhIGRlIGFsdW5vcyBtYXRyaWN1bGFkb3Mgbm8gc2lzdGVtYSBlZHVjYWNpb25hbCwgYW50ZXMgZGUgY29uY2x1w61yZW0gc3VhIGZvcm1hw6fDo28gYsOhc2ljYSBvdSBzZWN1bmTDoXJpYS4gRXNzZSBmZW7DtG1lbm8gZXN0w6EgZnJlcXVlbnRlbWVudGUgYXNzb2NpYWRvIGEgcHJvYmxlbWFzIGVzdHJ1dHVyYWlzIGRlbnRybyBkbyBzaXN0ZW1hIGVkdWNhY2lvbmFsLCBiZW0gY29tbyBhIGZhdG9yZXMgZXh0ZXJub3MsIGNvbW8gcG9icmV6YSwgdmlvbMOqbmNpYSBlIGZhbHRhIGRlIGFwb2lvIGZhbWlsaWFyLg0KDQpOZXN0ZSBjb250ZXh0bywgYSBhbsOhbGlzZSBleHBsb3JhdMOzcmlhIGRlIGRhZG9zIGRlc2VtcGVuaGEgdW0gcGFwZWwgZnVuZGFtZW50YWwgbmEgY29tcHJlZW5zw6NvIGRlc3NlcyBwcm9ibGVtYXMgY29tcGxleG9zLCBmb3JuZWNlbmRvIGluc2lnaHRzIHZhbGlvc29zIHNvYnJlIG9zIHBhZHLDtWVzLCB0ZW5kw6puY2lhcyBlIGNvcnJlbGHDp8O1ZXMgcHJlc2VudGVzIG5vcyBkYWRvcyByZWxhY2lvbmFkb3Mgw6AgYnVzY2EgYXRpdmEsIGFiYW5kb25vIGUgZXZhc8OjbyBlc2NvbGFyLiBBbyBleHBsb3JhciBlIHZpc3VhbGl6YXIgb3MgZGFkb3MgZGlzcG9uw612ZWlzLCBwb2RlbW9zIGlkZW50aWZpY2FyIHBhZHLDtWVzIGVtZXJnZW50ZXMsIMOhcmVhcyBkZSBwcmVvY3VwYcOnw6NvIGUgb3BvcnR1bmlkYWRlcyBwYXJhIGludGVydmVuw6fDo28sIGluZm9ybWFuZG8gYXNzaW0gbyBkZXNlbnZvbHZpbWVudG8gZGUgZXN0cmF0w6lnaWFzIG1haXMgZWZpY2F6ZXMgZSBkaXJlY2lvbmFkYXMuDQoNCk5lc3RlIG5vdGVib29rLCByZWFsaXphcmVtb3MgdW1hIGFuw6FsaXNlIGV4cGxvcmF0w7NyaWEgZGUgZGFkb3MgZGUgZGl2ZXJzYXMgZm9udGVzIHNvYnJlIGFiYW5kb25vIGUgZXZhc8OjbyBlc2NvbGFyLCB1dGlsaXphbmRvIHTDqWNuaWNhcyBkZSBlc3RhdMOtc3RpY2EgZGVzY3JpdGl2YSBlIGluZmVyZW5jaWFsIHBhcmEgZXhhbWluYXIgb3MgcGFkcsO1ZXMgZSB0ZW5kw6puY2lhcyBwcmVzZW50ZXMgbm9zIGRhZG9zLiBBdHJhdsOpcyBkZXNzYSBhbsOhbGlzZSwgYnVzY2Ftb3Mgb2J0ZXIgdW1hIGNvbXByZWVuc8OjbyBtYWlzIHByb2Z1bmRhIGRhcyBldmlkZW5jaWFzIHJlbGFjaW9uYWRzIGEgZXNzZXMgZmVuw7RtZW5vcyBlIGNvbnRyaWJ1aXIgcGFyYSBvIGFwcmltb3JhbWVudG8gZGUgcG9sw610aWNhcywgcHJvamV0b3MsIGHDp8O1ZXMgZSBwcm9jZXNzb3MgcXVlIHByb21vdmFtIGEgaW5jbHVzw6NvIGUgYSBlcXVpZGFkZSBuYSBlZHVjYcOnw6NvLg0KDQpgYGB7cn0NCiMgcGFjb3RlcyB1dGlsaXphZG9zIG5lc3NhIGFuYWxpc2U6DQojIHRpZHl2ZXJzZTogTyB0aWR5dmVyc2Ugw6kgdW0gY29uanVudG8gZGUgcGFjb3RlcyBkbyBSIHF1ZSBjb21wYXJ0aWxoYW0gdW1hIGZpbG9zb2ZpYSBjb211bSBkZSBtYW5pcHVsYcOnw6NvIGUgdmlzdWFsaXphw6fDo28gZGUgZGFkb3MuIEluY2x1aSBwYWNvdGVzIGNvbW8gZ2dwbG90MiBwYXJhIHZpc3VhbGl6YcOnw6NvIGRlIGRhZG9zLCBkcGx5ciBwYXJhIG1hbmlwdWxhw6fDo28gZGUgZGFkb3MgZSB0aWR5ciBwYXJhIHJlZm9ybXVsYcOnw6NvIGRlIGRhZG9zLg0KbGlicmFyeSh0aWR5dmVyc2UpDQojIGNhcmV0OiBPIHBhY290ZSBjYXJldCAoQ2xhc3NpZmljYcOnw6NvIGUgUmVncmVzc8OjbyBUcmVpbmFkYXMpIGZvcm5lY2UgdW1hIGludGVyZmFjZSB1bmlmaWNhZGEgcGFyYSBhIGNvbnN0cnXDp8OjbyBkZSBtb2RlbG9zIGRlIGFwcmVuZGl6YWRvIGRlIG3DoXF1aW5hIHN1cGVydmlzaW9uYWRvcyBlIG7Do28gc3VwZXJ2aXNpb25hZG9zLiBFbGUgc2ltcGxpZmljYSBvIHByb2Nlc3NvIGRlIGFqdXN0ZSwgYXZhbGlhw6fDo28gZSBzaW50b25pYSBkZSBtb2RlbG9zLCBvZmVyZWNlbmRvIHbDoXJpYXMgZnVuw6fDtWVzIGUgbcOpdG9kb3MuDQpsaWJyYXJ5KGNhcmV0KQ0KIyBzaWRyYXI6IE8gcGFjb3RlIHNpZHJhciBvZmVyZWNlIHVtYSBpbnRlcmZhY2UgcGFyYSBhY2Vzc2FyIGRhZG9zIGRvIFNJRFJBIChTaXN0ZW1hIElCR0UgZGUgUmVjdXBlcmHDp8OjbyBBdXRvbcOhdGljYSksIHF1ZSDDqSB1bWEgcGxhdGFmb3JtYSBkbyBJbnN0aXR1dG8gQnJhc2lsZWlybyBkZSBHZW9ncmFmaWEgZSBFc3RhdMOtc3RpY2EgKElCR0UpIHBhcmEgYWNlc3NvIGEgZGFkb3MgZXN0YXTDrXN0aWNvcy4NCmxpYnJhcnkoc2lkcmFyKQ0KIyByYW5kb21Gb3Jlc3Q6IE8gcGFjb3RlIHJhbmRvbUZvcmVzdCBpbXBsZW1lbnRhIG8gYWxnb3JpdG1vIGRlIGZsb3Jlc3RhcyBhbGVhdMOzcmlhcyBwYXJhIGFwcmVuZGl6YWRvIGRlIG3DoXF1aW5hLiDDiSB1bWEgdMOpY25pY2EgZGUgY29uanVudG8gcXVlIGNvbWJpbmEgbcO6bHRpcGxhcyDDoXJ2b3JlcyBkZSBkZWNpc8OjbyBwYXJhIHJlYWxpemFyIGNsYXNzaWZpY2HDp8OjbyBlIHJlZ3Jlc3PDo28uDQpsaWJyYXJ5KHJhbmRvbUZvcmVzdCkNCiMgcnBhcnQ6IE8gcGFjb3RlIHJwYXJ0IMOpIHVzYWRvIHBhcmEgYWp1c3RhciDDoXJ2b3JlcyBkZSBkZWNpc8OjbyByZWN1cnNpdmFzLiBFbGUgw6kgY29tdW1lbnRlIHVzYWRvIGVtIGFuw6FsaXNlIGRlIGRhZG9zIHBhcmEgY2xhc3NpZmljYcOnw6NvIGUgcmVncmVzc8Ojby4NCmxpYnJhcnkocnBhcnQpDQojIHJwYXJ0LnBsb3Q6IE8gcGFjb3RlIHJwYXJ0LnBsb3QgZm9ybmVjZSBmdW7Dp8O1ZXMgcGFyYSB2aXN1YWxpemFyIMOhcnZvcmVzIGRlIGRlY2lzw6NvIGNyaWFkYXMgY29tIG8gcGFjb3RlIHJwYXJ0LiBFbGUgcGVybWl0ZSBjcmlhciBncsOhZmljb3MgdmlzdWFsbWVudGUgYXRyYWVudGVzIGRhcyDDoXJ2b3JlcyBkZSBkZWNpc8OjbywgZmFjaWxpdGFuZG8gYSBpbnRlcnByZXRhw6fDo28gZG9zIHJlc3VsdGFkb3MuDQpsaWJyYXJ5KHJwYXJ0LnBsb3QpDQoNCg0KYGBgDQoNCiMjIElCR0UgLSBNSUNST0RBRE9TDQojIyBJbnRyb2R1w6fDo28NCk9zIG1pY3JvZGFkb3MgZGEgUGVzcXVpc2EgTmFjaW9uYWwgcG9yIEFtb3N0cmEgZGUgRG9taWPDrWxpb3MgQ29udMOtbnVhIChQTkFEQyksIGRpc3BvbmliaWxpemFkb3MgcGVsbyBJbnN0aXR1dG8gQnJhc2lsZWlybyBkZSBHZW9ncmFmaWEgZSBFc3RhdMOtc3RpY2EgKElCR0UpLCBzw6NvIHVtYSBmb250ZSB2YWxpb3NhIGRlIGluZm9ybWHDp8O1ZXMgc29icmUgYSBzaXR1YcOnw6NvIHNvY2lvZWNvbsO0bWljYSBkYSBwb3B1bGHDp8OjbyBicmFzaWxlaXJhLiBBIFBOQURDIMOpIHVtYSBwZXNxdWlzYSByZWFsaXphZGEgZW0gdG9kbyBvIHBhw61zLCBxdWUgaW52ZXN0aWdhIHVtYSBhbXBsYSBnYW1hIGRlIHRlbWFzLCBpbmNsdWluZG8gbWVyY2FkbyBkZSB0cmFiYWxobywgcmVuZGltZW50bywgZWR1Y2HDp8Ojbywgc2HDumRlIGUgb3V0cmFzIHF1ZXN0w7VlcyByZWxldmFudGVzIHBhcmEgYSBjb21wcmVlbnPDo28gZGEgcmVhbGlkYWRlIGJyYXNpbGVpcmEuDQoNClJlZmVyZW5jaWFzOiBodHRwczovL2RvaS5vcmcvMTAuNTI4MS96ZW5vZG8uODExMTg0MSAtIE1PVElWT1MgREUgQUJBTkRPTk8gRVNDT0xBUiBOTyBCUkFTSUw6IEFOw4FMSVNFIERFIERBRE9TIERBIFBOQUQgQ09OVMONTlVBIERFIDIwMTkNClRhYmVsYSA3MjE3DQoNCmBgYHtyfQ0KdHhfZXNjPC1nZXRfc2lkcmEoNzIxNyxnZW8gPSAiUmVnaW9uIikNCnR4X2VzYyRWYXJpw6F2ZWwgJT4lIHVuaXF1ZSgpDQp0eF9lc2MgJT4lIA0KICBmaWx0ZXIoVmFyacOhdmVsPT0gIkRpc3RyaWJ1acOnw6NvIHBlcmNlbnR1YWwgZGFzIHBlc3NvYXMgZGUgMTQgYSAyOSBhbm9zIHF1ZSBudW5jYSBmcmVxdWVudGFyYW0gZXNjb2xhIG91IHF1ZSBqw6EgZnJlcXVlbnRhcmFtIGUgbsOjbyBjb25jbHXDrXJhbSBvIGVuc2lubyBtw6lkaW8gb3UgY3Vyc28gZXF1aXZhbGVudGUiKSAlPiUgDQogIGZpbHRlcighYFByaW5jaXBhbCBtb3Rpdm8gZGUgdGVyIGRlaXhhZG8gb3UgbnVuY2EgdGVyIGZyZXF1ZW50YWRvIGVzY29sYWA9PSJUb3RhbCIsDQogICAgICAgICAhU2V4bz09IlRvdGFsIikgJT4lICNzZWxlY3QoVmFyacOhdmVsKSAlPiUgdW5pcXVlDQogIGdncGxvdChhZXMoYFByaW5jaXBhbCBtb3Rpdm8gZGUgdGVyIGRlaXhhZG8gb3UgbnVuY2EgdGVyIGZyZXF1ZW50YWRvIGVzY29sYWAsIFZhbG9yLGZpbGw9YFByaW5jaXBhbCBtb3Rpdm8gZGUgdGVyIGRlaXhhZG8gb3UgbnVuY2EgdGVyIGZyZXF1ZW50YWRvIGVzY29sYWApKStnZW9tX2NvbCgpKw0KICBsYWJzKHk9IiUgZGUgcGVzc29hcyBkZSAxNCBhIDI5IGFub3MgcXVlIG51bmNhIGZyZXF1ZW50YXJhbSBlc2NvbGEgb3UgcXVlIGrDoSBmcmVxdWVudGFyYW0gZSBuw6NvIGNvbmNsdcOtcmFtIG8gZW5zaW5vIG3DqWRpbyIsDQogICAgICAgdGl0bGUgPSAiIikrDQogIGZhY2V0X2dyaWQoYEdyYW5kZSBSZWdpw6NvYH5TZXhvKSsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1wYXN0ZShWYWxvciwiJSIpKSkNCmBgYA0KVGFiZWxhIDcyMTkNCg0KYGBge3J9DQp0eF9lc2M8LWdldF9zaWRyYSg3MjE5LGdlbyA9ICJSZWdpb24iKQ0KdHhfZXNjJGBQcmluY2lwYWwgbW90aXZvIGRlIGF0dWFsbWVudGUgbsOjbyBmcmVxdWVudGFyIGVzY29sYSBvdSBvdXRybyBjdXJzb2AgJT4lIHVuaXF1ZSgpDQp0eF9lc2MgJT4lIA0KICBmaWx0ZXIoVmFyacOhdmVsPT0gICJEaXN0cmlidWnDp8OjbyBwZXJjZW50dWFsIGRhcyBwZXNzb2FzIGRlIDE1IGEgMjkgYW5vcyBkZSBpZGFkZSBjb20gbsOtdmVsIGRlIGluc3RydcOnw6NvIGluZmVyaW9yIGFvIG3DqWRpbyBjb21wbGV0byBlIHF1ZSBuw6NvIGZyZXF1ZW50YW0gZXNjb2xhLCBjdXJzbyB0w6ljbmljbywgbm9ybWFsIChtYWdpc3TDqXJpbyksIHByw6ktdmVzdGlidWxhciBvdSBjdXJzbyBkZSBxdWFsaWZpY2HDp8OjbyBwcm9maXNzaW9uYWwiICkgJT4lIA0KICBmaWx0ZXIoIWBQcmluY2lwYWwgbW90aXZvIGRlIGF0dWFsbWVudGUgbsOjbyBmcmVxdWVudGFyIGVzY29sYSBvdSBvdXRybyBjdXJzb2A9PSJUb3RhbCIsDQogICAgICAgICAhU2V4bz09IlRvdGFsIikgJT4lICNzZWxlY3QoVmFyacOhdmVsKSAlPiUgdW5pcXVlDQogIGdncGxvdChhZXMoYFByaW5jaXBhbCBtb3Rpdm8gZGUgYXR1YWxtZW50ZSBuw6NvIGZyZXF1ZW50YXIgZXNjb2xhIG91IG91dHJvIGN1cnNvYCwgVmFsb3IsZmlsbD1gUHJpbmNpcGFsIG1vdGl2byBkZSBhdHVhbG1lbnRlIG7Do28gZnJlcXVlbnRhciBlc2NvbGEgb3Ugb3V0cm8gY3Vyc29gKSkrZ2VvbV9jb2woKSsNCiAgbGFicyh5PSIlIGRlIHBlc3NvYXMgZGUgMTQgYSAyOSBhbm9zIHF1ZSBudW5jYSBmcmVxdWVudGFyYW0gZXNjb2xhIG91IHF1ZSBqw6EgZnJlcXVlbnRhcmFtIGUgbsOjbyBjb25jbHXDrXJhbSBvIGVuc2lubyBtw6lkaW8iLA0KICAgICAgIHRpdGxlID0gIiIpKw0KICBmYWNldF9ncmlkKGBHcmFuZGUgUmVnacOjb2B+U2V4bykrDQogIGdlb21fdGV4dChhZXMobGFiZWw9cGFzdGUoVmFsb3IsIiUiKSkpDQpgYGANCg0KDQogICAgLSAgIDcxMzggLSBUYXhhIGRlIGVzY29sYXJpemHDp8OjbywgcG9yIHNleG8gZSBncnVwbyBkZSBpZGFkZQ0KDQpgYGB7ciB9DQpsaWJyYXJ5KHNpZHJhcikNCnR4X2VzYzwtZ2V0X3NpZHJhKDcxMzgsIGdlbyA9IGMoIlN0YXRlIiksZm9ybWF0ID0gMixwZXJpb2QgPSAiYWxsIikNCnR4X2VzYyAlPiUgZmlsdGVyKGBVbmlkYWRlIGRhIEZlZGVyYcOnw6NvYD09IkRpc3RyaXRvIEZlZGVyYWwiLFZhcmnDoXZlbD09IlRheGEgZGUgZXNjb2xhcml6YcOnw6NvIiklPiUgc2VsZWN0KC1gTsOtdmVsIFRlcnJpdG9yaWFsYCkgJT4lIA0KICBnZ3Bsb3QoYWVzKFNleG8sZmlsbD1TZXhvLFZhbG9yKSkrZ2VvbV9jb2woKStmYWNldF9ncmlkKGBHcnVwbyBkZSBpZGFkZWB+YXMubnVtZXJpYyhBbm8pKStnZW9tX3RleHQoYWVzKGxhYmVsPVZhbG9yKSkrbGFicyh0aXRsZSA9ICJUYXhhIGRlIEVzY29sYXJpemHDp8OjbyBwb3IgRmFpeGEgZGUgaWRhZGUgZSBTZXhvIixjYXB0aW9uID0gIkZvbnRlOiBJQkdFL1BOQURDL0EiKQ0KdHhfZXNjJGBHcnVwbyBkZSBpZGFkZWA8LWFzLmZhY3Rvcih0eF9lc2MkYEdydXBvIGRlIGlkYWRlYCkNCmxldmVscyh0eF9lc2MkYEdydXBvIGRlIGlkYWRlYCkNCnR4X2VzYyRgR3J1cG8gZGUgaWRhZGVgIDwtIG9yZGVyZWQodHhfZXNjJGBHcnVwbyBkZSBpZGFkZWAsIGxldmVscyA9IGMoIjAgYSAzIGFub3MiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMCBhIDUgYW5vcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI0IGEgNSBhbm9zIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjYgYSAxNCBhbm9zIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjE1IGEgMTcgYW5vcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIxOCBhIDI0IGFub3MiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMjUgYW5vcyBvdSBtYWlzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRvdGFsIiApKQ0KDQp0eF9lc2MgJT4lIGZpbHRlcihgVW5pZGFkZSBkYSBGZWRlcmHDp8Ojb2A9PSJEaXN0cml0byBGZWRlcmFsIixWYXJpw6F2ZWw9PSJUYXhhIGRlIGVzY29sYXJpemHDp8OjbyIpJT4lIHNlbGVjdCgtYE7DrXZlbCBUZXJyaXRvcmlhbGApICU+JSANCiAgZ2dwbG90KGFlcyhhcy5udW1lcmljKEFubyksY29sPVNleG8sVmFsb3IpKStnZW9tX2xpbmUoKStmYWNldF93cmFwKH5gR3J1cG8gZGUgaWRhZGVgLHNjYWxlcz0iZnJlZSIpK2dlb21fdGV4dChhZXMobGFiZWw9VmFsb3IpKStsYWJzKHRpdGxlID0gIlRheGEgZGUgRXNjb2xhcml6YcOnw6NvIHBvciBGYWl4YSBkZSBpZGFkZSBlIFNleG8iLGNhcHRpb24gPSAiRm9udGU6IElCR0UvUE5BREMvQSIpK3RoZW1lX21pbmltYWwoKQ0KDQoNCmBgYA0KDQotICAgTsOjbyBGcmVxdWVudGEgYSBlc2NvbGENCg0KICAgIC0gICA3MTM5IC0gW1RheGEgZGUgZXNjb2xhcml6YcOnw6NvLCBwb3IgY29yIG91IHJhw6dhIGUgZ3J1cG8gZGUNCiAgICAgICAgaWRhZGVdKGh0dHBzOi8vc2lkcmEuaWJnZS5nb3YuYnIvdGFiZWxhLzcxMzkgIkFicmlyIFRhYmVsYSIpDQoNCiAgICBgYGB7cn0NCmxpYnJhcnkoc2lkcmFyKQ0KdHhfZXNjPC1nZXRfc2lkcmEoNzEzOSwgZ2VvID0gYygiU3RhdGUiKSxmb3JtYXQgPSAyLHBlcmlvZCA9ICJhbGwiKQ0KDQp0eF9lc2MkYEdydXBvIGRlIGlkYWRlYDwtYXMuZmFjdG9yKHR4X2VzYyRgR3J1cG8gZGUgaWRhZGVgKQ0KdHhfZXNjJGBHcnVwbyBkZSBpZGFkZWAgPC0gb3JkZXJlZCh0eF9lc2MkYEdydXBvIGRlIGlkYWRlYCwgbGV2ZWxzID0gYygiMCBhIDMgYW5vcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMCBhIDUgYW5vcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNCBhIDUgYW5vcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNiBhIDE0IGFub3MiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjE1IGEgMTcgYW5vcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMTggYSAyNCBhbm9zIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIyNSBhbm9zIG91IG1haXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRvdGFsIiApKQ0KDQpgYGANCg0KYGBge3J9DQoNCnR4X2VzYyAlPiUgZmlsdGVyKGBVbmlkYWRlIGRhIEZlZGVyYcOnw6NvYD09IkRpc3RyaXRvIEZlZGVyYWwiLFZhcmnDoXZlbD09IlRheGEgZGUgZXNjb2xhcml6YcOnw6NvIiklPiUgc2VsZWN0KC1gTsOtdmVsIFRlcnJpdG9yaWFsYCkgJT4lDQogIGdncGxvdChhZXMoYXMubnVtZXJpYyhBbm8pLGNvbD1gQ29yIG91IHJhw6dhYCxWYWxvcikpK2dlb21fbGluZSgpKw0KICBmYWNldF93cmFwKH5gR3J1cG8gZGUgaWRhZGVgLHNjYWxlcz0iZnJlZSIpKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsPVZhbG9yKSkrDQogIGxhYnModGl0bGUgPSAiVGF4YSBkZSBFc2NvbGFyaXphw6fDo28gcG9yIEZhaXhhIGRlIGlkYWRlIGUgUmHDp2EiLGNhcHRpb24gPSAiRm9udGU6IElCR0UvUE5BREMvQSIpKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQotICAgNzE0MiBUYXhhIGFqdXN0YWRhIGRlIGZyZXF1w6puY2lhIGVzY29sYXIgbMOtcXVpZGEsIHBvciBjb3Igb3UgcmHDp2EgZSBmYWl4YQ0KICAgIGV0w6FyaWEgaWRlYWwgcG9yIGN1cnNvIGZyZXF1ZW50YWRvDQoNCmBgYHtyIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQ0KbGlicmFyeShzaWRyYXIpDQp0eF9lc2M8LWdldF9zaWRyYSg3MTQyLCBnZW8gPSBjKCJTdGF0ZSIpLGZvcm1hdCA9IDIscGVyaW9kID0gImFsbCIpDQojdHhfZXNjJGBHcnVwbyBkZSBpZGFkZWA8LWFzLmZhY3Rvcih0eF9lc2MkYEdydXBvIGRlIGlkYWRlYCkNCiN0eF9lc2MkYEdydXBvIGRlIGlkYWRlYCA8LSBvcmRlcmVkKHR4X2VzYyRgR3J1cG8gZGUgaWRhZGVgLCBsZXZlbHMgPSBjKCIwIGEgMyBhbm9zIiwNCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIwIGEgNSBhbm9zIiwNCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI0IGEgNSBhbm9zIiwNCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI2IGEgMTQgYW5vcyIsDQojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMTUgYSAxNyBhbm9zIiwNCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIxOCBhIDI0IGFub3MiLA0KIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjI1IGFub3Mgb3UgbWFpcyIsDQojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVG90YWwiICkpDQojdHhfZXNjICU+JSBmaWx0ZXIoYFVuaWRhZGUgZGEgRmVkZXJhw6fDo29gPT0iRGlzdHJpdG8gRmVkZXJhbCIsVmFyacOhdmVsPT0iVGF4YSBhanVzdGFkYSBkZSBmcmVxdcOqbmNpYSBlc2NvbGFyIGzDrXF1aWRhIiklPiUgc2VsZWN0KC1gTsOtdmVsICNUZXJyaXRvcmlhbGApICU+JSANCiMgIGdncGxvdChhZXMoYENvciBvdSByYcOnYWAsZmlsbD1gQ29yIG91IHJhw6dhYCxWYWxvcikpK2dlb21fY29sKCkrZmFjZXRfZ3JpZChgRmFpeGEgZXTDoXJpYSBpZGVhbCBwb3IgY3Vyc28gI2ZyZXF1ZW50YWRvYH5hcy5udW1lcmljKEFubykpK2dlb21fdGV4dChhZXMobGFiZWw9VmFsb3IpKStsYWJzKHRpdGxlID0gIlRheGEgYWp1c3RhZGEgZGUgZnJlcXXDqm5jaWEgZXNjb2xhciBsw61xdWlkYSBwb3IgRmFpeGEgZGUgaWRhZGUiLGNhcHRpb24gIz0gIkZvbnRlOiBJQkdFL1BOQURDL0EiKSt0aGVtZV92b2lkKCkNCiMNCnR4X2VzYyAlPiUgZmlsdGVyKGBVbmlkYWRlIGRhIEZlZGVyYcOnw6NvYD09IkRpc3RyaXRvIEZlZGVyYWwiLFZhcmnDoXZlbD09IlRheGEgYWp1c3RhZGEgZGUgZnJlcXXDqm5jaWEgZXNjb2xhciBsw61xdWlkYSIpJT4lIHNlbGVjdCgtYE7DrXZlbCBUZXJyaXRvcmlhbGApICU+JSANCiAgZ2dwbG90KGFlcyhhcy5udW1lcmljKEFubyksY29sPWBDb3Igb3UgcmHDp2FgLFZhbG9yKSkrZ2VvbV9saW5lKCkrZmFjZXRfd3JhcCh+YEZhaXhhIGV0w6FyaWEgaWRlYWwgcG9yIGN1cnNvIGZyZXF1ZW50YWRvYCxzY2FsZXM9ImZyZWUiKStnZW9tX3RleHQoYWVzKGxhYmVsPVZhbG9yKSkrbGFicyh0aXRsZSA9ICJUYXhhIGRlIEVzY29sYXJpemHDp8OjbyBwb3IgRmFpeGEgZGUgaWRhZGUgZSBSYcOnYSIsY2FwdGlvbiA9ICJGb250ZTogSUJHRS9QTkFEQy9BIikrdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KIyMgSVBERiAtIE1JQ1JPREFET1MNCg0KQXZhbGlhw6fDo28gZGEgQW1vc3RyYToNCg0KYGBge3J9DQpQREFEXzIwMjFfTW9yYWRvcmVzIDwtIHJlYWRfZGVsaW0oIi8vMTAuMjIxLjM3LjI0MS9kaW5mZS9Eb2N1bWVudG9zLzIwMjMvVHJhdGFtZW50by9USElBR08gUFJPSkVUTy9HRVRFRC9QQ0YvUERBRF8yMDIxLU1vcmFkb3Jlcy5jc3YiLCANCiAgICBkZWxpbSA9ICI7IiwgZXNjYXBlX2RvdWJsZSA9IEZBTFNFLCB0cmltX3dzID0gVFJVRSkNCiMgQ3JpYXIgbyBkYXRhZnJhbWUgY29tIGRpY2lvbmFyaW8gZGUgUkEncw0KZGljX1JBIDwtIGRhdGEuZnJhbWUoQTAxcmEgPSAxOjMzLCBSQSA9IGMoIlBsYW5vIFBpbG90byIsICJHYW1hIiwgIlRhZ3VhdGluZ2EiLCAiQnJhemzDom5kaWEiLCAiU29icmFkaW5obyIsICJQbGFuYWx0aW5hIiwgIlBhcmFub8OhIiwgDQogICAgICAgICAgICAgICAgIk7DumNsZW8gQmFuZGVpcmFudGUiLCAiQ2VpbMOibmRpYSIsICJHdWFyw6EiLCAiQ3J1emVpcm8iLCAiU2FtYW1iYWlhIiwgIlNhbnRhIE1hcmlhIiwgIlPDo28gU2ViYXN0acOjbyIsIA0KICAgICAgICAgICAgICAgICJSZWNhbnRvIERhcyBFbWFzIiwgIkxhZ28gU3VsIiwgIlJpYWNobyBGdW5kbyIsICJMYWdvIE5vcnRlIiwgIkNhbmRhbmdvbMOibmRpYSIsICLDgWd1YXMgQ2xhcmFzIiwgDQogICAgICAgICAgICAgICAgIlJpYWNobyBGdW5kbyBJSSIsICJTdWRvZXN0ZSBlIE9jdG9nb25hbCIsICJWYXJqw6NvIiwgIlBhcmsgV2F5IiwgIlNDSUEiLCAiU29icmFkaW5obyBJSSIsIA0KICAgICAgICAgICAgICAgICJKYXJkaW0gQm90w6JuaWNvIiwgIkl0YXBvw6MiLCAiU0lBIiwgIlZpY2VudGUgUGlyZXMiLCAiRmVyY2FsIiwgIlNvbCBOYXNjZW50ZSAvIFDDtHIgZG8gU29sIiwgDQogICAgICAgICAgICAgICAgIkFybmlxdWVpcmEiKSkNClBEQURfMjAyMV9Nb3JfUkE8LWxlZnRfam9pbihQREFEXzIwMjFfTW9yYWRvcmVzLGRpY19SQSxieT0iQTAxcmEiKQ0KDQojbsK6IGRlIHJlc2lkZW5jaWFzIGUgbW9yYWRvcmVzIGlkZW50aWZpY2Fkb3M6DQpQREFEXzIwMjFfTW9yX1JBICU+JSBzdW1tYXJpc2UoIm7CumRlIG1vcmFkb3JlcyI9bigpLCJuwrogZGUgUmVzaWRlbmNpYSI9bl9kaXN0aW5jdChBMDFuZmljaGEpKQ0KDQojbsK6IGRlIHJlc2lkZW5jaWFzIGUgbW9yYWRvcmVzIGlkZW50aWZpY2Fkb3MgcG9yIFJBDQpQREFEXzIwMjFfTW9yX1JBICU+JSBncm91cF9ieShSQSkgJT4lIHN1bW1hcmlzZSgibsK6ZGUgbW9yYWRvcmVzIj1uKCksIm7CuiBkZSBSZXNpZGVuY2lhIj1uX2Rpc3RpbmN0KEEwMW5maWNoYSkpDQoNCg0KYGBgDQoNCkgwMiBGcmVxdWVudGEgY3JlY2hlLCBlc2NvbGEgb3UgZmFjdWxkYWRlL3VuaXZlcnNpZGFkZSAxIFNpbSwgcMO6YmxpY2EgMiBTaW0sDQpwYXJ0aWN1bGFyIDMgTsOjbywgbWFzIGrDoSBmcmVxdWVudG91IDQgTsOjbywgbnVuY2EgZnJlcXVlbnRvdQ0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KDQpQREFEXzIwMjFfTW9yYWRvcmVzJEgwMyAlPiUgdW5pcXVlKCkNClBEQURfMjAyMV9Nb3JhZG9yZXMgJT4lIG11dGF0ZShFc2NvbGFyaXphY2FvPWlmX2Vsc2UoSDAyPT00LCJudW5jYV9mcmVxdWVudG91X2VzY29sYSIsImZyZXF1ZW50b3VfZXNjb2xhIikpICU+JSBncm91cF9ieShpZGFkZSxFc2NvbGFyaXphY2FvKSAlPiUgc3VtbWFyaXNlKG49bigpKSAlPiUgc3ByZWFkKEVzY29sYXJpemFjYW8sbikgJT4lIG11dGF0ZShwZXJjZW50dWFsPW51bmNhX2ZyZXF1ZW50b3VfZXNjb2xhLyhmcmVxdWVudG91X2VzY29sYStudW5jYV9mcmVxdWVudG91X2VzY29sYSkpICU+JSANCiAgZ2dwbG90KGFlcyhpZGFkZSxwZXJjZW50dWFsKSkrZ2VvbV9jb2woYWxwaGE9MC41KSsNCiAgeGxpbSgzLjIsMTcuOSkrICB5bGltKC0wLDAuNSkrDQoNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1wYXN0ZShyb3VuZChwZXJjZW50dWFsKjEwMCwyKSwiJSIpKSxudWRnZV95ID0gLjA1KSsNCiAgI3NjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDQsMTcpKSsNCiAgY29vcmRfZmxpcCgpKw0KICBsYWJzKHRpdGxlID0gIkV2YXPDo28gRXNjb2xhciBwb3IgSWRhZGUiLHN1YnRpdGxlID0gIlBlcmNlbnR1YWwgZGUgUmVzaWRlbnRlIGRvIERGIHF1ZSBudW5jYSBmcmVxdWVudG91IEVzY29sYSIsY2FwdGlvbiA9ICJGb250ZTpNaWNyb2RhZG9zIFBFREFEXzIwMjFfTW9yYWRvcmVzIikNCg0KDQpgYGANCg0KQW5hbGlzZSBwb3IgUkENCg0KYGBge3IgZmlnMiwgZmlnLmhlaWdodCA9IDE1LCBmaWcud2lkdGggPSAxMiwgZmlnLmFsaWduID0gImNlbnRlciJ9DQoNCg0KUERBRF8yMDIxX01vcl9SQSAlPiUgbXV0YXRlKEVzY29sYXJpemFjYW89aWZfZWxzZShIMDI9PTQsIm51bmNhX2ZyZXF1ZW50b3VfZXNjb2xhIiwiZnJlcXVlbnRvdV9lc2NvbGEiKSkgJT4lIGdyb3VwX2J5KGlkYWRlLEVzY29sYXJpemFjYW8sUkEpICU+JSBzdW1tYXJpc2Uobj1uKCkpICU+JSBzcHJlYWQoRXNjb2xhcml6YWNhbyxuKSAlPiUNCiAgbXV0YXRlKHBlcmNlbnR1YWw9bnVuY2FfZnJlcXVlbnRvdV9lc2NvbGEvKGZyZXF1ZW50b3VfZXNjb2xhK251bmNhX2ZyZXF1ZW50b3VfZXNjb2xhKSkgJT4lDQogIG11dGF0ZShwZXJjZW50dWFsPWlmZWxzZShpcy5uYShwZXJjZW50dWFsKSwwLHBlcmNlbnR1YWwpKSAlPiUgDQogIGdncGxvdChhZXMoaWRhZGUscGVyY2VudHVhbCkpK2dlb21fY29sKGFscGhhPTAuNSkreGxpbSgzLjksMTcuOSkrDQogIGdlb21fdGV4dChhZXMoeT0wLjI1LGxhYmVsPXBhc3RlKHJvdW5kKHBlcmNlbnR1YWwqMTAwLDIpLCIlIikpKStjb29yZF9mbGlwKCkrbGFicyh0aXRsZSA9ICJFdmFzw6NvIEVzY29sYXIgcG9yIElkYWRlIixzdWJ0aXRsZSA9ICJQZXJjZW50dWFsIGRlIFJlc2lkZW50ZSBkbyBERiBxdWUgbnVuY2EgZnJlcXVlbnRvdSBFc2NvbGEiLGNhcHRpb24gPSAiRm9udGU6TWljcm9kYWRvcyBQRURBRF8yMDIxX01vcmFkb3JlcyIpK2ZhY2V0X3dyYXAoflJBLHNjYWxlcyA9ICJmcmVlIikNCg0KYGBgDQoNCkNhcmFjdGVyaXN0aWNhcyBkb3MgcXVlIG51bmNhX2ZyZXF1ZW50b3VfZXNjb2xhDQoNCmBgYHtyfQ0KUERBRF8yMDIxX01vcl9SQSAlPiUgbXV0YXRlKEVzY29sYXJpemFjYW89aWZfZWxzZShIMDI9PTQsIm51bmNhX2ZyZXF1ZW50b3VfZXNjb2xhIiwiZnJlcXVlbnRvdV9lc2NvbGEiKSkgJT4lDQogIGdyb3VwX2J5KGlkYWRlLEVzY29sYXJpemFjYW8sRTA0KSAlPiUgc3VtbWFyaXNlKG49bigpKSAlPiUgc3ByZWFkKEVzY29sYXJpemFjYW8sbikgJT4lIA0KICBtdXRhdGUocGVyY2VudHVhbD1udW5jYV9mcmVxdWVudG91X2VzY29sYS8oZnJlcXVlbnRvdV9lc2NvbGErbnVuY2FfZnJlcXVlbnRvdV9lc2NvbGEpLA0KICAgICAgICAgcGVyY2VudHVhbD1pZmVsc2UoaXMubmEocGVyY2VudHVhbCksMCxwZXJjZW50dWFsKSwNCiAgICAgICAgIHNleG89aWZlbHNlKEUwND09MSwiTWFzY3VsaW5vIiwiRmVtaW5pbm8iKSkgJT4lIA0KICBtdXRhdGUocGVyY2VudHVhbDI9aWZlbHNlKEUwND09MSxwZXJjZW50dWFsLC1wZXJjZW50dWFsKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKGlkYWRlLHBlcmNlbnR1YWwyLGZpbGw9c2V4bykpK2dlb21fY29sKGFscGhhPTAuNSkreGxpbSgzLjksMTcuOSkreWxpbSgtMC4xLDAuMTUpKw0KICBnZW9tX3RleHQoYWVzKHk9cGVyY2VudHVhbDIsaGp1c3QgPWlmZWxzZShwZXJjZW50dWFsMj4wLC0xLDEpLGxhYmVsPXBhc3RlKHJvdW5kKHBlcmNlbnR1YWwqMTAwLDIpLCIlIikpKStjb29yZF9mbGlwKCkrbGFicyh0aXRsZSA9ICJFdmFzw6NvIEVzY29sYXIgcG9yIElkYWRlIGUgU2V4byIsc3VidGl0bGUgPSAiUGVyY2VudHVhbCBkZSBSZXNpZGVudGUgZG8gREYgcXVlIG51bmNhIGZyZXF1ZW50b3UgRXNjb2xhIHBvciBTZXhvIixjYXB0aW9uID0gIkZvbnRlOk1pY3JvZGFkb3MgUEVEQURfMjAyMV9Nb3JhZG9yZXMiKSMrZmFjZXRfd3JhcCh+UkEsc2NhbGVzID0gImZyZWUiKSAgDQoNCmBgYA0KDQpgYGB7cn0NCmE8LVBEQURfMjAyMV9Nb3JfUkEgJT4lIG11dGF0ZShFc2NvbGFyaXphY2FvPWlmX2Vsc2UoSDAyPT00LCJudW5jYV9mcmVxdWVudG91X2VzY29sYSIsImZyZXF1ZW50b3VfZXNjb2xhIikpICU+JQ0KICBncm91cF9ieShpZGFkZSxFc2NvbGFyaXphY2FvLEUwNikgJT4lIHN1bW1hcmlzZShuPW4oKSkgJT4lIHNwcmVhZChFc2NvbGFyaXphY2FvLG4sZmlsbCA9IDApICU+JSANCiAgbXV0YXRlKHBlcmNlbnR1YWw9bnVuY2FfZnJlcXVlbnRvdV9lc2NvbGEvKGZyZXF1ZW50b3VfZXNjb2xhK251bmNhX2ZyZXF1ZW50b3VfZXNjb2xhKSwNCiAgICAgICAgIHBlcmNlbnR1YWw9aWZlbHNlKGlzLm5hKHBlcmNlbnR1YWwpLDAscGVyY2VudHVhbCksDQogICAgICAgICBDb3JfX3Jhw6dhPWNhc2Vfd2hlbihFMDY9PTF+IkJyYW5jYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEUwNj09Mn4iUHJldGEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFMDY9PTN+IkFtYXJlbGEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFMDY9PTR+IlBhcmRhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRTA2PT01fiJJbmTDrWdlbmEiKSkgDQphJT4lIA0KICAjbXV0YXRlKHBlcmNlbnR1YWwyPWlmZWxzZShFMDQ9PTEscGVyY2VudHVhbCwtcGVyY2VudHVhbCkpICU+JSANCiAgZ2dwbG90KGFlcyhpZGFkZSxwZXJjZW50dWFsLGZpbGw9Q29yX19yYcOnYSkpK2dlb21fY29sKGFscGhhPTAuNSkreGxpbSgzLjUsMTguOSkrDQogIGdlb21fdGV4dChhZXMoeT1wZXJjZW50dWFsKzAuMyxsYWJlbD1wYXN0ZShyb3VuZChwZXJjZW50dWFsKjEwMCwyKSwiJSIpKSkrY29vcmRfZmxpcCgpK2xhYnModGl0bGUgPSAiRXZhc8OjbyBFc2NvbGFyIHBvciBJZGFkZSBlIFJhw6dhIixzdWJ0aXRsZSA9ICJQZXJjZW50dWFsIGRlIFJlc2lkZW50ZSBkbyBERiBxdWUgbnVuY2EgZnJlcXVlbnRvdSBFc2NvbGEiLGNhcHRpb24gPSAiRm9udGU6TWljcm9kYWRvcyBQRURBRF8yMDIxX01vcmFkb3JlcyBwb3IgY29yL3Jhw6dhIikrZmFjZXRfd3JhcCh+Q29yX19yYcOnYSxzY2FsZXMgPSAiZnJlZSIpICANCmBgYA0KDQpOYXNjZXUgbm8gREYgMSBTaW0gMiBOw6NvIDg4ODg4IE7Do28gc2FiZQ0KDQpgYGB7cn0NCmE8LVBEQURfMjAyMV9Nb3JfUkEgJT4lIG11dGF0ZShFc2NvbGFyaXphY2FvPWlmX2Vsc2UoSDAyPT00LCJudW5jYV9mcmVxdWVudG91X2VzY29sYSIsImZyZXF1ZW50b3VfZXNjb2xhIikpICU+JQ0KICBncm91cF9ieShpZGFkZSxFc2NvbGFyaXphY2FvLEUxNCkgJT4lIHN1bW1hcmlzZShuPW4oKSkgJT4lIHNwcmVhZChFc2NvbGFyaXphY2FvLG4sZmlsbCA9IDApICU+JSANCiAgbXV0YXRlKHBlcmNlbnR1YWw9bnVuY2FfZnJlcXVlbnRvdV9lc2NvbGEvKGZyZXF1ZW50b3VfZXNjb2xhK251bmNhX2ZyZXF1ZW50b3VfZXNjb2xhKSwNCiAgICAgICAgIHBlcmNlbnR1YWw9aWZlbHNlKGlzLm5hKHBlcmNlbnR1YWwpLDAscGVyY2VudHVhbCksDQogICAgICAgICBOYXNjZXVfREY9Y2FzZV93aGVuKEUxND09MX4iU2ltIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRTE0PT0yfiJOw6NvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmRlZmF1bHQgPSJOw6NvIHNhYmUiKSkgDQphJT4lIA0KICBtdXRhdGUocGVyY2VudHVhbDI9aWZlbHNlKEUxND09MSxwZXJjZW50dWFsLC1wZXJjZW50dWFsKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKGlkYWRlLHBlcmNlbnR1YWwyLGZpbGw9TmFzY2V1X0RGKSkrZ2VvbV9jb2woYWxwaGE9MC41KSt4bGltKDMuNSwxOC45KSsjeWxpbSgtMTAwMCwxMDAwKSsNCiAgZ2VvbV90ZXh0KGFlcyh5PWlmZWxzZShwZXJjZW50dWFsMj4wLDAuMiwtMC4yKSxsYWJlbD1wYXN0ZShyb3VuZChwZXJjZW50dWFsKjEwMCwyKSwiJSIpKSkrDQogIGNvb3JkX2ZsaXAoKSsNCiAgbGFicyh0aXRsZSA9ICJFdmFzw6NvIEVzY29sYXIgcG9yIElkYWRlIGUgU2V4byIsc3VidGl0bGUgPSAiUGVyY2VudHVhbCBkZSBSZXNpZGVudGUgZG8gREYgcXVlIG51bmNhIGZyZXF1ZW50b3UgRXNjb2xhIixjYXB0aW9uID0gIkZvbnRlOk1pY3JvZGFkb3MgUEVEQURfMjAyMV9Nb3JhZG9yZXMiKSMrDQogIGZhY2V0X3dyYXAofk5hc2NldV9ERixzY2FsZXMgPSAiZnJlZSIpIA0KYGBgDQoNCkgwMSBTYWJlIGxlciBlIGVzY3JldmVyIDEgU2ltIDIgTsOjbyA4ODg4OCBOw6NvIHNhYmUgOTk5OTkgTsOjbyBzZSBhcGxpY2ENCg0KYGBge3J9DQphPC1QREFEXzIwMjFfTW9yX1JBICU+JSBtdXRhdGUoRXNjb2xhcml6YWNhbz1pZl9lbHNlKEgwMj09NCwibnVuY2FfZnJlcXVlbnRvdV9lc2NvbGEiLCJmcmVxdWVudG91X2VzY29sYSIpKSAlPiUNCiAgZ3JvdXBfYnkoaWRhZGUsRXNjb2xhcml6YWNhbyxIMDEpICU+JSBzdW1tYXJpc2Uobj1uKCkpICU+JSBzcHJlYWQoRXNjb2xhcml6YWNhbyxuLGZpbGwgPSAwKSAlPiUgDQogIG11dGF0ZShwZXJjZW50dWFsPW51bmNhX2ZyZXF1ZW50b3VfZXNjb2xhLyhmcmVxdWVudG91X2VzY29sYStudW5jYV9mcmVxdWVudG91X2VzY29sYSksDQogICAgICAgICBwZXJjZW50dWFsPWlmZWxzZShpcy5uYShwZXJjZW50dWFsKSwwLHBlcmNlbnR1YWwpKQ0KYSU+JSANCiAgI211dGF0ZShwZXJjZW50dWFsMj1pZmVsc2UoRTA0PT0xLHBlcmNlbnR1YWwsLXBlcmNlbnR1YWwpKSAlPiUgDQogIGdncGxvdChhZXMoaWRhZGUscGVyY2VudHVhbCxmaWxsPWFzLmZhY3RvcihIMDEpKSkrZ2VvbV9jb2woYWxwaGE9MC41KSt4bGltKDMuNSwxOC45KSsNCiAgZ2VvbV90ZXh0KGFlcyh5PXBlcmNlbnR1YWwrMC4xLGxhYmVsPXBhc3RlKHJvdW5kKHBlcmNlbnR1YWwqMTAwLDIpLCIlIikpKStjb29yZF9mbGlwKCkrbGFicyh0aXRsZSA9ICJFdmFzw6NvIEVzY29sYXIgcG9yIElkYWRlIGUgU2V4byIsc3VidGl0bGUgPSAiUGVyY2VudHVhbCBkZSBSZXNpZGVudGUgZG8gREYgcXVlIG51bmNhIGZyZXF1ZW50b3UgRXNjb2xhIixjYXB0aW9uID0gIkZvbnRlOk1pY3JvZGFkb3MgUEVEQURfMjAyMV9Nb3JhZG9yZXMiKStmYWNldF93cmFwKH5IMDEsc2NhbGVzID0gImZyZWUiKSANCmBgYA0KDQoNCg0KDQoNCg0KDQptb2RlbG8gZGUgYXJ2b3JlIGRlIGRlY2lzw6NvDQoNCmBgYHtyfQ0KbGlicmFyeShjYXJldCkNCmxpYnJhcnkocmFuZG9tRm9yZXN0KQ0KbGlicmFyeShycGFydCkNCmxpYnJhcnkocnBhcnQucGxvdCkNCg0KYTwtUERBRF8yMDIxX01vcl9SQSAlPiUgbXV0YXRlKEVzY29sYXJpemFjYW89aWZfZWxzZShIMDI9PTQsIm51bmNhX2ZyZXF1ZW50b3VfZXNjb2xhIiwiZnJlcXVlbnRvdV9lc2NvbGEiKSkgJT4lDQogIHNlbGVjdChpZGFkZSxIMDEsRTA1LEVzY29sYXJpemFjYW8pDQoNCmEkRXNjb2xhcml6YWNhbyA8LWFzLmZhY3RvcihhJEVzY29sYXJpemFjYW8pDQpjdHJsIDwtIHRyYWluQ29udHJvbChtZXRob2QgPSAiY3YiLCBudW1iZXIgPSA1KSAgIyBFeGFtcGxlOiA1LWZvbGQgY3Jvc3MtdmFsaWRhdGlvbg0KIyBUcmFpbiBhIFJhbmRvbSBGb3Jlc3QgbW9kZWwNCm1vZGVsIDwtIHRyYWluKEVzY29sYXJpemFjYW8gfiAuLCAgIyBSZXBsYWNlICdDbGFzcycgd2l0aCB5b3VyIHRhcmdldCB2YXJpYWJsZQ0KICAgICAgICAgICAgICAgZGF0YSA9IGEsDQogICAgICAgICAgICAgICBtZXRob2QgPSAicnBhcnQiLA0KICAgICAgICAgICAgICAgdHJDb250cm9sID0gY3RybCkNCmltcG9ydGFuY2UgPC0gdmFySW1wKG1vZGVsKQ0KDQpycGFydC5wbG90KG1vZGVsJGZpbmFsTW9kZWwsZmFsbGVuLmxlYXZlcyA9IFQpDQogIyBWaWV3IHRoZSBpbXBvcnRhbmNlDQpwcmludChpbXBvcnRhbmNlKQ0KDQoNCmBgYA0KDQojIyBJTkVQDQoNCkFiYW5kb25vDQpgYGB7cn0NCiNNYXRyaWN1bGEgUG9yIHNpdHVhw6fDo28NCmxpYnJhcnkocmVhZHIpDQpNYXRyaWN1bGFzX3Bvcl9zaXR1YcOnw6NvXzIwMDdhMjAyMiA8LSByZWFkX2NzdigiLy8xMC4yMjEuMzcuMjQxL2RpbmZlL0RvY3VtZW50b3MvMjAyMy9UcmF0YW1lbnRvL1RISUFHTyBQUk9KRVRPL0dFVEVEL01hdHJpY3VsYXMgcG9yIHNpdHVhw6fDo28sMjAwN2EyMDIyLmNzdiIpDQoNCk1hdHJpY3VsYXNfcG9yX3NpdHVhw6fDo29fMjAwN2EyMDIyJE5PX0VUQVBBX0FHUkVHQURBICU+JSB1bmlxdWUoKQ0KYTwtTWF0cmljdWxhc19wb3Jfc2l0dWHDp8Ojb18yMDA3YTIwMjIgJT4lIGdyb3VwX2J5KE5PX1NJVFVBQ0FPLFRQX1NFWE8sTk9fRVRBUEFfQUdSRUdBREEpICU+JQ0KICBzdW1tYXJpc2Uobj1zdW0obikpICU+JSBzcHJlYWQoTk9fU0lUVUFDQU8sbixmaWxsID0gMCkgJT4lIG11dGF0ZSh0b3RhbD1BYmFuZG9ubytBcHJvdmFkbytGYWxlY2lkbytSZXByb3ZhZG8rU0lSLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBYmFuZG9ub19wZXI9QWJhbmRvbm8vdG90YWwpDQphICU+JSBtdXRhdGUoQWJhbmRvbm9fcGVyMj1pZl9lbHNlKFRQX1NFWE89PTEsQWJhbmRvbm9fcGVyLC1BYmFuZG9ub19wZXIpKSAlPiUgZmlsdGVyKCFBYmFuZG9ubz09MCkgJT4lIA0KICBnZ3Bsb3QoYWVzKE5PX0VUQVBBX0FHUkVHQURBLEFiYW5kb25vX3BlcjIsZmlsbD1hcy5mYWN0b3IoVFBfU0VYTykpKStnZW9tX2NvbChhbHBoYT0wLjMpKw0KICBnZW9tX3RleHQocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDEpLGFlcyhsYWJlbD1wYXN0ZShyb3VuZChBYmFuZG9ub19wZXIqMTAwLDIpLCIlIiksY29sPWFzLmZhY3RvcihUUF9TRVhPKSkpKw0KICBjb29yZF9mbGlwKCkrDQogIGxhYnModGl0bGUgPSAiQWJhbmRvbm8gcG9yIE1vZGFsaWRhZGUgZSBTZXhvIixzdWJ0aXRsZSA9ICJNYXRyaWN1bGFzIGFiYW5kb25hZGFzIGRlIDIwMDcgYSAyMDIyIikNCg0KYGBgDQpRdWFsIHRpcG8gZGUgcmVkZSBlc3TDo28gYXMgbWF0cmljdWxhcyBjb20gYWJhbmRvbm8/DQoiMSAtIEZlZGVyYWwNCjIgLSBFc3RhZHVhbA0KMyAtIE11bmljaXBhbA0KNCAtIFByaXZhZGEiDQoNCmBgYHtyfQ0KI01hdHJpY3VsYSBQb3Igc2l0dWHDp8Ojbw0KbGlicmFyeShyZWFkcikNCk1hdHJpY3VsYXNfcG9yX3NpdHVhw6fDo29fMjAwN2EyMDIyIDwtIHJlYWRfY3N2KCIvLzEwLjIyMS4zNy4yNDEvZGluZmUvRG9jdW1lbnRvcy8yMDIzL1RyYXRhbWVudG8vVEhJQUdPIFBST0pFVE8vR0VURUQvTWF0cmljdWxhcyBwb3Igc2l0dWHDp8OjbywyMDA3YTIwMjIuY3N2IikNCg0KTWF0cmljdWxhc19wb3Jfc2l0dWHDp8Ojb18yMDA3YTIwMjIkTk9fRVRBUEFfQUdSRUdBREEgJT4lIHVuaXF1ZSgpDQphPC1NYXRyaWN1bGFzX3Bvcl9zaXR1YcOnw6NvXzIwMDdhMjAyMiAlPiUgZ3JvdXBfYnkoTk9fU0lUVUFDQU8sVFBfREVQRU5ERU5DSUEsTk9fRVRBUEFfQUdSRUdBREEpICU+JQ0KICBzdW1tYXJpc2Uobj1zdW0obikpICU+JSBzcHJlYWQoTk9fU0lUVUFDQU8sbixmaWxsID0gMCkgJT4lIG11dGF0ZSh0b3RhbD1BYmFuZG9ubytBcHJvdmFkbytGYWxlY2lkbytSZXByb3ZhZG8rU0lSLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBYmFuZG9ub19wZXI9QWJhbmRvbm8vdG90YWwpDQphICU+JSBtdXRhdGUoQWJhbmRvbm9fcGVyMj1pZl9lbHNlKFRQX0RFUEVOREVOQ0lBPT00LEFiYW5kb25vX3BlciwtQWJhbmRvbm9fcGVyKSkgJT4lIGZpbHRlcighQWJhbmRvbm89PTApICU+JSANCiAgZ2dwbG90KGFlcyhhcy5jaGFyYWN0ZXIoVFBfREVQRU5ERU5DSUEpLEFiYW5kb25vX3BlcixmaWxsPWFzLmZhY3RvcihUUF9ERVBFTkRFTkNJQSkpKStnZW9tX2NvbChhbHBoYT0wLjkpKw0KICBnZW9tX3RleHQocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDEpLGFlcyhsYWJlbD1wYXN0ZShyb3VuZChBYmFuZG9ub19wZXIqMTAwLDIpLCIlIikpKSsNCiAgY29vcmRfZmxpcCgpK2ZhY2V0X3dyYXAofk5PX0VUQVBBX0FHUkVHQURBLHNjYWxlcz0iZnJlZSIpDQogIGxhYnModGl0bGUgPSAiQWJhbmRvbm8gcG9yIE1vZGFsaWRhZGUgZSBTZXhvIixzdWJ0aXRsZSA9ICJNYXRyaWN1bGFzIGFiYW5kb25hZGFzIGRlIDIwMDcgYSAyMDIyIikNCg0KYGBgDQoNCg0KDQpgYGB7cn0NCiNNYXRyaWN1bGEgUG9yIHNpdHVhw6fDo28NCmxpYnJhcnkocmVhZHIpDQpNYXRyaWN1bGFzX3Bvcl9zaXR1YcOnw6NvXzIwMDdhMjAyMiA8LSByZWFkX2NzdigiLy8xMC4yMjEuMzcuMjQxL2RpbmZlL0RvY3VtZW50b3MvMjAyMy9UcmF0YW1lbnRvL1RISUFHTyBQUk9KRVRPL0dFVEVEL01hdHJpY3VsYXMgcG9yIHNpdHVhw6fDo28sMjAwN2EyMDIyLmNzdiIpDQpNYXRyaWN1bGFzX3Bvcl9zaXR1YcOnw6NvXzIwMDdhMjAyMiROT19FVEFQQV9BR1JFR0FEQSAlPiUgdW5pcXVlDQphPC1NYXRyaWN1bGFzX3Bvcl9zaXR1YcOnw6NvXzIwMDdhMjAyMiAlPiUgZmlsdGVyKE5VX0FOT19DRU5TTz09MjAyMikgJT4lIGZpbHRlcihUUF9ERVBFTkRFTkNJQT09MikgJT4lIA0KICBncm91cF9ieShOT19TSVRVQUNBTyxUUF9TRVhPLE5PX0VUQVBBX0FHUkVHQURBKSAlPiUNCiAgc3VtbWFyaXNlKG49c3VtKG4pKSAlPiUgc3ByZWFkKE5PX1NJVFVBQ0FPLG4sZmlsbCA9IDApICU+JSBtdXRhdGUodG90YWw9QWJhbmRvbm8rQXByb3ZhZG8rRmFsZWNpZG8rUmVwcm92YWRvK1NJUiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQWJhbmRvbm9fcGVyPUFiYW5kb25vL3RvdGFsKQ0KYSAlPiUgbXV0YXRlKEFiYW5kb25vX3BlcjI9aWZfZWxzZShUUF9TRVhPPT0xLEFiYW5kb25vX3BlciwtQWJhbmRvbm9fcGVyKSkgJT4lIGZpbHRlcighQWJhbmRvbm89PTApICU+JSANCiAgZ2dwbG90KGFlcyhOT19FVEFQQV9BR1JFR0FEQSxBYmFuZG9ub19wZXIyLGZpbGw9YXMuZmFjdG9yKFRQX1NFWE8pKSkrZ2VvbV9jb2woYWxwaGE9MC4zKSsNCiAgZ2VvbV90ZXh0KHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAxKSxhZXMobGFiZWw9cGFzdGUocm91bmQoQWJhbmRvbm9fcGVyKjEwMCwyKSwiJSIpLGNvbD1hcy5mYWN0b3IoVFBfU0VYTykpKSsNCiAgY29vcmRfZmxpcCgpKw0KICBsYWJzKHRpdGxlID0gIkFiYW5kb25vIHBvciBNb2RhbGlkYWRlIGUgU2V4byIsc3VidGl0bGUgPSAiTWF0cmljdWxhcyBhYmFuZG9uYWRhcyBzw7MgZW0gMjAyMiIpDQoNCmBgYA0KDQpgYGB7cn0NCiNNYXRyaWN1bGEgUG9yIHNpdHVhw6fDo28NCmxpYnJhcnkocmVhZHIpDQpNYXRyaWN1bGFzX3Bvcl9zaXR1YcOnw6NvXzIwMDdhMjAyMiROT19FVEFQQV9BR1JFR0FEQSAlPiUgdW5pcXVlDQphPC1NYXRyaWN1bGFzX3Bvcl9zaXR1YcOnw6NvXzIwMDdhMjAyMiAlPiUgZmlsdGVyKE5VX0FOT19DRU5TTz09MjAyMikgJT4lIGZpbHRlcihUUF9ERVBFTkRFTkNJQT09MikgJT4lIA0KICBncm91cF9ieShOT19TSVRVQUNBTyxOT19FVEFQQV9BR1JFR0FEQSxUUF9DT1JfUkFDQSkgJT4lDQogIHN1bW1hcmlzZShuPXN1bShuKSkgJT4lIHNwcmVhZChOT19TSVRVQUNBTyxuLGZpbGwgPSAwKSAlPiUgbXV0YXRlKHRvdGFsPUFiYW5kb25vK0Fwcm92YWRvK0ZhbGVjaWRvK1JlcHJvdmFkbytTSVIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFiYW5kb25vX3Blcj1BYmFuZG9uby90b3RhbCkNCg0KYSAlPiUgI211dGF0ZShBYmFuZG9ub19wZXIyPWlmX2Vsc2UoVFBfQ09SX1JBQ0E9PTEsQWJhbmRvbm9fcGVyLC1BYmFuZG9ub19wZXIpKSAlPiUgZmlsdGVyKCFBYmFuZG9ubz09MCkgJT4lIA0KICBnZ3Bsb3QoYWVzKGFzLmZhY3RvcihUUF9DT1JfUkFDQSksQWJhbmRvbm9fcGVyLGZpbGw9YXMuZmFjdG9yKFRQX0NPUl9SQUNBKSkpK2dlb21fY29sKGFscGhhPTAuMykrDQogIGdlb21fdGV4dChwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMSksDQogICAgICAgICAgICBhZXMobGFiZWw9cGFzdGUocm91bmQoQWJhbmRvbm9fcGVyKjEwMCwyKSwiJSIpLA0KICAgICAgICAgICAgICAgIGNvbD1hcy5mYWN0b3IoVFBfQ09SX1JBQ0EpKSkrDQogICNjb29yZF9mbGlwKCkrDQogIGZhY2V0X3dyYXAofk5PX0VUQVBBX0FHUkVHQURBLHNjYWxlcyA9ICJmcmVlIikNCiAgbGFicyh0aXRsZSA9ICJBYmFuZG9ubyBwb3IgTW9kYWxpZGFkZSBlIFNleG8iLHN1YnRpdGxlID0gIk1hdHJpY3VsYXMgYWJhbmRvbmFkYXMgc8OzIGVtIDIwMjIiKQ0KDQpgYGANCg0KDQoNClNlcmllIEhpc3TDs3JpY2ENCmBgYHtyfQ0KTWF0cmljdWxhc19wb3Jfc2l0dWHDp8Ojb18yMDA3YTIwMjIkTk9fU0lUVUFDQU8gJT4lIHVuaXF1ZSgpDQphPC1NYXRyaWN1bGFzX3Bvcl9zaXR1YcOnw6NvXzIwMDdhMjAyMiAlPiUgZ3JvdXBfYnkoTlVfQU5PX0NFTlNPLE5PX1NJVFVBQ0FPLE5PX0VUQVBBX0FHUkVHQURBKSAlPiVmaWx0ZXIoVFBfREVQRU5ERU5DSUE9PTIpICU+JSANCiAgc3VtbWFyaXNlKG49c3VtKG4pKSAlPiUgc3ByZWFkKE5PX1NJVFVBQ0FPLG4sZmlsbCA9IDApICU+JSBtdXRhdGUodG90YWw9QWJhbmRvbm8rQXByb3ZhZG8rRmFsZWNpZG8rUmVwcm92YWRvK1NJUiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQWJhbmRvbm9fcGVyPUFiYW5kb25vL3RvdGFsKQ0KYSAlPiUjIG11dGF0ZShBYmFuZG9ub19wZXIyPWlmX2Vsc2UoVFBfU0VYTz09MSxBYmFuZG9ub19wZXIsLUFiYW5kb25vX3BlcikpICU+JSANCiAgZ2dwbG90KGFlcyhOVV9BTk9fQ0VOU08sQWJhbmRvbm9fcGVyLGNvbD1OT19FVEFQQV9BR1JFR0FEQSkpK2dlb21fbGluZShhbHBoYT0wLjUpK2dlb21fdGV4dChwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMSksYWVzKGxhYmVsPXBhc3RlKHJvdW5kKEFiYW5kb25vX3BlcioxMDAsMiksIiUiKSkpKyBsYWJzKHRpdGxlID0gIkFiYW5kb25vIHBvciBNb2RhbGlkYWRlIGUgU2V4byIpKw0KICBmYWNldF9ncmlkKE5PX0VUQVBBX0FHUkVHQURBfjEsc2NhbGVzID0gImZyZWUiKSsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmBgYA0KDQotICAgQWx1bm9zIG7Do28gRW5jb250cmFkb3MgXCpwZWRpciBwYXJhIE5ldnRvbg0KDQotICAgQWJhbmRvbm8gXCpWZXIgVFMgQWx1bm8NCg0KLSAgIEVWQVPDg08gXCo/Pw0K