There were 32 warnings (use warnings() to see them)

1 Seurat analysis and normalization

Feature names cannot have underscores ('_'), replacing with dashes ('-')

Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Calculating gene variances
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Calculating feature variances of standardized and clipped values
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
When using repel, set xnudge and ynudge to 0 for optimal results

Centering and scaling data matrix

  |                                                                                                            
  |                                                                                                      |   0%
  |                                                                                                            
  |========                                                                                              |   8%
  |                                                                                                            
  |================                                                                                      |  15%
  |                                                                                                            
  |========================                                                                              |  23%
  |                                                                                                            
  |===============================                                                                       |  31%
  |                                                                                                            
  |=======================================                                                               |  38%
  |                                                                                                            
  |===============================================                                                       |  46%
  |                                                                                                            
  |=======================================================                                               |  54%
  |                                                                                                            
  |===============================================================                                       |  62%
  |                                                                                                            
  |=======================================================================                               |  69%
  |                                                                                                            
  |==============================================================================                        |  77%
  |                                                                                                            
  |======================================================================================                |  85%
  |                                                                                                            
  |==============================================================================================        |  92%
  |                                                                                                            
  |======================================================================================================| 100%
PC_ 1 
Positive:  Fabp7, Aldoc, Mfge8, Dbi, Ednrb, Vim, Slc1a3, Mt3, Apoe, Ttyh1 
       Tnc, Sox2, Atp1a2, Ddah1, Hes5, Sparc, Mlc1, Ppap2b, Rgcc, Bcan 
       Ndrg2, Qk, Lxn, Id3, Phgdh, Slc9a3r1, Nr2e1, Aldh1l1, Gpx8, Mt1 
Negative:  Tubb3, Stmn2, Neurod6, Stmn4, Map1b, Stmn1, Myt1l, Mef2c, Thra, 4930506M07Rik 
       Bcl11a, Gap43, Bhlhe22, Syt4, Cntn2, Nell2, Hs6st2, 9130024F11Rik, Olfm1, Satb2 
       Akap9, Ptprd, Rbfox1, Clmp, Ina, Enc1, Camk2b, Dync1i1, Dab1, Atp2b1 
PC_ 2 
Positive:  Sstr2, Mdk, Meis2, Pou3f2, Eomes, Zbtb20, Unc5d, Sema3c, Fos, Tead2 
       Palmd, Mfap4, Nhlh1, Ulk4, H1f0, Uaca, Neurog2, Neurod1, Ezr, Ier2 
       Nrn1, Baz2b, Pdzrn3, Btg2, Egr1, Mfap2, Loxl1, H2afv, Hbp1, Nnat 
Negative:  Gap43, Sybu, Dync1i1, Meg3, Mef2c, Map1b, Fezf2, Camk2b, Ina, Stmn2 
       Cdh13, Thra, Nin, Rac3, Igfbp3, Ssbp2, Neto2, Cd200, Hmgcs1, Tuba1b 
       Syt1, Slc6a15, Mapre2, Plk2, Rprm, Atp1b1, Cadm2, Arpp21, Kitl, Ntrk2 
PC_ 3 
Positive:  Meg3, Smpdl3a, Slc9a3r1, Slc15a2, Timp3, Tmem47, Ndrg2, Apoe, Ttyh1, Fmo1 
       Mlc1, Scrg1, Islr2, Malat1, Gstm1, Gja1, Ndnf, Aldh1l1, Mt3, Sparc 
       Serpinh1, Paqr7, Asrgl1, Sepp1, S100a1, Atp1b1, Ctsl, Cpe, S100a16, Lhx5 
Negative:  Birc5, Top2a, Cenpm, Pbk, Tpx2, Cenpe, Mki67, Cdca8, Gmnn, Cks2 
       Ccnb1, Ccnb2, Spc24, Hmgb2, Cenpf, Tk1, Hmmr, Prc1, Kif11, Ccna2 
       2810417H13Rik, C330027C09Rik, Cdca2, Ect2, Nusap1, Cenpa, Uhrf1, Plk1, Spc25, Knstrn 
PC_ 4 
Positive:  Lhx5, Nhlh2, Snhg11, Reln, 1500016L03Rik, Trp73, Cacna2d2, Ndnf, Car10, Lhx1 
       Islr2, Pcp4, Meg3, RP24-351J24.2, Rcan2, Pnoc, Mab21l1, Zic1, E330013P04Rik, Emx2 
       Malat1, Ebf3, Nr2f2, Zcchc12, Zbtb20, Celf4, Tmem163, Ache, Calb2, Unc5b 
Negative:  Ptn, Satb2, 9130024F11Rik, Neurod6, Mef2c, Dab1, Limch1, Hs6st2, Abracl, Dok5 
       Gucy1a3, Nell2, Ptprz1, Syt4, Ttc28, Clmp, Macrod2, Fam19a2, Smpdl3a, Ndrg1 
       Gstm1, 4930506M07Rik, Paqr7, Aldh1l1, Myt1l, Hmgcs1, Slc15a2, Pdzrn4, Slc9a3r1, Aldoc 
PC_ 5 
Positive:  Fam210b, Sfrp1, Pax6, Enkur, Tubb3, Tuba1b, Mcm3, Veph1, Stmn1, Eif1b 
       Map1b, Hopx, Abracl, Cdk2ap2, Tfap2c, Rps27l, 2810025M15Rik, Slc14a2, Prdx1, Hells 
       Gap43, Sept11, Egln3, Gm1840, Ezr, Cpne2, 9130024F11Rik, Nes, Efnb2, Cux1 
Negative:  Serpine2, Id1, Olig1, Sparcl1, Igfbp3, Fam212b, Ccnb2, Ppic, Gng12, Ccnb1 
       Bcan, Cenpe, Pbk, Id3, Rasl11a, Plk1, Aqp4, Aspm, Hmmr, Slc6a1 
       Slc4a4, Malat1, Myo6, Timp3, Meg3, Cdk1, Prrx1, Npy, B2m, Cspg4 

2 WGCNA

2.1 Test usign all genes normalized by Seurat

Centering and scaling data matrix

  |                                                                                                            
  |                                                                                                      |   0%
  |                                                                                                            
  |========                                                                                              |   8%
  |                                                                                                            
  |================                                                                                      |  15%
  |                                                                                                            
  |========================                                                                              |  23%
  |                                                                                                            
  |===============================                                                                       |  31%
  |                                                                                                            
  |=======================================                                                               |  38%
  |                                                                                                            
  |===============================================                                                       |  46%
  |                                                                                                            
  |=======================================================                                               |  54%
  |                                                                                                            
  |===============================================================                                       |  62%
  |                                                                                                            
  |=======================================================================                               |  69%
  |                                                                                                            
  |==============================================================================                        |  77%
  |                                                                                                            
  |======================================================================================                |  85%
  |                                                                                                            
  |==============================================================================================        |  92%
  |                                                                                                            
  |======================================================================================================| 100%
 Flagging genes and samples with too many missing values...
  ..step 1
[1] TRUE

No outlier detected.

Automatic network construction and module detection Choose a set of soft-thresholding powers

pickSoftThreshold: will use block size 3465.
 pickSoftThreshold: calculating connectivity for given powers...
   ..working on genes 1 through 3465 of 12909
   ..working on genes 3466 through 6930 of 12909
   ..working on genes 6931 through 10395 of 12909
   ..working on genes 10396 through 12909 of 12909

