1 Introduction

I want to use this document to examine our first round of persistence samples. I checked my email from Najib and did not find a sample sheet but did find an explanation of the three sample types we expect.

In preparation for this, I downloaded a new hg38 genome. Since the panamensis asembly has not significantly changed (excepting the putative long read genome which I have not yet seen), I am just using the same one.

2 Loading annotation

The hg38 genome I got is brand new (202405), so do not use the archive for a while.

## Ok, so useast.ensembl is failing today, let us use the jan2024 archive?
#hs_annot <- load_biomart_annotations(archive = FALSE, species = "hsapiens")
## Seems like the 202401 archive is a good choice, it is explicitly the hg38_111 release.
## and it is waaaaay faster (like 100x) than useast right now.
hs_annot <- load_biomart_annotations(archive = TRUE, species = "hsapiens",
                                     year = 2024, month = "01")
## The biomart annotations file already exists, loading from it.
panamensis_orgdb_idx <- grep(pattern = "^org.+panamen.+MHOM.+db$", x = rownames(installed.packages()))
panamensis_orgdb <- tail(rownames(installed.packages())[panamensis_orgdb_idx], n = 1)
lp_annot <- load_orgdb_annotations(panamensis_orgdb, keytype = "gid")
## Loading required package: AnnotationDbi
## 
## Unable to find CDSNAME, setting it to ANNOT_EXTERNAL_DB_NAME.
## Unable to find CDSCHROM in the db, removing it.
## Unable to find CDSSTRAND in the db, removing it.
## Unable to find CDSSTART in the db, removing it.
## Unable to find CDSEND in the db, removing it.
## Extracted all gene ids.
## Attempting to select: ANNOT_EXTERNAL_DB_NAME, GENE_TYPE
## 'select()' returned 1:1 mapping between keys and columns

This is a little silly, but I am going to reload the annotations using the previous invocation to extract the annotation table without having to think. The previous block loads the orgdb for me, so I can just use that to get the fun annotations.

