Using Multi-Level Regression Models to look at cereal rating differences

Jacqueline Nosrati

Overview

Cereals are the go-to choice food for many individuals as part of their breakfast meal. There are studies that suggest that eating breakfast cereal and breakfast in general can reduce the likelihood of obesety (Hunty, Gibson, and Ashwell 2013). It can also help reduce decline in attention span and memory over the morning period. According to a 2003 study researchers tested school children’s memory and attention levels during the morning by giving them different kinds of breakfasts (either 2 different kinds of cereals, a sugary drink or no breakfast) and found that those students who had cereal for breakfast tended to have less reduced memory and attention spans in the morning compared to those who had a sugary drink or no breakfast at all(Wesnes et al. 2003).

One has to consider however that many cereals tend to have high sugar amounts and more calories, which can do more harm in the long run and might lead to obesity, diabetes and exhibiting lower concentration levels. To address some of the health concerns and consumer demands there is a current trend among cereal manufacturers to reduce the sugar and calorie amounts in their products and offer healthier cereal choices. Additionally, there is an effort among cereal manufacturers to increase the amount of whole grains used in cereal manufacturing(Thomas et al. 2013).

In this week’s assignment I will use nutrition data of cereals from different cereal manufacturers to look at cereal ratings and whether the amounts of sugars and number of calories affect cereal ratings.

Load data set

For the analysis the following variables were selected cereal name, manufacturer, calories, sugars, and rating.

Recode mfr (manufacturer) variable into factor

For the manufacturer variable A stands for American Home Food Products, G for General Mills, K for Kellogs, N for Nabisco,P for Post, Q for Quaker Oats and R for Ralston Purina. We convert this variable into a factor.

Cereal3
name mfr calories sugars rating n_manufacturer
100% Bran N 70 6 68.402973 4
100% Natural Bran Q 120 8 33.983679 6
All-Bran K 70 5 59.425505 3
All-Bran with Extra Fiber K 50 0 93.704912 3
Almond Delight R 110 8 34.384843 7
Apple Cinnamon Cheerios G 110 10 29.509541 2

First, we look at how many how many cereal manufacturers exits and how many cereals belong to each manufacturer.

[1] 7

We generated the average rating, calories and sugars amounts per manufacturer. We see that Manufacturer 4 (Nabisco) has the highest average cereal rating. We also see that Manufacturer 2 (General Mills) has the highest average calorie content and that that Manufacturer 5 (Post) has the highest average sugar amount.

Cereal Manufacturers & Cereal Ratings

Complete Pooling Models


Call:
lm(formula = rating ~ calories, data = Cereal3)

Residuals:
     Min       1Q   Median       3Q      Max 
-18.7201  -7.9317  -0.6678   5.9902  23.4161 

Coefficients:
            Estimate Std. Error t value             Pr(>|t|)    
(Intercept) 95.78802    6.55057  14.623 < 0.0000000000000002 ***
calories    -0.49701    0.06031  -8.241     0.00000000000414 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 10.24 on 75 degrees of freedom
Multiple R-squared:  0.4752,    Adjusted R-squared:  0.4682 
F-statistic: 67.92 on 1 and 75 DF,  p-value: 0.00000000000414

The output for the first complete pooling model shows that the average cereal rating (without accounting for differences among cereal manufacturers) is 95.79 if a cereal had 0 calories and that for each additional calorie the cereal rating decreases on average by 0.5. We see that the results are statistically significant at a 99% confidence level. To get a better look at rating differences we add for the next complete pooling model the amount of sugars into the model.


Call:
lm(formula = rating ~ sugars, data = Cereal3)

Residuals:
    Min      1Q  Median      3Q     Max 
-17.853  -5.677  -1.439   5.160  34.421 

Coefficients:
            Estimate Std. Error t value             Pr(>|t|)    
(Intercept)  59.2844     1.9485   30.43 < 0.0000000000000002 ***
sugars       -2.4008     0.2373  -10.12  0.00000000000000115 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 9.196 on 75 degrees of freedom
Multiple R-squared:  0.5771,    Adjusted R-squared:  0.5715 
F-statistic: 102.3 on 1 and 75 DF,  p-value: 0.000000000000001153

The output for the second complete pooling model shows that the average cereal rating (without accounting for differences among cereal manufacturers) is 59.28 if a cereal had 0 grams of sugar and that for each additional gram of sugar the cereal rating decreases on average by 2.4 We see that the results are statistically significant at a 99% confidence level.


Call:
lm(formula = rating ~ calories + sugars, data = Cereal3)

Residuals:
    Min      1Q  Median      3Q     Max 
-15.643  -6.339  -1.221   4.823  23.413 

Coefficients:
            Estimate Std. Error t value             Pr(>|t|)    
(Intercept) 84.11417    5.44513  15.448 < 0.0000000000000002 ***
calories    -0.27644    0.05755  -4.804        0.00000793294 ***
sugars      -1.71939    0.25225  -6.816        0.00000000216 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 8.083 on 74 degrees of freedom
Multiple R-squared:  0.6776,    Adjusted R-squared:  0.6689 
F-statistic: 77.78 on 2 and 74 DF,  p-value: < 0.00000000000000022

The output for the third complete pooling model shows that the average cereal rating (without accounting for differences among cereal manufacturers) is 84.11 if a cereal had 0 calories and 0 grams sugar and that for each additional calorie the cereal rating decreases on average by 0.28 and for each additional sugar gram the cereal rating decreases on average by 1.72. Again, we see that the results are statistically significant at a 99% confidence level. Finally, we will look at rating differences with an interaction between calories and sugar amounts for the complete pooling model