Thresholds tested: 2, 3, 6 The best is 2.

 Calculating module eigengenes block-wise from all genes
   Flagging genes and samples with too many missing values...
    ..step 1
 ..Working on block 1 .
    TOM calculation: adjacency..
    ..will not use multithreading.
     Fraction of slow calculations: 0.000000
    ..connectivity..
    ..matrix multiplication (system BLAS)..
    ..normalization..
    ..done.
   ..saving TOM for block 1 into file E17.5-block.1.RData
 ....clustering..
 ....detecting modules..
 ....calculating module eigengenes..
 ....checking kME in modules..
     ..removing 762 genes from module 1 because their KME is too low.
     ..removing 308 genes from module 2 because their KME is too low.
     ..removing 115 genes from module 3 because their KME is too low.
     ..removing 61 genes from module 4 because their KME is too low.
     ..removing 86 genes from module 5 because their KME is too low.
     ..removing 63 genes from module 6 because their KME is too low.
     ..removing 22 genes from module 7 because their KME is too low.
     ..removing 28 genes from module 8 because their KME is too low.
     ..removing 12 genes from module 9 because their KME is too low.
     ..removing 15 genes from module 10 because their KME is too low.
     ..removing 14 genes from module 11 because their KME is too low.
     ..removing 1 genes from module 12 because their KME is too low.
     ..removing 6 genes from module 14 because their KME is too low.
     ..removing 5 genes from module 15 because their KME is too low.
     ..removing 3 genes from module 16 because their KME is too low.
     ..removing 3 genes from module 17 because their KME is too low.
     ..removing 2 genes from module 19 because their KME is too low.
     ..removing 3 genes from module 20 because their KME is too low.
     ..removing 5 genes from module 22 because their KME is too low.
     ..removing 1 genes from module 23 because their KME is too low.
     ..removing 4 genes from module 26 because their KME is too low.
     ..removing 4 genes from module 27 because their KME is too low.
     ..removing 1 genes from module 30 because their KME is too low.
 ..merging modules that are too close..
     mergeCloseModules: Merging modules whose distance is less than 0.25
       Calculating new MEs...
  Reln   Lhx5   Cux1  Satb2   Rorb   Sox5  Fezf2 Bcl11b    Vim   Hes1 
    20     20      0      0      0      0      0      0      1      1 

As we can see the primary markers are not well distributed: it detect layer I and progenitors but all other genes are in the same cluster (module).

Plot the dendrogram and the module colors underneath

..connectivity..
..matrix multiplication (system BLAS)..
..normalization..
..done.

..connectivity..
..matrix multiplication (system BLAS)..
..normalization..
..done.

..connectivity..
..matrix multiplication (system BLAS)..
..normalization..
..done.

  Reln   Lhx5   Cux1  Satb2   Rorb   Sox5  Fezf2 Bcl11b    Vim   Hes1 
    20     20      0      0      0      0      0      0      1      1 
   Reln    Lhx5    Cux1   Satb2    Rorb    Sox5   Fezf2  Bcl11b     Vim    Hes1     Nes    Sox2    Sox1  Notch1 
     20      20       0       0       0       0       0       0       1       1       1       1       0      13 
   Hes5    Pax6   Tubb3    Tbr1   Stmn1 Neurod1     Dcx    Map2    Nefm    Nefl 
      1       1       1       0       0       0       0       0       0       0 
TOM calculation: adjacency..
..will not use multithreading.
 Fraction of slow calculations: 0.000000
..connectivity..
..matrix multiplication (system BLAS)..
..normalization..
..done.

2.2 Test with the 2000 most varied genes

 Flagging genes and samples with too many missing values...
  ..step 1
[1] TRUE

No outliner detected

pickSoftThreshold: will use block size 2000.
 pickSoftThreshold: calculating connectivity for given powers...
   ..working on genes 1 through 2000 of 2000

Plot the results:

Tested with 5, 3 and 2 and 4. The best seems 2

 Calculating module eigengenes block-wise from all genes
   Flagging genes and samples with too many missing values...
    ..step 1
 ..Working on block 1 .
    TOM calculation: adjacency..
    ..will not use multithreading.
     Fraction of slow calculations: 0.000000
    ..connectivity..
    ..matrix multiplication (system BLAS)..
    ..normalization..
    ..done.
   ..saving TOM for block 1 into file E17.5-block.1.RData
 ....clustering..
 ....detecting modules..
 ....calculating module eigengenes..
 ....checking kME in modules..
     ..removing 552 genes from module 1 because their KME is too low.
     ..removing 154 genes from module 2 because their KME is too low.
     ..removing 86 genes from module 3 because their KME is too low.
     ..removing 42 genes from module 4 because their KME is too low.
     ..removing 20 genes from module 5 because their KME is too low.
 ..merging modules that are too close..
     mergeCloseModules: Merging modules whose distance is less than 0.25
       Calculating new MEs...

Warning: Not all gene names were recognized. Only the following genes were recognized. 
    Reln,     Lhx5,     Cux1,     Satb2,     Rorb,     Sox5,     Fezf2,     Bcl11b,     Vim,     Hes1,     Nes,     Sox2,     Sox1,     Hes5,     Pax6,     Tubb3,     Stmn1,     Neurod1,     Nefm,     Nefl
..connectivity..
..matrix multiplication (system BLAS)..
..normalization..
..done.

..connectivity..
..matrix multiplication (system BLAS)..
..normalization..
..done.

TOM calculation: adjacency..
..will not use multithreading.
 Fraction of slow calculations: 0.000000
..connectivity..
..matrix multiplication (system BLAS)..
..normalization..
..done.

2.3 Comparition with Loo et al. markers

  Reln   Lhx5   Cux1  Satb2   Rorb   Sox5  Fezf2 Bcl11b    Vim   Hes1 
     4      4      0      0      0      0      0      0      1      1 
   Reln    Lhx5    Cux1   Satb2    Rorb    Sox5   Fezf2  Bcl11b     Vim    Hes1     Nes    Sox2    Sox1    <NA> 
      4       4       0       0       0       0       0       0       1       1       1       1       0      NA 
   Hes5    Pax6   Tubb3    <NA>   Stmn1 Neurod1    <NA>    <NA>    Nefm    Nefl 
      1       1       1      NA       1       0      NA      NA       0       0 
  Reln   Lhx5   Cux1  Satb2   Rorb   Sox5  Fezf2 Bcl11b    Vim   Hes1 
     4      4      0      0      0      0      0      0      1      1 

R version 4.0.4 (2021-02-15)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 18.04.5 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/openblas/libblas.so.3
LAPACK: /usr/lib/x86_64-linux-gnu/libopenblasp-r0.2.20.so

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8    LC_PAPER=en_US.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C             LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

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

other attached packages:
 [1] gplots_3.1.1          patchwork_1.1.1       SeuratObject_4.0.0    Seurat_4.0.0         
 [5] cluster_2.1.1         WGCNA_1.70-3          fastcluster_1.1.25    dynamicTreeCut_1.63-1
 [9] dendextend_1.14.0     MASS_7.3-53.1         htmlwidgets_1.5.3     forcats_0.5.1        
[13] stringr_1.4.0         dplyr_1.0.4           purrr_0.3.4           readr_1.4.0          
[17] tidyr_1.1.2           tibble_3.0.6          tidyverse_1.3.0       plotly_4.9.3         
[21] Rtsne_0.15            factoextra_1.0.7      ggrepel_0.9.1         ggplot2_3.3.3        
[25] Matrix_1.3-2          data.table_1.13.6     COTAN_0.1.0          

loaded via a namespace (and not attached):
  [1] reticulate_1.18       R.utils_2.10.1        tidyselect_1.1.0      RSQLite_2.2.3        
  [5] AnnotationDbi_1.52.0  grid_4.0.4            munsell_0.5.0         preprocessCore_1.52.1
  [9] codetools_0.2-18      ica_1.0-2             future_1.21.0         miniUI_0.1.1.1       
 [13] withr_2.4.1           colorspace_2.0-0      Biobase_2.50.0        filelock_1.0.2       
 [17] knitr_1.31            rstudioapi_0.13       stats4_4.0.4          ROCR_1.0-11          
 [21] ggsignif_0.6.1        tensor_1.5            listenv_0.8.0         labeling_0.4.2       
 [25] polyclip_1.10-0       bit64_4.0.5           farver_2.0.3          basilisk_1.2.1       
 [29] parallelly_1.23.0     vctrs_0.3.6           generics_0.1.0        xfun_0.20            
 [33] R6_2.5.0              doParallel_1.0.16     clue_0.3-58           bitops_1.0-6         
 [37] cachem_1.0.3          spatstat.utils_2.0-0  assertthat_0.2.1      promises_1.1.1       
 [41] scales_1.1.1          nnet_7.3-15           gtable_0.3.0          Cairo_1.5-12.2       
 [45] globals_0.14.0        goftest_1.2-2         rlang_0.4.10          GlobalOptions_0.1.2  
 [49] splines_4.0.4         rstatix_0.7.0         lazyeval_0.2.2        impute_1.64.0        
 [53] checkmate_2.0.0       broom_0.7.5           yaml_2.2.1            reshape2_1.4.4       
 [57] abind_1.4-5           modelr_0.1.8          crosstalk_1.1.1       backports_1.2.1      
 [61] httpuv_1.5.5          Hmisc_4.5-0           tools_4.0.4           ellipsis_0.3.1       
 [65] jquerylib_0.1.3       RColorBrewer_1.1-2    BiocGenerics_0.36.0   ggridges_0.5.3       
 [69] latex2exp_0.4.0       Rcpp_1.0.6            plyr_1.8.6            base64enc_0.1-3      
 [73] basilisk.utils_1.2.2  ggpubr_0.4.0          rpart_4.1-15          deldir_0.2-10        
 [77] pbapply_1.4-3         GetoptLong_1.0.5      viridis_0.5.1         cowplot_1.1.1        
 [81] S4Vectors_0.28.1      zoo_1.8-8             haven_2.3.1           fs_1.5.0             
 [85] magrittr_2.0.1        scattermore_0.7       openxlsx_4.2.3        circlize_0.4.12      
 [89] lmtest_0.9-38         reprex_1.0.0          RANN_2.6.1            fitdistrplus_1.1-3   
 [93] matrixStats_0.58.0    hms_1.0.0             mime_0.9              evaluate_0.14        
 [97] xtable_1.8-4          jpeg_0.1-8.1          rio_0.5.16            readxl_1.3.1         
