Package loading:

library(tidyverse)
library(DT)
library(plotly)               # This package does interactive graphs
library(rtweet)               # This package accesses Twitter data
library(lubridate)  

For this notebook, I am using rtweet which is a package that accesses data from twitter. I am also using lubridate and plotly to help with the data formatting and presentation.

get_token()        # this shows the token. make sure key is the same as consumer_key above
<Token>
<oauth_endpoint>
 request:   https://api.twitter.com/oauth/request_token
 authorize: https://api.twitter.com/oauth/authenticate
 access:    https://api.twitter.com/oauth/access_token
<oauth_app> RTweets for PSYC 541
  key:    9z2JeDsn0047F1W96VWxZCEVV
  secret: <hidden>
<credentials> oauth_token, oauth_token_secret
---

The above R code allows me to access the Twitter API data using my developer account.

  1. What I want to do is examine the Twitter habits of Donald Trump on his personal Twitter account, realDonaldTrump. The R code below pulls data for the most recent 10,000 Tweets.
trump_tweets <- get_timeline("realDonaldTrump", n = 10000)
  1. One interesting question is: which hashtags does Donald Trump use the most? The following R code creates a table of every hashtag Donald Trump has used along with the number of times that he has used it, ranked in order from most uses to least.
trump_tweets %>% 
  select(hashtags) %>%                   # Focus on the hashtags
  unnest() %>%                           # Separate multiple hashtags
  mutate(hashtags = tolower(hashtags)) %>%      # make all hashtags lowercase
  count(hashtags, sort=TRUE) %>%                # count how often they appear
  datatable()                                   # create an interactive table

NA
NA

As this table shows, the great majority of Donald Trump’s Tweets do not include a hashtag at all, but the next most popular hashtags include maga, usmca, kag2020, 2a, and kag. Apparently, Donald Trump is very fond of using his maga slogan as a hashtag.

  1. Now, I would like to find out how many tweets Donald Trump creates per day. The R code below will display how many tweets Donald Trump created on each day within our dataset.
trump_tweets %>% 
  group_by(day = date(created_at)) %>%    # extract the date, group by it
  summarize(tweets_per_day = n())         # count the number of tweets each day

Just by taking a quick glance, it looks like Donald Trump is a frequent tweeter–sending out sometimes several dozen tweets in a day.

So, I now would like to find out how many tweets Donald Trump has made on average per day. The R code below will find and display this average for us.

trump_tweets %>% 
  group_by(day = date(created_at)) %>%    # extract the date, group by it
  summarize(tweets_per_day = n()) %>%    # count the number of tweets each day
  summarize(mean(tweets_per_day))

Wow! It appears that Donald Trump averages over thirty tweets per day. It seems to me that that’s a lot of tweeting!

  1. I am now curious about what the number of Donald Trump’s tweets per day would like like on a histogram. Of course, it is nice to be using plotly, which allows for a dynamic graph with options for the user to play with built-in to the interface. The R code below creates this plotly graphic for us, which is interactive.
trump_tweets %>%
  mutate(day = date(created_at)) %>% 
  plot_ly(x = ~day) %>%                                        
  add_histogram() %>% 
  layout(title = "Number of tweets from @realDonaldTrump")

It appears that Trump’s tweets come noticabley more frequently on some days than on others.

  1. So, we’ve seen Trump’s tweet counts by day, but now I am curious about whether Donald Trump does most of his tweeting at a certain time of day. The R code below creates a table that shows how many tweets Trump has created by the hour (0 is midnight, 1 is 1 AM, and so on), using Eastern Standard Time, because Washington D.C. uses Eastern Standard Time and that is where Donald Trump lives, and possibly where he has sent most of his tweets from.
trump_tweets %>% 
  mutate(time = with_tz(created_at, "America/New_York")) %>% 
  mutate(time = hour(time)) %>% 
  count(time) %>% 
  datatable(options = (list(pageLength = 24)), rownames = F)

NA

Surprisingly, it looks like Donald Trump has created a good number of tweets at midnight, although it seems that most of his tweeting occurs between 7am and 10am.

Once again, I would like to display this data with plotly because it’s more fun and more intuitive that way. This graph shows us just how quiet Donald Trump’s Twitter account has been at 3 and 4 in the morning, and how prolific he is at 9am.

