require(tidyverse)
require(cowplot)

Goal

Testing the brightness of Pho4-GFP (mNeon and EGFP) either on a plasmid or integrated at the leu2 or endogenous Pho4 locus. also evaluate the population heterogeneity and use the PHO5pr-mCherry reporter to evaluate the functionality of the Pho4 variants

Material and methods

table of strains

methods

See gDoc for details. Some strains didn’t grow to saturation after the first overnight culture and thus the o/n culture instead of the second growth, which was at mid log phase at the time of harvest, was used for flow cytometry.

Data and analysis

dat <- read_csv("20201210-testing-Pho4-GFP-on-plasmid-or-integrated-with-PHO5pr-reporter.csv")

── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
  Sample = col_character(),
  Alias = col_character(),
  Tube = col_character(),
  Growth = col_character(),
  Group = col_character(),
  Pho4 = col_character(),
  Pho4GFP = col_character(),
  PHO5RFP = col_logical(),
  PHO2 = col_character(),
  Parameter = col_character(),
  Count = col_double(),
  Percent = col_double(),
  Mean = col_double(),
  Median = col_double(),
  CV = col_double(),
  rCV = col_double()
)
dat <- dat %>% mutate(Pho4GFP = factor(Pho4GFP, levels = c("No-GFP","ScPho4-mNeon","ScPho4-EGFP", "CgPho4-mNeon")),
                      Pho4 = factor(Pho4, levels = c("pho4-", "ScPho4", "CgPho4")))

Pho4-GFP expression levels

First look at the level of Pho4-GFP compared with the negative controls.

Figure 1 Pho4-GFP intensity by strain. Pho4-GFP intensities were quantified on an Attune NxT flow cytometer using 400 mV on the BL1 channel. Acquisition rate is 200 ul/min. Strain IDs are listed on the vertical axis while the Median Fluorescent Instensity (MFI, arbitrary units) on the horizontal axis. An asterisk next to a bar indicates an overnight growth instead of a mid-log phase growth was used for quantification. (A) omits A3, A5 and A6, which appear to be outliers to the rest. C2, B3 and D1 also appear to be much brighter than the rest. (B) includes all samples. Notice how the scale is dominated by A3,5,6.

Discussion

  • With limited samples for the endogenously integrated Pho4, it appears that this method generates less clone-to-clone variability.
  • Comparing G and H, which are endogenously integrated with mNeon or EGFP tag, it is clear that the former is brighter. The same comparison with the exogenously integrated strains, e.g. A vs B or D vs E, gave less clear answers. Specifically, B1-3 appear to show higher intensity than A’s, although a couple of A clones, i.e. A3, A5 and A6 are outliers as listed above. Also, in my previous test on 2020-11-09, B clones are generally dimmer than A clones. So there may be some reproducibility issues.
  • The outliers mentioned above are all within the exogenous group. My suspicion is that the ends-in integration method by the pRS305 based plasmids are likely to result in multiple integrations, which could happen at higher rate when a larger amount of digested plasmid is used in the transformation.
  • The plasmid-borne Pho4-GFP strains didn’t grow to saturation as the others did, likely due to expression levels of the Leu2 gene from the plasmids. As a result, for most of them I used the o/n culture. The two mid-log phase samples, M1 and M2, appear to be brighter than the o/n samples, although one needs to repeat this to know for sure.

Next let’s see the population heterogeneity within each strain, using the percent robust CV measure offered by the Attune software.

# let's also check the "spread" using %CV or %robustCV to see which methods produce more heterogeneity among cells
dat %>% filter(Parameter == "Pho4-GFP") %>% 
  ggplot(aes(x = Sample, y = rCV, color =  Group)) + 
  geom_point() +
  #geom_bar(stat = "identity", position = position_dodge2(width = 0.9)) +
  geom_text(aes(label = ifelse(Growth == "ovn", "*", ""), hjust = 1.2, vjust = 0.8), 
            size = 5, color = "white") +
  facet_grid(Pho4GFP~., scales = "free_y", space = "free_y") +
  scale_fill_brewer(type = "div") + ylab("%rCV") +
  coord_flip() + scale_y_continuous(expand = c(0.01,0)) +
  labs(title = "%rCV for Pho4-GFP fluorescent intensity", subtitle = "Asterisks indicate o/n instead of mid-log phase culture")

Figure 2 Pho4-GFP fluorescence cell-to-cell variability within each strain. Pho4-GFP intensities were quantified on an Attune NxT flow cytometer using 400 mV on the BL1 channel. Acquisition rate is 200 ul/min. Strain IDs are listed on the vertical axis while the percent robust CV (%rCV) on the horizontal axis. An asterisk next to a bar indicates an overnight growth instead of a mid-log phase growth was used for quantification.

Discussion

  • P1-4 had the highest level of spread, although it is unclear if that’s due to the o/n growth or due to the strain itself.
  • Note that the outliers in GFP fluorescence in Fig. 1, which are exogenously integrated, don’t have higher variability, suggesting that they are stable, but perhaps multiple integrants.

PHO5pr-mCherry raw intensities

# calculate rfp background and basal expression level
rfp.bg <- mean(dat %>% filter(!PHO5RFP, Parameter == "PHO5pr-mCherry") %>% pull(Median))
rfp.basal <- dat %>% filter(PHO5RFP, Pho4 == "pho4-", Parameter == "PHO5pr-mCherry") %>% pull(Median) %>% mean() - rfp.bg

p1 <- dat %>% filter(PHO5RFP) %>% 
  ggplot(aes(x = Sample, y = Median, fill =  Group, color = PHO2)) + 
  geom_bar(stat = "identity", position = position_dodge2(width = 0.9)) +
  geom_hline(yintercept = rfp.basal, linetype = 2, alpha = 0.6) +
  geom_text(aes(label = ifelse(Growth == "ovn", "*", ""), hjust = -0.2, vjust = 0.8), color = "black", size = 5) +
  facet_grid(Pho4 ~ Parameter, scales = "free", space = "free_y") + ylab("MFI") +
  scale_fill_brewer(type = "div") + scale_color_manual(values = c("red", NA)) +
  coord_flip() + scale_y_continuous(expand = c(0.01,0.02)) +
  theme_bw()
p1

Figure 3 Corresponding Pho4-GFP and PHO5pr-mCherry reporter fluorescence intensity per strain. Pho4-GFP and PHO5p-mCherry intensities were quantified on an Attune NxT flow cytometer using 400 mV on the BL1 and 430 mV on the YL2 channels respectively. Acquisition rate is 200 ul/min. At least 10,000 events were collected. Strain IDs are listed on the vertical axis and the Median Fluorescent Intensity (MFI, arbitury units) for each channel on the horizontal axis. An asterisk next to a bar indicates an overnight growth instead of a mid-log phase growth was used for quantification. The dashed vertical line for Pho4-GFP indicates the autofluorescence as calculated by the mean of the intensities in the strains without GFP; the dashed vertical line for the RFP plot indicates the basal level expression from the reporter without Pho4, calculated by the average of yH295 and yH296, both of which lack Pho4 but has the reporter).

Discussion

  • CgPho4 clearly has no dependence on Pho2 when assayed in S. cerevisiae, largely consistent with my previous results (although my RNA-seq has indicated a modest dependence with ~30-40% reduction in mRNA levels of PHO5 driven by CgPho4 without Pho2.)
  • ScPho4 has strong dependence on Pho2. P1-4 and B1,2,4 both showed that without Pho2, ScPho4 doesn’t induce reporter expression on its own. Some anormalies exist however, as will be discussed below.
  • H1-3 are supposed to be ScPho4-EGFP with the PHO5pr-mCherry and also with ScPho2. However, the results here suggest that this strain had little reporter induction. It may be that the integrated ScPho4-EGFP, even though it is expressed, is not functional. Is this consistent with Lindsey’s results, including flow cytometry and liquid phosphatase assays?
  • G2, 3, 4 have much higher levels than everyone else. Given that the G strains were constructed by Lindsey by integrating the pRS306-PHO5pr-mCherry-URA3 construct into the ura3 locus using the ends-in transformation, I wonder if G2,3 and 4, just like those leu2 integrated Pho4 variants, represent multiple integrations.
  • Lastly, note that the several A clones with high Pho4-GFP (A3, A5 and A6) also showed higher levels of reporter expression, suggesting that increasing the dose of Pho4 can certainly partially compensate for the loss of Pho2.

