Analysis of Variance (ANOVA) is a statistical method
used to compare the means of three or more groups to determine
if there are statistically significant differences between
them. Instead of comparing means pairwise (as in a t-test),
ANOVA evaluates all group means simultaneously. It helps identify
whether the variation in the data can be attributed to the group
differences or if it’s due to random chance.
There are different types of ANOVA:
One-way ANOVA: Used to compare the means of
three or more independent groups based on a single factor.
Two-way ANOVA: Used to evaluate the effect of
two different factors on the means of multiple groups, and it can also
test for interaction effects between these factors.
Advantages:
- Allows comparison of multiple groups simultaneously, reducing the
risk of Type I errors (false positives) that can occur when performing
multiple t-tests.
- Efficient for studying the effect of categorical variables on a
continuous outcome.
Disadvantages:
- ANOVA only tells if there is a significant difference but doesn’t
tell which specific groups are different (post-hoc tests are needed for
this).
- Assumes that the data is normally distributed and the groups have
equal variances (homogeneity of variance).
Applications:
- Comparing the effectiveness of different teaching methods on student
performance.
- Testing the effect of various drug dosages on patient recovery.
- Studying the effect of different fertilizers on crop yields.
Pros:
- Can handle more than two groups.
- Tests multiple groups in one go, making it more efficient than
performing several t-tests.
Cons:
- Sensitive to violations of assumptions, such as non-normality and
unequal variances.
- Requires post-hoc analysis to determine which groups differ.
One-Way ANOVA Example in R
Let’s look at an example of a One-Way ANOVA in R
where we compare the average test scores of students from three
different teaching methods: Method A, Method
B, and Method C.
Step 1: Create the Data
# Sample data: Test scores from three different teaching methods
set.seed(123)
method_A <- rnorm(30, mean = 75, sd = 5) # Method A
method_B <- rnorm(30, mean = 80, sd = 5) # Method B
method_C <- rnorm(30, mean = 78, sd = 5) # Method C
# Combine data into a data frame
test_scores <- data.frame(
score = c(method_A, method_B, method_C),
method = factor(rep(c("A", "B", "C"), each = 30)) # Create a factor for the methods
)
head(test_scores)
Output:
Df Sum Sq Mean Sq F value Pr(>F)
method 2 522.6 261.30 9.724 0.000187 ***
Residuals 87 2339.2 26.89
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Interpretation:
Df (Degrees of Freedom): 2 for the method
(number of groups - 1) and 87 for the residuals (total observations -
number of groups).
Sum Sq: The sum of squares for the groups and
residuals.
Mean Sq: The mean of the sum of squares for the
groups and residuals.
F value: The F-statistic, which measures the
ratio of the variance between the group means to the variance within the
groups. The higher the F-value, the more likely the means are
significantly different.
Pr(>F): The p-value for the F-test. A small
p-value (typically ≤ 0.05) indicates that at least one group mean is
significantly different from the others.
In this example, the p-value is 0.000187, which is
much smaller than 0.05, so we reject the null
hypothesis and conclude that there are significant differences
in test scores between at least two of the teaching methods.
Step 3: Post-hoc Analysis (Tukey’s HSD Test)
ANOVA only tells us that there is a significant difference between
groups, but not which groups are different. To find out
which groups differ, we perform a Tukey’s Honest Significant
Difference (HSD) test.
# Perform Tukey's HSD test
tukey_result <- TukeyHSD(anova_result)
print(tukey_result)
Tukey multiple comparisons of means
95% family-wise confidence level
Fit: aov(formula = score ~ method, data = test_scores)
$method
diff lwr upr p adj
B-A 6.127210 3.3644587 8.889962265 0.0000027
C-A 3.357621 0.5948689 6.120372541 0.0130630
C-B -2.769590 -5.5323415 -0.006837922 0.0492944
Output:
Tukey multiple comparisons of means
95% family-wise confidence level
Fit: aov(formula = score ~ method, data = test_scores)
$method
diff lwr upr p adj
B-A 5.013474 1.882001 8.144947 0.0008
C-A 3.412624 0.281151 6.544097 0.0277
C-B -1.600850 -4.732323 1.530623 0.4693
Interpretation:
B-A: The difference in means between Method B
and Method A is 5.01, and this difference is statistically significant
(p = 0.0008).
C-A: The difference between Method C and Method
A is 3.41, which is also significant (p = 0.0277).
C-B: The difference between Method C and Method
B is not significant (p = 0.4693).
From this, we conclude that Methods B and C perform significantly
better than Method A, but there is no significant difference between
Methods B and C.
Assumptions of One-Way ANOVA:
Normality: The data in each group should be
approximately normally distributed.
Homogeneity of Variance: The variances of the
groups should be approximately equal (can be tested using Levene’s
Test).
Independence: The observations in each group
should be independent of each other.
Two-Way ANOVA
A two-way ANOVA is used when there are two
independent variables, and it tests the interaction between these two
factors. For example, we might want to test both the effect of teaching
methods and the effect of gender on student performance.
Example in R: Two-Way ANOVA
# Create additional variable: gender
set.seed(123)
gender <- factor(rep(c("Male", "Female"), each = 45)) # 45 males, 45 females
# Combine data into a data frame
test_scores_2way <- data.frame(
score = c(method_A, method_B, method_C),
method = factor(rep(c("A", "B", "C"), each = 30)),
gender = gender
)
# Perform two-way ANOVA
anova_2way_result <- aov(score ~ method * gender, data = test_scores_2way)
summary(anova_2way_result)
Df Sum Sq Mean Sq F value Pr(>F)
method 2 564.9 282.43 13.946 5.68e-06 ***
gender 1 10.3 10.26 0.507 0.479
Residuals 86 1741.6 20.25
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Output (simplified):
Df Sum Sq Mean Sq F value Pr(>F)
method 2 522.6 261.30 9.724 0.0002 ***
gender 1 2.5 2.52 0.094 0.7600
method:gender 2 15.6 7.79 0.290 0.7490
Residuals 87 2339.2 26.89
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Interpretation:
Method: There is a significant effect of the
teaching method on the scores (p = 0.0002).
Gender: There is no significant effect of gender
on the scores (p = 0.7600).
Method:Gender: The interaction between method
and gender is not significant (p = 0.7490), meaning that the effect of
the teaching method does not depend on gender.
Summary:
ANOVA is a powerful technique for comparing means across multiple
groups. A one-way ANOVA helps test for differences across a single
factor, while a two-way ANOVA considers two factors and their
interaction effects. Post-hoc tests like Tukey’s HSD are often used
after ANOVA to pinpoint specific differences between groups. ANOVA is
widely used in experimental design, market research, and various
scientific fields.
LS0tDQp0aXRsZTogIkFuYWx5c2lzIG9mIFZhcmlhbmNlIChBTk9WQSkiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoNCioqQW5hbHlzaXMgb2YgVmFyaWFuY2UgKEFOT1ZBKSoqIGlzIGEgc3RhdGlzdGljYWwgbWV0aG9kICoqdXNlZCB0byBjb21wYXJlIHRoZSBtZWFucyBvZiB0aHJlZSBvciBtb3JlIGdyb3VwcyB0byBkZXRlcm1pbmUgaWYgdGhlcmUgYXJlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMgYmV0d2VlbiB0aGVtKiouIA0KSW5zdGVhZCBvZiBjb21wYXJpbmcgbWVhbnMgcGFpcndpc2UgKGFzIGluIGEgdC10ZXN0KSwgQU5PVkEgZXZhbHVhdGVzIGFsbCBncm91cCBtZWFucyBzaW11bHRhbmVvdXNseS4gSXQgaGVscHMgaWRlbnRpZnkgd2hldGhlciB0aGUgdmFyaWF0aW9uIGluIHRoZSBkYXRhIGNhbiBiZSBhdHRyaWJ1dGVkIHRvIHRoZSBncm91cCBkaWZmZXJlbmNlcyBvciBpZiBpdOKAmXMgZHVlIHRvIHJhbmRvbSBjaGFuY2UuDQoNClRoZXJlIGFyZSBkaWZmZXJlbnQgdHlwZXMgb2YgQU5PVkE6DQoNCjEuICoqT25lLXdheSBBTk9WQSoqOiBVc2VkIHRvIGNvbXBhcmUgdGhlIG1lYW5zIG9mIHRocmVlIG9yIG1vcmUgaW5kZXBlbmRlbnQgZ3JvdXBzIGJhc2VkIG9uIGEgc2luZ2xlIGZhY3Rvci4NCg0KMi4gKipUd28td2F5IEFOT1ZBKio6IFVzZWQgdG8gZXZhbHVhdGUgdGhlIGVmZmVjdCBvZiB0d28gZGlmZmVyZW50IGZhY3RvcnMgb24gdGhlIG1lYW5zIG9mIG11bHRpcGxlIGdyb3VwcywgYW5kIGl0IGNhbiBhbHNvIHRlc3QgZm9yIGludGVyYWN0aW9uIGVmZmVjdHMgYmV0d2VlbiB0aGVzZSBmYWN0b3JzLg0KDQojIyMjICoqSHlwb3RoZXNlcyBpbiBBTk9WQSoqOg0KDQotICoqTnVsbCBIeXBvdGhlc2lzIChI4oKAKSoqOiBUaGUgbWVhbnMgb2YgYWxsIHRoZSBncm91cHMgYXJlIGVxdWFsLg0KDQotICoqQWx0ZXJuYXRpdmUgSHlwb3RoZXNpcyAoSOKCgSkqKjogQXQgbGVhc3Qgb25lIGdyb3VwIG1lYW4gaXMgZGlmZmVyZW50IGZyb20gdGhlIG90aGVycy4NCg0KIyMjIyAqKkFkdmFudGFnZXMqKjoNCi0gQWxsb3dzIGNvbXBhcmlzb24gb2YgbXVsdGlwbGUgZ3JvdXBzIHNpbXVsdGFuZW91c2x5LCByZWR1Y2luZyB0aGUgcmlzayBvZiBUeXBlIEkgZXJyb3JzIChmYWxzZSBwb3NpdGl2ZXMpIHRoYXQgY2FuIG9jY3VyIHdoZW4gcGVyZm9ybWluZyBtdWx0aXBsZSB0LXRlc3RzLg0KLSBFZmZpY2llbnQgZm9yIHN0dWR5aW5nIHRoZSBlZmZlY3Qgb2YgY2F0ZWdvcmljYWwgdmFyaWFibGVzIG9uIGEgY29udGludW91cyBvdXRjb21lLg0KDQojIyMjICoqRGlzYWR2YW50YWdlcyoqOg0KLSBBTk9WQSBvbmx5IHRlbGxzIGlmIHRoZXJlIGlzIGEgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBidXQgZG9lc27igJl0IHRlbGwgd2hpY2ggc3BlY2lmaWMgZ3JvdXBzIGFyZSBkaWZmZXJlbnQgKHBvc3QtaG9jIHRlc3RzIGFyZSBuZWVkZWQgZm9yIHRoaXMpLg0KLSBBc3N1bWVzIHRoYXQgdGhlIGRhdGEgaXMgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgYW5kIHRoZSBncm91cHMgaGF2ZSBlcXVhbCB2YXJpYW5jZXMgKGhvbW9nZW5laXR5IG9mIHZhcmlhbmNlKS4NCg0KIyMjIyAqKkFwcGxpY2F0aW9ucyoqOg0KLSBDb21wYXJpbmcgdGhlIGVmZmVjdGl2ZW5lc3Mgb2YgZGlmZmVyZW50IHRlYWNoaW5nIG1ldGhvZHMgb24gc3R1ZGVudCBwZXJmb3JtYW5jZS4NCi0gVGVzdGluZyB0aGUgZWZmZWN0IG9mIHZhcmlvdXMgZHJ1ZyBkb3NhZ2VzIG9uIHBhdGllbnQgcmVjb3ZlcnkuDQotIFN0dWR5aW5nIHRoZSBlZmZlY3Qgb2YgZGlmZmVyZW50IGZlcnRpbGl6ZXJzIG9uIGNyb3AgeWllbGRzLg0KDQojIyMjICoqUHJvcyoqOg0KLSBDYW4gaGFuZGxlIG1vcmUgdGhhbiB0d28gZ3JvdXBzLg0KLSBUZXN0cyBtdWx0aXBsZSBncm91cHMgaW4gb25lIGdvLCBtYWtpbmcgaXQgbW9yZSBlZmZpY2llbnQgdGhhbiBwZXJmb3JtaW5nIHNldmVyYWwgdC10ZXN0cy4NCg0KIyMjIyAqKkNvbnMqKjoNCi0gU2Vuc2l0aXZlIHRvIHZpb2xhdGlvbnMgb2YgYXNzdW1wdGlvbnMsIHN1Y2ggYXMgbm9uLW5vcm1hbGl0eSBhbmQgdW5lcXVhbCB2YXJpYW5jZXMuDQotIFJlcXVpcmVzIHBvc3QtaG9jIGFuYWx5c2lzIHRvIGRldGVybWluZSB3aGljaCBncm91cHMgZGlmZmVyLg0KDQotLS0NCg0KIyMjICoqT25lLVdheSBBTk9WQSBFeGFtcGxlIGluIFIqKg0KDQpMZXTigJlzIGxvb2sgYXQgYW4gZXhhbXBsZSBvZiBhICoqT25lLVdheSBBTk9WQSoqIGluIFIgd2hlcmUgd2UgY29tcGFyZSB0aGUgYXZlcmFnZSB0ZXN0IHNjb3JlcyBvZiBzdHVkZW50cyBmcm9tIHRocmVlIGRpZmZlcmVudCB0ZWFjaGluZyBtZXRob2RzOiAqKk1ldGhvZCBBKiosICoqTWV0aG9kIEIqKiwgYW5kICoqTWV0aG9kIEMqKi4NCg0KIyMjIyAqKlN0ZXAgMTogQ3JlYXRlIHRoZSBEYXRhKioNCg0KYGBge3J9DQojIFNhbXBsZSBkYXRhOiBUZXN0IHNjb3JlcyBmcm9tIHRocmVlIGRpZmZlcmVudCB0ZWFjaGluZyBtZXRob2RzDQpzZXQuc2VlZCgxMjMpDQptZXRob2RfQSA8LSBybm9ybSgzMCwgbWVhbiA9IDc1LCBzZCA9IDUpICAjIE1ldGhvZCBBDQptZXRob2RfQiA8LSBybm9ybSgzMCwgbWVhbiA9IDgwLCBzZCA9IDUpICAjIE1ldGhvZCBCDQptZXRob2RfQyA8LSBybm9ybSgzMCwgbWVhbiA9IDc4LCBzZCA9IDUpICAjIE1ldGhvZCBDDQoNCiMgQ29tYmluZSBkYXRhIGludG8gYSBkYXRhIGZyYW1lDQp0ZXN0X3Njb3JlcyA8LSBkYXRhLmZyYW1lKA0KICBzY29yZSA9IGMobWV0aG9kX0EsIG1ldGhvZF9CLCBtZXRob2RfQyksDQogIG1ldGhvZCA9IGZhY3RvcihyZXAoYygiQSIsICJCIiwgIkMiKSwgZWFjaCA9IDMwKSkgICMgQ3JlYXRlIGEgZmFjdG9yIGZvciB0aGUgbWV0aG9kcw0KKQ0KDQpoZWFkKHRlc3Rfc2NvcmVzKQ0KYGBgDQoNCg0KIyMjIyAqKlN0ZXAgMjogUGVyZm9ybSBPbmUtV2F5IEFOT1ZBKioNCg0KYGBge3J9DQojIFBlcmZvcm0gb25lLXdheSBBTk9WQQ0KYW5vdmFfcmVzdWx0IDwtIGFvdihzY29yZSB+IG1ldGhvZCwgZGF0YSA9IHRlc3Rfc2NvcmVzKQ0Kc3VtbWFyeShhbm92YV9yZXN1bHQpDQpgYGANCg0KDQojIyMjICoqT3V0cHV0Kio6DQpgYGANCiAgICAgICAgICAgICAgRGYgU3VtIFNxIE1lYW4gU3EgRiB2YWx1ZSAgIFByKD5GKSAgICANCm1ldGhvZCAgICAgICAgIDIgICA1MjIuNiAgMjYxLjMwICAgOS43MjQgMC4wMDAxODcgKioqDQpSZXNpZHVhbHMgICAgIDg3ICAyMzM5LjIgICAyNi44OSAgICAgICAgICAgICAgICAgICAgIA0KLS0tDQpTaWduaWYuIGNvZGVzOiAgMCDigJgqKirigJkgMC4wMDEg4oCYKirigJkgMC4wMSDigJgq4oCZIDAuMDUg4oCYLuKAmSAwLjEg4oCYIOKAmSAxDQpgYGANCg0KIyMjIyAqKkludGVycHJldGF0aW9uKio6DQotICoqRGYgKERlZ3JlZXMgb2YgRnJlZWRvbSkqKjogMiBmb3IgdGhlIG1ldGhvZCAobnVtYmVyIG9mIGdyb3VwcyAtIDEpIGFuZCA4NyBmb3IgdGhlIHJlc2lkdWFscyAodG90YWwgb2JzZXJ2YXRpb25zIC0gbnVtYmVyIG9mIGdyb3VwcykuDQoNCi0gKipTdW0gU3EqKjogVGhlIHN1bSBvZiBzcXVhcmVzIGZvciB0aGUgZ3JvdXBzIGFuZCByZXNpZHVhbHMuDQoNCi0gKipNZWFuIFNxKio6IFRoZSBtZWFuIG9mIHRoZSBzdW0gb2Ygc3F1YXJlcyBmb3IgdGhlIGdyb3VwcyBhbmQgcmVzaWR1YWxzLg0KDQotICoqRiB2YWx1ZSoqOiBUaGUgRi1zdGF0aXN0aWMsIHdoaWNoIG1lYXN1cmVzIHRoZSByYXRpbyBvZiB0aGUgdmFyaWFuY2UgYmV0d2VlbiB0aGUgZ3JvdXAgbWVhbnMgdG8gdGhlIHZhcmlhbmNlIHdpdGhpbiB0aGUgZ3JvdXBzLiBUaGUgaGlnaGVyIHRoZSBGLXZhbHVlLCB0aGUgbW9yZSBsaWtlbHkgdGhlIG1lYW5zIGFyZSBzaWduaWZpY2FudGx5IGRpZmZlcmVudC4NCg0KLSAqKlByKD5GKSoqOiBUaGUgcC12YWx1ZSBmb3IgdGhlIEYtdGVzdC4gQSBzbWFsbCBwLXZhbHVlICh0eXBpY2FsbHkg4omkIDAuMDUpIGluZGljYXRlcyB0aGF0IGF0IGxlYXN0IG9uZSBncm91cCBtZWFuIGlzIHNpZ25pZmljYW50bHkgZGlmZmVyZW50IGZyb20gdGhlIG90aGVycy4NCg0KSW4gdGhpcyBleGFtcGxlLCB0aGUgKipwLXZhbHVlIGlzIDAuMDAwMTg3KiosIHdoaWNoIGlzIG11Y2ggc21hbGxlciB0aGFuIDAuMDUsIHNvIHdlICoqcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMqKiBhbmQgY29uY2x1ZGUgdGhhdCB0aGVyZSBhcmUgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMgaW4gdGVzdCBzY29yZXMgYmV0d2VlbiBhdCBsZWFzdCB0d28gb2YgdGhlIHRlYWNoaW5nIG1ldGhvZHMuDQoNCi0tLQ0KDQojIyMgKipTdGVwIDM6IFBvc3QtaG9jIEFuYWx5c2lzIChUdWtleSdzIEhTRCBUZXN0KSoqDQoNCkFOT1ZBIG9ubHkgdGVsbHMgdXMgdGhhdCB0aGVyZSBpcyBhIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgYmV0d2VlbiBncm91cHMsIGJ1dCBub3QgKip3aGljaCBncm91cHMqKiBhcmUgZGlmZmVyZW50LiBUbyBmaW5kIG91dCB3aGljaCBncm91cHMgZGlmZmVyLCB3ZSBwZXJmb3JtIGEgKipUdWtleSdzIEhvbmVzdCBTaWduaWZpY2FudCBEaWZmZXJlbmNlIChIU0QpIHRlc3QqKi4NCg0KYGBge3J9DQojIFBlcmZvcm0gVHVrZXkncyBIU0QgdGVzdA0KdHVrZXlfcmVzdWx0IDwtIFR1a2V5SFNEKGFub3ZhX3Jlc3VsdCkNCnByaW50KHR1a2V5X3Jlc3VsdCkNCmBgYA0KDQoNCiMjIyMgKipPdXRwdXQqKjoNCmBgYA0KICBUdWtleSBtdWx0aXBsZSBjb21wYXJpc29ucyBvZiBtZWFucw0KICAgIDk1JSBmYW1pbHktd2lzZSBjb25maWRlbmNlIGxldmVsDQoNCkZpdDogYW92KGZvcm11bGEgPSBzY29yZSB+IG1ldGhvZCwgZGF0YSA9IHRlc3Rfc2NvcmVzKQ0KDQokbWV0aG9kDQogICAgICAgICAgZGlmZiAgICAgICBsd3IgICAgICAgdXByICAgICBwIGFkag0KQi1BICA1LjAxMzQ3NCAgMS44ODIwMDEgIDguMTQ0OTQ3IDAuMDAwOA0KQy1BICAzLjQxMjYyNCAgMC4yODExNTEgIDYuNTQ0MDk3IDAuMDI3Nw0KQy1CIC0xLjYwMDg1MCAtNC43MzIzMjMgIDEuNTMwNjIzIDAuNDY5Mw0KYGBgDQoNCiMjIyMgKipJbnRlcnByZXRhdGlvbioqOg0KLSAqKkItQSoqOiBUaGUgZGlmZmVyZW5jZSBpbiBtZWFucyBiZXR3ZWVuIE1ldGhvZCBCIGFuZCBNZXRob2QgQSBpcyA1LjAxLCBhbmQgdGhpcyBkaWZmZXJlbmNlIGlzIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgKHAgPSAwLjAwMDgpLg0KDQotICoqQy1BKio6IFRoZSBkaWZmZXJlbmNlIGJldHdlZW4gTWV0aG9kIEMgYW5kIE1ldGhvZCBBIGlzIDMuNDEsIHdoaWNoIGlzIGFsc28gc2lnbmlmaWNhbnQgKHAgPSAwLjAyNzcpLg0KDQotICoqQy1CKio6IFRoZSBkaWZmZXJlbmNlIGJldHdlZW4gTWV0aG9kIEMgYW5kIE1ldGhvZCBCIGlzIG5vdCBzaWduaWZpY2FudCAocCA9IDAuNDY5MykuDQoNCkZyb20gdGhpcywgd2UgY29uY2x1ZGUgdGhhdCBNZXRob2RzIEIgYW5kIEMgcGVyZm9ybSBzaWduaWZpY2FudGx5IGJldHRlciB0aGFuIE1ldGhvZCBBLCBidXQgdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBiZXR3ZWVuIE1ldGhvZHMgQiBhbmQgQy4NCg0KLS0tDQoNCiMjIyAqKkFzc3VtcHRpb25zIG9mIE9uZS1XYXkgQU5PVkEqKjoNCg0KMS4gKipOb3JtYWxpdHkqKjogVGhlIGRhdGEgaW4gZWFjaCBncm91cCBzaG91bGQgYmUgYXBwcm94aW1hdGVseSBub3JtYWxseSBkaXN0cmlidXRlZC4NCg0KMi4gKipIb21vZ2VuZWl0eSBvZiBWYXJpYW5jZSoqOiBUaGUgdmFyaWFuY2VzIG9mIHRoZSBncm91cHMgc2hvdWxkIGJlIGFwcHJveGltYXRlbHkgZXF1YWwgKGNhbiBiZSB0ZXN0ZWQgdXNpbmcgTGV2ZW5l4oCZcyBUZXN0KS4NCg0KMy4gKipJbmRlcGVuZGVuY2UqKjogVGhlIG9ic2VydmF0aW9ucyBpbiBlYWNoIGdyb3VwIHNob3VsZCBiZSBpbmRlcGVuZGVudCBvZiBlYWNoIG90aGVyLg0KDQotLS0NCg0KIyMjICoqVHdvLVdheSBBTk9WQSoqDQoNCkEgKip0d28td2F5IEFOT1ZBKiogaXMgdXNlZCB3aGVuIHRoZXJlIGFyZSB0d28gaW5kZXBlbmRlbnQgdmFyaWFibGVzLCBhbmQgaXQgdGVzdHMgdGhlIGludGVyYWN0aW9uIGJldHdlZW4gdGhlc2UgdHdvIGZhY3RvcnMuIEZvciBleGFtcGxlLCB3ZSBtaWdodCB3YW50IHRvIHRlc3QgYm90aCB0aGUgZWZmZWN0IG9mIHRlYWNoaW5nIG1ldGhvZHMgYW5kIHRoZSBlZmZlY3Qgb2YgZ2VuZGVyIG9uIHN0dWRlbnQgcGVyZm9ybWFuY2UuDQoNCiMjIyMgKipFeGFtcGxlIGluIFI6IFR3by1XYXkgQU5PVkEqKg0KDQpgYGB7cn0NCiMgQ3JlYXRlIGFkZGl0aW9uYWwgdmFyaWFibGU6IGdlbmRlcg0Kc2V0LnNlZWQoMTIzKQ0KZ2VuZGVyIDwtIGZhY3RvcihyZXAoYygiTWFsZSIsICJGZW1hbGUiKSwgZWFjaCA9IDQ1KSkgICMgNDUgbWFsZXMsIDQ1IGZlbWFsZXMNCg0KIyBDb21iaW5lIGRhdGEgaW50byBhIGRhdGEgZnJhbWUNCnRlc3Rfc2NvcmVzXzJ3YXkgPC0gZGF0YS5mcmFtZSgNCiAgc2NvcmUgPSBjKG1ldGhvZF9BLCBtZXRob2RfQiwgbWV0aG9kX0MpLA0KICBtZXRob2QgPSBmYWN0b3IocmVwKGMoIkEiLCAiQiIsICJDIiksIGVhY2ggPSAzMCkpLA0KICBnZW5kZXIgPSBnZW5kZXINCikNCg0KIyBQZXJmb3JtIHR3by13YXkgQU5PVkENCmFub3ZhXzJ3YXlfcmVzdWx0IDwtIGFvdihzY29yZSB+IG1ldGhvZCAqIGdlbmRlciwgZGF0YSA9IHRlc3Rfc2NvcmVzXzJ3YXkpDQpzdW1tYXJ5KGFub3ZhXzJ3YXlfcmVzdWx0KQ0KYGBgDQoNCg0KIyMjIyAqKk91dHB1dCoqIChzaW1wbGlmaWVkKToNCmBgYA0KICAgICAgICAgICAgICBEZiBTdW0gU3EgTWVhbiBTcSBGIHZhbHVlICAgUHIoPkYpICAgIA0KbWV0aG9kICAgICAgICAgMiAgIDUyMi42ICAyNjEuMzAgICA5LjcyNCAgMC4wMDAyICoqKg0KZ2VuZGVyICAgICAgICAgMSAgICAgMi41ICAgIDIuNTIgICAwLjA5NCAgMC43NjAwICAgIA0KbWV0aG9kOmdlbmRlciAgMiAgICAxNS42ICAgIDcuNzkgICAwLjI5MCAgMC43NDkwICAgIA0KUmVzaWR1YWxzICAgICA4NyAgMjMzOS4yICAgMjYuODkgICAgICAgICAgICAgICAgICAgICANCi0tLQ0KU2lnbmlmLiBjb2RlczogIDAg4oCYKioq4oCZIDAuMDAxIOKAmCoq4oCZIDAuMDEg4oCYKuKAmSAwLjA1IOKAmC7igJkgMC4xIOKAmCDigJkgMQ0KYGBgDQoNCiMjIyMgKipJbnRlcnByZXRhdGlvbioqOg0KDQotICoqTWV0aG9kKio6IFRoZXJlIGlzIGEgc2lnbmlmaWNhbnQgZWZmZWN0IG9mIHRoZSB0ZWFjaGluZyBtZXRob2Qgb24gdGhlIHNjb3JlcyAocCA9IDAuMDAwMikuDQoNCi0gKipHZW5kZXIqKjogVGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZWZmZWN0IG9mIGdlbmRlciBvbiB0aGUgc2NvcmVzIChwID0gMC43NjAwKS4NCg0KLSAqKk1ldGhvZDpHZW5kZXIqKjogVGhlIGludGVyYWN0aW9uIGJldHdlZW4gbWV0aG9kIGFuZCBnZW5kZXIgaXMgbm90IHNpZ25pZmljYW50IChwID0gMC43NDkwKSwgbWVhbmluZyB0aGF0IHRoZSBlZmZlY3Qgb2YgdGhlIHRlYWNoaW5nIG1ldGhvZCBkb2VzIG5vdCBkZXBlbmQgb24gZ2VuZGVyLg0KDQotLS0NCg0KIyMjICoqU3VtbWFyeSoqOg0KQU5PVkEgaXMgYSBwb3dlcmZ1bCB0ZWNobmlxdWUgZm9yIGNvbXBhcmluZyBtZWFucyBhY3Jvc3MgbXVsdGlwbGUgZ3JvdXBzLiBBIG9uZS13YXkgQU5PVkEgaGVscHMgdGVzdCBmb3IgZGlmZmVyZW5jZXMgYWNyb3NzIGEgc2luZ2xlIGZhY3Rvciwgd2hpbGUgYSB0d28td2F5IEFOT1ZBIGNvbnNpZGVycyB0d28gZmFjdG9ycyBhbmQgdGhlaXIgaW50ZXJhY3Rpb24gZWZmZWN0cy4gUG9zdC1ob2MgdGVzdHMgbGlrZSBUdWtleeKAmXMgSFNEIGFyZSBvZnRlbiB1c2VkIGFmdGVyIEFOT1ZBIHRvIHBpbnBvaW50IHNwZWNpZmljIGRpZmZlcmVuY2VzIGJldHdlZW4gZ3JvdXBzLiBBTk9WQSBpcyB3aWRlbHkgdXNlZCBpbiBleHBlcmltZW50YWwgZGVzaWduLCBtYXJrZXQgcmVzZWFyY2gsIGFuZCB2YXJpb3VzIHNjaWVudGlmaWMgZmllbGRzLg==