Email             :
RPubs            : https://rpubs.com/aliciaarifin/
Jurusan          : Statistika
Address         : ARA Center, Matana University Tower
                         Jl. CBD Barat Kav, RT.1, Curug Sangereng, Kelapa Dua, Tangerang, Banten 15810.


1 Nomor 1

  1. Buatkan Rangkuman Materi Kuliah Pert-1-15

1.1 Jawaban

1.1.1 Probability Distribution

Probability Distribution adalah distribusi yang menggambarkan pola distribusi. Probabilty distribution memiliki banyak macam, setiap distribusi memiliki fungsi masing-masing dan ciri khas.

1.1.1.1 Binomial

Binomial distribution adalah distribusi yang menggunakan bilangan diskrit. Peluang ini hanya memiliki 2 output yaitu “Sukses” dan “Gagal”. Binomial distribution bisa dilakukan lebih dari 1x. Binomial ini mirip dengan distribusi Bernoulli, yang membedakan adalah distribusi bernoulli hanya bisa dilakukan 1x, sedangkan Binomial bisa dilakukan terus hingga jumlah yang diperlukan (n).
Rumus dari Distribusi Binomial adalah
Contoh kasus yang menggunakan binomial distribution adalah flip coin atau lempar koin, seperti “Berapa peluang dari 3”angka” dari 70 kali pelemparan koin?”
dalam R Binomial Distribusion bisa menggunakan code dbinom() untuk dan pbinom()

1.1.1.2 Poisson

Poisson Distribution adalah probability distribution yang menggunakan bilangan diskrit. Poisson distribution biasa disebut distribusi pelayanan. pada distribusi ini terdapat simbol baru yaitu lambda \(\lambda\), yang memiliki arti rata-rata dari jumlah event/ acara. Dengan \(x\) adalah nilai yang diketahui agar dicari probabilitasnya.
Rumus : Contoh kasus :
Jika diketahui seorang pemain NBA memiliki shooting average 46%, berapa probabilitas jika \(X\) = 250 dan \(n\) = 700?

1.1.1.3 Continuous Uniform

Uniform distribution adalah distribusi peluang yang outcome atau peluangnya hampir sama. Uniform = seragam, jadi sama semua. Yang membedakan dari distribusi yang lain adalah dengan memiliki interval antara \(a\) dan \(b\), yang density function (peluang untuk bilangan kontinu) adalah

Contoh : kasus” yang memilih suatu yang tidak memiliki bias, semua anggota memiliki kesempatan yang sama.

1.1.1.4 Exponential

Distribusi ini merupakan distribusi yang membentuk eksponensial. \(\mu\) adalah dengan rumus: di R kode yang bisa digunakan utnuk membuat sample distribusi ini menggunakan rexp(), gambaran grafik exponential seperti di bawah ini.

1.1.1.5 Normal

Distribusi Normal memiliki peluang (probability density function) yang \(\mu\) adalah rata” populasi, dan \(\sigma^2\) merupakan varians

1.1.1.6 chisquared

jika X1,X2,x3,…,Xn adalah n independen random variabel yang memiliki standar distribusi normal, Lalu memiliki chi-square distribution dengan n degree of freedom. rata-rata / meannya n, dan variansnya 2n.
\(V=X_1^2 +X_2^2 +...+X_n^2\)
nanti di materi goodness of fit akan lebih dalam bahasnya.

1.1.1.7 student-t

Asumsikan random variabel Z berdistribusi normal, dan random V mempunyai chi-squared distribution dengan m degree of freedom. Asumsikan Z dan V adalah independen, maka rumusnya adalah
t = Z / sqrt(V/m) ~ \(t_m\)

1.1.1.8 F

JIka V1 dan V2 adalah 2 variabel random yang memiliki distribusi chisquare dengan degree of freedom m1 dan m2, maka akan menggunakan F distribution yang m1=pembilang dof, dan m2=penyebut dof.
F = (V1/m1)/(V2/m2) ~ \(F_{m1,m2}\)

1.1.2 confidence Intervals

Confidence interval dalam bahasa Indonesia adalah selang kepercayaan. Apa itu selang kepercayaan? Selang kepercayaan dipakai untuk mencari kira-kira ada di bagian mana estimasi dari data yang kita dapat. Estimasi yang dimaksud di sini bukan angka eksak seperti rata-rata, melainkan rentang atau interval. Selang kepercayaan juga punya tingkat eror yang berbeda-beda yang disesuaikan dengan situasi, biasanya secara umum menggunakan tingkat error 5% atau \(\alpha = 5%\).
cara mencari selang kepercayaan ini bisa dicari melalui 2 cara, yaitu jika diketahui rata-rata populasi (Z-Test) dan jika tidak diketahui rata-rata populasi (t-test).
JIka rata-rata populasi diketahui, kita akan menggunakan Z-test dari Z a/2, dengan rumus
xbar +- Z a/2 . (sigma /sqrt(n))


JIka rata-rata populasi tidak diketahui, kita akan menggunakan t-test dari t a/2, dengan rumus
xbar +- t a/2 .( s /sqrt(n))

1.1.3 Hypothesis Testing

Dalam melakukan analisis data, kita pastinya akan menggunakan hipotesis untuk menguji asumsi-asumsi yang ada. Hipotesis bisa diterima atau ditolak.


Ada 3 tipe tes hipotesis, Left-tailed, right-tailed, dan two-tailed. * Left-tailed + Ketika asumsinya percaya bahwa miu < miu0 (H1) + Tolak H0 jika Z atau t hitung < -t atau Z alpha

  • right-tailed
    • Ketika asumsinya percaya bahwa miu > miu0 (H1)
    • Tolak H0 jika Z atau t hitung > t atau Z alpha
  • two-tailed
    • Ketika asumsinya percaya bahwa miu tidak sama dengan miu0(H1)
    • Tolak H0 jika Z atau t hitung < -t atau Z alpha/2 , atau Z atau t hitung > t atau Z alpha/2.
  • Note :
    • miu = rata-rata populasi
    • miu0 = rata-rata asumsi
    • Ztest dilakukan jika n >30, dan t-test n<30
    • Rumus :
      • One-tailed z = (xbar - mu0)/(sigma/sqrt(n)) (sigma known)
        t = (xbar - mu0)/(sigma/sqrt(n)) (sigma unknown)
      • Two-tailed mu0 = mu, cara menghitung z dan t sama seperti one tailed, tetapi bedanya di t/z alpha/2. kalau one tailed t alpha.

Tipe error dalam ini juga terdapat 2 error, yaitu error tipe 1 dan error tipe 2. Error type 1 (false positive) dan Type 2 (false Negative). Probabilitas type 1 error disebut siknifikansi level (\(\alpha\)), dan probabilitas type 2 error adalah \(\beta\).

1.1.4 A/B Testing

AB testing adalah ketika kita menggunakan satu sample yang dipecah menjadi 2 untuk mencari yang mana yang lebih efektif. Proporsi pecahan samplenya bisa bervariasi, 50-50 70-30, atau pecahan lainnya. Pecahahan ini disesuaikan dengan tujuan statistik yang ingin dicapai. AB testing ini dicoba untuk mengetahui apakah adanya perbedaan jika dilakukan perlakuan yang berbeda. Independent t-test merupakan salah satu contoh AB testing. AB testing ini digunakan untuk mencari varian mana yang lebih efektif. AB testing ini bisa dilakukan dengan bivariat ataupun multivariat.
Jika ingin melakukan AB testing, dipastikan bahwa data/sample yang sudah bisa langsung diolah. Jika terdapat masalah pada data, bisa dilakukan AA testing terlebih dahulu untuk memaksimalkan test.
AA testing adalah test statistik yang digunakan untuk membandingan antara 2 populasi yang berbeda dengan uji perlakuan yang sama. AA testing ini disebut dengan paired t-test.

1.1.5 Goodness of Fit

Test yang digunakan jika sample data dari beberapa populasi (distribusi normal atau dengan distribusi Weibull). Test ini melihat apakah sample yang digunakan sudah merepresentasi data asli (populasi). Test yang biasa digunakan adalah chi-squere, kolmogorov smirnov, anderson darling, dan shapiro wilk. Untuk kali ini kita akan fokus di Chi-squere test.
Chisquere (\(X^2\)) test adalah hipotesis test untuk proporsi dari satu atau lebih multinominal variabel kategori. Chisquere goodness of fit ini juga biasa disebut non-parametic test, yang berarti test ini tidak mengestimasi parameter populasi.
Lalu ada juga Independence Chi-squere test, Homogenity Chi-Squere, dan Multinomial Goodness of fit
Untuk hipotesis, jika p-value < daripada alpha, maka H0 ditolak. H0= bisa berupa independen atau berdistribusi normal, disesuaikan dengan test yang digunakan.

1.1.6 Regression

Regresi adalah salah satu metode untuk memprediksi.
Regresi membutuhkan asumsi-asumsi yang perlu dilakukan sebelum melanjutkan regresi : * Linearitas, apakah linear atau tidak, jika tidak linear maka buat non-linear * Auto korelasi, apakah nilai sebelumnya mempengaruhi atau tidak * Homogenitas, apakah variansnya sama? Jika varians tidak konstan, regresi tidak akurat. * Multikolinearitas, apakah sesama variabel dependen memiliki hubungan? Jika terdapat hubungan maka akan mempengaruhi output regresi atau hasil implementasi regresi.

1.1.6.1 Simple linear

Simple Linear regression adalah regresi yang variabel dependen dan variabel independennya numerik. Simple linear regression adalah regresi yang variabel dependen dan variabel independennya masing-masing 1.

1.1.6.2 multiple linear

regresi yang mana variabel independen dan variabel dependennya numerik. Regresi ini variabel independennya 1, dan variabel dependennya lebih dari 1 (>1).

1.1.6.2.1 implementasi hasil simple & multiple linear regression
  • P-value model = pvalue <alpha, model siknifikan terhadap Y
  • R-Squere, R-squre ini mengartikan bahwa …% variabel yang sudah masuk ke dalam model. Bisa dibilang R-squere adalah seberapa berguna variabel bisa memprediksi.
    • R-squere semakin tinggi semakin bagus, biasanya >80% sudah oke
    • Rsquere dibagi menjadi 2 yaitu multiple dan adjusted
      • Multiple : multiple regression
      • Adjusted : single regression
    • Faktor pengaruh
      • Koefisien +, berdampak +
      • Koefisien -, berdampak -
  • JIka p-value dan R-squere berbanding terbalik dalam memilih model, maka acuan yang akan kita dahulukan adalah R-squere, selama p-value < alpha.

1.1.6.3 Regresi bertahap

Regresi ini adalah regresi yang tidak memerlukan tes autokorelasi, homogenitas, dan multikolinearitas. Tetapi untuk regresi ini hanya bagus digunakan jika data yang kita punya linear. Regresi ini menggunakan parameter AIC, model yang terbaik adalah model yang memiliki AIC paling besar. AIC adalah Akaike Information Criterion. Sayangnya regresi ini memiliki kelemahan, yaitu nge-run nya lama alias lemot, dan tidak bisa digunakan dengan non-linear. Karena metode ini akan mencari semua kemungkinan model yang ada, laptop / PC yang digunakan bisa lebih lambat dari biasanya (saat nge-run coding saja).

1.1.6.4 logistic regression

Logistic regression adalah regresi yang outputnya numerik dan inputnya merupakan variabel kategorik atau numerik. Jadi logistic regression adalah regresi yang variabel dependennya campur (kategorikal dan numerik). Regresi ini memiliki n output, sesuai dengan berapa jenis kategori. Logistic regression ini akan membentuk n hasil regresi dalam suatu data, jadi nanti akan terbentuk n garis pada scatter plot atau visualisasinya.
Contohnya jika dalam suatu regresi tingkat kesehatan gigi dan mulut, variabelnya adalah nilai dmft, umur, sehari gosok gigi berapa kali, dan perokok. Maka outputnya akan memiliki Yperokok dan Y bukan perokok.

1.1.6.5 ANOVA

Anova (analisis of variance) adalah test regresi yang digunakan untuk membandingkan. Anova jarang digunakan untuk memprediksi. Anova memiliki input kategorik, dan output numerik. Ingat bahwa Anova memiliki 1 output. Anova ini gunanya untuk melihat apakah terdapat hubungan antar kelompok. ANOVA merupakan salah satu metode AB testing. Anova juga bisa dibilang seperti hipotesis.
Contohnya jika terdapat 2 kelompok yang memiliki mean dan n orang yang sama. Apakah kedua kelompok tersebut sama? Jawabannya tidak sama, walaupun rata-ratanya sama, varians nya tetap saja berbeda. Kita akan menggunakan ANOVA untuk mencari apakah ada perbedaan yang siknifikan atau tidak antara 2 kelompok tersebut.
Asumsi ANOVA ada 4 yaitu + independence, pastikan variabel dependennya tidak memempengaruhi variabel lainnya. + no significant outlier, tidak memiliki pencilan + normalitas, harus normal, jika tidak gunakan test non-parametrik + homogenitas, varians harus konstan

Jika salah satu asumsi tidak terpenuhi gunakan non-parametrik test (saran :kruskal wallis test)
Anova dibagi menjadi 3 yaitu one-way, two-way, dan multi-way. Anova oneway adalah extention of independent sample untuk lebih dari 2 grup yang hanya membandingkan 1 faktor, two-way = membandingkan 2 faktor, multiway = membandingkan lebih dari 2 faktor. Faktor yang dimaksud disini adalah variabel dependennya.

