1 Lots of samples!

1.1 Load all the data

## The biomart annotations file already exists, loading from it.
## Reading the sample metadata.
## The sample definitions comprises: 285 rows(samples) and 30 columns(metadata fields).
## Reading count tables.
## Using the transcript to gene mapping.
## Reading salmon data with tximport.
## Finished reading count tables.
## Matched 19629 annotations and counts.
## Bringing together the count matrix and gene information.
## Hey, your new gene map IDs are not the rownames of your gene information, changing them now.
## Some annotations were lost in merging, setting them to 'undefined'.

3 Perform a sample run of GSVA

Take the above expressionset and perform GSVA using it and a simple, controlled subset as the trainer.

## There were 266, now there are 203 samples.
## This function will replace the expt$expressionset slot with:
## rpkm(hpgl(data))
## It backs up the current data into a slot named:
##  expt$backup_expressionset. It will also save copies of each step along the way
##  in expt$normalized with the corresponding libsizes. Keep the libsizes in mind
##  when invoking limma.  The appropriate libsize is the non-log(cpm(normalized)).
##  This is most likely kept at:
##  'new_expt$normalized$intermediate_counts$normalization$libsizes'
##  A copy of this may also be found at:
##  new_expt$best_libsize
## Leaving the data in its current base format, keep in mind that
##  some metrics are easier to see when the data is log2 transformed, but
##  EdgeR/DESeq do not accept transformed data.
## Leaving the data unnormalized.  This is necessary for DESeq, but
##  EdgeR/limma might benefit from normalization.  Good choices include quantile,
##  size-factor, tmm, etc.
## Not correcting the count-data for batch effects.  If batch is
##  included in EdgerR/limma's model, then this is probably wise; but in extreme
##  batch effects this is a good parameter to play with.
## Step 1: performing count filter with option: hpgl
## Removing 5595 low-count genes (14034 remaining).
## Step 2: not normalizing the data.
## Step 3: converting the data with rpkm.
## Step 4: not transforming the data.
## Step 5: not doing batch correction.
## Converting the rownames() of the expressionset to ENTREZID.
## Converting the rownames() of the expressionset to ENTREZID.
## Converting the rownames() of the expressionset to ENTREZID.

4 Invoke GSVA

