Part-1:
Re-implement the computations described on pages 5.2-5.18 of the lecture slides using the Zelig 5 syntax
Reading data and making binary variable:
library(radiant.data)
data("Titanic")
titanic <- titanic %>%
mutate(survival = as.integer(survived)) %>%
mutate(survival = sjmisc::rec(survival, rec = "2=0; 1=1")) %>%
select(survival,survived, everything())
head(titanic)
Building model using zelig(Slide 5.2):
library(Zelig)
z_tit <- zlogit$new()
z_tit$zelig(survival ~ age + sex*pclass + fare, data = titanic)
summary(z_tit)
Model:
Call:
z_tit$zelig(formula = survival ~ age + sex * pclass + fare, data = titanic)
Deviance Residuals:
Min 1Q Median 3Q Max
-3.0634 -0.6641 -0.4943 0.4336 2.4941
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) 4.8978215 0.6131092 7.988 1.37e-15
age -0.0387245 0.0068044 -5.691 1.26e-08
sexmale -3.8996177 0.5015659 -7.775 7.55e-15
pclass2nd -1.5923247 0.6024844 -2.643 0.00822
pclass3rd -4.1382715 0.5601819 -7.387 1.50e-13
fare -0.0009058 0.0020509 -0.442 0.65874
sexmale:pclass2nd -0.0600076 0.6372949 -0.094 0.92498
sexmale:pclass3rd 2.5019110 0.5479901 4.566 4.98e-06
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 1409.99 on 1042 degrees of freedom
Residual deviance: 931.45 on 1035 degrees of freedom
AIC: 947.45
Number of Fisher Scoring iterations: 5
Next step: Use 'setx' method
Age effect (Slide 5.3-5.4)
z_tit$setrange(age=min(titanic$age):max(titanic$age))
z_tit$sim()
z_tit$graph()

Fare effect (Slide 5.5-5.6)
z_tit$setrange(fare=min(titanic$fare):max(titanic$fare))
z_tit$sim()
z_tit$graph()

Sex difference | Only simulated first difference(Slide 5.7-5.9)
z_tit$setx(sex="male")
z_tit$setx1(sex="female")
z_tit$sim()
fd <- z_tit$get_qi(xvalue="x1", qi="fd")
summary(fd)
V1
Min. :0.1259
1st Qu.:0.2269
Median :0.2542
Mean :0.2556
3rd Qu.:0.2841
Max. :0.3905
z_tit$graph()


Testing the class variations in sex difference using Zelig (Slide 5.10-5.14)
First Class:
z_tit1 <- zlogit$new()
z_tit1$zelig(survival ~ age +sex*pclass + fare, data=titanic)
#z_tit1<-z_tit
z_tit1$setx(sex="male", pclass="1st")
z_tit1$setx1(sex="female", pclass="1st")
z_tit1$sim()
z_tit1$graph()

Second Class:
z_tit2 <- zlogit$new()
z_tit2$zelig(survival ~ age +sex*pclass + fare, data=titanic)
z_tit2$setx(sex="male", pclass="2nd")
z_tit2$setx1(sex="female", pclass="2nd")
z_tit2$sim()
z_tit2$graph()

Third Class:
z_tit3 <- zlogit$new()
z_tit3$zelig(survival ~ age +sex*pclass + fare, data=titanic)
z_tit3$setx(sex="male", pclass="3rd")
z_tit3$setx1(sex="female", pclass="3rd")
z_tit3$sim()
z_tit3$graph()

Using Group By
tidd %>%
group_by(class) %>%
summarise(mean = mean(simv), sd = sd(simv))
Plotting:
ggplot(tidd, aes(simv)) + geom_histogram() + facet_grid(~class)+theme_bw()