all_columns <- keytypes(get0(panamensis_orgdb))
annot_idx <- grep(pattern = "^ANNOT_", x = all_columns)
annot_columns <- all_columns[annot_idx]
lp_annot <- load_orgdb_annotations(panamensis_orgdb, keytype = "gid", fields = annot_columns)
## Unable to find CDSNAME, setting it to ANNOT_EXTERNAL_DB_NAME.
## Unable to find CDSCHROM in the db, removing it.
## Unable to find CDSSTRAND in the db, removing it.
## Unable to find CDSSTART in the db, removing it.
## Unable to find CDSEND in the db, removing it.
## Extracted all gene ids.
## Attempting to select: ANNOT_EXTERNAL_DB_NAME, GENE_TYPE, ANNOT_AA_SEQUENCE_ID, ANNOT_ANNOTATED_GO_COMPONENT, ANNOT_ANNOTATED_GO_FUNCTION, ANNOT_ANNOTATED_GO_ID_COMPONENT, ANNOT_ANNOTATED_GO_ID_FUNCTION, ANNOT_ANNOTATED_GO_ID_PROCESS, ANNOT_ANNOTATED_GO_PROCESS, ANNOT_ANTICODON, ANNOT_APOLLO_LINK_OUT, ANNOT_APOLLO_TRANSCRIPT_DESCRIPTION, ANNOT_CDS, ANNOT_CDS_LENGTH, ANNOT_CHROMOSOME, ANNOT_CODING_END, ANNOT_CODING_START, ANNOT_EC_NUMBERS, ANNOT_EC_NUMBERS_DERIVED, ANNOT_END_MAX, ANNOT_EXON_COUNT, ANNOT_EXTERNAL_DB_NAME, ANNOT_EXTERNAL_DB_VERSION, ANNOT_FIVE_PRIME_UTR_LENGTH, ANNOT_GENE_CONTEXT_END, ANNOT_GENE_CONTEXT_START, ANNOT_GENE_END_MAX, ANNOT_GENE_END_MAX_TEXT, ANNOT_GENE_ENTREZ_ID, ANNOT_GENE_ENTREZ_LINK, ANNOT_GENE_EXON_COUNT, ANNOT_GENE_HTS_NONCODING_SNPS, ANNOT_GENE_HTS_NONSYN_SYN_RATIO, ANNOT_GENE_HTS_NONSYNONYMOUS_SNPS, ANNOT_GENE_HTS_STOP_CODON_SNPS, ANNOT_GENE_HTS_SYNONYMOUS_SNPS, ANNOT_GENE_LOCATION_TEXT, ANNOT_GENE_NAME, ANNOT_GENE_ORTHOLOG_NUMBER, ANNOT_GENE_ORTHOMCL_NAME, ANNOT_GENE_PARALOG_NUMBER, ANNOT_GENE_PREVIOUS_IDS, ANNOT_GENE_PRODUCT, ANNOT_GENE_START_MIN, ANNOT_GENE_START_MIN_TEXT, ANNOT_GENE_TOTAL_HTS_SNPS, ANNOT_GENE_TRANSCRIPT_COUNT, ANNOT_GENE_TYPE, ANNOT_GENOMIC_SEQUENCE_LENGTH, ANNOT_GENUS_SPECIES, ANNOT_HAS_MISSING_TRANSCRIPTS, ANNOT_INTERPRO_DESCRIPTION, ANNOT_INTERPRO_ID, ANNOT_IS_DEPRECATED, ANNOT_IS_PSEUDO, ANNOT_ISOELECTRIC_POINT, ANNOT_LOCATION_TEXT, ANNOT_MAP_LOCATION, ANNOT_MCMC_LOCATION, ANNOT_MOLECULAR_WEIGHT, ANNOT_NCBI_TAX_ID, ANNOT_ORTHOMCL_LINK, ANNOT_OVERVIEW, ANNOT_PFAM_DESCRIPTION, ANNOT_PFAM_ID, ANNOT_PIRSF_DESCRIPTION, ANNOT_PIRSF_ID, ANNOT_PREDICTED_GO_COMPONENT, ANNOT_PREDICTED_GO_FUNCTION, ANNOT_PREDICTED_GO_ID_COMPONENT, ANNOT_PREDICTED_GO_ID_FUNCTION, ANNOT_PREDICTED_GO_ID_PROCESS, ANNOT_PREDICTED_GO_PROCESS, ANNOT_PRIMARY_KEY, ANNOT_PROB_MAP, ANNOT_PROB_MCMC, ANNOT_PROSITEPROFILES_DESCRIPTION, ANNOT_PROSITEPROFILES_ID, ANNOT_PROTEIN_LENGTH, ANNOT_PROTEIN_SEQUENCE, ANNOT_PROTEIN_SOURCE_ID, ANNOT_PSEUDO_STRING, ANNOT_SEQUENCE_DATABASE_NAME, ANNOT_SEQUENCE_ID, ANNOT_SIGNALP_PEPTIDE, ANNOT_SMART_DESCRIPTION, ANNOT_SMART_ID, ANNOT_SNPOVERVIEW, ANNOT_SO_ID, ANNOT_SO_TERM_DEFINITION, ANNOT_SO_TERM_NAME, ANNOT_SO_VERSION, ANNOT_START_MIN, ANNOT_STRAND, ANNOT_STRAND_PLUS_MINUS, ANNOT_SUPERFAMILY_DESCRIPTION, ANNOT_SUPERFAMILY_ID, ANNOT_THREE_PRIME_UTR_LENGTH, ANNOT_TIGRFAM_DESCRIPTION, ANNOT_TIGRFAM_ID, ANNOT_TM_COUNT, ANNOT_TRANS_FOUND_PER_GENE_INTERNAL, ANNOT_TRANSCRIPT_INDEX_PER_GENE, ANNOT_TRANSCRIPT_LENGTH, ANNOT_TRANSCRIPT_LINK, ANNOT_TRANSCRIPT_PRODUCT, ANNOT_TRANSCRIPT_SEQUENCE, ANNOT_TRANSCRIPTS_FOUND_PER_GENE, ANNOT_UNIPROT_IDS, ANNOT_UNIPROT_LINKS
## 'select()' returned 1:1 mapping between keys and columns

3 Collect preprocessed metadata

first_spec <- make_rnaseq_spec()

pre_meta <- gather_preprocessing_metadata(
  starting_metadata = "sample_sheets/tmrc_persistence_202405.xlsx",
  specification = first_spec,
  basedir = "preprocessing/202405", species="lpanamensis_v68",
  new_metadata = "sample_sheets/tmrc_persistence_202405_lpanamensis.xlsx")
## Did not find the condition column in the sample sheet.
## Filling it in as undefined.
## Did not find the batch column in the sample sheet.
## Filling it in as undefined.
## Warning in dispatch_regex_search(meta, search, replace, input_file_spec, : NAs introduced by coercion
## Writing new metadata to: sample_sheets/tmrc_persistence_202405_lpanamensis.xlsx
## Deleting the file sample_sheets/tmrc_persistence_202405_lpanamensis.xlsx before writing the tables.
hisat_idx <- grep(pattern = "^hisat", x = names(first_spec))
second_spec <- first_spec[hisat_idx]
post_meta <- gather_preprocessing_metadata(
  starting_metadata = pre_meta[["new_meta"]],
  specification = second_spec, basedir = "preprocessing/202405", species = "hg38_111",
  new_metadata = "sample_sheets/tmrc2_persistence_202405_lp_hg.xlsx")
