Summary
QC_Status
|
PASS
|
Purity
|
0.43 (0.41-0.79)
|
Ploidy
|
2.911 (2.851-4.917)
|
Gender
|
MALE
|
Top MutSigs
|
Old: Sig3 (11082), Sig13 (6441) - New: SBS13 (6369), SBS39 (4511)
|
CNVs (Somatic)
|
Min: -0.52; Max: 11.52; N: 1497
|
SVs (unmelted)
|
Sum: 807, INS: 19, DUP: 205, DEL: 375, BND: 208
|
SVs (melted)
|
Sum: 15879, INS: 21, DUP: 6788, DEL: 8819, BND: 251
|
Genome
|
hg38
|
AF Summary Stats
set
|
n
|
mean
|
median
|
mode
|
Global
|
32264
|
0.28
|
0.24
|
0.25
|
Key genes CDS
|
67
|
0.32
|
0.25
|
0.25
|
Somatic Mutation Profiles
Allelic Frequencies
Summarised below are the allele frequencies (AFs) for somatic variants detected genome-wide (Global) vs. within the coding sequence of ~1,100 UMCCR cancer genes (Key Genes CDS). AFs range from 0 to 1, or 0%-100% (we filter out all novel variants with AF < 10%).
Details
Variants are typically called in bcbio by 3 different callers, with calls supported by at least 2 of them used (“ensemble” approach). In some cases only a single caller is used due to technical reasons (e.g. highly mutated FFPE sample).
The following post-processing steps occur:
somatic_vcf_annotate
: annotate VCF against databases of known hotspots, germline variants, low mappability regions, UMCCR panel of normals
somatic_vcf_filter
: filter VCF to remove germline variants and artefacts, but keep known hotspots
- As preparation for the allelic frequencies plots:
subset_to_giab
: keep variants in ‘high confidence’ regions as determined by the Genome in a Bottle consortium
- keep only variants with AF above 10%
- Allele frequencies for global and keygenes:
afs
: grab only the INFO/TUMOR_AF
field and output to final txt file
afs_keygenes
: grab the CHROM
, POS
, ID
, REF
, ALT
and INFO/TUMOR_AF
for variants in the UMCCR cancer gene BED file, and output to final txt file

Mutational Signatures
Deciphering the mutational signature of a tumor sample can provide insight into the mutational processes involved in carcinogenesis and help in cancer treatment and prevention. The MutationalPatterns R package is used to generate a mutation signature for the sample. We use the final filtered somatic calls as input.
Context signature

Point mutation spectrum
Description
We can count the mutation type occurrences for the input VCF. For C>T
mutations, a distinction is made between C>T
at CpG sites and other sites, as deamination of methylated cytosine at CpG sites is a common mutational process. This is the reason the reference genome is needed.
A mutation spectrum shows the relative contribution of each mutation type in the base substitution catalogs. We can plot the mean relative contribution of each of the 6 base substitution types over all samples. Error bars indicate standard deviation over all samples. The total number of mutations is indicated. We can also distinguish between C>T
at CpG sites and other sites.

Transcriptional strand bias
Description
We can determine if a gene mutation is on the transcribed or non-transcribed strand, which can be used to evaluate the involvement of transcription-coupled repair. By convention base substitutions are regarded as C>X or T>X, so we try to determine whether the C or T base is on the same strand as the gene definition. Base substitutions on the same strand as the gene definition are considered ‘untranscribed’, and on the opposite strand ‘transcribed’, since the gene definitions report the coding or sense strand, which is untranscribed. No strand information is reported for base substitutions that overlap with more than one gene on different strands.


Replicative strand bias
Description
The involvement of replication-associated mechanisms can be evaluated by testing for a mutational bias between the leading and lagging strand. The replication strand is dependent on the locations of replication origins from which DNA replication is fired. However, replication timing is dynamic and cell-type specific, which makes replication strand determination less straightforward than transcriptional strand bias analysis. Replication timing profiles can be generated with Repli-Seq experiments. Once the replication direction is defined, a strand asymmetry analysis can be performed similarly as the transcription strand bias analysis.


Signature Contribution
Description
The contribution of any set of signatures to the mutational profile of a sample can be quantified. This unique feature is specifically useful for mutational signature analyses of small cohorts or individual samples, but also to relate own findings to known signatures and published findings. The fit_to_signatures
function finds the optimal linear combination of mutational signatures that most closely reconstructs the mutation matrix by solving a non-negative least-squares constraints problem.
Shown are signatures with positive Contribution values, along with summarised descriptions and reference signature plots from https://cancer.sanger.ac.uk/cosmic/signatures.
OLD
Rank
|
Signature
|
Contribution
|
Description
|
Plot
|
1
|
Sig3
|
11082
|
Breast, ovarian, pancreatic; germline + somatic BRCA1/BRCA2 mut; failure of DNA ds break-repair; many large indels.
|
|
2
|
Sig13
|
6441
|
In 22 cancers; mostly cervical, bladder, breast; AID/APOBEC; C>G mut; similar to sig2; maybe viral infection, retrotransposon jumping or tissue inflammation; kataegis.
|
|
3
|
Sig2
|
4072
|
In 22 cancers; mostly cervical + bladder; AID/APOBEC; similar to sig13; maybe viral infection, retrotransposon jumping or tissue inflammation; exon TSB.
|
|
4
|
Sig8
|
3270
|
Breast cancer, medulloblastoma; many CC>AA subs; weak strand bias for C>A subs.
|
|
5
|
Sig19
|
2220
|
Only in pilocytic astrocytoma.
|
|
6
|
Sig7
|
1985
|
Skin, lip, head, neck or oral squamous cancers; ultraviolet light exposure; many CC>TT subs; strong TSB with many C>T mut.
|
|
7
|
Sig16
|
1246
|
Liver; strong TSB for T>C at ATN context.
|
|
8
|
Sig12
|
1093
|
Liver; TSB for T>C.
|
|
9
|
Sig1
|
1082
|
All cancers; correlates with age of diagnosis; few small indels
|
|
10
|
Sig9
|
996
|
Chronic lymphocytic leukaemias, malignant B-cell lymphomas; mut pattern associated with polymerase H (implicated with AID during som hypermutation).
|
|
11
|
Sig11
|
644
|
Melanoma, glioblastoma; alkylating agents; TSB for C>T.
|
|
12
|
Sig27
|
66
|
Subset of kidney clear cell carcinomas; strong TSB for T>A; many small indels.
|
|
13
|
Sig28
|
38
|
Subset of stomach cancers.
|
|
14
|
Sig10
|
6
|
In 6 cancers; mostly colorectal and uterine; hypermutated samples due to altered POLE activity; TSB for C>A at TCT context, T>G at TTT context.
|
|
Rainfall Plot
Rainfall plots show the distribution of mutations along the genome, with mutation types indicated with different colors. The y-axis corresponds to the distance of a mutation from the previous mutation, and is log10 transformed. Drop-downs from the plots indicate clusters or “hotspots” of mutations.

Circos Plots
Circos plots are generated by PURPLE. The first BAF plot is based on PURPLE data and configuration files.
BAF, Total/Minor CN, SVs
Description
- Track1: Chromosomes. Darker shaded areas: gaps in reference genome (centromeres, heterochromatin & missing short arms)
- Track2: Beta Allele Frequency. Given that the BAF points correspond to allele frequencies of heterozygous SNPs that are common in germline samples, there shouldn’t be any in chromosome Y (and chromosome X when male).
- Track3: Total copy number changes adjusted for tumor purity, including focal and chromosomal somatic events. Red = Loss; Green = Gain. Scaled from 0 (complete loss) to 6 (high level gains). If > 6, shown as 6 with a green dot on the outermost green gridline.
- Track4: Minor allele copy numbers. Range from 0 to 3. Expected normal minor allele copy number is 1, and anything below 1 is shown as a loss (Orange), representing an LOH event. Minor allele copy numbers above 1 (Blue) indicate gains of both A and B alleles.
- Track5 (Inner circle): Observed structural variants within or between the chromosomes.
- Blue = Translocations
- Red = Deletions
- Yellow = Insertions
- Green = Tandem duplications
- Black = Inversions

SNVs/Indels, Total/Minor CN, SVs
Description
- Track1: Chromosomes. Darker shaded areas: gaps in reference genome (centromeres, heterochromatin & missing short arms)
- Track2: Somatic variants (incl. exon, intron and intergenic regions).
- outer ring: SNP allele frequencies, corrected for tumor purity and scaled from 0 to 100%. Each dot represents a single somatic variant, coloured according to the type of base change (e.g. C>T/G>A in red).
- inner ring: short insertion (yellow) and deletion (red) locations.
- Track3: Observed total copy number changes adjusted for tumor purity, including focal and chromosomal somatic events. Red = Loss; Green = Gain. Scaled from 0 (complete loss) to 6 (high level gains). If > 6, shown as 6 with a green dot on the outermost green gridline.
- Track4: Observed minor allele copy numbers. Range from 0 to 3. Expected normal minor allele copy number is 1, and anything below 1 is shown as a loss (Orange), representing an LOH event. Minor allele copy numbers above 1 (Blue) indicate gains of both A and B alleles.
- Track5 (Inner circle): Observed structural variants within or between the chromosomes.
- Blue = Translocations
- Red = Deletions
- Yellow = Insertions
- Green = Tandem duplications
- Black = Inversions

Allele Ratios, BAF
Description
- Track1: Chromosomes. Darker shaded areas: gaps in reference genome (centromeres, heterochromatin & missing short arms)
- Track2: Tumor and Normal Allele Ratios
- Track3: Beta Allele Frequency Given that the BAF points correspond to allele frequencies of heterozygous SNPs that are common in germline samples, there shouldn’t be any in chromosome Y (and chromosome X when male).