Call:
lm(formula = rating ~ calories * sugars, data = Cereal3)

Residuals:
     Min       1Q   Median       3Q      Max 
-18.1761  -5.3793   0.1491   4.8486  15.7521 

Coefficients:
                  Estimate Std. Error t value             Pr(>|t|)    
(Intercept)     101.659340   7.560213  13.447 < 0.0000000000000002 ***
calories         -0.454542   0.078219  -5.811          0.000000151 ***
sugars           -5.038979   1.075503  -4.685          0.000012641 ***
calories:sugars   0.031056   0.009812   3.165              0.00226 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 7.631 on 73 degrees of freedom
Multiple R-squared:  0.7165,    Adjusted R-squared:  0.7049 
F-statistic: 61.51 on 3 and 73 DF,  p-value: < 0.00000000000000022

In the last complete pooling model we see that on their own calories and sugar amounts are still statistically significant at a 99% confidence level, however the interaction between the two indepedent variables is only statistically significant at a 95% confidence level.

Comparing the 4 complete pooling models

Comparing the Models
Model 1 Model 2 Model 3 Model 4
(Intercept) 95.79*** 59.28*** 84.11*** 101.66***
(6.55) (1.95) (5.45) (7.56)
calories -0.50*** -0.28*** -0.45***
(0.06) (0.06) (0.08)
sugars -2.40*** -1.72*** -5.04***
(0.24) (0.25) (1.08)
calories:sugars 0.03**
(0.01)
R2 0.48 0.58 0.68 0.72
Adj. R2 0.47 0.57 0.67 0.70
Num. obs. 77 77 77 77
RMSE 10.24 9.20 8.08 7.63
p < 0.001, p < 0.01, p < 0.05

When we compare the four complete pooling models we see that the fourth model is the best fitting model with an R2 of 0.72 (which is the highest amongst the three models).

No Pooling Model

Now we use the No pooling model to look at manufacturer differences in ratings. We see that large differences in cereal ratings among different manufacturers. The distribution looks somewhat normally distributed.

When looking at rating differences with respect to calories we now see a slightly right skewed distribution as the number of calories increase.

Random Intercept Model

Linear mixed-effects model fit by maximum likelihood
 Data: Cereal3 
       AIC      BIC    logLik
  568.5035 577.8787 -280.2517

Random effects:
 Formula: ~1 | n_manufacturer
        (Intercept) Residual
StdDev:    6.374507 8.503316

Fixed effects: rating ~ calories 
               Value Std.Error DF   t-value p-value
(Intercept) 91.86110  6.322652 69 14.528886       0
calories    -0.44305  0.054472 69 -8.133517       0
 Correlation: 
         (Intr)
calories -0.899

Standardized Within-Group Residuals:
        Min          Q1         Med          Q3         Max 
-1.76923784 -0.74835203  0.05835578  0.72828773  2.78544717 

Number of Observations: 77
Number of Groups: 7 

Random slope Model

Linear mixed-effects model fit by maximum likelihood
 Data: Cereal3 
       AIC      BIC    logLik
  550.0402 559.4154 -271.0201

Random effects:
 Formula: ~1 | n_manufacturer
        (Intercept) Residual
StdDev:    5.674263 7.540553

Fixed effects: rating ~ sugars 
               Value Std.Error DF   t-value p-value
(Intercept) 58.96186 2.7849719 69  21.17144       0
sugars      -2.17261 0.2126363 69 -10.21750       0
 Correlation: 
       (Intr)
sugars -0.469

Standardized Within-Group Residuals:
        Min          Q1         Med          Q3         Max 
-1.76232047 -0.66734610  0.08421924  0.50447067  4.42116697 

Number of Observations: 77
Number of Groups: 7 
Linear mixed-effects model fit by maximum likelihood
 Data: Cereal3 
       AIC      BIC    logLik
  527.6888 539.4078 -258.8444

Random effects:
 Formula: ~1 | n_manufacturer
        (Intercept) Residual
StdDev:    5.195241  6.40292

Fixed effects: rating ~ calories + sugars 
               Value Std.Error DF   t-value p-value
(Intercept) 81.93156  5.038979 68 16.259557       0
calories    -0.25440  0.048437 68 -5.252119       0
sugars      -1.58308  0.213238 68 -7.424006       0
 Correlation: 
         (Intr) calors
calories -0.868       
sugars    0.262 -0.520

Standardized Within-Group Residuals:
        Min          Q1         Med          Q3         Max 
-1.85332392 -0.62335188 -0.06762691  0.59790039  3.57112139 

Number of Observations: 77
Number of Groups: 7 
Linear mixed-effects model fit by maximum likelihood
 Data: Cereal3 
       AIC      BIC    logLik
  518.1851 536.9356 -251.0926

Random effects:
 Formula: ~sugars | n_manufacturer
 Structure: General positive-definite, Log-Cholesky parametrization
            StdDev        Corr  
(Intercept) 5.44074510787 (Intr)
sugars      0.00005841409 0     
Residual    5.72159189529       

Fixed effects: rating ~ calories * sugars 
                    Value Std.Error DF   t-value p-value
(Intercept)     100.89399  6.624025 67 15.231522  0.0000
calories         -0.44511  0.064296 67 -6.922701  0.0000
sugars           -5.05465  0.877583 67 -5.759745  0.0000
calories:sugars   0.03222  0.007927 67  4.064667  0.0001
 Correlation: 
                (Intr) calors sugars