##   [1] "Melanocytes%FANTOM%1.txt"                                                 
##   [2] "GSE9988_ANTI_TREM1_VS_VEHICLE_TREATED_MONOCYTES_UP"                       
##   [3] "GSE9988_ANTI_TREM1_VS_CTRL_TREATED_MONOCYTES_UP"                          
##   [4] "GSE9988_ANTI_TREM1_AND_LPS_VS_CTRL_TREATED_MONOCYTES_UP"                  
##   [5] "Mesangial cells%ENCODE%2.txt"                                             
##   [6] "GSE9988_ANTI_TREM1_AND_LPS_VS_VEHICLE_TREATED_MONOCYTES_UP"               
##   [7] "Epithelial cells%HPCA%2.txt"                                              
##   [8] "GSE22140_HEALTHY_VS_ARTHRITIC_GERMFREE_MOUSE_CD4_TCELL_DN"                
##   [9] "Chondrocytes%HPCA%3.txt"                                                  
##  [10] "GSE9988_LOW_LPS_VS_ANTI_TREM1_AND_LPS_MONOCYTE_DN"                        
##  [11] "ELSAYED_MACROPHAGE_INFECTED_HGH"                                          
##  [12] "Epithelial cells%HPCA%1.txt"                                              
##  [13] "GSE9988_LPS_VS_LPS_AND_ANTI_TREM1_MONOCYTE_DN"                            
##  [14] "NK cells%NOVERSHTERN%1.txt"                                               
##  [15] "Monocytes%IRIS%2.txt"                                                     
##  [16] "GSE9988_LOW_LPS_VS_CTRL_TREATED_MONOCYTE_UP"                              
##  [17] "Neurons%ENCODE%1.txt"                                                     
##  [18] "Monocytes%BLUEPRINT%3.txt"                                                
##  [19] "GSE2706_UNSTIM_VS_2H_R848_DC_DN"                                          
##  [20] "GSE9988_LOW_LPS_VS_VEHICLE_TREATED_MONOCYTE_UP"                           
##  [21] "GSE9988_LPS_VS_VEHICLE_TREATED_MONOCYTE_UP"                               
##  [22] "ELSAYED_MACROPHAGE_UNINFECTED_HGH"                                        
##  [23] "cDC%HPCA%3.txt"                                                           
##  [24] "GSE22140_GERMFREE_VS_SPF_MOUSE_CD4_TCELL_DN"                              
##  [25] "GSE22886_DAY0_VS_DAY1_MONOCYTE_IN_CULTURE_DN"                             
##  [26] "Monocytes%NOVERSHTERN%3.txt"                                              
##  [27] "Chondrocytes%HPCA%2.txt"                                                  
##  [28] "GSE19401_NAIVE_VS_IMMUNIZED_MOUSE_PLN_FOLLICULAR_DC_UP"                   
##  [29] "Keratinocytes%ENCODE%3.txt"                                               
##  [30] "GSE9988_LPS_VS_CTRL_TREATED_MONOCYTE_UP"                                  
##  [31] "GSE2706_UNSTIM_VS_2H_LPS_DC_DN"                                           
##  [32] "HSC%FANTOM%3.txt"                                                         
##  [33] "HSC%NOVERSHTERN%2.txt"                                                    
##  [34] "GSE22196_HEALTHY_VS_OBESE_MOUSE_SKIN_GAMMADELTA_TCELL_DN"                 
##  [35] "Monocytes%IRIS%1.txt"                                                     
##  [36] "Eosinophils%BLUEPRINT%3.txt"                                              
##  [37] "Sebocytes%FANTOM%2.txt"                                                   
##  [38] "GSE29617_CTRL_VS_DAY7_TIV_FLU_VACCINE_PBMC_2008_UP"                       
##  [39] "HSC%FANTOM%2.txt"                                                         
##  [40] "Monocytes%HPCA%1.txt"                                                     
##  [41] "Eosinophils%NOVERSHTERN%1.txt"                                            
##  [42] "Monocytes%IRIS%3.txt"                                                     
##  [43] "Monocytes%BLUEPRINT%1.txt"                                                
##  [44] "GSE2706_UNSTIM_VS_2H_LPS_AND_R848_DC_DN"                                  
##  [45] "Eosinophils%BLUEPRINT%1.txt"                                              
##  [46] "GSE36891_POLYIC_TLR3_VS_PAM_TLR2_STIM_PERITONEAL_MACROPHAGE_UP"           
##  [47] "GSE9988_ANTI_TREM1_VS_LOW_LPS_MONOCYTE_UP"                                
##  [48] "GSE1432_1H_VS_24H_IFNG_MICROGLIA_UP"                                      
##  [49] "GSE9988_ANTI_TREM1_VS_LPS_MONOCYTE_UP"                                    
##  [50] "GSE14769_UNSTIM_VS_80MIN_LPS_BMDM_DN"                                     
##  [51] "GSE18791_CTRL_VS_NEWCASTLE_VIRUS_DC_2H_DN"                                
##  [52] "Monocytes%NOVERSHTERN%2.txt"                                              
##  [53] "pDC%FANTOM%2.txt"                                                         
##  [54] "aDC%IRIS%1.txt"                                                           
##  [55] "GMP%NOVERSHTERN%1.txt"                                                    
##  [56] "GMP%NOVERSHTERN%2.txt"                                                    
##  [57] "GMP%NOVERSHTERN%3.txt"                                                    
##  [58] "GSE37605_TREG_VS_TCONV_NOD_FOXP3_FUSION_GFP_UP"                           
##  [59] "GSE22886_DAY1_VS_DAY7_MONOCYTE_IN_CULTURE_UP"                             
##  [60] "NK cells%NOVERSHTERN%2.txt"                                               
##  [61] "Chondrocytes%HPCA%1.txt"                                                  
##  [62] "CMP%BLUEPRINT%1.txt"                                                      
##  [63] "GSE9988_ANTI_TREM1_VS_ANTI_TREM1_AND_LPS_MONOCYTE_DN"                     
##  [64] "Tregs%HPCA%1.txt"                                                         
##  [65] "Erythrocytes%FANTOM%2.txt"                                                
##  [66] "GSE36891_UNSTIM_VS_POLYIC_TLR3_STIM_PERITONEAL_MACROPHAGE_UP"             
##  [67] "GSE14769_UNSTIM_VS_40MIN_LPS_BMDM_DN"                                     
##  [68] "GSE30971_CTRL_VS_LPS_STIM_MACROPHAGE_WBP7_HET_2H_UP"                      
##  [69] "CMP%BLUEPRINT%2.txt"                                                      
##  [70] "Tregs%HPCA%3.txt"                                                         
##  [71] "GSE19401_UNSTIM_VS_RETINOIC_ACID_AND_PAM2CSK4_STIM_FOLLICULAR_DC_DN"      
##  [72] "GSE14769_UNSTIM_VS_60MIN_LPS_BMDM_DN"                                     
##  [73] "GSE12392_IFNAR_KO_VS_IFNB_KO_CD8_NEG_SPLEEN_DC_UP"                        
##  [74] "iDC%HPCA%3.txt"                                                           
##  [75] "CMP%BLUEPRINT%3.txt"                                                      
##  [76] "GSE25123_CTRL_VS_ROSIGLITAZONE_STIM_PPARG_KO_MACROPHAGE_UP"               
##  [77] "Myocytes%FANTOM%2.txt"                                                    
##  [78] "Sebocytes%FANTOM%1.txt"                                                   
##  [79] "pDC%FANTOM%3.txt"                                                         
##  [80] "GSE46606_UNSTIM_VS_CD40L_IL2_IL5_1DAY_STIMULATED_IRF4HIGH_SORTED_BCELL_DN"
##  [81] "GSE3920_UNTREATED_VS_IFNG_TREATED_ENDOTHELIAL_CELL_UP"                    
##  [82] "NK cells%FANTOM%1.txt"                                                    
##  [83] "Eosinophils%BLUEPRINT%2.txt"                                              
##  [84] "CD4+ Tem%NOVERSHTERN%2.txt"                                               
##  [85] "CD4+ Tem%NOVERSHTERN%3.txt"                                               
##  [86] "GSE30971_CTRL_VS_LPS_STIM_MACROPHAGE_WBP7_KO_2H_UP"                       
##  [87] "GSE30971_CTRL_VS_LPS_STIM_MACROPHAGE_WBP7_KO_4H_UP"                       
##  [88] "Sebocytes%FANTOM%3.txt"                                                   
##  [89] "GSE369_PRE_VS_POST_IL6_INJECTION_SOCS3_KO_LIVER_UP"                       
##  [90] "GSE6269_FLU_VS_STAPH_AUREUS_INF_PBMC_DN"                                  
##  [91] "GSE40666_STAT1_KO_VS_STAT4_KO_CD8_TCELL_DN"                               
##  [92] "GSE45365_WT_VS_IFNAR_KO_CD8A_DC_DN"                                       
##  [93] "Pericytes%FANTOM%2.txt"                                                   
##  [94] "GSE27434_WT_VS_DNMT1_KO_TREG_DN"                                          
##  [95] "Astrocytes%ENCODE%3.txt"                                                  
##  [96] "GSE34156_NOD2_LIGAND_VS_TLR1_TLR2_LIGAND_6H_TREATED_MONOCYTE_DN"          
##  [97] "GSE19923_WT_VS_HEB_AND_E2A_KO_DP_THYMOCYTE_DN"                            
##  [98] "GSE21360_SECONDARY_VS_QUATERNARY_MEMORY_CD8_TCELL_UP"                     
##  [99] "GSE29617_CTRL_VS_TIV_FLU_VACCINE_PBMC_2008_UP"                            
## [100] "Neurons%FANTOM%1.txt"
##  [1] "Melanocytes%FANTOM%1.txt"                                  
##  [2] "GSE9988_ANTI_TREM1_VS_VEHICLE_TREATED_MONOCYTES_UP"        
##  [3] "GSE9988_ANTI_TREM1_VS_CTRL_TREATED_MONOCYTES_UP"           
##  [4] "GSE9988_ANTI_TREM1_AND_LPS_VS_CTRL_TREATED_MONOCYTES_UP"   
##  [5] "Mesangial cells%ENCODE%2.txt"                              
##  [6] "GSE9988_ANTI_TREM1_AND_LPS_VS_VEHICLE_TREATED_MONOCYTES_UP"
##  [7] "Epithelial cells%HPCA%2.txt"                               
##  [8] "GSE22140_HEALTHY_VS_ARTHRITIC_GERMFREE_MOUSE_CD4_TCELL_DN" 
##  [9] "Chondrocytes%HPCA%3.txt"                                   
## [10] "GSE9988_LOW_LPS_VS_ANTI_TREM1_AND_LPS_MONOCYTE_DN"         
## [11] "ELSAYED_MACROPHAGE_INFECTED_HGH"                           
## [12] "Epithelial cells%HPCA%1.txt"                               
## [13] "GSE9988_LPS_VS_LPS_AND_ANTI_TREM1_MONOCYTE_DN"             
## [14] "NK cells%NOVERSHTERN%1.txt"                                
## [15] "Monocytes%IRIS%2.txt"                                      
## [16] "GSE9988_LOW_LPS_VS_CTRL_TREATED_MONOCYTE_UP"               
## [17] "Neurons%ENCODE%1.txt"                                      
## [18] "Monocytes%BLUEPRINT%3.txt"                                 
## [19] "GSE2706_UNSTIM_VS_2H_R848_DC_DN"                           
## [20] "GSE9988_LOW_LPS_VS_VEHICLE_TREATED_MONOCYTE_UP"            
## [21] "GSE9988_LPS_VS_VEHICLE_TREATED_MONOCYTE_UP"                
## [22] "ELSAYED_MACROPHAGE_UNINFECTED_HGH"                         
## [23] "cDC%HPCA%3.txt"                                            
## [24] "GSE22140_GERMFREE_VS_SPF_MOUSE_CD4_TCELL_DN"               
## [25] "GSE22886_DAY0_VS_DAY1_MONOCYTE_IN_CULTURE_DN"              
## [26] "Monocytes%NOVERSHTERN%3.txt"                               
## [27] "Chondrocytes%HPCA%2.txt"                                   
## [28] "GSE19401_NAIVE_VS_IMMUNIZED_MOUSE_PLN_FOLLICULAR_DC_UP"    
## [29] "Keratinocytes%ENCODE%3.txt"                                
## [30] "GSE9988_LPS_VS_CTRL_TREATED_MONOCYTE_UP"                   
## [31] "GSE2706_UNSTIM_VS_2H_LPS_DC_DN"                            
## [32] "HSC%FANTOM%3.txt"                                          
## [33] "HSC%NOVERSHTERN%2.txt"                                     
## [34] "GSE22196_HEALTHY_VS_OBESE_MOUSE_SKIN_GAMMADELTA_TCELL_DN"  
## [35] "Monocytes%IRIS%1.txt"                                      
## [36] "Eosinophils%BLUEPRINT%3.txt"                               
## [37] "Sebocytes%FANTOM%2.txt"                                    
## [38] "GSE29617_CTRL_VS_DAY7_TIV_FLU_VACCINE_PBMC_2008_UP"        
## [39] "HSC%FANTOM%2.txt"                                          
## [40] "Monocytes%HPCA%1.txt"

