Cel opracowania

Na moment pisania niniejszego opracowania od ponad szesciu miesiecy trwa epidemia koronawirusa. U jej początków, dzienna liczba zachorowań kształtowala się na poziomie ok 200-400 przypadków dziennie. W miarę zbliżania się do miesięcy jesiennych, liczba ta zaczęła rosnąć do ponad 3000 tysiecy przypadków dziennie. Większość państw, w tym Polska, podjęło szereg drastycznych środków, by ograniczyć rozmiary epidemii koronawirusa.

Jednak nawet oficjalne dane o zdrowiu publicznym, a także badania naukowe nad wirusami grypy skłaniają do zadania dwóch podstawowych pytań:

Aby spróbować odpowiedzieć na te pytania (z pominięciem kwestii, jaka jest definicja epidemii wg WHO - i czy w ogóle istenieje takowa) warto:

Dla zainteresowanych prześledzeniem poniższych rozważań, udostępniam kod w języku R służący do pobrania danych, ich przetworzenia i zaprezentowania.

Źródła danych

Badanie typowej krzywej przebiegu zachorowań na grypę w ciągu roku zostanie przeprowadzone na podstawie danych Państwowego Zakładu Higieny Narodowego Instytutu Zdrowia Publicznego. Dane te udostępnione są w formie dwutygodniowych raportów w formacie PDF na poprzedniej wersji strony tej instytucji. W 2020 roku NIZP rozpoczął udostępnianie danych poprzez serwisy EpiBaza i ProfiBaza (w trakcie rozwoju), lecz dane te są zagregowane i nie obejmują okresów śródrocznych. Stąd aby ustalić śródroczny przebieg zapadalności na wybrane choroby zakaźne w Polsce, trzeba sięgnąć do poprzedniej wersji strony. Dane do niniejszego opracowania zostały pobrane ze strony: http://wwwold.pzh.gov.pl/oldpage/epimeld/index_p.html

Zestaw danych zostanie przygotowany w dwóch krokach:

  1. dane zostaną pobrane w formie plików PDF
  2. z pobranych archiwów zostaną wyodrębnione dane dotyczące poszczególnych chorób.
# Wymagane biblioteki
library(rvest)
library(dplyr)

# Pobranie całego archiwum meldunków o zachorowaniach na choroby zakaźne, zakażeniach i zatruciach w Polsce (dwutygodniowe, kwartalne, półroczne, roczne)
url <- "http://wwwold.pzh.gov.pl/oldpage/epimeld/index_p.html"
pzholdwp <- read_html(url)
links <- pzholdwp %>% html_nodes("a") %>% html_attr("href")
links <- grep("index_mp.html$", links, value = TRUE)
links <- paste0("http://wwwold.pzh.gov.pl/oldpage/epimeld/",links)
yrs <- as.data.frame(stringr::str_extract(links, "\\d{4}"))
l2p <- data.frame()
for (i in 1:length(yrs[,1])){
url2 <- links[i]
pzhYR <- read_html(url2)
links2pdf <- pzhYR %>% html_nodes("a") %>% html_attr("href")
links2pdf <- grep("pdf$", links2pdf, value = TRUE)
links2pdf <- as.data.frame(paste0("http://wwwold.pzh.gov.pl/oldpage/epimeld/",yrs[i,],"/",links2pdf))
l2p <- rbind(l2p, links2pdf)
}
dir.create("pdf")
pth <- paste0(getwd(),"/pdf/")
for (i in 1:length(l2p[,1])){
fname <- stringr::str_sub(l2p[i,], -15, -1)
fname <- stringr::str_remove(fname, "[//]")
httr::GET(l2p[i,], httr::authenticate(":", ":", type="ntlm"),
          httr::write_disk(paste0(pth,fname), overwrite = FALSE),
          httr::progress()
          )
}

Na moment sporządzania tego raportu, na stronach PZH znajduje się 637 meldunków o zachorowaniach na choroby zakaźne, zakażeniach i zatruciach w Polsce (dwutygodniowe, kwartalne, półroczne, roczne). Zestaw danych będzie oparty o raporty dwutygodniowe, by dokładniej zamodelować trend śródroczny.

# "Scrapping" plików pdf
library(pdftools)
library(stringr)
# library(lubridate)
library(plotly)

lista_plikow <- list.files(path = "pdf/")
grypa <- data.frame()

for (i in 1:length(lista_plikow)){
text_rep_temp <- pdf_text(pdf = paste0("pdf/",lista_plikow[i]))
text_rep_temp <- c(unlist(strsplit(text_rep_temp, "\r\n")))
# write(text_rep_temp, file = "test.txt")
wanted_lines <- c(grep("Grypa",text_rep_temp)[1],
                  grep("zgłoszonych w okresie od |o zgłoszonych zachorowaniach za okres od",text_rep_temp)[1]
                  )
wanted <- text_rep_temp[get("wanted_lines")]
data_raportu <- str_extract(wanted[2], "\\d{2}.\\d{2}.\\d{4}")
data_raportu <- lubridate::dmy(data_raportu)
wanted[1]
ilosc_przyp <- as.numeric(str_extract(wanted[1], "\\s\\d+"))
wiersz <- data.frame(data_raportu, ilosc_przyp) 
grypa <- rbind(grypa, wiersz)
}

grypa <- grypa[complete.cases(grypa),]


#################################
# Dane po 2008 - zmiana formatu raportu (data jest we właściwościach pliku, dane o zachorowanian są prezentowane narastająco)

grypa08 <- data.frame()
for (i in 1:length(lista_plikow)){
text_rep_temp08 <- pdf_text(pdf = paste0("pdf/",lista_plikow[i]))
text_rep_temp08 <- c(unlist(strsplit(text_rep_temp08, "\r\n")))
wanted_lines08 <- c(grep("Grypa i podejrzenia",text_rep_temp08)[1]
                  )
wanted08_data_raportu <- pdf_info(pdf = paste0("pdf/",lista_plikow[i]))$keys$Title
wanted08 <- text_rep_temp08[get("wanted_lines08")]
data_raportu08 <- str_extract(wanted08_data_raportu, "\\d{2}.\\d{2}\\s\\d{4}|\\d{2}.\\d{2}.\\d{4}")
data_raportu08 <- lubridate::dmy(data_raportu08)
ilosc_przyp08 <- as.numeric(gsub("\\s","",(str_extract(wanted08[1], "(\\s\\d+){1,3}"))))
wiersz08 <- data.frame(data_raportu08, ilosc_przyp08) 
grypa08 <- rbind(grypa08, wiersz08)
}
grypa08 <- grypa08[complete.cases(grypa08),]

# obliczenie ilości nowych przypadków (uwaga na dane z końca roku)
nowe_pryp_08 <- diff(grypa08$ilosc_przyp08) 
nowe_pryp_08 <- c(grypa08[1,2],nowe_pryp_08)
grypa08 <- cbind(grypa08, nowe_pryp_08)

#poprawa danych z końca roku i pierwszego raportu z początku nowego roku
temp_ds <- subset(grypa08, nowe_pryp_08 <0)
temp_ds$nowe_pryp_08 <- temp_ds$ilosc_przyp08
grypa08a <- subset(grypa08, nowe_pryp_08 > 0)
grypa08a <- rbind(grypa08a, temp_ds)
grypa08a <- grypa08a[order(grypa08a$data_raportu08),]
grypa08a <- grypa08a[,c(1,3)]


# Połączenie danych do 2008 i po, w całość
cn <- colnames(grypa)
colnames(grypa08a) <- cn
grypa_calosc <- rbind(grypa, grypa08a)
grypa_calosc <- grypa_calosc[order(grypa_calosc$data_raportu),]

Po zebranu danych z plików pdf pobranych ze stron PZH, został utworzony zestaw danych zawierający ilość przypadków zachorowań na grypę w interwałach dwutygodniowych. Dane zawierają 580 obserwacji za okres od 1996-01-01 do 2020-09-30.

Analiza rozpoznawcza

Pierwsze spojrzenie na dane wyodrębnione z plików pdf:

Sezonowość dająca się zaobserwować jest oczywista. Niemniej odnośnie samego zestawu danych, trzeba zauważyć:

  1. dane ze stycznia 1996 roku zawierają najprawdopodoniej narastające dane z 1995 roku (wskazuje na to ilość zaraportowanych przypadków: 1 775 089),
  2. brak jest danych z pierwszej połowy 2009 roku,
  3. wzorzec raportowania danych w drugiej połowie lat 90tych XX w. i w pierwszych latach XXI w. wskazywał skokowy wzrost zachorowań w styczniu. Natomiast od roku 2010 widać, że ilość zaraportowanych przypadków rośnie stopniowo.

Z powyższego wynika, że do opracowania śródrocznego modelu zachorowań na grypę należy użyć danych po roku 2009, gdyż są one dokładniejsze.

Trendy długoterminowe prezentuje wykres rocznej ilości przypadków:

Wydaje się, że do dalszej analizy śródrocznego przebiegu zachorowań warto pobrać w pierwszym podejściu dane od roku 2013, w którym widać istotnie większą ilość (ok 3 mln) niż w latach poprzednich, kiedy roczna ilość przypadków kształtowała sie na pomiędzy 300 tys. a 1.5 mln.

Łącząc dwie powyższe obserwacje (dokładniejszy model raportowania po roku 2009 oraz większą liczbę rocznych zachorowań po roku 2013) dalsza analiza będzie oparta na danych z lat 2010-2019.

Śródroczny model zachorowań na grypę

Normalizacja danych do zakresu 0 - 1 będzie pierwszym krokiem budowy modelu. Normalizacja danych pozwoli przeanalizować przebieg zachorowań w ciągu roku z różnych lat, niezależnie od łącznej liczby przypadków. Dodatkową operacją na danych będzie przenumerowanie miesięcy w ten sposów, aby połączyć połówki lat w jeden sezon. Lipiec jest pierwszym miesiącem sezonu, czerwiec ostatnim. Normalizacja zostanie przeprowadzona na danych w obrębie jednego sezonu.

# Normalizacja danych

library(dplyr)
normalizacja <- function(x) {return ((x - min(x)) / (max(x) - min(x)))}
grypa_calosc_rrmm <- grypa_calosc %>% group_by(rok, msc) %>% summarise(suma_przypadkow = sum(ilosc_przyp))
grypa_calosc_rrmm$nr_miesiaca_sezon <- ifelse(grypa_calosc_rrmm$msc<=6, grypa_calosc_rrmm$msc+6, grypa_calosc_rrmm$msc-6)
grypa_calosc_rrmm <- grypa_calosc_rrmm %>% mutate(etykieta_sezonu = 
                                                    ifelse(nr_miesiaca_sezon <= 6, 
                                                           paste0(rok, "/",rok+1),
                                                           paste0(rok-1, "/",rok)
                                                           ))
grypa_calosc_rrmm$msc_nazwa <- month(grypa_calosc_rrmm$msc, label = TRUE)

norm_data <- grypa_calosc_rrmm %>% group_by(etykieta_sezonu) %>% summarise(suma_przypadkow_norm = normalizacja(suma_przypadkow))

grypa_calosc_rrmm$sum_przy_norm <- norm_data$suma_przypadkow_norm

Wybrane dane z lat 2008-2019 pokazują następujący przebieg zachorowalności na grypę w ciągu roku:

Jak widać, śródroczny przebieg grypy w poszczególnych sezonach - jak wspomniano na wstępnie - przypomina prawoskośną krzywą dzwonowatą rozkładu normalnego. Jednak poszczególne lata dość znacząco się od siebie różniły - szczególnie w miesiącach wrzesień - grudzień:

Miesiąc Współczynnik zmienności
wrz 0.38
paź 0.29
lis 0.28
gru 0.27

Zaprezentowany współczynnik zmienności to stosunek odchylenia standardowego do średniej. Zachorowania we wrześniu w poszczególnch latach różniły się od swojej średniej 38%. Niemniej ogólny przebieg sezonu grypowego w tych latach wskazuje na występowanie wyraźnego wzorca.

Drugim krokiem będzie dobranie odpowiedniej funkcji i jej parametrów, która jest najlepiej dopasowana do znormalizowanych danych. Na zestawie danych określonym powyżej, został zastosowany algorym Quantile Random Forest (metoda numeryczna), dzięki której po normalizacji wyznaczono typowy przebieg sezonu grypowego. 1 Ilustruje to poniższy wykres:

Z powyższego wykresu widać, że model dość dobrze odzwierciedla przebieg sezonu. W początkowej fazie wartości są niedoszacowane, jednak od miesiąca 6 do 10 znajdują się mniej więcej w środku obserwowanych wartości. Potwierdzają to także podstawowe parametry modelu (należy je czytać w kontekście przytoczonego powyżej współczynnika zmienności):

mtry RMSE Rsquared MAE RMSESD RsquaredSD MAESD
2 0.2598494 0.4511912 0.1803596 0.024928 0.0736318 0.0155539

Wartość Rsquared na poziomie 0.45 oznacza, że model wyjaśnia badane zjawisko w 45%. Wydawałoby się, że jest to słaby wynik. Jednak biorąc pod uwagę współczynnik zmienności kształtujący się pomiędzy 30% a 40% w poszczególnych miesiącach, wartość 45% dla modelu można uznać za satysfakcjonującą.

Prognoza QRF na sezon 2020 / 2021

Ponieważ cel niniejszego opracowania to budowa Śródrocznego modelu zachorowalności na grypę, nie zaś modelu wyjaśniającego czynniki decydujące o zachrowalności, prognoza na sezon 2020/2021 będzie wykonana uproszczonymi metodami. Wyjaśnienie przyczyn zjawiska zachorowalności to osobne zagadnienie. Prezentowane tutaj podejście jest podejściem czysto numerycznym, zatem dane zostaną potraktowane jako zwykłe szeregi czasowe.

Aby móc wykorzystać zbudowany model do prognozy zachrowań na grypę w sezonie 2020/2021 należy najpierw założyć, lub przewidzieć maksymalny poziom zachorowań w danym sezonie (najgorszy miesiąc w sezonie). Jest to potrzebne, by powrócić od danych znormalizowanych (z przedziału 0-1) do danych w skali pierwotnej (rzeczywistej). Dalej są zaprezentowane trzy scenariusze, by wyznaczyć maksymalny poziom zachorowań w sezonie. Podobnie jak w przypadku budowy śródrocznego modelu, prognoza będzie oparta na danych z lat 2010-2019. Do progozowania został użyty pakiet forecast a w jego ramach model ETS (Exponential smoothing state space model)2. Poniższa tabela prezentuje prognozę maksymalnej rocznej (sezonowej) ilości przypadków wraz z przedziałami ufności:

