1 Informacja

Duża część tego materiału została zaadaptowana z Happy git with R autorstwa Jenny Bryan. To doskonałe źródło, ale zawiera wiele informacji, których nie potrzebujemy na tych zajęciach. Jeśli chcesz używać Gita i GitHuba w bardziej zaawansowany sposób lub jeśli moje instrukcje nie są wystarczająco jasne, zdecydowanie warto tam zajrzeć.

2 Samouczek wideo 1.

W pierwszym video-tutorialu pokazano jak zainstalować Git i skonfigurować go z R Studio.

Tutorial 1.

3 Samouczek wideo 2.

W drugim tutorialu pokazano, jak utworzyć repozytorium, sklonować je, dodać plik, zatwierdzić zmiany i wypchnąć je na GitHub (praca dwóch osób pracujących na jednym repo).


Tutorial 2.

4 Jak naprawić złą ścieżkę do Git?

Jeśli zauważysz, że coś nie działa, zacznij od sprawdzenia, czy masz prawidłową ścieżkę do Gita. W R Studio możesz to zrobić, zaglądając do zakładki Tools - Global Options - Git. Jeśli na komputerze Mac OS ustawiona została nieprawidłowa ścieżka, wykonaj kilka kroków, które pokazano na filmie: tutaj. W przypadku komputerów z Windowsem - po prostu wejdź w ten panel i wybierz prawidłową ścieżkę do Gita w Program Files/Git/bin/git.exe.

5 Git i GitHub

Git to system kontroli wersji. Jest podobny do Google Docs, ale obsługuje wiele typów plików, których Google Docs nie może … jak pliki .rmd! GitHub to interfejs online do pracy z Gitem.

Dlaczego uczymy się tych rzeczy?

  1. GitHub jest dobrze zintegrowany z R Studio. Nie będziemy więc musieli używać żadnych funkcji wiersza poleceń, przynajmniej nie po skonfigurowaniu wszystkiego.

  2. Wymagane jest użycie R do końcowego projektu. Prezentacja lub referat muszą być zapisane jako dokument .rmd, który można połączyć z dokumentem html. Korzystanie z GitHub pozwoli na łatwą pracę z grupą, nawet jeśli nie jesteście razem.

  3. GitHub uczy dobrych nawyków. Jesteś zmuszony do myślenia o tym, kiedy zapisujesz i do robienia notatek o tym, jakie zmiany wprowadziłeś za każdym razem, gdy to robisz.

