Julian Simon liked to proclaim that

The only true measure of scarcity is price …

In this lab we are going to take advantage of a database put together by David Jacks. The data for his paper “From Boom to Bust: A Typology of Real Commodity Prices in the Long Run” (2013, NBER Working Paper 18874) has consistent series of commodity prices for everything ranging from barley to zinc. For our lab we’ve selected prices since 1900.

We’re going to ask the following:

  1. What has been the long-term trend in commodity prices?

  2. Was Simon lucky to have won the bet?

  3. Do commodity price trends differ by commodity in a way that we can understand? (This section will be more exploratory than in past labs. Here the important point is to report what you find, not to find a specific “right” answer.)

# Do not edit this chunk, but *do* press the green button to the answer key for the quiz info (the unreadable string below)
tot = 0
answer.key = "eJzNVk2P4zYMvedXEDmMd4FASZzMYHeBwSIzLdBeiqKz94EiM7YaWfLqYz359yVlJ/Phaw69GKFok3yP5FPET5vaPfq1WMM90HMmlPMeVRTShv7smP82n4lG2ziaf3utMID0CNpW+IIVRAfrr6sVSFvlc1n9m0Ikx8F5eulgZNTOUhhtQ/RJsRXGcP9gZ6RCiA3CXzvodWzg5JKHoQb4hKIWCyh2BUWCn8lFDJ8pFL7QdzYHvkSSBrqxulzBJP8FcZkRl1PE7Jg/XBBns4mxC9+WS7Si10fdYaWlcL5esrV8bLxrdWon8MqrwcuRdopqrbStme5LHQv4cgsdeoU2gibgXUcdsNGcIAWsZoIpiA15nEXoku9cQAE7n0uiZ0j7EHVMlDfT1XkqgSBQHmohmu+vtJWZ53I6KINj/jjSNppP9M5pAdYBH36gp7xa98dIPxhNEUAZlJ7QSzAugjvAL8ftNzqeCLaJjUt1k/PlUeGw5Wp9y9w1uqYg5JOWj3mkFwN3lcNgi0gh3RGMPtKID4kgEtnVAoK2FIv5a5NqOC1nKFcEhzuT/OlNyl4GitR/SCXeEl1moifzOTjmF56z9WdtHS9diq4lpApaDEHWdLJ3Kb6jc4/c14KKHcMWM5GJY/jUqGI8L8YPBDykTKKiIIFR03gcKDwB7V0yFRAJdiai66WvoHgsJm2+1hb8T8FeOrbJHdtMO7Z5qyijuTMmC6VHGZyVe4MLwBeFXYRH6BtNI0Q1vlYOP2iAZC2JHH1gkFDpigdyhPogJrxvrsb7UPFFV2gl6N1RZ3umUzkbvTOGBJ890kfY8wIq+oWGGSUiq6TQBwFPiHAW1L7vhY5eE2ciHZf5OhFd0313Hae+V659bmnD8CbKcLyXMT5XrrfGyerGaHt81tX99uvd6vZGHfh3uc0rKImdoFIIFAMOpM6Qt6yiG4Fo9BhocYnhQEQofLN2m6wkm6m+DY5LE0fzj0EuRiZamg1oeTYD4VYsNx96srma5I2RdoxK8QxlGRsLCamuMcQwgL64Z6I4F1YsaMZkhN8bb3jUWI/2GLPmO/uOkDITMtGhzXglXQgZdtMGpN6T8mqL36Cggmz85LyutZVGUApB5CcTP2doTIByFT2aZI98qwUcaBneOqsofzeh8lqyckYCFms6+IUwQM/9DK9jTrcrj94i/8cJDp50S8M1yEIj6bP+HXPb3KHtdJS270dpNEfmhhuZhWG9umPcga/PSNbqIwPbqw3TGOmuXHJS/guRlXQlbr+I+X+1gFbM"
devtools::install_github("josh-goldstein-git/quizify")
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio
Downloading GitHub repo josh-goldstein-git/quizify@HEAD
── R CMD build ───────────────────────────────────────────────────────────────────────────────────────────────────
  
   checking for file ‘/tmp/RtmplAVnjh/remotes63144eccbd/josh-goldstein-git-quizify-20d36b4/DESCRIPTION’ ...
  
✔  checking for file ‘/tmp/RtmplAVnjh/remotes63144eccbd/josh-goldstein-git-quizify-20d36b4/DESCRIPTION’

  
─  preparing ‘quizify’:
✔  checking DESCRIPTION meta-information
─  checking for LF line-endings in source and make files and shell scripts
─  checking for empty or unneeded directories
   Omitted ‘LazyData’ from DESCRIPTION
─  building ‘quizify_0.1.0.tar.gz’

  
   
Installing package into ‘/srv/r’
(as ‘lib’ is unspecified)
* installing *source* package ‘quizify’ ...
** using staged installation
** R
** inst
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
** building package indices
** installing vignettes
** testing if installed package can be loaded from temporary location
** testing if installed package can be loaded from final location
** testing if installed package keeps a record of temporary installation path
* DONE (quizify)
library(quizify)
source.coded.txt(answer.key)

Note: the most helpful reading for this lab is David Lam (2011), “How the World Survived the Population Bomb”

Part 2. Visualizing commodity prices

Let’s see how the price of Chromium varies over time.

year.vec <- rownames(commod)
plot(year.vec, commod$Chromium, type = "l")
abline(v = 1980)                        # the date of "the bet"

Q2.1 How would you describe the history of Chromium prices?

A. Steadily rising

B. Steadily falling

C. Very volatile, with little clear long-term trend

D. Very volatile, with a clear upward trend

##  "Replace the NA with your answer (e.g., 'A' in quotes)"
answer2.1 = 'C'
quiz.check(answer2.1)
Your  answer2.1 : C
Correct.
Explanation:  There's clearly a lot of volatility. Although the price in 2015 is higher than in 1900, this doesn't look like a clear trend, since for much of the 20th century the price was lower than in 1900.

What does “trendless” data look like?

Imagine a “random walk”, in which prices go up or down each year by some random amount that averages zero. Each realization of this random walk will have, by luck, some trend, but the underlying process generating the randomness has no trend – on average the change is “zero”. It is very easy to falsely interpret a random walk as having an underlying trend. The subject of how to make inferences about the trend of a time series is covered in an econometrics or statistics class. For now, we will just look at some realizations of the random walk to get a feeling for what random realizations of trendless data can look like.

## here we create a function that will plot a random walk. 
plot.random.walk <- function(seed)
{
    set.seed(seed)                      # this initializes the random
                                        # number generator used in
                                        # sample(). If we use the same
                                        # seed, we will get the same
                                        # set of "random" numbers.
    random.steps <- sample(x = c(-1,1), size = 40, replace = TRUE)
    ## this selects the number -1 or 1 randomly 40 times
    random.walk <- cumsum(random.steps)
    ## this turns the random steps into a walk by summing them up.
    ## cumsum(c(1,2,3)) returns a vector with values 1, 3, and 6.
    plot(1:40, random.walk, type = "l")
}

Here’s an example

plot.random.walk(seed = 23)             # Here we set seed to 23

Modify the code below to try 1,2, 3, and 4 as “seeds”

plot.random.walk(seed = 23)

plot.random.walk(seed = 23)

plot.random.walk(seed = 23)

plot.random.walk(seed = 23)

Q.2.2 Which of the following seems to be true

A. Even if price changes are random, averaging zero, the realization of a random process can look like it has a trend.

B. A historical trend is the one reality we observe and we shouldn’t let anyone confuse us with alternative random realizations.

C. Thinking about randomness may help us understand and interpret the reality we see and thus is a subject worth of study.

##  "Replace the NA with your answer (e.g., 'A' in quotes)"
answer2.2 = 'C'
quiz.check(answer2.2)
Your  answer2.2 : C
Warning: Sorry, incorrect. Try again.
Warning: Hint: Ignore automatic message about your answer being 'incorrect.'
.There is no 'correct' answer. But of course a professor would lean
.toward 'C'

Repeating for Tin

Plot the price of tin. You can use the same code we used for Chromium, modifying just slightly.

## put your code for Tin here
## (Hint: you can copy and modify the commands we used for Chromium, and modify the name of the column of interest)
year.vec <- rownames(commod)
plot(year.vec, commod$Tin, type = "l")
abline(v = 1980)                        # the date of "the bet"

Q2.3 Why do you think Ehrlich chose Tin as one of his commodities to bet on?

  1. Tin is difficult to substitute for

  2. Tin had shown a sharp increase in price for the decade or so before 1980 and so it looked like it would continue.

  3. The price had been going down before 1980 and was ready for a recovery

  4. There was evidence that the tin mines were running out of ore

##  "Replace the NA with your answer (e.g., 'A' in quotes)"
answer2.3 = 'B'
quiz.check(answer2.3)
Your  answer2.3 : B
Correct.
Explanation:  Apparently, tin prices were controlled in part by a cartel of producers. See https://www.itri.co.uk/index.php?option=com_mtree&task=att_download&link_id=49605&cf_id=24 for a discussion from an industry research source.

Part 3. Replicating actual bet

In the original bet, Ehrlich was allowed to choose any commodities he wished. He chose Chromium, Copper, Tin, Tungsten, and Nickel. In our data, we don’t have Tungsten. We can check to see if Simon still wins with the four commodities we have.

We strongly suggest to see the Lam (2011) reading, p. 1242 for an account of the bet.

We will use a function to compare commodities over time. This uses the indexing by label we did above. It returns the change in value of a $1000 purchase of the commodity basket in the start year. So if the function returns +100, this means that the value of the commodity basket increased by $100.

Q3.1 If the value of the basket increased by $100, who would win?

A. Simon

B. Ehrlich

C. Neither, because the value of the basket doesn’t tell us if all of the commodities increased in price at the same time.