Structural Variants
Structural variants are inferred with Manta, adjusted using PURPLE, and prioritised using simple_sv_annotation. Allele frequencies, copy number changes and ploidy are purity-adjusted.
Details
The input file corresponds to umccrised/<batch>/structural/<batch>-manta.tsv
.
It’s generated through the following steps:
Step 1: Processing
- Input: Manta structural variant calls from bcbio (
final/<tumor-name>/<batch-name>-sv-prioritize-manta.vcf.gz
(or <batch-name>-manta.vcf.gz
if not prioritised))
- Remove following annotations from Manta VCF: ‘INFO/SIMPLE_ANN’, ‘INFO/SV_HIGHEST_TIER’, ‘FILTER/Intergenic’, ‘FILTER/MissingAnn’, ‘FILTER/REJECT’
- Prioritise variants with simple_sv_annotation`
- Output:
work/{batch}/structural/prioritize/{batch}-manta.vcf.gz
- Keep PASS variants
- If more than 100,000 variants, keep only variants where
INFO/SV_TOP_TIER <= 3
- Output:
work/{batch}/structural/keep_pass/{batch}-manta.vcf
- Deal with chromosome capitalisation occurring from SnpEff
- Run BreakPointInspector (BPI) if it was disabled in bcbio
- Output:
work/{batch}/structural/maybe_bpi/{batch}-manta.vcf
Step 2: Filtering
- Keep PASS variants (since BPI updates the FILTER column)
- For BND variants require paired reads support (PR) to be higher than split read support (SR)
- Keep all
INFO/SV_TOP_TIER <= 2
variants
- For
INFO/SV_TOP_TIER > 2
variants require split or paired reads support of at least 5x
- For
INFO/SV_TOP_TIER > 2
variants with low allele frequency at any breakpoint (BPI_AF[0 or 1] < 0.1
), require SR or PR support of at least 10x
- Output:
work/{batch}/structural/filt/{batch}-manta.vcf
Step 3: PURPLE and FFPE conditional
- If the sample is not FFPE:
- Feed above filtered SVs to PURPLE, which outputs
purple.sv.vcf.gz
that contains rescued SVs
- Prioritise variants (again)
- Remove ‘INFO/ANN’ annotation
- Output:
{batch}/structural/{batch}-manta.vcf.gz
- If the sample is FFPE:
- Just copy
filtered
variants and don’t do anything (i.e. we don’t want the rescued SVs from PURPLE since they’ll likely be heaps) (note that PURPLE will still get fed with the filtered
SVs)
- Output:
{batch}/structural/{batch}-manta.vcf.gz
Step 4: TSV final output
- Input:
{batch}/structural/{batch}-manta.vcf.gz
VCF
- Output:
{batch}/structural/{batch}-manta.tsv
TSV
Description of Manta TSV columns
Column
|
Description
|
AF_BPI
|
INFO/BPI_AF: AF at each breakpoint (so AF_BPI1,AF_BPI2)
|
AF_PURPLE
|
INFO/PURPLE_AF: AF at each breakend (purity adjusted) (so AF_PURPLE1,AF_PURPLE2)
|
annotation
|
INFO/SIMPLE_ANN: Simplified structural variant annotation: ‘SVTYPE | EFFECT | GENE(s) | TRANSCRIPT | PRIORITY (1-4)’
|
caller
|
Manta SV caller
|
chrom
|
CHROM column in VCF
|
CN_change_PURPLE
|
INFO/PURPLE_CN_CHANGE: change in CN at each breakend (purity adjusted) (so CN_change_PURPLE1,CN_change_PURPLE2)
|
CN_PURPLE
|
INFO/PURPLE_CN: CN at each breakend (purity adjusted) (so CN_PURPLE1,CN_PURPLE2)
|
end
|
INFO/END: End position of the variant described in this record
|
END_BPI
|
INFO/BPI_END: BPI adjusted breakend location
|
ID
|
ID column in VCF
|
MATEID
|
INFO/MATEID: ID of mate breakend
|
paired_support_PE
|
FORMAT/PE of tumor sample: ??
|
paired_support_PR
|
FORMAT/PR of tumor sample: Spanning paired-read support for the ref and alt alleles in the order listed, for reads where P(allele|read)>0.999
|
Ploidy_PURPLE
|
INFO/PURPLE_PLOIDY: Ploidy of variant (purity adjusted)
|
PURPLE_status
|
INFERRED if FILTER=INFERRED, or RECOVERED if has INFO/RECOVERED, else blank. INFERRED: Breakend inferred from copy number transition
|
sample
|
Tumor sample name
|
somaticscore
|
INFO/SOMATICSCORE: Somatic variant quality score
|
split_read_support
|
FORMAT/SR of tumor sample: Split reads for the ref and alt alleles in the order listed, for reads where P(allele|read)>0.999
|
start
|
POS column in VCF
|
START_BPI
|
INFO/BPI_START: BPI adjusted breakend location
|
svtype
|
INFO/SVTYPE: Type of structural variant
|
tier
|
INFO/SV_TOP_TIER (or 4 if missing): Highest priority tier for the effects of a variant entry
|
Prioritisation process
- Annotate with SnpEff based on Ensembl gene model
- Subset annotations to APPRIS principal transcripts
- Prioritize variants with simple_sv_annotation 1(high)-2(moderate)-3(low)-4(no interest):
name
|
abbreviation
|
3_prime_UTR_truncation
|
3UTRtrunc
|
3_prime_UTR_variant
|
3UTRvar
|
5_prime_UTR_truncation
|
5UTRtrunc
|
5_prime_UTR_variant
|
5UTRvar
|
bidirectional_gene_fusion
|
BidFusG
|
chromosome_number_variation
|
ChromNumV
|
conservative_inframe_deletion
|
ConsInframeDel
|
feature_ablation
|
DelG
|
transcript_ablation
|
DelTx
|
downstream_gene_variant
|
DnstreamGV
|
duplication
|
Dup
|
exon_loss_variant
|
ExonLossV
|
frameshift_variant
|
FrameshiftV
|
feature_fusion
|
Fus
|
gene_fusion
|
FusG
|
intergenic_region
|
IntergenReg
|
intragenic_variant
|
IntragenV
|
intron_variant
|
IntronV
|
no_func_effect
|
NoFuncEff
|
non_coding_transcript_variant
|
NoncodTxV
|
no_prio_effect
|
NoPrioEff
|
splice_acceptor_variant
|
SpliceAccV
|
splice_donor_variant
|
SpliceDonV
|
splice_region_variant
|
SpliceRegV
|
start_lost
|
StartLoss
|
stop_gained
|
StopGain
|
stop_lost
|
StopLoss
|
TFBS_ablation
|
TFBSDel
|
TF_binding_site_variant
|
TFBSVar
|
upstream_gene_variant
|
UpstreamGV
|
Summary
SV type by top tier before breaking down by annotation
|
BND
|
DEL
|
DUP
|
INS
|
Sum
|
1
|
0
|
0
|
1
|
0
|
1
|
2
|
20
|
27
|
35
|
0
|
82
|
3
|
4
|
27
|
11
|
1
|
43
|
4
|
184
|
321
|
158
|
18
|
681
|
Sum
|
208
|
375
|
205
|
19
|
807
|
|
SV type by individual tier after breaking down by annotation
|
BND
|
DEL
|
DUP
|
INS
|
Sum
|
1
|
0
|
0
|
1
|
0
|
1
|
2
|
26
|
117
|
43
|
0
|
186
|
3
|
6
|
257
|
222
|
1
|
486
|
4
|
219
|
8445
|
6522
|
20
|
15206
|
Sum
|
251
|
8819
|
6788
|
21
|
15879
|
|
Unmelted Variants
Description
Column
|
Description
|
varnum
|
Original event row number that connects variants to events
|
TierTop
|
Top priority of the event (from ‘simple_sv_annotation’: 1 highest, 4 lowest)
|
Chr
|
Chromosome
|
Start
|
Start position as inferred by BPI (for PURPLE-inferred SVs we use POS)
|
End
|
End position. For BNDs this has been assigned to the Chr:Start of the BND’s mate for convenience. Values are inferred by BPI (PURPLE-inferred SVs don’t have an End).
|
Type
|
Type of structural variant
|
ID
|
ID of BND from Manta (or PURPLE for PURPLE-inferred SVs))
|
MATEID
|
ID of BND mate from Manta
|
BND_ID
|
ID of BND pair simplified. BNDs with the same BND_ID belong to the same translocation event
|
BND_mate
|
‘A’ or ‘B’ depending on if it’s the first or second mate in the BND pair
|
SR_PR_alt
|
Number of Split Reads and Paired Reads supporting the alt allele, for reads where P(allele|read)>0.999
|
SR_PR_ref
|
Number of Split Reads and Paired Reads supporting the ref allele, for reads where P(allele|read)>0.999
|
Ploidy
|
Ploidy of variant from PURPLE (purity adjusted)
|
AF_PURPLE
|
PURPLE AF at each breakend preceded by their average
|
AF_BPI
|
BPI AF at each breakend preceded by their average
|
CNC
|
Copy Number Change at each breakend preceded by their average
|
CN
|
Copy Number at each breakend preceded by their average
|
SScore
|
Somatic variant quality score
|
nann
|
Number of annotations for given event
|
Translocations (BNDs)
Main Columns
Description
Column
|
Description
|
nrow
|
Row number that connects variants between tables in same tab set
|
varnum
|
Original event row number that connects variants to events
|
Tier
|
Priority of the specific event (from ‘simple_sv_annotation’: 1 highest, 4 lowest)
|
Chr
|
Chromosome
|
Start
|
Start position as inferred by BPI (for PURPLE-inferred SVs we use POS)
|
End
|
End position. For BNDs this has been assigned to the Chr:Start of the BND’s mate for convenience. Values are inferred by BPI (PURPLE-inferred SVs don’t have an End).
|
ID
|
ID of BND from Manta (or PURPLE for PURPLE-inferred SVs))
|
BND_ID
|
ID of BND pair simplified. BNDs with the same BND_ID belong to the same translocation event
|
BND_mate
|
‘A’ or ‘B’ depending on if it’s the first or second mate in the BND pair
|
Genes
|
Genes involved in the event. DEL/DUP/INS events involving more than 2 genes are shown in separate table.
|
Effect
|
SV effect (based on SnpEff Effect Sequence Ontology - abbreviations are shown under Details in the Effects table
|
Detail
|
Prioritisation detail (from ‘simple_sv_annotation’)
|
SR_PR_alt
|
Number of Split Reads and Paired Reads supporting the alt allele, for reads where P(allele|read)>0.999
|
Ploidy
|
Ploidy of variant from PURPLE (purity adjusted)
|
AF_PURPLE
|
PURPLE AF at each breakend preceded by their average
|
Other Columns
Description
Column
|
Description
|
nrow
|
Row number that connects variants between tables in same tab set
|
AF_BPI
|
BPI AF at each breakend preceded by their average
|
CNC
|
Copy Number Change at each breakend preceded by their average
|
CN
|
Copy Number at each breakend preceded by their average
|
SR_PR_ref
|
Number of Split Reads and Paired Reads supporting the ref allele, for reads where P(allele|read)>0.999
|
SScore
|
Somatic variant quality score
|
ntrx
|
Number of transcripts for given event
|
Transcript
|
Transcripts involved in the event. DEL/DUP/INS events involving more than 2 transcripts are shown in separate table.
|
PURPLE Inferred
Description
Column
|
Description
|
Tier
|
Priority of the specific event (from ‘simple_sv_annotation’: 1 highest, 4 lowest)
|
Chr
|
Chromosome
|
Start
|
Start position as inferred by BPI (for PURPLE-inferred SVs we use POS)
|
Effect
|
SV effect (based on SnpEff Effect Sequence Ontology - abbreviations are shown under Details in the Effects table
|
Detail
|
Prioritisation detail (from ‘simple_sv_annotation’)
|
Ploidy
|
Ploidy of variant from PURPLE (purity adjusted)
|
CN
|
Copy Number at each breakend preceded by their average
|
CNC
|
Copy Number Change at each breakend preceded by their average
|
ID
|
ID of BND from Manta (or PURPLE for PURPLE-inferred SVs))
|
DEL/DUP/INS
Main Columns
Description
Column
|
Description
|
nrow
|
Row number that connects variants between tables in same tab set
|
varnum
|
Original event row number that connects variants to events
|
TierTop
|
Top priority of the event (from ‘simple_sv_annotation’: 1 highest, 4 lowest)
|
Tier
|
Priority of the specific event (from ‘simple_sv_annotation’: 1 highest, 4 lowest)
|
Type
|
Type of structural variant
|
Chr
|
Chromosome
|
Start
|
Start position as inferred by BPI (for PURPLE-inferred SVs we use POS)
|
End
|
End position. For BNDs this has been assigned to the Chr:Start of the BND’s mate for convenience. Values are inferred by BPI (PURPLE-inferred SVs don’t have an End).
|
Effect
|
SV effect (based on SnpEff Effect Sequence Ontology - abbreviations are shown under Details in the Effects table
|
Genes
|
Genes involved in the event. DEL/DUP/INS events involving more than 2 genes are shown in separate table.
|
Transcript
|
Transcripts involved in the event. DEL/DUP/INS events involving more than 2 transcripts are shown in separate table.
|
Detail
|
Prioritisation detail (from ‘simple_sv_annotation’)
|
SR_PR_alt
|
Number of Split Reads and Paired Reads supporting the alt allele, for reads where P(allele|read)>0.999
|
AF_PURPLE
|
PURPLE AF at each breakend preceded by their average
|
Other Columns
Description
Column
|
Description
|
varnum
|
Original event row number that connects variants to events
|
Ploidy
|
Ploidy of variant from PURPLE (purity adjusted)
|
AF_BPI
|
BPI AF at each breakend preceded by their average
|
CNC
|
Copy Number Change at each breakend preceded by their average
|
CN
|
Copy Number at each breakend preceded by their average
|
SR_PR_ref
|
Number of Split Reads and Paired Reads supporting the ref allele, for reads where P(allele|read)>0.999
|
SScore
|
Somatic variant quality score
|
Many Genes
Description
Column
|
Description
|
nrow
|
Row number that connects variants between tables in same tab set
|
varnum
|
Original event row number that connects variants to events
|
Tier
|
Priority of the specific event (from ‘simple_sv_annotation’: 1 highest, 4 lowest)
|
Type
|
Type of structural variant
|
Chr
|
Chromosome
|
Start
|
Start position as inferred by BPI (for PURPLE-inferred SVs we use POS)
|
End
|
End position. For BNDs this has been assigned to the Chr:Start of the BND’s mate for convenience. Values are inferred by BPI (PURPLE-inferred SVs don’t have an End).
|
Effect
|
SV effect (based on SnpEff Effect Sequence Ontology - abbreviations are shown under Details in the Effects table
|
ngen
|
Number of genes for given event
|
Genes
|
Genes involved in the event. DEL/DUP/INS events involving more than 2 genes are shown in separate table.
|
Many Transcripts
Description
Column
|
Description
|
nrow
|
Row number that connects variants between tables in same tab set
|
varnum
|
Original event row number that connects variants to events
|
Tier
|
Priority of the specific event (from ‘simple_sv_annotation’: 1 highest, 4 lowest)
|
Type
|
Type of structural variant
|
Chr
|
Chromosome
|
Start
|
Start position as inferred by BPI (for PURPLE-inferred SVs we use POS)
|
End
|
End position. For BNDs this has been assigned to the Chr:Start of the BND’s mate for convenience. Values are inferred by BPI (PURPLE-inferred SVs don’t have an End).
|
Effect
|
SV effect (based on SnpEff Effect Sequence Ontology - abbreviations are shown under Details in the Effects table
|
ntrx
|
Number of transcripts for given event
|
Transcript
|
Transcripts involved in the event. DEL/DUP/INS events involving more than 2 transcripts are shown in separate table.
|
Copy Number Variants
The purity and ploidy estimator PURPLE is used to generate a copy number profile for the somatic sample.
QC, Purity and Ploidy Summary
PURPLE outputs a QC status along with a summary for the inferred purity and ploidy of the somatic sample. A failed QC status can be attributed to several factors (see Description
below).
Description
QC Status
The QC Status field reflects how we have determined the purity of the sample:
NORMAL
- PURPLE fit the purity using COBALT and AMBER output.
HIGHLY_DIPLOID
- The fitted purity solution is highly diploid (> 95%) with a large range of potential solutions, but somatic variants are unable to help either because they were not supplied or because their implied purity was too low.
SOMATIC
- Somatic variants have improved the otherwise highly diploid solution.
NO_TUMOR
- PURPLE failed to find any aneuploidy and somatic variants were supplied but there were fewer than 300 with observed VAF > 0.1.
QC Failure
There are several reasons PURPLE may classify a sample as failed:
FAIL_SEGMENT
: more than 220 copy number segments not supported at either end by SV breakpoints. Indicates samples with extreme GC bias, with differences in depth of >= 10x between high and low GC regions. GC normalisation is unreliable when the corrections are so extreme so it is recommended to fail the sample (concerns with miscalled deletions or amplifications or have poor sensitivity in high GC regions.
NO_TUMOR
: no aneuploidy found and the number of somatic SNVs found is less than 1,000
MIN_PURITY
: fitted purity < 20%
FAIL_DELETED_GENES
: more than 280 deleted genes. This QC step was added after observing that in a handful of samples with high MB scale positive GC bias we sometimes systematically underestimate the copy number in high GC regions. This can lead us to incorrectly infer homozygous loss of entire chromosomes, particularly on chromosomes 17 and 19.
FAIL_GENDER
: if the AMBER and COBALT inferred genders are inconsistent then the COBALT one is used but the sample is failed.
Variable
|
value
|
details
|
QC_Status
|
PASS
|
|
Purity
|
0.43 (0.41-0.79)
|
Purity of tumor in the sample (and min-max with score within 10% of best)
|
Ploidy
|
2.911 (2.851-4.917)
|
Average ploidy of tumor sample after adjusting for purity (and min-max with score within 10% of best)
|
Gender
|
MALE
|
|
WGD
|
true
|
Whole genome duplication
|
MSI (indels/Mb)
|
MSS (0.135)
|
MSI status (MSI, MSS or UNKNOWN if somatic variants not supplied) & MS Indels per Mb
|
Polyclonal Prop
|
0.287
|
Proportion of CN regions that are more than 0.25 from a whole copy number
|
Diploidy Prop
|
0.015 (0.001-0.015)
|
Proportion of CN regions that have 1 (+- 0.2) minor and major allele
|
Segment_Pass
|
TRUE
|
Score: 15; Unsupported: 15
|
Gender_Pass
|
TRUE
|
Amber: MALE; Cobalt: MALE
|
DelGenes_Pass
|
TRUE
|
count: 77
|
TMB
|
12.714 (HIGH)
|
Tumor mutational burden per mega base (Status: ‘HIGH’, ‘LOW’ or ‘UNKNOWN’ if somatic variants not supplied)
|
TML
|
0 (LOW)
|
Tumor mutational load (Status: ‘HIGH’, ‘LOW’ or ‘UNKNOWN’ if somatic variants not supplied)
|
UMCCR Gene CNV Calls
Description
PURPLE copy number alterations in the UMCCR Cancer Gene panel (~1,200 genes) - description is from https://github.com/hartwigmedical/hmftools/blob/master/purity-ploidy-estimator/README.md#gene-copy-number-file
Column
|
Description
|
gene
|
Name of gene
|
minCN/maxCN
|
Min/Max copy number found in gene exons
|
chrom/start/end
|
Chromosome/start/end location of gene transcript
|
chrBand
|
Chromosome band of the gene
|
onco_or_ts
|
oncogene (‘oncogene’), tumor suppressor (‘tsgene’), or both (‘onco+ts’), as reported by Cancermine
|
transcriptID
|
Ensembl transcript ID (dot version)
|
minMinorAllelePloidy
|
Minimum allele ploidy found over the gene exons - useful for identifying LOH events
|
somReg (somaticRegions)
|
Count of somatic copy number regions this gene spans
|
germDelReg (germlineHomDeletionRegions / germlineHetToHomDeletionRegions)
|
Number of regions spanned by this gene that are (homozygously deleted in the germline / both heterozygously deleted in the germline and homozygously deleted in the tumor)
|
minReg (minRegions)
|
Number of somatic regions inside the gene that share the min copy number
|
minRegStartEnd
|
Start/End base of the copy number region overlapping the gene with the minimum copy number
|
minRegSupportStartEndMethod
|
Start/end support of the CN region overlapping the gene with the min CN (plus determination method)
|
Genome-wide CNV Segments
Description
PURPLE outputs a file with the copy number profile of all contiguous segments of the tumor sample:
PURPLE copy number profile of all (contiguous) segments of the tumor sample - description is from https://github.com/hartwigmedical/hmftools/blob/master/purity-ploidy-estimator/README.md#copy-number-file
Column
|
Description
|
Chr/Start/End
|
Coordinates of copy number segment
|
CN
|
Fitted absolute copy number of segment adjusted for purity and ploidy
|
Ploidy Min+Maj
|
Ploidy of minor + major allele adjusted for purity
|
BAF
|
Tumor BAF after adjusted for purity and ploidy
|
BafCount
|
Count of AMBER baf points covered by this segment
|
Start/End SegSupport
|
Type of SV support for the CN breakpoint at start/end of region. Allowed values: CENTROMERE, TELOMERE, INV, DEL, DUP, BND (translocation), SGL (single breakend SV support), NONE (no SV support for CN breakpoint), MULT (multiple SV support at exact breakpoint)
|
Method
|
Method used to determine the CN of the region. Allowed values: BAF_WEIGHTED (avg of all depth windows for the region), STRUCTURAL_VARIANT (inferred using ploidy of flanking SVs), LONG_ARM (inferred from the long arm), GERMLINE_AMPLIFICATION (inferred using special logic to handle regions of germline amplification)
|
windowCount
|
Count of COBALT windows covered by this segment
|
GC
|
Proportion of segment that is G or C
|
PURPLE Charts
PURPLE generates charts for summarising tumor sample characteristics. Description is from the PURPLE docs.
Copy number / Minor allele ploidy
The following figures show the AMBER BAF count weighted distribution of copy number and minor allele ploidy throughout the fitted segments. Copy numbers are broken down by colour into their respective minor allele ploidy (MAP) while the minor allele ploidy figure is broken down by copy number.


Rainfall
If a somatic variant VCF has been supplied, a figure will be produced showing the somatic variant ploidy broken down by copy number as well as a rainfall plot with kataegis clusters highlighted in grey.


Purity/ploidy
The following ‘sunrise’ chart shows the range of scores of all examined solutions of purity and ploidy. Crosshairs identify the best purity / ploidy solution.

Clonality
The following diagram illustrates the clonality model of a typical sample.
The top figure shows the histogram of somatic ploidy for all SNVs and INDELs in blue. Superimposed are peaks in different colours fitted from the sample as described in the docs while the black line shows the overall fitted ploidy distribution. Red filled peaks are below the 0.85 subclonal threshold.
We can determine the likelihood of a variant being subclonal at any given ploidy as shown in the bottom half of the figure.

Segment
The contribution of each fitted segment to the final score of the best fit is shown in the following figure. Each segment is divided into its major and minor allele ploidy. The area of each circle shows the weight (AMBER baf count) of each segment.

Oncoviruses
Oncoviruses and their integration sites. Viral sequences are obtained from the GDC database. Host genes are reported if the integration site falls on a gene or at least before 100kbp of the gene start.
## No oncoviral content detected in this sample.
Addendum
Back to top
Conda Pkgs Main
name
|
version
|
build
|
channel
|
envs
|
umccrise
|
1.0.0
|
dev_0
|
<develop>
|
NA
|
snakemake
|
5.17.0
|
dev_0
|
<develop>
|
NA
|
reference-data
|
1.0.3
|
dev_0
|
<develop>
|
NA
|
r-base
|
3.5.1
|
hc461eb7_1012
|
conda-forge
|
_pcgr, _cancer_report
|
r-base
|
3.6.3
|
h316533a_2
|
conda-forge
|
_hmf
|
python
|
3.7.3
|
h357f687_2
|
conda-forge
|
NA, _pcgr, _hmf
|
python
|
3.8.2
|
he5300dc_7_cpython
|
conda-forge
|
_cancer_report
|
pcgr
|
0.8.4.10
|
py37r35_0
|
pcgr
|
_pcgr
|
pandocfilters
|
1.4.2
|
py37_1
|
NA
|
NA
|
pandoc
|
2.9.2.1
|
0
|
conda-forge
|
NA, _pcgr, _hmf, _cancer_report
|
ngs-utils
|
2.6.2
|
dev_0
|
<develop>
|
NA
|
ngs_utils
|
2.5.6
|
py37_0
|
vladsaveliev
|
_pcgr
|
multiqc-bcbio
|
0.2.8
|
pypi_0
|
pypi
|
NA
|
multiqc
|
1.9.dev0
|
dev_0
|
<develop>
|
NA
|
htslib
|
1.10.2
|
h78d89cc_0
|
bioconda
|
NA, _hmf
|
htslib
|
1.9
|
h244ad75_9
|
bioconda
|
_pcgr
|
hmftools-sage
|
1.0
|
0
|
bioconda
|
_hmf
|
hmftools-purple
|
2.40
|
0
|
bioconda
|
_hmf
|
hmftools-linx
|
1.7
|
0
|
bioconda
|
_hmf
|
hmftools-cobalt
|
1.8
|
0
|
bioconda
|
_hmf
|
hmftools-amber
|
3.2
|
0
|
bioconda
|
_hmf
|
gridss
|
2.8.3
|
0
|
bioconda
|
_hmf
|
cpsr
|
0.5.2.6
|
0
|
pcgr
|
_pcgr
|
conpair
|
0.2
|
pypi_0
|
pypi
|
NA
|
cacao
|
0.2.1.2
|
0
|
pcgr
|
_pcgr
|
LS0tCmF1dGhvcjogIlVuaXZlcnNpdHkgb2YgTWVsYm91cm5lIENlbnRyZSBmb3IgQ2FuY2VyIFJlc2VhcmNoIgpkYXRlOiAiYHIgU3lzLnRpbWUoKWAiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdGhlbWU6IGNvc21vICMgZGFya2x5CiAgICBjc3M6IHN0eWxlLmNzcwogICAgdG9jOiBmYWxzZQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogIHJtZGZvcm1hdHM6Om1hdGVyaWFsOgogICAgaGlnaGxpZ2h0OiBrYXRlCnBhcmFtczoKICB0aXRsZTogIkNhbmNlciBSZXBvcnQgZm9yIFNhbXBsZSAiCiAgdHVtb3JfbmFtZTogJ3gnCiAgYmF0Y2hfbmFtZTogJ3gnCiAgZ2Vub21lX2J1aWxkOiAnaGczOCcgIyAnaGcxOScKICBrZXlfZ2VuZXM6ICd4JwogIGFmX2dsb2JhbDogJ3gnCiAgYWZfa2V5Z2VuZXM6ICd4JwogIHNvbWF0aWNfc252OiAneCcKICBzb21hdGljX3N2OiAneCcKICBwdXJwbGVfZ2VuZV9jbnY6ICd4JwogIHB1cnBsZV9jbnY6ICd4JwogIHB1cnBsZV9wdXJpdHk6ICd4JwogIHB1cnBsZV9xYzogJ3gnCiAgb25jb3ZpcmFsX3ByZXNlbnRfdmlydXNlczogJ3gnCiAgb25jb3ZpcmFsX2JyZWFrcG9pbnRzX3RzdjogJ3gnCiAgY29uZGFfbGlzdDogJ3gnCiAgIyBnZW5vbWVfYnVpbGQ6ICAgICAnaGczOCcKICAjIHR1bW9yX25hbWU6ICAgICAgICdUX1NSUjc4OTA5MDJfMjBwYycKICAjIGJhdGNoX25hbWU6ICAgICAgICdUX1NSUjc4OTA5MDJfMjBwYycKICAjIGtleV9nZW5lczogICAgICAgICd+L3Jqbi9leHRyYXMvdmxhZC9zeW5jZWQvTkdTX1V0aWxzL25nc191dGlscy9yZWZlcmVuY2VfZGF0YS9rZXlfZ2VuZXMvdW1jY3JfY2FuY2VyX2dlbmVzLmxhdGVzdC50c3YnCiAgIyBhZl9nbG9iYWw6ICAgICAgICAnfi9yam4vZXh0cmFzL3ZsYWQvc3luY2VkL3VtY2NyL3VtY2NyaXNlX3Rlc3RfZGF0YS9yZXN1bHRzL1RfU1JSNzg5MDkwMl8yMHBjL3dvcmsvVF9TUlI3ODkwOTAyXzIwcGMvcm1kL2Fmcy9hZl90dW1vci50eHQnCiAgIyBhZl9rZXlnZW5lczogICAgICAnfi9yam4vZXh0cmFzL3ZsYWQvc3luY2VkL3VtY2NyL3VtY2NyaXNlX3Rlc3RfZGF0YS9yZXN1bHRzL1RfU1JSNzg5MDkwMl8yMHBjL3dvcmsvVF9TUlI3ODkwOTAyXzIwcGMvcm1kL2Fmcy9hZl90dW1vcl9rZXlnZW5lcy50eHQnCiAgIyBzb21hdGljX3NudjogICAgICAnfi9yam4vZXh0cmFzL3ZsYWQvc3luY2VkL3VtY2NyL3VtY2NyaXNlX3Rlc3RfZGF0YS9yZXN1bHRzL1RfU1JSNzg5MDkwMl8yMHBjL3dvcmsvVF9TUlI3ODkwOTAyXzIwcGMvcm1kL2RyYWdlbi13aXRoX2Nocl9wcmVmaXgudmNmJwogICMgc29tYXRpY19zdjogICAgICAgJ34vcmpuL2V4dHJhcy92bGFkL3N5bmNlZC91bWNjci91bWNjcmlzZV90ZXN0X2RhdGEvcmVzdWx0cy9UX1NSUjc4OTA5MDJfMjBwYy9UX1NSUjc4OTA5MDJfMjBwYy9zdHJ1Y3R1cmFsL1RfU1JSNzg5MDkwMl8yMHBjLW1hbnRhLnRzdicKICAjIHB1cnBsZV9nZW5lX2NudjogICd+L3Jqbi9leHRyYXMvdmxhZC9zeW5jZWQvdW1jY3IvdW1jY3Jpc2VfdGVzdF9kYXRhL3Jlc3VsdHMvVF9TUlI3ODkwOTAyXzIwcGMvd29yay9UX1NSUjc4OTA5MDJfMjBwYy9wdXJwbGUvVF9TUlI3ODkwOTAyXzIwcGMucHVycGxlLmNudi5nZW5lLnRzdicKICAjIHB1cnBsZV9jbnY6ICAgICAgICd+L3Jqbi9leHRyYXMvdmxhZC9zeW5jZWQvdW1jY3IvdW1jY3Jpc2VfdGVzdF9kYXRhL3Jlc3VsdHMvVF9TUlI3ODkwOTAyXzIwcGMvd29yay9UX1NSUjc4OTA5MDJfMjBwYy9wdXJwbGUvVF9TUlI3ODkwOTAyXzIwcGMucHVycGxlLmNudi5zb21hdGljLnRzdicKICAjIHB1cnBsZV9wdXJpdHk6ICAgICd+L3Jqbi9leHRyYXMvdmxhZC9zeW5jZWQvdW1jY3IvdW1jY3Jpc2VfdGVzdF9kYXRhL3Jlc3VsdHMvVF9TUlI3ODkwOTAyXzIwcGMvd29yay9UX1NSUjc4OTA5MDJfMjBwYy9wdXJwbGUvVF9TUlI3ODkwOTAyXzIwcGMucHVycGxlLnB1cml0eS50c3YnCiAgIyBwdXJwbGVfcWM6ICAgICAgICAnfi9yam4vZXh0cmFzL3ZsYWQvc3luY2VkL3VtY2NyL3VtY2NyaXNlX3Rlc3RfZGF0YS9yZXN1bHRzL1RfU1JSNzg5MDkwMl8yMHBjL3dvcmsvVF9TUlI3ODkwOTAyXzIwcGMvcHVycGxlL1RfU1JSNzg5MDkwMl8yMHBjLnB1cnBsZS5xYycKICAjIGNvbmRhX2xpc3Q6ICAgICAgICd+L3Jqbi9leHRyYXMvdmxhZC9zeW5jZWQvdW1jY3IvdW1jY3Jpc2VfdGVzdF9kYXRhL3Jlc3VsdHMvVF9TUlI3ODkwOTAyXzIwcGMvd29yay9UX1NSUjc4OTA5MDJfMjBwYy9ybWQvY29uZGFfcGtnX2xpc3QudHh0JwpkZXNjcmlwdGlvbjogIkFuYWx5c2lzIG9mIHR1bW9yL25vcm1hbCBzYW1wbGVzIGF0IFVNQ0NSIgp0aXRsZTogImByIHBhc3RlKHBhcmFtcyR0aXRsZSwgcGFyYW1zJGJhdGNoX25hbWUpYCIKLS0tCgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoubWFpbi1jb250YWluZXIgewogIG1heC13aWR0aDogMTQwMHB4OwogIG1hcmdpbi1sZWZ0OiBhdXRvOwogIG1hcmdpbi1yaWdodDogYXV0bzsKfQo8L3N0eWxlPgoKYGBge3Iga25pdHJfb3B0cywgaW5jbHVkZT1GfQprbml0cjo6b3B0c19jaHVuayRzZXQoY29sbGFwc2UgPSBUUlVFLCBlY2hvID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSkKYGBgCgpgYGB7ciByZW5kZXJfcmVwb3J0X2ludGVyYWN0aXZlbHksIGV2YWw9RiwgZWNobz1GfQpiYXRjaF9uYW1lIDwtICJFbG9uIgojIHR1bW9yX25hbWUgPC0gc3Ryc3BsaXQoYmF0Y2hfbmFtZSwgIl9fIilbWzFdXVsyXQp0dW1vcl9uYW1lIDwtICJFbG9uX1QiCnNudl9jYWxsZXIgPC0gImVuc2VtYmxlIiAjIGVuc2VtYmxlCgpwYXJhbXNfdG1wIDwtIGxpc3QoCiAgc3BhcnRhbiA9IGxpc3QoCiAgICB0dW1vcl9uYW1lPScnLAogICAgYmF0Y2hfbmFtZT0nJywKICAgIGdlbm9tZV9idWlsZD0nJywKICAgIGtleV9nZW5lcz0nJywKICAgIGFmX2dsb2JhbD0nJywKICAgIGFmX2tleWdlbmVzPScnLAogICAgc29tYXRpY19zbnY9JycsCiAgICBzb21hdGljX3N2PScnLAogICAgcHVycGxlX2dlbmVfY252PScnLAogICAgcHVycGxlX2Nudj0nJywKICAgIHB1cnBsZV9wdXJpdHk9JycsCiAgICBwdXJwbGVfcWM9JycpLAogIHJhaWppbiA9IGxpc3QoCiAgICB0dW1vcl9uYW1lPScnLAogICAgYmF0Y2hfbmFtZT0nJywKICAgIGdlbm9tZV9idWlsZD0nJywKICAgIGtleV9nZW5lcz0nJywKICAgIGFmX2dsb2JhbD0nJywKICAgIGFmX2tleWdlbmVzPScnLAogICAgc29tYXRpY19zbnY9JycsCiAgICBzb21hdGljX3N2PScnLAogICAgcHVycGxlX2dlbmVfY252PScnLAogICAgcHVycGxlX2Nudj0nJywKICAgIHB1cnBsZV9wdXJpdHk9JycsCiAgICBwdXJwbGVfcWM9JycpLAogIGxvY2FsID0gbGlzdCgKICAgIGdlbm9tZV9idWlsZD0naGczOCcsCiAgICBrZXlfZ2VuZXM9J2RhdGEvcmVmL3VtY2NyX2NhbmNlcl9nZW5lcy5sYXRlc3QudHN2JywKICAgIGFmX2dsb2JhbD1nbHVlOjpnbHVlKCdkYXRhL3dvcmsve2JhdGNoX25hbWV9L3JtZC9hZnMvYWZfdHVtb3IudHh0JyksCiAgICBhZl9rZXlnZW5lcz1nbHVlOjpnbHVlKCdkYXRhL3dvcmsve2JhdGNoX25hbWV9L3JtZC9hZnMvYWZfdHVtb3Jfa2V5Z2VuZXMudHh0JyksCiAgICBzb21hdGljX3Nudj1nbHVlOjpnbHVlKCdkYXRhL3dvcmsve2JhdGNoX25hbWV9L3JtZC97c252X2NhbGxlcn0td2l0aF9jaHJfcHJlZml4LnZjZicpLAogICAgc29tYXRpY19zdj1nbHVlOjpnbHVlKCdkYXRhL3tiYXRjaF9uYW1lfS9zdHJ1Y3R1cmFsL3tiYXRjaF9uYW1lfS1tYW50YS50c3YnKSwKICAgIHB1cnBsZV9nZW5lX2Nudj1nbHVlOjpnbHVlKCdkYXRhL3dvcmsve2JhdGNoX25hbWV9L3B1cnBsZS97YmF0Y2hfbmFtZX0ucHVycGxlLmNudi5nZW5lLnRzdicpLAogICAgcHVycGxlX2Nudj1nbHVlOjpnbHVlKCdkYXRhL3dvcmsve2JhdGNoX25hbWV9L3B1cnBsZS97YmF0Y2hfbmFtZX0ucHVycGxlLmNudi5zb21hdGljLnRzdicpLAogICAgcHVycGxlX3B1cml0eT1nbHVlOjpnbHVlKCdkYXRhL3dvcmsve2JhdGNoX25hbWV9L3B1cnBsZS97YmF0Y2hfbmFtZX0ucHVycGxlLnB1cml0eS50c3YnKSwKICAgIHB1cnBsZV9xYz1nbHVlOjpnbHVlKCdkYXRhL3dvcmsve2JhdGNoX25hbWV9L3B1cnBsZS97YmF0Y2hfbmFtZX0ucHVycGxlLnFjJyksCiAgICBjb25kYV9saXN0PWdsdWU6OmdsdWUoJ2RhdGEvd29yay9jb25kYV9wa2dfbGlzdC50eHQnKQogICkKKQoKcGFyYW1zIDwtIHBhcmFtc190bXBbWyJsb2NhbCJdXQpwYXJhbXMkYmF0Y2hfbmFtZSA8LSBiYXRjaF9uYW1lCnBhcmFtcyR0dW1vcl9uYW1lIDwtIHR1bW9yX25hbWUKCnJlbmRlcl9tZSA8LSBmdW5jdGlvbigpIHsKICBybWFya2Rvd246OnJlbmRlcigKICAgICJjYW5jZXJfcmVwb3J0LlJtZCIsCiAgICBwYXJhbXMgPSBwYXJhbXMpCn0KcmVuZGVyX21lKCkKYGBgCgpgYGB7ciBsb2FkX3BrZ3N9CiMgQmlvY29uZHVjdG9yCmxpYnJhcnkoQlNnZW5vbWUpCmxpYnJhcnkoTXV0YXRpb25hbFBhdHRlcm5zKQpyZWZfZ2Vub21lIDwtIHBhc3RlMCgiQlNnZW5vbWUuSHNhcGllbnMuVUNTQy4iLCBwYXJhbXMkZ2Vub21lX2J1aWxkKQpsaWJyYXJ5KHJlZl9nZW5vbWUsIGNoYXJhY3Rlci5vbmx5ID0gVFJVRSkKdHhfcmVmX2dlbm9tZSA8LSBwYXN0ZTAoIlR4RGIuSHNhcGllbnMuVUNTQy4iLCBwYXJhbXMkZ2Vub21lX2J1aWxkLCAiLmtub3duR2VuZSIpCmxpYnJhcnkodHhfcmVmX2dlbm9tZSwgY2hhcmFjdGVyLm9ubHkgPSBUUlVFKQojIENSQU4KbGlicmFyeShkZXZ0b29scykKbGlicmFyeShEVCkKbGlicmFyeShkcGx5cikKbGlicmFyeShnbHVlKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoaHRtbHRvb2xzKQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkocHVycnIpCmxpYnJhcnkocmVhZHIpCmxpYnJhcnkocm1hcmtkb3duKQpsaWJyYXJ5KHN0cmluZ3IpCmxpYnJhcnkodGlkeXIpCmBgYAoKYGBge3IgZnVuY3N9CiMgZm9yIGNoZWNraW5nIGlmIHRoZSBjb2x1bW5zIGluIHRoZSBkdCBhcmUgYWxsIGRlc2NyaWJlZApjaGVja19jb2xzX2Rlc2NyaWJlZCA8LSBmdW5jdGlvbihjb2xzLCBkZXNjcikgewogIHN0b3BpZm5vdChpcy5jaGFyYWN0ZXIoY29scyksIGlzLmF0b21pYyhjb2xzKSkKICBzdG9waWZub3QoaXMuY2hhcmFjdGVyKGRlc2NyKSwgaXMuYXRvbWljKGRlc2NyKSkKICBmb3IgKGNvbCBpbiBjb2xzKSB7CiAgICBpZiAoIWNvbCAlaW4lIGRlc2NyKSB7CiAgICAgIHdhcm5pbmcoZ2x1ZTo6Z2x1ZSgie2NvbH0gaXMgbm90IGRlc2NyaWJlZCEiKSkKICAgIH0KICB9Cn0KCiMgZ2V0IGpzIGluZGljZXMgd2hlbiB1c2luZyBpbiBEVCBvcHRpb25zCmNvbF9pbmRfanMgPC0gZnVuY3Rpb24oZHQsIGNvbCkgewogIG50YWIgPC0gc2V0TmFtZXMoKDE6bmNvbChkdCkgLSAxKSwgbmFtZXMoZHQpKQogIHN0b3BpZm5vdChhbGwoY29sICVpbiUgbmFtZXMoZHQpKSkKICBzb3J0KHVubmFtZShudGFiW2NvbF0pKQp9CgojIHVzZWQgaW4gU1YgdGFibGUgRGV0YWlscwpzdl9kZXRhaWxfdGFibGUgPC0gZnVuY3Rpb24odGFiKSB7CiAgY2hlY2tfY29sc19kZXNjcmliZWQoY29sbmFtZXModGFiKSwgc3ZfY29sX2Rlc2NyJENvbHVtbikKICBsaXN0KENvbHVtbiA9IGNvbG5hbWVzKHRhYikpICU+JQogICAgdGliYmxlOjphc190aWJibGUoKSAlPiUKICAgIGRwbHlyOjpsZWZ0X2pvaW4oc3ZfY29sX2Rlc2NyLCBieSA9ICJDb2x1bW4iKSAlPiUKICAgIGRwbHlyOjptdXRhdGUoCiAgICAgIENvbHVtbiA9IGthYmxlRXh0cmE6OmNlbGxfc3BlYyhDb2x1bW4sIGJvbGQgPSBUUlVFKSkgJT4lCiAgICBrbml0cjo6a2FibGUoZXNjYXBlID0gRkFMU0UpICU+JQogICAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gRkFMU0UsIHBvc2l0aW9uID0gImxlZnQiKSAlPiUKICAgIGthYmxlRXh0cmE6OnNjcm9sbF9ib3goaGVpZ2h0ID0gIjIwMHB4IikKfQpgYGAKCmBgYHtyIGFsbGVsZV9mcmVxX3ByZXB9CiMtLS0tIEFsbGVsZSBGcmVxdWVuY2llcyAtLS0tIwpzZXQuc2VlZCg0MikKYWZfZ2xvYmFsIDwtCiAgcmVhZHI6OnJlYWRfdHN2KHBhcmFtcyRhZl9nbG9iYWwsIGNvbF90eXBlcyA9ICJkIikgJT4lCiAgZHBseXI6Om11dGF0ZShzZXQgPSAiR2xvYmFsIikKCmFmX2tleWdlbmVzIDwtCiAgcmVhZHI6OnJlYWRfdHN2KHBhcmFtcyRhZl9rZXlnZW5lcywgY29sX3R5cGVzID0gImNpY2NjZCIpICU+JQogIGRwbHlyOjpzZWxlY3QoYWYpICU+JQogIGRwbHlyOjptdXRhdGUoc2V0ID0gJ0tleSBnZW5lcyBDRFMnKQoKYWZfYm90aCA8LQogIGRwbHlyOjpiaW5kX3Jvd3MoYWZfZ2xvYmFsLCBhZl9rZXlnZW5lcykgJT4lCiAgZHBseXI6Om11dGF0ZShzZXQgPSBmYWN0b3Ioc2V0LCBsZXZlbHMgPSBjKCJHbG9iYWwiLCAiS2V5IGdlbmVzIENEUyIpKSkKCm1vZGUyIDwtIGZ1bmN0aW9uKHgpIHsKICB1eCA8LSB1bmlxdWUoeCkKICB1eFt3aGljaC5tYXgodGFidWxhdGUobWF0Y2goeCwgdXgpKSldCn0KCmFmX3N0YXRzIDwtIGFmX2JvdGggJT4lCiAgZHBseXI6Omdyb3VwX2J5KHNldCkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShuID0gbigpLAogICAgICAgICAgICAgICAgICAgbWVhbiA9IHJvdW5kKG1lYW4oYWYpLCAyKSwKICAgICAgICAgICAgICAgICAgIG1lZGlhbiA9IHJvdW5kKG1lZGlhbihhZiksIDIpLAogICAgICAgICAgICAgICAgICAgbW9kZSA9IHJvdW5kKG1vZGUyKGFmKSwgMikpICU+JQogIHRpZHlyOjpjb21wbGV0ZShzZXQsIGZpbGwgPSBsaXN0KG4gPSAwKSkKYGBgCgpgYGB7ciBtdXRhdGlvbmFsX3NpZ3NfcHJlcH0KIy0tLS0gTXV0YXRpb25hbCBTaWduYXR1cmVzIC0tLS0jCnNvbWF0aWNfc252IDwtIE11dGF0aW9uYWxQYXR0ZXJuczo6cmVhZF92Y2ZzX2FzX2dyYW5nZXMoCiAgdmNmX2ZpbGVzID0gcGFyYW1zJHNvbWF0aWNfc252LAogIHNhbXBsZV9uYW1lcyA9IHBhcmFtcyR0dW1vcl9uYW1lLAogIGdlbm9tZSA9IHJlZl9nZW5vbWUsCiAgZ3JvdXAgPSAiYXV0bytzZXgiKQoKbXV0X21hdCA8LSBNdXRhdGlvbmFsUGF0dGVybnM6Om11dF9tYXRyaXgodmNmX2xpc3QgPSBzb21hdGljX3NudiwgcmVmX2dlbm9tZSA9IHJlZl9nZW5vbWUpCgojIyMtLS0gT0xEIFNpZ3MgLS0tIyMjCiMgR2V0IFNhbmdlciBzaWdzIGZyb20gImh0dHA6Ly9jYW5jZXIuc2FuZ2VyLmFjLnVrL2NhbmNlcmdlbm9tZS9hc3NldHMvc2lnbmF0dXJlc19wcm9iYWJpbGl0aWVzLnR4dCIKc2lnX3Byb2JzIDwtIGZpbGUucGF0aCgibWlzYy9zaWcvdjJfbWFyMjAxNS9zaWduYXR1cmVzX3Byb2JhYmlsaXRpZXMudHh0IikKIyBiZXR0ZXIgYmUgZXhwbGljaXQgLSB0aGUgc2lnX3Byb2JzIGZpbGUgaGFzIDcgZXh0cmEgZW1wdHkgY29sdW1ucwpjb2xfdHlwZXMgPC0gcGFzdGUwKGMoImNjYyIsIHBhc3RlMChyZXAoImQiLCAzMCksIGNvbGxhcHNlID0gIiIpLCAiY2NjY2NjYyIpLCBjb2xsYXBzZSA9ICIiKQpjb2xfbmFtZXMgPC0gYygiU3Vic3RUeXBlIiwgIlRyaW51Y2xlb3RpZGUiLCAiU29tTXV0VHlwZSIsIHBhc3RlMCgiU2lnIiwgMTozMCksIHBhc3RlMCgiZm9vIiwgMTo3KSkKY2FuY2VyX3NpZ25hdHVyZXMgPC0KICByZWFkcjo6cmVhZF90c3Yoc2lnX3Byb2JzLCBjb2xfbmFtZXMgPSBjb2xfbmFtZXMsIGNvbF90eXBlcyA9IGNvbF90eXBlcywgc2tpcCA9IDEpICU+JQogIGRwbHlyOjphcnJhbmdlKFN1YnN0VHlwZSkKCiMgc2FuaXR5IGNoZWNrIC0gbmVlZCB0byBiZSBpbiBzYW1lIG9yZGVyCnN0b3BpZm5vdChhbGwoY2FuY2VyX3NpZ25hdHVyZXMkU29tTXV0VHlwZSA9PSByb3duYW1lcyhtdXRfbWF0KSkpCiMgc2VsZWN0IG9ubHkgMzAgc2lnIGNvbHVtbnMsIDk2IG11dCB0eXBlcwpjYW5jZXJfc2lnbmF0dXJlcyA8LSBjYW5jZXJfc2lnbmF0dXJlcyAlPiUKICBkcGx5cjo6c2VsZWN0KDQ6MzMpICU+JQogIGFzLm1hdHJpeCgpCgojIyMtLS0gTkVXIFNpZ3MgLS0tIyMjCnNpZ19wcm9iczIgPC0gZmlsZS5wYXRoKCJtaXNjL3NpZy92M19tYXkyMDE5L3NpZ1Byb2ZpbGVyX1NCU19zaWduYXR1cmVzXzIwMTlfMDVfMjIuY3N2IikKY2FuY2VyX3NpZ25hdHVyZXMyIDwtCiAgcmVhZHI6OnJlYWRfY3N2KHNpZ19wcm9iczIsIGNvbF90eXBlcyA9IGNvbHMoLmRlZmF1bHQgPSAiZCIsIFR5cGUgPSAiYyIsIFN1YlR5cGUgPSAiYyIpKSAlPiUKICBkcGx5cjo6bXV0YXRlKFNvbU11dFR5cGUgPSBwYXN0ZTAoc3Vic3RyKFN1YlR5cGUsIDEsIDEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiWyIsIFR5cGUsICJdIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Vic3RyKFN1YlR5cGUsIDMsIDMpKSkgJT4lCiAgZHBseXI6OnNlbGVjdChTb21NdXRUeXBlLCBTQlMxOlNCUzg1KQoKIyBzYW5pdHkgY2hlY2sgLSBuZWVkIHRvIGJlIGluIHNhbWUgb3JkZXIKc3RvcGlmbm90KGFsbChjYW5jZXJfc2lnbmF0dXJlczIkU29tTXV0VHlwZSA9PSByb3duYW1lcyhtdXRfbWF0KSkpCiMgc2VsZWN0IG9ubHkgNjcgc2lnIGNvbHVtbnMsIDk2IG11dCB0eXBlcwpjYW5jZXJfc2lnbmF0dXJlczIgPC0gY2FuY2VyX3NpZ25hdHVyZXMyICU+JQogIGRwbHlyOjpzZWxlY3QoLTEpICU+JQogIGFzLm1hdHJpeCgpCgojIEZpdCBtdXRhdGlvbiBtYXRyaXggdG8gY2FuY2VyIHNpZ25hdHVyZXMKZml0X3JlcyA8LSBNdXRhdGlvbmFsUGF0dGVybnM6OmZpdF90b19zaWduYXR1cmVzKG11dF9tYXRyaXggPSBtdXRfbWF0LCBzaWduYXR1cmVzID0gY2FuY2VyX3NpZ25hdHVyZXMpCmZpdF9yZXMyIDwtIE11dGF0aW9uYWxQYXR0ZXJuczo6Zml0X3RvX3NpZ25hdHVyZXMobXV0X21hdHJpeCA9IG11dF9tYXQsIHNpZ25hdHVyZXMgPSBjYW5jZXJfc2lnbmF0dXJlczIpCgojIENvbnZlcnQgdG8gdGliYmxlcyBmb3IgbW9yZSBidWxsZXQtcHJvb2Ygc3Vic2V0dGluZwpmaXRfcmVzIDwtIHRpYmJsZTo6dGliYmxlKAogIHNpZyA9IHJvd25hbWVzKGZpdF9yZXMkY29udHJpYnV0aW9uKSwgIyBtYXRyaXggcm93bmFtZXMKICBjb250ciA9IHVubmFtZShmaXRfcmVzJGNvbnRyaWJ1dGlvblssIDFdKSkgIyBtYXRyaXggc2luZ2xlIGNvbHVtbiAtPiB2ZWN0b3IKCmZpdF9yZXMyIDwtIHRpYmJsZTo6dGliYmxlKAogIHNpZyA9IHJvd25hbWVzKGZpdF9yZXMyJGNvbnRyaWJ1dGlvbiksCiAgY29udHIgPSB1bm5hbWUoZml0X3JlczIkY29udHJpYnV0aW9uWywgMV0pKQoKIyBTZWxlY3Qgc2lnbmF0dXJlcyB3aXRoIHNvbWUgY29udHJpYnV0aW9uCmZpdF9yZXNfY29udHIgPC0gZHBseXI6OmZpbHRlcihmaXRfcmVzLCBjb250ciA+IDApCmZpdF9yZXNfY29udHIyIDwtIGRwbHlyOjpmaWx0ZXIoZml0X3JlczIsIGNvbnRyID4gMCkKCiMgSWYgdGhlcmUgYXJlIG5vIHNpZ25hdHVyZXMsIHJldHVybiBhIGR1bW15IHRpYmJsZQppZiAobnJvdyhmaXRfcmVzX2NvbnRyKSA9PSAwKSB7CiAgZml0X3Jlc19jb250ciA8LSB0aWJibGU6OnRpYmJsZSgKICAgIHNpZyA9ICJOT1NJR1MiLAogICAgY29udHIgPSAwCiAgKQp9CgppZiAobnJvdyhmaXRfcmVzX2NvbnRyMikgPT0gMCkgewogIGZpdF9yZXNfY29udHIyIDwtIHRpYmJsZTo6dGliYmxlKAogICAgc2lnID0gIk5PU0lHUyIsCiAgICBjb250ciA9IDAKICApCn0KCm11dF9zaWdfY29udHIgPC0KICBmaXRfcmVzX2NvbnRyICU+JQogIGRwbHlyOjptdXRhdGUoY29udHIgPSByb3VuZChjb250ciwgMCksCiAgICAgICAgICAgICAgICBSYW5rID0gYXMuaW50ZWdlcihiYXNlOjpyYW5rKC1jb250cikpKSAlPiUKICBkcGx5cjo6c2VsZWN0KFJhbmssIFNpZ25hdHVyZSA9IHNpZywgQ29udHJpYnV0aW9uID0gY29udHIpICU+JQogIGRwbHlyOjphcnJhbmdlKFJhbmspCm11dF9zaWdfY29udHIyIDwtCiAgZml0X3Jlc19jb250cjIgJT4lCiAgZHBseXI6Om11dGF0ZShjb250ciA9IHJvdW5kKGNvbnRyLCAwKSwKICAgICAgICAgICAgICAgIFJhbmsgPSBhcy5pbnRlZ2VyKGJhc2U6OnJhbmsoLWNvbnRyKSkpICU+JQogIGRwbHlyOjpzZWxlY3QoUmFuaywgU2lnbmF0dXJlID0gc2lnLCBDb250cmlidXRpb24gPSBjb250cikgJT4lCiAgZHBseXI6OmFycmFuZ2UoUmFuaykKYGBgCgpgYGB7ciBzdl9wcmlvcml0aXplX3ByZXB9CiMtLS0tIFN0cnVjdHVyYWwgVmFyaWFudHMgLS0tLSMKc3BsaXRfc3ZfZmllbGQgPC0gZnVuY3Rpb24oLmRhdGEsIGZpZWxkLCBpc19wY3QgPSBGQUxTRSkgewogICMgLSBzZXBhcmF0ZSBmaWVsZCBpbnRvIHR3byBwYXJ0cwogICMgLSBtdXRhdGUgdG8gcGN0IGFjY29yZGluZ2x5CiAgIyAtIG9yaWdpbmFsIGZpZWxkIGlzIG1lYW4gb2YgdHdvIHBhcnRzCiAgZl9xIDwtIHJsYW5nOjplbnF1byhmaWVsZCkKICBmX3N0ciA8LSBybGFuZzo6cXVvX25hbWUoZl9xKQogIGYxX3N0ciA8LSBzdHJfYyhmX3N0ciwgJzEnKQogIGYyX3N0ciA8LSBzdHJfYyhmX3N0ciwgJzInKQogIGYxX3EgPC0gc3ltKGYxX3N0cikKICBmMl9xIDwtIHN5bShmMl9zdHIpCiAgLmRhdGEgJT4lCiAgICB0aWR5cjo6c2VwYXJhdGUoISFmX3EsIGMoZjFfc3RyLCBmMl9zdHIpLCBzZXAgPSAiLCIsIGZpbGwgPSAicmlnaHQiKSAlPiUKICAgIGRwbHlyOjptdXRhdGUoCiAgICAgICEhZjFfcSA6PSByb3VuZChhcy5kb3VibGUoISFmMV9xKSAqIGlmZWxzZShpc19wY3QsIDEwMCwgMSksIDEpLAogICAgICAhIWYyX3EgOj0gcm91bmQoYXMuZG91YmxlKCEhZjJfcSkgKiBpZmVsc2UoaXNfcGN0LCAxMDAsIDEpLCAxKSwKICAgICAgISFmX3EgIDo9IHJvdW5kKCgoISFmMV9xICsgaWZlbHNlKGlzLm5hKCEhZjJfcSksICEhZjFfcSwgISFmMl9xKSkgLyAyKSwgMSkKICAgICkKfQoKY291bnRfcGllY2VzIDwtIGZ1bmN0aW9uKHgsIHNlcCkgewogIGlmZWxzZShuY2hhcih4KSA9PSAwLCAwLCBzdHJpbmdyOjpzdHJfY291bnQoeCwgc2VwKSArIDEpCn0KCmVmZmVjdF9hYmJyZXZpYXRpb25zIDwtIGMoCiAgIjNfcHJpbWVfVVRSX3RydW5jYXRpb24iID0gIjNVVFJ0cnVuYyIsICIzX3ByaW1lX1VUUl92YXJpYW50IiA9ICIzVVRSdmFyIiwKICAiNV9wcmltZV9VVFJfdHJ1bmNhdGlvbiIgPSAiNVVUUnRydW5jIiwgICI1X3ByaW1lX1VUUl92YXJpYW50IiA9ICI1VVRSdmFyIiwKICAiZmVhdHVyZV9mdXNpb24iID0gIkZ1cyIsICJiaWRpcmVjdGlvbmFsX2dlbmVfZnVzaW9uIiA9ICJCaWRGdXNHIiwgImdlbmVfZnVzaW9uIiA9ICJGdXNHIiwKICAiY2hyb21vc29tZV9udW1iZXJfdmFyaWF0aW9uIiA9ICJDaHJvbU51bVYiLCAiY29uc2VydmF0aXZlX2luZnJhbWVfZGVsZXRpb24iID0gIkNvbnNJbmZyYW1lRGVsIiwKICAiZG93bnN0cmVhbV9nZW5lX3ZhcmlhbnQiID0gIkRuc3RyZWFtR1YiLCAidXBzdHJlYW1fZ2VuZV92YXJpYW50IiA9ICJVcHN0cmVhbUdWIiwKICAiZHVwbGljYXRpb24iID0gIkR1cCIsICJleG9uX2xvc3NfdmFyaWFudCIgPSAiRXhvbkxvc3NWIiwKICAiZmVhdHVyZV9hYmxhdGlvbiIgPSAiRGVsRyIsICJ0cmFuc2NyaXB0X2FibGF0aW9uIiA9ICJEZWxUeCIsCiAgImZyYW1lc2hpZnRfdmFyaWFudCIgPSAiRnJhbWVzaGlmdFYiLCAiaW50ZXJnZW5pY19yZWdpb24iID0gIkludGVyZ2VuUmVnIiwgImludHJhZ2VuaWNfdmFyaWFudCIgPSAiSW50cmFnZW5WIiwKICAiaW50cm9uX3ZhcmlhbnQiID0gIkludHJvblYiLCAgIm5vX2Z1bmNfZWZmZWN0IiA9ICJOb0Z1bmNFZmYiLCAibm9fcHJpb19lZmZlY3QiID0gIk5vUHJpb0VmZiIsCiAgIm5vbl9jb2RpbmdfdHJhbnNjcmlwdF92YXJpYW50IiA9ICJOb25jb2RUeFYiLAogICJzcGxpY2VfYWNjZXB0b3JfdmFyaWFudCIgPSAiU3BsaWNlQWNjViIsCiAgInNwbGljZV9kb25vcl92YXJpYW50IiA9ICJTcGxpY2VEb25WIiwgInNwbGljZV9yZWdpb25fdmFyaWFudCIgPSAiU3BsaWNlUmVnViIsCiAgInN0YXJ0X2xvc3QiID0gIlN0YXJ0TG9zcyIsICJzdG9wX2dhaW5lZCIgPSAiU3RvcEdhaW4iLCAic3RvcF9sb3N0IiA9ICJTdG9wTG9zcyIsCiAgIlRGX2JpbmRpbmdfc2l0ZV92YXJpYW50IiA9ICJURkJTVmFyIiwgICJURkJTX2FibGF0aW9uIiA9ICJURkJTRGVsIikKZWZmZWN0X2FiYnJldl9ubXMgPC0gbmFtZXMoZWZmZWN0X2FiYnJldmlhdGlvbnMpCgphYmJyZXZpYXRlX2VmZmVjdCA8LSBmdW5jdGlvbihlZmZlY3RzKSB7CiAgIyB0YWtlIHN0cmluZyBhcyB4JnkmegogICMgc3BsaXQgYnkgJgogICMgYWJicmV2aWF0ZSBlYWNoIHBpZWNlIGFuZCBnbHVlIGJhY2sgd2l0aCBjb21tYQoKICAuYWJicmV2aWF0ZV9lZmZlY3QgPC0gZnVuY3Rpb24oZWZmZWN0KSB7CiAgICBpZmVsc2UoZWZmZWN0ICVpbiUgZWZmZWN0X2FiYnJldl9ubXMsIGVmZmVjdF9hYmJyZXZpYXRpb25zW2VmZmVjdF0sIGVmZmVjdCkKICB9CgogIHN0cnNwbGl0KGVmZmVjdHMsICImIilbWzFdXSAlPiUKICAgIHB1cnJyOjptYXBfY2hyKC5hYmJyZXZpYXRlX2VmZmVjdCkgJT4lCiAgICBwYXN0ZShjb2xsYXBzZSA9ICIsICIpCn0KYWJicmV2aWF0ZV9lZmZlY3R2IDwtIFZlY3Rvcml6ZShhYmJyZXZpYXRlX2VmZmVjdCkKCnN2X3BhdGggPC0gcGFyYW1zJHNvbWF0aWNfc3YKc3ZfdW5tZWx0ZWQgPC0gTlVMTApzdl9hbGwgPC0gTlVMTAoKc29tYXRpY19zdl90c3YgPC0gcmVhZHI6OnJlYWRfdHN2KHN2X3BhdGgsIGNvbF9uYW1lcyA9IFRSVUUsIGNvbF90eXBlcyA9ICJjY2NpaWNjY2NjaWNjY2NjZGNpaWNjIikKbm9fc3ZfZm91bmQgPSBsZW5ndGgocmVhZExpbmVzKGNvbiA9IHN2X3BhdGgsIG4gPSAyKSkgPCAyICAjIG9ubHkgaGVhZGVyIGluIHRoZSBmaWxlCgppZiAoIW5vX3N2X2ZvdW5kKSB7CiAgc3ZfdW5tZWx0ZWQgPC0gc29tYXRpY19zdl90c3YgJT4lCiAgICBkcGx5cjo6c2VsZWN0KC1jYWxsZXIsIC1zYW1wbGUpICU+JQogICAgc3BsaXRfc3ZfZmllbGQoQUZfQlBJKSAlPiUKICAgIHNwbGl0X3N2X2ZpZWxkKEFGX1BVUlBMRSkgJT4lCiAgICBzcGxpdF9zdl9maWVsZChDTl9QVVJQTEUpICU+JQogICAgc3BsaXRfc3ZfZmllbGQoQ05fY2hhbmdlX1BVUlBMRSkgJT4lCiAgICBkcGx5cjo6bXV0YXRlKAogICAgICBBRl9CUEkgPSBpZmVsc2UoaXMubmEoQUZfQlBJKSwgTkEsIHBhc3RlMChBRl9CUEksICIgKCIsIEFGX0JQSTEsICIsIiwgQUZfQlBJMiwgIikiKSksCiAgICAgIEFGX1BVUlBMRSA9IGlmZWxzZShpcy5uYShBRl9QVVJQTEUpLCBOQSwgcGFzdGUwKEFGX1BVUlBMRSwgIiAoIiwgQUZfUFVSUExFMSwgIiwgIiwgQUZfUFVSUExFMiwgIikiKSksCiAgICAgIENOX1BVUlBMRSA9IGlmZWxzZShpcy5uYShDTl9QVVJQTEUpLCBOQSwgcGFzdGUwKENOX1BVUlBMRSwgIiAoIiwgQ05fUFVSUExFMSwgIiwgIiwgQ05fUFVSUExFMiwgIikiKSksCiAgICAgIENOX2NoYW5nZV9QVVJQTEUgPSBpZmVsc2UoaXMubmEoQ05fY2hhbmdlX1BVUlBMRSksIE5BLCBwYXN0ZTAoQ05fY2hhbmdlX1BVUlBMRSwgIiAoIiwgQ05fY2hhbmdlX1BVUlBMRTEsICIsICIsIENOX2NoYW5nZV9QVVJQTEUyLCAiKSIpKQogICAgKSAlPiUKICAgIHRpZHlyOjpzZXBhcmF0ZShzcGxpdF9yZWFkX3N1cHBvcnQsIGMoIlNSX3JlZiIsICJTUl9hbHQiKSwgIiwiLCBjb252ZXJ0ID0gVFJVRSkgJT4lCiAgICB0aWR5cjo6c2VwYXJhdGUocGFpcmVkX3N1cHBvcnRfUFIsIGMoIlBSX3JlZiIsICJQUl9hbHQiKSwgIiwiLCBjb252ZXJ0ID0gVFJVRSkgJT4lCiAgICBkcGx5cjo6bXV0YXRlKAogICAgICBTUl9QUl9hbHQgPSBwYXN0ZTAoU1JfYWx0LCAiLCIsIFBSX2FsdCksCiAgICAgIFNSX1BSX3JlZiA9IHBhc3RlMChTUl9yZWYsICIsIiwgUFJfcmVmKSwKICAgICAgUGxvaWR5ID0gcm91bmQoYXMuZG91YmxlKFBsb2lkeV9QVVJQTEUpLCAyKSwKICAgICAgY2hyb20gPSBzdWIoImNociIsICIiLCBjaHJvbSksCiAgICAgIGNocm9tID0gYXMuZmFjdG9yKGNocm9tKSwgIyBmb3IgYmV0dGVyIERUIGZpbHRlcmluZwogICAgICBzdnR5cGUgPSBpZmVsc2UoaXMubmEoUFVSUExFX3N0YXR1cyksIHN2dHlwZSwgIlBVUlBMRV9pbmYiKSwKICAgICAgU3RhcnQgPSBpZmVsc2UoaXMubmEoUFVSUExFX3N0YXR1cyksIFNUQVJUX0JQSSwgc3RhcnQpLAogICAgICBuYW5uID0gY291bnRfcGllY2VzKGFubm90YXRpb24sICIsIiksCiAgICAgIHZhcm51bSA9IGRwbHlyOjpyb3dfbnVtYmVyKCksCiAgICAgIHZhcm51bSA9IHNwcmludGYoZ2x1ZTo6Z2x1ZSgiJTB7bmNoYXIobnJvdyguKSl9ZCIpLCB2YXJudW0pKQoKICAjIEZpeCBCTkQgSURzCiAgc3ZfdW5tZWx0ZWRfYm5kIDwtIHN2X3VubWVsdGVkICU+JQogICAgZHBseXI6OmZpbHRlcihzdnR5cGUgPT0gIkJORCIpICU+JQogICAgdGlkeXI6OnNlcGFyYXRlKElELCBpbnRvID0gYygiQk5EX2dyb3VwIiwgIkJORF9tYXRlIiksIHNlcCA9IC0xLCBjb252ZXJ0ID0gVFJVRSwgcmVtb3ZlID0gRkFMU0UpICU+JQogICAgZHBseXI6Omdyb3VwX2J5KEJORF9ncm91cCkgJT4lCiAgICBkcGx5cjo6bXV0YXRlKAogICAgICBCTkRfSUQgPSBkcGx5cjo6Z3JvdXBfaW5kaWNlcygpLAogICAgICBCTkRfSUQgPSBzcHJpbnRmKGdsdWU6OmdsdWUoIiUwe25jaGFyKG5yb3coLikpfWQiKSwgQk5EX0lEKSwKICAgICAgQk5EX21hdGUgPSBpZmVsc2UoQk5EX21hdGUgPT0gMCwgIkEiLCAiQiIpKSAlPiUKICAgIGRwbHlyOjp1bmdyb3VwKCkgJT4lCiAgICBkcGx5cjo6YmluZF9jb2xzKC4sIC5bbWF0Y2goLiRJRCwgLiRNQVRFSUQpLCAiY2hyb20iXSkgJT4lCiAgICBkcGx5cjo6cmVuYW1lKEJORF9tYXRlX2Nocm9tID0gY2hyb20xKQoKICBzdl91bm1lbHRlZF9vdGhlciA8LSBzdl91bm1lbHRlZCAlPiUKICAgIGRwbHlyOjpmaWx0ZXIoc3Z0eXBlICE9ICJCTkQiKQoKICBzdl91bm1lbHRlZCA8LQogICAgZHBseXI6OmJpbmRfcm93cyhzdl91bm1lbHRlZF9ibmQsCiAgICAgICAgICAgICAgICAgICAgIHN2X3VubWVsdGVkX290aGVyKSAlPiUKICAgIGRwbHlyOjptdXRhdGUoCiAgICAgIEVORF9CUEkgPSBiYXNlOjpmb3JtYXQoRU5EX0JQSSwgYmlnLm1hcmsgPSAiLCIsIHRyaW0gPSBUUlVFKSwKICAgICAgRW5kID0gaWZlbHNlKHN2dHlwZSA9PSAiQk5EIiwgcGFzdGUwKEJORF9tYXRlX2Nocm9tLCAiOiIsIEVORF9CUEkpLCBFTkRfQlBJKSkgJT4lCiAgICBkcGx5cjo6c2VsZWN0KHZhcm51bSwgVGllclRvcCA9IHRpZXIsCiAgICAgICAgICAgICAgICAgIENociA9IGNocm9tLCBTdGFydCwgRW5kLAogICAgICAgICAgICAgICAgICBUeXBlID0gc3Z0eXBlLAogICAgICAgICAgICAgICAgICBJRCwgTUFURUlELCBCTkRfSUQsIEJORF9tYXRlLAogICAgICAgICAgICAgICAgICBTUl9QUl9hbHQsIFNSX1BSX3JlZiwgUGxvaWR5LAogICAgICAgICAgICAgICAgICBBRl9QVVJQTEUsIEFGX0JQSSwKICAgICAgICAgICAgICAgICAgQ05DID0gQ05fY2hhbmdlX1BVUlBMRSwgQ04gPSBDTl9QVVJQTEUsCiAgICAgICAgICAgICAgICAgIFNTY29yZSA9IHNvbWF0aWNzY29yZSwgbmFubiwgYW5ub3RhdGlvbikKCiAgc3ZfYWxsIDwtIHN2X3VubWVsdGVkICU+JQogICAgZHBseXI6Om11dGF0ZShhbm5vdGF0aW9uID0gc3Ryc3BsaXQoYW5ub3RhdGlvbiwgJywnKSkgJT4lCiAgICB0aWR5cjo6dW5uZXN0KGFubm90YXRpb24pICU+JQogICAgdGlkeXI6OnNlcGFyYXRlKAogICAgICBhbm5vdGF0aW9uLCBjKCdFdmVudCcsICdFZmZlY3QnLCAnR2VuZXMnLCAnVHJhbnNjcmlwdCcsICdEZXRhaWwnLCAnVGllcicpLAogICAgICBzZXAgPSAnXFx8JywgY29udmVydCA9IEZBTFNFKSAlPiUKICAgIGRwbHlyOjptdXRhdGUoCiAgICAgIG50cnggPSBjb3VudF9waWVjZXMoVHJhbnNjcmlwdCwgIiYiKSwKICAgICAgbmdlbiA9IGNvdW50X3BpZWNlcyhHZW5lcywgIiYiKSwKICAgICAgbmVmZiA9IGNvdW50X3BpZWNlcyhFZmZlY3QsICImIiksCiAgICAgIFRyYW5zY3JpcHQgPSBUcmFuc2NyaXB0ICU+JSBzdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoJyYnLCAnLCAnKSwKICAgICAgR2VuZXMgPSBHZW5lcyAlPiUgc3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKCcmJywgJywgJyksCiAgICAgIEVmZmVjdCA9IGFiYnJldmlhdGVfZWZmZWN0dihFZmZlY3QpKSAlPiUKICAgIGRwbHlyOjpkaXN0aW5jdCgpICU+JQogICAgZHBseXI6OmFycmFuZ2UoVGllciwgR2VuZXMsIEVmZmVjdCkKfSBlbHNlIHsKICBzdl91bm1lbHRlZCA8LSB0aWJibGUoV0FSTklORyA9ICJUSEVSRSBXRVJFIDAgU1ZzIFBSSU9SSVRJU0VEISEiKQogIHN2X2FsbCA8LSB0aWJibGUoV0FSTklORyA9ICJUSEVSRSBXRVJFIDAgU1ZzIFBSSU9SSVRJU0VEISEiKQp9CmBgYAoKYGBge3IgcHVycGxlX3FjX3ByZXB9CiMtLS0tIFBVUlBMRSBRQyAtLS0tIwojIHJlYWQgYm90aCBkYXRhc2V0cwpxY19wYXRoIDwtIHBhcmFtcyRwdXJwbGVfcWMKcHVyaXR5X3BhdGggPC0gcGFyYW1zJHB1cnBsZV9wdXJpdHkKCnB1cnBsZV9xYyA8LQogIGZpbGUucGF0aChxY19wYXRoKSAlPiUKICByZWFkcjo6cmVhZF90c3YoY29sX25hbWVzID0gYygia2V5IiwgInZhbHVlIiksIGNvbF90eXBlcyA9ICJjYyIpICU+JQogIGRwbHlyOjptdXRhdGUodmFsdWUgPSB0b3VwcGVyKHZhbHVlKSkKIyB0dXJuIGludG8gbmFtZWQgdmVjdG9yCnB1cnBsZV9xYyA8LSBzdHJ1Y3R1cmUocHVycGxlX3FjJHZhbHVlLCBuYW1lcyA9IHB1cnBsZV9xYyRrZXkpCgpwdXJwbGVfcHVyaXR5IDwtCiAgZmlsZS5wYXRoKHB1cml0eV9wYXRoKSAlPiUKICByZWFkcjo6cmVhZF90c3YoY29sX3R5cGVzID0gY29scyguZGVmYXVsdCA9IGNvbF9kb3VibGUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5kZXIgPSBjb2xfY2hhcmFjdGVyKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzID0gY29sX2NoYXJhY3RlcigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdob2xlR2Vub21lRHVwbGljYXRpb24gPSBjb2xfY2hhcmFjdGVyKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXNTdGF0dXMgPSBjb2xfY2hhcmFjdGVyKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1sU3RhdHVzID0gY29sX2NoYXJhY3RlcigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRtYlN0YXR1cyA9IGNvbF9jaGFyYWN0ZXIoKQogICkpICU+JQogIGRwbHlyOjptdXRhdGVfaWYoaXMubnVtZXJpYywgcm91bmQsIDMpICU+JQogIHVubGlzdCgpCgojIHNhbml0eSBjaGVja3MgaW4gY2FzZSBzb21ldGhpbmcgY2hhbmdlcyBiZXR3ZWVuIHZlcnNpb25zIChQVVJQTEUgdjIuMzQgYXMgb2YgMjAxOS0wOS0yOSkKbm1zX3B1cnBsZV9xYyA8LSBjKCJRQ1N0YXR1cyIsICJTZWdtZW50UGFzcyIsICJHZW5kZXJQYXNzIiwgIkRlbGV0ZWRHZW5lc1Bhc3MiLAogICAgICAgICAgICAgICAgICAgIlNlZ21lbnRTY29yZSIsICJVbnN1cHBvcnRlZFNlZ21lbnRzIiwgIlBsb2lkeSIsCiAgICAgICAgICAgICAgICAgICAiQW1iZXJHZW5kZXIiLCAiQ29iYWx0R2VuZGVyIiwgIkRlbGV0ZWRHZW5lcyIpCgpubXNfcHVycGxlX3B1cml0eSA8LSBjKCJwdXJpdHkiLCAibm9ybUZhY3RvciIsICJzY29yZSIsICJkaXBsb2lkUHJvcG9ydGlvbiIsICJwbG9pZHkiLAogICAgICAgICAgICAgICAgICAgICAgICJnZW5kZXIiLCAic3RhdHVzIiwgInBvbHljbG9uYWxQcm9wb3J0aW9uIiwgIm1pblB1cml0eSIsICJtYXhQdXJpdHkiLAogICAgICAgICAgICAgICAgICAgICAgICJtaW5QbG9pZHkiLCAibWF4UGxvaWR5IiwgIm1pbkRpcGxvaWRQcm9wb3J0aW9uIiwgIm1heERpcGxvaWRQcm9wb3J0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAidmVyc2lvbiIsICJzb21hdGljUGVuYWx0eSIsICJ3aG9sZUdlbm9tZUR1cGxpY2F0aW9uIiwgIm1zSW5kZWxzUGVyTWIiLCAibXNTdGF0dXMiLAogICAgICAgICAgICAgICAgICAgICAgICJ0bWwiLCAidG1sU3RhdHVzIiwgInRtYlBlck1iIiwgInRtYlN0YXR1cyIpCgoKIyBmb3Igc2hvcnRlciByZWZlcmVuY2UgaW4gZ2x1ZQpwIDwtIHB1cnBsZV9wdXJpdHkKcSA8LSBwdXJwbGVfcWMKcHVycGxlX3FjX3N1bW1hcnkgPC0gZHBseXI6OnRyaWJibGUoCiAgflZhcmlhYmxlICAgICAgICAsIH52YWx1ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB+ZGV0YWlscywKICAnUUNfU3RhdHVzJyAgICAgICwgZ2x1ZSgne3FbIlFDU3RhdHVzIl19JykgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLCAiIiwKICAnUHVyaXR5JyAgICAgICAgICwgZ2x1ZSgne3BbInB1cml0eSJdfSAoe3BbIm1pblB1cml0eSJdfS17cFsibWF4UHVyaXR5Il19KScpLCAiUHVyaXR5IG9mIHR1bW9yIGluIHRoZSBzYW1wbGUgKGFuZCBtaW4tbWF4IHdpdGggc2NvcmUgd2l0aGluIDEwJSBvZiBiZXN0KSIsCiAgJ1Bsb2lkeScgICAgICAgICAsIGdsdWUoJ3twWyJwbG9pZHkiXX0gKHtwWyJtaW5QbG9pZHkiXX0te3BbIm1heFBsb2lkeSJdfSknKSwgIkF2ZXJhZ2UgcGxvaWR5IG9mIHR1bW9yIHNhbXBsZSBhZnRlciBhZGp1c3RpbmcgZm9yIHB1cml0eSAoYW5kIG1pbi1tYXggd2l0aCBzY29yZSB3aXRoaW4gMTAlIG9mIGJlc3QpIiwKICAnR2VuZGVyJyAgICAgICAgICwgZ2x1ZSgne3BbImdlbmRlciJdfScpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLCAiIiwKICAnV0dEJyAgICAgICAgICAgICwgZ2x1ZSgne3BbIndob2xlR2Vub21lRHVwbGljYXRpb24iXX0nKSAgICAgICAgICAgICAgICAgICAgLCAiV2hvbGUgZ2Vub21lIGR1cGxpY2F0aW9uIiwKICAnTVNJIChpbmRlbHMvTWIpJywgZ2x1ZSgne3BbIm1zU3RhdHVzIl19ICh7cFsibXNJbmRlbHNQZXJNYiJdfSknKSAgICAgICAgICAgLCAiTVNJIHN0YXR1cyAoTVNJLCBNU1Mgb3IgVU5LTk9XTiBpZiBzb21hdGljIHZhcmlhbnRzIG5vdCBzdXBwbGllZCkgJiBNUyBJbmRlbHMgcGVyIE1iIiwKICAnUG9seWNsb25hbCBQcm9wJywgZ2x1ZSgne3BbInBvbHljbG9uYWxQcm9wb3J0aW9uIl19JykgICAgICAgICAgICAgICAgICAgICAgLCAiUHJvcG9ydGlvbiBvZiBDTiByZWdpb25zIHRoYXQgYXJlIG1vcmUgdGhhbiAwLjI1IGZyb20gYSB3aG9sZSBjb3B5IG51bWJlciIsCiAgJ0RpcGxvaWR5IFByb3AnICAsIGdsdWUoJ3twWyJkaXBsb2lkUHJvcG9ydGlvbiJdfSAoe3BbIm1pbkRpcGxvaWRQcm9wb3J0aW9uIl19LXtwWyJtYXhEaXBsb2lkUHJvcG9ydGlvbiJdfSknKSwgZ2x1ZSgnUHJvcG9ydGlvbiBvZiBDTiByZWdpb25zIHRoYXQgaGF2ZSAxICgrLSAwLjIpIG1pbm9yIGFuZCBtYWpvciBhbGxlbGUnKSwKICAnU2VnbWVudF9QYXNzJyAgICwgZ2x1ZSgne3FbIlNlZ21lbnRQYXNzIl19JykgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLCBnbHVlKCdTY29yZToge3FbIlNlZ21lbnRTY29yZSJdfTsgVW5zdXBwb3J0ZWQ6IHtxWyJVbnN1cHBvcnRlZFNlZ21lbnRzIl19JyksCiAgJ0dlbmRlcl9QYXNzJyAgICAsIGdsdWUoJ3txWyJHZW5kZXJQYXNzIl19JykgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICwgZ2x1ZSgnQW1iZXI6IHtxWyJBbWJlckdlbmRlciJdfTsgQ29iYWx0OiB7cVsiQ29iYWx0R2VuZGVyIl19JyksCiAgJ0RlbEdlbmVzX1Bhc3MnICAsIGdsdWUoJ3txWyJEZWxldGVkR2VuZXNQYXNzIl19JykgICAgICAgICAgICAgICAgICAgICAgICAgICwgZ2x1ZSgnY291bnQ6IHtxWyJEZWxldGVkR2VuZXMiXX0nKSwKICAnVE1CJyAgICAgICAgICAgICwgZ2x1ZSgne3BbInRtYlBlck1iIl19ICh7cFsidG1iU3RhdHVzIl19KScpICAgICAgICAgICAgICAgLCAiVHVtb3IgbXV0YXRpb25hbCBidXJkZW4gcGVyIG1lZ2EgYmFzZSAoU3RhdHVzOiAnSElHSCcsICdMT1cnIG9yICdVTktOT1dOJyBpZiBzb21hdGljIHZhcmlhbnRzIG5vdCBzdXBwbGllZCkiLAogICdUTUwnICAgICAgICAgICAgLCBnbHVlKCd7cFsidG1sIl19ICh7cFsidG1sU3RhdHVzIl19KScpICAgICAgICAgICAgICAgICAgICAsICJUdW1vciBtdXRhdGlvbmFsIGxvYWQgKFN0YXR1czogJ0hJR0gnLCAnTE9XJyBvciAnVU5LTk9XTicgaWYgc29tYXRpYyB2YXJpYW50cyBub3Qgc3VwcGxpZWQpIgopCmBgYAoKYGBge3IgcHVycGxlX2dlbmVfY252X3ByZXB9CiMtLS0tIFBVUlBMRSBHZW5lIENOViBUYWJsZSAtLS0tIwprZXlfZ2VuZXMgPC0KICByZWFkcjo6cmVhZF90c3YocGFyYW1zJGtleV9nZW5lcywgY29sX3R5cGVzID0gY29scyhvbmNvZ2VuZSA9ICJsIiwgdHVtb3JzdXBwcmVzc29yID0gImwiKSkgJT4lCiAgZHBseXI6OnNlbGVjdChzeW1ib2wsIG9uY29nZW5lLCB0dW1vcnN1cHByZXNzb3IpCgpvbmNvZ2VuZXMgPC0ga2V5X2dlbmVzICU+JSBkcGx5cjo6ZmlsdGVyKG9uY29nZW5lKSAlPiUgZHBseXI6OnB1bGwoc3ltYm9sKQp0c2dlbmVzIDwtIGtleV9nZW5lcyAlPiUgZHBseXI6OmZpbHRlcih0dW1vcnN1cHByZXNzb3IpICU+JSBkcGx5cjo6cHVsbChzeW1ib2wpCgpwdXJwbGVfZ2VuZV9jbnYgPC0gcmVhZHI6OnJlYWRfdHN2KHBhcmFtcyRwdXJwbGVfZ2VuZV9jbnYsIGNvbF90eXBlcyA9ICJjaWljZGRjZGRkY2NjZGlpY2NjZCIpCgojIHNhbml0eSBjaGVja3MgaW4gY2FzZSBzb21ldGhpbmcgY2hhbmdlcyBiZXR3ZWVuIHZlcnNpb25zIChQVVJQTEUgdjIuMzQgYXMgb2YgMjAxOS0wOS0yOSkKbm1zX2dlbmVfY252IDwtIGMoImNocm9tb3NvbWUiLCAic3RhcnQiLCAiZW5kIiwgImdlbmUiLCAibWluQ29weU51bWJlciIsICJtYXhDb3B5TnVtYmVyIiwKICAgICAgICAgICAgICAgICAgInVudXNlZCIsICJzb21hdGljUmVnaW9ucyIsICJnZXJtbGluZUhvbURlbGV0aW9uUmVnaW9ucyIsICJnZXJtbGluZUhldFRvSG9tRGVsZXRpb25SZWdpb25zIiwKICAgICAgICAgICAgICAgICAgInRyYW5zY3JpcHRJZCIsICJ0cmFuc2NyaXB0VmVyc2lvbiIsICJjaHJvbW9zb21lQmFuZCIsICJtaW5SZWdpb25zIiwKICAgICAgICAgICAgICAgICAgIm1pblJlZ2lvblN0YXJ0IiwgIm1pblJlZ2lvbkVuZCIsICJtaW5SZWdpb25TdGFydFN1cHBvcnQiLCAibWluUmVnaW9uRW5kU3VwcG9ydCIsCiAgICAgICAgICAgICAgICAgICJtaW5SZWdpb25NZXRob2QiLCAibWluTWlub3JBbGxlbGVQbG9pZHkiKQpzdG9waWZub3QoYWxsKGNvbG5hbWVzKHB1cnBsZV9nZW5lX2NudikgPT0gbm1zX2dlbmVfY252KSkKCnB1cnBsZV9nZW5lX2NudiA8LSBwdXJwbGVfZ2VuZV9jbnYgJT4lCiAgZHBseXI6OmZpbHRlcihnZW5lICVpbiUga2V5X2dlbmVzJHN5bWJvbCkgJT4lCiAgZHBseXI6Om11dGF0ZShjaHJvbW9zb21lID0gYXMuZmFjdG9yKGNocm9tb3NvbWUpLAogICAgICAgICAgICAgICAgdHJhbnNjcmlwdElEID0gcGFzdGUwKHRyYW5zY3JpcHRJZCwgIi4iLCB0cmFuc2NyaXB0VmVyc2lvbiksCiAgICAgICAgICAgICAgICBtaW5SZWdTdGFydEVuZCA9IHBhc3RlMChtaW5SZWdpb25TdGFydCwgIi0iLCBtaW5SZWdpb25FbmQpLAogICAgICAgICAgICAgICAgbWluUmVnU3VwcG9ydFN0YXJ0RW5kTWV0aG9kID0gcGFzdGUwKG1pblJlZ2lvblN0YXJ0U3VwcG9ydCwgIi0iLCBtaW5SZWdpb25FbmRTdXBwb3J0LCAiICgiLCBtaW5SZWdpb25NZXRob2QsICIpIiksCiAgICAgICAgICAgICAgICBnZXJtRGVsUmVnID0gcGFzdGUwKGdlcm1saW5lSG9tRGVsZXRpb25SZWdpb25zLCAiLyIsIGdlcm1saW5lSGV0VG9Ib21EZWxldGlvblJlZ2lvbnMpLAogICAgICAgICAgICAgICAgb25jb2dlbmUgPSBnZW5lICVpbiUgb25jb2dlbmVzLAogICAgICAgICAgICAgICAgdHNnZW5lID0gZ2VuZSAlaW4lIHRzZ2VuZXMsCiAgICAgICAgICAgICAgICBvbmNvX29yX3RzID0gZHBseXI6OmNhc2Vfd2hlbigKICAgICAgICAgICAgICAgICAgb25jb2dlbmUgJiB0c2dlbmUgfiAib25jbyt0cyIsCiAgICAgICAgICAgICAgICAgIG9uY29nZW5lIH4gIm9uY29nZW5lIiwKICAgICAgICAgICAgICAgICAgdHNnZW5lIH4gInRzZ2VuZSIsCiAgICAgICAgICAgICAgICAgIFRSVUUgfiAiIikpICU+JQogIGRwbHlyOjpzZWxlY3QoZ2VuZSwgbWluQ04gPSBtaW5Db3B5TnVtYmVyLCBtYXhDTiA9IG1heENvcHlOdW1iZXIsCiAgICAgICAgICAgICAgICBjaHJvbSA9IGNocm9tb3NvbWUsIHN0YXJ0LCBlbmQsCiAgICAgICAgICAgICAgICBjaHJCYW5kID0gY2hyb21vc29tZUJhbmQsIG9uY29fb3JfdHMsIHRyYW5zY3JpcHRJRCwgbWluTWlub3JBbGxlbGVQbG9pZHksCiAgICAgICAgICAgICAgICBzb21SZWcgPSBzb21hdGljUmVnaW9ucywgZ2VybURlbFJlZywgbWluUmVnID0gbWluUmVnaW9ucywKICAgICAgICAgICAgICAgIG1pblJlZ1N0YXJ0RW5kLCBtaW5SZWdTdXBwb3J0U3RhcnRFbmRNZXRob2QpCmBgYAoKYGBge3IgcHVycGxlX2dsb2JhbF9jbnZfcHJlcH0KIy0tLS0gUFVSUExFIEdsb2JhbCBDTlYgVGFibGUgLS0tLSMKcHVycGxlX2dsb2JhbF9jbnYgPC0gZmlsZS5wYXRoKHBhcmFtcyRwdXJwbGVfY252KSAlPiUKICByZWFkcjo6cmVhZF90c3YoY29sX3R5cGVzID0gImNpaWRpZGRjY2NkZGRkZGQiKQoKbm1zX3B1cnBsZV9jbnYgPC0gYygiY2hyb21vc29tZSIsICJzdGFydCIsICJlbmQiLCAiY29weU51bWJlciIsICJiYWZDb3VudCIsICJvYnNlcnZlZEJBRiIsCiAgICAgICAgICAgICAgICAgICAgImJhZiIsICJzZWdtZW50U3RhcnRTdXBwb3J0IiwgInNlZ21lbnRFbmRTdXBwb3J0IiwgIm1ldGhvZCIsCiAgICAgICAgICAgICAgICAgICAgImRlcHRoV2luZG93Q291bnQiLCAiZ2NDb250ZW50IiwgIm1pblN0YXJ0IiwgIm1heFN0YXJ0IiwgIm1pbm9yQWxsZWxlUGxvaWR5IiwKICAgICAgICAgICAgICAgICAgICAibWFqb3JBbGxlbGVQbG9pZHkiKQoKIyBzYW5pdHkgY2hlY2tzIGluIGNhc2Ugc29tZXRoaW5nIGNoYW5nZXMgYmV0d2VlbiB2ZXJzaW9ucyAoUFVSUExFIHYyLjM0IGFzIG9mIDIwMTktMDktMjkpCnN0b3BpZm5vdChhbGwobmFtZXMocHVycGxlX2dsb2JhbF9jbnYpID09IG5tc19wdXJwbGVfY252KSkKYGBgCgojIyBTdW1tYXJ5CgpgYGB7ciBzdW1tYXJ5X3RhYmxlc30Kc3VtbWFyaXNlX3NpZ3MgPC0gZnVuY3Rpb24obXV0X3NpZ19jb250cikgewogIG11dF9zaWdfY29udHIgJT4lCiAgICBoZWFkKDIpICU+JQogICAgZHBseXI6Om11dGF0ZShzdHJpbmcgPSBwYXN0ZTAoU2lnbmF0dXJlLCAiICgiLCBDb250cmlidXRpb24sICIpIikpICU+JQogICAgZHBseXI6OnB1bGwoc3RyaW5nKSAlPiUKICAgIHBhc3RlKGNvbGxhcHNlID0gIiwgIikKfQoKYWZfc3VtbWFyeSA8LSBhZl9zdGF0cyAlPiUKICBrbml0cjo6a2FibGUoZm9ybWF0ID0gImh0bWwiLCBjYXB0aW9uID0gIkFGIFN1bW1hcnkgU3RhdHMiKSAlPiUKICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBGQUxTRSwgcG9zaXRpb24gPSAibGVmdCIpICU+JQogIGthYmxlRXh0cmE6OmNvbHVtbl9zcGVjKDEsIGJvbGQgPSBUUlVFKQoKY252X3N1bW1hcnkgPC0gcHVycGxlX2dsb2JhbF9jbnYgJT4lCiAgZHBseXI6OnJlbmFtZShjbiA9IGNvcHlOdW1iZXIpICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoTWluID0gcm91bmQobWluKGNuKSwgMiksCiAgICAgICAgICAgICAgICAgICBNYXggPSByb3VuZChtYXgoY24pLCAyKSwKICAgICAgICAgICAgICAgICAgIE4gPSBuKCkpICU+JSB1bmxpc3QoKQoKaWYgKG5vX3N2X2ZvdW5kKSB7CiAgc3Zfc3VtbWFyeSA8LSB0aWJibGUodW5tZWx0ZWQgPSBjKDApLCBtZWx0ZWQgPSBjKDApKQp9IGVsc2UgewogIHN2X3N1bW1hcnkgPC0KICAgIGxpc3QodW5tZWx0ZWQgPSBzdl91bm1lbHRlZCAlPiUgZHBseXI6OnNlbGVjdChUeXBlKSwKICAgICAgICAgbWVsdGVkID0gc3ZfYWxsICU+JSBkcGx5cjo6c2VsZWN0KFR5cGUpKSAlPiUKICAgIHB1cnJyOjptYXAoZnVuY3Rpb24oeCkgYWRkbWFyZ2lucyh0YWJsZSh4LCB1c2VOQSA9ICdpZmFueScpKSkgJT4lCiAgICBkby5jYWxsKCJyYmluZCIsIC4pICU+JQogICAgYXMuZGF0YS5mcmFtZSgpICU+JQogICAgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4odmFyID0gImdyb3VwIikgJT4lCiAgICB0aWR5cjo6cGl2b3RfbG9uZ2VyKC1ncm91cCkgJT4lCiAgICBkcGx5cjo6bXV0YXRlKHZhbHVlID0gcGFzdGUwKG5hbWUsICI6ICIsIHZhbHVlKSkgJT4lCiAgICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IGdyb3VwLCB2YWx1ZXNfZnJvbSA9IHZhbHVlKSAlPiUKICAgIGRwbHlyOjpzZWxlY3QodW5tZWx0ZWQsIG1lbHRlZCkKfQoKcWNfc3VtbWFyeV9hbGwgPC0gcHVycGxlX3FjX3N1bW1hcnkgJT4lCiAgZHBseXI6OmZpbHRlcihWYXJpYWJsZSAlaW4lIGMoIlFDX1N0YXR1cyIsICJHZW5kZXIiLCAiUHVyaXR5IiwgIlBsb2lkeSIpKSAlPiUKICBkcGx5cjo6c2VsZWN0KFZhcmlhYmxlLCB2YWx1ZSkgJT4lCiAgZHBseXI6OmJpbmRfcm93cygKICAgIGRwbHlyOjp0cmliYmxlKAogICAgICB+VmFyaWFibGUsIH52YWx1ZSwKICAgICAgIlRvcCBNdXRTaWdzIiwgZ2x1ZTo6Z2x1ZSgie2h0bWx0b29sczo6c3Ryb25nKCdPbGQ6Jyl9IHtzdW1tYXJpc2Vfc2lncyhtdXRfc2lnX2NvbnRyKX0gIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLSB7aHRtbHRvb2xzOjpzdHJvbmcoJ05ldzonKX0ge3N1bW1hcmlzZV9zaWdzKG11dF9zaWdfY29udHIyKX0iKSwKICAgICAgIkNOVnMgKFNvbWF0aWMpIiwgZ2x1ZTo6Z2x1ZSgie2h0bWx0b29sczo6c3Ryb25nKCdNaW46ICcpfXtjbnZfc3VtbWFyeVsnTWluJ119OyAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ7aHRtbHRvb2xzOjpzdHJvbmcoJ01heDogJyl9e2Nudl9zdW1tYXJ5WydNYXgnXX07ICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIntodG1sdG9vbHM6OnN0cm9uZygnTjogJyl9e2Nudl9zdW1tYXJ5WydOJ119ICIpLAogICAgICAiU1ZzICh1bm1lbHRlZCkiLCBwYXN0ZShyZXYoc3Zfc3VtbWFyeSR1bm1lbHRlZCksIGNvbGxhcHNlID0gIiwgIiksCiAgICAgICJTVnMgKG1lbHRlZCkiLCBwYXN0ZShyZXYoc3Zfc3VtbWFyeSRtZWx0ZWQpLCBjb2xsYXBzZSA9ICIsICIpLAogICAgICAiR2Vub21lIiwgcGFyYW1zJGdlbm9tZV9idWlsZAogICAgKQogICkgJT4lCiAgZHBseXI6Om11dGF0ZShWYXJpYWJsZSA9IGthYmxlRXh0cmE6OmNlbGxfc3BlYyhWYXJpYWJsZSwgYm9sZCA9IFRSVUUpKSAlPiUKICBrbml0cjo6a2FibGUoZXNjYXBlID0gRkFMU0UsIGNvbC5uYW1lcyA9IE5VTEwpICU+JQogIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFLCBwb3NpdGlvbiA9ICJsZWZ0IikKCnFjX3N1bW1hcnlfYWxsCmFmX3N1bW1hcnkKYGBgCgojIyBTb21hdGljIE11dGF0aW9uIFByb2ZpbGVzCgojIyMgQWxsZWxpYyBGcmVxdWVuY2llcyB7I2FsbGVsaWMtZnJlcXN9ClN1bW1hcmlzZWQgYmVsb3cgYXJlIHRoZSBhbGxlbGUgZnJlcXVlbmNpZXMgKEFGcykgZm9yIHNvbWF0aWMgdmFyaWFudHMgZGV0ZWN0ZWQKZ2Vub21lLXdpZGUgKF9fR2xvYmFsX18pIHZzLiB3aXRoaW4gdGhlIGNvZGluZyBzZXF1ZW5jZSBvZiB+MSwxMDAgVU1DQ1IKY2FuY2VyIGdlbmVzIChfX0tleSBHZW5lcyBDRFNfXykuCkFGcyByYW5nZSBmcm9tIDAgdG8gMSwgb3IgMCUtMTAwJSAod2UgZmlsdGVyIG91dCBhbGwgbm92ZWwgdmFyaWFudHMgd2l0aCBBRiA8IDEwJSkuCgo8ZGV0YWlscz4KPHN1bW1hcnk+RGV0YWlsczwvc3VtbWFyeT4KClZhcmlhbnRzIGFyZSB0eXBpY2FsbHkgY2FsbGVkIGluIGJjYmlvIGJ5IDMgZGlmZmVyZW50IGNhbGxlcnMsIHdpdGggY2FsbHMgc3VwcG9ydGVkIGJ5IGF0IGxlYXN0IDIgb2YgdGhlbSB1c2VkICgiZW5zZW1ibGUiIGFwcHJvYWNoKS4KSW4gc29tZSBjYXNlcyBvbmx5IGEgc2luZ2xlIGNhbGxlciBpcyB1c2VkIGR1ZSB0byB0ZWNobmljYWwgcmVhc29ucyAoZS5nLiBoaWdobHkgbXV0YXRlZCBGRlBFIHNhbXBsZSkuCgpUaGUgZm9sbG93aW5nIHBvc3QtcHJvY2Vzc2luZyBzdGVwcyBvY2N1cjoKCjEuIGBzb21hdGljX3ZjZl9hbm5vdGF0ZWA6IFthbm5vdGF0ZSBWQ0ZdKGh0dHBzOi8vZ2l0aHViLmNvbS91bWNjci92Y2Zfc3R1ZmYvYmxvYi9tYXN0ZXIvdmNmX3N0dWZmL2ZpbHRlcmluZy9hbm5vdGF0ZV9zb21hdGljX3ZjZi5zbWspCiAgICBhZ2FpbnN0IGRhdGFiYXNlcyBvZiBrbm93biBob3RzcG90cywgZ2VybWxpbmUgdmFyaWFudHMsIGxvdyBtYXBwYWJpbGl0eSByZWdpb25zLCBVTUNDUiBwYW5lbCBvZiBub3JtYWxzCjIuIGBzb21hdGljX3ZjZl9maWx0ZXJgOiBbZmlsdGVyIFZDRl0oaHR0cHM6Ly9naXRodWIuY29tL3VtY2NyL3ZjZl9zdHVmZi9ibG9iL21hc3Rlci9zY3JpcHRzL2ZpbHRlcl9zb21hdGljX3ZjZikKICAgIHRvIHJlbW92ZSBnZXJtbGluZSB2YXJpYW50cyBhbmQgYXJ0ZWZhY3RzLCBidXQga2VlcCBrbm93biBob3RzcG90cwozLiBBcyBwcmVwYXJhdGlvbiBmb3IgdGhlIGFsbGVsaWMgZnJlcXVlbmNpZXMgcGxvdHM6CiAgICAqIGBzdWJzZXRfdG9fZ2lhYmA6IGtlZXAgdmFyaWFudHMgaW4gJ2hpZ2ggY29uZmlkZW5jZScgcmVnaW9ucyBhcyBkZXRlcm1pbmVkIGJ5IHRoZSBbR2Vub21lIGluIGEgQm90dGxlIGNvbnNvcnRpdW1dKGh0dHA6Ly9qaW1iLnN0YW5mb3JkLmVkdS9naWFiLykKICAgICoga2VlcCBvbmx5IHZhcmlhbnRzIHdpdGggQUYgYWJvdmUgMTAlCjQuIEFsbGVsZSBmcmVxdWVuY2llcyBmb3IgZ2xvYmFsIGFuZCBrZXlnZW5lczoKICAgICogYGFmc2A6IGdyYWIgb25seSB0aGUgYElORk8vVFVNT1JfQUZgIGZpZWxkIGFuZCBvdXRwdXQgdG8gZmluYWwgdHh0IGZpbGUKICAgICogYGFmc19rZXlnZW5lc2A6IGdyYWIgdGhlIGBDSFJPTWAsIGBQT1NgLCBgSURgLCBgUkVGYCwgYEFMVGAgYW5kIGBJTkZPL1RVTU9SX0FGYAogICAgICBmb3IgdmFyaWFudHMgaW4gdGhlIFVNQ0NSIGNhbmNlciBnZW5lIEJFRCBmaWxlLCBhbmQgb3V0cHV0IHRvIGZpbmFsIHR4dCBmaWxlCjwvZGV0YWlscz4KCgpgYGB7ciBhbGxlbGVfZnJlcV9wbG90X3N0YXRzLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9M30KZ2dwbG90KGRhdGEgPSBhZl9ib3RoLCBhZXMoYWYpKSArCiAgZ2VvbV9oaXN0b2dyYW0oc3RhdCA9ICdiaW4nLCBiaW53aWR0aCA9IDAuMDEsIGZpbGwgPSAiIzAwNjQwMCIpICsKICBmYWNldF93cmFwKH5zZXQsIHNjYWxlcyA9ICdmcmVlX3knLCBkcm9wID0gRkFMU0UpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJBbGxlbGUgRnJlcXVlbmN5IiwKICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gc2VxKDAsIDEsIGJ5ID0gMC4xKSwKICAgICAgICAgICAgICAgICAgICAgbGltaXRzID0gYygwLCAxKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIHZqdXN0ID0gMSwgaGp1c3QgPSAxKSwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKSArCiAgbGFicyh0aXRsZSA9IHBhc3RlKCJBRiBjb3VudCBkaXN0cmlidXRpb24iKSkKYGBgCgojIyMgTXV0YXRpb25hbCBTaWduYXR1cmVzIHsudGFic2V0IC50YWJzZXQtZmFkZSAjc2lnbmF0dXJlc30KCkRlY2lwaGVyaW5nIHRoZSBtdXRhdGlvbmFsIHNpZ25hdHVyZSBvZiBhIHR1bW9yIHNhbXBsZSBjYW4gcHJvdmlkZSBpbnNpZ2h0IGludG8gdGhlIG11dGF0aW9uYWwKcHJvY2Vzc2VzIGludm9sdmVkIGluIGNhcmNpbm9nZW5lc2lzIGFuZCBoZWxwIGluIGNhbmNlciB0cmVhdG1lbnQgYW5kIHByZXZlbnRpb24uClRoZSBbTXV0YXRpb25hbFBhdHRlcm5zXShodHRwOi8vYmlvY29uZHVjdG9yLm9yZy9wYWNrYWdlcy9yZWxlYXNlL2Jpb2MvaHRtbC9NdXRhdGlvbmFsUGF0dGVybnMuaHRtbCkKUiBwYWNrYWdlIGlzIHVzZWQgdG8gZ2VuZXJhdGUgYSBtdXRhdGlvbiBzaWduYXR1cmUgZm9yIHRoZSBzYW1wbGUuIFdlIHVzZSB0aGUgZmluYWwgZmlsdGVyZWQgc29tYXRpYwpjYWxscyBhcyBpbnB1dC4KCiMjIyMgQ29udGV4dCBzaWduYXR1cmUKCmBgYHtyIHBsb3RfOTZfcHJvZiwgZmlnLmhlaWdodD0zfQpNdXRhdGlvbmFsUGF0dGVybnM6OnBsb3RfOTZfcHJvZmlsZShtdXRfbWF0LCBjb25kZW5zZWQgPSBUUlVFKQpgYGAKCiMjIyMgUG9pbnQgbXV0YXRpb24gc3BlY3RydW0KCjxkZXRhaWxzPgo8c3VtbWFyeT5EZXNjcmlwdGlvbjwvc3VtbWFyeT4KCldlIGNhbiBjb3VudCB0aGUgbXV0YXRpb24gdHlwZSBvY2N1cnJlbmNlcyBmb3IgdGhlIGlucHV0IFZDRi4KRm9yIGBDPlRgIG11dGF0aW9ucywgYSBkaXN0aW5jdGlvbiBpcyBtYWRlIGJldHdlZW4gYEM+VGAgYXQgQ3BHIHNpdGVzCmFuZCBvdGhlciBzaXRlcywgYXMgZGVhbWluYXRpb24gb2YgbWV0aHlsYXRlZCBjeXRvc2luZSBhdCBDcEcgc2l0ZXMgaXMgYSBjb21tb24gbXV0YXRpb25hbApwcm9jZXNzLiBUaGlzIGlzIHRoZSByZWFzb24gdGhlIHJlZmVyZW5jZSBnZW5vbWUgaXMgbmVlZGVkLgoKQSBtdXRhdGlvbiBzcGVjdHJ1bSBzaG93cyB0aGUgcmVsYXRpdmUgY29udHJpYnV0aW9uIG9mIGVhY2ggbXV0YXRpb24gdHlwZSBpbiB0aGUgYmFzZQpzdWJzdGl0dXRpb24gY2F0YWxvZ3MuIFdlIGNhbiBwbG90IHRoZSBtZWFuIHJlbGF0aXZlIGNvbnRyaWJ1dGlvbiBvZgplYWNoIG9mIHRoZSA2IGJhc2Ugc3Vic3RpdHV0aW9uIHR5cGVzIG92ZXIgYWxsIHNhbXBsZXMuIEVycm9yIGJhcnMgaW5kaWNhdGUgc3RhbmRhcmQgZGV2aWF0aW9uCm92ZXIgYWxsIHNhbXBsZXMuIFRoZSB0b3RhbCBudW1iZXIgb2YgbXV0YXRpb25zIGlzIGluZGljYXRlZC4gV2UgY2FuIGFsc28gZGlzdGluZ3Vpc2gKYmV0d2VlbiBgQz5UYCBhdCBDcEcgc2l0ZXMgYW5kIG90aGVyIHNpdGVzLgoKPC9kZXRhaWxzPgoKYGBge3IgcGxvdF9tdXRfdHlwZV9vY2N1cnJlbmNlcywgZmlnLmhlaWdodD0zfQp0eXBlX29jY3VycmVuY2VzIDwtIG11dF90eXBlX29jY3VycmVuY2VzKHZjZl9saXN0ID0gc29tYXRpY19zbnYsIHJlZl9nZW5vbWUgPSByZWZfZ2Vub21lKQpwbG90X3NwZWN0cnVtKHR5cGVfb2NjdXJyZW5jZXMsIENUID0gVFJVRSkKYGBgCgojIyMjIFRyYW5zY3JpcHRpb25hbCBzdHJhbmQgYmlhcwoKPGRldGFpbHM+CjxzdW1tYXJ5PkRlc2NyaXB0aW9uPC9zdW1tYXJ5PgoKV2UgY2FuIGRldGVybWluZSBpZiBhIGdlbmUgbXV0YXRpb24gaXMgb24gdGhlIHRyYW5zY3JpYmVkIG9yIG5vbi10cmFuc2NyaWJlZApzdHJhbmQsIHdoaWNoIGNhbiBiZSB1c2VkIHRvIGV2YWx1YXRlIHRoZSBpbnZvbHZlbWVudCBvZiB0cmFuc2NyaXB0aW9uLWNvdXBsZWQKcmVwYWlyLiBCeSBjb252ZW50aW9uIGJhc2Ugc3Vic3RpdHV0aW9ucyBhcmUgcmVnYXJkZWQgYXMgQz5YIG9yIFQ+WCwgc28gd2UgdHJ5CnRvIGRldGVybWluZSB3aGV0aGVyIHRoZSBDIG9yIFQgYmFzZSBpcyBvbiB0aGUgc2FtZSBzdHJhbmQgYXMgdGhlIGdlbmUKZGVmaW5pdGlvbi4gQmFzZSBzdWJzdGl0dXRpb25zIG9uIHRoZSBzYW1lIHN0cmFuZCBhcyB0aGUgZ2VuZSBkZWZpbml0aW9uIGFyZQpjb25zaWRlcmVkICd1bnRyYW5zY3JpYmVkJywgYW5kIG9uIHRoZSBvcHBvc2l0ZSBzdHJhbmQgJ3RyYW5zY3JpYmVkJywgc2luY2UgdGhlCmdlbmUgZGVmaW5pdGlvbnMgcmVwb3J0IHRoZSBjb2Rpbmcgb3Igc2Vuc2Ugc3RyYW5kLCB3aGljaCBpcyB1bnRyYW5zY3JpYmVkLiBObwpzdHJhbmQgaW5mb3JtYXRpb24gaXMgcmVwb3J0ZWQgZm9yIGJhc2Ugc3Vic3RpdHV0aW9ucyB0aGF0IG92ZXJsYXAgd2l0aCBtb3JlCnRoYW4gb25lIGdlbmUgb24gZGlmZmVyZW50IHN0cmFuZHMuCgo8L2RldGFpbHM+CgpgYGB7ciB0cmFuX3N0cmFuZF9iaWFzLCBmaWcuaGVpZ2h0PTN9CiMgR2V0IGtub3duIGdlbmVzIHRhYmxlIGZyb20gVUNTQwppZiAocGFyYW1zJGdlbm9tZV9idWlsZCA9PSAnaGcxOScpIHsKICBnZW5lc19saXN0IDwtIGdlbmVzKFR4RGIuSHNhcGllbnMuVUNTQy5oZzE5Lmtub3duR2VuZSkKfSBlbHNlIHsKICBnZW5lc19saXN0IDwtIGdlbmVzKFR4RGIuSHNhcGllbnMuVUNTQy5oZzM4Lmtub3duR2VuZSkKfQoKIyBNdXRhdGlvbiBjb3VudCBtYXRyaXggd2l0aCBzdHJhbmQgaW5mbyAoNCo2KjQ9OTYgLT4gOTYqMj0xOTIpCm11dF9tYXRfcyA8LSBNdXRhdGlvbmFsUGF0dGVybnM6Om11dF9tYXRyaXhfc3RyYW5kZWQoc29tYXRpY19zbnYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmX2dlbm9tZSA9IHJlZl9nZW5vbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2VzID0gZ2VuZXNfbGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RlID0gInRyYW5zY3JpcHRpb24iKQoKIyBNdXRhdGlvbiBjb3VudCBwZXIgdHlwZSBhbmQgc3RyYW5kCnN0cmFuZF9jb3VudHMgPC0gTXV0YXRpb25hbFBhdHRlcm5zOjpzdHJhbmRfb2NjdXJyZW5jZXMobXV0X21hdF9zLCBieSA9ICJhbGwiKQojIFBvaXNzb24gdGVzdCBmb3Igc3RyYW5kIGFzeW1tZXRyeSBzaWduaWZpY2FuY2UgdGVzdGluZwpzdHJhbmRfYmlhcyA8LSBNdXRhdGlvbmFsUGF0dGVybnM6OnN0cmFuZF9iaWFzX3Rlc3Qoc3RyYW5kX2NvdW50cykKCiMgbXV0YXRpb24gc3BlY3RydW0gd2l0aCBzdHJhbmQgZGlzdGluY3Rpb24KTXV0YXRpb25hbFBhdHRlcm5zOjpwbG90X3N0cmFuZChzdHJhbmRfY291bnRzLCBtb2RlID0gInJlbGF0aXZlIikKIyBlZmZlY3Qgc2l6ZSBvZiBzdHJhbmQgYmlhcwpNdXRhdGlvbmFsUGF0dGVybnM6OnBsb3Rfc3RyYW5kX2JpYXMoc3RyYW5kX2JpYXMpCmBgYAoKIyMjIyBSZXBsaWNhdGl2ZSBzdHJhbmQgYmlhcwoKPGRldGFpbHM+CjxzdW1tYXJ5PkRlc2NyaXB0aW9uPC9zdW1tYXJ5PgoKVGhlIGludm9sdmVtZW50IG9mIHJlcGxpY2F0aW9uLWFzc29jaWF0ZWQgbWVjaGFuaXNtcyBjYW4gYmUgZXZhbHVhdGVkIGJ5CnRlc3RpbmcgZm9yIGEgbXV0YXRpb25hbCBiaWFzIGJldHdlZW4gdGhlIGxlYWRpbmcgYW5kIGxhZ2dpbmcgc3RyYW5kLgpUaGUgcmVwbGljYXRpb24gc3RyYW5kIGlzIGRlcGVuZGVudCBvbiB0aGUgbG9jYXRpb25zIG9mIHJlcGxpY2F0aW9uCm9yaWdpbnMgZnJvbSB3aGljaCBETkEgcmVwbGljYXRpb24gaXMgZmlyZWQuCkhvd2V2ZXIsIHJlcGxpY2F0aW9uIHRpbWluZyBpcyBkeW5hbWljIGFuZCBjZWxsLXR5cGUgc3BlY2lmaWMsCndoaWNoIG1ha2VzIHJlcGxpY2F0aW9uIHN0cmFuZCBkZXRlcm1pbmF0aW9uIGxlc3Mgc3RyYWlnaHRmb3J3YXJkIHRoYW4KdHJhbnNjcmlwdGlvbmFsIHN0cmFuZCBiaWFzIGFuYWx5c2lzLgpSZXBsaWNhdGlvbiB0aW1pbmcgcHJvZmlsZXMgY2FuIGJlIGdlbmVyYXRlZCB3aXRoClJlcGxpLVNlcSBleHBlcmltZW50cy4gT25jZSB0aGUgcmVwbGljYXRpb24gZGlyZWN0aW9uIGlzIGRlZmluZWQsCmEgc3RyYW5kIGFzeW1tZXRyeSBhbmFseXNpcyBjYW4gYmUgcGVyZm9ybWVkIHNpbWlsYXJseSBhcyB0aGUgdHJhbnNjcmlwdGlvbgpzdHJhbmQgYmlhcyBhbmFseXNpcy4KCjwvZGV0YWlscz4KCmBgYHtyIHJlcF9zdHJhbmRfYmlhcywgZmlnLmhlaWdodD0zfQpyZXBsaV9maWxlIDwtIHN5c3RlbS5maWxlKCJleHRkYXRhL1JlcGxpY2F0aW9uRGlyZWN0aW9uUmVnaW9ucy5iZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2thZ2UgPSAiTXV0YXRpb25hbFBhdHRlcm5zIikKIyBzdGFydC9zdG9wIGNvbnRhaW4gc2NpZW50aWZpYyBub3RhdGlvbiwgc28gbmVlZCB0byBiZSBkb3VibGVzCnJlcGxpX3N0cmFuZCA8LQogIHJlYWRyOjpyZWFkX3RzdihyZXBsaV9maWxlLCBjb2xfbmFtZXMgPSBUUlVFLCBjb2xfdHlwZXMgPSAiY2RkY2MiKSAlPiUKICBkcGx5cjo6bXV0YXRlX2lmKGlzLmNoYXJhY3RlciwgYXMuZmFjdG9yKQpyZXBsaV9zdHJhbmRfZ3JhbmdlcyA8LSBHUmFuZ2VzKAogIHNlcW5hbWVzID0gcmVwbGlfc3RyYW5kJENociwKICByYW5nZXMgPSBJUmFuZ2VzKHN0YXJ0ID0gcmVwbGlfc3RyYW5kJFN0YXJ0ICsgMSwKICAgICAgICAgICAgICAgICAgIGVuZCA9IHJlcGxpX3N0cmFuZCRTdG9wKSwKICBzdHJhbmRfaW5mbyA9IHJlcGxpX3N0cmFuZCRDbGFzcykKCnNlcWxldmVsc1N0eWxlKHJlcGxpX3N0cmFuZF9ncmFuZ2VzKSA8LSBzZXFsZXZlbHNTdHlsZShiYXNlOjpnZXQocmVmX2dlbm9tZSkpCgptdXRfbWF0X3NfcmVwIDwtCiAgTXV0YXRpb25hbFBhdHRlcm5zOjptdXRfbWF0cml4X3N0cmFuZGVkKAogICAgdmNmX2xpc3QgPSBzb21hdGljX3NudiwKICAgIHJlZl9nZW5vbWUgPSByZWZfZ2Vub21lLAogICAgcmFuZ2VzID0gcmVwbGlfc3RyYW5kX2dyYW5nZXMsCiAgICBtb2RlID0gInJlcGxpY2F0aW9uIikKIyBNdXRhdGlvbiBjb3VudCBwZXIgdHlwZSBhbmQgc3RyYW5kCnN0cmFuZF9jb3VudHNfcmVwIDwtIHN0cmFuZF9vY2N1cnJlbmNlcyhtdXRfbWF0X3NfcmVwLCBieSA9ICJhbGwiKQojIFBvaXNzb24gdGVzdCBmb3Igc3RyYW5kIGFzeW1tZXRyeSBzaWduaWZpY2FuY2UgdGVzdGluZwpzdHJhbmRfYmlhc19yZXAgPC0gc3RyYW5kX2JpYXNfdGVzdChzdHJhbmRfY291bnRzX3JlcCkKCk11dGF0aW9uYWxQYXR0ZXJuczo6cGxvdF9zdHJhbmQoc3RyYW5kX2NvdW50c19yZXAsIG1vZGUgPSAicmVsYXRpdmUiKQpNdXRhdGlvbmFsUGF0dGVybnM6OnBsb3Rfc3RyYW5kX2JpYXMoc3RyYW5kX2JpYXNfcmVwKQpgYGAKCiMjIyBTaWduYXR1cmUgQ29udHJpYnV0aW9uIHsudGFic2V0IC50YWJzZXQtZmFkZSAjY29udHJpYnV0aW9uc30KCjxkZXRhaWxzPgo8c3VtbWFyeT5EZXNjcmlwdGlvbjwvc3VtbWFyeT4KClRoZSBjb250cmlidXRpb24gb2YgYW55IHNldCBvZiBzaWduYXR1cmVzIHRvIHRoZSBtdXRhdGlvbmFsIHByb2ZpbGUgb2YgYQpzYW1wbGUgY2FuIGJlIHF1YW50aWZpZWQuIFRoaXMgdW5pcXVlIGZlYXR1cmUgaXMgc3BlY2lmaWNhbGx5IHVzZWZ1bApmb3IgbXV0YXRpb25hbCBzaWduYXR1cmUgYW5hbHlzZXMgb2Ygc21hbGwgY29ob3J0cyBvciBpbmRpdmlkdWFsIHNhbXBsZXMsCmJ1dCBhbHNvIHRvIHJlbGF0ZSBvd24gZmluZGluZ3MgdG8ga25vd24gc2lnbmF0dXJlcyBhbmQgcHVibGlzaGVkIGZpbmRpbmdzLgpUaGUgYGZpdF90b19zaWduYXR1cmVzYCBmdW5jdGlvbiBmaW5kcyB0aGUgb3B0aW1hbCBsaW5lYXIgY29tYmluYXRpb24gb2YKbXV0YXRpb25hbCBzaWduYXR1cmVzIHRoYXQgbW9zdCBjbG9zZWx5IHJlY29uc3RydWN0cwp0aGUgbXV0YXRpb24gbWF0cml4IGJ5IHNvbHZpbmcgYSBub24tbmVnYXRpdmUgbGVhc3Qtc3F1YXJlcyBjb25zdHJhaW50cyBwcm9ibGVtLgoKU2hvd24gYXJlIHNpZ25hdHVyZXMgd2l0aCBwb3NpdGl2ZSBDb250cmlidXRpb24gdmFsdWVzLCBhbG9uZyB3aXRoIHN1bW1hcmlzZWQgZGVzY3JpcHRpb25zCmFuZCByZWZlcmVuY2Ugc2lnbmF0dXJlIHBsb3RzIGZyb20gPGh0dHBzOi8vY2FuY2VyLnNhbmdlci5hYy51ay9jb3NtaWMvc2lnbmF0dXJlcz4uCgo8L2RldGFpbHM+Cgo8cD4mbmJzcDs8L3A+CgojIyMjIE9MRAoKYGBge3IgbXV0YXRpb25hbF9zaWduYXR1cmVfY29udHJpYnV0aW9ufQpzaWdfdGFibGUgPC0KICByZWFkcjo6cmVhZF90c3YoZmlsZSA9ICJtaXNjL3NpZy92Ml9tYXIyMDE1L3NpZ25hdHVyZXNfZGVzY3JpcHRpb24udHN2IiwgY29sX3R5cGVzID0gImNjIikgJT4lCiAgZHBseXI6Om11dGF0ZShQbG90ID0gcGFzdGUwKCIhW10obWlzYy9zaWcvdjJfbWFyMjAxNS9pbWcvc2lnLSIsIHNpZ25hdHVyZSwgIi5wbmcpIiksCiAgICAgICAgICAgICAgICBzaWduYXR1cmUgPSBwYXN0ZTAoIlNpZyIsIHNpZ25hdHVyZSkpICU+JQogIGRwbHlyOjpzZWxlY3QoU2lnbmF0dXJlID0gc2lnbmF0dXJlLCBEZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uLCBQbG90KQoKbXV0X3NpZ19jb250ciAlPiUKICBkcGx5cjo6bGVmdF9qb2luKHNpZ190YWJsZSwgYnkgPSAiU2lnbmF0dXJlIikgJT4lCiAga25pdHI6OmthYmxlKCkgJT4lCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmb250X3NpemUgPSAxMikgJT4lCiAga2FibGVFeHRyYTo6c2Nyb2xsX2JveChoZWlnaHQgPSAiNDAwcHgiKQpgYGAKCiMjIyMgTkVXCgpgYGB7ciBtdXRhdGlvbmFsX3NpZ25hdHVyZV9jb250cmlidXRpb24yfQpzaWdfdGFibGUyIDwtCiAgcmVhZHI6OnJlYWRfdHN2KGZpbGUgPSAibWlzYy9zaWcvdjNfbWF5MjAxOS9zaWduYXR1cmVzX2Rlc2NyaXB0aW9uLnRzdiIsIGNvbF90eXBlcyA9ICJjYyIpICU+JQogIGRwbHlyOjptdXRhdGUoUGxvdCA9IHBhc3RlMCgiIVtdKG1pc2Mvc2lnL3YzX21heTIwMTkvaW1nL3NicyIsIHNpZ25hdHVyZSwgIi5wbmcpIiksCiAgICAgICAgICAgICAgICBzaWduYXR1cmUgPSBwYXN0ZTAoIlNCUyIsIHNpZ25hdHVyZSkpICU+JQogIGRwbHlyOjpzZWxlY3QoU2lnbmF0dXJlID0gc2lnbmF0dXJlLCBEZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uLCBQbG90KQoKcG9zc2libGVfc2VxX2FydGVmYWN0cyA8LSBjKCJTQlMyNyIsICJTQlM0MyIsICJTQlM0NSIsICJTQlM0NiIsICJTQlM0NyIsICJTQlM0OCIsICJTQlM0OSIsICJTQlM1MCIsICJTQlM1MSIsICJTQlM1MiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0JTNTMiLCAiU0JTNTQiLCAiU0JTNTUiLCAiU0JTNTYiLCAiU0JTNTciLCAiU0JTNTgiLCAiU0JTNTkiLCAiU0JTNjAiKQoKbXV0X3NpZ19jb250cjIgJT4lCiAgZHBseXI6OmxlZnRfam9pbihzaWdfdGFibGUyLCBieSA9ICJTaWduYXR1cmUiKSAlPiUKICBkcGx5cjo6bXV0YXRlKFNpZ25hdHVyZSA9IGlmZWxzZShTaWduYXR1cmUgJWluJSBwb3NzaWJsZV9zZXFfYXJ0ZWZhY3RzLCBwYXN0ZTAoU2lnbmF0dXJlLCAiIChTQSkiKSwgU2lnbmF0dXJlKSkgJT4lCiAga25pdHI6OmthYmxlKCkgJT4lCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmb250X3NpemUgPSAxMikgJT4lCiAga2FibGVFeHRyYTo6c2Nyb2xsX2JveChoZWlnaHQgPSAiNDAwcHgiKQpgYGAKCjxwPiZuYnNwOzwvcD4KCiMjIyBSYWluZmFsbCBQbG90IHsjcmFpbmZhbGx9ClJhaW5mYWxsIHBsb3RzIHNob3cgdGhlIGRpc3RyaWJ1dGlvbiBvZiBtdXRhdGlvbnMgYWxvbmcgdGhlIGdlbm9tZSwgd2l0aCBtdXRhdGlvbiB0eXBlcwppbmRpY2F0ZWQgd2l0aCBkaWZmZXJlbnQgY29sb3JzLiBUaGUgeS1heGlzIGNvcnJlc3BvbmRzIHRvIHRoZSBkaXN0YW5jZSBvZiBhIG11dGF0aW9uIGZyb20gdGhlCnByZXZpb3VzIG11dGF0aW9uLCBhbmQgaXMgbG9nMTAgdHJhbnNmb3JtZWQuIERyb3AtZG93bnMgZnJvbSB0aGUgcGxvdHMgaW5kaWNhdGUgY2x1c3RlcnMgb3IKImhvdHNwb3RzIiBvZiBtdXRhdGlvbnMuCgpgYGB7ciBtdXRhdGlvbmFscGF0dGVybnNfcmFpbmZhbGwsIG91dC53aWR0aD0iOTAlIiwgZmlnLndpZHRoPTE0fQojIFdoZW4gdGhlcmUgaXMgb25seSAxIG9yIGxvd2VyIG51bWJlciBvZiB2YXJpYW50cyBvbiBhIGNocm9tb3NvbWUsIE11dGF0aW9uYWxQYXR0ZXJuczo6cGxvdF9yYWluZmFsbCB3aWxsIGNyYXNoIHdpdGggYW4gZXJyb3IuIFNvIG5lZWQgdG8gY2hlY2sgaWYgaXQgd2lsbCB3b3JrIGJlZm9yZWhhbmQuCmNocm9tb3NvbWVzID0gc2VxbmFtZXMoZ2V0KHJlZl9nZW5vbWUpKVsxOjIyXQp2Y2YgPSBzb21hdGljX3NudltbMV1dCmNocl9zdWJzZXQgPSB2Y2Zbc2VxbmFtZXModmNmKSA9PSBjaHJvbW9zb21lc1sxXV0KbiA9IGxlbmd0aChjaHJfc3Vic2V0KQp3aWxsX3dvcmsgPSBGQUxTRQpmb3IgKGkgaW4gMTpsZW5ndGgoY2hyb21vc29tZXMpKSB7CiAgY2hyX3N1YnNldCA9IHZjZltzZXFuYW1lcyh2Y2YpID09IGNocm9tb3NvbWVzW2ldXQogIG4gPSBsZW5ndGgoY2hyX3N1YnNldCkKICBpZiAobiA+PSAyKSB7CiAgICB3aWxsX3dvcmsgPSBUUlVFCiAgfQp9CmlmICh3aWxsX3dvcmspIHsKICBNdXRhdGlvbmFsUGF0dGVybnM6OnBsb3RfcmFpbmZhbGwoc29tYXRpY19zbnZbWzFdXSwgY2hyb21vc29tZXMgPSBzZXFuYW1lcyhnZXQocmVmX2dlbm9tZSkpWzE6MjJdLCBjZXggPSAxLjIsIHlsaW0gPSAxZSswOSkKfQpgYGAKCgojIyBDaXJjb3MgUGxvdHMgey50YWJzZXQgLnRhYnNldC1mYWRlICNjaXJjb3N9CkNpcmNvcyBwbG90cyBhcmUgZ2VuZXJhdGVkIGJ5IFBVUlBMRS4KVGhlIGZpcnN0IEJBRiBwbG90IGlzIGJhc2VkIG9uIFBVUlBMRSBkYXRhIGFuZCBjb25maWd1cmF0aW9uIGZpbGVzLgoKIyMjIEJBRiwgVG90YWwvTWlub3IgQ04sIFNWcwoKPGRldGFpbHM+CjxzdW1tYXJ5PkRlc2NyaXB0aW9uPC9zdW1tYXJ5PgoKKiBfX1RyYWNrMV9fOiBDaHJvbW9zb21lcy4gRGFya2VyIHNoYWRlZCBhcmVhczogZ2FwcyBpbiByZWZlcmVuY2UgZ2Vub21lCiAgKGNlbnRyb21lcmVzLCBoZXRlcm9jaHJvbWF0aW4gJiBtaXNzaW5nIHNob3J0IGFybXMpCiogX19UcmFjazJfXzogPHNwYW4gc3R5bGU9ImNvbG9yOiM4QTJCRTIiPkJldGEgQWxsZWxlIEZyZXF1ZW5jeTwvc3Bhbj4uCiAgR2l2ZW4gdGhhdCB0aGUgQkFGIHBvaW50cyBjb3JyZXNwb25kIHRvIGFsbGVsZSBmcmVxdWVuY2llcyBvZiBoZXRlcm96eWdvdXMgU05QcyB0aGF0IGFyZSBjb21tb24gaW4gZ2VybWxpbmUgc2FtcGxlcywKICB0aGVyZSBzaG91bGRuJ3QgYmUgYW55IGluIGNocm9tb3NvbWUgWSAoYW5kIGNocm9tb3NvbWUgWCB3aGVuIG1hbGUpLgoqIF9fVHJhY2szX186IF9fVG90YWxfXyBjb3B5IG51bWJlciBjaGFuZ2VzIGFkanVzdGVkIGZvciB0dW1vciBwdXJpdHksCiAgaW5jbHVkaW5nIGZvY2FsIGFuZCBjaHJvbW9zb21hbCBzb21hdGljIGV2ZW50cy4KICA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj5SZWQ8L3NwYW4+ID0gTG9zczsgPHNwYW4gc3R5bGU9ImNvbG9yOiMzMkNEMzIiPkdyZWVuPC9zcGFuPiA9IEdhaW4uCiAgU2NhbGVkIGZyb20gMCAoY29tcGxldGUgbG9zcykgdG8gNiAoaGlnaCBsZXZlbCBnYWlucykuCiAgSWYgPiA2LCBzaG93biBhcyA2IHdpdGggYSBncmVlbiBkb3Qgb24gdGhlIG91dGVybW9zdCBncmVlbiBncmlkbGluZS4KKiBfX1RyYWNrNF9fOiBfX01pbm9yX18gYWxsZWxlIGNvcHkgbnVtYmVycy4gUmFuZ2UgZnJvbSAwIHRvIDMuCiAgRXhwZWN0ZWQgbm9ybWFsIG1pbm9yIGFsbGVsZSBjb3B5IG51bWJlciBpcyAxLCBhbmQgYW55dGhpbmcgYmVsb3cgMSBpcyBzaG93bgogIGFzIGEgbG9zcyAoPHNwYW4gc3R5bGU9ImNvbG9yOiNFRTc2MDAiPk9yYW5nZTwvc3Bhbj4pLCByZXByZXNlbnRpbmcgYW4gTE9IIGV2ZW50LgogIE1pbm9yIGFsbGVsZSBjb3B5IG51bWJlcnMgYWJvdmUgMSAoPHNwYW4gc3R5bGU9ImNvbG9yOiM3RUMwRUUiPkJsdWU8L3NwYW4+KSBpbmRpY2F0ZSBnYWlucwogIG9mIGJvdGggQSBhbmQgQiBhbGxlbGVzLgoqIF9fVHJhY2s1X18gKElubmVyIGNpcmNsZSk6IE9ic2VydmVkIHN0cnVjdHVyYWwgdmFyaWFudHMgd2l0aGluIG9yIGJldHdlZW4gdGhlIGNocm9tb3NvbWVzLgogICAgKiA8c3BhbiBzdHlsZT0iY29sb3I6IzdFQzBFRSI+Qmx1ZTwvc3Bhbj4gPSBUcmFuc2xvY2F0aW9ucwogICAgKiA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj5SZWQ8L3NwYW4+ID0gRGVsZXRpb25zCiAgICAqIDxzcGFuIHN0eWxlPSJjb2xvcjojZTZlNjAwIj5ZZWxsb3c8L3NwYW4+ID0gSW5zZXJ0aW9ucwogICAgKiA8c3BhbiBzdHlsZT0iY29sb3I6IzMyQ0QzMiI+R3JlZW48L3NwYW4+ID0gVGFuZGVtIGR1cGxpY2F0aW9ucwogICAgKiA8c3BhbiBzdHlsZT0iY29sb3I6IzAwMDAwMCI+QmxhY2s8L3NwYW4+ID0gSW52ZXJzaW9ucwoKPC9kZXRhaWxzPgoKYGBge3IgY2lyY29zX2JhZl9wbG90LCBvdXQud2lkdGg9IjgwJSJ9CmltZ19kaXIgPC0gZmlsZS5wYXRoKCdpbWcnKSAjIGNyZWF0ZWQgYmVmb3JlIHdoZW4gY29weWluZyBwdXJwbGUgZmlsZXMgdG8gdG1wIGRpcgprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhmaWxlLnBhdGgoaW1nX2RpciwgcGFzdGUwKHBhcmFtcyRiYXRjaF9uYW1lLCAnLmNpcmNvc19iYWYucG5nJykpKQpgYGAKCgojIyMgU05Wcy9JbmRlbHMsIFRvdGFsL01pbm9yIENOLCBTVnMKCjxkZXRhaWxzPgo8c3VtbWFyeT5EZXNjcmlwdGlvbjwvc3VtbWFyeT4KCiogX19UcmFjazFfXzogQ2hyb21vc29tZXMuIERhcmtlciBzaGFkZWQgYXJlYXM6IGdhcHMgaW4gcmVmZXJlbmNlIGdlbm9tZQogIChjZW50cm9tZXJlcywgaGV0ZXJvY2hyb21hdGluICYgbWlzc2luZyBzaG9ydCBhcm1zKQoqIF9fVHJhY2syX186IFNvbWF0aWMgdmFyaWFudHMgKGluY2wuIGV4b24sIGludHJvbiBhbmQgaW50ZXJnZW5pYyByZWdpb25zKS4KICAgICogb3V0ZXIgcmluZzogU05QIGFsbGVsZSBmcmVxdWVuY2llcywgY29ycmVjdGVkIGZvciB0dW1vciBwdXJpdHkgYW5kIHNjYWxlZCBmcm9tIDAgdG8gMTAwJS4KICAgICAgRWFjaCBkb3QgcmVwcmVzZW50cyBhIHNpbmdsZSBzb21hdGljIHZhcmlhbnQsIGNvbG91cmVkIGFjY29yZGluZyB0byB0aGUKICAgICAgdHlwZSBvZiBiYXNlIGNoYW5nZSAoZS5nLiBDPlQvRz5BIGluIHJlZCkuCiAgICAqIGlubmVyIHJpbmc6IHNob3J0IGluc2VydGlvbiAoeWVsbG93KSBhbmQgZGVsZXRpb24gKHJlZCkgbG9jYXRpb25zLgoqIF9fVHJhY2szX186IE9ic2VydmVkIF9fdG90YWxfXyBjb3B5IG51bWJlciBjaGFuZ2VzIGFkanVzdGVkIGZvciB0dW1vciBwdXJpdHksCiAgaW5jbHVkaW5nIGZvY2FsIGFuZCBjaHJvbW9zb21hbCBzb21hdGljIGV2ZW50cy4KICA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj5SZWQ8L3NwYW4+ID0gTG9zczsgPHNwYW4gc3R5bGU9ImNvbG9yOiMzMkNEMzIiPkdyZWVuPC9zcGFuPiA9IEdhaW4uCiAgU2NhbGVkIGZyb20gMCAoY29tcGxldGUgbG9zcykgdG8gNiAoaGlnaCBsZXZlbCBnYWlucykuCiAgSWYgPiA2LCBzaG93biBhcyA2IHdpdGggYSBncmVlbiBkb3Qgb24gdGhlIG91dGVybW9zdCBncmVlbiBncmlkbGluZS4KKiBfX1RyYWNrNF9fOiBPYnNlcnZlZCBfX21pbm9yX18gYWxsZWxlIGNvcHkgbnVtYmVycy4gUmFuZ2UgZnJvbSAwIHRvIDMuCiAgRXhwZWN0ZWQgbm9ybWFsIG1pbm9yIGFsbGVsZSBjb3B5IG51bWJlciBpcyAxLCBhbmQgYW55dGhpbmcgYmVsb3cgMSBpcyBzaG93bgogIGFzIGEgbG9zcyAoPHNwYW4gc3R5bGU9ImNvbG9yOiNFRTc2MDAiPk9yYW5nZTwvc3Bhbj4pLCByZXByZXNlbnRpbmcgYW4gTE9IIGV2ZW50LgogIE1pbm9yIGFsbGVsZSBjb3B5IG51bWJlcnMgYWJvdmUgMSAoPHNwYW4gc3R5bGU9ImNvbG9yOiM3RUMwRUUiPkJsdWU8L3NwYW4+KSBpbmRpY2F0ZSBnYWlucwogIG9mIGJvdGggQSBhbmQgQiBhbGxlbGVzLgoqIF9fVHJhY2s1X18gKElubmVyIGNpcmNsZSk6IE9ic2VydmVkIHN0cnVjdHVyYWwgdmFyaWFudHMgd2l0aGluIG9yIGJldHdlZW4gdGhlIGNocm9tb3NvbWVzLgogICAgKiA8c3BhbiBzdHlsZT0iY29sb3I6IzdFQzBFRSI+Qmx1ZTwvc3Bhbj4gPSBUcmFuc2xvY2F0aW9ucwogICAgKiA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj5SZWQ8L3NwYW4+ID0gRGVsZXRpb25zCiAgICAqIDxzcGFuIHN0eWxlPSJjb2xvcjojZTZlNjAwIj5ZZWxsb3c8L3NwYW4+ID0gSW5zZXJ0aW9ucwogICAgKiA8c3BhbiBzdHlsZT0iY29sb3I6IzMyQ0QzMiI+R3JlZW48L3NwYW4+ID0gVGFuZGVtIGR1cGxpY2F0aW9ucwogICAgKiA8c3BhbiBzdHlsZT0iY29sb3I6IzAwMDAwMCI+QmxhY2s8L3NwYW4+ID0gSW52ZXJzaW9ucwoKPC9kZXRhaWxzPgoKYGBge3IgY2lyY29zX2RlZmF1bHQxLCBvdXQud2lkdGg9IjgwJSJ9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGZpbGUucGF0aChpbWdfZGlyLCBwYXN0ZTAocGFyYW1zJGJhdGNoX25hbWUsICcuY2lyY29zLnBuZycpKSkKYGBgCgojIyMgQWxsZWxlIFJhdGlvcywgQkFGCgo8ZGV0YWlscz4KPHN1bW1hcnk+RGVzY3JpcHRpb248L3N1bW1hcnk+CgoqIF9fVHJhY2sxX186IENocm9tb3NvbWVzLiBEYXJrZXIgc2hhZGVkIGFyZWFzOiBnYXBzIGluIHJlZmVyZW5jZSBnZW5vbWUKICAoY2VudHJvbWVyZXMsIGhldGVyb2Nocm9tYXRpbiAmIG1pc3Npbmcgc2hvcnQgYXJtcykKKiBfX1RyYWNrMl9fOiA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+VHVtb3I8L3NwYW4+IGFuZCA8c3BhbiBzdHlsZT0iY29sb3I6IzMyQ0QzMiI+Tm9ybWFsPC9zcGFuPiBBbGxlbGUgUmF0aW9zCiogX19UcmFjazNfXzogPHNwYW4gc3R5bGU9ImNvbG9yOiNFRTc2MDAiPkJldGEgQWxsZWxlIEZyZXF1ZW5jeTwvc3Bhbj4KICBHaXZlbiB0aGF0IHRoZSBCQUYgcG9pbnRzIGNvcnJlc3BvbmQgdG8gYWxsZWxlIGZyZXF1ZW5jaWVzIG9mIGhldGVyb3p5Z291cyBTTlBzIHRoYXQgYXJlIGNvbW1vbiBpbiBnZXJtbGluZSBzYW1wbGVzLAogIHRoZXJlIHNob3VsZG4ndCBiZSBhbnkgaW4gY2hyb21vc29tZSBZIChhbmQgY2hyb21vc29tZSBYIHdoZW4gbWFsZSkuCgo8L2RldGFpbHM+CgpgYGB7ciBjaXJjb3NfZGVmYXVsdDIsIG91dC53aWR0aD0iODAlIn0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoZmlsZS5wYXRoKGltZ19kaXIsIHBhc3RlMChwYXJhbXMkYmF0Y2hfbmFtZSwgJy5pbnB1dC5wbmcnKSkpCmBgYAoKIyMgU3RydWN0dXJhbCBWYXJpYW50cyB7I3N2LXN1bW1hcnl9ClN0cnVjdHVyYWwgdmFyaWFudHMgYXJlIGluZmVycmVkIHdpdGggW01hbnRhXShodHRwczovL2dpdGh1Yi5jb20vaWxsdW1pbmEvbWFudGEpLAphZGp1c3RlZCB1c2luZyBbUFVSUExFXShodHRwczovL2dpdGh1Yi5jb20vaGFydHdpZ21lZGljYWwvaG1mdG9vbHMvdHJlZS9tYXN0ZXIvcHVyaXR5LXBsb2lkeS1lc3RpbWF0b3IjNy1zdHJ1Y3R1cmFsLXZhcmlhbnQtcmVjb3ZlcnktYW5kLXNpbmdsZS1icmVha2VuZC1maWx0ZXJpbmcpLAphbmQgcHJpb3JpdGlzZWQgdXNpbmcgW3NpbXBsZV9zdl9hbm5vdGF0aW9uXShodHRwczovL2dpdGh1Yi5jb20vQXN0cmFaZW5lY2EtTkdTL3NpbXBsZV9zdl9hbm5vdGF0aW9uKS4KQWxsZWxlIGZyZXF1ZW5jaWVzLCBjb3B5IG51bWJlciBjaGFuZ2VzIGFuZCBwbG9pZHkgYXJlIHB1cml0eS1hZGp1c3RlZC4KCjxkZXRhaWxzPgo8c3VtbWFyeT5EZXRhaWxzPC9zdW1tYXJ5PgoKVGhlIGlucHV0IGZpbGUgY29ycmVzcG9uZHMgdG8gYHVtY2NyaXNlZC88YmF0Y2g+L3N0cnVjdHVyYWwvPGJhdGNoPi1tYW50YS50c3ZgLgoKSXQncyBnZW5lcmF0ZWQgdGhyb3VnaCB0aGUgZm9sbG93aW5nIHN0ZXBzOgoKX19TdGVwIDE6IFByb2Nlc3NpbmdfXwoKKiBfX0lucHV0X186IE1hbnRhIHN0cnVjdHVyYWwgdmFyaWFudCBjYWxscyBmcm9tIGJjYmlvCihgZmluYWwvPHR1bW9yLW5hbWU+LzxiYXRjaC1uYW1lPi1zdi1wcmlvcml0aXplLW1hbnRhLnZjZi5nemAgKG9yCmA8YmF0Y2gtbmFtZT4tbWFudGEudmNmLmd6YCBpZiBub3QgcHJpb3JpdGlzZWQpKQoqIFJlbW92ZSBmb2xsb3dpbmcgYW5ub3RhdGlvbnMgZnJvbSBNYW50YSBWQ0Y6CiAgJ0lORk8vU0lNUExFX0FOTicsICdJTkZPL1NWX0hJR0hFU1RfVElFUicsICdGSUxURVIvSW50ZXJnZW5pYycsICdGSUxURVIvTWlzc2luZ0FubicsICdGSUxURVIvUkVKRUNUJwoqIFByaW9yaXRpc2UgdmFyaWFudHMgd2l0aCBbc2ltcGxlX3N2X2Fubm90YXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS92bGFkc2F2ZWxpZXYvc2ltcGxlX3N2X2Fubm90YXRpb24pYAoqIF9fT3V0cHV0X186IGB3b3JrL3tiYXRjaH0vc3RydWN0dXJhbC9wcmlvcml0aXplL3tiYXRjaH0tbWFudGEudmNmLmd6YAoqIEtlZXAgUEFTUyB2YXJpYW50cwoqIElmIG1vcmUgdGhhbiAxMDAsMDAwIHZhcmlhbnRzLCBrZWVwIG9ubHkgdmFyaWFudHMgd2hlcmUgYElORk8vU1ZfVE9QX1RJRVIgPD0gM2AKKiBfX091dHB1dF9fOiBgd29yay97YmF0Y2h9L3N0cnVjdHVyYWwva2VlcF9wYXNzL3tiYXRjaH0tbWFudGEudmNmYAoqIERlYWwgd2l0aCBjaHJvbW9zb21lIGNhcGl0YWxpc2F0aW9uIG9jY3VycmluZyBmcm9tIFNucEVmZgoqIFJ1biBCcmVha1BvaW50SW5zcGVjdG9yIChCUEkpIGlmIGl0IHdhcyBkaXNhYmxlZCBpbiBiY2JpbwoqIF9fT3V0cHV0X186IGB3b3JrL3tiYXRjaH0vc3RydWN0dXJhbC9tYXliZV9icGkve2JhdGNofS1tYW50YS52Y2ZgCgpfX1N0ZXAgMjogRmlsdGVyaW5nX18KCiogS2VlcCBQQVNTIHZhcmlhbnRzIChzaW5jZSBCUEkgdXBkYXRlcyB0aGUgRklMVEVSIGNvbHVtbikKKiBGb3IgQk5EIHZhcmlhbnRzIHJlcXVpcmUgcGFpcmVkIHJlYWRzIHN1cHBvcnQgKFBSKSB0byBiZSBoaWdoZXIgdGhhbiBzcGxpdCByZWFkIHN1cHBvcnQgKFNSKQoqIEtlZXAgYWxsIGBJTkZPL1NWX1RPUF9USUVSIDw9IDJgIHZhcmlhbnRzCiogRm9yIGBJTkZPL1NWX1RPUF9USUVSID4gMmAgdmFyaWFudHMgcmVxdWlyZSBzcGxpdCBfb3JfIHBhaXJlZCByZWFkcyBzdXBwb3J0IG9mIGF0IGxlYXN0IDV4CiogRm9yIGBJTkZPL1NWX1RPUF9USUVSID4gMmAgdmFyaWFudHMgd2l0aCBsb3cgYWxsZWxlIGZyZXF1ZW5jeSBhdCBhbnkgYnJlYWtwb2ludCAoYEJQSV9BRlswIG9yIDFdIDwgMC4xYCksCiAgcmVxdWlyZSBTUiBvciBQUiBzdXBwb3J0IG9mIGF0IGxlYXN0IDEweAoqIF9fT3V0cHV0X186IGB3b3JrL3tiYXRjaH0vc3RydWN0dXJhbC9maWx0L3tiYXRjaH0tbWFudGEudmNmYAoKX19TdGVwIDM6IFBVUlBMRSBhbmQgRkZQRSBjb25kaXRpb25hbF9fCgoqIElmIHRoZSBzYW1wbGUgX2lzIG5vdF8gRkZQRToKICAqIEZlZWQgYWJvdmUgZmlsdGVyZWQgU1ZzIHRvIFBVUlBMRSwgd2hpY2ggb3V0cHV0cyBgcHVycGxlLnN2LnZjZi5nemAgdGhhdCBjb250YWlucyByZXNjdWVkIFNWcwogICogUHJpb3JpdGlzZSB2YXJpYW50cyAoYWdhaW4pCiAgKiBSZW1vdmUgJ0lORk8vQU5OJyBhbm5vdGF0aW9uCiAgKiBfX091dHB1dF9fOiBge2JhdGNofS9zdHJ1Y3R1cmFsL3tiYXRjaH0tbWFudGEudmNmLmd6YAoqIElmIHRoZSBzYW1wbGUgX2lzXyBGRlBFOgogICogSnVzdCBjb3B5IGBmaWx0ZXJlZGAgdmFyaWFudHMgYW5kIGRvbid0IGRvIGFueXRoaW5nCiAgICAoaS5lLiB3ZSBkb24ndCB3YW50IHRoZSByZXNjdWVkIFNWcyBmcm9tIFBVUlBMRSBzaW5jZSB0aGV5J2xsIGxpa2VseSBiZSBoZWFwcykKICAgIChub3RlIHRoYXQgUFVSUExFIHdpbGwgc3RpbGwgZ2V0IGZlZCB3aXRoIHRoZSBgZmlsdGVyZWRgIFNWcykKICAqIF9fT3V0cHV0X186IGB7YmF0Y2h9L3N0cnVjdHVyYWwve2JhdGNofS1tYW50YS52Y2YuZ3pgCgpfX1N0ZXAgNDogVFNWIGZpbmFsIG91dHB1dF9fCgoqIElucHV0OiBge2JhdGNofS9zdHJ1Y3R1cmFsL3tiYXRjaH0tbWFudGEudmNmLmd6YCBWQ0YKKiBPdXRwdXQ6IGB7YmF0Y2h9L3N0cnVjdHVyYWwve2JhdGNofS1tYW50YS50c3ZgIFRTVgoKCmBgYHtyIG1hbnRhX3Rzdl9kZXNjcmlwdGlvbn0KbWFudGFfdHN2X2NvbF9kZXNjciA8LSBkcGx5cjo6dHJpYmJsZSgKICB+Q29sdW1uLCB+RGVzY3JpcHRpb24sCiAgImNhbGxlciIsICJNYW50YSBTViBjYWxsZXIiLAogICJzYW1wbGUiLCAiVHVtb3Igc2FtcGxlIG5hbWUiLAogICJjaHJvbSIsICJDSFJPTSBjb2x1bW4gaW4gVkNGIiwKICAic3RhcnQiLCAiUE9TIGNvbHVtbiBpbiBWQ0YiLAogICJlbmQiLCAiSU5GTy9FTkQ6IEVuZCBwb3NpdGlvbiBvZiB0aGUgdmFyaWFudCBkZXNjcmliZWQgaW4gdGhpcyByZWNvcmQiLAogICJzdnR5cGUiLCAiSU5GTy9TVlRZUEU6IFR5cGUgb2Ygc3RydWN0dXJhbCB2YXJpYW50IiwKICAic3BsaXRfcmVhZF9zdXBwb3J0IiwgIkZPUk1BVC9TUiBvZiB0dW1vciBzYW1wbGU6IFNwbGl0IHJlYWRzIGZvciB0aGUgcmVmIGFuZCBhbHQgYWxsZWxlcyBpbiB0aGUgb3JkZXIgbGlzdGVkLCBmb3IgcmVhZHMgd2hlcmUgUChhbGxlbGV8cmVhZCk+MC45OTkiLAogICJwYWlyZWRfc3VwcG9ydF9QRSIsICJGT1JNQVQvUEUgb2YgdHVtb3Igc2FtcGxlOiA/PyIsCiAgInBhaXJlZF9zdXBwb3J0X1BSIiwgIkZPUk1BVC9QUiBvZiB0dW1vciBzYW1wbGU6IFNwYW5uaW5nIHBhaXJlZC1yZWFkIHN1cHBvcnQgZm9yIHRoZSByZWYgYW5kIGFsdCBhbGxlbGVzIGluIHRoZSBvcmRlciBsaXN0ZWQsIGZvciByZWFkcyB3aGVyZSBQKGFsbGVsZXxyZWFkKT4wLjk5OSIsCiAgIkFGX0JQSSIsICJJTkZPL0JQSV9BRjogQUYgYXQgZWFjaCBicmVha3BvaW50IChzbyBBRl9CUEkxLEFGX0JQSTIpIiwKICAic29tYXRpY3Njb3JlIiwgIklORk8vU09NQVRJQ1NDT1JFOiBTb21hdGljIHZhcmlhbnQgcXVhbGl0eSBzY29yZSIsCiAgInRpZXIiLCAiSU5GTy9TVl9UT1BfVElFUiAob3IgNCBpZiBtaXNzaW5nKTogSGlnaGVzdCBwcmlvcml0eSB0aWVyIGZvciB0aGUgZWZmZWN0cyBvZiBhIHZhcmlhbnQgZW50cnkiLAogICJhbm5vdGF0aW9uIiwgIklORk8vU0lNUExFX0FOTjogU2ltcGxpZmllZCBzdHJ1Y3R1cmFsIHZhcmlhbnQgYW5ub3RhdGlvbjogJ1NWVFlQRSB8IEVGRkVDVCB8IEdFTkUocykgfCBUUkFOU0NSSVBUIHwgUFJJT1JJVFkgKDEtNCknIiwKICAiQUZfUFVSUExFIiwgIklORk8vUFVSUExFX0FGOiBBRiBhdCBlYWNoIGJyZWFrZW5kIChwdXJpdHkgYWRqdXN0ZWQpIChzbyBBRl9QVVJQTEUxLEFGX1BVUlBMRTIpIiwKICAiQ05fUFVSUExFIiwgIklORk8vUFVSUExFX0NOOiBDTiBhdCBlYWNoIGJyZWFrZW5kIChwdXJpdHkgYWRqdXN0ZWQpIChzbyBDTl9QVVJQTEUxLENOX1BVUlBMRTIpIiwKICAiQ05fY2hhbmdlX1BVUlBMRSIsICJJTkZPL1BVUlBMRV9DTl9DSEFOR0U6IGNoYW5nZSBpbiBDTiBhdCBlYWNoIGJyZWFrZW5kIChwdXJpdHkgYWRqdXN0ZWQpIChzbyBDTl9jaGFuZ2VfUFVSUExFMSxDTl9jaGFuZ2VfUFVSUExFMikiLAogICJQbG9pZHlfUFVSUExFIiwgIklORk8vUFVSUExFX1BMT0lEWTogUGxvaWR5IG9mIHZhcmlhbnQgKHB1cml0eSBhZGp1c3RlZCkiLAogICJQVVJQTEVfc3RhdHVzIiwgIklORkVSUkVEIGlmIEZJTFRFUj1JTkZFUlJFRCwgb3IgUkVDT1ZFUkVEIGlmIGhhcyBJTkZPL1JFQ09WRVJFRCwgZWxzZSBibGFuay4gSU5GRVJSRUQ6IEJyZWFrZW5kIGluZmVycmVkIGZyb20gY29weSBudW1iZXIgdHJhbnNpdGlvbiIsCiAgIlNUQVJUX0JQSSIsICJJTkZPL0JQSV9TVEFSVDogQlBJIGFkanVzdGVkIGJyZWFrZW5kIGxvY2F0aW9uIiwKICAiRU5EX0JQSSIsICJJTkZPL0JQSV9FTkQ6IEJQSSBhZGp1c3RlZCBicmVha2VuZCBsb2NhdGlvbiIsCiAgIklEIiwgIklEIGNvbHVtbiBpbiBWQ0YiLAogICJNQVRFSUQiLCAiSU5GTy9NQVRFSUQ6IElEIG9mIG1hdGUgYnJlYWtlbmQiKQoKY2hlY2tfY29sc19kZXNjcmliZWQobWFudGFfdHN2X2NvbF9kZXNjciRDb2x1bW4sIGNvbG5hbWVzKHNvbWF0aWNfc3ZfdHN2KSkKCm1hbnRhX3Rzdl9jb2xfZGVzY3IgJT4lCiAgZHBseXI6OmFycmFuZ2UoQ29sdW1uKSAlPiUKICBkcGx5cjo6bXV0YXRlKENvbHVtbiA9IGthYmxlRXh0cmE6OmNlbGxfc3BlYyhDb2x1bW4sIGJvbGQgPSBUUlVFKSkgJT4lCiAga25pdHI6OmthYmxlKGVzY2FwZSA9IEZBTFNFLCBjYXB0aW9uID0gIkRlc2NyaXB0aW9uIG9mIE1hbnRhIFRTViBjb2x1bW5zIikgJT4lCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gRkFMU0UsIHBvc2l0aW9uID0gImxlZnQiKSAlPiUKICBrYWJsZUV4dHJhOjpzY3JvbGxfYm94KGhlaWdodCA9ICIyNTBweCIpCmBgYAoKYGBge3Igc3ZfdGFibGVfZGVzY3JpcHRpb259CnN2X2NvbF9kZXNjciA8LSBkcGx5cjo6dHJpYmJsZSgKICB+Q29sdW1uLCB+RGVzY3JpcHRpb24sCiAgIm5yb3ciLCAiUm93IG51bWJlciB0aGF0IGNvbm5lY3RzIHZhcmlhbnRzIGJldHdlZW4gdGFibGVzIGluIHNhbWUgdGFiIHNldCIsCiAgInZhcm51bSIsICJPcmlnaW5hbCBldmVudCByb3cgbnVtYmVyIHRoYXQgY29ubmVjdHMgdmFyaWFudHMgdG8gZXZlbnRzIiwKICAiVGllclRvcCIsICJUb3AgcHJpb3JpdHkgb2YgdGhlIGV2ZW50IChmcm9tICdzaW1wbGVfc3ZfYW5ub3RhdGlvbic6IDEgaGlnaGVzdCwgNCBsb3dlc3QpIiwKICAiVGllciIsICJQcmlvcml0eSBvZiB0aGUgc3BlY2lmaWMgZXZlbnQgKGZyb20gJ3NpbXBsZV9zdl9hbm5vdGF0aW9uJzogMSBoaWdoZXN0LCA0IGxvd2VzdCkiLAogICJDaHIiLCAiQ2hyb21vc29tZSIsCiAgIlN0YXJ0IiwgIlN0YXJ0IHBvc2l0aW9uIGFzIGluZmVycmVkIGJ5IEJQSSAoZm9yIFBVUlBMRS1pbmZlcnJlZCBTVnMgd2UgdXNlIFBPUykiLAogICJFbmQiLCBwYXN0ZSgiRW5kIHBvc2l0aW9uLiBGb3IgQk5EcyB0aGlzIGhhcyBiZWVuIGFzc2lnbmVkIHRvIHRoZSBDaHI6U3RhcnQgb2YgdGhlIEJORCdzIG1hdGUgZm9yIGNvbnZlbmllbmNlLiIsCiAgICAgICAgICAgICAgICJWYWx1ZXMgYXJlIGluZmVycmVkIGJ5IEJQSSAoUFVSUExFLWluZmVycmVkIFNWcyBkb24ndCBoYXZlIGFuIEVuZCkuIiksCiAgIklEIiwgIklEIG9mIEJORCBmcm9tIE1hbnRhIChvciBQVVJQTEUgZm9yIFBVUlBMRS1pbmZlcnJlZCBTVnMpKSIsCiAgIk1BVEVJRCIsICJJRCBvZiBCTkQgbWF0ZSBmcm9tIE1hbnRhIiwKICAiQk5EX0lEIiwgIklEIG9mIEJORCBwYWlyIHNpbXBsaWZpZWQuIEJORHMgd2l0aCB0aGUgc2FtZSBCTkRfSUQgYmVsb25nIHRvIHRoZSBzYW1lIHRyYW5zbG9jYXRpb24gZXZlbnQiLAogICJCTkRfbWF0ZSIsICInQScgb3IgJ0InIGRlcGVuZGluZyBvbiBpZiBpdCdzIHRoZSBmaXJzdCBvciBzZWNvbmQgbWF0ZSBpbiB0aGUgQk5EIHBhaXIiLAogICJHZW5lcyIsICJHZW5lcyBpbnZvbHZlZCBpbiB0aGUgZXZlbnQuIERFTC9EVVAvSU5TIGV2ZW50cyBpbnZvbHZpbmcgbW9yZSB0aGFuIDIgZ2VuZXMgYXJlIHNob3duIGluIHNlcGFyYXRlIHRhYmxlLiIsCiAgIlRyYW5zY3JpcHQiLCAiVHJhbnNjcmlwdHMgaW52b2x2ZWQgaW4gdGhlIGV2ZW50LiBERUwvRFVQL0lOUyBldmVudHMgaW52b2x2aW5nIG1vcmUgdGhhbiAyIHRyYW5zY3JpcHRzIGFyZSBzaG93biBpbiBzZXBhcmF0ZSB0YWJsZS4iLAogICJFZmZlY3QiLCBnbHVlOjpnbHVlKCJTViBlZmZlY3QgKGJhc2VkIG9uICIsCiAgICAgICAgICAgICAgICAgICAgICAgIntodG1sdG9vbHM6OmEoaHJlZj0naHR0cDovL3NucGVmZi5zb3VyY2Vmb3JnZS5uZXQvU25wRWZmX21hbnVhbC5odG1sI2lucHV0JywgJ1NucEVmZiBFZmZlY3QgU2VxdWVuY2UgT250b2xvZ3knKX0iLAogICAgICAgICAgICAgICAgICAgICAgICIgLSBhYmJyZXZpYXRpb25zIGFyZSBzaG93biB1bmRlciB7aHRtbHRvb2xzOjphKGhyZWY9JyNzdi1zdW1tYXJ5JywgJ0RldGFpbHMnKX0gaW4gdGhlIEVmZmVjdHMgdGFibGUiKSwKICAiRGV0YWlsIiwgIlByaW9yaXRpc2F0aW9uIGRldGFpbCAoZnJvbSAnc2ltcGxlX3N2X2Fubm90YXRpb24nKSIsCiAgIlBsb2lkeSIsICJQbG9pZHkgb2YgdmFyaWFudCBmcm9tIFBVUlBMRSAocHVyaXR5IGFkanVzdGVkKSIsCiAgIkFGX1BVUlBMRSIsICJQVVJQTEUgQUYgYXQgZWFjaCBicmVha2VuZCBwcmVjZWRlZCBieSB0aGVpciBhdmVyYWdlIiwKICAiQUZfQlBJIiwgIkJQSSBBRiBhdCBlYWNoIGJyZWFrZW5kIHByZWNlZGVkIGJ5IHRoZWlyIGF2ZXJhZ2UiLAogICJDTiIsICJDb3B5IE51bWJlciBhdCBlYWNoIGJyZWFrZW5kIHByZWNlZGVkIGJ5IHRoZWlyIGF2ZXJhZ2UiLAogICJDTkMiLCAiQ29weSBOdW1iZXIgQ2hhbmdlIGF0IGVhY2ggYnJlYWtlbmQgcHJlY2VkZWQgYnkgdGhlaXIgYXZlcmFnZSIsCiAgIlNSX1BSX2FsdCIsICJOdW1iZXIgb2YgU3BsaXQgUmVhZHMgYW5kIFBhaXJlZCBSZWFkcyBzdXBwb3J0aW5nIHRoZSBhbHQgYWxsZWxlLCBmb3IgcmVhZHMgd2hlcmUgUChhbGxlbGV8cmVhZCk+MC45OTkiLAogICJTUl9QUl9yZWYiLCAiTnVtYmVyIG9mIFNwbGl0IFJlYWRzIGFuZCBQYWlyZWQgUmVhZHMgc3VwcG9ydGluZyB0aGUgcmVmIGFsbGVsZSwgZm9yIHJlYWRzIHdoZXJlIFAoYWxsZWxlfHJlYWQpPjAuOTk5IiwKICAiVHlwZSIsICJUeXBlIG9mIHN0cnVjdHVyYWwgdmFyaWFudCIsCiAgIlNTY29yZSIsICJTb21hdGljIHZhcmlhbnQgcXVhbGl0eSBzY29yZSIsCiAgIm50cngiLCAiTnVtYmVyIG9mIHRyYW5zY3JpcHRzIGZvciBnaXZlbiBldmVudCIsCiAgIm5nZW4iLCAiTnVtYmVyIG9mIGdlbmVzIGZvciBnaXZlbiBldmVudCIsCiAgIm5hbm4iLCAiTnVtYmVyIG9mIGFubm90YXRpb25zIGZvciBnaXZlbiBldmVudCIKKQpgYGAKCjxwPiZuYnNwOzwvcD4KCl9fUHJpb3JpdGlzYXRpb24gcHJvY2Vzc19fCgoxLiBBbm5vdGF0ZSB3aXRoIFtTbnBFZmZdKGh0dHA6Ly9zbnBlZmYuc291cmNlZm9yZ2UubmV0L1NucEVmZl9tYW51YWwuaHRtbCkgYmFzZWQgb24gRW5zZW1ibCBnZW5lIG1vZGVsCjIuIFN1YnNldCBhbm5vdGF0aW9ucyB0byBbQVBQUklTIHByaW5jaXBhbCB0cmFuc2NyaXB0c10oaHR0cDovL2FwcHJpcy5iaW9pbmZvLmNuaW8uZXMvIy8pCjMuIFByaW9yaXRpemUgdmFyaWFudHMgd2l0aCBbc2ltcGxlX3N2X2Fubm90YXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS92bGFkc2F2ZWxpZXYvc2ltcGxlX3N2X2Fubm90YXRpb24pCiAgIDEoaGlnaCktMihtb2RlcmF0ZSktMyhsb3cpLTQobm8gaW50ZXJlc3QpOgogICogZXhvbiBsb3NzCiAgICAgLSBvbiBwcmlvcml0aXNhdGlvbiBnZW5lIGxpc3QgKDEpCiAgICAgLSBvdGhlciAoMikKICAqIGdlbmVfZnVzaW9uCiAgICAgLSBwYWlyZWQgKGhpdHMgdHdvIGdlbmVzKQogICAgICAgIC0gb24gbGlzdCBvZiBrbm93biBwYWlycyAoMSkgKGN1cmF0ZWQgYnkgW0hNRl0oaHR0cHM6Ly9yZXNvdXJjZXMuaGFydHdpZ21lZGljYWxmb3VuZGF0aW9uLm5sKSkKICAgICAgICAtIG9uZSBnZW5lIGlzIGEga25vd24gcHJvbWlzY3VvdXMgZnVzaW9uIGdlbmUgKDEpIChjdXJhdGVkIGJ5IFtITUZdKGh0dHBzOi8vcmVzb3VyY2VzLmhhcnR3aWdtZWRpY2FsZm91bmRhdGlvbi5ubCkpCiAgICAgICAgLSBvbiBsaXN0IG9mIEZ1c2lvbkNhdGNoZXIga25vd24gcGFpcnMgKDIpCiAgICAgICAgLSBvdGhlcjoKICAgICAgICAgICAtIG9uZSBvciB0d28gZ2VuZXMgb24gcHJpb3JpdGlzYXRpb24gZ2VuZSBsaXN0ICgyKQogICAgICAgICAgIC0gbmVpdGhlciBnZW5lIG9uIHByaW9yaXRpc2F0aW9uIGdlbmUgbGlzdCAoMykKICAgICAtIHVucGFpcmVkIChoaXRzIG9uZSBnZW5lKQogICAgICAgICAtIG9uIHByaW9yaXRpc2F0aW9uIGdlbmUgbGlzdCAoMikKICAgICAgICAgLSBvdGhlcnMgKDMpCiAgKiB1cHN0cmVhbSBvciBkb3duc3RyZWFtCiAgICAgLSBvbiBwcmlvcml0aXNhdGlvbiBnZW5lIGxpc3QgZ2VuZXMgKDIpICAtIGUuZy4gb25lIGdlbmUgaXMgZ290IGludG8KICAgICAgIGNvbnRyb2wgb2YgYW5vdGhlciBnZW5lJ3MgcHJvbW90ZXIgYW5kIGdldCBvdmVyZXhwcmVzc2VkIChvbmNvZ2VuZSkgb3IgdW5kZXJleHByZXNzZWQgKHRzZ2VuZSkKICAqIExvRiBvciBISUdIIGltcGFjdCBpbiBhIHR1bW9yIHN1cHByZXNzb3IKICAgICAtIG9uIHByaW9yaXRpc2F0aW9uIGdlbmUgbGlzdCAoMikKICAgICAtIG90aGVyIFRTIGdlbmUgKDMpCiAgKiBvdGhlciAoNCkKCiogVXNlIFBVUlBMRSBjb3B5IG51bWJlciBjYWxsZXIgdG8gaW5mZXIgbW9yZSBTViBjYWxscyBmcm9tIGNvcHkgbnVtYmVyIHRyYW5zaXRpb25zIChtYXJrZWQgYXMgJ1BVUlBMRSBJbmZlcnJlZCcpCgpgYGB7ciBlZmZlY3RfYWJicmV2X3RhYn0KZWZmZWN0X2FiYnJldmlhdGlvbnMgJT4lCiAgdGliYmxlOjplbmZyYW1lKHZhbHVlID0gImFiYnJldmlhdGlvbiIpICU+JQogIGRwbHlyOjphcnJhbmdlKGFiYnJldmlhdGlvbikgJT4lCiAgZHBseXI6Om11dGF0ZShuYW1lID0ga2FibGVFeHRyYTo6Y2VsbF9zcGVjKG5hbWUsIGJvbGQgPSBUUlVFKSkgJT4lCiAga25pdHI6OmthYmxlKGVzY2FwZSA9IEZBTFNFKSAlPiUKICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBGQUxTRSwgcG9zaXRpb24gPSAibGVmdCIpICU+JQogIGthYmxlRXh0cmE6OnNjcm9sbF9ib3goaGVpZ2h0ID0gIjI1MHB4IikKYGBgCgo8L2RldGFpbHM+Cgo8cD4mbmJzcDs8L3A+CgojIyMgU3VtbWFyeQoKYGBge3Igc3Zfc3VtbWFyeSwgcmVzdWx0cz0nYXNpcyd9CmlmICghbm9fc3ZfZm91bmQpIHsKICBzdl90aWVyX3ZzX3N2dHlwZSA8LSBmdW5jdGlvbigpIHsKICAgIGwgPC0gbGlzdCh1bm1lbHRlZCA9IHN2X3VubWVsdGVkICU+JSBkcGx5cjo6c2VsZWN0KFRpZXJUb3AsIFR5cGUpLAogICAgICAgICAgICAgIG1lbHRlZCA9IHN2X2FsbCAlPiUgZHBseXI6OnNlbGVjdChUaWVyLCBUeXBlKSkgJT4lCiAgICAgIHB1cnJyOjptYXAoZnVuY3Rpb24oeCkgYWRkbWFyZ2lucyh0YWJsZSh4LCB1c2VOQSA9ICdpZmFueScpKSkKCiAgICBjYXBfdW5tZWx0IDwtIGdsdWU6OmdsdWUoIlNWIHR5cGUgYnkge2h0bWx0b29sczo6c3Ryb25nKCd0b3AnKX0gdGllciB7aHRtbHRvb2xzOjpzdHJvbmcoJ2JlZm9yZScpfSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIntodG1sdG9vbHM6OmJyKCl9YnJlYWtpbmcgZG93biBieSBhbm5vdGF0aW9uIikKICAgIGNhcF9tZWx0IDwtIGdsdWU6OmdsdWUoIlNWIHR5cGUgYnkge2h0bWx0b29sczo6c3Ryb25nKCdpbmRpdmlkdWFsJyl9IHRpZXIge2h0bWx0b29sczo6c3Ryb25nKCdhZnRlcicpfSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJ7aHRtbHRvb2xzOjpicigpfWJyZWFraW5nIGRvd24gYnkgYW5ub3RhdGlvbiIpCiAgICB1bm1lbHRlZCA8LSBrbml0cjo6a2FibGUobCR1bm1lbHRlZCwgZm9ybWF0ID0gImh0bWwiLCBjYXB0aW9uID0gY2FwX3VubWVsdCwgb3V0cHV0ID0gRkFMU0UpICU+JQogICAgICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBGQUxTRSwgcG9zaXRpb24gPSAiZmxvYXRfcmlnaHQiKQogICAgbWVsdGVkIDwtIGtuaXRyOjprYWJsZShsJG1lbHRlZCwgZm9ybWF0ID0gImh0bWwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjYXB0aW9uID0gY2FwX21lbHQsIG91dHB1dCA9IEZBTFNFKSAlPiUKICAgICAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gRkFMU0UsIHBvc2l0aW9uID0gImZsb2F0X3JpZ2h0IikKCiAgICBsaXN0KHVubWVsdGVkID0gdW5tZWx0ZWQsIG1lbHRlZCA9IG1lbHRlZCkKICB9CiAgY2F0KGMoJzx0YWJsZT48dHIgdmFsaWduPSJ0b3AiPjx0ZD4nLCBzdl90aWVyX3ZzX3N2dHlwZSgpJHVubWVsdGVkLCAnPC90ZD4nLCAnPHRkPicsIHN2X3RpZXJfdnNfc3Z0eXBlKCkkbWVsdGVkLCAnPC90ZD48L3RyPjwvdGFibGU+JyksIHNlcCA9ICcnKQp9IGVsc2UgewogIGNhdCgiTm8gU1ZzIGNhbGxlZC4iKQp9CmBgYAoKIyMjIFVubWVsdGVkIFZhcmlhbnRzIHsjc3YtdW5tZWx0ZWR9CgpgYGB7ciBzdnRhYl9yYXd9CmlmICghbm9fc3ZfZm91bmQpIHsKICBzdnRhYl9yYXcgPC0gc3ZfdW5tZWx0ZWQgJT4lCiAgICBkcGx5cjo6c2VsZWN0KC1hbm5vdGF0aW9uKSAlPiUKICAgIGRwbHlyOjphcnJhbmdlKFRpZXJUb3AsIHZhcm51bSkKCiAgc3Z0YWJfcmF3ZHQgPC0gc3Z0YWJfcmF3ICU+JQogICAgRFQ6OmRhdGF0YWJsZShmaWx0ZXIgPSBsaXN0KHBvc2l0aW9uID0gInRvcCIsIGNsZWFyID0gRkFMU0UsIHBsYWluID0gVFJVRSksCiAgICAgICAgICAgICAgICAgIGNsYXNzID0gImNlbGwtYm9yZGVyIGRpc3BsYXkgY29tcGFjdCIsCiAgICAgICAgICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsIGV4dGVuc2lvbnMgPSBjKCJTY3JvbGxlciIsICJCdXR0b25zIiwgIktleVRhYmxlIiksCiAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KAogICAgICAgICAgICAgICAgICAgIGNvbHVtbkRlZnMgPSBsaXN0KGxpc3QoY2xhc3NOYW1lID0gJ2R0LXJpZ2h0JywgdGFyZ2V0cyA9IGNvbF9pbmRfanMoc3Z0YWJfcmF3LCAiRW5kIikpKSwKICAgICAgICAgICAgICAgICAgICBzY3JvbGxlciA9IFRSVUUsIHNjcm9sbFkgPSA0MDAsIHNjcm9sbFggPSBUUlVFLCBhdXRvV2lkdGggPSBGQUxTRSwga2V5cyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgYnV0dG9ucyA9IGMoJ2NzdicpLCBkb20gPSAnQmxmcnRpcCcpKSAlPiUKICAgIERUOjpmb3JtYXRDdXJyZW5jeSh+IFN0YXJ0LCBjdXJyZW5jeSA9ICIiLCBpbnRlcnZhbCA9IDMsIG1hcmsgPSAiLCIsIGRpZ2l0cyA9IDApCn0gZWxzZSB7CiAgc3Z0YWJfcmF3IDwtIE5VTEwKICBzdnRhYl9yYXdkdCA8LSBOVUxMCn0KYGBgCgo8ZGV0YWlscz4KPHN1bW1hcnk+RGVzY3JpcHRpb248L3N1bW1hcnk+CgpgYGB7cn0KaWYgKCFub19zdl9mb3VuZCkgewogIHN2X2RldGFpbF90YWJsZShzdnRhYl9yYXcpCn0gZWxzZSB7CiAgY2F0KCJObyBTVnMgY2FsbGVkLiIpCn0KYGBgCgo8L2RldGFpbHM+CgpgYGB7ciBzdnRhYl9yYXdkdH0KaWYgKCFub19zdl9mb3VuZCkgewogIHN2dGFiX3Jhd2R0Cn0gZWxzZSB7CiAgY2F0KCJObyBTVnMgY2FsbGVkLiIpCn0KYGBgCgojIyMgVHJhbnNsb2NhdGlvbnMgKEJORHMpIHsudGFic2V0IC50YWJzZXQtZmFkZSAjdHJhbnNsb2NhdGlvbnN9CgpgYGB7ciBzdnRhYl9CTkR9CmlmICghbm9fc3ZfZm91bmQpIHsKICBzdl9CTkQgPC0gc3ZfYWxsICU+JQogICAgZHBseXI6OmZpbHRlcihUeXBlID09ICJCTkQiKSAlPiUKICAgIGRwbHlyOjptdXRhdGUobnJvdyA9IGRwbHlyOjpyb3dfbnVtYmVyKCksCiAgICAgICAgICAgICAgICAgIG5yb3cgPSBzcHJpbnRmKGdsdWU6OmdsdWUoIiUwe25jaGFyKG5yb3coLikpfWQiKSwgbnJvdykpICU+JQogICAgZHBseXI6OnNlbGVjdChucm93LCBkcGx5cjo6ZXZlcnl0aGluZygpKQoKICBzdl9CTkRfbWFpbiA8LSBzdl9CTkQgJT4lCiAgICBkcGx5cjo6c2VsZWN0KG5yb3csIHZhcm51bSwgVGllciwgQ2hyLCBTdGFydCwgRW5kLAogICAgICAgICAgICAgICAgICBJRCwgQk5EX0lELCBCTkRfbWF0ZSwKICAgICAgICAgICAgICAgICAgR2VuZXMsIEVmZmVjdCwgRGV0YWlsLCBTUl9QUl9hbHQsIFBsb2lkeSwgQUZfUFVSUExFKQoKICBzdl9CTkRfb3RoZXIgPC0gc3ZfQk5EICU+JQogICAgZHBseXI6OnNlbGVjdChucm93LCBBRl9CUEksIENOQywgQ04sIFNSX1BSX3JlZiwgU1Njb3JlLCBudHJ4LCBUcmFuc2NyaXB0KQoKICBzdl9CTkRfcHVycGxlIDwtIHN2X2FsbCAlPiUKICAgIGRwbHlyOjpmaWx0ZXIoVHlwZSAlaW4lIGMoIlBVUlBMRV9pbmYiKSkgJT4lCiAgICBkcGx5cjo6c2VsZWN0KFRpZXIsIENociwgU3RhcnQsIEVmZmVjdCwgRGV0YWlsLCBQbG9pZHksIENOLCBDTkMsIElEKQoKICBzdl9CTkRfbWFpbmR0IDwtIHN2X0JORF9tYWluICU+JQogICAgRFQ6OmRhdGF0YWJsZShmaWx0ZXIgPSBsaXN0KHBvc2l0aW9uID0gInRvcCIsIGNsZWFyID0gRkFMU0UsIHBsYWluID0gVFJVRSksCiAgICAgICAgICAgICAgICAgIGNsYXNzID0gImNlbGwtYm9yZGVyIGRpc3BsYXkgY29tcGFjdCIsCiAgICAgICAgICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsIGV4dGVuc2lvbnMgPSBjKCJTY3JvbGxlciIsICJCdXR0b25zIiwgIktleVRhYmxlIiksCiAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KAogICAgICAgICAgICAgICAgICAgIGNvbHVtbkRlZnMgPSBsaXN0KGxpc3QoY2xhc3NOYW1lID0gJ2R0LXJpZ2h0JywgdGFyZ2V0cyA9IGNvbF9pbmRfanMoc3Z0YWJfcmF3LCAiRW5kIikpKSwKICAgICAgICAgICAgICAgICAgICBzY3JvbGxlciA9IFRSVUUsIHNjcm9sbFkgPSA0MDAsIHNjcm9sbFggPSBUUlVFLCBhdXRvV2lkdGggPSBGQUxTRSwga2V5cyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgYnV0dG9ucyA9IGMoJ2NzdicpLCBkb20gPSAnQmxmcnRpcCcpKSAlPiUKICAgIERUOjpmb3JtYXRDdXJyZW5jeSh+IFN0YXJ0LCBjdXJyZW5jeSA9ICIiLCBpbnRlcnZhbCA9IDMsIG1hcmsgPSAiLCIsIGRpZ2l0cyA9IDApCgogIHN2X0JORF9vdGhlcmR0IDwtIHN2X0JORF9vdGhlciAlPiUKICAgIERUOjpkYXRhdGFibGUoZmlsdGVyID0gbGlzdChwb3NpdGlvbiA9ICJ0b3AiLCBjbGVhciA9IEZBTFNFLCBwbGFpbiA9IFRSVUUpLAogICAgICAgICAgICAgICAgICBjbGFzcyA9ICJjZWxsLWJvcmRlciBkaXNwbGF5IGNvbXBhY3QiLAogICAgICAgICAgICAgICAgICByb3duYW1lcyA9IEZBTFNFLCBleHRlbnNpb25zID0gYygiU2Nyb2xsZXIiLCAiQnV0dG9ucyIsICJLZXlUYWJsZSIpLAogICAgICAgICAgICAgICAgICBvcHRpb25zID0gbGlzdCgKICAgICAgICAgICAgICAgICAgICBzY3JvbGxlciA9IFRSVUUsIHNjcm9sbFkgPSA0MDAsIHNjcm9sbFggPSBUUlVFLCBrZXlzID0gVFJVRSwgYXV0b1dpZHRoID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgYnV0dG9ucyA9IGMoJ2NzdicpLCBkb20gPSAnQmxmcnRpcCcpKQoKICBzdl9CTkRfcHVycGxlZHQgPC0gc3ZfQk5EX3B1cnBsZSAlPiUKICAgIERUOjpkYXRhdGFibGUoZmlsdGVyID0gbGlzdChwb3NpdGlvbiA9ICJ0b3AiLCBjbGVhciA9IEZBTFNFLCBwbGFpbiA9IFRSVUUpLAogICAgICAgICAgICAgICAgICBjbGFzcyA9ICJjZWxsLWJvcmRlciBkaXNwbGF5IGNvbXBhY3QiLAogICAgICAgICAgICAgICAgICByb3duYW1lcyA9IEZBTFNFLCBleHRlbnNpb25zID0gYygiU2Nyb2xsZXIiLCAiQnV0dG9ucyIsICJLZXlUYWJsZSIpLAogICAgICAgICAgICAgICAgICBvcHRpb25zID0gbGlzdCgKICAgICAgICAgICAgICAgICAgICBzY3JvbGxlciA9IFRSVUUsIHNjcm9sbFkgPSA0MDAsIHNjcm9sbFggPSBUUlVFLCBhdXRvV2lkdGggPSBUUlVFLAogICAgICAgICAgICAgICAgICAgIGJ1dHRvbnMgPSBjKCdjc3YnKSwKICAgICAgICAgICAgICAgICAgICBkb20gPSAnQmxmcnRpcCcpKSAlPiUKICAgIERUOjpmb3JtYXRDdXJyZW5jeSh+IFN0YXJ0LCBjdXJyZW5jeSA9ICIiLCBpbnRlcnZhbCA9IDMsIG1hcmsgPSAiLCIsIGRpZ2l0cyA9IDApCn0KYGBgCgojIyMjIE1haW4gQ29sdW1ucwoKPGRldGFpbHM+CjxzdW1tYXJ5PkRlc2NyaXB0aW9uPC9zdW1tYXJ5PgoKYGBge3J9CmlmICghbm9fc3ZfZm91bmQpIHsKICBzdl9kZXRhaWxfdGFibGUoc3ZfQk5EX21haW4pCn0gZWxzZSB7CiAgY2F0KCJObyBTVnMgY2FsbGVkLiIpCn0KYGBgCgo8L2RldGFpbHM+CgpgYGB7ciBzdl9CTkRfbWFpbmR0fQppZiAoIW5vX3N2X2ZvdW5kKSB7CiAgc3ZfQk5EX21haW5kdAp9IGVsc2UgewogIGNhdCgiTm8gU1ZzIGNhbGxlZC4iKQp9CgpgYGAKCiMjIyMgT3RoZXIgQ29sdW1ucwoKPGRldGFpbHM+CjxzdW1tYXJ5PkRlc2NyaXB0aW9uPC9zdW1tYXJ5PgoKYGBge3J9CmlmICghbm9fc3ZfZm91bmQpIHsKICBzdl9kZXRhaWxfdGFibGUoc3ZfQk5EX290aGVyKQp9IGVsc2UgewogIGNhdCgiTm8gU1ZzIGNhbGxlZC4iKQp9CmBgYAoKPC9kZXRhaWxzPgoKYGBge3Igc3ZfQk5EX290aGVyZHR9CmlmICghbm9fc3ZfZm91bmQpIHsKICBzdl9CTkRfb3RoZXJkdAp9IGVsc2UgewogIGNhdCgiTm8gU1ZzIGNhbGxlZC4iKQp9CmBgYAoKIyMjIyBQVVJQTEUgSW5mZXJyZWQKCjxkZXRhaWxzPgo8c3VtbWFyeT5EZXNjcmlwdGlvbjwvc3VtbWFyeT4KCmBgYHtyfQppZiAoIW5vX3N2X2ZvdW5kKSB7CiAgc3ZfZGV0YWlsX3RhYmxlKHN2X0JORF9wdXJwbGUpCn0gZWxzZSB7CiAgY2F0KCJObyBTVnMgY2FsbGVkLiIpCn0KYGBgCgo8L2RldGFpbHM+CgpgYGB7ciBzdl9CTkRfcHVycGxlZHR9CmlmICghbm9fc3ZfZm91bmQpIHsKICBzdl9CTkRfcHVycGxlZHQKfSBlbHNlIHsKICBjYXQoIk5vIFNWcyBjYWxsZWQuIikKfQpgYGAKCiMjIyBERUwvRFVQL0lOUyB7LnRhYnNldCAudGFic2V0LWZhZGUgI2RlbGR1cGluc30KCmBgYHtyIHN2dGFiX25vQk5EfQppZiAoIW5vX3N2X2ZvdW5kKSB7CiAgc3Zfbm9CTkQgPC0gc3ZfYWxsICU+JQogICAgZHBseXI6OmZpbHRlcighVHlwZSAlaW4lIGMoIkJORCIsICJQVVJQTEVfaW5mIikpICU+JQogICAgZHBseXI6Om11dGF0ZShucm93ID0gZHBseXI6OnJvd19udW1iZXIoKSwKICAgICAgICAgICAgICAgICAgbnJvdyA9IHNwcmludGYoZ2x1ZTo6Z2x1ZSgiJTB7bmNoYXIobnJvdyguKSl9ZCIpLCBucm93KSwKICAgICAgICAgICAgICAgICAgR2VuZXNfb3JpZ2luYWwgPSBHZW5lcywKICAgICAgICAgICAgICAgICAgVHJhbnNjcmlwdF9vcmlnaW5hbCA9IFRyYW5zY3JpcHQpICU+JQogICAgZHBseXI6OnNlbGVjdCgtSUQpCgogIG1heF9nZW5lcyA8LSAyCiAgbWF4X3RyYW5zY3JpcHRzIDwtIDIKCiAgc3Zfbm9CTkRfbWFpbiA8LSBzdl9ub0JORCAlPiUKICAgIGRwbHlyOjptdXRhdGUoR2VuZXMgPSBpZmVsc2UobmdlbiA+IG1heF9nZW5lcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2x1ZTo6Z2x1ZSgiTWFueSBHZW5lcyAoe25nZW59KSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcyksCiAgICAgICAgICAgICAgICAgIFRyYW5zY3JpcHQgPSBpZmVsc2UobnRyeCA+IG1heF90cmFuc2NyaXB0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbHVlOjpnbHVlKCJNYW55IFRyYW5zY3JpcHRzICh7bnRyeH0pIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJhbnNjcmlwdCkpICU+JQogICAgZHBseXI6OnNlbGVjdChucm93LCB2YXJudW0sIFRpZXJUb3AsIFRpZXIsIFR5cGUsIENociwgU3RhcnQsIEVuZCwgRWZmZWN0LAogICAgICAgICAgICAgICAgICBHZW5lcywgVHJhbnNjcmlwdCwgRGV0YWlsLCBTUl9QUl9hbHQsIEFGX1BVUlBMRSkKCiAgc3Zfbm9CTkRfb3RoZXIgPC0gc3Zfbm9CTkQgJT4lCiAgICBkcGx5cjo6c2VsZWN0KHZhcm51bSwgUGxvaWR5LCBBRl9CUEksIENOQywgQ04sIFNSX1BSX3JlZiwgU1Njb3JlKSAlPiUKICAgIGRwbHlyOjpkaXN0aW5jdCgpCgogIHN2X25vQk5EX21hbnlnZW5lcyA8LSBzdl9ub0JORCAlPiUKICAgIGRwbHlyOjpmaWx0ZXIobmdlbiA+IG1heF9nZW5lcykgJT4lCiAgICBkcGx5cjo6c2VsZWN0KG5yb3csIHZhcm51bSwgVGllciwgVHlwZSwgQ2hyLCBTdGFydCwgRW5kLAogICAgICAgICAgICAgICAgICBFZmZlY3QsIG5nZW4sIEdlbmVzID0gR2VuZXNfb3JpZ2luYWwpCgogIHN2X25vQk5EX21hbnl0eCA8LSBzdl9ub0JORCAlPiUKICAgIGRwbHlyOjpmaWx0ZXIobnRyeCA+IG1heF90cmFuc2NyaXB0cykgJT4lCiAgICBkcGx5cjo6c2VsZWN0KG5yb3csIHZhcm51bSwgVGllciwgVHlwZSwgQ2hyLCBTdGFydCwgRW5kLAogICAgICAgICAgICAgICAgICBFZmZlY3QsIG50cngsIFRyYW5zY3JpcHQgPSBUcmFuc2NyaXB0X29yaWdpbmFsKQoKICBzdl9ub0JORF9tYWluZHQgPC0gc3Zfbm9CTkRfbWFpbiAlPiUKICAgIERUOjpkYXRhdGFibGUoZmlsdGVyID0gbGlzdChwb3NpdGlvbiA9ICJ0b3AiLCBjbGVhciA9IEZBTFNFLCBwbGFpbiA9IFRSVUUpLAogICAgICAgICAgICAgICAgICBjbGFzcyA9ICJjZWxsLWJvcmRlciBkaXNwbGF5IGNvbXBhY3QiLAogICAgICAgICAgICAgICAgICByb3duYW1lcyA9IEZBTFNFLCBleHRlbnNpb25zID0gYygiQnV0dG9ucyIpLAogICAgICAgICAgICAgICAgICBvcHRpb25zID0gbGlzdCgKICAgICAgICAgICAgICAgICAgICBjb2x1bW5EZWZzID0gbGlzdChsaXN0KGNsYXNzTmFtZSA9ICdkdC1yaWdodCcsIHRhcmdldHMgPSBjb2xfaW5kX2pzKHN2dGFiX3JhdywgIkVuZCIpKSksCiAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IDIwLAogICAgICAgICAgICAgICAgICAgIGF1dG9XaWR0aCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgIGJ1dHRvbnMgPSBjKCdjc3YnKSwgZG9tID0gJ0JsZnJ0aXAnKSkgJT4lCiAgICBEVDo6Zm9ybWF0Q3VycmVuY3kofiBTdGFydCwgY3VycmVuY3kgPSAiIiwgaW50ZXJ2YWwgPSAzLCBtYXJrID0gIiwiLCBkaWdpdHMgPSAwKQoKICBzdl9ub0JORF9vdGhlcmR0IDwtIHN2X25vQk5EX290aGVyICU+JQogICAgRFQ6OmRhdGF0YWJsZShmaWx0ZXIgPSBsaXN0KHBvc2l0aW9uID0gInRvcCIsIGNsZWFyID0gRkFMU0UsIHBsYWluID0gVFJVRSksCiAgICAgICAgICAgICAgICAgIGNsYXNzID0gImNlbGwtYm9yZGVyIGRpc3BsYXkgY29tcGFjdCIsCiAgICAgICAgICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsIGV4dGVuc2lvbnMgPSBjKCJCdXR0b25zIiksCiAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KAogICAgICAgICAgICAgICAgICAgIHBhZ2VMZW5ndGggPSAyMCwKICAgICAgICAgICAgICAgICAgICBhdXRvV2lkdGggPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICBidXR0b25zID0gYygnY3N2JyksCiAgICAgICAgICAgICAgICAgICAgZG9tID0gJ0JsZnJ0aXAnKSkKCiAgc3Zfbm9CTkRfbWFueWdlbmVzZHQgPC0gc3Zfbm9CTkRfbWFueWdlbmVzICU+JQogICAgRFQ6OmRhdGF0YWJsZShmaWx0ZXIgPSBsaXN0KHBvc2l0aW9uID0gInRvcCIsIGNsZWFyID0gRkFMU0UsIHBsYWluID0gVFJVRSksCiAgICAgICAgICAgICAgICAgIGNsYXNzID0gImNlbGwtYm9yZGVyIGRpc3BsYXkgY29tcGFjdCIsCiAgICAgICAgICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsIGV4dGVuc2lvbnMgPSBjKCJCdXR0b25zIiwgIktleVRhYmxlIiksCiAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KAogICAgICAgICAgICAgICAgICAgIGNvbHVtbkRlZnMgPSBsaXN0KGxpc3QoY2xhc3NOYW1lID0gJ2R0LXJpZ2h0JywgdGFyZ2V0cyA9IGNvbF9pbmRfanMoc3Z0YWJfcmF3LCAiRW5kIikpKSwKICAgICAgICAgICAgICAgICAgICBwYWdlTGVuZ3RoID0gMTAsCiAgICAgICAgICAgICAgICAgICAgYXV0b1dpZHRoID0gRkFMU0UsIGtleXMgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgIGJ1dHRvbnMgPSBjKCdjc3YnKSwKICAgICAgICAgICAgICAgICAgICBkb20gPSAnQmxmcnRpcCcpKSAlPiUKICAgIERUOjpmb3JtYXRDdXJyZW5jeSh+IFN0YXJ0LCBjdXJyZW5jeSA9ICIiLCBpbnRlcnZhbCA9IDMsIG1hcmsgPSAiLCIsIGRpZ2l0cyA9IDApCgogIHN2X25vQk5EX21hbnl0eGR0IDwtIHN2X25vQk5EX21hbnl0eCAlPiUKICAgIERUOjpkYXRhdGFibGUoZmlsdGVyID0gbGlzdChwb3NpdGlvbiA9ICJ0b3AiLCBjbGVhciA9IEZBTFNFLCBwbGFpbiA9IFRSVUUpLAogICAgICAgICAgICAgICAgICBjbGFzcyA9ICJjZWxsLWJvcmRlciBkaXNwbGF5IGNvbXBhY3QiLAogICAgICAgICAgICAgICAgICByb3duYW1lcyA9IEZBTFNFLCBleHRlbnNpb25zID0gYygiQnV0dG9ucyIsICJLZXlUYWJsZSIpLAogICAgICAgICAgICAgICAgICBvcHRpb25zID0gbGlzdCgKICAgICAgICAgICAgICAgICAgICBjb2x1bW5EZWZzID0gbGlzdChsaXN0KGNsYXNzTmFtZSA9ICdkdC1yaWdodCcsIHRhcmdldHMgPSBjb2xfaW5kX2pzKHN2dGFiX3JhdywgIkVuZCIpKSksCiAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IDEwLAogICAgICAgICAgICAgICAgICAgIGF1dG9XaWR0aCA9IEZBTFNFLCBrZXlzID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICBidXR0b25zID0gYygnY3N2JyksCiAgICAgICAgICAgICAgICAgICAgZG9tID0gJ0JsZnJ0aXAnKSkgJT4lCiAgICBEVDo6Zm9ybWF0Q3VycmVuY3kofiBTdGFydCwgY3VycmVuY3kgPSAiIiwgaW50ZXJ2YWwgPSAzLCBtYXJrID0gIiwiLCBkaWdpdHMgPSAwKQp9CmBgYAoKIyMjIyBNYWluIENvbHVtbnMKCjxkZXRhaWxzPgo8c3VtbWFyeT5EZXNjcmlwdGlvbjwvc3VtbWFyeT4KCmBgYHtyfQppZiAoIW5vX3N2X2ZvdW5kKSB7CiAgc3ZfZGV0YWlsX3RhYmxlKHN2X25vQk5EX21haW4pCn0gZWxzZSB7CiAgY2F0KCJObyBTVnMgY2FsbGVkLiIpCn0KYGBgCgo8L2RldGFpbHM+CgpgYGB7ciBzdl9ub0JORF9tYWluZHR9CmlmICghbm9fc3ZfZm91bmQpIHsKICBzdl9ub0JORF9tYWluZHQKfSBlbHNlIHsKICBjYXQoIk5vIFNWcyBjYWxsZWQuIikKfQpgYGAKCiMjIyMgT3RoZXIgQ29sdW1ucwoKPGRldGFpbHM+CjxzdW1tYXJ5PkRlc2NyaXB0aW9uPC9zdW1tYXJ5PgoKYGBge3J9CmlmICghbm9fc3ZfZm91bmQpIHsKICBzdl9kZXRhaWxfdGFibGUoc3Zfbm9CTkRfb3RoZXIpCn0gZWxzZSB7CiAgY2F0KCJObyBTVnMgY2FsbGVkLiIpCn0KYGBgCgo8L2RldGFpbHM+CgpgYGB7ciBzdl9ub0JORDJfZHR9CmlmICghbm9fc3ZfZm91bmQpIHsKICBzdl9ub0JORF9vdGhlcmR0Cn0gZWxzZSB7CiAgY2F0KCJObyBTVnMgY2FsbGVkLiIpCn0KYGBgCgojIyMjIE1hbnkgR2VuZXMKCjxkZXRhaWxzPgo8c3VtbWFyeT5EZXNjcmlwdGlvbjwvc3VtbWFyeT4KCmBgYHtyfQppZiAoIW5vX3N2X2ZvdW5kKSB7CiAgc3ZfZGV0YWlsX3RhYmxlKHN2X25vQk5EX21hbnlnZW5lcykKfSBlbHNlIHsKICBjYXQoIk5vIFNWcyBjYWxsZWQuIikKfQpgYGAKCjwvZGV0YWlscz4KCmBgYHtyIHN2X25vQk5EX21hbnlnZW5lc2R0fQppZiAoIW5vX3N2X2ZvdW5kKSB7CiAgc3Zfbm9CTkRfbWFueWdlbmVzZHQKfSBlbHNlIHsKICBjYXQoIk5vIFNWcyBjYWxsZWQuIikKfQpgYGAKCiMjIyMgTWFueSBUcmFuc2NyaXB0cwoKPGRldGFpbHM+CjxzdW1tYXJ5PkRlc2NyaXB0aW9uPC9zdW1tYXJ5PgoKYGBge3J9CmlmICghbm9fc3ZfZm91bmQpIHsKICBzdl9kZXRhaWxfdGFibGUoc3Zfbm9CTkRfbWFueXR4KQp9IGVsc2UgewogIGNhdCgiTm8gU1ZzIGNhbGxlZC4iKQp9CmBgYAoKPC9kZXRhaWxzPgoKYGBge3Igc3Zfbm9CTkRfbWFueXR4ZHR9CmlmICghbm9fc3ZfZm91bmQpIHsKICBzdl9ub0JORF9tYW55dHhkdAp9IGVsc2UgewogIGNhdCgiTm8gU1ZzIGNhbGxlZC4iKQp9CmBgYAoKIyMgQ29weSBOdW1iZXIgVmFyaWFudHMgeyNjbnYtcWN9ClRoZSBwdXJpdHkgYW5kIHBsb2lkeSBlc3RpbWF0b3IKW1BVUlBMRV0oaHR0cHM6Ly9naXRodWIuY29tL2hhcnR3aWdtZWRpY2FsL2htZnRvb2xzL3RyZWUvbWFzdGVyL3B1cml0eS1wbG9pZHktZXN0aW1hdG9yKQppcyB1c2VkIHRvIGdlbmVyYXRlIGEgY29weSBudW1iZXIgcHJvZmlsZSBmb3IgdGhlIHNvbWF0aWMgc2FtcGxlLgoKIyMjIFFDLCBQdXJpdHkgYW5kIFBsb2lkeSBTdW1tYXJ5CgpQVVJQTEUgb3V0cHV0cyBhIFFDIHN0YXR1cyBhbG9uZyB3aXRoIGEgc3VtbWFyeQpmb3IgdGhlIGluZmVycmVkIHB1cml0eSBhbmQgcGxvaWR5IG9mIHRoZSBzb21hdGljIHNhbXBsZS4KQSBmYWlsZWQgUUMgc3RhdHVzIGNhbiBiZSBhdHRyaWJ1dGVkIHRvIHNldmVyYWwgZmFjdG9ycwooc2VlIGBEZXNjcmlwdGlvbmAgYmVsb3cpLgoKPGRldGFpbHM+CjxzdW1tYXJ5PkRlc2NyaXB0aW9uPC9zdW1tYXJ5PgoKX19RQyBTdGF0dXNfXwoKVGhlIFFDIFN0YXR1cyBmaWVsZCByZWZsZWN0cyBob3cgd2UgaGF2ZSBkZXRlcm1pbmVkIHRoZSBwdXJpdHkgb2YgdGhlIHNhbXBsZToKCiogYE5PUk1BTGAgLSBQVVJQTEUgZml0IHRoZSBwdXJpdHkgdXNpbmcgQ09CQUxUIGFuZCBBTUJFUiBvdXRwdXQuCiogYEhJR0hMWV9ESVBMT0lEYCAtIFRoZSBmaXR0ZWQgcHVyaXR5IHNvbHV0aW9uIGlzIGhpZ2hseSBkaXBsb2lkICg+IDk1JSkKICB3aXRoIGEgbGFyZ2UgcmFuZ2Ugb2YgcG90ZW50aWFsIHNvbHV0aW9ucywgYnV0IHNvbWF0aWMgdmFyaWFudHMgYXJlIHVuYWJsZSB0bwogIGhlbHAgZWl0aGVyIGJlY2F1c2UgdGhleSB3ZXJlIG5vdCBzdXBwbGllZCBvciBiZWNhdXNlIHRoZWlyIGltcGxpZWQgcHVyaXR5IHdhcyB0b28gbG93LgoqIGBTT01BVElDYCAtIFNvbWF0aWMgdmFyaWFudHMgaGF2ZSBpbXByb3ZlZCB0aGUgb3RoZXJ3aXNlIGhpZ2hseSBkaXBsb2lkIHNvbHV0aW9uLgoqIGBOT19UVU1PUmAgLSBQVVJQTEUgZmFpbGVkIHRvIGZpbmQgYW55IGFuZXVwbG9pZHkgYW5kIHNvbWF0aWMgdmFyaWFudHMgd2VyZQogIHN1cHBsaWVkIGJ1dCB0aGVyZSB3ZXJlIGZld2VyIHRoYW4gMzAwIHdpdGggb2JzZXJ2ZWQgVkFGID4gMC4xLgoKX19RQyBGYWlsdXJlX18KClRoZXJlIGFyZSBzZXZlcmFsIHJlYXNvbnMgUFVSUExFIG1heSBjbGFzc2lmeSBhIHNhbXBsZSBhcyBmYWlsZWQ6CgoqIGBGQUlMX1NFR01FTlRgOiBtb3JlIHRoYW4gMjIwIGNvcHkgbnVtYmVyIHNlZ21lbnRzIF9fbm90X18gc3VwcG9ydGVkIGF0IGVpdGhlciBlbmQKICBieSBTViBicmVha3BvaW50cy4gSW5kaWNhdGVzIHNhbXBsZXMgd2l0aCBleHRyZW1lIEdDIGJpYXMsIHdpdGggZGlmZmVyZW5jZXMKICBpbiBkZXB0aCBvZiA+PSAxMHggYmV0d2VlbiBoaWdoIGFuZCBsb3cgR0MgcmVnaW9ucy4gR0Mgbm9ybWFsaXNhdGlvbiBpcwogIHVucmVsaWFibGUgd2hlbiB0aGUgY29ycmVjdGlvbnMgYXJlIHNvIGV4dHJlbWUgc28gaXQgaXMgcmVjb21tZW5kZWQgdG8gZmFpbAogIHRoZSBzYW1wbGUgKGNvbmNlcm5zIHdpdGggbWlzY2FsbGVkIGRlbGV0aW9ucyBvciBhbXBsaWZpY2F0aW9ucyBvciBoYXZlCiAgcG9vciBzZW5zaXRpdml0eSBpbiBoaWdoIEdDIHJlZ2lvbnMuCiogYE5PX1RVTU9SYDogbm8gYW5ldXBsb2lkeSBmb3VuZCBhbmQgdGhlIG51bWJlciBvZiBzb21hdGljIFNOVnMgZm91bmQgaXMKICBsZXNzIHRoYW4gMSwwMDAKKiBgTUlOX1BVUklUWWA6IGZpdHRlZCBwdXJpdHkgPCAyMCUKKiBgRkFJTF9ERUxFVEVEX0dFTkVTYDogbW9yZSB0aGFuIDI4MCBkZWxldGVkIGdlbmVzLiBUaGlzIFFDIHN0ZXAgd2FzIGFkZGVkCiAgYWZ0ZXIgb2JzZXJ2aW5nIHRoYXQgaW4gYSBoYW5kZnVsIG9mIHNhbXBsZXMgd2l0aCBoaWdoIE1CIHNjYWxlIHBvc2l0aXZlIEdDCiAgYmlhcyB3ZSBzb21ldGltZXMgc3lzdGVtYXRpY2FsbHkgdW5kZXJlc3RpbWF0ZSB0aGUgY29weSBudW1iZXIgaW4gaGlnaCBHQwogIHJlZ2lvbnMuIFRoaXMgY2FuIGxlYWQgdXMgdG8gaW5jb3JyZWN0bHkgaW5mZXIgaG9tb3p5Z291cyBsb3NzIG9mIGVudGlyZQogIGNocm9tb3NvbWVzLCBwYXJ0aWN1bGFybHkgb24gY2hyb21vc29tZXMgMTcgYW5kIDE5LgoqIGBGQUlMX0dFTkRFUmA6IGlmIHRoZSBBTUJFUiBhbmQgQ09CQUxUIGluZmVycmVkIGdlbmRlcnMgYXJlIGluY29uc2lzdGVudAogIHRoZW4gdGhlIENPQkFMVCBvbmUgaXMgdXNlZCBidXQgdGhlIHNhbXBsZSBpcyBmYWlsZWQuCgo8L2RldGFpbHM+Cgo8cD4mbmJzcDs8L3A+CgpgYGB7ciBwdXJwbGVfcWNfc3VtbWFyeX0KcHVycGxlX3FjX3N1bW1hcnkgJT4lCiAgZHBseXI6Om11dGF0ZSgKICAgIFZhcmlhYmxlID0ga2FibGVFeHRyYTo6Y2VsbF9zcGVjKFZhcmlhYmxlLCBib2xkID0gVFJVRSksCiAgICB2YWx1ZSA9IGthYmxlRXh0cmE6OmNlbGxfc3BlYyh2YWx1ZSwgYm9sZCA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGRwbHlyOjpjYXNlX3doZW4oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID09ICJQQVNTIiB+ICJncmVlbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyZXBsKCJGQUlMIiwgdmFsdWUpIH4gInJlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID09ICJGRU1BTEUiIH4gInB1cnBsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID09ICJNQUxFIiB+ICJibHVlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPT0gIk1BTEVfS0xJTkVGRUxURVIiIH4gInJlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID09ICJUUlVFIiB+ICJncmVlbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID09ICJGQUxTRSIgfiAicmVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+ICJibGFjayIpKSkgJT4lCiAga25pdHI6OmthYmxlKGVzY2FwZSA9IEZBTFNFKSAlPiUKICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBGQUxTRSwgcG9zaXRpb24gPSAibGVmdCIpCmBgYAoKIyMjIFVNQ0NSIEdlbmUgQ05WIENhbGxzIHsjY252LWdlbmV9Cgo8ZGV0YWlscz4KPHN1bW1hcnk+RGVzY3JpcHRpb248L3N1bW1hcnk+CgpQVVJQTEUgY29weSBudW1iZXIgYWx0ZXJhdGlvbnMgaW4gdGhlIFVNQ0NSIENhbmNlciBHZW5lIHBhbmVsICh+MSwyMDAgZ2VuZXMpIC0gZGVzY3JpcHRpb24KaXMgZnJvbSA8aHR0cHM6Ly9naXRodWIuY29tL2hhcnR3aWdtZWRpY2FsL2htZnRvb2xzL2Jsb2IvbWFzdGVyL3B1cml0eS1wbG9pZHktZXN0aW1hdG9yL1JFQURNRS5tZCNnZW5lLWNvcHktbnVtYmVyLWZpbGU+CgpgYGB7ciBwdXJwbGVfZ2VuZV9jbnZfZGVzY3JpcHRpb259CmRwbHlyOjp0cmliYmxlKAogIH5Db2x1bW4sIH5EZXNjcmlwdGlvbiwKICAiZ2VuZSIsICJOYW1lIG9mIGdlbmUiLAogICJtaW5DTi9tYXhDTiIsICJNaW4vTWF4IGNvcHkgbnVtYmVyIGZvdW5kIGluIGdlbmUgZXhvbnMiLAogICJjaHJvbS9zdGFydC9lbmQiLCAiQ2hyb21vc29tZS9zdGFydC9lbmQgbG9jYXRpb24gb2YgZ2VuZSB0cmFuc2NyaXB0IiwKICAiY2hyQmFuZCIsICJDaHJvbW9zb21lIGJhbmQgb2YgdGhlIGdlbmUiLAogICJvbmNvX29yX3RzIiwgIm9uY29nZW5lICgnb25jb2dlbmUnKSwgdHVtb3Igc3VwcHJlc3NvciAoJ3RzZ2VuZScpLCBvciBib3RoICgnb25jbyt0cycpLCBhcyByZXBvcnRlZCBieSBbQ2FuY2VybWluZV0oaHR0cHM6Ly9naXRodWIuY29tL2pha2VsZXZlci9jYW5jZXJtaW5lKSIsCiAgInRyYW5zY3JpcHRJRCIsICJFbnNlbWJsIHRyYW5zY3JpcHQgSUQgKGRvdCB2ZXJzaW9uKSIsCiAgIm1pbk1pbm9yQWxsZWxlUGxvaWR5IiwgIk1pbmltdW0gYWxsZWxlIHBsb2lkeSBmb3VuZCBvdmVyIHRoZSBnZW5lIGV4b25zIC0gdXNlZnVsIGZvciBpZGVudGlmeWluZyBMT0ggZXZlbnRzIiwKICAic29tUmVnIChzb21hdGljUmVnaW9ucykiLCAiQ291bnQgb2Ygc29tYXRpYyBjb3B5IG51bWJlciByZWdpb25zIHRoaXMgZ2VuZSBzcGFucyIsCiAgImdlcm1EZWxSZWcgKGdlcm1saW5lSG9tRGVsZXRpb25SZWdpb25zIC8gZ2VybWxpbmVIZXRUb0hvbURlbGV0aW9uUmVnaW9ucykiLCAiTnVtYmVyIG9mIHJlZ2lvbnMgc3Bhbm5lZCBieSB0aGlzIGdlbmUgdGhhdCBhcmUgKGhvbW96eWdvdXNseSBkZWxldGVkIGluIHRoZSBnZXJtbGluZSAvIGJvdGggaGV0ZXJvenlnb3VzbHkgZGVsZXRlZCBpbiB0aGUgZ2VybWxpbmUgYW5kIGhvbW96eWdvdXNseSBkZWxldGVkIGluIHRoZSB0dW1vcikiLAogICJtaW5SZWcgKG1pblJlZ2lvbnMpIiwgIk51bWJlciBvZiBzb21hdGljIHJlZ2lvbnMgaW5zaWRlIHRoZSBnZW5lIHRoYXQgc2hhcmUgdGhlIG1pbiBjb3B5IG51bWJlciIsCiAgIm1pblJlZ1N0YXJ0RW5kIiwgIlN0YXJ0L0VuZCBiYXNlIG9mIHRoZSBjb3B5IG51bWJlciByZWdpb24gb3ZlcmxhcHBpbmcgdGhlIGdlbmUgd2l0aCB0aGUgbWluaW11bSBjb3B5IG51bWJlciIsCiAgIm1pblJlZ1N1cHBvcnRTdGFydEVuZE1ldGhvZCIsICJTdGFydC9lbmQgc3VwcG9ydCBvZiB0aGUgQ04gcmVnaW9uIG92ZXJsYXBwaW5nIHRoZSBnZW5lIHdpdGggdGhlIG1pbiBDTiAocGx1cyBkZXRlcm1pbmF0aW9uIG1ldGhvZCkiCikgJT4lCiAgZHBseXI6Om11dGF0ZSgKICAgIENvbHVtbiA9IGthYmxlRXh0cmE6OmNlbGxfc3BlYyhDb2x1bW4sIGJvbGQgPSBUUlVFKSkgJT4lCiAga25pdHI6OmthYmxlKGVzY2FwZSA9IEZBTFNFKSAlPiUKICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBGQUxTRSwgcG9zaXRpb24gPSAibGVmdCIpICU+JQogIGthYmxlRXh0cmE6OnNjcm9sbF9ib3goaGVpZ2h0ID0gIjIwMHB4IikKYGBgCgo8L2RldGFpbHM+Cgo8cD4mbmJzcDs8L3A+CgpgYGB7ciBwdXJwbGVfZ2VuZV9jbnZfdGFifQpwdXJwbGVfZ2VuZV9jbnYgJT4lCiAgRFQ6OmRhdGF0YWJsZShmaWx0ZXIgPSBsaXN0KHBvc2l0aW9uID0gInRvcCIsIGNsZWFyID0gRkFMU0UsIHBsYWluID0gVFJVRSksCiAgICAgICAgICAgICAgICBjbGFzcyA9ICJjZWxsLWJvcmRlciBkaXNwbGF5IGNvbXBhY3QiLAogICAgICAgICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwgZXh0ZW5zaW9ucyA9IGMoIlNjcm9sbGVyIiwgIkJ1dHRvbnMiLCAiS2V5VGFibGUiKSwKICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNjcm9sbGVyID0gVFJVRSwgc2Nyb2xsWSA9IDQwMCwgc2Nyb2xsWCA9IFRSVUUsIGF1dG9XaWR0aCA9IFRSVUUsIGtleXMgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnV0dG9ucyA9IGMoJ2NzdicsICdleGNlbCcpLCBkb20gPSAnQmZydGlwJykpICU+JQogIERUOjpmb3JtYXRDdXJyZW5jeSh+IHN0YXJ0ICsgZW5kLCBjdXJyZW5jeSA9ICIiLCBpbnRlcnZhbCA9IDMsIG1hcmsgPSAiLCIsIGRpZ2l0cyA9IDApICU+JQogIERUOjpmb3JtYXRSb3VuZCh+IG1pbkNOICsgbWF4Q04sIGRpZ2l0cyA9IDEpCmBgYAoKIyMjIEdlbm9tZS13aWRlIENOViBTZWdtZW50cyB7I2Nudi1zZWdzfQoKPGRldGFpbHM+CjxzdW1tYXJ5PkRlc2NyaXB0aW9uPC9zdW1tYXJ5PgoKUFVSUExFIG91dHB1dHMgYSBmaWxlIHdpdGggdGhlIGNvcHkgbnVtYmVyIHByb2ZpbGUgb2YgYWxsIGNvbnRpZ3VvdXMgc2VnbWVudHMKb2YgdGhlIHR1bW9yIHNhbXBsZToKClBVUlBMRSBjb3B5IG51bWJlciBwcm9maWxlIG9mIGFsbCAoY29udGlndW91cykgc2VnbWVudHMgb2YgdGhlIHR1bW9yIHNhbXBsZSAtIGRlc2NyaXB0aW9uCmlzIGZyb20gPGh0dHBzOi8vZ2l0aHViLmNvbS9oYXJ0d2lnbWVkaWNhbC9obWZ0b29scy9ibG9iL21hc3Rlci9wdXJpdHktcGxvaWR5LWVzdGltYXRvci9SRUFETUUubWQjY29weS1udW1iZXItZmlsZT4KCgpgYGB7ciBwdXJwbGVfc2VnX2Rlc2NyaXB0aW9ufQpkcGx5cjo6dHJpYmJsZSgKICB+Q29sdW1uLCB+RGVzY3JpcHRpb24sCiAgIkNoci9TdGFydC9FbmQiLCAiQ29vcmRpbmF0ZXMgb2YgY29weSBudW1iZXIgc2VnbWVudCIsCiAgIkNOIiwgIkZpdHRlZCBhYnNvbHV0ZSBjb3B5IG51bWJlciBvZiBzZWdtZW50IGFkanVzdGVkIGZvciBwdXJpdHkgYW5kIHBsb2lkeSIsCiAgIlBsb2lkeSBNaW4rTWFqIiwgIlBsb2lkeSBvZiBtaW5vciArIG1ham9yIGFsbGVsZSBhZGp1c3RlZCBmb3IgcHVyaXR5IiwKICAiQkFGIiwgIlR1bW9yIEJBRiBhZnRlciBhZGp1c3RlZCBmb3IgcHVyaXR5IGFuZCBwbG9pZHkiLAogICJCYWZDb3VudCIsICJDb3VudCBvZiBBTUJFUiBiYWYgcG9pbnRzIGNvdmVyZWQgYnkgdGhpcyBzZWdtZW50IiwKICAiU3RhcnQvRW5kIFNlZ1N1cHBvcnQiLCAiVHlwZSBvZiBTViBzdXBwb3J0IGZvciB0aGUgQ04gYnJlYWtwb2ludCBhdCBzdGFydC9lbmQgb2YgcmVnaW9uLiBBbGxvd2VkIHZhbHVlczogQ0VOVFJPTUVSRSwgVEVMT01FUkUsIElOViwgREVMLCBEVVAsIEJORCAodHJhbnNsb2NhdGlvbiksIFNHTCAoc2luZ2xlIGJyZWFrZW5kIFNWIHN1cHBvcnQpLCBOT05FIChubyBTViBzdXBwb3J0IGZvciBDTiBicmVha3BvaW50KSwgTVVMVCAobXVsdGlwbGUgU1Ygc3VwcG9ydCBhdCBleGFjdCBicmVha3BvaW50KSIsCiAgIk1ldGhvZCIsICJNZXRob2QgdXNlZCB0byBkZXRlcm1pbmUgdGhlIENOIG9mIHRoZSByZWdpb24uIEFsbG93ZWQgdmFsdWVzOiBCQUZfV0VJR0hURUQgKGF2ZyBvZiBhbGwgZGVwdGggd2luZG93cyBmb3IgdGhlIHJlZ2lvbiksIFNUUlVDVFVSQUxfVkFSSUFOVCAoaW5mZXJyZWQgdXNpbmcgcGxvaWR5IG9mIGZsYW5raW5nIFNWcyksIExPTkdfQVJNIChpbmZlcnJlZCBmcm9tIHRoZSBsb25nIGFybSksIEdFUk1MSU5FX0FNUExJRklDQVRJT04gKGluZmVycmVkIHVzaW5nIHNwZWNpYWwgbG9naWMgdG8gaGFuZGxlIHJlZ2lvbnMgb2YgZ2VybWxpbmUgYW1wbGlmaWNhdGlvbikiLAogICJ3aW5kb3dDb3VudCIsICJDb3VudCBvZiBDT0JBTFQgd2luZG93cyBjb3ZlcmVkIGJ5IHRoaXMgc2VnbWVudCIsCiAgIkdDIiwgIlByb3BvcnRpb24gb2Ygc2VnbWVudCB0aGF0IGlzIEcgb3IgQyIpICU+JQogIGRwbHlyOjptdXRhdGUoCiAgICBDb2x1bW4gPSBrYWJsZUV4dHJhOjpjZWxsX3NwZWMoQ29sdW1uLCBib2xkID0gVFJVRSkpICU+JQogIGtuaXRyOjprYWJsZShlc2NhcGUgPSBGQUxTRSkgJT4lCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gRkFMU0UsIHBvc2l0aW9uID0gImxlZnQiKSAlPiUKICBrYWJsZUV4dHJhOjpzY3JvbGxfYm94KGhlaWdodCA9ICIyMDBweCIpCmBgYAoKPC9kZXRhaWxzPgoKPHA+Jm5ic3A7PC9wPgoKYGBge3IgcHVycGxlX2dsb2JhbF9jbnZfdGFifQpwdXJwbGVfZ2xvYmFsX2NudiAlPiUKICBkcGx5cjo6bXV0YXRlKENociA9IGFzLmZhY3RvcihgY2hyb21vc29tZWApLAogICAgICAgICAgICAgICAgbWlub3JBbGxlbGVQbG9pZHkgPSByb3VuZChtaW5vckFsbGVsZVBsb2lkeSwgMSksCiAgICAgICAgICAgICAgICBtYWpvckFsbGVsZVBsb2lkeSA9IHJvdW5kKG1ham9yQWxsZWxlUGxvaWR5LCAxKSwKICAgICAgICAgICAgICAgIGBQbG9pZHkgTWluK01hamAgPSBwYXN0ZTAobWlub3JBbGxlbGVQbG9pZHksICIrIiwgbWFqb3JBbGxlbGVQbG9pZHkpLAogICAgICAgICAgICAgICAgY29weU51bWJlciA9IHJvdW5kKGNvcHlOdW1iZXIsIDEpLAogICAgICAgICAgICAgICAgYmFmQWRqID0gcm91bmQoYmFmLCAyKSwKICAgICAgICAgICAgICAgIGdjQ29udGVudCA9IHJvdW5kKGdjQ29udGVudCwgMiksCiAgICAgICAgICAgICAgICBgU3RhcnQvRW5kIFNlZ1N1cHBvcnRgID0gcGFzdGUwKHNlZ21lbnRTdGFydFN1cHBvcnQsICItIiwgc2VnbWVudEVuZFN1cHBvcnQpLAogICAgICAgICAgICAgICAgYEJBRiAoY291bnQpYCA9IHBhc3RlMChiYWZBZGosICIgKCIsIGJhZkNvdW50LCAiKSIpLAogICAgICAgICAgICAgICAgYEdDICh3aW5kb3dDb3VudClgID0gcGFzdGUwKGdjQ29udGVudCwgIiAoIiwgZGVwdGhXaW5kb3dDb3VudCwgIikiKSkgJT4lCiAgZHBseXI6OnNlbGVjdChDaHIsIFN0YXJ0ID0gc3RhcnQsIEVuZCA9IGVuZCwgQ04gPSBjb3B5TnVtYmVyLCBgUGxvaWR5IE1pbitNYWpgLAogICAgICAgICAgICAgICAgYFN0YXJ0L0VuZCBTZWdTdXBwb3J0YCwgTWV0aG9kID0gbWV0aG9kLCBgQkFGIChjb3VudClgLCBgR0MgKHdpbmRvd0NvdW50KWApICU+JQogIERUOjpkYXRhdGFibGUoZmlsdGVyID0gbGlzdChwb3NpdGlvbiA9ICJ0b3AiLCBjbGVhciA9IEZBTFNFLCBwbGFpbiA9IFRSVUUpLAogICAgICAgICAgICAgICAgY2xhc3MgPSAiY2VsbC1ib3JkZXIgZGlzcGxheSBjb21wYWN0IiwKICAgICAgICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsIGV4dGVuc2lvbnMgPSBjKCJTY3JvbGxlciIsICJCdXR0b25zIiwgIktleVRhYmxlIiksCiAgICAgICAgICAgICAgICBvcHRpb25zID0gbGlzdChzY3JvbGxlciA9IFRSVUUsIHNjcm9sbFkgPSA0MDAsIHNjcm9sbFggPSBUUlVFLCBhdXRvV2lkdGggPSBUUlVFLCBrZXlzID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1dHRvbnMgPSBjKCdjc3YnLCAnZXhjZWwnKSwgZG9tID0gJ0JmcnRpcCcpKSAlPiUKICBEVDo6Zm9ybWF0Q3VycmVuY3kofiBTdGFydCArIEVuZCwgY3VycmVuY3kgPSAiIiwgaW50ZXJ2YWwgPSAzLCBtYXJrID0gIiwiLCBkaWdpdHMgPSAwKQpgYGAKCiMjIyBQVVJQTEUgQ2hhcnRzIHsudGFic2V0IC50YWJzZXQtZmFkZSAjcHVycGxlLWNoYXJ0c30KUFVSUExFIGdlbmVyYXRlcyBjaGFydHMgZm9yIHN1bW1hcmlzaW5nIHR1bW9yIHNhbXBsZSBjaGFyYWN0ZXJpc3RpY3MuCkRlc2NyaXB0aW9uIGlzIGZyb20gdGhlIFtQVVJQTEUgZG9jc10oaHR0cHM6Ly9naXRodWIuY29tL2hhcnR3aWdtZWRpY2FsL2htZnRvb2xzL3RyZWUvbWFzdGVyL3B1cml0eS1wbG9pZHktZXN0aW1hdG9yI2NoYXJ0cykuCgojIyMjIENvcHkgbnVtYmVyIC8gTWlub3IgYWxsZWxlIHBsb2lkeQpUaGUgZm9sbG93aW5nIGZpZ3VyZXMgc2hvdyB0aGUgQU1CRVIgQkFGIGNvdW50IHdlaWdodGVkIGRpc3RyaWJ1dGlvbiBvZgpjb3B5IG51bWJlciBhbmQgbWlub3IgYWxsZWxlIHBsb2lkeSB0aHJvdWdob3V0IHRoZSBmaXR0ZWQgc2VnbWVudHMuCkNvcHkgbnVtYmVycyBhcmUgYnJva2VuIGRvd24gYnkgY29sb3VyIGludG8gdGhlaXIgcmVzcGVjdGl2ZSBtaW5vcgphbGxlbGUgcGxvaWR5IChNQVApIHdoaWxlIHRoZSBtaW5vciBhbGxlbGUgcGxvaWR5IGZpZ3VyZSBpcyBicm9rZW4KZG93biBieSBjb3B5IG51bWJlci4KCmBgYHtyIHB1cnBsZV9wbG90X2NvcHludW1iZXIsIG91dC53aWR0aD0iNDAlIn0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoYyhmaWxlLnBhdGgoaW1nX2RpciwgcGFzdGUwKHBhcmFtcyRiYXRjaF9uYW1lLCAnLmNvcHludW1iZXIucG5nJykpLAogICAgICAgICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoaW1nX2RpciwgcGFzdGUwKHBhcmFtcyRiYXRjaF9uYW1lLCAnLm1hcC5wbmcnKSkpKQpgYGAKCiMjIyMgUmFpbmZhbGwKSWYgYSBzb21hdGljIHZhcmlhbnQgVkNGIGhhcyBiZWVuIHN1cHBsaWVkLCBhIGZpZ3VyZSB3aWxsIGJlIHByb2R1Y2VkCnNob3dpbmcgdGhlIHNvbWF0aWMgdmFyaWFudCBwbG9pZHkgYnJva2VuIGRvd24gYnkgY29weSBudW1iZXIgYXMgd2VsbAphcyBhIHJhaW5mYWxsIHBsb3Qgd2l0aCBrYXRhZWdpcyBjbHVzdGVycyBoaWdobGlnaHRlZCBpbiBncmV5LgoKYGBge3IgcHVycGxlX3Bsb3Rfc29tYXRpYywgb3V0LndpZHRoPSI0MCUifQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhmaWxlLnBhdGgoaW1nX2RpciwgcGFzdGUwKHBhcmFtcyRiYXRjaF9uYW1lLCAnLnNvbWF0aWMucG5nJykpKQpgYGAKCmBgYHtyIHB1cnBsZV9wbG90X3NvbWF0aWNyYWluZmFsbCwgb3V0LndpZHRoPSI5MCUifQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhmaWxlLnBhdGgoaW1nX2RpciwgcGFzdGUwKHBhcmFtcyRiYXRjaF9uYW1lLCAnLnNvbWF0aWMucmFpbmZhbGwucG5nJykpKQpgYGAKCiMjIyMgUHVyaXR5L3Bsb2lkeQpUaGUgZm9sbG93aW5nICdzdW5yaXNlJyBjaGFydCBzaG93cyB0aGUgcmFuZ2Ugb2Ygc2NvcmVzIG9mIGFsbCBleGFtaW5lZCBzb2x1dGlvbnMgb2YKcHVyaXR5IGFuZCBwbG9pZHkuIENyb3NzaGFpcnMgaWRlbnRpZnkgdGhlIGJlc3QgcHVyaXR5IC8gcGxvaWR5IHNvbHV0aW9uLgoKYGBge3IgcHVycGxlX3Bsb3RfcHVyaXR5cmFuZ2UsIG91dC53aWR0aD0iNDAlIn0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoZmlsZS5wYXRoKGltZ19kaXIsIHBhc3RlMChwYXJhbXMkYmF0Y2hfbmFtZSwgJy5wdXJpdHkucmFuZ2UucG5nJykpKQpgYGAKCiMjIyMgQ2xvbmFsaXR5ClRoZSBmb2xsb3dpbmcgZGlhZ3JhbSBpbGx1c3RyYXRlcyB0aGUgY2xvbmFsaXR5IG1vZGVsIG9mIGEgdHlwaWNhbCBzYW1wbGUuCgpUaGUgdG9wIGZpZ3VyZSBzaG93cyB0aGUgaGlzdG9ncmFtIG9mIHNvbWF0aWMgcGxvaWR5IGZvciBhbGwgU05WcyBhbmQgSU5ERUxzIGluIGJsdWUuClN1cGVyaW1wb3NlZCBhcmUgcGVha3MgaW4gZGlmZmVyZW50IGNvbG91cnMgZml0dGVkIGZyb20gdGhlIHNhbXBsZSBhcyBkZXNjcmliZWQgaW4gdGhlCmRvY3Mgd2hpbGUgdGhlIGJsYWNrIGxpbmUgc2hvd3MgdGhlIG92ZXJhbGwgZml0dGVkIHBsb2lkeSBkaXN0cmlidXRpb24uIFJlZCBmaWxsZWQKcGVha3MgYXJlIGJlbG93IHRoZSAwLjg1IHN1YmNsb25hbCB0aHJlc2hvbGQuCgpXZSBjYW4gZGV0ZXJtaW5lIHRoZSBsaWtlbGlob29kIG9mIGEgdmFyaWFudCBiZWluZyBzdWJjbG9uYWwgYXQKYW55IGdpdmVuIHBsb2lkeSBhcyBzaG93biBpbiB0aGUgYm90dG9tIGhhbGYgb2YgdGhlIGZpZ3VyZS4KCmBgYHtyIHB1cnBsZV9wbG90X3NvbWF0aWNjbG9uYWxpdHksIG91dC53aWR0aD0iNTAlIn0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoZmlsZS5wYXRoKGltZ19kaXIsIHBhc3RlMChwYXJhbXMkYmF0Y2hfbmFtZSwgJy5zb21hdGljLmNsb25hbGl0eS5wbmcnKSkpCmBgYAoKIyMjIyBTZWdtZW50ClRoZSBjb250cmlidXRpb24gb2YgZWFjaCBmaXR0ZWQgc2VnbWVudCB0byB0aGUgZmluYWwgc2NvcmUgb2YgdGhlIGJlc3QgZml0IGlzIHNob3duIGluCnRoZSBmb2xsb3dpbmcgZmlndXJlLiBFYWNoIHNlZ21lbnQgaXMgZGl2aWRlZCBpbnRvIGl0cyBtYWpvciBhbmQgbWlub3IgYWxsZWxlIHBsb2lkeS4KVGhlIGFyZWEgb2YgZWFjaCBjaXJjbGUgc2hvd3MgdGhlIHdlaWdodCAoQU1CRVIgYmFmIGNvdW50KSBvZiBlYWNoIHNlZ21lbnQuCgpgYGB7ciBwdXJwbGVfcGxvdF9zZWdtZW50LCBvdXQud2lkdGg9IjQwJSJ9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGZpbGUucGF0aChpbWdfZGlyLCBwYXN0ZTAocGFyYW1zJGJhdGNoX25hbWUsICcuc2VnbWVudC5wbmcnKSkpCmBgYAoKIyMgT25jb3ZpcnVzZXMgey50YWJzZXQgLnRhYnNldC1mYWRlICNvbmNvdmlydXNlc30KCk9uY292aXJ1c2VzIGFuZCB0aGVpciBpbnRlZ3JhdGlvbiBzaXRlcy4gVmlyYWwgc2VxdWVuY2VzIGFyZSBvYnRhaW5lZCBmcm9tIHRoZQo8YSBocmVmPSJodHRwczovL2dkYy5jYW5jZXIuZ292L2Fib3V0LWRhdGEvZGF0YS1oYXJtb25pemF0aW9uLWFuZC1nZW5lcmF0aW9uL2dkYy1yZWZlcmVuY2UtZmlsZXMiPkdEQyBkYXRhYmFzZTwvYT4uCkhvc3QgZ2VuZXMgYXJlIHJlcG9ydGVkIGlmIHRoZSBpbnRlZ3JhdGlvbiBzaXRlIGZhbGxzIG9uIGEgZ2VuZSBvciBhdCBsZWFzdCBiZWZvcmUgMTAwa2JwIG9mIHRoZSBnZW5lIHN0YXJ0LgoKYGBge3Igb25jb3ZpcnVzZXNfdGFibGV9CnByZXNlbnRfdmlydXNlcyA8LSBwYXJhbXMkb25jb3ZpcmFsX3ByZXNlbnRfdmlydXNlcwpicmVha3BvaW50c190c3YgPC0gcGFyYW1zJG9uY292aXJhbF9icmVha3BvaW50c190c3YKIyBwcmVzZW50X3ZpcnVzZXMgPC0gJy9Vc2Vycy92c2F2ZWxpZXYvdG1wL29uY292aS9wcmVzZW50X3ZpcnVzZXMudHh0JwojIGJyZWFrcG9pbnRzX3RzdiA8LSAnL1VzZXJzL3ZzYXZlbGlldi90bXAvb25jb3ZpL29uY292aXJhbF9icmVha3BvaW50cy50c3YnCgppZiAoYnJlYWtwb2ludHNfdHN2ICE9ICIiICYmIGZpbGUuZXhpc3RzKGJyZWFrcG9pbnRzX3RzdikpIHsKICBicmVha3BvaW50cyA8LSByZWFkcjo6cmVhZF90c3YoYnJlYWtwb2ludHNfdHN2LCBjb2xfbmFtZXMgPSBULCBjb2xfdHlwZXMgPSAiY2NpaWNpY2NjYyIpCiAgYnJlYWtwb2ludHMgJT4lIAogICAgZHBseXI6OnNlbGVjdChDb250aWcgPSBjb250aWcsIFN0YXJ0ID0gc3RhcnQsIEVuZCA9IGVuZCwgYFJlYWQgc3VwcG9ydGAgPSBQQUlSX0NPVU5ULCBgQWZmZWN0ZWQgZ2VuZXNgID0gR2VuZXMsIGBTViB0eXBlYCA9IHN2dHlwZSwgSUQsIE1BVEVJRCkgJT4lCiAgICBEVDo6ZGF0YXRhYmxlKGZpbHRlciA9IGxpc3QocG9zaXRpb24gPSAidG9wIiwgY2xlYXIgPSBGQUxTRSwgcGxhaW4gPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgY2xhc3MgPSAiY2VsbC1ib3JkZXIgZGlzcGxheSBjb21wYWN0IiwKICAgICAgICAgICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwgZXh0ZW5zaW9ucyA9IGMoIlNjcm9sbGVyIiwgIkJ1dHRvbnMiLCAiS2V5VGFibGUiKSwKICAgICAgICAgICAgICAgICAgb3B0aW9ucyA9IGxpc3Qoc2Nyb2xsZXIgPSBUUlVFLCBzY3JvbGxZID0gNDAwLCBzY3JvbGxYID0gVFJVRSwgYXV0b1dpZHRoID0gVFJVRSwga2V5cyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1dHRvbnMgPSBjKCdjc3YnLCAnZXhjZWwnKSwgZG9tID0gJ0JmcnRpcCcpKSAlPiUKICAgIERUOjpmb3JtYXRDdXJyZW5jeSh+IFN0YXJ0ICsgRW5kLCBjdXJyZW5jeSA9ICIiLCBpbnRlcnZhbCA9IDMsIG1hcmsgPSAiLCIsIGRpZ2l0cyA9IDApCn0gZWxzZSB7CiAgdmlydXNlcyA9IHJlYWRyOjpyZWFkX2ZpbGUocHJlc2VudF92aXJ1c2VzKQogIGlmIChzdHJfbGVuZ3RoKHZpcnVzZXMpID4gMCkgewogICAgY2F0KHN0cl9jKCJEZXRlY2VkIHNpZ25pZmljYW50IHRyYWNlcyBvZiBjb250ZW50IG9mIHRoZSBmb2xsb3dpbmcgdmlydXNlczogIiwgdmlydXNlcywgIiwgaG93ZXZlciBubyBldmlkZW5jZSBvZiB2aXJhbCBpbnRlZ3JhdGlvbiBpbnRvIHRoZSBob3N0IGdlbm9tZSBpcyBvYnNlcnZlZC4iKSkKICB9IGVsc2UgewogICAgY2F0KCJObyBvbmNvdmlyYWwgY29udGVudCBkZXRlY3RlZCBpbiB0aGlzIHNhbXBsZS4iKQogIH0KfQoKYGBgCgojIyBBZGRlbmR1bSB7LnRhYnNldCAudGFic2V0LWZhZGUgI2FkZGVuZHVtfQoKPGEgaHJlZj0iI3RvcCI+QmFjayB0byB0b3A8L2E+CgojIyMgQ29uZGEgUGtncyBNYWluCgpgYGB7ciBjb25kYV9saXN0X21haW59CmNvbmRhX3BrZ3MgPC0gcmVhZHI6OnJlYWRfdGFibGUyKHBhcmFtcyRjb25kYV9saXN0LCBjb2xfbmFtZXMgPSBjKCJuYW1lIiwgInZlcnNpb24iLCAiYnVpbGQiLCAiY2hhbm5lbCIsICJlbnYiKSwgY29sX3R5cGVzID0gImNjY2NjIikgJT4lCiAgZHBseXI6OmFycmFuZ2UobmFtZSkgJT4lCiAgZHBseXI6Omdyb3VwX2J5KG5hbWUsIHZlcnNpb24sIGJ1aWxkLCBjaGFubmVsKSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKGVudnMgPSBwYXN0ZShlbnYsIGNvbGxhcHNlID0gIiwgIikpCgptYWluX3BrZ3MgPC0gYygKICAiXmNhY2FvIiwgIl5jb25wYWlyJCIsICJeY3BzciIsCiAgIl5ncmlkc3MiLCAiXmhtZnRvb2xzIiwgIl5yZWZlcmVuY2UiLCAiXmh0c2xpYiQiLAogICJebXVsdGlxYyIsICJebmdzIiwKICAicGFuZG9jIiwgIl5wY2dyIiwgIl5weXRob24kIiwKICAiXnItYmFzZSQiLCAic25ha2VtYWtlIiwKICAiXnVtY2NyaXNlJCIpICU+JQogIHBhc3RlKGNvbGxhcHNlID0gInwiKQoKY29uZGFfcGtncyAlPiUKICBkcGx5cjo6ZmlsdGVyKGdyZXBsKG1haW5fcGtncywgbmFtZSkpICU+JQogIGRwbHlyOjphcnJhbmdlKGRlc2MobmFtZSkpICU+JQogIGtuaXRyOjprYWJsZShmb3JtYXQgPSAiaHRtbCIpICU+JQogIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IFRSVUUsIHBvc2l0aW9uID0gImxlZnQiKSAlPiUKICBrYWJsZUV4dHJhOjpjb2x1bW5fc3BlYygxLCBib2xkID0gVFJVRSkgJT4lCiAga2FibGVFeHRyYTo6c2Nyb2xsX2JveChoZWlnaHQgPSAiMzAwcHgiKQpgYGAKCiMjIyBSZXBvcnQgSW5wdXRzCgpgYGB7ciByZXBvcnRfaW5wdXRzfQpkcGx5cjo6dGliYmxlKGtleSA9IG5hbWVzKHBhcmFtcyksIHZhbHVlID0gdW5saXN0KHBhcmFtcykpICU+JQogIGtuaXRyOjprYWJsZShmb3JtYXQgPSAiaHRtbCIpICU+JQogIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFLCBwb3NpdGlvbiA9ICJsZWZ0IikgJT4lCiAga2FibGVFeHRyYTo6Y29sdW1uX3NwZWMoMSwgYm9sZCA9IFRSVUUpICU+JQogIGthYmxlRXh0cmE6OnNjcm9sbF9ib3goaGVpZ2h0ID0gIjIwMHB4IikKYGBgCgojIyMgQ29uZGEgUGtncyBBbGwKCmBgYHtyIGNvbmRhX2xpc3RfYWxsfQpjb25kYV9wa2dzICU+JQogIERUOjpkYXRhdGFibGUoZmlsdGVyID0gbGlzdChwb3NpdGlvbiA9ICJ0b3AiLCBjbGVhciA9IEZBTFNFLCBwbGFpbiA9IFRSVUUpLAogICAgICAgICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwgZXh0ZW5zaW9ucyA9IGMoIlNjcm9sbGVyIiwgIkJ1dHRvbnMiKSwKICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNjcm9sbGVyID0gVFJVRSwgc2Nyb2xsWCA9IFRSVUUsIHNjcm9sbFkgPSA0MDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidXR0b25zID0gYygnY3N2JyksIGRvbSA9ICdCZnJ0aXAnKSkKYGBgCgpgYGB7ciBzZXNzaW9uX2luZm8sIGV2YWw9Rn0Kc2kgPC0gZGV2dG9vbHM6OnNlc3Npb25faW5mbyhpbmNsdWRlX2Jhc2UgPSBUUlVFKQpzaV9wbCA8LSB1bmNsYXNzKHNpJHBsYXRmb3JtKSAlPiUgYXNfdGliYmxlKCkgJT4lIHQoKQojIHNpX3BrZyA8LSB1bmNsYXNzKHNpJHBhY2thZ2VzKSAlPiUKIyAgIGRwbHlyOjphc190aWJibGUoKSAlPiUKIyAgIGRwbHlyOjpzZWxlY3QocGFja2FnZSwgdmVyc2lvbiA9IG9uZGlza3ZlcnNpb24sIHBhdGgsIGRhdGVzdGFtcCA9IGRhdGUpCgpkcGx5cjo6dGliYmxlKHZhciA9IHJvdy5uYW1lcyhzaV9wbCksCiAgICAgICAgICAgICAgdmFsdWUgPSBzaV9wbFssICwgZHJvcCA9IFRSVUVdKSAlPiUKICBrbml0cjo6a2FibGUoZm9ybWF0ID0gImh0bWwiKSAlPiUKICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBGQUxTRSwgcG9zaXRpb24gPSAibGVmdCIpICU+JQogIGthYmxlRXh0cmE6OmNvbHVtbl9zcGVjKDEsIGJvbGQgPSBUUlVFKQpgYGAKCmBgYHtyIHNlc3Npb25faW5mb19wa2dzLCBldmFsPUZ9CmtuaXRyOjprYWJsZShzaV9wa2csIGZvcm1hdCA9ICJodG1sIikgJT4lCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gVFJVRSwgcG9zaXRpb24gPSAibGVmdCIpICU+JQogIGthYmxlRXh0cmE6OmNvbHVtbl9zcGVjKDEsIGJvbGQgPSBUUlVFKSAlPiUKICBrYWJsZUV4dHJhOjpzY3JvbGxfYm94KGhlaWdodCA9ICI0MDBweCIpCmBgYAoKPHA+Jm5ic3A7PC9wPgoK