Programa de Pós-Graduação em Ciência da Computação da Universidade
Federal de Campina Grande (PPGCC/UFCG)
Carregamento dos dados
Carregando dados sobre o clima de CG e JP. Serão usados dados do
INMET, agregados por semana. Os dados originais vêm do Banco de Dados
Meteorológicos para Ensino e Pesquisa (BDMEP) que tem como objetivo
apoiar as atividades de ensino e pesquisa e outras aplicações em
meteorologia, hidrologia, recursos hídricos, saúde pública, meio
ambiente, etc.
OBS: É válido salientar que este é um estudo feito com base em
informações sobre apenas temperatura e quantidade de chuvas. Portanto,
as análises realizadas não podem ser consideradas como afirmações
categóricas universais, e sim, como apontamentos baseados nos dados de
entrada utilizados.
climas = read_csv(here::here("data/clima_cg_jp-semanal.csv"),
col_types = "cTdddddd")
glimpse(climas)
Rows: 2,748
Columns: 8
$ cidade <chr> "Campina Grande", "Campina Grande", "Campina Grande", "Campina Grande", "Campina Grande", "Campina Gr…
$ semana <dttm> 1992-12-27, 1993-01-03, 1993-01-10, 1993-01-31, 1993-02-07, 1993-02-14, 1993-02-21, 1993-02-28, 1993…
$ tmedia <dbl> 26.13333, 26.11905, 25.76667, 25.74000, 26.31429, 26.28571, 26.47143, 26.56667, 25.76667, 25.22857, 2…
$ tmax <dbl> 30.4, 32.4, 32.2, 32.0, 32.7, 32.7, 32.3, 32.3, 32.1, 31.2, 32.2, 31.7, 32.7, 31.5, 31.9, 32.4, 32.6,…
$ tmin <dbl> 20.7, 19.3, 19.7, 19.9, 19.6, 20.0, 20.4, 21.2, 19.0, 19.0, 19.3, 19.9, 19.9, 20.0, 20.0, 20.0, 20.2,…
$ chuva <dbl> 0.0, 0.0, 0.0, 0.4, 0.3, 0.0, 4.9, 0.0, 0.0, 6.1, 0.4, 1.2, 0.0, 1.6, 0.0, 1.8, 0.8, 8.3, 2.4, 6.2, 1…
$ mes <dbl> 12, 1, 1, 1, 2, 2, 2, 2, 10, 11, 11, 11, 11, 12, 12, 12, 12, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4…
$ ano <dbl> 1992, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,…
climas = climas %>%
#mutate(temp_anterior = lag(temp_media, n = 1))
mutate(temp_anterior = lag(tmedia, n = 1))
Alterando a tabela adicionando uma coluna com a temperatura da semana
anterior em cada linha.
paged_table(climas)
É importante salientar que a base de dados utilizada mostra uma
variação de dados ao longo de meses iniciando em 1987 e finalizando em
2019. Porém, é possível verificar que existem meses e/ou anos onde há
ausências nas medições em ambas as cidades investigadas. Isto pode gerar
uma influência negativa na análise geral, uma vez que comparar um ano
com dados referente a 12 meses com outro(s) com uma quantidade inferior
a isto tornará a análise enviesada e, portanto, implicar em resultados,
interpretações errôneas e ameaçar a validade da pesquisa. Logo, é
necessário descobrir em quais anos as informações estão incompletas para
que sejam descartadas.
Verificando os dados sobre CG:
cg = climas %>%
filter(cidade == "Campina Grande")
meses_por_anoCG <- aggregate(cg$mes, by = list(cg$ano), FUN = function(x) length(unique(x)))
names(meses_por_anoCG) <- c("ano", "meses_com_dados")
meses_por_anoCG$meses_faltantes <- 12 - meses_por_anoCG$meses_com_dados
paged_table(meses_por_anoCG)
Pode-se verificar que os dados para Campina Grande iniciam em 1992 e
terminam em 2019, porém, os anos de 1992 a 1994, 2000, 2001 e 2019 estão
incompletos. Portanto, serão descartados da análise.
Verificando os dados sobre JP:
jp = climas %>%
filter(cidade == "João Pessoa")
meses_por_anoJP <- aggregate(jp$mes, by = list(jp$ano), FUN = function(x) length(unique(x)))
names(meses_por_anoJP) <- c("ano", "meses_com_dados")
meses_por_anoJP$meses_faltantes <- 12 - meses_por_anoJP$meses_com_dados
paged_table(meses_por_anoJP)
Pode-se verificar que os dados para João Pessoa iniciam em 1987 e
terminam em 2019, porém, os anos de 1987 a 1990, 1994 e 2019 estão
incompletos. Portanto, serão descartados da análise.
Logo, os anos válidos para a investigação estão compreendidos entre
1995 a 2018, com exceção de 2000 e 2001, uma vez que contêm dados sobre
os 12 meses de cada ano para ambas as cidades.
Recriando a tabela ‘climas’ com o conjunto válido de dados:
climas = climas %>%
filter(ano > 1994 & ano < 2019 & ano != 2000 & ano != 2001)
cg = climas %>%
filter(cidade == "Campina Grande")
jp = climas %>%
filter(cidade == "João Pessoa")
paged_table(climas)
Questões
Q1: Qual a cidade é mais quente? Isso muda se considerarmos apenas o
período de janeiro e fevereiro (pico do verão)?
- Investigando a cidade mais quente:
Observando o comportamento da temperatura nas duas cidades:
- Plotando histograma, gráfico de densidade, bloxplot e apresentando
sumários sobre a temperatura média das duas
cidades
# histograma
hist_temperaturaCG = cg %>%
ggplot(aes(x = tmedia)) +
geom_histogram(binwidth = .5, color = "#FCC8C5", fill = "#FCC8C5") +
labs(x = "Temperatura Média (ºC)", y = "Frequência")
hist_temperaturaJP = jp %>%
ggplot(aes(x = tmedia)) +
geom_histogram(binwidth = .5, color = "#99E5E7", fill = "#99E5E7") +
labs(x = "Temperatura Média (ºC)", y = "Frequência")
grid.arrange(hist_temperaturaCG, hist_temperaturaJP, ncol = 2)

# densidade
dens_temperaturaCG = cg %>%
ggplot(aes(x = tmedia)) +
geom_density(fill = "#FCC8C5") +
labs(x = "Temperatura Média (ºC)", y = "Densidade")
dens_temperaturaJP = jp %>%
ggplot(aes(x = tmedia)) +
geom_density(fill = "#99E5E7") +
labs(x = "Temperatura Média (ºC)", y = "Densidade")
grid.arrange(dens_temperaturaCG, dens_temperaturaJP, ncol = 2)

# boxplot
box_temperaturaCG = cg %>%
ggplot(aes(x = cidade, y = tmedia)) +
geom_boxplot(coef = 1000, width = .2, fill = "#FCC8C5") +
labs(x = "Cidade", y = "Temperatura Média (ºC)")
box_temperaturaJP = jp %>%
ggplot(aes(x = cidade, y = tmedia)) +
geom_boxplot(coef = 1000, width = .2, fill = "#99E5E7") +
labs(x = "Cidade", y = "Temperatura Média (ºC)")
grid.arrange(box_temperaturaCG, box_temperaturaJP, ncol = 2)

Histograma: É mostrado que existe uma frequência maior de
temperaturas médias para Campina Grande entre 25ºC e 26C. Já para João
Pessoa, entre 28ºC e 29ºC. Em ambas, existe uma tendência de suas
temperaturas mais frequentes serem menores que os respectivos valores
apontados como mais frequentes.
Densidade: Confirma a informação mostrada no histograma.
Boxplot: Para Campina Grande, 75% das medições para a temperatura
média estão abaixo de 25,82ºC. Para João Pessoa, 75% das medições para a
temperatura média estão abaixo de 28,64ºC.
Sumário para temperatura média de Campina Grande:
summary(cg$tmedia)
Min. 1st Qu. Median Mean 3rd Qu. Max.
20.77 23.36 24.91 24.62 25.82 28.15
Para Campina Grande, há uma variação de temperaturas médias de 20ºC a
28ºC, aproximadamente, com mediana e média em aproximadamente 25ºC.
Sumário para temperatura média de João Pessoa:
summary(jp$tmedia)
Min. 1st Qu. Median Mean 3rd Qu. Max.
23.99 26.85 27.91 27.73 28.64 30.11
Para João Pessoa, há uma variação de temperaturas médias de 24ºC a
30ºC, aproximadamente, com mediana e média em aproximadamente 28ºC.
Isto indica que Campina Grande tem uma temperatura
média mais frequentemente menor que João
Pessoa.
- Plotando bloxplot e apresentando sumários sobre a
temperatura mínima das duas cidades
# boxplot
box_temperaturaMinCG = cg %>%
ggplot(aes(x = cidade, y = tmin)) +
geom_boxplot(coef = 1000, width = .2, fill = "#FCC8C5") +
labs(x = "Cidade", y = "Temperatura Mínima (ºC)")
box_temperaturaMinJP = jp %>%
ggplot(aes(x = cidade, y = tmin)) +
geom_boxplot(coef = 1000, width = .2, fill = "#99E5E7") +
labs(x = "Cidade", y = "Temperatura Mínima (ºC)")
grid.arrange(box_temperaturaMinCG, box_temperaturaMinJP, ncol = 2)

Sumário para temperatura mínima de Campina Grande:
summary(cg$tmin)
Min. 1st Qu. Median Mean 3rd Qu. Max.
15.30 18.20 19.50 19.27 20.30 22.60
Para Campina Grande, há uma variação de temperaturas mínimas de 15ºC
a 23ºC, aproximadamente, com mediana e média em aproximadamente 19,5ºC.
Ainda, 75% dos valores estão abaixo de 20,3ºC.
Sumário para temperatura mínima de João Pessoa:
summary(jp$tmin)
Min. 1st Qu. Median Mean 3rd Qu. Max.
15.60 21.40 22.70 22.58 23.70 26.70
Para João Pessoa, há uma variação de temperaturas mínimas de 15ºC a
26ºC, aproximadamente, com mediana e média em aproximadamente 22,5ºC.
Ainda, 75% dos valores estão abaixo de 23,7ºC.
Isto indica que Campina Grande tem uma temperatura
mínima mais frequentemente menor que João
Pessoa.
- Plotando bloxplot e apresentando sumários sobre a
temperatura máxima das duas cidades
# boxplot
box_temperaturaMaxCG = cg %>%
ggplot(aes(x = cidade, y = tmax)) +
geom_boxplot(coef = 1000, width = .2, fill = "#FCC8C5") +
labs(x = "Cidade", y = "Temperatura Máxima (ºC)")
box_temperaturaMaxJP = jp %>%
ggplot(aes(x = cidade, y = tmax)) +
geom_boxplot(coef = 1000, width = .2, fill = "#99E5E7") +
labs(x = "Cidade", y = "Temperatura Máxima (ºC)")
grid.arrange(box_temperaturaMaxCG, box_temperaturaMaxJP, ncol = 2)

Sumário para temperatura máxima de Campina Grande:
summary(cg$tmax)
Min. 1st Qu. Median Mean 3rd Qu. Max.
25.00 28.60 30.50 30.24 31.90 34.60
Para Campina Grande, há uma variação de temperaturas máximas de 25ºC
a 35ºC, aproximadamente, com mediana e média em aproximadamente 30,5ºC.
Ainda, 75% dos valores estão abaixo de 31,9ºC.
Sumário para temperatura máxima de João Pessoa:
summary(jp$tmax)
Min. 1st Qu. Median Mean 3rd Qu. Max.
27.20 30.00 30.80 30.83 31.60 33.70
Para Campina Grande, há uma variação de temperaturas mínimas de 27ºC
a 34ºC, aproximadamente, com mediana e média em aproximadamente 31,8ºC.
Ainda, 75% dos valores estão abaixo de 31,6ºC.
Isto indica que para temperaturas máximas Campina
Grande e João Pessoa são praticamente equivalentes, com
a primeira tendo uma maior variação de valores para esta medição.
Agora, mostrando informações sobre temperatura de ambas as cidades
anualmente. A temperatura média é o resultado da média entre os valores
calculados para a temperatura média por ano. O pico de temperatura
mínima é o mínimo do conjunto de valores calculados para a temperatura
mínima. Já o pico de temperatura máxima é o máximo do conjunto de
valores calculados para a temperatura máxima.
- Gráfico de Linhas para a média da temperatura média anual
line_pico = pico %>%
group_by(cidade, ano) %>%
summarise(tmediaAno = round(mean(tmedia),2),
tminAno = min(tmin),
tmaxAno = max(tmax),
.groups = "drop")
line_pico %>%
ggplot(aes(x = ano, y = tmediaAno, color = cidade)) +
geom_point() +
geom_line() +
geom_text(aes(label = tmediaAno), hjust = 0.5, vjust = -1, size = 3, angle = 90) +
labs(y = "Temperatura Média (ºC)")

João Pessoa demonstra ter uma temperatura média anual
MAIOR que Campina Grande em todos os anos investigados. A
diferença de temperatura entre ambas chegou a 4ºC em alguns anos.
- Gráfico de Linhas para o pico da temperatura mínima anual
line_pico %>%
ggplot(aes(x = ano, y = tminAno, color = cidade)) +
geom_point() +
geom_line() +
geom_text(aes(label = tminAno), hjust = 0.5, vjust = -1, size = 3, angle = 90) +
labs(y = "Pico de Temperatura Mínima (ºC)")

João Pessoa demonstra ter uma temperatura mínima anual
MAIOR que Campina Grande em todos os anos investigados. A
diferença de temperatura entre ambas chegou a 5ºC em alguns anos.
- Gráfico de Linhas para o pico da temperatura máxima anual
line_pico %>%
ggplot(aes(x = ano, y = tmaxAno, color = cidade)) +
geom_point() +
geom_line() +
geom_text(aes(label = tmaxAno), hjust = 0.5, vjust = -1, size = 3, angle = 90) +
labs(y = "Pico de Temperatura Máxima (ºC)")

Campina Grande demonstra ter uma temperatura máxima anual
MAIOR que João Pessoa entre 1995 e 2015, ano a partir do qual
passa a ser MENOR. É válido destacar que a diferença de temperatura não
ultrapassou 2ºC em nenhum dos anos.
RESPOSTA:
De forma geral, Campina Grande tem uma maior variação de temperatura
ao longo do dia do que João Pessoa, mas esta permanece o dia com
temperaturas mais elevadas que aquela, o que torna João Pessoa
uma cidade mais quente.
Analisando ano por ano, Campina Grande demonstrou ter em relação a
João Pessoa: (i) temperatura média menor, com cerca de 4ºC a
menos em alguns anos; (ii) ter temperatura mínima menor, com
cerca de 5ºC a menos em alguns anos; e (iii) ter * temperatura máxima
maior*, com cerca de apenas 2ºC a mais em alguns anos. Isto confirma
João Pessoa como uma cidade mais quente do que Campina
Grande.
- Investigando o Pico de Verão (Janeiro e Fevereiro):
Considerando apenas os meses de Janeiro e Fevereiro para a análise a
seguir:
pico = climas %>%
filter(mes == 1 | mes == 2)
picoCG = cg %>%
filter(mes == 1 | mes == 2)
picoJP = jp %>%
filter(mes == 1 | mes == 2)
- Visualizando os boxplots da temperatura média para
cada cidade referentes a todos os meses de Janeiro e Fevereiro.
# boxplot
box_picoVeraoCG = picoCG %>%
ggplot(aes(x = cidade, y = tmedia)) +
geom_boxplot(coef = 1000, width = .2, fill = "#FCC8C5") +
labs(x = "Cidade", y = "Temperatura Média (ºC)")
box_picoVeraoJP = picoJP %>%
ggplot(aes(x = cidade, y = tmedia)) +
geom_boxplot(coef = 1000, width = .2, fill = "#99E5E7") +
labs(x = "Cidade", y = "Temperatura Média (ºC)")
grid.arrange(box_picoVeraoCG, box_picoVeraoJP, ncol = 2)

Sumário da temperatura média para os meses de Janeiro e Fevereiro de
Campina Grande
summary(picoCG$tmedia)
Min. 1st Qu. Median Mean 3rd Qu. Max.
22.98 25.26 25.92 25.83 26.54 27.97
Para Campina Grande, há uma variação de temperaturas médias de 23ºC a
28ºC, aproximadamente, com mediana e média em aproximadamente 26ºC.
Ainda, 75% dos valores estão abaixo de 26,54ºC.
Sumário da temperatura média para os meses de Janeiro e Fevereiro de
João Pessoa
summary(picoJP$tmedia)
Min. 1st Qu. Median Mean 3rd Qu. Max.
26.61 28.37 28.76 28.69 29.11 30.09
Para João Pessoa, há uma variação de temperaturas médias de 26ºC a
30ºC, aproximadamente, com mediana e média em aproximadamente 29ºC.
Ainda, 75% dos valores estão abaixo de 29,11ºC.
Isto indica que Campina Grande tem uma temperatura
média mais frequentemente menor que João
Pessoa.
- Visualizando os boxplots da temperatura mínima para
cada cidade referentes a todos os meses de Janeiro e Fevereiro.
box_picoVeraoMinCG = picoCG %>%
ggplot(aes(x = cidade, y = tmin)) +
geom_boxplot(coef = 1000, width = .2, fill = "#FCC8C5") +
labs(x = "Cidade", y = "Temperatura Mínima (ºC)")
box_picoVeraoMinJP = picoJP %>%
ggplot(aes(x = cidade, y = tmin)) +
geom_boxplot(coef = 1000, width = .2, fill = "#99E5E7") +
labs(x = "Cidade", y = "Temperatura Mínima (ºC)")
grid.arrange(box_picoVeraoMinCG, box_picoVeraoMinJP, ncol = 2)

Sumário da temperatura mínima para os meses de Janeiro e Fevereiro de
Campina Grande
summary(picoCG$tmin)
Min. 1st Qu. Median Mean 3rd Qu. Max.
18.10 20.10 20.40 20.46 21.00 22.50
Para Campina Grande, há uma variação de temperaturas mínimas de 18ºC
a 22,5ºC, aproximadamente, com mediana e média em aproximadamente
20,4ºC. Ainda, 75% dos valores estão abaixo de 21ºC.
Sumário da temperatura mínima para os meses de Janeiro e Fevereiro de
João Pessoa
summary(picoJP$tmin)
Min. 1st Qu. Median Mean 3rd Qu. Max.
20.90 22.93 23.70 23.60 24.27 26.70
Para João Pessoa, há uma variação de temperaturas mínimas de 21ºC a
27ºC, aproximadamente, com mediana e média em aproximadamente 23,7ºC.
Ainda, 75% dos valores estão abaixo de 24,27ºC.
Isto indica que Campina Grande tem uma temperatura
mínima mais frequentemente menor que João
Pessoa.
- Visualizando os boxplots da temperatura máxima para
cada cidade referentes a todos os meses de Janeiro e Fevereiro.
box_picoVeraoMaxCG = picoCG %>%
ggplot(aes(x = cidade, y = tmax)) +
geom_boxplot(coef = 1000, width = .2, fill = "#FCC8C5") +
labs(x = "Cidade", y = "Temperatura Máxima (ºC)")
box_picoVeraoMaxJP = picoJP %>%
ggplot(aes(x = cidade, y = tmax)) +
geom_boxplot(coef = 1000, width = .2, fill = "#99E5E7") +
labs(x = "Cidade", y = "Temperatura Máxima (ºC)")
grid.arrange(box_picoVeraoMaxCG, box_picoVeraoMaxJP, ncol = 2)