ANOVA memiliki hipotesis : + Hipotesis 0 : \(\mu_a =\mu_b = \mu_c =...=\mu_n =\) + HIpotesis \(\alpha\) =\(\mu_a \ne \mu_b \ne \mu_c \ne...\ne \mu_n =\) + Reject H0 jika p-value \(\le \alpha\) dan Accept H0 jika p-value > \(\alpha\), JIka H0 ditolak makan terdapat perbedaan. Perbedaan tersebut kita tidak tahu yang mana yang berbeda, bisa jadi hanya satu yang beda, atau semua berbeda. maka dari itu kita bisa gunakan uji lanjut menggunakan Uji Parsial atau sapiro test (sapiro()) , uji tukey ,dan levine’s test (untuk mencek data homogen atau tidak).

1.1.6.6 MANOVA

MANOVA (multivariate analysis of variance) adalah anova yang memiliki lebih dari 1 outcome.MAnova lebih mengarah ke experimental dan berfokus pada variabel dependen.

Uji asumsi anova : + variabel dependennya berdistribusi normal (mshapiro.test() dalam package mvnormtest) + homogenitas varians antar priktor + linearitas antar semua variabel dependen, semua covariat, dan semua variabel dependen-kovariat.

2 Nomor 2

  1. Buatlah contoh penyelesaian Hipotesis Testing dengan menggunakan R!
    Penjual kwetiaw goreng mengatakan bahwa sebungkus porsi beratnya 250 gram. Setelah kwetiawnya dibeli 60 porsi untuk sample, didapatkan hasil rata per-porsi 235 gram, dan standar deviasinya 35 gram. Apakah kita bisa menerima klaim penjual kwetiaw tersebut?
    \(H_0\) = \(\mu_0 = \mu\) = klaim diterima
    \(H_1\) = \(\mu_0 \ne \mu\) = klaim ditolak
# two-way dengan standar deviasi populasi tidak diketahui
miu0 = 250
xbar = 235
s = 35
n = 60
alpha =  0.05

t = (xbar-miu0)/(s/sqrt(n)) ; t
## [1] -3.3197
t.tab = qt(1-alpha/2,df = n-1)
c(-t.tab, t.tab)
## [1] -2.000995  2.000995
pval = 2*pt(t, df = n-1);pval
## [1] 0.001548771

Karena t berada di daerah penolakan (t hitung < t tab, dan pval <0,05), H0 ditolak. Maka bisa dikatakan klaim penjual tersebut bisa kita tolak.

3 Nomor 3

  1. Buatlah contoh penyelesaian ANOVA dengan menggunakan R!
    ## contoh 1 Terdapat data kesehatan gigi dan mulut :
  • karies : ada atau tidak adanya karies
  • JK : jenis kelamin
  • total : jumlah pengetahuan yang benar
library(readxl)
data.anova = read_excel('data.anova.xlsx')

# munculkan data agar tidak terlalu banyak munculnya
head(data.anova)
## # A tibble: 6 × 6
##      no karies    JK        total Kelas    Umur
##   <dbl> <chr>     <chr>     <dbl> <chr>   <dbl>
## 1     1 Ada       Laki-laki     7 Kelas 6    11
## 2     2 Ada       Laki-laki     8 Kelas 6    12
## 3     3 Ada       Laki-laki     8 Kelas 6    11
## 4     4 Ada       Perempuan     7 Kelas 6    11
## 5     5 Tidak Ada Perempuan     8 Kelas 6    11
## 6     6 Tidak Ada Perempuan     8 Kelas 6    11
library(dplyr)
## 
## 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(rstatix)
## 
## Attaching package: 'rstatix'
## The following object is masked from 'package:stats':
## 
##     filter
library(tidyr)
library(ggplot2)


data.anova %>%
  sample_n_by(karies, Kelas) 
## # A tibble: 12 × 6
##       no karies    JK        total Kelas    Umur
##    <dbl> <chr>     <chr>     <dbl> <chr>   <dbl>
##  1   148 Ada       Laki-laki     9 Kelas 1     7
##  2    48 Ada       Perempuan     8 Kelas 2     8
##  3   113 Ada       Laki-laki     9 Kelas 3    10
##  4   106 Ada       Perempuan    10 Kelas 4     9
##  5    17 Ada       Perempuan     8 Kelas 5    10
##  6     4 Ada       Perempuan     7 Kelas 6    11
##  7   151 Tidak Ada Perempuan     7 Kelas 1     6
##  8   133 Tidak Ada Laki-laki     6 Kelas 2     8
##  9   119 Tidak Ada Laki-laki     8 Kelas 3     8
## 10    23 Tidak Ada Perempuan     7 Kelas 4    10
## 11    85 Tidak Ada Perempuan    10 Kelas 5    10
## 12    72 Tidak Ada Laki-laki     6 Kelas 6    11
# cari summarynya
data.anova %>%
  group_by(karies, JK)%>%
  get_summary_stats(total, type = "mean_sd")
## # A tibble: 4 × 6
##   karies    JK        variable     n  mean    sd
##   <chr>     <chr>     <fct>    <dbl> <dbl> <dbl>
## 1 Ada       Laki-laki total       63  7.62 1.60 
## 2 Ada       Perempuan total       56  7.86 1.57 
## 3 Tidak Ada Laki-laki total       16  7.25 1.06 
## 4 Tidak Ada Perempuan total       18  7.94 0.998
# cek asumsi outlier yang ekstrim
ggplot(data.anova, aes(x = karies, y = total, fill = JK)) +
    geom_boxplot() +
    geom_jitter(shape = 15,
        color = "steelblue",
        position = position_jitter(0.21)) +
   theme_minimal()

data.anova %>%
  group_by(karies, JK)%>%
  identify_outliers(total)
## [1] karies     JK         no         total      Kelas      Umur       is.outlier
## [8] is.extreme
## <0 rows> (or 0-length row.names)

Karena pas dilihat tidak ada outlier dan

anova.interaksi   = aov(total ~ JK * karies, data = data.anova)
anova.tambahan    = aov(total ~ karies + JK, data = data.anova)
anova.karies      = aov(total ~ karies, data = data.anova)
anova.JK = aov(total ~ JK, data = data.anova)
anova.nol         = aov(total ~ 1, data = data.anova)
summary(anova.interaksi)
##              Df Sum Sq Mean Sq F value Pr(>F)
## JK            1    4.3   4.264   1.939  0.166
## karies        1    0.5   0.470   0.214  0.645
## JK:karies     1    1.4   1.372   0.624  0.431
## Residuals   149  327.7   2.199
summary(anova.tambahan)
##              Df Sum Sq Mean Sq F value Pr(>F)
## karies        1    0.3   0.340   0.155  0.694
## JK            1    4.4   4.394   2.003  0.159
## Residuals   150  329.0   2.194
summary(anova.karies)
##              Df Sum Sq Mean Sq F value Pr(>F)
## karies        1    0.3  0.3403   0.154  0.695
## Residuals   151  333.4  2.2081
summary(anova.JK)
##              Df Sum Sq Mean Sq F value Pr(>F)
## JK            1    4.3   4.264   1.954  0.164
## Residuals   151  329.5   2.182
summary(anova.nol)
##              Df Sum Sq Mean Sq F value Pr(>F)
## Residuals   152  333.8   2.196

Dengan menggunakan siknifikansi level \(\alpha = 5%\), kita bisa mengetahui bahwa H0 diterima. kedua variabel tersebut tidak memiliki hubungan yang siknifikan dengan jumlah total pengetahuan.

3.1 contoh 2

Kita akan melihat pada 50 data pemain NBA draft 2001-2015, pada draft ini kita akan membandingkan Pakah ada hubungan Posisi setiap pemain dan tahun di-draft terhadap nilai SPM. NIlai SPM adalah nilai statistik +/-.
sumber : https://github.com/fivethirtyeight/data/tree/master/nba-draft-2015

data2 = read.csv("historical_projections.csv")

head(data2)
##               Player Position                 ID Draft.Year Projected.SPM
## 1 Karl-Anthony Towns        C karl-anthony-towns       2015     1.0306057
## 2    Justise Winslow       SF    justise-winslow       2015     0.8753290
## 3    Stanley Johnson       SF    stanley-johnson       2015     0.6794933
## 4      Jahlil Okafor        C      jahlil-okafor       2015     0.5216613
## 5   D`Angelo Russell       PG   d-angelo-russell       2015     0.5119667
## 6     Dakari Johnson        C     dakari-johnson       2015     0.4917874
##    Superstar   Starter Role.Player      Bust
## 1 0.13476667 0.4271833  0.16308333 0.2749667
## 2 0.08352857 0.5109048  0.17676667 0.2288000
## 3 0.06780000 0.4237333  0.27850000 0.2299667
## 4 0.05871667 0.4099000  0.23553333 0.2958500
## 5 0.15203333 0.3422833  0.09658333 0.4091000
## 6 0.02134078 0.3675436  0.41757200 0.1935437

menggunakan data ini, kita akan memilih data POsition, DraftYear, dan Projected.SPM.
sebelum itu kita akan membuat hipotesis
\(\H_0\) = tidak memiliki perbedaan varians antara dua variabel (position dan draft year)
\(\H_1\) = terdapat perbedaan varians antara dua variabel (position dan draft year)

data2 %>%
  group_by(Position, Draft.Year)%>%
  get_summary_stats(Projected.SPM, type = "mean_sd")
## # A tibble: 75 × 6
##    Position Draft.Year variable          n   mean    sd
##    <chr>         <int> <fct>         <dbl>  <dbl> <dbl>
##  1 C              2001 Projected.SPM    11 -0.875 0.535
##  2 C              2002 Projected.SPM     9 -0.757 0.492
##  3 C              2003 Projected.SPM     4 -0.915 0.921
##  4 C              2004 Projected.SPM     7 -1.22  0.182
##  5 C              2005 Projected.SPM     6 -0.722 0.679
##  6 C              2006 Projected.SPM     9 -1.03  0.413
##  7 C              2007 Projected.SPM    10 -0.836 0.726
##  8 C              2008 Projected.SPM    14 -0.729 0.591
##  9 C              2009 Projected.SPM     6 -0.98  0.515
## 10 C              2010 Projected.SPM    13 -0.886 0.574
## # ℹ 65 more rows
# mengindentifikasi outlier dan menghilangkan outlier
hai = data2 %>%
  group_by(Position, Draft.Year)%>%
  identify_outliers(Projected.SPM) 
outlier = c(hai$ID)
data2_new  = data2[! data2$ID %in% outlier,]

Karena banyak outlier yang extrim, maka pemain” tersebut harus dikeluarkan.

int = aov(Projected.SPM~ Position*Draft.Year, data = data2_new)
add = aov(Projected.SPM~ Position+Draft.Year, data = data2_new)
pos = aov(Projected.SPM~ Position, data = data2_new)
year = aov(Projected.SPM~ Draft.Year, data = data2_new)
nba_null = aov(Projected.SPM~ 1, data = data2_new)
summary(int )
##                      Df Sum Sq Mean Sq F value   Pr(>F)    
## Position              4   3.11   0.778   3.825   0.0043 ** 
## Draft.Year            1   6.12   6.116  30.076 5.27e-08 ***
## Position:Draft.Year   4   0.56   0.141   0.692   0.5975    
## Residuals           996 202.54   0.203                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
summary(add )
##               Df Sum Sq Mean Sq F value   Pr(>F)    
## Position       4   3.11   0.778    3.83  0.00427 ** 
## Draft.Year     1   6.12   6.116   30.11 5.17e-08 ***
## Residuals   1000 203.10   0.203                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
summary(pos )
##               Df Sum Sq Mean Sq F value  Pr(>F)   
## Position       4   3.11  0.7779   3.722 0.00515 **
## Residuals   1001 209.22  0.2090                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
summary(year)
##               Df Sum Sq Mean Sq F value  Pr(>F)    
## Draft.Year     1   5.99   5.994   29.16 8.3e-08 ***
## Residuals   1004 206.33   0.206                    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
summary(nba_null)
##               Df Sum Sq Mean Sq F value Pr(>F)
## Residuals   1005  212.3  0.2113

Didapat dari hasil di atas bahwa semua tes yang kita gunakan semuanya berbeda siknifikan kecuali inteaksi. Bisa dibilang Draft.Year dan Position mementukan nilai Projected SPM. Karena p-value kurang dari \(\alpha = 0.05\), maka H0 ditolak, atau terdapat perbedaan yang siknifikan antara draft.year dan position.
lalu kita akan melihat lagi untuk mengetes Type 2 yaitu false negative.

aov_test_int <- data2_new %>% 
  anova_test(Projected.SPM~ Position+Draft.Year)
aov_test_int
## ANOVA Table (type II tests)
## 
##       Effect DFn  DFd      F        p p<.05   ges
## 1   Position   4 1000  3.981 3.00e-03     * 0.016
## 2 Draft.Year   1 1000 30.113 5.17e-08     * 0.029
aov_test_int <- data2_new %>% 
  anova_test(Projected.SPM~ Position)
aov_test_int
## ANOVA Table (type II tests)
## 
##     Effect DFn  DFd     F     p p<.05   ges
## 1 Position   4 1001 3.722 0.005     * 0.015
aov_test_int <- data2_new %>% 
  anova_test(Projected.SPM~ Draft.Year)
aov_test_int
## ANOVA Table (type II tests)
## 
##       Effect DFn  DFd      F       p p<.05   ges
## 1 Draft.Year   1 1004 29.165 8.3e-08     * 0.028

yang di dapat dari hasil tes type 2 adalah secara statistik berdapat perbedaan yang siknifikan antara tambahin, dan yang cek mandiri.

3.1.1 cek Asumsi

plot(add,1) # homogenitas

plot(add,2) # normalitas

data2_new %>%
  group_by(Position, Draft.Year)%>%
  shapiro_test(Projected.SPM)