##  "Replace the NA with your answer (e.g., 'A' in quotes)"
answer3.1 = 'B'
quiz.check(answer3.1)
Your  answer3.1 : B
Correct.
Explanation:  An increase in prices suggests an increase in
.'scarcity', what Ehrlich was betting on.
# This is the function described above.
bet.fun <- function(start, end, basket.vec, data)
{
    ## start = 1980
    ## end = 1990
    ## data = commod
    ## basket.vec <- c("Copper", "Chromium", "Nickel", "Tin")
    year <- rownames(data)
    start.price <- data[year == start, basket.vec]
    end.price   <- data[year == end, basket.vec]
    ## we invest 1000, buying an equal $ amount in each commodity.
    start.funds <- 1000
    dollars.per.commod <- start.funds/length(basket.vec) # e.g. $250 with 4
    ## amount purchased of each commodity
    holdings.vec <- dollars.per.commod/start.price
    ## value at the end
    value.at.end <- sum(holdings.vec * end.price)
    change.in.value <- value.at.end - start.funds
    return(change.in.value)
}

who.wins.fun <- function(change.in.value)
{
    ifelse(change.in.value > 0, "ehrlich", "simon")
}

Let’s try this for 1980 to 1990 with Ehrlich’s basket.

ehrlich.basket.vec <- c("Copper", "Chromium", "Nickel", "Tin")
original.bet.result <- bet.fun("start" = 1980,
                      "end" = 1990,
                      "basket.vec" = ehrlich.basket.vec,
                      "data" = commod)
who.wins.fun(original.bet.result)
[1] "simon"

Q3.2 How much would Simon have won with our version of the “bet”? Hint: what was the value of the bet result? Check the original.bet.result object

A. About 300 dollars

B. He wouldn’t have won. He would have lost about 300 dollars

C. About 500 dollars

D. About 100 dollars

##  "Replace the NA with your answer (e.g., 'A' in quotes)"
answer3.2 = 'A'
quiz.check(answer3.2)
Your  answer3.2 : A
Correct.
Explanation:  A negative number means prices went down, and so Simon would have won.

Part 4. Does Simon win in other periods?

Commodities are highly volatile. Even if commodities were generally rising, Ehrlich could have been unlucky about the timing of his bet.

Let’s check over all years since 1900. We can construct a “loop” using R that will repeat the bet according to our instructions. We can then save the output in a vector and make a judgement about whether Ehrlich was simply unlucky.

Here’s a simple example of a loop, in which we repeat an action 7 times, each time increasing the value of “i”, and printing this value along with a label “iteration”.

for (i in 1:7)   ## the variable "i" takes the value 1, 2, 3, ...
{
    ## anything in between {} is done once
    ## for each value that "i" takes
    print(c("iteration", i))
}
[1] "iteration" "1"        
[1] "iteration" "2"        
[1] "iteration" "3"        
[1] "iteration" "4"        
[1] "iteration" "5"        
[1] "iteration" "6"        
[1] "iteration" "7"        

Now let’s do a loop to see who won the bet in every year of the last century.

start.vec <- 1900:2005        ## a vector of years to start the bet
bet.result.vec <- rep(NA, length(start.vec)) ## an empty vector to be
                                             ## used to store the
                                             ## results
names(bet.result.vec) <- start.vec ## labeling the elements (you can ignore)
for (i in 1:length(start.vec))
{
    bet.result.vec[i] <- bet.fun(start = start.vec[i],
                                 end = start.vec[i] + 10,
                                 basket.vec = ehrlich.basket.vec,
                                 data = commod)
}
print(bet.result.vec)
       1900        1901        1902        1903        1904        1905        1906        1907        1908 
-258.700000 -156.431856   49.123809   -2.021327 -127.212088  -95.459327  -52.223399  -21.845369  293.912953 
       1909        1910        1911        1912        1913        1914        1915        1916        1917 
-175.917402 -424.804605 -552.181803 -531.713958 -479.901991 -406.828864 -457.454997 -483.863734 -488.154673 
       1918        1919        1920        1921        1922        1923        1924        1925        1926 
-501.451139 -259.693188  -81.082163  216.717344  243.454453  252.717049  341.054540  365.566495  331.228393 
       1927        1928        1929        1930        1931        1932        1933        1934        1935 
 386.168194  276.108124  306.675598  392.074108  414.174885  351.395641   38.681985  -29.656863  -72.914365 
       1936        1937        1938        1939        1940        1941        1942        1943        1944 
-150.671378 -113.895743   74.669806  -21.202224   -3.043024  132.044717  202.843571  269.671205  213.919871 
       1945        1946        1947        1948        1949        1950        1951        1952        1953 
 395.367748  542.721218  291.148075  176.863221  283.016148   92.501372  -34.354117   84.176895   16.043674 
       1954        1955        1956        1957        1958        1959        1960        1961        1962 
 199.861978  170.674010   38.283426  107.300058  183.451841  109.764135  286.654596  400.477990  181.086693 
       1963        1964        1965        1966        1967        1968        1969        1970        1971 
 314.033040  526.655925  591.149632  599.870085  591.992619  507.597248  647.651367  627.592390  308.600045 
       1972        1973        1974        1975        1976        1977        1978        1979        1980 
  97.417259  -38.528232 -294.608549 -353.756361 -475.654892 -441.250784   71.947758  -57.956949 -306.220473 
       1981        1982        1983        1984        1985        1986        1987        1988        1989 
-275.830073 -193.578232 -353.610315 -237.373103   35.802145   16.675437  -96.471592 -524.143483 -588.938139 
       1990        1991        1992        1993        1994        1995        1996        1997        1998 
-354.297500 -393.554388 -372.843395  -10.989176  366.094672   68.122978  768.730531 1523.535732 2017.405153 
       1999        2000        2001        2002        2003        2004        2005 
1150.647495 1747.100492 2599.771715 2193.400721 1525.633810  609.806673  216.228316 

To summarize our results, let’s look at them in several ways.

Plot the numbers

plot(start.vec, bet.result.vec)
abline(h = 0)
text(1960, 1500, "Ehrlich wins", col = "blue")
text(1960, -250, "Simon wins", col = "red")

In the graph, it looks like Ehrlich would have won more of the time. But not a lot more.

Let’s tabulate how many times Ehrlich and Simon would have won:

## Convert to a vector of "simon" and "ehrlich", depending on who won
winners.vec <- who.wins.fun(bet.result.vec)
print(winners.vec)
     1900      1901      1902      1903      1904      1905      1906      1907      1908      1909      1910 
  "simon"   "simon" "ehrlich"   "simon"   "simon"   "simon"   "simon"   "simon" "ehrlich"   "simon"   "simon" 
     1911      1912      1913      1914      1915      1916      1917      1918      1919      1920      1921 
  "simon"   "simon"   "simon"   "simon"   "simon"   "simon"   "simon"   "simon"   "simon"   "simon" "ehrlich" 
     1922      1923      1924      1925      1926      1927      1928      1929      1930      1931      1932 
"ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich" 
     1933      1934      1935      1936      1937      1938      1939      1940      1941      1942      1943 
"ehrlich"   "simon"   "simon"   "simon"   "simon" "ehrlich"   "simon"   "simon" "ehrlich" "ehrlich" "ehrlich" 
     1944      1945      1946      1947      1948      1949      1950      1951      1952      1953      1954 
"ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich"   "simon" "ehrlich" "ehrlich" "ehrlich" 
     1955      1956      1957      1958      1959      1960      1961      1962      1963      1964      1965 
"ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich" 
     1966      1967      1968      1969      1970      1971      1972      1973      1974      1975      1976 
"ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich"   "simon"   "simon"   "simon"   "simon" 
     1977      1978      1979      1980      1981      1982      1983      1984      1985      1986      1987 
  "simon" "ehrlich"   "simon"   "simon"   "simon"   "simon"   "simon"   "simon" "ehrlich" "ehrlich"   "simon" 
     1988      1989      1990      1991      1992      1993      1994      1995      1996      1997      1998 
  "simon"   "simon"   "simon"   "simon"   "simon"   "simon" "ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich" 
     1999      2000      2001      2002      2003      2004      2005 
"ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich" "ehrlich" 
## count number of times each won using the "table()" function
table(winners.vec)
winners.vec
ehrlich   simon 
     62      44 

Q4.1 What percent of the time would Ehrlich have won of the 106 simulated bets from 1900 to 2005?

A. About 62 percent

B. About 58 percent

##  "Replace the NA with your answer (e.g., 'A' in quotes)"
answer4.1 = 'B'
quiz.check(answer4.1)
Your  answer4.1 : B
Correct.
Explanation:  62/106 is about 0.58.

Make a fancier plot which shows all the periods when each would’ve won. (You don’t need to understand this code.)

plot(start.vec, bet.result.vec, type = "n") #an empty plot
abline(h = 0)
e <- which(winners.vec == "ehrlich")    # T or F, to subset text()
s <- which(winners.vec == "simon")
text(x = start.vec[e], y = bet.result.vec[e], labels = "e", col = "blue")
text(x = start.vec[s], y = bet.result.vec[s], labels = "s", col = "red")
text(1960, 1500, "Ehrlich wins", col = "blue")
text(1960, -250, "Simon wins", col = "red")

5. Generalizing the bet to other commodities

A change in the supply of a particular commodity may or may not cause a large price change – depending on the availability of substitutes. (Note: the results from this section will be useful for your write-up of the graded questions at the end of the lab.)

The following code provides a template for a single commodity, in this case “Chromium” (but you can change the commodity).

start.vec <- 1900:2005
result.vec <- rep(NA, length(start.vec))
for (i in 1:length(start.vec))
  {
  result.vec[i] <- bet.fun(start = start.vec[i],
                      end = start.vec[i] + 10,
                      basket.vec = c("Chromium"),
                      data = commod)
}
winner.vec <- who.wins.fun(result.vec)
cat("counts:\n")
counts:
table(winner.vec)
winner.vec
ehrlich   simon 
     61      45 
cat("proportions:\n")
proportions:
prop.table(table(winner.vec))
winner.vec
  ehrlich     simon 
0.5754717 0.4245283 

Well done. You are finished with the computing portion of Lab 5.

Part 5. Graded Questions

  1. What relationship did Ehrlich expect to hold between commodity prices and population growth? Ehrlich expected that with population growth, commodity prices would increase as well.
  1. Who won the bet in 1990? Given our analysis of other time periods, would you say that the winner was “lucky” or “right”, or both? [Explain your answer in 50 to 100 words.] Simon won the bet in 1990 for a check of $576 from Ehrlich. I would say he wwere both lucky and right. The timing of his decision definitely affects his winning, but he probably also had a good idea of how commodity prices were to grow or decrease.

