## Modified version of mapscape. Cannot be put into the same package as some
## of the components conflict
library(xcrmapscape)
library(htmlwidgets)

library(ithi.utils)
load_base_libs()
library(ithi.meta)
library(ithi.ihc)
library(ithi.xcr)
library(ithi.figures)

Parameters

db_path <- snakemake@params$db

mapscape_input_directories = snakemake@input$mapscape_inputs
xcr_table_path <- snakemake@input$xcr_table
show_full_track <- (snakemake@params$track_option == "full")
db <- src_sqlite(db_path, create = FALSE)
andrew_map <- collect(tbl(db, "andrew_map"))
plot_xcrmapscape <- function(clonal_prev, sample_locations, tree_edges, chord_data, 
    track_data, resize_factor) {
    img_ref = "/shahlab/alzhang/projects/ITH_Immune/paper/miscellaneous/FF4D00-0.8.png"
    # img_ref =
    # '~/shahlab/projects/ITH_Immune/paper/miscellaneous/FF4D00-0.8.png'
    
    xcrmapscape::xcrmapscape(clonal_prev = clonal_prev, tree_edges = tree_edges, 
        sample_locations = sample_locations, img_ref = img_ref, show_warnings = FALSE, 
        chord_data = chord_data, track_data = track_data, resize_factor = resize_factor)
}
xcr_table <- read_clonotypes(xcr_table_path, duplicates = FALSE, db_path)

Read 19.7% of 304912 rows
Read 62.3% of 304912 rows
Read 88.6% of 304912 rows
Read 304912 rows and 18 (of 18) columns from 0.070 GB file in 00:00:05
trb_intersect_table <- compute_overlap_table(xcr_table, segment_type = "TRB", 
    prevalence_option = "clones", id_type = "condensed_id")
trb_intersect_table$patient1 <- ithi.meta::map_id(trb_intersect_table$sample1, 
    from = "condensed_id", to = "patient_id", db_path)
trb_intersect_table$patient2 <- ithi.meta::map_id(trb_intersect_table$sample2, 
    from = "condensed_id", to = "patient_id", db_path)

trb_intersect_table <- subset(trb_intersect_table, patient1 == patient2)

intersect_table <- trb_intersect_table
clonotype_table <- subset(xcr_table, type == "TRB")
clonotype_counts <- clonotype_table %>% group_by(condensed_id, patient_id) %>% 
    summarise(n = n()) %>% plyr::rename(c(condensed_id = "label", n = "len"))
reformat_andrew_table <- function(dat, db_path, patient_id) {
    dat$patient_id <- patient_id
    dat <- subset(dat, !sample_id %in% c("Pv2", "Rec2", "Rec3"))
    dat <- dat %>% plyr::rename(c(sample_id = "plot_id", long_sample_id = "sample_id"))
    dat_remapped <- ithi.meta::remap_sample_ids(dat, db_path)
    dat_remapped$abbrev_id <- stringr::str_extract(dat_remapped$condensed_id, 
        "[A-Za-z0-9]+$")
    dat_remapped <- dat_remapped %>% plyr::rename(c(sample_id = "old_sample_id", 
        sample_key = "long_sample_id", plot_id = "old_plot_id", abbrev_id = "sample_id"))
    if ("location_id" %in% colnames(dat_remapped)) {
        dat_remapped$location_id <- dat_remapped$sample_id
    }
    return(dat_remapped)
}

Plots

