require(tidyverse)
Loading required package: tidyverse
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
── Attaching packages ──────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.0 ──
✓ ggplot2 3.3.3     ✓ purrr   0.3.4
✓ tibble  3.0.6     ✓ dplyr   1.0.4
✓ tidyr   1.1.2     ✓ stringr 1.4.0
✓ readr   1.4.0     ✓ forcats 0.5.0
── Conflicts ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
require(cowplot)
Loading required package: cowplot

Executive summary

  • A few technical things to correct in the collection of flow cytometry data, including setting the acquisition threshold, properly drawing the gate and identifying and removing problematic samples.
  • There is substantial variability in Pho4-chimera abundance as measured by mNeon intensity among the chimeric / endogenous constructs, but only in the pho2∆ background, while the same plasmids appear to be expressed to a similar level with PHO2.
  • hypotheses?
  • not necessarily real, see my 2020-12-21 vs 2020-12-23 analyses.
  • Chimera activity as measured by RFP/GFP confirms that CgPho4 is Pho2-independent while ScPho4 is dependent. But all chimera tested appear to be Pho2-dependent, in contrast to previous phosphatase assay results. Notably, part of this is due to the apparently higher expression level of the chimera.

TODO

  1. Investigate the effect of growth media (adenine and phosphate levels) on Pho4 chimera expression in pho2∆ strains.
  2. Use Western to confirm whether the higher Pho4 abundance for some chimera in pho2∆ is real, e.g. pH177
  3. Repeat this experiment to determine if the observations are reproducible.
  4. Validate the flow cytometry results with phosphatase assay (only works for yH295,6 parents)

Goal

Validate the phosphatase assay results for Xu’s Pho4 chimera using the new dual-fluorescence reporter approach.

Material and methods

Jia subcloned a set of Xu’s chimeric Pho4 plasmids into her mNeon tagged backbone (pH173) using the new Golden Gate approach. The complete list of plasmids can be found here.

All strains in the table below have pho80::Trp1

samples <- read_csv("20210310-Test-Xu-Chimeras-sample-list.csv", col_types = "ccccclc")
samples

Cells are first grown to saturation o/n in SD-leu, diluted in the morning to OD~0.2 in SD-leu and regrown for ~2 doublings. After the culture reached desired OD (mid log phase), cells were spun down and resuspended in PBS and used for flow cytometry. Voltages used are:

Detector Voltage Comments
FSC 350 mV I normally use 285 mV
SSC 350 mV NA
BL1 400 mV NA
YL2 450 mV higher than mine

Data import

dat0 <- read_csv("20210319-Bin-reanalyzed-chimera-test-1-results.csv")

── Column specification ─────────────────────────────────────────────────────────────────────
cols(
  Group = col_character(),
  Sample = col_character(),
  Rep = col_double(),
  Pho4 = col_character(),
  Pho2 = col_character(),
  Pho5RFP = col_character(),
  FP = col_logical(),
  Parameter = col_character(),
  Count = col_double(),
  Concentration = col_double(),
  Perc_total = col_double(),
  Median = col_double(),
  CV = col_double(),
  rCV = col_double()
)

Quality control

yLS_K and yJZ_B3, B4 each have one or more biological replicates that showed abnormal patterns on the FCS-H vs SSC-H – very few cells and a large number of small particles with high SSC-H and low FSC-H. See the last section of the knitted document.

ggplot(dat0, aes(x = Count, y = Concentration, shape = Pho2, color = Pho4)) + 
  geom_point(size = 2, alpha = 0.8) + 
  xlab("Total # of events recorded") + ylab("Concentration (events/s)") + 
  theme_cowplot() + background_grid() + panel_border()

Figure 1. Acquisition stats show a few samples undersampled and problematic. Concentration is measured by recorded events / second (y-axis) while total number of recorded events in the “singlet” gate is plotted on the x-axis. Samples are colored by the Pho4 genotype, and the shape reflects the status of Pho2 in the host strain. Lindsey and Jia’s samples are mixed.

Discussion

  • First of all, it appears that Lindsey and Jia didn’t correctly set the acquisition stop criteria. I suspect that they let the acquisition to stop when the number of events reach 10,000, but didn’t set the population to the “singlet” gate. By default, the criteria will apply to ALL events.
  • pH179 when transformed into the pho2∆ background appears to have trouble growing. We should consider changing the composition of the media to include additional adenine, since pho2∆ is sensitive to adenine deprivation. Also, it would be helpful to test and identify a media/growth condition in which the two host strains, with or without Pho2, grow roughly at the same rate.
  • A separate issue is that the voltage for the FSC channel is probably too large (350 mV, vs 285 in my experiments). As can be seen in the plot below, many events were cutoff of the right boundary on the FSC-H axis. While those events may not be what we want to include (seems like they have much higher SSC, but not sure if the result will look the same after lowering the voltage), we should still try adjust the FSC voltage to “bring them inside the plot”. yH156 example Figure 2. Example plots demonstrating potentially too high voltage for FSC

Filter data

issues <- c("K-1","K-2","K-3","B3-1","B3-2","B3-3","B4-1") # see below for reasons
dat <- dat0 %>% 
  mutate(id = paste(Sample, Rep, sep = "-")) %>% 
  filter(!id %in% issues) %>% 
  select(-id)

Analysis

Pho4-GFP expression levels

First look at the background fluorescence level in the GFP channel

gfp.bg <- dat %>% filter(!FP, Parameter == "chimera-GFP-H") %>% pull(Median) %>% mean()
p0 <- dat %>% 
  filter(!FP, Parameter == "chimera-GFP-H") %>% 
  ggplot(aes(x = Sample, y = Median)) + geom_col(position = position_dodge()) + 
  geom_hline(yintercept = gfp.bg, linetype = "dashed", alpha = 0.6) +
  labs(title = "Background GFP level") + ylab("MFI") + ylim(c(0, 6000)) + 
  theme_cowplot() + theme(axis.text.x = element_text(angle = 90), 
                          plot.title = element_text(hjust = 0.5))
p0

Figure 3. Background GFP in strains with no mNeon. MFI: Median fluorescent intensity. Dotted line shows the average of all negative samples and will be used for background subtraction in later analyses.

It’s good to see that all the negative strains have the same level of background in the BL1 (GFP) channel. Unfortunately we didn’t include any strain that have strong RFP but no GFP so as to evaluate the spillover of the RFP signal into the GFP channel.

Next, we can examine the Pho4-GFP levels for the different contructs, in PHO2 or pho2∆ backgrounds, and transformed into two genetic backgrounds.

p1 <- dat %>% filter(FP, Parameter == "chimera-GFP-H") %>% 
  ggplot(aes(x = Pho4, y = Median, alpha = Group)) + 
  scale_alpha_discrete("User", range = c(0.5, 1)) +
  geom_bar(aes(fill = Pho4), stat = "identity", position = position_dodge2()) + 
  stat_summary(fun = "mean", geom = "crossbar", colour = "red", size = 0.2, 
               position = position_dodge2(), show.legend = F) +
  geom_hline(yintercept = gfp.bg, linetype = "dashed", alpha = 0.6) +
  facet_wrap(~Pho2, nrow = 1, scales = "free_x") +
  ylab("MFI") + scale_y_continuous(expand = expansion(mult = c(0.01,0.1))) +
  labs(title = "GFP fluorescent intensity (arbitrary units)") +
  theme_cowplot() + theme(axis.text.x = element_text(angle = 40, vjust = 1, hjust = 1))
Using alpha for a discrete variable is not advised.
p1

#left_col <- plot_grid(p0, NULL, nrow = 2, rel_heights = c(2,1))
#plot_grid(left_col, p1, ncol = 2, rel_widths = c(1,4))

Figure 4. Pho4-chimera abundance measured by mNeon fluorescent intensity. Dotted line indicates the background level of GFP. Each bar represents one biological replicate. Jia and Lindsey’s samples were grouped by the plasmid they contain and arranged side-by-side to show their similarity or difference. The red lines indicate the mean for each group.

Discussion

  • There is great variability among Pho4 chimeric constructs, where pH177 showed the highest expression level by fluorescent protein abundance

  • There appear to be more chimera protein in the pho2∆ background than in the PHO2 wild type background.

    I’ve seen a similar picture in one of my previous experiments, but a repeat of that experiment didn’t reproduce the phenomenon.

    While I initially suspected some sort of transcriptional feedback – somehow lack of Pho2 induces Pho4 to be more highly expressed – the lack of reproducibility in the second try made me think it could have to do with how PHO2 and pho2∆ strains grow. We know that Pho2 is also responsible for regulating de novo purine synthesis and as such, pho2∆ strains are extremely sensitive to purine deprivation.

    What if we add additional adenine to our media for growing the strains (following the low autofluorescence media recipe perhaps)? One idea is to test a range of media with different concentrations of adenine and phosphate, and record growth curves for the PHO2 and pho2∆ strains, to determine if there is any difference in growth rate and hopefully identify a condition that shows no difference between the two.