Part 2: Conducting regression analysis using Zelig on my own data set
Binary Dependent Variable and Data:
The dataset i will use includes all valid felony, misdemeanor, and violation crimes reported to the New York City Police Department (NYPD) for all complete quarters so far in year 2017. I am only interested in the likelihood of whether crime was successfully completed(successfully accomplished by criminal) or attempted(not completed). Therefore, my binary dependent variable will be whether the crime was completed or not.
Prepering Dataset for Binary Dependent Variable:
ny_c<-read.csv("C:/Users/Afzal Hossain/Documents/A.Spring 2019/SOC 712/HW/HW6/NYPD_Complaint_Data_Current__Year_To_Date_.csv")
ny_cr<-select(ny_c, 'CRM_ATPT_CPTD_CD',"VIC_RACE",'VIC_SEX',"VIC_AGE_GROUP",'BORO_NM','LAW_CAT_CD')
dim(ny_cr)
[1] 464065 6
#Recoding Age
ny_cr$VIC_AGE_GROUP<-as.character(ny_cr$VIC_AGE_GROUP)
ny_cr$VIC_AGE_GROUP[ny_cr$VIC_AGE_GROUP=='<18']<-"CHILD"
ny_cr$VIC_AGE_GROUP[ny_cr$VIC_AGE_GROUP=='18-24' |
ny_cr$VIC_AGE_GROUP=='25-44']<-'YOUNG'
ny_cr$VIC_AGE_GROUP[ny_cr$VIC_AGE_GROUP=='45-64']<-'MIDDLE AGE'
ny_cr$VIC_AGE_GROUP[ny_cr$VIC_AGE_GROUP=='65+']<-'OLD'
# Recoding Variable for Sex
ny_cr$VIC_SEX<-as.character(ny_cr$VIC_SEX)
ny_cr$VIC_SEX[ny_cr$VIC_SEX=='E' |
ny_cr$VIC_SEX=='D' | ny_cr$VIC_SEX== 'U']<-NA
# Recoding Variable for Race
ny_cr$VIC_RACE<-as.character(ny_cr$VIC_RACE)
ny_cr$VIC_RACE[ny_cr$VIC_RACE=='ASIAN / PACIFIC ISLANDER' |
ny_cr$VIC_RACE=='BLACK HISPANIC'|
ny_cr$VIC_RACE =='BLACK' |
ny_cr$VIC_RACE=='WHITE HISPANIC' |
ny_cr$VIC_RACE=='AMERICAN INDIAN/ALASKAN NATIVE' |
ny_cr$VIC_RACE== 'UNKNOWN'] <- "NON WHITE"
#Changing data type
ny_cr$VIC_RACE<- as.factor(ny_cr$VIC_RACE)
ny_cr$VIC_SEX<- as.factor(ny_cr$VIC_SEX)
ny_cr$BORO_NM<- as.factor(ny_cr$BORO_NM)
ny_cr$LAW_CAT_CD<- as.factor(ny_cr$LAW_CAT_CD)
head(ny_cr)
ny_cr%>% select(VIC_AGE_GROUP)%>% distinct()
Victims age has a lot of negative and unusual number because of human error. Therefore, we will only take our four category that we created.
ny_cr <- subset(ny_cr, VIC_AGE_GROUP == "CHILD" | VIC_AGE_GROUP == "YOUNG" |VIC_AGE_GROUP == "MIDDLE AGE" |VIC_AGE_GROUP == "OLD")
dim(ny_cr)
[1] 332277 6
I lost around ten thousand record but I am not concern since, it is still a large sample.
#Creating Binary variable 1/0 instead of Completed/Attempted
ny_cr <- ny_cr %>%
mutate(Crime_Completed =as.integer(CRM_ATPT_CPTD_CD)) %>%
select(Crime_Completed,CRM_ATPT_CPTD_CD, everything())
ny_cr <- ny_cr%>%
filter(!is.na(VIC_RACE),!is.na(VIC_SEX),!is.na(LAW_CAT_CD),!is.na(CRM_ATPT_CPTD_CD))%>%
mutate(Crm_Completed = sjmisc::rec(Crime_Completed, rec = "1=0; 2=1")) %>%
select(Crm_Completed,CRM_ATPT_CPTD_CD,everything())
ny_cr$VIC_AGE_GROUP<- as.factor(ny_cr$VIC_AGE_GROUP)
ny_cr$Crm_Completed<- as.factor(ny_cr$Crm_Completed)
head(ny_cr)
Building logistic model using Zelig:
z.crime <- zelig(Crm_Completed ~ VIC_RACE + VIC_SEX* LAW_CAT_CD+VIC_AGE_GROUP , model = "logit", data = ny_cr, cite = FALSE)
|=========================================================================================|100% ~0 s remaining
summary(z.crime)
Model:
Call:
z5$zelig(formula = Crm_Completed ~ VIC_RACE + VIC_SEX * LAW_CAT_CD +
VIC_AGE_GROUP, data = ny_cr)
Deviance Residuals:
Min 1Q Median 3Q Max
-3.5260 0.1099 0.1183 0.2544 0.3419
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) 3.12091 0.05796 53.846 < 2e-16
VIC_RACEWHITE -0.04482 0.03276 -1.368 0.1713
VIC_SEXM -0.26563 0.03258 -8.153 3.54e-16
LAW_CAT_CDMISDEMEANOR 1.69260 0.04970 34.056 < 2e-16
LAW_CAT_CDVIOLATION 2.79991 0.10722 26.114 < 2e-16
VIC_AGE_GROUPMIDDLE AGE 0.19673 0.06072 3.240 0.0012
VIC_AGE_GROUPOLD 0.13482 0.07390 1.824 0.0681
VIC_AGE_GROUPYOUNG 0.29341 0.05712 5.137 2.79e-07
VIC_SEXM:LAW_CAT_CDMISDEMEANOR 0.11751 0.06834 1.720 0.0855
VIC_SEXM:LAW_CAT_CDVIOLATION 0.17115 0.17184 0.996 0.3193
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 54163 on 332187 degrees of freedom
Residual deviance: 49223 on 332178 degrees of freedom
AIC: 49243
Number of Fisher Scoring iterations: 8
Next step: Use 'setx' method
I don’t see any statistically significant coefficient which is not surprising to me since, whether a crime completed or just attempted not really depend on age, gender or race. Its more to do with whither someone call police or in some situation, victim is physically superior to the criminal and can defend themself.
But from here, I can say that log odds of crime event completed is less when the victim is Male compare to Female (-.265). Furthermore, when the crime is just a violation compare to Misdemeanor, the log odd are higher that crime will be completed, 2.799 compare to 1.693 and it is true for whither victims are male or female.Age group seems to have no effect, but if victim is old, crime has less log odd of being completed. Now, let’s use simulation-based results interpretation for better understand the result.
Making sense of regression results
First, I will look at sex difference:
x <- setx(z.crime, VIC_SEX = "M")
x1 <- setx(z.crime, VIC_SEX = "F")
c <- sim(z.crime, x = x, x1 = x1)
fd <- c$get_qi(xvalue="x1", qi="fd")
summary(fd)
V1
Min. :-0.0002070
1st Qu.: 0.0007046
Median : 0.0009567
Mean : 0.0009613
3rd Qu.: 0.0012279
Max. : 0.0020448
I can see that on average a crime will be completed 0.00096 more if the victims is female.
plot(c)

