Dlaczego kwantylowa?

Dlaczego potrzebujemy regresji kwantylowej (QR)?

W szczególności, QR:

  • jest odporna na punkty odstające i wpływowe

  • nie zakłada stałej wariancji (znanej jako homoskedastyczność) dla zmiennej odpowiedzi lub reszt

  • nie zakłada normalności ale główną zaletą QR w porównaniu z regresją liniową (LR) jest to, że QR bada różne wartości zmiennej odpowiedzi, a nie tylko średnią, i dostarcza w związku z tym pełniejszego obrazu związków między zmiennymi!

Wprowadzenie

Regresja kwantylowa (ang. quantile regression) została zaproponowana przez Koenkera i Bassetta (1978). Szczególny przypadek regresji kwantylowej dla kwantyla rzędu 0,5 (czyli mediany) jest równoważny estymatorowi LAD (ang. Least Absolute Deviation) – minimalizuje sumę bezwzględnych błędów.
Wprowadzenie różnych kwantyli regresji daje pełniejszy opis rozkładów warunkowych zwłaszcza w przypadku rozkładów asymetrycznych lub uciętych.

Regresja kwantylowa jest kolejną wariacją na temat najmniejszych kwadratów . Stratą jest współczynnik \(l_1\) funkcji:

\[ \phi(u) = \tau\max(u,0) - (1-\tau)\max(-u,0) = \frac{1}{2}|u| + \left(\tau - \frac{1}{2}\right)u, \]

gdzie \(\tau \in (0,1)\) oznacza konkretny kwantyl. Problemem jak poprzednio jest minimalizacja całkowitej straty resztowej. Model ten jest powszechnie stosowany w ekologii, ochronie zdrowia i innych dziedzinach, gdzie sama średnia nie wystarcza do uchwycenia złożonych zależności między zmiennymi.

Wymagania

Wymagana jest jedna liczbowa zmienna zależna. Zmienna przewidywana musi być zmienną ilościową. Predyktory mogą być zmiennymi ilościowymi lub sztucznymi zmiennymi w przypadku predyktorów jakościowych. Aby można było uruchomić analizę, wymagany jest wyraz wolny lub co najmniej jeden predyktor.

Regresja kwantylowa nie czyni założeń dotyczących rozkładu zmiennej przewidywanej i jest odporna na wpływ obserwacji odstających.

Analiza kwantylowa jest pokrewna regresji metodą najmniejszych kwadratów.

Przykład 1.

Wykorzystamy przykład z pakietu quantreg.

Jaki jest związek między całkowitym dochodem gospodarstwa domowego a odsetkiem dochodów wydatkowanych na żywność? Prawo Engela w ekonomii głosi, że w miarę wzrostu dochodów, część dochodów wydatkowanych na żywność spada, nawet jeśli wydatki na żywność bezwzględnie rosną. Stosując regresję kwantylową do tych danych, można określić, jakie wydatki na żywność ponosi 90% rodzin (dla 100 rodzin z danym dochodem), gdy nie interesują nas średnie wydatki na żywność.

Dane, które wykorzystamy - to zbiór “engel” - dane dotyczące wydatków na żywność. Jest to zbiór danych regresyjnych składający się z 235 obserwacji dotyczących dochodów i wydatków na żywność dla belgijskich gospodarstw domowych klasy robotniczej.

Powyższy wykres przedstawia dopasowanie regresji kwantylowej dla \(\tau = (0.1, 0.25, 0.5, 0.75, 0.90, 0.95)\). Dopasowanie KMNK to gruba czarna linia.

Poniżej znajduje się tabela z oszacowanymi współczynnikami.

knitr::kable(fits, format = "html", caption = "Oszacowania z KMNK oraz `quantreg`") %>%
    kable_styling("striped") %>%
    column_spec(1:8, background = "#ececec")
Oszacowania z KMNK oraz quantreg
OLS \(\tau_{0.10}\) \(\tau_{0.25}\) \(\tau_{0.50}\) \(\tau_{0.75}\) \(\tau_{0.90}\) \(\tau_{0.95}\)
(Intercept) 147.4753885 110.1415742 95.4835396 81.4822474 62.3965855 67.3508721 64.1039632
income 0.4851784 0.4017658 0.4741032 0.5601806 0.6440141 0.6862995 0.7090685

Ok, możemy to zrobić bardziej przejrzyście i sformatować w ładnej tabeli wyników:

## 
## Wyniki regresji kwantylowych
## ==========================================
##                   Dependent variable:     
##              -----------------------------
##                         foodexp           
##                 (1)       (2)       (3)   
## ------------------------------------------
## income       0.474***  0.560***  0.644*** 
##               (0.029)   (0.028)   (0.023) 
##                                           
## Constant     95.484*** 81.482*** 62.397***
##              (21.392)  (19.251)  (16.305) 
##                                           
## ------------------------------------------
## Observations    235       235       235   
## ==========================================
## Note:          *p<0.1; **p<0.05; ***p<0.01

Finalnie, zaprezentujmy wyłącznie te 3 modele na wykresie:

Przykład 2.

Tutaj przeprowadzimy testy użycia pakietu quantreg, wykorzystując wbudowany zbiór danych “mtcars”. Zmienna “mpg” oznacza spalanie samochodów (mile/galon).

Zamodulejmy zależność regresyjną dla tej zmiennej od kilku predyktorów.

Najpierw oszacujmy regresję KMNK:

kmnk <- lm(mpg ~ disp + hp + factor(am) + factor(vs), data = mtcars)
summary(kmnk)
## 
## Call:
## lm(formula = mpg ~ disp + hp + factor(am) + factor(vs), data = mtcars)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -4.7981 -1.9532  0.0111  1.5665  5.6321 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 24.832119   2.890418   8.591 3.32e-09 ***
## disp        -0.008304   0.010087  -0.823  0.41757    
## hp          -0.037623   0.013846  -2.717  0.01135 *  
## factor(am)1  4.419257   1.493243   2.960  0.00634 ** 
## factor(vs)1  2.052472   1.627096   1.261  0.21794    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2.812 on 27 degrees of freedom
## Multiple R-squared:  0.8104, Adjusted R-squared:  0.7823 
## F-statistic: 28.85 on 4 and 27 DF,  p-value: 2.13e-09

Teraz oszacujmy warunkowe regresje kwantylowe na różnych kwantylach, błąd standardowy uzyskany przez bootstrap.

Zauważ, że istnieje gradient we współczynnikach kwantylowych hp, jak również disp. Znak disp odwraca się, również współczynnik na czynniku am jest różny w zależności od kwantyli:

kwantyle <- c(0.25, 0.50, 0.75)
reg_kwantylowa <- rq(mpg ~ disp + hp + factor(am),tau = kwantyle,data = mtcars)
summary(reg_kwantylowa, se = "boot")
## 
## Call: rq(formula = mpg ~ disp + hp + factor(am), tau = kwantyle, data = mtcars)
## 
## tau: [1] 0.25
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept) 25.34665  1.65082   15.35395  0.00000
## disp        -0.02441  0.00718   -3.39750  0.00206
## hp          -0.01672  0.01661   -1.00628  0.32290
## factor(am)1  1.39719  1.35580    1.03053  0.31158
## 
## Call: rq(formula = mpg ~ disp + hp + factor(am), tau = kwantyle, data = mtcars)
## 
## tau: [1] 0.5
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept) 27.49722  1.85821   14.79771  0.00000
## disp        -0.02253  0.01574   -1.43150  0.16336
## hp          -0.02713  0.02403   -1.12915  0.26842
## factor(am)1  3.37328  2.10256    1.60437  0.11985
## 
## Call: rq(formula = mpg ~ disp + hp + factor(am), tau = kwantyle, data = mtcars)
## 
## tau: [1] 0.75
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept) 28.06384  1.76373   15.91168  0.00000
## disp         0.00445  0.01580    0.28171  0.78024
## hp          -0.06662  0.02121   -3.14053  0.00396
## factor(am)1  7.91402  2.49269    3.17489  0.00363

Testy współczynników

Użyjemy funkcji rq.anova z pakietu regresji kwantylowej, aby przeprowadzić test WALDA. Pamiętaj, że test WALDA mówi, że biorąc pod uwagę nieograniczone oszacowania modelu, przetestujemy hipotezę zerową mówiącą, że współczynniki spełniają pewne liniowe ograniczenia.

Aby ją przetestować, użyjemy obiektu zwróconego z uruchomienia rq z różnymi liczbami kwantyli i ustawimy opcję joint na true lub false. Gdy joint jest true: “równość współczynników kierunkowych powinna być wykonana jako wspólne testy na wszystkich parametrach nachylenia”, gdy joint jest false: “należy zgłaszać oddzielne testy na każdym z parametrów nachylenia”.

Zauważ, że testy kwantylowe są testami “linii równoległej”. Oznacza to, że powinniśmy wyjąć różne x-wyrazy_wolne dla każdego kwantyla, ponieważ reprezentują one poziomy rozkładów warunkowych. Jeśli jednak współczynniki kwantyli dla współczynnikow są takie same, to nie ma efektów specyficznych dla kwantyli, wystarczą efekty średnie.

Badanie statystycznej różnicy między 25. i 50. kwantylem warunkowym:

Biorąc pod uwagę powyższe oszacowania kwantyli, różnica między kwantylami 0,25 i 0,50 istnieje, ale czy są one wystarczająco duże, aby być statystycznie różne? Jaka jest wartość p? Przeglądając poniższe wyniki, nie są one statystycznie różne!

Po pierwsze, joint = TRUE. To nie jest testowanie, czy współczynnik na disp jest taki sam jak współczynnik na hp. To jest wspólne testowanie, czy współczynniki dla różnych kwantyli disp i różnych kwantyli hp są takie same dla każdej zmiennej.