PHO5pr-mCherry induction levels normalized by Pho4 abundance

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, there is minimal background (see below). However, there is a “basal” expression of the reporter in the absence of Pho4 – what we are interested in is not the absolute level of reporter expression but the fold induction compared with the pho4∆ strains.

# calculate gfp background
gfp.bg <- dat %>% filter(Pho4GFP == "No-GFP", Parameter == "Pho4-GFP") %>% pull(Median) %>% mean()
# transform
dat1 <- dat %>% select(-Count, -Mean, -CV, -rCV, -Percent) %>% 
  pivot_wider(names_from = Parameter, values_from = Median) %>% 
  mutate(GFP.noBG = ifelse(Pho4GFP == "No-GFP", NA, `Pho4-GFP` - gfp.bg),
         RFP.noBG = ifelse(PHO5RFP, `PHO5pr-mCherry` - rfp.bg, 0),
         RFP.FC = ifelse(PHO5RFP, RFP.noBG / rfp.basal, NA),
         nRFP.FC = RFP.FC / GFP.noBG * median(GFP.noBG, na.rm = T))
dat2 <- dat1 %>% filter(Pho4GFP != "No-GFP", PHO5RFP)
p1 <- dat2 %>% 
  mutate(GFP.noBG = GFP.noBG / 1000, RFP.noBG = RFP.noBG / 1000) %>% 
  pivot_longer(cols = c(GFP.noBG, RFP.noBG), names_to = "Parameter", values_to = "Value") %>%
  mutate(Parameter = factor(Parameter, levels = c("GFP.noBG", "RFP.noBG"),  
                            labels = c("Pho4-GFP abundance", "PHO5pr-mCherry level")),
         Group = factor(Group, levels = c("control", "endogenous", "exogenous", "plasmid"))) %>% 
  ggplot(aes(x = Sample, y = Value, fill =  Group, color = PHO2)) + 
  geom_bar(stat = "identity", position = position_dodge2(width = 0.9)) +
  geom_text(aes(label = ifelse(Growth == "ovn", "*", ""), hjust = -0.2, vjust = 0.8), color = "black", size = 5) +
  facet_grid(Pho4GFP ~ Parameter, scales = "free", space = "free_y") +
  scale_fill_brewer(type = "div", drop = FALSE) + scale_color_manual(values = c("red", NA)) +
  coord_flip() + scale_y_continuous(expand = c(0.01,0.02), trans = "sqrt") + ylab("MFI (x1000, a.u.)") + 
  theme_bw()
  
p2 <- dat2 %>% 
  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")),
         Group = factor(Group, levels = c("control", "endogenous", "exogenous", "plasmid"))) %>% 
  ggplot(aes(x = Sample, y = Value, fill =  Group, color = PHO2)) + 
  geom_bar(stat = "identity", position = position_dodge2(width = 0.9)) +
  geom_hline(yintercept = 1, linetype = 2) +
  geom_text(aes(label = ifelse(Growth == "ovn", "*", ""), hjust = -0.2, vjust = 0.8), color = "black", size = 5) +
  facet_grid(Pho4GFP ~ 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 = c(0.01,0.02), trans = "sqrt") + ylab("Fold Induction") + xlab("") +
  theme_bw()

## place shared legend at the bottom
## reference: https://wilkelab.org/cowplot/articles/shared_legends.html
legend <- get_legend(
  p1 + 
  guides(color = guide_legend(nrow = 1), fill = guide_legend(nrow = 1)) +
  theme(legend.position = "bottom")
)
prow <- plot_grid(
  p1 + theme(legend.position="none"),
  p2 + theme(legend.position="none"),
  align = 'vh',
  labels = c("A", "B", "C"),
  hjust = -1,
  nrow = 1
)
plot_grid(prow, legend, ncol = 1, rel_heights = c(1, .1))

Figure 4 Composite plot including Pho4 abundance, PHO5 reporter strength and fold induction values. Pho4-GFP and PHO5p-mCherry intensities were quantified as defined above. Strain IDs are listed on the vertical axis. 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, as measured by the mean of the two strains containing the reporter but have pho4∆. The normalized induction ratio 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. In both panels, the x-axes are square-root transformed so as to bring outliers into the plot without compressing the rest of the data range. An asterisk next to a bar indicates an overnight growth instead of a mid-log phase growth was used for quantification.

Discussions

  • If we look horizontally across the four columns for each alphabetic group (A, B, C, …, P), we can see that the plasmid born Pho4’s actually behave pretty well, especially after normalizing the RFP induction fold change by the Pho4 abundance.
  • Next, the endogenously integrated ScPho4-mNeon showed small clone-to-clone variability in the GFP level, but showed huge variation in the PHO5pr-mCherry levels. The normalized induction fold changes continue to show the dramatic differences between clones. As mentioned before, we suspect this is due to the multi-integration of the reporter construct at the ura3 locus.
  • The exogenously integrated ScPho4-mNeon exhibited large clone-to-clone variability in the GFP level, again possibly due to multi-integration of the Pho4-GFP in the leu2 locus. The normalization by Pho4 abundance didn’t fully remove the difference, likely because the induction fold change doesn’t scale linearly with Pho4 levels (saturation effect).
  • ScPho4-EGFP, both the endogenously and exogenously integrated ones, had issues that prevent a clear interpretation.
  • CgPho4-mNeon is similar to ScPho4-mNeon in that it showed relatively consistent GFP levels except for C2, which may be multi-integration. The normalized induction fold changes are pretty consistent with or without Pho2, except for C2, which showed a lower value likely indicating non-linear relationships between induction and Pho4 abundance.

Conclusions

  • mNeon appears to be as good as, if not better than EGFP in terms of both brightness and keeping the tagged Pho4 functional.
  • the ends-in integration seems to generate multiple integrations frequently (maybe a result of excess digested plasmid? but we are also fighting relatively low transformation efficiency)
  • increasing the dose of ScPho4 can partially compensate for the loss of Pho2, which further highlights the importance of ensuring equal or highly similar levels of expression for all constructs to be tested.