## Warning in gather_preprocessing_metadata(starting_metadata = pre_meta[["new_meta"]], : Column: hisat_rrna_percent_log already exists, replacing it.

## Warning in gather_preprocessing_metadata(starting_metadata = pre_meta[["new_meta"]], : NAs introduced by coercion
## Warning in gather_preprocessing_metadata(starting_metadata = pre_meta[["new_meta"]], : Column: hisat_genome_single_concordant already exists, replacing it.
## Warning in gather_preprocessing_metadata(starting_metadata = pre_meta[["new_meta"]], : Column: hisat_genome_multi_concordant already exists, replacing it.
## Warning in gather_preprocessing_metadata(starting_metadata = pre_meta[["new_meta"]], : Column: hisat_genome_single_all already exists, replacing it.
## Warning in gather_preprocessing_metadata(starting_metadata = pre_meta[["new_meta"]], : Column: hisat_genome_multi_all already exists, replacing it.
## Warning in gather_preprocessing_metadata(starting_metadata = pre_meta[["new_meta"]], : Column: hisat_unmapped already exists, replacing it.
## Warning in gather_preprocessing_metadata(starting_metadata = pre_meta[["new_meta"]], : Column: hisat_genome_percent_log already exists, replacing it.
## Warning in gather_preprocessing_metadata(starting_metadata = pre_meta[["new_meta"]], : Column: hisat_observed_genes already exists, replacing it.
## Warning in gather_preprocessing_metadata(starting_metadata = pre_meta[["new_meta"]], : Column: hisat_observed_mean_exprs already exists, replacing it.
## Warning in gather_preprocessing_metadata(starting_metadata = pre_meta[["new_meta"]], : Column: hisat_observed_median_exprs already exists, replacing it.
## Warning in gather_preprocessing_metadata(starting_metadata = pre_meta[["new_meta"]], : Column: hisat_count_table already exists, replacing it.
## Writing new metadata to: sample_sheets/tmrc2_persistence_202405_lp_hg.xlsx
## Deleting the file sample_sheets/tmrc2_persistence_202405_lp_hg.xlsx before writing the tables.
both_meta <- gather_preprocessing_metadata(
  starting_metadata = "sample_sheets/tmrc_persistence_202405.xlsx",
  specification = first_spec,
  basedir = "preprocessing/202405", species= c("lpanamensis_v68", "hg38_111"),
  new_metadata = "sample_sheets/tmrc_persistence_202405_both.xlsx")
## Did not find the condition column in the sample sheet.
## Filling it in as undefined.
## Did not find the batch column in the sample sheet.
## Filling it in as undefined.
## Warning in dispatch_regex_search(meta, search, replace, input_file_spec, : NAs introduced by coercion
## Warning in dispatch_regex_search(meta, search, replace, input_file_spec, : NAs introduced by coercion
## Writing new metadata to: sample_sheets/tmrc_persistence_202405_both.xlsx
## Deleting the file sample_sheets/tmrc_persistence_202405_both.xlsx before writing the tables.

4 Collect gene annotations

I should have all my load_xyz_annotation functions return some of the same elements in their retlists.

lp_genes <- lp_annot[["genes"]]
hg_genes <- hs_annot[["gene_annotations"]]

5 Quick peek at the SL samples, hg38 release 111

hs_all_samples <- create_expt("sample_sheets/tmrc_persistence_202405_both.xlsx",
                              gene_info = hg_genes,
                              file_column = "hisatcounttablehg38111")
## Reading the sample metadata.
## The sample definitions comprises: 21 rows(samples) and 41 columns(metadata fields).
## Matched 21557 annotations and counts.
## Bringing together the count matrix and gene information.
## Some annotations were lost in merging, setting them to 'undefined'.
## Saving the expressionset to 'expt.rda'.
## The final expressionset has 21557 features and 21 samples.
sl_idx <- pData(hs_all_samples)[["sampletype"]] == "SL"
hs_sl_samples <- hs_all_samples[, sl_idx]
## Subsetting on samples.
## The samples excluded are: PRCS0001, PRCS0002, PRCS0003, PRCS0004, PRCS0005, PRHU0001, PRHU0002, PRHU0003.
## subset_expt(): There were 21, now there are 13 samples.
hu_idx <- pData(hs_all_samples)[["sampletype"]] == "HU"
hs_hu_samples <- hs_all_samples[, hu_idx]
## Subsetting on samples.
## The samples excluded are: PRCS0001, PRCS0002, PRCS0003, PRCS0004, PRCS0005, PRSL0001, PRSL0002, PRSL0003, PRSL0004, PRSL0005, PRSL0006, PRSL0007, PRSL0008, PRSL0009, PRSL0010, PRSL0011, PRSL0012, PRSL0015.
## subset_expt(): There were 21, now there are 3 samples.

