This notebook identifies samples to include in subset files for the purpose of molecularly subtyping embryonal tumors (AlexsLemonade/OpenPBTA-analysis#251).

This closed pull request is also relevant to the task at hand: [AlexsLemonade/OpenPBTA-analysis#401](https://github.com/AlexsLemonade/OpenPBTA-analysis/pull/401

We’ll use the subset files generated in 02-generate-subset-files.R to construct tables that summarize the data on the subtyping issue.

Usage

This notebook is intended to be run via the command line from the top directory of the repository as follows:

Rscript -e "rmarkdown::render('analyses/molecular-subtyping-embryonal/04-table-prep.Rmd', clean = TRUE)"

Set up

Libraries and functions

subset_dir <- \subset-files\
results_dir <- \results\
data_dir <- file.path(\..\, \..\, \data\)
# full clinical file
histologies_file <- file.path(data_dir, \pbta-histologies.tsv\)
# full fusions of interest file
fusion_file <- file.path(data_dir,\fusion_summary_embryonal_foi.tsv\)
# subset files
manta_file <- file.path(subset_dir, \embryonal_manta_sv.tsv\)
polya_file <- file.path(subset_dir, \embryonal_zscored_exp.polya.rds\)
stranded_file <- file.path(subset_dir, \embryonal_zscored_exp.stranded.rds\)
# file that contains the biospecimen IDs that met criteria for subtyping
biospecimen_file <- file.path(results_dir, 
                              \biospecimen_ids_embryonal_subtyping.tsv\)
# cleaned chr19 data
chr19_file <- file.path(results_dir, \cleaned_chr19_cn.tsv\)
# annotated sex chromosomes copy number alterations
sex_chr_consensus <- file.path(\..\, \focal-cn-file-preparation\, \results\, 
                               \consensus_seg_annotated_cn_x_and_y.tsv.gz\)
sex_chr_cnvkit <- file.path(\..\, \focal-cn-file-preparation\, \results\, 
                            \cnvkit_annotated_cn_x_and_y.tsv.gz\)
sex_chr_controlfreec <- file.path(\..\, \focal-cn-file-preparation\, \results\, 
                                  \controlfreec_annotated_cn_x_and_y.tsv.gz\)

Directories

histologies_df <- read_tsv(histologies_file, 
                           col_types = cols(
                             molecular_subtype = col_character()
                          ))

# manta data for BCOR tandem duplication
manta_sv_df <- read_tsv(manta_file)

# all of the RNA data
polya_exp <- read_rds(polya_file)
stranded_exp <- read_rds(stranded_file)
fusions_df <- read_tsv(fusion_file)

# get biospecimen ids as a vector rather than data frame
biospecimen_ids <- read_tsv(biospecimen_file) %>%
  pull(Kids_First_Biospecimen_ID)

# cleaned chr19 amplification data
chr19_cn_df <- read_tsv(chr19_file)

# we'll filter to only the relevant biospecimens for the copy number alteration
# data that is committed to the repository
consensus_sex_chr <- read_tsv(sex_chr_consensus) %>%
  filter(biospecimen_id %in% biospecimen_ids)
cnvkit_sex_chr <- read_tsv(sex_chr_cnvkit) %>%
  filter(biospecimen_id %in% biospecimen_ids)
controlfreec_sex_chr <- read_tsv(sex_chr_controlfreec) %>%
  filter(biospecimen_id %in% biospecimen_ids)

Read in files

Set up filenames.

output_all <- file.path(results_dir, 
                        \embryonal_tumor_subtyping_relevant_data.tsv\)
output_subtypes  <- file.path(results_dir, 
                              \embryonal_tumor_molecular_subtypes.tsv\)

Read in files.

colnames(fusions_df)
 [1] \Kids_First_Biospecimen_ID\ \MACF1--TTYH1\             
 [3] \MN1--AC008667.1\           \MN1--CXXC5\               
 [5] \MN1--PATZ1\                \MN1--PSD2\                
 [7] \NPAS3--AC245884.4/TTYH1\   \TTYH1--DPRX/RNU6-698P\    
 [9] \TTYH1--MIR512-2/MIR1323\   \TTYH1--MIR515-2/MIR519C\  
[11] \ZC4H2--AL627224.1/FOXR2\   \ZC4H2--FOXR2\             
[13] \CIC--NUTM1\                \MN1--BEND2\               
Kids_First_Biospecimen_ID

MACF1--TTYH1

MN1--AC008667.1

MN1--CXXC5

MN1--PATZ1

MN1--PSD2

NPAS3--AC245884.4/TTYH1

TTYH1--DPRX/RNU6-698P

TTYH1--MIR512-2/MIR1323

TTYH1--MIR515-2/MIR519C

ZC4H2--AL627224.1/FOXR2

ZC4H2--FOXR2

CIC--NUTM1

MN1--BEND2

Output file

ttyh1_fusions <- wrangle_fusions(fusions_df, \TTYH1--\, \TTYH1_fusions\)
mn1_fusions <- wrangle_fusions(fusions_df, \MN1--\, \MN1_fusions\) 
foxr2_fusions <- wrangle_fusions(fusions_df, \FOXR2\, \FOXR2_fusions\)
cic_fusions <- wrangle_fusions(fusions_df, \CIC--\, \CIC_fusions\)
fusions_summary_df <- list(ttyh1_fusions,
                           mn1_fusions,
                           foxr2_fusions,
                           cic_fusions) %>%
  purrr::reduce(dplyr::inner_join, by = \Kids_First_Biospecimen_ID\)
# remove data.frame we no longer need
rm(ttyh1_fusions, mn1_fusions, foxr2_fusions, cic_fusions, fusions_df)

Wrangle data

Fusion data

Summarizing the salient points from AlexsLemonade/OpenPBTA-analysis#251:

ETMR, C19MC-altered: These tumors have focal amplification of the miRNA cluster on chr19 (denoted C19MC) and often have gene fusions involving TTYH1 and chr19 miRNA cluster genes

CNS HGNET-MN1: Contain gene fusions involving 5’ MN1. 3’ fusion partners can include BEND2 and CXXC5.

CNS NB-FOXR2: Over-expression and/or gene fusions in FOXR2

CNS EFT-CIC: Alterations in CIC, commonly fused with NUTM1

head(fusions_summary_df %>% arrange(desc(TTYH1_fusions)), n = 10)
exp_genes_of_interest <- c(\LIN28A\, \FOXR2\)
# set up poly-A data
polya_exp <- polya_exp[, exp_genes_of_interest] %>%
  as.data.frame() %>%
  tibble::rownames_to_column(\Kids_First_Biospecimen_ID\)
# set up stranded data
stranded_exp <- stranded_exp[, exp_genes_of_interest] %>%
  as.data.frame() %>%
  tibble::rownames_to_column(\Kids_First_Biospecimen_ID\)

# bind together both datasets, but keep track of what selection strategy was
# used
exp_df <- bind_rows(\polya\ = polya_exp, 
                    \stranded\ = stranded_exp, 
                    .id = \exp_dataset\) %>%
  select(-exp_dataset, everything())

# remove data.frame we no longer need
rm(polya_exp, stranded_exp, exp_genes_of_interest)
rna_df <- exp_df %>%
  left_join(fusions_summary_df) %>%
  select(-exp_dataset, everything())
# remove data.frame we no longer need
rm(exp_df)

Expression data

Summarizing salient points from AlexsLemonade/OpenPBTA-analysis#251:

ETMR, C19MC-altered: These tumors have high expression of LIN28A and serves as a biomarker for ETMRs

CNS NB-FOXR2: Over-expression and/or gene fusions in FOXR2

ETMR, NOS: These tumors have high expression of LIN28A and serves as a biomarker for ETMRs, but do not show focal amplification of C19MC.

head(rna_df, n = 10)

Join RNA data

# only include rows from Manta that make reference to BCOR, pass all filters
# https://github.com/Illumina/manta/blob/75b5c38d4fcd2f6961197b28a41eb61856f2d976/docs/userGuide/README.md#vcf-format-fields
# and are recorded as tandem duplication events
bcor_sv_df <- manta_sv_df %>%
  filter(str_detect(Gene.name, \BCOR\),
         FILTER == \PASS\,
         ALT == \<DUP:TANDEM>\)

# take a look at the genes 
bcor_sv_df %>% 
  head(n = 2) %>%
  pull(Gene.name)
[1] \ABCB7/ACE2/ACOT9/ADGRG2/AKAP4/ALAS2/AMELX/AMER1/ANOS1/AP1S2/APEX2/APOO/APOOL/AR/ARAF/ARHGAP6/ARHGEF9/ARHGEF9-IT1/ARR3/ARX/ASB11/ASB12/ASB9/ATP6AP2/ATP7A/ATRX/ATXN3L/AWAT1/AWAT2/BCLAF3/BCOR/BEND2/BMP15/BMX/BRDTP1/BRWD3/CA5B/CA5BP1/CA5BP1-CA5B/CACNA1F/CASK/CBLL2/CCDC120/CCDC22/CCNB3/CDK16/CDKL5/CDX4/CENPVL1/CENPVL2/CENPVL3/CFAP47/CFP/CHIC1/CHM/CHMP1B2P/CHST7/CITED1/CLCN4/CLCN5/CLDN34/CLTRN/CNKSR2/COX7B/CPXCR1/CTPS2/CXCR3/CXXC1P1/CXorf21/CXorf38/CXorf49/CXorf49B/CXorf58/CXorf65/CXorf67/CYBB/CYLC1/CYSLTR1/DACH2/DCAF8L1/DCAF8L2/DDX3X/DDX53/DGAT2L6/DGKK/DIAPH2/DIAPH2-AS1/DIPK2B/DLG3/DLG3-AS1/DMD/DMRTC1/DMRTC1B/DUSP21/DYNLT3/EBP/EDA/EDA2R/EFHC2/EFNB1/EGFL6/EIF1AX/EIF1AX-AS1/EIF2S3/ELK1/ERAS/ERCC6L/FAAH2/FAM104B/FAM120C/FAM133A/FAM155B/FAM156A/FAM156B/FAM226A/FAM226B/FAM236A/FAM236B/FAM236C/FAM236D/FAM47A/FAM47B/FAM47C/FAM9A/FAM9B/FAM9C/FANCB/FGD1/FGF16/FLICR/FLJ44635/FOXO4/FOXP3/FOXR2/FRMD8P1/FRMPD4/FTH1P18/FTHL17/FTSJ1/FTX/FUNDC1/GAGE1/GAGE10/GAGE12B/GAGE12C/GAGE12D/GAGE12E/GAGE12F/GAGE12G/GAGE12H/GAGE12I/GAGE12J/GAGE13/GAGE2A/GAGE2B/GAGE2C/GAGE2D/GAGE2E/GAGE4/GAGE5/GAGE6/GAGE7/GAGE8/GATA1/GCNA/GDPD2/GEMIN8/GJB1/GK/GLOD5/GLRA2/GNL3L/GPKOW/GPM6B/GPR143/GPR173/GPR174/GPR34/GPR82/GRIPAP1/GRPR/GS1-594A7.3/GS1-600G8.3/GSPT2/HCCS/HDAC6/HDAC8/HDX/HEPH/HMGN5/HSD17B10/HUWE1/HYPM/IGBP1/IL1RAPL1/IL2RG/INE1/INE2/INGX/IQSEC2/ITGB1BP2/ITIH6/ITM2A/JADE3/JPX/KANTR/KCND1/KDM5C/KDM6A/KIF4A/KLF8/KLHL15/KLHL34/KLHL4/KRBOX4/LANCL3/LAS1L/LINC00269/LINC00891/LINC01186/LINC01203/LINC01204/LINC01278/LINC01281/LINC01282/LINC01284/LINC01456/LINC01496/LINC01545/LINC01560/LINC02154/LINC02595/LINC02601/LOC100129291/LOC100132741/LOC100132831/LOC100421746/LOC101059915/LOC101927476/LOC101927635/LOC101928128/LOC101928201/LOC101928389/LOC101928627/LOC105373156/LOC392452/LOC729609/LPAR4/MAGEB1/MAGEB10/MAGEB16/MAGEB17/MAGEB18/MAGEB2/MAGEB3/MAGEB4/MAGEB5/MAGEB6/MAGED1/MAGED2/MAGED4/MAGED4B/MAGEE1/MAGEE2/MAGEH1/MAGIX/MAGT1/MAOA/MAOB/MAP2K4P1/MAP3K15/MAP7D2/MBTPS2/MED12/MED14/MED14OS/MID1/MID1IP1/MID1IP1-AS1/MIR1321/MIR1468/MIR1587/MIR188/MIR221/MIR222/MIR223/MIR23C/MIR325/MIR325HG/MIR361/MIR362/MIR374A/MIR374B/MIR374C/MIR384/MIR3915/MIR3937/MIR421/MIR4328/MIR4454/MIR4536-1/MIR4536-2/MIR4666B/MIR4767/MIR4768/MIR4769/MIR4770/MIR500A/MIR500B/MIR501/MIR502/MIR532/MIR545/MIR548AJ2/MIR548AM/MIR548AX/MIR548F5/MIR548I4/MIR548M/MIR6086/MIR6134/MIR651/MIR660/MIR676/MIR6857/MIR6894/MIR6895/MIR8088/MIR98/MIRLET7F2/MOSPD2/MPC1L/MSL3/MSN/MTMR8/MTRNR2L10/NAP1L2/NAP1L3/NAP1L6/NBDY/NDP/NDP-AS1/NDUFB11/NEXMIF/NHS/NHS-AS1/NHSL2/NLGN3/NLGN4X/NLRP2B/NONO/NR0B1/NUDT10/NUDT11/NYX/OFD1/OGT/OPHN1/OTC/OTUD5/OTUD6A/P2RY10/P2RY4/PABPC1L2A/PABPC1L2B/PABPC1L2B-AS1/PABPC5/PABPC5-AS1/PAGE1/PAGE2/PAGE2B/PAGE3/PAGE4/PAGE5/PBDC1/PCDH11X/PCSK1N/PCYT1B/PCYT1B-AS1/PDHA1/PDK3/PDZD11/PFKFB1/PGAM4/PGK1/PHEX/PHEX-AS1/PHF8/PHKA1/PHKA1-AS1/PHKA2/PHKA2-AS1/PIGA/PIM2/PIN4/PINCR/PIR/PIR-FIGF/PJA1/PLP2/PNPLA4/POF1B/POLA1/PORCN/POU3F4/PPEF1/PPEF1-AS1/PPP1R2C/PPP1R3F/PPP4R3C/PQBP1/PRAF2/PRDX4/PRICKLE3/PRPS2/PRRG1/PTCHD1/PTCHD1-AS/PUDP/RAB41/RAB9A/RAI2/RBBP7/RBM10/RBM3/REPS2/RGN/RIBC1/RLIM/RP2/RPA4/RPGR/RPS26P11/RPS4X/RPS6KA3/RPS6KA6/RRAGB/RS1/RTL3/RTL5/S100G/SAT1/SATL1/SCARNA23/SCARNA9L/SCML1/SCML2/SH3BGRL/SH3KBP1/SHROOM2/SHROOM4/SLC16A2/SLC35A2/SLC38A5/SLC7A3/SLC9A7/SMC1A/SMPX/SMS/SNORA109/SNORA11/SNORA11C/SNORA11D/SNORA11E/SNORA11G/SNORD3E/SNX12/SPACA5/SPACA5B/SPANXN5/SPIN2A/SPIN2B/SPIN3/SPIN4/SRPX/SSX1/SSX2/SSX2B/SSX3/SSX4/SSX4B/SSX5/SSX6P/SSX7/SSX8P/SSX9P/STARD8/STS/SUPT20HL1/SUPT20HL2/SUV39H1/SYAP1/SYN1/SYP/SYP-AS1/SYTL5/TAB3/TAB3-AS1/TAF1/TAF9B/TBC1D25/TBL1X/TBX22/TCEANC/TENT5D/TEX11/TFE3/TGIF2LX/TIMM17B/TIMP1/TLR7/TLR8/TLR8-AS1/TMEM47/TMSB4X/TRAPPC2/TRO/TSIX/TSPAN7/TSPYL2/TSR2/TTC3P1/TXLNG/UBA1/UBE2DNL/UBE2E4P/UBQLN2/UPRT/UQCRBP1/USP11/USP27X/USP27X-AS1/USP51/USP9X/UXT/UXT-AS1/VCX/VCX2/VCX3A/VCX3B/VEGFD/VENTXP1/VSIG4/WAS/WDR13/WDR45/WNK3/WWC3/XAGE1A/XAGE1B/XAGE2/XAGE3/XAGE5/XIST/XK/YIPF6/YY2/ZC3H12B/ZC4H2/ZCCHC13/ZDHHC15/ZFX/ZFX-AS1/ZMYM3/ZNF157/ZNF182/ZNF41/ZNF630/ZNF630-AS1/ZNF674/ZNF674-AS1/ZNF711/ZNF81/ZRSR2/ZXDA/ZXDB\
[2] \ACE2/ACOT9/ADGRG2/AMELX/ANOS1/AP1S2/APOO/ARHGAP6/ARX/ASB11/ASB9/ATP6AP2/ATXN3L/BCLAF3/BCOR/BEND2/BMX/CA5B/CA5BP1/CA5BP1-CA5B/CASK/CBLL2/CDKL5/CFAP47/CLCN4/CLDN34/CLTRN/CNKSR2/CTPS2/CXorf21/CXorf38/CXorf58/CYBB/DCAF8L1/DCAF8L2/DDX3X/DDX53/DIPK2B/DMD/DUSP21/DYNLT3/EFHC2/EGFL6/EIF1AX/EIF1AX-AS1/EIF2S3/FAM47A/FAM47B/FAM47C/FAM9A/FAM9B/FAM9C/FANCB/FRMPD4/FTH1P18/FTHL17/FUNDC1/GEMIN8/GK/GLRA2/GPM6B/GPR143/GPR34/GPR82/GRPR/GS1-594A7.3/GS1-600G8.3/HCCS/HYPM/IL1RAPL1/INE2/KDM6A/KLHL15/KLHL34/KRBOX4/LANCL3/LINC01186/LINC01203/LINC01204/LINC01281/LINC01282/LINC01456/LINC02154/LINC02595/LINC02601/LOC100132831/LOC101927476/LOC101928389/LOC101928627/LOC392452/LOC729609/MAGEB1/MAGEB10/MAGEB16/MAGEB17/MAGEB18/MAGEB2/MAGEB3/MAGEB4/MAGEB5/MAGEB6/MAOA/MAOB/MAP3K15/MAP7D2/MBTPS2/MED14/MED14OS/MID1/MID1IP1/MID1IP1-AS1/MIR1587/MIR221/MIR222/MIR23C/MIR3915/MIR3937/MIR4666B/MIR4767/MIR4768/MIR548AJ2/MIR548AM/MIR548AX/MIR548F5/MIR6086/MIR6134/MIR651/MOSPD2/MPC1L/MSL3/NDP/NDP-AS1/NHS/NHS-AS1/NR0B1/NYX/OFD1/OTC/PCYT1B/PCYT1B-AS1/PDHA1/PDK3/PHEX/PHEX-AS1/PHKA2/PHKA2-AS1/PIGA/PINCR/PIR/PIR-FIGF/PNPLA4/POLA1/PPEF1/PPEF1-AS1/PPP1R2C/PPP4R3C/PRDX4/PRPS2/PRRG1/PTCHD1/PTCHD1-AS/PUDP/RAB9A/RAI2/RBBP7/REPS2/RPGR/RPS6KA3/RS1/S100G/SAT1/SCARNA23/SCARNA9L/SCML1/SCML2/SH3KBP1/SHROOM2/SMPX/SMS/SRPX/STS/SUPT20HL1/SUPT20HL2/SYAP1/SYTL5/TAB3/TAB3-AS1/TBL1X/TCEANC/TLR7/TLR8/TLR8-AS1/TMEM47/TMSB4X/TRAPPC2/TSPAN7/TXLNG/UBE2E4P/USP9X/VCX/VCX2/VCX3B/VEGFD/VENTXP1/WWC3/XK/YY2/ZFX/ZFX-AS1/ZNF674/ZNF674-AS1/ZRSR2\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
ABCB7/ACE2/ACOT9/ADGRG2/AKAP4/ALAS2/AMELX/AMER1/ANOS1/AP1S2/APEX2/APOO/APOOL/AR/ARAF/ARHGAP6/ARHGEF9/ARHGEF9-IT1/ARR3/ARX/ASB11/ASB12/ASB9/ATP6AP2/ATP7A/ATRX/ATXN3L/AWAT1/AWAT2/BCLAF3/BCOR/BEND2/BMP15/BMX/BRDTP1/BRWD3/CA5B/CA5BP1/CA5BP1-CA5B/CACNA1F/CASK/CBLL2/CCDC120/CCDC22/CCNB3/CDK16/CDKL5/CDX4/CENPVL1/CENPVL2/CENPVL3/CFAP47/CFP/CHIC1/CHM/CHMP1B2P/CHST7/CITED1/CLCN4/CLCN5/CLDN34/CLTRN/CNKSR2/COX7B/CPXCR1/CTPS2/CXCR3/CXXC1P1/CXorf21/CXorf38/CXorf49/CXorf49B/CXorf58/CXorf65/CXorf67/CYBB/CYLC1/CYSLTR1/DACH2/DCAF8L1/DCAF8L2/DDX3X/DDX53/DGAT2L6/DGKK/DIAPH2/DIAPH2-AS1/DIPK2B/DLG3/DLG3-AS1/DMD/DMRTC1/DMRTC1B/DUSP21/DYNLT3/EBP/EDA/EDA2R/EFHC2/EFNB1/EGFL6/EIF1AX/EIF1AX-AS1/EIF2S3/ELK1/ERAS/ERCC6L/FAAH2/FAM104B/FAM120C/FAM133A/FAM155B/FAM156A/FAM156B/FAM226A/FAM226B/FAM236A/FAM236B/FAM236C/FAM236D/FAM47A/FAM47B/FAM47C/FAM9A/FAM9B/FAM9C/FANCB/FGD1/FGF16/FLICR/FLJ44635/FOXO4/FOXP3/FOXR2/FRMD8P1/FRMPD4/FTH1P18/FTHL17/FTSJ1/FTX/FUNDC1/GAGE1/GAGE10/GAGE12B/GAGE12C/GAGE12D/GAGE12E/GAGE12F/GAGE12G/GAGE12H/GAGE12I/GAGE12J/GAGE13/GAGE2A/GAGE2B/GAGE2C/GAGE2D/GAGE2E/GAGE4/GAGE5/GAGE6/GAGE7/GAGE8/GATA1/GCNA/GDPD2/GEMIN8/GJB1/GK/GLOD5/GLRA2/GNL3L/GPKOW/GPM6B/GPR143/GPR173/GPR174/GPR34/GPR82/GRIPAP1/GRPR/GS1-594A7.3/GS1-600G8.3/GSPT2/HCCS/HDAC6/HDAC8/HDX/HEPH/HMGN5/HSD17B10/HUWE1/HYPM/IGBP1/IL1RAPL1/IL2RG/INE1/INE2/INGX/IQSEC2/ITGB1BP2/ITIH6/ITM2A/JADE3/JPX/KANTR/KCND1/KDM5C/KDM6A/KIF4A/KLF8/KLHL15/KLHL34/KLHL4/KRBOX4/LANCL3/LAS1L/LINC00269/LINC00891/LINC01186/LINC01203/LINC01204/LINC01278/LINC01281/LINC01282/LINC01284/LINC01456/LINC01496/LINC01545/LINC01560/LINC02154/LINC02595/LINC02601/LOC100129291/LOC100132741/LOC100132831/LOC100421746/LOC101059915/LOC101927476/LOC101927635/LOC101928128/LOC101928201/LOC101928389/LOC101928627/LOC105373156/LOC392452/LOC729609/LPAR4/MAGEB1/MAGEB10/MAGEB16/MAGEB17/MAGEB18/MAGEB2/MAGEB3/MAGEB4/MAGEB5/MAGEB6/MAGED1/MAGED2/MAGED4/MAGED4B/MAGEE1/MAGEE2/MAGEH1/MAGIX/MAGT1/MAOA/MAOB/MAP2K4P1/MAP3K15/MAP7D2/MBTPS2/MED12/MED14/MED14OS/MID1/MID1IP1/MID1IP1-AS1/MIR1321/MIR1468/MIR1587/MIR188/MIR221/MIR222/MIR223/MIR23C/MIR325/MIR325HG/MIR361/MIR362/MIR374A/MIR374B/MIR374C/MIR384/MIR3915/MIR3937/MIR421/MIR4328/MIR4454/MIR4536-1/MIR4536-2/MIR4666B/MIR4767/MIR4768/MIR4769/MIR4770/MIR500A/MIR500B/MIR501/MIR502/MIR532/MIR545/MIR548AJ2/MIR548AM/MIR548AX/MIR548F5/MIR548I4/MIR548M/MIR6086/MIR6134/MIR651/MIR660/MIR676/MIR6857/MIR6894/MIR6895/MIR8088/MIR98/MIRLET7F2/MOSPD2/MPC1L/MSL3/MSN/MTMR8/MTRNR2L10/NAP1L2/NAP1L3/NAP1L6/NBDY/NDP/NDP-AS1/NDUFB11/NEXMIF/NHS/NHS-AS1/NHSL2/NLGN3/NLGN4X/NLRP2B/NONO/NR0B1/NUDT10/NUDT11/NYX/OFD1/OGT/OPHN1/OTC/OTUD5/OTUD6A/P2RY10/P2RY4/PABPC1L2A/PABPC1L2B/PABPC1L2B-AS1/PABPC5/PABPC5-AS1/PAGE1/PAGE2/PAGE2B/PAGE3/PAGE4/PAGE5/PBDC1/PCDH11X/PCSK1N/PCYT1B/PCYT1B-AS1/PDHA1/PDK3/PDZD11/PFKFB1/PGAM4/PGK1/PHEX/PHEX-AS1/PHF8/PHKA1/PHKA1-AS1/PHKA2/PHKA2-AS1/PIGA/PIM2/PIN4/PINCR/PIR/PIR-FIGF/PJA1/PLP2/PNPLA4/POF1B/POLA1/PORCN/POU3F4/PPEF1/PPEF1-AS1/PPP1R2C/PPP1R3F/PPP4R3C/PQBP1/PRAF2/PRDX4/PRICKLE3/PRPS2/PRRG1/PTCHD1/PTCHD1-AS/PUDP/RAB41/RAB9A/RAI2/RBBP7/RBM10/RBM3/REPS2/RGN/RIBC1/RLIM/RP2/RPA4/RPGR/RPS26P11/RPS4X/RPS6KA3/RPS6KA6/RRAGB/RS1/RTL3/RTL5/S100G/SAT1/SATL1/SCARNA23/SCARNA9L/SCML1/SCML2/SH3BGRL/SH3KBP1/SHROOM2/SHROOM4/SLC16A2/SLC35A2/SLC38A5/SLC7A3/SLC9A7/SMC1A/SMPX/SMS/SNORA109/SNORA11/SNORA11C/SNORA11D/SNORA11E/SNORA11G/SNORD3E/SNX12/SPACA5/SPACA5B/SPANXN5/SPIN2A/SPIN2B/SPIN3/SPIN4/SRPX/SSX1/SSX2/SSX2B/SSX3/SSX4/SSX4B/SSX5/SSX6P/SSX7/SSX8P/SSX9P/STARD8/STS/SUPT20HL1/SUPT20HL2/SUV39H1/SYAP1/SYN1/SYP/SYP-AS1/SYTL5/TAB3/TAB3-AS1/TAF1/TAF9B/TBC1D25/TBL1X/TBX22/TCEANC/TENT5D/TEX11/TFE3/TGIF2LX/TIMM17B/TIMP1/TLR7/TLR8/TLR8-AS1/TMEM47/TMSB4X/TRAPPC2/TRO/TSIX/TSPAN7/TSPYL2/TSR2/TTC3P1/TXLNG/UBA1/UBE2DNL/UBE2E4P/UBQLN2/UPRT/UQCRBP1/USP11/USP27X/USP27X-AS1/USP51/USP9X/UXT/UXT-AS1/VCX/VCX2/VCX3A/VCX3B/VEGFD/VENTXP1/VSIG4/WAS/WDR13/WDR45/WNK3/WWC3/XAGE1A/XAGE1B/XAGE2/XAGE3/XAGE5/XIST/XK/YIPF6/YY2/ZC3H12B/ZC4H2/ZCCHC13/ZDHHC15/ZFX/ZFX-AS1/ZMYM3/ZNF157/ZNF182/ZNF41/ZNF630/ZNF630-AS1/ZNF674/ZNF674-AS1/ZNF711/ZNF81/ZRSR2/ZXDA/ZXDB

ACE2/ACOT9/ADGRG2/AMELX/ANOS1/AP1S2/APOO/ARHGAP6/ARX/ASB11/ASB9/ATP6AP2/ATXN3L/BCLAF3/BCOR/BEND2/BMX/CA5B/CA5BP1/CA5BP1-CA5B/CASK/CBLL2/CDKL5/CFAP47/CLCN4/CLDN34/CLTRN/CNKSR2/CTPS2/CXorf21/CXorf38/CXorf58/CYBB/DCAF8L1/DCAF8L2/DDX3X/DDX53/DIPK2B/DMD/DUSP21/DYNLT3/EFHC2/EGFL6/EIF1AX/EIF1AX-AS1/EIF2S3/FAM47A/FAM47B/FAM47C/FAM9A/FAM9B/FAM9C/FANCB/FRMPD4/FTH1P18/FTHL17/FUNDC1/GEMIN8/GK/GLRA2/GPM6B/GPR143/GPR34/GPR82/GRPR/GS1-594A7.3/GS1-600G8.3/HCCS/HYPM/IL1RAPL1/INE2/KDM6A/KLHL15/KLHL34/KRBOX4/LANCL3/LINC01186/LINC01203/LINC01204/LINC01281/LINC01282/LINC01456/LINC02154/LINC02595/LINC02601/LOC100132831/LOC101927476/LOC101928389/LOC101928627/LOC392452/LOC729609/MAGEB1/MAGEB10/MAGEB16/MAGEB17/MAGEB18/MAGEB2/MAGEB3/MAGEB4/MAGEB5/MAGEB6/MAOA/MAOB/MAP3K15/MAP7D2/MBTPS2/MED14/MED14OS/MID1/MID1IP1/MID1IP1-AS1/MIR1587/MIR221/MIR222/MIR23C/MIR3915/MIR3937/MIR4666B/MIR4767/MIR4768/MIR548AJ2/MIR548AM/MIR548AX/MIR548F5/MIR6086/MIR6134/MIR651/MOSPD2/MPC1L/MSL3/NDP/NDP-AS1/NHS/NHS-AS1/NR0B1/NYX/OFD1/OTC/PCYT1B/PCYT1B-AS1/PDHA1/PDK3/PHEX/PHEX-AS1/PHKA2/PHKA2-AS1/PIGA/PINCR/PIR/PIR-FIGF/PNPLA4/POLA1/PPEF1/PPEF1-AS1/PPP1R2C/PPP4R3C/PRDX4/PRPS2/PRRG1/PTCHD1/PTCHD1-AS/PUDP/RAB9A/RAI2/RBBP7/REPS2/RPGR/RPS6KA3/RS1/S100G/SAT1/SCARNA23/SCARNA9L/SCML1/SCML2/SH3KBP1/SHROOM2/SMPX/SMS/SRPX/STS/SUPT20HL1/SUPT20HL2/SYAP1/SYTL5/TAB3/TAB3-AS1/TBL1X/TCEANC/TLR7/TLR8/TLR8-AS1/TMEM47/TMSB4X/TRAPPC2/TSPAN7/TXLNG/UBE2E4P/USP9X/VCX/VCX2/VCX3B/VEGFD/VENTXP1/WWC3/XK/YY2/ZFX/ZFX-AS1/ZNF674/ZNF674-AS1/ZRSR2
consensus_sex_chr %>% filter(gene_symbol == \BCOR\) 

We see some repeated negative values for the expression z-scores here. Generally that comes from small or zero log2(FPKM + 1) values. For example, all of the poly-A values for FOXR2 are zero prior to scaling.

Structural variant data

CNS HGNET-BCOR

  • CNS high-grade neuroepithelial tumor with BCOR alteration
  • Tumors have internal tandem duplication of BCOR

The definition of internal tandem duplication from Rustagi et al. BMC Bioinformatics. 2016.:

Detection of tandem duplication within coding exons, referred to as internal tandem duplication (ITD)

The annotated files from the focal-cn-file-preparation module use exons to check for overlaps. So, we can try to supplement the Manta calls with the annotated sex chromosome files.

cnvkit_sex_chr %>% filter(gene_symbol == \BCOR\) 

Not necessarily specific to BCOR alterations.

controlfreec_sex_chr %>% filter(gene_symbol == \BCOR\)
# remove all the sv and cnv data we will not use
rm(bcor_sv_df, manta_sv_df, consensus_sex_chr, controlfreec_sex_chr,
   cnvkit_sex_chr)
identifiers_df <- histologies_df %>%
  select(Kids_First_Participant_ID, 
         sample_id, 
         Kids_First_Biospecimen_ID)
# add IDs to chromosome 19 data
chr19_cn_df <- identifiers_df %>%
  inner_join(chr19_cn_df, by = \Kids_First_Biospecimen_ID\)
# add IDs to RNA data 
rna_df <- identifiers_df %>%
  inner_join(rna_df)

This is not conclusive.

molecular_data_df <- full_join(chr19_cn_df, rna_df,
                               by = c(\Kids_First_Participant_ID\,
                                      \sample_id\)) %>%
  rename(Kids_First_Biospecimen_ID_DNA = Kids_First_Biospecimen_ID.x,
         Kids_First_Biospecimen_ID_RNA = Kids_First_Biospecimen_ID.y)

Final table

Add Kids_First_Participant_ID and sample_id

relevant_clinical_data <- histologies_df %>% 
  filter(Kids_First_Biospecimen_ID %in% biospecimen_ids) %>%
  select(Kids_First_Participant_ID, 
         sample_id,
         age_at_diagnosis_days,
         germline_sex_estimate,
         pathology_diagnosis,
         integrated_diagnosis) %>%
  distinct() %>%
  # convert age to years
  mutate(age_at_diagnosis_yrs = 
           floor(as.numeric(age_at_diagnosis_days) / 365)) %>%
  select(-age_at_diagnosis_days)

all_data_df <- inner_join(relevant_clinical_data,
                          molecular_data_df)

Join molecular data

all_data_df %>%
  select(Kids_First_Participant_ID, 
         sample_id,
         Kids_First_Biospecimen_ID_DNA,
         Kids_First_Biospecimen_ID_RNA,
         age_at_diagnosis_yrs,
         germline_sex_estimate,
         pathology_diagnosis,
         integrated_diagnosis,
         LIN28A,
         TTYH1_fusions,
         chr19_amplification,
         FOXR2,
         FOXR2_fusions,
         MN1_fusions,
         CIC_fusions) %>%
  write_tsv(output_all)

Add clinical data

The following were mentioned in AlexsLemonade/OpenPBTA-analysis#251:

CNS HGNET-BCOR: Median age of diagnosis less than 10 years

CNS HGNET-MN1: Predominantly female patients.

CNS Embryonal, NOS: Tumors previously called PNET that do not fit into other groups above.

all_data_df %>%
  # 3 standard deviations above the mean for LIN28A expression or
  # evidence of C19MC amplification
  filter(LIN28A > 3 | chr19_amplification == \Yes\) %>%
  select(ends_with(\ID\), 
         ends_with(\diagnosis\),
         LIN28A,
         TTYH1_fusions,
         chr19_amplification)

Write to file.

etmr_c19mc_df <- all_data_df %>%
  filter(LIN28A > 3 | chr19_amplification == \Yes\,
         TTYH1_fusions != \None\) %>%
  select(contains(\ID\)) %>%
  mutate(molecular_subtype = \ETMR

Subtyping

ETMR, C19MC-altered and ETMR, NOS

The differences between ETMR, C19MC-altered and ETMR, NOS is a difference in C19MC amplification. We’ll filter on LIN28A overexpression, as that is a feature of both.

Recall that we z-scored these expression values before subsetting the matrix so they are in the context of all samples for a given selection strategy.

# TODO: is this the correct call or should this be a CNS Embryonal, NOS call?
etmr_nos_df <- all_data_df %>%
  filter(LIN28A > 3,
         TTYH1_fusions == \None\) %>%
  select(contains(\ID\)) %>%
  mutate(molecular_subtype = \ETMR

For some samples that have a TTYH1 fusion, we do not have DNA data to check for C19MC amplification but that’s okay per this comment which references Kleinman et al. Nat Genet. 2014.. We will call all samples with a TTYH1 fusion ETMR, C19MC altered.

all_data_df %>%
  # 3 standard deviations above the mean
  filter(MN1_fusions != \None\) %>%
  select(ends_with(\ID\), 
         ends_with(\diagnosis\),
         germline_sex_estimate,
         MN1_fusions)

For now, we will call the sample with a LIN28A z-score > 3 that has no TTYH1 fusion and no copy number data ETMR, NOS.

mn1_fusions <- fusions_summary_df %>%
  filter(MN1_fusions != \None\) 

mn1_fusions

CNS HGNET-MN1

  • CNS high-grade neuroepithelial tumor with MN1 alteration
  • Likely previously diagnosed as PNET.
  • Contain gene fusions involving 5’ MN1. 3’ fusion partners can include BEND2 and CXXC5.
  • Predominantly female patients.
histologies_df %>%
  filter(Kids_First_Biospecimen_ID %in% pull(mn1_fusions, 
                                             Kids_First_Biospecimen_ID)) %>%
  select(Kids_First_Participant_ID, 
         sample_id, 
         Kids_First_Biospecimen_ID,
         pathology_diagnosis,
         integrated_diagnosis,
         germline_sex_estimate)

No samples fit this criteria. There were other samples that did contain MN1 fusions.

hgnet_mn1_df <- histologies_df %>%
  filter(sample_id == \7316-765\) %>%
  select(Kids_First_Participant_ID,
         Kids_First_Biospecimen_ID_RNA = Kids_First_Biospecimen_ID,
         sample_id) %>%
  mutate(molecular_subtype = \CNS HGNET-MN1\)
all_data_df %>%
  filter(FOXR2_fusions != \None\ | FOXR2 > 3) %>%
  select(ends_with(\ID\), 
         ends_with(\diagnosis\),
         FOXR2,
         FOXR2_fusions)

They are classified as Ependymoma and Low-grade astrocytic tumor.

We will call the sample with the MN1–CXXC5 fusion CNS HGNET-MN1.

nb_foxr2_df <- all_data_df %>%
  filter(FOXR2_fusions != \None\ | FOXR2 > 3) %>%
  select(contains(\ID\)) %>%
  mutate(molecular_subtype = \CNS NB-FOXR2\)

CNS HGNET-BCOR

  • CNS high-grade neuroepithelial tumor with BCOR alteration
  • Tumors have internal tandem duplication of BCOR
  • Median age of diagnosis less than 10 years

We have no clear evidence of BCOR alterations.

CNS NB-FOXR2

  • Central nervous system (CNS) neuroblastoma with FOXR2 activation
  • Over-expression and/or gene fusions in FOXR2
all_data_df %>%
  filter(CIC_fusions != \None\)
subtypes_df <- bind_rows(
  etmr_c19mc_df,
  etmr_nos_df,
  hgnet_mn1_df,
  nb_foxr2_df
)

subtypes_df <- all_data_df %>%
  select(contains(\ID\)) %>%
  full_join(subtypes_df) %>%
  replace_na(list(molecular_subtype = \CNS Embryonal

CNS EFT-CIC

  • CNS Ewing sarcoma family tumor with CIC alteration
  • Alterations in CIC, commonly fused with NUTM1
subtypes_df %>%
  write_tsv(output_subtypes)

CNS Embryonal, NOS

  • CNS Embryonal tumor, not otherwise specified
  • Tumors previously called PNET that do not fit into other groups above.

All other samples will be called CNS Embryonal, NOS.

Subtyping file

sessionInfo()
R version 3.6.0 (2019-04-26)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Debian GNU/Linux 9 (stretch)

Matrix products: default
BLAS/LAPACK: /usr/lib/libopenblasp-r0.2.19.so

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

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

other attached packages:
[1] forcats_0.4.0   stringr_1.4.0   dplyr_0.8.3     purrr_0.3.2    
[5] readr_1.3.1     tidyr_0.8.3     tibble_2.1.3    ggplot2_3.2.0  
[9] tidyverse_1.2.1

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.1       plyr_1.8.4       cellranger_1.1.0 pillar_1.4.2    
 [5] compiler_3.6.0   base64enc_0.1-3  tools_3.6.0      digest_0.6.20   
 [9] lubridate_1.7.4  jsonlite_1.6     evaluate_0.14    nlme_3.1-140    
[13] gtable_0.3.0     lattice_0.20-38  pkgconfig_2.0.2  rlang_0.4.0     
[17] cli_1.1.0        rstudioapi_0.10  yaml_2.2.0       haven_2.1.1     
[21] xfun_0.8         withr_2.1.2      xml2_1.2.0       httr_1.4.0      
[25] knitr_1.23       generics_0.0.2   hms_0.4.2        grid_3.6.0      
[29] tidyselect_0.2.5 glue_1.3.1       R6_2.4.0         readxl_1.3.1    
[33] rmarkdown_1.13   reshape2_1.4.3   modelr_0.1.4     magrittr_1.5    
[37] backports_1.1.4  scales_1.0.0     htmltools_0.3.6  rvest_0.3.4     
[41] assertthat_0.2.1 colorspace_1.4-1 stringi_1.4.3    lazyeval_0.2.2  
[45] munsell_0.5.0    broom_0.5.2      crayon_1.3.4    
subtypes_df %>%
  write_tsv(output_subtypes)

Session Info

sessionInfo()
LS0tCnRpdGxlOiAiTW9sZWN1bGFybHkgU3VidHlwaW5nIEVtYnJ5b25hbCBUdW1vcnMgLSBGaW5hbCBUYWJsZSIKb3V0cHV0OiAKICBodG1sX25vdGVib29rOgogICAgdG9jOiBUUlVFCiAgICB0b2NfZmxvYXQ6IFRSVUUKYXV0aG9yOiBTdGVwaGFuaWUgSi4gU3BpZWxtYW4gYW5kIEphY2x5biBUYXJvbmkgZm9yIEFMU0YgQ0NETApkYXRlOiAyMDIwCi0tLQoKVGhpcyBub3RlYm9vayBpZGVudGlmaWVzIHNhbXBsZXMgdG8gaW5jbHVkZSBpbiBzdWJzZXQgZmlsZXMgZm9yIHRoZSBwdXJwb3NlIG9mIG1vbGVjdWxhcmx5IHN1YnR5cGluZyBlbWJyeW9uYWwgdHVtb3JzIChbYEFsZXhzTGVtb25hZGUvT3BlblBCVEEtYW5hbHlzaXMjMjUxYF0oaHR0cHM6Ly9naXRodWIuY29tL0FsZXhzTGVtb25hZGUvT3BlblBCVEEtYW5hbHlzaXMvaXNzdWVzLzI1MSkpLgoKVGhpcyBjbG9zZWQgcHVsbCByZXF1ZXN0IGlzIGFsc28gcmVsZXZhbnQgdG8gdGhlIHRhc2sgYXQgaGFuZDogW2BBbGV4c0xlbW9uYWRlL09wZW5QQlRBLWFuYWx5c2lzIzQwMWBdKGh0dHBzOi8vZ2l0aHViLmNvbS9BbGV4c0xlbW9uYWRlL09wZW5QQlRBLWFuYWx5c2lzL3B1bGwvNDAxCgpXZSdsbCB1c2UgdGhlIHN1YnNldCBmaWxlcyBnZW5lcmF0ZWQgaW4gW2AwMi1nZW5lcmF0ZS1zdWJzZXQtZmlsZXMuUmBdKC4vMDItZ2VuZXJhdGUtc3Vic2V0LWZpbGVzLlIpIHRvIGNvbnN0cnVjdCB0YWJsZXMgdGhhdCBzdW1tYXJpemUgdGhlIGRhdGEgb24gdGhlIHN1YnR5cGluZyBpc3N1ZS4KCiMjIFVzYWdlCgpUaGlzIG5vdGVib29rIGlzIGludGVuZGVkIHRvIGJlIHJ1biB2aWEgdGhlIGNvbW1hbmQgbGluZSBmcm9tIHRoZSB0b3AgZGlyZWN0b3J5Cm9mIHRoZSByZXBvc2l0b3J5IGFzIGZvbGxvd3M6CgpgYGAKUnNjcmlwdCAtZSAicm1hcmtkb3duOjpyZW5kZXIoJ2FuYWx5c2VzL21vbGVjdWxhci1zdWJ0eXBpbmctZW1icnlvbmFsLzA0LXRhYmxlLXByZXAuUm1kJywgY2xlYW4gPSBUUlVFKSIKYGBgCgojIyBTZXQgdXAKCiMjIyBMaWJyYXJpZXMgYW5kIGZ1bmN0aW9ucwoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpgYGAKCmBgYHtyfQojIFRPRE86IGNvbnNpZGVyIG1vdmluZyB0aGlzIG91dCBvZiB0aGlzIG5vdGVib29rIHRvIHVzZSB3aXRoIGVwZW5keW1vbWEgCiMgc3VidHlwaW5nPwp3cmFuZ2xlX2Z1c2lvbnMgPC0gZnVuY3Rpb24oZnVzaW9uc19kZiwgc3RyaW5nX3RvX21hdGNoLCBjb2x1bW5fbmFtZSkgewogICMgVGhpcyBmdW5jdGlvbiB0YWtlcyB0aGUgZnVzaW9uIHN1bW1hcnkgYmluYXJ5IG1hdHJpeCBhbmQgcmV0dXJucyBhIAogICMgZGF0YSBmcmFtZSB0aGF0IGNvbnRhaW5zIHR3byBjb2x1bW5zOiBLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lEIGFuZAogICMgYSBjb2x1bW4gY29udGFpbmluZyBhIGNvbW1hLXNlcGFyYXRlZCAnbGlzdCcgb2YgcmVsZXZhbnQgZnVzaW9ucy4KICAjIEEgInJlbGV2YW50IGZ1c2lvbiIgaXMgZGV0ZXJtaW5lZCBieSBwYXNzaW5nIHRoZSBzdHJpbmdfdG9fbWF0Y2ggYXJndW1lbnQKICAjIHRvIGRwbHlyOjptYXRjaGVzLiBUbyBzcGVjaWZ5IHRoYXQgYSBnZW5lIHN5bWJvbCBzaG91bGQgYmUgYSA1JyBwYXJ0bmVyLAogICMgeW91IGNhbiBwYXNzICI8Z2VuZSBzeW1ib2w+LS0iLiBUaGUgMm5kIGNvbHVtbiBuYW1lIGlzIGRldGVybWluZWQgYnkgdGhlCiAgIyBjb2x1bW5fbmFtZSBhcmd1bWVudC4KICAjCiAgIyBBcmdzOgogICMgICBmdXNpb25zX2RmOiBhIGZ1c2lvbl9zdW1tYXJ5IGRhdGEuZnJhbWUgZnJvbSBgZnVzaW9uLXN1bW1hcnlgCiAgIyAgIHN0cmluZ190b19tYXRjaDogY2hhcmFjdGVyOyBwYXNzZWQgdG8gZHBseXI6Om1hdGNoZXMgdG8gc2VsZWN0IHJlbGV2YW50CiAgIyAgICAgICAgICAgICAgICAgICAgY29sdW1ucwogICMgICBjb2x1bW5fbmFtZTogdGhlIG5hbWUgb2YgdGhlIHJlbGV2YW50IGZ1c2lvbiBjb2x1bW4gaW4gdGhlIGRhdGEuZnJhbWUgCiAgIyAgICAgICAgICAgICAgICB0aGF0IGlzIHJldHVybmVkCiAgIyAKICAjIFJldHVybnM6IGEgZGF0YS5mcmFtZSB3aXRoIEtpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSUQgYW5kIHJlbGV2YW50IGZ1c2lvbnMKICAjICAgICAgICAgIGNvbHVtbnM7IGJpb3NwZWNpbWVucyB3aXRob3V0IGFueSByZWxldmFudCBmdXNpb25zIHdpbGwgaGF2ZSAiTm9uZSIKICAjICAgICAgICAgIGluIHRoZSBzZWNvbmQgY29sdW1uCiAgCiAgc3BlY2lmaWNfZnVzaW9ucyA8LSBmdXNpb25zX2RmICU+JQogICAgIyBvbmx5IGluY2x1ZGUgcmVsZXZhbnQgZnVzaW9ucyB1c2luZyBzdHJpbmdfdG9fbWF0Y2gKICAgIHNlbGVjdChLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lELCBtYXRjaGVzKHN0cmluZ190b19tYXRjaCkpICU+JQogICAgcmVzaGFwZTI6Om1lbHQoKSAlPiUKICAgICMgYSB2YWx1ZSBvZiAwIG1lYW5zIHRoYXQgZnVzaW9uIGlzIG5vdCBwcmVzZW50IGluIHRoYXQgYmlvc3BlY2ltZW4KICAgIGZpbHRlcih2YWx1ZSA+IDApICU+JQogICAgc2VsZWN0KC12YWx1ZSkgJT4lCiAgICBncm91cF9ieShLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lEKSAlPiUKICAgICMgZ2V0IHRoZSBjb21tYSBzZXBhcmF0ZWQgJ2xpc3QnIG9mIHJlbGV2YW50IGZ1c2lvbnMKICAgIHN1bW1hcml6ZSghIWNvbHVtbl9uYW1lIDo9IHBhc3RlKHNvcnQodW5pcXVlKHZhcmlhYmxlKSksIGNvbGxhcHNlID0gIiwgIikpCiAgCiAgIyBpZiBhIHNhbXBsZSBoYWQgbm9uZSBvZiB0aGUgcmVsZXZhbnQgZnVzaW9ucywgaXQncyBtaXNzaW5nIGZyb20gCiAgIyBzcGVjaWZpY19mdXNpb25zIC0tIGxldCdzIGFkZCB0aGVtIGJhY2sgaW4gd2l0aCAiTm9uZSIgaW4gdGhlIHNlY29uZAogICMgY29sdW1uCiAgbWlzc2luZ19pZHMgPC0gc2V0ZGlmZihmdXNpb25zX2RmJEtpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWZpY19mdXNpb25zJEtpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSUQpCiAgc3BlY2lmaWNfZnVzaW9ucyA8LSBzcGVjaWZpY19mdXNpb25zICU+JQogICAgYmluZF9yb3dzKGRhdGEuZnJhbWUoS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCA9IG1pc3NpbmdfaWRzKSkgJT4lCiAgICByZXBsYWNlKGlzLm5hKC4pLCAiTm9uZSIpCiAgCiAgcmV0dXJuKHNwZWNpZmljX2Z1c2lvbnMpCn0KYGBgCgojIyMgRGlyZWN0b3JpZXMKCmBgYHtyfQpzdWJzZXRfZGlyIDwtICJzdWJzZXQtZmlsZXMiCnJlc3VsdHNfZGlyIDwtICJyZXN1bHRzIgpkYXRhX2RpciA8LSBmaWxlLnBhdGgoIi4uIiwgIi4uIiwgImRhdGEiKQpgYGAKCiMjIyBSZWFkIGluIGZpbGVzCgpTZXQgdXAgZmlsZW5hbWVzLgoKYGBge3J9CiMgZnVsbCBjbGluaWNhbCBmaWxlCmhpc3RvbG9naWVzX2ZpbGUgPC0gZmlsZS5wYXRoKGRhdGFfZGlyLCAicGJ0YS1oaXN0b2xvZ2llcy50c3YiKQojIGZ1bGwgZnVzaW9ucyBvZiBpbnRlcmVzdCBmaWxlCmZ1c2lvbl9maWxlIDwtIGZpbGUucGF0aChkYXRhX2RpciwiZnVzaW9uX3N1bW1hcnlfZW1icnlvbmFsX2ZvaS50c3YiKQojIHN1YnNldCBmaWxlcwptYW50YV9maWxlIDwtIGZpbGUucGF0aChzdWJzZXRfZGlyLCAiZW1icnlvbmFsX21hbnRhX3N2LnRzdiIpCnBvbHlhX2ZpbGUgPC0gZmlsZS5wYXRoKHN1YnNldF9kaXIsICJlbWJyeW9uYWxfenNjb3JlZF9leHAucG9seWEucmRzIikKc3RyYW5kZWRfZmlsZSA8LSBmaWxlLnBhdGgoc3Vic2V0X2RpciwgImVtYnJ5b25hbF96c2NvcmVkX2V4cC5zdHJhbmRlZC5yZHMiKQojIGZpbGUgdGhhdCBjb250YWlucyB0aGUgYmlvc3BlY2ltZW4gSURzIHRoYXQgbWV0IGNyaXRlcmlhIGZvciBzdWJ0eXBpbmcKYmlvc3BlY2ltZW5fZmlsZSA8LSBmaWxlLnBhdGgocmVzdWx0c19kaXIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmlvc3BlY2ltZW5faWRzX2VtYnJ5b25hbF9zdWJ0eXBpbmcudHN2IikKIyBjbGVhbmVkIGNocjE5IGRhdGEKY2hyMTlfZmlsZSA8LSBmaWxlLnBhdGgocmVzdWx0c19kaXIsICJjbGVhbmVkX2NocjE5X2NuLnRzdiIpCiMgYW5ub3RhdGVkIHNleCBjaHJvbW9zb21lcyBjb3B5IG51bWJlciBhbHRlcmF0aW9ucwpzZXhfY2hyX2NvbnNlbnN1cyA8LSBmaWxlLnBhdGgoZGF0YV9kaXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY29uc2Vuc3VzX3NlZ19hbm5vdGF0ZWRfY25feF9hbmRfeS50c3YuZ3oiKQpzZXhfY2hyX2NudmtpdCA8LSBmaWxlLnBhdGgoIi4uIiwgImZvY2FsLWNuLWZpbGUtcHJlcGFyYXRpb24iLCAicmVzdWx0cyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImNudmtpdF9hbm5vdGF0ZWRfY25feF9hbmRfeS50c3YuZ3oiKQpzZXhfY2hyX2NvbnRyb2xmcmVlYyA8LSBmaWxlLnBhdGgoIi4uIiwgImZvY2FsLWNuLWZpbGUtcHJlcGFyYXRpb24iLCAicmVzdWx0cyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvbnRyb2xmcmVlY19hbm5vdGF0ZWRfY25feF9hbmRfeS50c3YuZ3oiKQpgYGAKClJlYWQgaW4gZmlsZXMuCgpgYGB7ciBtZXNzYWdlPUZBTFNFfQpoaXN0b2xvZ2llc19kZiA8LSByZWFkX3RzdihoaXN0b2xvZ2llc19maWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sX3R5cGVzID0gY29scygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2xlY3VsYXJfc3VidHlwZSA9IGNvbF9jaGFyYWN0ZXIoKQogICAgICAgICAgICAgICAgICAgICAgICAgICkpCgojIG1hbnRhIGRhdGEgZm9yIEJDT1IgdGFuZGVtIGR1cGxpY2F0aW9uCm1hbnRhX3N2X2RmIDwtIHJlYWRfdHN2KG1hbnRhX2ZpbGUpCgojIGFsbCBvZiB0aGUgUk5BIGRhdGEKcG9seWFfZXhwIDwtIHJlYWRfcmRzKHBvbHlhX2ZpbGUpCnN0cmFuZGVkX2V4cCA8LSByZWFkX3JkcyhzdHJhbmRlZF9maWxlKQpmdXNpb25zX2RmIDwtIHJlYWRfdHN2KGZ1c2lvbl9maWxlKQoKIyBnZXQgYmlvc3BlY2ltZW4gaWRzIGFzIGEgdmVjdG9yIHJhdGhlciB0aGFuIGRhdGEgZnJhbWUKYmlvc3BlY2ltZW5faWRzIDwtIHJlYWRfdHN2KGJpb3NwZWNpbWVuX2ZpbGUpICU+JQogIHB1bGwoS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCkKCiMgY2xlYW5lZCBjaHIxOSBhbXBsaWZpY2F0aW9uIGRhdGEKY2hyMTlfY25fZGYgPC0gcmVhZF90c3YoY2hyMTlfZmlsZSkKCiMgd2UnbGwgZmlsdGVyIHRvIG9ubHkgdGhlIHJlbGV2YW50IGJpb3NwZWNpbWVucyBmb3IgdGhlIGNvcHkgbnVtYmVyIGFsdGVyYXRpb24KIyBkYXRhIHRoYXQgaXMgY29tbWl0dGVkIHRvIHRoZSByZXBvc2l0b3J5CmNvbnNlbnN1c19zZXhfY2hyIDwtIHJlYWRfdHN2KHNleF9jaHJfY29uc2Vuc3VzKSAlPiUKICBmaWx0ZXIoYmlvc3BlY2ltZW5faWQgJWluJSBiaW9zcGVjaW1lbl9pZHMpCmNudmtpdF9zZXhfY2hyIDwtIHJlYWRfdHN2KHNleF9jaHJfY252a2l0KSAlPiUKICBmaWx0ZXIoYmlvc3BlY2ltZW5faWQgJWluJSBiaW9zcGVjaW1lbl9pZHMpCmNvbnRyb2xmcmVlY19zZXhfY2hyIDwtIHJlYWRfdHN2KHNleF9jaHJfY29udHJvbGZyZWVjKSAlPiUKICBmaWx0ZXIoYmlvc3BlY2ltZW5faWQgJWluJSBiaW9zcGVjaW1lbl9pZHMpCmBgYAoKIyMjIE91dHB1dCBmaWxlCgpgYGB7cn0Kb3V0cHV0X2FsbCA8LSBmaWxlLnBhdGgocmVzdWx0c19kaXIsIAogICAgICAgICAgICAgICAgICAgICAgICAiZW1icnlvbmFsX3R1bW9yX3N1YnR5cGluZ19yZWxldmFudF9kYXRhLnRzdiIpCm91dHB1dF9zdWJ0eXBlcyAgPC0gZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImVtYnJ5b25hbF90dW1vcl9tb2xlY3VsYXJfc3VidHlwZXMudHN2IikKYGBgCgojIyBXcmFuZ2xlIGRhdGEKCiMjIyBGdXNpb24gZGF0YQoKU3VtbWFyaXppbmcgdGhlIHNhbGllbnQgcG9pbnRzIGZyb20gW2BBbGV4c0xlbW9uYWRlL09wZW5QQlRBLWFuYWx5c2lzIzI1MWBdKGh0dHBzOi8vZ2l0aHViLmNvbS9BbGV4c0xlbW9uYWRlL09wZW5QQlRBLWFuYWx5c2lzL2lzc3Vlcy8yNTEpOgoKPiAqKkVUTVIsIEMxOU1DLWFsdGVyZWQqKjogVGhlc2UgdHVtb3JzIGhhdmUgZm9jYWwgYW1wbGlmaWNhdGlvbiBvZiB0aGUgbWlSTkEgY2x1c3RlciBvbiBjaHIxOSAoZGVub3RlZCBDMTlNQykgYW5kIG9mdGVuIGhhdmUgZ2VuZSBmdXNpb25zIGludm9sdmluZyBfVFRZSDFfIGFuZCBjaHIxOSBtaVJOQSBjbHVzdGVyIGdlbmVzCgo+ICoqQ05TIEhHTkVULU1OMSoqOiBDb250YWluIGdlbmUgZnVzaW9ucyBpbnZvbHZpbmcgNScgX01OMV8uIDMnIGZ1c2lvbiBwYXJ0bmVycyBjYW4gaW5jbHVkZSBfQkVORDJfIGFuZCBfQ1hYQzVfLgoKPiAqKkNOUyBOQi1GT1hSMioqOiBPdmVyLWV4cHJlc3Npb24gYW5kL29yIGdlbmUgZnVzaW9ucyBpbiBfRk9YUjJfCgo+ICoqQ05TIEVGVC1DSUMqKjogQWx0ZXJhdGlvbnMgaW4gX0NJQ18sIGNvbW1vbmx5IGZ1c2VkIHdpdGggX05VVE0xXwoKYGBge3J9CmNvbG5hbWVzKGZ1c2lvbnNfZGYpCmBgYAoKYGBge3IgbWVzc2FnZT1GQUxTRX0KdHR5aDFfZnVzaW9ucyA8LSB3cmFuZ2xlX2Z1c2lvbnMoZnVzaW9uc19kZiwgIlRUWUgxLS0iLCAiVFRZSDFfZnVzaW9ucyIpCm1uMV9mdXNpb25zIDwtIHdyYW5nbGVfZnVzaW9ucyhmdXNpb25zX2RmLCAiTU4xLS0iLCAiTU4xX2Z1c2lvbnMiKSAKZm94cjJfZnVzaW9ucyA8LSB3cmFuZ2xlX2Z1c2lvbnMoZnVzaW9uc19kZiwgIkZPWFIyIiwgIkZPWFIyX2Z1c2lvbnMiKQpjaWNfZnVzaW9ucyA8LSB3cmFuZ2xlX2Z1c2lvbnMoZnVzaW9uc19kZiwgIkNJQy0tIiwgIkNJQ19mdXNpb25zIikKZnVzaW9uc19zdW1tYXJ5X2RmIDwtIGxpc3QodHR5aDFfZnVzaW9ucywKICAgICAgICAgICAgICAgICAgICAgICAgICAgbW4xX2Z1c2lvbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZveHIyX2Z1c2lvbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNpY19mdXNpb25zKSAlPiUKICBwdXJycjo6cmVkdWNlKGRwbHlyOjppbm5lcl9qb2luLCBieSA9ICJLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lEIikKIyByZW1vdmUgZGF0YS5mcmFtZSB3ZSBubyBsb25nZXIgbmVlZApybSh0dHloMV9mdXNpb25zLCBtbjFfZnVzaW9ucywgZm94cjJfZnVzaW9ucywgY2ljX2Z1c2lvbnMsIGZ1c2lvbnNfZGYpCmBgYAoKYGBge3J9CmhlYWQoZnVzaW9uc19zdW1tYXJ5X2RmICU+JSBhcnJhbmdlKGRlc2MoVFRZSDFfZnVzaW9ucykpLCBuID0gMTApCmBgYAoKIyMjIEV4cHJlc3Npb24gZGF0YQoKU3VtbWFyaXppbmcgc2FsaWVudCBwb2ludHMgZnJvbSBbYEFsZXhzTGVtb25hZGUvT3BlblBCVEEtYW5hbHlzaXMjMjUxYF0oaHR0cHM6Ly9naXRodWIuY29tL0FsZXhzTGVtb25hZGUvT3BlblBCVEEtYW5hbHlzaXMvaXNzdWVzLzI1MSk6Cgo+ICoqRVRNUiwgQzE5TUMtYWx0ZXJlZCoqOiBUaGVzZSB0dW1vcnMgaGF2ZSBoaWdoIGV4cHJlc3Npb24gb2YgX0xJTjI4QV8gYW5kIHNlcnZlcyBhcyBhIGJpb21hcmtlciBmb3IgRVRNUnMKCj4gKipDTlMgTkItRk9YUjIqKjogT3Zlci1leHByZXNzaW9uIGFuZC9vciBnZW5lIGZ1c2lvbnMgaW4gX0ZPWFIyXwoKPiAqKkVUTVIsIE5PUyoqOiBUaGVzZSB0dW1vcnMgaGF2ZSBoaWdoIGV4cHJlc3Npb24gb2YgX0xJTjI4QV8gYW5kIHNlcnZlcyBhcyBhIGJpb21hcmtlciBmb3IgRVRNUnMsIGJ1dCBkbyBub3Qgc2hvdyBmb2NhbCBhbXBsaWZpY2F0aW9uIG9mIEMxOU1DLgoKYGBge3J9CmV4cF9nZW5lc19vZl9pbnRlcmVzdCA8LSBjKCJMSU4yOEEiLCAiRk9YUjIiKQojIHNldCB1cCBwb2x5LUEgZGF0YQpwb2x5YV9leHAgPC0gcG9seWFfZXhwWywgZXhwX2dlbmVzX29mX2ludGVyZXN0XSAlPiUKICBhcy5kYXRhLmZyYW1lKCkgJT4lCiAgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oIktpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSUQiKQojIHNldCB1cCBzdHJhbmRlZCBkYXRhCnN0cmFuZGVkX2V4cCA8LSBzdHJhbmRlZF9leHBbLCBleHBfZ2VuZXNfb2ZfaW50ZXJlc3RdICU+JQogIGFzLmRhdGEuZnJhbWUoKSAlPiUKICB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigiS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCIpCgojIGJpbmQgdG9nZXRoZXIgYm90aCBkYXRhc2V0cywgYnV0IGtlZXAgdHJhY2sgb2Ygd2hhdCBzZWxlY3Rpb24gc3RyYXRlZ3kgd2FzCiMgdXNlZApleHBfZGYgPC0gYmluZF9yb3dzKCJwb2x5YSIgPSBwb2x5YV9leHAsIAogICAgICAgICAgICAgICAgICAgICJzdHJhbmRlZCIgPSBzdHJhbmRlZF9leHAsIAogICAgICAgICAgICAgICAgICAgIC5pZCA9ICJleHBfZGF0YXNldCIpICU+JQogIHNlbGVjdCgtZXhwX2RhdGFzZXQsIGV2ZXJ5dGhpbmcoKSkKCiMgcmVtb3ZlIGRhdGEuZnJhbWUgd2Ugbm8gbG9uZ2VyIG5lZWQKcm0ocG9seWFfZXhwLCBzdHJhbmRlZF9leHAsIGV4cF9nZW5lc19vZl9pbnRlcmVzdCkKYGBgCgojIyMgSm9pbiBSTkEgZGF0YQoKYGBge3J9CnJuYV9kZiA8LSBleHBfZGYgJT4lCiAgbGVmdF9qb2luKGZ1c2lvbnNfc3VtbWFyeV9kZikgJT4lCiAgc2VsZWN0KC1leHBfZGF0YXNldCwgZXZlcnl0aGluZygpKQoKIyByZW1vdmUgZGF0YS5mcmFtZSB3ZSBubyBsb25nZXIgbmVlZApybShleHBfZGYpCmBgYAoKYGBge3J9CmhlYWQocm5hX2RmLCBuID0gMTApCmBgYAoKV2Ugc2VlIHNvbWUgcmVwZWF0ZWQgbmVnYXRpdmUgdmFsdWVzIGZvciB0aGUgZXhwcmVzc2lvbiB6LXNjb3JlcyBoZXJlLgpHZW5lcmFsbHkgdGhhdCBjb21lcyBmcm9tIHNtYWxsIG9yIHplcm8gbG9nMihGUEtNICsgMSkgdmFsdWVzLgpGb3IgZXhhbXBsZSwgYWxsIG9mIHRoZSBwb2x5LUEgdmFsdWVzIGZvciBfRk9YUjJfIGFyZSB6ZXJvIHByaW9yIHRvIHNjYWxpbmcuCgojIyMgU3RydWN0dXJhbCB2YXJpYW50IGRhdGEKCj4gKipDTlMgSEdORVQtQkNPUioqCgo+ICogQ05TIGhpZ2gtZ3JhZGUgbmV1cm9lcGl0aGVsaWFsIHR1bW9yIHdpdGggQkNPUiBhbHRlcmF0aW9uCgo+ICogVHVtb3JzIGhhdmUgaW50ZXJuYWwgdGFuZGVtIGR1cGxpY2F0aW9uIG9mIEJDT1IKClRoZSBkZWZpbml0aW9uIG9mIGludGVybmFsIHRhbmRlbSBkdXBsaWNhdGlvbiBmcm9tIFtSdXN0YWdpIGV0IGFsLiBfQk1DIEJpb2luZm9ybWF0aWNzLl8gMjAxNi5dKGh0dHBzOi8vZG9pLm9yZy8xMC4xMTg2L3MxMjg1OS0wMTYtMTAzMS04KToKCj4gRGV0ZWN0aW9uIG9mIHRhbmRlbSBkdXBsaWNhdGlvbiB3aXRoaW4gY29kaW5nIGV4b25zLCByZWZlcnJlZCB0byBhcyBpbnRlcm5hbCB0YW5kZW0gZHVwbGljYXRpb24gKElURCkKClRoZSBhbm5vdGF0ZWQgZmlsZXMgZnJvbSB0aGUgW2Bmb2NhbC1jbi1maWxlLXByZXBhcmF0aW9uYF0oLi4vZm9jYWwtY24tZmlsZS1wcmVwYXJhdGlvbi8pIG1vZHVsZSB1c2UgZXhvbnMgdG8gY2hlY2sgZm9yIG92ZXJsYXBzLgpTbywgd2UgY2FuIHRyeSB0byBzdXBwbGVtZW50IHRoZSBNYW50YSBjYWxscyB3aXRoIHRoZSBhbm5vdGF0ZWQgc2V4IGNocm9tb3NvbWUgZmlsZXMuCgpgYGB7cn0KIyBvbmx5IGluY2x1ZGUgcm93cyBmcm9tIE1hbnRhIHRoYXQgbWFrZSByZWZlcmVuY2UgdG8gQkNPUiwgcGFzcyBhbGwgZmlsdGVycwojIGh0dHBzOi8vZ2l0aHViLmNvbS9JbGx1bWluYS9tYW50YS9ibG9iLzc1YjVjMzhkNGZjZDJmNjk2MTE5N2IyOGE0MWViNjE4NTZmMmQ5NzYvZG9jcy91c2VyR3VpZGUvUkVBRE1FLm1kI3ZjZi1mb3JtYXQtZmllbGRzCiMgYW5kIGFyZSByZWNvcmRlZCBhcyB0YW5kZW0gZHVwbGljYXRpb24gZXZlbnRzCmJjb3Jfc3ZfZGYgPC0gbWFudGFfc3ZfZGYgJT4lCiAgZmlsdGVyKHN0cl9kZXRlY3QoR2VuZS5uYW1lLCAiQkNPUiIpLAogICAgICAgICBGSUxURVIgPT0gIlBBU1MiLAogICAgICAgICBBTFQgPT0gIjxEVVA6VEFOREVNPiIpCgojIHRha2UgYSBsb29rIGF0IHRoZSBnZW5lcyAKYmNvcl9zdl9kZiAlPiUgCiAgaGVhZChuID0gMikgJT4lCiAgcHVsbChHZW5lLm5hbWUpCmBgYAoKTm90IG5lY2Vzc2FyaWx5IHNwZWNpZmljIHRvIF9CQ09SXyBhbHRlcmF0aW9ucy4KCmBgYHtyfQpjb25zZW5zdXNfc2V4X2NociAlPiUgZmlsdGVyKGdlbmVfc3ltYm9sID09ICJCQ09SIikgCmBgYAoKYGBge3J9CmNudmtpdF9zZXhfY2hyICU+JSBmaWx0ZXIoZ2VuZV9zeW1ib2wgPT0gIkJDT1IiKSAKYGBgCgpgYGB7cn0KY29udHJvbGZyZWVjX3NleF9jaHIgJT4lIGZpbHRlcihnZW5lX3N5bWJvbCA9PSAiQkNPUiIpCmBgYAoKVGhpcyBpcyBub3QgY29uY2x1c2l2ZS4KCmBgYHtyfQojIHJlbW92ZSBhbGwgdGhlIHN2IGFuZCBjbnYgZGF0YSB3ZSB3aWxsIG5vdCB1c2UKcm0oYmNvcl9zdl9kZiwgbWFudGFfc3ZfZGYsIGNvbnNlbnN1c19zZXhfY2hyLCBjb250cm9sZnJlZWNfc2V4X2NociwKICAgY252a2l0X3NleF9jaHIpCmBgYAoKIyMgRmluYWwgdGFibGUKCiMjIyBBZGQgYEtpZHNfRmlyc3RfUGFydGljaXBhbnRfSURgIGFuZCBgc2FtcGxlX2lkYAoKYGBge3J9CmlkZW50aWZpZXJzX2RmIDwtIGhpc3RvbG9naWVzX2RmICU+JQogIHNlbGVjdChLaWRzX0ZpcnN0X1BhcnRpY2lwYW50X0lELCAKICAgICAgICAgc2FtcGxlX2lkLCAKICAgICAgICAgS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCkKIyBhZGQgSURzIHRvIGNocm9tb3NvbWUgMTkgZGF0YQpjaHIxOV9jbl9kZiA8LSBpZGVudGlmaWVyc19kZiAlPiUKICBpbm5lcl9qb2luKGNocjE5X2NuX2RmLCBieSA9ICJLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lEIikKIyBhZGQgSURzIHRvIFJOQSBkYXRhIApybmFfZGYgPC0gaWRlbnRpZmllcnNfZGYgJT4lCiAgaW5uZXJfam9pbihybmFfZGYpCmBgYAoKIyMjIEpvaW4gbW9sZWN1bGFyIGRhdGEKCmBgYHtyfQptb2xlY3VsYXJfZGF0YV9kZiA8LSBmdWxsX2pvaW4oY2hyMTlfY25fZGYsIHJuYV9kZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gYygiS2lkc19GaXJzdF9QYXJ0aWNpcGFudF9JRCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNhbXBsZV9pZCIpKSAlPiUKICByZW5hbWUoS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRF9ETkEgPSBLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lELngsCiAgICAgICAgIEtpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSURfUk5BID0gS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRC55KQpgYGAKCiMjIyBBZGQgY2xpbmljYWwgZGF0YQoKVGhlIGZvbGxvd2luZyB3ZXJlIG1lbnRpb25lZCBpbiBbYEFsZXhzTGVtb25hZGUvT3BlblBCVEEtYW5hbHlzaXMjMjUxYF0oaHR0cHM6Ly9naXRodWIuY29tL0FsZXhzTGVtb25hZGUvT3BlblBCVEEtYW5hbHlzaXMvaXNzdWVzLzI1MSk6Cgo+ICoqQ05TIEhHTkVULUJDT1IqKjogTWVkaWFuIGFnZSBvZiBkaWFnbm9zaXMgbGVzcyB0aGFuIDEwIHllYXJzCgo+ICoqQ05TIEhHTkVULU1OMSoqOiBQcmVkb21pbmFudGx5IGZlbWFsZSBwYXRpZW50cy4KCj4gKipDTlMgRW1icnlvbmFsLCBOT1MqKjogVHVtb3JzIHByZXZpb3VzbHkgY2FsbGVkIFBORVQgdGhhdCBkbyBub3QgZml0IGludG8gb3RoZXIgZ3JvdXBzIGFib3ZlLgoKYGBge3J9CnJlbGV2YW50X2NsaW5pY2FsX2RhdGEgPC0gaGlzdG9sb2dpZXNfZGYgJT4lIAogIGZpbHRlcihLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lEICVpbiUgYmlvc3BlY2ltZW5faWRzKSAlPiUKICBzZWxlY3QoS2lkc19GaXJzdF9QYXJ0aWNpcGFudF9JRCwgCiAgICAgICAgIHNhbXBsZV9pZCwKICAgICAgICAgYWdlX2F0X2RpYWdub3Npc19kYXlzLAogICAgICAgICBnZXJtbGluZV9zZXhfZXN0aW1hdGUsCiAgICAgICAgIHBhdGhvbG9neV9kaWFnbm9zaXMsCiAgICAgICAgIGludGVncmF0ZWRfZGlhZ25vc2lzKSAlPiUKICBkaXN0aW5jdCgpICU+JQogICMgY29udmVydCBhZ2UgdG8geWVhcnMKICBtdXRhdGUoYWdlX2F0X2RpYWdub3Npc195cnMgPSAKICAgICAgICAgICBmbG9vcihhcy5udW1lcmljKGFnZV9hdF9kaWFnbm9zaXNfZGF5cykgLyAzNjUpKSAlPiUKICBzZWxlY3QoLWFnZV9hdF9kaWFnbm9zaXNfZGF5cykKCmFsbF9kYXRhX2RmIDwtIGlubmVyX2pvaW4ocmVsZXZhbnRfY2xpbmljYWxfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICBtb2xlY3VsYXJfZGF0YV9kZikKYGBgCgpXcml0ZSB0byBmaWxlLgoKYGBge3J9CmFsbF9kYXRhX2RmICU+JQogIHNlbGVjdChLaWRzX0ZpcnN0X1BhcnRpY2lwYW50X0lELCAKICAgICAgICAgc2FtcGxlX2lkLAogICAgICAgICBLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lEX0ROQSwKICAgICAgICAgS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRF9STkEsCiAgICAgICAgIGFnZV9hdF9kaWFnbm9zaXNfeXJzLAogICAgICAgICBnZXJtbGluZV9zZXhfZXN0aW1hdGUsCiAgICAgICAgIHBhdGhvbG9neV9kaWFnbm9zaXMsCiAgICAgICAgIGludGVncmF0ZWRfZGlhZ25vc2lzLAogICAgICAgICBMSU4yOEEsCiAgICAgICAgIFRUWUgxX2Z1c2lvbnMsCiAgICAgICAgIGNocjE5X2FtcGxpZmljYXRpb24sCiAgICAgICAgIEZPWFIyLAogICAgICAgICBGT1hSMl9mdXNpb25zLAogICAgICAgICBNTjFfZnVzaW9ucywKICAgICAgICAgQ0lDX2Z1c2lvbnMpICU+JQogIHdyaXRlX3RzdihvdXRwdXRfYWxsKQpgYGAKCiMjIFN1YnR5cGluZwoKIyMjIEVUTVIsIEMxOU1DLWFsdGVyZWQgYW5kIEVUTVIsIE5PUwoKVGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gRVRNUiwgQzE5TUMtYWx0ZXJlZCBhbmQgRVRNUiwgTk9TIGlzIGEgZGlmZmVyZW5jZSBpbiBDMTlNQyBhbXBsaWZpY2F0aW9uLgpXZSdsbCBmaWx0ZXIgb24gX0xJTjI4QV8gb3ZlcmV4cHJlc3Npb24sIGFzIHRoYXQgaXMgYSBmZWF0dXJlIG9mIGJvdGguCgoqUmVjYWxsIHRoYXQgd2Ugei1zY29yZWQgdGhlc2UgZXhwcmVzc2lvbiB2YWx1ZXMgYmVmb3JlIHN1YnNldHRpbmcgdGhlIG1hdHJpeCBzbyB0aGV5IGFyZSBpbiB0aGUgY29udGV4dCBvZiAqKmFsbCoqIHNhbXBsZXMgZm9yIGEgZ2l2ZW4gc2VsZWN0aW9uIHN0cmF0ZWd5LioKCmBgYHtyfQphbGxfZGF0YV9kZiAlPiUKICAjIDMgc3RhbmRhcmQgZGV2aWF0aW9ucyBhYm92ZSB0aGUgbWVhbiBmb3IgTElOMjhBIGV4cHJlc3Npb24gb3IKICAjIGV2aWRlbmNlIG9mIEMxOU1DIGFtcGxpZmljYXRpb24KICBmaWx0ZXIoTElOMjhBID4gMyB8IGNocjE5X2FtcGxpZmljYXRpb24gPT0gIlllcyIpICU+JQogIHNlbGVjdChlbmRzX3dpdGgoIklEIiksIAogICAgICAgICBlbmRzX3dpdGgoImRpYWdub3NpcyIpLAogICAgICAgICBMSU4yOEEsCiAgICAgICAgIFRUWUgxX2Z1c2lvbnMsCiAgICAgICAgIGNocjE5X2FtcGxpZmljYXRpb24pCmBgYAoKRm9yIHNvbWUgc2FtcGxlcyB0aGF0IGhhdmUgYSBfVFRZSDFfIGZ1c2lvbiwgd2UgZG8gbm90IGhhdmUgRE5BIGRhdGEgdG8gY2hlY2sgZm9yIEMxOU1DIGFtcGxpZmljYXRpb24gYnV0IHRoYXQncyBva2F5IHBlciBbdGhpcyBjb21tZW50XShodHRwczovL2dpdGh1Yi5jb20vQWxleHNMZW1vbmFkZS9PcGVuUEJUQS1hbmFseXNpcy9wdWxsLzQ1OCNpc3N1ZWNvbW1lbnQtNTgxMDUwMDUxKSB3aGljaCByZWZlcmVuY2VzIFtLbGVpbm1hbiBldCBhbC4gX05hdCBHZW5ldC5fIDIwMTQuXShodHRwczovL2RvaS5vcmcvMTAuMTAzOC9uZy4yODQ5KS4KV2Ugd2lsbCBjYWxsIGFsbCBzYW1wbGVzIHdpdGggYSBfVFRZSDFfIGZ1c2lvbiBFVE1SLCBDMTlNQyBhbHRlcmVkLgoKYGBge3J9CmV0bXJfYzE5bWNfZGYgPC0gYWxsX2RhdGFfZGYgJT4lCiAgZmlsdGVyKExJTjI4QSA+IDMgfCBjaHIxOV9hbXBsaWZpY2F0aW9uID09ICJZZXMiLAogICAgICAgICBUVFlIMV9mdXNpb25zICE9ICJOb25lIikgJT4lCiAgc2VsZWN0KGNvbnRhaW5zKCJJRCIpKSAlPiUKICBtdXRhdGUobW9sZWN1bGFyX3N1YnR5cGUgPSAiRVRNUiwgQzE5TUMtYWx0ZXJlZCIpCmBgYAoKRm9yIG5vdywgd2Ugd2lsbCBjYWxsIHRoZSBzYW1wbGUgd2l0aCBhIF9MSU4yOEFfIHotc2NvcmUgPiAzIHRoYXQgaGFzIG5vIF9UVFlIMV8gZnVzaW9uIGFuZCBubyBjb3B5IG51bWJlciBkYXRhIEVUTVIsIE5PUy4KCmBgYHtyfQojIFRPRE86IGlzIHRoaXMgdGhlIGNvcnJlY3QgY2FsbCBvciBzaG91bGQgdGhpcyBiZSBhIENOUyBFbWJyeW9uYWwsIE5PUyBjYWxsPwpldG1yX25vc19kZiA8LSBhbGxfZGF0YV9kZiAlPiUKICBmaWx0ZXIoTElOMjhBID4gMywKICAgICAgICAgVFRZSDFfZnVzaW9ucyA9PSAiTm9uZSIpICU+JQogIHNlbGVjdChjb250YWlucygiSUQiKSkgJT4lCiAgbXV0YXRlKG1vbGVjdWxhcl9zdWJ0eXBlID0gIkVUTVIsIE5PUyIpCmBgYAoKIyMjIENOUyBIR05FVC1NTjEKCj4gKiBDTlMgaGlnaC1ncmFkZSBuZXVyb2VwaXRoZWxpYWwgdHVtb3Igd2l0aCBfTU4xXyBhbHRlcmF0aW9uCj4gKiBMaWtlbHkgcHJldmlvdXNseSBkaWFnbm9zZWQgYXMgUE5FVC4KPiAqIENvbnRhaW4gZ2VuZSBmdXNpb25zIGludm9sdmluZyA1JyBfTU4xXy4gMycgZnVzaW9uIHBhcnRuZXJzIGNhbiBpbmNsdWRlIF9CRU5EMl8gYW5kIF9DWFhDNV8uCj4gKiBQcmVkb21pbmFudGx5IGZlbWFsZSBwYXRpZW50cy4KCmBgYHtyfQphbGxfZGF0YV9kZiAlPiUKICAjIDMgc3RhbmRhcmQgZGV2aWF0aW9ucyBhYm92ZSB0aGUgbWVhbgogIGZpbHRlcihNTjFfZnVzaW9ucyAhPSAiTm9uZSIpICU+JQogIHNlbGVjdChlbmRzX3dpdGgoIklEIiksIAogICAgICAgICBlbmRzX3dpdGgoImRpYWdub3NpcyIpLAogICAgICAgICBnZXJtbGluZV9zZXhfZXN0aW1hdGUsCiAgICAgICAgIE1OMV9mdXNpb25zKQpgYGAKCk5vIHNhbXBsZXMgZml0IHRoaXMgY3JpdGVyaWEuClRoZXJlIHdlcmUgb3RoZXIgc2FtcGxlcyB0aGF0ICoqZGlkKiogY29udGFpbiBfTU4xXyBmdXNpb25zLgoKYGBge3J9Cm1uMV9mdXNpb25zIDwtIGZ1c2lvbnNfc3VtbWFyeV9kZiAlPiUKICBmaWx0ZXIoTU4xX2Z1c2lvbnMgIT0gIk5vbmUiKSAKCm1uMV9mdXNpb25zCmBgYAoKYGBge3J9Cmhpc3RvbG9naWVzX2RmICU+JQogIGZpbHRlcihLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lEICVpbiUgcHVsbChtbjFfZnVzaW9ucywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSUQpKSAlPiUKICBzZWxlY3QoS2lkc19GaXJzdF9QYXJ0aWNpcGFudF9JRCwgCiAgICAgICAgIHNhbXBsZV9pZCwgCiAgICAgICAgIEtpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSUQsCiAgICAgICAgIHBhdGhvbG9neV9kaWFnbm9zaXMsCiAgICAgICAgIGludGVncmF0ZWRfZGlhZ25vc2lzLAogICAgICAgICBnZXJtbGluZV9zZXhfZXN0aW1hdGUpCmBgYAoKVGhleSBhcmUgY2xhc3NpZmllZCBhcyBgRXBlbmR5bW9tYWAgYW5kIGBMb3ctZ3JhZGUgYXN0cm9jeXRpYyB0dW1vcmAuCgpXZSB3aWxsIGNhbGwgdGhlIHNhbXBsZSB3aXRoIHRoZSBfTU4xLS1DWFhDNV8gZnVzaW9uIENOUyBIR05FVC1NTjEuCgpgYGB7cn0KaGduZXRfbW4xX2RmIDwtIGhpc3RvbG9naWVzX2RmICU+JQogIGZpbHRlcihzYW1wbGVfaWQgPT0gIjczMTYtNzY1IikgJT4lCiAgc2VsZWN0KEtpZHNfRmlyc3RfUGFydGljaXBhbnRfSUQsCiAgICAgICAgIEtpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSURfUk5BID0gS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCwKICAgICAgICAgc2FtcGxlX2lkKSAlPiUKICBtdXRhdGUobW9sZWN1bGFyX3N1YnR5cGUgPSAiQ05TIEhHTkVULU1OMSIpCmBgYAoKIyMjIENOUyBIR05FVC1CQ09SCgo+ICogQ05TIGhpZ2gtZ3JhZGUgbmV1cm9lcGl0aGVsaWFsIHR1bW9yIHdpdGggQkNPUiBhbHRlcmF0aW9uCj4gKiBUdW1vcnMgaGF2ZSBpbnRlcm5hbCB0YW5kZW0gZHVwbGljYXRpb24gb2YgQkNPUgo+ICogTWVkaWFuIGFnZSBvZiBkaWFnbm9zaXMgbGVzcyB0aGFuIDEwIHllYXJzCgpXZSBoYXZlIG5vIGNsZWFyIGV2aWRlbmNlIG9mIF9CQ09SXyBhbHRlcmF0aW9ucy4KCiMjIyBDTlMgTkItRk9YUjIKCj4gKiBDZW50cmFsIG5lcnZvdXMgc3lzdGVtIChDTlMpIG5ldXJvYmxhc3RvbWEgd2l0aCBfRk9YUjJfIGFjdGl2YXRpb24KPiAqIE92ZXItZXhwcmVzc2lvbiBhbmQvb3IgZ2VuZSBmdXNpb25zIGluIF9GT1hSMl8KCmBgYHtyfQphbGxfZGF0YV9kZiAlPiUKICBmaWx0ZXIoRk9YUjJfZnVzaW9ucyAhPSAiTm9uZSIgfCBGT1hSMiA+IDMpICU+JQogIHNlbGVjdChlbmRzX3dpdGgoIklEIiksIAogICAgICAgICBlbmRzX3dpdGgoImRpYWdub3NpcyIpLAogICAgICAgICBGT1hSMiwKICAgICAgICAgRk9YUjJfZnVzaW9ucykKYGBgCgpgYGB7cn0KbmJfZm94cjJfZGYgPC0gYWxsX2RhdGFfZGYgJT4lCiAgZmlsdGVyKEZPWFIyX2Z1c2lvbnMgIT0gIk5vbmUiIHwgRk9YUjIgPiAzKSAlPiUKICBzZWxlY3QoY29udGFpbnMoIklEIikpICU+JQogIG11dGF0ZShtb2xlY3VsYXJfc3VidHlwZSA9ICJDTlMgTkItRk9YUjIiKQpgYGAKCiMjIyBDTlMgRUZULUNJQwoKPiAqIENOUyBFd2luZyBzYXJjb21hIGZhbWlseSB0dW1vciB3aXRoIF9DSUNfIGFsdGVyYXRpb24KPiAqIEFsdGVyYXRpb25zIGluIF9DSUNfLCBjb21tb25seSBmdXNlZCB3aXRoIF9OVVRNMV8KCmBgYHtyfQphbGxfZGF0YV9kZiAlPiUKICBmaWx0ZXIoQ0lDX2Z1c2lvbnMgIT0gIk5vbmUiKQpgYGAKCiMjIyBDTlMgRW1icnlvbmFsLCBOT1MKCj4gKiBDTlMgRW1icnlvbmFsIHR1bW9yLCBub3Qgb3RoZXJ3aXNlIHNwZWNpZmllZAo+ICogVHVtb3JzIHByZXZpb3VzbHkgY2FsbGVkIFBORVQgdGhhdCBkbyBub3QgZml0IGludG8gb3RoZXIgZ3JvdXBzIGFib3ZlLgoKQWxsIG90aGVyIHNhbXBsZXMgd2lsbCBiZSBjYWxsZWQgQ05TIEVtYnJ5b25hbCwgTk9TLgoKIyMjIFN1YnR5cGluZyBmaWxlCgpgYGB7cn0Kc3VidHlwZXNfZGYgPC0gYmluZF9yb3dzKAogIGV0bXJfYzE5bWNfZGYsCiAgZXRtcl9ub3NfZGYsCiAgaGduZXRfbW4xX2RmLAogIG5iX2ZveHIyX2RmCikKCnN1YnR5cGVzX2RmIDwtIGFsbF9kYXRhX2RmICU+JQogIHNlbGVjdChjb250YWlucygiSUQiKSkgJT4lCiAgZnVsbF9qb2luKHN1YnR5cGVzX2RmKSAlPiUKICByZXBsYWNlX25hKGxpc3QobW9sZWN1bGFyX3N1YnR5cGUgPSAiQ05TIEVtYnJ5b25hbCwgTk9TIikpCmBgYAoKYGBge3J9CnN1YnR5cGVzX2RmICU+JQogIHdyaXRlX3RzdihvdXRwdXRfc3VidHlwZXMpCmBgYAoKIyMgU2Vzc2lvbiBJbmZvCgpgYGB7cn0Kc2Vzc2lvbkluZm8oKQpgYGAKCg==