Sumário da temperatura máxima para os meses de Janeiro e Fevereiro de
Campina Grande
summary(picoCG$tmax)
Min. 1st Qu. Median Mean 3rd Qu. Max.
28.40 31.07 32.00 31.83 32.70 34.20
Para Campina Grande, há uma variação de temperaturas máximas de 28ºC
a 34ºC, aproximadamente, com mediana e média em aproximadamente 32ºC.
Ainda, 75% dos valores estão abaixo de 32,7ºC.
Sumário da temperatura máxima para os meses de Janeiro e Fevereiro de
João Pessoa
summary(picoJP$tmax)
Min. 1st Qu. Median Mean 3rd Qu. Max.
29.90 31.20 31.60 31.62 32.00 33.70
Para João Pessoa, há uma variação de temperaturas máximas de 30ºC a
34ºC, aproximadamente, com mediana e média em aproximadamente 31,6ºC.
Ainda, 75% dos valores estão abaixo de 32ºC.
Isto indica que para temperaturas máximas Campina Grande e João
Pessoa são praticamente equivalentes, com a primeira tendo uma maior
variação de valores para esta medição.
Agora, mostrando informações sobre temperatura de ambas as cidades
anualmente. A temperatura média é o resultado da média entre os valores
calculados para a temperatura média por ano. O pico de temperatura
mínima é o mínimo do conjunto de valores calculados para a temperatura
mínima. Já o pico de temperatura máxima é o máximo do conjunto de
valores calculados para a temperatura máxima.
- Gráfico de Linhas para a média da temperatura média referente ao
pico do verão por ano
line_pico = pico %>%
group_by(cidade, ano) %>%
summarise(tmediaAno = round(mean(tmedia),2),
tminAno = min(tmin),
tmaxAno = max(tmax),
.groups = "drop")
line_pico %>%
ggplot(aes(x = ano, y = tmediaAno, color = cidade)) +
geom_point() +
geom_line() +
geom_text(aes(label = tmediaAno), hjust = 0.5, vjust = -1, size = 3, angle = 90) +
labs(x = "Ano", y = "Temperatura Média (ºC)")

João Pessoa demonstra ter uma temperatura média anual
MAIOR que Campina Grande em todos os anos investigados. A
diferença de temperatura entre ambas chegou a 4ºC em alguns anos.
- Gráfico de Linhas para o mínimo da temperatura mínima referente ao
pico do verão por ano
line_pico %>%
ggplot(aes(x = ano, y = tminAno, color = cidade)) +
geom_point() +
geom_line() +
geom_text(aes(label = tminAno), hjust = 0.5, vjust = -1, size = 3, angle = 90) +
labs(x = "Ano", y = "Temperatura Mínima (ºC)")

João Pessoa demonstra ter uma temperatura mínima anual
MAIOR que Campina Grande em todos os anos investigados. A
diferença de temperatura entre ambas chegou a 5ºC em alguns anos.
- Gráfico de Linhas para o máximo da temperatura máxima referente ao
pico do verão por ano
line_pico %>%
ggplot(aes(x = ano, y = tmaxAno, color = cidade)) +
geom_point() +
geom_line() +
geom_text(aes(label = tmaxAno), hjust = 0.5, vjust = -1, size = 3, angle = 90) +
labs(x = "Ano", y = "Temperatura Máxima (ºC)")

Campina Grande demonstra ter uma temperatura máxima anual MAIOR que
João Pessoa entre 1995 e 2015, ano a partir do qual passa a ser menor. É
válido destacar que a diferença de temperatura não ultrapassou 2ºC em
nenhum dos anos.
RESPOSTA:
De forma geral, Campina Grande tem uma maior variação de temperatura
ao longo do dia do que João Pessoa, mas esta permanece o dia com
temperaturas mais elevadas que aquela, o que torna João Pessoa
uma cidade mais quente também no Pico do Verão.
Analisando ano por ano, Campina Grande demonstrou ter em relação a
João Pessoa: (i) temperatura média menor, com cerca de 4ºC a
menos em alguns anos; (ii) ter temperatura mínima menor, com
cerca de 5ºC a menos em alguns anos; e (iii) ter * temperatura máxima
maior*, com cerca de apenas 2ºC a mais em alguns anos. Isto confirma
João Pessoa como uma cidade mais quente do que Campina
Grande também no Pico do Verão.
Por fim, foi percebido que existe comportamento idêntico na variação
de temperaturas entre as duas cidades, identificado tanto de forma geral
e anualmente, como considerando apenas o pico do verão (janeiro e
fevereiro) de maneira geral e por ano também. Logo, João Pessoa é mais
quente do que Campina Grande tanto no pico do verão quanto no ano todo
desde 1995, exceto nos anos de 2000 e 2001 em razão da falta de dados
sobre estes respectivos anos.
Q2: Quais os meses mais quentes e mais frios? Como você descreveria
a temperatura das festas juninas das cidades nos últimos anos?
- Investigando a temperatura em diferentes meses do ano
- Gráfico de Linhas para a média da temperatura média mensal
line_temperaturaMes = climas %>%
group_by(cidade, mes) %>%
summarise(tmediaMes = round(mean(tmedia),2),
tmaxMes = max(tmax),
tminMes = min(tmin),
.groups = "drop")
line_temperaturaMes %>%
ggplot(aes(x = mes, y = tmediaMes, color = cidade)) +
geom_point() +
geom_line() +
geom_text(aes(label = tmediaMes), hjust = 0.5, vjust = -1, size = 3, angle = 90) +
scale_x_continuous("Mês", breaks = 1:12) +
labs(y = "Temperatura Média (ºC)")

João Pessoa demonstra ter uma temperatura média mensal
MAIOR que Campina Grande em todos os meses investigados. A
diferença de temperatura manteve um padrão de cerca de 3ºC ao longo dos
meses. Na média, março é o mês mais quente e julho é o mês mais frio
para as duas cidades.
- Gráfico de Linhas para o máximo de temperatura máxima mensal
line_temperaturaMes %>%
ggplot(aes(x = mes, y = tmaxMes, color = cidade)) +
geom_point() +
geom_line() +
geom_text(aes(label = tmaxMes), hjust = 0.5, vjust = -1, size = 3, angle = 90) +
scale_x_continuous("Mês", breaks = 1:12) +
labs(y = "Temperatura Máxima (ºC)")

Campina Grande demonstra ter uma temperatura máxima mensal
MAIOR que Campina Grande na maioria dos meses investigados, com
exceção dos meses de Maio e Junho onde foi MENOR. A diferença de
temperatura foi bastante variada ao longo dos meses.
Para João Pessoa, o pico de temperatura máxima foi identificado nos
meses de janeiro e março. Para Campina Grande, o pico de temperatura
máxima foi identificado no mês março.
- Gráfico de Linhas para o mínimo de temperatura mínima mensal
line_temperaturaMes %>%
ggplot(aes(x = mes, y = tminMes, color = cidade)) +
geom_point() +
geom_line() +
geom_text(aes(label = tminMes), hjust = 0.5, vjust = -1, size = 3, angle = 90) +
scale_x_continuous("Mês", breaks = 1:12) +
labs(y = "Temperatura Mínima (ºC)")

João Pessoa demonstra ter uma temperatura mínima mensal
MAIOR que Campina Grande em todos os meses investigados. A
diferença de temperatura entre ambas chegou a 3ºC em alguns meses.
Para João Pessoa, a menor temperatura mínima foi identificada no mês
de agosto. Para Campina Grande, as menores temperaturas mínimas foram
identificadas nos meses de julho e agosto.
RESPOSTA:
Ao longo dos meses do ano, João Pessoa é mais quente do que Campina
Grande. Entretanto, no mês de junho, Campina Grande obtém temperaturas
menores do que João Pessoa tanto para a média, quanto para a mínima e
máxima. Logo, Campina Grande costuma estar mais fria no mês de
junho.
Na média, março é o mês mais quente e julho é o mês mais frio para as
duas cidades. As menores temperaturas estão nos meses de julho, somente
para Campina Grande, e em agosto, para ambas as cidades. Já as maiores
temperaturas estão nos meses de janeiro, apenas para Campina Grande, e
em março, para as duas cidades.
- Investigando a temperatura durante as festas juninas (mês de junho)
dos últimos 10 anos: Entre 2008 e 2018
Repetindo o processo anterior feito para a análise de temperaturas
mensais, agora considerando apenas o mês de Junho e os anos
compreendidos entre 2008 e 2018 (os últimos 10 anos da base de
dados).
temperaturaJunho = climas %>%
filter(mes == 6 & ano > 2007)
temperaturaJunho = temperaturaJunho %>%
group_by(cidade, ano) %>%
summarise(tmediaAno6 = round(mean(tmedia),2),
tmaxAno6 = max(tmax),
tmedmaxAno6 = round(mean(tmax),2),
tminAno6 = min(tmin),
tmedminAno6 = round(mean(tmin),2),
.groups = "drop")
temperaturaJunho %>%
ggplot(aes(x = ano, y = tmediaAno6, color = cidade)) +
geom_point() +
geom_line() +
geom_text(aes(label = tmediaAno6), hjust = 0.5, vjust = -1, size = 3, angle = 90) +
scale_x_continuous("Anos", breaks = 2008:2018) +
labs(x = "Ano", y = "Temperatura Média de Junho (ºC)")

temperaturaJunho %>%
ggplot(aes(x = ano, y = tmaxAno6, color = cidade)) +
geom_point() +
geom_line() +
geom_text(aes(label = tmaxAno6), hjust = 0.5, vjust = -1, size = 3, angle = 90) +
scale_x_continuous("Anos", breaks = 2008:2018) +
labs(x = "Ano", y = "Temperatura Máxima de Junho (ºC)")

temperaturaJunho %>%
ggplot(aes(x = ano, y = tmedmaxAno6, color = cidade)) +
geom_point() +
geom_line() +
geom_text(aes(label = tmedmaxAno6), hjust = 0.5, vjust = -1, size = 3, angle = 90) +
scale_x_continuous("Anos", breaks = 2008:2018) +
labs(x = "Ano", y = "Média da Temperatura Máxima de Junho (ºC)")

temperaturaJunho %>%
ggplot(aes(x = ano, y = tminAno6, color = cidade)) +
geom_point() +
geom_line() +
geom_text(aes(label = tminAno6), hjust = 0.5, vjust = -1, size = 3, angle = 90) +
scale_x_continuous("Anos", breaks = 2008:2018) +
labs(x = "Ano", y = "Temperatura Mínima de Junho (ºC)")

temperaturaJunho %>%
ggplot(aes(x = ano, y = tmedminAno6, color = cidade)) +
geom_point() +
geom_line() +
geom_text(aes(label = tmedminAno6), hjust = 0.5, vjust = -1, size = 3, angle = 90) +
scale_x_continuous(breaks = 2008:2018) +
labs(x = "Ano", y = "Média da Temperatura Mínima de Junho (ºC)")

RESPOSTA:
Considerando os últimos 10 anos da base de dados, anos compreendidos
entre 2008 e 2018, pode-se apontar que Campina Grande permaneceu mais
fria do que João Pessoa no mês de junho, com uma diferença de cerca de
4ºC vários anos.
Campina Grande ser mais fria que João Pessoa no mês de junho é válido
tanto para as medições de temperaturas mínimas e máximas quanto para as
médias das temperaturas mínima, média e máxima.
Q3: Quanto chove por semana em JP e CG? Descreva a distribuição do
volume de chuvas para as cidades?
Observando o comportamento das chuvas nas duas cidades:
- Plotando histograma, gráfico de densidade, bloxplot e apresentando
sumários sobre o índice de chuvas das duas cidades
hist_chuvasCG = cg %>%
ggplot(aes(x = chuva)) +
geom_histogram(binwidth = 10, color = "#FCC8C5", fill = "#FCC8C5") +
labs(x = "Índice de Chuvas (mm)", y = "Frequência")
hist_chuvasJP = jp %>%
ggplot(aes(x = chuva)) +
geom_histogram(binwidth = 10, color = "#99E5E7", fill = "#99E5E7") +
labs(x = "Índice de Chuvas (mm)", y = "Frequência")
grid.arrange(hist_chuvasCG, hist_chuvasJP, ncol = 2)

dens_chuvasCG = cg %>%
ggplot(aes(x = chuva)) +
geom_density(fill = "#FCC8C5") +
labs(x = "Índice de Chuvas (mm)", y = "Densidade")
dens_chuvasJP = jp %>%
ggplot(aes(x = chuva)) +
geom_density(fill = "#99E5E7") +
labs(x = "Índice de Chuvas (mm)", y = "Densidade")
grid.arrange(dens_chuvasCG, dens_chuvasJP, ncol = 2)

box_chuvasCG = cg %>%
ggplot(aes(x = cidade, y = chuva)) +
geom_boxplot(coef = 1000, width = .2, fill = "#FCC8C5") +
labs(x = "Cidade", y = "Índice de Chuvas (mm)")
box_chuvasJP = jp %>%
ggplot(aes(x = cidade, y = chuva)) +
geom_boxplot(coef = 1000, width = .2, fill = "#99E5E7") +
labs(x = "Cidade", y = "Índice de Chuvas (mm)")
grid.arrange(box_chuvasCG, box_chuvasJP, ncol = 2)

Histograma: É mostrado que existe uma frequência maior de chuvas
abaixo de 50mm para Campina Grande e de 100mm para João Pessoa. A maior
chuva para a Campina Grande não passou de 200mm, enquanto que João
Pessoa teve algumas chuvas maiores do que 200mm chegando a ultrapassar
350mm de chuva. É válido destacar que estas medições indicão valores
semanais.
Densidade: Confirma a informação mostrada no histograma.
Boxplot: Para Campina Grande, 75% dos índices semanais de chuva
estão abaixo de 25mm. Para João Pessoa, 75% das medições para chuvas
estão abaixo de 50mm. Além disso, ambas possuem índices de chuva muito
maiores do que as suas respectivas medianas.
summary(cg$chuva)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.00 0.40 5.05 14.22 19.05 191.90
Para Campina Grande, há uma variação de chuvas de 0mm a 192mm,
aproximadamente, com mediana equivalente a 5,05mm e média igual 14,22mm.
A diferença entre o 3º quartil e o valor máximo é muito grande,
mostrando uma distribuição irregular dos dados. Os valores de média e
mediana não são bem representativos.
summary(jp$chuva)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.00 3.00 14.50 33.59 47.12 351.60
Para João Pessoa, há uma variação de chuvas de 0mm a 352mm,
aproximadamente, com mediana equivalente a 14,5mm e média igual 33,59mm.
A diferença entre o 3º quartil e o valor máximo é muito grande (maior
ainda do que para Campina Grande), mostrando uma distribuição ainda mais
irregular dos dados. Os valores de média e mediana não são bem
representativos.
RESPOSTA:
Para Campina Grande, 75% dos índices semanais de chuva estão abaixo
de 25mm. Para João Pessoa, 75% das medições para chuvas estão abaixo de
50mm. Além disso, ambas possuem índices de chuva muito maiores do que as
suas respectivas medianas. Isto é, existe uma distribuição muito
irregular de chuvas, de maneira geral. A diferença entre o 3º quartil e
o valor máximo é muito grande (maior ainda em João Pessoa), mostrando
distribuições irregulares dos dados. Os valores de média e mediana não
são bem representativos.
Q4: Qual a relação entre a temperatura de uma semana e a temperatura
da semana anterior (descreva para as duas cidades)?
Visualizando graficamente os dados sobre temperaturas médias e sua
semana imediatamente anterior para verificar a possibilidade de
correlação.
- Gráfico de Pontos de Temperatura Média X Temperatura Média da Semana
Anterior
relacaoTemperatura = climas
relacaoTemperatura %>%
ggplot(aes(x = tmedia, y = temp_anterior, color = cidade)) +
geom_quasirandom(alpha = .5, size = 1) +
labs(x = "Temperatura Média (ºC)", y = "Temperatura Média da Semana Anterior (ºC)")

Visualmente, nota-se que existe uma relação linear entre a
temperatura média e a temperatura média da sua semana imediatamente
anterior, tanto para Campina Grande, quanto para João Pessoa. Isto
significa que a temperatura média de uma semana específica foi
semelhante à temperatura média de sua semana imediatamente anterior.
Para valores menores de temperaturas, Campina Grande destaca-se mais,
ao passo que para maiores temperaturas, João Pessoa destaca-se mais.
Verificando os valores de correlação para os coeficientes de
pearson, spearman e kendall para as duas
cidades.
correlacaoTemperaturaCG = cg
correlacaoTemperaturaCG %>%
summarise(pearson = cor(tmedia, temp_anterior, method = "pearson"),
spearman = cor(tmedia, temp_anterior, method = "spearman"),
kendall = cor(tmedia, temp_anterior, method = "kendall"))
Para Campina Grande, todos os três coeficientes calculados apontaram
uma correlação positiva alta entre a temperatura média e a temperatura
média de sua semana imediatamente anterior.
correlacaoTemperaturaJP = jp
correlacaoTemperaturaJP %>%
summarise(pearson = cor(tmedia, temp_anterior, method = "pearson"),
spearman = cor(tmedia, temp_anterior, method = "spearman"),
kendall = cor(tmedia, temp_anterior, method = "kendall"))
Para João Pessoa, todos os três coeficientes calculados apontaram uma
correlação positiva alta entre a temperatura média e a temperatura média
de sua semana imediatamente anterior.
Agora, verificando o sumário entre as temperaturas para as duas
cidades.
relacaoTemperaturaCG = cg
summary(relacaoTemperaturaCG$tmedia, relacaoTemperaturaCG$temp_anterior)
Min. 1st Qu. Median Mean 3rd Qu. Max.
20.77 23.36 24.91 24.62 25.82 28.15
Para Campina Grande, a média e a mediana obtiveram valores muito
próximos e não estão distantes dos seus pontos máximo e mínimo, o que
mostra uma distribuição regular dos dados.
relacaoTemperaturaJP = jp
summary(relacaoTemperaturaJP$tmedia, relacaoTemperaturaJP$temp_anterior)
Min. 1st Qu. Median Mean 3rd Qu. Max.
23.99 26.85 27.91 27.73 28.64 30.11
Para João Pessoa, a média e a mediana obtiveram valores muito
próximos e não estão distantes dos seus pontos máximo e mínimo, o que
mostra uma distribuição regular dos dados.
RESPOSTA:
Pode-se perceber que existe uma relação linear e de alta correlação
entre a temperatura média e a temperatura média da sua semana
imediatamente anterior, tanto para Campina Grande, quanto para João
Pessoa. Isto significa que a temperatura média de uma semana específica
foi semelhante à temperatura média de sua semana imediatamente
anterior.
A diferença está nos valores das temperaturas, onde Campina Grande
apresenta valores mais baixos do que João Pessoa. Contudo, ambas possuem
um comportamento semelhante para as temperaturas médias e as
temperaturas médias da semana imediatamente anterior.
Q5: Qual a relação entre temperatura e chuvas nas semanas em que
choveu (descreva para as duas cidades)?
Visualizando graficamente os dados sobre temperaturas médias e chuvas
para verificar a possibilidade de correlação.
- Gráfico de Pontos de Temperatura Média X Índice de Chuvas
relacaoTemperaturaChuva = climas
relacaoTemperaturaChuva %>%
ggplot(aes(x = tmedia, y = chuva, color = cidade)) +
geom_quasirandom(alpha = .5, size = 1) +
labs(x = "Temperatura Média (ºC)", y = "Índice de Chuvas (mm)")

