Generate Data
getmode <- function(v) {
x<-v
lim.inf=min(x)-1; lim.sup=max(x)+1
# hist(x,freq=FALSE,breaks=seq(lim.inf,lim.sup,0.2))
s<-density(x,from=lim.inf,to=lim.sup,bw=0.2)
n<-length(s$y)
v1<-s$y[1:(n-2)];
v2<-s$y[2:(n-1)];
v3<-s$y[3:n]
ix<-1+which((v1<v2)&(v2>v3))
#lines(s$x,s$y,col="red")
#points(s$x[ix],s$y[ix],col="blue")
md <- s$x[which(s$y==max(s$y))]
md
}
createDataWithContamination_EXP <- function(sample_size , rateData , rateContamination ,contamination_prop ){
data <- rexp(sample_size , rate = rateData)
contaminations <- rexp(sample_size , rate =rateContamination)
contaminations <- sort(contaminations)[(sample_size-(sample_size*contamination_prop)):sample_size]
data_with_contamination <- c(data, contaminations)
list(
data = data,
contaminations = contaminations,
data_with_contamination = data_with_contamination
)
}
Data Generations Factors
- sample size (20,50,100,200)
- Distribution Parameters \(\lambda\) (0.5)
- Contamination Distribution Parameters (0.05)
- contamination (10% , 20% , 30%)
generateData <- function(sampleSize , rate,rate_contamination , contamination ){
results = NULL
#create 1000 random sample with contamination
for(i in 1:2000){
#generate data
data_with_contamination <- createDataWithContamination_EXP(sampleSize,rate,rate_contamination ,contamination)$data_with_contamination
#Code To Handling outlier
#Quantile based flooring and capping
#In this technique, the outlier is capped at a certain value above the upper percentile value or floored at a factor below the lower percentile value.
estimated_rate_Before_Handling <- eexp(data_with_contamination, ci=TRUE, conf = 0.95)$parameters[["rate"]]
q1 <- quantile(data_with_contamination , c(.25))[["25%"]]
q3 <- quantile(data_with_contamination , c(.75))[["75%"]]
IQR <- q3-q1
lower = q1 - 1.5*IQR
upper = q3 + 1.5*IQR
outliers <- boxplot(data_with_contamination, plot=FALSE)$out
outliersPos <- which(data_with_contamination %in% outliers)
dataAfterHandling_Q_b_F_C <- data_with_contamination
dataAfterHandling_mean <- data_with_contamination
dataAfterHandling_median <- data_with_contamination
dataAfterHandling_mode <- data_with_contamination
dataAfterHandling_Q_b_F_C[dataAfterHandling_Q_b_F_C<lower] <- round(lower)
dataAfterHandling_Q_b_F_C[dataAfterHandling_Q_b_F_C>upper] <- round(upper)
estimated_rate_After_Q_b_F_C <- eexp(dataAfterHandling_Q_b_F_C, ci=TRUE, conf = 0.95)$parameters[["rate"]]
mean = mean(dataAfterHandling_mean)
dataAfterHandling_mean[outliersPos] <- round(mean)
estimated_rate_After_mean <- eexp(dataAfterHandling_mean, ci=TRUE, conf = 0.95)$parameters[["rate"]]
median = median(dataAfterHandling_median)
dataAfterHandling_median[outliersPos] <- round(median)
estimated_rate_After_median <- eexp(dataAfterHandling_median, ci=TRUE, conf = 0.95)$parameters[["rate"]]
mode = getmode(dataAfterHandling_mode)
dataAfterHandling_mode[outliersPos] <- round(mode)
estimated_rate_After_mode <- eexp(dataAfterHandling_mode, ci=TRUE, conf = 0.95)$parameters[["rate"]]
results = rbind(
results,
data.frame(
i,
estimated_rate_Before_Handling,
estimated_rate_After_Q_b_F_C,
estimated_rate_After_mean,
estimated_rate_After_median,
estimated_rate_After_mode
))
}
results
}
# different sample size with rate = .5 and contamination=10%
data_20_5_10 <- generateData(20 , .3 ,0.05, .1)
data_50_5_10 <- generateData(50 , .3 , 0.05,.1)
data_100_5_10 <- generateData(100 , .3 , 0.05,0.1)
data_200_5_10 <- generateData(200 , .3 , 0.05,0.1)
# different sample size with rate = .5 and contamination=20%
data_20_5_20 <- generateData(20 ,.5 , 0.05,0.2)
data_50_5_20 <- generateData(50 ,.5 , 0.05,0.2)
Results
doCalculations <- function(data , sampleSize ,rate , contamination) {
data %>% summarize(
sampleSize = sampleSize ,
contamination = contamination,
rate = rate,
bias_rate_Before = abs((bias(estimated_rate_Before_Handling , rate))),
bias_rate_Q_b_F_C = abs((bias(estimated_rate_After_Q_b_F_C , rate))),
bias_rate_Mean = abs((bias(estimated_rate_After_mean ,rate))),
bias_rate_Median = abs((bias(estimated_rate_After_median , rate))),
bias_rate_Mode = abs((bias(estimated_rate_After_mode ,rate))) ,
MSE_rate_Before = MSE(estimated_rate_Before_Handling , rate),
MSE_rate_Q_b_F_C = MSE(estimated_rate_After_Q_b_F_C, rate),
MSE_rate_Mean = MSE(estimated_rate_After_mean, rate),
MSE_rate_Median = MSE(estimated_rate_After_median, rate),
MSE_rate_Mode = MSE(estimated_rate_After_mode, rate)
)
}
finalResult <- NULL
finalResult <- rbind(
finalResult ,
doCalculations(data_20_3_10 , 20,0.5,10),
doCalculations(data_50_3_10 , 50,0.5,10),
doCalculations(data_100_3_10 , 100,0.5,10),
doCalculations(data_200_3_10 , 200,0.5,10),
doCalculations(data_20_3_20 , 20,0.5,20),
doCalculations(data_50_3_20 , 50,0.5,20),
doCalculations(data_100_3_20 , 100,0.5,20),
doCalculations(data_200_3_20 , 200,0.5,20),
doCalculations(data_20_3_30 , 20,0.5,30),
doCalculations(data_50_3_30 , 50,0.5,30),
doCalculations(data_100_3_30 , 100,0.5,30),
doCalculations(data_200_3_30 , 200,0.5,30)
)
finalResult %>% select(sampleSize , contamination ,bias_rate_Before , bias_rate_Q_b_F_C , bias_rate_Mean , bias_rate_Median ,bias_rate_Mode)
finalResult %>% select(sampleSize , contamination ,MSE_rate_Before , MSE_rate_Q_b_F_C , MSE_rate_Mean, MSE_rate_Median , MSE_rate_Mode)
NA
NA
#Relation Between sample size and Biased_prop for each method
finalResult %>% filter(rate==0.5) %>% select( sampleSize , contamination, bias_rate_Q_b_F_C , bias_rate_Mean , bias_rate_Median ,bias_rate_Mode , bias_rate_Before) %>%
gather("Method" , "Biased_rate" , bias_rate_Q_b_F_C , bias_rate_Mean , bias_rate_Median ,bias_rate_Mode , bias_rate_Before ) %>%
ggplot(aes(x = (sampleSize) , y = Biased_rate)) +
geom_point( aes(colour = as.factor(contamination))) +
geom_line( aes(colour = as.factor(contamination))) +
facet_wrap(.~Method)

