Programa de Pós-Graduação em Ciência da Computação da Universidade Federal de Campina Grande (PPGCC/UFCG)

Disciplina: Fundamentos de Pesquisa em Ciência da Computação II (FPCC II)

Professor: Fábio Jorge Almeida Morais

Aluno: Felipe Torres Leite

Tarefa: Laboratório 2: Campina Grande X João Pessoa

Data: 08/05/2023

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:

  1. 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.

  1. 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.

  1. 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.

  1. 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.

  1. 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.

  1. 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)
  1. 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.

  1. 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.

  1. 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.

  1. 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.

  1. 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.

  1. 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
  1. 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.

  1. 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.

  1. 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:

  1. 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.

  1. 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.

  1. 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==