Adjusting \(p\)-values
Example R code is provided below.
base_p_values <- c(0.0003, 0.0085, 0.001, 0.0001, 0.045, 0.62, 0.009, 0.18, 0.92, 0.02)
There are 7 \(p\)-values below 0.05, so we would find 7 genes to be significantly differentially expressed.
p.adjust(base_p_values, method = "bonferroni")
## [1] 0.003 0.085 0.010 0.001 0.450 1.000 0.090 1.000 1.000 0.200
Using the Bonferroni correction, we find that only 3 of the \(p\)-values are now below 0.05.
Example R code is provided below.
# Check all p-values
p.adjust(base_p_values, method = "holm")
## [1] 0.0027 0.0595 0.0080 0.0010 0.1800 1.0000 0.0595 0.5400 1.0000 0.1000
p.adjust(base_p_values, method = "hochberg")
## [1] 0.0027 0.0540 0.0080 0.0010 0.1800 0.9200 0.0540 0.5400 0.9200 0.1000
p.adjust(base_p_values, method = "hommel")
## [1] 0.0027 0.0510 0.0080 0.0010 0.1800 0.9200 0.0540 0.5400 0.9200 0.1000
# Compute number of significant p-values
c(sum(p.adjust(base_p_values, method = "holm") < .05),
sum(p.adjust(base_p_values, method = "hochberg") < .05),
sum(p.adjust(base_p_values, method = "hommel") < .05)
)
## [1] 3 3 3
All three methods result in 3 \(p\)-values below 0.05.
The Hochberg and Hommel methods produce near-identical results.
Example R code is provided below.
# Compute number of significant p-values
c(sum(p.adjust(base_p_values, method = "holm") < .01),
sum(p.adjust(base_p_values, method = "hochberg") < .01),
sum(p.adjust(base_p_values, method = "hommel") < .01)
)
## [1] 3 3 3
All three methods result in 3 \(p\)-values below 0.01. Note that the \(p\)-values themselves have not changed from 2.6, we are simply using a different threshold (level of significance) for determining if results are statistically significant or not.
SARS-CoV-2 Study \(p\)-values
For this question, you must have downloaded the SARS_data_subset.csv
file from LMS, and either:
- stored it in your working directory (RStudio users) or
- loaded it into jamovi (jamovi users)
Example R code for the subsequent step is provided below.
# For RStudio, you would have run this code:
sars_data <- read.csv(file = "SARS_data_subset.csv", header = T)
# For jamovi, you would have run this code:
sars_data <- data
# Store base p-values
covid_base_p_values <- sars_data$pvalue.Alpha_8h_vs_VIC_8h
# Number of significant p-values
sum(covid_base_p_values < .05)
## [1] 703
So based on the initial \(p\)-values, there are 703 differentially expressed genes at the 8 hour post-infection time point, between the two strains.
Example R code is provided below.
covid_bonferroni_p_values <- p.adjust(covid_base_p_values, method = "bonferroni")
Example R code is provided below.
covid_fdr_p_values <- p.adjust(covid_base_p_values, method = "fdr")
sum(covid_bonferroni_p_values < 0.05)
## [1] 19
sum(covid_fdr_p_values < 0.05)
## [1] 48
Initially, we had 703 statistically significantly differentially expressed genes at the 8 hour post-infection time point, between the two strains.
We can see that following Bonferroni correction we have 19 statistically significantly differentially expressed genes, a reduction of
684 genes.
If we instead use FDR correction, we obtain 48 statistically significantly differentially expressed genes. This is a reduction of 655 genes compared to the initial un-adjusted \(p\)-values. FDR correction is more lenient than the Bonferroni correction approach, with 29 more genes considered statistically significantly differentially expressed.
Volcano Plots
No answer required.
The two volcano plots are shown below.
Note that the y-axis shows the negative of the log of the \(p\)-values, meaning that small \(p\)-values appear high on the y-axis, while large \(p\)-values are close to 0 on the y-axis.
Recall also that on the x-axis, a log-fold change of 0 signifies that a gene’s expression status has not changed between the two groups (here Alpha
and VIC
), while a gene with a log-fold change which is large in magnitude is likely to be biologically significant.
plot(sars_data$log2FoldChange.Alpha_8h_vs_VIC_8h,
-log10(covid_base_p_values),
main = "Volcano Plot for SARS-CoV-2
VIC and Alpha strains
8h post-infection, using initial p-values",
xlab = "log FC", ylab = "-log10(pval)",
cex = 0.5, col = as.numeric(covid_base_p_values <= 0.05) + 1)