## # A tibble: 75 × 5
##    Position Draft.Year variable      statistic      p
##    <chr>         <int> <chr>             <dbl>  <dbl>
##  1 C              2001 Projected.SPM     0.903 0.203 
##  2 C              2002 Projected.SPM     0.865 0.107 
##  3 C              2003 Projected.SPM     0.841 0.197 
##  4 C              2004 Projected.SPM     0.963 0.844 
##  5 C              2005 Projected.SPM     0.918 0.491 
##  6 C              2006 Projected.SPM     0.889 0.227 
##  7 C              2007 Projected.SPM     0.798 0.0195
##  8 C              2008 Projected.SPM     0.865 0.0353
##  9 C              2009 Projected.SPM     0.856 0.216 
## 10 C              2010 Projected.SPM     0.888 0.0927
## # ℹ 65 more rows
oneway.test(Projected.SPM~ Position+Draft.Year,data=data2_new) # no assumption of equal variances
## 
##  One-way analysis of means (not assuming equal variances)
## 
## data:  Projected.SPM and Position + Draft.Year
## F = 3.1081, num df = 74.0, denom df = 263.3, p-value = 1.203e-11

dari hasil di atas, didapatkan p-value > 0,05. Artinya tidak ada bukti bahwa varians merupakan siknifikan scara statistik. Datanya homogen, normal, dan varians konstan.

3.1.2 cek perbedaan

library(emmeans)

cek =data2_new %>% 
  group_by(Position) %>%
  emmeans_test(Projected.SPM ~Draft.Year, p.adjust.method = "bonferroni") 
summary(cek)
##  Position     term               .y.               group1         
##  C :105   Length:525         Length:525         Length:525        
##  PF:105   Class :character   Class :character   Class :character  
##  PG:105   Mode  :character   Mode  :character   Mode  :character  
##  SF:105                                                           
##  SG:105                                                           
##                                                                   
##     group2                df        statistic             p          
##  Length:525         Min.   :931   Min.   :-5.5582   Min.   :0.00000  
##  Class :character   1st Qu.:931   1st Qu.:-1.4149   1st Qu.:0.08867  
##  Mode  :character   Median :931   Median :-0.4861   Median :0.35401  
##                     Mean   :931   Mean   :-0.5433   Mean   :0.38453  
##                     3rd Qu.:931   3rd Qu.: 0.4688   3rd Qu.:0.63275  
##                     Max.   :931   Max.   : 3.7850   Max.   :0.99866  
##      p.adj           p.adj.signif      
##  Min.   :0.0000037   Length:525        
##  1st Qu.:1.0000000   Class :character  
##  Median :1.0000000   Mode  :character  
##  Mean   :0.9244778                     
##  3rd Qu.:1.0000000                     
##  Max.   :1.0000000
cek[cek$p.adj <0.05,]
## # A tibble: 21 × 10
##    Position term       .y.         group1 group2    df statistic       p   p.adj
##    <fct>    <chr>      <chr>       <chr>  <chr>  <dbl>     <dbl>   <dbl>   <dbl>
##  1 C        Draft.Year Projected.… 2001   2015     931     -4.30 1.92e-5 2.01e-3
##  2 C        Draft.Year Projected.… 2002   2015     931     -3.58 3.61e-4 3.79e-2
##  3 C        Draft.Year Projected.… 2004   2015     931     -5.36 1.04e-7 1.09e-5
##  4 C        Draft.Year Projected.… 2006   2015     931     -5.27 1.70e-7 1.79e-5
##  5 C        Draft.Year Projected.… 2007   2015     931     -4.78 1.99e-6 2.09e-4
##  6 C        Draft.Year Projected.… 2008   2015     931     -3.76 1.81e-4 1.90e-2
##  7 C        Draft.Year Projected.… 2009   2015     931     -4.70 3.05e-6 3.21e-4
##  8 C        Draft.Year Projected.… 2010   2015     931     -4.49 8.18e-6 8.59e-4
##  9 C        Draft.Year Projected.… 2012   2015     931     -5.56 3.56e-8 3.74e-6
## 10 C        Draft.Year Projected.… 2014   2015     931     -4.42 1.08e-5 1.14e-3
## # ℹ 11 more rows
## # ℹ 1 more variable: p.adj.signif <chr>

dari semua data perbedaan (525 data), yang berpengaruh siknifikan terdapat 21 jenis, yaitu seperti hasil di atas. Cara bacanya adalah posisi … memiliki perbedaan yang siknifikan/sangat siknifikan antara draft tahun … dan …

4 Nomor 4

  1. Buatlah contoh penyelesaian MANOVA dengan menggunakan R! Pada data di bawah ini kita akan mengetahui apakah adanya perbedaan yang siknifikan antara Kinerja dan IQ antara angkatan.
data.manova <- data.frame(
  Angkatan = rep(c("2018", "2019", "2020"), 10),
  IQ = c(112, 116, 120, 129, 126, 141, 97, 103, 107, 125,
         113, 119, 124, 132, 131, 146, 99, 105, 111, 121,
         118, 127, 132, 138, 137, 153, 104, 109, 117, 126),
  Kinerja = c(61, 67, 73, 81, 77, 93, 56, 62, 67, 77,
              68, 74, 79, 87, 84, 99, 62, 67, 72, 82,
              71, 76, 82, 92, 88, 103, 68, 73, 79, 89)
)

4.1 cek asumsi

data.manova%>% # cek sample size
  group_by(Angkatan)%>%
  summarise(N = n())
## # A tibble: 3 × 2
##   Angkatan     N
##   <chr>    <int>
## 1 2018        10
## 2 2019        10
## 3 2020        10

Samplenya sudah oke, n setiap angkatan kebih dari 4.

# identifikasi univariat outliers, ada outlier tetapi tidak ekrim, jadi oke saja dimasukkan
data.manova%>% 
  group_by(Angkatan)%>%
  identify_outliers(IQ)
## [1] Angkatan   IQ         Kinerja    is.outlier is.extreme
## <0 rows> (or 0-length row.names)
data.manova%>% ## tidak ada outlier
  group_by(Angkatan)%>%
  identify_outliers(Kinerja)
## # A tibble: 2 × 5
##   Angkatan    IQ Kinerja is.outlier is.extreme
##   <chr>    <dbl>   <dbl> <lgl>      <lgl>     
## 1 2018        97      56 TRUE       FALSE     
## 2 2018       146      99 TRUE       FALSE
# deteksi outlier multivariat tidak perlu lagi karena pada univariat tidak terdapat outlier

# cek normalitas univariat
data.manova%>% 
  group_by(Angkatan)%>%
  shapiro_test(IQ, Kinerja)%>%
  arrange(variable)
## # A tibble: 6 × 4
##   Angkatan variable statistic      p
##   <chr>    <chr>        <dbl>  <dbl>
## 1 2018     IQ           0.975 0.933 
## 2 2019     IQ           0.959 0.780 
## 3 2020     IQ           0.933 0.473 
## 4 2018     Kinerja      0.968 0.875 
## 5 2019     Kinerja      0.925 0.401 
## 6 2020     Kinerja      0.849 0.0566

Dari hasil test sapiro di atas didapat semua variabel, p > 0.05, maka datanya berdistribusi normal

# identify multikolinearity
data.manova %>%
  cor_test(IQ, Kinerja)
## # A tibble: 1 × 8
##   var1  var2      cor statistic        p conf.low conf.high method 
##   <chr> <chr>   <dbl>     <dbl>    <dbl>    <dbl>     <dbl> <chr>  
## 1 IQ    Kinerja  0.94      14.9 7.49e-15    0.882     0.973 Pearson

Dari hasil korelasi di atas didapatkan bahwa variabel dependen tidak berkorelasi dengan hasil p<0.05

# linear asumption
library(GGally)
## Registered S3 method overwritten by 'GGally':
##   method from   
##   +.gg   ggplot2
## 
## Attaching package: 'GGally'
## The following object is masked from 'package:emmeans':
## 
##     pigs
results <- data.manova %>%
  select(Kinerja, IQ, Angkatan) %>%
  group_by(Angkatan) %>%
  doo(~ggpairs(.) + theme_bw(), result = "plots")
results$plots
## [[1]]

## 
## [[2]]

## 
## [[3]]

Dari hasil grafik di atas, didapat bahwa datanya linear.

box_m(data.manova[, c("IQ", "Kinerja")], data.manova$Angkatan) # uji homogenitas kovarian (p-value>0.05, terdapat homogenitas kovarian)
## # A tibble: 1 × 4
##   statistic p.value parameter method                                            
##       <dbl>   <dbl>     <dbl> <chr>                                             
## 1     0.556   0.997         6 Box's M-test for Homogeneity of Covariance Matric…
data.manova%>% 
  gather(key = "variable", value = "value", IQ,Kinerja) %>%
  group_by(variable) %>%
  levene_test(value ~ Angkatan) # didapatkan hasil tidak homogen antar varians (p-value>0.05)
## Warning: There were 2 warnings in `mutate()`.
## The first warning was:
## ℹ In argument: `data = map(.data$data, .f, ...)`.
## Caused by warning in `leveneTest.default()`:
## ! group coerced to factor.
## ℹ Run `dplyr::last_dplyr_warnings()` to see the 1 remaining warning.
## # A tibble: 2 × 5
##   variable   df1   df2 statistic     p
##   <chr>    <int> <int>     <dbl> <dbl>
## 1 IQ           2    27    0.0532 0.948
## 2 Kinerja      2    27    0.0678 0.935

Hasil yang didapatkan bahwa data ini kovarian homogen dan tidak homogen antar varians. maka dari itu terdapat asumsi yang tidak terpenuhi. Oleh karena itu kita akan lanjut, tetapi perlu diingat bahwa hasil MANOVA ini akan tidak terlalu akurat.

model1<- manova(cbind(Kinerja, IQ) ~ Angkatan, data.manova)
summary(model1)
##           Df   Pillai approx F num Df den Df Pr(>F)
## Angkatan   2 0.057994  0.40315      4     54 0.8055
## Residuals 27
model2<- lm(cbind(Kinerja, IQ) ~ Angkatan, data.manova)
Manova(model2, test.statistic = "Pillai")
## 
## Type II MANOVA Tests: Pillai test statistic
##          Df test stat approx F num Df den Df Pr(>F)
## Angkatan  2  0.057994  0.40315      4     54 0.8055

Dari hasil codingan di atas, tidak terdapat perbedaan yang siknifikan antara kinerja dan IQ. P-value > 0,05, maka H0 diterima. kedua variabel tersebut juga tidak berbeda siknifikan antar angkatan. # Referensi

Referensi : + https://bookdown.org/BaktiSiregar/data-science-for-beginners-part-2/12-RM-ANOVA.html + https://www.statology.org/left-tailed-test-vs-right-tailed-test/#:~:text=There%20are%20three%20different%20types,hypothesis%20contains%20the%20“%3E”%20sign + https://www.scribbr.com/statistics/type-i-and-type-ii-errors/ + https://oeis.org/wiki/List_of_LaTeX_mathematical_symbols + https://stackoverflow.com/questions/13012509/how-to-delete-rows-from-a-data-frame-based-on-an-external-list-using-r#:~:text=You%20can%20use%20also%20use%20match%20if%20there,rows%20that%20exactly%20matches%20your%20NAMES_list%20with%20main_data%24NAMES. + https://github.com/fivethirtyeight/data + data manova: data dari forms psikologi yang menanyakan tentang cara belajar.