6 SL metadata

lp_all_hisat_mapped <- plot_metadata_factors(lp_all_samples,
                                             column = "hisatgenomesingleconcordantlpanamensisv68")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'lp_all_samples' not found
lp_all_hisat_mapped
## Error in eval(expr, envir, enclos): object 'lp_all_hisat_mapped' not found
hs_all_hisat_mapped <- plot_metadata_factors(hs_all_samples,
                                            column = "hisatgenomesingleconcordanthg38111")
## Error in geom_jitter(height = 0, width = 0.1): could not find function "geom_jitter"
hs_all_hisat_mapped
## Error in eval(expr, envir, enclos): object 'hs_all_hisat_mapped' not found
lp_sl_hisat_genes <- plot_metadata_factors(lp_sl_samples,
                                           column = "hisatobservedgeneslpanamensisv68")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'lp_sl_samples' not found
lp_sl_hisat_genes
## Error in eval(expr, envir, enclos): object 'lp_sl_hisat_genes' not found
hs_sl_hisat_genes <- plot_metadata_factors(hs_sl_samples,
                                           column = "hisatobservedgeneshg38111")
## Error in geom_jitter(height = 0, width = 0.1): could not find function "geom_jitter"
hs_sl_hisat_genes
## Error in eval(expr, envir, enclos): object 'hs_sl_hisat_genes' not found

7 SL nonzero/libsize/etc

plot_libsize(lp_sl_samples)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'data' in selecting a method for function 'plot_libsize': object 'lp_sl_samples' not found
plot_libsize(hs_sl_samples)
## Library sizes of 13 samples, 
## ranging from 2,442,896 to 7,848,190.

plot_nonzero(lp_sl_samples)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'data' in selecting a method for function 'plot_nonzero': object 'lp_sl_samples' not found
plot_nonzero(hs_sl_samples)
## The following samples have less than 14012.05 genes.
## [1] "PRSL0001" "PRSL0002" "PRSL0003" "PRSL0004" "PRSL0005" "PRSL0006" "PRSL0007" "PRSL0008"
## Scale for colour is already present.
## Adding another scale for colour, which will replace the existing scale.
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.
## A non-zero genes plot of 13 samples.
## These samples have an average 4.26 CPM coverage and 11943 genes observed, ranging from 7260 to
## 16565.

post_filter <- plot_libsize_prepost(lp_sl_samples)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'data' in selecting a method for function 'plot_libsize': object 'lp_sl_samples' not found
post_filter[["lowgene_plot"]]
## Error in eval(expr, envir, enclos): object 'post_filter' not found

8 Distribution/PCA

lp_sl_norm <- normalize_expt(lp_sl_samples, transform = "log2", convert = "cpm",
                             norm = "tmm", filter = TRUE)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'lp_sl_samples' not found
plot_pca(lp_sl_norm)
## Error in eval(expr, envir, enclos): object 'lp_sl_norm' not found
plot_disheat(lp_sl_norm)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt_data' in selecting a method for function 'plot_heatmap': object 'lp_sl_norm' not found
plot_corheat(lp_sl_norm)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt_data' in selecting a method for function 'plot_heatmap': object 'lp_sl_norm' not found

9 SL metadata homo sapiens

hs_sl_hisat_mapped <- plot_metadata_factors(hs_sl_samples,
                                            column = "hisatgenomesingleconcordanthg38111")
## Error in geom_jitter(height = 0, width = 0.1): could not find function "geom_jitter"
hs_sl_hisat_mapped
## Error in eval(expr, envir, enclos): object 'hs_sl_hisat_mapped' not found
hs_sl_hisat_genes <- plot_metadata_factors(hs_sl_samples,
                                           column = "hisatobservedgeneshg38111")
## Error in geom_jitter(height = 0, width = 0.1): could not find function "geom_jitter"
hs_sl_hisat_genes
## Error in eval(expr, envir, enclos): object 'hs_sl_hisat_genes' not found

10 SL nonzero/libsize/etc

plot_libsize(hs_sl_samples)
## Library sizes of 13 samples, 
## ranging from 2,442,896 to 7,848,190.

plot_nonzero(hs_sl_samples)
## The following samples have less than 14012.05 genes.
## [1] "PRSL0001" "PRSL0002" "PRSL0003" "PRSL0004" "PRSL0005" "PRSL0006" "PRSL0007" "PRSL0008"
## Scale for colour is already present.
## Adding another scale for colour, which will replace the existing scale.
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.
## A non-zero genes plot of 13 samples.
## These samples have an average 4.26 CPM coverage and 11943 genes observed, ranging from 7260 to
## 16565.

