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", "Jordan", "Turkey", "Pakistan", "Indonesia", "Bangladesh", "Uni…
$ Region                  <chr> "North America and ANZ", "Middle East and North Africa", "Middle East and North Africa", "Middle East and North Africa", "Middl…
$ HappinessScore          <dbl> 6.951, 4.283, 4.918, 4.584, 6.494, 4.395, 4.948, 4.934, 5.345, 5.025, 7.064, 6.690, 7.155, 7.464, 6.834, 6.491, 6.483, 6.166, 5…
$ Population2019          <dbl> 328.239523, 100.388073, 36.471769, 6.855713, 34.268528, 10.101694, 83.429615, 216.565318, 270.625568, 163.046161, 66.834405, 67…
$ CovidDeaths2020         <dbl> 104.451, 7.457, 20.016, 21.508, 17.875, 37.577, 24.758, 4.607, 8.094, 4.590, 108.450, 99.212, 40.331, 67.260, 168.496, 108.731,…
$ MedianAge               <dbl> 38.3, 25.3, 29.6, 31.1, 31.9, 23.2, 31.6, 23.5, 29.3, 27.5, 40.8, 42.0, 46.6, 43.2, 41.8, 45.5, 47.9, 41.8, 43.4, 43.3, 43.0, 4…
$ FemaleGovBoss           <chr> "No", "No", "No", "No", "No", "No", "No", "No", "No", "Yes", "No", "No", "Yes", "No", "No", "No", "No", "No", "No", "No", "No",…
$ InstitutionalTrust      <dbl> 0.250, 0.446, 0.397, 0.107, 0.651, 0.465, 0.295, 0.277, 0.561, 0.577, 0.268, 0.234, 0.435, 0.522, 0.303, 0.143, 0.076, 0.304, 0…
$ ExcessDeaths            <dbl> 179.220, NA, NA, NA, NA, NA, NA, NA, NA, NA, 133.313, 106.597, 73.548, 114.468, 169.894, 173.233, 182.298, 206.508, 128.939, 18…
$ LogGDP                  <dbl> 11.023, 9.367, 8.903, 9.626, 10.743, 9.182, 10.240, 8.458, 9.365, 8.454, 10.707, 10.704, 10.873, 10.932, 10.823, 10.571, 10.623…
$ SocialSupport           <dbl> 0.920, 0.750, 0.560, 0.848, 0.891, 0.767, 0.822, 0.651, 0.811, 0.693, 0.934, 0.942, 0.903, 0.942, 0.906, 0.932, 0.880, 0.898, 0…
$ HealthyLifeExpectancy   <dbl> 68.200, 61.998, 66.208, 67.355, 66.603, 67.000, 67.199, 58.709, 62.236, 64.800, 72.500, 74.000, 72.500, 72.400, 72.199, 74.700,…
$ Freedom                 <dbl> 0.837, 0.749, 0.774, 0.525, 0.877, 0.755, 0.576, 0.726, 0.873, 0.877, 0.859, 0.822, 0.875, 0.913, 0.783, 0.761, 0.693, 0.841, 0…
$ PerceptionsOfCorruption <dbl> 0.698, 0.795, 0.801, 0.898, 0.684, 0.705, 0.776, 0.787, 0.867, 0.682, 0.459, 0.571, 0.460, 0.338, 0.646, 0.745, 0.866, 0.735, 0…
$ Island                  <chr> "No", "No", "No", "No", "No", "No", "No", "No", "Yes", "No", "Yes", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No",…

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

**Response**

Categorical: 1, 2, 7, 15

Numeric: 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14

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                          East Asia        Latin America and Caribbean 
                          5.984765                           5.467000                           5.810333                           5.908050 
      Middle East and North Africa              North America and ANZ                         South Asia                     Southeast Asia 
                          5.219765                           7.128500                           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:**

North America and ANZ has the highest mean and median happiness score

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

**Response:**

The minimum value, first quartile, second quartile, third quartile, maximum value, mean, standard deviation, number of data points, and number of blank data points in a data set.

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:**

A total of 6 outliers can be observed in the side-by-side boxplots.

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

**Response:**

The data suggests that there is a relationship between happiness scores and region.

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:**

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 countries are governed by female leaders.Categorical variables can be tabulated using "tally."
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:**

Countries run by female leaders are happier.

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.

             Island
FemaleGovBoss  No Yes
          No  109  17
          Yes  19   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:**

3/17 ~= 17.6%
[1] 0.1764706

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:**

19/109 ~= 17.4%
[1] 0.1743119

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:**

