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:

  1. One-way ANOVA: Used to compare the means of three or more independent groups based on a single factor.

  2. 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.

Hypotheses in ANOVA:

Advantages:

Disadvantages:

Applications:

Pros:

Cons:


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)

Step 2: Perform One-Way ANOVA

# Perform one-way ANOVA
anova_result <- aov(score ~ method, data = test_scores)
summary(anova_result)
            Df Sum Sq Mean Sq F value   Pr(>F)    
method       2  564.9  282.43   14.03 5.25e-06 ***
Residuals   87 1751.9   20.14                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

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:

  1. Normality: The data in each group should be approximately normally distributed.

  2. Homogeneity of Variance: The variances of the groups should be approximately equal (can be tested using Levene’s Test).

  3. 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==