Instalacao & Carregamento de Packages

if (!require("tidyverse", character.only = TRUE)) {
  install.packages(tidyverse)
  }
Loading required package: tidyverse
── Attaching core tidyverse packages ───────────────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.3     ✔ readr     2.1.4
✔ forcats   1.0.0     ✔ stringr   1.5.0
✔ ggplot2   3.4.3     ✔ tibble    3.2.1
✔ lubridate 1.9.2     ✔ tidyr     1.3.0
✔ purrr     1.0.2     
── Conflicts ─────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(tidyverse)
if (!require("urca", character.only = TRUE)) {
  install.packages(urca)
  }
Loading required package: urca
library(urca)
if (!require("forecast", character.only = TRUE)){
  install.packages(forecast)
  }
Loading required package: forecast
Registered S3 method overwritten by 'quantmod':
  method            from
  as.zoo.data.frame zoo 
library(forcast)
Error in library(forcast) : there is no package called ‘forcast’

Importacao dos Dados

setwd("~/DATA SCIENCES PROJECTS/R Projects/Exame series temporais") # defeinicao de directorio de trabalho
chuva <- read.table("chuva_anual.txt", header = TRUE) |> # Carregamento do dataset
  janitor::clean_names()

Estrutura

head(chuva) # primeiras linhas
tail(chuva) # ultimas linhas
dplyr::glimpse(chuva) # estrutura geral
Rows: 117
Columns: 1
$ chuva_anual_mm <int> 891, 1021, 433, 1048, 435, 635, 343, 314, 454, 384, 739, 383, 30…

Limpeza

# Identificar valores ausentes
chuva |> 
  dplyr::summarise_all(~sum(is.na(.)))

O resultado mostra que nao ha valores ausentes

# identificar linhas duplicadas
chuva |> 
  janitor::get_dupes()
No variable names specified - using all columns.

Os resultados mostram que ha duas linhas duplicadas na nossa base de dados, mas tratando-se de uma serie temporal nao sera feito nenhum tratamento pois pode ser comum um envento se repetir.

# Identificar Outliers
chuva |>
  dplyr::select_if(is.numeric) |> 
  outliers::outlier()
chuva_anual_mm 
          1503 
  
# Filtrando outliers
chuva |> 
  dplyr::filter(chuva_anual_mm !=1503)

identificou_se que que o outlier na base de dados e 1503, entao usou-se metodos de filtragem para remover esse outlier.

Pressupostos

Teste de normalidade de ShapiroWilk

  • H0: P-value ≥ 0.5

  • H1: P-value < 0.5

# texte de normalidade de ShapiroWilk
shapiro.test(chuva$chuva_anual_mm)

    Shapiro-Wilk normality test

data:  chuva$chuva_anual_mm
W = 0.97872, p-value = 0.05987

Os resultados mostram que o p-valor e de 0.05987, logo ha evidencias suficientes para rejejeitar a hipotese nula que diz que os dados seguem uma distribicao normal (H0: P-value ≥ 0.5). vamos usar o histograma para visualizar a distribuicao dos dados.

Histogram

ggplot2::ggplot(chuva, aes(x=chuva_anual_mm)) +geom_histogram(bins=15, 
                                                              fill="orange",
                                                              color ="black" ) +ggtitle("histograma da chuva anual")

O gráfico acima é um histograma que apresenta a presenta distribuíção dos dados de Chuva_Anual.mm. O mesmo mostra que os dados não apresentam uma distribuíção normal pois há uma assimetria para o lado esquerdo, confirmando o texte de ShapiroWilk.

Decomposição da Serie

Sazonalidade

plot.ts(chuva, ylab="Frequência", main="Chuva (mm)")

O gráfico acima ilustra a série temporal dados dados, o mesmo mostra sazonalidade nos dados de chuva, apresentando altas recorentes em alguns períodos ( 20, 40, 80, 70). Nesse caso deve se efectur a transformação logaritimica para remocao da sazonalidade nos dados.

Transformação logaritimica

chuva.log <- log(chuva)
chuva.log
hist(chuva.log$chuva_anual_mm, xlab = "chuva_anual_mm", 
     ylab ="frequência" )

