1 load libraries

2 Load Object & Set RNA Assay

2.1 Add Standardized Cell Labels

# ── Borcherding ───────────────────────────────────────────────────────────────
borcherding$cell_label <- ifelse(
  borcherding$Disease_state == "Healthy",
  "Healthy CD4\u207A T",
  "SS Malignant"
)
borcherding$cell_label <- factor(borcherding$cell_label,
                                  levels = c("SS Malignant",
                                             "Healthy CD4\u207A T"))
borcherding$cohort <- "Borcherding et al., 2022"

# ── Herrera ───────────────────────────────────────────────────────────────────
herrera$cell_label <- ifelse(
  herrera$condition == "Healthy",
  "Healthy CD4\u207A T",
  "SS Malignant"
)
herrera$cell_label <- factor(herrera$cell_label,
                              levels = c("SS Malignant",
                                         "Healthy CD4\u207A T"))
herrera$cohort <- "Herrera et al., 2021"

cat("Borcherding labels:\n")
Borcherding labels:
print(table(borcherding$cell_label))

  SS Malignant Healthy CD4⁺ T 
         33393           4437 
cat("\nHerrera labels:\n")

Herrera labels:
print(table(herrera$cell_label))

  SS Malignant Healthy CD4⁺ T 
          6366           4419 

3 Extract CLIC1 Expression

df_borch <- FetchData(borcherding,
                      vars = c("CLIC1", "cell_label",
                               "cohort", "Disease_state")) %>%
            tibble::rownames_to_column("cell_id") %>%
            rename(group = Disease_state)

df_herr  <- FetchData(herrera,
                      vars = c("CLIC1", "cell_label",
                               "cohort", "condition")) %>%
            tibble::rownames_to_column("cell_id") %>%
            rename(group = condition)

# Combine
clic1_df <- rbind(df_borch, df_herr)

clic1_df$cohort <- factor(clic1_df$cohort,
                           levels = c("Herrera et al., 2021",
                                      "Borcherding et al., 2022"))

# Summary statistics
cat("=== CLIC1 Expression Summary ===\n")
=== CLIC1 Expression Summary ===
clic1_df %>%
  group_by(cohort, cell_label) %>%
  summarise(
    n      = n(),
    mean   = round(mean(CLIC1),   3),
    median = round(median(CLIC1), 3),
    .groups = "drop"
  ) %>%
  print()
# A tibble: 4 × 5
  cohort                   cell_label         n  mean median
  <fct>                    <fct>          <int> <dbl>  <dbl>
1 Herrera et al., 2021     SS Malignant    6366  1.74   1.88
2 Herrera et al., 2021     Healthy CD4⁺ T  4419  1.46   1.66
3 Borcherding et al., 2022 SS Malignant   33393  1.55   1.93
4 Borcherding et al., 2022 Healthy CD4⁺ T  4437  1.15   1.26

3.1 Helper: UMAP Centroid Function

# Computes median UMAP coordinates per cell_label group
get_centroids <- function(seurat_obj, reduction = "umap") {
  coords <- as.data.frame(
    Embeddings(seurat_obj, reduction = reduction)
  )
  colnames(coords) <- c("UMAP_1", "UMAP_2")
  coords$label <- seurat_obj$cell_label

  coords %>%
    group_by(label) %>%
    summarise(
      UMAP_1  = median(UMAP_1),
      UMAP_2  = median(UMAP_2),
      .groups = "drop"
    )
}

centroids_h <- get_centroids(herrera,     "umap")
centroids_b <- get_centroids(borcherding, "umap")

cat("Herrera centroids:\n");    print(centroids_h)
Herrera centroids:
# A tibble: 2 × 3
  label          UMAP_1 UMAP_2
  <fct>           <dbl>  <dbl>
1 SS Malignant   -2.18   2.94 
2 Healthy CD4⁺ T  0.903 -0.928
cat("\nBorcherding centroids:\n"); print(centroids_b)

Borcherding centroids:
# A tibble: 2 × 3
  label          UMAP_1  UMAP_2
  <fct>           <dbl>   <dbl>
1 SS Malignant     2.58 -0.0684
2 Healthy CD4⁺ T -10.6  -0.171 

3.2 Figure 7F — Main Combined Violin Plot1

my_colors <- c("SS Malignant"        = "#E64B35",
               "Healthy CD4\u207A T" = "#4DBBD5")

fig7F <- ggplot(clic1_df,
                aes(x = cell_label, y = CLIC1, fill = cell_label)) +

  geom_violin(trim      = TRUE,
              alpha     = 0.85,
              scale     = "width",
              color     = "grey30",
              linewidth = 0.4) +

  geom_boxplot(width         = 0.12,
               fill          = "white",
               color         = "grey20",
               outlier.size  = 0.3,
               outlier.alpha = 0.4,
               linewidth     = 0.5) +

  stat_compare_means(
    comparisons = list(c("SS Malignant", "Healthy CD4\u207A T")),
    method      = "wilcox.test",
    label       = "p.format",
    size        = 4,
    label.y.npc = 0.93
  ) +

  facet_wrap(~ cohort, scales = "free_y", nrow = 1) +

  scale_fill_manual(values = my_colors) +

  labs(
    title    = "CLIC1 Overexpression Validated Across Independent SS Cohorts",
    subtitle = "Wilcoxon rank-sum test | log-normalized expression",
    x        = "",
    y        = "CLIC1 Expression (log-normalized)"
  ) +

  theme_classic(base_size = 13) +
  theme(
    plot.title       = element_text(hjust = 0.5, face = "bold", size = 14),
    plot.subtitle    = element_text(hjust = 0.5, size = 10, color = "grey50"),
    strip.text       = element_text(face = "bold", size = 12),
    strip.background = element_rect(fill = "grey95", color = "grey70"),
    axis.text.x      = element_text(size = 11),
    axis.text.y      = element_text(size = 11),
    panel.spacing    = unit(1.5, "lines"),
    legend.position  = "none"
  )

fig7F

3.3 Figure 7F — Main Combined Violin Plot2

my_colors <- c("SS Malignant"        = "#E64B35",
               "Healthy CD4\u207A T" = "#4DBBD5")

