

Email          : ali.19arifin@gmail.com
RPubs         : https://rpubs.com/aliciaarifin/
Jurusan      :
Statistika
Address     : ARA Center, Matana University Tower
   Â
         Jl. CBD Barat Kav, RT.1, Curug Sangereng, Kelapa Dua,
Tangerang, Banten 15810.
Library
setwd(getwd())
library(ggplot2)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(broom)
library(ggpubr)
Simple Regression
Simple regression : 1 variabel independen + 1 variabel dependen. ##
import data
income.data = read.csv("data/income.data.csv")
summary(income.data)
## X income happiness
## Min. : 1.0 Min. :1.506 Min. :0.266
## 1st Qu.:125.2 1st Qu.:3.006 1st Qu.:2.266
## Median :249.5 Median :4.424 Median :3.473
## Mean :249.5 Mean :4.467 Mean :3.393
## 3rd Qu.:373.8 3rd Qu.:5.992 3rd Qu.:4.503
## Max. :498.0 Max. :7.482 Max. :6.863
cek asumsi
Agar regresi bisa dijalankan, diperlukan beberapa asumsi-asumsi agar
regresi yang kita buat hasilnya maksimal. Asumsi-asumsi tersebut adalah
linearitas, autokorelasi, homodesitas, dan normalitas.
Yang harus
ditekanakan di regresi adalah data tersebut tidak autokorelasi,
homogenitas (tolak homodesitas), dan normalitas. Kalau linearitas akan
menentukan apakah kita akan membuat regresi linear atau regresi
non-linear.
linearitas
plot(happiness ~ income, data = income.data)
Karena pola grafik linear, maka kita akan menggunakan regresi
linear.
independensi atau
autokorelasi
Karena kita akan menggunakan regresi linear, maka kita hanya
mempunyai variabel independen dan variabel dependen. Kita tidak perlu
mencek hubungan antar variabel dependen karena variabel dependennya
hanya terdapat satu.
Apa itu autokorelasi?
Autokorelasi
adalah terdapat hubungan antara variabel dependen, hubungan tersebut
bisa mempengaruhi output sehingga regresi yang kita buat bisa tidak
akurat. Pada regresi antara variabel dependen harus tidak
berautokorelasi.
homosdesitas
(kehomogenitas varians)
ini akan diliat setelah plotnya jadi.
normalitas
hist(income.data$happiness)
hasil dari histogram di atas kira-kira datanya bersebar normal atau
berbentuk lonceng (bell-shaped), maka data kita merupakan normal.
Linear regression
analisis
income.happiness.lm <- lm(happiness ~ income, data = income.data)
summary(income.happiness.lm)
##
## Call:
## lm(formula = happiness ~ income, data = income.data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.02479 -0.48526 0.04078 0.45898 2.37805
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.20427 0.08884 2.299 0.0219 *
## income 0.71383 0.01854 38.505 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.7181 on 496 degrees of freedom
## Multiple R-squared: 0.7493, Adjusted R-squared: 0.7488
## F-statistic: 1483 on 1 and 496 DF, p-value: < 2.2e-16
Dari hasil tersebut didapat bahwa p-value < dari alpha 5%, dan
Adjusted R-square sebesar 74,88%. Berarti terdapat 74,88% variabel yang
sudah termsuk kedalam regresi. Untuk penelitian sosial, R-square >
70% sudah dikatakan baik. Sehingga regresi tersebut sudah bisa digunakan
meskipun belum terlalu baik. Kalau dilihat dari variabel dependen
(income) memiliki pengaruh yang signifikan terhadap variabel
independen(happiness).
Rumus / Model Regresinya adalah :
happiness = 0.204 + 0.714*income
Income atau
pendapatan memiliki dampak + terhadap regresi, yang berarti income atau
pendapatan berbanding lurus dengan happiness/kebahagiaan. Jika
pendapatan meningkat, maka kebahagiaan meningkat, begitu juga
sebaliknya.
visualisasi Hasil
dengan grafik
ggplot(income.data, aes(x=income, y=happiness))+
geom_point()+
geom_smooth(method="lm", col="black")+
stat_regline_equation(label.x = 3, label.y = 7)+
theme_bw() +
labs(title = "Reported happiness as a function of income",
x = "Income (x$10,000)",
y = "Happiness score (0 to 10)")
## `geom_smooth()` using formula = 'y ~ x'