trump_tweets %>% 
  mutate(time = with_tz(created_at, "America/New_York")) %>%    # convert to Eastern time zone
  mutate(time = hour(time)) %>%                                 # extract the hour
  plot_ly(x = ~time) %>%                                        # create plotly graph
  add_histogram() %>%                                              # make histogram
layout(title = "When Does @realDonaldTrump Tweet?", 
         xaxis = list(title = "Time of Day (0 = midnight)"),
         yaxis = list(title = "Number of Tweets"))
  1. Does Donald Trump create more tweets on some days of the week than on others? Let’s take a look. The R code below creates a table showing each day of the week, and how many tweets Donald Trump has sent overall on each.
trump_tweets %>% 
  mutate(Day = wday(created_at,           # find the weekday that the tweet was created
                    label = T)) %>%       # use labels (Sun, Mon, etc) rather than numbers
  count(Day) %>%                          # count the number of tweets each day
  datatable(rownames = F)

NA

We can see that Donald Trump sends a ton of tweets of Wednesdays especially, and slightly fewer tweets on Mondays, but overall he is about equally likely to send a lot of tweets no matter what day of the week it is.

Now, let’s use R to create another plotly graphic to get a better look at this pattern.

trump_tweets %>% 
  mutate(Day = wday(created_at,           # find the weekday that the tweet was created
                    label = T)) %>%       # use labels (Sun, Mon, etc) rather than numbers
  plot_ly(x = ~Day) %>%
  add_histogram()

This graph illustrates this same pattern; more tweets on Wednesdays, fewer tweets on Mondays, but plenty of tweets no matter what day of the week.

  1. A heatmap is a graphic that uses a gradient ranging from one color to another (for instance, from bright yellow to dark blue) to create a visually-appealing representation of data. In this case, I would like to use plotly to create a heatmap to chart out the frequency of Donald Trump tweets according to both the hour of the day and the day of the week. This helps us to really quickly understand the question of “When does Donald Trump tweet?” - The heat map shows brighter/yellower coloration in the times/days that Donald Trump tweets more, and shows the darker/bluer coloration in those times/days when he tweets less.
trump_tweets %>% 
  mutate(day = wday(created_at, label = T)) %>% 
  mutate(hour = hour(with_tz(created_at, "America/New_York"))) %>% 
  plot_ly(x = ~day, y = ~hour) %>% 
  add_histogram2d(nbinsx = 7, nbinsy = 24) %>%
  layout(title = "When Does @realDonaldTrump Tweet?", 
         xaxis = list(title = "Day of the Week"),
         yaxis = list(title = "Time of Day (0 = Midnight)"))

This heatmap shows us that Donald Trump does the most tweeting on Wednesdays before ten in the morning.