Looking at race difference:
wx <- setx(z.crime, VIC_RACE = "WHITE")
nwx1 <- setx(z.crime, VIC_RACE = "NON WHITE")
r <- sim(z.crime, x = wx, x1 = nwx1)
fd <- r$get_qi(xvalue ="x1", qi="fd")
summary(fd)
V1
Min. :-0.0003192
1st Qu.: 0.0001266
Median : 0.0002658
Mean : 0.0002684
3rd Qu.: 0.0004022
Max. : 0.0009140
If the victims is Non White, on average the crime slightly more likely to be completed(0.00027)
plot(r)

Test the crime variations in sex difference
# Felony
v1x <- setx(z.crime, VIC_SEX = "M", LAW_CAT_CD = "FELONY")
v1x1 <- setx(z.crime, VIC_SEX = "F", LAW_CAT_CD ="FELONY")
v1s <- sim(z.crime, x = v1x, x1 = v1x1)
#Misdemeanor
v2x <- setx(z.crime, VIC_SEX = "M", LAW_CAT_CD = "MISDEMEANOR")
v2x1 <- setx(z.crime, VIC_SEX = "F", LAW_CAT_CD = "MISDEMEANOR")
v2s <- sim(z.crime, x = v2x, x1 = v2x1)
#Violation
v3x <- setx(z.crime, VIC_SEX = "M", LAW_CAT_CD = "VIOLATION")
v3x1 <- setx(z.crime, VIC_SEX = "F", LAW_CAT_CD = "VIOLATION")
v3s <- sim(z.crime, x = v3x, x1 = v3x1)
Plotting Felony Crime:
plot(v1s)

Plotting Misdemeanor Crime:
plot(v2s)

Plotting Violation Crime:
plot(v3s)

Putting all of them in one place:
d1 <- v1s$get_qi(xvalue="x1", qi="fd")
d2 <- v2s$get_qi(xvalue="x1", qi="fd")
d3 <- v3s$get_qi(xvalue="x1", qi="fd")
dfd <- as.data.frame(cbind(d1, d2, d3))
law_categories <- dfd %>%
gather(Law, simv, 1:3)
head(law_categories)
Group Different Crime:
law_categories %>%
group_by(Law) %>%
summarise(mean = mean(simv), sd = sd(simv))
For all three different crime (Felony, Misdemeanor and Violation), if the victims is Female, crime is more likely to be completed, even though it is not statistically significant.
Plotting the Distributions:
ggplot(law_categories, aes(simv)) + geom_histogram() + facet_grid(~Law) +geom_vline(xintercept=mean(law_categories$simv), color="red") +theme_bw()