plot(sars_data$log2FoldChange.Alpha_8h_vs_VIC_8h,
-log10(covid_fdr_p_values),
main = "Volcano Plot for SARS-CoV-2
VIC and Alpha strains
8h post-infection, using FDR-corrected p-values",
xlab = "log FC", ylab = "-log10(pval)",
cex = 0.5, col = as.numeric(covid_fdr_p_values <= 0.05) + 1)

Note here how many of the FDR-corrected \(p\)-values are no longer considered statistically significant. However, the genes with low FDR-corrected \(p\)-values (and thus high y-axis scores in the volcano plot) appear to have log-fold changes in gene expression which are non-zero and relatively large in magnitude. This suggests that the genes coloured red in the second volcano plot are both biologically and statistically significant - so the FDR-correction has been beneficial, and has helped filter out some genes which, while having low initial \(p\)-values, were not biologically significant in this context.
For this example, it is worth considering why it might be important to compare gene expression differences between the two coronavirus strains. For example, identifying genes which are statistically significantly differentially expressed between the two strains could help researchers develop treatments which were personalised to the different strains. Such treatments could be more effective than using a generic treatment which may have varying levels of efficacy for different strains. Can you think of any other reasons?
That’s everything covered, well done.
LS0tDQp0aXRsZTogIlNUTTEwMDE6IENvbXB1dGVyIExhYiA4QiBTb2x1dGlvbnMiDQpvdXRwdXQ6DQogIGJvb2tkb3duOjpodG1sX2RvY3VtZW50MjogDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIHRoZW1lOiByZWFkYWJsZQ0KICAgIGNvZGVfZm9sZGluZzogc2hvdw0KYmlibGlvZ3JhcGh5OiBTVE0xMDAxX0RTX0NMX3JlZmVyZW5jZXMuYmliIA0KbGluay1jaXRhdGlvbnM6IHllcw0KLS0tDQoNCjxzdHlsZT4NCiNUT0Mgew0KICBiYWNrZ3JvdW5kOiB1cmwoImh0dHBzOi8vd3d3LmxhdHJvYmUuZWR1LmF1L19tZWRpYS9sYS10cm9iZS1hcGkvdjUvaW1nL2xvZ28uc3ZnIik7DQogIGJhY2tncm91bmQtc2l6ZTogY29udGFpbjsNCiAgcGFkZGluZy10b3A6IDgwcHggIWltcG9ydGFudDsNCiAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDsNCn0NCjwvc3R5bGU+DQoNCiMjIyBTY2llbmNlL0hlYWx0aC9EYXRhIFNjaWVuY2UgU3RyZWFtcyB7LX0NCg0KIyMjIFRvcGljIDhCOiBCaWcgRGF0YSBJSSAoJHAkLXZhbHVlIGFkanVzdG1lbnRzKSB7LX0NCg0KPGJyPg0KDQpFeGFtcGxlIFIgY29kZSBzb2x1dGlvbnMgZm9yIHRoZSBbU2NpZW5jZS9IZWFsdGgvRGF0YSBTY2llbmNlIENvbXB1dGVyIExhYiA4XShodHRwczovL3JwdWJzLmNvbS9MVFVfU1RNMTAwMS9TTURTTUNMOCksIHdoaWNoIHVzZXMgZGF0YSBmcm9tIFtTZXJpZXMgR1NFMTg0OTMyIG9uIHRoZSBOQ0JJIEdlbmUgRXhwcmVzc2lvbiBPbW5pYnVzIHdlYnNpdGVdKGh0dHBzOi8vd3d3Lm5jYmkubmxtLm5paC5nb3YvZ2VvL3F1ZXJ5L2FjYy5jZ2k/YWNjPUdTRTE4NDkzMikgYXJlIHByZXNlbnRlZCBiZWxvdy4NCg0KVGhpcyBjb21wdXRlciBsYWIgaXMgZGVzaWduZWQgdG8gcnVuIGFsb25nc2lkZSB0aGUgY29udGVudCBpbiB0aGUgW0ZvdW5kYXRpb25hbCBCaW9sb2d5IGZvciBBbmFseXNlcyBvZiBCaW9sb2dpY2FsIERhdGEgc3VwcGxlbWVudF0oaHR0cHM6Ly9ib29rZG93bi5vcmcvcmVoay9zdG0xMDAxX2ZvdW5kYXRpb25hbF9iaW9sb2d5X2Zvcl9hbmFseXNlc19vZl9iaW9sb2dpY2FsX2RhdGEvKS4gSXQgbWlnaHQgYmUgaGVscGZ1bCB0byBoYXZlIHRoaXMgbWF0ZXJpYWwgb3BlbiBhcyB5b3UgbG9vayB0aHJvdWdoIHRoZXNlIHNvbHV0aW9ucy4NCg0KIyBJbnRyb2R1Y3Rpb24NCiANCiMjIFR5cGUgSSBlcnJvciBwcm9iYWJpbGl0eSBleGFtcGxlDQoNCk5vIGFuc3dlciByZXF1aXJlZC4NCg0KIyBBZGp1c3RpbmcgJHAkLXZhbHVlcw0KDQojIw0KDQpObyBhbnN3ZXIgcmVxdWlyZWQuDQoNCiMjIA0KDQpFeGFtcGxlIFIgY29kZSBpcyBwcm92aWRlZCBiZWxvdy4NCg0KYGBgIHtyLCBldmFsID0gVCwgaW5jbHVkZSA9IFR9DQpiYXNlX3BfdmFsdWVzIDwtIGMoMC4wMDAzLCAwLjAwODUsIDAuMDAxLCAwLjAwMDEsIDAuMDQ1LCAwLjYyLCAwLjAwOSwgMC4xOCwgMC45MiwgMC4wMikNCmBgYA0KDQojIw0KDQpUaGVyZSBhcmUgYHIgc3VtKGJhc2VfcF92YWx1ZXMgPDAuMDUpYCAkcCQtdmFsdWVzIGJlbG93IDAuMDUsIHNvIHdlIHdvdWxkIGZpbmQgYHIgc3VtKGJhc2VfcF92YWx1ZXMgPDAuMDUpYCBnZW5lcyB0byBiZSBzaWduaWZpY2FudGx5IGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZC4NCg0KDQojIyANCg0KYGBgIHtyLCBldmFsID0gVCwgaW5jbHVkZSA9IFQsIG1lc3NhZ2UgPSBGLCB3YXJuaW5nID0gRn0NCnAuYWRqdXN0KGJhc2VfcF92YWx1ZXMsIG1ldGhvZCA9ICJib25mZXJyb25pIikNCmBgYA0KDQojIw0KDQpVc2luZyB0aGUgQm9uZmVycm9uaSBjb3JyZWN0aW9uLCB3ZSBmaW5kIHRoYXQgb25seSBgciBzdW0ocC5hZGp1c3QoYmFzZV9wX3ZhbHVlcywgbWV0aG9kID0gImJvbmZlcnJvbmkiKSA8MC4wNSlgIG9mIHRoZSAkcCQtdmFsdWVzIGFyZSBub3cgYmVsb3cgMC4wNS4NCg0KIyMgeyNob2xtfQ0KDQpFeGFtcGxlIFIgY29kZSBpcyBwcm92aWRlZCBiZWxvdy4NCg0KYGBgIHtyLCBldmFsID0gVCwgaW5jbHVkZSA9IFR9DQojIENoZWNrIGFsbCBwLXZhbHVlcw0KcC5hZGp1c3QoYmFzZV9wX3ZhbHVlcywgbWV0aG9kID0gImhvbG0iKQ0KcC5hZGp1c3QoYmFzZV9wX3ZhbHVlcywgbWV0aG9kID0gImhvY2hiZXJnIikNCnAuYWRqdXN0KGJhc2VfcF92YWx1ZXMsIG1ldGhvZCA9ICJob21tZWwiKQ0KDQojIENvbXB1dGUgbnVtYmVyIG9mIHNpZ25pZmljYW50IHAtdmFsdWVzDQpjKHN1bShwLmFkanVzdChiYXNlX3BfdmFsdWVzLCBtZXRob2QgPSAiaG9sbSIpIDwgLjA1KSwgDQogIHN1bShwLmFkanVzdChiYXNlX3BfdmFsdWVzLCBtZXRob2QgPSAiaG9jaGJlcmciKSA8IC4wNSksDQogIHN1bShwLmFkanVzdChiYXNlX3BfdmFsdWVzLCBtZXRob2QgPSAiaG9tbWVsIikgPCAuMDUpDQopDQpgYGANCg0KQWxsIHRocmVlIG1ldGhvZHMgcmVzdWx0IGluIDMgJHAkLXZhbHVlcyBiZWxvdyAwLjA1Lg0KVGhlIEhvY2hiZXJnIGFuZCBIb21tZWwgbWV0aG9kcyBwcm9kdWNlIG5lYXItaWRlbnRpY2FsIHJlc3VsdHMuDQoNCiMjDQoNCkV4YW1wbGUgUiBjb2RlIGlzIHByb3ZpZGVkIGJlbG93Lg0KDQpgYGAge3IsIGV2YWwgPSBULCBpbmNsdWRlID0gVH0NCiMgQ29tcHV0ZSBudW1iZXIgb2Ygc2lnbmlmaWNhbnQgcC12YWx1ZXMNCmMoc3VtKHAuYWRqdXN0KGJhc2VfcF92YWx1ZXMsIG1ldGhvZCA9ICJob2xtIikgPCAuMDEpLCANCiAgc3VtKHAuYWRqdXN0KGJhc2VfcF92YWx1ZXMsIG1ldGhvZCA9ICJob2NoYmVyZyIpIDwgLjAxKSwNCiAgc3VtKHAuYWRqdXN0KGJhc2VfcF92YWx1ZXMsIG1ldGhvZCA9ICJob21tZWwiKSA8IC4wMSkNCikNCmBgYA0KDQpBbGwgdGhyZWUgbWV0aG9kcyByZXN1bHQgaW4gMyAkcCQtdmFsdWVzIGJlbG93IDAuMDEuIE5vdGUgdGhhdCB0aGUgJHAkLXZhbHVlcyB0aGVtc2VsdmVzIGhhdmUgbm90IGNoYW5nZWQgZnJvbSBcQHJlZihob2xtKSwgd2UgYXJlIHNpbXBseSB1c2luZyBhIGRpZmZlcmVudCB0aHJlc2hvbGQgKGxldmVsIG9mIHNpZ25pZmljYW5jZSkgZm9yIGRldGVybWluaW5nIGlmIHJlc3VsdHMgYXJlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgb3Igbm90Lg0KDQoNCiMgRmFsc2UgRGlzY292ZXJ5IFJhdGUNCg0KIyMNCg0KRXhhbXBsZSBSIGNvZGUgaXMgcHJvdmlkZWQgYmVsb3cuDQoNCmBgYCB7ciwgZXZhbCA9IFQsIGluY2x1ZGUgPSBUfQ0KcC5hZGp1c3QoYmFzZV9wX3ZhbHVlcywgbWV0aG9kID0gImZkciIpDQpgYGANCg0KIyMNCg0KV2Ugc2VlIHRoYXQgdGhlcmUgYXJlIGByIHN1bShwLmFkanVzdChiYXNlX3BfdmFsdWVzLCBtZXRob2QgPSAiZmRyIikgPCAwLjA1KWAgJHAkLXZhbHVlcyBiZWxvdyAwLjA1LiBUaGUgRkRSIG1ldGhvZCBoYXMgYmVlbiBsZXNzIHN0cmluZ2VudCB0aGFuIHRoZSBGV0VSIG1ldGhvZHMsIGJ1dCBoYXMgc3RpbGwgcmVkdWNlZCB0aGUgbnVtYmVyIG9mIGdlbmVzIGNvbnNpZGVyZWQgdG8gYmUgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4NCg0KIyBTQVJTLUNvVi0yIFN0dWR5ICRwJC12YWx1ZXMNCg0KIyMNCg0KTm8gYW5zd2VyIHJlcXVpcmVkDQoNCiMjDQoNCkZvciB0aGlzIHF1ZXN0aW9uLCB5b3UgbXVzdCBoYXZlIGRvd25sb2FkZWQgdGhlIGBTQVJTX2RhdGFfc3Vic2V0LmNzdmAgZmlsZSBmcm9tIExNUywgYW5kIGVpdGhlcjoNCg0KKiBzdG9yZWQgaXQgaW4geW91ciB3b3JraW5nIGRpcmVjdG9yeSAoUlN0dWRpbyB1c2Vycykgb3IgDQoqIGxvYWRlZCBpdCBpbnRvIGphbW92aSAoamFtb3ZpIHVzZXJzKQ0KDQpFeGFtcGxlIFIgY29kZSBmb3IgdGhlIHN1YnNlcXVlbnQgc3RlcCBpcyBwcm92aWRlZCBiZWxvdy4NCg0KYGBgIHtyLCBldmFsID0gRiwgaW5jbHVkZSA9IFR9DQojIEZvciBSU3R1ZGlvLCB5b3Ugd291bGQgaGF2ZSBydW4gdGhpcyBjb2RlOg0Kc2Fyc19kYXRhIDwtIHJlYWQuY3N2KGZpbGUgPSAiU0FSU19kYXRhX3N1YnNldC5jc3YiLCBoZWFkZXIgPSBUKQ0KDQojIEZvciBqYW1vdmksIHlvdSB3b3VsZCBoYXZlIHJ1biB0aGlzIGNvZGU6DQpzYXJzX2RhdGEgPC0gZGF0YQ0KYGBgDQoNCmBgYCB7ciwgZXZhbCA9IFQsIGluY2x1ZGUgPSBGfQ0Kc2Fyc19kYXRhIDwtIHJlYWQuY3N2KGZpbGUgPSAiU0FSU19kYXRhX3N1YnNldC5jc3YiLCBoZWFkZXIgPSBUKQ0KYGBgDQoNCiMjDQoNCg0KYGBgIHtyLCBldmFsID0gVCwgaW5jbHVkZSA9IFR9DQojIFN0b3JlIGJhc2UgcC12YWx1ZXMNCmNvdmlkX2Jhc2VfcF92YWx1ZXMgPC0gc2Fyc19kYXRhJHB2YWx1ZS5BbHBoYV84aF92c19WSUNfOGgNCmBgYA0KDQojIw0KDQpgYGAge3IsIGV2YWwgPSBULCBpbmNsdWRlID0gVH0NCiMgTnVtYmVyIG9mIHNpZ25pZmljYW50IHAtdmFsdWVzDQpzdW0oY292aWRfYmFzZV9wX3ZhbHVlcyA8IC4wNSkNCmBgYA0KDQpTbyBiYXNlZCBvbiB0aGUgaW5pdGlhbCAkcCQtdmFsdWVzLCB0aGVyZSBhcmUgYHIgc3VtKGNvdmlkX2Jhc2VfcF92YWx1ZXMgPCAuMDUpYCBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMgYXQgdGhlIDggaG91ciBwb3N0LWluZmVjdGlvbiB0aW1lIHBvaW50LCBiZXR3ZWVuIHRoZSB0d28gc3RyYWlucy4NCg0KIyMNCg0KRXhhbXBsZSBSIGNvZGUgaXMgcHJvdmlkZWQgYmVsb3cuDQoNCmBgYCB7ciwgZXZhbCA9IFQsIGluY2x1ZGUgPSBUfQ0KY292aWRfYm9uZmVycm9uaV9wX3ZhbHVlcyA8LSBwLmFkanVzdChjb3ZpZF9iYXNlX3BfdmFsdWVzLCBtZXRob2QgPSAiYm9uZmVycm9uaSIpDQpgYGANCg0KIyMNCg0KRXhhbXBsZSBSIGNvZGUgaXMgcHJvdmlkZWQgYmVsb3cuDQoNCmBgYCB7ciwgZXZhbCA9IFQsIGluY2x1ZGUgPSBUfQ0KY292aWRfZmRyX3BfdmFsdWVzIDwtIHAuYWRqdXN0KGNvdmlkX2Jhc2VfcF92YWx1ZXMsIG1ldGhvZCA9ICJmZHIiKQ0KYGBgDQoNCiMjDQoNCmBgYCB7ciwgZXZhbCA9IFQsIGluY2x1ZGUgPSBUfQ0Kc3VtKGNvdmlkX2JvbmZlcnJvbmlfcF92YWx1ZXMgPCAwLjA1KQ0Kc3VtKGNvdmlkX2Zkcl9wX3ZhbHVlcyA8IDAuMDUpDQpgYGANCg0KSW5pdGlhbGx5LCB3ZSBoYWQgYHIgc3VtKGNvdmlkX2Jhc2VfcF92YWx1ZXMgPCAuMDUpYCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50bHkgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIGdlbmVzIGF0IHRoZSA4IGhvdXIgcG9zdC1pbmZlY3Rpb24gdGltZSBwb2ludCwgYmV0d2VlbiB0aGUgdHdvIHN0cmFpbnMuDQoNCldlIGNhbiBzZWUgdGhhdCBmb2xsb3dpbmcgQm9uZmVycm9uaSBjb3JyZWN0aW9uIHdlIGhhdmUgYHIgc3VtKGNvdmlkX2JvbmZlcnJvbmlfcF92YWx1ZXMgPCAwLjA1KWAgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudGx5IGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBnZW5lcywgYSByZWR1Y3Rpb24gb2YgDQpgciBzdW0oY292aWRfYmFzZV9wX3ZhbHVlcyA8IC4wNSkgLSBzdW0oY292aWRfYm9uZmVycm9uaV9wX3ZhbHVlcyA8IDAuMDUpYCBnZW5lcy4NCg0KSWYgd2UgaW5zdGVhZCB1c2UgRkRSIGNvcnJlY3Rpb24sIHdlIG9idGFpbiBgciBzdW0oY292aWRfZmRyX3BfdmFsdWVzIDwgMC4wNSlgIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMuIFRoaXMgaXMgYSByZWR1Y3Rpb24gb2YgYHIgc3VtKGNvdmlkX2Jhc2VfcF92YWx1ZXMgPCAuMDUpIC0gc3VtKGNvdmlkX2Zkcl9wX3ZhbHVlcyA8IDAuMDUpYCBnZW5lcyBjb21wYXJlZCB0byB0aGUgaW5pdGlhbCB1bi1hZGp1c3RlZCAkcCQtdmFsdWVzLiBGRFIgY29ycmVjdGlvbiBpcyBtb3JlIGxlbmllbnQgdGhhbiB0aGUgQm9uZmVycm9uaSBjb3JyZWN0aW9uIGFwcHJvYWNoLCB3aXRoIGByIHN1bShjb3ZpZF9mZHJfcF92YWx1ZXMgPCAuMDUpIC0gc3VtKGNvdmlkX2JvbmZlcnJvbmlfcF92YWx1ZXMgPCAwLjA1KWAgbW9yZSBnZW5lcyBjb25zaWRlcmVkIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQuDQoNCiMjIFZvbGNhbm8gUGxvdHMNCg0KTm8gYW5zd2VyIHJlcXVpcmVkLg0KDQojIw0KDQpUaGUgdHdvIHZvbGNhbm8gcGxvdHMgYXJlIHNob3duIGJlbG93LiANCg0KTm90ZSB0aGF0IHRoZSB5LWF4aXMgc2hvd3MgdGhlIG5lZ2F0aXZlIG9mIHRoZSBsb2cgb2YgdGhlICRwJC12YWx1ZXMsIG1lYW5pbmcgdGhhdCBzbWFsbCAkcCQtdmFsdWVzIGFwcGVhciBoaWdoIG9uIHRoZSB5LWF4aXMsIHdoaWxlIGxhcmdlICRwJC12YWx1ZXMgYXJlIGNsb3NlIHRvIDAgb24gdGhlIHktYXhpcy4NCg0KUmVjYWxsIGFsc28gdGhhdCBvbiB0aGUgeC1heGlzLCBhIGxvZy1mb2xkIGNoYW5nZSBvZiAwIHNpZ25pZmllcyB0aGF0IGEgZ2VuZSdzIGV4cHJlc3Npb24gc3RhdHVzIGhhcyBub3QgY2hhbmdlZCBiZXR3ZWVuIHRoZSB0d28gZ3JvdXBzIChoZXJlIGBBbHBoYWAgYW5kIGBWSUNgKSwgd2hpbGUgYSBnZW5lIHdpdGggYSBsb2ctZm9sZCBjaGFuZ2Ugd2hpY2ggaXMgbGFyZ2UgaW4gbWFnbml0dWRlIGlzIGxpa2VseSB0byBiZSBiaW9sb2dpY2FsbHkgc2lnbmlmaWNhbnQuIA0KDQpgYGAge3IsIGV2YWwgPSBULCBpbmNsdWRlID0gVCwgZmlnLmRpbSA9IGMoNiw2KSwgZmlnLmFsaWduID0gImNlbnRlciJ9DQpwbG90KHNhcnNfZGF0YSRsb2cyRm9sZENoYW5nZS5BbHBoYV84aF92c19WSUNfOGgsIA0KICAgICAtbG9nMTAoY292aWRfYmFzZV9wX3ZhbHVlcyksIA0KICAgICBtYWluID0gIlZvbGNhbm8gUGxvdCBmb3IgU0FSUy1Db1YtMiANCiAgICAgVklDIGFuZCBBbHBoYSBzdHJhaW5zDQogICAgIDhoIHBvc3QtaW5mZWN0aW9uLCB1c2luZyBpbml0aWFsIHAtdmFsdWVzIiwNCiAgICAgeGxhYiA9ICJsb2cgRkMiLCB5bGFiID0gIi1sb2cxMChwdmFsKSIsDQogICAgIGNleCA9IDAuNSwgY29sID0gYXMubnVtZXJpYyhjb3ZpZF9iYXNlX3BfdmFsdWVzIDw9IDAuMDUpICsgMSkNCmBgYA0KDQpgYGAge3IsIGV2YWwgPSBULCBpbmNsdWRlID0gVCwgZmlnLmRpbSA9IGMoNiw2KSwgZmlnLmFsaWduID0gImNlbnRlciJ9DQpwbG90KHNhcnNfZGF0YSRsb2cyRm9sZENoYW5nZS5BbHBoYV84aF92c19WSUNfOGgsIA0KICAgICAtbG9nMTAoY292aWRfZmRyX3BfdmFsdWVzKSwgDQogICAgIG1haW4gPSAiVm9sY2FubyBQbG90IGZvciBTQVJTLUNvVi0yIA0KICAgICBWSUMgYW5kIEFscGhhIHN0cmFpbnMNCiAgICAgOGggcG9zdC1pbmZlY3Rpb24sIHVzaW5nIEZEUi1jb3JyZWN0ZWQgcC12YWx1ZXMiLA0KICAgICB4bGFiID0gImxvZyBGQyIsIHlsYWIgPSAiLWxvZzEwKHB2YWwpIiwNCiAgICAgY2V4ID0gMC41LCBjb2wgPSBhcy5udW1lcmljKGNvdmlkX2Zkcl9wX3ZhbHVlcyA8PSAwLjA1KSArIDEpDQpgYGANCg0KTm90ZSBoZXJlIGhvdyBtYW55IG9mIHRoZSBGRFItY29ycmVjdGVkICRwJC12YWx1ZXMgYXJlIG5vIGxvbmdlciBjb25zaWRlcmVkIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQuIEhvd2V2ZXIsIHRoZSBnZW5lcyB3aXRoIGxvdyBGRFItY29ycmVjdGVkICRwJC12YWx1ZXMgKGFuZCB0aHVzIGhpZ2ggeS1heGlzIHNjb3JlcyBpbiB0aGUgdm9sY2FubyBwbG90KSBhcHBlYXIgdG8gaGF2ZSBsb2ctZm9sZCBjaGFuZ2VzIGluIGdlbmUgZXhwcmVzc2lvbiB3aGljaCBhcmUgbm9uLXplcm8gYW5kIHJlbGF0aXZlbHkgbGFyZ2UgaW4gbWFnbml0dWRlLiBUaGlzIHN1Z2dlc3RzIHRoYXQgdGhlIGdlbmVzIGNvbG91cmVkIHJlZCBpbiB0aGUgc2Vjb25kIHZvbGNhbm8gcGxvdCBhcmUgYm90aCBiaW9sb2dpY2FsbHkgYW5kIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgLSBzbyB0aGUgRkRSLWNvcnJlY3Rpb24gaGFzIGJlZW4gYmVuZWZpY2lhbCwgYW5kIGhhcyBoZWxwZWQgZmlsdGVyIG91dCBzb21lIGdlbmVzIHdoaWNoLCB3aGlsZSBoYXZpbmcgbG93IGluaXRpYWwgJHAkLXZhbHVlcywgd2VyZSBub3QgYmlvbG9naWNhbGx5IHNpZ25pZmljYW50IGluIHRoaXMgY29udGV4dC4NCg0KRm9yIHRoaXMgZXhhbXBsZSwgaXQgaXMgd29ydGggY29uc2lkZXJpbmcgd2h5IGl0IG1pZ2h0IGJlIGltcG9ydGFudCB0byBjb21wYXJlIGdlbmUgZXhwcmVzc2lvbiBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSB0d28gY29yb25hdmlydXMgc3RyYWlucy4gRm9yIGV4YW1wbGUsIGlkZW50aWZ5aW5nIGdlbmVzIHdoaWNoIGFyZSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50bHkgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIGJldHdlZW4gdGhlIHR3byBzdHJhaW5zIGNvdWxkIGhlbHAgcmVzZWFyY2hlcnMgZGV2ZWxvcCB0cmVhdG1lbnRzIHdoaWNoIHdlcmUgcGVyc29uYWxpc2VkIHRvIHRoZSBkaWZmZXJlbnQgc3RyYWlucy4gU3VjaCB0cmVhdG1lbnRzIGNvdWxkIGJlIG1vcmUgZWZmZWN0aXZlIHRoYW4gdXNpbmcgYSBnZW5lcmljIHRyZWF0bWVudCB3aGljaCBtYXkgaGF2ZSB2YXJ5aW5nIGxldmVscyBvZiBlZmZpY2FjeSBmb3IgZGlmZmVyZW50IHN0cmFpbnMuIENhbiB5b3UgdGhpbmsgb2YgYW55IG90aGVyIHJlYXNvbnM/DQoNCjxicj4NCg0KIyMjIyBUaGF0J3MgZXZlcnl0aGluZyBjb3ZlcmVkLCB3ZWxsIGRvbmUuICMjIyMgey19DQoNCjxicj4NCg0KIyBSZWZlcmVuY2VzIHstICNSZWZ9DQo8ZGl2IGlkPSJyZWZzIj48L2Rpdj4NCg0KPGJyPg0KDQo8Zm9udCBjb2xvciA9ICJncmV5Ij4NClRoZXNlIG5vdGVzIGhhdmUgYmVlbiBwcmVwYXJlZCBieSBSdXBlcnQgS3V2ZWtlIGFuZCBBbWFuZGEgU2hha2VyLiBUaGUgY29weXJpZ2h0IGZvciB0aGUgbWF0ZXJpYWwgaW4gdGhlc2Ugbm90ZXMgcmVzaWRlcyB3aXRoIHRoZSBhdXRob3JzIG5hbWVkIGFib3ZlLCB3aXRoIHRoZSBEZXBhcnRtZW50IG9mIE1hdGhlbWF0aWNhbCBhbmQgUGh5c2ljYWwgU2NpZW5jZXMgYW5kIHdpdGggTGEgVHJvYmUgVW5pdmVyc2l0eS4gQ29weXJpZ2h0IGluIHRoaXMgd29yayBpcyB2ZXN0ZWQgaW4gTGEgVHJvYmUgVW5pdmVyc2l0eSBpbmNsdWRpbmcgYWxsIExhIFRyb2JlIFVuaXZlcnNpdHkgYnJhbmRpbmcgYW5kIG5hbWluZy4gVW5sZXNzIG90aGVyd2lzZSBzdGF0ZWQsIG1hdGVyaWFsIHdpdGhpbiB0aGlzIHdvcmsgaXMgbGljZW5zZWQgdW5kZXIgYSBDcmVhdGl2ZSBDb21tb25zIEF0dHJpYnV0aW9uLU5vbiBDb21tZXJjaWFsLU5vbiBEZXJpdmF0aXZlcyBMaWNlbnNlIA0KPGEgaHJlZiA9ICJodHRwczovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktbmMtbmQvNC4wL0NDIiB0YXJnZXQ9Il9ibGFuayI+IEJZLU5DLU5ELiA8L2E+DQo8L2ZvbnQ+