Why ANOVA?

You’ve likely spent time working with \(t\)-tests to compare the means of two groups. What happens when you have three or more independent groups and you want to know if their population means are equal?

  • The Problem: If we have \(k\) groups (e.g., \(k=4\)), we could run \(\binom{4}{2} = 6\) individual \(t\)-tests. This approach drastically inflates the Family-Wise Error Rate (FWER), the probability of making at least one Type I error across all tests.

  • The Solution: ANOVA: ANOVA is an omnibus test. It tests the single null hypothesis that all population means are equal:

\[H_0: \mu_1 = \mu_2 = \mu_3 = \dots = \mu_k\] If we reject \(H_0\), it means at least one mean is different from the others.

The Logic of ANOVA: Partitioning Variance

The core concept of ANOVA is that it analyzes the variance in the data to make inferences about the means. Specifically, it partitions the total observed variance into components explained by the factors and unexplained error:

  • Between-Group Variance (Treatment Variance): The variability between the group means. If the null hypothesis is false (i.e., the treatment works), this variance should be large.

  • Within-Group Variance (Error Variance): The variability within each group. This represents natural, unexplained random variation, regardless of the treatment.

The F-Ratio

The test statistic for ANOVA is the F-ratio, which is the ratio of these two variances:

\[F = \frac{\text{Mean Square Between (MSB)}}{\text{Mean Square Within (MSW)}} = \frac{\text{Variance explained by the model}}{\text{Unexplained error variance}}\]

  • If \(H_0\) is true: The group means are close, so the MSB will be similar to the MSW. \(F \approx 1\).
  • If \(H_0\) is false: The group means are far apart, meaning the treatment explains a large portion of the variance. MSB will be much larger than MSW. \(F > 1\) (and often \(> 2\) or \(3\), depending on the degrees of freedom).

Case Study: Vitamin C and Tooth Growth (One-Way)

Imagine we’re working for a pharmaceutical company trying to see which level of Vitamin C dose makes guinea pig teeth grow the longest. We use the built-in R dataset ToothGrowth, which examines the effect of Vitamin C dosage on the growth of teeth (odontoblasts) in guinea pigs. We initially focus on the different dosage levels (dose).

  • Outcome Variable: len (Tooth length)

  • Factor (Independent Variable): dose (Three levels: 0.5, 1.0, and 2.0 mg/day)

Data Preparation and Exploration in R (One-Way Setup)

# Load the dataset (it's already in R)
data(ToothGrowth)

# Convert 'dose' to a factor/categorical variable for all ANOVA modeling
ToothGrowth$dose <- as.factor(ToothGrowth$dose)

# Inspect the first few rows and structure
head(ToothGrowth)
str(ToothGrowth)
'data.frame':   60 obs. of  3 variables:
 $ len : num  4.2 11.5 7.3 5.8 6.4 10 11.2 11.2 5.2 7 ...
 $ supp: Factor w/ 2 levels "OJ","VC": 2 2 2 2 2 2 2 2 2 2 ...
 $ dose: Factor w/ 3 levels "0.5","1","2": 1 1 1 1 1 1 1 1 1 1 ...
# Visualize the data using a Boxplot (Essential first step!)
library(ggplot2)
ggplot(ToothGrowth, aes(x = dose, y = len, fill = dose)) +
  geom_boxplot() +
  labs(title = "Tooth Length vs. Vitamin C Dose",
       x = "Dose (mg/day)",
       y = "Tooth Length (mm)") +
  theme_minimal()

Running the One-Way ANOVA Model

The Setup (The Model)

  • Tooth Length (\(\text{len}\)): This is what we’re measuring—our Dependent Variable.
  • Vitamin C Dose (\(\text{dose}\)): This is what we’re changing—our Factor. We have 3 groups: Low (0.5), Medium (1.0), and High (2.0).
  • The Big Question (\(\mathbf{H_0}\)): Does the dose really matter? Or is any difference in tooth length just due to random luck (some guinea pigs are naturally bigger than others)? Our Null Hypothesis (\(H_0\)) is: “All three dose groups have the exact same average tooth length.”
# 1. Fit the ANOVA model
# The formula is 'len' (outcome) explained only by 'dose' (factor)
anova_model_one_way <- aov(len ~ dose, data = ToothGrowth)

# 2. View the ANOVA Summary Table
summary(anova_model_one_way)
            Df Sum Sq Mean Sq F value   Pr(>F)    
dose         2   2426    1213   67.42 9.53e-16 ***
Residuals   57   1026      18                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

The Variability Breakdown (Sum of Squares)

ANOVA’s job is to figure out why the tooth lengths vary. We split the total variation into two piles of “credit”:

Component Statistical Term Plain Language Analogy Result
Differences BETWEEN Groups \(\text{Sum Sq}\) for \(\text{dose}\) (2426) The “Dose Effect” Credit: The variation in tooth length that is clearly due to the fact that we changed the dose. This is the difference between the average tooth lengths of the Low, Medium, and High groups. 2426
Differences WITHIN Groups \(\text{Sum Sq}\) for \(\text{Residuals}\) (1026) The “Random Luck” Credit (Error): The variation within a single group (e.g., why one guinea pig on the Low dose has a longer tooth than another guinea pig on the same Low dose). This is the unavoidable natural variation or “noise.” 1026

The Comparison (The F-Test)

We use the Mean Squares (\(\text{Mean Sq}\)) to turn the “piles of credit” into an average variance per observation, essentially controlling for sample size.

The F-statistic (67.42) is the ratio of these two variances:

\[\mathbf{F} = \frac{\text{Mean Sq}_{\text{Dose}}}{\text{Mean Sq}_{\text{Residuals}}} = \frac{\text{The Variance explained by our factor}}{\text{The Unexplained Variance (Error)}}\]

  • If the Null Hypothesis is TRUE (Dose doesn’t matter): The numerator (Dose Effect) should be about the same size as the denominator (Random Luck), so \(F \approx 1\).
  • If the Null Hypothesis is FALSE (Dose DOES matter): The Dose Effect is much bigger than Random Luck, so \(\mathbf{F \gg 1}\).

Our F-value is 67.42. This is a big number, telling us that the variation between the dose groups is about 67 times larger than the random variation within the groups. This strongly suggests the dose is doing something!

The Final Verdict (The P-Value)

  • P-Value (\(\text{Pr(>F)}\)): \(\mathbf{9.53\text{e-16}}\) (or \(0.000...0953\)).
  • What this P-Value means: This is the probability of getting an F-ratio as high as 67.42 if the null hypothesis were actually true (i.e., if all doses were exactly the same).
  • Since this probability is extremely tiny (much less than 0.05), we conclude that the results we observed are not due to random chance.

Conclusion:

We reject the Null Hypothesis. There is compelling evidence that the average tooth length is significantly affected by the dose of Vitamin C. The dose level definitely matters!

Assumptions and Diagnostics

ANOVA requires three key assumptions:

  1. Independence,

  2. Normality of Residuals, and

  3. Homogeneity of Variances.

# --- Checking Normality of Residuals ---
# A visual check using the QQ plot of the residuals
par(mfrow = c(1, 2)) # Set up plotting area
plot(anova_model_one_way, which = 2) # Q-Q Plot: Points should fall along the line.

Levene’s Test for Homogeneity of Variance

Before trusting the p-value from the ANOVA, we must check its assumptions. The most critical assumptions are normality (data within each group follows a normal distribution) and homogeneity of variance (the variance, or spread, of the data is roughly the same across all groups).

Levene’s Test is used specifically to check the homogeneity of variance assumption.

The Hypotheses for Levene’s Test