LS0tCnRpdGxlOiAiRXhhbWluaW5nIGZpcnN0IHJvdW5kIG9mIHNhbXBsZXMgcmVjZWl2ZWQgMjAyNDA1LiIKYXV0aG9yOiAiYXRiIGFiZWxld0BnbWFpbC5jb20iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGZpZ19jYXB0aW9uOiB0cnVlCiAgICBmaWdfaGVpZ2h0OiA3CiAgICBmaWdfd2lkdGg6IDcKICAgIGhpZ2hsaWdodDogemVuYnVybgogICAga2VlcF9tZDogZmFsc2UKICAgIG1vZGU6IHNlbGZjb250YWluZWQKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgc2VsZl9jb250YWluZWQ6IHRydWUKICAgIHRoZW1lOiByZWFkYWJsZQogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogZmFsc2UKICAgICAgc21vb3RoX3Njcm9sbDogZmFsc2UKICBybWRmb3JtYXRzOjpyZWFkdGhlZG93bjoKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgZmlnX2hlaWdodDogNwogICAgZmlnX3dpZHRoOiA3CiAgICBoaWdobGlnaHQ6IHplbmJ1cm4KICAgIHdpZHRoOiAzMDAKICAgIGtlZXBfbWQ6IGZhbHNlCiAgICBtb2RlOiBzZWxmY29udGFpbmVkCiAgICB0b2NfZmxvYXQ6IHRydWUKICBCaW9jU3R5bGU6Omh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGZpZ19jYXB0aW9uOiB0cnVlCiAgICBmaWdfaGVpZ2h0OiA3CiAgICBmaWdfd2lkdGg6IDcKICAgIGhpZ2hsaWdodDogemVuYnVybgogICAga2VlcF9tZDogZmFsc2UKICAgIG1vZGU6IHNlbGZjb250YWluZWQKICAgIHRvY19mbG9hdDogdHJ1ZQotLS0KCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+CmJvZHksIHRkIHsKICBmb250LXNpemU6IDE2cHg7Cn0KY29kZS5yewogIGZvbnQtc2l6ZTogMTZweDsKfQpwcmUgewogIGZvbnQtc2l6ZTogMTZweAp9CmJvZHkgLm1haW4tY29udGFpbmVyIHsKICBtYXgtd2lkdGg6IDE2MDBweDsKfQo8L3N0eWxlPgoKYGBge3Igb3B0aW9ucywgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShocGdsdG9vbHMpCmxpYnJhcnkocmV0aWN1bGF0ZSkKdHQgPC0gdHJ5KGRldnRvb2xzOjpsb2FkX2FsbCgifi9ocGdsdG9vbHMiKSkKa25pdHI6Om9wdHNfa25pdCRzZXQoCiAgcHJvZ3Jlc3MgPSBUUlVFLCB2ZXJib3NlID0gVFJVRSwgd2lkdGggPSA5MCwgZWNobyA9IFRSVUUpCmtuaXRyOjpvcHRzX2NodW5rJHNldCgKICBlcnJvciA9IFRSVUUsIGZpZy53aWR0aCA9IDgsIGZpZy5oZWlnaHQgPSA4LCBmaWcucmV0aW5hID0gMiwKICBvdXQud2lkdGggPSAiMTAwJSIsIGRldiA9ICJwbmciLAogIGRldi5hcmdzID0gbGlzdChwbmcgPSBsaXN0KHR5cGUgPSAiY2Fpcm8tcG5nIikpKQpvbGRfb3B0aW9ucyA8LSBvcHRpb25zKGRpZ2l0cyA9IDQsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSwga25pdHIuZHVwbGljYXRlLmxhYmVsID0gImFsbG93IikKZ2dwbG90Mjo6dGhlbWVfc2V0KGdncGxvdDI6OnRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDEyKSkKdmVyIDwtICIyMDI0MDUiCnByZXZpb3VzX2ZpbGUgPC0gIiIKdmVyIDwtIGZvcm1hdChTeXMuRGF0ZSgpLCAiJVklbSVkIikKCiMjdG1wIDwtIHNtKGxvYWRtZShmaWxlbmFtZT1wYXN0ZTAoZ3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSIiLCB4PXByZXZpb3VzX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikpKQpybWRfZmlsZSA8LSAicGVyc2lzdF9zYW1wbGVzXzIwMjQwNS5SbWQiCmBgYAoKIyBJbnRyb2R1Y3Rpb24KCkkgd2FudCB0byB1c2UgdGhpcyBkb2N1bWVudCB0byBleGFtaW5lIG91ciBmaXJzdCByb3VuZCBvZiBwZXJzaXN0ZW5jZQpzYW1wbGVzLiAgSSBjaGVja2VkIG15IGVtYWlsIGZyb20gTmFqaWIgYW5kIGRpZCBub3QgZmluZCBhIHNhbXBsZQpzaGVldCBidXQgZGlkIGZpbmQgYW4gZXhwbGFuYXRpb24gb2YgdGhlIHRocmVlIHNhbXBsZSB0eXBlcyB3ZSBleHBlY3QuCgpJbiBwcmVwYXJhdGlvbiBmb3IgdGhpcywgSSBkb3dubG9hZGVkIGEgbmV3IGhnMzggZ2Vub21lLiAgU2luY2UgdGhlCnBhbmFtZW5zaXMgYXNlbWJseSBoYXMgbm90IHNpZ25pZmljYW50bHkgY2hhbmdlZCAoZXhjZXB0aW5nIHRoZQpwdXRhdGl2ZSBsb25nIHJlYWQgZ2Vub21lIHdoaWNoIEkgaGF2ZSBub3QgeWV0IHNlZW4pLCBJIGFtIGp1c3QgdXNpbmcKdGhlIHNhbWUgb25lLgoKIyBMb2FkaW5nIGFubm90YXRpb24KClRoZSBoZzM4IGdlbm9tZSBJIGdvdCBpcyBicmFuZCBuZXcgKDIwMjQwNSksIHNvIGRvIG5vdCB1c2UgdGhlIGFyY2hpdmUKZm9yIGEgd2hpbGUuCgpgYGB7cn0KIyMgT2ssIHNvIHVzZWFzdC5lbnNlbWJsIGlzIGZhaWxpbmcgdG9kYXksIGxldCB1cyB1c2UgdGhlIGphbjIwMjQgYXJjaGl2ZT8KI2hzX2Fubm90IDwtIGxvYWRfYmlvbWFydF9hbm5vdGF0aW9ucyhhcmNoaXZlID0gRkFMU0UsIHNwZWNpZXMgPSAiaHNhcGllbnMiKQojIyBTZWVtcyBsaWtlIHRoZSAyMDI0MDEgYXJjaGl2ZSBpcyBhIGdvb2QgY2hvaWNlLCBpdCBpcyBleHBsaWNpdGx5IHRoZSBoZzM4XzExMSByZWxlYXNlLgojIyBhbmQgaXQgaXMgd2FhYWFheSBmYXN0ZXIgKGxpa2UgMTAweCkgdGhhbiB1c2Vhc3QgcmlnaHQgbm93Lgpoc19hbm5vdCA8LSBsb2FkX2Jpb21hcnRfYW5ub3RhdGlvbnMoYXJjaGl2ZSA9IFRSVUUsIHNwZWNpZXMgPSAiaHNhcGllbnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVhciA9IDIwMjQsIG1vbnRoID0gIjAxIikKCnBhbmFtZW5zaXNfb3JnZGJfaWR4IDwtIGdyZXAocGF0dGVybiA9ICJeb3JnLitwYW5hbWVuLitNSE9NLitkYiQiLCB4ID0gcm93bmFtZXMoaW5zdGFsbGVkLnBhY2thZ2VzKCkpKQpwYW5hbWVuc2lzX29yZ2RiIDwtIHRhaWwocm93bmFtZXMoaW5zdGFsbGVkLnBhY2thZ2VzKCkpW3BhbmFtZW5zaXNfb3JnZGJfaWR4XSwgbiA9IDEpCmxwX2Fubm90IDwtIGxvYWRfb3JnZGJfYW5ub3RhdGlvbnMocGFuYW1lbnNpc19vcmdkYiwga2V5dHlwZSA9ICJnaWQiKQpgYGAKClRoaXMgaXMgYSBsaXR0bGUgc2lsbHksIGJ1dCBJIGFtIGdvaW5nIHRvIHJlbG9hZCB0aGUgYW5ub3RhdGlvbnMgdXNpbmcKdGhlIHByZXZpb3VzIGludm9jYXRpb24gdG8gZXh0cmFjdCB0aGUgYW5ub3RhdGlvbiB0YWJsZSB3aXRob3V0IGhhdmluZwp0byB0aGluay4gIFRoZSBwcmV2aW91cyBibG9jayBsb2FkcyB0aGUgb3JnZGIgZm9yIG1lLCBzbyBJIGNhbiBqdXN0CnVzZSB0aGF0IHRvIGdldCB0aGUgZnVuIGFubm90YXRpb25zLgoKYGBge3J9CmFsbF9jb2x1bW5zIDwtIGtleXR5cGVzKGdldDAocGFuYW1lbnNpc19vcmdkYikpCmFubm90X2lkeCA8LSBncmVwKHBhdHRlcm4gPSAiXkFOTk9UXyIsIHggPSBhbGxfY29sdW1ucykKYW5ub3RfY29sdW1ucyA8LSBhbGxfY29sdW1uc1thbm5vdF9pZHhdCmxwX2Fubm90IDwtIGxvYWRfb3JnZGJfYW5ub3RhdGlvbnMocGFuYW1lbnNpc19vcmdkYiwga2V5dHlwZSA9ICJnaWQiLCBmaWVsZHMgPSBhbm5vdF9jb2x1bW5zKQpgYGAKCiMgQ29sbGVjdCBwcmVwcm9jZXNzZWQgbWV0YWRhdGEKCmBgYHtyfQpmaXJzdF9zcGVjIDwtIG1ha2Vfcm5hc2VxX3NwZWMoKQoKcHJlX21ldGEgPC0gZ2F0aGVyX3ByZXByb2Nlc3NpbmdfbWV0YWRhdGEoCiAgc3RhcnRpbmdfbWV0YWRhdGEgPSAic2FtcGxlX3NoZWV0cy90bXJjX3BlcnNpc3RlbmNlXzIwMjQwNS54bHN4IiwKICBzcGVjaWZpY2F0aW9uID0gZmlyc3Rfc3BlYywKICBiYXNlZGlyID0gInByZXByb2Nlc3NpbmcvMjAyNDA1Iiwgc3BlY2llcz0ibHBhbmFtZW5zaXNfdjY4IiwKICBuZXdfbWV0YWRhdGEgPSAic2FtcGxlX3NoZWV0cy90bXJjX3BlcnNpc3RlbmNlXzIwMjQwNV9scGFuYW1lbnNpcy54bHN4IikKaGlzYXRfaWR4IDwtIGdyZXAocGF0dGVybiA9ICJeaGlzYXQiLCB4ID0gbmFtZXMoZmlyc3Rfc3BlYykpCnNlY29uZF9zcGVjIDwtIGZpcnN0X3NwZWNbaGlzYXRfaWR4XQpwb3N0X21ldGEgPC0gZ2F0aGVyX3ByZXByb2Nlc3NpbmdfbWV0YWRhdGEoCiAgc3RhcnRpbmdfbWV0YWRhdGEgPSBwcmVfbWV0YVtbIm5ld19tZXRhIl1dLAogIHNwZWNpZmljYXRpb24gPSBzZWNvbmRfc3BlYywgYmFzZWRpciA9ICJwcmVwcm9jZXNzaW5nLzIwMjQwNSIsIHNwZWNpZXMgPSAiaGczOF8xMTEiLAogIG5ld19tZXRhZGF0YSA9ICJzYW1wbGVfc2hlZXRzL3RtcmMyX3BlcnNpc3RlbmNlXzIwMjQwNV9scF9oZy54bHN4IikKCmJvdGhfbWV0YSA8LSBnYXRoZXJfcHJlcHJvY2Vzc2luZ19tZXRhZGF0YSgKICBzdGFydGluZ19tZXRhZGF0YSA9ICJzYW1wbGVfc2hlZXRzL3RtcmNfcGVyc2lzdGVuY2VfMjAyNDA1Lnhsc3giLAogIHNwZWNpZmljYXRpb24gPSBmaXJzdF9zcGVjLAogIGJhc2VkaXIgPSAicHJlcHJvY2Vzc2luZy8yMDI0MDUiLCBzcGVjaWVzPSBjKCJscGFuYW1lbnNpc192NjgiLCAiaGczOF8xMTEiKSwKICBuZXdfbWV0YWRhdGEgPSAic2FtcGxlX3NoZWV0cy90bXJjX3BlcnNpc3RlbmNlXzIwMjQwNV9ib3RoLnhsc3giKQpgYGAKCiMgQ29sbGVjdCBnZW5lIGFubm90YXRpb25zCgpJIHNob3VsZCBoYXZlIGFsbCBteSBsb2FkX3h5el9hbm5vdGF0aW9uIGZ1bmN0aW9ucyByZXR1cm4gc29tZSBvZiB0aGUKc2FtZSBlbGVtZW50cyBpbiB0aGVpciByZXRsaXN0cy4KCmBgYHtyfQpscF9nZW5lcyA8LSBscF9hbm5vdFtbImdlbmVzIl1dCmhnX2dlbmVzIDwtIGhzX2Fubm90W1siZ2VuZV9hbm5vdGF0aW9ucyJdXQpgYGAKCiMgUXVpY2sgcGVlayBhdCB0aGUgU0wgc2FtcGxlcywgaGczOCByZWxlYXNlIDExMQoKYGBge3J9CmhzX2FsbF9zYW1wbGVzIDwtIGNyZWF0ZV9leHB0KCJzYW1wbGVfc2hlZXRzL3RtcmNfcGVyc2lzdGVuY2VfMjAyNDA1X2JvdGgueGxzeCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVfaW5mbyA9IGhnX2dlbmVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlX2NvbHVtbiA9ICJoaXNhdGNvdW50dGFibGVoZzM4MTExIikKCnNsX2lkeCA8LSBwRGF0YShoc19hbGxfc2FtcGxlcylbWyJzYW1wbGV0eXBlIl1dID09ICJTTCIKaHNfc2xfc2FtcGxlcyA8LSBoc19hbGxfc2FtcGxlc1ssIHNsX2lkeF0KCmh1X2lkeCA8LSBwRGF0YShoc19hbGxfc2FtcGxlcylbWyJzYW1wbGV0eXBlIl1dID09ICJIVSIKaHNfaHVfc2FtcGxlcyA8LSBoc19hbGxfc2FtcGxlc1ssIGh1X2lkeF0KYGBgCgoKIyBTTCBtZXRhZGF0YQoKYGBge3J9CmxwX2FsbF9oaXNhdF9tYXBwZWQgPC0gcGxvdF9tZXRhZGF0YV9mYWN0b3JzKGxwX2FsbF9zYW1wbGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW4gPSAiaGlzYXRnZW5vbWVzaW5nbGVjb25jb3JkYW50bHBhbmFtZW5zaXN2NjgiKQpscF9hbGxfaGlzYXRfbWFwcGVkCmhzX2FsbF9oaXNhdF9tYXBwZWQgPC0gcGxvdF9tZXRhZGF0YV9mYWN0b3JzKGhzX2FsbF9zYW1wbGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbiA9ICJoaXNhdGdlbm9tZXNpbmdsZWNvbmNvcmRhbnRoZzM4MTExIikKaHNfYWxsX2hpc2F0X21hcHBlZAoKbHBfc2xfaGlzYXRfZ2VuZXMgPC0gcGxvdF9tZXRhZGF0YV9mYWN0b3JzKGxwX3NsX3NhbXBsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW4gPSAiaGlzYXRvYnNlcnZlZGdlbmVzbHBhbmFtZW5zaXN2NjgiKQpscF9zbF9oaXNhdF9nZW5lcwoKaHNfc2xfaGlzYXRfZ2VuZXMgPC0gcGxvdF9tZXRhZGF0YV9mYWN0b3JzKGhzX3NsX3NhbXBsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW4gPSAiaGlzYXRvYnNlcnZlZGdlbmVzaGczODExMSIpCmhzX3NsX2hpc2F0X2dlbmVzCmBgYAoKIyBTTCBub256ZXJvL2xpYnNpemUvZXRjCgpgYGB7cn0KcGxvdF9saWJzaXplKGxwX3NsX3NhbXBsZXMpCnBsb3RfbGlic2l6ZShoc19zbF9zYW1wbGVzKQoKcGxvdF9ub256ZXJvKGxwX3NsX3NhbXBsZXMpCnBsb3Rfbm9uemVybyhoc19zbF9zYW1wbGVzKQoKcG9zdF9maWx0ZXIgPC0gcGxvdF9saWJzaXplX3ByZXBvc3QobHBfc2xfc2FtcGxlcykKcG9zdF9maWx0ZXJbWyJsb3dnZW5lX3Bsb3QiXV0KYGBgCgojIERpc3RyaWJ1dGlvbi9QQ0EKCmBgYHtyfQpscF9zbF9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KGxwX3NsX3NhbXBsZXMsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm0gPSAidG1tIiwgZmlsdGVyID0gVFJVRSkKcGxvdF9wY2EobHBfc2xfbm9ybSkKcGxvdF9kaXNoZWF0KGxwX3NsX25vcm0pCnBsb3RfY29yaGVhdChscF9zbF9ub3JtKQpgYGAKCiMgU0wgbWV0YWRhdGEgaG9tbyBzYXBpZW5zCgpgYGB7cn0KaHNfc2xfaGlzYXRfbWFwcGVkIDwtIHBsb3RfbWV0YWRhdGFfZmFjdG9ycyhoc19zbF9zYW1wbGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbiA9ICJoaXNhdGdlbm9tZXNpbmdsZWNvbmNvcmRhbnRoZzM4MTExIikKaHNfc2xfaGlzYXRfbWFwcGVkCgpoc19zbF9oaXNhdF9nZW5lcyA8LSBwbG90X21ldGFkYXRhX2ZhY3RvcnMoaHNfc2xfc2FtcGxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbiA9ICJoaXNhdG9ic2VydmVkZ2VuZXNoZzM4MTExIikKaHNfc2xfaGlzYXRfZ2VuZXMKYGBgCgojIFNMIG5vbnplcm8vbGlic2l6ZS9ldGMKCmBgYHtyfQpwbG90X2xpYnNpemUoaHNfc2xfc2FtcGxlcykKCnBsb3Rfbm9uemVybyhoc19zbF9zYW1wbGVzKQpgYGAK