As noted in the lab, this section is for you to explore and describe what you found. Whether what you find is conclusive or inconclusive, you can still get full credit by reporting whatever you found.

  1. Choose another easily substitutable commodity from the database. Conduct the analysis of its price as the previous part of the lab and answer the following questions.

3.1) Why do you think this commodity would be easily substitutable, explaining what “service” it provides with 1 or 2 sentences. I think Pork would be easily substitutable for any other variety of meat, such as beef or lamb. Since it is a food option, it isn’t so much vital as say beef and lamb, since those animals are valuable for more than just their meat, but also their leather/wool.

3.2) Attach a plot of the real price of your chosen commodity and comment on its trend up to 1980 in 1 sentence. Hint: you can modify code in section 2.

year.vec <- rownames(commod)
plot(year.vec, commod$Pork, type = "l")
abline(v = 1980)                        # the date of "the bet"

The trend definitely goes downward as time goes on.

3.3) Attach a plot of the change of prices (“bet.result”) of the chosen commodity.

start.vec <- 1900:2005        ## a vector of years to start the bet
bet.result.vec <- rep(NA, length(start.vec)) ## an empty vector to be
                                             ## used to store the
                                             ## results
names(bet.result.vec) <- start.vec ## labeling the elements (you can ignore)
for (i in 1:length(start.vec))
{
    bet.result.vec[i] <- bet.fun(start = start.vec[i],
                                 end = start.vec[i] + 10,
                                 basket.vec = c("Pork"),
                                 data = commod)
}

plot(start.vec, bet.result.vec)
abline(h = 0)                        # the date of "the bet"

text(1980, 1000, "Ehrlich wins", col = "blue")
text(1960, -500, "Simon wins", col = "red")

Hint 1: there would only be your chosen commodity in the “basket.vec”. You can either modify the original “ehrlich.basket.vec” or create your own “basket.vec”. Remember to modify for-loop consistently.

Hint 2: you don’t need to show whether Ehrlich or Simon win about this commodity. But labelling the plot with different colors can help you understand the general trend.

Note (NOT REQUIRED): To make it a better graph, you can add a title to the graph indicating the commodity you choose adding ‘main = “commodity name”’ to the syntax.

  1. Choose a commodity from the database which you think would be hard to substitute for. And explain why you think this commodity would NOT be easily substituted, explaining what “service” it provides. (In 1 or 2 sentences) [Note: you don’t need to analyze the data for this problem.] Wheat or Coal would be difficult to substitute for. Wheat is a common commodity for grains, such as bread, and gives lots of nutrition. Bread is very crucial for meals, and thus wheat would be very difficult to simply substitute for something else. Coal is also very important, as it is the main commodity for heat in homes and for machinery to work.

Congratulations! You are finished with Lab 5.