homosdesitas
(kehomogenitas varians)
par(mfrow=c(2,2))
plot(income.happiness.lm)

Residu yang disebutkan di atas merupakan varians. jika rata-rata
ataua mean dari residu tersebut terbentuk garis horizontal dan mendekati
0, maka tidak terdapat outlier atau pencilan. Kalau diliat dari Q-Qplot
yang bisa diliat adalah residunya hampir membentuk satu garis. dari
hasil residunya, kita bisa bilang kalau model yang dibuat homogen
(variansnya sama).
Multiple
Regression
Multiple regression : 1 variabel independen + n variabel dependen
dengan n > 1.
import data
heart.data = read.csv("data/heart.data.csv")
summary(heart.data)
## X biking smoking heart.disease
## Min. : 1.0 Min. : 1.119 Min. : 0.5259 Min. : 0.5519
## 1st Qu.:125.2 1st Qu.:20.205 1st Qu.: 8.2798 1st Qu.: 6.5137
## Median :249.5 Median :35.824 Median :15.8146 Median :10.3853
## Mean :249.5 Mean :37.788 Mean :15.4350 Mean :10.1745
## 3rd Qu.:373.8 3rd Qu.:57.853 3rd Qu.:22.5689 3rd Qu.:13.7240
## Max. :498.0 Max. :74.907 Max. :29.9467 Max. :20.4535
cek asumsi
Sama seperti simple regression, kita harus mengecek asumsi-asumsi
yang ada. ### linearitas
plot(heart.disease ~ biking, data=heart.data)

plot(heart.disease ~ smoking, data=heart.data)

Pola grafik biking linear, pola grafik smoking juga linear meskipun
kurang berpola tetapi linear. karena kedualnya linear, kita akan
membentuk regresi linear.
independensi atau
autokorelasi
cor(heart.data$biking, heart.data$smoking)
## [1] 0.01513618
korelasi antara biking dan smoking hanya 0.015 atau 1.5%, maka bisa
dipastikan bahwa variabel dependen kita tidak autokorelasi. kita bisa
menggunakan kedua parameter tersebut.
homosdesitas
(kehomogenitas varians)
akan di tes setelah plotnya terbentuk
normalitas
hist(heart.data$heart.disease)
hasil dari histogram di atas kira-kira datanya bersebar normal atau
berbentuk lonceng (bell-shaped), maka data kita merupakan normal.
Linear regression
analisis
heart.disease.lm<-lm(heart.disease ~ biking + smoking, data = heart.data)
summary(heart.disease.lm)
##
## Call:
## lm(formula = heart.disease ~ biking + smoking, data = heart.data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.1789 -0.4463 0.0362 0.4422 1.9331
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 14.984658 0.080137 186.99 <2e-16 ***
## biking -0.200133 0.001366 -146.53 <2e-16 ***
## smoking 0.178334 0.003539 50.39 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.654 on 495 degrees of freedom
## Multiple R-squared: 0.9796, Adjusted R-squared: 0.9795
## F-statistic: 1.19e+04 on 2 and 495 DF, p-value: < 2.2e-16
Dari hasil tersebut didapat bahwa p-value < dari alpha 5%, dan
Multiple R-square sebesar 97.96%. Berarti terdapat 97.96% variabel yang
sudah termsuk kedalam regresi yang dibuat. Untuk penelitian scientific,
R-square harus lebih dari samadengan 90%. Jadi regresi yang telah kita
buat sudah oke.
Kedua variabel dependen (biking dan smoking)
memiliki pengaruh siknifikan terhadap heart.disease.
Rumus / Model
Regresinya adalah :
heart.disease = 14.98 - 0.2*biking + 0.17*smoking
Biking/bersepeda memiliki dampak negatif terhadap penyakit jantung, dan
smoking/merokok memiliki dampak positif. Karena ini penyakit jantung,
semakin kecil nilai regresi yang didapat semakin kecil resiko seseorang
mengalami penyakit jantung. Sehingga Bisa dikatakan bahwa
biking/bersepeda memiliki dampak yang baik untuk tubuh, dan
smoking/merokok memiliki dampak negatif untuk tubuh. Smoking/merokok
bisa memicu penyakit jantung, dan sebaliknya pada biking/bersepeda.
visualisasi Hasil
dengan grafik
plotting.data<-expand.grid(
biking = seq(min(heart.data$biking), max(heart.data$biking), length.out=30),
smoking=c(min(heart.data$smoking), mean(heart.data$smoking), max(heart.data$smoking)))
plotting.data$predicted.y <- predict.lm(heart.disease.lm, newdata=plotting.data)
plotting.data$smoking <- as.factor(round(plotting.data$smoking, digits = 2))
ggplot(heart.data, aes(x=biking, y=heart.disease)) +
geom_point()+
geom_line(data=plotting.data, aes(x=biking, y=predicted.y, color=smoking), size=1.25)+
theme_bw() +
labs(title = "Rates of heart disease (% of population) \n as a function of biking to work and smoking",
x = "Biking to work (% of population)",
y = "Heart disease (% of population)",
color = "Smoking \n (% of population)")
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.

