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


1 BAB 6 SIMULASI DAN PENGAMBILAN SAMPEL ULANG

  • Bagian 6.1 memperkenalkan simulasi, alat komputasi luar biasa yang sangat berguna dalam pengaturan multivariat yang kompleks.

  • Bagian 6.2 memperkenalkan resampling dalam konteks bootstrap untuk menentukan ketepatan estimator. Resampling merupakan proses simulasi untuk menggambar dari distribusi empiris.

1.1 (6.1) Dasar-Dasar Simulasi

  1. Menghasilkan sekitar realisasi independen yang terdistribusi secara merata

  2. Ubah realisasi yang terdistribusi secara seragam menjadi pengamatan dari distribusi probabilitas yang menarik

  3. Hitung jumlah bunga dan tentukan ketepatan jumlah yang dihitung

1.1.1 (6.1.1) Menghasilkan Pengamatan Seragam Independen

Generator Kongruensi Linier.

Linear Congruential Generators (LCG) adalah sebuah metode yang membangkitkan bilangan acak yang banyak dipergunakan dalam program komputer. Pada metode ini, dilakukan perulangan pada periode waktu tertentu atau setelah sekian kali pembangkitan.Untuk menghasilkan urutan angka acak, mulailah dengan \(B_0\) , nilai awal yang dikenal sebagai ‘seed’ . Nilai ini diperbarui menggunakan hubungan rekursif

\[B_{n+1} = (a B_n + c) \text{ modulo }m, ~~ n=0, 1, 2, \ldots .\]

Algoritma ini disebut \(a\). Kasus \(c = 0\) disebut generator kongruensial perkalian

Untuk nilai ilustrasi dari \(a\) Dan $m4 , menggunakan Microsoft Visual Basic \(m=2^{24}\) , \(a = 1 , 140 , 671 , 485\) , Dan \(c = 12 , 820 , 163\). Ini adalah mesin yang mendasari pembuatan angka acak dalam program Microsoft Excel.

Urutan yang digunakan oleh analis didefinisikan sebagai \(U_n=B_n/m.\). Analis dapat menginterpretasikan urutan \(U_{i}\) menjadi (kira-kira) identik dan independen terdistribusi secara seragam pada interval (0,1). Untuk mengilustrasikan algoritme, maka pertimbangkan hal berikut.

Contoh 6.1.2. Menghasilkan Nomor Acak Seragam di R. Kode berikut menunjukkan cara menghasilkan tiga angka seragam (0,1) dalam R menggunakan perintah runif. Fungsi set.seed() di R digunakan untuk membuat hasil yang dapat direproduksi saat menulis kode yang melibatkan pembuatan variabel yang mengambil nilai acak.

set.seed(2017)
U <- runif(3)
knitr::kable(U, digits=5, align = "c", col.names = "Uniform")
Uniform
0.92424
0.53718
0.46920

1.1.2 (6.1.2) Metode Transformasi Invers

Metode transformasi invers digunakan untuk membangkitkan data acak dari distribusi peluang kontinu yang diketahui bentuk fungsinya.

Dengan urutan bilangan acak seragam, kemudian diubah menjadi distribution of interest (\(F\)).

\[X_i=F^{-1}\left( U_i \right) .\]

\[F^{-1}(y) = \inf_x ~ \{ F(x) \ge y \}\]

inf singkatan dari *infimum atau batas bawah terbesar. Ini pada dasarnya adalah nilai \(x\) terkecil yang memenuhi pertidaksamaan \(\{F(x) \ge y\}\). Hasilnya adalah urutan \(X_{i}\) kira-kira iid dengan fungsi distribusi \(F\) jika \(U_{i}\) adalah iid dengan fungsi distribusi seragam ( 0 , 1 ).

Contoh 6.1.3. Menghasilkan Bilangan Acak Eksponensial. Misalkan ingin menghasilkan pengamatan dari distribusi eksponensial dengan parameter skala \(θ\) sehingga \(F(x) = 1 - e^{-x/\theta}\). Untuk menghitung transformasi invers, maka dapat menggunakan langkah-langkah berikut:

\[\begin{aligned} y = F(x) &\Leftrightarrow y = 1-e^{-x/\theta} \\ &\Leftrightarrow -\theta \ln(1-y) = x = F^{-1}(y) . \end{aligned}\]

Jadi, jika \(U\) memiliki distribusi seragam (0,1), maka \(X = -\theta \ln(1-U)\) memiliki distribusi eksponensial dengan parameter \(θ\).

Seperti pada Contoh 6.1.2 kemudian mengubahnya menjadi variabel acak terdistribusi eksponensial independen dengan rata-rata \(10\). Sebagai alternatif, menggunakan fungsi rexp pada R digunakan untuk mensimulasikan sekumpulan bilangan acak yang diambil dari distribusi eksponensial.

set.seed(2017)
U <- runif(3)
X1 <- -10*log(1-U)
set.seed(2017)
X2 <- rexp(3, rate = 1/10)

Contoh 6.1.4. Menghasilkan Angka Acak Pareto. Misalkan ingin menghasilkan pengamatan dari distribusi Pareto dengan parameter \(α\) dan \(θ\) sehingga \(F(x) = 1 - \left(\frac{\theta}{x+\theta} \right)^{\alpha}\). Untuk menghitung transformasi invers, maka dapat menggunakan langkah-langkah berikut:

\[\begin{aligned} y = F(x) &\Leftrightarrow 1-y = \left(\frac{\theta}{x+\theta} \right)^{\alpha} \\ &\Leftrightarrow \left(1-y\right)^{-1/\alpha} = \frac{x+\theta}{\theta} = \frac{x}{\theta} +1 \\ &\Leftrightarrow \theta \left((1-y)^{-1/\alpha} - 1\right) = x = F^{-1}(y) .\end{aligned}\]

Dengan demikian, \(X = \theta \left((1-U)^{-1/\alpha} - 1\right)\) memiliki distribusi Pareto dengan parameter \(α\) dan \(θ\) .

Contoh 6.1.5. Menghasilkan Bilangan Acak Bernoulli. Misalkan ingin mensimulasikan variabel acak dari distribusi Bernoulli dengan parameter \(Q= 0,85\).

Grafik fungsi distribusi kumulatif pada Gambar diatas menunjukkan bahwa fungsi kuantil dapat ditulis sebagai berikut.