fig7F <- ggplot(clic1_df,
                aes(x = cell_label, y = CLIC1, fill = cell_label)) +

  geom_violin(trim      = TRUE,
              alpha     = 0.85,
              scale     = "width",
              color     = "grey30",
              linewidth = 0.4) +

  geom_boxplot(width         = 0.12,
               fill          = "white",
               color         = "grey20",
               outlier.size  = 0.3,
               outlier.alpha = 0.4,
               linewidth     = 0.5) +

  stat_compare_means(
    comparisons = list(c("SS Malignant", "Healthy CD4\u207A T")),
    method      = "wilcox.test",
    label       = "p.format",
    size        = 4,
    label.y.npc = 0.93
  ) +

  facet_wrap(~ cohort, scales = "free_y", nrow = 1) +

  scale_fill_manual(values = my_colors) +

  labs(
    title    = "CLIC1 Overexpression Validated Across Independent SS Cohorts",
    subtitle = "Wilcoxon rank-sum test | log-normalized expression",
    x        = "",
    y        = "CLIC1 Expression (log-normalized)"
  ) +

  theme_classic(base_size = 13) +
  theme(
    plot.title       = element_text(hjust = 0.5, face = "bold", size = 14),
    plot.subtitle    = element_text(hjust = 0.5, size = 10,
                                    color = "grey50"),
    strip.text       = element_text(face = "bold", size = 12),
    strip.background = element_rect(fill = "grey95", color = "grey70"),
    axis.text.x      = element_text(size = 11),
    axis.text.y      = element_text(size = 11),
    panel.spacing    = unit(1.5, "lines"),
    legend.position  = "none"
  )

fig7F

3.4 UMAP FeaturePlots with SS/Healthy Labels

# ── Herrera ───────────────────────────────────────────────────────────────────
p_umap_h <- FeaturePlot(herrera,
                         features  = "CLIC1",
                         reduction = "umap",
                         order     = TRUE,
                         cols      = c("grey90", "#E64B35"),
                         pt.size   = 0.3) +

  geom_shadowtext(data        = centroids_h,
                  aes(x       = UMAP_1,
                      y       = UMAP_2,
                      label   = label),
                  color       = "black",
                  bg.color    = "white",
                  bg.r        = 0.15,
                  fontface    = "bold",
                  size        = 4,
                  inherit.aes = FALSE) +

  labs(title = "CLIC1 | Herrera et al., 2021") +
  theme(plot.title = element_text(hjust = 0.5, face = "bold", size = 12))

# ── Borcherding ───────────────────────────────────────────────────────────────
p_umap_b <- FeaturePlot(borcherding,
                         features  = "CLIC1",
                         reduction = "umap",
                         order     = TRUE,
                         cols      = c("grey90", "#E64B35"),
                         pt.size   = 0.3) +

  geom_shadowtext(data        = centroids_b,
                  aes(x       = UMAP_1,
                      y       = UMAP_2,
                      label   = label),
                  color       = "black",
                  bg.color    = "white",
                  bg.r        = 0.15,
                  fontface    = "bold",
                  size        = 4,
                  inherit.aes = FALSE) +

  labs(title = "CLIC1 | Borcherding et al., 2022") +
  theme(plot.title = element_text(hjust = 0.5, face = "bold", size = 12))

p_umap_h | p_umap_b

3.5 DimPlot — Cell Identity with Labels

p_dim_h <- DimPlot(herrera,
                    group.by  = "cell_label",
                    reduction = "umap",
                    cols      = my_colors,
                    pt.size   = 0.3,
                    label     = FALSE) +

  geom_shadowtext(data        = centroids_h,
                  aes(x       = UMAP_1,
                      y       = UMAP_2,
                      label   = label),
                  color       = "black",
                  bg.color    = "white",
                  bg.r        = 0.15,
                  fontface    = "bold",
                  size        = 4,
                  inherit.aes = FALSE) +

  labs(title = "Herrera et al., 2021") +
  theme(plot.title    = element_text(hjust = 0.5, face = "bold"),
        legend.position = "none")

p_dim_b <- DimPlot(borcherding,
                    group.by  = "cell_label",
                    reduction = "umap",
                    cols      = my_colors,
                    pt.size   = 0.3,
                    label     = FALSE) +

  geom_shadowtext(data        = centroids_b,
                  aes(x       = UMAP_1,
                      y       = UMAP_2,
                      label   = label),
                  color       = "black",
                  bg.color    = "white",
                  bg.r        = 0.15,
                  fontface    = "bold",
                  size        = 4,
                  inherit.aes = FALSE) +

  labs(title = "Borcherding et al., 2022") +
  theme(plot.title    = element_text(hjust = 0.5, face = "bold"),
        legend.position = "none")

p_dim_h | p_dim_b

3.6 Full Publication Figure

full_fig <- (p_dim_h | p_dim_b) /
            (p_umap_h | p_umap_b) /
            fig7F +

  plot_layout(heights = c(1, 1, 1.2)) +

  plot_annotation(
    title      = "CLIC1 Overexpression Validated in Two Independent SS Cohorts",
    tag_levels = "A",
    theme      = theme(
      plot.title = element_text(hjust = 0.5, face = "bold", size = 15)
    )
  )

full_fig

4 Save Figures

dir.create("output", showWarnings = FALSE)

ggsave("output/Figure7F_CLIC1_violin_combined.pdf",
       plot = fig7F, width = 10, height = 5, dpi = 300)
ggsave("output/Figure7F_CLIC1_violin_combined.png",
       plot = fig7F, width = 10, height = 5, dpi = 300)

ggsave("output/Figure7F_CLIC1_UMAP_labeled.pdf",
       plot = p_umap_h | p_umap_b,
       width = 14, height = 5, dpi = 300)
ggsave("output/Figure7F_CLIC1_UMAP_labeled.png",
       plot = p_umap_h | p_umap_b,
       width = 14, height = 5, dpi = 300)

ggsave("output/Figure7F_DimPlot_labeled.pdf",
       plot = p_dim_h | p_dim_b,
       width = 14, height = 5, dpi = 300)
ggsave("output/Figure7F_DimPlot_labeled.png",
       plot = p_dim_h | p_dim_b,
       width = 14, height = 5, dpi = 300)

ggsave("output/Figure7F_full_figure.pdf",
       plot = full_fig, width = 14, height = 14, dpi = 300)
ggsave("output/Figure7F_full_figure.png",
       plot = full_fig, width = 14, height = 14, dpi = 300)

cat("All figures saved to output/\n")
All figures saved to output/

5 Session Info