LS0tCnRpdGxlOiAiRWNvbi9EZW1vZyBDMTc1IExhYiA1OiBUaGUgQmV0IC0tIE92ZXIgYW5kIG92ZXIgYWdhaW4iCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCgpKdWxpYW4gU2ltb24gbGlrZWQgdG8gcHJvY2xhaW0gdGhhdAoKPiBUaGUgb25seSB0cnVlIG1lYXN1cmUgb2Ygc2NhcmNpdHkgaXMgcHJpY2UgLi4uCgpJbiB0aGlzIGxhYiB3ZSBhcmUgZ29pbmcgdG8gdGFrZSBhZHZhbnRhZ2Ugb2YgYSBkYXRhYmFzZSBwdXQgdG9nZXRoZXIKYnkgRGF2aWQgSmFja3MuIFRoZSBkYXRhIGZvciBoaXMgcGFwZXIgIkZyb20gQm9vbSB0byBCdXN0OiBBIFR5cG9sb2d5Cm9mIFJlYWwgQ29tbW9kaXR5IFByaWNlcyBpbiB0aGUgTG9uZyBSdW4iICgyMDEzLCBOQkVSIFdvcmtpbmcgUGFwZXIKMTg4NzQpIGhhcyBjb25zaXN0ZW50IHNlcmllcyBvZiBjb21tb2RpdHkgcHJpY2VzIGZvciBldmVyeXRoaW5nCnJhbmdpbmcgZnJvbSBiYXJsZXkgdG8gemluYy4gRm9yIG91ciBsYWIgd2UndmUgc2VsZWN0ZWQgcHJpY2VzCnNpbmNlIDE5MDAuCgpXZSdyZSBnb2luZyB0byBhc2sgdGhlIGZvbGxvd2luZzoKCjEuIFdoYXQgaGFzIGJlZW4gdGhlIGxvbmctdGVybSB0cmVuZCBpbiBjb21tb2RpdHkgcHJpY2VzPwoKMi4gV2FzIFNpbW9uIGx1Y2t5IHRvIGhhdmUgd29uIHRoZSBiZXQ/CgozLiBEbyBjb21tb2RpdHkgcHJpY2UgdHJlbmRzIGRpZmZlciBieSBjb21tb2RpdHkgaW4gYSB3YXkgdGhhdCB3ZSBjYW4KICAgdW5kZXJzdGFuZD8gKFRoaXMgc2VjdGlvbiB3aWxsIGJlIG1vcmUgZXhwbG9yYXRvcnkgdGhhbiBpbiBwYXN0CiAgIGxhYnMuIEhlcmUgdGhlIGltcG9ydGFudCBwb2ludCBpcyB0byByZXBvcnQgX3doYXRfIHlvdSBmaW5kLCBub3QgdG8KICAgZmluZCBhIHNwZWNpZmljICJyaWdodCIgYW5zd2VyLikKCmBgYHtyfQojIERvIG5vdCBlZGl0IHRoaXMgY2h1bmssIGJ1dCAqZG8qIHByZXNzIHRoZSBncmVlbiBidXR0b24gdG8gdGhlIGFuc3dlciBrZXkgZm9yIHRoZSBxdWl6IGluZm8gKHRoZSB1bnJlYWRhYmxlIHN0cmluZyBiZWxvdykKdG90ID0gMAphbnN3ZXIua2V5ID0gImVKek5WazJQNHpZTXZlZFhFRG1NZDRGQVNaek1ZSGVCd1NJekxkQmVpcUt6OTRFaU03WWFXZkxxWXozNTl5VmxKL1BoYXc2OUdLRm9rM3lQNUZQRVQ1dmFQZnExV01NOTBITW1sUE1lVlJUU2h2N3NtUDgybjRsRzJ6aWFmM3V0TUlEMENOcFcrSUlWUkFmcnI2c1ZTRnZsYzFuOW0wSWt4OEY1ZXVsZ1pOVE9VaGh0US9SSnNSWEdjUDlnWjZSQ2lBM0NYenZvZFd6ZzVKS0hvUWI0aEtJV0N5aDJCVVdDbjhsRkRKOHBGTDdRZHpZSHZrU1NCcnF4dWx6QkpQOEZjWmtSbDFQRTdKZy9YQkJuczRteEM5K1dTN1NpMTBmZFlhV2xjTDVlc3JWOGJMeHJkV29uOE1xcndjdVJkb3BxcmJTdG1lNUxIUXY0Y2dzZGVvVTJnaWJnWFVjZHNOR2NJQVdzWm9JcGlBMTVuRVhva3U5Y1FBRTduMHVpWjBqN0VIVk1sRGZUMVhrcWdTQlFIbW9obXUrdnRKV1o1M0k2S0lOai9qalNOcHBQOU01cEFkWUJIMzZncDd4YTk4ZElQeGhORVVBWmxKN1FTekF1Z2p2QUw4ZnROenFlQ0xhSmpVdDFrL1BsVWVHdzVXcDl5OXcxdXFZZzVKT1dqM21rRndOM2xjTmdpMGdoM1JHTVB0S0lENGtnRXRuVkFvSzJGSXY1YTVOcU9DMW5LRmNFaHp1VC9PbE55bDRHaXRSL1NDWGVFbDFtb2lmek9Uam1GNTZ6OVdkdEhTOWRpcTRscEFwYURFSFdkTEozS2I2amM0L2MxNEtLSGNNV001R0pZL2pVcUdJOEw4WVBCRHlrVEtLaUlJRlIwM2djS0R3QjdWMHlGUkFKZGlhaTY2V3ZvSGdzSm0yKzFoYjhUOEZlT3JiSkhkdE1PN1o1cXlpanVUTW1DNlZIR1p5VmU0TUx3QmVGWFlSSDZCdE5JMFExdmxZT1AyaUFaQzJKSEgxZ2tGRHBpZ2R5aFBvZ0pyeHZyc2I3VVBGRlYyZ2w2TjFSWjN1bVV6a2J2VE9HQko4OTBrZlk4d0lxK29XR0dTVWlxNlRRQndGUGlIQVcxTDd2aFk1ZUUyY2lIWmY1T2hGZDAzMTNIYWUrVjY1OWJtbkQ4Q2JLY0x5WE1UNVhycmZHeWVyR2FIdDgxdFg5OXV2ZDZ2WkdIZmgzdWMwcktJbWRvRklJRkFNT3BNNlF0NnlpRzRGbzlCaG9jWW5oUUVRb2ZMTjJtNndrbTZtK0RZNUxFMGZ6ajBFdVJpWmFtZzFvZVRZRDRWWXNOeDk2c3JtYTVJMlJkb3hLOFF4bEdSc0xDYW11TWNRd2dMNjRaNkk0RjFZc2FNWmtoTjhiYjNqVVdJLzJHTFBtTy91T2tESVRNdEdoelhnbFhRZ1pkdE1HcE42VDhtcUwzNkNnZ216ODVMeXV0WlZHVUFwQjVDY1RQMmRvVElCeUZUMmFaSTk4cXdVY2FCbmVPcXNvZnplaDhscXlja1lDRm1zNitJVXdRTS85REs5alRyY3JqOTRpLzhjSkRwNTBTOE0xeUVJajZiUCtIWFBiM0tIdGRKUzI3MGRwTkVmbWhodVpoV0c5dW1QY2dhL1BTTmJxSXdQYnF3M1RHT211WEhKUy9ndVJsWFFsYnIrSStYKzFnRmJNIgpkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoImpvc2gtZ29sZHN0ZWluLWdpdC9xdWl6aWZ5IikKbGlicmFyeShxdWl6aWZ5KQpzb3VyY2UuY29kZWQudHh0KGFuc3dlci5rZXkpCmBgYAoKPiAgTm90ZTogdGhlIG1vc3QgaGVscGZ1bCByZWFkaW5nIGZvciB0aGlzIGxhYiBpcyBEYXZpZCBMYW0gKDIwMTEpLAo+ICJIb3cgdGhlIFdvcmxkIFN1cnZpdmVkIHRoZSBQb3B1bGF0aW9uIEJvbWIiCgoKIyBQYXJ0IDEuIFJlYWQgaW4gZGF0YSBhbmQgZ3JhcGggdHJlbmRzIGluIGNvbW1vZGl0eSBwcmljZXMKClRoZXNlIGNvbW1vZGl0eSBwcmljZXMgYXJlIG1vZGlmaWVkIGluIHR3byB3YXlzLiBGaXJzdCwgdGhlIG5vbWluYWwKcHJpY2VzIGhhdmUgYmVlbiBhZGp1c3RlZCBmb3IgaW5mbGF0aW9uLiBTZWNvbmQsIGFsbCBwcmljZXMgYXJlCmluZGV4ZWQgdG8gMTAwIGluIDE5MDAgKHdlIGNhbGwgdGhpcyB0aGUgYmFzZSB5ZWFyKS4gClRoaXMgbWFrZXMgaXQgZWFzeSBmb3IgdXMgdG8gY29tcGFyZSBhY3Jvc3MgY29tbW9kaXRpZXMgYW5kIG92ZXIgdGltZS4KCk1vcmUgZGV0YWlsczogbm9taW5hbCBwcmljZXMgYXJlIHRob3NlIHRoYXQgYXJlIGV4cGVyaWVuY2VkIGJ5IHBlb3BsZSwgYnV0IG1vcmUgCmltcG9ydGFudGx5IHRoZXkgY2FuIHZhcnkgYmV0d2VlbiBwZXJpb2RzIGJlY2F1c2Ugb2YgaW5mbGF0aW9uLiBGb3IgaW5zdGFuY2UsIHRoZSAKZmFjdCB0aGF0IHRoZSBwcmljZSBvZiBhIHByb2R1Y3QgaW5jcmVhc2VzIGZyb20gb25lIHllYXIgdG8gYW5vdGhlciwgbWF5IGJlIGZyb20KYSBjaGFuZ2UgaW4gaXRzIHZhbHVlLCBidXQgYWxzbyBqdXN0IGFzIGEgcmVzdWx0IGluIGluY3JlYXNpbmcgcHJpY2VzIG9mIGl0cyBpbnB1dHMuClNvLCB0byBhY2NvdW50IGZvciBjaGFuZ2luZyBwcmljZXMgKGluZmxhdGlvbiksIGVjb25vbWlzdHMgZXZhbHVhdGUgcHJpY2VzIGluIAoqcmVhbCogdGVybXMsIHdoaWNoICdyZW1vdmVzJyB0aGUgZWZmZWN0IG9mIGNoYW5naW5nIHByaWNlcywgc28gdGhhdCB3ZSBjYW4gCmNvbXBhcmUgdmFsdWVzIG92ZXIgdGltZS4gV2hlbiB5b3UgbG9vayBhdCB2YWx1ZXMgaW4gcmVhbCB0ZXJtcywgeW91IGFyZSBjb21wYXJpbmcKYXBwbGVzIHdpdGggYXBwbGVzLiAgCgpgYGB7cn0KIyMgZ2V0IGNvbW1vZGl0eSBkYXRhIGZyb20gYSBmaWxlIG9uIG91ciBzZXJ2ZXIKZmlsZSA8LSAiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2pvc2gtZ29sZHN0ZWluLWdpdC9lY29uX2RlbW9nX2MxNzUvbWFpbi9kYXRhL1JlYWxfY29tbW9kaXR5X3ByaWNlc18xOTAwXzIwMTUuY3N2Igpjb21tb2QgPC0gcmVhZC50YWJsZShmaWxlLCBzZXAgPSAiLCIpICMgcmVhZCB0aGUgZGF0YSBpbnRvLCB3aXRoIGNvbHVtbiBoZWFkZXIKaGVhZChjb21tb2QpICMgbG9va3MgYXQgZmlyc3QgZmV3IGxpbmVzCmBgYApZb3UgY2FuIHNjcm9sbCB0byB0aGUgcmlnaHQgYW5kIGxlZnQgdXNpbmcgdGhlIGJsYWNrIGFycm93cyBpbiB0aGUgZGlzcGxheSBvZiB0aGUgZGF0YS4gRm9yIHRoZSBxdWVzdGlvbiBiZWxvdywgc2Nyb2xsIHRvIHRoZSByaWdodCB1bnRpbCB5b3UgZmluZCB0aGUgY29sdW1uIGxhYmVsbGVkICdaaW5jJy4gCgpRMS4xIFdoYXQgZG9lcyB0aGUgbnVtYmVyIDExMC41MSB1bmRlciBaaW5jIG1lYW4/CgpBLiAgWmluYyBjb3N0cyAxMTAuNTEgY2VudHMgcGVyIHBvdW5kCgpCLiAgWmluYyBwcmljZXMgaW5jcmVhc2VkIGJ5IGFib3V0IDExMCBwZXJjZW50IGJldHdlZW4gMTkwMCBhbmQgMTkwNAoKQy4gIFppbmMgY29zdCBhYm91dCAxMC41MSBwZXJjZW50IG1vcmUgaW4gKm5vbWluYWwqIHRlcm1zIGluIDE5MDQgdGhhbiBpbiAxOTAwCgpELiAgWmluYyBjb3N0IDEwLjUxIHBlcmNlbnQgbW9yZSBpbiAqcmVhbCogdGVybXMgaW4gMTkwNCB0aGFuIGluIDE5MDAKCmBgYHtyfQojIyAgIlJlcGxhY2UgdGhlIE5BIHdpdGggeW91ciBhbnN3ZXIgKGUuZy4sICdBJyBpbiBxdW90ZXMpIgphbnN3ZXIxLjEgPSAnRCcKcXVpei5jaGVjayhhbnN3ZXIxLjEpCmBgYAoKClExLjIgV2hhdCBpcyB0aGUgbWFqb3IgdXNlIG9mIENocm9taXVtPwoKQS4gIEZvciBicm93c2luZyB0aGUgaW50ZXJuZXQKCkIuICBBcyBDaHJvbWUgcGxhdGluZyBhbmQgc3RhaW5sZXNzIHN0ZWVsCgpDLiAgQXMgdml0YW1pbiBzdXBwbGVtZW50IGZvciBicmVha2Zhc3QgY2VyZWFsCgpELiAgQXMgYSBwcmVjaW91cyBtZXRhbCBmb3Igc3RvcmluZyB2YWx1ZQoKYGBge3J9CiMjICAiUmVwbGFjZSB0aGUgTkEgd2l0aCB5b3VyIGFuc3dlciAoZS5nLiwgJ0EnIGluIHF1b3RlcykiCmFuc3dlcjEuMiA9ICdCJwpxdWl6LmNoZWNrKGFuc3dlcjEuMikKYGBgCgpUbyBzZWxlY3QgYSB2YWx1ZSBmcm9tIHRoaXMgbWF0cml4IG9mIGRhdGEgeW91IGNhbiBpbmRleCBieSB0aGUgbGFiZWwKb2YgdGhlIHJvdyBhbmQgY29sdW1uLiBGb3IgZXhhbXBsZSwKYGBge3J9CmNvbW1vZFsiMTk2MyIsICJDaHJvbWl1bSJdCiMjIG5vdGUgZm9yIHRob3NlIGludGVyZXN0ZWQgaW4gUjoKIyMgdGhlIGluZGV4ICIxOTYzIiBuZWVkcyB0byBiZSBpbiBxdW90ZXMsIG90aGVyd2lzZSBSIHdpbGwgdGhpbmsgaXQKIyMgaXMgdGhlIDE5NjNyZCByb3cgb2YgdGhlIG1hdHJpeC4gSGVyZSB3ZSdyZSB0ZWxsaW5nIGl0IHRoYXQgaXQgaXMKIyMgdGhlIHJvdyBsYWJlbGVkICIxOTYzIi4KYGBgCnRlbGxzIHVzIHRoYXQgdGhlIHJlYWwgcHJpY2Ugb2YgQ2hyb21pdW0gaW4gMTk2MyB3YXMgNTUgcGVyY2VudCBvZiB0aGF0CmluIDE5MDAuCgo+IChOb3RlOiBpbiB0aGUgcmVzdCBvZiB0aGUgbGFiLCB3aGVuIHdlIHNheSAicHJpY2UiIHdlIG1lYW4gInJlYWwKPiBwcmljZSIsIHVubGVzcyBvdGhlcndpc2Ugc3RhdGVkLikKCiMgUGFydCAyLiBWaXN1YWxpemluZyBjb21tb2RpdHkgcHJpY2VzCgpMZXQncyBzZWUgaG93IHRoZSBwcmljZSBvZiBDaHJvbWl1bSB2YXJpZXMgb3ZlciB0aW1lLgoKYGBge3J9CnllYXIudmVjIDwtIHJvd25hbWVzKGNvbW1vZCkKcGxvdCh5ZWFyLnZlYywgY29tbW9kJENocm9taXVtLCB0eXBlID0gImwiKQphYmxpbmUodiA9IDE5ODApICAgICAgICAgICAgICAgICAgICAgICAgIyB0aGUgZGF0ZSBvZiAidGhlIGJldCIKYGBgClEyLjEgSG93IHdvdWxkIHlvdSBkZXNjcmliZSB0aGUgaGlzdG9yeSBvZiBDaHJvbWl1bSBwcmljZXM/CgpBLiBTdGVhZGlseSByaXNpbmcKCkIuIFN0ZWFkaWx5IGZhbGxpbmcKCkMuIFZlcnkgdm9sYXRpbGUsIHdpdGggbGl0dGxlIGNsZWFyIGxvbmctdGVybSB0cmVuZAoKRC4gVmVyeSB2b2xhdGlsZSwgd2l0aCBhIGNsZWFyIHVwd2FyZCB0cmVuZAoKYGBge3J9CiMjICAiUmVwbGFjZSB0aGUgTkEgd2l0aCB5b3VyIGFuc3dlciAoZS5nLiwgJ0EnIGluIHF1b3RlcykiCmFuc3dlcjIuMSA9ICdDJwpxdWl6LmNoZWNrKGFuc3dlcjIuMSkKYGBgCgojIyBXaGF0IGRvZXMgInRyZW5kbGVzcyIgZGF0YSBsb29rIGxpa2U/CgpJbWFnaW5lIGEgInJhbmRvbSB3YWxrIiwgaW4gd2hpY2ggcHJpY2VzIGdvIHVwIG9yIGRvd24gZWFjaCB5ZWFyIGJ5CnNvbWUgcmFuZG9tIGFtb3VudCB0aGF0IGF2ZXJhZ2VzIHplcm8uIEVhY2ggcmVhbGl6YXRpb24gb2YgdGhpcyByYW5kb20Kd2FsayB3aWxsIGhhdmUsIGJ5IGx1Y2ssIHNvbWUgdHJlbmQsIGJ1dCB0aGUgdW5kZXJseWluZyBwcm9jZXNzCmdlbmVyYXRpbmcgdGhlIHJhbmRvbW5lc3MgaGFzIG5vIHRyZW5kIC0tIG9uIGF2ZXJhZ2UgdGhlIGNoYW5nZSBpcwoiemVybyIuIEl0IGlzIHZlcnkgZWFzeSB0byBmYWxzZWx5IGludGVycHJldCBhIHJhbmRvbSB3YWxrIGFzIGhhdmluZwphbiB1bmRlcmx5aW5nIHRyZW5kLiBUaGUgc3ViamVjdCBvZiBob3cgdG8gbWFrZSBpbmZlcmVuY2VzIGFib3V0IHRoZQp0cmVuZCBvZiBhIHRpbWUgc2VyaWVzIGlzIGNvdmVyZWQgaW4gYW4gZWNvbm9tZXRyaWNzIG9yIHN0YXRpc3RpY3MKY2xhc3MuIEZvciBub3csIHdlIHdpbGwganVzdCBsb29rIGF0IHNvbWUgcmVhbGl6YXRpb25zIG9mIHRoZSByYW5kb20Kd2FsayB0byBnZXQgYSBmZWVsaW5nIGZvciB3aGF0IHJhbmRvbSByZWFsaXphdGlvbnMgb2YgdHJlbmRsZXNzCmRhdGEgY2FuIGxvb2sgbGlrZS4KCmBgYHtyfQojIyBoZXJlIHdlIGNyZWF0ZSBhIGZ1bmN0aW9uIHRoYXQgd2lsbCBwbG90IGEgcmFuZG9tIHdhbGsuIApwbG90LnJhbmRvbS53YWxrIDwtIGZ1bmN0aW9uKHNlZWQpCnsKICAgIHNldC5zZWVkKHNlZWQpICAgICAgICAgICAgICAgICAgICAgICMgdGhpcyBpbml0aWFsaXplcyB0aGUgcmFuZG9tCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIG51bWJlciBnZW5lcmF0b3IgdXNlZCBpbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBzYW1wbGUoKS4gSWYgd2UgdXNlIHRoZSBzYW1lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHNlZWQsIHdlIHdpbGwgZ2V0IHRoZSBzYW1lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHNldCBvZiAicmFuZG9tIiBudW1iZXJzLgogICAgcmFuZG9tLnN0ZXBzIDwtIHNhbXBsZSh4ID0gYygtMSwxKSwgc2l6ZSA9IDQwLCByZXBsYWNlID0gVFJVRSkKICAgICMjIHRoaXMgc2VsZWN0cyB0aGUgbnVtYmVyIC0xIG9yIDEgcmFuZG9tbHkgNDAgdGltZXMKICAgIHJhbmRvbS53YWxrIDwtIGN1bXN1bShyYW5kb20uc3RlcHMpCiAgICAjIyB0aGlzIHR1cm5zIHRoZSByYW5kb20gc3RlcHMgaW50byBhIHdhbGsgYnkgc3VtbWluZyB0aGVtIHVwLgogICAgIyMgY3Vtc3VtKGMoMSwyLDMpKSByZXR1cm5zIGEgdmVjdG9yIHdpdGggdmFsdWVzIDEsIDMsIGFuZCA2LgogICAgcGxvdCgxOjQwLCByYW5kb20ud2FsaywgdHlwZSA9ICJsIikKfQpgYGAKCkhlcmUncyBhbiBleGFtcGxlCmBgYHtyfQpwbG90LnJhbmRvbS53YWxrKHNlZWQgPSAyMykgICAgICAgICAgICAgIyBIZXJlIHdlIHNldCBzZWVkIHRvIDIzCmBgYAoKCk1vZGlmeSB0aGUgY29kZSBiZWxvdyB0byB0cnkgMSwyLCAzLCBhbmQgNCBhcyAic2VlZHMiCmBgYHtyfQpwbG90LnJhbmRvbS53YWxrKHNlZWQgPSAyMykKcGxvdC5yYW5kb20ud2FsayhzZWVkID0gMjMpCnBsb3QucmFuZG9tLndhbGsoc2VlZCA9IDIzKQpwbG90LnJhbmRvbS53YWxrKHNlZWQgPSAyMykKYGBgCgpRLjIuMiBXaGljaCBvZiB0aGUgZm9sbG93aW5nIHNlZW1zIHRvIGJlIHRydWUKCkEuIEV2ZW4gaWYgcHJpY2UgY2hhbmdlcyBhcmUgcmFuZG9tLCBhdmVyYWdpbmcgemVybywgdGhlIHJlYWxpemF0aW9uCm9mIGEgcmFuZG9tIHByb2Nlc3MgY2FuIGxvb2sgbGlrZSBpdCBoYXMgYSB0cmVuZC4KCkIuIEEgaGlzdG9yaWNhbCB0cmVuZCBpcyB0aGUgb25lIHJlYWxpdHkgd2Ugb2JzZXJ2ZSBhbmQgd2Ugc2hvdWxkbid0IGxldAphbnlvbmUgY29uZnVzZSB1cyB3aXRoIGFsdGVybmF0aXZlIHJhbmRvbSByZWFsaXphdGlvbnMuCgpDLiBUaGlua2luZyBhYm91dCByYW5kb21uZXNzIG1heSBoZWxwIHVzIHVuZGVyc3RhbmQgYW5kIGludGVycHJldCB0aGUKcmVhbGl0eSB3ZSBzZWUgYW5kIHRodXMgaXMgYSBzdWJqZWN0IHdvcnRoIG9mIHN0dWR5LgoKYGBge3J9CiMjICAiUmVwbGFjZSB0aGUgTkEgd2l0aCB5b3VyIGFuc3dlciAoZS5nLiwgJ0EnIGluIHF1b3RlcykiCmFuc3dlcjIuMiA9ICdDJwpxdWl6LmNoZWNrKGFuc3dlcjIuMikKYGBgCgoKIyMgUmVwZWF0aW5nIGZvciBUaW4KClBsb3QgdGhlIHByaWNlIG9mIHRpbi4gWW91IGNhbiB1c2UgdGhlIHNhbWUgY29kZSB3ZSB1c2VkIGZvciBDaHJvbWl1bSwgbW9kaWZ5aW5nIGp1c3Qgc2xpZ2h0bHkuCmBgYHtyfQojIyBwdXQgeW91ciBjb2RlIGZvciBUaW4gaGVyZQojIyAoSGludDogeW91IGNhbiBjb3B5IGFuZCBtb2RpZnkgdGhlIGNvbW1hbmRzIHdlIHVzZWQgZm9yIENocm9taXVtLCBhbmQgbW9kaWZ5IHRoZSBuYW1lIG9mIHRoZSBjb2x1bW4gb2YgaW50ZXJlc3QpCnllYXIudmVjIDwtIHJvd25hbWVzKGNvbW1vZCkKcGxvdCh5ZWFyLnZlYywgY29tbW9kJFRpbiwgdHlwZSA9ICJsIikKYWJsaW5lKHYgPSAxOTgwKSAgICAgICAgICAgICAgICAgICAgICAgICMgdGhlIGRhdGUgb2YgInRoZSBiZXQiCmBgYAoKUTIuMyBXaHkgZG8geW91IHRoaW5rIEVocmxpY2ggY2hvc2UgVGluIGFzIG9uZSBvZiBoaXMgY29tbW9kaXRpZXMgdG8gYmV0IG9uPwoKQS4gIFRpbiBpcyBkaWZmaWN1bHQgdG8gc3Vic3RpdHV0ZSBmb3IKCkIuICBUaW4gaGFkIHNob3duIGEgc2hhcnAgaW5jcmVhc2UgaW4gcHJpY2UgZm9yIHRoZSBkZWNhZGUgb3Igc28gYmVmb3JlIDE5ODAgYW5kIHNvIGl0IGxvb2tlZCBsaWtlIGl0IHdvdWxkIGNvbnRpbnVlLgoKQy4gIFRoZSBwcmljZSBoYWQgYmVlbiBnb2luZyBkb3duIGJlZm9yZSAxOTgwIGFuZCB3YXMgcmVhZHkgZm9yIGEgcmVjb3ZlcnkKCkQuICBUaGVyZSB3YXMgZXZpZGVuY2UgdGhhdCB0aGUgdGluIG1pbmVzIHdlcmUgcnVubmluZyBvdXQgb2Ygb3JlCgpgYGB7cn0KIyMgICJSZXBsYWNlIHRoZSBOQSB3aXRoIHlvdXIgYW5zd2VyIChlLmcuLCAnQScgaW4gcXVvdGVzKSIKYW5zd2VyMi4zID0gJ0InCnF1aXouY2hlY2soYW5zd2VyMi4zKQpgYGAKCgojIFBhcnQgMy4gUmVwbGljYXRpbmcgYWN0dWFsIGJldAoKSW4gdGhlIG9yaWdpbmFsIGJldCwgRWhybGljaCB3YXMgYWxsb3dlZCB0byBjaG9vc2UgYW55IGNvbW1vZGl0aWVzIGhlCndpc2hlZC4gSGUgY2hvc2UgQ2hyb21pdW0sIENvcHBlciwgVGluLCBUdW5nc3RlbiwgYW5kIE5pY2tlbC4gSW4gb3VyCmRhdGEsIHdlIGRvbid0IGhhdmUgVHVuZ3N0ZW4uIFdlIGNhbiBjaGVjayB0byBzZWUgaWYgU2ltb24gc3RpbGwgd2lucwp3aXRoIHRoZSBmb3VyIGNvbW1vZGl0aWVzIHdlIGhhdmUuCgo+IFdlIHN0cm9uZ2x5IHN1Z2dlc3QgdG8gc2VlIHRoZSBMYW0gKDIwMTEpIHJlYWRpbmcsIHAuIDEyNDIgZm9yIAphbiBhY2NvdW50IG9mIHRoZSBiZXQuCgpXZSB3aWxsIHVzZSBhIGZ1bmN0aW9uIHRvIGNvbXBhcmUgY29tbW9kaXRpZXMgb3ZlciB0aW1lLiBUaGlzIHVzZXMgdGhlCmluZGV4aW5nIGJ5IGxhYmVsIHdlIGRpZCBhYm92ZS4gSXQgcmV0dXJucyB0aGUgY2hhbmdlIGluIHZhbHVlIG9mIGEKJDEwMDAgcHVyY2hhc2Ugb2YgdGhlIGNvbW1vZGl0eSBiYXNrZXQgaW4gdGhlIHN0YXJ0IHllYXIuIFNvIGlmIHRoZQpmdW5jdGlvbiByZXR1cm5zICsxMDAsIHRoaXMgbWVhbnMgdGhhdCB0aGUgdmFsdWUgb2YgdGhlIGNvbW1vZGl0eQpiYXNrZXQgaW5jcmVhc2VkIGJ5ICQxMDAuCgpRMy4xIElmIHRoZSB2YWx1ZSBvZiB0aGUgYmFza2V0IGluY3JlYXNlZCBieSAkMTAwLCB3aG8gd291bGQgd2luPwoKQS4gU2ltb24KCkIuIEVocmxpY2gKCkMuIE5laXRoZXIsIGJlY2F1c2UgdGhlIHZhbHVlIG9mIHRoZSBiYXNrZXQgZG9lc24ndCB0ZWxsIHVzIGlmCiphbGwqIG9mIHRoZSBjb21tb2RpdGllcyBpbmNyZWFzZWQgaW4gcHJpY2UgYXQgdGhlIHNhbWUgdGltZS4KCmBgYHtyfQojIyAgIlJlcGxhY2UgdGhlIE5BIHdpdGggeW91ciBhbnN3ZXIgKGUuZy4sICdBJyBpbiBxdW90ZXMpIgphbnN3ZXIzLjEgPSAnQicKcXVpei5jaGVjayhhbnN3ZXIzLjEpCmBgYAoKCmBgYHtyfQojIFRoaXMgaXMgdGhlIGZ1bmN0aW9uIGRlc2NyaWJlZCBhYm92ZS4KYmV0LmZ1biA8LSBmdW5jdGlvbihzdGFydCwgZW5kLCBiYXNrZXQudmVjLCBkYXRhKQp7CiAgICAjIyBzdGFydCA9IDE5ODAKICAgICMjIGVuZCA9IDE5OTAKICAgICMjIGRhdGEgPSBjb21tb2QKICAgICMjIGJhc2tldC52ZWMgPC0gYygiQ29wcGVyIiwgIkNocm9taXVtIiwgIk5pY2tlbCIsICJUaW4iKQogICAgeWVhciA8LSByb3duYW1lcyhkYXRhKQogICAgc3RhcnQucHJpY2UgPC0gZGF0YVt5ZWFyID09IHN0YXJ0LCBiYXNrZXQudmVjXQogICAgZW5kLnByaWNlICAgPC0gZGF0YVt5ZWFyID09IGVuZCwgYmFza2V0LnZlY10KICAgICMjIHdlIGludmVzdCAxMDAwLCBidXlpbmcgYW4gZXF1YWwgJCBhbW91bnQgaW4gZWFjaCBjb21tb2RpdHkuCiAgICBzdGFydC5mdW5kcyA8LSAxMDAwCiAgICBkb2xsYXJzLnBlci5jb21tb2QgPC0gc3RhcnQuZnVuZHMvbGVuZ3RoKGJhc2tldC52ZWMpICMgZS5nLiAkMjUwIHdpdGggNAogICAgIyMgYW1vdW50IHB1cmNoYXNlZCBvZiBlYWNoIGNvbW1vZGl0eQogICAgaG9sZGluZ3MudmVjIDwtIGRvbGxhcnMucGVyLmNvbW1vZC9zdGFydC5wcmljZQogICAgIyMgdmFsdWUgYXQgdGhlIGVuZAogICAgdmFsdWUuYXQuZW5kIDwtIHN1bShob2xkaW5ncy52ZWMgKiBlbmQucHJpY2UpCiAgICBjaGFuZ2UuaW4udmFsdWUgPC0gdmFsdWUuYXQuZW5kIC0gc3RhcnQuZnVuZHMKICAgIHJldHVybihjaGFuZ2UuaW4udmFsdWUpCn0KCndoby53aW5zLmZ1biA8LSBmdW5jdGlvbihjaGFuZ2UuaW4udmFsdWUpCnsKICAgIGlmZWxzZShjaGFuZ2UuaW4udmFsdWUgPiAwLCAiZWhybGljaCIsICJzaW1vbiIpCn0KCmBgYAoKTGV0J3MgdHJ5IHRoaXMgZm9yIDE5ODAgdG8gMTk5MCB3aXRoIEVocmxpY2gncyBiYXNrZXQuCgpgYGB7cn0KZWhybGljaC5iYXNrZXQudmVjIDwtIGMoIkNvcHBlciIsICJDaHJvbWl1bSIsICJOaWNrZWwiLCAiVGluIikKb3JpZ2luYWwuYmV0LnJlc3VsdCA8LSBiZXQuZnVuKCJzdGFydCIgPSAxOTgwLAogICAgICAgICAgICAgICAgICAgICAgImVuZCIgPSAxOTkwLAogICAgICAgICAgICAgICAgICAgICAgImJhc2tldC52ZWMiID0gZWhybGljaC5iYXNrZXQudmVjLAogICAgICAgICAgICAgICAgICAgICAgImRhdGEiID0gY29tbW9kKQp3aG8ud2lucy5mdW4ob3JpZ2luYWwuYmV0LnJlc3VsdCkKYGBgCgpRMy4yIEhvdyBtdWNoIHdvdWxkIFNpbW9uIGhhdmUgd29uIHdpdGggb3VyIHZlcnNpb24gb2YgdGhlICJiZXQiPyAKSGludDogd2hhdCB3YXMgdGhlIHZhbHVlIG9mIHRoZSBiZXQgcmVzdWx0PyBDaGVjayB0aGUgb3JpZ2luYWwuYmV0LnJlc3VsdCBvYmplY3QKCkEuIEFib3V0IDMwMCBkb2xsYXJzCgpCLiBIZSB3b3VsZG4ndCBoYXZlIHdvbi4gSGUgd291bGQgaGF2ZSBsb3N0IGFib3V0IDMwMCBkb2xsYXJzCgpDLiBBYm91dCA1MDAgZG9sbGFycwoKRC4gQWJvdXQgMTAwIGRvbGxhcnMKCmBgYHtyfQojIyAgIlJlcGxhY2UgdGhlIE5BIHdpdGggeW91ciBhbnN3ZXIgKGUuZy4sICdBJyBpbiBxdW90ZXMpIgphbnN3ZXIzLjIgPSAnQScKcXVpei5jaGVjayhhbnN3ZXIzLjIpCmBgYAoKCgojIFBhcnQgNC4gRG9lcyBTaW1vbiB3aW4gaW4gb3RoZXIgcGVyaW9kcz8KCkNvbW1vZGl0aWVzIGFyZSBoaWdobHkgdm9sYXRpbGUuICBFdmVuIGlmIGNvbW1vZGl0aWVzIHdlcmUgZ2VuZXJhbGx5CnJpc2luZywgRWhybGljaCBjb3VsZCBoYXZlIGJlZW4gdW5sdWNreSBhYm91dCB0aGUgdGltaW5nIG9mIGhpcyBiZXQuCgpMZXQncyBjaGVjayBvdmVyIGFsbCB5ZWFycyBzaW5jZSAxOTAwLiBXZSBjYW4gY29uc3RydWN0IGEgImxvb3AiIHVzaW5nClIgdGhhdCB3aWxsIHJlcGVhdCB0aGUgYmV0IGFjY29yZGluZyB0byBvdXIgaW5zdHJ1Y3Rpb25zLiBXZSBjYW4gdGhlbgpzYXZlIHRoZSBvdXRwdXQgaW4gYSB2ZWN0b3IgYW5kIG1ha2UgYSBqdWRnZW1lbnQgYWJvdXQgd2hldGhlciBFaHJsaWNoCndhcyBzaW1wbHkgdW5sdWNreS4KCkhlcmUncyBhIHNpbXBsZSBleGFtcGxlIG9mIGEgbG9vcCwgaW4gd2hpY2ggd2UgcmVwZWF0IGFuIGFjdGlvbiA3IHRpbWVzLAplYWNoIHRpbWUgaW5jcmVhc2luZyB0aGUgdmFsdWUgb2YgImkiLCBhbmQgcHJpbnRpbmcgdGhpcyB2YWx1ZSBhbG9uZyB3aXRoIGEgCmxhYmVsICJpdGVyYXRpb24iLgpgYGB7cn0KZm9yIChpIGluIDE6NykgICAjIyB0aGUgdmFyaWFibGUgImkiIHRha2VzIHRoZSB2YWx1ZSAxLCAyLCAzLCAuLi4KewogICAgIyMgYW55dGhpbmcgaW4gYmV0d2VlbiB7fSBpcyBkb25lIG9uY2UKICAgICMjIGZvciBlYWNoIHZhbHVlIHRoYXQgImkiIHRha2VzCiAgICBwcmludChjKCJpdGVyYXRpb24iLCBpKSkKfQpgYGAKCk5vdyBsZXQncyBkbyBhIGxvb3AgdG8gc2VlIHdobyB3b24gdGhlIGJldCBpbiBldmVyeSB5ZWFyIG9mIHRoZSBsYXN0CmNlbnR1cnkuCgpgYGB7cn0Kc3RhcnQudmVjIDwtIDE5MDA6MjAwNSAgICAgICAgIyMgYSB2ZWN0b3Igb2YgeWVhcnMgdG8gc3RhcnQgdGhlIGJldApiZXQucmVzdWx0LnZlYyA8LSByZXAoTkEsIGxlbmd0aChzdGFydC52ZWMpKSAjIyBhbiBlbXB0eSB2ZWN0b3IgdG8gYmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMgdXNlZCB0byBzdG9yZSB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMgcmVzdWx0cwpuYW1lcyhiZXQucmVzdWx0LnZlYykgPC0gc3RhcnQudmVjICMjIGxhYmVsaW5nIHRoZSBlbGVtZW50cyAoeW91IGNhbiBpZ25vcmUpCmZvciAoaSBpbiAxOmxlbmd0aChzdGFydC52ZWMpKQp7CiAgICBiZXQucmVzdWx0LnZlY1tpXSA8LSBiZXQuZnVuKHN0YXJ0ID0gc3RhcnQudmVjW2ldLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmQgPSBzdGFydC52ZWNbaV0gKyAxMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFza2V0LnZlYyA9IGVocmxpY2guYmFza2V0LnZlYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGNvbW1vZCkKfQpwcmludChiZXQucmVzdWx0LnZlYykKYGBgCgpUbyBzdW1tYXJpemUgb3VyIHJlc3VsdHMsIGxldCdzIGxvb2sgYXQgdGhlbSBpbiBzZXZlcmFsIHdheXMuCgpQbG90IHRoZSBudW1iZXJzCmBgYHtyfQpwbG90KHN0YXJ0LnZlYywgYmV0LnJlc3VsdC52ZWMpCmFibGluZShoID0gMCkKdGV4dCgxOTYwLCAxNTAwLCAiRWhybGljaCB3aW5zIiwgY29sID0gImJsdWUiKQp0ZXh0KDE5NjAsIC0yNTAsICJTaW1vbiB3aW5zIiwgY29sID0gInJlZCIpCmBgYApJbiB0aGUgZ3JhcGgsIGl0IGxvb2tzIGxpa2UgRWhybGljaCB3b3VsZCBoYXZlIHdvbiBtb3JlIG9mIHRoZSB0aW1lLiBCdXQgbm90IGEgbG90IG1vcmUuCgpMZXQncyB0YWJ1bGF0ZSBob3cgbWFueSB0aW1lcyBFaHJsaWNoIGFuZCBTaW1vbiB3b3VsZCBoYXZlIHdvbjoKYGBge3J9CiMjIENvbnZlcnQgdG8gYSB2ZWN0b3Igb2YgInNpbW9uIiBhbmQgImVocmxpY2giLCBkZXBlbmRpbmcgb24gd2hvIHdvbgp3aW5uZXJzLnZlYyA8LSB3aG8ud2lucy5mdW4oYmV0LnJlc3VsdC52ZWMpCnByaW50KHdpbm5lcnMudmVjKQpgYGAKYGBge3J9CiMjIGNvdW50IG51bWJlciBvZiB0aW1lcyBlYWNoIHdvbiB1c2luZyB0aGUgInRhYmxlKCkiIGZ1bmN0aW9uCnRhYmxlKHdpbm5lcnMudmVjKQpgYGAKClE0LjEgV2hhdCBwZXJjZW50IG9mIHRoZSB0aW1lIHdvdWxkIEVocmxpY2ggaGF2ZSB3b24gb2YgdGhlIDEwNiBzaW11bGF0ZWQgYmV0cyBmcm9tIDE5MDAgdG8gMjAwNT8KCkEuIEFib3V0IDYyIHBlcmNlbnQKCkIuIEFib3V0IDU4IHBlcmNlbnQKCmBgYHtyfQojIyAgIlJlcGxhY2UgdGhlIE5BIHdpdGggeW91ciBhbnN3ZXIgKGUuZy4sICdBJyBpbiBxdW90ZXMpIgphbnN3ZXI0LjEgPSAnQicKcXVpei5jaGVjayhhbnN3ZXI0LjEpCmBgYAoKCk1ha2UgYSBmYW5jaWVyIHBsb3Qgd2hpY2ggc2hvd3MgYWxsIHRoZSBwZXJpb2RzIHdoZW4gZWFjaCB3b3VsZCd2ZSB3b24uIChZb3UgZG9uJ3QgbmVlZCB0byB1bmRlcnN0YW5kIHRoaXMgY29kZS4pCmBgYHtyfQpwbG90KHN0YXJ0LnZlYywgYmV0LnJlc3VsdC52ZWMsIHR5cGUgPSAibiIpICNhbiBlbXB0eSBwbG90CmFibGluZShoID0gMCkKZSA8LSB3aGljaCh3aW5uZXJzLnZlYyA9PSAiZWhybGljaCIpICAgICMgVCBvciBGLCB0byBzdWJzZXQgdGV4dCgpCnMgPC0gd2hpY2god2lubmVycy52ZWMgPT0gInNpbW9uIikKdGV4dCh4ID0gc3RhcnQudmVjW2VdLCB5ID0gYmV0LnJlc3VsdC52ZWNbZV0sIGxhYmVscyA9ICJlIiwgY29sID0gImJsdWUiKQp0ZXh0KHggPSBzdGFydC52ZWNbc10sIHkgPSBiZXQucmVzdWx0LnZlY1tzXSwgbGFiZWxzID0gInMiLCBjb2wgPSAicmVkIikKdGV4dCgxOTYwLCAxNTAwLCAiRWhybGljaCB3aW5zIiwgY29sID0gImJsdWUiKQp0ZXh0KDE5NjAsIC0yNTAsICJTaW1vbiB3aW5zIiwgY29sID0gInJlZCIpCmBgYAoKCiMgNS4gR2VuZXJhbGl6aW5nIHRoZSBiZXQgdG8gb3RoZXIgY29tbW9kaXRpZXMKCkEgY2hhbmdlIGluIHRoZSBzdXBwbHkgb2YgYSBwYXJ0aWN1bGFyIGNvbW1vZGl0eSBtYXkgb3IgbWF5IG5vdCBjYXVzZQphIGxhcmdlIHByaWNlIGNoYW5nZSAtLSBkZXBlbmRpbmcgb24gdGhlIGF2YWlsYWJpbGl0eSBvZgpzdWJzdGl0dXRlcy4gKE5vdGU6IHRoZSByZXN1bHRzIGZyb20gdGhpcyBzZWN0aW9uIHdpbGwgYmUgdXNlZnVsIGZvcgp5b3VyIHdyaXRlLXVwIG9mIHRoZSBncmFkZWQgcXVlc3Rpb25zIGF0IHRoZSBlbmQgb2YgdGhlIGxhYi4pCgpUaGUgZm9sbG93aW5nIGNvZGUgcHJvdmlkZXMgYSB0ZW1wbGF0ZSBmb3IgYSBzaW5nbGUgY29tbW9kaXR5LCBpbiB0aGlzCmNhc2UgIkNocm9taXVtIiAoYnV0IHlvdSBjYW4gY2hhbmdlIHRoZSBjb21tb2RpdHkpLgoKYGBge3J9CnN0YXJ0LnZlYyA8LSAxOTAwOjIwMDUKcmVzdWx0LnZlYyA8LSByZXAoTkEsIGxlbmd0aChzdGFydC52ZWMpKQpmb3IgKGkgaW4gMTpsZW5ndGgoc3RhcnQudmVjKSkKICB7CiAgcmVzdWx0LnZlY1tpXSA8LSBiZXQuZnVuKHN0YXJ0ID0gc3RhcnQudmVjW2ldLAogICAgICAgICAgICAgICAgICAgICAgZW5kID0gc3RhcnQudmVjW2ldICsgMTAsCiAgICAgICAgICAgICAgICAgICAgICBiYXNrZXQudmVjID0gYygiQ2hyb21pdW0iKSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBjb21tb2QpCn0Kd2lubmVyLnZlYyA8LSB3aG8ud2lucy5mdW4ocmVzdWx0LnZlYykKY2F0KCJjb3VudHM6XG4iKQp0YWJsZSh3aW5uZXIudmVjKQpjYXQoInByb3BvcnRpb25zOlxuIikKcHJvcC50YWJsZSh0YWJsZSh3aW5uZXIudmVjKSkKYGBgCgpXZWxsIGRvbmUuIFlvdSBhcmUgZmluaXNoZWQgd2l0aCB0aGUgY29tcHV0aW5nIHBvcnRpb24gb2YgTGFiIDUuCgojIFBhcnQgNS4gR3JhZGVkIFF1ZXN0aW9ucwoKPiAxLiBXaGF0IHJlbGF0aW9uc2hpcCBkaWQgRWhybGljaCBleHBlY3QgdG8gaG9sZCBiZXR3ZWVuIGNvbW1vZGl0eQo+ICAgIHByaWNlcyBhbmQgcG9wdWxhdGlvbiBncm93dGg/CkVocmxpY2ggZXhwZWN0ZWQgdGhhdCB3aXRoIHBvcHVsYXRpb24gZ3Jvd3RoLCBjb21tb2RpdHkgcHJpY2VzIHdvdWxkIGluY3JlYXNlIGFzIHdlbGwuCgo+IDIuIFdobyB3b24gdGhlIGJldCBpbiAxOTkwPyBHaXZlbiBvdXIgYW5hbHlzaXMgb2Ygb3RoZXIgdGltZQo+ICAgIHBlcmlvZHMsIHdvdWxkIHlvdSBzYXkgdGhhdCB0aGUgd2lubmVyIHdhcyDigJxsdWNreeKAnSBvciDigJxyaWdodOKAnSwgb3IKPiAgICBib3RoPyAgW0V4cGxhaW4geW91ciBhbnN3ZXIgaW4gNTAgdG8gMTAwIHdvcmRzLl0KU2ltb24gd29uIHRoZSBiZXQgaW4gMTk5MCBmb3IgYSBjaGVjayBvZiAkNTc2IGZyb20gRWhybGljaC4gSSB3b3VsZCBzYXkgaGUgd3dlcmUgYm90aCBsdWNreSBhbmQgcmlnaHQuIFRoZSB0aW1pbmcgb2YgaGlzIGRlY2lzaW9uIGRlZmluaXRlbHkgYWZmZWN0cyBoaXMgd2lubmluZywgYnV0IGhlIHByb2JhYmx5IGFsc28gaGFkIGEgZ29vZCBpZGVhIG9mIGhvdyBjb21tb2RpdHkgcHJpY2VzIHdlcmUgdG8gZ3JvdyBvciBkZWNyZWFzZS4KCj4gQXMgbm90ZWQgaW4gdGhlIGxhYiwgdGhpcyBzZWN0aW9uIGlzIGZvciB5b3UgdG8gZXhwbG9yZSBhbmQgZGVzY3JpYmUKPiB3aGF0IHlvdSBmb3VuZC4gV2hldGhlciB3aGF0IHlvdSBmaW5kIGlzIGNvbmNsdXNpdmUgb3IgaW5jb25jbHVzaXZlLAo+IHlvdSBjYW4gc3RpbGwgZ2V0IGZ1bGwgY3JlZGl0IGJ5IHJlcG9ydGluZyB3aGF0ZXZlciB5b3UgZm91bmQuCgo+IDMuIENob29zZSBhbm90aGVyIGVhc2lseSBzdWJzdGl0dXRhYmxlIGNvbW1vZGl0eSBmcm9tIHRoZQo+ICAgIGRhdGFiYXNlLiBDb25kdWN0IHRoZSBhbmFseXNpcyBvZiBpdHMgcHJpY2UgYXMgdGhlIHByZXZpb3VzIHBhcnQKPiAgICBvZiB0aGUgbGFiIGFuZCBhbnN3ZXIgdGhlIGZvbGxvd2luZyBxdWVzdGlvbnMuCgo+IDMuMSkgV2h5IGRvIHlvdSB0aGluayB0aGlzIGNvbW1vZGl0eSB3b3VsZCBiZSBlYXNpbHkgc3Vic3RpdHV0YWJsZSwKPiAgICAgIGV4cGxhaW5pbmcgd2hhdCDigJxzZXJ2aWNl4oCdIGl0IHByb3ZpZGVzIHdpdGggMSBvciAyIHNlbnRlbmNlcy4KSSB0aGluayBQb3JrIHdvdWxkIGJlIGVhc2lseSBzdWJzdGl0dXRhYmxlIGZvciBhbnkgb3RoZXIgdmFyaWV0eSBvZiBtZWF0LCBzdWNoIGFzIGJlZWYgb3IgbGFtYi4gU2luY2UgaXQgaXMgYSBmb29kIG9wdGlvbiwgaXQgaXNuJ3Qgc28gbXVjaCB2aXRhbCBhcyBzYXkgYmVlZiBhbmQgbGFtYiwgc2luY2UgdGhvc2UgYW5pbWFscyBhcmUgdmFsdWFibGUgZm9yIG1vcmUgdGhhbiBqdXN0IHRoZWlyIG1lYXQsIGJ1dCBhbHNvIHRoZWlyIGxlYXRoZXIvd29vbC4KCj4gMy4yKSBBdHRhY2ggYSBwbG90IG9mIHRoZSByZWFsIHByaWNlIG9mIHlvdXIgY2hvc2VuIGNvbW1vZGl0eSBhbmQgY29tbWVudCBvbiBpdHMgdHJlbmQKPiB1cCB0byAxOTgwIGluIDEgc2VudGVuY2UuCj4gSGludDogeW91IGNhbiBtb2RpZnkgY29kZSBpbiBzZWN0aW9uIDIuCgpgYGAge3J9CnllYXIudmVjIDwtIHJvd25hbWVzKGNvbW1vZCkKcGxvdCh5ZWFyLnZlYywgY29tbW9kJFBvcmssIHR5cGUgPSAibCIpCmFibGluZSh2ID0gMTk4MCkgICAgICAgICAgICAgICAgICAgICAgICAjIHRoZSBkYXRlIG9mICJ0aGUgYmV0IgpgYGAKPiBUaGUgdHJlbmQgZGVmaW5pdGVseSBnb2VzIGRvd253YXJkIGFzIHRpbWUgZ29lcyBvbi4KCj4gMy4zKSBBdHRhY2ggYSBwbG90IG9mIHRoZSAqY2hhbmdlKiBvZiBwcmljZXMgKOKAnGJldC5yZXN1bHTigJ0pIG9mIHRoZQo+ICAgICAgY2hvc2VuIGNvbW1vZGl0eS4gCgpgYGAge3J9CnN0YXJ0LnZlYyA8LSAxOTAwOjIwMDUgICAgICAgICMjIGEgdmVjdG9yIG9mIHllYXJzIHRvIHN0YXJ0IHRoZSBiZXQKYmV0LnJlc3VsdC52ZWMgPC0gcmVwKE5BLCBsZW5ndGgoc3RhcnQudmVjKSkgIyMgYW4gZW1wdHkgdmVjdG9yIHRvIGJlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIHVzZWQgdG8gc3RvcmUgdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIHJlc3VsdHMKbmFtZXMoYmV0LnJlc3VsdC52ZWMpIDwtIHN0YXJ0LnZlYyAjIyBsYWJlbGluZyB0aGUgZWxlbWVudHMgKHlvdSBjYW4gaWdub3JlKQpmb3IgKGkgaW4gMTpsZW5ndGgoc3RhcnQudmVjKSkKewogICAgYmV0LnJlc3VsdC52ZWNbaV0gPC0gYmV0LmZ1bihzdGFydCA9IHN0YXJ0LnZlY1tpXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kID0gc3RhcnQudmVjW2ldICsgMTAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhc2tldC52ZWMgPSBjKCJQb3JrIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBjb21tb2QpCn0KCnBsb3Qoc3RhcnQudmVjLCBiZXQucmVzdWx0LnZlYykKYWJsaW5lKGggPSAwKSAgICAgICAgICAgICAgICAgICAgICAgICMgdGhlIGRhdGUgb2YgInRoZSBiZXQiCgp0ZXh0KDE5ODAsIDEwMDAsICJFaHJsaWNoIHdpbnMiLCBjb2wgPSAiYmx1ZSIpCnRleHQoMTk2MCwgLTUwMCwgIlNpbW9uIHdpbnMiLCBjb2wgPSAicmVkIikKYGBgCgo+IEhpbnQgMTogdGhlcmUgd291bGQgb25seSBiZSB5b3VyIGNob3NlbiBjb21tb2RpdHkgaW4gdGhlCj4g4oCcYmFza2V0LnZlY+KAnS4gWW91IGNhbiBlaXRoZXIgbW9kaWZ5IHRoZSBvcmlnaW5hbAo+IOKAnGVocmxpY2guYmFza2V0LnZlY+KAnSBvciBjcmVhdGUgeW91ciBvd24g4oCcYmFza2V0LnZlY+KAnS4gUmVtZW1iZXIgdG8KPiBtb2RpZnkgZm9yLWxvb3AgY29uc2lzdGVudGx5LgoKPiBIaW50IDI6IHlvdSBkb27igJl0IG5lZWQgdG8gc2hvdyB3aGV0aGVyIEVocmxpY2ggb3IgU2ltb24gd2luIGFib3V0Cj4gdGhpcyBjb21tb2RpdHkuIEJ1dCBsYWJlbGxpbmcgdGhlIHBsb3Qgd2l0aCBkaWZmZXJlbnQgY29sb3JzIGNhbgo+IGhlbHAgeW91IHVuZGVyc3RhbmQgdGhlIGdlbmVyYWwgdHJlbmQuCgo+IE5vdGUgKE5PVCBSRVFVSVJFRCk6IFRvIG1ha2UgaXQgYSBiZXR0ZXIgZ3JhcGgsIHlvdSBjYW4gYWRkIGEgdGl0bGUKPiB0byB0aGUgZ3JhcGggaW5kaWNhdGluZyB0aGUgY29tbW9kaXR5IHlvdSBjaG9vc2UgYWRkaW5nIOKAmG1haW4gPQo+IOKAnGNvbW1vZGl0eSBuYW1l4oCd4oCZIHRvIHRoZSBzeW50YXguCgo+IDQuIENob29zZSBhIGNvbW1vZGl0eSBmcm9tIHRoZSBkYXRhYmFzZSB3aGljaCB5b3UgdGhpbmsgd291bGQgYmUKPiAgICBoYXJkIHRvIHN1YnN0aXR1dGUgZm9yLiBBbmQgZXhwbGFpbiB3aHkgeW91IHRoaW5rIHRoaXMgY29tbW9kaXR5Cj4gICAgd291bGQgTk9UIGJlIGVhc2lseSBzdWJzdGl0dXRlZCwgZXhwbGFpbmluZyB3aGF0IOKAnHNlcnZpY2XigJ0gaXQKPiAgICBwcm92aWRlcy4gKEluIDEgb3IgMiBzZW50ZW5jZXMpIFtOb3RlOiB5b3UgZG9uJ3QgbmVlZCB0byBhbmFseXplCj4gICAgdGhlIGRhdGEgZm9yIHRoaXMgcHJvYmxlbS5dCldoZWF0IG9yIENvYWwgd291bGQgYmUgZGlmZmljdWx0IHRvIHN1YnN0aXR1dGUgZm9yLiBXaGVhdCBpcyBhIGNvbW1vbiBjb21tb2RpdHkgZm9yIGdyYWlucywgc3VjaCBhcyBicmVhZCwgYW5kIGdpdmVzIGxvdHMgb2YgbnV0cml0aW9uLiBCcmVhZCBpcyB2ZXJ5IGNydWNpYWwgZm9yIG1lYWxzLCBhbmQgdGh1cyB3aGVhdCB3b3VsZCBiZSB2ZXJ5IGRpZmZpY3VsdCB0byBzaW1wbHkgc3Vic3RpdHV0ZSBmb3Igc29tZXRoaW5nIGVsc2UuIENvYWwgaXMgYWxzbyB2ZXJ5IGltcG9ydGFudCwgYXMgaXQgaXMgdGhlIG1haW4gY29tbW9kaXR5IGZvciBoZWF0IGluIGhvbWVzIGFuZCBmb3IgbWFjaGluZXJ5IHRvIHdvcmsuCgpDb25ncmF0dWxhdGlvbnMhIFlvdSBhcmUgZmluaXNoZWQgd2l0aCBMYWIgNS4=