kwantyle <- c(0.25, 0.50)
reg_kwantylowa <- rq(mpg ~ disp + hp + factor(am),tau = kwantyle, data = mtcars)
anova(reg_kwantylowa, test = "Wald", joint=TRUE)
## Quantile Regression Analysis of Deviance Table
## 
## Model: mpg ~ disp + hp + factor(am)
## Joint Test of Equality of Slopes: tau in {  0.25 0.5  }
## 
##   Df Resid Df F value Pr(>F)
## 1  3       61  0.8421 0.4761

Po drugie, joint = False:

anova(reg_kwantylowa, test = "Wald", joint=FALSE)
## Quantile Regression Analysis of Deviance Table
## 
## Model: mpg ~ disp + hp + factor(am)
## Tests of Equality of Distinct Slopes: tau in {  0.25 0.5  }
## 
##             Df Resid Df F value Pr(>F)
## disp         1       63  0.0305 0.8619
## hp           1       63  0.5461 0.4627
## factor(am)1  1       63  1.3500 0.2497

Badanie statystycznej różnicy między 25, 50 i 75 kwantylem warunkowym:

Pierwszy kwartyl i mediana nie wydają się być statystycznie różne, teraz dołączymy trzeci kwartyl. Jak widać wcześniej, kwartyle wspólnie wykazują gradient. Teraz możemy zobaczyć, że disp, hp i am są oddzielnie statystycznie różne.

Po pierwsze, joint = TRUE:

kwantyle <- c(0.25, 0.50, 0.75)

reg_kwantylowa <- rq(mpg ~ disp + hp + factor(am),tau = kwantyle, data = mtcars)

anova(reg_kwantylowa, test = "Wald", joint=TRUE)
## Quantile Regression Analysis of Deviance Table
## 
## Model: mpg ~ disp + hp + factor(am)
## Joint Test of Equality of Slopes: tau in {  0.25 0.5 0.75  }
## 
##   Df Resid Df F value   Pr(>F)   
## 1  6       90  3.3173 0.005367 **
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Po drugie, joint = False:

anova(reg_kwantylowa, test = "Wald", joint=FALSE)
## Quantile Regression Analysis of Deviance Table
## 
## Model: mpg ~ disp + hp + factor(am)
## Tests of Equality of Distinct Slopes: tau in {  0.25 0.5 0.75  }
## 
##             Df Resid Df F value   Pr(>F)   
## disp         2       94  5.4903 0.005558 **
## hp           2       94  6.7221 0.001868 **
## factor(am)1  2       94  7.2758 0.001154 **
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Dobroć dopasowania

Możemy obliczyć współczynniki dobroci dopasowania regresji kwantylowej z wykorzystaniem reszt i reszt bezwarunkowych:

goodfit(resid, resid_nl, tau)

Miara dobroci dopasowania dla regresji kwantylowej jest szacowana jako 1 minus stosunek sumy odchyleń bezwzględnych w modelach w pełni sparametryzowanych do sumy odchyleń bezwzględnych w zerowym (bezwarunkowym) modelu kwantylowym.

Wartości te są przydatne do porównań między modelami kwantylowymi, ale nie są porównywalne ze standardowymi współczynnikami determinacji. Te ostatnie oparte są na wariancji odchyleń kwadratowych, natomiast wartości dobroci dopasowania dla regresji kwantylowej oparte są na odchyleniach bezwzględnych. Wartości dobroci dopasowania zawsze będą mniejsze niż wartości R2.

## model kwantylowy
model1 <- rq(mpg ~ disp + hp + factor(am),tau = 0.5, data = mtcars)
reszty1 <- resid(model1)

## bezwarunkowy (pusty) model kwantylowy
model2 <- rq(mpg ~ 1, tau = 0.5,data=mtcars)
reszty2 <- resid(model2)

goodfit(reszty1, reszty2, 0.5)
## [1] 0.5403311
## r2 modelu KMNK dla porównania
model_lm <- lm(mpg ~ disp + hp + factor(am), data = mtcars)

summary(model_lm)$r.squared
## [1] 0.7992061

Zadanie

Teraz Wasza kolej ;-)

Waszym zadaniem dzisiaj jest zamodelowanie - porównanie KMNK oraz regresji kwantylowej (różno-poziomowej) dla zmiennej “earnings” - wynagrodzenia.

Dobierz i przetestuj predyktory, kwantyle dla modeli. Wykonaj testy różnic współczynnikow dla finalnych modeli.

W przypadku problemów - obejrzyj video tutorial (włącz polskie napisy) oraz wejdź na jego stronę ze źródłami. Możesz również wykorzystać w/w przykłady.

data("CPSSW9298")
dane = CPSSW9298
dane92 <- filter(dane, year == 1992)
dane98 <- filter(dane, year == 1998)
  1. Model KMNK
lm_model92 <- lm(earnings ~ degree + gender + age, data = dane92)
summary(lm_model92)
## 
## Call:
## lm(formula = earnings ~ degree + gender + age, data = dane92)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -13.172  -3.324  -0.606   2.580  32.651 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)     0.62877    0.61537   1.022    0.307    
## degreebachelor  4.38740    0.11758  37.314   <2e-16 ***
## genderfemale   -2.00554    0.11581 -17.318   <2e-16 ***
## age             0.34221    0.02041  16.771   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 4.981 on 7586 degrees of freedom
## Multiple R-squared:  0.1956, Adjusted R-squared:  0.1953 
## F-statistic: 614.9 on 3 and 7586 DF,  p-value: < 2.2e-16

R-kwadrat dla modelu KNMK wynosi około 0,2, co oznacza, że tylko 20% zmienności w danych jest wyjaśnione przez model. Taki wynik sugeruje, że model ma ograniczoną zdolność do wyjaśniania rozkładu zmiennych zależnych i pozostaje duża część zmienności, która nie jest ujęta w analizie.

  1. Regresje kwantylowe dla tau = 0.25, 0.50, 0.75
kwantyle <- c(0.25, 0.50, 0.75)
reg_kwantylowa_92 <- rq(earnings ~ degree + gender + age, tau = kwantyle, data = dane92)
## Warning in rq.fit.br(x, y, tau = tau, ...): Solution may be nonunique
summary(reg_kwantylowa_92, se = "boot")
## 
## Call: rq(formula = earnings ~ degree + gender + age, tau = kwantyle, 
##     data = dane92)
## 
## tau: [1] 0.25
## 
## Coefficients:
##                Value    Std. Error t value  Pr(>|t|)
## (Intercept)     1.92427  0.70921    2.71324  0.00668
## degreebachelor  3.41880  0.13755   24.85535  0.00000
## genderfemale   -1.14850  0.12131   -9.46765  0.00000
## age             0.18222  0.02409    7.56283  0.00000
## 
## Call: rq(formula = earnings ~ degree + gender + age, tau = kwantyle, 
##     data = dane92)
## 
## tau: [1] 0.5
## 
## Coefficients:
##                Value     Std. Error t value   Pr(>|t|) 
## (Intercept)      0.73078   0.68726    1.06331   0.28767
## degreebachelor   4.33269   0.12128   35.72555   0.00000
## genderfemale    -1.91923   0.11753  -16.32935   0.00000
## age              0.31731   0.02400   13.21971   0.00000
## 
## Call: rq(formula = earnings ~ degree + gender + age, tau = kwantyle, 
##     data = dane92)
## 
## tau: [1] 0.75
## 
## Coefficients:
##                Value     Std. Error t value   Pr(>|t|) 
## (Intercept)      1.24944   0.94223    1.32604   0.18486
## degreebachelor   5.17262   0.17113   30.22693   0.00000
## genderfemale    -2.52525   0.16859  -14.97866   0.00000
## age              0.40965   0.03108   13.18221   0.00000
kwantyle <- c(0.25, 0.50)
reg_kwantylowa <- rq(earnings ~ degree + gender + age, tau = kwantyle, data = dane92)
## Warning in rq.fit.br(x, y, tau = tau, ...): Solution may be nonunique
anova(reg_kwantylowa, test = "Wald", joint=TRUE)
## Quantile Regression Analysis of Deviance Table
## 
## Model: earnings ~ degree + gender + age
## Joint Test of Equality of Slopes: tau in {  0.25 0.5  }
## 
##   Df Resid Df F value    Pr(>F)    
## 1  3    15177  48.241 < 2.2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Wyniki analizy wskazują, że zmienne takie jak wykształcenie, płeć i wiek mają istotny wpływ na dochody, szczególnie w różnych kwantylach dochodów, takich jak 0.25 i 0.5. Oznacza to, że te czynniki wywierają różny wpływ na dochody w zależności od poziomu dochodu, co sugeruje, że efekt tych zmiennych może się zmieniać w różnych częściach rozkładu dochodów. Ponadto, wartość p uzyskana w badaniu jest bardzo mała, co pozwala na odrzucenie hipotezy zerowej o braku różnic w nachyleniach między kwantylami. W rezultacie, możemy uznać, że istnieje statystycznie istotna różnica w sposobie, w jaki model zachowuje się w różnych kwantylach, co oznacza, że zmienne te mają zróżnicowany wpływ na dochody w różnych częściach rozkładu.

