library(rtweet)
library(dplyr)
library(ggplot2)
library(lubridate)
library(SentimentAnalysis)
library(dlookr)
library(hrbrthemes)
library(viridis)
library(stringr)
library(tidytext)
library(tm)
library(tokenizers)
library(wordcloud)
library(tidyr)
library(glue)
library(igraph)
library(syuzhet)

1. Cleaning and manipulating data

The purpose of this process will be to remove all unnecessary variables not required for research as well as create additional variables of sentiment and reception, then split the data frame based on the source of each tweet.

#Rename source variable as source_clean, and bind it to the final dataset.
final_data <- cbind(final_source$source, final_data)
names(final_data)[1] = "source_clean"
final_data <- subset(final_data, select = -c(source))
names(final_data)[1] = "source"
#Generate reception scores
options(scipen = 999)

#Generate retweet ratio
final_data$retweet_ratio <-
  (final_data$retweet_count*2/final_data$followers_count) * 100

#Generate favorite ratio
final_data$favorite_ratio <-
  (final_data$favorite_count/final_data$followers_count) * 100

#Generate reception score for each tweet.
final_data$reception <- apply(final_data[14:15], 1, mean, na.rm = TRUE)
#Transform the text viable into a usable form.
text_corpus <- Corpus(VectorSource(final_data$text))
text_corpus <- tm_map(text_corpus, tolower)
## Warning in tm_map.SimpleCorpus(text_corpus, tolower): transformation drops
## documents
text_corpus <- tm_map(text_corpus, removeWords, stopwords("english"))
## Warning in tm_map.SimpleCorpus(text_corpus, removeWords, stopwords("english")):
## transformation drops documents
text_corpus <- tm_map(text_corpus, removePunctuation)
## Warning in tm_map.SimpleCorpus(text_corpus, removePunctuation): transformation
## drops documents
text_df <- data.frame(text_clean = get("content", text_corpus), stringsAsFactors = FALSE)
final_data <- cbind.data.frame(final_data, text_df)

#Remove redundant text variable "full_text"
final_data <- subset(final_data, select= -c(text, full_text))

#create sentiment dataframe
sentiment <- analyzeSentiment(final_data$text_clean)

#bind and rename sentiment scores to dataset
final_data <- cbind(final_data, sentiment$SentimentGI)
names(final_data)[16] = "sentiment"
#reorder variables in dataframe
final_data <- final_data[, c(2,3,4,15,1,5,6,7,8,9,10,11,12,13,14,16)]
#Create new data frames for future analysis.

#Data frame for users
only_users <- final_data[final_data$source == "User", ]

#Data frame for LIVGolfInv
LIVGolf <- final_data[final_data$screen_name == "LIVGolfInv", ]

#Data frame for media
media <- final_data[final_data$source == "Media", ]

2. Exploratory Analysis

The purpose of this process is to understand basic properties of the dataset and begin to understand what information the dataset contains.

#Identify the quantity of tweets from each source.
final_source %>% group_by(source) %>% count(source, sort = TRUE)
#Identify aspects of the favorite_count variable.
favorites_w_user <- select(final_data, screen_name, favorite_count)
arrange(favorites_w_user, desc(favorite_count))
#Identify aspects of the retweet_count variable.
retweets_w_user <- select(final_data, screen_name, retweet_count)
arrange(retweets_w_user, desc(retweet_count))

Conclusions

Source Variable - LIVGolf has several hundred thousand followers, but those followers only create a very small amount of conversation about the series. While users as a whole create a larger total quantity of tweets, throughout the observation period, no other user created as many tweets about LIVGolf than the account “LIVGolfInv”.

Retweet Variable - As expected, the users with the highest amount of followers garnered the highest number of retweets per post. It is unexpected the amount of retweets that LIVGolf content creates among their followers.

Favorite_count Variable - As expected, the users with the highest amount of followers garnered the highest number of favorites per tweet. It is unexpected that LIVGolf content creates such a relatively small amount of likes in relation to their follower count.

Additional analysis is required to understand why users with significantly smaller amounts of followers recieved a comparable amount of favorites, specifically the users “20thCenturyDan” and “AndrewKirbyGolf”. What is it about those two tweets that generated engagement from thier followers and is it indicative of the reception of LIVGolf?

3. Frequency Analysis

The purpose of the frequency analysis is to determine to amount of conversation over time about LIV golf and to determine how much of the conversation is contributed to LIVGolf creating the conversation, media reporting on LIVGolf, and user generated content about the LIVGolf topic.

source_by_type <- final_data %>% group_by(day_created, source) %>%
  summarise(total_count = n (), .groups = "keep") %>%
  as.data.frame()
source_by_type

Frequency Plot Activity

histogram_all_plot <- ggplot(source_by_type, aes(x = day_created, 
                                                 y = total_count)) +
  geom_bar(aes(color = source, fill = source), stat = "identity", 
           position = position_stack()) +
  labs(title = "Source of LIVGolf Content",
      subtitle = "November 8th to November 28th 2022",
      caption = "Data Source: Twitter search for #LIVGolf") +
  labs(y = "Daily Count", x = "Date Created")
histogram_all_plot + scale_x_continuous(breaks =                                          c(8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29)) 

Cumulative Relative Frequency Plot

rel_freq_plot <- ggplot(source_by_type, aes(x = day_created, 
                                            y = total_count)) +
  geom_bar(aes(color = source, fill = source), stat = "identity", 
           position = "fill") +
  labs(title = "Relative Frequency of Source",
      subtitle = "November 8th to November 29th 2022",
      caption = "Data Source: Twitter search for #LIVGolf") +
  labs(y = "Percent of Tweets", x = "Date Created")
rel_freq_plot + scale_x_continuous(breaks =
        c(8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29))       

Conclusions

Media Contributors- Media reporting about LIVGolf saw a peak from the 13th to the 17th of November. Additional analysis is required to determine the topic of conversation for media tweets.

All Contributors - The highest level of activity seen on the Twitter platform from LIVGolf was on the 17th and 14th of November.

User Contribution - The highest level of activity seen on the platform from users was on the 18th and of November. Additional analysis could be conducted to understand content on the 18th of November to greater understand what motivated users to post about LIVGolf. LivGolf Contribution- The highest total number of tweets from LIvGolf occurred on the 17th of November.

Additional analysis is required to understand the conversation about LIVGolf during the peak conversational dates. It is possible to explore the connection between number of tweets from LIVGolf and number of user and media tweets.

4. Reception Analysis

Reception of the tweet is measured as a calculation of engagements while taking into account that the amounts of followers vary between users and vary over time. For the purposes of this research, reception can equate to popularity of opinion. Therefore, measuring reception is crucial to understanding dominant viewpoints about LIVGolf among users.

Reception is the mean of retweets * 2 divided by the number of followers and favorites divided by the number of followers times 100. This calculation accounts for the reach achieved by the number of followers as well as accounting for what occurs when a follower retweets content. The number of users that could potentially interact with content becomes larger as a user’s followers retweet content, thus, there is potential for content to be seen by a larger number of users than only followers.

The purpose of this section will be to understand the level of reception to LIVGolf generated content during the observation period. Then analysis will be conducted to determine if LIV Golf content is either growing in popularity, decreasing in popularity, or remaining relatively stable. A point of comparison is the mean reception score of content generated by users. If significantly different, future analysis could be conducted to understand the message behind content with higher or lower reception scored content.

Reception Scatter Plot

#Plot reception over time for LIVGolf generated content.
LIV_Golf_reception_plot <- ggplot(LIVGolf, aes(x = day_created, 
                                               y = reception)) + 
  geom_point(size = 1, color = "red") +
  labs(title = "Reception Score of LIVGolf Generated Tweets",
      subtitle = "November 8th to November 28th 2022",
      caption = "Data Source: Twitter search for #LIVGolf") +
  labs(y = "Reception Score", x = "Date of Tweet")
LIV_Golf_reception_plot + scale_x_continuous(breaks =
       c(8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29))         

Mean Reception Score - LIV Golf

#Generate Mean reception score per day of observation for LIVGolf generated content because of instances where LIVGolf created multiple tweets per day.
LIV_daily_reception <- LIVGolf %>% group_by(day_created) %>% summarise(reception = mean(reception))

#Plot mean daily reception values of LIVGolf generated content.
daily_reception_plot <- ggplot(LIV_daily_reception, aes(x = day_created, 
                                                y = reception)) + 
  geom_point(size = 1, color = "red") +
  geom_segment(aes(x = day_created, xend = day_created, y = 0, yend =
                     reception)) +
  labs(title = "Mean Reception Score of LIVGolf Generated Tweets",
      subtitle = "November 8th to November 27th 2022",
      caption = "Data Source: Twitter search for #LIVGolf") +
  labs(y = "Reception Score", x = "Date of Tweet")
daily_reception_plot + scale_x_continuous(breaks =                                        c(8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29)) 

Mean Reception Score - Users

#Create mean reception values for user generated content.
mean_user_daily_reception <- only_users %>% group_by(day_created) %>% summarise(reception = mean(reception))

#Plot mean daily reception values of user generated content.
mean_user_daily_reception_plot <- ggplot(mean_user_daily_reception, 
                                         aes(x = day_created,
                                             y = reception)) + 
  geom_point(size = 1, color = "blue") +
  geom_segment(aes(x = day_created, xend = day_created, y = 0, yend =
                     reception)) +
  labs(title = "Mean Reception Score of User Tweets",
      subtitle = "November 8th to November 28th 2022",
      caption = "Data Source: Twitter search for #LIVGolf") +
  labs(y = "Reception Score", x = "Date of Tweet")
mean_user_daily_reception_plot + scale_x_continuous(breaks =                               c(8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29))

only_users_reception <- select(only_users, day_created, reception) %>%
  arrange(day_created)
only_users_reception$day_created <-
  as.character(only_users_reception$day_created)
names(only_users_reception)[1] = "group"

Reception Boxplot - User

only_users_reception %>%
  ggplot( aes(x = group, y = reception, fill = group)) +
    geom_boxplot() +
  theme(legend.position="none",
        plot.title = element_text(size=15)) +
  labs(title = "User Reception Boxplot",
      subtitle = "November 8th to November 28th 2022",
      caption = "Data Source: Twitter search for #LIVGolf") +
  labs(y = "Reception Score", x = "Date Collected")

LIV_followers_count <- select(LIVGolf, day_created, followers_count) %>% arrange(day_created)

LIV Golf Follower Plot

LIV_followers_plot <- LIV_followers_count %>%
  ggplot( aes(x = day_created, y = followers_count)) +
    geom_line() +
  theme(legend.position="none",
        plot.title = element_text(size=15)) +
  labs(title = "Number of Users Following LIVGolf",
      subtitle = "November 8th to November 29th 2022",
      caption = "Data Source: Twitter search for #LIVGolf") +
  labs(y = "Followers", x = "Date")
LIV_followers_plot + scale_x_continuous(breaks =                                      c(8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29))

Conclusions

LIVGolf Reception - LIVGolf experienced the highest level of reception from its content from the 11th to 13th of November. Further Analysis is required to understand potential reasons why content during those dates was received differently than content on other days during the collection period.

User Reception - November 11th and 13th experienced the highest reception score of user generated content. From analysis in the boxplot, it is evident that outliers impact the mean level of reception from user generated tweets. The mean score is significantly lower if outliers were to be removed. A small minority of content is driving reception scores significantly higher on those dates.

Further analysis is required to determine if the content of the tweet is responsible for the presence of the outliers in user generated content. #Further analysis to understand reception will isolate tweets with significantly higher reception scores to understand the content in the tweets.

5. Sentiment Analysis

The purpose of this section is to understand the sentiment of opinion being used in tweets created by LIVGolf and by user generated content. The goal is to identify main ideas or topics of conversation to further guage reception of the LIVGolf product. Additionally, by generating the sentiment variable, research identify overall tone of the conversation as being either positive or negative.

#remove media and advertisements to isolate only users and LIVGolf.
all_sentiment <- subset(final_data, source != "Media")

#Create data frame to understand sentiment over time.
sentiment_data <- select(final_data, day_created, sentiment)

#calculate mean sentiment score throughout the observation period
daily_sentiment <- sentiment_data %>% group_by(day_created) %>% summarise(sentiment = mean(sentiment))
daily_sentiment

Daily Sentiment Score - LIV Golf

#Create Plot of daily sentiment of tweets with LIVGolf
sentiment_plot <- ggplot(daily_sentiment, aes(x = day_created, 
                                              y = sentiment)) +
  geom_point(size = 1, color = "blue") +
  geom_segment(aes(x = day_created, xend = day_created, y = 0, yend = 
    sentiment)) +
  labs(title = "Mean Sentiment Score of all LIVGolf Tweets",
      subtitle = "November 8th to November 29th 2022",
      caption = "Data Source: Twitter search for #LIVGolf") +
  labs(y = "Sentiment Score", x = "Date of Tweet")
sentiment_plot + scale_x_continuous(breaks =                                       c(8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29)) 

#understand user sentiment.
only_users_sentiment <- select(only_users, day_created, sentiment)

#calculate mean sentiment score throughout the observation period
user_sentiment_mean <- only_users_sentiment %>% group_by(day_created) %>% summarise(sentiment = mean(sentiment))
user_sentiment_mean

Daily Sentiment Score - User

#Create Plot of user authored tweets.
only_users_sentiment_plot <- ggplot(only_users_sentiment, 
  aes(x = day_created, y = sentiment)) +
  geom_point(size = 1, color = "blue") +
  labs(title = "Sentiment Scores of User Tweets",
      subtitle = "November 8th to November 29th 2022",
      caption = "Data Source: Twitter search for #LIVGolf") +
  labs(y = "Sentiment Score", x = "Date of Tweet")
only_users_sentiment_plot + scale_x_continuous(breaks =                               c(8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29)) 

Mean Sentiment Score - User

#Create Plot of user authored tweets.
user_sentiment_mean_plot <- ggplot(user_sentiment_mean, 
  aes(x = day_created, y = sentiment)) +
  geom_point(size = 1, color = "blue") +
  geom_segment(aes(x = day_created, xend = day_created, y = 0, yend =
                     sentiment)) +
  labs(title = "Mean Daily Sentiment of User Tweets",
      subtitle = "November 8th to November 29th 2022",
      caption = "Data Source: Twitter search for #LIVGolf") +
  labs(y = "Sentiment Score", x = "Date of Tweet")
user_sentiment_mean_plot + scale_x_continuous(breaks =                                c(8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29)) 

only_users_sentiment$day_created <-
  as.character(only_users_sentiment$day_created)
names(only_users_sentiment)[1] = "group"
#Boxplot of user sentiment per day of collection
only_users_sentiment %>%
  ggplot( aes(x = group, y = sentiment, fill = group)) +
    geom_boxplot() +
  theme(legend.position="none",
        plot.title = element_text(size=15)) +
  labs(title = "User Sentiment Boxplot by Date",
      subtitle = "November 8th to November 28th 2022",
      caption = "Data Source: Twitter search for #LIVGolf") +
  labs(y = "Sentiment Score", x = "Date Collected")

#Violin chart of user sentiment per day of collection
only_users_sentiment %>%
  ggplot( aes(x = group, y = sentiment, fill = group)) +
    geom_violin() +
  theme(legend.position="none",
        plot.title = element_text(size=15)) +
  labs(title = "User Sentiment Violin Chart by Date",
      subtitle = "November 8th to November 28th 2022",
      caption = "Data Source: Twitter search for #LIVGolf") +
  labs(y = "Sentiment Score", x = "Date Collected")

Conclusions

Sentiment of the entire dataset reveals that the 16th and 19th of November resulted in the dates with the lowest sentiment values. Even when the dataset of tweets was separated by author, the 16th and 19th had the lowest sentiment scores.

The 24th of November resulted in the highest mean sentiment score for all tweets and when analyzed by source. The violin plot and boxplot illustrates a relatively tight clustering of sentiment scores without any outliers.

The violin plot illustrates the range of sentiment scores and the amount of occurrences where observations are clustered. For example, the 22nd of November experienced a large amount of content with sentiment score close to zero, therefore, the violin is wider at that score. The 22nd also reveals height based on the presence of outliers that were significantly far away from the mean. The fewer the amount of outliers, and the wider the plot reveals a more consistent sentiment score for that date in the observation period. The 8th, 9th, and 13th experienced no outliers in sentiment.

6. Emotion Analysis

The purpose of this section is to understand the emotions conveyed through language analysis of the text in observed content.

#create dataframe to capture emotions from all tweets.
ew_sentiment_LIV <- get_nrc_sentiment(LIVGolf$text_clean)
sentimentscores_LIV <- data.frame(colSums(ew_sentiment_LIV[,]))
names(sentimentscores_LIV) <- "Score"
sentimentscores_LIV <- cbind("sentiment" =
                           rownames(sentimentscores_LIV),sentimentscores_LIV)
