library(tidyverse)
library(DT)
library(plotly)              
library(rtweet)               
library(lubridate)  
  1. The following table shows the top tweets that were made about Elon Musk. The tweets are ranked in popularity according to how many retweets the tweet has.
ElonMusk <- search_tweets("ElonMusk", n = 1000, include_rts = F) 
 
ElonMusk %>% 
  select(text, retweet_count) %>%    
  top_n(25) %>%                       # get the top 25 most popular tweets
  arrange(-retweet_count) %>%         # sort in descending order of popularity
  datatable()
Selecting by retweet_count

The most popular tweet about Elon Musk has 29 retweets and is written in French. For the sake of this assignment, I used Google Translate to translate the tweet to English. This is what the tweet says, “@JustinTrudeau accused Tories of sympathy for Freedom Convoy protesters whom he likened to Nazis. But following the adoption of an emergency law, it was the leftist head of state who was compared to Hitler by @elonmusk.” The next most popular tweet has 4 retweets and is about a cat. The third most popular tweet has 2 retweets, and after that, the rest of the top 10 tweets only have 1 retweet.

  1. The following table shows which hashtags Elon Musk uses the most.
elon_tweets <- get_timeline("elonmusk", n = 5000)
elon_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
Warning: `cols` is now required when using unnest().
Please use `cols = c(hashtags)`

According to the table, it is safe to say that Elon Musk almost never uses hashtags. There has only been use of one hashtag one time which was the hashtag teachhumanity.

  1. The following table shows the number of tweets each day that Elon Musk tweets.
elon_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
elon_tweets %>% 
  group_by(day = date(created_at)) %>%    # extract the date, group by it
  summarize(tweets_per_day = n()) %>%
  summarize(mean(tweets_per_day))         # count the number of tweets each day

The previous two graphs show us two related things. The first graph shows how many times Elon Musk tweets per day. It provides data from January 4, 2022 until the present day. The second graph shows the average number of times Elon Musk tweets per day. According to the graph, he tweets about 9 times per day.

  1. The following is an interactive graphic of Elon Musk’s tweets per day.
elon_tweets %>%
  mutate(day = date(created_at)) %>%
  plot_ly(x = ~day) %>%
  add_histogram() %>%
  layout(title = "tweets per day from @elonmusk")

The graph shows tweets from January 2nd until the present day. From the information on the graph, it seems that Elon Musk tweeted the most January 26th-January 28th with 43 tweets. Coming in close second was February 19th-February 21st with 42 tweets. There doesn’t seem to be an apparent pattern of how often Elon Musk tweets per day.

  1. The following graphs show the hour of the day that Elon Musk tweets.
elon_tweets %>% 
  mutate(time = with_tz(created_at, "America/Boca Chica")) %>% 
  mutate(time = hour(time)) %>% 
  count(time) %>% 
  datatable(options = (list(pageLength = 24)), rownames = F)
Warning: Problem with `mutate()` column `time`.
ℹ `time = with_tz(created_at, "America/Boca Chica")`.
ℹ Unrecognized time zone 'America/Boca Chica'
Warning: Problem with `mutate()` column `time`.
ℹ `time = hour(time)`.
ℹ unknown timezone 'America/Boca Chica'
elon_tweets %>% 
  mutate(time = with_tz(created_at, "America/Boca Chica")) %>%    
  mutate(time = hour(time)) %>%                                
  plot_ly(x = ~time) %>%                                        
  add_histogram() %>%
  layout(title = "When Does @elonmusk Tweet?", 
         xaxis = list(title = "Time of Day (0 = midnight)"),
         yaxis = list(title = "Number of Tweets"))
Warning: Problem with `mutate()` column `time`.
ℹ `time = with_tz(created_at, "America/Boca Chica")`.
ℹ Unrecognized time zone 'America/Boca Chica'
Warning: Problem with `mutate()` column `time`.
ℹ `time = hour(time)`.
ℹ unknown timezone 'America/Boca Chica'

The previous graphs illustrate at what hours Elon Musk tweets and how many times. According to the graphs, Elon Musk tweets the most around 8 pm-9 pm with 60 tweets. The second most popular time he tweets is 10 pm-11 pm with 59 tweets. From the graphs, it is safe to say that Elon tweets the most at night. The hour with the least amount of tweets is 12-1 pm.

  1. The following table and graph show the days of the week that Elon Musk tweets along with how many times.
