1 Introduction

The data from the CRD (Completely Randomized Design) were analyzed using a one-way ANOVA procedure. Since the treatment is a factor with different groups (representing different doses), it influences the response variable. One-way ANOVA, also called one-factor ANOVA, focuses on testing whether there is a treatment effect. In statistical terms, this is equivalent to testing the null hypothesis:

\[ H_0: \mu_1 = \mu_2 = \cdots = \mu_t. \]

Under this null hypothesis, the variance between treatments and the variance within treatments are approximately the same. Thus, we assess the equality of means across treatments by analyzing these variances, as summarized in the classical ANOVA table.

The key information \(MS_B\) and \(MS_W\) used to construct the test statistic are based on the \(SS_B\) and \(SS_W\) extracted from the total sum of squares.

\[ SS_T = SS_B + SS_W. \]

Two fundamental assumptions for the one-way ANOVA analysis are

  • Populations are normally distributed
  • Variances of treatment groups are equal

Under the null hypothesis \(H_0: \mu_1 = \mu_2 = \cdots = \mu_t\)

\[ F = \frac{SS_B/t-1}{SS_W/n-t} \rightarrow F_{t-1, \ n-t} \]

Where \(t\) is the number of treatment groups and \(n\) is the sample size.


The RBD designs add one additional factor variable. We are interested in assessing the effects of both the additional factor and the treatment effect. If the RBD has replicates, we also assess the potential interaction effect. Because of the additional factor, the decomposition of the total sum of squares becomes more complex, although the logic and mathematical derivation are the same as the one-way ANOVA.

Before discussing the construction of ANOVA for replicated RBD data, we first look at an example to see what practical questions we can answer based on the data collected from a replicated RBD.

Plant Grouth: a botanist wants to know whether or not plant growth is influenced by sunlight exposure and watering frequency. She plants 40 seeds and lets them grow for two months under different conditions for sunlight exposure and watering frequency. After two months, she records the height of each plant. The results are shown below:

Clearly, this is a balanced RBD with replications. The data structure required for analysis with software programs will be discussed later.


2 Hypotheses and Testing Methods

We will formulate the hypotheses based on the practical questions to be addressed based on replicated RBD data and set up the two-way ANOVA table for testing the hypothesis, along with the fundamental assumptions required for the two-way ANOVA.

2.1 Setting Up Hypotheses

As we see in the Plant Growth example, the practical question is whether sunlight exposure and watering frequency affect plant growth. The practical question has several sub-questions from an analytical point of view. For convenience, let call sunlight exposure Factor A and watering frequency Factor B. The related hypotheses associated with the original practical question are

  • Main Effect of Factor A:

\[ H_0: \text{All levels of Factor A have the same mean effect.} \ \ \text{vs} \ \ H_a: \text{At least one level of Factor A has a different mean effect.} \]

  • Main Effect of Factor B:

\[ H_0: \text{All levels of Factor B have the same mean effect.} \ \ \text{vs} \ \ H_a: \text{At least one level of Factor B has a different mean effect.} \]

  • Interaction Effect (A × B):

\[ H_0: \text{There is no interaction between Factor A and Factor B.} \ \ \text{vs} \ \ H_a: \text{There is a significant interaction effect.} \]

3 Two-way ANOVA

Two-way ANOVA is used to analyze the effects of two independent categorical variables (factors) on a continuous dependent variable while also assessing the interaction between these factors. Unlike one-way ANOVA, which examines only one factor, two-way ANOVA allows researchers to determine whether the two factors independently influence the outcome and whether their combined effect (interaction) is significant.

3.1 Two-Way ANOVA Table Structure

Because two factors are involved in the analysis, the mathematical decomposition of the total square into more components for testing the above three hypotheses is much more complex than the one-way ANOVA; algebra is not difficult. We will not derive the components in the ANOVA table based on the raw data values. Instead, we focus on the structure of the ANOVA table and how to use the key statistics in the table to test the above hypotheses. We use software programs to generate the ANOVA table. We first introduce some notations to help understand the ANOVA table.

  • Number of categories in factor A: \(a\)
  • Number of categories in factor B: \(b\)
  • Total sample size: \(N\)
  • Total Sum of Squares: \(SST\)
  • Sum of Squares for Factor A: \(SSA\) (Variation due to factor A).
  • Sum of Squares for Factor B: \(SSB\) (Variation due to factor B).
  • Sum of Squares for Interaction between Factor A and Factor B: \(SSAB\) (Variation due to the interaction between Factor A and Factor B).
  • Residual Sum of Squares: \(SSE\) (Unexplained variation - error).

Mathematically

\[ SST = SSA + SSB + SSAB + SSE \]

Each Sum of Squares has its own degrees of freedom. Next, we list the degrees of freedom os each of the sum of squares:

  • DF.A = \(a - 1\)
  • DF.B = \(b - 1\)
  • DF.AB = \((a-b)\times (b-1)\) (interaction term)
  • DF.E = \(N - ab\)
  • DF.T = \(N - 1\)

Note that \(N -1 = (a-1) + (b-1) + (a-1)(b-1) + N - ab\).

With the above notations, we introduce the two-way ANOVA table.

The first three rows of the table contain information related to testing the above three hypotheses. In one-way ANOVA, we used the F-distribution to find the p-value for a statistical decision under some assumptions as mentioned in the first section. We also need to make some assumptions in order to specify the distributions of F statistics. Next, we discuss the assumptions of two-way ANOVA and testing the hypotheses.


3.2 Assumptions of Two-Way ANOVA

As we know, in the one-way ANOVA table, the F value follows an F distribution under some assumptions. In the two-way ANOVA, we also need the following assumptions to make inferences about the three F statistics:

  • Normality: The dependent variable should be normally distributed within each combination of factor levels.

  • Homogeneity of Variance (Homoscedasticity): The variances across groups defined by each combination of factor levels should be equal. In practice, we usually perform a formal test to check this assumption.

  • Independence of Observations: Data points should be independent, meaning the measurement of one subject does not influence another. This assumption is hard to test for independence.. We usually justify the data collection process.

  • Random Sampling: Data should be collected using a random sampling method. This is justified by the data collection process.

Violations of these assumptions may require transformations or non-parametric alternatives like the Kruskal-Wallis test.


Assume that all the above assumptions are met. Next, we discuss the distribution of the test statistics for testing the three hypotheses.


  • Effect of Factor A: under the following null hypothesis,

\[ H_0: \text{All levels of Factor A have the same mean effect.} \] The test statistic

\[ F_A = \frac{MS_A}{SS_E} \rightarrow F_{a-1,\ n-ab }. \]

The p-value can be found from \(F_{a-1,\ n-ab }\).


  • Effect of Factor B: under the following null hypothesis,

\[ H_0: \text{All levels of Factor B have the same mean effect.} \] The test statistic

\[ F_B = \frac{MS_B}{MS_E} \rightarrow F_{b-1, \ n - ab} \]

The p-value can be found from \(F_{b-1,\ n-ab }\).


  • Interactive Effect between Factor A and Factor B: under the following null hypothesis,

\[ H_0: \text{There is no interaction between Factor A and Factor B.} \] The test statistic

\[ F_{AB} = \frac{MS_{AB}}{MS_E} \rightarrow F_{(a-b)(b-1), n -ab} \] The p-value can be found from \(F_{(a-1)(b-1),\ n-ab }\).


Remarks: understanding the structure of the ANOVA table is crucial.

  • If the first two columns are given, you are expected to derive the rest of the columns, including the p-values in the last column, using the R command pf(F, df1, df2, lower.tail = FALSE) (F table is not recommended).

  • The interaction effect is not available if working with RBD data with no replicates.


3.3 Performing ANOVA Using R

The R function aov() will be used to perform an ANOVA test. If the given data table is in wide format, we need to reformat it into a long table. This involves placing all response values in a single column and using two separate columns to label each response value with its associated factors.

The R function rep() is useful for generating patterned data. Its syntax is rep(data.value, times = n), which means it replicates data.value n times. The data.value argument can be either a single value or a vector of values. Below are some examples demonstrating how to use rep() to create patterned data.

rep(5, times = 3)   # replicate 5 three times
| [1] 5 5 5
rep("a", 9)         # replicate lowercase letter "a" 9 times
| [1] "a" "a" "a" "a" "a" "a" "a" "a" "a"
rep(c(1,3,5), 3)    # replicate vector (1,3,5) three times
| [1] 1 3 5 1 3 5 1 3 5
rep(rep(c("A", "B"), 2), 3) # nested replicate rep(c("A", "B")) three times
|  [1] "A" "B" "A" "B" "A" "B" "A" "B" "A" "B" "A" "B"

Next, we work on the wide table in the example given in Section 1.

## first, define 4 column vectors
None = c(4.8, 4.4, 3.2, 3.9, 4.4, 4.4, 4.2, 3.8, 3.7, 3.9)
Low = c(5.0, 5.2, 5.6, 4.3, 4.8, 4.9, 5.3, 5.7, 5.4, 4.8)
Medium = c(6.4, 6.2, 4.7, 5.5, 5.8, 5.8, 6.2, 6.3, 6.5, 5.5)
High = c(6.3, 6.4, 5.6, 4.8, 5.8, 6.0, 4.9, 4.6, 5.6, 5.5)
## Place the above values in a single column
growth <- c(None, Low, Medium, High)
## define sunlight labels
sunlight <- c(rep("None", length(None)), rep("Low", length(Low)),
              rep("Medium", length(Medium)), rep("High", length(High)))
## Watering patterns
## The inner rep() returns the pattern of first column
## The outer rep() replicate the rest of the columns
watering <-rep(c(rep("Daily", 5), rep("Weekly", 5)),4) 
## Store variables in a data frame
growthData <- data.frame(growth = growth, sunlight = sunlight, watering = watering)
## check the data frame
#growthData

We now perform the ANOVA using the data frame.

# We fit an ANOVA with an interactive effect
growth.aov <- aov(growth ~ sunlight*watering, data = growthData)
summary(growth.aov)
|                   Df Sum Sq Mean Sq F value  Pr(>F)    
| sunlight           3 18.765   6.255  23.049 3.9e-08 ***
| watering           1  0.000   0.000   0.001   0.976    
| sunlight:watering  3  1.011   0.337   1.242   0.311    
| Residuals         32  8.684   0.271                    
| ---
| Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Formal Summary of ANOVA: Two formats of write-up are recommended.

Format 1

The above two-way ANOVA revealed a significant main effect of sunlight (\(F(3, 32) = 23.049\)), \(p \approx 0\)), indicating that the plant heights (growth) were significantly higher when exposed to more sunlight. Neither the main effect of watering frequency (\(F(1, 32) = 0.01, p = 0.976\)) nor the sunlight and watering frequency interaction (\(F(1,32) =1.242, p = 0.311\)) was statistically significant.

Format 2

A two-way ANOVA was conducted, yielding the following findings:

  • Watering Frequency: No significant effect on plant growth (F(1, 32) = 0.01, p = 0.976).

  • Sunlight Exposure: Significant effect on plant growth (F(3, 32) = 23.049, p < 0.001). We will conduct a post-hoc comparison (e.g., Tukey’s HSD) would determine which sunlight levels differ.

  • Interaction (Watering × Sunlight): No significant interaction (F(3, 32) = 1.242, p = 0.311), indicating that the effect of sunlight does not depend on watering frequency.

4 Post-hoc Test

The interpretation of post hoc tests becomes more complex when two or more factors are included in an ANOVA, especially when interaction effects are present. In such cases, it is often useful to create line plots showing the means of the primary factor at each level of the secondary factor. As an illustrative example, we will use the data frame created in the previous section to calculate the means of groups defined by the combination of watering and sunlight. The R function aggregate() can be used to compute these group means. In general, aggregate() is used to summarize the values within groups using descriptive statistics such as the mean, variance, maximum, minimum, etc. The syntax of aggregate() is shown below.

## We use the data frame "growthData" created in the previous section 
grp.means <- aggregate(growth ~ watering + sunlight, data = growthData, mean)
## checking the resulting table
#grp.means
## split into daily means and weekly means
## using which() to find the rows in which watering is "Daily" and "Weekly" respectively
daily.id <- which(grp.means$watering == "Daily")
weekly.id <- which(grp.means$watering == "Weekly")
## subset of means of sunlight at its individual levels
daily.avg <- grp.means[daily.id, 3]
weekly.avg <- grp.means[weekly.id, 3]
### draw line plots of

We have not formally introduced the R base plot function with details. Next, we briefly introduce the base R function plot():

plot(x, y, type = "b", xaxt = "n", xlab = "Category", ylab = "Value", main = "Custom X-Axis Labels")

