if X is the count of independent Bernoulli trials required to achieve the rth successful trial when the probability of success is constant p.
Generate Data
getmode <- function(v) {
uniqv <- unique(v)
uniqv[which.max(tabulate(match(v, uniqv)))]
}
createDataWithContamination_NB_P <- function(sample_size , contamination_prop ){
data <- rnbinom(sample_size , size = 2, prob = .2)
contaminations <- rpois(round((sample_size*contamination_prop)), lambda = 32)
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 (2 , 0.2)
- contamination (10% , 20% , 30%)
generateData <- function(sampleSize , contamination ){
results = NULL
#create 1000 random sample with contamination
for(i in 1:2000){
#generate data
data_with_contamination <- createDataWithContamination_NB_P(sampleSize,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.
lower = quantile(data_with_contamination , c(.025))[["2.5%"]]
upper = quantile(data_with_contamination , c(.975))[["97.5%"]]
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_prop_After_Q_b_F_C <- enbinom(dataAfterHandling_Q_b_F_C, size = 2)$parameters[2][["prob"]]
mean = mean(dataAfterHandling_mean)
dataAfterHandling_mean[outliersPos] <- round(mean)
estimated_prop_After_mean <- enbinom(dataAfterHandling_mean, size = 2)$parameters[2][["prob"]]
median = median(dataAfterHandling_median)
dataAfterHandling_median[outliersPos] <- round(median)
estimated_prop_After_median <- enbinom(dataAfterHandling_median, size = 2)$parameters[2][["prob"]]
mode = getmode(dataAfterHandling_mode)
dataAfterHandling_mode[outliersPos] <- round(mode)
estimated_prop_After_mode <- enbinom(dataAfterHandling_mode, size = 2)$parameters[2][["prob"]]
results = rbind(
results,
data.frame(
i,
estimated_prop_After_Q_b_F_C,
estimated_prop_After_mean,
estimated_prop_After_median,
estimated_prop_After_mode
))
}
results
}
# different sample size and contamination=10%
data_20_2_10 <- generateData(20 , .1)
data_50_2_10 <- generateData(50 , .1)
data_100_2_10 <- generateData(100 , 0.1)
data_200_2_10 <- generateData(200 , 0.1)
# different sample size and contamination=20%
data_20_2_20 <- generateData(20 , 0.2)
data_50_2_20 <- generateData(50 , 0.2)
data_100_2_20 <- generateData(100,0.2)
data_200_2_20 <- generateData(200,0.2)
# different sample size and contamination=20%
data_20_2_30 <- generateData(20 , 0.3)
data_50_2_30 <- generateData(50 , 0.3)
Results
doCalculations <- function(data , sampleSize , contamination) {
data %>% summarize(
sampleSize = sampleSize ,
contamination = contamination,
bias_prop_Q_b_F_C = bias(estimated_prop_After_Q_b_F_C , 0.2 ),
bias_prop_Mean = bias(estimated_prop_After_mean ,0.2),
bias_prop_Median = bias(estimated_prop_After_median , 0.2),
bias_prop_Mode = bias(estimated_prop_After_mode ,0.2) ,
MSE_prop_Q_b_F_C = MSE(estimated_prop_After_Q_b_F_C, 0.2),
MSE_prop_Mean = MSE(estimated_prop_After_mean, 0.2),
MSE_prop_Median = MSE(estimated_prop_After_median, 0.2),
MSE_prop_Mode = MSE(estimated_prop_After_mode, 0.2),
)
}
finalResult <- NULL
finalResult <- rbind(
finalResult ,
doCalculations(data_20_2_10 , 20,10),
doCalculations(data_50_2_10 , 50,10),
doCalculations(data_100_2_10 , 100,10),
doCalculations(data_200_2_10 , 200,10),
doCalculations(data_20_2_20 , 20,20),
doCalculations(data_50_2_20 , 50,20),
doCalculations(data_100_2_20 , 100,20),
doCalculations(data_200_2_20 , 200,20),
doCalculations(data_20_2_30 , 20,30),
doCalculations(data_50_2_30 , 50,30),
doCalculations(data_100_2_30 , 100,30),
doCalculations(data_200_2_30 , 200,30)
)
finalResult %>% select(sampleSize , contamination , bias_prop_Q_b_F_C , bias_prop_Mean , bias_prop_Median ,bias_prop_Mode)
finalResult %>% select(sampleSize , contamination , MSE_prop_Q_b_F_C , MSE_prop_Mean, MSE_prop_Median , MSE_prop_Mode)
NA
NA
#Relation Between sample size and Biased_prop for each method
finalResult %>% select( sampleSize , contamination, bias_prop_Q_b_F_C , bias_prop_Mean , bias_prop_Median ,bias_prop_Mode) %>%
gather("Method" , "Biased_prop" , bias_prop_Q_b_F_C , bias_prop_Mean , bias_prop_Median ,bias_prop_Mode ) %>%
ggplot(aes(x = (sampleSize) , y = Biased_prop)) +
geom_point( aes(colour = as.factor(contamination))) +
geom_line( aes(colour = as.factor(contamination))) +
facet_wrap(.~Method)

finalResult %>% select( sampleSize , contamination,MSE_prop_Q_b_F_C , MSE_prop_Mean, MSE_prop_Median , MSE_prop_Mode) %>%
gather("Method" , "MSE_prop" , MSE_prop_Q_b_F_C , MSE_prop_Mean, MSE_prop_Median , MSE_prop_Mode ) %>%
ggplot(aes(x = (sampleSize) , y = MSE_prop)) +
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/D230BA69-OutlierHandling_Negative Binomial Distribution/1/CD6BAB307633CDB7/cojq04yy8pzmj_t/7a1201eaacdc4086a57059cbc89a92ef.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/D230BA69-OutlierHandling_Negative Binomial Distribution/1/CD6BAB307633CDB7/cojq04yy8pzmj_t/30f20766750349038d97ca4057157fb3.snapshot', probable reason 'No such file or directory'
Error in gzfile(file, "wb") : cannot open the connection
LS0tDQp0aXRsZTogIk91dGxpZXIgSGFuZGxpbmcgTWV0aG9kcyAoTmVnYXRpdmUgQmlub21pYWwgRGlzdHJpYnV0aW9uKSINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNClJhbmRvbSB2YXJpYWJsZSBYIGlzIGRpc3RyaWJ1dGVkICRYIFxzaW0gTkIocixwKSQgd2l0aCBtZWFuICRcbXUgPVxmcmFje3J9e3B9JCBhbmQgdmFyaWFuY2UgJFxzaWdtYV4yPSBcZnJhY3tyKDEtcCl9e3BeMn0kDQoNCmlmIFggaXMgdGhlIGNvdW50IG9mIGluZGVwZW5kZW50IEJlcm5vdWxsaSB0cmlhbHMgcmVxdWlyZWQgdG8gYWNoaWV2ZSB0aGUgcnRoIHN1Y2Nlc3NmdWwgdHJpYWwgd2hlbiB0aGUgcHJvYmFiaWxpdHkgb2Ygc3VjY2VzcyBpcyBjb25zdGFudCBwLg0KIA0KVGhlIHByb2JhYmlsaXR5IG9mIFg9biB0cmlhbHMgaXMgJGYoWD1uKT0ge24tMSBcY2hvb3NlIHItMX0gcF5yICgxLXApXntuLXJ9JA0KDQoNCg0KYGBge3IgaW1wb3J0TGlicmFyeSAsIGVjaG89RkFMU0UgLCB3YXJuaW5nPUZBTFNFICwgZXJyb3I9RkFMU0V9DQpsaWJyYXJ5KHJvYnVzdCkNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KE1MbWV0cmljcykNCmxpYnJhcnkoU2ltRGVzaWduKQ0KbGlicmFyeSh0aWR5cikNCmxpYnJhcnkoRW52U3RhdHMpDQoNCmBgYA0KDQojRXN0aW1hdGlvbg0KDQppZiBYIGlzIGRlZmluZWQgYXM6ICRYID0g4oiRXm5fe2kgPSAxfSB4X2kkDQp0aGVuIFggaXMgYW4gb2JzZXJ2YXRpb24gZnJvbSBhIG5lZ2F0aXZlIGJpbm9taWFsIGRpc3RyaWJ1dGlvbiB3aXRoIHBhcmFtZXRlcnMgcHJvYj1wIGFuZCBzaXplPUssIHdoZXJlICRLID0g4oiRXm5fe2kgPSAxfSBrX2kkDQoNCg0KVGhlIG1heGltdW0gbGlrZWxpaG9vZCBhbmQgbWV0aG9kIG9mIG1vbWVudHMgZXN0aW1hdG9yIChtbGUpIG9mIHAgaXMgZ2l2ZW4gYnk6DQokJCBcaGF0e3B9X3ttbGV9ID0gXGZyYWN7S317WCArIEt9ICQkDQoNCg0KIyBHZW5lcmF0ZSBEYXRhIA0KDQpgYGB7ciBGdW5jdGlvblVzZWRUb0dlbmVyYXRlRGF0YVdpdGhfY29udGFtaW5hdGlvbiAsZWNobz1UUlVFICwgd2FybmluZz1GQUxTRX0NCg0KZ2V0bW9kZSA8LSBmdW5jdGlvbih2KSB7DQogICB1bmlxdiA8LSB1bmlxdWUodikNCiAgIHVuaXF2W3doaWNoLm1heCh0YWJ1bGF0ZShtYXRjaCh2LCB1bmlxdikpKV0NCn0NCg0KY3JlYXRlRGF0YVdpdGhDb250YW1pbmF0aW9uX05CX1AgPC0gZnVuY3Rpb24oc2FtcGxlX3NpemUgLCBjb250YW1pbmF0aW9uX3Byb3AgICl7DQoNCiAgZGF0YSA8LSBybmJpbm9tKHNhbXBsZV9zaXplICwgc2l6ZSA9IDIsIHByb2IgPSAuMikgDQogIGNvbnRhbWluYXRpb25zIDwtICAgcnBvaXMocm91bmQoKHNhbXBsZV9zaXplKmNvbnRhbWluYXRpb25fcHJvcCkpLCBsYW1iZGEgPSAzMikNCiAgDQogIGRhdGFfd2l0aF9jb250YW1pbmF0aW9uIDwtIGMoZGF0YSwgY29udGFtaW5hdGlvbnMpIA0KDQogICBsaXN0KA0KICAgICBkYXRhID0gZGF0YSwNCiAgICAgY29udGFtaW5hdGlvbnMgPSBjb250YW1pbmF0aW9ucywNCiAgICAgZGF0YV93aXRoX2NvbnRhbWluYXRpb24gPSBkYXRhX3dpdGhfY29udGFtaW5hdGlvbg0KICAgICkNCiAgIA0KfQ0KDQpgYGANCg0KDQojIyMgRGF0YSBHZW5lcmF0aW9ucyBGYWN0b3JzDQoNCjEuIHNhbXBsZSBzaXplICAoMjAsNTAsMTAwLDIwMCkgDQoyLiBEaXN0cmlidXRpb24gUGFyYW1ldGVycyAgKDIgLCAwLjIpDQozLiBjb250YW1pbmF0aW9uICgxMCUgLCAyMCUgLCAzMCUpDQoNCg0KYGBge3IgZ2VuZXJhdGVEYXRlRnVuY3Rpb24gLHdhcm5pbmc9RkFMU0V9DQoNCmdlbmVyYXRlRGF0YSA8LSBmdW5jdGlvbihzYW1wbGVTaXplICwgY29udGFtaW5hdGlvbiApew0KICANCiAgDQpyZXN1bHRzID0gTlVMTA0KI2NyZWF0ZSAxMDAwIHJhbmRvbSBzYW1wbGUgd2l0aCBjb250YW1pbmF0aW9uDQpmb3IoaSBpbiAxOjIwMDApew0KICAjZ2VuZXJhdGUgZGF0YSAgDQogIGRhdGFfd2l0aF9jb250YW1pbmF0aW9uIDwtICBjcmVhdGVEYXRhV2l0aENvbnRhbWluYXRpb25fTkJfUChzYW1wbGVTaXplLGNvbnRhbWluYXRpb24pJGRhdGFfd2l0aF9jb250YW1pbmF0aW9uDQogICANCiAgI0NvZGUgVG8gSGFuZGxpbmcgb3V0bGllciANCiAgDQoNCiAgI1F1YW50aWxlIGJhc2VkIGZsb29yaW5nIGFuZCBjYXBwaW5nDQogICNJbiB0aGlzIHRlY2huaXF1ZSwgdGhlIG91dGxpZXIgaXMgY2FwcGVkIGF0IGEgY2VydGFpbiB2YWx1ZSBhYm92ZSB0aGUgdXBwZXIgcGVyY2VudGlsZSB2YWx1ZSBvciBmbG9vcmVkICAgYXQgYSBmYWN0b3IgYmVsb3cgdGhlIGxvd2VyIHBlcmNlbnRpbGUgdmFsdWUuDQogIA0KbG93ZXIgID0gcXVhbnRpbGUoZGF0YV93aXRoX2NvbnRhbWluYXRpb24gICwgYyguMDI1KSlbWyIyLjUlIl1dDQp1cHBlciA9IHF1YW50aWxlKGRhdGFfd2l0aF9jb250YW1pbmF0aW9uICAsIGMoLjk3NSkpW1siOTcuNSUiXV0NCg0KDQpvdXRsaWVycyA8LSBib3hwbG90KGRhdGFfd2l0aF9jb250YW1pbmF0aW9uLCBwbG90PUZBTFNFKSRvdXQNCm91dGxpZXJzUG9zIDwtIHdoaWNoKGRhdGFfd2l0aF9jb250YW1pbmF0aW9uICVpbiUgb3V0bGllcnMpDQogDQogIA0KIA0KZGF0YUFmdGVySGFuZGxpbmdfUV9iX0ZfQyA8LSBkYXRhX3dpdGhfY29udGFtaW5hdGlvbg0KZGF0YUFmdGVySGFuZGxpbmdfbWVhbiA8LSBkYXRhX3dpdGhfY29udGFtaW5hdGlvbg0KZGF0YUFmdGVySGFuZGxpbmdfbWVkaWFuIDwtIGRhdGFfd2l0aF9jb250YW1pbmF0aW9uDQpkYXRhQWZ0ZXJIYW5kbGluZ19tb2RlIDwtIGRhdGFfd2l0aF9jb250YW1pbmF0aW9uDQoNCg0KZGF0YUFmdGVySGFuZGxpbmdfUV9iX0ZfQ1tkYXRhQWZ0ZXJIYW5kbGluZ19RX2JfRl9DPGxvd2VyXSA8LSByb3VuZChsb3dlcikNCmRhdGFBZnRlckhhbmRsaW5nX1FfYl9GX0NbZGF0YUFmdGVySGFuZGxpbmdfUV9iX0ZfQz51cHBlcl0gPC0gcm91bmQodXBwZXIpDQplc3RpbWF0ZWRfcHJvcF9BZnRlcl9RX2JfRl9DIDwtIGVuYmlub20oZGF0YUFmdGVySGFuZGxpbmdfUV9iX0ZfQywgc2l6ZSA9IDIpJHBhcmFtZXRlcnNbMl1bWyJwcm9iIl1dDQoNCm1lYW4gPSBtZWFuKGRhdGFBZnRlckhhbmRsaW5nX21lYW4pDQpkYXRhQWZ0ZXJIYW5kbGluZ19tZWFuW291dGxpZXJzUG9zXSA8LSByb3VuZChtZWFuKQ0KZXN0aW1hdGVkX3Byb3BfQWZ0ZXJfbWVhbiA8LSBlbmJpbm9tKGRhdGFBZnRlckhhbmRsaW5nX21lYW4sIHNpemUgPSAyKSRwYXJhbWV0ZXJzWzJdW1sicHJvYiJdXQ0KDQogDQptZWRpYW4gPSBtZWRpYW4oZGF0YUFmdGVySGFuZGxpbmdfbWVkaWFuKQ0KZGF0YUFmdGVySGFuZGxpbmdfbWVkaWFuW291dGxpZXJzUG9zXSA8LSByb3VuZChtZWRpYW4pDQplc3RpbWF0ZWRfcHJvcF9BZnRlcl9tZWRpYW4gPC0gZW5iaW5vbShkYXRhQWZ0ZXJIYW5kbGluZ19tZWRpYW4sIHNpemUgPSAyKSRwYXJhbWV0ZXJzWzJdW1sicHJvYiJdXQ0KIA0KDQptb2RlID0gZ2V0bW9kZShkYXRhQWZ0ZXJIYW5kbGluZ19tb2RlKQ0KZGF0YUFmdGVySGFuZGxpbmdfbW9kZVtvdXRsaWVyc1Bvc10gPC0gcm91bmQobW9kZSkgDQplc3RpbWF0ZWRfcHJvcF9BZnRlcl9tb2RlIDwtIGVuYmlub20oZGF0YUFmdGVySGFuZGxpbmdfbW9kZSwgc2l6ZSA9IDIpJHBhcmFtZXRlcnNbMl1bWyJwcm9iIl1dDQogDQoNCiByZXN1bHRzID0gcmJpbmQoDQogICByZXN1bHRzLA0KICAgZGF0YS5mcmFtZSgNCiAgICAgaSwNCiAgICAgZXN0aW1hdGVkX3Byb3BfQWZ0ZXJfUV9iX0ZfQywNCiAgICAgZXN0aW1hdGVkX3Byb3BfQWZ0ZXJfbWVhbiwNCiAgICAgZXN0aW1hdGVkX3Byb3BfQWZ0ZXJfbWVkaWFuLA0KICAgICBlc3RpbWF0ZWRfcHJvcF9BZnRlcl9tb2RlDQogICAgICkpDQp9DQoNCnJlc3VsdHMNCn0NCmBgYA0KDQoNCg0KDQpgYGB7cn0NCg0KIyBkaWZmZXJlbnQgc2FtcGxlIHNpemUgICBhbmQgY29udGFtaW5hdGlvbj0xMCUNCmRhdGFfMjBfMl8xMCA8LSBnZW5lcmF0ZURhdGEoMjAgLCAgLjEpDQpkYXRhXzUwXzJfMTAgPC0gZ2VuZXJhdGVEYXRhKDUwICwgIC4xKQ0KZGF0YV8xMDBfMl8xMCA8LSBnZW5lcmF0ZURhdGEoMTAwICwgIDAuMSkNCmRhdGFfMjAwXzJfMTAgPC0gZ2VuZXJhdGVEYXRhKDIwMCAsICAwLjEpDQoNCiMgZGlmZmVyZW50IHNhbXBsZSBzaXplICAgYW5kIGNvbnRhbWluYXRpb249MjAlDQpkYXRhXzIwXzJfMjAgPC0gZ2VuZXJhdGVEYXRhKDIwICwgMC4yKQ0KZGF0YV81MF8yXzIwIDwtIGdlbmVyYXRlRGF0YSg1MCAsIDAuMikNCmRhdGFfMTAwXzJfMjAgPC0gZ2VuZXJhdGVEYXRhKDEwMCwwLjIpDQpkYXRhXzIwMF8yXzIwIDwtIGdlbmVyYXRlRGF0YSgyMDAsMC4yKQ0KDQoNCg0KIyBkaWZmZXJlbnQgc2FtcGxlIHNpemUgYW5kIGNvbnRhbWluYXRpb249MjAlDQpkYXRhXzIwXzJfMzAgPC0gZ2VuZXJhdGVEYXRhKDIwICwgMC4zKQ0KZGF0YV81MF8yXzMwIDwtIGdlbmVyYXRlRGF0YSg1MCAsIDAuMykNCmRhdGFfMTAwXzJfMzAgPC0gZ2VuZXJhdGVEYXRhKDEwMCwwLjMpDQpkYXRhXzIwMF8yXzMwIDwtIGdlbmVyYXRlRGF0YSgyMDAsMC4zKQ0KDQoNCmBgYA0KDQojIFJlc3VsdHMgDQoNCmBgYHtyfQ0KDQpkb0NhbGN1bGF0aW9ucyA8LSBmdW5jdGlvbihkYXRhICwgc2FtcGxlU2l6ZSAsIGNvbnRhbWluYXRpb24pIHsNCiAgDQogICBkYXRhICU+JSBzdW1tYXJpemUoDQogIHNhbXBsZVNpemUgPSBzYW1wbGVTaXplICwNCiAgY29udGFtaW5hdGlvbiA9IGNvbnRhbWluYXRpb24sDQogDQogIGJpYXNfcHJvcF9RX2JfRl9DID0gYmlhcyhlc3RpbWF0ZWRfcHJvcF9BZnRlcl9RX2JfRl9DICwgIDAuMiApLA0KICBiaWFzX3Byb3BfTWVhbiA9IGJpYXMoZXN0aW1hdGVkX3Byb3BfQWZ0ZXJfbWVhbiAsMC4yKSwNCiAgYmlhc19wcm9wX01lZGlhbiA9IGJpYXMoZXN0aW1hdGVkX3Byb3BfQWZ0ZXJfbWVkaWFuICwgMC4yKSwNCiAgYmlhc19wcm9wX01vZGUgPSBiaWFzKGVzdGltYXRlZF9wcm9wX0FmdGVyX21vZGUgLDAuMikgLA0KICANCiAgDQogIE1TRV9wcm9wX1FfYl9GX0MgID0gTVNFKGVzdGltYXRlZF9wcm9wX0FmdGVyX1FfYl9GX0MsIDAuMiksDQogIE1TRV9wcm9wX01lYW4gID0gTVNFKGVzdGltYXRlZF9wcm9wX0FmdGVyX21lYW4sIDAuMiksDQogIE1TRV9wcm9wX01lZGlhbiAgID0gTVNFKGVzdGltYXRlZF9wcm9wX0FmdGVyX21lZGlhbiwgMC4yKSwNCiAgTVNFX3Byb3BfTW9kZSAgPSBNU0UoZXN0aW1hdGVkX3Byb3BfQWZ0ZXJfbW9kZSwgMC4yKSwNCikgDQp9DQoNCg0KDQpgYGANCg0KYGBge3IgY2FsbF9DYWxjdWxhdGlvbnNGdW5jdGlvbiAgLHdhcm5pbmc9RkFMU0UgfQ0KDQpmaW5hbFJlc3VsdCA8LSBOVUxMIA0KDQpmaW5hbFJlc3VsdCA8LSByYmluZCgNCiAgZmluYWxSZXN1bHQgLA0KICAgICAgICAgICAgICAgIGRvQ2FsY3VsYXRpb25zKGRhdGFfMjBfMl8xMCAsIDIwLDEwKSwNCiAgICAgICAgICAgICAgICBkb0NhbGN1bGF0aW9ucyhkYXRhXzUwXzJfMTAgLCA1MCwxMCksDQogICAgICAgICAgICAgICAgZG9DYWxjdWxhdGlvbnMoZGF0YV8xMDBfMl8xMCAsIDEwMCwxMCksDQogICAgICAgICAgICAgICAgZG9DYWxjdWxhdGlvbnMoZGF0YV8yMDBfMl8xMCAsIDIwMCwxMCksDQogIA0KICAgICAgICAgICAgICAgIGRvQ2FsY3VsYXRpb25zKGRhdGFfMjBfMl8yMCAsIDIwLDIwKSwNCiAgICAgICAgICAgICAgICBkb0NhbGN1bGF0aW9ucyhkYXRhXzUwXzJfMjAgLCA1MCwyMCksDQogICAgICAgICAgICAgICAgZG9DYWxjdWxhdGlvbnMoZGF0YV8xMDBfMl8yMCAsIDEwMCwyMCksDQogICAgICAgICAgICAgICAgZG9DYWxjdWxhdGlvbnMoZGF0YV8yMDBfMl8yMCAsIDIwMCwyMCksDQogICAgIA0KICAgICAgICAgICAgICAgIGRvQ2FsY3VsYXRpb25zKGRhdGFfMjBfMl8zMCAsIDIwLDMwKSwNCiAgICAgICAgICAgICAgICBkb0NhbGN1bGF0aW9ucyhkYXRhXzUwXzJfMzAgLCA1MCwzMCksDQogICAgICAgICAgICAgICAgZG9DYWxjdWxhdGlvbnMoZGF0YV8xMDBfMl8zMCAsIDEwMCwzMCksDQogICAgICAgICAgICAgICAgZG9DYWxjdWxhdGlvbnMoZGF0YV8yMDBfMl8zMCAsIDIwMCwzMCkNCiAgICAgICAgICAgICAgICAgICAgICkNCg0KDQoNCg0KDQpgYGANCiANCg0KYGBge3IgIHdhcm5pbmc9RkFMU0V9DQoNCmZpbmFsUmVzdWx0ICU+JSBzZWxlY3Qoc2FtcGxlU2l6ZSAsIGNvbnRhbWluYXRpb24gLCBiaWFzX3Byb3BfUV9iX0ZfQyAsIGJpYXNfcHJvcF9NZWFuICwgYmlhc19wcm9wX01lZGlhbiAsYmlhc19wcm9wX01vZGUpDQoNCg0KDQpmaW5hbFJlc3VsdCAlPiUgc2VsZWN0KHNhbXBsZVNpemUgLCBjb250YW1pbmF0aW9uICwgTVNFX3Byb3BfUV9iX0ZfQyAgLCBNU0VfcHJvcF9NZWFuLCBNU0VfcHJvcF9NZWRpYW4gLCBNU0VfcHJvcF9Nb2RlKQ0KIA0KDQpgYGANCiANCg0KDQpgYGB7ciBSZXN1bHRWaXN1YWxpemF0aW9ufQ0KDQojUmVsYXRpb24gQmV0d2VlbiBzYW1wbGUgc2l6ZSBhbmQgQmlhc2VkX3Byb3AgZm9yIGVhY2ggbWV0aG9kDQoNCmZpbmFsUmVzdWx0ICU+JSBzZWxlY3QoIHNhbXBsZVNpemUgLCBjb250YW1pbmF0aW9uLCBiaWFzX3Byb3BfUV9iX0ZfQyAsIGJpYXNfcHJvcF9NZWFuICwgYmlhc19wcm9wX01lZGlhbiAsYmlhc19wcm9wX01vZGUpICU+JSANCiAgZ2F0aGVyKCJNZXRob2QiICwgIkJpYXNlZF9wcm9wIiAsIGJpYXNfcHJvcF9RX2JfRl9DICwgYmlhc19wcm9wX01lYW4gLCBiaWFzX3Byb3BfTWVkaWFuICxiaWFzX3Byb3BfTW9kZSApICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gKHNhbXBsZVNpemUpICwgeSA9IEJpYXNlZF9wcm9wKSkgKyANCiAgZ2VvbV9wb2ludCggYWVzKGNvbG91ciA9IGFzLmZhY3Rvcihjb250YW1pbmF0aW9uKSkpICsgDQogICAgZ2VvbV9saW5lKCBhZXMoY29sb3VyID0gYXMuZmFjdG9yKGNvbnRhbWluYXRpb24pKSkgKyANCg0KICBmYWNldF93cmFwKC5+TWV0aG9kKQ0KDQoNCg0KZmluYWxSZXN1bHQgJT4lIHNlbGVjdCggc2FtcGxlU2l6ZSAsIGNvbnRhbWluYXRpb24sTVNFX3Byb3BfUV9iX0ZfQyAgLCBNU0VfcHJvcF9NZWFuLCBNU0VfcHJvcF9NZWRpYW4gLCBNU0VfcHJvcF9Nb2RlKSAlPiUgDQogIGdhdGhlcigiTWV0aG9kIiAsICJNU0VfcHJvcCIgLCAgTVNFX3Byb3BfUV9iX0ZfQyAgLCBNU0VfcHJvcF9NZWFuLCBNU0VfcHJvcF9NZWRpYW4gLCBNU0VfcHJvcF9Nb2RlICkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSAoc2FtcGxlU2l6ZSkgLCB5ID0gTVNFX3Byb3ApKSArIA0KICBnZW9tX3BvaW50KCBhZXMoY29sb3VyID0gYXMuZmFjdG9yKGNvbnRhbWluYXRpb24pKSkgKyANCiAgZ2VvbV9saW5lKCBhZXMoY29sb3VyID0gYXMuZmFjdG9yKGNvbnRhbWluYXRpb24pKSkgKyANCiAgZmFjZXRfd3JhcCgufk1ldGhvZCkNCg0KIA0KDQoNCg0KDQpgYGANCg0KDQoNCg0KIyBSZWZlcmVuY2VzDQoNCjEuIGh0dHBzOi8vc2VhcmNoLnItcHJvamVjdC5vcmcvQ1JBTi9yZWZtYW5zL0VudlN0YXRzL2h0bWwvZW5iaW5vbS5odG1sDQoNCjIuIGh0dHBzOi8vc2VhcmNoLnItcHJvamVjdC5vcmcvQ1JBTi9yZWZtYW5zL0VudlN0YXRzL2h0bWwvMDBJbmRleC5odG1sDQoNCjMuIA0KDQo=