6 Utwórz konto GitHub

  • Przejdź do http://github.com i utwórz konto.
  • Utwórz nazwę użytkownika … zobacz [wskazówki] Jenny Bryan (https://happygitwithr.com/github-acct.html). Uwzględnij swoje rzeczywiste imię i nazwisko, użyj innej nazwy użytkownika, którą już posiadasz, * wybierz nazwę użytkownika, którą będziesz mógł ujawnić przyszłemu szefowi*.

7 Zainstaluj i skonfiguruj Git

  1. Sprawdź, czy masz już zainstalowany Git. Będzie to miało miejsce tylko wtedy, gdy używałeś go gdzie indziej. Aby to zrobić, otwórz terminal lub w R Studio rozwiń konsolę. Powinna tam być zakładka Terminal. W tym obszarze wpisz:
which git

Jeśli zwróci to coś takiego jak

/usr/bin/git

wtedy skończyłeś i nie musisz instalować Gita.

Na komputerze z systemem Windows możesz nawet nie być w stanie pomyślnie wpisać polecenia which git. Powinno to zostać naprawione przez zainstalowanie git. Albo będziesz musiał użyć powłoki. Możesz także spróbować wpisać where git.

  1. Jeśli nie masz zainstalowanego Gita, musisz go zainstalować. Instrukcje są nieco inne dla systemów Windows i Mac.

W systemie Windows:

  • Zainstaluj Git dla Windows. Gdy pojawi się pytanie o „Dostosowanie środowiska PATH”, upewnij się, że wybrano opcję „Git z wiersza poleceń, a także z oprogramowania innych firm”. W przeciwnym razie uważamy, że dobrze jest zaakceptować wartości domyślne.
  • R Studio dla Windows preferuje, aby Git był zainstalowany poniżej C:/Program Files i wydaje się, że jest to ustawienie domyślne. Oznacza to na przykład, że plik wykonywalny Git w moim systemie Windows znajduje się w C:/Program Files/Git/bin/git.exe. O ile nie masz szczególnych powodów, aby postąpić inaczej, postępuj zgodnie z tą konwencją.

Na Macu:

  • Przejdź do shell/terminal i wprowadź jedno z tych poleceń, aby wyświetlić ofertę instalacji narzędzi wiersza poleceń dla programistów. Zaakceptuj ofertę … kliknij zainstaluj.
git --version
git config
  • Niektórzy użytkownicy komputerów Mac mogą być zmuszeni do wykonania poniższych czynności w terminalu, jeśli próba otwarcia projektu zakończy się niepowodzeniem. Za chwilę dowiesz się, czy tak jest w tym przypadku.
xcode-select --install
  1. Teraz wróć do Console w R Studio i zainstaluj pakiet usethis w R Studio. Następnie zamknij R Studio i otwórz je ponownie.

  2. Załaduj bibliotekę usethis uruchamiając następujący fragment kodu w konsoli:

library(usethis)
  1. Uruchom poniższy kod w console z kilkoma drobnymi zmianami. user.name to nazwa użytkownika Git. Może się ona różnić od nazwy użytkownika GitHub, choć dobrym pomysłem może być pozostawienie jej takiej samej. Adres user.email MUSI być taki sam jak adres e-mail użytkownika GitHub.
use_git_config(user.name = „Jane Doe”, user.email = „jane@example.org”)

8 Skonfiguruj PAT

PAT, czyli Personal Access Token, jest teraz niezbędny (lub będzie wkrótce), aby RStudio i GitHub mogły ze sobą rozmawiać. Jenny Bryan omawia to w rozdziale 10 Happy Git with R, a David Keyes omawia to w swoim poście na blogu How to Use Git/Github with R (zobacz sekcję Connect RStudio and GitHub).

  1. Najpierw uruchom funkcję create_github_token() z biblioteki usethis w konsoli. Spowoduje to przejście do witryny GitHub, gdzie można utworzyć token - przechowuj go w bezpiecznym miejscu i nie zgub go! Będziesz go potrzebować za chwilę i być może kiedyś w odległej przyszłości.
  2. Zainstaluj pakiet gitcreds w RStudio i załaduj bibliotekę używając library(gitcreds) (możesz to zrobić w konsoli).
  3. Uruchom funkcję gitcreds_set() w konsoli. Jeśli masz dostępne opcje, wybierz opcję Zastąp te dane uwierzytelniające, a następnie wklej PAT, który właśnie utworzyłeś w poprzednim kroku.
  4. Podczas następnego zatwierdzania i wypychania może nadal pytać o nazwę użytkownika i hasło github, użyj PAT, gdy zapyta o hasło !!! .

Daj mi znać, jeśli masz problemy z którymkolwiek z tych kroków. Moją pierwszą sugestią zawsze będzie ponowne uruchomienie komputera. Niestety, kiedyś spędziłem dwie godziny próbując debugować błędy git tylko po to, by zostały magicznie naprawione po ponownym uruchomieniu. Nie bądź taki jak ja.

9 Utwórz swoje pierwsze repo i używaj go z R Studio

Słowo „repo” jest skrótem od repozytorium i dokładnie tym jest: miejscem do przechowywania rzeczy (w tym przypadku naszych plików). To tak, jakbyś utworzył folder do przechowywania całej swojej pracy dla tej klasy.

Przejdźmy do GitHub i zalogujmy się. Po zalogowaniu powinieneś zobaczyć małą ikonę w prawym górnym rogu. Moja przedstawia mnie. Jeśli ją kliknę, pojawi się menu rozwijane i będę mógł wybrać „Twoje repozytoria”. Zrób to. Powinieneś zobaczyć coś takiego:

Kliknij przycisk „Nowy”. Nazwij swoje repozytorium NAME_test_repo, gdzie NAME to twoje imię i nazwisko. Wybierz Public i zaznacz pole obok Add a README file. Następnie kliknij Utwórz repozytorium.

Istnieją rzeczy, które można zrobić bezpośrednio w GitHub, ale my skupimy się na jego integracji z R Studio.

10 Klonowanie repozytorium

Klonowanie repozytorium jest „kopiowaniem” repozytorium na komputer. Ale podczas kopiowania zachowuje połączenie z repozytorium online.

Zróbmy tak. Na stronie my_test_repo wybierz zielony przycisk z napisem Code i skopiuj ścieżkę, podświetlając i klikając ikonę przypominającą notatnik ze strzałką.

Teraz przejdź do R Studio. Kliknij File –> New Project …. Powinieneś zobaczyć okno, które wygląda tak:

Wybierz opcję Kontrola wersji. Następnie powinieneś zobaczyć ekran, który wygląda tak:

Wybierz Git. Następnie powinieneś zobaczyć ekran, który wygląda jak ten, bez wypełnionych wszystkich szczegółów. Adres URL repozytorium to miejsce, w którym należy wkleić adres URL repozytorium sklonowanego z github. Zostanie również wypełniona nazwa katalogu projektu. Po prostu zostaw to. Zwróć uwagę na to, gdzie znajduje się katalog projektu i w razie potrzeby zmień go na lepszy. Kliknij Create Project.

Jeśli spojrzysz na zakładkę Pliki w prawym dolnym panelu R Studio, powinieneś zobaczyć plik .gitignore, plik projektu (kończy się na .Rproj) i plik README.md. Powinieneś także zobaczyć zakładkę Git w prawym górnym panelu w R Studio. Jeśli klikniesz teraz na zakładkę Git, nic tam nie zobaczysz.

Po otwarciu zakładki Git otwórzmy plik README.md w R Studio. Wprowadź niewielką zmianę w pliku, dodając zdanie „Zmieniam coś w tym pliku”. Następnie kliknij ikonę zapisu. Po wykonaniu tej czynności plik README.md pojawi się w zakładce Git.

Teraz kliknij przycisk Zatwierdź w zakładce Git. Zaznacz pole wyboru obok pliku README.md pod słowem Staged (w przyszłości możesz wystawić wiele plików jednocześnie, zaznaczając pola obok wielu plików) i dodaj komentarz do pola zatwierdzenia. Powinien on wyglądać mniej więcej tak:

Na koniec kliknij przycisk Zatwierdź. Pojawi się komunikat informujący o zakończeniu. Wiadomość może wydawać się tajemnicza, jeśli nie jesteś do nich przyzwyczajony. Wygląda on mniej więcej tak:

Wprowadzona zmiana została zatwierdzona (gra słów zamierzona!) do pamięci lokalnej. Zmieniony plik jest zmieniany tylko na komputerze, NIE online, jeśli spojrzysz na GitHub … idź sprawdzić. Kliknij przycisk Diff w zakładce Git, a zobaczysz historię swoich commitów.

Następnie zamierzamy przesłać te zmiany do GitHub, klikając zieloną strzałkę w górę na karcie Git. Spowoduje to wyświetlenie komunikatu, który wygląda mniej więcej tak:

Czy zostałeś poproszony o podanie nazwy użytkownika i hasła? Spróbuj wprowadzić kolejną modyfikację, zatwierdzić i wysłać. Czy nadal pojawia się monit o nazwę użytkownika i hasło? Jeśli tak, wróć i upewnij się, że skonfigurowałeś osobisty token dostępu (PAT).

**TWOJA KOLEJ!

  1. Dodaj plik .rmd do swojego projektu. W tym celu wybierz Plik –> Nowy plik –> R Markdown …. Dodaj kilka słów i fragment kodu R do pliku .rmd. Zapisz go, zatwierdź (nie zapomnij o wiadomości!) i wyślij. Sprawdź GitHub online, aby upewnić się, że widzisz tam plik .rmd.

  2. Teraz dziergaj plik lokalnie. Zatwierdź zmiany (pamiętaj, aby zaznaczyć wszystko, co chcesz wystawić - .rmd, .html itp.) i wypchnij je do GitHub. Sprawdź GitHub online, aby upewnić się, że widzisz wszystko, czego oczekujesz.

11 Dodawanie współpracowników

Do tej pory tak naprawdę poznaliśmy tylko techniki korzystania z GitHub do zarządzania własnymi plikami, ale najfajniejszą częścią tego narzędzia są jego funkcje współpracy. Sposobem, w jaki zamierzamy się tego nauczyć, jest dodawanie współpracowników do repozytorium.

Znajdź kogoś do współpracy w klasie. Jeśli jest ich nieparzysta liczba, stwórz grupę składającą się z trzech osób. W swojej małej grupie dodajcie siebie nawzajem jako współpracowników do projektu. W serwisie GitHub, na stronie repozytorium, przejdź do Ustawień. Jedną z opcji po lewej stronie są Współpracownicy. Kliknij ją i postępuj zgodnie z instrukcjami.

Osoba, która została zaproszona do współpracy, otrzyma wiadomość e-mail i powinna być w stanie zobaczyć zaproszenie na GitHub. Musi je zaakceptować. Po zaakceptowaniu oboje powinniście mieć dostęp do zatwierdzania zmian w pliku.

12 Commit –> Push –> Pull –> … (i komunikacja)

Po dodaniu współpracowników wszyscy współpracownicy mogą zatwierdzać i wypychać zmiany. Ale co się stanie, jeśli ktoś zatwierdzi i wypchnie coś, a następnie pójdziesz pracować nad tym na swoim komputerze … jak uzyskać te zmiany? … PULL!

W swoich grupach spróbuj wykonać następujące czynności. Każdy z was powinien być współpracownikiem w swoich projektach, więc możecie zmienić role po zrobieniu tego raz.

  1. Współpracownik musi najpierw sklonować repozytorium, nad którym został poproszony o współpracę. Jeśli ma otwarty inny projekt, zapisać, zatwierdzić i wypchnąć wszelkie zmiany. Następnie zamknij ten projekt i otwórz projekt, o którego współpracę został poproszony, klonując repozytorium GitHub. Współpracownik powinien mieć otwarty projekt w R Studio.

  2. Współpracownik powinien spróbować pociągnąć, klikając wodną strzałkę w dół w zakładce Git. Powinien pojawić się komunikat, który wygląda następująco:

  1. Osoba, która utworzyła repozytorium, wprowadza zmianę w swoim pliku .rmd. Może to być niewielka zmiana, na przykład dodanie zdania. Ta sama osoba zapisuje plik, zatwierdza (etap i zapisuje wiadomość zatwierdzenia) i przesyła go do GitHub. Sprawdź online, aby upewnić się, że najnowsze zmiany zostały wypchnięte.

  2. Współpracownik pobiera teraz te zmiany do swojego lokalnego katalogu (na swój komputer). Kliknij ikonę pobierania. Powinieneś zobaczyć wiadomość podobną do tej:

Sprawdź plik, w którym dokonano zmiany, aby upewnić się, że zmiana została odzwierciedlona w pliku na komputerze.

  1. Przejdź tam i z powrotem jeszcze kilka razy, wprowadzając drobne zmiany. Ten, kto jest właścicielem repozytorium, powinien dokonać zmiany, a współpracownik powinien ją wprowadzić. Następnie zamieńcie się rolami. Podczas przełączania upewnij się, że pracujesz z właściwym projektem.

13 Scal konflikty

Podczas wspólnej pracy nad projektem może się zdarzyć, że dwie osoby będą edytować ten sam plik w tym samym czasie. Czasami, jeśli oboje spróbujecie wypchnąć swoje zmiany, pojawi się tak zwany „konflikt scalania”. GitHub nie będzie wiedział, którego z nich użyć. Zmusi Cię więc do podjęcia decyzji.

Gdy spróbujesz przesłać swoje zmiany do GitHub, a ktoś inny już przesłał swoje zmiany dotyczące tego samego pliku, otrzymasz komunikat taki jak ten:

Następnie, po wciągnięciu zmian, pojawi się następujący komunikat:

Zauważ, że informuje on o pliku, w którym wystąpił konflikt scalania. Musisz otworzyć ten plik i zdecydować, jak scalić sprzeczne informacje. Na początku będzie to wyglądać mniej więcej tak:

Część po słowie HEAD jest tym, co znajduje się w lokalnym pliku. Wszystko po ====== jest tym, co znajduje się w pliku zdalnym (tj. zmiany wprowadzone przez współpracownika). Możesz zdecydować się na naprawienie tego w dowolny sposób: połączyć oba pomysły, usunąć oba, zachować tylko jeden itp. Po zakończeniu upewnij się, że pozbyłeś się <<<<<<< HEAD i >>>>>>>, po których następuje ciąg alfanumeryczny oraz wszelkie inne dziwne znaki.

Następnie zapisz plik i wykonaj zwykłe zatwierdzenie i wypchnięcie. Powinieneś zobaczyć zmiany wypchnięte do GitHub.

14 Praca zespołowa!

  1. W grupach 3-4-osobowych przećwicz swoje umiejętności GitHub.

  2. Grupa wybiera team-lidera. Ten ktoś tworzy nowe repo na swoim GitHub o nazwie “nasz_wykresik”

  3. Lider dodaje pozostałe osoby jako współpracowników.

  4. Współpracownicy powinni sprawdzić swoją pocztę e-mail i zaakceptować bycie Twoim współpracownikami.

  5. Lider i współpracownicy klonują repozytorium lokalnie na swoich komputerach.

  6. Współpracownik dodaje lokalnie plik .rmd do projektu. Tytuł powinien brzmieć „Nasz wykres” i dodawać wszystkich członków grupy jako autorów. Dodaj fragment kodu R, który ładuje bibliotekę tidyverse. Zapisz plik, zatwierdź z komunikatem i wypchnij na GitHub. Sprawdź online, aby upewnić się, że plik został poprawnie przesłany.

  7. Wszyscy pozostali członkowie grupy pobierają zmiany lokalnie.

  8. Inny współpracownik dodaje kolejny fragment kodu R. Korzystając ze zbioru danych mpg, utwórz wykres punktowy z hwy na osi y, displ na osi x i pokoloruj punkty według drv. Zapisz zmiany. Zatwierdź plik. Następnie zatwierdź z komunikatem i wypchnij na GitHub. Upewnij się, że wszystkie pliki zostały zatwierdzone. Sprawdź online, aby upewnić się, że widzisz zmiany.

  9. Wszyscy pozostali członkowie grupy pobierają zmiany lokalnie.

  10. Inny członek grupy (współpracownik lub twórca, jeśli masz tylko 3 członków grupy) modyfikuje fragment kodu R, który tworzy wykres, dodając ładne etykiety x i y oraz zmieniając theme_minimal(). Zapisz zmiany. Zatwierdź plik. Następnie zatwierdź z wiadomością i wyślij na GitHub. Upewnij się, że wszystkie pliki zostały zatwierdzone. Sprawdź online na githubie, aby upewnić się, że widzisz zmiany.

  11. Wszyscy członkowie grupy wykonują “Pull”. Osoba, która właśnie dokonała push powinna zobaczyć, że jest już na bieżąco. Wszyscy inni powinni zobaczyć zmiany odzwierciedlone lokalnie.

  12. Teraz wszyscy członkowie grupy powinni dodać coś do pliku .rmd. Nie mówcie sobie nawzajem, co dodajecie. Gdy skończycie, zapiszcie, zatwierdźcie i wyślijcie do GitHub. Przynajmniej jeden z was otrzyma konflikt scalania, więc poprosi cię o pobranie zmian z GitHub i naprawienie konfliktu. Zrób to. Tym razem będziesz musiał zmodyfikować plik .rmd, a nie README, jak pokazałem wcześniej.

15 Źródło

Happy git with R autorstwa Jenny Bryan: świetne źródło, choć sporo w nim odniesień do wiersza poleceń.

LS0tCnRpdGxlOiAiR2l0IGkgR2l0SHViIHcgcHJhY3kgemVzcG/Fgm93ZWoiCmF1dGhvcjogIkthcm9sIEZsaXNpa293c2tpIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRoZW1lOiBjZXJ1bGVhbgogICAgaGlnaGxpZ2h0OiB0ZXh0bWF0ZQogICAgZm9udHNpemU6IDhwdAogICAgdG9jOiB0cnVlCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiBmYWxzZQplZGl0b3Jfb3B0aW9uczogCiAgbWFya2Rvd246IAogICAgd3JhcDogNzIKLS0tCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgZWNobz1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmBgYAoKIyBJbmZvcm1hY2phCgpEdcW8YSBjesSZxZvEhyB0ZWdvIG1hdGVyaWHFgnUgem9zdGHFgmEgemFhZGFwdG93YW5hIHogW0hhcHB5IGdpdCB3aXRoIFIKYXV0b3JzdHdhIEplbm55IEJyeWFuXShodHRwczovL2hhcHB5Z2l0d2l0aHIuY29tLykuIFRvIGRvc2tvbmHFgmUgxbpyw7NkxYJvLAphbGUgemF3aWVyYSB3aWVsZSBpbmZvcm1hY2ppLCBrdMOzcnljaCBuaWUgcG90cnplYnVqZW15IG5hIHR5Y2gKemFqxJljaWFjaC4gSmXFm2xpIGNoY2VzeiB1xbx5d2HEhyBHaXRhIGkgR2l0SHViYSB3IGJhcmR6aWVqIHphYXdhbnNvd2FueQpzcG9zw7NiIGx1YiBqZcWbbGkgbW9qZSBpbnN0cnVrY2plIG5pZSBzxIUgd3lzdGFyY3phasSFY28gamFzbmUsCnpkZWN5ZG93YW5pZSB3YXJ0byB0YW0gemFqcnplxIcuCgojIFNhbW91Y3playB3aWRlbyAxLgoKVyBwaWVyd3N6eW0gPGEgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vZW1iZWQvUUxGYzlnd19IZnMiIHRhcmdldD0iX2JsYW5rIj52aWRlby10dXRvcmlhbHUgPC9hPiBwb2themFubyBqYWsgemFpbnN0YWxvd2HEhyBHaXQgaSBza29uZmlndXJvd2HEhyBnbyB6IFIgU3R1ZGlvLgoKPGEgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vZW1iZWQvUUxGYzlnd19IZnMiIHRhcmdldD0iX2JsYW5rIj4KIVtUdXRvcmlhbCAxLl0oaW1hZ2VzL3NhbTEuanBnKSAgPC9hPgoKIyBTYW1vdWN6ZWsgd2lkZW8gMi4KClcgZHJ1Z2ltIDxhIGhyZWY9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9dFFjdWFfNlE5dFkiIHRhcmdldD0iX2JsYW5rIj4gIHR1dG9yaWFsdSA8L2E+IHBva2F6YW5vLCBqYWsgdXR3b3J6ecSHIHJlcG96eXRvcml1bSwgc2tsb25vd2HEhyBqZSwgZG9kYcSHIHBsaWssIHphdHdpZXJkemnEhyB6bWlhbnkgaSB3eXBjaG7EhcSHIGplIG5hIEdpdEh1YiAocHJhY2EgZHfDs2NoIG9zw7NiIHByYWN1asSFY3ljaCBuYSBqZWRueW0gcmVwbykuIAoKPGEgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj10UWN1YV82UTl0WSIgdGFyZ2V0PSJfYmxhbmsiPiAgCiFbVHV0b3JpYWwgMi5dKGltYWdlcy9zYW0yLmpwZykgPC9hPgoKIyBKYWsgbmFwcmF3acSHIHrFgsSFIMWbY2llxbxrxJkgZG8gR2l0PwoKSmXFm2xpIHphdXdhxbx5c3osIMW8ZSBjb8WbIG5pZSBkemlhxYJhLCB6YWN6bmlqIG9kIHNwcmF3ZHplbmlhLCBjenkgbWFzeiBwcmF3aWTFgm93xIUgxZtjaWXFvGvEmSBkbyBHaXRhLiBXIFIgU3R1ZGlvIG1vxbxlc3ogdG8genJvYmnEhywgemFnbMSFZGFqxIVjIGRvIHpha8WCYWRraSBUb29scyAtIEdsb2JhbCBPcHRpb25zIC0gR2l0LiBKZcWbbGkgbmEga29tcHV0ZXJ6ZSBNYWMgT1MgdXN0YXdpb25hIHpvc3RhxYJhIG5pZXByYXdpZMWCb3dhIMWbY2llxbxrYSwgd3lrb25haiBraWxrYSBrcm9rw7N3LCBrdMOzcmUgcG9rYXphbm8gbmEgZmlsbWllOiA8YSBocmVmPSJodHRwczovL3lvdXR1LmJlL0VkQlVKZUhGMnhBIiB0YXJnZXQ9Il9ibGFuayI+ICB0dXRhai4gPC9hPiBXIHByenlwYWRrdSBrb21wdXRlcsOzdyB6IFdpbmRvd3NlbSAtIHBvIHByb3N0dSB3ZWpkxbogdyB0ZW4gcGFuZWwgaSB3eWJpZXJ6IHByYXdpZMWCb3fEhSDFm2NpZcW8a8SZIGRvIEdpdGEgdyBQcm9ncmFtIEZpbGVzL0dpdC9iaW4vZ2l0LmV4ZS4KCiMgR2l0IGkgR2l0SHViCgpHaXQgdG8gc3lzdGVtIGtvbnRyb2xpIHdlcnNqaS4gSmVzdCBwb2RvYm55IGRvIEdvb2dsZSBEb2NzLCBhbGUKb2JzxYJ1Z3VqZSB3aWVsZSB0eXDDs3cgcGxpa8Ozdywga3TDs3J5Y2ggR29vZ2xlIERvY3MgbmllIG1vxbxlIC4uLiBqYWsgcGxpa2kKLnJtZCEgR2l0SHViIHRvIGludGVyZmVqcyBvbmxpbmUgZG8gcHJhY3kgeiBHaXRlbS4KCkRsYWN6ZWdvIHVjenlteSBzacSZIHR5Y2ggcnplY3p5PwoKMS4gIEdpdEh1YiBqZXN0IGRvYnJ6ZSB6aW50ZWdyb3dhbnkgeiBSIFN0dWRpby4gTmllIGLEmWR6aWVteSB3acSZYwogICAgbXVzaWVsaSB1xbx5d2HEhyDFvGFkbnljaCBmdW5rY2ppIHdpZXJzemEgcG9sZWNlxYQsIHByenluYWptbmllaiBuaWUgcG8KICAgIHNrb25maWd1cm93YW5pdSB3c3p5c3RraWVnby4KCjIuICBXeW1hZ2FuZSBqZXN0IHXFvHljaWUgUiBkbyBrb8WEY293ZWdvIHByb2pla3R1LiBQcmV6ZW50YWNqYSBsdWIKICAgIHJlZmVyYXQgbXVzesSFIGJ5xIcgemFwaXNhbmUgamFrbyBkb2t1bWVudCAucm1kLCBrdMOzcnkgbW/FvG5hIHBvxYLEhWN6ecSHCiAgICB6IGRva3VtZW50ZW0gaHRtbC4gS29yenlzdGFuaWUgeiBHaXRIdWIgcG96d29saSBuYSDFgmF0d8SFIHByYWPEmSB6CiAgICBncnVwxIUsIG5hd2V0IGplxZtsaSBuaWUgamVzdGXFm2NpZSByYXplbS4KCjMuICBHaXRIdWIgdWN6eSBkb2JyeWNoIG5hd3lrw7N3LiBKZXN0ZcWbIHptdXN6b255IGRvIG15xZtsZW5pYSBvIHR5bSwKICAgIGtpZWR5IHphcGlzdWplc3ogaSBkbyByb2JpZW5pYSBub3RhdGVrIG8gdHltLCBqYWtpZSB6bWlhbnkKICAgIHdwcm93YWR6acWCZcWbIHphIGthxbxkeW0gcmF6ZW0sIGdkeSB0byByb2Jpc3ouCgojIFV0d8Ozcnoga29udG8gR2l0SHViCgotICAgUHJ6ZWpkxbogZG8gPGh0dHA6Ly9naXRodWIuY29tPiBpIHV0d8Ozcnoga29udG8uCi0gICBVdHfDs3J6IG5henfEmSB1xbx5dGtvd25pa2EgLi4uIHpvYmFjeiBbd3NrYXrDs3draV0gSmVubnkgQnJ5YW4KICAgICg8aHR0cHM6Ly9oYXBweWdpdHdpdGhyLmNvbS9naXRodWItYWNjdC5odG1sPikuIFV3emdsxJlkbmlqIHN3b2plCiAgICByemVjenl3aXN0ZSBpbWnEmSBpIG5hendpc2tvLCB1xbx5aiBpbm5laiBuYXp3eSB1xbx5dGtvd25pa2EsIGt0w7NyxIUganXFvAogICAgcG9zaWFkYXN6LCBcKiB3eWJpZXJ6IG5henfEmSB1xbx5dGtvd25pa2EsIGt0w7NyxIUgYsSZZHppZXN6IG3Ds2fFgiB1amF3bmnEhwogICAgcHJ6eXN6xYJlbXUgc3plZm93aVwqLgoKIyBaYWluc3RhbHVqIGkgc2tvbmZpZ3VydWogR2l0CgoxLiAgU3ByYXdkxbosIGN6eSBtYXN6IGp1xbwgemFpbnN0YWxvd2FueSBHaXQuIELEmWR6aWUgdG8gbWlhxYJvIG1pZWpzY2UKICAgIHR5bGtvIHd0ZWR5LCBnZHkgdcW8eXdhxYJlxZsgZ28gZ2R6aWUgaW5kemllai4gQWJ5IHRvIHpyb2JpxIcsIG90d8OzcnoKICAgIHRlcm1pbmFsIGx1YiB3IFIgU3R1ZGlvIHJvendpxYQga29uc29sxJkuIFBvd2lubmEgdGFtIGJ5xIcgemFrxYJhZGthCiAgICBUZXJtaW5hbC4gVyB0eW0gb2JzemFyemUgd3Bpc3o6CgpgYGAgICAgICAgICAKd2hpY2ggZ2l0CmBgYAoKSmXFm2xpIHp3csOzY2kgdG8gY2/FmyB0YWtpZWdvIGphawoKYGBgICAgICAgICAgCi91c3IvYmluL2dpdApgYGAKCnd0ZWR5IHNrb8WEY3p5xYJlxZsgaSBuaWUgbXVzaXN6IGluc3RhbG93YcSHIEdpdGEuCgpOYSBrb21wdXRlcnplIHogc3lzdGVtZW0gV2luZG93cyBtb8W8ZXN6IG5hd2V0IG5pZSBiecSHIHcgc3RhbmllIHBvbXnFm2xuaWUKd3Bpc2HEhyBwb2xlY2VuaWEgYHdoaWNoIGdpdGAuIFBvd2lubm8gdG8gem9zdGHEhyBuYXByYXdpb25lIHByemV6CnphaW5zdGFsb3dhbmllIGdpdC4gQWxibyBixJlkemllc3ogbXVzaWHFgiB1xbx5xIcgcG93xYJva2kuIE1vxbxlc3ogdGFrxbxlCnNwcsOzYm93YcSHIHdwaXNhxIcgYHdoZXJlIGdpdGAuCgoyLiAgSmXFm2xpIG5pZSBtYXN6IHphaW5zdGFsb3dhbmVnbyBHaXRhLCBtdXNpc3ogZ28gemFpbnN0YWxvd2HEhy4KICAgIEluc3RydWtjamUgc8SFIG5pZWNvIGlubmUgZGxhIHN5c3RlbcOzdyBXaW5kb3dzIGkgTWFjLgoKKipXIHN5c3RlbWllIFdpbmRvd3M6KioKCi0gICBaYWluc3RhbHVqIFtHaXQgZGxhIFdpbmRvd3NdKGh0dHBzOi8vZ2l0Zm9yd2luZG93cy5vcmcvKS4gR2R5IHBvamF3aQogICAgc2nEmSBweXRhbmllIG8g4oCeRG9zdG9zb3dhbmllIMWbcm9kb3dpc2thIFBBVEjigJ0sIHVwZXduaWogc2nEmSwgxbxlCiAgICB3eWJyYW5vIG9wY2rEmSDigJ5HaXQgeiB3aWVyc3phIHBvbGVjZcWELCBhIHRha8W8ZSB6IG9wcm9ncmFtb3dhbmlhCiAgICBpbm55Y2ggZmlybeKAnS4gVyBwcnplY2l3bnltIHJhemllIHV3YcW8YW15LCDFvGUgZG9icnplIGplc3QKICAgIHphYWtjZXB0b3dhxIcgd2FydG/Fm2NpIGRvbXnFm2xuZS4KLSAgIFIgU3R1ZGlvIGRsYSBXaW5kb3dzIHByZWZlcnVqZSwgYWJ5IEdpdCBiecWCIHphaW5zdGFsb3dhbnkgcG9uacW8ZWoKICAgIEM6L1Byb2dyYW0gRmlsZXMgaSB3eWRhamUgc2nEmSwgxbxlIGplc3QgdG8gdXN0YXdpZW5pZSBkb215xZtsbmUuCiAgICBPem5hY3phIHRvIG5hIHByenlrxYJhZCwgxbxlIHBsaWsgd3lrb255d2FsbnkgR2l0IHcgbW9pbSBzeXN0ZW1pZQogICAgV2luZG93cyB6bmFqZHVqZSBzacSZIHcgQzovUHJvZ3JhbSBGaWxlcy9HaXQvYmluL2dpdC5leGUuIE8gaWxlIG5pZQogICAgbWFzeiBzemN6ZWfDs2xueWNoIHBvd29kw7N3LCBhYnkgcG9zdMSFcGnEhyBpbmFjemVqLCBwb3N0xJlwdWogemdvZG5pZSB6CiAgICB0xIUga29ud2VuY2rEhS4KCioqTmEgTWFjdToqKgoKLSAgIFByemVqZMW6IGRvICpzaGVsbC90ZXJtaW5hbCogaSB3cHJvd2FkxbogKipqZWRubyoqIHogdHljaCBwb2xlY2XFhCwgYWJ5CiAgICB3ecWbd2lldGxpxIcgb2ZlcnTEmSBpbnN0YWxhY2ppIG5hcnrEmWR6aSB3aWVyc3phIHBvbGVjZcWEIGRsYQogICAgcHJvZ3JhbWlzdMOzdy4gWmFha2NlcHR1aiBvZmVydMSZIC4uLiBrbGlrbmlqIHphaW5zdGFsdWouCgpgYGAgICAgICAgICAKZ2l0IC0tdmVyc2lvbgpnaXQgY29uZmlnCmBgYAoKLSAgIE5pZWt0w7NyenkgdcW8eXRrb3duaWN5IGtvbXB1dGVyw7N3IE1hYyBtb2fEhSBiecSHIHptdXN6ZW5pIGRvIHd5a29uYW5pYQogICAgcG9uacW8c3p5Y2ggY3p5bm5vxZtjaSB3ICp0ZXJtaW5hbHUqLCBqZcWbbGkgcHLDs2JhIG90d2FyY2lhIHByb2pla3R1CiAgICB6YWtvxYRjenkgc2nEmSBuaWVwb3dvZHplbmllbS4gWmEgY2h3aWzEmSBkb3dpZXN6IHNpxJksIGN6eSB0YWsgamVzdCB3CiAgICB0eW0gcHJ6eXBhZGt1LgoKYGBgICAgICAgICAgCnhjb2RlLXNlbGVjdCAtLWluc3RhbGwKYGBgCgozLiAgVGVyYXogd3LDs8SHIGRvICpDb25zb2xlKiB3IFIgU3R1ZGlvIGkgemFpbnN0YWx1aiBwYWtpZXQgYHVzZXRoaXNgIHcgUgogICAgU3R1ZGlvLiBOYXN0xJlwbmllIHphbWtuaWogUiBTdHVkaW8gaSBvdHfDs3J6IGplIHBvbm93bmllLgoKNC4gIFphxYJhZHVqIGJpYmxpb3Rla8SZIGB1c2V0aGlzYCB1cnVjaGFtaWFqxIVjIG5hc3TEmXB1asSFY3kgZnJhZ21lbnQga29kdQogICAgdyAqa29uc29saSo6CgpgYGAgICAgICAgICAKbGlicmFyeSh1c2V0aGlzKQpgYGAKCjUuICBVcnVjaG9tIHBvbmnFvHN6eSBrb2QgdyAqY29uc29sZSogeiBraWxrb21hIGRyb2JueW1pIHptaWFuYW1pLgogICAgYHVzZXIubmFtZWAgdG8gbmF6d2EgdcW8eXRrb3duaWthIEdpdC4gTW/FvGUgc2nEmSBvbmEgcsOzxbxuacSHIG9kIG5hend5CiAgICB1xbx5dGtvd25pa2EgR2l0SHViLCBjaG/EhyBkb2JyeW0gcG9teXPFgmVtIG1vxbxlIGJ5xIcgcG96b3N0YXdpZW5pZSBqZWoKICAgIHRha2llaiBzYW1lai4gQWRyZXMgYHVzZXIuZW1haWxgICpNVVNJKiBiecSHIHRha2kgc2FtIGphayBhZHJlcwogICAgZS1tYWlsIHXFvHl0a293bmlrYSBHaXRIdWIuCgpgYGAgICAgICAgICAKdXNlX2dpdF9jb25maWcodXNlci5uYW1lID0g4oCeSmFuZSBEb2XigJ0sIHVzZXIuZW1haWwgPSDigJ5qYW5lQGV4YW1wbGUub3Jn4oCdKQpgYGAKCiMgU2tvbmZpZ3VydWogUEFUCgpQQVQsIGN6eWxpIFBlcnNvbmFsIEFjY2VzcyBUb2tlbiwgamVzdCB0ZXJheiBuaWV6YsSZZG55IChsdWIgYsSZZHppZQp3a3LDs3RjZSksIGFieSBSU3R1ZGlvIGkgR2l0SHViIG1vZ8WCeSB6ZSBzb2LEhSByb3ptYXdpYcSHLiBKZW5ueSBCcnlhbgpvbWF3aWEgdG8gdyByb3pkemlhbGUgMTAgW0hhcHB5IEdpdCB3aXRoClJdKGh0dHBzOi8vaGFwcHlnaXR3aXRoci5jb20vY3JlZGVudGlhbC1jYWNoaW5nLmh0bWwjY3JlZGVudGlhbC1jYWNoaW5nKSwKYSBEYXZpZCBLZXllcyBvbWF3aWEgdG8gdyBzd29pbSBwb8WbY2llIG5hIGJsb2d1IFtIb3cgdG8gVXNlIEdpdC9HaXRodWIKd2l0aApSXShodHRwczovL3Jmb3J0aGVyZXN0b2Z1cy5jb20vMjAyMS8wMi9ob3ctdG8tdXNlLWdpdC1naXRodWItd2l0aC1yLykKKHpvYmFjeiBzZWtjasSZIENvbm5lY3QgUlN0dWRpbyBhbmQgR2l0SHViKS4KCjEuICBOYWpwaWVydyB1cnVjaG9tIGZ1bmtjasSZIGBjcmVhdGVfZ2l0aHViX3Rva2VuKClgIHogYmlibGlvdGVraQogICAgYHVzZXRoaXNgIHcga29uc29saS4gU3Bvd29kdWplIHRvIHByemVqxZtjaWUgZG8gd2l0cnlueSBHaXRIdWIsIGdkemllCiAgICBtb8W8bmEgdXR3b3J6ecSHIHRva2VuIC0gcHJ6ZWNob3d1aiBnbyB3IGJlenBpZWN6bnltIG1pZWpzY3UgaSBuaWUKICAgIHpndWIgZ28hIELEmWR6aWVzeiBnbyBwb3RyemVib3dhxIcgemEgY2h3aWzEmSBpIGJ5xIcgbW/FvGUga2llZHnFmyB3CiAgICBvZGxlZ8WCZWogcHJ6eXN6xYJvxZtjaS5cCjIuICBaYWluc3RhbHVqIHBha2lldCBgZ2l0Y3JlZHNgIHcgUlN0dWRpbyBpIHphxYJhZHVqIGJpYmxpb3Rla8SZIHXFvHl3YWrEhWMKICAgIGBsaWJyYXJ5KGdpdGNyZWRzKWAgKG1vxbxlc3ogdG8genJvYmnEhyB3IGtvbnNvbGkpLlwKMy4gIFVydWNob20gZnVua2NqxJkgYGdpdGNyZWRzX3NldCgpYCB3IGtvbnNvbGkuIEplxZtsaSBtYXN6IGRvc3TEmXBuZQogICAgb3BjamUsIHd5Ymllcnogb3BjasSZIFphc3TEhXAgdGUgZGFuZSB1d2llcnp5dGVsbmlhasSFY2UsIGEgbmFzdMSZcG5pZQogICAgd2tsZWogUEFULCBrdMOzcnkgd8WCYcWbbmllIHV0d29yennFgmXFmyB3IHBvcHJ6ZWRuaW0ga3Jva3UuXAo0LiAgUG9kY3phcyBuYXN0xJlwbmVnbyB6YXR3aWVyZHphbmlhIGkgd3lweWNoYW5pYSBtb8W8ZSBuYWRhbCBweXRhxIcgbwogICAgbmF6d8SZIHXFvHl0a293bmlrYSBpIGhhc8WCbyBnaXRodWIsICoqdcW8eWogUEFULCBnZHkgemFweXRhIG8gaGFzxYJvCiAgICAhISEqKiAuCgpEYWogbWkgem5hxIcsIGplxZtsaSBtYXN6IHByb2JsZW15IHoga3TDs3J5bWtvbHdpZWsgeiB0eWNoIGtyb2vDs3cuIE1vasSFCnBpZXJ3c3rEhSBzdWdlc3RpxIUgemF3c3plIGLEmWR6aWUgcG9ub3duZSB1cnVjaG9taWVuaWUga29tcHV0ZXJhLgpOaWVzdGV0eSwga2llZHnFmyBzcMSZZHppxYJlbSBkd2llIGdvZHppbnkgcHLDs2J1asSFYyBkZWJ1Z293YcSHIGLFgsSZZHkgZ2l0CnR5bGtvIHBvIHRvLCBieSB6b3N0YcWCeSBtYWdpY3puaWUgbmFwcmF3aW9uZSBwbyBwb25vd255bSB1cnVjaG9taWVuaXUuCk5pZSBixIVkxbogdGFraSBqYWsgamEuCgojIFV0d8Ozcnogc3dvamUgcGllcndzemUgcmVwbyBpIHXFvHl3YWogZ28geiBSIFN0dWRpbwoKU8WCb3dvIOKAnnJlcG/igJ0gamVzdCBza3LDs3RlbSBvZCByZXBvenl0b3JpdW0gaSBkb2vFgmFkbmllIHR5bSBqZXN0OiBtaWVqc2NlbQpkbyBwcnplY2hvd3l3YW5pYSByemVjenkgKHcgdHltIHByenlwYWRrdSBuYXN6eWNoIHBsaWvDs3cpLiBUbyB0YWssCmpha2J5xZsgdXR3b3J6ecWCIGZvbGRlciBkbyBwcnplY2hvd3l3YW5pYSBjYcWCZWogc3dvamVqIHByYWN5IGRsYSB0ZWoKa2xhc3kuCgpQcnplamTFum15IGRvIFtHaXRIdWJdKGh0dHBzOi8vZ2l0aHViLmNvbS8pIGkgemFsb2d1am15IHNpxJkuIFBvCnphbG9nb3dhbml1IHBvd2luaWVuZcWbIHpvYmFjennEhyBtYcWCxIUgaWtvbsSZIHcgcHJhd3ltIGfDs3JueW0gcm9ndS4gTW9qYQpwcnplZHN0YXdpYSBtbmllLiBKZcWbbGkgasSFIGtsaWtuxJksIHBvamF3aSBzacSZIG1lbnUgcm96d2lqYW5lIGkgYsSZZMSZIG3Ds2fFggp3eWJyYcSHIOKAnlR3b2plIHJlcG96eXRvcmlh4oCdLiBacsOzYiB0by4gUG93aW5pZW5lxZsgem9iYWN6ecSHIGNvxZsgdGFraWVnbzoKCiFbXShpbWFnZXMvbmV3X3JlcG8ucG5nKQoKS2xpa25paiBwcnp5Y2lzayDigJ5Ob3d54oCdLiBOYXp3aWogc3dvamUgcmVwb3p5dG9yaXVtIGBOQU1FX3Rlc3RfcmVwb2AsCmdkemllIGBOQU1FYCB0byB0d29qZSBpbWnEmSBpIG5hendpc2tvLiBXeWJpZXJ6IFB1YmxpYyBpIHphem5hY3ogcG9sZQpvYm9rIEFkZCBhIFJFQURNRSBmaWxlLiBOYXN0xJlwbmllIGtsaWtuaWogVXR3w7NyeiByZXBvenl0b3JpdW0uCgohW10oaW1hZ2VzL2NyZWF0ZV9uZXdfcmVwby5wbmcpCgpJc3RuaWVqxIUgcnplY3p5LCBrdMOzcmUgbW/FvG5hIHpyb2JpxIcgYmV6cG/Fm3JlZG5pbyB3IEdpdEh1YiwgYWxlIG15CnNrdXBpbXkgc2nEmSBuYSBqZWdvIGludGVncmFjamkgeiBSIFN0dWRpby4KCiMgS2xvbm93YW5pZSByZXBvenl0b3JpdW0KCktsb25vd2FuaWUgcmVwb3p5dG9yaXVtIGplc3Qg4oCea29waW93YW5pZW3igJ0gcmVwb3p5dG9yaXVtIG5hIGtvbXB1dGVyLiBBbGUKcG9kY3phcyBrb3Bpb3dhbmlhIHphY2hvd3VqZSBwb8WCxIVjemVuaWUgeiByZXBvenl0b3JpdW0gb25saW5lLgoKWnLDs2JteSB0YWsuIE5hIHN0cm9uaWUgbXlfdGVzdF9yZXBvIHd5YmllcnogemllbG9ueSBwcnp5Y2lzayB6IG5hcGlzZW0KQ29kZSBpIHNrb3BpdWogxZtjaWXFvGvEmSwgcG9kxZt3aWV0bGFqxIVjIGkga2xpa2FqxIVjIGlrb27EmSBwcnp5cG9taW5hasSFY8SFCm5vdGF0bmlrIHplIHN0cnphxYJrxIUuCgpUZXJheiBwcnplamTFuiBkbyBSIFN0dWRpby4gS2xpa25paiBGaWxlIC0tXD4gTmV3IFByb2plY3QgLi4uLiBQb3dpbmllbmXFmwp6b2JhY3p5xIcgb2tubywga3TDs3JlIHd5Z2zEhWRhIHRhazoKCiFbXShpbWFnZXMvbmV3X3Byb2plY3QucG5nKQoKV3liaWVyeiBvcGNqxJkgS29udHJvbGEgd2Vyc2ppLiBOYXN0xJlwbmllIHBvd2luaWVuZcWbIHpvYmFjennEhyBla3JhbiwKa3TDs3J5IHd5Z2zEhWRhIHRhazoKCiFbXShpbWFnZXMvZ2l0aHViLnBuZykKCld5YmllcnogR2l0LiBOYXN0xJlwbmllIHBvd2luaWVuZcWbIHpvYmFjennEhyBla3Jhbiwga3TDs3J5IHd5Z2zEhWRhIGphayB0ZW4sCmJleiB3eXBlxYJuaW9ueWNoIHdzenlzdGtpY2ggc3pjemVnw7PFgsOzdy4gQWRyZXMgVVJMIHJlcG96eXRvcml1bSB0bwptaWVqc2NlLCB3IGt0w7NyeW0gbmFsZcW8eSB3a2xlacSHIGFkcmVzIFVSTCByZXBvenl0b3JpdW0gc2tsb25vd2FuZWdvIHoKZ2l0aHViLiBab3N0YW5pZSByw7N3bmllxbwgd3lwZcWCbmlvbmEgbmF6d2Ega2F0YWxvZ3UgcHJvamVrdHUuIFBvIHByb3N0dQp6b3N0YXcgdG8uICoqWndyw7PEhyB1d2FnxJkqKiBuYSB0bywgZ2R6aWUgem5hamR1amUgc2nEmSBrYXRhbG9nIHByb2pla3R1IGkKdyByYXppZSBwb3RyemVieSB6bWllxYQgZ28gbmEgbGVwc3p5LiBLbGlrbmlqIENyZWF0ZSBQcm9qZWN0LgoKIVtdKGltYWdlcy9jbG9uZV9naXQucG5nKQoKSmXFm2xpIHNwb2pyenlzeiBuYSB6YWvFgmFka8SZIFBsaWtpIHcgcHJhd3ltIGRvbG55bSBwYW5lbHUgUiBTdHVkaW8sCnBvd2luaWVuZcWbIHpvYmFjennEhyBwbGlrIC5naXRpZ25vcmUsIHBsaWsgcHJvamVrdHUgKGtvxYRjenkgc2nEmSBuYQouUnByb2opIGkgcGxpayBSRUFETUUubWQuIFBvd2luaWVuZcWbIHRha8W8ZSB6b2JhY3p5xIcgemFrxYJhZGvEmSBHaXQgdwpwcmF3eW0gZ8Ozcm55bSBwYW5lbHUgdyBSIFN0dWRpby4gSmXFm2xpIGtsaWtuaWVzeiB0ZXJheiBuYSB6YWvFgmFka8SZIEdpdCwKbmljIHRhbSBuaWUgem9iYWN6eXN6LgoKUG8gb3R3YXJjaXUgemFrxYJhZGtpIEdpdCBvdHfDs3J6bXkgcGxpayBSRUFETUUubWQgdyBSIFN0dWRpby4gV3Byb3dhZMW6Cm5pZXdpZWxrxIUgem1pYW7EmSB3IHBsaWt1LCBkb2RhasSFYyB6ZGFuaWUg4oCeWm1pZW5pYW0gY2/FmyB3IHR5bSBwbGlrdeKAnS4KTmFzdMSZcG5pZSBrbGlrbmlqIGlrb27EmSB6YXBpc3UuIFBvIHd5a29uYW5pdSB0ZWogY3p5bm5vxZtjaSBwbGlrClJFQURNRS5tZCBwb2phd2kgc2nEmSB3IHpha8WCYWRjZSBHaXQuCgpUZXJheiBrbGlrbmlqIHByenljaXNrIFphdHdpZXJkxbogdyB6YWvFgmFkY2UgR2l0LiBaYXpuYWN6IHBvbGUgd3lib3J1Cm9ib2sgcGxpa3UgUkVBRE1FLm1kIHBvZCBzxYJvd2VtICpTdGFnZWQqICh3IHByenlzesWCb8WbY2kgbW/FvGVzeiB3eXN0YXdpxIcKd2llbGUgcGxpa8OzdyBqZWRub2N6ZcWbbmllLCB6YXpuYWN6YWrEhWMgcG9sYSBvYm9rIHdpZWx1IHBsaWvDs3cpIGkgKipkb2Rhagprb21lbnRhcnogZG8gcG9sYSB6YXR3aWVyZHplbmlhKiouIFBvd2luaWVuIG9uIHd5Z2zEhWRhxIcgbW5pZWogd2nEmWNlagp0YWs6CgohW10oaW1hZ2VzL2dpdF9zdGFnZV9jb21taXRfbXNnLnBuZykKCk5hIGtvbmllYyBrbGlrbmlqIHByenljaXNrIFphdHdpZXJkxbouIFBvamF3aSBzacSZIGtvbXVuaWthdCBpbmZvcm11asSFY3kgbwp6YWtvxYRjemVuaXUuIFdpYWRvbW/Fm8SHIG1vxbxlIHd5ZGF3YcSHIHNpxJkgdGFqZW1uaWN6YSwgamXFm2xpIG5pZSBqZXN0ZcWbIGRvCm5pY2ggcHJ6eXp3eWN6YWpvbnkuIFd5Z2zEhWRhIG9uIG1uaWVqIHdpxJljZWogdGFrOgoKIVtdKGltYWdlcy9naXRfY29tbWl0LnBuZykKCldwcm93YWR6b25hIHptaWFuYSB6b3N0YcWCYSB6YXR3aWVyZHpvbmEgKGdyYSBzxYLDs3cgemFtaWVyem9uYSEpIGRvCnBhbWnEmWNpIGxva2FsbmVqLiBabWllbmlvbnkgcGxpayBqZXN0IHptaWVuaWFueSB0eWxrbyBuYSBrb21wdXRlcnplLCBOSUUKb25saW5lLCBqZcWbbGkgc3BvanJ6eXN6IG5hIEdpdEh1YiAuLi4gaWTFuiBzcHJhd2R6acSHLiBLbGlrbmlqIHByenljaXNrCkRpZmYgdyB6YWvFgmFkY2UgR2l0LCBhIHpvYmFjenlzeiBoaXN0b3JpxJkgc3dvaWNoIGNvbW1pdMOzdy4KCk5hc3TEmXBuaWUgemFtaWVyemFteSBwcnplc8WCYcSHIHRlIHptaWFueSBkbyBHaXRIdWIsIGtsaWthasSFYyB6aWVsb27EhQpzdHJ6YcWCa8SZIHcgZ8OzcsSZIG5hIGthcmNpZSBHaXQuIFNwb3dvZHVqZSB0byB3ecWbd2lldGxlbmllIGtvbXVuaWthdHUsCmt0w7NyeSB3eWdsxIVkYSBtbmllaiB3acSZY2VqIHRhazoKCiFbXShpbWFnZXMvcHVzaF9tZXNzYWdlLnBuZykKCkN6eSB6b3N0YcWCZcWbIHBvcHJvc3pvbnkgbyBwb2RhbmllIG5hend5IHXFvHl0a293bmlrYSBpIGhhc8WCYT8gU3Byw7NidWoKd3Byb3dhZHppxIcga29sZWpuxIUgbW9keWZpa2FjasSZLCB6YXR3aWVyZHppxIcgaSB3eXPFgmHEhy4gQ3p5IG5hZGFsIHBvamF3aWEKc2nEmSBtb25pdCBvIG5henfEmSB1xbx5dGtvd25pa2EgaSBoYXPFgm8/IEplxZtsaSB0YWssIHdyw7PEhyBpIHVwZXduaWogc2nEmSwgxbxlCnNrb25maWd1cm93YcWCZcWbIG9zb2Jpc3R5IHRva2VuIGRvc3TEmXB1IChQQVQpLgoKXCpcKlRXT0pBIEtPTEVKIQoKMS4gIERvZGFqIHBsaWsgLnJtZCBkbyBzd29qZWdvIHByb2pla3R1LiBXIHR5bSBjZWx1IHd5YmllcnogUGxpayAtLVw+CiAgICBOb3d5IHBsaWsgLS1cPiBSIE1hcmtkb3duIC4uLi4gRG9kYWoga2lsa2Egc8WCw7N3IGkgZnJhZ21lbnQga29kdSBSIGRvCiAgICBwbGlrdSAucm1kLiBaYXBpc3ogZ28sIHphdHdpZXJkxbogKG5pZSB6YXBvbW5paiBvIHdpYWRvbW/Fm2NpISkgaQogICAgd3nFm2xpai4gU3ByYXdkxbogR2l0SHViIG9ubGluZSwgYWJ5IHVwZXduacSHIHNpxJksIMW8ZSB3aWR6aXN6IHRhbSBwbGlrCiAgICAucm1kLgoKMi4gIFRlcmF6IGR6aWVyZ2FqIHBsaWsgbG9rYWxuaWUuIFphdHdpZXJkxbogem1pYW55IChwYW1pxJl0YWosIGFieQogICAgemF6bmFjennEhyB3c3p5c3RrbywgY28gY2hjZXN6IHd5c3Rhd2nEhyAtIC5ybWQsIC5odG1sIGl0cC4pIGkKICAgIHd5cGNobmlqIGplIGRvIEdpdEh1Yi4gU3ByYXdkxbogR2l0SHViIG9ubGluZSwgYWJ5IHVwZXduacSHIHNpxJksIMW8ZQogICAgd2lkemlzeiB3c3p5c3RrbywgY3plZ28gb2N6ZWt1amVzei4KCiMgRG9kYXdhbmllIHdzcMOzxYJwcmFjb3duaWvDs3cKCkRvIHRlaiBwb3J5IHRhayBuYXByYXdkxJkgcG96bmFsacWbbXkgdHlsa28gdGVjaG5pa2kga29yenlzdGFuaWEgeiBHaXRIdWIKZG8gemFyesSFZHphbmlhIHfFgmFzbnltaSBwbGlrYW1pLCBhbGUgbmFqZmFqbmllanN6xIUgY3rEmcWbY2nEhSB0ZWdvCm5hcnrEmWR6aWEgc8SFIGplZ28gZnVua2NqZSB3c3DDs8WCcHJhY3kuIFNwb3NvYmVtLCB3IGpha2kgemFtaWVyemFteSBzacSZCnRlZ28gbmF1Y3p5xIcsIGplc3QgZG9kYXdhbmllIHdzcMOzxYJwcmFjb3duaWvDs3cgZG8gcmVwb3p5dG9yaXVtLgoKWm5hamTFuiBrb2dvxZsgZG8gd3Nww7PFgnByYWN5IHcga2xhc2llLiBKZcWbbGkgamVzdCBpY2ggbmllcGFyenlzdGEgbGljemJhLApzdHfDs3J6IGdydXDEmSBza8WCYWRhasSFY8SFIHNpxJkgeiB0cnplY2ggb3PDs2IuIFcgc3dvamVqIG1hxYJlaiBncnVwaWUKZG9kYWpjaWUgc2llYmllIG5hd3phamVtIGpha28gd3Nww7PFgnByYWNvd25pa8OzdyBkbyBwcm9qZWt0dS4gVyBzZXJ3aXNpZQpHaXRIdWIsIG5hIHN0cm9uaWUgcmVwb3p5dG9yaXVtLCBwcnplamTFuiBkbyBVc3Rhd2llxYQuIEplZG7EhSB6IG9wY2ppIHBvCmxld2VqIHN0cm9uaWUgc8SFIFdzcMOzxYJwcmFjb3duaWN5LiBLbGlrbmlqIGrEhSBpIHBvc3TEmXB1aiB6Z29kbmllIHoKaW5zdHJ1a2NqYW1pLgoKT3NvYmEsIGt0w7NyYSB6b3N0YcWCYSB6YXByb3N6b25hIGRvIHdzcMOzxYJwcmFjeSwgb3RyenltYSB3aWFkb21vxZvEhyBlLW1haWwKaSBwb3dpbm5hIGJ5xIcgdyBzdGFuaWUgem9iYWN6ecSHIHphcHJvc3plbmllIG5hIEdpdEh1Yi4gTXVzaSBqZQp6YWFrY2VwdG93YcSHLiBQbyB6YWFrY2VwdG93YW5pdSBvYm9qZSBwb3dpbm5pxZtjaWUgbWllxIcgZG9zdMSZcCBkbwp6YXR3aWVyZHphbmlhIHptaWFuIHcgcGxpa3UuCgojIENvbW1pdCAtLVw+IFB1c2ggLS1cPiBQdWxsIC0tXD4gLi4uIChpIGtvbXVuaWthY2phKQoKUG8gZG9kYW5pdSB3c3DDs8WCcHJhY293bmlrw7N3IHdzenlzY3kgd3Nww7PFgnByYWNvd25pY3kgbW9nxIUgemF0d2llcmR6YcSHIGkKd3lweWNoYcSHIHptaWFueS4gQWxlIGNvIHNpxJkgc3RhbmllLCBqZcWbbGkga3RvxZsgemF0d2llcmR6aSBpIHd5cGNobmllCmNvxZssIGEgbmFzdMSZcG5pZSBww7NqZHppZXN6IHByYWNvd2HEhyBuYWQgdHltIG5hIHN3b2ltIGtvbXB1dGVyemUgLi4uIGphawp1enlza2HEhyB0ZSB6bWlhbnk/IC4uLiBQVUxMIQoKVyBzd29pY2ggZ3J1cGFjaCBzcHLDs2J1aiB3eWtvbmHEhyBuYXN0xJlwdWrEhWNlIGN6eW5ub8WbY2kuIEthxbxkeSB6IHdhcwpwb3dpbmllbiBiecSHIHdzcMOzxYJwcmFjb3duaWtpZW0gdyBzd29pY2ggcHJvamVrdGFjaCwgd2nEmWMgbW/FvGVjaWUgem1pZW5pxIcKcm9sZSBwbyB6cm9iaWVuaXUgdGVnbyByYXouCgoxLiAgV3Nww7PFgnByYWNvd25payBtdXNpIG5hanBpZXJ3IHNrbG9ub3dhxIcgcmVwb3p5dG9yaXVtLCBuYWQga3TDs3J5bQogICAgem9zdGHFgiBwb3Byb3N6b255IG8gd3Nww7PFgnByYWPEmS4gSmXFm2xpIG1hIG90d2FydHkgaW5ueSBwcm9qZWt0LAogICAgemFwaXNhxIcsIHphdHdpZXJkemnEhyBpIHd5cGNobsSFxIcgd3N6ZWxraWUgem1pYW55LiBOYXN0xJlwbmllIHphbWtuaWoKICAgIHRlbiBwcm9qZWt0IGkgb3R3w7NyeiBwcm9qZWt0LCBvIGt0w7NyZWdvIHdzcMOzxYJwcmFjxJkgem9zdGHFggogICAgcG9wcm9zem9ueSwga2xvbnVqxIVjIHJlcG96eXRvcml1bSBHaXRIdWIuIFdzcMOzxYJwcmFjb3duaWsgcG93aW5pZW4KICAgIG1pZcSHIG90d2FydHkgcHJvamVrdCB3IFIgU3R1ZGlvLgoKMi4gIFdzcMOzxYJwcmFjb3duaWsgcG93aW5pZW4gc3Byw7Nib3dhxIcgcG9jacSFZ27EhcSHLCBrbGlrYWrEhWMgd29kbsSFIHN0cnphxYJrxJkKICAgIHcgZMOzxYIgdyB6YWvFgmFkY2UgR2l0LiBQb3dpbmllbiBwb2phd2nEhyBzacSZIGtvbXVuaWthdCwga3TDs3J5IHd5Z2zEhWRhCiAgICBuYXN0xJlwdWrEhWNvOgoKIVtdKGltYWdlcy9nb29kX3B1bGwucG5nKQoKMy4gIE9zb2JhLCBrdMOzcmEgdXR3b3J6ecWCYSByZXBvenl0b3JpdW0sIHdwcm93YWR6YSB6bWlhbsSZIHcgc3dvaW0gcGxpa3UKICAgIC5ybWQuIE1vxbxlIHRvIGJ5xIcgbmlld2llbGthIHptaWFuYSwgbmEgcHJ6eWvFgmFkIGRvZGFuaWUgemRhbmlhLiBUYQogICAgc2FtYSBvc29iYSB6YXBpc3VqZSBwbGlrLCB6YXR3aWVyZHphIChldGFwIGkgemFwaXN1amUgd2lhZG9tb8WbxIcKICAgIHphdHdpZXJkemVuaWEpIGkgcHJ6ZXN5xYJhIGdvIGRvIEdpdEh1Yi4gU3ByYXdkxbogb25saW5lLCBhYnkgdXBld25pxIcKICAgIHNpxJksIMW8ZSBuYWpub3dzemUgem1pYW55IHpvc3RhxYJ5IHd5cGNobmnEmXRlLgoKNC4gIFdzcMOzxYJwcmFjb3duaWsgcG9iaWVyYSB0ZXJheiB0ZSB6bWlhbnkgZG8gc3dvamVnbyBsb2thbG5lZ28ga2F0YWxvZ3UKICAgIChuYSBzd8OzaiBrb21wdXRlcikuIEtsaWtuaWogaWtvbsSZIHBvYmllcmFuaWEuIFBvd2luaWVuZcWbIHpvYmFjennEhwogICAgd2lhZG9tb8WbxIcgcG9kb2JuxIUgZG8gdGVqOgoKIVtdKGltYWdlcy9wdWxsX3dpdGhfc3R1ZmYucG5nKQoKU3ByYXdkxbogcGxpaywgdyBrdMOzcnltIGRva29uYW5vIHptaWFueSwgYWJ5IHVwZXduacSHIHNpxJksIMW8ZSB6bWlhbmEKem9zdGHFgmEgb2R6d2llcmNpZWRsb25hIHcgcGxpa3UgbmEga29tcHV0ZXJ6ZS4KCjUuICBQcnplamTFuiB0YW0gaSB6IHBvd3JvdGVtIGplc3pjemUga2lsa2EgcmF6eSwgd3Byb3dhZHphasSFYyBkcm9ibmUKICAgIHptaWFueS4gVGVuLCBrdG8gamVzdCB3xYJhxZtjaWNpZWxlbSByZXBvenl0b3JpdW0sIHBvd2luaWVuIGRva29uYcSHCiAgICB6bWlhbnksIGEgd3Nww7PFgnByYWNvd25payBwb3dpbmllbiBqxIUgd3Byb3dhZHppxIcuIE5hc3TEmXBuaWUgemFtaWXFhGNpZQogICAgc2nEmSByb2xhbWkuIFBvZGN6YXMgcHJ6ZcWCxIVjemFuaWEgdXBld25paiBzacSZLCDFvGUgcHJhY3VqZXN6IHoKICAgIHfFgmHFm2Npd3ltIHByb2pla3RlbS4KCiMgU2NhbCBrb25mbGlrdHkKClBvZGN6YXMgd3Nww7NsbmVqIHByYWN5IG5hZCBwcm9qZWt0ZW0gbW/FvGUgc2nEmSB6ZGFyennEhywgxbxlIGR3aWUgb3NvYnkKYsSZZMSFIGVkeXRvd2HEhyB0ZW4gc2FtIHBsaWsgdyB0eW0gc2FteW0gY3phc2llLiBDemFzYW1pLCBqZcWbbGkgb2JvamUKc3Byw7NidWplY2llIHd5cGNobsSFxIcgc3dvamUgem1pYW55LCBwb2phd2kgc2nEmSB0YWsgendhbnkg4oCea29uZmxpa3QKc2NhbGFuaWHigJ0uIEdpdEh1YiBuaWUgYsSZZHppZSB3aWVkemlhxYIsIGt0w7NyZWdvIHogbmljaCB1xbx5xIcuIFptdXNpIENpxJkKd2nEmWMgZG8gcG9kasSZY2lhIGRlY3l6amkuCgpHZHkgc3Byw7NidWplc3ogcHJ6ZXPFgmHEhyBzd29qZSB6bWlhbnkgZG8gR2l0SHViLCBhIGt0b8WbIGlubnkganXFvCBwcnplc8WCYcWCCnN3b2plIHptaWFueSBkb3R5Y3rEhWNlIHRlZ28gc2FtZWdvIHBsaWt1LCBvdHJ6eW1hc3oga29tdW5pa2F0IHRha2kgamFrCnRlbjoKCiFbXShpbWFnZXMvZ2l0X3B1c2hfbWVyZ2VfY29uZmxpY3QucG5nKQoKTmFzdMSZcG5pZSwgcG8gd2NpxIVnbmnEmWNpdSB6bWlhbiwgcG9qYXdpIHNpxJkgbmFzdMSZcHVqxIVjeSBrb211bmlrYXQ6CgohW10oaW1hZ2VzL2dpdF9wdWxsX21lcmdlX2NvbmZsaWN0LnBuZykKClphdXdhxbwsIMW8ZSBpbmZvcm11amUgb24gbyBwbGlrdSwgdyBrdMOzcnltIHd5c3TEhXBpxYIga29uZmxpa3Qgc2NhbGFuaWEuCk11c2lzeiBvdHdvcnp5xIcgdGVuIHBsaWsgaSB6ZGVjeWRvd2HEhywgamFrIHNjYWxpxIcgc3ByemVjem5lIGluZm9ybWFjamUuCk5hIHBvY3rEhXRrdSBixJlkemllIHRvIHd5Z2zEhWRhxIcgbW5pZWogd2nEmWNlaiB0YWs6CgohW10oaW1hZ2VzL21lcmdlX2NvbmZsaWN0X2ZpeF9jb2RlLnBuZykKCkN6xJnFm8SHIHBvIHPFgm93aWUgYEhFQURgIGplc3QgdHltLCBjbyB6bmFqZHVqZSBzacSZIHcgbG9rYWxueW0gcGxpa3UuCldzenlzdGtvIHBvIGA9PT09PT1gIGplc3QgdHltLCBjbyB6bmFqZHVqZSBzacSZIHcgcGxpa3UgemRhbG55bSAodGouCnptaWFueSB3cHJvd2Fkem9uZSBwcnpleiB3c3DDs8WCcHJhY293bmlrYSkuIE1vxbxlc3ogemRlY3lkb3dhxIcgc2nEmSBuYQpuYXByYXdpZW5pZSB0ZWdvIHcgZG93b2xueSBzcG9zw7NiOiBwb8WCxIVjennEhyBvYmEgcG9teXPFgnksIHVzdW7EhcSHIG9iYSwKemFjaG93YcSHIHR5bGtvIGplZGVuIGl0cC4gUG8gemFrb8WEY3plbml1IHVwZXduaWogc2nEmSwgxbxlIHBvemJ5xYJlxZsgc2nEmQpgPDw8PDw8PCBIRUFEYCBpIGA+Pj4+Pj4+YCwgcG8ga3TDs3J5Y2ggbmFzdMSZcHVqZSBjacSFZyBhbGZhbnVtZXJ5Y3pueQpvcmF6IHdzemVsa2llIGlubmUgZHppd25lIHpuYWtpLgoKTmFzdMSZcG5pZSB6YXBpc3ogcGxpayBpIHd5a29uYWogend5a8WCZSB6YXR3aWVyZHplbmllIGkgd3lwY2huacSZY2llLgpQb3dpbmllbmXFmyB6b2JhY3p5xIcgem1pYW55IHd5cGNobmnEmXRlIGRvIEdpdEh1Yi4KCiMgUHJhY2EgemVzcG/Fgm93YSEKCjEuICBXIGdydXBhY2ggMy00LW9zb2Jvd3ljaCBwcnplxId3aWN6IHN3b2plIHVtaWVqxJl0bm/Fm2NpIEdpdEh1Yi4KCjIuICBHcnVwYSB3eWJpZXJhIHRlYW0tbGlkZXJhLiBUZW4ga3RvxZsgdHdvcnp5IG5vd2UgcmVwbyBuYSBzd29pbSBHaXRIdWIKICAgIG8gbmF6d2llICJuYXN6X3d5a3Jlc2lrIlwKCjMuICBMaWRlciBkb2RhamUgcG96b3N0YcWCZSBvc29ieSBqYWtvIHdzcMOzxYJwcmFjb3duaWvDs3cuXAoKNC4gIFdzcMOzxYJwcmFjb3duaWN5IHBvd2lubmkgc3ByYXdkemnEhyBzd29qxIUgcG9jenTEmSBlLW1haWwgaSB6YWFrY2VwdG93YcSHCiAgICBieWNpZSBUd29pbSB3c3DDs8WCcHJhY293bmlrYW1pLlwKCjUuICBMaWRlciBpIHdzcMOzxYJwcmFjb3duaWN5IGtsb251asSFIHJlcG96eXRvcml1bSBsb2thbG5pZSBuYSBzd29pY2gKICAgIGtvbXB1dGVyYWNoLlwKCjYuICBXc3DDs8WCcHJhY293bmlrIGRvZGFqZSBsb2thbG5pZSBwbGlrIC5ybWQgZG8gcHJvamVrdHUuIFR5dHXFgiBwb3dpbmllbgogICAgYnJ6bWllxIcg4oCeTmFzeiB3eWtyZXPigJ0gaSBkb2Rhd2HEhyB3c3p5c3RraWNoIGN6xYJvbmvDs3cgZ3J1cHkgamFrbwogICAgYXV0b3LDs3cuIERvZGFqIGZyYWdtZW50IGtvZHUgUiwga3TDs3J5IMWCYWR1amUgYmlibGlvdGVrxJkgYHRpZHl2ZXJzZWAuCiAgICBaYXBpc3ogcGxpaywgemF0d2llcmTFuiB6IGtvbXVuaWthdGVtIGkgd3lwY2huaWogbmEgR2l0SHViLiBTcHJhd2TFugogICAgb25saW5lLCBhYnkgdXBld25pxIcgc2nEmSwgxbxlIHBsaWsgem9zdGHFgiBwb3ByYXduaWUgcHJ6ZXPFgmFueS5cCgo3LiAgV3N6eXNjeSBwb3pvc3RhbGkgY3rFgm9ua293aWUgZ3J1cHkgcG9iaWVyYWrEhSB6bWlhbnkgbG9rYWxuaWUuXAoKOC4gIElubnkgd3Nww7PFgnByYWNvd25payBkb2RhamUga29sZWpueSBmcmFnbWVudCBrb2R1IFIuIEtvcnp5c3RhasSFYyB6ZQogICAgemJpb3J1IGRhbnljaCAqbXBnKiwgdXR3w7NyeiB3eWtyZXMgcHVua3Rvd3kgeiAqaHd5KiBuYSBvc2kgeSwKICAgICpkaXNwbCogbmEgb3NpIHggaSBwb2tvbG9ydWogcHVua3R5IHdlZMWCdWcgKmRydiouIFphcGlzeiB6bWlhbnkuCiAgICBaYXR3aWVyZMW6IHBsaWsuIE5hc3TEmXBuaWUgemF0d2llcmTFuiB6IGtvbXVuaWthdGVtIGkgd3lwY2huaWogbmEKICAgIEdpdEh1Yi4gVXBld25paiBzacSZLCDFvGUgd3N6eXN0a2llIHBsaWtpIHpvc3RhxYJ5IHphdHdpZXJkem9uZS4KICAgIFNwcmF3ZMW6IG9ubGluZSwgYWJ5IHVwZXduacSHIHNpxJksIMW8ZSB3aWR6aXN6IHptaWFueS5cCgo5LiAgV3N6eXNjeSBwb3pvc3RhbGkgY3rFgm9ua293aWUgZ3J1cHkgcG9iaWVyYWrEhSB6bWlhbnkgbG9rYWxuaWUuCgoxMC4gSW5ueSBjesWCb25layBncnVweSAod3Nww7PFgnByYWNvd25payBsdWIgdHfDs3JjYSwgamXFm2xpIG1hc3ogdHlsa28gMwogICAgY3rFgm9ua8OzdyBncnVweSkgbW9keWZpa3VqZSBmcmFnbWVudCBrb2R1IFIsIGt0w7NyeSB0d29yenkgd3lrcmVzLAogICAgZG9kYWrEhWMgxYJhZG5lIGV0eWtpZXR5IHggaSB5IG9yYXogem1pZW5pYWrEhWMgYHRoZW1lX21pbmltYWwoKWAuCiAgICBaYXBpc3ogem1pYW55LiBaYXR3aWVyZMW6IHBsaWsuIE5hc3TEmXBuaWUgemF0d2llcmTFuiB6IHdpYWRvbW/Fm2NpxIUgaQogICAgd3nFm2xpaiBuYSBHaXRIdWIuIFVwZXduaWogc2nEmSwgxbxlIHdzenlzdGtpZSBwbGlraSB6b3N0YcWCeQogICAgemF0d2llcmR6b25lLiBTcHJhd2TFuiBvbmxpbmUgbmEgZ2l0aHViaWUsIGFieSB1cGV3bmnEhyBzacSZLCDFvGUKICAgIHdpZHppc3ogem1pYW55LlwKCjExLiBXc3p5c2N5IGN6xYJvbmtvd2llIGdydXB5IHd5a29udWrEhSAiUHVsbCIuIE9zb2JhLCBrdMOzcmEgd8WCYcWbbmllCiAgICBkb2tvbmHFgmEgcHVzaCBwb3dpbm5hIHpvYmFjennEhywgxbxlIGplc3QganXFvCBuYSBiaWXFvMSFY28uIFdzenlzY3kgaW5uaQogICAgcG93aW5uaSB6b2JhY3p5xIcgem1pYW55IG9kendpZXJjaWVkbG9uZSBsb2thbG5pZS5cCgoxMi4gVGVyYXogd3N6eXNjeSBjesWCb25rb3dpZSBncnVweSBwb3dpbm5pIGRvZGHEhyBjb8WbIGRvIHBsaWt1IC5ybWQuIE5pZQogICAgbcOzd2NpZSBzb2JpZSBuYXd6YWplbSwgY28gZG9kYWplY2llLiBHZHkgc2tvxYRjenljaWUsIHphcGlzemNpZSwKICAgIHphdHdpZXJkxbpjaWUgaSB3ecWbbGlqY2llIGRvIEdpdEh1Yi4gUHJ6eW5ham1uaWVqIGplZGVuIHogd2FzIG90cnp5bWEKICAgIGtvbmZsaWt0IHNjYWxhbmlhLCB3acSZYyBwb3Byb3NpIGNpxJkgbyBwb2JyYW5pZSB6bWlhbiB6IEdpdEh1YiBpCiAgICBuYXByYXdpZW5pZSBrb25mbGlrdHUuIFpyw7NiIHRvLiBUeW0gcmF6ZW0gYsSZZHppZXN6IG11c2lhxYIKICAgIHptb2R5Zmlrb3dhxIcgcGxpayAucm1kLCBhIG5pZSBSRUFETUUsIGphayBwb2themHFgmVtIHdjemXFm25pZWouCgojIMW5csOzZMWCbwoKW0hhcHB5IGdpdCB3aXRoIFIgYXV0b3JzdHdhIEplbm55IEJyeWFuXShodHRwczovL2hhcHB5Z2l0d2l0aHIuY29tLyk6CsWbd2lldG5lIMW6csOzZMWCbywgY2hvxIcgc3Bvcm8gdyBuaW0gb2RuaWVzaWXFhCBkbyB3aWVyc3phIHBvbGVjZcWELgo=