#projDirOsx <- "/Users/baller01/MyMount/clust1a/20200511_FernandesM_ME_crukBiSs2020"
#projDir <- "/mnt/scratcha/bioinformatics/baller01/20200511_FernandesM_ME_crukBiSs2020"
projDir <- "/home/ubuntu/Course_Materials/scRNAseq"
outDirBit <- "AnaWiSce/Attempt1"
library(DT)

1 Sequence Quality

1.1 Introduction

We will use two sets of Bone Marrow Mononuclear Cells (BMMC):

  • ‘CaronBourque2020’: pediatric samples
  • ‘Hca’: HCA Census of Immune Cells for adult BMMCs

Fastq files were retrieved from publicly available archive (SRA and HCA).

Sequencing quality was assessed and visualised using fastQC and MultiQC.

Library structure reminder:

  • The sample index identifies the library, with one I7 index per sample
  • The 10X cell barcode (or cell index) identifies the droplet in the library
  • The UMI identifies the transcript molecule within a cell and gene
  • The insert is the transcript molecule, ie the cDNA sequence

Each sample is described with three sets of fastq files:

  • I1: sample index
  • R1: 10x barcode + UMI
  • R2: insert sequence

The sample index is actually a set of four 8-ntd oligo. For example SIGAB8 is ‘AAAGTGCT-GCTACCTG-TGCTGTAA-CTGCAAGC’. All four are used and identified by a digit, eg 1-4. Depending on the processing pipeline, fastq files may be returned for each 8-ntd index, or combined into a single file.

For the Caron data set they are combined in a single file, and files for separate lanes were also combined into a single fastq file.

Each sample is identified by three fastq files, one per read type:

  • sample _ S0 _ L001 _ I1 _ 001 _ .fastq.gz: contains sample index
  • sample _ S0 _ L001 _ R1 _ 001 _ .fastq.gz: contains 10x barcode + UMI
  • sample _ S0 _ L001 _ R2 _ 001 _ .fastq.gz: contains insert sequence

We kept the same names for the fastqc output. With for example sample ‘SRR9264343’:

  • SRR9264343 _ S0 _ L001 _ I1 _ 001 _ fastqc.html
  • SRR9264343 _ S0 _ L001 _ R1 _ 001 _ fastqc.html
  • SRR9264343 _ S0 _ L001 _ R2 _ 001 _ fastqc.html
#wrkDir <- "/mnt/scratchb/bioinformatics/baller01/20200511_FernandesM_ME_crukBiSs2020/CaronBourque2020/grch38300"
#setwd(wrkDir)
outDirBit <- "AnaWiSeurat/Attempt1" # params$outDirBit # "AnaWiSeurat/Attempt1"
fastqcDir <- sprintf("%s/Data/%s/fastqc", projDir, "CaronBourque2020")
#fastqcDirOsx <- sprintf("%s/Data/%s/fastqc", projDirOsx, "CaronBourque2020")

1.2 CaronBourque2020 - fastqc

Sample sheet:

# CaronBourque2020
cb_sampleSheetFn <- file.path(projDir, "Data/CaronBourque2020/SraRunTable.txt")
cb_sampleSheet <- read.table(cb_sampleSheetFn, header=T, sep=",")
#cb_sampleSheet <-  cb_sampleSheet %>% filter(!Run == "SRR9264351")
cb_sampleSheet
htmlVec <- list.files(fastqcDir)
htmlVec <- grep("\\.html$", htmlVec, value=TRUE)
filesDf <- data.frame(
              "I1" = sprintf("%s_S0_L001_%s_001_fastqc.html", cb_sampleSheet$Run, "I1"),
              "R1" = sprintf("%s_S0_L001_%s_001_fastqc.html", cb_sampleSheet$Run, "R1"),
              "R2" = sprintf("%s_S0_L001_%s_001_fastqc.html", cb_sampleSheet$Run, "R2")
)
rownames(filesDf) <- cb_sampleSheet$Run
for (runx in cb_sampleSheet$Run)
{
    cat("Run ", runx, ":\n\n")
    for(i in c("I1", "R1", "R2"))
    {
        filepath <- file.path(fastqcDir, filesDf[runx,i])
        cat(i, ": [", filesDf[runx,i], "](",filepath,")\n\n")
    }
}

