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")
hs_all_hisat_mapped

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")
hs_sl_hisat_genes

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")
hs_sl_hisat_mapped

hs_sl_hisat_genes <- plot_metadata_factors(hs_sl_samples,
                                           column = "hisatobservedgeneshg38111")
hs_sl_hisat_genes

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+CmJvZHksIHRkIHsKICBmb250LXNpemU6IDE2cHg7Cn0KY29kZS5yewogIGZvbnQtc2l6ZTogMTZweDsKfQpwcmUgewogIGZvbnQtc2l6ZTogMTZweAp9CmJvZHkgLm1haW4tY29udGFpbmVyIHsKICBtYXgtd2lkdGg6IDE2MDBweDsKfQo8L3N0eWxlPgoKYGBge3Igb3B0aW9ucywgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGhwZ2x0b29scykKbGlicmFyeShyZXRpY3VsYXRlKQp0dCA8LSB0cnkoZGV2dG9vbHM6OmxvYWRfYWxsKCJ+L2hwZ2x0b29scyIpKQprbml0cjo6b3B0c19rbml0JHNldCgKICBwcm9ncmVzcyA9IFRSVUUsIHZlcmJvc2UgPSBUUlVFLCB3aWR0aCA9IDkwLCBlY2hvID0gVFJVRSkKa25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVycm9yID0gVFJVRSwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDgsIGZpZy5yZXRpbmEgPSAyLAogIG91dC53aWR0aCA9ICIxMDAlIiwgZGV2ID0gInBuZyIsCiAgZGV2LmFyZ3MgPSBsaXN0KHBuZyA9IGxpc3QodHlwZSA9ICJjYWlyby1wbmciKSkpCm9sZF9vcHRpb25zIDwtIG9wdGlvbnMoZGlnaXRzID0gNCwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFLCBrbml0ci5kdXBsaWNhdGUubGFiZWwgPSAiYWxsb3ciKQpnZ3Bsb3QyOjp0aGVtZV9zZXQoZ2dwbG90Mjo6dGhlbWVfYncoYmFzZV9zaXplID0gMTIpKQp2ZXIgPC0gIjIwMjQwNSIKcHJldmlvdXNfZmlsZSA8LSAiIgp2ZXIgPC0gZm9ybWF0KFN5cy5EYXRlKCksICIlWSVtJWQiKQoKIyN0bXAgPC0gc20obG9hZG1lKGZpbGVuYW1lPXBhc3RlMChnc3ViKHBhdHRlcm49IlxcLlJtZCIsIHJlcGxhY2U9IiIsIHg9cHJldmlvdXNfZmlsZSksICItdiIsIHZlciwgIi5yZGEueHoiKSkpCnJtZF9maWxlIDwtICJwZXJzaXN0X3NhbXBsZXNfMjAyNDA1LlJtZCIKYGBgCgojIEludHJvZHVjdGlvbgoKSSB3YW50IHRvIHVzZSB0aGlzIGRvY3VtZW50IHRvIGV4YW1pbmUgb3VyIGZpcnN0IHJvdW5kIG9mIHBlcnNpc3RlbmNlCnNhbXBsZXMuICBJIGNoZWNrZWQgbXkgZW1haWwgZnJvbSBOYWppYiBhbmQgZGlkIG5vdCBmaW5kIGEgc2FtcGxlCnNoZWV0IGJ1dCBkaWQgZmluZCBhbiBleHBsYW5hdGlvbiBvZiB0aGUgdGhyZWUgc2FtcGxlIHR5cGVzIHdlIGV4cGVjdC4KCkluIHByZXBhcmF0aW9uIGZvciB0aGlzLCBJIGRvd25sb2FkZWQgYSBuZXcgaGczOCBnZW5vbWUuICBTaW5jZSB0aGUKcGFuYW1lbnNpcyBhc2VtYmx5IGhhcyBub3Qgc2lnbmlmaWNhbnRseSBjaGFuZ2VkIChleGNlcHRpbmcgdGhlCnB1dGF0aXZlIGxvbmcgcmVhZCBnZW5vbWUgd2hpY2ggSSBoYXZlIG5vdCB5ZXQgc2VlbiksIEkgYW0ganVzdCB1c2luZwp0aGUgc2FtZSBvbmUuCgojIExvYWRpbmcgYW5ub3RhdGlvbgoKVGhlIGhnMzggZ2Vub21lIEkgZ290IGlzIGJyYW5kIG5ldyAoMjAyNDA1KSwgc28gZG8gbm90IHVzZSB0aGUgYXJjaGl2ZQpmb3IgYSB3aGlsZS4KCmBgYHtyfQojIyBPaywgc28gdXNlYXN0LmVuc2VtYmwgaXMgZmFpbGluZyB0b2RheSwgbGV0IHVzIHVzZSB0aGUgamFuMjAyNCBhcmNoaXZlPwojaHNfYW5ub3QgPC0gbG9hZF9iaW9tYXJ0X2Fubm90YXRpb25zKGFyY2hpdmUgPSBGQUxTRSwgc3BlY2llcyA9ICJoc2FwaWVucyIpCiMjIFNlZW1zIGxpa2UgdGhlIDIwMjQwMSBhcmNoaXZlIGlzIGEgZ29vZCBjaG9pY2UsIGl0IGlzIGV4cGxpY2l0bHkgdGhlIGhnMzhfMTExIHJlbGVhc2UuCiMjIGFuZCBpdCBpcyB3YWFhYWF5IGZhc3RlciAobGlrZSAxMDB4KSB0aGFuIHVzZWFzdCByaWdodCBub3cuCmhzX2Fubm90IDwtIGxvYWRfYmlvbWFydF9hbm5vdGF0aW9ucyhhcmNoaXZlID0gVFJVRSwgc3BlY2llcyA9ICJoc2FwaWVucyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFyID0gMjAyNCwgbW9udGggPSAiMDEiKQoKcGFuYW1lbnNpc19vcmdkYl9pZHggPC0gZ3JlcChwYXR0ZXJuID0gIl5vcmcuK3BhbmFtZW4uK01IT00uK2RiJCIsIHggPSByb3duYW1lcyhpbnN0YWxsZWQucGFja2FnZXMoKSkpCnBhbmFtZW5zaXNfb3JnZGIgPC0gdGFpbChyb3duYW1lcyhpbnN0YWxsZWQucGFja2FnZXMoKSlbcGFuYW1lbnNpc19vcmdkYl9pZHhdLCBuID0gMSkKbHBfYW5ub3QgPC0gbG9hZF9vcmdkYl9hbm5vdGF0aW9ucyhwYW5hbWVuc2lzX29yZ2RiLCBrZXl0eXBlID0gImdpZCIpCmBgYAoKVGhpcyBpcyBhIGxpdHRsZSBzaWxseSwgYnV0IEkgYW0gZ29pbmcgdG8gcmVsb2FkIHRoZSBhbm5vdGF0aW9ucyB1c2luZwp0aGUgcHJldmlvdXMgaW52b2NhdGlvbiB0byBleHRyYWN0IHRoZSBhbm5vdGF0aW9uIHRhYmxlIHdpdGhvdXQgaGF2aW5nCnRvIHRoaW5rLiAgVGhlIHByZXZpb3VzIGJsb2NrIGxvYWRzIHRoZSBvcmdkYiBmb3IgbWUsIHNvIEkgY2FuIGp1c3QKdXNlIHRoYXQgdG8gZ2V0IHRoZSBmdW4gYW5ub3RhdGlvbnMuCgpgYGB7cn0KYWxsX2NvbHVtbnMgPC0ga2V5dHlwZXMoZ2V0MChwYW5hbWVuc2lzX29yZ2RiKSkKYW5ub3RfaWR4IDwtIGdyZXAocGF0dGVybiA9ICJeQU5OT1RfIiwgeCA9IGFsbF9jb2x1bW5zKQphbm5vdF9jb2x1bW5zIDwtIGFsbF9jb2x1bW5zW2Fubm90X2lkeF0KbHBfYW5ub3QgPC0gbG9hZF9vcmdkYl9hbm5vdGF0aW9ucyhwYW5hbWVuc2lzX29yZ2RiLCBrZXl0eXBlID0gImdpZCIsIGZpZWxkcyA9IGFubm90X2NvbHVtbnMpCmBgYAoKIyBDb2xsZWN0IHByZXByb2Nlc3NlZCBtZXRhZGF0YQoKYGBge3J9CmZpcnN0X3NwZWMgPC0gbWFrZV9ybmFzZXFfc3BlYygpCgpwcmVfbWV0YSA8LSBnYXRoZXJfcHJlcHJvY2Vzc2luZ19tZXRhZGF0YSgKICBzdGFydGluZ19tZXRhZGF0YSA9ICJzYW1wbGVfc2hlZXRzL3RtcmNfcGVyc2lzdGVuY2VfMjAyNDA1Lnhsc3giLAogIHNwZWNpZmljYXRpb24gPSBmaXJzdF9zcGVjLAogIGJhc2VkaXIgPSAicHJlcHJvY2Vzc2luZy8yMDI0MDUiLCBzcGVjaWVzPSJscGFuYW1lbnNpc192NjgiLAogIG5ld19tZXRhZGF0YSA9ICJzYW1wbGVfc2hlZXRzL3RtcmNfcGVyc2lzdGVuY2VfMjAyNDA1X2xwYW5hbWVuc2lzLnhsc3giKQpoaXNhdF9pZHggPC0gZ3JlcChwYXR0ZXJuID0gIl5oaXNhdCIsIHggPSBuYW1lcyhmaXJzdF9zcGVjKSkKc2Vjb25kX3NwZWMgPC0gZmlyc3Rfc3BlY1toaXNhdF9pZHhdCnBvc3RfbWV0YSA8LSBnYXRoZXJfcHJlcHJvY2Vzc2luZ19tZXRhZGF0YSgKICBzdGFydGluZ19tZXRhZGF0YSA9IHByZV9tZXRhW1sibmV3X21ldGEiXV0sCiAgc3BlY2lmaWNhdGlvbiA9IHNlY29uZF9zcGVjLCBiYXNlZGlyID0gInByZXByb2Nlc3NpbmcvMjAyNDA1Iiwgc3BlY2llcyA9ICJoZzM4XzExMSIsCiAgbmV3X21ldGFkYXRhID0gInNhbXBsZV9zaGVldHMvdG1yYzJfcGVyc2lzdGVuY2VfMjAyNDA1X2xwX2hnLnhsc3giKQoKYm90aF9tZXRhIDwtIGdhdGhlcl9wcmVwcm9jZXNzaW5nX21ldGFkYXRhKAogIHN0YXJ0aW5nX21ldGFkYXRhID0gInNhbXBsZV9zaGVldHMvdG1yY19wZXJzaXN0ZW5jZV8yMDI0MDUueGxzeCIsCiAgc3BlY2lmaWNhdGlvbiA9IGZpcnN0X3NwZWMsCiAgYmFzZWRpciA9ICJwcmVwcm9jZXNzaW5nLzIwMjQwNSIsIHNwZWNpZXM9IGMoImxwYW5hbWVuc2lzX3Y2OCIsICJoZzM4XzExMSIpLAogIG5ld19tZXRhZGF0YSA9ICJzYW1wbGVfc2hlZXRzL3RtcmNfcGVyc2lzdGVuY2VfMjAyNDA1X2JvdGgueGxzeCIpCmBgYAoKIyBDb2xsZWN0IGdlbmUgYW5ub3RhdGlvbnMKCkkgc2hvdWxkIGhhdmUgYWxsIG15IGxvYWRfeHl6X2Fubm90YXRpb24gZnVuY3Rpb25zIHJldHVybiBzb21lIG9mIHRoZQpzYW1lIGVsZW1lbnRzIGluIHRoZWlyIHJldGxpc3RzLgoKYGBge3J9CmxwX2dlbmVzIDwtIGxwX2Fubm90W1siZ2VuZXMiXV0KaGdfZ2VuZXMgPC0gaHNfYW5ub3RbWyJnZW5lX2Fubm90YXRpb25zIl1dCmBgYAoKIyBRdWljayBwZWVrIGF0IHRoZSBTTCBzYW1wbGVzLCBoZzM4IHJlbGVhc2UgMTExCgpgYGB7cn0KaHNfYWxsX3NhbXBsZXMgPC0gY3JlYXRlX2V4cHQoInNhbXBsZV9zaGVldHMvdG1yY19wZXJzaXN0ZW5jZV8yMDI0MDVfYm90aC54bHN4IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuZV9pbmZvID0gaGdfZ2VuZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVfY29sdW1uID0gImhpc2F0Y291bnR0YWJsZWhnMzgxMTEiKQoKc2xfaWR4IDwtIHBEYXRhKGhzX2FsbF9zYW1wbGVzKVtbInNhbXBsZXR5cGUiXV0gPT0gIlNMIgpoc19zbF9zYW1wbGVzIDwtIGhzX2FsbF9zYW1wbGVzWywgc2xfaWR4XQoKaHVfaWR4IDwtIHBEYXRhKGhzX2FsbF9zYW1wbGVzKVtbInNhbXBsZXR5cGUiXV0gPT0gIkhVIgpoc19odV9zYW1wbGVzIDwtIGhzX2FsbF9zYW1wbGVzWywgaHVfaWR4XQpgYGAKCgojIFNMIG1ldGFkYXRhCgpgYGB7cn0KbHBfYWxsX2hpc2F0X21hcHBlZCA8LSBwbG90X21ldGFkYXRhX2ZhY3RvcnMobHBfYWxsX3NhbXBsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbiA9ICJoaXNhdGdlbm9tZXNpbmdsZWNvbmNvcmRhbnRscGFuYW1lbnNpc3Y2OCIpCmxwX2FsbF9oaXNhdF9tYXBwZWQKaHNfYWxsX2hpc2F0X21hcHBlZCA8LSBwbG90X21ldGFkYXRhX2ZhY3RvcnMoaHNfYWxsX3NhbXBsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uID0gImhpc2F0Z2Vub21lc2luZ2xlY29uY29yZGFudGhnMzgxMTEiKQpoc19hbGxfaGlzYXRfbWFwcGVkCgpscF9zbF9oaXNhdF9nZW5lcyA8LSBwbG90X21ldGFkYXRhX2ZhY3RvcnMobHBfc2xfc2FtcGxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbiA9ICJoaXNhdG9ic2VydmVkZ2VuZXNscGFuYW1lbnNpc3Y2OCIpCmxwX3NsX2hpc2F0X2dlbmVzCgpoc19zbF9oaXNhdF9nZW5lcyA8LSBwbG90X21ldGFkYXRhX2ZhY3RvcnMoaHNfc2xfc2FtcGxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbiA9ICJoaXNhdG9ic2VydmVkZ2VuZXNoZzM4MTExIikKaHNfc2xfaGlzYXRfZ2VuZXMKYGBgCgojIFNMIG5vbnplcm8vbGlic2l6ZS9ldGMKCmBgYHtyfQpwbG90X2xpYnNpemUobHBfc2xfc2FtcGxlcykKcGxvdF9saWJzaXplKGhzX3NsX3NhbXBsZXMpCgpwbG90X25vbnplcm8obHBfc2xfc2FtcGxlcykKcGxvdF9ub256ZXJvKGhzX3NsX3NhbXBsZXMpCgpwb3N0X2ZpbHRlciA8LSBwbG90X2xpYnNpemVfcHJlcG9zdChscF9zbF9zYW1wbGVzKQpwb3N0X2ZpbHRlcltbImxvd2dlbmVfcGxvdCJdXQpgYGAKCiMgRGlzdHJpYnV0aW9uL1BDQQoKYGBge3J9CmxwX3NsX25vcm0gPC0gbm9ybWFsaXplX2V4cHQobHBfc2xfc2FtcGxlcywgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9ybSA9ICJ0bW0iLCBmaWx0ZXIgPSBUUlVFKQpwbG90X3BjYShscF9zbF9ub3JtKQpwbG90X2Rpc2hlYXQobHBfc2xfbm9ybSkKcGxvdF9jb3JoZWF0KGxwX3NsX25vcm0pCmBgYAoKIyBTTCBtZXRhZGF0YSBob21vIHNhcGllbnMKCmBgYHtyfQpoc19zbF9oaXNhdF9tYXBwZWQgPC0gcGxvdF9tZXRhZGF0YV9mYWN0b3JzKGhzX3NsX3NhbXBsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uID0gImhpc2F0Z2Vub21lc2luZ2xlY29uY29yZGFudGhnMzgxMTEiKQpoc19zbF9oaXNhdF9tYXBwZWQKCmhzX3NsX2hpc2F0X2dlbmVzIDwtIHBsb3RfbWV0YWRhdGFfZmFjdG9ycyhoc19zbF9zYW1wbGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uID0gImhpc2F0b2JzZXJ2ZWRnZW5lc2hnMzgxMTEiKQpoc19zbF9oaXNhdF9nZW5lcwpgYGAKCiMgU0wgbm9uemVyby9saWJzaXplL2V0YwoKYGBge3J9CnBsb3RfbGlic2l6ZShoc19zbF9zYW1wbGVzKQoKcGxvdF9ub256ZXJvKGhzX3NsX3NhbXBsZXMpCmBgYAo=