[101] IRanges_2.24.1        gridExtra_2.3         shape_1.4.5           compiler_4.0.4       
[105] KernSmooth_2.23-18    crayon_1.4.0          R.oo_1.24.0           htmltools_0.5.1.1    
[109] mgcv_1.8-33           later_1.1.0.1         Formula_1.2-4         lubridate_1.7.9.2    
[113] DBI_1.1.1             dbplyr_2.1.0          ComplexHeatmap_2.6.2  rappdirs_0.3.3       
[117] car_3.0-10            cli_2.3.0             R.methodsS3_1.8.1     parallel_4.0.4       
[121] igraph_1.2.6          pkgconfig_2.0.3       foreign_0.8-81        xml2_1.3.2           
[125] foreach_1.5.1         bslib_0.2.4           rvest_0.3.6           digest_0.6.27        
[129] sctransform_0.3.2     RcppAnnoy_0.0.18      spatstat.data_2.0-0   rmarkdown_2.7        
[133] cellranger_1.1.0      leiden_0.3.7          htmlTable_2.1.0       uwot_0.1.10          
[137] curl_4.3              gtools_3.8.2          shiny_1.6.0           rjson_0.2.20         
[141] lifecycle_0.2.0       nlme_3.1-152          jsonlite_1.7.2        carData_3.0-4        
[145] viridisLite_0.3.0     pillar_1.4.7          lattice_0.20-41       fastmap_1.1.0        
[149] httr_1.4.2            survival_3.2-7        GO.db_3.12.1          glue_1.4.2           
[153] zip_2.1.1             spatstat_1.64-1       png_0.1-7             iterators_1.0.13     
[157] bit_4.0.4             stringi_1.5.3         sass_0.3.1            blob_1.2.1           
[161] caTools_1.18.1        latticeExtra_0.6-29   memoise_2.0.0         irlba_2.3.3          
[165] future.apply_1.7.0   
LS0tCnRpdGxlOiAiV0dDTkEgZXhwZXJpbWVudHMiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgY29sbGFwc2VkOiBubwogICAgY3NzOiBodG1sLW1kLTAxLmNzcwogICAgZmlnX2NhcHRpb246IHllcwogICAgaGlnaGxpZ2h0OiBoYWRkb2NrCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogICAgdGhlbWU6IHNwYWNlbGFiCiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICBodG1sX25vdGVib29rOgogICAgY29sbGFwc2VkOiBubwogICAgY3NzOiBodG1sLW1kLTAxLmNzcwogICAgZmlnX2NhcHRpb246IHllcwogICAgaGlnaGxpZ2h0OiBoYWRkb2NrCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogICAgdGhlbWU6IHNwYWNlbGFiCiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKLS0tCmBgYHtyLCBpbmNsdWRlID0gRkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldCgKICBjb2xsYXBzZSA9IFRSVUUsCiAgY29tbWVudCA9ICIjPiIKKQpvcHRpb25zKHJtYXJrZG93bi5odG1sX3ZpZ25ldHRlLmNoZWNrX3RpdGxlID0gRkFMU0UpCmBgYAoKYGBge3J9CndvcmtpbmdEaXIgPSAiLiIKbGlicmFyeShXR0NOQSkKbGlicmFyeShjbHVzdGVyKQpsaWJyYXJ5KGRhdGEudGFibGUpCmxpYnJhcnkoTWF0cml4KQpsaWJyYXJ5KFNldXJhdCkKbGlicmFyeSh1dGlscykKbGlicmFyeShkcGx5cikKbGlicmFyeShwYXRjaHdvcmspCmxpYnJhcnkoZ3JhcGhpY3MpCm9wdGlvbnMoc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQpkYXRhX2RpciA9ICJEYXRhLyIKbGlicmFyeShncGxvdHMpCm15aGVhdGNvbCA9IGNvbG9ycGFuZWwoMjUwLCdyZWQnLCJvcmFuZ2UiLCdsZW1vbmNoaWZmb24nKQoKYGBgCgojIFNldXJhdCBhbmFseXNpcyBhbmQgbm9ybWFsaXphdGlvbgoKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KZG93bmxvYWQuZmlsZSgiZnRwOi8vZnRwLm5jYmkubmxtLm5paC5nb3YvZ2VvL3NhbXBsZXMvR1NNMjg2MW5ubi9HU00yODYxNTE0L3N1cHBsL0dTTTI4NjE1MTRfRTE3NV9Pbmx5X0NvcnRpY2FsX0NlbGxzX0RHRS50eHQuZ3oiLAogICAgICAgICAgICAgICJEYXRhL0UxNzVfb25seV9jb3J0aWNhbF9jZWxscy50eHQuZ3oiLG1ldGhvZCA9ICJ3Z2V0IiwgcXVpZXQgPSBGKQpgYGAKYGBge3J9CmRhdGEgPSBhcy5kYXRhLmZyYW1lKGZyZWFkKHBhc3RlKGRhdGFfZGlyLCJFMTc1X29ubHlfY29ydGljYWxfY2VsbHMudHh0Lmd6Iiwgc2VwID0gIi8iKSxzZXAgPSAiXHQiKSkKZGF0YSA9IGFzLmRhdGEuZnJhbWUoZGF0YSkKcm93bmFtZXMoZGF0YSkgPSBkYXRhJFYxCmRhdGEgPSBkYXRhWywyOm5jb2woZGF0YSldCmRhdGFbMToxMCwxOjEwXQpgYGAKCmBgYHtyfQpFMTcgPC0gQ3JlYXRlU2V1cmF0T2JqZWN0KGNvdW50cyA9IGRhdGEsIHByb2plY3QgPSAiQ29ydGV4IEUxNy41IiwgbWluLmNlbGxzID0gMywgbWluLmZlYXR1cmVzID0gMjAwKQpFMTdbWyJwZXJjZW50Lm10Il1dIDwtIFBlcmNlbnRhZ2VGZWF0dXJlU2V0KEUxNywgcGF0dGVybiA9ICJebXQtIikKVmxuUGxvdChFMTcsIGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIiwgIm5Db3VudF9STkEiLCAicGVyY2VudC5tdCIpLCBuY29sID0gMykKYGBgCmBgYHtyfQpoaXN0KEUxNyRuRmVhdHVyZV9STkEvRTE3JG5Db3VudF9STkEsIGJyZWFrcyA9IDEwMCkKYGBgCmBgYHtyfQpwbG90MSA8LSBGZWF0dXJlU2NhdHRlcihFMTcsIGZlYXR1cmUxID0gIm5Db3VudF9STkEiLCBmZWF0dXJlMiA9ICJwZXJjZW50Lm10IikKcGxvdDIgPC0gRmVhdHVyZVNjYXR0ZXIoRTE3LCBmZWF0dXJlMSA9ICJuQ291bnRfUk5BIiwgZmVhdHVyZTIgPSAibkZlYXR1cmVfUk5BIikKcGxvdDEgKyBwbG90MgpgYGAKYGBge3J9CkUxNyA8LSBOb3JtYWxpemVEYXRhKEUxNywgbm9ybWFsaXphdGlvbi5tZXRob2QgPSAiTG9nTm9ybWFsaXplIiwgc2NhbGUuZmFjdG9yID0gMTAwMDApCkUxNyA8LSBGaW5kVmFyaWFibGVGZWF0dXJlcyhFMTcsIHNlbGVjdGlvbi5tZXRob2QgPSAidnN0IiwgbmZlYXR1cmVzID0gMjAwMCkKCiMgSWRlbnRpZnkgdGhlIDEwIG1vc3QgaGlnaGx5IHZhcmlhYmxlIGdlbmVzCnRvcDEwIDwtIGhlYWQoVmFyaWFibGVGZWF0dXJlcyhFMTcpLCAxMCkKCiMgcGxvdCB2YXJpYWJsZSBmZWF0dXJlcyB3aXRoIGFuZCB3aXRob3V0IGxhYmVscwpwbG90MSA8LSBWYXJpYWJsZUZlYXR1cmVQbG90KEUxNykKcGxvdDIgPC0gTGFiZWxQb2ludHMocGxvdCA9IHBsb3QxLCBwb2ludHMgPSB0b3AxMCwgcmVwZWwgPSBUUlVFKQpwbG90MgpgYGAKYGBge3J9CmFsbC5nZW5lcyA8LSByb3duYW1lcyhFMTcpCkUxNyA8LSBTY2FsZURhdGEoRTE3LCBmZWF0dXJlcyA9IGFsbC5nZW5lcykKRTE3IDwtIFJ1blBDQShFMTcsIGZlYXR1cmVzID0gVmFyaWFibGVGZWF0dXJlcyhvYmplY3QgPSBFMTcpKQpEaW1QbG90KEUxNywgcmVkdWN0aW9uID0gInBjYSIpCmBgYAoKIyBXR0NOQQoKIyMgVGVzdCB1c2lnbiBhbGwgZ2VuZXMgbm9ybWFsaXplZCBieSBTZXVyYXQKCmBgYHtyfQphbGwuZ2VuZXMgPC0gcm93bmFtZXMoRTE3KQpFMTcgPC0gU2NhbGVEYXRhKEUxNywgZmVhdHVyZXMgPSBhbGwuZ2VuZXMpCgpzZXVyYXQuZGF0YSA9IGFzLm1hdHJpeChFMTdbWyJSTkEiXV1AZGF0YSkKCmRhdEV4cHIwID0gdChzZXVyYXQuZGF0YSkKZ3NnID0gZ29vZFNhbXBsZXNHZW5lcyhkYXRFeHByMCwgdmVyYm9zZSA9IDMpCmdzZyRhbGxPSwppZiAoIWdzZyRhbGxPSyl7CiAgICAjIE9wdGlvbmFsbHksIHByaW50IHRoZSBnZW5lIGFuZCBzYW1wbGUgbmFtZXMgdGhhdCB3ZXJlIHJlbW92ZWQ6CiAgICBpZiAoc3VtKCFnc2ckZ29vZEdlbmVzKT4wKQogICAgICAgIHByaW50Rmx1c2gocGFzdGUoIlJlbW92aW5nIGdlbmVzOiIsIHBhc3RlKG5hbWVzKGRhdEV4cHIwKVshZ3NnJGdvb2RHZW5lc10sIGNvbGxhcHNlID0gIiwgIikpKTsKICAgIGlmIChzdW0oIWdzZyRnb29kU2FtcGxlcyk+MCkKICAgICAgICBwcmludEZsdXNoKHBhc3RlKCJSZW1vdmluZyBzYW1wbGVzOiIsIHBhc3RlKHJvd25hbWVzKGRhdEV4cHIwKVshZ3NnJGdvb2RTYW1wbGVzXSwgY29sbGFwc2UgPSAiLCAiKSkpOwogICAgIyBSZW1vdmUgdGhlIG9mZmVuZGluZyBnZW5lcyBhbmQgc2FtcGxlcyBmcm9tIHRoZSBkYXRhOgogICAgZGF0RXhwcjAgPSBkYXRFeHByMFtnc2ckZ29vZFNhbXBsZXMsIGdzZyRnb29kR2VuZXNdCn0KCgpzYW1wbGVUcmVlID0gaGNsdXN0KGRpc3QoZGF0RXhwcjApLCBtZXRob2QgPSAiYXZlcmFnZSIpCiMgUGxvdCB0aGUgc2FtcGxlIHRyZWU6IE9wZW4gYSBncmFwaGljIG91dHB1dCB3aW5kb3cgb2Ygc2l6ZSAxMiBieSA5IGluY2hlcwojIFRoZSB1c2VyIHNob3VsZCBjaGFuZ2UgdGhlIGRpbWVuc2lvbnMgaWYgdGhlIHdpbmRvdyBpcyB0b28gbGFyZ2Ugb3IgdG9vIHNtYWxsLgpzaXplR3JXaW5kb3coMTIsOSkKI3BkZihmaWxlID0gIlBsb3RzL3NhbXBsZUNsdXN0ZXJpbmcucGRmIiwgd2lkdGggPSAxMiwgaGVpZ2h0ID0gOSk7CnBhcihjZXggPSAwLjYpOwpwYXIobWFyID0gYygwLDQsMiwwKSkKcGxvdChzYW1wbGVUcmVlLCBtYWluID0gIlNhbXBsZSBjbHVzdGVyaW5nIHRvIGRldGVjdCBvdXRsaWVycyIsIHN1Yj0iIiwgeGxhYj0iIiwgY2V4LmxhYiA9IDEuNSwKICAgICBjZXguYXhpcyA9IDEuNSwgY2V4Lm1haW4gPSAyKQoKYGBgCk5vIG91dGxpZXIgZGV0ZWN0ZWQuCgpBdXRvbWF0aWMgbmV0d29yayBjb25zdHJ1Y3Rpb24gYW5kIG1vZHVsZSBkZXRlY3Rpb24KQ2hvb3NlIGEgc2V0IG9mIHNvZnQtdGhyZXNob2xkaW5nIHBvd2VycwpgYGB7cn0KcG93ZXJzID0gYyhjKDE6MTApLCBzZXEoZnJvbSA9IDEwLCB0bz0yMCwgYnk9MikpCiMgQ2FsbCB0aGUgbmV0d29yayB0b3BvbG9neSBhbmFseXNpcyBmdW5jdGlvbgpzZnQgPSBwaWNrU29mdFRocmVzaG9sZChkYXRFeHByMCwgcG93ZXJWZWN0b3IgPSBwb3dlcnMsIHZlcmJvc2UgPSA1KQojIFBsb3QgdGhlIHJlc3VsdHM6CnNpemVHcldpbmRvdyg5LCA1KQpwYXIobWZyb3cgPSBjKDEsMikpOwpjZXgxID0gMC45OwojIFNjYWxlLWZyZWUgdG9wb2xvZ3kgZml0IGluZGV4IGFzIGEgZnVuY3Rpb24gb2YgdGhlIHNvZnQtdGhyZXNob2xkaW5nIHBvd2VyCnBsb3Qoc2Z0JGZpdEluZGljZXNbLDFdLCAtc2lnbihzZnQkZml0SW5kaWNlc1ssM10pKnNmdCRmaXRJbmRpY2VzWywyXSwKICAgICB4bGFiPSJTb2Z0IFRocmVzaG9sZCAocG93ZXIpIix5bGFiPSJTY2FsZSBGcmVlIFRvcG9sb2d5IE1vZGVsIEZpdCxzaWduZWQgUl4yIix0eXBlPSJuIiwKICAgICBtYWluID0gcGFzdGUoIlNjYWxlIGluZGVwZW5kZW5jZSIpKTsKdGV4dChzZnQkZml0SW5kaWNlc1ssMV0sIC1zaWduKHNmdCRmaXRJbmRpY2VzWywzXSkqc2Z0JGZpdEluZGljZXNbLDJdLAogICAgIGxhYmVscz1wb3dlcnMsY2V4PWNleDEsY29sPSJyZWQiKTsKIyB0aGlzIGxpbmUgY29ycmVzcG9uZHMgdG8gdXNpbmcgYW4gUl4yIGN1dC1vZmYgb2YgaAphYmxpbmUoaD0wLjkwLGNvbD0icmVkIikKIyBNZWFuIGNvbm5lY3Rpdml0eSBhcyBhIGZ1bmN0aW9uIG9mIHRoZSBzb2Z0LXRocmVzaG9sZGluZyBwb3dlcgpwbG90KHNmdCRmaXRJbmRpY2VzWywxXSwgc2Z0JGZpdEluZGljZXNbLDVdLAogICAgIHhsYWI9IlNvZnQgVGhyZXNob2xkIChwb3dlcikiLHlsYWI9Ik1lYW4gQ29ubmVjdGl2aXR5IiwgdHlwZT0ibiIsCiAgICAgbWFpbiA9IHBhc3RlKCJNZWFuIGNvbm5lY3Rpdml0eSIpKQp0ZXh0KHNmdCRmaXRJbmRpY2VzWywxXSwgc2Z0JGZpdEluZGljZXNbLDVdLCBsYWJlbHM9cG93ZXJzLCBjZXg9Y2V4MSxjb2w9InJlZCIpCmBgYApUaHJlc2hvbGRzIHRlc3RlZDogMiwgMywgNgpUaGUgYmVzdCBpcyAyLgpgYGB7cn0KbmV0ID0gYmxvY2t3aXNlTW9kdWxlcyhkYXRFeHByMCwgcG93ZXIgPSAyLCBtYXhCbG9ja1NpemUgPSAyMDAwMCwKICAgICAgICAgICAgICAgICAgICAgICBUT01UeXBlID0gInNpZ25lZCIsIG1pbk1vZHVsZVNpemUgPSAzMCwKICAgICAgICAgICAgICAgICAgICAgICByZWFzc2lnblRocmVzaG9sZCA9IDAsIG1lcmdlQ3V0SGVpZ2h0ID0gMC4yNSwKICAgICAgICAgICAgICAgICAgICAgICBudW1lcmljTGFiZWxzID0gVFJVRSwgcGFtUmVzcGVjdHNEZW5kcm8gPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICBzYXZlVE9NcyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgc2F2ZVRPTUZpbGVCYXNlID0gIkUxNy41IiwKICAgICAgICAgICAgICAgICAgICAgICB2ZXJib3NlID0gMykKCiMgb3BlbiBhIGdyYXBoaWNzIHdpbmRvdwpzaXplR3JXaW5kb3coMTIsIDkpCiMgQ29udmVydCBsYWJlbHMgdG8gY29sb3JzIGZvciBwbG90dGluZwptZXJnZWRDb2xvcnMgPSBsYWJlbHMyY29sb3JzKG5ldCRjb2xvcnMpCmBgYApgYGB7cn0KcHJpbWFyeS5tYXJrZXJzID0gYygiUmVsbiIsIkxoeDUiLCJDdXgxIiwiU2F0YjIiLCJSb3JiIiwiU294NSIsIkZlemYyIiwiQmNsMTFiIiwiVmltIiwiSGVzMSIpCgpuZXQkY29sb3JzW3ByaW1hcnkubWFya2Vyc10KYGBgCgpBcyB3ZSBjYW4gc2VlIHRoZSBwcmltYXJ5IG1hcmtlcnMgYXJlIG5vdCB3ZWxsIGRpc3RyaWJ1dGVkOiBpdCBkZXRlY3QgbGF5ZXIgSSBhbmQgcHJvZ2VuaXRvcnMgYnV0IGFsbCBvdGhlciBnZW5lcyBhcmUgaW4gdGhlIHNhbWUgY2x1c3RlciAobW9kdWxlKS4KClBsb3QgdGhlIGRlbmRyb2dyYW0gYW5kIHRoZSBtb2R1bGUgY29sb3JzIHVuZGVybmVhdGgKYGBge3J9CnBsb3REZW5kcm9BbmRDb2xvcnMobmV0JGRlbmRyb2dyYW1zW1sxXV0sIG1lcmdlZENvbG9yc1tuZXQkYmxvY2tHZW5lc1tbMV1dXSwKICAgICAgICAgICAgICAgICAgICAiTW9kdWxlIGNvbG9ycyIsCiAgICAgICAgICAgICAgICAgICAgZGVuZHJvTGFiZWxzID0gRkFMU0UsIGhhbmcgPSAwLjAzLAogICAgICAgICAgICAgICAgICAgIGFkZEd1aWRlID0gVFJVRSwgZ3VpZGVIYW5nID0gMC4wNSkKYGBgCgoKCmBgYHtyfQpwbG90TmV0d29ya0hlYXRtYXAoZGF0RXhwcjAsIHBsb3RHZW5lcyA9IHByaW1hcnkubWFya2VycywKbmV0d29ya1R5cGU9InVuc2lnbmVkIiwgdXNlVE9NPVRSVUUsCnBvd2VyPTIsIG1haW49IkQuIFRPTSBpbiBhbiB1bnNpZ25lZCBuZXR3b3JrIikKYGBgCgoKYGBge3J9CnBsb3ROZXR3b3JrSGVhdG1hcChkYXRFeHByMCwgcGxvdEdlbmVzID0gcHJpbWFyeS5tYXJrZXJzLApuZXR3b3JrVHlwZT0ic2lnbmVkIiwgdXNlVE9NPVRSVUUsCnBvd2VyPTIsIG1haW49IkQuIFRPTSBpbiBhbiBzaWduZWQgbmV0d29yayIpCmBgYAoKYGBge3J9CmdlbmUuc2V0cy5saXN0ID0gbGlzdCgicHJpbWFyeS5tYXJrZXJzIj1wcmltYXJ5Lm1hcmtlcnMsCiAgICAgICAgICAgICAgICAgICAgICAiTlBHcyI9YygiTmVzIiwiVmltIiwiU294MiIsIlNveDEiLCJOb3RjaDEiLCAiSGVzMSIsIkhlczUiLCJQYXg2IiksIAogICAgICAgICAgICAgICAgICAgICAgIlJHIiA9IGMoIlZpbSIsIlNveDIiLCJQYXg2IiwiSGVzNSIsIkhlczEiKSwKICAgICAgICAgICAgICAgICAgICAgICJJTiIgPSBjKCJUdWJiMyIsIlRicjEiLCJTdG1uMSIsIk5ldXJvZDEiLCJEY3giKSwKICAgICAgICAgICAgICAgICAgICAgICJQTkdzIj1jKCJNYXAyIiwiVHViYjMiLCJOZXVyb2QxIiwiTmVmbSIsIk5lZmwiLCJEY3giLCJUYnIxIikpIywKICAgICAgICAgICAgICAgICAgICAgICMiY29uc3RpdHV0aXZlIiA9YygiQ2FsbTEiLCJDb3g2YjEiLCJQcGlhIiwiUnBsMTgiLCJDb3g3YyIsICJFcmgiLCJIM2YzYSIsIlRhZjFiIiwiVGFmMiIsIkdhcGRoIiwiQWN0YiIsICJHb2xwaDMiLCAiTXRtcjEyIiwgIlpmciIsICJTdWIxIiwgIlRhcnMiLCAiQW1hY3IiKSApCgpnZW5lcyA9IHVuaXF1ZSh1bmxpc3QoZ2VuZS5zZXRzLmxpc3QpKQoKcGxvdE5ldHdvcmtIZWF0bWFwKGRhdEV4cHIwLCBwbG90R2VuZXMgPSBnZW5lcywgbmV0d29ya1R5cGU9InNpZ25lZCIsIHVzZVRPTT1UUlVFLCAKICAgICAgICAgICAgICAgICAgIHBvd2VyPTIsIG1haW49IkQuIFRPTSBpbiBhbiBzaWduZWQgbmV0d29yayIpCgpgYGAKCgpgYGB7cn0KbmV0JGNvbG9yc1twcmltYXJ5Lm1hcmtlcnNdCmBgYApgYGB7cn0KbmV0JGNvbG9yc1t1bmlxdWUodW5saXN0KGdlbmUuc2V0cy5saXN0KSldCmBgYApgYGB7cn0KIyBDYWxjdWxhdGUgdG9wb2xvZ2ljYWwgb3ZlcmxhcCBhbmV3OiB0aGlzIGNvdWxkIGJlIGRvbmUgbW9yZSBlZmZpY2llbnRseSBieSBzYXZpbmcgdGhlIFRPTQojIGNhbGN1bGF0ZWQgZHVyaW5nIG1vZHVsZSBkZXRlY3Rpb24sIGJ1dCBsZXQgdXMgZG8gaXQgYWdhaW4gaGVyZS4KZGlzc1RPTSA9IDEtVE9Nc2ltaWxhcml0eUZyb21FeHByKGRhdEV4cHIwLCBwb3dlciA9IDIpOwojIFRyYW5zZm9ybSBkaXNzVE9NIHdpdGggYSBwb3dlciB0byBtYWtlIG1vZGVyYXRlbHkgc3Ryb25nIGNvbm5lY3Rpb25zIG1vcmUgdmlzaWJsZSBpbiB0aGUgaGVhdG1hcApwbG90VE9NID0gZGlzc1RPTV43OwojIFNldCBkaWFnb25hbCB0byBOQSBmb3IgYSBuaWNlciBwbG90CmRpYWcocGxvdFRPTSkgPSBOQTsKcm93bmFtZXMoZGlzc1RPTSk9Y29sbmFtZXMoZGF0RXhwcjApCmNvbG5hbWVzKGRpc3NUT00pPWNvbG5hbWVzKGRhdEV4cHIwKQoKc2VsZWN0VE9NID0gZGlzc1RPTVtwcmltYXJ5Lm1hcmtlcnMsIHByaW1hcnkubWFya2Vyc10KIyBUaGVyZeKAmXMgbm8gc2ltcGxlIHdheSBvZiByZXN0cmljdGluZyBhIGNsdXN0ZXJpbmcgdHJlZSB0byBhIHN1YnNldCBvZiBnZW5lcywgc28gd2UgbXVzdCByZS1jbHVzdGVyLgpzZWxlY3RUcmVlID0gaGNsdXN0KGFzLmRpc3Qoc2VsZWN0VE9NKSwgbWV0aG9kID0gImF2ZXJhZ2UiKQoKbW9kdWxlQ29sb3JzID0gbWVyZ2VkQ29sb3JzCm5hbWVzKG1vZHVsZUNvbG9ycykgPSByb3duYW1lcyhkaXNzVE9NKQpzZWxlY3RDb2xvcnMgPSBtb2R1bGVDb2xvcnNbcHJpbWFyeS5tYXJrZXJzXQojIE9wZW4gYSBncmFwaGljYWwgd2luZG93CnNpemVHcldpbmRvdyg5LDkpCiMgVGFraW5nIHRoZSBkaXNzaW1pbGFyaXR5IHRvIGEgcG93ZXIsIHNheSAxMCwgbWFrZXMgdGhlIHBsb3QgbW9yZSBpbmZvcm1hdGl2ZSBieSBlZmZlY3RpdmVseSBjaGFuZ2luZwojIHRoZSBjb2xvciBwYWxldHRlOyBzZXR0aW5nIHRoZSBkaWFnb25hbCB0byBOQSBhbHNvIGltcHJvdmVzIHRoZSBjbGFyaXR5IG9mIHRoZSBwbG90CnBsb3REaXNzID0gc2VsZWN0VE9NXjc7CmRpYWcocGxvdERpc3MpID0gTkE7ClRPTXBsb3QocGxvdERpc3MsIHNlbGVjdFRyZWUsIHNlbGVjdENvbG9ycywgbWFpbiA9ICJOZXR3b3JrIGhlYXRtYXAgcGxvdCwgc2VsZWN0ZWQgZ2VuZXMiLGNvbD1teWhlYXRjb2wpCgpgYGAKCmBgYHtyfQpwbG90RGVuZHJvQW5kQ29sb3JzKHNlbGVjdFRyZWUsc2VsZWN0Q29sb3JzLAogICAgICAgICAgICAgICAgICAgICAiTW9kdWxlIGNvbG9ycyIsCiAgICAgICAgICAgICAgICAgICAgIGRlbmRyb0xhYmVscyA9IE5VTEwsIGhhbmcgPSAwLjAzLAogICAgICAgICAgICAgICAgICAgICBhZGRHdWlkZSA9IFRSVUUsIGd1aWRlSGFuZyA9IDAuMDUpCmBgYAoKCiMjIFRlc3Qgd2l0aCB0aGUgMjAwMCBtb3N0IHZhcmllZCBnZW5lcwoKYGBge3J9ClZhci5nZW5lcyA9IFZhcmlhYmxlRmVhdHVyZXMoRTE3KVsxOjIwMDBdCgpgYGAKCgpgYGB7cn0KZGF0RXhwcjAgPSB0KHNldXJhdC5kYXRhW3Jvd25hbWVzKHNldXJhdC5kYXRhKSAlaW4lIFZhci5nZW5lcyxdKQpnc2cgPSBnb29kU2FtcGxlc0dlbmVzKGRhdEV4cHIwLCB2ZXJib3NlID0gMykKZ3NnJGFsbE9LCmlmICghZ3NnJGFsbE9LKXsKICAgICMgT3B0aW9uYWxseSwgcHJpbnQgdGhlIGdlbmUgYW5kIHNhbXBsZSBuYW1lcyB0aGF0IHdlcmUgcmVtb3ZlZDoKICAgIGlmIChzdW0oIWdzZyRnb29kR2VuZXMpPjApCiAgICAgICAgcHJpbnRGbHVzaChwYXN0ZSgiUmVtb3ZpbmcgZ2VuZXM6IiwgcGFzdGUobmFtZXMoZGF0RXhwcjApWyFnc2ckZ29vZEdlbmVzXSwgY29sbGFwc2UgPSAiLCAiKSkpOwogICAgaWYgKHN1bSghZ3NnJGdvb2RTYW1wbGVzKT4wKQogICAgICAgIHByaW50Rmx1c2gocGFzdGUoIlJlbW92aW5nIHNhbXBsZXM6IiwgcGFzdGUocm93bmFtZXMoZGF0RXhwcjApWyFnc2ckZ29vZFNhbXBsZXNdLCBjb2xsYXBzZSA9ICIsICIpKSk7CiAgICAjIFJlbW92ZSB0aGUgb2ZmZW5kaW5nIGdlbmVzIGFuZCBzYW1wbGVzIGZyb20gdGhlIGRhdGE6CiAgICBkYXRFeHByMCA9IGRhdEV4cHIwW2dzZyRnb29kU2FtcGxlcywgZ3NnJGdvb2RHZW5lc10KfQoKCgpzYW1wbGVUcmVlID0gaGNsdXN0KGRpc3QoZGF0RXhwcjApLCBtZXRob2QgPSAiYXZlcmFnZSIpOwojIFBsb3QgdGhlIHNhbXBsZSB0cmVlOiBPcGVuIGEgZ3JhcGhpYyBvdXRwdXQgd2luZG93IG9mIHNpemUgMTIgYnkgOSBpbmNoZXMKIyBUaGUgdXNlciBzaG91bGQgY2hhbmdlIHRoZSBkaW1lbnNpb25zIGlmIHRoZSB3aW5kb3cgaXMgdG9vIGxhcmdlIG9yIHRvbyBzbWFsbC4Kc2l6ZUdyV2luZG93KDEyLDkpCiNwZGYoZmlsZSA9ICJQbG90cy9zYW1wbGVDbHVzdGVyaW5nLnBkZiIsIHdpZHRoID0gMTIsIGhlaWdodCA9IDkpOwpwYXIoY2V4ID0gMC42KTsKcGFyKG1hciA9IGMoMCw0LDIsMCkpCnBsb3Qoc2FtcGxlVHJlZSwgbWFpbiA9ICJTYW1wbGUgY2x1c3RlcmluZyB0byBkZXRlY3Qgb3V0bGllcnMiLCBzdWI9IiIsIHhsYWI9IiIsIGNleC5sYWIgPSAxLjUsCiAgICAgY2V4LmF4aXMgPSAxLjUsIGNleC5tYWluID0gMikKCiMgUGxvdCBhIGxpbmUgdG8gc2hvdyB0aGUgY3V0CiNhYmxpbmUoaCA9IDQwMCwgY29sID0gInJlZCIpCmBgYApObyBvdXRsaW5lciBkZXRlY3RlZAoKYGBge3J9CiMgQXV0b21hdGljIG5ldHdvcmsgY29uc3RydWN0aW9uIGFuZCBtb2R1bGUgZGV0ZWN0aW9uCiMgQ2hvb3NlIGEgc2V0IG9mIHNvZnQtdGhyZXNob2xkaW5nIHBvd2Vycwpwb3dlcnMgPSBjKGMoMToxMCksIHNlcShmcm9tID0gMTAsIHRvPTI1LCBieT0yKSkKIyBDYWxsIHRoZSBuZXR3b3JrIHRvcG9sb2d5IGFuYWx5c2lzIGZ1bmN0aW9uCnNmdCA9IHBpY2tTb2Z0VGhyZXNob2xkKGRhdEV4cHIwLCBwb3dlclZlY3RvciA9IHBvd2VycywgdmVyYm9zZSA9IDUpCmBgYApQbG90IHRoZSByZXN1bHRzOgpgYGB7cn0Kc2l6ZUdyV2luZG93KDksIDUpCnBhcihtZnJvdyA9IGMoMSwyKSk7CmNleDEgPSAwLjk7CiMgU2NhbGUtZnJlZSB0b3BvbG9neSBmaXQgaW5kZXggYXMgYSBmdW5jdGlvbiBvZiB0aGUgc29mdC10aHJlc2hvbGRpbmcgcG93ZXIKcGxvdChzZnQkZml0SW5kaWNlc1ssMV0sIC1zaWduKHNmdCRmaXRJbmRpY2VzWywzXSkqc2Z0JGZpdEluZGljZXNbLDJdLAogICAgIHhsYWI9IlNvZnQgVGhyZXNob2xkIChwb3dlcikiLHlsYWI9IlNjYWxlIEZyZWUgVG9wb2xvZ3kgTW9kZWwgRml0LHNpZ25lZCBSXjIiLHR5cGU9Im4iLAogICAgIG1haW4gPSBwYXN0ZSgiU2NhbGUgaW5kZXBlbmRlbmNlIikpOwp0ZXh0KHNmdCRmaXRJbmRpY2VzWywxXSwgLXNpZ24oc2Z0JGZpdEluZGljZXNbLDNdKSpzZnQkZml0SW5kaWNlc1ssMl0sCiAgICAgbGFiZWxzPXBvd2VycyxjZXg9Y2V4MSxjb2w9InJlZCIpOwojIHRoaXMgbGluZSBjb3JyZXNwb25kcyB0byB1c2luZyBhbiBSXjIgY3V0LW9mZiBvZiBoCmFibGluZShoPTAuOTAsY29sPSJyZWQiKQojIE1lYW4gY29ubmVjdGl2aXR5IGFzIGEgZnVuY3Rpb24gb2YgdGhlIHNvZnQtdGhyZXNob2xkaW5nIHBvd2VyCnBsb3Qoc2Z0JGZpdEluZGljZXNbLDFdLCBzZnQkZml0SW5kaWNlc1ssNV0sCiAgICAgeGxhYj0iU29mdCBUaHJlc2hvbGQgKHBvd2VyKSIseWxhYj0iTWVhbiBDb25uZWN0aXZpdHkiLCB0eXBlPSJuIiwKICAgICBtYWluID0gcGFzdGUoIk1lYW4gY29ubmVjdGl2aXR5IikpCnRleHQoc2Z0JGZpdEluZGljZXNbLDFdLCBzZnQkZml0SW5kaWNlc1ssNV0sIGxhYmVscz1wb3dlcnMsIGNleD1jZXgxLGNvbD0icmVkIikKYGBgClRlc3RlZCB3aXRoIDUsIDMgYW5kIDIgYW5kIDQuIFRoZSBiZXN0IHNlZW1zIDIKYGBge3J9Cm5ldCA9IGJsb2Nrd2lzZU1vZHVsZXMoZGF0RXhwcjAsIHBvd2VyID0gMiwgbWF4QmxvY2tTaXplID0gMjAwMDAsCiAgICAgICAgICAgICAgICAgICAgICAgVE9NVHlwZSA9ICJzaWduZWQiLCBtaW5Nb2R1bGVTaXplID0gMzAsCiAgICAgICAgICAgICAgICAgICAgICAgcmVhc3NpZ25UaHJlc2hvbGQgPSAwLCBtZXJnZUN1dEhlaWdodCA9IDAuMjUsCiAgICAgICAgICAgICAgICAgICAgICAgbnVtZXJpY0xhYmVscyA9IFRSVUUsIHBhbVJlc3BlY3RzRGVuZHJvID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgc2F2ZVRPTXMgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgIHNhdmVUT01GaWxlQmFzZSA9ICJFMTcuNSIsCiAgICAgICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IDMpCgpgYGAKYGBge3J9CiMgb3BlbiBhIGdyYXBoaWNzIHdpbmRvdwpzaXplR3JXaW5kb3coMTIsIDkpCiMgQ29udmVydCBsYWJlbHMgdG8gY29sb3JzIGZvciBwbG90dGluZwptZXJnZWRDb2xvcnMgPSBsYWJlbHMyY29sb3JzKG5ldCRjb2xvcnMpCiMgUGxvdCB0aGUgZGVuZHJvZ3JhbSBhbmQgdGhlIG1vZHVsZSBjb2xvcnMgdW5kZXJuZWF0aApwbG90RGVuZHJvQW5kQ29sb3JzKG5ldCRkZW5kcm9ncmFtc1tbMV1dLCBtZXJnZWRDb2xvcnNbbmV0JGJsb2NrR2VuZXNbWzFdXV0sCiAgICAgICAgICAgICAgICAgICAgIk1vZHVsZSBjb2xvcnMiLAogICAgICAgICAgICAgICAgICAgIGRlbmRyb0xhYmVscyA9IEZBTFNFLCBoYW5nID0gMC4wMywKICAgICAgICAgICAgICAgICAgICBhZGRHdWlkZSA9IFRSVUUsIGd1aWRlSGFuZyA9IDAuMDUpCgpgYGAKYGBge3J9CnBsb3ROZXR3b3JrSGVhdG1hcChkYXRFeHByMCwgcGxvdEdlbmVzID0gdW5pcXVlKHVubGlzdChnZW5lLnNldHMubGlzdCkpLApuZXR3b3JrVHlwZT0ic2lnbmVkIiwgdXNlVE9NPVRSVUUsCnBvd2VyPTIsIG1haW49IkQuIFRPTSBpbiBhbiBzaWduZWQgbmV0d29yayIpCgpgYGAKYGBge3J9CnBsb3ROZXR3b3JrSGVhdG1hcChkYXRFeHByMCwgcGxvdEdlbmVzID0gcHJpbWFyeS5tYXJrZXJzLApuZXR3b3JrVHlwZT0ic2lnbmVkIiwgdXNlVE9NPVRSVUUsCnBvd2VyPTIsIG1haW49IkQuIFRPTSBpbiBhbiBzaWduZWQgbmV0d29yayIpCgpgYGAKYGBge3J9CiMgQ2FsY3VsYXRlIHRvcG9sb2dpY2FsIG92ZXJsYXAgYW5ldzogdGhpcyBjb3VsZCBiZSBkb25lIG1vcmUgZWZmaWNpZW50bHkgYnkgc2F2aW5nIHRoZSBUT00KIyBjYWxjdWxhdGVkIGR1cmluZyBtb2R1bGUgZGV0ZWN0aW9uLCBidXQgbGV0IHVzIGRvIGl0IGFnYWluIGhlcmUuCmRpc3NUT00gPSAxLVRPTXNpbWlsYXJpdHlGcm9tRXhwcihkYXRFeHByMCwgcG93ZXIgPSAyKTsKIyBUcmFuc2Zvcm0gZGlzc1RPTSB3aXRoIGEgcG93ZXIgdG8gbWFrZSBtb2RlcmF0ZWx5IHN0cm9uZyBjb25uZWN0aW9ucyBtb3JlIHZpc2libGUgaW4gdGhlIGhlYXRtYXAKcGxvdFRPTSA9IGRpc3NUT01eNzsKIyBTZXQgZGlhZ29uYWwgdG8gTkEgZm9yIGEgbmljZXIgcGxvdApkaWFnKHBsb3RUT00pID0gTkE7CnJvd25hbWVzKGRpc3NUT00pPWNvbG5hbWVzKGRhdEV4cHIwKQpjb2xuYW1lcyhkaXNzVE9NKT1jb2xuYW1lcyhkYXRFeHByMCkKCnNlbGVjdFRPTSA9IGRpc3NUT01bcHJpbWFyeS5tYXJrZXJzLCBwcmltYXJ5Lm1hcmtlcnNdOwojIFRoZXJl4oCZcyBubyBzaW1wbGUgd2F5IG9mIHJlc3RyaWN0aW5nIGEgY2x1c3RlcmluZyB0cmVlIHRvIGEgc3Vic2V0IG9mIGdlbmVzLCBzbyB3ZSBtdXN0IHJlLWNsdXN0ZXIuCnNlbGVjdFRyZWUgPSBoY2x1c3QoYXMuZGlzdChzZWxlY3RUT00pLCBtZXRob2QgPSAiYXZlcmFnZSIpCm1vZHVsZUNvbG9ycyA9IG1lcmdlZENvbG9ycwpuYW1lcyhtb2R1bGVDb2xvcnMpID0gcm93bmFtZXMoZGlzc1RPTSkKc2VsZWN0Q29sb3JzID0gbW9kdWxlQ29sb3JzW3ByaW1hcnkubWFya2Vyc10KIyBPcGVuIGEgZ3JhcGhpY2FsIHdpbmRvdwpzaXplR3JXaW5kb3coOSw5KQojIFRha2luZyB0aGUgZGlzc2ltaWxhcml0eSB0byBhIHBvd2VyLCBzYXkgMTAsIG1ha2VzIHRoZSBwbG90IG1vcmUgaW5mb3JtYXRpdmUgYnkgZWZmZWN0aXZlbHkgY2hhbmdpbmcKIyB0aGUgY29sb3IgcGFsZXR0ZTsgc2V0dGluZyB0aGUgZGlhZ29uYWwgdG8gTkEgYWxzbyBpbXByb3ZlcyB0aGUgY2xhcml0eSBvZiB0aGUgcGxvdApwbG90RGlzcyA9IHNlbGVjdFRPTV43OwpkaWFnKHBsb3REaXNzKSA9IE5BOwpUT01wbG90KHBsb3REaXNzLCBzZWxlY3RUcmVlLCBzZWxlY3RDb2xvcnMsIG1haW4gPSAiTmV0d29yayBoZWF0bWFwIHBsb3QsIHNlbGVjdGVkIGdlbmVzIixjb2w9bXloZWF0Y29sKQoKYGBgCgpgYGB7cn0KcGxvdERlbmRyb0FuZENvbG9ycyhzZWxlY3RUcmVlLHNlbGVjdENvbG9ycywKICAgICAgICAgICAgICAgICAgICAgIk1vZHVsZSBjb2xvcnMiLAogICAgICAgICAgICAgICAgICAgICBkZW5kcm9MYWJlbHMgPSBOVUxMLCBoYW5nID0gMC4wMywKICAgICAgICAgICAgICAgICAgICAgYWRkR3VpZGUgPSBUUlVFLCBndWlkZUhhbmcgPSAwLjA1KQpgYGAKCiMjIENvbXBhcml0aW9uIHdpdGggTG9vIGV0IGFsLiBtYXJrZXJzCgpgYGB7cn0KbmV0JGNvbG9yc1twcmltYXJ5Lm1hcmtlcnNdCmBgYApgYGB7cn0KbmV0JGNvbG9yc1tnZW5lc10KYGBgCmBgYHtyfQpNYXJrZXJzX0xvbyA9IHJlYWQuY3N2KCJEYXRhL01hcmtlcnNfTG9vLmNzdiIpCgpNYXJrZXJzX0xvbwpgYGAKCmBgYHtyfQp0YWJsZU1hcmtlcnNXR0NOQSA9IGFzLmRhdGEuZnJhbWUobWF0cml4KG5yb3cgPSA0LG5jb2wgPSA0KSkKY29sbmFtZXModGFibGVNYXJrZXJzV0dDTkEpPWMoIkxvby5MLkkiLCJMb28uTC5JSS5JViIsIkxvby5MLlYuVkkiLCJMb28uUFJPRyIpCnJvd25hbWVzKHRhYmxlTWFya2Vyc1dHQ05BKT1jKCJXR0NOQS5MLkkiLCJXR0NOQS5MLklJLlZJIiwiV0dDTkEuUFJPRyIsIldHQ05BLk5vdCBHcm91cHBlZCIpCgpuZXQkY29sb3JzW3ByaW1hcnkubWFya2Vyc10KYGBgCgoKYGBge3J9Cmdyb3VwcyA9IGxpc3QoIkwuSSI9NCwiTC5JSS5WSSI9MCwiUFJPRyI9MSkKCmZvcihsYXllcjEgaW4gYygiTC5JIiwiTC5JSS5WSSIsIlBST0ciKSl7CiAgICBmb3IobGF5ZXIyIGluIGMoIkwuSSIsIkwuSUkuSVYiLCAiTC5WLlZJIiwiUFJPRyIpKXsKICAgIHRhYmxlTWFya2Vyc1dHQ05BW3Bhc3RlMCgiV0dDTkEuIixsYXllcjEpLHBhc3RlMCgiTG9vLiIsbGF5ZXIyKV0gPQogICAgICAgIHN1bShuYW1lcyhuZXQkY29sb3JzW25ldCRjb2xvcnMgJWluJSBncm91cHNbW2xheWVyMV1dXSkgJWluJSBNYXJrZXJzX0xvb1tbbGF5ZXIyXV0pCiAgICB0YWJsZU1hcmtlcnNXR0NOQVtwYXN0ZTAoIldHQ05BLiIsIk5vdCBHcm91cHBlZCIpLHBhc3RlMCgiTG9vLiIsbGF5ZXIyKV0gPQogICAgICAgIHN1bShuYW1lcyhuZXQkY29sb3JzWyFuZXQkY29sb3JzICVpbiUgdW5saXN0KGdyb3VwcyldKSAlaW4lIE1hcmtlcnNfTG9vW1tsYXllcjJdXSkKICAgIH0KfQoKdGFibGVNYXJrZXJzV0dDTkEKYGBgCmBgYHtyfQpzZWxlY3RUT00gPSBkaXNzVE9NW3Jvd25hbWVzKGRpc3NUT00pICVpbiUgdW5saXN0KE1hcmtlcnNfTG9vKSxjb2xuYW1lcyhkaXNzVE9NKSAlaW4lICB1bmxpc3QoTWFya2Vyc19Mb28pXQojIFRoZXJl4oCZcyBubyBzaW1wbGUgd2F5IG9mIHJlc3RyaWN0aW5nIGEgY2x1c3RlcmluZyB0cmVlIHRvIGEgc3Vic2V0IG9mIGdlbmVzLCBzbyB3ZSBtdXN0IHJlLWNsdXN0ZXIuCnNlbGVjdFRyZWUgPSBoY2x1c3QoYXMuZGlzdChzZWxlY3RUT00pLCBtZXRob2QgPSAiYXZlcmFnZSIpCm1vZHVsZUNvbG9ycyA9IG1lcmdlZENvbG9ycwpuYW1lcyhtb2R1bGVDb2xvcnMpID0gcm93bmFtZXMoZGlzc1RPTSkKc2VsZWN0Q29sb3JzID0gbW9kdWxlQ29sb3JzW25hbWVzKG1vZHVsZUNvbG9ycykgJWluJSB1bmxpc3QoTWFya2Vyc19Mb28pXQojIE9wZW4gYSBncmFwaGljYWwgd2luZG93CnNpemVHcldpbmRvdyg5LDkpCiMgVGFraW5nIHRoZSBkaXNzaW1pbGFyaXR5IHRvIGEgcG93ZXIsIHNheSAxMCwgbWFrZXMgdGhlIHBsb3QgbW9yZSBpbmZvcm1hdGl2ZSBieSBlZmZlY3RpdmVseSBjaGFuZ2luZwojIHRoZSBjb2xvciBwYWxldHRlOyBzZXR0aW5nIHRoZSBkaWFnb25hbCB0byBOQSBhbHNvIGltcHJvdmVzIHRoZSBjbGFyaXR5IG9mIHRoZSBwbG90CnBsb3REaXNzID0gc2VsZWN0VE9NXjc7CmRpYWcocGxvdERpc3MpID0gTkE7ClRPTXBsb3QocGxvdERpc3MsIHNlbGVjdFRyZWUsIHNlbGVjdENvbG9ycywgbWFpbiA9ICJOZXR3b3JrIGhlYXRtYXAgcGxvdCwgbWFya2VycyBmcm9tIExvbyBldCBhbC4iLGNvbD1teWhlYXRjb2wpCmBgYApgYGB7cn0KcGxvdERlbmRyb0FuZENvbG9ycyhzZWxlY3RUcmVlLHNlbGVjdENvbG9ycywKICAgICAgICAgICAgICAgICAgICAgIk1vZHVsZSBjb2xvcnMiLAogICAgICAgICAgICAgICAgICAgICBkZW5kcm9MYWJlbHMgPSBOVUxMLCBoYW5nID0gMC4wMywKICAgICAgICAgICAgICAgICAgICAgYWRkR3VpZGUgPSBUUlVFLCBndWlkZUhhbmcgPSAwLjA1KQpgYGAKCgpgYGB7cn0Kc2Vzc2lvbkluZm8oKQpgYGAKCg==