Links to reports (on the student machine):

Run SRR9264343 :

I1 : SRR9264343_S0_L001_I1_001_fastqc.html

R1 : SRR9264343_S0_L001_R1_001_fastqc.html

R2 : SRR9264343_S0_L001_R2_001_fastqc.html

Run SRR9264344 :

I1 : SRR9264344_S0_L001_I1_001_fastqc.html

R1 : SRR9264344_S0_L001_R1_001_fastqc.html

R2 : SRR9264344_S0_L001_R2_001_fastqc.html

Run SRR9264345 :

I1 : SRR9264345_S0_L001_I1_001_fastqc.html

R1 : SRR9264345_S0_L001_R1_001_fastqc.html

R2 : SRR9264345_S0_L001_R2_001_fastqc.html

Run SRR9264346 :

I1 : SRR9264346_S0_L001_I1_001_fastqc.html

R1 : SRR9264346_S0_L001_R1_001_fastqc.html

R2 : SRR9264346_S0_L001_R2_001_fastqc.html

Run SRR9264347 :

I1 : SRR9264347_S0_L001_I1_001_fastqc.html

R1 : SRR9264347_S0_L001_R1_001_fastqc.html

R2 : SRR9264347_S0_L001_R2_001_fastqc.html

Run SRR9264348 :

I1 : SRR9264348_S0_L001_I1_001_fastqc.html

R1 : SRR9264348_S0_L001_R1_001_fastqc.html

R2 : SRR9264348_S0_L001_R2_001_fastqc.html

Run SRR9264349 :

I1 : SRR9264349_S0_L001_I1_001_fastqc.html

R1 : SRR9264349_S0_L001_R1_001_fastqc.html

R2 : SRR9264349_S0_L001_R2_001_fastqc.html

Run SRR9264350 :

I1 : SRR9264350_S0_L001_I1_001_fastqc.html

R1 : SRR9264350_S0_L001_R1_001_fastqc.html

R2 : SRR9264350_S0_L001_R2_001_fastqc.html

Run SRR9264351 :

I1 : SRR9264351_S0_L001_I1_001_fastqc.html

R1 : SRR9264351_S0_L001_R1_001_fastqc.html

R2 : SRR9264351_S0_L001_R2_001_fastqc.html

Run SRR9264352 :

I1 : SRR9264352_S0_L001_I1_001_fastqc.html

R1 : SRR9264352_S0_L001_R1_001_fastqc.html

R2 : SRR9264352_S0_L001_R2_001_fastqc.html

Run SRR9264353 :

I1 : SRR9264353_S0_L001_I1_001_fastqc.html

R1 : SRR9264353_S0_L001_R1_001_fastqc.html

R2 : SRR9264353_S0_L001_R2_001_fastqc.html

Run SRR9264354 :

I1 : SRR9264354_S0_L001_I1_001_fastqc.html

R1 : SRR9264354_S0_L001_R1_001_fastqc.html

R2 : SRR9264354_S0_L001_R2_001_fastqc.html

1.3 CaronBourque2020 - MultiQC

1.3.1 sample index: I1

htmlVec <- list.files(paste0(fastqcDir, "/Multiqc/I1"))
htmlVec <- grep("\\.html$", htmlVec, value=TRUE)
for(i in htmlVec){
    filename <- file.path(fastqcDir, "/Multiqc/I1", i)
    cat("[", i, "](",filename,")\n\n")
}

multiqc_report.html

1.3.2 cell barcode + UMI: R1

