Comparing Duke, UNC, and NC State Twitter Activity: A Text Mining Approach

Soraya Campbell

2021-05-10

1 Twitter activity of Duke, UNC, and NC State

Duke University, NC State University, and UNC-Chapel Hill are three research I universities in central North Carolina. Together they comprise of the ‘Research Triangle,’ which, together with the Research Triangle Park and other area universities, drive innovation and growth in the region. While these three universities share the research I university designation, they are distinct in many aspects. Can we discern this distinction by their Twitter activity? What topics do they engage in the most? Is there any overlap?

This analysis is intended for anyone interested in text mining techniques, especially for social media data like Twitter, those working for institutions of higher education, especially communications professionals or social media managers, or anyone who is a Blue Devil 😈, TarHeel 🐏, or part of the Wolfpack 🐺.

In this walk-through, we’ll explore:

  • When and how often do each of these accounts tweet
  • What do these schools tweet about the most? Is there is a difference between schools?
  • Which words are more likely to be retweeted or favorited between these accounts?
  • Do certain words share a similar sentiment?

Let’s find out!

2 Getting the Data

Using the rtweet package, I pulled the latest 3200 tweets from each university’s main twitter account.

## get timelines
tmls <- get_timelines(c("dukeu", "ncstate", "unc"), n = 3200)
glimpse(tmls)

I then filtered only to include tweets from a one year time range, which resulted in 7522 observations and the following activity by account:

tmlsyr <- tmls %>%
    filter(created_at >= "2020-04-25")
Table 2.1: Number of tweets between Apr 20-Apr 21 by account
screen_name n
NCState 3057
UNC 2435
DukeU 2030

3 Timeseries

NC State is the leader in number of tweets for this past year. Let’s look at the activity distribution with a ts_plot and ggplot histogram.

## ts_plot by screen name
ts_plot(group_by(tmlsyr, screen_name), "months")
Time series plot of Twitter Activity

Figure 3.1: Time series plot of Twitter Activity

## histogram with facet wrap
ggplot(tmlsyr, aes(x = created_at, fill = screen_name)) + geom_histogram(position = "identity", 
    bins = 20, show.legend = FALSE) + facet_wrap(~screen_name, ncol = 1)
Histogram of Twitter activity

Figure 3.2: Histogram of Twitter activity

We can see that each university account has a steady flow of tweets that averages out to the following per month in this year time period:

Table 3.1: Average number of tweets per month by account
screen_name avg
NCState 235
UNC 187
DukeU 156

Seems like NC State has been a busy bee, with significant activity in the months of September and March that skews its average upward. What’s going on here?

By analyzing the word counts per month for NC State, we can see that the term #GivingPack dominated for these two months. This makes sense since this is a fundraising campaign which is conducted heavily via social media and some donations were matched depending on Twitter activity.

Table 3.2: Sample NC State March Tweets
text created_at
@ecauley92 By #GivingPack today, you’re helping us keep NC State accessible to students from every economic background. Thank you for your gift to @NCStateCED and the NC State Extraordinary Opportunity Scholarship! https://t.co/9hd8azNGKG 2021-03-24 18:52:04

.@PackWomensBball head coach @WolfpackWes invites you to join us for NC State Day of Giving! Let’s show once again that there is strength in the Pack.

<U+0001F4C6> Wednesday, March 24 <U+0001F4CD> https://t.co/6fJa9tcy0V #<U+FE0F><U+20E3> #GivingPack https://t.co/qCJNjXGLfk
2021-03-21 19:19:00
Table 3.3: Sample NC State September Tweets
text created_at
Our first pet-tastic winner is @NCStateEngr! Thanks to Willis_Doodle on Instagram for repping the Wolfpack on this day of #GivingPack. <U+0001F43A><U+0001F43E> Congrats on that extra $3,000! https://t.co/pKOStG733d 2020-09-16 19:20:56
Today is #GivingPack, a day to support students impacted by #COVID. Throughout the day, we’re sharing the impact of every dollar raised to #SupportSurvivors &amp; #WOC through the #SurvivorFund &amp; Dr. Frances Graham WOC Leadership Fund. Help us if you can: https://t.co/dhLpvX6VbN https://t.co/6eJNzsch3T 2020-09-16 20:03:08

We’ll do an additional time series look when we get to the section Comparing Word Usage.

4 Comparing Word Frequencies

Now let’s compare which words were used most frequently by each university. In particular, I am interested in seeing change in word frequencies over the year time span we are looking at. For this I will adapt the Twitter case study and code from Julia Silge and David Robinson’s Text Mining with R.

With Twitter data, some form of clean-up is usually necessary, especially before tokenizing text. Whether you remove hashtags, mentions (@)’s, emojis, or other special characters will depend on your purpose. Here, we’ll use the specialized “tweets” tokenizer to deal with Twitter text, which retains hashtags and mentions of usernames with the @ symbol. The code below removes retweets so that the data is only of tweets these accounts wrote themselves. Some special characters were removed as well.

remove_reg <- "&amp;|&lt;|&gt;"
tidy_tweets <- tmlsyr %>%
    filter(!str_detect(text, "^RT")) %>%
    mutate(text = str_remove_all(text, remove_reg)) %>%
    unnest_tokens(word, text, token = "tweets") %>%
    filter(!word %in% stop_words$word, !word %in% str_remove_all(stop_words$word, 
        "'"), str_detect(word, "[a-z]"))

Now we can calculate word frequencies for each university’s account.

frequency <- tidy_tweets %>%
    group_by(screen_name) %>%
    count(word, sort = TRUE) %>%
    left_join(tidy_tweets %>%
        group_by(screen_name) %>%
        summarise(total = n())) %>%
    mutate(freq = n/total)

Then the data is pivoted wider to get it ready to plot.

frequency <- frequency %>%
    select(screen_name, word, freq) %>%
    pivot_wider(names_from = screen_name, values_from = freq) %>%
    arrange(NCState, UNC, DukeU)

These plots compare word usage between Duke University, NC State, and UNC-Chapel Hill. Words near the line are used with about equal frequency between the universities whereas words further away from it are used much more by that university than the other.

Word Frequency between NCState and UNC Twitter accounts

Figure 4.1: Word Frequency between NCState and UNC Twitter accounts

Word Frequency between UNC and DukeU Twitter accounts

Figure 4.2: Word Frequency between UNC and DukeU Twitter accounts

Word Frequency between NCState and DukeU Twitter accounts

Figure 4.3: Word Frequency between NCState and DukeU Twitter accounts

You can see that there are some common shared words between these universities:

  • student/students
  • covid19
  • community
  • care/support

These words make sense since this timeframe of tweets coincides with the covid19 pandemic. Universities made many efforts to support students during these challenging times.

Although I won’t be performing a formal topic model analysis of these tweets, I think we can safely say that covid19 was a ‘topic’ shared among these universities throughout this year. We will come back to this particular topic when we do our Sentiment Analysis.

To round out our look at word frequencies, let’s find words that have changed in frequency at a moderately significant level in each account’s tweets. This can help us determine ‘trending’ words.

Trending words in DukeU’s tweets

Figure 4.4: Trending words in DukeU’s tweets

Significant here is the slope of #covid19 which started off very frequently at the beginning of the pandemic, trended down, and then saw a moderate rise in December. Also the inverse occurred with the term ‘vaccine’ as it saw its prominence rise in December when news of covid19 vaccines started to become available.

Trending words in NCState’s tweets

Figure 4.5: Trending words in NCState’s tweets

There’s alot going on in this graph, but #givingpack features prominently, starting high in September, falling down precipitously until March when it picks back up accordingly with our discovery of their fundraising campaigns those two months.

Trending words in UNC’s tweets

Figure 4.6: Trending words in UNC’s tweets

Again, alot going on, but of note, and makes sense, is the term/hashtag #uncgrad which started off high May 2020, coinciding with Spring graduation and then falling off until December (Fall graduation). Following this trend, it would have picked back up again May 2021. The term ‘Fall’ rising in August coincides with the beginning of the Fall term, and ‘testing’ could be because of changes in testing protocols for covid19.

5 Comparing Word Usage

Now let’s see what words were being tweeted about the most. I’ll explore this in two ways:

  1. Simple word counts to analyze usage
  2. Term frequency/inverse document frequency (tf-idf) values to analyze which words are more likely to come from one account versus the other

First, let’s do a simple word count of the top twenty words that are in the corpus.

Word Counts for Duke, UNC, and NC State

Figure 5.1: Word Counts for Duke, UNC, and NC State

Next, let’s use wordcloud to help us visualize these terms per university.

Here’s Duke, whose name features prominently in the visualization along with ‘students,’ ‘covid19,’ ‘pandemic,’ ‘faculty,’ ‘research,’ ‘health,’ among many other terms.

Figure 5.2: Word Cloud Duke University’s most tweeted terms

Now here’s NC State, where their motto ‘think and do’ features prominently along with the word ‘students.’ Also many of the university’s individual colleges’ or departments’ twitter screen names are displayed here. You can also see the words ‘gift,’ ‘support,’ ‘scholarship,’ ‘giving,’ ‘helping,’ ‘donors,’ and of course, ‘wolfpack’ featured here.

NC State Wordcloud

And finally, here’s UNC with ‘tar’ ‘heels’ front and center, which is what they call themselves, along with their hashtag ‘#unc,’ ‘students,’ ‘covid19,’ ‘pandemic,’ and ‘community’ being featured.

UNC WordCloud

If we want to take this analysis further, we can add gganimate to our plot to view most frequently tweeted words over time.

words_by_time <- tidy_tweets %>%
    filter(!str_detect(word, "^@")) %>%
    mutate(time_floor = floor_date(created_at, unit = "1 month")) %>%
    count(time_floor, screen_name, word) %>%
    group_by(screen_name, time_floor) %>%
    mutate(time_total = sum(n)) %>%
    group_by(screen_name, word) %>%
    mutate(word_total = sum(n)) %>%
    ungroup() %>%
    rename(count = n) %>%
    filter(word_total > 30)
Duketime <- words_by_time %>%
    filter(screen_name == "DukeU")

gg <- Duketime %>%
    ggplot(aes(label = word, size = count)) + geom_text_wordcloud(area_corr = TRUE) + 
    scale_size_area(max_size = 20) + theme_minimal()
gg + transition_time(time_floor) + labs(title = "@DukeU's most tweeted words: {frame_time}")

With the help of worldcloud, these time series plots give us a good picture of what terms occurred most frequently throughout the year. Again, covid19 and words having to do with the pandemic are common among all the universities throughout the year in these visualizations.

5.1 Term-frequency, inverse document frequency

So, we’ve seen alot of overlap of terms between these universities. What is unique about what they tweet? Let’s calculate the tf-idf values to find out:

Unique words used by each university

Figure 5.3: Unique words used by each university

You can see that for Duke, they most uniquely tweet about ‘dukehealth,’ ‘engineering,’ the blue ‘devils,’ their mascot, the medical school and other departments that feature prominently in their research output. ‘Dukestudents’ also rounds out the top 10 words unique to Duke.

For NC State, as we have seen, ‘#givingpack’ is most uniquely identified with them as their big fundraising event that is so active on Twitter/social media. ‘Wolfpack,’ their mascot, ‘thinkanddo,’ their motto, and other NC State departments round out the list.

For UNC, their moniker, the ‘tar’ ‘heels,’ and their hashtag ‘#gdtbath’ (or good day to be a Tar Heel) features prominently.

6 Retweets and Favorites

Now let’s see how these accounts interact with each other via mentions and also look at their retweet and favorites activity. Initially, I thought because of their shared character as research universities and some of the synergies borne from that, they would be pretty tight Twitter pals. It turns out, not so much.

First let’s see whose account has the most retweets:

Table 6.1: Total Number of retweets by account
screen_name total_rts
DukeU 45585
UNC 36557
NCState 27505

What words were in the tweets that were the most retweeted?

It seems like retweets are dominated by terms related to sports activity. Also Duke’s retweet of Coach K’s speech about #blacklivesmatter garnered many retweets. ✊🏿

Now let’s do favorites:

Median Favorites

Figure 6.1: Median Favorites

Interesting here is the term ‘remdesivir’, which is an anti-viral drug developed through a UNC-Chapel Hill partnership, which was used in the fight against the covid19 virus. Otherwise, the favorited terms had alot to do about campus life, sports, places on campus, and my personal favorite, Duke Gardens.

How about top mentions for each university? As you can see, it’s very university-centric. Most mentions are to other departments/units within the same university. The top mention for all of them, of course, is to itself :-)

Table 6.2: Top mentions for DukeU
screen_name mentions n
DukeU @DukeU 106
DukeU @DukeHealth 62
DukeU @DukeEngineering 38
DukeU @DukeMedSchool 34
DukeU @DukeSanford 27
Table 6.2: Top mentions for UNC
screen_name mentions n
UNC @UNC 52
UNC @KevinGuskiewicz 44
UNC @UNCHealthCare 32
UNC @UNCpublichealth 31
UNC @UNCSOM 26
Table 6.2: Top mentions NC State
screen_name mentions n
NCState @NCState 210
NCState @NCStateEngr 159
NCState @NCStateCALS 139
NCState @NCStateCHASS 139
NCState @PackAthletics 125

And finally, let’s see how many times they mention each other:

Table 6.3: Mentions of each others’ accounts by university
screen_name mentions n
DukeU @NCState 4
NCState @DukeU 1
DukeU @UNC 9
UNC @DukeU 5
NCState @UNC 3
UNC @NCState 2

7 Sentiment Analysis

The last analysis we’ll do is a sentiment analysis on a shared topic. As we’ve seen throughout our dive into the data, covid19 featured prominently in the tweets of each of the universities. Indeed, the covid19 pandemic shaped the year snapshot that we are analyzing. Let’s analyze the sentiment shared amongst the universities by time in regards to covid19. We’ll use the vader package to make our lives easier, since it doesn’t necessitate tokenizing of text. It’s especially effective on social media data, such as Twitter, and can analyze the sentiments from emoticons as well! 😁

First, let’s count the number of tweets per university that mentioned the pandemic. Here we’ll use the grepl function to pull out tweets with the terms we need:

vader_tmlsyr <- vader_df(tmlsyr$text)


joinvader_tmlsyr <- tmlsyr %>%
    inner_join(vader_tmlsyr, by = "text")

vader_results <- joinvader_tmlsyr %>%
    select(screen_name, created_at, text, compound, pos, neu, neg, but_count) %>%
    mutate(sentiment = ifelse(compound > 0, "positive", ifelse(compound < 0, "negative", 
        "neutral")))
## covid sentiment
vader_covid <- vader_results %>%
    filter(grepl("(?i)COVID|corona|virus|pandemic", text))

Now let’s use lubridate to help us do our time series:

# lubridate
vader_date <- vader_covid %>%
    mutate(year_month = floor_date(created_at, "months") %>%
        ymd())

vader_date_summarise <- vader_date %>%
    group_by(screen_name, year_month) %>%
    summarise(mean = mean(compound))

## covid count
covid_plot_count <- vader_date %>%
    group_by(screen_name, year_month) %>%
    count(screen_name)
# plot covid tweets count
ggplot(covid_plot_count, aes(x = year_month, y = n, )) + geom_line(aes(color = screen_name))

Time Series Plot of tweets related to Covid19