LS0tCnRpdGxlOiAicnR3ZWV0IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpQYWNrYWdlIGxvYWRpbmc6CgpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoRFQpCmxpYnJhcnkocGxvdGx5KSAgICAgICAgICAgICAgICMgVGhpcyBwYWNrYWdlIGRvZXMgaW50ZXJhY3RpdmUgZ3JhcGhzCmxpYnJhcnkocnR3ZWV0KSAgICAgICAgICAgICAgICMgVGhpcyBwYWNrYWdlIGFjY2Vzc2VzIFR3aXR0ZXIgZGF0YQpsaWJyYXJ5KGx1YnJpZGF0ZSkgIApgYGAKCkZvciB0aGlzIG5vdGVib29rLCBJIGFtIHVzaW5nIHJ0d2VldCB3aGljaCBpcyBhIHBhY2thZ2UgdGhhdCBhY2Nlc3NlcyBkYXRhIGZyb20gdHdpdHRlci4gSSBhbSBhbHNvIHVzaW5nIGx1YnJpZGF0ZSBhbmQgcGxvdGx5IHRvIGhlbHAgd2l0aCB0aGUgZGF0YSBmb3JtYXR0aW5nIGFuZCBwcmVzZW50YXRpb24uIAoKCmBgYHtyfQpnZXRfdG9rZW4oKSAgICAgICAgIyB0aGlzIHNob3dzIHRoZSB0b2tlbi4gbWFrZSBzdXJlIGtleSBpcyB0aGUgc2FtZSBhcyBjb25zdW1lcl9rZXkgYWJvdmUKYGBgCgpUaGUgYWJvdmUgUiBjb2RlIGFsbG93cyBtZSB0byBhY2Nlc3MgdGhlIFR3aXR0ZXIgQVBJIGRhdGEgdXNpbmcgbXkgZGV2ZWxvcGVyIGFjY291bnQuIAoKCjEuIFdoYXQgSSB3YW50IHRvIGRvIGlzIGV4YW1pbmUgdGhlIFR3aXR0ZXIgaGFiaXRzIG9mIERvbmFsZCBUcnVtcCBvbiBoaXMgcGVyc29uYWwgVHdpdHRlciBhY2NvdW50LCByZWFsRG9uYWxkVHJ1bXAuIFRoZSBSIGNvZGUgYmVsb3cgcHVsbHMgZGF0YSBmb3IgdGhlIG1vc3QgcmVjZW50IDEwLDAwMCBUd2VldHMuCgpgYGB7cn0KdHJ1bXBfdHdlZXRzIDwtIGdldF90aW1lbGluZSgicmVhbERvbmFsZFRydW1wIiwgbiA9IDEwMDAwKQpgYGAKCgoyLiBPbmUgaW50ZXJlc3RpbmcgcXVlc3Rpb24gaXM6IHdoaWNoIGhhc2h0YWdzIGRvZXMgRG9uYWxkIFRydW1wIHVzZSB0aGUgbW9zdD8gVGhlIGZvbGxvd2luZyBSIGNvZGUgY3JlYXRlcyBhIHRhYmxlIG9mIGV2ZXJ5IGhhc2h0YWcgRG9uYWxkIFRydW1wIGhhcyB1c2VkIGFsb25nIHdpdGggdGhlIG51bWJlciBvZiB0aW1lcyB0aGF0IGhlIGhhcyB1c2VkIGl0LCByYW5rZWQgaW4gb3JkZXIgZnJvbSBtb3N0IHVzZXMgdG8gbGVhc3QuIAoKYGBge3J9CnRydW1wX3R3ZWV0cyAlPiUgCiAgc2VsZWN0KGhhc2h0YWdzKSAlPiUgICAgICAgICAgICAgICAgICAgIyBGb2N1cyBvbiB0aGUgaGFzaHRhZ3MKICB1bm5lc3QoKSAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgICAjIFNlcGFyYXRlIG11bHRpcGxlIGhhc2h0YWdzCiAgbXV0YXRlKGhhc2h0YWdzID0gdG9sb3dlcihoYXNodGFncykpICU+JSAgICAgICMgbWFrZSBhbGwgaGFzaHRhZ3MgbG93ZXJjYXNlCiAgY291bnQoaGFzaHRhZ3MsIHNvcnQ9VFJVRSkgJT4lICAgICAgICAgICAgICAgICMgY291bnQgaG93IG9mdGVuIHRoZXkgYXBwZWFyCiAgZGF0YXRhYmxlKCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgY3JlYXRlIGFuIGludGVyYWN0aXZlIHRhYmxlCgoKYGBgICAKCkFzIHRoaXMgdGFibGUgc2hvd3MsIHRoZSBncmVhdCBtYWpvcml0eSBvZiBEb25hbGQgVHJ1bXAncyBUd2VldHMgZG8gbm90IGluY2x1ZGUgYSBoYXNodGFnIGF0IGFsbCwgYnV0IHRoZSBuZXh0IG1vc3QgcG9wdWxhciBoYXNodGFncyBpbmNsdWRlIG1hZ2EsIHVzbWNhLCBrYWcyMDIwLCAyYSwgYW5kIGthZy4gQXBwYXJlbnRseSwgRG9uYWxkIFRydW1wIGlzIHZlcnkgZm9uZCBvZiB1c2luZyBoaXMgbWFnYSBzbG9nYW4gYXMgYSBoYXNodGFnLiAKCgozLiBOb3csIEkgd291bGQgbGlrZSB0byBmaW5kIG91dCBob3cgbWFueSB0d2VldHMgRG9uYWxkIFRydW1wIGNyZWF0ZXMgcGVyIGRheS4gVGhlIFIgY29kZSBiZWxvdyB3aWxsIGRpc3BsYXkgaG93IG1hbnkgdHdlZXRzIERvbmFsZCBUcnVtcCBjcmVhdGVkIG9uIGVhY2ggZGF5IHdpdGhpbiBvdXIgZGF0YXNldC4gCgpgYGB7cn0KdHJ1bXBfdHdlZXRzICU+JSAKICBncm91cF9ieShkYXkgPSBkYXRlKGNyZWF0ZWRfYXQpKSAlPiUgICAgIyBleHRyYWN0IHRoZSBkYXRlLCBncm91cCBieSBpdAogIHN1bW1hcml6ZSh0d2VldHNfcGVyX2RheSA9IG4oKSkgICAgICAgICAjIGNvdW50IHRoZSBudW1iZXIgb2YgdHdlZXRzIGVhY2ggZGF5CmBgYAoKSnVzdCBieSB0YWtpbmcgYSBxdWljayBnbGFuY2UsIGl0IGxvb2tzIGxpa2UgRG9uYWxkIFRydW1wIGlzIGEgZnJlcXVlbnQgdHdlZXRlci0tc2VuZGluZyBvdXQgc29tZXRpbWVzIHNldmVyYWwgZG96ZW4gdHdlZXRzIGluIGEgZGF5LiAKClNvLCBJIG5vdyB3b3VsZCBsaWtlIHRvIGZpbmQgb3V0IGhvdyBtYW55IHR3ZWV0cyBEb25hbGQgVHJ1bXAgaGFzIG1hZGUgb24gYXZlcmFnZSBwZXIgZGF5LiBUaGUgUiBjb2RlIGJlbG93IHdpbGwgZmluZCBhbmQgZGlzcGxheSB0aGlzIGF2ZXJhZ2UgZm9yIHVzLiAKCmBgYHtyfQp0cnVtcF90d2VldHMgJT4lIAogIGdyb3VwX2J5KGRheSA9IGRhdGUoY3JlYXRlZF9hdCkpICU+JSAgICAjIGV4dHJhY3QgdGhlIGRhdGUsIGdyb3VwIGJ5IGl0CiAgc3VtbWFyaXplKHR3ZWV0c19wZXJfZGF5ID0gbigpKSAlPiUgICAgIyBjb3VudCB0aGUgbnVtYmVyIG9mIHR3ZWV0cyBlYWNoIGRheQogIHN1bW1hcml6ZShtZWFuKHR3ZWV0c19wZXJfZGF5KSkKYGBgCgpXb3chIEl0IGFwcGVhcnMgdGhhdCBEb25hbGQgVHJ1bXAgYXZlcmFnZXMgb3ZlciB0aGlydHkgdHdlZXRzIHBlciBkYXkuIEl0IHNlZW1zIHRvIG1lIHRoYXQgdGhhdCdzIGEgbG90IG9mIHR3ZWV0aW5nISAKCgo0LiBJIGFtIG5vdyBjdXJpb3VzIGFib3V0IHdoYXQgdGhlIG51bWJlciBvZiBEb25hbGQgVHJ1bXAncyB0d2VldHMgcGVyIGRheSB3b3VsZCBsaWtlIGxpa2Ugb24gYSBoaXN0b2dyYW0uIE9mIGNvdXJzZSwgaXQgaXMgbmljZSB0byBiZSB1c2luZyBwbG90bHksIHdoaWNoIGFsbG93cyBmb3IgYSBkeW5hbWljIGdyYXBoIHdpdGggb3B0aW9ucyBmb3IgdGhlIHVzZXIgdG8gcGxheSB3aXRoIGJ1aWx0LWluIHRvIHRoZSBpbnRlcmZhY2UuIFRoZSBSIGNvZGUgYmVsb3cgY3JlYXRlcyB0aGlzIHBsb3RseSBncmFwaGljIGZvciB1cywgd2hpY2ggaXMgaW50ZXJhY3RpdmUuIAoKYGBge3J9CnRydW1wX3R3ZWV0cyAlPiUKICBtdXRhdGUoZGF5ID0gZGF0ZShjcmVhdGVkX2F0KSkgJT4lIAogIHBsb3RfbHkoeCA9IH5kYXkpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICBhZGRfaGlzdG9ncmFtKCkgJT4lIAogIGxheW91dCh0aXRsZSA9ICJOdW1iZXIgb2YgdHdlZXRzIGZyb20gQHJlYWxEb25hbGRUcnVtcCIpCmBgYAoKSXQgYXBwZWFycyB0aGF0IFRydW1wJ3MgdHdlZXRzIGNvbWUgbm90aWNhYmxleSBtb3JlIGZyZXF1ZW50bHkgb24gc29tZSBkYXlzIHRoYW4gb24gb3RoZXJzLiAKCgo1LiBTbywgd2UndmUgc2VlbiBUcnVtcCdzIHR3ZWV0IGNvdW50cyBieSBkYXksIGJ1dCBub3cgSSBhbSBjdXJpb3VzIGFib3V0IHdoZXRoZXIgRG9uYWxkIFRydW1wIGRvZXMgbW9zdCBvZiBoaXMgdHdlZXRpbmcgYXQgYSBjZXJ0YWluIHRpbWUgb2YgZGF5LiBUaGUgUiBjb2RlIGJlbG93IGNyZWF0ZXMgYSB0YWJsZSB0aGF0IHNob3dzIGhvdyBtYW55IHR3ZWV0cyBUcnVtcCBoYXMgY3JlYXRlZCBieSB0aGUgaG91ciAoMCBpcyBtaWRuaWdodCwgMSBpcyAxIEFNLCBhbmQgc28gb24pLCB1c2luZyBFYXN0ZXJuIFN0YW5kYXJkIFRpbWUsIGJlY2F1c2UgV2FzaGluZ3RvbiBELkMuIHVzZXMgRWFzdGVybiBTdGFuZGFyZCBUaW1lIGFuZCB0aGF0IGlzIHdoZXJlIERvbmFsZCBUcnVtcCBsaXZlcywgYW5kIHBvc3NpYmx5IHdoZXJlIGhlIGhhcyBzZW50IG1vc3Qgb2YgaGlzIHR3ZWV0cyBmcm9tLiAKCmBgYHtyfQp0cnVtcF90d2VldHMgJT4lIAogIG11dGF0ZSh0aW1lID0gd2l0aF90eihjcmVhdGVkX2F0LCAiQW1lcmljYS9OZXdfWW9yayIpKSAlPiUgCiAgbXV0YXRlKHRpbWUgPSBob3VyKHRpbWUpKSAlPiUgCiAgY291bnQodGltZSkgJT4lIAogIGRhdGF0YWJsZShvcHRpb25zID0gKGxpc3QocGFnZUxlbmd0aCA9IDI0KSksIHJvd25hbWVzID0gRikKCmBgYAoKU3VycHJpc2luZ2x5LCBpdCBsb29rcyBsaWtlIERvbmFsZCBUcnVtcCBoYXMgY3JlYXRlZCBhIGdvb2QgbnVtYmVyIG9mIHR3ZWV0cyBhdCBtaWRuaWdodCwgYWx0aG91Z2ggaXQgc2VlbXMgdGhhdCBtb3N0IG9mIGhpcyB0d2VldGluZyBvY2N1cnMgYmV0d2VlbiA3YW0gYW5kIDEwYW0uIAoKT25jZSBhZ2FpbiwgSSB3b3VsZCBsaWtlIHRvIGRpc3BsYXkgdGhpcyBkYXRhIHdpdGggcGxvdGx5IGJlY2F1c2UgaXQncyBtb3JlIGZ1biBhbmQgbW9yZSBpbnR1aXRpdmUgdGhhdCB3YXkuIFRoaXMgZ3JhcGggc2hvd3MgdXMganVzdCBob3cgcXVpZXQgRG9uYWxkIFRydW1wJ3MgVHdpdHRlciBhY2NvdW50IGhhcyBiZWVuIGF0IDMgYW5kIDQgaW4gdGhlIG1vcm5pbmcsIGFuZCBob3cgcHJvbGlmaWMgaGUgaXMgYXQgOWFtLiAKCmBgYHtyfQp0cnVtcF90d2VldHMgJT4lIAogIG11dGF0ZSh0aW1lID0gd2l0aF90eihjcmVhdGVkX2F0LCAiQW1lcmljYS9OZXdfWW9yayIpKSAlPiUgICAgIyBjb252ZXJ0IHRvIEVhc3Rlcm4gdGltZSB6b25lCiAgbXV0YXRlKHRpbWUgPSBob3VyKHRpbWUpKSAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGV4dHJhY3QgdGhlIGhvdXIKICBwbG90X2x5KHggPSB+dGltZSkgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgY3JlYXRlIHBsb3RseSBncmFwaAogIGFkZF9oaXN0b2dyYW0oKSAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBtYWtlIGhpc3RvZ3JhbQpsYXlvdXQodGl0bGUgPSAiV2hlbiBEb2VzIEByZWFsRG9uYWxkVHJ1bXAgVHdlZXQ/IiwgCiAgICAgICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICJUaW1lIG9mIERheSAoMCA9IG1pZG5pZ2h0KSIpLAogICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiTnVtYmVyIG9mIFR3ZWV0cyIpKQpgYGAKCgo2LiBEb2VzIERvbmFsZCBUcnVtcCBjcmVhdGUgbW9yZSB0d2VldHMgb24gc29tZSBkYXlzIG9mIHRoZSB3ZWVrIHRoYW4gb24gb3RoZXJzPyBMZXQncyB0YWtlIGEgbG9vay4gVGhlIFIgY29kZSBiZWxvdyBjcmVhdGVzIGEgdGFibGUgc2hvd2luZyBlYWNoIGRheSBvZiB0aGUgd2VlaywgYW5kIGhvdyBtYW55IHR3ZWV0cyBEb25hbGQgVHJ1bXAgaGFzIHNlbnQgb3ZlcmFsbCBvbiBlYWNoLiAKCmBgYHtyfQp0cnVtcF90d2VldHMgJT4lIAogIG11dGF0ZShEYXkgPSB3ZGF5KGNyZWF0ZWRfYXQsICAgICAgICAgICAjIGZpbmQgdGhlIHdlZWtkYXkgdGhhdCB0aGUgdHdlZXQgd2FzIGNyZWF0ZWQKICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IFQpKSAlPiUgICAgICAgIyB1c2UgbGFiZWxzIChTdW4sIE1vbiwgZXRjKSByYXRoZXIgdGhhbiBudW1iZXJzCiAgY291bnQoRGF5KSAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgICMgY291bnQgdGhlIG51bWJlciBvZiB0d2VldHMgZWFjaCBkYXkKICBkYXRhdGFibGUocm93bmFtZXMgPSBGKQoKYGBgCgpXZSBjYW4gc2VlIHRoYXQgRG9uYWxkIFRydW1wIHNlbmRzIGEgdG9uIG9mIHR3ZWV0cyBvZiBXZWRuZXNkYXlzIGVzcGVjaWFsbHksIGFuZCBzbGlnaHRseSBmZXdlciB0d2VldHMgb24gTW9uZGF5cywgYnV0IG92ZXJhbGwgaGUgaXMgYWJvdXQgZXF1YWxseSBsaWtlbHkgdG8gc2VuZCBhIGxvdCBvZiB0d2VldHMgbm8gbWF0dGVyIHdoYXQgZGF5IG9mIHRoZSB3ZWVrIGl0IGlzLiAKCk5vdywgbGV0J3MgdXNlIFIgdG8gY3JlYXRlIGFub3RoZXIgcGxvdGx5IGdyYXBoaWMgdG8gZ2V0IGEgYmV0dGVyIGxvb2sgYXQgdGhpcyBwYXR0ZXJuLiAKCmBgYHtyfQp0cnVtcF90d2VldHMgJT4lIAogIG11dGF0ZShEYXkgPSB3ZGF5KGNyZWF0ZWRfYXQsICAgICAgICAgICAjIGZpbmQgdGhlIHdlZWtkYXkgdGhhdCB0aGUgdHdlZXQgd2FzIGNyZWF0ZWQKICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IFQpKSAlPiUgICAgICAgIyB1c2UgbGFiZWxzIChTdW4sIE1vbiwgZXRjKSByYXRoZXIgdGhhbiBudW1iZXJzCiAgcGxvdF9seSh4ID0gfkRheSkgJT4lCiAgYWRkX2hpc3RvZ3JhbSgpCmBgYAoKVGhpcyBncmFwaCBpbGx1c3RyYXRlcyB0aGlzIHNhbWUgcGF0dGVybjsgbW9yZSB0d2VldHMgb24gV2VkbmVzZGF5cywgZmV3ZXIgdHdlZXRzIG9uIE1vbmRheXMsIGJ1dCBwbGVudHkgb2YgdHdlZXRzIG5vIG1hdHRlciB3aGF0IGRheSBvZiB0aGUgd2Vlay4gCgoKNy4gQSBoZWF0bWFwIGlzIGEgZ3JhcGhpYyB0aGF0IHVzZXMgYSBncmFkaWVudCByYW5naW5nIGZyb20gb25lIGNvbG9yIHRvIGFub3RoZXIgKGZvciBpbnN0YW5jZSwgZnJvbSBicmlnaHQgeWVsbG93IHRvIGRhcmsgYmx1ZSkgdG8gY3JlYXRlIGEgdmlzdWFsbHktYXBwZWFsaW5nIHJlcHJlc2VudGF0aW9uIG9mIGRhdGEuIEluIHRoaXMgY2FzZSwgSSB3b3VsZCBsaWtlIHRvIHVzZSBwbG90bHkgdG8gY3JlYXRlIGEgaGVhdG1hcCB0byBjaGFydCBvdXQgdGhlIGZyZXF1ZW5jeSBvZiBEb25hbGQgVHJ1bXAgdHdlZXRzIGFjY29yZGluZyB0byBib3RoIHRoZSBob3VyIG9mIHRoZSBkYXkgYW5kIHRoZSBkYXkgb2YgdGhlIHdlZWsuIFRoaXMgaGVscHMgdXMgdG8gcmVhbGx5IHF1aWNrbHkgdW5kZXJzdGFuZCB0aGUgcXVlc3Rpb24gb2YgIldoZW4gZG9lcyBEb25hbGQgVHJ1bXAgdHdlZXQ/IiAtIFRoZSBoZWF0IG1hcCBzaG93cyBicmlnaHRlci95ZWxsb3dlciBjb2xvcmF0aW9uIGluIHRoZSB0aW1lcy9kYXlzIHRoYXQgRG9uYWxkIFRydW1wIHR3ZWV0cyBtb3JlLCBhbmQgc2hvd3MgdGhlIGRhcmtlci9ibHVlciBjb2xvcmF0aW9uIGluIHRob3NlIHRpbWVzL2RheXMgd2hlbiBoZSB0d2VldHMgbGVzcy4gCgpgYGB7cn0KdHJ1bXBfdHdlZXRzICU+JSAKICBtdXRhdGUoZGF5ID0gd2RheShjcmVhdGVkX2F0LCBsYWJlbCA9IFQpKSAlPiUgCiAgbXV0YXRlKGhvdXIgPSBob3VyKHdpdGhfdHooY3JlYXRlZF9hdCwgIkFtZXJpY2EvTmV3X1lvcmsiKSkpICU+JSAKICBwbG90X2x5KHggPSB+ZGF5LCB5ID0gfmhvdXIpICU+JSAKICBhZGRfaGlzdG9ncmFtMmQobmJpbnN4ID0gNywgbmJpbnN5ID0gMjQpICU+JQogIGxheW91dCh0aXRsZSA9ICJXaGVuIERvZXMgQHJlYWxEb25hbGRUcnVtcCBUd2VldD8iLCAKICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIkRheSBvZiB0aGUgV2VlayIpLAogICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiVGltZSBvZiBEYXkgKDAgPSBNaWRuaWdodCkiKSkKYGBgCgpUaGlzIGhlYXRtYXAgc2hvd3MgdXMgdGhhdCBEb25hbGQgVHJ1bXAgZG9lcyB0aGUgbW9zdCB0d2VldGluZyBvbiBXZWRuZXNkYXlzIGJlZm9yZSB0ZW4gaW4gdGhlIG1vcm5pbmcuIAoK