rownames(sentimentscores_LIV) <- NULL

Emotion Frequency Plot - LIV Golf

#plot sentiment of emotions to understand the general tone of conversation about LIVGolf.
emotion_plot_LIV <- ggplot(data = sentimentscores_LIV, 
                       aes(x = sentiment, y = Score)) +
  geom_bar(aes(fill = sentiment), stat = "identity") +
  theme(legend.position = "none") +
  xlab("Sentiments") + ylab("Word Count by Emotion") +
  labs(title = "Emotion Count of LIV Golf Content",
      subtitle = "November 8th to November 29th 2022",
      caption = "Data Source: Twitter search for #LIVGolf")
  
emotion_plot_LIV + theme(axis.text.x = element_text(angle = 45, vjust = 1,
                                                hjust=1))

#create dataframe to capture emotions from all user generated content.
ew_sentiment_users <- get_nrc_sentiment(only_users$text_clean)
sentimentscores_users <- data.frame(colSums(ew_sentiment_users[,]))
names(sentimentscores_users) <- "Score"
sentimentscores_users <- cbind("sentiment" =
                           rownames(sentimentscores_users),
                           sentimentscores_users)
rownames(sentimentscores_users) <- NULL

Emotion Frequency Plot - All Content

#plot sentiment of emotions to understand the general tone of conversation about LIVGolf.
emotion_plot_users <- ggplot(data = sentimentscores_users, 
                       aes(x = sentiment, y = Score)) +
  geom_bar(aes(fill = sentiment), stat = "identity") +
  theme(legend.position = "none") +
  xlab("Sentiments") + ylab("Word Count") +
  labs(title = "Emotion Count of User Generated Content",
      subtitle = "November 8th to November 29th 2022",
      caption = "Data Source: Twitter search for #LIVGolf")
emotion_plot_users + theme(axis.text.x = element_text(angle = 45, vjust = 1,
                                                hjust=1))

Conclusions

LIVGolf - As expected, LIVGolf emotion count is indicative of an organization attempting to gather followers, spread awareness of their brand, and is largely positive. The LIVGolf content is expressing anticipation for future events with an overall positive emotion.

Users - When analyzing user generated content, the dominant emotion is happiness but there is a significant increase in the negativity conveyed in the tweet. Additionally, emotions like sadness, anger, and fear also increased.

7. Text Analysis

The purpose of this section is to further understand the conversation and topics discussed in tweets from LIVGolf and from users during the collection period.

#Create Corpus for LIVGolf authored content.
text_LIV <- Corpus(VectorSource(LIVGolf$text_clean))
#Clean the text variable
text_LIV <- text_LIV %>%
  tm_map(removeNumbers) %>%
  tm_map(removePunctuation) %>%
  tm_map(stripWhitespace)
text_LIV <- tm_map(text_LIV, content_transformer(tolower))
text_LIV <- tm_map(text_LIV, removeWords, stopwords("english"))
text_LIV <- tm_map(text_LIV, removeWords, c("LIV", "LIVGolf", "livgolf",
                                            "httpstcoiflvyyalvx"))
#Create dataframes for the words used and capture the frequency of use.
dtm_LIV <- TermDocumentMatrix(text_LIV) 
matrix_text_LIV <- as.matrix(dtm_LIV) 
words_text_LIV <- sort(rowSums(matrix_text_LIV),decreasing=TRUE) 
df_text_LIV <- data.frame(word = names(words_text_LIV),freq=words_text_LIV)

Worldcloud - LIV Golf Authored Content

#Create Wordcloud of most frequently used words used in LIVGolf authored content.
wordcloud(words = df_text_LIV$word, freq = df_text_LIV$freq, min.freq = 2,           max.words=200,random.order=FALSE, rot.per=0.35,colors=brewer.pal(8,            "Dark2")) 

#Create Corpus for user generated content.
text_user <- Corpus(VectorSource(only_users$text_clean))
#Clean the text variable
text_user <- text_user %>%
  tm_map(removeNumbers) %>%
  tm_map(removePunctuation) %>%
  tm_map(stripWhitespace)
text_user <- tm_map(text_user, content_transformer(tolower))
text_user <- tm_map(text_user, removeWords, stopwords("english"))
text_user <- tm_map(text_user, removeWords, c("liv", "livgolfinv", "livgolf",
                                              "'s", "said", "day", "amp", 
                                              "can"))
#Create dataframes for the words used and capture the frequency of use.
dtm_user <- TermDocumentMatrix(text_user) 
matrix_text_user <- as.matrix(dtm_user) 
words_text_user <- sort(rowSums(matrix_text_user),decreasing=TRUE) 
df_text_user <- data.frame(word = names(words_text_user),freq=words_text_user)

Worldcloud - User Authored Content

#Create Wordcloud of most frequently used words used in LIVGolf authored content.
wordcloud(words = df_text_user$word, freq = df_text_user$freq, min.freq = 12,           max.words=200,random.order=FALSE, rot.per=0.35,colors=brewer.pal(8,            "Dark2"))

final_data %>% 
  unnest_tokens(output = word, input = text_clean) %>% 
  anti_join(stop_words) %>% 
  count(word, sort = TRUE) %>% 
  slice(1:10)
bigram_words <- final_data %>% 
  unnest_tokens(
    input = text_clean, 
    output = bigram, 
    token = 'ngrams', 
    n = 2) %>% 
  filter(! is.na(bigram))

bigram_words %>% 
  select(bigram) %>% 
  head(10)
bigram_words <- bigram_words %>% 
 separate(col = bigram, into = c('word1', 'word2'), sep = ' ')
bigram_count <- bigram_words %>% 
  count(bigram_words$word1, bigram_words$word2, sort = TRUE) %>% 
  rename(weight = n)

bigram_count %>% head()
ScaleWeight <- function(x, lambda) {
  x / lambda}
threshold <- 4

User Content Bigram

network <-  bigram_count %>%
  filter(weight == threshold) %>%
  mutate(weight == ScaleWeight(x = weight, lambda = 2E3)) %>%
  graph_from_data_frame(directed = FALSE)
plot(
  network, 
  vertex.size = 1,
  vertex.label.color = 'black', 
  vertex.label.cex = 0.5, 
  vertex.label.dist = 1,
  edge.color = 'gray', 
  main = 'Bigram Count Network', 
  sub = glue('Weight Threshold: {threshold}'), 
  alpha = 50)

Conclusions

Wordcloud LIVGOLF - Content generated by LIV Golf is largely comprised on words indicative of fostering excitement and attention to the series.

Wordcloud Users - Users expose a greater amount of word usage and emotions behind those words than LIV Golf. A high frequency of using PGA Tour by users can be indicative of either support or resentment for the competing league and may not necessarily advocate for either league. Additionally, there are word choices by users that very significantly from LIV Golf as they have attempted to distance themselves from Saudi Arabian connection. The users continue to talk about that topic.

Bigram Network - The Bigram network shows that the words used in speaking about LIV Golf represents a very divided user base between accepting LIV for the a sporting league or highlighting its connection to the government of Saudi Arabia.

8. Correlation

The purpose of this section is to understand if there is any connection between how well a tweet is received and its overall sentiment. This section should answer the question if the most negative or most positive tweets are more or less likely to be the content that is engaged with the most.

correlation_test <- subset(final_data, select = -c(day_created, screen_name, location, followers_count, friends_count, listed_count, favourites_count, statuses_count, source, retweet_count, retweet_ratio, favorite_ratio, favorite_count, text_clean))
#Determine relationship between reception and sentiment for entire data set
cor.matrix_a <- cor(correlation_test[1:2])
cor.matrix_a
##            reception  sentiment
## reception 1.00000000 0.08203386
## sentiment 0.08203386 1.00000000
#Eliminate excess variables
correlation_test_LIV <- subset(LIVGolf, select = -c(day_created, screen_name, location, followers_count, friends_count, listed_count, favourites_count, statuses_count, source, retweet_count, retweet_ratio, favorite_ratio, favorite_count, text_clean))
#Determine relationship between reception and sentiment for LIV Golf data frame
cor.matrixb <- cor(correlation_test_LIV[1:2])
cor.matrixb
##             reception   sentiment
## reception  1.00000000 -0.04597686
## sentiment -0.04597686  1.00000000
#Eliminate excess variables
correlation_test_only_users <- subset(only_users, select = -c(day_created, screen_name, location, followers_count, friends_count, listed_count, favourites_count, statuses_count, source, retweet_count, retweet_ratio, favorite_ratio, favorite_count, text_clean))
#Determine relationship between reception and sentiment for LIV Golf data frame
cor.matrixc <- cor(correlation_test_only_users[1:2])
cor.matrixc
##           reception sentiment
## reception 1.0000000 0.0874266
## sentiment 0.0874266 1.0000000

9. Linear Regression

The purpose of this section is to understand future activity from users on the platform by testing the connection between how frequently LIV Golf authors content and measuring the impact that has on motivating users to generate content.

I will create a model that will predict user activity based on the amount of activity from LIV Golf.

#x = number of posts each day by LIV Golf
#y = number of user posts
#For every one LIV Golf post we should expect a response of an additional 1.031 user posts.
x <- c(1,2,1,1,1,2,3,2,2,4,2,1,0,1,1,1,1,0,1,1,0,0)
y <- c(15,14,18,28,31,26,32,24,30,26,37,25,28,30,29,26,16,13,19,22,23,38)
LIV_user_relationship <- lm(y~x)
print(LIV_user_relationship)
## 
## Call:
## lm(formula = y ~ x)
## 
## Coefficients:
## (Intercept)            x  
##      23.687        1.031
data <- data.frame(y,x)
cor.matrixd <- cor(data[1:2])
cor.matrixd
##           y         x
## y 1.0000000 0.1450017
## x 0.1450017 1.0000000
summary(LIV_user_relationship)
## 
## Call:
## lm(formula = y ~ x)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -11.7500  -4.9687   0.2656   4.3047  14.3125 
## 
## Coefficients:
##             Estimate Std. Error t value      Pr(>|t|)    
## (Intercept)   23.687      2.510   9.436 0.00000000833 ***
## x              1.031      1.573   0.655          0.52    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 7.101 on 20 degrees of freedom
## Multiple R-squared:  0.02103,    Adjusted R-squared:  -0.02792 
## F-statistic: 0.4295 on 1 and 20 DF,  p-value: 0.5197
RSE <- 7.101
error <- RSE/mean(y)
error
## [1] 0.28404
a <- data.frame(x = 10)
result <- predict(LIV_user_relationship, a)
print(result)
##  1 
## 34

Linear Regression Plot

linear_plot <- ggplot(data, aes(x = x, y = y)) + 
  geom_point( color="#69b3a2") +
  geom_smooth(method=lm , color="red", se=TRUE) +
  theme(legend.position = "none") +
  xlab("Number of LIV Golf Tweets") +
  ylab("Number of User Tweets") +
  labs(title = "Linear Regression Model of LIVGolf and User Generated Content",
       subtitle = "November 8th to November 29th 2022",
       caption = "Data Source: Twitter search for #LIVGolf")
linear_plot 

Conclusion

If all other variables remain constant, there is a connection between how many tweets LIV Golf creates and the response from users on the platform. While this model describes the a relationship between users and LIVGolf twitter activity, from a business perspective, it paints the picture of an organization failing to motivate its followers to talk about their product and attract additional followers. If LIVGolf created zero tweets, it would be reasonable to expect 23 user generated tweets. However, as they become more active on the platform, their efforts are not returned at a very high rate, especially when considering the amount of followers they have. If users generate 10 tweets, it is reasonable to expect 34 user tweets, which may not be worth their time. The model created during this study creates an average prediction error rate of 28%.