sessionInfo()
R version 4.5.2 (2025-10-31)
Platform: x86_64-pc-linux-gnu
Running under: Ubuntu 24.04.3 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.12.0 
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.12.0  LAPACK version 3.12.0

locale:
 [1] LC_CTYPE=en_GB.UTF-8       LC_NUMERIC=C               LC_TIME=fr_FR.UTF-8       
 [4] LC_COLLATE=en_GB.UTF-8     LC_MONETARY=fr_FR.UTF-8    LC_MESSAGES=en_GB.UTF-8   
 [7] LC_PAPER=fr_FR.UTF-8       LC_NAME=C                  LC_ADDRESS=C              
[10] LC_TELEPHONE=C             LC_MEASUREMENT=fr_FR.UTF-8 LC_IDENTIFICATION=C       

time zone: Europe/Paris
tzcode source: system (glibc)

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] shadowtext_0.1.6   patchwork_1.3.2    dplyr_1.2.0        ggpubr_0.6.2      
[5] ggplot2_4.0.2      Seurat_5.4.0       SeuratObject_5.3.0 sp_2.2-1          

loaded via a namespace (and not attached):
  [1] RColorBrewer_1.1-3      rstudioapi_0.18.0       jsonlite_2.0.0         
  [4] magrittr_2.0.4          spatstat.utils_3.2-1    farver_2.1.2           
  [7] ragg_1.5.0              vctrs_0.7.1             ROCR_1.0-12            
 [10] spatstat.explore_3.7-0  rstatix_0.7.3           htmltools_0.5.9        
 [13] broom_1.0.12            Formula_1.2-5           sctransform_0.4.3      
 [16] parallelly_1.46.1       KernSmooth_2.23-26      htmlwidgets_1.6.4      
 [19] ica_1.0-3               plyr_1.8.9              plotly_4.12.0          
 [22] zoo_1.8-15              igraph_2.2.2            mime_0.13              
 [25] lifecycle_1.0.5         pkgconfig_2.0.3         Matrix_1.7-4           
 [28] R6_2.6.1                fastmap_1.2.0           fitdistrplus_1.2-6     
 [31] future_1.69.0           shiny_1.12.1            digest_0.6.39          
 [34] tensor_1.5.1            RSpectra_0.16-2         irlba_2.3.7            
 [37] textshaping_1.0.4       labeling_0.4.3          progressr_0.18.0       
 [40] spatstat.sparse_3.1-0   httr_1.4.7              polyclip_1.10-7        
 [43] abind_1.4-8             compiler_4.5.2          fontquiver_0.2.1       
 [46] withr_3.0.2             S7_0.2.1                backports_1.5.0        
 [49] carData_3.0-6           fastDummies_1.7.5       ggsignif_0.6.4         
 [52] MASS_7.3-65             tools_4.5.2             lmtest_0.9-40          
 [55] otel_0.2.0              httpuv_1.6.16           future.apply_1.20.1    
 [58] goftest_1.2-3           glue_1.8.0              nlme_3.1-168           
 [61] promises_1.5.0          grid_4.5.2              Rtsne_0.17             
 [64] cluster_2.1.8.2         reshape2_1.4.5          generics_0.1.4         
 [67] gtable_0.3.6            spatstat.data_3.1-9     tidyr_1.3.2            
 [70] data.table_1.18.2.1     car_3.1-5               utf8_1.2.6             
 [73] spatstat.geom_3.7-0     RcppAnnoy_0.0.23        ggrepel_0.9.6          
 [76] RANN_2.6.2              pillar_1.11.1           stringr_1.6.0          
 [79] spam_2.11-3             RcppHNSW_0.6.0          later_1.4.5            
 [82] splines_4.5.2           lattice_0.22-9          survival_3.8-3         
 [85] deldir_2.0-4            tidyselect_1.2.1        fontLiberation_0.1.0   
 [88] miniUI_0.1.2            pbapply_1.7-4           knitr_1.51             
 [91] fontBitstreamVera_0.1.1 gridExtra_2.3           scattermore_1.2        
 [94] xfun_0.56               matrixStats_1.5.0       stringi_1.8.7          
 [97] lazyeval_0.2.2          evaluate_1.0.5          codetools_0.2-20       