htmlVec <- list.files(paste0(fastqcDir, "/Multiqc/R1"))
htmlVec <- grep("\\.html$", htmlVec, value=TRUE)
for(i in htmlVec){
    filename <- file.path(fastqcDir, "/Multiqc/R1", i)
    cat("[", i, "](",filename,")\n\n")
}

multiqc_report.html

1.3.3 insert: R2

htmlVec <- list.files(paste0(fastqcDir, "/Multiqc/R2"))
htmlVec <- grep("\\.html$", htmlVec, value=TRUE)
for(i in htmlVec){
    filename <- file.path(fastqcDir, "/Multiqc/R2", i)
    cat("[", i, "](",filename,")\n\n")
}

multiqc_report.html

1.4 HCA adult BMMC - fastqc

For the HCA adult BMMC fastq files were provided for each 8-ntd sample index and lane. We ran fastqc on each separately. We are therefore not listing links to the fastqc reports but only to the MultiQC reports.

Sample sheet:

fastqcDir <- sprintf("%s/Data/%s/fastqc", projDir, "Hca")

# HCA
hca_sampleSheetFn <- file.path(projDir, "Data/Hca/accList_Hca.txt")

hca_sampleSheet <- read.table(hca_sampleSheetFn, header=F, sep=",")
colnames(hca_sampleSheet) <- "Run"
hca_sampleSheet
htmlVec <- list.files(fastqcDir)
htmlVec <- grep("\\.html$", htmlVec, value=TRUE)

378 fastqc reports were compiled in the multiQC reports below.

1.5 HCA adult BMMC - MultiQC

1.5.1 sample index: I1

htmlVec <- list.files(paste0(fastqcDir, "/Multiqc/I1"))
htmlVec <- grep("\\.html$", htmlVec, value=TRUE)
for(i in htmlVec){
    filename <- file.path(fastqcDir, "/Multiqc/I1", i)
    cat("[", i, "](",filename,")\n\n")
}

multiqc_report.html

1.5.2 cell barcode + UMI: R1

htmlVec <- list.files(paste0(fastqcDir, "/Multiqc/R1"))
htmlVec <- grep("\\.html$", htmlVec, value=TRUE)
for(i in htmlVec){
    filename <- file.path(fastqcDir, "/Multiqc/R1", i)
    cat("[", i, "](",filename,")\n\n")
}

multiqc_report.html

1.5.3 insert: R2

htmlVec <- list.files(paste0(fastqcDir, "/Multiqc/R2"))
htmlVec <- grep("\\.html$", htmlVec, value=TRUE)
for(i in htmlVec){
    filename <- file.path(fastqcDir, "/Multiqc/R2", i)
    cat("[", i, "](",filename,")\n\n")
}

multiqc_report.html