## Grafico da serie transformada
chuva.ts<-ts(chuva.log, start=1898, freq=1)
chuva.ts
Time Series:
Start = 1898 
End = 2014 
Frequency = 1 
       chuva_anual_mm
  [1,]       6.792344
  [2,]       6.928538
  [3,]       6.070738
  [4,]       6.954639
  [5,]       6.075346
  [6,]       6.453625
  [7,]       5.837730
  [8,]       5.749393
  [9,]       6.118097
 [10,]       5.950643
 [11,]       6.605298
 [12,]       5.948035
 [13,]       5.730100
 [14,]       6.214608
 [15,]       7.001246
 [16,]       6.317165
 [17,]       6.823286
 [18,]       6.877296
 [19,]       6.815640
 [20,]       5.337538
 [21,]       6.775366
 [22,]       7.280697
 [23,]       6.469250
 [24,]       5.568345
 [25,]       6.582025
 [26,]       6.899723
 [27,]       7.153834
 [28,]       6.338594
 [29,]       7.207860
 [30,]       6.781058
 [31,]       6.646391
 [32,]       6.685861
 [33,]       6.342121
 [34,]       6.639876
 [35,]       6.008813
 [36,]       6.257668
 [37,]       5.796058
 [38,]       6.423247
 [39,]       7.163172
 [40,]       6.729824
 [41,]       6.879356
 [42,]       6.487684
 [43,]       6.637258
 [44,]       6.552508
 [45,]       6.919684
 [46,]       6.192362
 [47,]       5.863631
 [48,]       6.230481
 [49,]       6.626718
 [50,]       6.842683
 [51,]       6.563856
 [52,]       6.796824
 [53,]       6.432940
 [54,]       6.588926
 [55,]       6.716595
 [56,]       6.180017
 [57,]       6.326149
 [58,]       5.834811
 [59,]       5.897154
 [60,]       6.507278
 [61,]       6.383507
 [62,]       6.525030
 [63,]       5.765191
 [64,]       6.357842
 [65,]       6.573680
 [66,]       6.753438
 [67,]       6.472346
 [68,]       6.776507
 [69,]       7.179308
 [70,]       6.761573
 [71,]       6.643790
 [72,]       6.990257
 [73,]       6.689599
 [74,]       6.886532
 [75,]       6.364751
 [76,]       6.656727
 [77,]       6.386879
 [78,]       7.315218
 [79,]       7.147559
 [80,]       6.956545
 [81,]       6.331502
 [82,]       6.983790
 [83,]       6.598509
 [84,]       6.322565
 [85,]       6.846943
 [86,]       6.413459
 [87,]       6.704414
 [88,]       5.638355
 [89,]       6.999422
 [90,]       7.259820
 [91,]       7.181592
 [92,]       6.542472
 [93,]       6.618739
 [94,]       7.050989
 [95,]       6.224558
 [96,]       6.439350
 [97,]       6.368187
 [98,]       5.247024
 [99,]       6.725034
[100,]       6.568078
[101,]       6.637258
[102,]       6.700731
[103,]       5.521461
[104,]       6.613384
[105,]       6.601230
[106,]       6.388561
[107,]       6.977281
[108,]       6.499787
[109,]       7.058758
[110,]       6.135565
[111,]       6.510258
[112,]       6.343880
[113,]       6.606650
[114,]       7.007601
[115,]       6.519147
[116,]       6.779922
[117,]       5.598422
plot.ts(chuva.ts, ylab="Frequência", main="Chuva (mm)")

O gráfico mostra a persistencia de alguma tendência, por isso deve se fazer a seguir a differenciação para remoção da tendência que persiste.

Diferenciação