6 Venn the elements of the intersections

A corollary question from scoring: what signatures are shared/unique to each set of genes, infected/uninfected? We can use a set of venn diagrams to explore that question…

7 Venn genes in signatures for infected and uninfected samples

Now lets go one step deeper, completing a logical circle…

## 'select()' returned 1:many mapping between keys and columns

7.1 Repeat the above query but better

The following block attempts to formalize the logic above and make it possible to query these intersections in more flexible and hopefully informative ways.

## Examining the mean score for experimental factor: infected from column: infectstate.
## Examining the mean score for experimental factor: uninfected from column: infectstate.

7.2 The final piece of circular logic

What about genes implicated in the infected-only, uninfected-only, and shared signature sets? Well, our intersect_signatures() function provides an opportunity to query even that…

##  9816  3559  6723 23212 29889  1503 
##    25    23    22    22    21    21
## If you wish to reproduce this exact build of hpgltools, invoke the following:
## > git clone http://github.com/abelew/hpgltools.git
## > git reset 7c4477bb4fa3639cc6cf7940216e4c4b8cbee7ce
## This is hpgltools commit: Fri Oct 26 17:27:11 2018 -0400: 7c4477bb4fa3639cc6cf7940216e4c4b8cbee7ce
## Saving to 05_gsva_testing_v20180828.rda.xz
LS0tCnRpdGxlOiAiTGVpc2htYW5pYSBzdHJhaW5zIDIwMTgwODI4OiBQbGF5aW5nIHdpdGggR1NWQS4iCmF1dGhvcjogImF0YiBhYmVsZXdAZ21haWwuY29tIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKICBybWRmb3JtYXRzOjpyZWFkdGhlZG93bjoKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgZmlnX2hlaWdodDogNwogICAgZmlnX3dpZHRoOiA3CiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICB3aWR0aDogMzAwCiAgICBrZWVwX21kOiBmYWxzZQogICAgbW9kZTogc2VsZmNvbnRhaW5lZAogICAgdG9jX2Zsb2F0OiB0cnVlCiAgQmlvY1N0eWxlOjpodG1sX2RvY3VtZW50OgogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgZmlnX2hlaWdodDogNwogICAgZmlnX3dpZHRoOiA3CiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICBrZWVwX21kOiBmYWxzZQogICAgbW9kZTogc2VsZmNvbnRhaW5lZAogICAgdG9jX2Zsb2F0OiB0cnVlCiAgaHRtbF9kb2N1bWVudDoKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgZmlnX2NhcHRpb246IHRydWUKICAgIGZpZ19oZWlnaHQ6IDcKICAgIGZpZ193aWR0aDogNwogICAgaGlnaGxpZ2h0OiB0YW5nbwogICAga2VlcF9tZDogZmFsc2UKICAgIG1vZGU6IHNlbGZjb250YWluZWQKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgc2VsZl9jb250YWluZWQ6IHRydWUKICAgIHRoZW1lOiByZWFkYWJsZQogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogZmFsc2UKICAgICAgc21vb3RoX3Njcm9sbDogZmFsc2UKLS0tCgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgpib2R5LCB0ZCB7CiAgZm9udC1zaXplOiAxNnB4Owp9CmNvZGUucnsKICBmb250LXNpemU6IDE2cHg7Cn0KcHJlIHsKIGZvbnQtc2l6ZTogMTZweAp9Cjwvc3R5bGU+CgpgYGB7ciBvcHRpb25zLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KCJocGdsdG9vbHMiKQp0dCA8LSBkZXZ0b29sczo6bG9hZF9hbGwoIn4vaHBnbHRvb2xzIikKa25pdHI6Om9wdHNfa25pdCRzZXQod2lkdGg9MTIwLAogICAgICAgICAgICAgICAgICAgICBwcm9ncmVzcz1UUlVFLAogICAgICAgICAgICAgICAgICAgICB2ZXJib3NlPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgIGVjaG89VFJVRSkKa25pdHI6Om9wdHNfY2h1bmskc2V0KGVycm9yPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgICBkcGk9OTYpCm9sZF9vcHRpb25zIDwtIG9wdGlvbnMoZGlnaXRzPTQsCiAgICAgICAgICAgICAgICAgICAgICAgbWF4LnByaW50PTEyMCwKICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdzQXNGYWN0b3JzPUZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgIGtuaXRyLmR1cGxpY2F0ZS5sYWJlbD0iYWxsb3ciKQpnZ3Bsb3QyOjp0aGVtZV9zZXQoZ2dwbG90Mjo6dGhlbWVfYncoYmFzZV9zaXplPTEwKSkKdmVyIDwtICIyMDE4MDgyOCIKcHJldmlvdXNfZmlsZSA8LSBwYXN0ZTAoIjAxX2Fubm90YXRpb25fdiIsIHZlciwgIi5SbWQiKQoKdG1wIDwtIHRyeShzbShsb2FkbWUoZmlsZW5hbWU9Z3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSJcXC5yZGFcXC54eiIsIHg9cHJldmlvdXNfZmlsZSkpKSkKcm1kX2ZpbGUgPC0gcGFzdGUwKCIwNV9nc3ZhX3Rlc3RpbmdfdiIsIHZlciwgIi5SbWQiKQpzYXZlZmlsZSA8LSBnc3ViKHBhdHRlcm49IlxcLlJtZCIsIHJlcGxhY2U9IlxcLnJkYVxcLnh6IiwgeD1ybWRfZmlsZSkKYGBgCgojIExvdHMgb2Ygc2FtcGxlcyEKCiMjIExvYWQgYWxsIHRoZSBkYXRhCgpgYGB7ciBsb3RzX29mX3NhbXBsZXN9CmhzX2Fubm90IDwtIGxvYWRfYmlvbWFydF9hbm5vdGF0aW9ucygpJGFubm90YXRpb24Kcm93bmFtZXMoaHNfYW5ub3QpIDwtIG1ha2UubmFtZXMoCiAgcGFzdGUwKGhzX2Fubm90W1siZW5zZW1ibF90cmFuc2NyaXB0X2lkIl1dLCAiLiIsCiAgICAgICAgIGhzX2Fubm90W1sidHJhbnNjcmlwdF92ZXJzaW9uIl1dKSwKICB1bmlxdWU9VFJVRSkKaHNfdHhfZ2VuZSA8LSBoc19hbm5vdFssIGMoImVuc2VtYmxfZ2VuZV9pZCIsICJlbnNlbWJsX3RyYW5zY3JpcHRfaWQiKV0KaHNfdHhfZ2VuZVtbImlkIl1dIDwtIHJvd25hbWVzKGhzX3R4X2dlbmUpCmhzX3R4X2dlbmUgPC0gaHNfdHhfZ2VuZVssIGMoImlkIiwgImVuc2VtYmxfZ2VuZV9pZCIpXQpuZXdfaHNfYW5ub3QgPC0gaHNfYW5ub3QKcm93bmFtZXMobmV3X2hzX2Fubm90KSA8LSBtYWtlLm5hbWVzKGhzX2Fubm90W1siZW5zZW1ibF9nZW5lX2lkIl1dLCB1bmlxdWU9VFJVRSkKbG90cyA8LSBjcmVhdGVfZXhwdChtZXRhZGF0YT0ic2FtcGxlX3NoZWV0cy9tYW55X3NhbXBsZXMueGxzeCIsCiAgICAgICAgICAgICAgICAgICAgZ2VuZV9pbmZvPW5ld19oc19hbm5vdCwKICAgICAgICAgICAgICAgICAgICB0eF9nZW5lX21hcD1oc190eF9nZW5lKQpgYGAKCiMgQ3JlYXRlIGEgbmV3IEdTQwoKVGhlIGdlbmUgc2V0IGNvbGxlY3Rpb25zIGF2YWlsYWJsZSBpbiBHU1ZBIGFyZSBhIGJpdCBvdXQgb2YgZGF0ZTsgdGh1cyB0aGUKZm9sbG93aW5nIHNob3VsZCBjcmVhdGUgYSBmcmVzaCBjb3B5IHVzaW5nIHRoZSBkYXRhIGZpbGVzIGRvd25sb2FkZWQgZnJvbQpCcm9hZC4KCiMjIE1ha2UgR1NDIGZyb20geG1sCgpUaGVyZSBhcmUgdHdvIHJlZHVuZGFudCB3YXlzIHRvIGdldCB0aGUgc2FtZSBHU0MuIEluIHRoZSBmaXJzdCBpbnN0YW5jZSwgd2UKcGFyc2UgdGhlIG91dCBvZiB0aGUgbGFyZ2VyIFhNTCBmaWxlIHByb3ZpZGVkIGJ5IEJyb2FkLgoKYGBge3IgY3JlYXRlX2dzY194bWwsIGV2YWw9RkFMU0V9CmJyb2FkX2dzYyA8LSBHU0VBQmFzZTo6Z2V0QnJvYWRTZXRzKCJyZWZlcmVuY2UvbXNpZ2RiX3Y2LjIvbXNpZ2RiX3Y2LjIueG1sIikKYnJvYWRfdHlwZXMgPC0gc2FwcGx5KGJyb2FkX2dzYywgZnVuY3Rpb24oZWx0KSBHU0VBQmFzZTo6YmNDYXRlZ29yeShHU0VBQmFzZTo6Y29sbGVjdGlvblR5cGUoZWx0KSkpCmM3X2Zyb21feG1sIDwtIGJyb2FkX2dzY1ticm9hZF90eXBlcyA9PSAiYzciXQpgYGAKCiMjIEZyb20gZ210CgpUaGUgZm9sbG93aW5nIGluc3RhbmNlIGlzIHRoZSBvbmUgSSB3aWxsIGFjdHVhbGx5IHVzZSwganVzdCBiZWNhdXNlIEkgZmVlbCBsaWtlCml0IHdpbGwgdGFrZSBsZXNzIHRpbWUgdG8gZ2V0IHRoZW0gZnJvbSB0aGUgZ210IGZpbGVzLgoKYGBge3IgY3JlYXRlX2dzY19nbXR9CiMjIEluIHRoaXMgc2Vjb25kIGluc3RhbmNlLCB3ZSBnZXQgdGhlbSBmcm9tIHRoZSBnbXQgZmlsZSBmb3IgYzcgZXhwbGljaXRseS4KYnJvYWRfYzcgPC0gR1NFQUJhc2U6OmdldEdtdCgicmVmZXJlbmNlL21zaWdkYl92Ni4yL2M3LmFsbC52Ni4yLmVudHJlei5nbXQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbGxlY3Rpb25UeXBlPUdTRUFCYXNlOjpCcm9hZENvbGxlY3Rpb24oY2F0ZWdvcnk9ImM3IiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuZUlkVHlwZT1HU0VBQmFzZTo6RW50cmV6SWRlbnRpZmllcigpKQpsaWJyYXJ5KHhDZWxsKQpkYXRhKHhDZWxsLmRhdGEpCnhjZWxsX2RhdGEgPC0geENlbGwuZGF0YVtbInNpZ25hdHVyZXMiXV0KeGNlbGxfZW50cmV6IDwtIGNvbnZlcnRfZ3NjX2lkcyh4Y2VsbF9kYXRhLCBmcm9tX3R5cGU9IlNZTUJPTCIpCgpjb2xsZWN0aW9uIDwtIGxpc3QoKQpjN19sc3QgPC0gYXMubGlzdChicm9hZF9jNykKeGNlbGxfbHN0IDwtIGFzLmxpc3QoeGNlbGxfZW50cmV6KQpmb3IgKGMgaW4gMTpsZW5ndGgoYzdfbHN0KSkgewogIG5hbWUgPC0gbmFtZXMoYzdfbHN0KVtjXQogIGdzIDwtIGM3X2xzdFtbY11dCiAgY29sbGVjdGlvbltbbmFtZV1dIDwtIGdzCn0KZm9yIChjIGluIDE6bGVuZ3RoKHhjZWxsX2xzdCkpIHsKICBuYW1lIDwtIG5hbWVzKHhjZWxsX2xzdClbY10KICBncyA8LSB4Y2VsbF9sc3RbW2NdXQogIGNvbGxlY3Rpb25bW25hbWVdXSA8LSBncwp9CmBgYAoKIyBQZXJmb3JtIGEgc2FtcGxlIHJ1biBvZiBHU1ZBCgpUYWtlIHRoZSBhYm92ZSBleHByZXNzaW9uc2V0IGFuZCBwZXJmb3JtIEdTVkEgdXNpbmcgaXQgYW5kIGEgc2ltcGxlLCBjb250cm9sbGVkIHN1YnNldAphcyB0aGUgdHJhaW5lci4KCmBgYHtyIG91cl9jb2xsZWN0aW9ufQptYWNyX2RhdGEgPC0gc3Vic2V0X2V4cHQobG90cywgc3Vic2V0PSJjb25kaXRpb249PSdtYWNyb3BoYWdlJyIpCm1hY3Jfbm9ybSA8LSBub3JtYWxpemVfZXhwdChtYWNyX2RhdGEsIGZpbHRlcj1UUlVFLCBjb252ZXJ0PSJycGttIiwgY29sdW1uPSJjZHNfbGVuZ3RoIikKCnBhaXJfZGVsdGEgPC0gZXhwcnMobWFjcl9ub3JtKVssICJocGdsMDM3NiJdIC8gZXhwcnMobWFjcl9ub3JtKVssICJocGdsMDM3NSJdCnBhaXJfdXBfaWR4IDwtIG9yZGVyKHBhaXJfZGVsdGEsIGRlY3JlYXNpbmc9VFJVRSkKcGFpcl9kb3duX2lkeCA8LSBvcmRlcihwYWlyX2RlbHRhLCBkZWNyZWFzaW5nPUZBTFNFKQpwYWlyX3VwIDwtIHBhaXJfZGVsdGFbcGFpcl91cF9pZHhdCnBhaXJfZG93biA8LSBwYWlyX2RlbHRhW3BhaXJfZG93bl9pZHhdCgpzaW5nbGVfaW5mIDwtIGV4cHJzKG1hY3Jfbm9ybSlbLCAiaHBnbDAzNzYiXQpzaW5nbGVfdW5pbmYgPC0gZXhwcnMobWFjcl9ub3JtKVssICJocGdsMDM3NSJdCnNpbmdsZWluZl9oaWdoX2lkeCA8LSBvcmRlcihzaW5nbGVfaW5mLCBkZWNyZWFzaW5nPVRSVUUpCnNpbmdsZWluZl9sb3dfaWR4IDwtIG9yZGVyKHNpbmdsZV9pbmYsIGRlY3JlYXNpbmc9RkFMU0UpCnNpbmdsZWluZl9oaWdoIDwtIHNpbmdsZV9pbmZbc2luZ2xlaW5mX2hpZ2hfaWR4XQpzaW5nbGVpbmZfbG93IDwtIHNpbmdsZV9pbmZbc2luZ2xlaW5mX2xvd19pZHhdCgpzaW5nbGV1bmluZl9oaWdoX2lkeCA8LSBvcmRlcihzaW5nbGVfdW5pbmYsIGRlY3JlYXNpbmc9VFJVRSkKc2luZ2xldW5pbmZfbG93X2lkeCA8LSBvcmRlcihzaW5nbGVfdW5pbmYsIGRlY3JlYXNpbmc9RkFMU0UpCnNpbmdsZXVuaW5mX2hpZ2ggPC0gc2luZ2xlX3VuaW5mW3NpbmdsZXVuaW5mX2hpZ2hfaWR4XQpzaW5nbGV1bmluZl9sb3cgPC0gc2luZ2xlX3VuaW5mW3NpbmdsZXVuaW5mX2xvd19pZHhdCgpudW0gPC0gMTAwCnVwIDwtIG5hbWVzKGhlYWQocGFpcl91cCwgbj1udW0pKQpkbiA8LSBuYW1lcyhoZWFkKHBhaXJfZG93biwgbj1udW0pKQpwYWlyX2dzYyA8LSBtYWtlX2dzY19mcm9tX2lkcyh1cCwgZG4sIHBhaXJfbmFtZXM9YygidXAiLCAiZG4iKSkKCmhnaGluZiA8LSBuYW1lcyhoZWFkKHNpbmdsZWluZl9oaWdoLCBuPW51bSkpCmxvd2luZiA8LSBuYW1lcyhoZWFkKHNpbmdsZWluZl9sb3csIG49bnVtKSkKaW5mX2dzYyA8LSBtYWtlX2dzY19mcm9tX2lkcyhoZ2hpbmYsIGxvd2luZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXRlZ29yeV9uYW1lPSJpbmZlY3RlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFpcl9uYW1lcz1jKCJoZ2giLCAibG93IikpCgpoZ2h1bmluZiA8LSBuYW1lcyhoZWFkKHNpbmdsZXVuaW5mX2hpZ2gsIG49bnVtKSkKbG93dW5pbmYgPC0gbmFtZXMoaGVhZChzaW5nbGV1bmluZl9sb3csIG49bnVtKSkKdW5pbmZfZ3NjIDwtIG1ha2VfZ3NjX2Zyb21faWRzKGhnaHVuaW5mLCBsb3d1bmluZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGVnb3J5X25hbWU9InVuaW5mZWN0ZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFpcl9uYW1lcz1jKCJoZ2giLCAibG93IikpCgpvdXJfbHN0IDwtIGxpc3QoCiAgcGFpcl9nc2NbWzFdXSwgcGFpcl9nc2NbWzJdXSwKICBpbmZfZ3NjW1sxXV0sIGluZl9nc2NbWzJdXSwKICB1bmluZl9nc2NbWzFdXSwgdW5pbmZfZ3NjW1syXV0pCm5hbWVzKG91cl9sc3QpIDwtIGMobmFtZXMocGFpcl9nc2MpWzFdLCBuYW1lcyhwYWlyX2dzYylbMl0sCiAgICAgICAgICAgICAgICAgICAgbmFtZXMoaW5mX2dzYylbMV0sIG5hbWVzKGluZl9nc2MpWzJdLAogICAgICAgICAgICAgICAgICAgIG5hbWVzKHVuaW5mX2dzYylbMV0sIG5hbWVzKHVuaW5mX2dzYylbMl0pCmZvciAoYyBpbiAxOmxlbmd0aChvdXJfbHN0KSkgewogIG5hbWUgPC0gbmFtZXMob3VyX2xzdClbY10KICBncyA8LSBvdXJfbHN0W1tjXV0KICBjb2xsZWN0aW9uW1tuYW1lXV0gPC0gZ3MKfQp0dCA8LSBzbShsaWJyYXJ5KEdTRUFCYXNlKSkKY29sbGVjdGlvbl9nc2MgPC0gR2VuZVNldENvbGxlY3Rpb24oY29sbGVjdGlvbikKYGBgCgojIEludm9rZSBHU1ZBCgpgYGB7ciB0ZXN0X291cl9jb2xsZWN0aW9ufQpvdXJfdGVzdCA8LSBzbShzaW1wbGVfZ3N2YShtYWNyX25vcm0sIHNpZ25hdHVyZXM9Y29sbGVjdGlvbl9nc2MpKQpvdXJfdGVzdF9kYXRhIDwtIGV4cHJzKG91cl90ZXN0JGV4cHQpCnJhbmtfc2NvcmUgPC0gb3JkZXIob3VyX3Rlc3RfZGF0YVssICJocGdsMDM3NiJdLCBkZWNyZWFzaW5nPVRSVUUpCnRvcF9yYW5rIDwtIG91cl90ZXN0X2RhdGFbcmFua19zY29yZSwgXQp0b3BfMTAwIDwtIGhlYWQodG9wX3JhbmtbLCAiaHBnbDAzNzYiXSwgbj0xMDApCmhlYWQocHJpbnQobmFtZXModG9wXzEwMCkpLCBuPTQwKQpgYGAKCiMgUmVzY29yZSBHU1ZBIHJlc3VsdHMKClRoZSBzY29yZXMgZnJvbSBnc3ZhIGFyZSBhIGxpdHRsZSBkaWZmaWN1bHQgdG8gaW50ZXJwcmV0LCBidXQgZm9sbG93IGEgbm9ybWFsCmRpc3RyaWJ1dGlvbi4gIFRodXMgdGhlIGZvbGxvd2luZyBibG9jayBzZXJ2ZXMgdG8gcmVzY29yZSB0aGVtIGFzIHRoZWlyIHotc2NvcmUKd2l0aGluIHRoZWlyIGRpc3RyaWJ1dGlvbi4KCmBgYHtyIHJlc2NvcmV9CmhwZ2xfMDM3Nl9saWtlbGlob29kcyA8LSBnc3ZhX2xpa2VsaWhvb2RzKG91cl90ZXN0LCBzYW1wbGU9ImhwZ2wwMzc2IikKaHBnbF8wMzc1X2xpa2VsaWhvb2RzIDwtIGdzdmFfbGlrZWxpaG9vZHMob3VyX3Rlc3QsIHNhbXBsZT0iaHBnbDAzNzUiKQplc19pbmZlY3RlZF9oZ2hfbGlrZWxpaG9vZHMgPC0gZ3N2YV9saWtlbGlob29kcyhvdXJfdGVzdCwgY2F0ZWdvcnk9IkVMU0FZRURfTUFDUk9QSEFHRV9JTkZFQ1RFRF9IR0giKQoKIyMgSGVyZSBpcyBhIGhpc3RvZ3JhbSBzaG93aW5nIHRoZSBvZGQgZGlzdHJpYnV0aW9ucyBvZiBzY29yZXMgYWZ0ZXIgcmVzY29yaW5nLi4uCnBsb3RfaGlzdG9ncmFtKGhwZ2xfMDM3Nl9saWtlbGlob29kcykKcGxvdF9oaXN0b2dyYW0oaHBnbF8wMzc1X2xpa2VsaWhvb2RzKQpwbG90X2hpc3RvZ3JhbShlc19pbmZlY3RlZF9oZ2hfbGlrZWxpaG9vZHMpCgppbmZfdG9wMjAwIDwtIGhlYWQoaHBnbF8wMzc2X2xpa2VsaWhvb2RzLCBuPTIwMCkKdW5pbmZfdG9wMjAwIDwtIGhlYWQoaHBnbF8wMzc1X2xpa2VsaWhvb2RzLCBuPTIwMCkKYGBgCgojIFZlbm4gdGhlIGVsZW1lbnRzIG9mIHRoZSBpbnRlcnNlY3Rpb25zCgpBIGNvcm9sbGFyeSBxdWVzdGlvbiBmcm9tIHNjb3Jpbmc6IHdoYXQgc2lnbmF0dXJlcyBhcmUgc2hhcmVkL3VuaXF1ZSB0byBlYWNoIHNldApvZiBnZW5lcywgaW5mZWN0ZWQvdW5pbmZlY3RlZD8gIFdlIGNhbiB1c2UgYSBzZXQgb2YgdmVubiBkaWFncmFtcyB0byBleHBsb3JlCnRoYXQgcXVlc3Rpb24uLi4KCmBgYHtyIHZlbm5fc2NvcmVzfQpzZXRzIDwtIGxpc3QoImluZiIgPSBuYW1lcyhpbmZfdG9wMjAwKSwgInVuaW5mIiA9IG5hbWVzKHVuaW5mX3RvcDIwMCkpCnZlbm4gPC0gVmVubmVyYWJsZTo6VmVubihTZXRzPXNldHMpCnBsb3QodmVubiwgZG9XZWlnaHRzPUZBTFNFKQppbnRlcnNlY3Rpb25zIDwtIHZlbm5ASW50ZXJzZWN0aW9uU2V0cwoKaW5mX2Fsb25lX3NpZ25hdHVyZXMgPC0gaW50ZXJzZWN0aW9uc1tbMl1dCmFubm90IDwtIGZEYXRhKG91cl90ZXN0JGV4cHQpCmluZl9hbm5vdCA8LSBhbm5vdFtpbmZfYWxvbmVfc2lnbmF0dXJlcywgXQpnZW5lX2lkcyA8LSBpbmZfYW5ub3RbWzJdXQpyZXQgPC0gbGlzdCgpCmZvciAoaSBpbiAxOmxlbmd0aChnZW5lX2lkcykpIHsKICBpZF9sc3QgPC0gZ2VuZV9pZHNbaV0KICBpZHMgPC0gc3Ryc3BsaXQoaWRfbHN0LCAiLCAiKVtbMV1dCiAgZm9yIChqIGluIDE6bGVuZ3RoKGlkcykpIHsKICAgIGVsZW1lbnQgPC0gaWRzW2pdCiAgICBpZiAoaXMubnVsbChyZXRbW2VsZW1lbnRdXSkpIHsKICAgICAgcmV0W1tlbGVtZW50XV0gPC0gMQogICAgfSBlbHNlIHsKICAgICAgcmV0W1tlbGVtZW50XV0gPC0gcmV0W1tlbGVtZW50XV0gKyAxCiAgICB9CiAgfQp9CnJldCA8LSByZXRbb3JkZXIoYXMubnVtZXJpYyhyZXQpLCBkZWNyZWFzaW5nPVRSVUUpIF0KYGBgCgojIyBQcmludCB0aGUgNiBtb3N0LXNoYXJlZCBnZW5lIElEcyBhbW9uZyB0aGUgaW5mZWN0ZWQgc2FtcGxlcwoKYGBge3IgcHJpbnRfaW5mfQpoZWFkKHJldCkKYGBgCgojIyBSZXBlYXQgdGhlIHByb2Nlc3MgZm9yIHRoZSB1bmluZmVjdGVkIHNhbXBsZXMuCgpgYGB7ciByZXBlYXRfdW5pbmZ9CnVuaW5mX2Fsb25lX3NpZ25hdHVyZXMgPC0gaW50ZXJzZWN0aW9uc1tbM11dCmFubm90IDwtIGZEYXRhKG91cl90ZXN0JGV4cHQpCnVuaW5mX2Fubm90IDwtIGFubm90W3VuaW5mX2Fsb25lX3NpZ25hdHVyZXMsIF0KZ2VuZV9pZHMgPC0gdW5pbmZfYW5ub3RbWzJdXQpyZXQyIDwtIGxpc3QoKQpmb3IgKGkgaW4gMTpsZW5ndGgoZ2VuZV9pZHMpKSB7CiAgaWRfbHN0IDwtIGdlbmVfaWRzW2ldCiAgaWRzIDwtIHN0cnNwbGl0KGlkX2xzdCwgIiwgIilbWzFdXQogIGZvciAoaiBpbiAxOmxlbmd0aChpZHMpKSB7CiAgICBlbGVtZW50IDwtIGlkc1tqXQogICAgaWYgKGlzLm51bGwocmV0W1tlbGVtZW50XV0pKSB7CiAgICAgIHJldDJbW2VsZW1lbnRdXSA8LSAxCiAgICB9IGVsc2UgewogICAgICByZXQyW1tlbGVtZW50XV0gPC0gcmV0W1tlbGVtZW50XV0gKyAxCiAgICB9CiAgfQp9CnJldDIgPC0gcmV0MltvcmRlcihhcy5udW1lcmljKHJldDIpLCBkZWNyZWFzaW5nPVRSVUUpIF0KYGBgCgojIyBQcmludCB0aGUgcmVzdWx0IGZvciB1bmluZmVjdGVkIHNhbXBsZXMuCgpgYGB7ciBwcmludF91bmluZn0KaGVhZChyZXQyKQpgYGAKCiMgVmVubiBnZW5lcyBpbiBzaWduYXR1cmVzIGZvciBpbmZlY3RlZCBhbmQgdW5pbmZlY3RlZCBzYW1wbGVzCgpOb3cgbGV0cyBnbyBvbmUgc3RlcCBkZWVwZXIsIGNvbXBsZXRpbmcgYSBsb2dpY2FsIGNpcmNsZS4uLgoKYGBge3IgY2lyY3VsYXJpemVtZX0KIyMgUXVlcnkgZnJvbSBOYWppYjogYSB2ZW5uIG9mIHRoZSBnZW5lcyBpbiB0aGVzZSBpbmZlY3RlZC91bmluZmVjdGVkIHNldHMKaW5mZWN0ZWRfc2lnX2dlbmVzIDwtIG5hbWVzKHJldCkKdW5pbmZlY3RlZF9zaWdfZ2VuZXMgPC0gbmFtZXMocmV0MikKc2V0cyA8LSBsaXN0KCJpbmYiID0gaW5mZWN0ZWRfc2lnX2dlbmVzLCAidW5pbmYiID0gdW5pbmZlY3RlZF9zaWdfZ2VuZXMpCnZlbm4gPC0gVmVubmVyYWJsZTo6VmVubihTZXRzPXNldHMpCnBsb3QodmVubiwgZG9XZWlnaHRzPUZBTFNFKQpnZW5lX2ludGVyc2VjdGlvbnMgPC0gdmVubkBJbnRlcnNlY3Rpb25TZXRzCm9ubHlfaW5mZWN0ZWRfZ2VuZXMgPC0gZ2VuZV9pbnRlcnNlY3Rpb25zW1syXV0Kb25seV91bmluZmVjdGVkX2dlbmVzIDwtIGdlbmVfaW50ZXJzZWN0aW9uc1tbM11dCm9ubHlfaW5mZWN0ZWRfZ2VuZXNfZnJlcXVlbmN5IDwtIHJldFtvbmx5X2luZmVjdGVkX2dlbmVzXQpvbmx5X3VuaW5mZWN0ZWRfZ2VuZXNfZnJlcXVlbmN5IDwtIHJldDJbb25seV91bmluZmVjdGVkX2dlbmVzXQoKdGVuX29yX21vcmUgPC0gZGF0YS5mcmFtZShyb3cubmFtZXM9dGFpbChvbmx5X2luZmVjdGVkX2dlbmVzLCBuPTQyKSkKdGVuX29yX21vcmUkZnJlcXVlbmN5IDwtIHRhaWwoYXMubnVtZXJpYyhvbmx5X2luZmVjdGVkX2dlbmVzX2ZyZXF1ZW5jeSksIG49NDIpCgpsaWJyYXJ5KG9yZy5Icy5lZy5kYikKZW5zZW1ibF9pZHMgPC0gQW5ub3RhdGlvbkRiaTo6c2VsZWN0KHg9b3JnLkhzLmVnLmRiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5cz1yb3duYW1lcyh0ZW5fb3JfbW9yZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXl0eXBlPSJFTlRSRVpJRCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW5zPWMoIkVOU0VNQkwiKSkKbWVyZ2VkX3RlbiA8LSBtZXJnZSh0ZW5fb3JfbW9yZSwgZW5zZW1ibF9pZHMsIGJ5Lng9InJvdy5uYW1lcyIsIGJ5Lnk9IkVOVFJFWklEIikKbWVyZ2VkX3RlbiA8LSBtZXJnZShtZXJnZWRfdGVuLCBoc19hbm5vdCwgYnkueD0iRU5TRU1CTCIsIGJ5Lnk9ImVuc2VtYmxfZ2VuZV9pZCIpCmNvbG5hbWVzKG1lcmdlZF90ZW4pWzJdIDwtICJlbnRyZXppZCIKd3JpdGUuY3N2KGZpbGU9Ii90bXAvbWVyZ2VkX3Rlbi5jc3YiLCBtZXJnZWRfdGVuKQpgYGAKCiMjIFJlcGVhdCB0aGUgYWJvdmUgcXVlcnkgYnV0IGJldHRlcgoKVGhlIGZvbGxvd2luZyBibG9jayBhdHRlbXB0cyB0byBmb3JtYWxpemUgdGhlIGxvZ2ljIGFib3ZlIGFuZCBtYWtlIGl0IHBvc3NpYmxlCnRvIHF1ZXJ5IHRoZXNlIGludGVyc2VjdGlvbnMgaW4gbW9yZSBmbGV4aWJsZSBhbmQgaG9wZWZ1bGx5IGluZm9ybWF0aXZlIHdheXMuCgpgYGB7ciByZXBlYXRfYnV0X2JldHRlcn0KaW5mX2xpa2VsaWhvb2RzIDwtIGdzdmFfbGlrZWxpaG9vZHMob3VyX3Rlc3QsIGZhY3Rvcj0iaW5mZWN0ZWQiLCBmYWN0b3JfY29sdW1uPSJpbmZlY3RzdGF0ZSIpCnVuaW5mX2xpa2VsaWhvb2RzIDwtIGdzdmFfbGlrZWxpaG9vZHMob3VyX3Rlc3QsIGZhY3Rvcj0idW5pbmZlY3RlZCIsIGZhY3Rvcl9jb2x1bW49ImluZmVjdHN0YXRlIikKaW5mX3RvcCA8LSBoZWFkKGluZl9saWtlbGlob29kcywgbj0yMDApCnVuaW5mX3RvcCA8LSBoZWFkKHVuaW5mX2xpa2VsaWhvb2RzLCBuPTIwMCkKaW5mdW5pbmZfbmFtZXMgPC0gbGlzdCgiaW5mIiA9IG5hbWVzKGluZl90b3ApLCAidW5pbmYiID0gbmFtZXModW5pbmZfdG9wKSkKYGBgCgojIyBUaGUgZmluYWwgcGllY2Ugb2YgY2lyY3VsYXIgbG9naWMKCldoYXQgYWJvdXQgZ2VuZXMgaW1wbGljYXRlZCBpbiB0aGUgaW5mZWN0ZWQtb25seSwgdW5pbmZlY3RlZC1vbmx5LCBhbmQgc2hhcmVkCnNpZ25hdHVyZSBzZXRzPyAgV2VsbCwgb3VyIGludGVyc2VjdF9zaWduYXR1cmVzKCkgZnVuY3Rpb24gcHJvdmlkZXMgYW4Kb3Bwb3J0dW5pdHkgdG8gcXVlcnkgZXZlbiB0aGF0Li4uCgpgYGB7ciBmaW5hbF9jaXJjbH0Kc2lnaW50IDwtIGludGVyc2VjdF9zaWduYXR1cmVzKG91cl90ZXN0LCBpbmZ1bmluZl9uYW1lcywgZ2VuZV93ZWlnaHRzPUZBTFNFKQoKIyMgVGhpcyBuZXh0IGxpbmUgc2hvdWxkIHByaW50IHRoZSB0b3AgNiBnZW5lIElEcyBhbmQgdGhlIG51bWJlciBvZiBzaWduYXR1cmVzIHRoZXkgd2VyZQojIyBvYnNlcnZlZCBpbiBhbW9uZyB0aGUgc2lnbmF0dXJlcyB3aGljaCBhcmUgdW5pcXVlIHRvIHRoZSBpbmZlY3RlZCBzYW1wbGVzLgojIyBUaGlzIGlzIGdldHRpbmcgYSBiaXQgbWV0YS4uLgpoZWFkKHNpZ2ludCRzaWduYXR1cmVfZ2VuZXNbWyJpbmYiXV0pCiMjIFRoZXNlIGdlbmVzIHNob3dlZCB1cCBpbiBhIGxvdCBvZiBpbmZlY3Rpb24tcmVsYXRlZCBzaWduYXR1cmVzLgpgYGAKCmBgYHtyIHNhdmVtZX0KaWYgKCFpc1RSVUUoZ2V0MCgic2tpcF9sb2FkIikpKSB7CiAgcGFuZGVyOjpwYW5kZXIoc2Vzc2lvbkluZm8oKSkKICBtZXNzYWdlKHBhc3RlMCgiVGhpcyBpcyBocGdsdG9vbHMgY29tbWl0OiAiLCBnZXRfZ2l0X2NvbW1pdCgpKSkKICBtZXNzYWdlKHBhc3RlMCgiU2F2aW5nIHRvICIsIHNhdmVmaWxlKSkKICB0bXAgPC0gc20oc2F2ZW1lKGZpbGVuYW1lPXNhdmVmaWxlKSkKfQpgYGAK