calories        -0.924              
sugars          -0.651  0.639       
calories:sugars  0.708 -0.734 -0.976

Standardized Within-Group Residuals:
       Min         Q1        Med         Q3        Max 
-2.0230039 -0.7014219  0.1141536  0.6372830  2.3697122 

Number of Observations: 77
Number of Groups: 7 

Final Model Comparison

Comparing the Models
Model 1 Model 2 Model 3 Model 4
(Intercept) 91.86*** 58.96*** 81.93*** 100.89***
(6.32) (2.78) (5.04) (6.62)
calories -0.44*** -0.25*** -0.45***
(0.05) (0.05) (0.06)
sugars -2.17*** -1.58*** -5.05***
(0.21) (0.21) (0.88)
calories:sugars 0.03***
(0.01)
AIC 568.50 550.04 527.69 518.19
BIC 577.88 559.42 539.41 536.94
Log Likelihood -280.25 -271.02 -258.84 -251.09
Num. obs. 77 77 77 77
Num. groups 7 7 7 7
p < 0.001, p < 0.01, p < 0.05

Comparing the models, we see that the last model that accounts for manufacturer differences is the best fit model since it has the lowest AIC and BIC (with 518.19 and 536.94, respectively). Looking at the m4_crating model we see that there is a difference of 5.44 in cereal ratings when keeping the amoung of sugars constant at the higher-level (manufacturer level). We also see that there is a 5.72 rating difference after keeping cereal manufacturer and sugar amount constant.

Bibliography

Hunty, Anne de la, Sigrid Gibson, and Margaret Ashwell. 2013. “Does Regular Breakfast Cereal Consumption Help Children and Adolescents Stay Slimmer? A Systematic Review and Meta-Analysis.” Obesity Facts 6 (1). Karger Publishers: 70–85.

Thomas, Robin G, Pamela R Pehrsson, Jaspreet KC Ahuja, Erin Smieja, and Kevin B Miller. 2013. “Recent Trends in Ready-to-Eat Breakfast Cereals in the Us.” Procedia Food Science 2. Elsevier: 20–26.

Wesnes, Keith A, Claire Pincock, David Richardson, Gareth Helm, and Simon Hails. 2003. “Breakfast Reduces Declines in Attention and Memory over the Morning in Schoolchildren.” Appetite 41 (3). Elsevier: 329–31.