LS0tCnRpdGxlOiAiQ1JVSyBDSSBTdW1tZXIgU2Nob29sIDIwMjAgLSBpbnRyb2R1Y3Rpb24gdG8gc2luZ2xlLWNlbGwgUk5BLXNlcSBhbmFseXNpcyIKc3VidGl0bGU6ICdTZXF1ZW5jZSBxdWFsaXR5JwoKYXV0aG9yOiAiU3RlcGhhbmUgQmFsbGVyZWF1IgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgdG9jOiB5ZXMKICAgIHRvY19mbG9hdDogeWVzCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICB0b2M6IHllcwogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICBodG1sX2Jvb2s6CiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKcGFyYW1zOgogIG91dERpckJpdDogIkFuYVdpU2NlL0F0dGVtcHQxIgotLS0KCjwhLS0KVE9ETzoKLS0+CgpgYGB7ciBzZXFRdWFsLmtuaXRyX29wdGlvbnMsIGVjaG89RkFMU0UsIHJlc3VsdHM9ImhpZGUiLCBtZXNzYWdlPUZBTFNFfQpyZXF1aXJlKGtuaXRyKQojb3B0c19jaHVuayRzZXQoZXJyb3I9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGNhY2hlPVRSVUUpCm9wdHNfY2h1bmskc2V0KGVycm9yPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBjYWNoZT1GQUxTRSkKb3B0c19jaHVuayRzZXQoZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9NykgCmBgYAoKYGBge3J9CiNwcm9qRGlyT3N4IDwtICIvVXNlcnMvYmFsbGVyMDEvTXlNb3VudC9jbHVzdDFhLzIwMjAwNTExX0Zlcm5hbmRlc01fTUVfY3J1a0JpU3MyMDIwIgojcHJvakRpciA8LSAiL21udC9zY3JhdGNoYS9iaW9pbmZvcm1hdGljcy9iYWxsZXIwMS8yMDIwMDUxMV9GZXJuYW5kZXNNX01FX2NydWtCaVNzMjAyMCIKcHJvakRpciA8LSAiL2hvbWUvdWJ1bnR1L0NvdXJzZV9NYXRlcmlhbHMvc2NSTkFzZXEiCm91dERpckJpdCA8LSAiQW5hV2lTY2UvQXR0ZW1wdDEiCmBgYAoKYGBge3J9CmxpYnJhcnkoRFQpCmBgYAoKIyBTZXF1ZW5jZSBRdWFsaXR5IHsjU2VxUXVhbFRvcH0KCioqV09SS0lORyBET0NVTUVOVCAtIElOIFBST0dSRVNTKioKCiMjIEludHJvZHVjdGlvbgoKV2Ugd2lsbCB1c2UgdHdvIHNldHMgb2YgQm9uZSBNYXJyb3cgTW9ub251Y2xlYXIgQ2VsbHMgKEJNTUMpOgoKKiAnQ2Fyb25Cb3VycXVlMjAyMCc6IHBlZGlhdHJpYyBzYW1wbGVzCiogJ0hjYSc6IEhDQSBDZW5zdXMgb2YgSW1tdW5lIENlbGxzIGZvciBhZHVsdCBCTU1DcwoKRmFzdHEgZmlsZXMgd2VyZSByZXRyaWV2ZWQgZnJvbSBwdWJsaWNseSBhdmFpbGFibGUgYXJjaGl2ZSAoU1JBIGFuZCBIQ0EpLiAKClNlcXVlbmNpbmcgcXVhbGl0eSB3YXMgYXNzZXNzZWQgYW5kIHZpc3VhbGlzZWQgdXNpbmcgZmFzdFFDIGFuZCBNdWx0aVFDLgoKTGlicmFyeSBzdHJ1Y3R1cmUgcmVtaW5kZXI6Cgo8IS0tCiFbXShgciBzcHJpbnRmKCIlcy9JbWFnZXMvdGVueExpYlN0cnVjdHVyZVYzLnBuZyIsIHByb2pEaXIpYCkKLS0+CgoqIFRoZSAqKnNhbXBsZSBpbmRleCoqIGlkZW50aWZpZXMgdGhlIGxpYnJhcnksIHdpdGggb25lIEk3IGluZGV4IHBlciBzYW1wbGUKKiBUaGUgMTBYICoqY2VsbCBiYXJjb2RlKiogKG9yIGNlbGwgaW5kZXgpIGlkZW50aWZpZXMgdGhlIGRyb3BsZXQgaW4gdGhlIGxpYnJhcnkKKiBUaGUgKipVTUkqKiBpZGVudGlmaWVzIHRoZSB0cmFuc2NyaXB0IG1vbGVjdWxlIHdpdGhpbiBhIGNlbGwgYW5kIGdlbmUKKiBUaGUgKippbnNlcnQqKiBpcyB0aGUgdHJhbnNjcmlwdCBtb2xlY3VsZSwgaWUgdGhlIGNETkEgc2VxdWVuY2UKCkVhY2ggc2FtcGxlIGlzIGRlc2NyaWJlZCB3aXRoIHRocmVlIHNldHMgb2YgZmFzdHEgZmlsZXM6CgoqICoqSTEqKjogc2FtcGxlIGluZGV4CiogKipSMSoqOiAxMHggYmFyY29kZSArIFVNSQoqICoqUjIqKjogaW5zZXJ0IHNlcXVlbmNlCgpUaGUgc2FtcGxlIGluZGV4IGlzIGFjdHVhbGx5IGEgc2V0IG9mIGZvdXIgOC1udGQgb2xpZ28uCkZvciBleGFtcGxlIFNJR0FCOCBpcyAnQUFBR1RHQ1QtR0NUQUNDVEctVEdDVEdUQUEtQ1RHQ0FBR0MnLgpBbGwgZm91ciBhcmUgdXNlZCBhbmQgaWRlbnRpZmllZCBieSBhIGRpZ2l0LCBlZyAxLTQuCkRlcGVuZGluZyBvbiB0aGUgcHJvY2Vzc2luZyBwaXBlbGluZSwgZmFzdHEgZmlsZXMgbWF5IGJlIHJldHVybmVkIGZvciBlYWNoIDgtbnRkIGluZGV4LCBvciBjb21iaW5lZCBpbnRvIGEgc2luZ2xlIGZpbGUuCgpGb3IgdGhlIENhcm9uIGRhdGEgc2V0IHRoZXkgYXJlIGNvbWJpbmVkIGluIGEgc2luZ2xlIGZpbGUsIGFuZCBmaWxlcyBmb3Igc2VwYXJhdGUgbGFuZXMgd2VyZSBhbHNvIGNvbWJpbmVkIGludG8gYSBzaW5nbGUgZmFzdHEgZmlsZS4KCkVhY2ggc2FtcGxlIGlzIGlkZW50aWZpZWQgYnkgdGhyZWUgZmFzdHEgZmlsZXMsIG9uZSBwZXIgcmVhZCB0eXBlOgoKKiAqKnNhbXBsZSoqIF8gUzAgXyBMMDAxIF8gKipJMSoqIF8gMDAxIF8gLmZhc3RxLmd6OiBjb250YWlucyBzYW1wbGUgaW5kZXgKKiAqKnNhbXBsZSoqIF8gUzAgXyBMMDAxIF8gKipSMSoqIF8gMDAxIF8gLmZhc3RxLmd6OiBjb250YWlucyAxMHggYmFyY29kZSArIFVNSQoqICoqc2FtcGxlKiogXyBTMCBfIEwwMDEgXyAqKlIyKiogXyAwMDEgXyAuZmFzdHEuZ3o6IGNvbnRhaW5zIGluc2VydCBzZXF1ZW5jZQoKV2Uga2VwdCB0aGUgc2FtZSBuYW1lcyBmb3IgdGhlIGZhc3RxYyBvdXRwdXQuIFdpdGggZm9yIGV4YW1wbGUgc2FtcGxlICdTUlI5MjY0MzQzJzoKCiogKipTUlI5MjY0MzQzKiogXyBTMCBfIEwwMDEgXyAqKkkxKiogXyAwMDEgXyBmYXN0cWMuaHRtbAoqICoqU1JSOTI2NDM0MyoqIF8gUzAgXyBMMDAxIF8gKipSMSoqIF8gMDAxIF8gZmFzdHFjLmh0bWwKKiAqKlNSUjkyNjQzNDMqKiBfIFMwIF8gTDAwMSBfICoqUjIqKiBfIDAwMSBfIGZhc3RxYy5odG1sCgpgYGB7cn0KI3dya0RpciA8LSAiL21udC9zY3JhdGNoYi9iaW9pbmZvcm1hdGljcy9iYWxsZXIwMS8yMDIwMDUxMV9GZXJuYW5kZXNNX01FX2NydWtCaVNzMjAyMC9DYXJvbkJvdXJxdWUyMDIwL2dyY2gzODMwMCIKI3NldHdkKHdya0RpcikKb3V0RGlyQml0IDwtICJBbmFXaVNldXJhdC9BdHRlbXB0MSIgIyBwYXJhbXMkb3V0RGlyQml0ICPCoCJBbmFXaVNldXJhdC9BdHRlbXB0MSIKYGBgCgpgYGB7cn0KZmFzdHFjRGlyIDwtIHNwcmludGYoIiVzL0RhdGEvJXMvZmFzdHFjIiwgcHJvakRpciwgIkNhcm9uQm91cnF1ZTIwMjAiKQojZmFzdHFjRGlyT3N4IDwtIHNwcmludGYoIiVzL0RhdGEvJXMvZmFzdHFjIiwgcHJvakRpck9zeCwgIkNhcm9uQm91cnF1ZTIwMjAiKQpgYGAKCiMjIENhcm9uQm91cnF1ZTIwMjAgLSBmYXN0cWMKCmBgYHtyfQojwqBDYXJvbkJvdXJxdWUyMDIwCmNiX3NhbXBsZVNoZWV0Rm4gPC0gZmlsZS5wYXRoKHByb2pEaXIsICJEYXRhL0Nhcm9uQm91cnF1ZTIwMjAvU3JhUnVuVGFibGUudHh0IikKY2Jfc2FtcGxlU2hlZXQgPC0gcmVhZC50YWJsZShjYl9zYW1wbGVTaGVldEZuLCBoZWFkZXI9VCwgc2VwPSIsIikKI2NiX3NhbXBsZVNoZWV0IDwtICBjYl9zYW1wbGVTaGVldCAlPiUgZmlsdGVyKCFSdW4gPT0gIlNSUjkyNjQzNTEiKQpjYl9zYW1wbGVTaGVldApgYGAKCmBgYHtyLCByZXN1bHRzID0gJ2FzaXMnfQpodG1sVmVjIDwtIGxpc3QuZmlsZXMoZmFzdHFjRGlyKQpodG1sVmVjIDwtIGdyZXAoIlxcLmh0bWwkIiwgaHRtbFZlYywgdmFsdWU9VFJVRSkKYGBgCgpgYGB7cn0KZmlsZXNEZiA8LSBkYXRhLmZyYW1lKAoJCSAgICAgICJJMSIgPSBzcHJpbnRmKCIlc19TMF9MMDAxXyVzXzAwMV9mYXN0cWMuaHRtbCIsIGNiX3NhbXBsZVNoZWV0JFJ1biwgIkkxIiksCgkJICAgICAgIlIxIiA9IHNwcmludGYoIiVzX1MwX0wwMDFfJXNfMDAxX2Zhc3RxYy5odG1sIiwgY2Jfc2FtcGxlU2hlZXQkUnVuLCAiUjEiKSwKCQkgICAgICAiUjIiID0gc3ByaW50ZigiJXNfUzBfTDAwMV8lc18wMDFfZmFzdHFjLmh0bWwiLCBjYl9zYW1wbGVTaGVldCRSdW4sICJSMiIpCikKcm93bmFtZXMoZmlsZXNEZikgPC0gY2Jfc2FtcGxlU2hlZXQkUnVuCmBgYAoKYGBge3IsIHJlc3VsdHMgPSAnYXNpcyd9CmZvciAocnVueCBpbiBjYl9zYW1wbGVTaGVldCRSdW4pCnsKCWNhdCgiUnVuICIsIHJ1bngsICI6XG5cbiIpCglmb3IoaSBpbiBjKCJJMSIsICJSMSIsICJSMiIpKQoJewoJCWZpbGVwYXRoIDwtIGZpbGUucGF0aChmYXN0cWNEaXIsIGZpbGVzRGZbcnVueCxpXSkKCQljYXQoaSwgIjogWyIsIGZpbGVzRGZbcnVueCxpXSwgIl0oIixmaWxlcGF0aCwiKVxuXG4iKQoJfQp9CmBgYAoKIyMgQ2Fyb25Cb3VycXVlMjAyMCAtIE11bHRpUUMKCiMjIyBzYW1wbGUgaW5kZXg6IEkxCgpgYGB7ciwgcmVzdWx0cyA9ICdhc2lzJ30KaHRtbFZlYyA8LSBsaXN0LmZpbGVzKHBhc3RlMChmYXN0cWNEaXIsICIvTXVsdGlxYy9JMSIpKQpodG1sVmVjIDwtIGdyZXAoIlxcLmh0bWwkIiwgaHRtbFZlYywgdmFsdWU9VFJVRSkKZm9yKGkgaW4gaHRtbFZlYyl7CglmaWxlbmFtZSA8LSBmaWxlLnBhdGgoZmFzdHFjRGlyLCAiL011bHRpcWMvSTEiLCBpKQoJY2F0KCJbIiwgaSwgIl0oIixmaWxlbmFtZSwiKVxuXG4iKQp9CmBgYAoKIyMjIGNlbGwgYmFyY29kZSArIFVNSTogUjEKCmBgYHtyLCByZXN1bHRzID0gJ2FzaXMnfQpodG1sVmVjIDwtIGxpc3QuZmlsZXMocGFzdGUwKGZhc3RxY0RpciwgIi9NdWx0aXFjL1IxIikpCmh0bWxWZWMgPC0gZ3JlcCgiXFwuaHRtbCQiLCBodG1sVmVjLCB2YWx1ZT1UUlVFKQpmb3IoaSBpbiBodG1sVmVjKXsKCWZpbGVuYW1lIDwtIGZpbGUucGF0aChmYXN0cWNEaXIsICIvTXVsdGlxYy9SMSIsIGkpCgljYXQoIlsiLCBpLCAiXSgiLGZpbGVuYW1lLCIpXG5cbiIpCn0KYGBgCgojIyMgaW5zZXJ0OiBSMgoKYGBge3IsIHJlc3VsdHMgPSAnYXNpcyd9Cmh0bWxWZWMgPC0gbGlzdC5maWxlcyhwYXN0ZTAoZmFzdHFjRGlyLCAiL011bHRpcWMvUjIiKSkKaHRtbFZlYyA8LSBncmVwKCJcXC5odG1sJCIsIGh0bWxWZWMsIHZhbHVlPVRSVUUpCmZvcihpIGluIGh0bWxWZWMpewoJZmlsZW5hbWUgPC0gZmlsZS5wYXRoKGZhc3RxY0RpciwgIi9NdWx0aXFjL1IyIiwgaSkKCWNhdCgiWyIsIGksICJdKCIsZmlsZW5hbWUsIilcblxuIikKfQpgYGAKCiMjIEhDQSBhZHVsdCBCTU1DIC0gZmFzdHFjCgpGb3IgdGhlIEhDQSBhZHVsdCBCTU1DIGZhc3RxIGZpbGVzIHdlcmUgcHJvdmlkZWQgZm9yIGVhY2ggOC1udGQgc2FtcGxlIGluZGV4IGFuZCBsYW5lLiBXZSByYW4gZmFzdHFjIG9uIGVhY2ggc2VwYXJhdGVseS4gV2UgYXJlIHRoZXJlZm9yZSBub3QgbGlzdGluZyBsaW5rcyB0byB0aGUgZmFzdHFjIHJlcG9ydHMgYnV0IG9ubHkgdG8gdGhlIE11bHRpUUMgcmVwb3J0cy4KCmBgYHtyfQpmYXN0cWNEaXIgPC0gc3ByaW50ZigiJXMvRGF0YS8lcy9mYXN0cWMiLCBwcm9qRGlyLCAiSGNhIikKCiPCoEhDQQpoY2Ffc2FtcGxlU2hlZXRGbiA8LSBmaWxlLnBhdGgocHJvakRpciwgIkRhdGEvSGNhL2FjY0xpc3RfSGNhLnR4dCIpCgpoY2Ffc2FtcGxlU2hlZXQgPC0gcmVhZC50YWJsZShoY2Ffc2FtcGxlU2hlZXRGbiwgaGVhZGVyPUYsIHNlcD0iLCIpCmNvbG5hbWVzKGhjYV9zYW1wbGVTaGVldCkgPC0gIlJ1biIKaGNhX3NhbXBsZVNoZWV0CmBgYAoKYGBge3IsIHJlc3VsdHMgPSAnYXNpcyd9Cmh0bWxWZWMgPC0gbGlzdC5maWxlcyhmYXN0cWNEaXIpCmh0bWxWZWMgPC0gZ3JlcCgiXFwuaHRtbCQiLCBodG1sVmVjLCB2YWx1ZT1UUlVFKQpgYGAKCmByICNsZW5ndGgoaHRtbFZlYylgCjM3OCBmYXN0cWMgcmVwb3J0cyB3ZXJlIGNvbXBpbGVkIGluIHRoZSBtdWx0aVFDIHJlcG9ydHMgYmVsb3cuCgojIyAgSENBIGFkdWx0IEJNTUMgLSBNdWx0aVFDCgojIyMgc2FtcGxlIGluZGV4OiBJMQoKYGBge3IsIHJlc3VsdHMgPSAnYXNpcyd9Cmh0bWxWZWMgPC0gbGlzdC5maWxlcyhwYXN0ZTAoZmFzdHFjRGlyLCAiL011bHRpcWMvSTEiKSkKaHRtbFZlYyA8LSBncmVwKCJcXC5odG1sJCIsIGh0bWxWZWMsIHZhbHVlPVRSVUUpCmZvcihpIGluIGh0bWxWZWMpewoJZmlsZW5hbWUgPC0gZmlsZS5wYXRoKGZhc3RxY0RpciwgIi9NdWx0aXFjL0kxIiwgaSkKCWNhdCgiWyIsIGksICJdKCIsZmlsZW5hbWUsIilcblxuIikKfQpgYGAKCiMjIyBjZWxsIGJhcmNvZGUgKyBVTUk6IFIxCgpgYGB7ciwgcmVzdWx0cyA9ICdhc2lzJ30KaHRtbFZlYyA8LSBsaXN0LmZpbGVzKHBhc3RlMChmYXN0cWNEaXIsICIvTXVsdGlxYy9SMSIpKQpodG1sVmVjIDwtIGdyZXAoIlxcLmh0bWwkIiwgaHRtbFZlYywgdmFsdWU9VFJVRSkKZm9yKGkgaW4gaHRtbFZlYyl7CglmaWxlbmFtZSA8LSBmaWxlLnBhdGgoZmFzdHFjRGlyLCAiL011bHRpcWMvUjEiLCBpKQoJY2F0KCJbIiwgaSwgIl0oIixmaWxlbmFtZSwiKVxuXG4iKQp9CmBgYAoKIyMjIGluc2VydDogUjIKCmBgYHtyLCByZXN1bHRzID0gJ2FzaXMnfQpodG1sVmVjIDwtIGxpc3QuZmlsZXMocGFzdGUwKGZhc3RxY0RpciwgIi9NdWx0aXFjL1IyIikpCmh0bWxWZWMgPC0gZ3JlcCgiXFwuaHRtbCQiLCBodG1sVmVjLCB2YWx1ZT1UUlVFKQpmb3IoaSBpbiBodG1sVmVjKXsKCWZpbGVuYW1lIDwtIGZpbGUucGF0aChmYXN0cWNEaXIsICIvTXVsdGlxYy9SMiIsIGkpCgljYXQoIlsiLCBpLCAiXSgiLGZpbGVuYW1lLCIpXG5cbiIpCn0KYGBgCgoK