LS0tDQp0aXRsZTogIk1kIEFmemFsIEhvc3NhaW4gfCBTb2MgNzEyIHxIb21lIFdvcmsgNiINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCg0KIyMjKipQYXJ0LTE6KioNCg0KKipSZS1pbXBsZW1lbnQgdGhlIGNvbXB1dGF0aW9ucyBkZXNjcmliZWQgb24gcGFnZXMgNS4yLTUuMTggb2YgdGhlIGxlY3R1cmUgc2xpZGVzIHVzaW5nIHRoZSBaZWxpZyA1IHN5bnRheCoqDQoNCg0KDQoNCg0KIyMjIyoqUmVhZGluZyBkYXRhIGFuZCBtYWtpbmcgYmluYXJ5IHZhcmlhYmxlOioqDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KHJhZGlhbnQuZGF0YSkNCmRhdGEoIlRpdGFuaWMiKQ0KDQp0aXRhbmljIDwtIHRpdGFuaWMgJT4lDQogIG11dGF0ZShzdXJ2aXZhbCA9IGFzLmludGVnZXIoc3Vydml2ZWQpKSAlPiUgDQogIG11dGF0ZShzdXJ2aXZhbCA9IHNqbWlzYzo6cmVjKHN1cnZpdmFsLCByZWMgPSAiMj0wOyAxPTEiKSkgJT4lIA0KICBzZWxlY3Qoc3Vydml2YWwsc3Vydml2ZWQsIGV2ZXJ5dGhpbmcoKSkNCg0KaGVhZCh0aXRhbmljKQ0KYGBgDQoNCiMjIyMqKkJ1aWxkaW5nIG1vZGVsIHVzaW5nIHplbGlnKFNsaWRlIDUuMik6KioNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxpYnJhcnkoWmVsaWcpDQoNCnpfdGl0IDwtIHpsb2dpdCRuZXcoKQ0Kel90aXQkemVsaWcoc3Vydml2YWwgfiBhZ2UgKyBzZXgqcGNsYXNzICsgZmFyZSwgZGF0YSA9IHRpdGFuaWMpDQpzdW1tYXJ5KHpfdGl0KQ0KYGBgDQoNCg0KIyMjIyoqQWdlIGVmZmVjdCAoU2xpZGUgNS4zLTUuNCkqKg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0Kel90aXQkc2V0cmFuZ2UoYWdlPW1pbih0aXRhbmljJGFnZSk6bWF4KHRpdGFuaWMkYWdlKSkNCnpfdGl0JHNpbSgpDQp6X3RpdCRncmFwaCgpDQoNCmBgYA0KDQoNCiMjIyMqKkZhcmUgZWZmZWN0IChTbGlkZSA1LjUtNS42KSoqDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQoNCnpfdGl0JHNldHJhbmdlKGZhcmU9bWluKHRpdGFuaWMkZmFyZSk6bWF4KHRpdGFuaWMkZmFyZSkpDQp6X3RpdCRzaW0oKQ0Kel90aXQkZ3JhcGgoKQ0KDQpgYGANCg0KIyMjIyoqU2V4IGRpZmZlcmVuY2UgfCBPbmx5IHNpbXVsYXRlZCBmaXJzdCBkaWZmZXJlbmNlKFNsaWRlIDUuNy01LjkpKioNCg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0Kel90aXQkc2V0eChzZXg9Im1hbGUiKQ0Kel90aXQkc2V0eDEoc2V4PSJmZW1hbGUiKQ0Kel90aXQkc2ltKCkNCmZkIDwtIHpfdGl0JGdldF9xaSh4dmFsdWU9IngxIiwgcWk9ImZkIikNCnN1bW1hcnkoZmQpDQoNCmBgYA0KDQoNCmBgYHtyIGZpZy5hc3A9MS4xLCBmaWcud2lkdGg9OC41LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0Kel90aXQkZ3JhcGgoKQ0KDQpgYGANCg0KDQojIyMqKlRlc3RpbmcgdGhlIGNsYXNzIHZhcmlhdGlvbnMgaW4gc2V4IGRpZmZlcmVuY2UgdXNpbmcgWmVsaWcgKFNsaWRlIDUuMTAtNS4xNCkqKg0KDQojIyMjKipGaXJzdCBDbGFzczogKioNCg0KYGBge3IgZmlnLmFzcD0xLjEsIGZpZy53aWR0aD04LjUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQp6X3RpdDEgPC0gemxvZ2l0JG5ldygpDQp6X3RpdDEkemVsaWcoc3Vydml2YWwgfiBhZ2UgK3NleCpwY2xhc3MgKyBmYXJlLCBkYXRhPXRpdGFuaWMpDQojel90aXQxPC16X3RpdA0Kel90aXQxJHNldHgoc2V4PSJtYWxlIiwgcGNsYXNzPSIxc3QiKQ0Kel90aXQxJHNldHgxKHNleD0iZmVtYWxlIiwgcGNsYXNzPSIxc3QiKQ0Kel90aXQxJHNpbSgpDQp6X3RpdDEkZ3JhcGgoKQ0KDQpgYGANCg0KDQojIyMjKipTZWNvbmQgQ2xhc3M6ICoqDQoNCmBgYHtyIGZpZy5hc3A9MS4xLCBmaWcud2lkdGg9OC41LCBtZXNzYWdlPVRSVUUsIHdhcm5pbmc9VFJVRX0NCnpfdGl0MiA8LSB6bG9naXQkbmV3KCkNCnpfdGl0MiR6ZWxpZyhzdXJ2aXZhbCB+IGFnZSArc2V4KnBjbGFzcyArIGZhcmUsIGRhdGE9dGl0YW5pYykNCnpfdGl0MiRzZXR4KHNleD0ibWFsZSIsIHBjbGFzcz0iMm5kIikNCnpfdGl0MiRzZXR4MShzZXg9ImZlbWFsZSIsIHBjbGFzcz0iMm5kIikNCnpfdGl0MiRzaW0oKQ0Kel90aXQyJGdyYXBoKCkNCmBgYA0KDQoNCiMjIyMqKlRoaXJkIENsYXNzOiAqKg0KDQpgYGB7ciBmaWcuYXNwPTEuMSwgZmlnLndpZHRoPTguNSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0Kel90aXQzIDwtIHpsb2dpdCRuZXcoKQ0Kel90aXQzJHplbGlnKHN1cnZpdmFsIH4gYWdlICtzZXgqcGNsYXNzICsgZmFyZSwgZGF0YT10aXRhbmljKQ0Kel90aXQzJHNldHgoc2V4PSJtYWxlIiwgcGNsYXNzPSIzcmQiKQ0Kel90aXQzJHNldHgxKHNleD0iZmVtYWxlIiwgcGNsYXNzPSIzcmQiKQ0Kel90aXQzJHNpbSgpDQp6X3RpdDMkZ3JhcGgoKQ0KDQoNCmBgYA0KDQoNCiMjIyMqKlB1dHRpbmcgdGhlbSBpbiBvbmUgcGxhY2UgYW5kIG1ha2luZyBpdCBsb25nIGZvcm1hdCAoU2xpZGUgNS4xNS01LjE4KSoqDQpgYGB7cn0NCmQxIDwtIHpfdGl0MSRnZXRfcWkoeHZhbHVlPSJ4MSIsIHFpPSJmZCIpDQpkMiA8LSB6X3RpdDIkZ2V0X3FpKHh2YWx1ZT0ieDEiLCBxaT0iZmQiKQ0KZDMgPC0gel90aXQzJGdldF9xaSh4dmFsdWU9IngxIiwgcWk9ImZkIikNCiAgDQpkZmQgPC0gYXMuZGF0YS5mcmFtZShjYmluZChkMSwgZDIsIGQzKSkNCnRpZGQgPC0gZGZkICU+JSANCiAgZ2F0aGVyKGNsYXNzLCBzaW12LCAxOjMpDQoNCmhlYWQodGlkZCkNCmBgYA0KDQoNCiMjIyMqKlVzaW5nIEdyb3VwIEJ5KioNCmBgYHtyfQ0KdGlkZCAlPiUgDQogIGdyb3VwX2J5KGNsYXNzKSAlPiUgDQogIHN1bW1hcmlzZShtZWFuID0gbWVhbihzaW12KSwgc2QgPSBzZChzaW12KSkNCg0KDQpgYGANCg0KDQojIyMjKipQbG90dGluZzogKioNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpnZ3Bsb3QodGlkZCwgYWVzKHNpbXYpKSArIGdlb21faGlzdG9ncmFtKCkgKyBmYWNldF9ncmlkKH5jbGFzcykrdGhlbWVfYncoKQ0KYGBgDQoNCiMjKipQYXJ0IDI6IENvbmR1Y3RpbmcgcmVncmVzc2lvbiBhbmFseXNpcyB1c2luZyBaZWxpZyBvbiBteSBvd24gZGF0YSBzZXQqKg0KDQoNCg0KDQoNCioqQmluYXJ5IERlcGVuZGVudCBWYXJpYWJsZSBhbmQgRGF0YTogKioNCg0KVGhlIGRhdGFzZXQgaSB3aWxsIHVzZSBpbmNsdWRlcyBhbGwgdmFsaWQgZmVsb255LCBtaXNkZW1lYW5vciwgYW5kIHZpb2xhdGlvbiBjcmltZXMgcmVwb3J0ZWQgdG8gdGhlIFtOZXcgWW9yayBDaXR5IFBvbGljZSBEZXBhcnRtZW50IChOWVBEKV0oaHR0cHM6Ly9kYXRhLmNpdHlvZm5ld3lvcmsudXMvUHVibGljLVNhZmV0eS9OWUMtY3JpbWUvcWI3dS1yYm1yKSBmb3IgYWxsIGNvbXBsZXRlIHF1YXJ0ZXJzIHNvIGZhciBpbiB5ZWFyIDIwMTcuIEkgYW0gb25seSBpbnRlcmVzdGVkIGluIHRoZSBsaWtlbGlob29kIG9mIHdoZXRoZXIgY3JpbWUgd2FzIHN1Y2Nlc3NmdWxseSBjb21wbGV0ZWQoc3VjY2Vzc2Z1bGx5IGFjY29tcGxpc2hlZCBieSBjcmltaW5hbCkgb3IgYXR0ZW1wdGVkKG5vdCBjb21wbGV0ZWQpLiBUaGVyZWZvcmUsIG15IGJpbmFyeSBkZXBlbmRlbnQgdmFyaWFibGUgd2lsbCBiZSB3aGV0aGVyIHRoZSBjcmltZSB3YXMgY29tcGxldGVkIG9yIG5vdC4gDQoNCg0KIyMjICoqUHJlcGVyaW5nIERhdGFzZXQgZm9yIEJpbmFyeSBEZXBlbmRlbnQgVmFyaWFibGU6KioNCg0KDQpgYGB7cn0NCm55X2M8LXJlYWQuY3N2KCJDOi9Vc2Vycy9BZnphbCBIb3NzYWluL0RvY3VtZW50cy9BLlNwcmluZyAyMDE5L1NPQyA3MTIvSFcvSFc2L05ZUERfQ29tcGxhaW50X0RhdGFfQ3VycmVudF9fWWVhcl9Ub19EYXRlXy5jc3YiKQ0KDQpueV9jcjwtc2VsZWN0KG55X2MsICdDUk1fQVRQVF9DUFREX0NEJywiVklDX1JBQ0UiLCdWSUNfU0VYJywiVklDX0FHRV9HUk9VUCIsJ0JPUk9fTk0nLCdMQVdfQ0FUX0NEJykNCmRpbShueV9jcikNCg0KYGBgDQoNCg0KDQoNCg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KI1JlY29kaW5nIEFnZQ0KbnlfY3IkVklDX0FHRV9HUk9VUDwtYXMuY2hhcmFjdGVyKG55X2NyJFZJQ19BR0VfR1JPVVApDQpueV9jciRWSUNfQUdFX0dST1VQW255X2NyJFZJQ19BR0VfR1JPVVA9PSc8MTgnXTwtIkNISUxEIg0KbnlfY3IkVklDX0FHRV9HUk9VUFtueV9jciRWSUNfQUdFX0dST1VQPT0nMTgtMjQnIHwNCiAgICAgICAgICAgICAgICAgIG55X2NyJFZJQ19BR0VfR1JPVVA9PScyNS00NCddPC0nWU9VTkcnDQpueV9jciRWSUNfQUdFX0dST1VQW255X2NyJFZJQ19BR0VfR1JPVVA9PSc0NS02NCddPC0nTUlERExFIEFHRScNCm55X2NyJFZJQ19BR0VfR1JPVVBbbnlfY3IkVklDX0FHRV9HUk9VUD09JzY1KyddPC0nT0xEJw0KDQoNCiMgUmVjb2RpbmcgVmFyaWFibGUgZm9yIFNleA0KbnlfY3IkVklDX1NFWDwtYXMuY2hhcmFjdGVyKG55X2NyJFZJQ19TRVgpIA0KbnlfY3IkVklDX1NFWFtueV9jciRWSUNfU0VYPT0nRScgfA0KICAgICAgICAgICAgICAgICAgIG55X2NyJFZJQ19TRVg9PSdEJyB8IG55X2NyJFZJQ19TRVg9PSAnVSddPC1OQQ0KDQojIFJlY29kaW5nIFZhcmlhYmxlIGZvciBSYWNlDQpueV9jciRWSUNfUkFDRTwtYXMuY2hhcmFjdGVyKG55X2NyJFZJQ19SQUNFKQ0KbnlfY3IkVklDX1JBQ0VbbnlfY3IkVklDX1JBQ0U9PSdBU0lBTiAvIFBBQ0lGSUMgSVNMQU5ERVInIHwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBueV9jciRWSUNfUkFDRT09J0JMQUNLIEhJU1BBTklDJ3wNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG55X2NyJFZJQ19SQUNFID09J0JMQUNLJyB8DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBueV9jciRWSUNfUkFDRT09J1dISVRFIEhJU1BBTklDJyB8DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBueV9jciRWSUNfUkFDRT09J0FNRVJJQ0FOIElORElBTi9BTEFTS0FOIE5BVElWRScgfA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnlfY3IkVklDX1JBQ0U9PSAnVU5LTk9XTiddIDwtICJOT04gV0hJVEUiIA0KDQojQ2hhbmdpbmcgZGF0YSB0eXBlDQpueV9jciRWSUNfUkFDRTwtIGFzLmZhY3RvcihueV9jciRWSUNfUkFDRSkNCm55X2NyJFZJQ19TRVg8LSBhcy5mYWN0b3IobnlfY3IkVklDX1NFWCkNCm55X2NyJEJPUk9fTk08LSBhcy5mYWN0b3IobnlfY3IkQk9ST19OTSkNCm55X2NyJExBV19DQVRfQ0Q8LSBhcy5mYWN0b3IobnlfY3IkTEFXX0NBVF9DRCkNCmhlYWQobnlfY3IpDQpgYGANCg0KDQpgYGB7cn0NCg0KbnlfY3IlPiUgc2VsZWN0KFZJQ19BR0VfR1JPVVApJT4lIGRpc3RpbmN0KCkNCmBgYA0KDQpWaWN0aW1zIGFnZSBoYXMgYSBsb3Qgb2YgbmVnYXRpdmUgYW5kIHVudXN1YWwgbnVtYmVyIGJlY2F1c2Ugb2YgaHVtYW4gZXJyb3IuIFRoZXJlZm9yZSwgd2Ugd2lsbCBvbmx5IHRha2Ugb3VyIGZvdXIgY2F0ZWdvcnkgdGhhdCB3ZSBjcmVhdGVkLg0KDQoNCmBgYHtyfQ0KbnlfY3IgPC0gc3Vic2V0KG55X2NyLCBWSUNfQUdFX0dST1VQID09ICJDSElMRCIgfCBWSUNfQUdFX0dST1VQID09ICJZT1VORyIgfFZJQ19BR0VfR1JPVVAgPT0gIk1JRERMRSBBR0UiIHxWSUNfQUdFX0dST1VQID09ICJPTEQiKQ0KZGltKG55X2NyKQ0KDQpgYGANCg0KDQpJIGxvc3QgYXJvdW5kIHRlbiB0aG91c2FuZCByZWNvcmQgYnV0IEkgYW0gbm90IGNvbmNlcm4gc2luY2UsIGl0IGlzIHN0aWxsIGEgbGFyZ2Ugc2FtcGxlLg0KDQoNCg0KYGBge3J9DQojQ3JlYXRpbmcgQmluYXJ5IHZhcmlhYmxlIDEvMCBpbnN0ZWFkIG9mIENvbXBsZXRlZC9BdHRlbXB0ZWQNCm55X2NyIDwtIG55X2NyICU+JSANCiAgbXV0YXRlKENyaW1lX0NvbXBsZXRlZCA9YXMuaW50ZWdlcihDUk1fQVRQVF9DUFREX0NEKSkgJT4lIA0KICBzZWxlY3QoQ3JpbWVfQ29tcGxldGVkLENSTV9BVFBUX0NQVERfQ0QsIGV2ZXJ5dGhpbmcoKSkNCg0KbnlfY3IgPC0gbnlfY3IlPiUgDQogICAgICAgICAgZmlsdGVyKCFpcy5uYShWSUNfUkFDRSksIWlzLm5hKFZJQ19TRVgpLCFpcy5uYShMQVdfQ0FUX0NEKSwhaXMubmEoQ1JNX0FUUFRfQ1BURF9DRCkpJT4lDQogICAgICAgICAgICAgICAgIG11dGF0ZShDcm1fQ29tcGxldGVkID0gc2ptaXNjOjpyZWMoQ3JpbWVfQ29tcGxldGVkLCByZWMgPSAiMT0wOyAyPTEiKSkgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3QoQ3JtX0NvbXBsZXRlZCxDUk1fQVRQVF9DUFREX0NELGV2ZXJ5dGhpbmcoKSkNCg0KbnlfY3IkVklDX0FHRV9HUk9VUDwtIGFzLmZhY3RvcihueV9jciRWSUNfQUdFX0dST1VQKQ0KbnlfY3IkQ3JtX0NvbXBsZXRlZDwtIGFzLmZhY3RvcihueV9jciRDcm1fQ29tcGxldGVkKQ0KDQpoZWFkKG55X2NyKQ0KDQpgYGANCg0KIyMjKipCdWlsZGluZyBsb2dpc3RpYyBtb2RlbCB1c2luZyBgWmVsaWdgOiAqKg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0Kei5jcmltZSA8LSB6ZWxpZyhDcm1fQ29tcGxldGVkIH4gVklDX1JBQ0UgKyBWSUNfU0VYKiBMQVdfQ0FUX0NEK1ZJQ19BR0VfR1JPVVAgLCBtb2RlbCA9ICJsb2dpdCIsIGRhdGEgPSBueV9jciwgY2l0ZSA9IEZBTFNFKQ0Kc3VtbWFyeSh6LmNyaW1lKQ0KYGBgDQoNCkkgZG9uJ3Qgc2VlIGFueSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGNvZWZmaWNpZW50IHdoaWNoIGlzIG5vdCBzdXJwcmlzaW5nIHRvIG1lIHNpbmNlLCB3aGV0aGVyIGEgY3JpbWUgY29tcGxldGVkIG9yIGp1c3QgYXR0ZW1wdGVkIG5vdCByZWFsbHkgZGVwZW5kIG9uIGFnZSwgZ2VuZGVyIG9yIHJhY2UuIEl0cyBtb3JlIHRvIGRvIHdpdGggd2hpdGhlciBzb21lb25lIGNhbGwgcG9saWNlIG9yIGluIHNvbWUgc2l0dWF0aW9uLCB2aWN0aW0gaXMgcGh5c2ljYWxseSBzdXBlcmlvciB0byB0aGUgY3JpbWluYWwgYW5kIGNhbiBkZWZlbmQgdGhlbXNlbGYuDQoNCkJ1dCBmcm9tIGhlcmUsIEkgY2FuIHNheSB0aGF0IGxvZyBvZGRzIG9mIGNyaW1lIGV2ZW50IGNvbXBsZXRlZCBpcyBsZXNzIHdoZW4gdGhlIHZpY3RpbSBpcyBNYWxlIGNvbXBhcmUgdG8gRmVtYWxlICgtLjI2NSkuIEZ1cnRoZXJtb3JlLCB3aGVuIHRoZSBjcmltZSBpcyBqdXN0IGEgdmlvbGF0aW9uIGNvbXBhcmUgdG8gTWlzZGVtZWFub3IsIHRoZSBsb2cgb2RkIGFyZSBoaWdoZXIgdGhhdCBjcmltZSB3aWxsIGJlIGNvbXBsZXRlZCwgMi43OTkgY29tcGFyZSB0byAxLjY5MyBhbmQgaXQgaXMgdHJ1ZSBmb3Igd2hpdGhlciB2aWN0aW1zIGFyZSBtYWxlIG9yIGZlbWFsZS5BZ2UgZ3JvdXAgc2VlbXMgdG8gaGF2ZSBubyBlZmZlY3QsIGJ1dCBpZiB2aWN0aW0gaXMgb2xkLCBjcmltZSBoYXMgbGVzcyBsb2cgb2RkIG9mIGJlaW5nIGNvbXBsZXRlZC4gTm93LCBsZXQncyB1c2Ugc2ltdWxhdGlvbi1iYXNlZCByZXN1bHRzIGludGVycHJldGF0aW9uIGZvciBiZXR0ZXIgdW5kZXJzdGFuZCB0aGUgcmVzdWx0Lg0KDQoNCiMjIyoqTWFraW5nIHNlbnNlIG9mIHJlZ3Jlc3Npb24gcmVzdWx0cyAqKg0KDQojIyMjKipGaXJzdCwgSSB3aWxsIGxvb2sgYXQgc2V4IGRpZmZlcmVuY2U6KioNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnggPC0gc2V0eCh6LmNyaW1lLCBWSUNfU0VYID0gIk0iKQ0KeDEgPC0gc2V0eCh6LmNyaW1lLCBWSUNfU0VYID0gIkYiKQ0KYyA8LSBzaW0oei5jcmltZSwgeCA9IHgsIHgxID0geDEpDQoNCmZkIDwtIGMkZ2V0X3FpKHh2YWx1ZT0ieDEiLCBxaT0iZmQiKQ0Kc3VtbWFyeShmZCkNCg0KYGBgDQoNCg0KSSBjYW4gc2VlIHRoYXQgb24gYXZlcmFnZSBhIGNyaW1lIHdpbGwgYmUgY29tcGxldGVkIDAuMDAwOTYgbW9yZSBpZiB0aGUgdmljdGltcyBpcyBmZW1hbGUuDQoNCg0KYGBge3IgZmlnLmFzcD0xLjEsIGZpZy53aWR0aD04LjUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpwbG90KGMpDQpgYGANCg0KDQojIyMjKipMb29raW5nIGF0IHJhY2UgZGlmZmVyZW5jZTogKioNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnd4IDwtIHNldHgoei5jcmltZSwgVklDX1JBQ0UgPSAiV0hJVEUiKQ0Kbnd4MSA8LSBzZXR4KHouY3JpbWUsIFZJQ19SQUNFID0gIk5PTiBXSElURSIpDQpyIDwtIHNpbSh6LmNyaW1lLCB4ID0gd3gsIHgxID0gbnd4MSkNCg0KZmQgPC0gciRnZXRfcWkoeHZhbHVlID0ieDEiLCBxaT0iZmQiKQ0Kc3VtbWFyeShmZCkNCmBgYA0KDQpJZiB0aGUgdmljdGltcyBpcyBOb24gV2hpdGUsIG9uIGF2ZXJhZ2UgdGhlIGNyaW1lIHNsaWdodGx5IG1vcmUgbGlrZWx5IHRvIGJlIGNvbXBsZXRlZCgwLjAwMDI3KQ0KDQpgYGB7ciBmaWcuYXNwPTEuMSwgZmlnLndpZHRoPTguNSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnBsb3QocikNCmBgYA0KDQoNCiMjIyMqKlRlc3QgdGhlIGNyaW1lIHZhcmlhdGlvbnMgaW4gc2V4IGRpZmZlcmVuY2UqKg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQojIEZlbG9ueQ0KdjF4IDwtIHNldHgoei5jcmltZSwgVklDX1NFWCA9ICJNIiwgTEFXX0NBVF9DRCA9ICJGRUxPTlkiKQ0KdjF4MSA8LSBzZXR4KHouY3JpbWUsIFZJQ19TRVggPSAiRiIsIExBV19DQVRfQ0QgPSJGRUxPTlkiKQ0KdjFzIDwtIHNpbSh6LmNyaW1lLCB4ID0gdjF4LCB4MSA9IHYxeDEpDQoNCg0KI01pc2RlbWVhbm9yDQp2MnggPC0gc2V0eCh6LmNyaW1lLCBWSUNfU0VYID0gIk0iLCBMQVdfQ0FUX0NEID0gIk1JU0RFTUVBTk9SIikNCnYyeDEgPC0gc2V0eCh6LmNyaW1lLCBWSUNfU0VYID0gIkYiLCBMQVdfQ0FUX0NEID0gIk1JU0RFTUVBTk9SIikNCnYycyA8LSBzaW0oei5jcmltZSwgeCA9IHYyeCwgeDEgPSB2MngxKQ0KDQoNCiNWaW9sYXRpb24NCnYzeCA8LSBzZXR4KHouY3JpbWUsIFZJQ19TRVggPSAiTSIsIExBV19DQVRfQ0QgPSAiVklPTEFUSU9OIikNCnYzeDEgPC0gc2V0eCh6LmNyaW1lLCBWSUNfU0VYID0gIkYiLCBMQVdfQ0FUX0NEID0gIlZJT0xBVElPTiIpDQp2M3MgPC0gc2ltKHouY3JpbWUsIHggPSB2M3gsIHgxID0gdjN4MSkNCg0KYGBgDQoNCiMjIyMqKlBsb3R0aW5nIEZlbG9ueSBDcmltZToqKg0KDQpgYGB7ciBmaWcuYXNwPTEuMSwgZmlnLndpZHRoPTguNSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnBsb3QodjFzKQ0KDQpgYGANCg0KIyMjIyoqUGxvdHRpbmcgTWlzZGVtZWFub3IgQ3JpbWU6KioNCg0KYGBge3IgZmlnLmFzcD0xLjEsIGZpZy53aWR0aD04LjUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpwbG90KHYycykNCmBgYA0KDQoNCiMjIyMqKlBsb3R0aW5nIFZpb2xhdGlvbiBDcmltZToqKg0KDQpgYGB7ciBmaWcuYXNwPTEuMSwgZmlnLndpZHRoPTguNSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnBsb3QodjNzKQ0KYGBgDQoNCg0KDQojIyMqKlB1dHRpbmcgYWxsIG9mIHRoZW0gaW4gb25lIHBsYWNlOiAqKg0KDQpgYGB7cn0NCmQxIDwtIHYxcyRnZXRfcWkoeHZhbHVlPSJ4MSIsIHFpPSJmZCIpDQpkMiA8LSB2MnMkZ2V0X3FpKHh2YWx1ZT0ieDEiLCBxaT0iZmQiKQ0KZDMgPC0gdjNzJGdldF9xaSh4dmFsdWU9IngxIiwgcWk9ImZkIikNCg0KZGZkIDwtIGFzLmRhdGEuZnJhbWUoY2JpbmQoZDEsIGQyLCBkMykpDQoNCg0KDQpsYXdfY2F0ZWdvcmllcyA8LSBkZmQgJT4lIA0KICBnYXRoZXIoTGF3LCBzaW12LCAxOjMpDQoNCmhlYWQobGF3X2NhdGVnb3JpZXMpDQpgYGANCg0KIyMjIyoqR3JvdXAgRGlmZmVyZW50IENyaW1lOiAqKg0KDQpgYGB7cn0NCmxhd19jYXRlZ29yaWVzICU+JSANCiAgZ3JvdXBfYnkoTGF3KSAlPiUgDQogIHN1bW1hcmlzZShtZWFuID0gbWVhbihzaW12KSwgc2QgPSBzZChzaW12KSkNCmBgYA0KDQpGb3IgYWxsIHRocmVlIGRpZmZlcmVudCBjcmltZSAoRmVsb255LCBNaXNkZW1lYW5vciBhbmQgVmlvbGF0aW9uKSwgaWYgdGhlIHZpY3RpbXMgaXMgRmVtYWxlLCBjcmltZSBpcyBtb3JlIGxpa2VseSB0byBiZSBjb21wbGV0ZWQsIGV2ZW4gdGhvdWdoIGl0IGlzIG5vdCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50Lg0KDQojIyMjKipQbG90dGluZyB0aGUgRGlzdHJpYnV0aW9uczogKioNCg0KYGBge3IgZmlnLmFzcD0uNSwgZmlnLndpZHRoPTguNSxtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQpnZ3Bsb3QobGF3X2NhdGVnb3JpZXMsIGFlcyhzaW12KSkgKyBnZW9tX2hpc3RvZ3JhbSgpICsgZmFjZXRfZ3JpZCh+TGF3KSArZ2VvbV92bGluZSh4aW50ZXJjZXB0PW1lYW4obGF3X2NhdGVnb3JpZXMkc2ltdiksIGNvbG9yPSJyZWQiKSArZ2VvbV92bGluZSh4aW50ZXJjZXB0PXNkKGxhd19jYXRlZ29yaWVzJHNpbXYpLCBjb2xvcj0iYmx1ZSIpICt0aGVtZV9idygpDQoNCmBgYA0K