elon_tweets %>% 
  mutate(Day = wday(created_at,label = T)) %>%       
  count(Day) %>%
  datatable(rownames = F)
elon_tweets %>%
  mutate(Day = wday(created_at, label = T)) %>%
  plot_ly(x = ~Day) %>%
  add_histogram() %>%
  layout(title = "When Does @elonmusk Tweet?", xaxis= list(title = "Days of the Week"), yaxis = list(title = "Number of Tweets"))
NA

There does not seem to be a particular pattern with the days of the week that Elon Musk tweets. According to the graph, he tweets the most on Thursday with 68 tweets and closely following is Sunday with 67 tweets. The day Elon Musk tweets the least seems to be Saturday with 41 tweets.

  1. The following graph is a heatmap that shows every day of the week along with every hour in the day. It includes how many times Elon Musk tweets during each of these times.
elon_tweets %>% 
  mutate(day = wday(created_at, label = T)) %>% 
  mutate(hour = hour(with_tz(created_at, "America/Boca Chica"))) %>% 
  plot_ly(x = ~day, y = ~hour) %>% 
  add_histogram2d(nbinsx = 7, nbinsy = 24) %>%
  layout(title = "When Does @elonmusk Tweet?", 
         xaxis = list(title = "Day of the week"),
         yaxis = list(title = "Hour of the day (0 = midnight)"))
Warning: Problem while computing `hour = hour(with_tz(created_at, "America/Boca Chica"))`.
ℹ Unrecognized time zone 'America/Boca Chica'
Warning: Problem while computing `hour = hour(with_tz(created_at, "America/Boca Chica"))`.
ℹ unknown timezone 'America/Boca Chica'

The heatmap shows two factors, day of the week and hour of the day, that Elon Musk tweets. According to the heatmap, the most popular day and hour he tweets is Monday night around 11 pm. Like previous tables and graphs in this assignment have shown, Elon Musk’s tweeting is sporadic and doesn’t follow much of a pattern. This can be seen in the heatmap as well. However, if there is one conclusion that can be drawn, it is that Elon Musk tweets more often at night. Also, the pattern of not tweeting as much on Saturday can also be seen on the heatmap.