chuva.ts.dif<-diff(chuva.ts,1)
chuva.ts.dif
Time Series:
Start = 1899 
End = 2014 
Frequency = 1 
       chuva_anual_mm
  [1,]     0.13619339
  [2,]    -0.85780009
  [3,]     0.88390114
  [4,]    -0.87929283
  [5,]     0.37827897
  [6,]    -0.61589455
  [7,]    -0.08833746
  [8,]     0.36870421
  [9,]    -0.16745465
 [10,]     0.65465537
 [11,]    -0.65726293
 [12,]    -0.21793521
 [13,]     0.48450832
 [14,]     0.78663752
 [15,]    -0.68408094
 [16,]     0.50612144
 [17,]     0.05400995
 [18,]    -0.06165608
 [19,]    -1.47810191
 [20,]     1.43782801
 [21,]     0.50533110
 [22,]    -0.81144688
 [23,]    -0.90090581
 [24,]     1.01368064
 [25,]     0.31769797
 [26,]     0.25411069
 [27,]    -0.81523972
 [28,]     0.86926579
 [29,]    -0.42680225
 [30,]    -0.13466711
 [31,]     0.03947043
 [32,]    -0.34373953
 [33,]     0.29775442
 [34,]    -0.63106265
 [35,]     0.24885440
 [36,]    -0.46160984
 [37,]     0.62718921
 [38,]     0.73992543
 [39,]    -0.43334832
 [40,]     0.14953173
 [41,]    -0.39167179
 [42,]     0.14957401
 [43,]    -0.08475014
 [44,]     0.36717596
 [45,]    -0.72732136
 [46,]    -0.32873131
 [47,]     0.36685027
 [48,]     0.39623630
 [49,]     0.21596553
 [50,]    -0.27882776
 [51,]     0.23296819
 [52,]    -0.36388363
 [53,]     0.15598638
 [54,]     0.12766830
 [55,]    -0.53657812
 [56,]     0.14613282
 [57,]    -0.49133874
 [58,]     0.06234313
 [59,]     0.61012384
 [60,]    -0.12377108
 [61,]     0.14152302
 [62,]    -0.75983856
 [63,]     0.59265116
 [64,]     0.21583790
 [65,]     0.17975775
 [66,]    -0.28109162
 [67,]     0.30416070
 [68,]     0.40280098
 [69,]    -0.41773520
 [70,]    -0.11778304
 [71,]     0.34646677
 [72,]    -0.30065723
 [73,]     0.19693237
 [74,]    -0.52178089
 [75,]     0.29197577
 [76,]    -0.26984720
 [77,]     0.92833907
 [78,]    -0.16765912
 [79,]    -0.19101383
 [80,]    -0.62504359
 [81,]     0.65228812
 [82,]    -0.38528094
 [83,]    -0.27594379
 [84,]     0.52437790
 [85,]    -0.43348418
 [86,]     0.29095540
 [87,]    -1.06605969
 [88,]     1.36106780
 [89,]     0.26039714
 [90,]    -0.07822767
 [91,]    -0.63911998
 [92,]     0.07626702
 [93,]     0.43225046
 [94,]    -0.82643102
 [95,]     0.21479194
 [96,]    -0.07116318
 [97,]    -1.12116311
 [98,]     1.47800957
 [99,]    -0.15695573
[100,]     0.06918012
[101,]     0.06347308
[102,]    -1.17927019
[103,]     1.09192330
[104,]    -0.01215410
[105,]    -0.21266871
[106,]     0.58871994
[107,]    -0.47749430
[108,]     0.55897111
[109,]    -0.92319326
[110,]     0.37469345
[111,]    -0.16637791
[112,]     0.26276975
[113,]     0.40095043
[114,]    -0.48845333
[115,]     0.26077462
[116,]    -1.18149995
plot(chuva.ts.dif, ylab="Dif(Log(Chuva))", main="Aplicação da difêrnciação")

## Distribuicao da serie diferenciada
qqnorm(chuva.ts.dif)
qqline(chuva.ts.dif)

O gráfico mostra o Q-Q Plot, usado para verificar a distribuíção normal, o mesmo mostra que a série diferênciada tem uma distribuíção normal, mas com alguns poucos valores que não se ajustam perfeitamente a recta.

Analisar a autocorrelação (ACF), autocorrelação parcial (PACF) e selecionar os valores significativos de p e q da série

par(mfrow=c(2,2))

plot(acf(chuva.ts.dif))

plot(pacf(chuva.ts.dif))

Os gráficos acima, ilustram a autocorelação  (ACF) e autocolrelação parcial (PACF). Nos gráficos gerados, as linhas tracejadas azuis são os limites de significância ou intervalos de confiança; sempre que houver uma ultrapassagem, diz-se que há, ali, um ponto com significância. Diante do exposto pode-se facilmente concluir que tanto para ACF e PACF os valores significativos são encintrados na posição 0, sendo assim temos volores de p e q da série (1,1).

ARIMA

chuva.ts.dif.aj <-arima(chuva.ts.dif, order = c(1,0,1), include.mean = FALSE)     ### Funcao amima (x, ordem (p,q,d)), Se ja fez as diferenciacoes fora no lugar de q coloca zero
chuva.ts.dif.aj

Call:
arima(x = chuva.ts.dif, order = c(1, 0, 1), include.mean = FALSE)

Coefficients:
         ar1      ma1
      0.1307  -0.9946
s.e.  0.0988   0.1020

sigma^2 estimated as 0.188:  log likelihood = -69.63,  aic = 145.26

O AJustado/Estimado é perfeito pois apresenta um aic relativamente alto

Análisar os resíduos para afereir aqualidade do modelo ajustado

par(mfrow=c(2,2))
plot(resid(chuva.ts.dif.aj))

qqnorm(resid(chuva.ts.dif.aj))
qqline(resid(chuva.ts.dif.aj))

acf(resid(chuva.ts.dif.aj))
pacf(resid(chuva.ts.dif.aj))

Representação visual do modelo ajustado