homosdesitas
(kehomogenitas varians)
par(mfrow=c(2,2))
plot(heart.disease.lm)

sama seperti simple regresi, residunya tidak menunjukkan adanya bias,
dan bisa dibilnag model kita cocok untuk asumsi homogenitas.
LS0tDQp0aXRsZTogIktvbXB1dGFzaSBTdGF0aXN0aWthIg0Kc3VidGl0bGU6ICJUdWdhcyAiDQphdXRob3I6ICJBbGljaWEgQXJpZmluICgyMDIxNDkyMDAwMSkiDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy5EYXRlKCksICclQiAlZCwgJVknKWAiDQpvdXRwdXQ6IA0KICBodG1sX2RvY3VtZW50OiANCiAgICBodG1sX2RvY3VtZW50OiBudWxsDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6DQogICAgICBjb2xsYXBzZWQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgdGhlbWU6IHNhbmRzdG9uZQ0KICAgIGNzczogc3R5bGUxLmNzcw0KICAgIGhpZ2hsaWdodDogbW9ub2Nocm9tZQ0KLS0tDQoNCg0KPGltZyBzdHlsZT0iZmxvYXQ6IHJpZ2h0OyBtYXJnaW46IDBweCAxMDBweCAwcHggMHB4OyB3aWR0aDoyNSUiIHNyYz0iZm90b2RpcmkucG5nIi8+IA0KDQpgYGB7ciBsb2dvLCBlY2hvPUZBTFNFLGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoID0gJzMwJSd9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygibG9nb21hdGFuYS5wbmciKQ0KYGBgDQoNCkVtYWlsICZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyZuYnNwOzogIGFsaS4xOWFyaWZpbkBnbWFpbC5jb20gPGJyPg0KUlB1YnMgICZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOzogaHR0cHM6Ly9ycHVicy5jb20vYWxpY2lhYXJpZmluLyA8YnI+DQpKdXJ1c2FuICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDs6IFtTdGF0aXN0aWthXShodHRwczovL21hdGFuYXVuaXZlcnNpdHkuYWMuaWQvP2x5PWFjYWRlbWljJmM9c2IpIDxicj4NCkFkZHJlc3MgICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyA6IEFSQSBDZW50ZXIsIE1hdGFuYSBVbml2ZXJzaXR5IFRvd2VyIDxicj4NCiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7Jm5ic3A7IEpsLiBDQkQgQmFyYXQgS2F2LCBSVC4xLCBDdXJ1ZyBTYW5nZXJlbmcsIEtlbGFwYSBEdWEsIFRhbmdlcmFuZywgQmFudGVuIDE1ODEwLg0KDQoqKioqDQoNCiMgTGlicmFyeQ0KYGBge3J9DQpzZXR3ZChnZXR3ZCgpKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoYnJvb20pDQpsaWJyYXJ5KGdncHVicikNCmBgYA0KDQoNCiMgU2ltcGxlIFJlZ3Jlc3Npb24NClNpbXBsZSByZWdyZXNzaW9uIDogMSB2YXJpYWJlbCBpbmRlcGVuZGVuICsgMSB2YXJpYWJlbCBkZXBlbmRlbi4NCiMjIGltcG9ydCBkYXRhDQpgYGB7cn0NCmluY29tZS5kYXRhID0gcmVhZC5jc3YoImRhdGEvaW5jb21lLmRhdGEuY3N2IikNCnN1bW1hcnkoaW5jb21lLmRhdGEpDQpgYGANCg0KDQojIyBjZWsgYXN1bXNpDQpBZ2FyIHJlZ3Jlc2kgYmlzYSBkaWphbGFua2FuLCBkaXBlcmx1a2FuIGJlYmVyYXBhIGFzdW1zaS1hc3Vtc2kgYWdhciByZWdyZXNpIHlhbmcga2l0YSBidWF0IGhhc2lsbnlhIG1ha3NpbWFsLiBBc3Vtc2ktYXN1bXNpIHRlcnNlYnV0IGFkYWxhaCBsaW5lYXJpdGFzLCBhdXRva29yZWxhc2ksIGhvbW9kZXNpdGFzLCBkYW4gbm9ybWFsaXRhcy4gDQo8YnI+DQpZYW5nIGhhcnVzIGRpdGVrYW5ha2FuIGRpIHJlZ3Jlc2kgYWRhbGFoIGRhdGEgdGVyc2VidXQgdGlkYWsgYXV0b2tvcmVsYXNpLCBob21vZ2VuaXRhcyAodG9sYWsgaG9tb2Rlc2l0YXMpLCBkYW4gbm9ybWFsaXRhcy4gS2FsYXUgbGluZWFyaXRhcyBha2FuIG1lbmVudHVrYW4gYXBha2FoIGtpdGEgYWthbiBtZW1idWF0IHJlZ3Jlc2kgbGluZWFyIGF0YXUgcmVncmVzaSBub24tbGluZWFyLg0KDQoNCiMjIyBsaW5lYXJpdGFzIA0KYGBge3J9DQpwbG90KGhhcHBpbmVzcyB+IGluY29tZSwgZGF0YSA9IGluY29tZS5kYXRhKQ0KYGBgDQpLYXJlbmEgcG9sYSBncmFmaWsgbGluZWFyLCBtYWthIGtpdGEgYWthbiBtZW5nZ3VuYWthbiByZWdyZXNpIGxpbmVhci4gDQoNCg0KIyMjIGluZGVwZW5kZW5zaSBhdGF1IGF1dG9rb3JlbGFzaQ0KS2FyZW5hIGtpdGEgYWthbiBtZW5nZ3VuYWthbiByZWdyZXNpIGxpbmVhciwgbWFrYSBraXRhIGhhbnlhIG1lbXB1bnlhaSB2YXJpYWJlbCBpbmRlcGVuZGVuIGRhbiB2YXJpYWJlbCBkZXBlbmRlbi4gS2l0YSB0aWRhayBwZXJsdSBtZW5jZWsgaHVidW5nYW4gYW50YXIgdmFyaWFiZWwgZGVwZW5kZW4ga2FyZW5hIHZhcmlhYmVsIGRlcGVuZGVubnlhIGhhbnlhIHRlcmRhcGF0IHNhdHUuIA0KPGJyPg0KPGJyPg0KQXBhIGl0dSBhdXRva29yZWxhc2k/IA0KPGJyPg0KQXV0b2tvcmVsYXNpIGFkYWxhaCB0ZXJkYXBhdCBodWJ1bmdhbiBhbnRhcmEgdmFyaWFiZWwgZGVwZW5kZW4sIGh1YnVuZ2FuIHRlcnNlYnV0IGJpc2EgbWVtcGVuZ2FydWhpIG91dHB1dCBzZWhpbmdnYSByZWdyZXNpIHlhbmcga2l0YSBidWF0IGJpc2EgdGlkYWsgYWt1cmF0LiBQYWRhIHJlZ3Jlc2kgYW50YXJhIHZhcmlhYmVsIGRlcGVuZGVuIGhhcnVzIHRpZGFrIGJlcmF1dG9rb3JlbGFzaS4NCg0KIyMjIGhvbW9zZGVzaXRhcyAoa2Vob21vZ2VuaXRhcyB2YXJpYW5zKQ0KDQppbmkgYWthbiBkaWxpYXQgc2V0ZWxhaCBwbG90bnlhIGphZGkuDQoNCg0KIyMjIG5vcm1hbGl0YXMNCmBgYHtyfQ0KaGlzdChpbmNvbWUuZGF0YSRoYXBwaW5lc3MpDQpgYGANCmhhc2lsIGRhcmkgaGlzdG9ncmFtIGRpIGF0YXMga2lyYS1raXJhIGRhdGFueWEgYmVyc2ViYXIgbm9ybWFsIGF0YXUgYmVyYmVudHVrIGxvbmNlbmcgKGJlbGwtc2hhcGVkKSwgbWFrYSBkYXRhIGtpdGEgbWVydXBha2FuIG5vcm1hbC4NCg0KDQojIyBMaW5lYXIgcmVncmVzc2lvbiBhbmFsaXNpcw0KDQpgYGB7cn0NCmluY29tZS5oYXBwaW5lc3MubG0gPC0gbG0oaGFwcGluZXNzIH4gaW5jb21lLCBkYXRhID0gaW5jb21lLmRhdGEpDQoNCnN1bW1hcnkoaW5jb21lLmhhcHBpbmVzcy5sbSkNCmBgYA0KRGFyaSBoYXNpbCB0ZXJzZWJ1dCBkaWRhcGF0IGJhaHdhIHAtdmFsdWUgPCBkYXJpIGFscGhhIDUlLCBkYW4gQWRqdXN0ZWQgUi1zcXVhcmUgc2ViZXNhciA3NCw4OCUuIEJlcmFydGkgdGVyZGFwYXQgNzQsODglIHZhcmlhYmVsIHlhbmcgc3VkYWggdGVybXN1ayBrZWRhbGFtIHJlZ3Jlc2kuIFVudHVrIHBlbmVsaXRpYW4gc29zaWFsLCBSLXNxdWFyZSA+IDcwJSBzdWRhaCBkaWthdGFrYW4gYmFpay4gU2VoaW5nZ2EgcmVncmVzaSB0ZXJzZWJ1dCBzdWRhaCBiaXNhIGRpZ3VuYWthbiBtZXNraXB1biBiZWx1bSB0ZXJsYWx1IGJhaWsuIEthbGF1IGRpbGloYXQgZGFyaSB2YXJpYWJlbCBkZXBlbmRlbiAoaW5jb21lKSBtZW1pbGlraSBwZW5nYXJ1aCB5YW5nIHNpZ25pZmlrYW4gdGVyaGFkYXAgdmFyaWFiZWwgaW5kZXBlbmRlbihoYXBwaW5lc3MpLg0KPGJyPg0KUnVtdXMgLyBNb2RlbCBSZWdyZXNpbnlhIGFkYWxhaCA6IGBoYXBwaW5lc3MgPSAwLjIwNCArIDAuNzE0KmluY29tZWAgDQo8YnI+DQpJbmNvbWUgYXRhdSBwZW5kYXBhdGFuIG1lbWlsaWtpIGRhbXBhayArIHRlcmhhZGFwIHJlZ3Jlc2ksIHlhbmcgYmVyYXJ0aSBpbmNvbWUgYXRhdSBwZW5kYXBhdGFuIGJlcmJhbmRpbmcgbHVydXMgZGVuZ2FuIGhhcHBpbmVzcy9rZWJhaGFnaWFhbi4gSmlrYSBwZW5kYXBhdGFuIG1lbmluZ2thdCwgbWFrYSBrZWJhaGFnaWFhbiBtZW5pbmdrYXQsIGJlZ2l0dSBqdWdhIHNlYmFsaWtueWEuDQoNCiMjIHZpc3VhbGlzYXNpIEhhc2lsIGRlbmdhbiBncmFmaWsNCmBgYHtyfQ0KZ2dwbG90KGluY29tZS5kYXRhLCBhZXMoeD1pbmNvbWUsIHk9aGFwcGluZXNzKSkrDQogIGdlb21fcG9pbnQoKSsgDQogIGdlb21fc21vb3RoKG1ldGhvZD0ibG0iLCBjb2w9ImJsYWNrIikrDQogIHN0YXRfcmVnbGluZV9lcXVhdGlvbihsYWJlbC54ID0gMywgbGFiZWwueSA9IDcpKw0KICB0aGVtZV9idygpICsNCiAgbGFicyh0aXRsZSA9ICJSZXBvcnRlZCBoYXBwaW5lc3MgYXMgYSBmdW5jdGlvbiBvZiBpbmNvbWUiLA0KICAgICAgeCA9ICJJbmNvbWUgKHgkMTAsMDAwKSIsDQogICAgICB5ID0gIkhhcHBpbmVzcyBzY29yZSAoMCB0byAxMCkiKQ0KDQoNCmBgYA0KDQojIyMgaG9tb3NkZXNpdGFzIChrZWhvbW9nZW5pdGFzIHZhcmlhbnMpDQoNCmBgYHtyfQ0KcGFyKG1mcm93PWMoMiwyKSkNCnBsb3QoaW5jb21lLmhhcHBpbmVzcy5sbSkNCnBhcihtZnJvdz1jKDEsMSkpDQpgYGANCg0KUmVzaWR1IHlhbmcgZGlzZWJ1dGthbiBkaSBhdGFzIG1lcnVwYWthbiB2YXJpYW5zLiBqaWthIHJhdGEtcmF0YSBhdGF1YSBtZWFuIGRhcmkgcmVzaWR1IHRlcnNlYnV0IHRlcmJlbnR1ayBnYXJpcyBob3Jpem9udGFsIGRhbiBtZW5kZWthdGkgMCwgbWFrYSB0aWRhayB0ZXJkYXBhdCBvdXRsaWVyIGF0YXUgcGVuY2lsYW4uIEthbGF1IGRpbGlhdCBkYXJpIFEtUXBsb3QgeWFuZyBiaXNhIGRpbGlhdCBhZGFsYWggcmVzaWR1bnlhIGhhbXBpciBtZW1iZW50dWsgc2F0dSBnYXJpcy4gZGFyaSBoYXNpbCByZXNpZHVueWEsIGtpdGEgYmlzYSBiaWxhbmcga2FsYXUgbW9kZWwgeWFuZyBkaWJ1YXQgaG9tb2dlbiAodmFyaWFuc255YSBzYW1hKS4gDQoNCg0KDQojIE11bHRpcGxlIFJlZ3Jlc3Npb24NCk11bHRpcGxlIHJlZ3Jlc3Npb24gOiAxIHZhcmlhYmVsIGluZGVwZW5kZW4gKyBuIHZhcmlhYmVsIGRlcGVuZGVuDQo8YnI+DQpkZW5nYW4gYG4gPiAxYC4NCg0KIyMgaW1wb3J0IGRhdGENCmBgYHtyfQ0KaGVhcnQuZGF0YSA9IHJlYWQuY3N2KCJkYXRhL2hlYXJ0LmRhdGEuY3N2IikNCnN1bW1hcnkoaGVhcnQuZGF0YSkNCmBgYA0KDQoNCiMjIGNlayBhc3Vtc2kNClNhbWEgc2VwZXJ0aSBzaW1wbGUgcmVncmVzc2lvbiwga2l0YSBoYXJ1cyBtZW5nZWNlayBhc3Vtc2ktYXN1bXNpIHlhbmcgYWRhLg0KIyMjIGxpbmVhcml0YXMgDQpgYGB7cn0NCnBsb3QoaGVhcnQuZGlzZWFzZSB+IGJpa2luZywgZGF0YT1oZWFydC5kYXRhKQ0KcGxvdChoZWFydC5kaXNlYXNlIH4gc21va2luZywgZGF0YT1oZWFydC5kYXRhKQ0KDQpgYGANCg0KUG9sYSBncmFmaWsgYmlraW5nIGxpbmVhciwgcG9sYSBncmFmaWsgc21va2luZyBqdWdhIGxpbmVhciBtZXNraXB1biBrdXJhbmcgYmVycG9sYSB0ZXRhcGkgbGluZWFyLiBrYXJlbmEga2VkdWFsbnlhIGxpbmVhciwga2l0YSBha2FuIG1lbWJlbnR1ayByZWdyZXNpIGxpbmVhci4NCg0KDQojIyMgaW5kZXBlbmRlbnNpIGF0YXUgYXV0b2tvcmVsYXNpDQpgYGB7cn0NCmNvcihoZWFydC5kYXRhJGJpa2luZywgaGVhcnQuZGF0YSRzbW9raW5nKQ0KYGBgDQprb3JlbGFzaSBhbnRhcmEgYmlraW5nIGRhbiBzbW9raW5nIGhhbnlhIDAuMDE1IGF0YXUgMS41JSwgbWFrYSBiaXNhIGRpcGFzdGlrYW4gYmFod2EgdmFyaWFiZWwgZGVwZW5kZW4ga2l0YSB0aWRhayBhdXRva29yZWxhc2kuIGtpdGEgYmlzYSBtZW5nZ3VuYWthbiBrZWR1YSBwYXJhbWV0ZXIgdGVyc2VidXQuDQoNCiMjIyBob21vc2Rlc2l0YXMgKGtlaG9tb2dlbml0YXMgdmFyaWFucykNCmFrYW4gZGkgdGVzIHNldGVsYWggcGxvdG55YSB0ZXJiZW50dWsgDQoNCiMjIyBub3JtYWxpdGFzDQpgYGB7cn0NCmhpc3QoaGVhcnQuZGF0YSRoZWFydC5kaXNlYXNlKQ0KYGBgDQpoYXNpbCBkYXJpIGhpc3RvZ3JhbSBkaSBhdGFzIGtpcmEta2lyYSBkYXRhbnlhIGJlcnNlYmFyIG5vcm1hbCBhdGF1IGJlcmJlbnR1ayBsb25jZW5nIChiZWxsLXNoYXBlZCksIG1ha2EgZGF0YSBraXRhIG1lcnVwYWthbiBub3JtYWwuDQoNCg0KIyMgTGluZWFyIHJlZ3Jlc3Npb24gYW5hbGlzaXMNCg0KYGBge3J9DQpoZWFydC5kaXNlYXNlLmxtPC1sbShoZWFydC5kaXNlYXNlIH4gYmlraW5nICsgc21va2luZywgZGF0YSA9IGhlYXJ0LmRhdGEpDQoNCnN1bW1hcnkoaGVhcnQuZGlzZWFzZS5sbSkNCmBgYA0KRGFyaSBoYXNpbCB0ZXJzZWJ1dCBkaWRhcGF0IGJhaHdhIHAtdmFsdWUgPCBkYXJpIGFscGhhIDUlLCBkYW4gTXVsdGlwbGUgUi1zcXVhcmUgc2ViZXNhciA5Ny45NiUuIEJlcmFydGkgdGVyZGFwYXQgOTcuOTYlIHZhcmlhYmVsIHlhbmcgc3VkYWggdGVybXN1ayBrZWRhbGFtIHJlZ3Jlc2kgeWFuZyBkaWJ1YXQuIFVudHVrIHBlbmVsaXRpYW4gc2NpZW50aWZpYywgUi1zcXVhcmUgaGFydXMgbGViaWggZGFyaSBzYW1hZGVuZ2FuIDkwJS4gDQpKYWRpIHJlZ3Jlc2kgeWFuZyB0ZWxhaCBraXRhIGJ1YXQgc3VkYWggb2tlLg0KPGJyPg0KS2VkdWEgdmFyaWFiZWwgZGVwZW5kZW4gKGJpa2luZyBkYW4gc21va2luZykgbWVtaWxpa2kgcGVuZ2FydWggc2lrbmlmaWthbiB0ZXJoYWRhcCBoZWFydC5kaXNlYXNlLiANCjxicj4NClJ1bXVzIC8gTW9kZWwgUmVncmVzaW55YSBhZGFsYWggOiBgaGVhcnQuZGlzZWFzZSA9IDE0Ljk4IC0gMC4yKmJpa2luZyArIDAuMTcqc21va2luZ2ANCjxicj4NCkJpa2luZy9iZXJzZXBlZGEgbWVtaWxpa2kgZGFtcGFrIG5lZ2F0aWYgdGVyaGFkYXAgcGVueWFraXQgamFudHVuZywgZGFuIHNtb2tpbmcvbWVyb2tvayBtZW1pbGlraSBkYW1wYWsgcG9zaXRpZi4gS2FyZW5hIGluaSBwZW55YWtpdCBqYW50dW5nLCBzZW1ha2luIGtlY2lsIG5pbGFpIHJlZ3Jlc2kgeWFuZyBkaWRhcGF0IHNlbWFraW4ga2VjaWwgcmVzaWtvIHNlc2VvcmFuZyBtZW5nYWxhbWkgcGVueWFraXQgamFudHVuZy4gU2VoaW5nZ2EgQmlzYSBkaWthdGFrYW4gYmFod2EgYmlraW5nL2JlcnNlcGVkYSBtZW1pbGlraSBkYW1wYWsgeWFuZyBiYWlrIHVudHVrIHR1YnVoLCBkYW4gc21va2luZy9tZXJva29rIG1lbWlsaWtpIGRhbXBhayBuZWdhdGlmIHVudHVrIHR1YnVoLiBTbW9raW5nL21lcm9rb2sgYmlzYSBtZW1pY3UgcGVueWFraXQgamFudHVuZywgZGFuIHNlYmFsaWtueWEgcGFkYSBiaWtpbmcvYmVyc2VwZWRhLg0KDQoNCiMjIHZpc3VhbGlzYXNpIEhhc2lsIGRlbmdhbiBncmFmaWsNCmBgYHtyfQ0KcGxvdHRpbmcuZGF0YTwtZXhwYW5kLmdyaWQoDQogIGJpa2luZyA9IHNlcShtaW4oaGVhcnQuZGF0YSRiaWtpbmcpLCBtYXgoaGVhcnQuZGF0YSRiaWtpbmcpLCBsZW5ndGgub3V0PTMwKSwNCiAgICBzbW9raW5nPWMobWluKGhlYXJ0LmRhdGEkc21va2luZyksIG1lYW4oaGVhcnQuZGF0YSRzbW9raW5nKSwgbWF4KGhlYXJ0LmRhdGEkc21va2luZykpKQ0KDQpwbG90dGluZy5kYXRhJHByZWRpY3RlZC55IDwtIHByZWRpY3QubG0oaGVhcnQuZGlzZWFzZS5sbSwgbmV3ZGF0YT1wbG90dGluZy5kYXRhKQ0KDQpwbG90dGluZy5kYXRhJHNtb2tpbmcgPC0gYXMuZmFjdG9yKHJvdW5kKHBsb3R0aW5nLmRhdGEkc21va2luZywgZGlnaXRzID0gMikpDQoNCg0KZ2dwbG90KGhlYXJ0LmRhdGEsIGFlcyh4PWJpa2luZywgeT1oZWFydC5kaXNlYXNlKSkgKw0KICBnZW9tX3BvaW50KCkrDQogIGdlb21fbGluZShkYXRhPXBsb3R0aW5nLmRhdGEsIGFlcyh4PWJpa2luZywgeT1wcmVkaWN0ZWQueSwgY29sb3I9c21va2luZyksIHNpemU9MS4yNSkrDQogIHRoZW1lX2J3KCkgKw0KICBsYWJzKHRpdGxlID0gIlJhdGVzIG9mIGhlYXJ0IGRpc2Vhc2UgKCUgb2YgcG9wdWxhdGlvbikgXG4gYXMgYSBmdW5jdGlvbiBvZiBiaWtpbmcgdG8gd29yayBhbmQgc21va2luZyIsDQogICAgICB4ID0gIkJpa2luZyB0byB3b3JrICglIG9mIHBvcHVsYXRpb24pIiwNCiAgICAgIHkgPSAiSGVhcnQgZGlzZWFzZSAoJSBvZiBwb3B1bGF0aW9uKSIsDQogICAgICBjb2xvciA9ICJTbW9raW5nIFxuICglIG9mIHBvcHVsYXRpb24pIikNCg0KYGBgDQoNCiMjIyBob21vc2Rlc2l0YXMgKGtlaG9tb2dlbml0YXMgdmFyaWFucykNCg0KYGBge3J9DQpwYXIobWZyb3c9YygyLDIpKQ0KcGxvdChoZWFydC5kaXNlYXNlLmxtKQ0KcGFyKG1mcm93PWMoMSwxKSkNCmBgYA0KDQpzYW1hIHNlcGVydGkgc2ltcGxlIHJlZ3Jlc2ksIHJlc2lkdW55YSB0aWRhayBtZW51bmp1a2thbiBhZGFueWEgYmlhcywgZGFuIGJpc2EgZGliaWxuYWcgbW9kZWwga2l0YSBjb2NvayB1bnR1ayBhc3Vtc2kgaG9tb2dlbml0YXMuDQoNCg0KDQoNCg0KDQo=