finalResult %>% filter(rate==0.5) %>% select( sampleSize , contamination,MSE_rate_Q_b_F_C , MSE_rate_Mean, MSE_rate_Median , MSE_rate_Mode , MSE_rate_Before) %>%
gather("Method" , "MSE_rate" , MSE_rate_Q_b_F_C , MSE_rate_Mean, MSE_rate_Median , MSE_rate_Mode ,MSE_rate_Before ) %>%
ggplot(aes(x = (sampleSize) , y = MSE_rate)) +
geom_point( aes(colour = as.factor(contamination))) +
geom_line( aes(colour = as.factor(contamination))) +
facet_wrap(.~Method)
Warning in gzfile(file, "wb") :
cannot open compressed file 'C:/Users/eyada/Desktop/master/University courses/Statistical inference for data science/OutlierHandlingMethods/.Rproj.user/shared/notebooks/B66824C9-Outlier Handling (Exponential Distribution)/1/CD6BAB30B80C719B/ch93dsphw4i6h_t/0aa43442d7bf49b7b24833350a841dae.snapshot', probable reason 'No such file or directory'
Error in gzfile(file, "wb") : cannot open the connection

Warning in gzfile(file, "wb") :
cannot open compressed file 'C:/Users/eyada/Desktop/master/University courses/Statistical inference for data science/OutlierHandlingMethods/.Rproj.user/shared/notebooks/B66824C9-Outlier Handling (Exponential Distribution)/1/CD6BAB30B80C719B/ch93dsphw4i6h_t/f31ee6ce127541ad9e03df0b7d488736.snapshot', probable reason 'No such file or directory'
Error in gzfile(file, "wb") : cannot open the connection
LS0tDQp0aXRsZTogIk91dGxpZXIgSGFuZGxpbmcgTWV0aG9kcyAoVEhFIEVYUE9ORU5USUFMIGRpc3RyaWJ1dGlvbiApIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCiANCg0KYGBge3IgaW1wb3J0TGlicmFyeSAsIGVjaG89RkFMU0UgLCB3YXJuaW5nPUZBTFNFICwgZXJyb3I9RkFMU0V9DQpsaWJyYXJ5KHJvYnVzdCkNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KE1MbWV0cmljcykNCmxpYnJhcnkoU2ltRGVzaWduKQ0KbGlicmFyeSh0aWR5cikNCmxpYnJhcnkoRW52U3RhdHMpDQoNCmBgYA0KDQojIEludHJvZHVjdGlpb24gDQoNClRIRSBFWFBPTkVOVElBTCBkaXN0cmlidXRpb24gaXMgdGhlIG1vc3QgY29tbW9ubHkgdXNlZCBtb2RlbCBpbiByZWxpYWJpbGl0eSAmIGxpZmUtdGVzdGluZyBhbmFseXNpcw0KDQojRXN0aW1hdGlvbg0KDQpMZXQgJHt4fSA9ICh4XzEsIHhfMiwg4oCmLCB4X24pJCBiZSBhIHZlY3RvciBvZiBuIG9ic2VydmF0aW9ucyBmcm9tIGFuIGV4cG9uZW50aWFsIGRpc3RyaWJ1dGlvbiB3aXRoIHBhcmFtZXRlciByYXRlPSRcbGFtYmRhICQuDQoNClRoZSBtYXhpbXVtIGxpa2VsaWhvb2QgZXN0aW1hdG9yIChtbGUpIG9mICRcbGFtYmRhICQgaXMgZ2l2ZW4gYnk6DQokXGhhdHvOu31fe21sZX0gPSBcZnJhY3sxfXtcYmFye3h9fSQgd2hlcmUgJFxiYXJ7eH0gPSBcZnJhY3sxfXtufeKIkV5uX3tpPTF9IHhfaSQNCg0KDQojIEdlbmVyYXRlIERhdGEgDQoNCmBgYHtyIEZ1bmN0aW9uVXNlZFRvR2VuZXJhdGVEYXRhV2l0aF9jb250YW1pbmF0aW9uICxlY2hvPVRSVUUgLCB3YXJuaW5nPUZBTFNFfQ0KDQpnZXRtb2RlIDwtIGZ1bmN0aW9uKHYpIHsNCiAgDQogICAgeDwtdg0KICAgIGxpbS5pbmY9bWluKHgpLTE7IGxpbS5zdXA9bWF4KHgpKzENCg0KICAgIyBoaXN0KHgsZnJlcT1GQUxTRSxicmVha3M9c2VxKGxpbS5pbmYsbGltLnN1cCwwLjIpKQ0KICAgIHM8LWRlbnNpdHkoeCxmcm9tPWxpbS5pbmYsdG89bGltLnN1cCxidz0wLjIpDQogICAgbjwtbGVuZ3RoKHMkeSkNCiAgICB2MTwtcyR5WzE6KG4tMildOw0KICAgIHYyPC1zJHlbMjoobi0xKV07DQogICAgdjM8LXMkeVszOm5dDQogICAgaXg8LTErd2hpY2goKHYxPHYyKSYodjI+djMpKQ0KICAgIA0KICAgICNsaW5lcyhzJHgscyR5LGNvbD0icmVkIikNCiAgICAjcG9pbnRzKHMkeFtpeF0scyR5W2l4XSxjb2w9ImJsdWUiKQ0KICAgIA0KICAgIG1kIDwtIHMkeFt3aGljaChzJHk9PW1heChzJHkpKV0gDQoNCiAgICBtZA0KfQ0KDQpjcmVhdGVEYXRhV2l0aENvbnRhbWluYXRpb25fRVhQIDwtIGZ1bmN0aW9uKHNhbXBsZV9zaXplICwgcmF0ZURhdGEgLCByYXRlQ29udGFtaW5hdGlvbiAsY29udGFtaW5hdGlvbl9wcm9wICl7DQoNCmRhdGEgPC0gcmV4cChzYW1wbGVfc2l6ZSAsIHJhdGUgPSByYXRlRGF0YSkgDQpjb250YW1pbmF0aW9ucyA8LSByZXhwKHNhbXBsZV9zaXplICwgcmF0ZSA9cmF0ZUNvbnRhbWluYXRpb24pDQpjb250YW1pbmF0aW9ucyA8LSBzb3J0KGNvbnRhbWluYXRpb25zKVsoc2FtcGxlX3NpemUtKHNhbXBsZV9zaXplKmNvbnRhbWluYXRpb25fcHJvcCkpOnNhbXBsZV9zaXplXQ0KICAgDQogIGRhdGFfd2l0aF9jb250YW1pbmF0aW9uIDwtIGMoZGF0YSwgY29udGFtaW5hdGlvbnMpIA0KDQogICBsaXN0KA0KICAgICBkYXRhID0gZGF0YSwNCiAgICAgY29udGFtaW5hdGlvbnMgPSBjb250YW1pbmF0aW9ucywNCiAgICAgZGF0YV93aXRoX2NvbnRhbWluYXRpb24gPSBkYXRhX3dpdGhfY29udGFtaW5hdGlvbg0KICAgICkNCiAgIA0KfQ0KDQpgYGANCg0KIyMjIERhdGEgR2VuZXJhdGlvbnMgRmFjdG9ycw0KDQoxLiBzYW1wbGUgc2l6ZSAgKDIwLDUwLDEwMCwyMDApIA0KMi4gRGlzdHJpYnV0aW9uIFBhcmFtZXRlcnMgICRcbGFtYmRhJCAoMC41KQ0KMy4gQ29udGFtaW5hdGlvbiBEaXN0cmlidXRpb24gUGFyYW1ldGVycyAoMC4wNSkNCjMuIGNvbnRhbWluYXRpb24gKDEwJSAsIDIwJSAsIDMwJSkNCg0KDQoNCmBgYHtyIGdlbmVyYXRlRGF0ZUZ1bmN0aW9uICx3YXJuaW5nPUZBTFNFfQ0KDQpnZW5lcmF0ZURhdGEgPC0gZnVuY3Rpb24oc2FtcGxlU2l6ZSAsIHJhdGUscmF0ZV9jb250YW1pbmF0aW9uICwgY29udGFtaW5hdGlvbiApew0KICANCiAgDQpyZXN1bHRzID0gTlVMTA0KI2NyZWF0ZSAxMDAwIHJhbmRvbSBzYW1wbGUgd2l0aCBjb250YW1pbmF0aW9uDQpmb3IoaSBpbiAxOjIwMDApew0KICAjZ2VuZXJhdGUgZGF0YSAgDQogIGRhdGFfd2l0aF9jb250YW1pbmF0aW9uIDwtICBjcmVhdGVEYXRhV2l0aENvbnRhbWluYXRpb25fRVhQKHNhbXBsZVNpemUscmF0ZSxyYXRlX2NvbnRhbWluYXRpb24gLGNvbnRhbWluYXRpb24pJGRhdGFfd2l0aF9jb250YW1pbmF0aW9uDQogICANCiAgI0NvZGUgVG8gSGFuZGxpbmcgb3V0bGllciANCiAgDQoNCiAgI1F1YW50aWxlIGJhc2VkIGZsb29yaW5nIGFuZCBjYXBwaW5nDQogICNJbiB0aGlzIHRlY2huaXF1ZSwgdGhlIG91dGxpZXIgaXMgY2FwcGVkIGF0IGEgY2VydGFpbiB2YWx1ZSBhYm92ZSB0aGUgdXBwZXIgcGVyY2VudGlsZSB2YWx1ZSBvciBmbG9vcmVkICAgYXQgYSBmYWN0b3IgYmVsb3cgdGhlIGxvd2VyIHBlcmNlbnRpbGUgdmFsdWUuDQogIA0KZXN0aW1hdGVkX3JhdGVfQmVmb3JlX0hhbmRsaW5nIDwtIGVleHAoZGF0YV93aXRoX2NvbnRhbWluYXRpb24sIGNpPVRSVUUsIGNvbmYgPSAwLjk1KSRwYXJhbWV0ZXJzW1sicmF0ZSJdXQ0KDQogIA0KcTEgPC0gcXVhbnRpbGUoZGF0YV93aXRoX2NvbnRhbWluYXRpb24gICwgYyguMjUpKVtbIjI1JSJdXQ0KcTMgPC0gcXVhbnRpbGUoZGF0YV93aXRoX2NvbnRhbWluYXRpb24gICwgYyguNzUpKVtbIjc1JSJdXQ0KSVFSIDwtIHEzLXExDQpsb3dlciAgPSBxMSAtIDEuNSpJUVINCnVwcGVyID0gcTMgKyAxLjUqSVFSDQoNCg0Kb3V0bGllcnMgPC0gYm94cGxvdChkYXRhX3dpdGhfY29udGFtaW5hdGlvbiwgcGxvdD1GQUxTRSkkb3V0DQpvdXRsaWVyc1BvcyA8LSB3aGljaChkYXRhX3dpdGhfY29udGFtaW5hdGlvbiAlaW4lIG91dGxpZXJzKQ0KIA0KICANCiANCmRhdGFBZnRlckhhbmRsaW5nX1FfYl9GX0MgPC0gZGF0YV93aXRoX2NvbnRhbWluYXRpb24NCmRhdGFBZnRlckhhbmRsaW5nX21lYW4gPC0gZGF0YV93aXRoX2NvbnRhbWluYXRpb24NCmRhdGFBZnRlckhhbmRsaW5nX21lZGlhbiA8LSBkYXRhX3dpdGhfY29udGFtaW5hdGlvbg0KZGF0YUFmdGVySGFuZGxpbmdfbW9kZSA8LSBkYXRhX3dpdGhfY29udGFtaW5hdGlvbg0KDQoNCmRhdGFBZnRlckhhbmRsaW5nX1FfYl9GX0NbZGF0YUFmdGVySGFuZGxpbmdfUV9iX0ZfQzxsb3dlcl0gPC0gcm91bmQobG93ZXIpDQpkYXRhQWZ0ZXJIYW5kbGluZ19RX2JfRl9DW2RhdGFBZnRlckhhbmRsaW5nX1FfYl9GX0M+dXBwZXJdIDwtIHJvdW5kKHVwcGVyKQ0KZXN0aW1hdGVkX3JhdGVfQWZ0ZXJfUV9iX0ZfQyA8LSBlZXhwKGRhdGFBZnRlckhhbmRsaW5nX1FfYl9GX0MsIGNpPVRSVUUsIGNvbmYgPSAwLjk1KSRwYXJhbWV0ZXJzW1sicmF0ZSJdXQ0KDQoNCm1lYW4gPSBtZWFuKGRhdGFBZnRlckhhbmRsaW5nX21lYW4pDQpkYXRhQWZ0ZXJIYW5kbGluZ19tZWFuW291dGxpZXJzUG9zXSA8LSByb3VuZChtZWFuKQ0KZXN0aW1hdGVkX3JhdGVfQWZ0ZXJfbWVhbiA8LSAgZWV4cChkYXRhQWZ0ZXJIYW5kbGluZ19tZWFuLCBjaT1UUlVFLCBjb25mID0gMC45NSkkcGFyYW1ldGVyc1tbInJhdGUiXV0NCg0KIA0KbWVkaWFuID0gbWVkaWFuKGRhdGFBZnRlckhhbmRsaW5nX21lZGlhbikNCmRhdGFBZnRlckhhbmRsaW5nX21lZGlhbltvdXRsaWVyc1Bvc10gPC0gcm91bmQobWVkaWFuKQ0KZXN0aW1hdGVkX3JhdGVfQWZ0ZXJfbWVkaWFuIDwtICBlZXhwKGRhdGFBZnRlckhhbmRsaW5nX21lZGlhbiwgY2k9VFJVRSwgY29uZiA9IDAuOTUpJHBhcmFtZXRlcnNbWyJyYXRlIl1dDQogDQoNCm1vZGUgPSBnZXRtb2RlKGRhdGFBZnRlckhhbmRsaW5nX21vZGUpDQpkYXRhQWZ0ZXJIYW5kbGluZ19tb2RlW291dGxpZXJzUG9zXSA8LSByb3VuZChtb2RlKSANCmVzdGltYXRlZF9yYXRlX0FmdGVyX21vZGUgPC0gZWV4cChkYXRhQWZ0ZXJIYW5kbGluZ19tb2RlLCBjaT1UUlVFLCBjb25mID0gMC45NSkkcGFyYW1ldGVyc1tbInJhdGUiXV0NCg0KIA0KDQoNCiByZXN1bHRzID0gcmJpbmQoDQogICByZXN1bHRzLA0KICAgZGF0YS5mcmFtZSgNCiAgICAgaSwNCiAgICAgZXN0aW1hdGVkX3JhdGVfQmVmb3JlX0hhbmRsaW5nLA0KICAgICBlc3RpbWF0ZWRfcmF0ZV9BZnRlcl9RX2JfRl9DLA0KICAgICBlc3RpbWF0ZWRfcmF0ZV9BZnRlcl9tZWFuLA0KICAgICBlc3RpbWF0ZWRfcmF0ZV9BZnRlcl9tZWRpYW4sDQogICAgIGVzdGltYXRlZF9yYXRlX0FmdGVyX21vZGUgDQogICAgICkpDQp9DQoNCnJlc3VsdHMNCn0NCmBgYA0KDQoNCmBgYHtyfQ0KIA0KDQojIGRpZmZlcmVudCBzYW1wbGUgc2l6ZSB3aXRoIHJhdGUgPSAuNSAgYW5kIGNvbnRhbWluYXRpb249MTAlDQpkYXRhXzIwXzVfMTAgPC0gZ2VuZXJhdGVEYXRhKDIwICwgLjMgLDAuMDUsIC4xKQ0KZGF0YV81MF81XzEwIDwtIGdlbmVyYXRlRGF0YSg1MCAsIC4zICwgMC4wNSwuMSkNCmRhdGFfMTAwXzVfMTAgPC0gZ2VuZXJhdGVEYXRhKDEwMCAsIC4zICwgMC4wNSwwLjEpDQpkYXRhXzIwMF81XzEwIDwtIGdlbmVyYXRlRGF0YSgyMDAgLCAuMyAsIDAuMDUsMC4xKQ0KDQogDQojIGRpZmZlcmVudCBzYW1wbGUgc2l6ZSAgd2l0aCByYXRlID0gLjUgYW5kIGNvbnRhbWluYXRpb249MjAlDQpkYXRhXzIwXzVfMjAgPC0gZ2VuZXJhdGVEYXRhKDIwICwuNSAsIDAuMDUsMC4yKQ0KZGF0YV81MF81XzIwIDwtIGdlbmVyYXRlRGF0YSg1MCAsLjUgLCAwLjA1LDAuMikNCmRhdGFfMTAwXzVfMjAgPC0gZ2VuZXJhdGVEYXRhKDEwMCwuNSAsMC4wNSwwLjIpDQpkYXRhXzIwMF81XzIwIDwtIGdlbmVyYXRlRGF0YSgyMDAsLjUgLDAuMDUsMC4yKQ0KICANCg0KIA0KIyBkaWZmZXJlbnQgc2FtcGxlIHNpemUgd2l0aCByYXRlID0gLjUgIGFuZCBjb250YW1pbmF0aW9uPTMwJQ0KZGF0YV8yMF81XzMwIDwtIGdlbmVyYXRlRGF0YSgyMCAsIC41ICwwLjA1LDAuMykNCmRhdGFfNTBfNV8zMCA8LSBnZW5lcmF0ZURhdGEoNTAgLCAuNSAsIDAuMDUsMC4zKQ0KZGF0YV8xMDBfNV8zMCA8LSBnZW5lcmF0ZURhdGEoMTAwLCAuNSAsMC4wNSwwLjMpDQpkYXRhXzIwMF81XzMwIDwtIGdlbmVyYXRlRGF0YSgyMDAsLjUgLDAuMDUsMC4zKQ0KDQogDQogDQpgYGANCg0KDQojIFJlc3VsdHMgDQoNCmBgYHtyfQ0KDQpkb0NhbGN1bGF0aW9ucyA8LSBmdW5jdGlvbihkYXRhICwgc2FtcGxlU2l6ZSAscmF0ZSAsIGNvbnRhbWluYXRpb24pIHsNCiAgDQogICBkYXRhICU+JSBzdW1tYXJpemUoDQogIHNhbXBsZVNpemUgPSBzYW1wbGVTaXplICwNCiAgY29udGFtaW5hdGlvbiA9IGNvbnRhbWluYXRpb24sDQogIHJhdGUgPSByYXRlLA0KIA0KIA0KICBiaWFzX3JhdGVfQmVmb3JlID0gYWJzKChiaWFzKGVzdGltYXRlZF9yYXRlX0JlZm9yZV9IYW5kbGluZyAsIHJhdGUpKSksDQogIGJpYXNfcmF0ZV9RX2JfRl9DID0gYWJzKChiaWFzKGVzdGltYXRlZF9yYXRlX0FmdGVyX1FfYl9GX0MgLCByYXRlKSkpLA0KICBiaWFzX3JhdGVfTWVhbiA9IGFicygoYmlhcyhlc3RpbWF0ZWRfcmF0ZV9BZnRlcl9tZWFuICxyYXRlKSkpLA0KICBiaWFzX3JhdGVfTWVkaWFuID0gYWJzKChiaWFzKGVzdGltYXRlZF9yYXRlX0FmdGVyX21lZGlhbiAsIHJhdGUpKSksDQogIGJpYXNfcmF0ZV9Nb2RlID0gYWJzKChiaWFzKGVzdGltYXRlZF9yYXRlX0FmdGVyX21vZGUgLHJhdGUpKSkgLA0KICANCiAgTVNFX3JhdGVfQmVmb3JlID0gTVNFKGVzdGltYXRlZF9yYXRlX0JlZm9yZV9IYW5kbGluZyAsIHJhdGUpLA0KICBNU0VfcmF0ZV9RX2JfRl9DICA9IE1TRShlc3RpbWF0ZWRfcmF0ZV9BZnRlcl9RX2JfRl9DLCByYXRlKSwNCiAgTVNFX3JhdGVfTWVhbiAgPSBNU0UoZXN0aW1hdGVkX3JhdGVfQWZ0ZXJfbWVhbiwgcmF0ZSksDQogIE1TRV9yYXRlX01lZGlhbiAgID0gTVNFKGVzdGltYXRlZF9yYXRlX0FmdGVyX21lZGlhbiwgcmF0ZSksDQogIE1TRV9yYXRlX01vZGUgID0gTVNFKGVzdGltYXRlZF9yYXRlX0FmdGVyX21vZGUsIHJhdGUpDQopIA0KfQ0KDQoNCg0KYGBgDQoNCmBgYHtyIGNhbGxfQ2FsY3VsYXRpb25zRnVuY3Rpb24gICx3YXJuaW5nPUZBTFNFIH0NCg0KZmluYWxSZXN1bHQgPC0gTlVMTCANCg0KZmluYWxSZXN1bHQgPC0gcmJpbmQoDQogIGZpbmFsUmVzdWx0ICwNCiAgICAgICAgICAgICAgICBkb0NhbGN1bGF0aW9ucyhkYXRhXzIwXzNfMTAgLCAyMCwwLjUsMTApLA0KICAgICAgICAgICAgICAgIGRvQ2FsY3VsYXRpb25zKGRhdGFfNTBfM18xMCAsIDUwLDAuNSwxMCksDQogICAgICAgICAgICAgICAgZG9DYWxjdWxhdGlvbnMoZGF0YV8xMDBfM18xMCAsIDEwMCwwLjUsMTApLA0KICAgICAgICAgICAgICAgIGRvQ2FsY3VsYXRpb25zKGRhdGFfMjAwXzNfMTAgLCAyMDAsMC41LDEwKSwNCiAgDQogICAgICAgICAgICAgICAgZG9DYWxjdWxhdGlvbnMoZGF0YV8yMF8zXzIwICwgMjAsMC41LDIwKSwNCiAgICAgICAgICAgICAgICBkb0NhbGN1bGF0aW9ucyhkYXRhXzUwXzNfMjAgLCA1MCwwLjUsMjApLA0KICAgICAgICAgICAgICAgIGRvQ2FsY3VsYXRpb25zKGRhdGFfMTAwXzNfMjAgLCAxMDAsMC41LDIwKSwNCiAgICAgICAgICAgICAgICBkb0NhbGN1bGF0aW9ucyhkYXRhXzIwMF8zXzIwICwgMjAwLDAuNSwyMCksDQogICAgIA0KICAgICAgICAgICAgICAgIGRvQ2FsY3VsYXRpb25zKGRhdGFfMjBfM18zMCAsIDIwLDAuNSwzMCksDQogICAgICAgICAgICAgICAgZG9DYWxjdWxhdGlvbnMoZGF0YV81MF8zXzMwICwgNTAsMC41LDMwKSwNCiAgICAgICAgICAgICAgICBkb0NhbGN1bGF0aW9ucyhkYXRhXzEwMF8zXzMwICwgMTAwLDAuNSwzMCksDQogICAgICAgICAgICAgICAgZG9DYWxjdWxhdGlvbnMoZGF0YV8yMDBfM18zMCAsIDIwMCwwLjUsMzApDQogIA0KICAgDQogICANCiAgICAgICAgICAgICAgICAgICAgICkNCg0KDQoNCg0KDQpgYGANCg0KDQoNCmBgYHtyICB3YXJuaW5nPUZBTFNFfQ0KDQpmaW5hbFJlc3VsdCAlPiUgc2VsZWN0KHNhbXBsZVNpemUgLCBjb250YW1pbmF0aW9uICxiaWFzX3JhdGVfQmVmb3JlICwgYmlhc19yYXRlX1FfYl9GX0MgLCBiaWFzX3JhdGVfTWVhbiAsIGJpYXNfcmF0ZV9NZWRpYW4gLGJpYXNfcmF0ZV9Nb2RlKQ0KDQoNCg0KZmluYWxSZXN1bHQgJT4lIHNlbGVjdChzYW1wbGVTaXplICwgY29udGFtaW5hdGlvbiAsTVNFX3JhdGVfQmVmb3JlICAsIE1TRV9yYXRlX1FfYl9GX0MgICwgTVNFX3JhdGVfTWVhbiwgTVNFX3JhdGVfTWVkaWFuICwgTVNFX3JhdGVfTW9kZSkNCiANCg0KYGBgDQoNCmBgYHtyIFJlc3VsdFZpc3VhbGl6YXRpb24wM30NCg0KI1JlbGF0aW9uIEJldHdlZW4gc2FtcGxlIHNpemUgYW5kIEJpYXNlZF9wcm9wIGZvciBlYWNoIG1ldGhvZA0KDQpmaW5hbFJlc3VsdCAlPiUgZmlsdGVyKHJhdGU9PTAuNSkgJT4lIHNlbGVjdCggc2FtcGxlU2l6ZSAsIGNvbnRhbWluYXRpb24sIGJpYXNfcmF0ZV9RX2JfRl9DICwgYmlhc19yYXRlX01lYW4gLCBiaWFzX3JhdGVfTWVkaWFuICxiaWFzX3JhdGVfTW9kZSAsIGJpYXNfcmF0ZV9CZWZvcmUpICU+JSANCiAgZ2F0aGVyKCJNZXRob2QiICwgIkJpYXNlZF9yYXRlIiAsIGJpYXNfcmF0ZV9RX2JfRl9DICwgYmlhc19yYXRlX01lYW4gLCBiaWFzX3JhdGVfTWVkaWFuICxiaWFzX3JhdGVfTW9kZSAsIGJpYXNfcmF0ZV9CZWZvcmUgKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IChzYW1wbGVTaXplKSAsIHkgPSBCaWFzZWRfcmF0ZSkpICsgDQogIGdlb21fcG9pbnQoIGFlcyhjb2xvdXIgPSBhcy5mYWN0b3IoY29udGFtaW5hdGlvbikpKSArIA0KICAgIGdlb21fbGluZSggYWVzKGNvbG91ciA9IGFzLmZhY3Rvcihjb250YW1pbmF0aW9uKSkpICsgDQoNCiAgZmFjZXRfd3JhcCgufk1ldGhvZCkNCg0KDQoNCmZpbmFsUmVzdWx0ICU+JSBmaWx0ZXIocmF0ZT09MC41KSAgJT4lIHNlbGVjdCggc2FtcGxlU2l6ZSAsIGNvbnRhbWluYXRpb24sTVNFX3JhdGVfUV9iX0ZfQyAgLCBNU0VfcmF0ZV9NZWFuLCBNU0VfcmF0ZV9NZWRpYW4gLCBNU0VfcmF0ZV9Nb2RlICwgTVNFX3JhdGVfQmVmb3JlKSAlPiUgDQogIGdhdGhlcigiTWV0aG9kIiAsICJNU0VfcmF0ZSIgLCAgTVNFX3JhdGVfUV9iX0ZfQyAgLCBNU0VfcmF0ZV9NZWFuLCBNU0VfcmF0ZV9NZWRpYW4gLCBNU0VfcmF0ZV9Nb2RlICxNU0VfcmF0ZV9CZWZvcmUgKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IChzYW1wbGVTaXplKSAsIHkgPSBNU0VfcmF0ZSkpICsgDQogIGdlb21fcG9pbnQoIGFlcyhjb2xvdXIgPSBhcy5mYWN0b3IoY29udGFtaW5hdGlvbikpKSArIA0KICBnZW9tX2xpbmUoIGFlcyhjb2xvdXIgPSBhcy5mYWN0b3IoY29udGFtaW5hdGlvbikpKSArIA0KICBmYWNldF93cmFwKC5+TWV0aG9kKQ0KDQogDQoNCg0KDQoNCmBgYA0KIA0KDQoNCiMgUmVmZXJlbmNlcyANCg0KMS4gaHR0cHM6Ly9ycHVicy5jb20vbXBmb2xleTczLzQ1OTA0MA0KDQoyLiBodHRwczovL3NlYXJjaC5yLXByb2plY3Qub3JnL0NSQU4vcmVmbWFucy9FbnZTdGF0cy9odG1sL2VleHAuaHRtbA0KDQo=