\[BACHELOR\ NE\ INXHINIERI\ MATEMATIKE\ DHE\ INFORMATIKE\]

\[DATA\ ANALYSIS\ NE\ RSTUDIO\]

\[Realizuar\ nga\ Jakup\ Ymeraj\ dhe\ Adisa\ Hoxhaj\]

\[Fakulteti\ i\ Shkencave\ te\ Natyres\\ Qershor\ 2024\]

Prezantimi me RStudio

\[RStudio\]

Cfare eshte RStudio?

R eshte nje gjuhe programimi e specializuar ne llogaritje statistikore dhe vizualizimin e te dhenave, e miratuar nga fushat e nxjerrjes se te dhenave, bioinformatikes dhe analizes se te dhenave.

\(RStudio\) eshte nje mjedis zhvillimi i integruar per gjuhen \(R\)

Kjo platforme eshte e disponueshme ne dy formate: \(RStudio\) \(Desktop\) i cila eshte nje aplikacion i rregullt desktop dhe \(Rstudio\) \(Server\) i cili funksionon ne nje server te madh dhe lejon hyrjen ne \(RStudio\) duke perdorur nje shfletues web. \(RStudio\) \(IDE\) eshte nje produkt i \(Posit\) \(PBC\) (dikur \(RStudio\) \(PBC\), me pare \(RStudio\) \(Inc.\)).

RStudio perfshin:

• nje mjet efektiv per trajtimin dhe ruajtjen e te dhenave;

• nje grup operatoresh per llogaritjet ne vargje, ne vecanti matrica;

• nje koleksion te madh, koherent dhe te integruar te mjeteve te ndermjetme per analizen e te dhenave;

• pajisje grafike per analizen dhe shfaqjen e te dhenave ne ekran ose ne kopje fizike;

• nje gjuhe programimi te zhvilluar mire, e thjeshte dhe efektive, e cila perfshin kushte, funksione rekursive te percaktuara nga perdoruesi dhe pajisje hyrese-dalese;

\[Objektivat:\]

Ne kete projekt kemi si synim:

~ Te shqyrtojme ne menyre analitike, statistikore dhe grafike te dhenat e datasetit ne gjuhen \(R\);

~ Te jemi te afte te lexojme dhe interpretojme kodet e perdorura dhe te shpjegojme qellimin e perdorimit te tyre;

~ Te analizojme cdo grafik te ndertuar;

~ Te evidentojme dhe perdorim te gjithe funksionet dhe librarite e ndryshme te mesuara ne seancat laboratorike dhe me gjere;

Njohje me Databazen

\[Student\ Spending\ Dataset\]

Dataseti i zgjedhur titullohet \(Student\) \(Spending\) dhe ne te listohen te ardhurat dhe shpenzimet e 1000 studenteve te zgjedhur ne nje zgjedhje te rastit, ku ne thelbin e studimit qendron fakti se ne varesi te moshes, formimit arsimor dhe gjinise, sa fiton, sa shpenzon dhe si i shpenzon nje student te ardhurat mujore te tij. Nje rendesi e vecante i eshte kushtuar edhe menyres sesi parate transaksionohen, duke na lene te kuptojme se si nje student preferon te paguaje dhe paguhet gjate veprimtarise se tij te perditshme.

CREDITS: \(Student\) \(Spending\) \(Dataset\) eshte shkarkuar ne \(kaggle.com/datasets\), duke qene brenda rregullave dhe kritereve me te cilat web-faqja \(kaggle.com\) funksionon!

Le te njihemi me datasetin \(Student\) \(Spending\):

Ky dataset perbehet nga variabla dhe vlera si me poshte:

Fillimisht na duhet te importojme datasetin nga file explorer dhe per ta bere kete na duhet libraria \(readxl\) e cila do te lexoje skedarin excel dhe me pas perdorim funksionin \(setwd()\) i cili do te marre si parameter path-in e file qe duam te importojme:

library(readxl)
Warning: package ‘readxl’ was built under R version 4.3.3
setwd("C:/Users/Perdorues/Downloads")
Warning: The working directory was changed to C:/Users/Perdorues/Downloads inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
getwd()
[1] "C:/Users/Perdorues/Downloads"
data  = read.csv("student_spending.csv")
data

\(Student\) \(Spending\) permban 17 lloje te ndryshme ndryshoresh, ku seciles ndryshore i korrespondojne 1000 te dhena;

Dataseti ka gjithsej 4 \(ndryshore\) \(cilesore\) dhe 13 \(ndryshore\) \(sasiore\);

\(Ndryshoret\) \(Cilesore:\)

Gjinia;

Viti i Studimeve;

Diplomimi;

Metoda e Pageses;

\(Ndryshoret\) \(Sasiore:\)

Mosha

Te ardhurat mujore

Ndihma financiare

Shkollimi

Strehimi

Ushqimi

Transporti

Mjetet shkollore

Argetim

Kujdesi personal

Teknologji

Mireqenia shendetesore

Te ndryshme/ Te tjera

\[Cdo\ ndryshore\ do\ te\ analizohet\ nga\ ana\ statistikore!\]

Analiza e te Dhenave

\(Analiza\) \(e\) \(te\) \(dhenave\)\(RStudio\) eshte nje proces ku perpunohen, vizualizohen dhe interpretohen te dhenat per te nxjerre informacione dhe kuptim nga to. Ne kete proces perfshihet importimi, pastrimi, perpunimi, vizualizimi dhe interpretimi i te dhenave ne nje menyre sa me te sakte.

Per te bere nje analize te sakte te te dhenave do fillojme te aplikojme disa metoda te cilat jane themelore ne data analysis.

\(Librarite\) \(e\) \(perdorura\) \(ne\) \(analizimin\) \(e\) \(te\) \(dhenave\) \(jane:\)

library(readxl)

library(ggpubr)

library(tidytext)

library(correlation)

library(tidyr)

library(corrplot)

library(DataExplorer)

library(MASS)

library(survey)

library(datawizard)

library(stats)

library(grid)

library(wordcloud)

library(tidyverse)

library(RColorBrewer) etj..

\[PERPUNIMI\ I\ TE\ DHENAVE\]

Per te nisur perpunimin e te dhenave fillimisht duhet te lexojme datasetin me ane te funksionit \(stwd()\), gjithashtu duhet te perdorim edhe librarine \(readxl\) e cila do te lexoje skedarin tone excel.

library(readxl)
setwd("C:/Users/Perdorues/Downloads")
Warning: The working directory was changed to C:/Users/Perdorues/Downloads inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
getwd()
[1] "C:/Users/Perdorues/Downloads"

Funksioni \(getwd()\) na jep file path.

Tregojme cfare klase eshte dataseti:

class(data) 
[1] "data.frame"

Percaktojme dimensionin/permasen e datasetit:

dim(data)
[1] 1000   17

Rezultati i shfaqur na tregon se dataseti perbehet nga 1000 rreshta dhe 17 kolona.

Shfaqim strukturen e objektit tone te te dhenave (\(Data\) \(Frame\)). Ky veprim arrihet duke aplikuar funksionin \(str(data)\) dhe me anen e tij ne percaktojme:

1.Numrin e rreshtave dhe kolonave te datasetit;

2.Tipin e te dhenave per secilen kolone si int, char, boolean etj.;

3.Nje pjese te vogel te te dhenave ne dataset;

str(data)
'data.frame':   1000 obs. of  17 variables:
 $ mosha                 : int  19 24 24 23 20 25 23 23 22 18 ...
 $ gjinia                : chr  "Non-binary" "Female" "Non-binary" "Female" ...
 $ viti_i_studimeve      : chr  "Freshman" "Junior" "Junior" "Senior" ...
 $ diplomimi             : chr  "Psychology" "Economics" "Economics" "Computer Science" ...
 $ te_ardhurat_mujore    : int  958 1006 734 617 810 523 1354 631 1402 1423 ...
 $ ndihma_financiare     : int  270 875 928 265 522 790 69 748 248 74 ...
 $ shkollimi             : int  5939 4908 3051 4935 3887 3151 4973 3966 5638 3977 ...
 $ strehimi              : int  709 557 666 652 825 413 812 571 599 626 ...
 $ ushqimi               : int  296 365 220 289 372 386 398 269 354 249 ...
 $ transporti            : int  123 85 137 114 168 122 101 92 82 117 ...
 $ mjetet_shkollore      : int  188 252 99 223 194 131 213 251 155 123 ...
 $ argetim               : int  41 74 130 99 48 73 21 37 123 51 ...
 $ kujdesi_personal      : int  78 92 23 30 71 38 38 90 41 74 ...
 $ teknologji            : int  134 226 239 163 88 234 157 152 162 243 ...
 $ mireqenia_shendetesore: int  127 129 112 105 71 108 117 56 172 34 ...
 $ te_ndryshme           : int  72 68 133 55 104 99 48 62 194 196 ...
 $ metoda_e_pageses      : chr  "Credit/Debit Card" "Credit/Debit Card" "Cash" "Mobile Payment App" ...

Aplikojme funksionin \(summary(data)\) per te kryer nje permbledhje te shpejte, paraprake te te dhenave ne dataset.

Rezultati i kthyer nga \(summary(data)\) perfshin informacione si:

~Vlerat ekstremale (max, min), mesatarja, mesorja, moda,kuartili i pare, kuartili i 3-te;

~Numrin e vlerave qe mungojne ne secilen nga kolonat e datasetit (NAN).

~Nje permbledhje te te dhenave per vlerat e ndryshoreve cilesore, duke perfshire numrin e vlerave unike dhe frekuencen e tyre.

Kjo ndihmon ne njohjen e shperndarjes se te dhenave ne kolona duke perfshire vlerat minimale dhe maksimale, vleren mesatare dhe tendencat e tjera statistikore.

summary(data)
     mosha          gjinia          viti_i_studimeve    diplomimi         te_ardhurat_mujore ndihma_financiare   shkollimi   
 Min.   :18.00   Length:1000        Length:1000        Length:1000        Min.   : 501.0     Min.   :   0.0    Min.   :3003  
 1st Qu.:20.00   Class :character   Class :character   Class :character   1st Qu.: 770.8     1st Qu.: 261.0    1st Qu.:3780  
 Median :22.00   Mode  :character   Mode  :character   Mode  :character   Median :1021.0     Median : 513.0    Median :4548  
 Mean   :21.68                                                            Mean   :1020.6     Mean   : 504.8    Mean   :4520  
 3rd Qu.:24.00                                                            3rd Qu.:1288.2     3rd Qu.: 751.5    3rd Qu.:5285  
 Max.   :25.00                                                            Max.   :1500.0     Max.   :1000.0    Max.   :6000  
    strehimi         ushqimi        transporti    mjetet_shkollore    argetim       kujdesi_personal   teknologji   
 Min.   : 401.0   Min.   :100.0   Min.   : 50.0   Min.   : 50.0    Min.   : 20.00   Min.   : 20.0    Min.   : 50.0  
 1st Qu.: 538.8   1st Qu.:175.0   1st Qu.: 88.0   1st Qu.:112.0    1st Qu.: 54.00   1st Qu.: 41.0    1st Qu.:114.0  
 Median : 704.5   Median :255.0   Median :123.0   Median :175.0    Median : 86.00   Median : 62.0    Median :178.0  
 Mean   : 696.0   Mean   :252.6   Mean   :124.6   Mean   :174.8    Mean   : 84.81   Mean   : 60.7    Mean   :178.3  
 3rd Qu.: 837.2   3rd Qu.:330.0   3rd Qu.:162.2   3rd Qu.:238.0    3rd Qu.:116.00   3rd Qu.: 80.0    3rd Qu.:241.0  
 Max.   :1000.0   Max.   :400.0   Max.   :200.0   Max.   :300.0    Max.   :150.00   Max.   :100.0    Max.   :300.0  
 mireqenia_shendetesore  te_ndryshme     metoda_e_pageses  
 Min.   : 30.0          Min.   : 20.00   Length:1000       
 1st Qu.: 73.0          1st Qu.: 63.75   Class :character  
 Median :115.0          Median :110.00   Mode  :character  
 Mean   :114.3          Mean   :108.91                     
 3rd Qu.:158.0          3rd Qu.:153.00                     
 Max.   :200.0          Max.   :200.00                     

Kontrollojme per numra qe mungojne:

num <- sum(is.na(data))
num
[1] 0

Kontrollojme per vlera duplicated:

dupl <- sum(duplicated(data))
dupl
[1] 0

Meqenese nuk mungojne vlera dhe nuk ka vlera duplicated, grupi i te dhenave eshte i paster.

\[ANALIZA\ E\ NDRYSHOREVE\ SASIORE\]

\(Ndryshoret\) \(Sasiore\) klasifikohen ne ndryshore \(diskrete\) dhe \(te\) \(vazhdueshme\).

Ndryshoret Sasiore ne datasetin tone jane diskrete, me vlera te fundme, qe do te thote se ato do te pershkruhen numerikisht nepermjet efektivave, frekuencave dhe tabelave statistikore.

Ne kete headline do te trajtojme analizen e treguesve te pozicionit ku perfshihen mesatarja, moda, mesorja, kuartilet dhe treguesit e shperhapjes, intervalet nderkuartilore, amplituda, dispersioni dhe menjanimi mesatar katror.

Mesatarja, Moda, Mesorja & Kuartilet, Intervalet Nderkuartilore;

\[Mesatarja\ Aritmetike\]

\(Mesatarja\) \(Aritmetike\) ne statistike eshte nje parameter qe tregon pozicionin e vlerave te ndryshores. Ajo paraqet vleren e pergjithshme te nje grupi te te dhenave dhe ka kuptim vetem kur ndryshorja eshte sasiore. Per te llogaritur vleren mesatare te dhenat mblidhen se bashku dhe me pas pjesetohen me numrin e tyre te pergjithshem.

\[Formula\ matematike:\\{\displaystyle {\overline {X}}={\frac {X_{1}+\cdots +X_{n}}{n}}}={\frac {1}{n} \sum _{i=1}^{n}{x_{i}}}\]

Le te kryejme nje llogaritje te vlerave mesatare per cdo variabel sasiore ne dataset nepermjet funksionit \(mean()\).

Per te kryer kete llogaritje per cdo ndryshore sasiore do ti therrasim ato me ate te funksionit \(df\)$\(emri\)_\(variablit\):

Mosha mesatare e nje studenti ne dataset eshte:

mean_mosha <- mean(data$mosha)
print(mean_mosha)
[1] 21.675

Te ardhurat mesatare te studenteve jane:

mean_te_ardhurat_mujore <- mean(data$te_ardhurat_mujore)
print(mean_te_ardhurat_mujore)
[1] 1020.65

Ndihma financiare qe i atribohet cdo studenti mesatarisht arrin vleren:

mean_ndihma_financiare <- mean(data$ndihma_financiare)
print(mean_ndihma_financiare)
[1] 504.771

Shuma qe nje student shpenzon mesatarisht per shkollimin e tij:

mean_shkollimi <- mean(data$shkollimi)
print(mean_shkollimi)
[1] 4520.395

Shuma qe nje student shpenzon mesatarisht per te siguruar strehimin e tij:

mean_strehimi <- mean(data$strehimi)
print(mean_strehimi)
[1] 696.006

Shuma qe nje student shpenzon mesatarisht ne muaj per te siguruar ushqimin e tij:

mean_ushqimi <- mean(data$ushqimi)
print(mean_ushqimi)
[1] 252.642

Shuma qe nje student shpenzon mesatarisht ne muaj per sa i perket transportit:

mean_transporti <- mean(data$transporti)
print(mean_transporti)
[1] 124.637

Shuma qe nje student shpenzon mesatarisht ne muaj per te siguruar mjetet e tij shkollore (ketu perfshihen libra, fotokopje, lapsa, ngjyra etj.):

mean_mjetet_shkollore <- mean(data$mjetet_shkollore)
print(mean_mjetet_shkollore)
[1] 174.761

Shuma qe nje student shpenzon mesatarisht ne muaj per t’u argetuar:

mean_argetim <- mean(data$argetim)
print(mean_argetim)
[1] 84.814

Shuma mesatare qe nje student ia dedikon kujdesit te tij personal si qethje, parukiere, veshje, higjiene etj.

mean_kujdesi_personal <- mean(data$kujdesi_personal)
print(mean_kujdesi_personal) 
[1] 60.699

Shuma qe nje student shpenzon mesatarisht ne muaj ne aspektin e teknologjise; ketu perfshihen telefon, laptop/pc dhe cdo angazhim tjeter ne kete fushe:

mean_teknologji <- mean(data$teknologji)
print(mean_teknologji)
[1] 178.304

Shuma qe nje student ia dedikon mireqenies se tij shendetesore, duke perfshire vizitat mjekesore, konsultat te dentisti, medikamente farmaceutike etj.:

mean_mireqenia_shendetesore <- mean(data$mireqenia_shendetesore)
print(mean_mireqenia_shendetesore)
[1] 114.31

Shuma qe nje student shpenzon per cdo aktivitet tjeter ne perditshmerine e tij; kjo shume varet nga teprica e shumes monetare te mbetur ne llogarine e tij:

mean_te_ndryshme <- mean(data$te_ndryshme)
print(mean_te_ndryshme)
[1] 108.91

\[Mesatarja\ e\ Grupuar\]

Tani le te llogarisim shpenzimet mujore te studenteve sipas kategorive/grupimeve;

Per ta realizuar na duhen dy librari: libraria \(dplyr\) dhe \(tidyr\); Ne fillimisht do ti kategorizojme te dhenat ne disa grupime dhe me pas do te llogarisim se sa shpenzon secila prej tyre mesatarisht;

Grupojme te dhenat me ane te funksionit \(group\)_\(by\):

library(dplyr)
Warning: package ‘dplyr’ was built under R version 4.3.3

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
library(tidyr)
Warning: package ‘tidyr’ was built under R version 4.3.3
grupi_mosha <- data %>% group_by(data$mosha)
grupi_gjinia <- data %>% group_by(data$gjinia)
grupi_viti_i_studimeve <- data %>% group_by(data$viti_i_studimeve)
grupi_diplomimi <- data %>% group_by(data$diplomimi)

Shpenzimet e grupimit \(mosha\):

shpenzimet_mesatare_mosha <- grupi_mosha %>%
  summarize(
    shkollimi = mean(shkollimi),
    strehimi = mean(strehimi),
    ushqimi = mean(ushqimi),
    transporti = mean(transporti),
    mjetet_shkollore = mean(mjetet_shkollore),
    argetim = mean(argetim),
    kujdesi_personal = mean(kujdesi_personal),
    teknologji = mean(teknologji),
    mireqenia_shendetesore = mean(mireqenia_shendetesore),
    te_ndryshme = mean(te_ndryshme)
  )

Shpenzimet mesatare per cdo kategori te shpenzimeve brenda cdo grupi te moshes jane:

print(shpenzimet_mesatare_mosha)

Kodi:

Fillimisht therrasim librarite e nevojshme \(dplyr\) dhe \(tidyr\).

\(grupi\)_\(mosha\) \(<-\) \(data\) \(`%>%`\) \(group\)_\(by(data`\)mosha)$ kryen grupimin e kerkuar, duke marre si parameter emrin e kolones se datasetit mbi te cilen kerkojme te kryejme nje llogaritje te tille statistikore ($mosha$). E njejta procedure perdoret ne 3 rreshtat pasues te kodit, ku kryhet grupimi per variablat $gjinia$, $viti$$i$`\(studimeve\) dhe \(diplomimi\)

Pasi kemi kryer te gjitha grupimet e deshiruara, duke perdorur funksionin \(summarize(...)\) ne llogaritim nje mesatare te grupimeve te mesiperme ku perfshihen fushat si \(shkollimi\), \(strehimi\), \(ushqimi\) etj., te cilat afishohen ne nje tabele.

Leximi i tabeles eshte i tille: 18 vjecaret shpenzojne mesatarisht $4485.952 per shkollimin, $712.2419 per strehim, e keshtu me rradhe per te gjitha kategorite e tjera ne tabele.

E njejta menyre interpretimi vlen per cdo tabele tjeter te ndertuar me poshte.

Shpenzimet e grupimit \(gjinia\):

shpenzimet_mesatare_gjinia <- grupi_gjinia %>%
  summarize(
    shkollimi = mean(shkollimi),
    strehimi = mean(strehimi),
    ushqimi = mean(ushqimi),
    transporti = mean(transporti),
    mjetet_shkollore = mean(mjetet_shkollore),
    argetim = mean(argetim),
    kujdesi_personal = mean(kujdesi_personal),
    teknologji = mean(teknologji),
    mireqenia_shendetesore = mean(mireqenia_shendetesore),
    te_ndryshme = mean(te_ndryshme)
  )

Shpenzimet mesatare per cdo kategori te shpenzimeve brenda cdo grupi te gjinise jane:

print(shpenzimet_mesatare_gjinia)

Shpenzimet e grupimit \(viti\) \(i\) \(studimeve\):

shpenzimet_mesatare_viti_i_studimeve <- grupi_viti_i_studimeve %>%
  summarize(
    shkollimi = mean(shkollimi),
    strehimi = mean(strehimi),
    ushqimi = mean(ushqimi),
    transporti = mean(transporti),
    mjetet_shkollore = mean(mjetet_shkollore),
    argetim = mean(argetim),
    kujdesi_personal = mean(kujdesi_personal),
    teknologji = mean(teknologji),
    mireqenia_shendetesore = mean(mireqenia_shendetesore),
    te_ndryshme = mean(te_ndryshme)
  )

Shpenzimet mesatare per cdo kategori te shpenzimeve brenda cdo grupi te vitit te studimeve jane:

print(shpenzimet_mesatare_viti_i_studimeve)

Shpenzimet e grupimit \(diplomimi\):

shpenzimet_mesatare_diplomimi <- grupi_diplomimi %>%
  summarize(
    shkollimi = mean(shkollimi),
    strehimi = mean(strehimi),
    ushqimi = mean(ushqimi),
    transporti = mean(transporti),
    mjetet_shkollore = mean(mjetet_shkollore),
    argetim = mean(argetim),
    kujdesi_personal = mean(kujdesi_personal),
    teknologji = mean(teknologji),
    mireqenia_shendetesore = mean(mireqenia_shendetesore),
    te_ndryshme = mean(te_ndryshme)
  )

Shpenzimet mesatare per cdo kategori te shpenzimeve brenda cdo grupi te diplomimit jane:

print(shpenzimet_mesatare_diplomimi)

\[Moda\]

\(Moda\) ne statistike eshte vlera qe paraqitet me shpesh ne nje grup te te dhenave.

Moda mund te aplikohet ne te dhenat e shprehura ne forme numerike, si dhe ne te dhenat kategorike qe perbehen nga kategori ose etiketa.

Ne disa raste nje grup i te dhenave mund te kete me shume se nje modalitet me vlera te njejte te shpeshta. Ne kete rast grupi quhet \(bimodal\) ose \(multimodal\). Perveç kesaj, ndonjehere mund te ndodhe qe grupi te mos kete mode fare, ne rastin kur te dhenat jane te shperndara ne menyre te barabarte dhe nuk ka vlere qe paraqitet me shume se te tjerat.

Le te gjejme vlerat modale ne te dhenat tona per secilen variabel sasiore me ane te funksionit \(names\)(\(table\)(\(df\)$\(variabli\)))[\(table\)(\(df\)$\(variabli\)) \(==\) \(max\)(\(table\)(\(df\)$\(variabli\)))]:

Mosha e perseritur me shpesh:

mode_mosha <- names(table(data$mosha))[table(data$mosha) == max(table(data$mosha))]
print(mode_mosha)
[1] "25"

Vlera e te ardhurave qe perseritet me teper:

mode_te_ardhurat_mujore <- names(table(data$te_ardhurat_mujore))[table(data$te_ardhurat_mujore) == max(table(data$te_ardhurat_mujore))]
print(mode_te_ardhurat_mujore)
[1] "1021" "1126" "1176" "1268" "1309" "1354" "1483"

Vlera e ndihmes financiare e perseritur me shpesh:

mode_ndihma_financiare <- names(table(data$ndihma_financiare))[table(data$ndihma_financiare) == max(table(data$ndihma_financiare))]
print(mode_ndihma_financiare)
[1] "387" "671"

Vlera e perseritur me shpesh per sa i perket shpenzimit mbi shkollimin:

mode_shkollimi <- names(table(data$shkollimi))[table(data$shkollimi) == max(table(data$shkollimi))]
print(mode_shkollimi)
[1] "5452"

Vlera e perseritur me shpesh per sa i perket shpenzimit mbi strehimin:

mode_strehimi <- names(table(data$strehimi))[table(data$strehimi) == max(table(data$strehimi))]
print(mode_strehimi)
[1] "759"

Vlera e perseritur me shpesh per sa i perket shpenzimit mbi ushqyerjen:

mode_ushqimi <- names(table(data$ushqimi))[table(data$ushqimi) == max(table(data$ushqimi))]
print(mode_ushqimi)
[1] "249"

Vlera e perseritur me shpesh per sa i perket shpenzimit mbi transportin:

mode_transporti <- names(table(data$transporti))[table(data$transporti) == max(table(data$transporti))]
print(mode_transporti)
[1] "60"  "179" "182"

Vlera e perseritur me shpesh per sa i perket shpenzimit mbi mjetet shkollore:

mode_mjetet_shkollore <- names(table(data$mjetet_shkollore))[table(data$mjetet_shkollore) == max(table(data$mjetet_shkollore))]
print(mode_mjetet_shkollore)
[1] "87"  "112" "183"

Vlera e perseritur me shpesh per sa i perket shpenzimit mbi argetimin:

mode_argetim <- names(table(data$argetim))[table(data$argetim) == max(table(data$argetim))]
print(mode_argetim)
[1] "129"

Vlera e perseritur me shpesh per sa i perket shpenzimit mbi kujdesin personal:

mode_kujdesi_personal <- names(table(data$kujdesi_personal))[table(data$kujdesi_personal) == max(table(data$kujdesi_personal))]
print(mode_kujdesi_personal)
[1] "21" "60" "81"

Vlera e perseritur me shpesh per sa i perket shpenzimit mbi teknologjine:

mode_teknologji <- names(table(data$teknologji))[table(data$teknologji) == max(table(data$teknologji))]
print(mode_teknologji)
[1] "77"

Vlera e perseritur me shpesh per sa i perket shpenzimit mbi mireqenien shendetesore:

mode_mireqenia_shendetesore <- names(table(data$mireqenia_shendetesore))[table(data$mireqenia_shendetesore) == max(table(data$mireqenia_shendetesore))]
print(mode_mireqenia_shendetesore)
[1] "87"

Vlera e perseritur me shpesh per sa i perket shpenzimeve te tjera qe studentet kryejne:

mode_te_ndryshme <- names(table(data$te_ndryshme))[table(data$te_ndryshme) == max(table(data$te_ndryshme))]
print(mode_te_ndryshme)
[1] "196"

\[Mesorja\]

\(Mesorja\) në statistike eshte nje mase qendrore e cila paraqet vleren e mesme ose vleren qe ndan nje grup te dhene te te dhenave ne dy pjese te barabarta. Nenkupton qe gjysma e te dhenave jane me te medha se mesorja dhe gjysma tjeter jane me te vogla.

Mesorja llogaritet duke e renditur grupin e të dhenave ne rradhe te rritjes se vlerave dhe duke gjetur vleren qe ndodhet ne mesin e tyre. Nese numri i te dhenave eshte çift, atehere mesorja eshte vlera e mesme e dy vlerave të qendruara. Nese numri i te dhenave eshte tek, atehere mesorja eshte vlera e vetme qe ndodhet ne mes te grupit.

Gjejme mesoren per secilen ndryshore sasiore me ane te funksionit \(median()\):

Mesorja e moshes:

median_mosha <- median(data$mosha)
print(median_mosha)
[1] 22

Mesorja e te ardhurave mujore:

median_te_ardhurat_mujore <- median(data$te_ardhurat_mujore)
print(median_te_ardhurat_mujore)
[1] 1021

Mesorja e ndihmes financiare:

median_ndihma_financiare <- median(data$ndihma_financiare)
print(median_ndihma_financiare)
[1] 513

Mesorja e shumave te shpenzuara per shkollim:

median_shkollimi <- median(data$shkollimi)
print(median_shkollimi)
[1] 4547.5

Mesorja e shumave te shpenzuara per strehim:

median_strehimi <- median(data$strehimi)
print(median_strehimi)
[1] 704.5

Mesorja e shumave te shpenzuara per ushqim:

median_ushqimi <- median(data$ushqimi)
print(median_ushqimi)
[1] 255

Mesorja e shumave te shpenzuara per transport:

median_transporti <- median(data$transporti)
print(median_transporti)
[1] 123

Mesorja e shumave te shpenzuara per mjete shkollore:

median_mjetet_shkollore <- median(data$mjetet_shkollore)
print(median_mjetet_shkollore)
[1] 175

Mesorja e shumave te shpenzuara per argetim:

median_argetim <- median(data$argetim)
print(median_argetim)
[1] 86

Mesorja e shumave te shpenzuara per kujdes personal:

median_kujdesi_personal <- median(data$kujdesi_personal)
print(median_kujdesi_personal)
[1] 62

Mesorja e shumave te shpenzuara ne fushen e teknologjise:

median_teknologji <- median(data$teknologji)
print(median_teknologji)
[1] 178

Mesorja e shumave te shpenzuara per mireqenien shendetesore:

median_mireqenia_shendetesore <- median(data$mireqenia_shendetesore)
print(median_mireqenia_shendetesore)
[1] 115

Mesorja e shumave te shpenzuara per shpenzime te tjera te ndryshme:

median_te_ndryshme <- median(data$te_ndryshme)
print(median_te_ndryshme)
[1] 110

\[Kuartilet\]

\(Kuartilet\) ne statistike jane vlerat qe ndajne nje grup te te dhenave ne kater pjese te barabarta. Keto pjese perbehen nga 25% te te dhenave te renditura ne rradhe te rritjes se tyre.

Kuartilet perdoren per te vleresuar shperndarjen e te dhenave dhe per te identifikuar vlerat e rendesishme ne grup. Ketu jane tre lloje kuartilesh te zakonshme:

1. Kuartili i pare \(Q1\) eshte vlera qe ndan 25% te te dhenave me te vogla nga grupi i te dhenave te renditura. Nenkupton se 25% e te dhenave jane me te vogla se kuartili i pare dhe 75% jane me te medha se kjo vlere.

2. Kuartili i dyte ose mesi \(Q2\) eshte vlera qe ndan grupin e te dhenave ne dy pjese te barabarta. Njeren gjysme me vlerat me te vogla dhe gjysmen tjeter me vlerat me te medha.

3. Kuartili i trete \(Q3\) eshte vlera qe ndan 75% te te dhenave me te medha nga grupi i te dhenave te renditura. Kjo nenkupton se 75% e te dhenave jane me te vogla se kuartili i trete dhe 25% jane me te medha.

Le te llogaritim kuartilet me ane te funksionit \(quantile()\) dhe intervalet nderkuartilore per secilen ndryshore sasiore me ane te funksionit \(IQR()\):

Kuartilet e moshes:

q75 <- quantile(data$mosha, 0.75)  
q25 <- quantile(data$mosha, 0.25) 
quantile(data$mosha)
  0%  25%  50%  75% 100% 
  18   20   22   24   25 
IQR(data$mosha)
[1] 4

Ky rezultat tregon vlerat perkatese te kuantileve per kolonen “mosha” ne dataset:

• 0%: Vlera minimale e te dhenave eshte 18.

• 25%: Kjo eshte vlera e kuantilit te 25%, qe ne kete rast eshte 20. Kjo do te thote qe 25% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 50%: Kjo eshte vlera qendrore, e njohur si mesorja, qe ne kete rast eshte 22. Kjo tregon se 50% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 75%: Kjo eshte vlera e kuantilit te 75%, qe ne kete rast eshte 24. Kjo do te thote qe 75% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 100%: Vlera maksimale e te dhenave eshte 25.

Funksioni IQR afishon vleren 4, kjo do te thote se diferenca midis kuantilit te 25% dhe kuantilit te 75% eshte 4. Kjo tregon se 50% e te dhenave jane te perhapura ne nje interval prej 4 njesi.

Kuartilet e te ardhurave mujore:

q75 <- quantile(data$te_ardhurat_mujore, 0.75)  
q25 <- quantile(data$te_ardhurat_mujore, 0.25) 
quantile(data$te_ardhurat_mujore)
     0%     25%     50%     75%    100% 
 501.00  770.75 1021.00 1288.25 1500.00 
IQR(data$te_ardhurat_mujore)
[1] 517.5

Ky rezultat tregon vlerat perkatese te kuantileve per kolonen “te_ardhurat_mujore” ne dataset:

• 0%: Vlera minimale e te dhenave eshte 501.00.

• 25%: Kjo eshte vlera e kuantilit te 25%, qe ne kete rast eshte 770.75. Kjo do te thote qe 25% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 50%: Kjo eshte vlera qendrore, e njohur si mesorja, qe ne kete rast eshte 1021.00. Kjo tregon se 50% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 75%: Kjo eshte vlera e kuantilit te 75%, qe ne kete rast eshte 1288.25. Kjo do te thote qe 75% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 100%: Vlera maksimale e te dhenave eshte 1500.00.

Funksioni IQR afishon vleren 517.5, kjo do te thote se diferenca midis kuantilit te 25% dhe kuantilit te 75% eshte 517.5. Kjo tregon se 50% e te dhenave jane te perhapura ne nje interval prej 517.5 njesi.

Kuartilet e ndihmave financiare:

q75 <- quantile(data$ndihma_financiare, 0.75)  
q25 <- quantile(data$ndihma_financiare, 0.25) 
quantile(data$ndihma_financiare)
    0%    25%    50%    75%   100% 
   0.0  261.0  513.0  751.5 1000.0 
IQR(data$ndihma_financiare)
[1] 490.5

Ky rezultat tregon vlerat perkatese te kuantileve per kolonen “ndihma_financiare” ne dataset:

• 0%: Vlera minimale e te dhenave eshte 0.0.

• 25%: Kjo eshte vlera e kuantilit te 25%, qe ne kete rast eshte 261.0. Kjo do te thote qe 25% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 50%: Kjo eshte vlera qendrore, e njohur si mesorja, qe ne kete rast eshte 513.0. Kjo tregon se 50% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 75%: Kjo eshte vlera e kuantilit te 75%, qe ne kete rast eshte 751.5. Kjo do te thote qe 75% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 100%: Vlera maksimale e te dhenave eshte 1000.00.

Funksioni IQR afishon vleren 490.5, kjo do te thote se diferenca midis kuantilit te 25% dhe kuantilit te 75% eshte 490.5. Kjo tregon se 50% e te dhenave jane te perhapura ne nje interval prej 490.5 njesi.

Kuartilet e shumave te shpenzuara ndaj shkollimit:

q75 <- quantile(data$shkollimi, 0.75)  
q25 <- quantile(data$shkollimi, 0.25) 
quantile(data$shkollimi)
     0%     25%     50%     75%    100% 
3003.00 3779.75 4547.50 5285.00 6000.00 
IQR(data$shkollimi)
[1] 1505.25

Ky rezultat tregon vlerat perkatese te kuantileve per kolonen “shkollimi” ne dataset:

• 0%: Vlera minimale e te dhenave eshte 3003.00.

• 25%: Kjo eshte vlera e kuantilit te 25%, qe ne kete rast eshte 3779.75. Kjo do te thote qe 25% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 50%: Kjo eshte vlera qendrore, e njohur si mesorja, qe ne kete rast eshte 4547.50. Kjo tregon se 50% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 75%: Kjo eshte vlera e kuantilit te 75%, qe ne kete rast eshte 5285.00. Kjo do te thote qe 75% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 100%: Vlera maksimale e te dhenave eshte 6000.00.

Funksioni IQR afishon vleren 1505.25, kjo do te thote se diferenca midis kuantilit te 25% dhe kuantilit te 75% eshte 1505.25. Kjo tregon se 50% e te dhenave jane te perhapura ne nje interval prej 1505.25 njesi.

Kuartilet e shumave te shpenzuara ndaj strehimit:

q75 <- quantile(data$strehimi, 0.75)  
q25 <- quantile(data$strehimi, 0.25) 
quantile(data$strehimi)
     0%     25%     50%     75%    100% 
 401.00  538.75  704.50  837.25 1000.00 
IQR(data$strehimi)
[1] 298.5

Ky rezultat tregon vlerat perkatese te kuantileve per kolonen “strehimi” ne dataset:

• 0%: Vlera minimale e te dhenave eshte 401.00.

• 25%: Kjo eshte vlera e kuantilit te 25%, qe ne kete rast eshte 538.75. Kjo do te thote qe 25% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 50%: Kjo eshte vlera qendrore, e njohur si mesorja, qe ne kete rast eshte 704.50. Kjo tregon se 50% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 75%: Kjo eshte vlera e kuantilit te 75%, qe ne kete rast eshte 837.25. Kjo do te thote qe 75% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 100%: Vlera maksimale e te dhenave eshte 1000.00.

Funksioni IQR afishon vleren 298.5, kjo do te thote se diferenca midis kuantilit te 25% dhe kuantilit te 75% eshte 298.5. Kjo tregon se 50% e te dhenave jane te perhapura ne nje interval prej 298.5 njesi.

Kuartilet e shumave te shpenzuara ndaj ushqimit:

q75 <- quantile(data$ushqimi, 0.75)  
q25 <- quantile(data$ushqimi, 0.25) 
quantile(data$ushqimi)
  0%  25%  50%  75% 100% 
 100  175  255  330  400 
IQR(data$ushqimi)
[1] 155

Ky rezultat tregon vlerat perkatese te kuantileve per kolonen “ushqimi” ne dataset:

• 0%: Vlera minimale e te dhenave eshte 100.

• 25%: Kjo eshte vlera e kuantilit te 25%, qe ne kete rast eshte 175. Kjo do te thote qe 25% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 50%: Kjo eshte vlera qendrore, e njohur si mesorja, qe ne kete rast eshte 255. Kjo tregon se 50% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 75%: Kjo eshte vlera e kuantilit te 75%, qe ne kete rast eshte 330. Kjo do te thote qe 75% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 100%: Vlera maksimale e te dhenave eshte 400.

Funksioni IQR afishon vleren 155, kjo do te thote se diferenca midis kuantilit te 25% dhe kuantilit te 75% eshte 155. Kjo tregon se 50% e te dhenave jane te perhapura ne nje interval prej 155 njesi.

Kuartilet e shumave te shpenzuara ndaj transportit:

q75 <- quantile(data$transporti, 0.75)  
q25 <- quantile(data$transporti, 0.25) 
quantile(data$transporti)
    0%    25%    50%    75%   100% 
 50.00  88.00 123.00 162.25 200.00 
IQR(data$transporti)
[1] 74.25

Ky rezultat tregon vlerat perkatese te kuantileve per kolonen “transporti” ne dataset:

• 0%: Vlera minimale e te dhenave eshte 50.00.

• 25%: Kjo eshte vlera e kuantilit te 25%, qe ne kete rast eshte 88.00. Kjo do te thote qe 25% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 50%: Kjo eshte vlera qendrore, e njohur si mesorja, qe ne kete rast eshte 123.00. Kjo tregon se 50% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 75%: Kjo eshte vlera e kuantilit te 75%, qe ne kete rast eshte 162.25. Kjo do te thote qe 75% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 100%: Vlera maksimale e te dhenave eshte 200.00.

Funksioni IQR afishon vleren 74.25, kjo do te thote se diferenca midis kuantilit te 25% dhe kuantilit te 75% eshte 74.25. Kjo tregon se 50% e te dhenave jane te perhapura ne nje interval prej 74.25 njesi.

Kuartilet e shumave te shpenzuara ndaj mjeteve shkollore:

q75 <- quantile(data$mjetet_shkollore, 0.75)  
q25 <- quantile(data$mjetet_shkollore, 0.25) 
quantile(data$mjetet_shkollore)
  0%  25%  50%  75% 100% 
  50  112  175  238  300 
IQR(data$mjetet_shkollore)
[1] 126

Ky rezultat tregon vlerat perkatese te kuantileve per kolonen “mjetet_shkollore” ne dataset:

• 0%: Vlera minimale e te dhenave eshte 50.00.

• 25%: Kjo eshte vlera e kuantilit te 25%, qe ne kete rast eshte 112. Kjo do te thote qe 25% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 50%: Kjo eshte vlera qendrore, e njohur si mesorja, qe ne kete rast eshte 175. Kjo tregon se 50% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 75%: Kjo eshte vlera e kuantilit te 75%, qe ne kete rast eshte 238. Kjo do te thote qe 75% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 100%: Vlera maksimale e te dhenave eshte 300.

Funksioni IQR afishon vleren 126, kjo do te thote se diferenca midis kuantilit te 25% dhe kuantilit te 75% eshte 126. Kjo tregon se 50% e te dhenave jane te perhapura ne nje interval prej 126 njesi.

Kuartilet e shumave te shpenzuara ndaj argetimit:

q75 <- quantile(data$argetim, 0.75)  
q25 <- quantile(data$argetim, 0.25) 
quantile(data$argetim)
  0%  25%  50%  75% 100% 
  20   54   86  116  150 
IQR(data$argetim)
[1] 62

Ky rezultat tregon vlerat perkatese te kuantileve per kolonen “argetim” ne dataset:

• 0%: Vlera minimale e te dhenave eshte 20.

• 25%: Kjo eshte vlera e kuantilit te 25%, qe ne kete rast eshte 54. Kjo do te thote qe 25% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 50%: Kjo eshte vlera qendrore, e njohur si mesorja, qe ne kete rast eshte 86. Kjo tregon se 50% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 75%: Kjo eshte vlera e kuantilit te 75%, qe ne kete rast eshte 116. Kjo do te thote qe 75% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 100%: Vlera maksimale e te dhenave eshte 150.

Funksioni IQR afishon vleren 62, kjo do te thote se diferenca midis kuantilit te 25% dhe kuantilit te 75% eshte 62. Kjo tregon se 50% e te dhenave jane te perhapura ne nje interval prej 62 njesi.

Kuartilet e shumave te shpenzuara ndaj kujdesit personal:

q75 <- quantile(data$kujdesi_personal, 0.75)  
q25 <- quantile(data$kujdesi_personal, 0.25) 
quantile(data$kujdesi_personal)
  0%  25%  50%  75% 100% 
  20   41   62   80  100 
IQR(data$kujdesi_personal)
[1] 39

Ky rezultat tregon vlerat perkatese te kuantileve per kolonen “kujdesi_personal” ne dataset:

• 0%: Vlera minimale e te dhenave eshte 20.

• 25%: Kjo eshte vlera e kuantilit te 25%, qe ne kete rast eshte 41. Kjo do te thote qe 25% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 50%: Kjo eshte vlera qendrore, e njohur si mesorja, qe ne kete rast eshte 62. Kjo tregon se 50% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 75%: Kjo eshte vlera e kuantilit te 75%, qe ne kete rast eshte 80. Kjo do te thote qe 75% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 100%: Vlera maksimale e te dhenave eshte 100.

Funksioni IQR afishon vleren 39, kjo do te thote se diferenca midis kuantilit te 25% dhe kuantilit te 75% eshte 39. Kjo tregon se 50% e te dhenave jane te perhapura ne nje interval prej 39 njesi.

Kuartilet e shumave te shpenzuara ne fushen e teknologjise:

q75 <- quantile(data$teknologji, 0.75)  
q25 <- quantile(data$teknologji, 0.25) 
quantile(data$teknologji)
  0%  25%  50%  75% 100% 
  50  114  178  241  300 
IQR(data$teknologji)
[1] 127

Ky rezultat tregon vlerat perkatese te kuantileve per kolonen “teknologji” ne dataset:

• 0%: Vlera minimale e te dhenave eshte 50.

• 25%: Kjo eshte vlera e kuantilit te 25%, qe ne kete rast eshte 114. Kjo do te thote qe 25% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 50%: Kjo eshte vlera qendrore, e njohur si mesorja, qe ne kete rast eshte 178. Kjo tregon se 50% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 75%: Kjo eshte vlera e kuantilit te 75%, qe ne kete rast eshte 241. Kjo do te thote qe 75% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 100%: Vlera maksimale e te dhenave eshte 300.

Funksioni IQR afishon vleren 127, kjo do te thote se diferenca midis kuantilit te 25% dhe kuantilit te 75% eshte 127. Kjo tregon se 50% e te dhenave jane te perhapura ne nje interval prej 127 njesi.

Kuartilet e shumave te shpenzuara ndaj mireqenies shendetesore:

q75 <- quantile(data$mireqenia_shendetesore, 0.75)  
q25 <- quantile(data$mireqenia_shendetesore, 0.25) 
quantile(data$mireqenia_shendetesore)
  0%  25%  50%  75% 100% 
  30   73  115  158  200 
IQR(data$mireqenia_shendetesore)
[1] 85

Ky rezultat tregon vlerat perkatese te kuantileve per kolonen “mireqenia_shendetesore” ne dataset:

• 0%: Vlera minimale e te dhenave eshte 30

• 25%: Kjo eshte vlera e kuantilit te 25%, qe ne kete rast eshte 73. Kjo do te thote qe 25% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 50%: Kjo eshte vlera qendrore, e njohur si mesorja, qe ne kete rast eshte 115. Kjo tregon se 50% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 75%: Kjo eshte vlera e kuantilit te 75%, qe ne kete rast eshte 158. Kjo do te thote qe 75% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 100%: Vlera maksimale e te dhenave eshte 200.

Funksioni IQR afishon vleren 85, kjo do te thote se diferenca midis kuantilit te 25% dhe kuantilit te 75% eshte 85. Kjo tregon se 50% e te dhenave jane te perhapura ne nje interval prej 85 njesi.

Kuartilet e shumave te shpenzuara ndaj shpenzimeve te tjera te ndryshme:

q75 <- quantile(data$te_ndryshme, 0.75)  
q25 <- quantile(data$te_ndryshme, 0.25) 
quantile(data$te_ndryshme)
    0%    25%    50%    75%   100% 
 20.00  63.75 110.00 153.00 200.00 
IQR(data$te_ndryshme)
[1] 89.25

Ky rezultat tregon vlerat perkatese te kuantileve per kolonen “te_ndryshme” ne dataset:

• 0%: Vlera minimale e te dhenave eshte 20.00

• 25%: Kjo eshte vlera e kuantilit te 25%, qe ne kete rast eshte 63.75. Kjo do te thote qe 25% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 50%: Kjo eshte vlera qendrore, e njohur si mesorja, qe ne kete rast eshte 110.00. Kjo tregon se 50% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 75%: Kjo eshte vlera e kuantilit te 75%, qe ne kete rast eshte 153.00. Kjo do te thote qe 75% e te dhenave jane me te vogla ose te barabarta me kete vlere.

• 100%: Vlera maksimale e te dhenave eshte 200.00.

Funksioni IQR afishon vleren 89.25, kjo do te thote se diferenca midis kuantilit te 25% dhe kuantilit te 75% eshte 89.25. Kjo tregon se 50% e te dhenave jane te perhapura ne nje interval prej 89.25 njesi.

\[Vlerat\ Ekstremale:\ Maximum,\ Minimum\]

\(Vlerat\) \(ekstremale\) \(min,\) \(max;\) \(indekset\) \(perkatese;\) \(Amplituda;\)

Gjetja e vleres maksimale do te kryhet me ane te funksionit \(max()\), gjetja e vleres minimale do te kryhet me ane te funksionit \(min()\) ndersa pozicionet perkatese do te gjenden me ane te funksionit \(which.max()\) dhe \(which.min()\).

Gjetja e vleres maksimale dhe pozicionit te saj ne kolone per variablin \(mosha:\)

Vlera maksimale:

max_values <- max(data$mosha)
print(max_values)
[1] 25

Pozicioni ne kolone:

pozicioni <- which.min(data$mosha) 
print(pozicioni-1)
[1] 9

Gjetja e vleres maksimale dhe pozicionit te saj ne kolone per variablin \(te\) \(ardhurat\) \(mujore:\)

Vlera maksimale:

max_values <- max(data$te_ardhurat_mujore)
print(max_values)
[1] 1500

Pozicioni ne kolone:

pozicioni <- which.max(data$te_ardhurat_mujore) 
print(pozicioni-1)
[1] 517

Gjetja e vleres maksimale dhe pozicionit te saj ne kolone per variablin \(ndihma\) \(financiare:\)

Vlera maksimale:

max_values <- max(data$ndihma_financiare)
print(max_values)
[1] 1000

Pozicioni ne kolone:

pozicioni <- which.max(data$ndihma_financiare) 
print(pozicioni-1)
[1] 878

Gjetja e vleres maksimale dhe pozicionit te saj ne kolone per variablin \(shkollimi:\)

Vlera maksimale:

max_values <- max(data$shkollimi)
print(max_values)
[1] 6000

Pozicioni ne kolone:

pozicioni <- which.max(data$shkollimi) 
print(pozicioni-1)
[1] 582

Gjetja e vleres maksimale dhe pozicionit te saj ne kolone per variablin \(strehimi:\)

Vlera maksimale:

max_values <- max(data$strehimi)
print(max_values)
[1] 1000

Pozicioni ne kolone:

pozicioni <- which.max(data$strehimi) 
print(pozicioni-1)
[1] 272

Gjetja e vleres maksimale dhe pozicionit te saj ne kolone per variablin \(ushqimi:\)

Vlera maksimale:

max_values <- max(data$ushqimi)
print(max_values)
[1] 400

Pozicioni ne kolone:

pozicioni <- which.max(data$ushqimi) 
print(pozicioni-1)
[1] 25

Gjetja e vleres maksimale dhe pozicionit te saj ne kolone per variablin \(transporti:\)

Vlera maksimale:

max_values <- max(data$transporti)
print(max_values)
[1] 200

Pozicioni ne kolone:

pozicioni <- which.max(data$transporti) 
print(pozicioni-1)
[1] 11

Gjetja e vleres maksimale dhe pozicionit te saj ne kolone per variablin \(mjetet\) \(shkollore:\)

Vlera maksimale:

max_values <- max(data$mjetet_shkollore)
print(max_values)
[1] 300

Pozicioni ne kolone:

pozicioni <- which.max(data$mjetet_shkollore) 
print(pozicioni-1)
[1] 173

Gjetja e vleres maksimale dhe pozicionit te saj ne kolone per variablin \(argetim:\)

Vlera maksimale:

max_values <- max(data$argetim)
print(max_values)
[1] 150

Pozicioni ne kolone:

pozicioni <- which.max(data$argetim) 
print(pozicioni-1)
[1] 308

Gjetja e vleres maksimale dhe pozicionit te saj ne kolone per variablin \(kujdesi\) \(personal:\)

Vlera maksimale:

max_values <- max(data$kujdesi_personal)
print(max_values)
[1] 100

Pozicioni ne kolone:

pozicioni <- which.max(data$kujdesi_personal) 
print(pozicioni-1)
[1] 82

Gjetja e vleres maksimale dhe pozicionit te saj ne kolone per variablin \(teknologji:\)

Vlera maksimale:

max_values <- max(data$teknologji)
print(max_values)
[1] 300

Pozicioni ne kolone:

pozicioni <- which.max(data$teknologji) 
print(pozicioni-1)
[1] 885

Gjetja e vleres maksimale dhe pozicionit te saj ne kolone per variablin \(mireqenia\) \(shendetesore:\)

Vlera maksimale:

max_values <- max(data$mireqenia_shendetesore)
print(max_values)
[1] 200

Pozicioni ne kolone:

pozicioni <- which.max(data$mireqenia_shendetesore) 
print(pozicioni-1)
[1] 50

Gjetja e vleres maksimale dhe pozicionit te saj ne kolone per variablin \(te\) \(ndryshme:\)

Vlera maksimale:

max_values <- max(data$mireqenia_shendetesore)
print(max_values)
[1] 200

Pozicioni ne kolone:

pozicioni <- which.max(data$mireqenia_shendetesore) 
print(pozicioni-1)
[1] 50

Gjetja e vlerës minimale dhe pozicionit te saj ne kolone per variablin \(mosha:\)

Vlera minimale:

min_values <- min(data$mosha)
print(min_values)
[1] 18

Pozicioni ne kolone:

pozicioni <- which.min(data$mosha) 
print(pozicioni-1)
[1] 9

Gjetja e vleres minimale dhe pozicionit te saj ne kolone per variablin \(te\) \(ardhurat\) \(mujore:\)

Vlera minimale:

min_values <- min(data$te_ardhurat_mujore)
print(min_values)
[1] 501

Pozicioni ne kolone:

pozicioni <- which.min(data$te_ardhurat_mujore) 
print(pozicioni-1)
[1] 876

Gjetja e vleres minimale dhe pozicionit te saj ne kolone per variablin \(ndihma\) \(financiare:\)

Vlera minimale:

min_values <- min(data$ndihma_financiare)
print(min_values)
[1] 0

Pozicioni ne kolone:

pozicioni <- which.min(data$ndihma_financiare) 
print(pozicioni-1)
[1] 347

Gjetja e vleres minimale dhe pozicionit te saj ne kolone per variablin \(shkollimi:\)

Vlera minimale:

min_values <- min(data$shkollimi)
print(min_values)
[1] 3003

Pozicioni ne kolone:

pozicioni <- which.min(data$shkollimi) 
print(pozicioni-1)
[1] 349

Gjetja e vleres minimale dhe pozicionit te saj ne kolone per variablin \(strehimi:\)

Vlera minimale:

min_values <- min(data$strehimi)
print(min_values)
[1] 401

Pozicioni ne kolone:

pozicioni <- which.min(data$strehimi) 
print(pozicioni-1)
[1] 833

Gjetja e vleres minimale dhe pozicionit te saj ne kolone per variablin \(ushqimi:\)

Vlera minimale:

min_values <- min(data$ushqimi)
print(pozicioni-1)
[1] 833

Pozicioni ne kolone:

pozicioni <- which.min(data$ushqimi) 
print(pozicioni-1)
[1] 242

Gjetja e vleres minimale dhe pozicionit te saj ne kolone per variablin \(transporti:\)

Vlera minimale:

min_values <- min(data$transporti)
print(min_values)
[1] 50

Pozicioni ne kolone:

pozicioni <- which.min(data$transporti) 
print(pozicioni-1)
[1] 13

Gjetja e vleres minimale dhe pozicionit te saj ne kolone per variablin \(mjetet\) \(shkollore:\)

Vlera minimale:

min_values <- min(data$mjetet_shkollore)
print(min_values)
[1] 50

Pozicioni ne kolone:

pozicioni <- which.min(data$mjetet_shkollore) 
print(pozicioni-1)
[1] 420

Gjetja e vleres minimale dhe pozicionit te saj ne kolone per variablin \(argetim:\)

Vlera minimale:

min_values <- min(data$argetim)
print(min_values)
[1] 20

Pozicioni ne kolone:

pozicioni <- which.min(data$argetim) 
print(pozicioni-1)
[1] 13

Gjetja e vleres minimale dhe pozicionit te saj ne kolone per variablin \(kujdesi\) \(personal:\)

Vlera minimale:

min_values <- min(data$kujdesi_personal)
print(min_values)
[1] 20

Pozicioni ne kolone:

pozicioni <- which.min(data$kujdesi_personal) 
print(pozicioni-1)
[1] 269

Gjetja e vleres minimale dhe pozicionit te saj ne kolone per variablin \(teknologji:\)

Vlera minimale:

min_values <- min(data$teknologji)
print(min_values)
[1] 50

Pozicioni ne kolone:

pozicioni <- which.min(data$teknologji) 
print(pozicioni-1)
[1] 17

Gjetja e vleres minimale dhe pozicionit te saj ne kolone per variablin \(mireqenia\) \(shendetesore:\)

Vlera minimale:

min_values <- min(data$mireqenia_shendetesore)
print(min_values)
[1] 30

Pozicioni ne kolone:

pozicioni <- which.min(data$mireqenia_shendetesore) 
print(pozicioni-1)
[1] 68

Gjetja e vleres minimale dhe pozicionit te saj ne kolone per variablin \(te\) \(ndryshme:\)

Vlera minimale:

min_values <- min(data$te_ndryshme)
print(min_values)
[1] 20

Pozicioni ne kolone:

pozicioni <- which.min(data$te_ndryshme) 
print(pozicioni-1)
[1] 431

Sqarim: Indeksi i vlerave maksimale dhe minimale eshte zbritur me 1 per arsye se, nese shohim ne kolonat e datasetit, indeksi real rezulton i+1, pra, pershembull pozicioni i minimumit te ndryshores \(te\)$ndryshme$ ne dataset do te jete 432 .

\[Amplituda\\ A = {x_{max}}\ +\ {x_{min}}\] Diferenca midis vleres maksimale dhe minimale percakton \(amplituden\).

Llogaritja e amplitudes per variablin \(mosha:\)

amplituda <- max(data$mosha) - min(data$mosha)
print(amplituda)
[1] 7

Llogaritja e amplitudes per variablin \(te\) \(ardhurat\) \(mujore:\)

amplituda <- max(data$te_ardhurat_mujore) - min(data$te_ardhurat_mujore)
print(amplituda)
[1] 999

Llogaritja e amplitudes per variablin \(ndihma\) \(financiare:\)

amplituda <- max(data$ndihma_financiare) - min(data$ndihma_financiare)
print(amplituda)
[1] 1000

Llogaritja e amplitudes per variablin \(shkollimi:\)

amplituda <- max(data$shkollimi) - min(data$shkollimi)
print(amplituda)
[1] 2997

Llogaritja e amplitudes per variablin \(strehimi:\)

amplituda <- max(data$strehimi) - min(data$strehimi)
print(amplituda)
[1] 599

Llogaritja e amplitudes per variablin \(ushqimi:\)

amplituda <- max(data$ushqimi) - min(data$ushqimi)
print(amplituda)
[1] 300

Llogaritja e amplitudes per variablin \(transporti:\)

amplituda <- max(data$transporti) - min(data$transporti)
print(amplituda)
[1] 150

Llogaritja e amplitudes per variablin \(mjetet\) \(shkollore:\)

amplituda <- max(data$mjetet_shkollore) - min(data$mjetet_shkollore)
print(amplituda)
[1] 250

Llogaritja e amplitudes per variablin \(argetim:\)

amplituda <- max(data$argetim) - min(data$argetim)
print(amplituda)
[1] 130

Llogaritja e amplitudes per variablin \(kujdesi\) \(personal:\)

amplituda <- max(data$kujdesi_personal) - min(data$kujdesi_personal)
print(amplituda)
[1] 80

Llogaritja e amplitudes per variablin \(teknologji:\)

amplituda <- max(data$teknologji) - min(data$teknologji)
print(amplituda)
[1] 250

Llogaritja e amplitudes per variablin \(mireqenia\) \(shendetesore:\)

amplituda <- max(data$mireqenia_shendetesore) - min(data$mireqenia_shendetesore)
print(amplituda)
[1] 170

Llogaritja e amplitudes per variablin \(te\) \(ndryshme:\)

amplituda <- max(data$te_ndryshme) - min(data$te_ndryshme)
print(amplituda)
[1] 180

\[Varianca/Dispersioni\]

\(Dispersioni\) dhe \(Menjanimi\) \(Mesatar\) \(Katror\) jane dy parametra te rendesishem te shperhapjes. Dispersioni eshte mesatarja aritmetike e katroreve te diferencave midis cdo te dhene dhe mesatares. Pra ai mat shperhapjen e vlerave rrotull vleres mesatare.

Per te llogaritur Dispersionin perdoret funksioni \(var(x);\)

\[Formula\ matematike:\\ \displaystyle {S}^2 = \frac {1}{n}{\displaystyle\sum_{i=1}^{n}(x_i - \mu)^2}\\ e\ cila\ llogarit\ variancen\ e\ grupit\ te\ te\ dhenave,\ indeksi\ "i"\ specifikon\ vleren\ e\ i^{{th}}\ ne\ grupin\ e\ te\ dhenave,\\ "μ"\ specifikon\ mesataren\ e\ grupit\ te\ te\ dhenave,\ dhe\ "n"\ specifikon\ numrin\ total\ te\ vezhgimeve.\]

\(Menjanimi\) \(Mesatar\) \(Katror\) eshte rrenja katrore e dispersionit dhe mat te njejten gje njesoj si dispersioni dhe ka permasen e te dhenave. Eshte nje numer qe ndihmon per te kuptuar se si vlerat individuale te vrojtuara shperndahen rrotull mesatares.

\(Menjanimi\) \(Mesatar\) ka permasen e te dhenave sepse gjendet si rrenje katrore e dispersionit (dollar, euro, metra, kilograme).

\[\displaystyle Devijimi\ Standard:\ {S} = \sqrt{\frac{\displaystyle\sum_{i=1}^{n}(x_i - \mu)^2} {n}}\\ {S} = \sqrt{Varianca} = \sqrt{{S}^2}\]

Per te llogaritur menjanimin mesatar ne R nuk egziston nje funksion i gatshem, keshtu qe ai do te merret sa rrenja katrore e dispersionit te llogaritur se pari: \(sqrt(var(x))\);

Le te llogaritim variancen dhe menjanimin mesatar per ndryshoret tona me ane te funksionit \(var(x)\) dhe \(sqrt(var(x))\):

Varianca per ndryshoren \(mosha\):

v1 <- c(data$mosha)
var(v1)
[1] 5.39477

Menjanimi Mesatar Katror per ndryshoren \(mosha\):

d1 <- sqrt(var(v1))
d1
[1] 2.322664

Varianca per ndryshoren \(te\) \(ardhurat\) \(mujore\):

v2 <- c(data$te_ardhurat_mujore)
var(v2)
[1] 86342.63

Menjanimi Mesatar Katror per ndryshoren \(te\) \(ardhurat\) \(mujore\):

d2 <- sqrt(var(v2))
d2
[1] 293.8412

Varianca per ndryshoren \(ndihma\) \(financiare\):

v3 <- c(data$ndihma_financiare)
var(v3)
[1] 82422.15

Menjanimi Mesatar Katror per ndryshoren \(ndihma\) \(financiare\):

d3 <- sqrt(var(v3))
d3
[1] 287.0926

Varianca per ndryshoren \(shkollimi\):

v4 <- c(data$shkollimi)
var(v4)
[1] 740732.1

Menjanimi Mesatar Katror per ndryshoren \(shkollimi\):

d4 <- sqrt(var(v4))
d4
[1] 860.6579

Varianca per ndryshoren \(strehimi\):

v5 <- c(data$strehimi)
var(v5)
[1] 29315.82

Menjanimi Mesatar Katror per ndryshoren \(strehimi\):

d5 <- sqrt(var(v5))
d5
[1] 171.2186

Varianca per ndryshoren \(ushqimi\):

v6 <- c(data$ushqimi)
var(v6)
[1] 7560.234

Menjanimi Mesatar Katror per ndryshoren \(ushqimi\):

d6 <- sqrt(var(v6))
d6
[1] 86.94961

Varianca per ndryshoren \(transporti\):

v7 <- c(data$transporti)
var(v7)
[1] 1897.299

Menjanimi Mesatar Katror per ndryshoren \(transporti\):

d7 <- sqrt(var(v7))
d7
[1] 43.55799

Varianca per ndryshoren \(mjetet\) \(shkollore\):

v8 <- c(data$mjetet_shkollore)
var(v8)
[1] 5242.414

Menjanimi Mesatar Katror per ndryshoren \(mjetet\) \(shkollore\):

d8 <- sqrt(var(v8))
d8
[1] 72.40452

Varianca per ndryshoren \(argetim\):

v9 <- c(data$argetim)
var(v9)
[1] 1441.755

Menjanimi Mesatar Katror per ndryshoren \(argetim\):

d9 <- sqrt(var(v9))
d9
[1] 37.97045

Varianca per ndryshoren \(kujdesi\) \(personal\):

v10 <- c(data$kujdesi_personal)
var(v10)
[1] 524.3187

Menjanimi Mesatar Katror per ndryshoren \(kujdesi\) \(personal\):

d10 <- sqrt(var(v10))
d10
[1] 22.89801

Varianca per ndryshoren \(teknologji\):

v11 <- c(data$teknologji)
var(v11)
[1] 5147.265

Menjanimi Mesatar Katror per ndryshoren \(teknologji\):

d11 <- sqrt(var(v11))
d11
[1] 71.74444

Varianca per ndryshoren \(mireqenia\) \(shendetesore\):

v12 <- c(data$mireqenia_shendetesore)
var(v12)
[1] 2459.321

Menjanimi Mesatar Katror per ndryshoren \(mireqenia\) \(shendetesore\):

d12 <- sqrt(var(v12))
d12
[1] 49.59154

Varianca per ndryshoren \(te\) \(ndryshme\):

v13 <- c(data$te_ndryshme)
var(v13)
[1] 2747.041

Menjanimi Mesatar Katror per ndryshoren \(te\) \(ndryshme\):

d13 <- sqrt(var(v13))
d13
[1] 52.41222

Interpretimi i rezultateve do te jete i tille per cdo ndryshore mbi te cilen kemi llogaritur variancen dhe menjanimin mesatar katror: le te marrim ndryshoren \(mosha\); vlera 5.3947 tregon se vlerat jane te shperhapura mesatarisht 5.3947 njesi katrore larg nga vlera mesatare e grupit te te dhenave. Vlera 2.322664 tregon se vlerat jane 2.322664 njesi larg nga vlera mesatare.

I njejti interpretim vlen per te gjitha ndryshoret e tjera.

\[ANALIZA\ E\ NDRYSHOREVE\ CILESORE\]

\(Ndryshoret\) \(Cilesore\) klasifikohen si ndryshore \(nominale\) dhe \(ordinale\).

\(Ndryshoret\) \(Nominale\) jane ato lloje ndryshoresh cilesore mbi te cilat nuk mund te kryhet veprimi i renditjes. Ndersa nje \(Ndryshore\) \(Ordinale\) eshte nje lloj i ndryshoreve cilesore mbi te cilat mund te kryejme renditje (ordinal , order - renditje).

Ne dataset ndryshoret nominale jane \(gjinia\), \(diplomimi\) dhe \(metoda\) \(e\) \(pageses\), ndersa ndryshoret ordinale jane dhe \(viti\) \(i\) \(studimeve\)

**Analiza e ndryshoreve cilesore do te perfshije ndertimin e tabelave te frekuences, tabelave te kontigjences, ku bashke me keto do te ndertojme edhe tabelat me vlerat probabilitare perkatese per cdo tabele kontigjence e gjithashtu edhe testin Hi-katror.*

\[Tabelat\ e\ frekuencave:\ Moda\ dhe\ Frekuenca\ e\ saj\]

Tabela e Frekuences per ndryshoren cilesore \(gjinia\) dhe moda: cilesia e perseritur me shpesh;

Tabela e Frekuences:

tab <- table(data$gjinia)
print(tab)

    Female       Male Non-binary 
       323        356        321 

Moda:

moda <- names(tab)[tab == max(tab)]
print(moda)
[1] "Male"

Frekuenca:

max_frequency = max(tab)
print(max_frequency)
[1] 356

Interpretimi i tabeles se frekuences:

Funksioni \(table()\) na sherben per ndertimin e tabeles, duke marre si parameter emrin e ndryshores per te cilen deshirojme te ndertojme nje tabele frekuence. Funksioni \(names(tab)[tab == max(tab)]\) sherben per te gjetur moden e ndryshores ndersa \(max(tab)\) sherben per te gjetur frekuencen e saj. Veme re qe moda per kete ndryshore eshte \(male\) dhe frekuenca e saj eshte 356, pra ajo shfaqet 356 here ne grupin e te dhenave. I njejti interpretim do te vleje per cdo tabele tjeter te ndertuar me poshte.

Tabela e Frekuences per ndryshoren cilesore \(viti\) \(i\) \(studimeve\) dhe moda: cilesia e perseritur me shpesh;

Tabela e Frekuences:

tab <- table(data$viti_i_studimeve)
print(tab)

 Freshman    Junior    Senior Sophomore 
      253       247       254       246 

Moda:

moda <- names(tab)[tab == max(tab)]
print(moda)
[1] "Senior"

Frekuenca:

max_frequency = max(tab)
print(max_frequency)
[1] 254

Tabela e Frekuences per ndryshoren cilesore \(diplomimi\) dhe moda: cilesia e perseritur me shpesh;

Tabela e Frekuences:

tab <- table(data$diplomimi)
print(tab)

         Biology Computer Science        Economics      Engineering       Psychology 
             228              192              204              192              184 

Moda:

moda <- names(tab)[tab == max(tab)]
print(moda)
[1] "Biology"

Frekuenca:

max_frequency = max(tab)
print(max_frequency)
[1] 228

Tabela e Frekuences per ndryshoren cilesore \(metoda\) \(e\) \(pageses\) dhe moda: cilesia e perseritur me shpesh;

Tabela e Frekuences:

tab <- table(data$metoda_e_pageses)
print(tab)

              Cash  Credit/Debit Card Mobile Payment App 
               310                340                350 

Moda:

moda <- names(tab)[tab == max(tab)]
print(moda)
[1] "Mobile Payment App"

Frekuenca:

max_frequency = max(tab)
print(max_frequency)
[1] 350

\[Tabelat\ e\ Kontigjences\]

Tabelat e kontigjences, te njohura gjithashtu si tabela e ndarjes se kryqezuar, perdoren per te paraqitur frekuencat e kombinimeve te dy variablave ne nje format te strukturuar. Keto tabela jane te rendesishme ne analizen e lidhjeve midis variablave dhe ne zhvillimin e testimeve statistikore si testi Chi-Squared.

Me krijimin e ketyre tabelave interesohemi per ndonje marredhenie te mundshme midis dy variablave cilesore.

Me poshte do te ndertojme Tabelat e Kontigjences per variablat cilesore me ane te funksionit \(table()\). Vecmas ketij funksioni do te perdorim edhe funksionin \(prop.table()\) i cili do te marre si parameter emrin e tabeles se kontigjences dhe do te na afishoje perseri tabelen e kontigjences, por kesaj here me vlera probabilitare/perqindje. Pra sa perqind ze ne te dhena kjo pjese e popullimit.

Tabela e Kontigjences per ndryshoret \(gjinia\) dhe \(viti\) \(i\) \(studimeve:\)

tabela1 <- table(data$gjinia, data$viti_i_studimeve) 
print(tabela1)
            
             Freshman Junior Senior Sophomore
  Female           78     83     87        75
  Male             91     81     90        94
  Non-binary       84     83     77        77

Leximi i tabeles se kontigjences eshte i tille: vlera 78 ne tabele, ne pozicionin (1,1) tregon se 78 nga gjithe popullimi jane femra dhe jane ne statusin studente te vitit te pare (freshman), 81 meshkuj qe jane ne statusin junior dhe keshtu veprojme per te gjitha vlerat e tjera ne cdo tabele tjeter kontigjence.

prop.table(tabela1, 1)
            
              Freshman    Junior    Senior Sophomore
  Female     0.2414861 0.2569659 0.2693498 0.2321981
  Male       0.2556180 0.2275281 0.2528090 0.2640449
  Non-binary 0.2616822 0.2585670 0.2398754 0.2398754

Interpretimi: vlera 0.2414861 ne tabele tregon se 24.14861% e te dhenave jane femra dhe jane ne statusin freshman. 25.2609% jane meshkuj ne statusin senior, e keshtu me radhe. I njejti interpretim do te vleje per te gjitha tabelat e meposhtme.

Tabela e Kontigjences per ndryshoret \(gjinia\) dhe \(diplomimi:\)

tabela2 <- table(data$gjinia, data$diplomimi) 
print(tabela2)
            
             Biology Computer Science Economics Engineering Psychology
  Female          68               67        56          68         64
  Male            77               68        77          71         63
  Non-binary      83               57        71          53         57
prop.table(tabela2, 1)
            
               Biology Computer Science Economics Engineering Psychology
  Female     0.2105263        0.2074303 0.1733746   0.2105263  0.1981424
  Male       0.2162921        0.1910112 0.2162921   0.1994382  0.1769663
  Non-binary 0.2585670        0.1775701 0.2211838   0.1651090  0.1775701

Tabela e Kontigjences per ndryshoret \(gjinia\) dhe \(metoda\) \(e\) \(pageses:\)

tabela3 <- table(data$gjinia, data$metoda_e_pageses) 
print(tabela3)
            
             Cash Credit/Debit Card Mobile Payment App
  Female       97               106                120
  Male        111               120                125
  Non-binary  102               114                105
prop.table(tabela3, 1)
            
                  Cash Credit/Debit Card Mobile Payment App
  Female     0.3003096         0.3281734          0.3715170
  Male       0.3117978         0.3370787          0.3511236
  Non-binary 0.3177570         0.3551402          0.3271028

Tabela e Kontigjences per ndryshoret \(diplomimi\) dhe \(metoda\) \(e\) \(pageses:\)

tabela4 <- table(data$diplomimi, data$metoda_e_pageses) 
print(tabela4)
                  
                   Cash Credit/Debit Card Mobile Payment App
  Biology            69                81                 78
  Computer Science   65                63                 64
  Economics          59                73                 72
  Engineering        63                62                 67
  Psychology         54                61                 69
prop.table(tabela4, 1)
                  
                        Cash Credit/Debit Card Mobile Payment App
  Biology          0.3026316         0.3552632          0.3421053
  Computer Science 0.3385417         0.3281250          0.3333333
  Economics        0.2892157         0.3578431          0.3529412
  Engineering      0.3281250         0.3229167          0.3489583
  Psychology       0.2934783         0.3315217          0.3750000

Tabela e Kontigjences per ndryshoret \(viti\) \(i\) \(studimeve\) dhe \(metoda\) \(e\) \(pageses:\)

tabela5 <- table(data$viti_i_studimeve, data$metoda_e_pageses) 
print(tabela5)
           
            Cash Credit/Debit Card Mobile Payment App
  Freshman    76                85                 92
  Junior      73                84                 90
  Senior      69                98                 87
  Sophomore   92                73                 81
prop.table(tabela5, 1)
           
                 Cash Credit/Debit Card Mobile Payment App
  Freshman  0.3003953         0.3359684          0.3636364
  Junior    0.2955466         0.3400810          0.3643725
  Senior    0.2716535         0.3858268          0.3425197
  Sophomore 0.3739837         0.2967480          0.3292683

\[Testi\ Hi-Katror\]

Çfare eshte nje statistike \(Hi-katror\)?

Testi χ2 shikon modelin e vezhgimeve dhe na tregon nese disa kombinime te kategorive ndodhin me shpesh sesa do te prisnim rastesisht, duke pasur parasysh numrin e pergjithshem te hereve qe ka ndodhur secila kategori. Pra kerkon nje lidhje midis variablave.

\[Formula\ matematike:\\ χ2=\displaystyle\sum_{i=1}^{n}\frac{(O_{ij}-E_{ij})^2}{E_{ij}}\\ χ2\ eshte\ statistika\ e\ testit;\ Σ\ eshte\ operatori\ shumator;\\ O\ eshte\ frekuenca\ e\ vezhguar;\ E\ eshte\ frekuenca\ e\ pritur;\]

Per te llogaritur vleren e Hi-katrorit ndertohet nje tabele me efektiva teorike. Keta efektiva i korrespondojne rastit kur ndryshoret jane te pavarura. Testi χ2 do te kryhet me ane te funksionit \(chisq.test()\) i cili merr si parameter emrin e tabeles se kontigjences.

Ne gjithashtu duhet te percaktojme shkallet e lirise per tabelen tone

Per te zbatuar testin \(Hi-katror\) ndaj dy ndryshoreve na duhet nje tabele kontigjence e tyre, te cilat i kemi ndertuar me siper.

Le ta zbatojme:

Testi Hi-katror per ndryshoret \(gjinia\) dhe $viti \(i\) \(studimeve:\)

test1 <- chisq.test(tabela1)
test1

    Pearson's Chi-squared test

data:  tabela1
X-squared = 2.4488, df = 6, p-value = 0.8742

Ne kete rezultat, ka disa informacione kyçe qe na ndihmojne ne interpretimin e rezultateve.

1. Test i kryer eshte testi Hi-katror i Pearson-it.

2. Vlera e testit Hi-katror eshte 2.4488.

3. Numri i shkalleve te lirise eshte 6.

4. P-vlera e testit eshte 0.8742.

Interpretimi i ketyre rezultateve eshte si me poshte:

• Vlera e testit Hi-katror 2.4488 tregon se diferenca midis te dhenave te vezhguara dhe te pranuara nuk eshte shume e madhe.

• P-value 0.8742 eshte me e madhe se niveli i zakonshem i rendesise (p-value > 0.05). Kjo do te thote se duhet te pranojme hipotezen zero, e cila supozon pavaresi statistikore midis dy variablave ne tabelen e kontigjences.

Testi Hi-katror per ndryshoret \(gjinia\) dhe \(diplomimi:\)

test2 <- chisq.test(tabela2)
test2

    Pearson's Chi-squared test

data:  tabela2
X-squared = 7.3338, df = 8, p-value = 0.5011

Ne kete rezultat, ka disa informacione kyçe qe na ndihmojne ne interpretimin e rezultateve.

1. Test i kryer eshte testi Hi-katror i Pearson-it.

2. Vlera e testit Hi-katror eshte 7.3338.

3. Numri i shkalleve te lirise eshte 8.

4. P-vlera e testit eshte 0.2202.

Interpretimi i ketyre rezultateve eshte si me poshte:

• Vlera e testit Hi-katror 7.3338 tregon se diferenca midis te dhenave te vezhguara dhe te pranuara nuk eshte shume e madhe.

• P-value 0.5011 eshte me e madhe se niveli i zakonshem i rendesise (p-value > 0.05). Kjo do te thote se nuk mund te refuzojme hipotezen zero, e cila supozon pavaresi statistikore midis dy variablave ne tabele.

Testi Hi-katror per ndryshoret \(gjinia\) dhe \(metoda\) \(e\) \(pageses:\)

test3 <- chisq.test(tabela3)
test3

    Pearson's Chi-squared test

data:  tabela3
X-squared = 1.4315, df = 4, p-value = 0.8387

Ne kete rezultat, ka disa informacione kyçe qe na ndihmojne ne interpretimin e rezultateve.

1. Test i kryer eshte testi Hi-katror i Pearson-it.

2. Vlera e testit Hi-katror eshte 1.4315.

3. Numri i shkalleve te lirise eshte 4.

4. P-vlera e testit eshte 0.8387.

Interpretimi i ketyre rezultateve eshte si me poshte:

• Vlera e testit Hi-katror 8.2527 tregon se diferenca midis te dhenave te vezhguara dhe te pranuara nuk eshte shume e madhe.

• P-value-ja 0.8387 eshte me e madhe se niveli i zakonshem i rendesise (p-value > 0.05). Kjo do te thote se nuk mund te refuzojme hipotezen zero, e cila supozon pavaresi statistikore midis dy variablave ne tabele.

Testi Hi-katror per ndryshoret \(diplomimi\) dhe \(metoda\) \(e\) \(pageses:\)

test4 <- chisq.test(tabela4)
test4

    Pearson's Chi-squared test

data:  tabela4
X-squared = 2.352, df = 8, p-value = 0.9683

Ne kete rezultat, ka disa informacione kyçe qe na ndihmojne ne interpretimin e rezultateve.

1. Test i kryer eshte testi Hi-katror i Pearson-it.

2. Vlera e testit Hi-katror eshte 2.352.

3. Numri i shkalleve te lirise eshte 8.

4. P-vlera e testit eshte 0.9683.

Interpretimi i ketyre rezultateve eshte si me poshte:

• Vlera e testit Hi-katror 2.352 tregon se diferenca midis te dhenave te vezhguara dhe te pranuara nuk eshte shume e madhe.

• P-value-ja 0.9683 eshte me e madhe se niveli i zakonshem i rendesise (p-value > 0.05). Kjo do te thote se nuk mund te refuzojme hipotezen zero, e cila supozon pavaresi statistikore midis dy variablave ne tabele.

Testi Hi-katror per ndryshoret \(viti\) \(i\) \(studimeve\) dhe \(metoda\) \(e\) \(pageses:\)

test5 <- chisq.test(tabela5)
test5

    Pearson's Chi-squared test

data:  tabela5
X-squared = 8.2527, df = 6, p-value = 0.2202

Ne kete rezultat, ka disa informacione kyçe qe na ndihmojne ne interpretimin e rezultateve.

1. Test i kryer eshte testi Hi-katror i Pearson-it.

2. Vlera e testit Hi-katror eshte 8.2527.

3. Numri i shkalleve te lirise eshte 6.

4. P-vlera e testit eshte 0.2202.

Interpretimi i ketyre rezultateve eshte si me poshte:

• Vlera e testit Hi-katror 8.2527 tregon se diferenca midis te dhenave te vezhguara dhe te pranuara nuk eshte shume e madhe.

• P-value-ja 0.2202 eshte me e madhe se niveli i zakonshem i rendesise (p-value > 0.05). Kjo do te thote se nuk mund te refuzojme hipotezen zero, e cila supozon pavaresi statistikore midis dy variablave ne tabele.

Paraqitje Grafike

\[VIZUALIZIMI\ I\ TE\ DHENAVE\]

\(Vizualizimi\) \(i\) \(te\) \(dhenave\) eshte teknika e perdorur per te dhene njohuri ne te dhena duke perdorur metoda vizuale si grafiket, diagramat, histogramat, hartat dhe shume trajta te tjera. Kjo eshte e dobishme pasi ndihmon ne kuptimin intuitiv dhe te lehte te sasive te medha te te dhenave dhe ne kete menyre per te marre vendime me te mira ne lidhje me to.

R eshte nje gjuhe qe eshte krijuar per llogaritje statistikore, analiza grafike te te dhenave dhe kerkime shkencore. Zakonisht preferohet per vizualizimin e te dhenave pasi ofron fleksibilitet dhe kodim minimal te kerkuar permes paketave te saj.

Vizualizimi i te dhenave ne analizen e te dhenave ka rendesi te madhe per disa arsye:

1. Kuptimi i mire i te dhenave;

2. Interpretimi i rezultateve: Vizualizimi i te dhenave eshte nje menyre e mire per te komunikuar rezultatet e analizes. Grafiket jane me te lehte per t’u kuptuar dhe per te shpjeguar se si ndryshojne te dhenat ne kohe, hapesire ose ndaj nje variabli tjeter.

3. Zbulimi i modeleve dhe tendencave;

Sigurisht, per paraqitjen grafike sa me egzakte dhe estetike te te dhenave do te na duhen disa librari kryesore, sic jane \(ggplot2\), \(correlation\), \(ggpubr\) & \(tidyr\), \(dataExplorer\) etj.;

\[Histogrami\]

Nje \(histogram\) eshte nje paraqitje vizuale e shperndarjes se te dhenave sasiore. Ata japin nje kuptim te perafert te densitetit dhe shpesh here vleren e sakte te tij.

Me poshte do te ndertojme nje histogram per variablin tone sasior \(mosha\). Do te na duhen 2 librari kryesore: \(ggplot2\) e cila sherben per ndertimin e grafikeve dhe libraria \(scales\) e cila do te na sherbeje per kostumizimin e grafikut.

Per te paraqitur grafikisht nje ndryshore sasiore te vazhdueshme ndertohet nje histogram.

Per kete qellim intervali I vlerave te mundshme te tiparit ndahet ne nje numer intervalesh ose klasash.

Histogrami paraqet se sa eshte numri i studenteve per secilen grupmoshe duke filluar nga 18 vjec deri ne 25. Nga lartesia e kolonave veme re se pjesen me te madhe e ze mosha 25 vjec (moda) dhe me te voglen mosha 19 vjec.

library(ggplot2)
Warning: package ‘ggplot2’ was built under R version 4.3.3
library(scales)
Warning: package ‘scales’ was built under R version 4.3.3
g1 <- hist(data$mosha, breaks=seq(17.5, 25.5, by=1), density = 40, angle=60, xlab="Grupmoshat e studenteve", ylab="Efektivat", main="Histogrami i Moshes", las=1, col="purple4", fill = "purple4",
          ylim=c(0,200),xlim=c(18,25), cex.main=1.4, cex.lab=1.2, axt='n') 
Warning in plot.window(xlim, ylim, "", ...) :
  "fill" is not a graphical parameter
Warning in plot.window(xlim, ylim, "", ...) :
  "axt" is not a graphical parameter
Warning in title(main = main, sub = sub, xlab = xlab, ylab = ylab, ...) :
  "fill" is not a graphical parameter
Warning in title(main = main, sub = sub, xlab = xlab, ylab = ylab, ...) :
  "axt" is not a graphical parameter
Warning in axis(1, ...) : "fill" is not a graphical parameter
Warning in axis(1, ...) : "axt" is not a graphical parameter
Warning in axis(2, at = yt, ...) : "fill" is not a graphical parameter
Warning in axis(2, at = yt, ...) : "axt" is not a graphical parameter
#kustomizojme grafikun me disa vija te pjerreta 60  degrees
axis(1, at=18:25, labels=18:25)
text(g1$mids, g1$counts, labels=ifelse(g1$counts != 0, g1$counts, ""), pos=3, cex=0.8)

Per te ndertuar histogramin na sherben libraria \(ggplot2\) dhe \(scales\).

Me ane te te funksionit \(hist()\) percaktojme llojin e grafikut qe duam te ndertojme, ne kete rast histogram.

\(data\)$\(mosha\): therrasim te dhenat te cilat do te paraqesim ne histogram.

\(breaks=seq(17.5, 25.5, by=1)\) percakton kufijte e histogramit, qe variojne nga 17.5 ne 25.5, me hap 1.

\(density=40\): denduria e vijave brenda shtyllave te histogramit;

\(angle=60\): vendosim nje kend per vijat brenda histogramit;

\(xlab\), \(ylab\) dhe \(main\): percaktojne emertimin e boshteve x, y dhe titullin e histogramit;

\(las=1\) pozicionon emertimet e boshteve;

Vendosim ngjyrat me ane te funksionit \(col=""\);

\(ylim=c(0,200)\) dhe \(xlim=c(18, 25)\) vendos kufijte e vlerave te histogramit;

\(cex.main=1.4\) dhe \(cex.lab=1.2\) rrit madhesine e shkrimit te titullit kryesore dhe emertimeve te boshteve;

\(axt=n\) heq emertimet e meparshme te boshtit x;

\(axis(1, at=18:25, labels=18:25)\) shton shenjat dhe emertimet e bushtit x nga 18 ne 25;

\(text(g1\)$\(mids\), \(g1\)$\(counts\), \(labels=ifelse\)(\(g1\)$\(counts\) \(!=0\), \(g1\)$\(counts\), “”), \(pos=3\), \(cex=0.8)\) shton vlerat numerike siper cdo shtylle, por vetem ne rastet kur vlerat jane te ndryshme nga zero. Parametri \(pos=3\) pozicionon vlerat ndersa \(cex=0.8\) percakton madhesine e shkrimit.

Interpretimi i histogramit eshte relativisht i thjeshte. Shohim qe shperndarja e studenteve eshte e tille: 124 individe kane moshen 18 vjecare, 108 jane 19 vjecare, 111 jane 20 vjecare, 118 jane 21 vjecare, 130 jane 22 vjecare, 128 kane moshen 23 vjec, 136 jane 24 vjecare dhe 145 jane 25 vjecare. Ajo qe vihet re tjeter eshte edhe se cila nga grupmoshat eshte me e shpeshte: eshte ajo 25 vjecare me 145 individe, ndersa ajo me pak eshte grupmosha 19 vjecare me 108 individe.

\[Grafiket\ Violine\]

library(ggplot2)
library(gridExtra)
Warning: package ‘gridExtra’ was built under R version 4.3.3

Attaching package: ‘gridExtra’

The following object is masked from ‘package:dplyr’:

    combine
violinplot1 <- ggplot(data, aes(x = "", y=data$te_ardhurat_mujore)) +
  geom_violin(fill="dodgerblue2", color="black") +
  labs(title = "Violin PLot per te Ardhurat Mujore", x="Te Ardhurat Mujore", y="Shperndarja")

violinplot2 <- ggplot(data, aes(x = "", y=data$ndihma_financiare)) +
  geom_violin(fill="dodgerblue2", color="black") +
  labs(title = "Violin PLot per Ndihmen Financiare", x="Ndihma Financiare", y="Shperndarja")

grid.arrange(violinplot1, violinplot2, ncol=2)
Warning: Use of `data$te_ardhurat_mujore` is discouraged.
ℹ Use `te_ardhurat_mujore` instead.
Warning: Use of `data$ndihma_financiare` is discouraged.
ℹ Use `ndihma_financiare` instead.

Forma e grafikut violine tregon shperndarjen e te ardhurave mujore dhe te ndihmes financiare. Ne pjeset ku grafiku eshte me i gjere do te thote se ka me shume te dhena rreth atyre vlerave. Kur eshte me i ngushte atehere ka me pak te dhena. Vlera mesatare tregohet nga brezi me i gjere qe ndodhet ne qender. Nje shperndarje me te madhe kane vlerat qe jane teorikisht midis 1250-1500, pasi aty dallohet nje brez me i gjere. Ndersa ne rastin e ndryshores tjeter vlerat kane nje shperndarje me te larte ne intervalin 500-600. Pra ,te ardhurat mujore mesatare sipas grafikut jane afersisht $1020.65 ,ndersa ndihma financiare mesatare eshte afersisht $504

\[Box plot\]

Nje \(box\) \(plot\) eshte nje lloj grafiku statistikor i cili ofron nje permbledhje vizuale te shperndarjes se nje grupi te dhenash. Ai shfaq informacionin kryesor te meposhtem:

1. Mesoren: Vlera mesore perfaqesohet nga vija horizontale brenda kutise;

2. Intervali Nderkuartilor: kutia perfaqeson 50% te vlerave te mesit te te dhenave, fundi I saj tregon 25% te te dhenave dhe pjesa e siperme tregon 75% te tyre. IQR eshte diferenca Q3 – Q1.

3. Vlerat maksimale dhe minimale: jane ato vija vertikale qe dalin nga kutia.

library(ggplot2)

ggplot(data)+aes(x=mosha, y=gjinia, fill=viti_i_studimeve, colour = te_ardhurat_mujore, size=ndihma_financiare)+
  geom_boxplot()+ scale_fill_hue(direction=2) + scale_color_gradient() +
  labs(x="Mosha", y="Gjinia", fill="Viti i Studimeve")+
  theme_classic()
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.
This warning is displayed once every 8 hours.
Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.
Warning: The following aesthetics were dropped during statistical transformation: colour and size.
ℹ This can happen when ggplot fails to infer the correct grouping structure in the data.
ℹ Did you forget to specify a `group` aesthetic or to convert a numerical variable into a factor?

Ne kete grafik eshte paraqitur nje boxplot i cili tregon lidhjen midis gjinise dhe vitit te studimit te studenteve. Per gjinine femerore jane paraqitur 4 box-plote per kategorine e Freshman, Junior, Senior, Sophomore. Nga box-plotet arrijme te dallojme qe vlera min per te katert eshte 18, ndersa vlera max 25. Keto jane dy vlerat ne skaje. Ana e majte tregon kuartilin e pare qe ne rastin e Sophomore dhe Junior eshte 20, ndersa per Senior dhe Freshman eshte 19. Vija ne mes tregon \(mesoren\), perkatesisht 21 per Junior dhe Senior dhe 22 per Freshman dhe Sophomor. Ana e djathte tregon kuartilin e trete, 24 per Sophomore dhe 23 per Junior dhe Senior. Meqe jashte box-plotit nuk kemi pika te tjera atehere themi se nuk ka \(outliers§\). Njesoj veprojme dhe per te tjeret.

library(ggplot2)

ggplot(data, aes(x=gjinia, y=mosha, fill=gjinia)) + 
  geom_boxplot(outlier.shape = NA)+
  geom_jitter(aes(color=gjinia, shape=gjinia), width=0.2, size=1.5) +
  scale_color_manual(values=c("black", "gold", "red"))+
  scale_fill_manual(values = c("blue", "red", "green"))+
  labs(title = "Box Plot Gjinia~Mosha", x="Gjinia", y="Mosha", fill="Gjinia", color="Gjinia", color="Gjinia", shape="Gjinia")+ theme_classic()

Rezultatet dhe interpretimi I tyre:

Sipas grafikut te mesiperm, kutite e krijuara shprehin shperndarjen e moshes sipas gjinise. Meset e kutise se box-ploteve bien ne moshen 22, per te treja rastet. Pikat jitter tregojne shperndarjen e te dhenave ne secilin grup.

Kodi:

Fillimisht therrasim librarite qe na nevojiten: \(ggplot2\), e cila na ndihmon per vizualizimin e te dhenave.

Krijojme nje variable te quajtur \(data\) e cila do te permbaje dy parametra kryesore:

i: \(mosha\);

ii: \(gjinia\);

Krijimi I box plot pergjithesisht eshte I njejte si ne rastin e mesiperm, me perjashtim te funksionit \(geom\)_\(jitter()\) I cili shton nje sasi te vogel pikash qe tregojne nje shperndarje sipas kutise se box plot.

Shtimi i linjave te references:

\(scale\)_\(color\)_\(manual()\) vendos ngjyren e pikave jitter ne box plot. Ngjyra blu perdoret per femrat, e kuqja perdoret per meshkujt ndersa gold per ata non-binary;

\(scale\)_\(fill\)_\(manual()\) vendos ngjyren e mbushjes se kutive;

\(labs()\) shton titullin, emertimet e boshteve \(x\),\(y\) dhe legjenden.

\[Grafiku\ Densitet\]

library(ggplot2)
ggplot(data, aes(x=ushqimi))+ 
  geom_density(aes(fill="Ushqimi"), alpha=0.5)+
  geom_density(aes(x=strehimi, fill="Strehimi"), alpha=0.5)+
    geom_density(aes(x=transporti, fill="Transporti"), alpha=0.5)+
    geom_density(aes(x= mjetet_shkollore, fill="Mjetet Shkollore"), alpha=0.5)+
  geom_density(aes(x=argetim, fill="Argetimi"), alpha=0.5) +
  labs(x="Vlera", y="Densiteti", title="Grafiku Densitet per 5 variabla numerike", fill="Legjenda:")+
  scale_fill_manual(values=c("dodgerblue2", "red", "purple3", "green2", "yellow2"))+
  theme_classic()

Rezultati:

Ketu kemi paraqitur grafikun e densiteteve per 5 ndryshore numerike (argetimi,mjetet shkollore ,strehimi,transporti,ushqimi).

Boshti i y paraqet densitetin e secilit variabel brenda intervalit te vlerave te dhena(boshti x). Dendesia i referohet sa shpesh ndodhin vlerat brenda nje intervali specifik. Zona nen cdo kurbe perfaqeson perqindjen e te te dhenave qe ndodhen brenda nje intervali. Nje kurbe me e larte (densitet me te larte) do te thote qe me shume te dhena kane vlera rreth asaj pike ne boshtin X. Ne grafikun tone shohim qe kategoria \(argetim\) ka densitet me te madh duke qene se kurba eshte me e larte ,ndersa \(strehimi\) ka densitet me te vogel. Lartesia e kurbave eshte shkallezuar ne menyre qe siperfaqja nen kurbe te jete e barabarte me 1.

\[Grafiku\ Mozaik\]

Nje nje projekt Data Science eshte shume e rendesishme nxjerja e sa me shume rezultateve dhe perfundimeve te nevojshme nga te dhenat tona. Ne nje nga fazat e analizes se te dhenave eshte edhe ajo e vizualizimit te cilen jemi duke e trajtuar akualisht.

Nje karakteristike e vecante eshte marredhenia midis dy variablave. Nese te dyja variablat jane cilesore (kategorike), atehere, per te shprehur nje marredhenie mes tyre ne perdorim ate qe quhet \(Grafiku\) \(Mozaik\). Ne disa disiplina nuk njihet, por ne R eshte i shpeshte dhe teper i nevojshem ne disa raste.

Grafiku Mozaik bazohet ne te dhena probabilitare. Per ti marre keto te dhena na nevojiten tabelat; \(tabelat\) \(e\) \(kontigjences\).

Me siper, ne kreun \(Tabelat\) \(e\) \(Kontigjences\) ne kemi ndertuar keto tabela per variablat tona kategorike dhe gjithashtu me ane te funksionit \(prop.table\) ne konvertuam keto tabela kontigjence ne tabela me vlera probabilitare.

Jane pikerisht keto tabela te cilat do te na hyjne ne pune.

Me poshte eshte ndertuar nje grafik mozaik per tabelen e katert te kontigjences \(diplomimi\)~\(metoda\)_\(e\)_\(pageses\):

library(ggplot2)
ggplot(data) + aes(x=diplomimi, y=metoda_e_pageses, fill=gjinia, colour=viti_i_studimeve, group = metoda_e_pageses)+
  labs(x="Diplomimi", y="Metoda e Pageses", title = "Grafiku Mozaik i Metodes se Preferuar te Pageses", fill="Legjenda:")+
geom_tile()+ 
  scale_fill_manual(values=c(Female="gold", Male="red",`Non-binary`="cyan" ))+
  scale_color_manual(values = c(Female="gold", Male="red", `Non-binary`="cyan"))+ 
  theme_minimal()
Warning: No shared levels found between `names(values)` of the manual scale and the data's colour values.
Warning: No shared levels found between `names(values)` of the manual scale and the data's colour values.

Analizojme kodin:

Variabli \(data\) permban te dhenat tona;

Funksioni \(aes()\) do te kombinoje te dhenat ne estetikat e ndryshme ne grafik;

\(x = diplomimi\): I atribon variablin \(diplomimi\) boshtit x;

\(y=metoda\)_\(e\)_\(pageses\): I atribon variablin \(metoda\) $$e \(pageses\) boshtit y;

\(fill = gjinia\): do te ndihmoje ne ngjyrosjen e copezave te grafikut mozaik;

\(color=viti I studimeve\): I atribon variablin \(viti\) \(i\) \(studimeve\) ngjyres se copezave;

\(group = metoda\)_\(e\)_\(pageses\): grupon copezat bazuar ne variablin \(metoda\) \(e\) \(pageses\);

Etiketimi: funksioni \(labs()\) vendos titujt per boshtet x, y.

\(geom\)_\(tile()\): krijon grafikun mozaik, ku cdo copez perfaqeson kombinimin e ndryshoreve \(diplomimi\) dhe \(metoda\) \(e\) \(pageses\);

Ngjyrat: funksionet \(scale\)_\(fill\)_\(manual()\) dhe \(scale\)_\(color\)_\(manual()\) perdoren per te ngjyrosur secilen nga pllakat e grafikut bazuar ne percaktimet e mesiperme.

Grafiku mozaik paraqet nje pamje vizuale te marredhenies midis Variablave \(diplomimi\), \(metoda\) \(e\) \(pageses\), \(gjinia\) dhe \(viti\) \(i\) \(studimeve\). Madhesia, ngjyrimi dhe pozicionimi I copezave te grafikut percjell frekuencat relative te secilit kombinim prej ketyre Variablave cilesore.

Rezultatet:

Metoda e Pageses: boshti \(y\) shfaq tre metodat e pageses; \(Cash\), \(Aplikacion\) dhe \(Karte\) \(Krediti\).

Gjinia: cdo pjesez ne grafik eshte e ngjyrosur per te perfaqesuar gjinine.

Diplomimi: boshti \(x\) I kategorizon njerezit sipas diplomimit te tyre.

Nga grafiku dalim ne perfundimin se:

Metoda me e popullarizuar e pageses eshte ajo \(Cash\), ndjekur nga \(Karta\) \(e\) \(Kreditit/Debitit\) dhe me pak ajo nepermjet aplikacioneve.

Kategoria gjinore me e shpeshte eshte ajo \(Non-binary\) e cila ndeshet me teper ne grafik (ngjyra blu e celet).

Mes te diplomuarve aplikacionet jane me pak te perdorura se kartat e kreditit.

Kujdes: grafiku mozaik nuk na tregon asgje per numrin e personave qe perdorin keto metoda pagese;

Madhesia e copezave nuk tregon asnjehere se sa eshte numri i individeve qe e perbejne ate pjese. Ajo tregon vetem proporcionin relative brenda cdo kategorie te metodes se preferuar te pageses.

\[Grafiku\ me\ Shtylla\]

library(plotly)
Warning: package ‘plotly’ was built under R version 4.3.3

Attaching package: ‘plotly’

The following object is masked from ‘package:ggplot2’:

    last_plot

The following object is masked from ‘package:stats’:

    filter

The following object is masked from ‘package:graphics’:

    layout
plot_ly (data, x=~diplomimi, color =~ metoda_e_pageses, colors="Accent")
No trace type specified:
  Based on info supplied, a 'histogram' trace seems appropriate.
  Read more about this trace type -> https://plotly.com/r/reference/#histogram
No trace type specified:
  Based on info supplied, a 'histogram' trace seems appropriate.
  Read more about this trace type -> https://plotly.com/r/reference/#histogram

Grafikut te cilit i referohemi eshte nje grafik me shtylla qe tregon perdorimin e metodave te ndryshme te pageses ne disiplina te ndryshme akademike.

Nga grafiku arrijme te dallojme qe studentet e shkencave kompjuterike dhe inxhinierise duken kryesisht indiferente, duke shfaqur pak ndryshime ne zgjedhjet e tyre te metodes se pageses. Nje kontrast i forte shfaqet midis studenteve te ekonomise dhe biologjise ,ku egzistojne pabarazi te konsiderueshme ne preferencat e tyre midis pagesave elektronike dhe atyre me para.

Gjithashtu dhe studentet e psikologjise shfaqin pabarazi te dukshme ne zgjedhjen e metodes se pageses ,ku me e preferuar rezulton \(Mobile\) \(Payment\) \(App\). Kjo metode rezulton gjithashtu e preferuar dhe nga studentet e inxhinierise. Ndersa per studentet e ekonomise dhe biologjise me e preferuara rezulton metoda \(Credit/Debit\) \(Card\).

\[Pie\ Chart\]

Kodi I meposhtem afishon nje \(pie\) \(chart\) qe vizualizon shpenzimet totale ne kategori te ndryshme shpenzimesh per te dhenat tona numerike.

library(ggplot2)
library(tidyverse)
Warning: package ‘tidyverse’ was built under R version 4.3.3
Warning: package ‘tibble’ was built under R version 4.3.3
Warning: package ‘readr’ was built under R version 4.3.3
Warning: package ‘purrr’ was built under R version 4.3.3
Warning: package ‘stringr’ was built under R version 4.3.3
Warning: package ‘forcats’ was built under R version 4.3.3
Warning: package ‘lubridate’ was built under R version 4.3.3
── Attaching core tidyverse packages ────────────────────────────────────────────────────────────────────────── tidyverse 2.0.0 ──
✔ forcats   1.0.0     ✔ readr     2.1.5
✔ lubridate 1.9.3     ✔ stringr   1.5.1
✔ purrr     1.0.2     ✔ tibble    3.2.1
── Conflicts ──────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ readr::col_factor()  masks scales::col_factor()
✖ gridExtra::combine() masks dplyr::combine()
✖ purrr::discard()     masks scales::discard()
✖ plotly::filter()     masks dplyr::filter(), stats::filter()
✖ dplyr::lag()         masks stats::lag()
ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
shpenzimet_totale <- data.frame( kategorite_e_shpenzimit = c("shkollimi","strehimi","ushqimi","transporti","mjetet_shkollore","argetim","kujdesi_personal","teknologji","mireqenia_shendetesore","te_ndryshme"),
shpenzimet = c(sum(data$shkollimi), sum(data$strehimi), sum(data$ushqimi), sum(data$transporti), sum(data$mjetet_shkollore), sum(data$argetim), sum(data$kujdesi_personal), sum(data$teknologji), sum(data$mireqenia_shendetesore), sum(data$te_ndryshme)))

#llogaritim perqindjen per secilen kategori:
shuma_totale <- sum(shpenzimet_totale$shpenzimet)
shpenzimet_totale$percentage <- round(shpenzimet_totale$shpenzimet / shuma_totale * 100, 2)

#grafiku
ggplot(shpenzimet_totale, aes(x="", y=shpenzimet, fill=kategorite_e_shpenzimit, type='3D pie')) +
  geom_bar(stat="identity", width = 2) +
  geom_text(aes(label=paste0(percentage, "%")), position=position_stack(vjust=0.6), size = 2, color="black", fontface="bold") + 
coord_polar("y", start=1)+
  labs(title="Shpenzimet Totale sipas Kategorive", x=NULL, y=NULL)+
  scale_fill_manual(values = c("lightblue", "orange", "green", "red","blue","yellow","maroon3", "cyan", "pink2","purple") )+
  theme_void()+
  theme(plot.title = element_text(hjust=0.5, size=15, face="bold"),
        legend.title=element_blank(),
        legend.text = element_text(size=8),
        legend.position = "right")

NA

Interpretimi:

Kodi krijon nje permbledhje te te gjitha shumave te shpenzuara per te gjitha kategorite (shkollimi, ushqimi, transporti etj.).

1. \(shpenzimet\)_\(totale\) paraqet shumen totale te te gjitha shpenzimeve te kryera.

2. \(Llogaritja\) \(e\) \(perqindjeve\): kodi llogarit perqindjen e seciles nga shpenzimet totale te kryera, cfare pjese do te zere secila pjese e shpenzimeve ne pie chart. Ato do te paraqiten te rrumbullakosura ne 2 shifra pas presjes dhjetore.

3. Vizualizimi I pie chart-it: Funksioni \(ggplot()\) perdoret per te krijuar kete grafik.

Funksioni \(aes()\) lidh kategorite e shpenzimeve me \(fill()\) aesthetic dhe shpenzimet totale me y aesthetic.

Funksioni \(geom\)_\(bar()\) perdoret per te krijuar copetimet/copat e grafikut pie, ku se bashku me parametrin \(width\), jep nje efekt 3D.

\(geom\)_\(text()\) perdoret per te shtuar vlerat e perqindjes ne copat perkatese. Parametri \(position()\) vendos keto vlera brenda copave, pra I pozicionon ato.

Funksioni \(coord\)_\(polar()\) perdoret per te transformuar krafikun drejtkendor ne nje grafik rrethor (rreth). \(scale\)_\(fill\)_\(manual()\) perdoret per te vendosur ngjyra te vecanta per secilen nga copat e pie chart-it.

Funksioni \(theme\)_\(void()\) perdoret per te ndertuar legjenden e cila na sherben per orientim ndaj te dhenave te paraqitura ne pie chart.

Ky lloj vizualizimi eshte I rendesishem per te kuptuar shperndarjen e shpenzimeve dhe identifikimin e kategorive me te rendesishme te kostos per te dhenat qe ne disponojme.

\[Korrelacioni\\ Matrica\ e\ Korrelacionit\\ Regresi\ Linear\]

Korrelacioni eshte cdo marredhenie statistikore midis dy ndryshoreve te rastit. Zakonisht i referohet shkalles ne te cilen nje pale ndryshoresh jane te lidhura ne menyre lineare.

\[Formula\ matematike:\\ {𝜌(𝑋,𝑌)} = {\frac{\displaystyle\ S_{xy}} {{S_x}{S_y}}}\]

Me poshte do te ndertojme matricen e korrelacionit ne baze te se ciles do te ndertohet drejteza e regresit linear.

Ngjyra blu do te tregoje nje lidhje te dobet mes variablave, ndersa ngjyra e kuqe do te tregoje nje lidhje te forte mes tyre.

correlation_matrix <- cor(numeric_df)

library(pheatmap)
Warning: package ‘pheatmap’ was built under R version 4.3.3
pheatmap(correlation_matrix, 
         color = colorRampPalette(c("darkblue", "white", "red3"))(200),
         fontsize = 10,
         fontsize_row = 8,
         fontsize_col = 8,
         main = "Correlation Heatmap i Variablave Numerike",
         display_numbers = TRUE, 
         number_color = "white" )

Per te arsyetuar mbi varesine ndermjet ndryshoreve numerike shikojme grafikun dhe vlerat e koeficienteve te korrelacionit.

Nga matrica verejme se te dhenat nuk kane nje lidhje te forte me njera tjetren, dhe kjo percaktohet nga ngjyrimi blu i kufizave te matrices.Ne do te zgjedhim disa ndryshore qe mendojme se kane pak varesi me njera tjetren (dy qe e kane ngjyren me te zbehte).

library(ggplot2)
library(ggpubr)
Warning: package ‘ggpubr’ was built under R version 4.3.3
ggplot(data, aes(x = argetim, y = te_ardhurat_mujore)) + 
  geom_point(color = "#FF0000",size=0.9) + 
  labs(x = "Shpenzimet per argetim", y = "Te ardhurat mujore", title = "Shpenzimet per argetim krahasuar me te ardhurat mujore") +  
  geom_smooth(method = "lm", color = "black", formula = y ~ x) + 
  stat_cor(label.x = 100, label.y = 1400, size = 5) + 
  stat_regline_equation(label.x = 100, label.y = 1300, size = 5)

library(ggplot2)
library(ggpubr)

ggplot(data, aes(x = transporti, y = te_ardhurat_mujore)) + 
  geom_point(color = "black",size=0.9) + 
  labs(x = "Shpenzimet per transport", y = "Te ardhurat mujore", title = "Shpenzimet per transport krahasuar me te ardhurat mujore") +  
  geom_smooth(method = "lm", color = "black", formula = y ~ x) + 
  stat_cor(label.x = 100, label.y = 1400, size = 5) + 
  stat_regline_equation(label.x = 100, label.y = 1300, size = 5)

library(ggplot2)
library(ggpubr)

ggplot(data, aes(x = shkollimi, y = te_ardhurat_mujore)) + 
  geom_point(color = "blue", size = 1) + 
  labs(x = "Shkollimi", y = "Te ardhurat mujore", title = "Shpenzimet per shkollim krahasuar me te ardhurat mujore") +  
  geom_smooth(method = "lm", color = "black", formula = y ~ x) + 
  stat_cor(label.x = 4000, label.y = 1400, size = 5, alpha = 2) + 
  stat_regline_equation(label.x = 4000, label.y = 1300, size = 5, alpha = 2)

library(ggplot2)
library(ggpubr)

ggplot(data, aes(x = kujdesi_personal, y = te_ardhurat_mujore)) + 
  geom_point(color = "purple3", size = 1) + 
  labs(x = "Shpenzimet per kujdes personal", y = "Te ardhurat mujore", title = "Shpenzimet per kujdes personal krahasuar me te ardhurat mujore") +  
  geom_smooth(method = "lm", color = "black", formula = y ~ x) + 
  stat_cor(label.x = 15, label.y = max(data$te_ardhurat_mujore) * 0.95, size = 5) + 
  stat_regline_equation(label.x = 15, label.y = max(data$te_ardhurat_mujore) * 0.90, size = 5)

Nga grafiket e ndertuar me siper se bashku me drejtezat e regresit shohim qe lidhja ndermjet te ardhurave mujore dhe shpenzimeve sipas kujdesit personal, transportit, shkollimit dhe argetimit eshte shume pak lineare. Ne po marrim ne shqyrtim njerin grafik prej tyre.

\[Koeficenti\ i\ Korrelacionit\]

Koeficenti i korrelacionit na ndihmon te kuptojme nese ndermjet te dhenave ka lidhje lineare apo jo.

Vetite e tij:

Koeficenti i korrelacionit merr vlera nga -1 ne 1.

Nese vlera e ketij koeficenti eshte afer 0 (midis -0.2 dhe 0.2 ) na tregon se ndermjet variablave nuk ka nje varesi lineare.

Mund te perdorim dy funksione per te pare vleren e korrelacionit qe jane pjese e librarise status:

1.\(cor.test\)

2.\(cor\);


cor(data$transporti, data$te_ardhurat_mujore)
[1] 0.04615186
koeficentet <- cor.test(data$transporti,data$te_ardhurat_mujore)

koeficentet$estimate
       cor 
0.04615186 

Shohim qe vlera e koeficentit te korrelacionit eshte 0.04615186 qe eshte shume prane 0.

Pra midis variablave nuk ka nje lidhje lineare.

Po te veme re dhe grafiket e tjere dhe drejtezat e tyre, gjithashtu nuk ka nje varesi te dukshme.

\[Ndertimi\ i\ nje\ modeli\ te\ thjeshte\ linear\]

\[Y\ = \ β_0\ +\ β_1\ +\ gabimi\\ ku\ β_0\ dhe\ β_1\ jane\ parametrat\ e\ vijes\]

Perdorim funksionin \(lm()\) per te ndertuar nje model linear.

set.seed(123)
zgjedhja<-sample(c(TRUE,FALSE),nrow(data),replace=T,prob=c(0.6,0.4))

Specifikojme qe te dhenat do te ndahen 40% testues dhe 60% trajnues; ndajme te dhenat ne test dhe train:

train<-data[zgjedhja,]
test<-data[!zgjedhja,]

Ndertohet modeli duke marre si te dhena te dhenat train (trajnuese)

model1<-lm(transporti~te_ardhurat_mujore,data= train)
model1

Call:
lm(formula = transporti ~ te_ardhurat_mujore, data = train)

Coefficients:
       (Intercept)  te_ardhurat_mujore  
         1.181e+02           5.277e-03  

\[Miresia\ e\ modelit\] Per te kontrolluar miresine e nje modeli shikojme:

1.\(RSE->residual\) \(standart\) \(error\): eshte distanca mesatare qe vlerat e vezhguara te jene larg vleres se modelit. Sa me e vogel kjo vlere aq me i mire modeli sepse kuptojme qe vlerat qe jep modeli ndodhen afer atyre qe jane vlera te verteta.

2.\(R^2\)-> na tregon sasa perqind te dhenave te shpjegohen nga modeli.

3.\(p-value\)->nese kjo vlere eshte me e vogel se 0.05 atehere themi qe kemi nje lidhje te rendesishme ndermjet ndryshoreve.

Bejme nje summary te modelit per te pare perfundimet:

summary(model1)

Call:
lm(formula = transporti ~ te_ardhurat_mujore, data = train)

Residuals:
    Min      1Q  Median      3Q     Max 
-74.835 -37.737  -0.988  39.736  78.186 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)        1.181e+02  6.601e+00  17.896   <2e-16 ***
te_ardhurat_mujore 5.277e-03  6.120e-03   0.862    0.389    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 43.93 on 605 degrees of freedom
Multiple R-squared:  0.001228,  Adjusted R-squared:  -0.0004232 
F-statistic: 0.7436 on 1 and 605 DF,  p-value: 0.3888

Shohim qe:

Residual standard error: 43.93. Kjo do thote qe shpenzimet reale per transport devijojne nga modeli linear ne vleren 43.93. Mund ta kthejme ne %:

mesatarja_RSE<-sigma(model1)/mean(train$transporti)
sprintf("Gabimi ne perqindje i modelit:%s%%",round(mesatarja_RSE*100,2))
[1] "Gabimi ne perqindje i modelit:35.54%"

Gabimi ne % eshte 35.54%. Kjo do te thote se modeli yne nuk pershtatet shume mire me te dhenat e verteta.

Vlera e R^2 = 0.001228 modeli shpjegon 0.1228% te te dhenave, pothuajse aspak.

Kontrollojme mbetjet e modelit:

Mbetja eshte distanca ndermjet vleres aktuale dhe asaj qe jep modeli qe ne kemi ndertuar.

vlerat_e_modelit <- predict(model1, data = train)
 vlerat_e_modelit
       1        3        6        7        9       10       12       14       15       17       18       19       27       28 
123.1910 122.0089 120.8954 125.2808 125.5341 125.6449 123.7715 124.3415 126.0302 125.6238 125.8085 125.9827 121.6553 122.3361 
      29       30       35       36       38       39       40       41       42       43       44       45       46       47 
122.9113 120.9376 125.3283 125.1436 125.0433 123.2280 121.3018 121.3281 122.3783 124.8586 120.8215 124.9167 123.0380 124.2729 
      48       49       51       52       54       55       56       57       60       62       63       64       66       70 
124.4417 123.6026 125.4022 125.7927 124.9642 123.1013 124.1040 122.6422 121.8031 123.8560 122.0036 123.7346 123.8982 121.1012 
      74       75       76       77       79       80       81       83       85       86       90       91       93       95 
124.3415 125.1753 125.7452 123.3229 122.8744 124.2781 125.9669 123.9668 123.0433 125.2386 122.3572 124.4628 124.9695 125.4391 
      96       98       99      100      101      102      103      105      109      110      112      113      116      117 
123.5974 122.1831 123.0591 122.3730 125.1700 124.0195 122.9905 122.7899 123.2280 122.2728 125.2544 122.1461 124.9220 124.1251 
     119      120      122      123      124      125      127      128      129      135      140      141      142      143 
124.8111 124.3362 125.9827 125.1383 123.9140 125.8402 122.5472 124.5314 125.9616 121.7028 120.9112 123.1541 125.0011 123.9562 
     144      146      147      148      149      152      153      154      155      156      157      158      159      160 
123.8507 125.2808 122.7636 121.5603 122.8691 121.5498 121.5973 124.1040 125.0961 122.9746 122.7372 122.8902 120.9640 120.8057 
     161      162      164      165      166      168      169      170      172      177      178      180      182      184 
124.4734 124.4101 124.3678 122.4100 122.6475 123.7082 121.4073 124.5051 123.5868 124.9220 123.9615 124.6264 125.5816 121.3440 
     185      186      187      188      191      192      196      197      199      200      201      204      205      207 
121.1223 125.0486 125.2808 123.5182 125.7769 123.2438 125.9880 122.8480 122.3783 121.0221 120.8954 120.7951 124.4839 122.6580 
     208      209      210      211      212      213      215      217      218      221      225      226      227      228 
122.4205 120.9851 122.8269 123.3704 122.1461 124.4628 123.3810 125.7558 124.4839 123.8718 122.2200 125.3389 122.4100 122.6527 
     232      233      234      235      236      237      239      241      243      245      247      251      252      253 
122.8533 122.7477 122.6211 122.7741 122.4153 122.4047 122.6527 124.4945 124.8270 124.4998 124.7320 122.2306 122.3572 123.8243 
     254      255      257      258      259      265      266      267      268      269      270      272      273      274 
125.5447 123.9246 122.1197 123.8718 123.0485 124.8692 122.7794 125.6502 124.8692 121.8136 125.4127 124.0776 124.0776 121.3967 
     278      279      282      283      284      285      286      287      288      289      291      292      293      298 
125.1964 124.0512 125.4655 124.0565 124.0090 122.7741 125.9932 122.7213 125.4233 125.1278 121.7978 121.3809 125.4919 121.6553 
     299      302      306      307      308      309      310      311      312      314      315      318      319      322 
125.8297 122.0247 120.8321 124.2623 124.0037 123.1910 124.3415 121.9720 125.9616 125.2439 121.9614 122.7213 121.0009 121.6659 
     323      325      326      328      329      332      335      336      341      342      343      344      345      346 
125.1858 125.2017 121.3492 125.0433 125.8983 122.9219 121.6131 125.9880 121.2068 125.8824 123.5235 122.1461 123.2491 123.3599 
     348      349      351      353      354      358      359      361      362      364      365      367      368      369 
122.3836 124.3573 122.5841 121.1962 123.2807 123.4971 123.2491 123.3177 123.5235 125.7558 121.5445 125.3125 124.0618 123.5182 
     370      371      372      374      375      378      379      381      383      385      387      388      389      390 
122.0195 123.0485 125.7505 121.0959 124.5314 121.8400 125.6977 120.9640 121.8348 122.5789 124.1198 123.3704 125.5658 125.3547 
     392      395      396      397      398      399      402      404      405      406      408      409      411      413 
124.5948 123.2702 122.0195 121.1487 122.5314 121.8981 124.8270 123.4390 124.4945 125.2914 121.8611 123.9509 125.8244 125.0433 
     414      415      416      418      419      420      421      423      424      427      428      429      432      433 
125.9563 125.8824 122.7213 125.7505 122.1778 125.5394 125.3758 125.0117 121.1540 123.0063 121.4126 121.6184 125.6661 120.9165 
     435      437      438      439      440      441      442      444      448      449      451      452      453      454 
124.5684 125.9616 121.5445 122.4522 124.8270 121.1065 124.7478 122.6052 122.0036 121.7450 125.2386 125.8613 124.7742 123.0169 
     455      459      460      462      463      464      465      466      467      469      471      473      476      478 
123.0274 122.9377 125.1172 123.4338 125.6027 123.1382 123.4654 122.7424 122.9958 121.6817 126.0091 123.2068 125.1594 125.2703 
     479      481      483      486      487      489      492      493      495      497      498      501      502      503 
125.7188 125.2122 124.4417 122.6791 121.1329 122.4680 120.7846 122.6738 120.9851 120.7899 121.6870 123.7399 125.5183 125.5341 
     504      505      506      507      508      510      511      512      514      516      517      519      521      522 
124.3837 122.0564 125.4391 123.3968 121.3967 123.1963 123.1488 124.9220 124.0776 122.3730 121.6395 123.4390 125.6713 122.9166 
     523      524      525      528      530      533      535      537      539      540      542      544      547      550 
123.3652 124.7109 124.8534 122.9694 123.1013 124.9695 122.5102 124.8797 120.9060 123.4443 121.0326 124.4523 123.9879 120.7899 
     551      552      553      555      556      558      559      560      561      564      567      569      571      573 
124.9589 122.9008 124.1990 123.7082 124.7056 124.6053 123.2280 125.1964 125.5975 125.4022 124.9378 123.6238 122.8585 123.3177 
     574      577      578      579      580      584      586      587      590      591      592      594      595      597 
125.5288 123.1277 122.5366 121.8031 125.9405 121.9720 125.4814 126.0038 125.6027 124.1304 123.2596 120.8954 120.9482 122.0353 
     598      600      601      603      604      605      607      609      610      612      613      615      620      624 
123.9351 125.0222 124.8006 123.2807 125.8349 125.0064 122.4416 123.6976 125.3758 124.7742 125.5183 121.0907 120.9957 123.5235 
     625      626      627      629      630      633      635      636      640      641      644      645      648      649 
124.6212 121.6184 125.2228 121.0643 120.9904 124.6581 121.0801 123.0169 123.0380 124.7056 123.4127 121.2595 124.9853 124.1568 
     653      654      658      659      660      663      665      666      668      670      671      672      673      674 
125.3072 124.2676 125.1383 123.6501 121.4020 123.1013 123.8982 125.7294 125.5922 121.0854 124.1726 124.9747 123.1910 122.2253 
     675      676      678      679      680      686      687      688      689      690      691      693      694      695 
125.9616 125.0170 125.7347 125.8402 125.4127 123.8612 121.6448 125.6397 125.3441 121.9034 124.7795 125.6291 121.3229 124.7320 
     696      697      698      699      700      702      703      705      707      708      709      710      712      715 
121.1276 121.0168 124.3045 122.5366 124.0301 125.6977 122.8269 121.5392 122.0933 121.5867 124.1568 122.4153 124.7584 122.4364 
     716      717      718      720      721      730      731      735      736      739      740      742      743      744 
123.5921 123.5288 125.2122 124.5631 125.1647 125.9458 120.8901 121.3704 122.5894 123.3916 123.9721 125.6238 121.3545 125.7822 
     745      746      748      751      752      753      754      755      756      757      759      760      761      762 
124.8375 122.1989 125.0117 122.3783 124.8270 126.0091 125.5341 121.6870 124.3309 121.4865 123.4021 122.7055 125.5658 121.9984 
     763      764      765      766      767      768      775      776      777      778      781      783      786      787 
123.9773 124.2834 125.0803 125.8983 120.9640 123.6501 124.7689 123.7768 122.1303 122.3255 120.8479 121.4759 125.6977 122.4839 
     788      789      792      793      794      796      797      798      799      800      801      802      803      804 
123.2385 124.0776 123.4602 125.9352 121.0221 125.1331 122.1514 125.2280 122.8585 123.6026 121.6395 125.5394 123.9087 122.2992 
     805      807      808      811      813      816      817      818      819      820      822      826      827      828 
121.2331 125.4286 125.0011 122.7055 125.3758 121.5076 125.5077 123.0696 122.7899 125.5130 125.6819 120.9798 123.5393 125.5500 
     829      831      833      836      839      840      844      845      846      848      849      850      851      855 
121.7820 121.0643 124.6106 121.0696 123.0538 121.7398 122.5894 125.3441 123.0063 124.0987 122.6105 123.5288 124.4101 124.7689 
     856      858      859      861      862      864      866      867      868      869      870      871      872      874 
125.0644 121.6659 121.9772 123.2016 124.9325 125.5922 123.8560 124.8375 122.5947 125.6449 121.7398 125.0433 122.8216 123.2280 
     877      881      884      887      888      889      890      891      894      897      898      899      902      904 
120.7793 123.6079 125.7980 125.1700 123.2966 124.1568 125.5183 124.4681 123.9087 120.8426 124.3309 124.5948 122.8533 125.9563 
     906      910      911      912      914      915      917      918      919      920      922      923      927      928 
125.9246 125.7716 123.5710 123.5921 123.8665 125.1753 125.9616 122.8216 124.4892 123.6607 121.3704 124.8903 125.4761 125.2333 
     929      932      934      936      937      940      942      943      944      945      946      947      948      949 
125.2280 123.6132 125.2333 124.3415 122.5472 124.1937 122.2411 124.1515 121.0748 123.1382 124.7267 123.8982 121.9192 122.6580 
     950      951      952      954      955      958      959      960      961      962      964      966      967      968 
123.5235 123.7082 122.1356 121.5287 121.6606 124.0882 124.3942 120.9218 122.2200 124.6581 124.3045 120.8479 123.4918 122.0564 
     970      972      974      975      978      979      980      981      987      988      989      990      991      992 
124.1620 125.8613 125.1331 124.5684 125.4444 121.0537 123.4813 123.5129 125.4233 123.8454 124.2570 123.4707 125.5869 125.4761 
     993      994      995      998     1000 
124.9589 125.4180 122.1672 123.1857 120.9904 
 mbetjet_e_modelit <- resid(model1)
 mbetjet_e_modelit
          1           3           6           7           9          10          12          14          15          17 
 -0.1910156  14.9910944   1.1045998 -24.2808171 -43.5341264  -8.6449492  76.2284840 -74.3414619 -63.0301904  74.3761599 
         18          19          27          28          29          30          35          36          38          39 
-15.8085448 -56.9826949  63.3446720  56.6639033   8.0886801  58.0623816  40.6716874 -32.1436079  22.9566603 -35.2279565 
         40          41          42          43          44          45          46          47          48          49 
 56.6982495  67.6718631  24.6216851 -69.8586350  71.1784817  57.0833150  72.9620255 -38.2728573 -67.4417301 -37.6026431 
         51          52          54          55          56          57          60          62          63          64 
 11.5978055 -58.7927130 -27.9641805  73.8986981  17.8960156  22.3578212 -17.8030918 -47.8559524  41.9963717 -65.7345751 
         66          70          74          75          76          77          79          80          81          83 
 19.1018294 -16.1012140 -27.3414619  60.8247284  40.2547825   4.6770525   6.1256210   0.7218654 -51.9668631  40.0332248 
         85          86          90          91          93          95          96          98          99         100 
-69.0432518  26.7614011 -25.3572058 -42.4628392  19.0305422  48.5608646 -66.5973659  77.8169443  12.9409164 -68.3730377 
        101         102         103         105         109         110         112         113         116         117 
-74.1699943  11.9804520  20.0095210 -19.7899425 -67.2279565 -12.2727694   3.7455692 -38.1461148  69.0780377  43.8749065 
        119         120         122         123         124         125         127         128         129         135 
 -2.8111395  45.6638154  20.0173051  53.8616693  43.0859975  50.1597915  37.4528122 -71.5314438  12.0384142 -46.7028235 
        140         141         142         143         144         146         147         148         149         152 
 62.0887680 -55.1540746 -74.0011215  25.0437793 -43.8506752 -50.2808171 -26.7635561  39.4396629   2.1308983 -60.5497825 
        153         154         155         156         157         158         159         160         161         162 
 66.4027220  52.8960156 -52.0961125  61.0253528  43.2628302 -38.8902108 -38.9640048  54.1943135 -68.4733938 -45.4100665 
        164         165         166         168         169         170         172         177         178         180 
 12.6321517 -71.4099786  23.3525439  70.2918113  75.5927040  18.4949425 -59.5868113   4.0780377  61.0385020 -25.6264348 
        182         184         185         186         187         188         191         192         196         197 
-48.5816219  64.6560313 -57.1223231 -65.0486170 -65.2808171  32.4817933  46.2231189 -67.2437883  67.0120278  69.1520074 
        199         200         201         204         205         207         208         209         210         211 
 44.6216851 -27.0220548 -55.8954002 -51.7951319  32.5160516   3.3419894  66.5794668  26.0148861  -9.8268835 -39.3704430 
        212         213         215         217         218         221         225         226         227         228 
-28.1461148  -1.4628392 -69.3809975  63.2442280 -16.4839484  62.1282157 -49.2199966 -73.3388672  57.5900214 -10.6527333 
        232         233         234         235         236         237         239         241         243         245 
  4.1467301 -11.7477243 -20.6210697  66.2258893 -16.4152559  53.5952987   0.3472667  65.5054971 -71.8269713 -58.4997802 
        247         251         252         253         254         255         257         258         259         265 
-32.7319804 -27.2305512 -62.3572058  51.1757112 -21.5446810   1.0754430   3.8802716 -37.8717843  63.9514709 -27.8691896 
        266         267         268         269         270         272         273         274         278         279 
-22.7793880  19.3497735  19.1308104  78.1863537  17.5872509 -61.0775980  10.9224020  23.6032585  13.8036193 -23.0512117 
        282         283         284         285         286         287         288         289         291         292 
-34.4655218 -20.0564889  53.9910065 -17.7741107  61.0067505   4.2786621 -60.4233036  74.8722239 -29.7978145 -12.3809097 
        293         298         299         302         306         307         308         309         310         311 
-41.4919082   1.3446720  14.1703461  37.9752626  31.1679271  30.7376973 -31.0037162 -45.1910156 -31.3414619 -45.9719646 
        312         314         315         318         319         322         323         325         326         328 
-22.9615858   8.7561238 -60.9614101 -10.7213379  31.9990543  54.3341174   5.8141738 -12.2016580  56.6507540 -10.0433397 
        329         332         335         336         341         342         343         344         345         346 
-12.8982585  47.0781256 -44.6131098  -5.9879722  66.7932405  31.1175733  64.4765160 -34.1461148 -64.2490656 -34.3598884 
        348         349         351         353         354         358         359         361         362         364 
-21.3835922  -6.3572937  73.4158713  48.8037950  53.7192707 -69.4970976  58.7509344  -5.3176702 -37.5234840 -55.7557720 
        365         367         368         369         370         371         372         374         375         378 
-47.5445052  27.6875192  -2.0617662  14.4817933  57.9805399  22.9514709  43.2495052 -33.0959367 -59.5314438  28.1599673 
        379         381         383         385         387         388         389         390         392         395 
-74.6977220 -16.9640048 -56.8347554  33.4211485 -28.1198163  -9.3704430 -47.5657901 -66.3546990 -69.5947712  59.7298253 
        396         397         398         399         402         404         405         406         408         409 
-47.0194601 -65.1487095 -32.5313560  -1.8980828  34.1730287  24.5609524  17.5054971  44.7086283  61.1388582  -1.9509434 
        411         413         414         415         416         418         419         420         421         423 
 13.1756234  26.9566603  18.0436914 -51.8824267  38.2786621  26.2495052  51.8222216  53.4605963  58.6241919  53.9883240 
        424         427         428         429         432         433         435         437         438         439 
-49.1539868  -6.0063109 -12.4125733 -33.6183871  35.3339417  13.0834907   1.4316152  33.0384142 -44.5445052  37.5478032 
        440         441         442         444         448         449         451         452         453         454 
 -5.8269713  59.8935087  53.2521878  42.3947622 -51.0036283  18.2549583  -0.2385989 -64.8613176  70.2258014 -43.0168654 
        455         459         460         462         463         464         465         466         467         469 
 22.9725800  41.0622937 -65.1172216  55.5662297 -11.6027310 -12.1382428  46.5345660  -2.7424470 -44.9957563 -57.6817144 
        471         473         476         478         479         481         483         486         487         489 
-50.0090813 -67.2068474  -0.1594398  70.7297374  35.2811689  57.7877875  58.5582699  67.3208803 -29.1328776  10.5319713 
        492         493         495         497         498         501         502         503         504         505 
-66.7845774  48.3261576  14.0148861  56.2101453 -26.6869917  -6.7398523  56.4817054   8.4658736  43.6163199 -71.0564011 
        506         507         508         510         511         512         514         516         517         519 
 32.5608646   6.6031706  -3.3967415 -56.1962928 -26.1487973 -64.9219623 -24.0775980  50.6269623 -51.6394962 -67.4390476 
        521         522         523         524         525         528         530         533         535         537 
 58.3286644   3.0834028 -25.3651657 -17.7108713  72.1466423  34.0306301 -10.1013019  12.0305422 -34.5102469 -43.8797441 
        539         540         542         544         547         550         551         552         553         555 
-35.9059547 -49.4443248 -55.0326094 -33.4522847  -0.9878843   0.2101453  24.0410967 -45.9007653  46.8010246  33.2918113 
        556         558         559         560         561         564         567         569         571         573 
 11.2944060  67.3946743  67.7720435 -46.1963807  13.4025463   7.5978055 -65.9377942 -42.6237523 -28.8585471   2.6823298 
        574         577         578         579         580         584         586         587         590         591 
 23.4711509  55.8723118 -20.5366333 -44.8030918 -32.9404767  60.0280354 -24.4813537  17.9961960  30.3972690  -3.1303708 
        592         594         595         597         598         600         601         603         604         605 
 10.7403798  67.1045998  45.0518270 -11.0352920 -25.9351116  -5.0222306  -7.8005850 -30.2807293 -74.8349312 -37.0063987 
        607         609         610         612         613         615         620         624         625         626 
-19.4416423  46.3023659 -49.3758081  -3.7741986  43.4817054   0.9093406 -53.9956685 -66.5234840 -39.6211576 -62.6183871 
        627         629         630         633         635         636         640         641         644         645 
-50.2227671 -52.0642730 -41.9903912  20.3419015 -32.0801049 -17.0168654 -50.0379745   3.2944060 -19.4126612 -28.2595323 
        648         649         653         654         658         659         660         663         665         666 
 43.0147104  59.8432428  67.6927965  -7.2675800  27.8616693 -52.6501386 -32.4020188  11.8986981 -30.8981706 -39.7293857 
        668         670         671         672         673         674         675         676         678         679 
-54.5921765 -18.0853822   5.8274110 -55.9747351  32.8089844  59.7747261  42.0384142 -23.0169533 -50.7346629 -63.8402085 
        680         686         687         688         689         690         691         693         694         695 
 -6.4127491  58.1387703 -71.6447735  22.3603280   1.6558555 -55.9033600 -30.7794759  64.3708826 -55.3228596 -26.7319804 
        696         697         698         699         700         702         703         705         707         708 
-25.1276004 -21.0167776 -41.3045209 -34.5366333 -37.0301026 -48.6977220 -40.8268835 -52.5392280  68.9066580 -65.5867234 
        709         710         712         715         716         717         718         720         721         730 
-41.1567572  -2.4152559 -56.7583667  42.5636350 -13.5920886  43.4712387  -3.2122125   6.4368925  73.8352829 -25.9457540 
        731         735         736         739         740         742         743         744         745         746 
-40.8901229 -64.3703551  66.4105940  -2.3915521  42.0279475  25.3761599  42.6454767 -68.7821584   7.1624741 -67.1988875 
        748         751         752         753         754         755         756         757         759         760 
 57.9883240  50.6216851  62.1730287  59.9909187  12.4658736 -18.6869917  66.6690927  74.5135448 -52.4021066 -22.7055061 
        761         762         763         764         765         766         767         768         775         776 
 42.4342099  32.0016490   7.0226702  71.7165882  59.9197194  54.1017415   7.0359952  40.3498614  22.2310787 -40.7767933 
        777         778         781         783         786         787         788         789         792         793 
-53.1302829 -49.3255422 -28.8479047   6.5240994  -2.6977220   4.5161395 -16.2385111  34.9224020  -6.4601567 -48.9351995 
        794         796         797         798         799         800         801         802         803         804 
-63.0220548 -34.1330534 -69.1513921  41.7719556  34.1414529  10.3973569 -46.6394962   3.4605963 -33.9087252   5.7008442 
        805         807         808         811         813         816         817         818         819         820 
 49.7668541  54.5714191 -10.0011215  58.2944939  18.6241919  -1.5075643  -2.5077400  -1.0696382  30.2100575  55.4869827 
        822         826         827         828         829         831         833         836         839         840 
-36.6818902 -13.9798366 -11.5393158 -73.5499583 -63.7819827  73.9357270  12.3893970   8.9304497 -39.0538064  33.2602355 
        844         845         846         848         849         850         851         855         856         858 
-51.5894060  37.6558555 -13.0063109  35.9012928  44.3894849 -50.5287613 -72.4100665 -17.7689213  64.9355512 -43.6658826 
        859         861         862         864         866         867         868         869         870         871 
 56.0227581   4.7984299 -59.9325169  68.4078235 -34.8559524  35.1624741 -71.5946833  31.3550508  64.2602355  71.9566603 
        872         874         877         881         884         887         888         889         890         891 
 -1.8216062 -35.2279565  21.2206999  52.3920796 -60.7979903  57.8300057  22.7034389  -3.1567572 -32.5182946 -73.4681165 
        894         897         898         899         902         904         906         910         911         912 
 48.0912748  40.1573726  38.6690927 -23.5947712  21.1467301  -0.9563086 -52.9246449 -12.7716039 -24.5709795  -7.5920886 
        914         915         917         918         919         920         922         923         927         928 
-70.8665070   3.8247284 -35.9615858  59.1783938  -4.4892256  73.3393068 -22.3703551 -25.8902987 -17.4760764   6.7666784 
        929         932         934         936         937         940         942         943         944         945 
 16.7719556   9.3868023 -24.2333216 -31.3414619  26.4528122  34.8063019  48.7588942  58.8485201  36.9251724  57.8617572 
        946         947         948         949         950         951         952         954         955         958 
 57.2732969  34.1018294  72.0808081 -27.6580106  37.4765160  55.2918113 -46.1355602  60.4713266 -33.6606053 -59.0881526 
        959         960         961         962         964         966         967         968         970         972 
-65.3942347  15.0782134 -47.2199966  -9.6580985  34.6954791 -36.8479047  23.5081797 -17.0564011  41.8379655 -38.8613176 
        974         975         978         979         980         981         987         988         989         990 
-38.1330534  27.4316152  -6.4444127  13.9462815 -61.4812658 -58.5129294  16.5766964   7.1546021  57.7429745  63.5292888 
        991         992         993         994         995         998        1000 
 -6.5868992 -70.4760764  67.0410967  61.5819737 -61.1672239  15.8142617  70.0096088 

Ne te dhenat tona trajnuese mund te shtojme nje kolone te re qe permban vlerat qe parashikon modeli.

train$vlerat_e_modelit<-predict(model1)
 train$mbetjet_e_modelit<-residuals(model1)
 View(train)
 
 grafik1<-ggplot(train,aes(transporti , te_ardhurat_mujore)) + geom_point() + geom_point (aes(y = vlerat_e_modelit,color = "red2"))
 grafik1

Mund te ndertojme segmentet qe paraqesin gabimet:

library(ggplot2)

grafik2 <- ggplot(train,aes(transporti ,te_ardhurat_mujore))+geom_point() + labs(x="Transporti", y= "Te Ardhurat Mujore") + geom_point(aes(y=vlerat_e_modelit),color="blue")+geom_segment(aes(xend= transporti, yend=vlerat_e_modelit),color="red")
grafik2

library(correlation)
Warning: package ‘correlation’ was built under R version 4.3.3
plot(data$ushqimi, data$mjetet_shkollore)

cor(data$ushqimi,data$mjetet_shkollore)
[1] 0.07548524
model1<-lm(ushqimi ~ mjetet_shkollore, data=data)
model1

Call:
lm(formula = ushqimi ~ mjetet_shkollore, data = data)

Coefficients:
     (Intercept)  mjetet_shkollore  
       236.80006           0.09065  
library(ggplot2)

ggplot(data) + aes(x = ushqimi, y= mjetet_shkollore) +
  geom_point(size = 1L, colour = "#000000") +
  geom_smooth(method = "lm", formula  = y~x, se = TRUE, color = "blue") + 
  stat_cor(label.x=2, label.y=4) +
  stat_regline_equation(label.x=1, labe.y=2, size=3) +
  labs(x = "Ushqimi", y = "Mjetet Shkollore",
       title = "Shpenzimet per ushqim vs Shpenzimet per Mjete Shkollore",
       subtitle = "A ndikojne shpenzimet ne ushqyerje ne ato per mjete shkollore?") +
  theme_classic()
Warning in stat_regline_equation(label.x = 1, labe.y = 2, size = 3) :
  Ignoring unknown parameters: `labe.y`

Le te analizojme nje nga rezultatet e regreseve te ndertuara me siper:

REZULTATI: Nga pergjigjja e mesiperme ne modelin \(Shpenzimet\) \(per\) \(ushqim\) \(vs\) \(Shpenzimet\) \(per\) \(Mjete\) \(Shkollore\) kemi se ekuacioni qe i pershtatet ketij modeli regresi eshte

\[Vleresimi\ = \ 160\ +\ 0.063X\] qe do te thote se per cdo njesi shpenzimi ne ushqim, kemi nje rritje me 0.063 njesi ne mjete shkollore.

Mundemi te gjejme edhe intervalin e besimit nepermjet funksionit \(confint()\):

confint(model1, level = 0.95)
                        2.5 %      97.5 %
(Intercept)      222.73043149 250.8696790
mjetet_shkollore   0.01626667   0.1650317

Sic duket edhe nga rezultati, intervali i besimit eshte [222.73 ; 250.86]

Funksioni \(predict()\) parashikon se sa do te jete vlera e ndryshores se varur kur jepen disa vlera te ndryshores se pavarur.

summary(model1)

Call:
lm(formula = ushqimi ~ mjetet_shkollore, data = data)

Residuals:
     Min       1Q   Median       3Q      Max 
-160.913  -77.172    3.852   74.670  155.764 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)      236.80006    7.16981  33.027   <2e-16 ***
mjetet_shkollore   0.09065    0.03790   2.391    0.017 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 86.74 on 998 degrees of freedom
Multiple R-squared:  0.005698,  Adjusted R-squared:  0.004702 
F-statistic: 5.719 on 1 and 998 DF,  p-value: 0.01696

Interpretimi i rezultateve te modelit:

1. \(Interpretimi\) \(i\) \(mbetjeve\): mbetjet paraqesin diferencat midis vlerave te vezhguara te ndryshores se varur \(ushqimi\) dhe vlerave te parashikuara nga modeli. Rangu i mbetjeve te modelit sugjeron qe modeli nuk i pershtatet ne menyre te persosur te dhenave. Mbetja minimale eshte -160.913, Kuartili i pare eshte -77.172, mesatarja eshte 3.852, Q3 eshte 74.67 dhe vlera e mbetur 155.764 eshte mbetja maksimale.

2. \(Intercept\) \((nderprerja)\) 236.80006 paraqet vleren e parashikuar te ndryshores se varur \(ushqimi\) kur ndryshorja e pavarur \(mjetet\) \(shkollore\) eshte 0. Koeficienti per variablin e pavarur eshte 0.09065. Kjo do te thote qe per cdo rritje prej 1 njesi ne variablin e pavarur, ndryshorja e varur parashikohet te rritet me 0.09065 njesi, duke mbajtur te gjithe variablat e tjere konstante.

3. \(P-value\): vlera \(p\) per variablin e pavarur eshte 0.01696, e cila eshte me e vogel se niveli i rendesise 0.05. Kjo tregon se lidhja midis variablit te pavarur dhe ndryshores se varur eshte statistikisht e rendesishme, qe do te thote se ndryshorja e pavarur ka nje efekt te rendesishem ne variablin e varur.

4. \(Vlera\) \(R^2\) eshte 0.005698, qe do te thote se ndryshorja e pavarur shpjegon rreth 0.57% te variances ne variablin e varur.

Ne menyre te permbledhur rezultatet sugjerojne se variabli i pavarur \(mjetet\) \(shkollore\) ka nje efekt statistikisht domethenes por relativisht te vogel ne variablin e varur \(ushqimi\).

Duke qene se modeli yne ka 3 yje, aq me shume te rendesishme jane rezultatet e modelit te ndertuar.

Nese bejme plot te modelit qe kemi krijuar ate do te marrim 4 grafike:

1.Residuals vs Fitted;

2.Normal Q-Q;

3.Fitted vs sqrt (standardized residuals);

4.Leverage vs standardized residuals;

\[Scale\ Location\ Plot\]

model <- lm(ushqimi~mjetet_shkollore, data = data)

plot(model)

NA

\[Residuals\ vs\ Fitted\ Plot\] Grafiku i pare na tregon qe nuk kemi nje varesi lineare ndermjet te dhenave tona. Pra nuk jemi ne homoskedasticitet.

\[Q-Q\ Plot\] Nje menyre tjeter paraqitje per te dhenat tona eshte dhe grafiku Normal Q-Q. Ky lloj grafiku perdoret per te percaktuar nese nje grup te dhenash jane apo jo te shperndara normalisht. Nese ato jane, atehere te gjitha pikat e tij duhet te shtrihen ne nje vije te drejte diagonale. Ne rastin tone te dhenat nuk perputhen shume mire me shperndarjen normale, sepse nje pjese e konsiderueshme e pikave nuk shtrihen mbi drejtez. Kjo do te thote se shpenzimet minimale per ushqim nuk jane mjaftueshem te ulta sa duhen per tu perputhur me drejtezen dhe shpenzimet max nuk jane mjaftueshem te larta sa te shtrihen mbi drejtez. Kjo tregon se bishtat e shperndarjes jane shume “te dobet” ne krahasim me shperndarjen.

\[Scale\ Location\ Plot\]

Grafiku Scale-Location eshte i njejte me grafikun e pare, por me ndryshimin qe ne boshtin vertikal kemi mbetjet e standartizuara. Shikohet dhe ketu lidhja ndermjet mbetjeve te standartizuara dhe vlerave te pershtatura dhe shikohet homoskedasticiteti. Ne rastin tone po te shikohet vija e kuqe ajo eshte thuajse horizontale pra nuk ka ndonje lidhje mes vlerave te perafruara dhe mbetjeve te standartizuara.

\[Residuals\ vs.\ Leverage\ Plot\]

Grafiku Residuals vs. Leverage na lejon te shikojme nese ka vezhgime qe ndikojme ne modelin e regresit qe kemi ndertuar. E thene ndryshe, shikojme nese ka vezhgime qe po te mos merren ne konsiderate ndryshojne modelin tone.


y_i_perafruar <- fitted.values(model1)
View(y_i_perafruar)


y_i_parashikuar <- predict(model1, newdata = data, interval='confidence')
head(y_i_parashikuar, 500)
         fit      lwr      upr
1   253.8421 248.3698 259.3144
2   259.6437 251.7707 267.5166
3   245.7743 237.9812 253.5674
4   257.0148 250.5456 263.4840
5   254.3860 248.8161 259.9559
6   248.6751 242.3845 254.9657
7   256.1083 250.0201 262.1965
8   259.5530 251.7341 267.3719
9   250.8507 245.2707 256.4307
10  247.9499 241.3318 254.5680
11  253.3889 247.9711 258.8066
12  257.4681 250.7854 264.1507
13  248.2219 241.7310 254.7127
14  261.6379 252.5020 270.7738
15  245.1398 236.9623 253.3173
16  252.6637 247.2807 258.0466
17  249.5816 243.6417 255.5215
18  253.8421 248.3698 259.3144
19  241.4232 230.7592 252.0871
20  256.3803 250.1847 262.5759
21  242.8736 233.2183 252.5289
22  262.3631 252.7400 271.9862
23  263.4509 253.0759 273.8259
24  249.7629 243.8843 255.6414
25  243.6894 234.5822 252.7966
26  255.9270 249.9069 261.9472
27  262.9070 252.9109 272.9032
28  260.3688 252.0517 268.6860
29  249.5816 243.6417 255.5215
30  245.4117 237.4008 253.4226
31  249.2190 243.1473 255.2907
32  248.9470 242.7690 255.1251
33  250.1255 244.3601 255.8909
34  258.9185 251.4686 266.3683
35  245.7743 237.9812 253.5674
36  255.2925 249.4868 261.0982
37  262.3631 252.7400 271.9862
38  253.6608 248.2133 259.1083
39  259.3717 251.6601 267.0833
40  242.8736 233.2183 252.5289
41  250.4881 244.8224 256.1537
42  250.6694 245.0484 256.2904
43  259.3717 251.6601 267.0833
44  260.7314 252.1853 269.2776
45  257.6494 250.8775 264.4213
46  253.3889 247.9711 258.8066
47  253.5702 248.1336 259.0067
48  244.7772 236.3734 253.1810
49  246.3182 238.8415 253.7950
50  254.7486 249.0949 260.4023
51  253.7515 248.2921 259.2108
52  248.4032 241.9943 254.8120
53  243.5987 234.4314 252.7660
54  243.2361 233.8264 252.6459
55  250.0348 244.2424 255.8273
56  258.2839 251.1840 265.3838
57  248.8564 242.6415 255.0713
58  263.9042 253.2095 274.5988
59  256.8335 250.4456 263.2214
60  254.9299 249.2290 260.6308
61  250.3068 244.5930 256.0206
62  249.5816 243.6417 255.5215
63  258.6465 251.3491 265.9439
64  243.7800 234.7327 252.8274
65  254.0234 248.5224 259.5244
66  260.0969 251.9486 268.2452
67  249.4003 243.3960 255.4046
68  262.8164 252.8828 272.7499
69  252.3011 246.9109 257.6913
70  246.6808 239.4074 253.9542
71  258.5559 251.3085 265.8032
72  257.4681 250.7854 264.1507
73  245.0491 236.8155 253.2828
74  246.4089 238.9836 253.8342
75  258.1933 251.1417 265.2449
76  246.3182 238.8415 253.7950
77  260.2782 252.0176 268.5388
78  242.3297 232.3008 252.3585
79  250.2161 244.4769 255.9553
80  254.8392 249.1624 260.5161
81  241.7858 231.3776 252.1940
82  254.2954 248.7441 259.8466
83  246.6808 239.4074 253.9542
84  243.5987 234.4314 252.7660
85  252.5730 247.1898 257.9563
86  250.9413 245.3804 256.5022
87  253.1169 247.7199 258.5139
88  247.7686 241.0629 254.4744
89  260.7314 252.1853 269.2776
90  241.4232 230.7592 252.0871
91  258.3746 251.2260 265.5232
92  261.0940 252.3148 269.8733
93  242.6016 232.7603 252.4429
94  242.5110 232.6073 252.4146
95  244.5052 235.9289 253.0816
96  245.4117 237.4008 253.4226
97  244.1426 235.3327 252.9526
98  247.2247 240.2436 254.2058
99  246.4089 238.9836 253.8342
100 250.0348 244.2424 255.8273
101 256.6522 250.3432 262.9613
102 247.3154 240.3814 254.2493
103 243.7800 234.7327 252.8274
104 259.5530 251.7341 267.3719
105 244.1426 235.3327 252.9526
106 256.7429 250.3947 263.0910
107 255.0205 249.2947 260.7464
108 261.8192 252.5627 271.0758
109 243.2361 233.8264 252.6459
110 249.4909 243.5192 255.4627
111 247.1341 240.1054 254.1627
112 244.7772 236.3734 253.1810
113 242.5110 232.6073 252.4146
114 261.9099 252.5928 271.2270
115 250.6694 245.0484 256.2904
116 253.2982 247.8884 258.7080
117 245.5930 237.6917 253.4944
118 255.6551 249.7315 261.5787
119 242.5110 232.6073 252.4146
120 242.5110 232.6073 252.4146
121 260.0969 251.9486 268.2452
122 253.3889 247.9711 258.8066
123 253.7515 248.2921 259.2108
124 258.8278 251.4292 266.2264
125 251.1226 245.5972 256.6481
126 248.1312 241.5985 254.6639
127 254.2954 248.7441 259.8466
128 247.6780 240.9276 254.4283
129 261.7286 252.5325 270.9247
130 246.1369 238.5562 253.7177
131 248.2219 241.7310 254.7127
132 246.7715 239.5479 253.9951
133 261.4566 252.4405 270.4728
134 262.5444 252.7977 272.2912
135 257.3774 250.7386 264.0163
136 249.4003 243.3960 255.4046
137 251.7572 246.3255 257.1889
138 253.3889 247.9711 258.8066
139 243.8707 234.8831 252.8583
140 254.6579 249.0266 260.2893
141 245.4117 237.4008 253.4226
142 262.0005 252.6226 271.3785
143 248.8564 242.6415 255.0713
144 258.1026 251.0988 265.1064
145 247.4060 240.5187 254.2933
146 248.2219 241.7310 254.7127
147 241.5138 230.9140 252.1136
148 254.9299 249.2290 260.6308
149 263.0883 252.9665 273.2101
150 257.1961 250.6432 263.7490
151 256.1083 250.0201 262.1965
152 256.1990 250.0757 262.3223
153 245.4117 237.4008 253.4226
154 247.4967 240.6555 254.3378
155 257.5587 250.8317 264.2857
156 261.9099 252.5928 271.2270
157 250.6694 245.0484 256.2904
158 263.7229 253.1565 274.2893
159 246.8621 239.6879 254.0363
160 244.0520 235.1830 252.9209
161 254.8392 249.1624 260.5161
162 242.7829 233.0658 252.5000
163 241.6045 231.0687 252.1403
164 244.8678 236.5210 253.2146
165 245.6837 237.8366 253.5307
166 252.5730 247.1898 257.9563
167 246.9528 239.8275 254.0780
168 253.7515 248.2921 259.2108
169 262.6351 252.8262 272.4439
170 258.6465 251.3491 265.9439
171 262.0005 252.6226 271.3785
172 260.2782 252.0176 268.5388
173 261.0034 252.2828 269.7240
174 263.9948 253.2358 274.7538
175 244.5959 236.0773 253.1145
176 249.0377 242.8958 255.1796
177 241.8764 231.5318 252.2210
178 244.9585 236.6684 253.2486
179 246.6808 239.4074 253.9542
180 252.1198 246.7198 257.5197
181 242.9642 233.3706 252.5578
182 256.6522 250.3432 262.9613
183 260.7314 252.1853 269.2776
184 251.2133 245.7042 256.7224
185 262.9977 252.9388 273.0566
186 243.3268 233.9779 252.6756
187 254.8392 249.1624 260.5161
188 258.5559 251.3085 265.8032
189 250.0348 244.2424 255.8273
190 254.5673 248.9573 260.1773
191 246.1369 238.5562 253.7177
192 248.4938 242.1250 254.8626
193 249.1283 243.0219 255.2348
194 257.5587 250.8317 264.2857
195 255.0205 249.2947 260.7464
196 251.1226 245.5972 256.6481
197 256.9242 250.4959 263.3524
198 253.5702 248.1336 259.0067
199 250.4881 244.8224 256.1537
200 250.1255 244.3601 255.8909
201 255.6551 249.7315 261.5787
202 254.5673 248.9573 260.1773
203 242.4203 232.4541 252.3865
204 254.8392 249.1624 260.5161
205 263.2696 253.0215 273.5177
206 262.8164 252.8828 272.7499
207 251.3039 245.8102 256.7977
208 263.6322 253.1298 274.1347
209 247.0434 239.9667 254.1202
210 247.0434 239.9667 254.1202
211 261.8192 252.5627 271.0758
212 244.5959 236.0773 253.1145
213 243.1455 233.6746 252.6164
214 242.0577 231.8398 252.2756
215 243.9613 235.0332 252.8895
216 243.2361 233.8264 252.6459
217 248.1312 241.5985 254.6639
218 262.9070 252.9109 272.9032
219 251.2133 245.7042 256.7224
220 262.5444 252.7977 272.2912
221 247.3154 240.3814 254.2493
222 242.3297 232.3008 252.3585
223 244.8678 236.5210 253.2146
224 257.5587 250.8317 264.2857
225 261.3660 252.4094 270.3226
226 247.7686 241.0629 254.4744
227 246.9528 239.8275 254.0780
228 254.5673 248.9573 260.1773
229 249.0377 242.8958 255.1796
230 242.0577 231.8398 252.2756
231 257.2868 250.6912 263.8824
232 243.0549 233.5227 252.5870
233 258.2839 251.1840 265.3838
234 256.0177 249.9639 262.0715
235 256.9242 250.4959 263.3524
236 243.5081 234.2805 252.7357
237 256.4709 250.2382 262.7037
238 248.2219 241.7310 254.7127
239 254.7486 249.0949 260.4023
240 254.7486 249.0949 260.4023
241 243.9613 235.0332 252.8895
242 250.5787 244.9358 256.2216
243 246.0463 238.4130 253.6796
244 260.9127 252.2505 269.5749
245 247.6780 240.9276 254.4283
246 245.4117 237.4008 253.4226
247 248.8564 242.6415 255.0713
248 252.9356 247.5473 258.3239
249 258.8278 251.4292 266.2264
250 247.0434 239.9667 254.1202
251 256.6522 250.3432 262.9613
252 248.1312 241.5985 254.6639
253 242.6016 232.7603 252.4429
254 247.8593 241.1976 254.5209
255 261.0034 252.2828 269.7240
256 258.8278 251.4292 266.2264
257 257.7400 250.9228 264.5573
258 252.8450 247.4595 258.2305
259 245.5024 237.5464 253.4583
260 260.0063 251.9136 268.0989
261 255.6551 249.7315 261.5787
262 262.8164 252.8828 272.7499
263 254.6579 249.0266 260.2893
264 261.0034 252.2828 269.7240
265 261.3660 252.4094 270.3226
266 263.2696 253.0215 273.5177
267 250.9413 245.3804 256.5022
268 263.8135 253.1831 274.4440
269 244.8678 236.5210 253.2146
270 255.9270 249.9069 261.9472
271 242.0577 231.8398 252.2756
272 241.6045 231.0687 252.1403
273 244.4146 235.7802 253.0490
274 255.1112 249.3596 260.8628
275 245.1398 236.9623 253.3173
276 245.2304 237.1087 253.3521
277 254.1141 248.5973 259.6308
278 252.6637 247.2807 258.0466
279 252.2104 246.8158 257.6050
280 244.7772 236.3734 253.1810
281 260.9127 252.2505 269.5749
282 258.0120 251.0555 264.9684
283 248.9470 242.7690 255.1251
284 243.9613 235.0332 252.8895
285 262.1818 252.6817 271.6820
286 247.8593 241.1976 254.5209
287 256.1990 250.0757 262.3223
288 245.5930 237.6917 253.4944
289 257.6494 250.8775 264.4213
290 253.6608 248.2133 259.1083
291 256.2896 250.1305 262.4487
292 242.5110 232.6073 252.4146
293 249.5816 243.6417 255.5215
294 251.8478 246.4256 257.2701
295 252.3011 246.9109 257.6913
296 243.4174 234.1293 252.7056
297 248.8564 242.6415 255.0713
298 255.2925 249.4868 261.0982
299 260.8221 252.2180 269.4261
300 252.4824 247.0978 257.8669
301 250.5787 244.9358 256.2216
302 246.3182 238.8415 253.7950
303 256.1083 250.0201 262.1965
304 256.1990 250.0757 262.3223
305 247.5873 240.7918 254.3828
306 247.4060 240.5187 254.2933
307 256.1083 250.0201 262.1965
308 262.9070 252.9109 272.9032
309 245.5024 237.5464 253.4583
310 246.5902 239.2665 253.9138
311 245.6837 237.8366 253.5307
312 262.0005 252.6226 271.3785
313 250.1255 244.3601 255.8909
314 256.9242 250.4959 263.3524
315 254.2047 248.6711 259.7383
316 259.0998 251.5463 266.6532
317 247.1341 240.1054 254.1627
318 243.2361 233.8264 252.6459
319 244.5959 236.0773 253.1145
320 252.4824 247.0978 257.8669
321 241.6045 231.0687 252.1403
322 256.5616 250.2910 262.8322
323 258.2839 251.1840 265.3838
324 256.7429 250.3947 263.0910
325 243.1455 233.6746 252.6164
326 261.4566 252.4405 270.4728
327 258.2839 251.1840 265.3838
328 260.6408 252.1523 269.1293
329 243.6894 234.5822 252.7966
330 254.7486 249.0949 260.4023
331 247.4060 240.5187 254.2933
332 242.5110 232.6073 252.4146
333 247.1341 240.1054 254.1627
 [ reached getOption("max.print") -- omitted 167 rows ]

Ky kod na sherben per te identifikuar vlerat e parashikuara. Do te na hapet nje dritare e re e cila ne nje tabele do te kete te afishuara te gjitha vlerat e parashikuara.

Le te ndertojme nje grafik per vlerat tona te parashikuara:

plot(y_i_parashikuar)

Nisur nga grafiku i ndertuar me siper, shperndarja e vlerave ne ate grafik ngjason me nje shperndarje logaritmike. Mund te themi se me rritjen e vlerave ne boshtin ‘fit’ nuk kemi nje rritje lineare te vlerave ne boshtin ‘lwr’. Pra vlerat y nuk rriten ne menyre te drejteperdrejte me ato ne boshtin horizontal.

\[Paired\ Plots\]

Libraria \(GGally\) na ofron nje opsion te ngjashem me \(ggplot\): ate te quajtur \(ggpairs\). Nga fjala pairs menjehere nenkuptojme cifte, pra cifte ose grupime grafikesh.

Me poshte kemi ndertuar nje paired plot per 9 variabla te datasetit tone.

library(GGally)
Warning: package ‘GGally’ was built under R version 4.3.3
Registered S3 method overwritten by 'GGally':
  method from   
  +.gg   ggplot2
ggpairs(data[, c(1, 2, 3, 4, 5, 6, 7, 8, 9)], ggplot2::aes(color="red"))

 plot: [1, 1] [>--------------------------------------------------------------------------------------------------]  1% est: 0s 
 plot: [1, 2] [=>-------------------------------------------------------------------------------------------------]  2% est: 9s 
 plot: [1, 3] [===>-----------------------------------------------------------------------------------------------]  4% est:15s 
 plot: [1, 4] [====>----------------------------------------------------------------------------------------------]  5% est:17s 
 plot: [1, 5] [=====>---------------------------------------------------------------------------------------------]  6% est:16s 
 plot: [1, 6] [======>--------------------------------------------------------------------------------------------]  7% est:15s 
 plot: [1, 7] [========>------------------------------------------------------------------------------------------]  9% est:15s 
 plot: [1, 8] [=========>-----------------------------------------------------------------------------------------] 10% est:14s 
 plot: [1, 9] [==========>----------------------------------------------------------------------------------------] 11% est:14s 
 plot: [2, 1] [===========>---------------------------------------------------------------------------------------] 12% est:14s 
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

 plot: [2, 2] [============>--------------------------------------------------------------------------------------] 14% est:16s 
 plot: [2, 3] [==============>------------------------------------------------------------------------------------] 15% est:16s 
 plot: [2, 4] [===============>-----------------------------------------------------------------------------------] 16% est:15s 
 plot: [2, 5] [================>----------------------------------------------------------------------------------] 17% est:16s 
 plot: [2, 6] [=================>---------------------------------------------------------------------------------] 19% est:16s 
 plot: [2, 7] [===================>-------------------------------------------------------------------------------] 20% est:16s 
 plot: [2, 8] [====================>------------------------------------------------------------------------------] 21% est:15s 
 plot: [2, 9] [=====================>-----------------------------------------------------------------------------] 22% est:15s 
 plot: [3, 1] [======================>----------------------------------------------------------------------------] 23% est:15s 
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

 plot: [3, 2] [=======================>---------------------------------------------------------------------------] 25% est:15s 
 plot: [3, 3] [=========================>-------------------------------------------------------------------------] 26% est:15s 
 plot: [3, 4] [==========================>------------------------------------------------------------------------] 27% est:15s 
 plot: [3, 5] [===========================>-----------------------------------------------------------------------] 28% est:14s 
 plot: [3, 6] [============================>----------------------------------------------------------------------] 30% est:14s 
 plot: [3, 7] [==============================>--------------------------------------------------------------------] 31% est:14s 
 plot: [3, 8] [===============================>-------------------------------------------------------------------] 32% est:13s 
 plot: [3, 9] [================================>------------------------------------------------------------------] 33% est:13s 
 plot: [4, 1] [=================================>-----------------------------------------------------------------] 35% est:13s 
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

 plot: [4, 2] [==================================>----------------------------------------------------------------] 36% est:14s 
 plot: [4, 3] [====================================>--------------------------------------------------------------] 37% est:14s 
 plot: [4, 4] [=====================================>-------------------------------------------------------------] 38% est:14s 
 plot: [4, 5] [======================================>------------------------------------------------------------] 40% est:14s 
 plot: [4, 6] [=======================================>-----------------------------------------------------------] 41% est:14s 
 plot: [4, 7] [=========================================>---------------------------------------------------------] 42% est:13s 
 plot: [4, 8] [==========================================>--------------------------------------------------------] 43% est:13s 
 plot: [4, 9] [===========================================>-------------------------------------------------------] 44% est:13s 
 plot: [5, 1] [============================================>------------------------------------------------------] 46% est:13s 
 plot: [5, 2] [=============================================>-----------------------------------------------------] 47% est:12s 
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

 plot: [5, 3] [===============================================>---------------------------------------------------] 48% est:12s 
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

 plot: [5, 4] [================================================>--------------------------------------------------] 49% est:13s 
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

 plot: [5, 5] [=================================================>-------------------------------------------------] 51% est:13s 
 plot: [5, 6] [==================================================>------------------------------------------------] 52% est:12s 
 plot: [5, 7] [====================================================>----------------------------------------------] 53% est:12s 
 plot: [5, 8] [=====================================================>---------------------------------------------] 54% est:12s 
 plot: [5, 9] [======================================================>--------------------------------------------] 56% est:11s 
 plot: [6, 1] [=======================================================>-------------------------------------------] 57% est:11s 
 plot: [6, 2] [========================================================>------------------------------------------] 58% est:10s 
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

 plot: [6, 3] [==========================================================>----------------------------------------] 59% est:10s 
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

 plot: [6, 4] [===========================================================>---------------------------------------] 60% est:10s 
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

 plot: [6, 5] [============================================================>--------------------------------------] 62% est:10s 
 plot: [6, 6] [=============================================================>-------------------------------------] 63% est:10s 
 plot: [6, 7] [===============================================================>-----------------------------------] 64% est: 9s 
 plot: [6, 8] [================================================================>----------------------------------] 65% est: 9s 
 plot: [6, 9] [=================================================================>---------------------------------] 67% est: 8s 
 plot: [7, 1] [==================================================================>--------------------------------] 68% est: 8s 
 plot: [7, 2] [===================================================================>-------------------------------] 69% est: 8s 
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

 plot: [7, 3] [=====================================================================>-----------------------------] 70% est: 8s 
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

 plot: [7, 4] [======================================================================>----------------------------] 72% est: 7s 
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

 plot: [7, 5] [=======================================================================>---------------------------] 73% est: 7s 
 plot: [7, 6] [========================================================================>--------------------------] 74% est: 7s 
 plot: [7, 7] [==========================================================================>------------------------] 75% est: 6s 
 plot: [7, 8] [===========================================================================>-----------------------] 77% est: 6s 
 plot: [7, 9] [============================================================================>----------------------] 78% est: 6s 
 plot: [8, 1] [=============================================================================>---------------------] 79% est: 5s 
 plot: [8, 2] [==============================================================================>--------------------] 80% est: 5s 
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

 plot: [8, 3] [================================================================================>------------------] 81% est: 5s 
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

 plot: [8, 4] [=================================================================================>-----------------] 83% est: 4s 
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

 plot: [8, 5] [==================================================================================>----------------] 84% est: 4s 
 plot: [8, 6] [===================================================================================>---------------] 85% est: 4s 
 plot: [8, 7] [=====================================================================================>-------------] 86% est: 3s 
 plot: [8, 8] [======================================================================================>------------] 88% est: 3s 
 plot: [8, 9] [=======================================================================================>-----------] 89% est: 3s 
 plot: [9, 1] [========================================================================================>----------] 90% est: 2s 
 plot: [9, 2] [=========================================================================================>---------] 91% est: 2s 
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

 plot: [9, 3] [===========================================================================================>-------] 93% est: 2s 
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

 plot: [9, 4] [============================================================================================>------] 94% est: 1s 
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

 plot: [9, 5] [=============================================================================================>-----] 95% est: 1s 
 plot: [9, 6] [==============================================================================================>----] 96% est: 1s 
 plot: [9, 7] [================================================================================================>--] 98% est: 1s 
 plot: [9, 8] [=================================================================================================>-] 99% est: 0s 
 plot: [9, 9] [===================================================================================================]100% est: 0s 
                                                                                                                                

Ne grafik verejme pjeset perberese te tij. Ai perbehet nga grafike densiteti, box plote, histograma, dhe gjithashtu koeficiente korrelacioni te cilet na tregojne varesine midis ndryshoreve cilesore. Pra me ane te ketij grafiku ne marrim ne nje fare menyre nje permbledhje te gjithe vizualizimit te kryer.

Cfare tregojne vlerat ne perqindje?

\(plot: [2, 1] [===========>---------------]\) 12% tregon qe ne nje moment te kohes (gjate ekzekutimit te kodit) eshte duke u krijuar grafiku i pozicionuar ne (2,1) ne matrice dhe perben 12% te saj.

\(stat\)_\(bin()\) \(using\) \(bins = 30\) do te thote se funksioni \(stat\)_\(bin\) po perdor 30 pika per histogramet dhe tenton te zgjedhi nje vlere sa me te mire \(binwidth\) per te permiresuar paraqitjen e tyre.

Ne menyre te ngjashme arsyetojme per cdo element tjeter te afishuar.

Perfundime dhe Referenca

\[Perfundime\]

Ashtu sic e kemi cituar ne hyrje te projektit, \(Student\) \(Spending\) \(Dataset\) ishte nje zgjedhje e jona per te studiuar dhe analizuar nje fenomen (nese do te quhet i tille) i cili na karakterizon te gjitheve ne si studente ne jeten tone te perditshme studentore. Pra per te analizuar shpenzimet e nje grupi studentesh me ane te metodave pergjithesisht te njohura statistikore, ku ne ndihme na vjen gjuha R dhe mjedisi i saj i zhvillimit \(RStudio\).

Duke qene projekti i pare i mirefillte per ne, gjate gjithe kohes jemi perpjekur qe te tregohemi te sakte dhe te qarte ne strukturimin, analizimin dhe interpretimin e te dhenave tona. Jemi perpjekur tu kushtojme rendesi dhe vemendje te gjitha elementeve statistikore, madhesive te njohura, koncepteve.

Mbyllja e ketij projekti sigurisht qe do te perfshije ato cka ne kishim si objektiv: nje permbledhje te strukturuar te gjithe rezultateve te nxjerra nga cdo llogaritje statistikore e kryer mbi dataset.

Ne perfundim te analizimit te datasetit \(Student\) \(Spending\) arritem ne keto rezultate te rendesishme:

Mosha mesatare e studenteve te zgjedhur eshte 21 vjec, ndersa gjinia dominuese eshte ajo mashkullore.

Te ardhurat mujore mesatare te nje studenti rezultojne $1020.65.

Nga rezultatet e nxjerra arritem ne perfundimin se studentet shpenzonin me shume per shkollim, ndjekur nga strehimi dhe ushqimi.

Sipas gjinise me shume shpenzime benin meshkujt ne kategorite shkollim ,strehim , ushqim dhe teknologji ,ndersa vajzat shpenzonin me shume ne kategorite e tjera si: transport, mjete shkollore, argetim, kujdes personal, mireqenie shendetesore dhe te ndryshme.

Sipas vitit te studimit per shkollim me teper shpenzonin studentet \(Junior\) ndjekur nga \(Sophomore\), \(Freshman\) dhe me pak \(Senior\).

Per strehim me shume shpenzonin \(Senior\) dhe me pak \(Sophomore\).

Per ushqim dhe kujdes personal me shume shpenzojne \(Seniors\), ndersa me pak \(Junior\).

Per transport, mjete shkollore, argetim, teknologji me shume shpenzojne \(Freshman\), ndersa me pak \(Junior\).

Sipas deges se diplomuar me shume per shkollim shpenzojne studentet e psikologjise dhe me pak ata te inxhiniersie.

Per strehim me shume shpenzojne ata te shkencave kompjuterike dhe me pak te ekonomikut.

Per ushqim me shume shpenzojne studentet e ekonomikut, ndersa me pak ata per shkenca kompjuterike.

Per transport me shume shpenzojne studentet e psikologjise, ndersa me pak ata te inxhinierise.

Per mjete shkollore, argetim, teknologji, mireqenie shendetesore shpenzojne me shume studentet e biologjise.

Per varesine midis ndyshoreve te datasetit nga matrica e korrelacionit dhe testeve Hi-katror dolem ne perfundim qe ndryshoret jane te pavarura me njera-tjetren.

Nga kjo pavaresi edhe modelet e testeve parashikuese rezultuan me nje marzh shpjegimi shume te ulet.

\[Referenca\]

Ne analizen e te dhenave gjate punes se pavarur shpesh jemi ndeshur ne situata per te cilat kishim nevoje per nje shpjegim dhe orientim. Per kete arsye i jemi referuar tekstit te statistikes, por edhe faqeve si \(google.com\), platformave si \(wikipedia.com\), \(geekforgeeks.com\), \(youtube.com\) etj.. Me poshte listohen disa nga sitet ne te cilat perfituam nje sasi informacioni:

Credits to: \(Hyrje\) \(ne\) \(Statistiken\) \(e\) \(Zbatuar\) \(3\) nga \(Prof.\) \(Dr.\) \(Llukan\) \(Puka\);

Link to dataset: https://www.kaggle.com/datasets/sumanthnimmagadda/student-spending-dataset/data

https://posit.co/download/rstudio-desktop/

https://www.khanacademy.org/math/statistics-probability/summarizing-quantitative-data/mean-median-basics/a/mean-median-and-mode-review

https://search.yahoo.com/search?fr2=p%3ads%2cv%3aomn%2cm%3asa%2cbrws%3achrome%2cpos%3a4&fr=mcafee&type=E210US91215G0&p=degrees+of+freedom+formula

https://search.yahoo.com/search;_ylt=AwrFaE1RmD9mZQQA8lVXNyoA;_ylc=X1MDMjc2NjY3OQRfcgMyBGZyA21jYWZlZQRmcjIDc2ItdG9wBGdwcmlkA0FaSlRvNUJVVDNxTXZuVks0VHlHaUEEbl9yc2x0AzAEbl9zdWdnAzEEb3JpZ2luA3NlYXJjaC55YWhvby5jb20EcG9zAzAEcHFzdHIDBHBxc3RybAMwBHFzdHJsAzI1BHF1ZXJ5A3RhYmxlJTIwb2YlMjBjb250aW5nZW5jeSUyMGluJTIwUgR0X3N0bXADMTcxNTQ0Mzc5OQ--?p=table+of+contingency+in+R&fr=mcafee&type=E210US91215G0&fr2=sb-top&iscqry=

https://search.yahoo.com/search?fr=mcafee&type=E210US91215G0&p=imi+fshn

Chi-squared Test: https://search.yahoo.com/search?fr2=p%3ads%2cv%3aomn%2cm%3asa%2cbrws%3achrome%2cpos%3a1&fr=mcafee&type=E210US91215G0&p=chi-square+test

http://www.sthda.com/english/articles/32-r-graphics-essentials/133-plot-one-variable-frequency-graph-density-distribution-and-more/

Mosaic Plot: https://search.yahoo.com/search?fr=mcafee&type=E210US91215G0&p=mosaic+plot

Word Cloud in R: https://www.marsja.se/how-to-create-a-word-cloud-in-r/#google_vignette

Visualization using \(ggplot2\): https://www.dataquest.io/blog/data-visualization-in-r-with-ggplot2-a-beginner-tutorial/

Residuals vs Leverage Plot: https://images.search.yahoo.com/search/images;_ylt=AwrEq4z_UlRmRAQAoeJXNyoA;_ylu=Y29sbwNiZjEEcG9zAzEEdnRpZAMEc2VjA3BpdnM-?p=residuals+vs+leverage+plot+in+r&fr2=piv-web&type=E210US91215G0&fr=mcafee

How to interpret a Scale-Location Plot: https://www.statology.org/scale-location-plot/

Predicted y values: https://search.yahoo.com/search?fr=mcafee&type=E210US91215G0&p=predicted+value+of+y+in+plots

R installation & more: https://youtu.be/FIrsOBy5k58?si=fDkTBu06nhf8UA0A

https://youtu.be/2_tW7e4e_dM?si=-sRLFJpb7hPEGoTf

https://youtu.be/YrEe2TLr3MI?si=fLCYGjaiW6VH6ZRg

https://youtu.be/48b4BzxHHH8?si=LOR1OgqnS-fAiAiL

https://youtu.be/Uo1C7Iligw0?si=5Eg3vqXA1aisYarv

https://youtu.be/ePD96i0YHII?si=zHZdVeTEwm6rMjzw

https://youtu.be/svgEpRzhG7M?si=n1IEDUfyOIgy9DT3

Link to esquisser: esquisse::esquisser(data, viewer = “browser”)

\[Word\ Cloud\]

library(wordcloud)
Warning: package ‘wordcloud’ was built under R version 4.3.3
Loading required package: RColorBrewer
library(wordcloud2)
Warning: package ‘wordcloud2’ was built under R version 4.3.3
library(RColorBrewer)

fjalet <- c("Jakup","Jakup","Jakup","Jakup","Jakup","Jakup","Jakup","Jakup","Jakup","Jakup","Jakup", "Adisa", "Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa",
"Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Data","Data","Data","Data","Data","Data","Data","Data","Data","Data","Data","Data","Data", "Science","Science","Science","Science","Science","Science","Science","Science","Engineer","Engineer","Engineer","Engineer","Engineer","Engineer","Engineer", "FSHN","FSHN","FSHN","FSHN","FSHN","FSHN","FSHN","FSHN","FSHN","FSHN","IMI","IMI","IMI","IMI","IMI","IMI","IMI","IMI","IMI","IMI","IMI","IMI","IMI","IMI","IMI","IMI","IMI", "2024","2024","2024","2024","2024","2024","2024","2024","2024","2024","Jakup","Jakup","Jakup","Jakup","Jakup","Jakup","Jakup","Jakup","Jakup","Jakup","Jakup", "Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Adisa","Data","Data","Data","Data","Data","Data","Data","Data","Data","Data","Data","Data","Data", "Science","Science","Science","Science","Science","Science","Science","Science","Engineer","Engineer","Engineer","Engineer","Engineer","Engineer","Engineer", "FSHN","FSHN","FSHN","FSHN","FSHN","FSHN","FSHN","FSHN","FSHN","FSHN","IMI","IMI","IMI","IMI","IMI","IMI","IMI","IMI","IMI","IMI","IMI","IMI","IMI","IMI","IMI","IMI","IMI", "2024","2024","2024","2024","2024","2024","2024","2024","2024","2024")

frekuencat <- rep(frekuencat, length.out = length(fjalet))
data <- data.frame(word = fjalet, freq = frekuencat)

wordcloud2(data = data, size = 0.1, shape='random', color='random-dark')

\["Do\ not\ trust\ any\ statistics\ you\ did\ not\ fake\ yourself.\ Facts\ are\ stubborn,\ but\ statistics\ are\ more\ pliable."\\ :)\]

LS0tDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCmRmX3ByaW50OiBwYWdlZA0KLS0tDQoNCiMjICB7LnRhYnNldH0NCg0KIyMjIyAkJEJBQ0hFTE9SXCBORVwgSU5YSElOSUVSSVwgTUFURU1BVElLRVwgREhFXCBJTkZPUk1BVElLRSQkDQoNCiMjIyMgJCREQVRBXCBBTkFMWVNJU1wgTkVcIFJTVFVESU8kJA0KDQojIyMjICQkUmVhbGl6dWFyXCBuZ2FcIEpha3VwXCBZbWVyYWpcIGRoZVwgQWRpc2FcIEhveGhhaiQkDQoNCiQkRmFrdWx0ZXRpXCBpXCBTaGtlbmNhdmVcIHRlXCBOYXR5cmVzXFwgUWVyc2hvclwgMjAyNCQkDQoNCiMjIyAqKmByIGNvbG9yaXplICgiUHJlemFudGltaSBtZSBSU3R1ZGlvIiwgImJsdWUiKWAqKg0KJCRSU3R1ZGlvJCQNCg0KKipDZmFyZVwgZXNodGVcIFJTdHVkaW8/KioNCg0KKipSIGVzaHRlIG5qZSBnanVoZSBwcm9ncmFtaW1pIGUgc3BlY2lhbGl6dWFyIG5lIGxsb2dhcml0amUgc3RhdGlzdGlrb3JlIGRoZSB2aXp1YWxpemltaW4gZSB0ZSBkaGVuYXZlLCBlIG1pcmF0dWFyIG5nYSBmdXNoYXQgZSBueGplcnJqZXMgc2UgdGUgZGhlbmF2ZSwgYmlvaW5mb3JtYXRpa2VzIGRoZSBhbmFsaXplcyBzZSB0ZSBkaGVuYXZlLioqDQoNCioqJFJTdHVkaW8kIGVzaHRlIG5qZSBtamVkaXMgemh2aWxsaW1pIGkgaW50ZWdydWFyIHBlciBnanVoZW4gJFIkKioNCg0KKipLam8gcGxhdGZvcm1lIGVzaHRlIGUgZGlzcG9udWVzaG1lIG5lIGR5IGZvcm1hdGU6ICRSU3R1ZGlvJCAkRGVza3RvcCQgaSBjaWxhIGVzaHRlIG5qZSBhcGxpa2FjaW9uIGkgcnJlZ3VsbHQgZGVza3RvcCBkaGUgJFJzdHVkaW8kICRTZXJ2ZXIkIGkgY2lsaSBmdW5rc2lvbm9uIG5lIG5qZSBzZXJ2ZXIgdGUgbWFkaCBkaGUgbGVqb24gaHlyamVuIG5lICRSU3R1ZGlvJCBkdWtlIHBlcmRvcnVyIG5qZSBzaGZsZXR1ZXMgd2ViLiAkUlN0dWRpbyQgJElERSQgZXNodGUgbmplIHByb2R1a3QgaSAkUG9zaXQkICRQQkMkIChkaWt1ciAkUlN0dWRpbyQgJFBCQyQsIG1lIHBhcmUgJFJTdHVkaW8kICRJbmMuJCkuKioNCg0KKlJTdHVkaW8gcGVyZnNoaW46Kg0KDQoqKuKAoiBuamUgbWpldCBlZmVrdGl2IHBlciB0cmFqdGltaW4gZGhlIHJ1YWp0amVuIGUgdGUgZGhlbmF2ZTsqKg0KDQoqKuKAoiBuamUgZ3J1cCBvcGVyYXRvcmVzaCBwZXIgbGxvZ2FyaXRqZXQgbmUgdmFyZ2plLCBuZSB2ZWNhbnRpIG1hdHJpY2E7KioNCg0KKirigKIgbmplIGtvbGVrc2lvbiB0ZSBtYWRoLCBrb2hlcmVudCBkaGUgdGUgaW50ZWdydWFyIHRlIG1qZXRldmUgdGUgbmRlcm1qZXRtZSBwZXIgYW5hbGl6ZW4gZSB0ZSBkaGVuYXZlOyoqDQoNCioq4oCiIHBhamlzamUgZ3JhZmlrZSBwZXIgYW5hbGl6ZW4gZGhlIHNoZmFxamVuIGUgdGUgZGhlbmF2ZSBuZSBla3JhbiBvc2UgbmUga29wamUgZml6aWtlOyoqDQoNCioq4oCiIG5qZSBnanVoZSBwcm9ncmFtaW1pIHRlIHpodmlsbHVhciBtaXJlLCBlIHRoamVzaHRlIGRoZSBlZmVrdGl2ZSwgZSBjaWxhIHBlcmZzaGluIGt1c2h0ZSwgZnVua3Npb25lIHJla3Vyc2l2ZSB0ZSBwZXJjYWt0dWFyYSBuZ2EgcGVyZG9ydWVzaSBkaGUgcGFqaXNqZSBoeXJlc2UtZGFsZXNlOyoqDQoNCg0KJCRPYmpla3RpdmF0OiQkDQoNCioqTmUga2V0ZSBwcm9qZWt0IGtlbWkgc2kgc3luaW06KioNCg0KKip+IFRlIHNocXlydG9qbWUgbmUgbWVueXJlIGFuYWxpdGlrZSwgc3RhdGlzdGlrb3JlIGRoZSBncmFmaWtlIHRlIGRoZW5hdCBlIGRhdGFzZXRpdCBuZSBnanVoZW4gJFIkOyoqDQoNCioqfiBUZSBqZW1pIHRlIGFmdGUgdGUgbGV4b2ptZSBkaGUgaW50ZXJwcmV0b2ptZSBrb2RldCBlIHBlcmRvcnVyYSBkaGUgdGUgc2hwamVnb2ptZSBxZWxsaW1pbiBlIHBlcmRvcmltaXQgdGUgdHlyZTsqKg0KDQoqKn4gVGUgYW5hbGl6b2ptZSBjZG8gZ3JhZmlrIHRlIG5kZXJ0dWFyOyoqDQoNCioqfiBUZSBldmlkZW50b2ptZSBkaGUgcGVyZG9yaW0gdGUgZ2ppdGhlIGZ1bmtzaW9uZXQgZGhlIGxpYnJhcml0ZSBlIG5kcnlzaG1lIHRlIG1lc3VhcmEgbmUgc2VhbmNhdCBsYWJvcmF0b3Jpa2UgZGhlIG1lIGdqZXJlOyoqDQoNCg0KDQoNCiMjIyAqKmByIGNvbG9yaXplKCJOam9oamUgbWUgRGF0YWJhemVuIiwgImJsdWUiKWAqKg0KDQokJFN0dWRlbnRcIFNwZW5kaW5nXCBEYXRhc2V0JCQNCg0KKipEYXRhc2V0aSBpIHpnamVkaHVyIHRpdHVsbG9oZXQgJFN0dWRlbnQkICRTcGVuZGluZyQgZGhlIG5lIHRlIGxpc3RvaGVuIHRlIGFyZGh1cmF0IGRoZSBzaHBlbnppbWV0IGUgMTAwMCBzdHVkZW50ZXZlIHRlIHpnamVkaHVyIG5lIG5qZSB6Z2plZGhqZSB0ZSByYXN0aXQsIGt1IG5lIHRoZWxiaW4gZSBzdHVkaW1pdCBxZW5kcm9uIGZha3RpIHNlIG5lIHZhcmVzaSB0ZSBtb3NoZXMsIGZvcm1pbWl0IGFyc2ltb3IgZGhlIGdqaW5pc2UsIHNhIGZpdG9uLCBzYSBzaHBlbnpvbiBkaGUgc2kgaSBzaHBlbnpvbiBuamUgc3R1ZGVudCB0ZSBhcmRodXJhdCBtdWpvcmUgdGUgdGlqLiBOamUgcmVuZGVzaSBlIHZlY2FudGUgaSBlc2h0ZSBrdXNodHVhciBlZGhlIG1lbnlyZXMgc2VzaSBwYXJhdGUgdHJhbnNha3Npb25vaGVuLCBkdWtlIG5hIGxlbmUgdGUga3VwdG9qbWUgc2Ugc2kgbmplIHN0dWRlbnQgcHJlZmVyb24gdGUgcGFndWFqZSBkaGUgcGFndWhldCBnamF0ZSB2ZXByaW10YXJpc2Ugc2UgdGlqIHRlIHBlcmRpdHNobWUuKioNCg0KKkNSRURJVFM6ICRTdHVkZW50JCAkU3BlbmRpbmckICREYXRhc2V0JCBlc2h0ZSBzaGthcmt1YXIgbmUgJGthZ2dsZS5jb20vZGF0YXNldHMkLCBkdWtlIHFlbmUgYnJlbmRhIHJyZWd1bGxhdmUgZGhlIGtyaXRlcmV2ZSBtZSB0ZSBjaWxhdCB3ZWItZmFxamEgJGthZ2dsZS5jb20kIGZ1bmtzaW9ub24hKg0KDQoNCioqTGUgdGUgbmppaGVtaSBtZSBkYXRhc2V0aW4gJFN0dWRlbnQkICRTcGVuZGluZyQ6KioNCg0KKipLeSBkYXRhc2V0IHBlcmJlaGV0IG5nYSB2YXJpYWJsYSBkaGUgdmxlcmEgc2kgbWUgcG9zaHRlOioqDQoNCioqRmlsbGltaXNodCBuYSBkdWhldCB0ZSBpbXBvcnRvam1lIGRhdGFzZXRpbiBuZ2EgZmlsZSBleHBsb3JlciBkaGUgcGVyIHRhIGJlcmUga2V0ZSBuYSBkdWhldCBsaWJyYXJpYSAkcmVhZHhsJCBlIGNpbGEgZG8gdGUgbGV4b2plIHNrZWRhcmluIGV4Y2VsIGRoZSBtZSBwYXMgcGVyZG9yaW0gZnVua3Npb25pbiAkc2V0d2QoKSQgaSBjaWxpIGRvIHRlIG1hcnJlIHNpIHBhcmFtZXRlciBwYXRoLWluIGUgZmlsZSBxZSBkdWFtIHRlIGltcG9ydG9qbWU6KioNCg0KYGBge3J9DQpsaWJyYXJ5KHJlYWR4bCkNCnNldHdkKCJDOi9Vc2Vycy9QZXJkb3J1ZXMvRG93bmxvYWRzIikNCmdldHdkKCkNCmRhdGEgID0gcmVhZC5jc3YoInN0dWRlbnRfc3BlbmRpbmcuY3N2IikNCmRhdGENCmBgYA0KDQoqKiRTdHVkZW50JCAkU3BlbmRpbmckIHBlcm1iYW4gMTcgbGxvamUgdGUgbmRyeXNobWUgbmRyeXNob3Jlc2gsIGt1IHNlY2lsZXMgbmRyeXNob3JlIGkga29ycmVzcG9uZG9qbmUgMTAwMCB0ZSBkaGVuYTsqKg0KDQoqKkRhdGFzZXRpIGthIGdqaXRoc2VqIDQgJG5kcnlzaG9yZSQgJGNpbGVzb3JlJCBkaGUgMTMgJG5kcnlzaG9yZSQgJHNhc2lvcmUkOyoqDQoNCiROZHJ5c2hvcmV0JCAkQ2lsZXNvcmU6JA0KDQoqKkdqaW5pYTsqKg0KDQoqKlZpdGkgaSBTdHVkaW1ldmU7KioNCg0KKipEaXBsb21pbWk7KioNCg0KKipNZXRvZGEgZSBQYWdlc2VzOyoqDQoNCiROZHJ5c2hvcmV0JCAkU2FzaW9yZTokDQoNCioqTW9zaGEqKg0KDQoqKlRlIGFyZGh1cmF0IG11am9yZSoqDQoNCioqTmRpaG1hIGZpbmFuY2lhcmUqKg0KDQoqKlNoa29sbGltaSoqDQoNCioqU3RyZWhpbWkqKg0KDQoqKlVzaHFpbWkqKg0KDQoqKlRyYW5zcG9ydGkqKg0KDQoqKk1qZXRldCBzaGtvbGxvcmUqKg0KDQoqKkFyZ2V0aW0qKg0KDQoqKkt1amRlc2kgcGVyc29uYWwqKg0KDQoqKlRla25vbG9namkqKg0KDQoqKk1pcmVxZW5pYSBzaGVuZGV0ZXNvcmUqKg0KDQoqKlRlIG5kcnlzaG1lLyBUZSB0amVyYSoqDQoNCiMjIyMgJCRDZG9cIG5kcnlzaG9yZVwgZG9cIHRlXCBhbmFsaXpvaGV0XCBuZ2FcIGFuYVwgc3RhdGlzdGlrb3JlISQkDQoNCg0KIyMjICoqYHIgY29sb3JpemUgKCJBbmFsaXphIGUgdGUgRGhlbmF2ZSIsICJibHVlIilgKioNCg0KKiokQW5hbGl6YSQgJGUkICR0ZSQgJGRoZW5hdmUkIG7DqyAkUlN0dWRpbyQgZXNodGUgbmplIHByb2NlcyBrdSBwZXJwdW5vaGVuLCB2aXp1YWxpem9oZW4gZGhlIGludGVycHJldG9oZW4gdGUgZGhlbmF0IHBlciB0ZSBueGplcnJlIGluZm9ybWFjaW9uZSBkaGUga3VwdGltIG5nYSB0by4gTmUga2V0ZSBwcm9jZXMgcGVyZnNoaWhldCBpbXBvcnRpbWksIHBhc3RyaW1pLCBwZXJwdW5pbWksIHZpenVhbGl6aW1pIGRoZSBpbnRlcnByZXRpbWkgaSB0ZSBkaGVuYXZlIG5lIG5qZSBtZW55cmUgc2EgbWUgdGUgc2FrdGUuKioNCg0KKipQZXIgdGUgYmVyZSBuamUgYW5hbGl6ZSB0ZSBzYWt0ZSB0ZSB0ZSBkaGVuYXZlIGRvIGZpbGxvam1lIHRlIGFwbGlrb2ptZSBkaXNhIG1ldG9kYSB0ZSBjaWxhdCBqYW5lIHRoZW1lbG9yZSBuZSBkYXRhIGFuYWx5c2lzLioqDQoNCiRMaWJyYXJpdGUkICRlJCAkcGVyZG9ydXJhJCAkbmUkICRhbmFsaXppbWluJCAkZSQgJHRlJCAkZGhlbmF2ZSQgJGphbmU6JA0KDQoqKmxpYnJhcnkocmVhZHhsKSoqDQoNCioqbGlicmFyeShnZ3B1YnIpKioNCg0KKipsaWJyYXJ5KHRpZHl0ZXh0KSoqDQoNCioqbGlicmFyeShjb3JyZWxhdGlvbikqKg0KDQoqKmxpYnJhcnkodGlkeXIpKioNCg0KKipsaWJyYXJ5KGNvcnJwbG90KSoqDQoNCioqbGlicmFyeShEYXRhRXhwbG9yZXIpKioNCg0KKipsaWJyYXJ5KE1BU1MpKioNCg0KKipsaWJyYXJ5KHN1cnZleSkqKg0KDQoqKmxpYnJhcnkoZGF0YXdpemFyZCkqKg0KDQoqKmxpYnJhcnkoc3RhdHMpKioNCg0KKipsaWJyYXJ5KGdyaWQpKioNCg0KKipsaWJyYXJ5KHdvcmRjbG91ZCkqKg0KDQoqKmxpYnJhcnkodGlkeXZlcnNlKSoqDQoNCioqbGlicmFyeShSQ29sb3JCcmV3ZXIpIGV0ai4uKioNCg0KJCRQRVJQVU5JTUlcIElcIFRFXCBESEVOQVZFJCQNCg0KKipQZXIgdGUgbmlzdXIgcGVycHVuaW1pbiBlIHRlIGRoZW5hdmUgZmlsbGltaXNodCBkdWhldCB0ZSBsZXhvam1lIGRhdGFzZXRpbiBtZSBhbmUgdGUgZnVua3Npb25pdCAkc3R3ZCgpJCwgZ2ppdGhhc2h0dSBkdWhldCB0ZSBwZXJkb3JpbSBlZGhlIGxpYnJhcmluZSAkcmVhZHhsJCBlIGNpbGEgZG8gdGUgbGV4b2plIHNrZWRhcmluIHRvbmUgZXhjZWwuKioNCmBgYHtyfQ0KbGlicmFyeShyZWFkeGwpDQpzZXR3ZCgiQzovVXNlcnMvUGVyZG9ydWVzL0Rvd25sb2FkcyIpDQpnZXR3ZCgpDQpgYGANCg0KKipGdW5rc2lvbmkgJGdldHdkKCkkIG5hIGplcCBmaWxlIHBhdGguKioNCg0KKipUcmVnb2ptZSBjZmFyZSBrbGFzZSBlc2h0ZSBkYXRhc2V0aToqKg0KYGBge3J9DQpjbGFzcyhkYXRhKSANCmBgYA0KDQoqKlBlcmNha3Rvam1lIGRpbWVuc2lvbmluL3Blcm1hc2VuIGUgZGF0YXNldGl0OioqDQpgYGB7cn0NCmRpbShkYXRhKQ0KYGBgDQoNCioqUmV6dWx0YXRpIGkgc2hmYXF1ciBuYSB0cmVnb24gc2UgZGF0YXNldGkgcGVyYmVoZXQgbmdhIDEwMDAgcnJlc2h0YSBkaGUgMTcga29sb25hLioqDQoNCioqU2hmYXFpbSBzdHJ1a3R1cmVuIGUgb2JqZWt0aXQgdG9uZSB0ZSB0ZSBkaGVuYXZlICgkRGF0YSQgJEZyYW1lJCkuIEt5IHZlcHJpbSBhcnJpaGV0IGR1a2UgYXBsaWt1YXIgZnVua3Npb25pbiAkc3RyKGRhdGEpJCBkaGUgbWUgYW5lbiBlIHRpaiBuZSBwZXJjYWt0b2ptZToqKg0KDQoqKjEuTnVtcmluIGUgcnJlc2h0YXZlIGRoZSBrb2xvbmF2ZSB0ZSBkYXRhc2V0aXQ7KioNCg0KKioyLlRpcGluIGUgdGUgZGhlbmF2ZSBwZXIgc2VjaWxlbiBrb2xvbmUgc2kgaW50LCBjaGFyLCBib29sZWFuIGV0ai47KioNCg0KKiozLk5qZSBwamVzZSB0ZSB2b2dlbCB0ZSB0ZSBkaGVuYXZlIG5lIGRhdGFzZXQ7KioNCmBgYHtyfQ0Kc3RyKGRhdGEpDQpgYGANCg0KKipBcGxpa29qbWUgZnVua3Npb25pbiAkc3VtbWFyeShkYXRhKSQgcGVyIHRlIGtyeWVyIG5qZSBwZXJtYmxlZGhqZSB0ZSBzaHBlanRlLCBwYXJhcHJha2UgdGUgdGUgZGhlbmF2ZSBuZSBkYXRhc2V0LioqDQoNCioqUmV6dWx0YXRpIGkga3RoeWVyIG5nYSAkc3VtbWFyeShkYXRhKSQgcGVyZnNoaW4gaW5mb3JtYWNpb25lIHNpOioqDQoNCioqflZsZXJhdCBla3N0cmVtYWxlIChtYXgsIG1pbiksIG1lc2F0YXJqYSwgbWVzb3JqYSwgbW9kYSxrdWFydGlsaSBpIHBhcmUsIGt1YXJ0aWxpIGkgMy10ZTsqKg0KDQoqKn5OdW1yaW4gZSB2bGVyYXZlIHFlIG11bmdvam5lIG5lIHNlY2lsZW4gbmdhIGtvbG9uYXQgZSBkYXRhc2V0aXQgKE5BTikuKioNCg0KKip+TmplIHBlcm1ibGVkaGplIHRlIHRlIGRoZW5hdmUgcGVyIHZsZXJhdCBlIG5kcnlzaG9yZXZlIGNpbGVzb3JlLCBkdWtlIHBlcmZzaGlyZSBudW1yaW4gZSB2bGVyYXZlIHVuaWtlIGRoZSBmcmVrdWVuY2VuIGUgdHlyZS4qKg0KDQoqKktqbyBuZGlobW9uIG5lIG5qb2hqZW4gZSBzaHBlcm5kYXJqZXMgc2UgdGUgZGhlbmF2ZSBuZSBrb2xvbmEgZHVrZSBwZXJmc2hpcmUgdmxlcmF0IG1pbmltYWxlIGRoZSBtYWtzaW1hbGUsIHZsZXJlbiBtZXNhdGFyZSBkaGUgdGVuZGVuY2F0IGUgdGplcmEgc3RhdGlzdGlrb3JlLioqDQoNCmBgYHtyfQ0Kc3VtbWFyeShkYXRhKQ0KYGBgDQoNCioqS29udHJvbGxvam1lIHBlciBudW1yYSBxZSBtdW5nb2puZToqKg0KYGBge3J9DQpudW0gPC0gc3VtKGlzLm5hKGRhdGEpKQ0KbnVtDQpgYGANCg0KKipLb250cm9sbG9qbWUgcGVyIHZsZXJhIGR1cGxpY2F0ZWQ6KioNCmBgYHtyfQ0KZHVwbCA8LSBzdW0oZHVwbGljYXRlZChkYXRhKSkNCmR1cGwNCmBgYA0KKipNZXFlbmVzZSBudWsgbXVuZ29qbmUgdmxlcmEgZGhlIG51ayBrYSB2bGVyYSBkdXBsaWNhdGVkLCBncnVwaSBpIHRlIGRoZW5hdmUgZXNodGUgaSBwYXN0ZXIuKioNCg0KDQoNCiMjIyMgJCRBTkFMSVpBXCBFXCBORFJZU0hPUkVWRVwgU0FTSU9SRSQkDQoNCioqJE5kcnlzaG9yZXQkICRTYXNpb3JlJCBrbGFzaWZpa29oZW4gbmUgbmRyeXNob3JlICRkaXNrcmV0ZSQgZGhlICR0ZSQgJHZhemhkdWVzaG1lJC4qKg0KDQoqKk5kcnlzaG9yZXQgU2FzaW9yZSBuZSBkYXRhc2V0aW4gdG9uZSBqYW5lIGRpc2tyZXRlLCBtZSB2bGVyYSB0ZSBmdW5kbWUsIHFlIGRvIHRlIHRob3RlIHNlIGF0byBkbyB0ZSBwZXJzaGtydWhlbiBudW1lcmlraXNodCBuZXBlcm1qZXQgZWZla3RpdmF2ZSwgZnJla3VlbmNhdmUgZGhlIHRhYmVsYXZlIHN0YXRpc3Rpa29yZS4qKg0KDQoqKk5lIGtldGUgaGVhZGxpbmUgZG8gdGUgdHJhanRvam1lIGFuYWxpemVuIGUgdHJlZ3Vlc3ZlIHRlIHBvemljaW9uaXQga3UgcGVyZnNoaWhlbiBtZXNhdGFyamEsIG1vZGEsIG1lc29yamEsIGt1YXJ0aWxldCBkaGUgdHJlZ3Vlc2l0IGUgc2hwZXJoYXBqZXMsIGludGVydmFsZXQgbmRlcmt1YXJ0aWxvcmUsIGFtcGxpdHVkYSwgZGlzcGVyc2lvbmkgZGhlIG1lbmphbmltaSBtZXNhdGFyIGthdHJvci4qKg0KDQoqKk1lc2F0YXJqYSwgTW9kYSwgTWVzb3JqYSAmIEt1YXJ0aWxldCwgSW50ZXJ2YWxldCBOZGVya3VhcnRpbG9yZTsqKg0KDQokJE1lc2F0YXJqYVwgQXJpdG1ldGlrZSQkDQoNCioqJE1lc2F0YXJqYSQgJEFyaXRtZXRpa2UkIG5lIHN0YXRpc3Rpa2UgZXNodGUgbmplIHBhcmFtZXRlciBxZSB0cmVnb24gcG96aWNpb25pbiBlIHZsZXJhdmUgdGUgbmRyeXNob3Jlcy4gQWpvIHBhcmFxZXQgdmxlcmVuIGUgcGVyZ2ppdGhzaG1lIHRlIG5qZSBncnVwaSB0ZSB0ZSBkaGVuYXZlIGRoZSBrYSBrdXB0aW0gdmV0ZW0ga3VyIG5kcnlzaG9yamEgZXNodGUgc2FzaW9yZS4gUGVyIHRlIGxsb2dhcml0dXIgdmxlcmVuIG1lc2F0YXJlIHRlIGRoZW5hdCBtYmxpZGhlbiBzZSBiYXNoa3UgZGhlIG1lIHBhcyBwamVzZXRvaGVuIG1lIG51bXJpbiBlIHR5cmUgdGUgcGVyZ2ppdGhzaGVtLioqDQoNCiQkRm9ybXVsYVwgbWF0ZW1hdGlrZTpcXHtcZGlzcGxheXN0eWxlIHtcb3ZlcmxpbmUge1h9fT17XGZyYWMge1hfezF9K1xjZG90cyArWF97bn19e259fX09e1xmcmFjIHsxfXtufSBcc3VtIF97aT0xfV57bn17eF97aX19fSQkDQoNCioqTGUgdGUga3J5ZWptZSBuamUgbGxvZ2FyaXRqZSB0ZSB2bGVyYXZlIG1lc2F0YXJlIHBlciBjZG8gdmFyaWFiZWwgc2FzaW9yZSBuZSBkYXRhc2V0IG5lcGVybWpldCBmdW5rc2lvbml0ICRtZWFuKCkkLioqDQoNCioqUGVyIHRlIGtyeWVyIGtldGUgbGxvZ2FyaXRqZSBwZXIgY2RvIG5kcnlzaG9yZSBzYXNpb3JlIGRvIHRpIHRoZXJyYXNpbSBhdG8gbWUgYXRlIHRlIGZ1bmtzaW9uaXQgJGRmJGAkYCRlbXJpJGBfYCR2YXJpYWJsaXQkOiAqKg0KDQoqKk1vc2hhIG1lc2F0YXJlIGUgbmplIHN0dWRlbnRpIG5lIGRhdGFzZXQgZXNodGU6KioNCmBgYHtyfQ0KbWVhbl9tb3NoYSA8LSBtZWFuKGRhdGEkbW9zaGEpDQpwcmludChtZWFuX21vc2hhKQ0KYGBgDQoNCioqVGUgYXJkaHVyYXQgbWVzYXRhcmUgdGUgc3R1ZGVudGV2ZSBqYW5lOioqDQpgYGB7cn0NCm1lYW5fdGVfYXJkaHVyYXRfbXVqb3JlIDwtIG1lYW4oZGF0YSR0ZV9hcmRodXJhdF9tdWpvcmUpDQpwcmludChtZWFuX3RlX2FyZGh1cmF0X211am9yZSkNCmBgYA0KDQoqKk5kaWhtYSBmaW5hbmNpYXJlIHFlIGkgYXRyaWJvaGV0IGNkbyBzdHVkZW50aSBtZXNhdGFyaXNodCBhcnJpbiB2bGVyZW46KioNCmBgYHtyfQ0KbWVhbl9uZGlobWFfZmluYW5jaWFyZSA8LSBtZWFuKGRhdGEkbmRpaG1hX2ZpbmFuY2lhcmUpDQpwcmludChtZWFuX25kaWhtYV9maW5hbmNpYXJlKQ0KYGBgDQoNCioqU2h1bWEgcWUgbmplIHN0dWRlbnQgc2hwZW56b24gbWVzYXRhcmlzaHQgcGVyIHNoa29sbGltaW4gZSB0aWo6KioNCmBgYHtyfQ0KbWVhbl9zaGtvbGxpbWkgPC0gbWVhbihkYXRhJHNoa29sbGltaSkNCnByaW50KG1lYW5fc2hrb2xsaW1pKQ0KYGBgDQoNCioqU2h1bWEgcWUgbmplIHN0dWRlbnQgc2hwZW56b24gbWVzYXRhcmlzaHQgcGVyIHRlIHNpZ3VydWFyIHN0cmVoaW1pbiBlIHRpajoqKg0KYGBge3J9DQptZWFuX3N0cmVoaW1pIDwtIG1lYW4oZGF0YSRzdHJlaGltaSkNCnByaW50KG1lYW5fc3RyZWhpbWkpDQoNCmBgYA0KDQoqKlNodW1hIHFlIG5qZSBzdHVkZW50IHNocGVuem9uIG1lc2F0YXJpc2h0IG5lIG11YWogcGVyIHRlIHNpZ3VydWFyIHVzaHFpbWluIGUgdGlqOioqDQpgYGB7cn0NCm1lYW5fdXNocWltaSA8LSBtZWFuKGRhdGEkdXNocWltaSkNCnByaW50KG1lYW5fdXNocWltaSkNCmBgYA0KDQoqKlNodW1hIHFlIG5qZSBzdHVkZW50IHNocGVuem9uIG1lc2F0YXJpc2h0IG5lIG11YWogcGVyIHNhIGkgcGVya2V0IHRyYW5zcG9ydGl0OioqDQpgYGB7cn0NCm1lYW5fdHJhbnNwb3J0aSA8LSBtZWFuKGRhdGEkdHJhbnNwb3J0aSkNCnByaW50KG1lYW5fdHJhbnNwb3J0aSkNCmBgYA0KDQoqKlNodW1hIHFlIG5qZSBzdHVkZW50IHNocGVuem9uIG1lc2F0YXJpc2h0IG5lIG11YWogcGVyIHRlIHNpZ3VydWFyIG1qZXRldCBlIHRpaiBzaGtvbGxvcmUgKGtldHUgcGVyZnNoaWhlbiBsaWJyYSwgZm90b2tvcGplLCBsYXBzYSwgbmdqeXJhIGV0ai4pOioqDQpgYGB7cn0NCm1lYW5fbWpldGV0X3Noa29sbG9yZSA8LSBtZWFuKGRhdGEkbWpldGV0X3Noa29sbG9yZSkNCnByaW50KG1lYW5fbWpldGV0X3Noa29sbG9yZSkNCmBgYA0KDQoqKlNodW1hIHFlIG5qZSBzdHVkZW50IHNocGVuem9uIG1lc2F0YXJpc2h0IG5lIG11YWogcGVyIHQndSBhcmdldHVhcjoqKg0KYGBge3J9DQptZWFuX2FyZ2V0aW0gPC0gbWVhbihkYXRhJGFyZ2V0aW0pDQpwcmludChtZWFuX2FyZ2V0aW0pDQpgYGANCg0KKipTaHVtYSBtZXNhdGFyZSBxZSBuamUgc3R1ZGVudCBpYSBkZWRpa29uIGt1amRlc2l0IHRlIHRpaiBwZXJzb25hbCBzaSBxZXRoamUsIHBhcnVraWVyZSwgdmVzaGplLCBoaWdqaWVuZSBldGouKioNCmBgYHtyfQ0KbWVhbl9rdWpkZXNpX3BlcnNvbmFsIDwtIG1lYW4oZGF0YSRrdWpkZXNpX3BlcnNvbmFsKQ0KcHJpbnQobWVhbl9rdWpkZXNpX3BlcnNvbmFsKSANCmBgYA0KDQoqKlNodW1hIHFlIG5qZSBzdHVkZW50IHNocGVuem9uIG1lc2F0YXJpc2h0IG5lIG11YWogbmUgYXNwZWt0aW4gZSB0ZWtub2xvZ2ppc2U7IGtldHUgcGVyZnNoaWhlbiB0ZWxlZm9uLCBsYXB0b3AvcGMgZGhlIGNkbyBhbmdhemhpbSB0amV0ZXIgbmUga2V0ZSBmdXNoZToqKg0KYGBge3J9DQptZWFuX3Rla25vbG9namkgPC0gbWVhbihkYXRhJHRla25vbG9namkpDQpwcmludChtZWFuX3Rla25vbG9namkpDQpgYGANCg0KKipTaHVtYSBxZSBuamUgc3R1ZGVudCBpYSBkZWRpa29uIG1pcmVxZW5pZXMgc2UgdGlqIHNoZW5kZXRlc29yZSwgZHVrZSBwZXJmc2hpcmUgdml6aXRhdCBtamVrZXNvcmUsIGtvbnN1bHRhdCB0ZSBkZW50aXN0aSwgbWVkaWthbWVudGUgZmFybWFjZXV0aWtlIGV0ai46KioNCmBgYHtyfQ0KbWVhbl9taXJlcWVuaWFfc2hlbmRldGVzb3JlIDwtIG1lYW4oZGF0YSRtaXJlcWVuaWFfc2hlbmRldGVzb3JlKQ0KcHJpbnQobWVhbl9taXJlcWVuaWFfc2hlbmRldGVzb3JlKQ0KYGBgDQoNCioqU2h1bWEgcWUgbmplIHN0dWRlbnQgc2hwZW56b24gcGVyIGNkbyBha3Rpdml0ZXQgdGpldGVyIG5lIHBlcmRpdHNobWVyaW5lIGUgdGlqOyBram8gc2h1bWUgdmFyZXQgbmdhIHRlcHJpY2EgZSBzaHVtZXMgbW9uZXRhcmUgdGUgbWJldHVyIG5lIGxsb2dhcmluZSBlIHRpajoqKg0KYGBge3J9DQptZWFuX3RlX25kcnlzaG1lIDwtIG1lYW4oZGF0YSR0ZV9uZHJ5c2htZSkNCnByaW50KG1lYW5fdGVfbmRyeXNobWUpDQpgYGANCg0KJCRNZXNhdGFyamFcIGVcIEdydXB1YXIkJA0KDQoqKlRhbmkgbGUgdGUgbGxvZ2FyaXNpbSBzaHBlbnppbWV0IG11am9yZSB0ZSBzdHVkZW50ZXZlIHNpcGFzIGthdGVnb3JpdmUvZ3J1cGltZXZlOyoqDQoNCioqUGVyIHRhIHJlYWxpenVhciBuYSBkdWhlbiBkeSBsaWJyYXJpOiBsaWJyYXJpYSAkZHBseXIkIGRoZSAkdGlkeXIkOyBOZSBmaWxsaW1pc2h0IGRvIHRpIGthdGVnb3Jpem9qbWUgdGUgZGhlbmF0IG5lIGRpc2EgZ3J1cGltZSBkaGUgbWUgcGFzIGRvIHRlIGxsb2dhcmlzaW0gc2Ugc2Egc2hwZW56b24gc2VjaWxhIHByZWogdHlyZSBtZXNhdGFyaXNodDsqKg0KDQoqKkdydXBvam1lIHRlIGRoZW5hdCBtZSBhbmUgdGUgZnVua3Npb25pdCAkZ3JvdXAkYF9gJGJ5JDoqKg0KYGBge3J9DQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeSh0aWR5cikNCg0KZ3J1cGlfbW9zaGEgPC0gZGF0YSAlPiUgZ3JvdXBfYnkoZGF0YSRtb3NoYSkNCmdydXBpX2dqaW5pYSA8LSBkYXRhICU+JSBncm91cF9ieShkYXRhJGdqaW5pYSkNCmdydXBpX3ZpdGlfaV9zdHVkaW1ldmUgPC0gZGF0YSAlPiUgZ3JvdXBfYnkoZGF0YSR2aXRpX2lfc3R1ZGltZXZlKQ0KZ3J1cGlfZGlwbG9taW1pIDwtIGRhdGEgJT4lIGdyb3VwX2J5KGRhdGEkZGlwbG9taW1pKQ0KYGBgDQoNCioqU2hwZW56aW1ldCBlIGdydXBpbWl0ICRtb3NoYSQ6KioNCmBgYHtyfQ0Kc2hwZW56aW1ldF9tZXNhdGFyZV9tb3NoYSA8LSBncnVwaV9tb3NoYSAlPiUNCiAgc3VtbWFyaXplKA0KICAgIHNoa29sbGltaSA9IG1lYW4oc2hrb2xsaW1pKSwNCiAgICBzdHJlaGltaSA9IG1lYW4oc3RyZWhpbWkpLA0KICAgIHVzaHFpbWkgPSBtZWFuKHVzaHFpbWkpLA0KICAgIHRyYW5zcG9ydGkgPSBtZWFuKHRyYW5zcG9ydGkpLA0KICAgIG1qZXRldF9zaGtvbGxvcmUgPSBtZWFuKG1qZXRldF9zaGtvbGxvcmUpLA0KICAgIGFyZ2V0aW0gPSBtZWFuKGFyZ2V0aW0pLA0KICAgIGt1amRlc2lfcGVyc29uYWwgPSBtZWFuKGt1amRlc2lfcGVyc29uYWwpLA0KICAgIHRla25vbG9namkgPSBtZWFuKHRla25vbG9namkpLA0KICAgIG1pcmVxZW5pYV9zaGVuZGV0ZXNvcmUgPSBtZWFuKG1pcmVxZW5pYV9zaGVuZGV0ZXNvcmUpLA0KICAgIHRlX25kcnlzaG1lID0gbWVhbih0ZV9uZHJ5c2htZSkNCiAgKQ0KYGBgDQoNCioqU2hwZW56aW1ldCBtZXNhdGFyZSBwZXIgY2RvIGthdGVnb3JpIHRlIHNocGVuemltZXZlIGJyZW5kYSBjZG8gZ3J1cGkgdGUgbW9zaGVzIGphbmU6KioNCmBgYHtyfQ0KcHJpbnQoc2hwZW56aW1ldF9tZXNhdGFyZV9tb3NoYSkNCmBgYA0KDQoqKktvZGk6KioNCg0KKipGaWxsaW1pc2h0IHRoZXJyYXNpbSBsaWJyYXJpdGUgZSBuZXZvanNobWUgJGRwbHlyJCBkaGUgJHRpZHlyJC4qKg0KDQoqKiRncnVwaSRgX2AkbW9zaGEkICQ8LSQgJGRhdGEkICRgJT4lYCQgJGdyb3VwJGBfYCRieShkYXRhYCRgbW9zaGEpJCBrcnllbiBncnVwaW1pbiBlIGtlcmt1YXIsIGR1a2UgbWFycmUgc2kgcGFyYW1ldGVyIGVtcmluIGUga29sb25lcyBzZSBkYXRhc2V0aXQgbWJpIHRlIGNpbGVuIGtlcmtvam1lIHRlIGtyeWVqbWUgbmplIGxsb2dhcml0amUgdGUgdGlsbGUgc3RhdGlzdGlrb3JlICgkbW9zaGEkKS4gRSBuamVqdGEgcHJvY2VkdXJlIHBlcmRvcmV0IG5lIDMgcnJlc2h0YXQgcGFzdWVzIHRlIGtvZGl0LCBrdSBrcnloZXQgZ3J1cGltaSBwZXIgdmFyaWFibGF0ICRnamluaWEkLCAkdml0aSRgX2AkaSRgX2Akc3R1ZGltZXZlJCBkaGUgJGRpcGxvbWltaSQqKg0KDQoqKlBhc2kga2VtaSBrcnllciB0ZSBnaml0aGEgZ3J1cGltZXQgZSBkZXNoaXJ1YXJhLCBkdWtlIHBlcmRvcnVyIGZ1bmtzaW9uaW4gJHN1bW1hcml6ZSguLi4pJCBuZSBsbG9nYXJpdGltIG5qZSBtZXNhdGFyZSB0ZSBncnVwaW1ldmUgdGUgbWVzaXBlcm1lIGt1IHBlcmZzaGloZW4gZnVzaGF0IHNpICRzaGtvbGxpbWkkLCAkc3RyZWhpbWkkLCAkdXNocWltaSQgZXRqLiwgdGUgY2lsYXQgYWZpc2hvaGVuIG5lIG5qZSB0YWJlbGUuKioNCg0KKipMZXhpbWkgaSB0YWJlbGVzIGVzaHRlIGkgdGlsbGU6IDE4IHZqZWNhcmV0IHNocGVuem9qbmUgbWVzYXRhcmlzaHQgJDQ0ODUuOTUyIHBlciBzaGtvbGxpbWluLCAkNzEyLjI0MTkgcGVyIHN0cmVoaW0sIGUga2VzaHR1IG1lIHJyYWRoZSBwZXIgdGUgZ2ppdGhhIGthdGVnb3JpdGUgZSB0amVyYSBuZSB0YWJlbGUuKioNCg0KKipFIG5qZWp0YSBtZW55cmUgaW50ZXJwcmV0aW1pIHZsZW4gcGVyIGNkbyB0YWJlbGUgdGpldGVyIHRlIG5kZXJ0dWFyIG1lIHBvc2h0ZS4qKg0KDQoqKlNocGVuemltZXQgZSBncnVwaW1pdCAkZ2ppbmlhJDoqKg0KYGBge3J9DQpzaHBlbnppbWV0X21lc2F0YXJlX2dqaW5pYSA8LSBncnVwaV9namluaWEgJT4lDQogIHN1bW1hcml6ZSgNCiAgICBzaGtvbGxpbWkgPSBtZWFuKHNoa29sbGltaSksDQogICAgc3RyZWhpbWkgPSBtZWFuKHN0cmVoaW1pKSwNCiAgICB1c2hxaW1pID0gbWVhbih1c2hxaW1pKSwNCiAgICB0cmFuc3BvcnRpID0gbWVhbih0cmFuc3BvcnRpKSwNCiAgICBtamV0ZXRfc2hrb2xsb3JlID0gbWVhbihtamV0ZXRfc2hrb2xsb3JlKSwNCiAgICBhcmdldGltID0gbWVhbihhcmdldGltKSwNCiAgICBrdWpkZXNpX3BlcnNvbmFsID0gbWVhbihrdWpkZXNpX3BlcnNvbmFsKSwNCiAgICB0ZWtub2xvZ2ppID0gbWVhbih0ZWtub2xvZ2ppKSwNCiAgICBtaXJlcWVuaWFfc2hlbmRldGVzb3JlID0gbWVhbihtaXJlcWVuaWFfc2hlbmRldGVzb3JlKSwNCiAgICB0ZV9uZHJ5c2htZSA9IG1lYW4odGVfbmRyeXNobWUpDQogICkNCmBgYA0KDQoqKlNocGVuemltZXQgbWVzYXRhcmUgcGVyIGNkbyBrYXRlZ29yaSB0ZSBzaHBlbnppbWV2ZSBicmVuZGEgY2RvIGdydXBpIHRlIGdqaW5pc2UgamFuZToqKg0KYGBge3J9DQpwcmludChzaHBlbnppbWV0X21lc2F0YXJlX2dqaW5pYSkNCmBgYA0KDQoqKlNocGVuemltZXQgZSBncnVwaW1pdCAkdml0aSQgJGkkICRzdHVkaW1ldmUkOioqDQpgYGB7cn0NCnNocGVuemltZXRfbWVzYXRhcmVfdml0aV9pX3N0dWRpbWV2ZSA8LSBncnVwaV92aXRpX2lfc3R1ZGltZXZlICU+JQ0KICBzdW1tYXJpemUoDQogICAgc2hrb2xsaW1pID0gbWVhbihzaGtvbGxpbWkpLA0KICAgIHN0cmVoaW1pID0gbWVhbihzdHJlaGltaSksDQogICAgdXNocWltaSA9IG1lYW4odXNocWltaSksDQogICAgdHJhbnNwb3J0aSA9IG1lYW4odHJhbnNwb3J0aSksDQogICAgbWpldGV0X3Noa29sbG9yZSA9IG1lYW4obWpldGV0X3Noa29sbG9yZSksDQogICAgYXJnZXRpbSA9IG1lYW4oYXJnZXRpbSksDQogICAga3VqZGVzaV9wZXJzb25hbCA9IG1lYW4oa3VqZGVzaV9wZXJzb25hbCksDQogICAgdGVrbm9sb2dqaSA9IG1lYW4odGVrbm9sb2dqaSksDQogICAgbWlyZXFlbmlhX3NoZW5kZXRlc29yZSA9IG1lYW4obWlyZXFlbmlhX3NoZW5kZXRlc29yZSksDQogICAgdGVfbmRyeXNobWUgPSBtZWFuKHRlX25kcnlzaG1lKQ0KICApDQpgYGANCg0KKipTaHBlbnppbWV0IG1lc2F0YXJlIHBlciBjZG8ga2F0ZWdvcmkgdGUgc2hwZW56aW1ldmUgYnJlbmRhIGNkbyBncnVwaSB0ZSB2aXRpdCB0ZSBzdHVkaW1ldmUgamFuZToqKg0KYGBge3J9DQpwcmludChzaHBlbnppbWV0X21lc2F0YXJlX3ZpdGlfaV9zdHVkaW1ldmUpDQpgYGANCg0KKipTaHBlbnppbWV0IGUgZ3J1cGltaXQgJGRpcGxvbWltaSQ6KioNCmBgYHtyfQ0Kc2hwZW56aW1ldF9tZXNhdGFyZV9kaXBsb21pbWkgPC0gZ3J1cGlfZGlwbG9taW1pICU+JQ0KICBzdW1tYXJpemUoDQogICAgc2hrb2xsaW1pID0gbWVhbihzaGtvbGxpbWkpLA0KICAgIHN0cmVoaW1pID0gbWVhbihzdHJlaGltaSksDQogICAgdXNocWltaSA9IG1lYW4odXNocWltaSksDQogICAgdHJhbnNwb3J0aSA9IG1lYW4odHJhbnNwb3J0aSksDQogICAgbWpldGV0X3Noa29sbG9yZSA9IG1lYW4obWpldGV0X3Noa29sbG9yZSksDQogICAgYXJnZXRpbSA9IG1lYW4oYXJnZXRpbSksDQogICAga3VqZGVzaV9wZXJzb25hbCA9IG1lYW4oa3VqZGVzaV9wZXJzb25hbCksDQogICAgdGVrbm9sb2dqaSA9IG1lYW4odGVrbm9sb2dqaSksDQogICAgbWlyZXFlbmlhX3NoZW5kZXRlc29yZSA9IG1lYW4obWlyZXFlbmlhX3NoZW5kZXRlc29yZSksDQogICAgdGVfbmRyeXNobWUgPSBtZWFuKHRlX25kcnlzaG1lKQ0KICApDQpgYGANCg0KKipTaHBlbnppbWV0IG1lc2F0YXJlIHBlciBjZG8ga2F0ZWdvcmkgdGUgc2hwZW56aW1ldmUgYnJlbmRhIGNkbyBncnVwaSB0ZSBkaXBsb21pbWl0IGphbmU6KioNCmBgYHtyfQ0KcHJpbnQoc2hwZW56aW1ldF9tZXNhdGFyZV9kaXBsb21pbWkpDQpgYGANCg0KJCRNb2RhJCQNCg0KKiokTW9kYSQgbmUgc3RhdGlzdGlrZSBlc2h0ZSB2bGVyYSBxZSBwYXJhcWl0ZXQgbWUgc2hwZXNoIG5lIG5qZSBncnVwIHRlIHRlIGRoZW5hdmUuKioNCg0KKipNb2RhIG11bmQgdGUgYXBsaWtvaGV0IG5lIHRlIGRoZW5hdCBlIHNocHJlaHVyYSBuZSBmb3JtZSBudW1lcmlrZSwgc2kgZGhlIG5lIHRlIGRoZW5hdCBrYXRlZ29yaWtlIHFlIHBlcmJlaGVuIG5nYSBrYXRlZ29yaSBvc2UgZXRpa2V0YS4qKg0KDQoqKk5lIGRpc2EgcmFzdGUgbmplIGdydXAgaSB0ZSBkaGVuYXZlIG11bmQgdGUga2V0ZSBtZSBzaHVtZSBzZSBuamUgbW9kYWxpdGV0IG1lIHZsZXJhIHRlIG5qZWp0ZSB0ZSBzaHBlc2h0YS4gTmUga2V0ZSByYXN0IGdydXBpIHF1aGV0ICRiaW1vZGFsJCBvc2UgJG11bHRpbW9kYWwkLiBQZXJ2ZcOnIGtlc2FqLCBuZG9uamVoZXJlIG11bmQgdGUgbmRvZGhlIHFlIGdydXBpIHRlIG1vcyBrZXRlIG1vZGUgZmFyZSwgbmUgcmFzdGluIGt1ciB0ZSBkaGVuYXQgamFuZSB0ZSBzaHBlcm5kYXJhIG5lIG1lbnlyZSB0ZSBiYXJhYmFydGUgZGhlIG51ayBrYSB2bGVyZSBxZSBwYXJhcWl0ZXQgbWUgc2h1bWUgc2UgdGUgdGplcmF0LioqDQoNCioqTGUgdGUgZ2plam1lIHZsZXJhdCBtb2RhbGUgbmUgdGUgZGhlbmF0IHRvbmEgcGVyIHNlY2lsZW4gdmFyaWFiZWwgc2FzaW9yZSBtZSBhbmUgdGUgZnVua3Npb25pdCAkbmFtZXMkKCR0YWJsZSQoJGRmJGAkYCR2YXJpYWJsaSQpKVskdGFibGUkKCRkZiRgJGAkdmFyaWFibGkkKSAkPT0kICRtYXgkKCR0YWJsZSQoJGRmJGAkYCR2YXJpYWJsaSQpKV06KioNCg0KKipNb3NoYSBlIHBlcnNlcml0dXIgbWUgc2hwZXNoOioqDQpgYGB7cn0NCm1vZGVfbW9zaGEgPC0gbmFtZXModGFibGUoZGF0YSRtb3NoYSkpW3RhYmxlKGRhdGEkbW9zaGEpID09IG1heCh0YWJsZShkYXRhJG1vc2hhKSldDQpwcmludChtb2RlX21vc2hhKQ0KYGBgDQoNCioqVmxlcmEgZSB0ZSBhcmRodXJhdmUgcWUgcGVyc2VyaXRldCBtZSB0ZXBlcjoqKg0KYGBge3J9DQptb2RlX3RlX2FyZGh1cmF0X211am9yZSA8LSBuYW1lcyh0YWJsZShkYXRhJHRlX2FyZGh1cmF0X211am9yZSkpW3RhYmxlKGRhdGEkdGVfYXJkaHVyYXRfbXVqb3JlKSA9PSBtYXgodGFibGUoZGF0YSR0ZV9hcmRodXJhdF9tdWpvcmUpKV0NCnByaW50KG1vZGVfdGVfYXJkaHVyYXRfbXVqb3JlKQ0KYGBgDQoNCioqVmxlcmEgZSBuZGlobWVzIGZpbmFuY2lhcmUgZSBwZXJzZXJpdHVyIG1lIHNocGVzaDoqKg0KYGBge3J9DQptb2RlX25kaWhtYV9maW5hbmNpYXJlIDwtIG5hbWVzKHRhYmxlKGRhdGEkbmRpaG1hX2ZpbmFuY2lhcmUpKVt0YWJsZShkYXRhJG5kaWhtYV9maW5hbmNpYXJlKSA9PSBtYXgodGFibGUoZGF0YSRuZGlobWFfZmluYW5jaWFyZSkpXQ0KcHJpbnQobW9kZV9uZGlobWFfZmluYW5jaWFyZSkNCmBgYA0KDQoqKlZsZXJhIGUgcGVyc2VyaXR1ciBtZSBzaHBlc2ggcGVyIHNhIGkgcGVya2V0IHNocGVuemltaXQgbWJpIHNoa29sbGltaW46KioNCmBgYHtyfQ0KbW9kZV9zaGtvbGxpbWkgPC0gbmFtZXModGFibGUoZGF0YSRzaGtvbGxpbWkpKVt0YWJsZShkYXRhJHNoa29sbGltaSkgPT0gbWF4KHRhYmxlKGRhdGEkc2hrb2xsaW1pKSldDQpwcmludChtb2RlX3Noa29sbGltaSkNCmBgYA0KDQoqKlZsZXJhIGUgcGVyc2VyaXR1ciBtZSBzaHBlc2ggcGVyIHNhIGkgcGVya2V0IHNocGVuemltaXQgbWJpIHN0cmVoaW1pbjoqKg0KYGBge3J9DQptb2RlX3N0cmVoaW1pIDwtIG5hbWVzKHRhYmxlKGRhdGEkc3RyZWhpbWkpKVt0YWJsZShkYXRhJHN0cmVoaW1pKSA9PSBtYXgodGFibGUoZGF0YSRzdHJlaGltaSkpXQ0KcHJpbnQobW9kZV9zdHJlaGltaSkNCmBgYA0KDQoqKlZsZXJhIGUgcGVyc2VyaXR1ciBtZSBzaHBlc2ggcGVyIHNhIGkgcGVya2V0IHNocGVuemltaXQgbWJpIHVzaHF5ZXJqZW46KioNCmBgYHtyfQ0KbW9kZV91c2hxaW1pIDwtIG5hbWVzKHRhYmxlKGRhdGEkdXNocWltaSkpW3RhYmxlKGRhdGEkdXNocWltaSkgPT0gbWF4KHRhYmxlKGRhdGEkdXNocWltaSkpXQ0KcHJpbnQobW9kZV91c2hxaW1pKQ0KYGBgDQoNCioqVmxlcmEgZSBwZXJzZXJpdHVyIG1lIHNocGVzaCBwZXIgc2EgaSBwZXJrZXQgc2hwZW56aW1pdCBtYmkgdHJhbnNwb3J0aW46KioNCmBgYHtyfQ0KbW9kZV90cmFuc3BvcnRpIDwtIG5hbWVzKHRhYmxlKGRhdGEkdHJhbnNwb3J0aSkpW3RhYmxlKGRhdGEkdHJhbnNwb3J0aSkgPT0gbWF4KHRhYmxlKGRhdGEkdHJhbnNwb3J0aSkpXQ0KcHJpbnQobW9kZV90cmFuc3BvcnRpKQ0KYGBgDQoNCioqVmxlcmEgZSBwZXJzZXJpdHVyIG1lIHNocGVzaCBwZXIgc2EgaSBwZXJrZXQgc2hwZW56aW1pdCBtYmkgbWpldGV0IHNoa29sbG9yZToqKg0KYGBge3J9DQptb2RlX21qZXRldF9zaGtvbGxvcmUgPC0gbmFtZXModGFibGUoZGF0YSRtamV0ZXRfc2hrb2xsb3JlKSlbdGFibGUoZGF0YSRtamV0ZXRfc2hrb2xsb3JlKSA9PSBtYXgodGFibGUoZGF0YSRtamV0ZXRfc2hrb2xsb3JlKSldDQpwcmludChtb2RlX21qZXRldF9zaGtvbGxvcmUpDQpgYGANCg0KKipWbGVyYSBlIHBlcnNlcml0dXIgbWUgc2hwZXNoIHBlciBzYSBpIHBlcmtldCBzaHBlbnppbWl0IG1iaSBhcmdldGltaW46KioNCmBgYHtyfQ0KbW9kZV9hcmdldGltIDwtIG5hbWVzKHRhYmxlKGRhdGEkYXJnZXRpbSkpW3RhYmxlKGRhdGEkYXJnZXRpbSkgPT0gbWF4KHRhYmxlKGRhdGEkYXJnZXRpbSkpXQ0KcHJpbnQobW9kZV9hcmdldGltKQ0KYGBgDQoNCioqVmxlcmEgZSBwZXJzZXJpdHVyIG1lIHNocGVzaCBwZXIgc2EgaSBwZXJrZXQgc2hwZW56aW1pdCBtYmkga3VqZGVzaW4gcGVyc29uYWw6KioNCmBgYHtyfQ0KbW9kZV9rdWpkZXNpX3BlcnNvbmFsIDwtIG5hbWVzKHRhYmxlKGRhdGEka3VqZGVzaV9wZXJzb25hbCkpW3RhYmxlKGRhdGEka3VqZGVzaV9wZXJzb25hbCkgPT0gbWF4KHRhYmxlKGRhdGEka3VqZGVzaV9wZXJzb25hbCkpXQ0KcHJpbnQobW9kZV9rdWpkZXNpX3BlcnNvbmFsKQ0KYGBgDQoNCioqVmxlcmEgZSBwZXJzZXJpdHVyIG1lIHNocGVzaCBwZXIgc2EgaSBwZXJrZXQgc2hwZW56aW1pdCBtYmkgdGVrbm9sb2dqaW5lOioqDQpgYGB7cn0NCm1vZGVfdGVrbm9sb2dqaSA8LSBuYW1lcyh0YWJsZShkYXRhJHRla25vbG9namkpKVt0YWJsZShkYXRhJHRla25vbG9namkpID09IG1heCh0YWJsZShkYXRhJHRla25vbG9namkpKV0NCnByaW50KG1vZGVfdGVrbm9sb2dqaSkNCmBgYA0KDQoqKlZsZXJhIGUgcGVyc2VyaXR1ciBtZSBzaHBlc2ggcGVyIHNhIGkgcGVya2V0IHNocGVuemltaXQgbWJpIG1pcmVxZW5pZW4gc2hlbmRldGVzb3JlOioqDQpgYGB7cn0NCm1vZGVfbWlyZXFlbmlhX3NoZW5kZXRlc29yZSA8LSBuYW1lcyh0YWJsZShkYXRhJG1pcmVxZW5pYV9zaGVuZGV0ZXNvcmUpKVt0YWJsZShkYXRhJG1pcmVxZW5pYV9zaGVuZGV0ZXNvcmUpID09IG1heCh0YWJsZShkYXRhJG1pcmVxZW5pYV9zaGVuZGV0ZXNvcmUpKV0NCnByaW50KG1vZGVfbWlyZXFlbmlhX3NoZW5kZXRlc29yZSkNCmBgYA0KDQoqKlZsZXJhIGUgcGVyc2VyaXR1ciBtZSBzaHBlc2ggcGVyIHNhIGkgcGVya2V0IHNocGVuemltZXZlIHRlIHRqZXJhIHFlIHN0dWRlbnRldCBrcnllam5lOioqDQpgYGB7cn0NCm1vZGVfdGVfbmRyeXNobWUgPC0gbmFtZXModGFibGUoZGF0YSR0ZV9uZHJ5c2htZSkpW3RhYmxlKGRhdGEkdGVfbmRyeXNobWUpID09IG1heCh0YWJsZShkYXRhJHRlX25kcnlzaG1lKSldDQpwcmludChtb2RlX3RlX25kcnlzaG1lKQ0KYGBgDQoNCiQkTWVzb3JqYSQkDQoNCioqJE1lc29yamEkIG7DqyBzdGF0aXN0aWtlIGVzaHRlIG5qZSBtYXNlIHFlbmRyb3JlIGUgY2lsYSBwYXJhcWV0IHZsZXJlbiBlIG1lc21lIG9zZSB2bGVyZW4gcWUgbmRhbiBuamUgZ3J1cCB0ZSBkaGVuZSB0ZSB0ZSBkaGVuYXZlIG5lIGR5IHBqZXNlIHRlIGJhcmFiYXJ0YS4gTmVua3VwdG9uIHFlIGdqeXNtYSBlIHRlIGRoZW5hdmUgamFuZSBtZSB0ZSBtZWRoYSBzZSBtZXNvcmphIGRoZSBnanlzbWEgdGpldGVyIGphbmUgbWUgdGUgdm9nbGEuKioNCg0KKipNZXNvcmphIGxsb2dhcml0ZXQgZHVrZSBlIHJlbmRpdHVyIGdydXBpbiBlIHTDqyBkaGVuYXZlIG5lIHJyYWRoZSB0ZSBycml0amVzIHNlIHZsZXJhdmUgZGhlIGR1a2UgZ2pldHVyIHZsZXJlbiBxZSBuZG9kaGV0IG5lIG1lc2luIGUgdHlyZS4gTmVzZSBudW1yaSBpIHRlIGRoZW5hdmUgZXNodGUgw6dpZnQsIGF0ZWhlcmUgbWVzb3JqYSBlc2h0ZSB2bGVyYSBlIG1lc21lIGUgZHkgdmxlcmF2ZSB0w6sgcWVuZHJ1YXJhLiBOZXNlIG51bXJpIGkgdGUgZGhlbmF2ZSBlc2h0ZSB0ZWssIGF0ZWhlcmUgbWVzb3JqYSBlc2h0ZSB2bGVyYSBlIHZldG1lIHFlIG5kb2RoZXQgbmUgbWVzIHRlIGdydXBpdC4qKg0KDQoqKkdqZWptZSBtZXNvcmVuIHBlciBzZWNpbGVuIG5kcnlzaG9yZSBzYXNpb3JlIG1lIGFuZSB0ZSBmdW5rc2lvbml0ICRtZWRpYW4oKSQ6KioNCg0KKipNZXNvcmphIGUgbW9zaGVzOioqDQpgYGB7cn0NCm1lZGlhbl9tb3NoYSA8LSBtZWRpYW4oZGF0YSRtb3NoYSkNCnByaW50KG1lZGlhbl9tb3NoYSkNCmBgYA0KDQoqKk1lc29yamEgZSB0ZSBhcmRodXJhdmUgbXVqb3JlOioqDQpgYGB7cn0NCm1lZGlhbl90ZV9hcmRodXJhdF9tdWpvcmUgPC0gbWVkaWFuKGRhdGEkdGVfYXJkaHVyYXRfbXVqb3JlKQ0KcHJpbnQobWVkaWFuX3RlX2FyZGh1cmF0X211am9yZSkNCmBgYA0KDQoqKk1lc29yamEgZSBuZGlobWVzIGZpbmFuY2lhcmU6KioNCmBgYHtyfQ0KbWVkaWFuX25kaWhtYV9maW5hbmNpYXJlIDwtIG1lZGlhbihkYXRhJG5kaWhtYV9maW5hbmNpYXJlKQ0KcHJpbnQobWVkaWFuX25kaWhtYV9maW5hbmNpYXJlKQ0KYGBgDQoNCioqTWVzb3JqYSBlIHNodW1hdmUgdGUgc2hwZW56dWFyYSBwZXIgc2hrb2xsaW06KioNCmBgYHtyfQ0KbWVkaWFuX3Noa29sbGltaSA8LSBtZWRpYW4oZGF0YSRzaGtvbGxpbWkpDQpwcmludChtZWRpYW5fc2hrb2xsaW1pKQ0KYGBgDQoNCioqTWVzb3JqYSBlIHNodW1hdmUgdGUgc2hwZW56dWFyYSBwZXIgc3RyZWhpbToqKg0KYGBge3J9DQptZWRpYW5fc3RyZWhpbWkgPC0gbWVkaWFuKGRhdGEkc3RyZWhpbWkpDQpwcmludChtZWRpYW5fc3RyZWhpbWkpDQpgYGANCg0KKipNZXNvcmphIGUgc2h1bWF2ZSB0ZSBzaHBlbnp1YXJhIHBlciB1c2hxaW06KioNCmBgYHtyfQ0KbWVkaWFuX3VzaHFpbWkgPC0gbWVkaWFuKGRhdGEkdXNocWltaSkNCnByaW50KG1lZGlhbl91c2hxaW1pKQ0KYGBgDQoNCioqTWVzb3JqYSBlIHNodW1hdmUgdGUgc2hwZW56dWFyYSBwZXIgdHJhbnNwb3J0OioqDQpgYGB7cn0NCm1lZGlhbl90cmFuc3BvcnRpIDwtIG1lZGlhbihkYXRhJHRyYW5zcG9ydGkpDQpwcmludChtZWRpYW5fdHJhbnNwb3J0aSkNCmBgYA0KDQoqKk1lc29yamEgZSBzaHVtYXZlIHRlIHNocGVuenVhcmEgcGVyIG1qZXRlIHNoa29sbG9yZToqKg0KYGBge3J9DQptZWRpYW5fbWpldGV0X3Noa29sbG9yZSA8LSBtZWRpYW4oZGF0YSRtamV0ZXRfc2hrb2xsb3JlKQ0KcHJpbnQobWVkaWFuX21qZXRldF9zaGtvbGxvcmUpDQpgYGANCg0KKipNZXNvcmphIGUgc2h1bWF2ZSB0ZSBzaHBlbnp1YXJhIHBlciBhcmdldGltOioqDQpgYGB7cn0NCm1lZGlhbl9hcmdldGltIDwtIG1lZGlhbihkYXRhJGFyZ2V0aW0pDQpwcmludChtZWRpYW5fYXJnZXRpbSkNCmBgYA0KDQoqKk1lc29yamEgZSBzaHVtYXZlIHRlIHNocGVuenVhcmEgcGVyIGt1amRlcyBwZXJzb25hbDoqKg0KYGBge3J9DQptZWRpYW5fa3VqZGVzaV9wZXJzb25hbCA8LSBtZWRpYW4oZGF0YSRrdWpkZXNpX3BlcnNvbmFsKQ0KcHJpbnQobWVkaWFuX2t1amRlc2lfcGVyc29uYWwpDQpgYGANCg0KKipNZXNvcmphIGUgc2h1bWF2ZSB0ZSBzaHBlbnp1YXJhIG5lIGZ1c2hlbiBlIHRla25vbG9namlzZToqKg0KYGBge3J9DQptZWRpYW5fdGVrbm9sb2dqaSA8LSBtZWRpYW4oZGF0YSR0ZWtub2xvZ2ppKQ0KcHJpbnQobWVkaWFuX3Rla25vbG9namkpDQpgYGANCg0KKipNZXNvcmphIGUgc2h1bWF2ZSB0ZSBzaHBlbnp1YXJhIHBlciBtaXJlcWVuaWVuIHNoZW5kZXRlc29yZToqKg0KYGBge3J9DQptZWRpYW5fbWlyZXFlbmlhX3NoZW5kZXRlc29yZSA8LSBtZWRpYW4oZGF0YSRtaXJlcWVuaWFfc2hlbmRldGVzb3JlKQ0KcHJpbnQobWVkaWFuX21pcmVxZW5pYV9zaGVuZGV0ZXNvcmUpDQpgYGANCg0KKipNZXNvcmphIGUgc2h1bWF2ZSB0ZSBzaHBlbnp1YXJhIHBlciBzaHBlbnppbWUgdGUgdGplcmEgdGUgbmRyeXNobWU6KioNCmBgYHtyfQ0KbWVkaWFuX3RlX25kcnlzaG1lIDwtIG1lZGlhbihkYXRhJHRlX25kcnlzaG1lKQ0KcHJpbnQobWVkaWFuX3RlX25kcnlzaG1lKQ0KYGBgDQoNCiQkS3VhcnRpbGV0JCQNCg0KKiokS3VhcnRpbGV0JCBuZSBzdGF0aXN0aWtlIGphbmUgdmxlcmF0IHFlIG5kYWpuZSBuamUgZ3J1cCB0ZSB0ZSBkaGVuYXZlIG5lIGthdGVyIHBqZXNlIHRlIGJhcmFiYXJ0YS4gS2V0byBwamVzZSBwZXJiZWhlbiBuZ2EgMjUlIHRlIHRlIGRoZW5hdmUgdGUgcmVuZGl0dXJhIG5lIHJyYWRoZSB0ZSBycml0amVzIHNlIHR5cmUuKioNCg0KKipLdWFydGlsZXQgcGVyZG9yZW4gcGVyIHRlIHZsZXJlc3VhciBzaHBlcm5kYXJqZW4gZSB0ZSBkaGVuYXZlIGRoZSBwZXIgdGUgaWRlbnRpZmlrdWFyIHZsZXJhdCBlIHJlbmRlc2lzaG1lIG5lIGdydXAuIEtldHUgamFuZSB0cmUgbGxvamUga3VhcnRpbGVzaCB0ZSB6YWtvbnNobWU6KioNCg0KKioxLiBLdWFydGlsaSBpIHBhcmUgJFExJCBlc2h0ZSB2bGVyYSBxZSBuZGFuIDI1JSB0ZSB0ZSBkaGVuYXZlIG1lIHRlIHZvZ2xhIG5nYSBncnVwaSBpIHRlIGRoZW5hdmUgdGUgcmVuZGl0dXJhLiBOZW5rdXB0b24gc2UgMjUlIGUgdGUgZGhlbmF2ZSBqYW5lIG1lIHRlIHZvZ2xhIHNlIGt1YXJ0aWxpIGkgcGFyZSBkaGUgNzUlIGphbmUgbWUgdGUgbWVkaGEgc2Uga2pvIHZsZXJlLioqDQoNCioqMi4gS3VhcnRpbGkgaSBkeXRlIG9zZSBtZXNpICRRMiQgZXNodGUgdmxlcmEgcWUgbmRhbiBncnVwaW4gZSB0ZSBkaGVuYXZlIG5lIGR5IHBqZXNlIHRlIGJhcmFiYXJ0YS4gTmplcmVuIGdqeXNtZSBtZSB2bGVyYXQgbWUgdGUgdm9nbGEgZGhlIGdqeXNtZW4gdGpldGVyIG1lIHZsZXJhdCBtZSB0ZSBtZWRoYS4qKg0KDQoqKjMuIEt1YXJ0aWxpIGkgdHJldGUgJFEzJCBlc2h0ZSB2bGVyYSBxZSBuZGFuIDc1JSB0ZSB0ZSBkaGVuYXZlIG1lIHRlIG1lZGhhIG5nYSBncnVwaSBpIHRlIGRoZW5hdmUgdGUgcmVuZGl0dXJhLiBLam8gbmVua3VwdG9uIHNlIDc1JSBlIHRlIGRoZW5hdmUgamFuZSBtZSB0ZSB2b2dsYSBzZSBrdWFydGlsaSBpIHRyZXRlIGRoZSAyNSUgamFuZSBtZSB0ZSBtZWRoYS4qKg0KDQoqKkxlIHRlIGxsb2dhcml0aW0ga3VhcnRpbGV0IG1lIGFuZSB0ZSBmdW5rc2lvbml0ICRxdWFudGlsZSgpJCBkaGUgaW50ZXJ2YWxldCBuZGVya3VhcnRpbG9yZSBwZXIgc2VjaWxlbiBuZHJ5c2hvcmUgc2FzaW9yZSBtZSBhbmUgdGUgZnVua3Npb25pdCAkSVFSKCkkOioqDQoNCioqS3VhcnRpbGV0IGUgbW9zaGVzOioqDQpgYGB7cn0NCnE3NSA8LSBxdWFudGlsZShkYXRhJG1vc2hhLCAwLjc1KSAgDQpxMjUgPC0gcXVhbnRpbGUoZGF0YSRtb3NoYSwgMC4yNSkgDQpxdWFudGlsZShkYXRhJG1vc2hhKQ0KSVFSKGRhdGEkbW9zaGEpDQpgYGANCg0KKipLeSByZXp1bHRhdCB0cmVnb24gdmxlcmF0IHBlcmthdGVzZSB0ZSBrdWFudGlsZXZlIHBlciBrb2xvbmVuICJtb3NoYSIgbmUgZGF0YXNldDoqKg0KDQoqKuKAogkwJTogVmxlcmEgbWluaW1hbGUgZSB0ZSBkaGVuYXZlIGVzaHRlIDE4LioqDQoNCioq4oCiCTI1JTogS2pvIGVzaHRlIHZsZXJhIGUga3VhbnRpbGl0IHRlIDI1JSwgcWUgbmUga2V0ZSByYXN0IGVzaHRlIDIwLiBLam8gZG8gdGUgdGhvdGUgcWUgMjUlIGUgdGUgZGhlbmF2ZSBqYW5lIG1lIHRlIHZvZ2xhIG9zZSB0ZSBiYXJhYmFydGEgbWUga2V0ZSB2bGVyZS4qKg0KDQoqKuKAogk1MCU6IEtqbyBlc2h0ZSB2bGVyYSBxZW5kcm9yZSwgZSBuam9odXIgc2kgbWVzb3JqYSwgcWUgbmUga2V0ZSByYXN0IGVzaHRlIDIyLiBLam8gdHJlZ29uIHNlIDUwJSBlIHRlIGRoZW5hdmUgamFuZSBtZSB0ZSB2b2dsYSBvc2UgdGUgYmFyYWJhcnRhIG1lIGtldGUgdmxlcmUuKioNCg0KKirigKIJNzUlOiBLam8gZXNodGUgdmxlcmEgZSBrdWFudGlsaXQgdGUgNzUlLCBxZSBuZSBrZXRlIHJhc3QgZXNodGUgMjQuIEtqbyBkbyB0ZSB0aG90ZSBxZSA3NSUgZSB0ZSBkaGVuYXZlIGphbmUgbWUgdGUgdm9nbGEgb3NlIHRlIGJhcmFiYXJ0YSBtZSBrZXRlIHZsZXJlLioqDQoNCioq4oCiCTEwMCU6IFZsZXJhIG1ha3NpbWFsZSBlIHRlIGRoZW5hdmUgZXNodGUgMjUuKioNCg0KKipGdW5rc2lvbmkgSVFSIGFmaXNob24gdmxlcmVuIDQsIGtqbyBkbyB0ZSB0aG90ZSBzZSBkaWZlcmVuY2EgbWlkaXMga3VhbnRpbGl0IHRlIDI1JSBkaGUga3VhbnRpbGl0IHRlIDc1JSBlc2h0ZSA0LiBLam8gdHJlZ29uIHNlIDUwJSBlIHRlIGRoZW5hdmUgamFuZSB0ZSBwZXJoYXB1cmEgbmUgbmplIGludGVydmFsIHByZWogNCBuamVzaS4qKg0KDQoNCioqS3VhcnRpbGV0IGUgdGUgYXJkaHVyYXZlIG11am9yZToqKg0KYGBge3J9DQpxNzUgPC0gcXVhbnRpbGUoZGF0YSR0ZV9hcmRodXJhdF9tdWpvcmUsIDAuNzUpICANCnEyNSA8LSBxdWFudGlsZShkYXRhJHRlX2FyZGh1cmF0X211am9yZSwgMC4yNSkgDQpxdWFudGlsZShkYXRhJHRlX2FyZGh1cmF0X211am9yZSkNCklRUihkYXRhJHRlX2FyZGh1cmF0X211am9yZSkNCmBgYA0KDQoqKkt5IHJlenVsdGF0IHRyZWdvbiB2bGVyYXQgcGVya2F0ZXNlIHRlIGt1YW50aWxldmUgcGVyIGtvbG9uZW4gInRlX2FyZGh1cmF0X211am9yZSIgbmUgZGF0YXNldDoqKg0KDQoqKuKAogkwJTogVmxlcmEgbWluaW1hbGUgZSB0ZSBkaGVuYXZlIGVzaHRlIDUwMS4wMC4qKg0KDQoqKuKAogkyNSU6IEtqbyBlc2h0ZSB2bGVyYSBlIGt1YW50aWxpdCB0ZSAyNSUsIHFlIG5lIGtldGUgcmFzdCBlc2h0ZSA3NzAuNzUuIEtqbyBkbyB0ZSB0aG90ZSBxZSAyNSUgZSB0ZSBkaGVuYXZlIGphbmUgbWUgdGUgdm9nbGEgb3NlIHRlIGJhcmFiYXJ0YSBtZSBrZXRlIHZsZXJlLioqDQoNCioq4oCiCTUwJTogS2pvIGVzaHRlIHZsZXJhIHFlbmRyb3JlLCBlIG5qb2h1ciBzaSBtZXNvcmphLCBxZSBuZSBrZXRlIHJhc3QgZXNodGUgMTAyMS4wMC4gS2pvIHRyZWdvbiBzZSA1MCUgZSB0ZSBkaGVuYXZlIGphbmUgbWUgdGUgdm9nbGEgb3NlIHRlIGJhcmFiYXJ0YSBtZSBrZXRlIHZsZXJlLioqDQoNCioq4oCiCTc1JTogS2pvIGVzaHRlIHZsZXJhIGUga3VhbnRpbGl0IHRlIDc1JSwgcWUgbmUga2V0ZSByYXN0IGVzaHRlIDEyODguMjUuIEtqbyBkbyB0ZSB0aG90ZSBxZSA3NSUgZSB0ZSBkaGVuYXZlIGphbmUgbWUgdGUgdm9nbGEgb3NlIHRlIGJhcmFiYXJ0YSBtZSBrZXRlIHZsZXJlLioqDQoNCioq4oCiCTEwMCU6IFZsZXJhIG1ha3NpbWFsZSBlIHRlIGRoZW5hdmUgZXNodGUgMTUwMC4wMC4qKg0KDQoqKkZ1bmtzaW9uaSBJUVIgYWZpc2hvbiB2bGVyZW4gNTE3LjUsIGtqbyBkbyB0ZSB0aG90ZSBzZSBkaWZlcmVuY2EgbWlkaXMga3VhbnRpbGl0IHRlIDI1JSBkaGUga3VhbnRpbGl0IHRlIDc1JSBlc2h0ZSA1MTcuNS4gS2pvIHRyZWdvbiBzZSA1MCUgZSB0ZSBkaGVuYXZlIGphbmUgdGUgcGVyaGFwdXJhIG5lIG5qZSBpbnRlcnZhbCBwcmVqIDUxNy41IG5qZXNpLioqDQoNCg0KKipLdWFydGlsZXQgZSBuZGlobWF2ZSBmaW5hbmNpYXJlOioqDQpgYGB7cn0NCnE3NSA8LSBxdWFudGlsZShkYXRhJG5kaWhtYV9maW5hbmNpYXJlLCAwLjc1KSAgDQpxMjUgPC0gcXVhbnRpbGUoZGF0YSRuZGlobWFfZmluYW5jaWFyZSwgMC4yNSkgDQpxdWFudGlsZShkYXRhJG5kaWhtYV9maW5hbmNpYXJlKQ0KSVFSKGRhdGEkbmRpaG1hX2ZpbmFuY2lhcmUpDQpgYGANCg0KKipLeSByZXp1bHRhdCB0cmVnb24gdmxlcmF0IHBlcmthdGVzZSB0ZSBrdWFudGlsZXZlIHBlciBrb2xvbmVuICJuZGlobWFfZmluYW5jaWFyZSIgbmUgZGF0YXNldDoqKg0KDQoqKuKAogkwJTogVmxlcmEgbWluaW1hbGUgZSB0ZSBkaGVuYXZlIGVzaHRlIDAuMC4qKg0KDQoqKuKAogkyNSU6IEtqbyBlc2h0ZSB2bGVyYSBlIGt1YW50aWxpdCB0ZSAyNSUsIHFlIG5lIGtldGUgcmFzdCBlc2h0ZSAyNjEuMC4gS2pvIGRvIHRlIHRob3RlIHFlIDI1JSBlIHRlIGRoZW5hdmUgamFuZSBtZSB0ZSB2b2dsYSBvc2UgdGUgYmFyYWJhcnRhIG1lIGtldGUgdmxlcmUuKioNCg0KKirigKIJNTAlOiBLam8gZXNodGUgdmxlcmEgcWVuZHJvcmUsIGUgbmpvaHVyIHNpIG1lc29yamEsIHFlIG5lIGtldGUgcmFzdCBlc2h0ZSA1MTMuMC4gS2pvIHRyZWdvbiBzZSA1MCUgZSB0ZSBkaGVuYXZlIGphbmUgbWUgdGUgdm9nbGEgb3NlIHRlIGJhcmFiYXJ0YSBtZSBrZXRlIHZsZXJlLioqDQoNCioq4oCiCTc1JTogS2pvIGVzaHRlIHZsZXJhIGUga3VhbnRpbGl0IHRlIDc1JSwgcWUgbmUga2V0ZSByYXN0IGVzaHRlIDc1MS41LiBLam8gZG8gdGUgdGhvdGUgcWUgNzUlIGUgdGUgZGhlbmF2ZSBqYW5lIG1lIHRlIHZvZ2xhIG9zZSB0ZSBiYXJhYmFydGEgbWUga2V0ZSB2bGVyZS4qKg0KDQoqKuKAogkxMDAlOiBWbGVyYSBtYWtzaW1hbGUgZSB0ZSBkaGVuYXZlIGVzaHRlIDEwMDAuMDAuKioNCg0KKipGdW5rc2lvbmkgSVFSIGFmaXNob24gdmxlcmVuIDQ5MC41LCBram8gZG8gdGUgdGhvdGUgc2UgZGlmZXJlbmNhIG1pZGlzIGt1YW50aWxpdCB0ZSAyNSUgZGhlIGt1YW50aWxpdCB0ZSA3NSUgZXNodGUgNDkwLjUuIEtqbyB0cmVnb24gc2UgNTAlIGUgdGUgZGhlbmF2ZSBqYW5lIHRlIHBlcmhhcHVyYSBuZSBuamUgaW50ZXJ2YWwgcHJlaiA0OTAuNSBuamVzaS4qKg0KDQoNCioqS3VhcnRpbGV0IGUgc2h1bWF2ZSB0ZSBzaHBlbnp1YXJhIG5kYWogc2hrb2xsaW1pdDoqKg0KYGBge3J9DQpxNzUgPC0gcXVhbnRpbGUoZGF0YSRzaGtvbGxpbWksIDAuNzUpICANCnEyNSA8LSBxdWFudGlsZShkYXRhJHNoa29sbGltaSwgMC4yNSkgDQpxdWFudGlsZShkYXRhJHNoa29sbGltaSkNCklRUihkYXRhJHNoa29sbGltaSkNCmBgYA0KKipLeSByZXp1bHRhdCB0cmVnb24gdmxlcmF0IHBlcmthdGVzZSB0ZSBrdWFudGlsZXZlIHBlciBrb2xvbmVuICJzaGtvbGxpbWkiIG5lIGRhdGFzZXQ6KioNCg0KKirigKIJMCU6IFZsZXJhIG1pbmltYWxlIGUgdGUgZGhlbmF2ZSBlc2h0ZSAzMDAzLjAwLioqDQoNCioq4oCiCTI1JTogS2pvIGVzaHRlIHZsZXJhIGUga3VhbnRpbGl0IHRlIDI1JSwgcWUgbmUga2V0ZSByYXN0IGVzaHRlIDM3NzkuNzUuIEtqbyBkbyB0ZSB0aG90ZSBxZSAyNSUgZSB0ZSBkaGVuYXZlIGphbmUgbWUgdGUgdm9nbGEgb3NlIHRlIGJhcmFiYXJ0YSBtZSBrZXRlIHZsZXJlLioqDQoNCioq4oCiCTUwJTogS2pvIGVzaHRlIHZsZXJhIHFlbmRyb3JlLCBlIG5qb2h1ciBzaSBtZXNvcmphLCBxZSBuZSBrZXRlIHJhc3QgZXNodGUgNDU0Ny41MC4gS2pvIHRyZWdvbiBzZSA1MCUgZSB0ZSBkaGVuYXZlIGphbmUgbWUgdGUgdm9nbGEgb3NlIHRlIGJhcmFiYXJ0YSBtZSBrZXRlIHZsZXJlLioqDQoNCioq4oCiCTc1JTogS2pvIGVzaHRlIHZsZXJhIGUga3VhbnRpbGl0IHRlIDc1JSwgcWUgbmUga2V0ZSByYXN0IGVzaHRlIDUyODUuMDAuIEtqbyBkbyB0ZSB0aG90ZSBxZSA3NSUgZSB0ZSBkaGVuYXZlIGphbmUgbWUgdGUgdm9nbGEgb3NlIHRlIGJhcmFiYXJ0YSBtZSBrZXRlIHZsZXJlLioqDQoNCioq4oCiCTEwMCU6IFZsZXJhIG1ha3NpbWFsZSBlIHRlIGRoZW5hdmUgZXNodGUgNjAwMC4wMC4qKg0KDQoqKkZ1bmtzaW9uaSBJUVIgYWZpc2hvbiB2bGVyZW4gMTUwNS4yNSwga2pvIGRvIHRlIHRob3RlIHNlIGRpZmVyZW5jYSBtaWRpcyBrdWFudGlsaXQgdGUgMjUlIGRoZSBrdWFudGlsaXQgdGUgNzUlIGVzaHRlIDE1MDUuMjUuIEtqbyB0cmVnb24gc2UgNTAlIGUgdGUgZGhlbmF2ZSBqYW5lIHRlIHBlcmhhcHVyYSBuZSBuamUgaW50ZXJ2YWwgcHJlaiAxNTA1LjI1IG5qZXNpLioqDQoNCg0KKipLdWFydGlsZXQgZSBzaHVtYXZlIHRlIHNocGVuenVhcmEgbmRhaiBzdHJlaGltaXQ6KioNCmBgYHtyfQ0KcTc1IDwtIHF1YW50aWxlKGRhdGEkc3RyZWhpbWksIDAuNzUpICANCnEyNSA8LSBxdWFudGlsZShkYXRhJHN0cmVoaW1pLCAwLjI1KSANCnF1YW50aWxlKGRhdGEkc3RyZWhpbWkpDQpJUVIoZGF0YSRzdHJlaGltaSkNCmBgYA0KKipLeSByZXp1bHRhdCB0cmVnb24gdmxlcmF0IHBlcmthdGVzZSB0ZSBrdWFudGlsZXZlIHBlciBrb2xvbmVuICJzdHJlaGltaSIgbmUgZGF0YXNldDoqKg0KDQoqKuKAogkwJTogVmxlcmEgbWluaW1hbGUgZSB0ZSBkaGVuYXZlIGVzaHRlIDQwMS4wMC4qKg0KDQoqKuKAogkyNSU6IEtqbyBlc2h0ZSB2bGVyYSBlIGt1YW50aWxpdCB0ZSAyNSUsIHFlIG5lIGtldGUgcmFzdCBlc2h0ZSA1MzguNzUuIEtqbyBkbyB0ZSB0aG90ZSBxZSAyNSUgZSB0ZSBkaGVuYXZlIGphbmUgbWUgdGUgdm9nbGEgb3NlIHRlIGJhcmFiYXJ0YSBtZSBrZXRlIHZsZXJlLioqDQoNCioq4oCiCTUwJTogS2pvIGVzaHRlIHZsZXJhIHFlbmRyb3JlLCBlIG5qb2h1ciBzaSBtZXNvcmphLCBxZSBuZSBrZXRlIHJhc3QgZXNodGUgNzA0LjUwLiBLam8gdHJlZ29uIHNlIDUwJSBlIHRlIGRoZW5hdmUgamFuZSBtZSB0ZSB2b2dsYSBvc2UgdGUgYmFyYWJhcnRhIG1lIGtldGUgdmxlcmUuKioNCg0KKirigKIJNzUlOiBLam8gZXNodGUgdmxlcmEgZSBrdWFudGlsaXQgdGUgNzUlLCBxZSBuZSBrZXRlIHJhc3QgZXNodGUgODM3LjI1LiBLam8gZG8gdGUgdGhvdGUgcWUgNzUlIGUgdGUgZGhlbmF2ZSBqYW5lIG1lIHRlIHZvZ2xhIG9zZSB0ZSBiYXJhYmFydGEgbWUga2V0ZSB2bGVyZS4qKg0KDQoqKuKAogkxMDAlOiBWbGVyYSBtYWtzaW1hbGUgZSB0ZSBkaGVuYXZlIGVzaHRlIDEwMDAuMDAuKioNCg0KKipGdW5rc2lvbmkgSVFSIGFmaXNob24gdmxlcmVuIDI5OC41LCBram8gZG8gdGUgdGhvdGUgc2UgZGlmZXJlbmNhIG1pZGlzIGt1YW50aWxpdCB0ZSAyNSUgZGhlIGt1YW50aWxpdCB0ZSA3NSUgZXNodGUgMjk4LjUuIEtqbyB0cmVnb24gc2UgNTAlIGUgdGUgZGhlbmF2ZSBqYW5lIHRlIHBlcmhhcHVyYSBuZSBuamUgaW50ZXJ2YWwgcHJlaiAyOTguNSBuamVzaS4qKg0KDQoNCioqS3VhcnRpbGV0IGUgc2h1bWF2ZSB0ZSBzaHBlbnp1YXJhIG5kYWogdXNocWltaXQ6KioNCmBgYHtyfQ0KcTc1IDwtIHF1YW50aWxlKGRhdGEkdXNocWltaSwgMC43NSkgIA0KcTI1IDwtIHF1YW50aWxlKGRhdGEkdXNocWltaSwgMC4yNSkgDQpxdWFudGlsZShkYXRhJHVzaHFpbWkpDQpJUVIoZGF0YSR1c2hxaW1pKQ0KYGBgDQoqKkt5IHJlenVsdGF0IHRyZWdvbiB2bGVyYXQgcGVya2F0ZXNlIHRlIGt1YW50aWxldmUgcGVyIGtvbG9uZW4gInVzaHFpbWkiIG5lIGRhdGFzZXQ6KioNCg0KKirigKIJMCU6IFZsZXJhIG1pbmltYWxlIGUgdGUgZGhlbmF2ZSBlc2h0ZSAxMDAuKioNCg0KKirigKIJMjUlOiBLam8gZXNodGUgdmxlcmEgZSBrdWFudGlsaXQgdGUgMjUlLCBxZSBuZSBrZXRlIHJhc3QgZXNodGUgMTc1LiBLam8gZG8gdGUgdGhvdGUgcWUgMjUlIGUgdGUgZGhlbmF2ZSBqYW5lIG1lIHRlIHZvZ2xhIG9zZSB0ZSBiYXJhYmFydGEgbWUga2V0ZSB2bGVyZS4qKg0KDQoqKuKAogk1MCU6IEtqbyBlc2h0ZSB2bGVyYSBxZW5kcm9yZSwgZSBuam9odXIgc2kgbWVzb3JqYSwgcWUgbmUga2V0ZSByYXN0IGVzaHRlIDI1NS4gS2pvIHRyZWdvbiBzZSA1MCUgZSB0ZSBkaGVuYXZlIGphbmUgbWUgdGUgdm9nbGEgb3NlIHRlIGJhcmFiYXJ0YSBtZSBrZXRlIHZsZXJlLioqDQoNCioq4oCiCTc1JTogS2pvIGVzaHRlIHZsZXJhIGUga3VhbnRpbGl0IHRlIDc1JSwgcWUgbmUga2V0ZSByYXN0IGVzaHRlIDMzMC4gS2pvIGRvIHRlIHRob3RlIHFlIDc1JSBlIHRlIGRoZW5hdmUgamFuZSBtZSB0ZSB2b2dsYSBvc2UgdGUgYmFyYWJhcnRhIG1lIGtldGUgdmxlcmUuKioNCg0KKirigKIJMTAwJTogVmxlcmEgbWFrc2ltYWxlIGUgdGUgZGhlbmF2ZSBlc2h0ZSA0MDAuKioNCg0KKipGdW5rc2lvbmkgSVFSIGFmaXNob24gdmxlcmVuIDE1NSwga2pvIGRvIHRlIHRob3RlIHNlIGRpZmVyZW5jYSBtaWRpcyBrdWFudGlsaXQgdGUgMjUlIGRoZSBrdWFudGlsaXQgdGUgNzUlIGVzaHRlIDE1NS4gS2pvIHRyZWdvbiBzZSA1MCUgZSB0ZSBkaGVuYXZlIGphbmUgdGUgcGVyaGFwdXJhIG5lIG5qZSBpbnRlcnZhbCBwcmVqIDE1NSBuamVzaS4qKg0KDQoNCioqS3VhcnRpbGV0IGUgc2h1bWF2ZSB0ZSBzaHBlbnp1YXJhIG5kYWogIHRyYW5zcG9ydGl0OioqDQpgYGB7cn0NCnE3NSA8LSBxdWFudGlsZShkYXRhJHRyYW5zcG9ydGksIDAuNzUpICANCnEyNSA8LSBxdWFudGlsZShkYXRhJHRyYW5zcG9ydGksIDAuMjUpIA0KcXVhbnRpbGUoZGF0YSR0cmFuc3BvcnRpKQ0KSVFSKGRhdGEkdHJhbnNwb3J0aSkNCmBgYA0KKipLeSByZXp1bHRhdCB0cmVnb24gdmxlcmF0IHBlcmthdGVzZSB0ZSBrdWFudGlsZXZlIHBlciBrb2xvbmVuICJ0cmFuc3BvcnRpIiBuZSBkYXRhc2V0OioqDQoNCioq4oCiCTAlOiBWbGVyYSBtaW5pbWFsZSBlIHRlIGRoZW5hdmUgZXNodGUgNTAuMDAuKioNCg0KKirigKIJMjUlOiBLam8gZXNodGUgdmxlcmEgZSBrdWFudGlsaXQgdGUgMjUlLCBxZSBuZSBrZXRlIHJhc3QgZXNodGUgODguMDAuIEtqbyBkbyB0ZSB0aG90ZSBxZSAyNSUgZSB0ZSBkaGVuYXZlIGphbmUgbWUgdGUgdm9nbGEgb3NlIHRlIGJhcmFiYXJ0YSBtZSBrZXRlIHZsZXJlLioqDQoNCioq4oCiCTUwJTogS2pvIGVzaHRlIHZsZXJhIHFlbmRyb3JlLCBlIG5qb2h1ciBzaSBtZXNvcmphLCBxZSBuZSBrZXRlIHJhc3QgZXNodGUgMTIzLjAwLiBLam8gdHJlZ29uIHNlIDUwJSBlIHRlIGRoZW5hdmUgamFuZSBtZSB0ZSB2b2dsYSBvc2UgdGUgYmFyYWJhcnRhIG1lIGtldGUgdmxlcmUuKioNCg0KKirigKIJNzUlOiBLam8gZXNodGUgdmxlcmEgZSBrdWFudGlsaXQgdGUgNzUlLCBxZSBuZSBrZXRlIHJhc3QgZXNodGUgMTYyLjI1LiBLam8gZG8gdGUgdGhvdGUgcWUgNzUlIGUgdGUgZGhlbmF2ZSBqYW5lIG1lIHRlIHZvZ2xhIG9zZSB0ZSBiYXJhYmFydGEgbWUga2V0ZSB2bGVyZS4qKg0KDQoqKuKAogkxMDAlOiBWbGVyYSBtYWtzaW1hbGUgZSB0ZSBkaGVuYXZlIGVzaHRlIDIwMC4wMC4qKg0KDQoqKkZ1bmtzaW9uaSBJUVIgYWZpc2hvbiB2bGVyZW4gNzQuMjUsIGtqbyBkbyB0ZSB0aG90ZSBzZSBkaWZlcmVuY2EgbWlkaXMga3VhbnRpbGl0IHRlIDI1JSBkaGUga3VhbnRpbGl0IHRlIDc1JSBlc2h0ZSA3NC4yNS4gS2pvIHRyZWdvbiBzZSA1MCUgZSB0ZSBkaGVuYXZlIGphbmUgdGUgcGVyaGFwdXJhIG5lIG5qZSBpbnRlcnZhbCBwcmVqIDc0LjI1IG5qZXNpLioqDQoNCg0KKipLdWFydGlsZXQgZSBzaHVtYXZlIHRlIHNocGVuenVhcmEgbmRhaiBtamV0ZXZlIHNoa29sbG9yZToqKg0KYGBge3J9DQpxNzUgPC0gcXVhbnRpbGUoZGF0YSRtamV0ZXRfc2hrb2xsb3JlLCAwLjc1KSAgDQpxMjUgPC0gcXVhbnRpbGUoZGF0YSRtamV0ZXRfc2hrb2xsb3JlLCAwLjI1KSANCnF1YW50aWxlKGRhdGEkbWpldGV0X3Noa29sbG9yZSkNCklRUihkYXRhJG1qZXRldF9zaGtvbGxvcmUpDQpgYGANCioqS3kgcmV6dWx0YXQgdHJlZ29uIHZsZXJhdCBwZXJrYXRlc2UgdGUga3VhbnRpbGV2ZSBwZXIga29sb25lbiAibWpldGV0X3Noa29sbG9yZSIgbmUgZGF0YXNldDoqKg0KDQoqKuKAogkwJTogVmxlcmEgbWluaW1hbGUgZSB0ZSBkaGVuYXZlIGVzaHRlIDUwLjAwLioqDQoNCioq4oCiCTI1JTogS2pvIGVzaHRlIHZsZXJhIGUga3VhbnRpbGl0IHRlIDI1JSwgcWUgbmUga2V0ZSByYXN0IGVzaHRlIDExMi4gS2pvIGRvIHRlIHRob3RlIHFlIDI1JSBlIHRlIGRoZW5hdmUgamFuZSBtZSB0ZSB2b2dsYSBvc2UgdGUgYmFyYWJhcnRhIG1lIGtldGUgdmxlcmUuKioNCg0KKirigKIJNTAlOiBLam8gZXNodGUgdmxlcmEgcWVuZHJvcmUsIGUgbmpvaHVyIHNpIG1lc29yamEsIHFlIG5lIGtldGUgcmFzdCBlc2h0ZSAxNzUuIEtqbyB0cmVnb24gc2UgNTAlIGUgdGUgZGhlbmF2ZSBqYW5lIG1lIHRlIHZvZ2xhIG9zZSB0ZSBiYXJhYmFydGEgbWUga2V0ZSB2bGVyZS4qKg0KDQoqKuKAogk3NSU6IEtqbyBlc2h0ZSB2bGVyYSBlIGt1YW50aWxpdCB0ZSA3NSUsIHFlIG5lIGtldGUgcmFzdCBlc2h0ZSAyMzguIEtqbyBkbyB0ZSB0aG90ZSBxZSA3NSUgZSB0ZSBkaGVuYXZlIGphbmUgbWUgdGUgdm9nbGEgb3NlIHRlIGJhcmFiYXJ0YSBtZSBrZXRlIHZsZXJlLioqDQoNCioq4oCiCTEwMCU6IFZsZXJhIG1ha3NpbWFsZSBlIHRlIGRoZW5hdmUgZXNodGUgMzAwLioqDQoNCioqRnVua3Npb25pIElRUiBhZmlzaG9uIHZsZXJlbiAxMjYsIGtqbyBkbyB0ZSB0aG90ZSBzZSBkaWZlcmVuY2EgbWlkaXMga3VhbnRpbGl0IHRlIDI1JSBkaGUga3VhbnRpbGl0IHRlIDc1JSBlc2h0ZSAxMjYuIEtqbyB0cmVnb24gc2UgNTAlIGUgdGUgZGhlbmF2ZSBqYW5lIHRlIHBlcmhhcHVyYSBuZSBuamUgaW50ZXJ2YWwgcHJlaiAxMjYgbmplc2kuKioNCg0KDQoqKkt1YXJ0aWxldCBlIHNodW1hdmUgdGUgc2hwZW56dWFyYSBuZGFqIGFyZ2V0aW1pdDoqKg0KYGBge3J9DQpxNzUgPC0gcXVhbnRpbGUoZGF0YSRhcmdldGltLCAwLjc1KSAgDQpxMjUgPC0gcXVhbnRpbGUoZGF0YSRhcmdldGltLCAwLjI1KSANCnF1YW50aWxlKGRhdGEkYXJnZXRpbSkNCklRUihkYXRhJGFyZ2V0aW0pDQpgYGANCioqS3kgcmV6dWx0YXQgdHJlZ29uIHZsZXJhdCBwZXJrYXRlc2UgdGUga3VhbnRpbGV2ZSBwZXIga29sb25lbiAiYXJnZXRpbSIgbmUgZGF0YXNldDoqKg0KDQoqKuKAogkwJTogVmxlcmEgbWluaW1hbGUgZSB0ZSBkaGVuYXZlIGVzaHRlIDIwLioqDQoNCioq4oCiCTI1JTogS2pvIGVzaHRlIHZsZXJhIGUga3VhbnRpbGl0IHRlIDI1JSwgcWUgbmUga2V0ZSByYXN0IGVzaHRlIDU0LiBLam8gZG8gdGUgdGhvdGUgcWUgMjUlIGUgdGUgZGhlbmF2ZSBqYW5lIG1lIHRlIHZvZ2xhIG9zZSB0ZSBiYXJhYmFydGEgbWUga2V0ZSB2bGVyZS4qKg0KDQoqKuKAogk1MCU6IEtqbyBlc2h0ZSB2bGVyYSBxZW5kcm9yZSwgZSBuam9odXIgc2kgbWVzb3JqYSwgcWUgbmUga2V0ZSByYXN0IGVzaHRlIDg2LiBLam8gdHJlZ29uIHNlIDUwJSBlIHRlIGRoZW5hdmUgamFuZSBtZSB0ZSB2b2dsYSBvc2UgdGUgYmFyYWJhcnRhIG1lIGtldGUgdmxlcmUuKioNCg0KKirigKIJNzUlOiBLam8gZXNodGUgdmxlcmEgZSBrdWFudGlsaXQgdGUgNzUlLCBxZSBuZSBrZXRlIHJhc3QgZXNodGUgMTE2LiBLam8gZG8gdGUgdGhvdGUgcWUgNzUlIGUgdGUgZGhlbmF2ZSBqYW5lIG1lIHRlIHZvZ2xhIG9zZSB0ZSBiYXJhYmFydGEgbWUga2V0ZSB2bGVyZS4qKg0KDQoqKuKAogkxMDAlOiBWbGVyYSBtYWtzaW1hbGUgZSB0ZSBkaGVuYXZlIGVzaHRlIDE1MC4qKg0KDQoqKkZ1bmtzaW9uaSBJUVIgYWZpc2hvbiB2bGVyZW4gNjIsIGtqbyBkbyB0ZSB0aG90ZSBzZSBkaWZlcmVuY2EgbWlkaXMga3VhbnRpbGl0IHRlIDI1JSBkaGUga3VhbnRpbGl0IHRlIDc1JSBlc2h0ZSA2Mi4gS2pvIHRyZWdvbiBzZSA1MCUgZSB0ZSBkaGVuYXZlIGphbmUgdGUgcGVyaGFwdXJhIG5lIG5qZSBpbnRlcnZhbCBwcmVqIDYyIG5qZXNpLioqDQoNCioqS3VhcnRpbGV0IGUgc2h1bWF2ZSB0ZSBzaHBlbnp1YXJhIG5kYWoga3VqZGVzaXQgcGVyc29uYWw6KioNCmBgYHtyfQ0KcTc1IDwtIHF1YW50aWxlKGRhdGEka3VqZGVzaV9wZXJzb25hbCwgMC43NSkgIA0KcTI1IDwtIHF1YW50aWxlKGRhdGEka3VqZGVzaV9wZXJzb25hbCwgMC4yNSkgDQpxdWFudGlsZShkYXRhJGt1amRlc2lfcGVyc29uYWwpDQpJUVIoZGF0YSRrdWpkZXNpX3BlcnNvbmFsKQ0KYGBgDQoqKkt5IHJlenVsdGF0IHRyZWdvbiB2bGVyYXQgcGVya2F0ZXNlIHRlIGt1YW50aWxldmUgcGVyIGtvbG9uZW4gImt1amRlc2lfcGVyc29uYWwiIG5lIGRhdGFzZXQ6KioNCg0KKirigKIJMCU6IFZsZXJhIG1pbmltYWxlIGUgdGUgZGhlbmF2ZSBlc2h0ZSAyMC4qKg0KDQoqKuKAogkyNSU6IEtqbyBlc2h0ZSB2bGVyYSBlIGt1YW50aWxpdCB0ZSAyNSUsIHFlIG5lIGtldGUgcmFzdCBlc2h0ZSA0MS4gS2pvIGRvIHRlIHRob3RlIHFlIDI1JSBlIHRlIGRoZW5hdmUgamFuZSBtZSB0ZSB2b2dsYSBvc2UgdGUgYmFyYWJhcnRhIG1lIGtldGUgdmxlcmUuKioNCg0KKirigKIJNTAlOiBLam8gZXNodGUgdmxlcmEgcWVuZHJvcmUsIGUgbmpvaHVyIHNpIG1lc29yamEsIHFlIG5lIGtldGUgcmFzdCBlc2h0ZSA2Mi4gS2pvIHRyZWdvbiBzZSA1MCUgZSB0ZSBkaGVuYXZlIGphbmUgbWUgdGUgdm9nbGEgb3NlIHRlIGJhcmFiYXJ0YSBtZSBrZXRlIHZsZXJlLioqDQoNCioq4oCiCTc1JTogS2pvIGVzaHRlIHZsZXJhIGUga3VhbnRpbGl0IHRlIDc1JSwgcWUgbmUga2V0ZSByYXN0IGVzaHRlIDgwLiBLam8gZG8gdGUgdGhvdGUgcWUgNzUlIGUgdGUgZGhlbmF2ZSBqYW5lIG1lIHRlIHZvZ2xhIG9zZSB0ZSBiYXJhYmFydGEgbWUga2V0ZSB2bGVyZS4qKg0KDQoqKuKAogkxMDAlOiBWbGVyYSBtYWtzaW1hbGUgZSB0ZSBkaGVuYXZlIGVzaHRlIDEwMC4qKg0KDQoqKkZ1bmtzaW9uaSBJUVIgYWZpc2hvbiB2bGVyZW4gMzksIGtqbyBkbyB0ZSB0aG90ZSBzZSBkaWZlcmVuY2EgbWlkaXMga3VhbnRpbGl0IHRlIDI1JSBkaGUga3VhbnRpbGl0IHRlIDc1JSBlc2h0ZSAzOS4gS2pvIHRyZWdvbiBzZSA1MCUgZSB0ZSBkaGVuYXZlIGphbmUgdGUgcGVyaGFwdXJhIG5lIG5qZSBpbnRlcnZhbCBwcmVqIDM5IG5qZXNpLioqDQoNCg0KKipLdWFydGlsZXQgZSBzaHVtYXZlIHRlIHNocGVuenVhcmEgbmUgZnVzaGVuIGUgdGVrbm9sb2dqaXNlOioqDQpgYGB7cn0NCnE3NSA8LSBxdWFudGlsZShkYXRhJHRla25vbG9namksIDAuNzUpICANCnEyNSA8LSBxdWFudGlsZShkYXRhJHRla25vbG9namksIDAuMjUpIA0KcXVhbnRpbGUoZGF0YSR0ZWtub2xvZ2ppKQ0KSVFSKGRhdGEkdGVrbm9sb2dqaSkNCmBgYA0KKipLeSByZXp1bHRhdCB0cmVnb24gdmxlcmF0IHBlcmthdGVzZSB0ZSBrdWFudGlsZXZlIHBlciBrb2xvbmVuICJ0ZWtub2xvZ2ppIiBuZSBkYXRhc2V0OioqDQoNCioq4oCiCTAlOiBWbGVyYSBtaW5pbWFsZSBlIHRlIGRoZW5hdmUgZXNodGUgNTAuKioNCg0KKirigKIJMjUlOiBLam8gZXNodGUgdmxlcmEgZSBrdWFudGlsaXQgdGUgMjUlLCBxZSBuZSBrZXRlIHJhc3QgZXNodGUgMTE0LiBLam8gZG8gdGUgdGhvdGUgcWUgMjUlIGUgdGUgZGhlbmF2ZSBqYW5lIG1lIHRlIHZvZ2xhIG9zZSB0ZSBiYXJhYmFydGEgbWUga2V0ZSB2bGVyZS4qKg0KDQoqKuKAogk1MCU6IEtqbyBlc2h0ZSB2bGVyYSBxZW5kcm9yZSwgZSBuam9odXIgc2kgbWVzb3JqYSwgcWUgbmUga2V0ZSByYXN0IGVzaHRlIDE3OC4gS2pvIHRyZWdvbiBzZSA1MCUgZSB0ZSBkaGVuYXZlIGphbmUgbWUgdGUgdm9nbGEgb3NlIHRlIGJhcmFiYXJ0YSBtZSBrZXRlIHZsZXJlLioqDQoNCioq4oCiCTc1JTogS2pvIGVzaHRlIHZsZXJhIGUga3VhbnRpbGl0IHRlIDc1JSwgcWUgbmUga2V0ZSByYXN0IGVzaHRlIDI0MS4gS2pvIGRvIHRlIHRob3RlIHFlIDc1JSBlIHRlIGRoZW5hdmUgamFuZSBtZSB0ZSB2b2dsYSBvc2UgdGUgYmFyYWJhcnRhIG1lIGtldGUgdmxlcmUuKioNCg0KKirigKIJMTAwJTogVmxlcmEgbWFrc2ltYWxlIGUgdGUgZGhlbmF2ZSBlc2h0ZSAzMDAuKioNCg0KKipGdW5rc2lvbmkgSVFSIGFmaXNob24gdmxlcmVuIDEyNywga2pvIGRvIHRlIHRob3RlIHNlIGRpZmVyZW5jYSBtaWRpcyBrdWFudGlsaXQgdGUgMjUlIGRoZSBrdWFudGlsaXQgdGUgNzUlIGVzaHRlIDEyNy4gS2pvIHRyZWdvbiBzZSA1MCUgZSB0ZSBkaGVuYXZlIGphbmUgdGUgcGVyaGFwdXJhIG5lIG5qZSBpbnRlcnZhbCBwcmVqIDEyNyBuamVzaS4qKg0KDQoNCioqS3VhcnRpbGV0IGUgc2h1bWF2ZSB0ZSBzaHBlbnp1YXJhIG5kYWogbWlyZXFlbmllcyBzaGVuZGV0ZXNvcmU6KioNCmBgYHtyfQ0KcTc1IDwtIHF1YW50aWxlKGRhdGEkbWlyZXFlbmlhX3NoZW5kZXRlc29yZSwgMC43NSkgIA0KcTI1IDwtIHF1YW50aWxlKGRhdGEkbWlyZXFlbmlhX3NoZW5kZXRlc29yZSwgMC4yNSkgDQpxdWFudGlsZShkYXRhJG1pcmVxZW5pYV9zaGVuZGV0ZXNvcmUpDQpJUVIoZGF0YSRtaXJlcWVuaWFfc2hlbmRldGVzb3JlKQ0KYGBgDQoqKkt5IHJlenVsdGF0IHRyZWdvbiB2bGVyYXQgcGVya2F0ZXNlIHRlIGt1YW50aWxldmUgcGVyIGtvbG9uZW4gIm1pcmVxZW5pYV9zaGVuZGV0ZXNvcmUiIG5lIGRhdGFzZXQ6KioNCg0KKirigKIJMCU6IFZsZXJhIG1pbmltYWxlIGUgdGUgZGhlbmF2ZSBlc2h0ZSAzMCoqDQoNCioq4oCiCTI1JTogS2pvIGVzaHRlIHZsZXJhIGUga3VhbnRpbGl0IHRlIDI1JSwgcWUgbmUga2V0ZSByYXN0IGVzaHRlIDczLiBLam8gZG8gdGUgdGhvdGUgcWUgMjUlIGUgdGUgZGhlbmF2ZSBqYW5lIG1lIHRlIHZvZ2xhIG9zZSB0ZSBiYXJhYmFydGEgbWUga2V0ZSB2bGVyZS4qKg0KDQoqKuKAogk1MCU6IEtqbyBlc2h0ZSB2bGVyYSBxZW5kcm9yZSwgZSBuam9odXIgc2kgbWVzb3JqYSwgcWUgbmUga2V0ZSByYXN0IGVzaHRlIDExNS4gS2pvIHRyZWdvbiBzZSA1MCUgZSB0ZSBkaGVuYXZlIGphbmUgbWUgdGUgdm9nbGEgb3NlIHRlIGJhcmFiYXJ0YSBtZSBrZXRlIHZsZXJlLioqDQoNCioq4oCiCTc1JTogS2pvIGVzaHRlIHZsZXJhIGUga3VhbnRpbGl0IHRlIDc1JSwgcWUgbmUga2V0ZSByYXN0IGVzaHRlIDE1OC4gS2pvIGRvIHRlIHRob3RlIHFlIDc1JSBlIHRlIGRoZW5hdmUgamFuZSBtZSB0ZSB2b2dsYSBvc2UgdGUgYmFyYWJhcnRhIG1lIGtldGUgdmxlcmUuKioNCg0KKirigKIJMTAwJTogVmxlcmEgbWFrc2ltYWxlIGUgdGUgZGhlbmF2ZSBlc2h0ZSAyMDAuKioNCg0KKipGdW5rc2lvbmkgSVFSIGFmaXNob24gdmxlcmVuIDg1LCBram8gZG8gdGUgdGhvdGUgc2UgZGlmZXJlbmNhIG1pZGlzIGt1YW50aWxpdCB0ZSAyNSUgZGhlIGt1YW50aWxpdCB0ZSA3NSUgZXNodGUgODUuIEtqbyB0cmVnb24gc2UgNTAlIGUgdGUgZGhlbmF2ZSBqYW5lIHRlIHBlcmhhcHVyYSBuZSBuamUgaW50ZXJ2YWwgcHJlaiA4NSBuamVzaS4qKg0KDQoNCioqS3VhcnRpbGV0IGUgc2h1bWF2ZSB0ZSBzaHBlbnp1YXJhIG5kYWogc2hwZW56aW1ldmUgdGUgdGplcmEgdGUgbmRyeXNobWU6KioNCmBgYHtyfQ0KcTc1IDwtIHF1YW50aWxlKGRhdGEkdGVfbmRyeXNobWUsIDAuNzUpICANCnEyNSA8LSBxdWFudGlsZShkYXRhJHRlX25kcnlzaG1lLCAwLjI1KSANCnF1YW50aWxlKGRhdGEkdGVfbmRyeXNobWUpDQpJUVIoZGF0YSR0ZV9uZHJ5c2htZSkNCmBgYA0KKipLeSByZXp1bHRhdCB0cmVnb24gdmxlcmF0IHBlcmthdGVzZSB0ZSBrdWFudGlsZXZlIHBlciBrb2xvbmVuICJ0ZV9uZHJ5c2htZSIgbmUgZGF0YXNldDoqKg0KDQoqKuKAogkwJTogVmxlcmEgbWluaW1hbGUgZSB0ZSBkaGVuYXZlIGVzaHRlIDIwLjAwKioNCg0KKirigKIJMjUlOiBLam8gZXNodGUgdmxlcmEgZSBrdWFudGlsaXQgdGUgMjUlLCBxZSBuZSBrZXRlIHJhc3QgZXNodGUgNjMuNzUuIEtqbyBkbyB0ZSB0aG90ZSBxZSAyNSUgZSB0ZSBkaGVuYXZlIGphbmUgbWUgdGUgdm9nbGEgb3NlIHRlIGJhcmFiYXJ0YSBtZSBrZXRlIHZsZXJlLioqDQoNCioq4oCiCTUwJTogS2pvIGVzaHRlIHZsZXJhIHFlbmRyb3JlLCBlIG5qb2h1ciBzaSBtZXNvcmphLCBxZSBuZSBrZXRlIHJhc3QgZXNodGUgMTEwLjAwLiBLam8gdHJlZ29uIHNlIDUwJSBlIHRlIGRoZW5hdmUgamFuZSBtZSB0ZSB2b2dsYSBvc2UgdGUgYmFyYWJhcnRhIG1lIGtldGUgdmxlcmUuKioNCg0KKirigKIJNzUlOiBLam8gZXNodGUgdmxlcmEgZSBrdWFudGlsaXQgdGUgNzUlLCBxZSBuZSBrZXRlIHJhc3QgZXNodGUgMTUzLjAwLiBLam8gZG8gdGUgdGhvdGUgcWUgNzUlIGUgdGUgZGhlbmF2ZSBqYW5lIG1lIHRlIHZvZ2xhIG9zZSB0ZSBiYXJhYmFydGEgbWUga2V0ZSB2bGVyZS4qKg0KDQoqKuKAogkxMDAlOiBWbGVyYSBtYWtzaW1hbGUgZSB0ZSBkaGVuYXZlIGVzaHRlIDIwMC4wMC4qKg0KDQoqKkZ1bmtzaW9uaSBJUVIgYWZpc2hvbiB2bGVyZW4gODkuMjUsIGtqbyBkbyB0ZSB0aG90ZSBzZSBkaWZlcmVuY2EgbWlkaXMga3VhbnRpbGl0IHRlIDI1JSBkaGUga3VhbnRpbGl0IHRlIDc1JSBlc2h0ZSA4OS4yNS4gS2pvIHRyZWdvbiBzZSA1MCUgZSB0ZSBkaGVuYXZlIGphbmUgdGUgcGVyaGFwdXJhIG5lIG5qZSBpbnRlcnZhbCBwcmVqIDg5LjI1IG5qZXNpLioqDQoNCg0KJCRWbGVyYXRcIEVrc3RyZW1hbGU6XCBNYXhpbXVtLFwgTWluaW11bSQkDQoNCiokVmxlcmF0JCAkZWtzdHJlbWFsZSQgJG1pbiwkICRtYXg7JCAkaW5kZWtzZXQkICRwZXJrYXRlc2U7JCAkQW1wbGl0dWRhOyQqDQoNCioqR2pldGphIGUgdmxlcmVzIG1ha3NpbWFsZSBkbyB0ZSBrcnloZXQgbWUgYW5lIHRlIGZ1bmtzaW9uaXQgJG1heCgpJCwgZ2pldGphIGUgdmxlcmVzIG1pbmltYWxlIGRvIHRlIGtyeWhldCBtZSBhbmUgdGUgZnVua3Npb25pdCAkbWluKCkkIG5kZXJzYSBwb3ppY2lvbmV0IHBlcmthdGVzZSBkbyB0ZSBnamVuZGVuIG1lIGFuZSB0ZSBmdW5rc2lvbml0ICR3aGljaC5tYXgoKSQgZGhlICR3aGljaC5taW4oKSQuKioNCg0KKipHamV0amEgZSB2bGVyZXMgbWFrc2ltYWxlIGRoZSBwb3ppY2lvbml0IHRlIHNhaiBuZSBrb2xvbmUgcGVyIHZhcmlhYmxpbiAkbW9zaGE6JCoqDQoNCioqVmxlcmEgbWFrc2ltYWxlOioqDQpgYGB7cn0NCm1heF92YWx1ZXMgPC0gbWF4KGRhdGEkbW9zaGEpDQpwcmludChtYXhfdmFsdWVzKQ0KYGBgDQoNCioqUG96aWNpb25pIG5lIGtvbG9uZToqKg0KYGBge3J9DQpwb3ppY2lvbmkgPC0gd2hpY2gubWluKGRhdGEkbW9zaGEpIA0KcHJpbnQocG96aWNpb25pLTEpDQpgYGANCg0KKipHamV0amEgZSB2bGVyZXMgbWFrc2ltYWxlIGRoZSBwb3ppY2lvbml0IHRlIHNhaiBuZSBrb2xvbmUgcGVyIHZhcmlhYmxpbiAkdGUkICRhcmRodXJhdCQgJG11am9yZTokKioNCg0KKipWbGVyYSBtYWtzaW1hbGU6KioNCmBgYHtyfQ0KbWF4X3ZhbHVlcyA8LSBtYXgoZGF0YSR0ZV9hcmRodXJhdF9tdWpvcmUpDQpwcmludChtYXhfdmFsdWVzKQ0KYGBgDQoNCioqUG96aWNpb25pIG5lIGtvbG9uZToqKg0KYGBge3J9DQpwb3ppY2lvbmkgPC0gd2hpY2gubWF4KGRhdGEkdGVfYXJkaHVyYXRfbXVqb3JlKSANCnByaW50KHBvemljaW9uaS0xKQ0KYGBgDQoNCioqR2pldGphIGUgdmxlcmVzIG1ha3NpbWFsZSBkaGUgcG96aWNpb25pdCB0ZSBzYWogbmUga29sb25lIHBlciB2YXJpYWJsaW4gJG5kaWhtYSQgJGZpbmFuY2lhcmU6JCoqDQoNCioqVmxlcmEgbWFrc2ltYWxlOioqDQpgYGB7cn0NCm1heF92YWx1ZXMgPC0gbWF4KGRhdGEkbmRpaG1hX2ZpbmFuY2lhcmUpDQpwcmludChtYXhfdmFsdWVzKQ0KYGBgDQoNCioqUG96aWNpb25pIG5lIGtvbG9uZToqKg0KYGBge3J9DQpwb3ppY2lvbmkgPC0gd2hpY2gubWF4KGRhdGEkbmRpaG1hX2ZpbmFuY2lhcmUpIA0KcHJpbnQocG96aWNpb25pLTEpDQpgYGANCg0KKipHamV0amEgZSB2bGVyZXMgbWFrc2ltYWxlIGRoZSBwb3ppY2lvbml0IHRlIHNhaiBuZSBrb2xvbmUgcGVyIHZhcmlhYmxpbiAkc2hrb2xsaW1pOiQqKg0KDQoqKlZsZXJhIG1ha3NpbWFsZToqKg0KYGBge3J9DQptYXhfdmFsdWVzIDwtIG1heChkYXRhJHNoa29sbGltaSkNCnByaW50KG1heF92YWx1ZXMpDQpgYGANCg0KKipQb3ppY2lvbmkgbmUga29sb25lOioqDQpgYGB7cn0NCnBvemljaW9uaSA8LSB3aGljaC5tYXgoZGF0YSRzaGtvbGxpbWkpIA0KcHJpbnQocG96aWNpb25pLTEpDQpgYGANCg0KKipHamV0amEgZSB2bGVyZXMgbWFrc2ltYWxlIGRoZSBwb3ppY2lvbml0IHRlIHNhaiBuZSBrb2xvbmUgcGVyIHZhcmlhYmxpbiAkc3RyZWhpbWk6JCoqDQoNCioqVmxlcmEgbWFrc2ltYWxlOioqDQpgYGB7cn0NCm1heF92YWx1ZXMgPC0gbWF4KGRhdGEkc3RyZWhpbWkpDQpwcmludChtYXhfdmFsdWVzKQ0KYGBgDQoNCioqUG96aWNpb25pIG5lIGtvbG9uZToqKg0KYGBge3J9DQpwb3ppY2lvbmkgPC0gd2hpY2gubWF4KGRhdGEkc3RyZWhpbWkpIA0KcHJpbnQocG96aWNpb25pLTEpDQpgYGANCg0KKipHamV0amEgZSB2bGVyZXMgbWFrc2ltYWxlIGRoZSBwb3ppY2lvbml0IHRlIHNhaiBuZSBrb2xvbmUgcGVyIHZhcmlhYmxpbiAkdXNocWltaTokKioNCg0KKipWbGVyYSBtYWtzaW1hbGU6KioNCmBgYHtyfQ0KbWF4X3ZhbHVlcyA8LSBtYXgoZGF0YSR1c2hxaW1pKQ0KcHJpbnQobWF4X3ZhbHVlcykNCmBgYA0KDQoqKlBvemljaW9uaSBuZSBrb2xvbmU6KioNCmBgYHtyfQ0KcG96aWNpb25pIDwtIHdoaWNoLm1heChkYXRhJHVzaHFpbWkpIA0KcHJpbnQocG96aWNpb25pLTEpDQpgYGANCg0KKipHamV0amEgZSB2bGVyZXMgbWFrc2ltYWxlIGRoZSBwb3ppY2lvbml0IHRlIHNhaiBuZSBrb2xvbmUgcGVyIHZhcmlhYmxpbiAkdHJhbnNwb3J0aTokKioNCg0KKipWbGVyYSBtYWtzaW1hbGU6KioNCmBgYHtyfQ0KbWF4X3ZhbHVlcyA8LSBtYXgoZGF0YSR0cmFuc3BvcnRpKQ0KcHJpbnQobWF4X3ZhbHVlcykNCmBgYA0KDQoqKlBvemljaW9uaSBuZSBrb2xvbmU6KioNCmBgYHtyfQ0KcG96aWNpb25pIDwtIHdoaWNoLm1heChkYXRhJHRyYW5zcG9ydGkpIA0KcHJpbnQocG96aWNpb25pLTEpDQpgYGANCg0KKipHamV0amEgZSB2bGVyZXMgbWFrc2ltYWxlIGRoZSBwb3ppY2lvbml0IHRlIHNhaiBuZSBrb2xvbmUgcGVyIHZhcmlhYmxpbiAkbWpldGV0JCAkc2hrb2xsb3JlOiQqKg0KDQoqKlZsZXJhIG1ha3NpbWFsZToqKg0KYGBge3J9DQptYXhfdmFsdWVzIDwtIG1heChkYXRhJG1qZXRldF9zaGtvbGxvcmUpDQpwcmludChtYXhfdmFsdWVzKQ0KYGBgDQoNCioqUG96aWNpb25pIG5lIGtvbG9uZToqKg0KYGBge3J9DQpwb3ppY2lvbmkgPC0gd2hpY2gubWF4KGRhdGEkbWpldGV0X3Noa29sbG9yZSkgDQpwcmludChwb3ppY2lvbmktMSkNCmBgYA0KDQoqKkdqZXRqYSBlIHZsZXJlcyBtYWtzaW1hbGUgZGhlIHBvemljaW9uaXQgdGUgc2FqIG5lIGtvbG9uZSBwZXIgdmFyaWFibGluICRhcmdldGltOiQqKg0KDQoqKlZsZXJhIG1ha3NpbWFsZToqKg0KYGBge3J9DQptYXhfdmFsdWVzIDwtIG1heChkYXRhJGFyZ2V0aW0pDQpwcmludChtYXhfdmFsdWVzKQ0KYGBgDQoNCioqUG96aWNpb25pIG5lIGtvbG9uZToqKg0KYGBge3J9DQpwb3ppY2lvbmkgPC0gd2hpY2gubWF4KGRhdGEkYXJnZXRpbSkgDQpwcmludChwb3ppY2lvbmktMSkNCmBgYA0KDQoqKkdqZXRqYSBlIHZsZXJlcyBtYWtzaW1hbGUgZGhlIHBvemljaW9uaXQgdGUgc2FqIG5lIGtvbG9uZSBwZXIgdmFyaWFibGluICRrdWpkZXNpJCAkcGVyc29uYWw6JCoqDQoNCioqVmxlcmEgbWFrc2ltYWxlOioqDQpgYGB7cn0NCm1heF92YWx1ZXMgPC0gbWF4KGRhdGEka3VqZGVzaV9wZXJzb25hbCkNCnByaW50KG1heF92YWx1ZXMpDQpgYGANCg0KKipQb3ppY2lvbmkgbmUga29sb25lOioqDQpgYGB7cn0NCnBvemljaW9uaSA8LSB3aGljaC5tYXgoZGF0YSRrdWpkZXNpX3BlcnNvbmFsKSANCnByaW50KHBvemljaW9uaS0xKQ0KYGBgDQoNCioqR2pldGphIGUgdmxlcmVzIG1ha3NpbWFsZSBkaGUgcG96aWNpb25pdCB0ZSBzYWogbmUga29sb25lIHBlciB2YXJpYWJsaW4gJHRla25vbG9namk6JCoqDQoNCioqVmxlcmEgbWFrc2ltYWxlOioqDQpgYGB7cn0NCm1heF92YWx1ZXMgPC0gbWF4KGRhdGEkdGVrbm9sb2dqaSkNCnByaW50KG1heF92YWx1ZXMpDQpgYGANCg0KKipQb3ppY2lvbmkgbmUga29sb25lOioqDQpgYGB7cn0NCnBvemljaW9uaSA8LSB3aGljaC5tYXgoZGF0YSR0ZWtub2xvZ2ppKSANCnByaW50KHBvemljaW9uaS0xKQ0KYGBgDQoNCioqR2pldGphIGUgdmxlcmVzIG1ha3NpbWFsZSBkaGUgcG96aWNpb25pdCB0ZSBzYWogbmUga29sb25lIHBlciB2YXJpYWJsaW4gJG1pcmVxZW5pYSQgJHNoZW5kZXRlc29yZTokKioNCg0KKipWbGVyYSBtYWtzaW1hbGU6KioNCmBgYHtyfQ0KbWF4X3ZhbHVlcyA8LSBtYXgoZGF0YSRtaXJlcWVuaWFfc2hlbmRldGVzb3JlKQ0KcHJpbnQobWF4X3ZhbHVlcykNCmBgYA0KDQoqKlBvemljaW9uaSBuZSBrb2xvbmU6KioNCmBgYHtyfQ0KcG96aWNpb25pIDwtIHdoaWNoLm1heChkYXRhJG1pcmVxZW5pYV9zaGVuZGV0ZXNvcmUpIA0KcHJpbnQocG96aWNpb25pLTEpDQpgYGANCg0KKipHamV0amEgZSB2bGVyZXMgbWFrc2ltYWxlIGRoZSBwb3ppY2lvbml0IHRlIHNhaiBuZSBrb2xvbmUgcGVyIHZhcmlhYmxpbiAkdGUkICRuZHJ5c2htZTokKioNCg0KKipWbGVyYSBtYWtzaW1hbGU6KioNCmBgYHtyfQ0KbWF4X3ZhbHVlcyA8LSBtYXgoZGF0YSRtaXJlcWVuaWFfc2hlbmRldGVzb3JlKQ0KcHJpbnQobWF4X3ZhbHVlcykNCmBgYA0KDQoqKlBvemljaW9uaSBuZSBrb2xvbmU6KioNCmBgYHtyfQ0KcG96aWNpb25pIDwtIHdoaWNoLm1heChkYXRhJG1pcmVxZW5pYV9zaGVuZGV0ZXNvcmUpIA0KcHJpbnQocG96aWNpb25pLTEpDQpgYGANCg0KKipHamV0amEgZSB2bGVyw6tzIG1pbmltYWxlIGRoZSBwb3ppY2lvbml0IHRlIHNhaiBuZSBrb2xvbmUgcGVyIHZhcmlhYmxpbiAkbW9zaGE6JCoqDQoNCioqVmxlcmEgbWluaW1hbGU6KioNCmBgYHtyfQ0KbWluX3ZhbHVlcyA8LSBtaW4oZGF0YSRtb3NoYSkNCnByaW50KG1pbl92YWx1ZXMpDQpgYGANCg0KKipQb3ppY2lvbmkgbmUga29sb25lOioqDQpgYGB7cn0NCnBvemljaW9uaSA8LSB3aGljaC5taW4oZGF0YSRtb3NoYSkgDQpwcmludChwb3ppY2lvbmktMSkNCmBgYA0KDQoqKkdqZXRqYSBlIHZsZXJlcyBtaW5pbWFsZSBkaGUgcG96aWNpb25pdCB0ZSBzYWogbmUga29sb25lIHBlciB2YXJpYWJsaW4gJHRlJCAkYXJkaHVyYXQkICRtdWpvcmU6JCoqDQoNCioqVmxlcmEgbWluaW1hbGU6KioNCmBgYHtyfQ0KbWluX3ZhbHVlcyA8LSBtaW4oZGF0YSR0ZV9hcmRodXJhdF9tdWpvcmUpDQpwcmludChtaW5fdmFsdWVzKQ0KYGBgDQoNCioqUG96aWNpb25pIG5lIGtvbG9uZToqKg0KYGBge3J9DQpwb3ppY2lvbmkgPC0gd2hpY2gubWluKGRhdGEkdGVfYXJkaHVyYXRfbXVqb3JlKSANCnByaW50KHBvemljaW9uaS0xKQ0KYGBgDQoNCioqR2pldGphIGUgdmxlcmVzIG1pbmltYWxlIGRoZSBwb3ppY2lvbml0IHRlIHNhaiBuZSBrb2xvbmUgcGVyIHZhcmlhYmxpbiAkbmRpaG1hJCAkZmluYW5jaWFyZTokKioNCg0KKipWbGVyYSBtaW5pbWFsZToqKg0KYGBge3J9DQptaW5fdmFsdWVzIDwtIG1pbihkYXRhJG5kaWhtYV9maW5hbmNpYXJlKQ0KcHJpbnQobWluX3ZhbHVlcykNCmBgYA0KDQoqKlBvemljaW9uaSBuZSBrb2xvbmU6KioNCmBgYHtyfQ0KcG96aWNpb25pIDwtIHdoaWNoLm1pbihkYXRhJG5kaWhtYV9maW5hbmNpYXJlKSANCnByaW50KHBvemljaW9uaS0xKQ0KYGBgDQoNCioqR2pldGphIGUgdmxlcmVzIG1pbmltYWxlIGRoZSBwb3ppY2lvbml0IHRlIHNhaiBuZSBrb2xvbmUgcGVyIHZhcmlhYmxpbiAkc2hrb2xsaW1pOiQqKg0KDQoqKlZsZXJhIG1pbmltYWxlOioqDQpgYGB7cn0NCm1pbl92YWx1ZXMgPC0gbWluKGRhdGEkc2hrb2xsaW1pKQ0KcHJpbnQobWluX3ZhbHVlcykNCmBgYA0KDQoqKlBvemljaW9uaSBuZSBrb2xvbmU6KioNCmBgYHtyfQ0KcG96aWNpb25pIDwtIHdoaWNoLm1pbihkYXRhJHNoa29sbGltaSkgDQpwcmludChwb3ppY2lvbmktMSkNCmBgYA0KDQoqKkdqZXRqYSBlIHZsZXJlcyBtaW5pbWFsZSBkaGUgcG96aWNpb25pdCB0ZSBzYWogbmUga29sb25lIHBlciB2YXJpYWJsaW4gJHN0cmVoaW1pOiQqKg0KDQoqKlZsZXJhIG1pbmltYWxlOioqDQpgYGB7cn0NCm1pbl92YWx1ZXMgPC0gbWluKGRhdGEkc3RyZWhpbWkpDQpwcmludChtaW5fdmFsdWVzKQ0KYGBgDQoNCioqUG96aWNpb25pIG5lIGtvbG9uZToqKg0KYGBge3J9DQpwb3ppY2lvbmkgPC0gd2hpY2gubWluKGRhdGEkc3RyZWhpbWkpIA0KcHJpbnQocG96aWNpb25pLTEpDQpgYGANCg0KKipHamV0amEgZSB2bGVyZXMgbWluaW1hbGUgZGhlIHBvemljaW9uaXQgdGUgc2FqIG5lIGtvbG9uZSBwZXIgdmFyaWFibGluICR1c2hxaW1pOiQqKg0KDQoqKlZsZXJhIG1pbmltYWxlOioqDQpgYGB7cn0NCm1pbl92YWx1ZXMgPC0gbWluKGRhdGEkdXNocWltaSkNCnByaW50KHBvemljaW9uaS0xKQ0KYGBgDQoNCioqUG96aWNpb25pIG5lIGtvbG9uZToqKg0KYGBge3J9DQpwb3ppY2lvbmkgPC0gd2hpY2gubWluKGRhdGEkdXNocWltaSkgDQpwcmludChwb3ppY2lvbmktMSkNCmBgYA0KDQoqKkdqZXRqYSBlIHZsZXJlcyBtaW5pbWFsZSBkaGUgcG96aWNpb25pdCB0ZSBzYWogbmUga29sb25lIHBlciB2YXJpYWJsaW4gJHRyYW5zcG9ydGk6JCoqDQoNCioqVmxlcmEgbWluaW1hbGU6KioNCmBgYHtyfQ0KbWluX3ZhbHVlcyA8LSBtaW4oZGF0YSR0cmFuc3BvcnRpKQ0KcHJpbnQobWluX3ZhbHVlcykNCmBgYA0KDQoqKlBvemljaW9uaSBuZSBrb2xvbmU6KioNCmBgYHtyfQ0KcG96aWNpb25pIDwtIHdoaWNoLm1pbihkYXRhJHRyYW5zcG9ydGkpIA0KcHJpbnQocG96aWNpb25pLTEpDQpgYGANCg0KKipHamV0amEgZSB2bGVyZXMgbWluaW1hbGUgZGhlIHBvemljaW9uaXQgdGUgc2FqIG5lIGtvbG9uZSBwZXIgdmFyaWFibGluICRtamV0ZXQkICRzaGtvbGxvcmU6JCoqDQoNCioqVmxlcmEgbWluaW1hbGU6KioNCmBgYHtyfQ0KbWluX3ZhbHVlcyA8LSBtaW4oZGF0YSRtamV0ZXRfc2hrb2xsb3JlKQ0KcHJpbnQobWluX3ZhbHVlcykNCmBgYA0KDQoqKlBvemljaW9uaSBuZSBrb2xvbmU6KioNCmBgYHtyfQ0KcG96aWNpb25pIDwtIHdoaWNoLm1pbihkYXRhJG1qZXRldF9zaGtvbGxvcmUpIA0KcHJpbnQocG96aWNpb25pLTEpDQpgYGANCg0KKipHamV0amEgZSB2bGVyZXMgbWluaW1hbGUgZGhlIHBvemljaW9uaXQgdGUgc2FqIG5lIGtvbG9uZSBwZXIgdmFyaWFibGluICRhcmdldGltOiQqKg0KDQoqKlZsZXJhIG1pbmltYWxlOioqDQpgYGB7cn0NCm1pbl92YWx1ZXMgPC0gbWluKGRhdGEkYXJnZXRpbSkNCnByaW50KG1pbl92YWx1ZXMpDQpgYGANCg0KKipQb3ppY2lvbmkgbmUga29sb25lOioqDQpgYGB7cn0NCnBvemljaW9uaSA8LSB3aGljaC5taW4oZGF0YSRhcmdldGltKSANCnByaW50KHBvemljaW9uaS0xKQ0KYGBgDQoNCioqR2pldGphIGUgdmxlcmVzIG1pbmltYWxlIGRoZSBwb3ppY2lvbml0IHRlIHNhaiBuZSBrb2xvbmUgcGVyIHZhcmlhYmxpbiAka3VqZGVzaSQgJHBlcnNvbmFsOiQqKg0KDQoqKlZsZXJhIG1pbmltYWxlOioqDQpgYGB7cn0NCm1pbl92YWx1ZXMgPC0gbWluKGRhdGEka3VqZGVzaV9wZXJzb25hbCkNCnByaW50KG1pbl92YWx1ZXMpDQpgYGANCg0KKipQb3ppY2lvbmkgbmUga29sb25lOioqDQpgYGB7cn0NCnBvemljaW9uaSA8LSB3aGljaC5taW4oZGF0YSRrdWpkZXNpX3BlcnNvbmFsKSANCnByaW50KHBvemljaW9uaS0xKQ0KYGBgDQoNCioqR2pldGphIGUgdmxlcmVzIG1pbmltYWxlIGRoZSBwb3ppY2lvbml0IHRlIHNhaiBuZSBrb2xvbmUgcGVyIHZhcmlhYmxpbiAkdGVrbm9sb2dqaTokKioNCg0KKipWbGVyYSBtaW5pbWFsZToqKg0KYGBge3J9DQptaW5fdmFsdWVzIDwtIG1pbihkYXRhJHRla25vbG9namkpDQpwcmludChtaW5fdmFsdWVzKQ0KYGBgDQoNCioqUG96aWNpb25pIG5lIGtvbG9uZToqKg0KYGBge3J9DQpwb3ppY2lvbmkgPC0gd2hpY2gubWluKGRhdGEkdGVrbm9sb2dqaSkgDQpwcmludChwb3ppY2lvbmktMSkNCmBgYA0KDQoqKkdqZXRqYSBlIHZsZXJlcyBtaW5pbWFsZSBkaGUgcG96aWNpb25pdCB0ZSBzYWogbmUga29sb25lIHBlciB2YXJpYWJsaW4gJG1pcmVxZW5pYSQgJHNoZW5kZXRlc29yZTokKioNCg0KKipWbGVyYSBtaW5pbWFsZToqKg0KYGBge3J9DQptaW5fdmFsdWVzIDwtIG1pbihkYXRhJG1pcmVxZW5pYV9zaGVuZGV0ZXNvcmUpDQpwcmludChtaW5fdmFsdWVzKQ0KYGBgDQoNCioqUG96aWNpb25pIG5lIGtvbG9uZToqKg0KYGBge3J9DQpwb3ppY2lvbmkgPC0gd2hpY2gubWluKGRhdGEkbWlyZXFlbmlhX3NoZW5kZXRlc29yZSkgDQpwcmludChwb3ppY2lvbmktMSkNCmBgYA0KDQoqKkdqZXRqYSBlIHZsZXJlcyBtaW5pbWFsZSBkaGUgcG96aWNpb25pdCB0ZSBzYWogbmUga29sb25lIHBlciB2YXJpYWJsaW4gJHRlJCAkbmRyeXNobWU6JCoqDQoNCioqVmxlcmEgbWluaW1hbGU6KioNCmBgYHtyfQ0KbWluX3ZhbHVlcyA8LSBtaW4oZGF0YSR0ZV9uZHJ5c2htZSkNCnByaW50KG1pbl92YWx1ZXMpDQpgYGANCg0KKipQb3ppY2lvbmkgbmUga29sb25lOioqDQpgYGB7cn0NCnBvemljaW9uaSA8LSB3aGljaC5taW4oZGF0YSR0ZV9uZHJ5c2htZSkgDQpwcmludChwb3ppY2lvbmktMSkNCmBgYA0KDQoqKlNxYXJpbTpcIEluZGVrc2lcIGlcIHZsZXJhdmVcIG1ha3NpbWFsZVwgZGhlXCBtaW5pbWFsZVwgZXNodGVcIHpicml0dXJcIG1lXCAxXCBwZXJcIGFyc3llXCBzZSxcIG5lc2VcIHNob2hpbVwgbmVcIGtvbG9uYXRcIGVcIGRhdGFzZXRpdCxcIGluZGVrc2lcIHJlYWxcIHJlenVsdG9uXCBpKzEsXCBwcmEsXCBwZXJzaGVtYnVsbFwgcG96aWNpb25pXCBpXCBtaW5pbXVtaXRcIHRlXCBuZHJ5c2hvcmVzXCAkdGUkXCRuZHJ5c2htZSRcIG5lXCBkYXRhc2V0XCBkb1wgdGVcIGpldGVcIDQzMiAuKioNCg0KJCRBbXBsaXR1ZGFcXCBBID0ge3hfe21heH19XCArXCB7eF97bWlufX0kJA0KKipEaWZlcmVuY2EgbWlkaXMgdmxlcmVzIG1ha3NpbWFsZSBkaGUgbWluaW1hbGUgcGVyY2FrdG9uICRhbXBsaXR1ZGVuJC4qKg0KDQoqKkxsb2dhcml0amEgZSBhbXBsaXR1ZGVzIHBlciB2YXJpYWJsaW4gJG1vc2hhOiQqKg0KYGBge3J9DQphbXBsaXR1ZGEgPC0gbWF4KGRhdGEkbW9zaGEpIC0gbWluKGRhdGEkbW9zaGEpDQpwcmludChhbXBsaXR1ZGEpDQpgYGANCg0KKipMbG9nYXJpdGphIGUgYW1wbGl0dWRlcyBwZXIgdmFyaWFibGluICR0ZSQgJGFyZGh1cmF0JCAkbXVqb3JlOiQqKg0KYGBge3J9DQphbXBsaXR1ZGEgPC0gbWF4KGRhdGEkdGVfYXJkaHVyYXRfbXVqb3JlKSAtIG1pbihkYXRhJHRlX2FyZGh1cmF0X211am9yZSkNCnByaW50KGFtcGxpdHVkYSkNCmBgYA0KDQoqKkxsb2dhcml0amEgZSBhbXBsaXR1ZGVzIHBlciB2YXJpYWJsaW4gJG5kaWhtYSQgJGZpbmFuY2lhcmU6JCoqDQpgYGB7cn0NCmFtcGxpdHVkYSA8LSBtYXgoZGF0YSRuZGlobWFfZmluYW5jaWFyZSkgLSBtaW4oZGF0YSRuZGlobWFfZmluYW5jaWFyZSkNCnByaW50KGFtcGxpdHVkYSkNCmBgYA0KDQoqKkxsb2dhcml0amEgZSBhbXBsaXR1ZGVzIHBlciB2YXJpYWJsaW4gJHNoa29sbGltaTokKioNCmBgYHtyfQ0KYW1wbGl0dWRhIDwtIG1heChkYXRhJHNoa29sbGltaSkgLSBtaW4oZGF0YSRzaGtvbGxpbWkpDQpwcmludChhbXBsaXR1ZGEpDQpgYGANCg0KKipMbG9nYXJpdGphIGUgYW1wbGl0dWRlcyBwZXIgdmFyaWFibGluICRzdHJlaGltaTokKioNCmBgYHtyfQ0KYW1wbGl0dWRhIDwtIG1heChkYXRhJHN0cmVoaW1pKSAtIG1pbihkYXRhJHN0cmVoaW1pKQ0KcHJpbnQoYW1wbGl0dWRhKQ0KYGBgDQoNCioqTGxvZ2FyaXRqYSBlIGFtcGxpdHVkZXMgcGVyIHZhcmlhYmxpbiAkdXNocWltaTokKioNCmBgYHtyfQ0KYW1wbGl0dWRhIDwtIG1heChkYXRhJHVzaHFpbWkpIC0gbWluKGRhdGEkdXNocWltaSkNCnByaW50KGFtcGxpdHVkYSkNCmBgYA0KDQoqKkxsb2dhcml0amEgZSBhbXBsaXR1ZGVzIHBlciB2YXJpYWJsaW4gJHRyYW5zcG9ydGk6JCoqDQpgYGB7cn0NCmFtcGxpdHVkYSA8LSBtYXgoZGF0YSR0cmFuc3BvcnRpKSAtIG1pbihkYXRhJHRyYW5zcG9ydGkpDQpwcmludChhbXBsaXR1ZGEpDQpgYGANCg0KKipMbG9nYXJpdGphIGUgYW1wbGl0dWRlcyBwZXIgdmFyaWFibGluICRtamV0ZXQkICRzaGtvbGxvcmU6JCoqDQpgYGB7cn0NCmFtcGxpdHVkYSA8LSBtYXgoZGF0YSRtamV0ZXRfc2hrb2xsb3JlKSAtIG1pbihkYXRhJG1qZXRldF9zaGtvbGxvcmUpDQpwcmludChhbXBsaXR1ZGEpDQpgYGANCg0KKipMbG9nYXJpdGphIGUgYW1wbGl0dWRlcyBwZXIgdmFyaWFibGluICRhcmdldGltOiQqKg0KYGBge3J9DQphbXBsaXR1ZGEgPC0gbWF4KGRhdGEkYXJnZXRpbSkgLSBtaW4oZGF0YSRhcmdldGltKQ0KcHJpbnQoYW1wbGl0dWRhKQ0KYGBgDQoNCioqTGxvZ2FyaXRqYSBlIGFtcGxpdHVkZXMgcGVyIHZhcmlhYmxpbiAka3VqZGVzaSQgJHBlcnNvbmFsOiQqKg0KYGBge3J9DQphbXBsaXR1ZGEgPC0gbWF4KGRhdGEka3VqZGVzaV9wZXJzb25hbCkgLSBtaW4oZGF0YSRrdWpkZXNpX3BlcnNvbmFsKQ0KcHJpbnQoYW1wbGl0dWRhKQ0KYGBgDQoNCioqTGxvZ2FyaXRqYSBlIGFtcGxpdHVkZXMgcGVyIHZhcmlhYmxpbiAkdGVrbm9sb2dqaTokKioNCmBgYHtyfQ0KYW1wbGl0dWRhIDwtIG1heChkYXRhJHRla25vbG9namkpIC0gbWluKGRhdGEkdGVrbm9sb2dqaSkNCnByaW50KGFtcGxpdHVkYSkNCmBgYA0KDQoqKkxsb2dhcml0amEgZSBhbXBsaXR1ZGVzIHBlciB2YXJpYWJsaW4gJG1pcmVxZW5pYSQgJHNoZW5kZXRlc29yZTokKioNCmBgYHtyfQ0KYW1wbGl0dWRhIDwtIG1heChkYXRhJG1pcmVxZW5pYV9zaGVuZGV0ZXNvcmUpIC0gbWluKGRhdGEkbWlyZXFlbmlhX3NoZW5kZXRlc29yZSkNCnByaW50KGFtcGxpdHVkYSkNCmBgYA0KDQoqKkxsb2dhcml0amEgZSBhbXBsaXR1ZGVzIHBlciB2YXJpYWJsaW4gJHRlJCAkbmRyeXNobWU6JCoqDQpgYGB7cn0NCmFtcGxpdHVkYSA8LSBtYXgoZGF0YSR0ZV9uZHJ5c2htZSkgLSBtaW4oZGF0YSR0ZV9uZHJ5c2htZSkNCnByaW50KGFtcGxpdHVkYSkNCmBgYA0KDQojIyMjICQkVmFyaWFuY2EvRGlzcGVyc2lvbmkkJA0KDQoqKiREaXNwZXJzaW9uaSQgZGhlICRNZW5qYW5pbWkkICRNZXNhdGFyJCAkS2F0cm9yJCBqYW5lIGR5IHBhcmFtZXRyYSB0ZSByZW5kZXNpc2hlbSB0ZSBzaHBlcmhhcGplcy4gRGlzcGVyc2lvbmkgZXNodGUgbWVzYXRhcmphIGFyaXRtZXRpa2UgZSBrYXRyb3JldmUgdGUgZGlmZXJlbmNhdmUgbWlkaXMgY2RvIHRlIGRoZW5lIGRoZSBtZXNhdGFyZXMuIFByYSBhaSBtYXQgc2hwZXJoYXBqZW4gZSB2bGVyYXZlIHJyb3R1bGwgdmxlcmVzIG1lc2F0YXJlLioqDQoNCioqUGVyIHRlIGxsb2dhcml0dXIgRGlzcGVyc2lvbmluIHBlcmRvcmV0IGZ1bmtzaW9uaSAkdmFyKHgpOyQqKg0KDQokJEZvcm11bGFcIG1hdGVtYXRpa2U6XFwgXGRpc3BsYXlzdHlsZSB7U31eMiA9IFxmcmFjIHsxfXtufXtcZGlzcGxheXN0eWxlXHN1bV97aT0xfV57bn0oeF9pIC0gXG11KV4yfVxcIGVcIGNpbGFcIGxsb2dhcml0XCB2YXJpYW5jZW5cIGVcIGdydXBpdFwgdGVcIHRlXCBkaGVuYXZlLFwgICBpbmRla3NpXCAiaSJcIHNwZWNpZmlrb25cIHZsZXJlblwgZVwgIGlee3t0aH19XCAgbmVcIGdydXBpblwgZVwgdGVcIGRoZW5hdmUsXFwgICLOvCJcIHNwZWNpZmlrb25cIG1lc2F0YXJlblwgZVwgZ3J1cGl0XCB0ZVwgdGVcIGRoZW5hdmUsXCBkaGVcICJuIlwgc3BlY2lmaWtvblwgbnVtcmluXCB0b3RhbFwgdGVcIHZlemhnaW1ldmUuJCQNCg0KKiokTWVuamFuaW1pJCAkTWVzYXRhciQgJEthdHJvciQgZXNodGUgcnJlbmphIGthdHJvcmUgZSBkaXNwZXJzaW9uaXQgZGhlIG1hdCB0ZSBuamVqdGVuIGdqZSBuamVzb2ogc2kgZGlzcGVyc2lvbmkgZGhlIGthIHBlcm1hc2VuIGUgdGUgZGhlbmF2ZS4gRXNodGUgbmplIG51bWVyIHFlIG5kaWhtb24gcGVyIHRlIGt1cHR1YXIgc2Ugc2kgdmxlcmF0IGluZGl2aWR1YWxlIHRlIHZyb2p0dWFyYSBzaHBlcm5kYWhlbiBycm90dWxsIG1lc2F0YXJlcy4qKg0KDQoqKiRNZW5qYW5pbWkkICRNZXNhdGFyJCBrYSBwZXJtYXNlbiBlIHRlIGRoZW5hdmUgc2Vwc2UgZ2plbmRldCBzaSBycmVuamUga2F0cm9yZSBlIGRpc3BlcnNpb25pdCAoZG9sbGFyLCBldXJvLCBtZXRyYSwga2lsb2dyYW1lKS4qKg0KDQokJFxkaXNwbGF5c3R5bGUgRGV2aWppbWlcIFN0YW5kYXJkOlwge1N9ID0gXHNxcnR7XGZyYWN7XGRpc3BsYXlzdHlsZVxzdW1fe2k9MX1ee259KHhfaSAtIFxtdSleMn0ge259fVxcIHtTfSA9IFxzcXJ0e1ZhcmlhbmNhfSA9IFxzcXJ0e3tTfV4yfSQkDQoNCioqUGVyIHRlIGxsb2dhcml0dXIgbWVuamFuaW1pbiBtZXNhdGFyIG5lIFIgbnVrIGVnemlzdG9uIG5qZSBmdW5rc2lvbiBpIGdhdHNoZW0sIGtlc2h0dSBxZSBhaSBkbyB0ZSBtZXJyZXQgc2EgcnJlbmphIGthdHJvcmUgZSBkaXNwZXJzaW9uaXQgdGUgbGxvZ2FyaXR1ciBzZSBwYXJpOiAkc3FydCh2YXIoeCkpJDsqKg0KDQoqKkxlIHRlIGxsb2dhcml0aW0gdmFyaWFuY2VuIGRoZSBtZW5qYW5pbWluIG1lc2F0YXIgcGVyIG5kcnlzaG9yZXQgdG9uYSBtZSBhbmUgdGUgZnVua3Npb25pdCAkdmFyKHgpJCBkaGUgJHNxcnQodmFyKHgpKSQ6KioNCg0KKipWYXJpYW5jYSBwZXIgbmRyeXNob3JlbiAkbW9zaGEkOioqDQpgYGB7cn0NCnYxIDwtIGMoZGF0YSRtb3NoYSkNCnZhcih2MSkNCmBgYA0KKipNZW5qYW5pbWkgTWVzYXRhciBLYXRyb3IgcGVyIG5kcnlzaG9yZW4gJG1vc2hhJDoqKg0KYGBge3J9DQpkMSA8LSBzcXJ0KHZhcih2MSkpDQpkMQ0KYGBgDQoNCioqVmFyaWFuY2EgcGVyIG5kcnlzaG9yZW4gJHRlJCAkYXJkaHVyYXQkICRtdWpvcmUkOioqDQpgYGB7cn0NCnYyIDwtIGMoZGF0YSR0ZV9hcmRodXJhdF9tdWpvcmUpDQp2YXIodjIpDQpgYGANCg0KKipNZW5qYW5pbWkgTWVzYXRhciBLYXRyb3IgcGVyIG5kcnlzaG9yZW4gJHRlJCAkYXJkaHVyYXQkICRtdWpvcmUkOioqDQpgYGB7cn0NCmQyIDwtIHNxcnQodmFyKHYyKSkNCmQyDQpgYGANCg0KKipWYXJpYW5jYSBwZXIgbmRyeXNob3JlbiAkbmRpaG1hJCAkZmluYW5jaWFyZSQ6KioNCmBgYHtyfQ0KdjMgPC0gYyhkYXRhJG5kaWhtYV9maW5hbmNpYXJlKQ0KdmFyKHYzKQ0KYGBgDQoNCioqTWVuamFuaW1pIE1lc2F0YXIgS2F0cm9yIHBlciBuZHJ5c2hvcmVuICRuZGlobWEkICRmaW5hbmNpYXJlJDoqKg0KYGBge3J9DQpkMyA8LSBzcXJ0KHZhcih2MykpDQpkMw0KYGBgDQoNCioqVmFyaWFuY2EgcGVyIG5kcnlzaG9yZW4gJHNoa29sbGltaSQ6KioNCmBgYHtyfQ0KdjQgPC0gYyhkYXRhJHNoa29sbGltaSkNCnZhcih2NCkNCmBgYA0KDQoqKk1lbmphbmltaSBNZXNhdGFyIEthdHJvciBwZXIgbmRyeXNob3JlbiAkc2hrb2xsaW1pJDoqKg0KYGBge3J9DQpkNCA8LSBzcXJ0KHZhcih2NCkpDQpkNA0KYGBgDQoNCioqVmFyaWFuY2EgcGVyIG5kcnlzaG9yZW4gJHN0cmVoaW1pJDoqKg0KYGBge3J9DQp2NSA8LSBjKGRhdGEkc3RyZWhpbWkpDQp2YXIodjUpDQpgYGANCg0KKipNZW5qYW5pbWkgTWVzYXRhciBLYXRyb3IgcGVyIG5kcnlzaG9yZW4gJHN0cmVoaW1pJDoqKg0KYGBge3J9DQpkNSA8LSBzcXJ0KHZhcih2NSkpDQpkNQ0KYGBgDQoNCioqVmFyaWFuY2EgcGVyIG5kcnlzaG9yZW4gJHVzaHFpbWkkOioqDQpgYGB7cn0NCnY2IDwtIGMoZGF0YSR1c2hxaW1pKQ0KdmFyKHY2KQ0KYGBgDQoNCioqTWVuamFuaW1pIE1lc2F0YXIgS2F0cm9yIHBlciBuZHJ5c2hvcmVuICR1c2hxaW1pJDoqKg0KYGBge3J9DQpkNiA8LSBzcXJ0KHZhcih2NikpDQpkNg0KYGBgDQoNCioqVmFyaWFuY2EgcGVyIG5kcnlzaG9yZW4gJHRyYW5zcG9ydGkkOioqDQpgYGB7cn0NCnY3IDwtIGMoZGF0YSR0cmFuc3BvcnRpKQ0KdmFyKHY3KQ0KYGBgDQoNCioqTWVuamFuaW1pIE1lc2F0YXIgS2F0cm9yIHBlciBuZHJ5c2hvcmVuICR0cmFuc3BvcnRpJDoqKg0KYGBge3J9DQpkNyA8LSBzcXJ0KHZhcih2NykpDQpkNw0KYGBgDQoNCioqVmFyaWFuY2EgcGVyIG5kcnlzaG9yZW4gJG1qZXRldCQgJHNoa29sbG9yZSQ6KioNCmBgYHtyfQ0KdjggPC0gYyhkYXRhJG1qZXRldF9zaGtvbGxvcmUpDQp2YXIodjgpDQpgYGANCg0KKipNZW5qYW5pbWkgTWVzYXRhciBLYXRyb3IgcGVyIG5kcnlzaG9yZW4gJG1qZXRldCQgJHNoa29sbG9yZSQ6KioNCmBgYHtyfQ0KZDggPC0gc3FydCh2YXIodjgpKQ0KZDgNCmBgYA0KDQoqKlZhcmlhbmNhIHBlciBuZHJ5c2hvcmVuICRhcmdldGltJDoqKg0KYGBge3J9DQp2OSA8LSBjKGRhdGEkYXJnZXRpbSkNCnZhcih2OSkNCmBgYA0KDQoqKk1lbmphbmltaSBNZXNhdGFyIEthdHJvciBwZXIgbmRyeXNob3JlbiAkYXJnZXRpbSQ6KioNCmBgYHtyfQ0KZDkgPC0gc3FydCh2YXIodjkpKQ0KZDkNCmBgYA0KDQoqKlZhcmlhbmNhIHBlciBuZHJ5c2hvcmVuICRrdWpkZXNpJCAkcGVyc29uYWwkOioqDQpgYGB7cn0NCnYxMCA8LSBjKGRhdGEka3VqZGVzaV9wZXJzb25hbCkNCnZhcih2MTApDQpgYGANCg0KKipNZW5qYW5pbWkgTWVzYXRhciBLYXRyb3IgcGVyIG5kcnlzaG9yZW4gJGt1amRlc2kkICRwZXJzb25hbCQ6KioNCmBgYHtyfQ0KZDEwIDwtIHNxcnQodmFyKHYxMCkpDQpkMTANCmBgYA0KDQoqKlZhcmlhbmNhIHBlciBuZHJ5c2hvcmVuICR0ZWtub2xvZ2ppJDoqKg0KYGBge3J9DQp2MTEgPC0gYyhkYXRhJHRla25vbG9namkpDQp2YXIodjExKQ0KYGBgDQoNCioqTWVuamFuaW1pIE1lc2F0YXIgS2F0cm9yIHBlciBuZHJ5c2hvcmVuICR0ZWtub2xvZ2ppJDoqKg0KYGBge3J9DQpkMTEgPC0gc3FydCh2YXIodjExKSkNCmQxMQ0KYGBgDQoqKlZhcmlhbmNhIHBlciBuZHJ5c2hvcmVuICRtaXJlcWVuaWEkICRzaGVuZGV0ZXNvcmUkOioqDQpgYGB7cn0NCnYxMiA8LSBjKGRhdGEkbWlyZXFlbmlhX3NoZW5kZXRlc29yZSkNCnZhcih2MTIpDQpgYGANCg0KKipNZW5qYW5pbWkgTWVzYXRhciBLYXRyb3IgcGVyIG5kcnlzaG9yZW4gJG1pcmVxZW5pYSQgJHNoZW5kZXRlc29yZSQ6KioNCmBgYHtyfQ0KZDEyIDwtIHNxcnQodmFyKHYxMikpDQpkMTINCmBgYA0KKipWYXJpYW5jYSBwZXIgbmRyeXNob3JlbiAkdGUkICRuZHJ5c2htZSQ6KioNCmBgYHtyfQ0KdjEzIDwtIGMoZGF0YSR0ZV9uZHJ5c2htZSkNCnZhcih2MTMpDQpgYGANCg0KKipNZW5qYW5pbWkgTWVzYXRhciBLYXRyb3IgcGVyIG5kcnlzaG9yZW4gJHRlJCAkbmRyeXNobWUkOioqDQpgYGB7cn0NCmQxMyA8LSBzcXJ0KHZhcih2MTMpKQ0KZDEzDQpgYGANCg0KKipJbnRlcnByZXRpbWkgaSByZXp1bHRhdGV2ZSBkbyB0ZSBqZXRlIGkgdGlsbGUgcGVyIGNkbyBuZHJ5c2hvcmUgbWJpIHRlIGNpbGVuIGtlbWkgbGxvZ2FyaXR1ciB2YXJpYW5jZW4gZGhlIG1lbmphbmltaW4gbWVzYXRhciBrYXRyb3I6IGxlIHRlIG1hcnJpbSBuZHJ5c2hvcmVuICRtb3NoYSQ7IHZsZXJhIDUuMzk0NyB0cmVnb24gc2UgdmxlcmF0IGphbmUgdGUgc2hwZXJoYXB1cmEgbWVzYXRhcmlzaHQgNS4zOTQ3IG5qZXNpIGthdHJvcmUgbGFyZyBuZ2EgdmxlcmEgbWVzYXRhcmUgZSBncnVwaXQgdGUgdGUgZGhlbmF2ZS4gVmxlcmEgMi4zMjI2NjQgdHJlZ29uIHNlIHZsZXJhdCBqYW5lIDIuMzIyNjY0IG5qZXNpIGxhcmcgbmdhIHZsZXJhIG1lc2F0YXJlLioqDQoNCioqSSBuamVqdGkgaW50ZXJwcmV0aW0gdmxlbiBwZXIgdGUgZ2ppdGhhIG5kcnlzaG9yZXQgZSB0amVyYS4qKg0KDQoNCiMjIyMgJCRBTkFMSVpBXCBFXCBORFJZU0hPUkVWRVwgQ0lMRVNPUkUkJA0KDQoqKiROZHJ5c2hvcmV0JCAkQ2lsZXNvcmUkIGtsYXNpZmlrb2hlbiBzaSBuZHJ5c2hvcmUgJG5vbWluYWxlJCBkaGUgJG9yZGluYWxlJC4qKg0KDQoqKiROZHJ5c2hvcmV0JCAkTm9taW5hbGUkIGphbmUgYXRvIGxsb2plIG5kcnlzaG9yZXNoIGNpbGVzb3JlIG1iaSB0ZSBjaWxhdCBudWsgbXVuZCB0ZSBrcnloZXQgdmVwcmltaSBpIHJlbmRpdGplcy4gTmRlcnNhIG5qZSAkTmRyeXNob3JlJCAkT3JkaW5hbGUkIGVzaHRlIG5qZSBsbG9qIGkgbmRyeXNob3JldmUgY2lsZXNvcmUgbWJpIHRlIGNpbGF0IG11bmQgdGUga3J5ZWptZSByZW5kaXRqZSAob3JkaW5hbCAsIG9yZGVyIC0gcmVuZGl0amUpLioqDQoNCioqTmUgZGF0YXNldCBuZHJ5c2hvcmV0IG5vbWluYWxlIGphbmUgJGdqaW5pYSQsICRkaXBsb21pbWkkIGRoZSAkbWV0b2RhJCAkZSQgJHBhZ2VzZXMkLCBuZGVyc2EgbmRyeXNob3JldCBvcmRpbmFsZSBqYW5lIGRoZSAkdml0aSQgJGkkICRzdHVkaW1ldmUkKioNCg0KKipBbmFsaXphIGUgbmRyeXNob3JldmUgY2lsZXNvcmUgZG8gdGUgcGVyZnNoaWplIG5kZXJ0aW1pbiBlIHRhYmVsYXZlIHRlIGZyZWt1ZW5jZXMsIHRhYmVsYXZlIHRlIGtvbnRpZ2plbmNlcywga3UgYmFzaGtlIG1lIGtldG8gZG8gdGUgbmRlcnRvam1lIGVkaGUgdGFiZWxhdCBtZSB2bGVyYXQgcHJvYmFiaWxpdGFyZSBwZXJrYXRlc2UgcGVyIGNkbyB0YWJlbGUga29udGlnamVuY2UgZSBnaml0aGFzaHR1IGVkaGUgdGVzdGluIEhpLWthdHJvci4qDQoNCiMjIyMgJCRUYWJlbGF0XCBlXCBmcmVrdWVuY2F2ZTpcIE1vZGFcIGRoZVwgRnJla3VlbmNhXCBlXCBzYWokJA0KDQoqKlRhYmVsYSBlIEZyZWt1ZW5jZXMgcGVyIG5kcnlzaG9yZW4gY2lsZXNvcmUgJGdqaW5pYSQgZGhlIG1vZGE6IGNpbGVzaWEgZSBwZXJzZXJpdHVyIG1lIHNocGVzaDsqKg0KDQoqKlRhYmVsYSBlIEZyZWt1ZW5jZXM6KioNCmBgYHtyfQ0KdGFiIDwtIHRhYmxlKGRhdGEkZ2ppbmlhKQ0KcHJpbnQodGFiKQ0KYGBgDQoNCioqTW9kYToqKg0KYGBge3J9DQptb2RhIDwtIG5hbWVzKHRhYilbdGFiID09IG1heCh0YWIpXQ0KcHJpbnQobW9kYSkNCmBgYA0KDQoqKkZyZWt1ZW5jYToqKg0KYGBge3J9DQptYXhfZnJlcXVlbmN5ID0gbWF4KHRhYikNCnByaW50KG1heF9mcmVxdWVuY3kpDQpgYGANCg0KKipJbnRlcnByZXRpbWkgaSB0YWJlbGVzIHNlIGZyZWt1ZW5jZXM6KiogDQoNCioqRnVua3Npb25pICR0YWJsZSgpJCBuYSBzaGVyYmVuIHBlciBuZGVydGltaW4gZSB0YWJlbGVzLCBkdWtlIG1hcnJlIHNpIHBhcmFtZXRlciBlbXJpbiBlIG5kcnlzaG9yZXMgcGVyIHRlIGNpbGVuIGRlc2hpcm9qbWUgdGUgbmRlcnRvam1lIG5qZSB0YWJlbGUgZnJla3VlbmNlLiBGdW5rc2lvbmkgJG5hbWVzKHRhYilbdGFiID09IG1heCh0YWIpXSQgc2hlcmJlbiBwZXIgdGUgZ2pldHVyIG1vZGVuIGUgbmRyeXNob3JlcyBuZGVyc2EgJG1heCh0YWIpJCBzaGVyYmVuIHBlciB0ZSBnamV0dXIgZnJla3VlbmNlbiBlIHNhai4gVmVtZSByZSBxZSBtb2RhIHBlciBrZXRlIG5kcnlzaG9yZSBlc2h0ZSAkbWFsZSQgZGhlIGZyZWt1ZW5jYSBlIHNhaiBlc2h0ZSAzNTYsIHByYSBham8gc2hmYXFldCAzNTYgaGVyZSBuZSBncnVwaW4gZSB0ZSBkaGVuYXZlLiBJIG5qZWp0aSBpbnRlcnByZXRpbSBkbyB0ZSB2bGVqZSBwZXIgY2RvIHRhYmVsZSB0amV0ZXIgdGUgbmRlcnR1YXIgbWUgcG9zaHRlLioqDQoNCg0KKipUYWJlbGEgZSBGcmVrdWVuY2VzIHBlciBuZHJ5c2hvcmVuIGNpbGVzb3JlICR2aXRpJCAkaSQgJHN0dWRpbWV2ZSQgZGhlIG1vZGE6IGNpbGVzaWEgZSBwZXJzZXJpdHVyIG1lIHNocGVzaDsqKg0KDQoqKlRhYmVsYSBlIEZyZWt1ZW5jZXM6KioNCmBgYHtyfQ0KdGFiIDwtIHRhYmxlKGRhdGEkdml0aV9pX3N0dWRpbWV2ZSkNCnByaW50KHRhYikNCmBgYA0KDQoqKk1vZGE6KioNCmBgYHtyfQ0KbW9kYSA8LSBuYW1lcyh0YWIpW3RhYiA9PSBtYXgodGFiKV0NCnByaW50KG1vZGEpDQpgYGANCg0KKipGcmVrdWVuY2E6KioNCmBgYHtyfQ0KbWF4X2ZyZXF1ZW5jeSA9IG1heCh0YWIpDQpwcmludChtYXhfZnJlcXVlbmN5KQ0KYGBgDQoNCioqVGFiZWxhIGUgRnJla3VlbmNlcyBwZXIgbmRyeXNob3JlbiBjaWxlc29yZSAkZGlwbG9taW1pJCBkaGUgbW9kYTogY2lsZXNpYSBlIHBlcnNlcml0dXIgbWUgc2hwZXNoOyoqDQoNCioqVGFiZWxhIGUgRnJla3VlbmNlczoqKg0KYGBge3J9DQp0YWIgPC0gdGFibGUoZGF0YSRkaXBsb21pbWkpDQpwcmludCh0YWIpDQpgYGANCg0KKipNb2RhOioqDQpgYGB7cn0NCm1vZGEgPC0gbmFtZXModGFiKVt0YWIgPT0gbWF4KHRhYildDQpwcmludChtb2RhKQ0KYGBgDQoNCioqRnJla3VlbmNhOioqDQpgYGB7cn0NCm1heF9mcmVxdWVuY3kgPSBtYXgodGFiKQ0KcHJpbnQobWF4X2ZyZXF1ZW5jeSkNCmBgYA0KDQoqKlRhYmVsYSBlIEZyZWt1ZW5jZXMgcGVyIG5kcnlzaG9yZW4gY2lsZXNvcmUgJG1ldG9kYSQgJGUkICRwYWdlc2VzJCBkaGUgbW9kYTogY2lsZXNpYSBlIHBlcnNlcml0dXIgbWUgc2hwZXNoOyoqDQoNCioqVGFiZWxhIGUgRnJla3VlbmNlczoqKg0KYGBge3J9DQp0YWIgPC0gdGFibGUoZGF0YSRtZXRvZGFfZV9wYWdlc2VzKQ0KcHJpbnQodGFiKQ0KYGBgDQoNCioqTW9kYToqKg0KYGBge3J9DQptb2RhIDwtIG5hbWVzKHRhYilbdGFiID09IG1heCh0YWIpXQ0KcHJpbnQobW9kYSkNCmBgYA0KDQoqKkZyZWt1ZW5jYToqKg0KYGBge3J9DQptYXhfZnJlcXVlbmN5ID0gbWF4KHRhYikNCnByaW50KG1heF9mcmVxdWVuY3kpDQpgYGANCg0KIyMjIyAkJFRhYmVsYXRcIGVcIEtvbnRpZ2plbmNlcyQkDQoNCioqVGFiZWxhdCBlIGtvbnRpZ2plbmNlcywgdGUgbmpvaHVyYSBnaml0aGFzaHR1IHNpIHRhYmVsYSBlIG5kYXJqZXMgc2Uga3J5cWV6dWFyLCBwZXJkb3JlbiBwZXIgdGUgcGFyYXFpdHVyIGZyZWt1ZW5jYXQgZSBrb21iaW5pbWV2ZSB0ZSBkeSB2YXJpYWJsYXZlIG5lIG5qZSBmb3JtYXQgdGUgc3RydWt0dXJ1YXIuIEtldG8gdGFiZWxhIGphbmUgdGUgcmVuZGVzaXNobWUgbmUgYW5hbGl6ZW4gZSBsaWRoamV2ZSBtaWRpcyB2YXJpYWJsYXZlIGRoZSBuZSB6aHZpbGxpbWluIGUgdGVzdGltZXZlIHN0YXRpc3Rpa29yZSBzaSB0ZXN0aSBDaGktU3F1YXJlZC4qKiANCg0KKipNZSBrcmlqaW1pbiBlIGtldHlyZSB0YWJlbGF2ZSBpbnRlcmVzb2hlbWkgcGVyIG5kb25qZSBtYXJyZWRoZW5pZSB0ZSBtdW5kc2htZSBtaWRpcyBkeSB2YXJpYWJsYXZlIGNpbGVzb3JlLioqDQoNCioqTWUgcG9zaHRlIGRvIHRlIG5kZXJ0b2ptZSBUYWJlbGF0IGUgS29udGlnamVuY2VzIHBlciB2YXJpYWJsYXQgY2lsZXNvcmUgbWUgYW5lIHRlIGZ1bmtzaW9uaXQgJHRhYmxlKCkkLiBWZWNtYXMga2V0aWogZnVua3Npb25pIGRvIHRlIHBlcmRvcmltIGVkaGUgZnVua3Npb25pbiAkcHJvcC50YWJsZSgpJCBpIGNpbGkgZG8gdGUgbWFycmUgc2kgcGFyYW1ldGVyIGVtcmluIGUgdGFiZWxlcyBzZSBrb250aWdqZW5jZXMgZGhlIGRvIHRlIG5hIGFmaXNob2plIHBlcnNlcmkgdGFiZWxlbiBlIGtvbnRpZ2plbmNlcywgcG9yIGtlc2FqIGhlcmUgbWUgdmxlcmEgcHJvYmFiaWxpdGFyZS9wZXJxaW5kamUuIFByYSBzYSBwZXJxaW5kIHplIG5lIHRlIGRoZW5hIGtqbyBwamVzZSBlIHBvcHVsbGltaXQuKioNCg0KKipUYWJlbGEgZSBLb250aWdqZW5jZXMgcGVyIG5kcnlzaG9yZXQgJGdqaW5pYSQgZGhlICR2aXRpJCAkaSQgJHN0dWRpbWV2ZTokKioNCmBgYHtyfQ0KdGFiZWxhMSA8LSB0YWJsZShkYXRhJGdqaW5pYSwgZGF0YSR2aXRpX2lfc3R1ZGltZXZlKSANCnByaW50KHRhYmVsYTEpDQpgYGANCg0KKipMZXhpbWkgaSB0YWJlbGVzIHNlIGtvbnRpZ2plbmNlcyBlc2h0ZSBpIHRpbGxlOiB2bGVyYSA3OCBuZSB0YWJlbGUsIG5lIHBvemljaW9uaW4gKDEsMSkgdHJlZ29uIHNlIDc4IG5nYSBnaml0aGUgcG9wdWxsaW1pIGphbmUgZmVtcmEgZGhlIGphbmUgbmUgc3RhdHVzaW4gc3R1ZGVudGUgdGUgdml0aXQgdGUgcGFyZSAoZnJlc2htYW4pLCA4MSBtZXNoa3VqIHFlIGphbmUgbmUgc3RhdHVzaW4ganVuaW9yIGRoZSBrZXNodHUgdmVwcm9qbWUgcGVyIHRlIGdqaXRoYSB2bGVyYXQgZSB0amVyYSBuZSBjZG8gdGFiZWxlIHRqZXRlciBrb250aWdqZW5jZS4qKg0KDQpgYGB7cn0NCnByb3AudGFibGUodGFiZWxhMSwgMSkNCmBgYA0KDQoqKkludGVycHJldGltaTogdmxlcmEgMC4yNDE0ODYxIG5lIHRhYmVsZSB0cmVnb24gc2UgMjQuMTQ4NjElIGUgdGUgZGhlbmF2ZSBqYW5lIGZlbXJhIGRoZSBqYW5lIG5lIHN0YXR1c2luIGZyZXNobWFuLiAyNS4yNjA5JSBqYW5lIG1lc2hrdWogbmUgc3RhdHVzaW4gc2VuaW9yLCBlIGtlc2h0dSBtZSByYWRoZS4gSSBuamVqdGkgaW50ZXJwcmV0aW0gZG8gdGUgdmxlamUgcGVyIHRlIGdqaXRoYSB0YWJlbGF0IGUgbWVwb3NodG1lLioqDQoNCioqVGFiZWxhIGUgS29udGlnamVuY2VzIHBlciBuZHJ5c2hvcmV0ICRnamluaWEkIGRoZSAkZGlwbG9taW1pOiQqKg0KYGBge3J9DQp0YWJlbGEyIDwtIHRhYmxlKGRhdGEkZ2ppbmlhLCBkYXRhJGRpcGxvbWltaSkgDQpwcmludCh0YWJlbGEyKQ0KYGBgDQpgYGB7cn0NCnByb3AudGFibGUodGFiZWxhMiwgMSkNCmBgYA0KDQoqKlRhYmVsYSBlIEtvbnRpZ2plbmNlcyBwZXIgbmRyeXNob3JldCAkZ2ppbmlhJCBkaGUgJG1ldG9kYSQgJGUkICRwYWdlc2VzOiQqKg0KYGBge3J9DQp0YWJlbGEzIDwtIHRhYmxlKGRhdGEkZ2ppbmlhLCBkYXRhJG1ldG9kYV9lX3BhZ2VzZXMpIA0KcHJpbnQodGFiZWxhMykNCmBgYA0KYGBge3J9DQpwcm9wLnRhYmxlKHRhYmVsYTMsIDEpDQpgYGANCg0KKipUYWJlbGEgZSBLb250aWdqZW5jZXMgcGVyIG5kcnlzaG9yZXQgJGRpcGxvbWltaSQgZGhlICRtZXRvZGEkICRlJCAkcGFnZXNlczokKioNCmBgYHtyfQ0KdGFiZWxhNCA8LSB0YWJsZShkYXRhJGRpcGxvbWltaSwgZGF0YSRtZXRvZGFfZV9wYWdlc2VzKSANCnByaW50KHRhYmVsYTQpDQpgYGANCmBgYHtyfQ0KcHJvcC50YWJsZSh0YWJlbGE0LCAxKQ0KYGBgDQoNCioqVGFiZWxhIGUgS29udGlnamVuY2VzIHBlciBuZHJ5c2hvcmV0ICR2aXRpJCAkaSQgJHN0dWRpbWV2ZSQgZGhlICRtZXRvZGEkICRlJCAkcGFnZXNlczokKioNCmBgYHtyfQ0KdGFiZWxhNSA8LSB0YWJsZShkYXRhJHZpdGlfaV9zdHVkaW1ldmUsIGRhdGEkbWV0b2RhX2VfcGFnZXNlcykgDQpwcmludCh0YWJlbGE1KQ0KYGBgDQpgYGB7cn0NCnByb3AudGFibGUodGFiZWxhNSwgMSkNCmBgYA0KDQojIyMjICQkVGVzdGlcIEhpLUthdHJvciQkDQoNCioqw4dmYXJlIGVzaHRlIG5qZSBzdGF0aXN0aWtlICRIaS1rYXRyb3IkPyoqDQoNCioqVGVzdGkgz4cyIHNoaWtvbiBtb2RlbGluIGUgdmV6aGdpbWV2ZSBkaGUgbmEgdHJlZ29uIG5lc2UgZGlzYSBrb21iaW5pbWUgdGUga2F0ZWdvcml2ZSBuZG9kaGluIG1lIHNocGVzaCBzZXNhIGRvIHRlIHByaXNuaW0gcmFzdGVzaXNodCwgZHVrZSBwYXN1ciBwYXJhc3lzaCBudW1yaW4gZSBwZXJnaml0aHNoZW0gdGUgaGVyZXZlIHFlIGthIG5kb2RodXIgc2VjaWxhIGthdGVnb3JpLiBQcmEga2Vya29uIG5qZSBsaWRoamUgbWlkaXMgdmFyaWFibGF2ZS4qKg0KDQokJEZvcm11bGFcIG1hdGVtYXRpa2U6XFwgz4cyPVxkaXNwbGF5c3R5bGVcc3VtX3tpPTF9XntufVxmcmFjeyhPX3tpan0tRV97aWp9KV4yfXtFX3tpan19XFwgz4cyXCBlc2h0ZVwgc3RhdGlzdGlrYVwgZVwgdGVzdGl0O1wgzqNcIGVzaHRlXCBvcGVyYXRvcmlcIHNodW1hdG9yO1xcIE9cIGVzaHRlXCBmcmVrdWVuY2FcIGVcIHZlemhndWFyO1wgRVwgZXNodGVcIGZyZWt1ZW5jYVwgZVwgcHJpdHVyOyQkDQoNCioqUGVyIHRlIGxsb2dhcml0dXIgdmxlcmVuIGUgSGkta2F0cm9yaXQgbmRlcnRvaGV0IG5qZSB0YWJlbGUgbWUgZWZla3RpdmEgdGVvcmlrZS4gS2V0YSBlZmVrdGl2YSBpIGtvcnJlc3BvbmRvam5lIHJhc3RpdCBrdXIgbmRyeXNob3JldCBqYW5lIHRlIHBhdmFydXJhLiBUZXN0aSDPhzIgZG8gdGUga3J5aGV0IG1lIGFuZSB0ZSBmdW5rc2lvbml0ICRjaGlzcS50ZXN0KCkkIGkgY2lsaSBtZXJyIHNpIHBhcmFtZXRlciBlbXJpbiBlIHRhYmVsZXMgc2Uga29udGlnamVuY2VzLioqDQoNCioqTmUgZ2ppdGhhc2h0dSBkdWhldCB0ZSBwZXJjYWt0b2ptZSBzaGthbGxldCBlIGxpcmlzZSBwZXIgdGFiZWxlbiB0b25lKioNCg0KKipQZXIgdGUgemJhdHVhciB0ZXN0aW4gJEhpLWthdHJvciQgbmRhaiBkeSBuZHJ5c2hvcmV2ZSBuYSBkdWhldCBuamUgdGFiZWxlIGtvbnRpZ2plbmNlIGUgdHlyZSwgdGUgY2lsYXQgaSBrZW1pIG5kZXJ0dWFyIG1lIHNpcGVyLioqDQoNCioqTGUgdGEgemJhdG9qbWU6KioNCg0KKipUZXN0aSBIaS1rYXRyb3IgcGVyIG5kcnlzaG9yZXQgJGdqaW5pYSQgZGhlICR2aXRpICRpJCAkc3R1ZGltZXZlOiQqKg0KYGBge3J9DQp0ZXN0MSA8LSBjaGlzcS50ZXN0KHRhYmVsYTEpDQp0ZXN0MQ0KYGBgDQoNCioqTmUga2V0ZSByZXp1bHRhdCwga2EgZGlzYSBpbmZvcm1hY2lvbmUga3nDp2UgcWUgbmEgbmRpaG1vam5lIG5lIGludGVycHJldGltaW4gZSByZXp1bHRhdGV2ZS4qKg0KDQoqKjEuCVRlc3QgaSBrcnllciBlc2h0ZSB0ZXN0aSBIaS1rYXRyb3IgaSBQZWFyc29uLWl0LioqDQoNCioqMi4JVmxlcmEgZSB0ZXN0aXQgSGkta2F0cm9yIGVzaHRlIDIuNDQ4OC4qKg0KDQoqKjMuCU51bXJpIGkgc2hrYWxsZXZlIHRlIGxpcmlzZSBlc2h0ZSA2LioqDQoNCioqNC4JUC12bGVyYSBlIHRlc3RpdCBlc2h0ZSAwLjg3NDIuKioNCg0KKipJbnRlcnByZXRpbWkgaSBrZXR5cmUgcmV6dWx0YXRldmUgZXNodGUgc2kgbWUgcG9zaHRlOioqDQoNCioq4oCiCVZsZXJhIGUgdGVzdGl0IEhpLWthdHJvciAyLjQ0ODggdHJlZ29uIHNlIGRpZmVyZW5jYSBtaWRpcyB0ZSBkaGVuYXZlIHRlIHZlemhndWFyYSBkaGUgdGUgcHJhbnVhcmEgbnVrIGVzaHRlIHNodW1lIGUgbWFkaGUuKioNCg0KKirigKIJUC12YWx1ZSAwLjg3NDIgZXNodGUgbWUgZSBtYWRoZSBzZSBuaXZlbGkgaSB6YWtvbnNoZW0gaSByZW5kZXNpc2UgKHAtdmFsdWUgPiAwLjA1KS4gS2pvIGRvIHRlIHRob3RlIHNlIGR1aGV0IHRlIHByYW5vam1lIGhpcG90ZXplbiB6ZXJvLCBlIGNpbGEgc3Vwb3pvbiBwYXZhcmVzaSBzdGF0aXN0aWtvcmUgbWlkaXMgZHkgdmFyaWFibGF2ZSBuZSB0YWJlbGVuIGUga29udGlnamVuY2VzLioqDQoNCg0KKipUZXN0aSBIaS1rYXRyb3IgcGVyIG5kcnlzaG9yZXQgJGdqaW5pYSQgZGhlICRkaXBsb21pbWk6JCoqDQpgYGB7cn0NCnRlc3QyIDwtIGNoaXNxLnRlc3QodGFiZWxhMikNCnRlc3QyDQpgYGANCg0KKipOZSBrZXRlIHJlenVsdGF0LCBrYSBkaXNhIGluZm9ybWFjaW9uZSBrecOnZSBxZSBuYSBuZGlobW9qbmUgbmUgaW50ZXJwcmV0aW1pbiBlIHJlenVsdGF0ZXZlLioqDQoNCioqMS4JVGVzdCBpIGtyeWVyIGVzaHRlIHRlc3RpIEhpLWthdHJvciBpIFBlYXJzb24taXQuKioNCg0KKioyLglWbGVyYSBlIHRlc3RpdCBIaS1rYXRyb3IgZXNodGUgNy4zMzM4LioqDQoNCioqMy4JTnVtcmkgaSBzaGthbGxldmUgdGUgbGlyaXNlIGVzaHRlIDguKioNCg0KKio0LglQLXZsZXJhIGUgdGVzdGl0IGVzaHRlIDAuMjIwMi4qKg0KDQoqKkludGVycHJldGltaSBpIGtldHlyZSByZXp1bHRhdGV2ZSBlc2h0ZSBzaSBtZSBwb3NodGU6KioNCg0KKirigKIJVmxlcmEgZSB0ZXN0aXQgSGkta2F0cm9yIDcuMzMzOCB0cmVnb24gc2UgZGlmZXJlbmNhIG1pZGlzIHRlIGRoZW5hdmUgdGUgdmV6aGd1YXJhIGRoZSB0ZSBwcmFudWFyYSBudWsgZXNodGUgc2h1bWUgZSBtYWRoZS4qKg0KDQoqKuKAoglQLXZhbHVlIDAuNTAxMSBlc2h0ZSBtZSBlIG1hZGhlIHNlIG5pdmVsaSBpIHpha29uc2hlbSBpIHJlbmRlc2lzZSAocC12YWx1ZSA+IDAuMDUpLiBLam8gZG8gdGUgdGhvdGUgc2UgbnVrIG11bmQgdGUgcmVmdXpvam1lIGhpcG90ZXplbiB6ZXJvLCBlIGNpbGEgc3Vwb3pvbiBwYXZhcmVzaSBzdGF0aXN0aWtvcmUgbWlkaXMgZHkgdmFyaWFibGF2ZSBuZSB0YWJlbGUuKioNCg0KDQoqKlRlc3RpIEhpLWthdHJvciBwZXIgbmRyeXNob3JldCAkZ2ppbmlhJCBkaGUgJG1ldG9kYSQgJGUkICRwYWdlc2VzOiQqKg0KYGBge3J9DQp0ZXN0MyA8LSBjaGlzcS50ZXN0KHRhYmVsYTMpDQp0ZXN0Mw0KYGBgDQoNCioqTmUga2V0ZSByZXp1bHRhdCwga2EgZGlzYSBpbmZvcm1hY2lvbmUga3nDp2UgcWUgbmEgbmRpaG1vam5lIG5lIGludGVycHJldGltaW4gZSByZXp1bHRhdGV2ZS4qKg0KDQoqKjEuCVRlc3QgaSBrcnllciBlc2h0ZSB0ZXN0aSBIaS1rYXRyb3IgaSBQZWFyc29uLWl0LioqDQoNCioqMi4JVmxlcmEgZSB0ZXN0aXQgSGkta2F0cm9yIGVzaHRlIDEuNDMxNS4qKg0KDQoqKjMuCU51bXJpIGkgc2hrYWxsZXZlIHRlIGxpcmlzZSBlc2h0ZSA0LioqDQoNCioqNC4JUC12bGVyYSBlIHRlc3RpdCBlc2h0ZSAwLjgzODcuKioNCg0KKipJbnRlcnByZXRpbWkgaSBrZXR5cmUgcmV6dWx0YXRldmUgZXNodGUgc2kgbWUgcG9zaHRlOioqDQoNCioq4oCiCVZsZXJhIGUgdGVzdGl0IEhpLWthdHJvciA4LjI1MjcgdHJlZ29uIHNlIGRpZmVyZW5jYSBtaWRpcyB0ZSBkaGVuYXZlIHRlIHZlemhndWFyYSBkaGUgdGUgcHJhbnVhcmEgbnVrIGVzaHRlIHNodW1lIGUgbWFkaGUuKioNCg0KKirigKIJUC12YWx1ZS1qYSAwLjgzODcgZXNodGUgbWUgZSBtYWRoZSBzZSBuaXZlbGkgaSB6YWtvbnNoZW0gaSByZW5kZXNpc2UgKHAtdmFsdWUgPiAwLjA1KS4gS2pvIGRvIHRlIHRob3RlIHNlIG51ayBtdW5kIHRlIHJlZnV6b2ptZSBoaXBvdGV6ZW4gemVybywgZSBjaWxhIHN1cG96b24gcGF2YXJlc2kgc3RhdGlzdGlrb3JlIG1pZGlzIGR5IHZhcmlhYmxhdmUgbmUgdGFiZWxlLioqDQoNCg0KKipUZXN0aSBIaS1rYXRyb3IgcGVyIG5kcnlzaG9yZXQgJGRpcGxvbWltaSQgZGhlICRtZXRvZGEkICRlJCAkcGFnZXNlczokKioNCmBgYHtyfQ0KdGVzdDQgPC0gY2hpc3EudGVzdCh0YWJlbGE0KQ0KdGVzdDQNCmBgYA0KDQoqKk5lIGtldGUgcmV6dWx0YXQsIGthIGRpc2EgaW5mb3JtYWNpb25lIGt5w6dlIHFlIG5hIG5kaWhtb2puZSBuZSBpbnRlcnByZXRpbWluIGUgcmV6dWx0YXRldmUuKioNCg0KKioxLglUZXN0IGkga3J5ZXIgZXNodGUgdGVzdGkgSGkta2F0cm9yIGkgUGVhcnNvbi1pdC4qKg0KDQoqKjIuCVZsZXJhIGUgdGVzdGl0IEhpLWthdHJvciBlc2h0ZSAyLjM1Mi4qKg0KDQoqKjMuCU51bXJpIGkgc2hrYWxsZXZlIHRlIGxpcmlzZSBlc2h0ZSA4LioqDQoNCioqNC4JUC12bGVyYSBlIHRlc3RpdCBlc2h0ZSAwLjk2ODMuKioNCg0KKipJbnRlcnByZXRpbWkgaSBrZXR5cmUgcmV6dWx0YXRldmUgZXNodGUgc2kgbWUgcG9zaHRlOioqDQoNCioq4oCiCVZsZXJhIGUgdGVzdGl0IEhpLWthdHJvciAyLjM1MiB0cmVnb24gc2UgZGlmZXJlbmNhIG1pZGlzIHRlIGRoZW5hdmUgdGUgdmV6aGd1YXJhIGRoZSB0ZSBwcmFudWFyYSBudWsgZXNodGUgc2h1bWUgZSBtYWRoZS4qKg0KDQoqKuKAoglQLXZhbHVlLWphIDAuOTY4MyBlc2h0ZSBtZSBlIG1hZGhlIHNlIG5pdmVsaSBpIHpha29uc2hlbSBpIHJlbmRlc2lzZSAocC12YWx1ZSA+IDAuMDUpLiBLam8gZG8gdGUgdGhvdGUgc2UgbnVrIG11bmQgdGUgcmVmdXpvam1lIGhpcG90ZXplbiB6ZXJvLCBlIGNpbGEgc3Vwb3pvbiBwYXZhcmVzaSBzdGF0aXN0aWtvcmUgbWlkaXMgZHkgdmFyaWFibGF2ZSBuZSB0YWJlbGUuKioNCg0KDQoNCioqVGVzdGkgSGkta2F0cm9yIHBlciBuZHJ5c2hvcmV0ICAkdml0aSQgJGkkICRzdHVkaW1ldmUkIGRoZSAkbWV0b2RhJCAkZSQgJHBhZ2VzZXM6JCoqDQpgYGB7cn0NCnRlc3Q1IDwtIGNoaXNxLnRlc3QodGFiZWxhNSkNCnRlc3Q1DQpgYGANCg0KKipOZSBrZXRlIHJlenVsdGF0LCBrYSBkaXNhIGluZm9ybWFjaW9uZSBrecOnZSBxZSBuYSBuZGlobW9qbmUgbmUgaW50ZXJwcmV0aW1pbiBlIHJlenVsdGF0ZXZlLioqDQoNCioqMS4JVGVzdCBpIGtyeWVyIGVzaHRlIHRlc3RpIEhpLWthdHJvciBpIFBlYXJzb24taXQuKioNCg0KKioyLglWbGVyYSBlIHRlc3RpdCBIaS1rYXRyb3IgZXNodGUgOC4yNTI3LioqDQoNCioqMy4JTnVtcmkgaSBzaGthbGxldmUgdGUgbGlyaXNlIGVzaHRlIDYuKioNCg0KKio0LglQLXZsZXJhIGUgdGVzdGl0IGVzaHRlIDAuMjIwMi4qKg0KDQoqKkludGVycHJldGltaSBpIGtldHlyZSByZXp1bHRhdGV2ZSBlc2h0ZSBzaSBtZSBwb3NodGU6KioNCg0KKirigKIJVmxlcmEgZSB0ZXN0aXQgSGkta2F0cm9yIDguMjUyNyB0cmVnb24gc2UgZGlmZXJlbmNhIG1pZGlzIHRlIGRoZW5hdmUgdGUgdmV6aGd1YXJhIGRoZSB0ZSBwcmFudWFyYSBudWsgZXNodGUgc2h1bWUgZSBtYWRoZS4qKg0KDQoqKuKAoglQLXZhbHVlLWphIDAuMjIwMiBlc2h0ZSBtZSBlIG1hZGhlIHNlIG5pdmVsaSBpIHpha29uc2hlbSBpIHJlbmRlc2lzZSAocC12YWx1ZSA+IDAuMDUpLiBLam8gZG8gdGUgdGhvdGUgc2UgbnVrIG11bmQgdGUgcmVmdXpvam1lIGhpcG90ZXplbiB6ZXJvLCBlIGNpbGEgc3Vwb3pvbiBwYXZhcmVzaSBzdGF0aXN0aWtvcmUgbWlkaXMgZHkgdmFyaWFibGF2ZSBuZSB0YWJlbGUuKioNCg0KDQoNCiMjIyAqKmByIGNvbG9yaXplKCJQYXJhcWl0amUgR3JhZmlrZSIsICJibHVlIilgKioNCg0KIyMjIyAkJFZJWlVBTElaSU1JXCBJXCBURVwgREhFTkFWRSQkDQoNCioqJFZpenVhbGl6aW1pJCAkaSQgJHRlJCAkZGhlbmF2ZSQgZXNodGUgdGVrbmlrYSBlIHBlcmRvcnVyIHBlciB0ZSBkaGVuZSBuam9odXJpIG5lIHRlIGRoZW5hIGR1a2UgcGVyZG9ydXIgbWV0b2RhIHZpenVhbGUgc2kgZ3JhZmlrZXQsIGRpYWdyYW1hdCwgaGlzdG9ncmFtYXQsIGhhcnRhdCBkaGUgc2h1bWUgdHJhanRhIHRlIHRqZXJhLiBLam8gZXNodGUgZSBkb2Jpc2htZSBwYXNpIG5kaWhtb24gbmUga3VwdGltaW4gaW50dWl0aXYgZGhlIHRlIGxlaHRlIHRlIHNhc2l2ZSB0ZSBtZWRoYSB0ZSB0ZSBkaGVuYXZlIGRoZSBuZSBrZXRlIG1lbnlyZSBwZXIgdGUgbWFycmUgdmVuZGltZSBtZSB0ZSBtaXJhIG5lIGxpZGhqZSBtZSB0by4qKg0KDQoqKlIgZXNodGUgbmplIGdqdWhlIHFlIGVzaHRlIGtyaWp1YXIgcGVyIGxsb2dhcml0amUgc3RhdGlzdGlrb3JlLCBhbmFsaXphIGdyYWZpa2UgdGUgdGUgZGhlbmF2ZSBkaGUga2Vya2ltZSBzaGtlbmNvcmUuIFpha29uaXNodCBwcmVmZXJvaGV0IHBlciB2aXp1YWxpemltaW4gZSB0ZSBkaGVuYXZlIHBhc2kgb2Zyb24gZmxla3NpYmlsaXRldCBkaGUga29kaW0gbWluaW1hbCB0ZSBrZXJrdWFyIHBlcm1lcyBwYWtldGF2ZSB0ZSBzYWouKioNCg0KKipWaXp1YWxpemltaSBpIHRlIGRoZW5hdmUgbmUgYW5hbGl6ZW4gZSB0ZSBkaGVuYXZlIGthIHJlbmRlc2kgdGUgbWFkaGUgcGVyIGRpc2EgYXJzeWU6KioNCg0KKioxLglLdXB0aW1pIGkgbWlyZSBpIHRlIGRoZW5hdmU7KioNCg0KKioyLglJbnRlcnByZXRpbWkgaSByZXp1bHRhdGV2ZTogVml6dWFsaXppbWkgaSB0ZSBkaGVuYXZlIGVzaHRlIG5qZSBtZW55cmUgZSBtaXJlIHBlciB0ZSBrb211bmlrdWFyIHJlenVsdGF0ZXQgZSBhbmFsaXplcy4gR3JhZmlrZXQgamFuZSBtZSB0ZSBsZWh0ZSBwZXIgdCd1IGt1cHR1YXIgZGhlIHBlciB0ZSBzaHBqZWd1YXIgc2Ugc2kgbmRyeXNob2puZSB0ZSBkaGVuYXQgbmUga29oZSwgaGFwZXNpcmUgb3NlIG5kYWogbmplIHZhcmlhYmxpIHRqZXRlci4qKg0KDQoqKjMuCVpidWxpbWkgaSBtb2RlbGV2ZSBkaGUgdGVuZGVuY2F2ZTsqKg0KDQoqKlNpZ3VyaXNodCwgcGVyIHBhcmFxaXRqZW4gZ3JhZmlrZSBzYSBtZSBlZ3pha3RlIGRoZSBlc3RldGlrZSB0ZSB0ZSBkaGVuYXZlIGRvIHRlIG5hIGR1aGVuIGRpc2EgbGlicmFyaSBrcnllc29yZSwgc2ljIGphbmUgJGdncGxvdDIkLCAkY29ycmVsYXRpb24kLCAkZ2dwdWJyJCAmICR0aWR5ciQsICRkYXRhRXhwbG9yZXIkIGV0ai47KioNCg0KDQoNCiMjIyMgJCRIaXN0b2dyYW1pJCQNCg0KKipOamUgJGhpc3RvZ3JhbSQgZXNodGUgbmplIHBhcmFxaXRqZSB2aXp1YWxlIGUgc2hwZXJuZGFyamVzIHNlIHRlIGRoZW5hdmUgc2FzaW9yZS4gQXRhIGphcGluIG5qZSBrdXB0aW0gdGUgcGVyYWZlcnQgdGUgZGVuc2l0ZXRpdCBkaGUgc2hwZXNoIGhlcmUgdmxlcmVuIGUgc2FrdGUgdGUgdGlqLioqDQoNCioqTWUgcG9zaHRlIGRvIHRlIG5kZXJ0b2ptZSBuamUgaGlzdG9ncmFtIHBlciB2YXJpYWJsaW4gdG9uZSBzYXNpb3IgJG1vc2hhJC4gRG8gdGUgbmEgZHVoZW4gMiBsaWJyYXJpIGtyeWVzb3JlOiAkZ2dwbG90MiQgZSBjaWxhIHNoZXJiZW4gcGVyIG5kZXJ0aW1pbiBlIGdyYWZpa2V2ZSBkaGUgbGlicmFyaWEgJHNjYWxlcyQgZSBjaWxhIGRvIHRlIG5hIHNoZXJiZWplIHBlciBrb3N0dW1pemltaW4gZSBncmFmaWt1dC4qKg0KDQoqKlBlciB0ZSBwYXJhcWl0dXIgZ3JhZmlraXNodCBuamUgbmRyeXNob3JlIHNhc2lvcmUgdGUgdmF6aGR1ZXNobWUgbmRlcnRvaGV0IG5qZSBoaXN0b2dyYW0uKioNCg0KKipQZXIga2V0ZSBxZWxsaW0gaW50ZXJ2YWxpIEkgdmxlcmF2ZSB0ZSBtdW5kc2htZSB0ZSB0aXBhcml0IG5kYWhldCBuZSBuamUgbnVtZXIgaW50ZXJ2YWxlc2ggb3NlIGtsYXNhc2guKioNCg0KKipIaXN0b2dyYW1pIHBhcmFxZXQgc2Ugc2EgZXNodGUgbnVtcmkgaSBzdHVkZW50ZXZlIHBlciBzZWNpbGVuIGdydXBtb3NoZSBkdWtlIGZpbGx1YXIgbmdhIDE4IHZqZWMgZGVyaSBuZSAyNS4gTmdhIGxhcnRlc2lhIGUga29sb25hdmUgdmVtZSByZSBzZSBwamVzZW4gbWUgdGUgbWFkaGUgZSB6ZSBtb3NoYSAyNSB2amVjIChtb2RhKSBkaGUgbWUgdGUgdm9nbGVuIG1vc2hhIDE5IHZqZWMuKioNCg0KYGBge3J9DQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHNjYWxlcykNCg0KZzEgPC0gaGlzdChkYXRhJG1vc2hhLCBicmVha3M9c2VxKDE3LjUsIDI1LjUsIGJ5PTEpLCBkZW5zaXR5ID0gNDAsIGFuZ2xlPTYwLCB4bGFiPSJHcnVwbW9zaGF0IGUgc3R1ZGVudGV2ZSIsIHlsYWI9IkVmZWt0aXZhdCIsIG1haW49Ikhpc3RvZ3JhbWkgaSBNb3NoZXMiLCBsYXM9MSwgY29sPSJwdXJwbGU0IiwgZmlsbCA9ICJwdXJwbGU0IiwNCiAgICAgICAgICB5bGltPWMoMCwyMDApLHhsaW09YygxOCwyNSksIGNleC5tYWluPTEuNCwgY2V4LmxhYj0xLjIsIGF4dD0nbicpIA0KDQoja3VzdG9taXpvam1lIGdyYWZpa3VuIG1lIGRpc2EgdmlqYSB0ZSBwamVycmV0YSA2MCAgZGVncmVlcw0KYXhpcygxLCBhdD0xODoyNSwgbGFiZWxzPTE4OjI1KQ0KdGV4dChnMSRtaWRzLCBnMSRjb3VudHMsIGxhYmVscz1pZmVsc2UoZzEkY291bnRzICE9IDAsIGcxJGNvdW50cywgIiIpLCBwb3M9MywgY2V4PTAuOCkNCg0KYGBgDQoqKlBlciB0ZSBuZGVydHVhciBoaXN0b2dyYW1pbiBuYSBzaGVyYmVuIGxpYnJhcmlhICRnZ3Bsb3QyJCBkaGUgJHNjYWxlcyQuKioNCg0KKipNZSBhbmUgdGUgdGUgZnVua3Npb25pdCAkaGlzdCgpJCBwZXJjYWt0b2ptZSBsbG9qaW4gZSBncmFmaWt1dCBxZSBkdWFtIHRlIG5kZXJ0b2ptZSwgbmUga2V0ZSByYXN0IGhpc3RvZ3JhbS4qKg0KDQoqKiRkYXRhJGAkYCRtb3NoYSQ6IHRoZXJyYXNpbSB0ZSBkaGVuYXQgdGUgY2lsYXQgZG8gdGUgcGFyYXFlc2ltIG5lIGhpc3RvZ3JhbS4qKg0KDQoqKiRicmVha3M9c2VxKDE3LjUsIDI1LjUsIGJ5PTEpJCBwZXJjYWt0b24ga3VmaWp0ZSBlIGhpc3RvZ3JhbWl0LCBxZSB2YXJpb2puZSBuZ2EgMTcuNSBuZSAyNS41LCBtZSBoYXAgMS4qKg0KDQoqKiRkZW5zaXR5PTQwJDogZGVuZHVyaWEgZSB2aWphdmUgYnJlbmRhIHNodHlsbGF2ZSB0ZSBoaXN0b2dyYW1pdDsqKg0KDQoqKiRhbmdsZT02MCQ6IHZlbmRvc2ltIG5qZSBrZW5kIHBlciB2aWphdCBicmVuZGEgaGlzdG9ncmFtaXQ7KioNCg0KKiokeGxhYiQsICR5bGFiJCBkaGUgJG1haW4kOiBwZXJjYWt0b2puZSBlbWVydGltaW4gZSBib3NodGV2ZSB4LCB5IGRoZSB0aXR1bGxpbiBlIGhpc3RvZ3JhbWl0OyoqDQoNCioqJGxhcz0xJCBwb3ppY2lvbm9uIGVtZXJ0aW1ldCBlIGJvc2h0ZXZlOyoqDQoNCioqVmVuZG9zaW0gbmdqeXJhdCBtZSBhbmUgdGUgZnVua3Npb25pdCAkY29sPSIiJDsqKg0KDQoqKiR5bGltPWMoMCwyMDApJCBkaGUgJHhsaW09YygxOCwgMjUpJCB2ZW5kb3Mga3VmaWp0ZSBlIHZsZXJhdmUgdGUgaGlzdG9ncmFtaXQ7KioNCg0KKiokY2V4Lm1haW49MS40JCBkaGUgJGNleC5sYWI9MS4yJCBycml0IG1hZGhlc2luZSBlIHNoa3JpbWl0IHRlIHRpdHVsbGl0IGtyeWVzb3JlIGRoZSBlbWVydGltZXZlIHRlIGJvc2h0ZXZlOyoqDQoNCioqJGF4dD1uJCBoZXEgZW1lcnRpbWV0IGUgbWVwYXJzaG1lIHRlIGJvc2h0aXQgeDsqKg0KDQoqKiRheGlzKDEsIGF0PTE4OjI1LCBsYWJlbHM9MTg6MjUpJCBzaHRvbiBzaGVuamF0IGRoZSBlbWVydGltZXQgZSBidXNodGl0IHggbmdhIDE4IG5lIDI1OyoqDQoNCioqJHRleHQoZzEkYCRgJG1pZHMkLCAkZzEkYCRgJGNvdW50cyQsICRsYWJlbHM9aWZlbHNlJCgkZzEkYCRgJGNvdW50cyQgJCE9MCQsICRnMSRgJGAkY291bnRzJCwg4oCc4oCdKSwgJHBvcz0zJCwgJGNleD0wLjgpJCBzaHRvbiB2bGVyYXQgbnVtZXJpa2Ugc2lwZXIgY2RvIHNodHlsbGUsIHBvciB2ZXRlbSBuZSByYXN0ZXQga3VyIHZsZXJhdCBqYW5lIHRlIG5kcnlzaG1lIG5nYSB6ZXJvLiBQYXJhbWV0cmkgJHBvcz0zJCBwb3ppY2lvbm9uIHZsZXJhdCBuZGVyc2EgJGNleD0wLjgkIHBlcmNha3RvbiBtYWRoZXNpbmUgZSBzaGtyaW1pdC4qKg0KDQoqKkludGVycHJldGltaSBpIGhpc3RvZ3JhbWl0IGVzaHRlIHJlbGF0aXZpc2h0IGkgdGhqZXNodGUuIFNob2hpbSBxZSBzaHBlcm5kYXJqYSBlIHN0dWRlbnRldmUgZXNodGUgZSB0aWxsZTogMTI0IGluZGl2aWRlIGthbmUgbW9zaGVuIDE4IHZqZWNhcmUsIDEwOCBqYW5lIDE5IHZqZWNhcmUsIDExMSBqYW5lIDIwIHZqZWNhcmUsIDExOCBqYW5lIDIxIHZqZWNhcmUsIDEzMCBqYW5lIDIyIHZqZWNhcmUsIDEyOCBrYW5lIG1vc2hlbiAyMyB2amVjLCAxMzYgamFuZSAyNCB2amVjYXJlIGRoZSAxNDUgamFuZSAyNSB2amVjYXJlLiBBam8gcWUgdmloZXQgcmUgdGpldGVyIGVzaHRlIGVkaGUgc2UgY2lsYSBuZ2EgZ3J1cG1vc2hhdCBlc2h0ZSBtZSBlIHNocGVzaHRlOiBlc2h0ZSBham8gMjUgdmplY2FyZSBtZSAxNDUgaW5kaXZpZGUsIG5kZXJzYSBham8gbWUgcGFrIGVzaHRlIGdydXBtb3NoYSAxOSB2amVjYXJlIG1lIDEwOCBpbmRpdmlkZS4qKg0KDQoNCiMjIyMgJCRHcmFmaWtldFwgVmlvbGluZSQkDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShncmlkRXh0cmEpDQoNCnZpb2xpbnBsb3QxIDwtIGdncGxvdChkYXRhLCBhZXMoeCA9ICIiLCB5PWRhdGEkdGVfYXJkaHVyYXRfbXVqb3JlKSkgKw0KICBnZW9tX3Zpb2xpbihmaWxsPSJkb2RnZXJibHVlMiIsIGNvbG9yPSJibGFjayIpICsNCiAgbGFicyh0aXRsZSA9ICJWaW9saW4gUExvdCBwZXIgdGUgQXJkaHVyYXQgTXVqb3JlIiwgeD0iVGUgQXJkaHVyYXQgTXVqb3JlIiwgeT0iU2hwZXJuZGFyamEiKQ0KDQp2aW9saW5wbG90MiA8LSBnZ3Bsb3QoZGF0YSwgYWVzKHggPSAiIiwgeT1kYXRhJG5kaWhtYV9maW5hbmNpYXJlKSkgKw0KICBnZW9tX3Zpb2xpbihmaWxsPSJkb2RnZXJibHVlMiIsIGNvbG9yPSJibGFjayIpICsNCiAgbGFicyh0aXRsZSA9ICJWaW9saW4gUExvdCBwZXIgTmRpaG1lbiBGaW5hbmNpYXJlIiwgeD0iTmRpaG1hIEZpbmFuY2lhcmUiLCB5PSJTaHBlcm5kYXJqYSIpDQoNCmdyaWQuYXJyYW5nZSh2aW9saW5wbG90MSwgdmlvbGlucGxvdDIsIG5jb2w9MikNCmBgYA0KDQoqKkZvcm1hIGUgZ3JhZmlrdXQgdmlvbGluZSB0cmVnb24gc2hwZXJuZGFyamVuIGUgdGUgYXJkaHVyYXZlIG11am9yZSBkaGUgdGUgbmRpaG1lcyBmaW5hbmNpYXJlLiBOZSBwamVzZXQga3UgZ3JhZmlrdSBlc2h0ZSBtZSBpIGdqZXJlIGRvIHRlIHRob3RlIHNlIGthIG1lIHNodW1lIHRlIGRoZW5hIHJyZXRoIGF0eXJlIHZsZXJhdmUuIEt1ciBlc2h0ZSBtZSBpIG5ndXNodGUgYXRlaGVyZSBrYSBtZSBwYWsgdGUgZGhlbmEuIFZsZXJhIG1lc2F0YXJlIHRyZWdvaGV0IG5nYSBicmV6aSBtZSBpIGdqZXJlIHFlIG5kb2RoZXQgbmUgcWVuZGVyLiBOamUgc2hwZXJuZGFyamUgbWUgdGUgbWFkaGUga2FuZSB2bGVyYXQgcWUgamFuZSB0ZW9yaWtpc2h0IG1pZGlzIDEyNTAtMTUwMCwgcGFzaSBhdHkgZGFsbG9oZXQgbmplIGJyZXogbWUgaSBnamVyZS4gTmRlcnNhIG5lIHJhc3RpbiBlIG5kcnlzaG9yZXMgdGpldGVyIHZsZXJhdCBrYW5lIG5qZSBzaHBlcm5kYXJqZSBtZSB0ZSBsYXJ0ZSBuZSBpbnRlcnZhbGluIDUwMC02MDAuIFByYSAsdGUgYXJkaHVyYXQgbXVqb3JlIG1lc2F0YXJlIHNpcGFzIGdyYWZpa3V0IGphbmUgYWZlcnNpc2h0ICQxMDIwLjY1ICxuZGVyc2EgbmRpaG1hIGZpbmFuY2lhcmUgbWVzYXRhcmUgZXNodGUgIGFmZXJzaXNodCAkNTA0KioNCg0KDQoNCiMjIyMgJCRCb3ggcGxvdCQkDQoNCioqTmplICRib3gkICRwbG90JCBlc2h0ZSBuamUgbGxvaiBncmFmaWt1IHN0YXRpc3Rpa29yIGkgY2lsaSBvZnJvbiBuamUgcGVybWJsZWRoamUgdml6dWFsZSB0ZSBzaHBlcm5kYXJqZXMgc2UgbmplIGdydXBpIHRlIGRoZW5hc2guIEFpIHNoZmFxIGluZm9ybWFjaW9uaW4ga3J5ZXNvciB0ZSBtZXBvc2h0ZW06KioNCg0KKioxLiBNZXNvcmVuOiBWbGVyYSBtZXNvcmUgcGVyZmFxZXNvaGV0IG5nYSB2aWphIGhvcml6b250YWxlIGJyZW5kYSBrdXRpc2U7KioNCg0KKioyLiBJbnRlcnZhbGkgTmRlcmt1YXJ0aWxvcjoga3V0aWEgcGVyZmFxZXNvbiA1MCUgdGUgdmxlcmF2ZSB0ZSBtZXNpdCB0ZSB0ZSBkaGVuYXZlLCBmdW5kaSBJIHNhaiB0cmVnb24gMjUlIHRlIHRlIGRoZW5hdmUgZGhlIHBqZXNhIGUgc2lwZXJtZSB0cmVnb24gNzUlIHRlIHR5cmUuIElRUiBlc2h0ZSBkaWZlcmVuY2EgUTMg4oCTIFExLioqDQoNCioqMy4gVmxlcmF0IG1ha3NpbWFsZSBkaGUgbWluaW1hbGU6IGphbmUgYXRvIHZpamEgdmVydGlrYWxlIHFlIGRhbGluIG5nYSBrdXRpYS4qKg0KDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCg0KZ2dwbG90KGRhdGEpK2Flcyh4PW1vc2hhLCB5PWdqaW5pYSwgZmlsbD12aXRpX2lfc3R1ZGltZXZlLCBjb2xvdXIgPSB0ZV9hcmRodXJhdF9tdWpvcmUsIHNpemU9bmRpaG1hX2ZpbmFuY2lhcmUpKw0KICBnZW9tX2JveHBsb3QoKSsgc2NhbGVfZmlsbF9odWUoZGlyZWN0aW9uPTIpICsgc2NhbGVfY29sb3JfZ3JhZGllbnQoKSArDQogIGxhYnMoeD0iTW9zaGEiLCB5PSJHamluaWEiLCBmaWxsPSJWaXRpIGkgU3R1ZGltZXZlIikrDQogIHRoZW1lX2NsYXNzaWMoKQ0KYGBgDQoNCioqTmUga2V0ZSBncmFmaWsgZXNodGUgcGFyYXFpdHVyIG5qZSBib3hwbG90IGkgY2lsaSB0cmVnb24gbGlkaGplbiBtaWRpcyBnamluaXNlIGRoZSB2aXRpdCB0ZSBzdHVkaW1pdCB0ZSBzdHVkZW50ZXZlLiBQZXIgZ2ppbmluZSBmZW1lcm9yZSBqYW5lIHBhcmFxaXR1ciA0IGJveC1wbG90ZSBwZXIga2F0ZWdvcmluZSBlIEZyZXNobWFuLCBKdW5pb3IsIFNlbmlvciwgU29waG9tb3JlLiBOZ2EgYm94LXBsb3RldCBhcnJpam1lIHRlIGRhbGxvam1lIHFlIHZsZXJhIG1pbiBwZXIgdGUga2F0ZXJ0IGVzaHRlIDE4LCBuZGVyc2EgdmxlcmEgbWF4IDI1LiBLZXRvIGphbmUgZHkgdmxlcmF0IG5lIHNrYWplLiBBbmEgZSBtYWp0ZSB0cmVnb24ga3VhcnRpbGluIGUgcGFyZSBxZSBuZSByYXN0aW4gZSBTb3Bob21vcmUgZGhlIEp1bmlvciBlc2h0ZSAyMCwgbmRlcnNhIHBlciBTZW5pb3IgZGhlIEZyZXNobWFuIGVzaHRlIDE5LiBWaWphIG5lIG1lcyB0cmVnb24gJG1lc29yZW4kLCBwZXJrYXRlc2lzaHQgMjEgcGVyIEp1bmlvciBkaGUgU2VuaW9yIGRoZSAyMiBwZXIgRnJlc2htYW4gZGhlIFNvcGhvbW9yLiBBbmEgZSBkamF0aHRlIHRyZWdvbiBrdWFydGlsaW4gZSB0cmV0ZSwgMjQgcGVyIFNvcGhvbW9yZSBkaGUgMjMgcGVyIEp1bmlvciBkaGUgU2VuaW9yLiBNZXFlIGphc2h0ZSBib3gtcGxvdGl0IG51ayBrZW1pIHBpa2EgdGUgdGplcmEgYXRlaGVyZSB0aGVtaSBzZSBudWsga2EgJG91dGxpZXJzwqckLiBOamVzb2ogdmVwcm9qbWUgZGhlIHBlciB0ZSB0amVyZXQuKioNCg0KDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCg0KZ2dwbG90KGRhdGEsIGFlcyh4PWdqaW5pYSwgeT1tb3NoYSwgZmlsbD1namluaWEpKSArIA0KICBnZW9tX2JveHBsb3Qob3V0bGllci5zaGFwZSA9IE5BKSsNCiAgZ2VvbV9qaXR0ZXIoYWVzKGNvbG9yPWdqaW5pYSwgc2hhcGU9Z2ppbmlhKSwgd2lkdGg9MC4yLCBzaXplPTEuNSkgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoImJsYWNrIiwgImdvbGQiLCAicmVkIikpKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJibHVlIiwgInJlZCIsICJncmVlbiIpKSsNCiAgbGFicyh0aXRsZSA9ICJCb3ggUGxvdCBHamluaWF+TW9zaGEiLCB4PSJHamluaWEiLCB5PSJNb3NoYSIsIGZpbGw9IkdqaW5pYSIsIGNvbG9yPSJHamluaWEiLCBjb2xvcj0iR2ppbmlhIiwgc2hhcGU9IkdqaW5pYSIpKyB0aGVtZV9jbGFzc2ljKCkNCmBgYA0KDQoNCioqUmV6dWx0YXRldCBkaGUgaW50ZXJwcmV0aW1pIEkgdHlyZToqKg0KDQoqKlNpcGFzIGdyYWZpa3V0IHRlIG1lc2lwZXJtLCBrdXRpdGUgZSBrcmlqdWFyYSBzaHByZWhpbiBzaHBlcm5kYXJqZW4gZSBtb3NoZXMgc2lwYXMgZ2ppbmlzZS4gTWVzZXQgZSBrdXRpc2Ugc2UgYm94LXBsb3RldmUgYmllbiBuZSBtb3NoZW4gMjIsIHBlciB0ZSB0cmVqYSByYXN0ZXQuIFBpa2F0IGppdHRlciB0cmVnb2puZSBzaHBlcm5kYXJqZW4gZSB0ZSBkaGVuYXZlIG5lIHNlY2lsaW4gZ3J1cC4qKg0KDQoqKktvZGk6KioNCg0KKipGaWxsaW1pc2h0IHRoZXJyYXNpbSBsaWJyYXJpdGUgcWUgbmEgbmV2b2ppdGVuOiAkZ2dwbG90MiQsIGUgY2lsYSBuYSBuZGlobW9uIHBlciB2aXp1YWxpemltaW4gZSB0ZSBkaGVuYXZlLioqDQoNCioqS3Jpam9qbWUgbmplIHZhcmlhYmxlIHRlIHF1YWp0dXIgJGRhdGEkIGUgY2lsYSBkbyB0ZSBwZXJtYmFqZSBkeSBwYXJhbWV0cmEga3J5ZXNvcmU6KioNCg0KKippOiAkbW9zaGEkOyoqDQoNCioqaWk6ICRnamluaWEkOyoqDQoNCioqS3JpamltaSBJIGJveCBwbG90IHBlcmdqaXRoZXNpc2h0IGVzaHRlIEkgbmplanRlIHNpIG5lIHJhc3RpbiBlIG1lc2lwZXJtLCBtZSBwZXJqYXNodGltIHRlIGZ1bmtzaW9uaXQgJGdlb20kYF9gJGppdHRlcigpJCBJIGNpbGkgc2h0b24gbmplIHNhc2kgdGUgdm9nZWwgcGlrYXNoIHFlIHRyZWdvam5lIG5qZSBzaHBlcm5kYXJqZSBzaXBhcyBrdXRpc2Ugc2UgYm94IHBsb3QuKioNCg0KKipTaHRpbWkgaSBsaW5qYXZlIHRlIHJlZmVyZW5jZXM6KioNCg0KKiokc2NhbGUkYF9gJGNvbG9yJGBfYCRtYW51YWwoKSQgdmVuZG9zIG5nanlyZW4gZSBwaWthdmUgaml0dGVyIG5lIGJveCBwbG90LiBOZ2p5cmEgYmx1IHBlcmRvcmV0IHBlciBmZW1yYXQsIGUga3VxamEgcGVyZG9yZXQgcGVyIG1lc2hrdWp0IG5kZXJzYSBnb2xkIHBlciBhdGEgbm9uLWJpbmFyeTsqKg0KDQoqKiRzY2FsZSRgX2AkZmlsbCRgX2AkbWFudWFsKCkkIHZlbmRvcyBuZ2p5cmVuIGUgbWJ1c2hqZXMgc2Uga3V0aXZlOyoqDQoNCioqJGxhYnMoKSQgc2h0b24gdGl0dWxsaW4sIGVtZXJ0aW1ldCBlIGJvc2h0ZXZlICR4JCwkeSQgZGhlIGxlZ2plbmRlbi4qKg0KDQoNCiMjIyMgJCRHcmFmaWt1XCBEZW5zaXRldCQkDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KZ2dwbG90KGRhdGEsIGFlcyh4PXVzaHFpbWkpKSsgDQogIGdlb21fZGVuc2l0eShhZXMoZmlsbD0iVXNocWltaSIpLCBhbHBoYT0wLjUpKw0KICBnZW9tX2RlbnNpdHkoYWVzKHg9c3RyZWhpbWksIGZpbGw9IlN0cmVoaW1pIiksIGFscGhhPTAuNSkrDQogICAgZ2VvbV9kZW5zaXR5KGFlcyh4PXRyYW5zcG9ydGksIGZpbGw9IlRyYW5zcG9ydGkiKSwgYWxwaGE9MC41KSsNCiAgICBnZW9tX2RlbnNpdHkoYWVzKHg9IG1qZXRldF9zaGtvbGxvcmUsIGZpbGw9Ik1qZXRldCBTaGtvbGxvcmUiKSwgYWxwaGE9MC41KSsNCiAgZ2VvbV9kZW5zaXR5KGFlcyh4PWFyZ2V0aW0sIGZpbGw9IkFyZ2V0aW1pIiksIGFscGhhPTAuNSkgKw0KICBsYWJzKHg9IlZsZXJhIiwgeT0iRGVuc2l0ZXRpIiwgdGl0bGU9IkdyYWZpa3UgRGVuc2l0ZXQgcGVyIDUgdmFyaWFibGEgbnVtZXJpa2UiLCBmaWxsPSJMZWdqZW5kYToiKSsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoImRvZGdlcmJsdWUyIiwgInJlZCIsICJwdXJwbGUzIiwgImdyZWVuMiIsICJ5ZWxsb3cyIikpKw0KICB0aGVtZV9jbGFzc2ljKCkNCmBgYA0KDQoqKlJlenVsdGF0aToqKg0KDQoqKktldHUga2VtaSBwYXJhcWl0dXIgZ3JhZmlrdW4gZSBkZW5zaXRldGV2ZSBwZXIgNSBuZHJ5c2hvcmUgbnVtZXJpa2UgKGFyZ2V0aW1pLG1qZXRldCBzaGtvbGxvcmUgLHN0cmVoaW1pLHRyYW5zcG9ydGksdXNocWltaSkuKioNCg0KKipCb3NodGkgaSB5IHBhcmFxZXQgZGVuc2l0ZXRpbiBlIHNlY2lsaXQgdmFyaWFiZWwgYnJlbmRhIGludGVydmFsaXQgdGUgdmxlcmF2ZSB0ZSBkaGVuYShib3NodGkgeCkuIERlbmRlc2lhIGkgcmVmZXJvaGV0IHNhIHNocGVzaCBuZG9kaGluIHZsZXJhdCBicmVuZGEgbmplIGludGVydmFsaSBzcGVjaWZpay4gWm9uYSBuZW4gY2RvIGt1cmJlIHBlcmZhcWVzb24gcGVycWluZGplbiBlIHRlIHRlIGRoZW5hdmUgcWUgbmRvZGhlbiBicmVuZGEgbmplIGludGVydmFsaS4gTmplIGt1cmJlIG1lIGUgbGFydGUgKGRlbnNpdGV0IG1lIHRlIGxhcnRlKSBkbyB0ZSB0aG90ZSBxZSBtZSBzaHVtZSB0ZSBkaGVuYSBrYW5lIHZsZXJhIHJyZXRoIGFzYWogcGlrZSBuZSBib3NodGluIFguIE5lIGdyYWZpa3VuIHRvbmUgc2hvaGltIHFlIGthdGVnb3JpYSAkYXJnZXRpbSQga2EgZGVuc2l0ZXQgbWUgdGUgbWFkaCBkdWtlIHFlbmUgc2Uga3VyYmEgZXNodGUgbWUgZSBsYXJ0ZSAsbmRlcnNhICRzdHJlaGltaSQga2EgZGVuc2l0ZXQgbWUgdGUgdm9nZWwuIExhcnRlc2lhIGUga3VyYmF2ZSBlc2h0ZSBzaGthbGxlenVhciBuZSBtZW55cmUgcWUgc2lwZXJmYXFqYSBuZW4ga3VyYmUgdGUgamV0ZSBlIGJhcmFiYXJ0ZSBtZSAxLioqDQoNCg0KIyMjIyAkJEdyYWZpa3VcIE1vemFpayQkDQoNCioqTmplIG5qZSBwcm9qZWt0IERhdGEgU2NpZW5jZSBlc2h0ZSBzaHVtZSBlIHJlbmRlc2lzaG1lIG54amVyamEgZSBzYSBtZSBzaHVtZSByZXp1bHRhdGV2ZSBkaGUgcGVyZnVuZGltZXZlIHRlIG5ldm9qc2htZSBuZ2EgdGUgZGhlbmF0IHRvbmEuIE5lIG5qZSBuZ2EgZmF6YXQgZSBhbmFsaXplcyBzZSB0ZSBkaGVuYXZlIGVzaHRlIGVkaGUgYWpvIGUgdml6dWFsaXppbWl0IHRlIGNpbGVuIGplbWkgZHVrZSBlIHRyYWp0dWFyIGFrdWFsaXNodC4qKg0KDQoqKk5qZSBrYXJha3RlcmlzdGlrZSBlIHZlY2FudGUgZXNodGUgbWFycmVkaGVuaWEgbWlkaXMgZHkgdmFyaWFibGF2ZS4gTmVzZSB0ZSBkeWphIHZhcmlhYmxhdCBqYW5lIGNpbGVzb3JlIChrYXRlZ29yaWtlKSwgYXRlaGVyZSwgcGVyIHRlIHNocHJlaHVyIG5qZSBtYXJyZWRoZW5pZSBtZXMgdHlyZSBuZSBwZXJkb3JpbSBhdGUgcWUgcXVoZXQgJEdyYWZpa3UkICRNb3phaWskLiBOZSBkaXNhIGRpc2lwbGluYSBudWsgbmppaGV0LCBwb3IgbmUgUiBlc2h0ZSBpIHNocGVzaHRlIGRoZSB0ZXBlciBpIG5ldm9qc2hlbSBuZSBkaXNhIHJhc3RlLioqDQoNCioqR3JhZmlrdSBNb3phaWsgYmF6b2hldCBuZSB0ZSBkaGVuYSBwcm9iYWJpbGl0YXJlLiBQZXIgdGkgbWFycmUga2V0byB0ZSBkaGVuYSBuYSBuZXZvaml0ZW4gdGFiZWxhdDsgJHRhYmVsYXQkICRlJCAka29udGlnamVuY2VzJC4qKg0KDQoqKk1lIHNpcGVyLCBuZSBrcmV1biAkVGFiZWxhdCQgJGUkICRLb250aWdqZW5jZXMkIG5lIGtlbWkgbmRlcnR1YXIga2V0byB0YWJlbGEgcGVyIHZhcmlhYmxhdCB0b25hIGthdGVnb3Jpa2UgZGhlIGdqaXRoYXNodHUgbWUgYW5lIHRlIGZ1bmtzaW9uaXQgJHByb3AudGFibGUkIG5lIGtvbnZlcnR1YW0ga2V0byB0YWJlbGEga29udGlnamVuY2UgbmUgdGFiZWxhIG1lIHZsZXJhIHByb2JhYmlsaXRhcmUuKioNCg0KKipKYW5lIHBpa2VyaXNodCBrZXRvIHRhYmVsYSB0ZSBjaWxhdCBkbyB0ZSBuYSBoeWpuZSBuZSBwdW5lLioqDQoNCioqTWUgcG9zaHRlIGVzaHRlIG5kZXJ0dWFyIG5qZSBncmFmaWsgbW96YWlrIHBlciB0YWJlbGVuIGUga2F0ZXJ0IHRlIGtvbnRpZ2plbmNlcyAkZGlwbG9taW1pJGB+YCRtZXRvZGEkYF9gJGUkYF9gJHBhZ2VzZXMkOioqDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KZ2dwbG90KGRhdGEpICsgYWVzKHg9ZGlwbG9taW1pLCB5PW1ldG9kYV9lX3BhZ2VzZXMsIGZpbGw9Z2ppbmlhLCBjb2xvdXI9dml0aV9pX3N0dWRpbWV2ZSwgZ3JvdXAgPSBtZXRvZGFfZV9wYWdlc2VzKSsNCiAgbGFicyh4PSJEaXBsb21pbWkiLCB5PSJNZXRvZGEgZSBQYWdlc2VzIiwgdGl0bGUgPSAiR3JhZmlrdSBNb3phaWsgaSBNZXRvZGVzIHNlIFByZWZlcnVhciB0ZSBQYWdlc2VzIiwgZmlsbD0iTGVnamVuZGE6IikrDQpnZW9tX3RpbGUoKSsgDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKEZlbWFsZT0iZ29sZCIsIE1hbGU9InJlZCIsYE5vbi1iaW5hcnlgPSJjeWFuIiApKSsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoRmVtYWxlPSJnb2xkIiwgTWFsZT0icmVkIiwgYE5vbi1iaW5hcnlgPSJjeWFuIikpKyANCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KKipBbmFsaXpvam1lIGtvZGluOioqDQoNCioqVmFyaWFibGkgJGRhdGEkIHBlcm1iYW4gdGUgZGhlbmF0IHRvbmE7KioNCg0KKipGdW5rc2lvbmkgJGFlcygpJCBkbyB0ZSBrb21iaW5vamUgdGUgZGhlbmF0IG5lIGVzdGV0aWthdCBlIG5kcnlzaG1lIG5lIGdyYWZpazsqKg0KDQoqKiR4ID0gZGlwbG9taW1pJDogSSBhdHJpYm9uIHZhcmlhYmxpbiAkZGlwbG9taW1pJCBib3NodGl0IHg7KioNCg0KKiokeT1tZXRvZGEkYF9gJGUkYF9gJHBhZ2VzZXMkOiBJIGF0cmlib24gdmFyaWFibGluICRtZXRvZGEkICQkZSAkcGFnZXNlcyQgYm9zaHRpdCB5OyoqDQoNCioqJGZpbGwgPSBnamluaWEkOiBkbyB0ZSBuZGlobW9qZSBuZSBuZ2p5cm9zamVuIGUgY29wZXphdmUgdGUgZ3JhZmlrdXQgbW96YWlrOyoqDQoNCioqJGNvbG9yPXZpdGkgSSBzdHVkaW1ldmUkOiBJIGF0cmlib24gdmFyaWFibGluICR2aXRpJCAkaSQgJHN0dWRpbWV2ZSQgbmdqeXJlcyBzZSBjb3BlemF2ZTsqKiANCg0KKiokZ3JvdXAgPSBtZXRvZGEkYF9gJGUkYF9gJHBhZ2VzZXMkOiBncnVwb24gY29wZXphdCBiYXp1YXIgbmUgdmFyaWFibGluICRtZXRvZGEkICRlJCAkcGFnZXNlcyQ7KioNCg0KKipFdGlrZXRpbWk6IGZ1bmtzaW9uaSAkbGFicygpJCB2ZW5kb3MgdGl0dWp0IHBlciBib3NodGV0IHgsIHkuKioNCg0KKiokZ2VvbSRgX2AkdGlsZSgpJDoga3Jpam9uIGdyYWZpa3VuIG1vemFpaywga3UgY2RvIGNvcGV6IHBlcmZhcWVzb24ga29tYmluaW1pbiBlIG5kcnlzaG9yZXZlICRkaXBsb21pbWkkIGRoZSAkbWV0b2RhJCAkZSQgJHBhZ2VzZXMkOyoqDQoNCioqTmdqeXJhdDogZnVua3Npb25ldCAkc2NhbGUkYF9gJGZpbGwkYF9gJG1hbnVhbCgpJCBkaGUgJHNjYWxlJGBfYCRjb2xvciRgX2AkbWFudWFsKCkkIHBlcmRvcmVuIHBlciB0ZSBuZ2p5cm9zdXIgc2VjaWxlbiBuZ2EgcGxsYWthdCBlIGdyYWZpa3V0IGJhenVhciBuZSBwZXJjYWt0aW1ldCAgZSBtZXNpcGVybWUuKioNCg0KKipHcmFmaWt1IG1vemFpayBwYXJhcWV0IG5qZSBwYW1qZSB2aXp1YWxlIHRlIG1hcnJlZGhlbmllcyBtaWRpcyBWYXJpYWJsYXZlICRkaXBsb21pbWkkLCAkbWV0b2RhJCAkZSQgJHBhZ2VzZXMkLCAkZ2ppbmlhJCBkaGUgJHZpdGkkICRpJCAkc3R1ZGltZXZlJC4gTWFkaGVzaWEsIG5nanlyaW1pIGRoZSBwb3ppY2lvbmltaSBJIGNvcGV6YXZlIHRlIGdyYWZpa3V0IHBlcmNqZWxsIGZyZWt1ZW5jYXQgcmVsYXRpdmUgdGUgc2VjaWxpdCBrb21iaW5pbSBwcmVqIGtldHlyZSBWYXJpYWJsYXZlIGNpbGVzb3JlLioqDQoNCg0KKipSZXp1bHRhdGV0OioqDQoNCioqTWV0b2RhIGUgUGFnZXNlczogYm9zaHRpICR5JCBzaGZhcSB0cmUgbWV0b2RhdCBlIHBhZ2VzZXM7ICRDYXNoJCwgJEFwbGlrYWNpb24kIGRoZSAkS2FydGUkICRLcmVkaXRpJC4qKg0KDQoqKkdqaW5pYTogY2RvIHBqZXNleiBuZSBncmFmaWsgZXNodGUgZSBuZ2p5cm9zdXIgcGVyIHRlIHBlcmZhcWVzdWFyIGdqaW5pbmUuKioNCg0KKipEaXBsb21pbWk6IGJvc2h0aSAkeCQgSSBrYXRlZ29yaXpvbiBuamVyZXppdCBzaXBhcyBkaXBsb21pbWl0IHRlIHR5cmUuKioNCg0KKipOZ2EgZ3JhZmlrdSBkYWxpbSBuZSBwZXJmdW5kaW1pbiBzZTogKioNCg0KKipNZXRvZGEgbWUgZSBwb3B1bGxhcml6dWFyIGUgcGFnZXNlcyBlc2h0ZSBham8gJENhc2gkLCBuZGpla3VyIG5nYSAkS2FydGEkICRlJCAkS3JlZGl0aXQvRGViaXRpdCQgZGhlIG1lIHBhayBham8gbmVwZXJtamV0IGFwbGlrYWNpb25ldmUuKioNCg0KKipLYXRlZ29yaWEgZ2ppbm9yZSBtZSBlIHNocGVzaHRlIGVzaHRlIGFqbyAkTm9uLWJpbmFyeSQgZSBjaWxhIG5kZXNoZXQgbWUgdGVwZXIgbmUgZ3JhZmlrIChuZ2p5cmEgYmx1IGUgY2VsZXQpLioqDQoNCioqTWVzIHRlIGRpcGxvbXVhcnZlIGFwbGlrYWNpb25ldCBqYW5lIG1lIHBhayB0ZSBwZXJkb3J1cmEgc2Uga2FydGF0IGUga3JlZGl0aXQuKioNCg0KIyMjIyAqS3VqZGVzOiBncmFmaWt1IG1vemFpayBudWsgbmEgdHJlZ29uIGFzZ2plIHBlciBudW1yaW4gZSBwZXJzb25hdmUgcWUgcGVyZG9yaW4ga2V0byBtZXRvZGEgcGFnZXNlOyoNCg0KKipNYWRoZXNpYSBlIGNvcGV6YXZlIG51ayB0cmVnb24gYXNuamVoZXJlIHNlIHNhIGVzaHRlIG51bXJpIGkgaW5kaXZpZGV2ZSBxZSBlIHBlcmJlam5lIGF0ZSBwamVzZS4gQWpvIHRyZWdvbiB2ZXRlbSBwcm9wb3JjaW9uaW4gcmVsYXRpdmUgYnJlbmRhIGNkbyBrYXRlZ29yaWUgdGUgbWV0b2RlcyBzZSBwcmVmZXJ1YXIgdGUgcGFnZXNlcy4qKg0KDQojIyMjICQkR3JhZmlrdVwgbWVcIFNodHlsbGEkJA0KDQpgYGB7cn0NCmxpYnJhcnkocGxvdGx5KQ0KcGxvdF9seSAoZGF0YSwgeD1+ZGlwbG9taW1pLCBjb2xvciA9fiBtZXRvZGFfZV9wYWdlc2VzLCBjb2xvcnM9IkFjY2VudCIpDQpgYGANCg0KKipHcmFmaWt1dCB0ZSBjaWxpdCBpIHJlZmVyb2hlbWkgZXNodGUgbmplIGdyYWZpayBtZSBzaHR5bGxhIHFlIHRyZWdvbiBwZXJkb3JpbWluIGUgbWV0b2RhdmUgdGUgbmRyeXNobWUgdGUgcGFnZXNlcyBuZSBkaXNpcGxpbmEgdGUgbmRyeXNobWUgYWthZGVtaWtlLioqIA0KDQoqKk5nYSBncmFmaWt1IGFycmlqbWUgdGUgZGFsbG9qbWUgcWUgc3R1ZGVudGV0IGUgc2hrZW5jYXZlIGtvbXBqdXRlcmlrZSBkaGUgaW54aGluaWVyaXNlIGR1a2VuIGtyeWVzaXNodCBpbmRpZmVyZW50ZSwgZHVrZSBzaGZhcXVyIHBhayBuZHJ5c2hpbWUgbmUgemdqZWRoamV0IGUgdHlyZSB0ZSBtZXRvZGVzIHNlIHBhZ2VzZXMuIE5qZSBrb250cmFzdCBpIGZvcnRlIHNoZmFxZXQgbWlkaXMgc3R1ZGVudGV2ZSB0ZSBla29ub21pc2UgZGhlIGJpb2xvZ2ppc2UgLGt1IGVnemlzdG9qbmUgcGFiYXJhemkgdGUga29uc2lkZXJ1ZXNobWUgbmUgcHJlZmVyZW5jYXQgZSB0eXJlIG1pZGlzIHBhZ2VzYXZlIGVsZWt0cm9uaWtlIGRoZSBhdHlyZSBtZSBwYXJhLioqIA0KDQoqKkdqaXRoYXNodHUgZGhlIHN0dWRlbnRldCBlIHBzaWtvbG9namlzZSBzaGZhcWluIHBhYmFyYXppIHRlIGR1a3NobWUgbmUgemdqZWRoamVuIGUgbWV0b2RlcyBzZSBwYWdlc2VzICxrdSBtZSBlIHByZWZlcnVhciByZXp1bHRvbiAkTW9iaWxlJCAkUGF5bWVudCQgJEFwcCQuIEtqbyBtZXRvZGUgcmV6dWx0b24gZ2ppdGhhc2h0dSBlIHByZWZlcnVhciBkaGUgbmdhIHN0dWRlbnRldCBlIGlueGhpbmllcmlzZS4gTmRlcnNhIHBlciBzdHVkZW50ZXQgZSBla29ub21pc2UgZGhlIGJpb2xvZ2ppc2UgbWUgZSBwcmVmZXJ1YXJhIHJlenVsdG9uIG1ldG9kYSAkQ3JlZGl0L0RlYml0JCAkQ2FyZCQuKioNCg0KDQojIyMjICQkUGllXCBDaGFydCQkDQoNCioqS29kaSBJIG1lcG9zaHRlbSBhZmlzaG9uIG5qZSAkcGllJCAkY2hhcnQkIHFlIHZpenVhbGl6b24gc2hwZW56aW1ldCB0b3RhbGUgbmUga2F0ZWdvcmkgdGUgbmRyeXNobWUgc2hwZW56aW1lc2ggcGVyIHRlIGRoZW5hdCB0b25hIG51bWVyaWtlLioqDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQoNCnNocGVuemltZXRfdG90YWxlIDwtIGRhdGEuZnJhbWUoIGthdGVnb3JpdGVfZV9zaHBlbnppbWl0ID0gYygic2hrb2xsaW1pIiwic3RyZWhpbWkiLCJ1c2hxaW1pIiwidHJhbnNwb3J0aSIsIm1qZXRldF9zaGtvbGxvcmUiLCJhcmdldGltIiwia3VqZGVzaV9wZXJzb25hbCIsInRla25vbG9namkiLCJtaXJlcWVuaWFfc2hlbmRldGVzb3JlIiwidGVfbmRyeXNobWUiKSwNCnNocGVuemltZXQgPSBjKHN1bShkYXRhJHNoa29sbGltaSksIHN1bShkYXRhJHN0cmVoaW1pKSwgc3VtKGRhdGEkdXNocWltaSksIHN1bShkYXRhJHRyYW5zcG9ydGkpLCBzdW0oZGF0YSRtamV0ZXRfc2hrb2xsb3JlKSwgc3VtKGRhdGEkYXJnZXRpbSksIHN1bShkYXRhJGt1amRlc2lfcGVyc29uYWwpLCBzdW0oZGF0YSR0ZWtub2xvZ2ppKSwgc3VtKGRhdGEkbWlyZXFlbmlhX3NoZW5kZXRlc29yZSksIHN1bShkYXRhJHRlX25kcnlzaG1lKSkpDQoNCiNsbG9nYXJpdGltIHBlcnFpbmRqZW4gcGVyIHNlY2lsZW4ga2F0ZWdvcmk6DQpzaHVtYV90b3RhbGUgPC0gc3VtKHNocGVuemltZXRfdG90YWxlJHNocGVuemltZXQpDQpzaHBlbnppbWV0X3RvdGFsZSRwZXJjZW50YWdlIDwtIHJvdW5kKHNocGVuemltZXRfdG90YWxlJHNocGVuemltZXQgLyBzaHVtYV90b3RhbGUgKiAxMDAsIDIpDQoNCiNncmFmaWt1DQpnZ3Bsb3Qoc2hwZW56aW1ldF90b3RhbGUsIGFlcyh4PSIiLCB5PXNocGVuemltZXQsIGZpbGw9a2F0ZWdvcml0ZV9lX3NocGVuemltaXQsIHR5cGU9JzNEIHBpZScpKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5Iiwgd2lkdGggPSAyKSArDQogIGdlb21fdGV4dChhZXMobGFiZWw9cGFzdGUwKHBlcmNlbnRhZ2UsICIlIikpLCBwb3NpdGlvbj1wb3NpdGlvbl9zdGFjayh2anVzdD0wLjYpLCBzaXplID0gMiwgY29sb3I9ImJsYWNrIiwgZm9udGZhY2U9ImJvbGQiKSArIA0KY29vcmRfcG9sYXIoInkiLCBzdGFydD0xKSsNCiAgbGFicyh0aXRsZT0iU2hwZW56aW1ldCBUb3RhbGUgc2lwYXMgS2F0ZWdvcml2ZSIsIHg9TlVMTCwgeT1OVUxMKSsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygibGlnaHRibHVlIiwgIm9yYW5nZSIsICJncmVlbiIsICJyZWQiLCJibHVlIiwieWVsbG93IiwibWFyb29uMyIsICJjeWFuIiwgInBpbmsyIiwicHVycGxlIikgKSsNCiAgdGhlbWVfdm9pZCgpKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0PTAuNSwgc2l6ZT0xNSwgZmFjZT0iYm9sZCIpLA0KICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTgpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQ0KICANCmBgYA0KDQoNCioqSW50ZXJwcmV0aW1pOioqDQoNCioqS29kaSBrcmlqb24gbmplIHBlcm1ibGVkaGplIHRlIHRlIGdqaXRoYSBzaHVtYXZlIHRlIHNocGVuenVhcmEgcGVyIHRlIGdqaXRoYSBrYXRlZ29yaXRlIChzaGtvbGxpbWksIHVzaHFpbWksIHRyYW5zcG9ydGkgZXRqLikuICoqDQoNCioqMS4gJHNocGVuemltZXQkYF9gJHRvdGFsZSQgcGFyYXFldCBzaHVtZW4gdG90YWxlIHRlIHRlIGdqaXRoYSBzaHBlbnppbWV2ZSB0ZSBrcnllcmEuKioNCg0KKioyLiAkTGxvZ2FyaXRqYSQgJGUkICRwZXJxaW5kamV2ZSQ6IGtvZGkgbGxvZ2FyaXQgcGVycWluZGplbiBlIHNlY2lsZXMgbmdhIHNocGVuemltZXQgdG90YWxlIHRlIGtyeWVyYSwgY2ZhcmUgcGplc2UgZG8gdGUgemVyZSBzZWNpbGEgcGplc2UgZSBzaHBlbnppbWV2ZSBuZSBwaWUgY2hhcnQuIEF0byBkbyB0ZSBwYXJhcWl0ZW4gdGUgcnJ1bWJ1bGxha29zdXJhIG5lIDIgc2hpZnJhIHBhcyBwcmVzamVzIGRoamV0b3JlLioqDQoNCioqMy4gVml6dWFsaXppbWkgSSBwaWUgY2hhcnQtaXQ6IEZ1bmtzaW9uaSAkZ2dwbG90KCkkIHBlcmRvcmV0IHBlciB0ZSBrcmlqdWFyIGtldGUgZ3JhZmlrLioqDQoNCioqRnVua3Npb25pICRhZXMoKSQgbGlkaCBrYXRlZ29yaXRlIGUgc2hwZW56aW1ldmUgbWUgJGZpbGwoKSQgYWVzdGhldGljIGRoZSBzaHBlbnppbWV0IHRvdGFsZSBtZSB5IGFlc3RoZXRpYy4qKg0KDQoqKkZ1bmtzaW9uaSAkZ2VvbSRgX2AkYmFyKCkkIHBlcmRvcmV0IHBlciB0ZSBrcmlqdWFyIGNvcGV0aW1ldC9jb3BhdCBlIGdyYWZpa3V0IHBpZSwga3Ugc2UgYmFzaGt1IG1lIHBhcmFtZXRyaW4gJHdpZHRoJCwgamVwIG5qZSBlZmVrdCAzRC4qKg0KDQoqKiRnZW9tJGBfYCR0ZXh0KCkkIHBlcmRvcmV0IHBlciB0ZSBzaHR1YXIgdmxlcmF0IGUgcGVycWluZGplcyBuZSBjb3BhdCBwZXJrYXRlc2UuIFBhcmFtZXRyaSAkcG9zaXRpb24oKSQgdmVuZG9zIGtldG8gdmxlcmEgYnJlbmRhIGNvcGF2ZSwgcHJhIEkgcG96aWNpb25vbiBhdG8uICoqDQoNCioqRnVua3Npb25pICRjb29yZCRgX2AkcG9sYXIoKSQgcGVyZG9yZXQgcGVyIHRlIHRyYW5zZm9ybXVhciBrcmFmaWt1biBkcmVqdGtlbmRvciBuZSBuamUgZ3JhZmlrIHJyZXRob3IgKHJyZXRoKS4gJHNjYWxlJGBfYCRmaWxsJGBfYCRtYW51YWwoKSQgcGVyZG9yZXQgcGVyIHRlIHZlbmRvc3VyIG5nanlyYSB0ZSB2ZWNhbnRhIHBlciBzZWNpbGVuIG5nYSBjb3BhdCBlIHBpZSBjaGFydC1pdC4qKiANCg0KKipGdW5rc2lvbmkgJHRoZW1lJGBfYCR2b2lkKCkkIHBlcmRvcmV0IHBlciB0ZSBuZGVydHVhciBsZWdqZW5kZW4gZSBjaWxhIG5hIHNoZXJiZW4gcGVyIG9yaWVudGltIG5kYWogdGUgZGhlbmF2ZSB0ZSBwYXJhcWl0dXJhIG5lIHBpZSBjaGFydC4qKg0KDQoqKkt5IGxsb2ogdml6dWFsaXppbWkgZXNodGUgSSByZW5kZXNpc2hlbSBwZXIgdGUga3VwdHVhciBzaHBlcm5kYXJqZW4gZSBzaHBlbnppbWV2ZSBkaGUgaWRlbnRpZmlraW1pbiBlIGthdGVnb3JpdmUgbWUgdGUgcmVuZGVzaXNobWUgdGUga29zdG9zIHBlciB0ZSBkaGVuYXQgcWUgbmUgZGlzcG9ub2ptZS4qKg0KDQoNCiMjIyMgJCRLb3JyZWxhY2lvbmlcXCBNYXRyaWNhXCBlXCBLb3JyZWxhY2lvbml0XFwgUmVncmVzaVwgTGluZWFyJCQNCg0KKipLb3JyZWxhY2lvbmkgZXNodGUgY2RvIG1hcnJlZGhlbmllIHN0YXRpc3Rpa29yZSBtaWRpcyBkeSBuZHJ5c2hvcmV2ZSB0ZSByYXN0aXQuIFpha29uaXNodCBpIHJlZmVyb2hldCBzaGthbGxlcyBuZSB0ZSBjaWxlbiBuamUgcGFsZSBuZHJ5c2hvcmVzaCBqYW5lIHRlIGxpZGh1cmEgbmUgbWVueXJlIGxpbmVhcmUuKioNCg0KJCRGb3JtdWxhXCBtYXRlbWF0aWtlOlxcIHvwnZyMKPCdkYss8J2RjCl9ID0ge1xmcmFje1xkaXNwbGF5c3R5bGVcIFNfe3h5fX0ge3tTX3h9e1NfeX19fSQkDQoNCioqTWUgcG9zaHRlIGRvIHRlIG5kZXJ0b2ptZSBtYXRyaWNlbiBlIGtvcnJlbGFjaW9uaXQgbmUgYmF6ZSB0ZSBzZSBjaWxlcyBkbyB0ZSBuZGVydG9oZXQgZHJlanRlemEgZSByZWdyZXNpdCBsaW5lYXIuKioNCg0KKipOZ2p5cmEgYmx1IGRvIHRlIHRyZWdvamUgbmplIGxpZGhqZSB0ZSBkb2JldCBtZXMgdmFyaWFibGF2ZSwgbmRlcnNhIG5nanlyYSBlIGt1cWUgZG8gdGUgdHJlZ29qZSBuamUgbGlkaGplIHRlIGZvcnRlIG1lcyB0eXJlLioqDQoNCmBgYHtyfQ0KY29ycmVsYXRpb25fbWF0cml4IDwtIGNvcihudW1lcmljX2RmKQ0KDQpsaWJyYXJ5KHBoZWF0bWFwKQ0KcGhlYXRtYXAoY29ycmVsYXRpb25fbWF0cml4LCANCiAgICAgICAgIGNvbG9yID0gY29sb3JSYW1wUGFsZXR0ZShjKCJkYXJrYmx1ZSIsICJ3aGl0ZSIsICJyZWQzIikpKDIwMCksDQogICAgICAgICBmb250c2l6ZSA9IDEwLA0KICAgICAgICAgZm9udHNpemVfcm93ID0gOCwNCiAgICAgICAgIGZvbnRzaXplX2NvbCA9IDgsDQogICAgICAgICBtYWluID0gIkNvcnJlbGF0aW9uIEhlYXRtYXAgaSBWYXJpYWJsYXZlIE51bWVyaWtlIiwNCiAgICAgICAgIGRpc3BsYXlfbnVtYmVycyA9IFRSVUUsIA0KICAgICAgICAgbnVtYmVyX2NvbG9yID0gIndoaXRlIiApDQpgYGANCg0KKipQZXIgdGUgYXJzeWV0dWFyIG1iaSB2YXJlc2luZSBuZGVybWpldCBuZHJ5c2hvcmV2ZSBudW1lcmlrZSBzaGlrb2ptZSBncmFmaWt1biBkaGUgdmxlcmF0IGUga29lZmljaWVudGV2ZSB0ZSBrb3JyZWxhY2lvbml0LioqDQoNCioqTmdhIG1hdHJpY2EgdmVyZWptZSBzZSB0ZSBkaGVuYXQgbnVrIGthbmUgbmplIGxpZGhqZSB0ZSBmb3J0ZSBtZSBuamVyYSB0amV0cmVuLCBkaGUga2pvIHBlcmNha3RvaGV0IG5nYSBuZ2p5cmltaSBibHUgaSBrdWZpemF2ZSB0ZSBtYXRyaWNlcy5OZSBkbyB0ZSB6Z2plZGhpbSBkaXNhIG5kcnlzaG9yZSBxZSBtZW5kb2ptZSBzZSBrYW5lIHBhayB2YXJlc2kgbWUgbmplcmEgdGpldHJlbiAoZHkgcWUgZSBrYW5lIG5nanlyZW4gbWUgdGUgemJlaHRlKS4qKg0KDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZ2dwdWJyKQ0KDQpnZ3Bsb3QoZGF0YSwgYWVzKHggPSBhcmdldGltLCB5ID0gdGVfYXJkaHVyYXRfbXVqb3JlKSkgKyANCiAgZ2VvbV9wb2ludChjb2xvciA9ICIjRkYwMDAwIixzaXplPTAuOSkgKyANCiAgbGFicyh4ID0gIlNocGVuemltZXQgcGVyIGFyZ2V0aW0iLCB5ID0gIlRlIGFyZGh1cmF0IG11am9yZSIsIHRpdGxlID0gIlNocGVuemltZXQgcGVyIGFyZ2V0aW0ga3JhaGFzdWFyIG1lIHRlIGFyZGh1cmF0IG11am9yZSIpICsgIA0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBjb2xvciA9ICJibGFjayIsIGZvcm11bGEgPSB5IH4geCkgKyANCiAgc3RhdF9jb3IobGFiZWwueCA9IDEwMCwgbGFiZWwueSA9IDE0MDAsIHNpemUgPSA1KSArIA0KICBzdGF0X3JlZ2xpbmVfZXF1YXRpb24obGFiZWwueCA9IDEwMCwgbGFiZWwueSA9IDEzMDAsIHNpemUgPSA1KQ0KYGBgDQoNCg0KDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZ2dwdWJyKQ0KDQpnZ3Bsb3QoZGF0YSwgYWVzKHggPSB0cmFuc3BvcnRpLCB5ID0gdGVfYXJkaHVyYXRfbXVqb3JlKSkgKyANCiAgZ2VvbV9wb2ludChjb2xvciA9ICJibGFjayIsc2l6ZT0wLjkpICsgDQogIGxhYnMoeCA9ICJTaHBlbnppbWV0IHBlciB0cmFuc3BvcnQiLCB5ID0gIlRlIGFyZGh1cmF0IG11am9yZSIsIHRpdGxlID0gIlNocGVuemltZXQgcGVyIHRyYW5zcG9ydCBrcmFoYXN1YXIgbWUgdGUgYXJkaHVyYXQgbXVqb3JlIikgKyAgDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGNvbG9yID0gImJsYWNrIiwgZm9ybXVsYSA9IHkgfiB4KSArIA0KICBzdGF0X2NvcihsYWJlbC54ID0gMTAwLCBsYWJlbC55ID0gMTQwMCwgc2l6ZSA9IDUpICsgDQogIHN0YXRfcmVnbGluZV9lcXVhdGlvbihsYWJlbC54ID0gMTAwLCBsYWJlbC55ID0gMTMwMCwgc2l6ZSA9IDUpDQpgYGANCg0KDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShnZ3B1YnIpDQoNCmdncGxvdChkYXRhLCBhZXMoeCA9IHNoa29sbGltaSwgeSA9IHRlX2FyZGh1cmF0X211am9yZSkpICsgDQogIGdlb21fcG9pbnQoY29sb3IgPSAiYmx1ZSIsIHNpemUgPSAxKSArIA0KICBsYWJzKHggPSAiU2hrb2xsaW1pIiwgeSA9ICJUZSBhcmRodXJhdCBtdWpvcmUiLCB0aXRsZSA9ICJTaHBlbnppbWV0IHBlciBzaGtvbGxpbSBrcmFoYXN1YXIgbWUgdGUgYXJkaHVyYXQgbXVqb3JlIikgKyAgDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGNvbG9yID0gImJsYWNrIiwgZm9ybXVsYSA9IHkgfiB4KSArIA0KICBzdGF0X2NvcihsYWJlbC54ID0gNDAwMCwgbGFiZWwueSA9IDE0MDAsIHNpemUgPSA1LCBhbHBoYSA9IDIpICsgDQogIHN0YXRfcmVnbGluZV9lcXVhdGlvbihsYWJlbC54ID0gNDAwMCwgbGFiZWwueSA9IDEzMDAsIHNpemUgPSA1LCBhbHBoYSA9IDIpDQpgYGANCg0KDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShnZ3B1YnIpDQoNCmdncGxvdChkYXRhLCBhZXMoeCA9IGt1amRlc2lfcGVyc29uYWwsIHkgPSB0ZV9hcmRodXJhdF9tdWpvcmUpKSArIA0KICBnZW9tX3BvaW50KGNvbG9yID0gInB1cnBsZTMiLCBzaXplID0gMSkgKyANCiAgbGFicyh4ID0gIlNocGVuemltZXQgcGVyIGt1amRlcyBwZXJzb25hbCIsIHkgPSAiVGUgYXJkaHVyYXQgbXVqb3JlIiwgdGl0bGUgPSAiU2hwZW56aW1ldCBwZXIga3VqZGVzIHBlcnNvbmFsIGtyYWhhc3VhciBtZSB0ZSBhcmRodXJhdCBtdWpvcmUiKSArICANCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgY29sb3IgPSAiYmxhY2siLCBmb3JtdWxhID0geSB+IHgpICsgDQogIHN0YXRfY29yKGxhYmVsLnggPSAxNSwgbGFiZWwueSA9IG1heChkYXRhJHRlX2FyZGh1cmF0X211am9yZSkgKiAwLjk1LCBzaXplID0gNSkgKyANCiAgc3RhdF9yZWdsaW5lX2VxdWF0aW9uKGxhYmVsLnggPSAxNSwgbGFiZWwueSA9IG1heChkYXRhJHRlX2FyZGh1cmF0X211am9yZSkgKiAwLjkwLCBzaXplID0gNSkNCmBgYA0KDQoqKk5nYSBncmFmaWtldCBlIG5kZXJ0dWFyIG1lIHNpcGVyIHNlIGJhc2hrdSBtZSBkcmVqdGV6YXQgZSByZWdyZXNpdCBzaG9oaW0gcWUgbGlkaGphIG5kZXJtamV0IHRlIGFyZGh1cmF2ZSBtdWpvcmUgZGhlIHNocGVuemltZXZlIHNpcGFzIGt1amRlc2l0IHBlcnNvbmFsLCB0cmFuc3BvcnRpdCwgc2hrb2xsaW1pdCBkaGUgYXJnZXRpbWl0IGVzaHRlIHNodW1lIHBhayBsaW5lYXJlLiBOZSBwbyBtYXJyaW0gbmUgc2hxeXJ0aW0gbmplcmluIGdyYWZpayBwcmVqIHR5cmUuKioNCg0KDQokJEtvZWZpY2VudGlcIGlcIEtvcnJlbGFjaW9uaXQkJA0KICANCioqS29lZmljZW50aSBpIGtvcnJlbGFjaW9uaXQgbmEgbmRpaG1vbiB0ZSBrdXB0b2ptZSBuZXNlIG5kZXJtamV0IHRlIGRoZW5hdmUga2EgbGlkaGplIGxpbmVhcmUgYXBvIGpvLioqDQoNCioqVmV0aXRlIGUgdGlqOioqDQoNCioqS29lZmljZW50aSBpIGtvcnJlbGFjaW9uaXQgbWVyciB2bGVyYSBuZ2EgLTEgbmUgMS4qKg0KDQoqKk5lc2UgdmxlcmEgZSBrZXRpaiBrb2VmaWNlbnRpIGVzaHRlIGFmZXIgMCAobWlkaXMgLTAuMiBkaGUgMC4yICkgbmEgdHJlZ29uIHNlIG5kZXJtamV0IHZhcmlhYmxhdmUgbnVrIGthIG5qZSB2YXJlc2kgbGluZWFyZS4qKg0KDQoqKk11bmQgdGUgcGVyZG9yaW0gZHkgZnVua3Npb25lIHBlciB0ZSBwYXJlIHZsZXJlbiBlIGtvcnJlbGFjaW9uaXQgcWUgamFuZSBwamVzZSBlIGxpYnJhcmlzZSBzdGF0dXM6KioNCg0KKioxLiRjb3IudGVzdCQqKg0KDQoqKjIuJGNvciQ7KioNCg0KYGBge3J9DQoNCmNvcihkYXRhJHRyYW5zcG9ydGksIGRhdGEkdGVfYXJkaHVyYXRfbXVqb3JlKQ0KDQprb2VmaWNlbnRldCA8LSBjb3IudGVzdChkYXRhJHRyYW5zcG9ydGksZGF0YSR0ZV9hcmRodXJhdF9tdWpvcmUpDQoNCmtvZWZpY2VudGV0JGVzdGltYXRlDQpgYGANCg0KKipTaG9oaW0gcWUgdmxlcmEgZSBrb2VmaWNlbnRpdCB0ZSBrb3JyZWxhY2lvbml0IGVzaHRlIDAuMDQ2MTUxODYgcWUgZXNodGUgc2h1bWUgcHJhbmUgMC4qKg0KDQoqKlByYSBtaWRpcyB2YXJpYWJsYXZlIG51ayBrYSBuamUgbGlkaGplIGxpbmVhcmUuKioNCg0KKipQbyB0ZSB2ZW1lIHJlIGRoZSBncmFmaWtldCBlIHRqZXJlIGRoZSBkcmVqdGV6YXQgZSB0eXJlLCBnaml0aGFzaHR1IG51ayBrYSBuamUgdmFyZXNpIHRlIGR1a3NobWUuKioNCg0KIyMjIyAkJE5kZXJ0aW1pXCBpXCBuamVcIG1vZGVsaVwgdGVcIHRoamVzaHRlXCBsaW5lYXIkJA0KDQogICQkWVwgPSBcICDOsl8wXCArXCAgzrJfMVwgK1wgZ2FiaW1pXFwga3VcICDOsl8wXCBkaGVcICDOsl8xXCBqYW5lXCBwYXJhbWV0cmF0XCBlXCB2aWplcyQkDQoNCioqUGVyZG9yaW0gZnVua3Npb25pbiAkbG0oKSQgcGVyIHRlIG5kZXJ0dWFyIG5qZSBtb2RlbCBsaW5lYXIuKioNCg0KYGBge3J9DQpzZXQuc2VlZCgxMjMpDQp6Z2plZGhqYTwtc2FtcGxlKGMoVFJVRSxGQUxTRSksbnJvdyhkYXRhKSxyZXBsYWNlPVQscHJvYj1jKDAuNiwwLjQpKQ0KYGBgDQoNCioqU3BlY2lmaWtvam1lIHFlIHRlIGRoZW5hdCBkbyB0ZSBuZGFoZW4gNDAlIHRlc3R1ZXMgZGhlIDYwJSB0cmFqbnVlczsgbmRham1lIHRlIGRoZW5hdCBuZSB0ZXN0IGRoZSB0cmFpbjoqKg0KDQpgYGB7cn0NCnRyYWluPC1kYXRhW3pnamVkaGphLF0NCnRlc3Q8LWRhdGFbIXpnamVkaGphLF0NCmBgYA0KDQoqKk5kZXJ0b2hldCBtb2RlbGkgZHVrZSBtYXJyZSBzaSB0ZSBkaGVuYSB0ZSBkaGVuYXQgdHJhaW4gKHRyYWpudWVzZSkqKg0KDQpgYGB7cn0NCm1vZGVsMTwtbG0odHJhbnNwb3J0aX50ZV9hcmRodXJhdF9tdWpvcmUsZGF0YT0gdHJhaW4pDQptb2RlbDENCmBgYA0KDQokJE1pcmVzaWFcIGVcIG1vZGVsaXQkJA0KKipQZXIgdGUga29udHJvbGx1YXIgbWlyZXNpbmUgZSBuamUgbW9kZWxpIHNoaWtvam1lOioqDQoNCioqMS4kUlNFLT5yZXNpZHVhbCQgJHN0YW5kYXJ0JCAgJGVycm9yJDogZXNodGUgZGlzdGFuY2EgbWVzYXRhcmUgcWUgdmxlcmF0IGUgdmV6aGd1YXJhIHRlIGplbmUgbGFyZyB2bGVyZXMgc2UgbW9kZWxpdC4gU2EgbWUgZSB2b2dlbCBram8gdmxlcmUgYXEgbWUgaSBtaXJlIG1vZGVsaSBzZXBzZSBrdXB0b2ptZSBxZSB2bGVyYXQgcWUgamVwIG1vZGVsaSBuZG9kaGVuIGFmZXIgYXR5cmUgcWUgamFuZSB2bGVyYSB0ZSB2ZXJ0ZXRhLioqDQoNCioqMi4kUl4yJC0+IG5hIHRyZWdvbiBzYXNhIHBlcnFpbmQgdGUgZGhlbmF2ZSB0ZSBzaHBqZWdvaGVuIG5nYSBtb2RlbGkuKioNCg0KKiozLiRwLXZhbHVlJC0+bmVzZSBram8gdmxlcmUgZXNodGUgbWUgZSB2b2dlbCBzZSAwLjA1IGF0ZWhlcmUgdGhlbWkgcWUga2VtaSBuamUgbGlkaGplIHRlIHJlbmRlc2lzaG1lIG5kZXJtamV0IG5kcnlzaG9yZXZlLioqDQogIA0KKipCZWptZSBuamUgc3VtbWFyeSB0ZSBtb2RlbGl0IHBlciB0ZSBwYXJlIHBlcmZ1bmRpbWV0OioqDQoNCmBgYHtyfQ0Kc3VtbWFyeShtb2RlbDEpDQpgYGANCg0KKipTaG9oaW0gcWU6KioNCg0KKipSZXNpZHVhbCBzdGFuZGFyZCBlcnJvcjogNDMuOTMuKioNCioqS2pvIGRvIHRob3RlIHFlIHNocGVuemltZXQgcmVhbGUgcGVyIHRyYW5zcG9ydCBkZXZpam9qbmUgbmdhIG1vZGVsaSBsaW5lYXIgbmUgdmxlcmVuIDQzLjkzLiBNdW5kIHRhIGt0aGVqbWUgbmUgJToqKg0KDQpgYGB7cn0NCm1lc2F0YXJqYV9SU0U8LXNpZ21hKG1vZGVsMSkvbWVhbih0cmFpbiR0cmFuc3BvcnRpKQ0Kc3ByaW50ZigiR2FiaW1pIG5lIHBlcnFpbmRqZSBpIG1vZGVsaXQ6JXMlJSIscm91bmQobWVzYXRhcmphX1JTRSoxMDAsMikpDQpgYGANCg0KKipHYWJpbWkgbmUgJSBlc2h0ZSAzNS41NCUuIEtqbyBkbyB0ZSB0aG90ZSBzZSBtb2RlbGkgeW5lIG51ayBwZXJzaHRhdGV0IHNodW1lIG1pcmUgbWUgdGUgZGhlbmF0IGUgdmVydGV0YS4qKg0KDQoqKlZsZXJhIGUgUl4yID0gMC4wMDEyMjggbW9kZWxpIHNocGplZ29uIDAuMTIyOCUgdGUgdGUgZGhlbmF2ZSwgcG90aHVhanNlIGFzcGFrLioqDQoNCg0KKipLb250cm9sbG9qbWUgbWJldGpldCBlIG1vZGVsaXQ6KioNCg0KKipNYmV0amEgZXNodGUgZGlzdGFuY2EgbmRlcm1qZXQgdmxlcmVzIGFrdHVhbGUgZGhlIGFzYWogcWUgamVwIG1vZGVsaSBxZSBuZSBrZW1pIG5kZXJ0dWFyLioqDQoNCmBgYHtyfQ0KdmxlcmF0X2VfbW9kZWxpdCA8LSBwcmVkaWN0KG1vZGVsMSwgZGF0YSA9IHRyYWluKQ0KIHZsZXJhdF9lX21vZGVsaXQNCiBtYmV0amV0X2VfbW9kZWxpdCA8LSByZXNpZChtb2RlbDEpDQogbWJldGpldF9lX21vZGVsaXQNCmBgYA0KDQoqKk5lIHRlIGRoZW5hdCB0b25hIHRyYWpudWVzZSBtdW5kIHRlIHNodG9qbWUgbmplIGtvbG9uZSB0ZSByZSBxZSBwZXJtYmFuIHZsZXJhdCBxZSBwYXJhc2hpa29uIG1vZGVsaS4qKg0KDQpgYGB7cn0NCnRyYWluJHZsZXJhdF9lX21vZGVsaXQ8LXByZWRpY3QobW9kZWwxKQ0KIHRyYWluJG1iZXRqZXRfZV9tb2RlbGl0PC1yZXNpZHVhbHMobW9kZWwxKQ0KIFZpZXcodHJhaW4pDQogDQogZ3JhZmlrMTwtZ2dwbG90KHRyYWluLGFlcyh0cmFuc3BvcnRpICwgdGVfYXJkaHVyYXRfbXVqb3JlKSkgKyBnZW9tX3BvaW50KCkgKyBnZW9tX3BvaW50IChhZXMoeSA9IHZsZXJhdF9lX21vZGVsaXQsY29sb3IgPSAicmVkMiIpKQ0KIGdyYWZpazENCmBgYA0KDQoqKk11bmQgdGUgbmRlcnRvam1lIHNlZ21lbnRldCBxZSBwYXJhcWVzaW4gZ2FiaW1ldDoqKg0KDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCg0KZ3JhZmlrMiA8LSBnZ3Bsb3QodHJhaW4sYWVzKHRyYW5zcG9ydGkgLHRlX2FyZGh1cmF0X211am9yZSkpK2dlb21fcG9pbnQoKSArIGxhYnMoeD0iVHJhbnNwb3J0aSIsIHk9ICJUZSBBcmRodXJhdCBNdWpvcmUiKSArIGdlb21fcG9pbnQoYWVzKHk9dmxlcmF0X2VfbW9kZWxpdCksY29sb3I9ImJsdWUiKStnZW9tX3NlZ21lbnQoYWVzKHhlbmQ9IHRyYW5zcG9ydGksIHllbmQ9dmxlcmF0X2VfbW9kZWxpdCksY29sb3I9InJlZCIpDQpncmFmaWsyDQpgYGANCg0KDQpgYGB7cn0NCmxpYnJhcnkoY29ycmVsYXRpb24pDQoNCnBsb3QoZGF0YSR1c2hxaW1pLCBkYXRhJG1qZXRldF9zaGtvbGxvcmUpDQpjb3IoZGF0YSR1c2hxaW1pLGRhdGEkbWpldGV0X3Noa29sbG9yZSkNCm1vZGVsMTwtbG0odXNocWltaSB+IG1qZXRldF9zaGtvbGxvcmUsIGRhdGE9ZGF0YSkNCm1vZGVsMQ0KDQpgYGANCg0KYGBge3J9DQpsaWJyYXJ5KGdncGxvdDIpDQoNCmdncGxvdChkYXRhKSArIGFlcyh4ID0gdXNocWltaSwgeT0gbWpldGV0X3Noa29sbG9yZSkgKw0KICBnZW9tX3BvaW50KHNpemUgPSAxTCwgY29sb3VyID0gIiMwMDAwMDAiKSArDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGZvcm11bGEgID0geX54LCBzZSA9IFRSVUUsIGNvbG9yID0gImJsdWUiKSArIA0KICBzdGF0X2NvcihsYWJlbC54PTIsIGxhYmVsLnk9NCkgKw0KICBzdGF0X3JlZ2xpbmVfZXF1YXRpb24obGFiZWwueD0xLCBsYWJlLnk9Miwgc2l6ZT0zKSArDQogIGxhYnMoeCA9ICJVc2hxaW1pIiwgeSA9ICJNamV0ZXQgU2hrb2xsb3JlIiwNCiAgICAgICB0aXRsZSA9ICJTaHBlbnppbWV0IHBlciB1c2hxaW0gdnMgU2hwZW56aW1ldCBwZXIgTWpldGUgU2hrb2xsb3JlIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJBIG5kaWtvam5lIHNocGVuemltZXQgbmUgdXNocXllcmplIG5lIGF0byBwZXIgbWpldGUgc2hrb2xsb3JlPyIpICsNCiAgdGhlbWVfY2xhc3NpYygpDQpgYGANCg0KKipMZSB0ZSBhbmFsaXpvam1lIG5qZSBuZ2EgcmV6dWx0YXRldCBlIHJlZ3Jlc2V2ZSB0ZSBuZGVydHVhcmEgbWUgc2lwZXI6KioNCg0KKipSRVpVTFRBVEk6IE5nYSBwZXJnamlnamphIGUgbWVzaXBlcm1lIG5lIG1vZGVsaW4gJFNocGVuemltZXQkICRwZXIkICR1c2hxaW0kICR2cyQgJFNocGVuemltZXQkICRwZXIkICRNamV0ZSQgJFNoa29sbG9yZSQga2VtaSBzZSBla3VhY2lvbmkgcWUgaSBwZXJzaHRhdGV0IGtldGlqIG1vZGVsaSByZWdyZXNpIGVzaHRlKioNCg0KJCRWbGVyZXNpbWlcID0gXCAxNjBcICtcIDAuMDYzWCQkDQoqKnFlIGRvIHRlIHRob3RlIHNlIHBlciBjZG8gbmplc2kgc2hwZW56aW1pIG5lIHVzaHFpbSwga2VtaSBuamUgcnJpdGplIG1lIDAuMDYzIG5qZXNpIG5lIG1qZXRlIHNoa29sbG9yZS4qKg0KDQoqKk11bmRlbWkgdGUgZ2plam1lIGVkaGUgaW50ZXJ2YWxpbiBlIGJlc2ltaXQgbmVwZXJtamV0IGZ1bmtzaW9uaXQgJGNvbmZpbnQoKSQ6KioNCg0KYGBge3J9DQpjb25maW50KG1vZGVsMSwgbGV2ZWwgPSAwLjk1KQ0KYGBgDQoNCioqU2ljIGR1a2V0IGVkaGUgbmdhIHJlenVsdGF0aSwgaW50ZXJ2YWxpIGkgYmVzaW1pdCBlc2h0ZSBbMjIyLjczIDsgMjUwLjg2XSoqDQoNCioqRnVua3Npb25pICRwcmVkaWN0KCkkIHBhcmFzaGlrb24gc2Ugc2EgZG8gdGUgamV0ZSB2bGVyYSBlIG5kcnlzaG9yZXMgc2UgdmFydXIga3VyIGplcGVuIGRpc2EgdmxlcmEgdGUgbmRyeXNob3JlcyBzZSBwYXZhcnVyLioqDQoNCmBgYHtyfQ0Kc3VtbWFyeShtb2RlbDEpDQpgYGANCg0KKipJbnRlcnByZXRpbWkgaSByZXp1bHRhdGV2ZSB0ZSBtb2RlbGl0OioqDQoNCioqMS4gJEludGVycHJldGltaSQgJGkkICRtYmV0amV2ZSQ6IG1iZXRqZXQgcGFyYXFlc2luIGRpZmVyZW5jYXQgbWlkaXMgdmxlcmF2ZSB0ZSB2ZXpoZ3VhcmEgdGUgbmRyeXNob3JlcyBzZSB2YXJ1ciAkdXNocWltaSQgZGhlIHZsZXJhdmUgdGUgcGFyYXNoaWt1YXJhIG5nYSBtb2RlbGkuIFJhbmd1IGkgbWJldGpldmUgdGUgbW9kZWxpdCBzdWdqZXJvbiBxZSBtb2RlbGkgbnVrIGkgcGVyc2h0YXRldCBuZSBtZW55cmUgdGUgcGVyc29zdXIgdGUgZGhlbmF2ZS4gTWJldGphIG1pbmltYWxlIGVzaHRlIC0xNjAuOTEzLCBLdWFydGlsaSBpIHBhcmUgZXNodGUgLTc3LjE3MiwgbWVzYXRhcmphIGVzaHRlIDMuODUyLCBRMyBlc2h0ZSA3NC42NyAgZGhlIHZsZXJhIGUgbWJldHVyIDE1NS43NjQgZXNodGUgbWJldGphIG1ha3NpbWFsZS4qKg0KDQoqKjIuICRJbnRlcmNlcHQkICQobmRlcnByZXJqYSkkIDIzNi44MDAwNiBwYXJhcWV0IHZsZXJlbiBlIHBhcmFzaGlrdWFyIHRlIG5kcnlzaG9yZXMgc2UgdmFydXIgJHVzaHFpbWkkIGt1ciBuZHJ5c2hvcmphIGUgcGF2YXJ1ciAkbWpldGV0JCAkc2hrb2xsb3JlJCBlc2h0ZSAwLiBLb2VmaWNpZW50aSBwZXIgdmFyaWFibGluIGUgcGF2YXJ1ciBlc2h0ZSAwLjA5MDY1LiBLam8gZG8gdGUgdGhvdGUgcWUgcGVyIGNkbyBycml0amUgcHJlaiAxIG5qZXNpIG5lIHZhcmlhYmxpbiBlIHBhdmFydXIsIG5kcnlzaG9yamEgZSB2YXJ1ciBwYXJhc2hpa29oZXQgdGUgcnJpdGV0IG1lIDAuMDkwNjUgbmplc2ksIGR1a2UgbWJhanR1ciB0ZSBnaml0aGUgdmFyaWFibGF0IGUgdGplcmUga29uc3RhbnRlLioqDQoNCioqMy4gJFAtdmFsdWUkOiB2bGVyYSAkcCQgcGVyIHZhcmlhYmxpbiBlIHBhdmFydXIgZXNodGUgMC4wMTY5NiwgZSBjaWxhIGVzaHRlIG1lIGUgdm9nZWwgc2Ugbml2ZWxpIGkgcmVuZGVzaXNlIDAuMDUuIEtqbyB0cmVnb24gc2UgbGlkaGphIG1pZGlzIHZhcmlhYmxpdCB0ZSBwYXZhcnVyIGRoZSBuZHJ5c2hvcmVzIHNlIHZhcnVyIGVzaHRlIHN0YXRpc3Rpa2lzaHQgZSByZW5kZXNpc2htZSwgcWUgZG8gdGUgdGhvdGUgc2UgbmRyeXNob3JqYSBlIHBhdmFydXIga2EgbmplIGVmZWt0IHRlIHJlbmRlc2lzaGVtIG5lIHZhcmlhYmxpbiBlIHZhcnVyLioqDQoNCioqNC4gJFZsZXJhJCAkUl4yJCBlc2h0ZSAwLjAwNTY5OCwgcWUgZG8gdGUgdGhvdGUgc2UgbmRyeXNob3JqYSBlIHBhdmFydXIgc2hwamVnb24gcnJldGggMC41NyUgdGUgdmFyaWFuY2VzIG5lIHZhcmlhYmxpbiBlIHZhcnVyLioqDQoNCioqTmUgbWVueXJlIHRlIHBlcm1ibGVkaHVyIHJlenVsdGF0ZXQgc3VnamVyb2puZSBzZSB2YXJpYWJsaSBpIHBhdmFydXIgJG1qZXRldCQgJHNoa29sbG9yZSQga2EgbmplIGVmZWt0IHN0YXRpc3Rpa2lzaHQgZG9tZXRoZW5lcyBwb3IgcmVsYXRpdmlzaHQgdGUgdm9nZWwgbmUgdmFyaWFibGluIGUgdmFydXIgJHVzaHFpbWkkLioqDQoNCioqRHVrZSBxZW5lIHNlIG1vZGVsaSB5bmUga2EgMyB5amUsIGFxIG1lIHNodW1lIHRlIHJlbmRlc2lzaG1lIGphbmUgcmV6dWx0YXRldCBlIG1vZGVsaXQgdGUgbmRlcnR1YXIuKioNCg0KKipOZXNlIGJlam1lIHBsb3QgdGUgbW9kZWxpdCBxZSBrZW1pIGtyaWp1YXIgYXRlIGRvIHRlIG1hcnJpbSA0IGdyYWZpa2U6KioNCg0KKioxLlJlc2lkdWFscyB2cyBGaXR0ZWQ7KioNCg0KKioyLk5vcm1hbCBRLVE7KioNCg0KKiozLkZpdHRlZCB2cyBzcXJ0IChzdGFuZGFyZGl6ZWQgcmVzaWR1YWxzKTsqKg0KDQoqKjQuTGV2ZXJhZ2UgdnMgc3RhbmRhcmRpemVkIHJlc2lkdWFsczsgKioNCg0KJCRTY2FsZVwgTG9jYXRpb25cIFBsb3QkJA0KDQpgYGB7cn0NCm1vZGVsIDwtIGxtKHVzaHFpbWl+bWpldGV0X3Noa29sbG9yZSwgZGF0YSA9IGRhdGEpDQoNCnBsb3QobW9kZWwpDQoNCmBgYA0KDQokJFJlc2lkdWFsc1wgdnNcIEZpdHRlZFwgUGxvdCQkDQoqKkdyYWZpa3UgaSBwYXJlIG5hIHRyZWdvbiBxZSBudWsga2VtaSBuamUgdmFyZXNpIGxpbmVhcmUgbmRlcm1qZXQgdGUgZGhlbmF2ZSB0b25hLiBQcmEgbnVrIGplbWkgbmUgaG9tb3NrZWRhc3RpY2l0ZXQuKioNCg0KDQokJFEtUVwgUGxvdCQkDQoqKk5qZSBtZW55cmUgdGpldGVyIHBhcmFxaXRqZSBwZXIgdGUgZGhlbmF0IHRvbmEgZXNodGUgZGhlIGdyYWZpa3UgTm9ybWFsIFEtUS4gS3kgbGxvaiBncmFmaWt1IHBlcmRvcmV0IHBlciB0ZSBwZXJjYWt0dWFyIG5lc2UgbmplIGdydXAgdGUgZGhlbmFzaCBqYW5lIGFwbyBqbyAgdGUgc2hwZXJuZGFyYSBub3JtYWxpc2h0LiBOZXNlIGF0byBqYW5lLCBhdGVoZXJlIHRlIGdqaXRoYSBwaWthdCBlIHRpaiBkdWhldCB0ZSBzaHRyaWhlbiBuZSBuamUgdmlqZSB0ZSBkcmVqdGUgZGlhZ29uYWxlLiBOZSByYXN0aW4gdG9uZSB0ZSBkaGVuYXQgbnVrIHBlcnB1dGhlbiBzaHVtZSBtaXJlIG1lIHNocGVybmRhcmplbiBub3JtYWxlLCBzZXBzZSBuamUgcGplc2UgZSBrb25zaWRlcnVlc2htZSBlIHBpa2F2ZSBudWsgc2h0cmloZW4gbWJpIGRyZWp0ZXouIEtqbyBkbyB0ZSB0aG90ZSBzZSBzaHBlbnppbWV0IG1pbmltYWxlIHBlciB1c2hxaW0gbnVrIGphbmUgbWphZnR1ZXNoZW0gdGUgdWx0YSBzYSBkdWhlbiBwZXIgdHUgcGVycHV0aHVyIG1lIGRyZWp0ZXplbiBkaGUgc2hwZW56aW1ldCBtYXggbnVrIGphbmUgbWphZnR1ZXNoZW0gdGUgbGFydGEgc2EgdGUgc2h0cmloZW4gbWJpIGRyZWp0ZXouIEtqbyB0cmVnb24gc2UgYmlzaHRhdCBlIHNocGVybmRhcmplcyBqYW5lIHNodW1lICJ0ZSBkb2JldCIgbmUga3JhaGFzaW0gbWUgc2hwZXJuZGFyamVuLioqDQoNCiQkU2NhbGVcIExvY2F0aW9uXCBQbG90JCQNCg0KKipHcmFmaWt1IFNjYWxlLUxvY2F0aW9uIGVzaHRlIGkgbmplanRlIG1lIGdyYWZpa3VuIGUgcGFyZSwgcG9yIG1lIG5kcnlzaGltaW4gcWUgbmUgYm9zaHRpbiB2ZXJ0aWthbCBrZW1pIG1iZXRqZXQgZSBzdGFuZGFydGl6dWFyYS4gU2hpa29oZXQgZGhlIGtldHUgbGlkaGphIG5kZXJtamV0IG1iZXRqZXZlIHRlIHN0YW5kYXJ0aXp1YXJhIGRoZSB2bGVyYXZlIHRlIHBlcnNodGF0dXJhIGRoZSBzaGlrb2hldCBob21vc2tlZGFzdGljaXRldGkuIE5lIHJhc3RpbiB0b25lIHBvIHRlIHNoaWtvaGV0IHZpamEgZSBrdXFlIGFqbyBlc2h0ZSB0aHVhanNlIGhvcml6b250YWxlIHByYSBudWsga2EgbmRvbmplIGxpZGhqZSBtZXMgdmxlcmF2ZSB0ZSBwZXJhZnJ1YXJhIGRoZSBtYmV0amV2ZSB0ZSBzdGFuZGFydGl6dWFyYS4qKg0KDQoNCiQkUmVzaWR1YWxzXCB2cy5cIExldmVyYWdlXCBQbG90JCQNCg0KKipHcmFmaWt1IFJlc2lkdWFscyB2cy4gTGV2ZXJhZ2UgbmEgbGVqb24gdGUgc2hpa29qbWUgbmVzZSBrYSB2ZXpoZ2ltZSBxZSBuZGlrb2ptZSBuZSBtb2RlbGluIGUgcmVncmVzaXQgcWUga2VtaSBuZGVydHVhci4gRSB0aGVuZSBuZHJ5c2hlLCBzaGlrb2ptZSBuZXNlIGthIHZlemhnaW1lIHFlIHBvIHRlIG1vcyBtZXJyZW4gbmUga29uc2lkZXJhdGUgbmRyeXNob2puZSBtb2RlbGluIHRvbmUuKioNCg0KDQpgYGB7cn0NCg0KeV9pX3BlcmFmcnVhciA8LSBmaXR0ZWQudmFsdWVzKG1vZGVsMSkNClZpZXcoeV9pX3BlcmFmcnVhcikNCg0KDQp5X2lfcGFyYXNoaWt1YXIgPC0gcHJlZGljdChtb2RlbDEsIG5ld2RhdGEgPSBkYXRhLCBpbnRlcnZhbD0nY29uZmlkZW5jZScpDQpoZWFkKHlfaV9wYXJhc2hpa3VhciwgNTAwKQ0KDQpgYGANCg0KKipLeSBrb2QgbmEgc2hlcmJlbiBwZXIgdGUgaWRlbnRpZmlrdWFyIHZsZXJhdCBlIHBhcmFzaGlrdWFyYS4gRG8gdGUgbmEgaGFwZXQgbmplIGRyaXRhcmUgZSByZSBlIGNpbGEgbmUgbmplIHRhYmVsZSBkbyB0ZSBrZXRlIHRlIGFmaXNodWFyYSB0ZSBnaml0aGEgdmxlcmF0IGUgcGFyYXNoaWt1YXJhLioqDQoNCioqTGUgdGUgbmRlcnRvam1lIG5qZSBncmFmaWsgcGVyIHZsZXJhdCB0b25hIHRlIHBhcmFzaGlrdWFyYToqKg0KDQpgYGB7cn0NCnBsb3QoeV9pX3BhcmFzaGlrdWFyKQ0KYGBgDQoNCioqTmlzdXIgbmdhIGdyYWZpa3UgaSBuZGVydHVhciBtZSBzaXBlciwgc2hwZXJuZGFyamEgZSB2bGVyYXZlIG5lIGF0ZSBncmFmaWsgbmdqYXNvbiBtZSBuamUgc2hwZXJuZGFyamUgbG9nYXJpdG1pa2UuIE11bmQgdGUgdGhlbWkgc2UgbWUgcnJpdGplbiBlIHZsZXJhdmUgbmUgYm9zaHRpbiAnZml0JyBudWsga2VtaSBuamUgcnJpdGplIGxpbmVhcmUgdGUgdmxlcmF2ZSBuZSBib3NodGluICdsd3InLiBQcmEgdmxlcmF0IHkgbnVrIHJyaXRlbiBuZSBtZW55cmUgdGUgZHJlanRlcGVyZHJlanRlIG1lIGF0byBuZSBib3NodGluIGhvcml6b250YWwuKioNCg0KDQojIyMjICQkUGFpcmVkXCBQbG90cyQkDQoNCioqTGlicmFyaWEgJEdHYWxseSQgbmEgb2Zyb24gbmplIG9wc2lvbiB0ZSBuZ2phc2hlbSBtZSAkZ2dwbG90JDogYXRlIHRlIHF1YWp0dXIgJGdncGFpcnMkLiBOZ2EgZmphbGEgcGFpcnMgbWVuamVoZXJlIG5lbmt1cHRvam1lIGNpZnRlLCBwcmEgY2lmdGUgb3NlIGdydXBpbWUgZ3JhZmlrZXNoLioqDQoNCioqTWUgcG9zaHRlIGtlbWkgbmRlcnR1YXIgbmplIHBhaXJlZCBwbG90IHBlciA5IHZhcmlhYmxhIHRlIGRhdGFzZXRpdCB0b25lLioqDQpgYGB7cn0NCmxpYnJhcnkoR0dhbGx5KQ0KZ2dwYWlycyhkYXRhWywgYygxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5KV0sIGdncGxvdDI6OmFlcyhjb2xvcj0icmVkIikpDQpgYGANCg0KKipOZSBncmFmaWsgdmVyZWptZSBwamVzZXQgcGVyYmVyZXNlIHRlIHRpai4gQWkgcGVyYmVoZXQgbmdhIGdyYWZpa2UgZGVuc2l0ZXRpLCBib3ggcGxvdGUsIGhpc3RvZ3JhbWEsIGRoZSBnaml0aGFzaHR1IGtvZWZpY2llbnRlIGtvcnJlbGFjaW9uaSB0ZSBjaWxldCBuYSB0cmVnb2puZSB2YXJlc2luZSBtaWRpcyBuZHJ5c2hvcmV2ZSBjaWxlc29yZS4qKg0KKipQcmEgbWUgYW5lIHRlIGtldGlqIGdyYWZpa3UgbmUgbWFycmltIG5lIG5qZSBmYXJlIG1lbnlyZSBuamUgcGVybWJsZWRoamUgdGUgZ2ppdGhlIHZpenVhbGl6aW1pdCB0ZSBrcnllci4qKg0KDQoqKkNmYXJlIHRyZWdvam5lIHZsZXJhdCBuZSBwZXJxaW5kamU/KioNCg0KKiokcGxvdDogWzIsIDFdIFs9PT09PT09PT09PT4tLS0tLS0tLS0tLS0tLS1dJCAxMiUgdHJlZ29uIHFlIG5lIG5qZSBtb21lbnQgdGUga29oZXMgKGdqYXRlIGVremVrdXRpbWl0IHRlIGtvZGl0KSBlc2h0ZSBkdWtlIHUga3JpanVhciBncmFmaWt1IGkgcG96aWNpb251YXIgbmUgKDIsMSkgbmUgbWF0cmljZSBkaGUgcGVyYmVuIDEyJSB0ZSBzYWouKioNCg0KKiokc3RhdCRgX2AkYmluKCkkICR1c2luZyQgJGJpbnMgPSAzMCQgZG8gdGUgdGhvdGUgc2UgZnVua3Npb25pICRzdGF0JGBfYCRiaW4kIHBvIHBlcmRvciAzMCBwaWthIHBlciBoaXN0b2dyYW1ldCBkaGUgdGVudG9uIHRlIHpnamVkaGkgbmplIHZsZXJlIHNhIG1lIHRlIG1pcmUgJGJpbndpZHRoJCBwZXIgdGUgcGVybWlyZXN1YXIgcGFyYXFpdGplbiBlIHR5cmUuKioNCg0KKipOZSBtZW55cmUgdGUgbmdqYXNobWUgYXJzeWV0b2ptZSBwZXIgY2RvIGVsZW1lbnQgdGpldGVyIHRlIGFmaXNodWFyLioqDQoNCg0KDQojIyMgKipgciBjb2xvcml6ZSgiUGVyZnVuZGltZSBkaGUgUmVmZXJlbmNhIiwgImJsdWUiKWAqKg0KDQojIyMjICQkUGVyZnVuZGltZSQkDQoNCioqQXNodHUgc2ljIGUga2VtaSBjaXR1YXIgbmUgaHlyamUgdGUgcHJvamVrdGl0LCAkU3R1ZGVudCQgJFNwZW5kaW5nJCAkRGF0YXNldCQgaXNodGUgbmplIHpnamVkaGplIGUgam9uYSBwZXIgdGUgc3R1ZGl1YXIgZGhlIGFuYWxpenVhciBuamUgZmVub21lbiAobmVzZSBkbyB0ZSBxdWhldCBpIHRpbGxlKSBpIGNpbGkgbmEga2FyYWt0ZXJpem9uIHRlIGdqaXRoZXZlIG5lIHNpIHN0dWRlbnRlIG5lIGpldGVuIHRvbmUgdGUgcGVyZGl0c2htZSBzdHVkZW50b3JlLiBQcmEgcGVyIHRlIGFuYWxpenVhciBzaHBlbnppbWV0IGUgbmplIGdydXBpIHN0dWRlbnRlc2ggbWUgYW5lIHRlIG1ldG9kYXZlIHBlcmdqaXRoZXNpc2h0IHRlIG5qb2h1cmEgc3RhdGlzdGlrb3JlLCBrdSBuZSBuZGlobWUgbmEgdmplbiBnanVoYSBSIGRoZSBtamVkaXNpIGkgc2FqIGkgemh2aWxsaW1pdCAkUlN0dWRpbyQuKioNCg0KKipEdWtlIHFlbmUgcHJvamVrdGkgaSBwYXJlIGkgbWlyZWZpbGx0ZSBwZXIgbmUsIGdqYXRlIGdqaXRoZSBrb2hlcyBqZW1pIHBlcnBqZWt1ciBxZSB0ZSB0cmVnb2hlbWkgdGUgc2FrdGUgZGhlIHRlIHFhcnRlIG5lIHN0cnVrdHVyaW1pbiwgYW5hbGl6aW1pbiBkaGUgaW50ZXJwcmV0aW1pbiBlIHRlIGRoZW5hdmUgdG9uYS4gSmVtaSBwZXJwamVrdXIgdHUga3VzaHRvam1lIHJlbmRlc2kgZGhlIHZlbWVuZGplIHRlIGdqaXRoYSBlbGVtZW50ZXZlIHN0YXRpc3Rpa29yZSwgbWFkaGVzaXZlIHRlIG5qb2h1cmEsIGtvbmNlcHRldmUuKioNCg0KKipNYnlsbGphIGUga2V0aWogcHJvamVrdGkgc2lndXJpc2h0IHFlIGRvIHRlIHBlcmZzaGlqZSBhdG8gY2thIG5lIGtpc2hpbSBzaSBvYmpla3RpdjogbmplIHBlcm1ibGVkaGplIHRlIHN0cnVrdHVydWFyIHRlIGdqaXRoZSByZXp1bHRhdGV2ZSB0ZSBueGplcnJhIG5nYSBjZG8gbGxvZ2FyaXRqZSBzdGF0aXN0aWtvcmUgZSBrcnllciBtYmkgZGF0YXNldC4qKg0KDQpgYA0KYGANCmBgDQpgYA0KDQojIyMjICpOZSBwZXJmdW5kaW0gdGUgYW5hbGl6aW1pdCB0ZSBkYXRhc2V0aXQgJFN0dWRlbnQkICRTcGVuZGluZyQgYXJyaXRlbSBuZSBrZXRvIHJlenVsdGF0ZSB0ZSByZW5kZXNpc2htZToqDQoNCioqTW9zaGEgbWVzYXRhcmUgZSBzdHVkZW50ZXZlIHRlIHpnamVkaHVyIGVzaHRlIDIxIHZqZWMsIG5kZXJzYSBnamluaWEgZG9taW51ZXNlIGVzaHRlIGFqbyBtYXNoa3VsbG9yZS4qKg0KDQoqKlRlIGFyZGh1cmF0IG11am9yZSBtZXNhdGFyZSB0ZSBuamUgc3R1ZGVudGkgcmV6dWx0b2puZSAkMTAyMC42NS4qKg0KDQoqKk5nYSByZXp1bHRhdGV0IGUgbnhqZXJyYSBhcnJpdGVtIG5lIHBlcmZ1bmRpbWluIHNlIHN0dWRlbnRldCBzaHBlbnpvbmluIG1lIHNodW1lIHBlciBzaGtvbGxpbSwgbmRqZWt1ciBuZ2Egc3RyZWhpbWkgZGhlIHVzaHFpbWkuKioNCg0KKipTaXBhcyBnamluaXNlIG1lIHNodW1lIHNocGVuemltZSBiZW5pbiBtZXNoa3VqdCBuZSBrYXRlZ29yaXRlIHNoa29sbGltICxzdHJlaGltICwgdXNocWltIGRoZSAgdGVrbm9sb2dqaSAsbmRlcnNhIHZhanphdCBzaHBlbnpvbmluIG1lIHNodW1lIG5lIGthdGVnb3JpdGUgZSB0amVyYSBzaTogdHJhbnNwb3J0LCBtamV0ZSBzaGtvbGxvcmUsIGFyZ2V0aW0sIGt1amRlcyBwZXJzb25hbCwgbWlyZXFlbmllIHNoZW5kZXRlc29yZSBkaGUgdGUgbmRyeXNobWUuKioNCg0KKipTaXBhcyB2aXRpdCB0ZSBzdHVkaW1pdCBwZXIgc2hrb2xsaW0gIG1lIHRlcGVyIHNocGVuem9uaW4gc3R1ZGVudGV0ICRKdW5pb3IkIG5kamVrdXIgbmdhICAkU29waG9tb3JlJCwgJEZyZXNobWFuJCBkaGUgbWUgcGFrICRTZW5pb3IkLioqDQoNCioqUGVyIHN0cmVoaW0gbWUgc2h1bWUgc2hwZW56b25pbiAkU2VuaW9yJCBkaGUgbWUgcGFrICRTb3Bob21vcmUkLioqDQoNCioqUGVyIHVzaHFpbSBkaGUga3VqZGVzIHBlcnNvbmFsIG1lIHNodW1lIHNocGVuem9qbmUgJFNlbmlvcnMkLCBuZGVyc2EgbWUgcGFrICRKdW5pb3IkLioqDQoNCioqUGVyIHRyYW5zcG9ydCwgbWpldGUgc2hrb2xsb3JlLCBhcmdldGltLCB0ZWtub2xvZ2ppIG1lIHNodW1lIHNocGVuem9qbmUgJEZyZXNobWFuJCwgbmRlcnNhIG1lIHBhayAkSnVuaW9yJC4qKg0KDQoqKlNpcGFzIGRlZ2VzIHNlIGRpcGxvbXVhciBtZSBzaHVtZSBwZXIgc2hrb2xsaW0gc2hwZW56b2puZSBzdHVkZW50ZXQgZSBwc2lrb2xvZ2ppc2UgZGhlIG1lIHBhayBhdGEgdGUgaW54aGluaWVyc2llLioqDQoNCioqUGVyIHN0cmVoaW0gbWUgc2h1bWUgc2hwZW56b2puZSBhdGEgdGUgc2hrZW5jYXZlIGtvbXBqdXRlcmlrZSBkaGUgbWUgcGFrIHRlIGVrb25vbWlrdXQuKioNCg0KKipQZXIgdXNocWltIG1lIHNodW1lIHNocGVuem9qbmUgc3R1ZGVudGV0IGUgZWtvbm9taWt1dCwgbmRlcnNhIG1lIHBhayBhdGEgcGVyIHNoa2VuY2Ega29tcGp1dGVyaWtlLioqDQoNCioqUGVyIHRyYW5zcG9ydCBtZSBzaHVtZSBzaHBlbnpvam5lIHN0dWRlbnRldCBlIHBzaWtvbG9namlzZSwgbmRlcnNhIG1lIHBhayBhdGEgdGUgaW54aGluaWVyaXNlLioqDQoNCioqUGVyIG1qZXRlIHNoa29sbG9yZSwgYXJnZXRpbSwgdGVrbm9sb2dqaSwgbWlyZXFlbmllIHNoZW5kZXRlc29yZSBzaHBlbnpvam5lIG1lIHNodW1lIHN0dWRlbnRldCBlIGJpb2xvZ2ppc2UuKioNCg0KKipQZXIgdmFyZXNpbmUgbWlkaXMgbmR5c2hvcmV2ZSB0ZSBkYXRhc2V0aXQgbmdhIG1hdHJpY2EgZSBrb3JyZWxhY2lvbml0IGRoZSB0ZXN0ZXZlIEhpLWthdHJvciBkb2xlbSBuZSBwZXJmdW5kaW0gcWUgbmRyeXNob3JldCBqYW5lIHRlIHBhdmFydXJhIG1lIG5qZXJhLXRqZXRyZW4uKioNCg0KKipOZ2Ega2pvIHBhdmFyZXNpIGVkaGUgbW9kZWxldCBlIHRlc3RldmUgcGFyYXNoaWt1ZXNlIHJlenVsdHVhbiBtZSBuamUgbWFyemggc2hwamVnaW1pIHNodW1lIHRlIHVsZXQuKioNCg0KIyMjIyAkJFJlZmVyZW5jYSQkDQoNCioqTmUgYW5hbGl6ZW4gZSB0ZSBkaGVuYXZlIGdqYXRlIHB1bmVzIHNlIHBhdmFydXIgc2hwZXNoIGplbWkgbmRlc2h1ciBuZSBzaXR1YXRhIHBlciB0ZSBjaWxhdCBraXNoaW0gbmV2b2plIHBlciBuamUgc2hwamVnaW0gZGhlIG9yaWVudGltLiBQZXIga2V0ZSBhcnN5ZSBpIGplbWkgcmVmZXJ1YXIgdGVrc3RpdCB0ZSBzdGF0aXN0aWtlcywgcG9yIGVkaGUgZmFxZXZlIHNpICRnb29nbGUuY29tJCwgcGxhdGZvcm1hdmUgc2kgJHdpa2lwZWRpYS5jb20kLCAkZ2Vla2ZvcmdlZWtzLmNvbSQsICR5b3V0dWJlLmNvbSQgZXRqLi4gTWUgcG9zaHRlIGxpc3RvaGVuIGRpc2EgbmdhIHNpdGV0IG5lIHRlIGNpbGF0IHBlcmZpdHVhbSBuamUgc2FzaSBpbmZvcm1hY2lvbmk6KioNCg0KKipDcmVkaXRzIHRvOiAkSHlyamUkICRuZSQgJFN0YXRpc3Rpa2VuJCAkZSQgJFpiYXR1YXIkICQzJCBuZ2EgJFByb2YuJCAkRHIuJCAkTGx1a2FuJCAkUHVrYSQ7KioNCg0KKipMaW5rIHRvIGRhdGFzZXQ6KiogaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9kYXRhc2V0cy9zdW1hbnRobmltbWFnYWRkYS9zdHVkZW50LXNwZW5kaW5nLWRhdGFzZXQvZGF0YQ0KDQpodHRwczovL3Bvc2l0LmNvL2Rvd25sb2FkL3JzdHVkaW8tZGVza3RvcC8NCg0KaHR0cHM6Ly93d3cua2hhbmFjYWRlbXkub3JnL21hdGgvc3RhdGlzdGljcy1wcm9iYWJpbGl0eS9zdW1tYXJpemluZy1xdWFudGl0YXRpdmUtZGF0YS9tZWFuLW1lZGlhbi1iYXNpY3MvYS9tZWFuLW1lZGlhbi1hbmQtbW9kZS1yZXZpZXcNCg0KaHR0cHM6Ly9zZWFyY2gueWFob28uY29tL3NlYXJjaD9mcjI9cCUzYWRzJTJjdiUzYW9tbiUyY20lM2FzYSUyY2Jyd3MlM2FjaHJvbWUlMmNwb3MlM2E0JmZyPW1jYWZlZSZ0eXBlPUUyMTBVUzkxMjE1RzAmcD1kZWdyZWVzK29mK2ZyZWVkb20rZm9ybXVsYQ0KDQpodHRwczovL3NlYXJjaC55YWhvby5jb20vc2VhcmNoO195bHQ9QXdyRmFFMVJtRDltWlFRQThsVlhOeW9BO195bGM9WDFNRE1qYzJOalkzT1FSZmNnTXlCR1p5QTIxallXWmxaUVJtY2pJRGMySXRkRzl3Qkdkd2NtbGtBMEZhU2xSdk5VSlZWRE54VFhadVZrczBWSGxIYVVFRWJsOXljMngwQXpBRWJsOXpkV2RuQXpFRWIzSnBaMmx1QTNObFlYSmphQzU1WVdodmJ5NWpiMjBFY0c5ekF6QUVjSEZ6ZEhJREJIQnhjM1J5YkFNd0JIRnpkSEpzQXpJMUJIRjFaWEo1QTNSaFlteGxKVEl3YjJZbE1qQmpiMjUwYVc1blpXNWplU1V5TUdsdUpUSXdVZ1IwWDNOMGJYQURNVGN4TlRRME16YzVPUS0tP3A9dGFibGUrb2YrY29udGluZ2VuY3kraW4rUiZmcj1tY2FmZWUmdHlwZT1FMjEwVVM5MTIxNUcwJmZyMj1zYi10b3AmaXNjcXJ5PQ0KDQpodHRwczovL3NlYXJjaC55YWhvby5jb20vc2VhcmNoP2ZyPW1jYWZlZSZ0eXBlPUUyMTBVUzkxMjE1RzAmcD1pbWkrZnNobg0KDQoqKkNoaS1zcXVhcmVkIFRlc3Q6KiogaHR0cHM6Ly9zZWFyY2gueWFob28uY29tL3NlYXJjaD9mcjI9cCUzYWRzJTJjdiUzYW9tbiUyY20lM2FzYSUyY2Jyd3MlM2FjaHJvbWUlMmNwb3MlM2ExJmZyPW1jYWZlZSZ0eXBlPUUyMTBVUzkxMjE1RzAmcD1jaGktc3F1YXJlK3Rlc3QNCg0KaHR0cDovL3d3dy5zdGhkYS5jb20vZW5nbGlzaC9hcnRpY2xlcy8zMi1yLWdyYXBoaWNzLWVzc2VudGlhbHMvMTMzLXBsb3Qtb25lLXZhcmlhYmxlLWZyZXF1ZW5jeS1ncmFwaC1kZW5zaXR5LWRpc3RyaWJ1dGlvbi1hbmQtbW9yZS8NCg0KKipNb3NhaWMgUGxvdDoqKiBodHRwczovL3NlYXJjaC55YWhvby5jb20vc2VhcmNoP2ZyPW1jYWZlZSZ0eXBlPUUyMTBVUzkxMjE1RzAmcD1tb3NhaWMrcGxvdA0KDQoqKldvcmQgQ2xvdWQgaW4gUjoqKiBodHRwczovL3d3dy5tYXJzamEuc2UvaG93LXRvLWNyZWF0ZS1hLXdvcmQtY2xvdWQtaW4tci8jZ29vZ2xlX3ZpZ25ldHRlDQoNCioqVmlzdWFsaXphdGlvbiB1c2luZyAkZ2dwbG90MiQ6KiogaHR0cHM6Ly93d3cuZGF0YXF1ZXN0LmlvL2Jsb2cvZGF0YS12aXN1YWxpemF0aW9uLWluLXItd2l0aC1nZ3Bsb3QyLWEtYmVnaW5uZXItdHV0b3JpYWwvDQoNCioqUmVzaWR1YWxzIHZzIExldmVyYWdlIFBsb3Q6KiogaHR0cHM6Ly9pbWFnZXMuc2VhcmNoLnlhaG9vLmNvbS9zZWFyY2gvaW1hZ2VzO195bHQ9QXdyRXE0el9VbFJtUkFRQW9lSlhOeW9BO195bHU9WTI5c2J3TmlaakVFY0c5ekF6RUVkblJwWkFNRWMyVmpBM0JwZG5NLT9wPXJlc2lkdWFscyt2cytsZXZlcmFnZStwbG90K2luK3ImZnIyPXBpdi13ZWImdHlwZT1FMjEwVVM5MTIxNUcwJmZyPW1jYWZlZQ0KDQoqKkhvdyB0byBpbnRlcnByZXQgYSBTY2FsZS1Mb2NhdGlvbiBQbG90OioqIGh0dHBzOi8vd3d3LnN0YXRvbG9neS5vcmcvc2NhbGUtbG9jYXRpb24tcGxvdC8NCg0KKipQcmVkaWN0ZWQgeSB2YWx1ZXM6KiogaHR0cHM6Ly9zZWFyY2gueWFob28uY29tL3NlYXJjaD9mcj1tY2FmZWUmdHlwZT1FMjEwVVM5MTIxNUcwJnA9cHJlZGljdGVkK3ZhbHVlK29mK3kraW4rcGxvdHMNCg0KKipSIGluc3RhbGxhdGlvbiAmIG1vcmU6KiogaHR0cHM6Ly95b3V0dS5iZS9GSXJzT0J5NWs1OD9zaT1mRGtUQnUwNm5oZjhVQTBBDQoNCmh0dHBzOi8veW91dHUuYmUvMl90VzdlNGVfZE0/c2k9LXNSTEZKcGI3aFBFR29UZg0KDQpodHRwczovL3lvdXR1LmJlL1lyRWUyVExyM01JP3NpPWZMQ1lHamFpVzZWSDZaUmcNCg0KaHR0cHM6Ly95b3V0dS5iZS80OGI0Qnp4SEhIOD9zaT1MT1IxT2dxblMtZkFpQWlMDQoNCmh0dHBzOi8veW91dHUuYmUvVW8xQzdJbGlndzA/c2k9NUVnM3ZxWEExYWlzWWFydg0KDQpodHRwczovL3lvdXR1LmJlL2VQRDk2aTBZSElJP3NpPXpIWmRWZVRFd202ck1qencNCg0KaHR0cHM6Ly95b3V0dS5iZS9zdmdFcFJ6aEc3TT9zaT1uMUlFRFVmeU9JZ3k5RFQzDQoNCioqTGluayB0byBlc3F1aXNzZXI6IGVzcXVpc3NlOjplc3F1aXNzZXIoZGF0YSwgdmlld2VyID0gImJyb3dzZXIiKSoqDQoNCiMjIyMgJCRXb3JkXCBDbG91ZCQkDQoNCmBgYHtyfQ0KbGlicmFyeSh3b3JkY2xvdWQpDQpsaWJyYXJ5KHdvcmRjbG91ZDIpDQpsaWJyYXJ5KFJDb2xvckJyZXdlcikNCg0KZmphbGV0IDwtIGMoIkpha3VwIiwiSmFrdXAiLCJKYWt1cCIsIkpha3VwIiwiSmFrdXAiLCJKYWt1cCIsIkpha3VwIiwiSmFrdXAiLCJKYWt1cCIsIkpha3VwIiwiSmFrdXAiLCAiQWRpc2EiLCAiQWRpc2EiLCJBZGlzYSIsIkFkaXNhIiwiQWRpc2EiLCJBZGlzYSIsIkFkaXNhIiwiQWRpc2EiLCJBZGlzYSIsIkFkaXNhIiwiQWRpc2EiLCJBZGlzYSIsIkFkaXNhIiwiQWRpc2EiLCJBZGlzYSIsIkFkaXNhIiwNCiJBZGlzYSIsIkFkaXNhIiwiQWRpc2EiLCJBZGlzYSIsIkFkaXNhIiwiQWRpc2EiLCJBZGlzYSIsIkRhdGEiLCJEYXRhIiwiRGF0YSIsIkRhdGEiLCJEYXRhIiwiRGF0YSIsIkRhdGEiLCJEYXRhIiwiRGF0YSIsIkRhdGEiLCJEYXRhIiwiRGF0YSIsIkRhdGEiLCAiU2NpZW5jZSIsIlNjaWVuY2UiLCJTY2llbmNlIiwiU2NpZW5jZSIsIlNjaWVuY2UiLCJTY2llbmNlIiwiU2NpZW5jZSIsIlNjaWVuY2UiLCJFbmdpbmVlciIsIkVuZ2luZWVyIiwiRW5naW5lZXIiLCJFbmdpbmVlciIsIkVuZ2luZWVyIiwiRW5naW5lZXIiLCJFbmdpbmVlciIsICJGU0hOIiwiRlNITiIsIkZTSE4iLCJGU0hOIiwiRlNITiIsIkZTSE4iLCJGU0hOIiwiRlNITiIsIkZTSE4iLCJGU0hOIiwiSU1JIiwiSU1JIiwiSU1JIiwiSU1JIiwiSU1JIiwiSU1JIiwiSU1JIiwiSU1JIiwiSU1JIiwiSU1JIiwiSU1JIiwiSU1JIiwiSU1JIiwiSU1JIiwiSU1JIiwiSU1JIiwiSU1JIiwgIjIwMjQiLCIyMDI0IiwiMjAyNCIsIjIwMjQiLCIyMDI0IiwiMjAyNCIsIjIwMjQiLCIyMDI0IiwiMjAyNCIsIjIwMjQiLCJKYWt1cCIsIkpha3VwIiwiSmFrdXAiLCJKYWt1cCIsIkpha3VwIiwiSmFrdXAiLCJKYWt1cCIsIkpha3VwIiwiSmFrdXAiLCJKYWt1cCIsIkpha3VwIiwgIkFkaXNhIiwiQWRpc2EiLCJBZGlzYSIsIkFkaXNhIiwiQWRpc2EiLCJBZGlzYSIsIkFkaXNhIiwiQWRpc2EiLCJBZGlzYSIsIkFkaXNhIiwiQWRpc2EiLCJBZGlzYSIsIkFkaXNhIiwiQWRpc2EiLCJBZGlzYSIsIkFkaXNhIiwiQWRpc2EiLCJBZGlzYSIsIkFkaXNhIiwiQWRpc2EiLCJBZGlzYSIsIkFkaXNhIiwiQWRpc2EiLCJEYXRhIiwiRGF0YSIsIkRhdGEiLCJEYXRhIiwiRGF0YSIsIkRhdGEiLCJEYXRhIiwiRGF0YSIsIkRhdGEiLCJEYXRhIiwiRGF0YSIsIkRhdGEiLCJEYXRhIiwgIlNjaWVuY2UiLCJTY2llbmNlIiwiU2NpZW5jZSIsIlNjaWVuY2UiLCJTY2llbmNlIiwiU2NpZW5jZSIsIlNjaWVuY2UiLCJTY2llbmNlIiwiRW5naW5lZXIiLCJFbmdpbmVlciIsIkVuZ2luZWVyIiwiRW5naW5lZXIiLCJFbmdpbmVlciIsIkVuZ2luZWVyIiwiRW5naW5lZXIiLCAiRlNITiIsIkZTSE4iLCJGU0hOIiwiRlNITiIsIkZTSE4iLCJGU0hOIiwiRlNITiIsIkZTSE4iLCJGU0hOIiwiRlNITiIsIklNSSIsIklNSSIsIklNSSIsIklNSSIsIklNSSIsIklNSSIsIklNSSIsIklNSSIsIklNSSIsIklNSSIsIklNSSIsIklNSSIsIklNSSIsIklNSSIsIklNSSIsIklNSSIsIklNSSIsICIyMDI0IiwiMjAyNCIsIjIwMjQiLCIyMDI0IiwiMjAyNCIsIjIwMjQiLCIyMDI0IiwiMjAyNCIsIjIwMjQiLCIyMDI0IikNCg0KZnJla3VlbmNhdCA8LSByZXAoZnJla3VlbmNhdCwgbGVuZ3RoLm91dCA9IGxlbmd0aChmamFsZXQpKQ0KZGF0YSA8LSBkYXRhLmZyYW1lKHdvcmQgPSBmamFsZXQsIGZyZXEgPSBmcmVrdWVuY2F0KQ0KDQp3b3JkY2xvdWQyKGRhdGEgPSBkYXRhLCBzaXplID0gMC4xLCBzaGFwZT0ncmFuZG9tJywgY29sb3I9J3JhbmRvbS1kYXJrJykNCmBgYA0KDQojIyMjICQkIkRvXCBub3RcIHRydXN0XCBhbnlcIHN0YXRpc3RpY3NcIHlvdVwgZGlkXCBub3RcIGZha2VcIHlvdXJzZWxmLlwgRmFjdHNcIGFyZVwgc3R1YmJvcm4sXCBidXRcIHN0YXRpc3RpY3NcIGFyZVwgbW9yZVwgcGxpYWJsZS4iXFwgOikkJA0KDQo=