where * x horizontal x-axis * y vertical y-axis * type = "b" draws both points and lines. * xlab= the label of x-axis * ylab = the label of y-axis * main= the title of the plot * xaxt = "n" suppresses the default x-axis. * axis(side = 1, ...) adds a customized horizontal axis.

The code below draws a line plot of the mean sunlight levels for each watering level.

# Custom tick mark positions and labels
x.ticks <- c(1,2,3,4)                           # tick marks / location of tick labels
x.labels <- c("None", "Low", "Medium", "High")

# Create the plot without x-axis (xaxt = "n")
plot(c(1,2,3,4), weekly.avg, 
     type = "b",
     xaxt = "n", 
     xlab = "Sunlight", 
     ylab = "Length (growth)", 
     col = "red",          # color of the line graph
     lty = 1,              # line type. 1 = solid line
     main = "Mean Length across Sunlight Level")
## Add a line plot of weekly watering
lines(c(1,2,3,4), daily.avg, 
      col = "blue",
      lty = 1)
# Add custom x-axis
axis(side = 1, at = x.ticks, labels = x.labels)
## Add a legend to specify the watering level
legend("bottomleft",              # location for the legend
       c("Weekly", "Daily"),      # names of line plot, Caution: keep the order of the names!
       lty = c(1,1),
       col = c("red", "blue"),
       bty = "n"                  # don't include the box of the legend
       )

If the two line graphs are parallel (i.e., there is NO intersection), the factors watering and sunlight do not have an interactive effect!. Otherwise, the two factors do have an interactive effect!

Graphical Interpretations:

  • Main Effect interpret sunlight patterns (trends) at each watering level:
    • When watered weekly, the plant grew best with medium sunlight and poorest with the high sunlight.
    • The same growth patterns were observed when watering daily.
  • Interactive effect cross comparison between watering frequencies
    • The plants grew better with Low and Medium sunlight when watered weekly
    • However, the plant grew better with None and High sunlight when watered daily

The following subsections provide detailed numerical comparisons with differences and associated confidence intervals.

4.1 ANOVA with No Interactive Effect

If there is no interaction effect, we interpret the main effects of the factor variables independently. In the plant growth analysis, the key factor is sunlight, and the secondary factor is watering. We compare the main effects of the key and secondary factors separately. For example:

  • Sunlight (Key Factor): Compare mean outcomes across sunlight levels, ignoring watering. “High sunlight yields higher growth than low sunlight, averaged over all watering levels.

The above line plot shows that the growth rate generally decreases as sunlight increases, except at the medium sunlight level, at which the rate peaks.


  • Watering (Secondary Factor): Compare means across watering levels, ignoring sunlight. Frequent watering increases growth, but this effect is smaller than sunlight’s effect.

The plot above shows that the plant grew better when watered daily.


4.2 ANOVA with Interactive Effect

After finishing the ANOVA test, we report multiple comparisons between groups associated with the significant factors. If a two-way ANOVA reveals a significant interaction effect, it means the impact of one factor (e.g., Sunlight Exposure) depends on the level of the other factor (e.g., Watering Frequency). To interpret this interaction properly, we must:

  • Compare groups within combinations (e.g., “Daily + Low Sunlight” vs. “Weekly + Medium Sunlight”).

  • Control for inflated Type I error rates (false positives) due to multiple comparisons by using simultaneous methods such as Tukey’s HSD to adjust p-values to maintain the family-wise error rate (FWER) at a set level (e.g., 5%).

In the above plant growth dataset, the ANOVA test suggests insignificance of the interactive effect between sunlight and watering. The only significant factor is sunlight. For illustration, we perform simultaneous comparisons for individual factors and their interactions using Tukey’s HSD.

The general idea in interpreting multiple comparisons is to focus on the key factor (such as sunlight) and break down the secondary factor (watering)

anova.interact <- aov(growth ~ sunlight*watering, data = growthData)  
TukeyHSD(anova.interact)  # Compare sunlight levels within Daily watering 
|   Tukey multiple comparisons of means
|     95% family-wise confidence level
| 
| Fit: aov(formula = growth ~ sunlight * watering, data = growthData)
| 
| $sunlight
|              diff        lwr        upr     p adj
| Low-High    -0.45 -1.0811999  0.1811999 0.2353814
| Medium-High  0.34 -0.2911999  0.9711999 0.4730539
| None-High   -1.48 -2.1111999 -0.8488001 0.0000023
| Medium-Low   0.79  0.1588001  1.4211999 0.0095962
| None-Low    -1.03 -1.6611999 -0.3988001 0.0005862
| None-Medium -1.82 -2.4511999 -1.1888001 0.0000000
| 
| $watering
|                diff        lwr       upr    p adj
| Weekly-Daily -0.005 -0.3405535 0.3305535 0.975975
| 
| $`sunlight:watering`
|                             diff         lwr         upr     p adj
| Low:Daily-High:Daily       -0.80 -1.86724928  0.26724928 0.2626201
| Medium:Daily-High:Daily    -0.06 -1.12724928  1.00724928 0.9999996
| None:Daily-High:Daily      -1.64 -2.70724928 -0.57275072 0.0005069
| High:Weekly-High:Daily     -0.46 -1.52724928  0.60724928 0.8523023
| Low:Weekly-High:Daily      -0.56 -1.62724928  0.50724928 0.6873529
| Medium:Weekly-High:Daily    0.28 -0.78724928  1.34724928 0.9884511
| None:Weekly-High:Daily     -1.78 -2.84724928 -0.71275072 0.0001516
| Medium:Daily-Low:Daily      0.74 -0.32724928  1.80724928 0.3529276
| None:Daily-Low:Daily       -0.84 -1.90724928  0.22724928 0.2118374
| High:Weekly-Low:Daily       0.34 -0.72724928  1.40724928 0.9657630
| Low:Weekly-Low:Daily        0.24 -0.82724928  1.30724928 0.9954055
| Medium:Weekly-Low:Daily     1.08  0.01275072  2.14724928 0.0456827
| None:Weekly-Low:Daily      -0.98 -2.04724928  0.08724928 0.0905656
| None:Daily-Medium:Daily    -1.58 -2.64724928 -0.51275072 0.0008466
| High:Weekly-Medium:Daily   -0.40 -1.46724928  0.66724928 0.9217373
| Low:Weekly-Medium:Daily    -0.50 -1.56724928  0.56724928 0.7925032
| Medium:Weekly-Medium:Daily  0.34 -0.72724928  1.40724928 0.9657630
| None:Weekly-Medium:Daily   -1.72 -2.78724928 -0.65275072 0.0002546
| High:Weekly-None:Daily      1.18  0.11275072  2.24724928 0.0219109
| Low:Weekly-None:Daily       1.08  0.01275072  2.14724928 0.0456827
| Medium:Weekly-None:Daily    1.92  0.85275072  2.98724928 0.0000450
| None:Weekly-None:Daily     -0.14 -1.20724928  0.92724928 0.9998578
| Low:Weekly-High:Weekly     -0.10 -1.16724928  0.96724928 0.9999854
| Medium:Weekly-High:Weekly   0.74 -0.32724928  1.80724928 0.3529276
| None:Weekly-High:Weekly    -1.32 -2.38724928 -0.25275072 0.0073419
| Medium:Weekly-Low:Weekly    0.84 -0.22724928  1.90724928 0.2118374
| None:Weekly-Low:Weekly     -1.22 -2.28724928 -0.15275072 0.0161418
| None:Weekly-Medium:Weekly  -2.06 -3.12724928 -0.99275072 0.0000134

The above simultaneous multiple comparisons are presented in the form of confidence intervals for the differences, as well as adjusted p-values to ensure that the overall p-value is not inflated. As the number of combinations of factor levels increases, interpreting the confidence intervals becomes more difficult. To aid interpretation, we provide a visual representation of the outputted confidence intervals.

The first two plots correspond to the first two sets of confidence intervals. The interpretation of these confidence tables and figures is straightforward. However, the number of intervals associated with interaction effects increases as the number of factor levels grows, making interpretation more complex. In the plant growth example, the two factors result in 28 different group comparisons! Practically meaningful comparisons focus on differences in growth rates under the same sunlight conditions but with different watering frequencies.

par(mai=c(1.5,3,1,1))           # Makes room on the plot for the group names
plot(TukeyHSD(anova.interact),  # name of the TukeyHSD() object
     cex.lab = 0.6,             # adjust the font size of the labels of the 
                                # vertical axis
     las = 1) 

The line segments represent confidence intervals. The middle bar indicates the estimated difference, and the two ends represent the lower and upper bounds of the confidence interval. The vertical dashed line represents zero. That is, if a line segment intersects the vertical dashed line, the confidence interval includes zero. This implies that the difference is not statistically significant. Therefore, we conclude that there is no significant difference between the two means associated with the underlying groups.

The across comparison we should focus on is highlighted in the following figure.

Among all confidence intervals, the following intervals should be reported.

Group Difference diff lower CI upper CI p-value
None:Weekly-None:Daily -0.14 -1.20724928 0.92724928 0.9998578
Low:Weekly-Low:Daily 0.24 -0.82724928 1.30724928 0.9954055
Medium:Weekly-Medium:Daily 0.34 -0.72724928 1.40724928 0.9657630
High:Weekly-High:Daily -0.46 -1.52724928 0.60724928 0.8523023


5 Concluding Remarks and Practice Exercise

We have discussed the two-way ANOVA method for analyzing a replicated randomized block design, without focusing on mathematical derivations. Instead, we emphasized understanding the underlying concepts and logic of the two-way ANOVA, as well as using the R software to analyze data from real-world problems. The R code and commands provided in this and previous notes are ready to be applied to other real-world data and practical applications.

