Objectives:

For this lab you should…

Part 1: Getting ready to use data

The following packages will need to be loaded into R before you begin the lab. To run a chunk of R code, click the green arrow symbol in the upper right of the gray chunk. If you would like to run line by line, hit Ctrl-Enter with your cursor next to the desired line.

The Happiness Data

The happiness data set is from the 2021 World Happiness Report https://Worldhappiness.report/ed/2021. Each observation in this dataset represents a country in the world. There are 14 variables observed about citizens opinions on their countries, characteristics of their countries, and Covid-19 related summaries. A multitude of interesting questions can be posed (and answered!) using these data.

TASK 1.0 Download the dataset WorldHappiness.csv from the Lab 1.1 assignment page. Once you’ve downloaded it, using the following code to read it into R:

TASK 1.1 To ensure that you have successfully loaded the dataset, you can check using the function head(DataSetName), which displays the first six rows of the data, and glimpse(DataSetName), which provides a summary of the data frame.

Rows: 148
Columns: 15
$ Name                    <chr> "United States", "Egypt", "Morocco", "Lebanon", "Saudi Arabia", "…
$ Region                  <chr> "North America and ANZ", "Middle East and North Africa", "Middle …
$ HappinessScore          <dbl> 6.951, 4.283, 4.918, 4.584, 6.494, 4.395, 4.948, 4.934, 5.345, 5.…
$ Population2019          <dbl> 328.239523, 100.388073, 36.471769, 6.855713, 34.268528, 10.101694…
$ CovidDeaths2020         <dbl> 104.451, 7.457, 20.016, 21.508, 17.875, 37.577, 24.758, 4.607, 8.…
$ MedianAge               <dbl> 38.3, 25.3, 29.6, 31.1, 31.9, 23.2, 31.6, 23.5, 29.3, 27.5, 40.8,…
$ FemaleGovBoss           <chr> "No", "No", "No", "No", "No", "No", "No", "No", "No", "Yes", "No"…
$ InstitutionalTrust      <dbl> 0.250, 0.446, 0.397, 0.107, 0.651, 0.465, 0.295, 0.277, 0.561, 0.…
$ ExcessDeaths            <dbl> 179.220, NA, NA, NA, NA, NA, NA, NA, NA, NA, 133.313, 106.597, 73…
$ LogGDP                  <dbl> 11.023, 9.367, 8.903, 9.626, 10.743, 9.182, 10.240, 8.458, 9.365,…
$ SocialSupport           <dbl> 0.920, 0.750, 0.560, 0.848, 0.891, 0.767, 0.822, 0.651, 0.811, 0.…
$ HealthyLifeExpectancy   <dbl> 68.200, 61.998, 66.208, 67.355, 66.603, 67.000, 67.199, 58.709, 6…
$ Freedom                 <dbl> 0.837, 0.749, 0.774, 0.525, 0.877, 0.755, 0.576, 0.726, 0.873, 0.…
$ PerceptionsOfCorruption <dbl> 0.698, 0.795, 0.801, 0.898, 0.684, 0.705, 0.776, 0.787, 0.867, 0.…
$ Island                  <chr> "No", "No", "No", "No", "No", "No", "No", "No", "Yes", "No", "Yes…

TASK 1.2 Use your results from Task 1.1 to determine which columns are categorical data, and which are numeric:

**Response**

Categorical: Name, Region, FemaleGovBoss, Island

Numeric: HappinessScore, Population2019, CovidDeaths2020, MedianAge, InstitutionalTrust, ExcessDeaths, LogGDP, SocialSupport, HealthyLifeExpectancy, Freedom, PerceptionsOfCorruption

Model-centric approach to R

For the purposes of our class, it’s useful to learn a model-centric approach to R. The psuedo-code below is going to be our foundation for the rest of the class:

function( Y ~ X, data = DataSetName )

Here’s a short description of each part in the pseudo-code above:

  • function is an R function that dictates something you want to do with your data e.g. 
    • for example, mean calculates the mean
  • Y is the outcome of interest (response variable)
  • X is some explanatory variable or you can use “1” as a placeholder if there is no explanatory variable
  • DataSetName is the name of a data set loaded into the R environment

A summary of the most commonly used functions for this class are provided at the bottom of this document. In the work below you will be introduced to the functions and their uses one at a time in the context of answering research questions.

Research Question A: Are different regions of the world happier?

To use the data to answer the research question, we could find data summaries such as average happiness, for each of the regions. In this situation, HappinessScore is our response variable and Region is our explanatory variable.

TASK 2.1 Modify and run the code below to calculate the mean HappinessScore for each region.

        Central and Eastern Europe Commonwealth of Independent States 
                          5.984765                           5.467000 
                         East Asia        Latin America and Caribbean 
                          5.810333                           5.908050 
      Middle East and North Africa              North America and ANZ 
                          5.219765                           7.128500 
                        South Asia                     Southeast Asia 
                          4.441857                           5.407556 
                Sub-Saharan Africa                     Western Europe 
                          4.499800                           6.914905 

TASK 2.2 Use the function ‘favstats()’, and model-centric syntax, to determine which region has the country with the highest happiness score.

**Response: WesternEurope**

TASK 2.3 Which summary statistics are calculated by the favstats() function?

**Response: min, Q1, median, Q3, max, mean, n, missing**

Now it’s time to visualize the distribution of Happiness Score for the different reasons.

TASK 2.4 Modify the code below to create a histogram of Happiness Score, without accounting for other variables. What is the shape of the distribution: left-skewed, right-skewed, or roughly symmetric?

**Response: Roughly Symmetric**

TASK 2.5 Generate side-by-side boxplots of the HappinessScore, separated by Region. Write a sentence about what you observe in the figure.

**Response: First World countries report significantly higher Happiness Scores than countries in the second and third world, on average.**

TASK 2.6 Based on everything you’ve learned, do you think that happiness scores vary by region?

**Response: Based on the box plot above, happiness scores appear to vary by region because many of the boxes do not overlap or have little overlap.**

Research Question B: Are countries run by female leaders happier?

TASK 3.1 Write and run code to determine whether the mean Happiness Score is higher or lower for countries with female leaders. Hint: the variable ‘FemaleGovBoss’ indicates whether a country is run by a female leader.

**Response:There appears to be association between having a female leader and reporting a higher happiness score, as the mean happiness score for countries with female leaders is higher than countries without them. However, the Q1 for both cases is very similar, and the Q3 values are not far apart either, which leads me to think there may not be direct causation between the two variables.**

TASK 3.2 How many countries are governed by female leaders? You can tabulate observations of a categorical variable using the ‘tally’ command. Modify the code below to answer the question.

**Response:22**
FemaleGovBoss
 No Yes 
126  22 

TASK 3.3 Create an appropriate visual summary to investigate research question B.

TASK 3.4 Based on what you learned in tasks 3.1 and 3.3, what do you think the answer to research question B would be?