vader_date_summarise %>%
    ggplot(aes(x = year_month, y = mean)) + geom_point(aes(color = screen_name)) + 
    geom_smooth(method = "auto") + labs(x = NULL, y = "Mean Compound Score", title = "Tweets related to Covid-19 and the 
       Pandemic: Vader Sentiment Score over time for Duke, UNC, and NC State", 
    caption = "Compound Score:
       -1 (most extreme negative) and +1 (most extreme positive)")

Sentiment Score for Tweets Related to Covid19

The compound score for the sentiment is computed by summing the valence scores of each word in the lexicon, adjusted according to the rules, and then normalized to be between -1 (most extreme negative) and +1 (most extreme positive).

The results of the sentiment analysis are interesting. The sentiment skews positive for all three universities overall. This makes some sense in the context of these main accounts tweeting mainly informational positions, like policies or directives for their campus community, or tweets related to research ongoing in this area - most likely research gains. You can see a slight bow curve from April 2020, the beginning of the pandemic, to April 2021. Duke and NC State had their negative moments in August 2020 and November 2020 respectively. An outlier is UNC in July 2020 with an almost 0.6 compound score.

What’s also interesting to note, is that the sentiment scores during April 2021 seemed to be the most homogenous than that of any other time in the year. As vaccines are administered and restrictions loosened on campuses, I’ll be curious to see how these sentiment scores evolve.

And because I’m curious, and these universities share the research I designation, let’s look at the twitter activity and sentiment score of tweets related to research:

Time Series Plot of tweets related to Research
The activity for research is a little less than that relating to covid19. UNC had alot of activity October 2020.

Now let’s look at the sentiment score:


Sentiment Score for Tweets Related to Research

It’s pretty positive, with an overall upward slope at the end. Again, UNC trends positive. Duke’s sentiment score in regards to research trend downward, which is interesting. After inspecting the tweets, it may be that the issues they are researching might skew the sentiment negative, i.e. diseases, social problems, etc.

8 Discussion

The central question that I set out for this analysis is what is unique to each university in the way they carry out their Twitter activity? Are there certain characteristics that define each university? Our analysis yielded some common results:

  • These universities have similar amounts of tweets per month on average, with the exception of NC State when they are conducting their #givingpack campaign
  • There were many common words expressed between the accounts, especially having to do with the pandemic, which dominated the year snapshot
  • These universities do not mention each other often, rather they amplify the accounts of those belonging to their university (departments, etc.)

As for differences, each university’s focus came out in analyzing the tweets. For example, Duke is known for their medical system and research in health and medicine so it is natural for them to tweet often about this. NC State’s fundraising campaign and their college of engineering features prominently and they really engage with students, alumni, and their various colleges/departments on campus on Twitter. UNC tended to focus on their identity as a “Tarheel” and was the university that spoke more towards sports than the others, even though the others have strong athletics.

We must also remember the limitations of this analysis which mainly lie in the exploration of one social media platform to extrapolate the overall considerations of each university. This analysis can only offer a snapshot of a wider communications network that each university employs. Also, each method of text analysis has its pros/cons as to the accuracy or efficacy of the model. However, taken altogether, these methods have provided us a glimpse into our research question.

9 Final Thoughts

This analysis gave us a good picture of the characteristics of each university’s main Twitter account. They do have some things in common, and the breath of what was discussed in their accounts could be because of their profile of being large, research I universities. However, each sought to amplify their own unique strengths and what makes them distinct in terms of student focus, their academic departments, research, and other campus activities. For those who manage social media accounts or communications for institutions for higher education, this analysis is a useful case study of how each of these universities have told their unique story during the common challenge of the covid-19 pandemic. The metrics obtained about frequency and engagement are especially useful as a benchmark for effective Twitter social media management.

10 About Me

By day, I am Assistant Director for the Global Education Office at Duke University. By (late) night, I mess around with data. Follow me on Twitter @sorayaworldwide

LS0tDQp0aXRsZTogIkNvbXBhcmluZyBEdWtlLCBVTkMsIGFuZCBOQyBTdGF0ZSBUd2l0dGVyIEFjdGl2aXR5OiBBIFRleHQgTWluaW5nIEFwcHJvYWNoIg0KZGF0ZTogImByIFN5cy5EYXRlKClgIg0KYXV0aG9yOiAiW1NvcmF5YSBDYW1wYmVsbF0oaHR0cHM6Ly90d2l0dGVyLmNvbS9zb3JheWF3b3JsZHdpZGUpIg0Kb3V0cHV0Og0KICBybWRmb3JtYXRzOjpkb3duY3V0ZToNCiAgICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQ0KICAgIHRodW1ibmFpbHM6IHRydWUgICAgIA0KICAgIGxpZ2h0Ym94OiB0cnVlICAgICANCiAgICBnYWxsZXJ5OiBmYWxzZSAgICAgDQogICAgaGlnaGxpZ2h0OiBrYXRlICAgIA0KICAgIGNvZGVfZm9sZGluZzogc2hvdyAgICAgDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIHVzZV9ib29rZG93bjogdHJ1ZQ0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkocm1kZm9ybWF0cykNCg0KIyMgR2xvYmFsIG9wdGlvbnMNCm9wdGlvbnMobWF4LnByaW50PSI3NSIpDQpvcHRzX2NodW5rJHNldChlY2hvPUZBTFNFLA0KCSAgICAgICAgICAgICBjYWNoZT1UUlVFLA0KICAgICAgICAgICAgICAgcHJvbXB0PUZBTFNFLA0KICAgICAgICAgICAgICAgdGlkeT1UUlVFLA0KICAgICAgICAgICAgICAgY29tbWVudD0nJywNCiAgICAgICAgICAgICAgIG1lc3NhZ2U9RkFMU0UsDQogICAgICAgICAgICAgICB3YXJuaW5nPUZBTFNFKQ0Kb3B0c19rbml0JHNldCh3aWR0aD03NSkNCmBgYA0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeSh0aWR5cikNCmxpYnJhcnkodGlkeXRleHQpIA0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkod29yZGNsb3VkMikgDQpsaWJyYXJ5KGZvcmNhdHMpDQpsaWJyYXJ5KHJlbW90ZXMpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpsaWJyYXJ5KHJlYWR4bCkNCmxpYnJhcnkocnR3ZWV0KQ0KbGlicmFyeSh0d2VldHJtZCkNCmxpYnJhcnkoZ2dhbmltYXRlKQ0KbGlicmFyeShnZ3dvcmRjbG91ZCkNCmxpYnJhcnkoc3RyaW5ncikNCmxpYnJhcnkoc2NhbGVzKQ0KbGlicmFyeShsdWJyaWRhdGUpDQpsaWJyYXJ5KHB1cnJyKQ0KbGlicmFyeShicm9vbSkNCmxpYnJhcnkodmFkZXIpDQpsaWJyYXJ5KGh0bWx3aWRnZXRzKQ0KbGlicmFyeSh3ZWJzaG90KQ0KbGlicmFyeShmb3JtYXRSKQ0KIyNkYXRhDQp0bWxzeXI8LXJlYWRfeGxzeCgiVW5pdmVyc2l0eVR3ZWV0cy54bHN4IikNCmBgYA0KDQojIFR3aXR0ZXIgYWN0aXZpdHkgb2YgRHVrZSwgVU5DLCBhbmQgTkMgU3RhdGUNCg0KW0R1a2UgVW5pdmVyc2l0eV0oaHR0cHM6Ly90d2l0dGVyLmNvbS9EdWtlVSksIFtOQyBTdGF0ZSBVbml2ZXJzaXR5XShodHRwczovL3R3aXR0ZXIuY29tL05DU3RhdGUpLCBhbmQgW1VOQy1DaGFwZWwgSGlsbF0oaHR0cHM6Ly90d2l0dGVyLmNvbS9VTkMpIGFyZSB0aHJlZSBbcmVzZWFyY2ggSSB1bml2ZXJzaXRpZXNdKGh0dHBzOi8vY2FybmVnaWVjbGFzc2lmaWNhdGlvbnMuaXUuZWR1L2NsYXNzaWZpY2F0aW9uX2Rlc2NyaXB0aW9ucy9iYXNpYy5waHApIGluIGNlbnRyYWwgTm9ydGggQ2Fyb2xpbmEuIFRvZ2V0aGVyIHRoZXkgY29tcHJpc2Ugb2YgdGhlICdSZXNlYXJjaCBUcmlhbmdsZSwnIHdoaWNoLCB0b2dldGhlciB3aXRoIHRoZSBbUmVzZWFyY2ggVHJpYW5nbGUgUGFya10oaHR0cHM6Ly93d3cucnRwLm9yZy8pIGFuZCBvdGhlciBhcmVhIHVuaXZlcnNpdGllcywgZHJpdmUgaW5ub3ZhdGlvbiBhbmQgZ3Jvd3RoIGluIHRoZSByZWdpb24uIFdoaWxlIHRoZXNlIHRocmVlIHVuaXZlcnNpdGllcyBzaGFyZSB0aGUgcmVzZWFyY2ggSSB1bml2ZXJzaXR5IGRlc2lnbmF0aW9uLCB0aGV5IGFyZSBkaXN0aW5jdCBpbiBtYW55IGFzcGVjdHMuIENhbiB3ZSBkaXNjZXJuIHRoaXMgZGlzdGluY3Rpb24gYnkgdGhlaXIgVHdpdHRlciBhY3Rpdml0eT8gV2hhdCB0b3BpY3MgZG8gdGhleSBlbmdhZ2UgaW4gdGhlIG1vc3Q/IElzIHRoZXJlIGFueSBvdmVybGFwPw0KDQpUaGlzIGFuYWx5c2lzIGlzIGludGVuZGVkIGZvciBhbnlvbmUgaW50ZXJlc3RlZCBpbiB0ZXh0IG1pbmluZyB0ZWNobmlxdWVzLCBlc3BlY2lhbGx5IGZvciBzb2NpYWwgbWVkaWEgZGF0YSBsaWtlIFR3aXR0ZXIsIHRob3NlIHdvcmtpbmcgZm9yIGluc3RpdHV0aW9ucyBvZiBoaWdoZXIgZWR1Y2F0aW9uLCBlc3BlY2lhbGx5IGNvbW11bmljYXRpb25zIHByb2Zlc3Npb25hbHMgb3Igc29jaWFsIG1lZGlhIG1hbmFnZXJzLCBvciBhbnlvbmUgd2hvIGlzIGEgQmx1ZSBEZXZpbCDwn5iILCBUYXJIZWVsIPCfkI8sIG9yIHBhcnQgb2YgdGhlIFdvbGZwYWNrIPCfkLouDQoNCioqSW4gdGhpcyB3YWxrLXRocm91Z2gsIHdlJ2xsIGV4cGxvcmU6KioNCg0KLSAgIFdoZW4gYW5kIGhvdyBvZnRlbiBkbyBlYWNoIG9mIHRoZXNlIGFjY291bnRzIHR3ZWV0DQotICAgV2hhdCBkbyB0aGVzZSBzY2hvb2xzIHR3ZWV0IGFib3V0IHRoZSBtb3N0PyBJcyB0aGVyZSBpcyBhIGRpZmZlcmVuY2UgYmV0d2VlbiBzY2hvb2xzPw0KLSAgIFdoaWNoIHdvcmRzIGFyZSBtb3JlIGxpa2VseSB0byBiZSByZXR3ZWV0ZWQgb3IgZmF2b3JpdGVkIGJldHdlZW4gdGhlc2UgYWNjb3VudHM/DQotICAgRG8gY2VydGFpbiB3b3JkcyBzaGFyZSBhIHNpbWlsYXIgc2VudGltZW50Pw0KDQpMZXQncyBmaW5kIG91dCENCg0KYGBge3J9DQppbmNsdWRlX3R3ZWV0KCJodHRwczovL3R3aXR0ZXIuY29tL0VzaGlwQXREdWtlL3N0YXR1cy8xMzg1NTY3NjYxMTYyMjEzMzc2P3M9MjAiKSANCmBgYA0KDQojIEdldHRpbmcgdGhlIERhdGENCg0KVXNpbmcgdGhlIGBydHdlZXRgIHBhY2thZ2UsIEkgcHVsbGVkIHRoZSBsYXRlc3QgMzIwMCB0d2VldHMgZnJvbSBlYWNoIHVuaXZlcnNpdHkncyBtYWluIHR3aXR0ZXIgYWNjb3VudC4NCg0KYGBge3IsIGluY2x1ZGU9VFJVRSwgZWNobyA9IFRSVUUsIGV2YWw9RkFMU0V9DQojI2dldCB0aW1lbGluZXMNCnRtbHMgPC0gZ2V0X3RpbWVsaW5lcyhjKCJkdWtldSIsICJuY3N0YXRlIiwgInVuYyIpLCBuID0gMzIwMCkNCmdsaW1wc2UodG1scykNCmBgYA0KDQpJIHRoZW4gZmlsdGVyZWQgb25seSB0byBpbmNsdWRlIHR3ZWV0cyBmcm9tIGEgb25lIHllYXIgdGltZSByYW5nZSwgd2hpY2ggcmVzdWx0ZWQgaW4gNzUyMiBvYnNlcnZhdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgYWN0aXZpdHkgYnkgYWNjb3VudDoNCg0KYGBge3IsIGluY2x1ZGU9VFJVRSwgZWNobyA9IFRSVUUsIGV2YWw9RkFMU0V9DQp0bWxzeXI8LXRtbHMlPiUNCiAgZmlsdGVyKGNyZWF0ZWRfYXQ+PSIyMDIwLTA0LTI1IikNCmBgYA0KDQpgYGB7ciwgaW5jbHVkZT1UUlVFLCBldmFsPVRSVUV9DQp0bWxzeXJjb3VudCA8LSB0bWxzeXIgJT4lDQogIGNvdW50KHNjcmVlbl9uYW1lLCBzb3J0PVRSVUUpDQp0bWxzeXJjb3VudCU+JQ0KICBrYmwoY2FwdGlvbiA9ICJOdW1iZXIgb2YgdHdlZXRzIGJldHdlZW4gQXByIDIwLUFwciAyMSBieSBhY2NvdW50IiklPiUNCiAgcm93X3NwZWMoMCwgYm9sZD1UUlVFKSU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJjb25kZW5zZWQiLCAicmVzcG9uc2l2ZSIpLCBmdWxsX3dpZHRoID0gRkFMU0UsIHBvc2l0aW9uID0gImxlZnQiKQ0KYGBgDQoNCiMgVGltZXNlcmllcw0KDQpOQyBTdGF0ZSBpcyB0aGUgbGVhZGVyIGluIG51bWJlciBvZiB0d2VldHMgZm9yIHRoaXMgcGFzdCB5ZWFyLiBMZXQncyBsb29rIGF0IHRoZSBhY3Rpdml0eSBkaXN0cmlidXRpb24gd2l0aCBhIGB0c19wbG90YCBhbmQgYGdncGxvdGAgaGlzdG9ncmFtLg0KDQpgYGB7ciwgaW5jbHVkZT1UUlVFLCBlY2hvID0gVFJVRSwgZXZhbD1UUlVFLCBmaWcuY2FwPSJUaW1lIHNlcmllcyBwbG90IG9mIFR3aXR0ZXIgQWN0aXZpdHkifQ0KIyN0c19wbG90IGJ5IHNjcmVlbiBuYW1lDQogIHRzX3Bsb3QoZ3JvdXBfYnkodG1sc3lyLCBzY3JlZW5fbmFtZSksICJtb250aHMiKQ0KYGBgDQoNCmBgYHtyLCBpbmNsdWRlPVRSVUUsIGVjaG8gPSBUUlVFLCBldmFsPVRSVUUsIGZpZy5jYXA9Ikhpc3RvZ3JhbSBvZiBUd2l0dGVyIGFjdGl2aXR5In0NCiMjIGhpc3RvZ3JhbSB3aXRoIGZhY2V0IHdyYXANCmdncGxvdCh0bWxzeXIsIGFlcyh4ID0gY3JlYXRlZF9hdCwgZmlsbCA9IHNjcmVlbl9uYW1lKSkgKw0KICAgIGdlb21faGlzdG9ncmFtKHBvc2l0aW9uID0gImlkZW50aXR5IiwgYmlucyA9IDIwLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArDQogICAgZmFjZXRfd3JhcCh+c2NyZWVuX25hbWUsIG5jb2wgPSAxKSAgDQpgYGANCg0KV2UgY2FuIHNlZSB0aGF0IGVhY2ggdW5pdmVyc2l0eSBhY2NvdW50IGhhcyBhIHN0ZWFkeSBmbG93IG9mIHR3ZWV0cyB0aGF0IGF2ZXJhZ2VzIG91dCB0byB0aGUgZm9sbG93aW5nIHBlciBtb250aCBpbiB0aGlzIHllYXIgdGltZSBwZXJpb2Q6DQoNCmBgYHtyLCBpbmNsdWRlPVRSVUUsIGVjaG89RkFMU0UsIGV2YWw9VFJVRX0NCmNvdW50d2VldHNieW1vbnRoPC10bWxzeXIgJT4lDQogIG11dGF0ZShtb250aCA9IGZvcm1hdChjcmVhdGVkX2F0LCAiJW0iKSwgeWVhciA9IGZvcm1hdChjcmVhdGVkX2F0LCAiJVkiKSkgJT4lDQogIGdyb3VwX2J5KHNjcmVlbl9uYW1lLCBtb250aCwgeWVhciklPiUNCiAgY291bnQoc2NyZWVuX25hbWUpDQoNCmNvdW50d2VldHNieW1vbnRoMjwtdG1sc3lyICU+JQ0KICBtdXRhdGUobW9udGggPSBmb3JtYXQoY3JlYXRlZF9hdCwgIiVtIiksIHllYXIgPSBmb3JtYXQoY3JlYXRlZF9hdCwgIiVZIikpICU+JQ0KICBncm91cF9ieShtb250aCwgeWVhciklPiUNCiAgY291bnQoc2NyZWVuX25hbWUpDQogIA0KYXZlcmFnZXR3dDwtY291bnR3ZWV0c2J5bW9udGgyJT4lDQogICAgZ3JvdXBfYnkoc2NyZWVuX25hbWUpJT4lDQogICAgc3VtbWFyaXNlKGF2Zz0gcm91bmQobWVhbihuKSwwKSklPiUNCiAgICBhcnJhbmdlKGRlc2MoYXZnKSkNCmBgYA0KDQpgYGB7ciwgaW5jbHVkZT1UUlVFLCBldmFsPVRSVUV9DQphdmVyYWdldHd0JT4lDQogIGtibChjYXB0aW9uID0gIkF2ZXJhZ2UgbnVtYmVyIG9mIHR3ZWV0cyBwZXIgbW9udGggYnkgYWNjb3VudCIpJT4lDQogIHJvd19zcGVjKDAsIGJvbGQ9VFJVRSklPiUNCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiLCAiY29uZGVuc2VkIiwgInJlc3BvbnNpdmUiKSwgZnVsbF93aWR0aCA9IEZBTFNFLCBwb3NpdGlvbiA9ICJsZWZ0IikNCg0KYGBgDQoNClNlZW1zIGxpa2UgTkMgU3RhdGUgaGFzIGJlZW4gYSBidXN5IGJlZSwgd2l0aCBzaWduaWZpY2FudCBhY3Rpdml0eSBpbiB0aGUgbW9udGhzIG9mIFNlcHRlbWJlciBhbmQgTWFyY2ggdGhhdCBza2V3cyBpdHMgYXZlcmFnZSB1cHdhcmQuIFdoYXQncyBnb2luZyBvbiBoZXJlPw0KDQpCeSBhbmFseXppbmcgdGhlIHdvcmQgY291bnRzIHBlciBtb250aCBmb3IgTkMgU3RhdGUsIHdlIGNhbiBzZWUgdGhhdCB0aGUgdGVybSBbXCNHaXZpbmdQYWNrXShodHRwczovL2NhbXBhaWduLm5jc3UuZWR1L2ZlYXR1cmVkLXNlcmllcy9naXZpbmctcGFjay8pIGRvbWluYXRlZCBmb3IgdGhlc2UgdHdvIG1vbnRocy4gVGhpcyBtYWtlcyBzZW5zZSBzaW5jZSB0aGlzIGlzIGEgZnVuZHJhaXNpbmcgY2FtcGFpZ24gd2hpY2ggaXMgY29uZHVjdGVkIGhlYXZpbHkgdmlhIHNvY2lhbCBtZWRpYSBhbmQgc29tZSBkb25hdGlvbnMgd2VyZSBtYXRjaGVkIGRlcGVuZGluZyBvbiBUd2l0dGVyIGFjdGl2aXR5Lg0KDQpgYGB7ciwgaW5jbHVkZT1UUlVFLCBldmFsPVRSVUV9DQpOQ1N0YXRlTWFyY2g8LXRtbHN5ciU+JQ0KICBmaWx0ZXIoc2NyZWVuX25hbWU9PSJOQ1N0YXRlIiwgY3JlYXRlZF9hdD49IjIwMjEtMDMtMDEiICYgY3JlYXRlZF9hdCA8PSIyMDIxLTAzLTMxIiklPiUNCiAgc2VsZWN0KHRleHQsIGNyZWF0ZWRfYXQpDQoNCk5DU3RhdGVNYXJjaCU+JQ0KICBmaWx0ZXIoZ3JlcGwoIiNHaXZpbmdQYWNrIiwgdGV4dCkpJT4lDQogIHNhbXBsZV9uKDIpJT4lDQogIGtibChjYXB0aW9uID0gIlNhbXBsZSBOQyBTdGF0ZSBNYXJjaCBUd2VldHMiKSU+JQ0KICByb3dfc3BlYygwLCBib2xkPVRSVUUpJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIsICJyZXNwb25zaXZlIiksIGZ1bGxfd2lkdGggPSBGQUxTRSwgcG9zaXRpb24gPSAibGVmdCIpDQoNCmluY2x1ZGVfdHdlZXQoImh0dHBzOi8vdHdpdHRlci5jb20vaGVsZW5fcGhpZmVyL3N0YXR1cy8xMzc1MDgyODg1MzgwNzI2NzkwIikNCmBgYA0KDQpgYGB7ciwgaW5jbHVkZT1UUlVFLCBldmFsPVRSVUV9DQpOQ1N0YXRlU2VwdGVtYmVyPC10bWxzeXIlPiUNCiAgZmlsdGVyKHNjcmVlbl9uYW1lPT0iTkNTdGF0ZSIsIGNyZWF0ZWRfYXQ+PSIyMDIwLTA5LTAxIiAmIGNyZWF0ZWRfYXQgPD0iMjAyMC0wOS0zMCIpJT4lDQogIHNlbGVjdCh0ZXh0LCBjcmVhdGVkX2F0KQ0KDQpOQ1N0YXRlU2VwdGVtYmVyJT4lDQogIGZpbHRlcihncmVwbCgiI0dpdmluZ1BhY2siLCB0ZXh0KSklPiUNCiAgc2FtcGxlX24oMiklPiUNCiAga2JsKGNhcHRpb24gPSAiU2FtcGxlIE5DIFN0YXRlIFNlcHRlbWJlciBUd2VldHMiKSU+JQ0KICByb3dfc3BlYygwLCBib2xkPVRSVUUpJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIsICJyZXNwb25zaXZlIiksIGZ1bGxfd2lkdGggPSBGQUxTRSwgcG9zaXRpb24gPSAibGVmdCIpDQoNCmluY2x1ZGVfdHdlZXQoImh0dHBzOi8vdHdpdHRlci5jb20vTkNTdGF0ZS9zdGF0dXMvMTMwNjA5OTI4Mzg2Mzc1NjgwMSIpDQpgYGANCg0KV2UnbGwgZG8gYW4gYWRkaXRpb25hbCB0aW1lIHNlcmllcyBsb29rIHdoZW4gd2UgZ2V0IHRvIHRoZSBzZWN0aW9uIFtDb21wYXJpbmcgV29yZCBVc2FnZV0uDQoNCiMgQ29tcGFyaW5nIFdvcmQgRnJlcXVlbmNpZXMNCg0KTm93IGxldCdzIGNvbXBhcmUgd2hpY2ggd29yZHMgd2VyZSB1c2VkIG1vc3QgZnJlcXVlbnRseSBieSBlYWNoIHVuaXZlcnNpdHkuIEluIHBhcnRpY3VsYXIsIEkgYW0gaW50ZXJlc3RlZCBpbiBzZWVpbmcgY2hhbmdlIGluIHdvcmQgZnJlcXVlbmNpZXMgb3ZlciB0aGUgeWVhciB0aW1lIHNwYW4gd2UgYXJlIGxvb2tpbmcgYXQuIEZvciB0aGlzIEkgd2lsbCBhZGFwdCB0aGUgVHdpdHRlciBjYXNlIHN0dWR5IGFuZCBjb2RlIGZyb20gW0p1bGlhIFNpbGdlXShodHRwczovL3R3aXR0ZXIuY29tL2p1bGlhc2lsZ2UpIGFuZCBbRGF2aWQgUm9iaW5zb25dKGh0dHBzOi8vdHdpdHRlci5jb20vZHJvYikncyBbVGV4dCBNaW5pbmcgd2l0aCBSXShodHRwczovL3d3dy50aWR5dGV4dG1pbmluZy5jb20vaW5kZXguaHRtbCkuDQoNCldpdGggVHdpdHRlciBkYXRhLCBzb21lIGZvcm0gb2YgY2xlYW4tdXAgaXMgdXN1YWxseSBuZWNlc3NhcnksIGVzcGVjaWFsbHkgYmVmb3JlIHRva2VuaXppbmcgdGV4dC4gV2hldGhlciB5b3UgcmVtb3ZlIGhhc2h0YWdzLCBtZW50aW9ucyAoXEApJ3MsIGVtb2ppcywgb3Igb3RoZXIgc3BlY2lhbCBjaGFyYWN0ZXJzIHdpbGwgZGVwZW5kIG9uIHlvdXIgcHVycG9zZS4gSGVyZSwgd2UnbGwgdXNlIHRoZSBzcGVjaWFsaXplZCAidHdlZXRzIiB0b2tlbml6ZXIgdG8gZGVhbCB3aXRoIFR3aXR0ZXIgdGV4dCwgd2hpY2ggcmV0YWlucyBoYXNodGFncyBhbmQgbWVudGlvbnMgb2YgdXNlcm5hbWVzIHdpdGggdGhlIFxAIHN5bWJvbC4gVGhlIGNvZGUgYmVsb3cgcmVtb3ZlcyByZXR3ZWV0cyBzbyB0aGF0IHRoZSBkYXRhIGlzIG9ubHkgb2YgdHdlZXRzIHRoZXNlIGFjY291bnRzIHdyb3RlIHRoZW1zZWx2ZXMuIFNvbWUgc3BlY2lhbCBjaGFyYWN0ZXJzIHdlcmUgcmVtb3ZlZCBhcyB3ZWxsLg0KDQpgYGB7ciBpbmNsdWRlPVRSVUUsIGVjaG8gPSBUUlVFLCBldmFsPVRSVUV9DQpyZW1vdmVfcmVnIDwtICImYW1wO3wmbHQ7fCZndDsiDQp0aWR5X3R3ZWV0cyA8LSB0bWxzeXIgJT4lIA0KICBmaWx0ZXIoIXN0cl9kZXRlY3QodGV4dCwgIl5SVCIpKSAlPiUNCiAgbXV0YXRlKHRleHQgPSBzdHJfcmVtb3ZlX2FsbCh0ZXh0LCByZW1vdmVfcmVnKSkgJT4lDQogIHVubmVzdF90b2tlbnMod29yZCwgdGV4dCwgdG9rZW4gPSAidHdlZXRzIikgJT4lDQogIGZpbHRlcighd29yZCAlaW4lIHN0b3Bfd29yZHMkd29yZCwNCiAgICAgICAgICF3b3JkICVpbiUgc3RyX3JlbW92ZV9hbGwoc3RvcF93b3JkcyR3b3JkLCAiJyIpLA0KICAgICAgICAgc3RyX2RldGVjdCh3b3JkLCAiW2Etel0iKSkNCmBgYA0KDQpOb3cgd2UgY2FuIGNhbGN1bGF0ZSB3b3JkIGZyZXF1ZW5jaWVzIGZvciBlYWNoIHVuaXZlcnNpdHkncyBhY2NvdW50Lg0KDQpgYGB7ciBpbmNsdWRlPVRSVUUsIGVjaG8gPSBUUlVFLCBldmFsPVRSVUV9DQpmcmVxdWVuY3kgPC10aWR5X3R3ZWV0cyU+JQ0KICBncm91cF9ieShzY3JlZW5fbmFtZSklPiUNCiAgY291bnQod29yZCwgc29ydD1UUlVFKSU+JQ0KICBsZWZ0X2pvaW4odGlkeV90d2VldHMgJT4lDQogICAgICAgICAgICAgIGdyb3VwX2J5KHNjcmVlbl9uYW1lKSU+JQ0KICAgICAgICAgICAgICBzdW1tYXJpc2UodG90YWw9bigpKSklPiUNCiAgbXV0YXRlKGZyZXEgPSBuL3RvdGFsKQ0KYGBgDQoNClRoZW4gdGhlIGRhdGEgaXMgcGl2b3RlZCB3aWRlciB0byBnZXQgaXQgcmVhZHkgdG8gcGxvdC4NCg0KYGBge3IgaW5jbHVkZT1UUlVFLCBlY2hvID0gVFJVRSwgZXZhbD1UUlVFfQ0KDQpmcmVxdWVuY3kgPC0gZnJlcXVlbmN5ICU+JSANCiAgc2VsZWN0KHNjcmVlbl9uYW1lLCB3b3JkLCBmcmVxKSAlPiUgDQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzY3JlZW5fbmFtZSwgdmFsdWVzX2Zyb20gPSBmcmVxKSAlPiUNCiAgYXJyYW5nZShOQ1N0YXRlLCBVTkMsIER1a2VVKQ0KYGBgDQoNClRoZXNlIHBsb3RzIGNvbXBhcmUgd29yZCB1c2FnZSBiZXR3ZWVuIER1a2UgVW5pdmVyc2l0eSwgTkMgU3RhdGUsIGFuZCBVTkMtQ2hhcGVsIEhpbGwuIFdvcmRzIG5lYXIgdGhlIGxpbmUgYXJlIHVzZWQgd2l0aCBhYm91dCBlcXVhbCBmcmVxdWVuY3kgYmV0d2VlbiB0aGUgdW5pdmVyc2l0aWVzIHdoZXJlYXMgd29yZHMgZnVydGhlciBhd2F5IGZyb20gaXQgYXJlIHVzZWQgbXVjaCBtb3JlIGJ5IHRoYXQgdW5pdmVyc2l0eSB0aGFuIHRoZSBvdGhlci4NCg0KYGBge3IsIGluY2x1ZGU9VFJVRSwgZWNobyA9IEZBTFNFLCBldmFsPVRSVUUsIGZpZy5jYXA9IldvcmQgRnJlcXVlbmN5IGJldHdlZW4gTkNTdGF0ZSBhbmQgVU5DIFR3aXR0ZXIgYWNjb3VudHMifQ0KZ2dwbG90KGZyZXF1ZW5jeSwgYWVzKE5DU3RhdGUsIFVOQykpICsNCiAgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAwLjEsIHNpemUgPSAyLjUsIHdpZHRoID0gMC4yNSwgaGVpZ2h0ID0gMC4yNSkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gd29yZCksIGNoZWNrX292ZXJsYXAgPSBUUlVFLCB2anVzdCA9IDEuNSkgKw0KICBzY2FsZV94X2xvZzEwKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KCkpICsNCiAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdCgpKSArDQogIGdlb21fYWJsaW5lKGNvbG9yID0gInJlZCIpDQpgYGANCg0KYGBge3IsIGluY2x1ZGU9VFJVRSwgZWNobyA9IEZBTFNFLCBldmFsPVRSVUUsIGZpZy5jYXA9IldvcmQgRnJlcXVlbmN5IGJldHdlZW4gVU5DIGFuZCBEdWtlVSBUd2l0dGVyIGFjY291bnRzIn0NCmdncGxvdChmcmVxdWVuY3ksIGFlcyhVTkMsIER1a2VVKSkgKw0KICBnZW9tX2ppdHRlcihhbHBoYSA9IDAuMSwgc2l6ZSA9IDIuNSwgd2lkdGggPSAwLjI1LCBoZWlnaHQgPSAwLjI1KSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSB3b3JkKSwgY2hlY2tfb3ZlcmxhcCA9IFRSVUUsIHZqdXN0ID0gMS41KSArDQogIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoKSkgKw0KICBzY2FsZV95X2xvZzEwKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KCkpICsNCiAgZ2VvbV9hYmxpbmUoY29sb3IgPSAicmVkIikgDQpgYGANCg0KYGBge3IsIGluY2x1ZGU9VFJVRSwgZWNobyA9IEZBTFNFLCBldmFsPVRSVUUsIGZpZy5jYXA9IldvcmQgRnJlcXVlbmN5IGJldHdlZW4gTkNTdGF0ZSBhbmQgRHVrZVUgVHdpdHRlciBhY2NvdW50cyJ9DQpnZ3Bsb3QoZnJlcXVlbmN5LCBhZXMoTkNTdGF0ZSwgRHVrZVUpKSArDQogIGdlb21faml0dGVyKGFscGhhID0gMC4xLCBzaXplID0gMi41LCB3aWR0aCA9IDAuMjUsIGhlaWdodCA9IDAuMjUpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHdvcmQpLCBjaGVja19vdmVybGFwID0gVFJVRSwgdmp1c3QgPSAxLjUpICsNCiAgc2NhbGVfeF9sb2cxMChsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdCgpKSArDQogIHNjYWxlX3lfbG9nMTAobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoKSkgKw0KICBnZW9tX2FibGluZShjb2xvciA9ICJyZWQiKSAgDQpgYGANCg0KWW91IGNhbiBzZWUgdGhhdCB0aGVyZSBhcmUgc29tZSBjb21tb24gc2hhcmVkIHdvcmRzIGJldHdlZW4gdGhlc2UgdW5pdmVyc2l0aWVzOg0KDQotICAgc3R1ZGVudC9zdHVkZW50c1wNCi0gICBjb3ZpZDE5XA0KLSAgIGNvbW11bml0eVwNCi0gICBjYXJlL3N1cHBvcnQNCg0KVGhlc2Ugd29yZHMgbWFrZSBzZW5zZSBzaW5jZSB0aGlzIHRpbWVmcmFtZSBvZiB0d2VldHMgY29pbmNpZGVzIHdpdGggdGhlIGNvdmlkMTkgcGFuZGVtaWMuIFVuaXZlcnNpdGllcyBtYWRlIG1hbnkgZWZmb3J0cyB0byBzdXBwb3J0IHN0dWRlbnRzIGR1cmluZyB0aGVzZSBjaGFsbGVuZ2luZyB0aW1lcy4NCg0KQWx0aG91Z2ggSSB3b24ndCBiZSBwZXJmb3JtaW5nIGEgZm9ybWFsIFt0b3BpYyBtb2RlbCBhbmFseXNpc10oaHR0cHM6Ly9zaWNzcy5pby8yMDIwL21hdGVyaWFscy9kYXkzLXRleHQtYW5hbHlzaXMvdG9waWMtbW9kZWxpbmcvcm1hcmtkb3duL1RvcGljX01vZGVsaW5nLmh0bWwpIG9mIHRoZXNlIHR3ZWV0cywgSSB0aGluayB3ZSBjYW4gc2FmZWx5IHNheSB0aGF0IGNvdmlkMTkgd2FzIGEgJ3RvcGljJyBzaGFyZWQgYW1vbmcgdGhlc2UgdW5pdmVyc2l0aWVzIHRocm91Z2hvdXQgdGhpcyB5ZWFyLiBXZSB3aWxsIGNvbWUgYmFjayB0byB0aGlzIHBhcnRpY3VsYXIgdG9waWMgd2hlbiB3ZSBkbyBvdXIgW1NlbnRpbWVudCBBbmFseXNpc10uDQoNClRvIHJvdW5kIG91dCBvdXIgbG9vayBhdCB3b3JkIGZyZXF1ZW5jaWVzLCBsZXQncyBmaW5kIHdvcmRzIHRoYXQgaGF2ZSBjaGFuZ2VkIGluIGZyZXF1ZW5jeSBhdCBhIG1vZGVyYXRlbHkgc2lnbmlmaWNhbnQgbGV2ZWwgaW4gZWFjaCBhY2NvdW50J3MgdHdlZXRzLiBUaGlzIGNhbiBoZWxwIHVzIGRldGVybWluZSAndHJlbmRpbmcnIHdvcmRzLg0KDQpgYGB7ciBpbmNsdWRlPVRSVUUsIGVjaG8gPSBGQUxTRSwgZXZhbD1UUlVFfQ0Kd29yZHNfYnlfdGltZSA8LSB0aWR5X3R3ZWV0cyAlPiUNCiAgZmlsdGVyKCFzdHJfZGV0ZWN0KHdvcmQsICJeQCIpKSAlPiUNCiAgbXV0YXRlKHRpbWVfZmxvb3IgPSBmbG9vcl9kYXRlKGNyZWF0ZWRfYXQsIHVuaXQgPSAiMSBtb250aCIpKSAlPiUNCiAgY291bnQodGltZV9mbG9vciwgc2NyZWVuX25hbWUsIHdvcmQpICU+JQ0KICBncm91cF9ieShzY3JlZW5fbmFtZSwgdGltZV9mbG9vcikgJT4lDQogIG11dGF0ZSh0aW1lX3RvdGFsID0gc3VtKG4pKSAlPiUNCiAgZ3JvdXBfYnkoc2NyZWVuX25hbWUsIHdvcmQpICU+JQ0KICBtdXRhdGUod29yZF90b3RhbCA9IHN1bShuKSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgcmVuYW1lKGNvdW50ID0gbikgJT4lDQogIGZpbHRlcih3b3JkX3RvdGFsID4gMzApDQoNCm5lc3RlZF9kYXRhIDwtIHdvcmRzX2J5X3RpbWUgJT4lDQogIG5lc3QoLXdvcmQsIC1zY3JlZW5fbmFtZSkgDQoNCm5lc3RlZF9tb2RlbHMgPC0gbmVzdGVkX2RhdGEgJT4lDQogIG11dGF0ZShtb2RlbHMgPSBtYXAoZGF0YSwgfiBnbG0oY2JpbmQoY291bnQsIHRpbWVfdG90YWwpIH4gdGltZV9mbG9vciwgLiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gImJpbm9taWFsIikpKQ0KDQpzbG9wZXMgPC0gbmVzdGVkX21vZGVscyAlPiUNCiAgbXV0YXRlKG1vZGVscyA9IG1hcChtb2RlbHMsIHRpZHkpKSAlPiUNCiAgdW5uZXN0KGNvbHMgPSBjKG1vZGVscykpICU+JQ0KICBmaWx0ZXIodGVybSA9PSAidGltZV9mbG9vciIpICU+JQ0KICBtdXRhdGUoYWRqdXN0ZWQucC52YWx1ZSA9IHAuYWRqdXN0KHAudmFsdWUpKQ0KDQp0b3Bfc2xvcGVzIDwtIHNsb3BlcyAlPiUgDQogIGZpbHRlcihhZGp1c3RlZC5wLnZhbHVlIDwgMC4wNSkNCmBgYA0KDQpgYGB7ciwgaW5jbHVkZT1UUlVFLCBlY2hvID0gRkFMU0UsIGV2YWw9VFJVRSwgZmlnLmNhcD0iVHJlbmRpbmcgd29yZHMgaW4gRHVrZVXigJlzIHR3ZWV0cyJ9DQp3b3Jkc19ieV90aW1lICU+JQ0KICBpbm5lcl9qb2luKHRvcF9zbG9wZXMsIGJ5ID0gYygid29yZCIsICJzY3JlZW5fbmFtZSIpKSAlPiUNCiAgZmlsdGVyKHNjcmVlbl9uYW1lID09ICJEdWtlVSIpICU+JQ0KICBmaWx0ZXIod29yZCAhPSAiZHVrZSIpICU+JQ0KICBnZ3Bsb3QoYWVzKHRpbWVfZmxvb3IsIGNvdW50L3RpbWVfdG90YWwsIGNvbG9yID0gd29yZCkpICsNCiAgZ2VvbV9saW5lKHNpemUgPSAxLjMpICsNCiAgbGFicyh4ID0gTlVMTCwgeSA9ICJXb3JkIGZyZXF1ZW5jeSIpDQpgYGANCg0KU2lnbmlmaWNhbnQgaGVyZSBpcyB0aGUgc2xvcGUgb2YgXCNjb3ZpZDE5IHdoaWNoIHN0YXJ0ZWQgb2ZmIHZlcnkgZnJlcXVlbnRseSBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBwYW5kZW1pYywgdHJlbmRlZCBkb3duLCBhbmQgdGhlbiBzYXcgYSBtb2RlcmF0ZSByaXNlIGluIERlY2VtYmVyLiBBbHNvIHRoZSBpbnZlcnNlIG9jY3VycmVkIHdpdGggdGhlIHRlcm0gJ3ZhY2NpbmUnIGFzIGl0IHNhdyBpdHMgcHJvbWluZW5jZSByaXNlIGluIERlY2VtYmVyIHdoZW4gbmV3cyBvZiBjb3ZpZDE5IHZhY2NpbmVzIHN0YXJ0ZWQgdG8gYmVjb21lIGF2YWlsYWJsZS4NCg0KYGBge3IsIGluY2x1ZGU9VFJVRSwgZWNobyA9IEZBTFNFLCBldmFsPVRSVUUsIGZpZy5jYXA9IlRyZW5kaW5nIHdvcmRzIGluIE5DU3RhdGXigJlzIHR3ZWV0cyJ9DQp3b3Jkc19ieV90aW1lICU+JQ0KICBpbm5lcl9qb2luKHRvcF9zbG9wZXMsIGJ5ID0gYygid29yZCIsICJzY3JlZW5fbmFtZSIpKSAlPiUNCiAgZmlsdGVyKHNjcmVlbl9uYW1lID09ICJOQ1N0YXRlIikgJT4lDQogIGdncGxvdChhZXModGltZV9mbG9vciwgY291bnQvdGltZV90b3RhbCwgY29sb3IgPSB3b3JkKSkgKw0KICBnZW9tX2xpbmUoc2l6ZSA9IDEuMykgKw0KICBsYWJzKHggPSBOVUxMLCB5ID0gIldvcmQgZnJlcXVlbmN5IikNCmBgYA0KDQpUaGVyZSdzIGFsb3QgZ29pbmcgb24gaW4gdGhpcyBncmFwaCwgYnV0IFwjZ2l2aW5ncGFjayBmZWF0dXJlcyBwcm9taW5lbnRseSwgc3RhcnRpbmcgaGlnaCBpbiBTZXB0ZW1iZXIsIGZhbGxpbmcgZG93biBwcmVjaXBpdG91c2x5IHVudGlsIE1hcmNoIHdoZW4gaXQgcGlja3MgYmFjayB1cCBhY2NvcmRpbmdseSB3aXRoIG91ciBkaXNjb3Zlcnkgb2YgdGhlaXIgZnVuZHJhaXNpbmcgY2FtcGFpZ25zIHRob3NlIHR3byBtb250aHMuDQoNCmBgYHtyLCBpbmNsdWRlPVRSVUUsIGVjaG8gPSBGQUxTRSwgZXZhbD1UUlVFLCBmaWcuY2FwPSJUcmVuZGluZyB3b3JkcyBpbiBVTkPigJlzIHR3ZWV0cyJ9DQp3b3Jkc19ieV90aW1lICU+JQ0KICBpbm5lcl9qb2luKHRvcF9zbG9wZXMsIGJ5ID0gYygid29yZCIsICJzY3JlZW5fbmFtZSIpKSAlPiUNCiAgZmlsdGVyKHNjcmVlbl9uYW1lID09ICJVTkMiKSAlPiUNCiAgZ2dwbG90KGFlcyh0aW1lX2Zsb29yLCBjb3VudC90aW1lX3RvdGFsLCBjb2xvciA9IHdvcmQpKSArDQogIGdlb21fbGluZShzaXplID0gMS4zKSArDQogIGxhYnMoeCA9IE5VTEwsIHkgPSAiV29yZCBmcmVxdWVuY3kiKQ0KYGBgDQoNCkFnYWluLCBhbG90IGdvaW5nIG9uLCBidXQgb2Ygbm90ZSwgYW5kIG1ha2VzIHNlbnNlLCBpcyB0aGUgdGVybS9oYXNodGFnIFwjdW5jZ3JhZCB3aGljaCBzdGFydGVkIG9mZiBoaWdoIE1heSAyMDIwLCBjb2luY2lkaW5nIHdpdGggU3ByaW5nIGdyYWR1YXRpb24gYW5kIHRoZW4gZmFsbGluZyBvZmYgdW50aWwgRGVjZW1iZXIgKEZhbGwgZ3JhZHVhdGlvbikuIEZvbGxvd2luZyB0aGlzIHRyZW5kLCBpdCB3b3VsZCBoYXZlIHBpY2tlZCBiYWNrIHVwIGFnYWluIE1heSAyMDIxLiBUaGUgdGVybSAnRmFsbCcgcmlzaW5nIGluIEF1Z3VzdCBjb2luY2lkZXMgd2l0aCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBGYWxsIHRlcm0sIGFuZCAndGVzdGluZycgY291bGQgYmUgYmVjYXVzZSBvZiBjaGFuZ2VzIGluIHRlc3RpbmcgcHJvdG9jb2xzIGZvciBjb3ZpZDE5Lg0KDQojIENvbXBhcmluZyBXb3JkIFVzYWdlDQoNCk5vdyBsZXQncyBzZWUgd2hhdCB3b3JkcyB3ZXJlIGJlaW5nIHR3ZWV0ZWQgYWJvdXQgdGhlIG1vc3QuIEknbGwgZXhwbG9yZSB0aGlzIGluIHR3byB3YXlzOg0KDQoxLiAgU2ltcGxlIHdvcmQgY291bnRzIHRvIGFuYWx5emUgdXNhZ2VcDQoyLiAgVGVybSBmcmVxdWVuY3kvaW52ZXJzZSBkb2N1bWVudCBmcmVxdWVuY3kgKHRmLWlkZikgdmFsdWVzIHRvIGFuYWx5emUgd2hpY2ggd29yZHMgYXJlIG1vcmUgbGlrZWx5IHRvIGNvbWUgZnJvbSBvbmUgYWNjb3VudCB2ZXJzdXMgdGhlIG90aGVyDQoNCkZpcnN0LCBsZXQncyBkbyBhIHNpbXBsZSB3b3JkIGNvdW50IG9mIHRoZSB0b3AgdHdlbnR5IHdvcmRzIHRoYXQgYXJlIGluIHRoZSBjb3JwdXMuDQoNCmBgYHtyLCBpbmNsdWRlPVRSVUUsIGVjaG8gPSBGQUxTRSwgZXZhbD1UUlVFLCBmaWcuY2FwPSJXb3JkIENvdW50cyBmb3IgRHVrZSwgVU5DLCBhbmQgTkMgU3RhdGUifQ0KDQp0d2VldHNfY291bnQgPC1jb3VudCh0aWR5X3R3ZWV0cywgd29yZCwgc29ydCA9IFRSVUUpDQoNCnR3ZWV0c19jb3VudCU+JQ0KICB0b3BfbigyMCklPiUNCiAgbXV0YXRlKHdvcmQgPSByZW9yZGVyKHdvcmQsIG4pKSU+JQ0KICBnZ3Bsb3QoYWVzKG4sIHdvcmQsIGZpbGw9bikpKw0KICBnZW9tX2NvbCgpDQoNCmBgYA0KDQpOZXh0LCBsZXQncyB1c2UgYHdvcmRjbG91ZGAgdG8gaGVscCB1cyB2aXN1YWxpemUgdGhlc2UgdGVybXMgcGVyIHVuaXZlcnNpdHkuXA0KIVtdKGh0dHBzOi8vbWVkaWEuZ2lwaHkuY29tL21lZGlhLzNvN1RLVVpmSktVS3VTV1RaZS9naXBoeS5naWYpDQoNCkhlcmUncyBEdWtlLCB3aG9zZSBuYW1lIGZlYXR1cmVzIHByb21pbmVudGx5IGluIHRoZSB2aXN1YWxpemF0aW9uIGFsb25nIHdpdGggJ3N0dWRlbnRzLCcgJ2NvdmlkMTksJyAncGFuZGVtaWMsJyAnZmFjdWx0eSwnICdyZXNlYXJjaCwnICdoZWFsdGgsJyBhbW9uZyBtYW55IG90aGVyIHRlcm1zLg0KDQpgYGB7ciwgaW5jbHVkZT1UUlVFLCBlY2hvID0gRkFMU0UsIGV2YWw9VFJVRSwgZmlnLmNhcD0iV29yZCBDbG91ZCBEdWtlIFVuaXZlcnNpdHkncyBtb3N0IHR3ZWV0ZWQgdGVybXMifQ0KIER1a2V0d2VldHNfY291bnQgPC10aWR5X3R3ZWV0cyU+JQ0KICBmaWx0ZXIoc2NyZWVuX25hbWU9PSJEdWtlVSIpJT4lDQogIGNvdW50KHdvcmQsIHNvcnQ9VFJVRSkNCg0Kd29yZGNsb3VkMihEdWtldHdlZXRzX2NvdW50LCBzaXplPTEuNiwgY29sb3I9cmVwX2xlbihjKCJibHVlIiwgImdyZXkiKSwgbnJvdyhEdWtldHdlZXRzX2NvdW50KSkpDQpgYGANCg0KTm93IGhlcmUncyBOQyBTdGF0ZSwgd2hlcmUgdGhlaXIgbW90dG8gJ3RoaW5rIGFuZCBkbycgZmVhdHVyZXMgcHJvbWluZW50bHkgYWxvbmcgd2l0aCB0aGUgd29yZCAnc3R1ZGVudHMuJyBBbHNvIG1hbnkgb2YgdGhlIHVuaXZlcnNpdHkncyBpbmRpdmlkdWFsIGNvbGxlZ2VzJyBvciBkZXBhcnRtZW50cycgdHdpdHRlciBzY3JlZW4gbmFtZXMgYXJlIGRpc3BsYXllZCBoZXJlLiBZb3UgY2FuIGFsc28gc2VlIHRoZSB3b3JkcyAnZ2lmdCwnICdzdXBwb3J0LCcgJ3NjaG9sYXJzaGlwLCcgJ2dpdmluZywnICdoZWxwaW5nLCcgJ2Rvbm9ycywnIGFuZCBvZiBjb3Vyc2UsICd3b2xmcGFjaycgZmVhdHVyZWQgaGVyZS4NCg0KYGBge3IsIGluY2x1ZGU9VFJVRSwgZWNobyA9IEZBTFNFLCBldmFsPUZBTFNFLCBmaWcuY2FwPSJXb3JkIENsb3VkIE5DIFN0YXRlIFVuaXZlcnNpdHkncyBtb3N0IHR3ZWV0ZWQgdGVybXMifQ0Kd2Vic2hvdDo6aW5zdGFsbF9waGFudG9tanMoKQ0KDQogTkNTdGF0ZXR3ZWV0c19jb3VudCA8LXRpZHlfdHdlZXRzJT4lDQogIGZpbHRlcihzY3JlZW5fbmFtZT09Ik5DU3RhdGUiKSU+JQ0KICBjb3VudCh3b3JkLCBzb3J0PVRSVUUpDQoNCmh3PXdvcmRjbG91ZDIoTkNTdGF0ZXR3ZWV0c19jb3VudCwgc2l6ZT0xLjYsIGNvbG9yPXJlcF9sZW4oYygicmVkIiwgImJsYWNrIiksIG5yb3coTkNTdGF0ZXR3ZWV0c19jb3VudCkpKQ0KDQpzYXZlV2lkZ2V0KGh3LCAiMS5odG1sIiwgc2VsZmNvbnRhaW5lZCA9IEYpDQp3ZWJzaG90Ojp3ZWJzaG90KCIxLmh0bWwiLCAiMS5wbmciLCB2d2lkdGggPSA3MDAsIHZoZWlnaHQgPSA1MDAsIGRlbGF5ID0gMTApDQpgYGANCg0KIVtOQyBTdGF0ZSBXb3JkY2xvdWRdKE5DJTIwU3RhdGUlMjB3b3JkY2xvdWQlMjBScGxvdC5wbmcpDQoNCkFuZCBmaW5hbGx5LCBoZXJlJ3MgVU5DIHdpdGggJ3RhcicgJ2hlZWxzJyBmcm9udCBhbmQgY2VudGVyLCB3aGljaCBpcyB3aGF0IHRoZXkgY2FsbCB0aGVtc2VsdmVzLCBhbG9uZyB3aXRoIHRoZWlyIGhhc2h0YWcgJ1wjdW5jLCcgJ3N0dWRlbnRzLCcgJ2NvdmlkMTksJyAncGFuZGVtaWMsJyBhbmQgJ2NvbW11bml0eScgYmVpbmcgZmVhdHVyZWQuDQoNCmBgYHtyLCBpbmNsdWRlPVRSVUUsIGVjaG8gPSBGQUxTRSwgZXZhbD1GQUxTRSwgZmlnLmNhcD0iV29yZCBDbG91ZCBVTkMtQ2hhcGVsIEhpbGwgbW9zdCB0d2VldGVkIHRlcm1zIn0NClVOQ3R3ZWV0c19jb3VudCA8LXRpZHlfdHdlZXRzJT4lDQogIGZpbHRlcihzY3JlZW5fbmFtZT09IlVOQyIpJT4lDQogIGNvdW50KHdvcmQsIHNvcnQ9VFJVRSkNCg0KaHcyPXdvcmRjbG91ZDIoVU5DdHdlZXRzX2NvdW50LCBzaXplPTEuNiwgY29sb3I9cmVwX2xlbihjKCJjeWFuIiwgImdyZXkiKSwgbnJvdyhVTkN0d2VldHNfY291bnQpKSkNCg0Kc2F2ZVdpZGdldChodzIsICIyLmh0bWwiLCBzZWxmY29udGFpbmVkID0gRikNCndlYnNob3Q6OndlYnNob3QoIjIuaHRtbCIsICIyLnBuZyIsIHZ3aWR0aCA9NzAwLCB2aGVpZ2h0ID01MDAsIGRlbGF5ID0gMTApDQpgYGANCg0KIVtVTkMgV29yZENsb3VkXShVTkMlMjB3b3JkJTIwY2xvdWQlMjBScGxvdC5wbmcpDQoNCklmIHdlIHdhbnQgdG8gdGFrZSB0aGlzIGFuYWx5c2lzIGZ1cnRoZXIsIHdlIGNhbiBhZGQgYGdnYW5pbWF0ZWAgdG8gb3VyIHBsb3QgdG8gdmlldyBtb3N0IGZyZXF1ZW50bHkgdHdlZXRlZCB3b3JkcyBvdmVyIHRpbWUuDQoNCmBgYHtyLCBpbmNsdWRlPVRSVUUsIGVjaG8gPSBUUlVFLCBldmFsPVRSVUV9DQp3b3Jkc19ieV90aW1lIDwtIHRpZHlfdHdlZXRzICU+JQ0KICBmaWx0ZXIoIXN0cl9kZXRlY3Qod29yZCwgIl5AIikpICU+JQ0KICBtdXRhdGUodGltZV9mbG9vciA9IGZsb29yX2RhdGUoY3JlYXRlZF9hdCwgdW5pdCA9ICIxIG1vbnRoIikpICU+JQ0KICBjb3VudCh0aW1lX2Zsb29yLCBzY3JlZW5fbmFtZSwgd29yZCkgJT4lDQogIGdyb3VwX2J5KHNjcmVlbl9uYW1lLCB0aW1lX2Zsb29yKSAlPiUNCiAgbXV0YXRlKHRpbWVfdG90YWwgPSBzdW0obikpICU+JQ0KICBncm91cF9ieShzY3JlZW5fbmFtZSwgd29yZCkgJT4lDQogIG11dGF0ZSh3b3JkX3RvdGFsID0gc3VtKG4pKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICByZW5hbWUoY291bnQgPSBuKSAlPiUNCiAgZmlsdGVyKHdvcmRfdG90YWwgPiAzMCkNCmBgYA0KDQpgYGB7ciwgaW5jbHVkZT1UUlVFLCBlY2hvID0gVFJVRSwgZXZhbD1GQUxTRSwgZmlnLmNhcD0iRXhhbXBsZSBvZiBnZ2FuaW1hdGUgdGltZSBzZXJpZXMifQ0KRHVrZXRpbWUgPC13b3Jkc19ieV90aW1lJT4lDQogIGZpbHRlcihzY3JlZW5fbmFtZT09IkR1a2VVIikNCg0KZ2cgPC0gRHVrZXRpbWUgJT4lDQogIGdncGxvdChhZXMobGFiZWwgPSB3b3JkLCBzaXplPWNvdW50KSkgKw0KICBnZW9tX3RleHRfd29yZGNsb3VkKGFyZWFfY29yciA9IFRSVUUpICsNCiAgc2NhbGVfc2l6ZV9hcmVhKG1heF9zaXplID0gMjApKw0KICB0aGVtZV9taW5pbWFsKCkNCmdnK3RyYW5zaXRpb25fdGltZSh0aW1lX2Zsb29yKSArDQogIGxhYnModGl0bGUgPSAiQER1a2VVJ3MgbW9zdCB0d2VldGVkIHdvcmRzOiB7ZnJhbWVfdGltZX0iKQ0KYGBgDQoNCiFbXShnZ19EdWtlLmdpZiAiRHVrZSBVbml2ZXJzaXR5IFdvcmQgQ2xvdWQgVGltZSBTZXJpZXMiKQ0KDQohW10oZ2dfTkNTdGF0ZS5naWYgIk5DIFN0YXRlIFdvcmxkIENsb3VkIFRpbWUgU2VyaWVzIikNCg0KIVtdKGdnX1VOQy5naWYgIlVOQyBXb3JsZGNsb3VkIFRpbWUgU2VyaWVzIikNCg0KV2l0aCB0aGUgaGVscCBvZiB3b3JsZGNsb3VkLCB0aGVzZSB0aW1lIHNlcmllcyBwbG90cyBnaXZlIHVzIGEgZ29vZCBwaWN0dXJlIG9mIHdoYXQgdGVybXMgb2NjdXJyZWQgbW9zdCBmcmVxdWVudGx5IHRocm91Z2hvdXQgdGhlIHllYXIuIEFnYWluLCBjb3ZpZDE5IGFuZCB3b3JkcyBoYXZpbmcgdG8gZG8gd2l0aCB0aGUgcGFuZGVtaWMgYXJlIGNvbW1vbiBhbW9uZyBhbGwgdGhlIHVuaXZlcnNpdGllcyB0aHJvdWdob3V0IHRoZSB5ZWFyIGluIHRoZXNlIHZpc3VhbGl6YXRpb25zLg0KDQojIyBUZXJtLWZyZXF1ZW5jeSwgaW52ZXJzZSBkb2N1bWVudCBmcmVxdWVuY3kNCg0KU28sIHdlJ3ZlIHNlZW4gYWxvdCBvZiBvdmVybGFwIG9mIHRlcm1zIGJldHdlZW4gdGhlc2UgdW5pdmVyc2l0aWVzLiBXaGF0IGlzIHVuaXF1ZSBhYm91dCB3aGF0IHRoZXkgdHdlZXQ/IExldCdzIGNhbGN1bGF0ZSB0aGUgdGYtaWRmIHZhbHVlcyB0byBmaW5kIG91dDoNCg0KYGBge3IsIGluY2x1ZGU9VFJVRSwgZWNobyA9IEZBTFNFLCBldmFsPVRSVUUsIGZpZy5jYXA9IlVuaXF1ZSB3b3JkcyB1c2VkIGJ5IGVhY2ggdW5pdmVyc2l0eSJ9DQogIA0KdG1sc3lyX3dvcmRzIDwtIHRtbHN5ciAlPiUNCnVubmVzdF90b2tlbnMod29yZCwgdGV4dCkgJT4lDQpjb3VudChzY3JlZW5fbmFtZSwgd29yZCwgc29ydCA9IFRSVUUpDQoNCnRvdGFsX3dvcmRzIDwtdG1sc3lyX3dvcmRzJT4lDQogIGdyb3VwX2J5KHNjcmVlbl9uYW1lKSAlPiUNCiAgc3VtbWFyaXNlKHRvdGFsID0gc3VtKG4pKQ0KDQp0bWxzeXJfdG90YWxzIDwtIGxlZnRfam9pbih0bWxzeXJfd29yZHMsIHRvdGFsX3dvcmRzKQ0KDQp0bWxzeXJfdGZfaWRmIDwtIHRtbHN5cl90b3RhbHMgJT4lDQogIGJpbmRfdGZfaWRmKHdvcmQsIHNjcmVlbl9uYW1lLCBuKQ0KICANCiAgdG1sc3lyX3RmX2lkZiAlPiUNCiAgZ3JvdXBfYnkoc2NyZWVuX25hbWUpICU+JQ0KICBzbGljZV9tYXgodGZfaWRmLCBuID0gMTApICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZShzY3JlZW5fbmFtZT1hcy5mYWN0b3Ioc2NyZWVuX25hbWUpLA0KICAgICAgICAgd29yZD1yZW9yZGVyX3dpdGhpbih3b3JkLCB0Zl9pZGYsIHNjcmVlbl9uYW1lKSkgJT4lDQogIGdncGxvdChhZXMod29yZCwgdGZfaWRmLCBmaWxsID0gc2NyZWVuX25hbWUpKSArDQogIGdlb21fY29sKHNob3cubGVnZW5kID0gRkFMU0UpICsNCiAgZmFjZXRfd3JhcCh+c2NyZWVuX25hbWUsIG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZSIpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgc2NhbGVfeF9yZW9yZGVyZWQoKSArDQogIGxhYnModGl0bGUgPSAiVG9wIDEwIFdvcmRzIFVuaXF1ZSB0byBFYWNoIFVuaXZlcnNpdHkncyBUd2VldHMgQXByIDIwMjAtIEFwciAyMDIxIiwgeCA9ICJ0Zi1pZGYgdmFsdWUiLCB5ID0gTlVMTCkNCmBgYA0KDQpZb3UgY2FuIHNlZSB0aGF0IGZvciBEdWtlLCB0aGV5IG1vc3QgdW5pcXVlbHkgdHdlZXQgYWJvdXQgJ2R1a2VoZWFsdGgsJyAnZW5naW5lZXJpbmcsJyB0aGUgYmx1ZSAnZGV2aWxzLCcgdGhlaXIgbWFzY290LCB0aGUgbWVkaWNhbCBzY2hvb2wgYW5kIG90aGVyIGRlcGFydG1lbnRzIHRoYXQgZmVhdHVyZSBwcm9taW5lbnRseSBpbiB0aGVpciByZXNlYXJjaCBvdXRwdXQuICdEdWtlc3R1ZGVudHMnIGFsc28gcm91bmRzIG91dCB0aGUgdG9wIDEwIHdvcmRzIHVuaXF1ZSB0byBEdWtlLg0KDQpGb3IgTkMgU3RhdGUsIGFzIHdlIGhhdmUgc2VlbiwgJ1wjZ2l2aW5ncGFjaycgaXMgbW9zdCB1bmlxdWVseSBpZGVudGlmaWVkIHdpdGggdGhlbSBhcyB0aGVpciBiaWcgZnVuZHJhaXNpbmcgZXZlbnQgdGhhdCBpcyBzbyBhY3RpdmUgb24gVHdpdHRlci9zb2NpYWwgbWVkaWEuICdXb2xmcGFjaywnIHRoZWlyIG1hc2NvdCwgJ3RoaW5rYW5kZG8sJyB0aGVpciBtb3R0bywgYW5kIG90aGVyIE5DIFN0YXRlIGRlcGFydG1lbnRzIHJvdW5kIG91dCB0aGUgbGlzdC4NCg0KRm9yIFVOQywgdGhlaXIgbW9uaWtlciwgdGhlICd0YXInICdoZWVscywnIGFuZCB0aGVpciBoYXNodGFnICdcI2dkdGJhdGgnIChvciBnb29kIGRheSB0byBiZSBhIFRhciBIZWVsKSBmZWF0dXJlcyBwcm9taW5lbnRseS4NCg0KIyBSZXR3ZWV0cyBhbmQgRmF2b3JpdGVzDQoNCk5vdyBsZXQncyBzZWUgaG93IHRoZXNlIGFjY291bnRzIGludGVyYWN0IHdpdGggZWFjaCBvdGhlciB2aWEgbWVudGlvbnMgYW5kIGFsc28gbG9vayBhdCB0aGVpciByZXR3ZWV0IGFuZCBmYXZvcml0ZXMgYWN0aXZpdHkuIEluaXRpYWxseSwgSSB0aG91Z2h0IGJlY2F1c2Ugb2YgdGhlaXIgc2hhcmVkIGNoYXJhY3RlciBhcyByZXNlYXJjaCB1bml2ZXJzaXRpZXMgYW5kIHNvbWUgb2YgdGhlIHN5bmVyZ2llcyBib3JuZSBmcm9tIHRoYXQsIHRoZXkgd291bGQgYmUgcHJldHR5IHRpZ2h0IFR3aXR0ZXIgcGFscy4gSXQgdHVybnMgb3V0LCBub3Qgc28gbXVjaC4NCg0KRmlyc3QgbGV0J3Mgc2VlIHdob3NlIGFjY291bnQgaGFzIHRoZSBtb3N0IHJldHdlZXRzOg0KDQpgYGB7ciBpbmNsdWRlPVRSVUUsIGVjaG8gPSBGQUxTRSwgZXZhbD1UUlVFfQ0KDQp0aWR5X3R3ZWV0c3JlZmF2IDwtIHRtbHN5ciAlPiUgDQogIGZpbHRlcighc3RyX2RldGVjdCh0ZXh0LCAiXihSVHxAKSIpKSAlPiUNCiAgbXV0YXRlKHRleHQgPSBzdHJfcmVtb3ZlX2FsbCh0ZXh0LCByZW1vdmVfcmVnKSkgJT4lDQogIHVubmVzdF90b2tlbnMod29yZCwgdGV4dCwgdG9rZW4gPSAidHdlZXRzIiwgc3RyaXBfdXJsID0gVFJVRSkgJT4lDQogIGZpbHRlcighd29yZCAlaW4lIHN0b3Bfd29yZHMkd29yZCwNCiAgICAgICAgICF3b3JkICVpbiUgc3RyX3JlbW92ZV9hbGwoc3RvcF93b3JkcyR3b3JkLCAiJyIpKQ0KDQp0b3RhbHNyZWZhdiA8LSB0aWR5X3R3ZWV0c3JlZmF2ICU+JSANCiAgZ3JvdXBfYnkoc2NyZWVuX25hbWUsIHN0YXR1c19pZCkgJT4lIA0KICBzdW1tYXJpc2UocnRzID0gZmlyc3QocmV0d2VldF9jb3VudCkpICU+JSANCiAgZ3JvdXBfYnkoc2NyZWVuX25hbWUpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX3J0cyA9IHN1bShydHMpKQ0KYGBgDQoNCmBgYHtyIGluY2x1ZGU9VFJVRSwgZWNobyA9IEZBTFNFLCBldmFsPVRSVUV9DQp0b3RhbHNyZWZhdiU+JQ0KICBhcnJhbmdlKGRlc2ModG90YWxfcnRzKSklPiUNCiAga2JsKGNhcHRpb24gPSAiVG90YWwgTnVtYmVyIG9mIHJldHdlZXRzIGJ5IGFjY291bnQiKSU+JQ0KICByb3dfc3BlYygwLCBib2xkPVRSVUUpJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIsICJyZXNwb25zaXZlIiksIGZ1bGxfd2lkdGggPSBGQUxTRSwgcG9zaXRpb24gPSAibGVmdCIpDQpgYGANCg0KYGBge3IsIGluY2x1ZGU9RkFMU0UsIGVjaG8gPSBGQUxTRSwgZXZhbD1UUlVFfQ0Kd29yZF9ieV9ydHMgPC0gdGlkeV90d2VldHNyZWZhdiAlPiUgDQogIGdyb3VwX2J5KHN0YXR1c19pZCwgd29yZCwgc2NyZWVuX25hbWUpICU+JSANCiAgc3VtbWFyaXNlKHJ0cyA9IGZpcnN0KHJldHdlZXRfY291bnQpKSAlPiUgDQogIGdyb3VwX2J5KHNjcmVlbl9uYW1lLCB3b3JkKSAlPiUgDQogIHN1bW1hcmlzZShyZXR3ZWV0X2NvdW50ID0gbWVkaWFuKHJ0cyksIHVzZXMgPSBuKCkpICU+JQ0KICBsZWZ0X2pvaW4odG90YWxzcmVmYXYpICU+JQ0KICBmaWx0ZXIocmV0d2VldF9jb3VudCAhPSAwKSAlPiUNCiAgdW5ncm91cCgpDQoNCndvcmRfYnlfcnRzJT4lDQogIGZpbHRlcih1c2VzID49IDUpICU+JQ0KICBhcnJhbmdlKGRlc2MocmV0d2VldF9jb3VudCkpDQpgYGANCg0KV2hhdCB3b3JkcyB3ZXJlIGluIHRoZSB0d2VldHMgdGhhdCB3ZXJlIHRoZSBtb3N0IHJldHdlZXRlZD8NCg0KYGBge3IsIGluY2x1ZGU9VFJVRSwgZWNobyA9IEZBTFNFLCBldmFsPVRSVUV9DQojIyBoaWdoZXN0IG1lZGlhbiByZXR3ZWV0DQogIHdvcmRfYnlfcnRzICU+JQ0KICBmaWx0ZXIodXNlcyA+PSA1KSAlPiUNCiAgZ3JvdXBfYnkoc2NyZWVuX25hbWUpICU+JQ0KICBzbGljZV9tYXgocmV0d2VldF9jb3VudCwgbiA9IDEwKSAlPiUgDQogIGFycmFuZ2UocmV0d2VldF9jb3VudCkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKHdvcmQgPSBmYWN0b3Iod29yZCwgdW5pcXVlKHdvcmQpKSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgZ2dwbG90KGFlcyh3b3JkLCByZXR3ZWV0X2NvdW50LCBmaWxsID0gc2NyZWVuX25hbWUpKSArDQogIGdlb21fY29sKHNob3cubGVnZW5kID0gRkFMU0UpICsNCiAgZmFjZXRfd3JhcCh+IHNjcmVlbl9uYW1lLCBzY2FsZXMgPSAiZnJlZSIsIG5jb2wgPSAzKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnMoeCA9IE5VTEwsIA0KICAgICAgIHkgPSAiTWVkaWFuICMgb2YgcmV0d2VldHMgZm9yIHR3ZWV0cyBjb250YWluaW5nIGVhY2ggd29yZCIpDQpgYGANCg0KSXQgc2VlbXMgbGlrZSByZXR3ZWV0cyBhcmUgZG9taW5hdGVkIGJ5IHRlcm1zIHJlbGF0ZWQgdG8gc3BvcnRzIGFjdGl2aXR5LiBBbHNvIER1a2UncyByZXR3ZWV0IG9mIENvYWNoIEsncyBzcGVlY2ggYWJvdXQgXCNibGFja2xpdmVzbWF0dGVyIGdhcm5lcmVkIG1hbnkgcmV0d2VldHMuIOKcivCfj78NCg0KYGBge3J9DQppbmNsdWRlX3R3ZWV0KCJodHRwczovL3R3aXR0ZXIuY29tL0R1a2VNQkIvc3RhdHVzLzEyOTkwNzUyMzM0MTI5MTExMDU/cz0yMCIpDQpgYGANCg0KTm93IGxldCdzIGRvIGZhdm9yaXRlczoNCg0KYGBge3IgaW5jbHVkZT1UUlVFLCBlY2hvID0gRkFMU0UsIGV2YWw9VFJVRSwgZmlnLmNhcD0iTWVkaWFuIEZhdm9yaXRlcyJ9DQojIyBmYXZvcml0ZXMNCnRvdGFsc3JlZmF2MiA8LSB0aWR5X3R3ZWV0cyAlPiUgDQogIGdyb3VwX2J5KHNjcmVlbl9uYW1lLCBzdGF0dXNfaWQpICU+JSANCiAgc3VtbWFyaXNlKGZhdnMgPSBmaXJzdChmYXZvcml0ZV9jb3VudCkpICU+JSANCiAgZ3JvdXBfYnkoc2NyZWVuX25hbWUpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2ZhdnMgPSBzdW0oZmF2cykpDQoNCndvcmRfYnlfZmF2cyA8LSB0aWR5X3R3ZWV0cyAlPiUgDQogIGdyb3VwX2J5KHN0YXR1c19pZCwgd29yZCwgc2NyZWVuX25hbWUpICU+JSANCiAgc3VtbWFyaXNlKGZhdnMgPSBmaXJzdChmYXZvcml0ZV9jb3VudCkpICU+JSANCiAgZ3JvdXBfYnkoc2NyZWVuX25hbWUsIHdvcmQpICU+JSANCiAgc3VtbWFyaXNlKGZhdm9yaXRlX2NvdW50ID0gbWVkaWFuKGZhdnMpLCB1c2VzID0gbigpKSAlPiUNCiAgbGVmdF9qb2luKHRvdGFsc3JlZmF2MikgJT4lDQogIGZpbHRlcihmYXZvcml0ZV9jb3VudCAhPSAwKSAlPiUNCiAgdW5ncm91cCgpDQoNCiAgd29yZF9ieV9mYXZzICU+JQ0KICBmaWx0ZXIodXNlcyA+PSA1KSAlPiUNCiAgZ3JvdXBfYnkoc2NyZWVuX25hbWUpICU+JQ0KICBzbGljZV9tYXgoZmF2b3JpdGVfY291bnQsIG4gPSAxMCkgJT4lIA0KICBhcnJhbmdlKGZhdm9yaXRlX2NvdW50KSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUod29yZCA9IGZhY3Rvcih3b3JkLCB1bmlxdWUod29yZCkpKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBnZ3Bsb3QoYWVzKHdvcmQsIGZhdm9yaXRlX2NvdW50LCBmaWxsID0gc2NyZWVuX25hbWUpKSArDQogIGdlb21fY29sKHNob3cubGVnZW5kID0gRkFMU0UpICsNCiAgZmFjZXRfd3JhcCh+IHNjcmVlbl9uYW1lLCBzY2FsZXMgPSAiZnJlZSIsIG5jb2wgPSAzKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnMoeCA9IE5VTEwsIA0KICAgICAgIHkgPSAiTWVkaWFuICMgb2YgZmF2b3JpdGVzIGZvciB0d2VldHMgY29udGFpbmluZyBlYWNoIHdvcmQiKQ0KYGBgDQoNCmBgYHtyLCBpbmNsdWRlPUZBTFNFLCBlY2hvID0gRkFMU0UsIGV2YWw9VFJVRX0NCiMjcmVtb3ZlIHN0b3Agd29yZHMgZnJvbSB0b3RhbHMNCg0KdG1sc3lyX25vc3RvcDwtdG1sc3lyX3RvdGFscyU+JQ0KICBhbnRpX2pvaW4oc3RvcF93b3JkcyklPiUNCiAgZmlsdGVyKHdvcmQgIT0idC5jbyIpJT4lDQogIGZpbHRlcih3b3JkICE9ICJodHRwcyIpDQpgYGANCg0KSW50ZXJlc3RpbmcgaGVyZSBpcyB0aGUgdGVybSAncmVtZGVzaXZpcicsIHdoaWNoIGlzIGFuIFthbnRpLXZpcmFsIGRydWddKGh0dHBzOi8vc3BoLnVuYy5lZHUvc3BoLW5ld3MvcmVtZGVzaXZpci1kZXZlbG9wZWQtYXQtdW5jLWNoYXBlbC1oaWxsLXByb3Zlcy1lZmZlY3RpdmUtYWdhaW5zdC1jb3ZpZC0xOS1pbi1uaWFpZC1odW1hbi1jbGluaWNhbC10cmlhbHMvKSBkZXZlbG9wZWQgdGhyb3VnaCBhIFVOQy1DaGFwZWwgSGlsbCBwYXJ0bmVyc2hpcCwgd2hpY2ggd2FzIHVzZWQgaW4gdGhlIGZpZ2h0IGFnYWluc3QgdGhlIGNvdmlkMTkgdmlydXMuIE90aGVyd2lzZSwgdGhlIGZhdm9yaXRlZCB0ZXJtcyBoYWQgYWxvdCB0byBkbyBhYm91dCBjYW1wdXMgbGlmZSwgc3BvcnRzLCBwbGFjZXMgb24gY2FtcHVzLCBhbmQgbXkgcGVyc29uYWwgZmF2b3JpdGUsIFtEdWtlIEdhcmRlbnNdKGh0dHBzOi8vZ2FyZGVucy5kdWtlLmVkdS8pLg0KDQpIb3cgYWJvdXQgdG9wIG1lbnRpb25zIGZvciBlYWNoIHVuaXZlcnNpdHk/IEFzIHlvdSBjYW4gc2VlLCBpdCdzIHZlcnkgdW5pdmVyc2l0eS1jZW50cmljLiBNb3N0IG1lbnRpb25zIGFyZSB0byBvdGhlciBkZXBhcnRtZW50cy91bml0cyB3aXRoaW4gdGhlIHNhbWUgdW5pdmVyc2l0eS4gVGhlIHRvcCBtZW50aW9uIGZvciBhbGwgb2YgdGhlbSwgb2YgY291cnNlLCBpcyB0byBpdHNlbGYgOi0pDQoNCmBgYHtyIGluY2x1ZGU9VFJVRSwgZWNobyA9IEZBTFNFLCBldmFsPVRSVUV9DQojIyB0b3AgbWVudGlvbnMNCnRvcF9tZW50aW9uczwtdG1sc3lyICU+JSANCiAgZ3JvdXBfYnkoc2NyZWVuX25hbWUpJT4lDQogIHVubmVzdF90b2tlbnMobWVudGlvbnMsIHRleHQsICJ0d2VldHMiLCB0b19sb3dlciA9IEZBTFNFKSAlPiUNCiAgZmlsdGVyKHN0cl9kZXRlY3QobWVudGlvbnMsICJeQCIpKSAlPiUgIA0KICBjb3VudChtZW50aW9ucywgc29ydCA9IFRSVUUpDQogIA0KRHVrZV90b3BtZW50aW9uczwtdG9wX21lbnRpb25zJT4lDQogIGZpbHRlcihzY3JlZW5fbmFtZT09IkR1a2VVIiklPiUNCiAgdG9wX24oNSkNCg0KRHVrZV90b3BtZW50aW9ucyU+JQ0KICBrYmwoY2FwdGlvbiA9ICJUb3AgbWVudGlvbnMgZm9yIER1a2VVIiklPiUNCiAgcm93X3NwZWMoMCwgYm9sZD1UUlVFKSU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJjb25kZW5zZWQiLCAicmVzcG9uc2l2ZSIpLCBmdWxsX3dpZHRoID0gRkFMU0UsIHBvc2l0aW9uID0gImxlZnQiKQ0KICANCg0KVU5DX3RvcG1lbnRpb25zPC10b3BfbWVudGlvbnMlPiUNCiAgZmlsdGVyKHNjcmVlbl9uYW1lPT0iVU5DIiklPiUNCiAgdG9wX24oNSkNCg0KVU5DX3RvcG1lbnRpb25zJT4lDQogIGtibChjYXB0aW9uID0gIlRvcCBtZW50aW9ucyBmb3IgVU5DIiklPiUNCiAgcm93X3NwZWMoMCwgYm9sZD1UUlVFKSU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJjb25kZW5zZWQiLCAicmVzcG9uc2l2ZSIpLCBmdWxsX3dpZHRoID0gRkFMU0UsIHBvc2l0aW9uID0gImxlZnQiKQ0KDQoNCk5DU3RhdGVfdG9wbWVudGlvbnM8LXRvcF9tZW50aW9ucyU+JQ0KICBmaWx0ZXIoc2NyZWVuX25hbWU9PSJOQ1N0YXRlIiklPiUNCiAgdG9wX24oNSkNCg0KTkNTdGF0ZV90b3BtZW50aW9ucyU+JQ0Ka2JsKGNhcHRpb24gPSAiVG9wIG1lbnRpb25zIE5DIFN0YXRlIiklPiUNCiAgcm93X3NwZWMoMCwgYm9sZD1UUlVFKSU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJjb25kZW5zZWQiLCAicmVzcG9uc2l2ZSIpLCBmdWxsX3dpZHRoID0gRkFMU0UsIHBvc2l0aW9uID0gImxlZnQiKQ0KYGBgDQoNCkFuZCBmaW5hbGx5LCBsZXQncyBzZWUgaG93IG1hbnkgdGltZXMgdGhleSBtZW50aW9uIGVhY2ggb3RoZXI6DQoNCmBgYHtyIGluY2x1ZGU9VFJVRSwgZWNobyA9IEZBTFNFLCBldmFsPVRSVUV9DQpEdWtlTkNTdGF0ZW1lbnRpb248LXRvcF9tZW50aW9ucyU+JSAjNA0KICBmaWx0ZXIoc2NyZWVuX25hbWU9PSJEdWtlVSIgJiBtZW50aW9ucz09IkBOQ1N0YXRlIikNCg0KTkNTdGF0ZUR1a2VtZW50aW9uIDwtdG9wX21lbnRpb25zJT4lICMgMSB0aW1lDQogIGZpbHRlcihzY3JlZW5fbmFtZT09Ik5DU3RhdGUiICYgbWVudGlvbnM9PSJARHVrZVUiKQ0KDQpEdWtlVU5DbWVudGlvbiA8LXRvcF9tZW50aW9ucyU+JSAjOSB0aW1lcyANCiAgZmlsdGVyKHNjcmVlbl9uYW1lPT0iRHVrZVUiICYgbWVudGlvbnM9PSJAVU5DIikNCg0KVU5DRHVrZW1lbnRpb24gPC0gdG9wX21lbnRpb25zJT4lICMgNSB0aW1lcyANCiAgZmlsdGVyKHNjcmVlbl9uYW1lPT0iVU5DIiAmIG1lbnRpb25zPT0iQER1a2VVIikNCg0KTkNTdGF0ZXVuY21lbnRpb24gPC0gdG9wX21lbnRpb25zJT4lICMgMyB0aW1lDQogIGZpbHRlcihzY3JlZW5fbmFtZT09Ik5DU3RhdGUiICYgbWVudGlvbnM9PSJAVU5DIikNCg0KVU5DTkNTdGF0ZSA8LXRvcF9tZW50aW9ucyU+JSAjIDIgdGltZQ0KICBmaWx0ZXIoc2NyZWVuX25hbWU9PSJVTkMiICYgbWVudGlvbnM9PSJATkNTdGF0ZSIpDQoNCkFsbG1lbnRpb25zPC1yYmluZC5kYXRhLmZyYW1lKER1a2VOQ1N0YXRlbWVudGlvbiwgTkNTdGF0ZUR1a2VtZW50aW9uLCBEdWtlVU5DbWVudGlvbiwgVU5DRHVrZW1lbnRpb24sIE5DU3RhdGV1bmNtZW50aW9uLCBVTkNOQ1N0YXRlKQ0KDQpBbGxtZW50aW9ucyU+JQ0Ka2JsKGNhcHRpb24gPSAiTWVudGlvbnMgb2YgZWFjaCBvdGhlcnMnIGFjY291bnRzIGJ5IHVuaXZlcnNpdHkiKSU+JQ0KICByb3dfc3BlYygwLCBib2xkPVRSVUUpJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIsICJyZXNwb25zaXZlIiksIGZ1bGxfd2lkdGggPSBGQUxTRSwgcG9zaXRpb24gPSAibGVmdCIpDQpgYGANCg0KIyBTZW50aW1lbnQgQW5hbHlzaXMNCg0KVGhlIGxhc3QgYW5hbHlzaXMgd2UnbGwgZG8gaXMgYSBzZW50aW1lbnQgYW5hbHlzaXMgb24gYSBzaGFyZWQgdG9waWMuIEFzIHdlJ3ZlIHNlZW4gdGhyb3VnaG91dCBvdXIgZGl2ZSBpbnRvIHRoZSBkYXRhLCBjb3ZpZDE5IGZlYXR1cmVkIHByb21pbmVudGx5IGluIHRoZSB0d2VldHMgb2YgZWFjaCBvZiB0aGUgdW5pdmVyc2l0aWVzLiBJbmRlZWQsIHRoZSBjb3ZpZDE5IHBhbmRlbWljIHNoYXBlZCB0aGUgeWVhciBzbmFwc2hvdCB0aGF0IHdlIGFyZSBhbmFseXppbmcuIExldCdzIGFuYWx5emUgdGhlIHNlbnRpbWVudCBzaGFyZWQgYW1vbmdzdCB0aGUgdW5pdmVyc2l0aWVzIGJ5IHRpbWUgaW4gcmVnYXJkcyB0byBjb3ZpZDE5LiBXZSdsbCB1c2UgdGhlIFtgdmFkZXJgXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvdmFkZXIvaW5kZXguaHRtbCkgcGFja2FnZSB0byBtYWtlIG91ciBsaXZlcyBlYXNpZXIsIHNpbmNlIGl0IGRvZXNuJ3QgbmVjZXNzaXRhdGUgdG9rZW5pemluZyBvZiB0ZXh0LiBJdCdzIGVzcGVjaWFsbHkgZWZmZWN0aXZlIG9uIHNvY2lhbCBtZWRpYSBkYXRhLCBzdWNoIGFzIFR3aXR0ZXIsIGFuZCBjYW4gYW5hbHl6ZSB0aGUgc2VudGltZW50cyBmcm9tIGVtb3RpY29ucyBhcyB3ZWxsISDwn5iBXA0KIVtdKGhhcHB5ZmFjZXZhZGVyLmpwZyl7d2lkdGg9IjMwMCJ9XA0KRmlyc3QsIGxldCdzIGNvdW50IHRoZSBudW1iZXIgb2YgdHdlZXRzIHBlciB1bml2ZXJzaXR5IHRoYXQgbWVudGlvbmVkIHRoZSBwYW5kZW1pYy4gSGVyZSB3ZSdsbCB1c2UgdGhlIGBncmVwbGAgZnVuY3Rpb24gdG8gcHVsbCBvdXQgdHdlZXRzIHdpdGggdGhlIHRlcm1zIHdlIG5lZWQ6DQoNCmBgYHtyIGluY2x1ZGU9VFJVRSwgZWNobyA9IFRSVUUsIGV2YWw9RkFMU0V9DQp2YWRlcl90bWxzeXIgPC12YWRlcl9kZih0bWxzeXIkdGV4dCkNCg0KDQpqb2ludmFkZXJfdG1sc3lyIDwtdG1sc3lyICU+JQ0KICBpbm5lcl9qb2luKHZhZGVyX3RtbHN5ciwgYnk9InRleHQiKQ0KDQp2YWRlcl9yZXN1bHRzPC1qb2ludmFkZXJfdG1sc3lyJT4lDQogIHNlbGVjdChzY3JlZW5fbmFtZSwgY3JlYXRlZF9hdCwgdGV4dCwgY29tcG91bmQsIHBvcywgbmV1LCBuZWcsIGJ1dF9jb3VudCklPiUNCiAgbXV0YXRlKHNlbnRpbWVudCA9IGlmZWxzZShjb21wb3VuZCA+IDAsICJwb3NpdGl2ZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGNvbXBvdW5kIDwwLCAibmVnYXRpdmUiLCAibmV1dHJhbCIpKSkNCmBgYA0KDQpgYGB7ciBpbmNsdWRlPVRSVUUsIGVjaG8gPSBUUlVFLCBldmFsPUZBTFNFfQ0KIyNjb3ZpZCBzZW50aW1lbnQNCnZhZGVyX2NvdmlkIDwtIHZhZGVyX3Jlc3VsdHMgJT4lDQogIGZpbHRlcihncmVwbCgiKD9pKUNPVklEfGNvcm9uYXx2aXJ1c3xwYW5kZW1pYyIsIHRleHQpKQ0KYGBgDQoNCk5vdyBsZXQncyB1c2UgYGx1YnJpZGF0ZWAgdG8gaGVscCB1cyBkbyBvdXIgdGltZSBzZXJpZXM6DQoNCmBgYHtyIGluY2x1ZGU9VFJVRSwgZWNobyA9IFRSVUUsIGV2YWw9RkFMU0V9DQojbHVicmlkYXRlDQp2YWRlcl9kYXRlIDwtdmFkZXJfY292aWQlPiUNCiAgbXV0YXRlKHllYXJfbW9udGggPSBmbG9vcl9kYXRlKGNyZWF0ZWRfYXQsICJtb250aHMiKSAlPiUgeW1kKCkpDQoNCnZhZGVyX2RhdGVfc3VtbWFyaXNlPC12YWRlcl9kYXRlJT4lDQogIGdyb3VwX2J5KHNjcmVlbl9uYW1lLCB5ZWFyX21vbnRoKSU+JQ0KICBzdW1tYXJpc2UobWVhbj0gbWVhbihjb21wb3VuZCkpDQoNCiMjY292aWQgY291bnQNCmNvdmlkX3Bsb3RfY291bnQ8LXZhZGVyX2RhdGUlPiUNCiAgZ3JvdXBfYnkoc2NyZWVuX25hbWUsIHllYXJfbW9udGgpJT4lDQogIGNvdW50KHNjcmVlbl9uYW1lKQ0KI3Bsb3QgY292aWQgdHdlZXRzIGNvdW50DQpnZ3Bsb3QoY292aWRfcGxvdF9jb3VudCwgYWVzKHg9eWVhcl9tb250aCwgeT1uLCkpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG9yPXNjcmVlbl9uYW1lKSkNCmBgYA0KDQohW1RpbWUgU2VyaWVzIFBsb3Qgb2YgdHdlZXRzIHJlbGF0ZWQgdG8gQ292aWQxOV0oY292aWQlMjByZWxhdGVkJTIwdHdlZXRzJTIwdHMlMjBScGxvdC5wbmcpDQoNCmBgYHtyIGluY2x1ZGU9VFJVRSwgZWNobyA9IFRSVUUsIGV2YWw9RkFMU0UsIGZpZy5jYXA9IlZhZGVyIFNlbnRpbWVudCBQbG90OiBDb3ZpZDE5IGFuZCAzIGFyZWEgdW5pdmVyc2l0aWVzIn0NCnZhZGVyX2RhdGVfc3VtbWFyaXNlICU+JQ0KZ2dwbG90KGFlcyh4PXllYXJfbW9udGgsIHk9bWVhbikpICsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9c2NyZWVuX25hbWUpKSsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kPSJhdXRvIikrDQogIGxhYnMoeD1OVUxMLCB5PSJNZWFuIENvbXBvdW5kIFNjb3JlIiwgdGl0bGU9IlR3ZWV0cyByZWxhdGVkIHRvIENvdmlkLTE5IGFuZCB0aGUgDQogICAgICAgUGFuZGVtaWM6IFZhZGVyIFNlbnRpbWVudCBTY29yZSBvdmVyIHRpbWUgZm9yIER1a2UsIFVOQywgYW5kIE5DIFN0YXRlIiwgY2FwdGlvbj0iQ29tcG91bmQgU2NvcmU6DQogICAgICAgLTEgKG1vc3QgZXh0cmVtZSBuZWdhdGl2ZSkgYW5kICsxIChtb3N0IGV4dHJlbWUgcG9zaXRpdmUpIikNCmBgYA0KDQohW1NlbnRpbWVudCBTY29yZSBmb3IgVHdlZXRzIFJlbGF0ZWQgdG8gQ292aWQxOV0oU2VudGltZW50JTIwQW5hbHlzaXMlMjBDb3ZpZDE5JTIwUnBsb3QucG5nKQ0KDQpUaGUgY29tcG91bmQgc2NvcmUgZm9yIHRoZSBzZW50aW1lbnQgaXMgY29tcHV0ZWQgYnkgc3VtbWluZyB0aGUgdmFsZW5jZSBzY29yZXMgb2YgZWFjaCB3b3JkIGluIHRoZSBsZXhpY29uLCBhZGp1c3RlZCBhY2NvcmRpbmcgdG8gdGhlIHJ1bGVzLCBhbmQgdGhlbiBub3JtYWxpemVkIHRvIGJlIGJldHdlZW4gLTEgKG1vc3QgZXh0cmVtZSBuZWdhdGl2ZSkgYW5kICsxIChtb3N0IGV4dHJlbWUgcG9zaXRpdmUpLg0KDQpUaGUgcmVzdWx0cyBvZiB0aGUgc2VudGltZW50IGFuYWx5c2lzIGFyZSBpbnRlcmVzdGluZy4gVGhlIHNlbnRpbWVudCBza2V3cyBwb3NpdGl2ZSBmb3IgYWxsIHRocmVlIHVuaXZlcnNpdGllcyBvdmVyYWxsLiBUaGlzIG1ha2VzIHNvbWUgc2Vuc2UgaW4gdGhlIGNvbnRleHQgb2YgdGhlc2UgbWFpbiBhY2NvdW50cyB0d2VldGluZyBtYWlubHkgaW5mb3JtYXRpb25hbCBwb3NpdGlvbnMsIGxpa2UgcG9saWNpZXMgb3IgZGlyZWN0aXZlcyBmb3IgdGhlaXIgY2FtcHVzIGNvbW11bml0eSwgb3IgdHdlZXRzIHJlbGF0ZWQgdG8gcmVzZWFyY2ggb25nb2luZyBpbiB0aGlzIGFyZWEgLSBtb3N0IGxpa2VseSByZXNlYXJjaCBnYWlucy4gWW91IGNhbiBzZWUgYSBzbGlnaHQgYm93IGN1cnZlIGZyb20gQXByaWwgMjAyMCwgdGhlIGJlZ2lubmluZyBvZiB0aGUgcGFuZGVtaWMsIHRvIEFwcmlsIDIwMjEuIER1a2UgYW5kIE5DIFN0YXRlIGhhZCB0aGVpciBuZWdhdGl2ZSBtb21lbnRzIGluIEF1Z3VzdCAyMDIwIGFuZCBOb3ZlbWJlciAyMDIwIHJlc3BlY3RpdmVseS4gQW4gb3V0bGllciBpcyBVTkMgaW4gSnVseSAyMDIwIHdpdGggYW4gYWxtb3N0IDAuNiBjb21wb3VuZCBzY29yZS4NCg0KV2hhdCdzIGFsc28gaW50ZXJlc3RpbmcgdG8gbm90ZSwgaXMgdGhhdCB0aGUgc2VudGltZW50IHNjb3JlcyBkdXJpbmcgQXByaWwgMjAyMSBzZWVtZWQgdG8gYmUgdGhlIG1vc3QgaG9tb2dlbm91cyB0aGFuIHRoYXQgb2YgYW55IG90aGVyIHRpbWUgaW4gdGhlIHllYXIuIEFzIHZhY2NpbmVzIGFyZSBhZG1pbmlzdGVyZWQgYW5kIHJlc3RyaWN0aW9ucyBsb29zZW5lZCBvbiBjYW1wdXNlcywgSSdsbCBiZSBjdXJpb3VzIHRvIHNlZSBob3cgdGhlc2Ugc2VudGltZW50IHNjb3JlcyBldm9sdmUuDQoNCkFuZCBiZWNhdXNlIEknbSBjdXJpb3VzLCBhbmQgdGhlc2UgdW5pdmVyc2l0aWVzIHNoYXJlIHRoZSByZXNlYXJjaCBJIGRlc2lnbmF0aW9uLCBsZXQncyBsb29rIGF0IHRoZSB0d2l0dGVyIGFjdGl2aXR5IGFuZCBzZW50aW1lbnQgc2NvcmUgb2YgdHdlZXRzIHJlbGF0ZWQgdG8gKipyZXNlYXJjaCoqOg0KDQohW1RpbWUgU2VyaWVzIFBsb3Qgb2YgdHdlZXRzIHJlbGF0ZWQgdG8gUmVzZWFyY2hdKFJlc2VhcmNoJTIwd29yZCUyMGNvdW50JTIwUnBsb3QucG5nKVwNClRoZSBhY3Rpdml0eSBmb3IgcmVzZWFyY2ggaXMgYSBsaXR0bGUgbGVzcyB0aGFuIHRoYXQgcmVsYXRpbmcgdG8gY292aWQxOS4gVU5DIGhhZCBhbG90IG9mIGFjdGl2aXR5IE9jdG9iZXIgMjAyMC4NCg0KTm93IGxldCdzIGxvb2sgYXQgdGhlIHNlbnRpbWVudCBzY29yZToNCg0KXA0KIVtTZW50aW1lbnQgU2NvcmUgZm9yIFR3ZWV0cyBSZWxhdGVkIHRvIFJlc2VhcmNoXShTZW50aW1lbnQlMjBSZXNlYXJjaCUyMFJwbG90LnBuZykNCg0KSXQncyBwcmV0dHkgcG9zaXRpdmUsIHdpdGggYW4gb3ZlcmFsbCB1cHdhcmQgc2xvcGUgYXQgdGhlIGVuZC4gQWdhaW4sIFVOQyB0cmVuZHMgcG9zaXRpdmUuIER1a2UncyBzZW50aW1lbnQgc2NvcmUgaW4gcmVnYXJkcyB0byByZXNlYXJjaCB0cmVuZCBkb3dud2FyZCwgd2hpY2ggaXMgaW50ZXJlc3RpbmcuIEFmdGVyIGluc3BlY3RpbmcgdGhlIHR3ZWV0cywgaXQgbWF5IGJlIHRoYXQgdGhlIGlzc3VlcyB0aGV5IGFyZSByZXNlYXJjaGluZyBtaWdodCBza2V3IHRoZSBzZW50aW1lbnQgbmVnYXRpdmUsIGkuZS4gZGlzZWFzZXMsIHNvY2lhbCBwcm9ibGVtcywgZXRjLg0KDQojIERpc2N1c3Npb24NCg0KVGhlIGNlbnRyYWwgcXVlc3Rpb24gdGhhdCBJIHNldCBvdXQgZm9yIHRoaXMgYW5hbHlzaXMgaXMgd2hhdCBpcyB1bmlxdWUgdG8gZWFjaCB1bml2ZXJzaXR5IGluIHRoZSB3YXkgdGhleSBjYXJyeSBvdXQgdGhlaXIgVHdpdHRlciBhY3Rpdml0eT8gQXJlIHRoZXJlIGNlcnRhaW4gY2hhcmFjdGVyaXN0aWNzIHRoYXQgZGVmaW5lIGVhY2ggdW5pdmVyc2l0eT8gT3VyIGFuYWx5c2lzIHlpZWxkZWQgc29tZSBjb21tb24gcmVzdWx0czoNCg0KLSAgIFRoZXNlIHVuaXZlcnNpdGllcyBoYXZlIHNpbWlsYXIgYW1vdW50cyBvZiB0d2VldHMgcGVyIG1vbnRoIG9uIGF2ZXJhZ2UsIHdpdGggdGhlIGV4Y2VwdGlvbiBvZiBOQyBTdGF0ZSB3aGVuIHRoZXkgYXJlIGNvbmR1Y3RpbmcgdGhlaXIgXCNnaXZpbmdwYWNrIGNhbXBhaWduDQotICAgVGhlcmUgd2VyZSBtYW55IGNvbW1vbiB3b3JkcyBleHByZXNzZWQgYmV0d2VlbiB0aGUgYWNjb3VudHMsIGVzcGVjaWFsbHkgaGF2aW5nIHRvIGRvIHdpdGggdGhlIHBhbmRlbWljLCB3aGljaCBkb21pbmF0ZWQgdGhlIHllYXIgc25hcHNob3QNCi0gICBUaGVzZSB1bml2ZXJzaXRpZXMgZG8gbm90IG1lbnRpb24gZWFjaCBvdGhlciBvZnRlbiwgcmF0aGVyIHRoZXkgYW1wbGlmeSB0aGUgYWNjb3VudHMgb2YgdGhvc2UgYmVsb25naW5nIHRvIHRoZWlyIHVuaXZlcnNpdHkgKGRlcGFydG1lbnRzLCBldGMuKQ0KDQpBcyBmb3IgZGlmZmVyZW5jZXMsIGVhY2ggdW5pdmVyc2l0eSdzIGZvY3VzIGNhbWUgb3V0IGluIGFuYWx5emluZyB0aGUgdHdlZXRzLiBGb3IgZXhhbXBsZSwgRHVrZSBpcyBrbm93biBmb3IgdGhlaXIgbWVkaWNhbCBzeXN0ZW0gYW5kIHJlc2VhcmNoIGluIGhlYWx0aCBhbmQgbWVkaWNpbmUgc28gaXQgaXMgbmF0dXJhbCBmb3IgdGhlbSB0byB0d2VldCBvZnRlbiBhYm91dCB0aGlzLiBOQyBTdGF0ZSdzIGZ1bmRyYWlzaW5nIGNhbXBhaWduIGFuZCB0aGVpciBjb2xsZWdlIG9mIGVuZ2luZWVyaW5nIGZlYXR1cmVzIHByb21pbmVudGx5IGFuZCB0aGV5IHJlYWxseSBlbmdhZ2Ugd2l0aCBzdHVkZW50cywgYWx1bW5pLCBhbmQgdGhlaXIgdmFyaW91cyBjb2xsZWdlcy9kZXBhcnRtZW50cyBvbiBjYW1wdXMgb24gVHdpdHRlci4gVU5DIHRlbmRlZCB0byBmb2N1cyBvbiB0aGVpciBpZGVudGl0eSBhcyBhICJUYXJoZWVsIiBhbmQgd2FzIHRoZSB1bml2ZXJzaXR5IHRoYXQgc3Bva2UgbW9yZSB0b3dhcmRzIHNwb3J0cyB0aGFuIHRoZSBvdGhlcnMsIGV2ZW4gdGhvdWdoIHRoZSBvdGhlcnMgaGF2ZSBzdHJvbmcgYXRobGV0aWNzLg0KDQpXZSBtdXN0IGFsc28gcmVtZW1iZXIgdGhlIGxpbWl0YXRpb25zIG9mIHRoaXMgYW5hbHlzaXMgd2hpY2ggbWFpbmx5IGxpZSBpbiB0aGUgZXhwbG9yYXRpb24gb2Ygb25lIHNvY2lhbCBtZWRpYSBwbGF0Zm9ybSB0byBleHRyYXBvbGF0ZSB0aGUgb3ZlcmFsbCBjb25zaWRlcmF0aW9ucyBvZiBlYWNoIHVuaXZlcnNpdHkuIFRoaXMgYW5hbHlzaXMgY2FuIG9ubHkgb2ZmZXIgYSBzbmFwc2hvdCBvZiBhIHdpZGVyIGNvbW11bmljYXRpb25zIG5ldHdvcmsgdGhhdCBlYWNoIHVuaXZlcnNpdHkgZW1wbG95cy4gQWxzbywgZWFjaCBtZXRob2Qgb2YgdGV4dCBhbmFseXNpcyBoYXMgaXRzIHByb3MvY29ucyBhcyB0byB0aGUgYWNjdXJhY3kgb3IgZWZmaWNhY3kgb2YgdGhlIG1vZGVsLiBIb3dldmVyLCB0YWtlbiBhbHRvZ2V0aGVyLCB0aGVzZSBtZXRob2RzIGhhdmUgcHJvdmlkZWQgdXMgYSBnbGltcHNlIGludG8gb3VyIHJlc2VhcmNoIHF1ZXN0aW9uLg0KDQojIEZpbmFsIFRob3VnaHRzDQoNClRoaXMgYW5hbHlzaXMgZ2F2ZSB1cyBhIGdvb2QgcGljdHVyZSBvZiB0aGUgY2hhcmFjdGVyaXN0aWNzIG9mIGVhY2ggdW5pdmVyc2l0eSdzIG1haW4gVHdpdHRlciBhY2NvdW50LiBUaGV5IGRvIGhhdmUgc29tZSB0aGluZ3MgaW4gY29tbW9uLCBhbmQgdGhlIGJyZWF0aCBvZiB3aGF0IHdhcyBkaXNjdXNzZWQgaW4gdGhlaXIgYWNjb3VudHMgY291bGQgYmUgYmVjYXVzZSBvZiB0aGVpciBwcm9maWxlIG9mIGJlaW5nIGxhcmdlLCByZXNlYXJjaCBJIHVuaXZlcnNpdGllcy4gSG93ZXZlciwgZWFjaCBzb3VnaHQgdG8gYW1wbGlmeSB0aGVpciBvd24gdW5pcXVlIHN0cmVuZ3RocyBhbmQgd2hhdCBtYWtlcyB0aGVtIGRpc3RpbmN0IGluIHRlcm1zIG9mIHN0dWRlbnQgZm9jdXMsIHRoZWlyIGFjYWRlbWljIGRlcGFydG1lbnRzLCByZXNlYXJjaCwgYW5kIG90aGVyIGNhbXB1cyBhY3Rpdml0aWVzLiBGb3IgdGhvc2Ugd2hvIG1hbmFnZSBzb2NpYWwgbWVkaWEgYWNjb3VudHMgb3IgY29tbXVuaWNhdGlvbnMgZm9yIGluc3RpdHV0aW9ucyBmb3IgaGlnaGVyIGVkdWNhdGlvbiwgdGhpcyBhbmFseXNpcyBpcyBhIHVzZWZ1bCBjYXNlIHN0dWR5IG9mIGhvdyBlYWNoIG9mIHRoZXNlIHVuaXZlcnNpdGllcyBoYXZlIHRvbGQgdGhlaXIgdW5pcXVlIHN0b3J5IGR1cmluZyB0aGUgY29tbW9uIGNoYWxsZW5nZSBvZiB0aGUgY292aWQtMTkgcGFuZGVtaWMuIFRoZSBtZXRyaWNzIG9idGFpbmVkIGFib3V0IGZyZXF1ZW5jeSBhbmQgZW5nYWdlbWVudCBhcmUgZXNwZWNpYWxseSB1c2VmdWwgYXMgYSBiZW5jaG1hcmsgZm9yIGVmZmVjdGl2ZSBUd2l0dGVyIHNvY2lhbCBtZWRpYSBtYW5hZ2VtZW50Lg0KDQojIEFib3V0IE1lDQoNCkJ5IGRheSwgSSBhbSBBc3Npc3RhbnQgRGlyZWN0b3IgZm9yIHRoZSBbR2xvYmFsIEVkdWNhdGlvbiBPZmZpY2VdKGh0dHBzOi8vZ2xvYmFsZWQuZHVrZS5lZHUvKSBhdCBEdWtlIFVuaXZlcnNpdHkuIEJ5IChsYXRlKSBuaWdodCwgSSBtZXNzIGFyb3VuZCB3aXRoIGRhdGEuIEZvbGxvdyBtZSBvbiBUd2l0dGVyIFtcQHNvcmF5YXdvcmxkd2lkZV0oaHR0cHM6Ly90d2l0dGVyLmNvbS9zb3JheWF3b3JsZHdpZGUpDQoNCiFbXShodHRwczovL21lZGlhLmdpcGh5LmNvbS9tZWRpYS9KV3VCSDlyQ08ydVp1SEJGcG0vZ2lwaHkuZ2lmKQ0K