Levene’s Test uses an \(F\)-statistic, just like ANOVA, but its hypotheses are about the variances (\(\sigma^2\)), not the means (\(\mu\)):

  • Null Hypothesis (\(H_0\)): All population variances are equal. \[\mathbf{H_0}: \sigma^2_{0.5} = \sigma^2_{1.0} = \sigma^2_{2.0}\] (In plain language: The spread of tooth length data is the same for all three dose groups.)
  • Alternative Hypothesis (\(H_a\)): At least one population variance is different. \[\mathbf{H_a}: \text{Not all } \sigma^2 \text{'s are equal.}\] (In plain language: The spread of tooth length data is different for at least one dose group.)

In contrast to the ANOVA, we actually want to FAIL to reject \(H_0\) for Levene’s test. Rejecting \(H_0\) means the assumption is violated, and our ANOVA results might be unreliable.

# --- Checking Homogeneity of Variance ---
# Formal Test for Homogeneity: Levene's Test (use 'car' package)
library(car)
leveneTest(len ~ dose, data = ToothGrowth)

# H0 for Levene's test: Variances are equal.
# A non-significant p-value (p > 0.05) means we DO NOT reject H0,
# supporting the assumption of homogeneity.

Interpreting the Output

Source \(\text{Df}\) \(\text{F value}\) \(\text{Pr(>F)}\)
\(\text{group}\) 2 0.6457 0.5281
57
  • Degrees of Freedom (\(\text{Df}\)):

    • \(\text{group}\) (2): Degrees of freedom for the numerator (number of groups minus 1).
    • 57: Degrees of freedom for the denominator (total observations minus number of groups).
  • F-Value (\(\mathbf{0.6457}\)): This is the test statistic for Levene’s test.

  • P-Value (\(\text{Pr(>F)}\)): \(\mathbf{0.5281}\). This is the probability of observing an \(F\)-statistic this large (or larger) if the variances were truly equal.

Conclusion on Homogeneity of Variance

To make a decision, we compare the p-value (\(\mathbf{0.5281}\)) to our significance level, \(\alpha = 0.05\).

  • Since the p-value (\(0.5281\)) is greater than \(\alpha = 0.05\), we FAIL to reject the Null Hypothesis (\(\mathbf{H_0}\)) of equal variances.

What this means: We do not have sufficient statistical evidence to conclude that the variance (spread) in tooth length is different across the three dose groups.

Final Assessment of the ANOVA Model:

Because we failed to reject \(H_0\) in Levene’s test, we can conclude that the homogeneity of variance assumption is met. Therefore, the \(F\)-test and p-value obtained from your initial one-way ANOVA (which found a significant effect of dose) are reliable.

(Self-Correction/Next Step): If this test had been significant (\(p < 0.05\)), you would need an alternative robust ANOVA methods, like Welch’s ANOVA, which does not require the assumption of equal variances or the Kruskal-Wallis test, which requires no distributional assumptions.

Post-Hoc Analysis (The Follow-up)

If the overall ANOVA \(F\)-test is significant, we use post-hoc tests to find which specific pairs differ, controlling the Family-Wise Error Rate (FWER).

Our F-test told us “Something is different.” It didn’t tell us “Which specific dose levels are different from each other.”

To answer that, you need to run Post-Hoc Tests (like Tukey’s HSD) to perform multiple head-to-head comparisons: * Does \(0.5\text{ mg}\) differ from \(1.0\text{ mg}\)? * Does \(1.0\text{ mg}\) differ from \(2.0\text{ mg}\)? * Does \(0.5\text{ mg}\) differ from \(2.0\text{ mg}\)?

# If the F-test was significant (e.g., p < 0.05), run Tukey's HSD.
tukey_results_one_way <- TukeyHSD(anova_model_one_way)

# Print the results
print(tukey_results_one_way)

The ANOVA told us, “Yes, the dose matters.” Tukey’s HSD test answers the question, “Specifically, which doses are different from each other?”

Tukey’s test performs all possible pairwise comparisons (group A vs. group B, group A vs. group C, and group B vs. group C) while controlling the Family-Wise Error Rate (FWER). This means the overall 95% confidence level applies to the entire set of three comparisons, not just to each individual one.

Understanding the Output Structure

Comparison \(\text{diff}\) (Mean Difference) \(\text{lwr}\) (Lower 95% CI) \(\text{upr}\) (Upper 95% CI) \(\text{p adj}\) (Adjusted P-Value)
\(\mathbf{1 - 0.5}\) \(9.130\) \(5.901805\) \(12.358195\) \(0.00\text{e}+00\)
\(\mathbf{2 - 0.5}\) \(15.495\) \(12.266805\) \(18.723195\) \(0.00\text{e}+00\)
\(\mathbf{2 - 1}\) \(6.365\) \(3.136805\) \(9.593195\) \(4.25\text{e}-05\)

The columns show the result for the three comparisons between the dose levels (0.5, 1, and 2 mg/day).

Analysis of Each Comparison

We look at two things for each row: 1. Does the 95% Confidence Interval (CI) contain zero? If the interval (\(\text{lwr}\) to \(\text{upr}\)) does not contain zero, the difference is statistically significant. 2. Is the Adjusted P-value (\(\text{p adj}\)) less than \(\alpha = 0.05\)? If yes, the difference is statistically significant.

Comparison 1: Dose 1.0 vs. Dose 0.5 (1 - 0.5)

  • Difference (\(\text{diff}\)): \(9.130\). The average tooth length at \(1.0\text{ mg}\) dose is \(9.13\text{ units}\) longer than at the \(0.5\text{ mg}\) dose.
  • 95% CI: \([5.90, 12.36]\). This entire interval is positive (it does not contain zero).
  • P-Value (\(\text{p adj}\)): \(0.00\text{e}+00\) (extremely small).
  • Conclusion: The difference between \(1.0\text{ mg}\) and \(0.5\text{ mg}\) is highly statistically significant.

Comparison 2: Dose 2.0 vs. Dose 0.5 (2 - 0.5)

  • Difference (\(\text{diff}\)): \(15.495\). The average tooth length at \(2.0\text{ mg}\) dose is \(15.5\text{ units}\) longer than at the \(0.5\text{ mg}\) dose.
  • 95% CI: \([12.27, 18.72]\). This interval is also fully positive (does not contain zero).
  • P-Value (\(\text{p adj}\)): \(0.00\text{e}+00\) (extremely small).
  • Conclusion: The difference between \(2.0\text{ mg}\) and \(0.5\text{ mg}\) is highly statistically significant.

Comparison 3: Dose 2.0 vs. Dose 1.0 (2 - 1)

  • Difference (\(\text{diff}\)): \(6.365\). The average tooth length at \(2.0\text{ mg}\) dose is \(6.365\text{ units}\) longer than at the \(1.0\text{ mg}\) dose.
  • 95% CI: \([3.14, 9.59]\). This interval is also fully positive (does not contain zero).
  • P-Value (\(\text{p adj}\)): \(4.25\text{e}-05\), which is \(0.0000425\). This is much smaller than \(0.05\).
  • Conclusion: The difference between \(2.0\text{ mg}\) and \(1.0\text{ mg}\) is statistically significant.

Summary of Findings

Based on the Tukey HSD test, we find that all three pairwise comparisons are statistically significant. This means that increasing the dose from one level to the next (low to medium, medium to high, and low to high) resulted in a measurable, non-random increase in average tooth length.

  • \(\mathbf{0.5\text{ mg}}\) is significantly different from \(\mathbf{1.0\text{ mg}}\).
  • \(\mathbf{0.5\text{ mg}}\) is significantly different from \(\mathbf{2.0\text{ mg}}\).
  • \(\mathbf{1.0\text{ mg}}\) is significantly different from \(\mathbf{2.0\text{ mg}}\).

In a research context, you would report this by stating that increasing the Vitamin C dose leads to a dose-dependent increase in tooth growth, and that the effect observed at each dose level is distinct from the others.

Visualize the post-hoc results

plot(tukey_results_one_way)

Summary of One-Way ANOVA

Step R Function(s) Purpose
Model Fit anova_model <- aov(Y ~ X, data=...) Partitions variance.
Global Test summary(anova_model) Checks if \(H_0: \mu_1=\dots=\mu_k\) is rejected via the F-ratio.
Assumptions plot(anova_model) / leveneTest() Confirms Normality and Homogeneity of Variance.
Post-Hoc TukeyHSD(anova_model) Identifies specific pairwise mean differences if the Global Test was significant.

Extending the Model: Two-Way ANOVA

Two-Way ANOVA is used when you have two independent categorical factors influencing one continuous outcome variable. Our ToothGrowth dataset has a second factor:

  • Factor 1: dose (0.5, 1.0, 2.0 mg/day)
  • Factor 2: supp (Supplement type: Orange Juice [OJ] vs. Ascorbic Acid [VC])

Two-Way ANOVA allows us to test three separate null hypotheses: - Main Effect of Factor 1: \(H_0: \mu_{\text{dose}_{0.5}} = \mu_{\text{dose}_{1.0}} = \mu_{\text{dose}_{2.0}}\) (Averaged across supplement types).

  • Main Effect of Factor 2: \(H_0: \mu_{\text{OJ}} = \mu_{\text{VC}}\) (Averaged across dose levels). Interaction Effect (Factor 1 \(\times\) Factor 2): \(H_0\): The effect of dose is the same across both levels of supp.

Model 1: Additive Effects (No Interaction)

This model assumes the effect of dose is constant regardless of supp, and vice versa. It is specified using the + operator.

# Note: 'supp' is already a factor in the original dataset
anova_model_additive <- aov(len ~ dose + supp, data = ToothGrowth)

# View the ANOVA Summary Table
summary(anova_model_additive)

The Hypotheses

For this Two-Way ANOVA, we test two separate Null Hypotheses:

Source Null Hypothesis (\(H_0\))
Dose (\(\text{dose}\)) The mean tooth length is the same across all dose levels (0.5, 1.0, 2.0).
Supplement (\(\text{supp}\)) The mean tooth length is the same for both supplement types (OJ and VC).

Interpreting the Summary Table (Main Effects)

The table breaks down the total variability into the variance explained by each factor and the remaining unexplained error (\(\text{Residuals}\)).

Source Df Sum Sq Mean Sq F value \(\text{Pr(>F)}\)
\(\text{dose}\) 2 2426.4 1213.2 82.81 \(< 2\text{e-16}\)
\(\text{supp}\) 1 205.3 205.3 14.02 \(0.000429\)
\(\text{Residuals}\) 56 820.4 14.7

The Effect of Dose

  • P-Value (\(\text{Pr(>F)}\)): \(< 2\text{e-16}\). This is an extremely small number, far below \(\alpha = 0.05\).
  • F-Value: \(82.81\). This is the ratio of the variance explained by \(\text{dose}\) to the unexplained error. It is very large.
  • Conclusion: We reject the null hypothesis for \(\text{dose}\). There is a highly statistically significant effect of the Vitamin C dose level on mean tooth length (\(F(2, 56) = 82.81, p < 0.001\)).
  • (Next Step): Since the \(\text{dose}\) factor has more than two levels, you would need to run Tukey’s HSD (post-hoc test) to see which specific dose levels differ (0.5 vs 1.0, 1.0 vs 2.0, etc.).

The Effect of Supplement Type

  • P-Value (\(\text{Pr(>F)}\)): \(0.000429\). This is also far below \(\alpha = 0.05\).
  • F-Value: \(14.02\).
  • Conclusion: We reject the null hypothesis for \(\text{supp}\). There is a highly statistically significant effect of the supplement type (OJ vs. VC) on mean tooth length (\(F(1, 56) = 14.02, p < 0.001\)).
  • (Interpretation): Since \(\text{supp}\) only has two levels, this significant result immediately tells us that the mean tooth length for one supplement type (we don’t know which one yet, but likely Orange Juice) is significantly different from the other (Ascorbic Acid). No post-hoc test is needed.

The Residuals (Error)

  • \(\text{Df} = 56\): This is the degrees of freedom for the error term, used in calculating the p-values.
  • \(\text{Mean Sq} = 14.7\): This is the Mean Square Error (\(\text{MSE}\)). It is our best estimate of the population variance (\(\sigma^2\)) that is not explained by either \(\text{dose}\) or \(\text{supp}\). This value (14.7) is the denominator used to calculate both \(F\)-values: \[\text{F}_{\text{dose}} = \frac{1213.2}{14.7} \approx 82.81\] \[\text{F}_{\text{supp}} = \frac{205.3}{14.7} \approx 14.02\]

Summary in Plain Language

The analysis shows that both factors we tested have a statistically significant impact on tooth growth:

  1. Dose Level: Increasing the dose of Vitamin C leads to changes in tooth length that are not due to random chance.
  2. Supplement Type: The way the Vitamin C is delivered (Orange Juice vs. Ascorbic Acid) also has a significant effect on tooth length, independent of the actual dose.

(A Note on the Missing Interaction:) If the model had included an interaction term (\(\text{dose} \times \text{supp}\)), we would check that first. If the interaction were significant, it would mean the effect of \(\text{dose}\) depends on the type of \(\text{supp}\), making the main effects interpretations less meaningful. Since it’s missing here, we interpret the two main effects as independent influences.

Model 2: Interaction Effects (Non-Additive)

The interaction term checks if the relationship between one factor and the outcome depends on the level of the second factor. This is specified using the * operator, which is a shortcut for Factor1 + Factor2 + Factor1:Factor2.

# Use the '*' operator to include main effects and the interaction term
anova_model_interaction <- aov(len ~ dose * supp, data = ToothGrowth)

# View the ANOVA Summary Table
summary(anova_model_interaction)

The Hierarchy of Interpretation

When reading a Two-Way ANOVA table, always look at the interaction term first.

Source \(F \text{ value}\) \(\text{Pr(>F)}\) Significance Interpretation Focus
\(\mathbf{\text{dose:supp}}\) (Interaction) 4.107 0.021860 \(\mathbf{*}\) (Significant) Start Here! If this is significant, the main effects are complex.
\(\text{dose}\) (Main Effect) 92.000 \(< 2\text{e-16}\) \(\mathbf{***}\) Interpret these effects with caution in light of the interaction.
\(\text{supp}\) (Main Effect) 15.572 \(0.000231\) \(\mathbf{***}\) Interpret these effects with caution in light of the interaction.

The Critical Interaction Effect

The interaction term tests the following:

  • Null Hypothesis (\(H_{0, \text{int}}\)): The effect of \(\text{dose}\) on tooth length is the same regardless of the \(\text{supp}\) type (i.e., the lines on a plot of means are parallel).
  • Alternative Hypothesis (\(H_{a, \text{int}}\)): The effect of \(\text{dose}\) depends on the \(\text{supp}\) type (i.e., the lines are not parallel).

Interpretation of \(\text{dose:supp}\):

  • P-Value (\(\text{Pr(>F)}\)): \(\mathbf{0.021860}\).
  • Since \(0.021860 < 0.05\), we reject the Null Hypothesis for the interaction.
  • Conclusion: The interaction between \(\text{dose}\) and \(\text{supp}\) is statistically significant (\(\mathbf{F(2, 54) = 4.107, p = 0.022}\)).

What this means in plain language: The way dose affects tooth length is different for animals receiving Orange Juice (OJ) versus those receiving Ascorbic Acid (VC). You cannot make a single, simple statement about the effect of dose alone or supplement alone; you must describe the effect of one factor at each level of the other factor.

Interpreting Significant Main Effects (In Context)

Because the interaction is significant, the interpretation of the main effects of \(\text{dose}\) and \(\text{supp}\) becomes secondary and needs qualification. They tell us there are overall differences, but the interaction shows how those differences manifest.

Main Effect of Dose

  • P-Value: \(< 2\text{e-16}\). Highly Significant.
  • Interpretation: Although the effect of \(\text{dose}\) is highly significant overall, we know from the interaction that this effect is not uniform across the two supplement types.
    • The dose effect exists, but its magnitude or pattern changes depending on whether the supplement is OJ or VC.

Main Effect of Supplement

  • P-Value: \(0.000231\). Highly Significant.
  • Interpretation: While overall, one supplement type produces significantly longer teeth than the other, the significant interaction means this difference varies across the different dose levels.
    • For example, OJ might be much better than VC at a low dose, but the difference might disappear or even reverse at a high dose.

Next Steps for Analysis

When the interaction is significant, the main effects are often ignored in favor of a deeper dive into the specific group combinations.

The statistical technique required is Simple Effects Analysis or Post-Hoc Tests on the Cell Means.

  1. Simple Effects: Run separate one-way ANOVAs (or \(t\)-tests) to find:
    • Is there a significant difference between OJ and VC at the \(0.5\text{ mg}\) dose?
    • Is there a significant difference between OJ and VC at the \(1.0\text{ mg}\) dose?
    • Is there a significant difference between OJ and VC at the \(2.0\text{ mg}\) dose?
  2. Visualization: The best way to present this is with an Interaction Plot . This visual clearly shows the non-parallel lines, confirming the dependence of the \(\text{dose}\) effect on \(\text{supp}\).

Follow-up when Interaction is Significant (Model 2):

If the interaction term (dose:supp) is significant, the appropriate next step is to visualize the interaction and test the simple main effects—the effect of one factor at a specific level of the other factor.

# Visualize the interaction (Essential for a significant interaction!)
ggplot(ToothGrowth, aes(x = dose, y = len, group = supp, color = supp)) +
  stat_summary(fun = mean, geom = "point") + # Plot means
  stat_summary(fun = mean, geom = "line") + # Connect means with lines
  labs(title = "Interaction Plot: Tooth Length by Dose and Supplement",
       x = "Dose (mg/day)",
       y = "Tooth Length (mm)") +
  theme_minimal()

Non-parallel lines suggest an interaction.

Iterpretation of Main Effects vs. Interaction

Be aware that interpreting significant main effects when a significant interaction is present is generally inappropriate, as the averaged main effects hide the complexity of the conditional effects. The interaction plot becomes the primary tool for initial interpretation.

The interpretation of the main effects must be qualified by the significance of the interaction term.

Interaction Term (pp-value) Interpretation Guidance
Not Significant (\(p > \alpha\)) Additive Model is preferred. Interpret the main effects of dose and supp directly. Their effects are independent.
Significant (\(p \le \alpha\)) The interaction effect is the focus. The main effects are misleading or uninterpretable on their own. The effect of dose depends on supp (and vice-versa). You must follow up with simple main effects or contrasts to understand the group means.
LS0tDQp0aXRsZTogIkFuYWx5c2lzIG9mIFZhcmlhbmNlIChBTk9WQSkgaW4gUiINCm91dHB1dDogDQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQotLS0NCg0KIyBXaHkgQU5PVkE/DQpZb3UndmUgbGlrZWx5IHNwZW50IHRpbWUgd29ya2luZyB3aXRoICR0JC10ZXN0cyB0byBjb21wYXJlIHRoZSBtZWFucyBvZiB0d28gZ3JvdXBzLiBXaGF0IGhhcHBlbnMgd2hlbiB5b3UgaGF2ZSB0aHJlZSBvciBtb3JlIGluZGVwZW5kZW50IGdyb3VwcyBhbmQgeW91IHdhbnQgdG8ga25vdyBpZiB0aGVpciBwb3B1bGF0aW9uIG1lYW5zIGFyZSBlcXVhbD8NCg0KIC0gX19UaGUgUHJvYmxlbTpfXyBJZiB3ZSBoYXZlICRrJCBncm91cHMgKGUuZy4sICRrPTQkKSwgd2UgY291bGQgcnVuICRcYmlub217NH17Mn0gPSA2JCBpbmRpdmlkdWFsICR0JC10ZXN0cy4gVGhpcyBhcHByb2FjaCBkcmFzdGljYWxseSBpbmZsYXRlcyB0aGUgRmFtaWx5LVdpc2UgRXJyb3IgUmF0ZSAoW0ZXRVJdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0ZhbWlseS13aXNlX2Vycm9yX3JhdGUpKSwgdGhlIHByb2JhYmlsaXR5IG9mIG1ha2luZyBhdCBsZWFzdCBvbmUgVHlwZSBJIGVycm9yIGFjcm9zcyBhbGwgdGVzdHMuICANCiANCiAtIF9fVGhlIFNvbHV0aW9uOiBBTk9WQTpfXyBBTk9WQSBpcyBhbiBvbW5pYnVzIHRlc3QuIEl0IHRlc3RzIHRoZSBzaW5nbGUgbnVsbCBoeXBvdGhlc2lzIHRoYXQgYWxsIHBvcHVsYXRpb24gbWVhbnMgYXJlIGVxdWFsOiAgDQoNCiQkSF8wOiBcbXVfMSA9IFxtdV8yID0gXG11XzMgPSBcZG90cyA9IFxtdV9rJCQNCklmIHdlIHJlamVjdCAkSF8wJCwgaXQgbWVhbnMgYXQgbGVhc3Qgb25lIG1lYW4gaXMgZGlmZmVyZW50IGZyb20gdGhlIG90aGVycy4NCg0KIyMgVGhlIExvZ2ljIG9mIEFOT1ZBOiBQYXJ0aXRpb25pbmcgVmFyaWFuY2UgIA0KDQpUaGUgY29yZSBjb25jZXB0IG9mIEFOT1ZBIGlzIHRoYXQgaXQgYW5hbHl6ZXMgdGhlIHZhcmlhbmNlIGluIHRoZSBkYXRhIHRvIG1ha2UgaW5mZXJlbmNlcyBhYm91dCB0aGUgbWVhbnMuIFNwZWNpZmljYWxseSwgaXQgcGFydGl0aW9ucyB0aGUgdG90YWwgb2JzZXJ2ZWQgdmFyaWFuY2UgaW50byBjb21wb25lbnRzIGV4cGxhaW5lZCBieSB0aGUgZmFjdG9ycyBhbmQgdW5leHBsYWluZWQgZXJyb3I6DQoNCiAtIF9fQmV0d2Vlbi1Hcm91cCBWYXJpYW5jZSAoVHJlYXRtZW50IFZhcmlhbmNlKTpfXyBUaGUgdmFyaWFiaWxpdHkgYmV0d2VlbiB0aGUgZ3JvdXAgbWVhbnMuIElmIHRoZSBudWxsIGh5cG90aGVzaXMgaXMgZmFsc2UgKGkuZS4sIHRoZSB0cmVhdG1lbnQgd29ya3MpLCB0aGlzIHZhcmlhbmNlIHNob3VsZCBiZSBsYXJnZS4gIA0KDQogLSBfX1dpdGhpbi1Hcm91cCBWYXJpYW5jZSAoRXJyb3IgVmFyaWFuY2UpOl9fIFRoZSB2YXJpYWJpbGl0eSB3aXRoaW4gZWFjaCBncm91cC4gVGhpcyByZXByZXNlbnRzIG5hdHVyYWwsIHVuZXhwbGFpbmVkIHJhbmRvbSB2YXJpYXRpb24sIHJlZ2FyZGxlc3Mgb2YgdGhlIHRyZWF0bWVudC4NCiANCiMjIyBUaGUgRi1SYXRpbw0KDQpUaGUgdGVzdCBzdGF0aXN0aWMgZm9yIEFOT1ZBIGlzIHRoZSBGLXJhdGlvLCB3aGljaCBpcyB0aGUgcmF0aW8gb2YgdGhlc2UgdHdvIHZhcmlhbmNlczogIA0KDQokJEYgPSBcZnJhY3tcdGV4dHtNZWFuIFNxdWFyZSBCZXR3ZWVuIChNU0IpfX17XHRleHR7TWVhbiBTcXVhcmUgV2l0aGluIChNU1cpfX0gPSBcZnJhY3tcdGV4dHtWYXJpYW5jZSBleHBsYWluZWQgYnkgdGhlIG1vZGVsfX17XHRleHR7VW5leHBsYWluZWQgZXJyb3IgdmFyaWFuY2V9fSQkDQoNCiAtIElmICRIXzAkIGlzIHRydWU6IFRoZSBncm91cCBtZWFucyBhcmUgY2xvc2UsIHNvIHRoZSBNU0Igd2lsbCBiZSBzaW1pbGFyIHRvIHRoZSBNU1cuICRGIFxhcHByb3ggMSQuICANCiAtIElmICRIXzAkIGlzIGZhbHNlOiBUaGUgZ3JvdXAgbWVhbnMgYXJlIGZhciBhcGFydCwgbWVhbmluZyB0aGUgdHJlYXRtZW50IGV4cGxhaW5zIGEgbGFyZ2UgcG9ydGlvbiBvZiB0aGUgdmFyaWFuY2UuIE1TQiB3aWxsIGJlIG11Y2ggbGFyZ2VyIHRoYW4gTVNXLiAkRiA+IDEkIChhbmQgb2Z0ZW4gJD4gMiQgb3IgJDMkLCBkZXBlbmRpbmcgb24gdGhlIGRlZ3JlZXMgb2YgZnJlZWRvbSkuICANCg0KIyBDYXNlIFN0dWR5OiBWaXRhbWluIEMgYW5kIFRvb3RoIEdyb3d0aCAoT25lLVdheSkNCkltYWdpbmUgd2UncmUgd29ya2luZyBmb3IgYSBwaGFybWFjZXV0aWNhbCBjb21wYW55IHRyeWluZyB0byBzZWUgd2hpY2ggbGV2ZWwgb2YgVml0YW1pbiBDIGRvc2UgbWFrZXMgZ3VpbmVhIHBpZyB0ZWV0aCBncm93IHRoZSBsb25nZXN0LiBXZSB1c2UgdGhlIGJ1aWx0LWluIFIgZGF0YXNldCBbVG9vdGhHcm93dGhdKGh0dHBzOi8vd3d3LnJkb2N1bWVudGF0aW9uLm9yZy9wYWNrYWdlcy9kYXRhc2V0cy92ZXJzaW9ucy8zLjYuMi90b3BpY3MvVG9vdGhHcm93dGgpLCB3aGljaCBleGFtaW5lcyB0aGUgZWZmZWN0IG9mIFZpdGFtaW4gQyBkb3NhZ2Ugb24gdGhlIGdyb3d0aCBvZiB0ZWV0aCAob2RvbnRvYmxhc3RzKSBpbiBndWluZWEgcGlncy4gV2UgaW5pdGlhbGx5IGZvY3VzIG9uIHRoZSBkaWZmZXJlbnQgZG9zYWdlIGxldmVscyAoZG9zZSkuDQoNCiAtIF9fT3V0Y29tZSBWYXJpYWJsZTpfXyBgbGVuYCAoVG9vdGggbGVuZ3RoKQ0KDQogLSBfX0ZhY3RvciAoSW5kZXBlbmRlbnQgVmFyaWFibGUpOl9fIGBkb3NlYCAoVGhyZWUgbGV2ZWxzOiAwLjUsIDEuMCwgYW5kIDIuMCBtZy9kYXkpDQoNCiMjIERhdGEgUHJlcGFyYXRpb24gYW5kIEV4cGxvcmF0aW9uIGluIFIgKE9uZS1XYXkgU2V0dXApDQoNCmBgYHtyfQ0KIyBMb2FkIHRoZSBkYXRhc2V0IChpdCdzIGFscmVhZHkgaW4gUikNCmRhdGEoVG9vdGhHcm93dGgpDQoNCiMgQ29udmVydCAnZG9zZScgdG8gYSBmYWN0b3IvY2F0ZWdvcmljYWwgdmFyaWFibGUgZm9yIGFsbCBBTk9WQSBtb2RlbGluZw0KVG9vdGhHcm93dGgkZG9zZSA8LSBhcy5mYWN0b3IoVG9vdGhHcm93dGgkZG9zZSkNCg0KIyBJbnNwZWN0IHRoZSBmaXJzdCBmZXcgcm93cyBhbmQgc3RydWN0dXJlDQpoZWFkKFRvb3RoR3Jvd3RoKQ0Kc3RyKFRvb3RoR3Jvd3RoKQ0KDQojIFZpc3VhbGl6ZSB0aGUgZGF0YSB1c2luZyBhIEJveHBsb3QgKEVzc2VudGlhbCBmaXJzdCBzdGVwISkNCmxpYnJhcnkoZ2dwbG90MikNCmdncGxvdChUb290aEdyb3d0aCwgYWVzKHggPSBkb3NlLCB5ID0gbGVuLCBmaWxsID0gZG9zZSkpICsNCiAgZ2VvbV9ib3hwbG90KCkgKw0KICBsYWJzKHRpdGxlID0gIlRvb3RoIExlbmd0aCB2cy4gVml0YW1pbiBDIERvc2UiLA0KICAgICAgIHggPSAiRG9zZSAobWcvZGF5KSIsDQogICAgICAgeSA9ICJUb290aCBMZW5ndGggKG1tKSIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KIyMgUnVubmluZyB0aGUgT25lLVdheSBBTk9WQSBNb2RlbA0KDQojIyMgVGhlIFNldHVwIChUaGUgTW9kZWwpDQoNCiogKipUb290aCBMZW5ndGggKCRcdGV4dHtsZW59JCk6KiogVGhpcyBpcyB3aGF0IHdlJ3JlIG1lYXN1cmluZ+KAlG91ciAqKkRlcGVuZGVudCBWYXJpYWJsZSoqLg0KKiAqKlZpdGFtaW4gQyBEb3NlICgkXHRleHR7ZG9zZX0kKToqKiBUaGlzIGlzIHdoYXQgd2UncmUgY2hhbmdpbmfigJRvdXIgKipGYWN0b3IqKi4gV2UgaGF2ZSAzIGdyb3VwczogTG93ICgwLjUpLCBNZWRpdW0gKDEuMCksIGFuZCBIaWdoICgyLjApLg0KKiAqKlRoZSBCaWcgUXVlc3Rpb24gKCRcbWF0aGJme0hfMH0kKToqKiBEb2VzIHRoZSBkb3NlICpyZWFsbHkqIG1hdHRlcj8gT3IgaXMgYW55IGRpZmZlcmVuY2UgaW4gdG9vdGggbGVuZ3RoIGp1c3QgZHVlIHRvIHJhbmRvbSBsdWNrIChzb21lIGd1aW5lYSBwaWdzIGFyZSBuYXR1cmFsbHkgYmlnZ2VyIHRoYW4gb3RoZXJzKT8gT3VyIE51bGwgSHlwb3RoZXNpcyAoJEhfMCQpIGlzOiAqKiJBbGwgdGhyZWUgZG9zZSBncm91cHMgaGF2ZSB0aGUgZXhhY3Qgc2FtZSBhdmVyYWdlIHRvb3RoIGxlbmd0aC4iKioNCg0KYGBge3J9DQojIDEuIEZpdCB0aGUgQU5PVkEgbW9kZWwNCiMgVGhlIGZvcm11bGEgaXMgJ2xlbicgKG91dGNvbWUpIGV4cGxhaW5lZCBvbmx5IGJ5ICdkb3NlJyAoZmFjdG9yKQ0KYW5vdmFfbW9kZWxfb25lX3dheSA8LSBhb3YobGVuIH4gZG9zZSwgZGF0YSA9IFRvb3RoR3Jvd3RoKQ0KDQojIDIuIFZpZXcgdGhlIEFOT1ZBIFN1bW1hcnkgVGFibGUNCnN1bW1hcnkoYW5vdmFfbW9kZWxfb25lX3dheSkNCmBgYA0KDQojIyMgVGhlIFZhcmlhYmlsaXR5IEJyZWFrZG93biAoU3VtIG9mIFNxdWFyZXMpDQoNCkFOT1ZBJ3Mgam9iIGlzIHRvIGZpZ3VyZSBvdXQgKip3aHkqKiB0aGUgdG9vdGggbGVuZ3RocyB2YXJ5LiBXZSBzcGxpdCB0aGUgdG90YWwgdmFyaWF0aW9uIGludG8gdHdvIHBpbGVzIG9mICJjcmVkaXQiOg0KDQp8IENvbXBvbmVudCB8IFN0YXRpc3RpY2FsIFRlcm0gfCBQbGFpbiBMYW5ndWFnZSBBbmFsb2d5IHwgUmVzdWx0IHwNCnwgOi0tLSB8IDotLS0gfCA6LS0tIHwgOi0tLSB8DQp8ICoqRGlmZmVyZW5jZXMgQkVUV0VFTiBHcm91cHMqKiB8ICRcdGV4dHtTdW0gU3F9JCBmb3IgJFx0ZXh0e2Rvc2V9JCAoMjQyNikgfCAqKlRoZSAiRG9zZSBFZmZlY3QiIENyZWRpdDoqKiBUaGUgdmFyaWF0aW9uIGluIHRvb3RoIGxlbmd0aCB0aGF0IGlzIGNsZWFybHkgZHVlIHRvIHRoZSBmYWN0IHRoYXQgd2UgY2hhbmdlZCB0aGUgZG9zZS4gVGhpcyBpcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBhdmVyYWdlIHRvb3RoIGxlbmd0aHMgb2YgdGhlIExvdywgTWVkaXVtLCBhbmQgSGlnaCBncm91cHMuIHwgMjQyNiB8DQp8ICoqRGlmZmVyZW5jZXMgV0lUSElOIEdyb3VwcyoqIHwgJFx0ZXh0e1N1bSBTcX0kIGZvciAkXHRleHR7UmVzaWR1YWxzfSQgKDEwMjYpIHwgKipUaGUgIlJhbmRvbSBMdWNrIiBDcmVkaXQgKEVycm9yKToqKiBUaGUgdmFyaWF0aW9uICp3aXRoaW4qIGEgc2luZ2xlIGdyb3VwIChlLmcuLCB3aHkgb25lIGd1aW5lYSBwaWcgb24gdGhlIExvdyBkb3NlIGhhcyBhIGxvbmdlciB0b290aCB0aGFuIGFub3RoZXIgZ3VpbmVhIHBpZyBvbiB0aGUgKnNhbWUqIExvdyBkb3NlKS4gVGhpcyBpcyB0aGUgdW5hdm9pZGFibGUgbmF0dXJhbCB2YXJpYXRpb24gb3IgIm5vaXNlLiIgfCAxMDI2IHwNCg0KIyMjIFRoZSBDb21wYXJpc29uIChUaGUgRi1UZXN0KQ0KDQpXZSB1c2UgdGhlICoqTWVhbiBTcXVhcmVzKiogKCRcdGV4dHtNZWFuIFNxfSQpIHRvIHR1cm4gdGhlICJwaWxlcyBvZiBjcmVkaXQiIGludG8gYW4gKiphdmVyYWdlIHZhcmlhbmNlKiogcGVyIG9ic2VydmF0aW9uLCBlc3NlbnRpYWxseSBjb250cm9sbGluZyBmb3Igc2FtcGxlIHNpemUuDQoNClRoZSAqKkYtc3RhdGlzdGljICg2Ny40MikqKiBpcyB0aGUgcmF0aW8gb2YgdGhlc2UgdHdvIHZhcmlhbmNlczoNCg0KJCRcbWF0aGJme0Z9ID0gXGZyYWN7XHRleHR7TWVhbiBTcX1fe1x0ZXh0e0Rvc2V9fX17XHRleHR7TWVhbiBTcX1fe1x0ZXh0e1Jlc2lkdWFsc319fSA9IFxmcmFje1x0ZXh0e1RoZSBWYXJpYW5jZSBleHBsYWluZWQgYnkgb3VyIGZhY3Rvcn19e1x0ZXh0e1RoZSBVbmV4cGxhaW5lZCBWYXJpYW5jZSAoRXJyb3IpfX0kJA0KDQoqICoqSWYgdGhlIE51bGwgSHlwb3RoZXNpcyBpcyBUUlVFIChEb3NlIGRvZXNuJ3QgbWF0dGVyKToqKiBUaGUgbnVtZXJhdG9yIChEb3NlIEVmZmVjdCkgc2hvdWxkIGJlIGFib3V0IHRoZSBzYW1lIHNpemUgYXMgdGhlIGRlbm9taW5hdG9yIChSYW5kb20gTHVjayksIHNvICRGIFxhcHByb3ggMSQuDQoqICoqSWYgdGhlIE51bGwgSHlwb3RoZXNpcyBpcyBGQUxTRSAoRG9zZSBET0VTIG1hdHRlcik6KiogVGhlIERvc2UgRWZmZWN0IGlzIG11Y2ggYmlnZ2VyIHRoYW4gUmFuZG9tIEx1Y2ssIHNvICRcbWF0aGJme0YgXGdnIDF9JC4NCg0KT3VyIEYtdmFsdWUgaXMgKio2Ny40MioqLiBUaGlzIGlzIGEgKipiaWcgbnVtYmVyKiosIHRlbGxpbmcgdXMgdGhhdCB0aGUgdmFyaWF0aW9uICpiZXR3ZWVuKiB0aGUgZG9zZSBncm91cHMgaXMgYWJvdXQgNjcgdGltZXMgbGFyZ2VyIHRoYW4gdGhlIHJhbmRvbSB2YXJpYXRpb24gKndpdGhpbiogdGhlIGdyb3Vwcy4gVGhpcyBzdHJvbmdseSBzdWdnZXN0cyB0aGUgZG9zZSBpcyBkb2luZyBzb21ldGhpbmchDQoNCiMjIyBUaGUgRmluYWwgVmVyZGljdCAoVGhlIFAtVmFsdWUpDQoNCiogKipQLVZhbHVlICgkXHRleHR7UHIoPkYpfSQpOioqICRcbWF0aGJmezkuNTNcdGV4dHtlLTE2fX0kIChvciAkMC4wMDAuLi4wOTUzJCkuDQoqICoqV2hhdCB0aGlzIFAtVmFsdWUgbWVhbnM6KiogVGhpcyBpcyB0aGUgcHJvYmFiaWxpdHkgb2YgZ2V0dGluZyBhbiBGLXJhdGlvIGFzIGhpZ2ggYXMgNjcuNDIgKmlmKiB0aGUgbnVsbCBoeXBvdGhlc2lzIHdlcmUgYWN0dWFsbHkgdHJ1ZSAoaS5lLiwgaWYgYWxsIGRvc2VzIHdlcmUgZXhhY3RseSB0aGUgc2FtZSkuDQoqIFNpbmNlIHRoaXMgcHJvYmFiaWxpdHkgaXMgKipleHRyZW1lbHkgdGlueSAobXVjaCBsZXNzIHRoYW4gMC4wNSkqKiwgd2UgY29uY2x1ZGUgdGhhdCB0aGUgcmVzdWx0cyB3ZSBvYnNlcnZlZCBhcmUgKipub3QqKiBkdWUgdG8gcmFuZG9tIGNoYW5jZS4NCg0KIyMjIyAqKkNvbmNsdXNpb246KioNCg0KV2UgKipyZWplY3QgdGhlIE51bGwgSHlwb3RoZXNpcyoqLiBUaGVyZSBpcyBjb21wZWxsaW5nIGV2aWRlbmNlIHRoYXQgKip0aGUgYXZlcmFnZSB0b290aCBsZW5ndGggaXMgc2lnbmlmaWNhbnRseSBhZmZlY3RlZCBieSB0aGUgZG9zZSBvZiBWaXRhbWluIEMqKi4gVGhlIGRvc2UgbGV2ZWwgZGVmaW5pdGVseSBtYXR0ZXJzIQ0KDQojIyBBc3N1bXB0aW9ucyBhbmQgRGlhZ25vc3RpY3MNCkFOT1ZBIHJlcXVpcmVzIHRocmVlIGtleSBhc3N1bXB0aW9uczoNCg0KMS4gSW5kZXBlbmRlbmNlLCANCg0KMi4gTm9ybWFsaXR5IG9mIFJlc2lkdWFscywgYW5kIA0KDQozLiBIb21vZ2VuZWl0eSBvZiBWYXJpYW5jZXMuDQoNCmBgYHtyfQ0KIyAtLS0gQ2hlY2tpbmcgTm9ybWFsaXR5IG9mIFJlc2lkdWFscyAtLS0NCiMgQSB2aXN1YWwgY2hlY2sgdXNpbmcgdGhlIFFRIHBsb3Qgb2YgdGhlIHJlc2lkdWFscw0KcGFyKG1mcm93ID0gYygxLCAyKSkgIyBTZXQgdXAgcGxvdHRpbmcgYXJlYQ0KcGxvdChhbm92YV9tb2RlbF9vbmVfd2F5LCB3aGljaCA9IDIpICMgUS1RIFBsb3Q6IFBvaW50cyBzaG91bGQgZmFsbCBhbG9uZyB0aGUgbGluZS4NCmBgYA0KDQojIyMgIExldmVuZSdzIFRlc3QgZm9yIEhvbW9nZW5laXR5IG9mIFZhcmlhbmNlDQoNCkJlZm9yZSB0cnVzdGluZyB0aGUgcC12YWx1ZSBmcm9tIHRoZSBBTk9WQSwgd2UgbXVzdCBjaGVjayBpdHMgYXNzdW1wdGlvbnMuIFRoZSBtb3N0IGNyaXRpY2FsIGFzc3VtcHRpb25zIGFyZSAqKm5vcm1hbGl0eSoqIChkYXRhIHdpdGhpbiBlYWNoIGdyb3VwIGZvbGxvd3MgYSBub3JtYWwgZGlzdHJpYnV0aW9uKSBhbmQgKipob21vZ2VuZWl0eSBvZiB2YXJpYW5jZSoqICh0aGUgdmFyaWFuY2UsIG9yIHNwcmVhZCwgb2YgdGhlIGRhdGEgaXMgcm91Z2hseSB0aGUgc2FtZSBhY3Jvc3MgYWxsIGdyb3VwcykuDQoNCkxldmVuZSdzIFRlc3QgaXMgdXNlZCBzcGVjaWZpY2FsbHkgdG8gY2hlY2sgdGhlICoqaG9tb2dlbmVpdHkgb2YgdmFyaWFuY2UqKiBhc3N1bXB0aW9uLg0KDQojIyMjIFRoZSBIeXBvdGhlc2VzIGZvciBMZXZlbmUncyBUZXN0DQoNCkxldmVuZSdzIFRlc3QgdXNlcyBhbiAkRiQtc3RhdGlzdGljLCBqdXN0IGxpa2UgQU5PVkEsIGJ1dCBpdHMgaHlwb3RoZXNlcyBhcmUgYWJvdXQgdGhlIHZhcmlhbmNlcyAoJFxzaWdtYV4yJCksIG5vdCB0aGUgbWVhbnMgKCRcbXUkKToNCg0KKiAqKk51bGwgSHlwb3RoZXNpcyAoJEhfMCQpOioqIEFsbCBwb3B1bGF0aW9uIHZhcmlhbmNlcyBhcmUgZXF1YWwuDQogICAgJCRcbWF0aGJme0hfMH06IFxzaWdtYV4yX3swLjV9ID0gXHNpZ21hXjJfezEuMH0gPSBcc2lnbWFeMl97Mi4wfSQkDQogICAgKEluIHBsYWluIGxhbmd1YWdlOiBUaGUgc3ByZWFkIG9mIHRvb3RoIGxlbmd0aCBkYXRhIGlzIHRoZSAqKnNhbWUqKiBmb3IgYWxsIHRocmVlIGRvc2UgZ3JvdXBzLikNCiogKipBbHRlcm5hdGl2ZSBIeXBvdGhlc2lzICgkSF9hJCk6KiogQXQgbGVhc3Qgb25lIHBvcHVsYXRpb24gdmFyaWFuY2UgaXMgZGlmZmVyZW50Lg0KICAgICQkXG1hdGhiZntIX2F9OiBcdGV4dHtOb3QgYWxsIH0gXHNpZ21hXjIgXHRleHR7J3MgYXJlIGVxdWFsLn0kJA0KICAgIChJbiBwbGFpbiBsYW5ndWFnZTogVGhlIHNwcmVhZCBvZiB0b290aCBsZW5ndGggZGF0YSBpcyAqKmRpZmZlcmVudCoqIGZvciBhdCBsZWFzdCBvbmUgZG9zZSBncm91cC4pDQoNCkluIGNvbnRyYXN0IHRvIHRoZSBBTk9WQSwgd2UgYWN0dWFsbHkgKip3YW50IHRvIEZBSUwgdG8gcmVqZWN0ICRIXzAkKiogZm9yIExldmVuZSdzIHRlc3QuIFJlamVjdGluZyAkSF8wJCBtZWFucyB0aGUgYXNzdW1wdGlvbiBpcyB2aW9sYXRlZCwgYW5kIG91ciBBTk9WQSByZXN1bHRzIG1pZ2h0IGJlIHVucmVsaWFibGUuDQoNCmBgYHtyfQ0KIyAtLS0gQ2hlY2tpbmcgSG9tb2dlbmVpdHkgb2YgVmFyaWFuY2UgLS0tDQojIEZvcm1hbCBUZXN0IGZvciBIb21vZ2VuZWl0eTogTGV2ZW5lJ3MgVGVzdCAodXNlICdjYXInIHBhY2thZ2UpDQpsaWJyYXJ5KGNhcikNCmxldmVuZVRlc3QobGVuIH4gZG9zZSwgZGF0YSA9IFRvb3RoR3Jvd3RoKQ0KDQojIEgwIGZvciBMZXZlbmUncyB0ZXN0OiBWYXJpYW5jZXMgYXJlIGVxdWFsLg0KIyBBIG5vbi1zaWduaWZpY2FudCBwLXZhbHVlIChwID4gMC4wNSkgbWVhbnMgd2UgRE8gTk9UIHJlamVjdCBIMCwNCiMgc3VwcG9ydGluZyB0aGUgYXNzdW1wdGlvbiBvZiBob21vZ2VuZWl0eS4NCmBgYA0KIyMjIyBJbnRlcnByZXRpbmcgdGhlIE91dHB1dA0KDQp8IFNvdXJjZSB8ICRcdGV4dHtEZn0kIHwgJFx0ZXh0e0YgdmFsdWV9JCB8ICRcdGV4dHtQcig+Ril9JCB8DQp8IDotLS0gfCA6LS0tIHwgOi0tLSB8IDotLS0gfA0KfCAkXHRleHR7Z3JvdXB9JCB8IDIgfCAwLjY0NTcgfCAwLjUyODEgfA0KfCB8IDU3IHwgfCB8DQoNCiogKipEZWdyZWVzIG9mIEZyZWVkb20gKCRcdGV4dHtEZn0kKToqKg0KICAgICogKiokXHRleHR7Z3JvdXB9JCAoMik6KiogRGVncmVlcyBvZiBmcmVlZG9tIGZvciB0aGUgbnVtZXJhdG9yIChudW1iZXIgb2YgZ3JvdXBzIG1pbnVzIDEpLg0KICAgICogKio1NzoqKiBEZWdyZWVzIG9mIGZyZWVkb20gZm9yIHRoZSBkZW5vbWluYXRvciAodG90YWwgb2JzZXJ2YXRpb25zIG1pbnVzIG51bWJlciBvZiBncm91cHMpLg0KDQoqICoqRi1WYWx1ZSAoJFxtYXRoYmZ7MC42NDU3fSQpOioqIFRoaXMgaXMgdGhlIHRlc3Qgc3RhdGlzdGljIGZvciBMZXZlbmUncyB0ZXN0Lg0KDQoqICoqUC1WYWx1ZSAoJFx0ZXh0e1ByKD5GKX0kKToqKiAkXG1hdGhiZnswLjUyODF9JC4gVGhpcyBpcyB0aGUgcHJvYmFiaWxpdHkgb2Ygb2JzZXJ2aW5nIGFuICRGJC1zdGF0aXN0aWMgdGhpcyBsYXJnZSAob3IgbGFyZ2VyKSBpZiB0aGUgdmFyaWFuY2VzIHdlcmUgdHJ1bHkgZXF1YWwuDQoNCiMjIyMgQ29uY2x1c2lvbiBvbiBIb21vZ2VuZWl0eSBvZiBWYXJpYW5jZQ0KDQpUbyBtYWtlIGEgZGVjaXNpb24sIHdlIGNvbXBhcmUgdGhlIHAtdmFsdWUgKCRcbWF0aGJmezAuNTI4MX0kKSB0byBvdXIgc2lnbmlmaWNhbmNlIGxldmVsLCAkXGFscGhhID0gMC4wNSQuDQoNCiogU2luY2UgdGhlIHAtdmFsdWUgKCQwLjUyODEkKSBpcyAqKmdyZWF0ZXIgdGhhbioqICRcYWxwaGEgPSAwLjA1JCwgd2UgKipGQUlMIHRvIHJlamVjdCB0aGUgTnVsbCBIeXBvdGhlc2lzICgkXG1hdGhiZntIXzB9JCkgb2YgZXF1YWwgdmFyaWFuY2VzLioqDQoNCioqV2hhdCB0aGlzIG1lYW5zOioqIFdlIGRvIG5vdCBoYXZlIHN1ZmZpY2llbnQgc3RhdGlzdGljYWwgZXZpZGVuY2UgdG8gY29uY2x1ZGUgdGhhdCB0aGUgdmFyaWFuY2UgKHNwcmVhZCkgaW4gdG9vdGggbGVuZ3RoIGlzIGRpZmZlcmVudCBhY3Jvc3MgdGhlIHRocmVlIGRvc2UgZ3JvdXBzLg0KDQoqKkZpbmFsIEFzc2Vzc21lbnQgb2YgdGhlIEFOT1ZBIE1vZGVsOioqDQoNCkJlY2F1c2Ugd2UgKipmYWlsZWQgdG8gcmVqZWN0ICRIXzAkKiogaW4gTGV2ZW5lJ3MgdGVzdCwgd2UgY2FuIGNvbmNsdWRlIHRoYXQgdGhlICoqaG9tb2dlbmVpdHkgb2YgdmFyaWFuY2UgYXNzdW1wdGlvbiBpcyBtZXQqKi4gVGhlcmVmb3JlLCB0aGUgJEYkLXRlc3QgYW5kIHAtdmFsdWUgb2J0YWluZWQgZnJvbSB5b3VyIGluaXRpYWwgb25lLXdheSBBTk9WQSAod2hpY2ggZm91bmQgYSBzaWduaWZpY2FudCBlZmZlY3Qgb2YgZG9zZSkgYXJlIHJlbGlhYmxlLiANCg0KKiooU2VsZi1Db3JyZWN0aW9uL05leHQgU3RlcCk6KiogSWYgdGhpcyB0ZXN0ICpoYWQqIGJlZW4gc2lnbmlmaWNhbnQgKCRwIDwgMC4wNSQpLCB5b3Ugd291bGQgbmVlZCBhbiBhbHRlcm5hdGl2ZSByb2J1c3QgQU5PVkEgbWV0aG9kcywgbGlrZSBbKipXZWxjaCdzIEFOT1ZBKipdKGh0dHBzOi8vd3d3LnN0YXRvbG9neS5vcmcvd2VsY2hzLWFub3ZhLWluLXIvKSwgd2hpY2ggZG9lcyBub3QgcmVxdWlyZSB0aGUgYXNzdW1wdGlvbiBvZiBlcXVhbCB2YXJpYW5jZXMgb3IgdGhlIFtLcnVza2FsLVdhbGxpc10oaHR0cHM6Ly93d3cuc3RoZGEuY29tL2VuZ2xpc2gvd2lraS9rcnVza2FsLXdhbGxpcy10ZXN0LWluLXIpIHRlc3QsIHdoaWNoIHJlcXVpcmVzIG5vIGRpc3RyaWJ1dGlvbmFsIGFzc3VtcHRpb25zLg0KDQojIyBQb3N0LUhvYyBBbmFseXNpcyAoVGhlIEZvbGxvdy11cCkNCg0KSWYgdGhlIG92ZXJhbGwgQU5PVkEgJEYkLXRlc3QgaXMgc2lnbmlmaWNhbnQsIHdlIHVzZSBwb3N0LWhvYyB0ZXN0cyB0byBmaW5kIHdoaWNoIHNwZWNpZmljIHBhaXJzIGRpZmZlciwgY29udHJvbGxpbmcgdGhlIEZhbWlseS1XaXNlIEVycm9yIFJhdGUgKEZXRVIpLg0KDQpPdXIgRi10ZXN0IHRvbGQgdXMgKioiU29tZXRoaW5nIGlzIGRpZmZlcmVudC4iKiogSXQgZGlkbid0IHRlbGwgdXMgKioiV2hpY2ggc3BlY2lmaWMgZG9zZSBsZXZlbHMgYXJlIGRpZmZlcmVudCBmcm9tIGVhY2ggb3RoZXIuIioqDQoNClRvIGFuc3dlciB0aGF0LCB5b3UgbmVlZCB0byBydW4gKipQb3N0LUhvYyBUZXN0cyoqIChsaWtlIFR1a2V5J3MgSFNEKSB0byBwZXJmb3JtIG11bHRpcGxlIGhlYWQtdG8taGVhZCBjb21wYXJpc29uczoNCiogRG9lcyAkMC41XHRleHR7IG1nfSQgZGlmZmVyIGZyb20gJDEuMFx0ZXh0eyBtZ30kPw0KKiBEb2VzICQxLjBcdGV4dHsgbWd9JCBkaWZmZXIgZnJvbSAkMi4wXHRleHR7IG1nfSQ/DQoqIERvZXMgJDAuNVx0ZXh0eyBtZ30kIGRpZmZlciBmcm9tICQyLjBcdGV4dHsgbWd9JD8NCg0KYGBge3J9DQojIElmIHRoZSBGLXRlc3Qgd2FzIHNpZ25pZmljYW50IChlLmcuLCBwIDwgMC4wNSksIHJ1biBUdWtleSdzIEhTRC4NCnR1a2V5X3Jlc3VsdHNfb25lX3dheSA8LSBUdWtleUhTRChhbm92YV9tb2RlbF9vbmVfd2F5KQ0KDQojIFByaW50IHRoZSByZXN1bHRzDQpwcmludCh0dWtleV9yZXN1bHRzX29uZV93YXkpDQpgYGANCg0KVGhlIEFOT1ZBIHRvbGQgdXMsICJZZXMsIHRoZSBkb3NlIG1hdHRlcnMuIiBUdWtleSdzIEhTRCB0ZXN0IGFuc3dlcnMgdGhlIHF1ZXN0aW9uLCAqKiJTcGVjaWZpY2FsbHksIHdoaWNoIGRvc2VzIGFyZSBkaWZmZXJlbnQgZnJvbSBlYWNoIG90aGVyPyIqKg0KDQpUdWtleSdzIHRlc3QgcGVyZm9ybXMgYWxsIHBvc3NpYmxlICpwYWlyd2lzZSBjb21wYXJpc29ucyogKGdyb3VwIEEgdnMuIGdyb3VwIEIsIGdyb3VwIEEgdnMuIGdyb3VwIEMsIGFuZCBncm91cCBCIHZzLiBncm91cCBDKSB3aGlsZSBjb250cm9sbGluZyB0aGUgKipGYW1pbHktV2lzZSBFcnJvciBSYXRlKiogKEZXRVIpLiBUaGlzIG1lYW5zIHRoZSBvdmVyYWxsIDk1JSBjb25maWRlbmNlIGxldmVsIGFwcGxpZXMgdG8gdGhlIGVudGlyZSBzZXQgb2YgdGhyZWUgY29tcGFyaXNvbnMsIG5vdCBqdXN0IHRvIGVhY2ggaW5kaXZpZHVhbCBvbmUuDQoNCiMjIyBVbmRlcnN0YW5kaW5nIHRoZSBPdXRwdXQgU3RydWN0dXJlDQoNCnwgQ29tcGFyaXNvbiB8ICRcdGV4dHtkaWZmfSQgKE1lYW4gRGlmZmVyZW5jZSkgfCAkXHRleHR7bHdyfSQgKExvd2VyIDk1JSBDSSkgfCAkXHRleHR7dXByfSQgKFVwcGVyIDk1JSBDSSkgfCAkXHRleHR7cCBhZGp9JCAoQWRqdXN0ZWQgUC1WYWx1ZSkgfA0KfCA6LS0tIHwgOi0tLSB8IDotLS0gfCA6LS0tIHwgOi0tLSB8DQp8ICRcbWF0aGJmezEgLSAwLjV9JCB8ICQ5LjEzMCQgfCAkNS45MDE4MDUkIHwgJDEyLjM1ODE5NSQgfCAkMC4wMFx0ZXh0e2V9KzAwJCB8DQp8ICRcbWF0aGJmezIgLSAwLjV9JCB8ICQxNS40OTUkIHwgJDEyLjI2NjgwNSQgfCAkMTguNzIzMTk1JCB8ICQwLjAwXHRleHR7ZX0rMDAkIHwNCnwgJFxtYXRoYmZ7MiAtIDF9JCB8ICQ2LjM2NSQgfCAkMy4xMzY4MDUkIHwgJDkuNTkzMTk1JCB8ICQ0LjI1XHRleHR7ZX0tMDUkIHwNCg0KVGhlIGNvbHVtbnMgc2hvdyB0aGUgcmVzdWx0IGZvciB0aGUgdGhyZWUgY29tcGFyaXNvbnMgYmV0d2VlbiB0aGUgZG9zZSBsZXZlbHMgKDAuNSwgMSwgYW5kIDIgbWcvZGF5KS4NCg0KIyMjIEFuYWx5c2lzIG9mIEVhY2ggQ29tcGFyaXNvbg0KDQpXZSBsb29rIGF0IHR3byB0aGluZ3MgZm9yIGVhY2ggcm93Og0KMS4gICoqRG9lcyB0aGUgOTUlIENvbmZpZGVuY2UgSW50ZXJ2YWwgKENJKSBjb250YWluIHplcm8/KiogSWYgdGhlIGludGVydmFsICgkXHRleHR7bHdyfSQgdG8gJFx0ZXh0e3Vwcn0kKSAqKmRvZXMgbm90KiogY29udGFpbiB6ZXJvLCB0aGUgZGlmZmVyZW5jZSBpcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50Lg0KMi4gICoqSXMgdGhlIEFkanVzdGVkIFAtdmFsdWUgKCRcdGV4dHtwIGFkan0kKSBsZXNzIHRoYW4gJFxhbHBoYSA9IDAuMDUkPyoqIElmIHllcywgdGhlIGRpZmZlcmVuY2UgaXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4NCg0KIyMjIyAqKkNvbXBhcmlzb24gMTogRG9zZSAxLjAgdnMuIERvc2UgMC41ICgxIC0gMC41KSoqDQoNCiogKipEaWZmZXJlbmNlICgkXHRleHR7ZGlmZn0kKToqKiAkOS4xMzAkLiBUaGUgYXZlcmFnZSB0b290aCBsZW5ndGggYXQgJDEuMFx0ZXh0eyBtZ30kIGRvc2UgaXMgJDkuMTNcdGV4dHsgdW5pdHN9JCAqbG9uZ2VyKiB0aGFuIGF0IHRoZSAkMC41XHRleHR7IG1nfSQgZG9zZS4NCiogKio5NSUgQ0k6KiogJFs1LjkwLCAxMi4zNl0kLiBUaGlzIGVudGlyZSBpbnRlcnZhbCBpcyAqKnBvc2l0aXZlKiogKGl0IGRvZXMgbm90IGNvbnRhaW4gemVybykuDQoqICoqUC1WYWx1ZSAoJFx0ZXh0e3AgYWRqfSQpOioqICQwLjAwXHRleHR7ZX0rMDAkIChleHRyZW1lbHkgc21hbGwpLg0KKiAqKkNvbmNsdXNpb246KiogVGhlIGRpZmZlcmVuY2UgYmV0d2VlbiAkMS4wXHRleHR7IG1nfSQgYW5kICQwLjVcdGV4dHsgbWd9JCBpcyAqKmhpZ2hseSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50KiouDQoNCiMjIyMgKipDb21wYXJpc29uIDI6IERvc2UgMi4wIHZzLiBEb3NlIDAuNSAoMiAtIDAuNSkqKg0KDQoqICoqRGlmZmVyZW5jZSAoJFx0ZXh0e2RpZmZ9JCk6KiogJDE1LjQ5NSQuIFRoZSBhdmVyYWdlIHRvb3RoIGxlbmd0aCBhdCAkMi4wXHRleHR7IG1nfSQgZG9zZSBpcyAkMTUuNVx0ZXh0eyB1bml0c30kICpsb25nZXIqIHRoYW4gYXQgdGhlICQwLjVcdGV4dHsgbWd9JCBkb3NlLg0KKiAqKjk1JSBDSToqKiAkWzEyLjI3LCAxOC43Ml0kLiBUaGlzIGludGVydmFsIGlzIGFsc28gKipmdWxseSBwb3NpdGl2ZSoqIChkb2VzIG5vdCBjb250YWluIHplcm8pLg0KKiAqKlAtVmFsdWUgKCRcdGV4dHtwIGFkan0kKToqKiAkMC4wMFx0ZXh0e2V9KzAwJCAoZXh0cmVtZWx5IHNtYWxsKS4NCiogKipDb25jbHVzaW9uOioqIFRoZSBkaWZmZXJlbmNlIGJldHdlZW4gJDIuMFx0ZXh0eyBtZ30kIGFuZCAkMC41XHRleHR7IG1nfSQgaXMgKipoaWdobHkgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCoqLg0KDQojIyMjICoqQ29tcGFyaXNvbiAzOiBEb3NlIDIuMCB2cy4gRG9zZSAxLjAgKDIgLSAxKSoqDQoNCiogKipEaWZmZXJlbmNlICgkXHRleHR7ZGlmZn0kKToqKiAkNi4zNjUkLiBUaGUgYXZlcmFnZSB0b290aCBsZW5ndGggYXQgJDIuMFx0ZXh0eyBtZ30kIGRvc2UgaXMgJDYuMzY1XHRleHR7IHVuaXRzfSQgKmxvbmdlciogdGhhbiBhdCB0aGUgJDEuMFx0ZXh0eyBtZ30kIGRvc2UuDQoqICoqOTUlIENJOioqICRbMy4xNCwgOS41OV0kLiBUaGlzIGludGVydmFsIGlzIGFsc28gKipmdWxseSBwb3NpdGl2ZSoqIChkb2VzIG5vdCBjb250YWluIHplcm8pLg0KKiAqKlAtVmFsdWUgKCRcdGV4dHtwIGFkan0kKToqKiAkNC4yNVx0ZXh0e2V9LTA1JCwgd2hpY2ggaXMgJDAuMDAwMDQyNSQuIFRoaXMgaXMgbXVjaCBzbWFsbGVyIHRoYW4gJDAuMDUkLg0KKiAqKkNvbmNsdXNpb246KiogVGhlIGRpZmZlcmVuY2UgYmV0d2VlbiAkMi4wXHRleHR7IG1nfSQgYW5kICQxLjBcdGV4dHsgbWd9JCBpcyAqKnN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQqKi4NCg0KKioqDQoNCiMjIyBTdW1tYXJ5IG9mIEZpbmRpbmdzDQoNCkJhc2VkIG9uIHRoZSBUdWtleSBIU0QgdGVzdCwgd2UgZmluZCB0aGF0ICoqYWxsIHRocmVlIHBhaXJ3aXNlIGNvbXBhcmlzb25zIGFyZSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50KiouIFRoaXMgbWVhbnMgdGhhdCBpbmNyZWFzaW5nIHRoZSBkb3NlIGZyb20gb25lIGxldmVsIHRvIHRoZSBuZXh0IChsb3cgdG8gbWVkaXVtLCBtZWRpdW0gdG8gaGlnaCwgYW5kIGxvdyB0byBoaWdoKSByZXN1bHRlZCBpbiBhIG1lYXN1cmFibGUsIG5vbi1yYW5kb20gaW5jcmVhc2UgaW4gYXZlcmFnZSB0b290aCBsZW5ndGguDQoNCiogJFxtYXRoYmZ7MC41XHRleHR7IG1nfX0kIGlzIHNpZ25pZmljYW50bHkgZGlmZmVyZW50IGZyb20gJFxtYXRoYmZ7MS4wXHRleHR7IG1nfX0kLg0KKiAkXG1hdGhiZnswLjVcdGV4dHsgbWd9fSQgaXMgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnQgZnJvbSAkXG1hdGhiZnsyLjBcdGV4dHsgbWd9fSQuDQoqICRcbWF0aGJmezEuMFx0ZXh0eyBtZ319JCBpcyBzaWduaWZpY2FudGx5IGRpZmZlcmVudCBmcm9tICRcbWF0aGJmezIuMFx0ZXh0eyBtZ319JC4NCg0KSW4gYSByZXNlYXJjaCBjb250ZXh0LCB5b3Ugd291bGQgcmVwb3J0IHRoaXMgYnkgc3RhdGluZyB0aGF0IGluY3JlYXNpbmcgdGhlIFZpdGFtaW4gQyBkb3NlIGxlYWRzIHRvIGEgKipkb3NlLWRlcGVuZGVudCBpbmNyZWFzZSoqIGluIHRvb3RoIGdyb3d0aCwgYW5kIHRoYXQgdGhlIGVmZmVjdCBvYnNlcnZlZCBhdCBlYWNoIGRvc2UgbGV2ZWwgaXMgZGlzdGluY3QgZnJvbSB0aGUgb3RoZXJzLg0KDQojIyBWaXN1YWxpemUgdGhlIHBvc3QtaG9jIHJlc3VsdHMgDQoNCmBgYHtyfQ0KcGxvdCh0dWtleV9yZXN1bHRzX29uZV93YXkpDQpgYGANCg0KIyMgU3VtbWFyeSBvZiBPbmUtV2F5IEFOT1ZBDQp8IFN0ZXAgICAgICAgIHwgUiBGdW5jdGlvbihzKSAgICAgICAgICAgICAgICAgICAgICAgfCBQdXJwb3NlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfC0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwNCnwgKipNb2RlbCBGaXQqKiAgIHwgYGFub3ZhX21vZGVsIDwtIGFvdihZIH4gWCwgZGF0YT0uLi4pYCB8IFBhcnRpdGlvbnMgdmFyaWFuY2UuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8DQp8ICoqR2xvYmFsIFRlc3QqKiB8IGBzdW1tYXJ5KGFub3ZhX21vZGVsKWAgICAgICAgICAgICAgICAgfCBDaGVja3MgaWYgJEhfMDogXG11XzE9XGRvdHM9XG11X2skIGlzIHJlamVjdGVkIHZpYSB0aGUgRi1yYXRpby4gICAgICAgICAgICAgICAgICAgfA0KfCAqKkFzc3VtcHRpb25zKiogfCBgcGxvdChhbm92YV9tb2RlbCkgLyBsZXZlbmVUZXN0KClgICAgIHwgQ29uZmlybXMgTm9ybWFsaXR5IGFuZCBIb21vZ2VuZWl0eSBvZiBWYXJpYW5jZS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwNCnwgKipQb3N0LUhvYyoqICAgIHwgYFR1a2V5SFNEKGFub3ZhX21vZGVsKWAgICAgICAgICAgICAgICB8IElkZW50aWZpZXMgc3BlY2lmaWMgcGFpcndpc2UgbWVhbiBkaWZmZXJlbmNlcyBpZiB0aGUgR2xvYmFsIFRlc3Qgd2FzIHNpZ25pZmljYW50LiB8DQoNCiMgRXh0ZW5kaW5nIHRoZSBNb2RlbDogVHdvLVdheSBBTk9WQQ0KDQpUd28tV2F5IEFOT1ZBIGlzIHVzZWQgd2hlbiB5b3UgaGF2ZSB0d28gaW5kZXBlbmRlbnQgY2F0ZWdvcmljYWwgZmFjdG9ycyBpbmZsdWVuY2luZyBvbmUgY29udGludW91cyBvdXRjb21lIHZhcmlhYmxlLiBPdXIgVG9vdGhHcm93dGggZGF0YXNldCBoYXMgYSBzZWNvbmQgZmFjdG9yOiAgDQoNCiAtIF9fRmFjdG9yIDE6X18gYGRvc2VgICgwLjUsIDEuMCwgMi4wIG1nL2RheSkNCiAtIF9fRmFjdG9yIDI6X18gYHN1cHBgIChTdXBwbGVtZW50IHR5cGU6IE9yYW5nZSBKdWljZSBbT0pdIHZzLiBBc2NvcmJpYyBBY2lkIFtWQ10pDQoNClR3by1XYXkgQU5PVkEgYWxsb3dzIHVzIHRvIHRlc3QgdGhyZWUgc2VwYXJhdGUgbnVsbCBoeXBvdGhlc2VzOg0KIC0gX19NYWluIEVmZmVjdCBvZiBGYWN0b3IgMTpfXyAkSF8wOiBcbXVfe1x0ZXh0e2Rvc2V9X3swLjV9fSA9IFxtdV97XHRleHR7ZG9zZX1fezEuMH19ID0gXG11X3tcdGV4dHtkb3NlfV97Mi4wfX0kIChBdmVyYWdlZCBhY3Jvc3Mgc3VwcGxlbWVudCB0eXBlcykuDQogDQogLSBfX01haW4gRWZmZWN0IG9mIEZhY3RvciAyOl9fICRIXzA6IFxtdV97XHRleHR7T0p9fSA9IFxtdV97XHRleHR7VkN9fSQgKEF2ZXJhZ2VkIGFjcm9zcyBkb3NlIGxldmVscykuDQpJbnRlcmFjdGlvbiBFZmZlY3QgKEZhY3RvciAxICRcdGltZXMkIEZhY3RvciAyKTogJEhfMCQ6IFRoZSBlZmZlY3Qgb2YgZG9zZSBpcyB0aGUgc2FtZSBhY3Jvc3MgYm90aCBsZXZlbHMgb2Ygc3VwcC4NCg0KIyMgTW9kZWwgMTogQWRkaXRpdmUgRWZmZWN0cyAoTm8gSW50ZXJhY3Rpb24pDQpUaGlzIG1vZGVsIGFzc3VtZXMgdGhlIGVmZmVjdCBvZiBgZG9zZWAgaXMgY29uc3RhbnQgcmVnYXJkbGVzcyBvZiBgc3VwcGAsIGFuZCB2aWNlIHZlcnNhLiBJdCBpcyBzcGVjaWZpZWQgdXNpbmcgdGhlIGArYCBvcGVyYXRvci4NCg0KYGBge3J9DQojIE5vdGU6ICdzdXBwJyBpcyBhbHJlYWR5IGEgZmFjdG9yIGluIHRoZSBvcmlnaW5hbCBkYXRhc2V0DQphbm92YV9tb2RlbF9hZGRpdGl2ZSA8LSBhb3YobGVuIH4gZG9zZSArIHN1cHAsIGRhdGEgPSBUb290aEdyb3d0aCkNCg0KIyBWaWV3IHRoZSBBTk9WQSBTdW1tYXJ5IFRhYmxlDQpzdW1tYXJ5KGFub3ZhX21vZGVsX2FkZGl0aXZlKQ0KYGBgDQoNCiMjIyBUaGUgSHlwb3RoZXNlcw0KDQpGb3IgdGhpcyBUd28tV2F5IEFOT1ZBLCB3ZSB0ZXN0ICoqdHdvKiogc2VwYXJhdGUgTnVsbCBIeXBvdGhlc2VzOg0KDQp8IFNvdXJjZSB8IE51bGwgSHlwb3RoZXNpcyAoJEhfMCQpIHwNCnwgOi0tLSB8IDotLS0gfA0KfCAqKkRvc2UqKiAoJFx0ZXh0e2Rvc2V9JCkgfCBUaGUgbWVhbiB0b290aCBsZW5ndGggaXMgdGhlICoqc2FtZSoqIGFjcm9zcyBhbGwgZG9zZSBsZXZlbHMgKDAuNSwgMS4wLCAyLjApLiB8DQp8ICoqU3VwcGxlbWVudCoqICgkXHRleHR7c3VwcH0kKSB8IFRoZSBtZWFuIHRvb3RoIGxlbmd0aCBpcyB0aGUgKipzYW1lKiogZm9yIGJvdGggc3VwcGxlbWVudCB0eXBlcyAoT0ogYW5kIFZDKS4gfA0KDQojIyMjIEludGVycHJldGluZyB0aGUgU3VtbWFyeSBUYWJsZSAoTWFpbiBFZmZlY3RzKQ0KDQpUaGUgdGFibGUgYnJlYWtzIGRvd24gdGhlIHRvdGFsIHZhcmlhYmlsaXR5IGludG8gdGhlIHZhcmlhbmNlIGV4cGxhaW5lZCBieSBlYWNoIGZhY3RvciBhbmQgdGhlIHJlbWFpbmluZyB1bmV4cGxhaW5lZCBlcnJvciAoJFx0ZXh0e1Jlc2lkdWFsc30kKS4NCg0KfCBTb3VyY2UgfCBEZiB8IFN1bSBTcSB8IE1lYW4gU3EgfCBGIHZhbHVlIHwgJFx0ZXh0e1ByKD5GKX0kIHwNCnwgOi0tLSB8IDotLS0gfCA6LS0tIHwgOi0tLSB8IDotLS0gfCA6LS0tIHwNCnwgJFx0ZXh0e2Rvc2V9JCB8IDIgfCAyNDI2LjQgfCAxMjEzLjIgfCA4Mi44MSB8ICQ8IDJcdGV4dHtlLTE2fSQgfA0KfCAkXHRleHR7c3VwcH0kIHwgMSB8IDIwNS4zIHwgMjA1LjMgfCAxNC4wMiB8ICQwLjAwMDQyOSQgfA0KfCAkXHRleHR7UmVzaWR1YWxzfSQgfCA1NiB8IDgyMC40IHwgMTQuNyB8IHwgfA0KDQojIyMjIFRoZSBFZmZlY3Qgb2YgRG9zZQ0KDQoqICoqUC1WYWx1ZSAoJFx0ZXh0e1ByKD5GKX0kKToqKiAkPCAyXHRleHR7ZS0xNn0kLiBUaGlzIGlzIGFuIGV4dHJlbWVseSBzbWFsbCBudW1iZXIsIGZhciBiZWxvdyAkXGFscGhhID0gMC4wNSQuDQoqICoqRi1WYWx1ZToqKiAkODIuODEkLiBUaGlzIGlzIHRoZSByYXRpbyBvZiB0aGUgdmFyaWFuY2UgZXhwbGFpbmVkIGJ5ICRcdGV4dHtkb3NlfSQgdG8gdGhlIHVuZXhwbGFpbmVkIGVycm9yLiBJdCBpcyB2ZXJ5IGxhcmdlLg0KKiAqKkNvbmNsdXNpb246KiogV2UgKipyZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyoqIGZvciAkXHRleHR7ZG9zZX0kLiBUaGVyZSBpcyBhICoqaGlnaGx5IHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQqKiBlZmZlY3Qgb2YgdGhlIFZpdGFtaW4gQyAqKmRvc2UgbGV2ZWwqKiBvbiBtZWFuIHRvb3RoIGxlbmd0aCAoJEYoMiwgNTYpID0gODIuODEsIHAgPCAwLjAwMSQpLg0KKiAqKihOZXh0IFN0ZXApOioqIFNpbmNlIHRoZSAkXHRleHR7ZG9zZX0kIGZhY3RvciBoYXMgbW9yZSB0aGFuIHR3byBsZXZlbHMsIHlvdSB3b3VsZCBuZWVkIHRvIHJ1biAqKlR1a2V5J3MgSFNEKiogKHBvc3QtaG9jIHRlc3QpIHRvIHNlZSB3aGljaCBzcGVjaWZpYyBkb3NlIGxldmVscyBkaWZmZXIgKDAuNSB2cyAxLjAsIDEuMCB2cyAyLjAsIGV0Yy4pLg0KDQojIyMjIFRoZSBFZmZlY3Qgb2YgU3VwcGxlbWVudCBUeXBlDQoNCiogKipQLVZhbHVlICgkXHRleHR7UHIoPkYpfSQpOioqICQwLjAwMDQyOSQuIFRoaXMgaXMgYWxzbyBmYXIgYmVsb3cgJFxhbHBoYSA9IDAuMDUkLg0KKiAqKkYtVmFsdWU6KiogJDE0LjAyJC4NCiogKipDb25jbHVzaW9uOioqIFdlICoqcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMqKiBmb3IgJFx0ZXh0e3N1cHB9JC4gVGhlcmUgaXMgYSAqKmhpZ2hseSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50KiogZWZmZWN0IG9mIHRoZSAqKnN1cHBsZW1lbnQgdHlwZSoqIChPSiB2cy4gVkMpIG9uIG1lYW4gdG9vdGggbGVuZ3RoICgkRigxLCA1NikgPSAxNC4wMiwgcCA8IDAuMDAxJCkuDQoqICoqKEludGVycHJldGF0aW9uKToqKiBTaW5jZSAkXHRleHR7c3VwcH0kIG9ubHkgaGFzIHR3byBsZXZlbHMsIHRoaXMgc2lnbmlmaWNhbnQgcmVzdWx0IGltbWVkaWF0ZWx5IHRlbGxzIHVzIHRoYXQgdGhlIG1lYW4gdG9vdGggbGVuZ3RoIGZvciBvbmUgc3VwcGxlbWVudCB0eXBlICh3ZSBkb24ndCBrbm93IHdoaWNoIG9uZSB5ZXQsIGJ1dCBsaWtlbHkgT3JhbmdlIEp1aWNlKSBpcyBzaWduaWZpY2FudGx5IGRpZmZlcmVudCBmcm9tIHRoZSBvdGhlciAoQXNjb3JiaWMgQWNpZCkuICoqTm8gcG9zdC1ob2MgdGVzdCBpcyBuZWVkZWQuKioNCg0KIyMjIyBUaGUgUmVzaWR1YWxzIChFcnJvcikNCg0KKiAqKiRcdGV4dHtEZn0gPSA1NiQ6KiogVGhpcyBpcyB0aGUgZGVncmVlcyBvZiBmcmVlZG9tIGZvciB0aGUgZXJyb3IgdGVybSwgdXNlZCBpbiBjYWxjdWxhdGluZyB0aGUgcC12YWx1ZXMuDQoqICoqJFx0ZXh0e01lYW4gU3F9ID0gMTQuNyQ6KiogVGhpcyBpcyB0aGUgKipNZWFuIFNxdWFyZSBFcnJvciAoJFx0ZXh0e01TRX0kKSoqLiBJdCBpcyBvdXIgYmVzdCBlc3RpbWF0ZSBvZiB0aGUgcG9wdWxhdGlvbiB2YXJpYW5jZSAoJFxzaWdtYV4yJCkgdGhhdCBpcyAqKm5vdCoqIGV4cGxhaW5lZCBieSBlaXRoZXIgJFx0ZXh0e2Rvc2V9JCBvciAkXHRleHR7c3VwcH0kLiBUaGlzIHZhbHVlICgxNC43KSBpcyB0aGUgZGVub21pbmF0b3IgdXNlZCB0byBjYWxjdWxhdGUgYm90aCAkRiQtdmFsdWVzOg0KICAgICQkXHRleHR7Rn1fe1x0ZXh0e2Rvc2V9fSA9IFxmcmFjezEyMTMuMn17MTQuN30gXGFwcHJveCA4Mi44MSQkICAgJCRcdGV4dHtGfV97XHRleHR7c3VwcH19ID0gXGZyYWN7MjA1LjN9ezE0Ljd9IFxhcHByb3ggMTQuMDIkJA0KDQoNCg0KIyMjIFN1bW1hcnkgaW4gUGxhaW4gTGFuZ3VhZ2UNCg0KVGhlIGFuYWx5c2lzIHNob3dzIHRoYXQgKipib3RoKiogZmFjdG9ycyB3ZSB0ZXN0ZWQgaGF2ZSBhIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIHRvb3RoIGdyb3d0aDoNCg0KMS4gICoqRG9zZSBMZXZlbDoqKiAqKkluY3JlYXNpbmcgdGhlIGRvc2Ugb2YgVml0YW1pbiBDKiogbGVhZHMgdG8gY2hhbmdlcyBpbiB0b290aCBsZW5ndGggdGhhdCBhcmUgbm90IGR1ZSB0byByYW5kb20gY2hhbmNlLg0KMi4gICoqU3VwcGxlbWVudCBUeXBlOioqIFRoZSAqKndheSB0aGUgVml0YW1pbiBDIGlzIGRlbGl2ZXJlZCoqIChPcmFuZ2UgSnVpY2UgdnMuIEFzY29yYmljIEFjaWQpIGFsc28gaGFzIGEgc2lnbmlmaWNhbnQgZWZmZWN0IG9uIHRvb3RoIGxlbmd0aCwgaW5kZXBlbmRlbnQgb2YgdGhlIGFjdHVhbCBkb3NlLg0KDQoqKCoqQSBOb3RlIG9uIHRoZSBNaXNzaW5nIEludGVyYWN0aW9uOioqKSogSWYgdGhlIG1vZGVsIGhhZCBpbmNsdWRlZCBhbiBpbnRlcmFjdGlvbiB0ZXJtICgkXHRleHR7ZG9zZX0gXHRpbWVzIFx0ZXh0e3N1cHB9JCksIHdlIHdvdWxkIGNoZWNrIHRoYXQgZmlyc3QuIElmIHRoZSBpbnRlcmFjdGlvbiB3ZXJlIHNpZ25pZmljYW50LCBpdCB3b3VsZCBtZWFuIHRoZSBlZmZlY3Qgb2YgJFx0ZXh0e2Rvc2V9JCAqKmRlcGVuZHMgb24qKiB0aGUgdHlwZSBvZiAkXHRleHR7c3VwcH0kLCBtYWtpbmcgdGhlIG1haW4gZWZmZWN0cyBpbnRlcnByZXRhdGlvbnMgbGVzcyBtZWFuaW5nZnVsLiBTaW5jZSBpdCdzIG1pc3NpbmcgaGVyZSwgd2UgaW50ZXJwcmV0IHRoZSB0d28gbWFpbiBlZmZlY3RzIGFzIGluZGVwZW5kZW50IGluZmx1ZW5jZXMuDQoNCiMjIE1vZGVsIDI6IEludGVyYWN0aW9uIEVmZmVjdHMgKE5vbi1BZGRpdGl2ZSkNClRoZSBpbnRlcmFjdGlvbiB0ZXJtIGNoZWNrcyBpZiB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gb25lIGZhY3RvciBhbmQgdGhlIG91dGNvbWUgZGVwZW5kcyBvbiB0aGUgbGV2ZWwgb2YgdGhlIHNlY29uZCBmYWN0b3IuIFRoaXMgaXMgc3BlY2lmaWVkIHVzaW5nIHRoZSAqIG9wZXJhdG9yLCB3aGljaCBpcyBhIHNob3J0Y3V0IGZvciBGYWN0b3IxICsgRmFjdG9yMiArIEZhY3RvcjE6RmFjdG9yMi4NCg0KYGBge3J9DQojIFVzZSB0aGUgJyonIG9wZXJhdG9yIHRvIGluY2x1ZGUgbWFpbiBlZmZlY3RzIGFuZCB0aGUgaW50ZXJhY3Rpb24gdGVybQ0KYW5vdmFfbW9kZWxfaW50ZXJhY3Rpb24gPC0gYW92KGxlbiB+IGRvc2UgKiBzdXBwLCBkYXRhID0gVG9vdGhHcm93dGgpDQoNCiMgVmlldyB0aGUgQU5PVkEgU3VtbWFyeSBUYWJsZQ0Kc3VtbWFyeShhbm92YV9tb2RlbF9pbnRlcmFjdGlvbikNCmBgYA0KIyMjIFRoZSBIaWVyYXJjaHkgb2YgSW50ZXJwcmV0YXRpb24NCg0KV2hlbiByZWFkaW5nIGEgVHdvLVdheSBBTk9WQSB0YWJsZSwgYWx3YXlzIGxvb2sgYXQgdGhlICoqaW50ZXJhY3Rpb24gdGVybSBmaXJzdCoqLg0KDQp8IFNvdXJjZSB8ICRGIFx0ZXh0eyB2YWx1ZX0kIHwgJFx0ZXh0e1ByKD5GKX0kIHwgU2lnbmlmaWNhbmNlIHwgSW50ZXJwcmV0YXRpb24gRm9jdXMgfA0KfCA6LS0tIHwgOi0tLSB8IDotLS0gfCA6LS0tIHwgOi0tLSB8DQp8ICRcbWF0aGJme1x0ZXh0e2Rvc2U6c3VwcH19JCAoSW50ZXJhY3Rpb24pIHwgNC4xMDcgfCAqKjAuMDIxODYwKiogfCAkXG1hdGhiZnsqfSQgKFNpZ25pZmljYW50KSB8ICoqU3RhcnQgSGVyZSEqKiBJZiB0aGlzIGlzIHNpZ25pZmljYW50LCB0aGUgbWFpbiBlZmZlY3RzIGFyZSBjb21wbGV4LiB8DQp8ICRcdGV4dHtkb3NlfSQgKE1haW4gRWZmZWN0KSB8IDkyLjAwMCB8ICQ8IDJcdGV4dHtlLTE2fSQgfCAkXG1hdGhiZnsqKip9JCB8IEludGVycHJldCB0aGVzZSBlZmZlY3RzICoqd2l0aCBjYXV0aW9uKiogaW4gbGlnaHQgb2YgdGhlIGludGVyYWN0aW9uLiB8DQp8ICRcdGV4dHtzdXBwfSQgKE1haW4gRWZmZWN0KSB8IDE1LjU3MiB8ICQwLjAwMDIzMSQgfCAkXG1hdGhiZnsqKip9JCB8IEludGVycHJldCB0aGVzZSBlZmZlY3RzICoqd2l0aCBjYXV0aW9uKiogaW4gbGlnaHQgb2YgdGhlIGludGVyYWN0aW9uLiB8DQoNCiMjIyBUaGUgQ3JpdGljYWwgSW50ZXJhY3Rpb24gRWZmZWN0DQoNClRoZSBpbnRlcmFjdGlvbiB0ZXJtIHRlc3RzIHRoZSBmb2xsb3dpbmc6DQoNCiogKipOdWxsIEh5cG90aGVzaXMgKCRIX3swLCBcdGV4dHtpbnR9fSQpOioqIFRoZSBlZmZlY3Qgb2YgJFx0ZXh0e2Rvc2V9JCBvbiB0b290aCBsZW5ndGggaXMgdGhlICoqc2FtZSoqIHJlZ2FyZGxlc3Mgb2YgdGhlICRcdGV4dHtzdXBwfSQgdHlwZSAoaS5lLiwgdGhlIGxpbmVzIG9uIGEgcGxvdCBvZiBtZWFucyBhcmUgcGFyYWxsZWwpLg0KKiAqKkFsdGVybmF0aXZlIEh5cG90aGVzaXMgKCRIX3thLCBcdGV4dHtpbnR9fSQpOioqIFRoZSBlZmZlY3Qgb2YgJFx0ZXh0e2Rvc2V9JCAqKmRlcGVuZHMgb24qKiB0aGUgJFx0ZXh0e3N1cHB9JCB0eXBlIChpLmUuLCB0aGUgbGluZXMgYXJlIG5vdCBwYXJhbGxlbCkuDQoNCioqSW50ZXJwcmV0YXRpb24gb2YgJFx0ZXh0e2Rvc2U6c3VwcH0kOioqDQoNCiogKipQLVZhbHVlICgkXHRleHR7UHIoPkYpfSQpOioqICRcbWF0aGJmezAuMDIxODYwfSQuDQoqIFNpbmNlICQwLjAyMTg2MCA8IDAuMDUkLCB3ZSAqKnJlamVjdCB0aGUgTnVsbCBIeXBvdGhlc2lzKiogZm9yIHRoZSBpbnRlcmFjdGlvbi4NCiogKipDb25jbHVzaW9uOioqIFRoZSBpbnRlcmFjdGlvbiBiZXR3ZWVuICRcdGV4dHtkb3NlfSQgYW5kICRcdGV4dHtzdXBwfSQgaXMgKipzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50KiogKCRcbWF0aGJme0YoMiwgNTQpID0gNC4xMDcsIHAgPSAwLjAyMn0kKS4NCg0KKipXaGF0IHRoaXMgbWVhbnMgaW4gcGxhaW4gbGFuZ3VhZ2U6KiogVGhlIHdheSAqKmRvc2UqKiBhZmZlY3RzIHRvb3RoIGxlbmd0aCBpcyAqKmRpZmZlcmVudCoqIGZvciBhbmltYWxzIHJlY2VpdmluZyBPcmFuZ2UgSnVpY2UgKE9KKSB2ZXJzdXMgdGhvc2UgcmVjZWl2aW5nIEFzY29yYmljIEFjaWQgKFZDKS4gWW91IGNhbm5vdCBtYWtlIGEgc2luZ2xlLCBzaW1wbGUgc3RhdGVtZW50IGFib3V0IHRoZSBlZmZlY3Qgb2YgZG9zZSBhbG9uZSBvciBzdXBwbGVtZW50IGFsb25lOyB5b3UgbXVzdCBkZXNjcmliZSB0aGUgZWZmZWN0IG9mIG9uZSBmYWN0b3IgKmF0IGVhY2ggbGV2ZWwqIG9mIHRoZSBvdGhlciBmYWN0b3IuDQoNCiMjIyBJbnRlcnByZXRpbmcgU2lnbmlmaWNhbnQgTWFpbiBFZmZlY3RzIChJbiBDb250ZXh0KQ0KDQpCZWNhdXNlIHRoZSBpbnRlcmFjdGlvbiBpcyBzaWduaWZpY2FudCwgdGhlIGludGVycHJldGF0aW9uIG9mIHRoZSBtYWluIGVmZmVjdHMgb2YgJFx0ZXh0e2Rvc2V9JCBhbmQgJFx0ZXh0e3N1cHB9JCBiZWNvbWVzICoqc2Vjb25kYXJ5KiogYW5kIG5lZWRzIHF1YWxpZmljYXRpb24uIFRoZXkgdGVsbCB1cyB0aGVyZSBhcmUgb3ZlcmFsbCBkaWZmZXJlbmNlcywgYnV0IHRoZSBpbnRlcmFjdGlvbiBzaG93cyAqaG93KiB0aG9zZSBkaWZmZXJlbmNlcyBtYW5pZmVzdC4NCg0KIyMjIyAqKk1haW4gRWZmZWN0IG9mIERvc2UqKg0KDQoqICoqUC1WYWx1ZToqKiAkPCAyXHRleHR7ZS0xNn0kLiAqKkhpZ2hseSBTaWduaWZpY2FudC4qKg0KKiAqKkludGVycHJldGF0aW9uOioqIEFsdGhvdWdoIHRoZSBlZmZlY3Qgb2YgJFx0ZXh0e2Rvc2V9JCBpcyBoaWdobHkgc2lnbmlmaWNhbnQgKipvdmVyYWxsKiosIHdlIGtub3cgZnJvbSB0aGUgaW50ZXJhY3Rpb24gdGhhdCB0aGlzIGVmZmVjdCBpcyAqKm5vdCB1bmlmb3JtKiogYWNyb3NzIHRoZSB0d28gc3VwcGxlbWVudCB0eXBlcy4NCiAgICAqICpUaGUgZG9zZSBlZmZlY3QgZXhpc3RzLCBidXQgaXRzIG1hZ25pdHVkZSBvciBwYXR0ZXJuIGNoYW5nZXMgZGVwZW5kaW5nIG9uIHdoZXRoZXIgdGhlIHN1cHBsZW1lbnQgaXMgT0ogb3IgVkMuKg0KDQojIyMjICoqTWFpbiBFZmZlY3Qgb2YgU3VwcGxlbWVudCoqDQoNCiogKipQLVZhbHVlOioqICQwLjAwMDIzMSQuICoqSGlnaGx5IFNpZ25pZmljYW50LioqDQoqICoqSW50ZXJwcmV0YXRpb246KiogV2hpbGUgKipvdmVyYWxsKiosIG9uZSBzdXBwbGVtZW50IHR5cGUgcHJvZHVjZXMgc2lnbmlmaWNhbnRseSBsb25nZXIgdGVldGggdGhhbiB0aGUgb3RoZXIsIHRoZSBzaWduaWZpY2FudCBpbnRlcmFjdGlvbiBtZWFucyB0aGlzIGRpZmZlcmVuY2UgKip2YXJpZXMqKiBhY3Jvc3MgdGhlIGRpZmZlcmVudCBkb3NlIGxldmVscy4NCiAgICAqICpGb3IgZXhhbXBsZSwgT0ogbWlnaHQgYmUgbXVjaCBiZXR0ZXIgdGhhbiBWQyBhdCBhIGxvdyBkb3NlLCBidXQgdGhlIGRpZmZlcmVuY2UgbWlnaHQgZGlzYXBwZWFyIG9yIGV2ZW4gcmV2ZXJzZSBhdCBhIGhpZ2ggZG9zZS4qDQoNCiMjIyBOZXh0IFN0ZXBzIGZvciBBbmFseXNpcw0KDQpXaGVuIHRoZSBpbnRlcmFjdGlvbiBpcyBzaWduaWZpY2FudCwgdGhlIG1haW4gZWZmZWN0cyBhcmUgb2Z0ZW4gaWdub3JlZCBpbiBmYXZvciBvZiBhIGRlZXBlciBkaXZlIGludG8gdGhlIHNwZWNpZmljIGdyb3VwIGNvbWJpbmF0aW9ucy4NCg0KVGhlIHN0YXRpc3RpY2FsIHRlY2huaXF1ZSByZXF1aXJlZCBpcyAqKlNpbXBsZSBFZmZlY3RzIEFuYWx5c2lzKiogb3IgKipQb3N0LUhvYyBUZXN0cyBvbiB0aGUgQ2VsbCBNZWFucyoqLg0KDQoxLiAgKipTaW1wbGUgRWZmZWN0czoqKiBSdW4gc2VwYXJhdGUgb25lLXdheSBBTk9WQXMgKG9yICR0JC10ZXN0cykgdG8gZmluZDoNCiAgICAqIElzIHRoZXJlIGEgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBiZXR3ZWVuIE9KIGFuZCBWQyAqKmF0IHRoZSAkMC41XHRleHR7IG1nfSQgZG9zZSoqPw0KICAgICogSXMgdGhlcmUgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGJldHdlZW4gT0ogYW5kIFZDICoqYXQgdGhlICQxLjBcdGV4dHsgbWd9JCBkb3NlKio/DQogICAgKiBJcyB0aGVyZSBhIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgYmV0d2VlbiBPSiBhbmQgVkMgKiphdCB0aGUgJDIuMFx0ZXh0eyBtZ30kIGRvc2UqKj8NCjIuICAqKlZpc3VhbGl6YXRpb246KiogVGhlIGJlc3Qgd2F5IHRvIHByZXNlbnQgdGhpcyBpcyB3aXRoIGFuICoqSW50ZXJhY3Rpb24gUGxvdCoqIC4gVGhpcyB2aXN1YWwgY2xlYXJseSBzaG93cyB0aGUgbm9uLXBhcmFsbGVsIGxpbmVzLCBjb25maXJtaW5nIHRoZSBkZXBlbmRlbmNlIG9mIHRoZSAkXHRleHR7ZG9zZX0kIGVmZmVjdCBvbiAkXHRleHR7c3VwcH0kLg0KDQojIyBGb2xsb3ctdXAgd2hlbiBJbnRlcmFjdGlvbiBpcyBTaWduaWZpY2FudCAoTW9kZWwgMik6DQpJZiB0aGUgaW50ZXJhY3Rpb24gdGVybSAoYGRvc2U6c3VwcGApIGlzIHNpZ25pZmljYW50LCB0aGUgYXBwcm9wcmlhdGUgbmV4dCBzdGVwIGlzIHRvIHZpc3VhbGl6ZSB0aGUgaW50ZXJhY3Rpb24gYW5kIHRlc3QgdGhlIHNpbXBsZSBtYWluIGVmZmVjdHPigJR0aGUgZWZmZWN0IG9mIG9uZSBmYWN0b3IgYXQgYSBzcGVjaWZpYyBsZXZlbCBvZiB0aGUgb3RoZXIgZmFjdG9yLg0KDQpgYGB7cn0NCiMgVmlzdWFsaXplIHRoZSBpbnRlcmFjdGlvbiAoRXNzZW50aWFsIGZvciBhIHNpZ25pZmljYW50IGludGVyYWN0aW9uISkNCmdncGxvdChUb290aEdyb3d0aCwgYWVzKHggPSBkb3NlLCB5ID0gbGVuLCBncm91cCA9IHN1cHAsIGNvbG9yID0gc3VwcCkpICsNCiAgc3RhdF9zdW1tYXJ5KGZ1biA9IG1lYW4sIGdlb20gPSAicG9pbnQiKSArICMgUGxvdCBtZWFucw0KICBzdGF0X3N1bW1hcnkoZnVuID0gbWVhbiwgZ2VvbSA9ICJsaW5lIikgKyAjIENvbm5lY3QgbWVhbnMgd2l0aCBsaW5lcw0KICBsYWJzKHRpdGxlID0gIkludGVyYWN0aW9uIFBsb3Q6IFRvb3RoIExlbmd0aCBieSBEb3NlIGFuZCBTdXBwbGVtZW50IiwNCiAgICAgICB4ID0gIkRvc2UgKG1nL2RheSkiLA0KICAgICAgIHkgPSAiVG9vdGggTGVuZ3RoIChtbSkiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQpOb24tcGFyYWxsZWwgbGluZXMgc3VnZ2VzdCBhbiBpbnRlcmFjdGlvbi4NCg0KIyMjIEl0ZXJwcmV0YXRpb24gb2YgTWFpbiBFZmZlY3RzIHZzLiBJbnRlcmFjdGlvbg0KDQpCZSBhd2FyZSB0aGF0IGludGVycHJldGluZyBzaWduaWZpY2FudCBtYWluIGVmZmVjdHMgd2hlbiBhIHNpZ25pZmljYW50IGludGVyYWN0aW9uIGlzIHByZXNlbnQgaXMgZ2VuZXJhbGx5IGluYXBwcm9wcmlhdGUsIGFzIHRoZSBhdmVyYWdlZCBtYWluIGVmZmVjdHMgaGlkZSB0aGUgY29tcGxleGl0eSBvZiB0aGUgY29uZGl0aW9uYWwgZWZmZWN0cy4gVGhlIGludGVyYWN0aW9uIHBsb3QgYmVjb21lcyB0aGUgcHJpbWFyeSB0b29sIGZvciBpbml0aWFsIGludGVycHJldGF0aW9uLg0KDQpUaGUgaW50ZXJwcmV0YXRpb24gb2YgdGhlIG1haW4gZWZmZWN0cyBtdXN0IGJlIHF1YWxpZmllZCBieSB0aGUgc2lnbmlmaWNhbmNlIG9mIHRoZSBpbnRlcmFjdGlvbiB0ZXJtLg0KDQp8IEludGVyYWN0aW9uIFRlcm0gKHBwLXZhbHVlKSAgICB8IEludGVycHJldGF0aW9uIEd1aWRhbmNlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwNCnwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfA0KfCBOb3QgU2lnbmlmaWNhbnQgKCRwID4gXGFscGhhJCkgfCBBZGRpdGl2ZSBNb2RlbCBpcyBwcmVmZXJyZWQuIEludGVycHJldCB0aGUgbWFpbiBlZmZlY3RzIG9mIGRvc2UgYW5kIHN1cHAgZGlyZWN0bHkuIFRoZWlyIGVmZmVjdHMgYXJlIGluZGVwZW5kZW50LiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8DQp8IFNpZ25pZmljYW50ICgkcCBcbGUgXGFscGhhJCkgICB8IFRoZSBpbnRlcmFjdGlvbiBlZmZlY3QgaXMgdGhlIGZvY3VzLiBUaGUgbWFpbiBlZmZlY3RzIGFyZSBtaXNsZWFkaW5nIG9yIHVuaW50ZXJwcmV0YWJsZSBvbiB0aGVpciBvd24uIFRoZSBlZmZlY3Qgb2YgZG9zZSBkZXBlbmRzIG9uIHN1cHAgKGFuZCB2aWNlLXZlcnNhKS4gWW91IG11c3QgZm9sbG93IHVwIHdpdGggc2ltcGxlIG1haW4gZWZmZWN0cyBvciBjb250cmFzdHMgdG8gdW5kZXJzdGFuZCB0aGUgZ3JvdXAgbWVhbnMuIHwNCg0K