LS0tCnRpdGxlOiAiTUJEQSBMSVYgR29sZiBQcm9qZWN0IgphdXRob3I6ICJEYXZpZCBDdXJ0aXMiCmRhdGU6ICIyMDIzLTAxLTIxIgpvdXRwdXQ6IAogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCi0tLQoKYGBge3IsIG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkocnR3ZWV0KQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkobHVicmlkYXRlKQpsaWJyYXJ5KFNlbnRpbWVudEFuYWx5c2lzKQpsaWJyYXJ5KGRsb29rcikKbGlicmFyeShocmJydGhlbWVzKQpsaWJyYXJ5KHZpcmlkaXMpCmxpYnJhcnkoc3RyaW5ncikKbGlicmFyeSh0aWR5dGV4dCkKbGlicmFyeSh0bSkKbGlicmFyeSh0b2tlbml6ZXJzKQpsaWJyYXJ5KHdvcmRjbG91ZCkKbGlicmFyeSh0aWR5cikKbGlicmFyeShnbHVlKQpsaWJyYXJ5KGlncmFwaCkKbGlicmFyeShzeXV6aGV0KQpgYGAKCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQojaW1wb3J0IGRhdGFzZXQKZmluYWxfZGF0YSA8LSByZWFkLmNzdigiZmluYWxfZGF0YSIpCmBgYAoKIyMgMS4gQ2xlYW5pbmcgYW5kIG1hbmlwdWxhdGluZyBkYXRhCgpUaGUgcHVycG9zZSBvZiB0aGlzIHByb2Nlc3Mgd2lsbCBiZSB0byByZW1vdmUgYWxsIHVubmVjZXNzYXJ5IHZhcmlhYmxlcyBub3QgcmVxdWlyZWQgZm9yIHJlc2VhcmNoIGFzIHdlbGwgYXMgY3JlYXRlIGFkZGl0aW9uYWwgdmFyaWFibGVzIG9mIHNlbnRpbWVudCBhbmQgcmVjZXB0aW9uLCB0aGVuIHNwbGl0IHRoZSBkYXRhIGZyYW1lIGJhc2VkIG9uIHRoZSBzb3VyY2Ugb2YgZWFjaCB0d2VldC4KCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQojUmVtb3ZlIGR1cGxpY2F0ZSB2YXJpYWJsZXMKZmluYWxfZGF0YSA8LSBzdWJzZXQoZmluYWxfZGF0YSwgc2VsZWN0ID0gLWMoWCwgbmFtZSwgYWNjb3VudF9jcmVhdGVkX2F0KSkKCiNkZWxldGUgaXJyZWxldmFudCB0d2VldHMgZnJvbSBib3RzIGFuZCBhZHMsIG9yIGZvbGxvd2VycyA9PSAwCmZpbmFsX2RhdGEgPC0gc3Vic2V0KGZpbmFsX2RhdGEsIHNjcmVlbl9uYW1lIT0gIkJlbjA5NzgzOTUyIikKZmluYWxfZGF0YSA8LSBzdWJzZXQoZmluYWxfZGF0YSwgc2NyZWVuX25hbWUhPSAiTmV3ODA1R3V5IikKZmluYWxfZGF0YSA8LSBzdWJzZXQoZmluYWxfZGF0YSwgc2NyZWVuX25hbWUhPSAiY29obnNpbnMiKQpmaW5hbF9kYXRhIDwtIHN1YnNldChmaW5hbF9kYXRhLCBzY3JlZW5fbmFtZSE9ICJwbHVtY3JhenkxMyIpCmZpbmFsX2RhdGEgPC0gc3Vic2V0KGZpbmFsX2RhdGEsIHNjcmVlbl9uYW1lIT0gIk1IUzk4ODc3ODEyIikKZmluYWxfZGF0YSA8LSBzdWJzZXQoZmluYWxfZGF0YSwgc2NyZWVuX25hbWUhPSAiZml0Z29sZmVyZ2lybCIpCmZpbmFsX2RhdGEgPC0gc3Vic2V0KGZpbmFsX2RhdGEsIHNjcmVlbl9uYW1lIT0gImFnb256YWxlemZsIikKZmluYWxfZGF0YSA8LSBzdWJzZXQoZmluYWxfZGF0YSwgc2NyZWVuX25hbWUhPSAiTG9mdHlMbGFtYUdvbGYiKQpmaW5hbF9kYXRhIDwtIHN1YnNldChmaW5hbF9kYXRhLCBzY3JlZW5fbmFtZSE9ICJEdWZmaW5VcCIpCmZpbmFsX2RhdGEgPC0gc3Vic2V0KGZpbmFsX2RhdGEsIHNjcmVlbl9uYW1lIT0gIkxGU3RldmllMSIpCmZpbmFsX2RhdGEgPC0gc3Vic2V0KGZpbmFsX2RhdGEsIHNjcmVlbl9uYW1lIT0gIkV4cG9zZTE5OTYiKQpmaW5hbF9kYXRhIDwtIHN1YnNldChmaW5hbF9kYXRhLCBzY3JlZW5fbmFtZSE9ICJHZW9yZ2VENzk3MTY0NTMiKQpmaW5hbF9kYXRhIDwtIHN1YnNldChmaW5hbF9kYXRhLCAKICAgICAgICAgICAgICAgICAgICAgc2NyZWVuX25hbWUhPSAiQW5vbnltbzQwMzY0MDUzIikKZmluYWxfZGF0YSA8LSBzdWJzZXQoZmluYWxfZGF0YSwgc2NyZWVuX25hbWUhPSAiVGh5c0xvdXJlbnMxNCIpCmZpbmFsX2RhdGEgPC0gc3Vic2V0KGZpbmFsX2RhdGEsIHNjcmVlbl9uYW1lIT0gIlBpbkhpZ2hNZWRpYSIpCmZpbmFsX2RhdGEgPC0gc3Vic2V0KGZpbmFsX2RhdGEsIHNjcmVlbl9uYW1lIT0gIkFuZHlDb2xxIikKZmluYWxfZGF0YSA8LSBzdWJzZXQoZmluYWxfZGF0YSwgc2NyZWVuX25hbWUhPSAiWEdvbGZPcmxhbmRQYXJrIikKCiNmb3JtYXQgdGhlIGNyZWF0ZWRfYXQgdmFyaWFibGUgaW50byBhIHVzYWJsZSBmb3JtYXQuCmZpbmFsX2RhdGEkY3JlYXRlZF9hdC4xIDwtIHltZF9obXMoZmluYWxfZGF0YSRjcmVhdGVkX2F0LjEpCgojQmluZCBkYXkgdmFyaWFibGUgaW50byBvcmlnaW5hbCBkYXRhIGZyYW1lCmRheV9jcmVhdGVkIDwtIGRheShmaW5hbF9kYXRhJGNyZWF0ZWRfYXQuMSkKZmluYWxfZGF0YSA8LWNiaW5kKGRheV9jcmVhdGVkLCBmaW5hbF9kYXRhKQpmaW5hbF9kYXRhIDwtIHN1YnNldChmaW5hbF9kYXRhLCBzZWxlY3QgPSAtYyhjcmVhdGVkX2F0LjEpKQoKI2NyZWF0ZSBhIGRhdGEgZnJhbWUgd2l0aCByZWxldmFudCB2YXJpYWJsZXMgdG8gaWRlbnRpZnkgdGhlIHNvdXJjZSBvZiBlYWNoIHR3ZWV0LgpmaW5hbF9zb3VyY2UgPC0gZmluYWxfZGF0YSAlPiUgCiAgc2VsZWN0KHNvdXJjZSwgdGV4dCwgc2NyZWVuX25hbWUpIApgYGAKCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQojQ2xlYW4gc291cmNlIHZhcmlhYmxlIGZvciBmdXR1cmUgYW5hbHlzaXMKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJcXCQiLCAiIiwgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJAXFx3KyIsICIiLCBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoIltbOnB1bmN0Ol1dIiwiIiwgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJodHRwd3d3IiwgIiIsIGZpbmFsX3NvdXJjZSRzb3VyY2UpCmZpbmFsX3NvdXJjZSRzb3VyY2UgPC0gZ3N1YigiWyB8XHRdezIsfSIsICIiLCBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlPC0gZ3N1YigiXiAiLCAiIiwgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZTwtIGdzdWIoIiAkIiwgIiIsIGZpbmFsX3NvdXJjZSRzb3VyY2UpCmZpbmFsX3NvdXJjZSRzb3VyY2UgPC0gZ3N1YigiUlQiLCIiLCBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoImhyZWYiLCAiIiwgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCIoWzAtOV0pIiwiIiwgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJyZWxub2ZvbGxvd1R3aXR0ZXIiLCIiLCBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoImZvciIsIiIsIGZpbmFsX3NvdXJjZSRzb3VyY2UpCmZpbmFsX3NvdXJjZSRzb3VyY2UgPC0gZ3N1YigiQXBwIiwiIiwgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCIgIiwiIiwgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJhc29jaWFsYmFrZXJzY29tcmVsbm9mb2xsb3ciLCIiLAogIGZpbmFsX3NvdXJjZSRzb3VyY2UpCmZpbmFsX3NvdXJjZSRzb3VyY2UgPC0gZ3N1YigiYWh0dHBzc3R1ZGlvdHdpdHRlcmNvbSIsIiIsCiAgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJhaHR0cHR3aXR0ZXJjb21kb3dubG9hZGlwaG9uZSIsIiIsCiAgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJhaHR0cHN3d3dzcG9ydG5ld3NjZW50cmFsY29tcmVsbm9mb2xsb3ciLCIiLAogIGZpbmFsX3NvdXJjZSRzb3VyY2UpCmZpbmFsX3NvdXJjZSRzb3VyY2UgPC0gZ3N1YigiYWh0dHBzaHlwZWZ1cnljb21yZWxub2ZvbGxvdyIsIiIsCiAgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJhaHR0cHNtb2JpbGV0d2l0dGVyY29tIiwiIiwKICBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoImFodHRwdHdpdHRlcmNvbWRvd25sb2FkYW5kcm9pZCIsIiIsCiAgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJhaHR0cHN3d3dob290c3VpdGVjb21yZWxub2ZvbGxvdyIsIiIsCiAgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJhaHR0cHN0d2l0dGVyY29tcmVsbm9mb2xsb3ciLCIiLAogIGZpbmFsX3NvdXJjZSRzb3VyY2UpCmZpbmFsX3NvdXJjZSRzb3VyY2UgPC0gZ3N1YigiYWh1YnNwb3Rjb21yZWxub2ZvbGxvdyIsIiIsCiAgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJhaHR0cHNpZnR0dGNvbXJlbG5vZm9sbG93IiwiIiwKICBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoImFodHRwc2J1ZmZlcmNvbXJlbG5vZm9sbG93IiwiIiwKICBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtCiAgZ3N1YigiYWh0dHBzYWJvdXR0d2l0dGVyY29tcHJvZHVjdHN0d2VldGRlY2tyZWxub2ZvbGxvdyIsIiIsCiAgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJhaHR0cHN3d3dzcHJlYWtlcmNvbXJlbG5vZm9sbG93IiwiIiwKICBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoImFodHRwdHdpdHRlcmNvbWRvd25sb2FkaXBhZCIsIiIsCiAgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJhaHR0cHNkbHZyaXRjb21yZWxub2ZvbGxvdyIsIiIsCiAgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJhaHR0cHN3d3d0d2VldGVkdGltZXNjb21yZWxub2ZvbGxvdyIsIiIsCiAgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJhaHR0cGdhaW5hcHBjb21yZWxub2ZvbGxvdyIsIiIsCiAgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJhaHR0cHN0d2l0dGVyY29tIiwiIiwKICBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoImFodHRwc3d3d3NwcmVkZmFzdGNvbXJlbG5vZm9sbG93IiwiIiwKICBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoImFodHRwaW5zdGFncmFtY29tcmVsbm9mb2xsb3ciLCIiLAogIGZpbmFsX3NvdXJjZSRzb3VyY2UpCmZpbmFsX3NvdXJjZSRzb3VyY2UgPC0gZ3N1YigiYWh0dHBwdWJsaWNpemV3cGNvbXJlbG5vZm9sbG93IiwiIiwKICBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoImFwb3dlcmFwcHNjb21yZWxub2ZvbGxvdyIsIiIsCiAgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJhaHR0cHNzb2NpYWx6b2hvY29tcmVsbm9mb2xsb3ciLCIiLAogIGZpbmFsX3NvdXJjZSRzb3VyY2UpCmZpbmFsX3NvdXJjZSRzb3VyY2UgPC0gZ3N1YigiYWh0dHBzdXBzdHJhY3Rjb21yZWxub2ZvbGxvdyIsIiIsCiAgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJhaHR0cHN3d3dtZWV0c29jaWNvbXJlbG5vZm9sbG93IiwiIiwKICBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoImF0b2JlYW5ub3VuY2VkY29tcmVsbm9mb2xsb3ciLCIiLAogIGZpbmFsX3NvdXJjZSRzb3VyY2UpCmZpbmFsX3NvdXJjZSRzb3VyY2UgPC0gCiAgZ3N1YigiYWh0dHBzaGFqaW1lbWFuYWJ1aW5mb3JlbG5vZm9sbG93d3B0d2l0dGVyYXBwYSIsIkFkdmVydGlzZW1lbnQiLAogIGZpbmFsX3NvdXJjZSRzb3VyY2UpCmZpbmFsX3NvdXJjZSRzb3VyY2UgPC0gCiAgZ3N1YigiYWh0dHBzaGFqaW1lbWFuYWJ1aW5lbG5vZm9sbG93d3B0d2l0dGVyYXBwYSIsIkFkdmVydGlzZW1lbnQiLAogIGZpbmFsX3NvdXJjZSRzb3VyY2UpCmBgYAoKYGBge3IsIGluY2x1ZGU9RkFMU0V9CiNCaW4gZWFjaCBvZiB0aGUgc291cmNlcyBpbnRvIGEgdHdlZXQgZ2VuZXJhdGVkIGJ5IGEgdXNlciwgbWVkaWEsIGFkdmVydGlzZW1lbnQsIG9yIHRoZSBvcmdhbml6YXRpb24gIkxJViBHb2xmIi4gCmZpbmFsX3NvdXJjZSRzb3VyY2UgPC0gZ3N1YigiV2ViYSIsICJVc2VyIiwgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJpUGhvbmVhIiwgIlVzZXIiLCBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoIkFuZHJvaWRhIiwgIlVzZXIiLCBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoImlQYWRhIiwgIlVzZXIiLCBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoIkVtcGxpZmlhIiwgIlVzZXIiLCBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoIkJ1ZmZlcmEiLCAiQWR2ZXJ0aXNlbWVudCIsIGZpbmFsX3NvdXJjZSRzb3VyY2UpCmZpbmFsX3NvdXJjZSRzb3VyY2UgPC0gZ3N1YigiSW5zdGFncmFtYSIsICJBZHZlcnRpc2VtZW50IiwgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJwdHdpdHRlcmFwcGEiLCAiQWR2ZXJ0aXNlbWVudCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoIlNPQ2lhIiwgIkFkdmVydGlzZW1lbnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJXb3JkUHJlc3Njb21hIiwgIkFkdmVydGlzZW1lbnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJBZHZlcnRpc2Vyc2EiLCAiTWVkaWEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJab2hvU29jaWFsYSIsICJNZWRpYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoIlR3ZWV0RGVja1VzZXIiLCAiTWVkaWEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJUd2VldERlY2thIiwgIk1lZGlhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsX3NvdXJjZSRzb3VyY2UpCmZpbmFsX3NvdXJjZSRzb3VyY2UgPC0gZ3N1YigiVGhlVHdlZXRlZFRpbWVzYSIsICJNZWRpYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoIlNwcmVha2VyYSIsICJNZWRpYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoInNwb3J0Y250cmxib3RhIiwgIk1lZGlhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsX3NvdXJjZSRzb3VyY2UpCmZpbmFsX3NvdXJjZSRzb3VyY2UgPC0gZ3N1YigiTWljcm9zb2Z0UG93ZXJQbGF0bWEiLCAiTWVkaWEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJNZWRpYVN0dWRpb2EiLCAiTWVkaWEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJLaG9yb3NQdWJsaXNoaW5nYSIsICJNZWRpYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoIkh5cGVmdXJ5YSIsICJNZWRpYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoIkh5cGVmdXJ5YSIsICJNZWRpYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoImRsdnJpdGEiLCAiTWVkaWEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJHYWluUGxhdG1hIiwgIk1lZGlhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsX3NvdXJjZSRzb3VyY2UpCmZpbmFsX3NvdXJjZSRzb3VyY2UgPC0gZ3N1YigiSUZUVFRhIiwgIk1lZGlhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsX3NvdXJjZSRzb3VyY2UpCmZpbmFsX3NvdXJjZSRzb3VyY2UgPC0gZ3N1YigiSHViU3BvdGEiLCAiTWVkaWEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJIb290c3VpdGVJbmNhIiwgIk1lZGlhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsX3NvdXJjZSRzb3VyY2UpCmZpbmFsX3NvdXJjZSRzb3VyY2UgPC0gZ3N1YigiYWh0dHBpdHVuZXNhcHBsZWNvbXVzYXBwdHdpdHRlcmlkbXRNYWNhIiwgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWVkaWEiLCBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoIkVkZ2VFbGVjdGlvblBvZCIsICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1lZGlhIiwgZmluYWxfc291cmNlJHNvdXJjZSkKZmluYWxfc291cmNlJHNvdXJjZSA8LSBnc3ViKCJOZXdzVXNlcnNhIiwgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWVkaWEiLCBmaW5hbF9zb3VyY2Ukc291cmNlKQpmaW5hbF9zb3VyY2Ukc291cmNlIDwtIGdzdWIoIlVwc3RyYWN0TmV3c0Jyb2FkY2FzdGEiLCAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNZWRpYSIsIGZpbmFsX3NvdXJjZSRzb3VyY2UpCmZpbmFsX3NvdXJjZSRzb3VyY2VbZmluYWxfc291cmNlJHNjcmVlbl9uYW1lID09ICJMSVZHb2xmSW52Il0gPC0gIkxJVkdvbGYiCmZpbmFsX3NvdXJjZSRzb3VyY2VbZmluYWxfc291cmNlJHNjcmVlbl9uYW1lID09ICJGaWVsZExldmVsTWVkaWEiXSA8LSAiTWVkaWEiCmBgYAoKYGBge3J9CiNSZW5hbWUgc291cmNlIHZhcmlhYmxlIGFzIHNvdXJjZV9jbGVhbiwgYW5kIGJpbmQgaXQgdG8gdGhlIGZpbmFsIGRhdGFzZXQuCmZpbmFsX2RhdGEgPC0gY2JpbmQoZmluYWxfc291cmNlJHNvdXJjZSwgZmluYWxfZGF0YSkKbmFtZXMoZmluYWxfZGF0YSlbMV0gPSAic291cmNlX2NsZWFuIgpmaW5hbF9kYXRhIDwtIHN1YnNldChmaW5hbF9kYXRhLCBzZWxlY3QgPSAtYyhzb3VyY2UpKQpuYW1lcyhmaW5hbF9kYXRhKVsxXSA9ICJzb3VyY2UiCmBgYAoKYGBge3J9CiNHZW5lcmF0ZSByZWNlcHRpb24gc2NvcmVzCm9wdGlvbnMoc2NpcGVuID0gOTk5KQoKI0dlbmVyYXRlIHJldHdlZXQgcmF0aW8KZmluYWxfZGF0YSRyZXR3ZWV0X3JhdGlvIDwtCiAgKGZpbmFsX2RhdGEkcmV0d2VldF9jb3VudCoyL2ZpbmFsX2RhdGEkZm9sbG93ZXJzX2NvdW50KSAqIDEwMAoKI0dlbmVyYXRlIGZhdm9yaXRlIHJhdGlvCmZpbmFsX2RhdGEkZmF2b3JpdGVfcmF0aW8gPC0KICAoZmluYWxfZGF0YSRmYXZvcml0ZV9jb3VudC9maW5hbF9kYXRhJGZvbGxvd2Vyc19jb3VudCkgKiAxMDAKCiNHZW5lcmF0ZSByZWNlcHRpb24gc2NvcmUgZm9yIGVhY2ggdHdlZXQuCmZpbmFsX2RhdGEkcmVjZXB0aW9uIDwtIGFwcGx5KGZpbmFsX2RhdGFbMTQ6MTVdLCAxLCBtZWFuLCBuYS5ybSA9IFRSVUUpCmBgYAoKYGBge3J9CiNUcmFuc2Zvcm0gdGhlIHRleHQgdmlhYmxlIGludG8gYSB1c2FibGUgZm9ybS4KdGV4dF9jb3JwdXMgPC0gQ29ycHVzKFZlY3RvclNvdXJjZShmaW5hbF9kYXRhJHRleHQpKQp0ZXh0X2NvcnB1cyA8LSB0bV9tYXAodGV4dF9jb3JwdXMsIHRvbG93ZXIpCnRleHRfY29ycHVzIDwtIHRtX21hcCh0ZXh0X2NvcnB1cywgcmVtb3ZlV29yZHMsIHN0b3B3b3JkcygiZW5nbGlzaCIpKQp0ZXh0X2NvcnB1cyA8LSB0bV9tYXAodGV4dF9jb3JwdXMsIHJlbW92ZVB1bmN0dWF0aW9uKQp0ZXh0X2RmIDwtIGRhdGEuZnJhbWUodGV4dF9jbGVhbiA9IGdldCgiY29udGVudCIsIHRleHRfY29ycHVzKSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQpmaW5hbF9kYXRhIDwtIGNiaW5kLmRhdGEuZnJhbWUoZmluYWxfZGF0YSwgdGV4dF9kZikKCiNSZW1vdmUgcmVkdW5kYW50IHRleHQgdmFyaWFibGUgImZ1bGxfdGV4dCIKZmluYWxfZGF0YSA8LSBzdWJzZXQoZmluYWxfZGF0YSwgc2VsZWN0PSAtYyh0ZXh0LCBmdWxsX3RleHQpKQoKI2NyZWF0ZSBzZW50aW1lbnQgZGF0YWZyYW1lCnNlbnRpbWVudCA8LSBhbmFseXplU2VudGltZW50KGZpbmFsX2RhdGEkdGV4dF9jbGVhbikKCiNiaW5kIGFuZCByZW5hbWUgc2VudGltZW50IHNjb3JlcyB0byBkYXRhc2V0CmZpbmFsX2RhdGEgPC0gY2JpbmQoZmluYWxfZGF0YSwgc2VudGltZW50JFNlbnRpbWVudEdJKQpuYW1lcyhmaW5hbF9kYXRhKVsxNl0gPSAic2VudGltZW50IgpgYGAKCmBgYHtyfQojcmVvcmRlciB2YXJpYWJsZXMgaW4gZGF0YWZyYW1lCmZpbmFsX2RhdGEgPC0gZmluYWxfZGF0YVssIGMoMiwzLDQsMTUsMSw1LDYsNyw4LDksMTAsMTEsMTIsMTMsMTQsMTYpXQpgYGAKCmBgYHtyfQojQ3JlYXRlIG5ldyBkYXRhIGZyYW1lcyBmb3IgZnV0dXJlIGFuYWx5c2lzLgoKI0RhdGEgZnJhbWUgZm9yIHVzZXJzCm9ubHlfdXNlcnMgPC0gZmluYWxfZGF0YVtmaW5hbF9kYXRhJHNvdXJjZSA9PSAiVXNlciIsIF0KCiNEYXRhIGZyYW1lIGZvciBMSVZHb2xmSW52CkxJVkdvbGYgPC0gZmluYWxfZGF0YVtmaW5hbF9kYXRhJHNjcmVlbl9uYW1lID09ICJMSVZHb2xmSW52IiwgXQoKI0RhdGEgZnJhbWUgZm9yIG1lZGlhCm1lZGlhIDwtIGZpbmFsX2RhdGFbZmluYWxfZGF0YSRzb3VyY2UgPT0gIk1lZGlhIiwgXQpgYGAKCiMjIDIuIEV4cGxvcmF0b3J5IEFuYWx5c2lzCgpUaGUgcHVycG9zZSBvZiB0aGlzIHByb2Nlc3MgaXMgdG8gdW5kZXJzdGFuZCBiYXNpYyBwcm9wZXJ0aWVzIG9mIHRoZSBkYXRhc2V0IGFuZCBiZWdpbiB0byB1bmRlcnN0YW5kIHdoYXQgaW5mb3JtYXRpb24gdGhlIGRhdGFzZXQgY29udGFpbnMuCgpgYGB7cn0KI0lkZW50aWZ5IHRoZSBxdWFudGl0eSBvZiB0d2VldHMgZnJvbSBlYWNoIHNvdXJjZS4KZmluYWxfc291cmNlICU+JSBncm91cF9ieShzb3VyY2UpICU+JSBjb3VudChzb3VyY2UsIHNvcnQgPSBUUlVFKQpgYGAKCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQojSWRlbnRpZnkgZWFjaCB1c2VycyBjb250cmlidXRpb24gdG8gdGhlIGRhdGFzZXQuIApmaW5hbF9kYXRhICU+JSBncm91cF9ieShzY3JlZW5fbmFtZSkgJT4lIGNvdW50KHNjcmVlbl9uYW1lLCBzb3J0ID0gVFJVRSkKYGBgCgpgYGB7ciwgaW5jbHVkZT1GQUxTRX0KI0lkZW50aWZ5IGRpc3RyaWJ1dGlvbiBvZiB0d2VldHMgb3ZlciB0aW1lLgpmaW5hbF9kYXRhICU+JSBncm91cF9ieShkYXlfY3JlYXRlZCkgJT4lIGNvdW50KGRheV9jcmVhdGVkLCBzb3J0ID0gRkFMU0UpCmRheV9jcmVhdGVkCmBgYAoKYGBge3J9CiNJZGVudGlmeSBhc3BlY3RzIG9mIHRoZSBmYXZvcml0ZV9jb3VudCB2YXJpYWJsZS4KZmF2b3JpdGVzX3dfdXNlciA8LSBzZWxlY3QoZmluYWxfZGF0YSwgc2NyZWVuX25hbWUsIGZhdm9yaXRlX2NvdW50KQphcnJhbmdlKGZhdm9yaXRlc193X3VzZXIsIGRlc2MoZmF2b3JpdGVfY291bnQpKQpgYGAKCmBgYHtyfQojSWRlbnRpZnkgYXNwZWN0cyBvZiB0aGUgcmV0d2VldF9jb3VudCB2YXJpYWJsZS4KcmV0d2VldHNfd191c2VyIDwtIHNlbGVjdChmaW5hbF9kYXRhLCBzY3JlZW5fbmFtZSwgcmV0d2VldF9jb3VudCkKYXJyYW5nZShyZXR3ZWV0c193X3VzZXIsIGRlc2MocmV0d2VldF9jb3VudCkpCmBgYAoKIyMjIENvbmNsdXNpb25zCgpTb3VyY2UgVmFyaWFibGUgLSBMSVZHb2xmIGhhcyBzZXZlcmFsIGh1bmRyZWQgdGhvdXNhbmQgZm9sbG93ZXJzLCBidXQgdGhvc2UgZm9sbG93ZXJzIG9ubHkgY3JlYXRlIGEgdmVyeSBzbWFsbCBhbW91bnQgb2YgY29udmVyc2F0aW9uIGFib3V0IHRoZSBzZXJpZXMuIFdoaWxlIHVzZXJzIGFzIGEgd2hvbGUgY3JlYXRlIGEgbGFyZ2VyIHRvdGFsIHF1YW50aXR5IG9mIHR3ZWV0cywgdGhyb3VnaG91dCB0aGUgb2JzZXJ2YXRpb24gcGVyaW9kLCBubyBvdGhlciB1c2VyIGNyZWF0ZWQgYXMgbWFueSB0d2VldHMgYWJvdXQgTElWR29sZiB0aGFuIHRoZSBhY2NvdW50ICJMSVZHb2xmSW52Ii4KClJldHdlZXQgVmFyaWFibGUgLSBBcyBleHBlY3RlZCwgdGhlIHVzZXJzIHdpdGggdGhlIGhpZ2hlc3QgYW1vdW50IG9mIGZvbGxvd2VycyBnYXJuZXJlZCB0aGUgaGlnaGVzdCBudW1iZXIgb2YgcmV0d2VldHMgcGVyIHBvc3QuIEl0IGlzIHVuZXhwZWN0ZWQgdGhlIGFtb3VudCBvZiByZXR3ZWV0cyB0aGF0IExJVkdvbGYgY29udGVudCBjcmVhdGVzIGFtb25nIHRoZWlyIGZvbGxvd2Vycy4KCkZhdm9yaXRlX2NvdW50IFZhcmlhYmxlIC0gQXMgZXhwZWN0ZWQsIHRoZSB1c2VycyB3aXRoIHRoZSBoaWdoZXN0IGFtb3VudCBvZiBmb2xsb3dlcnMgZ2FybmVyZWQgdGhlIGhpZ2hlc3QgbnVtYmVyIG9mIGZhdm9yaXRlcyBwZXIgdHdlZXQuIEl0IGlzIHVuZXhwZWN0ZWQgdGhhdCBMSVZHb2xmIGNvbnRlbnQgY3JlYXRlcyBzdWNoIGEgcmVsYXRpdmVseSBzbWFsbCBhbW91bnQgb2YgbGlrZXMgaW4gcmVsYXRpb24gdG8gdGhlaXIgZm9sbG93ZXIgY291bnQuCgpBZGRpdGlvbmFsIGFuYWx5c2lzIGlzIHJlcXVpcmVkIHRvIHVuZGVyc3RhbmQgd2h5IHVzZXJzIHdpdGggc2lnbmlmaWNhbnRseSBzbWFsbGVyIGFtb3VudHMgb2YgZm9sbG93ZXJzIHJlY2lldmVkIGEgY29tcGFyYWJsZSBhbW91bnQgb2YgZmF2b3JpdGVzLCBzcGVjaWZpY2FsbHkgdGhlIHVzZXJzICIyMHRoQ2VudHVyeURhbiIgYW5kICJBbmRyZXdLaXJieUdvbGYiLiBXaGF0IGlzIGl0IGFib3V0IHRob3NlIHR3byB0d2VldHMgdGhhdCBnZW5lcmF0ZWQgZW5nYWdlbWVudCBmcm9tIHRoaWVyIGZvbGxvd2VycyBhbmQgaXMgaXQgaW5kaWNhdGl2ZSBvZiB0aGUgcmVjZXB0aW9uIG9mIExJVkdvbGY/CgojIyAzLiBGcmVxdWVuY3kgQW5hbHlzaXMKClRoZSBwdXJwb3NlIG9mIHRoZSBmcmVxdWVuY3kgYW5hbHlzaXMgaXMgdG8gZGV0ZXJtaW5lIHRvIGFtb3VudCBvZiBjb252ZXJzYXRpb24gb3ZlciB0aW1lIGFib3V0IExJViBnb2xmIGFuZCB0byBkZXRlcm1pbmUgaG93IG11Y2ggb2YgdGhlIGNvbnZlcnNhdGlvbiBpcyBjb250cmlidXRlZCB0byBMSVZHb2xmIGNyZWF0aW5nIHRoZSBjb252ZXJzYXRpb24sIG1lZGlhIHJlcG9ydGluZyBvbiBMSVZHb2xmLCBhbmQgdXNlciBnZW5lcmF0ZWQgY29udGVudCBhYm91dCB0aGUgTElWR29sZiB0b3BpYy4KCmBgYHtyfQpzb3VyY2VfYnlfdHlwZSA8LSBmaW5hbF9kYXRhICU+JSBncm91cF9ieShkYXlfY3JlYXRlZCwgc291cmNlKSAlPiUKICBzdW1tYXJpc2UodG90YWxfY291bnQgPSBuICgpLCAuZ3JvdXBzID0gImtlZXAiKSAlPiUKICBhcy5kYXRhLmZyYW1lKCkKc291cmNlX2J5X3R5cGUKYGBgCgojIyMgRnJlcXVlbmN5IFBsb3QgQWN0aXZpdHkKCmBgYHtyfQpoaXN0b2dyYW1fYWxsX3Bsb3QgPC0gZ2dwbG90KHNvdXJjZV9ieV90eXBlLCBhZXMoeCA9IGRheV9jcmVhdGVkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSB0b3RhbF9jb3VudCkpICsKICBnZW9tX2JhcihhZXMoY29sb3IgPSBzb3VyY2UsIGZpbGwgPSBzb3VyY2UpLCBzdGF0ID0gImlkZW50aXR5IiwgCiAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjaygpKSArCiAgbGFicyh0aXRsZSA9ICJTb3VyY2Ugb2YgTElWR29sZiBDb250ZW50IiwKICAgICAgc3VidGl0bGUgPSAiTm92ZW1iZXIgOHRoIHRvIE5vdmVtYmVyIDI4dGggMjAyMiIsCiAgICAgIGNhcHRpb24gPSAiRGF0YSBTb3VyY2U6IFR3aXR0ZXIgc2VhcmNoIGZvciAjTElWR29sZiIpICsKICBsYWJzKHkgPSAiRGFpbHkgQ291bnQiLCB4ID0gIkRhdGUgQ3JlYXRlZCIpCmhpc3RvZ3JhbV9hbGxfcGxvdCArIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5LDIwLDIxLDIyLDIzLDI0LDI1LDI2LDI3LDI4LDI5KSkgCmBgYAoKIyMjIEN1bXVsYXRpdmUgUmVsYXRpdmUgRnJlcXVlbmN5IFBsb3QKCmBgYHtyfQpyZWxfZnJlcV9wbG90IDwtIGdncGxvdChzb3VyY2VfYnlfdHlwZSwgYWVzKHggPSBkYXlfY3JlYXRlZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHRvdGFsX2NvdW50KSkgKwogIGdlb21fYmFyKGFlcyhjb2xvciA9IHNvdXJjZSwgZmlsbCA9IHNvdXJjZSksIHN0YXQgPSAiaWRlbnRpdHkiLCAKICAgICAgICAgICBwb3NpdGlvbiA9ICJmaWxsIikgKwogIGxhYnModGl0bGUgPSAiUmVsYXRpdmUgRnJlcXVlbmN5IG9mIFNvdXJjZSIsCiAgICAgIHN1YnRpdGxlID0gIk5vdmVtYmVyIDh0aCB0byBOb3ZlbWJlciAyOXRoIDIwMjIiLAogICAgICBjYXB0aW9uID0gIkRhdGEgU291cmNlOiBUd2l0dGVyIHNlYXJjaCBmb3IgI0xJVkdvbGYiKSArCiAgbGFicyh5ID0gIlBlcmNlbnQgb2YgVHdlZXRzIiwgeCA9ICJEYXRlIENyZWF0ZWQiKQpyZWxfZnJlcV9wbG90ICsgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9CiAgICAgICAgYyg4LDksMTAsMTEsMTIsMTMsMTQsMTUsMTYsMTcsMTgsMTksMjAsMjEsMjIsMjMsMjQsMjUsMjYsMjcsMjgsMjkpKSAgICAgICAKYGBgCgojIyMgQ29uY2x1c2lvbnMKCk1lZGlhIENvbnRyaWJ1dG9ycy0gTWVkaWEgcmVwb3J0aW5nIGFib3V0IExJVkdvbGYgc2F3IGEgcGVhayBmcm9tIHRoZSAxM3RoIHRvIHRoZSAxN3RoIG9mIE5vdmVtYmVyLiBBZGRpdGlvbmFsIGFuYWx5c2lzIGlzIHJlcXVpcmVkIHRvIGRldGVybWluZSB0aGUgdG9waWMgb2YgY29udmVyc2F0aW9uIGZvciBtZWRpYSB0d2VldHMuCgpBbGwgQ29udHJpYnV0b3JzIC0gVGhlIGhpZ2hlc3QgbGV2ZWwgb2YgYWN0aXZpdHkgc2VlbiBvbiB0aGUgVHdpdHRlciBwbGF0Zm9ybSBmcm9tIExJVkdvbGYgd2FzIG9uIHRoZSAxN3RoIGFuZCAxNHRoIG9mIE5vdmVtYmVyLgoKVXNlciBDb250cmlidXRpb24gLSBUaGUgaGlnaGVzdCBsZXZlbCBvZiBhY3Rpdml0eSBzZWVuIG9uIHRoZSBwbGF0Zm9ybSBmcm9tIHVzZXJzIHdhcyBvbiB0aGUgMTh0aCBhbmQgb2YgTm92ZW1iZXIuIEFkZGl0aW9uYWwgYW5hbHlzaXMgY291bGQgYmUgY29uZHVjdGVkIHRvIHVuZGVyc3RhbmQgY29udGVudCBvbiB0aGUgMTh0aCBvZiBOb3ZlbWJlciB0byBncmVhdGVyIHVuZGVyc3RhbmQgd2hhdCBtb3RpdmF0ZWQgdXNlcnMgdG8gcG9zdCBhYm91dCBMSVZHb2xmLiBMaXZHb2xmIENvbnRyaWJ1dGlvbi0gVGhlIGhpZ2hlc3QgdG90YWwgbnVtYmVyIG9mIHR3ZWV0cyBmcm9tIExJdkdvbGYgb2NjdXJyZWQgb24gdGhlIDE3dGggb2YgTm92ZW1iZXIuCgpBZGRpdGlvbmFsIGFuYWx5c2lzIGlzIHJlcXVpcmVkIHRvIHVuZGVyc3RhbmQgdGhlIGNvbnZlcnNhdGlvbiBhYm91dCBMSVZHb2xmIGR1cmluZyB0aGUgcGVhayBjb252ZXJzYXRpb25hbCBkYXRlcy4gSXQgaXMgcG9zc2libGUgdG8gZXhwbG9yZSB0aGUgY29ubmVjdGlvbiBiZXR3ZWVuIG51bWJlciBvZiB0d2VldHMgZnJvbSBMSVZHb2xmIGFuZCBudW1iZXIgb2YgdXNlciBhbmQgbWVkaWEgdHdlZXRzLgoKIyMgNC4gUmVjZXB0aW9uIEFuYWx5c2lzCgpSZWNlcHRpb24gb2YgdGhlIHR3ZWV0IGlzIG1lYXN1cmVkIGFzIGEgY2FsY3VsYXRpb24gb2YgZW5nYWdlbWVudHMgd2hpbGUgdGFraW5nIGludG8gYWNjb3VudCB0aGF0IHRoZSBhbW91bnRzIG9mIGZvbGxvd2VycyB2YXJ5IGJldHdlZW4gdXNlcnMgYW5kIHZhcnkgb3ZlciB0aW1lLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgcmVzZWFyY2gsIHJlY2VwdGlvbiBjYW4gZXF1YXRlIHRvIHBvcHVsYXJpdHkgb2Ygb3Bpbmlvbi4gVGhlcmVmb3JlLCBtZWFzdXJpbmcgcmVjZXB0aW9uIGlzIGNydWNpYWwgdG8gdW5kZXJzdGFuZGluZyBkb21pbmFudCB2aWV3cG9pbnRzIGFib3V0IExJVkdvbGYgYW1vbmcgdXNlcnMuCgpSZWNlcHRpb24gaXMgdGhlIG1lYW4gb2YgcmV0d2VldHMgXCogMiBkaXZpZGVkIGJ5IHRoZSBudW1iZXIgb2YgZm9sbG93ZXJzIGFuZCBmYXZvcml0ZXMgZGl2aWRlZCBieSB0aGUgbnVtYmVyIG9mIGZvbGxvd2VycyB0aW1lcyAxMDAuIFRoaXMgY2FsY3VsYXRpb24gYWNjb3VudHMgZm9yIHRoZSByZWFjaCBhY2hpZXZlZCBieSB0aGUgbnVtYmVyIG9mIGZvbGxvd2VycyBhcyB3ZWxsIGFzIGFjY291bnRpbmcgZm9yIHdoYXQgb2NjdXJzIHdoZW4gYSBmb2xsb3dlciByZXR3ZWV0cyBjb250ZW50LiBUaGUgbnVtYmVyIG9mIHVzZXJzIHRoYXQgY291bGQgcG90ZW50aWFsbHkgaW50ZXJhY3Qgd2l0aCBjb250ZW50IGJlY29tZXMgbGFyZ2VyIGFzIGEgdXNlcidzIGZvbGxvd2VycyByZXR3ZWV0IGNvbnRlbnQsIHRodXMsIHRoZXJlIGlzIHBvdGVudGlhbCBmb3IgY29udGVudCB0byBiZSBzZWVuIGJ5IGEgbGFyZ2VyIG51bWJlciBvZiB1c2VycyB0aGFuIG9ubHkgZm9sbG93ZXJzLgoKVGhlIHB1cnBvc2Ugb2YgdGhpcyBzZWN0aW9uIHdpbGwgYmUgdG8gdW5kZXJzdGFuZCB0aGUgbGV2ZWwgb2YgcmVjZXB0aW9uIHRvIExJVkdvbGYgZ2VuZXJhdGVkIGNvbnRlbnQgZHVyaW5nIHRoZSBvYnNlcnZhdGlvbiBwZXJpb2QuIFRoZW4gYW5hbHlzaXMgd2lsbCBiZSBjb25kdWN0ZWQgdG8gZGV0ZXJtaW5lIGlmIExJViBHb2xmIGNvbnRlbnQgaXMgZWl0aGVyIGdyb3dpbmcgaW4gcG9wdWxhcml0eSwgZGVjcmVhc2luZyBpbiBwb3B1bGFyaXR5LCBvciByZW1haW5pbmcgcmVsYXRpdmVseSBzdGFibGUuIEEgcG9pbnQgb2YgY29tcGFyaXNvbiBpcyB0aGUgbWVhbiByZWNlcHRpb24gc2NvcmUgb2YgY29udGVudCBnZW5lcmF0ZWQgYnkgdXNlcnMuIElmIHNpZ25pZmljYW50bHkgZGlmZmVyZW50LCBmdXR1cmUgYW5hbHlzaXMgY291bGQgYmUgY29uZHVjdGVkIHRvIHVuZGVyc3RhbmQgdGhlIG1lc3NhZ2UgYmVoaW5kIGNvbnRlbnQgd2l0aCBoaWdoZXIgb3IgbG93ZXIgcmVjZXB0aW9uIHNjb3JlZCBjb250ZW50LgoKYGBge3IsIGluY2x1ZGU9RkFMU0V9CiNJZGVudGlmeSB1c2VycyB3aXRoIHRoZSBoaWdoZXN0IHJlY2VwdGlvbiBzY29yZQpyZXR3ZWV0X3JlYWNoIDwtIHNlbGVjdChmaW5hbF9kYXRhLCBzY3JlZW5fbmFtZSwgcmVjZXB0aW9uLCBzb3VyY2UsIGRheV9jcmVhdGVkKQphcnJhbmdlKHJldHdlZXRfcmVhY2gsIGRlc2MocmVjZXB0aW9uKSkKYGBgCgojIyMgUmVjZXB0aW9uIFNjYXR0ZXIgUGxvdAoKYGBge3J9CiNQbG90IHJlY2VwdGlvbiBvdmVyIHRpbWUgZm9yIExJVkdvbGYgZ2VuZXJhdGVkIGNvbnRlbnQuCkxJVl9Hb2xmX3JlY2VwdGlvbl9wbG90IDwtIGdncGxvdChMSVZHb2xmLCBhZXMoeCA9IGRheV9jcmVhdGVkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gcmVjZXB0aW9uKSkgKyAKICBnZW9tX3BvaW50KHNpemUgPSAxLCBjb2xvciA9ICJyZWQiKSArCiAgbGFicyh0aXRsZSA9ICJSZWNlcHRpb24gU2NvcmUgb2YgTElWR29sZiBHZW5lcmF0ZWQgVHdlZXRzIiwKICAgICAgc3VidGl0bGUgPSAiTm92ZW1iZXIgOHRoIHRvIE5vdmVtYmVyIDI4dGggMjAyMiIsCiAgICAgIGNhcHRpb24gPSAiRGF0YSBTb3VyY2U6IFR3aXR0ZXIgc2VhcmNoIGZvciAjTElWR29sZiIpICsKICBsYWJzKHkgPSAiUmVjZXB0aW9uIFNjb3JlIiwgeCA9ICJEYXRlIG9mIFR3ZWV0IikKTElWX0dvbGZfcmVjZXB0aW9uX3Bsb3QgKyBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0KICAgICAgIGMoOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5LDIwLDIxLDIyLDIzLDI0LDI1LDI2LDI3LDI4LDI5KSkgICAgICAgICAKYGBgCgojIyMgTWVhbiBSZWNlcHRpb24gU2NvcmUgLSBMSVYgR29sZgoKYGBge3J9CiNHZW5lcmF0ZSBNZWFuIHJlY2VwdGlvbiBzY29yZSBwZXIgZGF5IG9mIG9ic2VydmF0aW9uIGZvciBMSVZHb2xmIGdlbmVyYXRlZCBjb250ZW50IGJlY2F1c2Ugb2YgaW5zdGFuY2VzIHdoZXJlIExJVkdvbGYgY3JlYXRlZCBtdWx0aXBsZSB0d2VldHMgcGVyIGRheS4KTElWX2RhaWx5X3JlY2VwdGlvbiA8LSBMSVZHb2xmICU+JSBncm91cF9ieShkYXlfY3JlYXRlZCkgJT4lIHN1bW1hcmlzZShyZWNlcHRpb24gPSBtZWFuKHJlY2VwdGlvbikpCgojUGxvdCBtZWFuIGRhaWx5IHJlY2VwdGlvbiB2YWx1ZXMgb2YgTElWR29sZiBnZW5lcmF0ZWQgY29udGVudC4KZGFpbHlfcmVjZXB0aW9uX3Bsb3QgPC0gZ2dwbG90KExJVl9kYWlseV9yZWNlcHRpb24sIGFlcyh4ID0gZGF5X2NyZWF0ZWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gcmVjZXB0aW9uKSkgKyAKICBnZW9tX3BvaW50KHNpemUgPSAxLCBjb2xvciA9ICJyZWQiKSArCiAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gZGF5X2NyZWF0ZWQsIHhlbmQgPSBkYXlfY3JlYXRlZCwgeSA9IDAsIHllbmQgPQogICAgICAgICAgICAgICAgICAgICByZWNlcHRpb24pKSArCiAgbGFicyh0aXRsZSA9ICJNZWFuIFJlY2VwdGlvbiBTY29yZSBvZiBMSVZHb2xmIEdlbmVyYXRlZCBUd2VldHMiLAogICAgICBzdWJ0aXRsZSA9ICJOb3ZlbWJlciA4dGggdG8gTm92ZW1iZXIgMjd0aCAyMDIyIiwKICAgICAgY2FwdGlvbiA9ICJEYXRhIFNvdXJjZTogVHdpdHRlciBzZWFyY2ggZm9yICNMSVZHb2xmIikgKwogIGxhYnMoeSA9ICJSZWNlcHRpb24gU2NvcmUiLCB4ID0gIkRhdGUgb2YgVHdlZXQiKQpkYWlseV9yZWNlcHRpb25fcGxvdCArIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKDgsOSwxMCwxMSwxMiwxMywxNCwxNSwxNiwxNywxOCwxOSwyMCwyMSwyMiwyMywyNCwyNSwyNiwyNywyOCwyOSkpIApgYGAKCiMjIyBNZWFuIFJlY2VwdGlvbiBTY29yZSAtIFVzZXJzCgpgYGB7cn0KI0NyZWF0ZSBtZWFuIHJlY2VwdGlvbiB2YWx1ZXMgZm9yIHVzZXIgZ2VuZXJhdGVkIGNvbnRlbnQuCm1lYW5fdXNlcl9kYWlseV9yZWNlcHRpb24gPC0gb25seV91c2VycyAlPiUgZ3JvdXBfYnkoZGF5X2NyZWF0ZWQpICU+JSBzdW1tYXJpc2UocmVjZXB0aW9uID0gbWVhbihyZWNlcHRpb24pKQoKI1Bsb3QgbWVhbiBkYWlseSByZWNlcHRpb24gdmFsdWVzIG9mIHVzZXIgZ2VuZXJhdGVkIGNvbnRlbnQuCm1lYW5fdXNlcl9kYWlseV9yZWNlcHRpb25fcGxvdCA8LSBnZ3Bsb3QobWVhbl91c2VyX2RhaWx5X3JlY2VwdGlvbiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBkYXlfY3JlYXRlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHJlY2VwdGlvbikpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMSwgY29sb3IgPSAiYmx1ZSIpICsKICBnZW9tX3NlZ21lbnQoYWVzKHggPSBkYXlfY3JlYXRlZCwgeGVuZCA9IGRheV9jcmVhdGVkLCB5ID0gMCwgeWVuZCA9CiAgICAgICAgICAgICAgICAgICAgIHJlY2VwdGlvbikpICsKICBsYWJzKHRpdGxlID0gIk1lYW4gUmVjZXB0aW9uIFNjb3JlIG9mIFVzZXIgVHdlZXRzIiwKICAgICAgc3VidGl0bGUgPSAiTm92ZW1iZXIgOHRoIHRvIE5vdmVtYmVyIDI4dGggMjAyMiIsCiAgICAgIGNhcHRpb24gPSAiRGF0YSBTb3VyY2U6IFR3aXR0ZXIgc2VhcmNoIGZvciAjTElWR29sZiIpICsKICBsYWJzKHkgPSAiUmVjZXB0aW9uIFNjb3JlIiwgeCA9ICJEYXRlIG9mIFR3ZWV0IikKbWVhbl91c2VyX2RhaWx5X3JlY2VwdGlvbl9wbG90ICsgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5LDIwLDIxLDIyLDIzLDI0LDI1LDI2LDI3LDI4LDI5KSkKYGBgCgpgYGB7cn0Kb25seV91c2Vyc19yZWNlcHRpb24gPC0gc2VsZWN0KG9ubHlfdXNlcnMsIGRheV9jcmVhdGVkLCByZWNlcHRpb24pICU+JQogIGFycmFuZ2UoZGF5X2NyZWF0ZWQpCm9ubHlfdXNlcnNfcmVjZXB0aW9uJGRheV9jcmVhdGVkIDwtCiAgYXMuY2hhcmFjdGVyKG9ubHlfdXNlcnNfcmVjZXB0aW9uJGRheV9jcmVhdGVkKQpuYW1lcyhvbmx5X3VzZXJzX3JlY2VwdGlvbilbMV0gPSAiZ3JvdXAiCmBgYAoKIyMjIFJlY2VwdGlvbiBCb3hwbG90IC0gVXNlcgoKYGBge3J9Cm9ubHlfdXNlcnNfcmVjZXB0aW9uICU+JQogIGdncGxvdCggYWVzKHggPSBncm91cCwgeSA9IHJlY2VwdGlvbiwgZmlsbCA9IGdyb3VwKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIsCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSkgKwogIGxhYnModGl0bGUgPSAiVXNlciBSZWNlcHRpb24gQm94cGxvdCIsCiAgICAgIHN1YnRpdGxlID0gIk5vdmVtYmVyIDh0aCB0byBOb3ZlbWJlciAyOHRoIDIwMjIiLAogICAgICBjYXB0aW9uID0gIkRhdGEgU291cmNlOiBUd2l0dGVyIHNlYXJjaCBmb3IgI0xJVkdvbGYiKSArCiAgbGFicyh5ID0gIlJlY2VwdGlvbiBTY29yZSIsIHggPSAiRGF0ZSBDb2xsZWN0ZWQiKQpgYGAKCmBgYHtyfQpMSVZfZm9sbG93ZXJzX2NvdW50IDwtIHNlbGVjdChMSVZHb2xmLCBkYXlfY3JlYXRlZCwgZm9sbG93ZXJzX2NvdW50KSAlPiUgYXJyYW5nZShkYXlfY3JlYXRlZCkKYGBgCgojIyMgTElWIEdvbGYgRm9sbG93ZXIgUGxvdAoKYGBge3J9CkxJVl9mb2xsb3dlcnNfcGxvdCA8LSBMSVZfZm9sbG93ZXJzX2NvdW50ICU+JQogIGdncGxvdCggYWVzKHggPSBkYXlfY3JlYXRlZCwgeSA9IGZvbGxvd2Vyc19jb3VudCkpICsKICAgIGdlb21fbGluZSgpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSkpICsKICBsYWJzKHRpdGxlID0gIk51bWJlciBvZiBVc2VycyBGb2xsb3dpbmcgTElWR29sZiIsCiAgICAgIHN1YnRpdGxlID0gIk5vdmVtYmVyIDh0aCB0byBOb3ZlbWJlciAyOXRoIDIwMjIiLAogICAgICBjYXB0aW9uID0gIkRhdGEgU291cmNlOiBUd2l0dGVyIHNlYXJjaCBmb3IgI0xJVkdvbGYiKSArCiAgbGFicyh5ID0gIkZvbGxvd2VycyIsIHggPSAiRGF0ZSIpCkxJVl9mb2xsb3dlcnNfcGxvdCArIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyg4LDksMTAsMTEsMTIsMTMsMTQsMTUsMTYsMTcsMTgsMTksMjAsMjEsMjIsMjMsMjQsMjUsMjYsMjcsMjgsMjkpKQpgYGAKCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQpkaWFnbm9zZV9vdXRsaWVyKG9ubHlfdXNlcnNfcmVjZXB0aW9uKQpgYGAKCiMjIyBDb25jbHVzaW9ucwoKTElWR29sZiBSZWNlcHRpb24gLSBMSVZHb2xmIGV4cGVyaWVuY2VkIHRoZSBoaWdoZXN0IGxldmVsIG9mIHJlY2VwdGlvbiBmcm9tIGl0cyBjb250ZW50IGZyb20gdGhlIDExdGggdG8gMTN0aCBvZiBOb3ZlbWJlci4gRnVydGhlciBBbmFseXNpcyBpcyByZXF1aXJlZCB0byB1bmRlcnN0YW5kIHBvdGVudGlhbCByZWFzb25zIHdoeSBjb250ZW50IGR1cmluZyB0aG9zZSBkYXRlcyB3YXMgcmVjZWl2ZWQgZGlmZmVyZW50bHkgdGhhbiBjb250ZW50IG9uIG90aGVyIGRheXMgZHVyaW5nIHRoZSBjb2xsZWN0aW9uIHBlcmlvZC4KClVzZXIgUmVjZXB0aW9uIC0gTm92ZW1iZXIgMTF0aCBhbmQgMTN0aCBleHBlcmllbmNlZCB0aGUgaGlnaGVzdCByZWNlcHRpb24gc2NvcmUgb2YgdXNlciBnZW5lcmF0ZWQgY29udGVudC4gRnJvbSBhbmFseXNpcyBpbiB0aGUgYm94cGxvdCwgaXQgaXMgZXZpZGVudCB0aGF0IG91dGxpZXJzIGltcGFjdCB0aGUgbWVhbiBsZXZlbCBvZiByZWNlcHRpb24gZnJvbSB1c2VyIGdlbmVyYXRlZCB0d2VldHMuIFRoZSBtZWFuIHNjb3JlIGlzIHNpZ25pZmljYW50bHkgbG93ZXIgaWYgb3V0bGllcnMgd2VyZSB0byBiZSByZW1vdmVkLiBBIHNtYWxsIG1pbm9yaXR5IG9mIGNvbnRlbnQgaXMgZHJpdmluZyByZWNlcHRpb24gc2NvcmVzIHNpZ25pZmljYW50bHkgaGlnaGVyIG9uIHRob3NlIGRhdGVzLgoKRnVydGhlciBhbmFseXNpcyBpcyByZXF1aXJlZCB0byBkZXRlcm1pbmUgaWYgdGhlIGNvbnRlbnQgb2YgdGhlIHR3ZWV0IGlzIHJlc3BvbnNpYmxlIGZvciB0aGUgcHJlc2VuY2Ugb2YgdGhlIG91dGxpZXJzIGluIHVzZXIgZ2VuZXJhdGVkIGNvbnRlbnQuICNGdXJ0aGVyIGFuYWx5c2lzIHRvIHVuZGVyc3RhbmQgcmVjZXB0aW9uIHdpbGwgaXNvbGF0ZSB0d2VldHMgd2l0aCBzaWduaWZpY2FudGx5IGhpZ2hlciByZWNlcHRpb24gc2NvcmVzIHRvIHVuZGVyc3RhbmQgdGhlIGNvbnRlbnQgaW4gdGhlIHR3ZWV0cy4KCiMjIDUuIFNlbnRpbWVudCBBbmFseXNpcwoKVGhlIHB1cnBvc2Ugb2YgdGhpcyBzZWN0aW9uIGlzIHRvIHVuZGVyc3RhbmQgdGhlIHNlbnRpbWVudCBvZiBvcGluaW9uIGJlaW5nIHVzZWQgaW4gdHdlZXRzIGNyZWF0ZWQgYnkgTElWR29sZiBhbmQgYnkgdXNlciBnZW5lcmF0ZWQgY29udGVudC4gVGhlIGdvYWwgaXMgdG8gaWRlbnRpZnkgbWFpbiBpZGVhcyBvciB0b3BpY3Mgb2YgY29udmVyc2F0aW9uIHRvIGZ1cnRoZXIgZ3VhZ2UgcmVjZXB0aW9uIG9mIHRoZSBMSVZHb2xmIHByb2R1Y3QuIEFkZGl0aW9uYWxseSwgYnkgZ2VuZXJhdGluZyB0aGUgc2VudGltZW50IHZhcmlhYmxlLCByZXNlYXJjaCBpZGVudGlmeSBvdmVyYWxsIHRvbmUgb2YgdGhlIGNvbnZlcnNhdGlvbiBhcyBiZWluZyBlaXRoZXIgcG9zaXRpdmUgb3IgbmVnYXRpdmUuCgpgYGB7cn0KI3JlbW92ZSBtZWRpYSBhbmQgYWR2ZXJ0aXNlbWVudHMgdG8gaXNvbGF0ZSBvbmx5IHVzZXJzIGFuZCBMSVZHb2xmLgphbGxfc2VudGltZW50IDwtIHN1YnNldChmaW5hbF9kYXRhLCBzb3VyY2UgIT0gIk1lZGlhIikKCiNDcmVhdGUgZGF0YSBmcmFtZSB0byB1bmRlcnN0YW5kIHNlbnRpbWVudCBvdmVyIHRpbWUuCnNlbnRpbWVudF9kYXRhIDwtIHNlbGVjdChmaW5hbF9kYXRhLCBkYXlfY3JlYXRlZCwgc2VudGltZW50KQoKI2NhbGN1bGF0ZSBtZWFuIHNlbnRpbWVudCBzY29yZSB0aHJvdWdob3V0IHRoZSBvYnNlcnZhdGlvbiBwZXJpb2QKZGFpbHlfc2VudGltZW50IDwtIHNlbnRpbWVudF9kYXRhICU+JSBncm91cF9ieShkYXlfY3JlYXRlZCkgJT4lIHN1bW1hcmlzZShzZW50aW1lbnQgPSBtZWFuKHNlbnRpbWVudCkpCmRhaWx5X3NlbnRpbWVudApgYGAKCiMjIyBEYWlseSBTZW50aW1lbnQgU2NvcmUgLSBMSVYgR29sZgoKYGBge3J9CiNDcmVhdGUgUGxvdCBvZiBkYWlseSBzZW50aW1lbnQgb2YgdHdlZXRzIHdpdGggTElWR29sZgpzZW50aW1lbnRfcGxvdCA8LSBnZ3Bsb3QoZGFpbHlfc2VudGltZW50LCBhZXMoeCA9IGRheV9jcmVhdGVkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBzZW50aW1lbnQpKSArCiAgZ2VvbV9wb2ludChzaXplID0gMSwgY29sb3IgPSAiYmx1ZSIpICsKICBnZW9tX3NlZ21lbnQoYWVzKHggPSBkYXlfY3JlYXRlZCwgeGVuZCA9IGRheV9jcmVhdGVkLCB5ID0gMCwgeWVuZCA9IAogICAgc2VudGltZW50KSkgKwogIGxhYnModGl0bGUgPSAiTWVhbiBTZW50aW1lbnQgU2NvcmUgb2YgYWxsIExJVkdvbGYgVHdlZXRzIiwKICAgICAgc3VidGl0bGUgPSAiTm92ZW1iZXIgOHRoIHRvIE5vdmVtYmVyIDI5dGggMjAyMiIsCiAgICAgIGNhcHRpb24gPSAiRGF0YSBTb3VyY2U6IFR3aXR0ZXIgc2VhcmNoIGZvciAjTElWR29sZiIpICsKICBsYWJzKHkgPSAiU2VudGltZW50IFNjb3JlIiwgeCA9ICJEYXRlIG9mIFR3ZWV0IikKc2VudGltZW50X3Bsb3QgKyBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKDgsOSwxMCwxMSwxMiwxMywxNCwxNSwxNiwxNywxOCwxOSwyMCwyMSwyMiwyMywyNCwyNSwyNiwyNywyOCwyOSkpIApgYGAKCmBgYHtyfQojdW5kZXJzdGFuZCB1c2VyIHNlbnRpbWVudC4Kb25seV91c2Vyc19zZW50aW1lbnQgPC0gc2VsZWN0KG9ubHlfdXNlcnMsIGRheV9jcmVhdGVkLCBzZW50aW1lbnQpCgojY2FsY3VsYXRlIG1lYW4gc2VudGltZW50IHNjb3JlIHRocm91Z2hvdXQgdGhlIG9ic2VydmF0aW9uIHBlcmlvZAp1c2VyX3NlbnRpbWVudF9tZWFuIDwtIG9ubHlfdXNlcnNfc2VudGltZW50ICU+JSBncm91cF9ieShkYXlfY3JlYXRlZCkgJT4lIHN1bW1hcmlzZShzZW50aW1lbnQgPSBtZWFuKHNlbnRpbWVudCkpCnVzZXJfc2VudGltZW50X21lYW4KYGBgCgojIyMgRGFpbHkgU2VudGltZW50IFNjb3JlIC0gVXNlcgoKYGBge3J9CiNDcmVhdGUgUGxvdCBvZiB1c2VyIGF1dGhvcmVkIHR3ZWV0cy4Kb25seV91c2Vyc19zZW50aW1lbnRfcGxvdCA8LSBnZ3Bsb3Qob25seV91c2Vyc19zZW50aW1lbnQsIAogIGFlcyh4ID0gZGF5X2NyZWF0ZWQsIHkgPSBzZW50aW1lbnQpKSArCiAgZ2VvbV9wb2ludChzaXplID0gMSwgY29sb3IgPSAiYmx1ZSIpICsKICBsYWJzKHRpdGxlID0gIlNlbnRpbWVudCBTY29yZXMgb2YgVXNlciBUd2VldHMiLAogICAgICBzdWJ0aXRsZSA9ICJOb3ZlbWJlciA4dGggdG8gTm92ZW1iZXIgMjl0aCAyMDIyIiwKICAgICAgY2FwdGlvbiA9ICJEYXRhIFNvdXJjZTogVHdpdHRlciBzZWFyY2ggZm9yICNMSVZHb2xmIikgKwogIGxhYnMoeSA9ICJTZW50aW1lbnQgU2NvcmUiLCB4ID0gIkRhdGUgb2YgVHdlZXQiKQpvbmx5X3VzZXJzX3NlbnRpbWVudF9wbG90ICsgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5LDIwLDIxLDIyLDIzLDI0LDI1LDI2LDI3LDI4LDI5KSkgCmBgYAoKIyMjIE1lYW4gU2VudGltZW50IFNjb3JlIC0gVXNlcgoKYGBge3J9CiNDcmVhdGUgUGxvdCBvZiB1c2VyIGF1dGhvcmVkIHR3ZWV0cy4KdXNlcl9zZW50aW1lbnRfbWVhbl9wbG90IDwtIGdncGxvdCh1c2VyX3NlbnRpbWVudF9tZWFuLCAKICBhZXMoeCA9IGRheV9jcmVhdGVkLCB5ID0gc2VudGltZW50KSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDEsIGNvbG9yID0gImJsdWUiKSArCiAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gZGF5X2NyZWF0ZWQsIHhlbmQgPSBkYXlfY3JlYXRlZCwgeSA9IDAsIHllbmQgPQogICAgICAgICAgICAgICAgICAgICBzZW50aW1lbnQpKSArCiAgbGFicyh0aXRsZSA9ICJNZWFuIERhaWx5IFNlbnRpbWVudCBvZiBVc2VyIFR3ZWV0cyIsCiAgICAgIHN1YnRpdGxlID0gIk5vdmVtYmVyIDh0aCB0byBOb3ZlbWJlciAyOXRoIDIwMjIiLAogICAgICBjYXB0aW9uID0gIkRhdGEgU291cmNlOiBUd2l0dGVyIHNlYXJjaCBmb3IgI0xJVkdvbGYiKSArCiAgbGFicyh5ID0gIlNlbnRpbWVudCBTY29yZSIsIHggPSAiRGF0ZSBvZiBUd2VldCIpCnVzZXJfc2VudGltZW50X21lYW5fcGxvdCArIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyg4LDksMTAsMTEsMTIsMTMsMTQsMTUsMTYsMTcsMTgsMTksMjAsMjEsMjIsMjMsMjQsMjUsMjYsMjcsMjgsMjkpKSAKYGBgCgpgYGB7cn0Kb25seV91c2Vyc19zZW50aW1lbnQkZGF5X2NyZWF0ZWQgPC0KICBhcy5jaGFyYWN0ZXIob25seV91c2Vyc19zZW50aW1lbnQkZGF5X2NyZWF0ZWQpCm5hbWVzKG9ubHlfdXNlcnNfc2VudGltZW50KVsxXSA9ICJncm91cCIKYGBgCgpgYGB7cn0KI0JveHBsb3Qgb2YgdXNlciBzZW50aW1lbnQgcGVyIGRheSBvZiBjb2xsZWN0aW9uCm9ubHlfdXNlcnNfc2VudGltZW50ICU+JQogIGdncGxvdCggYWVzKHggPSBncm91cCwgeSA9IHNlbnRpbWVudCwgZmlsbCA9IGdyb3VwKSkgKwogICAgZ2VvbV9ib3hwbG90KCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIsCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSkgKwogIGxhYnModGl0bGUgPSAiVXNlciBTZW50aW1lbnQgQm94cGxvdCBieSBEYXRlIiwKICAgICAgc3VidGl0bGUgPSAiTm92ZW1iZXIgOHRoIHRvIE5vdmVtYmVyIDI4dGggMjAyMiIsCiAgICAgIGNhcHRpb24gPSAiRGF0YSBTb3VyY2U6IFR3aXR0ZXIgc2VhcmNoIGZvciAjTElWR29sZiIpICsKICBsYWJzKHkgPSAiU2VudGltZW50IFNjb3JlIiwgeCA9ICJEYXRlIENvbGxlY3RlZCIpCmBgYAoKYGBge3J9CiNWaW9saW4gY2hhcnQgb2YgdXNlciBzZW50aW1lbnQgcGVyIGRheSBvZiBjb2xsZWN0aW9uCm9ubHlfdXNlcnNfc2VudGltZW50ICU+JQogIGdncGxvdCggYWVzKHggPSBncm91cCwgeSA9IHNlbnRpbWVudCwgZmlsbCA9IGdyb3VwKSkgKwogICAgZ2VvbV92aW9saW4oKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIiwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTUpKSArCiAgbGFicyh0aXRsZSA9ICJVc2VyIFNlbnRpbWVudCBWaW9saW4gQ2hhcnQgYnkgRGF0ZSIsCiAgICAgIHN1YnRpdGxlID0gIk5vdmVtYmVyIDh0aCB0byBOb3ZlbWJlciAyOHRoIDIwMjIiLAogICAgICBjYXB0aW9uID0gIkRhdGEgU291cmNlOiBUd2l0dGVyIHNlYXJjaCBmb3IgI0xJVkdvbGYiKSArCiAgbGFicyh5ID0gIlNlbnRpbWVudCBTY29yZSIsIHggPSAiRGF0ZSBDb2xsZWN0ZWQiKQpgYGAKCiMjIyBDb25jbHVzaW9ucwoKU2VudGltZW50IG9mIHRoZSBlbnRpcmUgZGF0YXNldCByZXZlYWxzIHRoYXQgdGhlIDE2dGggYW5kIDE5dGggb2YgTm92ZW1iZXIgcmVzdWx0ZWQgaW4gdGhlIGRhdGVzIHdpdGggdGhlIGxvd2VzdCBzZW50aW1lbnQgdmFsdWVzLiBFdmVuIHdoZW4gdGhlIGRhdGFzZXQgb2YgdHdlZXRzIHdhcyBzZXBhcmF0ZWQgYnkgYXV0aG9yLCB0aGUgMTZ0aCBhbmQgMTl0aCBoYWQgdGhlIGxvd2VzdCBzZW50aW1lbnQgc2NvcmVzLgoKVGhlIDI0dGggb2YgTm92ZW1iZXIgcmVzdWx0ZWQgaW4gdGhlIGhpZ2hlc3QgbWVhbiBzZW50aW1lbnQgc2NvcmUgZm9yIGFsbCB0d2VldHMgYW5kIHdoZW4gYW5hbHl6ZWQgYnkgc291cmNlLiBUaGUgdmlvbGluIHBsb3QgYW5kIGJveHBsb3QgaWxsdXN0cmF0ZXMgYSByZWxhdGl2ZWx5IHRpZ2h0IGNsdXN0ZXJpbmcgb2Ygc2VudGltZW50IHNjb3JlcyB3aXRob3V0IGFueSBvdXRsaWVycy4KClRoZSB2aW9saW4gcGxvdCBpbGx1c3RyYXRlcyB0aGUgcmFuZ2Ugb2Ygc2VudGltZW50IHNjb3JlcyBhbmQgdGhlIGFtb3VudCBvZiBvY2N1cnJlbmNlcyB3aGVyZSBvYnNlcnZhdGlvbnMgYXJlIGNsdXN0ZXJlZC4gRm9yIGV4YW1wbGUsIHRoZSAyMm5kIG9mIE5vdmVtYmVyIGV4cGVyaWVuY2VkIGEgbGFyZ2UgYW1vdW50IG9mIGNvbnRlbnQgd2l0aCBzZW50aW1lbnQgc2NvcmUgY2xvc2UgdG8gemVybywgdGhlcmVmb3JlLCB0aGUgdmlvbGluIGlzIHdpZGVyIGF0IHRoYXQgc2NvcmUuIFRoZSAyMm5kIGFsc28gcmV2ZWFscyBoZWlnaHQgYmFzZWQgb24gdGhlIHByZXNlbmNlIG9mIG91dGxpZXJzIHRoYXQgd2VyZSBzaWduaWZpY2FudGx5IGZhciBhd2F5IGZyb20gdGhlIG1lYW4uIFRoZSBmZXdlciB0aGUgYW1vdW50IG9mIG91dGxpZXJzLCBhbmQgdGhlIHdpZGVyIHRoZSBwbG90IHJldmVhbHMgYSBtb3JlIGNvbnNpc3RlbnQgc2VudGltZW50IHNjb3JlIGZvciB0aGF0IGRhdGUgaW4gdGhlIG9ic2VydmF0aW9uIHBlcmlvZC4gVGhlIDh0aCwgOXRoLCBhbmQgMTN0aCBleHBlcmllbmNlZCBubyBvdXRsaWVycyBpbiBzZW50aW1lbnQuCgojIyA2LiBFbW90aW9uIEFuYWx5c2lzClRoZSBwdXJwb3NlIG9mIHRoaXMgc2VjdGlvbiBpcyB0byB1bmRlcnN0YW5kIHRoZSBlbW90aW9ucyBjb252ZXllZCB0aHJvdWdoIGxhbmd1YWdlIGFuYWx5c2lzIG9mIHRoZSB0ZXh0IGluIG9ic2VydmVkIGNvbnRlbnQuCgpgYGB7ciwgd2FybmluZz1GQUxTRX0KI2NyZWF0ZSBkYXRhZnJhbWUgdG8gY2FwdHVyZSBlbW90aW9ucyBmcm9tIGFsbCB0d2VldHMuCmV3X3NlbnRpbWVudF9MSVYgPC0gZ2V0X25yY19zZW50aW1lbnQoTElWR29sZiR0ZXh0X2NsZWFuKQpzZW50aW1lbnRzY29yZXNfTElWIDwtIGRhdGEuZnJhbWUoY29sU3Vtcyhld19zZW50aW1lbnRfTElWWyxdKSkKbmFtZXMoc2VudGltZW50c2NvcmVzX0xJVikgPC0gIlNjb3JlIgpzZW50aW1lbnRzY29yZXNfTElWIDwtIGNiaW5kKCJzZW50aW1lbnQiID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgcm93bmFtZXMoc2VudGltZW50c2NvcmVzX0xJViksc2VudGltZW50c2NvcmVzX0xJVikKcm93bmFtZXMoc2VudGltZW50c2NvcmVzX0xJVikgPC0gTlVMTApgYGAKCiMjIyBFbW90aW9uIEZyZXF1ZW5jeSBQbG90IC0gTElWIEdvbGYKCmBgYHtyfQojcGxvdCBzZW50aW1lbnQgb2YgZW1vdGlvbnMgdG8gdW5kZXJzdGFuZCB0aGUgZ2VuZXJhbCB0b25lIG9mIGNvbnZlcnNhdGlvbiBhYm91dCBMSVZHb2xmLgplbW90aW9uX3Bsb3RfTElWIDwtIGdncGxvdChkYXRhID0gc2VudGltZW50c2NvcmVzX0xJViwgCiAgICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBzZW50aW1lbnQsIHkgPSBTY29yZSkpICsKICBnZW9tX2JhcihhZXMoZmlsbCA9IHNlbnRpbWVudCksIHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgeGxhYigiU2VudGltZW50cyIpICsgeWxhYigiV29yZCBDb3VudCBieSBFbW90aW9uIikgKwogIGxhYnModGl0bGUgPSAiRW1vdGlvbiBDb3VudCBvZiBMSVYgR29sZiBDb250ZW50IiwKICAgICAgc3VidGl0bGUgPSAiTm92ZW1iZXIgOHRoIHRvIE5vdmVtYmVyIDI5dGggMjAyMiIsCiAgICAgIGNhcHRpb24gPSAiRGF0YSBTb3VyY2U6IFR3aXR0ZXIgc2VhcmNoIGZvciAjTElWR29sZiIpCiAgCmVtb3Rpb25fcGxvdF9MSVYgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCB2anVzdCA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhqdXN0PTEpKQpgYGAKCmBgYHtyfQojY3JlYXRlIGRhdGFmcmFtZSB0byBjYXB0dXJlIGVtb3Rpb25zIGZyb20gYWxsIHVzZXIgZ2VuZXJhdGVkIGNvbnRlbnQuCmV3X3NlbnRpbWVudF91c2VycyA8LSBnZXRfbnJjX3NlbnRpbWVudChvbmx5X3VzZXJzJHRleHRfY2xlYW4pCnNlbnRpbWVudHNjb3Jlc191c2VycyA8LSBkYXRhLmZyYW1lKGNvbFN1bXMoZXdfc2VudGltZW50X3VzZXJzWyxdKSkKbmFtZXMoc2VudGltZW50c2NvcmVzX3VzZXJzKSA8LSAiU2NvcmUiCnNlbnRpbWVudHNjb3Jlc191c2VycyA8LSBjYmluZCgic2VudGltZW50IiA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvd25hbWVzKHNlbnRpbWVudHNjb3Jlc191c2VycyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbnRpbWVudHNjb3Jlc191c2VycykKcm93bmFtZXMoc2VudGltZW50c2NvcmVzX3VzZXJzKSA8LSBOVUxMCmBgYAoKIyMjIEVtb3Rpb24gRnJlcXVlbmN5IFBsb3QgLSBBbGwgQ29udGVudAoKYGBge3J9CiNwbG90IHNlbnRpbWVudCBvZiBlbW90aW9ucyB0byB1bmRlcnN0YW5kIHRoZSBnZW5lcmFsIHRvbmUgb2YgY29udmVyc2F0aW9uIGFib3V0IExJVkdvbGYuCmVtb3Rpb25fcGxvdF91c2VycyA8LSBnZ3Bsb3QoZGF0YSA9IHNlbnRpbWVudHNjb3Jlc191c2VycywgCiAgICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBzZW50aW1lbnQsIHkgPSBTY29yZSkpICsKICBnZW9tX2JhcihhZXMoZmlsbCA9IHNlbnRpbWVudCksIHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgeGxhYigiU2VudGltZW50cyIpICsgeWxhYigiV29yZCBDb3VudCIpICsKICBsYWJzKHRpdGxlID0gIkVtb3Rpb24gQ291bnQgb2YgVXNlciBHZW5lcmF0ZWQgQ29udGVudCIsCiAgICAgIHN1YnRpdGxlID0gIk5vdmVtYmVyIDh0aCB0byBOb3ZlbWJlciAyOXRoIDIwMjIiLAogICAgICBjYXB0aW9uID0gIkRhdGEgU291cmNlOiBUd2l0dGVyIHNlYXJjaCBmb3IgI0xJVkdvbGYiKQplbW90aW9uX3Bsb3RfdXNlcnMgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCB2anVzdCA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhqdXN0PTEpKQpgYGAKCiMjIyBDb25jbHVzaW9ucwoKTElWR29sZiAtIEFzIGV4cGVjdGVkLCBMSVZHb2xmIGVtb3Rpb24gY291bnQgaXMgaW5kaWNhdGl2ZSBvZiBhbiBvcmdhbml6YXRpb24gYXR0ZW1wdGluZyB0byBnYXRoZXIgZm9sbG93ZXJzLCBzcHJlYWQgYXdhcmVuZXNzIG9mIHRoZWlyIGJyYW5kLCBhbmQgaXMgbGFyZ2VseSBwb3NpdGl2ZS4gVGhlIExJVkdvbGYgY29udGVudCBpcyBleHByZXNzaW5nIGFudGljaXBhdGlvbiBmb3IgZnV0dXJlIGV2ZW50cyB3aXRoIGFuIG92ZXJhbGwgcG9zaXRpdmUgZW1vdGlvbi4KClVzZXJzIC0gV2hlbiBhbmFseXppbmcgdXNlciBnZW5lcmF0ZWQgY29udGVudCwgdGhlIGRvbWluYW50IGVtb3Rpb24gaXMgaGFwcGluZXNzIGJ1dCB0aGVyZSBpcyBhIHNpZ25pZmljYW50IGluY3JlYXNlIGluIHRoZSBuZWdhdGl2aXR5IGNvbnZleWVkIGluIHRoZSB0d2VldC4gQWRkaXRpb25hbGx5LCBlbW90aW9ucyBsaWtlIHNhZG5lc3MsIGFuZ2VyLCBhbmQgZmVhciBhbHNvIGluY3JlYXNlZC4KCiMjIDcuIFRleHQgQW5hbHlzaXMKClRoZSBwdXJwb3NlIG9mIHRoaXMgc2VjdGlvbiBpcyB0byBmdXJ0aGVyIHVuZGVyc3RhbmQgdGhlIGNvbnZlcnNhdGlvbiBhbmQgdG9waWNzIGRpc2N1c3NlZCBpbiB0d2VldHMgZnJvbSBMSVZHb2xmIGFuZCBmcm9tIHVzZXJzIGR1cmluZyB0aGUgY29sbGVjdGlvbiBwZXJpb2QuCgpgYGB7cn0KI0NyZWF0ZSBDb3JwdXMgZm9yIExJVkdvbGYgYXV0aG9yZWQgY29udGVudC4KdGV4dF9MSVYgPC0gQ29ycHVzKFZlY3RvclNvdXJjZShMSVZHb2xmJHRleHRfY2xlYW4pKQpgYGAKCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQojQ2xlYW4gdGhlIHRleHQgdmFyaWFibGUKdGV4dF9MSVYgPC0gdGV4dF9MSVYgJT4lCiAgdG1fbWFwKHJlbW92ZU51bWJlcnMpICU+JQogIHRtX21hcChyZW1vdmVQdW5jdHVhdGlvbikgJT4lCiAgdG1fbWFwKHN0cmlwV2hpdGVzcGFjZSkKdGV4dF9MSVYgPC0gdG1fbWFwKHRleHRfTElWLCBjb250ZW50X3RyYW5zZm9ybWVyKHRvbG93ZXIpKQp0ZXh0X0xJViA8LSB0bV9tYXAodGV4dF9MSVYsIHJlbW92ZVdvcmRzLCBzdG9wd29yZHMoImVuZ2xpc2giKSkKdGV4dF9MSVYgPC0gdG1fbWFwKHRleHRfTElWLCByZW1vdmVXb3JkcywgYygiTElWIiwgIkxJVkdvbGYiLCAibGl2Z29sZiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImh0dHBzdGNvaWZsdnl5YWx2eCIpKQpgYGAKCmBgYHtyfQojQ3JlYXRlIGRhdGFmcmFtZXMgZm9yIHRoZSB3b3JkcyB1c2VkIGFuZCBjYXB0dXJlIHRoZSBmcmVxdWVuY3kgb2YgdXNlLgpkdG1fTElWIDwtIFRlcm1Eb2N1bWVudE1hdHJpeCh0ZXh0X0xJVikgCm1hdHJpeF90ZXh0X0xJViA8LSBhcy5tYXRyaXgoZHRtX0xJVikgCndvcmRzX3RleHRfTElWIDwtIHNvcnQocm93U3VtcyhtYXRyaXhfdGV4dF9MSVYpLGRlY3JlYXNpbmc9VFJVRSkgCmRmX3RleHRfTElWIDwtIGRhdGEuZnJhbWUod29yZCA9IG5hbWVzKHdvcmRzX3RleHRfTElWKSxmcmVxPXdvcmRzX3RleHRfTElWKQpgYGAKCiMjIyBXb3JsZGNsb3VkIC0gTElWIEdvbGYgQXV0aG9yZWQgQ29udGVudAoKYGBge3J9CiNDcmVhdGUgV29yZGNsb3VkIG9mIG1vc3QgZnJlcXVlbnRseSB1c2VkIHdvcmRzIHVzZWQgaW4gTElWR29sZiBhdXRob3JlZCBjb250ZW50Lgp3b3JkY2xvdWQod29yZHMgPSBkZl90ZXh0X0xJViR3b3JkLCBmcmVxID0gZGZfdGV4dF9MSVYkZnJlcSwgbWluLmZyZXEgPSAyLCAgICAgICAgICAgbWF4LndvcmRzPTIwMCxyYW5kb20ub3JkZXI9RkFMU0UsIHJvdC5wZXI9MC4zNSxjb2xvcnM9YnJld2VyLnBhbCg4LCAgICAgICAgICAgICJEYXJrMiIpKSAKYGBgCgpgYGB7cn0KI0NyZWF0ZSBDb3JwdXMgZm9yIHVzZXIgZ2VuZXJhdGVkIGNvbnRlbnQuCnRleHRfdXNlciA8LSBDb3JwdXMoVmVjdG9yU291cmNlKG9ubHlfdXNlcnMkdGV4dF9jbGVhbikpCmBgYAoKYGBge3IsIHdhcm5pbmc9RkFMU0V9CiNDbGVhbiB0aGUgdGV4dCB2YXJpYWJsZQp0ZXh0X3VzZXIgPC0gdGV4dF91c2VyICU+JQogIHRtX21hcChyZW1vdmVOdW1iZXJzKSAlPiUKICB0bV9tYXAocmVtb3ZlUHVuY3R1YXRpb24pICU+JQogIHRtX21hcChzdHJpcFdoaXRlc3BhY2UpCnRleHRfdXNlciA8LSB0bV9tYXAodGV4dF91c2VyLCBjb250ZW50X3RyYW5zZm9ybWVyKHRvbG93ZXIpKQp0ZXh0X3VzZXIgPC0gdG1fbWFwKHRleHRfdXNlciwgcmVtb3ZlV29yZHMsIHN0b3B3b3JkcygiZW5nbGlzaCIpKQp0ZXh0X3VzZXIgPC0gdG1fbWFwKHRleHRfdXNlciwgcmVtb3ZlV29yZHMsIGMoImxpdiIsICJsaXZnb2xmaW52IiwgImxpdmdvbGYiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIidzIiwgInNhaWQiLCAiZGF5IiwgImFtcCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNhbiIpKQpgYGAKCmBgYHtyfQojQ3JlYXRlIGRhdGFmcmFtZXMgZm9yIHRoZSB3b3JkcyB1c2VkIGFuZCBjYXB0dXJlIHRoZSBmcmVxdWVuY3kgb2YgdXNlLgpkdG1fdXNlciA8LSBUZXJtRG9jdW1lbnRNYXRyaXgodGV4dF91c2VyKSAKbWF0cml4X3RleHRfdXNlciA8LSBhcy5tYXRyaXgoZHRtX3VzZXIpIAp3b3Jkc190ZXh0X3VzZXIgPC0gc29ydChyb3dTdW1zKG1hdHJpeF90ZXh0X3VzZXIpLGRlY3JlYXNpbmc9VFJVRSkgCmRmX3RleHRfdXNlciA8LSBkYXRhLmZyYW1lKHdvcmQgPSBuYW1lcyh3b3Jkc190ZXh0X3VzZXIpLGZyZXE9d29yZHNfdGV4dF91c2VyKQpgYGAKCiMjIyBXb3JsZGNsb3VkIC0gVXNlciBBdXRob3JlZCBDb250ZW50CgpgYGB7cn0KI0NyZWF0ZSBXb3JkY2xvdWQgb2YgbW9zdCBmcmVxdWVudGx5IHVzZWQgd29yZHMgdXNlZCBpbiBMSVZHb2xmIGF1dGhvcmVkIGNvbnRlbnQuCndvcmRjbG91ZCh3b3JkcyA9IGRmX3RleHRfdXNlciR3b3JkLCBmcmVxID0gZGZfdGV4dF91c2VyJGZyZXEsIG1pbi5mcmVxID0gMTIsICAgICAgICAgICBtYXgud29yZHM9MjAwLHJhbmRvbS5vcmRlcj1GQUxTRSwgcm90LnBlcj0wLjM1LGNvbG9ycz1icmV3ZXIucGFsKDgsICAgICAgICAgICAgIkRhcmsyIikpCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0V9CmZpbmFsX2RhdGEgJT4lIAogIHVubmVzdF90b2tlbnMob3V0cHV0ID0gd29yZCwgaW5wdXQgPSB0ZXh0X2NsZWFuKSAlPiUgCiAgYW50aV9qb2luKHN0b3Bfd29yZHMpICU+JSAKICBjb3VudCh3b3JkLCBzb3J0ID0gVFJVRSkgJT4lIAogIHNsaWNlKDE6MTApCmBgYAoKYGBge3J9CmJpZ3JhbV93b3JkcyA8LSBmaW5hbF9kYXRhICU+JSAKICB1bm5lc3RfdG9rZW5zKAogICAgaW5wdXQgPSB0ZXh0X2NsZWFuLCAKICAgIG91dHB1dCA9IGJpZ3JhbSwgCiAgICB0b2tlbiA9ICduZ3JhbXMnLCAKICAgIG4gPSAyKSAlPiUgCiAgZmlsdGVyKCEgaXMubmEoYmlncmFtKSkKCmJpZ3JhbV93b3JkcyAlPiUgCiAgc2VsZWN0KGJpZ3JhbSkgJT4lIAogIGhlYWQoMTApCmBgYAoKYGBge3J9CmJpZ3JhbV93b3JkcyA8LSBiaWdyYW1fd29yZHMgJT4lIAogc2VwYXJhdGUoY29sID0gYmlncmFtLCBpbnRvID0gYygnd29yZDEnLCAnd29yZDInKSwgc2VwID0gJyAnKQpgYGAKCmBgYHtyfQpiaWdyYW1fY291bnQgPC0gYmlncmFtX3dvcmRzICU+JSAKICBjb3VudChiaWdyYW1fd29yZHMkd29yZDEsIGJpZ3JhbV93b3JkcyR3b3JkMiwgc29ydCA9IFRSVUUpICU+JSAKICByZW5hbWUod2VpZ2h0ID0gbikKCmJpZ3JhbV9jb3VudCAlPiUgaGVhZCgpCmBgYAoKYGBge3J9ClNjYWxlV2VpZ2h0IDwtIGZ1bmN0aW9uKHgsIGxhbWJkYSkgewogIHggLyBsYW1iZGF9CnRocmVzaG9sZCA8LSA0CmBgYAoKIyMjIFVzZXIgQ29udGVudCBCaWdyYW0KCmBgYHtyfQpuZXR3b3JrIDwtICBiaWdyYW1fY291bnQgJT4lCiAgZmlsdGVyKHdlaWdodCA9PSB0aHJlc2hvbGQpICU+JQogIG11dGF0ZSh3ZWlnaHQgPT0gU2NhbGVXZWlnaHQoeCA9IHdlaWdodCwgbGFtYmRhID0gMkUzKSkgJT4lCiAgZ3JhcGhfZnJvbV9kYXRhX2ZyYW1lKGRpcmVjdGVkID0gRkFMU0UpCnBsb3QoCiAgbmV0d29yaywgCiAgdmVydGV4LnNpemUgPSAxLAogIHZlcnRleC5sYWJlbC5jb2xvciA9ICdibGFjaycsIAogIHZlcnRleC5sYWJlbC5jZXggPSAwLjUsIAogIHZlcnRleC5sYWJlbC5kaXN0ID0gMSwKICBlZGdlLmNvbG9yID0gJ2dyYXknLCAKICBtYWluID0gJ0JpZ3JhbSBDb3VudCBOZXR3b3JrJywgCiAgc3ViID0gZ2x1ZSgnV2VpZ2h0IFRocmVzaG9sZDoge3RocmVzaG9sZH0nKSwgCiAgYWxwaGEgPSA1MCkKYGBgCgojIyMgQ29uY2x1c2lvbnMKCldvcmRjbG91ZCBMSVZHT0xGIC0gQ29udGVudCBnZW5lcmF0ZWQgYnkgTElWIEdvbGYgaXMgbGFyZ2VseSBjb21wcmlzZWQgb24gd29yZHMgaW5kaWNhdGl2ZSBvZiBmb3N0ZXJpbmcgZXhjaXRlbWVudCBhbmQgYXR0ZW50aW9uIHRvIHRoZSBzZXJpZXMuCgpXb3JkY2xvdWQgVXNlcnMgLSBVc2VycyBleHBvc2UgYSBncmVhdGVyIGFtb3VudCBvZiB3b3JkIHVzYWdlIGFuZCBlbW90aW9ucyBiZWhpbmQgdGhvc2Ugd29yZHMgdGhhbiBMSVYgR29sZi4gQSBoaWdoIGZyZXF1ZW5jeSBvZiB1c2luZyBQR0EgVG91ciBieSB1c2VycyBjYW4gYmUgaW5kaWNhdGl2ZSBvZiBlaXRoZXIgc3VwcG9ydCBvciByZXNlbnRtZW50IGZvciB0aGUgY29tcGV0aW5nIGxlYWd1ZSBhbmQgbWF5IG5vdCBuZWNlc3NhcmlseSBhZHZvY2F0ZSBmb3IgZWl0aGVyIGxlYWd1ZS4gQWRkaXRpb25hbGx5LCB0aGVyZSBhcmUgd29yZCBjaG9pY2VzIGJ5IHVzZXJzIHRoYXQgdmVyeSBzaWduaWZpY2FudGx5IGZyb20gTElWIEdvbGYgYXMgdGhleSBoYXZlIGF0dGVtcHRlZCB0byBkaXN0YW5jZSB0aGVtc2VsdmVzIGZyb20gU2F1ZGkgQXJhYmlhbiBjb25uZWN0aW9uLiBUaGUgdXNlcnMgY29udGludWUgdG8gdGFsayBhYm91dCB0aGF0IHRvcGljLgoKQmlncmFtIE5ldHdvcmsgLSBUaGUgQmlncmFtIG5ldHdvcmsgc2hvd3MgdGhhdCB0aGUgd29yZHMgdXNlZCBpbiBzcGVha2luZyBhYm91dCBMSVYgR29sZiByZXByZXNlbnRzIGEgdmVyeSBkaXZpZGVkIHVzZXIgYmFzZSBiZXR3ZWVuIGFjY2VwdGluZyBMSVYgZm9yIHRoZSBhIHNwb3J0aW5nIGxlYWd1ZSBvciBoaWdobGlnaHRpbmcgaXRzIGNvbm5lY3Rpb24gdG8gdGhlIGdvdmVybm1lbnQgb2YgU2F1ZGkgQXJhYmlhLgoKIyMgOC4gQ29ycmVsYXRpb24gCgpUaGUgcHVycG9zZSBvZiB0aGlzIHNlY3Rpb24gaXMgdG8gdW5kZXJzdGFuZCBpZiB0aGVyZSBpcyBhbnkgY29ubmVjdGlvbiBiZXR3ZWVuIGhvdyB3ZWxsIGEgdHdlZXQgaXMgcmVjZWl2ZWQgYW5kIGl0cyBvdmVyYWxsIHNlbnRpbWVudC4gVGhpcyBzZWN0aW9uIHNob3VsZCBhbnN3ZXIgdGhlIHF1ZXN0aW9uIGlmIHRoZSBtb3N0IG5lZ2F0aXZlIG9yIG1vc3QgcG9zaXRpdmUgdHdlZXRzIGFyZSBtb3JlIG9yIGxlc3MgbGlrZWx5IHRvIGJlIHRoZSBjb250ZW50IHRoYXQgaXMgZW5nYWdlZCB3aXRoIHRoZSBtb3N0LgoKYGBge3J9Cgpjb3JyZWxhdGlvbl90ZXN0IDwtIHN1YnNldChmaW5hbF9kYXRhLCBzZWxlY3QgPSAtYyhkYXlfY3JlYXRlZCwgc2NyZWVuX25hbWUsIGxvY2F0aW9uLCBmb2xsb3dlcnNfY291bnQsIGZyaWVuZHNfY291bnQsIGxpc3RlZF9jb3VudCwgZmF2b3VyaXRlc19jb3VudCwgc3RhdHVzZXNfY291bnQsIHNvdXJjZSwgcmV0d2VldF9jb3VudCwgcmV0d2VldF9yYXRpbywgZmF2b3JpdGVfcmF0aW8sIGZhdm9yaXRlX2NvdW50LCB0ZXh0X2NsZWFuKSkKYGBgCgpgYGB7cn0KI0RldGVybWluZSByZWxhdGlvbnNoaXAgYmV0d2VlbiByZWNlcHRpb24gYW5kIHNlbnRpbWVudCBmb3IgZW50aXJlIGRhdGEgc2V0CmNvci5tYXRyaXhfYSA8LSBjb3IoY29ycmVsYXRpb25fdGVzdFsxOjJdKQpjb3IubWF0cml4X2EKYGBgCgpgYGB7cn0KI0VsaW1pbmF0ZSBleGNlc3MgdmFyaWFibGVzCmNvcnJlbGF0aW9uX3Rlc3RfTElWIDwtIHN1YnNldChMSVZHb2xmLCBzZWxlY3QgPSAtYyhkYXlfY3JlYXRlZCwgc2NyZWVuX25hbWUsIGxvY2F0aW9uLCBmb2xsb3dlcnNfY291bnQsIGZyaWVuZHNfY291bnQsIGxpc3RlZF9jb3VudCwgZmF2b3VyaXRlc19jb3VudCwgc3RhdHVzZXNfY291bnQsIHNvdXJjZSwgcmV0d2VldF9jb3VudCwgcmV0d2VldF9yYXRpbywgZmF2b3JpdGVfcmF0aW8sIGZhdm9yaXRlX2NvdW50LCB0ZXh0X2NsZWFuKSkKYGBgCgpgYGB7cn0KI0RldGVybWluZSByZWxhdGlvbnNoaXAgYmV0d2VlbiByZWNlcHRpb24gYW5kIHNlbnRpbWVudCBmb3IgTElWIEdvbGYgZGF0YSBmcmFtZQpjb3IubWF0cml4YiA8LSBjb3IoY29ycmVsYXRpb25fdGVzdF9MSVZbMToyXSkKY29yLm1hdHJpeGIKYGBgCgpgYGB7cn0KI0VsaW1pbmF0ZSBleGNlc3MgdmFyaWFibGVzCmNvcnJlbGF0aW9uX3Rlc3Rfb25seV91c2VycyA8LSBzdWJzZXQob25seV91c2Vycywgc2VsZWN0ID0gLWMoZGF5X2NyZWF0ZWQsIHNjcmVlbl9uYW1lLCBsb2NhdGlvbiwgZm9sbG93ZXJzX2NvdW50LCBmcmllbmRzX2NvdW50LCBsaXN0ZWRfY291bnQsIGZhdm91cml0ZXNfY291bnQsIHN0YXR1c2VzX2NvdW50LCBzb3VyY2UsIHJldHdlZXRfY291bnQsIHJldHdlZXRfcmF0aW8sIGZhdm9yaXRlX3JhdGlvLCBmYXZvcml0ZV9jb3VudCwgdGV4dF9jbGVhbikpCmBgYAoKYGBge3J9CiNEZXRlcm1pbmUgcmVsYXRpb25zaGlwIGJldHdlZW4gcmVjZXB0aW9uIGFuZCBzZW50aW1lbnQgZm9yIExJViBHb2xmIGRhdGEgZnJhbWUKY29yLm1hdHJpeGMgPC0gY29yKGNvcnJlbGF0aW9uX3Rlc3Rfb25seV91c2Vyc1sxOjJdKQpjb3IubWF0cml4YwpgYGAKCiMjIDkuIExpbmVhciBSZWdyZXNzaW9uCgpUaGUgcHVycG9zZSBvZiB0aGlzIHNlY3Rpb24gaXMgdG8gdW5kZXJzdGFuZCBmdXR1cmUgYWN0aXZpdHkgZnJvbSB1c2VycyBvbiB0aGUgcGxhdGZvcm0gYnkgdGVzdGluZyB0aGUgY29ubmVjdGlvbiBiZXR3ZWVuIGhvdyBmcmVxdWVudGx5IExJViBHb2xmIGF1dGhvcnMgY29udGVudCBhbmQgbWVhc3VyaW5nIHRoZSBpbXBhY3QgdGhhdCBoYXMgb24gbW90aXZhdGluZyB1c2VycyB0byBnZW5lcmF0ZSBjb250ZW50LgoKSSB3aWxsIGNyZWF0ZSBhIG1vZGVsIHRoYXQgd2lsbCBwcmVkaWN0IHVzZXIgYWN0aXZpdHkgYmFzZWQgb24gdGhlIGFtb3VudCBvZiBhY3Rpdml0eSBmcm9tIExJViBHb2xmLgoKYGBge3J9CiN4ID0gbnVtYmVyIG9mIHBvc3RzIGVhY2ggZGF5IGJ5IExJViBHb2xmCiN5ID0gbnVtYmVyIG9mIHVzZXIgcG9zdHMKI0ZvciBldmVyeSBvbmUgTElWIEdvbGYgcG9zdCB3ZSBzaG91bGQgZXhwZWN0IGEgcmVzcG9uc2Ugb2YgYW4gYWRkaXRpb25hbCAxLjAzMSB1c2VyIHBvc3RzLgp4IDwtIGMoMSwyLDEsMSwxLDIsMywyLDIsNCwyLDEsMCwxLDEsMSwxLDAsMSwxLDAsMCkKeSA8LSBjKDE1LDE0LDE4LDI4LDMxLDI2LDMyLDI0LDMwLDI2LDM3LDI1LDI4LDMwLDI5LDI2LDE2LDEzLDE5LDIyLDIzLDM4KQpMSVZfdXNlcl9yZWxhdGlvbnNoaXAgPC0gbG0oeX54KQpwcmludChMSVZfdXNlcl9yZWxhdGlvbnNoaXApCmBgYAoKYGBge3J9CmRhdGEgPC0gZGF0YS5mcmFtZSh5LHgpCmBgYAoKYGBge3J9CmNvci5tYXRyaXhkIDwtIGNvcihkYXRhWzE6Ml0pCmNvci5tYXRyaXhkCmBgYAoKYGBge3J9CnN1bW1hcnkoTElWX3VzZXJfcmVsYXRpb25zaGlwKQpgYGAKCmBgYHtyfQpSU0UgPC0gNy4xMDEKZXJyb3IgPC0gUlNFL21lYW4oeSkKZXJyb3IKYGBgCgpgYGB7cn0KYSA8LSBkYXRhLmZyYW1lKHggPSAxMCkKcmVzdWx0IDwtIHByZWRpY3QoTElWX3VzZXJfcmVsYXRpb25zaGlwLCBhKQpwcmludChyZXN1bHQpCmBgYAoKIyMjIExpbmVhciBSZWdyZXNzaW9uIFBsb3QKCmBgYHtyLCBtZXNzYWdlPUZBTFNFfQpsaW5lYXJfcGxvdCA8LSBnZ3Bsb3QoZGF0YSwgYWVzKHggPSB4LCB5ID0geSkpICsgCiAgZ2VvbV9wb2ludCggY29sb3I9IiM2OWIzYTIiKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtICwgY29sb3I9InJlZCIsIHNlPVRSVUUpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICB4bGFiKCJOdW1iZXIgb2YgTElWIEdvbGYgVHdlZXRzIikgKwogIHlsYWIoIk51bWJlciBvZiBVc2VyIFR3ZWV0cyIpICsKICBsYWJzKHRpdGxlID0gIkxpbmVhciBSZWdyZXNzaW9uIE1vZGVsIG9mIExJVkdvbGYgYW5kIFVzZXIgR2VuZXJhdGVkIENvbnRlbnQiLAogICAgICAgc3VidGl0bGUgPSAiTm92ZW1iZXIgOHRoIHRvIE5vdmVtYmVyIDI5dGggMjAyMiIsCiAgICAgICBjYXB0aW9uID0gIkRhdGEgU291cmNlOiBUd2l0dGVyIHNlYXJjaCBmb3IgI0xJVkdvbGYiKQpsaW5lYXJfcGxvdCAKYGBgCgojIyMgQ29uY2x1c2lvbgoKSWYgYWxsIG90aGVyIHZhcmlhYmxlcyByZW1haW4gY29uc3RhbnQsIHRoZXJlIGlzIGEgY29ubmVjdGlvbiBiZXR3ZWVuIGhvdyBtYW55IHR3ZWV0cyBMSVYgR29sZiBjcmVhdGVzIGFuZCB0aGUgcmVzcG9uc2UgZnJvbSB1c2VycyBvbiB0aGUgcGxhdGZvcm0uIFdoaWxlIHRoaXMgbW9kZWwgZGVzY3JpYmVzIHRoZSBhIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHVzZXJzIGFuZCBMSVZHb2xmIHR3aXR0ZXIgYWN0aXZpdHksIGZyb20gYSBidXNpbmVzcyBwZXJzcGVjdGl2ZSwgaXQgcGFpbnRzIHRoZSBwaWN0dXJlIG9mIGFuIG9yZ2FuaXphdGlvbiBmYWlsaW5nIHRvIG1vdGl2YXRlIGl0cyBmb2xsb3dlcnMgdG8gdGFsayBhYm91dCB0aGVpciBwcm9kdWN0IGFuZCBhdHRyYWN0IGFkZGl0aW9uYWwgZm9sbG93ZXJzLiBJZiBMSVZHb2xmIGNyZWF0ZWQgemVybyB0d2VldHMsIGl0IHdvdWxkIGJlIHJlYXNvbmFibGUgdG8gZXhwZWN0IDIzIHVzZXIgZ2VuZXJhdGVkIHR3ZWV0cy4gSG93ZXZlciwgYXMgdGhleSBiZWNvbWUgbW9yZSBhY3RpdmUgb24gdGhlIHBsYXRmb3JtLCB0aGVpciBlZmZvcnRzIGFyZSBub3QgcmV0dXJuZWQgYXQgYSB2ZXJ5IGhpZ2ggcmF0ZSwgZXNwZWNpYWxseSB3aGVuIGNvbnNpZGVyaW5nIHRoZSBhbW91bnQgb2YgZm9sbG93ZXJzIHRoZXkgaGF2ZS4gSWYgdXNlcnMgZ2VuZXJhdGUgMTAgdHdlZXRzLCBpdCBpcyByZWFzb25hYmxlIHRvIGV4cGVjdCAzNCB1c2VyIHR3ZWV0cywgd2hpY2ggbWF5IG5vdCBiZSB3b3J0aCB0aGVpciB0aW1lLiBUaGUgbW9kZWwgY3JlYXRlZCBkdXJpbmcgdGhpcyBzdHVkeSBjcmVhdGVzIGFuIGF2ZXJhZ2UgcHJlZGljdGlvbiBlcnJvciByYXRlIG9mIDI4JS4gIA==