\[\begin{aligned} F^{-1}(y) = \left\{ \begin{array}{cc} 0 & 0<y \leq 0.85 \\ 1 & 0.85 < y \leq 1.0 . \end{array} \right. \end{aligned}\]

Jadi, dengan transformasi invers kita dapat mendefinisikan

\[\begin{aligned} X = \left\{ \begin{array}{cc} 0 & 0<U \leq 0.85 \\ 1 & 0.85 < U \leq 1.0 \end{array} \right. \end{aligned}\]

Misalnya, ingin menghasilkan tiga angka acak untuk diperoleh

set.seed(2017)
U <- runif(3)
X <- 1*(U > 0.85)

Contoh 6.1.6. Menghasilkan Angka Acak dari Distribusi Diskrit. Pertimbangkan waktu kegagalan mesin dalam lima tahun pertama. Distribusi waktu kegagalan diberikan sebagai:

Dengan menggunakan grafik fungsi distribusi pada gambar diatas , dengan transformasi invers dapat definisikan

\[\small{ \begin{aligned} X = \left\{ \begin{array}{cc} 1 & 0<U \leq 0.1 \\ 2 & 0.1 < U \leq 0.3\\ 3 & 0.3 < U \leq 0.4\\ 4 & 0.4 < U \leq 0.8 \\ 5 & 0.8 < U \leq 1.0 . \end{array} \right. \end{aligned} }\]

Untuk variabel acak diskrit umum mungkin tidak ada urutan hasil. Misalnya, seseorang dapat memiliki salah satu dari lima jenis produk asuransi jiwa dan dapat menggunakan algoritme berikut untuk menghasilkan hasil acak:

\[{\small \begin{aligned} X = \left\{ \begin{array}{cc} \textrm{whole life} & 0<U \leq 0.1 \\ \textrm{endowment} & 0.1 < U \leq 0.3\\ \textrm{term life} & 0.3 < U \leq 0.4\\ \textrm{universal life} & 0.4 < U \leq 0.8 \\ \textrm{variable life} & 0.8 < U \leq 1.0 . \end{array} \right. \end{aligned} }\]

Analis lain dapat menggunakan prosedur alternatif seperti:

\[{\small \begin{aligned} X = \left\{ \begin{array}{cc} \textrm{whole life} & 0.9<U<1.0 \\ \textrm{endowment} & 0.7 \leq U < 0.9\\ \textrm{term life} & 0.6 \leq U < 0.7\\ \textrm{universal life} & 0.2 \leq U < 0.6 \\ \textrm{variable life} & 0 \leq U < 0.2 . \end{array} \right. \end{aligned} }\]

Kedua algoritma menghasilkan (dalam jangka panjang) probabilitas yang sama, misalnya, \(\Pr(\textrm{whole life})=0.1\) , Dan seterusnya. Jadi, tidak ada yang salah ini menunjukkan bahwa ada lebih dari satu cara untuk mencapai suatu tujuan. Demikian pula, dapat menggunakan algoritme alternatif untuk hasil yang diurutkan (seperti waktu kegagalan 1, 2, 3, 4, atau 5, di atas).

Contoh 6.1.7. Menghasilkan Angka Acak dari Distribusi Hybrid. Pertimbangkan variabel acak yaitu 0 dengan probabilitas 70% dan terdistribusi secara eksponensial dengan parameter \(\theta= 10,000\) dengan probabilitas 30%. Dalam aplikasi asuransi, ini mungkin sesuai dengan peluang 70% tidak memiliki klaim asuransi dan peluang klaim 30% - jika klaim terjadi, maka itu didistribusikan secara eksponensial. Fungsi distribusi, digambarkan pada gambar dibawah ini , diberikan sebagai

\[\begin{aligned} F(y) = \left\{ \begin{array}{cc} 0 & x<0 \\ 1 - 0.3 \exp(-x/10000) & x \ge 0 . \end{array} \right. \end{aligned}\]

Dari Gambar diatas dapat dilihat bahwa transformasi invers untuk membangkitkan variabel acak dengan fungsi distribusi ini adalah

\[\begin{aligned} X = F^{-1}(U) = \left\{ \begin{array}{cc} 0 & 0< U \leq 0.7 \\ -1000 \ln (\frac{1-U}{0.3}) & 0.7 < U < 1 . \end{array} \right. \end{aligned}\]

1.1.3 (6.1.3) Presisi Simulasi

Setelah mengetahui cara menghasilkan realisasi simulasi independen dari distribusi bunga, maka dapat menyusun distribusi empiris (distribusi empiris mengelompokkan data ke dalam suatu interval, di mana frekuensi data dalam setiap interval dapat digunakan untuk menentukan frekuensi relatifnya) dan memperkirakan distribusi yang diperlukan.

Banyak dari aplikasi ini dapat direduksi menjadi masalah perkiraan \(\mathrm{E~}[h(X)]\) , Di mana \(h(\cdot)\) adalah beberapa fungsi yang diketahui. Berdasarkan simulasi R (replikasi), sehingga didapatkan \(X_1,\ldots,X_R\). Dari sampel yang disimulasikan ini, dapat menghitung rata-rata sebagai berikut.

\[\overline{h}_R=\frac{1}{R}\sum_{i=1}^{R} h(X_i)\]

sebagai perkiraan simulasi dari \(\mathrm{E~}[h(X)]\). Untuk memperkirakan ketepatan perkiraan tersebut, maka menggunakan varians simulasi

\[s_{h,R}^2 = \frac{1}{R-1} \sum_{i=1}^{R}\left( h(X_i) -\overline{h}_R \right) ^2.\]

Dari independensi, kesalahan standar estimasi adalah \(s_{h,R}/\sqrt{R}\). Kesalahan standar estimasi dapat dibuat sekecil dengan meningkatkan jumlah replikasi \(R\).

Contoh 6.1.8. Manajemen portofolio. Pada Bagian 3.4 telah mempelajari cara menghitung nilai ekspektasi polis dengan deductible. Sebagai contoh dari sesuatu yang tidak dapat dilakukan dengan ekspresi bentuk tertutup, kemudian akan mempertimbangkan dua risiko. (Ini adalah variasi dari contoh yang lebih kompleks yang akan dibahas sebagai Contoh 10.3.6).

Dengan mempertimbangkan dua risiko properti dari perusahaan telekomunikasi:

  • \(X_1\) - bangunan, dimodelkan menggunakan distribusi gamma dengan rata-rata 200 dan parameter skala 100.

  • \(X_2\) - kendaraan bermotor, dimodelkan menggunakan distribusi gamma dengan mean 400 dan parameter skala 200.

Nyatakan risiko total sebagai \(X = X_1 + X_2\). Untuk penyederhanaan, dapat diasumsikan bahwa risiko ini tidak bergantung.

Untuk mengelola risiko maka diperlukan perlindungan atau penjamin asuransi dan bersedia mempertahankan jumlah bangunan dan kendaraan bermotor kecil secara internal, hingga \(M\). Jumlah acak lebih dari \(M\) akan memiliki pengaruh yang tidak terduga pada anggaran dan karenanya untuk jumlah ini dapat mencari perlindungan asuransi. Dinyatakan secara matematis, risiko yang dipertahankan adalah \(Y_{retained}=\min(X_1 + X_2,M)\) dan bagian penanggung adalah \(Y_{insurer} = X- Y_{retained}\).

Misalnya \(M= 400\) serta \(R = 1000000\).

A. Dengan pengaturan tersebut, ingin menentukan perkiraan jumlah klaim dan standar deviasi terkait dari (i) yang ditahan, (ii) yang diterima oleh perusahaan asuransi, dan (iii) total jumlah keseluruhan.

# Simulate the risks
nSim <- 1e6  #number of simulations
set.seed(2017) #set seed to reproduce work 
X1 <- rgamma(nSim ,alpha1,scale = theta1)  
X2 <- rgamma(nSim ,alpha2,scale = theta2) 

# Portfolio Risks
X         <- X1 + X2 
Yretained <- pmin(X, M)
Yinsurer  <- X - Yretained

Kemudian jumlah klaim yang diharapkan adalah

# Expected Claim Amounts
ExpVec <- t(as.matrix(c(mean(Yretained),mean(Yinsurer),mean(X))))
sdVec <- t(as.matrix(c(sd(Yretained),sd(Yinsurer),sd(X))))
outMat <- rbind(ExpVec, sdVec)
colnames(outMat) <- c("Retained", "Insurer","Total")
row.names(outMat) <- c("Mean","Standard Deviation")
round(outMat,digits=2)

B. Untuk klaim yang diasuransikan, kesalahan standar perkiraan simulasi adalah \(s_{h,R}/\sqrt{1000000} =/\sqrt{1000000} =0.281\). Untuk contoh ini, simulasi cepat dan nilai yang besar seperti 1000000 adalah pilihan yang mudah. Namun, untuk masalah yang lebih kompleks, ukuran simulasi mungkin menjadi masalah.

Yinsurefct <- function(numSim){
X1 <- rgamma(numSim,alpha1,scale = theta1)  
X2 <- rgamma(numSim,alpha2,scale = theta2)  
# Portfolio Risks
X         <- X1 + X2 
Yinsurer <- X - pmin(X, M)
return(Yinsurer)
}
R <- 1e3
nPath <- 20
set.seed(2017)
simU <- matrix(Yinsurefct(R*nPath),R,nPath)
sumP2 <- apply(simU, 2, cumsum)/(1:R)
matplot(1:R,sumP2[,1:20],type="l",col=rgb(1,0,0,.2), ylim=c(100, 400),
        xlab=expression(paste("Number of Simulations (", italic('R'), ")")), 
        ylab="Expected Insurer Claims")
abline(h=mean(Yinsurer),lty=2)
bonds <- cbind(1.96*sd(Yinsurer)*sqrt(1/(1:R)),-1.96*sd(Yinsurer)*sqrt(1/(1:R)))
matlines(1:R,bonds+mean(Yinsurer),col="red",lty=1)

Dari grafik diatas dapat dilihat, semakin banyak jumlah simulasi R maka semakin sedikit jumlah klaim yang diharapkan.

Penentuan Jumlah Simulasi

Misalkan ingin berada dalam 1% dari rata-rata dengan kepastian 95%. Artinya, \(\Pr \left( |\overline{h}_R - \mathrm{E~}[h(X)]| \le 0.01 \mathrm{E~}[h(X)] \right) \ge 0.95\). Menurut teorema limit pusat, perkiraan harus terdistribusi secara normal dan mengharapkan R cukup besar untuk \(0.01 \mathrm{E~}[h(X)]/\sqrt{\mathrm{Var~}[h(X)]/R}) \ge 1.96\) . (Ingat bahwa 1,96 adalah persentil ke-97,5 dari distribusi normal standar.) Mengganti \(\mathrm{E~}[h(X)]\) Dan \(\mathrm{Var~}[h(X)]\) dengan estimasi,sehingga

\[\frac{.01\overline{h}_R}{s_{h,R}/\sqrt{R}}\geq 1.96\]

\[\begin{equation} R \geq 38,416\frac{s_{h,R}^2}{\overline{h}_R^2}. \tag{6.1} \end{equation}\]

Contoh 6.1.9. Pilihan Perkiraan.

Sebuah aplikasi penting dari simulasi adalah pendekatan dari \(\mathrm{E~}[h(X)]\). Dalam contoh ini, kami menunjukkan bahwa pilihan dari \(h(\cdot)\) fungsi dan distribusi \(X\) dapat berperan.

Pertimbangkan pertanyaan berikut: apa itu \(\Pr[X>2]\). Kapan \(X\) mempunyai sebuah distribusi Cauchy (distribusi probabilitas kontinu), dengan fungsi kepadatan \(f(x) =\left(\pi(1+x^2)\right)^{-1}\), pada garis sebenarnya? Nilai sebenarnya adalah

\[\Pr\left[X>2\right] = \int_2^\infty \frac{dx}{\pi(1+x^2)} .\]

true_value <- integrate(function(x) 1/(pi*(1+x^2)),lower=2,upper=Inf)$value
true_value 
## [1] 0.1475836

Perkiraan 1. Sebagai alternatif, seseorang dapat menggunakan teknik simulasi untuk memperkirakan besaran tersebut. Dari kalkulus, dapat memeriksa bahwa fungsi kuantil dari distribusi Cauchy adalah \(F^{-1}(y) = \tan \left( \pi(y-0.5) \right)\) . Kemudian, dengan variasi seragam (0,1) yang disimulasikan, \(U_1, \ldots, U_R\), sehingga dapat membangun estimator

Q <- function(u) tan(pi*(u-.5))
R <- 1e6
set.seed(1)
X <- Q(runif(R))
p1 <- mean(X>2)
se.p1 <- sd(X>2)/sqrt(R)
p1
## [1] 0.147439
se.p1
## [1] 0.0003545432

Dengan satu juta simulasi, diperoleh estimasi sebesar 0,14744 dengan standard error 0,355 (dibagi 1000). Dapat dibuktikan bahwa varian dari \(P_1\) teratur \(0.127/R\).

Perkiraan 2. Dengan pilihan lain dari \(h(\cdot)\) Dan \(f(\cdot)\) adalah mungkin untuk mengurangi ketidakpastian bahkan dengan menggunakan jumlah simulasi yang sama \(R\) . Untuk memulai, seseorang dapat menggunakan simetri distribusi Cauchy untuk menulis \(\Pr[X>2]=0.5\cdot\Pr[|X|>2]\) . Dengan ini, dapat membuat estimator baru

\[p_2 = \frac{1}{2R}\sum_{i=1}^R \mathrm{I}(|F^{-1}(U_i)|>2) .\]

Dengan satu juta simulasi, diperoleh estimasi sebesar 0,14748 dengan standard error 0,228 (dibagi 1000). Dapat dibuktikan bahwa varian dari \(P_2\) teratur \(0.052/R\).

Perkiraan 3. Integral tak wajar dapat ditulis dengan sifat simetri sederhana (karena fungsinya simetris dan integral pada garis real sama dengan 1 ).

\[\int_2^\infty \frac{dx}{\pi(1+x^2)}=\frac{1}{2}-\int_0^2\frac{dx}{\pi(1+x^2)} .\]

\[p_3 = \frac{1}{2}-\frac{1}{R}\sum_{i=1}^R h_3(2U_i), ~~~~~~\text{where}~h_3(x)=\frac{2}{\pi(1+x^2)} .\]

Dengan satu juta simulasi, diperoleh estimasi sebesar 0,14756 dengan standard error 0,169 (dibagi 1000). Dapat dibuktikan bahwa varian dari \(P_3\) teratur \(0,0285 / R\).

Perkiraan 4. Akhirnya, seseorang juga dapat mempertimbangkan beberapa perubahan variabel dalam integral.

\[\int_2^\infty \frac{dx}{\pi(1+x^2)}=\int_0^{1/2}\frac{y^{-2}dy}{\pi(1-y^{-2})} .\]

\[p_4 = \frac{1}{R}\sum_{i=1}^R h_4(U_i/2),~~~~~\text{where}~h_4(x)=\frac{1}{2\pi(1+x^2)} .\]

Dengan satu juta simulasi, diperoleh estimasi sebesar 0,14759 dengan standard error 0,01 (dibagi 1000). Dapat dibuktikan bahwa varian dari \(P_4\) teratur \(0,00009 / R\) , yang jauh lebih kecil dari yang lainnya.

Tabel berikut merupakan rangkuman dari empat pilihan \(h(\cdot)\) Dan \(f(\cdot)\)) untuk memperkirakan \(\Pr[X>2] = 0,14758\). Kesalahan standar bervariasi. Jadi, jika memiliki tingkat akurasi yang diinginkan, maka jumlah simulasi sangat bergantung pada bagaimana menulis integral yang akan diaproksimasi.

1.1.4 (6.1.4) imulasi dan Inferensi Statistik

Simulasi tidak hanya membantu dalam memperkirakan nilai yang diharapkan tetapi juga berguna dalam menghitung aspek lain dari fungsi distribusi. Secara khusus, ini sangat berguna ketika distribusi statistik uji terlalu rumit untuk diturunkan. Dalam hal ini, seseorang dapat menggunakan simulasi untuk memperkirakan distribusi referensi.

Contoh 6.1.10. Uji Distribusi Kolmogorov-Smirnov.

Misalkan terdapata \(n = 100\) observasi \(\{x_1,\cdots,x_n\}\) yang, tidak diketahui oleh analis, dihasilkan dari distribusi gamma dengan parameter \(\alpha = 6\) Dan \(\theta=2\) . Analis percaya bahwa data berasal dari distribusi lognormal dengan parameter 1 dan 0,4 dan ingin menguji asumsi ini.

set.seed(1)
n <- 100
x <- rgamma(n, 6, 2)

u=seq(0,7,by=.01)
vx = c(0,sort(x))
vy = (0:n)/n
par(mfrow=c(1,2))
hist(x,probability = TRUE,main="Histogram", col="light blue",
     border="white",xlim=c(0,7),ylim=c(0,.4))
lines(u,dlnorm(u,1,.4),col="red",lty=2)
plot(vx,vy,type="l",xlab="x",ylab="Cumulative Distribution",main="Empirical cdf")
lines(u,plnorm(u,1,.4),col="red",lty=2)

Dari grafik diatas dapat dilihat bahwa garis putus-putus merah tersebut sesuai dengan distribusi lognormal yang dihipotesiskan.

Perlu digaris bawahi bahwa statistik Kolmogorov-Smirnov sama dengan perbedaan terbesar antara distribusi empiris dan hipotesis. Ini \(\max_x |F_n(x)-F_0(x)|\), Di mana \(F_0\) adalah distribusi lognormal yang dihipotesiskan, sehingga

# test statistic
D <- function(data, F0){
   F <- Vectorize(function(x) mean((data<=x)))
   n <- length(data)
   x <- sort(data)
   d1=abs(F(x+1e-6)-F0(x+1e-6))
   d2=abs(F(x-1e-6)-F0(x-1e-6))
   return(max(c(d1,d2)))
}
D(x,function(x) plnorm(x,1,.4))
## [1] 0.09703627
ks.test(x, plnorm, mean=1, sd=0.4)
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  x
## D = 0.097037, p-value = 0.3031
## alternative hypothesis: two-sided

Secara khusus, untuk menghitung P-value, maka hasilkan ribuan sampel acak dari \(LN(1,0.4)\) distribusi (dengan ukuran yang sama), dan menghitung secara empiris distribusi statistik,

ns <- 1e4
d_KS <- rep(NA,ns)
# compute the test statistics for a large (ns) number of simulated samples
for(s in 1:ns) d_KS[s] <- D(rlnorm(n,1,.4),function(x) plnorm(x,1,.4))

mean(d_KS>D(x,function(x) plnorm(x,1,.4)))
## [1] 0.2843
hist(d_KS,probability = TRUE,col="light blue",border="white",xlab="Test Statistic",main="")
lines(density(d_KS),col="red")
abline(v=D(x,function(x) plnorm(x,1,.4)),lty=2,col="red")

Distribusi yang disimulasikan berdasarkan 10.000 sampel acak dirangkum grafik diatas. Di sini, statistik melebihi nilai empiris (0,09704) dalam 28,43%, sedangkan P-value adalah 0,3031. Baik untuk simulasi maupun teoretis P-value, kesimpulannya adalah data tidak memberikan bukti yang cukup untuk menolak hipotesis distribusi lognormal.

Meskipun hanya perkiraan, pendekatan simulasi bekerja dalam berbagai distribusi dan uji statistik tanpa perlu mengembangkan nuansa teori yang mendasari untuk setiap situasi. Berikut ringkasan prosedur untuk mengembangkan distribusi simulasi dan p-value sebagai berikut:

  1. Gambarlah sampel berukuran n , katakanlah, \(X_1, \ldots, X_n\), dari fungsi distribusi yang diketahui \(F\). Hitung statistik minat, dilambangkan sebagai \(\hat{\theta}(X_1, \ldots, X_n)\). Panggil ini \(\hat{\theta}^r\) untuk replikasi ke -r .

  2. Ulangi ini \(r=1, \ldots, R\) kali untuk mendapatkan sampel statistik, \(\hat{\theta}^1, \ldots,\hat{\theta}^R\).

  3. Dari sampel statistik pada Langkah 2, \(\{\hat{\theta}^1, \ldots,\hat{\theta}^R\}\), hitung ukuran ringkasan minat, seperti p-value.

1.2 (6.2) Bootstrap dan Resampling

Subbab ini akan mempelajari :

  1. Hasilkan distribusi bootstrap nonparametrik untuk statistik minat

  2. Gunakan distribusi bootstrap untuk menghasilkan estimasi presisi untuk statistik yang diminati, termasuk bias, standar deviasi, dan interval kepercayaan

  3. Lakukan analisis bootstrap untuk distribusi parametrik

1.2.1 (6.2.1) Dasar-dasar Bootstrap

Metode bootstrap adalah metode berbasis resampling data sampel dengan syarat pengembalian pada datanya dalam menyelesaikan statistik ukuran suatu sampel dengan harapan sampel tersebut mewakili data populai sebenarnya, biasanya ukuran resampling diambil secara ribuan kali agar dapat mewakili data populasinya. Algoritma resamplign umum dengan \(\{X_1, \ldots, X_n\}\) untuk menunjukkan sampel asli dan \(\{X_1^*, \ldots, X_n^*\}\) menunjukkan undian yang disimulasikan.

Untuk setiap sampel, \(n\) merupakan undian simulasi, jumlah yang sama dengan ukuran sampel asli. Untuk membedakan prosedur ini dari simulasi, biasanya digunakan \(B\) (untuk bootstrap) sebagai jumlah sampel yang disimulasikan. Sehingga dapat dituliskan \(\{X_1^{(b)}, \ldots, X_n^{(b)}\}\).

Ada dua metode resampling dasar, model-free dan model-based , masing-masing sebagai nonparametrik dan parametrik . Pengundian yang disimulasikan berasal dari fungsi distribusi empiris \(F_n(\cdot)\) , jadi setiap undian berasal \(\{X_1, \ldots, X_n\}\) dengan probabilitas \(1/n\).

Bootstrap Nonparametrik

Gagasan bootstrap nonparametrik adalah menggunakan metode transformasi terbalik \(F_N\) , fungsi distribusi kumulatif empiris, digambarkan pada grafik dibawah ini.

Karena \(F_N\) adalah step-function, \(F_n^{-1}\) subtitusi nilai-nilai \(\{x_1,\cdots,x_n\}\) sehingga

  1. jika \(y\in(0,1/n)\) (dengan probabilitas \(1 / n\) ) dengan menggambar nilai terkecil ( \(\min\{x_i\}\) )

  2. jika \(y\in(1/n,2/n)\) (dengan probabilitas \(1 / n\) ) dengan menggambar nilai terkecil kedua,

…

  1. jika \(y\in((n-1)/n,1)\) (dengan probabilitas \(1 / n\) ) kami menggambar nilai terbesar ( \(\max\{x_i\}\) )

Menggunakan metode transformasi terbalik dengan \(F_N\) berarti pengambilan sampel dari \(\{x_1,\cdots,x_n\}\), dengan probabilitas \(1 / n\) . Menghasilkan sampel ukuran bootstrap \(B\) berarti pengambilan sampel dari \(\{x_1,\cdots,x_n\}\) , dengan probabilitas \(1 / n\) , dengan penggantian.

set.seed(1)
n <- 10
x <- rexp(n, 1/6)
m <- 8
bootvalues <- sample(x, size=m, replace=TRUE)

1.2.2 (6.2.2) Presisi Bootstrap: Bias, Standar Deviasi, dan Mean Square Error

Berikut adalah rangkuman prosedur bootstrap nonparametrik sebagai berikut:

  1. Dari sampel \(\{X_1, \ldots, X_n\}\), gambar sampel berukuran n (dengan penggantian), katakanlah, \(X_1^*, \ldots, X_n^*\) . Dari undian yang disimulasikan, hitung statistik minat, dilambangkan sebagai \(\hat{\theta}(X_1^*, \ldots, X_n^*)\) . Panggil ini \(\hat{\theta}_b^*\) untuk ulangan ke-b .

  2. Ulangi ini \(b=1, \ldots, B\) kali untuk mendapatkan sampel statistik \(\hat{\theta}_1^*, \ldots,\hat{\theta}_B^*\).

  3. Dari sampel statistik pada Langkah 2,\(\{\hat{\theta}_1^*, \ldots, \hat{\theta}_B^*\}\) hitung ukuran ringkasan minat.

Pada bagian ini, ada tiga langkah ringkasan yaitu bias, standar deviasi, dan mean square error ( MSE ). Tabel dibawah ini merangkum ketiga ukuran. Di Sini, \(\overline{\hat{\theta^*}}\) adalah rata-rata dari \(\{\hat{\theta}_1^*, \ldots,\hat{\theta}_B^*\}\).

# Example from Derrig et al
BIData <- read.csv("Data/DerrigResampling.csv", header =T)
BIData$Censored <- 1*(BIData$AmountPaid >= BIData$PolicyLimit)
BIDataUncensored <- subset(BIData, Censored == 0)
LER.boot <- function(ded, data, indices){
  resample.data <- data[indices,]
  sumClaims <- sum(resample.data$AmountPaid)
  sumClaims_d <- sum(pmin(resample.data$AmountPaid,ded))
  LER <-   sumClaims_d/sumClaims
  return(LER)  
}

##Derrig et al
set.seed(2019)
dVec2 <- c(4000, 5000, 10500, 11500, 14000, 18500)
OutBoot <- matrix(0,length(dVec2),6)
  for (i in 1:length(dVec2)) {
OutBoot[i,1] <- dVec2[i]
results <- boot(data=BIDataUncensored, statistic=LER.boot, R=1000, ded=dVec2[i])
OutBoot[i,2] <- results$t0
biasboot <- mean(results$t)-results$t0 -> OutBoot[i,3]
sdboot <- sd(results$t) -> OutBoot[i,4]
temp <- boot.ci(results)
OutBoot[i,5] <- temp$normal[2]
OutBoot[i,6] <- temp$normal[3]
}

Berdasarkan tabel diatas hasil estimasi bootstrap. Misalnya, di D= 14000 , estimasi nonparametrik LER adalah 0,97678. Ini memiliki perkiraan bias 0,00018 dengan standar deviasi 0,00701. Untuk beberapa aplikasi, mungkin ingin menerapkan estimasi bias ke estimasi asli untuk memberikan estimator yang dikoreksi bias. Untuk ilustrasi ini, biasnya kecil sehingga koreksi semacam itu tidak relevan.

Standar deviasi bootstrap memberikan ukuran presisi. Untuk satu penerapan standar deviasi dapat menggunakan pendekatan normal untuk membuat selang kepercayaan. Misalnya, pada R fungsi boot.ci menghasilkan interval kepercayaan normal sebesar 95%. Ini dihasilkan dengan membuat interval dua kali panjang standar deviasi bootstrap 1,95994, berpusat di sekitar estimator yang dikoreksi bias (1,95994 adalah kuantil ke-97,5 dari distribusi normal). Misalnya, CI 95% normal yang lebih rendah di \(D= 14000\) adalah \((0.97678-0.00018)- 1.95994*0.00701\).

Contoh 6.2.2. Memperkirakan \(\exp(\mu)\) . Bootstrap dapat digunakan untuk mengukur bias estimator, misalnya. Pertimbangkan di sini sampel \(\mathbf{x}=\{x_1,\cdots,x_n\}\) adalah rata-rata μ .

sample_x <- c(2.46,2.80,3.28,3.86,2.85,3.67,3.37,3.40,5.22,2.55,
              2.79,4.50,3.37,2.88,1.44,2.56,2.00,2.07,2.19,1.77)

Misalkan kuantitas bunga adalah \(\theta=\exp(\mu)\). Penaksir alami akan menjadi \(\widehat{\theta}_1=\exp(\overline{x})\). Estimator ini bias (karena ketidaksetaraan Jensen) tetapi tidak bias secara asimtotik. Untuk sampel, perkiraannya adalah sebagai berikuT

(theta_1 <- exp(mean(sample_x)))
## [1] 19.13463

Seseorang dapat menggunakan teorema limit pusat untuk mendapatkan koreksi menggunakan

\[\overline{X}\approx\mathcal{N}\left(\mu,\frac{\sigma^2}{n}\right)\text{ where }\sigma^2=\text{Var}[X_i] ,\]

sehingga dengan fungsi pembangkit momen normal didapatkan

\[\mathrm{E}~\left[\exp(\overline{X})\right] \approx \exp\left(\mu+\frac{\sigma^2}{2n}\right) .\]

Oleh karena itu, seseorang dapat mempertimbangkan secara alami

\[\widehat{\theta}_2=\exp\left(\overline{x}-\frac{\widehat{\sigma}^2}{2n}\right) .\]

n <- length(sample_x)
(theta_2 <- exp(mean(sample_x)-var(sample_x)/(2*n)))
## [1] 18.73334

Sebagai strategi lain, seseorang juga dapat menggunakan pendekatan Taylor untuk mendapatkan penaksir yang lebih akurat (seperti dalam metode delta)

\[g(\overline{x})=g(\mu)+(\overline{x}-\mu)g'(\mu)+(\overline{x}-\mu)^2\frac{g''(\mu)}{2}+\cdots\]

Alternatif selanjutnya adalah menggunakan strategi bootstrap dengan sampel bootstrap \(\mathbf{x}^{\ast}_{b}\) sehingga \(\overline{x}^{\ast}_{b}\).

\[\widehat{\theta}_3=\frac{1}{B}\sum_{b=1}^B\exp(\overline{x}^{\ast}_{b}) .\]

library(boot)
results <- boot(data=sample_x, 
                statistic=function(y,indices) exp(mean(y[indices])), 
                R=1000)
theta_3 <- mean(results$t)

Ini menghasilkan tiga estimator, estimator mentah \(\widehat{\theta}_1=19.135\), koreksi urutan kedua \(\widehat{\theta}_2= 18.733\), dan estimator bootstrap \(\widehat{\theta}_3= 19.388\).

Bagaimana cara kerjanya dengan ukuran sampel yang berbeda? Diasumsikan bahwa \(X_i\) dihasilkan dari distribusi lognormal \(LN(0,1)\) , sehingga \(\mu = \exp(0 + 1/2) = 1.648721\) Dan \(\theta = \exp(1.648721)= 5,200326\). Dengan menggunakan simulasi untuk menggambar ukuran sampel.

param <- function(x){
  n <- length(x)
  theta_1 <- exp(mean(x))
  theta_2 <- exp(mean(x)-var(x)/(2*n))
  results <- boot(data=x, 
                statistic=function(y,indices) exp(mean(y[indices])), 
                R=999)
  theta_3 <- mean(results$t)
  return(c(theta_1,theta_2,theta_3))
}
set.seed(2074)
ns<- 200
est <- function(n){
call_param <- function(i) param(rlnorm(n,0,1))
V <- Vectorize(call_param)(1:ns)
apply(V,1,median)
}
VN=seq(15,100,by=5)
Est <- Vectorize(est)(VN)
matplot(VN,t(Est),type="l", col=2:4, lty=2:4, ylim=exp(exp(1/2))+c(-1,1),
        xlab="sample size (n)", ylab="estimator")
abline(h=exp(exp(1/2)),lty=1, col=1)
legend("topleft", c("raw estimator", "second order correction", "bootstrap"),
       col=2:4,lty=2:4, bty="n")

Hasil perbandingan dirangkum dalam gambar diatas menunjukkan bahwa estimator bootstrap mendekati nilai parameter sebenarnya untuk hampir semua ukuran sampel. Bias dari ketiga estimator berkurang dengan meningkatnya ukuran sampel.

1.2.3 (6.2.3) Interval Keyakinan

Prosedur bootstrap menghasilkan \(B\) bentuk ulang dari \(\hat{\theta}_1^*, \ldots,\hat{\theta}_B^*\) dari penaksir \(\hat{\theta}\) . Dalam Contoh 6.2.1, dapat dilihat bagaimana menggunakan pendekatan normal standar untuk membuat interval kepercayaan untuk parameter yang diinginkan. Namun, mengingat poin utamanya adalah menggunakan bootstrapping untuk menghindari ketergantungan pada asumsi perkiraan normalitas, tidak mengherankan jika tersedia interval kepercayaan alternatif.

Untuk estimator \(\hat{\theta}\) , interval kepercayaan bootstrap dasar adalah

\[\begin{equation} \left(2 \hat{\theta} - q_U, 2 \hat{\theta} - q_L \right) , \tag{6.2} \end{equation}\]

Di mana \(q_L\) Dan \(q_U\) adalah kuantil 2,5% bawah dan atas dari sampel bootstrap \(\hat{\theta}_1^*, \ldots,\hat{\theta}_B^*\)

Untuk melihat dari mana asalnya, mula-mula \((q_L, q_U)\) menyediakan interval 95% untuk \(\hat{\theta}_1^*, \ldots,\hat{\theta}_B^*\) . Jadi, untuk acak \(\hat{\theta}_b^*\), ada kemungkinan 95% itu \(q_L \le \hat{\theta}_b^* \le q_U\). Membalikkan pertidaksamaan dan menjumlahkan \(\hat{\theta}\) ke setiap sisi memberikan interval 95%

\[\hat{\theta} -q_U \le \hat{\theta} - \hat{\theta}_b^* \le \hat{\theta} -q_L .\]

Jadi, \(\left( \hat{\theta}-q_U, \hat{\theta} -q_L\right)\) adalah interval 95% untuk \(\hat{\theta} - \hat{\theta}_b^*\). Ide perkiraan bootstrap mengatakan bahwa ini juga merupakan interval 95% untuk \(\theta - \hat{\theta}\). Dengan menambahkan \(\hat{\theta}\) ke setiap sisi memberikan interval 95% dalam persamaan diatas.

Banyak alternatif interval bootstrap yang tersedia. Yang paling mudah dijelaskan adalah interval bootstrap persentil yang didefinisikan sebagai \((q_L,q_U)\).

Contoh 6.2.3. Klaim Cidera Tubuh dan Tindakan Risiko. Untuk melihat bagaimana interval kepercayaan bootstrap bekerja, dengan kembali ke klaim otomatis cedera tubuh yang dipertimbangkan dalam Contoh 6.2.1 . Alih-alih rasio eliminasi kerugian, misalkan ingin memperkirakan persentil ke-95 \(F^{-1}(0.95)\) dan ukuran didefinisikan sebagai

\[TVaR_{0.95}[X] = \mathrm{E}[X | X > F^{-1}(0.95)] .\]

Pengukuran ini disebut dengan ekor nilai berisiko; itu adalah nilai yang diharapkan dari X bersyarat X melebihi persentil ke-95. Bagian 10.2 menjelaskan bagaimana quantiles dan tail value-at-risk adalah dua contoh paling penting dari apa yang disebut sebagai ukuran risiko . Untuk saat ini, hanya akan menganggap ini sebagai ukuran yang ingin diperkirakan. Untuk persentil, dengan menggunakan estimator nonparametrik \(F^{-1}_n(0.95)\) didefinisikan dalam Bagian 4.1.1.3 . Untuk tail value-at-risk, menggunakan prinsip plug-in untuk menentukan estimator nonparametrik

\[TVaR_{n,0.95}[X] = \frac{\sum_{i=1}^n X_i I(X_i > F^{-1}_n(0.95))}{\sum_{i=1}^n I(X_i > F^{-1}_n(0.95))} ~.\]

Dalam ungkapan ini, penyebut menghitung jumlah pengamatan yang melebihi persentil ke-95 \(F^{-1}_n(0.95)\) . Pembilang menjumlahkan kerugian untuk pengamatan yang melebihi \(F^{-1}_n(0.95)\) . Tabel dibawah ini merangkum penaksir untuk pecahan terpilih.

# Example from Derrig et al
#BIData <- read.csv("Data/DerrigResampling.csv", header =T)
BIData$Censored <- 1*(BIData$AmountPaid >= BIData$PolicyLimit)
BIDataUncensored <- subset(BIData, Censored == 0)

set.seed(2017)
PercentVec <- c(0.50, 0.80, 0.90, 0.95, 0.98)
OutBoot1 <- matrix(0,5,10)
for (i in 1:length(PercentVec)) {
OutBoot1[i,1] <- PercentVec[i]
results <- boot(data=BIDataUncensored$AmountPaid,
                statistic=function(X,indices)
                    quantile(X[indices],PercentVec[i]),
                 R=1000)
if (i==1){bootreal <- results$t}
OutBoot1[i,2] <- results$t0
OutBoot1[i,3] <- mean(results$t)-results$t0 
OutBoot1[i,4] <- sd(results$t) 
temp <- boot.ci(results, type = c("norm", "basic", "perc"))
OutBoot1[i,5] <- temp$normal[2]
OutBoot1[i,6] <- temp$normal[3]
OutBoot1[i,7] <- temp$basic[4]
OutBoot1[i,8] <- temp$basic[5]
OutBoot1[i,9] <- temp$percent[4]
OutBoot1[i,10] <- temp$percent[5]
}

Misalnya, ketika pecahannya adalah 0,50, dapat melihat bahwa kuantil 2,5 bawah dan atas dari simulasi bootstrap adalah \(q_L= 6000\) dan \(q_U= 6700\). Ini membentuk interval kepercayaan bootstrap persentil. Dengan estimator nonparametrik \(6500\), ini menghasilkan batas bawah dan atas interval kepercayaan dasar masing-masing \(6300\) dan \(7000\).

CTE.boot <- function(data, indices, RiskLevel){
  resample.data <- data[indices,]
  X <- resample.data$AmountPaid
  cutoff <- quantile(X, RiskLevel)
  CTE <- sum(X*(X > cutoff))/sum(X > cutoff)
  return(CTE) 
}

set.seed(2017)  
PercentVec <- c(0.50, 0.80, 0.90, 0.95, 0.98)
OutBoot1 <- matrix(0,5,10)
  for (i in 1:length(PercentVec)) {
OutBoot1[i,1] <- PercentVec[i]
results <- boot(data=BIDataUncensored, statistic=CTE.boot, R=1000, RiskLevel=PercentVec[i])
OutBoot1[i,2] <- results$t0
OutBoot1[i,3] <- mean(results$t)-results$t0 
OutBoot1[i,4] <- sd(results$t) 
temp <- boot.ci(results, type = c("norm", "basic", "perc"))
OutBoot1[i,5] <- temp$normal[2]
OutBoot1[i,6] <- temp$normal[3]
OutBoot1[i,7] <- temp$basic[4]
OutBoot1[i,8] <- temp$basic[5]
OutBoot1[i,9] <- temp$percent[4]
OutBoot1[i,10] <- temp$percent[5]
  }

Tabel di atas menunjukkan kalkulasi serupa untuk tail value-at-risk. Dalam setiap kasus, dapat melihat bahwa deviasi standar bootstrap meningkat seiring dengan peningkatan fraksi. Hal ini karena ada lebih sedikit pengamatan untuk memperkirakan kuantil seiring meningkatnya fraksi, yang menyebabkan ketidaktepatan yang lebih besar. Interval kepercayaan juga menjadi lebih lebar. Menariknya, tampaknya tidak ada pola yang sama dalam estimasi bias tersebut.

1.2.4 (6.2.4) Bootstrap Parametrik

Gagasan dari bootstrap nonparametrik adalah untuk mengambil sampel ulang dengan menggambar variabel independen dari fungsi distribusi kumulatif empiris \(F_n\). Sebaliknya, dengan bootstrap parametrik, kami menarik variabel independen dari \(F_{\widehat{\theta}}\) di mana distribusi yang mendasarinya diasumsikan dalam keluarga parametrik \(\mathcal{F}=\{F_{\theta},\theta\in\Theta\}\) . Biasanya, parameter dari distribusi ini diperkirakan berdasarkan sampel dan dinotasikan sebagai \(\hat{\theta}\).

contoh 6.2.4. distribusi lognormal. Pertimbangkan lagi kumpulan datanya

sample_x <- c(2.46,2.80,3.28,3.86,2.85,3.67,3.37,3.40,
              5.22,2.55,2.79,4.50,3.37,2.88,1.44,2.56,2.00,2.07,2.19,1.77)

Bootstrap klasik (nonparametrik) didasarkan pada contoh berikut.

x <- sample(sample_x,replace=TRUE)

Sebagai gantinya, untuk bootstrap parametrik harus mengasumsikan bahwa distribusi dari \(x_i\) adalah dari kelompok tertentu. Sebagai contoh, kode berikut menggunakan distribusi lognormal.

library(MASS)
fit <- fitdistr(sample_x, dlnorm, list(meanlog = 1, sdlog = 1))
fit

x <- rlnorm(length(sample_x), meanlog=fit$estimate[1], sdlog=fit$estimate[2])
set.seed(2074)
CV <- matrix(NA,1e5,2)
for(s in 1:nrow(CV)){
x1 <- sample(sample_x,replace=TRUE)
x2 <- rlnorm(length(sample_x), meanlog=fit$estimate[1], sdlog=fit$estimate[2])
CV[s,] <- c(sd(x1)/mean(x1),sd(x2)/mean(x2))
}
plot(density(CV[,1]),col="red",main="",xlab="Coefficient of Variation", lty=1)
lines(density(CV[,2]),col="blue",lty=2)
abline(v=sd(sample_x)/mean(sample_x),lty=3)
legend("topright",c("nonparametric","parametric(LN)"),
       col=c("red","blue"),lty=1:2,bty="n"

Grafik di atas membandingkan distribusi bootstrap untuk koefisien variasi, yang satu berdasarkan pendekatan nonparametrik dan yang lainnya berdasarkan pendekatan parametrik, dengan asumsi distribusi lognormal.

Contoh 6.2.5. Pengamatan yang Disensor Bootstrap.

Bootstrap parametrik menarik realisasi simulasi dari perkiraan parametrik dari fungsi distribusi. Dengan cara yang sama, sehingga dapat menggambar realisasi simulasi dari estimasi fungsi distribusi. Sebagai salah satu contoh, dengan mengambil dari estimasi yang dihaluskan dari fungsi distribusi yang diperkenalkan di Bagian 4.1.1.4 . Kasus khusus lainnya, yang dipertimbangkan di sini adalah menggambar estimasi dari estimator Kaplan-Meier yang dibahas di Bagian 4.3.2.2. Dengan cara ini, dapat ditangani pengamatan yang disensor.

Secara khusus, kembali ke data cedera tubuh pada Contoh 6.2.1 dan 6.2.3 tetapi sekarang menyertakan 17 klaim yang disensor oleh batasan kebijakan. Dalam Contoh 4.3.6 menggunakan kumpulan data lengkap ini untuk mengestimasi estimator Kaplan-Meier dari fungsi survival yang diperkenalkan di Bagian 4.3.2.2 . Tabel 6.6 menyajikan estimasi bootstrap kuantil dari estimator fungsi survival Kaplan-Meier. Ini termasuk perkiraan presisi bootstrap, bias dan standar deviasi, serta interval kepercayaan dasar 95%.

# Example from Derrig et al
library(survival)                # for Surv(), survfit()
BIData$UnCensored <- 1*(BIData$AmountPaid < BIData$PolicyLimit)
## KM estimate
KM0 <- survfit(Surv(AmountPaid, UnCensored) ~ 1,  
               type="kaplan-meier", data=BIData)

set.seed(2019)
PercentVec <- c(0.50, 0.80, 0.90, 0.95, 0.98)
OutBoot1 <- matrix(NA,5,6)
KM.survobj <- Surv(BIData$AmountPaid, BIData$UnCensored) 
for (i in 1:length(PercentVec)) {
OutBoot1[i,1] <- PercentVec[i]
results <- bootkm(KM.survobj, q=1-PercentVec[i], B=1000, pr = FALSE)
if (i==1){bootreal <- results}
OutBoot1[i,2] <- quantile(KM0, PercentVec[i])$quantile
OutBoot1[i,3] <- mean(results)-OutBoot1[i,2]
OutBoot1[i,4] <- sd(results) 
# temp <- boot.ci(results, type = c("norm",  "basic","perc"))
OutBoot1[i,5] <- 2*OutBoot1[i,2]-quantile(results,.975, type=6)
OutBoot1[i,6] <- 2*OutBoot1[i,2]-quantile(results,.025, type=6)
}

Hasil pada tabel di atas konsisten dengan hasil untuk subsampel tanpa sensor pada Tabel 6.4 . Pada tabel di atas tercatat kesulitan dalam memperkirakan kuantil pada pecahan besar karena penyensoran. Namun, untuk fraksi berukuran sedang (0,50, 0,80, dan 0,90), estimasi nonparametrik Kaplan-Meier (KM NP) dari kuantil konsisten dengan Tabel 6.4 . Standar Deviasi bootstrap lebih kecil pada 0,50 (sesuai dengan median) tetapi lebih besar pada level 0,80 dan 0,90. Analisis data tersensor yang dirangkum dalam tabel di atas menggunakan lebih banyak data daripada analisis subsampel tanpa sensor pada Tabel 6.4 , tetapi juga mengalami kesulitan dalam mengekstraksi informasi untuk kuantil besar.

LS0tDQp0aXRsZTogIlRFT1JJIFJJU0lLTyINCnN1YnRpdGxlOiAiV0VFSyA2Ig0KYXV0aG9yOiAiQnJpZ2l0YSBUaWFyYSBFbGdpdHlhbmEgTWVsYW50aWthICgyMDIwNDkyMDAwMSkiDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy5EYXRlKCksICclQiAlZCwgJVknKWAiDQpvdXRwdXQ6IA0KICBodG1sX2RvY3VtZW50OiANCiAgICBodG1sX2RvY3VtZW50OiBudWxsDQogICAgY29kZV9mb2xkaW5nOiBzaG93DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6DQogICAgICBjb2xsYXBzZWQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgdGhlbWU6IHNhbmRzdG9uZQ0KICAgIGNzczogc3R5bGUxLmNzcw0KICAgIGhpZ2hsaWdodDogcHlnbWVudHMNCi0tLQ0KDQpgYGB7ciBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGNsYXNzLnNvdXJjZSA9ICJub2NvcHkiLA0KICAgICAgICAgICAgICAgICAgICAgIGNsYXNzLm91dHB1dCA9ICJub2NvcHkiLA0KICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGLA0KICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGKQ0KYGBgDQoNCjxpbWcgc3R5bGU9ImZsb2F0OiByaWdodDsgbWFyZ2luOiAwcHggMTAwcHggMHB4IDBweDsgd2lkdGg6MjUlIiBzcmM9ImZvdG9iYXJ1a3UuanBlZyIvPiANCg0KYGBge3IgbG9nbywgZWNobz1GQUxTRSxmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aCA9ICczMCUnfQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoImxvZ29tYXRhbmEucG5nIikNCmBgYA0KDQpFbWFpbCAmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsmbmJzcDs6ICBicmlnaXRhLm1lbGFudGlrYUBzdHVkZW50Lm1hdGFuYXVuaXZlcnNpdHkuYWMuaWQgPGJyPg0KUlB1YnMgICZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOzogaHR0cHM6Ly9ycHVicy5jb20vYnJpZ2l0YXRpYXJhZW0vIDxicj4NCkp1cnVzYW4gJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOzogW1N0YXRpc3Rpa2FdKGh0dHBzOi8vbWF0YW5hdW5pdmVyc2l0eS5hYy5pZC8/bHk9YWNhZGVtaWMmYz1zYikgPGJyPg0KQWRkcmVzcyAgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7IDogQVJBIENlbnRlciwgTWF0YW5hIFVuaXZlcnNpdHkgVG93ZXIgPGJyPg0KJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsmbmJzcDsgSmwuIENCRCBCYXJhdCBLYXYsIFJULjEsIEN1cnVnIFNhbmdlcmVuZywgS2VsYXBhIER1YSwgVGFuZ2VyYW5nLCBCYW50ZW4gMTU4MTAuDQoNCioqKioNCg0KIyBCQUIgNiBTSU1VTEFTSSBEQU4gUEVOR0FNQklMQU4gU0FNUEVMIFVMQU5HDQoNCi0gQmFnaWFuIDYuMSBtZW1wZXJrZW5hbGthbiBzaW11bGFzaSwgYWxhdCBrb21wdXRhc2kgbHVhciBiaWFzYSB5YW5nIHNhbmdhdCBiZXJndW5hIGRhbGFtIHBlbmdhdHVyYW4gbXVsdGl2YXJpYXQgeWFuZyBrb21wbGVrcy4NCg0KLSBCYWdpYW4gNi4yIG1lbXBlcmtlbmFsa2FuIHJlc2FtcGxpbmcgZGFsYW0ga29udGVrcyBib290c3RyYXAgdW50dWsgbWVuZW50dWthbiBrZXRlcGF0YW4gZXN0aW1hdG9yLiBSZXNhbXBsaW5nIG1lcnVwYWthbiBwcm9zZXMgc2ltdWxhc2kgdW50dWsgbWVuZ2dhbWJhciBkYXJpIGRpc3RyaWJ1c2kgZW1waXJpcy4NCg0KIyMgKDYuMSkgRGFzYXItRGFzYXIgU2ltdWxhc2kNCg0KMS4gTWVuZ2hhc2lsa2FuIHNla2l0YXIgcmVhbGlzYXNpIGluZGVwZW5kZW4geWFuZyB0ZXJkaXN0cmlidXNpIHNlY2FyYSBtZXJhdGENCg0KMi4gVWJhaCByZWFsaXNhc2kgeWFuZyB0ZXJkaXN0cmlidXNpIHNlY2FyYSBzZXJhZ2FtIG1lbmphZGkgcGVuZ2FtYXRhbiBkYXJpIGRpc3RyaWJ1c2kgcHJvYmFiaWxpdGFzIHlhbmcgbWVuYXJpaw0KDQozLiBIaXR1bmcganVtbGFoIGJ1bmdhIGRhbiB0ZW50dWthbiBrZXRlcGF0YW4ganVtbGFoIHlhbmcgZGloaXR1bmcNCg0KDQojIyMgKDYuMS4xKSBNZW5naGFzaWxrYW4gUGVuZ2FtYXRhbiBTZXJhZ2FtIEluZGVwZW5kZW4NCg0KYEdlbmVyYXRvciBLb25ncnVlbnNpIExpbmllci5gIA0KDQpMaW5lYXIgQ29uZ3J1ZW50aWFsIEdlbmVyYXRvcnMgKExDRykgYWRhbGFoIHNlYnVhaCBtZXRvZGUgeWFuZyBtZW1iYW5na2l0a2FuIGJpbGFuZ2FuIGFjYWsgeWFuZyBiYW55YWsgZGlwZXJndW5ha2FuIGRhbGFtIHByb2dyYW0ga29tcHV0ZXIuIFBhZGEgbWV0b2RlIGluaSwgZGlsYWt1a2FuIHBlcnVsYW5nYW4gcGFkYSBwZXJpb2RlIHdha3R1IHRlcnRlbnR1IGF0YXUgc2V0ZWxhaCBzZWtpYW4ga2FsaSBwZW1iYW5na2l0YW4uVW50dWsgbWVuZ2hhc2lsa2FuIHVydXRhbiBhbmdrYSBhY2FrLCBtdWxhaWxhaCBkZW5nYW4gJEJfMCQgLCBuaWxhaSBhd2FsIHlhbmcgZGlrZW5hbCBzZWJhZ2FpICdzZWVkJyAuIE5pbGFpIGluaSBkaXBlcmJhcnVpIG1lbmdndW5ha2FuIGh1YnVuZ2FuIHJla3Vyc2lmDQoNCiQkQl97bisxfSA9IChhIEJfbiArIGMpICBcdGV4dHsgbW9kdWxvIH1tLCB+fiBuPTAsIDEsIDIsIFxsZG90cyAuJCQNCg0KQWxnb3JpdG1hIGluaSBkaXNlYnV0ICRhJC4gS2FzdXMgJGMgPSAwJCBkaXNlYnV0IGdlbmVyYXRvciBrb25ncnVlbnNpYWwgcGVya2FsaWFuDQoNClVudHVrIG5pbGFpIGlsdXN0cmFzaSBkYXJpICRhJCBEYW4gJG00ICwgbWVuZ2d1bmFrYW4gTWljcm9zb2Z0IFZpc3VhbCBCYXNpYyAgJG09Ml57MjR9JCAsICRhID0gMSAsIDE0MCAsIDY3MSAsIDQ4NSQgLCBEYW4gJGMgPSAxMiAsIDgyMCAsIDE2MyQuIEluaSBhZGFsYWggbWVzaW4geWFuZyBtZW5kYXNhcmkgcGVtYnVhdGFuIGFuZ2thIGFjYWsgZGFsYW0gcHJvZ3JhbSBNaWNyb3NvZnQgRXhjZWwuDQoNClVydXRhbiB5YW5nIGRpZ3VuYWthbiBvbGVoIGFuYWxpcyBkaWRlZmluaXNpa2FuIHNlYmFnYWkgJFVfbj1CX24vbS4kLiBBbmFsaXMgZGFwYXQgbWVuZ2ludGVycHJldGFzaWthbiB1cnV0YW4gJFVfe2l9JCBtZW5qYWRpIChraXJhLWtpcmEpIGlkZW50aWsgZGFuIGluZGVwZW5kZW4gdGVyZGlzdHJpYnVzaSBzZWNhcmEgc2VyYWdhbSBwYWRhIGludGVydmFsICgwLDEpLiBVbnR1ayBtZW5naWx1c3RyYXNpa2FuIGFsZ29yaXRtZSwgbWFrYSBwZXJ0aW1iYW5na2FuIGhhbCBiZXJpa3V0Lg0KDQpgYGB7ciBpbWFnZTEsIGVjaG89RkFMU0UsIGZpZy5jYXA9IiIsZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnMTAwJSd9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiZW5hbXNhdHUucG5nIikNCmBgYA0KDQpgQ29udG9oIDYuMS4yLmAgTWVuZ2hhc2lsa2FuIE5vbW9yIEFjYWsgU2VyYWdhbSBkaSBfUl8uIEtvZGUgYmVyaWt1dCBtZW51bmp1a2thbiBjYXJhIG1lbmdoYXNpbGthbiB0aWdhIGFuZ2thIHNlcmFnYW0gKDAsMSkgZGFsYW0gUiBtZW5nZ3VuYWthbiBwZXJpbnRhaCBfcnVuaWZfLiBGdW5nc2kgX3NldC5zZWVkKClfIGRpIFIgZGlndW5ha2FuIHVudHVrIG1lbWJ1YXQgaGFzaWwgeWFuZyBkYXBhdCBkaXJlcHJvZHVrc2kgc2FhdCBtZW51bGlzIGtvZGUgeWFuZyBtZWxpYmF0a2FuIHBlbWJ1YXRhbiB2YXJpYWJlbCB5YW5nIG1lbmdhbWJpbCBuaWxhaSBhY2FrLg0KDQpgYGB7cn0NCnNldC5zZWVkKDIwMTcpDQpVIDwtIHJ1bmlmKDMpDQprbml0cjo6a2FibGUoVSwgZGlnaXRzPTUsIGFsaWduID0gImMiLCBjb2wubmFtZXMgPSAiVW5pZm9ybSIpDQpgYGANCg0KIyMjICg2LjEuMikgTWV0b2RlIFRyYW5zZm9ybWFzaSBJbnZlcnMNCg0KTWV0b2RlIHRyYW5zZm9ybWFzaSBpbnZlcnMgZGlndW5ha2FuIHVudHVrIG1lbWJhbmdraXRrYW4gZGF0YSBhY2FrIGRhcmkgZGlzdHJpYnVzaSBwZWx1YW5nIGtvbnRpbnUgeWFuZyBkaWtldGFodWkgYmVudHVrIGZ1bmdzaW55YS4NCg0KRGVuZ2FuIHVydXRhbiBiaWxhbmdhbiBhY2FrIHNlcmFnYW0sIGtlbXVkaWFuIGRpdWJhaCBtZW5qYWRpIGRpc3RyaWJ1dGlvbiBvZiBpbnRlcmVzdCAoJEYkKS4NCg0KJCRYX2k9Rl57LTF9XGxlZnQoIFVfaSBccmlnaHQpIC4kJA0KDQokJEZeey0xfSh5KSA9IFxpbmZfeCB+IFx7IEYoeCkgXGdlIHkgXH0kJA0KDQpfaW5mXyBzaW5na2F0YW4gZGFyaSAqaW5maW11bSBhdGF1IGJhdGFzIGJhd2FoIHRlcmJlc2FyLiBJbmkgcGFkYSBkYXNhcm55YSBhZGFsYWggbmlsYWkgJHgkIHRlcmtlY2lsIHlhbmcgbWVtZW51aGkgcGVydGlkYWtzYW1hYW4gJFx7Rih4KSBcZ2UgeVx9JC4gSGFzaWxueWEgYWRhbGFoIHVydXRhbiAkWF97aX0kIGtpcmEta2lyYSBpaWQgZGVuZ2FuIGZ1bmdzaSBkaXN0cmlidXNpICRGJCBqaWthICRVX3tpfSQgYWRhbGFoIGlpZCBkZW5nYW4gZnVuZ3NpIGRpc3RyaWJ1c2kgc2VyYWdhbSAoIDAgLCAxICkuDQoNCmBDb250b2ggNi4xLjMuYCBNZW5naGFzaWxrYW4gQmlsYW5nYW4gQWNhayBFa3Nwb25lbnNpYWwuIE1pc2Fsa2FuIGluZ2luIG1lbmdoYXNpbGthbiBwZW5nYW1hdGFuIGRhcmkgZGlzdHJpYnVzaSBla3Nwb25lbnNpYWwgZGVuZ2FuIHBhcmFtZXRlciBza2FsYSAkzrgkIHNlaGluZ2dhICRGKHgpID0gMSAtIGVeey14L1x0aGV0YX0kLiBVbnR1ayBtZW5naGl0dW5nIHRyYW5zZm9ybWFzaSBpbnZlcnMsIG1ha2EgZGFwYXQgbWVuZ2d1bmFrYW4gbGFuZ2thaC1sYW5na2FoIGJlcmlrdXQ6DQoNCiQkXGJlZ2lue2FsaWduZWR9DQogeSA9IEYoeCkgJlxMZWZ0cmlnaHRhcnJvdyAgeSA9IDEtZV57LXgvXHRoZXRhfSBcXA0KICAmXExlZnRyaWdodGFycm93IC1cdGhldGEgXGxuKDEteSkgPSB4ID0gRl57LTF9KHkpIC4NClxlbmR7YWxpZ25lZH0kJA0KDQpKYWRpLCBqaWthICRVJCBtZW1pbGlraSBkaXN0cmlidXNpIHNlcmFnYW0gKDAsMSksIG1ha2EgJFggPSAtXHRoZXRhIFxsbigxLVUpJCBtZW1pbGlraSBkaXN0cmlidXNpIGVrc3BvbmVuc2lhbCBkZW5nYW4gcGFyYW1ldGVyICTOuCQuDQoNClNlcGVydGkgcGFkYSBDb250b2ggNi4xLjIga2VtdWRpYW4gbWVuZ3ViYWhueWEgbWVuamFkaSB2YXJpYWJlbCBhY2FrIHRlcmRpc3RyaWJ1c2kgZWtzcG9uZW5zaWFsIGluZGVwZW5kZW4gZGVuZ2FuIHJhdGEtcmF0YSAkMTAkLiBTZWJhZ2FpIGFsdGVybmF0aWYsICBtZW5nZ3VuYWthbiBmdW5nc2kgX3JleHBfIHBhZGEgUiBkaWd1bmFrYW4gdW50dWsgbWVuc2ltdWxhc2lrYW4gc2VrdW1wdWxhbiBiaWxhbmdhbiBhY2FrIHlhbmcgZGlhbWJpbCBkYXJpIGRpc3RyaWJ1c2kgZWtzcG9uZW5zaWFsLg0KDQpgYGB7cn0NCnNldC5zZWVkKDIwMTcpDQpVIDwtIHJ1bmlmKDMpDQpYMSA8LSAtMTAqbG9nKDEtVSkNCnNldC5zZWVkKDIwMTcpDQpYMiA8LSByZXhwKDMsIHJhdGUgPSAxLzEwKQ0KYGBgDQoNCmBgYHtyIGltYWdlMiwgZWNobz1GQUxTRSwgZmlnLmNhcD0iIixmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aCA9ICcxMDAlJ30NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCI2LjEuMi0xLnBuZyIpDQpgYGANCg0KYENvbnRvaCA2LjEuNC5gIE1lbmdoYXNpbGthbiBBbmdrYSBBY2FrIFBhcmV0by4gTWlzYWxrYW4gaW5naW4gbWVuZ2hhc2lsa2FuIHBlbmdhbWF0YW4gZGFyaSBkaXN0cmlidXNpIFBhcmV0byBkZW5nYW4gcGFyYW1ldGVyICTOsSQgZGFuICAkzrgkIHNlaGluZ2dhICRGKHgpID0gMSAtIFxsZWZ0KFxmcmFje1x0aGV0YX17eCtcdGhldGF9IFxyaWdodClee1xhbHBoYX0kLiBVbnR1ayBtZW5naGl0dW5nIHRyYW5zZm9ybWFzaSBpbnZlcnMsIG1ha2EgZGFwYXQgbWVuZ2d1bmFrYW4gbGFuZ2thaC1sYW5na2FoIGJlcmlrdXQ6DQoNCiQkXGJlZ2lue2FsaWduZWR9DQogeSA9IEYoeCkgJlxMZWZ0cmlnaHRhcnJvdyAxLXkgPSBcbGVmdChcZnJhY3tcdGhldGF9e3grXHRoZXRhfSBccmlnaHQpXntcYWxwaGF9IFxcDQogICZcTGVmdHJpZ2h0YXJyb3cgXGxlZnQoMS15XHJpZ2h0KV57LTEvXGFscGhhfSA9IFxmcmFje3grXHRoZXRhfXtcdGhldGF9ID0gXGZyYWN7eH17XHRoZXRhfSArMSBcXA0KICAgICZcTGVmdHJpZ2h0YXJyb3cgXHRoZXRhIFxsZWZ0KCgxLXkpXnstMS9cYWxwaGF9IC0gMVxyaWdodCkgPSB4ID0gRl57LTF9KHkpIC5cZW5ke2FsaWduZWR9JCQNCg0KRGVuZ2FuIGRlbWlraWFuLCAkWCA9IFx0aGV0YSBcbGVmdCgoMS1VKV57LTEvXGFscGhhfSAtIDFccmlnaHQpJCBtZW1pbGlraSBkaXN0cmlidXNpIFBhcmV0byBkZW5nYW4gcGFyYW1ldGVyICTOsSQgZGFuICTOuCQgLg0KDQpgQ29udG9oIDYuMS41LmAgTWVuZ2hhc2lsa2FuIEJpbGFuZ2FuIEFjYWsgQmVybm91bGxpLiBNaXNhbGthbiBpbmdpbiBtZW5zaW11bGFzaWthbiB2YXJpYWJlbCBhY2FrIGRhcmkgZGlzdHJpYnVzaSBCZXJub3VsbGkgZGVuZ2FuIHBhcmFtZXRlciAkUT0gMCw4NSQuDQoNCmBgYHtyIGltYWdlMywgZWNobz1GQUxTRSwgZmlnLmNhcD0iIixmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aCA9ICcxMDAlJ30NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCI2LjEuMi0yLnBuZyIpDQpgYGANCkdyYWZpayBmdW5nc2kgZGlzdHJpYnVzaSBrdW11bGF0aWYgcGFkYSBHYW1iYXIgZGlhdGFzIG1lbnVuanVra2FuIGJhaHdhIGZ1bmdzaSBrdWFudGlsIGRhcGF0IGRpdHVsaXMgc2ViYWdhaSBiZXJpa3V0Lg0KDQokJFxiZWdpbnthbGlnbmVkfQ0KRl57LTF9KHkpID0gXGxlZnRceyBcYmVnaW57YXJyYXl9e2NjfQ0KICAgICAgICAgICAgICAwICYgMDx5IFxsZXEgMC44NSBcXA0KICAgICAgICAgICAgICAxICYgMC44NSA8IHkgIFxsZXEgIDEuMCAuDQogICAgICAgICAgICBcZW5ke2FycmF5fSBccmlnaHQuDQpcZW5ke2FsaWduZWR9JCQNCg0KSmFkaSwgZGVuZ2FuIHRyYW5zZm9ybWFzaSBpbnZlcnMga2l0YSBkYXBhdCBtZW5kZWZpbmlzaWthbg0KDQokJFxiZWdpbnthbGlnbmVkfQ0KWCA9IFxsZWZ0XHsgXGJlZ2lue2FycmF5fXtjY30NCiAgICAgICAgICAgICAgMCAmIDA8VSBcbGVxIDAuODUgIFxcDQogICAgICAgICAgICAgIDEgJiAgMC44NSA8IFUgIFxsZXEgIDEuMA0KICAgICAgICAgICAgXGVuZHthcnJheX0gXHJpZ2h0Lg0KXGVuZHthbGlnbmVkfSQkDQoNCk1pc2FsbnlhLCBpbmdpbiBtZW5naGFzaWxrYW4gdGlnYSBhbmdrYSBhY2FrIHVudHVrIGRpcGVyb2xlaA0KDQpgYGB7cn0NCnNldC5zZWVkKDIwMTcpDQpVIDwtIHJ1bmlmKDMpDQpYIDwtIDEqKFUgPiAwLjg1KQ0KYGBgDQoNCmBgYHtyIGltYWdlNCwgZWNobz1GQUxTRSwgZmlnLmNhcD0iIixmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aCA9ICcxMDAlJ30NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCI2LjEuMi0zLnBuZyIpDQpgYGANCmBDb250b2ggNi4xLjYuYCBNZW5naGFzaWxrYW4gQW5na2EgQWNhayBkYXJpIERpc3RyaWJ1c2kgRGlza3JpdC4gUGVydGltYmFuZ2thbiB3YWt0dSBrZWdhZ2FsYW4gbWVzaW4gZGFsYW0gbGltYSB0YWh1biBwZXJ0YW1hLiBEaXN0cmlidXNpIHdha3R1IGtlZ2FnYWxhbiBkaWJlcmlrYW4gc2ViYWdhaToNCg0KYGBge3IgaW1hZ2U1LCBlY2hvPUZBTFNFLCBmaWcuY2FwPSIiLGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoID0gJzEwMCUnfQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIjYuMS4yLTQucG5nIikNCmBgYA0KDQpgYGB7ciBpbWFnZTYsIGVjaG89RkFMU0UsIGZpZy5jYXA9IiIsZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnMTAwJSd9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiNi4xLjItNS5wbmciKQ0KYGBgDQpEZW5nYW4gbWVuZ2d1bmFrYW4gZ3JhZmlrIGZ1bmdzaSBkaXN0cmlidXNpIHBhZGEgZ2FtYmFyIGRpYXRhcyAsIGRlbmdhbiB0cmFuc2Zvcm1hc2kgaW52ZXJzIGRhcGF0IGRlZmluaXNpa2FuDQoNCiQkXHNtYWxsew0KXGJlZ2lue2FsaWduZWR9DQpYID0gXGxlZnRceyBcYmVnaW57YXJyYXl9e2NjfQ0KICAgICAgICAgICAgICAxICYgICAwPFUgIFxsZXEgMC4xICBcXA0KICAgICAgICAgICAgICAyICYgIDAuMSA8IFUgIFxsZXEgIDAuM1xcDQogICAgICAgICAgICAgIDMgJiAgMC4zIDwgVSAgXGxlcSAgMC40XFwNCiAgICAgICAgICAgICAgNCAmICAwLjQgPCBVICBcbGVxICAwLjggIFxcDQogICAgICAgICAgICAgIDUgJiAgMC44IDwgVSAgXGxlcSAgMS4wICAgICAuDQogICAgICAgICAgICBcZW5ke2FycmF5fSBccmlnaHQuDQpcZW5ke2FsaWduZWR9DQp9JCQNCg0KVW50dWsgdmFyaWFiZWwgYWNhayBkaXNrcml0IHVtdW0gbXVuZ2tpbiB0aWRhayBhZGEgdXJ1dGFuIGhhc2lsLiBNaXNhbG55YSwgc2VzZW9yYW5nIGRhcGF0IG1lbWlsaWtpIHNhbGFoIHNhdHUgZGFyaSBsaW1hIGplbmlzIHByb2R1ayBhc3VyYW5zaSBqaXdhIGRhbiBkYXBhdCBtZW5nZ3VuYWthbiBhbGdvcml0bWUgYmVyaWt1dCB1bnR1ayBtZW5naGFzaWxrYW4gaGFzaWwgYWNhazoNCg0KJCR7XHNtYWxsDQpcYmVnaW57YWxpZ25lZH0NClggPSBcbGVmdFx7IFxiZWdpbnthcnJheX17Y2N9DQogIFx0ZXh0cm17d2hvbGUgbGlmZX0gJiAgIDA8VSAgXGxlcSAwLjEgIFxcDQogXHRleHRybXtlbmRvd21lbnR9ICYgIDAuMSA8IFUgIFxsZXEgIDAuM1xcDQpcdGV4dHJte3Rlcm0gbGlmZX0gJiAgMC4zIDwgVSAgXGxlcSAgMC40XFwNCiAgXHRleHRybXt1bml2ZXJzYWwgbGlmZX0gJiAgMC40IDwgVSAgXGxlcSAgMC44ICBcXA0KICBcdGV4dHJte3ZhcmlhYmxlIGxpZmV9ICYgIDAuOCA8IFUgIFxsZXEgIDEuMCAuDQogICAgICAgICAgICBcZW5ke2FycmF5fSBccmlnaHQuDQpcZW5ke2FsaWduZWR9DQp9JCQNCg0KQW5hbGlzIGxhaW4gZGFwYXQgbWVuZ2d1bmFrYW4gcHJvc2VkdXIgYWx0ZXJuYXRpZiBzZXBlcnRpOg0KDQokJHtcc21hbGwNClxiZWdpbnthbGlnbmVkfQ0KWCA9IFxsZWZ0XHsgXGJlZ2lue2FycmF5fXtjY30NCiAgXHRleHRybXt3aG9sZSBsaWZlfSAmICAgMC45PFU8MS4wICBcXA0KIFx0ZXh0cm17ZW5kb3dtZW50fSAmICAwLjcgXGxlcSBVIDwgMC45XFwNClx0ZXh0cm17dGVybSBsaWZlfSAmICAwLjYgXGxlcSBVIDwgMC43XFwNCiAgXHRleHRybXt1bml2ZXJzYWwgbGlmZX0gJiAgMC4yIFxsZXEgVSA8IDAuNiAgXFwNCiAgXHRleHRybXt2YXJpYWJsZSBsaWZlfSAmICAwIFxsZXEgVSA8IDAuMiAuDQogICAgICAgICAgICBcZW5ke2FycmF5fSBccmlnaHQuDQpcZW5ke2FsaWduZWR9DQp9JCQNCg0KS2VkdWEgYWxnb3JpdG1hIG1lbmdoYXNpbGthbiAoZGFsYW0gamFuZ2thIHBhbmphbmcpIHByb2JhYmlsaXRhcyB5YW5nIHNhbWEsIG1pc2FsbnlhLCAkXFByKFx0ZXh0cm17d2hvbGUgbGlmZX0pPTAuMSQgLCBEYW4gc2V0ZXJ1c255YS4gSmFkaSwgdGlkYWsgYWRhIHlhbmcgc2FsYWggaW5pIG1lbnVuanVra2FuIGJhaHdhIGFkYSBsZWJpaCBkYXJpIHNhdHUgY2FyYSB1bnR1ayBtZW5jYXBhaSBzdWF0dSB0dWp1YW4uIERlbWlraWFuIHB1bGEsIGRhcGF0IG1lbmdndW5ha2FuIGFsZ29yaXRtZSBhbHRlcm5hdGlmIHVudHVrIGhhc2lsIHlhbmcgZGl1cnV0a2FuIChzZXBlcnRpIHdha3R1IGtlZ2FnYWxhbiAxLCAyLCAzLCA0LCBhdGF1IDUsIGRpIGF0YXMpLg0KDQpgQ29udG9oIDYuMS43LmAgTWVuZ2hhc2lsa2FuIEFuZ2thIEFjYWsgZGFyaSBEaXN0cmlidXNpIEh5YnJpZC4gUGVydGltYmFuZ2thbiB2YXJpYWJlbCBhY2FrIHlhaXR1IDAgZGVuZ2FuIHByb2JhYmlsaXRhcyA3MCUgZGFuIHRlcmRpc3RyaWJ1c2kgc2VjYXJhIGVrc3BvbmVuc2lhbCBkZW5nYW4gcGFyYW1ldGVyICAkXHRoZXRhPSAxMCwwMDAkIGRlbmdhbiBwcm9iYWJpbGl0YXMgMzAlLiBEYWxhbSBhcGxpa2FzaSBhc3VyYW5zaSwgaW5pIG11bmdraW4gc2VzdWFpIGRlbmdhbiBwZWx1YW5nIDcwJSB0aWRhayBtZW1pbGlraSBrbGFpbSBhc3VyYW5zaSBkYW4gcGVsdWFuZyBrbGFpbSAzMCUgLSBqaWthIGtsYWltIHRlcmphZGksIG1ha2EgaXR1IGRpZGlzdHJpYnVzaWthbiBzZWNhcmEgZWtzcG9uZW5zaWFsLiBGdW5nc2kgZGlzdHJpYnVzaSwgZGlnYW1iYXJrYW4gcGFkYSBnYW1iYXIgZGliYXdhaCBpbmkgLCBkaWJlcmlrYW4gc2ViYWdhaQ0KDQokJFxiZWdpbnthbGlnbmVkfQ0KRih5KSA9IFxsZWZ0XHsgXGJlZ2lue2FycmF5fXtjY30NCiAgICAgICAgICAgICAgMCAmICB4PDAgIFxcDQogICAgICAgICAgICAgIDEgLSAwLjMgXGV4cCgteC8xMDAwMCkgJiB4IFxnZSAwIC4NCiAgICAgICAgICAgIFxlbmR7YXJyYXl9IFxyaWdodC4NClxlbmR7YWxpZ25lZH0kJA0KDQpgYGB7ciBpbWFnZTcsIGVjaG89RkFMU0UsIGZpZy5jYXA9IiIsZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnMTAwJSd9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiNi4xLjItNi5wbmciKQ0KYGBgDQpEYXJpIEdhbWJhciBkaWF0YXMgZGFwYXQgZGlsaWhhdCBiYWh3YSB0cmFuc2Zvcm1hc2kgaW52ZXJzIHVudHVrIG1lbWJhbmdraXRrYW4gdmFyaWFiZWwgYWNhayBkZW5nYW4gZnVuZ3NpIGRpc3RyaWJ1c2kgaW5pIGFkYWxhaA0KDQokJFxiZWdpbnthbGlnbmVkfQ0KWCA9IEZeey0xfShVKSA9IFxsZWZ0XHsgXGJlZ2lue2FycmF5fXtjY30NCiAgICAgICAgICAgICAgMCAmICAwPCBVICBcbGVxICAwLjcgIFxcDQogICAgICAgICAgICAgIC0xMDAwIFxsbiAoXGZyYWN7MS1VfXswLjN9KSAmIDAuNyA8IFUgPCAxIC4NCiAgICAgICAgICAgIFxlbmR7YXJyYXl9IFxyaWdodC4NClxlbmR7YWxpZ25lZH0kJA0KDQojIyMgKDYuMS4zKSBQcmVzaXNpIFNpbXVsYXNpDQoNClNldGVsYWggIG1lbmdldGFodWkgY2FyYSBtZW5naGFzaWxrYW4gcmVhbGlzYXNpIHNpbXVsYXNpIGluZGVwZW5kZW4gZGFyaSBkaXN0cmlidXNpIGJ1bmdhLCBtYWthIGRhcGF0IG1lbnl1c3VuIGRpc3RyaWJ1c2kgZW1waXJpcyAoZGlzdHJpYnVzaSBlbXBpcmlzIG1lbmdlbG9tcG9ra2FuIGRhdGEga2UgZGFsYW0gc3VhdHUgaW50ZXJ2YWwsIGRpIG1hbmEgZnJla3VlbnNpIGRhdGEgZGFsYW0gc2V0aWFwIGludGVydmFsIGRhcGF0IGRpZ3VuYWthbiB1bnR1ayBtZW5lbnR1a2FuIGZyZWt1ZW5zaSByZWxhdGlmbnlhKSBkYW4gbWVtcGVya2lyYWthbiBkaXN0cmlidXNpIHlhbmcgZGlwZXJsdWthbi4gDQoNCkJhbnlhayBkYXJpIGFwbGlrYXNpIGluaSBkYXBhdCBkaXJlZHVrc2kgbWVuamFkaSBtYXNhbGFoIHBlcmtpcmFhbiAkXG1hdGhybXtFfn1baChYKV0kICwgRGkgbWFuYSAkaChcY2RvdCkkIGFkYWxhaCBiZWJlcmFwYSBmdW5nc2kgeWFuZyBkaWtldGFodWkuIEJlcmRhc2Fya2FuIHNpbXVsYXNpIFIgKHJlcGxpa2FzaSksIHNlaGluZ2dhIGRpZGFwYXRrYW4gJFhfMSxcbGRvdHMsWF9SJC4gRGFyaSBzYW1wZWwgeWFuZyBkaXNpbXVsYXNpa2FuIGluaSwgZGFwYXQgbWVuZ2hpdHVuZyByYXRhLXJhdGEgc2ViYWdhaSBiZXJpa3V0Lg0KDQokJFxvdmVybGluZXtofV9SPVxmcmFjezF9e1J9XHN1bV97aT0xfV57Un0gaChYX2kpJCQNCg0Kc2ViYWdhaSBwZXJraXJhYW4gc2ltdWxhc2kgZGFyaSAkXG1hdGhybXtFfn1baChYKV0kLiBVbnR1ayBtZW1wZXJraXJha2FuIGtldGVwYXRhbiBwZXJraXJhYW4gdGVyc2VidXQsIG1ha2EgbWVuZ2d1bmFrYW4gdmFyaWFucyBzaW11bGFzaQ0KDQokJHNfe2gsUn1eMiA9IFxmcmFjezF9e1ItMX0gXHN1bV97aT0xfV57Un1cbGVmdCggaChYX2kpIC1cb3ZlcmxpbmV7aH1fUg0KXHJpZ2h0KSBeMi4kJA0KDQpEYXJpIGluZGVwZW5kZW5zaSwga2VzYWxhaGFuIHN0YW5kYXIgZXN0aW1hc2kgYWRhbGFoICRzX3toLFJ9L1xzcXJ0e1J9JC4gS2VzYWxhaGFuIHN0YW5kYXIgZXN0aW1hc2kgZGFwYXQgZGlidWF0IHNla2VjaWwgZGVuZ2FuIG1lbmluZ2thdGthbiBqdW1sYWggcmVwbGlrYXNpICRSJC4NCg0KYENvbnRvaCA2LjEuOC5gIE1hbmFqZW1lbiBwb3J0b2ZvbGlvLiBQYWRhIEJhZ2lhbiAzLjQgdGVsYWggbWVtcGVsYWphcmkgY2FyYSBtZW5naGl0dW5nIG5pbGFpIGVrc3Bla3Rhc2kgcG9saXMgZGVuZ2FuIGRlZHVjdGlibGUuIFNlYmFnYWkgY29udG9oIGRhcmkgc2VzdWF0dSB5YW5nIHRpZGFrIGRhcGF0IGRpbGFrdWthbiBkZW5nYW4gZWtzcHJlc2kgYmVudHVrIHRlcnR1dHVwLCBrZW11ZGlhbiBha2FuIG1lbXBlcnRpbWJhbmdrYW4gZHVhIHJpc2lrby4gKEluaSBhZGFsYWggdmFyaWFzaSBkYXJpIGNvbnRvaCB5YW5nIGxlYmloIGtvbXBsZWtzIHlhbmcgYWthbiBkaWJhaGFzIHNlYmFnYWkgQ29udG9oIDEwLjMuNikuDQoNCkRlbmdhbiBtZW1wZXJ0aW1iYW5na2FuIGR1YSByaXNpa28gcHJvcGVydGkgZGFyaSBwZXJ1c2FoYWFuIHRlbGVrb211bmlrYXNpOiANCg0KLSAkWF8xJCAtIGJhbmd1bmFuLCBkaW1vZGVsa2FuIG1lbmdndW5ha2FuIGRpc3RyaWJ1c2kgZ2FtbWEgZGVuZ2FuIHJhdGEtcmF0YSAyMDAgZGFuIHBhcmFtZXRlciBza2FsYSAxMDAuIA0KDQotICRYXzIkIC0ga2VuZGFyYWFuIGJlcm1vdG9yLCBkaW1vZGVsa2FuIG1lbmdndW5ha2FuIGRpc3RyaWJ1c2kgZ2FtbWEgZGVuZ2FuIG1lYW4gNDAwIGRhbiBwYXJhbWV0ZXIgc2thbGEgMjAwLiANCg0KTnlhdGFrYW4gcmlzaWtvIHRvdGFsIHNlYmFnYWkgJFggPSBYXzEgKyBYXzIkLiBVbnR1ayBwZW55ZWRlcmhhbmFhbiwgZGFwYXQgZGlhc3Vtc2lrYW4gYmFod2EgcmlzaWtvIGluaSB0aWRhayBiZXJnYW50dW5nLg0KDQpVbnR1ayBtZW5nZWxvbGEgcmlzaWtvIG1ha2EgZGlwZXJsdWthbiBwZXJsaW5kdW5nYW4gYXRhdSBwZW5qYW1pbiBhc3VyYW5zaSBkYW4gYmVyc2VkaWEgbWVtcGVydGFoYW5rYW4ganVtbGFoIGJhbmd1bmFuIGRhbiBrZW5kYXJhYW4gYmVybW90b3Iga2VjaWwgc2VjYXJhIGludGVybmFsLCBoaW5nZ2EgJE0kLiBKdW1sYWggYWNhayBsZWJpaCBkYXJpICRNJCBha2FuIG1lbWlsaWtpIHBlbmdhcnVoIHlhbmcgdGlkYWsgdGVyZHVnYSBwYWRhIGFuZ2dhcmFuIGRhbiBrYXJlbmFueWEgdW50dWsganVtbGFoIGluaSBkYXBhdCBtZW5jYXJpIHBlcmxpbmR1bmdhbiBhc3VyYW5zaS4gRGlueWF0YWthbiBzZWNhcmEgbWF0ZW1hdGlzLCByaXNpa28geWFuZyBkaXBlcnRhaGFua2FuIGFkYWxhaCAkWV97cmV0YWluZWR9PVxtaW4oWF8xICsgWF8yLE0pJCBkYW4gYmFnaWFuIHBlbmFuZ2d1bmcgYWRhbGFoICRZX3tpbnN1cmVyfSA9IFgtIFlfe3JldGFpbmVkfSQuDQoNCk1pc2FsbnlhICRNPSA0MDAkIHNlcnRhICRSID0gMTAwMDAwMCQuDQoNCmBBLmAgRGVuZ2FuIHBlbmdhdHVyYW4gdGVyc2VidXQsIGluZ2luIG1lbmVudHVrYW4gcGVya2lyYWFuIGp1bWxhaCBrbGFpbSBkYW4gc3RhbmRhciBkZXZpYXNpIHRlcmthaXQgZGFyaSAoaSkgeWFuZyBkaXRhaGFuLCAoaWkpIHlhbmcgZGl0ZXJpbWEgb2xlaCBwZXJ1c2FoYWFuIGFzdXJhbnNpLCBkYW4gKGlpaSkgdG90YWwganVtbGFoIGtlc2VsdXJ1aGFuLg0KDQpgYGB7ciBldmFsID1GQUxTRX0NCiMgU2ltdWxhdGUgdGhlIHJpc2tzDQpuU2ltIDwtIDFlNiAgI251bWJlciBvZiBzaW11bGF0aW9ucw0Kc2V0LnNlZWQoMjAxNykgI3NldCBzZWVkIHRvIHJlcHJvZHVjZSB3b3JrIA0KWDEgPC0gcmdhbW1hKG5TaW0gLGFscGhhMSxzY2FsZSA9IHRoZXRhMSkgIA0KWDIgPC0gcmdhbW1hKG5TaW0gLGFscGhhMixzY2FsZSA9IHRoZXRhMikgDQoNCiMgUG9ydGZvbGlvIFJpc2tzDQpYICAgICAgICAgPC0gWDEgKyBYMiANCllyZXRhaW5lZCA8LSBwbWluKFgsIE0pDQpZaW5zdXJlciAgPC0gWCAtIFlyZXRhaW5lZA0KYGBgDQoNCktlbXVkaWFuIGp1bWxhaCBrbGFpbSB5YW5nIGRpaGFyYXBrYW4gYWRhbGFoDQpgYGB7ciBldmFsID1GQUxTRX0NCiMgRXhwZWN0ZWQgQ2xhaW0gQW1vdW50cw0KRXhwVmVjIDwtIHQoYXMubWF0cml4KGMobWVhbihZcmV0YWluZWQpLG1lYW4oWWluc3VyZXIpLG1lYW4oWCkpKSkNCnNkVmVjIDwtIHQoYXMubWF0cml4KGMoc2QoWXJldGFpbmVkKSxzZChZaW5zdXJlciksc2QoWCkpKSkNCm91dE1hdCA8LSByYmluZChFeHBWZWMsIHNkVmVjKQ0KY29sbmFtZXMob3V0TWF0KSA8LSBjKCJSZXRhaW5lZCIsICJJbnN1cmVyIiwiVG90YWwiKQ0Kcm93Lm5hbWVzKG91dE1hdCkgPC0gYygiTWVhbiIsIlN0YW5kYXJkIERldmlhdGlvbiIpDQpyb3VuZChvdXRNYXQsZGlnaXRzPTIpDQpgYGANCg0KYGBge3IgaW1hZ2U4LCBlY2hvPUZBTFNFLCBmaWcuY2FwPSIiLGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoID0gJzEwMCUnfQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIjYuMS4zLTEucG5nIikNCmBgYA0KYEIuYCBVbnR1ayBrbGFpbSB5YW5nIGRpYXN1cmFuc2lrYW4sIGtlc2FsYWhhbiBzdGFuZGFyIHBlcmtpcmFhbiBzaW11bGFzaSBhZGFsYWggJHNfe2gsUn0vXHNxcnR7MTAwMDAwMH0gPS9cc3FydHsxMDAwMDAwfSA9MC4yODEkLiBVbnR1ayBjb250b2ggaW5pLCBzaW11bGFzaSBjZXBhdCBkYW4gbmlsYWkgeWFuZyBiZXNhciBzZXBlcnRpIDEwMDAwMDAgYWRhbGFoIHBpbGloYW4geWFuZyBtdWRhaC4gTmFtdW4sIHVudHVrIG1hc2FsYWggeWFuZyBsZWJpaCBrb21wbGVrcywgdWt1cmFuIHNpbXVsYXNpIG11bmdraW4gbWVuamFkaSBtYXNhbGFoLg0KDQpgYGB7ciBldmFsID1GQUxTRX0NCllpbnN1cmVmY3QgPC0gZnVuY3Rpb24obnVtU2ltKXsNClgxIDwtIHJnYW1tYShudW1TaW0sYWxwaGExLHNjYWxlID0gdGhldGExKSAgDQpYMiA8LSByZ2FtbWEobnVtU2ltLGFscGhhMixzY2FsZSA9IHRoZXRhMikgIA0KIyBQb3J0Zm9saW8gUmlza3MNClggICAgICAgICA8LSBYMSArIFgyIA0KWWluc3VyZXIgPC0gWCAtIHBtaW4oWCwgTSkNCnJldHVybihZaW5zdXJlcikNCn0NClIgPC0gMWUzDQpuUGF0aCA8LSAyMA0Kc2V0LnNlZWQoMjAxNykNCnNpbVUgPC0gbWF0cml4KFlpbnN1cmVmY3QoUipuUGF0aCksUixuUGF0aCkNCnN1bVAyIDwtIGFwcGx5KHNpbVUsIDIsIGN1bXN1bSkvKDE6UikNCmBgYA0KDQpgYGB7ciBldmFsID1GQUxTRX0NCm1hdHBsb3QoMTpSLHN1bVAyWywxOjIwXSx0eXBlPSJsIixjb2w9cmdiKDEsMCwwLC4yKSwgeWxpbT1jKDEwMCwgNDAwKSwNCiAgICAgICAgeGxhYj1leHByZXNzaW9uKHBhc3RlKCJOdW1iZXIgb2YgU2ltdWxhdGlvbnMgKCIsIGl0YWxpYygnUicpLCAiKSIpKSwgDQogICAgICAgIHlsYWI9IkV4cGVjdGVkIEluc3VyZXIgQ2xhaW1zIikNCmFibGluZShoPW1lYW4oWWluc3VyZXIpLGx0eT0yKQ0KYm9uZHMgPC0gY2JpbmQoMS45NipzZChZaW5zdXJlcikqc3FydCgxLygxOlIpKSwtMS45NipzZChZaW5zdXJlcikqc3FydCgxLygxOlIpKSkNCm1hdGxpbmVzKDE6Uixib25kcyttZWFuKFlpbnN1cmVyKSxjb2w9InJlZCIsbHR5PTEpDQpgYGANCg0KYGBge3IgaW1hZ2U5LCBlY2hvPUZBTFNFLCBmaWcuY2FwPSIiLGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoID0gJzEwMCUnfQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIjYuMS4zLTIucG5nIikNCmBgYA0KRGFyaSBncmFmaWsgZGlhdGFzIGRhcGF0IGRpbGloYXQsIHNlbWFraW4gYmFueWFrIGp1bWxhaCBzaW11bGFzaSBSIG1ha2Egc2VtYWtpbiBzZWRpa2l0IGp1bWxhaCBrbGFpbSB5YW5nIGRpaGFyYXBrYW4uDQoNCmBQZW5lbnR1YW4gSnVtbGFoIFNpbXVsYXNpYA0KDQpNaXNhbGthbiBpbmdpbiBiZXJhZGEgZGFsYW0gMSUgZGFyaSByYXRhLXJhdGEgZGVuZ2FuIGtlcGFzdGlhbiA5NSUuIEFydGlueWEsICRcUHIgXGxlZnQoIHxcb3ZlcmxpbmV7aH1fUiAtIFxtYXRocm17RX59W2goWCldfCBcbGUgMC4wMSBcbWF0aHJte0V+fVtoKFgpXSBccmlnaHQpIFxnZSAwLjk1JC4gTWVudXJ1dCB0ZW9yZW1hIGxpbWl0IHB1c2F0LCBwZXJraXJhYW4gaGFydXMgdGVyZGlzdHJpYnVzaSBzZWNhcmEgbm9ybWFsIGRhbiBtZW5naGFyYXBrYW4gUiBjdWt1cCBiZXNhciB1bnR1ayAgJDAuMDEgXG1hdGhybXtFfn1baChYKV0vXHNxcnR7XG1hdGhybXtWYXJ+fVtoKFgpXS9SfSkgXGdlIDEuOTYkIC4gKEluZ2F0IGJhaHdhIDEsOTYgYWRhbGFoIHBlcnNlbnRpbCBrZS05Nyw1IGRhcmkgZGlzdHJpYnVzaSBub3JtYWwgc3RhbmRhci4pIE1lbmdnYW50aSAkXG1hdGhybXtFfn1baChYKV0kIERhbiAkXG1hdGhybXtWYXJ+fVtoKFgpXSQgZGVuZ2FuIGVzdGltYXNpLHNlaGluZ2dhDQoNCiQkXGZyYWN7LjAxXG92ZXJsaW5le2h9X1J9e3Nfe2gsUn0vXHNxcnR7Un19XGdlcSAxLjk2JCQNCg0KJCRcYmVnaW57ZXF1YXRpb259DQpSIFxnZXEgMzgsNDE2XGZyYWN7c197aCxSfV4yfXtcb3ZlcmxpbmV7aH1fUl4yfS4NClx0YWd7Ni4xfQ0KXGVuZHtlcXVhdGlvbn0kJA0KDQpgQ29udG9oIDYuMS45LmAgUGlsaWhhbiBQZXJraXJhYW4uIA0KDQpTZWJ1YWggYXBsaWthc2kgcGVudGluZyBkYXJpIHNpbXVsYXNpIGFkYWxhaCBwZW5kZWthdGFuIGRhcmkgJFxtYXRocm17RX59W2goWCldJC4gRGFsYW0gY29udG9oIGluaSwga2FtaSBtZW51bmp1a2thbiBiYWh3YSBwaWxpaGFuIGRhcmkgJGgoXGNkb3QpJCBmdW5nc2kgZGFuIGRpc3RyaWJ1c2kgJFgkIGRhcGF0IGJlcnBlcmFuLiANCg0KUGVydGltYmFuZ2thbiBwZXJ0YW55YWFuIGJlcmlrdXQ6IGFwYSBpdHUgJFxQcltYPjJdJC4gS2FwYW4gJFgkIG1lbXB1bnlhaSBzZWJ1YWggZGlzdHJpYnVzaSBDYXVjaHkgKGRpc3RyaWJ1c2kgcHJvYmFiaWxpdGFzIGtvbnRpbnUpLCBkZW5nYW4gZnVuZ3NpIGtlcGFkYXRhbiAkZih4KSA9XGxlZnQoXHBpKDEreF4yKVxyaWdodCleey0xfSQsIHBhZGEgZ2FyaXMgc2ViZW5hcm55YT8gTmlsYWkgc2ViZW5hcm55YSBhZGFsYWgNCg0KJCRcUHJcbGVmdFtYPjJccmlnaHRdID0gXGludF8yXlxpbmZ0eSBcZnJhY3tkeH17XHBpKDEreF4yKX0gLiQkDQoNCmBgYHtyfQ0KdHJ1ZV92YWx1ZSA8LSBpbnRlZ3JhdGUoZnVuY3Rpb24oeCkgMS8ocGkqKDEreF4yKSksbG93ZXI9Mix1cHBlcj1JbmYpJHZhbHVlDQp0cnVlX3ZhbHVlIA0KYGBgDQoNCmBQZXJraXJhYW4gMS5gIFNlYmFnYWkgYWx0ZXJuYXRpZiwgc2VzZW9yYW5nIGRhcGF0IG1lbmdndW5ha2FuIHRla25payBzaW11bGFzaSB1bnR1ayBtZW1wZXJraXJha2FuIGJlc2FyYW4gdGVyc2VidXQuIERhcmkga2Fsa3VsdXMsIGRhcGF0IG1lbWVyaWtzYSBiYWh3YSBmdW5nc2kga3VhbnRpbCBkYXJpIGRpc3RyaWJ1c2kgQ2F1Y2h5IGFkYWxhaCAkRl57LTF9KHkpID0gXHRhbiBcbGVmdCggXHBpKHktMC41KSBccmlnaHQpJCAuIEtlbXVkaWFuLCBkZW5nYW4gdmFyaWFzaSBzZXJhZ2FtICgwLDEpIHlhbmcgZGlzaW11bGFzaWthbiwgJFVfMSwgXGxkb3RzLCBVX1IkLCBzZWhpbmdnYSBkYXBhdCBtZW1iYW5ndW4gZXN0aW1hdG9yDQoNCmBgYHtyfQ0KUSA8LSBmdW5jdGlvbih1KSB0YW4ocGkqKHUtLjUpKQ0KUiA8LSAxZTYNCnNldC5zZWVkKDEpDQpYIDwtIFEocnVuaWYoUikpDQpwMSA8LSBtZWFuKFg+MikNCnNlLnAxIDwtIHNkKFg+Mikvc3FydChSKQ0KcDENCnNlLnAxDQpgYGANCg0KRGVuZ2FuIHNhdHUganV0YSBzaW11bGFzaSwgZGlwZXJvbGVoIGVzdGltYXNpIHNlYmVzYXIgMCwxNDc0NCBkZW5nYW4gc3RhbmRhcmQgZXJyb3IgMCwzNTUgKGRpYmFnaSAxMDAwKS4gRGFwYXQgZGlidWt0aWthbiBiYWh3YSB2YXJpYW4gZGFyaSAkUF8xJCB0ZXJhdHVyICQwLjEyNy9SJC4NCg0KYFBlcmtpcmFhbiAyLmAgRGVuZ2FuIHBpbGloYW4gbGFpbiBkYXJpICRoKFxjZG90KSQgRGFuICRmKFxjZG90KSQgYWRhbGFoIG11bmdraW4gdW50dWsgbWVuZ3VyYW5naSBrZXRpZGFrcGFzdGlhbiBiYWhrYW4gZGVuZ2FuIG1lbmdndW5ha2FuIGp1bWxhaCBzaW11bGFzaSB5YW5nIHNhbWEgJFIkIC4gVW50dWsgbWVtdWxhaSwgc2VzZW9yYW5nIGRhcGF0IG1lbmdndW5ha2FuIHNpbWV0cmkgZGlzdHJpYnVzaSBDYXVjaHkgdW50dWsgbWVudWxpcyAkXFByW1g+Ml09MC41XGNkb3RcUHJbfFh8PjJdJCAuIERlbmdhbiBpbmksIGRhcGF0IG1lbWJ1YXQgZXN0aW1hdG9yIGJhcnUNCg0KJCRwXzIgPSBcZnJhY3sxfXsyUn1cc3VtX3tpPTF9XlIgXG1hdGhybXtJfSh8Rl57LTF9KFVfaSl8PjIpIC4kJA0KDQpEZW5nYW4gc2F0dSBqdXRhIHNpbXVsYXNpLCBkaXBlcm9sZWggZXN0aW1hc2kgc2ViZXNhciAwLDE0NzQ4IGRlbmdhbiBzdGFuZGFyZCBlcnJvciAwLDIyOCAoZGliYWdpIDEwMDApLiBEYXBhdCBkaWJ1a3Rpa2FuIGJhaHdhIHZhcmlhbiBkYXJpICRQXzIkIHRlcmF0dXIgJDAuMDUyL1IkLg0KDQpgUGVya2lyYWFuIDMuYCBJbnRlZ3JhbCB0YWsgd2FqYXIgZGFwYXQgZGl0dWxpcyBkZW5nYW4gc2lmYXQgc2ltZXRyaSBzZWRlcmhhbmEgKGthcmVuYSBmdW5nc2lueWEgc2ltZXRyaXMgZGFuIGludGVncmFsIHBhZGEgZ2FyaXMgcmVhbCBzYW1hIGRlbmdhbiAxICkuDQoNCiQkXGludF8yXlxpbmZ0eSBcZnJhY3tkeH17XHBpKDEreF4yKX09XGZyYWN7MX17Mn0tXGludF8wXjJcZnJhY3tkeH17XHBpKDEreF4yKX0gLiQkDQoNCiQkcF8zID0gXGZyYWN7MX17Mn0tXGZyYWN7MX17Un1cc3VtX3tpPTF9XlIgaF8zKDJVX2kpLCB+fn5+fn5cdGV4dHt3aGVyZX1+aF8zKHgpPVxmcmFjezJ9e1xwaSgxK3heMil9IC4kJA0KDQpEZW5nYW4gc2F0dSBqdXRhIHNpbXVsYXNpLCBkaXBlcm9sZWggZXN0aW1hc2kgc2ViZXNhciAwLDE0NzU2IGRlbmdhbiBzdGFuZGFyZCBlcnJvciAwLDE2OSAoZGliYWdpIDEwMDApLiBEYXBhdCBkaWJ1a3Rpa2FuIGJhaHdhIHZhcmlhbiBkYXJpICRQXzMkIHRlcmF0dXIgJDAsMDI4NSAvIFIkLg0KDQpgUGVya2lyYWFuIDQuYCBBa2hpcm55YSwgc2VzZW9yYW5nIGp1Z2EgZGFwYXQgbWVtcGVydGltYmFuZ2thbiBiZWJlcmFwYSBwZXJ1YmFoYW4gdmFyaWFiZWwgZGFsYW0gaW50ZWdyYWwuDQoNCiQkXGludF8yXlxpbmZ0eSBcZnJhY3tkeH17XHBpKDEreF4yKX09XGludF8wXnsxLzJ9XGZyYWN7eV57LTJ9ZHl9e1xwaSgxLXleey0yfSl9IC4kJA0KDQokJHBfNCA9IFxmcmFjezF9e1J9XHN1bV97aT0xfV5SIGhfNChVX2kvMiksfn5+fn5cdGV4dHt3aGVyZX1+aF80KHgpPVxmcmFjezF9ezJccGkoMSt4XjIpfSAuJCQNCg0KRGVuZ2FuIHNhdHUganV0YSBzaW11bGFzaSwgZGlwZXJvbGVoIGVzdGltYXNpIHNlYmVzYXIgMCwxNDc1OSBkZW5nYW4gc3RhbmRhcmQgZXJyb3IgMCwwMSAoZGliYWdpIDEwMDApLiBEYXBhdCBkaWJ1a3Rpa2FuIGJhaHdhIHZhcmlhbiBkYXJpICRQXzQkIHRlcmF0dXIgJDAsMDAwMDkgLyBSJCAsIHlhbmcgamF1aCBsZWJpaCBrZWNpbCBkYXJpIHlhbmcgbGFpbm55YS4NCg0KVGFiZWwgYmVyaWt1dCBtZXJ1cGFrYW4gcmFuZ2t1bWFuIGRhcmkgZW1wYXQgcGlsaWhhbiAkaChcY2RvdCkkIERhbiAkZihcY2RvdCkkKSB1bnR1ayBtZW1wZXJraXJha2FuICRcUHJbWD4yXSA9IDAsMTQ3NTgkLiBLZXNhbGFoYW4gc3RhbmRhciBiZXJ2YXJpYXNpLiBKYWRpLCBqaWthIG1lbWlsaWtpIHRpbmdrYXQgYWt1cmFzaSB5YW5nIGRpaW5naW5rYW4sIG1ha2EganVtbGFoIHNpbXVsYXNpIHNhbmdhdCBiZXJnYW50dW5nIHBhZGEgYmFnYWltYW5hICBtZW51bGlzIGludGVncmFsIHlhbmcgYWthbiBkaWFwcm9rc2ltYXNpLg0KDQpgYGB7ciBpbWFnZTEwLCBlY2hvPUZBTFNFLCBmaWcuY2FwPSIiLGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoID0gJzEwMCUnfQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIjYuMS4zLTMucG5nIikNCmBgYA0KDQojIyMgKDYuMS40KSBpbXVsYXNpIGRhbiBJbmZlcmVuc2kgU3RhdGlzdGlrDQoNClNpbXVsYXNpIHRpZGFrIGhhbnlhIG1lbWJhbnR1IGRhbGFtIG1lbXBlcmtpcmFrYW4gbmlsYWkgeWFuZyBkaWhhcmFwa2FuIHRldGFwaSBqdWdhIGJlcmd1bmEgZGFsYW0gbWVuZ2hpdHVuZyBhc3BlayBsYWluIGRhcmkgZnVuZ3NpIGRpc3RyaWJ1c2kuIFNlY2FyYSBraHVzdXMsIGluaSBzYW5nYXQgYmVyZ3VuYSBrZXRpa2EgZGlzdHJpYnVzaSBzdGF0aXN0aWsgdWppIHRlcmxhbHUgcnVtaXQgdW50dWsgZGl0dXJ1bmthbi4gRGFsYW0gaGFsIGluaSwgc2VzZW9yYW5nIGRhcGF0IG1lbmdndW5ha2FuIHNpbXVsYXNpIHVudHVrIG1lbXBlcmtpcmFrYW4gZGlzdHJpYnVzaSByZWZlcmVuc2kuDQoNCmBDb250b2ggNi4xLjEwLmAgVWppIERpc3RyaWJ1c2kgS29sbW9nb3Jvdi1TbWlybm92LiANCg0KTWlzYWxrYW4gdGVyZGFwYXRhICRuID0gMTAwJCBvYnNlcnZhc2kgJFx7eF8xLFxjZG90cyx4X25cfSQgeWFuZywgdGlkYWsgZGlrZXRhaHVpIG9sZWggYW5hbGlzLCBkaWhhc2lsa2FuIGRhcmkgZGlzdHJpYnVzaSBnYW1tYSBkZW5nYW4gcGFyYW1ldGVyICRcYWxwaGEgPSA2JCBEYW4gJFx0aGV0YT0yJCAuIEFuYWxpcyBwZXJjYXlhIGJhaHdhIGRhdGEgYmVyYXNhbCBkYXJpIGRpc3RyaWJ1c2kgbG9nbm9ybWFsIGRlbmdhbiBwYXJhbWV0ZXIgMSBkYW4gMCw0IGRhbiBpbmdpbiBtZW5ndWppIGFzdW1zaSBpbmkuDQoNCmBgYHtyfQ0Kc2V0LnNlZWQoMSkNCm4gPC0gMTAwDQp4IDwtIHJnYW1tYShuLCA2LCAyKQ0KDQp1PXNlcSgwLDcsYnk9LjAxKQ0KdnggPSBjKDAsc29ydCh4KSkNCnZ5ID0gKDA6bikvbg0KYGBgDQoNCmBgYHtyfQ0KcGFyKG1mcm93PWMoMSwyKSkNCmhpc3QoeCxwcm9iYWJpbGl0eSA9IFRSVUUsbWFpbj0iSGlzdG9ncmFtIiwgY29sPSJsaWdodCBibHVlIiwNCiAgICAgYm9yZGVyPSJ3aGl0ZSIseGxpbT1jKDAsNykseWxpbT1jKDAsLjQpKQ0KbGluZXModSxkbG5vcm0odSwxLC40KSxjb2w9InJlZCIsbHR5PTIpDQpwbG90KHZ4LHZ5LHR5cGU9ImwiLHhsYWI9IngiLHlsYWI9IkN1bXVsYXRpdmUgRGlzdHJpYnV0aW9uIixtYWluPSJFbXBpcmljYWwgY2RmIikNCmxpbmVzKHUscGxub3JtKHUsMSwuNCksY29sPSJyZWQiLGx0eT0yKQ0KYGBgDQoNCkRhcmkgZ3JhZmlrIGRpYXRhcyBkYXBhdCBkaWxpaGF0IGJhaHdhIGdhcmlzIHB1dHVzLXB1dHVzIG1lcmFoIHRlcnNlYnV0IHNlc3VhaSBkZW5nYW4gZGlzdHJpYnVzaSBsb2dub3JtYWwgeWFuZyBkaWhpcG90ZXNpc2thbi4NCg0KUGVybHUgZGlnYXJpcyBiYXdhaGkgYmFod2Egc3RhdGlzdGlrIEtvbG1vZ29yb3YtU21pcm5vdiBzYW1hIGRlbmdhbiBwZXJiZWRhYW4gdGVyYmVzYXIgYW50YXJhIGRpc3RyaWJ1c2kgZW1waXJpcyBkYW4gaGlwb3Rlc2lzLiBJbmkgJFxtYXhfeCB8Rl9uKHgpLUZfMCh4KXwkLCBEaSBtYW5hICRGXzAkIGFkYWxhaCBkaXN0cmlidXNpIGxvZ25vcm1hbCB5YW5nIGRpaGlwb3Rlc2lza2FuLCBzZWhpbmdnYQ0KDQpgYGB7cn0NCiMgdGVzdCBzdGF0aXN0aWMNCkQgPC0gZnVuY3Rpb24oZGF0YSwgRjApew0KICAgRiA8LSBWZWN0b3JpemUoZnVuY3Rpb24oeCkgbWVhbigoZGF0YTw9eCkpKQ0KICAgbiA8LSBsZW5ndGgoZGF0YSkNCiAgIHggPC0gc29ydChkYXRhKQ0KICAgZDE9YWJzKEYoeCsxZS02KS1GMCh4KzFlLTYpKQ0KICAgZDI9YWJzKEYoeC0xZS02KS1GMCh4LTFlLTYpKQ0KICAgcmV0dXJuKG1heChjKGQxLGQyKSkpDQp9DQpEKHgsZnVuY3Rpb24oeCkgcGxub3JtKHgsMSwuNCkpDQpgYGANCg0KYGBge3J9DQprcy50ZXN0KHgsIHBsbm9ybSwgbWVhbj0xLCBzZD0wLjQpDQpgYGANCg0KU2VjYXJhIGtodXN1cywgdW50dWsgbWVuZ2hpdHVuZyBQLXZhbHVlLCBtYWthIGhhc2lsa2FuIHJpYnVhbiBzYW1wZWwgYWNhayBkYXJpICRMTigxLDAuNCkkIGRpc3RyaWJ1c2kgKGRlbmdhbiB1a3VyYW4geWFuZyBzYW1hKSwgZGFuIG1lbmdoaXR1bmcgc2VjYXJhIGVtcGlyaXMgZGlzdHJpYnVzaSBzdGF0aXN0aWssDQoNCmBgYHtyfQ0KbnMgPC0gMWU0DQpkX0tTIDwtIHJlcChOQSxucykNCiMgY29tcHV0ZSB0aGUgdGVzdCBzdGF0aXN0aWNzIGZvciBhIGxhcmdlIChucykgbnVtYmVyIG9mIHNpbXVsYXRlZCBzYW1wbGVzDQpmb3IocyBpbiAxOm5zKSBkX0tTW3NdIDwtIEQocmxub3JtKG4sMSwuNCksZnVuY3Rpb24oeCkgcGxub3JtKHgsMSwuNCkpDQoNCm1lYW4oZF9LUz5EKHgsZnVuY3Rpb24oeCkgcGxub3JtKHgsMSwuNCkpKQ0KYGBgDQoNCmBgYHtyfQ0KaGlzdChkX0tTLHByb2JhYmlsaXR5ID0gVFJVRSxjb2w9ImxpZ2h0IGJsdWUiLGJvcmRlcj0id2hpdGUiLHhsYWI9IlRlc3QgU3RhdGlzdGljIixtYWluPSIiKQ0KbGluZXMoZGVuc2l0eShkX0tTKSxjb2w9InJlZCIpDQphYmxpbmUodj1EKHgsZnVuY3Rpb24oeCkgcGxub3JtKHgsMSwuNCkpLGx0eT0yLGNvbD0icmVkIikNCmBgYA0KDQpEaXN0cmlidXNpIHlhbmcgZGlzaW11bGFzaWthbiBiZXJkYXNhcmthbiAxMC4wMDAgc2FtcGVsIGFjYWsgZGlyYW5na3VtIGdyYWZpayBkaWF0YXMuIERpIHNpbmksIHN0YXRpc3RpayBtZWxlYmloaSBuaWxhaSBlbXBpcmlzICgwLDA5NzA0KSBkYWxhbSAyOCw0MyUsIHNlZGFuZ2thbiAgUC12YWx1ZSBhZGFsYWggMCwzMDMxLiBCYWlrIHVudHVrIHNpbXVsYXNpIG1hdXB1biB0ZW9yZXRpcyBQLXZhbHVlLCBrZXNpbXB1bGFubnlhIGFkYWxhaCBkYXRhIHRpZGFrIG1lbWJlcmlrYW4gYnVrdGkgeWFuZyBjdWt1cCB1bnR1ayBtZW5vbGFrIGhpcG90ZXNpcyBkaXN0cmlidXNpIGxvZ25vcm1hbC4NCg0KTWVza2lwdW4gaGFueWEgcGVya2lyYWFuLCBwZW5kZWthdGFuIHNpbXVsYXNpIGJla2VyamEgZGFsYW0gYmVyYmFnYWkgZGlzdHJpYnVzaSBkYW4gdWppIHN0YXRpc3RpayB0YW5wYSBwZXJsdSBtZW5nZW1iYW5na2FuIG51YW5zYSB0ZW9yaSB5YW5nIG1lbmRhc2FyaSB1bnR1ayBzZXRpYXAgc2l0dWFzaS4gQmVyaWt1dCByaW5na2FzYW4gcHJvc2VkdXIgdW50dWsgbWVuZ2VtYmFuZ2thbiBkaXN0cmlidXNpIHNpbXVsYXNpIGRhbiBwLXZhbHVlIHNlYmFnYWkgYmVyaWt1dDoNCg0KMS4gR2FtYmFybGFoIHNhbXBlbCBiZXJ1a3VyYW4gbiAsIGthdGFrYW5sYWgsICRYXzEsIFxsZG90cywgWF9uJCwgZGFyaSBmdW5nc2kgZGlzdHJpYnVzaSB5YW5nIGRpa2V0YWh1aSAkRiQuIEhpdHVuZyBzdGF0aXN0aWsgbWluYXQsIGRpbGFtYmFuZ2thbiBzZWJhZ2FpICRcaGF0e1x0aGV0YX0oWF8xLCBcbGRvdHMsIFhfbikkLiBQYW5nZ2lsIGluaSAkXGhhdHtcdGhldGF9XnIkIHVudHVrIHJlcGxpa2FzaSBrZSAtciAuIA0KDQoyLiBVbGFuZ2kgaW5pICRyPTEsIFxsZG90cywgUiQga2FsaSB1bnR1ayBtZW5kYXBhdGthbiBzYW1wZWwgc3RhdGlzdGlrLCAkXGhhdHtcdGhldGF9XjEsIFxsZG90cyxcaGF0e1x0aGV0YX1eUiQuIA0KDQozLiBEYXJpIHNhbXBlbCBzdGF0aXN0aWsgcGFkYSBMYW5na2FoIDIsICRce1xoYXR7XHRoZXRhfV4xLCBcbGRvdHMsXGhhdHtcdGhldGF9XlJcfSQsIGhpdHVuZyB1a3VyYW4gcmluZ2thc2FuIG1pbmF0LCBzZXBlcnRpIHAtdmFsdWUuDQoNCiMjICg2LjIpIEJvb3RzdHJhcCBkYW4gUmVzYW1wbGluZw0KDQpTdWJiYWIgaW5pIGFrYW4gbWVtcGVsYWphcmkgOg0KDQoxLiBIYXNpbGthbiBkaXN0cmlidXNpIGJvb3RzdHJhcCBub25wYXJhbWV0cmlrIHVudHVrIHN0YXRpc3RpayBtaW5hdA0KDQoyLiBHdW5ha2FuIGRpc3RyaWJ1c2kgYm9vdHN0cmFwIHVudHVrIG1lbmdoYXNpbGthbiBlc3RpbWFzaSBwcmVzaXNpIHVudHVrIHN0YXRpc3RpayB5YW5nIGRpbWluYXRpLCB0ZXJtYXN1ayBiaWFzLCBzdGFuZGFyIGRldmlhc2ksIGRhbiBpbnRlcnZhbCBrZXBlcmNheWFhbg0KDQozLiBMYWt1a2FuIGFuYWxpc2lzIGJvb3RzdHJhcCB1bnR1ayBkaXN0cmlidXNpIHBhcmFtZXRyaWsNCg0KIyMjICg2LjIuMSkgRGFzYXItZGFzYXIgQm9vdHN0cmFwDQoNCk1ldG9kZSBib290c3RyYXAgYWRhbGFoIG1ldG9kZSBiZXJiYXNpcyByZXNhbXBsaW5nIGRhdGEgc2FtcGVsIGRlbmdhbiBzeWFyYXQgcGVuZ2VtYmFsaWFuIHBhZGEgZGF0YW55YSBkYWxhbSBtZW55ZWxlc2Fpa2FuIHN0YXRpc3RpayB1a3VyYW4gc3VhdHUgc2FtcGVsIGRlbmdhbiBoYXJhcGFuIHNhbXBlbCB0ZXJzZWJ1dCBtZXdha2lsaSBkYXRhIHBvcHVsYWkgc2ViZW5hcm55YSwgYmlhc2FueWEgdWt1cmFuIHJlc2FtcGxpbmcgZGlhbWJpbCBzZWNhcmEgcmlidWFuIGthbGkgYWdhciBkYXBhdCBtZXdha2lsaSBkYXRhIHBvcHVsYXNpbnlhLiBBbGdvcml0bWEgcmVzYW1wbGlnbiB1bXVtIGRlbmdhbiAkXHtYXzEsIFxsZG90cywgWF9uXH0kIHVudHVrIG1lbnVuanVra2FuIHNhbXBlbCBhc2xpIGRhbiAkXHtYXzFeKiwgXGxkb3RzLCBYX25eKlx9JCBtZW51bmp1a2thbiB1bmRpYW4geWFuZyBkaXNpbXVsYXNpa2FuLg0KDQpVbnR1ayBzZXRpYXAgc2FtcGVsLCAkbiQgbWVydXBha2FuIHVuZGlhbiBzaW11bGFzaSwganVtbGFoIHlhbmcgc2FtYSBkZW5nYW4gdWt1cmFuIHNhbXBlbCBhc2xpLiBVbnR1ayBtZW1iZWRha2FuIHByb3NlZHVyIGluaSBkYXJpIHNpbXVsYXNpLCBiaWFzYW55YSBkaWd1bmFrYW4gJEIkICh1bnR1ayBib290c3RyYXApIHNlYmFnYWkganVtbGFoIHNhbXBlbCB5YW5nIGRpc2ltdWxhc2lrYW4uIFNlaGluZ2dhIGRhcGF0IGRpdHVsaXNrYW4gJFx7WF8xXnsoYil9LCBcbGRvdHMsIFhfbl57KGIpfVx9JC4NCg0KQWRhIGR1YSBtZXRvZGUgcmVzYW1wbGluZyBkYXNhciwgbW9kZWwtZnJlZSBkYW4gbW9kZWwtYmFzZWQgLCBtYXNpbmctbWFzaW5nIHNlYmFnYWkgbm9ucGFyYW1ldHJpayBkYW4gcGFyYW1ldHJpayAuIFBlbmd1bmRpYW4geWFuZyBkaXNpbXVsYXNpa2FuIGJlcmFzYWwgZGFyaSBmdW5nc2kgZGlzdHJpYnVzaSBlbXBpcmlzICRGX24oXGNkb3QpJCAsIGphZGkgc2V0aWFwIHVuZGlhbiBiZXJhc2FsICRce1hfMSwgXGxkb3RzLCBYX25cfSQgZGVuZ2FuIHByb2JhYmlsaXRhcyAkMS9uJC4NCg0KYEJvb3RzdHJhcCBOb25wYXJhbWV0cmlrYA0KDQpHYWdhc2FuIGJvb3RzdHJhcCBub25wYXJhbWV0cmlrIGFkYWxhaCBtZW5nZ3VuYWthbiBtZXRvZGUgdHJhbnNmb3JtYXNpIHRlcmJhbGlrICRGX04kICwgZnVuZ3NpIGRpc3RyaWJ1c2kga3VtdWxhdGlmIGVtcGlyaXMsIGRpZ2FtYmFya2FuIHBhZGEgZ3JhZmlrIGRpYmF3YWggaW5pLg0KDQpgYGB7ciBpbWFnZTI4LCBlY2hvPUZBTFNFLCBmaWcuY2FwPSIiLGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoID0gJzEwMCUnfQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIjYuMi4xLTEucG5nIikNCmBgYA0KDQpLYXJlbmEgJEZfTiQgYWRhbGFoIHN0ZXAtZnVuY3Rpb24sICRGX25eey0xfSQgc3VidGl0dXNpIG5pbGFpLW5pbGFpICRce3hfMSxcY2RvdHMseF9uXH0kIHNlaGluZ2dhDQoNCjEuIGppa2EgJHlcaW4oMCwxL24pJCAoZGVuZ2FuIHByb2JhYmlsaXRhcyAkMSAvIG4kICkgZGVuZ2FuIG1lbmdnYW1iYXIgbmlsYWkgdGVya2VjaWwgKCAkXG1pblx7eF9pXH0kICkNCg0KMi4gamlrYSAkeVxpbigxL24sMi9uKSQgKGRlbmdhbiBwcm9iYWJpbGl0YXMgJDEgLyBuJCApIGRlbmdhbiBtZW5nZ2FtYmFyIG5pbGFpIHRlcmtlY2lsIGtlZHVhLA0KDQrigKYNCg0KMy4gamlrYSAkeVxpbigobi0xKS9uLDEpJCAoZGVuZ2FuIHByb2JhYmlsaXRhcyAkMSAvIG4kICkga2FtaSBtZW5nZ2FtYmFyIG5pbGFpIHRlcmJlc2FyICggJFxtYXhce3hfaVx9JCApDQoNCmBgYHtyIGltYWdlMTEsIGVjaG89RkFMU0UsIGZpZy5jYXA9IiIsZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnMTAwJSd9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiNi4yLjEtMi5wbmciKQ0KYGBgDQoNCk1lbmdndW5ha2FuIG1ldG9kZSB0cmFuc2Zvcm1hc2kgdGVyYmFsaWsgZGVuZ2FuICRGX04kIGJlcmFydGkgcGVuZ2FtYmlsYW4gc2FtcGVsIGRhcmkgJFx7eF8xLFxjZG90cyx4X25cfSQsIGRlbmdhbiBwcm9iYWJpbGl0YXMgJDEgLyBuJCAuIE1lbmdoYXNpbGthbiBzYW1wZWwgdWt1cmFuIGJvb3RzdHJhcCAkQiQgYmVyYXJ0aSBwZW5nYW1iaWxhbiBzYW1wZWwgZGFyaSAkXHt4XzEsXGNkb3RzLHhfblx9JCAsIGRlbmdhbiBwcm9iYWJpbGl0YXMgJDEgLyBuJCAsIGRlbmdhbiBwZW5nZ2FudGlhbi4gDQoNCmBgYHtyfQ0Kc2V0LnNlZWQoMSkNCm4gPC0gMTANCnggPC0gcmV4cChuLCAxLzYpDQptIDwtIDgNCmJvb3R2YWx1ZXMgPC0gc2FtcGxlKHgsIHNpemU9bSwgcmVwbGFjZT1UUlVFKQ0KYGBgDQoNCiMjIyAoNi4yLjIpIFByZXNpc2kgQm9vdHN0cmFwOiBCaWFzLCBTdGFuZGFyIERldmlhc2ksIGRhbiBNZWFuIFNxdWFyZSBFcnJvcg0KDQpCZXJpa3V0IGFkYWxhaCByYW5na3VtYW4gcHJvc2VkdXIgYm9vdHN0cmFwIG5vbnBhcmFtZXRyaWsgc2ViYWdhaSBiZXJpa3V0Og0KDQoxLiBEYXJpIHNhbXBlbCAkXHtYXzEsIFxsZG90cywgWF9uXH0kLCBnYW1iYXIgc2FtcGVsIGJlcnVrdXJhbiBuIChkZW5nYW4gcGVuZ2dhbnRpYW4pLCBrYXRha2FubGFoLCAkWF8xXiosIFxsZG90cywgWF9uXiokIC4gRGFyaSB1bmRpYW4geWFuZyBkaXNpbXVsYXNpa2FuLCBoaXR1bmcgc3RhdGlzdGlrIG1pbmF0LCBkaWxhbWJhbmdrYW4gc2ViYWdhaSAkXGhhdHtcdGhldGF9KFhfMV4qLCBcbGRvdHMsIFhfbl4qKSQgLiBQYW5nZ2lsIGluaSAkXGhhdHtcdGhldGF9X2JeKiQgdW50dWsgdWxhbmdhbiBrZS1iIC4NCg0KMi4gVWxhbmdpIGluaSAkYj0xLCBcbGRvdHMsIEIkIGthbGkgdW50dWsgbWVuZGFwYXRrYW4gc2FtcGVsIHN0YXRpc3RpayAkXGhhdHtcdGhldGF9XzFeKiwgXGxkb3RzLFxoYXR7XHRoZXRhfV9CXiokLg0KDQozLiBEYXJpIHNhbXBlbCBzdGF0aXN0aWsgcGFkYSBMYW5na2FoIDIsJFx7XGhhdHtcdGhldGF9XzFeKiwgXGxkb3RzLCBcaGF0e1x0aGV0YX1fQl4qXH0kIGhpdHVuZyB1a3VyYW4gcmluZ2thc2FuIG1pbmF0Lg0KDQpQYWRhIGJhZ2lhbiBpbmksIGFkYSB0aWdhIGxhbmdrYWggcmluZ2thc2FuIHlhaXR1IGJpYXMsIHN0YW5kYXIgZGV2aWFzaSwgZGFuIG1lYW4gc3F1YXJlIGVycm9yICggTVNFICkuIFRhYmVsIGRpYmF3YWggaW5pIG1lcmFuZ2t1bSBrZXRpZ2EgdWt1cmFuLiBEaSBTaW5pLCAkXG92ZXJsaW5le1xoYXR7XHRoZXRhXip9fSQgYWRhbGFoIHJhdGEtcmF0YSBkYXJpICRce1xoYXR7XHRoZXRhfV8xXiosIFxsZG90cyxcaGF0e1x0aGV0YX1fQl4qXH0kLg0KDQpgYGB7ciBpbWFnZTEyLCBlY2hvPUZBTFNFLCBmaWcuY2FwPSIiLGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoID0gJzEwMCUnfQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIjYuMi4xLTMucG5nIikNCmBgYA0KDQpgYGB7ciBldmFsPUZBTFNFfQ0KIyBFeGFtcGxlIGZyb20gRGVycmlnIGV0IGFsDQpCSURhdGEgPC0gcmVhZC5jc3YoIkRhdGEvRGVycmlnUmVzYW1wbGluZy5jc3YiLCBoZWFkZXIgPVQpDQpCSURhdGEkQ2Vuc29yZWQgPC0gMSooQklEYXRhJEFtb3VudFBhaWQgPj0gQklEYXRhJFBvbGljeUxpbWl0KQ0KQklEYXRhVW5jZW5zb3JlZCA8LSBzdWJzZXQoQklEYXRhLCBDZW5zb3JlZCA9PSAwKQ0KTEVSLmJvb3QgPC0gZnVuY3Rpb24oZGVkLCBkYXRhLCBpbmRpY2VzKXsNCiAgcmVzYW1wbGUuZGF0YSA8LSBkYXRhW2luZGljZXMsXQ0KICBzdW1DbGFpbXMgPC0gc3VtKHJlc2FtcGxlLmRhdGEkQW1vdW50UGFpZCkNCiAgc3VtQ2xhaW1zX2QgPC0gc3VtKHBtaW4ocmVzYW1wbGUuZGF0YSRBbW91bnRQYWlkLGRlZCkpDQogIExFUiA8LSAgIHN1bUNsYWltc19kL3N1bUNsYWltcw0KICByZXR1cm4oTEVSKSAgDQp9DQoNCiMjRGVycmlnIGV0IGFsDQpzZXQuc2VlZCgyMDE5KQ0KZFZlYzIgPC0gYyg0MDAwLCA1MDAwLCAxMDUwMCwgMTE1MDAsIDE0MDAwLCAxODUwMCkNCk91dEJvb3QgPC0gbWF0cml4KDAsbGVuZ3RoKGRWZWMyKSw2KQ0KICBmb3IgKGkgaW4gMTpsZW5ndGgoZFZlYzIpKSB7DQpPdXRCb290W2ksMV0gPC0gZFZlYzJbaV0NCnJlc3VsdHMgPC0gYm9vdChkYXRhPUJJRGF0YVVuY2Vuc29yZWQsIHN0YXRpc3RpYz1MRVIuYm9vdCwgUj0xMDAwLCBkZWQ9ZFZlYzJbaV0pDQpPdXRCb290W2ksMl0gPC0gcmVzdWx0cyR0MA0KYmlhc2Jvb3QgPC0gbWVhbihyZXN1bHRzJHQpLXJlc3VsdHMkdDAgLT4gT3V0Qm9vdFtpLDNdDQpzZGJvb3QgPC0gc2QocmVzdWx0cyR0KSAtPiBPdXRCb290W2ksNF0NCnRlbXAgPC0gYm9vdC5jaShyZXN1bHRzKQ0KT3V0Qm9vdFtpLDVdIDwtIHRlbXAkbm9ybWFsWzJdDQpPdXRCb290W2ksNl0gPC0gdGVtcCRub3JtYWxbM10NCn0NCmBgYA0KDQpgYGB7ciBpbWFnZTEzLCBlY2hvPUZBTFNFLCBmaWcuY2FwPSIiLGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoID0gJzEwMCUnfQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIjYuMi4xLTQucG5nIikNCmBgYA0KDQpCZXJkYXNhcmthbiB0YWJlbCBkaWF0YXMgaGFzaWwgZXN0aW1hc2kgYm9vdHN0cmFwLiBNaXNhbG55YSwgZGkgRD0gMTQwMDAgLCBlc3RpbWFzaSBub25wYXJhbWV0cmlrIExFUiBhZGFsYWggMCw5NzY3OC4gSW5pIG1lbWlsaWtpIHBlcmtpcmFhbiBiaWFzIDAsMDAwMTggZGVuZ2FuIHN0YW5kYXIgZGV2aWFzaSAwLDAwNzAxLiBVbnR1ayBiZWJlcmFwYSBhcGxpa2FzaSwgbXVuZ2tpbiBpbmdpbiBtZW5lcmFwa2FuIGVzdGltYXNpIGJpYXMga2UgZXN0aW1hc2kgYXNsaSB1bnR1ayBtZW1iZXJpa2FuIGVzdGltYXRvciB5YW5nIGRpa29yZWtzaSBiaWFzLiBVbnR1ayBpbHVzdHJhc2kgaW5pLCBiaWFzbnlhIGtlY2lsIHNlaGluZ2dhIGtvcmVrc2kgc2VtYWNhbSBpdHUgdGlkYWsgcmVsZXZhbi4NCg0KDQpTdGFuZGFyIGRldmlhc2kgYm9vdHN0cmFwIG1lbWJlcmlrYW4gdWt1cmFuIHByZXNpc2kuIFVudHVrIHNhdHUgcGVuZXJhcGFuIHN0YW5kYXIgZGV2aWFzaSBkYXBhdCBtZW5nZ3VuYWthbiBwZW5kZWthdGFuIG5vcm1hbCB1bnR1ayBtZW1idWF0IHNlbGFuZyBrZXBlcmNheWFhbi4gTWlzYWxueWEsIHBhZGEgX1JfIGZ1bmdzaSBfYm9vdC5jaV8gbWVuZ2hhc2lsa2FuIGludGVydmFsIGtlcGVyY2F5YWFuIG5vcm1hbCBzZWJlc2FyIDk1JS4gSW5pIGRpaGFzaWxrYW4gZGVuZ2FuIG1lbWJ1YXQgaW50ZXJ2YWwgZHVhIGthbGkgcGFuamFuZyBzdGFuZGFyIGRldmlhc2kgYm9vdHN0cmFwIDEsOTU5OTQsIGJlcnB1c2F0IGRpIHNla2l0YXIgZXN0aW1hdG9yIHlhbmcgZGlrb3Jla3NpIGJpYXMgKDEsOTU5OTQgYWRhbGFoIGt1YW50aWwga2UtOTcsNSBkYXJpIGRpc3RyaWJ1c2kgbm9ybWFsKS4gTWlzYWxueWEsIENJIDk1JSBub3JtYWwgeWFuZyBsZWJpaCByZW5kYWggZGkgJEQ9IDE0MDAwJCBhZGFsYWggJCgwLjk3Njc4LTAuMDAwMTgpLSAxLjk1OTk0KjAuMDA3MDEkLiANCg0KYENvbnRvaCA2LjIuMi5gIE1lbXBlcmtpcmFrYW4gJFxleHAoXG11KSQgLiBCb290c3RyYXAgZGFwYXQgZGlndW5ha2FuIHVudHVrIG1lbmd1a3VyIGJpYXMgZXN0aW1hdG9yLCBtaXNhbG55YS4gUGVydGltYmFuZ2thbiBkaSBzaW5pIHNhbXBlbCAkXG1hdGhiZnt4fT1ce3hfMSxcY2RvdHMseF9uXH0kIGFkYWxhaCByYXRhLXJhdGEgzrwgLg0KDQpgYGB7cn0NCnNhbXBsZV94IDwtIGMoMi40NiwyLjgwLDMuMjgsMy44NiwyLjg1LDMuNjcsMy4zNywzLjQwLDUuMjIsMi41NSwNCiAgICAgICAgICAgICAgMi43OSw0LjUwLDMuMzcsMi44OCwxLjQ0LDIuNTYsMi4wMCwyLjA3LDIuMTksMS43NykNCmBgYA0KDQpNaXNhbGthbiBrdWFudGl0YXMgYnVuZ2EgYWRhbGFoICRcdGhldGE9XGV4cChcbXUpJC4gUGVuYWtzaXIgYWxhbWkgYWthbiBtZW5qYWRpICRcd2lkZWhhdHtcdGhldGF9XzE9XGV4cChcb3ZlcmxpbmV7eH0pJC4gRXN0aW1hdG9yIGluaSBiaWFzIChrYXJlbmEga2V0aWRha3NldGFyYWFuIEplbnNlbikgdGV0YXBpIHRpZGFrIGJpYXMgc2VjYXJhIGFzaW10b3Rpay4gVW50dWsgc2FtcGVsLCBwZXJraXJhYW5ueWEgYWRhbGFoIHNlYmFnYWkgYmVyaWt1VA0KDQpgYGB7cn0NCih0aGV0YV8xIDwtIGV4cChtZWFuKHNhbXBsZV94KSkpDQpgYGANCg0KU2VzZW9yYW5nIGRhcGF0IG1lbmdndW5ha2FuIHRlb3JlbWEgbGltaXQgcHVzYXQgdW50dWsgbWVuZGFwYXRrYW4ga29yZWtzaSBtZW5nZ3VuYWthbg0KDQokJFxvdmVybGluZXtYfVxhcHByb3hcbWF0aGNhbHtOfVxsZWZ0KFxtdSxcZnJhY3tcc2lnbWFeMn17bn1ccmlnaHQpXHRleHR7IHdoZXJlIH1cc2lnbWFeMj1cdGV4dHtWYXJ9W1hfaV0gLCQkDQoNCnNlaGluZ2dhIGRlbmdhbiBmdW5nc2kgcGVtYmFuZ2tpdCBtb21lbiBub3JtYWwgZGlkYXBhdGthbg0KDQokJFxtYXRocm17RX1+XGxlZnRbXGV4cChcb3ZlcmxpbmV7WH0pXHJpZ2h0XSBcYXBwcm94IFxleHBcbGVmdChcbXUrXGZyYWN7XHNpZ21hXjJ9ezJufVxyaWdodCkgLiQkDQoNCk9sZWgga2FyZW5hIGl0dSwgc2VzZW9yYW5nIGRhcGF0IG1lbXBlcnRpbWJhbmdrYW4gc2VjYXJhIGFsYW1pDQoNCiQkXHdpZGVoYXR7XHRoZXRhfV8yPVxleHBcbGVmdChcb3ZlcmxpbmV7eH0tXGZyYWN7XHdpZGVoYXR7XHNpZ21hfV4yfXsybn1ccmlnaHQpIC4kJA0KDQpgYGB7cn0NCm4gPC0gbGVuZ3RoKHNhbXBsZV94KQ0KKHRoZXRhXzIgPC0gZXhwKG1lYW4oc2FtcGxlX3gpLXZhcihzYW1wbGVfeCkvKDIqbikpKQ0KYGBgDQoNClNlYmFnYWkgc3RyYXRlZ2kgbGFpbiwgc2VzZW9yYW5nIGp1Z2EgZGFwYXQgbWVuZ2d1bmFrYW4gcGVuZGVrYXRhbiBUYXlsb3IgdW50dWsgbWVuZGFwYXRrYW4gcGVuYWtzaXIgeWFuZyBsZWJpaCBha3VyYXQgKHNlcGVydGkgZGFsYW0gbWV0b2RlIGRlbHRhKQ0KDQokJGcoXG92ZXJsaW5le3h9KT1nKFxtdSkrKFxvdmVybGluZXt4fS1cbXUpZycoXG11KSsoXG92ZXJsaW5le3h9LVxtdSleMlxmcmFje2cnJyhcbXUpfXsyfStcY2RvdHMkJA0KDQpBbHRlcm5hdGlmIHNlbGFuanV0bnlhIGFkYWxhaCBtZW5nZ3VuYWthbiBzdHJhdGVnaSBib290c3RyYXAgZGVuZ2FuIHNhbXBlbCBib290c3RyYXAgJFxtYXRoYmZ7eH1ee1xhc3R9X3tifSQgc2VoaW5nZ2EgJFxvdmVybGluZXt4fV57XGFzdH1fe2J9JC4NCg0KJCRcd2lkZWhhdHtcdGhldGF9XzM9XGZyYWN7MX17Qn1cc3VtX3tiPTF9XkJcZXhwKFxvdmVybGluZXt4fV57XGFzdH1fe2J9KSAuJCQNCg0KYGBge3J9DQpsaWJyYXJ5KGJvb3QpDQpyZXN1bHRzIDwtIGJvb3QoZGF0YT1zYW1wbGVfeCwgDQogICAgICAgICAgICAgICAgc3RhdGlzdGljPWZ1bmN0aW9uKHksaW5kaWNlcykgZXhwKG1lYW4oeVtpbmRpY2VzXSkpLCANCiAgICAgICAgICAgICAgICBSPTEwMDApDQp0aGV0YV8zIDwtIG1lYW4ocmVzdWx0cyR0KQ0KYGBgDQoNCmBgYHtyIGltYWdlMTQsIGVjaG89RkFMU0UsIGZpZy5jYXA9IiIsZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnMTAwJSd9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiNi4yLjItMS5wbmciKQ0KYGBgDQoNCmBgYHtyIGltYWdlMTUsIGVjaG89RkFMU0UsIGZpZy5jYXA9IiIsZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnMTAwJSd9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiNi4yLjItMi5wbmciKQ0KYGBgDQoNCkluaSBtZW5naGFzaWxrYW4gdGlnYSBlc3RpbWF0b3IsIGVzdGltYXRvciBtZW50YWggJFx3aWRlaGF0e1x0aGV0YX1fMT0xOS4xMzUkLCBrb3Jla3NpIHVydXRhbiBrZWR1YSAkXHdpZGVoYXR7XHRoZXRhfV8yPSAxOC43MzMkLCBkYW4gZXN0aW1hdG9yIGJvb3RzdHJhcCAkXHdpZGVoYXR7XHRoZXRhfV8zPSAxOS4zODgkLiANCg0KQmFnYWltYW5hIGNhcmEga2VyamFueWEgZGVuZ2FuIHVrdXJhbiBzYW1wZWwgeWFuZyBiZXJiZWRhPyBEaWFzdW1zaWthbiBiYWh3YSAkWF9pJCBkaWhhc2lsa2FuIGRhcmkgZGlzdHJpYnVzaSBsb2dub3JtYWwgJExOKDAsMSkkICwgc2VoaW5nZ2EgJFxtdSA9IFxleHAoMCArIDEvMikgPSAxLjY0ODcyMSQgRGFuICRcdGhldGEgPSBcZXhwKDEuNjQ4NzIxKT0gNSwyMDAzMjYkLiBEZW5nYW4gbWVuZ2d1bmFrYW4gc2ltdWxhc2kgdW50dWsgbWVuZ2dhbWJhciB1a3VyYW4gc2FtcGVsLg0KDQpgYGB7ciBldmFsPUZBTFNFfQ0KcGFyYW0gPC0gZnVuY3Rpb24oeCl7DQogIG4gPC0gbGVuZ3RoKHgpDQogIHRoZXRhXzEgPC0gZXhwKG1lYW4oeCkpDQogIHRoZXRhXzIgPC0gZXhwKG1lYW4oeCktdmFyKHgpLygyKm4pKQ0KICByZXN1bHRzIDwtIGJvb3QoZGF0YT14LCANCiAgICAgICAgICAgICAgICBzdGF0aXN0aWM9ZnVuY3Rpb24oeSxpbmRpY2VzKSBleHAobWVhbih5W2luZGljZXNdKSksIA0KICAgICAgICAgICAgICAgIFI9OTk5KQ0KICB0aGV0YV8zIDwtIG1lYW4ocmVzdWx0cyR0KQ0KICByZXR1cm4oYyh0aGV0YV8xLHRoZXRhXzIsdGhldGFfMykpDQp9DQpzZXQuc2VlZCgyMDc0KQ0KbnM8LSAyMDANCmVzdCA8LSBmdW5jdGlvbihuKXsNCmNhbGxfcGFyYW0gPC0gZnVuY3Rpb24oaSkgcGFyYW0ocmxub3JtKG4sMCwxKSkNClYgPC0gVmVjdG9yaXplKGNhbGxfcGFyYW0pKDE6bnMpDQphcHBseShWLDEsbWVkaWFuKQ0KfQ0KVk49c2VxKDE1LDEwMCxieT01KQ0KRXN0IDwtIFZlY3Rvcml6ZShlc3QpKFZOKQ0KYGBgDQoNCmBgYHtyIGV2YWw9RkFMU0V9DQptYXRwbG90KFZOLHQoRXN0KSx0eXBlPSJsIiwgY29sPTI6NCwgbHR5PTI6NCwgeWxpbT1leHAoZXhwKDEvMikpK2MoLTEsMSksDQogICAgICAgIHhsYWI9InNhbXBsZSBzaXplIChuKSIsIHlsYWI9ImVzdGltYXRvciIpDQphYmxpbmUoaD1leHAoZXhwKDEvMikpLGx0eT0xLCBjb2w9MSkNCmxlZ2VuZCgidG9wbGVmdCIsIGMoInJhdyBlc3RpbWF0b3IiLCAic2Vjb25kIG9yZGVyIGNvcnJlY3Rpb24iLCAiYm9vdHN0cmFwIiksDQogICAgICAgY29sPTI6NCxsdHk9Mjo0LCBidHk9Im4iKQ0KYGBgDQoNCmBgYHtyIGltYWdlMTYsIGVjaG89RkFMU0UsIGZpZy5jYXA9IiIsZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnMTAwJSd9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiNi4yLjItMy5wbmciKQ0KYGBgDQoNCkhhc2lsIHBlcmJhbmRpbmdhbiBkaXJhbmdrdW0gZGFsYW0gZ2FtYmFyIGRpYXRhcyBtZW51bmp1a2thbiBiYWh3YSBlc3RpbWF0b3IgYm9vdHN0cmFwIG1lbmRla2F0aSBuaWxhaSBwYXJhbWV0ZXIgc2ViZW5hcm55YSB1bnR1ayBoYW1waXIgc2VtdWEgdWt1cmFuIHNhbXBlbC4gQmlhcyBkYXJpIGtldGlnYSBlc3RpbWF0b3IgYmVya3VyYW5nIGRlbmdhbiBtZW5pbmdrYXRueWEgdWt1cmFuIHNhbXBlbC4NCg0KIyMjICg2LjIuMykgSW50ZXJ2YWwgS2V5YWtpbmFuDQoNClByb3NlZHVyIGJvb3RzdHJhcCBtZW5naGFzaWxrYW4gJEIkIGJlbnR1ayB1bGFuZyBkYXJpICRcaGF0e1x0aGV0YX1fMV4qLCBcbGRvdHMsXGhhdHtcdGhldGF9X0JeKiQgZGFyaSBwZW5ha3NpciAkXGhhdHtcdGhldGF9JCAuIERhbGFtIENvbnRvaCA2LjIuMSwgZGFwYXQgZGlsaWhhdCBiYWdhaW1hbmEgbWVuZ2d1bmFrYW4gcGVuZGVrYXRhbiBub3JtYWwgc3RhbmRhciB1bnR1ayBtZW1idWF0IGludGVydmFsIGtlcGVyY2F5YWFuIHVudHVrIHBhcmFtZXRlciB5YW5nIGRpaW5naW5rYW4uIE5hbXVuLCBtZW5naW5nYXQgcG9pbiB1dGFtYW55YSBhZGFsYWggbWVuZ2d1bmFrYW4gYm9vdHN0cmFwcGluZyB1bnR1ayBtZW5naGluZGFyaSBrZXRlcmdhbnR1bmdhbiBwYWRhIGFzdW1zaSBwZXJraXJhYW4gbm9ybWFsaXRhcywgdGlkYWsgbWVuZ2hlcmFua2FuIGppa2EgdGVyc2VkaWEgaW50ZXJ2YWwga2VwZXJjYXlhYW4gYWx0ZXJuYXRpZi4NCg0KVW50dWsgZXN0aW1hdG9yICRcaGF0e1x0aGV0YX0kICwgaW50ZXJ2YWwga2VwZXJjYXlhYW4gYm9vdHN0cmFwIGRhc2FyIGFkYWxhaA0KDQokJFxiZWdpbntlcXVhdGlvbn0gDQogIFxsZWZ0KDIgXGhhdHtcdGhldGF9IC0gcV9VLCAyIFxoYXR7XHRoZXRhfSAtIHFfTCBccmlnaHQpICwNClx0YWd7Ni4yfQ0KXGVuZHtlcXVhdGlvbn0kJA0KDQpEaSBtYW5hICRxX0wkIERhbiAkcV9VJCBhZGFsYWgga3VhbnRpbCAyLDUlIGJhd2FoIGRhbiBhdGFzIGRhcmkgc2FtcGVsIGJvb3RzdHJhcCAkXGhhdHtcdGhldGF9XzFeKiwgXGxkb3RzLFxoYXR7XHRoZXRhfV9CXiokDQoNClVudHVrIG1lbGloYXQgZGFyaSBtYW5hIGFzYWxueWEsIG11bGEtbXVsYSAkKHFfTCwgcV9VKSQgbWVueWVkaWFrYW4gaW50ZXJ2YWwgOTUlIHVudHVrICRcaGF0e1x0aGV0YX1fMV4qLCBcbGRvdHMsXGhhdHtcdGhldGF9X0JeKiQgLiBKYWRpLCB1bnR1ayBhY2FrICRcaGF0e1x0aGV0YX1fYl4qJCwgYWRhIGtlbXVuZ2tpbmFuIDk1JSBpdHUgJHFfTCBcbGUgXGhhdHtcdGhldGF9X2JeKiBcbGUgcV9VJC4gTWVtYmFsaWtrYW4gcGVydGlkYWtzYW1hYW4gZGFuIG1lbmp1bWxhaGthbiAkXGhhdHtcdGhldGF9JCBrZSBzZXRpYXAgc2lzaSBtZW1iZXJpa2FuIGludGVydmFsIDk1JQ0KDQokJFxoYXR7XHRoZXRhfSAtcV9VIFxsZSBcaGF0e1x0aGV0YX0gLSBcaGF0e1x0aGV0YX1fYl4qIFxsZSAgXGhhdHtcdGhldGF9IC1xX0wgLiQkDQoNCkphZGksICRcbGVmdCggXGhhdHtcdGhldGF9LXFfVSwgXGhhdHtcdGhldGF9IC1xX0xccmlnaHQpJCBhZGFsYWggaW50ZXJ2YWwgOTUlIHVudHVrICRcaGF0e1x0aGV0YX0gLSBcaGF0e1x0aGV0YX1fYl4qJC4gSWRlIHBlcmtpcmFhbiBib290c3RyYXAgbWVuZ2F0YWthbiBiYWh3YSBpbmkganVnYSBtZXJ1cGFrYW4gaW50ZXJ2YWwgOTUlIHVudHVrICRcdGhldGEgLSBcaGF0e1x0aGV0YX0kLiBEZW5nYW4gbWVuYW1iYWhrYW4gJFxoYXR7XHRoZXRhfSQga2Ugc2V0aWFwIHNpc2kgbWVtYmVyaWthbiBpbnRlcnZhbCA5NSUgZGFsYW0gcGVyc2FtYWFuIGRpYXRhcy4NCg0KQmFueWFrIGFsdGVybmF0aWYgaW50ZXJ2YWwgYm9vdHN0cmFwIHlhbmcgdGVyc2VkaWEuIFlhbmcgcGFsaW5nIG11ZGFoIGRpamVsYXNrYW4gYWRhbGFoIGludGVydmFsIGJvb3RzdHJhcCBwZXJzZW50aWwgeWFuZyBkaWRlZmluaXNpa2FuIHNlYmFnYWkgJChxX0wscV9VKSQuDQoNCmBDb250b2ggNi4yLjMuYCBLbGFpbSBDaWRlcmEgVHVidWggZGFuIFRpbmRha2FuIFJpc2lrby4gVW50dWsgbWVsaWhhdCBiYWdhaW1hbmEgaW50ZXJ2YWwga2VwZXJjYXlhYW4gYm9vdHN0cmFwIGJla2VyamEsIGRlbmdhbiBrZW1iYWxpIGtlIGtsYWltIG90b21hdGlzIGNlZGVyYSB0dWJ1aCB5YW5nIGRpcGVydGltYmFuZ2thbiBkYWxhbSBDb250b2ggNi4yLjEgLiBBbGloLWFsaWggcmFzaW8gZWxpbWluYXNpIGtlcnVnaWFuLCBtaXNhbGthbiBpbmdpbiBtZW1wZXJraXJha2FuIHBlcnNlbnRpbCBrZS05NSAkRl57LTF9KDAuOTUpJCBkYW4gdWt1cmFuIGRpZGVmaW5pc2lrYW4gc2ViYWdhaQ0KDQokJFRWYVJfezAuOTV9W1hdID0gXG1hdGhybXtFfVtYIHwgWCA+IEZeey0xfSgwLjk1KV0gLiQkDQoNClBlbmd1a3VyYW4gaW5pIGRpc2VidXQgZGVuZ2FuIGVrb3IgbmlsYWkgYmVyaXNpa287IGl0dSBhZGFsYWggbmlsYWkgeWFuZyBkaWhhcmFwa2FuIGRhcmkgWCBiZXJzeWFyYXQgWCBtZWxlYmloaSBwZXJzZW50aWwga2UtOTUuIEJhZ2lhbiAxMC4yIG1lbmplbGFza2FuIGJhZ2FpbWFuYSBxdWFudGlsZXMgZGFuIHRhaWwgdmFsdWUtYXQtcmlzayBhZGFsYWggZHVhIGNvbnRvaCBwYWxpbmcgcGVudGluZyBkYXJpIGFwYSB5YW5nIGRpc2VidXQgc2ViYWdhaSB1a3VyYW4gcmlzaWtvIC4gVW50dWsgc2FhdCBpbmksIGhhbnlhIGFrYW4gbWVuZ2FuZ2dhcCBpbmkgc2ViYWdhaSB1a3VyYW4geWFuZyBpbmdpbiBkaXBlcmtpcmFrYW4uIFVudHVrIHBlcnNlbnRpbCwgZGVuZ2FuIG1lbmdndW5ha2FuIGVzdGltYXRvciBub25wYXJhbWV0cmlrICRGXnstMX1fbigwLjk1KSQgZGlkZWZpbmlzaWthbiBkYWxhbSBCYWdpYW4gNC4xLjEuMyAuIFVudHVrIHRhaWwgdmFsdWUtYXQtcmlzaywgbWVuZ2d1bmFrYW4gcHJpbnNpcCBwbHVnLWluIHVudHVrIG1lbmVudHVrYW4gZXN0aW1hdG9yIG5vbnBhcmFtZXRyaWsNCg0KJCRUVmFSX3tuLDAuOTV9W1hdID0gXGZyYWN7XHN1bV97aT0xfV5uIFhfaSBJKFhfaSA+IEZeey0xfV9uKDAuOTUpKX17XHN1bV97aT0xfV5uIEkoWF9pID4gRl57LTF9X24oMC45NSkpfSB+LiQkDQoNCkRhbGFtIHVuZ2thcGFuIGluaSwgcGVueWVidXQgbWVuZ2hpdHVuZyBqdW1sYWggcGVuZ2FtYXRhbiB5YW5nIG1lbGViaWhpIHBlcnNlbnRpbCBrZS05NSAkRl57LTF9X24oMC45NSkkIC4gUGVtYmlsYW5nIG1lbmp1bWxhaGthbiBrZXJ1Z2lhbiB1bnR1ayBwZW5nYW1hdGFuIHlhbmcgbWVsZWJpaGkgJEZeey0xfV9uKDAuOTUpJCAuIFRhYmVsIGRpYmF3YWggaW5pIG1lcmFuZ2t1bSBwZW5ha3NpciB1bnR1ayBwZWNhaGFuIHRlcnBpbGloLg0KDQpgYGB7ciBldmFsPUZBTFNFfQ0KIyBFeGFtcGxlIGZyb20gRGVycmlnIGV0IGFsDQojQklEYXRhIDwtIHJlYWQuY3N2KCJEYXRhL0RlcnJpZ1Jlc2FtcGxpbmcuY3N2IiwgaGVhZGVyID1UKQ0KQklEYXRhJENlbnNvcmVkIDwtIDEqKEJJRGF0YSRBbW91bnRQYWlkID49IEJJRGF0YSRQb2xpY3lMaW1pdCkNCkJJRGF0YVVuY2Vuc29yZWQgPC0gc3Vic2V0KEJJRGF0YSwgQ2Vuc29yZWQgPT0gMCkNCg0Kc2V0LnNlZWQoMjAxNykNClBlcmNlbnRWZWMgPC0gYygwLjUwLCAwLjgwLCAwLjkwLCAwLjk1LCAwLjk4KQ0KT3V0Qm9vdDEgPC0gbWF0cml4KDAsNSwxMCkNCmZvciAoaSBpbiAxOmxlbmd0aChQZXJjZW50VmVjKSkgew0KT3V0Qm9vdDFbaSwxXSA8LSBQZXJjZW50VmVjW2ldDQpyZXN1bHRzIDwtIGJvb3QoZGF0YT1CSURhdGFVbmNlbnNvcmVkJEFtb3VudFBhaWQsDQogICAgICAgICAgICAgICAgc3RhdGlzdGljPWZ1bmN0aW9uKFgsaW5kaWNlcykNCiAgICAgICAgICAgICAgICAgICAgcXVhbnRpbGUoWFtpbmRpY2VzXSxQZXJjZW50VmVjW2ldKSwNCiAgICAgICAgICAgICAgICAgUj0xMDAwKQ0KaWYgKGk9PTEpe2Jvb3RyZWFsIDwtIHJlc3VsdHMkdH0NCk91dEJvb3QxW2ksMl0gPC0gcmVzdWx0cyR0MA0KT3V0Qm9vdDFbaSwzXSA8LSBtZWFuKHJlc3VsdHMkdCktcmVzdWx0cyR0MCANCk91dEJvb3QxW2ksNF0gPC0gc2QocmVzdWx0cyR0KSANCnRlbXAgPC0gYm9vdC5jaShyZXN1bHRzLCB0eXBlID0gYygibm9ybSIsICJiYXNpYyIsICJwZXJjIikpDQpPdXRCb290MVtpLDVdIDwtIHRlbXAkbm9ybWFsWzJdDQpPdXRCb290MVtpLDZdIDwtIHRlbXAkbm9ybWFsWzNdDQpPdXRCb290MVtpLDddIDwtIHRlbXAkYmFzaWNbNF0NCk91dEJvb3QxW2ksOF0gPC0gdGVtcCRiYXNpY1s1XQ0KT3V0Qm9vdDFbaSw5XSA8LSB0ZW1wJHBlcmNlbnRbNF0NCk91dEJvb3QxW2ksMTBdIDwtIHRlbXAkcGVyY2VudFs1XQ0KfQ0KYGBgDQoNCmBgYHtyIGltYWdlMTcsIGVjaG89RkFMU0UsIGZpZy5jYXA9IiIsZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnMTAwJSd9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiNi4yLjMtMS5wbmciKQ0KYGBgDQoNCk1pc2FsbnlhLCBrZXRpa2EgcGVjYWhhbm55YSBhZGFsYWggMCw1MCwgZGFwYXQgbWVsaWhhdCBiYWh3YSBrdWFudGlsIDIsNSBiYXdhaCBkYW4gYXRhcyBkYXJpIHNpbXVsYXNpIGJvb3RzdHJhcCBhZGFsYWggJHFfTD0gNjAwMCQgZGFuICRxX1U9IDY3MDAkLiBJbmkgbWVtYmVudHVrIGludGVydmFsIGtlcGVyY2F5YWFuIGJvb3RzdHJhcCBwZXJzZW50aWwuIERlbmdhbiBlc3RpbWF0b3Igbm9ucGFyYW1ldHJpayAkNjUwMCQsIGluaSBtZW5naGFzaWxrYW4gYmF0YXMgYmF3YWggZGFuIGF0YXMgaW50ZXJ2YWwga2VwZXJjYXlhYW4gZGFzYXIgbWFzaW5nLW1hc2luZyAkNjMwMCQgZGFuICQ3MDAwJC4gDQoNCmBgYHtyIGV2YWw9RkFMU0V9DQpDVEUuYm9vdCA8LSBmdW5jdGlvbihkYXRhLCBpbmRpY2VzLCBSaXNrTGV2ZWwpew0KICByZXNhbXBsZS5kYXRhIDwtIGRhdGFbaW5kaWNlcyxdDQogIFggPC0gcmVzYW1wbGUuZGF0YSRBbW91bnRQYWlkDQogIGN1dG9mZiA8LSBxdWFudGlsZShYLCBSaXNrTGV2ZWwpDQogIENURSA8LSBzdW0oWCooWCA+IGN1dG9mZikpL3N1bShYID4gY3V0b2ZmKQ0KICByZXR1cm4oQ1RFKSANCn0NCg0Kc2V0LnNlZWQoMjAxNykgIA0KUGVyY2VudFZlYyA8LSBjKDAuNTAsIDAuODAsIDAuOTAsIDAuOTUsIDAuOTgpDQpPdXRCb290MSA8LSBtYXRyaXgoMCw1LDEwKQ0KICBmb3IgKGkgaW4gMTpsZW5ndGgoUGVyY2VudFZlYykpIHsNCk91dEJvb3QxW2ksMV0gPC0gUGVyY2VudFZlY1tpXQ0KcmVzdWx0cyA8LSBib290KGRhdGE9QklEYXRhVW5jZW5zb3JlZCwgc3RhdGlzdGljPUNURS5ib290LCBSPTEwMDAsIFJpc2tMZXZlbD1QZXJjZW50VmVjW2ldKQ0KT3V0Qm9vdDFbaSwyXSA8LSByZXN1bHRzJHQwDQpPdXRCb290MVtpLDNdIDwtIG1lYW4ocmVzdWx0cyR0KS1yZXN1bHRzJHQwIA0KT3V0Qm9vdDFbaSw0XSA8LSBzZChyZXN1bHRzJHQpIA0KdGVtcCA8LSBib290LmNpKHJlc3VsdHMsIHR5cGUgPSBjKCJub3JtIiwgImJhc2ljIiwgInBlcmMiKSkNCk91dEJvb3QxW2ksNV0gPC0gdGVtcCRub3JtYWxbMl0NCk91dEJvb3QxW2ksNl0gPC0gdGVtcCRub3JtYWxbM10NCk91dEJvb3QxW2ksN10gPC0gdGVtcCRiYXNpY1s0XQ0KT3V0Qm9vdDFbaSw4XSA8LSB0ZW1wJGJhc2ljWzVdDQpPdXRCb290MVtpLDldIDwtIHRlbXAkcGVyY2VudFs0XQ0KT3V0Qm9vdDFbaSwxMF0gPC0gdGVtcCRwZXJjZW50WzVdDQogIH0NCmBgYA0KDQpgYGB7ciBpbWFnZTE4LCBlY2hvPUZBTFNFLCBmaWcuY2FwPSIiLGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoID0gJzEwMCUnfQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIjYuMi4zLTIucG5nIikNCmBgYA0KDQpUYWJlbCBkaSBhdGFzIG1lbnVuanVra2FuIGthbGt1bGFzaSBzZXJ1cGEgdW50dWsgdGFpbCB2YWx1ZS1hdC1yaXNrLiBEYWxhbSBzZXRpYXAga2FzdXMsIGRhcGF0IG1lbGloYXQgYmFod2EgZGV2aWFzaSBzdGFuZGFyIGJvb3RzdHJhcCBtZW5pbmdrYXQgc2VpcmluZyBkZW5nYW4gcGVuaW5na2F0YW4gZnJha3NpLiBIYWwgaW5pIGthcmVuYSBhZGEgbGViaWggc2VkaWtpdCBwZW5nYW1hdGFuIHVudHVrIG1lbXBlcmtpcmFrYW4ga3VhbnRpbCBzZWlyaW5nIG1lbmluZ2thdG55YSBmcmFrc2ksIHlhbmcgbWVueWViYWJrYW4ga2V0aWRha3RlcGF0YW4geWFuZyBsZWJpaCBiZXNhci4gSW50ZXJ2YWwga2VwZXJjYXlhYW4ganVnYSBtZW5qYWRpIGxlYmloIGxlYmFyLiBNZW5hcmlrbnlhLCB0YW1wYWtueWEgdGlkYWsgYWRhIHBvbGEgeWFuZyBzYW1hIGRhbGFtIGVzdGltYXNpIGJpYXMgdGVyc2VidXQuDQoNCiMjIyAoNi4yLjQpIEJvb3RzdHJhcCBQYXJhbWV0cmlrDQoNCkdhZ2FzYW4gZGFyaSBib290c3RyYXAgbm9ucGFyYW1ldHJpayBhZGFsYWggdW50dWsgbWVuZ2FtYmlsIHNhbXBlbCB1bGFuZyBkZW5nYW4gbWVuZ2dhbWJhciB2YXJpYWJlbCBpbmRlcGVuZGVuIGRhcmkgZnVuZ3NpIGRpc3RyaWJ1c2kga3VtdWxhdGlmIGVtcGlyaXMgJEZfbiQuIFNlYmFsaWtueWEsIGRlbmdhbiBib290c3RyYXAgcGFyYW1ldHJpaywga2FtaSBtZW5hcmlrIHZhcmlhYmVsIGluZGVwZW5kZW4gZGFyaSAkRl97XHdpZGVoYXR7XHRoZXRhfX0kIGRpIG1hbmEgZGlzdHJpYnVzaSB5YW5nIG1lbmRhc2FyaW55YSBkaWFzdW1zaWthbiBkYWxhbSBrZWx1YXJnYSBwYXJhbWV0cmlrICRcbWF0aGNhbHtGfT1ce0Zfe1x0aGV0YX0sXHRoZXRhXGluXFRoZXRhXH0kIC4gQmlhc2FueWEsIHBhcmFtZXRlciBkYXJpIGRpc3RyaWJ1c2kgaW5pIGRpcGVya2lyYWthbiBiZXJkYXNhcmthbiBzYW1wZWwgZGFuIGRpbm90YXNpa2FuIHNlYmFnYWkgJFxoYXR7XHRoZXRhfSQuDQoNCmBjb250b2ggNi4yLjQuYCBkaXN0cmlidXNpIGxvZ25vcm1hbC4gUGVydGltYmFuZ2thbiBsYWdpIGt1bXB1bGFuIGRhdGFueWENCg0KYGBge3J9DQpzYW1wbGVfeCA8LSBjKDIuNDYsMi44MCwzLjI4LDMuODYsMi44NSwzLjY3LDMuMzcsMy40MCwNCiAgICAgICAgICAgICAgNS4yMiwyLjU1LDIuNzksNC41MCwzLjM3LDIuODgsMS40NCwyLjU2LDIuMDAsMi4wNywyLjE5LDEuNzcpDQpgYGANCg0KQm9vdHN0cmFwIGtsYXNpayAobm9ucGFyYW1ldHJpaykgZGlkYXNhcmthbiBwYWRhIGNvbnRvaCBiZXJpa3V0Lg0KDQpgYGB7cn0NCnggPC0gc2FtcGxlKHNhbXBsZV94LHJlcGxhY2U9VFJVRSkNCmBgYA0KDQpTZWJhZ2FpIGdhbnRpbnlhLCB1bnR1ayBib290c3RyYXAgcGFyYW1ldHJpayBoYXJ1cyBtZW5nYXN1bXNpa2FuIGJhaHdhIGRpc3RyaWJ1c2kgZGFyaSAkeF9pJCBhZGFsYWggZGFyaSBrZWxvbXBvayB0ZXJ0ZW50dS4gU2ViYWdhaSBjb250b2gsIGtvZGUgYmVyaWt1dCBtZW5nZ3VuYWthbiBkaXN0cmlidXNpIGxvZ25vcm1hbC4NCg0KYGBge3IgZXZhbD1GQUxTRX0NCmxpYnJhcnkoTUFTUykNCmZpdCA8LSBmaXRkaXN0cihzYW1wbGVfeCwgZGxub3JtLCBsaXN0KG1lYW5sb2cgPSAxLCBzZGxvZyA9IDEpKQ0KZml0DQpgYGANCg0KYGBge3IgaW1hZ2UyNywgZWNobz1GQUxTRSwgZmlnLmNhcD0iIixmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aCA9ICcxMDAlJ30NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCI2LjIuNC0xLnBuZyIpDQpgYGANCg0KYGBge3IgZXZhbD1GQUxTRX0NCnggPC0gcmxub3JtKGxlbmd0aChzYW1wbGVfeCksIG1lYW5sb2c9Zml0JGVzdGltYXRlWzFdLCBzZGxvZz1maXQkZXN0aW1hdGVbMl0pDQpgYGANCg0KYGBge3IgZXZhbD1GQUxTRX0NCnNldC5zZWVkKDIwNzQpDQpDViA8LSBtYXRyaXgoTkEsMWU1LDIpDQpmb3IocyBpbiAxOm5yb3coQ1YpKXsNCngxIDwtIHNhbXBsZShzYW1wbGVfeCxyZXBsYWNlPVRSVUUpDQp4MiA8LSBybG5vcm0obGVuZ3RoKHNhbXBsZV94KSwgbWVhbmxvZz1maXQkZXN0aW1hdGVbMV0sIHNkbG9nPWZpdCRlc3RpbWF0ZVsyXSkNCkNWW3MsXSA8LSBjKHNkKHgxKS9tZWFuKHgxKSxzZCh4MikvbWVhbih4MikpDQp9DQpgYGANCg0KYGBge3IgZXZhbD1GQUxTRX0NCnBsb3QoZGVuc2l0eShDVlssMV0pLGNvbD0icmVkIixtYWluPSIiLHhsYWI9IkNvZWZmaWNpZW50IG9mIFZhcmlhdGlvbiIsIGx0eT0xKQ0KbGluZXMoZGVuc2l0eShDVlssMl0pLGNvbD0iYmx1ZSIsbHR5PTIpDQphYmxpbmUodj1zZChzYW1wbGVfeCkvbWVhbihzYW1wbGVfeCksbHR5PTMpDQpsZWdlbmQoInRvcHJpZ2h0IixjKCJub25wYXJhbWV0cmljIiwicGFyYW1ldHJpYyhMTikiKSwNCiAgICAgICBjb2w9YygicmVkIiwiYmx1ZSIpLGx0eT0xOjIsYnR5PSJuIg0KYGBgDQoNCmBgYHtyIGltYWdlMjIsIGVjaG89RkFMU0UsIGZpZy5jYXA9IiIsZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnMTAwJSd9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiNi4yLjMtMy5wbmciKQ0KYGBgDQoNCkdyYWZpayBkaSBhdGFzIG1lbWJhbmRpbmdrYW4gZGlzdHJpYnVzaSBib290c3RyYXAgdW50dWsga29lZmlzaWVuIHZhcmlhc2ksIHlhbmcgc2F0dSBiZXJkYXNhcmthbiBwZW5kZWthdGFuIG5vbnBhcmFtZXRyaWsgZGFuIHlhbmcgbGFpbm55YSBiZXJkYXNhcmthbiBwZW5kZWthdGFuIHBhcmFtZXRyaWssIGRlbmdhbiBhc3Vtc2kgZGlzdHJpYnVzaSBsb2dub3JtYWwuDQoNCmBDb250b2ggNi4yLjUuYCBQZW5nYW1hdGFuIHlhbmcgRGlzZW5zb3IgQm9vdHN0cmFwLiANCg0KQm9vdHN0cmFwIHBhcmFtZXRyaWsgbWVuYXJpayByZWFsaXNhc2kgc2ltdWxhc2kgZGFyaSBwZXJraXJhYW4gcGFyYW1ldHJpayBkYXJpIGZ1bmdzaSBkaXN0cmlidXNpLiBEZW5nYW4gY2FyYSB5YW5nIHNhbWEsIHNlaGluZ2dhIGRhcGF0IG1lbmdnYW1iYXIgcmVhbGlzYXNpIHNpbXVsYXNpIGRhcmkgZXN0aW1hc2kgZnVuZ3NpIGRpc3RyaWJ1c2kuIFNlYmFnYWkgc2FsYWggc2F0dSBjb250b2gsIGRlbmdhbiBtZW5nYW1iaWwgZGFyaSBlc3RpbWFzaSB5YW5nIGRpaGFsdXNrYW4gZGFyaSBmdW5nc2kgZGlzdHJpYnVzaSB5YW5nIGRpcGVya2VuYWxrYW4gZGkgQmFnaWFuIDQuMS4xLjQgLiBLYXN1cyBraHVzdXMgbGFpbm55YSwgeWFuZyBkaXBlcnRpbWJhbmdrYW4gZGkgc2luaSBhZGFsYWggbWVuZ2dhbWJhciBlc3RpbWFzaSBkYXJpIGVzdGltYXRvciBLYXBsYW4tTWVpZXIgeWFuZyBkaWJhaGFzIGRpIEJhZ2lhbiA0LjMuMi4yLiBEZW5nYW4gY2FyYSBpbmksIGRhcGF0IGRpdGFuZ2FuaSBwZW5nYW1hdGFuIHlhbmcgZGlzZW5zb3IuDQoNClNlY2FyYSBraHVzdXMsIGtlbWJhbGkga2UgZGF0YSBjZWRlcmEgdHVidWggcGFkYSBDb250b2ggNi4yLjEgZGFuIDYuMi4zIHRldGFwaSBzZWthcmFuZyBtZW55ZXJ0YWthbiAxNyBrbGFpbSB5YW5nIGRpc2Vuc29yIG9sZWggYmF0YXNhbiBrZWJpamFrYW4uIERhbGFtIENvbnRvaCA0LjMuNiBtZW5nZ3VuYWthbiBrdW1wdWxhbiBkYXRhIGxlbmdrYXAgaW5pIHVudHVrIG1lbmdlc3RpbWFzaSBlc3RpbWF0b3IgS2FwbGFuLU1laWVyIGRhcmkgZnVuZ3NpIHN1cnZpdmFsIHlhbmcgZGlwZXJrZW5hbGthbiBkaSBCYWdpYW4gNC4zLjIuMiAuIFRhYmVsIDYuNiBtZW55YWppa2FuIGVzdGltYXNpIGJvb3RzdHJhcCBrdWFudGlsIGRhcmkgZXN0aW1hdG9yIGZ1bmdzaSBzdXJ2aXZhbCBLYXBsYW4tTWVpZXIuIEluaSB0ZXJtYXN1ayBwZXJraXJhYW4gcHJlc2lzaSBib290c3RyYXAsIGJpYXMgZGFuIHN0YW5kYXIgZGV2aWFzaSwgc2VydGEgaW50ZXJ2YWwga2VwZXJjYXlhYW4gZGFzYXIgOTUlLg0KDQpgYGB7ciBldmFsPUZBTFNFfQ0KIyBFeGFtcGxlIGZyb20gRGVycmlnIGV0IGFsDQpsaWJyYXJ5KHN1cnZpdmFsKSAgICAgICAgICAgICAgICAjIGZvciBTdXJ2KCksIHN1cnZmaXQoKQ0KQklEYXRhJFVuQ2Vuc29yZWQgPC0gMSooQklEYXRhJEFtb3VudFBhaWQgPCBCSURhdGEkUG9saWN5TGltaXQpDQojIyBLTSBlc3RpbWF0ZQ0KS00wIDwtIHN1cnZmaXQoU3VydihBbW91bnRQYWlkLCBVbkNlbnNvcmVkKSB+IDEsICANCiAgICAgICAgICAgICAgIHR5cGU9ImthcGxhbi1tZWllciIsIGRhdGE9QklEYXRhKQ0KDQpzZXQuc2VlZCgyMDE5KQ0KUGVyY2VudFZlYyA8LSBjKDAuNTAsIDAuODAsIDAuOTAsIDAuOTUsIDAuOTgpDQpPdXRCb290MSA8LSBtYXRyaXgoTkEsNSw2KQ0KS00uc3Vydm9iaiA8LSBTdXJ2KEJJRGF0YSRBbW91bnRQYWlkLCBCSURhdGEkVW5DZW5zb3JlZCkgDQpmb3IgKGkgaW4gMTpsZW5ndGgoUGVyY2VudFZlYykpIHsNCk91dEJvb3QxW2ksMV0gPC0gUGVyY2VudFZlY1tpXQ0KcmVzdWx0cyA8LSBib290a20oS00uc3Vydm9iaiwgcT0xLVBlcmNlbnRWZWNbaV0sIEI9MTAwMCwgcHIgPSBGQUxTRSkNCmlmIChpPT0xKXtib290cmVhbCA8LSByZXN1bHRzfQ0KT3V0Qm9vdDFbaSwyXSA8LSBxdWFudGlsZShLTTAsIFBlcmNlbnRWZWNbaV0pJHF1YW50aWxlDQpPdXRCb290MVtpLDNdIDwtIG1lYW4ocmVzdWx0cyktT3V0Qm9vdDFbaSwyXQ0KT3V0Qm9vdDFbaSw0XSA8LSBzZChyZXN1bHRzKSANCiMgdGVtcCA8LSBib290LmNpKHJlc3VsdHMsIHR5cGUgPSBjKCJub3JtIiwgICJiYXNpYyIsInBlcmMiKSkNCk91dEJvb3QxW2ksNV0gPC0gMipPdXRCb290MVtpLDJdLXF1YW50aWxlKHJlc3VsdHMsLjk3NSwgdHlwZT02KQ0KT3V0Qm9vdDFbaSw2XSA8LSAyKk91dEJvb3QxW2ksMl0tcXVhbnRpbGUocmVzdWx0cywuMDI1LCB0eXBlPTYpDQp9DQpgYGANCg0KYGBge3IgaW1hZ2UxOSwgZWNobz1GQUxTRSwgZmlnLmNhcD0iIixmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aCA9ICcxMDAlJ30NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCI2LjIuMy00LnBuZyIpDQpgYGANCg0KSGFzaWwgcGFkYSB0YWJlbCBkaSBhdGFzIGtvbnNpc3RlbiBkZW5nYW4gaGFzaWwgdW50dWsgc3Vic2FtcGVsIHRhbnBhIHNlbnNvciBwYWRhIFRhYmVsIDYuNCAuIFBhZGEgdGFiZWwgZGkgYXRhcyB0ZXJjYXRhdCBrZXN1bGl0YW4gZGFsYW0gbWVtcGVya2lyYWthbiBrdWFudGlsIHBhZGEgcGVjYWhhbiBiZXNhciBrYXJlbmEgcGVueWVuc29yYW4uIE5hbXVuLCB1bnR1ayBmcmFrc2kgYmVydWt1cmFuIHNlZGFuZyAoMCw1MCwgMCw4MCwgZGFuIDAsOTApLCBlc3RpbWFzaSBub25wYXJhbWV0cmlrIEthcGxhbi1NZWllciAoS00gTlApIGRhcmkga3VhbnRpbCBrb25zaXN0ZW4gZGVuZ2FuIFRhYmVsIDYuNCAuIFN0YW5kYXIgRGV2aWFzaSBib290c3RyYXAgbGViaWgga2VjaWwgcGFkYSAwLDUwIChzZXN1YWkgZGVuZ2FuIG1lZGlhbikgdGV0YXBpIGxlYmloIGJlc2FyIHBhZGEgbGV2ZWwgMCw4MCBkYW4gMCw5MC4gQW5hbGlzaXMgZGF0YSB0ZXJzZW5zb3IgeWFuZyBkaXJhbmdrdW0gZGFsYW0gdGFiZWwgZGkgYXRhcyBtZW5nZ3VuYWthbiBsZWJpaCBiYW55YWsgZGF0YSBkYXJpcGFkYSBhbmFsaXNpcyBzdWJzYW1wZWwgdGFucGEgc2Vuc29yIHBhZGEgVGFiZWwgNi40ICwgdGV0YXBpIGp1Z2EgbWVuZ2FsYW1pIGtlc3VsaXRhbiBkYWxhbSBtZW5nZWtzdHJha3NpIGluZm9ybWFzaSB1bnR1ayBrdWFudGlsIGJlc2FyLg==