PHO5p-RFP reporter expression

rfp.bg <- dat %>% filter(!FP, Parameter == "PHO5pr-mCherry-H") %>% pull(Median) %>% mean()
rfp.basal <- dat %>% filter(FP, Parameter == "PHO5pr-mCherry-H", Pho4 == "pho4del") %>% pull(Median) %>% mean()
dat %>% 
  filter(Parameter == "PHO5pr-mCherry-H", xor(!FP, Pho4 == "pho4del")) %>% 
  ggplot(aes(x = Sample, y = Median)) + geom_col(position = position_dodge()) + 
  ylim(c(0, 6000)) + ylab("Median Fluorescent Intensity") +
  labs(title = "RFP background fluorescence (yH156) and\nbasal expression w/o Pho4 (yH295-373)") + 
  theme_cowplot()

Figure 5. Background RFP level and basal PHO5pr-mCherry expression.

p1 <- dat %>% 
  filter(FP, Pho4 != "pho4del") %>% 
  mutate(MFI = Median / 1000) %>% 
  ggplot(aes(x = Pho4, y = MFI, fill = Pho4, alpha = Group)) + scale_alpha_discrete("User", range = c(0.5, 1)) +
  geom_col(position = position_dodge2(width = 0.9)) +
  #stat_summary(fun = "mean", geom = "crossbar", color = "red", size = 0.3, width = 0.3) +
  geom_hline(aes(yintercept = ifelse(Parameter == "chimera-GFP-H", gfp.bg/1000, rfp.basal/1000)), linetype = 2, alpha = 0.6) +
  facet_grid(Pho2 ~ Parameter, scales = "free", space = "free_y") + ylab("Median Fluorescent Intensity (x1000)") +
  #scale_color_brewer(type = "qual") + scale_color_manual(values = c("red", NA)) +
  coord_flip() + scale_y_continuous(expand = expansion(mult = c(0.01,0.1))) +
  theme_cowplot() + background_grid(major = "x", minor = "x") + panel_border()
Using alpha for a discrete variable is not advised.
p1

Figure 6. Pho4-GFP and PHO5pr-RFP intensities plotted side-by-side. The raw fluorescent intensities in arbitrary units are plotted on the x-axis. Color of the bars are meant to highlight the different Pho4 chimera (or endogenous Pho4) constructs. To distinguish and compare the results from Jia and Lindsey’s experiments, the two sets of results were combined and grouped by the Pho4 chimera, and plotted side-by-side with Jia’s results shown in a lighter (semi-transparent) color. The dashed lines in the GFP panel indicates background fluorescence, while the dashed line in the RFP channel indicates basal mCherry levels (in strains with the PHO5pr-mCherry reporter but lacking Pho4).

Discussion

  • For the majority of the Pho4 chimera, their expression levels as judged by the GFP intensity are similar between Jia and Lindsey’s strains, which is expected. However, a few constructs did show differences, e.g. pH193, pH180 and pH177. Interestingly, the differences are only seen in the pho2∆ background.
  • For CgPho4 (pH188), the PHO5pr-mCherry reporter levels are comparable in pho2∆ vs PHO2 wild type backgrounds, while for ScPho4 (pH194), the reporter level without Pho2 is clearly the lowest compared with all the chimera and CgPho4.
  • In PHO2 wild type background, Lindsey’s strains show more variability among the Pho4 chimera, e.g. pH177 and pH180 induce higher levels of reporter expression than either pure ScPho4 or pure CgPho4 (although, pH177 seems to be at ~2 fold more abundant than the others).

Normalized Pho4 chimera activity with and without Pho2

We will first transform the raw GFP and RFP intensities to make them more interpretable. For the GFP intensity, as there is a substantial background, we will subtract the background from all the GFP-containing strains to obtain the meaningful measure for Pho4 protein levels. For RFP, we will similarly subtract the background, which is minimal (~100 a.u. w/o mCherry reporter). Since what we are interested in is not the absolute level of reporter expression but the fold induction compared with the pho4∆ strains, we will divide the background subtracted RFP levels in the experimental strain by the basal expression level. Then, the induction fold change, call it M, is a function of both Pho4 chimera’s activity (A) in each strain and also the protein level of the chimera (C) (other factors matter, too, but we assume they are the same among all strains for simplicity). We will further assume that M is proportional to both S and C (may not be correct), which leads to \(M = kSA\). Rearranging this equation, we get the quantity we are interested in, i.e. activity, as \(A/k = M/S\). Since \(k\) is a constant and we are only interested in the relative values of activity among the chimera, we can let \(A' = A/k\), and for simplicity, we will equate \(A'\) with \(A\) below.

dat1 <- dat %>% 
  # remove all the control strains, including the parents, and only retain the experimental ones
  filter(FP, Pho4 != "pho4del") %>% 
  select(Group, Sample, Rep, Pho4, Pho2, Pho5RFP, Parameter, Median) %>% 
  pivot_wider(names_from = Parameter, values_from = Median) %>% 
  mutate(GFP.noBG = `chimera-GFP-H` - gfp.bg,
         RFP.noBG = `PHO5pr-mCherry-H` - rfp.bg,
         RFP.FC = RFP.noBG / rfp.basal,
         nRFP.FC = RFP.FC / GFP.noBG * median(GFP.noBG, na.rm = T))
p2 <- dat1 %>% 
  pivot_longer(cols = c(RFP.FC, nRFP.FC), names_to = "Parameter", values_to = "Value") %>%
  mutate(Parameter = factor(Parameter, levels = c("RFP.FC", "nRFP.FC"), 
                            labels = c("PHO5 fold induction", "PHO5 induction / Pho4-GFP"))) %>% 
  ggplot(aes(x = Pho4, y = Value, fill =  Pho4, alpha = Group)) + scale_alpha_discrete("User", range = c(0.5, 1)) +
  geom_col(position = position_dodge2(width = 0.9, preserve = "total")) +
  stat_summary(fun = "mean", geom = "crossbar", position = position_dodge2(width = 0.9), 
               color = "red", size = 0.3, show.legend = F) +
  #geom_text(aes(label = ifelse(Sample %in% issues, "*", ""), hjust = -0.2, vjust = 0.8), color = "black", size = 5) +
  geom_hline(yintercept = 1, linetype = 2) +
  facet_grid(Pho2 ~ Parameter, scales = "free", space = "free_y") +
  #scale_fill_brewer(type = "div", drop = F) + scale_color_manual(values = c("red", NA)) +
  coord_flip() + scale_y_continuous(expand = expansion(mult=c(0.01,0.1))) + ylab("Fold Induction") + xlab("") +
  theme_bw()
Using alpha for a discrete variable is not advised.
p2

Figure 7. Composite plot including Pho4 abundance, PHO5 reporter strength and fold induction values. Pho4-GFP and PHO5p-mCherry intensities were quantified using flow cytometry. Pho4 chimera were labeled by the plasmid ID (see table at the top for details) and are listed on the vertical axis. Each bar is one biological replicate, with Jia and Lindsey’s strains grouped by the plasmid transformed and arranged side-by-side (Jia’s data are lighter in color). The red vertical bar indicate the mean value across biological replicates for either Jia or Lindsey’s strains. In (A), the x-axis values represent the Median Fluorescent Intensity (MFI, arbitury units) for either Pho4-GFP or PHO5pr-mCherry after subtracting the background (based on strains without the corresponding fluorescent protein). In (B), the fold change for PHO5 reporter is calculated as the background-subtracted RFP level divided by the basal expression level. The normalized induction on the right column is calculated by dividing the induction fold change from the left column by the corresponding Pho4-GFP (background subtracted) levels and multiplied by the median Pho4-GFP levels of all strains. The dashed lines in both columns indicate the induction fold change of 1, i.e. no change compared to the pho4∆ strains.

Discussion

  • Other than CgPho4 (pH188), the rest seem not different from ScPho4 in that they have little activity without Pho2.
  • We need to first figure out the Pho4 chimera level in pho2∆ background, as the unnormalized ratio (in B left column) for a few of the chimera do seem to be above ScPho4, but after the normalization all went down, because the corresponding chimera appear to be expressed at a higher level. What’s curious is that the higher expression is only in the pho2∆ background.
  • We also need to repeat this experiment to examine the variability.

Supplementary figures

Here are plots that demonstrate the issues with some of the samples: Lindsey sample K1 Lindsey sample K2 Lindsey sample K3 Jia sample B3-1 Jia sample B3-2 Jia sample B3-3 Jia sample B4-1

