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()

Putting them in one place and making it long format (Slide 5.15-5.18)

d1 <- z_tit1$get_qi(xvalue="x1", qi="fd")
d2 <- z_tit2$get_qi(xvalue="x1", qi="fd")
d3 <- z_tit3$get_qi(xvalue="x1", qi="fd")
  
dfd <- as.data.frame(cbind(d1, d2, d3))
tidd <- dfd %>% 
  gather(class, simv, 1:3)
head(tidd)

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