LS0tCnRpdGxlOiAicnR3ZWV0IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoRFQpCmxpYnJhcnkocGxvdGx5KSAgICAgICAgICAgICAgCmxpYnJhcnkocnR3ZWV0KSAgICAgICAgICAgICAgIApsaWJyYXJ5KGx1YnJpZGF0ZSkgIApgYGAKCjEuIFRoZSBmb2xsb3dpbmcgdGFibGUgc2hvd3MgdGhlIHRvcCB0d2VldHMgdGhhdCB3ZXJlIG1hZGUgYWJvdXQgRWxvbiBNdXNrLiBUaGUgdHdlZXRzIGFyZSByYW5rZWQgaW4gcG9wdWxhcml0eSBhY2NvcmRpbmcgdG8gaG93IG1hbnkgcmV0d2VldHMgdGhlIHR3ZWV0IGhhcy4gCmBgYHtyfQpFbG9uTXVzayA8LSBzZWFyY2hfdHdlZXRzKCJFbG9uTXVzayIsIG4gPSAxMDAwLCBpbmNsdWRlX3J0cyA9IEYpIAogCmBgYApgYGB7cn0KRWxvbk11c2sgJT4lIAogIHNlbGVjdCh0ZXh0LCByZXR3ZWV0X2NvdW50KSAlPiUgICAgCiAgdG9wX24oMjUpICU+JSAgICAgICAgICAgICAgICAgICAgICAgIyBnZXQgdGhlIHRvcCAyNSBtb3N0IHBvcHVsYXIgdHdlZXRzCiAgYXJyYW5nZSgtcmV0d2VldF9jb3VudCkgJT4lICAgICAgICAgIyBzb3J0IGluIGRlc2NlbmRpbmcgb3JkZXIgb2YgcG9wdWxhcml0eQogIGRhdGF0YWJsZSgpCmBgYApUaGUgbW9zdCBwb3B1bGFyIHR3ZWV0IGFib3V0IEVsb24gTXVzayBoYXMgMjkgcmV0d2VldHMgYW5kIGlzIHdyaXR0ZW4gaW4gRnJlbmNoLiBGb3IgdGhlIHNha2Ugb2YgdGhpcyBhc3NpZ25tZW50LCBJIHVzZWQgR29vZ2xlIFRyYW5zbGF0ZSB0byB0cmFuc2xhdGUgdGhlIHR3ZWV0IHRvIEVuZ2xpc2guIFRoaXMgaXMgd2hhdCB0aGUgdHdlZXQgc2F5cywgIkBKdXN0aW5UcnVkZWF1IGFjY3VzZWQgVG9yaWVzIG9mIHN5bXBhdGh5IGZvciBGcmVlZG9tIENvbnZveSBwcm90ZXN0ZXJzIHdob20gaGUgbGlrZW5lZCB0byBOYXppcy4gQnV0IGZvbGxvd2luZyB0aGUgYWRvcHRpb24gb2YgYW4gZW1lcmdlbmN5IGxhdywgaXQgd2FzIHRoZSBsZWZ0aXN0IGhlYWQgb2Ygc3RhdGUgd2hvIHdhcyBjb21wYXJlZCB0byBIaXRsZXIgYnkgQGVsb25tdXNrLiIgVGhlIG5leHQgbW9zdCBwb3B1bGFyIHR3ZWV0IGhhcyA0IHJldHdlZXRzIGFuZCBpcyBhYm91dCBhIGNhdC4gVGhlIHRoaXJkIG1vc3QgcG9wdWxhciB0d2VldCBoYXMgMiByZXR3ZWV0cywgYW5kIGFmdGVyIHRoYXQsIHRoZSByZXN0IG9mIHRoZSB0b3AgMTAgdHdlZXRzIG9ubHkgaGF2ZSAxIHJldHdlZXQuIAoKMi4gVGhlIGZvbGxvd2luZyB0YWJsZSBzaG93cyB3aGljaCBoYXNodGFncyBFbG9uIE11c2sgdXNlcyB0aGUgbW9zdC4gCmBgYHtyfQplbG9uX3R3ZWV0cyA8LSBnZXRfdGltZWxpbmUoImVsb25tdXNrIiwgbiA9IDUwMDApCmBgYApgYGB7cn0KZWxvbl90d2VldHMgJT4lIAogIHNlbGVjdChoYXNodGFncykgJT4lICAgICAgICAgICAgICAgICAgICMgRm9jdXMgb24gdGhlIGhhc2h0YWdzCiAgdW5uZXN0KCkgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBTZXBhcmF0ZSBtdWx0aXBsZSBoYXNodGFncwogIG11dGF0ZShoYXNodGFncyA9IHRvbG93ZXIoaGFzaHRhZ3MpKSAlPiUgICAgICAjIG1ha2UgYWxsIGhhc2h0YWdzIGxvd2VyY2FzZQogIGNvdW50KGhhc2h0YWdzLCBzb3J0PVRSVUUpICU+JSAgICAgICAgICAgICAgICAjIGNvdW50IGhvdyBvZnRlbiB0aGV5IGFwcGVhcgogIGRhdGF0YWJsZSgpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGNyZWF0ZSBhbiBpbnRlcmFjdGl2ZSB0YWJsZQoKCmBgYApBY2NvcmRpbmcgdG8gdGhlIHRhYmxlLCBpdCBpcyBzYWZlIHRvIHNheSB0aGF0IEVsb24gTXVzayBhbG1vc3QgbmV2ZXIgdXNlcyBoYXNodGFncy4gVGhlcmUgaGFzIG9ubHkgYmVlbiB1c2Ugb2Ygb25lIGhhc2h0YWcgb25lIHRpbWUgd2hpY2ggd2FzIHRoZSBoYXNodGFnIHRlYWNoaHVtYW5pdHkuIAoKMy4gVGhlIGZvbGxvd2luZyB0YWJsZSBzaG93cyB0aGUgbnVtYmVyIG9mIHR3ZWV0cyBlYWNoIGRheSB0aGF0IEVsb24gTXVzayB0d2VldHMuIApgYGB7cn0KZWxvbl90d2VldHMgJT4lIAogIGdyb3VwX2J5KGRheSA9IGRhdGUoY3JlYXRlZF9hdCkpICU+JSAgICAjIGV4dHJhY3QgdGhlIGRhdGUsIGdyb3VwIGJ5IGl0CiAgc3VtbWFyaXplKHR3ZWV0c19wZXJfZGF5ID0gbigpKSAgICAgICAgICMgY291bnQgdGhlIG51bWJlciBvZiB0d2VldHMgZWFjaCBkYXkKYGBgCmBgYHtyfQplbG9uX3R3ZWV0cyAlPiUgCiAgZ3JvdXBfYnkoZGF5ID0gZGF0ZShjcmVhdGVkX2F0KSkgJT4lICAgICMgZXh0cmFjdCB0aGUgZGF0ZSwgZ3JvdXAgYnkgaXQKICBzdW1tYXJpemUodHdlZXRzX3Blcl9kYXkgPSBuKCkpICU+JQogIHN1bW1hcml6ZShtZWFuKHR3ZWV0c19wZXJfZGF5KSkgICAgICAgICAjIGNvdW50IHRoZSBudW1iZXIgb2YgdHdlZXRzIGVhY2ggZGF5CmBgYApUaGUgcHJldmlvdXMgdHdvIGdyYXBocyBzaG93IHVzIHR3byByZWxhdGVkIHRoaW5ncy4gVGhlIGZpcnN0IGdyYXBoIHNob3dzIGhvdyBtYW55IHRpbWVzIEVsb24gTXVzayB0d2VldHMgcGVyIGRheS4gSXQgcHJvdmlkZXMgZGF0YSBmcm9tIEphbnVhcnkgNCwgMjAyMiB1bnRpbCB0aGUgcHJlc2VudCBkYXkuIFRoZSBzZWNvbmQgZ3JhcGggc2hvd3MgdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIHRpbWVzIEVsb24gTXVzayB0d2VldHMgcGVyIGRheS4gQWNjb3JkaW5nIHRvIHRoZSBncmFwaCwgaGUgdHdlZXRzIGFib3V0IDkgdGltZXMgcGVyIGRheS4gCgo0LiBUaGUgZm9sbG93aW5nIGlzIGFuIGludGVyYWN0aXZlIGdyYXBoaWMgb2YgRWxvbiBNdXNrJ3MgdHdlZXRzIHBlciBkYXkuCmBgYHtyfQplbG9uX3R3ZWV0cyAlPiUKICBtdXRhdGUoZGF5ID0gZGF0ZShjcmVhdGVkX2F0KSkgJT4lCiAgcGxvdF9seSh4ID0gfmRheSkgJT4lCiAgYWRkX2hpc3RvZ3JhbSgpICU+JQogIGxheW91dCh0aXRsZSA9ICJ0d2VldHMgcGVyIGRheSBmcm9tIEBlbG9ubXVzayIpCmBgYApUaGUgZ3JhcGggc2hvd3MgdHdlZXRzIGZyb20gSmFudWFyeSAybmQgdW50aWwgdGhlIHByZXNlbnQgZGF5LiBGcm9tIHRoZSBpbmZvcm1hdGlvbiBvbiB0aGUgZ3JhcGgsIGl0IHNlZW1zIHRoYXQgRWxvbiBNdXNrIHR3ZWV0ZWQgdGhlIG1vc3QgSmFudWFyeSAyNnRoLUphbnVhcnkgMjh0aCB3aXRoIDQzIHR3ZWV0cy4gQ29taW5nIGluIGNsb3NlIHNlY29uZCB3YXMgRmVicnVhcnkgMTl0aC1GZWJydWFyeSAyMXN0IHdpdGggNDIgdHdlZXRzLiBUaGVyZSBkb2Vzbid0IHNlZW0gdG8gYmUgYW4gYXBwYXJlbnQgcGF0dGVybiBvZiBob3cgb2Z0ZW4gRWxvbiBNdXNrIHR3ZWV0cyBwZXIgZGF5LiAgCgo1LiBUaGUgZm9sbG93aW5nIGdyYXBocyBzaG93IHRoZSBob3VyIG9mIHRoZSBkYXkgdGhhdCBFbG9uIE11c2sgdHdlZXRzLiAKYGBge3J9CmVsb25fdHdlZXRzICU+JSAKICBtdXRhdGUodGltZSA9IHdpdGhfdHooY3JlYXRlZF9hdCwgIkFtZXJpY2EvQm9jYSBDaGljYSIpKSAlPiUgCiAgbXV0YXRlKHRpbWUgPSBob3VyKHRpbWUpKSAlPiUgCiAgY291bnQodGltZSkgJT4lIAogIGRhdGF0YWJsZShvcHRpb25zID0gKGxpc3QocGFnZUxlbmd0aCA9IDI0KSksIHJvd25hbWVzID0gRikKCmBgYApgYGB7cn0KZWxvbl90d2VldHMgJT4lIAogIG11dGF0ZSh0aW1lID0gd2l0aF90eihjcmVhdGVkX2F0LCAiQW1lcmljYS9Cb2NhIENoaWNhIikpICU+JSAgICAKICBtdXRhdGUodGltZSA9IGhvdXIodGltZSkpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgcGxvdF9seSh4ID0gfnRpbWUpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICBhZGRfaGlzdG9ncmFtKCkgJT4lCiAgbGF5b3V0KHRpdGxlID0gIldoZW4gRG9lcyBAZWxvbm11c2sgVHdlZXQ/IiwgCiAgICAgICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICJUaW1lIG9mIERheSAoMCA9IG1pZG5pZ2h0KSIpLAogICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiTnVtYmVyIG9mIFR3ZWV0cyIpKQoKCmBgYApUaGUgcHJldmlvdXMgZ3JhcGhzIGlsbHVzdHJhdGUgYXQgd2hhdCBob3VycyBFbG9uIE11c2sgdHdlZXRzIGFuZCBob3cgbWFueSB0aW1lcy4gQWNjb3JkaW5nIHRvIHRoZSBncmFwaHMsIEVsb24gTXVzayB0d2VldHMgdGhlIG1vc3QgYXJvdW5kIDggcG0tOSBwbSB3aXRoIDYwIHR3ZWV0cy4gVGhlIHNlY29uZCBtb3N0IHBvcHVsYXIgdGltZSBoZSB0d2VldHMgaXMgMTAgcG0tMTEgcG0gd2l0aCA1OSB0d2VldHMuIEZyb20gdGhlIGdyYXBocywgaXQgaXMgc2FmZSB0byBzYXkgdGhhdCBFbG9uIHR3ZWV0cyB0aGUgbW9zdCBhdCBuaWdodC4gVGhlIGhvdXIgd2l0aCB0aGUgbGVhc3QgYW1vdW50IG9mIHR3ZWV0cyBpcyAxMi0xIHBtLiAKCjYuIFRoZSBmb2xsb3dpbmcgdGFibGUgYW5kIGdyYXBoIHNob3cgdGhlIGRheXMgb2YgdGhlIHdlZWsgdGhhdCBFbG9uIE11c2sgdHdlZXRzIGFsb25nIHdpdGggaG93IG1hbnkgdGltZXMuIApgYGB7cn0KZWxvbl90d2VldHMgJT4lIAogIG11dGF0ZShEYXkgPSB3ZGF5KGNyZWF0ZWRfYXQsbGFiZWwgPSBUKSkgJT4lICAgICAgIAogIGNvdW50KERheSkgJT4lCiAgZGF0YXRhYmxlKHJvd25hbWVzID0gRikKYGBgCmBgYHtyfQplbG9uX3R3ZWV0cyAlPiUKICBtdXRhdGUoRGF5ID0gd2RheShjcmVhdGVkX2F0LCBsYWJlbCA9IFQpKSAlPiUKICBwbG90X2x5KHggPSB+RGF5KSAlPiUKICBhZGRfaGlzdG9ncmFtKCkgJT4lCiAgbGF5b3V0KHRpdGxlID0gIldoZW4gRG9lcyBAZWxvbm11c2sgVHdlZXQ/IiwgeGF4aXM9IGxpc3QodGl0bGUgPSAiRGF5cyBvZiB0aGUgV2VlayIpLCB5YXhpcyA9IGxpc3QodGl0bGUgPSAiTnVtYmVyIG9mIFR3ZWV0cyIpKQogICAgICAgICAKYGBgClRoZXJlIGRvZXMgbm90IHNlZW0gdG8gYmUgYSBwYXJ0aWN1bGFyIHBhdHRlcm4gd2l0aCB0aGUgZGF5cyBvZiB0aGUgd2VlayB0aGF0IEVsb24gTXVzayB0d2VldHMuIEFjY29yZGluZyB0byB0aGUgZ3JhcGgsIGhlIHR3ZWV0cyB0aGUgbW9zdCBvbiBUaHVyc2RheSB3aXRoIDY4IHR3ZWV0cyBhbmQgY2xvc2VseSBmb2xsb3dpbmcgaXMgU3VuZGF5IHdpdGggNjcgdHdlZXRzLiBUaGUgZGF5IEVsb24gTXVzayB0d2VldHMgdGhlIGxlYXN0IHNlZW1zIHRvIGJlIFNhdHVyZGF5IHdpdGggNDEgdHdlZXRzLiAKCgo3LiBUaGUgZm9sbG93aW5nIGdyYXBoIGlzIGEgaGVhdG1hcCB0aGF0IHNob3dzIGV2ZXJ5IGRheSBvZiB0aGUgd2VlayBhbG9uZyB3aXRoIGV2ZXJ5IGhvdXIgaW4gdGhlIGRheS4gSXQgaW5jbHVkZXMgaG93IG1hbnkgdGltZXMgRWxvbiBNdXNrIHR3ZWV0cyBkdXJpbmcgZWFjaCBvZiB0aGVzZSB0aW1lcy4gCmBgYHtyfQplbG9uX3R3ZWV0cyAlPiUgCiAgbXV0YXRlKGRheSA9IHdkYXkoY3JlYXRlZF9hdCwgbGFiZWwgPSBUKSkgJT4lIAogIG11dGF0ZShob3VyID0gaG91cih3aXRoX3R6KGNyZWF0ZWRfYXQsICJBbWVyaWNhL0JvY2EgQ2hpY2EiKSkpICU+JSAKICBwbG90X2x5KHggPSB+ZGF5LCB5ID0gfmhvdXIpICU+JSAKICBhZGRfaGlzdG9ncmFtMmQobmJpbnN4ID0gNywgbmJpbnN5ID0gMjQpICU+JQogIGxheW91dCh0aXRsZSA9ICJXaGVuIERvZXMgQGVsb25tdXNrIFR3ZWV0PyIsIAogICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiRGF5IG9mIHRoZSB3ZWVrIiksCiAgICAgICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICJIb3VyIG9mIHRoZSBkYXkgKDAgPSBtaWRuaWdodCkiKSkKCgpgYGAKVGhlIGhlYXRtYXAgc2hvd3MgdHdvIGZhY3RvcnMsIGRheSBvZiB0aGUgd2VlayBhbmQgaG91ciBvZiB0aGUgZGF5LCB0aGF0IEVsb24gTXVzayB0d2VldHMuIEFjY29yZGluZyB0byB0aGUgaGVhdG1hcCwgdGhlIG1vc3QgcG9wdWxhciBkYXkgYW5kIGhvdXIgaGUgdHdlZXRzIGlzIE1vbmRheSBuaWdodCBhcm91bmQgMTEgcG0uIExpa2UgcHJldmlvdXMgdGFibGVzIGFuZCBncmFwaHMgaW4gdGhpcyBhc3NpZ25tZW50IGhhdmUgc2hvd24sIEVsb24gTXVzaydzIHR3ZWV0aW5nIGlzIHNwb3JhZGljIGFuZCBkb2Vzbid0IGZvbGxvdyBtdWNoIG9mIGEgcGF0dGVybi4gVGhpcyBjYW4gYmUgc2VlbiBpbiB0aGUgaGVhdG1hcCBhcyB3ZWxsLiBIb3dldmVyLCBpZiB0aGVyZSBpcyBvbmUgY29uY2x1c2lvbiB0aGF0IGNhbiBiZSBkcmF3biwgaXQgaXMgdGhhdCBFbG9uIE11c2sgdHdlZXRzIG1vcmUgb2Z0ZW4gYXQgbmlnaHQuIEFsc28sIHRoZSBwYXR0ZXJuIG9mIG5vdCB0d2VldGluZyBhcyBtdWNoIG9uIFNhdHVyZGF5IGNhbiBhbHNvIGJlIHNlZW4gb24gdGhlIGhlYXRtYXAuIAoK