[100] gdtools_0.5.0           tibble_3.3.1            cli_3.6.5              
[103] uwot_0.2.4              systemfonts_1.3.1       xtable_1.8-4           
[106] reticulate_1.44.1       dichromat_2.0-0.1       Rcpp_1.1.1             
[109] globals_0.19.0          spatstat.random_3.4-4   png_0.1-8              
[112] spatstat.univar_3.1-6   parallel_4.5.2          dotCall64_1.2          
[115] listenv_0.10.0          viridisLite_0.4.3       ggiraph_0.9.4          
[118] scales_1.4.0            ggridges_0.5.7          purrr_1.2.1            
[121] rlang_1.1.7             cowplot_1.2.0          
LS0tCnRpdGxlOiAiRmlndXJlIDdGIC0gQ0xJQzEgVmFsaWRhdGlvbiB8IEJvcmNoZXJkaW5nIDIwMjIgJiBIZXJyZXJhIDIwMjEiCmF1dGhvcjogTmFzaXIgTWFobW9vZCBBYmJhc2kKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIGNzczogc3R5bGUuY3NzCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IHRydWUKICAgIHRoZW1lOiBqb3VybmFsCi0tLQoKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgZWNobyAgICAgICA9IFRSVUUsCiAgd2FybmluZyAgICA9IEZBTFNFLAogIG1lc3NhZ2UgICAgPSBGQUxTRSwKICBmaWcud2lkdGggID0gMTAsCiAgZmlnLmhlaWdodCA9IDYsCiAgZHBpICAgICAgICA9IDMwMAopCmBgYAoKCgoKIyBsb2FkIGxpYnJhcmllcwpgYGB7ciAsIGluY2x1ZGU9RkFMU0V9CgpsaWJyYXJ5KFNldXJhdCkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdncHVicikKbGlicmFyeShkcGx5cikKbGlicmFyeShwYXRjaHdvcmspCmxpYnJhcnkoc2hhZG93dGV4dCkgICAjIGZvciB3aGl0ZS1vdXRsaW5lZCBsYWJlbHMgb24gVU1BUAoKYGBgCgoKIyBMb2FkIE9iamVjdCAmIFNldCBSTkEgQXNzYXkKYGBge3IgLCBpbmNsdWRlPUZBTFNFfQoKYm9yY2hlcmRpbmcgPC0gcmVhZFJEUygiL2hvbWUvYmlvaW5mby8xLVRoZXNpc19GaW5hbF9ZZWFyXzIwMjUvMjAyNS1ZZWFyM19BbmFseXNpcy8xLXNjUk5BX1JFU1VMVFMtMTktMTEtMjAyNS8xLUJpb21hcmtlcnNfVmFsaWRhdGlvbl93aXRoX1B1YmxpY19EYXRhLUF1Z3VzdDIwMjUvQm9yY2hfQ29tYmluZWQvZGF0YS9TZXphcnlfU1NfdnNfSENfX0JvcmNoZXJkaW5nMjAyM19UQ1JfZmlsdGVyZWQucmRzIikKCmhlcnJlcmEgICAgIDwtIHJlYWRSRFMoIi9ob21lL2Jpb2luZm8vMS1UaGVzaXNfRmluYWxfWWVhcl8yMDI1LzIwMjUtWWVhcjNfQW5hbHlzaXMvMS1zY1JOQV9SRVNVTFRTLTE5LTExLTIwMjUvMS1CaW9tYXJrZXJzX1ZhbGlkYXRpb25fd2l0aF9QdWJsaWNfRGF0YS1BdWd1c3QyMDI1L0hlcnJlcmFfRGF0YS9IZXJyYXJhX1RDUl9BQi9BbmFseXNpcy9TZXphcnlfQmxvb2RfU2tpbl92c19IQ19UQ1JfZmlsdGVyZWQucmRzIikKCiMg4pSA4pSAIFJOQSBhc3NheSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKRGVmYXVsdEFzc2F5KGJvcmNoZXJkaW5nKSA8LSAiUk5BIgpEZWZhdWx0QXNzYXkoaGVycmVyYSkgICAgIDwtICJSTkEiCgojIOKUgOKUgCBKb2luIGxheWVycyAoU2V1cmF0IHY1KSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKYm9yY2hlcmRpbmcgPC0gSm9pbkxheWVycyhib3JjaGVyZGluZykKaGVycmVyYSAgICAgPC0gSm9pbkxheWVycyhoZXJyZXJhKQoKY2F0KCJCb3JjaGVyZGluZyDigJQgQ2VsbHM6IiwgbmNvbChib3JjaGVyZGluZyksICJcbiIpCnByaW50KHRhYmxlKGJvcmNoZXJkaW5nJERpc2Vhc2Vfc3RhdGUpKQoKY2F0KCJcbkhlcnJlcmEg4oCUIENlbGxzOiIsIG5jb2woaGVycmVyYSksICJcbiIpCnByaW50KHRhYmxlKGhlcnJlcmEkY29uZGl0aW9uKSkKCmNhdCgiXG5DTElDMSBpbiBCb3JjaGVyZGluZzoiLCAiQ0xJQzEiICVpbiUgcm93bmFtZXMoYm9yY2hlcmRpbmcpLCAiXG4iKQpjYXQoIkNMSUMxIGluIEhlcnJlcmE6ICAgICIsICJDTElDMSIgJWluJSByb3duYW1lcyhoZXJyZXJhKSwgICAgICJcbiIpCmBgYAoKCgoKCgojIyBBZGQgU3RhbmRhcmRpemVkIENlbGwgTGFiZWxzCmBgYHtyIHBhdGhzfQojIOKUgOKUgCBCb3JjaGVyZGluZyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKYm9yY2hlcmRpbmckY2VsbF9sYWJlbCA8LSBpZmVsc2UoCiAgYm9yY2hlcmRpbmckRGlzZWFzZV9zdGF0ZSA9PSAiSGVhbHRoeSIsCiAgIkhlYWx0aHkgQ0Q0XHUyMDdBIFQiLAogICJTUyBNYWxpZ25hbnQiCikKYm9yY2hlcmRpbmckY2VsbF9sYWJlbCA8LSBmYWN0b3IoYm9yY2hlcmRpbmckY2VsbF9sYWJlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIlNTIE1hbGlnbmFudCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJIZWFsdGh5IENENFx1MjA3QSBUIikpCmJvcmNoZXJkaW5nJGNvaG9ydCA8LSAiQm9yY2hlcmRpbmcgZXQgYWwuLCAyMDIyIgoKIyDilIDilIAgSGVycmVyYSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKaGVycmVyYSRjZWxsX2xhYmVsIDwtIGlmZWxzZSgKICBoZXJyZXJhJGNvbmRpdGlvbiA9PSAiSGVhbHRoeSIsCiAgIkhlYWx0aHkgQ0Q0XHUyMDdBIFQiLAogICJTUyBNYWxpZ25hbnQiCikKaGVycmVyYSRjZWxsX2xhYmVsIDwtIGZhY3RvcihoZXJyZXJhJGNlbGxfbGFiZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIlNTIE1hbGlnbmFudCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkhlYWx0aHkgQ0Q0XHUyMDdBIFQiKSkKaGVycmVyYSRjb2hvcnQgPC0gIkhlcnJlcmEgZXQgYWwuLCAyMDIxIgoKY2F0KCJCb3JjaGVyZGluZyBsYWJlbHM6XG4iKQpwcmludCh0YWJsZShib3JjaGVyZGluZyRjZWxsX2xhYmVsKSkKY2F0KCJcbkhlcnJlcmEgbGFiZWxzOlxuIikKcHJpbnQodGFibGUoaGVycmVyYSRjZWxsX2xhYmVsKSkKYGBgCgojIEV4dHJhY3QgQ0xJQzEgRXhwcmVzc2lvbgpgYGB7ciAsIG1lc3NhZ2U9RkFMU0V9CmRmX2JvcmNoIDwtIEZldGNoRGF0YShib3JjaGVyZGluZywKICAgICAgICAgICAgICAgICAgICAgIHZhcnMgPSBjKCJDTElDMSIsICJjZWxsX2xhYmVsIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb2hvcnQiLCAiRGlzZWFzZV9zdGF0ZSIpKSAlPiUKICAgICAgICAgICAgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oImNlbGxfaWQiKSAlPiUKICAgICAgICAgICAgcmVuYW1lKGdyb3VwID0gRGlzZWFzZV9zdGF0ZSkKCmRmX2hlcnIgIDwtIEZldGNoRGF0YShoZXJyZXJhLAogICAgICAgICAgICAgICAgICAgICAgdmFycyA9IGMoIkNMSUMxIiwgImNlbGxfbGFiZWwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvaG9ydCIsICJjb25kaXRpb24iKSkgJT4lCiAgICAgICAgICAgIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKCJjZWxsX2lkIikgJT4lCiAgICAgICAgICAgIHJlbmFtZShncm91cCA9IGNvbmRpdGlvbikKCiMgQ29tYmluZQpjbGljMV9kZiA8LSByYmluZChkZl9ib3JjaCwgZGZfaGVycikKCmNsaWMxX2RmJGNvaG9ydCA8LSBmYWN0b3IoY2xpYzFfZGYkY29ob3J0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJIZXJyZXJhIGV0IGFsLiwgMjAyMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkJvcmNoZXJkaW5nIGV0IGFsLiwgMjAyMiIpKQoKIyBTdW1tYXJ5IHN0YXRpc3RpY3MKY2F0KCI9PT0gQ0xJQzEgRXhwcmVzc2lvbiBTdW1tYXJ5ID09PVxuIikKY2xpYzFfZGYgJT4lCiAgZ3JvdXBfYnkoY29ob3J0LCBjZWxsX2xhYmVsKSAlPiUKICBzdW1tYXJpc2UoCiAgICBuICAgICAgPSBuKCksCiAgICBtZWFuICAgPSByb3VuZChtZWFuKENMSUMxKSwgICAzKSwKICAgIG1lZGlhbiA9IHJvdW5kKG1lZGlhbihDTElDMSksIDMpLAogICAgLmdyb3VwcyA9ICJkcm9wIgogICkgJT4lCiAgcHJpbnQoKQoKYGBgCgojIyBIZWxwZXI6IFVNQVAgQ2VudHJvaWQgRnVuY3Rpb24KYGBge3IgLCBtZXNzYWdlPUZBTFNFfQojIENvbXB1dGVzIG1lZGlhbiBVTUFQIGNvb3JkaW5hdGVzIHBlciBjZWxsX2xhYmVsIGdyb3VwCmdldF9jZW50cm9pZHMgPC0gZnVuY3Rpb24oc2V1cmF0X29iaiwgcmVkdWN0aW9uID0gInVtYXAiKSB7CiAgY29vcmRzIDwtIGFzLmRhdGEuZnJhbWUoCiAgICBFbWJlZGRpbmdzKHNldXJhdF9vYmosIHJlZHVjdGlvbiA9IHJlZHVjdGlvbikKICApCiAgY29sbmFtZXMoY29vcmRzKSA8LSBjKCJVTUFQXzEiLCAiVU1BUF8yIikKICBjb29yZHMkbGFiZWwgPC0gc2V1cmF0X29iaiRjZWxsX2xhYmVsCgogIGNvb3JkcyAlPiUKICAgIGdyb3VwX2J5KGxhYmVsKSAlPiUKICAgIHN1bW1hcmlzZSgKICAgICAgVU1BUF8xICA9IG1lZGlhbihVTUFQXzEpLAogICAgICBVTUFQXzIgID0gbWVkaWFuKFVNQVBfMiksCiAgICAgIC5ncm91cHMgPSAiZHJvcCIKICAgICkKfQoKY2VudHJvaWRzX2ggPC0gZ2V0X2NlbnRyb2lkcyhoZXJyZXJhLCAgICAgInVtYXAiKQpjZW50cm9pZHNfYiA8LSBnZXRfY2VudHJvaWRzKGJvcmNoZXJkaW5nLCAidW1hcCIpCgpjYXQoIkhlcnJlcmEgY2VudHJvaWRzOlxuIik7ICAgIHByaW50KGNlbnRyb2lkc19oKQpjYXQoIlxuQm9yY2hlcmRpbmcgY2VudHJvaWRzOlxuIik7IHByaW50KGNlbnRyb2lkc19iKQoKYGBgCgojIyBGaWd1cmUgN0Yg4oCUIE1haW4gQ29tYmluZWQgVmlvbGluIFBsb3QxCmBgYHtyICwgbWVzc2FnZT1GQUxTRX0KbXlfY29sb3JzIDwtIGMoIlNTIE1hbGlnbmFudCIgICAgICAgID0gIiNFNjRCMzUiLAogICAgICAgICAgICAgICAiSGVhbHRoeSBDRDRcdTIwN0EgVCIgPSAiIzREQkJENSIpCgpmaWc3RiA8LSBnZ3Bsb3QoY2xpYzFfZGYsCiAgICAgICAgICAgICAgICBhZXMoeCA9IGNlbGxfbGFiZWwsIHkgPSBDTElDMSwgZmlsbCA9IGNlbGxfbGFiZWwpKSArCgogIGdlb21fdmlvbGluKHRyaW0gICAgICA9IFRSVUUsCiAgICAgICAgICAgICAgYWxwaGEgICAgID0gMC44NSwKICAgICAgICAgICAgICBzY2FsZSAgICAgPSAid2lkdGgiLAogICAgICAgICAgICAgIGNvbG9yICAgICA9ICJncmV5MzAiLAogICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDAuNCkgKwoKICBnZW9tX2JveHBsb3Qod2lkdGggICAgICAgICA9IDAuMTIsCiAgICAgICAgICAgICAgIGZpbGwgICAgICAgICAgPSAid2hpdGUiLAogICAgICAgICAgICAgICBjb2xvciAgICAgICAgID0gImdyZXkyMCIsCiAgICAgICAgICAgICAgIG91dGxpZXIuc2l6ZSAgPSAwLjMsCiAgICAgICAgICAgICAgIG91dGxpZXIuYWxwaGEgPSAwLjQsCiAgICAgICAgICAgICAgIGxpbmV3aWR0aCAgICAgPSAwLjUpICsKCiAgc3RhdF9jb21wYXJlX21lYW5zKAogICAgY29tcGFyaXNvbnMgPSBsaXN0KGMoIlNTIE1hbGlnbmFudCIsICJIZWFsdGh5IENENFx1MjA3QSBUIikpLAogICAgbWV0aG9kICAgICAgPSAid2lsY294LnRlc3QiLAogICAgbGFiZWwgICAgICAgPSAicC5mb3JtYXQiLAogICAgc2l6ZSAgICAgICAgPSA0LAogICAgbGFiZWwueS5ucGMgPSAwLjkzCiAgKSArCgogIGZhY2V0X3dyYXAofiBjb2hvcnQsIHNjYWxlcyA9ICJmcmVlX3kiLCBucm93ID0gMSkgKwoKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBteV9jb2xvcnMpICsKCiAgbGFicygKICAgIHRpdGxlICAgID0gIkNMSUMxIE92ZXJleHByZXNzaW9uIFZhbGlkYXRlZCBBY3Jvc3MgSW5kZXBlbmRlbnQgU1MgQ29ob3J0cyIsCiAgICBzdWJ0aXRsZSA9ICJXaWxjb3hvbiByYW5rLXN1bSB0ZXN0IHwgbG9nLW5vcm1hbGl6ZWQgZXhwcmVzc2lvbiIsCiAgICB4ICAgICAgICA9ICIiLAogICAgeSAgICAgICAgPSAiQ0xJQzEgRXhwcmVzc2lvbiAobG9nLW5vcm1hbGl6ZWQpIgogICkgKwoKICB0aGVtZV9jbGFzc2ljKGJhc2Vfc2l6ZSA9IDEzKSArCiAgdGhlbWUoCiAgICBwbG90LnRpdGxlICAgICAgID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiLCBzaXplID0gMTQpLAogICAgcGxvdC5zdWJ0aXRsZSAgICA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgc2l6ZSA9IDEwLCBjb2xvciA9ICJncmV5NTAiKSwKICAgIHN0cmlwLnRleHQgICAgICAgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDEyKSwKICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJncmV5OTUiLCBjb2xvciA9ICJncmV5NzAiKSwKICAgIGF4aXMudGV4dC54ICAgICAgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExKSwKICAgIGF4aXMudGV4dC55ICAgICAgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExKSwKICAgIHBhbmVsLnNwYWNpbmcgICAgPSB1bml0KDEuNSwgImxpbmVzIiksCiAgICBsZWdlbmQucG9zaXRpb24gID0gIm5vbmUiCiAgKQoKZmlnN0YKCmBgYAoKIyMgRmlndXJlIDdGIOKAlCBNYWluIENvbWJpbmVkIFZpb2xpbiBQbG90MgpgYGB7ciAsIG1lc3NhZ2U9RkFMU0V9Cm15X2NvbG9ycyA8LSBjKCJTUyBNYWxpZ25hbnQiICAgICAgICA9ICIjRTY0QjM1IiwKICAgICAgICAgICAgICAgIkhlYWx0aHkgQ0Q0XHUyMDdBIFQiID0gIiM0REJCRDUiKQoKZmlnN0YgPC0gZ2dwbG90KGNsaWMxX2RmLAogICAgICAgICAgICAgICAgYWVzKHggPSBjZWxsX2xhYmVsLCB5ID0gQ0xJQzEsIGZpbGwgPSBjZWxsX2xhYmVsKSkgKwoKICBnZW9tX3Zpb2xpbih0cmltICAgICAgPSBUUlVFLAogICAgICAgICAgICAgIGFscGhhICAgICA9IDAuODUsCiAgICAgICAgICAgICAgc2NhbGUgICAgID0gIndpZHRoIiwKICAgICAgICAgICAgICBjb2xvciAgICAgPSAiZ3JleTMwIiwKICAgICAgICAgICAgICBsaW5ld2lkdGggPSAwLjQpICsKCiAgZ2VvbV9ib3hwbG90KHdpZHRoICAgICAgICAgPSAwLjEyLAogICAgICAgICAgICAgICBmaWxsICAgICAgICAgID0gIndoaXRlIiwKICAgICAgICAgICAgICAgY29sb3IgICAgICAgICA9ICJncmV5MjAiLAogICAgICAgICAgICAgICBvdXRsaWVyLnNpemUgID0gMC4zLAogICAgICAgICAgICAgICBvdXRsaWVyLmFscGhhID0gMC40LAogICAgICAgICAgICAgICBsaW5ld2lkdGggICAgID0gMC41KSArCgogIHN0YXRfY29tcGFyZV9tZWFucygKICAgIGNvbXBhcmlzb25zID0gbGlzdChjKCJTUyBNYWxpZ25hbnQiLCAiSGVhbHRoeSBDRDRcdTIwN0EgVCIpKSwKICAgIG1ldGhvZCAgICAgID0gIndpbGNveC50ZXN0IiwKICAgIGxhYmVsICAgICAgID0gInAuZm9ybWF0IiwKICAgIHNpemUgICAgICAgID0gNCwKICAgIGxhYmVsLnkubnBjID0gMC45MwogICkgKwoKICBmYWNldF93cmFwKH4gY29ob3J0LCBzY2FsZXMgPSAiZnJlZV95IiwgbnJvdyA9IDEpICsKCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbXlfY29sb3JzKSArCgogIGxhYnMoCiAgICB0aXRsZSAgICA9ICJDTElDMSBPdmVyZXhwcmVzc2lvbiBWYWxpZGF0ZWQgQWNyb3NzIEluZGVwZW5kZW50IFNTIENvaG9ydHMiLAogICAgc3VidGl0bGUgPSAiV2lsY294b24gcmFuay1zdW0gdGVzdCB8IGxvZy1ub3JtYWxpemVkIGV4cHJlc3Npb24iLAogICAgeCAgICAgICAgPSAiIiwKICAgIHkgICAgICAgID0gIkNMSUMxIEV4cHJlc3Npb24gKGxvZy1ub3JtYWxpemVkKSIKICApICsKCiAgdGhlbWVfY2xhc3NpYyhiYXNlX3NpemUgPSAxMykgKwogIHRoZW1lKAogICAgcGxvdC50aXRsZSAgICAgICA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE0KSwKICAgIHBsb3Quc3VidGl0bGUgICAgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIHNpemUgPSAxMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAiZ3JleTUwIiksCiAgICBzdHJpcC50ZXh0ICAgICAgID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxMiksCiAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiZ3JleTk1IiwgY29sb3IgPSAiZ3JleTcwIiksCiAgICBheGlzLnRleHQueCAgICAgID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSksCiAgICBheGlzLnRleHQueSAgICAgID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSksCiAgICBwYW5lbC5zcGFjaW5nICAgID0gdW5pdCgxLjUsICJsaW5lcyIpLAogICAgbGVnZW5kLnBvc2l0aW9uICA9ICJub25lIgogICkKCmZpZzdGCgpgYGAKCgojIyAgVU1BUCBGZWF0dXJlUGxvdHMgd2l0aCBTUy9IZWFsdGh5IExhYmVscwpgYGB7ciAsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTE0fQojIOKUgOKUgCBIZXJyZXJhIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgApwX3VtYXBfaCA8LSBGZWF0dXJlUGxvdChoZXJyZXJhLAogICAgICAgICAgICAgICAgICAgICAgICAgZmVhdHVyZXMgID0gIkNMSUMxIiwKICAgICAgICAgICAgICAgICAgICAgICAgIHJlZHVjdGlvbiA9ICJ1bWFwIiwKICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyICAgICA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICBjb2xzICAgICAgPSBjKCJncmV5OTAiLCAiI0U2NEIzNSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgcHQuc2l6ZSAgID0gMC4zKSArCgogIGdlb21fc2hhZG93dGV4dChkYXRhICAgICAgICA9IGNlbnRyb2lkc19oLAogICAgICAgICAgICAgICAgICBhZXMoeCAgICAgICA9IFVNQVBfMSwKICAgICAgICAgICAgICAgICAgICAgIHkgICAgICAgPSBVTUFQXzIsCiAgICAgICAgICAgICAgICAgICAgICBsYWJlbCAgID0gbGFiZWwpLAogICAgICAgICAgICAgICAgICBjb2xvciAgICAgICA9ICJibGFjayIsCiAgICAgICAgICAgICAgICAgIGJnLmNvbG9yICAgID0gIndoaXRlIiwKICAgICAgICAgICAgICAgICAgYmcuciAgICAgICAgPSAwLjE1LAogICAgICAgICAgICAgICAgICBmb250ZmFjZSAgICA9ICJib2xkIiwKICAgICAgICAgICAgICAgICAgc2l6ZSAgICAgICAgPSA0LAogICAgICAgICAgICAgICAgICBpbmhlcml0LmFlcyA9IEZBTFNFKSArCgogIGxhYnModGl0bGUgPSAiQ0xJQzEgfCBIZXJyZXJhIGV0IGFsLiwgMjAyMSIpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiLCBzaXplID0gMTIpKQoKIyDilIDilIAgQm9yY2hlcmRpbmcg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACnBfdW1hcF9iIDwtIEZlYXR1cmVQbG90KGJvcmNoZXJkaW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgZmVhdHVyZXMgID0gIkNMSUMxIiwKICAgICAgICAgICAgICAgICAgICAgICAgIHJlZHVjdGlvbiA9ICJ1bWFwIiwKICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyICAgICA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICBjb2xzICAgICAgPSBjKCJncmV5OTAiLCAiI0U2NEIzNSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgcHQuc2l6ZSAgID0gMC4zKSArCgogIGdlb21fc2hhZG93dGV4dChkYXRhICAgICAgICA9IGNlbnRyb2lkc19iLAogICAgICAgICAgICAgICAgICBhZXMoeCAgICAgICA9IFVNQVBfMSwKICAgICAgICAgICAgICAgICAgICAgIHkgICAgICAgPSBVTUFQXzIsCiAgICAgICAgICAgICAgICAgICAgICBsYWJlbCAgID0gbGFiZWwpLAogICAgICAgICAgICAgICAgICBjb2xvciAgICAgICA9ICJibGFjayIsCiAgICAgICAgICAgICAgICAgIGJnLmNvbG9yICAgID0gIndoaXRlIiwKICAgICAgICAgICAgICAgICAgYmcuciAgICAgICAgPSAwLjE1LAogICAgICAgICAgICAgICAgICBmb250ZmFjZSAgICA9ICJib2xkIiwKICAgICAgICAgICAgICAgICAgc2l6ZSAgICAgICAgPSA0LAogICAgICAgICAgICAgICAgICBpbmhlcml0LmFlcyA9IEZBTFNFKSArCgogIGxhYnModGl0bGUgPSAiQ0xJQzEgfCBCb3JjaGVyZGluZyBldCBhbC4sIDIwMjIiKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDEyKSkKCnBfdW1hcF9oIHwgcF91bWFwX2IKCmBgYAoKCgoKIyMgIERpbVBsb3Qg4oCUIENlbGwgSWRlbnRpdHkgd2l0aCBMYWJlbHMKYGBge3IgLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xNH0KcF9kaW1faCA8LSBEaW1QbG90KGhlcnJlcmEsCiAgICAgICAgICAgICAgICAgICAgZ3JvdXAuYnkgID0gImNlbGxfbGFiZWwiLAogICAgICAgICAgICAgICAgICAgIHJlZHVjdGlvbiA9ICJ1bWFwIiwKICAgICAgICAgICAgICAgICAgICBjb2xzICAgICAgPSBteV9jb2xvcnMsCiAgICAgICAgICAgICAgICAgICAgcHQuc2l6ZSAgID0gMC4zLAogICAgICAgICAgICAgICAgICAgIGxhYmVsICAgICA9IEZBTFNFKSArCgogIGdlb21fc2hhZG93dGV4dChkYXRhICAgICAgICA9IGNlbnRyb2lkc19oLAogICAgICAgICAgICAgICAgICBhZXMoeCAgICAgICA9IFVNQVBfMSwKICAgICAgICAgICAgICAgICAgICAgIHkgICAgICAgPSBVTUFQXzIsCiAgICAgICAgICAgICAgICAgICAgICBsYWJlbCAgID0gbGFiZWwpLAogICAgICAgICAgICAgICAgICBjb2xvciAgICAgICA9ICJibGFjayIsCiAgICAgICAgICAgICAgICAgIGJnLmNvbG9yICAgID0gIndoaXRlIiwKICAgICAgICAgICAgICAgICAgYmcuciAgICAgICAgPSAwLjE1LAogICAgICAgICAgICAgICAgICBmb250ZmFjZSAgICA9ICJib2xkIiwKICAgICAgICAgICAgICAgICAgc2l6ZSAgICAgICAgPSA0LAogICAgICAgICAgICAgICAgICBpbmhlcml0LmFlcyA9IEZBTFNFKSArCgogIGxhYnModGl0bGUgPSAiSGVycmVyYSBldCBhbC4sIDIwMjEiKSArCiAgdGhlbWUocGxvdC50aXRsZSAgICA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIiksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQoKcF9kaW1fYiA8LSBEaW1QbG90KGJvcmNoZXJkaW5nLAogICAgICAgICAgICAgICAgICAgIGdyb3VwLmJ5ICA9ICJjZWxsX2xhYmVsIiwKICAgICAgICAgICAgICAgICAgICByZWR1Y3Rpb24gPSAidW1hcCIsCiAgICAgICAgICAgICAgICAgICAgY29scyAgICAgID0gbXlfY29sb3JzLAogICAgICAgICAgICAgICAgICAgIHB0LnNpemUgICA9IDAuMywKICAgICAgICAgICAgICAgICAgICBsYWJlbCAgICAgPSBGQUxTRSkgKwoKICBnZW9tX3NoYWRvd3RleHQoZGF0YSAgICAgICAgPSBjZW50cm9pZHNfYiwKICAgICAgICAgICAgICAgICAgYWVzKHggICAgICAgPSBVTUFQXzEsCiAgICAgICAgICAgICAgICAgICAgICB5ICAgICAgID0gVU1BUF8yLAogICAgICAgICAgICAgICAgICAgICAgbGFiZWwgICA9IGxhYmVsKSwKICAgICAgICAgICAgICAgICAgY29sb3IgICAgICAgPSAiYmxhY2siLAogICAgICAgICAgICAgICAgICBiZy5jb2xvciAgICA9ICJ3aGl0ZSIsCiAgICAgICAgICAgICAgICAgIGJnLnIgICAgICAgID0gMC4xNSwKICAgICAgICAgICAgICAgICAgZm9udGZhY2UgICAgPSAiYm9sZCIsCiAgICAgICAgICAgICAgICAgIHNpemUgICAgICAgID0gNCwKICAgICAgICAgICAgICAgICAgaW5oZXJpdC5hZXMgPSBGQUxTRSkgKwoKICBsYWJzKHRpdGxlID0gIkJvcmNoZXJkaW5nIGV0IGFsLiwgMjAyMiIpICsKICB0aGVtZShwbG90LnRpdGxlICAgID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgpwX2RpbV9oIHwgcF9kaW1fYgpgYGAKCgojIyAgRnVsbCBQdWJsaWNhdGlvbiBGaWd1cmUKYGBge3IgLCBmaWcuaGVpZ2h0PTE4LCBmaWcud2lkdGg9MTR9CmZ1bGxfZmlnIDwtIChwX2RpbV9oIHwgcF9kaW1fYikgLwogICAgICAgICAgICAocF91bWFwX2ggfCBwX3VtYXBfYikgLwogICAgICAgICAgICBmaWc3RiArCgogIHBsb3RfbGF5b3V0KGhlaWdodHMgPSBjKDEsIDEsIDEuMikpICsKCiAgcGxvdF9hbm5vdGF0aW9uKAogICAgdGl0bGUgICAgICA9ICJDTElDMSBPdmVyZXhwcmVzc2lvbiBWYWxpZGF0ZWQgaW4gVHdvIEluZGVwZW5kZW50IFNTIENvaG9ydHMiLAogICAgdGFnX2xldmVscyA9ICJBIiwKICAgIHRoZW1lICAgICAgPSB0aGVtZSgKICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE1KQogICAgKQogICkKCmZ1bGxfZmlnCmBgYAoKCgojICAgU2F2ZSBGaWd1cmVzCmBgYHtyfQpkaXIuY3JlYXRlKCJvdXRwdXQiLCBzaG93V2FybmluZ3MgPSBGQUxTRSkKCmdnc2F2ZSgib3V0cHV0L0ZpZ3VyZTdGX0NMSUMxX3Zpb2xpbl9jb21iaW5lZC5wZGYiLAogICAgICAgcGxvdCA9IGZpZzdGLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA1LCBkcGkgPSAzMDApCmdnc2F2ZSgib3V0cHV0L0ZpZ3VyZTdGX0NMSUMxX3Zpb2xpbl9jb21iaW5lZC5wbmciLAogICAgICAgcGxvdCA9IGZpZzdGLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA1LCBkcGkgPSAzMDApCgpnZ3NhdmUoIm91dHB1dC9GaWd1cmU3Rl9DTElDMV9VTUFQX2xhYmVsZWQucGRmIiwKICAgICAgIHBsb3QgPSBwX3VtYXBfaCB8IHBfdW1hcF9iLAogICAgICAgd2lkdGggPSAxNCwgaGVpZ2h0ID0gNSwgZHBpID0gMzAwKQpnZ3NhdmUoIm91dHB1dC9GaWd1cmU3Rl9DTElDMV9VTUFQX2xhYmVsZWQucG5nIiwKICAgICAgIHBsb3QgPSBwX3VtYXBfaCB8IHBfdW1hcF9iLAogICAgICAgd2lkdGggPSAxNCwgaGVpZ2h0ID0gNSwgZHBpID0gMzAwKQoKZ2dzYXZlKCJvdXRwdXQvRmlndXJlN0ZfRGltUGxvdF9sYWJlbGVkLnBkZiIsCiAgICAgICBwbG90ID0gcF9kaW1faCB8IHBfZGltX2IsCiAgICAgICB3aWR0aCA9IDE0LCBoZWlnaHQgPSA1LCBkcGkgPSAzMDApCmdnc2F2ZSgib3V0cHV0L0ZpZ3VyZTdGX0RpbVBsb3RfbGFiZWxlZC5wbmciLAogICAgICAgcGxvdCA9IHBfZGltX2ggfCBwX2RpbV9iLAogICAgICAgd2lkdGggPSAxNCwgaGVpZ2h0ID0gNSwgZHBpID0gMzAwKQoKZ2dzYXZlKCJvdXRwdXQvRmlndXJlN0ZfZnVsbF9maWd1cmUucGRmIiwKICAgICAgIHBsb3QgPSBmdWxsX2ZpZywgd2lkdGggPSAxNCwgaGVpZ2h0ID0gMTQsIGRwaSA9IDMwMCkKZ2dzYXZlKCJvdXRwdXQvRmlndXJlN0ZfZnVsbF9maWd1cmUucG5nIiwKICAgICAgIHBsb3QgPSBmdWxsX2ZpZywgd2lkdGggPSAxNCwgaGVpZ2h0ID0gMTQsIGRwaSA9IDMwMCkKCmNhdCgiQWxsIGZpZ3VyZXMgc2F2ZWQgdG8gb3V0cHV0L1xuIikKYGBgCgoKCiMgICAgU2Vzc2lvbiBJbmZvCmBgYHtyfQpzZXNzaW9uSW5mbygpCmBgYAoKCgoKCg==