htmltools::tagList(lapply(mapscape_input_directories, function(dir) {
    patient_id <- stringr::str_extract(dir, "[0-9]+$")
    df <- subset(intersect_table, patient1 == patient_id)
    clonal_prev = read.table(file.path(dir, "clonal_prevalence_table.tsv"), 
        sep = "\t", header = T)
    tree_edges = read.table(file.path(dir, "tree_edges.tsv"), sep = "\t", header = T)
    sample_locations = read.table(file.path(dir, "sample_locations.tsv"), sep = "\t", 
        header = T)
    sample_locations$long_sample_id <- df_as_map(clonal_prev, sample_locations$sample_id, 
        from = "sample_id", to = "long_sample_id")
    
    clonal_prev <- reformat_andrew_table(clonal_prev, db_path, patient_id)
    sample_locations <- reformat_andrew_table(sample_locations, db_path, patient_id)
    
    # df <- merge(df, subset(andrew_map, select=c(sample_key, sample_id)),
    # by.x=c('sample1'), by.y=c('sample_key')) %>%
    # plyr::rename(c('sample_id'='sample_id1')) df <- merge(df,
    # subset(andrew_map, select=c(sample_key, sample_id)), by.x=c('sample2'),
    # by.y=c('sample_key')) %>% plyr::rename(c('sample_id'='sample_id2'))
    
    clonotype_counts_sub <- clonotype_counts[as.character(clonotype_counts$patient_id) == 
        patient_id, ]
    
    patient_tmp <- patient_id
    
    clonotypes_sub <- xcr_table[(xcr_table$type == "TRB") & (xcr_table$patient_id == 
        as.numeric(patient_tmp)), ]
    clonotypes_sub$condensed_id <- factor(clonotypes_sub$condensed_id)
    cross_table <- ithi.xcr::cross_tabulate(clonotypes_sub, id_type = "condensed_id")
    
    # df$sample1 <- df$sample_id1 df$sample2 <- df$sample_id2
    
    sample_ids <- intersect(clonal_prev$long_sample_id, unique(df$sample1))
    
    if (length(sample_ids) == 0) {
        return(NULL)
    }
    
    df <- subset(df, (sample1 %in% sample_ids) & (sample2 %in% sample_ids))
    df$sample1 <- factor(df$sample1, levels = sample_ids)
    df$sample2 <- factor(df$sample2, levels = sample_ids)
    df <- df[order(df$sample1), ]
    
    ## IF YOU ONLY WANT THE INTERSECTION TO BE SHOWN, JUST SET CLONOTYPE TABLE TO
    ## NULL Otherwise set it to clonotype_counts_sub
    if (show_full_track) {
        res <- ithi.figures::format_xcrcircos_data(df, clonotype_counts = clonotype_counts_sub, 
            cross_table = cross_table)
    } else {
        res <- ithi.figures::format_xcrcircos_data(df, clonotype_counts = NULL)
    }
    chord_data <- res$chords
    track_data <- as.data.frame(res$tracks)
    
    resize_factor <- min(sum(track_data$len)/max(track_data$len) * 1/nrow(track_data), 
        0.9)
    
    clonal_prev <- subset(clonal_prev, long_sample_id %in% sample_ids)
    sample_locations <- subset(sample_locations, sample_id %in% clonal_prev$sample_id)
    
    print(patient_id)
    plot_xcrmapscape(clonal_prev, sample_locations, tree_edges, chord_data = chord_data, 
        track_data = track_data, resize_factor = resize_factor)
}))
[1] "1"
[1] "2"
[1] "3"
[1] "4"
[1] "7"
[1] "9"
[1] "10"
[1] "11"
[1] "12"
[1] "13"
[1] "14"
[1] "15"
[1] "16"
[1] "17"
LS0tCnRpdGxlOiAiWENSLU1hcHNjYXBlIHBsb3RzIgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKICAgIHRvY19kZXB0aDogNQogICAgdG9jX2Zsb2F0OiB0cnVlCnBhcmFtczoKICBybWQ6ICJ4Y3JtYXBzY2FwZS5SbWQiCi0tLQogICAgICAgICAgICAgICAgICAgICAgICBgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KCiMjIyMjIyMjIFNuYWtlbWFrZSBoZWFkZXIgIyMjIyMjIyMKbGlicmFyeShtZXRob2RzKQpTbmFrZW1ha2UgPC0gc2V0Q2xhc3MoCiAgICAiU25ha2VtYWtlIiwKICAgIHNsb3RzID0gYygKICAgICAgICBpbnB1dCA9ICJsaXN0IiwKICAgICAgICBvdXRwdXQgPSAibGlzdCIsCiAgICAgICAgcGFyYW1zID0gImxpc3QiLAogICAgICAgIHdpbGRjYXJkcyA9ICJsaXN0IiwKICAgICAgICB0aHJlYWRzID0gIm51bWVyaWMiLAogICAgICAgIGxvZyA9ICJsaXN0IiwKICAgICAgICByZXNvdXJjZXMgPSAibGlzdCIsCiAgICAgICAgY29uZmlnID0gImxpc3QiLAogICAgICAgIHJ1bGUgPSAiY2hhcmFjdGVyIgogICAgKQopCnNuYWtlbWFrZSA8LSBTbmFrZW1ha2UoCiAgICBpbnB1dCA9IGxpc3QoJ1JtZC94Y3JtYXBzY2FwZS5SbWQnLCAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3BhcGVyL2FuYWx5c2lzL1JtZC9fc2l0ZS55bWwnLCAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3BhcGVyL3Jlc3VsdHMvdGFibGVzL3J1bjIveGNyX3RhYmxlLnRzdicsICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy9pbnRlcm1lZGlhdGVzL3J1bjIvbWFwc2NhcGVfcG9zdHByb2Nlc3NlZF9ITUMvMScsICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy9pbnRlcm1lZGlhdGVzL3J1bjIvbWFwc2NhcGVfcG9zdHByb2Nlc3NlZF9ITUMvMicsICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy9pbnRlcm1lZGlhdGVzL3J1bjIvbWFwc2NhcGVfcG9zdHByb2Nlc3NlZF9ITUMvMycsICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy9pbnRlcm1lZGlhdGVzL3J1bjIvbWFwc2NhcGVfcG9zdHByb2Nlc3NlZF9ITUMvNCcsICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy9pbnRlcm1lZGlhdGVzL3J1bjIvbWFwc2NhcGVfcG9zdHByb2Nlc3NlZF9ITUMvNycsICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy9pbnRlcm1lZGlhdGVzL3J1bjIvbWFwc2NhcGVfcG9zdHByb2Nlc3NlZF9ITUMvOScsICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy9pbnRlcm1lZGlhdGVzL3J1bjIvbWFwc2NhcGVfcG9zdHByb2Nlc3NlZF9ITUMvMTAnLCAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3BhcGVyL3Jlc3VsdHMvaW50ZXJtZWRpYXRlcy9ydW4yL21hcHNjYXBlX3Bvc3Rwcm9jZXNzZWRfSE1DLzExJywgJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9wYXBlci9yZXN1bHRzL2ludGVybWVkaWF0ZXMvcnVuMi9tYXBzY2FwZV9wb3N0cHJvY2Vzc2VkX0hNQy8xMicsICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy9pbnRlcm1lZGlhdGVzL3J1bjIvbWFwc2NhcGVfcG9zdHByb2Nlc3NlZF9ITUMvMTMnLCAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3BhcGVyL3Jlc3VsdHMvaW50ZXJtZWRpYXRlcy9ydW4yL21hcHNjYXBlX3Bvc3Rwcm9jZXNzZWRfSE1DLzE0JywgJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9wYXBlci9yZXN1bHRzL2ludGVybWVkaWF0ZXMvcnVuMi9tYXBzY2FwZV9wb3N0cHJvY2Vzc2VkX0hNQy8xNScsICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy9pbnRlcm1lZGlhdGVzL3J1bjIvbWFwc2NhcGVfcG9zdHByb2Nlc3NlZF9ITUMvMTYnLCAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3BhcGVyL3Jlc3VsdHMvaW50ZXJtZWRpYXRlcy9ydW4yL21hcHNjYXBlX3Bvc3Rwcm9jZXNzZWRfSE1DLzE3JywgIm5vdGVib29rIiA9ICdSbWQveGNybWFwc2NhcGUuUm1kJywgInNpdGVfZmlsZSIgPSAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3BhcGVyL2FuYWx5c2lzL1JtZC9fc2l0ZS55bWwnLCAieGNyX3RhYmxlIiA9ICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy90YWJsZXMvcnVuMi94Y3JfdGFibGUudHN2JywgIm1hcHNjYXBlX2lucHV0cyIgPSBjKCcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy9pbnRlcm1lZGlhdGVzL3J1bjIvbWFwc2NhcGVfcG9zdHByb2Nlc3NlZF9ITUMvMScsICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy9pbnRlcm1lZGlhdGVzL3J1bjIvbWFwc2NhcGVfcG9zdHByb2Nlc3NlZF9ITUMvMicsICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy9pbnRlcm1lZGlhdGVzL3J1bjIvbWFwc2NhcGVfcG9zdHByb2Nlc3NlZF9ITUMvMycsICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy9pbnRlcm1lZGlhdGVzL3J1bjIvbWFwc2NhcGVfcG9zdHByb2Nlc3NlZF9ITUMvNCcsICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy9pbnRlcm1lZGlhdGVzL3J1bjIvbWFwc2NhcGVfcG9zdHByb2Nlc3NlZF9ITUMvNycsICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy9pbnRlcm1lZGlhdGVzL3J1bjIvbWFwc2NhcGVfcG9zdHByb2Nlc3NlZF9ITUMvOScsICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy9pbnRlcm1lZGlhdGVzL3J1bjIvbWFwc2NhcGVfcG9zdHByb2Nlc3NlZF9ITUMvMTAnLCAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3BhcGVyL3Jlc3VsdHMvaW50ZXJtZWRpYXRlcy9ydW4yL21hcHNjYXBlX3Bvc3Rwcm9jZXNzZWRfSE1DLzExJywgJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9wYXBlci9yZXN1bHRzL2ludGVybWVkaWF0ZXMvcnVuMi9tYXBzY2FwZV9wb3N0cHJvY2Vzc2VkX0hNQy8xMicsICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy9pbnRlcm1lZGlhdGVzL3J1bjIvbWFwc2NhcGVfcG9zdHByb2Nlc3NlZF9ITUMvMTMnLCAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3BhcGVyL3Jlc3VsdHMvaW50ZXJtZWRpYXRlcy9ydW4yL21hcHNjYXBlX3Bvc3Rwcm9jZXNzZWRfSE1DLzE0JywgJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9wYXBlci9yZXN1bHRzL2ludGVybWVkaWF0ZXMvcnVuMi9tYXBzY2FwZV9wb3N0cHJvY2Vzc2VkX0hNQy8xNScsICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy9pbnRlcm1lZGlhdGVzL3J1bjIvbWFwc2NhcGVfcG9zdHByb2Nlc3NlZF9ITUMvMTYnLCAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3BhcGVyL3Jlc3VsdHMvaW50ZXJtZWRpYXRlcy9ydW4yL21hcHNjYXBlX3Bvc3Rwcm9jZXNzZWRfSE1DLzE3JykpLAogICAgb3V0cHV0ID0gbGlzdCgnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3BhcGVyL3Jlc3VsdHMvd2ViL3hjcm1hcHNjYXBlLm5iLmh0bWwnKSwKICAgIHBhcmFtcyA9IGxpc3QoJ2l0aGktYW5hbHlzaXMtcGxvdF94Y3JtYXBzY2FwZXMnLCAnaW50ZXJzZWN0JywgJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9tZXRhZGF0YS9kYi9pbW11bmVfcHJvamVjdC5zcWxpdGUzJywgImRiIiA9ICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvbWV0YWRhdGEvZGIvaW1tdW5lX3Byb2plY3Quc3FsaXRlMycsICJuYW1lIiA9ICdpdGhpLWFuYWx5c2lzLXBsb3RfeGNybWFwc2NhcGVzJywgInRyYWNrX29wdGlvbiIgPSAnaW50ZXJzZWN0JyksCiAgICB3aWxkY2FyZHMgPSBsaXN0KCksCiAgICB0aHJlYWRzID0gMSwKICAgIGxvZyA9IGxpc3QoJy9zaGFobGFiL2FsemhhbmcvY2x1c3R0bXAvcGFwZXJhbmFseXNpczIvcGxvdF94Y3JtYXBzY2FwZS5sb2cnKSwKICAgIHJlc291cmNlcyA9IGxpc3QoKSwKICAgIGNvbmZpZyA9IGxpc3QoIm11dHNpZ190aWx0eXBlcyIgPSBjKCdFX0NEOF9kZW5zaXR5JywgJ0VfQ0Q0X2RlbnNpdHknLCAnRV9DRDIwX2RlbnNpdHknLCAnRV9QbGFzbWFfZGVuc2l0eScsICdTX0NEOF9kZW5zaXR5JywgJ1NfQ0Q0X2RlbnNpdHknLCAnU19DRDIwX2RlbnNpdHknLCAnU19QbGFzbWFfZGVuc2l0eScsICdUX0NEOF9kZW5zaXR5JywgJ1RfQ0Q0X2RlbnNpdHknLCAnVF9DRDIwX2RlbnNpdHknLCAnVF9QbGFzbWFfZGVuc2l0eScpLCAicGF0aWVudHNfZm9yX2Nsb25hbCIgPSBjKDEsIDIsIDMsIDQsIDcsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsIDE2LCAxNyksICJpY2djX3NwZWNpbWVuX2ZpbGUiID0gJy9zaGFobGFiL2FsemhhbmcvZGF0YS9JQ0dDL3NwZWNpbWVuLnRzdicsICJtb2xzdWJ0eXBlX3RpbHR5cGVzIiA9IGMoJ0VfQ0Q4X2RlbnNpdHknLCAnRV9DRDRfZGVuc2l0eScsICdFX0NEMjBfZGVuc2l0eScsICdFX1BsYXNtYV9kZW5zaXR5JywgJ1NfQ0Q4X2RlbnNpdHknLCAnU19DRDRfZGVuc2l0eScsICdTX0NEMjBfZGVuc2l0eScsICdTX1BsYXNtYV9kZW5zaXR5JyksICJsb2dkaXIiID0gJy9zaGFobGFiL2FsemhhbmcvY2x1c3R0bXAvcGFwZXJhbmFseXNpczInLCAiZHJpdmVyX21hcCIgPSAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3N1YnByb2plY3RzL2RyaXZlcnMvZGF0YS9nZW5lX2xpc3RfbWFwcGVkLmJlZCcsICJpY2djX25vcm1hbGl6ZWRfcmVhZHNfbWF0cml4IiA9ICcvc2hhaGxhYi9hbHpoYW5nL2RhdGEvSUNHQy9PVkFVX2V4cHJfbWF0cml4LnRzdicsICJzaXRlX2ZpbGUiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9wYXBlci9hbmFseXNpcy9SbWQvX3NpdGUueW1sJywgIndhbmdfZmJpX3N0YXR1cyIgPSAnL3NoYWhsYWIvYWx6aGFuZy9kYXRhL0lDR0MvbmcuMzg0OS1TMTIudHh0JywgIm1tY3RtX3BhdGllbnRfYW5jZXN0cmFsX2Rlc2NlbmRhbnRfcmVzdWx0X2RpciIgPSAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3Jlc3VsdHMvbW1jdG1fcmVzdWx0cy9pdGhfYnktcGF0aWVudC1hbmNlc3RyeS9vdXRwdXQnLCAiaWNnY19tb2xlY3VsYXJfc3VidHlwZXMiID0gJy9zaGFobGFiL2FsemhhbmcvZGF0YS9JQ0dDL2ljZ2NfcHJpbWFyeV90dW1vdXJfc3VidHlwZXMudHN2JywgInNwYXRpYWxfbm90ZWJvb2siID0gJ1JtZC9zcGF0aWFsX2FuYWx5c2lzLlJtZCcsICJiY3JfZGl2ZXJzaXR5IiA9ICcvc2hhaGxhYi9hbHpoYW5nL3BpcGVsaW5lX291dHB1dHMvaXRoX2ltbXVuZS9taXhjci9taXhjcl9ydW5zL2l0aF8xXzJfMy9taXhjcjUvcG9zdHByb2Nlc3MvSUdIL3Bvc3RmaWx0ZXJfZGl2ZXJzaXR5X3N0YXRzL2RpdmVyc2l0eS5zdHJpY3QucmVzYW1wbGVkLnR4dCcsICJ4Y3JfY2xvbmVzX25vdGVib29rIiA9ICdSbWQveGNyX2Nsb25lc19hbmFseXNpcy5SbWQnLCAibGlicmFyeV9zaXplcyIgPSAnL3NoYWhsYWIvYWx6aGFuZy9waXBlbGluZV9vdXRwdXRzL2l0aF9pbW11bmUvbWl4Y3IvbWl4Y3JfcnVucy9pdGhfMV8yXzMvbWl4Y3I1L2xpYnJhcnlfc2l6ZXMudHN2JywgInRjcl9kaXZlcnNpdHkiID0gJy9zaGFobGFiL2FsemhhbmcvcGlwZWxpbmVfb3V0cHV0cy9pdGhfaW1tdW5lL21peGNyL21peGNyX3J1bnMvaXRoXzFfMl8zL21peGNyNS9wb3N0cHJvY2Vzcy9UUkIvcG9zdGZpbHRlcl9kaXZlcnNpdHlfc3RhdHMvZGl2ZXJzaXR5LnN0cmljdC5yZXNhbXBsZWQudHh0JywgIm1tY3RtX292X2NvbWJpbmVkX3Jlc3VsdF9kaXIiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9yZXN1bHRzL21tY3RtX3Jlc3VsdHMvY29tYmluZWRfb3ZfbW1jdG0vb3V0cHV0JywgImJjcnBoeWxvX3RpbHR5cGVzIiA9IGMoJ0VfQ0Q4X2RlbnNpdHknLCAnRV9DRDRfZGVuc2l0eScsICdFX0NEMjBfZGVuc2l0eScsICdFX1BsYXNtYV9kZW5zaXR5JywgJ1NfQ0Q4X2RlbnNpdHknLCAnU19DRDRfZGVuc2l0eScsICdTX0NEMjBfZGVuc2l0eScsICdTX1BsYXNtYV9kZW5zaXR5JywgJ1RfQ0Q4X2RlbnNpdHknLCAnVF9DRDRfZGVuc2l0eScsICdUX0NEMjBfZGVuc2l0eScsICdUX1BsYXNtYV9kZW5zaXR5JyksICJuYW5vc3RyaW5nX3NpZ25hdHVyZV9ub3RlYm9vayIgPSAnUm1kL25hbm9zdHJpbmdfc2lnbmF0dXJlcy5SbWQnLCAic3BhdGlhbF9yZXN1bHRfZGlycyIgPSBsaXN0KCJlcGl0aGVsaWFsIiA9ICcvc2hhaGxhYi9hbHpoYW5nL3BpcGVsaW5lX291dHB1dHMvaXRoX2ltbXVuZS9zcGF0c2ltL2l0aDMvYWJjJywgInN0cm9tYWwiID0gJy9zaGFobGFiL2FsemhhbmcvcGlwZWxpbmVfb3V0cHV0cy9pdGhfaW1tdW5lL3NwYXRzaW0vaXRoNS9hYmMnKSwgImloY194Y3JfdGlsdHlwZXMiID0gYygnRV9DRDhfZGVuc2l0eScsICdFX0NENF9kZW5zaXR5JywgJ0VfQ0QyMF9kZW5zaXR5JywgJ0VfUGxhc21hX2RlbnNpdHknLCAnU19DRDhfZGVuc2l0eScsICdTX0NENF9kZW5zaXR5JywgJ1NfQ0QyMF9kZW5zaXR5JywgJ1NfUGxhc21hX2RlbnNpdHknLCAnVF9DRDhfZGVuc2l0eScsICdUX0NENF9kZW5zaXR5JywgJ1RfQ0QyMF9kZW5zaXR5JywgJ1RfUGxhc21hX2RlbnNpdHknKSwgInByZXZhbGVuY2VfdGhyZXNob2xkIiA9IDAuMDEsICJqX2RpY3Rpb25hcnkiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9zdWJwcm9qZWN0cy9pbW10eXBlci9tZXRhZGF0YS9pbWd0L0hvbW9fc2FwaWVuc19UUkJKLmZhc3RhJywgIm5jbHVzdHMiID0gMywgIm11dGF0aW9uX3NpZ25hdHVyZV9ub3RlYm9vayIgPSAnUm1kL211dGF0aW9uX3NpZ25hdHVyZXMuUm1kJywgIm1tY3RtX3BhdGllbnRfYWRfc2lncGxvdCIgPSAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3Jlc3VsdHMvbW1jdG1fcmVzdWx0cy9pdGhfYnktcGF0aWVudC1hbmNlc3RyeS9wbG90cy9pdGgtYnktcGF0aWVudC1hbmNlc3RyeV9zbnYtc3Zfc2lnc19tdWx0aXBhbmVsLnBkZicsICJtb2xzdWJ0eXBlX25vdGVib29rIiA9ICdSbWQvbW9sZWN1bGFyX3N1YnR5cGVzLlJtZCcsICJpdGhfc3RhdGlzdGljc19ub3RlYm9vayIgPSAnUm1kL2l0aF9zdGF0aXN0aWNzLlJtZCcsICJ0aWxzX2Zvcl9jbHVzdGVyIiA9IGMoJ0VfQ0Q4X2RlbnNpdHknLCAnRV9DRDRfZGVuc2l0eScsICdFX0NEMjBfZGVuc2l0eScsICdFX1BsYXNtYV9kZW5zaXR5JywgJ1NfQ0Q4X2RlbnNpdHknLCAnU19DRDRfZGVuc2l0eScsICdTX0NEMjBfZGVuc2l0eScsICdTX1BsYXNtYV9kZW5zaXR5JyksICJleGFtcGxlX2Fubm90YXRpb25zIiA9ICcvc2hhaGxhYi9hbHpoYW5nL3BpcGVsaW5lX291dHB1dHMvaXRoX2ltbXVuZS9pZ3BhcnRpdGlvbi9ydW4xMy9maW5hbF9wYXJ0aXRpb25zL2l0aDJfMi9jbHVzdDkvYW5ub3RhdGlvbnNfZmxhZ2dlZC50c3YnLCAibWFzdGVyX2JyZWFrcG9pbnRfZmlsZSIgPSAnL3NoYWhsYWIvYW1jcGhlcnNvbi9wcm9qZWN0cy9pdGgzL2l0aDMvbm90ZWJvb2tzL2Jlc3Bva2UvaXRoX2JyZWFrcG9pbnRzLnRzdicsICJjbG9uZV9wcmV2YWxlbmNlX2ZpbGUiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9kYXRhL2l0aC9jb21wbGV0ZS9jbG9uZV9kYXRhLnRzdicsICJ0YWJsZV9kaXIiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9wYXBlci9yZXN1bHRzL3RhYmxlcy9ydW4yJywgIm11bHRpdmlld2NsdXN0ZXJpbmdfbm90ZWJvb2siID0gJ1JtZC9tdWx0aXZpZXdjbHVzdGVyaW5nLlJtZCcsICJtbWN0bV9zYW1wbGVfcmVzdWx0X2RpciIgPSAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3Jlc3VsdHMvbW1jdG1fcmVzdWx0cy9pdGhfYnktc2FtcGxlL291dHB1dCcsICJpbmRleF9ub3RlYm9vayIgPSAnUm1kL2luZGV4LlJtZCcsICJtdmNsdXN0X25jbHVzdCIgPSAzLCAidl9kaWN0aW9uYXJ5IiA9ICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvc3VicHJvamVjdHMvaW1tdHlwZXIvbWV0YWRhdGEvaW1ndC9Ib21vX3NhcGllbnNfVFJCVi5mYXN0YScsICJpbW10eXBlcl9sZW5ndGhzIiA9ICcxMSAxMiAxMyAxNCAxNSAxNiAxNyAxOCcsICJ4Y3JfZGlzdGFuY2VfbWV0aG9kIiA9ICdob3JuJywgImJjcnBoeWxvX2V4YW1wbGVzX25vdGVib29rIiA9ICdSbWQvYmNyX3BoeWxvX2V4YW1wbGVzLlJtZCcsICJpdGhfcHJvamVjdF9yZXN1bHRzIiA9ICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL2l0aDMvZGF0YS9yZXN1bHRzJywgImJjcnBoeWxvX2NvcnJlbGF0aW9uc19ub3RlYm9vayIgPSAnUm1kL2Jjcl9waHlsb19jb3JyZWxhdGlvbnMuUm1kJywgImRiIiA9ICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvbWV0YWRhdGEvZGIvaW1tdW5lX3Byb2plY3Quc3FsaXRlMycsICJQTkdfREVOU0lUWSIgPSAzMDAsICJjbG9uZV90cmVlX2ZpbGUiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9kYXRhL2l0aC9jb21wbGV0ZS90cmVlX2RhdGEudHN2JywgImZpZ3VyZV9nYWxsZXJ5X25vdGVib29rIiA9ICdSbWQvZmlndXJlcy5SbWQnLCAidGNnYV9vdl9hbm5vdGF0aW9ucyIgPSAnL3NoYWhsYWIvYWx6aGFuZy9kYXRhL1RDR0EvdGNnYV9vdl9hbm5vdGF0aW9uX3N1cDEzLnR4dCcsICJtbWN0bV9maW5hbF9wYXRpZW50X2RpciIgPSAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3Jlc3VsdHMvbW1jdG1fcmVzdWx0cy9pdGhfYnktcGF0aWVudF93aXRoLW92JywgImltbXR5cGVyX21vZGVscyIgPSAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3Jlc3VsdHMvaW1tdHlwZXJfcmVzdWx0cy9rbGFyZW5iZWVrL2FhX3ZqL2dyYWRib29zdCcsICJ0Y3JfY2xvbm90eXBlcyIgPSAnL3NoYWhsYWIvYWx6aGFuZy9waXBlbGluZV9vdXRwdXRzL2l0aF9pbW11bmUvbWl4Y3IvbWl4Y3JfcnVucy9pdGhfMV8yXzMvbWl4Y3I1L2Nsb25vdHlwZXMvVFJCX2Nsb25vdHlwZXNfZmlsdGVyZWQudHh0JywgImlncGFydGl0aW9uX291dGRpciIgPSAnL3NoYWhsYWIvYWx6aGFuZy9waXBlbGluZV9vdXRwdXRzL2l0aF9pbW11bmUvaWdwYXJ0aXRpb24vcnVuMjInLCAieGNyX3FjX25vdGVib29rIiA9ICdSbWQvcmVwbGljYXRlcy5SbWQnLCAiaW50ZXJtZWRpYXRlX2RpciIgPSAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3BhcGVyL3Jlc3VsdHMvaW50ZXJtZWRpYXRlcy9ydW4yJywgInBoZW5vdHlwZV90aHJlc2hvbGQiID0gMC44NSwgIlBOR19RVUFMSVRZIiA9IDMwMCwgInRjZ2FfZXhwcl9tYXRyaXgiID0gJy9zaGFobGFiL2FsemhhbmcvZGF0YS9UQ0dBL2V4cHJfbWF0cml4X25vcm1hbGl6ZV9zdGFuZGFyZGl6ZV9ub2R1cGxpY2F0ZXMudHN2JywgInNhZF9ub3RlYm9vayIgPSAnUm1kL3NwZWNpZXNfYWJ1bmRhbmNlX2Rpc3RyaWJ1dGlvbnMuUm1kJywgInRpbHNfZm9yX3ZhcmlhYmlsaXR5IiA9IGMoJ0VfQ0Q4X2RlbnNpdHknLCAnRV9DRDRfZGVuc2l0eScsICdFX0NEMjBfZGVuc2l0eScsICdFX1BsYXNtYV9kZW5zaXR5JywgJ1NfQ0Q4X2RlbnNpdHknLCAnU19DRDRfZGVuc2l0eScsICdTX0NEMjBfZGVuc2l0eScsICdTX1BsYXNtYV9kZW5zaXR5JyksICJpdGhfc3RhdF90eXBlcyIgPSBjKCdlbnRyb3B5JywgJ3Bvc3Rwcm9jZXNzZWRfZGl2ZXJnZW5jZScsICdjb21iaW5lZF9pdGhfbm9ybWFsaXplZCcsICdwcm9wb3J0aW9uX3N1YmNsb25hbCcpLCAiaWhjX3J1bjIiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9kYXRhL2loYy9jZDc5Y2QxMzhjZDY4L3ZhbGlkYXRlZF9zdGF0c193ZWlnaHRlZC5yZGF0YScsICJwcm9wb3J0aW9uX3N1YmNsb25hbF9maWxlIiA9ICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvZGF0YS9pdGgvY29tcGxldGUvb2xkX3Byb3BvcnRpb25fc3ViY2xvbmFsLnRzdicsICJtbWN0bV9maW5hbF9wYXRpZW50X3NpZ3Bsb3QiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9yZXN1bHRzL21tY3RtX3Jlc3VsdHMvaXRoX2J5LXBhdGllbnRfd2l0aC1vdi9wbG90cy9pdGgtYnktcGF0aWVudF9zbnYtc3Zfc2lnc19tdWx0aXBhbmVsLnBkZicsICJleGFtcGxlX21zYV9wbG90IiA9ICcvc2hhaGxhYi9hbHpoYW5nL3BpcGVsaW5lX291dHB1dHMvaXRoX2ltbXVuZS9pZ3BhcnRpdGlvbi9ydW4xMy9vbGQvYWxpZ25tZW50X3Bsb3RzL21zYS9pdGgyXzIvY2x1c3Q5L2luZGVsX3JldmVyc2VkLmh0bWwnLCAiaWhjX3J1bjEiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9kYXRhL2loYy9jZDhjZDNjZDIwL3ZhbGlkYXRlZF9zdGF0c193ZWlnaHRlZF9uZXcucmRhdGEnLCAidmFyaWFiaWxpdHlfdHlwZSIgPSAnc3RhYmlsaXplJywgImltbXVuZV92YXJpYWJpbGl0eV9ub3RlYm9vayIgPSAnUm1kL2ltbXVuZV92YXJpYWJpbGl0eS5SbWQnLCAibmFub3N0cmluZ19hbm5vdGF0aW9ucyIgPSAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL2RhdGEvZXhwcmVzc2lvbi9uYW5vc3RyaW5nL3BhbmNhbmNlcl9hbm5vdGF0aW9ucy50c3YnLCAiaXRoX3N0YXRzX2ZpbGUiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9kYXRhL2l0aC9jb21wbGV0ZS9jbG9uYWxfbWVhc3VyZXMudHN2JywgInhjcm1hcHNjYXBlX25vdGVib29rIiA9ICdSbWQveGNybWFwc2NhcGUuUm1kJywgImNsb25hbF9zYW1wbGVycyIgPSBjKCdITUMnLCAnTlVUUycpLCAia25vd25fc3VidHlwZXNfbWVyZ2VkIiA9ICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvZGF0YS9leHByZXNzaW9uL2tub3duX3N1YnR5cGVzX21lcmdlZC50c3YnLCAiYmNyX2Nsb25vdHlwZXMiID0gJy9zaGFobGFiL2FsemhhbmcvcGlwZWxpbmVfb3V0cHV0cy9pdGhfaW1tdW5lL21peGNyL21peGNyX3J1bnMvaXRoXzFfMl8zL21peGNyNS9jbG9ub3R5cGVzL0lHSF9jbG9ub3R5cGVzX2ZpbHRlcmVkLnR4dCcsICJpY2djX2V4cHJfbWVsdGVkIiA9ICcvc2hhaGxhYi9hbHpoYW5nL2RhdGEvSUNHQy9PVkFVX2V4cHJfbWVsdGVkLnRzdicsICJkZWZhdWx0X3NhbXBsZXIiID0gJ0hNQycsICJuYW5vc3RyaW5nX2RhdGEiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9yZXN1bHRzL25hbm9zdHJpbmdfcmVzdWx0cy9pdGhfZnVsbC9xYy9saW1tYV9xdWFudGlsZS9ub3JtYWxpemVkX2V4cHJlc3Npb25fdm9hX2xhYmVsc19maWx0ZXJlZC50c3YnLCAibW1jdG1fYW5jZXN0cmFsX2Rlc2NlbmRhbnRfcmVzdWx0X2RpciIgPSAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3Jlc3VsdHMvbW1jdG1fcmVzdWx0cy9pdGhfYnktYW5jZXN0cnktc2FtcGxlL291dHB1dCcsICJpaGNfeGNyX3N0YXRzX25vdGVib29rIiA9ICdSbWQvaWhjX3hjcl9zdGF0cy5SbWQnLCAibW1jdG1fc2FtcGxlX2FkX3NpZ3Bsb3QiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9yZXN1bHRzL21tY3RtX3Jlc3VsdHMvaXRoX2J5LWFuY2VzdHJ5LXNhbXBsZS9wbG90cy9pdGgtYnktYW5jZXN0cmFsLXNhbXBsZV9zbnYtc3Zfc2lnc19tdWx0aXBhbmVsLnBkZicsICJtbWN0bV9vdl9jb21iaW5lZF9zaWdwbG90IiA9ICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcmVzdWx0cy9tbWN0bV9yZXN1bHRzL2NvbWJpbmVkX292X21tY3RtL3Bsb3RzL292X3Nudi1zdl9zaWdzX211bHRpcGFuZWwucGRmJywgIm12Y2x1c3RfdGlsdHlwZXMiID0gYygnRV9DRDhfZGVuc2l0eScsICdFX0NENF9kZW5zaXR5JywgJ0VfQ0QyMF9kZW5zaXR5JywgJ0VfUGxhc21hX2RlbnNpdHknLCAnU19DRDhfZGVuc2l0eScsICdTX0NENF9kZW5zaXR5JywgJ1NfQ0QyMF9kZW5zaXR5JywgJ1NfUGxhc21hX2RlbnNpdHknKSwgIm5lb2VkaXRpbmdfb3V0ZGlyIiA9ICcvc2hhaGxhYi9hbHpoYW5nL3BpcGVsaW5lX291dHB1dHMvaXRoX2ltbXVuZS9uZW9lZGl0aW5nL3J1bjQnLCAibW1jdG1fc2FtcGxlX3NpZ3Bsb3QiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9yZXN1bHRzL21tY3RtX3Jlc3VsdHMvaXRoX2J5LXNhbXBsZS9wbG90cy9pdGgtYnktc2FtcGxlX3Nudi1zdl9zaWdzX211bHRpcGFuZWwucGRmJywgImtub3duX3N1YnR5cGVfZmlsZSIgPSAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL2RhdGEvZXhwcmVzc2lvbi9hcnJheS9zdWJ0eXBlcy9rbm93bl9zdWJ0eXBlcy50c3YnLCAibWFwc2NhcGVfbm90ZWJvb2siID0gJ1JtZC9tYXBzY2FwZS5SbWQnLCAibm90ZWJvb2tfZGlyIiA9ICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy93ZWInLCAic3VidHlwZV9tYXJrZXJfZmlsZSIgPSAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL2RhdGEvZXhwcmVzc2lvbi9uYW5vc3RyaW5nL3N1YnR5cGVfbWFya2Vycy50c3YnLCAiaXRoX3RpbF9ub3RlYm9vayIgPSAnUm1kL2l0aF90aWxfZGVuc2l0aWVzLlJtZCcsICJpY2djX2NsaW5pY2FsIiA9ICcvc2hhaGxhYi9hbHpoYW5nL2RhdGEvSUNHQy9kb25vci5PVi1BVS50c3YnLCAiY2xhc3NpZmllcl90eXBlIiA9ICdrbm4nLCAidGlsX2NsYXNzaWZpZXJfbm90ZWJvb2siID0gJ1JtZC90aWxfY2xhc3NpZmllci5SbWQnLCAiYmVuY2htYXJrZGlyIiA9ICcvc2hhaGxhYi9hbHpoYW5nL2JlbmNobWFya3MvcGFwZXJhbmFseXNpczInLCAidGNnYV9jbGluaWNhbCIgPSAnL3NoYWhsYWIvYWx6aGFuZy9kYXRhL1RDR0Evc3luYXBzZV9jbGluQWxsX2RhdGEudHN2JywgInhjcl9tYXBwaW5nX25vdGVib29rIiA9ICdSbWQveGNyX21hcHBpbmcuUm1kJywgIm1hc3Rlcl92YXJpYW50X2ZpbGUiID0gJy9zaGFobGFiL2FtY3BoZXJzb24vcHJvamVjdHMvaXRoMy9pdGgzL25vdGVib29rcy9iZXNwb2tlL2l0aF9zbnZzLnRzdicsICJjbG9uZV9icmFuY2hfbGVuZ3RoX2ZpbGUiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9kYXRhL2l0aC9jb21wbGV0ZS9icmFuY2hfZGF0YS50c3YnLCAiZHJpdmVyX2FuYWx5c2lzX25vdGVib29rIiA9ICdSbWQvZHJpdmVyX2FuYWx5c2lzLlJtZCcsICJuZW9hbnRpZ2VuX2VkaXRpbmdfbm90ZWJvb2siID0gJ1JtZC9pbW11bm9lZGl0aW5nLlJtZCcpLAogICAgcnVsZSA9ICdwbG90X3hjcm1hcHNjYXBlJwopCiMjIyMjIyMjIE9yaWdpbmFsIHNjcmlwdCAjIyMjIyMjIyMKCiAgICAgICAgICAgICAgICAgICAgICAgIGBgYAoKCmBgYHtyIGdsb2JhbF9jaHVua19vcHRpb25zLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIHRpZHk9VFJVRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSkKYGBgCgpgYGB7cn0KIyMgTW9kaWZpZWQgdmVyc2lvbiBvZiBtYXBzY2FwZS4gQ2Fubm90IGJlIHB1dCBpbnRvIHRoZSBzYW1lIHBhY2thZ2UgYXMgc29tZSBvZiB0aGUgY29tcG9uZW50cyBjb25mbGljdApsaWJyYXJ5KHhjcm1hcHNjYXBlKQpsaWJyYXJ5KGh0bWx3aWRnZXRzKQoKbGlicmFyeShpdGhpLnV0aWxzKQpsb2FkX2Jhc2VfbGlicygpCmxpYnJhcnkoaXRoaS5tZXRhKQpsaWJyYXJ5KGl0aGkuaWhjKQpsaWJyYXJ5KGl0aGkueGNyKQpsaWJyYXJ5KGl0aGkuZmlndXJlcykKYGBgCgojIyBQYXJhbWV0ZXJzCgpgYGB7cn0KZGJfcGF0aCA8LSBzbmFrZW1ha2VAcGFyYW1zJGRiCgptYXBzY2FwZV9pbnB1dF9kaXJlY3RvcmllcyA9IHNuYWtlbWFrZUBpbnB1dCRtYXBzY2FwZV9pbnB1dHMKeGNyX3RhYmxlX3BhdGggPC0gc25ha2VtYWtlQGlucHV0JHhjcl90YWJsZQpzaG93X2Z1bGxfdHJhY2sgPC0gKHNuYWtlbWFrZUBwYXJhbXMkdHJhY2tfb3B0aW9uID09ICJmdWxsIikKYGBgCgpgYGB7cn0KZGIgPC0gc3JjX3NxbGl0ZShkYl9wYXRoLCBjcmVhdGU9RkFMU0UpCmFuZHJld19tYXAgPC0gY29sbGVjdCh0YmwoZGIsICJhbmRyZXdfbWFwIikpCmBgYAoKYGBge3J9CnBsb3RfeGNybWFwc2NhcGUgPC0gZnVuY3Rpb24oY2xvbmFsX3ByZXYsIHNhbXBsZV9sb2NhdGlvbnMsIHRyZWVfZWRnZXMsIGNob3JkX2RhdGEsIHRyYWNrX2RhdGEsIHJlc2l6ZV9mYWN0b3IpIHsKICBpbWdfcmVmID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9wYXBlci9taXNjZWxsYW5lb3VzL0ZGNEQwMC0wLjgucG5nJwogICNpbWdfcmVmID0gJ34vc2hhaGxhYi9wcm9qZWN0cy9JVEhfSW1tdW5lL3BhcGVyL21pc2NlbGxhbmVvdXMvRkY0RDAwLTAuOC5wbmcnCiAgCiAgeGNybWFwc2NhcGU6Onhjcm1hcHNjYXBlKAogICAgY2xvbmFsX3ByZXYgPSBjbG9uYWxfcHJldiwKICAgIHRyZWVfZWRnZXMgPSB0cmVlX2VkZ2VzLAogICAgc2FtcGxlX2xvY2F0aW9ucyA9IHNhbXBsZV9sb2NhdGlvbnMsCiAgICBpbWdfcmVmID0gaW1nX3JlZiwKICAgIHNob3dfd2FybmluZ3MgPSBGQUxTRSwKICAgIGNob3JkX2RhdGEgPSBjaG9yZF9kYXRhLAogICAgdHJhY2tfZGF0YSA9IHRyYWNrX2RhdGEsCiAgICByZXNpemVfZmFjdG9yID0gcmVzaXplX2ZhY3RvcikKfQpgYGAKCmBgYHtyfQp4Y3JfdGFibGUgPC0gcmVhZF9jbG9ub3R5cGVzKHhjcl90YWJsZV9wYXRoLCBkdXBsaWNhdGVzID0gRkFMU0UsIGRiX3BhdGgpCnRyYl9pbnRlcnNlY3RfdGFibGUgPC0gY29tcHV0ZV9vdmVybGFwX3RhYmxlKHhjcl90YWJsZSwgc2VnbWVudF90eXBlID0gIlRSQiIsIHByZXZhbGVuY2Vfb3B0aW9uID0gImNsb25lcyIsIGlkX3R5cGUgPSAiY29uZGVuc2VkX2lkIikKdHJiX2ludGVyc2VjdF90YWJsZSRwYXRpZW50MSA8LSBpdGhpLm1ldGE6Om1hcF9pZCh0cmJfaW50ZXJzZWN0X3RhYmxlJHNhbXBsZTEsIGZyb20gPSAiY29uZGVuc2VkX2lkIiwgdG89InBhdGllbnRfaWQiLCBkYl9wYXRoKQp0cmJfaW50ZXJzZWN0X3RhYmxlJHBhdGllbnQyIDwtIGl0aGkubWV0YTo6bWFwX2lkKHRyYl9pbnRlcnNlY3RfdGFibGUkc2FtcGxlMiwgZnJvbSA9ICJjb25kZW5zZWRfaWQiLCB0bz0icGF0aWVudF9pZCIsIGRiX3BhdGgpCgp0cmJfaW50ZXJzZWN0X3RhYmxlIDwtIHN1YnNldCh0cmJfaW50ZXJzZWN0X3RhYmxlLCBwYXRpZW50MSA9PSBwYXRpZW50MikKCmludGVyc2VjdF90YWJsZSA8LSB0cmJfaW50ZXJzZWN0X3RhYmxlCmNsb25vdHlwZV90YWJsZSA8LSBzdWJzZXQoeGNyX3RhYmxlLCB0eXBlID09ICJUUkIiKQpjbG9ub3R5cGVfY291bnRzIDwtIGNsb25vdHlwZV90YWJsZSAlPiUgZ3JvdXBfYnkoY29uZGVuc2VkX2lkLCBwYXRpZW50X2lkKSAlPiUgc3VtbWFyaXNlKG49bigpKSAlPiUgcGx5cjo6cmVuYW1lKGMoImNvbmRlbnNlZF9pZCI9ImxhYmVsIiwgIm4iPSJsZW4iKSkKYGBgCgpgYGB7cn0KcmVmb3JtYXRfYW5kcmV3X3RhYmxlIDwtIGZ1bmN0aW9uKGRhdCwgZGJfcGF0aCwgcGF0aWVudF9pZCkgewogIGRhdCRwYXRpZW50X2lkIDwtIHBhdGllbnRfaWQKICBkYXQgPC0gc3Vic2V0KGRhdCwgIXNhbXBsZV9pZCAlaW4lIGMoIlB2MiIsICJSZWMyIiwgIlJlYzMiKSkKICBkYXQgPC0gZGF0ICU+JSBwbHlyOjpyZW5hbWUoYygic2FtcGxlX2lkIj0icGxvdF9pZCIsICJsb25nX3NhbXBsZV9pZCI9InNhbXBsZV9pZCIpKQogIGRhdF9yZW1hcHBlZCA8LSBpdGhpLm1ldGE6OnJlbWFwX3NhbXBsZV9pZHMoZGF0LCBkYl9wYXRoKQogIGRhdF9yZW1hcHBlZCRhYmJyZXZfaWQgPC0gc3RyaW5ncjo6c3RyX2V4dHJhY3QoZGF0X3JlbWFwcGVkJGNvbmRlbnNlZF9pZCwgIltBLVphLXowLTldKyQiKQogIGRhdF9yZW1hcHBlZCA8LSBkYXRfcmVtYXBwZWQgJT4lIHBseXI6OnJlbmFtZShjKCJzYW1wbGVfaWQiPSJvbGRfc2FtcGxlX2lkIiwgInNhbXBsZV9rZXkiPSJsb25nX3NhbXBsZV9pZCIsICJwbG90X2lkIj0ib2xkX3Bsb3RfaWQiLCAiYWJicmV2X2lkIj0ic2FtcGxlX2lkIikpCiAgaWYgKCJsb2NhdGlvbl9pZCIgJWluJSBjb2xuYW1lcyhkYXRfcmVtYXBwZWQpKSB7CiAgICBkYXRfcmVtYXBwZWQkbG9jYXRpb25faWQgPC0gZGF0X3JlbWFwcGVkJHNhbXBsZV9pZAogIH0KICByZXR1cm4oZGF0X3JlbWFwcGVkKQp9CmBgYAoKIyMgUGxvdHMKCmBgYHtyfQpodG1sdG9vbHM6OnRhZ0xpc3QobGFwcGx5KG1hcHNjYXBlX2lucHV0X2RpcmVjdG9yaWVzLCBmdW5jdGlvbihkaXIpIHsKICBwYXRpZW50X2lkIDwtIHN0cmluZ3I6OnN0cl9leHRyYWN0KGRpciwgIlswLTldKyQiKQogIGRmIDwtIHN1YnNldChpbnRlcnNlY3RfdGFibGUsIHBhdGllbnQxID09IHBhdGllbnRfaWQpCiAgY2xvbmFsX3ByZXYgPSByZWFkLnRhYmxlKGZpbGUucGF0aChkaXIsICJjbG9uYWxfcHJldmFsZW5jZV90YWJsZS50c3YiKSwgc2VwPSdcdCcsIGhlYWRlcj1UKQogIHRyZWVfZWRnZXMgPSByZWFkLnRhYmxlKGZpbGUucGF0aChkaXIsICJ0cmVlX2VkZ2VzLnRzdiIpLCBzZXA9J1x0JywgaGVhZGVyPVQpCiAgc2FtcGxlX2xvY2F0aW9ucyA9IHJlYWQudGFibGUoZmlsZS5wYXRoKGRpciwgInNhbXBsZV9sb2NhdGlvbnMudHN2IiksIHNlcD0nXHQnLCBoZWFkZXI9VCkKICBzYW1wbGVfbG9jYXRpb25zJGxvbmdfc2FtcGxlX2lkIDwtIGRmX2FzX21hcChjbG9uYWxfcHJldiwgc2FtcGxlX2xvY2F0aW9ucyRzYW1wbGVfaWQsIGZyb20gPSAic2FtcGxlX2lkIiwgdG8gPSAibG9uZ19zYW1wbGVfaWQiKQogIAogIGNsb25hbF9wcmV2IDwtIHJlZm9ybWF0X2FuZHJld190YWJsZShjbG9uYWxfcHJldiwgZGJfcGF0aCwgcGF0aWVudF9pZCkKICBzYW1wbGVfbG9jYXRpb25zIDwtIHJlZm9ybWF0X2FuZHJld190YWJsZShzYW1wbGVfbG9jYXRpb25zLCBkYl9wYXRoLCBwYXRpZW50X2lkKQogIAogICNkZiA8LSBtZXJnZShkZiwgc3Vic2V0KGFuZHJld19tYXAsIHNlbGVjdD1jKHNhbXBsZV9rZXksIHNhbXBsZV9pZCkpLCBieS54PWMoInNhbXBsZTEiKSwgYnkueT1jKCJzYW1wbGVfa2V5IikpICU+JSBwbHlyOjpyZW5hbWUoYygic2FtcGxlX2lkIj0ic2FtcGxlX2lkMSIpKQogICNkZiA8LSBtZXJnZShkZiwgc3Vic2V0KGFuZHJld19tYXAsIHNlbGVjdD1jKHNhbXBsZV9rZXksIHNhbXBsZV9pZCkpLCBieS54PWMoInNhbXBsZTIiKSwgYnkueT1jKCJzYW1wbGVfa2V5IikpICU+JSBwbHlyOjpyZW5hbWUoYygic2FtcGxlX2lkIj0ic2FtcGxlX2lkMiIpKQogIAogIGNsb25vdHlwZV9jb3VudHNfc3ViIDwtIGNsb25vdHlwZV9jb3VudHNbYXMuY2hhcmFjdGVyKGNsb25vdHlwZV9jb3VudHMkcGF0aWVudF9pZCkgPT0gcGF0aWVudF9pZCxdCiAgCiAgcGF0aWVudF90bXAgPC0gcGF0aWVudF9pZAogIAogIGNsb25vdHlwZXNfc3ViIDwtIHhjcl90YWJsZVsoeGNyX3RhYmxlJHR5cGUgPT0gIlRSQiIpICYgKHhjcl90YWJsZSRwYXRpZW50X2lkID09IGFzLm51bWVyaWMocGF0aWVudF90bXApKSxdCiAgY2xvbm90eXBlc19zdWIkY29uZGVuc2VkX2lkIDwtIGZhY3RvcihjbG9ub3R5cGVzX3N1YiRjb25kZW5zZWRfaWQpCiAgY3Jvc3NfdGFibGUgPC0gaXRoaS54Y3I6OmNyb3NzX3RhYnVsYXRlKGNsb25vdHlwZXNfc3ViLCBpZF90eXBlID0gImNvbmRlbnNlZF9pZCIpCiAgCiAgI2RmJHNhbXBsZTEgPC0gZGYkc2FtcGxlX2lkMQogICNkZiRzYW1wbGUyIDwtIGRmJHNhbXBsZV9pZDIKICAKICBzYW1wbGVfaWRzIDwtIGludGVyc2VjdChjbG9uYWxfcHJldiRsb25nX3NhbXBsZV9pZCwgdW5pcXVlKGRmJHNhbXBsZTEpKQogIAogIGlmIChsZW5ndGgoc2FtcGxlX2lkcykgPT0gMCkgewogICAgcmV0dXJuKE5VTEwpCiAgfQogIAogIGRmIDwtIHN1YnNldChkZiwgKHNhbXBsZTEgJWluJSBzYW1wbGVfaWRzKSAmIChzYW1wbGUyICVpbiUgc2FtcGxlX2lkcykpCiAgZGYkc2FtcGxlMSA8LSBmYWN0b3IoZGYkc2FtcGxlMSwgbGV2ZWxzID0gc2FtcGxlX2lkcykKICBkZiRzYW1wbGUyIDwtIGZhY3RvcihkZiRzYW1wbGUyLCBsZXZlbHMgPSBzYW1wbGVfaWRzKQogIGRmIDwtIGRmW29yZGVyKGRmJHNhbXBsZTEpLF0KICAKICAjIyBJRiBZT1UgT05MWSBXQU5UIFRIRSBJTlRFUlNFQ1RJT04gVE8gQkUgU0hPV04sIEpVU1QgU0VUIENMT05PVFlQRSBUQUJMRSBUTyBOVUxMCiAgIyMgT3RoZXJ3aXNlIHNldCBpdCB0byBjbG9ub3R5cGVfY291bnRzX3N1YgogIGlmIChzaG93X2Z1bGxfdHJhY2spIHsKICAgIHJlcyA8LSBpdGhpLmZpZ3VyZXM6OmZvcm1hdF94Y3JjaXJjb3NfZGF0YShkZiwgY2xvbm90eXBlX2NvdW50cyA9IGNsb25vdHlwZV9jb3VudHNfc3ViLCBjcm9zc190YWJsZSA9IGNyb3NzX3RhYmxlKQogIH0gZWxzZSB7CiAgICByZXMgPC0gaXRoaS5maWd1cmVzOjpmb3JtYXRfeGNyY2lyY29zX2RhdGEoZGYsIGNsb25vdHlwZV9jb3VudHMgPSBOVUxMKQogIH0KICBjaG9yZF9kYXRhIDwtIHJlcyRjaG9yZHMKICB0cmFja19kYXRhIDwtIGFzLmRhdGEuZnJhbWUocmVzJHRyYWNrcykKICAKICByZXNpemVfZmFjdG9yIDwtIG1pbihzdW0odHJhY2tfZGF0YSRsZW4pL21heCh0cmFja19kYXRhJGxlbikgKiAxL25yb3codHJhY2tfZGF0YSksIDAuOSkKICAKICBjbG9uYWxfcHJldiA8LSBzdWJzZXQoY2xvbmFsX3ByZXYsIGxvbmdfc2FtcGxlX2lkICVpbiUgc2FtcGxlX2lkcykKICBzYW1wbGVfbG9jYXRpb25zIDwtIHN1YnNldChzYW1wbGVfbG9jYXRpb25zLCBzYW1wbGVfaWQgJWluJSBjbG9uYWxfcHJldiRzYW1wbGVfaWQpCiAgCiAgcHJpbnQocGF0aWVudF9pZCkKICBwbG90X3hjcm1hcHNjYXBlKGNsb25hbF9wcmV2LCBzYW1wbGVfbG9jYXRpb25zLCB0cmVlX2VkZ2VzLCBjaG9yZF9kYXRhID0gY2hvcmRfZGF0YSwgdHJhY2tfZGF0YSA9IHRyYWNrX2RhdGEsIHJlc2l6ZV9mYWN0b3IgPSByZXNpemVfZmFjdG9yKQp9KSkKYGBgCg==