LS0tCnRpdGxlOiBhbmFseXplIGZsb3cgY3l0b21ldHJ5IGRhdGEgZnJvbSAyMDIxLTAzLTEwCmF1dGhvcjogQmluIEhlCm91dHB1dDogCiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBkZl9wcmludDogZGVmYXVsdAogICAgY29kZV9mb2xkaW5nOiBoaWRlCi0tLQoKYGBge3Igc2V0dXB9CnJlcXVpcmUodGlkeXZlcnNlKQpyZXF1aXJlKGNvd3Bsb3QpCmBgYAoKIyMgRXhlY3V0aXZlIHN1bW1hcnkKPi0gW0EgZmV3XSgjcWMpIFt0ZWNobmljYWwgdGhpbmdzXSgjc3VwZmlnKSB0byBjb3JyZWN0IGluIHRoZSBjb2xsZWN0aW9uIG9mIGZsb3cgY3l0b21ldHJ5IGRhdGEsIGluY2x1ZGluZyBzZXR0aW5nIHRoZSBhY3F1aXNpdGlvbiB0aHJlc2hvbGQsIHByb3Blcmx5IGRyYXdpbmcgdGhlIGdhdGUgYW5kIGlkZW50aWZ5aW5nIGFuZCByZW1vdmluZyBwcm9ibGVtYXRpYyBzYW1wbGVzLgo+LSBUaGVyZSBpcyBzdWJzdGFudGlhbCB2YXJpYWJpbGl0eSBpbiBQaG80LWNoaW1lcmEgYWJ1bmRhbmNlIGFzIG1lYXN1cmVkIGJ5IG1OZW9uIGludGVuc2l0eSBhbW9uZyB0aGUgY2hpbWVyaWMgLyBlbmRvZ2Vub3VzIGNvbnN0cnVjdHMsIGJ1dCBvbmx5IGluIHRoZSBfcGhvMuKIhl8gYmFja2dyb3VuZCwgd2hpbGUgdGhlIHNhbWUgcGxhc21pZHMgYXBwZWFyIHRvIGJlIGV4cHJlc3NlZCB0byBhIHNpbWlsYXIgbGV2ZWwgd2l0aCBfUEhPMl8uCj4gIC0gaHlwb3RoZXNlcz8KPiAgLSBub3QgbmVjZXNzYXJpbHkgcmVhbCwgc2VlIG15IFsyMDIwLTEyLTIxXShodHRwczovL3JwdWJzLmNvbS9lbXB0eWhiL1BobzQtR0ZQLXRlc3QtMjAyMDEyMjEpIHZzIFsyMDIwLTEyLTIzXShodHRwczovL3JwdWJzLmNvbS9lbXB0eWhiL3Rlc3QtcGhvNC1nZnAtMjAyMDEyMjMpIGFuYWx5c2VzLgo+LSBDaGltZXJhIGFjdGl2aXR5IGFzIG1lYXN1cmVkIGJ5IFJGUC9HRlAgY29uZmlybXMgdGhhdCBDZ1BobzQgaXMgUGhvMi1pbmRlcGVuZGVudCB3aGlsZSBTY1BobzQgaXMgZGVwZW5kZW50LiBCdXQgYWxsIGNoaW1lcmEgdGVzdGVkIGFwcGVhciB0byBiZSBQaG8yLWRlcGVuZGVudCwgaW4gY29udHJhc3QgdG8gcHJldmlvdXMgcGhvc3BoYXRhc2UgYXNzYXkgcmVzdWx0cy4gTm90YWJseSwgcGFydCBvZiB0aGlzIGlzIGR1ZSB0byB0aGUgYXBwYXJlbnRseSBoaWdoZXIgZXhwcmVzc2lvbiBsZXZlbCBvZiB0aGUgY2hpbWVyYS4KPgo+KipfVE9ET18qKgo+Cj4xLiBJbnZlc3RpZ2F0ZSB0aGUgZWZmZWN0IG9mIGdyb3d0aCBtZWRpYSAoYWRlbmluZSBhbmQgcGhvc3BoYXRlIGxldmVscykgb24gUGhvNCBjaGltZXJhIGV4cHJlc3Npb24gaW4gX3BobzLiiIZfIHN0cmFpbnMuCj4xLiBVc2UgV2VzdGVybiB0byBjb25maXJtIHdoZXRoZXIgdGhlIGhpZ2hlciBQaG80IGFidW5kYW5jZSBmb3Igc29tZSBjaGltZXJhIGluIF9waG8y4oiGXyBpcyByZWFsLCBlLmcuIHBIMTc3Cj4xLiBSZXBlYXQgdGhpcyBleHBlcmltZW50IHRvIGRldGVybWluZSBpZiB0aGUgb2JzZXJ2YXRpb25zIGFyZSByZXByb2R1Y2libGUuCj4xLiBWYWxpZGF0ZSB0aGUgZmxvdyBjeXRvbWV0cnkgcmVzdWx0cyB3aXRoIHBob3NwaGF0YXNlIGFzc2F5IChvbmx5IHdvcmtzIGZvciB5SDI5NSw2IHBhcmVudHMpCgojIyBHb2FsCgpWYWxpZGF0ZSB0aGUgcGhvc3BoYXRhc2UgYXNzYXkgcmVzdWx0cyBmb3IgWHUncyBQaG80IGNoaW1lcmEgdXNpbmcgdGhlIG5ldyBkdWFsLWZsdW9yZXNjZW5jZSByZXBvcnRlciBhcHByb2FjaC4KCiMjIE1hdGVyaWFsIGFuZCBtZXRob2RzCgpKaWEgc3ViY2xvbmVkIGEgc2V0IG9mIFh1J3MgY2hpbWVyaWMgUGhvNCBwbGFzbWlkcyBpbnRvIGhlciBtTmVvbiB0YWdnZWQgYmFja2JvbmUgKHBIMTczKSB1c2luZyB0aGUgbmV3IEdvbGRlbiBHYXRlIGFwcHJvYWNoLiBUaGUgY29tcGxldGUgbGlzdCBvZiBwbGFzbWlkcyBjYW4gYmUgZm91bmQgW2hlcmVdKGh0dHBzOi8vZG9jcy5nb29nbGUuY29tL3NwcmVhZHNoZWV0cy9kLzF5Zjc3ZWtkb1o5U1QwdGNLZE1xRERqQWlyMlRtdFNlQ1hmZHpweHhzZ1dzL2VkaXQ/dXNwPXNoYXJpbmcpLgoKQWxsIHN0cmFpbnMgaW4gdGhlIHRhYmxlIGJlbG93IGhhdmUgKnBobzgwOjpUcnAxKgoKYGBge3J9CnNhbXBsZXMgPC0gcmVhZF9jc3YoIjIwMjEwMzEwLVRlc3QtWHUtQ2hpbWVyYXMtc2FtcGxlLWxpc3QuY3N2IiwgY29sX3R5cGVzID0gImNjY2NjbGMiKQpzYW1wbGVzCmBgYAoKQ2VsbHMgYXJlIGZpcnN0IGdyb3duIHRvIHNhdHVyYXRpb24gby9uIGluIFNELWxldSwgZGlsdXRlZCBpbiB0aGUgbW9ybmluZyB0byBPRH4wLjIgaW4gU0QtbGV1IGFuZCByZWdyb3duIGZvciB+MiBkb3VibGluZ3MuIEFmdGVyIHRoZSBjdWx0dXJlIHJlYWNoZWQgZGVzaXJlZCBPRCAobWlkIGxvZyBwaGFzZSksIGNlbGxzIHdlcmUgc3B1biBkb3duIGFuZCByZXN1c3BlbmRlZCBpbiBQQlMgYW5kIHVzZWQgZm9yIGZsb3cgY3l0b21ldHJ5LiBWb2x0YWdlcyB1c2VkIGFyZToKCnwgRGV0ZWN0b3IgfCBWb2x0YWdlIHwgQ29tbWVudHMgfAp8LS0tLS0tLS0tLXwtLS0tLS0tLS18LS0tLS0tLS0tLXwKfCBGU0MgICAgICB8IDM1MCBtViAgfCBJIG5vcm1hbGx5IHVzZSAyODUgbVYgfAp8IFNTQyAgICAgIHwgMzUwIG1WICB8IE5BIHwKfCBCTDEgICAgICB8IDQwMCBtViAgfCBOQSB8CnwgWUwyICAgICAgfCA0NTAgbVYgIHwgaGlnaGVyIHRoYW4gbWluZSB8CgojIyBEYXRhIGltcG9ydApgYGB7ciBpbXBvcnRfZGF0YX0KZGF0MCA8LSByZWFkX2NzdigiMjAyMTAzMTktQmluLXJlYW5hbHl6ZWQtY2hpbWVyYS10ZXN0LTEtcmVzdWx0cy5jc3YiKQpgYGAKCiMjIFF1YWxpdHkgY29udHJvbHsjcWN9CnlMU19LIGFuZCB5SlpfQjMsIEI0IGVhY2ggaGF2ZSBvbmUgb3IgbW9yZSBiaW9sb2dpY2FsIHJlcGxpY2F0ZXMgdGhhdCBzaG93ZWQgYWJub3JtYWwgcGF0dGVybnMgb24gdGhlIEZDUy1IIHZzIFNTQy1IIC0tIHZlcnkgZmV3IGNlbGxzIGFuZCBhIGxhcmdlIG51bWJlciBvZiBzbWFsbCBwYXJ0aWNsZXMgd2l0aCBoaWdoIFNTQy1IIGFuZCBsb3cgRlNDLUguIFNlZSB0aGUgW2xhc3Qgc2VjdGlvbl0oI3N1cGZpZykgb2YgdGhlIGtuaXR0ZWQgZG9jdW1lbnQuCgpgYGB7ciBRQywgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NH0KZ2dwbG90KGRhdDAsIGFlcyh4ID0gQ291bnQsIHkgPSBDb25jZW50cmF0aW9uLCBzaGFwZSA9IFBobzIsIGNvbG9yID0gUGhvNCkpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMiwgYWxwaGEgPSAwLjgpICsgCiAgeGxhYigiVG90YWwgIyBvZiBldmVudHMgcmVjb3JkZWQiKSArIHlsYWIoIkNvbmNlbnRyYXRpb24gKGV2ZW50cy9zKSIpICsgCiAgdGhlbWVfY293cGxvdCgpICsgYmFja2dyb3VuZF9ncmlkKCkgKyBwYW5lbF9ib3JkZXIoKQpgYGAKKipGaWd1cmUgMS4gQWNxdWlzaXRpb24gc3RhdHMgc2hvdyBhIGZldyBzYW1wbGVzIHVuZGVyc2FtcGxlZCBhbmQgcHJvYmxlbWF0aWMuKiogQ29uY2VudHJhdGlvbiBpcyBtZWFzdXJlZCBieSByZWNvcmRlZCBldmVudHMgLyBzZWNvbmQgKHktYXhpcykgd2hpbGUgdG90YWwgbnVtYmVyIG9mIHJlY29yZGVkIGV2ZW50cyBpbiB0aGUgInNpbmdsZXQiIGdhdGUgaXMgcGxvdHRlZCBvbiB0aGUgeC1heGlzLiBTYW1wbGVzIGFyZSBjb2xvcmVkIGJ5IHRoZSBQaG80IGdlbm90eXBlLCBhbmQgdGhlIHNoYXBlIHJlZmxlY3RzIHRoZSBzdGF0dXMgb2YgUGhvMiBpbiB0aGUgaG9zdCBzdHJhaW4uIExpbmRzZXkgYW5kIEppYSdzIHNhbXBsZXMgYXJlIG1peGVkLgoKKipfRGlzY3Vzc2lvbl8qKgoKLSBGaXJzdCBvZiBhbGwsIGl0IGFwcGVhcnMgdGhhdCBMaW5kc2V5IGFuZCBKaWEgZGlkbid0IGNvcnJlY3RseSBzZXQgdGhlIGFjcXVpc2l0aW9uIHN0b3AgY3JpdGVyaWEuIEkgc3VzcGVjdCB0aGF0IHRoZXkgbGV0IHRoZSBhY3F1aXNpdGlvbiB0byBzdG9wIHdoZW4gdGhlIG51bWJlciBvZiBldmVudHMgcmVhY2ggMTAsMDAwLCBidXQgZGlkbid0IHNldCB0aGUgcG9wdWxhdGlvbiB0byB0aGUgInNpbmdsZXQiIGdhdGUuIEJ5IGRlZmF1bHQsIHRoZSBjcml0ZXJpYSB3aWxsIGFwcGx5IHRvIEFMTCBldmVudHMuCi0gcEgxNzkgd2hlbiB0cmFuc2Zvcm1lZCBpbnRvIHRoZSBfcGhvMuKIhl8gYmFja2dyb3VuZCBhcHBlYXJzIHRvIGhhdmUgdHJvdWJsZSBncm93aW5nLiBXZSBzaG91bGQgY29uc2lkZXIgY2hhbmdpbmcgdGhlIGNvbXBvc2l0aW9uIG9mIHRoZSBtZWRpYSB0byBpbmNsdWRlIGFkZGl0aW9uYWwgYWRlbmluZSwgc2luY2UgX3BobzLiiIZfIGlzIHNlbnNpdGl2ZSB0byBhZGVuaW5lIGRlcHJpdmF0aW9uLiBBbHNvLCBpdCB3b3VsZCBiZSBoZWxwZnVsIHRvIHRlc3QgYW5kIGlkZW50aWZ5IGEgbWVkaWEvZ3Jvd3RoIGNvbmRpdGlvbiBpbiB3aGljaCB0aGUgdHdvIGhvc3Qgc3RyYWlucywgd2l0aCBvciB3aXRob3V0IFBobzIsIGdyb3cgcm91Z2hseSBhdCB0aGUgc2FtZSByYXRlLgotIEEgc2VwYXJhdGUgaXNzdWUgaXMgdGhhdCB0aGUgdm9sdGFnZSBmb3IgdGhlIEZTQyBjaGFubmVsIGlzIHByb2JhYmx5IHRvbyBsYXJnZSAoMzUwIG1WLCB2cyAyODUgaW4gbXkgZXhwZXJpbWVudHMpLiBBcyBjYW4gYmUgc2VlbiBpbiB0aGUgcGxvdCBiZWxvdywgbWFueSBldmVudHMgd2VyZSBjdXRvZmYgb2YgdGhlIHJpZ2h0IGJvdW5kYXJ5IG9uIHRoZSBGU0MtSCBheGlzLiBXaGlsZSB0aG9zZSBldmVudHMgbWF5IG5vdCBiZSB3aGF0IHdlIHdhbnQgdG8gaW5jbHVkZSAoc2VlbXMgbGlrZSB0aGV5IGhhdmUgbXVjaCBoaWdoZXIgU1NDLCBidXQgbm90IHN1cmUgaWYgdGhlIHJlc3VsdCB3aWxsIGxvb2sgdGhlIHNhbWUgYWZ0ZXIgbG93ZXJpbmcgdGhlIHZvbHRhZ2UpLCB3ZSBzaG91bGQgc3RpbGwgdHJ5IGFkanVzdCB0aGUgRlNDIHZvbHRhZ2UgdG8gImJyaW5nIHRoZW0gaW5zaWRlIHRoZSBwbG90Ii4KICAgICFbeUgxNTYgZXhhbXBsZV0oLi9pbWcveUgxNTYtcGxvdC5wbmcpCioqRmlndXJlIDIuIEV4YW1wbGUgcGxvdHMgZGVtb25zdHJhdGluZyBwb3RlbnRpYWxseSB0b28gaGlnaCB2b2x0YWdlIGZvciBGU0MqKgoKKipGaWx0ZXIgZGF0YSoqCmBgYHtyfQppc3N1ZXMgPC0gYygiSy0xIiwiSy0yIiwiSy0zIiwiQjMtMSIsIkIzLTIiLCJCMy0zIiwiQjQtMSIpICMgc2VlIGJlbG93IGZvciByZWFzb25zCmRhdCA8LSBkYXQwICU+JSAKICBtdXRhdGUoaWQgPSBwYXN0ZShTYW1wbGUsIFJlcCwgc2VwID0gIi0iKSkgJT4lIAogIGZpbHRlcighaWQgJWluJSBpc3N1ZXMpICU+JSAKICBzZWxlY3QoLWlkKQpgYGAKCiMjIEFuYWx5c2lzCiMjIyBQaG80LUdGUCBleHByZXNzaW9uIGxldmVscwpGaXJzdCBsb29rIGF0IHRoZSBiYWNrZ3JvdW5kIGZsdW9yZXNjZW5jZSBsZXZlbCBpbiB0aGUgR0ZQIGNoYW5uZWwKYGBge3IgZmlnLndpZHRoID0gNCwgZmlnLmhlaWdodD00fQpnZnAuYmcgPC0gZGF0ICU+JSBmaWx0ZXIoIUZQLCBQYXJhbWV0ZXIgPT0gImNoaW1lcmEtR0ZQLUgiKSAlPiUgcHVsbChNZWRpYW4pICU+JSBtZWFuKCkKcDAgPC0gZGF0ICU+JSAKICBmaWx0ZXIoIUZQLCBQYXJhbWV0ZXIgPT0gImNoaW1lcmEtR0ZQLUgiKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gU2FtcGxlLCB5ID0gTWVkaWFuKSkgKyBnZW9tX2NvbChwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKCkpICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gZ2ZwLmJnLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBhbHBoYSA9IDAuNikgKwogIGxhYnModGl0bGUgPSAiQmFja2dyb3VuZCBHRlAgbGV2ZWwiKSArIHlsYWIoIk1GSSIpICsgeWxpbShjKDAsIDYwMDApKSArIAogIHRoZW1lX2Nvd3Bsb3QoKSArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKcDAKYGBgCioqRmlndXJlIDMuIEJhY2tncm91bmQgR0ZQIGluIHN0cmFpbnMgd2l0aCBubyBtTmVvbi4qKiBNRkk6IE1lZGlhbiBmbHVvcmVzY2VudCBpbnRlbnNpdHkuIERvdHRlZCBsaW5lIHNob3dzIHRoZSBhdmVyYWdlIG9mIGFsbCBuZWdhdGl2ZSBzYW1wbGVzIGFuZCB3aWxsIGJlIHVzZWQgZm9yIGJhY2tncm91bmQgc3VidHJhY3Rpb24gaW4gbGF0ZXIgYW5hbHlzZXMuCgpJdCdzIGdvb2QgdG8gc2VlIHRoYXQgYWxsIHRoZSBuZWdhdGl2ZSBzdHJhaW5zIGhhdmUgdGhlIHNhbWUgbGV2ZWwgb2YgYmFja2dyb3VuZCBpbiB0aGUgQkwxIChHRlApIGNoYW5uZWwuIFVuZm9ydHVuYXRlbHkgd2UgZGlkbid0IGluY2x1ZGUgYW55IHN0cmFpbiB0aGF0IGhhdmUgc3Ryb25nIFJGUCBidXQgbm8gR0ZQIHNvIGFzIHRvIGV2YWx1YXRlIHRoZSBzcGlsbG92ZXIgb2YgdGhlIFJGUCBzaWduYWwgaW50byB0aGUgR0ZQIGNoYW5uZWwuCgpOZXh0LCB3ZSBjYW4gZXhhbWluZSB0aGUgUGhvNC1HRlAgbGV2ZWxzIGZvciB0aGUgZGlmZmVyZW50IGNvbnRydWN0cywgaW4gX1BITzJfIG9yIF9waG8y4oiGXyBiYWNrZ3JvdW5kcywgYW5kIHRyYW5zZm9ybWVkIGludG8gdHdvIGdlbmV0aWMgYmFja2dyb3VuZHMuCmBgYHtyLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD00fQpwMSA8LSBkYXQgJT4lIGZpbHRlcihGUCwgUGFyYW1ldGVyID09ICJjaGltZXJhLUdGUC1IIikgJT4lIAogIGdncGxvdChhZXMoeCA9IFBobzQsIHkgPSBNZWRpYW4sIGFscGhhID0gR3JvdXApKSArIAogIHNjYWxlX2FscGhhX2Rpc2NyZXRlKCJVc2VyIiwgcmFuZ2UgPSBjKDAuNSwgMSkpICsKICBnZW9tX2JhcihhZXMoZmlsbCA9IFBobzQpLCBzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZTIoKSkgKyAKICBzdGF0X3N1bW1hcnkoZnVuID0gIm1lYW4iLCBnZW9tID0gImNyb3NzYmFyIiwgY29sb3VyID0gInJlZCIsIHNpemUgPSAwLjIsIAogICAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlMigpLCBzaG93LmxlZ2VuZCA9IEYpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBnZnAuYmcsIGxpbmV0eXBlID0gImRhc2hlZCIsIGFscGhhID0gMC42KSArCiAgZmFjZXRfd3JhcCh+UGhvMiwgbnJvdyA9IDEsIHNjYWxlcyA9ICJmcmVlX3giKSArCiAgeWxhYigiTUZJIikgKyBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gZXhwYW5zaW9uKG11bHQgPSBjKDAuMDEsMC4xKSkpICsKICBsYWJzKHRpdGxlID0gIkdGUCBmbHVvcmVzY2VudCBpbnRlbnNpdHkgKGFyYml0cmFyeSB1bml0cykiKSArCiAgdGhlbWVfY293cGxvdCgpICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0MCwgdmp1c3QgPSAxLCBoanVzdCA9IDEpKQoKcDEKI2xlZnRfY29sIDwtIHBsb3RfZ3JpZChwMCwgTlVMTCwgbnJvdyA9IDIsIHJlbF9oZWlnaHRzID0gYygyLDEpKQojcGxvdF9ncmlkKGxlZnRfY29sLCBwMSwgbmNvbCA9IDIsIHJlbF93aWR0aHMgPSBjKDEsNCkpCmBgYAoqKkZpZ3VyZSA0LiBQaG80LWNoaW1lcmEgYWJ1bmRhbmNlIG1lYXN1cmVkIGJ5IG1OZW9uIGZsdW9yZXNjZW50IGludGVuc2l0eS4qKiBEb3R0ZWQgbGluZSBpbmRpY2F0ZXMgdGhlIGJhY2tncm91bmQgbGV2ZWwgb2YgR0ZQLiBFYWNoIGJhciByZXByZXNlbnRzIG9uZSBiaW9sb2dpY2FsIHJlcGxpY2F0ZS4gSmlhIGFuZCBMaW5kc2V5J3Mgc2FtcGxlcyB3ZXJlIGdyb3VwZWQgYnkgdGhlIHBsYXNtaWQgdGhleSBjb250YWluIGFuZCBhcnJhbmdlZCBzaWRlLWJ5LXNpZGUgdG8gc2hvdyB0aGVpciBzaW1pbGFyaXR5IG9yIGRpZmZlcmVuY2UuIFRoZSByZWQgbGluZXMgaW5kaWNhdGUgdGhlIG1lYW4gZm9yIGVhY2ggZ3JvdXAuCgoqKl9EaXNjdXNzaW9uXyoqCgotIFRoZXJlIGlzIGdyZWF0IHZhcmlhYmlsaXR5IGFtb25nIFBobzQgY2hpbWVyaWMgY29uc3RydWN0cywgd2hlcmUgcEgxNzcgc2hvd2VkIHRoZSBoaWdoZXN0IGV4cHJlc3Npb24gbGV2ZWwgYnkgZmx1b3Jlc2NlbnQgcHJvdGVpbiBhYnVuZGFuY2UKLSBUaGVyZSBhcHBlYXIgdG8gYmUgbW9yZSBjaGltZXJhIHByb3RlaW4gaW4gdGhlIF9waG8y4oiGXyBiYWNrZ3JvdW5kIHRoYW4gaW4gdGhlIF9QSE8yXyB3aWxkIHR5cGUgYmFja2dyb3VuZC4gCgogICAgSSd2ZSBzZWVuIGEgc2ltaWxhciBwaWN0dXJlIGluIFtvbmUgb2YgbXkgcHJldmlvdXMgZXhwZXJpbWVudHNdKGh0dHBzOi8vcnB1YnMuY29tL2VtcHR5aGIvUGhvNC1HRlAtdGVzdC0yMDIwMTIyMSksIGJ1dCBhIFtyZXBlYXQgb2YgdGhhdCBleHBlcmltZW50XShodHRwczovL3JwdWJzLmNvbS9lbXB0eWhiL3Rlc3QtcGhvNC1nZnAtMjAyMDEyMjMpIGRpZG4ndCByZXByb2R1Y2UgdGhlIHBoZW5vbWVub24uIAogICAgCiAgICBXaGlsZSBJIGluaXRpYWxseSBzdXNwZWN0ZWQgc29tZSBzb3J0IG9mIHRyYW5zY3JpcHRpb25hbCBmZWVkYmFjayAtLSBzb21laG93IGxhY2sgb2YgUGhvMiBpbmR1Y2VzIFBobzQgdG8gYmUgbW9yZSBoaWdobHkgZXhwcmVzc2VkIC0tIHRoZSBsYWNrIG9mIHJlcHJvZHVjaWJpbGl0eSBpbiB0aGUgc2Vjb25kIHRyeSBtYWRlIG1lIHRoaW5rIGl0IGNvdWxkIGhhdmUgdG8gZG8gd2l0aCBob3cgX1BITzJfIGFuZCBfcGhvMuKIhl8gc3RyYWlucyBncm93LiBXZSBrbm93IHRoYXQgUGhvMiBpcyBhbHNvIHJlc3BvbnNpYmxlIGZvciByZWd1bGF0aW5nIGRlIG5vdm8gcHVyaW5lIHN5bnRoZXNpcyBhbmQgYXMgc3VjaCwgX3BobzLiiIZfIHN0cmFpbnMgYXJlIGV4dHJlbWVseSBzZW5zaXRpdmUgdG8gcHVyaW5lIGRlcHJpdmF0aW9uLiAKICAgIAogICAgV2hhdCBpZiB3ZSBhZGQgYWRkaXRpb25hbCBhZGVuaW5lIHRvIG91ciBtZWRpYSBmb3IgZ3Jvd2luZyB0aGUgc3RyYWlucyAoZm9sbG93aW5nIHRoZSBsb3cgYXV0b2ZsdW9yZXNjZW5jZSBtZWRpYSByZWNpcGUgcGVyaGFwcyk/IE9uZSBpZGVhIGlzIHRvIHRlc3QgYSByYW5nZSBvZiBtZWRpYSB3aXRoIGRpZmZlcmVudCBjb25jZW50cmF0aW9ucyBvZiBhZGVuaW5lIGFuZCBwaG9zcGhhdGUsIGFuZCByZWNvcmQgZ3Jvd3RoIGN1cnZlcyBmb3IgdGhlIF9QSE8yXyBhbmQgX3BobzLiiIZfIHN0cmFpbnMsIHRvIGRldGVybWluZSBpZiB0aGVyZSBpcyBhbnkgZGlmZmVyZW5jZSBpbiBncm93dGggcmF0ZSBhbmQgaG9wZWZ1bGx5IGlkZW50aWZ5IGEgY29uZGl0aW9uIHRoYXQgc2hvd3Mgbm8gZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSB0d28uCgojIyMgUEhPNXAtUkZQIHJlcG9ydGVyIGV4cHJlc3Npb24KYGBge3IsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9CnJmcC5iZyA8LSBkYXQgJT4lIGZpbHRlcighRlAsIFBhcmFtZXRlciA9PSAiUEhPNXByLW1DaGVycnktSCIpICU+JSBwdWxsKE1lZGlhbikgJT4lIG1lYW4oKQpyZnAuYmFzYWwgPC0gZGF0ICU+JSBmaWx0ZXIoRlAsIFBhcmFtZXRlciA9PSAiUEhPNXByLW1DaGVycnktSCIsIFBobzQgPT0gInBobzRkZWwiKSAlPiUgcHVsbChNZWRpYW4pICU+JSBtZWFuKCkKZGF0ICU+JSAKICBmaWx0ZXIoUGFyYW1ldGVyID09ICJQSE81cHItbUNoZXJyeS1IIiwgeG9yKCFGUCwgUGhvNCA9PSAicGhvNGRlbCIpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gU2FtcGxlLCB5ID0gTWVkaWFuKSkgKyBnZW9tX2NvbChwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKCkpICsgCiAgeWxpbShjKDAsIDYwMDApKSArIHlsYWIoIk1lZGlhbiBGbHVvcmVzY2VudCBJbnRlbnNpdHkiKSArCiAgbGFicyh0aXRsZSA9ICJSRlAgYmFja2dyb3VuZCBmbHVvcmVzY2VuY2UgKHlIMTU2KSBhbmRcbmJhc2FsIGV4cHJlc3Npb24gdy9vIFBobzQgKHlIMjk1LTM3MykiKSArIAogIHRoZW1lX2Nvd3Bsb3QoKQpgYGAKKipGaWd1cmUgNS4gQmFja2dyb3VuZCBSRlAgbGV2ZWwgYW5kIGJhc2FsIFBITzVwci1tQ2hlcnJ5IGV4cHJlc3Npb24uKioKCmBgYHtyLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD04fQpwMSA8LSBkYXQgJT4lIAogIGZpbHRlcihGUCwgUGhvNCAhPSAicGhvNGRlbCIpICU+JSAKICBtdXRhdGUoTUZJID0gTWVkaWFuIC8gMTAwMCkgJT4lIAogIGdncGxvdChhZXMoeCA9IFBobzQsIHkgPSBNRkksIGZpbGwgPSBQaG80LCBhbHBoYSA9IEdyb3VwKSkgKyBzY2FsZV9hbHBoYV9kaXNjcmV0ZSgiVXNlciIsIHJhbmdlID0gYygwLjUsIDEpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZTIod2lkdGggPSAwLjkpKSArCiAgI3N0YXRfc3VtbWFyeShmdW4gPSAibWVhbiIsIGdlb20gPSAiY3Jvc3NiYXIiLCBjb2xvciA9ICJyZWQiLCBzaXplID0gMC4zLCB3aWR0aCA9IDAuMykgKwogIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSBpZmVsc2UoUGFyYW1ldGVyID09ICJjaGltZXJhLUdGUC1IIiwgZ2ZwLmJnLzEwMDAsIHJmcC5iYXNhbC8xMDAwKSksIGxpbmV0eXBlID0gMiwgYWxwaGEgPSAwLjYpICsKICBmYWNldF9ncmlkKFBobzIgfiBQYXJhbWV0ZXIsIHNjYWxlcyA9ICJmcmVlIiwgc3BhY2UgPSAiZnJlZV95IikgKyB5bGFiKCJNZWRpYW4gRmx1b3Jlc2NlbnQgSW50ZW5zaXR5ICh4MTAwMCkiKSArCiAgI3NjYWxlX2NvbG9yX2JyZXdlcih0eXBlID0gInF1YWwiKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJyZWQiLCBOQSkpICsKICBjb29yZF9mbGlwKCkgKyBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gZXhwYW5zaW9uKG11bHQgPSBjKDAuMDEsMC4xKSkpICsKICB0aGVtZV9jb3dwbG90KCkgKyBiYWNrZ3JvdW5kX2dyaWQobWFqb3IgPSAieCIsIG1pbm9yID0gIngiKSArIHBhbmVsX2JvcmRlcigpCnAxCmBgYAoqKkZpZ3VyZSA2LiBQaG80LUdGUCBhbmQgUEhPNXByLVJGUCBpbnRlbnNpdGllcyBwbG90dGVkIHNpZGUtYnktc2lkZS4qKiBUaGUgcmF3IGZsdW9yZXNjZW50IGludGVuc2l0aWVzIGluIGFyYml0cmFyeSB1bml0cyBhcmUgcGxvdHRlZCBvbiB0aGUgeC1heGlzLiBDb2xvciBvZiB0aGUgYmFycyBhcmUgbWVhbnQgdG8gaGlnaGxpZ2h0IHRoZSBkaWZmZXJlbnQgUGhvNCBjaGltZXJhIChvciBlbmRvZ2Vub3VzIFBobzQpIGNvbnN0cnVjdHMuIFRvIGRpc3Rpbmd1aXNoIGFuZCBjb21wYXJlIHRoZSByZXN1bHRzIGZyb20gSmlhIGFuZCBMaW5kc2V5J3MgZXhwZXJpbWVudHMsIHRoZSB0d28gc2V0cyBvZiByZXN1bHRzIHdlcmUgY29tYmluZWQgYW5kIGdyb3VwZWQgYnkgdGhlIFBobzQgY2hpbWVyYSwgYW5kIHBsb3R0ZWQgc2lkZS1ieS1zaWRlIHdpdGggSmlhJ3MgcmVzdWx0cyBzaG93biBpbiBhIGxpZ2h0ZXIgKHNlbWktdHJhbnNwYXJlbnQpIGNvbG9yLiBUaGUgZGFzaGVkIGxpbmVzIGluIHRoZSBHRlAgcGFuZWwgaW5kaWNhdGVzIGJhY2tncm91bmQgZmx1b3Jlc2NlbmNlLCB3aGlsZSB0aGUgZGFzaGVkIGxpbmUgaW4gdGhlIFJGUCBjaGFubmVsIGluZGljYXRlcyBiYXNhbCBtQ2hlcnJ5IGxldmVscyAoaW4gc3RyYWlucyB3aXRoIHRoZSBQSE81cHItbUNoZXJyeSByZXBvcnRlciBidXQgbGFja2luZyBQaG80KS4KCioqX0Rpc2N1c3Npb25fKioKCi0gRm9yIHRoZSBtYWpvcml0eSBvZiB0aGUgUGhvNCBjaGltZXJhLCB0aGVpciBleHByZXNzaW9uIGxldmVscyBhcyBqdWRnZWQgYnkgdGhlIEdGUCBpbnRlbnNpdHkgYXJlIHNpbWlsYXIgYmV0d2VlbiBKaWEgYW5kIExpbmRzZXkncyBzdHJhaW5zLCB3aGljaCBpcyBleHBlY3RlZC4gSG93ZXZlciwgYSBmZXcgY29uc3RydWN0cyBkaWQgc2hvdyBkaWZmZXJlbmNlcywgZS5nLiBwSDE5MywgcEgxODAgYW5kIHBIMTc3LiBJbnRlcmVzdGluZ2x5LCB0aGUgZGlmZmVyZW5jZXMgYXJlIG9ubHkgc2VlbiBpbiB0aGUgX3BobzLiiIZfIGJhY2tncm91bmQuCi0gRm9yIENnUGhvNCAocEgxODgpLCB0aGUgUEhPNXByLW1DaGVycnkgcmVwb3J0ZXIgbGV2ZWxzIGFyZSBjb21wYXJhYmxlIGluIF9waG8y4oiGXyB2cyBfUEhPMl8gd2lsZCB0eXBlIGJhY2tncm91bmRzLCB3aGlsZSBmb3IgU2NQaG80IChwSDE5NCksIHRoZSByZXBvcnRlciBsZXZlbCB3aXRob3V0IFBobzIgaXMgY2xlYXJseSB0aGUgbG93ZXN0IGNvbXBhcmVkIHdpdGggYWxsIHRoZSBjaGltZXJhIGFuZCBDZ1BobzQuCi0gSW4gX1BITzJfIHdpbGQgdHlwZSBiYWNrZ3JvdW5kLCBMaW5kc2V5J3Mgc3RyYWlucyBzaG93IG1vcmUgdmFyaWFiaWxpdHkgYW1vbmcgdGhlIFBobzQgY2hpbWVyYSwgZS5nLiBwSDE3NyBhbmQgcEgxODAgaW5kdWNlIGhpZ2hlciBsZXZlbHMgb2YgcmVwb3J0ZXIgZXhwcmVzc2lvbiB0aGFuIGVpdGhlciBwdXJlIFNjUGhvNCBvciBwdXJlIENnUGhvNCAoYWx0aG91Z2gsIHBIMTc3IHNlZW1zIHRvIGJlIGF0IH4yIGZvbGQgbW9yZSBhYnVuZGFudCB0aGFuIHRoZSBvdGhlcnMpLgoKCiMjIyBOb3JtYWxpemVkIFBobzQgY2hpbWVyYSBhY3Rpdml0eSB3aXRoIGFuZCB3aXRob3V0IFBobzIKV2Ugd2lsbCBmaXJzdCB0cmFuc2Zvcm0gdGhlIHJhdyBHRlAgYW5kIFJGUCBpbnRlbnNpdGllcyB0byBtYWtlIHRoZW0gbW9yZSBpbnRlcnByZXRhYmxlLiBGb3IgdGhlIEdGUCBpbnRlbnNpdHksIGFzIHRoZXJlIGlzIGEgc3Vic3RhbnRpYWwgYmFja2dyb3VuZCwgd2Ugd2lsbCBzdWJ0cmFjdCB0aGUgYmFja2dyb3VuZCBmcm9tIGFsbCB0aGUgR0ZQLWNvbnRhaW5pbmcgc3RyYWlucyB0byBvYnRhaW4gdGhlIG1lYW5pbmdmdWwgbWVhc3VyZSBmb3IgUGhvNCBwcm90ZWluIGxldmVscy4gRm9yIFJGUCwgd2Ugd2lsbCBzaW1pbGFybHkgc3VidHJhY3QgdGhlIGJhY2tncm91bmQsIHdoaWNoIGlzIG1pbmltYWwgKH4xMDAgYS51LiB3L28gbUNoZXJyeSByZXBvcnRlcikuIFNpbmNlIHdoYXQgd2UgYXJlIGludGVyZXN0ZWQgaW4gaXMgbm90IHRoZSBhYnNvbHV0ZSBsZXZlbCBvZiByZXBvcnRlciBleHByZXNzaW9uIGJ1dCB0aGUgZm9sZCBpbmR1Y3Rpb24gY29tcGFyZWQgd2l0aCB0aGUgX3BobzTiiIZfIHN0cmFpbnMsIHdlIHdpbGwgZGl2aWRlIHRoZSBiYWNrZ3JvdW5kIHN1YnRyYWN0ZWQgUkZQIGxldmVscyBpbiB0aGUgZXhwZXJpbWVudGFsIHN0cmFpbiBieSB0aGUgYmFzYWwgZXhwcmVzc2lvbiBsZXZlbC4gVGhlbiwgdGhlIGluZHVjdGlvbiBmb2xkIGNoYW5nZSwgY2FsbCBpdCBNLCBpcyBhIGZ1bmN0aW9uIG9mIGJvdGggUGhvNCBjaGltZXJhJ3MgYWN0aXZpdHkgKEEpIGluIGVhY2ggc3RyYWluIGFuZCBhbHNvIHRoZSBwcm90ZWluIGxldmVsIG9mIHRoZSBjaGltZXJhIChDKSAob3RoZXIgZmFjdG9ycyBtYXR0ZXIsIHRvbywgYnV0IHdlIGFzc3VtZSB0aGV5IGFyZSB0aGUgc2FtZSBhbW9uZyBhbGwgc3RyYWlucyBmb3Igc2ltcGxpY2l0eSkuIFdlIHdpbGwgZnVydGhlciBhc3N1bWUgdGhhdCBNIGlzIHByb3BvcnRpb25hbCB0byBib3RoIFMgYW5kIEMgKG1heSBub3QgYmUgY29ycmVjdCksIHdoaWNoIGxlYWRzIHRvICRNID0ga1NBJC4gUmVhcnJhbmdpbmcgdGhpcyBlcXVhdGlvbiwgd2UgZ2V0IHRoZSBxdWFudGl0eSB3ZSBhcmUgaW50ZXJlc3RlZCBpbiwgaS5lLiBhY3Rpdml0eSwgYXMgJEEvayA9IE0vUyQuIFNpbmNlICRrJCBpcyBhIGNvbnN0YW50IGFuZCB3ZSBhcmUgb25seSBpbnRlcmVzdGVkIGluIHRoZSByZWxhdGl2ZSB2YWx1ZXMgb2YgYWN0aXZpdHkgYW1vbmcgdGhlIGNoaW1lcmEsIHdlIGNhbiBsZXQgJEEnID0gQS9rJCwgYW5kIGZvciBzaW1wbGljaXR5LCB3ZSB3aWxsIGVxdWF0ZSAkQSckIHdpdGggJEEkIGJlbG93LiAKYGBge3IgdHJhbnNmb3JtfQpkYXQxIDwtIGRhdCAlPiUgCiAgIyByZW1vdmUgYWxsIHRoZSBjb250cm9sIHN0cmFpbnMsIGluY2x1ZGluZyB0aGUgcGFyZW50cywgYW5kIG9ubHkgcmV0YWluIHRoZSBleHBlcmltZW50YWwgb25lcwogIGZpbHRlcihGUCwgUGhvNCAhPSAicGhvNGRlbCIpICU+JSAKICBzZWxlY3QoR3JvdXAsIFNhbXBsZSwgUmVwLCBQaG80LCBQaG8yLCBQaG81UkZQLCBQYXJhbWV0ZXIsIE1lZGlhbikgJT4lIAogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBQYXJhbWV0ZXIsIHZhbHVlc19mcm9tID0gTWVkaWFuKSAlPiUgCiAgbXV0YXRlKEdGUC5ub0JHID0gYGNoaW1lcmEtR0ZQLUhgIC0gZ2ZwLmJnLAogICAgICAgICBSRlAubm9CRyA9IGBQSE81cHItbUNoZXJyeS1IYCAtIHJmcC5iZywKICAgICAgICAgUkZQLkZDID0gUkZQLm5vQkcgLyByZnAuYmFzYWwsCiAgICAgICAgIG5SRlAuRkMgPSBSRlAuRkMgLyBHRlAubm9CRyAqIG1lZGlhbihHRlAubm9CRywgbmEucm0gPSBUKSkKYGBgCgpgYGB7ciwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9OH0KcDIgPC0gZGF0MSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKFJGUC5GQywgblJGUC5GQyksIG5hbWVzX3RvID0gIlBhcmFtZXRlciIsIHZhbHVlc190byA9ICJWYWx1ZSIpICU+JQogIG11dGF0ZShQYXJhbWV0ZXIgPSBmYWN0b3IoUGFyYW1ldGVyLCBsZXZlbHMgPSBjKCJSRlAuRkMiLCAiblJGUC5GQyIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIlBITzUgZm9sZCBpbmR1Y3Rpb24iLCAiUEhPNSBpbmR1Y3Rpb24gLyBQaG80LUdGUCIpKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IFBobzQsIHkgPSBWYWx1ZSwgZmlsbCA9ICBQaG80LCBhbHBoYSA9IEdyb3VwKSkgKyBzY2FsZV9hbHBoYV9kaXNjcmV0ZSgiVXNlciIsIHJhbmdlID0gYygwLjUsIDEpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZTIod2lkdGggPSAwLjksIHByZXNlcnZlID0gInRvdGFsIikpICsKICBzdGF0X3N1bW1hcnkoZnVuID0gIm1lYW4iLCBnZW9tID0gImNyb3NzYmFyIiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZTIod2lkdGggPSAwLjkpLCAKICAgICAgICAgICAgICAgY29sb3IgPSAicmVkIiwgc2l6ZSA9IDAuMywgc2hvdy5sZWdlbmQgPSBGKSArCiAgI2dlb21fdGV4dChhZXMobGFiZWwgPSBpZmVsc2UoU2FtcGxlICVpbiUgaXNzdWVzLCAiKiIsICIiKSwgaGp1c3QgPSAtMC4yLCB2anVzdCA9IDAuOCksIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDUpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxLCBsaW5ldHlwZSA9IDIpICsKICBmYWNldF9ncmlkKFBobzIgfiBQYXJhbWV0ZXIsIHNjYWxlcyA9ICJmcmVlIiwgc3BhY2UgPSAiZnJlZV95IikgKwogICNzY2FsZV9maWxsX2JyZXdlcih0eXBlID0gImRpdiIsIGRyb3AgPSBGKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJyZWQiLCBOQSkpICsKICBjb29yZF9mbGlwKCkgKyBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gZXhwYW5zaW9uKG11bHQ9YygwLjAxLDAuMSkpKSArIHlsYWIoIkZvbGQgSW5kdWN0aW9uIikgKyB4bGFiKCIiKSArCiAgdGhlbWVfYncoKQoKcDIKYGBgCioqRmlndXJlIDcuIENvbXBvc2l0ZSBwbG90IGluY2x1ZGluZyBQaG80IGFidW5kYW5jZSwgX1BITzVfIHJlcG9ydGVyIHN0cmVuZ3RoIGFuZCBmb2xkIGluZHVjdGlvbiB2YWx1ZXMuKiogUGhvNC1HRlAgYW5kIFBITzVwLW1DaGVycnkgaW50ZW5zaXRpZXMgd2VyZSBxdWFudGlmaWVkIHVzaW5nIGZsb3cgY3l0b21ldHJ5LiBQaG80IGNoaW1lcmEgd2VyZSBsYWJlbGVkIGJ5IHRoZSBwbGFzbWlkIElEIChzZWUgdGFibGUgYXQgdGhlIHRvcCBmb3IgZGV0YWlscykgYW5kIGFyZSBsaXN0ZWQgb24gdGhlIHZlcnRpY2FsIGF4aXMuIEVhY2ggYmFyIGlzIG9uZSBiaW9sb2dpY2FsIHJlcGxpY2F0ZSwgd2l0aCBKaWEgYW5kIExpbmRzZXkncyBzdHJhaW5zIGdyb3VwZWQgYnkgdGhlIHBsYXNtaWQgdHJhbnNmb3JtZWQgYW5kIGFycmFuZ2VkIHNpZGUtYnktc2lkZSAoSmlhJ3MgZGF0YSBhcmUgbGlnaHRlciBpbiBjb2xvcikuIFRoZSByZWQgdmVydGljYWwgYmFyIGluZGljYXRlIHRoZSBtZWFuIHZhbHVlIGFjcm9zcyBiaW9sb2dpY2FsIHJlcGxpY2F0ZXMgZm9yIGVpdGhlciBKaWEgb3IgTGluZHNleSdzIHN0cmFpbnMuIEluICoqKEEpKiosIHRoZSB4LWF4aXMgdmFsdWVzIHJlcHJlc2VudCB0aGUgTWVkaWFuIEZsdW9yZXNjZW50IEludGVuc2l0eSAoTUZJLCBhcmJpdHVyeSB1bml0cykgZm9yIGVpdGhlciBQaG80LUdGUCBvciBQSE81cHItbUNoZXJyeSBhZnRlciBzdWJ0cmFjdGluZyB0aGUgYmFja2dyb3VuZCAoYmFzZWQgb24gc3RyYWlucyB3aXRob3V0IHRoZSBjb3JyZXNwb25kaW5nIGZsdW9yZXNjZW50IHByb3RlaW4pLiBJbiAqKihCKSoqLCB0aGUgZm9sZCBjaGFuZ2UgZm9yIF9QSE81XyByZXBvcnRlciBpcyBjYWxjdWxhdGVkIGFzIHRoZSBiYWNrZ3JvdW5kLXN1YnRyYWN0ZWQgUkZQIGxldmVsIGRpdmlkZWQgYnkgdGhlIGJhc2FsIGV4cHJlc3Npb24gbGV2ZWwuIFRoZSBub3JtYWxpemVkIGluZHVjdGlvbiBvbiB0aGUgcmlnaHQgY29sdW1uIGlzIGNhbGN1bGF0ZWQgYnkgZGl2aWRpbmcgdGhlIGluZHVjdGlvbiBmb2xkIGNoYW5nZSBmcm9tIHRoZSBsZWZ0IGNvbHVtbiBieSB0aGUgY29ycmVzcG9uZGluZyBQaG80LUdGUCAoYmFja2dyb3VuZCBzdWJ0cmFjdGVkKSBsZXZlbHMgYW5kIG11bHRpcGxpZWQgYnkgdGhlIG1lZGlhbiBQaG80LUdGUCBsZXZlbHMgb2YgYWxsIHN0cmFpbnMuIFRoZSBkYXNoZWQgbGluZXMgaW4gYm90aCBjb2x1bW5zIGluZGljYXRlIHRoZSBpbmR1Y3Rpb24gZm9sZCBjaGFuZ2Ugb2YgMSwgaS5lLiBubyBjaGFuZ2UgY29tcGFyZWQgdG8gdGhlIF9waG804oiGXyBzdHJhaW5zLiAKCioqX0Rpc2N1c3Npb25fKioKCi0gT3RoZXIgdGhhbiBDZ1BobzQgKHBIMTg4KSwgdGhlIHJlc3Qgc2VlbSBub3QgZGlmZmVyZW50IGZyb20gU2NQaG80IGluIHRoYXQgdGhleSBoYXZlIGxpdHRsZSBhY3Rpdml0eSB3aXRob3V0IFBobzIuCi0gV2UgbmVlZCB0byBmaXJzdCBmaWd1cmUgb3V0IHRoZSBQaG80IGNoaW1lcmEgbGV2ZWwgaW4gX3BobzLiiIZfIGJhY2tncm91bmQsIGFzIHRoZSB1bm5vcm1hbGl6ZWQgcmF0aW8gKGluICoqQioqIGxlZnQgY29sdW1uKSBmb3IgYSBmZXcgb2YgdGhlIGNoaW1lcmEgZG8gc2VlbSB0byBiZSBhYm92ZSBTY1BobzQsIGJ1dCBhZnRlciB0aGUgbm9ybWFsaXphdGlvbiBhbGwgd2VudCBkb3duLCBiZWNhdXNlIHRoZSBjb3JyZXNwb25kaW5nIGNoaW1lcmEgYXBwZWFyIHRvIGJlIGV4cHJlc3NlZCBhdCBhIGhpZ2hlciBsZXZlbC4gV2hhdCdzIGN1cmlvdXMgaXMgdGhhdCB0aGUgaGlnaGVyIGV4cHJlc3Npb24gaXMgb25seSBpbiB0aGUgX3BobzLiiIZfIGJhY2tncm91bmQuCi0gV2UgYWxzbyBuZWVkIHRvIHJlcGVhdCB0aGlzIGV4cGVyaW1lbnQgdG8gZXhhbWluZSB0aGUgdmFyaWFiaWxpdHkuCgojIyBTdXBwbGVtZW50YXJ5IGZpZ3VyZXN7I3N1cGZpZ30KSGVyZSBhcmUgcGxvdHMgdGhhdCBkZW1vbnN0cmF0ZSB0aGUgaXNzdWVzIHdpdGggc29tZSBvZiB0aGUgc2FtcGxlczoKIVtMaW5kc2V5IHNhbXBsZSBLMV0oLi9pbWcvSzEtaXNzdWUtcGxvdC5wbmcpCiFbTGluZHNleSBzYW1wbGUgSzJdKC4vaW1nL0syLWlzc3VlLXBsb3QucG5nKQohW0xpbmRzZXkgc2FtcGxlIEszXSguL2ltZy9LMy1pc3N1ZS1wbG90LnBuZykKIVtKaWEgc2FtcGxlIEIzLTFdKC4vaW1nL0IzLTEtaXNzdWUtcGxvdC5wbmcpCiFbSmlhIHNhbXBsZSBCMy0yXSguL2ltZy9CMy0yLWlzc3VlLXBsb3QucG5nKQohW0ppYSBzYW1wbGUgQjMtM10oLi9pbWcvQjMtMy1pc3N1ZS1wbG90LnBuZykKIVtKaWEgc2FtcGxlIEI0LTFdKC4vaW1nL0I0LTEtaXNzdWUtcGxvdC5wbmcp