anova(reg_kwantylowa, test = "Wald", joint=FALSE)
## Quantile Regression Analysis of Deviance Table
## 
## Model: earnings ~ degree + gender + age
## Tests of Equality of Distinct Slopes: tau in {  0.25 0.5  }
## 
##                Df Resid Df F value    Pr(>F)    
## degreebachelor  1    15179  54.171 1.932e-13 ***
## genderfemale    1    15179  49.118 2.512e-12 ***
## age             1    15179  47.431 5.920e-12 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Te zmienne mają istotny wpływ na dochody w różnych częściach rozkładu, co sugeruje, że wpływ wykształcenia, płci i wieku na dochody może różnić się w zależności od tego, czy analizujemy niższe, czy wyższe kwantyle dochodów. W praktyce oznacza to, że te czynniki mogą oddziaływać na osoby z niższymi dochodami w inny sposób niż na osoby z wyższymi dochodami. Takie różnice w wpływie mogą wynikać z tego, że na różnych poziomach dochodów różne zmienne mogą odgrywać odmienną rolę w kształtowaniu wynagrodzeń. Na przykład, wykształcenie może mieć większy wpływ na osoby w niższych kwantylach dochodów, podczas gdy inne czynniki, takie jak doświadczenie zawodowe czy sieć kontaktów, mogą być bardziej znaczące dla osób w wyższych kwantylach. Takie różnice wskazują, że podejście do analizy dochodów powinno uwzględniać nie tylko ogólny wpływ zmiennych, ale także ich zróżnicowane efekty w zależności od poziomu dochodu.

kwantyle <- c(0.25, 0.50, 0.75)

reg_kwantylowa <- rq(earnings ~ degree + gender + age, tau = kwantyle, data = dane92)
## Warning in rq.fit.br(x, y, tau = tau, ...): Solution may be nonunique
anova(reg_kwantylowa, test = "Wald", joint=TRUE)
## Quantile Regression Analysis of Deviance Table
## 
## Model: earnings ~ degree + gender + age
## Joint Test of Equality of Slopes: tau in {  0.25 0.5 0.75  }
## 
##   Df Resid Df F value    Pr(>F)    
## 1  6    22764  39.282 < 2.2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Tak jak wczesniej takze i przy uwzględnieniu kwantylu 0.75 wszystkie zmienne okazały się być istotne statystyczne.

anova(reg_kwantylowa, test = "Wald", joint=FALSE)
## Quantile Regression Analysis of Deviance Table
## 
## Model: earnings ~ degree + gender + age
## Tests of Equality of Distinct Slopes: tau in {  0.25 0.5 0.75  }
## 
##                Df Resid Df F value    Pr(>F)    
## degreebachelor  2    22768  48.950 < 2.2e-16 ***
## genderfemale    2    22768  39.262 < 2.2e-16 ***
## age             2    22768  35.296 4.441e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Wyniki te są również podobne do tych uzyskanych przy analizie kwantyli, w której nie uwzględniono wartości 0.75. Oznacza to, że wpływ zmiennych takich jak wykształcenie, płeć i wiek na dochody pozostaje zasadniczo spójny, niezależnie od tego, czy analizujemy tylko kwantyle 0.25 i 0.5, czy również dodajemy 0.75. Choć uwzględnienie dodatkowego kwantyla mogłoby potencjalnie wpłynąć na wyniki, obserwowane zmiany w dochodach w niższych i średnich kwantylach wskazują na podobne zależności, co sugeruje, że główne efekty zmiennych pozostają stabilne.

## model kwantylowy dla 0.25
model1 <- rq(earnings ~ degree + gender + age, tau = 0.25, data = dane92)
reszty1 <- resid(model1)

## bezwarunkowy (pusty) model kwantylowy
model2 <- rq(earnings ~ 1, tau = 0.25,data=dane92)
reszty2 <- resid(model2)

goodfit(reszty1, reszty2, 0.25)
## [1] 0.08036852
## model kwantylowy dla 0.5
model1 <- rq(earnings ~ degree + gender + age, tau = 0.5, data = dane92)
## Warning in rq.fit.br(x, y, tau = tau, ...): Solution may be nonunique
reszty1 <- resid(model1)

## bezwarunkowy (pusty) model kwantylowy
model2 <- rq(earnings ~ 1, tau = 0.5,data=dane92)
## Warning in rq.fit.br(x, y, tau = tau, ...): Solution may be nonunique
reszty2 <- resid(model2)

goodfit(reszty1, reszty2, 0.5)
## [1] 0.1095095
## model kwantylowy 0.75
model1 <- rq(earnings ~ degree + gender + age, tau = 0.75, data = dane92)
reszty1 <- resid(model1)

## bezwarunkowy (pusty) model kwantylowy
model2 <- rq(earnings ~ 1, tau = 0.75,data=dane92)
reszty2 <- resid(model2)

goodfit(reszty1, reszty2, 0.75)
## [1] 0.1401108

Wartości w zakresie od 0.08 do 0.14 wskazują, że model kwantylowy rzeczywiście wprowadza pewną poprawę w stosunku do modelu pustego, jednak ta zmiana nie jest znacząca. Takie wartości sugerują, że wpływ zmiennych na dochody w analizowanych kwantylach nie jest bardzo silny, a różnica w dopasowaniu modeli nie jest ogromna. W szczególności, gdyby wartości miary dopasowania były bliskie zeru, oznaczałoby to, że zmienne miałyby bardzo silny wpływ na dochody w danym kwantylu.

Biorąc pod uwagę miarę dopasowania, model kwantylowy dla tau = 0.25 wydaje się być najbardziej odpowiedni, ponieważ oferuje najlepsze dopasowanie do danych w tym kwantylu. Oznacza to, że zmienne takie jak wykształcenie, płeć i wiek mają najsilniejszy wpływ na dochody w tym właśnie przedziale dochodów w porównaniu do innych modeli, co sugeruje, że w tym zakresie zmienne te odgrywają kluczową rolę w kształtowaniu wynagrodzeń. Choć zmiana w dopasowaniu nie jest drastyczna, model kwantylowy dla tau = 0.25 wydaje się lepiej oddawać rzeczywisty rozkład dochodów w tym konkretnym kwantylu.