LS0tCnRpdGxlOiBhbmFseXplIGZsb3cgY3l0b21ldHJ5IGRhdGEgZnJvbSAyMDIwLTEyLTEwCmF1dGhvcjogQmluIEhlCmRhdGU6IDIwMjAtMTItMTQKb3V0cHV0OiAKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGRmX3ByaW50OiBkZWZhdWx0CiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKLS0tCgpgYGB7ciBzZXR1cH0KcmVxdWlyZSh0aWR5dmVyc2UpCnJlcXVpcmUoY293cGxvdCkKYGBgCgojIyBHb2FsCgpUZXN0aW5nIHRoZSBicmlnaHRuZXNzIG9mIFBobzQtR0ZQIChtTmVvbiBhbmQgRUdGUCkgZWl0aGVyIG9uIGEgcGxhc21pZCBvciBpbnRlZ3JhdGVkIGF0IHRoZSBsZXUyIG9yIGVuZG9nZW5vdXMgUGhvNCBsb2N1cy4gYWxzbyBldmFsdWF0ZSB0aGUgcG9wdWxhdGlvbiBoZXRlcm9nZW5laXR5IGFuZCB1c2UgdGhlIFBITzVwci1tQ2hlcnJ5IHJlcG9ydGVyIHRvIGV2YWx1YXRlIHRoZSBmdW5jdGlvbmFsaXR5IG9mIHRoZSBQaG80IHZhcmlhbnRzCgojIyBNYXRlcmlhbCBhbmQgbWV0aG9kcwoKIyMjIHRhYmxlIG9mIHN0cmFpbnMKYGBge3IgZWNobyA9IEZ9CnNhbXBsZXMgPC0gcmVhZF90c3YoInN0cmFpbnMtZ2Vub3R5cGUudHN2IiwgY29sX3R5cGVzID0gImNjY2NjY2NjRCIpCihzYW1wbGVzKQpgYGAKCiMjIyBtZXRob2RzClNlZSBnRG9jIGZvciBkZXRhaWxzLiBTb21lIHN0cmFpbnMgZGlkbid0IGdyb3cgdG8gc2F0dXJhdGlvbiBhZnRlciB0aGUgZmlyc3Qgb3Zlcm5pZ2h0IGN1bHR1cmUgYW5kIHRodXMgdGhlIG8vbiBjdWx0dXJlIGluc3RlYWQgb2YgdGhlIHNlY29uZCBncm93dGgsIHdoaWNoIHdhcyBhdCBtaWQgbG9nIHBoYXNlIGF0IHRoZSB0aW1lIG9mIGhhcnZlc3QsIHdhcyB1c2VkIGZvciBmbG93IGN5dG9tZXRyeS4KCiMjIERhdGEgYW5kIGFuYWx5c2lzCmBgYHtyfQpkYXQgPC0gcmVhZF9jc3YoIjIwMjAxMjEwLXRlc3RpbmctUGhvNC1HRlAtb24tcGxhc21pZC1vci1pbnRlZ3JhdGVkLXdpdGgtUEhPNXByLXJlcG9ydGVyLmNzdiIpCmRhdCA8LSBkYXQgJT4lIG11dGF0ZShQaG80R0ZQID0gZmFjdG9yKFBobzRHRlAsIGxldmVscyA9IGMoIk5vLUdGUCIsIlNjUGhvNC1tTmVvbiIsIlNjUGhvNC1FR0ZQIiwgIkNnUGhvNC1tTmVvbiIpKSwKICAgICAgICAgICAgICAgICAgICAgIFBobzQgPSBmYWN0b3IoUGhvNCwgbGV2ZWxzID0gYygicGhvNC0iLCAiU2NQaG80IiwgIkNnUGhvNCIpKSkKYGBgCgojIyMgUGhvNC1HRlAgZXhwcmVzc2lvbiBsZXZlbHMKRmlyc3QgbG9vayBhdCB0aGUgbGV2ZWwgb2YgUGhvNC1HRlAgY29tcGFyZWQgd2l0aCB0aGUgbmVnYXRpdmUgY29udHJvbHMuCmBgYHtyLCBlY2hvID0gRiwgZmlnLmhlaWdodCA9IDcsIGZpZy53aWR0aCA9IDEwfQpnZnAuYmcgPC0gZGF0ICU+JSBmaWx0ZXIoUGhvNEdGUCA9PSAiTm8tR0ZQIiwgUGFyYW1ldGVyID09ICJQaG80LUdGUCIpICU+JSBwdWxsKE1lZGlhbikgJT4lIG1lYW4oKQpwMSA8LSBkYXQgJT4lIGZpbHRlcihQYXJhbWV0ZXIgPT0gIlBobzQtR0ZQIiwgTWVkaWFuIDwgMzAwMCkgJT4lIAogIGdncGxvdChhZXMoeCA9IFNhbXBsZSwgeSA9IE1lZGlhbiwgZmlsbCA9ICBHcm91cCkpICsgCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UyKHdpZHRoID0gMC45KSkgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSBpZmVsc2UoR3Jvd3RoID09ICJvdm4iLCAiKiIsICIiKSwgaGp1c3QgPSAtMC4yLCB2anVzdCA9IDAuOCksIAogICAgICAgICAgICBzaXplID0gNSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGdmcC5iZywgbGluZXR5cGUgPSAiZGFzaGVkIiwgYWxwaGEgPSAwLjYpICsKICBmYWNldF9ncmlkKFBobzRHRlB+Liwgc2NhbGVzID0gImZyZWVfeSIsIHNwYWNlID0gImZyZWVfeSIpICsKICBzY2FsZV9maWxsX2JyZXdlcih0eXBlID0gImRpdiIpICsgeWxhYigiTUZJIikgKwogIGNvb3JkX2ZsaXAoKSArIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsMzAwMCksIGV4cGFuZCA9IGMoMC4wMSwwKSkgKwogIHRoZW1lX2J3KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgojIGluY2x1ZGUgdGhlIG91dGxpZXJzCnAyIDwtIGRhdCAlPiUgZmlsdGVyKFBhcmFtZXRlciA9PSAiUGhvNC1HRlAiKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gU2FtcGxlLCB5ID0gTWVkaWFuLCBmaWxsID0gIEdyb3VwKSkgKyAKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZTIod2lkdGggPSAwLjkpKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGlmZWxzZShHcm93dGggPT0gIm92biIsICIqIiwgIiIpLCBoanVzdCA9IC0wLjIsIHZqdXN0ID0gMC44KSwgCiAgICAgICAgICAgIHNpemUgPSA1KSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gZ2ZwLmJnLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBhbHBoYSA9IDAuNikgKwogIGZhY2V0X2dyaWQoUGhvNEdGUH4uLCBzY2FsZXMgPSAiZnJlZV95Iiwgc3BhY2UgPSAiZnJlZV95IikgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHR5cGUgPSAiZGl2IikgKyB5bGFiKCJNRkkiKSArIHhsYWIoIiIpICsKICBjb29yZF9mbGlwKCkgKyBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLjAxLDApKSArIAogIHRoZW1lX2J3KCkKCiMgY29kZSBiZWxvdyBmcm9tIGh0dHBzOi8vd2lsa2VsYWIub3JnL2Nvd3Bsb3QvYXJ0aWNsZXMvcGxvdF9ncmlkLmh0bWwKIyBwbG90dGluZyBib3RoCnBsb3Rfcm93IDwtIHBsb3RfZ3JpZChwMSwgcDIsIHJlbF93aWR0aHMgPSBjKDEsMS4zKSwgbGFiZWxzID0gIkFVVE8iKQoKIyBub3cgYWRkIHRoZSB0aXRsZQp0aXRsZSA8LSBnZ2RyYXcoKSArCiAgZHJhd19sYWJlbCgKICAgICJHRlAgZmx1b3Jlc2NlbnQgaW50ZW5zaXR5IChhcmJpdHJhcnkgdW5pdHMpLCBkYXNoZWQgbGluZSBpbmRpY2F0ZXMgYmFja2dyb3VuZCBmbHVvcmVzY2VuY2UiLAogICAgZm9udGZhY2UgPSAnYm9sZCcsCiAgICB4ID0gMCwKICAgIGhqdXN0ID0gMAogICkgKwogIHRoZW1lKAogICAgIyBhZGQgbWFyZ2luIG9uIHRoZSBsZWZ0IG9mIHRoZSBkcmF3aW5nIGNhbnZhcywKICAgICMgc28gdGl0bGUgaXMgYWxpZ25lZCB3aXRoIGxlZnQgZWRnZSBvZiBmaXJzdCBwbG90CiAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbigwLCAwLCAwLCA3KQogICkKcGxvdF9ncmlkKAogIHRpdGxlLCBwbG90X3JvdywKICBuY29sID0gMSwKICAjIHJlbF9oZWlnaHRzIHZhbHVlcyBjb250cm9sIHZlcnRpY2FsIHRpdGxlIG1hcmdpbnMKICByZWxfaGVpZ2h0cyA9IGMoMC4wNywgMSkKKQpgYGAKKipGaWd1cmUgMSBQaG80LUdGUCBpbnRlbnNpdHkgYnkgc3RyYWluLioqIFBobzQtR0ZQIGludGVuc2l0aWVzIHdlcmUgcXVhbnRpZmllZCBvbiBhbiBBdHR1bmUgTnhUIGZsb3cgY3l0b21ldGVyIHVzaW5nIDQwMCBtViBvbiB0aGUgQkwxIGNoYW5uZWwuIEFjcXVpc2l0aW9uIHJhdGUgaXMgMjAwIHVsL21pbi4gU3RyYWluIElEcyBhcmUgbGlzdGVkIG9uIHRoZSB2ZXJ0aWNhbCBheGlzIHdoaWxlIHRoZSBNZWRpYW4gRmx1b3Jlc2NlbnQgSW5zdGVuc2l0eSAoTUZJLCBhcmJpdHJhcnkgdW5pdHMpIG9uIHRoZSBob3Jpem9udGFsIGF4aXMuIEFuIGFzdGVyaXNrIG5leHQgdG8gYSBiYXIgaW5kaWNhdGVzIGFuIG92ZXJuaWdodCBncm93dGggaW5zdGVhZCBvZiBhIG1pZC1sb2cgcGhhc2UgZ3Jvd3RoIHdhcyB1c2VkIGZvciBxdWFudGlmaWNhdGlvbi4gKiooQSkqKiBvbWl0cyBBMywgQTUgYW5kIEE2LCB3aGljaCBhcHBlYXIgdG8gYmUgb3V0bGllcnMgdG8gdGhlIHJlc3QuIEMyLCBCMyBhbmQgRDEgYWxzbyBhcHBlYXIgdG8gYmUgbXVjaCBicmlnaHRlciB0aGFuIHRoZSByZXN0LiAqKihCKSoqIGluY2x1ZGVzIGFsbCBzYW1wbGVzLiBOb3RpY2UgaG93IHRoZSBzY2FsZSBpcyBkb21pbmF0ZWQgYnkgQTMsNSw2LgoKX0Rpc2N1c3Npb25fCgotIFdpdGggbGltaXRlZCBzYW1wbGVzIGZvciB0aGUgZW5kb2dlbm91c2x5IGludGVncmF0ZWQgUGhvNCwgaXQgYXBwZWFycyB0aGF0IHRoaXMgbWV0aG9kIGdlbmVyYXRlcyBsZXNzIGNsb25lLXRvLWNsb25lIHZhcmlhYmlsaXR5LgotIENvbXBhcmluZyBHIGFuZCBILCB3aGljaCBhcmUgZW5kb2dlbm91c2x5IGludGVncmF0ZWQgd2l0aCBtTmVvbiBvciBFR0ZQIHRhZywgaXQgaXMgY2xlYXIgdGhhdCB0aGUgZm9ybWVyIGlzIGJyaWdodGVyLiBUaGUgc2FtZSBjb21wYXJpc29uIHdpdGggdGhlIGV4b2dlbm91c2x5IGludGVncmF0ZWQgc3RyYWlucywgZS5nLiBBIHZzIEIgb3IgRCB2cyBFLCBnYXZlIGxlc3MgY2xlYXIgYW5zd2Vycy4gU3BlY2lmaWNhbGx5LCBCMS0zIGFwcGVhciB0byBzaG93IGhpZ2hlciBpbnRlbnNpdHkgdGhhbiBBJ3MsIGFsdGhvdWdoIGEgY291cGxlIG9mIEEgY2xvbmVzLCBpLmUuIEEzLCBBNSBhbmQgQTYgYXJlIG91dGxpZXJzIGFzIGxpc3RlZCBhYm92ZS4gQWxzbywgaW4gbXkgcHJldmlvdXMgdGVzdCBvbiAyMDIwLTExLTA5LCBCIGNsb25lcyBhcmUgZ2VuZXJhbGx5IGRpbW1lciB0aGFuIEEgY2xvbmVzLiBTbyB0aGVyZSBtYXkgYmUgc29tZSByZXByb2R1Y2liaWxpdHkgaXNzdWVzLgotIFRoZSBvdXRsaWVycyBtZW50aW9uZWQgYWJvdmUgYXJlIGFsbCB3aXRoaW4gdGhlIGV4b2dlbm91cyBncm91cC4gTXkgc3VzcGljaW9uIGlzIHRoYXQgdGhlIGVuZHMtaW4gaW50ZWdyYXRpb24gbWV0aG9kIGJ5IHRoZSBwUlMzMDUgYmFzZWQgcGxhc21pZHMgYXJlIGxpa2VseSB0byByZXN1bHQgaW4gbXVsdGlwbGUgaW50ZWdyYXRpb25zLCB3aGljaCBjb3VsZCBoYXBwZW4gYXQgaGlnaGVyIHJhdGUgd2hlbiBhIGxhcmdlciBhbW91bnQgb2YgZGlnZXN0ZWQgcGxhc21pZCBpcyB1c2VkIGluIHRoZSB0cmFuc2Zvcm1hdGlvbi4KLSBUaGUgcGxhc21pZC1ib3JuZSBQaG80LUdGUCBzdHJhaW5zIGRpZG4ndCBncm93IHRvIHNhdHVyYXRpb24gYXMgdGhlIG90aGVycyBkaWQsIGxpa2VseSBkdWUgdG8gZXhwcmVzc2lvbiBsZXZlbHMgb2YgdGhlIExldTIgZ2VuZSBmcm9tIHRoZSBwbGFzbWlkcy4gQXMgYSByZXN1bHQsIGZvciBtb3N0IG9mIHRoZW0gSSB1c2VkIHRoZSBvL24gY3VsdHVyZS4gVGhlIHR3byBtaWQtbG9nIHBoYXNlIHNhbXBsZXMsIE0xIGFuZCBNMiwgYXBwZWFyIHRvIGJlIGJyaWdodGVyIHRoYW4gdGhlIG8vbiBzYW1wbGVzLCBhbHRob3VnaCBvbmUgbmVlZHMgdG8gcmVwZWF0IHRoaXMgdG8ga25vdyBmb3Igc3VyZS4KCk5leHQgbGV0J3Mgc2VlIHRoZSBwb3B1bGF0aW9uIGhldGVyb2dlbmVpdHkgd2l0aGluIGVhY2ggc3RyYWluLCB1c2luZyB0aGUgcGVyY2VudCByb2J1c3QgQ1YgbWVhc3VyZSBvZmZlcmVkIGJ5IHRoZSBBdHR1bmUgc29mdHdhcmUuCmBgYHtyIHBsb3Rfcm9idXN0X0NWLCBmaWcuaGVpZ2h0ID0gNiwgZmlnLndpZHRoID0gNn0KIyBsZXQncyBhbHNvIGNoZWNrIHRoZSAic3ByZWFkIiB1c2luZyAlQ1Ygb3IgJXJvYnVzdENWIHRvIHNlZSB3aGljaCBtZXRob2RzIHByb2R1Y2UgbW9yZSBoZXRlcm9nZW5laXR5IGFtb25nIGNlbGxzCmRhdCAlPiUgZmlsdGVyKFBhcmFtZXRlciA9PSAiUGhvNC1HRlAiKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gU2FtcGxlLCB5ID0gckNWLCBjb2xvciA9ICBHcm91cCkpICsgCiAgZ2VvbV9wb2ludCgpICsKICAjZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UyKHdpZHRoID0gMC45KSkgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSBpZmVsc2UoR3Jvd3RoID09ICJvdm4iLCAiKiIsICIiKSwgaGp1c3QgPSAxLjIsIHZqdXN0ID0gMC44KSwgCiAgICAgICAgICAgIHNpemUgPSA1LCBjb2xvciA9ICJ3aGl0ZSIpICsKICBmYWNldF9ncmlkKFBobzRHRlB+Liwgc2NhbGVzID0gImZyZWVfeSIsIHNwYWNlID0gImZyZWVfeSIpICsKICBzY2FsZV9maWxsX2JyZXdlcih0eXBlID0gImRpdiIpICsgeWxhYigiJXJDViIpICsKICBjb29yZF9mbGlwKCkgKyBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLjAxLDApKSArCiAgbGFicyh0aXRsZSA9ICIlckNWIGZvciBQaG80LUdGUCBmbHVvcmVzY2VudCBpbnRlbnNpdHkiLCBzdWJ0aXRsZSA9ICJBc3Rlcmlza3MgaW5kaWNhdGUgby9uIGluc3RlYWQgb2YgbWlkLWxvZyBwaGFzZSBjdWx0dXJlIikKYGBgCioqRmlndXJlIDIgUGhvNC1HRlAgZmx1b3Jlc2NlbmNlIGNlbGwtdG8tY2VsbCB2YXJpYWJpbGl0eSB3aXRoaW4gZWFjaCBzdHJhaW4uKiogUGhvNC1HRlAgaW50ZW5zaXRpZXMgd2VyZSBxdWFudGlmaWVkIG9uIGFuIEF0dHVuZSBOeFQgZmxvdyBjeXRvbWV0ZXIgdXNpbmcgNDAwIG1WIG9uIHRoZSBCTDEgY2hhbm5lbC4gQWNxdWlzaXRpb24gcmF0ZSBpcyAyMDAgdWwvbWluLiBTdHJhaW4gSURzIGFyZSBsaXN0ZWQgb24gdGhlIHZlcnRpY2FsIGF4aXMgd2hpbGUgdGhlIHBlcmNlbnQgcm9idXN0IENWICglckNWKSBvbiB0aGUgaG9yaXpvbnRhbCBheGlzLiBBbiBhc3RlcmlzayBuZXh0IHRvIGEgYmFyIGluZGljYXRlcyBhbiBvdmVybmlnaHQgZ3Jvd3RoIGluc3RlYWQgb2YgYSBtaWQtbG9nIHBoYXNlIGdyb3d0aCB3YXMgdXNlZCBmb3IgcXVhbnRpZmljYXRpb24uCgpfRGlzY3Vzc2lvbl8KCi0gUDEtNCBoYWQgdGhlIGhpZ2hlc3QgbGV2ZWwgb2Ygc3ByZWFkLCBhbHRob3VnaCBpdCBpcyB1bmNsZWFyIGlmIHRoYXQncyBkdWUgdG8gdGhlIG8vbiBncm93dGggb3IgZHVlIHRvIHRoZSBzdHJhaW4gaXRzZWxmLgotIE5vdGUgdGhhdCB0aGUgb3V0bGllcnMgaW4gR0ZQIGZsdW9yZXNjZW5jZSBpbiAqKkZpZy4gMSoqLCB3aGljaCBhcmUgZXhvZ2Vub3VzbHkgaW50ZWdyYXRlZCwgX2Rvbid0XyBoYXZlIGhpZ2hlciB2YXJpYWJpbGl0eSwgc3VnZ2VzdGluZyB0aGF0IHRoZXkgYXJlIHN0YWJsZSwgYnV0IHBlcmhhcHMgbXVsdGlwbGUgaW50ZWdyYW50cy4KCiMjIyBQSE81cHItbUNoZXJyeSByYXcgaW50ZW5zaXRpZXMKCmBgYHtyLCBmaWcuaGVpZ2h0ID0gNiwgZmlnLndpZHRoID0gN30KIyBjYWxjdWxhdGUgcmZwIGJhY2tncm91bmQgYW5kIGJhc2FsIGV4cHJlc3Npb24gbGV2ZWwKcmZwLmJnIDwtIG1lYW4oZGF0ICU+JSBmaWx0ZXIoIVBITzVSRlAsIFBhcmFtZXRlciA9PSAiUEhPNXByLW1DaGVycnkiKSAlPiUgcHVsbChNZWRpYW4pKQpyZnAuYmFzYWwgPC0gZGF0ICU+JSBmaWx0ZXIoUEhPNVJGUCwgUGhvNCA9PSAicGhvNC0iLCBQYXJhbWV0ZXIgPT0gIlBITzVwci1tQ2hlcnJ5IikgJT4lIHB1bGwoTWVkaWFuKSAlPiUgbWVhbigpIC0gcmZwLmJnCgpwMSA8LSBkYXQgJT4lIGZpbHRlcihQSE81UkZQKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gU2FtcGxlLCB5ID0gTWVkaWFuLCBmaWxsID0gIEdyb3VwLCBjb2xvciA9IFBITzIpKSArIAogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlMih3aWR0aCA9IDAuOSkpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSByZnAuYmFzYWwsIGxpbmV0eXBlID0gMiwgYWxwaGEgPSAwLjYpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gaWZlbHNlKEdyb3d0aCA9PSAib3ZuIiwgIioiLCAiIiksIGhqdXN0ID0gLTAuMiwgdmp1c3QgPSAwLjgpLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSA1KSArCiAgZmFjZXRfZ3JpZChQaG80IH4gUGFyYW1ldGVyLCBzY2FsZXMgPSAiZnJlZSIsIHNwYWNlID0gImZyZWVfeSIpICsgeWxhYigiTUZJIikgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHR5cGUgPSAiZGl2IikgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygicmVkIiwgTkEpKSArCiAgY29vcmRfZmxpcCgpICsgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMC4wMSwwLjAyKSkgKwogIHRoZW1lX2J3KCkKcDEKYGBgCioqRmlndXJlIDMgQ29ycmVzcG9uZGluZyBQaG80LUdGUCBhbmQgUEhPNXByLW1DaGVycnkgcmVwb3J0ZXIgZmx1b3Jlc2NlbmNlIGludGVuc2l0eSBwZXIgc3RyYWluLioqIFBobzQtR0ZQIGFuZCBQSE81cC1tQ2hlcnJ5IGludGVuc2l0aWVzIHdlcmUgcXVhbnRpZmllZCBvbiBhbiBBdHR1bmUgTnhUIGZsb3cgY3l0b21ldGVyIHVzaW5nIDQwMCBtViBvbiB0aGUgQkwxIGFuZCA0MzAgbVYgb24gdGhlIFlMMiBjaGFubmVscyByZXNwZWN0aXZlbHkuIEFjcXVpc2l0aW9uIHJhdGUgaXMgMjAwIHVsL21pbi4gQXQgbGVhc3QgMTAsMDAwIGV2ZW50cyB3ZXJlIGNvbGxlY3RlZC4gU3RyYWluIElEcyBhcmUgbGlzdGVkIG9uIHRoZSB2ZXJ0aWNhbCBheGlzIGFuZCB0aGUgTWVkaWFuIEZsdW9yZXNjZW50IEludGVuc2l0eSAoTUZJLCBhcmJpdHVyeSB1bml0cykgZm9yIGVhY2ggY2hhbm5lbCBvbiB0aGUgaG9yaXpvbnRhbCBheGlzLiBBbiBhc3RlcmlzayBuZXh0IHRvIGEgYmFyIGluZGljYXRlcyBhbiBvdmVybmlnaHQgZ3Jvd3RoIGluc3RlYWQgb2YgYSBtaWQtbG9nIHBoYXNlIGdyb3d0aCB3YXMgdXNlZCBmb3IgcXVhbnRpZmljYXRpb24uIFRoZSBkYXNoZWQgdmVydGljYWwgbGluZSBmb3IgUGhvNC1HRlAgaW5kaWNhdGVzIHRoZSBhdXRvZmx1b3Jlc2NlbmNlIGFzIGNhbGN1bGF0ZWQgYnkgdGhlIG1lYW4gb2YgdGhlIGludGVuc2l0aWVzIGluIHRoZSBzdHJhaW5zIHdpdGhvdXQgR0ZQOyB0aGUgZGFzaGVkIHZlcnRpY2FsIGxpbmUgZm9yIHRoZSBSRlAgcGxvdCBpbmRpY2F0ZXMgdGhlIGJhc2FsIGxldmVsIGV4cHJlc3Npb24gZnJvbSB0aGUgcmVwb3J0ZXIgd2l0aG91dCBQaG80LCBjYWxjdWxhdGVkIGJ5IHRoZSBhdmVyYWdlIG9mIHlIMjk1IGFuZCB5SDI5NiwgYm90aCBvZiB3aGljaCBsYWNrIFBobzQgYnV0IGhhcyB0aGUgcmVwb3J0ZXIpLgoKX0Rpc2N1c3Npb25fCgotIENnUGhvNCBjbGVhcmx5IGhhcyBubyBkZXBlbmRlbmNlIG9uIFBobzIgd2hlbiBhc3NheWVkIGluIF9TLiBjZXJldmlzaWFlXywgbGFyZ2VseSBjb25zaXN0ZW50IHdpdGggbXkgcHJldmlvdXMgcmVzdWx0cyAoYWx0aG91Z2ggbXkgUk5BLXNlcSBoYXMgaW5kaWNhdGVkIGEgbW9kZXN0IGRlcGVuZGVuY2Ugd2l0aCB+MzAtNDAlIHJlZHVjdGlvbiBpbiBtUk5BIGxldmVscyBvZiBfUEhPNV8gZHJpdmVuIGJ5IENnUGhvNCB3aXRob3V0IFBobzIuKQotIFNjUGhvNCBoYXMgc3Ryb25nIGRlcGVuZGVuY2Ugb24gUGhvMi4gUDEtNCBhbmQgQjEsMiw0IGJvdGggc2hvd2VkIHRoYXQgd2l0aG91dCBQaG8yLCBTY1BobzQgZG9lc24ndCBpbmR1Y2UgcmVwb3J0ZXIgZXhwcmVzc2lvbiBvbiBpdHMgb3duLiBTb21lIGFub3JtYWxpZXMgZXhpc3QgaG93ZXZlciwgYXMgd2lsbCBiZSBkaXNjdXNzZWQgYmVsb3cuCi0gSDEtMyBhcmUgc3VwcG9zZWQgdG8gYmUgU2NQaG80LUVHRlAgd2l0aCB0aGUgUEhPNXByLW1DaGVycnkgYW5kIGFsc28gd2l0aCBTY1BobzIuIEhvd2V2ZXIsIHRoZSByZXN1bHRzIGhlcmUgc3VnZ2VzdCB0aGF0IHRoaXMgc3RyYWluIGhhZCBsaXR0bGUgcmVwb3J0ZXIgaW5kdWN0aW9uLiBJdCBtYXkgYmUgdGhhdCB0aGUgaW50ZWdyYXRlZCBTY1BobzQtRUdGUCwgZXZlbiB0aG91Z2ggaXQgaXMgZXhwcmVzc2VkLCBpcyBub3QgZnVuY3Rpb25hbC4gSXMgdGhpcyBjb25zaXN0ZW50IHdpdGggTGluZHNleSdzIHJlc3VsdHMsIGluY2x1ZGluZyBmbG93IGN5dG9tZXRyeSBhbmQgbGlxdWlkIHBob3NwaGF0YXNlIGFzc2F5cz8KLSBHMiwgMywgNCBoYXZlIG11Y2ggaGlnaGVyIGxldmVscyB0aGFuIGV2ZXJ5b25lIGVsc2UuIEdpdmVuIHRoYXQgdGhlIEcgc3RyYWlucyB3ZXJlIGNvbnN0cnVjdGVkIGJ5IExpbmRzZXkgYnkgaW50ZWdyYXRpbmcgdGhlIHBSUzMwNi1QSE81cHItbUNoZXJyeS1VUkEzIGNvbnN0cnVjdCBpbnRvIHRoZSB1cmEzIGxvY3VzIHVzaW5nIHRoZSBlbmRzLWluIHRyYW5zZm9ybWF0aW9uLCBJIHdvbmRlciBpZiBHMiwzIGFuZCA0LCBqdXN0IGxpa2UgdGhvc2UgbGV1MiBpbnRlZ3JhdGVkIFBobzQgdmFyaWFudHMsIHJlcHJlc2VudCBtdWx0aXBsZSBpbnRlZ3JhdGlvbnMuCi0gTGFzdGx5LCBub3RlIHRoYXQgdGhlIHNldmVyYWwgQSBjbG9uZXMgd2l0aCBoaWdoIFBobzQtR0ZQIChBMywgQTUgYW5kIEE2KSBhbHNvIHNob3dlZCBoaWdoZXIgbGV2ZWxzIG9mIHJlcG9ydGVyIGV4cHJlc3Npb24sIHN1Z2dlc3RpbmcgdGhhdCBpbmNyZWFzaW5nIHRoZSBkb3NlIG9mIFBobzQgY2FuIGNlcnRhaW5seSBwYXJ0aWFsbHkgY29tcGVuc2F0ZSBmb3IgdGhlIGxvc3Mgb2YgUGhvMi4KCiMjIyBfUEhPNXByLW1DaGVycnlfIGluZHVjdGlvbiBsZXZlbHMgbm9ybWFsaXplZCBieSBQaG80IGFidW5kYW5jZQpXZSB3aWxsIGZpcnN0IHRyYW5zZm9ybSB0aGUgcmF3IEdGUCBhbmQgUkZQIGludGVuc2l0aWVzIHRvIG1ha2UgdGhlbSBtb3JlIGludGVycHJldGFibGUuIEZvciB0aGUgR0ZQIGludGVuc2l0eSwgYXMgdGhlcmUgaXMgYSBzdWJzdGFudGlhbCBiYWNrZ3JvdW5kLCB3ZSB3aWxsIHN1YnRyYWN0IHRoZSBiYWNrZ3JvdW5kIGZyb20gYWxsIHRoZSBHRlAtY29udGFpbmluZyBzdHJhaW5zIHRvIG9idGFpbiB0aGUgbWVhbmluZ2Z1bCBtZWFzdXJlIGZvciBQaG80IHByb3RlaW4gbGV2ZWxzLiBGb3IgUkZQLCB0aGVyZSBpcyBtaW5pbWFsIGJhY2tncm91bmQgKHNlZSBiZWxvdykuIEhvd2V2ZXIsIHRoZXJlIGlzIGEgImJhc2FsIiBleHByZXNzaW9uIG9mIHRoZSByZXBvcnRlciBpbiB0aGUgYWJzZW5jZSBvZiBQaG80IC0tIHdoYXQgd2UgYXJlIGludGVyZXN0ZWQgaW4gaXMgbm90IHRoZSBhYnNvbHV0ZSBsZXZlbCBvZiByZXBvcnRlciBleHByZXNzaW9uIGJ1dCB0aGUgZm9sZCBpbmR1Y3Rpb24gY29tcGFyZWQgd2l0aCB0aGUgX3BobzTiiIZfIHN0cmFpbnMuCmBgYHtyIHRyYW5zZm9ybX0KIyBjYWxjdWxhdGUgZ2ZwIGJhY2tncm91bmQKZ2ZwLmJnIDwtIGRhdCAlPiUgZmlsdGVyKFBobzRHRlAgPT0gIk5vLUdGUCIsIFBhcmFtZXRlciA9PSAiUGhvNC1HRlAiKSAlPiUgcHVsbChNZWRpYW4pICU+JSBtZWFuKCkKIyB0cmFuc2Zvcm0KZGF0MSA8LSBkYXQgJT4lIHNlbGVjdCgtQ291bnQsIC1NZWFuLCAtQ1YsIC1yQ1YsIC1QZXJjZW50KSAlPiUgCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IFBhcmFtZXRlciwgdmFsdWVzX2Zyb20gPSBNZWRpYW4pICU+JSAKICBtdXRhdGUoR0ZQLm5vQkcgPSBpZmVsc2UoUGhvNEdGUCA9PSAiTm8tR0ZQIiwgTkEsIGBQaG80LUdGUGAgLSBnZnAuYmcpLAogICAgICAgICBSRlAubm9CRyA9IGlmZWxzZShQSE81UkZQLCBgUEhPNXByLW1DaGVycnlgIC0gcmZwLmJnLCAwKSwKICAgICAgICAgUkZQLkZDID0gaWZlbHNlKFBITzVSRlAsIFJGUC5ub0JHIC8gcmZwLmJhc2FsLCBOQSksCiAgICAgICAgIG5SRlAuRkMgPSBSRlAuRkMgLyBHRlAubm9CRyAqIG1lZGlhbihHRlAubm9CRywgbmEucm0gPSBUKSkKYGBgCgpgYGB7ciBwbG90X25vcm1hbGl6ZWRfaW5kdWN0aW9uLCBmaWcuaGVpZ2h0ID0gNywgZmlnLndpZHRoPTEwLCB3YXJuaW5nPUZBTFNFfQpkYXQyIDwtIGRhdDEgJT4lIGZpbHRlcihQaG80R0ZQICE9ICJOby1HRlAiLCBQSE81UkZQKQpwMSA8LSBkYXQyICU+JSAKICBtdXRhdGUoR0ZQLm5vQkcgPSBHRlAubm9CRyAvIDEwMDAsIFJGUC5ub0JHID0gUkZQLm5vQkcgLyAxMDAwKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKEdGUC5ub0JHLCBSRlAubm9CRyksIG5hbWVzX3RvID0gIlBhcmFtZXRlciIsIHZhbHVlc190byA9ICJWYWx1ZSIpICU+JQogIG11dGF0ZShQYXJhbWV0ZXIgPSBmYWN0b3IoUGFyYW1ldGVyLCBsZXZlbHMgPSBjKCJHRlAubm9CRyIsICJSRlAubm9CRyIpLCAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJQaG80LUdGUCBhYnVuZGFuY2UiLCAiUEhPNXByLW1DaGVycnkgbGV2ZWwiKSksCiAgICAgICAgIEdyb3VwID0gZmFjdG9yKEdyb3VwLCBsZXZlbHMgPSBjKCJjb250cm9sIiwgImVuZG9nZW5vdXMiLCAiZXhvZ2Vub3VzIiwgInBsYXNtaWQiKSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBTYW1wbGUsIHkgPSBWYWx1ZSwgZmlsbCA9ICBHcm91cCwgY29sb3IgPSBQSE8yKSkgKyAKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZTIod2lkdGggPSAwLjkpKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGlmZWxzZShHcm93dGggPT0gIm92biIsICIqIiwgIiIpLCBoanVzdCA9IC0wLjIsIHZqdXN0ID0gMC44KSwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gNSkgKwogIGZhY2V0X2dyaWQoUGhvNEdGUCB+IFBhcmFtZXRlciwgc2NhbGVzID0gImZyZWUiLCBzcGFjZSA9ICJmcmVlX3kiKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIodHlwZSA9ICJkaXYiLCBkcm9wID0gRkFMU0UpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoInJlZCIsIE5BKSkgKwogIGNvb3JkX2ZsaXAoKSArIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAuMDEsMC4wMiksIHRyYW5zID0gInNxcnQiKSArIHlsYWIoIk1GSSAoeDEwMDAsIGEudS4pIikgKyAKICB0aGVtZV9idygpCiAgCnAyIDwtIGRhdDIgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gYyhSRlAuRkMsIG5SRlAuRkMpLCBuYW1lc190byA9ICJQYXJhbWV0ZXIiLCB2YWx1ZXNfdG8gPSAiVmFsdWUiKSAlPiUKICBtdXRhdGUoUGFyYW1ldGVyID0gZmFjdG9yKFBhcmFtZXRlciwgbGV2ZWxzID0gYygiUkZQLkZDIiwgIm5SRlAuRkMiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJQSE81IGZvbGQgaW5kdWN0aW9uIiwgIlBITzUgaW5kdWN0aW9uIC8gUGhvNC1HRlAiKSksCiAgICAgICAgIEdyb3VwID0gZmFjdG9yKEdyb3VwLCBsZXZlbHMgPSBjKCJjb250cm9sIiwgImVuZG9nZW5vdXMiLCAiZXhvZ2Vub3VzIiwgInBsYXNtaWQiKSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBTYW1wbGUsIHkgPSBWYWx1ZSwgZmlsbCA9ICBHcm91cCwgY29sb3IgPSBQSE8yKSkgKyAKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZTIod2lkdGggPSAwLjkpKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMSwgbGluZXR5cGUgPSAyKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGlmZWxzZShHcm93dGggPT0gIm92biIsICIqIiwgIiIpLCBoanVzdCA9IC0wLjIsIHZqdXN0ID0gMC44KSwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gNSkgKwogIGZhY2V0X2dyaWQoUGhvNEdGUCB+IFBhcmFtZXRlciwgc2NhbGVzID0gImZyZWUiLCBzcGFjZSA9ICJmcmVlX3kiKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIodHlwZSA9ICJkaXYiLCBkcm9wID0gRikgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygicmVkIiwgTkEpKSArCiAgY29vcmRfZmxpcCgpICsgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMC4wMSwwLjAyKSwgdHJhbnMgPSAic3FydCIpICsgeWxhYigiRm9sZCBJbmR1Y3Rpb24iKSArIHhsYWIoIiIpICsKICB0aGVtZV9idygpCgojIyBwbGFjZSBzaGFyZWQgbGVnZW5kIGF0IHRoZSBib3R0b20KIyMgcmVmZXJlbmNlOiBodHRwczovL3dpbGtlbGFiLm9yZy9jb3dwbG90L2FydGljbGVzL3NoYXJlZF9sZWdlbmRzLmh0bWwKbGVnZW5kIDwtIGdldF9sZWdlbmQoCiAgcDEgKyAKICBndWlkZXMoY29sb3IgPSBndWlkZV9sZWdlbmQobnJvdyA9IDEpLCBmaWxsID0gZ3VpZGVfbGVnZW5kKG5yb3cgPSAxKSkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQopCnByb3cgPC0gcGxvdF9ncmlkKAogIHAxICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIiksCiAgcDIgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSwKICBhbGlnbiA9ICd2aCcsCiAgbGFiZWxzID0gYygiQSIsICJCIiwgIkMiKSwKICBoanVzdCA9IC0xLAogIG5yb3cgPSAxCikKcGxvdF9ncmlkKHByb3csIGxlZ2VuZCwgbmNvbCA9IDEsIHJlbF9oZWlnaHRzID0gYygxLCAuMSkpCmBgYAoqKkZpZ3VyZSA0IENvbXBvc2l0ZSBwbG90IGluY2x1ZGluZyBQaG80IGFidW5kYW5jZSwgX1BITzVfIHJlcG9ydGVyIHN0cmVuZ3RoIGFuZCBmb2xkIGluZHVjdGlvbiB2YWx1ZXMuKiogUGhvNC1HRlAgYW5kIFBITzVwLW1DaGVycnkgaW50ZW5zaXRpZXMgd2VyZSBxdWFudGlmaWVkIGFzIGRlZmluZWQgYWJvdmUuIFN0cmFpbiBJRHMgYXJlIGxpc3RlZCBvbiB0aGUgdmVydGljYWwgYXhpcy4gSW4gKiooQSkqKiwgdGhlIHgtYXhpcyB2YWx1ZXMgcmVwcmVzZW50IHRoZSBNZWRpYW4gRmx1b3Jlc2NlbnQgSW50ZW5zaXR5IChNRkksIGFyYml0dXJ5IHVuaXRzKSBmb3IgZWl0aGVyIFBobzQtR0ZQIG9yIFBITzVwci1tQ2hlcnJ5IGFmdGVyIHN1YnRyYWN0aW5nIHRoZSBiYWNrZ3JvdW5kIChiYXNlZCBvbiBzdHJhaW5zIHdpdGhvdXQgdGhlIGNvcnJlc3BvbmRpbmcgZmx1b3Jlc2NlbnQgcHJvdGVpbikuIEluICoqKEIpKiosIHRoZSBmb2xkIGNoYW5nZSBmb3IgX1BITzVfIHJlcG9ydGVyIGlzIGNhbGN1bGF0ZWQgYXMgdGhlIGJhY2tncm91bmQtc3VidHJhY3RlZCBSRlAgbGV2ZWwgZGl2aWRlZCBieSB0aGUgYmFzYWwgZXhwcmVzc2lvbiBsZXZlbCwgYXMgbWVhc3VyZWQgYnkgdGhlIG1lYW4gb2YgdGhlIHR3byBzdHJhaW5zIGNvbnRhaW5pbmcgdGhlIHJlcG9ydGVyIGJ1dCBoYXZlIF9waG804oiGXy4gVGhlIG5vcm1hbGl6ZWQgaW5kdWN0aW9uIHJhdGlvIG9uIHRoZSByaWdodCBjb2x1bW4gaXMgY2FsY3VsYXRlZCBieSBkaXZpZGluZyB0aGUgaW5kdWN0aW9uIGZvbGQgY2hhbmdlIGZyb20gdGhlIGxlZnQgY29sdW1uIGJ5IHRoZSBjb3JyZXNwb25kaW5nIFBobzQtR0ZQIChiYWNrZ3JvdW5kIHN1YnRyYWN0ZWQpIGxldmVscyBhbmQgbXVsdGlwbGllZCBieSB0aGUgbWVkaWFuIFBobzQtR0ZQIGxldmVscyBvZiBhbGwgc3RyYWlucy4gVGhlIGRhc2hlZCBsaW5lcyBpbiBib3RoIGNvbHVtbnMgaW5kaWNhdGUgdGhlIGluZHVjdGlvbiBmb2xkIGNoYW5nZSBvZiAxLCBpLmUuIG5vIGNoYW5nZSBjb21wYXJlZCB0byB0aGUgX3BobzTiiIZfIHN0cmFpbnMuIEluIGJvdGggcGFuZWxzLCB0aGUgeC1heGVzIGFyZSBzcXVhcmUtcm9vdCB0cmFuc2Zvcm1lZCBzbyBhcyB0byBicmluZyBvdXRsaWVycyBpbnRvIHRoZSBwbG90IHdpdGhvdXQgY29tcHJlc3NpbmcgdGhlIHJlc3Qgb2YgdGhlIGRhdGEgcmFuZ2UuIEFuIGFzdGVyaXNrIG5leHQgdG8gYSBiYXIgaW5kaWNhdGVzIGFuIG92ZXJuaWdodCBncm93dGggaW5zdGVhZCBvZiBhIG1pZC1sb2cgcGhhc2UgZ3Jvd3RoIHdhcyB1c2VkIGZvciBxdWFudGlmaWNhdGlvbi4KCl9EaXNjdXNzaW9uc18KCi0gSWYgd2UgbG9vayBob3Jpem9udGFsbHkgYWNyb3NzIHRoZSBmb3VyIGNvbHVtbnMgZm9yIGVhY2ggYWxwaGFiZXRpYyBncm91cCAoQSwgQiwgQywgLi4uLCBQKSwgd2UgY2FuIHNlZSB0aGF0IHRoZSBwbGFzbWlkIGJvcm4gUGhvNCdzIGFjdHVhbGx5IGJlaGF2ZSBwcmV0dHkgd2VsbCwgZXNwZWNpYWxseSBhZnRlciBub3JtYWxpemluZyB0aGUgUkZQIGluZHVjdGlvbiBmb2xkIGNoYW5nZSBieSB0aGUgUGhvNCBhYnVuZGFuY2UuCi0gTmV4dCwgdGhlIGVuZG9nZW5vdXNseSBpbnRlZ3JhdGVkIFNjUGhvNC1tTmVvbiBzaG93ZWQgc21hbGwgY2xvbmUtdG8tY2xvbmUgdmFyaWFiaWxpdHkgaW4gdGhlIEdGUCBsZXZlbCwgYnV0IHNob3dlZCBodWdlIHZhcmlhdGlvbiBpbiB0aGUgX1BITzVwci1tQ2hlcnJ5XyBsZXZlbHMuIFRoZSBub3JtYWxpemVkIGluZHVjdGlvbiBmb2xkIGNoYW5nZXMgY29udGludWUgdG8gc2hvdyB0aGUgZHJhbWF0aWMgZGlmZmVyZW5jZXMgYmV0d2VlbiBjbG9uZXMuIEFzIG1lbnRpb25lZCBiZWZvcmUsIHdlIHN1c3BlY3QgdGhpcyBpcyBkdWUgdG8gdGhlIG11bHRpLWludGVncmF0aW9uIG9mIHRoZSByZXBvcnRlciBjb25zdHJ1Y3QgYXQgdGhlIHVyYTMgbG9jdXMuCi0gVGhlIGV4b2dlbm91c2x5IGludGVncmF0ZWQgU2NQaG80LW1OZW9uIGV4aGliaXRlZCBsYXJnZSBjbG9uZS10by1jbG9uZSB2YXJpYWJpbGl0eSBpbiB0aGUgR0ZQIGxldmVsLCBhZ2FpbiBwb3NzaWJseSBkdWUgdG8gbXVsdGktaW50ZWdyYXRpb24gb2YgdGhlIFBobzQtR0ZQIGluIHRoZSBfbGV1Ml8gbG9jdXMuIFRoZSBub3JtYWxpemF0aW9uIGJ5IFBobzQgYWJ1bmRhbmNlIGRpZG4ndCBmdWxseSByZW1vdmUgdGhlIGRpZmZlcmVuY2UsIGxpa2VseSBiZWNhdXNlIHRoZSBpbmR1Y3Rpb24gZm9sZCBjaGFuZ2UgZG9lc24ndCBzY2FsZSBsaW5lYXJseSB3aXRoIFBobzQgbGV2ZWxzIChzYXR1cmF0aW9uIGVmZmVjdCkuCi0gU2NQaG80LUVHRlAsIGJvdGggdGhlIGVuZG9nZW5vdXNseSBhbmQgZXhvZ2Vub3VzbHkgaW50ZWdyYXRlZCBvbmVzLCBoYWQgaXNzdWVzIHRoYXQgcHJldmVudCBhIGNsZWFyIGludGVycHJldGF0aW9uLgotIENnUGhvNC1tTmVvbiBpcyBzaW1pbGFyIHRvIFNjUGhvNC1tTmVvbiBpbiB0aGF0IGl0IHNob3dlZCByZWxhdGl2ZWx5IGNvbnNpc3RlbnQgR0ZQIGxldmVscyBleGNlcHQgZm9yIEMyLCB3aGljaCBtYXkgYmUgbXVsdGktaW50ZWdyYXRpb24uIFRoZSBub3JtYWxpemVkIGluZHVjdGlvbiBmb2xkIGNoYW5nZXMgYXJlIHByZXR0eSBjb25zaXN0ZW50IHdpdGggb3Igd2l0aG91dCBQaG8yLCBleGNlcHQgZm9yIEMyLCB3aGljaCBzaG93ZWQgYSBsb3dlciB2YWx1ZSBsaWtlbHkgaW5kaWNhdGluZyBub24tbGluZWFyIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBpbmR1Y3Rpb24gYW5kIFBobzQgYWJ1bmRhbmNlLgoKIyMgQ29uY2x1c2lvbnMKLSBtTmVvbiBhcHBlYXJzIHRvIGJlIGFzIGdvb2QgYXMsIGlmIG5vdCBiZXR0ZXIgdGhhbiBFR0ZQIGluIHRlcm1zIG9mIGJvdGggYnJpZ2h0bmVzcyBhbmQga2VlcGluZyB0aGUgdGFnZ2VkIFBobzQgZnVuY3Rpb25hbC4KLSB0aGUgZW5kcy1pbiBpbnRlZ3JhdGlvbiBzZWVtcyB0byBnZW5lcmF0ZSBtdWx0aXBsZSBpbnRlZ3JhdGlvbnMgZnJlcXVlbnRseSAobWF5YmUgYSByZXN1bHQgb2YgZXhjZXNzIGRpZ2VzdGVkIHBsYXNtaWQ/IGJ1dCB3ZSBhcmUgYWxzbyBmaWdodGluZyByZWxhdGl2ZWx5IGxvdyB0cmFuc2Zvcm1hdGlvbiBlZmZpY2llbmN5KQotIGluY3JlYXNpbmcgdGhlIGRvc2Ugb2YgU2NQaG80IGNhbiBwYXJ0aWFsbHkgY29tcGVuc2F0ZSBmb3IgdGhlIGxvc3Mgb2YgUGhvMiwgd2hpY2ggZnVydGhlciBoaWdobGlnaHRzIHRoZSBpbXBvcnRhbmNlIG9mIGVuc3VyaW5nIGVxdWFsIG9yIGhpZ2hseSBzaW1pbGFyIGxldmVscyBvZiBleHByZXNzaW9uIGZvciBhbGwgY29uc3RydWN0cyB0byBiZSB0ZXN0ZWQu