LS0tCnRpdGxlOiAiS29tcHV0YXNpIFN0YXRpc3Rpa2EiCnN1YnRpdGxlOiAiVWppYW4gQWtoaXIgU2VtZXN0ZXIgS29tcHV0YXNpIFN0YXRpc3Rpa2EiCmF1dGhvcjogIkFsaWNpYSBBcmlmaW4gKDIwMjE0OTIwMDAxKSIKZGF0ZTogImByIGZvcm1hdChTeXMuRGF0ZSgpLCAnJUIgJWQsICVZJylgIgpvdXRwdXQ6IAogIGh0bWxfZG9jdW1lbnQ6IAogICAgaHRtbF9kb2N1bWVudDogbnVsbAogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IHllcwogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMKICAgIGNvZGVfZG93bmxvYWQ6IHllcwogICAgdGhlbWU6IHNhbmRzdG9uZQogICAgY3NzOiBzdHlsZTEuY3NzCiAgICBoaWdobGlnaHQ6IG1vbm9jaHJvbWUKLS0tCgoKPGltZyBzdHlsZT0iZmxvYXQ6IHJpZ2h0OyBtYXJnaW46IDBweCAxMDBweCAwcHggMHB4OyB3aWR0aDoyNSUiIHNyYz0iZm90b2RpcmkucG5nIi8+IAoKYGBge3IgbG9nbywgZWNobz1GQUxTRSxmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aCA9ICczMCUnfQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygibG9nb21hdGFuYS5wbmciKQpgYGAKCkVtYWlsICZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyZuYnNwOzogIGFsaS4xOWFyaWZpbkBnbWFpbC5jb20gPGJyPgpSUHVicyAgJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7OiBodHRwczovL3JwdWJzLmNvbS9hbGljaWFhcmlmaW4vIDxicj4KSnVydXNhbiAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7OiBbU3RhdGlzdGlrYV0oaHR0cHM6Ly9tYXRhbmF1bml2ZXJzaXR5LmFjLmlkLz9seT1hY2FkZW1pYyZjPXNiKSA8YnI+CkFkZHJlc3MgICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyA6IEFSQSBDZW50ZXIsIE1hdGFuYSBVbml2ZXJzaXR5IFRvd2VyIDxicj4KJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsmbmJzcDsgSmwuIENCRCBCYXJhdCBLYXYsIFJULjEsIEN1cnVnIFNhbmdlcmVuZywgS2VsYXBhIER1YSwgVGFuZ2VyYW5nLCBCYW50ZW4gMTU4MTAuCgoqKioqCiMgTm9tb3IgMQoxLiBCdWF0a2FuIFJhbmdrdW1hbiBNYXRlcmkgS3VsaWFoIFBlcnQtMS0xNQoKIyMgSmF3YWJhbgoKIyMjIFByb2JhYmlsaXR5IERpc3RyaWJ1dGlvbgpQcm9iYWJpbGl0eSBEaXN0cmlidXRpb24gYWRhbGFoIGRpc3RyaWJ1c2kgeWFuZyBtZW5nZ2FtYmFya2FuIHBvbGEgZGlzdHJpYnVzaS4gUHJvYmFiaWx0eSBkaXN0cmlidXRpb24gbWVtaWxpa2kgYmFueWFrIG1hY2FtLCBzZXRpYXAgZGlzdHJpYnVzaSBtZW1pbGlraSBmdW5nc2kgbWFzaW5nLW1hc2luZyBkYW4gY2lyaSBraGFzLiAKCiMjIyMgQmlub21pYWwKQmlub21pYWwgZGlzdHJpYnV0aW9uIGFkYWxhaCBkaXN0cmlidXNpIHlhbmcgbWVuZ2d1bmFrYW4gYmlsYW5nYW4gZGlza3JpdC4gUGVsdWFuZyBpbmkgaGFueWEgbWVtaWxpa2kgMiBvdXRwdXQgeWFpdHUgIlN1a3NlcyIgZGFuICJHYWdhbCIuIEJpbm9taWFsIGRpc3RyaWJ1dGlvbiBiaXNhIGRpbGFrdWthbiBsZWJpaCBkYXJpIDF4LiBCaW5vbWlhbCBpbmkgbWlyaXAgZGVuZ2FuIGRpc3RyaWJ1c2kgQmVybm91bGxpLCB5YW5nIG1lbWJlZGFrYW4gYWRhbGFoIGRpc3RyaWJ1c2kgYmVybm91bGxpIGhhbnlhIGJpc2EgZGlsYWt1a2FuIDF4LCBzZWRhbmdrYW4gQmlub21pYWwgYmlzYSBkaWxha3VrYW4gdGVydXMgaGluZ2dhIGp1bWxhaCB5YW5nIGRpcGVybHVrYW4gKG4pLgo8YnI+ClJ1bXVzIGRhcmkgRGlzdHJpYnVzaSBCaW5vbWlhbCBhZGFsYWgKYGBge3IsIGVjaG89RkFMU0UsZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnMTAwJSd9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJiaW5vbS5wbmciKQpgYGAKPGJyPgpDb250b2gga2FzdXMgeWFuZyBtZW5nZ3VuYWthbiBiaW5vbWlhbCBkaXN0cmlidXRpb24gYWRhbGFoIGZsaXAgY29pbiBhdGF1IGxlbXBhciBrb2luLCBzZXBlcnRpICJCZXJhcGEgcGVsdWFuZyBkYXJpIDMgImFuZ2thIiBkYXJpIDcwIGthbGkgcGVsZW1wYXJhbiBrb2luPyIKPGJyPgpkYWxhbSBSIEJpbm9taWFsIERpc3RyaWJ1c2lvbiBiaXNhIG1lbmdndW5ha2FuIGNvZGUgYGRiaW5vbSgpYCB1bnR1ayBkYW4gYHBiaW5vbSgpYAoKCiMjIyMgUG9pc3NvbiAKUG9pc3NvbiBEaXN0cmlidXRpb24gYWRhbGFoIHByb2JhYmlsaXR5IGRpc3RyaWJ1dGlvbiB5YW5nIG1lbmdndW5ha2FuIGJpbGFuZ2FuIGRpc2tyaXQuIFBvaXNzb24gZGlzdHJpYnV0aW9uIGJpYXNhIGRpc2VidXQgZGlzdHJpYnVzaSBwZWxheWFuYW4uIHBhZGEgZGlzdHJpYnVzaSBpbmkgdGVyZGFwYXQgc2ltYm9sIGJhcnUgeWFpdHUgbGFtYmRhICRcbGFtYmRhJCwgeWFuZyBtZW1pbGlraSBhcnRpIHJhdGEtcmF0YSBkYXJpIGp1bWxhaCBldmVudC8gYWNhcmEuIERlbmdhbiAkeCQgYWRhbGFoIG5pbGFpIHlhbmcgZGlrZXRhaHVpIGFnYXIgZGljYXJpIHByb2JhYmlsaXRhc255YS4KPGJyPgpSdW11cyA6CmBgYHtyLCBlY2hvPUZBTFNFLGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoID0gJzEwMCUnfQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygicG9pc3Nvbi5wbmciKQpgYGAKQ29udG9oIGthc3VzIDoKPGJyPgpKaWthIGRpa2V0YWh1aSBzZW9yYW5nIHBlbWFpbiBOQkEgbWVtaWxpa2kgc2hvb3RpbmcgYXZlcmFnZSA0NiUsIGJlcmFwYSBwcm9iYWJpbGl0YXMgamlrYSAkWCQgPSAyNTAgZGFuICRuJCA9IDcwMD8KCgojIyMjIENvbnRpbnVvdXMgVW5pZm9ybSAKVW5pZm9ybSBkaXN0cmlidXRpb24gYWRhbGFoIGRpc3RyaWJ1c2kgcGVsdWFuZyB5YW5nIG91dGNvbWUgYXRhdSBwZWx1YW5nbnlhIGhhbXBpciBzYW1hLiBVbmlmb3JtID0gc2VyYWdhbSwgamFkaSBzYW1hIHNlbXVhLiBZYW5nIG1lbWJlZGFrYW4gZGFyaSBkaXN0cmlidXNpIHlhbmcgbGFpbiBhZGFsYWggZGVuZ2FuIG1lbWlsaWtpIGludGVydmFsIGFudGFyYSAkYSQgZGFuICRiJCwgeWFuZyBkZW5zaXR5IGZ1bmN0aW9uIChwZWx1YW5nIHVudHVrIGJpbGFuZ2FuIGtvbnRpbnUpIGFkYWxhaApgYGB7ciwgZWNobz1GQUxTRSxmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aCA9ICcxMDAlJ30Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoInVuaWZvcm0ucG5nIikKYGBgCgpDb250b2ggOiBrYXN1cyIgeWFuZyBtZW1pbGloIHN1YXR1IHlhbmcgdGlkYWsgbWVtaWxpa2kgYmlhcywgc2VtdWEgYW5nZ290YSBtZW1pbGlraSBrZXNlbXBhdGFuIHlhbmcgc2FtYS4KCgojIyMjIEV4cG9uZW50aWFsIApEaXN0cmlidXNpICBpbmkgbWVydXBha2FuIGRpc3RyaWJ1c2kgeWFuZyBtZW1iZW50dWsgZWtzcG9uZW5zaWFsLiAkXG11JCBhZGFsYWggIGRlbmdhbiBydW11czoKYGBge3IsIGVjaG89RkFMU0UsZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnMTAwJSd9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJleHAucG5nIikKYGBgCmRpIFIga29kZSB5YW5nIGJpc2EgZGlndW5ha2FuIHV0bnVrIG1lbWJ1YXQgc2FtcGxlIGRpc3RyaWJ1c2kgaW5pIG1lbmdndW5ha2FuIGByZXhwKClgLCBnYW1iYXJhbiBncmFmaWsgZXhwb25lbnRpYWwgc2VwZXJ0aSBkaSBiYXdhaCBpbmkuCmBgYHtyLCBlY2hvPUZBTFNFLGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoID0gJzEwMCUnfQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiZXhwLnBpYy5wbmciKQpgYGAKCgoKIyMjIyBOb3JtYWwKRGlzdHJpYnVzaSBOb3JtYWwgbWVtaWxpa2kgcGVsdWFuZyAocHJvYmFiaWxpdHkgZGVuc2l0eSBmdW5jdGlvbikgeWFuZyAkXG11JCBhZGFsYWggcmF0YSIgcG9wdWxhc2ksIGRhbiAkXHNpZ21hXjIkIG1lcnVwYWthbiB2YXJpYW5zCmBgYHtyLCBlY2hvPUZBTFNFLGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoID0gJzEwMCUnfQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygibm9ybWFsLnBuZyIpCmBgYAoKIyMjIyBjaGlzcXVhcmVkCmppa2EgWDEsWDIseDMsLi4uLFhuIGFkYWxhaCBuIGluZGVwZW5kZW4gcmFuZG9tIHZhcmlhYmVsIHlhbmcgbWVtaWxpa2kgc3RhbmRhciBkaXN0cmlidXNpIG5vcm1hbCwgTGFsdSBtZW1pbGlraSBjaGktc3F1YXJlIGRpc3RyaWJ1dGlvbiBkZW5nYW4gbiBkZWdyZWUgb2YgZnJlZWRvbS4gcmF0YS1yYXRhIC8gbWVhbm55YSBuLCBkYW4gdmFyaWFuc255YSAybi4KPGJyPgokVj1YXzFeMiArWF8yXjIgKy4uLitYX25eMiQKPGJyPgpuYW50aSBkaSBtYXRlcmkgZ29vZG5lc3Mgb2YgZml0IGFrYW4gbGViaWggZGFsYW0gYmFoYXNueWEuCgojIyMjIHN0dWRlbnQtdApBc3Vtc2lrYW4gcmFuZG9tIHZhcmlhYmVsIFogYmVyZGlzdHJpYnVzaSBub3JtYWwsIGRhbiByYW5kb20gViBtZW1wdW55YWkgY2hpLXNxdWFyZWQgZGlzdHJpYnV0aW9uIGRlbmdhbiBtIGRlZ3JlZSBvZiBmcmVlZG9tLiBBc3Vtc2lrYW4gWiBkYW4gViBhZGFsYWggaW5kZXBlbmRlbiwgbWFrYSBydW11c255YSBhZGFsYWgKPGJyPgp0ID0gWiAvIHNxcnQoVi9tKSB+ICR0X20kCgoKIyMjIyBGCkpJa2EgVjEgZGFuIFYyIGFkYWxhaCAyIHZhcmlhYmVsIHJhbmRvbSB5YW5nIG1lbWlsaWtpIGRpc3RyaWJ1c2kgY2hpc3F1YXJlIGRlbmdhbiBkZWdyZWUgb2YgZnJlZWRvbSBtMSBkYW4gbTIsIG1ha2EgYWthbiBtZW5nZ3VuYWthbiBGIGRpc3RyaWJ1dGlvbiB5YW5nIG0xPXBlbWJpbGFuZyBkb2YsIGRhbiBtMj1wZW55ZWJ1dCBkb2YuIAo8YnI+CkYgPSAoVjEvbTEpLyhWMi9tMikgfiAkRl97bTEsbTJ9JAoKCiMjIyBjb25maWRlbmNlIEludGVydmFscwpDb25maWRlbmNlIGludGVydmFsIGRhbGFtIGJhaGFzYSBJbmRvbmVzaWEgYWRhbGFoIHNlbGFuZyBrZXBlcmNheWFhbi4gQXBhIGl0dSBzZWxhbmcga2VwZXJjYXlhYW4/IFNlbGFuZyBrZXBlcmNheWFhbiBkaXBha2FpIHVudHVrIG1lbmNhcmkga2lyYS1raXJhIGFkYSBkaSBiYWdpYW4gbWFuYSBlc3RpbWFzaSBkYXJpIGRhdGEgeWFuZyBraXRhIGRhcGF0LiBFc3RpbWFzaSB5YW5nIGRpbWFrc3VkIGRpIHNpbmkgYnVrYW4gYW5na2EgZWtzYWsgc2VwZXJ0aSByYXRhLXJhdGEsIG1lbGFpbmthbiByZW50YW5nIGF0YXUgaW50ZXJ2YWwuIFNlbGFuZyBrZXBlcmNheWFhbiBqdWdhIHB1bnlhICB0aW5na2F0IGVyb3IgeWFuZyBiZXJiZWRhLWJlZGEgeWFuZyBkaXNlc3VhaWthbiBkZW5nYW4gc2l0dWFzaSwgYmlhc2FueWEgc2VjYXJhIHVtdW0gbWVuZ2d1bmFrYW4gdGluZ2thdCBlcnJvciA1JSBhdGF1ICRcYWxwaGEgPSA1JSQuIAo8YnI+CmNhcmEgbWVuY2FyaSBzZWxhbmcga2VwZXJjYXlhYW4gaW5pIGJpc2EgZGljYXJpIG1lbGFsdWkgMiBjYXJhLCB5YWl0dSBqaWthIGRpa2V0YWh1aSByYXRhLXJhdGEgcG9wdWxhc2kgKFotVGVzdCkgZGFuIGppa2EgdGlkYWsgZGlrZXRhaHVpIHJhdGEtcmF0YSBwb3B1bGFzaSAodC10ZXN0KS4KPGJyPgpKSWthIHJhdGEtcmF0YSBwb3B1bGFzaSBkaWtldGFodWksIGtpdGEgYWthbiBtZW5nZ3VuYWthbiBaLXRlc3QgZGFyaSBaIGEvMiwgZGVuZ2FuIHJ1bXVzCjxicj4KeGJhciArLSBaIGEvMiAuIChzaWdtYSAvc3FydChuKSkKCjxicj4KSklrYSByYXRhLXJhdGEgcG9wdWxhc2kgdGlkYWsgZGlrZXRhaHVpLCBraXRhIGFrYW4gbWVuZ2d1bmFrYW4gdC10ZXN0IGRhcmkgdCBhLzIsIGRlbmdhbiBydW11cyAKPGJyPgp4YmFyICstIHQgYS8yIC4oIHMgL3NxcnQobikpCgoKIyMjIEh5cG90aGVzaXMgVGVzdGluZwpEYWxhbSBtZWxha3VrYW4gYW5hbGlzaXMgZGF0YSwga2l0YSBwYXN0aW55YSBha2FuIG1lbmdndW5ha2FuIGhpcG90ZXNpcyB1bnR1ayBtZW5ndWppIGFzdW1zaS1hc3Vtc2kgeWFuZyBhZGEuIEhpcG90ZXNpcyBiaXNhIGRpdGVyaW1hIGF0YXUgZGl0b2xhay4gCgo8YnI+CkFkYSAzIHRpcGUgdGVzIGhpcG90ZXNpcywgTGVmdC10YWlsZWQsIHJpZ2h0LXRhaWxlZCwgZGFuIHR3by10YWlsZWQuCiogTGVmdC10YWlsZWQKICArIEtldGlrYSBhc3Vtc2lueWEgcGVyY2F5YSBiYWh3YSBtaXUgPCBtaXUwIChIMSkKICArIFRvbGFrIEgwIGppa2EgWiBhdGF1IHQgaGl0dW5nIDwgLXQgYXRhdSBaIGFscGhhCgoqIHJpZ2h0LXRhaWxlZAogICsgS2V0aWthIGFzdW1zaW55YSBwZXJjYXlhIGJhaHdhIG1pdSA+IG1pdTAgKEgxKQogICsgVG9sYWsgSDAgamlrYSBaIGF0YXUgdCBoaXR1bmcgPiB0IGF0YXUgWiBhbHBoYQoKKiB0d28tdGFpbGVkCiAgKyBLZXRpa2EgYXN1bXNpbnlhIHBlcmNheWEgYmFod2EgbWl1IHRpZGFrIHNhbWEgZGVuZ2FuIG1pdTAoSDEpIAogICsgVG9sYWsgSDAgamlrYSBaIGF0YXUgdCBoaXR1bmcgPCAtdCBhdGF1IFogYWxwaGEvMiAsIGF0YXUgWiBhdGF1IHQgaGl0dW5nID4gdCBhdGF1IFogYWxwaGEvMi4KCgoqIE5vdGUgOgogICsgbWl1ID0gcmF0YS1yYXRhIHBvcHVsYXNpCiAgKyBtaXUwID0gcmF0YS1yYXRhIGFzdW1zaQogICsgWnRlc3QgZGlsYWt1a2FuIGppa2EgbiA+MzAsIGRhbiB0LXRlc3QgbjwzMAogICsgUnVtdXMgOgogICAgLSBPbmUtdGFpbGVkCiAgICAgIHogPSAoeGJhciAtIG11MCkvKHNpZ21hL3NxcnQobikpIChzaWdtYSBrbm93bikKICAgICAgPGJyPgogICAgICB0ID0gKHhiYXIgLSBtdTApLyhzaWdtYS9zcXJ0KG4pKSAoc2lnbWEgdW5rbm93bikKICAgIC0gVHdvLXRhaWxlZAogICAgICBtdTAgPSBtdSwgY2FyYSBtZW5naGl0dW5nIHogZGFuIHQgc2FtYSBzZXBlcnRpIG9uZSB0YWlsZWQsIHRldGFwaSBiZWRhbnlhIGRpIHQveiBhbHBoYS8yLiBrYWxhdSBvbmUgdGFpbGVkIHQgYWxwaGEuCiAgICAgIAogICAgICAKClRpcGUgZXJyb3IgZGFsYW0gaW5pIGp1Z2EgdGVyZGFwYXQgMiBlcnJvciwgeWFpdHUgZXJyb3IgdGlwZSAxIGRhbiBlcnJvciB0aXBlIDIuIEVycm9yIHR5cGUgMSAoZmFsc2UgcG9zaXRpdmUpIGRhbiBUeXBlIDIgKGZhbHNlIE5lZ2F0aXZlKS4gUHJvYmFiaWxpdGFzIHR5cGUgMSBlcnJvciBkaXNlYnV0IHNpa25pZmlrYW5zaSBsZXZlbCAoJFxhbHBoYSQpLCBkYW4gcHJvYmFiaWxpdGFzIHR5cGUgMiBlcnJvciBhZGFsYWggJFxiZXRhJC4gCgoKIyMjIEEvQiBUZXN0aW5nCkFCIHRlc3RpbmcgYWRhbGFoIGtldGlrYSBraXRhIG1lbmdndW5ha2FuIHNhdHUgc2FtcGxlIHlhbmcgZGlwZWNhaCBtZW5qYWRpIDIgdW50dWsgbWVuY2FyaSB5YW5nIG1hbmEgeWFuZyBsZWJpaCBlZmVrdGlmLiBQcm9wb3JzaSBwZWNhaGFuIHNhbXBsZW55YSBiaXNhIGJlcnZhcmlhc2ksIDUwLTUwIDcwLTMwLCBhdGF1IHBlY2FoYW4gbGFpbm55YS4gUGVjYWhhaGFuIGluaSBkaXNlc3VhaWthbiBkZW5nYW4gdHVqdWFuIHN0YXRpc3RpayB5YW5nIGluZ2luIGRpY2FwYWkuIEFCIHRlc3RpbmcgaW5pIGRpY29iYSB1bnR1ayBtZW5nZXRhaHVpIGFwYWthaCBhZGFueWEgcGVyYmVkYWFuIGppa2EgZGlsYWt1a2FuIHBlcmxha3VhbiB5YW5nIGJlcmJlZGEuIEluZGVwZW5kZW50IHQtdGVzdCBtZXJ1cGFrYW4gc2FsYWggc2F0dSBjb250b2ggQUIgdGVzdGluZy4gQUIgdGVzdGluZyBpbmkgZGlndW5ha2FuIHVudHVrIG1lbmNhcmkgdmFyaWFuIG1hbmEgeWFuZyBsZWJpaCBlZmVrdGlmLiBBQiB0ZXN0aW5nIGluaSBiaXNhIGRpbGFrdWthbiBkZW5nYW4gYml2YXJpYXQgYXRhdXB1biBtdWx0aXZhcmlhdC4KPGJyPgpKaWthIGluZ2luIG1lbGFrdWthbiBBQiB0ZXN0aW5nLCBkaXBhc3Rpa2FuIGJhaHdhIGRhdGEvc2FtcGxlIHlhbmcgc3VkYWggYmlzYSBsYW5nc3VuZyBkaW9sYWguIEppa2EgdGVyZGFwYXQgbWFzYWxhaCBwYWRhIGRhdGEsIGJpc2EgZGlsYWt1a2FuIEFBIHRlc3RpbmcgdGVybGViaWggZGFodWx1IHVudHVrIG1lbWFrc2ltYWxrYW4gdGVzdC4KPGJyPgpBQSB0ZXN0aW5nIGFkYWxhaCB0ZXN0IHN0YXRpc3RpayB5YW5nIGRpZ3VuYWthbiB1bnR1ayBtZW1iYW5kaW5nYW4gYW50YXJhIDIgcG9wdWxhc2kgeWFuZyBiZXJiZWRhIGRlbmdhbiB1amkgcGVybGFrdWFuIHlhbmcgc2FtYS4gQUEgdGVzdGluZyBpbmkgZGlzZWJ1dCBkZW5nYW4gcGFpcmVkIHQtdGVzdC4KCiMjIyBHb29kbmVzcyBvZiBGaXQKClRlc3QgeWFuZyBkaWd1bmFrYW4gamlrYSBzYW1wbGUgZGF0YSBkYXJpIGJlYmVyYXBhIHBvcHVsYXNpIChkaXN0cmlidXNpIG5vcm1hbCBhdGF1IGRlbmdhbiBkaXN0cmlidXNpIFdlaWJ1bGwpLiBUZXN0IGluaSBtZWxpaGF0IGFwYWthaCBzYW1wbGUgeWFuZyBkaWd1bmFrYW4gc3VkYWggbWVyZXByZXNlbnRhc2kgZGF0YSBhc2xpIChwb3B1bGFzaSkuIFRlc3QgeWFuZyBiaWFzYSBkaWd1bmFrYW4gYWRhbGFoIGNoaS1zcXVlcmUsIGtvbG1vZ29yb3Ygc21pcm5vdiwgYW5kZXJzb24gZGFybGluZywgZGFuIHNoYXBpcm8gd2lsay4gVW50dWsga2FsaSBpbmkga2l0YSBha2FuIGZva3VzIGRpIENoaS1zcXVlcmUgdGVzdC4KPGJyPgpDaGlzcXVlcmUgKCRYXjIkKSB0ZXN0IGFkYWxhaCBoaXBvdGVzaXMgdGVzdCB1bnR1ayBwcm9wb3JzaSBkYXJpIHNhdHUgYXRhdSBsZWJpaCBtdWx0aW5vbWluYWwgdmFyaWFiZWwga2F0ZWdvcmkuIENoaXNxdWVyZSBnb29kbmVzcyBvZiBmaXQgaW5pIGp1Z2EgYmlhc2EgZGlzZWJ1dCBub24tcGFyYW1ldGljIHRlc3QsIHlhbmcgYmVyYXJ0aSB0ZXN0IGluaSB0aWRhayBtZW5nZXN0aW1hc2kgcGFyYW1ldGVyIHBvcHVsYXNpLgo8YnI+CkxhbHUgYWRhIGp1Z2EgSW5kZXBlbmRlbmNlIENoaS1zcXVlcmUgdGVzdCwgSG9tb2dlbml0eSBDaGktU3F1ZXJlLCBkYW4gTXVsdGlub21pYWwgR29vZG5lc3Mgb2YgZml0Cjxicj4KVW50dWsgaGlwb3Rlc2lzLCBqaWthIHAtdmFsdWUgPCBkYXJpcGFkYSBhbHBoYSwgbWFrYSBIMCBkaXRvbGFrLgpIMD0gYmlzYSBiZXJ1cGEgaW5kZXBlbmRlbiBhdGF1IGJlcmRpc3RyaWJ1c2kgbm9ybWFsLCBkaXNlc3VhaWthbiBkZW5nYW4gdGVzdCB5YW5nIGRpZ3VuYWthbi4KCgojIyMgUmVncmVzc2lvbgpSZWdyZXNpIGFkYWxhaCBzYWxhaCBzYXR1IG1ldG9kZSB1bnR1ayBtZW1wcmVkaWtzaS4gCjxicj4KUmVncmVzaSBtZW1idXR1aGthbiBhc3Vtc2ktYXN1bXNpIHlhbmcgcGVybHUgZGlsYWt1a2FuIHNlYmVsdW0gbWVsYW5qdXRrYW4gcmVncmVzaSA6CiogTGluZWFyaXRhcywgYXBha2FoIGxpbmVhciBhdGF1IHRpZGFrLCBqaWthIHRpZGFrIGxpbmVhciBtYWthIGJ1YXQgbm9uLWxpbmVhcgoqIEF1dG8ga29yZWxhc2ksIGFwYWthaCBuaWxhaSBzZWJlbHVtbnlhIG1lbXBlbmdhcnVoaSBhdGF1IHRpZGFrCiogSG9tb2dlbml0YXMsIGFwYWthaCB2YXJpYW5zbnlhIHNhbWE/IEppa2EgdmFyaWFucyB0aWRhayBrb25zdGFuLCByZWdyZXNpIHRpZGFrIGFrdXJhdC4KKiBNdWx0aWtvbGluZWFyaXRhcywgYXBha2FoIHNlc2FtYSB2YXJpYWJlbCBkZXBlbmRlbiBtZW1pbGlraSBodWJ1bmdhbj8gSmlrYSB0ZXJkYXBhdCBodWJ1bmdhbiBtYWthIGFrYW4gbWVtcGVuZ2FydWhpIG91dHB1dCByZWdyZXNpIGF0YXUgaGFzaWwgaW1wbGVtZW50YXNpIHJlZ3Jlc2kuCgojIyMjIFNpbXBsZSBsaW5lYXIKU2ltcGxlIExpbmVhciByZWdyZXNzaW9uIGFkYWxhaCByZWdyZXNpIHlhbmcgdmFyaWFiZWwgZGVwZW5kZW4gZGFuIHZhcmlhYmVsIGluZGVwZW5kZW5ueWEgbnVtZXJpay4gU2ltcGxlIGxpbmVhciByZWdyZXNzaW9uIGFkYWxhaCByZWdyZXNpIHlhbmcgdmFyaWFiZWwgZGVwZW5kZW4gZGFuIHZhcmlhYmVsIGluZGVwZW5kZW5ueWEgbWFzaW5nLW1hc2luZyAxLiAKCiMjIyMgbXVsdGlwbGUgbGluZWFyCnJlZ3Jlc2kgeWFuZyBtYW5hIHZhcmlhYmVsIGluZGVwZW5kZW4gZGFuIHZhcmlhYmVsIGRlcGVuZGVubnlhIG51bWVyaWsuIFJlZ3Jlc2kgaW5pIHZhcmlhYmVsIGluZGVwZW5kZW5ueWEgMSwgZGFuIHZhcmlhYmVsIGRlcGVuZGVubnlhIGxlYmloIGRhcmkgMSAoPjEpLiAKCiMjIyMjIGltcGxlbWVudGFzaSBoYXNpbCBzaW1wbGUgJiBtdWx0aXBsZSBsaW5lYXIgcmVncmVzc2lvbgoqIFAtdmFsdWUgbW9kZWwgPSBwdmFsdWUgPGFscGhhLCBtb2RlbCBzaWtuaWZpa2FuIHRlcmhhZGFwIFkKKiBSLVNxdWVyZSwgUi1zcXVyZSBpbmkgbWVuZ2FydGlrYW4gYmFod2Eg4oCmJSB2YXJpYWJlbCB5YW5nIHN1ZGFoIG1hc3VrIGtlIGRhbGFtIG1vZGVsLiBCaXNhIGRpYmlsYW5nIFItc3F1ZXJlIGFkYWxhaCBzZWJlcmFwYSBiZXJndW5hIHZhcmlhYmVsIGJpc2EgbWVtcHJlZGlrc2kuCiAgKyBSLXNxdWVyZSBzZW1ha2luIHRpbmdnaSBzZW1ha2luIGJhZ3VzLCBiaWFzYW55YSA+ODAlIHN1ZGFoIG9rZQogICsgUnNxdWVyZSBkaWJhZ2kgbWVuamFkaSAyIHlhaXR1IG11bHRpcGxlIGRhbiBhZGp1c3RlZAogICAgLSBNdWx0aXBsZSAgIDogbXVsdGlwbGUgcmVncmVzc2lvbgogICAgLSBBZGp1c3RlZCA6IHNpbmdsZSByZWdyZXNzaW9uIAogICsgRmFrdG9yIHBlbmdhcnVoCiAgICAtIEtvZWZpc2llbiArLCBiZXJkYW1wYWsgKwogICAgLSBLb2VmaXNpZW4gLSwgYmVyZGFtcGFrIC0KCiogSklrYSBwLXZhbHVlIGRhbiBSLXNxdWVyZSBiZXJiYW5kaW5nIHRlcmJhbGlrIGRhbGFtIG1lbWlsaWggbW9kZWwsIG1ha2EgYWN1YW4geWFuZyBha2FuIGtpdGEgZGFodWx1a2FuIGFkYWxhaCBSLXNxdWVyZSwgc2VsYW1hIHAtdmFsdWUgPCBhbHBoYS4KCgojIyMjIFJlZ3Jlc2kgYmVydGFoYXAKUmVncmVzaSBpbmkgYWRhbGFoIHJlZ3Jlc2kgeWFuZyB0aWRhayBtZW1lcmx1a2FuIHRlcyBhdXRva29yZWxhc2ksIGhvbW9nZW5pdGFzLCBkYW4gbXVsdGlrb2xpbmVhcml0YXMuIFRldGFwaSB1bnR1ayByZWdyZXNpIGluaSBoYW55YSBiYWd1cyBkaWd1bmFrYW4gamlrYSBkYXRhIHlhbmcga2l0YSBwdW55YSBsaW5lYXIuIFJlZ3Jlc2kgaW5pIG1lbmdndW5ha2FuIHBhcmFtZXRlciBBSUMsIG1vZGVsIHlhbmcgdGVyYmFpayBhZGFsYWggbW9kZWwgeWFuZyBtZW1pbGlraSBBSUMgcGFsaW5nIGJlc2FyLiBBSUMgYWRhbGFoIEFrYWlrZSBJbmZvcm1hdGlvbiBDcml0ZXJpb24uIFNheWFuZ255YSByZWdyZXNpIGluaSBtZW1pbGlraSBrZWxlbWFoYW4sIHlhaXR1IG5nZS1ydW4gbnlhIGxhbWEgYWxpYXMgbGVtb3QsIGRhbiB0aWRhayBiaXNhIGRpZ3VuYWthbiBkZW5nYW4gbm9uLWxpbmVhci4gS2FyZW5hIG1ldG9kZSBpbmkgYWthbiBtZW5jYXJpIHNlbXVhIGtlbXVuZ2tpbmFuIG1vZGVsIHlhbmcgYWRhLCBsYXB0b3AgLyBQQyB5YW5nIGRpZ3VuYWthbiAgYmlzYSBsZWJpaCBsYW1iYXQgZGFyaSBiaWFzYW55YSAoc2FhdCBuZ2UtcnVuIGNvZGluZyBzYWphKS4KCgojIyMjIGxvZ2lzdGljIHJlZ3Jlc3Npb24KTG9naXN0aWMgcmVncmVzc2lvbiBhZGFsYWggcmVncmVzaSB5YW5nIG91dHB1dG55YSBudW1lcmlrIGRhbiBpbnB1dG55YSBtZXJ1cGFrYW4gdmFyaWFiZWwga2F0ZWdvcmlrIGF0YXUgbnVtZXJpay4gSmFkaSBsb2dpc3RpYyByZWdyZXNzaW9uIGFkYWxhaCByZWdyZXNpIHlhbmcgdmFyaWFiZWwgZGVwZW5kZW5ueWEgY2FtcHVyIChrYXRlZ29yaWthbCBkYW4gbnVtZXJpaykuIFJlZ3Jlc2kgaW5pIG1lbWlsaWtpIG4gb3V0cHV0LCBzZXN1YWkgZGVuZ2FuIGJlcmFwYSBqZW5pcyBrYXRlZ29yaS4gTG9naXN0aWMgcmVncmVzc2lvbiBpbmkgYWthbiBtZW1iZW50dWsgbiBoYXNpbCByZWdyZXNpIGRhbGFtIHN1YXR1IGRhdGEsIGphZGkgbmFudGkgYWthbiB0ZXJiZW50dWsgbiBnYXJpcyBwYWRhIHNjYXR0ZXIgcGxvdCBhdGF1IHZpc3VhbGlzYXNpbnlhLgo8YnI+CkNvbnRvaG55YSBqaWthIGRhbGFtIHN1YXR1IHJlZ3Jlc2kgdGluZ2thdCBrZXNlaGF0YW4gZ2lnaSBkYW4gbXVsdXQsIHZhcmlhYmVsbnlhIGFkYWxhaCAgbmlsYWkgZG1mdCwgdW11ciwgc2VoYXJpIGdvc29rIGdpZ2kgYmVyYXBhIGthbGksIGRhbiBwZXJva29rLiBNYWthIG91dHB1dG55YSBha2FuIG1lbWlsaWtpIFlwZXJva29rIGRhbiBZIGJ1a2FuIHBlcm9rb2suIAoKIyMjIyBBTk9WQQpBbm92YSAoYW5hbGlzaXMgb2YgdmFyaWFuY2UpIGFkYWxhaCB0ZXN0IHJlZ3Jlc2kgeWFuZyBkaWd1bmFrYW4gdW50dWsgbWVtYmFuZGluZ2thbi4gQW5vdmEgamFyYW5nIGRpZ3VuYWthbiB1bnR1ayBtZW1wcmVkaWtzaS4gQW5vdmEgbWVtaWxpa2kgaW5wdXQga2F0ZWdvcmlrLCBkYW4gb3V0cHV0IG51bWVyaWsuIEluZ2F0IGJhaHdhIEFub3ZhIG1lbWlsaWtpIDEgb3V0cHV0LiBBbm92YSBpbmkgZ3VuYW55YSB1bnR1ayBtZWxpaGF0IGFwYWthaCB0ZXJkYXBhdCBodWJ1bmdhbiBhbnRhciBrZWxvbXBvay4gQU5PVkEgbWVydXBha2FuIHNhbGFoIHNhdHUgbWV0b2RlIEFCIHRlc3RpbmcuIEFub3ZhIGp1Z2EgYmlzYSBkaWJpbGFuZyBzZXBlcnRpIGhpcG90ZXNpcy4KPGJyPgpDb250b2hueWEgamlrYSB0ZXJkYXBhdCAyIGtlbG9tcG9rIHlhbmcgbWVtaWxpa2kgbWVhbiBkYW4gbiBvcmFuZyB5YW5nIHNhbWEuIEFwYWthaCBrZWR1YSBrZWxvbXBvayB0ZXJzZWJ1dCBzYW1hPyBKYXdhYmFubnlhIHRpZGFrIHNhbWEsIHdhbGF1cHVuIHJhdGEtcmF0YW55YSBzYW1hLCB2YXJpYW5zIG55YSB0ZXRhcCBzYWphIGJlcmJlZGEuIEtpdGEgYWthbiBtZW5nZ3VuYWthbiBBTk9WQSB1bnR1ayBtZW5jYXJpIGFwYWthaCBhZGEgcGVyYmVkYWFuIHlhbmcgc2lrbmlmaWthbiBhdGF1IHRpZGFrIGFudGFyYSAyIGtlbG9tcG9rIHRlcnNlYnV0Lgo8YnI+CkFzdW1zaSBBTk9WQSBhZGEgNCB5YWl0dQorIGluZGVwZW5kZW5jZSwgcGFzdGlrYW4gdmFyaWFiZWwgZGVwZW5kZW5ueWEgdGlkYWsgbWVtZW1wZW5nYXJ1aGkgdmFyaWFiZWwgbGFpbm55YS4KKyBubyBzaWduaWZpY2FudCBvdXRsaWVyLCB0aWRhayBtZW1pbGlraSBwZW5jaWxhbgorIG5vcm1hbGl0YXMsIGhhcnVzIG5vcm1hbCwgamlrYSB0aWRhayBndW5ha2FuIHRlc3Qgbm9uLXBhcmFtZXRyaWsKKyBob21vZ2VuaXRhcywgdmFyaWFucyBoYXJ1cyBrb25zdGFuCjxicj4KPGJyPgpKaWthIHNhbGFoIHNhdHUgYXN1bXNpIHRpZGFrIHRlcnBlbnVoaSBndW5ha2FuIG5vbi1wYXJhbWV0cmlrIHRlc3QgKHNhcmFuIDprcnVza2FsIHdhbGxpcyB0ZXN0KQo8YnI+CkFub3ZhIGRpYmFnaSBtZW5qYWRpIDMgeWFpdHUgb25lLXdheSwgdHdvLXdheSwgZGFuIG11bHRpLXdheS4gQW5vdmEgb25ld2F5IGFkYWxhaCBleHRlbnRpb24gb2YgaW5kZXBlbmRlbnQgc2FtcGxlIHVudHVrIGxlYmloIGRhcmkgMiBncnVwIHlhbmcgaGFueWEgbWVtYmFuZGluZ2thbiAxIGZha3RvciwgdHdvLXdheSA9IG1lbWJhbmRpbmdrYW4gMiBmYWt0b3IsIG11bHRpd2F5ID0gbWVtYmFuZGluZ2thbiBsZWJpaCBkYXJpIDIgZmFrdG9yLiBGYWt0b3IgeWFuZyBkaW1ha3N1ZCBkaXNpbmkgYWRhbGFoIHZhcmlhYmVsIGRlcGVuZGVubnlhLiAKYGBge3IsIGVjaG89RkFMU0UsZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnMTAwJSd9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJhbm92YV93YXkuanBnIikKYGBgCjxicj4KCgpBTk9WQSBtZW1pbGlraSBoaXBvdGVzaXMgOgorIEhpcG90ZXNpcyAwIDogJFxtdV9hID1cbXVfYiA9IFxtdV9jID0uLi49XG11X24gPSQKKyBISXBvdGVzaXMgJFxhbHBoYSQgPSRcbXVfYSAgXG5lIFxtdV9iIFxuZSBcbXVfYyBcbmUuLi5cbmUgXG11X24gPSQKKyBSZWplY3QgSDAgamlrYSBwLXZhbHVlICRcbGUgXGFscGhhJCBkYW4gQWNjZXB0IEgwIGppa2EgcC12YWx1ZSA+ICRcYWxwaGEkLCBKSWthIEgwIGRpdG9sYWsgbWFrYW4gdGVyZGFwYXQgcGVyYmVkYWFuLiBQZXJiZWRhYW4gdGVyc2VidXQga2l0YSB0aWRhayB0YWh1IHlhbmcgbWFuYSB5YW5nIGJlcmJlZGEsIGJpc2EgamFkaSBoYW55YSBzYXR1IHlhbmcgYmVkYSwgYXRhdSBzZW11YSBiZXJiZWRhLiBtYWthIGRhcmkgaXR1IGtpdGEgYmlzYSBndW5ha2FuIHVqaSBsYW5qdXQgbWVuZ2d1bmFrYW4gVWppIFBhcnNpYWwgYXRhdSBzYXBpcm8gIHRlc3QgKGBzYXBpcm8oKWApICwgdWppIHR1a2V5ICxkYW4gbGV2aW5lJ3MgdGVzdCAodW50dWsgbWVuY2VrIGRhdGEgaG9tb2dlbiBhdGF1IHRpZGFrKS4KPGJyPgoKCgojIyMjIE1BTk9WQSAKTUFOT1ZBIChtdWx0aXZhcmlhdGUgYW5hbHlzaXMgb2YgdmFyaWFuY2UpIGFkYWxhaCBhbm92YSB5YW5nIG1lbWlsaWtpIGxlYmloIGRhcmkgMSBvdXRjb21lLk1Bbm92YSBsZWJpaCBtZW5nYXJhaCBrZSBleHBlcmltZW50YWwgZGFuIGJlcmZva3VzIHBhZGEgdmFyaWFiZWwgZGVwZW5kZW4uCgpVamkgYXN1bXNpIGFub3ZhIDoKKyB2YXJpYWJlbCBkZXBlbmRlbm55YSBiZXJkaXN0cmlidXNpIG5vcm1hbCAoYG1zaGFwaXJvLnRlc3QoKWAgZGFsYW0gcGFja2FnZSBgbXZub3JtdGVzdGApCisgaG9tb2dlbml0YXMgdmFyaWFucyBhbnRhciBwcmlrdG9yCisgbGluZWFyaXRhcyBhbnRhciBzZW11YSB2YXJpYWJlbCBkZXBlbmRlbiwgc2VtdWEgY292YXJpYXQsIGRhbiBzZW11YSB2YXJpYWJlbCBkZXBlbmRlbi1rb3ZhcmlhdC4gCgoKCgoKIyBOb21vciAyCjIuIEJ1YXRsYWggY29udG9oIHBlbnllbGVzYWlhbiBIaXBvdGVzaXMgVGVzdGluZyBkZW5nYW4gbWVuZ2d1bmFrYW4gUiEKPGJyPgpQZW5qdWFsIGt3ZXRpYXcgZ29yZW5nIG1lbmdhdGFrYW4gYmFod2Egc2VidW5na3VzIHBvcnNpIGJlcmF0bnlhIDI1MCBncmFtLiBTZXRlbGFoIGt3ZXRpYXdueWEgZGliZWxpIDYwIHBvcnNpIHVudHVrIHNhbXBsZSwgZGlkYXBhdGthbiBoYXNpbCByYXRhIHBlci1wb3JzaSAyMzUgZ3JhbSwgZGFuIHN0YW5kYXIgZGV2aWFzaW55YSAzNSBncmFtLiBBcGFrYWgga2l0YSBiaXNhIG1lbmVyaW1hIGtsYWltIHBlbmp1YWwga3dldGlhdyB0ZXJzZWJ1dD8KPGJyPgokSF8wJCA9ICRcbXVfMCA9IFxtdSQgPSBrbGFpbSBkaXRlcmltYQo8YnI+CiRIXzEkID0gJFxtdV8wIFxuZSBcbXUkID0ga2xhaW0gZGl0b2xhawpgYGB7cn0KIyB0d28td2F5IGRlbmdhbiBzdGFuZGFyIGRldmlhc2kgcG9wdWxhc2kgdGlkYWsgZGlrZXRhaHVpCm1pdTAgPSAyNTAKeGJhciA9IDIzNQpzID0gMzUKbiA9IDYwCmFscGhhID0gIDAuMDUKCnQgPSAoeGJhci1taXUwKS8ocy9zcXJ0KG4pKSA7IHQKdC50YWIgPSBxdCgxLWFscGhhLzIsZGYgPSBuLTEpCmMoLXQudGFiLCB0LnRhYikKcHZhbCA9IDIqcHQodCwgZGYgPSBuLTEpO3B2YWwKYGBgCkthcmVuYSB0IGJlcmFkYSBkaSBkYWVyYWggcGVub2xha2FuICh0IGhpdHVuZyA8IHQgdGFiLCBkYW4gcHZhbCA8MCwwNSksIEgwIGRpdG9sYWsuIE1ha2EgYmlzYSBkaWthdGFrYW4ga2xhaW0gcGVuanVhbCB0ZXJzZWJ1dCBiaXNhIGtpdGEgdG9sYWsuCgojIE5vbW9yIDMKMy4gQnVhdGxhaCBjb250b2ggcGVueWVsZXNhaWFuIEFOT1ZBIGRlbmdhbiBtZW5nZ3VuYWthbiBSIQo8YnI+CiMjIGNvbnRvaCAxClRlcmRhcGF0IGRhdGEga2VzZWhhdGFuIGdpZ2kgZGFuIG11bHV0IDoKKyBrYXJpZXMgOiBhZGEgYXRhdSB0aWRhayBhZGFueWEga2FyaWVzCisgSksgOiBqZW5pcyBrZWxhbWluCisgdG90YWwgOiBqdW1sYWggcGVuZ2V0YWh1YW4geWFuZyBiZW5hcgpgYGB7cn0KbGlicmFyeShyZWFkeGwpCmRhdGEuYW5vdmEgPSByZWFkX2V4Y2VsKCdkYXRhLmFub3ZhLnhsc3gnKQoKIyBtdW5jdWxrYW4gZGF0YSBhZ2FyIHRpZGFrIHRlcmxhbHUgYmFueWFrIG11bmN1bG55YQpoZWFkKGRhdGEuYW5vdmEpCmBgYApgYGB7cn0KbGlicmFyeShkcGx5cikKbGlicmFyeShyc3RhdGl4KQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KGdncGxvdDIpCgoKZGF0YS5hbm92YSAlPiUKICBzYW1wbGVfbl9ieShrYXJpZXMsIEtlbGFzKSAKYGBgCgpgYGB7cn0KIyBjYXJpIHN1bW1hcnlueWEKZGF0YS5hbm92YSAlPiUKICBncm91cF9ieShrYXJpZXMsIEpLKSU+JQogIGdldF9zdW1tYXJ5X3N0YXRzKHRvdGFsLCB0eXBlID0gIm1lYW5fc2QiKQoKCiMgY2VrIGFzdW1zaSBvdXRsaWVyIHlhbmcgZWtzdHJpbQpnZ3Bsb3QoZGF0YS5hbm92YSwgYWVzKHggPSBrYXJpZXMsIHkgPSB0b3RhbCwgZmlsbCA9IEpLKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgKwogICAgZ2VvbV9qaXR0ZXIoc2hhcGUgPSAxNSwKICAgICAgICBjb2xvciA9ICJzdGVlbGJsdWUiLAogICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyKDAuMjEpKSArCiAgIHRoZW1lX21pbmltYWwoKQoKCmRhdGEuYW5vdmEgJT4lCiAgZ3JvdXBfYnkoa2FyaWVzLCBKSyklPiUKICBpZGVudGlmeV9vdXRsaWVycyh0b3RhbCkKCmBgYAoKS2FyZW5hIHBhcyBkaWxpaGF0IHRpZGFrIGFkYSBvdXRsaWVyIGRhbiAKCmBgYHtyfQphbm92YS5pbnRlcmFrc2kgICA9IGFvdih0b3RhbCB+IEpLICoga2FyaWVzLCBkYXRhID0gZGF0YS5hbm92YSkKYW5vdmEudGFtYmFoYW4gICAgPSBhb3YodG90YWwgfiBrYXJpZXMgKyBKSywgZGF0YSA9IGRhdGEuYW5vdmEpCmFub3ZhLmthcmllcyAgICAgID0gYW92KHRvdGFsIH4ga2FyaWVzLCBkYXRhID0gZGF0YS5hbm92YSkKYW5vdmEuSksgPSBhb3YodG90YWwgfiBKSywgZGF0YSA9IGRhdGEuYW5vdmEpCmFub3ZhLm5vbCAgICAgICAgID0gYW92KHRvdGFsIH4gMSwgZGF0YSA9IGRhdGEuYW5vdmEpCmBgYAoKYGBge3J9CnN1bW1hcnkoYW5vdmEuaW50ZXJha3NpKQpzdW1tYXJ5KGFub3ZhLnRhbWJhaGFuKQpzdW1tYXJ5KGFub3ZhLmthcmllcykKc3VtbWFyeShhbm92YS5KSykKc3VtbWFyeShhbm92YS5ub2wpCmBgYAoKRGVuZ2FuIG1lbmdndW5ha2FuIHNpa25pZmlrYW5zaSBsZXZlbCAkXGFscGhhID0gNSUkLCBraXRhIGJpc2EgbWVuZ2V0YWh1aSBiYWh3YSBIMCBkaXRlcmltYS4ga2VkdWEgdmFyaWFiZWwgdGVyc2VidXQgdGlkYWsgbWVtaWxpa2kgaHVidW5nYW4geWFuZyBzaWtuaWZpa2FuIGRlbmdhbiBqdW1sYWggdG90YWwgcGVuZ2V0YWh1YW4uCgoKIyMgY29udG9oIDIKS2l0YSBha2FuIG1lbGloYXQgcGFkYSA1MCBkYXRhIHBlbWFpbiBOQkEgZHJhZnQgMjAwMS0yMDE1LCBwYWRhIGRyYWZ0IGluaSBraXRhIGFrYW4gbWVtYmFuZGluZ2thbiBQYWthaCBhZGEgaHVidW5nYW4gUG9zaXNpIHNldGlhcCBwZW1haW4gZGFuIHRhaHVuIGRpLWRyYWZ0IHRlcmhhZGFwIG5pbGFpIFNQTS4gTklsYWkgU1BNIGFkYWxhaCBuaWxhaSBzdGF0aXN0aWsgKy8tLgo8YnI+CnN1bWJlciA6IGh0dHBzOi8vZ2l0aHViLmNvbS9maXZldGhpcnR5ZWlnaHQvZGF0YS90cmVlL21hc3Rlci9uYmEtZHJhZnQtMjAxNQpgYGB7cn0KZGF0YTIgPSByZWFkLmNzdigiaGlzdG9yaWNhbF9wcm9qZWN0aW9ucy5jc3YiKQoKaGVhZChkYXRhMikKYGBgCm1lbmdndW5ha2FuIGRhdGEgaW5pLCBraXRhIGFrYW4gbWVtaWxpaCBkYXRhIFBPc2l0aW9uLCBEcmFmdFllYXIsIGRhbiBQcm9qZWN0ZWQuU1BNLgo8YnI+CnNlYmVsdW0gaXR1IGtpdGEgYWthbiBtZW1idWF0IGhpcG90ZXNpcyAKPGJyPgokXEhfMCQgPSB0aWRhayBtZW1pbGlraSBwZXJiZWRhYW4gdmFyaWFucyBhbnRhcmEgZHVhIHZhcmlhYmVsIChwb3NpdGlvbiBkYW4gZHJhZnQgeWVhcikKPGJyPgokXEhfMSQgPSB0ZXJkYXBhdCBwZXJiZWRhYW4gdmFyaWFucyBhbnRhcmEgZHVhIHZhcmlhYmVsIChwb3NpdGlvbiBkYW4gZHJhZnQgeWVhcikKYGBge3J9CmRhdGEyICU+JQogIGdyb3VwX2J5KFBvc2l0aW9uLCBEcmFmdC5ZZWFyKSU+JQogIGdldF9zdW1tYXJ5X3N0YXRzKFByb2plY3RlZC5TUE0sIHR5cGUgPSAibWVhbl9zZCIpCgojIG1lbmdpbmRlbnRpZmlrYXNpIG91dGxpZXIgZGFuIG1lbmdoaWxhbmdrYW4gb3V0bGllcgpoYWkgPSBkYXRhMiAlPiUKICBncm91cF9ieShQb3NpdGlvbiwgRHJhZnQuWWVhciklPiUKICBpZGVudGlmeV9vdXRsaWVycyhQcm9qZWN0ZWQuU1BNKSAKb3V0bGllciA9IGMoaGFpJElEKQpkYXRhMl9uZXcgID0gZGF0YTJbISBkYXRhMiRJRCAlaW4lIG91dGxpZXIsXQpgYGAKS2FyZW5hIGJhbnlhayBvdXRsaWVyIHlhbmcgZXh0cmltLCBtYWthIHBlbWFpbiIgdGVyc2VidXQgaGFydXMgZGlrZWx1YXJrYW4uCgoKYGBge3J9CmludCA9IGFvdihQcm9qZWN0ZWQuU1BNfiBQb3NpdGlvbipEcmFmdC5ZZWFyLCBkYXRhID0gZGF0YTJfbmV3KQphZGQgPSBhb3YoUHJvamVjdGVkLlNQTX4gUG9zaXRpb24rRHJhZnQuWWVhciwgZGF0YSA9IGRhdGEyX25ldykKcG9zID0gYW92KFByb2plY3RlZC5TUE1+IFBvc2l0aW9uLCBkYXRhID0gZGF0YTJfbmV3KQp5ZWFyID0gYW92KFByb2plY3RlZC5TUE1+IERyYWZ0LlllYXIsIGRhdGEgPSBkYXRhMl9uZXcpCm5iYV9udWxsID0gYW92KFByb2plY3RlZC5TUE1+IDEsIGRhdGEgPSBkYXRhMl9uZXcpCmBgYAoKYGBge3J9CnN1bW1hcnkoaW50ICkKc3VtbWFyeShhZGQgKQpzdW1tYXJ5KHBvcyApCnN1bW1hcnkoeWVhcikKc3VtbWFyeShuYmFfbnVsbCkKYGBgCkRpZGFwYXQgZGFyaSBoYXNpbCBkaSBhdGFzIGJhaHdhIHNlbXVhIHRlcyB5YW5nIGtpdGEgZ3VuYWthbiBzZW11YW55YSBiZXJiZWRhIHNpa25pZmlrYW4ga2VjdWFsaSBpbnRlYWtzaS4gQmlzYSBkaWJpbGFuZyBEcmFmdC5ZZWFyIGRhbiBQb3NpdGlvbiBtZW1lbnR1a2FuIG5pbGFpIFByb2plY3RlZCBTUE0uIEthcmVuYSBwLXZhbHVlIGt1cmFuZyBkYXJpICRcYWxwaGEgPSAwLjA1JCwgbWFrYSBIMCBkaXRvbGFrLCBhdGF1IHRlcmRhcGF0IHBlcmJlZGFhbiB5YW5nIHNpa25pZmlrYW4gYW50YXJhIGRyYWZ0LnllYXIgZGFuIHBvc2l0aW9uLgo8YnI+CmxhbHUga2l0YSBha2FuIG1lbGloYXQgbGFnaSB1bnR1ayBtZW5nZXRlcyBUeXBlIDIgeWFpdHUgZmFsc2UgbmVnYXRpdmUuCgpgYGB7cn0KYW92X3Rlc3RfaW50IDwtIGRhdGEyX25ldyAlPiUgCiAgYW5vdmFfdGVzdChQcm9qZWN0ZWQuU1BNfiBQb3NpdGlvbitEcmFmdC5ZZWFyKQphb3ZfdGVzdF9pbnQKCmFvdl90ZXN0X2ludCA8LSBkYXRhMl9uZXcgJT4lIAogIGFub3ZhX3Rlc3QoUHJvamVjdGVkLlNQTX4gUG9zaXRpb24pCmFvdl90ZXN0X2ludAoKYW92X3Rlc3RfaW50IDwtIGRhdGEyX25ldyAlPiUgCiAgYW5vdmFfdGVzdChQcm9qZWN0ZWQuU1BNfiBEcmFmdC5ZZWFyKQphb3ZfdGVzdF9pbnQKYGBgCgp5YW5nIGRpIGRhcGF0IGRhcmkgaGFzaWwgdGVzIHR5cGUgMiBhZGFsYWggc2VjYXJhIHN0YXRpc3RpayBiZXJkYXBhdCBwZXJiZWRhYW4geWFuZyBzaWtuaWZpa2FuIGFudGFyYSB0YW1iYWhpbiwgZGFuIHlhbmcgY2VrIG1hbmRpcmkuCjxicj4KCiMjIyBjZWsgQXN1bXNpCgpgYGB7cn0KcGxvdChhZGQsMSkgIyBob21vZ2VuaXRhcwpwbG90KGFkZCwyKSAjIG5vcm1hbGl0YXMKZGF0YTJfbmV3ICU+JQogIGdyb3VwX2J5KFBvc2l0aW9uLCBEcmFmdC5ZZWFyKSU+JQogIHNoYXBpcm9fdGVzdChQcm9qZWN0ZWQuU1BNKQpvbmV3YXkudGVzdChQcm9qZWN0ZWQuU1BNfiBQb3NpdGlvbitEcmFmdC5ZZWFyLGRhdGE9ZGF0YTJfbmV3KSAjIG5vIGFzc3VtcHRpb24gb2YgZXF1YWwgdmFyaWFuY2VzCmBgYAoKZGFyaSBoYXNpbCBkaSBhdGFzLCBkaWRhcGF0a2FuIHAtdmFsdWUgPiAwLDA1LiBBcnRpbnlhIHRpZGFrIGFkYSBidWt0aSBiYWh3YSB2YXJpYW5zIG1lcnVwYWthbiBzaWtuaWZpa2FuIHNjYXJhIHN0YXRpc3Rpay4gRGF0YW55YSBob21vZ2VuLCBub3JtYWwsIGRhbiB2YXJpYW5zIGtvbnN0YW4uCgoKIyMjIGNlayBwZXJiZWRhYW4KYGBge3J9CmxpYnJhcnkoZW1tZWFucykKCmNlayA9ZGF0YTJfbmV3ICU+JSAKICBncm91cF9ieShQb3NpdGlvbikgJT4lCiAgZW1tZWFuc190ZXN0KFByb2plY3RlZC5TUE0gfkRyYWZ0LlllYXIsIHAuYWRqdXN0Lm1ldGhvZCA9ICJib25mZXJyb25pIikgCnN1bW1hcnkoY2VrKQoKY2VrW2NlayRwLmFkaiA8MC4wNSxdCmBgYApkYXJpIHNlbXVhIGRhdGEgcGVyYmVkYWFuICg1MjUgZGF0YSksIHlhbmcgYmVycGVuZ2FydWggc2lrbmlmaWthbiAgdGVyZGFwYXQgMjEgamVuaXMsIHlhaXR1IHNlcGVydGkgaGFzaWwgZGkgYXRhcy4gQ2FyYSBiYWNhbnlhIGFkYWxhaCBwb3Npc2kgLi4uIG1lbWlsaWtpIHBlcmJlZGFhbiB5YW5nIHNpa25pZmlrYW4vc2FuZ2F0IHNpa25pZmlrYW4gYW50YXJhIGRyYWZ0IHRhaHVuIC4uLiBkYW4gLi4uCgoKCiMgTm9tb3IgNAo0LiBCdWF0bGFoIGNvbnRvaCBwZW55ZWxlc2FpYW4gTUFOT1ZBIGRlbmdhbiBtZW5nZ3VuYWthbiBSIQpQYWRhIGRhdGEgZGkgYmF3YWggaW5pIGtpdGEgYWthbiBtZW5nZXRhaHVpIGFwYWthaCBhZGFueWEgcGVyYmVkYWFuIHlhbmcgc2lrbmlmaWthbiBhbnRhcmEgS2luZXJqYSBkYW4gSVEgYW50YXJhIGFuZ2thdGFuLgpgYGB7cn0KZGF0YS5tYW5vdmEgPC0gZGF0YS5mcmFtZSgKICBBbmdrYXRhbiA9IHJlcChjKCIyMDE4IiwgIjIwMTkiLCAiMjAyMCIpLCAxMCksCiAgSVEgPSBjKDExMiwgMTE2LCAxMjAsIDEyOSwgMTI2LCAxNDEsIDk3LCAxMDMsIDEwNywgMTI1LAogICAgICAgICAxMTMsIDExOSwgMTI0LCAxMzIsIDEzMSwgMTQ2LCA5OSwgMTA1LCAxMTEsIDEyMSwKICAgICAgICAgMTE4LCAxMjcsIDEzMiwgMTM4LCAxMzcsIDE1MywgMTA0LCAxMDksIDExNywgMTI2KSwKICBLaW5lcmphID0gYyg2MSwgNjcsIDczLCA4MSwgNzcsIDkzLCA1NiwgNjIsIDY3LCA3NywKICAgICAgICAgICAgICA2OCwgNzQsIDc5LCA4NywgODQsIDk5LCA2MiwgNjcsIDcyLCA4MiwKICAgICAgICAgICAgICA3MSwgNzYsIDgyLCA5MiwgODgsIDEwMywgNjgsIDczLCA3OSwgODkpCikKCmBgYAoKIyMgY2VrIGFzdW1zaQpgYGB7cn0KZGF0YS5tYW5vdmElPiUgIyBjZWsgc2FtcGxlIHNpemUKICBncm91cF9ieShBbmdrYXRhbiklPiUKICBzdW1tYXJpc2UoTiA9IG4oKSkKYGBgClNhbXBsZW55YSBzdWRhaCBva2UsIG4gc2V0aWFwIGFuZ2thdGFuIGtlYmloIGRhcmkgNC4KYGBge3J9CiMgaWRlbnRpZmlrYXNpIHVuaXZhcmlhdCBvdXRsaWVycywgYWRhIG91dGxpZXIgdGV0YXBpIHRpZGFrIGVrcmltLCBqYWRpIG9rZSBzYWphIGRpbWFzdWtrYW4KZGF0YS5tYW5vdmElPiUgCiAgZ3JvdXBfYnkoQW5na2F0YW4pJT4lCiAgaWRlbnRpZnlfb3V0bGllcnMoSVEpCgpkYXRhLm1hbm92YSU+JSAjIyB0aWRhayBhZGEgb3V0bGllcgogIGdyb3VwX2J5KEFuZ2thdGFuKSU+JQogIGlkZW50aWZ5X291dGxpZXJzKEtpbmVyamEpCgojIGRldGVrc2kgb3V0bGllciBtdWx0aXZhcmlhdCB0aWRhayBwZXJsdSBsYWdpIGthcmVuYSBwYWRhIHVuaXZhcmlhdCB0aWRhayB0ZXJkYXBhdCBvdXRsaWVyCgojIGNlayBub3JtYWxpdGFzIHVuaXZhcmlhdApkYXRhLm1hbm92YSU+JSAKICBncm91cF9ieShBbmdrYXRhbiklPiUKICBzaGFwaXJvX3Rlc3QoSVEsIEtpbmVyamEpJT4lCiAgYXJyYW5nZSh2YXJpYWJsZSkKYGBgCkRhcmkgaGFzaWwgdGVzdCBzYXBpcm8gZGkgYXRhcyBkaWRhcGF0IHNlbXVhIHZhcmlhYmVsLCBwID4gMC4wNSwgbWFrYSBkYXRhbnlhIGJlcmRpc3RyaWJ1c2kgbm9ybWFsCgpgYGB7cn0KIyBpZGVudGlmeSBtdWx0aWtvbGluZWFyaXR5CmRhdGEubWFub3ZhICU+JQogIGNvcl90ZXN0KElRLCBLaW5lcmphKQpgYGAKRGFyaSBoYXNpbCBrb3JlbGFzaSBkaSBhdGFzIGRpZGFwYXRrYW4gYmFod2EgdmFyaWFiZWwgZGVwZW5kZW4gdGlkYWsgIGJlcmtvcmVsYXNpIGRlbmdhbiBoYXNpbCBwPDAuMDUKCmBgYHtyfQojIGxpbmVhciBhc3VtcHRpb24KbGlicmFyeShHR2FsbHkpCnJlc3VsdHMgPC0gZGF0YS5tYW5vdmEgJT4lCiAgc2VsZWN0KEtpbmVyamEsIElRLCBBbmdrYXRhbikgJT4lCiAgZ3JvdXBfYnkoQW5na2F0YW4pICU+JQogIGRvbyh+Z2dwYWlycyguKSArIHRoZW1lX2J3KCksIHJlc3VsdCA9ICJwbG90cyIpCnJlc3VsdHMkcGxvdHMKYGBgCgpEYXJpIGhhc2lsIGdyYWZpayBkaSBhdGFzLCBkaWRhcGF0IGJhaHdhIGRhdGFueWEgbGluZWFyLgpgYGB7cn0KYm94X20oZGF0YS5tYW5vdmFbLCBjKCJJUSIsICJLaW5lcmphIildLCBkYXRhLm1hbm92YSRBbmdrYXRhbikgIyB1amkgaG9tb2dlbml0YXMga292YXJpYW4gKHAtdmFsdWU+MC4wNSwgdGVyZGFwYXQgaG9tb2dlbml0YXMga292YXJpYW4pCmRhdGEubWFub3ZhJT4lIAogIGdhdGhlcihrZXkgPSAidmFyaWFibGUiLCB2YWx1ZSA9ICJ2YWx1ZSIsIElRLEtpbmVyamEpICU+JQogIGdyb3VwX2J5KHZhcmlhYmxlKSAlPiUKICBsZXZlbmVfdGVzdCh2YWx1ZSB+IEFuZ2thdGFuKSAjIGRpZGFwYXRrYW4gaGFzaWwgdGlkYWsgaG9tb2dlbiBhbnRhciB2YXJpYW5zIChwLXZhbHVlPjAuMDUpCmBgYApIYXNpbCB5YW5nIGRpZGFwYXRrYW4gYmFod2EgZGF0YSBpbmkga292YXJpYW4gaG9tb2dlbiBkYW4gdGlkYWsgaG9tb2dlbiBhbnRhciB2YXJpYW5zLiBtYWthIGRhcmkgaXR1IHRlcmRhcGF0IGFzdW1zaSB5YW5nIHRpZGFrIHRlcnBlbnVoaS4gT2xlaCBrYXJlbmEgaXR1IGtpdGEgYWthbiBsYW5qdXQsIHRldGFwaSBwZXJsdSBkaWluZ2F0IGJhaHdhIGhhc2lsIE1BTk9WQSBpbmkgYWthbiB0aWRhayB0ZXJsYWx1IGFrdXJhdC4KYGBge3J9Cm1vZGVsMTwtIG1hbm92YShjYmluZChLaW5lcmphLCBJUSkgfiBBbmdrYXRhbiwgZGF0YS5tYW5vdmEpCnN1bW1hcnkobW9kZWwxKQoKbW9kZWwyPC0gbG0oY2JpbmQoS2luZXJqYSwgSVEpIH4gQW5na2F0YW4sIGRhdGEubWFub3ZhKQpNYW5vdmEobW9kZWwyLCB0ZXN0LnN0YXRpc3RpYyA9ICJQaWxsYWkiKQpgYGAKRGFyaSBoYXNpbCBjb2RpbmdhbiBkaSBhdGFzLCB0aWRhayB0ZXJkYXBhdCBwZXJiZWRhYW4geWFuZyBzaWtuaWZpa2FuIGFudGFyYSBraW5lcmphIGRhbiBJUS4gUC12YWx1ZSA+IDAsMDUsIG1ha2EgSDAgZGl0ZXJpbWEuIGtlZHVhIHZhcmlhYmVsIHRlcnNlYnV0IGp1Z2EgdGlkYWsgYmVyYmVkYSBzaWtuaWZpa2FuIGFudGFyIGFuZ2thdGFuLgojIFJlZmVyZW5zaQoKCgpSZWZlcmVuc2kgOgorIGh0dHBzOi8vYm9va2Rvd24ub3JnL0Jha3RpU2lyZWdhci9kYXRhLXNjaWVuY2UtZm9yLWJlZ2lubmVycy1wYXJ0LTIvMTItUk0tQU5PVkEuaHRtbAorIGh0dHBzOi8vd3d3LnN0YXRvbG9neS5vcmcvbGVmdC10YWlsZWQtdGVzdC12cy1yaWdodC10YWlsZWQtdGVzdC8jOn46dGV4dD1UaGVyZSUyMGFyZSUyMHRocmVlJTIwZGlmZmVyZW50JTIwdHlwZXMsaHlwb3RoZXNpcyUyMGNvbnRhaW5zJTIwdGhlJTIw4oCcJTNF4oCdJTIwc2lnbgorIGh0dHBzOi8vd3d3LnNjcmliYnIuY29tL3N0YXRpc3RpY3MvdHlwZS1pLWFuZC10eXBlLWlpLWVycm9ycy8KKyBodHRwczovL29laXMub3JnL3dpa2kvTGlzdF9vZl9MYVRlWF9tYXRoZW1hdGljYWxfc3ltYm9scworIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEzMDEyNTA5L2hvdy10by1kZWxldGUtcm93cy1mcm9tLWEtZGF0YS1mcmFtZS1iYXNlZC1vbi1hbi1leHRlcm5hbC1saXN0LXVzaW5nLXIjOn46dGV4dD1Zb3UlMjBjYW4lMjB1c2UlMjBhbHNvJTIwdXNlJTIwbWF0Y2glMjBpZiUyMHRoZXJlLHJvd3MlMjB0aGF0JTIwZXhhY3RseSUyMG1hdGNoZXMlMjB5b3VyJTIwTkFNRVNfbGlzdCUyMHdpdGglMjBtYWluX2RhdGElMjROQU1FUy4KKyBodHRwczovL2dpdGh1Yi5jb20vZml2ZXRoaXJ0eWVpZ2h0L2RhdGEKKyBkYXRhIG1hbm92YTogZGF0YSBkYXJpIGZvcm1zIHBzaWtvbG9naSB5YW5nIG1lbmFueWFrYW4gdGVudGFuZyBjYXJhIGJlbGFqYXIu