The following YouTube video provides another example using R (https://www.youtube.com/watch?v=nRtv6boEOtk).



CAUTION: The one-way and two-way ANOVA methods introduced in this and previous notes are based on the assumption of independent observations. However, in more complex experimental designs, measurements of the same characteristic may be taken from the same subject multiple times. Such data must be analyzed using repeated measures ANOVA - which is different from the ANOVA used for a replicated RBD!


Finally, as an exercise to enhance your understanding of the methodology and to practice your R skills for future real-world applications, we encourage you to use the following reaction time dataset, collected from a replicated randomized block design (RBD) experiment, to perform a comprehensive ANOVA analysis and post hoc tests. The objective of the replicated RBD is to assess the effects of beer and caffeine on response time.

LS0tDQp0aXRsZTogIlR3by13YXkgQU5PVkEgQW5hbHl6aW5nIFJhbmRvbWl6ZWQgQmxvY2sgRGVzaWduIg0KYXV0aG9yOiAiQ2hlbmcgUGVuZyINCmRhdGU6ICJTVEEyMDAgU3RhdGlzdGljcyBJSSAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRvY19jb2xsYXBzZWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogc2hvdw0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIHNtb290aF9zY3JvbGw6IHllcw0KICAgIHRoZW1lOiBsdW1lbg0KICBwZGZfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgZmlnX3dpZHRoOiA1DQogICAgZmlnX2hlaWdodDogNA0KLS0tDQoNCmBgYHs9aHRtbH0NCg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCg0KZGl2I1RPQyBsaSB7DQogICAgbGlzdC1zdHlsZTpub25lOw0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCn0NCmgxLnRpdGxlIHsNCiAgZm9udC1zaXplOiAyNHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmg0LmF1dGhvciB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBEYXJrUmVkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoMSB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAyMHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoMiB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNnB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQo8L3N0eWxlPg0KYGBgDQoNCg0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMgY29kZSBjaHVuayBzcGVjaWZpZXMgd2hldGhlciB0aGUgUiBjb2RlLCB3YXJuaW5ncywgYW5kIG91dHB1dCANCiMgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IGZpbGVzLg0KDQppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikNCiAgIGxpYnJhcnkoa25pdHIpDQp9DQojIGtuaXRyOjpvcHRzX2tuaXQkc2V0KHJvb3QuZGlyID0gIkM6L1VzZXJzLzc1Q1BFTkcvT25lRHJpdmUgLSBXZXN0IENoZXN0ZXIgVW5pdmVyc2l0eSBvZiBQQS9Eb2N1bWVudHMiKQ0KIyBrbml0cjo6b3B0c19rbml0JHNldChyb290LmRpciA9ICJDOlxcU1RBNDkwXFx3MDUiKQ0KDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSwgICANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBUUlVFLCAgIA0KICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICBjb21tZW50ID0gInwiKQ0KYGBgDQoNClwNCg0KDQojIEludHJvZHVjdGlvbg0KDQpUaGUgZGF0YSBmcm9tIHRoZSBDUkQgKENvbXBsZXRlbHkgUmFuZG9taXplZCBEZXNpZ24pIHdlcmUgYW5hbHl6ZWQgdXNpbmcgYSBvbmUtd2F5IEFOT1ZBIHByb2NlZHVyZS4gU2luY2UgdGhlIHRyZWF0bWVudCBpcyBhIGZhY3RvciB3aXRoIGRpZmZlcmVudCBncm91cHMgKHJlcHJlc2VudGluZyBkaWZmZXJlbnQgZG9zZXMpLCBpdCBpbmZsdWVuY2VzIHRoZSByZXNwb25zZSB2YXJpYWJsZS4gT25lLXdheSBBTk9WQSwgYWxzbyBjYWxsZWQgb25lLWZhY3RvciBBTk9WQSwgZm9jdXNlcyBvbiB0ZXN0aW5nIHdoZXRoZXIgdGhlcmUgaXMgYSB0cmVhdG1lbnQgZWZmZWN0LiBJbiBzdGF0aXN0aWNhbCB0ZXJtcywgdGhpcyBpcyBlcXVpdmFsZW50IHRvIHRlc3RpbmcgdGhlIG51bGwgaHlwb3RoZXNpczoNCg0KJCQNCkhfMDogXG11XzEgPSBcbXVfMiA9IFxjZG90cyA9IFxtdV90Lg0KJCQNCg0KVW5kZXIgdGhpcyBudWxsIGh5cG90aGVzaXMsIHRoZSB2YXJpYW5jZSBiZXR3ZWVuIHRyZWF0bWVudHMgYW5kIHRoZSB2YXJpYW5jZSB3aXRoaW4gdHJlYXRtZW50cyBhcmUgYXBwcm94aW1hdGVseSB0aGUgc2FtZS4gVGh1cywgd2UgYXNzZXNzIHRoZSBlcXVhbGl0eSBvZiBtZWFucyBhY3Jvc3MgdHJlYXRtZW50cyBieSBhbmFseXppbmcgdGhlc2UgdmFyaWFuY2VzLCBhcyBzdW1tYXJpemVkIGluIHRoZSBjbGFzc2ljYWwgQU5PVkEgdGFibGUuDQoNClRoZSBrZXkgaW5mb3JtYXRpb24gJE1TX0IkIGFuZCAkTVNfVyQgdXNlZCB0byBjb25zdHJ1Y3QgdGhlIHRlc3Qgc3RhdGlzdGljIGFyZSBiYXNlZCBvbiB0aGUgJFNTX0IkIGFuZCAkU1NfVyQgZXh0cmFjdGVkIGZyb20gdGhlIHRvdGFsIHN1bSBvZiBzcXVhcmVzLg0KDQokJA0KU1NfVCA9IFNTX0IgKyBTU19XLg0KJCQNCg0KVHdvIGZ1bmRhbWVudGFsIGFzc3VtcHRpb25zIGZvciB0aGUgb25lLXdheSBBTk9WQSBhbmFseXNpcyBhcmUNCg0KKiBQb3B1bGF0aW9ucyBhcmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQNCiogVmFyaWFuY2VzIG9mIHRyZWF0bWVudCBncm91cHMgYXJlIGVxdWFsDQoNClVuZGVyIHRoZSBudWxsIGh5cG90aGVzaXMgJEhfMDogXG11XzEgPSBcbXVfMiA9IFxjZG90cyA9IFxtdV90JA0KDQokJA0KRiA9IFxmcmFje1NTX0IvdC0xfXtTU19XL24tdH0gXHJpZ2h0YXJyb3cgRl97dC0xLCBcIG4tdH0NCiQkDQoNCldoZXJlICR0JCBpcyB0aGUgbnVtYmVyIG9mIHRyZWF0bWVudCBncm91cHMgYW5kICRuJCBpcyB0aGUgc2FtcGxlIHNpemUuDQoNClwNCg0KVGhlIFJCRCBkZXNpZ25zIGFkZCBvbmUgYWRkaXRpb25hbCBmYWN0b3IgdmFyaWFibGUuIFdlIGFyZSBpbnRlcmVzdGVkIGluIGFzc2Vzc2luZyB0aGUgZWZmZWN0cyBvZiBib3RoIHRoZSBhZGRpdGlvbmFsIGZhY3RvciBhbmQgdGhlIHRyZWF0bWVudCBlZmZlY3QuIElmIHRoZSBSQkQgaGFzIHJlcGxpY2F0ZXMsIHdlIGFsc28gYXNzZXNzIHRoZSBwb3RlbnRpYWwgaW50ZXJhY3Rpb24gZWZmZWN0LiBCZWNhdXNlIG9mIHRoZSBhZGRpdGlvbmFsIGZhY3RvciwgdGhlIGRlY29tcG9zaXRpb24gb2YgdGhlIHRvdGFsIHN1bSBvZiBzcXVhcmVzIGJlY29tZXMgbW9yZSBjb21wbGV4LCBhbHRob3VnaCB0aGUgbG9naWMgYW5kIG1hdGhlbWF0aWNhbCBkZXJpdmF0aW9uIGFyZSB0aGUgc2FtZSBhcyB0aGUgb25lLXdheSBBTk9WQS4gDQoNCg0KQmVmb3JlIGRpc2N1c3NpbmcgdGhlIGNvbnN0cnVjdGlvbiBvZiBBTk9WQSBmb3IgcmVwbGljYXRlZCBSQkQgZGF0YSwgd2UgZmlyc3QgbG9vayBhdCBhbiBleGFtcGxlIHRvIHNlZSB3aGF0IHByYWN0aWNhbCBxdWVzdGlvbnMgd2UgY2FuIGFuc3dlciBiYXNlZCBvbiB0aGUgZGF0YSBjb2xsZWN0ZWQgZnJvbSBhIHJlcGxpY2F0ZWQgUkJELg0KDQoqKlBsYW50IEdyb3V0aCoqOiBhIGJvdGFuaXN0IHdhbnRzIHRvIGtub3cgd2hldGhlciBvciBub3QgKipwbGFudCBncm93dGgqKiBpcyBpbmZsdWVuY2VkIGJ5ICoqc3VubGlnaHQgZXhwb3N1cmUqKiBhbmQgKip3YXRlcmluZyBmcmVxdWVuY3kqKi4gU2hlIHBsYW50cyA0MCBzZWVkcyBhbmQgbGV0cyB0aGVtIGdyb3cgZm9yIHR3byBtb250aHMgdW5kZXIgZGlmZmVyZW50IGNvbmRpdGlvbnMgZm9yIHN1bmxpZ2h0IGV4cG9zdXJlIGFuZCB3YXRlcmluZyBmcmVxdWVuY3kuIEFmdGVyIHR3byBtb250aHMsIHNoZSByZWNvcmRzIHRoZSBoZWlnaHQgb2YgZWFjaCBwbGFudC4gVGhlIHJlc3VsdHMgYXJlIHNob3duIGJlbG93Og0KDQoNCmBgYHtyIGVjaG8gPSBGQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGg9IjUwJSJ9DQppbmNsdWRlX2dyYXBoaWNzKCJ3ZWVrMDQvMndheWFub3ZhLWV4YW1wbGUucG5nIikNCmBgYA0KDQpDbGVhcmx5LCB0aGlzIGlzIGEgYmFsYW5jZWQgUkJEIHdpdGggcmVwbGljYXRpb25zLiBUaGUgZGF0YSBzdHJ1Y3R1cmUgcmVxdWlyZWQgZm9yIGFuYWx5c2lzIHdpdGggc29mdHdhcmUgcHJvZ3JhbXMgd2lsbCBiZSBkaXNjdXNzZWQgbGF0ZXIuDQoNClwNCg0KIyBIeXBvdGhlc2VzIGFuZCBUZXN0aW5nIE1ldGhvZHMNCg0KV2Ugd2lsbCBmb3JtdWxhdGUgdGhlIGh5cG90aGVzZXMgYmFzZWQgb24gdGhlIHByYWN0aWNhbCBxdWVzdGlvbnMgdG8gYmUgYWRkcmVzc2VkIGJhc2VkIG9uIHJlcGxpY2F0ZWQgUkJEIGRhdGEgYW5kIHNldCB1cCB0aGUgdHdvLXdheSBBTk9WQSB0YWJsZSBmb3IgdGVzdGluZyB0aGUgaHlwb3RoZXNpcywgYWxvbmcgd2l0aCB0aGUgZnVuZGFtZW50YWwgYXNzdW1wdGlvbnMgcmVxdWlyZWQgZm9yIHRoZSB0d28td2F5IEFOT1ZBLg0KDQojIyBTZXR0aW5nIFVwIEh5cG90aGVzZXMNCg0KQXMgd2Ugc2VlIGluIHRoZSAqKlBsYW50IEdyb3d0aCoqIGV4YW1wbGUsIHRoZSBwcmFjdGljYWwgcXVlc3Rpb24gaXMgd2hldGhlciAqKnN1bmxpZ2h0IGV4cG9zdXJlKiogYW5kICoqd2F0ZXJpbmcgZnJlcXVlbmN5KiogYWZmZWN0ICoqcGxhbnQgZ3Jvd3RoKiouIFRoZSBwcmFjdGljYWwgcXVlc3Rpb24gaGFzIHNldmVyYWwgc3ViLXF1ZXN0aW9ucyBmcm9tIGFuIGFuYWx5dGljYWwgcG9pbnQgb2Ygdmlldy4gRm9yIGNvbnZlbmllbmNlLCBsZXQgY2FsbCAqKnN1bmxpZ2h0IGV4cG9zdXJlKiogPGZvbnQgY29sb3IgPSAicmVkIj4qKlxjb2xvcntyZWR9RmFjdG9yIEEqKjwvZm9udD4gYW5kICoqd2F0ZXJpbmcgZnJlcXVlbmN5KiogPGZvbnQgY29sb3IgPSAicmVkIj4qKlxjb2xvcntyZWR9RmFjdG9yIEIqKjwvZm9udD4uIFRoZSByZWxhdGVkIGh5cG90aGVzZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBvcmlnaW5hbCBwcmFjdGljYWwgcXVlc3Rpb24gYXJlDQoNCg0KKiAqKk1haW4gRWZmZWN0IG9mIEZhY3RvciBBKio6DQoNCiQkDQpIXzA6IFx0ZXh0e0FsbCBsZXZlbHMgb2YgRmFjdG9yIEEgaGF2ZSB0aGUgc2FtZSBtZWFuIGVmZmVjdC59IFwgXCBcdGV4dHt2c30gXCBcIEhfYTogXHRleHR7QXQgbGVhc3Qgb25lIGxldmVsIG9mIEZhY3RvciBBIGhhcyBhIGRpZmZlcmVudCBtZWFuIGVmZmVjdC59DQokJA0KDQoqICoqTWFpbiBFZmZlY3Qgb2YgRmFjdG9yIEIqKjoNCg0KJCQgDQpIXzA6IFx0ZXh0e0FsbCBsZXZlbHMgb2YgRmFjdG9yIEIgaGF2ZSB0aGUgc2FtZSBtZWFuIGVmZmVjdC59IFwgXCBcdGV4dHt2c30gXCBcIEhfYTogXHRleHR7QXQgbGVhc3Qgb25lIGxldmVsIG9mIEZhY3RvciBCIGhhcyBhIGRpZmZlcmVudCBtZWFuIGVmZmVjdC59DQokJA0KDQoqICoqSW50ZXJhY3Rpb24gRWZmZWN0IChBIMOXIEIpKio6DQoNCiQkDQpIXzA6IFx0ZXh0e1RoZXJlIGlzIG5vIGludGVyYWN0aW9uIGJldHdlZW4gRmFjdG9yIEEgYW5kIEZhY3RvciBCLn0gXCBcIFx0ZXh0e3ZzfSBcIFwgSF9hOiBcdGV4dHtUaGVyZSBpcyBhIHNpZ25pZmljYW50IGludGVyYWN0aW9uIGVmZmVjdC59DQokJA0KDQojIFR3by13YXkgQU5PVkENCg0KVHdvLXdheSBBTk9WQSBpcyB1c2VkIHRvIGFuYWx5emUgdGhlIGVmZmVjdHMgb2YgdHdvIGluZGVwZW5kZW50IGNhdGVnb3JpY2FsIHZhcmlhYmxlcyAoZmFjdG9ycykgb24gYSBjb250aW51b3VzIGRlcGVuZGVudCB2YXJpYWJsZSB3aGlsZSBhbHNvIGFzc2Vzc2luZyB0aGUgaW50ZXJhY3Rpb24gYmV0d2VlbiB0aGVzZSBmYWN0b3JzLiBVbmxpa2Ugb25lLXdheSBBTk9WQSwgd2hpY2ggZXhhbWluZXMgb25seSBvbmUgZmFjdG9yLCB0d28td2F5IEFOT1ZBIGFsbG93cyByZXNlYXJjaGVycyB0byBkZXRlcm1pbmUgd2hldGhlciB0aGUgdHdvIGZhY3RvcnMgaW5kZXBlbmRlbnRseSBpbmZsdWVuY2UgdGhlIG91dGNvbWUgYW5kIHdoZXRoZXIgdGhlaXIgY29tYmluZWQgZWZmZWN0IChpbnRlcmFjdGlvbikgaXMgc2lnbmlmaWNhbnQuIA0KDQojIyBUd28tV2F5IEFOT1ZBIFRhYmxlIFN0cnVjdHVyZQ0KDQpCZWNhdXNlIHR3byBmYWN0b3JzIGFyZSBpbnZvbHZlZCBpbiB0aGUgYW5hbHlzaXMsIHRoZSBtYXRoZW1hdGljYWwgZGVjb21wb3NpdGlvbiBvZiB0aGUgdG90YWwgc3F1YXJlIGludG8gbW9yZSBjb21wb25lbnRzIGZvciB0ZXN0aW5nIHRoZSBhYm92ZSB0aHJlZSBoeXBvdGhlc2VzIGlzIG11Y2ggbW9yZSBjb21wbGV4IHRoYW4gdGhlIG9uZS13YXkgQU5PVkE7IGFsZ2VicmEgaXMgbm90ICoqZGlmZmljdWx0KiouIFdlIHdpbGwgbm90IGRlcml2ZSB0aGUgY29tcG9uZW50cyBpbiB0aGUgQU5PVkEgdGFibGUgYmFzZWQgb24gdGhlIHJhdyBkYXRhIHZhbHVlcy4gSW5zdGVhZCwgd2UgZm9jdXMgb24gdGhlIHN0cnVjdHVyZSBvZiB0aGUgQU5PVkEgdGFibGUgYW5kIGhvdyB0byB1c2UgdGhlIGtleSBzdGF0aXN0aWNzIGluIHRoZSB0YWJsZSB0byB0ZXN0IHRoZSBhYm92ZSBoeXBvdGhlc2VzLiBXZSB1c2Ugc29mdHdhcmUgcHJvZ3JhbXMgdG8gZ2VuZXJhdGUgdGhlIEFOT1ZBIHRhYmxlLiBXZSBmaXJzdCBpbnRyb2R1Y2Ugc29tZSBub3RhdGlvbnMgdG8gaGVscCB1bmRlcnN0YW5kIHRoZSBBTk9WQSB0YWJsZS4NCg0KKiBOdW1iZXIgb2YgY2F0ZWdvcmllcyBpbiAqKmZhY3RvciBBKio6ICRhJA0KKiBOdW1iZXIgb2YgY2F0ZWdvcmllcyBpbiAqKmZhY3RvciBCKio6ICRiJA0KKiBUb3RhbCBzYW1wbGUgc2l6ZTogJE4kDQoqICoqVG90YWwgU3VtIG9mIFNxdWFyZXMqKjogJFNTVCQNCiogKipTdW0gb2YgU3F1YXJlcyBmb3IgRmFjdG9yIEEqKjogJFNTQSQgKFZhcmlhdGlvbiBkdWUgdG8gKipmYWN0b3IgQSoqKS4NCiogKipTdW0gb2YgU3F1YXJlcyBmb3IgRmFjdG9yIEIqKjogJFNTQiQgKFZhcmlhdGlvbiBkdWUgdG8gKipmYWN0b3IgQioqKS4NCiogKipTdW0gb2YgU3F1YXJlcyBmb3IgSW50ZXJhY3Rpb24gYmV0d2VlbiBGYWN0b3IgQSBhbmQgRmFjdG9yIEIqKjogJFNTQUIkICAoVmFyaWF0aW9uIGR1ZSB0byB0aGUgaW50ZXJhY3Rpb24gYmV0d2VlbiAqKkZhY3RvciBBKiogYW5kICoqRmFjdG9yIEIqKikuDQoqICoqUmVzaWR1YWwgU3VtIG9mIFNxdWFyZXMqKjogJFNTRSQgKFVuZXhwbGFpbmVkIHZhcmlhdGlvbiAtIGVycm9yKS4NCg0KTWF0aGVtYXRpY2FsbHkNCg0KJCQNClNTVCA9IFNTQSArIFNTQiArIFNTQUIgKyBTU0UNCiQkDQoNCkVhY2ggKipTdW0gb2YgU3F1YXJlcyoqIGhhcyBpdHMgb3duICoqZGVncmVlcyBvZiBmcmVlZG9tKiouIE5leHQsIHdlIGxpc3QgdGhlIGRlZ3JlZXMgb2YgZnJlZWRvbSBvcyBlYWNoIG9mIHRoZSAqKnN1bSBvZiBzcXVhcmVzKio6DQoNCiogREYuQSA9ICRhIC0gMSQNCiogREYuQiA9ICRiIC0gMSQNCiogREYuQUIgPSAkKGEtYilcdGltZXMgKGItMSkkIChpbnRlcmFjdGlvbiB0ZXJtKQ0KKiBERi5FID0gJE4gLSBhYiQNCiogREYuVCA9ICROIC0gMSQNCg0KTm90ZSB0aGF0ICROIC0xID0gKGEtMSkgKyAoYi0xKSArIChhLTEpKGItMSkgKyBOIC0gYWIkLg0KDQpXaXRoIHRoZSBhYm92ZSBub3RhdGlvbnMsIHdlIGludHJvZHVjZSB0aGUgdHdvLXdheSBBTk9WQSB0YWJsZS4NCg0KYGBge3IgZWNobyA9IEZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aD0iODAlIn0NCmluY2x1ZGVfZ3JhcGhpY3MoIndlZWswNC9Ud29XYXktQU5PVkEucG5nIikNCmBgYA0KDQpUaGUgZmlyc3QgdGhyZWUgcm93cyBvZiB0aGUgdGFibGUgY29udGFpbiBpbmZvcm1hdGlvbiByZWxhdGVkIHRvIHRlc3RpbmcgdGhlIGFib3ZlIHRocmVlIGh5cG90aGVzZXMuIEluIG9uZS13YXkgQU5PVkEsIHdlIHVzZWQgdGhlIEYtZGlzdHJpYnV0aW9uIHRvIGZpbmQgdGhlIHAtdmFsdWUgZm9yIGEgc3RhdGlzdGljYWwgZGVjaXNpb24gdW5kZXIgc29tZSBhc3N1bXB0aW9ucyBhcyBtZW50aW9uZWQgaW4gdGhlIGZpcnN0IHNlY3Rpb24uIFdlIGFsc28gbmVlZCB0byBtYWtlIHNvbWUgYXNzdW1wdGlvbnMgaW4gb3JkZXIgdG8gc3BlY2lmeSB0aGUgZGlzdHJpYnV0aW9ucyBvZiBGIHN0YXRpc3RpY3MuIE5leHQsIHdlIGRpc2N1c3MgdGhlIGFzc3VtcHRpb25zIG9mIHR3by13YXkgQU5PVkEgYW5kIHRlc3RpbmcgdGhlIGh5cG90aGVzZXMuDQoNClwNCg0KIyMgQXNzdW1wdGlvbnMgb2YgVHdvLVdheSBBTk9WQQ0KDQpBcyB3ZSBrbm93LCBpbiB0aGUgb25lLXdheSBBTk9WQSB0YWJsZSwgdGhlIEYgdmFsdWUgZm9sbG93cyBhbiBGIGRpc3RyaWJ1dGlvbiB1bmRlciBzb21lIGFzc3VtcHRpb25zLiBJbiB0aGUgdHdvLXdheSBBTk9WQSwgd2UgYWxzbyBuZWVkIHRoZSBmb2xsb3dpbmcgYXNzdW1wdGlvbnMgdG8gbWFrZSBpbmZlcmVuY2VzIGFib3V0IHRoZSB0aHJlZSBGIHN0YXRpc3RpY3M6DQoNCiogKipOb3JtYWxpdHkqKjogVGhlIGRlcGVuZGVudCB2YXJpYWJsZSBzaG91bGQgYmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgd2l0aGluICoqZWFjaCBjb21iaW5hdGlvbiBvZiBmYWN0b3IgbGV2ZWxzKiouDQoNCiogKipIb21vZ2VuZWl0eSBvZiBWYXJpYW5jZSAoSG9tb3NjZWRhc3RpY2l0eSkqKjogVGhlIHZhcmlhbmNlcyBhY3Jvc3MgZ3JvdXBzIGRlZmluZWQgYnkgKiplYWNoIGNvbWJpbmF0aW9uIG9mIGZhY3RvciBsZXZlbHMqKiBzaG91bGQgYmUgZXF1YWwuIEluIHByYWN0aWNlLCB3ZSB1c3VhbGx5IHBlcmZvcm0gYSBmb3JtYWwgdGVzdCB0byBjaGVjayB0aGlzIGFzc3VtcHRpb24uDQoNCiogKipJbmRlcGVuZGVuY2Ugb2YgT2JzZXJ2YXRpb25zKio6IERhdGEgcG9pbnRzIHNob3VsZCBiZSBpbmRlcGVuZGVudCwgbWVhbmluZyB0aGUgbWVhc3VyZW1lbnQgb2Ygb25lIHN1YmplY3QgZG9lcyBub3QgaW5mbHVlbmNlIGFub3RoZXIuICoqVGhpcyBhc3N1bXB0aW9uIGlzIGhhcmQgdG8gdGVzdCBmb3IgaW5kZXBlbmRlbmNlLioqLiBXZSB1c3VhbGx5IGp1c3RpZnkgdGhlIGRhdGEgY29sbGVjdGlvbiBwcm9jZXNzLg0KDQoqICoqUmFuZG9tIFNhbXBsaW5nKio6IERhdGEgc2hvdWxkIGJlIGNvbGxlY3RlZCB1c2luZyBhIHJhbmRvbSBzYW1wbGluZyBtZXRob2QuIFRoaXMgaXMganVzdGlmaWVkIGJ5IHRoZSBkYXRhIGNvbGxlY3Rpb24gcHJvY2Vzcy4NCg0KDQpWaW9sYXRpb25zIG9mIHRoZXNlIGFzc3VtcHRpb25zIG1heSByZXF1aXJlIHRyYW5zZm9ybWF0aW9ucyBvciBub24tcGFyYW1ldHJpYyBhbHRlcm5hdGl2ZXMgbGlrZSB0aGUgS3J1c2thbC1XYWxsaXMgdGVzdC4gDQoNClwNCg0KQXNzdW1lIHRoYXQgYWxsIHRoZSBhYm92ZSBhc3N1bXB0aW9ucyBhcmUgbWV0LiBOZXh0LCB3ZSBkaXNjdXNzIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHRlc3Qgc3RhdGlzdGljcyBmb3IgdGVzdGluZyB0aGUgdGhyZWUgaHlwb3RoZXNlcy4NCg0KXA0KDQoqIEVmZmVjdCBvZiAqKkZhY3RvciBBKio6IHVuZGVyIHRoZSBmb2xsb3dpbmcgbnVsbCBoeXBvdGhlc2lzLA0KDQokJA0KSF8wOiBcdGV4dHtBbGwgbGV2ZWxzIG9mIEZhY3RvciBBIGhhdmUgdGhlIHNhbWUgbWVhbiBlZmZlY3QufSANCiQkDQpUaGUgdGVzdCBzdGF0aXN0aWMNCg0KJCQNCkZfQSA9IFxmcmFje01TX0F9e1NTX0V9IFxyaWdodGFycm93IEZfe2EtMSxcIG4tYWIgfS4NCiQkDQoNClRoZSBwLXZhbHVlIGNhbiBiZSBmb3VuZCBmcm9tICRGX3thLTEsXCBuLWFiIH0kLg0KDQpcDQoNCiogRWZmZWN0IG9mICoqRmFjdG9yIEIqKjogdW5kZXIgdGhlIGZvbGxvd2luZyBudWxsIGh5cG90aGVzaXMsDQoNCiQkIA0KSF8wOiBcdGV4dHtBbGwgbGV2ZWxzIG9mIEZhY3RvciBCIGhhdmUgdGhlIHNhbWUgbWVhbiBlZmZlY3QufSANCiQkDQpUaGUgdGVzdCBzdGF0aXN0aWMNCg0KJCQNCkZfQiA9IFxmcmFje01TX0J9e01TX0V9IFxyaWdodGFycm93IEZfe2ItMSwgXCBuIC0gYWJ9DQokJA0KDQpUaGUgcC12YWx1ZSBjYW4gYmUgZm91bmQgZnJvbSAkRl97Yi0xLFwgbi1hYiB9JC4NCg0KXA0KDQoqIEludGVyYWN0aXZlIEVmZmVjdCBiZXR3ZWVuICoqRmFjdG9yIEEqKiBhbmQgKipGYWN0b3IgQioqOiB1bmRlciB0aGUgZm9sbG93aW5nIG51bGwgaHlwb3RoZXNpcywNCg0KJCQNCkhfMDogXHRleHR7VGhlcmUgaXMgbm8gaW50ZXJhY3Rpb24gYmV0d2VlbiBGYWN0b3IgQSBhbmQgRmFjdG9yIEIufSANCiQkDQpUaGUgdGVzdCBzdGF0aXN0aWMNCg0KJCQNCkZfe0FCfSA9IFxmcmFje01TX3tBQn19e01TX0V9IFxyaWdodGFycm93IEZfeyhhLWIpKGItMSksIG4gLWFifQ0KJCQNClRoZSBwLXZhbHVlIGNhbiBiZSBmb3VuZCBmcm9tICRGX3soYS0xKShiLTEpLFwgbi1hYiB9JC4NCg0KXA0KDQo8Zm9udCBjb2xvciA9ICJyZWQiPioqXGNvbG9ye3JlZH1SZW1hcmtzKio8L2ZvbnQ+OiB1bmRlcnN0YW5kaW5nIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIEFOT1ZBIHRhYmxlIGlzIGNydWNpYWwuIA0KDQoqIElmIHRoZSBmaXJzdCB0d28gY29sdW1ucyBhcmUgZ2l2ZW4sIHlvdSBhcmUgZXhwZWN0ZWQgdG8gZGVyaXZlIHRoZSByZXN0IG9mIHRoZSBjb2x1bW5zLCBpbmNsdWRpbmcgdGhlIHAtdmFsdWVzIGluIHRoZSBsYXN0IGNvbHVtbiwgdXNpbmcgdGhlIFIgY29tbWFuZCBgcGYoRiwgZGYxLCBkZjIsIGxvd2VyLnRhaWwgPSBGQUxTRSlgIChGIHRhYmxlIGlzIG5vdCByZWNvbW1lbmRlZCkuDQoNCiogVGhlIGludGVyYWN0aW9uIGVmZmVjdCBpcyBub3QgYXZhaWxhYmxlIGlmIHdvcmtpbmcgd2l0aCBSQkQgZGF0YSB3aXRoIG5vIHJlcGxpY2F0ZXMuDQoNClwNCg0KIyMgUGVyZm9ybWluZyBBTk9WQSBVc2luZyBSDQoNClRoZSBSIGZ1bmN0aW9uIGBhb3YoKWAgd2lsbCBiZSB1c2VkIHRvIHBlcmZvcm0gYW4gQU5PVkEgdGVzdC4gSWYgdGhlIGdpdmVuIGRhdGEgdGFibGUgaXMgaW4gd2lkZSBmb3JtYXQsIHdlIG5lZWQgdG8gcmVmb3JtYXQgaXQgaW50byBhIGxvbmcgdGFibGUuIFRoaXMgaW52b2x2ZXMgcGxhY2luZyBhbGwgcmVzcG9uc2UgdmFsdWVzIGluIGEgc2luZ2xlIGNvbHVtbiBhbmQgdXNpbmcgdHdvIHNlcGFyYXRlIGNvbHVtbnMgdG8gbGFiZWwgZWFjaCByZXNwb25zZSB2YWx1ZSB3aXRoIGl0cyBhc3NvY2lhdGVkIGZhY3RvcnMuIA0KDQpUaGUgUiBmdW5jdGlvbiBgcmVwKClgIGlzIHVzZWZ1bCBmb3IgZ2VuZXJhdGluZyBwYXR0ZXJuZWQgZGF0YS4gSXRzIHN5bnRheCBpcyBgcmVwKGRhdGEudmFsdWUsIHRpbWVzID0gbilgLCB3aGljaCBtZWFucyBpdCAqKnJlcGxpY2F0ZXMqKiBgZGF0YS52YWx1ZWAgKm4qIHRpbWVzLiBUaGUgYGRhdGEudmFsdWVgIGFyZ3VtZW50IGNhbiBiZSBlaXRoZXIgYSAqKnNpbmdsZSB2YWx1ZSoqIG9yIGEgKip2ZWN0b3Igb2YgdmFsdWVzKiouIEJlbG93IGFyZSBzb21lIGV4YW1wbGVzIGRlbW9uc3RyYXRpbmcgaG93IHRvIHVzZSBgcmVwKClgIHRvIGNyZWF0ZSBwYXR0ZXJuZWQgZGF0YS4NCg0KDQpgYGB7cn0NCnJlcCg1LCB0aW1lcyA9IDMpICAgIyByZXBsaWNhdGUgNSB0aHJlZSB0aW1lcw0KcmVwKCJhIiwgOSkgICAgICAgICAjIHJlcGxpY2F0ZSBsb3dlcmNhc2UgbGV0dGVyICJhIiA5IHRpbWVzDQpyZXAoYygxLDMsNSksIDMpICAgICMgcmVwbGljYXRlIHZlY3RvciAoMSwzLDUpIHRocmVlIHRpbWVzDQpyZXAocmVwKGMoIkEiLCAiQiIpLCAyKSwgMykgIyBuZXN0ZWQgcmVwbGljYXRlIHJlcChjKCJBIiwgIkIiKSkgdGhyZWUgdGltZXMNCmBgYA0KDQpOZXh0LCB3ZSB3b3JrIG9uIHRoZSB3aWRlIHRhYmxlIGluIHRoZSBleGFtcGxlIGdpdmVuIGluIFNlY3Rpb24gMS4NCg0KYGBge3J9DQojIyBmaXJzdCwgZGVmaW5lIDQgY29sdW1uIHZlY3RvcnMNCk5vbmUgPSBjKDQuOCwgNC40LCAzLjIsIDMuOSwgNC40LCA0LjQsIDQuMiwgMy44LCAzLjcsIDMuOSkNCkxvdyA9IGMoNS4wLCA1LjIsIDUuNiwgNC4zLCA0LjgsIDQuOSwgNS4zLCA1LjcsIDUuNCwgNC44KQ0KTWVkaXVtID0gYyg2LjQsIDYuMiwgNC43LCA1LjUsIDUuOCwgNS44LCA2LjIsIDYuMywgNi41LCA1LjUpDQpIaWdoID0gYyg2LjMsIDYuNCwgNS42LCA0LjgsIDUuOCwgNi4wLCA0LjksIDQuNiwgNS42LCA1LjUpDQojIyBQbGFjZSB0aGUgYWJvdmUgdmFsdWVzIGluIGEgc2luZ2xlIGNvbHVtbg0KZ3Jvd3RoIDwtIGMoTm9uZSwgTG93LCBNZWRpdW0sIEhpZ2gpDQojIyBkZWZpbmUgc3VubGlnaHQgbGFiZWxzDQpzdW5saWdodCA8LSBjKHJlcCgiTm9uZSIsIGxlbmd0aChOb25lKSksIHJlcCgiTG93IiwgbGVuZ3RoKExvdykpLA0KICAgICAgICAgICAgICByZXAoIk1lZGl1bSIsIGxlbmd0aChNZWRpdW0pKSwgcmVwKCJIaWdoIiwgbGVuZ3RoKEhpZ2gpKSkNCiMjIFdhdGVyaW5nIHBhdHRlcm5zDQojIyBUaGUgaW5uZXIgcmVwKCkgcmV0dXJucyB0aGUgcGF0dGVybiBvZiBmaXJzdCBjb2x1bW4NCiMjIFRoZSBvdXRlciByZXAoKSByZXBsaWNhdGUgdGhlIHJlc3Qgb2YgdGhlIGNvbHVtbnMNCndhdGVyaW5nIDwtcmVwKGMocmVwKCJEYWlseSIsIDUpLCByZXAoIldlZWtseSIsIDUpKSw0KSANCiMjIFN0b3JlIHZhcmlhYmxlcyBpbiBhIGRhdGEgZnJhbWUNCmdyb3d0aERhdGEgPC0gZGF0YS5mcmFtZShncm93dGggPSBncm93dGgsIHN1bmxpZ2h0ID0gc3VubGlnaHQsIHdhdGVyaW5nID0gd2F0ZXJpbmcpDQojIyBjaGVjayB0aGUgZGF0YSBmcmFtZQ0KI2dyb3d0aERhdGENCmBgYA0KDQpXZSBub3cgcGVyZm9ybSB0aGUgQU5PVkEgdXNpbmcgdGhlIGRhdGEgZnJhbWUuDQoNCmBgYHtyfQ0KIyBXZSBmaXQgYW4gQU5PVkEgd2l0aCBhbiBpbnRlcmFjdGl2ZSBlZmZlY3QNCmdyb3d0aC5hb3YgPC0gYW92KGdyb3d0aCB+IHN1bmxpZ2h0KndhdGVyaW5nLCBkYXRhID0gZ3Jvd3RoRGF0YSkNCnN1bW1hcnkoZ3Jvd3RoLmFvdikNCmBgYA0KDQo8Zm9udCBjb2xvciA9ICJyZWQiIHNpemUgPSA0PioqXGNvbG9ye3JlZH1Gb3JtYWwgU3VtbWFyeSBvZiBBTk9WQSoqOjwvZm9udD4gVHdvIGZvcm1hdHMgb2Ygd3JpdGUtdXAgYXJlIHJlY29tbWVuZGVkLg0KDQoqKkZvcm1hdCAxKioNCg0KVGhlIGFib3ZlIHR3by13YXkgQU5PVkEgcmV2ZWFsZWQgYSBzaWduaWZpY2FudCBtYWluIGVmZmVjdCBvZiAqKnN1bmxpZ2h0KiogKCRGKDMsIDMyKSA9IDIzLjA0OSQpLCAkcCBcYXBwcm94IDAkKSwgaW5kaWNhdGluZyB0aGF0IHRoZSBwbGFudCBoZWlnaHRzIChncm93dGgpIHdlcmUgc2lnbmlmaWNhbnRseSBoaWdoZXIgd2hlbiBleHBvc2VkIHRvIG1vcmUgc3VubGlnaHQuIE5laXRoZXIgdGhlIG1haW4gZWZmZWN0IG9mICoqd2F0ZXJpbmcgZnJlcXVlbmN5KiogKCRGKDEsIDMyKSA9IDAuMDEsIHAgPSAwLjk3NiQpIG5vciB0aGUgKipzdW5saWdodCoqIGFuZCAqKndhdGVyaW5nIGZyZXF1ZW5jeSoqIGludGVyYWN0aW9uICgkRigxLDMyKSA9MS4yNDIsIHAgPSAwLjMxMSQpIHdhcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50Lg0KDQoNCioqRm9ybWF0IDIqKg0KDQpBIHR3by13YXkgQU5PVkEgd2FzIGNvbmR1Y3RlZCwgeWllbGRpbmcgdGhlIGZvbGxvd2luZyBmaW5kaW5nczoNCg0KKiAqKldhdGVyaW5nIEZyZXF1ZW5jeSoqOiBObyBzaWduaWZpY2FudCBlZmZlY3Qgb24gcGxhbnQgZ3Jvd3RoIChGKDEsIDMyKSA9IDAuMDEsICpwKiA9IDAuOTc2KS4NCg0KKiAqKlN1bmxpZ2h0IEV4cG9zdXJlKio6IFNpZ25pZmljYW50IGVmZmVjdCBvbiBwbGFudCBncm93dGggKEYoMywgMzIpID0gMjMuMDQ5LCAqcCogPCAwLjAwMSkuIFdlIHdpbGwgY29uZHVjdCBhIHBvc3QtaG9jIGNvbXBhcmlzb24gKGUuZy4sIFR1a2V54oCZcyBIU0QpIHdvdWxkIGRldGVybWluZSB3aGljaCBzdW5saWdodCBsZXZlbHMgZGlmZmVyLg0KDQoqICoqSW50ZXJhY3Rpb24gKFdhdGVyaW5nIMOXIFN1bmxpZ2h0KSoqOiBObyBzaWduaWZpY2FudCBpbnRlcmFjdGlvbiAoRigzLCAzMikgPSAxLjI0MiwgKnAqID0gMC4zMTEpLCBpbmRpY2F0aW5nIHRoYXQgdGhlIGVmZmVjdCBvZiBzdW5saWdodCBkb2VzIG5vdCBkZXBlbmQgb24gd2F0ZXJpbmcgZnJlcXVlbmN5Lg0KDQoNCiMgUG9zdC1ob2MgVGVzdA0KDQpUaGUgaW50ZXJwcmV0YXRpb24gb2YgcG9zdCBob2MgdGVzdHMgYmVjb21lcyBtb3JlIGNvbXBsZXggd2hlbiB0d28gb3IgbW9yZSBmYWN0b3JzIGFyZSBpbmNsdWRlZCBpbiBhbiBBTk9WQSwgZXNwZWNpYWxseSB3aGVuIGludGVyYWN0aW9uIGVmZmVjdHMgYXJlIHByZXNlbnQuIEluIHN1Y2ggY2FzZXMsIGl0IGlzIG9mdGVuIHVzZWZ1bCB0byBjcmVhdGUgbGluZSBwbG90cyBzaG93aW5nIHRoZSBtZWFucyBvZiB0aGUgcHJpbWFyeSBmYWN0b3IgYXQgZWFjaCBsZXZlbCBvZiB0aGUgc2Vjb25kYXJ5IGZhY3Rvci4gQXMgYW4gaWxsdXN0cmF0aXZlIGV4YW1wbGUsIHdlIHdpbGwgdXNlIHRoZSBkYXRhIGZyYW1lIGNyZWF0ZWQgaW4gdGhlIHByZXZpb3VzIHNlY3Rpb24gdG8gY2FsY3VsYXRlIHRoZSBtZWFucyBvZiBncm91cHMgZGVmaW5lZCBieSB0aGUgY29tYmluYXRpb24gb2YgYHdhdGVyaW5nYCBhbmQgYHN1bmxpZ2h0YC4gVGhlIFIgZnVuY3Rpb24gYGFnZ3JlZ2F0ZSgpYCBjYW4gYmUgdXNlZCB0byBjb21wdXRlIHRoZXNlIGdyb3VwIG1lYW5zLiBJbiBnZW5lcmFsLCBgYWdncmVnYXRlKClgIGlzIHVzZWQgdG8gc3VtbWFyaXplIHRoZSB2YWx1ZXMgd2l0aGluIGdyb3VwcyB1c2luZyBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIHN1Y2ggYXMgdGhlIG1lYW4sIHZhcmlhbmNlLCBtYXhpbXVtLCBtaW5pbXVtLCBldGMuIFRoZSBzeW50YXggb2YgYWdncmVnYXRlKCkgaXMgc2hvd24gYmVsb3cuDQoNCg0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoPSI5NSUifQ0KaW5jbHVkZV9ncmFwaGljcygid2VlazA0L0FnZ3JlZ2F0ZVN5bnRheC5wbmciKQ0KYGBgDQoNCmBgYHtyfQ0KIyMgV2UgdXNlIHRoZSBkYXRhIGZyYW1lICJncm93dGhEYXRhIiBjcmVhdGVkIGluIHRoZSBwcmV2aW91cyBzZWN0aW9uIA0KZ3JwLm1lYW5zIDwtIGFnZ3JlZ2F0ZShncm93dGggfiB3YXRlcmluZyArIHN1bmxpZ2h0LCBkYXRhID0gZ3Jvd3RoRGF0YSwgbWVhbikNCiMjIGNoZWNraW5nIHRoZSByZXN1bHRpbmcgdGFibGUNCiNncnAubWVhbnMNCiMjIHNwbGl0IGludG8gZGFpbHkgbWVhbnMgYW5kIHdlZWtseSBtZWFucw0KIyMgdXNpbmcgd2hpY2goKSB0byBmaW5kIHRoZSByb3dzIGluIHdoaWNoIHdhdGVyaW5nIGlzICJEYWlseSIgYW5kICJXZWVrbHkiIHJlc3BlY3RpdmVseQ0KZGFpbHkuaWQgPC0gd2hpY2goZ3JwLm1lYW5zJHdhdGVyaW5nID09ICJEYWlseSIpDQp3ZWVrbHkuaWQgPC0gd2hpY2goZ3JwLm1lYW5zJHdhdGVyaW5nID09ICJXZWVrbHkiKQ0KIyMgc3Vic2V0IG9mIG1lYW5zIG9mIHN1bmxpZ2h0IGF0IGl0cyBpbmRpdmlkdWFsIGxldmVscw0KZGFpbHkuYXZnIDwtIGdycC5tZWFuc1tkYWlseS5pZCwgM10NCndlZWtseS5hdmcgPC0gZ3JwLm1lYW5zW3dlZWtseS5pZCwgM10NCiMjIyBkcmF3IGxpbmUgcGxvdHMgb2YNCmBgYA0KDQoNCldlIGhhdmUgbm90IGZvcm1hbGx5IGludHJvZHVjZWQgdGhlIFIgYmFzZSBwbG90IGZ1bmN0aW9uIHdpdGggZGV0YWlscy4gTmV4dCwgd2UgYnJpZWZseSBpbnRyb2R1Y2UgdGhlIGJhc2UgUiBmdW5jdGlvbiBgcGxvdCgpYDoNCg0KDQpgYGB7fQ0KcGxvdCh4LCB5LCB0eXBlID0gImIiLCB4YXh0ID0gIm4iLCB4bGFiID0gIkNhdGVnb3J5IiwgeWxhYiA9ICJWYWx1ZSIsIG1haW4gPSAiQ3VzdG9tIFgtQXhpcyBMYWJlbHMiKQ0KYGBgDQp3aGVyZQ0KKiBgeGAgaG9yaXpvbnRhbCB4LWF4aXMNCiogYHlgIHZlcnRpY2FsIHktYXhpcyANCiogYHR5cGUgPSAiYiJgIGRyYXdzIGJvdGggcG9pbnRzIGFuZCBsaW5lcy4NCiogYHhsYWI9YCB0aGUgbGFiZWwgb2YgeC1heGlzDQoqIGB5bGFiID1gIHRoZSBsYWJlbCBvZiB5LWF4aXMNCiogYG1haW49YCB0aGUgdGl0bGUgb2YgdGhlIHBsb3QNCiogYHhheHQgPSAibiJgIHN1cHByZXNzZXMgdGhlIGRlZmF1bHQgeC1heGlzLg0KKiBgYXhpcyhzaWRlID0gMSwgLi4uKWAgYWRkcyBhIGN1c3RvbWl6ZWQgaG9yaXpvbnRhbCBheGlzLg0KDQpUaGUgY29kZSBiZWxvdyBkcmF3cyBhIGxpbmUgcGxvdCBvZiB0aGUgbWVhbiBzdW5saWdodCBsZXZlbHMgZm9yIGVhY2ggd2F0ZXJpbmcgbGV2ZWwuDQoNCmBgYHtyfQ0KIyBDdXN0b20gdGljayBtYXJrIHBvc2l0aW9ucyBhbmQgbGFiZWxzDQp4LnRpY2tzIDwtIGMoMSwyLDMsNCkgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRpY2sgbWFya3MgLyBsb2NhdGlvbiBvZiB0aWNrIGxhYmVscw0KeC5sYWJlbHMgPC0gYygiTm9uZSIsICJMb3ciLCAiTWVkaXVtIiwgIkhpZ2giKQ0KDQojIENyZWF0ZSB0aGUgcGxvdCB3aXRob3V0IHgtYXhpcyAoeGF4dCA9ICJuIikNCnBsb3QoYygxLDIsMyw0KSwgd2Vla2x5LmF2ZywgDQogICAgIHR5cGUgPSAiYiIsDQogICAgIHhheHQgPSAibiIsIA0KICAgICB4bGFiID0gIlN1bmxpZ2h0IiwgDQogICAgIHlsYWIgPSAiTGVuZ3RoIChncm93dGgpIiwgDQogICAgIGNvbCA9ICJyZWQiLCAgICAgICAgICAjIGNvbG9yIG9mIHRoZSBsaW5lIGdyYXBoDQogICAgIGx0eSA9IDEsICAgICAgICAgICAgICAjIGxpbmUgdHlwZS4gMSA9IHNvbGlkIGxpbmUNCiAgICAgbWFpbiA9ICJNZWFuIExlbmd0aCBhY3Jvc3MgU3VubGlnaHQgTGV2ZWwiKQ0KIyMgQWRkIGEgbGluZSBwbG90IG9mIHdlZWtseSB3YXRlcmluZw0KbGluZXMoYygxLDIsMyw0KSwgZGFpbHkuYXZnLCANCiAgICAgIGNvbCA9ICJibHVlIiwNCiAgICAgIGx0eSA9IDEpDQojIEFkZCBjdXN0b20geC1heGlzDQpheGlzKHNpZGUgPSAxLCBhdCA9IHgudGlja3MsIGxhYmVscyA9IHgubGFiZWxzKQ0KIyMgQWRkIGEgbGVnZW5kIHRvIHNwZWNpZnkgdGhlIHdhdGVyaW5nIGxldmVsDQpsZWdlbmQoImJvdHRvbWxlZnQiLCAgICAgICAgICAgICAgIyBsb2NhdGlvbiBmb3IgdGhlIGxlZ2VuZA0KICAgICAgIGMoIldlZWtseSIsICJEYWlseSIpLCAgICAgICMgbmFtZXMgb2YgbGluZSBwbG90LCBDYXV0aW9uOiBrZWVwIHRoZSBvcmRlciBvZiB0aGUgbmFtZXMhDQogICAgICAgbHR5ID0gYygxLDEpLA0KICAgICAgIGNvbCA9IGMoInJlZCIsICJibHVlIiksDQogICAgICAgYnR5ID0gIm4iICAgICAgICAgICAgICAgICAgIyBkb24ndCBpbmNsdWRlIHRoZSBib3ggb2YgdGhlIGxlZ2VuZA0KICAgICAgICkNCmBgYA0KDQo8Zm9udCBjb2xvciA9ICJyZWQiIHNpemUgPSA0PioqXGNvbG9ye3JlZH0gSWYgdGhlIHR3byBsaW5lIGdyYXBocyBhcmUgcGFyYWxsZWwgKGkuZS4sIHRoZXJlIGlzIE5PIGludGVyc2VjdGlvbiksIHRoZSBmYWN0b3JzIGB3YXRlcmluZ2AgYW5kIGBzdW5saWdodGAgZG8gbm90IGhhdmUgYW4gaW50ZXJhY3RpdmUgZWZmZWN0IS4gT3RoZXJ3aXNlLCB0aGUgdHdvIGZhY3RvcnMgZG8gaGF2ZSBhbiBpbnRlcmFjdGl2ZSBlZmZlY3QhKio8L2ZvbnQ+DQoNCg0KKipHcmFwaGljYWwgSW50ZXJwcmV0YXRpb25zKio6DQoNCiogKk1haW4gRWZmZWN0KiBpbnRlcnByZXQgYHN1bmxpZ2h0YCBwYXR0ZXJucyAodHJlbmRzKSBhdCBlYWNoIGB3YXRlcmluZ2AgbGV2ZWw6DQogICsgV2hlbiB3YXRlcmVkIHdlZWtseSwgdGhlIHBsYW50IGdyZXcgYmVzdCB3aXRoICoqbWVkaXVtIHN1bmxpZ2h0KiogYW5kIHBvb3Jlc3Qgd2l0aCB0aGUgKipoaWdoIHN1bmxpZ2h0KiouDQogICsgVGhlIHNhbWUgZ3Jvd3RoIHBhdHRlcm5zIHdlcmUgb2JzZXJ2ZWQgd2hlbiB3YXRlcmluZyBkYWlseS4NCiogKipJbnRlcmFjdGl2ZSBlZmZlY3QqKiBjcm9zcyBjb21wYXJpc29uIGJldHdlZW4gKip3YXRlcmluZyBmcmVxdWVuY2llcyoqDQogICsgVGhlIHBsYW50cyBncmV3IGJldHRlciB3aXRoIGBMb3dgIGFuZCBgTWVkaXVtYCBzdW5saWdodCB3aGVuICoqd2F0ZXJlZCB3ZWVrbHkqKg0KICArIEhvd2V2ZXIsIHRoZSBwbGFudCBncmV3IGJldHRlciB3aXRoIGBOb25lYCBhbmQgYEhpZ2hgIHN1bmxpZ2h0IHdoZW4gKip3YXRlcmVkIGRhaWx5KioNCg0KDQpUaGUgZm9sbG93aW5nIHN1YnNlY3Rpb25zIHByb3ZpZGUgZGV0YWlsZWQgbnVtZXJpY2FsIGNvbXBhcmlzb25zIHdpdGggZGlmZmVyZW5jZXMgYW5kIGFzc29jaWF0ZWQgY29uZmlkZW5jZSBpbnRlcnZhbHMuDQoNCiMjIEFOT1ZBIHdpdGggTm8gSW50ZXJhY3RpdmUgRWZmZWN0DQoNCklmIHRoZXJlIGlzIG5vIGludGVyYWN0aW9uIGVmZmVjdCwgd2UgaW50ZXJwcmV0IHRoZSBtYWluIGVmZmVjdHMgb2YgdGhlIGZhY3RvciB2YXJpYWJsZXMgaW5kZXBlbmRlbnRseS4gSW4gdGhlICoqcGxhbnQgZ3Jvd3RoKiogYW5hbHlzaXMsIHRoZSBrZXkgZmFjdG9yIGlzICoqc3VubGlnaHQqKiwgYW5kIHRoZSBzZWNvbmRhcnkgZmFjdG9yIGlzICoqd2F0ZXJpbmcqKi4gV2UgY29tcGFyZSB0aGUgbWFpbiBlZmZlY3RzIG9mIHRoZSBrZXkgYW5kIHNlY29uZGFyeSBmYWN0b3JzIHNlcGFyYXRlbHkuIEZvciBleGFtcGxlOg0KDQoNCiogKipTdW5saWdodCAoS2V5IEZhY3RvcikqKjogQ29tcGFyZSBtZWFuIG91dGNvbWVzIGFjcm9zcyBzdW5saWdodCBsZXZlbHMsIGlnbm9yaW5nIHdhdGVyaW5nLiAiPGZvbnQgY29sb3IgPSAiYmx1ZSI+Klxjb2xvcntibHVlfUhpZ2ggc3VubGlnaHQgeWllbGRzIGhpZ2hlciBncm93dGggdGhhbiBsb3cgc3VubGlnaHQsIGF2ZXJhZ2VkIG92ZXIgYWxsIHdhdGVyaW5nIGxldmVscy4qPC9mb250Pg0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTUsIGZpZy5oZWlnaHQ9NH0NCiMgQ3VzdG9tIHRpY2sgbWFyayBwb3NpdGlvbnMgYW5kIGxhYmVscw0KeC50aWNrcyA8LSBjKDEsMiwzLDQpICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0aWNrIG1hcmtzIC8gbG9jYXRpb24gb2YgdGljayBsYWJlbHMNCngubGFiZWxzIDwtIGMoIk5vbmUiLCAiTG93IiwgIk1lZGl1bSIsICJIaWdoIikNCiMgc3VubGlnaHQgbWVhbnMsIGlnbm9yaW5nDQpzdW4uZ3JwLm1lYW5zIDwtIGFnZ3JlZ2F0ZShncm93dGggfiBzdW5saWdodCwgZGF0YSA9IGdyb3d0aERhdGEsIG1lYW4pDQoNCiMgQ3JlYXRlIHRoZSBwbG90IHdpdGhvdXQgeC1heGlzICh4YXh0ID0gIm4iKQ0KcGxvdChjKDEsMiwzLDQpLCBzdW4uZ3JwLm1lYW5zJGdyb3d0aCwgDQogICAgIHR5cGUgPSAiYiIsDQogICAgIHhheHQgPSAibiIsIA0KICAgICB4bGFiID0gIlN1bmxpZ2h0IiwgDQogICAgIHlsYWIgPSAiTGVuZ3RoIChncm93dGgpIiwgDQogICAgIGNvbCA9ICJwdXJwbGUiLCAgICAgICAgICAjIGNvbG9yIG9mIHRoZSBsaW5lIGdyYXBoDQogICAgIGx0eSA9IDEsICAgICAgICAgICAgICAjIGxpbmUgdHlwZS4gMSA9IHNvbGlkIGxpbmUNCiAgICAgbWFpbiA9ICJNZWFuIExlbmd0aCBhY3Jvc3MgU3VubGlnaHQgTGV2ZWwiKQ0KIyBBZGQgY3VzdG9tIHgtYXhpcw0KYXhpcyhzaWRlID0gMSwgYXQgPSB4LnRpY2tzLCBsYWJlbHMgPSB4LmxhYmVscykNCmBgYA0KDQpUaGUgYWJvdmUgbGluZSBwbG90IHNob3dzIHRoYXQgKip0aGUgZ3Jvd3RoIHJhdGUgZ2VuZXJhbGx5IGRlY3JlYXNlcyBhcyBzdW5saWdodCBpbmNyZWFzZXMsIGV4Y2VwdCBhdCB0aGUgbWVkaXVtIHN1bmxpZ2h0IGxldmVsLCBhdCB3aGljaCB0aGUgcmF0ZSBwZWFrcyoqLg0KDQpcDQoNCiogKipXYXRlcmluZyAoU2Vjb25kYXJ5IEZhY3RvcikqKjogQ29tcGFyZSBtZWFucyBhY3Jvc3Mgd2F0ZXJpbmcgbGV2ZWxzLCBpZ25vcmluZyBzdW5saWdodC4gPGZvbnQgY29sb3IgPSAiYmx1ZSI+Klxjb2xvcntibHVlfUZyZXF1ZW50IHdhdGVyaW5nIGluY3JlYXNlcyBncm93dGgsIGJ1dCB0aGlzIGVmZmVjdCBpcyBzbWFsbGVyIHRoYW4gc3VubGlnaHQncyBlZmZlY3QuKjwvZm9udD4NCg0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTUsIGZpZy5oZWlnaHQ9NH0NCiMgQ3VzdG9tIHRpY2sgbWFyayBwb3NpdGlvbnMgYW5kIGxhYmVscw0KeC50aWNrcyA8LSBjKDEsMikgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRpY2sgbWFya3MgLyBsb2NhdGlvbiBvZiB0aWNrIGxhYmVscw0KeC5sYWJlbHMgPC0gYygiRGFpbHkiLCAiV2Vla2x5IikNCiMgc3VubGlnaHQgbWVhbnMsIGlnbm9yaW5nDQpzdW4uZ3JwLm1lYW5zIDwtIGFnZ3JlZ2F0ZShncm93dGggfiB3YXRlcmluZywgZGF0YSA9IGdyb3d0aERhdGEsIG1lYW4pDQoNCiMgQ3JlYXRlIHRoZSBwbG90IHdpdGhvdXQgeC1heGlzICh4YXh0ID0gIm4iKQ0KcGxvdChjKDEsMiksIHN1bi5ncnAubWVhbnMkZ3Jvd3RoLCANCiAgICAgdHlwZSA9ICJiIiwNCiAgICAgeGF4dCA9ICJuIiwgDQogICAgIHhsYWIgPSAiV2F0ZXJpbmciLCANCiAgICAgeWxhYiA9ICJMZW5ndGggKGdyb3d0aCkiLCANCiAgICAgY29sID0gIm9yYW5nZTMiLCAgICAgICAgICAjIGNvbG9yIG9mIHRoZSBsaW5lIGdyYXBoDQogICAgIGx0eSA9IDEsICAgICAgICAgICAgICAjIGxpbmUgdHlwZS4gMSA9IHNvbGlkIGxpbmUNCiAgICAgbWFpbiA9ICJNZWFuIExlbmd0aCBhY3Jvc3MgV2F0ZXJpbmcgRnJlcXVlbmN5IikNCiMgQWRkIGN1c3RvbSB4LWF4aXMNCmF4aXMoc2lkZSA9IDEsIGF0ID0geC50aWNrcywgbGFiZWxzID0geC5sYWJlbHMpDQpgYGANCg0KVGhlIHBsb3QgYWJvdmUgc2hvd3MgdGhhdCAqKnRoZSBwbGFudCBncmV3IGJldHRlciB3aGVuIHdhdGVyZWQgZGFpbHkqKi4NCg0KXA0KDQojIyBBTk9WQSB3aXRoIEludGVyYWN0aXZlIEVmZmVjdA0KDQpBZnRlciBmaW5pc2hpbmcgdGhlIEFOT1ZBIHRlc3QsIHdlIHJlcG9ydCBtdWx0aXBsZSBjb21wYXJpc29ucyBiZXR3ZWVuIGdyb3VwcyBhc3NvY2lhdGVkIHdpdGggdGhlICoqc2lnbmlmaWNhbnQgZmFjdG9ycyoqLiBJZiBhIHR3by13YXkgQU5PVkEgcmV2ZWFscyBhIHNpZ25pZmljYW50IGludGVyYWN0aW9uIGVmZmVjdCwgaXQgbWVhbnMgdGhlIGltcGFjdCBvZiBvbmUgZmFjdG9yIChlLmcuLCBTdW5saWdodCBFeHBvc3VyZSkgZGVwZW5kcyBvbiB0aGUgbGV2ZWwgb2YgdGhlIG90aGVyIGZhY3RvciAoZS5nLiwgV2F0ZXJpbmcgRnJlcXVlbmN5KS4gVG8gaW50ZXJwcmV0IHRoaXMgaW50ZXJhY3Rpb24gcHJvcGVybHksIHdlIG11c3Q6DQoNCiogQ29tcGFyZSBncm91cHMgKip3aXRoaW4gY29tYmluYXRpb25zKiogKGUuZy4sICJgRGFpbHkgKyBMb3cgU3VubGlnaHRgIiB2cy4gImBXZWVrbHkgKyBNZWRpdW0gU3VubGlnaHRgIikuDQoNCiogQ29udHJvbCBmb3IgaW5mbGF0ZWQgVHlwZSBJIGVycm9yIHJhdGVzIChmYWxzZSBwb3NpdGl2ZXMpIGR1ZSB0byAqKm11bHRpcGxlIGNvbXBhcmlzb25zKiogYnkgdXNpbmcgKipzaW11bHRhbmVvdXMgbWV0aG9kcyoqIHN1Y2ggYXMgVHVrZXkncyBIU0QgdG8gYWRqdXN0ICpwKi12YWx1ZXMgdG8gbWFpbnRhaW4gdGhlIGZhbWlseS13aXNlIGVycm9yIHJhdGUgKEZXRVIpIGF0IGEgc2V0IGxldmVsIChlLmcuLCA1JSkuDQoNCkluIHRoZSBhYm92ZSAqKnBsYW50IGdyb3d0aCoqIGRhdGFzZXQsIHRoZSBBTk9WQSB0ZXN0IHN1Z2dlc3RzIGluc2lnbmlmaWNhbmNlIG9mIHRoZSBpbnRlcmFjdGl2ZSBlZmZlY3QgYmV0d2VlbiAqKnN1bmxpZ2h0KiogYW5kICoqd2F0ZXJpbmcqKi4gVGhlIG9ubHkgc2lnbmlmaWNhbnQgZmFjdG9yIGlzICoqc3VubGlnaHQqKi4gRm9yIGlsbHVzdHJhdGlvbiwgd2UgcGVyZm9ybSAqKnNpbXVsdGFuZW91cyBjb21wYXJpc29ucyoqIGZvciBpbmRpdmlkdWFsIGZhY3RvcnMgYW5kIHRoZWlyIGludGVyYWN0aW9ucyB1c2luZyBUdWtleSdzIEhTRC4NCg0KDQpUaGUgZ2VuZXJhbCBpZGVhIGluIGludGVycHJldGluZyBtdWx0aXBsZSBjb21wYXJpc29ucyBpcyB0byBmb2N1cyBvbiB0aGUga2V5IGZhY3RvciAoc3VjaCBhcyBzdW5saWdodCkgYW5kIGJyZWFrIGRvd24gdGhlIHNlY29uZGFyeSBmYWN0b3IgKHdhdGVyaW5nKQ0KDQoNCmBgYHtyfQ0KYW5vdmEuaW50ZXJhY3QgPC0gYW92KGdyb3d0aCB+IHN1bmxpZ2h0KndhdGVyaW5nLCBkYXRhID0gZ3Jvd3RoRGF0YSkgIA0KVHVrZXlIU0QoYW5vdmEuaW50ZXJhY3QpICAjIENvbXBhcmUgc3VubGlnaHQgbGV2ZWxzIHdpdGhpbiBEYWlseSB3YXRlcmluZyANCmBgYA0KDQpUaGUgYWJvdmUgc2ltdWx0YW5lb3VzIG11bHRpcGxlIGNvbXBhcmlzb25zIGFyZSBwcmVzZW50ZWQgaW4gdGhlIGZvcm0gb2YgY29uZmlkZW5jZSBpbnRlcnZhbHMgZm9yIHRoZSBkaWZmZXJlbmNlcywgYXMgd2VsbCBhcyBhZGp1c3RlZCBwLXZhbHVlcyB0byBlbnN1cmUgdGhhdCB0aGUgb3ZlcmFsbCBwLXZhbHVlIGlzIG5vdCBpbmZsYXRlZC4gQXMgdGhlIG51bWJlciBvZiBjb21iaW5hdGlvbnMgb2YgZmFjdG9yIGxldmVscyBpbmNyZWFzZXMsIGludGVycHJldGluZyB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbHMgYmVjb21lcyBtb3JlIGRpZmZpY3VsdC4gVG8gYWlkIGludGVycHJldGF0aW9uLCB3ZSBwcm92aWRlIGEgdmlzdWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBvdXRwdXR0ZWQgY29uZmlkZW5jZSBpbnRlcnZhbHMuIA0KDQpUaGUgZmlyc3QgdHdvIHBsb3RzIGNvcnJlc3BvbmQgdG8gdGhlIGZpcnN0IHR3byBzZXRzIG9mIGNvbmZpZGVuY2UgaW50ZXJ2YWxzLiBUaGUgaW50ZXJwcmV0YXRpb24gb2YgdGhlc2UgY29uZmlkZW5jZSB0YWJsZXMgYW5kIGZpZ3VyZXMgaXMgc3RyYWlnaHRmb3J3YXJkLiBIb3dldmVyLCB0aGUgbnVtYmVyIG9mIGludGVydmFscyBhc3NvY2lhdGVkIHdpdGggaW50ZXJhY3Rpb24gZWZmZWN0cyBpbmNyZWFzZXMgYXMgdGhlIG51bWJlciBvZiBmYWN0b3IgbGV2ZWxzIGdyb3dzLCBtYWtpbmcgaW50ZXJwcmV0YXRpb24gbW9yZSBjb21wbGV4LiBJbiB0aGUgcGxhbnQgZ3Jvd3RoIGV4YW1wbGUsIHRoZSB0d28gZmFjdG9ycyByZXN1bHQgaW4gMjggZGlmZmVyZW50IGdyb3VwIGNvbXBhcmlzb25zISBQcmFjdGljYWxseSBtZWFuaW5nZnVsIGNvbXBhcmlzb25zIGZvY3VzIG9uIGRpZmZlcmVuY2VzIGluIGdyb3d0aCByYXRlcyB1bmRlciB0aGUgc2FtZSBzdW5saWdodCBjb25kaXRpb25zIGJ1dCB3aXRoIGRpZmZlcmVudCB3YXRlcmluZyBmcmVxdWVuY2llcy4gIA0KDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9OH0NCnBhcihtYWk9YygxLjUsMywxLDEpKSAgICAgICAgICAgIyBNYWtlcyByb29tIG9uIHRoZSBwbG90IGZvciB0aGUgZ3JvdXAgbmFtZXMNCnBsb3QoVHVrZXlIU0QoYW5vdmEuaW50ZXJhY3QpLCAgIyBuYW1lIG9mIHRoZSBUdWtleUhTRCgpIG9iamVjdA0KICAgICBjZXgubGFiID0gMC42LCAgICAgICAgICAgICAjIGFkanVzdCB0aGUgZm9udCBzaXplIG9mIHRoZSBsYWJlbHMgb2YgdGhlIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHZlcnRpY2FsIGF4aXMNCiAgICAgbGFzID0gMSkgDQpgYGANCg0KVGhlIGxpbmUgc2VnbWVudHMgcmVwcmVzZW50IGNvbmZpZGVuY2UgaW50ZXJ2YWxzLiBUaGUgbWlkZGxlIGJhciBpbmRpY2F0ZXMgdGhlIGVzdGltYXRlZCBkaWZmZXJlbmNlLCBhbmQgdGhlIHR3byBlbmRzIHJlcHJlc2VudCB0aGUgbG93ZXIgYW5kIHVwcGVyIGJvdW5kcyBvZiB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbC4gVGhlIHZlcnRpY2FsIGRhc2hlZCBsaW5lIHJlcHJlc2VudHMgemVyby4gVGhhdCBpcywgaWYgYSBsaW5lIHNlZ21lbnQgaW50ZXJzZWN0cyB0aGUgdmVydGljYWwgZGFzaGVkIGxpbmUsIHRoZSBjb25maWRlbmNlIGludGVydmFsIGluY2x1ZGVzIHplcm8uIFRoaXMgaW1wbGllcyB0aGF0IHRoZSBkaWZmZXJlbmNlIGlzIG5vdCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LiBUaGVyZWZvcmUsIHdlIGNvbmNsdWRlIHRoYXQgdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSB0d28gbWVhbnMgYXNzb2NpYXRlZCB3aXRoIHRoZSB1bmRlcmx5aW5nIGdyb3Vwcy4NCg0KDQpUaGUgYWNyb3NzIGNvbXBhcmlzb24gd2Ugc2hvdWxkIGZvY3VzIG9uIGlzIGhpZ2hsaWdodGVkIGluIHRoZSBmb2xsb3dpbmcgZmlndXJlLg0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoPSI3NSUifQ0KaW5jbHVkZV9ncmFwaGljcygid2VlazA0L0ludGVyYWN0aW9uQ0ktUGxhbnRHcm93dGgucG5nIikNCmBgYA0KDQoNCkFtb25nIGFsbCBjb25maWRlbmNlIGludGVydmFscywgdGhlIGZvbGxvd2luZyBpbnRlcnZhbHMgc2hvdWxkIGJlIHJlcG9ydGVkLg0KDQp8ICoqR3JvdXAgRGlmZmVyZW5jZSoqICAgICB8ICoqZGlmZioqIHwgICoqbG93ZXIgQ0kqKiB8ICoqdXBwZXIgQ0kqKiAgfCAqKnAtdmFsdWUqKnwNCnw6LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXw6LS0tLS0tLXw6LS0tLS0tLS0tLS0tLS0tLXw6LS0tLS0tLS0tLS0tLS0tfDotLS0tLS0tLS18DQp8IE5vbmU6V2Vla2x5LU5vbmU6RGFpbHkgICAgIHwgLTAuMTQgfCAtMS4yMDcyNDkyOCAgfCAwLjkyNzI0OTI4IHwgMC45OTk4NTc4fCANCnwgTG93OldlZWtseS1Mb3c6RGFpbHkgICAgICAgfCAgMC4yNCB8IC0wLjgyNzI0OTI4ICB8IDEuMzA3MjQ5MjggfCAwLjk5NTQwNTV8IA0KfCBNZWRpdW06V2Vla2x5LU1lZGl1bTpEYWlseSB8ICAwLjM0IHwgLTAuNzI3MjQ5MjggIHwgMS40MDcyNDkyOCB8IDAuOTY1NzYzMHwgDQp8IEhpZ2g6V2Vla2x5LUhpZ2g6RGFpbHkgICAgIHwgLTAuNDYgfCAtMS41MjcyNDkyOCAgfCAwLjYwNzI0OTI4IHwgMC44NTIzMDIzfCANCg0KDQpcDQoNCiMgQ29uY2x1ZGluZyBSZW1hcmtzIGFuZCBQcmFjdGljZSBFeGVyY2lzZQ0KDQpXZSBoYXZlIGRpc2N1c3NlZCB0aGUgdHdvLXdheSBBTk9WQSBtZXRob2QgZm9yIGFuYWx5emluZyBhICoqcmVwbGljYXRlZCByYW5kb21pemVkIGJsb2NrIGRlc2lnbioqLCB3aXRob3V0IGZvY3VzaW5nIG9uIG1hdGhlbWF0aWNhbCBkZXJpdmF0aW9ucy4gSW5zdGVhZCwgd2UgZW1waGFzaXplZCB1bmRlcnN0YW5kaW5nIHRoZSB1bmRlcmx5aW5nIGNvbmNlcHRzIGFuZCBsb2dpYyBvZiB0aGUgdHdvLXdheSBBTk9WQSwgYXMgd2VsbCBhcyB1c2luZyB0aGUgUiBzb2Z0d2FyZSB0byBhbmFseXplIGRhdGEgZnJvbSByZWFsLXdvcmxkIHByb2JsZW1zLiBUaGUgUiBjb2RlIGFuZCBjb21tYW5kcyBwcm92aWRlZCBpbiB0aGlzIGFuZCBwcmV2aW91cyBub3RlcyBhcmUgcmVhZHkgdG8gYmUgYXBwbGllZCB0byBvdGhlciByZWFsLXdvcmxkIGRhdGEgYW5kIHByYWN0aWNhbCBhcHBsaWNhdGlvbnMuDQoNCg0KVGhlIGZvbGxvd2luZyBZb3VUdWJlIHZpZGVvIHByb3ZpZGVzIGFub3RoZXIgZXhhbXBsZSB1c2luZyBSICg8aHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1uUnR2NmJvRU90az4pLg0KDQpcDQoNCjxjZW50ZXI+PGEgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1uUnR2NmJvRU90ayIgdGFyZ2V0PSJwb3B1cCIgDQogICAgICAgICAgICAgICAgICAgb25jbGljaz0id2luZG93Lm9wZW4oJ2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9blJ0djZib0VPdGsnLA0KICAgICAgICAgICAgICAgICAgICAgICduYW1lJywnd2lkdGg9ODUwLGhlaWdodD01MDAnKSI+PGltZyBzcmMgPSAiaHR0cHM6Ly9wZW5nZHNjaS5naXRodWIuaW8vTUFUMTIxVzUvaW1nL1ZpZGVvSWNvbi5wbmciIHdpZHRoPSIyMDAiIGhlaWdodD0iMTIwIj48L2E+DQo8L2NlbnRlcj4NCg0KXA0KDQo8Zm9udCBjb2xvcj0icmVkIiBzaXplPSI0Ij4qKlxjb2xvcntyZWR9Q0FVVElPTioqPC9mb250PjogVGhlIG9uZS13YXkgYW5kIHR3by13YXkgQU5PVkEgbWV0aG9kcyBpbnRyb2R1Y2VkIGluIHRoaXMgYW5kIHByZXZpb3VzIG5vdGVzIGFyZSBiYXNlZCBvbiB0aGUgYXNzdW1wdGlvbiBvZiAqKmluZGVwZW5kZW50IG9ic2VydmF0aW9ucyoqLiBIb3dldmVyLCBpbiBtb3JlIGNvbXBsZXggZXhwZXJpbWVudGFsIGRlc2lnbnMsIG1lYXN1cmVtZW50cyBvZiB0aGUgKipzYW1lIGNoYXJhY3RlcmlzdGljKiogbWF5IGJlIHRha2VuIGZyb20gdGhlICoqc2FtZSBzdWJqZWN0KiogPGZvbnQgY29sb3IgPSAiYmx1ZSI+KipcY29sb3J7Ymx1ZX1tdWx0aXBsZSB0aW1lcyoqPC9mb250Pi4gU3VjaCBkYXRhIG11c3QgYmUgYW5hbHl6ZWQgdXNpbmcgPGZvbnQgY29sb3IgPSAicmVkIj4qKlxjb2xvcntyZWR9cmVwZWF0ZWQgbWVhc3VyZXMgQU5PVkEqKjwvZm9udD4gLSB3aGljaCBpcyBkaWZmZXJlbnQgZnJvbSB0aGUgQU5PVkEgdXNlZCBmb3IgYSByZXBsaWNhdGVkIFJCRCE8L2ZvbnQ+DQoNClwNCg0KRmluYWxseSwgYXMgYW4gZXhlcmNpc2UgdG8gZW5oYW5jZSB5b3VyIHVuZGVyc3RhbmRpbmcgb2YgdGhlIG1ldGhvZG9sb2d5IGFuZCB0byBwcmFjdGljZSB5b3VyIFIgc2tpbGxzIGZvciBmdXR1cmUgcmVhbC13b3JsZCBhcHBsaWNhdGlvbnMsIHdlIGVuY291cmFnZSB5b3UgdG8gdXNlIHRoZSBmb2xsb3dpbmcgKipyZWFjdGlvbiB0aW1lIGRhdGFzZXQqKiwgY29sbGVjdGVkIGZyb20gYSByZXBsaWNhdGVkIHJhbmRvbWl6ZWQgYmxvY2sgZGVzaWduIChSQkQpIGV4cGVyaW1lbnQsIHRvIHBlcmZvcm0gYSBjb21wcmVoZW5zaXZlIEFOT1ZBIGFuYWx5c2lzIGFuZCBwb3N0IGhvYyB0ZXN0cy4gVGhlIG9iamVjdGl2ZSBvZiB0aGUgcmVwbGljYXRlZCBSQkQgaXMgdG8gYXNzZXNzIHRoZSBlZmZlY3RzIG9mIGBiZWVyYCBhbmQgYGNhZmZlaW5lYCBvbiBgcmVzcG9uc2UgdGltZWAuDQoNCg0KYGBge3IgZWNobyA9IEZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aD0iNzAlIn0NCmluY2x1ZGVfZ3JhcGhpY3MoIndlZWswNC9SZXBsaWNhdGVSQkQtd29ya2luZ0RhdGEucG5nIikNCmBgYA0KDQoNCg0KDQo=