par(mfrow=c(1,1))

plot(chuva.ts.dif, ylab="Dif(Log(Chuva)) (mmm)",  main="Representação visual ARIMA (1,1,1)")              

lines(chuva.ts.dif-chuva.ts.dif.aj$resid, col="red")

O gráfico ilustra visualmente o modelo ajustado, onde temos em preto a série temporal diferenciada e em vermelho a série ajustada.

Previsão para os próximos 12 períodos com intervalos de confiança de 95%

require(forecast)

chuva.ts.dif.aj %>% forecast(h=12, level=95,) %>% plot()

O gráfico exibe a previsão da quantidade de chuva para os próximos 12 períodos, com intervalos de confiança de 95%. No primeiro mês da previsão, observa-se um aumento significativo na quantidade de chuva prevista, sugerindo condições mais úmidas. Nos meses seguintes, a previsão indica uma diminuição gradual na quantidade de chuva, seguida por uma estabilização, indicando que as condições de chuva devem permanecer relativamente constantes. Os intervalos de confiança de 95% fornecem uma faixa de variação na previsão, com alta certeza de que a quantidade de chuva estará dentro desses limites.

LS0tDQp0aXRsZTogIlByZXZpc8OjbyBkYSBjaHV2YSB1c2FuZG8gU2VyaWVzIFRlbXBvcmFpcyINCmF1dGhvcjogImJlbG90ZW1hdHNpbmhlQGdtYWlsLmNvbSINCm91dHB1dDoNCiBodG1sX25vdGVib29rOg0KICAgIHRvYzogZmFsc2UNCiAgICB0b2NfZmxvYXQ6DQogICAgICBjb2xsYXBzZWQ6IHRydWUNCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cNCiAgICBoaWdobGlnaHQ6IHplbmJ1cm4NCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMgRGVmaW5lIG8gdGVtYSwgZXN0aWxvIGRlIHJlYWxjZSBkZSBzaW50YXhlIGUgdGFtYW5obyBkZSBmb250ZQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KA0KdGhlbWUgPSAiY2VydWxlYW4iLA0KaGlnaGxpZ2h0ID0gInplbmJ1cm4iLA0KZmlnLndpZHRoID0gOCwNCmZpZy5oZWlnaHQgPSA2LA0KZmlnLmFsaWduID0gImNlbnRlciIsDQpkZXYgPSAicG5nIiwNCmRwaSA9IDMwMCwNCmZpZy5yZXRpbmEgPSAyDQopDQpgYGANCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMjIEluc3RhbGFjYW8gJiBDYXJyZWdhbWVudG8gZGUgUGFja2FnZXMNCg0KYGBge3J9DQppZiAoIXJlcXVpcmUoInRpZHl2ZXJzZSIsIGNoYXJhY3Rlci5vbmx5ID0gVFJVRSkpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcyh0aWR5dmVyc2UpDQogIH0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KaWYgKCFyZXF1aXJlKCJ1cmNhIiwgY2hhcmFjdGVyLm9ubHkgPSBUUlVFKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKHVyY2EpDQogIH0NCmxpYnJhcnkodXJjYSkNCmlmICghcmVxdWlyZSgiZm9yZWNhc3QiLCBjaGFyYWN0ZXIub25seSA9IFRSVUUpKXsNCiAgaW5zdGFsbC5wYWNrYWdlcyhmb3JlY2FzdCkNCiAgfQ0KbGlicmFyeShmb3JjYXN0KQ0KDQppZiAoIXJlcXVpcmUoInRzZXJpZXMiLCBjaGFyYWN0ZXIub25seSA9IFRSVUUpKSB7DQogIGluc3RhbGwucGFja2VnZXModHNlcmllcykNCiAgfQ0KbGlicmFyeSh0c2VyaWVzKQ0KaWYoIXJlcXVpcmUoIm91dGxpZXJzIiwgY2hhcmFjdGVyLm9ubHkgPSBUUlVFKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKG91dGxpZXJzKQ0KfQ0KbGlicmFyeShvdXRsaWVycykNCmBgYA0KDQojIyBJbXBvcnRhY2FvIGRvcyBEYWRvcw0KDQpgYGB7cn0NCnNldHdkKCJ+L0RBVEEgU0NJRU5DRVMgUFJPSkVDVFMvUiBQcm9qZWN0cy9FeGFtZSBzZXJpZXMgdGVtcG9yYWlzIikgIyBkZWZlaW5pY2FvIGRlIGRpcmVjdG9yaW8gZGUgdHJhYmFsaG8NCmNodXZhIDwtIHJlYWQudGFibGUoImNodXZhX2FudWFsLnR4dCIsIGhlYWRlciA9IFRSVUUpIHw+ICMgQ2FycmVnYW1lbnRvIGRvIGRhdGFzZXQNCiAgamFuaXRvcjo6Y2xlYW5fbmFtZXMoKQ0KYGBgDQoNCiMjIEVzdHJ1dHVyYQ0KDQpgYGB7cn0NCmhlYWQoY2h1dmEpICMgcHJpbWVpcmFzIGxpbmhhcw0KdGFpbChjaHV2YSkgIyB1bHRpbWFzIGxpbmhhcw0KZHBseXI6OmdsaW1wc2UoY2h1dmEpICMgZXN0cnV0dXJhIGdlcmFsDQoNCmBgYA0KDQojIyBMaW1wZXphDQoNCmBgYHtyfQ0KIyBJZGVudGlmaWNhciB2YWxvcmVzIGF1c2VudGVzDQpjaHV2YSB8PiANCiAgZHBseXI6OnN1bW1hcmlzZV9hbGwofnN1bShpcy5uYSguKSkpDQpgYGANCg0KTyByZXN1bHRhZG8gbW9zdHJhIHF1ZSBuYW8gaGEgdmFsb3JlcyBhdXNlbnRlcw0KDQpgYGB7cn0NCiMgaWRlbnRpZmljYXIgbGluaGFzIGR1cGxpY2FkYXMNCmNodXZhIHw+IA0KICBqYW5pdG9yOjpnZXRfZHVwZXMoKQ0KYGBgDQoNCk9zIHJlc3VsdGFkb3MgbW9zdHJhbSBxdWUgaGEgZHVhcyBsaW5oYXMgZHVwbGljYWRhcyBuYSBub3NzYSBiYXNlIGRlIGRhZG9zLCBtYXMgdHJhdGFuZG8tc2UgZGUgdW1hIHNlcmllIHRlbXBvcmFsIG5hbyBzZXJhIGZlaXRvIG5lbmh1bSB0cmF0YW1lbnRvIHBvaXMgcG9kZSBzZXIgY29tdW0gdW0gZW52ZW50byBzZSByZXBldGlyLg0KDQpgYGB7cn0NCiMgSWRlbnRpZmljYXIgT3V0bGllcnMNCmNodXZhIHw+DQogIGRwbHlyOjpzZWxlY3RfaWYoaXMubnVtZXJpYykgfD4gDQogIG91dGxpZXJzOjpvdXRsaWVyKCkNCiAgDQojIEZpbHRyYW5kbyBvdXRsaWVycw0KY2h1dmEgfD4gDQogIGRwbHlyOjpmaWx0ZXIoY2h1dmFfYW51YWxfbW0gIT0xNTAzKQ0KYGBgDQoNCmlkZW50aWZpY291X3NlIHF1ZSBxdWUgbyBvdXRsaWVyIG5hIGJhc2UgZGUgZGFkb3MgZSAxNTAzLCBlbnRhbyB1c291LXNlIG1ldG9kb3MgZGUgZmlsdHJhZ2VtIHBhcmEgcmVtb3ZlciBlc3NlIG91dGxpZXIuDQoNCiMjIFByZXNzdXBvc3Rvcw0KDQojIyMgVGVzdGUgZGUgbm9ybWFsaWRhZGUgZGUgU2hhcGlyb1dpbGsNCg0KLSAgICoqKkgwOioqKiBQLXZhbHVlIOKJpSAwLjUNCg0KLSAgICoqKkgxKioqKio6KiogUC12YWx1ZSBcPCAwLjUNCg0KYGBge3J9DQojIHRleHRlIGRlIG5vcm1hbGlkYWRlIGRlIFNoYXBpcm9XaWxrDQpzaGFwaXJvLnRlc3QoY2h1dmEkY2h1dmFfYW51YWxfbW0pDQoNCmBgYA0KDQpPcyByZXN1bHRhZG9zIG1vc3RyYW0gcXVlIG8gcC12YWxvciBlIGRlIDAuMDU5ODcsIGxvZ28gaGEgZXZpZGVuY2lhcyBzdWZpY2llbnRlcyBwYXJhIHJlamVqZWl0YXIgYSBoaXBvdGVzZSBudWxhIHF1ZSBkaXogcXVlIG9zIGRhZG9zIHNlZ3VlbSB1bWEgZGlzdHJpYmljYW8gbm9ybWFsICgqKipIMDoqKiogUC12YWx1ZSDiiaUgMC41KS4gdmFtb3MgdXNhciBvIGhpc3RvZ3JhbWEgcGFyYSB2aXN1YWxpemFyIGEgZGlzdHJpYnVpY2FvIGRvcyBkYWRvcy4NCg0KIyMjIEhpc3RvZ3JhbQ0KDQpgYGB7cn0NCmdncGxvdDI6OmdncGxvdChjaHV2YSwgYWVzKHg9Y2h1dmFfYW51YWxfbW0pKSArZ2VvbV9oaXN0b2dyYW0oYmlucz0xNSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw9Im9yYW5nZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0iYmxhY2siICkgK2dndGl0bGUoImhpc3RvZ3JhbWEgZGEgY2h1dmEgYW51YWwiKQ0KDQpgYGANCg0KTyBncsOhZmljbyBhY2ltYSDDqSB1bSBoaXN0b2dyYW1hIHF1ZSBhcHJlc2VudGEgYSBwcmVzZW50YSBkaXN0cmlidcOtw6fDo28gZG9zIGRhZG9zIGRlIENodXZhX0FudWFsLm1tLiBPIG1lc21vIG1vc3RyYSBxdWUgb3MgZGFkb3MgbsOjbyBhcHJlc2VudGFtIHVtYSBkaXN0cmlidcOtw6fDo28gbm9ybWFsIHBvaXMgaMOhIHVtYSBhc3NpbWV0cmlhIHBhcmEgbyBsYWRvIGVzcXVlcmRvLCBjb25maXJtYW5kbyBvIHRleHRlIGRlIFNoYXBpcm9XaWxrLg0KDQojIyBEZWNvbXBvc2nDp8OjbyBkYSBTZXJpZQ0KDQojIyBTYXpvbmFsaWRhZGUNCg0KYGBge3J9DQpwbG90LnRzKGNodXZhLCB5bGFiPSJGcmVxdcOqbmNpYSIsIG1haW49IkNodXZhIChtbSkiKQ0KDQpgYGANCg0KTyBncsOhZmljbyBhY2ltYSBpbHVzdHJhIGEgc8OpcmllIHRlbXBvcmFsIGRhZG9zIGRhZG9zLCBvIG1lc21vIG1vc3RyYSBzYXpvbmFsaWRhZGUgbm9zIGRhZG9zIGRlIGNodXZhLCBhcHJlc2VudGFuZG8gYWx0YXMgcmVjb3JlbnRlcyBlbSBhbGd1bnMgcGVyw61vZG9zICggMjAsIDQwLCA4MCwgNzApLiBOZXNzZSBjYXNvIGRldmUgc2UgZWZlY3R1ciBhIHRyYW5zZm9ybWHDp8OjbyBsb2dhcml0aW1pY2EgcGFyYSByZW1vY2FvIGRhIHNhem9uYWxpZGFkZSBub3MgZGFkb3MuDQoNCiMjIyBUcmFuc2Zvcm1hw6fDo28gbG9nYXJpdGltaWNhDQoNCmBgYHtyfQ0KY2h1dmEubG9nIDwtIGxvZyhjaHV2YSkNCmNodXZhLmxvZw0KYGBgDQoNCmBgYHtyfQ0KaGlzdChjaHV2YS5sb2ckY2h1dmFfYW51YWxfbW0sIHhsYWIgPSAiY2h1dmFfYW51YWxfbW0iLCANCiAgICAgeWxhYiA9ImZyZXF1w6puY2lhIiApDQpgYGANCg0KYGBge3J9DQojIyBHcmFmaWNvIGRhIHNlcmllIHRyYW5zZm9ybWFkYQ0KY2h1dmEudHM8LXRzKGNodXZhLmxvZywgc3RhcnQ9MTg5OCwgZnJlcT0xKQ0KY2h1dmEudHMNCnBsb3QudHMoY2h1dmEudHMsIHlsYWI9IkZyZXF1w6puY2lhIiwgbWFpbj0iQ2h1dmEgKG1tKSIpDQpgYGANCg0KTyBncsOhZmljbyBtb3N0cmEgYSBwZXJzaXN0ZW5jaWEgZGUgYWxndW1hIHRlbmTDqm5jaWEsIHBvciBpc3NvIGRldmUgc2UgZmF6ZXIgYSBzZWd1aXIgYSBkaWZmZXJlbmNpYcOnw6NvIHBhcmEgcmVtb8Onw6NvIGRhIHRlbmTDqm5jaWEgcXVlIHBlcnNpc3RlLg0KDQojIyBEaWZlcmVuY2lhw6fDo28NCg0KYGBge3J9DQpjaHV2YS50cy5kaWY8LWRpZmYoY2h1dmEudHMsMSkNCmNodXZhLnRzLmRpZg0KDQpwbG90KGNodXZhLnRzLmRpZiwgeWxhYj0iRGlmKExvZyhDaHV2YSkpIiwgbWFpbj0iQXBsaWNhw6fDo28gZGEgZGlmw6pybmNpYcOnw6NvIikNCiMjIERpc3RyaWJ1aWNhbyBkYSBzZXJpZSBkaWZlcmVuY2lhZGENCnFxbm9ybShjaHV2YS50cy5kaWYpDQpxcWxpbmUoY2h1dmEudHMuZGlmKQ0KYGBgDQoNCk8gZ3LDoWZpY28gbW9zdHJhIG8gUS1RIFBsb3QsIHVzYWRvIHBhcmEgdmVyaWZpY2FyIGEgZGlzdHJpYnXDrcOnw6NvIG5vcm1hbCwgbyBtZXNtbyBtb3N0cmEgcXVlIGEgc8OpcmllIGRpZmVyw6puY2lhZGEgdGVtIHVtYSBkaXN0cmlidcOtw6fDo28gbm9ybWFsLCBtYXMgY29tIGFsZ3VucyBwb3Vjb3MgdmFsb3JlcyBxdWUgbsOjbyBzZSBhanVzdGFtIHBlcmZlaXRhbWVudGUgYSByZWN0YS4NCg0KIyMjIEFuYWxpc2FyIGEgYXV0b2NvcnJlbGHDp8OjbyAoQUNGKSwgYXV0b2NvcnJlbGHDp8OjbyBwYXJjaWFsIChQQUNGKSBlIHNlbGVjaW9uYXIgb3MgdmFsb3JlcyBzaWduaWZpY2F0aXZvcyBkZSBwIGUgcSBkYSBzw6lyaWUNCg0KYGBge3J9DQpwYXIobWZyb3c9YygyLDIpKQ0KDQpwbG90KGFjZihjaHV2YS50cy5kaWYpKQ0KDQpwbG90KHBhY2YoY2h1dmEudHMuZGlmKSkNCmBgYA0KDQpPcyBncsOhZmljb3MgYWNpbWEsIGlsdXN0cmFtIGEgYXV0b2NvcmVsYcOnw6NvwqAgKEFDRikgZSBhdXRvY29scmVsYcOnw6NvIHBhcmNpYWwgKFBBQ0YpLiBOb3MgZ3LDoWZpY29zIGdlcmFkb3MsIGFzIGxpbmhhcyB0cmFjZWphZGFzIGF6dWlzIHPDo28gb3MgbGltaXRlcyBkZSBzaWduaWZpY8OibmNpYSBvdSBpbnRlcnZhbG9zIGRlIGNvbmZpYW7Dp2E7IHNlbXByZSBxdWUgaG91dmVyIHVtYSB1bHRyYXBhc3NhZ2VtLCBkaXotc2UgcXVlIGjDoSwgYWxpLCB1bSBwb250byBjb20gc2lnbmlmaWPDom5jaWEuIERpYW50ZSBkbyBleHBvc3RvIHBvZGUtc2UgZmFjaWxtZW50ZSBjb25jbHVpciBxdWUgdGFudG8gcGFyYSBBQ0YgZSBQQUNGIG9zIHZhbG9yZXMgc2lnbmlmaWNhdGl2b3Mgc8OjbyBlbmNpbnRyYWRvcyBuYSBwb3Npw6fDo28gMCwgc2VuZG8gYXNzaW0gdGVtb3Mgdm9sb3JlcyBkZSBwIGUgcSBkYSBzw6lyaWUgKDEsMSkuDQoNCiMjIyBBUklNQQ0KDQpgYGB7cn0NCmNodXZhLnRzLmRpZi5haiA8LWFyaW1hKGNodXZhLnRzLmRpZiwgb3JkZXIgPSBjKDEsMCwxKSwgaW5jbHVkZS5tZWFuID0gRkFMU0UpICAgICAjIyMgRnVuY2FvIGFtaW1hICh4LCBvcmRlbSAocCxxLGQpKSwgU2UgamEgZmV6IGFzIGRpZmVyZW5jaWFjb2VzIGZvcmEgbm8gbHVnYXIgZGUgcSBjb2xvY2EgemVybw0KY2h1dmEudHMuZGlmLmFqDQpgYGANCg0KTyBBSnVzdGFkby9Fc3RpbWFkbyDDqSBwZXJmZWl0byBwb2lzIGFwcmVzZW50YSB1bSBhaWMgcmVsYXRpdmFtZW50ZSBhbHRvDQoNCiMjIyBBbsOhbGlzYXIgb3MgcmVzw61kdW9zIHBhcmEgYWZlcmVpciBhcXVhbGlkYWRlIGRvIG1vZGVsbyBhanVzdGFkbw0KDQpgYGB7cn0NCnBhcihtZnJvdz1jKDIsMikpDQpwbG90KHJlc2lkKGNodXZhLnRzLmRpZi5haikpDQoNCnFxbm9ybShyZXNpZChjaHV2YS50cy5kaWYuYWopKQ0KcXFsaW5lKHJlc2lkKGNodXZhLnRzLmRpZi5haikpDQoNCmFjZihyZXNpZChjaHV2YS50cy5kaWYuYWopKQ0KcGFjZihyZXNpZChjaHV2YS50cy5kaWYuYWopKQ0KYGBgDQoNCiMjIyBSZXByZXNlbnRhw6fDo28gdmlzdWFsIGRvIG1vZGVsbyBhanVzdGFkbw0KDQpgYGB7cn0NCnBhcihtZnJvdz1jKDEsMSkpDQoNCnBsb3QoY2h1dmEudHMuZGlmLCB5bGFiPSJEaWYoTG9nKENodXZhKSkgKG1tbSkiLCAgbWFpbj0iUmVwcmVzZW50YcOnw6NvIHZpc3VhbCBBUklNQSAoMSwxLDEpIikgICAgICAgICAgICAgIA0KDQpsaW5lcyhjaHV2YS50cy5kaWYtY2h1dmEudHMuZGlmLmFqJHJlc2lkLCBjb2w9InJlZCIpDQpgYGANCg0KTyBncsOhZmljbyBpbHVzdHJhIHZpc3VhbG1lbnRlIG8gbW9kZWxvIGFqdXN0YWRvLCBvbmRlIHRlbW9zIGVtIHByZXRvIGEgc8OpcmllIHRlbXBvcmFsIGRpZmVyZW5jaWFkYSBlIGVtIHZlcm1lbGhvIGEgc8OpcmllIGFqdXN0YWRhLg0KDQojIyMgUHJldmlzw6NvIHBhcmEgb3MgcHLDs3hpbW9zIDEyIHBlcsOtb2RvcyBjb20gaW50ZXJ2YWxvcyBkZSBjb25maWFuw6dhIGRlIDk1JQ0KDQpgYGB7cn0NCnJlcXVpcmUoZm9yZWNhc3QpDQoNCmNodXZhLnRzLmRpZi5haiAlPiUgZm9yZWNhc3QoaD0xMiwgbGV2ZWw9OTUsKSAlPiUgcGxvdCgpDQpgYGANCg0KTyBncsOhZmljbyBleGliZSBhIHByZXZpc8OjbyBkYSBxdWFudGlkYWRlIGRlIGNodXZhIHBhcmEgb3MgcHLDs3hpbW9zIDEyIHBlcsOtb2RvcywgY29tIGludGVydmFsb3MgZGUgY29uZmlhbsOnYSBkZSA5NSUuIE5vIHByaW1laXJvIG3DqnMgZGEgcHJldmlzw6NvLCBvYnNlcnZhLXNlIHVtIGF1bWVudG8gc2lnbmlmaWNhdGl2byBuYSBxdWFudGlkYWRlIGRlIGNodXZhIHByZXZpc3RhLCBzdWdlcmluZG8gY29uZGnDp8O1ZXMgbWFpcyDDum1pZGFzLiBOb3MgbWVzZXMgc2VndWludGVzLCBhIHByZXZpc8OjbyBpbmRpY2EgdW1hIGRpbWludWnDp8OjbyBncmFkdWFsIG5hIHF1YW50aWRhZGUgZGUgY2h1dmEsIHNlZ3VpZGEgcG9yIHVtYSBlc3RhYmlsaXphw6fDo28sIGluZGljYW5kbyBxdWUgYXMgY29uZGnDp8O1ZXMgZGUgY2h1dmEgZGV2ZW0gcGVybWFuZWNlciByZWxhdGl2YW1lbnRlIGNvbnN0YW50ZXMuIE9zIGludGVydmFsb3MgZGUgY29uZmlhbsOnYSBkZSA5NSUgZm9ybmVjZW0gdW1hIGZhaXhhIGRlIHZhcmlhw6fDo28gbmEgcHJldmlzw6NvLCBjb20gYWx0YSBjZXJ0ZXphIGRlIHF1ZSBhIHF1YW50aWRhZGUgZGUgY2h1dmEgZXN0YXLDoSBkZW50cm8gZGVzc2VzIGxpbWl0ZXMuDQo=