Islands are not significantly more likely to have female leaders.

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
LS0tDQp0aXRsZTogJ0xhYiAxLTE6IFVzaW5nIFIgTWFya2Rvd24gdG8gZXhwbG9yZSBkYXRhJw0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KDQojIyMgT2JqZWN0aXZlczoNCg0KRm9yIHRoaXMgbGFiIHlvdSBzaG91bGQuLi4NCg0KICAtIFJlYWQgZGF0YXNldHMgaW50byBSDQogIC0gRmFtaWxpYXJpemUgeW91cnNlbGYgd2l0aCBjb21tb25seSB1c2VkIGZ1bmN0aW9ucyBhbmQgbW9kZWwtY2VudHJpYyBzeW50YXggaW4gUg0KICAtIFByb3ZpZGUgc3VtbWFyeSBzdGF0aXN0aWNzIG9mIGEgZGF0YXNldA0KICAtIHZpc3VhbGl6ZSB0aGUgZGF0YXNldCB1c2luZyBoaXN0b2dyYW1zIGFuZCBib3hwbG90cyANCiANCg0KIyBQYXJ0IDE6IEdldHRpbmcgcmVhZHkgdG8gdXNlIGRhdGENCg0KVGhlIGZvbGxvd2luZyBwYWNrYWdlcyB3aWxsIG5lZWQgdG8gYmUgbG9hZGVkIGludG8gUiBiZWZvcmUgeW91IGJlZ2luIHRoZSBsYWIuIFRvIHJ1biBhIGNodW5rIG9mIFIgY29kZSwgY2xpY2sgdGhlIGdyZWVuIGFycm93IHN5bWJvbCBpbiB0aGUgdXBwZXIgcmlnaHQgb2YgdGhlIGdyYXkgY2h1bmsuIElmIHlvdSB3b3VsZCBsaWtlIHRvIHJ1biBsaW5lIGJ5IGxpbmUsIGhpdCBDdHJsLUVudGVyIHdpdGggeW91ciBjdXJzb3IgbmV4dCB0byB0aGUgZGVzaXJlZCBsaW5lLg0KDQpgYGB7ciwgZWNobyA9IEYsIG1lc3NhZ2UgPSBGfQ0KIyMgIE5PVEUgLSBpbiBhbGwgZnV0dXJlIGRvY3VtZW50cy9hc3NpZ25tZW50cyB0aGlzIGNvZGUgd2lsbCBiZSBpbmNsdWRlZCBmb3IgeW91IGFuZCB5b3UgYXJlIGV4cGVjdGVkIHRvIHJ1biBpdCB3aXRob3V0IHByb21wdGluZy4NCg0KDQojIENsZWFyIFdvcmtzcGFjZQ0Kcm0obGlzdCA9IGxzKCkpIA0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG89RkFMU0UpDQoNCiMgbG9hZCBwYWNrYWdlcyB3ZSB0eXBpY2FsbHkgdXNlIGZvciB0aGlzIGNsYXNzLg0KbGlicmFyeShtb3NhaWMsIHdhcm4uY29uZmxpY3RzID0gRkFMU0UpIA0KbGlicmFyeShnZ2Zvcm11bGEsIHdhcm4uY29uZmxpY3RzID0gRkFMU0UpDQoNCg0KYGBgDQoNCiMjIyBUaGUgSGFwcGluZXNzIERhdGENCg0KVGhlIGhhcHBpbmVzcyBkYXRhIHNldCBpcyBmcm9tIHRoZSAyMDIxIFdvcmxkIEhhcHBpbmVzcyBSZXBvcnQgPGh0dHBzOi8vV29ybGRoYXBwaW5lc3MucmVwb3J0L2VkLzIwMjE+LiAgRWFjaCBvYnNlcnZhdGlvbiBpbiB0aGlzIGRhdGFzZXQgcmVwcmVzZW50cyBhIGNvdW50cnkgaW4gdGhlIHdvcmxkLiBUaGVyZSBhcmUgMTQgdmFyaWFibGVzIG9ic2VydmVkIGFib3V0IGNpdGl6ZW5zIG9waW5pb25zIG9uIHRoZWlyIGNvdW50cmllcywgY2hhcmFjdGVyaXN0aWNzIG9mIHRoZWlyIGNvdW50cmllcywgYW5kIENvdmlkLTE5IHJlbGF0ZWQgc3VtbWFyaWVzLiAgQSBtdWx0aXR1ZGUgb2YgaW50ZXJlc3RpbmcgcXVlc3Rpb25zIGNhbiBiZSBwb3NlZCAoYW5kIGFuc3dlcmVkISkgdXNpbmcgdGhlc2UgZGF0YS4NCg0KKipUQVNLIDEuMCoqIERvd25sb2FkIHRoZSBkYXRhc2V0IFdvcmxkSGFwcGluZXNzLmNzdiBmcm9tIHRoZSBMYWIgMS4xIGFzc2lnbm1lbnQgcGFnZS4gT25jZSB5b3UndmUgZG93bmxvYWRlZCBpdCwgdXNpbmcgdGhlIGZvbGxvd2luZyBjb2RlIHRvIHJlYWQgaXQgaW50byBSOg0KDQpgYGB7cixlY2hvID0gRn0NCg0KSGFwIDwtIHJlYWQuY3N2KGZpbGUuY2hvb3NlKCkpICNzZWxlY3QgeW91ciBmaWxlIGluIGl0cyBzYXZlZCBsb2NhdGlvbiB3aGVuIHRoZSBwcm9tcHQgb3BlbnMNCg0KYGBgDQoNCioqVEFTSyAxLjEqKiBUbyBlbnN1cmUgdGhhdCB5b3UgaGF2ZSBzdWNjZXNzZnVsbHkgbG9hZGVkIHRoZSBkYXRhc2V0LCB5b3UgY2FuIGNoZWNrIHVzaW5nIHRoZSBmdW5jdGlvbiBoZWFkKERhdGFTZXROYW1lKSwgd2hpY2ggZGlzcGxheXMgdGhlIGZpcnN0IHNpeCByb3dzIG9mIHRoZSBkYXRhLCBhbmQgZ2xpbXBzZShEYXRhU2V0TmFtZSksIHdoaWNoIHByb3ZpZGVzIGEgc3VtbWFyeSBvZiB0aGUgZGF0YSBmcmFtZS4NCg0KYGBge3IsZWNobyA9IEZ9DQojIG1vZGlmeSB0aGUgY29kZSBiZWxvdw0KDQpoZWFkKEhhcCkgIyBkaXNwbGF5cyB0aGUgZmlyc3QgNiByb3dzIG9mIHRoZSBkYXRhc2V0LCBpbmNsdWRpbmcgaGVhZGVycyANCmdsaW1wc2UoSGFwKSAjIHByb3ZpZGVzIGEgc3VtbWFyeSBvZiB0aGUgZGF0YSBmcmFtZQ0KDQpgYGANCg0KDQoqKlRBU0sgMS4yKiogVXNlIHlvdXIgcmVzdWx0cyBmcm9tIFRhc2sgMS4xIHRvIGRldGVybWluZSB3aGljaCBjb2x1bW5zIGFyZSBjYXRlZ29yaWNhbCBkYXRhLCBhbmQgd2hpY2ggYXJlIG51bWVyaWM6DQoNCiAgICAqKlJlc3BvbnNlKioNCg0KICAgIENhdGVnb3JpY2FsOiAxLCAyLCA3LCAxNQ0KICAgIA0KICAgIE51bWVyaWM6IDMsIDQsIDUsIDYsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNA0KIA0KDQojIyMgTW9kZWwtY2VudHJpYyBhcHByb2FjaCB0byBSDQoNCkZvciB0aGUgcHVycG9zZXMgb2Ygb3VyIGNsYXNzLCBpdCdzIHVzZWZ1bCB0byBsZWFybiBhIG1vZGVsLWNlbnRyaWMgYXBwcm9hY2ggdG8gUi4gIFRoZSBwc3VlZG8tY29kZSBiZWxvdyBpcyBnb2luZyB0byBiZSBvdXIgZm91bmRhdGlvbiBmb3IgdGhlIHJlc3Qgb2YgdGhlIGNsYXNzOiANCg0KYGZ1bmN0aW9uKCBZIH4gWCwgZGF0YSA9IERhdGFTZXROYW1lIClgDQoNCkhlcmUncyBhIHNob3J0IGRlc2NyaXB0aW9uIG9mIGVhY2ggcGFydCBpbiB0aGUgcHNldWRvLWNvZGUgYWJvdmU6DQoNCi0gYGZ1bmN0aW9uYCBpcyBhbiBSIGZ1bmN0aW9uIHRoYXQgZGljdGF0ZXMgc29tZXRoaW5nIHlvdSB3YW50IHRvIGRvIHdpdGggeW91ciBkYXRhIGUuZy4gDQogICAgLSBmb3IgZXhhbXBsZSwgYG1lYW5gIGNhbGN1bGF0ZXMgdGhlIG1lYW4NCi0gYFlgIGlzIHRoZSBvdXRjb21lIG9mIGludGVyZXN0IChyZXNwb25zZSB2YXJpYWJsZSkgIA0KLSBgWGAgaXMgc29tZSBleHBsYW5hdG9yeSB2YXJpYWJsZSBvciB5b3UgY2FuIHVzZSAiMSIgYXMgYSBwbGFjZWhvbGRlciBpZiB0aGVyZSBpcyBubyBleHBsYW5hdG9yeSB2YXJpYWJsZSAgDQotIGBEYXRhU2V0TmFtZWAgaXMgdGhlIG5hbWUgb2YgYSBkYXRhIHNldCBsb2FkZWQgaW50byB0aGUgUiBlbnZpcm9ubWVudA0KDQpBIHN1bW1hcnkgb2YgdGhlIG1vc3QgY29tbW9ubHkgdXNlZCBmdW5jdGlvbnMgZm9yIHRoaXMgY2xhc3MgYXJlIHByb3ZpZGVkIGF0IHRoZSBib3R0b20gb2YgdGhpcyBkb2N1bWVudC4gIEluIHRoZSB3b3JrIGJlbG93IHlvdSB3aWxsIGJlIGludHJvZHVjZWQgdG8gdGhlIGZ1bmN0aW9ucyBhbmQgdGhlaXIgdXNlcyBvbmUgYXQgYSB0aW1lIGluIHRoZSBjb250ZXh0IG9mIGFuc3dlcmluZyByZXNlYXJjaCBxdWVzdGlvbnMuDQoNCiMjIFJlc2VhcmNoIFF1ZXN0aW9uIEE6IEFyZSBkaWZmZXJlbnQgcmVnaW9ucyBvZiB0aGUgd29ybGQgaGFwcGllcj8NCg0KVG8gdXNlIHRoZSBkYXRhIHRvIGFuc3dlciB0aGUgcmVzZWFyY2ggcXVlc3Rpb24sIHdlIGNvdWxkIGZpbmQgZGF0YSBzdW1tYXJpZXMgc3VjaCBhcyBhdmVyYWdlIGhhcHBpbmVzcywgZm9yIGVhY2ggb2YgdGhlIHJlZ2lvbnMuICBJbiB0aGlzIHNpdHVhdGlvbiwgSGFwcGluZXNzU2NvcmUgaXMgb3VyIHJlc3BvbnNlIHZhcmlhYmxlIGFuZCBSZWdpb24gaXMgb3VyIGV4cGxhbmF0b3J5IHZhcmlhYmxlLg0KDQoqKlRBU0sgMi4xKiogTW9kaWZ5IGFuZCBydW4gdGhlIGNvZGUgYmVsb3cgdG8gY2FsY3VsYXRlIHRoZSBtZWFuIEhhcHBpbmVzc1Njb3JlIGZvciBlYWNoIHJlZ2lvbi4NCg0KYGBge3IsZWNobyA9IEZ9DQoNCm1lYW4oSGFwcGluZXNzU2NvcmUgfiBSZWdpb24sIGRhdGEgPSBIYXApDQoNCmBgYA0KDQoqKlRBU0sgMi4yKiogIFVzZSB0aGUgZnVuY3Rpb24gJ2ZhdnN0YXRzKCknLCBhbmQgbW9kZWwtY2VudHJpYyBzeW50YXgsIHRvIGRldGVybWluZSB3aGljaCByZWdpb24gaGFzIHRoZSBjb3VudHJ5IHdpdGggdGhlIGhpZ2hlc3QgaGFwcGluZXNzIHNjb3JlLg0KDQogICAgKipSZXNwb25zZToqKg0KICAgIA0KICAgIE5vcnRoIEFtZXJpY2EgYW5kIEFOWiBoYXMgdGhlIGhpZ2hlc3QgbWVhbiBhbmQgbWVkaWFuIGhhcHBpbmVzcyBzY29yZQ0KICANCmBgYHtyLCBlY2hvID0gRn0NCg0KZmF2c3RhdHMoSGFwcGluZXNzU2NvcmUgfiBSZWdpb24sIGRhdGEgPSBIYXApDQoNCmBgYA0KDQoqKlRBU0sgMi4zKiogV2hpY2ggc3VtbWFyeSBzdGF0aXN0aWNzIGFyZSBjYWxjdWxhdGVkIGJ5IHRoZSBmYXZzdGF0cygpIGZ1bmN0aW9uPw0KDQogICAgKipSZXNwb25zZToqKg0KICAgIA0KICAgIFRoZSBtaW5pbXVtIHZhbHVlLCBmaXJzdCBxdWFydGlsZSwgc2Vjb25kIHF1YXJ0aWxlLCB0aGlyZCBxdWFydGlsZSwgbWF4aW11bSB2YWx1ZSwgbWVhbiwgc3RhbmRhcmQgZGV2aWF0aW9uLCBudW1iZXIgb2YgZGF0YSBwb2ludHMsIGFuZCBudW1iZXIgb2YgYmxhbmsgZGF0YSBwb2ludHMgaW4gYSBkYXRhIHNldC4NCg0KTm93IGl0J3MgdGltZSB0byB2aXN1YWxpemUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBIYXBwaW5lc3MgU2NvcmUgZm9yIHRoZSBkaWZmZXJlbnQgcmVhc29ucy4gIA0KDQoqKlRBU0sgMi40KiogTW9kaWZ5IHRoZSBjb2RlIGJlbG93IHRvIGNyZWF0ZSBhIGhpc3RvZ3JhbSBvZiBIYXBwaW5lc3MgU2NvcmUsIHdpdGhvdXQgYWNjb3VudGluZyBmb3Igb3RoZXIgdmFyaWFibGVzLiAgV2hhdCBpcyB0aGUgc2hhcGUgb2YgdGhlIGRpc3RyaWJ1dGlvbjogbGVmdC1za2V3ZWQsIHJpZ2h0LXNrZXdlZCwgb3Igcm91Z2hseSBzeW1tZXRyaWM/DQoNCiAgICAqKlJlc3BvbnNlOioqDQogICAgDQogICAgUm91Z2hseSBzeW1tZXRyaWMNCiAgICANCmBgYHtyLGVjaG8gPSBGfQ0KDQpnZl9oaXN0b2dyYW0ofiBIYXBwaW5lc3NTY29yZSwgZGF0YSA9IEhhcCkNCg0KYGBgDQoNCioqVEFTSyAyLjUqKiBHZW5lcmF0ZSBzaWRlLWJ5LXNpZGUgYm94cGxvdHMgb2YgdGhlIEhhcHBpbmVzc1Njb3JlLCBzZXBhcmF0ZWQgYnkgUmVnaW9uLiBXcml0ZSBhIHNlbnRlbmNlIGFib3V0IHdoYXQgeW91IG9ic2VydmUgaW4gdGhlIGZpZ3VyZS4NCg0KICAgICoqUmVzcG9uc2U6KioNCiAgICANCiAgICBBIHRvdGFsIG9mIDYgb3V0bGllcnMgY2FuIGJlIG9ic2VydmVkIGluIHRoZSBzaWRlLWJ5LXNpZGUgYm94cGxvdHMuDQoNCmBgYHtyLGVjaG8gPSBGfQ0KI2dmX2JveHBsb3QoSGFwcGluZXNzU2NvcmUgfiBSZWdpb24sIGRhdGEgPSBIYXApDQoNCiMgaWYgdGhlIGF4ZXMgbGFiZWxzIGFyZW4ndCByZWFkYWJsZSwgdHJ5IG1vZGlmeWluZyBhbmQgcnVubmluZyB0aGUgY29kZSBiZWxvdyENCmdmX2JveHBsb3QoSGFwcGluZXNzU2NvcmUgfiBSZWdpb24sIGRhdGEgPSBIYXApICsgY29vcmRfZmxpcCgpDQoNCmBgYA0KDQoqKlRBU0sgMi42KiogQmFzZWQgb24gZXZlcnl0aGluZyB5b3UndmUgbGVhcm5lZCwgZG8geW91IHRoaW5rIHRoYXQgaGFwcGluZXNzIHNjb3JlcyB2YXJ5IGJ5IHJlZ2lvbj8NCg0KICAgICoqUmVzcG9uc2U6KioNCiAgICANCiAgICBUaGUgZGF0YSBzdWdnZXN0cyB0aGF0IHRoZXJlIGlzIGEgcmVsYXRpb25zaGlwIGJldHdlZW4gaGFwcGluZXNzIHNjb3JlcyBhbmQgcmVnaW9uLg0KICAgIA0KICAgIA0KIyMjIyBSZXNlYXJjaCBRdWVzdGlvbiBCOiBBcmUgY291bnRyaWVzIHJ1biBieSBmZW1hbGUgbGVhZGVycyBoYXBwaWVyPw0KDQoqKlRBU0sgMy4xKiogV3JpdGUgYW5kIHJ1biBjb2RlIHRvIGRldGVybWluZSB3aGV0aGVyIHRoZSBtZWFuIEhhcHBpbmVzcyBTY29yZSBpcyBoaWdoZXIgb3IgbG93ZXIgZm9yIGNvdW50cmllcyB3aXRoIGZlbWFsZSBsZWFkZXJzLiAgSGludDogIHRoZSB2YXJpYWJsZSAnRmVtYWxlR292Qm9zcycgaW5kaWNhdGVzIHdoZXRoZXIgYSBjb3VudHJ5IGlzIHJ1biBieSBhIGZlbWFsZSBsZWFkZXIuDQoNCiAgICAqKlJlc3BvbnNlOioqDQoNCmBgYHtyLGVjaG8gPSBGfQ0KDQpmYXZzdGF0cyhIYXBwaW5lc3NTY29yZSB+IEZlbWFsZUdvdkJvc3MsIGRhdGEgPSBIYXApDQoNCmBgYA0KKipUQVNLIDMuMioqIEhvdyBtYW55IGNvdW50cmllcyBhcmUgZ292ZXJuZWQgYnkgZmVtYWxlIGxlYWRlcnM/IFlvdSBjYW4gdGFidWxhdGUgb2JzZXJ2YXRpb25zIG9mIGEgY2F0ZWdvcmljYWwgdmFyaWFibGUgdXNpbmcgdGhlICd0YWxseScgY29tbWFuZC4gIE1vZGlmeSB0aGUgY29kZSBiZWxvdyB0byBhbnN3ZXIgdGhlIHF1ZXN0aW9uLg0KDQogICAgKipSZXNwb25zZToqKg0KICAgIA0KICAgIDIyIGNvdW50cmllcyBhcmUgZ292ZXJuZWQgYnkgZmVtYWxlIGxlYWRlcnMuQ2F0ZWdvcmljYWwgdmFyaWFibGVzIGNhbiBiZSB0YWJ1bGF0ZWQgdXNpbmcgInRhbGx5LiINCiAgICANCmBgYHtyLGVjaG8gPSBGfQ0KdGFsbHkoIH4gRmVtYWxlR292Qm9zcywgZGF0YSA9IEhhcCkNCmBgYA0KDQoNCioqVEFTSyAzLjMqKiBDcmVhdGUgYW4gYXBwcm9wcmlhdGUgdmlzdWFsIHN1bW1hcnkgdG8gaW52ZXN0aWdhdGUgcmVzZWFyY2ggcXVlc3Rpb24gQi4NCg0KYGBge3IsZWNobyA9IEZ9DQoNCmdmX2JveHBsb3QoSGFwcGluZXNzU2NvcmUgfiBGZW1hbGVHb3ZCb3NzLCBkYXRhID0gSGFwKSArIGNvb3JkX2ZsaXAoKQ0KDQpgYGANCg0KKipUQVNLIDMuNCoqIEJhc2VkIG9uIHdoYXQgeW91IGxlYXJuZWQgaW4gdGFza3MgMy4xIGFuZCAzLjMsIHdoYXQgZG8geW91IHRoaW5rIHRoZSBhbnN3ZXIgdG8gcmVzZWFyY2ggcXVlc3Rpb24gQiB3b3VsZCBiZT8NCg0KICAgICoqUmVzcG9uc2U6KioNCiAgICANCiAgICBDb3VudHJpZXMgcnVuIGJ5IGZlbWFsZSBsZWFkZXJzIGFyZSBoYXBwaWVyLg0KICAgIA0KDQojIyBSZXNlYXJjaCBRdWVzdGlvbiBDOiBBcmUgSXNsYW5kIG5hdGlvbnMgbW9yZSBsaWtlbHkgdG8gaGF2ZSBmZW1hbGUgbGVhZGVycz8NCg0KDQoqKlRBU0sgNC4xKiogVXNlIFIgdGFsbHkgdXAgaG93IG1hbnkgY291bnRyaWVzIGFyZSBpc2xhbmRzIHdpdGggZmVtYWxlIGxlYWRlcnMsIGlzbGFuZHMgYXJlIG1hbGUgbGVhZGVycywgbm90IGlzbGFuZHMgd2l0aCBmZW1hbGUgbGVhZGVycywgYW5kIG5vdCBpc2xhbmRzIHdpdGggbWFsZSBsZWFkZXJzLiAgTW9kaWZ5IHRoZSBjb2RlIGJlbG93IHRvIGV4dHJhY3QgdGhlIG51bWJlcnMuDQoNCmBgYHtyLCBlY2hvID0gRn0NCnRhbGx5KEZlbWFsZUdvdkJvc3MgfiBJc2xhbmQsIGRhdGEgPSBIYXApDQpgYGANCkZvciBhIHJlc2VhcmNoIHF1ZXN0aW9uIGxpa2UgdGhpcyBvbmUgdGhhdCBpbnZvbHZlcyB0d28gYmluYXJ5IHZhcmlhYmxlcywgaXQgaXMgdXNlZnVsIHRvIGNhbGN1bGF0ZSBhbmQgY29tcGFyZSB0d28gcHJvcG9ydGlvbnM6DQoNCioqVEFTSyA0LjIqKiAgV2hhdCBwcm9wb3J0aW9uIG9mIElzbGFuZCBOYXRpb25zIGhhdmUgZmVtYWxlIGxlYWRlcnM/ICBZb3Ugc2hvdWxkIGNhbGN1bGF0ZSAoIyBpc2xhbmQgbmF0aW9ucyB3aXRoIGZlbWFsZSBsZWFkZXJzKS8oIyBpc2xhbmQgbmF0aW9ucykNCg0KICAgICoqUmVzcG9uc2U6KioNCiAgICANCiAgICAzLzE3IH49IDE3LjYlDQogICAgDQpgYGB7cn0NCiMgeW91IGNhbiB1c2UgdGhpcyBSIGNodW5rIGFzIGEgY2FsY3VsYXRvciBpZiBuZWVkZWQNCg0KMy8xNw0KDQpgYGANCg0KICANCioqVEFTSyA0LjMqKiAgV2hhdCBwcm9wb3J0aW9uIG9mIG5vbi1Jc2xhbmQgTmF0aW9ucyBoYXZlIGZlbWFsZSBsZWFkZXJzPyBZb3Ugc2hvdWxkIGNhbGN1bGF0ZSAoIyBub24taXNsYW5kIG5hdGlvbnMgd2l0aCBmZW1hbGUgbGVhZGVycykvKCMgbm9uLWlzbGFuZCBuYXRpb25zKQ0KDQogICAgKipSZXNwb25zZToqKg0KICAgIA0KICAgIDE5LzEwOSB+PSAxNy40JQ0KICAgIA0KYGBge3J9DQojIHlvdSBjYW4gdXNlIHRoaXMgUiBjaHVuayBhcyBhIGNhbGN1bGF0b3IgaWYgbmVlZGVkDQoNCjE5LzEwOQ0KDQoNCmBgYA0KDQpUbyB2aXN1YWxpemUgdGhlIGRhdGEgYXMgaXQgcmVsYXRlcyB0byB0aGlzIHF1ZXN0aW9uLCB5b3Ugc2hvdWxkIG1ha2Ugc2lkZS1ieS1zaWRlIG9yIHN0YWNrZWQgYmFyY2hhcnRzLg0KICANCioqVEFTSyA0LjQqKiAgTW9kaWZ5IHRoZSBjb2RlIGJlbG93IHRvIGNyZWF0ZSBhIHNpZGUgYnkgc2lkZSBiYXJjaGFydC4gIE5vdGljZSB0aGUgc3ludGF4IGlzIGEgbGl0dGxlIGRpZmZlcmVudDsgeW91IHNob3VsZCB0cnkgZGlmZmVyZW50IG9wdGlvbnMgZm9yIFggYW5kIFkgdW50aWwgeW91IGhhdmUgSXNsYW5kcyBvbiB0aGUgYm90dG9tIGFuZCBkaWZmZXJlbnQgY29sb3JzIGZvciBGZW1hbGVHb3ZCb3NzLg0KDQpgYGB7ciwgZWNobyA9IEZ9DQpnZl9iYXIofklzbGFuZCwgZmlsbCA9ICB+IEZlbWFsZUdvdkJvc3MsIGRhdGEgPSBIYXAsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoKSkNCmBgYA0KDQoqKlRBU0sgNC41KiogQmFzZWQgb24geW91ciBhbnN3ZXJzIHRvIFRhc2tzIDQuMS0tNC40LCB3aGF0IGRvIHlvdSB0aGluayB0aGUgYW5zd2VyIHRvIHJlc2VhcmNoIHF1ZXN0aW9uIEMgd291bGQgYmU/DQoNCiAgICAqKlJlc3BvbnNlOioqDQogICAgDQogICAgSXNsYW5kcyBhcmUgbm90IHNpZ25pZmljYW50bHkgbW9yZSBsaWtlbHkgdG8gaGF2ZSBmZW1hbGUgbGVhZGVycy4NCg0KDQojIyBSZXNlYXJjaCBRdWVzdGlvbiBEOiBXaGljaCBvZiB0aGUgcXVhbnRpdGF0aXZlIHZhcmlhYmxlcyBhcmUgcmVsYXRlZCB0byBIYXBwaW5lc3MgU2NvcmU/DQoNClRvIGFuc3dlciB0aGlzIHF1ZXN0aW9uLCB3ZSBjb25zaWRlciBwbG90cyB0aGF0IHZpc3VhbGl6ZSB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdHdvIHF1YW50aXRhdGl2ZSB2YXJpYWJsZXMuIEEgc2NhdHRlcnBsb3QgaXMgc2ltcGx5IGFuICh4LHkpIHBsb3QgaW4gdGhlIENhcnRlc2lhbiBwbGFuZS4gVXNpbmcgb3VyIFkgfiBYIGZvcm1hdCwgdGhlIFkgdmFyaWFibGUgd2lsbCBiZSBhbG9uZyB0aGUgWSBheGlzLiANCg0KKipUQVNLIDUuMSoqIE1vZGlmeSB0aGUgY29kZSBiZWxvdyB0byBnZW5lcmF0ZSBhIHNjYXR0ZXJwbG90IG9mIHRoZSBIYXBwaW5lc3NTY29yZSB2ZXJzdXMgdGhlIEluc3RpdHV0aW9uYWwgVHJ1c3QuDQoNCg0KYGBge3IsZWNobyA9IEZ9DQpnZl9wb2ludChIYXBwaW5lc3NTY29yZSB+IEluc3RpdHV0aW9uYWxUcnVzdCwgZGF0YSA9IEhhcCkNCg0KYGBgDQoqKlRBU0sgNS4yKiogV3JpdGUgY29kZSBhbmQgcHJvZHVjZSBzY2F0dGVycGxvdHMgb2YgdGhlIEhhcHBpbmVzc1Njb3JlIHZlcnN1czogU29jaWFsU3VwcG9ydCwgSGVhbHRoeUxpZmVFeHBlY3RhbmN5LCBhbmQgRnJlZWRvbS4gDQoNCmBgYHtyLGVjaG8gPSBGfQ0KDQpnZl9wb2ludChIYXBwaW5lc3NTY29yZSB+IFNvY2lhbFN1cHBvcnQsIGRhdGEgPSBIYXApIA0KDQpnZl9wb2ludChIYXBwaW5lc3NTY29yZSB+IEhlYWx0aHlMaWZlRXhwZWN0YW5jeSwgZGF0YSA9IEhhcCkNCg0KZ2ZfcG9pbnQoSGFwcGluZXNzU2NvcmUgfiBGcmVlZG9tLCBkYXRhID0gSGFwKQ0KDQpgYGAgDQoNCioqVEFTSyA1LjMqKiAgQ29tbWVudCBvbiB3aGljaCBvZiB0aGUgZm91ciB2YXJpYWJsZXMgdGhhdCBoYXZlIGJlZW4gcGxvdHRlZCBzdWdnZXN0IGEgc3Ryb25nIGxpbmVhciByZWxhdGlvbnNoaXAgd2l0aCB0aGUgSGFwcGluZXNzIFNjb3JlLiANCg0KICAgICoqUmVzcG9uc2UqKiANCiAgICANCiAgICBTb2NpYWwgc3VwcG9ydCwgbGlmZSBleHBlY3RhbmN5LCBhbmQgZnJlZWRvbSBoYXZlIGNsZWFyLCBsaW5lYXIgcmVsYXRpb25zaGlwcyB3aXRoIGhhcHBpbmVzcyBzY29yZS4NCg0KKipSZXNwb25zZSoqIA0KDQoNCiMjIFJlc2VhcmNoIFF1ZXN0aW9uIEU6IFdoaWNoIHZhcmlhYmxlcyBhcmUgcmVsYXRlZCB0byBDb3ZpZCBEZWF0aHMgMjAyMD8/DQoNCkEgc3RyZW5ndGggb2YgUiBpcyBpdHMgYWJpbGl0eSB0byBxdWlja2x5IGFuZCBlYXNpbHkgcHJvZHVjZSBzb3BoaXN0aWNhdGVkIGRhdGEgdmlzdWFsaXphdGlvbnMuICBZb3Ugd2lsbCB1c2UgIGN1cmlvc2l0eSBhbmQgdG9vbHMgaW4gUiB0byBjcmVhdGUgdmlzdWFsaXphdGlvbnMgdGhhdCBleHBsb3JlIHRoaXMgcmVzZWFyY2ggcXVlc3Rpb24uDQoNClVzZSB0aGUgY29kZSBiZWxvdyB0byByZW1pbmQgeW91cnNlbGYgd2hpY2ggdmFyaWFibGVzIGFyZSBhdmFpbGFibGUgaW4gdGhpcyBkYXRhc2V0LiAgQ2hvb3NlIGEgcXVhbnRpdGF0aXZlIHZhcmlhYmxlIHRoYXQgeW91IHRoaW5rIHdpbGwgYmUgcmVsYXRlZCB0byBDb3ZpZERlYXRoczIwMjAuDQoNCioqVEFTSyA2LjEqKiBNYWtlIGEgc2NhdHRlcnBsb3QgdG8gZXhhbWluZSB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gQ292aWQgRGVhdGhzIGluIDIwMjAgYW5kIHRoZSB2YXJpYWJsZSB5b3UgY2hvc2UuIA0KYGBge3IsZWNobyA9IEZ9DQoNCg0KZ2ZfcG9pbnQoQ292aWREZWF0aHMyMDIwIH4gTWVkaWFuQWdlLCBkYXRhID0gSGFwKQ0KDQoNCmBgYCANCg0KKipUQVNLIDYuMioqIE5vdywgY29sb3IgdGhlIHBvaW50cyBpbiB5b3VyIHBsb3QgYmFzZWQgb24gdGhlIHZhbHVlcyBvZiBhIHRoaXJkIHZhcmlhYmxlIHN1Y2ggYXMgRmVtYWxlR292Qm9zcywgSXNsYW5kLCBvciBSZWdpb24uIFlvdSBjb3VsZCBhbHNvIGNob29zZSBhIHF1YW50aXRhdGl2ZSB2YXJpYWJsZSwgaWYgeW91IGRlc2lyZWQuDQoNCmBgYHtyLGVjaG8gPSBGfQ0KDQpnZl9wb2ludChDb3ZpZERlYXRoczIwMjAgfiBNZWRpYW5BZ2UsIGNvbCA9IH4gTG9nR0RQLCBkYXRhID0gSGFwKQ0KDQoNCmBgYCANCioqVEFTSyA2LjMqKiBOb3cgd2UgY2FuIGFkZCBvbmUgbW9yZSBsYXllciwgYmFzZWQgb24gYSBjYXRlZ29yaWNhbCB2YXJpYWJsZS4gIENob29zZSBvbmUgb2YgdGhlIGJpbmFyeSB2YXJpYWJsZXMgRmVtYWxlR292Qm9zcyBvciBJc2xhbmQgdGhhdCB5b3UgaGF2ZW4ndCBhbHJlYWR5IGluY2x1ZGVkIGFuZCBtb2RpZnkgdGhlIGNvZGUgYmVsb3c6DQoNCmBgYHtyLCBlY2hvID0gRn0NCmdmX3BvaW50KENvdmlkRGVhdGhzMjAyMCB+IE1lZGlhbkFnZSB8IElzbGFuZCwgY29sID0gfkxvZ0dEUCwgZGF0YSA9IEhhcCkNCmBgYA0KDQoNCioqVEFTSyA2LjQqKiAgTWFrZSB0d28gaW50ZXJlc3RpbmcgY29tbWVudHMgYWJvdXQgd2hhdCB5b3UgbGVhcm5lZCBhYm91dCB0aGUgdmFyaWFibGVzIHlvdSBjaG9zZSBhbmQgY292aWQgZGVhdGhzIGluIDIwMjAuDQoNCiAgICAqKlJlc3BvbnNlOioqDQogICAgDQogICAgUG9wdWxhdGlvbnMgd2l0aCBsYXJnZXIgbWVkaWFuIGFnZXMgZGlkIHNob3cgZXZpZGVuY2Ugb2YgaGlnaGVyIG51bWJlcnMgb2YgY292aWQgZGVhdGhzLCBhbmQgcG9wdWxhdGlvbnMgd2l0aCBsb3dlciBHRFBzIHNob3dlZCBldmlkZW5jZSBvZiBmZXdlciBjb3ZpZCBkZWF0aHMsIGhvd2V2ZXIgdGhlIGxhdHRlciBpcyBub3QgYSBwcm9wb3J0aW9uYWwgcmVwcmVzZW50YXRpb24gb2YgY292aWQgZGVhdGhzLg0KICAgIA0KDQojIEVwaWxvZ3VlDQoNCkJlbG93IGFyZSBzb21lIHN1bW1hcmllcyB5b3UgY2FuIHJlZmVyZW5jZSBhdCBhbnkgdGltZS4NCg0KIyMjIyBOdW1lcmljYWwgc3VtbWFyaWVzDQoNClRoZSBwcmltYXJ5IG51bWVyaWNhbCBzdW1tYXJpZXMgdXNlZCBpbiB0aGlzIGNvdXJzZSBpbmNsdWRlIHRoZSBtZWFuLCB0aGUgZml2ZS1udW1iZXIgc3VtbWFyeSwgYW5kIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24uICBUaGUgZnVuY3Rpb25zIGJlbG93IGNhbGN1bGF0ZSB0aGVzZSBzdW1tYXJpZXMgZm9yIGEgc2luZ2xlIHZhcmlhYmxlLCBvciBmb3IgdGhhdCB2YXJpYWJsZSBiYXNlZCBvbiB0aGUgdmFsdWUgb2YgYSBzZWNvbmQgY2F0ZWdvcmljYWwgdmFyaWFibGUuDQoNCiAgLSBtZWFuKH4gWSwgZGF0YSA9IERhdGFTZXROYW1lKSAgIyBtZWFuIG9mIFkgd2l0aG91dCBjb25zaWRlcmluZyBvdGhlciB2YXJpYWJsZXMNCiAgLSBtZWFuKFkgfiBYLCBkYXRhID0gRGF0YVNldE5hbWUpICAjIG1lYW4gb2YgWSBmb3IgZGlmZmVyZW50IHZhbHVlcyBvZiBYDQogIC0gc2QofiBZLCBkYXRhID0gRGF0YVNldE5hbWUpICAjIHN0YW5kYXJkIGRldmlhdGlvbiBvZiBZIA0KICAtIHNkKFkgfiBYLCBkYXRhID0gRGF0YVNldE5hbWUpICAjIHN0YW5kYXJkIGRldmlhdGlvbiBvZiBZIGZvciBkaWZmZXJlbnQgdmFsdWVzIG9mIFgNCiAgLSBmYXZzdGF0cyh+IFksIGRhdGEgPSBEYXRhU2V0TmFtZSkgICMgc3VtbWFyeSBzdGF0aXN0aWNzIG9mIFkgDQogIC0gZmF2c3RhdHMoWSB+IFgsIGRhdGEgPSBEYXRhU2V0TmFtZSkgICMgc3VtbWFyeSBzdGF0aXN0aWNzIG9mIFkgZm9yIGRpZmZlcmVudCB2YWx1ZXMgb2YgWA0KDQojIyMjIFZpc3VhbCBzdW1tYXJpZXMNCg0KVGhlIHByaW1hcnkgZ3JhcGhpY2FsIHJlcHJlc2VudGF0aW9ucyB1c2VkIGluIHRoaXMgY291cnNlIHdpbGwgYmUgYSBiYXJjaGFydHMsIGJveHBsb3RzLCBoaXN0b2dyYW1zIGFuZCBzY2F0dGVycGxvdHMuIEVhY2ggcGxvdCBoZWxwcyB0byB2aXN1YWxpemUgZGlmZmVyZW50IGFzcGVjdHMgb2YgYSBkYXRhc2V0LiANCg0KVGhlIGZ1bmN0aW9ucyB0aGF0IHdpbGwgYmUgdXNlZCB0byBnZW5lcmF0ZSB0aGVzZSBwbG90cyBhcmU6DQoNCiAgLSBnZl9ib3hwbG90KFkgfiBYLCBkYXRhID0gRGF0YVNldE5hbWUpICMgYm94cGxvdCBvZiBZIGZvciBlYWNoIHZhbHVlIG9mIFgsIGlmIHNwZWNpZmllZA0KICAtIGdmX2hpc3RvZ3JhbSh+WSwgZGF0YSA9IERhdGFTZXROYW1lKSAjIGhpc3RvZ3JhbSBvZiBZDQogIC0gZ2ZfcG9pbnQoWSB+IFgsIGRhdGEgPSBEYXRhU2V0TmFtZSkgIyBzY2F0dGVycGxvdCBvZiBZIHZlcnN1cyBYDQogIC0gZ2ZfYmFyKCB+WSwgZGF0YSA9IERhdGFTZXROYW1lKSAjIEJhciBjaGFydCBmb3IgYSBzaW5nbGUgdmFyaWFibGUNCiAgLSBnZl9iYXIoIH4gWCwgZmlsbCA9IH4gWSwgZGF0YSA9IERhdGFTZXROYW1lLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKCkpICMgc2lkZS1ieS1zaWRlIGJhciBjaGFydA0KICAtIGdmX2JhciggfiBYLCBmaWxsID0gfiBZLCBkYXRhID0gRGF0YVNldE5hbWUpICMgc3RhY2tlZCBiYXIgY2hhcnQNCg0K