Carefully read over the directions and be sure that you are using the appropriate data set as specified in each problem statement. Choosing an incorrect data set will cause you problems and hurt your grade. As a general note, be careful and check over all your problems a couple times to make sure you have completed all tasks!
The point totals for each problem are given after the problem number. I encourage you to carefully look these over as you work through the exam.
Note: If you’d like to enter a table in a “nice” format in markdown you can do so with something like:
Chester |
R guy |
33 |
Doug |
Carpenter |
60 |
Susan |
Astronaut |
42 |
Student Learning Objectives
This exam is designed to test your understanding of the following Student Learning Objectives from the syllabus:
- Create tidy data sets by carefully identifying the observational units and the types of variables that make up the data set.
- Make and interpret the Five Named Graphs: histograms, boxplots, barplots, scatter-plots, and line-graphs.
- Use multivariate thinking by producing and discussing appropriate plots showing the relationships between three (or more) variables.
- Identify the appropriate plot and type of analysis needed to answer a given social research question.
Here are the rules for the exam:
You are to take this exam by yourself. You shouldn’t be asking any questions of your classmates or discussing this exam in any way with your classmates or anyone else that may be able to help you with this exam. The only exception is Chester, but he will only answer clarifying questions. (Remember that I don’t know how to start. is not a good request for help.)
You can use the course textbooks, your labs (with my corrections), your homework and my answers, and any links directly from the class webpage at http://ismayc.github.io/teaching/soc301-f2016/. You cannot ask questions directly of someone on the Internet asking for help, but you can Google if you’d like assistance with something ggplot2
related. I urge you to stick to only using the types of code we have discussed in class though. If you aren’t sure about whether some R code is OK to use, you should be emailing me and if you really aren’t sure, you probably shouldn’t be using it.
Your plots should be done using the ggplot2
package and I recommend you load this package in the first R chunk. I will not accept plots (you will receive no credit) made using base R or other plotting systems in R or non-R tools.
Your exam should be reproducible. In other words, you should not be copying R output into the R Markdown file and all of the R code needed should be stored in chunks with the desired output immediately following the chunks. You’ll potentially lose all points for the Problem if this policy is not followed.
Typos will lead to a deduction of points, likely a significant number. You all have the ability to spellcheck and it shows that you have pride in your work and that you value my time when you do so. I also encourage you to have a friend / tutor read over your exam to make sure your sentences make sense. (DON’T ASK THEM FOR STATISTICAL/R HELP THOUGH!)
Agreement to exam rules
Please type your first and last name below next to NAME: and the DATE: acknowledging that you will follow these rules. Failure to follow these rules may result in failing the course due to academic dishonesty.
NAME:
DATE:
This exam will focus on using data made famous by Hans Rosling in his TED talk from 2006 entitled “The Best Stats You’ve Ever Seen.” While you’re not required to watch the video for this exam, it’s a really interesting talk and Hans has a unique way of discussing statistical ideas. The video is available here. The data discussed there has been updated and is now stored on the Gapminder project at http://www.gapminder.org. (You don’t need to go to the website, but it is a nice reference.)
Problem 1 (10 points)
One of the data sets presented on Gapminder gives a “democracy score” to each country for each year. I’ve extracted years 1952 to 2007 in five year increments in the CSV below. The “democracy score” is lowest at -10 and highest at 10. The more negative a value, the more non-democratic (autocratic) the country is rated to be. The more positive a value, the more democratic the country is rated to be. Run the R chunk below, which loads this data set into a data frame in R.
library(readr)
dem_score <- read_csv("dem_score.csv")
Is the dem_score
data frame a tidy data frame?
Answer:
If so, clearly explain how each of the properties of a tidy data set are met. If not, explain how many variables a corresponding tidy data set would have and layout what five rows of this tidy data set would look like using the note at the beginning of the exam.
Answer:
In the remaining problems on this exam, you’ll be either directly working with or using a subset of the data set read in the following chunk:
gap <- read_csv("gapminder.csv")
Problem 2 (10 points)
Use the str
function in the blank R chunk below to describe the different types of variables in this gap
dataset.
Which are categorical?
Answer:
Which are numeric?
Answer:
Why is one of the variables labeled as int
?
Answer:
Run the R chunk below:
gap$dem_rank <- factor(gap$dem_rank,
levels = c("Strongly Autocratic",
"Mildly Autocratic",
"Middle of the Road",
"Mildly Democratic",
"Strongly Democratic")
)
What is the purpose of this R chunk?
Answer:
How does the factor
function help with plots? (You may be able to better answer this question after working through the entire exam.)
Answer:
Problem 3 (10 points)
You may have already guessed by running View(gap)
that the variables correspond to measurements on a country in a year. Specifically,
lifeExp
corresponds to (average) life expectancy,
pop
corresponds to an estimate of population,
gdpPercap
corresponds to gross domestic product per capita, and
dem_score
is a categorical version of the values in the dem_score
data frame from earlier.
What is the observational unit for this gap
data frame? Remember to be as specific as possible.
Answer:
The following code attempts to extract all values for pop
in gap
except for entries with indices 1, 10, 14, 15, and 1000 and assigns that to a new vector called few_pop
. Explain what is wrong with the code (there are at least 6 things) and correct the code to give the desired result.
few_pop -> gap%pop[[c(-1, 10, 14-15), 1000]]
Answer:
Problem 4 (10 points)
As you look over the gap
data frame, you’ll notice that each country has 12 entries for the 12 different years with information. For the purposes of this problem, we will focus on only 2007. (You’ll see more details on doing procedures like this in Chapter 5 and on your next lab.) The chunk below creates a new data frame focused only on a year
value of 2007 in the gap
data frame.
gap2007 <- dplyr::filter(gap, year == 2007)
Produce an appropriate plot looking at the frequency of countries by subRegion
in the gap2007
data frame. Also, fill based on region
. Your horizontal axis labels will likely be jumbled up so you need to add (+
) theme(axis.text.x = element_text = 60, hjust = 1)
as a layer to the plot.
Which subRegion
has the most countries?
Answer:
Which subRegion
appears in two different region
s?
Answer:
Which region
is made up entirely of only one subRegion
?
Answer:
Problem 5 (20 points)
Using the gap2007
data frame, produce an appropriate plot comparing the relationship of gdpPercap
on the horizontal axis and lifeExp
on the vertical axis.
Would you describe the overall relationship as strongly linear? Explain in two or three sentences what the pattern shows.
Answer:
Looking over this plot and focusing on gdpPercap
smaller than 5000, how many countries have an average life expectancy over 75?
Answer:
Does the country with the highest gdpPercap
also have the highest lifeExp
? If not, around what gdpPercap
corresponds to the highest lifeExp
?
Answer:
EXTENDING KNOWLEDGE Produce the same plot asked for in part a. but now change the transparency based on values of dem_rank
and change the size to be based on population.
Describe in two or three sentences how this plot provides more insights into your responses to parts c. and d.
Answer:
Problem 6 (20 points)
When you use View(gap2007)
, you’ll notice that many of the entries for dem_rank
have a value of NA
. We can remove all rows that have any of these NA
values and create a new smaller data set using
gap2007small <- na.omit(gap2007)
What do NA
values mean in R?
Answer:
What are some reasons why NA
values may exist in the data? (This is more of a practical question than a statistical one.)
Answer:
Produce an appropriate plot looking at the distribution of gdpPercap
in gap2007small
. Change the color of the inside of the plotted values and the border of the plotted values as you have done in labs and in class. (The words aren’t intended to be vague here, but I don’t want to tell you the answer of which plot to make…)
Produce an appropriate plot looking at the distribution of gdpPercap
over dem_rank
in gap2007small
. Make sure to tweak the default color settings to your liking.
EXTENDING KNOWLEDGE Produce a faceted boxplot (you read that right) looking at the distribution of gdpPercap
over values of region
in combination with dem_rank
in gap2007small
. Note that you’ll need to add the tilting of the axis labels via theme(axis.text.x = element_text = 60, hjust = 1)
again.
EXTENDING KNOWLEDGE Focusing on the Strongly Democratic
small multiple plot produced in part e., describe how the 25th, 50th, and 75th percentile vary across the levels of region
.
Answer:
Problem 7 (10 points)
Another feature we will see in Chapter 5 is the ability to choose specific values from a list and filter the data set according to this. Below we will pick 6 countries from different regions in the world and then make an appropriate plot to see how each country’s life expectancy has changed over time.
country_list <- c("Argentina", "United States", "Liberia", "Pakistan", "Finland", "New Zealand")
six_countries <- dplyr::filter(gap, country %in% country_list)
Now run View(six_countries)
in the R console to get a sense for what this new data set looks like.
EXTENDING KNOWLEDGE Produce the appropriate plot showing how the life expectancy from each country in six_countries
has changed over time. You should color based on subRegion
.
What is the name of the country in six_countries
that had the lowest life expectancy in 1970?
Answer:
Which three countries overlapped on the plot?
Answer:
What is the only country to show a decline in life expectancy? In what years did this drop occur?
Answer:
Which country showed the greatest increase in life expectancy from 1952 to 2007?
Answer:
Problem 8 (8 points)
Identify AT LEAST two variables that have not been analyzed together so far on this exam in the gap
data set. Produce a plot looking at the relationship between the variables and discuss in three or four sentences the major findings from your plot.
Answer:
Closing notes
PRESS THE SPELLCHECK BUTTON!
Make sure to Knit HTML your Rmd when you are done. You may also find errors by knitting so you are encouraged to Knit HTML frequently as you work on this exam.
Reflect (2 points for completion)
Just as with the labs, I want you to take a bit of time to reflect on what you learned via this take home exam. I expect some of the problems to be challenging but I believe you are all capable of figuring them out if you push yourselves to learn more and review the material we have covered so far. Resist the urge to go to the book immediately for an answer or go to Google to ask questions. You should try to think about a problem for 15 minutes or so to see if an answer comes to you first. You may also find value in skipping problems that you don’t immediately know how to do as other problems may guide you to the correct reasoning.
Answer each of these reflections in two or more complete sentences for full credit.
What surprised you the most about this exam?
Response:
Looking back over the Take Home Exam - Study Guide, do you see how many of the points there were addressed on this exam? If not, which Problems here do you believe were not addressed?
Response:
You’ve come a long way already in learning how to use R. How do you feel today compared to how you felt in the first week or two of class with regards to this?
Response:
What have you learned from a social perspective by analyzing the gap
data? What new questions do you have about the data?
Response:
LS0tCnRpdGxlOiAiVGFrZSBIb21lIEV4YW0gMSAtIEZhbGwgMjAxNiIKc3VidGl0bGU6ICJTT0MgMzAxIHdpdGggRHIuIENoZXN0ZXIgSXNtYXkgLSBQYWNpZmljIFVuaXZlcnNpdHkiCmF1dGhvcjogIkVudGVyIE5hbWUgSGVyZSIKZGF0ZTogIkR1ZSBvbiBNb25kYXksIE9jdG9iZXIgMTAsIDIwMTYgYXQgMiBQTSBQRFQiCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKLS0tCgoqKioKCkNhcmVmdWxseSByZWFkIG92ZXIgdGhlIGRpcmVjdGlvbnMgYW5kIGJlIHN1cmUgdGhhdCB5b3UgYXJlIHVzaW5nIHRoZSBhcHByb3ByaWF0ZSBkYXRhIHNldCBhcyBzcGVjaWZpZWQgaW4gZWFjaCBwcm9ibGVtIHN0YXRlbWVudC4gIENob29zaW5nIGFuIGluY29ycmVjdCBkYXRhIHNldCB3aWxsIGNhdXNlIHlvdSBwcm9ibGVtcyBhbmQgaHVydCB5b3VyIGdyYWRlLiAgQXMgYSBnZW5lcmFsIG5vdGUsIGJlIGNhcmVmdWwgYW5kIGNoZWNrIG92ZXIgYWxsIHlvdXIgcHJvYmxlbXMgYSBjb3VwbGUgdGltZXMgdG8gbWFrZSBzdXJlIHlvdSBoYXZlIGNvbXBsZXRlZCBhbGwgdGFza3MhCgpUaGUgcG9pbnQgdG90YWxzIGZvciBlYWNoIHByb2JsZW0gYXJlIGdpdmVuIGFmdGVyIHRoZSBwcm9ibGVtIG51bWJlci4gIEkgZW5jb3VyYWdlIHlvdSB0byBjYXJlZnVsbHkgbG9vayB0aGVzZSBvdmVyIGFzIHlvdSB3b3JrIHRocm91Z2ggdGhlIGV4YW0uCgoqKk5vdGUqKjogIElmIHlvdSdkIGxpa2UgdG8gZW50ZXIgYSB0YWJsZSBpbiBhICJuaWNlIiBmb3JtYXQgaW4gbWFya2Rvd24geW91IGNhbiBkbyBzbyB3aXRoIHNvbWV0aGluZyBsaWtlOgoKCm5hbWUgICAgIHwgICAgcm9sZSAgICAgfCAgICAgYWdlCi0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0KQ2hlc3RlciAgfCAgICBSIGd1eSAgICB8ICAgICAgMzMKRG91ZyAgICAgfCAgQ2FycGVudGVyICB8ICAgICAgNjAKU3VzYW4gICAgfCAgIEFzdHJvbmF1dCB8ICAgICAgNDIKCioqKgoKIyMgU3R1ZGVudCBMZWFybmluZyBPYmplY3RpdmVzCgpUaGlzIGV4YW0gaXMgZGVzaWduZWQgdG8gdGVzdCB5b3VyIHVuZGVyc3RhbmRpbmcgb2YgdGhlIGZvbGxvd2luZyBTdHVkZW50IExlYXJuaW5nIE9iamVjdGl2ZXMgZnJvbSB0aGUgc3lsbGFidXM6CgotIENyZWF0ZSB0aWR5IGRhdGEgc2V0cyBieSBjYXJlZnVsbHkgaWRlbnRpZnlpbmcgdGhlIG9ic2VydmF0aW9uYWwgdW5pdHMgYW5kIHRoZSB0eXBlcyBvZiB2YXJpYWJsZXMgdGhhdCBtYWtlIHVwIHRoZSBkYXRhIHNldC4KLSBNYWtlIGFuZCBpbnRlcnByZXQgdGhlIEZpdmUgTmFtZWQgR3JhcGhzOiBoaXN0b2dyYW1zLCBib3hwbG90cywgYmFycGxvdHMsIHNjYXR0ZXItcGxvdHMsIGFuZCBsaW5lLWdyYXBocy4KLSBVc2UgbXVsdGl2YXJpYXRlIHRoaW5raW5nIGJ5IHByb2R1Y2luZyBhbmQgZGlzY3Vzc2luZyBhcHByb3ByaWF0ZSBwbG90cyBzaG93aW5nIHRoZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gdGhyZWUgKG9yIG1vcmUpIHZhcmlhYmxlcy4KLSBJZGVudGlmeSB0aGUgYXBwcm9wcmlhdGUgcGxvdCBhbmQgdHlwZSBvZiBhbmFseXNpcyBuZWVkZWQgdG8gYW5zd2VyIGEgZ2l2ZW4gc29jaWFsIHJlc2VhcmNoIHF1ZXN0aW9uLgoKKioqCgpIZXJlIGFyZSB0aGUgcnVsZXMgZm9yIHRoZSBleGFtOgoKMS4gWW91IGFyZSB0byB0YWtlIHRoaXMgZXhhbSBieSB5b3Vyc2VsZi4gIFlvdSBzaG91bGRuJ3QgYmUgYXNraW5nIGFueSBxdWVzdGlvbnMgb2YgeW91ciBjbGFzc21hdGVzIG9yIGRpc2N1c3NpbmcgdGhpcyBleGFtIGluIGFueSB3YXkgd2l0aCB5b3VyIGNsYXNzbWF0ZXMgb3IgYW55b25lIGVsc2UgdGhhdCBtYXkgYmUgYWJsZSB0byBoZWxwIHlvdSB3aXRoIHRoaXMgZXhhbS4gIFRoZSBvbmx5IGV4Y2VwdGlvbiBpcyBDaGVzdGVyLCBidXQgaGUgd2lsbCBvbmx5IGFuc3dlciBjbGFyaWZ5aW5nIHF1ZXN0aW9ucy4gKFJlbWVtYmVyIHRoYXQgKkkgZG9uJ3Qga25vdyBob3cgdG8gc3RhcnQuKiBpcyBub3QgYSBnb29kIHJlcXVlc3QgZm9yIGhlbHAuKQoKMi4gWW91IGNhbiB1c2UgdGhlIGNvdXJzZSB0ZXh0Ym9va3MsIHlvdXIgbGFicyAod2l0aCBteSBjb3JyZWN0aW9ucyksIHlvdXIgaG9tZXdvcmsgYW5kIG15IGFuc3dlcnMsIGFuZCBhbnkgbGlua3MgZGlyZWN0bHkgZnJvbSB0aGUgY2xhc3Mgd2VicGFnZSBhdCA8aHR0cDovL2lzbWF5Yy5naXRodWIuaW8vdGVhY2hpbmcvc29jMzAxLWYyMDE2Lz4uICBZb3UgY2Fubm90IGFzayBxdWVzdGlvbnMgZGlyZWN0bHkgb2Ygc29tZW9uZSBvbiB0aGUgSW50ZXJuZXQgYXNraW5nIGZvciBoZWxwLCBidXQgeW91IGNhbiBHb29nbGUgaWYgeW91J2QgbGlrZSBhc3Npc3RhbmNlIHdpdGggc29tZXRoaW5nIGBnZ3Bsb3QyYCByZWxhdGVkLiAgSSB1cmdlIHlvdSB0byBzdGljayB0byBvbmx5IHVzaW5nIHRoZSB0eXBlcyBvZiBjb2RlIHdlIGhhdmUgZGlzY3Vzc2VkIGluIGNsYXNzIHRob3VnaC4gIElmIHlvdSBhcmVuJ3Qgc3VyZSBhYm91dCB3aGV0aGVyIHNvbWUgUiBjb2RlIGlzIE9LIHRvIHVzZSwgeW91IHNob3VsZCBiZSBlbWFpbGluZyBtZSBhbmQgaWYgeW91IHJlYWxseSBhcmVuJ3Qgc3VyZSwgeW91IHByb2JhYmx5IHNob3VsZG4ndCBiZSB1c2luZyBpdC4KCjMuIFlvdXIgcGxvdHMgc2hvdWxkIGJlIGRvbmUgdXNpbmcgdGhlIGBnZ3Bsb3QyYCBwYWNrYWdlIGFuZCBJIHJlY29tbWVuZCB5b3UgbG9hZCB0aGlzIHBhY2thZ2UgaW4gdGhlIGZpcnN0IFIgY2h1bmsuICBJIHdpbGwgbm90IGFjY2VwdCBwbG90cyAoeW91IHdpbGwgcmVjZWl2ZSBubyBjcmVkaXQpIG1hZGUgdXNpbmcgYmFzZSBSIG9yIG90aGVyIHBsb3R0aW5nIHN5c3RlbXMgaW4gUiBvciBub24tUiB0b29scy4gCgo0LiAgWW91ciBleGFtIHNob3VsZCBiZSByZXByb2R1Y2libGUuICBJbiBvdGhlciB3b3JkcywgeW91IHNob3VsZCBub3QgYmUgY29weWluZyBSIG91dHB1dCBpbnRvIHRoZSBSIE1hcmtkb3duIGZpbGUgYW5kIGFsbCBvZiB0aGUgUiBjb2RlIG5lZWRlZCBzaG91bGQgYmUgc3RvcmVkIGluIGNodW5rcyB3aXRoIHRoZSBkZXNpcmVkIG91dHB1dCBpbW1lZGlhdGVseSBmb2xsb3dpbmcgdGhlIGNodW5rcy4gIFlvdSdsbCBwb3RlbnRpYWxseSBsb3NlIGFsbCBwb2ludHMgZm9yIHRoZSBQcm9ibGVtIGlmIHRoaXMgcG9saWN5IGlzIG5vdCBmb2xsb3dlZC4KCjUuICBUeXBvcyB3aWxsIGxlYWQgdG8gYSBkZWR1Y3Rpb24gb2YgcG9pbnRzLCBsaWtlbHkgYSBzaWduaWZpY2FudCBudW1iZXIuIFlvdSBhbGwgaGF2ZSB0aGUgYWJpbGl0eSB0byBzcGVsbGNoZWNrIGFuZCBpdCBzaG93cyB0aGF0IHlvdSBoYXZlIHByaWRlIGluIHlvdXIgd29yayBhbmQgdGhhdCB5b3UgdmFsdWUgbXkgdGltZSB3aGVuIHlvdSBkbyBzby4gIEkgYWxzbyBlbmNvdXJhZ2UgeW91IHRvIGhhdmUgYSBmcmllbmQgLyB0dXRvciByZWFkIG92ZXIgeW91ciBleGFtIHRvIG1ha2Ugc3VyZSB5b3VyIHNlbnRlbmNlcyBtYWtlIHNlbnNlLiAgKERPTidUIEFTSyBUSEVNIEZPUiBTVEFUSVNUSUNBTC9SIEhFTFAgVEhPVUdIISkKCioqKgoKIyMgQWdyZWVtZW50IHRvIGV4YW0gcnVsZXMKClBsZWFzZSB0eXBlIHlvdXIgZmlyc3QgYW5kIGxhc3QgbmFtZSBiZWxvdyBuZXh0IHRvICoqTkFNRToqKiBhbmQgdGhlICoqREFURToqKiBhY2tub3dsZWRnaW5nIHRoYXQgeW91IHdpbGwgZm9sbG93IHRoZXNlIHJ1bGVzLiAgRmFpbHVyZSB0byBmb2xsb3cgdGhlc2UgcnVsZXMgbWF5IHJlc3VsdCBpbiBmYWlsaW5nIHRoZSBjb3Vyc2UgZHVlIHRvIGFjYWRlbWljIGRpc2hvbmVzdHkuCgoqKk5BTUU6KiogCgoqKkRBVEU6KiogCgotLS0KClRoaXMgZXhhbSB3aWxsIGZvY3VzIG9uIHVzaW5nIGRhdGEgbWFkZSBmYW1vdXMgYnkgSGFucyBSb3NsaW5nIGluIGhpcyBURUQgdGFsayBmcm9tIDIwMDYgZW50aXRsZWQgIlRoZSBCZXN0IFN0YXRzIFlvdSd2ZSBFdmVyIFNlZW4uIiAgV2hpbGUgeW91J3JlIG5vdCByZXF1aXJlZCB0byB3YXRjaCB0aGUgdmlkZW8gZm9yIHRoaXMgZXhhbSwgaXQncyBhIHJlYWxseSBpbnRlcmVzdGluZyB0YWxrIGFuZCBIYW5zIGhhcyBhIHVuaXF1ZSB3YXkgb2YgZGlzY3Vzc2luZyBzdGF0aXN0aWNhbCBpZGVhcy4gIFRoZSB2aWRlbyBpcyBhdmFpbGFibGUgW2hlcmVdKGh0dHBzOi8vd3d3LnRlZC5jb20vdGFsa3MvaGFuc19yb3NsaW5nX3Nob3dzX3RoZV9iZXN0X3N0YXRzX3lvdV92ZV9ldmVyX3NlZW4/bGFuZ3VhZ2U9ZW4pLiAgVGhlIGRhdGEgZGlzY3Vzc2VkIHRoZXJlIGhhcyBiZWVuIHVwZGF0ZWQgYW5kIGlzIG5vdyBzdG9yZWQgb24gdGhlIEdhcG1pbmRlciBwcm9qZWN0IGF0IDxodHRwOi8vd3d3LmdhcG1pbmRlci5vcmc+LiAgKFlvdSBkb24ndCBuZWVkIHRvIGdvIHRvIHRoZSB3ZWJzaXRlLCBidXQgaXQgaXMgYSBuaWNlIHJlZmVyZW5jZS4pCgojIyBQcm9ibGVtIDEgKDEwIHBvaW50cykKCk9uZSBvZiB0aGUgZGF0YSBzZXRzIHByZXNlbnRlZCBvbiBHYXBtaW5kZXIgZ2l2ZXMgYSAiZGVtb2NyYWN5IHNjb3JlIiB0byBlYWNoIGNvdW50cnkgZm9yIGVhY2ggeWVhci4gIEkndmUgZXh0cmFjdGVkIHllYXJzIDE5NTIgdG8gMjAwNyBpbiBmaXZlIHllYXIgaW5jcmVtZW50cyBpbiB0aGUgQ1NWIGJlbG93LiAgVGhlICJkZW1vY3JhY3kgc2NvcmUiIGlzIGxvd2VzdCBhdCAtMTAgYW5kIGhpZ2hlc3QgYXQgMTAuICBUaGUgbW9yZSBuZWdhdGl2ZSBhIHZhbHVlLCB0aGUgbW9yZSBub24tZGVtb2NyYXRpYyAoYXV0b2NyYXRpYykgdGhlIGNvdW50cnkgaXMgcmF0ZWQgdG8gYmUuICBUaGUgbW9yZSBwb3NpdGl2ZSBhIHZhbHVlLCB0aGUgbW9yZSBkZW1vY3JhdGljIHRoZSBjb3VudHJ5IGlzIHJhdGVkIHRvIGJlLiAgUnVuIHRoZSBSIGNodW5rIGJlbG93LCB3aGljaCBsb2FkcyB0aGlzIGRhdGEgc2V0IGludG8gYSBkYXRhIGZyYW1lIGluIFIuCgpgYGB7ciBsb2FkX2RlbV9zY29yZSwgbWVzc2FnZT1GQUxTRX0KbGlicmFyeShyZWFkcikKZGVtX3Njb3JlIDwtIHJlYWRfY3N2KCJkZW1fc2NvcmUuY3N2IikKYGBgCgphLiBJcyB0aGUgYGRlbV9zY29yZWAgZGF0YSBmcmFtZSBhICoqdGlkeSoqIGRhdGEgZnJhbWU/ICAKCiAgICAqKkFuc3dlcioqOiAKCmIuIElmIHNvLCBjbGVhcmx5IGV4cGxhaW4gaG93IGVhY2ggb2YgdGhlIHByb3BlcnRpZXMgb2YgYSAqKnRpZHkqKiBkYXRhIHNldCBhcmUgbWV0LiAgSWYgbm90LCBleHBsYWluIGhvdyBtYW55IHZhcmlhYmxlcyBhIGNvcnJlc3BvbmRpbmcgKip0aWR5KiogZGF0YSBzZXQgd291bGQgaGF2ZSBhbmQgbGF5b3V0IHdoYXQgZml2ZSByb3dzIG9mIHRoaXMgKip0aWR5KiogZGF0YSBzZXQgd291bGQgbG9vayBsaWtlIHVzaW5nIHRoZSBub3RlIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGV4YW0uCgogICAgKipBbnN3ZXIqKjogCgoqKioKCkluIHRoZSByZW1haW5pbmcgcHJvYmxlbXMgb24gdGhpcyBleGFtLCB5b3UnbGwgYmUgZWl0aGVyIGRpcmVjdGx5IHdvcmtpbmcgd2l0aCBvciB1c2luZyBhIHN1YnNldCBvZiB0aGUgZGF0YSBzZXQgcmVhZCBpbiB0aGUgZm9sbG93aW5nIGNodW5rOgoKYGBge3IgbG9hZF9nYXAsIG1lc3NhZ2U9RkFMU0V9CmdhcCA8LSByZWFkX2NzdigiZ2FwbWluZGVyLmNzdiIpCmBgYAoKCiMjIFByb2JsZW0gMiAoMTAgcG9pbnRzKQoKVXNlIHRoZSBgc3RyYCBmdW5jdGlvbiBpbiB0aGUgYmxhbmsgUiBjaHVuayBiZWxvdyB0byBkZXNjcmliZSB0aGUgZGlmZmVyZW50IHR5cGVzIG9mIHZhcmlhYmxlcyBpbiB0aGlzIGBnYXBgIGRhdGFzZXQuCgoKYGBge3J9CgpgYGAKCmEuIFdoaWNoIGFyZSBjYXRlZ29yaWNhbD8KCiAgICAqKkFuc3dlcioqOgoKYi4gV2hpY2ggYXJlIG51bWVyaWM/CgogICAgKipBbnN3ZXIqKjoKCmMuIFdoeSBpcyBvbmUgb2YgdGhlIHZhcmlhYmxlcyBsYWJlbGVkIGFzIGBpbnRgPwoKICAgICoqQW5zd2VyKio6CgpkLiBSdW4gdGhlIFIgY2h1bmsgYmVsb3c6CgogICAgYGBge3IgZmFjdG9yfQogICAgZ2FwJGRlbV9yYW5rIDwtIGZhY3RvcihnYXAkZGVtX3JhbmssIAogICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIlN0cm9uZ2x5IEF1dG9jcmF0aWMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNaWxkbHkgQXV0b2NyYXRpYyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWlkZGxlIG9mIHRoZSBSb2FkIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWlsZGx5IERlbW9jcmF0aWMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdHJvbmdseSBEZW1vY3JhdGljIikKICAgICAgICAgICAgICAgICAgICAgICApCiAgICBgYGAKCiAgICBpLiBXaGF0IGlzIHRoZSBwdXJwb3NlIG9mIHRoaXMgUiBjaHVuaz8gIAogICAgCiAgICAgICAgKipBbnN3ZXIqKjogCiAgICAKICAgIGlpLiBIb3cgZG9lcyB0aGUgYGZhY3RvcmAgZnVuY3Rpb24gaGVscCB3aXRoIHBsb3RzPyAgKFlvdSBtYXkgYmUgYWJsZSB0byBiZXR0ZXIgYW5zd2VyIHRoaXMgcXVlc3Rpb24gYWZ0ZXIgd29ya2luZyB0aHJvdWdoIHRoZSBlbnRpcmUgZXhhbS4pCiAgICAKICAgICAgICAqKkFuc3dlcioqOgoKKioqCgojIyBQcm9ibGVtIDMgKDEwIHBvaW50cykKCllvdSBtYXkgaGF2ZSBhbHJlYWR5IGd1ZXNzZWQgYnkgcnVubmluZyBgVmlldyhnYXApYCB0aGF0IHRoZSB2YXJpYWJsZXMgY29ycmVzcG9uZCB0byBtZWFzdXJlbWVudHMgb24gYSBjb3VudHJ5IGluIGEgeWVhci4gIFNwZWNpZmljYWxseSwgCgogIC0gYGxpZmVFeHBgIGNvcnJlc3BvbmRzIHRvIChhdmVyYWdlKSBsaWZlIGV4cGVjdGFuY3ksIAogIC0gYHBvcGAgY29ycmVzcG9uZHMgdG8gYW4gZXN0aW1hdGUgb2YgcG9wdWxhdGlvbiwgCiAgLSBgZ2RwUGVyY2FwYCBjb3JyZXNwb25kcyB0byBncm9zcyBkb21lc3RpYyBwcm9kdWN0IHBlciBjYXBpdGEsIGFuZCAKICAtIGBkZW1fc2NvcmVgIGlzIGEgY2F0ZWdvcmljYWwgdmVyc2lvbiBvZiB0aGUgdmFsdWVzIGluIHRoZSBgZGVtX3Njb3JlYCBkYXRhIGZyYW1lIGZyb20gZWFybGllci4KCmEuIFdoYXQgaXMgdGhlIG9ic2VydmF0aW9uYWwgdW5pdCBmb3IgdGhpcyBgZ2FwYCBkYXRhIGZyYW1lPyAgUmVtZW1iZXIgdG8gYmUgYXMgc3BlY2lmaWMgYXMgcG9zc2libGUuCgogICAgKipBbnN3ZXIqKjoKCmIuIFRoZSBmb2xsb3dpbmcgY29kZSBhdHRlbXB0cyB0byBleHRyYWN0IGFsbCB2YWx1ZXMgZm9yIGBwb3BgIGluIGBnYXBgIGV4Y2VwdCBmb3IgZW50cmllcyB3aXRoIGluZGljZXMgMSwgMTAsIDE0LCAxNSwgYW5kIDEwMDAgYW5kIGFzc2lnbnMgdGhhdCB0byBhIG5ldyB2ZWN0b3IgY2FsbGVkIGBmZXdfcG9wYC4gIEV4cGxhaW4gd2hhdCBpcyB3cm9uZyB3aXRoIHRoZSBjb2RlICh0aGVyZSBhcmUgYXQgbGVhc3QgNiB0aGluZ3MpIGFuZCBjb3JyZWN0IHRoZSBjb2RlIHRvIGdpdmUgdGhlIGRlc2lyZWQgcmVzdWx0LgoKICAgIGBgYHtyIGV4dHJhY3QsIGV2YWw9RkFMU0V9CiAgICBmZXdfcG9wIC0+IGdhcCVwb3BbW2MoLTEsIDEwLCAxNC0xNSksIDEwMDBdXQogICAgYGBgCiAgICAKICAgICoqQW5zd2VyKio6CgogICAgYGBge3J9CgogICAgYGBgCgoKKioqCgojIyBQcm9ibGVtIDQgKDEwIHBvaW50cykKCkFzIHlvdSBsb29rIG92ZXIgdGhlIGBnYXBgIGRhdGEgZnJhbWUsIHlvdSdsbCBub3RpY2UgdGhhdCBlYWNoIGNvdW50cnkgaGFzIDEyIGVudHJpZXMgZm9yIHRoZSAxMiBkaWZmZXJlbnQgeWVhcnMgd2l0aCBpbmZvcm1hdGlvbi4gIEZvciB0aGUgcHVycG9zZXMgb2YgdGhpcyBwcm9ibGVtLCB3ZSB3aWxsIGZvY3VzIG9uIG9ubHkgMjAwNy4gIChZb3UnbGwgc2VlIG1vcmUgZGV0YWlscyBvbiBkb2luZyBwcm9jZWR1cmVzIGxpa2UgdGhpcyBpbiBDaGFwdGVyIDUgYW5kIG9uIHlvdXIgbmV4dCBsYWIuKSAgVGhlIGNodW5rIGJlbG93IGNyZWF0ZXMgYSBuZXcgZGF0YSBmcmFtZSBmb2N1c2VkIG9ubHkgb24gYSBgeWVhcmAgdmFsdWUgb2YgMjAwNyBpbiB0aGUgYGdhcGAgZGF0YSBmcmFtZS4KCmBgYHtyIGdhcDIwMDd9CmdhcDIwMDcgPC0gZHBseXI6OmZpbHRlcihnYXAsIHllYXIgPT0gMjAwNykKYGBgCgphLiBQcm9kdWNlIGFuIGFwcHJvcHJpYXRlIHBsb3QgbG9va2luZyBhdCB0aGUgZnJlcXVlbmN5IG9mIGNvdW50cmllcyBieSBgc3ViUmVnaW9uYCBpbiB0aGUgYGdhcDIwMDdgIGRhdGEgZnJhbWUuICBBbHNvLCBmaWxsIGJhc2VkIG9uIGByZWdpb25gLiAgWW91ciBob3Jpem9udGFsIGF4aXMgbGFiZWxzIHdpbGwgbGlrZWx5IGJlIGp1bWJsZWQgdXAgc28geW91IG5lZWQgdG8gYWRkIChgK2ApIGB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCA9IDYwLCBoanVzdCA9IDEpYCBhcyBhIGxheWVyIHRvIHRoZSBwbG90LgoKYGBge3J9CgpgYGAKCmIuIFdoaWNoIGBzdWJSZWdpb25gIGhhcyB0aGUgbW9zdCBjb3VudHJpZXM/CgogICAgKipBbnN3ZXIqKjoKCmMuIFdoaWNoIGBzdWJSZWdpb25gIGFwcGVhcnMgaW4gdHdvIGRpZmZlcmVudCBgcmVnaW9uYHM/CgogICAgKipBbnN3ZXIqKjoKCmQuIFdoaWNoIGByZWdpb25gIGlzIG1hZGUgdXAgZW50aXJlbHkgb2Ygb25seSBvbmUgYHN1YlJlZ2lvbmA/CgogICAgKipBbnN3ZXIqKjoKCioqKgoKIyMgUHJvYmxlbSA1ICgyMCBwb2ludHMpCgphLiBVc2luZyB0aGUgYGdhcDIwMDdgIGRhdGEgZnJhbWUsIHByb2R1Y2UgYW4gYXBwcm9wcmlhdGUgcGxvdCBjb21wYXJpbmcgdGhlIHJlbGF0aW9uc2hpcCBvZiBgZ2RwUGVyY2FwYCBvbiB0aGUgaG9yaXpvbnRhbCBheGlzIGFuZCBgbGlmZUV4cGAgb24gdGhlIHZlcnRpY2FsIGF4aXMuICAKCmBgYHtyfQoKYGBgCgoKYi4gV291bGQgeW91IGRlc2NyaWJlIHRoZSBvdmVyYWxsIHJlbGF0aW9uc2hpcCBhcyBzdHJvbmdseSBsaW5lYXI/ICBFeHBsYWluIGluIHR3byBvciB0aHJlZSBzZW50ZW5jZXMgd2hhdCB0aGUgcGF0dGVybiBzaG93cy4KCiAgICAqKkFuc3dlcioqOgoKYy4gTG9va2luZyBvdmVyIHRoaXMgcGxvdCBhbmQgZm9jdXNpbmcgb24gYGdkcFBlcmNhcGAgc21hbGxlciB0aGFuIDUwMDAsIGhvdyBtYW55IGNvdW50cmllcyBoYXZlIGFuIGF2ZXJhZ2UgbGlmZSBleHBlY3RhbmN5IG92ZXIgNzU/CgogICAgKipBbnN3ZXIqKjoKCmQuIERvZXMgdGhlIGNvdW50cnkgd2l0aCB0aGUgaGlnaGVzdCBgZ2RwUGVyY2FwYCBhbHNvIGhhdmUgdGhlIGhpZ2hlc3QgYGxpZmVFeHBgPyAgSWYgbm90LCBhcm91bmQgd2hhdCBgZ2RwUGVyY2FwYCBjb3JyZXNwb25kcyB0byB0aGUgaGlnaGVzdCBgbGlmZUV4cGA/CgogICAgKipBbnN3ZXIqKjoKCmUuICoqRVhURU5ESU5HIEtOT1dMRURHRSoqIFByb2R1Y2UgdGhlIHNhbWUgcGxvdCBhc2tlZCBmb3IgaW4gcGFydCBhLiBidXQgbm93IGNoYW5nZSB0aGUgdHJhbnNwYXJlbmN5IGJhc2VkIG9uIHZhbHVlcyBvZiBgZGVtX3JhbmtgIGFuZCBjaGFuZ2UgdGhlIHNpemUgdG8gYmUgYmFzZWQgb24gcG9wdWxhdGlvbi4KCmBgYHtyfQoKYGBgCgpmLiAgRGVzY3JpYmUgaW4gdHdvIG9yIHRocmVlIHNlbnRlbmNlcyBob3cgdGhpcyBwbG90IHByb3ZpZGVzIG1vcmUgaW5zaWdodHMgaW50byB5b3VyIHJlc3BvbnNlcyB0byBwYXJ0cyBjLiBhbmQgZC4KCiAgICAqKkFuc3dlcioqOgoKKioqCgojIyBQcm9ibGVtIDYgKDIwIHBvaW50cykKCldoZW4geW91IHVzZSBgVmlldyhnYXAyMDA3KWAsIHlvdSdsbCBub3RpY2UgdGhhdCBtYW55IG9mIHRoZSBlbnRyaWVzIGZvciBgZGVtX3JhbmtgIGhhdmUgYSB2YWx1ZSBvZiBgTkFgLiAgV2UgY2FuIHJlbW92ZSBhbGwgcm93cyB0aGF0IGhhdmUgYW55IG9mIHRoZXNlIGBOQWAgdmFsdWVzIGFuZCBjcmVhdGUgYSBuZXcgc21hbGxlciBkYXRhIHNldCB1c2luZyAKCmBgYHtyIGdhcHNtYWxsfQpnYXAyMDA3c21hbGwgPC0gbmEub21pdChnYXAyMDA3KSAKYGBgCgphLiBXaGF0IGRvIGBOQWAgdmFsdWVzIG1lYW4gaW4gUj8KCiAgICAqKkFuc3dlcioqOgoKYi4gV2hhdCBhcmUgc29tZSByZWFzb25zIHdoeSBgTkFgIHZhbHVlcyBtYXkgZXhpc3QgaW4gdGhlIGRhdGE/IChUaGlzIGlzIG1vcmUgb2YgYSBwcmFjdGljYWwgcXVlc3Rpb24gdGhhbiBhIHN0YXRpc3RpY2FsIG9uZS4pCgogICAgKipBbnN3ZXIqKjoKCmMuIFByb2R1Y2UgYW4gYXBwcm9wcmlhdGUgcGxvdCBsb29raW5nIGF0IHRoZSBkaXN0cmlidXRpb24gb2YgYGdkcFBlcmNhcGAgaW4gYGdhcDIwMDdzbWFsbGAuICBDaGFuZ2UgdGhlIGNvbG9yIG9mIHRoZSBpbnNpZGUgb2YgdGhlIHBsb3R0ZWQgdmFsdWVzIGFuZCB0aGUgYm9yZGVyIG9mIHRoZSBwbG90dGVkIHZhbHVlcyBhcyB5b3UgaGF2ZSBkb25lIGluIGxhYnMgYW5kIGluIGNsYXNzLiAgKFRoZSB3b3JkcyBhcmVuJ3QgaW50ZW5kZWQgdG8gYmUgdmFndWUgaGVyZSwgYnV0IEkgZG9uJ3Qgd2FudCB0byB0ZWxsIHlvdSB0aGUgYW5zd2VyIG9mIHdoaWNoIHBsb3QgdG8gbWFrZS4uLikKCmBgYHtyfQoKYGBgCgpkLiBQcm9kdWNlIGFuIGFwcHJvcHJpYXRlIHBsb3QgbG9va2luZyBhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIGBnZHBQZXJjYXBgIG92ZXIgYGRlbV9yYW5rYCBpbiBgZ2FwMjAwN3NtYWxsYC4gIE1ha2Ugc3VyZSB0byB0d2VhayB0aGUgZGVmYXVsdCBjb2xvciBzZXR0aW5ncyB0byB5b3VyIGxpa2luZy4KCgpgYGB7cn0KCmBgYAoKZS4gKipFWFRFTkRJTkcgS05PV0xFREdFKiogUHJvZHVjZSBhIGZhY2V0ZWQgYm94cGxvdCAoeW91IHJlYWQgdGhhdCByaWdodCkgbG9va2luZyBhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIGBnZHBQZXJjYXBgIG92ZXIgdmFsdWVzIG9mIGByZWdpb25gIGluIGNvbWJpbmF0aW9uIHdpdGggYGRlbV9yYW5rYCBpbiBgZ2FwMjAwN3NtYWxsYC4gIE5vdGUgdGhhdCB5b3UnbGwgbmVlZCB0byBhZGQgdGhlIHRpbHRpbmcgb2YgdGhlIGF4aXMgbGFiZWxzIHZpYSBgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQgPSA2MCwgaGp1c3QgPSAxKWAgYWdhaW4uCgpgYGB7cn0KCmBgYAoKZi4gKipFWFRFTkRJTkcgS05PV0xFREdFKiogRm9jdXNpbmcgb24gdGhlIGBTdHJvbmdseSBEZW1vY3JhdGljYCBzbWFsbCBtdWx0aXBsZSBwbG90IHByb2R1Y2VkIGluIHBhcnQgZS4sIGRlc2NyaWJlIGhvdyB0aGUgMjV0aCwgNTB0aCwgYW5kIDc1dGggcGVyY2VudGlsZSB2YXJ5IGFjcm9zcyB0aGUgbGV2ZWxzIG9mIGByZWdpb25gLgoKICAgICoqQW5zd2VyKio6CiAgICAKKioqCgojIyBQcm9ibGVtIDcgKDEwIHBvaW50cykKCkFub3RoZXIgZmVhdHVyZSB3ZSB3aWxsIHNlZSBpbiBDaGFwdGVyIDUgaXMgdGhlIGFiaWxpdHkgdG8gY2hvb3NlIHNwZWNpZmljIHZhbHVlcyBmcm9tIGEgbGlzdCBhbmQgZmlsdGVyIHRoZSBkYXRhIHNldCBhY2NvcmRpbmcgdG8gdGhpcy4gIEJlbG93IHdlIHdpbGwgcGljayA2IGNvdW50cmllcyBmcm9tIGRpZmZlcmVudCByZWdpb25zIGluIHRoZSB3b3JsZCBhbmQgdGhlbiBtYWtlIGFuIGFwcHJvcHJpYXRlIHBsb3QgdG8gc2VlIGhvdyBlYWNoIGNvdW50cnkncyBsaWZlIGV4cGVjdGFuY3kgaGFzIGNoYW5nZWQgb3ZlciB0aW1lLgoKYGBge3J9CmNvdW50cnlfbGlzdCA8LSBjKCJBcmdlbnRpbmEiLCAiVW5pdGVkIFN0YXRlcyIsICJMaWJlcmlhIiwgIlBha2lzdGFuIiwgIkZpbmxhbmQiLCAiTmV3IFplYWxhbmQiKQpzaXhfY291bnRyaWVzIDwtIGRwbHlyOjpmaWx0ZXIoZ2FwLCBjb3VudHJ5ICVpbiUgY291bnRyeV9saXN0KQpgYGAKCk5vdyBydW4gYFZpZXcoc2l4X2NvdW50cmllcylgIGluIHRoZSBSIGNvbnNvbGUgdG8gZ2V0IGEgc2Vuc2UgZm9yIHdoYXQgdGhpcyBuZXcgZGF0YSBzZXQgbG9va3MgbGlrZS4KCmEuICoqRVhURU5ESU5HIEtOT1dMRURHRSoqIFByb2R1Y2UgdGhlIGFwcHJvcHJpYXRlIHBsb3Qgc2hvd2luZyBob3cgdGhlIGxpZmUgZXhwZWN0YW5jeSBmcm9tIGVhY2ggY291bnRyeSBpbiBgc2l4X2NvdW50cmllc2AgaGFzIGNoYW5nZWQgb3ZlciB0aW1lLiAgWW91IHNob3VsZCBjb2xvciBiYXNlZCBvbiBgc3ViUmVnaW9uYC4KCmBgYHtyfQoKYGBgCgpiLiBXaGF0IGlzIHRoZSBuYW1lIG9mIHRoZSBjb3VudHJ5IGluIGBzaXhfY291bnRyaWVzYCB0aGF0IGhhZCB0aGUgbG93ZXN0IGxpZmUgZXhwZWN0YW5jeSBpbiAxOTcwPwoKICAgICoqQW5zd2VyKio6CgpjLiBXaGljaCB0aHJlZSBjb3VudHJpZXMgb3ZlcmxhcHBlZCBvbiB0aGUgcGxvdD8gCgogICAgKipBbnN3ZXIqKjoKCmQuIFdoYXQgaXMgdGhlIG9ubHkgY291bnRyeSB0byBzaG93IGEgZGVjbGluZSBpbiBsaWZlIGV4cGVjdGFuY3k/ICBJbiB3aGF0IHllYXJzIGRpZCB0aGlzIGRyb3Agb2NjdXI/CgogICAgKipBbnN3ZXIqKjoKCmUuIFdoaWNoIGNvdW50cnkgc2hvd2VkIHRoZSBncmVhdGVzdCBpbmNyZWFzZSBpbiBsaWZlIGV4cGVjdGFuY3kgZnJvbSAxOTUyIHRvIDIwMDc/CgogICAgKipBbnN3ZXIqKjoKCioqKgoKIyMgUHJvYmxlbSA4ICg4IHBvaW50cykKCklkZW50aWZ5IEFUIExFQVNUIHR3byB2YXJpYWJsZXMgdGhhdCBoYXZlIG5vdCBiZWVuIGFuYWx5emVkIHRvZ2V0aGVyIHNvIGZhciBvbiB0aGlzIGV4YW0gaW4gdGhlIGBnYXBgIGRhdGEgc2V0LiAgUHJvZHVjZSBhIHBsb3QgbG9va2luZyBhdCB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIHZhcmlhYmxlcyBhbmQgZGlzY3VzcyBpbiB0aHJlZSBvciBmb3VyIHNlbnRlbmNlcyB0aGUgbWFqb3IgZmluZGluZ3MgZnJvbSB5b3VyIHBsb3QuCgpgYGB7cn0KCmBgYAoKKipBbnN3ZXIqKjogCgoqKioKCiMjIENsb3Npbmcgbm90ZXMKCiMjIyMgUFJFU1MgVEhFIFNQRUxMQ0hFQ0sgQlVUVE9OIQoKIyMjIyBNYWtlIHN1cmUgdG8gS25pdCBIVE1MIHlvdXIgUm1kIHdoZW4geW91IGFyZSBkb25lLiAgWW91IG1heSBhbHNvIGZpbmQgZXJyb3JzIGJ5IGtuaXR0aW5nIHNvIHlvdSBhcmUgZW5jb3VyYWdlZCB0byBLbml0IEhUTUwgZnJlcXVlbnRseSBhcyB5b3Ugd29yayBvbiB0aGlzIGV4YW0uCgoqKioKCiMjIFJlZmxlY3QgKDIgcG9pbnRzIGZvciBjb21wbGV0aW9uKQoKSnVzdCBhcyB3aXRoIHRoZSBsYWJzLCBJIHdhbnQgeW91IHRvIHRha2UgYSBiaXQgb2YgdGltZSB0byByZWZsZWN0IG9uIHdoYXQgeW91IGxlYXJuZWQgdmlhIHRoaXMgdGFrZSBob21lIGV4YW0uICBJIGV4cGVjdCBzb21lIG9mIHRoZSBwcm9ibGVtcyB0byBiZSBjaGFsbGVuZ2luZyBidXQgSSBiZWxpZXZlIHlvdSBhcmUgYWxsIGNhcGFibGUgb2YgZmlndXJpbmcgdGhlbSBvdXQgaWYgeW91IHB1c2ggeW91cnNlbHZlcyB0byBsZWFybiBtb3JlIGFuZCByZXZpZXcgdGhlIG1hdGVyaWFsIHdlIGhhdmUgY292ZXJlZCBzbyBmYXIuICBSZXNpc3QgdGhlIHVyZ2UgdG8gZ28gdG8gdGhlIGJvb2sgaW1tZWRpYXRlbHkgZm9yIGFuIGFuc3dlciBvciBnbyB0byBHb29nbGUgdG8gYXNrIHF1ZXN0aW9ucy4gIFlvdSBzaG91bGQgdHJ5IHRvIHRoaW5rIGFib3V0IGEgcHJvYmxlbSBmb3IgMTUgbWludXRlcyBvciBzbyB0byBzZWUgaWYgYW4gYW5zd2VyIGNvbWVzIHRvIHlvdSBmaXJzdC4gIFlvdSBtYXkgYWxzbyBmaW5kIHZhbHVlIGluIHNraXBwaW5nIHByb2JsZW1zIHRoYXQgeW91IGRvbid0IGltbWVkaWF0ZWx5IGtub3cgaG93IHRvIGRvIGFzIG90aGVyIHByb2JsZW1zIG1heSBndWlkZSB5b3UgdG8gdGhlIGNvcnJlY3QgcmVhc29uaW5nLgoKQW5zd2VyIGVhY2ggb2YgdGhlc2UgcmVmbGVjdGlvbnMgaW4gdHdvIG9yIG1vcmUgY29tcGxldGUgc2VudGVuY2VzIGZvciBmdWxsIGNyZWRpdC4KCi0gV2hhdCBzdXJwcmlzZWQgeW91IHRoZSBtb3N0IGFib3V0IHRoaXMgZXhhbT8gIAoKICAgICoqUmVzcG9uc2UqKjoKCi0gTG9va2luZyBiYWNrIG92ZXIgdGhlIFtUYWtlIEhvbWUgRXhhbSAtIFN0dWR5IEd1aWRlXShodHRwOi8vaXNtYXljLmdpdGh1Yi5pby90ZWFjaGluZy9zb2MzMDEtZjIwMTYvZXhhbTFyZXZpZXcuaHRtbCksIGRvIHlvdSBzZWUgaG93IG1hbnkgb2YgdGhlIHBvaW50cyB0aGVyZSB3ZXJlIGFkZHJlc3NlZCBvbiB0aGlzIGV4YW0/ICBJZiBub3QsIHdoaWNoIFByb2JsZW1zIGhlcmUgZG8geW91IGJlbGlldmUgd2VyZSBub3QgYWRkcmVzc2VkPwoKICAgICoqUmVzcG9uc2UqKjoKCi0gWW91J3ZlIGNvbWUgYSBsb25nIHdheSBhbHJlYWR5IGluIGxlYXJuaW5nIGhvdyB0byB1c2UgUi4gIEhvdyBkbyB5b3UgZmVlbCB0b2RheSBjb21wYXJlZCB0byBob3cgeW91IGZlbHQgaW4gdGhlIGZpcnN0IHdlZWsgb3IgdHdvIG9mIGNsYXNzIHdpdGggcmVnYXJkcyB0byB0aGlzPwoKICAgICoqUmVzcG9uc2UqKjoKICAgIAotIFdoYXQgaGF2ZSB5b3UgbGVhcm5lZCBmcm9tIGEgc29jaWFsIHBlcnNwZWN0aXZlIGJ5IGFuYWx5emluZyB0aGUgYGdhcGAgZGF0YT8gIFdoYXQgbmV3IHF1ZXN0aW9ucyBkbyB5b3UgaGF2ZSBhYm91dCB0aGUgZGF0YT8KCiAgICAqKlJlc3BvbnNlKio6Cg==