Não é possível observar visualmente alguma correlação entre
temperatura média e índice de chuvas em nenhuma das cidades. O que pode
ser visto é apenas que para valores menores de temperaturas, Campina
Grande destaca-se mais, ao passo que para maiores temperaturas, João
Pessoa destaca-se mais.
Verificando os valores de correlação para os coeficientes de
pearson, spearman e kendall para as duas
cidades.
correlacaoTemperaturaChuvasCG = cg
correlacaoTemperaturaChuvasCG %>%
summarise(pearson = cor(tmedia, chuva, method = "pearson"),
spearman = cor(tmedia, chuva, method = "spearman"),
kendall = cor(tmedia, chuva, method = "kendall"))
Para Campina Grande, os coeficientes calculados apontaram uma
correlação negativa fraca (pearson e kendall) e
negativa moderada (spearman) entre a temperatura média e o
índice de chuvas.
correlacaoTemperaturaChuvasJP = jp
correlacaoTemperaturaChuvasJP %>%
summarise(pearson = cor(tmedia, chuva, method = "pearson"),
spearman = cor(tmedia, chuva, method = "spearman"),
kendall = cor(tmedia, chuva, method = "kendall"))
Para Campina Grande, todos os três coeficientes calculados apontaram
uma correlação negativa fraca entre a temperatura média e o índice de
chuvas.
Agora, verificando o sumário entre as temperaturas e os índices de
chuvas para as duas cidades.
relacaoTemperaturaChuvaCG = cg
summary(relacaoTemperaturaChuvaCG$chuva, relacaoTemperaturaChuvaCG$tmedia)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.00 0.40 5.05 14.22 19.05 191.90
Para Campina Grande, a média e a mediana obtiveram valores não
próximos, não estão próximas do valor mínimo e estão muito distantes do
seu ponto máximo, o que mostra uma distribuição irregular dos dados.
relacaoTemperaturaChuvaJP = jp
summary(relacaoTemperaturaChuvaJP$chuva, relacaoTemperaturaChuvaJP$tmedia)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.00 3.00 14.50 33.59 47.12 351.60
Para João Pessoa, a média e a mediana obtiveram valores não próximos,
não estão próximas do valor mínimo e estão muito distantes do seu ponto
máximo, o que mostra uma distribuição irregular dos dados. Neste caso, a
irregularidade é ainda maior que em Campina Grande.
RESPOSTA:
Não é possível observar alguma correlação entre temperatura média e
índice de chuvas em nenhuma das cidades. O que pode ser visto é apenas
que para valores menores de temperaturas, Campina Grande destaca-se
mais, ao passo que para maiores temperaturas, João Pessoa destaca-se
mais.
Os coeficientes de pearson, spearman e
kendall apontaram uma correlação negativa fraca entre
temperatura média e índice de chuvas para as duas cidades, no geral.
Além disso, a variação de dados mostra irregularidade também nas duas
cidades.
Logo, não é possível afirmar que existe correlação entre temperatura
média e índice de chuvas para as cidades de Campina Grande e João
Pessoa. Por exemplo, pode chover em dias quentes e frios e também pode
não chover em dias quentes e frios. Isto dificulta a identificação de
uma relação entre a temperatura média e o índice de chuvas.
LS0tDQp0aXRsZTogIkVzdHVkbyBzb2JyZSBjbGltYTogQ0cgeCBKUCINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNClByb2dyYW1hIGRlIFDDs3MtR3JhZHVhw6fDo28gZW0gQ2nDqm5jaWEgZGEgQ29tcHV0YcOnw6NvIGRhIFVuaXZlcnNpZGFkZSBGZWRlcmFsIGRlIENhbXBpbmEgR3JhbmRlIChQUEdDQy9VRkNHKQ0KDQpEaXNjaXBsaW5hOiBGdW5kYW1lbnRvcyBkZSBQZXNxdWlzYSBlbSBDacOqbmNpYSBkYSBDb21wdXRhw6fDo28gSUkgKEZQQ0MgSUkpDQoNClByb2Zlc3NvcjogRsOhYmlvIEpvcmdlIEFsbWVpZGEgTW9yYWlzDQoNCkFsdW5vOiBGZWxpcGUgVG9ycmVzIExlaXRlDQoNClRhcmVmYTogW0xhYm9yYXTDs3JpbyAyOiBDYW1waW5hIEdyYW5kZSBYIEpvw6NvIFBlc3NvYV0oaHR0cHM6Ly9naXRodWIuY29tL2ZwY2MyLTIwMjMtMS9mcGNjMi1sYWIyLU1yRmVsaXBlVG9ycmVzKQ0KDQpEYXRhOiAwOC8wNS8yMDIzDQoNCiMjIENhcnJlZ2FtZW50byBkb3MgZGFkb3MNCg0KQ2FycmVnYW5kbyBkYWRvcyBzb2JyZSBvIGNsaW1hIGRlIENHIGUgSlAuIFNlcsOjbyB1c2Fkb3MgZGFkb3MgZG8gSU5NRVQsIGFncmVnYWRvcyBwb3Igc2VtYW5hLiBPcyBkYWRvcyBvcmlnaW5haXMgdsOqbSBkbyBCYW5jbyBkZSBEYWRvcyBNZXRlb3JvbMOzZ2ljb3MgcGFyYSBFbnNpbm8gZSBQZXNxdWlzYSAoQkRNRVApIHF1ZSB0ZW0gY29tbyBvYmpldGl2byBhcG9pYXIgYXMgYXRpdmlkYWRlcyBkZSBlbnNpbm8gZSBwZXNxdWlzYSBlIG91dHJhcyBhcGxpY2HDp8O1ZXMgZW0gbWV0ZW9yb2xvZ2lhLCBoaWRyb2xvZ2lhLCByZWN1cnNvcyBow61kcmljb3MsIHNhw7pkZSBww7pibGljYSwgbWVpbyBhbWJpZW50ZSwgZXRjLg0KDQoqT0JTOiDDiSB2w6FsaWRvIHNhbGllbnRhciBxdWUgZXN0ZSDDqSB1bSBlc3R1ZG8gZmVpdG8gY29tIGJhc2UgZW0gaW5mb3JtYcOnw7VlcyBzb2JyZSBhcGVuYXMgdGVtcGVyYXR1cmEgZSBxdWFudGlkYWRlIGRlIGNodXZhcy4gUG9ydGFudG8sIGFzIGFuw6FsaXNlcyByZWFsaXphZGFzIG7Do28gcG9kZW0gc2VyIGNvbnNpZGVyYWRhcyBjb21vIGFmaXJtYcOnw7VlcyBjYXRlZ8OzcmljYXMgdW5pdmVyc2FpcywgZSBzaW0sIGNvbW8gYXBvbnRhbWVudG9zIGJhc2VhZG9zIG5vcyBkYWRvcyBkZSBlbnRyYWRhIHV0aWxpemFkb3MuKg0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGhlcmUpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkoZ2diZWVzd2FybSkNCmxpYnJhcnkoZ3JpZEV4dHJhKQ0KbGlicmFyeShybWFya2Rvd24pDQp0aGVtZV9zZXQodGhlbWVfYncoKSkNCmBgYA0KDQpgYGB7cn0NCmNsaW1hcyA9IHJlYWRfY3N2KGhlcmU6OmhlcmUoImRhdGEvY2xpbWFfY2dfanAtc2VtYW5hbC5jc3YiKSwgDQogICAgICAgICAgICAgICAgICBjb2xfdHlwZXMgPSAiY1RkZGRkZGQiKQ0KDQpnbGltcHNlKGNsaW1hcykNCmBgYA0KDQpgYGB7ciByZWFkfQ0KY2xpbWFzID0gY2xpbWFzICU+JSANCiAgI211dGF0ZSh0ZW1wX2FudGVyaW9yID0gbGFnKHRlbXBfbWVkaWEsIG4gPSAxKSkNCiAgIG11dGF0ZSh0ZW1wX2FudGVyaW9yID0gbGFnKHRtZWRpYSwgbiA9IDEpKSANCmBgYA0KDQpBbHRlcmFuZG8gYSB0YWJlbGEgYWRpY2lvbmFuZG8gdW1hIGNvbHVuYSBjb20gYSB0ZW1wZXJhdHVyYSBkYSBzZW1hbmEgYW50ZXJpb3IgZW0gY2FkYSBsaW5oYS4NCg0KYGBge3J9DQpwYWdlZF90YWJsZShjbGltYXMpDQpgYGANCg0Kw4kgaW1wb3J0YW50ZSBzYWxpZW50YXIgcXVlIGEgYmFzZSBkZSBkYWRvcyB1dGlsaXphZGEgbW9zdHJhIHVtYSB2YXJpYcOnw6NvIGRlIGRhZG9zIGFvIGxvbmdvIGRlIG1lc2VzIGluaWNpYW5kbyBlbSAxOTg3IGUgZmluYWxpemFuZG8gZW0gMjAxOS4gUG9yw6ltLCDDqSBwb3Nzw612ZWwgdmVyaWZpY2FyIHF1ZSBleGlzdGVtIG1lc2VzIGUvb3UgYW5vcyBvbmRlIGjDoSBhdXPDqm5jaWFzIG5hcyBtZWRpw6fDtWVzIGVtIGFtYmFzIGFzIGNpZGFkZXMgaW52ZXN0aWdhZGFzLiBJc3RvIHBvZGUgZ2VyYXIgdW1hIGluZmx1w6puY2lhIG5lZ2F0aXZhIG5hIGFuw6FsaXNlIGdlcmFsLCB1bWEgdmV6IHF1ZSBjb21wYXJhciB1bSBhbm8gY29tIGRhZG9zIHJlZmVyZW50ZSBhIDEyIG1lc2VzIGNvbSBvdXRybyhzKSBjb20gdW1hIHF1YW50aWRhZGUgaW5mZXJpb3IgYSBpc3RvIHRvcm5hcsOhIGEgYW7DoWxpc2UgZW52aWVzYWRhIGUsIHBvcnRhbnRvLCBpbXBsaWNhciBlbSByZXN1bHRhZG9zLCBpbnRlcnByZXRhw6fDtWVzIGVycsO0bmVhcyBlIGFtZWHDp2FyIGEgdmFsaWRhZGUgZGEgcGVzcXVpc2EuIExvZ28sIMOpIG5lY2Vzc8OhcmlvIGRlc2NvYnJpciBlbSBxdWFpcyBhbm9zIGFzIGluZm9ybWHDp8O1ZXMgZXN0w6NvIGluY29tcGxldGFzIHBhcmEgcXVlIHNlamFtIGRlc2NhcnRhZGFzLg0KDQpWZXJpZmljYW5kbyBvcyBkYWRvcyBzb2JyZSBDRzoNCg0KYGBge3J9DQpjZyA9IGNsaW1hcyAlPiUgDQogICAgZmlsdGVyKGNpZGFkZSA9PSAiQ2FtcGluYSBHcmFuZGUiKSANCg0KbWVzZXNfcG9yX2Fub0NHIDwtIGFnZ3JlZ2F0ZShjZyRtZXMsIGJ5ID0gbGlzdChjZyRhbm8pLCBGVU4gPSBmdW5jdGlvbih4KSBsZW5ndGgodW5pcXVlKHgpKSkNCm5hbWVzKG1lc2VzX3Bvcl9hbm9DRykgPC0gYygiYW5vIiwgIm1lc2VzX2NvbV9kYWRvcyIpDQptZXNlc19wb3JfYW5vQ0ckbWVzZXNfZmFsdGFudGVzIDwtIDEyIC0gbWVzZXNfcG9yX2Fub0NHJG1lc2VzX2NvbV9kYWRvcw0KDQpwYWdlZF90YWJsZShtZXNlc19wb3JfYW5vQ0cpDQpgYGANCg0KUG9kZS1zZSB2ZXJpZmljYXIgcXVlIG9zIGRhZG9zIHBhcmEgQ2FtcGluYSBHcmFuZGUgaW5pY2lhbSBlbSAxOTkyIGUgdGVybWluYW0gZW0gMjAxOSwgcG9yw6ltLCBvcyBhbm9zIGRlIDE5OTIgYSAxOTk0LCAyMDAwLCAyMDAxIGUgMjAxOSBlc3TDo28gaW5jb21wbGV0b3MuIFBvcnRhbnRvLCBzZXLDo28gZGVzY2FydGFkb3MgZGEgYW7DoWxpc2UuDQoNClZlcmlmaWNhbmRvIG9zIGRhZG9zIHNvYnJlIEpQOg0KDQpgYGB7cn0NCmpwID0gY2xpbWFzICU+JSANCiAgICBmaWx0ZXIoY2lkYWRlID09ICJKb8OjbyBQZXNzb2EiKQ0KDQptZXNlc19wb3JfYW5vSlAgPC0gYWdncmVnYXRlKGpwJG1lcywgYnkgPSBsaXN0KGpwJGFubyksIEZVTiA9IGZ1bmN0aW9uKHgpIGxlbmd0aCh1bmlxdWUoeCkpKQ0KbmFtZXMobWVzZXNfcG9yX2Fub0pQKSA8LSBjKCJhbm8iLCAibWVzZXNfY29tX2RhZG9zIikNCm1lc2VzX3Bvcl9hbm9KUCRtZXNlc19mYWx0YW50ZXMgPC0gMTIgLSBtZXNlc19wb3JfYW5vSlAkbWVzZXNfY29tX2RhZG9zDQoNCnBhZ2VkX3RhYmxlKG1lc2VzX3Bvcl9hbm9KUCkNCmBgYA0KDQpQb2RlLXNlIHZlcmlmaWNhciBxdWUgb3MgZGFkb3MgcGFyYSBKb8OjbyBQZXNzb2EgaW5pY2lhbSBlbSAxOTg3IGUgdGVybWluYW0gZW0gMjAxOSwgcG9yw6ltLCBvcyBhbm9zIGRlIDE5ODcgYSAxOTkwLCAxOTk0IGUgMjAxOSBlc3TDo28gaW5jb21wbGV0b3MuIFBvcnRhbnRvLCBzZXLDo28gZGVzY2FydGFkb3MgZGEgYW7DoWxpc2UuDQoNCkxvZ28sIG9zIGFub3MgdsOhbGlkb3MgcGFyYSBhIGludmVzdGlnYcOnw6NvIGVzdMOjbyBjb21wcmVlbmRpZG9zIGVudHJlIDE5OTUgYSAyMDE4LCBjb20gZXhjZcOnw6NvIGRlIDIwMDAgZSAyMDAxLCB1bWEgdmV6IHF1ZSBjb250w6ptIGRhZG9zIHNvYnJlIG9zIDEyIG1lc2VzIGRlIGNhZGEgYW5vIHBhcmEgYW1iYXMgYXMgY2lkYWRlcy4NCg0KUmVjcmlhbmRvIGEgdGFiZWxhICdjbGltYXMnIGNvbSBvIGNvbmp1bnRvIHbDoWxpZG8gZGUgZGFkb3M6DQoNCmBgYHtyfQ0KY2xpbWFzID0gY2xpbWFzICU+JSANCiAgICBmaWx0ZXIoYW5vID4gMTk5NCAmIGFubyA8IDIwMTkgJiBhbm8gIT0gMjAwMCAmIGFubyAhPSAyMDAxKQ0KDQpjZyA9IGNsaW1hcyAlPiUgDQogICAgZmlsdGVyKGNpZGFkZSA9PSAiQ2FtcGluYSBHcmFuZGUiKQ0KDQpqcCA9IGNsaW1hcyAlPiUgDQogICAgZmlsdGVyKGNpZGFkZSA9PSAiSm/Do28gUGVzc29hIikNCg0KcGFnZWRfdGFibGUoY2xpbWFzKQ0KYGBgDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyBRdWVzdMO1ZXMNCg0KIyMjIFExOiBRdWFsIGEgY2lkYWRlIMOpIG1haXMgcXVlbnRlPyBJc3NvIG11ZGEgc2UgY29uc2lkZXJhcm1vcyBhcGVuYXMgbyBwZXLDrW9kbyBkZSBqYW5laXJvIGUgZmV2ZXJlaXJvIChwaWNvIGRvIHZlcsOjbyk/DQoNCi0gICBJbnZlc3RpZ2FuZG8gYSBjaWRhZGUgbWFpcyBxdWVudGU6DQoNCk9ic2VydmFuZG8gbyBjb21wb3J0YW1lbnRvIGRhIHRlbXBlcmF0dXJhIG5hcyBkdWFzIGNpZGFkZXM6DQoNCjEuICBQbG90YW5kbyBoaXN0b2dyYW1hLCBncsOhZmljbyBkZSBkZW5zaWRhZGUsIGJsb3hwbG90IGUgYXByZXNlbnRhbmRvIHN1bcOhcmlvcyBzb2JyZSBhICoqdGVtcGVyYXR1cmEgbcOpZGlhKiogZGFzIGR1YXMgY2lkYWRlcw0KDQpgYGB7cn0NCiMgaGlzdG9ncmFtYQ0KaGlzdF90ZW1wZXJhdHVyYUNHID0gY2cgJT4lIA0KICAgIGdncGxvdChhZXMoeCA9IHRtZWRpYSkpICsNCiAgICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IC41LCBjb2xvciA9ICIjRkNDOEM1IiwgZmlsbCA9ICIjRkNDOEM1IikgKw0KICAgIGxhYnMoeCA9ICJUZW1wZXJhdHVyYSBNw6lkaWEgKMK6QykiLCB5ID0gIkZyZXF1w6puY2lhIikgDQoNCmhpc3RfdGVtcGVyYXR1cmFKUCA9IGpwICU+JSANCiAgICBnZ3Bsb3QoYWVzKHggPSB0bWVkaWEpKSArIA0KICAgIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gLjUsIGNvbG9yID0gIiM5OUU1RTciLCBmaWxsID0gIiM5OUU1RTciKSArDQogICAgbGFicyh4ID0gIlRlbXBlcmF0dXJhIE3DqWRpYSAowrpDKSIsIHkgPSAiRnJlcXXDqm5jaWEiKQ0KDQpncmlkLmFycmFuZ2UoaGlzdF90ZW1wZXJhdHVyYUNHLCBoaXN0X3RlbXBlcmF0dXJhSlAsIG5jb2wgPSAyKQ0KDQojIGRlbnNpZGFkZQ0KZGVuc190ZW1wZXJhdHVyYUNHID0gY2cgJT4lIA0KICAgIGdncGxvdChhZXMoeCA9IHRtZWRpYSkpICsgDQogICAgZ2VvbV9kZW5zaXR5KGZpbGwgPSAiI0ZDQzhDNSIpICsNCiAgICBsYWJzKHggPSAiVGVtcGVyYXR1cmEgTcOpZGlhICjCukMpIiwgeSA9ICJEZW5zaWRhZGUiKSAgDQoNCmRlbnNfdGVtcGVyYXR1cmFKUCA9IGpwICU+JSANCiAgICBnZ3Bsb3QoYWVzKHggPSB0bWVkaWEpKSArIA0KICAgIGdlb21fZGVuc2l0eShmaWxsID0gIiM5OUU1RTciKSArDQogICAgbGFicyh4ID0gIlRlbXBlcmF0dXJhIE3DqWRpYSAowrpDKSIsIHkgPSAiRGVuc2lkYWRlIikgDQoNCmdyaWQuYXJyYW5nZShkZW5zX3RlbXBlcmF0dXJhQ0csIGRlbnNfdGVtcGVyYXR1cmFKUCwgbmNvbCA9IDIpDQoNCiMgYm94cGxvdA0KYm94X3RlbXBlcmF0dXJhQ0cgPSBjZyAlPiUgDQogICAgZ2dwbG90KGFlcyh4ID0gY2lkYWRlLCB5ID0gdG1lZGlhKSkgKyANCiAgICBnZW9tX2JveHBsb3QoY29lZiA9IDEwMDAsIHdpZHRoID0gLjIsIGZpbGwgPSAiI0ZDQzhDNSIpICsNCiAgICBsYWJzKHggPSAiQ2lkYWRlIiwgeSA9ICJUZW1wZXJhdHVyYSBNw6lkaWEgKMK6QykiKQ0KDQpib3hfdGVtcGVyYXR1cmFKUCA9IGpwICU+JSANCiAgICBnZ3Bsb3QoYWVzKHggPSBjaWRhZGUsIHkgPSB0bWVkaWEpKSArIA0KICAgIGdlb21fYm94cGxvdChjb2VmID0gMTAwMCwgd2lkdGggPSAuMiwgZmlsbCA9ICIjOTlFNUU3IikgKw0KICAgIGxhYnMoeCA9ICJDaWRhZGUiLCB5ID0gIlRlbXBlcmF0dXJhIE3DqWRpYSAowrpDKSIpDQoNCmdyaWQuYXJyYW5nZShib3hfdGVtcGVyYXR1cmFDRywgYm94X3RlbXBlcmF0dXJhSlAsIG5jb2wgPSAyKQ0KYGBgDQoNCi0gSGlzdG9ncmFtYTogw4kgbW9zdHJhZG8gcXVlIGV4aXN0ZSB1bWEgZnJlcXXDqm5jaWEgbWFpb3IgZGUgdGVtcGVyYXR1cmFzIG3DqWRpYXMgcGFyYSBDYW1waW5hIEdyYW5kZSBlbnRyZSAyNcK6QyBlIDI2Qy4gSsOhIHBhcmEgSm/Do28gUGVzc29hLCBlbnRyZSAyOMK6QyBlIDI5wrpDLiBFbSBhbWJhcywgZXhpc3RlIHVtYSB0ZW5kw6puY2lhIGRlIHN1YXMgdGVtcGVyYXR1cmFzIG1haXMgZnJlcXVlbnRlcyBzZXJlbSBtZW5vcmVzIHF1ZSBvcyByZXNwZWN0aXZvcyB2YWxvcmVzIGFwb250YWRvcyBjb21vIG1haXMgZnJlcXVlbnRlcy4NCg0KLSBEZW5zaWRhZGU6IENvbmZpcm1hIGEgaW5mb3JtYcOnw6NvIG1vc3RyYWRhIG5vIGhpc3RvZ3JhbWEuDQoNCi0gQm94cGxvdDogUGFyYSBDYW1waW5hIEdyYW5kZSwgNzUlIGRhcyBtZWRpw6fDtWVzIHBhcmEgYSB0ZW1wZXJhdHVyYSBtw6lkaWEgZXN0w6NvIGFiYWl4byBkZSAyNSw4MsK6Qy4gUGFyYSBKb8OjbyBQZXNzb2EsIDc1JSBkYXMgbWVkacOnw7VlcyBwYXJhIGEgdGVtcGVyYXR1cmEgbcOpZGlhIGVzdMOjbyBhYmFpeG8gZGUgMjgsNjTCukMuDQoNClN1bcOhcmlvIHBhcmEgdGVtcGVyYXR1cmEgbcOpZGlhIGRlIENhbXBpbmEgR3JhbmRlOg0KDQpgYGB7cn0NCnN1bW1hcnkoY2ckdG1lZGlhKQ0KYGBgDQpQYXJhIENhbXBpbmEgR3JhbmRlLCBow6EgdW1hIHZhcmlhw6fDo28gZGUgdGVtcGVyYXR1cmFzIG3DqWRpYXMgZGUgMjDCukMgYSAyOMK6QywgYXByb3hpbWFkYW1lbnRlLCBjb20gbWVkaWFuYSBlIG3DqWRpYSBlbSBhcHJveGltYWRhbWVudGUgMjXCukMuDQoNClN1bcOhcmlvIHBhcmEgdGVtcGVyYXR1cmEgbcOpZGlhIGRlIEpvw6NvIFBlc3NvYToNCg0KYGBge3J9DQpzdW1tYXJ5KGpwJHRtZWRpYSkNCmBgYA0KUGFyYSBKb8OjbyBQZXNzb2EsIGjDoSB1bWEgdmFyaWHDp8OjbyBkZSB0ZW1wZXJhdHVyYXMgbcOpZGlhcyBkZSAyNMK6QyBhIDMwwrpDLCBhcHJveGltYWRhbWVudGUsIGNvbSBtZWRpYW5hIGUgbcOpZGlhIGVtIGFwcm94aW1hZGFtZW50ZSAyOMK6Qy4NCg0KSXN0byBpbmRpY2EgcXVlIENhbXBpbmEgR3JhbmRlIHRlbSB1bWEgKip0ZW1wZXJhdHVyYSBtw6lkaWEqKiBtYWlzIGZyZXF1ZW50ZW1lbnRlICoqbWVub3IqKiBxdWUgSm/Do28gUGVzc29hLg0KDQoyLiAgUGxvdGFuZG8gYmxveHBsb3QgZSBhcHJlc2VudGFuZG8gc3Vtw6FyaW9zIHNvYnJlIGEgKip0ZW1wZXJhdHVyYSBtw61uaW1hKiogZGFzIGR1YXMgY2lkYWRlcw0KDQpgYGB7cn0NCiMgYm94cGxvdA0KYm94X3RlbXBlcmF0dXJhTWluQ0cgPSBjZyAlPiUgDQogICAgZ2dwbG90KGFlcyh4ID0gY2lkYWRlLCB5ID0gdG1pbikpICsgDQogICAgZ2VvbV9ib3hwbG90KGNvZWYgPSAxMDAwLCB3aWR0aCA9IC4yLCBmaWxsID0gIiNGQ0M4QzUiKSArDQogICAgbGFicyh4ID0gIkNpZGFkZSIsIHkgPSAiVGVtcGVyYXR1cmEgTcOtbmltYSAowrpDKSIpDQoNCmJveF90ZW1wZXJhdHVyYU1pbkpQID0ganAgJT4lIA0KICAgIGdncGxvdChhZXMoeCA9IGNpZGFkZSwgeSA9IHRtaW4pKSArIA0KICAgIGdlb21fYm94cGxvdChjb2VmID0gMTAwMCwgd2lkdGggPSAuMiwgZmlsbCA9ICIjOTlFNUU3IikgKw0KICAgIGxhYnMoeCA9ICJDaWRhZGUiLCB5ID0gIlRlbXBlcmF0dXJhIE3DrW5pbWEgKMK6QykiKQ0KDQpncmlkLmFycmFuZ2UoYm94X3RlbXBlcmF0dXJhTWluQ0csIGJveF90ZW1wZXJhdHVyYU1pbkpQLCBuY29sID0gMikNCmBgYA0KDQpTdW3DoXJpbyBwYXJhIHRlbXBlcmF0dXJhIG3DrW5pbWEgZGUgQ2FtcGluYSBHcmFuZGU6DQoNCmBgYHtyfQ0Kc3VtbWFyeShjZyR0bWluKQ0KYGBgDQoNClBhcmEgQ2FtcGluYSBHcmFuZGUsIGjDoSB1bWEgdmFyaWHDp8OjbyBkZSB0ZW1wZXJhdHVyYXMgbcOtbmltYXMgZGUgMTXCukMgYSAyM8K6QywgYXByb3hpbWFkYW1lbnRlLCBjb20gbWVkaWFuYSBlIG3DqWRpYSBlbSBhcHJveGltYWRhbWVudGUgMTksNcK6Qy4gQWluZGEsIDc1JSBkb3MgdmFsb3JlcyBlc3TDo28gYWJhaXhvIGRlIDIwLDPCukMuDQoNClN1bcOhcmlvIHBhcmEgdGVtcGVyYXR1cmEgbcOtbmltYSBkZSBKb8OjbyBQZXNzb2E6DQoNCmBgYHtyfQ0Kc3VtbWFyeShqcCR0bWluKQ0KYGBgDQoNClBhcmEgSm/Do28gUGVzc29hLCBow6EgdW1hIHZhcmlhw6fDo28gZGUgdGVtcGVyYXR1cmFzIG3DrW5pbWFzIGRlIDE1wrpDIGEgMjbCukMsIGFwcm94aW1hZGFtZW50ZSwgY29tIG1lZGlhbmEgZSBtw6lkaWEgZW0gYXByb3hpbWFkYW1lbnRlIDIyLDXCukMuIEFpbmRhLCA3NSUgZG9zIHZhbG9yZXMgZXN0w6NvIGFiYWl4byBkZSAyMyw3wrpDLg0KDQpJc3RvIGluZGljYSBxdWUgQ2FtcGluYSBHcmFuZGUgdGVtIHVtYSAqKnRlbXBlcmF0dXJhIG3DrW5pbWEqKiBtYWlzIGZyZXF1ZW50ZW1lbnRlICoqbWVub3IqKiBxdWUgSm/Do28gUGVzc29hLg0KDQozLiAgUGxvdGFuZG8gYmxveHBsb3QgZSBhcHJlc2VudGFuZG8gc3Vtw6FyaW9zIHNvYnJlIGEgKip0ZW1wZXJhdHVyYSBtw6F4aW1hKiogZGFzIGR1YXMgY2lkYWRlcw0KDQpgYGB7cn0NCiMgYm94cGxvdA0KYm94X3RlbXBlcmF0dXJhTWF4Q0cgPSBjZyAlPiUgDQogICAgZ2dwbG90KGFlcyh4ID0gY2lkYWRlLCB5ID0gdG1heCkpICsgDQogICAgZ2VvbV9ib3hwbG90KGNvZWYgPSAxMDAwLCB3aWR0aCA9IC4yLCBmaWxsID0gIiNGQ0M4QzUiKSArDQogICAgbGFicyh4ID0gIkNpZGFkZSIsIHkgPSAiVGVtcGVyYXR1cmEgTcOheGltYSAowrpDKSIpDQoNCmJveF90ZW1wZXJhdHVyYU1heEpQID0ganAgJT4lIA0KICAgIGdncGxvdChhZXMoeCA9IGNpZGFkZSwgeSA9IHRtYXgpKSArIA0KICAgIGdlb21fYm94cGxvdChjb2VmID0gMTAwMCwgd2lkdGggPSAuMiwgZmlsbCA9ICIjOTlFNUU3IikgKw0KICAgIGxhYnMoeCA9ICJDaWRhZGUiLCB5ID0gIlRlbXBlcmF0dXJhIE3DoXhpbWEgKMK6QykiKQ0KDQpncmlkLmFycmFuZ2UoYm94X3RlbXBlcmF0dXJhTWF4Q0csIGJveF90ZW1wZXJhdHVyYU1heEpQLCBuY29sID0gMikNCmBgYA0KDQpTdW3DoXJpbyBwYXJhIHRlbXBlcmF0dXJhIG3DoXhpbWEgZGUgQ2FtcGluYSBHcmFuZGU6DQoNCmBgYHtyfQ0Kc3VtbWFyeShjZyR0bWF4KQ0KYGBgDQoNClBhcmEgQ2FtcGluYSBHcmFuZGUsIGjDoSB1bWEgdmFyaWHDp8OjbyBkZSB0ZW1wZXJhdHVyYXMgbcOheGltYXMgZGUgMjXCukMgYSAzNcK6QywgYXByb3hpbWFkYW1lbnRlLCBjb20gbWVkaWFuYSBlIG3DqWRpYSBlbSBhcHJveGltYWRhbWVudGUgMzAsNcK6Qy4gQWluZGEsIDc1JSBkb3MgdmFsb3JlcyBlc3TDo28gYWJhaXhvIGRlIDMxLDnCukMuDQoNClN1bcOhcmlvIHBhcmEgdGVtcGVyYXR1cmEgbcOheGltYSBkZSBKb8OjbyBQZXNzb2E6DQoNCmBgYHtyfQ0Kc3VtbWFyeShqcCR0bWF4KQ0KYGBgDQoNClBhcmEgQ2FtcGluYSBHcmFuZGUsIGjDoSB1bWEgdmFyaWHDp8OjbyBkZSB0ZW1wZXJhdHVyYXMgbcOtbmltYXMgZGUgMjfCukMgYSAzNMK6QywgYXByb3hpbWFkYW1lbnRlLCBjb20gbWVkaWFuYSBlIG3DqWRpYSBlbSBhcHJveGltYWRhbWVudGUgMzEsOMK6Qy4gQWluZGEsIDc1JSBkb3MgdmFsb3JlcyBlc3TDo28gYWJhaXhvIGRlIDMxLDbCukMuDQoNCklzdG8gaW5kaWNhIHF1ZSBwYXJhICoqdGVtcGVyYXR1cmFzIG3DoXhpbWFzKiogQ2FtcGluYSBHcmFuZGUgZSBKb8OjbyBQZXNzb2Egc8OjbyBwcmF0aWNhbWVudGUgKiplcXVpdmFsZW50ZXMqKiwgY29tIGEgcHJpbWVpcmEgdGVuZG8gdW1hIG1haW9yIHZhcmlhw6fDo28gZGUgdmFsb3JlcyBwYXJhIGVzdGEgbWVkacOnw6NvLg0KDQpBZ29yYSwgbW9zdHJhbmRvIGluZm9ybWHDp8O1ZXMgc29icmUgdGVtcGVyYXR1cmEgZGUgYW1iYXMgYXMgY2lkYWRlcyBhbnVhbG1lbnRlLiBBIHRlbXBlcmF0dXJhIG3DqWRpYSDDqSBvIHJlc3VsdGFkbyBkYSBtw6lkaWEgZW50cmUgb3MgdmFsb3JlcyBjYWxjdWxhZG9zIHBhcmEgYSB0ZW1wZXJhdHVyYSBtw6lkaWEgcG9yIGFuby4gTyBwaWNvIGRlIHRlbXBlcmF0dXJhIG3DrW5pbWEgw6kgbyBtw61uaW1vIGRvIGNvbmp1bnRvIGRlIHZhbG9yZXMgY2FsY3VsYWRvcyBwYXJhIGEgdGVtcGVyYXR1cmEgbcOtbmltYS4gSsOhIG8gcGljbyBkZSB0ZW1wZXJhdHVyYSBtw6F4aW1hIMOpIG8gbcOheGltbyBkbyBjb25qdW50byBkZSB2YWxvcmVzIGNhbGN1bGFkb3MgcGFyYSBhIHRlbXBlcmF0dXJhIG3DoXhpbWEuDQoNCjQuICBHcsOhZmljbyBkZSBMaW5oYXMgcGFyYSBhIG3DqWRpYSBkYSB0ZW1wZXJhdHVyYSBtw6lkaWEgYW51YWwNCg0KYGBge3J9DQpsaW5lX3BpY28gPSBwaWNvICU+JSANCiAgICBncm91cF9ieShjaWRhZGUsIGFubykgJT4lDQogICAgc3VtbWFyaXNlKHRtZWRpYUFubyA9IHJvdW5kKG1lYW4odG1lZGlhKSwyKSwNCiAgICAgICAgICAgICAgdG1pbkFubyA9IG1pbih0bWluKSwNCiAgICAgICAgICAgICAgdG1heEFubyA9IG1heCh0bWF4KSwNCiAgICAgICAgICAgICAgLmdyb3VwcyA9ICJkcm9wIikNCg0KbGluZV9waWNvICU+JSANCiAgICBnZ3Bsb3QoYWVzKHggPSBhbm8sIHkgPSB0bWVkaWFBbm8sIGNvbG9yID0gY2lkYWRlKSkgKw0KICAgIGdlb21fcG9pbnQoKSArDQogICAgZ2VvbV9saW5lKCkgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSB0bWVkaWFBbm8pLCBoanVzdCA9IDAuNSwgdmp1c3QgPSAtMSwgc2l6ZSA9IDMsIGFuZ2xlID0gOTApICsNCiAgICBsYWJzKHkgPSAiVGVtcGVyYXR1cmEgTcOpZGlhICjCukMpIikNCmBgYA0KDQpKb8OjbyBQZXNzb2EgZGVtb25zdHJhIHRlciB1bWEgKip0ZW1wZXJhdHVyYSBtw6lkaWEgYW51YWwgTUFJT1IqKiBxdWUgQ2FtcGluYSBHcmFuZGUgZW0gdG9kb3Mgb3MgYW5vcyBpbnZlc3RpZ2Fkb3MuIEEgZGlmZXJlbsOnYSBkZSB0ZW1wZXJhdHVyYSBlbnRyZSBhbWJhcyBjaGVnb3UgYSA0wrpDIGVtIGFsZ3VucyBhbm9zLg0KDQo1LiAgR3LDoWZpY28gZGUgTGluaGFzIHBhcmEgbyBwaWNvIGRhIHRlbXBlcmF0dXJhIG3DrW5pbWEgYW51YWwNCg0KYGBge3J9DQpsaW5lX3BpY28gJT4lIA0KICAgIGdncGxvdChhZXMoeCA9IGFubywgeSA9IHRtaW5Bbm8sIGNvbG9yID0gY2lkYWRlKSkgKw0KICAgIGdlb21fcG9pbnQoKSArDQogICAgZ2VvbV9saW5lKCkgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSB0bWluQW5vKSwgaGp1c3QgPSAwLjUsIHZqdXN0ID0gLTEsIHNpemUgPSAzLCBhbmdsZSA9IDkwKSArDQogICAgbGFicyh5ID0gIlBpY28gZGUgVGVtcGVyYXR1cmEgTcOtbmltYSAowrpDKSIpDQpgYGANCg0KSm/Do28gUGVzc29hIGRlbW9uc3RyYSB0ZXIgdW1hICoqdGVtcGVyYXR1cmEgbcOtbmltYSBhbnVhbCBNQUlPUioqIHF1ZSBDYW1waW5hIEdyYW5kZSBlbSB0b2RvcyBvcyBhbm9zIGludmVzdGlnYWRvcy4gQSBkaWZlcmVuw6dhIGRlIHRlbXBlcmF0dXJhIGVudHJlIGFtYmFzIGNoZWdvdSBhIDXCukMgZW0gYWxndW5zIGFub3MuDQoNCjYuICBHcsOhZmljbyBkZSBMaW5oYXMgcGFyYSBvIHBpY28gZGEgdGVtcGVyYXR1cmEgbcOheGltYSBhbnVhbA0KDQpgYGB7cn0NCmxpbmVfcGljbyAlPiUgDQogICAgZ2dwbG90KGFlcyh4ID0gYW5vLCB5ID0gdG1heEFubywgY29sb3IgPSBjaWRhZGUpKSArDQogICAgZ2VvbV9wb2ludCgpICsNCiAgICBnZW9tX2xpbmUoKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHRtYXhBbm8pLCBoanVzdCA9IDAuNSwgdmp1c3QgPSAtMSwgc2l6ZSA9IDMsIGFuZ2xlID0gOTApICsNCiAgICBsYWJzKHkgPSAiUGljbyBkZSBUZW1wZXJhdHVyYSBNw6F4aW1hICjCukMpIikNCmBgYA0KDQpDYW1waW5hIEdyYW5kZSBkZW1vbnN0cmEgdGVyIHVtYSAqKnRlbXBlcmF0dXJhIG3DoXhpbWEgYW51YWwgTUFJT1IqKiBxdWUgSm/Do28gUGVzc29hIGVudHJlIDE5OTUgZSAyMDE1LCBhbm8gYSBwYXJ0aXIgZG8gcXVhbCBwYXNzYSBhIHNlciBNRU5PUi4gw4kgdsOhbGlkbyBkZXN0YWNhciBxdWUgYSBkaWZlcmVuw6dhIGRlIHRlbXBlcmF0dXJhIG7Do28gdWx0cmFwYXNzb3UgMsK6QyBlbSBuZW5odW0gZG9zIGFub3MuDQoNCioqUkVTUE9TVEE6KioNCg0KRGUgZm9ybWEgZ2VyYWwsIENhbXBpbmEgR3JhbmRlIHRlbSB1bWEgbWFpb3IgdmFyaWHDp8OjbyBkZSB0ZW1wZXJhdHVyYSBhbyBsb25nbyBkbyBkaWEgZG8gcXVlIEpvw6NvIFBlc3NvYSwgbWFzIGVzdGEgcGVybWFuZWNlIG8gZGlhIGNvbSB0ZW1wZXJhdHVyYXMgbWFpcyBlbGV2YWRhcyBxdWUgYXF1ZWxhLCBvIHF1ZSB0b3JuYSAqKkpvw6NvIFBlc3NvYSB1bWEgY2lkYWRlIG1haXMgcXVlbnRlKiouIA0KDQpBbmFsaXNhbmRvIGFubyBwb3IgYW5vLCBDYW1waW5hIEdyYW5kZSBkZW1vbnN0cm91IHRlciBlbSByZWxhw6fDo28gYSBKb8OjbyBQZXNzb2E6IChpKSAqdGVtcGVyYXR1cmEgbcOpZGlhIG1lbm9yKiwgY29tIGNlcmNhIGRlIDTCukMgYSBtZW5vcyBlbSBhbGd1bnMgYW5vczsgKGlpKSB0ZXIgKnRlbXBlcmF0dXJhIG3DrW5pbWEgbWVub3IqLCBjb20gY2VyY2EgZGUgNcK6QyBhIG1lbm9zIGVtIGFsZ3VucyBhbm9zOyBlIChpaWkpIHRlciAqIHRlbXBlcmF0dXJhIG3DoXhpbWEgbWFpb3IqLCBjb20gY2VyY2EgZGUgYXBlbmFzIDLCukMgYSBtYWlzIGVtIGFsZ3VucyBhbm9zLiBJc3RvIGNvbmZpcm1hICoqSm/Do28gUGVzc29hIGNvbW8gdW1hIGNpZGFkZSBtYWlzIHF1ZW50ZSoqIGRvIHF1ZSBDYW1waW5hIEdyYW5kZS4NCg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCi0gICBJbnZlc3RpZ2FuZG8gbyBQaWNvIGRlIFZlcsOjbyAoSmFuZWlybyBlIEZldmVyZWlybyk6DQoNCkNvbnNpZGVyYW5kbyBhcGVuYXMgb3MgbWVzZXMgZGUgSmFuZWlybyBlIEZldmVyZWlybyBwYXJhIGEgYW7DoWxpc2UgYSBzZWd1aXI6DQoNCmBgYHtyfQ0KcGljbyA9IGNsaW1hcyAlPiUgDQogICAgZmlsdGVyKG1lcyA9PSAxIHwgbWVzID09IDIpDQoNCnBpY29DRyA9IGNnICU+JSANCiAgICBmaWx0ZXIobWVzID09IDEgfCBtZXMgPT0gMikNCg0KcGljb0pQID0ganAgJT4lIA0KICAgIGZpbHRlcihtZXMgPT0gMSB8IG1lcyA9PSAyKQ0KYGBgDQoNCjEuIFZpc3VhbGl6YW5kbyBvcyBib3hwbG90cyBkYSAqKnRlbXBlcmF0dXJhIG3DqWRpYSoqIHBhcmEgY2FkYSBjaWRhZGUgcmVmZXJlbnRlcyBhIHRvZG9zIG9zIG1lc2VzIGRlIEphbmVpcm8gZSBGZXZlcmVpcm8uDQoNCmBgYHtyfQ0KIyBib3hwbG90DQpib3hfcGljb1ZlcmFvQ0cgPSBwaWNvQ0cgJT4lIA0KICAgIGdncGxvdChhZXMoeCA9IGNpZGFkZSwgeSA9IHRtZWRpYSkpICsgDQogICAgZ2VvbV9ib3hwbG90KGNvZWYgPSAxMDAwLCB3aWR0aCA9IC4yLCBmaWxsID0gIiNGQ0M4QzUiKSArDQogICAgbGFicyh4ID0gIkNpZGFkZSIsIHkgPSAiVGVtcGVyYXR1cmEgTcOpZGlhICjCukMpIikgDQoNCmJveF9waWNvVmVyYW9KUCA9IHBpY29KUCAlPiUgDQogICAgZ2dwbG90KGFlcyh4ID0gY2lkYWRlLCB5ID0gdG1lZGlhKSkgKyANCiAgICBnZW9tX2JveHBsb3QoY29lZiA9IDEwMDAsIHdpZHRoID0gLjIsIGZpbGwgPSAiIzk5RTVFNyIpICsNCiAgICBsYWJzKHggPSAiQ2lkYWRlIiwgeSA9ICJUZW1wZXJhdHVyYSBNw6lkaWEgKMK6QykiKQ0KDQpncmlkLmFycmFuZ2UoYm94X3BpY29WZXJhb0NHLCBib3hfcGljb1ZlcmFvSlAsIG5jb2wgPSAyKSANCmBgYA0KDQpTdW3DoXJpbyBkYSB0ZW1wZXJhdHVyYSBtw6lkaWEgcGFyYSBvcyBtZXNlcyBkZSBKYW5laXJvIGUgRmV2ZXJlaXJvIGRlIENhbXBpbmEgR3JhbmRlDQoNCmBgYHtyfQ0Kc3VtbWFyeShwaWNvQ0ckdG1lZGlhKQ0KYGBgDQpQYXJhIENhbXBpbmEgR3JhbmRlLCBow6EgdW1hIHZhcmlhw6fDo28gZGUgdGVtcGVyYXR1cmFzIG3DqWRpYXMgZGUgMjPCukMgYSAyOMK6QywgYXByb3hpbWFkYW1lbnRlLCBjb20gbWVkaWFuYSBlIG3DqWRpYSBlbSBhcHJveGltYWRhbWVudGUgMjbCukMuIEFpbmRhLCA3NSUgZG9zIHZhbG9yZXMgZXN0w6NvIGFiYWl4byBkZSAyNiw1NMK6Qy4NCg0KU3Vtw6FyaW8gZGEgdGVtcGVyYXR1cmEgbcOpZGlhIHBhcmEgb3MgbWVzZXMgZGUgSmFuZWlybyBlIEZldmVyZWlybyBkZSBKb8OjbyBQZXNzb2ENCg0KYGBge3J9DQpzdW1tYXJ5KHBpY29KUCR0bWVkaWEpDQpgYGANCg0KUGFyYSBKb8OjbyBQZXNzb2EsIGjDoSB1bWEgdmFyaWHDp8OjbyBkZSB0ZW1wZXJhdHVyYXMgbcOpZGlhcyBkZSAyNsK6QyBhIDMwwrpDLCBhcHJveGltYWRhbWVudGUsIGNvbSBtZWRpYW5hIGUgbcOpZGlhIGVtIGFwcm94aW1hZGFtZW50ZSAyOcK6Qy4gQWluZGEsIDc1JSBkb3MgdmFsb3JlcyBlc3TDo28gYWJhaXhvIGRlIDI5LDExwrpDLg0KDQpJc3RvIGluZGljYSBxdWUgQ2FtcGluYSBHcmFuZGUgdGVtIHVtYSAqKnRlbXBlcmF0dXJhIG3DqWRpYSoqIG1haXMgZnJlcXVlbnRlbWVudGUgKiptZW5vcioqIHF1ZSBKb8OjbyBQZXNzb2EuDQoNCjIuIFZpc3VhbGl6YW5kbyBvcyBib3hwbG90cyBkYSAqKnRlbXBlcmF0dXJhIG3DrW5pbWEqKiBwYXJhIGNhZGEgY2lkYWRlIHJlZmVyZW50ZXMgYSB0b2RvcyBvcyBtZXNlcyBkZSBKYW5laXJvIGUgRmV2ZXJlaXJvLg0KDQpgYGB7cn0NCmJveF9waWNvVmVyYW9NaW5DRyA9IHBpY29DRyAlPiUgDQogICAgZ2dwbG90KGFlcyh4ID0gY2lkYWRlLCB5ID0gdG1pbikpICsgDQogICAgZ2VvbV9ib3hwbG90KGNvZWYgPSAxMDAwLCB3aWR0aCA9IC4yLCBmaWxsID0gIiNGQ0M4QzUiKSArDQogICAgbGFicyh4ID0gIkNpZGFkZSIsIHkgPSAiVGVtcGVyYXR1cmEgTcOtbmltYSAowrpDKSIpIA0KDQpib3hfcGljb1ZlcmFvTWluSlAgPSBwaWNvSlAgJT4lIA0KICAgIGdncGxvdChhZXMoeCA9IGNpZGFkZSwgeSA9IHRtaW4pKSArIA0KICAgIGdlb21fYm94cGxvdChjb2VmID0gMTAwMCwgd2lkdGggPSAuMiwgZmlsbCA9ICIjOTlFNUU3IikgKw0KICAgIGxhYnMoeCA9ICJDaWRhZGUiLCB5ID0gIlRlbXBlcmF0dXJhIE3DrW5pbWEgKMK6QykiKQ0KDQpncmlkLmFycmFuZ2UoYm94X3BpY29WZXJhb01pbkNHLCBib3hfcGljb1ZlcmFvTWluSlAsIG5jb2wgPSAyKQ0KYGBgDQoNClN1bcOhcmlvIGRhIHRlbXBlcmF0dXJhIG3DrW5pbWEgcGFyYSBvcyBtZXNlcyBkZSBKYW5laXJvIGUgRmV2ZXJlaXJvIGRlIENhbXBpbmEgR3JhbmRlDQoNCmBgYHtyfQ0Kc3VtbWFyeShwaWNvQ0ckdG1pbikNCmBgYA0KDQpQYXJhIENhbXBpbmEgR3JhbmRlLCBow6EgdW1hIHZhcmlhw6fDo28gZGUgdGVtcGVyYXR1cmFzIG3DrW5pbWFzIGRlIDE4wrpDIGEgMjIsNcK6QywgYXByb3hpbWFkYW1lbnRlLCBjb20gbWVkaWFuYSBlIG3DqWRpYSBlbSBhcHJveGltYWRhbWVudGUgMjAsNMK6Qy4gQWluZGEsIDc1JSBkb3MgdmFsb3JlcyBlc3TDo28gYWJhaXhvIGRlIDIxwrpDLg0KDQpTdW3DoXJpbyBkYSB0ZW1wZXJhdHVyYSBtw61uaW1hIHBhcmEgb3MgbWVzZXMgZGUgSmFuZWlybyBlIEZldmVyZWlybyBkZSBKb8OjbyBQZXNzb2ENCg0KYGBge3J9DQpzdW1tYXJ5KHBpY29KUCR0bWluKQ0KYGBgDQoNClBhcmEgSm/Do28gUGVzc29hLCBow6EgdW1hIHZhcmlhw6fDo28gZGUgdGVtcGVyYXR1cmFzIG3DrW5pbWFzIGRlIDIxwrpDIGEgMjfCukMsIGFwcm94aW1hZGFtZW50ZSwgY29tIG1lZGlhbmEgZSBtw6lkaWEgZW0gYXByb3hpbWFkYW1lbnRlIDIzLDfCukMuIEFpbmRhLCA3NSUgZG9zIHZhbG9yZXMgZXN0w6NvIGFiYWl4byBkZSAyNCwyN8K6Qy4NCg0KSXN0byBpbmRpY2EgcXVlIENhbXBpbmEgR3JhbmRlIHRlbSB1bWEgKip0ZW1wZXJhdHVyYSBtw61uaW1hKiogbWFpcyBmcmVxdWVudGVtZW50ZSAqKm1lbm9yKiogcXVlIEpvw6NvIFBlc3NvYS4NCg0KMy4gVmlzdWFsaXphbmRvIG9zIGJveHBsb3RzIGRhICoqdGVtcGVyYXR1cmEgbcOheGltYSoqIHBhcmEgY2FkYSBjaWRhZGUgcmVmZXJlbnRlcyBhIHRvZG9zIG9zIG1lc2VzIGRlIEphbmVpcm8gZSBGZXZlcmVpcm8uDQoNCmBgYHtyfQ0KYm94X3BpY29WZXJhb01heENHID0gcGljb0NHICU+JSANCiAgICBnZ3Bsb3QoYWVzKHggPSBjaWRhZGUsIHkgPSB0bWF4KSkgKyANCiAgICBnZW9tX2JveHBsb3QoY29lZiA9IDEwMDAsIHdpZHRoID0gLjIsIGZpbGwgPSAiI0ZDQzhDNSIpICsNCiAgICBsYWJzKHggPSAiQ2lkYWRlIiwgeSA9ICJUZW1wZXJhdHVyYSBNw6F4aW1hICjCukMpIikNCg0KYm94X3BpY29WZXJhb01heEpQID0gcGljb0pQICU+JSANCiAgICBnZ3Bsb3QoYWVzKHggPSBjaWRhZGUsIHkgPSB0bWF4KSkgKyANCiAgICBnZW9tX2JveHBsb3QoY29lZiA9IDEwMDAsIHdpZHRoID0gLjIsIGZpbGwgPSAiIzk5RTVFNyIpICsNCiAgICBsYWJzKHggPSAiQ2lkYWRlIiwgeSA9ICJUZW1wZXJhdHVyYSBNw6F4aW1hICjCukMpIikNCg0KZ3JpZC5hcnJhbmdlKGJveF9waWNvVmVyYW9NYXhDRywgYm94X3BpY29WZXJhb01heEpQLCBuY29sID0gMikNCmBgYA0KDQpTdW3DoXJpbyBkYSB0ZW1wZXJhdHVyYSBtw6F4aW1hIHBhcmEgb3MgbWVzZXMgZGUgSmFuZWlybyBlIEZldmVyZWlybyBkZSBDYW1waW5hIEdyYW5kZQ0KDQpgYGB7cn0NCnN1bW1hcnkocGljb0NHJHRtYXgpDQpgYGANCg0KUGFyYSBDYW1waW5hIEdyYW5kZSwgaMOhIHVtYSB2YXJpYcOnw6NvIGRlIHRlbXBlcmF0dXJhcyBtw6F4aW1hcyBkZSAyOMK6QyBhIDM0wrpDLCBhcHJveGltYWRhbWVudGUsIGNvbSBtZWRpYW5hIGUgbcOpZGlhIGVtIGFwcm94aW1hZGFtZW50ZSAzMsK6Qy4gQWluZGEsIDc1JSBkb3MgdmFsb3JlcyBlc3TDo28gYWJhaXhvIGRlIDMyLDfCukMuDQoNClN1bcOhcmlvIGRhIHRlbXBlcmF0dXJhIG3DoXhpbWEgcGFyYSBvcyBtZXNlcyBkZSBKYW5laXJvIGUgRmV2ZXJlaXJvIGRlIEpvw6NvIFBlc3NvYQ0KDQpgYGB7cn0NCnN1bW1hcnkocGljb0pQJHRtYXgpDQpgYGANCg0KUGFyYSBKb8OjbyBQZXNzb2EsIGjDoSB1bWEgdmFyaWHDp8OjbyBkZSB0ZW1wZXJhdHVyYXMgbcOheGltYXMgZGUgMzDCukMgYSAzNMK6QywgYXByb3hpbWFkYW1lbnRlLCBjb20gbWVkaWFuYSBlIG3DqWRpYSBlbSBhcHJveGltYWRhbWVudGUgMzEsNsK6Qy4gQWluZGEsIDc1JSBkb3MgdmFsb3JlcyBlc3TDo28gYWJhaXhvIGRlIDMywrpDLg0KDQpJc3RvIGluZGljYSBxdWUgcGFyYSB0ZW1wZXJhdHVyYXMgbcOheGltYXMgQ2FtcGluYSBHcmFuZGUgZSBKb8OjbyBQZXNzb2Egc8OjbyBwcmF0aWNhbWVudGUgZXF1aXZhbGVudGVzLCBjb20gYSBwcmltZWlyYSB0ZW5kbyB1bWEgbWFpb3IgdmFyaWHDp8OjbyBkZSB2YWxvcmVzIHBhcmEgZXN0YSBtZWRpw6fDo28uDQoNCkFnb3JhLCBtb3N0cmFuZG8gaW5mb3JtYcOnw7VlcyBzb2JyZSB0ZW1wZXJhdHVyYSBkZSBhbWJhcyBhcyBjaWRhZGVzIGFudWFsbWVudGUuIEEgdGVtcGVyYXR1cmEgbcOpZGlhIMOpIG8gcmVzdWx0YWRvIGRhIG3DqWRpYSBlbnRyZSBvcyB2YWxvcmVzIGNhbGN1bGFkb3MgcGFyYSBhIHRlbXBlcmF0dXJhIG3DqWRpYSBwb3IgYW5vLiBPIHBpY28gZGUgdGVtcGVyYXR1cmEgbcOtbmltYSDDqSBvIG3DrW5pbW8gZG8gY29uanVudG8gZGUgdmFsb3JlcyBjYWxjdWxhZG9zIHBhcmEgYSB0ZW1wZXJhdHVyYSBtw61uaW1hLiBKw6EgbyBwaWNvIGRlIHRlbXBlcmF0dXJhIG3DoXhpbWEgw6kgbyBtw6F4aW1vIGRvIGNvbmp1bnRvIGRlIHZhbG9yZXMgY2FsY3VsYWRvcyBwYXJhIGEgdGVtcGVyYXR1cmEgbcOheGltYS4gDQoNCg0KNC4gR3LDoWZpY28gZGUgTGluaGFzIHBhcmEgYSBtw6lkaWEgZGEgdGVtcGVyYXR1cmEgbcOpZGlhIHJlZmVyZW50ZSBhbyBwaWNvIGRvIHZlcsOjbyBwb3IgYW5vDQoNCmBgYHtyfQ0KbGluZV9waWNvID0gcGljbyAlPiUgDQogICAgZ3JvdXBfYnkoY2lkYWRlLCBhbm8pICU+JQ0KICAgIHN1bW1hcmlzZSh0bWVkaWFBbm8gPSByb3VuZChtZWFuKHRtZWRpYSksMiksDQogICAgICAgICAgICAgIHRtaW5Bbm8gPSBtaW4odG1pbiksDQogICAgICAgICAgICAgIHRtYXhBbm8gPSBtYXgodG1heCksDQogICAgICAgICAgICAgIC5ncm91cHMgPSAiZHJvcCIpDQoNCmxpbmVfcGljbyAlPiUgDQogICAgZ2dwbG90KGFlcyh4ID0gYW5vLCB5ID0gdG1lZGlhQW5vLCBjb2xvciA9IGNpZGFkZSkpICsNCiAgICBnZW9tX3BvaW50KCkgKw0KICAgIGdlb21fbGluZSgpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gdG1lZGlhQW5vKSwgaGp1c3QgPSAwLjUsIHZqdXN0ID0gLTEsIHNpemUgPSAzLCBhbmdsZSA9IDkwKSArDQogICAgbGFicyh4ID0gIkFubyIsIHkgPSAiVGVtcGVyYXR1cmEgTcOpZGlhICjCukMpIikNCg0KYGBgDQoNCkpvw6NvIFBlc3NvYSBkZW1vbnN0cmEgdGVyIHVtYSAqKnRlbXBlcmF0dXJhIG3DqWRpYSBhbnVhbCBNQUlPUioqIHF1ZSBDYW1waW5hIEdyYW5kZSBlbSB0b2RvcyBvcyBhbm9zIGludmVzdGlnYWRvcy4gQSBkaWZlcmVuw6dhIGRlIHRlbXBlcmF0dXJhIGVudHJlIGFtYmFzIGNoZWdvdSBhIDTCukMgZW0gYWxndW5zIGFub3MuDQoNCjUuIEdyw6FmaWNvIGRlIExpbmhhcyBwYXJhIG8gbcOtbmltbyBkYSB0ZW1wZXJhdHVyYSBtw61uaW1hIHJlZmVyZW50ZSBhbyBwaWNvIGRvIHZlcsOjbyBwb3IgYW5vDQoNCmBgYHtyfQ0KbGluZV9waWNvICU+JSANCiAgICBnZ3Bsb3QoYWVzKHggPSBhbm8sIHkgPSB0bWluQW5vLCBjb2xvciA9IGNpZGFkZSkpICsNCiAgICBnZW9tX3BvaW50KCkgKw0KICAgIGdlb21fbGluZSgpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gdG1pbkFubyksIGhqdXN0ID0gMC41LCB2anVzdCA9IC0xLCBzaXplID0gMywgYW5nbGUgPSA5MCkgKw0KICAgIGxhYnMoeCA9ICJBbm8iLCB5ID0gIlRlbXBlcmF0dXJhIE3DrW5pbWEgKMK6QykiKQ0KYGBgDQoNCkpvw6NvIFBlc3NvYSBkZW1vbnN0cmEgdGVyIHVtYSAqKnRlbXBlcmF0dXJhIG3DrW5pbWEgYW51YWwgTUFJT1IqKiBxdWUgQ2FtcGluYSBHcmFuZGUgZW0gdG9kb3Mgb3MgYW5vcyBpbnZlc3RpZ2Fkb3MuIEEgZGlmZXJlbsOnYSBkZSB0ZW1wZXJhdHVyYSBlbnRyZSBhbWJhcyBjaGVnb3UgYSA1wrpDIGVtIGFsZ3VucyBhbm9zLg0KDQo2LiBHcsOhZmljbyBkZSBMaW5oYXMgcGFyYSBvIG3DoXhpbW8gZGEgdGVtcGVyYXR1cmEgbcOheGltYSByZWZlcmVudGUgYW8gcGljbyBkbyB2ZXLDo28gcG9yIGFubw0KDQpgYGB7cn0NCmxpbmVfcGljbyAlPiUgDQogICAgZ2dwbG90KGFlcyh4ID0gYW5vLCB5ID0gdG1heEFubywgY29sb3IgPSBjaWRhZGUpKSArDQogICAgZ2VvbV9wb2ludCgpICsNCiAgICBnZW9tX2xpbmUoKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHRtYXhBbm8pLCBoanVzdCA9IDAuNSwgdmp1c3QgPSAtMSwgc2l6ZSA9IDMsIGFuZ2xlID0gOTApICsNCiAgICBsYWJzKHggPSAiQW5vIiwgeSA9ICJUZW1wZXJhdHVyYSBNw6F4aW1hICjCukMpIikNCmBgYA0KDQpDYW1waW5hIEdyYW5kZSBkZW1vbnN0cmEgdGVyIHVtYSB0ZW1wZXJhdHVyYSBtw6F4aW1hIGFudWFsIE1BSU9SIHF1ZSBKb8OjbyBQZXNzb2EgZW50cmUgMTk5NSBlIDIwMTUsIGFubyBhIHBhcnRpciBkbyBxdWFsIHBhc3NhIGEgc2VyIG1lbm9yLiDDiSB2w6FsaWRvIGRlc3RhY2FyIHF1ZSBhIGRpZmVyZW7Dp2EgZGUgdGVtcGVyYXR1cmEgbsOjbyB1bHRyYXBhc3NvdSAywrpDIGVtIG5lbmh1bSBkb3MgYW5vcy4NCg0KKipSRVNQT1NUQToqKg0KDQpEZSBmb3JtYSBnZXJhbCwgQ2FtcGluYSBHcmFuZGUgdGVtIHVtYSBtYWlvciB2YXJpYcOnw6NvIGRlIHRlbXBlcmF0dXJhIGFvIGxvbmdvIGRvIGRpYSBkbyBxdWUgSm/Do28gUGVzc29hLCBtYXMgZXN0YSBwZXJtYW5lY2UgbyBkaWEgY29tIHRlbXBlcmF0dXJhcyBtYWlzIGVsZXZhZGFzIHF1ZSBhcXVlbGEsIG8gcXVlIHRvcm5hICoqSm/Do28gUGVzc29hIHVtYSBjaWRhZGUgbWFpcyBxdWVudGUqKiB0YW1iw6ltIG5vIFBpY28gZG8gVmVyw6NvLg0KDQpBbmFsaXNhbmRvIGFubyBwb3IgYW5vLCBDYW1waW5hIEdyYW5kZSBkZW1vbnN0cm91IHRlciBlbSByZWxhw6fDo28gYSBKb8OjbyBQZXNzb2E6IChpKSAqdGVtcGVyYXR1cmEgbcOpZGlhIG1lbm9yKiwgY29tIGNlcmNhIGRlIDTCukMgYSBtZW5vcyBlbSBhbGd1bnMgYW5vczsgKGlpKSB0ZXIgKnRlbXBlcmF0dXJhIG3DrW5pbWEgbWVub3IqLCBjb20gY2VyY2EgZGUgNcK6QyBhIG1lbm9zIGVtIGFsZ3VucyBhbm9zOyBlIChpaWkpIHRlciAqIHRlbXBlcmF0dXJhIG3DoXhpbWEgbWFpb3IqLCBjb20gY2VyY2EgZGUgYXBlbmFzIDLCukMgYSBtYWlzIGVtIGFsZ3VucyBhbm9zLiBJc3RvIGNvbmZpcm1hICoqSm/Do28gUGVzc29hIGNvbW8gdW1hIGNpZGFkZSBtYWlzIHF1ZW50ZSoqIGRvIHF1ZSBDYW1waW5hIEdyYW5kZSB0YW1iw6ltIG5vIFBpY28gZG8gVmVyw6NvLg0KDQpQb3IgZmltLCBmb2kgcGVyY2ViaWRvIHF1ZSBleGlzdGUgY29tcG9ydGFtZW50byBpZMOqbnRpY28gbmEgdmFyaWHDp8OjbyBkZSB0ZW1wZXJhdHVyYXMgZW50cmUgYXMgZHVhcyBjaWRhZGVzLCBpZGVudGlmaWNhZG8gdGFudG8gZGUgZm9ybWEgZ2VyYWwgZSBhbnVhbG1lbnRlLCBjb21vIGNvbnNpZGVyYW5kbyBhcGVuYXMgbyBwaWNvIGRvIHZlcsOjbyAoamFuZWlybyBlIGZldmVyZWlybykgZGUgbWFuZWlyYSBnZXJhbCBlIHBvciBhbm8gdGFtYsOpbS4gTG9nbywgSm/Do28gUGVzc29hIMOpIG1haXMgcXVlbnRlIGRvIHF1ZSBDYW1waW5hIEdyYW5kZSB0YW50byBubyBwaWNvIGRvIHZlcsOjbyBxdWFudG8gbm8gYW5vIHRvZG8gZGVzZGUgMTk5NSwgZXhjZXRvIG5vcyBhbm9zIGRlIDIwMDAgZSAyMDAxIGVtIHJhesOjbyBkYSBmYWx0YSBkZSBkYWRvcyBzb2JyZSBlc3RlcyByZXNwZWN0aXZvcyBhbm9zLg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMjIyBRMjogUXVhaXMgb3MgbWVzZXMgbWFpcyBxdWVudGVzIGUgbWFpcyBmcmlvcz8gQ29tbyB2b2PDqiBkZXNjcmV2ZXJpYSBhIHRlbXBlcmF0dXJhIGRhcyBmZXN0YXMganVuaW5hcyBkYXMgY2lkYWRlcyBub3Mgw7psdGltb3MgYW5vcz8NCg0KLSAgIEludmVzdGlnYW5kbyBhIHRlbXBlcmF0dXJhIGVtIGRpZmVyZW50ZXMgbWVzZXMgZG8gYW5vDQoNCjEuIEdyw6FmaWNvIGRlIExpbmhhcyBwYXJhIGEgbcOpZGlhIGRhIHRlbXBlcmF0dXJhIG3DqWRpYSBtZW5zYWwNCg0KYGBge3J9DQpsaW5lX3RlbXBlcmF0dXJhTWVzID0gY2xpbWFzICU+JSANCiAgICBncm91cF9ieShjaWRhZGUsIG1lcykgJT4lDQogICAgc3VtbWFyaXNlKHRtZWRpYU1lcyA9IHJvdW5kKG1lYW4odG1lZGlhKSwyKSwNCiAgICAgICAgICAgICAgdG1heE1lcyA9IG1heCh0bWF4KSwNCiAgICAgICAgICAgICAgdG1pbk1lcyA9IG1pbih0bWluKSwNCiAgICAgICAgICAgICAgLmdyb3VwcyA9ICJkcm9wIikNCg0KbGluZV90ZW1wZXJhdHVyYU1lcyAlPiUgDQogICAgZ2dwbG90KGFlcyh4ID0gbWVzLCB5ID0gdG1lZGlhTWVzLCBjb2xvciA9IGNpZGFkZSkpICsNCiAgICBnZW9tX3BvaW50KCkgKw0KICAgIGdlb21fbGluZSgpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gdG1lZGlhTWVzKSwgaGp1c3QgPSAwLjUsIHZqdXN0ID0gLTEsIHNpemUgPSAzLCBhbmdsZSA9IDkwKSArDQogICAgc2NhbGVfeF9jb250aW51b3VzKCJNw6pzIiwgYnJlYWtzID0gMToxMikgKw0KICAgIGxhYnMoeSA9ICJUZW1wZXJhdHVyYSBNw6lkaWEgKMK6QykiKSANCmBgYA0KDQpKb8OjbyBQZXNzb2EgZGVtb25zdHJhIHRlciB1bWEgKip0ZW1wZXJhdHVyYSBtw6lkaWEgbWVuc2FsIE1BSU9SKiogcXVlIENhbXBpbmEgR3JhbmRlIGVtIHRvZG9zIG9zIG1lc2VzIGludmVzdGlnYWRvcy4gQSBkaWZlcmVuw6dhIGRlIHRlbXBlcmF0dXJhIG1hbnRldmUgdW0gcGFkcsOjbyBkZSBjZXJjYSBkZSAzwrpDIGFvIGxvbmdvIGRvcyBtZXNlcy4gTmEgbcOpZGlhLCBtYXLDp28gw6kgbyBtw6pzIG1haXMgcXVlbnRlIGUganVsaG8gw6kgbyBtw6pzIG1haXMgZnJpbyBwYXJhIGFzIGR1YXMgY2lkYWRlcy4NCg0KMi4gR3LDoWZpY28gZGUgTGluaGFzIHBhcmEgbyBtw6F4aW1vIGRlIHRlbXBlcmF0dXJhIG3DoXhpbWEgbWVuc2FsDQoNCmBgYHtyfQ0KbGluZV90ZW1wZXJhdHVyYU1lcyAlPiUgDQogICAgZ2dwbG90KGFlcyh4ID0gbWVzLCB5ID0gdG1heE1lcywgY29sb3IgPSBjaWRhZGUpKSArDQogICAgZ2VvbV9wb2ludCgpICsNCiAgICBnZW9tX2xpbmUoKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHRtYXhNZXMpLCBoanVzdCA9IDAuNSwgdmp1c3QgPSAtMSwgc2l6ZSA9IDMsIGFuZ2xlID0gOTApICsNCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoIk3DqnMiLCBicmVha3MgPSAxOjEyKSArDQogICAgbGFicyh5ID0gIlRlbXBlcmF0dXJhIE3DoXhpbWEgKMK6QykiKSANCmBgYA0KDQpDYW1waW5hIEdyYW5kZSBkZW1vbnN0cmEgdGVyIHVtYSAqKnRlbXBlcmF0dXJhIG3DoXhpbWEgbWVuc2FsIE1BSU9SKiogcXVlIENhbXBpbmEgR3JhbmRlIG5hIG1haW9yaWEgZG9zIG1lc2VzIGludmVzdGlnYWRvcywgY29tIGV4Y2XDp8OjbyBkb3MgbWVzZXMgZGUgTWFpbyBlIEp1bmhvIG9uZGUgZm9pIE1FTk9SLiBBIGRpZmVyZW7Dp2EgZGUgdGVtcGVyYXR1cmEgZm9pIGJhc3RhbnRlIHZhcmlhZGEgYW8gbG9uZ28gZG9zIG1lc2VzLg0KDQpQYXJhIEpvw6NvIFBlc3NvYSwgbyBwaWNvIGRlIHRlbXBlcmF0dXJhIG3DoXhpbWEgZm9pIGlkZW50aWZpY2FkbyBub3MgbWVzZXMgZGUgamFuZWlybyBlIG1hcsOnby4gUGFyYSBDYW1waW5hIEdyYW5kZSwgbyBwaWNvIGRlIHRlbXBlcmF0dXJhIG3DoXhpbWEgZm9pIGlkZW50aWZpY2FkbyBubyBtw6pzIG1hcsOnby4NCg0KMy4gR3LDoWZpY28gZGUgTGluaGFzIHBhcmEgbyBtw61uaW1vIGRlIHRlbXBlcmF0dXJhIG3DrW5pbWEgbWVuc2FsDQoNCmBgYHtyfQ0KbGluZV90ZW1wZXJhdHVyYU1lcyAlPiUgDQogICAgZ2dwbG90KGFlcyh4ID0gbWVzLCB5ID0gdG1pbk1lcywgY29sb3IgPSBjaWRhZGUpKSArDQogICAgZ2VvbV9wb2ludCgpICsNCiAgICBnZW9tX2xpbmUoKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHRtaW5NZXMpLCBoanVzdCA9IDAuNSwgdmp1c3QgPSAtMSwgc2l6ZSA9IDMsIGFuZ2xlID0gOTApICsNCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoIk3DqnMiLCBicmVha3MgPSAxOjEyKSArDQogICAgbGFicyh5ID0gIlRlbXBlcmF0dXJhIE3DrW5pbWEgKMK6QykiKSANCmBgYA0KDQpKb8OjbyBQZXNzb2EgZGVtb25zdHJhIHRlciB1bWEgKip0ZW1wZXJhdHVyYSBtw61uaW1hIG1lbnNhbCBNQUlPUioqIHF1ZSBDYW1waW5hIEdyYW5kZSBlbSB0b2RvcyBvcyBtZXNlcyBpbnZlc3RpZ2Fkb3MuIEEgZGlmZXJlbsOnYSBkZSB0ZW1wZXJhdHVyYSBlbnRyZSBhbWJhcyBjaGVnb3UgYSAzwrpDIGVtIGFsZ3VucyBtZXNlcy4NCg0KUGFyYSBKb8OjbyBQZXNzb2EsIGEgbWVub3IgdGVtcGVyYXR1cmEgbcOtbmltYSBmb2kgaWRlbnRpZmljYWRhIG5vIG3DqnMgZGUgYWdvc3RvLiBQYXJhIENhbXBpbmEgR3JhbmRlLCBhcyBtZW5vcmVzIHRlbXBlcmF0dXJhcyBtw61uaW1hcyBmb3JhbSBpZGVudGlmaWNhZGFzIG5vcyBtZXNlcyBkZSBqdWxobyBlIGFnb3N0by4NCg0KKipSRVNQT1NUQToqKg0KDQpBbyBsb25nbyBkb3MgbWVzZXMgZG8gYW5vLCBKb8OjbyBQZXNzb2Egw6kgbWFpcyBxdWVudGUgZG8gcXVlIENhbXBpbmEgR3JhbmRlLiBFbnRyZXRhbnRvLCBubyBtw6pzIGRlIGp1bmhvLCBDYW1waW5hIEdyYW5kZSBvYnTDqW0gdGVtcGVyYXR1cmFzIG1lbm9yZXMgZG8gcXVlIEpvw6NvIFBlc3NvYSB0YW50byBwYXJhIGEgbcOpZGlhLCBxdWFudG8gcGFyYSBhIG3DrW5pbWEgZSBtw6F4aW1hLiBMb2dvLCBDYW1waW5hIEdyYW5kZSBjb3N0dW1hIGVzdGFyIG1haXMgZnJpYSBubyBtw6pzIGRlIGp1bmhvLg0KDQpOYSBtw6lkaWEsIG1hcsOnbyDDqSBvIG3DqnMgbWFpcyBxdWVudGUgZSBqdWxobyDDqSBvIG3DqnMgbWFpcyBmcmlvIHBhcmEgYXMgZHVhcyBjaWRhZGVzLiBBcyBtZW5vcmVzIHRlbXBlcmF0dXJhcyBlc3TDo28gbm9zIG1lc2VzIGRlIGp1bGhvLCBzb21lbnRlIHBhcmEgQ2FtcGluYSBHcmFuZGUsIGUgZW0gYWdvc3RvLCBwYXJhIGFtYmFzIGFzIGNpZGFkZXMuIErDoSBhcyBtYWlvcmVzIHRlbXBlcmF0dXJhcyBlc3TDo28gbm9zIG1lc2VzIGRlIGphbmVpcm8sIGFwZW5hcyBwYXJhIENhbXBpbmEgR3JhbmRlLCBlIGVtIG1hcsOnbywgcGFyYSBhcyBkdWFzIGNpZGFkZXMuDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KLSAgIEludmVzdGlnYW5kbyBhIHRlbXBlcmF0dXJhIGR1cmFudGUgYXMgZmVzdGFzIGp1bmluYXMgKG3DqnMgZGUganVuaG8pIGRvcyDDumx0aW1vcyAxMCBhbm9zOiBFbnRyZSAyMDA4IGUgMjAxOA0KDQpSZXBldGluZG8gbyBwcm9jZXNzbyBhbnRlcmlvciBmZWl0byBwYXJhIGEgYW7DoWxpc2UgZGUgdGVtcGVyYXR1cmFzIG1lbnNhaXMsIGFnb3JhIGNvbnNpZGVyYW5kbyBhcGVuYXMgbyBtw6pzIGRlIEp1bmhvIGUgb3MgYW5vcyBjb21wcmVlbmRpZG9zIGVudHJlIDIwMDggZSAyMDE4IChvcyDDumx0aW1vcyAxMCBhbm9zIGRhIGJhc2UgZGUgZGFkb3MpLg0KDQpgYGB7cn0NCnRlbXBlcmF0dXJhSnVuaG8gPSBjbGltYXMgJT4lIA0KICAgIGZpbHRlcihtZXMgPT0gNiAmIGFubyA+IDIwMDcpDQoNCnRlbXBlcmF0dXJhSnVuaG8gPSB0ZW1wZXJhdHVyYUp1bmhvICU+JSANCiAgICBncm91cF9ieShjaWRhZGUsIGFubykgJT4lDQogICAgc3VtbWFyaXNlKHRtZWRpYUFubzYgPSByb3VuZChtZWFuKHRtZWRpYSksMiksDQogICAgICAgICAgICAgIHRtYXhBbm82ID0gbWF4KHRtYXgpLA0KICAgICAgICAgICAgICB0bWVkbWF4QW5vNiA9IHJvdW5kKG1lYW4odG1heCksMiksDQogICAgICAgICAgICAgIHRtaW5Bbm82ID0gbWluKHRtaW4pLA0KICAgICAgICAgICAgICB0bWVkbWluQW5vNiA9IHJvdW5kKG1lYW4odG1pbiksMiksDQogICAgICAgICAgICAgIC5ncm91cHMgPSAiZHJvcCIpDQoNCnRlbXBlcmF0dXJhSnVuaG8gJT4lIA0KICAgIGdncGxvdChhZXMoeCA9IGFubywgeSA9IHRtZWRpYUFubzYsIGNvbG9yID0gY2lkYWRlKSkgKw0KICAgIGdlb21fcG9pbnQoKSArDQogICAgZ2VvbV9saW5lKCkgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSB0bWVkaWFBbm82KSwgaGp1c3QgPSAwLjUsIHZqdXN0ID0gLTEsIHNpemUgPSAzLCBhbmdsZSA9IDkwKSArDQogICAgc2NhbGVfeF9jb250aW51b3VzKCJBbm9zIiwgYnJlYWtzID0gMjAwODoyMDE4KSArDQogICAgbGFicyh4ID0gIkFubyIsIHkgPSAiVGVtcGVyYXR1cmEgTcOpZGlhIGRlIEp1bmhvICjCukMpIikgDQoNCnRlbXBlcmF0dXJhSnVuaG8gJT4lIA0KICAgIGdncGxvdChhZXMoeCA9IGFubywgeSA9IHRtYXhBbm82LCBjb2xvciA9IGNpZGFkZSkpICsNCiAgICBnZW9tX3BvaW50KCkgKw0KICAgIGdlb21fbGluZSgpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gdG1heEFubzYpLCBoanVzdCA9IDAuNSwgdmp1c3QgPSAtMSwgc2l6ZSA9IDMsIGFuZ2xlID0gOTApICsNCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoIkFub3MiLCBicmVha3MgPSAyMDA4OjIwMTgpICsNCiAgICBsYWJzKHggPSAiQW5vIiwgeSA9ICJUZW1wZXJhdHVyYSBNw6F4aW1hIGRlIEp1bmhvICjCukMpIikgDQoNCnRlbXBlcmF0dXJhSnVuaG8gJT4lIA0KICAgIGdncGxvdChhZXMoeCA9IGFubywgeSA9IHRtZWRtYXhBbm82LCBjb2xvciA9IGNpZGFkZSkpICsNCiAgICBnZW9tX3BvaW50KCkgKw0KICAgIGdlb21fbGluZSgpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gdG1lZG1heEFubzYpLCBoanVzdCA9IDAuNSwgdmp1c3QgPSAtMSwgc2l6ZSA9IDMsIGFuZ2xlID0gOTApICsNCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoIkFub3MiLCBicmVha3MgPSAyMDA4OjIwMTgpICsNCiAgICBsYWJzKHggPSAiQW5vIiwgeSA9ICJNw6lkaWEgZGEgVGVtcGVyYXR1cmEgTcOheGltYSBkZSBKdW5obyAowrpDKSIpIA0KDQp0ZW1wZXJhdHVyYUp1bmhvICU+JSANCiAgICBnZ3Bsb3QoYWVzKHggPSBhbm8sIHkgPSB0bWluQW5vNiwgY29sb3IgPSBjaWRhZGUpKSArDQogICAgZ2VvbV9wb2ludCgpICsNCiAgICBnZW9tX2xpbmUoKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHRtaW5Bbm82KSwgaGp1c3QgPSAwLjUsIHZqdXN0ID0gLTEsIHNpemUgPSAzLCBhbmdsZSA9IDkwKSArDQogICAgc2NhbGVfeF9jb250aW51b3VzKCJBbm9zIiwgYnJlYWtzID0gMjAwODoyMDE4KSArDQogICAgbGFicyh4ID0gIkFubyIsIHkgPSAiVGVtcGVyYXR1cmEgTcOtbmltYSBkZSBKdW5obyAowrpDKSIpIA0KDQp0ZW1wZXJhdHVyYUp1bmhvICU+JSANCiAgICBnZ3Bsb3QoYWVzKHggPSBhbm8sIHkgPSB0bWVkbWluQW5vNiwgY29sb3IgPSBjaWRhZGUpKSArDQogICAgZ2VvbV9wb2ludCgpICsNCiAgICBnZW9tX2xpbmUoKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHRtZWRtaW5Bbm82KSwgaGp1c3QgPSAwLjUsIHZqdXN0ID0gLTEsIHNpemUgPSAzLCBhbmdsZSA9IDkwKSArDQogICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IDIwMDg6MjAxOCkgKw0KICAgIGxhYnMoeCA9ICJBbm8iLCB5ID0gIk3DqWRpYSBkYSBUZW1wZXJhdHVyYSBNw61uaW1hIGRlIEp1bmhvICAowrpDKSIpIA0KYGBgDQoNCioqUkVTUE9TVEE6KioNCg0KQ29uc2lkZXJhbmRvIG9zIMO6bHRpbW9zIDEwIGFub3MgZGEgYmFzZSBkZSBkYWRvcywgYW5vcyBjb21wcmVlbmRpZG9zIGVudHJlIDIwMDggZSAyMDE4LCBwb2RlLXNlIGFwb250YXIgcXVlIENhbXBpbmEgR3JhbmRlIHBlcm1hbmVjZXUgbWFpcyBmcmlhIGRvIHF1ZSBKb8OjbyBQZXNzb2Egbm8gbcOqcyBkZSBqdW5obywgY29tIHVtYSBkaWZlcmVuw6dhIGRlIGNlcmNhIGRlIDTCukMgdsOhcmlvcyBhbm9zLiANCg0KQ2FtcGluYSBHcmFuZGUgc2VyIG1haXMgZnJpYSBxdWUgSm/Do28gUGVzc29hIG5vIG3DqnMgZGUganVuaG8gw6kgdsOhbGlkbyB0YW50byBwYXJhIGFzIG1lZGnDp8O1ZXMgZGUgdGVtcGVyYXR1cmFzIG3DrW5pbWFzIGUgbcOheGltYXMgcXVhbnRvIHBhcmEgYXMgbcOpZGlhcyBkYXMgdGVtcGVyYXR1cmFzIG3DrW5pbWEsIG3DqWRpYSBlIG3DoXhpbWEuDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyMjIFEzOiBRdWFudG8gY2hvdmUgcG9yIHNlbWFuYSBlbSBKUCBlIENHPyBEZXNjcmV2YSBhIGRpc3RyaWJ1acOnw6NvIGRvIHZvbHVtZSBkZSBjaHV2YXMgcGFyYSBhcyBjaWRhZGVzPw0KDQpPYnNlcnZhbmRvIG8gY29tcG9ydGFtZW50byBkYXMgY2h1dmFzIG5hcyBkdWFzIGNpZGFkZXM6DQoNCjEuIFBsb3RhbmRvIGhpc3RvZ3JhbWEsIGdyw6FmaWNvIGRlIGRlbnNpZGFkZSwgYmxveHBsb3QgZSBhcHJlc2VudGFuZG8gc3Vtw6FyaW9zIHNvYnJlIG8gw61uZGljZSBkZSBjaHV2YXMgZGFzIGR1YXMgY2lkYWRlcw0KDQpgYGB7cn0NCg0KaGlzdF9jaHV2YXNDRyA9IGNnICU+JQ0KICAgIGdncGxvdChhZXMoeCA9IGNodXZhKSkgKw0KICAgIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMTAsIGNvbG9yID0gIiNGQ0M4QzUiLCBmaWxsID0gIiNGQ0M4QzUiKSArDQogICAgbGFicyh4ID0gIsONbmRpY2UgZGUgQ2h1dmFzIChtbSkiLCB5ID0gIkZyZXF1w6puY2lhIikgDQoNCmhpc3RfY2h1dmFzSlAgPSBqcCAlPiUNCiAgICBnZ3Bsb3QoYWVzKHggPSBjaHV2YSkpICsNCiAgICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEwLCBjb2xvciA9ICIjOTlFNUU3IiwgZmlsbCA9ICIjOTlFNUU3IikgKw0KICAgIGxhYnMoeCA9ICLDjW5kaWNlIGRlIENodXZhcyAobW0pIiwgeSA9ICJGcmVxdcOqbmNpYSIpIA0KDQpncmlkLmFycmFuZ2UoaGlzdF9jaHV2YXNDRywgaGlzdF9jaHV2YXNKUCwgbmNvbCA9IDIpDQoNCmRlbnNfY2h1dmFzQ0cgPSBjZyAlPiUNCiAgICBnZ3Bsb3QoYWVzKHggPSBjaHV2YSkpICsNCiAgICBnZW9tX2RlbnNpdHkoZmlsbCA9ICIjRkNDOEM1IikgKw0KICAgIGxhYnMoeCA9ICLDjW5kaWNlIGRlIENodXZhcyAobW0pIiwgeSA9ICJEZW5zaWRhZGUiKSAgDQoNCmRlbnNfY2h1dmFzSlAgPSBqcCAlPiUNCiAgICBnZ3Bsb3QoYWVzKHggPSBjaHV2YSkpICsNCiAgICBnZW9tX2RlbnNpdHkoZmlsbCA9ICIjOTlFNUU3IikgKw0KICAgIGxhYnMoeCA9ICLDjW5kaWNlIGRlIENodXZhcyAobW0pIiwgeSA9ICJEZW5zaWRhZGUiKSANCg0KZ3JpZC5hcnJhbmdlKGRlbnNfY2h1dmFzQ0csIGRlbnNfY2h1dmFzSlAsIG5jb2wgPSAyKQ0KDQpib3hfY2h1dmFzQ0cgPSBjZyAlPiUNCiAgICBnZ3Bsb3QoYWVzKHggPSBjaWRhZGUsIHkgPSBjaHV2YSkpICsNCiAgICBnZW9tX2JveHBsb3QoY29lZiA9IDEwMDAsIHdpZHRoID0gLjIsIGZpbGwgPSAiI0ZDQzhDNSIpICsNCiAgICBsYWJzKHggPSAiQ2lkYWRlIiwgeSA9ICLDjW5kaWNlIGRlIENodXZhcyAobW0pIikNCg0KYm94X2NodXZhc0pQID0ganAgJT4lDQogICAgZ2dwbG90KGFlcyh4ID0gY2lkYWRlLCB5ID0gY2h1dmEpKSArDQogICAgZ2VvbV9ib3hwbG90KGNvZWYgPSAxMDAwLCB3aWR0aCA9IC4yLCBmaWxsID0gIiM5OUU1RTciKSArDQogICAgbGFicyh4ID0gIkNpZGFkZSIsIHkgPSAiw41uZGljZSBkZSBDaHV2YXMgKG1tKSIpDQoNCmdyaWQuYXJyYW5nZShib3hfY2h1dmFzQ0csIGJveF9jaHV2YXNKUCwgbmNvbCA9IDIpDQpgYGANCiANCi0gSGlzdG9ncmFtYTogw4kgbW9zdHJhZG8gcXVlIGV4aXN0ZSB1bWEgZnJlcXXDqm5jaWEgbWFpb3IgZGUgY2h1dmFzIGFiYWl4byBkZSA1MG1tIHBhcmEgQ2FtcGluYSBHcmFuZGUgZSBkZSAxMDBtbSBwYXJhIEpvw6NvIFBlc3NvYS4gQSBtYWlvciBjaHV2YSBwYXJhIGEgQ2FtcGluYSBHcmFuZGUgbsOjbyBwYXNzb3UgZGUgMjAwbW0sIGVucXVhbnRvIHF1ZSBKb8OjbyBQZXNzb2EgdGV2ZSBhbGd1bWFzIGNodXZhcyBtYWlvcmVzIGRvIHF1ZSAyMDBtbSBjaGVnYW5kbyBhIHVsdHJhcGFzc2FyIDM1MG1tIGRlIGNodXZhLiDDiSB2w6FsaWRvIGRlc3RhY2FyIHF1ZSBlc3RhcyBtZWRpw6fDtWVzIGluZGljw6NvIHZhbG9yZXMgc2VtYW5haXMuDQoNCi0gRGVuc2lkYWRlOiBDb25maXJtYSBhIGluZm9ybWHDp8OjbyBtb3N0cmFkYSBubyBoaXN0b2dyYW1hLg0KDQotIEJveHBsb3Q6IFBhcmEgQ2FtcGluYSBHcmFuZGUsIDc1JSBkb3Mgw61uZGljZXMgc2VtYW5haXMgZGUgY2h1dmEgZXN0w6NvIGFiYWl4byBkZSAyNW1tLiBQYXJhIEpvw6NvIFBlc3NvYSwgNzUlIGRhcyBtZWRpw6fDtWVzIHBhcmEgY2h1dmFzIGVzdMOjbyBhYmFpeG8gZGUgNTBtbS4gQWzDqW0gZGlzc28sIGFtYmFzIHBvc3N1ZW0gw61uZGljZXMgZGUgY2h1dmEgbXVpdG8gbWFpb3JlcyBkbyBxdWUgYXMgc3VhcyByZXNwZWN0aXZhcyBtZWRpYW5hcy4NCg0KYGBge3J9DQpzdW1tYXJ5KGNnJGNodXZhKQ0KYGBgDQoNClBhcmEgQ2FtcGluYSBHcmFuZGUsIGjDoSB1bWEgdmFyaWHDp8OjbyBkZSBjaHV2YXMgZGUgMG1tIGEgMTkybW0sIGFwcm94aW1hZGFtZW50ZSwgY29tIG1lZGlhbmEgZXF1aXZhbGVudGUgYSA1LDA1bW0gZSBtw6lkaWEgaWd1YWwgMTQsMjJtbS4gQSBkaWZlcmVuw6dhIGVudHJlIG8gM8K6IHF1YXJ0aWwgZSBvIHZhbG9yIG3DoXhpbW8gw6kgbXVpdG8gZ3JhbmRlLCBtb3N0cmFuZG8gdW1hIGRpc3RyaWJ1acOnw6NvIGlycmVndWxhciBkb3MgZGFkb3MuIE9zIHZhbG9yZXMgZGUgbcOpZGlhIGUgbWVkaWFuYSBuw6NvIHPDo28gYmVtIHJlcHJlc2VudGF0aXZvcy4NCg0KYGBge3J9DQpzdW1tYXJ5KGpwJGNodXZhKQ0KYGBgDQoNClBhcmEgSm/Do28gUGVzc29hLCBow6EgdW1hIHZhcmlhw6fDo28gZGUgY2h1dmFzIGRlIDBtbSBhIDM1Mm1tLCBhcHJveGltYWRhbWVudGUsIGNvbSBtZWRpYW5hIGVxdWl2YWxlbnRlIGEgMTQsNW1tIGUgbcOpZGlhIGlndWFsIDMzLDU5bW0uIEEgZGlmZXJlbsOnYSBlbnRyZSBvIDPCuiBxdWFydGlsIGUgbyB2YWxvciBtw6F4aW1vIMOpIG11aXRvIGdyYW5kZSAobWFpb3IgYWluZGEgZG8gcXVlIHBhcmEgQ2FtcGluYSBHcmFuZGUpLCBtb3N0cmFuZG8gdW1hIGRpc3RyaWJ1acOnw6NvIGFpbmRhIG1haXMgaXJyZWd1bGFyIGRvcyBkYWRvcy4gT3MgdmFsb3JlcyBkZSBtw6lkaWEgZSBtZWRpYW5hIG7Do28gc8OjbyBiZW0gcmVwcmVzZW50YXRpdm9zLg0KDQoqKlJFU1BPU1RBOioqDQoNClBhcmEgQ2FtcGluYSBHcmFuZGUsIDc1JSBkb3Mgw61uZGljZXMgc2VtYW5haXMgZGUgY2h1dmEgZXN0w6NvIGFiYWl4byBkZSAyNW1tLiBQYXJhIEpvw6NvIFBlc3NvYSwgNzUlIGRhcyBtZWRpw6fDtWVzIHBhcmEgY2h1dmFzIGVzdMOjbyBhYmFpeG8gZGUgNTBtbS4gQWzDqW0gZGlzc28sIGFtYmFzIHBvc3N1ZW0gw61uZGljZXMgZGUgY2h1dmEgbXVpdG8gbWFpb3JlcyBkbyBxdWUgYXMgc3VhcyByZXNwZWN0aXZhcyBtZWRpYW5hcy4gSXN0byDDqSwgZXhpc3RlIHVtYSBkaXN0cmlidWnDp8OjbyBtdWl0byBpcnJlZ3VsYXIgZGUgY2h1dmFzLCBkZSBtYW5laXJhIGdlcmFsLiBBIGRpZmVyZW7Dp2EgZW50cmUgbyAzwrogcXVhcnRpbCBlIG8gdmFsb3IgbcOheGltbyDDqSBtdWl0byBncmFuZGUgKG1haW9yIGFpbmRhIGVtIEpvw6NvIFBlc3NvYSksIG1vc3RyYW5kbyBkaXN0cmlidWnDp8O1ZXMgaXJyZWd1bGFyZXMgZG9zIGRhZG9zLiBPcyB2YWxvcmVzIGRlIG3DqWRpYSBlIG1lZGlhbmEgbsOjbyBzw6NvIGJlbSByZXByZXNlbnRhdGl2b3MuDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyMgUTQ6IFF1YWwgYSByZWxhw6fDo28gZW50cmUgYSB0ZW1wZXJhdHVyYSBkZSB1bWEgc2VtYW5hIGUgYSB0ZW1wZXJhdHVyYSBkYSBzZW1hbmEgYW50ZXJpb3IgKGRlc2NyZXZhIHBhcmEgYXMgZHVhcyBjaWRhZGVzKT8NCg0KVmlzdWFsaXphbmRvIGdyYWZpY2FtZW50ZSBvcyBkYWRvcyBzb2JyZSB0ZW1wZXJhdHVyYXMgbcOpZGlhcyBlIHN1YSBzZW1hbmEgaW1lZGlhdGFtZW50ZSBhbnRlcmlvciBwYXJhIHZlcmlmaWNhciBhIHBvc3NpYmlsaWRhZGUgZGUgY29ycmVsYcOnw6NvLg0KDQoxLiBHcsOhZmljbyBkZSBQb250b3MgZGUgVGVtcGVyYXR1cmEgTcOpZGlhIFggVGVtcGVyYXR1cmEgTcOpZGlhIGRhIFNlbWFuYSBBbnRlcmlvcg0KDQpgYGB7cn0NCnJlbGFjYW9UZW1wZXJhdHVyYSA9IGNsaW1hcw0KDQpyZWxhY2FvVGVtcGVyYXR1cmEgJT4lIA0KICAgIGdncGxvdChhZXMoeCA9IHRtZWRpYSwgeSA9IHRlbXBfYW50ZXJpb3IsIGNvbG9yID0gY2lkYWRlKSkgKw0KICAgIGdlb21fcXVhc2lyYW5kb20oYWxwaGEgPSAuNSwgc2l6ZSA9IDEpICsNCiAgICBsYWJzKHggPSAiVGVtcGVyYXR1cmEgTcOpZGlhICjCukMpIiwgeSA9ICJUZW1wZXJhdHVyYSBNw6lkaWEgZGEgU2VtYW5hIEFudGVyaW9yICjCukMpIikNCmBgYA0KDQpWaXN1YWxtZW50ZSwgbm90YS1zZSBxdWUgZXhpc3RlIHVtYSByZWxhw6fDo28gbGluZWFyIGVudHJlIGEgdGVtcGVyYXR1cmEgbcOpZGlhIGUgYSB0ZW1wZXJhdHVyYSBtw6lkaWEgZGEgc3VhIHNlbWFuYSBpbWVkaWF0YW1lbnRlIGFudGVyaW9yLCB0YW50byBwYXJhIENhbXBpbmEgR3JhbmRlLCBxdWFudG8gcGFyYSBKb8OjbyBQZXNzb2EuIElzdG8gc2lnbmlmaWNhIHF1ZSBhIHRlbXBlcmF0dXJhIG3DqWRpYSBkZSB1bWEgc2VtYW5hIGVzcGVjw61maWNhIGZvaSBzZW1lbGhhbnRlIMOgIHRlbXBlcmF0dXJhIG3DqWRpYSBkZSBzdWEgc2VtYW5hIGltZWRpYXRhbWVudGUgYW50ZXJpb3IuDQoNClBhcmEgdmFsb3JlcyBtZW5vcmVzIGRlIHRlbXBlcmF0dXJhcywgQ2FtcGluYSBHcmFuZGUgZGVzdGFjYS1zZSBtYWlzLCBhbyBwYXNzbyBxdWUgcGFyYSBtYWlvcmVzIHRlbXBlcmF0dXJhcywgSm/Do28gUGVzc29hIGRlc3RhY2Etc2UgbWFpcy4NCg0KVmVyaWZpY2FuZG8gb3MgdmFsb3JlcyBkZSBjb3JyZWxhw6fDo28gcGFyYSBvcyBjb2VmaWNpZW50ZXMgZGUgKnBlYXJzb24qLCAqc3BlYXJtYW4qIGUgKmtlbmRhbGwqIHBhcmEgYXMgZHVhcyBjaWRhZGVzLg0KDQpgYGB7cn0NCmNvcnJlbGFjYW9UZW1wZXJhdHVyYUNHID0gY2cgDQoNCmNvcnJlbGFjYW9UZW1wZXJhdHVyYUNHICU+JSANCiAgICBzdW1tYXJpc2UocGVhcnNvbiA9IGNvcih0bWVkaWEsIHRlbXBfYW50ZXJpb3IsIG1ldGhvZCA9ICJwZWFyc29uIiksDQogICAgICAgICAgICAgIHNwZWFybWFuID0gY29yKHRtZWRpYSwgdGVtcF9hbnRlcmlvciwgbWV0aG9kID0gInNwZWFybWFuIiksDQogICAgICAgICAgICAgIGtlbmRhbGwgPSBjb3IodG1lZGlhLCB0ZW1wX2FudGVyaW9yLCBtZXRob2QgPSAia2VuZGFsbCIpKQ0KYGBgDQoNClBhcmEgQ2FtcGluYSBHcmFuZGUsIHRvZG9zIG9zIHRyw6pzIGNvZWZpY2llbnRlcyBjYWxjdWxhZG9zIGFwb250YXJhbSB1bWEgY29ycmVsYcOnw6NvIHBvc2l0aXZhIGFsdGEgZW50cmUgYSB0ZW1wZXJhdHVyYSBtw6lkaWEgZSBhIHRlbXBlcmF0dXJhIG3DqWRpYSBkZSBzdWEgc2VtYW5hIGltZWRpYXRhbWVudGUgYW50ZXJpb3IuDQoNCmBgYHtyfQ0KY29ycmVsYWNhb1RlbXBlcmF0dXJhSlAgPSBqcCANCg0KY29ycmVsYWNhb1RlbXBlcmF0dXJhSlAgJT4lIA0KICAgIHN1bW1hcmlzZShwZWFyc29uID0gY29yKHRtZWRpYSwgdGVtcF9hbnRlcmlvciwgbWV0aG9kID0gInBlYXJzb24iKSwNCiAgICAgICAgICAgICAgc3BlYXJtYW4gPSBjb3IodG1lZGlhLCB0ZW1wX2FudGVyaW9yLCBtZXRob2QgPSAic3BlYXJtYW4iKSwNCiAgICAgICAgICAgICAga2VuZGFsbCA9IGNvcih0bWVkaWEsIHRlbXBfYW50ZXJpb3IsIG1ldGhvZCA9ICJrZW5kYWxsIikpDQpgYGANCg0KUGFyYSBKb8OjbyBQZXNzb2EsIHRvZG9zIG9zIHRyw6pzIGNvZWZpY2llbnRlcyBjYWxjdWxhZG9zIGFwb250YXJhbSB1bWEgY29ycmVsYcOnw6NvIHBvc2l0aXZhIGFsdGEgZW50cmUgYSB0ZW1wZXJhdHVyYSBtw6lkaWEgZSBhIHRlbXBlcmF0dXJhIG3DqWRpYSBkZSBzdWEgc2VtYW5hIGltZWRpYXRhbWVudGUgYW50ZXJpb3IuDQoNCkFnb3JhLCB2ZXJpZmljYW5kbyBvIHN1bcOhcmlvIGVudHJlIGFzIHRlbXBlcmF0dXJhcyBwYXJhIGFzIGR1YXMgY2lkYWRlcy4NCg0KYGBge3J9DQpyZWxhY2FvVGVtcGVyYXR1cmFDRyA9IGNnDQoNCnN1bW1hcnkocmVsYWNhb1RlbXBlcmF0dXJhQ0ckdG1lZGlhLCByZWxhY2FvVGVtcGVyYXR1cmFDRyR0ZW1wX2FudGVyaW9yKQ0KYGBgDQoNClBhcmEgQ2FtcGluYSBHcmFuZGUsIGEgbcOpZGlhIGUgYSBtZWRpYW5hIG9idGl2ZXJhbSB2YWxvcmVzIG11aXRvIHByw7N4aW1vcyBlIG7Do28gZXN0w6NvIGRpc3RhbnRlcyBkb3Mgc2V1cyBwb250b3MgbcOheGltbyBlIG3DrW5pbW8sIG8gcXVlIG1vc3RyYSB1bWEgZGlzdHJpYnVpw6fDo28gcmVndWxhciBkb3MgZGFkb3MuDQoNCmBgYHtyfQ0KcmVsYWNhb1RlbXBlcmF0dXJhSlAgPSBqcA0KDQpzdW1tYXJ5KHJlbGFjYW9UZW1wZXJhdHVyYUpQJHRtZWRpYSwgcmVsYWNhb1RlbXBlcmF0dXJhSlAkdGVtcF9hbnRlcmlvcikNCmBgYA0KDQpQYXJhIEpvw6NvIFBlc3NvYSwgYSBtw6lkaWEgZSBhIG1lZGlhbmEgb2J0aXZlcmFtIHZhbG9yZXMgbXVpdG8gcHLDs3hpbW9zIGUgbsOjbyBlc3TDo28gZGlzdGFudGVzIGRvcyBzZXVzIHBvbnRvcyBtw6F4aW1vIGUgbcOtbmltbywgbyBxdWUgbW9zdHJhIHVtYSBkaXN0cmlidWnDp8OjbyByZWd1bGFyIGRvcyBkYWRvcy4NCg0KKipSRVNQT1NUQToqKg0KDQpQb2RlLXNlIHBlcmNlYmVyIHF1ZSBleGlzdGUgdW1hIHJlbGHDp8OjbyBsaW5lYXIgZSBkZSBhbHRhIGNvcnJlbGHDp8OjbyBlbnRyZSBhIHRlbXBlcmF0dXJhIG3DqWRpYSBlIGEgdGVtcGVyYXR1cmEgbcOpZGlhIGRhIHN1YSBzZW1hbmEgaW1lZGlhdGFtZW50ZSBhbnRlcmlvciwgdGFudG8gcGFyYSBDYW1waW5hIEdyYW5kZSwgcXVhbnRvIHBhcmEgSm/Do28gUGVzc29hLiBJc3RvIHNpZ25pZmljYSBxdWUgYSB0ZW1wZXJhdHVyYSBtw6lkaWEgZGUgdW1hIHNlbWFuYSBlc3BlY8OtZmljYSBmb2kgc2VtZWxoYW50ZSDDoCB0ZW1wZXJhdHVyYSBtw6lkaWEgZGUgc3VhIHNlbWFuYSBpbWVkaWF0YW1lbnRlIGFudGVyaW9yLiANCg0KQSBkaWZlcmVuw6dhIGVzdMOhIG5vcyB2YWxvcmVzIGRhcyB0ZW1wZXJhdHVyYXMsIG9uZGUgQ2FtcGluYSBHcmFuZGUgYXByZXNlbnRhIHZhbG9yZXMgbWFpcyBiYWl4b3MgZG8gcXVlIEpvw6NvIFBlc3NvYS4gQ29udHVkbywgYW1iYXMgcG9zc3VlbSB1bSBjb21wb3J0YW1lbnRvIHNlbWVsaGFudGUgcGFyYSBhcyB0ZW1wZXJhdHVyYXMgbcOpZGlhcyBlIGFzIHRlbXBlcmF0dXJhcyBtw6lkaWFzIGRhIHNlbWFuYSBpbWVkaWF0YW1lbnRlIGFudGVyaW9yLg0KDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyMjIFE1OiBRdWFsIGEgcmVsYcOnw6NvIGVudHJlIHRlbXBlcmF0dXJhIGUgY2h1dmFzIG5hcyBzZW1hbmFzIGVtIHF1ZSBjaG92ZXUgKGRlc2NyZXZhIHBhcmEgYXMgZHVhcyBjaWRhZGVzKT8NCg0KVmlzdWFsaXphbmRvIGdyYWZpY2FtZW50ZSBvcyBkYWRvcyBzb2JyZSB0ZW1wZXJhdHVyYXMgbcOpZGlhcyBlIGNodXZhcyBwYXJhIHZlcmlmaWNhciBhIHBvc3NpYmlsaWRhZGUgZGUgY29ycmVsYcOnw6NvLg0KDQoxLiBHcsOhZmljbyBkZSBQb250b3MgZGUgVGVtcGVyYXR1cmEgTcOpZGlhIFggw41uZGljZSBkZSBDaHV2YXMNCg0KYGBge3J9DQpyZWxhY2FvVGVtcGVyYXR1cmFDaHV2YSA9IGNsaW1hcw0KDQpyZWxhY2FvVGVtcGVyYXR1cmFDaHV2YSAlPiUgDQogICAgZ2dwbG90KGFlcyh4ID0gdG1lZGlhLCB5ID0gY2h1dmEsIGNvbG9yID0gY2lkYWRlKSkgKw0KICAgIGdlb21fcXVhc2lyYW5kb20oYWxwaGEgPSAuNSwgc2l6ZSA9IDEpICsNCiAgICBsYWJzKHggPSAiVGVtcGVyYXR1cmEgTcOpZGlhICjCukMpIiwgeSA9ICLDjW5kaWNlIGRlIENodXZhcyAobW0pIikNCmBgYA0KDQpOw6NvIMOpIHBvc3PDrXZlbCBvYnNlcnZhciB2aXN1YWxtZW50ZSBhbGd1bWEgY29ycmVsYcOnw6NvIGVudHJlIHRlbXBlcmF0dXJhIG3DqWRpYSBlIMOtbmRpY2UgZGUgY2h1dmFzIGVtIG5lbmh1bWEgZGFzIGNpZGFkZXMuIE8gcXVlIHBvZGUgc2VyIHZpc3RvIMOpIGFwZW5hcyBxdWUgcGFyYSB2YWxvcmVzIG1lbm9yZXMgZGUgdGVtcGVyYXR1cmFzLCBDYW1waW5hIEdyYW5kZSBkZXN0YWNhLXNlIG1haXMsIGFvIHBhc3NvIHF1ZSBwYXJhIG1haW9yZXMgdGVtcGVyYXR1cmFzLCBKb8OjbyBQZXNzb2EgZGVzdGFjYS1zZSBtYWlzLg0KDQpWZXJpZmljYW5kbyBvcyB2YWxvcmVzIGRlIGNvcnJlbGHDp8OjbyBwYXJhIG9zIGNvZWZpY2llbnRlcyBkZSAqcGVhcnNvbiosICpzcGVhcm1hbiogZSAqa2VuZGFsbCogcGFyYSBhcyBkdWFzIGNpZGFkZXMuDQoNCmBgYHtyfQ0KY29ycmVsYWNhb1RlbXBlcmF0dXJhQ2h1dmFzQ0cgPSBjZyANCg0KY29ycmVsYWNhb1RlbXBlcmF0dXJhQ2h1dmFzQ0cgJT4lIA0KICAgIHN1bW1hcmlzZShwZWFyc29uID0gY29yKHRtZWRpYSwgY2h1dmEsIG1ldGhvZCA9ICJwZWFyc29uIiksDQogICAgICAgICAgICAgIHNwZWFybWFuID0gY29yKHRtZWRpYSwgY2h1dmEsIG1ldGhvZCA9ICJzcGVhcm1hbiIpLA0KICAgICAgICAgICAgICBrZW5kYWxsID0gY29yKHRtZWRpYSwgY2h1dmEsIG1ldGhvZCA9ICJrZW5kYWxsIikpDQpgYGANCg0KUGFyYSBDYW1waW5hIEdyYW5kZSwgb3MgY29lZmljaWVudGVzIGNhbGN1bGFkb3MgYXBvbnRhcmFtIHVtYSBjb3JyZWxhw6fDo28gbmVnYXRpdmEgZnJhY2EgKCpwZWFyc29uKiBlICprZW5kYWxsKikgZSBuZWdhdGl2YSBtb2RlcmFkYSAoKnNwZWFybWFuKikgZW50cmUgYSB0ZW1wZXJhdHVyYSBtw6lkaWEgZSBvIMOtbmRpY2UgZGUgY2h1dmFzLg0KDQpgYGB7cn0NCmNvcnJlbGFjYW9UZW1wZXJhdHVyYUNodXZhc0pQID0ganAgDQoNCmNvcnJlbGFjYW9UZW1wZXJhdHVyYUNodXZhc0pQICU+JSANCiAgICBzdW1tYXJpc2UocGVhcnNvbiA9IGNvcih0bWVkaWEsIGNodXZhLCBtZXRob2QgPSAicGVhcnNvbiIpLA0KICAgICAgICAgICAgICBzcGVhcm1hbiA9IGNvcih0bWVkaWEsIGNodXZhLCBtZXRob2QgPSAic3BlYXJtYW4iKSwNCiAgICAgICAgICAgICAga2VuZGFsbCA9IGNvcih0bWVkaWEsIGNodXZhLCBtZXRob2QgPSAia2VuZGFsbCIpKQ0KYGBgDQoNClBhcmEgQ2FtcGluYSBHcmFuZGUsIHRvZG9zIG9zIHRyw6pzIGNvZWZpY2llbnRlcyBjYWxjdWxhZG9zIGFwb250YXJhbSB1bWEgY29ycmVsYcOnw6NvIG5lZ2F0aXZhIGZyYWNhIGVudHJlIGEgdGVtcGVyYXR1cmEgbcOpZGlhIGUgbyDDrW5kaWNlIGRlIGNodXZhcy4NCg0KQWdvcmEsIHZlcmlmaWNhbmRvIG8gc3Vtw6FyaW8gZW50cmUgYXMgdGVtcGVyYXR1cmFzIGUgb3Mgw61uZGljZXMgZGUgY2h1dmFzIHBhcmEgYXMgZHVhcyBjaWRhZGVzLg0KDQpgYGB7cn0NCnJlbGFjYW9UZW1wZXJhdHVyYUNodXZhQ0cgPSBjZw0KDQpzdW1tYXJ5KHJlbGFjYW9UZW1wZXJhdHVyYUNodXZhQ0ckY2h1dmEsIHJlbGFjYW9UZW1wZXJhdHVyYUNodXZhQ0ckdG1lZGlhKQ0KYGBgDQoNClBhcmEgQ2FtcGluYSBHcmFuZGUsIGEgbcOpZGlhIGUgYSBtZWRpYW5hIG9idGl2ZXJhbSB2YWxvcmVzIG7Do28gcHLDs3hpbW9zLCBuw6NvIGVzdMOjbyBwcsOzeGltYXMgZG8gdmFsb3IgbcOtbmltbyBlIGVzdMOjbyBtdWl0byBkaXN0YW50ZXMgZG8gc2V1IHBvbnRvIG3DoXhpbW8sIG8gcXVlIG1vc3RyYSB1bWEgZGlzdHJpYnVpw6fDo28gaXJyZWd1bGFyIGRvcyBkYWRvcy4NCg0KYGBge3J9DQpyZWxhY2FvVGVtcGVyYXR1cmFDaHV2YUpQID0ganANCg0Kc3VtbWFyeShyZWxhY2FvVGVtcGVyYXR1cmFDaHV2YUpQJGNodXZhLCByZWxhY2FvVGVtcGVyYXR1cmFDaHV2YUpQJHRtZWRpYSkNCmBgYA0KDQpQYXJhIEpvw6NvIFBlc3NvYSwgYSBtw6lkaWEgZSBhIG1lZGlhbmEgb2J0aXZlcmFtIHZhbG9yZXMgbsOjbyBwcsOzeGltb3MsIG7Do28gZXN0w6NvIHByw7N4aW1hcyBkbyB2YWxvciBtw61uaW1vIGUgZXN0w6NvIG11aXRvIGRpc3RhbnRlcyBkbyBzZXUgcG9udG8gbcOheGltbywgbyBxdWUgbW9zdHJhIHVtYSBkaXN0cmlidWnDp8OjbyBpcnJlZ3VsYXIgZG9zIGRhZG9zLiBOZXN0ZSBjYXNvLCBhIGlycmVndWxhcmlkYWRlIMOpIGFpbmRhIG1haW9yIHF1ZSBlbSBDYW1waW5hIEdyYW5kZS4NCg0KKipSRVNQT1NUQToqKg0KDQpOw6NvIMOpIHBvc3PDrXZlbCBvYnNlcnZhciBhbGd1bWEgY29ycmVsYcOnw6NvIGVudHJlIHRlbXBlcmF0dXJhIG3DqWRpYSBlIMOtbmRpY2UgZGUgY2h1dmFzIGVtIG5lbmh1bWEgZGFzIGNpZGFkZXMuIE8gcXVlIHBvZGUgc2VyIHZpc3RvIMOpIGFwZW5hcyBxdWUgcGFyYSB2YWxvcmVzIG1lbm9yZXMgZGUgdGVtcGVyYXR1cmFzLCBDYW1waW5hIEdyYW5kZSBkZXN0YWNhLXNlIG1haXMsIGFvIHBhc3NvIHF1ZSBwYXJhIG1haW9yZXMgdGVtcGVyYXR1cmFzLCBKb8OjbyBQZXNzb2EgZGVzdGFjYS1zZSBtYWlzLg0KDQpPcyBjb2VmaWNpZW50ZXMgZGUgKnBlYXJzb24qLCAqc3BlYXJtYW4qIGUgKmtlbmRhbGwqIGFwb250YXJhbSB1bWEgY29ycmVsYcOnw6NvIG5lZ2F0aXZhIGZyYWNhIGVudHJlIHRlbXBlcmF0dXJhIG3DqWRpYSBlIMOtbmRpY2UgZGUgY2h1dmFzIHBhcmEgYXMgZHVhcyBjaWRhZGVzLCBubyBnZXJhbC4gQWzDqW0gZGlzc28sIGEgdmFyaWHDp8OjbyBkZSBkYWRvcyBtb3N0cmEgaXJyZWd1bGFyaWRhZGUgdGFtYsOpbSBuYXMgZHVhcyBjaWRhZGVzLg0KDQpMb2dvLCBuw6NvIMOpIHBvc3PDrXZlbCBhZmlybWFyIHF1ZSBleGlzdGUgY29ycmVsYcOnw6NvIGVudHJlIHRlbXBlcmF0dXJhIG3DqWRpYSBlIMOtbmRpY2UgZGUgY2h1dmFzIHBhcmEgYXMgY2lkYWRlcyBkZSBDYW1waW5hIEdyYW5kZSBlIEpvw6NvIFBlc3NvYS4gUG9yIGV4ZW1wbG8sIHBvZGUgY2hvdmVyIGVtIGRpYXMgcXVlbnRlcyBlIGZyaW9zIGUgdGFtYsOpbSBwb2RlIG7Do28gY2hvdmVyIGVtIGRpYXMgcXVlbnRlcyBlIGZyaW9zLiBJc3RvIGRpZmljdWx0YSBhIGlkZW50aWZpY2HDp8OjbyBkZSB1bWEgcmVsYcOnw6NvIGVudHJlIGEgdGVtcGVyYXR1cmEgbcOpZGlhIGUgbyDDrW5kaWNlIGRlIGNodXZhcy4NCg==