Point Forecast Lo 80 Hi 80
11 847383 521187.5 1173578

Prognozowana ilość zachorowań w szczycie sezonu 2020/2021 to 847,3 tys. osób. Z prawdopodobieństwem 80% można oczekiwać, że liczba zachorowań w szczycie, będzie mieścić się w przedziale: 521,2 do 1 173,6 tys. osób. Posługując się tą prognozą oraz modelem wyznaczonym w poprzednim punkcie, mozna wyznaczyć prawdopodobny przebieg sezonu grypowego:

Zgodnie z numerycznym modelem QRF, sezon grypowy 2020/2021 będzie miał swój szczyt w lutym 2021. Łaczna ilość zachorowań według wariantu pośredniego wyniesie 3 588 814.

Szczegółową prognozę w miesiącach prezentuje poniższa tabela:

Miesiąc Dzienne zachorowania, wariant minimalny Miesięcznie, wariant minimalny Dzienne zachorowania, wariant pośredni Miesięcznie, wariant pośredni Dzienne zachorowania, wariant maksymalny Miesięcznie, wariant maksymalny
lip 1362 40854 1401 42043 1441 43233
sie 1303 39096 1303 39096 1303 39096
wrz 1726 51767 2011 60340 2297 68914
paź 4988 149640 7481 224437 9974 299235
lis 7026 210780 10898 326946 14770 443112
gru 7508 225228 11706 351170 15904 477112
sty 11733 352002 18791 563723 25848 775443
lut 17373 521187 28246 847383 39119 1173578
mar 14238 427146 22990 689712 31743 952276
kwi 6315 189457 9707 291196 13098 392934
maj 2104 63118 2646 79372 3188 95626
cze 1985 59554 2447 73396 2908 87238

Wnioski dotyczące SARS-CoV-2

Odnosząc powyższe rozważania odnośnie zachorowalności na grypę, na epidemię koronawirusa, należy przytoczyć najważniejsze badania w tym zakresie. Badania te pozwolą oszacować, jaka ilość zachorowań może w rzeczywistości dotyczyć koronawirusa. Warto poznać:

  1. “Virus–virus interactions impact the population dynamics of influenza and the common cold”, PNAS December 26, 2019 116 (52) 27142-27150; first published December 16, 2019, Sema Nickbakhsh, Colette Mair, Louise Matthews, Richard Reeve, Paul C. D. Johnson, Fiona Thorburn, Beatrix von Wissmann, Arlene Reynolds, James McMenamin, Rory N. Gunson, and Pablo R. Murcia PNAS
  2. “Epidemiology of Seasonal Coronaviruses: Establishing the Context for the Emergence of Coronavirus Disease 2019”, The Journal of Infectious Diseases, 01 Jun 2020, 222(1):17-25, EUROPE PMC

Najważniejszy wniosek płynący z tych badań to:

udział koronawirusów w corocznych zachorowaniach na grypę wynosi od 7 do 15 procent

Dzięki tym badaniom oraz zbudowanej prognozie, można w prosty sposób wyznaczyć prawodopodobną liczbę zachorowań na koronawirusa zarówno w latach ubiegłych, jak i w sezonie 2020/2021. Przy wszystkich zastrzeżeniach, że obecny szczep koronawirusa jest inny od poprzednich, należy zauważyć, że nawet “sezonowe” koronawirusy różnią się od siebie. Biorąc pod uwagę nowoczesną wiedzę molekularną o wirusach, można z dość dużą pewnością stwierdzić, że koronawirus z początków 2020 roku zdążył w ciągu kilku miesięcy zmutować i już różni się od początkowej swojej wersji.

Sezon Suma zachorowań Zachorowania na koronawirusa (15%) Zachorowania na koronawirusa (7%)
2010/2011 1055300 158295 738710
2011/2012 1040955 156143 728668
2012/2013 2959318 443898 2071523
2013/2014 2724400 408660 1907080
2014/2015 3786125 567919 2650288
2015/2016 4050970 607646 2835679
2016/2017 4803745 720562 3362622
2017/2018 5431585 814738 3802109
2018/2019 4635847 695377 3245093
2019/2020 4103763 615564 2872634

Jak wynika z tej prostej kalkulacji, w sezonie 2019/2020 liczba chorych na koronawirusa wynosła pomiędzy 287,2 tys. a 615,5 tys. co daje średnią dzienną zachorowalność w ciągu sezonu między ok 800 a 1670 przypadków dziennie.

Model zachrowalności na grypę użyty do prognozy ilości przypadków koronawirusa w sezonie 2020/2021 wskazuje na następujący teoretyczny przebieg zachorowań (wg 15% udziału w infekcjach):

Według modelu pośredniego, we wrześniu powinno być wykryte 51,8 tys. przypadków grypy. w tym 8,8 tys. przypadków koronawirusa. Jak wynika z danych PZH we wrześniu wykryto 217,6 tys. przypadków grypy, w tym 26,1 tys. przypadków koronawirusa:

### Budowa zestawu danych dla sezonu 2020/2021 

grypa20 <- data.frame()
for (i in 1:length(lista_plikow)){
text_rep_temp20 <- pdf_text(pdf = paste0("pdf/",lista_plikow[i]))
text_rep_temp20 <- c(unlist(strsplit(text_rep_temp20, "\r\n")))
wanted_lines20 <- c(
                  grep("Zakażenia SARS-CoV-2",text_rep_temp20)[1]
                  )
wanted_lines20
wanted20_data_raportu <- pdf_info(pdf = paste0("pdf/",lista_plikow[i]))$keys$Title
wanted20 <- text_rep_temp20[get("wanted_lines20")]
data_raportu20 <- str_extract(wanted20_data_raportu, "\\d{2}.\\d{2}\\s\\d{4}|\\d{2}.\\d{2}.\\d{4}")
data_raportu20 <- lubridate::dmy(data_raportu20)
ilosc_przyp20 <- as.numeric(gsub("\\s","",(str_extract(wanted20[1], "(\\s\\d+){1,3}"))))
wiersz20 <- data.frame(data_raportu20, ilosc_przyp20) 
grypa20 <- rbind(grypa20, wiersz20)
}
grypa20 <- grypa20[complete.cases(grypa20),]

# obliczenie ilości nowych przypadków (covida, dane od lipca)
nowe_pryp_20 <- diff(grypa20$ilosc_przyp20) 
nowe_pryp_20 <- c(grypa20[1,2],nowe_pryp_20)
grypa20 <- cbind(grypa20, nowe_pryp_20)
grypa20 <- subset(grypa20, grypa20$data_raportu20 > "2020-06-30")
grypa20$msc <- month(grypa20$data_raportu20)
grypa20 <- grypa20 %>% group_by(msc) %>% summarise(suma_covid = sum(nowe_pryp_20))
gry2021 <- subset(grypa_calosc_rrmm, grypa_calosc_rrmm$etykieta_sezonu=="2020/2021"&grypa_calosc_rrmm$msc>6)
gry2021 <- gry2021[,c(1:6)]
gry2021 <- cbind(gry2021, grypa20$suma_covid)
gry2021$suma_przypadkow_z_cov <- gry2021$suma_przypadkow + gry2021$...7
Miesiąc Suma przypadków Grypa: pozostałe szczepy Grypa: koronawirus
lip 51331 39096 12235
sie 92087 70564 21523
wrz 217602 191476 26126

Udział koronawirusa w łącznej liczbie przypadków wynosi 12% i jest zgodny z obserwacjami i badaniami przytoczonymi powyżej: “Virus–virus interactions impact the population…” oraz “Epidemiology of Seasonal Coronaviruses: …”.

Rozwój zachorowań na grypę w sezonie 2020/2021 w porównaniu do modelu i ostatnich 5 lat wygląda na wykresie następująco:

Na powyższym wykresie wyraźnie widać dwie rzeczy:

  1. model teoretyczny zedycowanie niedoszacowuje rozwój zachorowań w początkowych miesiącach sezonu,
  2. sezon grypowy 2020/2021 jest zdecydowanie łagodniejszy niż sezony 2017/2018, 2018/2019, 2019/2020.

Na koniec niniejszego opracowania przytoczę jeszcze ostatni wykres, podobny jak poprzedni, tyle, że zawierający dane odnośnie zachorowań na grypę spowodowanych koronawirusem:

Dane historyczne odnośnie zachorowań są obliczone przy założeniu 15% udziału tego szczepu wirusa w ogólnych zachorowaniach. Sezon 2020/2021 jest nie tylko łagodniejszy (udział koronawirusa wynosi 12%) ale i ogólna liczba zachorowań jest znacząco mniejsza niż w latach ubiegłych.



  1. Journal of Machine Learning Research 7 (2006) 983–99, Nicolai Meinshausen “Quantile Regression Forests”.

  2. International Journal of Forecasting, Volume 18, Issue 3, July–September 2002, Pages 439-454, Rob J Hyndman, Anne B Koehler, Ralph D Snyder, Simone Grosea