**Response: I think the answer to the question would be that having a higher happiness score is associated with and may even be directly caused by having a female leader. The whisker on the boxplot above for countries without a female leader extends significantly lower than that of countries with female leaders, and the median happiness score for countries with female leaders is significantly higher than that of countries without them, which point towards having female leaders being a positive factor of happiness.**

Research Question C: Are Island nations more likely to have female leaders?

TASK 4.1 Use R tally up how many countries are islands with female leaders, islands are male leaders, not islands with female leaders, and not islands with male leaders. Modify the code below to extract the numbers.

      FemaleGovBoss
Island  No Yes
   No  109  19
   Yes  17   3

For a research question like this one that involves two binary variables, it is useful to calculate and compare two proportions:

TASK 4.2 What proportion of Island Nations have female leaders? You should calculate (# island nations with female leaders)/(# island nations)

**Response: 15%**

TASK 4.3 What proportion of non-Island Nations have female leaders? You should calculate (# non-island nations with female leaders)/(# non-island nations)

**Response: 17.4%**

To visualize the data as it relates to this question, you should make side-by-side or stacked barcharts.

TASK 4.4 Modify the code below to create a side by side barchart. Notice the syntax is a little different; you should try different options for X and Y until you have Islands on the bottom and different colors for FemaleGovBoss.

TASK 4.5 Based on your answers to Tasks 4.1–4.4, what do you think the answer to research question C would be?

**Response: Based on the bar graph above, whether or not a country is an island does not appear to affect the likelihood of it having a female leader, as the proportion of male to female leaders for both island and non-island countries appears very similar.**

Epilogue

Below are some summaries you can reference at any time.

Numerical summaries

The primary numerical summaries used in this course include the mean, the five-number summary, and the standard deviation. The functions below calculate these summaries for a single variable, or for that variable based on the value of a second categorical variable.

  • mean(~ Y, data = DataSetName) # mean of Y without considering other variables
  • mean(Y ~ X, data = DataSetName) # mean of Y for different values of X
  • sd(~ Y, data = DataSetName) # standard deviation of Y
  • sd(Y ~ X, data = DataSetName) # standard deviation of Y for different values of X
  • favstats(~ Y, data = DataSetName) # summary statistics of Y
  • favstats(Y ~ X, data = DataSetName) # summary statistics of Y for different values of X

Visual summaries

The primary graphical representations used in this course will be a barcharts, boxplots, histograms and scatterplots. Each plot helps to visualize different aspects of a dataset.

The functions that will be used to generate these plots are:

  • gf_boxplot(Y ~ X, data = DataSetName) # boxplot of Y for each value of X, if specified
  • gf_histogram(~Y, data = DataSetName) # histogram of Y
  • gf_point(Y ~ X, data = DataSetName) # scatterplot of Y versus X
  • gf_bar( ~Y, data = DataSetName) # Bar chart for a single variable
  • gf_bar( ~ X, fill = ~ Y, data = DataSetName, position = position_dodge()) # side-by-side bar chart
  • gf_bar( ~ X, fill = ~ Y, data = DataSetName) # stacked bar chart
LS0tDQp0aXRsZTogJ0xhYiAxLTI6IFVzaW5nIFIgTWFya2Rvd24gdG8gZXhwbG9yZSBkYXRhJw0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KDQojIyMgT2JqZWN0aXZlczoNCg0KRm9yIHRoaXMgbGFiIHlvdSBzaG91bGQuLi4NCg0KICAtIFJlYWQgZGF0YXNldHMgaW50byBSDQogIC0gRmFtaWxpYXJpemUgeW91cnNlbGYgd2l0aCBjb21tb25seSB1c2VkIGZ1bmN0aW9ucyBhbmQgbW9kZWwtY2VudHJpYyBzeW50YXggaW4gUg0KICAtIFByb3ZpZGUgc3VtbWFyeSBzdGF0aXN0aWNzIG9mIGEgZGF0YXNldA0KICAtIHZpc3VhbGl6ZSB0aGUgZGF0YXNldCB1c2luZyBoaXN0b2dyYW1zIGFuZCBib3hwbG90cyANCiANCg0KIyBQYXJ0IDE6IEdldHRpbmcgcmVhZHkgdG8gdXNlIGRhdGENCg0KVGhlIGZvbGxvd2luZyBwYWNrYWdlcyB3aWxsIG5lZWQgdG8gYmUgbG9hZGVkIGludG8gUiBiZWZvcmUgeW91IGJlZ2luIHRoZSBsYWIuIFRvIHJ1biBhIGNodW5rIG9mIFIgY29kZSwgY2xpY2sgdGhlIGdyZWVuIGFycm93IHN5bWJvbCBpbiB0aGUgdXBwZXIgcmlnaHQgb2YgdGhlIGdyYXkgY2h1bmsuIElmIHlvdSB3b3VsZCBsaWtlIHRvIHJ1biBsaW5lIGJ5IGxpbmUsIGhpdCBDdHJsLUVudGVyIHdpdGggeW91ciBjdXJzb3IgbmV4dCB0byB0aGUgZGVzaXJlZCBsaW5lLg0KDQpgYGB7ciwgZWNobyA9IEYsIG1lc3NhZ2UgPSBGfQ0KIyMgIE5PVEUgLSBpbiBhbGwgZnV0dXJlIGRvY3VtZW50cy9hc3NpZ25tZW50cyB0aGlzIGNvZGUgd2lsbCBiZSBpbmNsdWRlZCBmb3IgeW91IGFuZCB5b3UgYXJlIGV4cGVjdGVkIHRvIHJ1biBpdCB3aXRob3V0IHByb21wdGluZy4NCg0KDQojIENsZWFyIFdvcmtzcGFjZQ0Kcm0obGlzdCA9IGxzKCkpIA0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG89RkFMU0UpDQoNCiMgbG9hZCBwYWNrYWdlcyB3ZSB0eXBpY2FsbHkgdXNlIGZvciB0aGlzIGNsYXNzLg0KbGlicmFyeShtb3NhaWMsIHdhcm4uY29uZmxpY3RzID0gRkFMU0UpIA0KbGlicmFyeShnZ2Zvcm11bGEsIHdhcm4uY29uZmxpY3RzID0gRkFMU0UpDQoNCg0KYGBgDQoNCiMjIyBUaGUgSGFwcGluZXNzIERhdGENCg0KVGhlIGhhcHBpbmVzcyBkYXRhIHNldCBpcyBmcm9tIHRoZSAyMDIxIFdvcmxkIEhhcHBpbmVzcyBSZXBvcnQgPGh0dHBzOi8vV29ybGRoYXBwaW5lc3MucmVwb3J0L2VkLzIwMjE+LiAgRWFjaCBvYnNlcnZhdGlvbiBpbiB0aGlzIGRhdGFzZXQgcmVwcmVzZW50cyBhIGNvdW50cnkgaW4gdGhlIHdvcmxkLiBUaGVyZSBhcmUgMTQgdmFyaWFibGVzIG9ic2VydmVkIGFib3V0IGNpdGl6ZW5zIG9waW5pb25zIG9uIHRoZWlyIGNvdW50cmllcywgY2hhcmFjdGVyaXN0aWNzIG9mIHRoZWlyIGNvdW50cmllcywgYW5kIENvdmlkLTE5IHJlbGF0ZWQgc3VtbWFyaWVzLiAgQSBtdWx0aXR1ZGUgb2YgaW50ZXJlc3RpbmcgcXVlc3Rpb25zIGNhbiBiZSBwb3NlZCAoYW5kIGFuc3dlcmVkISkgdXNpbmcgdGhlc2UgZGF0YS4NCg0KKipUQVNLIDEuMCoqIERvd25sb2FkIHRoZSBkYXRhc2V0IFdvcmxkSGFwcGluZXNzLmNzdiBmcm9tIHRoZSBMYWIgMS4xIGFzc2lnbm1lbnQgcGFnZS4gT25jZSB5b3UndmUgZG93bmxvYWRlZCBpdCwgdXNpbmcgdGhlIGZvbGxvd2luZyBjb2RlIHRvIHJlYWQgaXQgaW50byBSOg0KDQpgYGB7cixlY2hvID0gRn0NCiMgVGhlIGNvZGUgYmVsb3cgcmVhZHMgaW4gdGhlIGRhdGEgYXMgYSBkYXRhZnJhbWUgYW5kIHN0b3JlcyBpdCBpbiBSIHVzaW5nIHRoZSBuYW1lICdIYXAnDQoNCkhhcCA8LSByZWFkLmNzdihmaWxlLmNob29zZSgpKSAjc2VsZWN0IHlvdXIgZmlsZSBpbiBpdHMgc2F2ZWQgbG9jYXRpb24gd2hlbiB0aGUgcHJvbXB0IG9wZW5zDQoNCmBgYA0KDQoqKlRBU0sgMS4xKiogVG8gZW5zdXJlIHRoYXQgeW91IGhhdmUgc3VjY2Vzc2Z1bGx5IGxvYWRlZCB0aGUgZGF0YXNldCwgeW91IGNhbiBjaGVjayB1c2luZyB0aGUgZnVuY3Rpb24gaGVhZChEYXRhU2V0TmFtZSksIHdoaWNoIGRpc3BsYXlzIHRoZSBmaXJzdCBzaXggcm93cyBvZiB0aGUgZGF0YSwgYW5kIGdsaW1wc2UoRGF0YVNldE5hbWUpLCB3aGljaCBwcm92aWRlcyBhIHN1bW1hcnkgb2YgdGhlIGRhdGEgZnJhbWUuDQoNCmBgYHtyLGVjaG8gPSBGfQ0KIyBtb2RpZnkgdGhlIGNvZGUgYmVsb3cNCg0KaGVhZChIYXApICMgZGlzcGxheXMgdGhlIGZpcnN0IDYgcm93cyBvZiB0aGUgZGF0YXNldCwgaW5jbHVkaW5nIGhlYWRlcnMgDQpnbGltcHNlKEhhcCkgIyBwcm92aWRlcyBhIHN1bW1hcnkgb2YgdGhlIGRhdGEgZnJhbWUNCg0KYGBgDQoNCg0KKipUQVNLIDEuMioqIFVzZSB5b3VyIHJlc3VsdHMgZnJvbSBUYXNrIDEuMSB0byBkZXRlcm1pbmUgd2hpY2ggY29sdW1ucyBhcmUgY2F0ZWdvcmljYWwgZGF0YSwgYW5kIHdoaWNoIGFyZSBudW1lcmljOg0KDQogICAgKipSZXNwb25zZSoqDQoNCiAgICBDYXRlZ29yaWNhbDogTmFtZSwgUmVnaW9uLCBGZW1hbGVHb3ZCb3NzLCBJc2xhbmQNCiAgICANCiAgICBOdW1lcmljOiBIYXBwaW5lc3NTY29yZSwgUG9wdWxhdGlvbjIwMTksIENvdmlkRGVhdGhzMjAyMCwgTWVkaWFuQWdlLCBJbnN0aXR1dGlvbmFsVHJ1c3QsIEV4Y2Vzc0RlYXRocywgTG9nR0RQLCBTb2NpYWxTdXBwb3J0LCBIZWFsdGh5TGlmZUV4cGVjdGFuY3ksIEZyZWVkb20sIFBlcmNlcHRpb25zT2ZDb3JydXB0aW9uDQogDQoNCiMjIyBNb2RlbC1jZW50cmljIGFwcHJvYWNoIHRvIFINCg0KRm9yIHRoZSBwdXJwb3NlcyBvZiBvdXIgY2xhc3MsIGl0J3MgdXNlZnVsIHRvIGxlYXJuIGEgbW9kZWwtY2VudHJpYyBhcHByb2FjaCB0byBSLiAgVGhlIHBzdWVkby1jb2RlIGJlbG93IGlzIGdvaW5nIHRvIGJlIG91ciBmb3VuZGF0aW9uIGZvciB0aGUgcmVzdCBvZiB0aGUgY2xhc3M6IA0KDQpgZnVuY3Rpb24oIFkgfiBYLCBkYXRhID0gRGF0YVNldE5hbWUgKWANCg0KSGVyZSdzIGEgc2hvcnQgZGVzY3JpcHRpb24gb2YgZWFjaCBwYXJ0IGluIHRoZSBwc2V1ZG8tY29kZSBhYm92ZToNCg0KLSBgZnVuY3Rpb25gIGlzIGFuIFIgZnVuY3Rpb24gdGhhdCBkaWN0YXRlcyBzb21ldGhpbmcgeW91IHdhbnQgdG8gZG8gd2l0aCB5b3VyIGRhdGEgZS5nLiANCiAgICAtIGZvciBleGFtcGxlLCBgbWVhbmAgY2FsY3VsYXRlcyB0aGUgbWVhbg0KLSBgWWAgaXMgdGhlIG91dGNvbWUgb2YgaW50ZXJlc3QgKHJlc3BvbnNlIHZhcmlhYmxlKSAgDQotIGBYYCBpcyBzb21lIGV4cGxhbmF0b3J5IHZhcmlhYmxlIG9yIHlvdSBjYW4gdXNlICIxIiBhcyBhIHBsYWNlaG9sZGVyIGlmIHRoZXJlIGlzIG5vIGV4cGxhbmF0b3J5IHZhcmlhYmxlICANCi0gYERhdGFTZXROYW1lYCBpcyB0aGUgbmFtZSBvZiBhIGRhdGEgc2V0IGxvYWRlZCBpbnRvIHRoZSBSIGVudmlyb25tZW50DQoNCkEgc3VtbWFyeSBvZiB0aGUgbW9zdCBjb21tb25seSB1c2VkIGZ1bmN0aW9ucyBmb3IgdGhpcyBjbGFzcyBhcmUgcHJvdmlkZWQgYXQgdGhlIGJvdHRvbSBvZiB0aGlzIGRvY3VtZW50LiAgSW4gdGhlIHdvcmsgYmVsb3cgeW91IHdpbGwgYmUgaW50cm9kdWNlZCB0byB0aGUgZnVuY3Rpb25zIGFuZCB0aGVpciB1c2VzIG9uZSBhdCBhIHRpbWUgaW4gdGhlIGNvbnRleHQgb2YgYW5zd2VyaW5nIHJlc2VhcmNoIHF1ZXN0aW9ucy4NCg0KIyMgUmVzZWFyY2ggUXVlc3Rpb24gQTogQXJlIGRpZmZlcmVudCByZWdpb25zIG9mIHRoZSB3b3JsZCBoYXBwaWVyPw0KDQpUbyB1c2UgdGhlIGRhdGEgdG8gYW5zd2VyIHRoZSByZXNlYXJjaCBxdWVzdGlvbiwgd2UgY291bGQgZmluZCBkYXRhIHN1bW1hcmllcyBzdWNoIGFzIGF2ZXJhZ2UgaGFwcGluZXNzLCBmb3IgZWFjaCBvZiB0aGUgcmVnaW9ucy4gIEluIHRoaXMgc2l0dWF0aW9uLCBIYXBwaW5lc3NTY29yZSBpcyBvdXIgcmVzcG9uc2UgdmFyaWFibGUgYW5kIFJlZ2lvbiBpcyBvdXIgZXhwbGFuYXRvcnkgdmFyaWFibGUuDQoNCioqVEFTSyAyLjEqKiBNb2RpZnkgYW5kIHJ1biB0aGUgY29kZSBiZWxvdyB0byBjYWxjdWxhdGUgdGhlIG1lYW4gSGFwcGluZXNzU2NvcmUgZm9yIGVhY2ggcmVnaW9uLg0KDQpgYGB7cixlY2hvID0gRn0NCg0KbWVhbihIYXBwaW5lc3NTY29yZSB+IFJlZ2lvbiwgZGF0YSA9IEhhcCkNCg0KYGBgDQoNCioqVEFTSyAyLjIqKiAgVXNlIHRoZSBmdW5jdGlvbiAnZmF2c3RhdHMoKScsIGFuZCBtb2RlbC1jZW50cmljIHN5bnRheCwgdG8gZGV0ZXJtaW5lIHdoaWNoIHJlZ2lvbiBoYXMgdGhlIGNvdW50cnkgd2l0aCB0aGUgaGlnaGVzdCBoYXBwaW5lc3Mgc2NvcmUuDQoNCiAgICAqKlJlc3BvbnNlOiBXZXN0ZXJuRXVyb3BlKioNCiAgDQpgYGB7ciwgZWNobyA9IEZ9DQoNCmZhdnN0YXRzKEhhcHBpbmVzc1Njb3JlIH4gUmVnaW9uLCBkYXRhID0gSGFwKQ0KDQpgYGANCg0KKipUQVNLIDIuMyoqIFdoaWNoIHN1bW1hcnkgc3RhdGlzdGljcyBhcmUgY2FsY3VsYXRlZCBieSB0aGUgZmF2c3RhdHMoKSBmdW5jdGlvbj8NCg0KICAgICoqUmVzcG9uc2U6IG1pbiwgUTEsIG1lZGlhbiwgUTMsIG1heCwgbWVhbiwgbiwgbWlzc2luZyoqDQoNCk5vdyBpdCdzIHRpbWUgdG8gdmlzdWFsaXplIHRoZSBkaXN0cmlidXRpb24gb2YgSGFwcGluZXNzIFNjb3JlIGZvciB0aGUgZGlmZmVyZW50IHJlYXNvbnMuICANCg0KKipUQVNLIDIuNCoqIE1vZGlmeSB0aGUgY29kZSBiZWxvdyB0byBjcmVhdGUgYSBoaXN0b2dyYW0gb2YgSGFwcGluZXNzIFNjb3JlLCB3aXRob3V0IGFjY291bnRpbmcgZm9yIG90aGVyIHZhcmlhYmxlcy4gIFdoYXQgaXMgdGhlIHNoYXBlIG9mIHRoZSBkaXN0cmlidXRpb246IGxlZnQtc2tld2VkLCByaWdodC1za2V3ZWQsIG9yIHJvdWdobHkgc3ltbWV0cmljPw0KDQogICAgKipSZXNwb25zZTogUm91Z2hseSBTeW1tZXRyaWMqKg0KYGBge3IsZWNobyA9IEZ9DQoNCmdmX2hpc3RvZ3JhbSh+IEhhcHBpbmVzc1Njb3JlLCBkYXRhID0gSGFwKQ0KDQpgYGANCg0KKipUQVNLIDIuNSoqIEdlbmVyYXRlIHNpZGUtYnktc2lkZSBib3hwbG90cyBvZiB0aGUgSGFwcGluZXNzU2NvcmUsIHNlcGFyYXRlZCBieSBSZWdpb24uIFdyaXRlIGEgc2VudGVuY2UgYWJvdXQgd2hhdCB5b3Ugb2JzZXJ2ZSBpbiB0aGUgZmlndXJlLg0KDQogICAgKipSZXNwb25zZTogRmlyc3QgV29ybGQgY291bnRyaWVzIHJlcG9ydCBzaWduaWZpY2FudGx5IGhpZ2hlciBIYXBwaW5lc3MgU2NvcmVzIHRoYW4gY291bnRyaWVzIGluIHRoZSBzZWNvbmQgYW5kIHRoaXJkIHdvcmxkLCBvbiBhdmVyYWdlLioqDQoNCmBgYHtyLGVjaG8gPSBGfQ0KZ2ZfYm94cGxvdChIYXBwaW5lc3NTY29yZSB+IFJlZ2lvbiwgZGF0YSA9IEhhcCkNCg0KIyBpZiB0aGUgYXhlcyBsYWJlbHMgYXJlbid0IHJlYWRhYmxlLCB0cnkgbW9kaWZ5aW5nIGFuZCBydW5uaW5nIHRoZSBjb2RlIGJlbG93IQ0KZ2ZfYm94cGxvdChIYXBwaW5lc3NTY29yZSB+IFJlZ2lvbiwgZGF0YSA9IEhhcCkgKyBjb29yZF9mbGlwKCkNCg0KYGBgDQoNCioqVEFTSyAyLjYqKiBCYXNlZCBvbiBldmVyeXRoaW5nIHlvdSd2ZSBsZWFybmVkLCBkbyB5b3UgdGhpbmsgdGhhdCBoYXBwaW5lc3Mgc2NvcmVzIHZhcnkgYnkgcmVnaW9uPw0KDQogICAgKipSZXNwb25zZTogQmFzZWQgb24gdGhlIGJveCBwbG90IGFib3ZlLCBoYXBwaW5lc3Mgc2NvcmVzIGFwcGVhciB0byB2YXJ5IGJ5IHJlZ2lvbiBiZWNhdXNlIG1hbnkgb2YgdGhlIGJveGVzIGRvIG5vdCBvdmVybGFwIG9yIGhhdmUgbGl0dGxlIG92ZXJsYXAuKioNCiAgICANCiAgICANCiMjIyMgUmVzZWFyY2ggUXVlc3Rpb24gQjogQXJlIGNvdW50cmllcyBydW4gYnkgZmVtYWxlIGxlYWRlcnMgaGFwcGllcj8NCg0KKipUQVNLIDMuMSoqIFdyaXRlIGFuZCBydW4gY29kZSB0byBkZXRlcm1pbmUgd2hldGhlciB0aGUgbWVhbiBIYXBwaW5lc3MgU2NvcmUgaXMgaGlnaGVyIG9yIGxvd2VyIGZvciBjb3VudHJpZXMgd2l0aCBmZW1hbGUgbGVhZGVycy4gIEhpbnQ6ICB0aGUgdmFyaWFibGUgJ0ZlbWFsZUdvdkJvc3MnIGluZGljYXRlcyB3aGV0aGVyIGEgY291bnRyeSBpcyBydW4gYnkgYSBmZW1hbGUgbGVhZGVyLg0KDQogICAgKipSZXNwb25zZTpUaGVyZSBhcHBlYXJzIHRvIGJlIGFzc29jaWF0aW9uIGJldHdlZW4gaGF2aW5nIGEgZmVtYWxlIGxlYWRlciBhbmQgcmVwb3J0aW5nIGEgaGlnaGVyIGhhcHBpbmVzcyBzY29yZSwgYXMgdGhlIG1lYW4gaGFwcGluZXNzIHNjb3JlIGZvciBjb3VudHJpZXMgd2l0aCBmZW1hbGUgbGVhZGVycyBpcyBoaWdoZXIgdGhhbiBjb3VudHJpZXMgd2l0aG91dCB0aGVtLiBIb3dldmVyLCB0aGUgUTEgZm9yIGJvdGggY2FzZXMgaXMgdmVyeSBzaW1pbGFyLCBhbmQgdGhlIFEzIHZhbHVlcyBhcmUgbm90IGZhciBhcGFydCBlaXRoZXIsIHdoaWNoIGxlYWRzIG1lIHRvIHRoaW5rIHRoZXJlIG1heSBub3QgYmUgZGlyZWN0IGNhdXNhdGlvbiBiZXR3ZWVuIHRoZSB0d28gdmFyaWFibGVzLioqDQoNCmBgYHtyLGVjaG8gPSBGfQ0KZmF2c3RhdHMoSGFwcGluZXNzU2NvcmUgfiBGZW1hbGVHb3ZCb3NzLCBkYXRhID0gSGFwKQ0KDQpgYGANCioqVEFTSyAzLjIqKiBIb3cgbWFueSBjb3VudHJpZXMgYXJlIGdvdmVybmVkIGJ5IGZlbWFsZSBsZWFkZXJzPyBZb3UgY2FuIHRhYnVsYXRlIG9ic2VydmF0aW9ucyBvZiBhIGNhdGVnb3JpY2FsIHZhcmlhYmxlIHVzaW5nIHRoZSAndGFsbHknIGNvbW1hbmQuICBNb2RpZnkgdGhlIGNvZGUgYmVsb3cgdG8gYW5zd2VyIHRoZSBxdWVzdGlvbi4NCg0KICAgICoqUmVzcG9uc2U6MjIqKg0KICAgIA0KYGBge3IsZWNobyA9IEZ9DQp0YWxseSggfiBGZW1hbGVHb3ZCb3NzLCBkYXRhID0gSGFwKQ0KYGBgDQoNCg0KKipUQVNLIDMuMyoqIENyZWF0ZSBhbiBhcHByb3ByaWF0ZSB2aXN1YWwgc3VtbWFyeSB0byBpbnZlc3RpZ2F0ZSByZXNlYXJjaCBxdWVzdGlvbiBCLg0KDQpgYGB7cixlY2hvID0gRn0NCmdmX2JveHBsb3QoSGFwcGluZXNzU2NvcmUgfiBGZW1hbGVHb3ZCb3NzLCBkYXRhID0gSGFwKQ0KDQpgYGANCg0KKipUQVNLIDMuNCoqIEJhc2VkIG9uIHdoYXQgeW91IGxlYXJuZWQgaW4gdGFza3MgMy4xIGFuZCAzLjMsIHdoYXQgZG8geW91IHRoaW5rIHRoZSBhbnN3ZXIgdG8gcmVzZWFyY2ggcXVlc3Rpb24gQiB3b3VsZCBiZT8NCg0KICAgICoqUmVzcG9uc2U6IEkgdGhpbmsgdGhlIGFuc3dlciB0byB0aGUgcXVlc3Rpb24gd291bGQgYmUgdGhhdCBoYXZpbmcgYSBoaWdoZXIgaGFwcGluZXNzIHNjb3JlIGlzIGFzc29jaWF0ZWQgd2l0aCBhbmQgbWF5IGV2ZW4gYmUgZGlyZWN0bHkgY2F1c2VkIGJ5IGhhdmluZyBhIGZlbWFsZSBsZWFkZXIuIFRoZSB3aGlza2VyIG9uIHRoZSBib3hwbG90IGFib3ZlIGZvciBjb3VudHJpZXMgd2l0aG91dCBhIGZlbWFsZSBsZWFkZXIgZXh0ZW5kcyBzaWduaWZpY2FudGx5IGxvd2VyIHRoYW4gdGhhdCBvZiBjb3VudHJpZXMgd2l0aCBmZW1hbGUgbGVhZGVycywgYW5kIHRoZSBtZWRpYW4gaGFwcGluZXNzIHNjb3JlIGZvciBjb3VudHJpZXMgd2l0aCBmZW1hbGUgbGVhZGVycyBpcyBzaWduaWZpY2FudGx5IGhpZ2hlciB0aGFuIHRoYXQgb2YgY291bnRyaWVzIHdpdGhvdXQgdGhlbSwgd2hpY2ggcG9pbnQgdG93YXJkcyBoYXZpbmcgZmVtYWxlIGxlYWRlcnMgYmVpbmcgYSBwb3NpdGl2ZSBmYWN0b3Igb2YgaGFwcGluZXNzLioqDQogICAgDQogICAgDQoNCiMjIFJlc2VhcmNoIFF1ZXN0aW9uIEM6IEFyZSBJc2xhbmQgbmF0aW9ucyBtb3JlIGxpa2VseSB0byBoYXZlIGZlbWFsZSBsZWFkZXJzPw0KDQoNCioqVEFTSyA0LjEqKiBVc2UgUiB0YWxseSB1cCBob3cgbWFueSBjb3VudHJpZXMgYXJlIGlzbGFuZHMgd2l0aCBmZW1hbGUgbGVhZGVycywgaXNsYW5kcyBhcmUgbWFsZSBsZWFkZXJzLCBub3QgaXNsYW5kcyB3aXRoIGZlbWFsZSBsZWFkZXJzLCBhbmQgbm90IGlzbGFuZHMgd2l0aCBtYWxlIGxlYWRlcnMuICBNb2RpZnkgdGhlIGNvZGUgYmVsb3cgdG8gZXh0cmFjdCB0aGUgbnVtYmVycy4NCg0KYGBge3IsIGVjaG8gPSBGfQ0KdGFsbHkoSXNsYW5kIH4gRmVtYWxlR292Qm9zcywgZGF0YSA9IEhhcCkNCmBgYA0KRm9yIGEgcmVzZWFyY2ggcXVlc3Rpb24gbGlrZSB0aGlzIG9uZSB0aGF0IGludm9sdmVzIHR3byBiaW5hcnkgdmFyaWFibGVzLCBpdCBpcyB1c2VmdWwgdG8gY2FsY3VsYXRlIGFuZCBjb21wYXJlIHR3byBwcm9wb3J0aW9uczoNCg0KKipUQVNLIDQuMioqICBXaGF0IHByb3BvcnRpb24gb2YgSXNsYW5kIE5hdGlvbnMgaGF2ZSBmZW1hbGUgbGVhZGVycz8gIFlvdSBzaG91bGQgY2FsY3VsYXRlICgjIGlzbGFuZCBuYXRpb25zIHdpdGggZmVtYWxlIGxlYWRlcnMpLygjIGlzbGFuZCBuYXRpb25zKQ0KDQogICAgKipSZXNwb25zZTogMTUlKioNCiAgICANCmBgYHtyfQ0KIyB5b3UgY2FuIHVzZSB0aGlzIFIgY2h1bmsgYXMgYSBjYWxjdWxhdG9yIGlmIG5lZWRlZA0KDQpgYGANCg0KICANCioqVEFTSyA0LjMqKiAgV2hhdCBwcm9wb3J0aW9uIG9mIG5vbi1Jc2xhbmQgTmF0aW9ucyBoYXZlIGZlbWFsZSBsZWFkZXJzPyBZb3Ugc2hvdWxkIGNhbGN1bGF0ZSAoIyBub24taXNsYW5kIG5hdGlvbnMgd2l0aCBmZW1hbGUgbGVhZGVycykvKCMgbm9uLWlzbGFuZCBuYXRpb25zKQ0KDQogICAgKipSZXNwb25zZTogMTcuNCUqKg0KICAgIA0KYGBge3J9DQojIHlvdSBjYW4gdXNlIHRoaXMgUiBjaHVuayBhcyBhIGNhbGN1bGF0b3IgaWYgbmVlZGVkDQoNCmBgYA0KDQpUbyB2aXN1YWxpemUgdGhlIGRhdGEgYXMgaXQgcmVsYXRlcyB0byB0aGlzIHF1ZXN0aW9uLCB5b3Ugc2hvdWxkIG1ha2Ugc2lkZS1ieS1zaWRlIG9yIHN0YWNrZWQgYmFyY2hhcnRzLg0KICANCioqVEFTSyA0LjQqKiAgTW9kaWZ5IHRoZSBjb2RlIGJlbG93IHRvIGNyZWF0ZSBhIHNpZGUgYnkgc2lkZSBiYXJjaGFydC4gIE5vdGljZSB0aGUgc3ludGF4IGlzIGEgbGl0dGxlIGRpZmZlcmVudDsgeW91IHNob3VsZCB0cnkgZGlmZmVyZW50IG9wdGlvbnMgZm9yIFggYW5kIFkgdW50aWwgeW91IGhhdmUgSXNsYW5kcyBvbiB0aGUgYm90dG9tIGFuZCBkaWZmZXJlbnQgY29sb3JzIGZvciBGZW1hbGVHb3ZCb3NzLg0KDQpgYGB7ciwgZWNobyA9IEZ9DQpnZl9iYXIofklzbGFuZCwgZmlsbCA9ICB+IEZlbWFsZUdvdkJvc3MsIGRhdGEgPSBIYXAsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoKSkNCmBgYA0KDQoqKlRBU0sgNC41KiogQmFzZWQgb24geW91ciBhbnN3ZXJzIHRvIFRhc2tzIDQuMS0tNC40LCB3aGF0IGRvIHlvdSB0aGluayB0aGUgYW5zd2VyIHRvIHJlc2VhcmNoIHF1ZXN0aW9uIEMgd291bGQgYmU/DQoNCiAgICAqKlJlc3BvbnNlOiBCYXNlZCBvbiB0aGUgYmFyIGdyYXBoIGFib3ZlLCB3aGV0aGVyIG9yIG5vdCBhIGNvdW50cnkgaXMgYW4gaXNsYW5kIGRvZXMgbm90IGFwcGVhciB0byBhZmZlY3QgdGhlIGxpa2VsaWhvb2Qgb2YgaXQgaGF2aW5nIGEgZmVtYWxlIGxlYWRlciwgYXMgdGhlIHByb3BvcnRpb24gb2YgbWFsZSB0byBmZW1hbGUgbGVhZGVycyBmb3IgYm90aCBpc2xhbmQgYW5kIG5vbi1pc2xhbmQgY291bnRyaWVzIGFwcGVhcnMgdmVyeSBzaW1pbGFyLioqDQoNCg0KIyMgUmVzZWFyY2ggUXVlc3Rpb24gRDogV2hpY2ggb2YgdGhlIHF1YW50aXRhdGl2ZSB2YXJpYWJsZXMgYXJlIHJlbGF0ZWQgdG8gSGFwcGluZXNzIFNjb3JlPw0KDQpUbyBhbnN3ZXIgdGhpcyBxdWVzdGlvbiwgd2UgY29uc2lkZXIgcGxvdHMgdGhhdCB2aXN1YWxpemUgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHR3byBxdWFudGl0YXRpdmUgdmFyaWFibGVzLiBBIHNjYXR0ZXJwbG90IGlzIHNpbXBseSBhbiAoeCx5KSBwbG90IGluIHRoZSBDYXJ0ZXNpYW4gcGxhbmUuIFVzaW5nIG91ciBZIH4gWCBmb3JtYXQsIHRoZSBZIHZhcmlhYmxlIHdpbGwgYmUgYWxvbmcgdGhlIFkgYXhpcy4gDQoNCioqVEFTSyA1LjEqKiBNb2RpZnkgdGhlIGNvZGUgYmVsb3cgdG8gZ2VuZXJhdGUgYSBzY2F0dGVycGxvdCBvZiB0aGUgSGFwcGluZXNzU2NvcmUgdmVyc3VzIHRoZSBJbnN0aXR1dGlvbmFsIFRydXN0Lg0KDQoNCmBgYHtyLGVjaG8gPSBGfQ0KZ2ZfcG9pbnQoSGFwcGluZXNzU2NvcmUgfiBJbnN0aXR1dGlvbmFsVHJ1c3QsIGRhdGEgPSBIYXApDQoNCmBgYA0KKipUQVNLIDUuMioqIFdyaXRlIGNvZGUgYW5kIHByb2R1Y2Ugc2NhdHRlcnBsb3RzIG9mIHRoZSBIYXBwaW5lc3NTY29yZSB2ZXJzdXM6IFNvY2lhbFN1cHBvcnQsIEhlYWx0aHlMaWZlRXhwZWN0YW5jeSwgYW5kIEZyZWVkb20uIA0KDQpgYGB7cixlY2hvID0gRn0NCmdmX3BvaW50KEhhcHBpbmVzc1Njb3JlIH4gU29jaWFsU3VwcG9ydCwgZGF0YSA9IEhhcCkNCmdmX3BvaW50KEhhcHBpbmVzc1Njb3JlIH4gSGVhbHRoeUxpZmVFeHBlY3RhbmN5LCBkYXRhID0gSGFwKQ0KZ2ZfcG9pbnQoSGFwcGluZXNzU2NvcmUgfiBGcmVlZG9tLCBkYXRhID0gSGFwKQ0KDQpgYGAgDQoNCioqVEFTSyA1LjMqKiAgQ29tbWVudCBvbiB3aGljaCBvZiB0aGUgZm91ciB2YXJpYWJsZXMgdGhhdCBoYXZlIGJlZW4gcGxvdHRlZCBzdWdnZXN0IGEgc3Ryb25nIGxpbmVhciByZWxhdGlvbnNoaXAgd2l0aCB0aGUgSGFwcGluZXNzIFNjb3JlLiANCg0KICAgICoqSGVhbHRoeSBMaWZlIEV4cGVjdGFuY3kgYW5kIFNvY2lhbCBTdXBwb3J0IGFwcGVhciB0byBoYXZlIHNvbWUgbGluZWFyIGNvcnJlbGF0aW9uIGJldHdlZW4gdGhlbXNlbHZlcyBhbmQgSGFwcGluZXNzIFNjb3JlLioqIA0KDQoqKlJlc3BvbnNlKiogDQoNCioqVEFTSyA1LjQqKiBDYWxjdWxhdGUgdGhlIGNvcnJlbGF0aW9uIGZvciBlYWNoIG9mIHRoZSBmb3VyIHZhcmlhYmxlIHBhaXJzIGFib3ZlLg0KDQogICAgKipSZXNwb25zZSoqIA0KICAgIA0KICAgIEhhcHBpbmVzc1Njb3JlIGFuZCBJbnN0aXR1dGlvbmFsVHJ1c3Q6IDAuMDcwOTQ0OA0KICAgIA0KICAgIEhhcHBpbmVzc1Njb3JlIGFuZCBTb2NpYWxTdXBwb3J0OiAwLjc1NzYxNDYNCiAgICANCiAgICBIYXBwaW5lc3NTY29yZSBhbmQgSGVhbHRoeUxpZmVFeHBlY3RhbmN5OiAwLjc2NjcyMzUNCiAgICANCiAgICBIYXBwaW5lc3NTY29yZSBhbmQgRnJlZWRvbTogMC42MDM4Njk5DQoNCmBgYHtyLCBlY2hvID0gRn0NCmNvcihIYXBwaW5lc3NTY29yZSB+IEluc3RpdHV0aW9uYWxUcnVzdCwgZGF0YSA9IEhhcCkNCmNvcihIYXBwaW5lc3NTY29yZSB+IFNvY2lhbFN1cHBvcnQsIGRhdGEgPSBIYXApDQpjb3IoSGFwcGluZXNzU2NvcmUgfiBIZWFsdGh5TGlmZUV4cGVjdGFuY3ksIGRhdGEgPSBIYXApDQpjb3IoSGFwcGluZXNzU2NvcmUgfiBGcmVlZG9tLCBkYXRhID0gSGFwKQ0KYGBgDQoNCg0KDQojIyBSZXNlYXJjaCBRdWVzdGlvbiBFOiBXaGljaCB2YXJpYWJsZXMgYXJlIHJlbGF0ZWQgdG8gQ292aWQgRGVhdGhzIDIwMjA/DQoNCkEgc3RyZW5ndGggb2YgUiBpcyBpdHMgYWJpbGl0eSB0byBxdWlja2x5IGFuZCBlYXNpbHkgcHJvZHVjZSBzb3BoaXN0aWNhdGVkIGRhdGEgdmlzdWFsaXphdGlvbnMuICBZb3Ugd2lsbCB1c2UgIGN1cmlvc2l0eSBhbmQgdG9vbHMgaW4gUiB0byBjcmVhdGUgdmlzdWFsaXphdGlvbnMgdGhhdCBleHBsb3JlIHRoaXMgcmVzZWFyY2ggcXVlc3Rpb24uDQoNClVzZSB0aGUgY29kZSBiZWxvdyB0byByZW1pbmQgeW91cnNlbGYgd2hpY2ggdmFyaWFibGVzIGFyZSBhdmFpbGFibGUgaW4gdGhpcyBkYXRhc2V0LiAgQ2hvb3NlIGEgcXVhbnRpdGF0aXZlIHZhcmlhYmxlIHRoYXQgeW91IHRoaW5rIHdpbGwgYmUgcmVsYXRlZCB0byBDb3ZpZERlYXRoczIwMjAuDQoNCioqVEFTSyA2LjEqKiBNYWtlIGEgc2NhdHRlcnBsb3QgdG8gZXhhbWluZSB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gQ292aWQgRGVhdGhzIGluIDIwMjAgYW5kIHRoZSB2YXJpYWJsZSB5b3UgY2hvc2UuIA0KYGBge3IsZWNobyA9IEZ9DQpnZl9wb2ludChDb3ZpZERlYXRoczIwMjAgfiBIZWFsdGh5TGlmZUV4cGVjdGFuY3ksIGRhdGEgPSBIYXApDQoNCmBgYCANCg0KKipUQVNLIDYuMioqIE5vdywgY29sb3IgdGhlIHBvaW50cyBpbiB5b3VyIHBsb3QgYmFzZWQgb24gdGhlIHZhbHVlcyBvZiBhIHRoaXJkIHZhcmlhYmxlIHN1Y2ggYXMgRmVtYWxlR292Qm9zcywgSXNsYW5kLCBvciBSZWdpb24uIFlvdSBjb3VsZCBhbHNvIGNob29zZSBhIHF1YW50aXRhdGl2ZSB2YXJpYWJsZSwgaWYgeW91IGRlc2lyZWQuDQoNCmBgYHtyLGVjaG8gPSBGfQ0KDQpnZl9wb2ludChDb3ZpZERlYXRoczIwMjAgfiBIZWFsdGh5TGlmZUV4cGVjdGFuY3ksIGNvbCA9IH4gSXNsYW5kLCBkYXRhID0gSGFwKQ0KDQoNCmBgYCANCioqVEFTSyA2LjMqKiBOb3cgd2UgY2FuIGFkZCBvbmUgbW9yZSBsYXllciwgYmFzZWQgb24gYSBjYXRlZ29yaWNhbCB2YXJpYWJsZS4gIENob29zZSBvbmUgb2YgdGhlIGJpbmFyeSB2YXJpYWJsZXMgRmVtYWxlR292Qm9zcyBvciBJc2xhbmQgdGhhdCB5b3UgaGF2ZW4ndCBhbHJlYWR5IGluY2x1ZGVkIGFuZCBtb2RpZnkgdGhlIGNvZGUgYmVsb3c6DQoNCmBgYHtyLCBlY2hvID0gRn0NCmdmX3BvaW50KENvdmlkRGVhdGhzMjAyMCB+IEhlYWx0aHlMaWZlRXhwZWN0YW5jeSB8IEZlbWFsZUdvdkJvc3MsIGNvbCA9IH5Jc2xhbmQsIGRhdGEgPSBIYXApDQpgYGANCg0KDQoqKlRBU0sgNi40KiogIE1ha2UgdHdvIGludGVyZXN0aW5nIGNvbW1lbnRzIGFib3V0IHdoYXQgeW91IGxlYXJuZWQgYWJvdXQgdGhlIHZhcmlhYmxlcyB5b3UgY2hvc2UgYW5kIGNvdmlkIGRlYXRocyBpbiAyMDIwLg0KDQogICAgKipSZXNwb25zZTogQ292aWQgRGVhdGhzIGFwcGVhcnMgdG8gYmUgaGlnaGVzdCBpbiBjb3VudHJpZXMgd2hlcmUgdGhlIGhlYWx0aHkgbGlmZSBleHBlY3RhbmN5IGlzIGFib3ZlIDYwLiBUaGV5IGFwcGVhciB0byBiZSBsb3dlciBvbiBhdmVyYWdlIGluIGlzbGFuZCBjb3VudHJpZXMuKioNCiAgICANCg0KIyBFcGlsb2d1ZQ0KDQpCZWxvdyBhcmUgc29tZSBzdW1tYXJpZXMgeW91IGNhbiByZWZlcmVuY2UgYXQgYW55IHRpbWUuDQoNCiMjIyMgTnVtZXJpY2FsIHN1bW1hcmllcw0KDQpUaGUgcHJpbWFyeSBudW1lcmljYWwgc3VtbWFyaWVzIHVzZWQgaW4gdGhpcyBjb3Vyc2UgaW5jbHVkZSB0aGUgbWVhbiwgdGhlIGZpdmUtbnVtYmVyIHN1bW1hcnksIGFuZCB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uLiAgVGhlIGZ1bmN0aW9ucyBiZWxvdyBjYWxjdWxhdGUgdGhlc2Ugc3VtbWFyaWVzIGZvciBhIHNpbmdsZSB2YXJpYWJsZSwgb3IgZm9yIHRoYXQgdmFyaWFibGUgYmFzZWQgb24gdGhlIHZhbHVlIG9mIGEgc2Vjb25kIGNhdGVnb3JpY2FsIHZhcmlhYmxlLg0KDQogIC0gbWVhbih+IFksIGRhdGEgPSBEYXRhU2V0TmFtZSkgICMgbWVhbiBvZiBZIHdpdGhvdXQgY29uc2lkZXJpbmcgb3RoZXIgdmFyaWFibGVzDQogIC0gbWVhbihZIH4gWCwgZGF0YSA9IERhdGFTZXROYW1lKSAgIyBtZWFuIG9mIFkgZm9yIGRpZmZlcmVudCB2YWx1ZXMgb2YgWA0KICAtIHNkKH4gWSwgZGF0YSA9IERhdGFTZXROYW1lKSAgIyBzdGFuZGFyZCBkZXZpYXRpb24gb2YgWSANCiAgLSBzZChZIH4gWCwgZGF0YSA9IERhdGFTZXROYW1lKSAgIyBzdGFuZGFyZCBkZXZpYXRpb24gb2YgWSBmb3IgZGlmZmVyZW50IHZhbHVlcyBvZiBYDQogIC0gZmF2c3RhdHMofiBZLCBkYXRhID0gRGF0YVNldE5hbWUpICAjIHN1bW1hcnkgc3RhdGlzdGljcyBvZiBZIA0KICAtIGZhdnN0YXRzKFkgfiBYLCBkYXRhID0gRGF0YVNldE5hbWUpICAjIHN1bW1hcnkgc3RhdGlzdGljcyBvZiBZIGZvciBkaWZmZXJlbnQgdmFsdWVzIG9mIFgNCg0KIyMjIyBWaXN1YWwgc3VtbWFyaWVzDQoNClRoZSBwcmltYXJ5IGdyYXBoaWNhbCByZXByZXNlbnRhdGlvbnMgdXNlZCBpbiB0aGlzIGNvdXJzZSB3aWxsIGJlIGEgYmFyY2hhcnRzLCBib3hwbG90cywgaGlzdG9ncmFtcyBhbmQgc2NhdHRlcnBsb3RzLiBFYWNoIHBsb3QgaGVscHMgdG8gdmlzdWFsaXplIGRpZmZlcmVudCBhc3BlY3RzIG9mIGEgZGF0YXNldC4gDQoNClRoZSBmdW5jdGlvbnMgdGhhdCB3aWxsIGJlIHVzZWQgdG8gZ2VuZXJhdGUgdGhlc2UgcGxvdHMgYXJlOg0KDQogIC0gZ2ZfYm94cGxvdChZIH4gWCwgZGF0YSA9IERhdGFTZXROYW1lKSAjIGJveHBsb3Qgb2YgWSBmb3IgZWFjaCB2YWx1ZSBvZiBYLCBpZiBzcGVjaWZpZWQNCiAgLSBnZl9oaXN0b2dyYW0oflksIGRhdGEgPSBEYXRhU2V0TmFtZSkgIyBoaXN0b2dyYW0gb2YgWQ0KICAtIGdmX3BvaW50KFkgfiBYLCBkYXRhID0gRGF0YVNldE5hbWUpICMgc2NhdHRlcnBsb3Qgb2YgWSB2ZXJzdXMgWA0KICAtIGdmX2JhciggflksIGRhdGEgPSBEYXRhU2V0TmFtZSkgIyBCYXIgY2hhcnQgZm9yIGEgc2luZ2xlIHZhcmlhYmxlDQogIC0gZ2ZfYmFyKCB+IFgsIGZpbGwgPSB+IFksIGRhdGEgPSBEYXRhU2V0TmFtZSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgpKSAjIHNpZGUtYnktc2lkZSBiYXIgY2hhcnQNCiAgLSBnZl9iYXIoIH4gWCwgZmlsbCA9IH4gWSwgZGF0YSA9IERhdGFTZXROYW1lKSAjIHN0YWNrZWQgYmFyIGNoYXJ0DQoNCg==