LS0tDQp0aXRsZTogIldlZWsgOSINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KYmlibGlvZ3JhcGh5OiBzb2M3MTJfd2VlazkuYmliDQotLS0NCg0KDQojIyoqVXNpbmcgTXVsdGktTGV2ZWwgUmVncmVzc2lvbiBNb2RlbHMgdG8gbG9vayBhdCBjZXJlYWwgcmF0aW5nIGRpZmZlcmVuY2VzICoqDQoNCiMjIyNKYWNxdWVsaW5lIE5vc3JhdGkNCg0KIVtdKGh0dHBzOi8vc2MwMS5hbGljZG4uY29tL2tmL1VUQjhSMWt6WGJQSlhLSmtTYWZTNzYxcVVYWGF2L0dvb2QtZ3JhZGUtb2YtQlJBS0ZBU1QtQ0VSRUFMLWZvci1jaGVhcC5wbmcpDQoNCiMjI092ZXJ2aWV3DQoNCkNlcmVhbHMgYXJlIHRoZSBnby10byBjaG9pY2UgZm9vZCBmb3IgbWFueSBpbmRpdmlkdWFscyBhcyBwYXJ0IG9mIHRoZWlyIGJyZWFrZmFzdCBtZWFsLiBUaGVyZSBhcmUgc3R1ZGllcyB0aGF0IHN1Z2dlc3QgdGhhdCBlYXRpbmcgYnJlYWtmYXN0IGNlcmVhbCBhbmQgYnJlYWtmYXN0IGluIGdlbmVyYWwgY2FuIHJlZHVjZSB0aGUgbGlrZWxpaG9vZCBvZiBvYmVzZXR5IFtAZGUyMDEzZG9lc10uIEl0IGNhbiBhbHNvIGhlbHAgcmVkdWNlIGRlY2xpbmUgaW4gYXR0ZW50aW9uIHNwYW4gYW5kIG1lbW9yeSBvdmVyIHRoZSBtb3JuaW5nIHBlcmlvZC4gQWNjb3JkaW5nIHRvIGEgMjAwMyBzdHVkeSByZXNlYXJjaGVycyB0ZXN0ZWQgc2Nob29sIGNoaWxkcmVuJ3MgbWVtb3J5IGFuZCBhdHRlbnRpb24gbGV2ZWxzIGR1cmluZyB0aGUgbW9ybmluZyBieSBnaXZpbmcgdGhlbSBkaWZmZXJlbnQga2luZHMgb2YgYnJlYWtmYXN0cyAoZWl0aGVyIDIgZGlmZmVyZW50IGtpbmRzIG9mIGNlcmVhbHMsIGEgc3VnYXJ5IGRyaW5rIG9yIG5vIGJyZWFrZmFzdCkgYW5kIGZvdW5kIHRoYXQgdGhvc2Ugc3R1ZGVudHMgd2hvIGhhZCBjZXJlYWwgZm9yIGJyZWFrZmFzdCB0ZW5kZWQgdG8gaGF2ZSBsZXNzIHJlZHVjZWQgbWVtb3J5IGFuZCBhdHRlbnRpb24gc3BhbnMgaW4gdGhlIG1vcm5pbmcgY29tcGFyZWQgdG8gdGhvc2Ugd2hvIGhhZCBhIHN1Z2FyeSBkcmluayBvciBubyBicmVha2Zhc3QgYXQgYWxsW0B3ZXNuZXMyMDAzYnJlYWtmYXN0XS4gDQoNCk9uZSBoYXMgdG8gY29uc2lkZXIgaG93ZXZlciB0aGF0IG1hbnkgY2VyZWFscyB0ZW5kIHRvIGhhdmUgaGlnaCBzdWdhciBhbW91bnRzIGFuZCBtb3JlIGNhbG9yaWVzLCB3aGljaCBjYW4gZG8gbW9yZSBoYXJtIGluIHRoZSBsb25nIHJ1biBhbmQgbWlnaHQgbGVhZCB0byBvYmVzaXR5LCBkaWFiZXRlcyBhbmQgZXhoaWJpdGluZyBsb3dlciBjb25jZW50cmF0aW9uIGxldmVscy4gVG8gYWRkcmVzcyBzb21lIG9mIHRoZSBoZWFsdGggY29uY2VybnMgYW5kIGNvbnN1bWVyIGRlbWFuZHMgdGhlcmUgaXMgYSBjdXJyZW50IHRyZW5kIGFtb25nIGNlcmVhbCBtYW51ZmFjdHVyZXJzIHRvIHJlZHVjZSB0aGUgc3VnYXIgYW5kIGNhbG9yaWUgYW1vdW50cyBpbiB0aGVpciBwcm9kdWN0cyBhbmQgb2ZmZXIgaGVhbHRoaWVyIGNlcmVhbCBjaG9pY2VzLiBBZGRpdGlvbmFsbHksIHRoZXJlIGlzIGFuIGVmZm9ydCBhbW9uZyBjZXJlYWwgbWFudWZhY3R1cmVycyB0byBpbmNyZWFzZSB0aGUgYW1vdW50IG9mIHdob2xlIGdyYWlucyB1c2VkIGluIGNlcmVhbCBtYW51ZmFjdHVyaW5nW0B0aG9tYXMyMDEzcmVjZW50XS4gDQoNCkluIHRoaXMgd2VlaydzIGFzc2lnbm1lbnQgSSB3aWxsIHVzZSBudXRyaXRpb24gZGF0YSBvZiBjZXJlYWxzIGZyb20gZGlmZmVyZW50IGNlcmVhbCBtYW51ZmFjdHVyZXJzIHRvIGxvb2sgYXQgY2VyZWFsIHJhdGluZ3MgYW5kIHdoZXRoZXIgdGhlIGFtb3VudHMgb2Ygc3VnYXJzIGFuZCBudW1iZXIgb2YgY2Fsb3JpZXMgYWZmZWN0IGNlcmVhbCByYXRpbmdzLg0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeSh0aWR5cikNCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeSh2aXNyZWcpDQpsaWJyYXJ5KG5sbWUpDQpsaWJyYXJ5KHNqbWlzYykNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZ2d0aGVtZXMpDQpsaWJyYXJ5KHJhZGlhbnQuZGF0YSkNCmxpYnJhcnkocGFuZGVyKQ0KbGlicmFyeShtYWdyaXR0cikNCmxpYnJhcnkoaGF2ZW4pDQpsaWJyYXJ5KGxtZXJUZXN0KQ0KbGlicmFyeSh0ZXhyZWcpDQpsaWJyYXJ5KHN0YXJnYXplcikNCmxpYnJhcnkocGxvdGx5KQ0KbGlicmFyeShDaXRlKQ0KYGBgDQoNCiMjI0xvYWQgZGF0YSBzZXQNCg0KYGBge3IsbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRX0NCkNlcmVhbDwtIHJlYWRfY3N2KCJDOi9Vc2Vycy9QYXBhL0Rlc2t0b3AvU29jIDcxMiAtUi9jZXJlYWwuY3N2IiwgY29sX25hbWVzID0gVFJVRSkNCmhlYWQoQ2VyZWFsKQ0KYGBgDQoNCg0KRm9yIHRoZSBhbmFseXNpcyB0aGUgZm9sbG93aW5nIHZhcmlhYmxlcyB3ZXJlIHNlbGVjdGVkIGNlcmVhbCBuYW1lLCBtYW51ZmFjdHVyZXIsIGNhbG9yaWVzLCBzdWdhcnMsIGFuZCByYXRpbmcuDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQ0KQ2VyZWFsMiA8LSBzZWxlY3QoQ2VyZWFsLCBuYW1lLCBtZnIsIGNhbG9yaWVzLCBzdWdhcnMsIHJhdGluZykNCmhlYWQoQ2VyZWFsMikNCmBgYA0KDQoNCiMjI1JlY29kZSBtZnIgKG1hbnVmYWN0dXJlcikgdmFyaWFibGUgaW50byBmYWN0b3INCg0KRm9yIHRoZSBtYW51ZmFjdHVyZXIgdmFyaWFibGUgQSBzdGFuZHMgZm9yIEFtZXJpY2FuIEhvbWUgRm9vZCBQcm9kdWN0cywgRyBmb3IgR2VuZXJhbCBNaWxscywgSyBmb3IgS2VsbG9ncywgTiBmb3IgTmFiaXNjbyxQIGZvciBQb3N0LCBRIGZvciBRdWFrZXIgT2F0cyBhbmQgUiBmb3IgUmFsc3RvbiBQdXJpbmEuIFdlIGNvbnZlcnQgdGhpcyB2YXJpYWJsZSBpbnRvIGEgZmFjdG9yLiANCiANCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQ0KQ2VyZWFsMzwtQ2VyZWFsMiAlPiUgbXV0YXRlIChuX21hbnVmYWN0dXJlciA9IGZhY3RvcihpZmVsc2UobWZyID09ICJBIiwgMSwNCiAgICAgICAgICAgICAgICBpZmVsc2UobWZyID09ICJHIiwgMiwNCiAgICAgICAgICAgICAgICBpZmVsc2UobWZyID09ICJLIiwgMywNCiAgICAgICAgICAgICAgICBpZmVsc2UobWZyID09ICJOIiwgNCwNCiAgICAgICAgICAgICAgICBpZmVsc2UobWZyID09ICJQIiwgNSwNCiAgICAgICAgICAgICAgICBpZmVsc2UobWZyID09ICJRIiwgNiwNCiAgICAgICAgICAgICAgICBpZmVsc2UobWZyID09ICJSIiwgNywgImVycm9yIikpKSkpKSkpKQ0KaGVhZChDZXJlYWwzKQ0KYGBgDQoNCg0KDQpgYGB7cixtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdhc2lzJ30NCnN0YXJnYXplcihoZWFkKENlcmVhbDMpLCBzdW1tYXJ5ID0gRkFMU0UsIHR5cGUgPSAiaHRtbCIsIHJvd25hbWVzPUZBTFNFLCB0aXRsZSA9IkNlcmVhbDMiKQ0KYGBgDQoNCiAgDQogICAgDQpGaXJzdCwgd2UgbG9vayBhdCBob3cgbWFueSBob3cgbWFueSBjZXJlYWwgbWFudWZhY3R1cmVycyBleGl0cyBhbmQgaG93IG1hbnkgY2VyZWFscyBiZWxvbmcgdG8gZWFjaCBtYW51ZmFjdHVyZXIuICANCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0V9DQpsZW5ndGgodW5pcXVlKENlcmVhbDMkbl9tYW51ZmFjdHVyZXIpKQ0KDQpDZXJlYWwzICU+JSANCiAgZ3JvdXBfYnkobl9tYW51ZmFjdHVyZXIpICU+JSANCiAgc3VtbWFyaXNlKG5fbWFuID0gbigpKQ0KYGBgDQoNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0V9DQptYW51ZmFjdHVyZXJzIDwtIENlcmVhbDMgJT4lIA0KICBncm91cF9ieShuX21hbnVmYWN0dXJlcikgJT4lIA0KICBzdW1tYXJpc2UobWVhbl9yID0gbWVhbihyYXRpbmcsIG5hLnJtID0gVFJVRSksIG1lYW5fYyA9IG1lYW4oY2Fsb3JpZXMsIG5hLnJtID0gVFJVRSksIG1lYW5fcyA9IG1lYW4oc3VnYXJzLCBuYS5ybSA9IFRSVUUpKQ0KbWFudWZhY3R1cmVycw0KYGBgDQoNCldlIGdlbmVyYXRlZCB0aGUgYXZlcmFnZSByYXRpbmcsIGNhbG9yaWVzIGFuZCBzdWdhcnMgYW1vdW50cyBwZXIgbWFudWZhY3R1cmVyLiBXZSBzZWUgdGhhdCBNYW51ZmFjdHVyZXIgNCAoTmFiaXNjbykgaGFzIHRoZSBoaWdoZXN0IGF2ZXJhZ2UgY2VyZWFsIHJhdGluZy4gV2UgYWxzbyBzZWUgdGhhdCBNYW51ZmFjdHVyZXIgMiAoR2VuZXJhbCBNaWxscykgaGFzIHRoZSBoaWdoZXN0IGF2ZXJhZ2UgY2Fsb3JpZSBjb250ZW50IGFuZCB0aGF0IHRoYXQgTWFudWZhY3R1cmVyIDUgKFBvc3QpIGhhcyB0aGUgaGlnaGVzdCBhdmVyYWdlIHN1Z2FyIGFtb3VudC4NCg0KDQoNCiMjI0NlcmVhbCBNYW51ZmFjdHVyZXJzICYgQ2VyZWFsIFJhdGluZ3MNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2FzaXMnfQ0KeCA8LSBjKCdBbWVyaWNhbiBIb21lIEZvb2QgUHJvZHVjdHMnLCAnR2VuZXJhbCBNaWxscycsICdLZWxsb2dzJyAsICdOYWJpc2NvJywgJ1Bvc3QnLCAnUXVha2VyIE9hdHMnLCAnUmFsc3RvbiBQdXJpbmEnICkNCnkgPC0gYyg1NC44NSwgMzQuNDksIDQ0LjA0LCA2Ny45NywgNDEuNzEsIDQyLjkyLCA0MS41NCkNCnRleHQgPC0gYygnNTQuODUgcmF0aW5nJywgJzM0LjQ5IHJhdGluZycsICc0NC4wNCByYXRpbmcnLCAnNjcuOTcgcmF0aW5nJywnNDEuNzEgcmF0aW5nJywgJzQyLjkyIHJhdGluZycsICc0MS41NCByYXRpbmcnKQ0KZGF0YSA8LSBkYXRhLmZyYW1lKHgsIHksIHRleHQpDQoNCnAgPC0gcGxvdF9seShkYXRhLCB4ID0gfngsIHkgPSB+eSwgdHlwZSA9ICdiYXInLCB0ZXh0ID0gdGV4dCwNCiAgICAgICAgbWFya2VyID0gbGlzdChjb2xvciA9ICdyZ2IoMTU4LDIwMiwyMjUpJywNCiAgICAgICAgICAgICAgICAgICAgICBsaW5lID0gbGlzdChjb2xvciA9ICdyZ2IoOCw0OCwxMDcpJywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCA9IDEuNSkpKSAlPiUNCiAgbGF5b3V0KHRpdGxlID0gIkF2ZXJhZ2UgUmF0aW5ncyBmb3IgQ2VyZWFsIE1hbnVmYWN0dXJlcnMiLA0KICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIiIpLA0KICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIiIpKQ0KcA0KYGBgDQoNCg0KDQoNCg0KIyMjQ29tcGxldGUgUG9vbGluZyBNb2RlbHMNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQ0KY3Bvb2xpbmcgPC0gbG0ocmF0aW5nIH4gY2Fsb3JpZXMsIGRhdGEgPSBDZXJlYWwzKQ0Kc3VtbWFyeShjcG9vbGluZykNCmBgYA0KDQoNClRoZSBvdXRwdXQgZm9yIHRoZSBmaXJzdCBjb21wbGV0ZSBwb29saW5nIG1vZGVsIHNob3dzIHRoYXQgdGhlIGF2ZXJhZ2UgY2VyZWFsIHJhdGluZyAod2l0aG91dCBhY2NvdW50aW5nIGZvciBkaWZmZXJlbmNlcyBhbW9uZyBjZXJlYWwgbWFudWZhY3R1cmVycykgaXMgOTUuNzkgaWYgYSBjZXJlYWwgaGFkIDAgY2Fsb3JpZXMgYW5kIHRoYXQgZm9yIGVhY2ggYWRkaXRpb25hbCBjYWxvcmllIHRoZSBjZXJlYWwgcmF0aW5nIGRlY3JlYXNlcyBvbiBhdmVyYWdlIGJ5IDAuNS4gV2Ugc2VlIHRoYXQgdGhlIHJlc3VsdHMgYXJlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgYXQgYSA5OSUgY29uZmlkZW5jZSBsZXZlbC4gVG8gZ2V0IGEgYmV0dGVyIGxvb2sgYXQgcmF0aW5nIGRpZmZlcmVuY2VzIHdlIGFkZCBmb3IgdGhlIG5leHQgY29tcGxldGUgcG9vbGluZyBtb2RlbCB0aGUgYW1vdW50IG9mIHN1Z2FycyBpbnRvIHRoZSBtb2RlbC4gDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdhc2lzJ30NCmdjIDwtIGdncGxvdChjcG9vbGluZywgbWFwcGluZyA9IGFlcyh4ID0gY2Fsb3JpZXMsIHkgPSByYXRpbmcpKQ0KZ2MyPC0gZ2MgKyBnZW9tX3Ntb290aCgpICsgZ2d0aXRsZSgiQ2Fsb3JpZXMgVnMgUmF0aW5ncyIpDQpnYzINCmBgYA0KDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQ0KY3Bvb2xpbmcyIDwtIGxtKHJhdGluZyB+IHN1Z2FycywgZGF0YSA9IENlcmVhbDMpDQpzdW1tYXJ5KGNwb29saW5nMikNCmBgYA0KDQpUaGUgb3V0cHV0IGZvciB0aGUgc2Vjb25kIGNvbXBsZXRlIHBvb2xpbmcgbW9kZWwgc2hvd3MgdGhhdCB0aGUgYXZlcmFnZSBjZXJlYWwgcmF0aW5nICh3aXRob3V0IGFjY291bnRpbmcgZm9yIGRpZmZlcmVuY2VzIGFtb25nIGNlcmVhbCBtYW51ZmFjdHVyZXJzKSBpcyA1OS4yOCBpZiBhIGNlcmVhbCBoYWQgMCBncmFtcyBvZiBzdWdhciBhbmQgdGhhdCBmb3IgZWFjaCBhZGRpdGlvbmFsIGdyYW0gb2Ygc3VnYXIgdGhlIGNlcmVhbCByYXRpbmcgZGVjcmVhc2VzIG9uIGF2ZXJhZ2UgYnkgMi40IFdlIHNlZSB0aGF0IHRoZSByZXN1bHRzIGFyZSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGF0IGEgOTklIGNvbmZpZGVuY2UgbGV2ZWwuIA0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRSwgcmVzdWx0cz0nYXNpcyd9DQpncyA8LSBnZ3Bsb3QoY3Bvb2xpbmcyLCBtYXBwaW5nID0gYWVzKHggPSBzdWdhcnMsIHkgPSByYXRpbmcpKQ0KZ3MyPC0gZ3MgKyBnZW9tX3Ntb290aCgpICsgZ2d0aXRsZSgiU3VnYXIgVnMgUmF0aW5ncyIpDQpnczINCmBgYA0KDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQ0KY3Bvb2xpbmczIDwtIGxtKHJhdGluZyB+IGNhbG9yaWVzICsgc3VnYXJzLCBkYXRhID0gQ2VyZWFsMykNCnN1bW1hcnkoY3Bvb2xpbmczKQ0KYGBgDQoNCg0KVGhlIG91dHB1dCBmb3IgdGhlIHRoaXJkIGNvbXBsZXRlIHBvb2xpbmcgbW9kZWwgc2hvd3MgdGhhdCB0aGUgYXZlcmFnZSBjZXJlYWwgcmF0aW5nICh3aXRob3V0IGFjY291bnRpbmcgZm9yIGRpZmZlcmVuY2VzIGFtb25nIGNlcmVhbCBtYW51ZmFjdHVyZXJzKSBpcyA4NC4xMSBpZiBhIGNlcmVhbCBoYWQgMCBjYWxvcmllcyBhbmQgMCBncmFtcyBzdWdhciBhbmQgdGhhdCBmb3IgZWFjaCBhZGRpdGlvbmFsIGNhbG9yaWUgdGhlIGNlcmVhbCByYXRpbmcgZGVjcmVhc2VzIG9uIGF2ZXJhZ2UgYnkgMC4yOCBhbmQgZm9yIGVhY2ggYWRkaXRpb25hbCBzdWdhciBncmFtIHRoZSBjZXJlYWwgcmF0aW5nIGRlY3JlYXNlcyBvbiBhdmVyYWdlIGJ5IDEuNzIuIEFnYWluLCB3ZSBzZWUgdGhhdCB0aGUgcmVzdWx0cyBhcmUgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBhdCBhIDk5JSBjb25maWRlbmNlIGxldmVsLiBGaW5hbGx5LCB3ZSB3aWxsIGxvb2sgYXQgcmF0aW5nIGRpZmZlcmVuY2VzIHdpdGggYW4gaW50ZXJhY3Rpb24gYmV0d2VlbiBjYWxvcmllcyBhbmQgc3VnYXIgYW1vdW50cyBmb3IgdGhlIGNvbXBsZXRlIHBvb2xpbmcgbW9kZWwgDQoNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0V9DQpjcG9vbGluZzQgPC0gbG0ocmF0aW5nIH4gY2Fsb3JpZXMqc3VnYXJzLCBkYXRhID0gQ2VyZWFsMykNCnN1bW1hcnkoY3Bvb2xpbmc0KQ0KYGBgDQoNCkluIHRoZSBsYXN0IGNvbXBsZXRlIHBvb2xpbmcgbW9kZWwgd2Ugc2VlIHRoYXQgb24gdGhlaXIgb3duIGNhbG9yaWVzIGFuZCBzdWdhciBhbW91bnRzIGFyZSBzdGlsbCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGF0IGEgOTklIGNvbmZpZGVuY2UgbGV2ZWwsIGhvd2V2ZXIgdGhlIGludGVyYWN0aW9uIGJldHdlZW4gdGhlIHR3byBpbmRlcGVkZW50IHZhcmlhYmxlcyBpcyBvbmx5IHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgYXQgYSA5NSUgY29uZmlkZW5jZSBsZXZlbC4NCg0KDQojIyNDb21wYXJpbmcgdGhlIDQgY29tcGxldGUgcG9vbGluZyBtb2RlbHMNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2FzaXMnfQ0KaHRtbHJlZyhsaXN0KGNwb29saW5nLGNwb29saW5nMiwgY3Bvb2xpbmczLCBjcG9vbGluZzQpLCBjYXB0aW9uLmFib3ZlID0gVFJVRSwgY2FwdGlvbiA9ICJDb21wYXJpbmcgdGhlIE1vZGVscyIpDQpgYGANCg0KV2hlbiB3ZSBjb21wYXJlIHRoZSBmb3VyIGNvbXBsZXRlIHBvb2xpbmcgbW9kZWxzIHdlIHNlZSB0aGF0IHRoZSBmb3VydGggbW9kZWwgaXMgdGhlIGJlc3QgZml0dGluZyBtb2RlbCB3aXRoIGFuIFJeMl4gb2YgMC43MiAod2hpY2ggaXMgdGhlIGhpZ2hlc3QgYW1vbmdzdCB0aGUgdGhyZWUgbW9kZWxzKS4NCg0KIyMjIE5vIFBvb2xpbmcgTW9kZWwNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0V9DQpkY29lZiA8LSBDZXJlYWwzICU+JSANCiAgICBncm91cF9ieShuX21hbnVmYWN0dXJlcikgJT4lIA0KICAgIGRvKG1vZCA9IGxtKHJhdGluZyB+IGNhbG9yaWVzICsgc3VnYXJzLCBkYXRhID0gLikpDQpjb2VmIDwtIGRjb2VmICU+JSBkbyhkYXRhLmZyYW1lKGludGMgPSBjb2VmKC4kbW9kKVsxXSkpDQpnZ3Bsb3QoY29lZiwgYWVzKHggPSBpbnRjKSkgKyBnZW9tX2hpc3RvZ3JhbSgpDQpgYGANCg0KTm93IHdlIHVzZSB0aGUgTm8gcG9vbGluZyBtb2RlbCB0byBsb29rIGF0IG1hbnVmYWN0dXJlciBkaWZmZXJlbmNlcyBpbiByYXRpbmdzLiBXZSBzZWUgdGhhdCBsYXJnZSBkaWZmZXJlbmNlcyBpbiBjZXJlYWwgcmF0aW5ncyBhbW9uZyBkaWZmZXJlbnQgbWFudWZhY3R1cmVycy4gVGhlIGRpc3RyaWJ1dGlvbiBsb29rcyBzb21ld2hhdCBub3JtYWxseSBkaXN0cmlidXRlZC4gDQoNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0V9DQpkY29lZiA8LSBDZXJlYWwzICU+JSANCiAgICBncm91cF9ieShuX21hbnVmYWN0dXJlcikgJT4lIA0KICAgIGRvKG1vZCA9IGxtKHJhdGluZyB+IGNhbG9yaWVzLCBkYXRhID0gLikpDQpjb2VmIDwtIGRjb2VmICU+JSBkbyhkYXRhLmZyYW1lKGNhbG9yaWVzID0gY29lZiguJG1vZClbMl0pKQ0KZ2dwbG90KGNvZWYsIGFlcyh4ID0gY2Fsb3JpZXMpKSArIGdlb21faGlzdG9ncmFtKCkNCmBgYA0KDQpXaGVuIGxvb2tpbmcgYXQgcmF0aW5nIGRpZmZlcmVuY2VzIHdpdGggcmVzcGVjdCB0byBjYWxvcmllcyB3ZSBub3cgc2VlIGEgc2xpZ2h0bHkgcmlnaHQgc2tld2VkIGRpc3RyaWJ1dGlvbiBhcyB0aGUgbnVtYmVyIG9mIGNhbG9yaWVzIGluY3JlYXNlLg0KDQojIyNSYW5kb20gSW50ZXJjZXB0IE1vZGVsDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRX0NCm0xX2NyYXRpbmcgPC0gbG1lKHJhdGluZyB+IGNhbG9yaWVzLCBkYXRhID0gQ2VyZWFsMywgcmFuZG9tID0gfjF8bl9tYW51ZmFjdHVyZXIsIG1ldGhvZCA9ICJNTCIpDQpzdW1tYXJ5KG0xX2NyYXRpbmcpDQpgYGANCg0KIyMjUmFuZG9tIHNsb3BlIE1vZGVsDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQ0KbTJfY3JhdGluZyA8LSBsbWUocmF0aW5nIH4gIHN1Z2FycywgZGF0YSA9IENlcmVhbDMsIHJhbmRvbSA9IH4xfG5fbWFudWZhY3R1cmVyLCBtZXRob2QgPSAiTUwiKQ0Kc3VtbWFyeShtMl9jcmF0aW5nKQ0KYGBgDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQ0KbTNfY3JhdGluZyA8LSBsbWUocmF0aW5nIH4gY2Fsb3JpZXMgKyBzdWdhcnMsIGRhdGEgPSBDZXJlYWwzLCByYW5kb20gPSB+MXxuX21hbnVmYWN0dXJlciwgbWV0aG9kID0gIk1MIikNCnN1bW1hcnkobTNfY3JhdGluZykNCmBgYA0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRX0NCm00X2NyYXRpbmcgPC0gbG1lKHJhdGluZyB+IGNhbG9yaWVzKnN1Z2FycywgZGF0YSA9IENlcmVhbDMsIHJhbmRvbSA9IH4gc3VnYXJzfG5fbWFudWZhY3R1cmVyLCBtZXRob2QgPSAiTUwiKQ0Kc3VtbWFyeShtNF9jcmF0aW5nKQ0KYGBgDQoNCg0KIyMjRmluYWwgTW9kZWwgQ29tcGFyaXNvbg0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRSwgcmVzdWx0cz0nYXNpcyd9DQpodG1scmVnKGxpc3QobTFfY3JhdGluZywgbTJfY3JhdGluZywgbTNfY3JhdGluZywgbTRfY3JhdGluZyksIGNhcHRpb24uYWJvdmUgPSBUUlVFLCBjYXB0aW9uID0gIkNvbXBhcmluZyB0aGUgTW9kZWxzIikNCmBgYA0KDQoNCg0KDQpDb21wYXJpbmcgdGhlIG1vZGVscywgd2Ugc2VlIHRoYXQgdGhlIGxhc3QgbW9kZWwgdGhhdCBhY2NvdW50cyBmb3IgbWFudWZhY3R1cmVyIGRpZmZlcmVuY2VzIGlzIHRoZSBiZXN0IGZpdCBtb2RlbCBzaW5jZSBpdCBoYXMgdGhlIGxvd2VzdCBBSUMgYW5kIEJJQyAod2l0aCA1MTguMTkgYW5kIDUzNi45NCwgcmVzcGVjdGl2ZWx5KS4gTG9va2luZyBhdCB0aGUgbTRfY3JhdGluZyBtb2RlbCB3ZSBzZWUgdGhhdCB0aGVyZSBpcyBhIGRpZmZlcmVuY2Ugb2YgNS40NCBpbiBjZXJlYWwgcmF0aW5ncyB3aGVuIGtlZXBpbmcgdGhlIGFtb3VuZyBvZiBzdWdhcnMgY29uc3RhbnQgYXQgdGhlIGhpZ2hlci1sZXZlbCAobWFudWZhY3R1cmVyIGxldmVsKS4gV2UgYWxzbyBzZWUgdGhhdCB0aGVyZSBpcyBhIDUuNzIgcmF0aW5nIGRpZmZlcmVuY2UgYWZ0ZXIga2VlcGluZyBjZXJlYWwgbWFudWZhY3R1cmVyIGFuZCBzdWdhciBhbW91bnQgY29uc3RhbnQuDQoNCg0KIyMjQmlibGlvZ3JhcGh5DQoNCg0KDQoNCg0KDQo=