LS0tDQp0aXRsZTogIsWacsOzZHJvY3pueSBtb2RlbCB6YXBhZGFsbm/Fm2NpIG5hIGdyeXDEmSINCmF1dGhvcjogIkJhcnRlayBCaWVsc2tpIg0KZGF0ZTogJzIwMjAtMTAtMDYnDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQojIyMgQ2VsIG9wcmFjb3dhbmlhDQoNCk5hIG1vbWVudCBwaXNhbmlhIG5pbmllanN6ZWdvIG9wcmFjb3dhbmlhIG9kIHBvbmFkIHN6ZXNjaXUgbWllc2llY3kgdHJ3YSAgZXBpZGVtaWEga29yb25hd2lydXNhLiBVIGplaiBwb2N6xIV0a8OzdywgZHppZW5uYSBsaWN6YmEgemFjaG9yb3dhxYQga3N6dGHFgnRvd2FsYSBzacSZIG5hIHBvemlvbWllIG9rIDIwMC00MDAgcHJ6eXBhZGvDs3cgZHppZW5uaWUuIFcgbWlhcsSZIHpibGnFvGFuaWEgc2nEmSBkbyBtaWVzacSZY3kgamVzaWVubnljaCwgbGljemJhIHRhIHphY3rEmcWCYSByb3NuxIXEhyBkbyBwb25hZCAzMDAwIHR5c2llY3kgcHJ6eXBhZGvDs3cgZHppZW5uaWUuIFdpxJlrc3pvxZvEhyBwYcWEc3R3LCB3IHR5bSBQb2xza2EsIHBvZGrEmcWCbyBzemVyZWcgZHJhc3R5Y3pueWNoIMWbcm9ka8OzdywgYnkgb2dyYW5pY3p5xIcgcm96bWlhcnkgZXBpZGVtaWkga29yb25hd2lydXNhLg0KDQpKZWRuYWsgbmF3ZXQgb2ZpY2phbG5lIGRhbmUgbyB6ZHJvd2l1IHB1YmxpY3pueW0sIGEgdGFrxbxlIGJhZGFuaWEgbmF1a293ZSBuYWQgd2lydXNhbWkgZ3J5cHkgc2vFgmFuaWFqxIUgZG8gemFkYW5pYSBkd8OzY2ggcG9kc3Rhd293eWNoIHB5dGHFhDoNCg0KLSBjenkgemphd2lza28gemFjaG9yb3dhxYQgbmEgU0FSUy1Db1YtMiBtb8W8bmEgdyBvZ8OzbGUgemFrbGFzeWZpa293YWMgamFrbyBlcGlkZW1pxJk/DQotIGplc2xpIG5pZSwgdG8gY3p5IG9iZWNuZSB6YWNob3Jvd2FuaWEgbmllIHPEhSBzdGHFgnltIHpqYXdpc2tpZW0sIG5pZSBkaWFnbm96b3dhbnltIHdjemXFm25pZWouDQoNCkFieSBzcHLDs2Jvd2HEhyBvZHBvd2llZHppZcSHIG5hIHRlIHB5dGFuaWEgKHogcG9taW5pxJljaWVtIGt3ZXN0aWksIGpha2EgamVzdCBkZWZpbmljamEgZXBpZGVtaWkgd2cgV0hPIC0gaSBjenkgdyBvZ8OzbGUgaXN0ZW5pZWplIHRha293YSkgd2FydG86DQoNCi0gemJhZGHEhyB0eXBvd8SFIGtyenl3xIUgcHJ6ZWJpZWd1IHphY2hvcm93YcWEIG5hIGdyeXDEmSB3IGNpxIVndSByb2t1LCANCi0gbmEgdGVqIHBvZHN0YXdpZSB6YnVkb3dhxIcgbW9kZWwgxZtyw7Nkcm9jem55Y2ggemFjaG9yb3dhxYQgbmEgZ3J5cMSZIG9yYXogDQotIHBvcsOzd25hxIcgZGFuZSBvIG9iZWNueWNoIHphY2hvcm93YW5pYWNoIG5hIGtvcm9uYXdpcnVzYSB6IGRhbnltaSBoaXN0b3J5Y3pueW1pIGkgeiBtb2RlbGVtLg0KDQpEbGEgemFpbnRlcmVzb3dhbnljaCBwcnplxZtsZWR6ZW5pZW0gcG9uacW8c3p5Y2ggcm96d2HFvGHFhCwgdWRvc3TEmXBuaWFtIGtvZCB3IGrEmXp5a3UgUiBzxYJ1xbzEhWN5IGRvIHBvYnJhbmlhIGRhbnljaCwgaWNoIHByemV0d29yemVuaWEgaSB6YXByZXplbnRvd2FuaWEuDQoNCiMjIyDFuXLDs2TFgmEgZGFueWNoDQoNCkJhZGFuaWUgdHlwb3dlaiBrcnp5d2VqIHByemViaWVndSB6YWNob3Jvd2HFhCBuYSBncnlwxJkgdyBjacSFZ3Ugcm9rdSB6b3N0YW5pZSBwcnplcHJvd2Fkem9uZSBuYSBwb2RzdGF3aWUgZGFueWNoIFBhxYRzdHdvd2VnbyBaYWvFgmFkdSBIaWdpZW55IE5hcm9kb3dlZ28gSW5zdHl0dXR1IFpkcm93aWEgUHVibGljem5lZ28uIERhbmUgdGUgdWRvc3TEmXBuaW9uZSBzxIUgdyBmb3JtaWUgZHd1dHlnb2RuaW93eWNoIHJhcG9ydMOzdyB3IGZvcm1hY2llIFBERiBuYSBwb3ByemVkbmllaiB3ZXJzamkgc3Ryb255IHRlaiBpbnN0eXR1Y2ppLiBXIDIwMjAgcm9rdSBOSVpQIHJvenBvY3rEhcWCIHVkb3N0xJlwbmlhbmllIGRhbnljaCBwb3ByemV6IHNlcndpc3kgRXBpQmF6YSBpIFByb2ZpQmF6YSAodyB0cmFrY2llIHJvendvanUpLCBsZWN6IGRhbmUgdGUgc8SFIHphZ3JlZ293YW5lIGkgbmllIG9iZWptdWrEhSBva3Jlc8OzdyDFm3LDs2Ryb2N6bnljaC4gU3TEhWQgYWJ5IHVzdGFsacSHIMWbcsOzZHJvY3pueSBwcnplYmllZyB6YXBhZGFsbm/Fm2NpIG5hIHd5YnJhbmUgY2hvcm9ieSB6YWthxbpuZSB3IFBvbHNjZSwgdHJ6ZWJhIHNpxJlnbsSFxIcgZG8gcG9wcnplZG5pZWogd2Vyc2ppIHN0cm9ueS4gRGFuZSBkbyBuaW5pZWpzemVnbyBvcHJhY293YW5pYSB6b3N0YcWCeSBwb2JyYW5lIHplIHN0cm9ueToNCmh0dHA6Ly93d3dvbGQucHpoLmdvdi5wbC9vbGRwYWdlL2VwaW1lbGQvaW5kZXhfcC5odG1sDQoNClplc3RhdyBkYW55Y2ggem9zdGFuaWUgcHJ6eWdvdG93YW55IHcgZHfDs2NoIGtyb2thY2g6DQoNCmEuIGRhbmUgem9zdGFuxIUgcG9icmFuZSB3IGZvcm1pZSBwbGlrw7N3IFBERiANCmIuIHogcG9icmFueWNoIGFyY2hpd8OzdyB6b3N0YW7EhSB3eW9kcsSZYm5pb25lIGRhbmUgZG90eWN6xIVjZSBwb3N6Y3plZ8OzbG55Y2ggY2hvcsOzYi4NCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgY2FjaGU9VFJVRX0NCiMgV3ltYWdhbmUgYmlibGlvdGVraQ0KbGlicmFyeShydmVzdCkNCmxpYnJhcnkoZHBseXIpDQoNCiMgUG9icmFuaWUgY2HFgmVnbyBhcmNoaXd1bSBtZWxkdW5rw7N3IG8gemFjaG9yb3dhbmlhY2ggbmEgY2hvcm9ieSB6YWthxbpuZSwgemFrYcW8ZW5pYWNoIGkgemF0cnVjaWFjaCB3IFBvbHNjZSAoZHd1dHlnb2RuaW93ZSwga3dhcnRhbG5lLCBww7PFgnJvY3puZSwgcm9jem5lKQ0KdXJsIDwtICJodHRwOi8vd3d3b2xkLnB6aC5nb3YucGwvb2xkcGFnZS9lcGltZWxkL2luZGV4X3AuaHRtbCINCnB6aG9sZHdwIDwtIHJlYWRfaHRtbCh1cmwpDQpsaW5rcyA8LSBwemhvbGR3cCAlPiUgaHRtbF9ub2RlcygiYSIpICU+JSBodG1sX2F0dHIoImhyZWYiKQ0KbGlua3MgPC0gZ3JlcCgiaW5kZXhfbXAuaHRtbCQiLCBsaW5rcywgdmFsdWUgPSBUUlVFKQ0KbGlua3MgPC0gcGFzdGUwKCJodHRwOi8vd3d3b2xkLnB6aC5nb3YucGwvb2xkcGFnZS9lcGltZWxkLyIsbGlua3MpDQp5cnMgPC0gYXMuZGF0YS5mcmFtZShzdHJpbmdyOjpzdHJfZXh0cmFjdChsaW5rcywgIlxcZHs0fSIpKQ0KbDJwIDwtIGRhdGEuZnJhbWUoKQ0KZm9yIChpIGluIDE6bGVuZ3RoKHlyc1ssMV0pKXsNCnVybDIgPC0gbGlua3NbaV0NCnB6aFlSIDwtIHJlYWRfaHRtbCh1cmwyKQ0KbGlua3MycGRmIDwtIHB6aFlSICU+JSBodG1sX25vZGVzKCJhIikgJT4lIGh0bWxfYXR0cigiaHJlZiIpDQpsaW5rczJwZGYgPC0gZ3JlcCgicGRmJCIsIGxpbmtzMnBkZiwgdmFsdWUgPSBUUlVFKQ0KbGlua3MycGRmIDwtIGFzLmRhdGEuZnJhbWUocGFzdGUwKCJodHRwOi8vd3d3b2xkLnB6aC5nb3YucGwvb2xkcGFnZS9lcGltZWxkLyIseXJzW2ksXSwiLyIsbGlua3MycGRmKSkNCmwycCA8LSByYmluZChsMnAsIGxpbmtzMnBkZikNCn0NCmRpci5jcmVhdGUoInBkZiIpDQpwdGggPC0gcGFzdGUwKGdldHdkKCksIi9wZGYvIikNCmZvciAoaSBpbiAxOmxlbmd0aChsMnBbLDFdKSl7DQpmbmFtZSA8LSBzdHJpbmdyOjpzdHJfc3ViKGwycFtpLF0sIC0xNSwgLTEpDQpmbmFtZSA8LSBzdHJpbmdyOjpzdHJfcmVtb3ZlKGZuYW1lLCAiWy8vXSIpDQpodHRyOjpHRVQobDJwW2ksXSwgaHR0cjo6YXV0aGVudGljYXRlKCI6IiwgIjoiLCB0eXBlPSJudGxtIiksDQogICAgICAgICAgaHR0cjo6d3JpdGVfZGlzayhwYXN0ZTAocHRoLGZuYW1lKSwgb3ZlcndyaXRlID0gRkFMU0UpLA0KICAgICAgICAgIGh0dHI6OnByb2dyZXNzKCkNCiAgICAgICAgICApDQp9DQpgYGANCk5hIG1vbWVudCBzcG9yesSFZHphbmlhIHRlZ28gcmFwb3J0dSwgbmEgc3Ryb25hY2ggUFpIIHpuYWpkdWplIHNpxJkgKio2MzcqKiBtZWxkdW5rw7N3IG8gemFjaG9yb3dhbmlhY2ggbmEgY2hvcm9ieSB6YWthxbpuZSwgemFrYcW8ZW5pYWNoIGkgemF0cnVjaWFjaCB3IFBvbHNjZSAoZHd1dHlnb2RuaW93ZSwga3dhcnRhbG5lLCBww7PFgnJvY3puZSwgcm9jem5lKS4gWmVzdGF3IGRhbnljaCBixJlkemllIG9wYXJ0eSBvIHJhcG9ydHkgZHd1dHlnb2RuaW93ZSwgYnkgZG9rxYJhZG5pZWogemFtb2RlbG93YcSHIHRyZW5kIMWbcsOzZHJvY3pueS4NCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgY2FjaGU9VFJVRX0NCiMgIlNjcmFwcGluZyIgcGxpa8OzdyBwZGYNCmxpYnJhcnkocGRmdG9vbHMpDQpsaWJyYXJ5KHN0cmluZ3IpDQojIGxpYnJhcnkobHVicmlkYXRlKQ0KbGlicmFyeShwbG90bHkpDQoNCmxpc3RhX3BsaWtvdyA8LSBsaXN0LmZpbGVzKHBhdGggPSAicGRmLyIpDQpncnlwYSA8LSBkYXRhLmZyYW1lKCkNCg0KZm9yIChpIGluIDE6bGVuZ3RoKGxpc3RhX3BsaWtvdykpew0KdGV4dF9yZXBfdGVtcCA8LSBwZGZfdGV4dChwZGYgPSBwYXN0ZTAoInBkZi8iLGxpc3RhX3BsaWtvd1tpXSkpDQp0ZXh0X3JlcF90ZW1wIDwtIGModW5saXN0KHN0cnNwbGl0KHRleHRfcmVwX3RlbXAsICJcclxuIikpKQ0KIyB3cml0ZSh0ZXh0X3JlcF90ZW1wLCBmaWxlID0gInRlc3QudHh0IikNCndhbnRlZF9saW5lcyA8LSBjKGdyZXAoIkdyeXBhIix0ZXh0X3JlcF90ZW1wKVsxXSwNCiAgICAgICAgICAgICAgICAgIGdyZXAoInpnxYJvc3pvbnljaCB3IG9rcmVzaWUgb2QgfG8gemfFgm9zem9ueWNoIHphY2hvcm93YW5pYWNoIHphIG9rcmVzIG9kIix0ZXh0X3JlcF90ZW1wKVsxXQ0KICAgICAgICAgICAgICAgICAgKQ0Kd2FudGVkIDwtIHRleHRfcmVwX3RlbXBbZ2V0KCJ3YW50ZWRfbGluZXMiKV0NCmRhdGFfcmFwb3J0dSA8LSBzdHJfZXh0cmFjdCh3YW50ZWRbMl0sICJcXGR7Mn0uXFxkezJ9LlxcZHs0fSIpDQpkYXRhX3JhcG9ydHUgPC0gbHVicmlkYXRlOjpkbXkoZGF0YV9yYXBvcnR1KQ0Kd2FudGVkWzFdDQppbG9zY19wcnp5cCA8LSBhcy5udW1lcmljKHN0cl9leHRyYWN0KHdhbnRlZFsxXSwgIlxcc1xcZCsiKSkNCndpZXJzeiA8LSBkYXRhLmZyYW1lKGRhdGFfcmFwb3J0dSwgaWxvc2NfcHJ6eXApIA0KZ3J5cGEgPC0gcmJpbmQoZ3J5cGEsIHdpZXJzeikNCn0NCg0KZ3J5cGEgPC0gZ3J5cGFbY29tcGxldGUuY2FzZXMoZ3J5cGEpLF0NCg0KDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMgRGFuZSBwbyAyMDA4IC0gem1pYW5hIGZvcm1hdHUgcmFwb3J0dSAoZGF0YSBqZXN0IHdlIHfFgmHFm2Npd2/Fm2NpYWNoIHBsaWt1LCBkYW5lIG8gemFjaG9yb3dhbmlhbiBzxIUgcHJlemVudG93YW5lIG5hcmFzdGFqxIVjbykNCg0KZ3J5cGEwOCA8LSBkYXRhLmZyYW1lKCkNCmZvciAoaSBpbiAxOmxlbmd0aChsaXN0YV9wbGlrb3cpKXsNCnRleHRfcmVwX3RlbXAwOCA8LSBwZGZfdGV4dChwZGYgPSBwYXN0ZTAoInBkZi8iLGxpc3RhX3BsaWtvd1tpXSkpDQp0ZXh0X3JlcF90ZW1wMDggPC0gYyh1bmxpc3Qoc3Ryc3BsaXQodGV4dF9yZXBfdGVtcDA4LCAiXHJcbiIpKSkNCndhbnRlZF9saW5lczA4IDwtIGMoZ3JlcCgiR3J5cGEgaSBwb2RlanJ6ZW5pYSIsdGV4dF9yZXBfdGVtcDA4KVsxXQ0KICAgICAgICAgICAgICAgICAgKQ0Kd2FudGVkMDhfZGF0YV9yYXBvcnR1IDwtIHBkZl9pbmZvKHBkZiA9IHBhc3RlMCgicGRmLyIsbGlzdGFfcGxpa293W2ldKSkka2V5cyRUaXRsZQ0Kd2FudGVkMDggPC0gdGV4dF9yZXBfdGVtcDA4W2dldCgid2FudGVkX2xpbmVzMDgiKV0NCmRhdGFfcmFwb3J0dTA4IDwtIHN0cl9leHRyYWN0KHdhbnRlZDA4X2RhdGFfcmFwb3J0dSwgIlxcZHsyfS5cXGR7Mn1cXHNcXGR7NH18XFxkezJ9LlxcZHsyfS5cXGR7NH0iKQ0KZGF0YV9yYXBvcnR1MDggPC0gbHVicmlkYXRlOjpkbXkoZGF0YV9yYXBvcnR1MDgpDQppbG9zY19wcnp5cDA4IDwtIGFzLm51bWVyaWMoZ3N1YigiXFxzIiwiIiwoc3RyX2V4dHJhY3Qod2FudGVkMDhbMV0sICIoXFxzXFxkKyl7MSwzfSIpKSkpDQp3aWVyc3owOCA8LSBkYXRhLmZyYW1lKGRhdGFfcmFwb3J0dTA4LCBpbG9zY19wcnp5cDA4KSANCmdyeXBhMDggPC0gcmJpbmQoZ3J5cGEwOCwgd2llcnN6MDgpDQp9DQpncnlwYTA4IDwtIGdyeXBhMDhbY29tcGxldGUuY2FzZXMoZ3J5cGEwOCksXQ0KDQojIG9ibGljemVuaWUgaWxvxZtjaSBub3d5Y2ggcHJ6eXBhZGvDs3cgKHV3YWdhIG5hIGRhbmUgeiBrb8WEY2Egcm9rdSkNCm5vd2VfcHJ5cF8wOCA8LSBkaWZmKGdyeXBhMDgkaWxvc2NfcHJ6eXAwOCkgDQpub3dlX3ByeXBfMDggPC0gYyhncnlwYTA4WzEsMl0sbm93ZV9wcnlwXzA4KQ0KZ3J5cGEwOCA8LSBjYmluZChncnlwYTA4LCBub3dlX3ByeXBfMDgpDQoNCiNwb3ByYXdhIGRhbnljaCB6IGtvxYRjYSByb2t1IGkgcGllcndzemVnbyByYXBvcnR1IHogcG9jesSFdGt1IG5vd2VnbyByb2t1DQp0ZW1wX2RzIDwtIHN1YnNldChncnlwYTA4LCBub3dlX3ByeXBfMDggPDApDQp0ZW1wX2RzJG5vd2VfcHJ5cF8wOCA8LSB0ZW1wX2RzJGlsb3NjX3ByenlwMDgNCmdyeXBhMDhhIDwtIHN1YnNldChncnlwYTA4LCBub3dlX3ByeXBfMDggPiAwKQ0KZ3J5cGEwOGEgPC0gcmJpbmQoZ3J5cGEwOGEsIHRlbXBfZHMpDQpncnlwYTA4YSA8LSBncnlwYTA4YVtvcmRlcihncnlwYTA4YSRkYXRhX3JhcG9ydHUwOCksXQ0KZ3J5cGEwOGEgPC0gZ3J5cGEwOGFbLGMoMSwzKV0NCg0KDQojIFBvxYLEhWN6ZW5pZSBkYW55Y2ggZG8gMjAwOCBpIHBvLCB3IGNhxYJvxZvEhw0KY24gPC0gY29sbmFtZXMoZ3J5cGEpDQpjb2xuYW1lcyhncnlwYTA4YSkgPC0gY24NCmdyeXBhX2NhbG9zYyA8LSByYmluZChncnlwYSwgZ3J5cGEwOGEpDQpncnlwYV9jYWxvc2MgPC0gZ3J5cGFfY2Fsb3NjW29yZGVyKGdyeXBhX2NhbG9zYyRkYXRhX3JhcG9ydHUpLF0NCmBgYA0KDQpQbyB6ZWJyYW51IGRhbnljaCB6IHBsaWvDs3cgcGRmIHBvYnJhbnljaCB6ZSBzdHJvbiBQWkgsIHpvc3RhxYIgdXR3b3J6b255IHplc3RhdyBkYW55Y2ggemF3aWVyYWrEhWN5IGlsb8WbxIcgcHJ6eXBhZGvDs3cgemFjaG9yb3dhxYQgbmEgZ3J5cMSZIHcgaW50ZXJ3YcWCYWNoIGR3dXR5Z29kbmlvd3ljaC4gRGFuZSB6YXdpZXJhasSFIDU4MCBvYnNlcndhY2ppIHphIG9rcmVzIG9kIDE5OTYtMDEtMDEgZG8gMjAyMC0wOS0zMC4NCg0KIyMjIEFuYWxpemEgcm96cG96bmF3Y3phDQoNClBpZXJ3c3plIHNwb2pyemVuaWUgbmEgZGFuZSB3eW9kcsSZYm5pb25lIHogcGxpa8OzdyBwZGY6DQpgYGB7ciBaYWNoLTJ3ZWVrcywgZWNobz1GQUxTRSwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgY2FjaGU9RkFMU0V9DQpsaWJyYXJ5KHBsb3RseSkNCnd5ayA8LSBwbG90X2x5KGRhdGE9Z3J5cGFfY2Fsb3NjLCB4ID0gfmRhdGFfcmFwb3J0dSAsIHkgPSB+aWxvc2NfcHJ6eXAsIHR5cGUgPSAnc2NhdHRlcicsIG1vZGUgPSAnbGluZXMnKQ0Kd3lrIDwtIHd5ayAlPiUgbGF5b3V0KHRpdGxlID0gIlphY2hvcm93YW5pYSBuYSBncnlwxJkgdyBsYXRhY2ggMTk5Ni0yMDIwIChkYW5lIGR3dXR5Z29kbmlvd2UpIiwNCiAgICAgICAgICAgICAgICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiUm9rIiksIHlheGlzID0gbGlzdCh0aXRsZSA9ICJJbG/Fm8SHIHphY2hvcm93YcWEIikNCiAgICAgICAgICAgICAgICAgICAgICApDQp3eWsNCmBgYA0KDQpTZXpvbm93b8WbxIcgZGFqxIVjYSBzacSZIHphb2JzZXJ3b3dhxIcgamVzdCBvY3p5d2lzdGEuIE5pZW1uaWVqIG9kbm/Fm25pZSBzYW1lZ28gemVzdGF3dSBkYW55Y2gsIHRyemViYSB6YXV3YcW8ecSHOg0KDQphLiBkYW5lIHplIHN0eWN6bmlhIDE5OTYgcm9rdSB6YXdpZXJhasSFIG5hanByYXdkb3BvZG9uaWVqIG5hcmFzdGFqxIVjZSBkYW5lIHogMTk5NSByb2t1ICh3c2thenVqZSBuYSB0byBpbG/Fm8SHIHphcmFwb3J0b3dhbnljaCBwcnp5cGFka8OzdzogMSA3NzUgMDg5KSwNCmIuIGJyYWsgamVzdCBkYW55Y2ggeiBwaWVyd3N6ZWogcG/Fgm93eSAyMDA5IHJva3UsDQpjLiB3em9yemVjIHJhcG9ydG93YW5pYSBkYW55Y2ggdyBkcnVnaWVqIHBvxYJvd2llIGxhdCA5MHR5Y2ggWFggdy4gaSB3IHBpZXJ3c3p5Y2ggbGF0YWNoIFhYSSB3LiB3c2thenl3YcWCIHNrb2tvd3kgd3pyb3N0IHphY2hvcm93YcWEIHcgc3R5Y3puaXUuIE5hdG9taWFzdCBvZCByb2t1IDIwMTAgd2lkYcSHLCDFvGUgaWxvxZvEhyB6YXJhcG9ydG93YW55Y2ggcHJ6eXBhZGvDs3cgcm/Fm25pZSBzdG9wbmlvd28uDQoNClogcG93ecW8c3plZ28gd3luaWthLCDFvGUgZG8gb3ByYWNvd2FuaWEgxZtyw7Nkcm9jem5lZ28gbW9kZWx1IHphY2hvcm93YcWEIG5hIGdyeXDEmSBuYWxlxbx5IHXFvHnEhyBkYW55Y2ggcG8gcm9rdSAyMDA5LCBnZHnFvCBzxIUgb25lIGRva8WCYWRuaWVqc3plLg0KDQpUcmVuZHkgZMWCdWdvdGVybWlub3dlIHByZXplbnR1amUgd3lrcmVzIHJvY3puZWogaWxvxZtjaSBwcnp5cGFka8OzdzoNCmBgYHtyIFphY2gteWVhcmx5LCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBjYWNoZT1GQUxTRX0NCmxpYnJhcnkobHVicmlkYXRlKQ0KbGlicmFyeShkcGx5cikNCmdyeXBhX2NhbG9zYyRyb2sgPC0geWVhcihncnlwYV9jYWxvc2MkZGF0YV9yYXBvcnR1KQ0KZ3J5cGFfY2Fsb3NjX3JvY3puaWUgPC0gZ3J5cGFfY2Fsb3NjICU+JSBncm91cF9ieShyb2spICU+JSBzdW1tYXJpc2Uoc3VtYV9wcnp5cGFka293ID0gc3VtKGlsb3NjX3ByenlwKSkNCmdyeXBhX2NhbG9zYyRtc2MgPC0gbW9udGgoZ3J5cGFfY2Fsb3NjJGRhdGFfcmFwb3J0dSkgDQp3eWsyIDwtIHBsb3RfbHkoZGF0YT1ncnlwYV9jYWxvc2Nfcm9jem5pZSwgeCA9IH5yb2sgLCB5ID0gfnN1bWFfcHJ6eXBhZGtvdywgdHlwZSA9ICdiYXInKQ0Kd3lrMiA8LSB3eWsyICU+JSBsYXlvdXQodGl0bGUgPSAiWmFjaG9yb3dhbmlhIG5hIGdyeXDEmSB3IGxhdGFjaCAxOTk2LTIwMjAgKHBvZHN1bW93YW5pZSByb2N6bmUpIiwNCiAgICAgICAgICAgICAgICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiUm9rIiksIHlheGlzID0gbGlzdCh0aXRsZSA9ICJJbG/Fm8SHIHphY2hvcm93YcWEIikNCiAgICAgICAgICAgICAgICAgICAgICApDQp3eWsyDQpgYGANCg0KV3lkYWplIHNpxJksIMW8ZSBkbyBkYWxzemVqIGFuYWxpenkgxZtyw7Nkcm9jem5lZ28gcHJ6ZWJpZWd1IHphY2hvcm93YcWEIHdhcnRvIHBvYnJhxIcgdyBwaWVyd3N6eW0gcG9kZWrFm2NpdSBkYW5lIG9kIHJva3UgMjAxMywgdyBrdMOzcnltIHdpZGHEhyBpc3RvdG5pZSB3acSZa3N6xIUgaWxvxZvEhyAob2sgMyBtbG4pIG5pxbwgdyBsYXRhY2ggcG9wcnplZG5pY2gsIGtpZWR5IHJvY3puYSBpbG/Fm8SHIHByenlwYWRrw7N3IGtzenRhxYJ0b3dhxYJhIHNpZSBuYSBwb21pxJlkenkgMzAwIHR5cy4gYSAxLjUgbWxuLiANCg0KxYHEhWN6xIVjIGR3aWUgcG93ecW8c3plIG9ic2Vyd2FjamUgKGRva8WCYWRuaWVqc3p5IG1vZGVsIHJhcG9ydG93YW5pYSBwbyByb2t1IDIwMDkgb3JheiB3acSZa3N6xIUgbGljemLEmSByb2N6bnljaCB6YWNob3Jvd2HFhCBwbyByb2t1IDIwMTMpIGRhbHN6YSBhbmFsaXphIGLEmWR6aWUgb3BhcnRhIG5hIGRhbnljaCB6IGxhdCAyMDEwLTIwMTkuDQoNCiMjIyDFmnLDs2Ryb2N6bnkgbW9kZWwgemFjaG9yb3dhxYQgbmEgZ3J5cMSZDQoNCk5vcm1hbGl6YWNqYSBkYW55Y2ggZG8gemFrcmVzdSAwIC0gMSBixJlkemllICoqcGllcndzenltKioga3Jva2llbSBidWRvd3kgbW9kZWx1LiBOb3JtYWxpemFjamEgZGFueWNoIHBvendvbGkgcHJ6ZWFuYWxpem93YcSHIHByemViaWVnIHphY2hvcm93YcWEIHcgY2nEhWd1IHJva3UgeiByw7PFvG55Y2ggbGF0LCBuaWV6YWxlxbxuaWUgb2QgxYLEhWN6bmVqICBsaWN6YnkgcHJ6eXBhZGvDs3cuIA0KRG9kYXRrb3fEhSBvcGVyYWNqxIUgbmEgZGFueWNoIGLEmWR6aWUgcHJ6ZW51bWVyb3dhbmllIG1pZXNpxJljeSB3IHRlbiBzcG9zw7N3LCBhYnkgcG/FgsSFY3p5xIcgcG/FgsOzd2tpIGxhdCB3IGplZGVuIHNlem9uLiBMaXBpZWMgamVzdCBwaWVyd3N6eW0gbWllc2nEhWNlbSBzZXpvbnUsIGN6ZXJ3aWVjIG9zdGF0bmltLiBOb3JtYWxpemFjamEgem9zdGFuaWUgcHJ6ZXByb3dhZHpvbmEgbmEgZGFueWNoIHcgb2JyxJliaWUgamVkbmVnbyBzZXpvbnUuDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGNhY2hlPVRSVUV9DQojIE5vcm1hbGl6YWNqYSBkYW55Y2gNCg0KbGlicmFyeShkcGx5cikNCm5vcm1hbGl6YWNqYSA8LSBmdW5jdGlvbih4KSB7cmV0dXJuICgoeCAtIG1pbih4KSkgLyAobWF4KHgpIC0gbWluKHgpKSl9DQpncnlwYV9jYWxvc2NfcnJtbSA8LSBncnlwYV9jYWxvc2MgJT4lIGdyb3VwX2J5KHJvaywgbXNjKSAlPiUgc3VtbWFyaXNlKHN1bWFfcHJ6eXBhZGtvdyA9IHN1bShpbG9zY19wcnp5cCkpDQpncnlwYV9jYWxvc2NfcnJtbSRucl9taWVzaWFjYV9zZXpvbiA8LSBpZmVsc2UoZ3J5cGFfY2Fsb3NjX3JybW0kbXNjPD02LCBncnlwYV9jYWxvc2NfcnJtbSRtc2MrNiwgZ3J5cGFfY2Fsb3NjX3JybW0kbXNjLTYpDQpncnlwYV9jYWxvc2NfcnJtbSA8LSBncnlwYV9jYWxvc2NfcnJtbSAlPiUgbXV0YXRlKGV0eWtpZXRhX3Nlem9udSA9IA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShucl9taWVzaWFjYV9zZXpvbiA8PSA2LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUwKHJvaywgIi8iLHJvaysxKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUwKHJvay0xLCAiLyIscm9rKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApKQ0KZ3J5cGFfY2Fsb3NjX3JybW0kbXNjX25hendhIDwtIG1vbnRoKGdyeXBhX2NhbG9zY19ycm1tJG1zYywgbGFiZWwgPSBUUlVFKQ0KDQpub3JtX2RhdGEgPC0gZ3J5cGFfY2Fsb3NjX3JybW0gJT4lIGdyb3VwX2J5KGV0eWtpZXRhX3Nlem9udSkgJT4lIHN1bW1hcmlzZShzdW1hX3ByenlwYWRrb3dfbm9ybSA9IG5vcm1hbGl6YWNqYShzdW1hX3ByenlwYWRrb3cpKQ0KDQpncnlwYV9jYWxvc2NfcnJtbSRzdW1fcHJ6eV9ub3JtIDwtIG5vcm1fZGF0YSRzdW1hX3ByenlwYWRrb3dfbm9ybQ0KDQpgYGANCg0KV3licmFuZSBkYW5lIHogbGF0IDIwMDgtMjAxOSBwb2thenVqxIUgbmFzdMSZcHVqxIVjeSBwcnplYmllZyB6YWNob3Jvd2Fsbm/Fm2NpIG5hIGdyeXDEmSB3IGNpxIVndSByb2t1Og0KYGBge3IgIHllYXJseV9ydW4sIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGNhY2hlPUZBTFNFLCByZXN1bHRzID0gJ2hpZGUnfQ0Kd3lrMyA8LSBwbG90X2x5KGRhdGEgPSBzdWJzZXQoZ3J5cGFfY2Fsb3NjX3JybW0sZ3J5cGFfY2Fsb3NjX3JybW0kZXR5a2lldGFfc2V6b251ICVpbiUgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoIjIwMTAvMjAxMSIsICIyMDExLzIwMTIiLCIyMDEyLzIwMTMiLCAiMjAxMy8yMDE0IiwgIjIwMTQvMjAxNSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjIwMTUvMjAxNiIsIjIwMTYvMjAxNyIsIjIwMTcvMjAxOCIsIjIwMTgvMjAxOSIsIjIwMTkvMjAyMCIpKVssYyg0OjcpXSwgDQogICAgICAgICAgICAgICAgeCA9IH5ucl9taWVzaWFjYV9zZXpvbiwNCiAgICAgICAgICAgICAgICB5ID0gfnN1bV9wcnp5X25vcm0sDQogICAgICAgICAgICAgICAgY29sb3IgPSB+ZXR5a2lldGFfc2V6b251LA0KICAgICAgICAgICAgICAgIHRleHQgPSB+bXNjX25hendhLCANCiAgICAgICAgICAgICAgICBob292ZXJpbmZvID0gJ3RleHQnDQogICAgICAgICAgICAgICAgKQ0Kd3lrMyA8LSB3eWszICU+JSAgYWRkX2xpbmVzKCkNCnd5azMgPC0gd3lrMyAlPiUgbGF5b3V0KHRpdGxlID0gIlphY2hvcm93YW5pYSBuYSBncnlwxJkgdyBsYXRhY2ggMjAxMC0yMDIwIChwb2RzdW1vd2FuaWUgc2V6b25vd2UpIiwNCiAgICAgICAgICAgICAgICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiTWllc2nEhWMgc2V6b251IGdyeXBvd2VnbyIpLCB5YXhpcyA9IGxpc3QodGl0bGUgPSAiSWxvxZvEhyB6YWNob3Jvd2HFhCAoem5vcm1hbGl6b3dhbmEpIikNCiAgICAgICAgICAgICAgICAgICAgICApDQp3eWszDQpgYGANCg0KSmFrIHdpZGHEhywgxZtyw7Nkcm9jem55IHByemViaWVnIGdyeXB5IHcgcG9zemN6ZWfDs2xueWNoIHNlem9uYWNoIC0gamFrIHdzcG9tbmlhbm8gbmEgd3N0xJlwbmllIC0gcHJ6eXBvbWluYSBwcmF3b3Nrb8WbbsSFIGtyenl3xIUgZHp3b25vd2F0xIUgcm96a8WCYWR1IG5vcm1hbG5lZ28uIEplZG5hayBwb3N6Y3plZ8OzbG5lIGxhdGEgZG/Fm8SHIHpuYWN6xIVjbyBzacSZIG9kIHNpZWJpZSByw7PFvG5pxYJ5IC0gc3pjemVnw7NsbmllIHcgbWllc2nEhWNhY2ggd3J6ZXNpZcWEIC0gZ3J1ZHppZcWEOiANCg0KYGBge3IgdmksIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHdhcm5pbmdzID0gRkFMU0UsIGNhY2hlPUZBTFNFLCByZXN1bHRzID0gJ2hpZGUnfQ0KbGlicmFyeShrYWJsZUV4dHJhKQ0KdmkgPC0gZGF0YS5mcmFtZSgpDQpmb3IgKGkgaW4gKDM6NikpIHsNCm1kcyA8LSBzdWJzZXQoZ3J5cGFfY2Fsb3NjX3JybW0sZ3J5cGFfY2Fsb3NjX3JybW0kZXR5a2lldGFfc2V6b251ICVpbiUgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoIjIwMTAvMjAxMSIsICIyMDExLzIwMTIiLCIyMDEyLzIwMTMiLCAiMjAxMy8yMDE0IiwgIjIwMTQvMjAxNSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjIwMTUvMjAxNiIsIjIwMTYvMjAxNyIsIjIwMTcvMjAxOCIsIjIwMTgvMjAxOSIsIjIwMTkvMjAyMCIpICYgZ3J5cGFfY2Fsb3NjX3JybW0kbnJfbWllc2lhY2Ffc2V6b24gPT0gaQ0KICAgICAgICAgICAgICApWyxjKDQ6NyldDQptZHNfdmkgPC0gcm91bmQoc2QobWRzJHN1bV9wcnp5X25vcm0pIC8gbWVhbihtZHMkc3VtX3Byenlfbm9ybSksMikNCm0gPC0gdW5pcXVlKGdyeXBhX2NhbG9zY19ycm1tW2dyeXBhX2NhbG9zY19ycm1tJG5yX21pZXNpYWNhX3Nlem9uID09IGksIDZdKSAgIA0KcnIgPC0gZGF0YS5mcmFtZShtZHNfdmksIG0pDQp2aSA8LSByYmluZCh2aSwgcnIpDQp9DQp2aSA8LSB2aVssYygyLDEpXQ0KY29sbmFtZXModmkpIDwtIGMoIk1pZXNpxIVjIiwgIldzcMOzxYJjenlubmlrIHptaWVubm/Fm2NpIikNCnZpIDwtIHZpICU+JSAgIGtibCgpICU+JQ0KICBrYWJsZV9taW5pbWFsKCJob3ZlciIsIGZ1bGxfd2lkdGggPSBGKQ0KdmkNCmBgYA0KWmFwcmV6ZW50b3dhbnkgd3Nww7PFgmN6eW5uaWsgem1pZW5ub8WbY2kgdG8gc3Rvc3VuZWsgb2RjaHlsZW5pYSBzdGFuZGFyZG93ZWdvIGRvIMWbcmVkbmllai4gWmFjaG9yb3dhbmlhIHdlIHdyemXFm25pdSB3IHBvc3pjemVnw7NsbmNoIGxhdGFjaCByw7PFvG5pxYJ5IHNpxJkgb2Qgc3dvamVqIMWbcmVkbmllaiAzOCUuIE5pZW1uaWVqIG9nw7NsbnkgcHJ6ZWJpZWcgc2V6b251IGdyeXBvd2VnbyB3IHR5Y2ggbGF0YWNoIHdza2F6dWplIG5hIHd5c3TEmXBvd2FuaWUgd3lyYcW6bmVnbyB3em9yY2EuDQoNCioqRHJ1Z2ltKioga3Jva2llbSBixJlkemllIGRvYnJhbmllIG9kcG93aWVkbmllaiBmdW5rY2ppIGkgamVqIHBhcmFtZXRyw7N3LCBrdMOzcmEgamVzdCBuYWpsZXBpZWogZG9wYXNvd2FuYSBkbyB6bm9ybWFsaXpvd2FueWNoIGRhbnljaC4gTmEgemVzdGF3aWUgZGFueWNoIG9rcmXFm2xvbnltIHBvd3nFvGVqLCB6b3N0YcWCIHphc3Rvc293YW55IGFsZ29yeW0gKipRdWFudGlsZSBSYW5kb20gRm9yZXN0KiogKG1ldG9kYSBudW1lcnljem5hKSwgZHppxJlraSBrdMOzcmVqIHBvIG5vcm1hbGl6YWNqaSB3eXpuYWN6b25vIHR5cG93eSBwcnplYmllZyBzZXpvbnUgZ3J5cG93ZWdvLiBbXjFdIElsdXN0cnVqZSB0byBwb25pxbxzenkgd3lrcmVzOg0KDQpgYGB7ciBtb2RlbCwgZWNobz1GQUxTRSwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgY2FjaGU9RkFMU0UsIHJlc3VsdHMgPSAnaGlkZSd9DQpsaWJyYXJ5KGNhcmV0KQ0Kc2V0LnNlZWQoOTk5KQ0KbTEgPC0gYXMuZGF0YS5mcmFtZSh4ID0gc2VxKDE6MTIpKQ0KY29sbmFtZXMobTEpIDwtIGMoIm5yX21pZXNpYWNhX3Nlem9uIikNCm0xJGV0eWtpZXRhX3Nlem9udSA8LSAibW9kZWwiDQptb2RlbCA8LSB0cmFpbihzdW1fcHJ6eV9ub3Jtfm5yX21pZXNpYWNhX3Nlem9uLCBkYXRhID0gZ3J5cGFfY2Fsb3NjX3JybW0sIG1ldGhvZCA9ICJxcmYiKQ0KDQptMSRzdW1fcHJ6eV9ub3JtIDwtIHByZWRpY3QobW9kZWwsIG5ld2RhdGEgPSBtMSkNCm0xJHN1bV9wcnp5X25vcm0gPC0gbm9ybWFsaXphY2phKG0xJHN1bV9wcnp5X25vcm0pDQoNCnd5azQgPC0gcGxvdF9seShkYXRhID0gc3Vic2V0KGdyeXBhX2NhbG9zY19ycm1tLGdyeXBhX2NhbG9zY19ycm1tJGV0eWtpZXRhX3Nlem9udSAlaW4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKCIyMDEwLzIwMTEiLCAiMjAxMS8yMDEyIiwiMjAxMi8yMDEzIiwgIjIwMTMvMjAxNCIsICIyMDE0LzIwMTUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIyMDE1LzIwMTYiLCIyMDE2LzIwMTciLCIyMDE3LzIwMTgiLCIyMDE4LzIwMTkiLCIyMDE5LzIwMjAiKSlbLGMoNDo3KV0sIA0KICAgICAgICAgICAgICAgIHggPSB+bnJfbWllc2lhY2Ffc2V6b24sDQogICAgICAgICAgICAgICAgeSA9IH5zdW1fcHJ6eV9ub3JtLA0KICAgICAgICAgICAgICAgIGNvbG9yID0gfmV0eWtpZXRhX3Nlem9udQ0KICAgICAgICAgICAgICAgICkNCnd5azQgPC0gd3lrNCAlPiUgIGFkZF9saW5lcygpDQp3eWs0IDwtIHd5azQgJT4lIGFkZF90cmFjZShkYXRhID0gbTEseSA9IH5tMSRzdW1fcHJ6eV9ub3JtICwgbmFtZSA9ICdNT0RFTCcsIHR5cGUgPSAnc2NhdHRlcicsIG1vZGUgPSAnbGluZXMnLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZSA9IGxpc3QoY29sb3IgPSAncmdiKDIyLCA5NiwgMTY3KScsIHdpZHRoID0gNiwgZGFzaCA9ICdkYXNoJykpDQoNCnd5azQgPC0gd3lrNCAlPiUgbGF5b3V0KHRpdGxlID0gIk1vZGVsIFFSRiB6YWNob3Jvd2HFhCBuYSBncnlwxJkiLA0KICAgICAgICAgICAgICAgICAgICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICJNaWVzacSFYyBzZXpvbnUgZ3J5cG93ZWdvIiksIHlheGlzID0gbGlzdCh0aXRsZSA9ICJJbG/Fm8SHIHphY2hvcm93YcWEICh6bm9ybWFsaXpvd2FuYSkiKQ0KICAgICAgICAgICAgICAgICAgICAgICkNCg0Kd3lrNA0KYGBgDQoNClogcG93ecW8c3plZ28gd3lrcmVzdSB3aWRhxIcsIMW8ZSBtb2RlbCBkb8WbxIcgZG9icnplIG9kendpZXJjaWVkbGEgcHJ6ZWJpZWcgc2V6b251LiBXIHBvY3rEhXRrb3dlaiBmYXppZSB3YXJ0b8WbY2kgc8SFIG5pZWRvc3phY293YW5lLCBqZWRuYWsgb2QgbWllc2nEhWNhIDYgZG8gMTAgem5hamR1asSFIHNpxJkgbW5pZWogd2nEmWNlaiB3IMWbcm9ka3Ugb2JzZXJ3b3dhbnljaCB3YXJ0b8WbY2kuIFBvdHdpZXJkemFqxIUgdG8gdGFrxbxlIHBvZHN0YXdvd2UgcGFyYW1ldHJ5IG1vZGVsdSAobmFsZcW8eSBqZSBjenl0YcSHIHcga29udGVrxZtjaWUgcHJ6eXRvY3pvbmVnbyBwb3d5xbxlaiB3c3DDs8WCY3p5bm5pa2Egem1pZW5ub8WbY2kpOg0KDQpgYGB7ciAgcXJmX21vZGVsLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCB3YXJuaW5ncyA9IEZBTFNFLCBjYWNoZT1GQUxTRSwgcmVzdWx0cyA9ICdoaWRlJ30NCmxpYnJhcnkoa2FibGVFeHRyYSkNCm1yIDwtIG1vZGVsJHJlc3VsdHMgJT4lICAga2JsKCkgJT4lDQogIGthYmxlX21pbmltYWwoImhvdmVyIiwgZnVsbF93aWR0aCA9IEYpDQptcg0KYGBgDQoNCldhcnRvxZvEhyBSc3F1YXJlZCBuYSBwb3ppb21pZSAwLjQ1IG96bmFjemEsIMW8ZSBtb2RlbCB3eWphxZtuaWEgYmFkYW5lIHpqYXdpc2tvIHcgNDUlLiBXeWRhd2HFgm9ieSBzacSZLCDFvGUgamVzdCB0byBzxYJhYnkgd3luaWsuIEplZG5hayBiaW9yxIVjIHBvZCB1d2FnxJkgd3Nww7PFgmN6eW5uaWsgem1pZW5ub8WbY2kga3N6dGHFgnR1asSFY3kgc2nEmSBwb21pxJlkenkgMzAlIGEgNDAlIHcgcG9zemN6ZWfDs2xueWNoIG1pZXNpxIVjYWNoLCB3YXJ0b8WbxIcgNDUlIGRsYSBtb2RlbHUgbW/FvG5hIHV6bmHEhyB6YSBzYXR5c2Zha2Nqb251asSFY8SFLg0KDQojIyMgUHJvZ25vemEgUVJGIG5hIHNlem9uIDIwMjAgLyAyMDIxDQoNClBvbmlld2HFvCBjZWwgbmluaWVqc3plZ28gb3ByYWNvd2FuaWEgdG8gYnVkb3dhICoqxZpyw7Nkcm9jem5lZ28gbW9kZWx1IHphY2hvcm93YWxub8WbY2kgbmEgZ3J5cMSZKiosIG5pZSB6YcWbIG1vZGVsdSB3eWphxZtuaWFqxIVjZWdvIGN6eW5uaWtpIGRlY3lkdWrEhWNlIG8gemFjaHJvd2Fsbm/Fm2NpLCBwcm9nbm96YSBuYSBzZXpvbiAyMDIwLzIwMjEgYsSZZHppZSB3eWtvbmFuYSB1cHJvc3pjem9ueW1pIG1ldG9kYW1pLiBXeWphxZtuaWVuaWUgcHJ6eWN6eW4gemphd2lza2EgemFjaG9yb3dhbG5vxZtjaSB0byBvc29ibmUgemFnYWRuaWVuaWUuIFByZXplbnRvd2FuZSB0dXRhaiBwb2RlasWbY2llIGplc3QgcG9kZWrFm2NpZW0gY3p5c3RvICoqbnVtZXJ5Y3pueW0qKiwgemF0ZW0gZGFuZSB6b3N0YW7EhSBwb3RyYWt0b3dhbmUgamFrbyB6d3lrxYJlIHN6ZXJlZ2kgY3phc293ZS4gDQoNCkFieSBtw7NjIHd5a29yenlzdGHEhyB6YnVkb3dhbnkgbW9kZWwgZG8gcHJvZ25venkgemFjaHJvd2HFhCBuYSBncnlwxJkgdyBzZXpvbmllIDIwMjAvMjAyMSBuYWxlxbx5IG5hanBpZXJ3IHphxYJvxbx5xIcsIGx1YiBwcnpld2lkemllxIcgbWFrc3ltYWxueSBwb3ppb20gemFjaG9yb3dhxYQgdyBkYW55bSBzZXpvbmllIChuYWpnb3JzenkgbWllc2nEhWMgdyBzZXpvbmllKS4gSmVzdCB0byBwb3RyemVibmUsIGJ5IHBvd3LDs2NpxIcgb2QgZGFueWNoIHpub3JtYWxpem93YW55Y2ggKHogcHJ6ZWR6aWHFgnUgMC0xKSBkbyBkYW55Y2ggdyBza2FsaSBwaWVyd290bmVqIChyemVjenl3aXN0ZWopLiBEYWxlaiBzxIUgemFwcmV6ZW50b3dhbmUgdHJ6eSBzY2VuYXJpdXN6ZSwgYnkgd3l6bmFjennEhyBtYWtzeW1hbG55IHBvemlvbSB6YWNob3Jvd2HFhCB3IHNlem9uaWUuIA0KUG9kb2JuaWUgamFrIHcgcHJ6eXBhZGt1IGJ1ZG93eSDFm3LDs2Ryb2N6bmVnbyBtb2RlbHUsIHByb2dub3phIGLEmWR6aWUgb3BhcnRhIG5hIGRhbnljaCB6IGxhdCAyMDEwLTIwMTkuIERvIHByb2dvem93YW5pYSB6b3N0YcWCIHXFvHl0eSBwYWtpZXQgYGZvcmVjYXN0YCBhIHcgamVnbyByYW1hY2ggbW9kZWwgRVRTIChFeHBvbmVudGlhbCBzbW9vdGhpbmcgc3RhdGUgc3BhY2UgbW9kZWwpW14yXS4gDQpQb25pxbxzemEgdGFiZWxhIHByZXplbnR1amUgcHJvZ25vesSZIG1ha3N5bWFsbmVqIHJvY3puZWogKHNlem9ub3dlaikgaWxvxZtjaSBwcnp5cGFka8OzdyB3cmF6IHogcHJ6ZWR6aWHFgmFtaSB1Zm5vxZtjaToNCg0KYGBge3IgcXJmX3Byb2duLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCB3YXJuaW5ncyA9IEZBTFNFLCBjYWNoZT1GQUxTRSwgcmVzdWx0cyA9ICdoaWRlJ30NCmxpYnJhcnkoZm9yZWNhc3QpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShrYWJsZUV4dHJhKQ0Kc2V0LnNlZWQoOTk5KQ0KZiA8LSBncnlwYV9jYWxvc2NfcnJtbSAlPiUgZ3JvdXBfYnkoZXR5a2lldGFfc2V6b251KSAlPiUgc3VtbWFyaXNlKG1heF9zZXpvbnUgPSBtYXgoc3VtYV9wcnp5cGFka293KSkNCmYgPC0gZltmJGV0eWtpZXRhX3Nlem9udSAlaW4lIGMoIjIwMTAvMjAxMSIsICIyMDExLzIwMTIiLCIyMDEyLzIwMTMiLCAiMjAxMy8yMDE0IiwgIjIwMTQvMjAxNSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjIwMTUvMjAxNiIsIjIwMTYvMjAxNyIsIjIwMTcvMjAxOCIsIjIwMTgvMjAxOSIsIjIwMTkvMjAyMCIpLF0NCiMgZiRldHlraWV0YV9zZXpvbnUgPC0gYXMuZmFjdG9yKGYkZXR5a2lldGFfc2V6b251KQ0KZnRzIDwtIGFzLnRzKGYkbWF4X3Nlem9udSkNCnByb2duX21heF9zZXpvbiA8LSBmb3JlY2FzdChmJG1heF9zZXpvbnUsIGg9MSwgbGV2ZWwgPSBjKDgwKSkNCnByb2duX21heF9zZXpvbiA8LSBhcy5kYXRhLmZyYW1lKHByb2duX21heF9zZXpvbikNCnQwIDwtIHByb2duX21heF9zZXpvbiAlPiUgICBrYmwoKSAlPiUNCiAga2FibGVfbWluaW1hbCgiaG92ZXIiLCBmdWxsX3dpZHRoID0gRikNCnQwDQpgYGANCg0KUHJvZ25vem93YW5hIGlsb8WbxIcgemFjaG9yb3dhxYQgdyBzemN6eWNpZSBzZXpvbnUgMjAyMC8yMDIxIHRvICoqODQ3LDMqKiB0eXMuIG9zw7NiLiBaIHByYXdkb3BvZG9iaWXFhHN0d2VtIDgwJSBtb8W8bmEgb2N6ZWtpd2HEhywgxbxlIGxpY3piYSB6YWNob3Jvd2HFhCAqKncgc3pjenljaWUqKiwgYsSZZHppZSBtaWXFm2NpxIcgc2nEmSB3IHByemVkemlhbGU6ICoqNTIxLDIqKiBkbyAqKjEgMTczLDYqKiB0eXMuIG9zw7NiLiBQb3PFgnVndWrEhWMgc2nEmSB0xIUgcHJvZ25vesSFIG9yYXogbW9kZWxlbSB3eXpuYWN6b255bSB3IHBvcHJ6ZWRuaW0gcHVua2NpZSwgbW96bmEgd3l6bmFjennEhyBwcmF3ZG9wb2RvYm55IHByemViaWVnIHNlem9udSBncnlwb3dlZ286DQoNCg0KYGBge3IgcHJvZ25fd3lrLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBjYWNoZT1GQUxTRSwgcmVzdWx0cyA9ICdoaWRlJ30NCmxpYnJhcnkocGxvdGx5KQ0KbGlicmFyeShsdWJyaWRhdGUpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpkZW5vcm1hbGl6YWNqYSA8LSBmdW5jdGlvbih4LCBteCwgbW4pIHtyZXR1cm4gKCh4KihteCAtIG1uKSkgKyBtbil9DQptbiA9IG1pbihncnlwYV9jYWxvc2NfcnJtbVtncnlwYV9jYWxvc2NfcnJtbSRldHlraWV0YV9zZXpvbnU9PSIyMDIwLzIwMjEiLF0kc3VtYV9wcnp5cGFka293KQ0KbXggPSByb3VuZChwcm9nbl9tYXhfc2V6b24kYFBvaW50IEZvcmVjYXN0YCwwKQ0KbXhsbyA9IHJvdW5kKHByb2duX21heF9zZXpvbiRgTG8gODBgLDApDQpteGhpID0gcm91bmQocHJvZ25fbWF4X3Nlem9uJGBIaSA4MGAsMCkNCg0KDQojIG5vcm1hbGl6YWNqYSA8LSBmdW5jdGlvbih4KSB7cmV0dXJuICgoeCAtIG1pbih4KSkgLyAobWF4KHgpIC0gbWluKHgpKSl9DQoNCm0xJHByb2dub3phX3NyIDwtIHJvdW5kKGRlbm9ybWFsaXphY2phKG0xJHN1bV9wcnp5X25vcm0sIG1uID0gbW4sIG14ID0gbXgpLDApDQptMSRwcm9nbm96YV9oaSA8LSByb3VuZChkZW5vcm1hbGl6YWNqYShtMSRzdW1fcHJ6eV9ub3JtLCBtbiA9IG1uLCBteCA9IG14aGkpLDApDQptMSRwcm9nbm96YV9sbyA8LSByb3VuZChkZW5vcm1hbGl6YWNqYShtMSRzdW1fcHJ6eV9ub3JtLCBtbiA9IG1uLCBteCA9IG14bG8pLDApDQptMSRwcm9nbm96YV9zcl9keiA8LSByb3VuZChkZW5vcm1hbGl6YWNqYShtMSRzdW1fcHJ6eV9ub3JtLCBtbiA9IG1uLCBteCA9IG14KS8zMCwwKQ0KbTEkcHJvZ25vemFfaGlfZHogPC0gcm91bmQoZGVub3JtYWxpemFjamEobTEkc3VtX3Byenlfbm9ybSwgbW4gPSBtbiwgbXggPSBteGhpKS8zMCwwKQ0KbTEkcHJvZ25vemFfbG9fZHogPC0gcm91bmQoZGVub3JtYWxpemFjamEobTEkc3VtX3Byenlfbm9ybSwgbW4gPSBtbiwgbXggPSBteGxvKS8zMCwwKQ0KDQoNCg0KDQptMSRucl9taWVzaWFjYSA8LSBpZmVsc2UobTEkbnJfbWllc2lhY2Ffc2V6b248PTYsIG0xJG5yX21pZXNpYWNhX3Nlem9uKzYsIG0xJG5yX21pZXNpYWNhX3Nlem9uLTYpDQptMSRtc2Nfa2FsZW5kIDwtIG1vbnRoKG0xJG5yX21pZXNpYWNhLCBsYWJlbCA9IFRSVUUpDQoNCnd5azYgPC0gcGxvdF9seShkYXRhID0gbTEsIHggPSB+bnJfbWllc2lhY2Ffc2V6b24sIHkgPSB+cHJvZ25vemFfc3IsIHRleHQgPSB+bXNjX2thbGVuZCwgaG9vdmVyaW5mbyA9ICd0ZXh0JywgbmFtZSA9ICd3YXJpYW50IHBvxZtyZWRuaScpDQp3eWs2IDwtIHd5azYgJT4lIGFkZF9saW5lcygpDQp3eWs2IDwtIHd5azYgJT4lIGFkZF90cmFjZSh5ID0gfnByb2dub3phX2xvLCB0eXBlID0gJ3NjYXR0ZXInLCBtb2RlID0gJ2xpbmVzJywNCiAgICAgICAgICAgIGZpbGwgPSAndG9uZXh0eScsIGZpbGxjb2xvcj0ncmdiYSgwLDEwMCw4MCwwLjIpJywgbGluZSA9IGxpc3QoY29sb3IgPSAndHJhbnNwYXJlbnQnKSwNCiAgICAgICAgICAgIHNob3dsZWdlbmQgPSBUUlVFLCBuYW1lID0gJ3dhcmlhbnQgbWluaW1hbG55JykgDQp3eWs2IDwtIHd5azYgJT4lIGFkZF90cmFjZSh5ID0gfnByb2dub3phX2hpLCB0eXBlID0gJ3NjYXR0ZXInLCBtb2RlID0gJ2xpbmVzJywNCiAgICAgICAgICAgIGZpbGwgPSAndG9uZXh0eScsIGZpbGxjb2xvcj0ncmdiYSgwLDEwMCw4MCwwLjIpJywgbGluZSA9IGxpc3QoY29sb3IgPSAndHJhbnNwYXJlbnQnKSwNCiAgICAgICAgICAgIHNob3dsZWdlbmQgPSBUUlVFLCBuYW1lID0gJ3dhcmlhbnQgbWFrc3ltYWxueScpIA0Kd3lrNiA8LSB3eWs2ICU+JSBsYXlvdXQodGl0bGUgPSAiUHJvZ25vemEgUVJGIHphY2hvcm93YcWEIG5hIGdyeXDEmSB3IHNlem9uaWUgMjAyMC8yMDIxIiwNCiAgICAgICAgICAgICAgICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiTWllc2nEhWMgc2V6b251IGdyeXBvd2VnbyIpLCB5YXhpcyA9IGxpc3QodGl0bGUgPSAiSWxvxZvEhyB6YWNob3Jvd2HFhCAoem5vcm1hbGl6b3dhbmEpIikNCiAgICAgICAgICAgICAgICAgICAgICApDQoNCnd5azYNCmBgYA0KDQpaZ29kbmllIHogbnVtZXJ5Y3pueW0gbW9kZWxlbSBRUkYsIHNlem9uIGdyeXBvd3kgMjAyMC8yMDIxIGLEmWR6aWUgbWlhxYIgc3fDs2ogc3pjenl0IHcgbHV0eW0gMjAyMS4gxYFhY3puYSBpbG/Fm8SHIHphY2hvcm93YcWEIHdlZMWCdWcgd2FyaWFudHUgcG/Fm3JlZG5pZWdvIHd5bmllc2llICoqMyA1ODggODE0KiouDQoNClN6Y3plZ8OzxYJvd8SFIHByb2dub3rEmSB3IG1pZXNpxIVjYWNoIHByZXplbnR1amUgcG9uacW8c3phIHRhYmVsYToNCmBgYHtyIHFyZl9wcm9nbl90YWJsZSwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgd2FybmluZ3MgPSBGQUxTRSwgY2FjaGU9RkFMU0UsIHJlc3VsdHMgPSAnaGlkZSd9DQpsaWJyYXJ5KGthYmxlRXh0cmEpDQp0YWJlbGEyIDwtIG0xWyxjKDExLDksNiw3LDQsOCw1KV0NCmNuMyA8LSBjKCJNaWVzacSFYyIsICJEemllbm5lIHphY2hvcm93YW5pYSwgd2FyaWFudCBtaW5pbWFsbnkiLCAiTWllc2nEmWN6bmllLCB3YXJpYW50IG1pbmltYWxueSINCiAgICAgICAgICwgIkR6aWVubmUgemFjaG9yb3dhbmlhLCB3YXJpYW50IHBvxZtyZWRuaSIsICJNaWVzacSZY3puaWUsIHdhcmlhbnQgcG/Fm3JlZG5pIg0KICAgICAgICAgLCAiRHppZW5uZSB6YWNob3Jvd2FuaWEsIHdhcmlhbnQgbWFrc3ltYWxueSIsICJNaWVzacSZY3puaWUsIHdhcmlhbnQgbWFrc3ltYWxueSIpDQpjb2xuYW1lcyh0YWJlbGEyKSA8LSBjbjMNCnRhYmVsYTIgPC0gdGFiZWxhMiAlPiUga2JsKCkgJT4lIGthYmxlX21pbmltYWwoImhvdmVyIiwgZnVsbF93aWR0aCA9IEYpDQp0YWJlbGEyDQpgYGANCg0KDQoNCiMjIyBXbmlvc2tpIGRvdHljesSFY2UgU0FSUy1Db1YtMg0KDQpPZG5vc3rEhWMgcG93ecW8c3plIHJvendhxbxhbmlhIG9kbm/Fm25pZSB6YWNob3Jvd2Fsbm/Fm2NpIG5hIGdyeXDEmSwgbmEgZXBpZGVtacSZIGtvcm9uYXdpcnVzYSwgbmFsZcW8eSBwcnp5dG9jennEhyBuYWp3YcW8bmllanN6ZSBiYWRhbmlhIHcgdHltIHpha3Jlc2llLiBCYWRhbmlhIHRlIHBvendvbMSFIG9zemFjb3dhxIcsIGpha2EgaWxvxZvEhyB6YWNob3Jvd2HFhCBtb8W8ZSB3IHJ6ZWN6eXdpc3RvxZtjaSBkb3R5Y3p5xIcga29yb25hd2lydXNhLiBXYXJ0byBwb3puYcSHOg0KDQoxLiAiVmlydXPigJN2aXJ1cyBpbnRlcmFjdGlvbnMgaW1wYWN0IHRoZSBwb3B1bGF0aW9uIGR5bmFtaWNzIG9mIGluZmx1ZW56YSBhbmQgdGhlIGNvbW1vbiBjb2xkIiwgUE5BUyBEZWNlbWJlciAyNiwgMjAxOSAxMTYgKDUyKSAyNzE0Mi0yNzE1MDsgZmlyc3QgcHVibGlzaGVkIERlY2VtYmVyIDE2LCAyMDE5LCBTZW1hIE5pY2tiYWtoc2gsIENvbGV0dGUgTWFpciwgTG91aXNlIE1hdHRoZXdzLCBSaWNoYXJkIFJlZXZlLCBQYXVsIEMuIEQuIEpvaG5zb24sIEZpb25hIFRob3JidXJuLCBCZWF0cml4IHZvbiBXaXNzbWFubiwgQXJsZW5lIFJleW5vbGRzLCBKYW1lcyBNY01lbmFtaW4sIFJvcnkgTi4gR3Vuc29uLCBhbmQgUGFibG8gUi4gTXVyY2lhIFtQTkFTXShodHRwczovL3d3dy5wbmFzLm9yZy9jb250ZW50LzExNi81Mi8yNzE0MikNCjIuICJFcGlkZW1pb2xvZ3kgb2YgU2Vhc29uYWwgQ29yb25hdmlydXNlczogRXN0YWJsaXNoaW5nIHRoZSBDb250ZXh0IGZvciB0aGUgRW1lcmdlbmNlIG9mIENvcm9uYXZpcnVzIERpc2Vhc2UgMjAxOSIsIFRoZSBKb3VybmFsIG9mIEluZmVjdGlvdXMgRGlzZWFzZXMsIDAxIEp1biAyMDIwLCAyMjIoMSk6MTctMjUsIFtFVVJPUEUgUE1DXShodHRwczovL2V1cm9wZXBtYy5vcmcvYXJ0aWNsZS9QTUMvNzE4NDQwND90ZXN0aW5nKQ0KDQpOYWp3YcW8bmllanN6eSB3bmlvc2VrIHDFgnluxIVjeSB6IHR5Y2ggYmFkYcWEIHRvOg0KDQoNCjxjZW50ZXI+DQoqKnVkemlhxYIga29yb25hd2lydXPDs3cgdyBjb3JvY3pueWNoIHphY2hvcm93YW5pYWNoIG5hIGdyeXDEmSB3eW5vc2kgb2QgNyBkbyAxNSBwcm9jZW50KioNCjwvY2VudGVyPg0KDQpEemnEmWtpIHR5bSBiYWRhbmlvbSBvcmF6IHpidWRvd2FuZWogcHJvZ25vemllLCBtb8W8bmEgdyBwcm9zdHkgc3Bvc8OzYiB3eXpuYWN6ecSHIHByYXdvZG9wb2RvYm7EhSBsaWN6YsSZIHphY2hvcm93YcWEIG5hIGtvcm9uYXdpcnVzYSB6YXLDs3dubyB3IGxhdGFjaCB1YmllZ8WCeWNoLCBqYWsgaSB3IHNlem9uaWUgMjAyMC8yMDIxLiBQcnp5IHdzenlzdGtpY2ggemFzdHJ6ZcW8ZW5pYWNoLCDFvGUgb2JlY255IHN6Y3plcCBrb3JvbmF3aXJ1c2EgamVzdCBpbm55IG9kIHBvcHJ6ZWRuaWNoLCBuYWxlxbx5IHphdXdhxbx5xIcsIMW8ZSBuYXdldCAic2V6b25vd2UiIGtvcm9uYXdpcnVzeSByw7PFvG5pxIUgc2nEmSBvZCBzaWViaWUuIEJpb3LEhWMgcG9kIHV3YWfEmSBub3dvY3plc27EhSB3aWVkesSZIG1vbGVrdWxhcm7EhSBvIHdpcnVzYWNoLCBtb8W8bmEgeiBkb8WbxIcgZHXFvMSFIHBld25vxZtjacSFIHN0d2llcmR6acSHLCDFvGUga29yb25hd2lydXMgeiBwb2N6xIV0a8OzdyAyMDIwIHJva3UgemTEhcW8ecWCIHcgY2nEhWd1IGtpbGt1IG1pZXNpxJljeSB6bXV0b3dhxIcgaSBqdcW8IHLDs8W8bmkgc2nEmSBvZCBwb2N6xIV0a293ZWogc3dvamVqIHdlcnNqaS4NCg0KDQpgYGB7ciBxcmZfcHJvZ25fdGFibGUyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCB3YXJuaW5ncyA9IEZBTFNFLCBjYWNoZT1GQUxTRSwgcmVzdWx0cyA9ICdoaWRlJ30NCmxpYnJhcnkoa2FibGVFeHRyYSkNCmxpYnJhcnkoZHBseXIpDQprb3dfbGF0YV91YmllZ2xlIDwtIGdyeXBhX2NhbG9zY19ycm1tW2dyeXBhX2NhbG9zY19ycm1tJGV0eWtpZXRhX3Nlem9udSAlaW4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKCIyMDEwLzIwMTEiLCAiMjAxMS8yMDEyIiwiMjAxMi8yMDEzIiwgIjIwMTMvMjAxNCIsICIyMDE0LzIwMTUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIyMDE1LzIwMTYiLCIyMDE2LzIwMTciLCIyMDE3LzIwMTgiLCIyMDE4LzIwMTkiLCIyMDE5LzIwMjAiKSxdICU+JSBncm91cF9ieShldHlraWV0YV9zZXpvbnUpICU+JSBzdW1tYXJpc2Uoc3VtYV9wcnp5cGFka293ID0gc3VtKHN1bWFfcHJ6eXBhZGtvdykpIA0Ka293X2xhdGFfdWJpZWdsZSA8LSBrb3dfbGF0YV91YmllZ2xlICU+JSBtdXRhdGUoa293X21heCA9IHJvdW5kKHN1bWFfcHJ6eXBhZGtvdyouMTUsMCkpICU+JSBtdXRhdGUoa293X21pbiA9IHJvdW5kKHN1bWFfcHJ6eXBhZGtvdyouNywwKSkNCmNuNCA8LSBjKCJTZXpvbiIsICJTdW1hIHphY2hvcm93YcWEIiwgIlphY2hvcm93YW5pYSBuYSBrb3JvbmF3aXJ1c2EgKDE1JSkiLCAiWmFjaG9yb3dhbmlhIG5hIGtvcm9uYXdpcnVzYSAoNyUpIikNCmNvbG5hbWVzKGtvd19sYXRhX3ViaWVnbGUpIDwtIGNuNA0Ka293X2xhdGFfdWJpZWdsZTIgPC0ga293X2xhdGFfdWJpZWdsZSAlPiUga2JsKCkgJT4lIGthYmxlX21pbmltYWwoImhvdmVyIiwgZnVsbF93aWR0aCA9IEYpDQprb3dfbGF0YV91YmllZ2xlMg0KYGBgDQoNCkphayB3eW5pa2EgeiB0ZWogcHJvc3RlaiBrYWxrdWxhY2ppLCB3IHNlem9uaWUgMjAxOS8yMDIwIGxpY3piYSBjaG9yeWNoIG5hIGtvcm9uYXdpcnVzYSB3eW5vc8WCYSBwb21pxJlkenkgKioyODcsMiB0eXMuKiogYSAqKjYxNSw1IHR5cy4qKiBjbyBkYWplIMWbcmVkbmnEhSBkemllbm7EhSB6YWNob3Jvd2Fsbm/Fm8SHIHcgY2nEhWd1IHNlem9udSBtacSZZHp5IG9rICoqODAwKiogYSAqKjE2NzAqKiBwcnp5cGFka8OzdyBkemllbm5pZS4NCg0KTW9kZWwgemFjaHJvd2Fsbm/Fm2NpIG5hIGdyeXDEmSB1xbx5dHkgZG8gcHJvZ25venkgaWxvxZtjaSBwcnp5cGFka8OzdyBrb3JvbmF3aXJ1c2EgdyBzZXpvbmllIDIwMjAvMjAyMSB3c2thenVqZSBuYSBuYXN0xJlwdWrEhWN5IHRlb3JldHljem55IHByemViaWVnIHphY2hvcm93YcWEICh3ZyAxNSUgdWR6aWHFgnUgdyBpbmZla2NqYWNoKToNCg0KYGBge3IgcHJvZ25fd3lrMiwgZWNobz1GQUxTRSwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgY2FjaGU9RkFMU0UsIHJlc3VsdHMgPSAnaGlkZSd9DQptMSRrb3dfbG8gPC0gcm91bmQobTEkcHJvZ25vemFfbG8qLjE1LDApDQptMSRrb3dfcG9zIDwtIHJvdW5kKG0xJHByb2dub3phX3NyKi4xNSwwKQ0KbTEka293X2hpIDwtIHJvdW5kKG0xJHByb2dub3phX2hpKi4xNSwwKQ0KDQp3eWs3IDwtIHd5azYgJT4lIGFkZF90cmFjZShkYXRhID0gbTEsIHkgPSB+a293X3BvcywgdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdsaW5lcycpDQoNCnd5azcgPC0gd3lrNyAlPiUgYWRkX3RyYWNlKGRhdGEgPSBtMSwgeSA9IH5rb3dfbG8sIHR5cGUgPSAnc2NhdHRlcicsIG1vZGUgPSAnbGluZXMnLA0KICAgICAgICAgICAgZmlsbCA9ICd0b25leHR5JywgZmlsbGNvbG9yPSdyZ2JhKDIwMCwwLDAsMC4yKScsIGxpbmUgPSBsaXN0KGNvbG9yID0gJ3RyYW5zcGFyZW50JyksDQogICAgICAgICAgICBzaG93bGVnZW5kID0gVFJVRSwgbmFtZSA9ICdLb3JvbmF3aXJ1czogd2FyaWFudCBtaW5pbWFsbnknKSANCg0Kd3lrNyA8LSB3eWs3ICU+JSBhZGRfdHJhY2UoZGF0YSA9IG0xLCB5ID0gfmtvd19oaSwgdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdsaW5lcycsDQogICAgICAgICAgICBmaWxsID0gJ3RvbmV4dHknLCBmaWxsY29sb3I9J3JnYmEoMjUwLDAsMCwwLjIpJywgbGluZSA9IGxpc3QoY29sb3IgPSAndHJhbnNwYXJlbnQnKSwNCiAgICAgICAgICAgIHNob3dsZWdlbmQgPSBUUlVFLCBuYW1lID0gJ0tvcm9uYXdpcnVzOiB3YXJpYW50IG1ha3N5bWFsbnknKSANCnd5azcgPC0gd3lrNyAlPiUgbGF5b3V0KHRpdGxlID0gIlByb2dub3phIFFSRiB6YWNob3Jvd2HFhCBuYSBncnlwxJksIHcgdHltIGtvcm9uYXdpcnVzYSB3IHNlem9uaWUgMjAyMC8yMDIxIiwNCiAgICAgICAgICAgICAgICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiTWllc2nEhWMgc2V6b251IGdyeXBvd2VnbyIpLCB5YXhpcyA9IGxpc3QodGl0bGUgPSAiSWxvxZvEhyB6YWNob3Jvd2HFhCAoem5vcm1hbGl6b3dhbmEpIikNCiAgICAgICAgICAgICAgICAgICAgICApDQoNCnd5azcNCiAgDQpgYGANCg0KV2VkxYJ1ZyBtb2RlbHUgcG/Fm3JlZG5pZWdvLCB3ZSB3cnplxZtuaXUgcG93aW5ubyBiecSHIHd5a3J5dGUgNTEsOCB0eXMuIHByenlwYWRrw7N3IGdyeXB5LiB3IHR5bSA4LDggdHlzLiBwcnp5cGFka8OzdyBrb3JvbmF3aXJ1c2EuIEphayB3eW5pa2EgeiBkYW55Y2ggUFpIIHdlIHdyemXFm25pdSB3eWtyeXRvIDIxNyw2IHR5cy4gcHJ6eXBhZGvDs3cgZ3J5cHksIHcgdHltIDI2LDEgdHlzLiBwcnp5cGFka8OzdyBrb3JvbmF3aXJ1c2E6DQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGNhY2hlPVRSVUV9DQojIyMgQnVkb3dhIHplc3Rhd3UgZGFueWNoIGRsYSBzZXpvbnUgMjAyMC8yMDIxIA0KDQpncnlwYTIwIDwtIGRhdGEuZnJhbWUoKQ0KZm9yIChpIGluIDE6bGVuZ3RoKGxpc3RhX3BsaWtvdykpew0KdGV4dF9yZXBfdGVtcDIwIDwtIHBkZl90ZXh0KHBkZiA9IHBhc3RlMCgicGRmLyIsbGlzdGFfcGxpa293W2ldKSkNCnRleHRfcmVwX3RlbXAyMCA8LSBjKHVubGlzdChzdHJzcGxpdCh0ZXh0X3JlcF90ZW1wMjAsICJcclxuIikpKQ0Kd2FudGVkX2xpbmVzMjAgPC0gYygNCiAgICAgICAgICAgICAgICAgIGdyZXAoIlpha2HFvGVuaWEgU0FSUy1Db1YtMiIsdGV4dF9yZXBfdGVtcDIwKVsxXQ0KICAgICAgICAgICAgICAgICAgKQ0Kd2FudGVkX2xpbmVzMjANCndhbnRlZDIwX2RhdGFfcmFwb3J0dSA8LSBwZGZfaW5mbyhwZGYgPSBwYXN0ZTAoInBkZi8iLGxpc3RhX3BsaWtvd1tpXSkpJGtleXMkVGl0bGUNCndhbnRlZDIwIDwtIHRleHRfcmVwX3RlbXAyMFtnZXQoIndhbnRlZF9saW5lczIwIildDQpkYXRhX3JhcG9ydHUyMCA8LSBzdHJfZXh0cmFjdCh3YW50ZWQyMF9kYXRhX3JhcG9ydHUsICJcXGR7Mn0uXFxkezJ9XFxzXFxkezR9fFxcZHsyfS5cXGR7Mn0uXFxkezR9IikNCmRhdGFfcmFwb3J0dTIwIDwtIGx1YnJpZGF0ZTo6ZG15KGRhdGFfcmFwb3J0dTIwKQ0KaWxvc2NfcHJ6eXAyMCA8LSBhcy5udW1lcmljKGdzdWIoIlxccyIsIiIsKHN0cl9leHRyYWN0KHdhbnRlZDIwWzFdLCAiKFxcc1xcZCspezEsM30iKSkpKQ0Kd2llcnN6MjAgPC0gZGF0YS5mcmFtZShkYXRhX3JhcG9ydHUyMCwgaWxvc2NfcHJ6eXAyMCkgDQpncnlwYTIwIDwtIHJiaW5kKGdyeXBhMjAsIHdpZXJzejIwKQ0KfQ0KZ3J5cGEyMCA8LSBncnlwYTIwW2NvbXBsZXRlLmNhc2VzKGdyeXBhMjApLF0NCg0KIyBvYmxpY3plbmllIGlsb8WbY2kgbm93eWNoIHByenlwYWRrw7N3IChjb3ZpZGEsIGRhbmUgb2QgbGlwY2EpDQpub3dlX3ByeXBfMjAgPC0gZGlmZihncnlwYTIwJGlsb3NjX3ByenlwMjApIA0Kbm93ZV9wcnlwXzIwIDwtIGMoZ3J5cGEyMFsxLDJdLG5vd2VfcHJ5cF8yMCkNCmdyeXBhMjAgPC0gY2JpbmQoZ3J5cGEyMCwgbm93ZV9wcnlwXzIwKQ0KZ3J5cGEyMCA8LSBzdWJzZXQoZ3J5cGEyMCwgZ3J5cGEyMCRkYXRhX3JhcG9ydHUyMCA+ICIyMDIwLTA2LTMwIikNCmdyeXBhMjAkbXNjIDwtIG1vbnRoKGdyeXBhMjAkZGF0YV9yYXBvcnR1MjApDQpncnlwYTIwIDwtIGdyeXBhMjAgJT4lIGdyb3VwX2J5KG1zYykgJT4lIHN1bW1hcmlzZShzdW1hX2NvdmlkID0gc3VtKG5vd2VfcHJ5cF8yMCkpDQpncnkyMDIxIDwtIHN1YnNldChncnlwYV9jYWxvc2NfcnJtbSwgZ3J5cGFfY2Fsb3NjX3JybW0kZXR5a2lldGFfc2V6b251PT0iMjAyMC8yMDIxIiZncnlwYV9jYWxvc2NfcnJtbSRtc2M+NikNCmdyeTIwMjEgPC0gZ3J5MjAyMVssYygxOjYpXQ0KZ3J5MjAyMSA8LSBjYmluZChncnkyMDIxLCBncnlwYTIwJHN1bWFfY292aWQpDQpncnkyMDIxJHN1bWFfcHJ6eXBhZGtvd196X2NvdiA8LSBncnkyMDIxJHN1bWFfcHJ6eXBhZGtvdyArIGdyeTIwMjEkLi4uNw0KDQpgYGANCg0KYGBge3IgcXJmX3Byb2duX3RhYmxlNCwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgd2FybmluZ3MgPSBGQUxTRSwgY2FjaGU9RkFMU0UsIHJlc3VsdHMgPSAnaGlkZSd9DQojIyMgVGFiZWxhIHogZGFueW0gc2V6b251IDIwMjAvMjAyMQ0KDQp0YWIyMDIxIDwtIGdyeTIwMjFbLGMoNiw4LDMsNyldDQpjbjUgPC0gYygiTWllc2nEhWMiLCAiU3VtYSBwcnp5cGFka8OzdyIsICJHcnlwYTogcG96b3N0YcWCZSBzemN6ZXB5IiwgIkdyeXBhOiBrb3JvbmF3aXJ1cyIpDQpjb2xuYW1lcyh0YWIyMDIxKSA8LSBjbjUNCnRhYjIwMjEgPC0gdGFiMjAyMSAlPiUga2JsKCkgJT4lIGthYmxlX21pbmltYWwoImhvdmVyIiwgZnVsbF93aWR0aCA9IEYpDQp0YWIyMDIxDQoNCmBgYA0KDQoNClVkemlhxYIga29yb25hd2lydXNhIHcgxYLEhWN6bmVqIGxpY3piaWUgcHJ6eXBhZGvDs3cgd3lub3NpIDEyJSBpIGplc3QgemdvZG55IHogb2JzZXJ3YWNqYW1pIGkgYmFkYW5pYW1pIHByenl0b2N6b255bWkgcG93ecW8ZWo6ICJWaXJ1c+KAk3ZpcnVzIGludGVyYWN0aW9ucyBpbXBhY3QgdGhlIHBvcHVsYXRpb24uLi4iIG9yYXogIkVwaWRlbWlvbG9neSBvZiBTZWFzb25hbCBDb3JvbmF2aXJ1c2VzOiAuLi4iLg0KDQpSb3p3w7NqIHphY2hvcm93YcWEIG5hIGdyeXDEmSB3IHNlem9uaWUgMjAyMC8yMDIxIHcgcG9yw7N3bmFuaXUgZG8gbW9kZWx1IGkgb3N0YXRuaWNoIDUgbGF0IHd5Z2zEhWRhIG5hIHd5a3Jlc2llIG5hc3TEmXB1asSFY286DQpgYGB7ciAgcHJvZ25fd3lrNCwgZWNobz1GQUxTRSwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgY2FjaGU9RkFMU0UsIHJlc3VsdHMgPSAnaGlkZSd9DQptY2UgPC0gYyg3LDgsOSkNCnNlem9ueV9hbmFsaXpvd2FuZSA8LSBjKCIyMDE0LzIwMTUiLCIyMDE1LzIwMTYiLCIyMDE3LzIwMTgiLCIyMDE4LzIwMTkiLCIyMDE5LzIwMjAiKQ0Ka3cxX3Nlem9udSA8LSBzdWJzZXQoZ3J5cGFfY2Fsb3NjX3JybW0sIChldHlraWV0YV9zZXpvbnUgJWluJSAgc2V6b255X2FuYWxpem93YW5lICYgbXNjICVpbiUgbWNlKSlbLGMoNSw2LDMpXQ0Ka3cxX3Nlem9udSA8LSBrdzFfc2V6b251ICU+JSBtdXRhdGUoImtvcm9uYXdpcnVzIiA9IHJvdW5kKHN1bWFfcHJ6eXBhZGtvdyouMTUsMCkpDQp0bXAgPC0gZ3J5MjAyMVssYyg1LDYsOCw3KV0NCmNuNiA8LSBjb2xuYW1lcyhrdzFfc2V6b251KQ0KY29sbmFtZXModG1wKSA8LSBjbjYNCiMga3cxX3Nlem9udSA8LSByYmluZChrdzFfc2V6b251LCB0bXApDQp0bXAyIDwtIG0xW20xJG5yX21pZXNpYWNhJWluJW1jZSxjKDIsMTEsNSwxNCldDQpjb2xuYW1lcyh0bXAyKSA8LSBjbjYNCiMgcm0odG1wKQ0Kd3lrOCA8LSBwbG90X2x5KGRhdGEgPSBrdzFfc2V6b251LCB4ID0gfm1zY19uYXp3YSwgeSA9IH5zdW1hX3ByenlwYWRrb3csIGNvbG9yID0gfmV0eWtpZXRhX3Nlem9udSkNCnd5azggPC0gd3lrOCAlPiUgYWRkX2xpbmVzKCkNCg0Kd3lrOCA8LSB3eWs4ICU+JSBhZGRfdHJhY2UoZGF0YSA9IHRtcCx5ID0gfnRtcCRzdW1hX3ByenlwYWRrb3cgLCBuYW1lID0gfmV0eWtpZXRhX3Nlem9udSwgdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdsaW5lcycsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lID0gbGlzdChjb2xvciA9ICdyZ2IoMjA1LCA5MiwgOTIpJywgd2lkdGggPSA2KSkNCnd5azggPC0gd3lrOCAlPiUgYWRkX3RyYWNlKGRhdGEgPSB0bXAyLHkgPSB+dG1wMiRzdW1hX3ByenlwYWRrb3cgLCBuYW1lID0gJ01PREVMJywgdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdsaW5lcycsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lID0gbGlzdChjb2xvciA9ICdyZ2IoMjIsIDk2LCAxNjcpJywgd2lkdGggPSA2LCBkYXNoID0gJ2Rhc2gnKSkNCnd5azggPC0gd3lrOCAlPiUgbGF5b3V0KHRpdGxlID0gIlphY2hvcm93YW5pYSBuYSBncnlwxJkgdyBzZXpvbmllIDIwMjAvMjAyMSB3IHN0b3N1bmt1IGRvIGxhdCB1YmllZ8WCeWNoIiwNCiAgICAgICAgICAgICAgICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiTWllc2nEhWMgc2V6b251IGdyeXBvd2VnbyIpLCB5YXhpcyA9IGxpc3QodGl0bGUgPSAiSWxvxZvEhyB6YWNob3Jvd2HFhCIpDQogICAgICAgICAgICAgICAgICAgICAgKQ0Kd3lrOA0KYGBgDQoNCk5hIHBvd3nFvHN6eW0gd3lrcmVzaWUgd3lyYcW6bmllIHdpZGHEhyBkd2llIHJ6ZWN6eToNCg0KMS4gbW9kZWwgdGVvcmV0eWN6bnkgemVkeWNvd2FuaWUgKipuaWVkb3N6YWNvd3VqZSoqIHJvenfDs2ogemFjaG9yb3dhxYQgdyBwb2N6xIV0a293eWNoIG1pZXNpxIVjYWNoIHNlem9udSwNCjIuIHNlem9uIGdyeXBvd3kgMjAyMC8yMDIxIGplc3QgKip6ZGVjeWRvd2FuaWUgxYJhZ29kbmllanN6eSoqIG5pxbwgc2V6b255IDIwMTcvMjAxOCwgMjAxOC8yMDE5LCAyMDE5LzIwMjAuDQoNCk5hIGtvbmllYyBuaW5pZWpzemVnbyBvcHJhY293YW5pYSBwcnp5dG9jesSZIGplc3pjemUgb3N0YXRuaSB3eWtyZXMsIHBvZG9ibnkgamFrIHBvcHJ6ZWRuaSwgdHlsZSwgxbxlIHphd2llcmFqxIVjeSBkYW5lIG9kbm/Fm25pZSB6YWNob3Jvd2HFhCBuYSBncnlwxJkgc3Bvd29kb3dhbnljaCBrb3JvbmF3aXJ1c2VtOg0KDQpgYGB7ciBwcm9nbl93eWs1LCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBjYWNoZT1GQUxTRSwgcmVzdWx0cyA9ICdoaWRlJ30NCnd5azkgPC0gcGxvdF9seShkYXRhID0ga3cxX3Nlem9udSwgeCA9IH5tc2NfbmF6d2EsIHkgPSB+a29yb25hd2lydXMsIGNvbG9yID0gfmV0eWtpZXRhX3Nlem9udSkNCnd5azkgPC0gd3lrOSAlPiUgYWRkX2xpbmVzKCkNCnd5azkgPC0gd3lrOSAlPiUgYWRkX3RyYWNlKGRhdGEgPSB0bXAseSA9IH50bXAka29yb25hd2lydXMgLCBuYW1lID0gfmV0eWtpZXRhX3Nlem9udSwgdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdsaW5lcycsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lID0gbGlzdChjb2xvciA9ICdyZ2IoMjU1LCAwLCAwKScsIHdpZHRoID0gNikpDQp3eWs5IDwtIHd5azkgJT4lIGxheW91dCh0aXRsZSA9ICJaYWNob3Jvd2FuaWEgbmEga29yb25hd2lydXNhIHcgMjAyMC8yMDIxIHcgc3Rvc3Vua3UgZG8gbGF0IHViaWVnxYJ5Y2giLA0KICAgICAgICAgICAgICAgICAgICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICJNaWVzacSFYyBzZXpvbnUgZ3J5cG93ZWdvIiksIHlheGlzID0gbGlzdCh0aXRsZSA9ICJJbG/Fm8SHIHphY2hvcm93YcWEIikNCiAgICAgICAgICAgICAgICAgICAgICApDQp3eWs5DQpgYGANCg0KRGFuZSBoaXN0b3J5Y3puZSBvZG5vxZtuaWUgemFjaG9yb3dhxYQgc8SFIG9ibGljem9uZSBwcnp5IHphxYJvxbxlbml1IDE1JSB1ZHppYcWCdSB0ZWdvIHN6Y3plcHUgd2lydXNhIHcgb2fDs2xueWNoIHphY2hvcm93YW5pYWNoLiBTZXpvbiAyMDIwLzIwMjEgamVzdCBuaWUgdHlsa28gxYJhZ29kbmllanN6eSAodWR6aWHFgiBrb3JvbmF3aXJ1c2Egd3lub3NpIDEyJSkgYWxlIGkgb2fDs2xuYSBsaWN6YmEgemFjaG9yb3dhxYQgamVzdCB6bmFjesSFY28gbW5pZWpzemEgbmnFvCB3IGxhdGFjaCB1YmllZ8WCeWNoLg0KDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KW14xXTogSm91cm5hbCBvZiBNYWNoaW5lIExlYXJuaW5nIFJlc2VhcmNoIDcgKDIwMDYpIDk4M+KAkzk5LCBOaWNvbGFpIE1laW5zaGF1c2VuICJRdWFudGlsZSBSZWdyZXNzaW9uIEZvcmVzdHMiLg0KW14yXTogSW50ZXJuYXRpb25hbCBKb3VybmFsIG9mIEZvcmVjYXN0aW5nLCBWb2x1bWUgMTgsIElzc3VlIDMsIEp1bHnigJNTZXB0ZW1iZXIgMjAwMiwgUGFnZXMgNDM5LTQ1NCwgUm9iIEogSHluZG1hbiwgQW5uZSBCIEtvZWhsZXIsIFJhbHBoIEQgU255ZGVyLCBTaW1vbmUgR3Jvc2VhDQo=