LS0tDQp0aXRsZTogJ05pZWtsYXN5Y3puZSBtZXRvZHkgc3RhdHlzdHlraScNCnN1YnRpdGxlOiAnUmVncmVzamEga3dhbnR5bG93YScNCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCINCmF1dGhvcjogIkFsZWtzYW5kcmEgQnVrb3dza2EiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIHRoZW1lOiBjZXJ1bGVhbg0KICAgIGhpZ2hsaWdodDogdGV4dG1hdGUNCiAgICBmb250c2l6ZTogMTBwdA0KICAgIHRvYzogeWVzDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgdG9jX2Zsb2F0Og0KICAgICAgY29sbGFwc2VkOiBubw0KICAgIGRmX3ByaW50OiBkZWZhdWx0DQogICAgdG9jX2RlcHRoOiA1DQplZGl0b3Jfb3B0aW9uczogDQogIG1hcmtkb3duOiANCiAgICB3cmFwOiA3Mg0KLS0tDQoNCmBgYHtyIHByZXJlcXMsIG1lc3NhZ2UgPSBGQUxTRSwgZWNobyA9IEZBTFNFfQ0KI2luc3RhbGwucGFja2FnZXMoIkNWWFIiKQ0KbGlicmFyeShDVlhSKQ0KI2luc3RhbGwucGFja2FnZXMoIkFFUiIpDQojaW5zdGFsbC5wYWNrYWdlcygic3RhcmdhemVyIikNCiNpbnN0YWxsLnBhY2thZ2VzKCJrYWJsZUV4dHJhIikNCmxpYnJhcnkoQUVSKQ0KbGlicmFyeShzdGFyZ2F6ZXIpDQpsaWJyYXJ5KFdSVERTdGlkYWwpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoa2FibGVFeHRyYSkNCmxpYnJhcnkocXVhbnRyZWcpDQpsaWJyYXJ5KFBvZ3JvbWN5RGFueWNoKQ0KYGBgDQoNCiMjIERsYWN6ZWdvIGt3YW50eWxvd2E/DQoNCkRsYWN6ZWdvIHBvdHJ6ZWJ1amVteSByZWdyZXNqaSBrd2FudHlsb3dlaiAoUVIpPw0KDQpXIHN6Y3plZ8OzbG5vxZtjaSwgUVI6DQoNCi0gICBqZXN0IG9kcG9ybmEgbmEgcHVua3R5IG9kc3RhasSFY2UgaSB3cMWCeXdvd2UNCg0KLSAgIG5pZSB6YWvFgmFkYSBzdGHFgmVqIHdhcmlhbmNqaSAoem5hbmVqIGpha28gaG9tb3NrZWRhc3R5Y3pub8WbxIcpIGRsYQ0KICAgIHptaWVubmVqIG9kcG93aWVkemkgbHViIHJlc3p0DQoNCi0gICBuaWUgemFrxYJhZGEgbm9ybWFsbm/Fm2NpIGFsZSBnxYLDs3duxIUgemFsZXTEhSBRUiB3IHBvcsOzd25hbml1IHogcmVncmVzasSFDQogICAgbGluaW93xIUgKExSKSBqZXN0IHRvLCDFvGUgUVIgYmFkYSByw7PFvG5lIHdhcnRvxZtjaSB6bWllbm5laiBvZHBvd2llZHppLA0KICAgIGEgbmllIHR5bGtvIMWbcmVkbmnEhSwgaSBkb3N0YXJjemEgdyB6d2nEhXprdSB6IHR5bSBwZcWCbmllanN6ZWdvIG9icmF6dQ0KICAgIHp3acSFemvDs3cgbWnEmWR6eSB6bWllbm55bWkhDQoNCiMjIFdwcm93YWR6ZW5pZQ0KDQpSZWdyZXNqYSBrd2FudHlsb3dhIChhbmcuIHF1YW50aWxlIHJlZ3Jlc3Npb24pIHpvc3RhxYJhIHphcHJvcG9ub3dhbmENCnByemV6IEtvZW5rZXJhIGkgQmFzc2V0dGEgKDE5NzgpLiBTemN6ZWfDs2xueSBwcnp5cGFkZWsgcmVncmVzamkNCmt3YW50eWxvd2VqIGRsYSBrd2FudHlsYSByesSZZHUgMCw1IChjenlsaSBtZWRpYW55KSBqZXN0IHLDs3dub3dhxbxueQ0KZXN0eW1hdG9yb3dpIExBRCAoYW5nLiBMZWFzdCBBYnNvbHV0ZSBEZXZpYXRpb24pIC0tIG1pbmltYWxpenVqZSBzdW3EmQ0KYmV6d3pnbMSZZG55Y2ggYsWCxJlkw7N3LlwNCldwcm93YWR6ZW5pZSByw7PFvG55Y2gga3dhbnR5bGkgcmVncmVzamkgZGFqZSBwZcWCbmllanN6eSBvcGlzIHJvemvFgmFkw7N3DQp3YXJ1bmtvd3ljaCB6d8WCYXN6Y3phIHcgcHJ6eXBhZGt1IHJvemvFgmFkw7N3IGFzeW1ldHJ5Y3pueWNoIGx1YiB1Y2nEmXR5Y2guDQoNClJlZ3Jlc2phIGt3YW50eWxvd2EgamVzdCBrb2xlam7EhSB3YXJpYWNqxIUgbmEgdGVtYXQgbmFqbW5pZWpzenljaA0Ka3dhZHJhdMOzdyBcY2l0ZXB7cXVhbnRpbGV9LiBTdHJhdMSFIGplc3Qgd3Nww7PFgmN6eW5uaWsgJGxfMSQgZnVua2NqaToNCg0KJCQNCiAgICBccGhpKHUpID0gXHRhdVxtYXgodSwwKSAtICgxLVx0YXUpXG1heCgtdSwwKSA9IFxmcmFjezF9ezJ9fHV8ICsgXGxlZnQoXHRhdSAtIFxmcmFjezF9ezJ9XHJpZ2h0KXUsDQokJA0KDQpnZHppZSAkXHRhdSBcaW4gKDAsMSkkIG96bmFjemEga29ua3JldG55IGt3YW50eWwuIFByb2JsZW1lbSBqYWsNCnBvcHJ6ZWRuaW8gamVzdCBtaW5pbWFsaXphY2phIGNhxYJrb3dpdGVqIHN0cmF0eSByZXN6dG93ZWouIE1vZGVsIHRlbg0KamVzdCBwb3dzemVjaG5pZSBzdG9zb3dhbnkgdyBla29sb2dpaSwgb2Nocm9uaWUgemRyb3dpYSBpIGlubnljaA0KZHppZWR6aW5hY2gsIGdkemllIHNhbWEgxZtyZWRuaWEgbmllIHd5c3RhcmN6YSBkbyB1Y2h3eWNlbmlhIHrFgm/FvG9ueWNoDQp6YWxlxbxub8WbY2kgbWnEmWR6eSB6bWllbm55bWkuDQoNCiMjIFd5bWFnYW5pYQ0KDQpXeW1hZ2FuYSBqZXN0IGplZG5hIGxpY3pib3dhIHptaWVubmEgemFsZcW8bmEuIFptaWVubmEgcHJ6ZXdpZHl3YW5hIG11c2kNCmJ5xIcgem1pZW5uxIUgaWxvxZtjaW93xIUuIFByZWR5a3RvcnkgbW9nxIUgYnnEhyB6bWllbm55bWkgaWxvxZtjaW93eW1pIGx1Yg0Kc3p0dWN6bnltaSB6bWllbm55bWkgdyBwcnp5cGFka3UgcHJlZHlrdG9yw7N3IGpha2/Fm2Npb3d5Y2guIEFieSBtb8W8bmENCmJ5xYJvIHVydWNob21pxIcgYW5hbGl6xJksIHd5bWFnYW55IGplc3Qgd3lyYXogd29sbnkgbHViIGNvIG5ham1uaWVqIGplZGVuDQpwcmVkeWt0b3IuDQoNClJlZ3Jlc2phIGt3YW50eWxvd2EgbmllIGN6eW5pIHphxYJvxbxlxYQgZG90eWN6xIVjeWNoIHJvemvFgmFkdSB6bWllbm5lag0KcHJ6ZXdpZHl3YW5laiBpIGplc3Qgb2Rwb3JuYSBuYSB3cMWCeXcgb2JzZXJ3YWNqaSBvZHN0YWrEhWN5Y2guDQoNCkFuYWxpemEga3dhbnR5bG93YSBqZXN0IHBva3Jld25hIHJlZ3Jlc2ppIG1ldG9kxIUgbmFqbW5pZWpzenljaA0Ka3dhZHJhdMOzdy4NCg0KIyMgUHJ6eWvFgmFkIDEuDQoNCld5a29yenlzdGFteSBwcnp5a8WCYWQgeiBwYWtpZXR1IHF1YW50cmVnLg0KDQpKYWtpIGplc3QgendpxIV6ZWsgbWnEmWR6eSBjYcWCa293aXR5bSBkb2Nob2RlbSBnb3Nwb2RhcnN0d2EgZG9tb3dlZ28gYQ0Kb2RzZXRraWVtIGRvY2hvZMOzdyB3eWRhdGtvd2FueWNoIG5hIMW8eXdub8WbxIc/IFByYXdvIEVuZ2VsYSB3IGVrb25vbWlpDQpnxYJvc2ksIMW8ZSB3IG1pYXLEmSB3enJvc3R1IGRvY2hvZMOzdywgY3rEmcWbxIcgZG9jaG9kw7N3IHd5ZGF0a293YW55Y2ggbmENCsW8eXdub8WbxIcgc3BhZGEsIG5hd2V0IGplxZtsaSB3eWRhdGtpIG5hIMW8eXdub8WbxIcgYmV6d3pnbMSZZG5pZSByb3NuxIUuDQpTdG9zdWrEhWMgcmVncmVzasSZIGt3YW50eWxvd8SFIGRvIHR5Y2ggZGFueWNoLCBtb8W8bmEgb2tyZcWbbGnEhywgamFraWUNCnd5ZGF0a2kgbmEgxbx5d25vxZvEhyBwb25vc2kgOTAlIHJvZHppbiAoZGxhIDEwMCByb2R6aW4geiBkYW55bSBkb2Nob2RlbSksDQpnZHkgbmllIGludGVyZXN1asSFIG5hcyDFm3JlZG5pZSB3eWRhdGtpIG5hIMW8eXdub8WbxIcuDQoNCkRhbmUsIGt0w7NyZSB3eWtvcnp5c3RhbXkgLSB0byB6YmnDs3IgImVuZ2VsIiAtIGRhbmUgZG90eWN6xIVjZSB3eWRhdGvDs3cgbmENCsW8eXdub8WbxIcuIEplc3QgdG8gemJpw7NyIGRhbnljaCByZWdyZXN5am55Y2ggc2vFgmFkYWrEhWN5IHNpxJkgeiAyMzUNCm9ic2Vyd2FjamkgZG90eWN6xIVjeWNoIGRvY2hvZMOzdyBpIHd5ZGF0a8OzdyBuYSDFvHl3bm/Fm8SHIGRsYSBiZWxnaWpza2ljaA0KZ29zcG9kYXJzdHcgZG9tb3d5Y2gga2xhc3kgcm9ib3RuaWN6ZWouDQoNCmBgYHtyIGVjaG89RkFMU0V9DQpkYXRhKGVuZ2VsKSAjZGFuZSANCnAgPC0gZ2dwbG90KGRhdGEgPSBlbmdlbCkgKw0KICAgIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gaW5jb21lLCB5ID0gZm9vZGV4cCksIGNvbG9yID0gImJsdWUiKQ0KdGF1cyA8LSBjKDAuMSwgMC4yNSwgMC41LCAwLjc1LCAwLjkwLCAwLjk1KQ0KZml0cyA8LSBkYXRhLmZyYW1lKA0KICAgIGNvZWYobG0oZm9vZGV4cCB+IGluY29tZSwgZGF0YSA9IGVuZ2VsKSksDQogICAgc2FwcGx5KHRhdXMsIGZ1bmN0aW9uKHgpIGNvZWYocnEoZm9ybXVsYSA9IGZvb2RleHAgfiBpbmNvbWUsIGRhdGEgPSBlbmdlbCwgdGF1ID0geCkpKSkNCm5hbWVzKGZpdHMpIDwtIGMoIk9MUyIsIHNwcmludGYoIiRcXHRhdV97JTAuMmZ9JCIsIHRhdXMpKQ0KbmYgPC0gbmNvbChmaXRzKQ0KY29sb3JzIDwtIGNvbG9yUmFtcFBhbGV0dGUoY29sb3JzID0gYygiYmxhY2siLCAicmVkIikpKG5mKQ0KcCA8LSBwICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gZml0c1sxLCAxXSwgc2xvcGUgPSBmaXRzWzIsIDFdLCBjb2xvciA9IGNvbG9yc1sxXSwgbGluZXdpZHRoID0gMS41KQ0KZm9yIChpIGluIHNlcV9sZW4obmYpWy0xXSkgew0KICAgIHAgPC0gcCArIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IGZpdHNbMSwgaV0sIHNsb3BlID0gZml0c1syLCBpXSwgY29sb3IgPSBjb2xvcnNbaV0pDQp9DQpwDQpgYGANCg0KUG93ecW8c3p5IHd5a3JlcyBwcnplZHN0YXdpYSBkb3Bhc293YW5pZSByZWdyZXNqaSBrd2FudHlsb3dlaiBkbGENCiRcdGF1ID0gKDAuMSwgMC4yNSwgMC41LCAwLjc1LCAwLjkwLCAwLjk1KSQuIERvcGFzb3dhbmllIEtNTksgdG8gZ3J1YmENCmN6YXJuYSBsaW5pYS4NCg0KUG9uacW8ZWogem5hamR1amUgc2nEmSB0YWJlbGEgeiBvc3phY293YW55bWkgd3Nww7PFgmN6eW5uaWthbWkuDQoNCmBgYHtyfQ0Ka25pdHI6OmthYmxlKGZpdHMsIGZvcm1hdCA9ICJodG1sIiwgY2FwdGlvbiA9ICJPc3phY293YW5pYSB6IEtNTksgb3JheiBgcXVhbnRyZWdgIikgJT4lDQogICAga2FibGVfc3R5bGluZygic3RyaXBlZCIpICU+JQ0KICAgIGNvbHVtbl9zcGVjKDE6OCwgYmFja2dyb3VuZCA9ICIjZWNlY2VjIikNCmBgYA0KDQpPaywgbW/FvGVteSB0byB6cm9iacSHIGJhcmR6aWVqIHByemVqcnp5xZtjaWUgaSBzZm9ybWF0b3dhxIcgdyDFgmFkbmVqIHRhYmVsaQ0Kd3luaWvDs3c6DQoNCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHBhZ2VkLnByaW50PVRSVUV9DQpxMjUgPC0gcnEoZm9vZGV4cCB+IGluY29tZSwgZGF0YSA9IGVuZ2VsLCB0YXUgPSAwLjI1KQ0KcTUwIDwtIHJxKGZvb2RleHAgfiBpbmNvbWUsIGRhdGEgPSBlbmdlbCwgdGF1ID0gMC41MCkNCnE3NSA8LSBycShmb29kZXhwIH4gaW5jb21lLCBkYXRhID0gZW5nZWwsIHRhdSA9IDAuNzUpDQoNCiMgVGFiZWxhIHogcG9yw7N3bmFuaWVtIHd5bmlrw7N3IHRyemVjaCBtb2RlbGk6IA0KDQpzdGFyZ2F6ZXIocTI1LCBxNTAsIHE3NSwgdGl0bGUgPSAiV3luaWtpIHJlZ3Jlc2ppIGt3YW50eWxvd3ljaCIsIHR5cGUgPSAidGV4dCIpDQpgYGANCg0KRmluYWxuaWUsIHphcHJlemVudHVqbXkgd3nFgsSFY3puaWUgdGUgMyBtb2RlbGUgbmEgd3lrcmVzaWU6DQoNCmBgYHtyIGVjaG89RkFMU0V9DQpteV9xciA8LSBycShmb29kZXhwIH4gaW5jb21lLCBkYXRhID0gZW5nZWwsIHRhdSA9IHNlcSgwLjI1LCAwLjc1LCAwLjI1KSkNCg0KaW50ZXJjZXB0X3Nsb3BlIDwtIG15X3FyICU+JSANCiAgY29lZigpICU+JSANCiAgdCgpICU+JSANCiAgZGF0YS5mcmFtZSgpICU+JSANCiAgcmVuYW1lKGludGVyY2VwdCA9IFguSW50ZXJjZXB0Liwgc2xvcGUgPSBpbmNvbWUpICU+JSANCiAgbXV0YXRlKHF1YW50aWxlID0gcm93Lm5hbWVzKC4pKQ0KDQpnZ3Bsb3QoKSArIA0KICBnZW9tX3BvaW50KGRhdGEgPSBlbmdlbCwgYWVzKGluY29tZSwgZm9vZGV4cCksIGFscGhhID0gMC41KSArIA0KICBnZW9tX2FibGluZShkYXRhID0gaW50ZXJjZXB0X3Nsb3BlLCBhZXMoaW50ZXJjZXB0ID0gaW50ZXJjZXB0LCBzbG9wZSA9IHNsb3BlLCBjb2xvciA9IHF1YW50aWxlKSkgKyANCiAgdGhlbWVfbWluaW1hbCgpICsgDQogIGxhYnMoeCA9ICJEb2Now7NkIiwgeSA9ICJXeWRhdGtpIG5hIMW8eXdub8WbxIciLCB0aXRsZSA9ICJSZWdyZXNqZSBrd2FudHlsb3dlIHogdGF1ID0gMC4yNSwgMC41MCBvcmF6IDAuNzUiLCANCiAgICAgICBjYXB0aW9uID0gIsW5csOzZMWCbyBkYW55Y2g6IEtvZW5rZXIgYW5kIEJhc3NldHQgKDE5ODIpIikNCmBgYA0KDQojIyBQcnp5a8WCYWQgMi4NCg0KVHV0YWogcHJ6ZXByb3dhZHppbXkgdGVzdHkgdcW8eWNpYSBwYWtpZXR1IHF1YW50cmVnLCB3eWtvcnp5c3R1asSFYw0Kd2J1ZG93YW55IHpiacOzciBkYW55Y2ggIioqbXRjYXJzKioiLiBabWllbm5hICIqKm1wZyoqIiBvem5hY3phIHNwYWxhbmllDQpzYW1vY2hvZMOzdyAoKm1pbGUvZ2Fsb24qKS4NCg0KWmFtb2R1bGVqbXkgemFsZcW8bm/Fm8SHIHJlZ3Jlc3lqbsSFIGRsYSB0ZWogem1pZW5uZWogb2Qga2lsa3UgcHJlZHlrdG9yw7N3Lg0KDQpOYWpwaWVydyBvc3phY3VqbXkgcmVncmVzasSZIEtNTks6DQoNCmBgYHtyfQ0Ka21uayA8LSBsbShtcGcgfiBkaXNwICsgaHAgKyBmYWN0b3IoYW0pICsgZmFjdG9yKHZzKSwgZGF0YSA9IG10Y2FycykNCnN1bW1hcnkoa21uaykNCmBgYA0KDQpUZXJheiBvc3phY3VqbXkgd2FydW5rb3dlIHJlZ3Jlc2plIGt3YW50eWxvd2UgbmEgcsOzxbxueWNoIGt3YW50eWxhY2gsDQpixYLEhWQgc3RhbmRhcmRvd3kgdXp5c2thbnkgcHJ6ZXogKioqYm9vdHN0cmFwKioqLg0KDQpaYXV3YcW8LCDFvGUgaXN0bmllamUgZ3JhZGllbnQgd2Ugd3Nww7PFgmN6eW5uaWthY2gga3dhbnR5bG93eWNoICoqaHAqKiwgamFrDQpyw7N3bmllxbwgKipkaXNwKiouIFpuYWsgKipkaXNwKiogb2R3cmFjYSBzacSZLCByw7N3bmllxbwgd3Nww7PFgmN6eW5uaWsgbmENCmN6eW5uaWt1ICoqYW0qKiBqZXN0IHLDs8W8bnkgdyB6YWxlxbxub8WbY2kgb2Qga3dhbnR5bGk6DQoNCmBgYHtyfQ0Ka3dhbnR5bGUgPC0gYygwLjI1LCAwLjUwLCAwLjc1KQ0KcmVnX2t3YW50eWxvd2EgPC0gcnEobXBnIH4gZGlzcCArIGhwICsgZmFjdG9yKGFtKSx0YXUgPSBrd2FudHlsZSxkYXRhID0gbXRjYXJzKQ0Kc3VtbWFyeShyZWdfa3dhbnR5bG93YSwgc2UgPSAiYm9vdCIpDQpgYGANCg0KIyMjIFRlc3R5IHdzcMOzxYJjenlubmlrw7N3DQoNClXFvHlqZW15IGZ1bmtjamkgcnEuYW5vdmEgeiBwYWtpZXR1IHJlZ3Jlc2ppIGt3YW50eWxvd2VqLCBhYnkNCnByemVwcm93YWR6acSHIHRlc3QgV0FMREEuIFBhbWnEmXRhaiwgxbxlIHRlc3QgV0FMREEgbcOzd2ksIMW8ZSBiaW9yxIVjIHBvZA0KdXdhZ8SZIG5pZW9ncmFuaWN6b25lIG9zemFjb3dhbmlhIG1vZGVsdSwgcHJ6ZXRlc3R1amVteSBoaXBvdGV6xJkgemVyb3fEhQ0KbcOzd2nEhWPEhSwgxbxlIHdzcMOzxYJjenlubmlraSBzcGXFgm5pYWrEhSBwZXduZSBsaW5pb3dlIG9ncmFuaWN6ZW5pYS4NCg0KQWJ5IGrEhSBwcnpldGVzdG93YcSHLCB1xbx5amVteSBvYmlla3R1IHp3csOzY29uZWdvIHogdXJ1Y2hvbWllbmlhICoqKnJxKioqDQp6IHLDs8W8bnltaSBsaWN6YmFtaSBrd2FudHlsaSBpIHVzdGF3aW15IG9wY2rEmSAqKipqb2ludCoqKiBuYSB0cnVlIGx1Yg0KZmFsc2UuIEdkeSAqKipqb2ludCoqKiBqZXN0IHRydWU6ICJyw7N3bm/Fm8SHIHdzcMOzxYJjenlubmlrw7N3IGtpZXJ1bmtvd3ljaA0KcG93aW5uYSBiecSHIHd5a29uYW5hIGpha28gd3Nww7NsbmUgdGVzdHkgbmEgd3N6eXN0a2ljaCBwYXJhbWV0cmFjaA0KbmFjaHlsZW5pYSIsIGdkeSAqKipqb2ludCoqKiBqZXN0IGZhbHNlOiAibmFsZcW8eSB6Z8WCYXN6YcSHIG9kZHppZWxuZQ0KdGVzdHkgbmEga2HFvGR5bSB6IHBhcmFtZXRyw7N3IG5hY2h5bGVuaWEiLg0KDQpaYXV3YcW8LCDFvGUgdGVzdHkga3dhbnR5bG93ZSBzxIUgdGVzdGFtaSAibGluaWkgcsOzd25vbGVnxYJlaiIuIE96bmFjemEgdG8sDQrFvGUgcG93aW5uacWbbXkgd3lqxIXEhyByw7PFvG5lIHgtd3lyYXp5X3dvbG5lIGRsYSBrYcW8ZGVnbyBrd2FudHlsYSwgcG9uaWV3YcW8DQpyZXByZXplbnR1asSFIG9uZSBwb3ppb215IHJvemvFgmFkw7N3IHdhcnVua293eWNoLiBKZcWbbGkgamVkbmFrDQp3c3DDs8WCY3p5bm5pa2kga3dhbnR5bGkgZGxhIHdzcMOzxYJjenlubmlrb3cgc8SFIHRha2llIHNhbWUsIHRvIG5pZSBtYQ0KZWZla3TDs3cgc3BlY3lmaWN6bnljaCBkbGEga3dhbnR5bGksIHd5c3RhcmN6xIUgZWZla3R5IMWbcmVkbmllLg0KDQoqKkJhZGFuaWUgc3RhdHlzdHljem5laiByw7PFvG5pY3kgbWnEmWR6eSAyNS4gaSA1MC4ga3dhbnR5bGVtIHdhcnVua293eW06KioNCg0KQmlvcsSFYyBwb2QgdXdhZ8SZIHBvd3nFvHN6ZSBvc3phY293YW5pYSBrd2FudHlsaSwgcsOzxbxuaWNhIG1pxJlkenkNCmt3YW50eWxhbWkgMCwyNSBpIDAsNTAgaXN0bmllamUsIGFsZSBjenkgc8SFIG9uZSB3eXN0YXJjemFqxIVjbyBkdcW8ZSwgYWJ5DQpiecSHIHN0YXR5c3R5Y3puaWUgcsOzxbxuZT8gSmFrYSBqZXN0IHdhcnRvxZvEhyBwPyBQcnplZ2zEhWRhasSFYyBwb25pxbxzemUNCnd5bmlraSwgbmllIHPEhSBvbmUgc3RhdHlzdHljem5pZSByw7PFvG5lIQ0KDQpQbyBwaWVyd3N6ZSwgam9pbnQgPSBUUlVFLiBUbyBuaWUgamVzdCB0ZXN0b3dhbmllLCBjenkgd3Nww7PFgmN6eW5uaWsgbmENCmRpc3AgamVzdCB0YWtpIHNhbSBqYWsgd3Nww7PFgmN6eW5uaWsgbmEgaHAuIFRvIGplc3Qgd3Nww7NsbmUgdGVzdG93YW5pZSwNCmN6eSB3c3DDs8WCY3p5bm5pa2kgZGxhIHLDs8W8bnljaCBrd2FudHlsaSBkaXNwIGkgcsOzxbxueWNoIGt3YW50eWxpIGhwIHPEhQ0KdGFraWUgc2FtZSBkbGEga2HFvGRlaiB6bWllbm5lai4NCg0KYGBge3J9DQprd2FudHlsZSA8LSBjKDAuMjUsIDAuNTApDQpyZWdfa3dhbnR5bG93YSA8LSBycShtcGcgfiBkaXNwICsgaHAgKyBmYWN0b3IoYW0pLHRhdSA9IGt3YW50eWxlLCBkYXRhID0gbXRjYXJzKQ0KYW5vdmEocmVnX2t3YW50eWxvd2EsIHRlc3QgPSAiV2FsZCIsIGpvaW50PVRSVUUpDQpgYGANCg0KUG8gZHJ1Z2llLCBqb2ludCA9IEZhbHNlOg0KDQpgYGB7cn0NCmFub3ZhKHJlZ19rd2FudHlsb3dhLCB0ZXN0ID0gIldhbGQiLCBqb2ludD1GQUxTRSkNCmBgYA0KDQoqKkJhZGFuaWUgc3RhdHlzdHljem5laiByw7PFvG5pY3kgbWnEmWR6eSAyNSwgNTAgaSA3NSBrd2FudHlsZW0NCndhcnVua293eW06KioNCg0KUGllcndzenkga3dhcnR5bCBpIG1lZGlhbmEgbmllIHd5ZGFqxIUgc2nEmSBiecSHIHN0YXR5c3R5Y3puaWUgcsOzxbxuZSwgdGVyYXoNCmRvxYLEhWN6eW15IHRyemVjaSBrd2FydHlsLiBKYWsgd2lkYcSHIHdjemXFm25pZWosIGt3YXJ0eWxlIHdzcMOzbG5pZQ0Kd3lrYXp1asSFIGdyYWRpZW50LiBUZXJheiBtb8W8ZW15IHpvYmFjennEhywgxbxlICoqZGlzcCoqLCAqKmhwKiogaSAqKmFtKioNCnPEhSBvZGR6aWVsbmllIHN0YXR5c3R5Y3puaWUgcsOzxbxuZS4NCg0KUG8gcGllcndzemUsIGpvaW50ID0gVFJVRToNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmt3YW50eWxlIDwtIGMoMC4yNSwgMC41MCwgMC43NSkNCg0KcmVnX2t3YW50eWxvd2EgPC0gcnEobXBnIH4gZGlzcCArIGhwICsgZmFjdG9yKGFtKSx0YXUgPSBrd2FudHlsZSwgZGF0YSA9IG10Y2FycykNCg0KYW5vdmEocmVnX2t3YW50eWxvd2EsIHRlc3QgPSAiV2FsZCIsIGpvaW50PVRSVUUpDQpgYGANCg0KUG8gZHJ1Z2llLCBqb2ludCA9IEZhbHNlOg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KYW5vdmEocmVnX2t3YW50eWxvd2EsIHRlc3QgPSAiV2FsZCIsIGpvaW50PUZBTFNFKQ0KYGBgDQoNCiMjIyBEb2Jyb8SHIGRvcGFzb3dhbmlhDQoNCk1vxbxlbXkgb2JsaWN6ecSHIHdzcMOzxYJjenlubmlraSBkb2Jyb2NpIGRvcGFzb3dhbmlhIHJlZ3Jlc2ppIGt3YW50eWxvd2VqIHoNCnd5a29yenlzdGFuaWVtIHJlc3p0IGkgcmVzenQgYmV6d2FydW5rb3d5Y2g6DQoNCmBgYCByDQpnb29kZml0KHJlc2lkLCByZXNpZF9ubCwgdGF1KQ0KYGBgDQoNCk1pYXJhIGRvYnJvY2kgZG9wYXNvd2FuaWEgZGxhIHJlZ3Jlc2ppIGt3YW50eWxvd2VqIGplc3Qgc3phY293YW5hIGpha28gMQ0KbWludXMgc3Rvc3VuZWsgc3VteSBvZGNoeWxlxYQgYmV6d3pnbMSZZG55Y2ggdyBtb2RlbGFjaCB3IHBlxYJuaQ0Kc3BhcmFtZXRyeXpvd2FueWNoIGRvIHN1bXkgb2RjaHlsZcWEIGJlend6Z2zEmWRueWNoIHcgemVyb3d5bQ0KKGJlendhcnVua293eW0pIG1vZGVsdSBrd2FudHlsb3d5bS4NCg0KV2FydG/Fm2NpIHRlIHPEhSBwcnp5ZGF0bmUgZG8gcG9yw7N3bmHFhCBtacSZZHp5IG1vZGVsYW1pIGt3YW50eWxvd3ltaSwgYWxlDQpuaWUgc8SFIHBvcsOzd255d2FsbmUgemUgc3RhbmRhcmRvd3ltaSB3c3DDs8WCY3p5bm5pa2FtaSBkZXRlcm1pbmFjamkuIFRlDQpvc3RhdG5pZSBvcGFydGUgc8SFIG5hIHdhcmlhbmNqaSBvZGNoeWxlxYQga3dhZHJhdG93eWNoLCBuYXRvbWlhc3QNCndhcnRvxZtjaSBkb2Jyb2NpIGRvcGFzb3dhbmlhIGRsYSByZWdyZXNqaSBrd2FudHlsb3dlaiBvcGFydGUgc8SFIG5hDQpvZGNoeWxlbmlhY2ggYmV6d3pnbMSZZG55Y2guIFdhcnRvxZtjaSBkb2Jyb2NpIGRvcGFzb3dhbmlhIHphd3N6ZSBixJlkxIUNCm1uaWVqc3plIG5pxbwgd2FydG/Fm2NpIFJeMl4uDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIyBtb2RlbCBrd2FudHlsb3d5DQptb2RlbDEgPC0gcnEobXBnIH4gZGlzcCArIGhwICsgZmFjdG9yKGFtKSx0YXUgPSAwLjUsIGRhdGEgPSBtdGNhcnMpDQpyZXN6dHkxIDwtIHJlc2lkKG1vZGVsMSkNCg0KIyMgYmV6d2FydW5rb3d5IChwdXN0eSkgbW9kZWwga3dhbnR5bG93eQ0KbW9kZWwyIDwtIHJxKG1wZyB+IDEsIHRhdSA9IDAuNSxkYXRhPW10Y2FycykNCnJlc3p0eTIgPC0gcmVzaWQobW9kZWwyKQ0KDQpnb29kZml0KHJlc3p0eTEsIHJlc3p0eTIsIDAuNSkNCg0KIyMgcjIgbW9kZWx1IEtNTksgZGxhIHBvcsOzd25hbmlhDQptb2RlbF9sbSA8LSBsbShtcGcgfiBkaXNwICsgaHAgKyBmYWN0b3IoYW0pLCBkYXRhID0gbXRjYXJzKQ0KDQpzdW1tYXJ5KG1vZGVsX2xtKSRyLnNxdWFyZWQNCmBgYA0KDQojIyBaYWRhbmllDQoNClRlcmF6IFdhc3phIGtvbGVqIDstKQ0KDQpXYXN6eW0gemFkYW5pZW0gZHppc2lhaiBqZXN0IHphbW9kZWxvd2FuaWUgLSBwb3LDs3duYW5pZSBLTU5LIG9yYXoNCnJlZ3Jlc2ppIGt3YW50eWxvd2VqIChyw7PFvG5vLXBvemlvbW93ZWopIGRsYSB6bWllbm5laiAiZWFybmluZ3MiIC0NCnd5bmFncm9kemVuaWEuDQoNCkRvYmllcnogaSBwcnpldGVzdHVqIHByZWR5a3RvcnksIGt3YW50eWxlIGRsYSBtb2RlbGkuIFd5a29uYWogdGVzdHkNCnLDs8W8bmljIHdzcMOzxYJjenlubmlrb3cgZGxhIGZpbmFsbnljaCBtb2RlbGkuDQoNClcgcHJ6eXBhZGt1IHByb2JsZW3Ds3cgLSBvYmVqcnp5aiB2aWRlbyB0dXRvcmlhbCAod8WCxIVjeiBwb2xza2llIG5hcGlzeSkNCm9yYXogd2VqZMW6IG5hIGplZ28gc3Ryb27EmSB6ZSDFunLDs2TFgmFtaS4gTW/FvGVzeiByw7N3bmllxbwgd3lrb3J6eXN0YcSHIHcvdw0KcHJ6eWvFgmFkeS4NCg0KYGBge3J9DQpkYXRhKCJDUFNTVzkyOTgiKQ0KZGFuZSA9IENQU1NXOTI5OA0KYGBgDQoNCmBgYHtyfQ0KZGFuZTkyIDwtIGZpbHRlcihkYW5lLCB5ZWFyID09IDE5OTIpDQpkYW5lOTggPC0gZmlsdGVyKGRhbmUsIHllYXIgPT0gMTk5OCkNCmBgYA0KDQoxLiBNb2RlbCBLTU5LDQoNCmBgYHtyfQ0KbG1fbW9kZWw5MiA8LSBsbShlYXJuaW5ncyB+IGRlZ3JlZSArIGdlbmRlciArIGFnZSwgZGF0YSA9IGRhbmU5MikNCnN1bW1hcnkobG1fbW9kZWw5MikNCmBgYA0KUi1rd2FkcmF0IGRsYSBtb2RlbHUgS05NSyB3eW5vc2kgb2tvxYJvIDAsMiwgY28gb3puYWN6YSwgxbxlIHR5bGtvIDIwJSB6bWllbm5vxZtjaSB3IGRhbnljaCBqZXN0IHd5amHFm25pb25lIHByemV6IG1vZGVsLiBUYWtpIHd5bmlrIHN1Z2VydWplLCDFvGUgbW9kZWwgbWEgb2dyYW5pY3pvbsSFIHpkb2xub8WbxIcgZG8gd3lqYcWbbmlhbmlhIHJvemvFgmFkdSB6bWllbm55Y2ggemFsZcW8bnljaCBpIHBvem9zdGFqZSBkdcW8YSBjesSZxZvEhyB6bWllbm5vxZtjaSwga3TDs3JhIG5pZSBqZXN0IHVqxJl0YSB3IGFuYWxpemllLg0KDQoyLiBSZWdyZXNqZSBrd2FudHlsb3dlIGRsYSB0YXUgPSAwLjI1LCAwLjUwLCAwLjc1DQoNCmBgYHtyfQ0Ka3dhbnR5bGUgPC0gYygwLjI1LCAwLjUwLCAwLjc1KQ0KcmVnX2t3YW50eWxvd2FfOTIgPC0gcnEoZWFybmluZ3MgfiBkZWdyZWUgKyBnZW5kZXIgKyBhZ2UsIHRhdSA9IGt3YW50eWxlLCBkYXRhID0gZGFuZTkyKQ0Kc3VtbWFyeShyZWdfa3dhbnR5bG93YV85Miwgc2UgPSAiYm9vdCIpDQpgYGANCg0KYGBge3J9DQprd2FudHlsZSA8LSBjKDAuMjUsIDAuNTApDQpyZWdfa3dhbnR5bG93YSA8LSBycShlYXJuaW5ncyB+IGRlZ3JlZSArIGdlbmRlciArIGFnZSwgdGF1ID0ga3dhbnR5bGUsIGRhdGEgPSBkYW5lOTIpDQphbm92YShyZWdfa3dhbnR5bG93YSwgdGVzdCA9ICJXYWxkIiwgam9pbnQ9VFJVRSkNCmBgYA0KV3luaWtpIGFuYWxpenkgd3NrYXp1asSFLCDFvGUgem1pZW5uZSB0YWtpZSBqYWsgd3lrc3p0YcWCY2VuaWUsIHDFgmXEhyBpIHdpZWsgbWFqxIUgaXN0b3RueSB3cMWCeXcgbmEgZG9jaG9keSwgc3pjemVnw7NsbmllIHcgcsOzxbxueWNoIGt3YW50eWxhY2ggZG9jaG9kw7N3LCB0YWtpY2ggamFrIDAuMjUgaSAwLjUuIE96bmFjemEgdG8sIMW8ZSB0ZSBjenlubmlraSB3eXdpZXJhasSFIHLDs8W8bnkgd3DFgnl3IG5hIGRvY2hvZHkgdyB6YWxlxbxub8WbY2kgb2QgcG96aW9tdSBkb2Nob2R1LCBjbyBzdWdlcnVqZSwgxbxlIGVmZWt0IHR5Y2ggem1pZW5ueWNoIG1vxbxlIHNpxJkgem1pZW5pYcSHIHcgcsOzxbxueWNoIGN6xJnFm2NpYWNoIHJvemvFgmFkdSBkb2Nob2TDs3cuIFBvbmFkdG8sIHdhcnRvxZvEhyBwIHV6eXNrYW5hIHcgYmFkYW5pdSBqZXN0IGJhcmR6byBtYcWCYSwgY28gcG96d2FsYSBuYSBvZHJ6dWNlbmllIGhpcG90ZXp5IHplcm93ZWogbyBicmFrdSByw7PFvG5pYyB3IG5hY2h5bGVuaWFjaCBtacSZZHp5IGt3YW50eWxhbWkuIFcgcmV6dWx0YWNpZSwgbW/FvGVteSB1em5hxIcsIMW8ZSBpc3RuaWVqZSBzdGF0eXN0eWN6bmllIGlzdG90bmEgcsOzxbxuaWNhIHcgc3Bvc29iaWUsIHcgamFraSBtb2RlbCB6YWNob3d1amUgc2nEmSB3IHLDs8W8bnljaCBrd2FudHlsYWNoLCBjbyBvem5hY3phLCDFvGUgem1pZW5uZSB0ZSBtYWrEhSB6csOzxbxuaWNvd2FueSB3cMWCeXcgbmEgZG9jaG9keSB3IHLDs8W8bnljaCBjesSZxZtjaWFjaCByb3prxYJhZHUuDQoNCmBgYHtyfQ0KYW5vdmEocmVnX2t3YW50eWxvd2EsIHRlc3QgPSAiV2FsZCIsIGpvaW50PUZBTFNFKQ0KYGBgDQpUZSB6bWllbm5lIG1hasSFIGlzdG90bnkgd3DFgnl3IG5hIGRvY2hvZHkgdyByw7PFvG55Y2ggY3rEmcWbY2lhY2ggcm96a8WCYWR1LCBjbyBzdWdlcnVqZSwgxbxlIHdwxYJ5dyB3eWtzenRhxYJjZW5pYSwgcMWCY2kgaSB3aWVrdSBuYSBkb2Nob2R5IG1vxbxlIHLDs8W8bmnEhyBzacSZIHcgemFsZcW8bm/Fm2NpIG9kIHRlZ28sIGN6eSBhbmFsaXp1amVteSBuacW8c3plLCBjenkgd3nFvHN6ZSBrd2FudHlsZSBkb2Nob2TDs3cuIFcgcHJha3R5Y2Ugb3puYWN6YSB0bywgxbxlIHRlIGN6eW5uaWtpIG1vZ8SFIG9kZHppYcWCeXdhxIcgbmEgb3NvYnkgeiBuacW8c3p5bWkgZG9jaG9kYW1pIHcgaW5ueSBzcG9zw7NiIG5pxbwgbmEgb3NvYnkgeiB3ecW8c3p5bWkgZG9jaG9kYW1pLiBUYWtpZSByw7PFvG5pY2UgdyB3cMWCeXdpZSBtb2fEhSB3eW5pa2HEhyB6IHRlZ28sIMW8ZSBuYSByw7PFvG55Y2ggcG96aW9tYWNoIGRvY2hvZMOzdyByw7PFvG5lIHptaWVubmUgbW9nxIUgb2Rncnl3YcSHIG9kbWllbm7EhSByb2zEmSB3IGtzenRhxYJ0b3dhbml1IHd5bmFncm9kemXFhC4gTmEgcHJ6eWvFgmFkLCB3eWtzenRhxYJjZW5pZSBtb8W8ZSBtaWXEhyB3acSZa3N6eSB3cMWCeXcgbmEgb3NvYnkgdyBuacW8c3p5Y2gga3dhbnR5bGFjaCBkb2Nob2TDs3csIHBvZGN6YXMgZ2R5IGlubmUgY3p5bm5pa2ksIHRha2llIGphayBkb8Wbd2lhZGN6ZW5pZSB6YXdvZG93ZSBjenkgc2llxIcga29udGFrdMOzdywgbW9nxIUgYnnEhyBiYXJkemllaiB6bmFjesSFY2UgZGxhIG9zw7NiIHcgd3nFvHN6eWNoIGt3YW50eWxhY2guIFRha2llIHLDs8W8bmljZSB3c2thenVqxIUsIMW8ZSBwb2RlasWbY2llIGRvIGFuYWxpenkgZG9jaG9kw7N3IHBvd2lubm8gdXd6Z2zEmWRuaWHEhyBuaWUgdHlsa28gb2fDs2xueSB3cMWCeXcgem1pZW5ueWNoLCBhbGUgdGFrxbxlIGljaCB6csOzxbxuaWNvd2FuZSBlZmVrdHkgdyB6YWxlxbxub8WbY2kgb2QgcG96aW9tdSBkb2Nob2R1Lg0KDQpgYGB7cn0NCmt3YW50eWxlIDwtIGMoMC4yNSwgMC41MCwgMC43NSkNCg0KcmVnX2t3YW50eWxvd2EgPC0gcnEoZWFybmluZ3MgfiBkZWdyZWUgKyBnZW5kZXIgKyBhZ2UsIHRhdSA9IGt3YW50eWxlLCBkYXRhID0gZGFuZTkyKQ0KDQphbm92YShyZWdfa3dhbnR5bG93YSwgdGVzdCA9ICJXYWxkIiwgam9pbnQ9VFJVRSkNCmBgYA0KVGFrIGphayB3Y3plc25pZWogdGFremUgaSBwcnp5IHV3emdsxJlkbmllbml1IGt3YW50eWx1IDAuNzUgd3N6eXN0a2llIHptaWVubmUgb2themHFgnkgc2nEmSBiecSHIGlzdG90bmUgc3RhdHlzdHljem5lLg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KYW5vdmEocmVnX2t3YW50eWxvd2EsIHRlc3QgPSAiV2FsZCIsIGpvaW50PUZBTFNFKQ0KYGBgDQpXeW5pa2kgdGUgc8SFIHLDs3duaWXFvCBwb2RvYm5lIGRvIHR5Y2ggdXp5c2thbnljaCBwcnp5IGFuYWxpemllIGt3YW50eWxpLCB3IGt0w7NyZWogbmllIHV3emdsxJlkbmlvbm8gd2FydG/Fm2NpIDAuNzUuIE96bmFjemEgdG8sIMW8ZSB3cMWCeXcgem1pZW5ueWNoIHRha2ljaCBqYWsgd3lrc3p0YcWCY2VuaWUsIHDFgmXEhyBpIHdpZWsgbmEgZG9jaG9keSBwb3pvc3RhamUgemFzYWRuaWN6byBzcMOzam55LCBuaWV6YWxlxbxuaWUgb2QgdGVnbywgY3p5IGFuYWxpenVqZW15IHR5bGtvIGt3YW50eWxlIDAuMjUgaSAwLjUsIGN6eSByw7N3bmllxbwgZG9kYWplbXkgMC43NS4gQ2hvxIcgdXd6Z2zEmWRuaWVuaWUgZG9kYXRrb3dlZ28ga3dhbnR5bGEgbW9nxYJvYnkgcG90ZW5jamFsbmllIHdwxYJ5bsSFxIcgbmEgd3luaWtpLCBvYnNlcndvd2FuZSB6bWlhbnkgdyBkb2Nob2RhY2ggdyBuacW8c3p5Y2ggaSDFm3JlZG5pY2gga3dhbnR5bGFjaCB3c2thenVqxIUgbmEgcG9kb2JuZSB6YWxlxbxub8WbY2ksIGNvIHN1Z2VydWplLCDFvGUgZ8WCw7N3bmUgZWZla3R5IHptaWVubnljaCBwb3pvc3RhasSFIHN0YWJpbG5lLg0KDQpgYGB7cn0NCiMjIG1vZGVsIGt3YW50eWxvd3kgZGxhIDAuMjUNCm1vZGVsMSA8LSBycShlYXJuaW5ncyB+IGRlZ3JlZSArIGdlbmRlciArIGFnZSwgdGF1ID0gMC4yNSwgZGF0YSA9IGRhbmU5MikNCnJlc3p0eTEgPC0gcmVzaWQobW9kZWwxKQ0KDQojIyBiZXp3YXJ1bmtvd3kgKHB1c3R5KSBtb2RlbCBrd2FudHlsb3d5DQptb2RlbDIgPC0gcnEoZWFybmluZ3MgfiAxLCB0YXUgPSAwLjI1LGRhdGE9ZGFuZTkyKQ0KcmVzenR5MiA8LSByZXNpZChtb2RlbDIpDQoNCmdvb2RmaXQocmVzenR5MSwgcmVzenR5MiwgMC4yNSkNCg0KIyMgbW9kZWwga3dhbnR5bG93eSBkbGEgMC41DQptb2RlbDEgPC0gcnEoZWFybmluZ3MgfiBkZWdyZWUgKyBnZW5kZXIgKyBhZ2UsIHRhdSA9IDAuNSwgZGF0YSA9IGRhbmU5MikNCnJlc3p0eTEgPC0gcmVzaWQobW9kZWwxKQ0KDQojIyBiZXp3YXJ1bmtvd3kgKHB1c3R5KSBtb2RlbCBrd2FudHlsb3d5DQptb2RlbDIgPC0gcnEoZWFybmluZ3MgfiAxLCB0YXUgPSAwLjUsZGF0YT1kYW5lOTIpDQpyZXN6dHkyIDwtIHJlc2lkKG1vZGVsMikNCg0KZ29vZGZpdChyZXN6dHkxLCByZXN6dHkyLCAwLjUpDQoNCiMjIG1vZGVsIGt3YW50eWxvd3kgMC43NQ0KbW9kZWwxIDwtIHJxKGVhcm5pbmdzIH4gZGVncmVlICsgZ2VuZGVyICsgYWdlLCB0YXUgPSAwLjc1LCBkYXRhID0gZGFuZTkyKQ0KcmVzenR5MSA8LSByZXNpZChtb2RlbDEpDQoNCiMjIGJlendhcnVua293eSAocHVzdHkpIG1vZGVsIGt3YW50eWxvd3kNCm1vZGVsMiA8LSBycShlYXJuaW5ncyB+IDEsIHRhdSA9IDAuNzUsZGF0YT1kYW5lOTIpDQpyZXN6dHkyIDwtIHJlc2lkKG1vZGVsMikNCg0KZ29vZGZpdChyZXN6dHkxLCByZXN6dHkyLCAwLjc1KQ0KYGBgDQoNCldhcnRvxZtjaSB3IHpha3Jlc2llIG9kIDAuMDggZG8gMC4xNCB3c2thenVqxIUsIMW8ZSBtb2RlbCBrd2FudHlsb3d5IHJ6ZWN6eXdpxZtjaWUgd3Byb3dhZHphIHBld27EhSBwb3ByYXfEmSB3IHN0b3N1bmt1IGRvIG1vZGVsdSBwdXN0ZWdvLCBqZWRuYWsgdGEgem1pYW5hIG5pZSBqZXN0IHpuYWN6xIVjYS4gVGFraWUgd2FydG/Fm2NpIHN1Z2VydWrEhSwgxbxlIHdwxYJ5dyB6bWllbm55Y2ggbmEgZG9jaG9keSB3IGFuYWxpem93YW55Y2gga3dhbnR5bGFjaCBuaWUgamVzdCBiYXJkem8gc2lsbnksIGEgcsOzxbxuaWNhIHcgZG9wYXNvd2FuaXUgbW9kZWxpIG5pZSBqZXN0IG9ncm9tbmEuIFcgc3pjemVnw7Nsbm/Fm2NpLCBnZHlieSB3YXJ0b8WbY2kgbWlhcnkgZG9wYXNvd2FuaWEgYnnFgnkgYmxpc2tpZSB6ZXJ1LCBvem5hY3phxYJvYnkgdG8sIMW8ZSB6bWllbm5lIG1pYcWCeWJ5IGJhcmR6byBzaWxueSB3cMWCeXcgbmEgZG9jaG9keSB3IGRhbnltIGt3YW50eWx1Lg0KDQpCaW9yxIVjIHBvZCB1d2FnxJkgbWlhcsSZIGRvcGFzb3dhbmlhLCBtb2RlbCBrd2FudHlsb3d5IGRsYSB0YXUgPSAwLjI1IHd5ZGFqZSBzacSZIGJ5xIcgbmFqYmFyZHppZWogb2Rwb3dpZWRuaSwgcG9uaWV3YcW8IG9mZXJ1amUgbmFqbGVwc3plIGRvcGFzb3dhbmllIGRvIGRhbnljaCB3IHR5bSBrd2FudHlsdS4gT3puYWN6YSB0bywgxbxlIHptaWVubmUgdGFraWUgamFrIHd5a3N6dGHFgmNlbmllLCBwxYJlxIcgaSB3aWVrIG1hasSFIG5hanNpbG5pZWpzenkgd3DFgnl3IG5hIGRvY2hvZHkgdyB0eW0gd8WCYcWbbmllIHByemVkemlhbGUgZG9jaG9kw7N3IHcgcG9yw7N3bmFuaXUgZG8gaW5ueWNoIG1vZGVsaSwgY28gc3VnZXJ1amUsIMW8ZSB3IHR5bSB6YWtyZXNpZSB6bWllbm5lIHRlIG9kZ3J5d2FqxIUga2x1Y3pvd8SFIHJvbMSZIHcga3N6dGHFgnRvd2FuaXUgd3luYWdyb2R6ZcWELiBDaG/EhyB6bWlhbmEgdyBkb3Bhc293YW5pdSBuaWUgamVzdCBkcmFzdHljem5hLCBtb2RlbCBrd2FudHlsb3d5IGRsYSB0YXUgPSAwLjI1IHd5ZGFqZSBzacSZIGxlcGllaiBvZGRhd2HEhyByemVjenl3aXN0eSByb3prxYJhZCBkb2Nob2TDs3cgdyB0eW0ga29ua3JldG55bSBrd2FudHlsdS4NCg==