library(ggplot2)
library(readxl)
library(vembedr)
library(visdat)
library(tidyverse)
library(skimr)
library(palmerpenguins)
library(dplyr)
library(ggthemes)
library(ggridges)
library(janitor)
library(wesanderson)
library(here)

Research Question (10 points)


Define your research question below. What about the data interests you? What is a specific question you want to find out about the data?


I will be working on the friends datasets from the provided webside. I am a fan of this series and excited to work on a dataset about the characters’ emotions. The specific research question that I want to answer is “Which of the main six characters in friends series showed the most drastic change in few emotional responses from season one through four?” Since it is a comedy series (or I consider it so), I wanted to see the number of joyful and sad scenes especially and who play them the most over the seasons. Unfortunately, emotion data is only available till season 4 in my downloaded files, so I will be using only season 1, 2 3, and 4.


Given your question, what is your expectation about the data?


I think Chandler would play the most joyful scenes, Ross the sad ones, Rachel would play more mad scenes and Monica would play the powerful scenes.


Data Loading (10 points)


Load the data below and use dplyr::glimpse() or skimr::skim() on the data. You should upload the data file into the data directory.


# Using read_excel here because this is what I am learning in this class, it is new to me. I always converted xlsx into csv and and loaded csv data. 

friends = read_excel(here('data/friends_excel.xlsx'), 
                      sheet=1, 
                      na="NA")
friendsEMO = read_excel(here('data/friends_emotions_excel.xlsx'), 
                      sheet=1, 
                      na="NA")

# Direct links from the provided website
#friends = readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-09-08/friends.csv')
#friends_emotions = readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-09-08/friends_emotions.csv')

#friendsCSV = read.csv("friends.csv")
#friendsEmoCSV = read.csv("friends_emotions.csv")

# text and speaker are character variables and season, episode, scene and utterance are numeric variable.
dplyr::glimpse(friends)
## Rows: 67,373
## Columns: 6
## $ text      <chr> "There's nothing to tell! He's just some guy I work with!",…
## $ speaker   <chr> "Monica Geller", "Joey Tribbiani", "Chandler Bing", "Phoebe…
## $ season    <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
## $ episode   <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
## $ scene     <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
## $ utterance <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, …

skimr::skim(friendsEMO)
Data summary
Name friendsEMO
Number of rows 12606
Number of columns 5
_______________________
Column type frequency:
character 1
numeric 4
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
emotion 0 1 3 8 0 7 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
season 0 1 2.57 1.11 1 2 3 4 4 ▆▆▁▇▇
episode 0 1 13.19 7.20 1 7 14 20 25 ▇▆▇▇▇
scene 0 1 7.52 4.43 1 4 7 11 29 ▇▇▂▁▁
utterance 0 1 9.80 5.94 1 5 9 14 30 ▇▇▅▂▁

slice(friendsEMO)
## # A tibble: 12,606 x 5
##    season episode scene utterance emotion
##     <dbl>   <dbl> <dbl>     <dbl> <chr>  
##  1      1       1     4         1 Mad    
##  2      1       1     4         3 Neutral
##  3      1       1     4         4 Joyful 
##  4      1       1     4         5 Neutral
##  5      1       1     4         6 Neutral
##  6      1       1     4         7 Neutral
##  7      1       1     4         8 Scared 
##  8      1       1     4        10 Joyful 
##  9      1       1     4        11 Joyful 
## 10      1       1     4        12 Sad    
## # … with 12,596 more rows

If there are any quirks that you have to deal with NA coded as something else, or it is multiple tables, please make some notes here about what you need to do before you start transforming the data in the next section.


I converted the CSV files to excel, and assigned missing values as “NA”. I want the emotions with character names in a single data frame; hence I will be merging the two datasets using left_join.


Make sure your data types are correct!


Data Transforming (15 points)


If the data needs to be transformed in any way (values recoded, pivoted, etc), do it here. Examples include transforming a continuous variable into a categorical using case_when(), etc.


# I dont need to transform values but need to merge the two main dataset because one has the emotional responses and the other has the character names.
friendsMERGE = friendsEMO %>%
  left_join(y = friends, 
             by = c("season" = "season", "episode" = "episode", 
                    "scene" = "scene", "utterance" = "utterance"))
#nrow(friendsMERGE)
#friendsMERGEinner = friendsEMO %>%
#  inner_join(y = friends, 
#             by = c("season" = "season", "episode" = "episode", 
#                    "scene" = "scene", "utterance" = "utterance"))
#nrow(friendsMERGEinner)

friendsMERGE = friendsMERGE %>% 
  select(season, emotion, speaker) 

#!is.na(friendsMERGE) too many rows to check
vis_dat(friendsMERGE)


Bonus points (5 points) for datasets that require merging of tables, but only if you reason through whether you should use left_join, inner_join, or right_join on these tables. No credit will be provided if you don’t.


Left_join adds columns to the right even if they do not have values in few rows for the conditions I am joining them. Inner_join returns rows when both merging tables have maching values.I am using left_join here because to me it is more intuitive (I have a table I like I want to add columns in that table). However, I did test inner_join and it does not give a different row numbers, and also I want the emotional responses for the rows with character names and no emotional response value would have been no use for this project.


Show your transformed table here. Use tools such as glimpse(), skim() or head() to illustrate your point.


slice(friendsMERGE)
## # A tibble: 12,606 x 3
##    season emotion speaker       
##     <dbl> <chr>   <chr>         
##  1      1 Mad     Ross Geller   
##  2      1 Neutral Joey Tribbiani
##  3      1 Joyful  Chandler Bing 
##  4      1 Neutral Joey Tribbiani
##  5      1 Neutral Chandler Bing 
##  6      1 Neutral Joey Tribbiani
##  7      1 Scared  Chandler Bing 
##  8      1 Joyful  Joey Tribbiani
##  9      1 Joyful  Chandler Bing 
## 10      1 Sad     Ross Geller   
## # … with 12,596 more rows

Are the values what you expected for the variables? Why or Why not?


I believe I got the right values for the variables. I will only be looking at season one through four, emotional responses and the main six characters. I have more than the four seasons I need, more emotional responses than I need and more characters than I need which I will be filtering through in the next step.


Visualizing and Summarizing (15 points)


Use group_by()/summarize() to make a summary of the data here. The summary should be relevant to your research question


# Here I am filtering the the emotions I need and for the main six characters. We have emotions data only for four seasons. 
friendsFinal = friendsMERGE %>%
    filter(emotion %in% c("Joyful", "Sad", "Powerful", "Mad")) %>%
    filter(speaker %in% c("Chandler Bing", "Joey Tribbiani",
           "Ross Geller", "Phoebe Buffay", "Monica Geller",
           "Rachel Green")) %>%
    filter(season %in% c(1, 2, 3, 4)) %>%
    group_by(speaker, emotion, season) %>%
    summarize(EmoCount = n()) 
## `summarise()` has grouped output by 'speaker', 'emotion'. You can override using the `.groups` argument.
glimpse(friendsFinal)
## Rows: 96
## Columns: 4
## Groups: speaker, emotion [24]
## $ speaker  <chr> "Chandler Bing", "Chandler Bing", "Chandler Bing", "Chandler…
## $ emotion  <chr> "Joyful", "Joyful", "Joyful", "Joyful", "Mad", "Mad", "Mad",…
## $ season   <dbl> 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, …
## $ EmoCount <int> 96, 92, 103, 96, 57, 57, 63, 41, 20, 17, 39, 65, 17, 18, 18,…
slice(friendsFinal)
## # A tibble: 96 x 4
## # Groups:   speaker, emotion [24]
##    speaker       emotion  season EmoCount
##    <chr>         <chr>     <dbl>    <int>
##  1 Chandler Bing Joyful        1       96
##  2 Chandler Bing Joyful        2       92
##  3 Chandler Bing Joyful        3      103
##  4 Chandler Bing Joyful        4       96
##  5 Chandler Bing Mad           1       57
##  6 Chandler Bing Mad           2       57
##  7 Chandler Bing Mad           3       63
##  8 Chandler Bing Mad           4       41
##  9 Chandler Bing Powerful      1       20
## 10 Chandler Bing Powerful      2       17
## # … with 86 more rows

What are your findings about the summary? Are they what you expected?


The summary successfully filtered out first four seasons and few emotions that I will be looking at. This table is exactly what I needed for further analysis.


Make at least two plots that help you answer your question on the transformed or summarized data.


# Bar plot by each four interested emotions 
ggplot(data = friendsFinal,
       aes(x = speaker,
           y = EmoCount, 
           fill = factor(season))) +
    geom_bar(stat = "identity", position = "dodge") +
    facet_wrap(vars(emotion)) +  
    scale_fill_discrete(name = "Seasons") +
    labs(x = "character Names",  
       y = "Emotional Response Count",  
       title = "Barplot of Emotions by Seasons") +  
    theme_bw() +  
    theme(axis.text.x = element_text(angle = -30, hjust = 0), 
          legend.position = "bottom") +  
    scale_fill_viridis_d(name = "Seasons") +
    scale_color_manual(values = wes_palette("BottleRocket2"))
## Scale for 'fill' is already present. Adding another scale for 'fill', which
## will replace the existing scale.


# Bar plot for all emotional response by season
ggplot(data = friendsFinal,
       aes(x = season,
           y = EmoCount, 
           fill = factor(speaker))) +
    geom_bar(stat = "identity", position = "dodge") +
    scale_fill_discrete(name = "Seasons") +
    labs(x = "Seasons",  
       y = "Emotional Response Count",  
       title = "Barplot of Emotions by Seasons") +  
    theme_bw() +  
    theme(axis.text.x = element_text(angle = -30, hjust = 0), 
          legend.position = "bottom") +  
    scale_fill_viridis_d(name = "character Names") +
    scale_color_manual(values = wes_palette("BottleRocket1"))
## Scale for 'fill' is already present. Adding another scale for 'fill', which
## will replace the existing scale.


Final Summary (10 points)


Summarize your research question and findings below.


I was looking at emotional response change over the first four seasons of the friends series. The barplot shows each four emotions that were focused in this project in four separate graphs and named accordingly, seasons are represented by colors and noted below the graph, and character names are shows below the graphs which also applies for the above two bar plots. From the plot above we see that joyful scenes are most prevelent among all six characters all thoughout the four seasons. The characters Chandler, Monica and Rachel seem to be more prevelent to show mad emotions than others. Powerful emotional scenes increased for all characters over the first few few seasons and are most prevelant in the fourth season. The character Phoebe seems to have more sad scenes in season three; however, Rachel started the series performing in more sad scenes than others.


Are your findings what you expected? Why or Why not?


I expected drestic change in all characters’ emotional response over the years; however, only powerful emotional scenes increased significantly in season four. Also, mad emotional responses did increase steadily for three characters. Total emotional response wise season three and four showed more responses than the first two for all six characters. All seasons’ data on emotional responses might have shown more prominent trend than what we are seeing here.


Functions


# I followed the class notes and this website to write the functions https://www.statmethods.net/management/userfunctions.html

gubla = function(df, emo, seas){
  outDF  = df %>%
    filter(emotion %in% c(emo)) %>%
    filter(season == seas) %>%
    filter(speaker %in% c("Chandler Bing", "Joey Tribbiani",
           "Ross Geller", "Phoebe Buffay", "Monica Geller",
           "Rachel Green")) # I only want the main six characters' emotional responses
  return(outDF)
}

pipra = function(df, emo){
  outDF  = df %>%
    group_by(speaker) %>%
    summarize(emo = n())
  return(outDF)
}

# This is how I planned to use them
#JoyS1 = gubla(df = friendsMERGE, emo = "Joyful", seas = 1)
#SadS1 = gubla(df = friendsMERGE, emo = "Sad", seas = 1)
#JoyS1summary = pipra(df = JoyS1)
#SadS1summary = pipra(df = SadS1)
#MERGEemoS1 = JoyS1summary%>%
#  left_join(y = SadS1summary, 
#             by = c("speaker" = "speaker"))
#slice(MERGEemoS1)

LS0tCnRpdGxlOiAiTWlkdGVybSIKYXV0aG9yOiAiRmFyemFuYSBOYW9zaGluIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdGhlbWU6IGNlcnVsZWFuCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogbm8KICAgICAgc21vb3RoX3Njcm9sbDogeWVzCiAgICAgIGhpZ2hsaWdodDogdGFuZ28KLS0tCgoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkKYGBgCgoKKioqICAKCmBgYHtyIGxvYWRsaWIsIGVjaG89VCwgcmVzdWx0cz0naGlkZScsIG1lc3NhZ2U9Riwgd2FybmluZz1GfQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KHZlbWJlZHIpCmxpYnJhcnkodmlzZGF0KQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShza2ltcikKbGlicmFyeShwYWxtZXJwZW5ndWlucykKbGlicmFyeShkcGx5cikKbGlicmFyeShnZ3RoZW1lcykKbGlicmFyeShnZ3JpZGdlcykKbGlicmFyeShqYW5pdG9yKQpsaWJyYXJ5KHdlc2FuZGVyc29uKQpsaWJyYXJ5KGhlcmUpCmBgYAoKCioqKiAgCgojIyAqKlJlc2VhcmNoIFF1ZXN0aW9uKiogKDEwIHBvaW50cykKCioqKgoKIyMjIyAqKkRlZmluZSB5b3VyIHJlc2VhcmNoIHF1ZXN0aW9uIGJlbG93LiBXaGF0IGFib3V0IHRoZSBkYXRhIGludGVyZXN0cyB5b3U/IFdoYXQgaXMgYSBzcGVjaWZpYyBxdWVzdGlvbiB5b3Ugd2FudCB0byBmaW5kIG91dCBhYm91dCB0aGUgZGF0YT8qKgoKKioqICAKCjxzdHlsZT4KZGl2LmJsdWUgeyBiYWNrZ3JvdW5kLWNvbG9yOiNlNmYwZmY7IGJvcmRlci1yYWRpdXM6IDRweDsgcGFkZGluZzogMTBweDt9Cjwvc3R5bGU+CjxkaXYgY2xhc3MgPSAiYmx1ZSI+CiMjIyMgSSB3aWxsIGJlIHdvcmtpbmcgb24gdGhlIGZyaWVuZHMgZGF0YXNldHMgZnJvbSB0aGUgcHJvdmlkZWQgd2Vic2lkZS4gSSBhbSBhIGZhbiBvZiB0aGlzIHNlcmllcyBhbmQgZXhjaXRlZCB0byB3b3JrIG9uIGEgZGF0YXNldCBhYm91dCB0aGUgY2hhcmFjdGVycycgZW1vdGlvbnMuIFRoZSBzcGVjaWZpYyByZXNlYXJjaCBxdWVzdGlvbiB0aGF0IEkgd2FudCB0byBhbnN3ZXIgaXMgIldoaWNoIG9mIHRoZSBtYWluIHNpeCBjaGFyYWN0ZXJzIGluIGZyaWVuZHMgc2VyaWVzIHNob3dlZCB0aGUgbW9zdCBkcmFzdGljIGNoYW5nZSBpbiBmZXcgZW1vdGlvbmFsIHJlc3BvbnNlcyBmcm9tIHNlYXNvbiBvbmUgdGhyb3VnaCBmb3VyPyIgU2luY2UgaXQgaXMgYSBjb21lZHkgc2VyaWVzIChvciBJIGNvbnNpZGVyIGl0IHNvKSwgSSB3YW50ZWQgdG8gc2VlIHRoZSBudW1iZXIgb2Ygam95ZnVsIGFuZCBzYWQgc2NlbmVzIGVzcGVjaWFsbHkgYW5kIHdobyBwbGF5IHRoZW0gdGhlIG1vc3Qgb3ZlciB0aGUgc2Vhc29ucy4gVW5mb3J0dW5hdGVseSwgZW1vdGlvbiBkYXRhIGlzIG9ubHkgYXZhaWxhYmxlIHRpbGwgc2Vhc29uIDQgaW4gbXkgZG93bmxvYWRlZCBmaWxlcywgc28gSSB3aWxsIGJlIHVzaW5nIG9ubHkgc2Vhc29uIDEsIDIgMywgYW5kIDQuIAo8L2Rpdj4gIAoKKioqICAKCiMjIyMgKipHaXZlbiB5b3VyIHF1ZXN0aW9uLCB3aGF0IGlzIHlvdXIgZXhwZWN0YXRpb24gYWJvdXQgdGhlIGRhdGE/KioKCioqKiAgCgo8c3R5bGU+CmRpdi5ibHVlIHsgYmFja2dyb3VuZC1jb2xvcjojZTZmMGZmOyBib3JkZXItcmFkaXVzOiA0cHg7IHBhZGRpbmc6IDEwcHg7fQo8L3N0eWxlPgo8ZGl2IGNsYXNzID0gImJsdWUiPgojIyMjIEkgdGhpbmsgQ2hhbmRsZXIgd291bGQgcGxheSB0aGUgbW9zdCBqb3lmdWwgc2NlbmVzLCBSb3NzIHRoZSBzYWQgb25lcywgUmFjaGVsIHdvdWxkIHBsYXkgbW9yZSBtYWQgc2NlbmVzIGFuZCBNb25pY2Egd291bGQgcGxheSB0aGUgcG93ZXJmdWwgc2NlbmVzLiAKPC9kaXY+IAoKKioqICAKCiMjICoqRGF0YSBMb2FkaW5nKiogKDEwIHBvaW50cykKCioqKiAgCgojIyMjICoqTG9hZCB0aGUgZGF0YSBiZWxvdyBhbmQgdXNlIGBkcGx5cjo6Z2xpbXBzZSgpYCBvciBgc2tpbXI6OnNraW0oKWAgb24gdGhlIGRhdGEuIFlvdSBzaG91bGQgdXBsb2FkIHRoZSBkYXRhIGZpbGUgaW50byB0aGUgYGRhdGFgIGRpcmVjdG9yeS4qKgoKKioqICAKCmBgYHtyfQojIFVzaW5nIHJlYWRfZXhjZWwgaGVyZSBiZWNhdXNlIHRoaXMgaXMgd2hhdCBJIGFtIGxlYXJuaW5nIGluIHRoaXMgY2xhc3MsIGl0IGlzIG5ldyB0byBtZS4gSSBhbHdheXMgY29udmVydGVkIHhsc3ggaW50byBjc3YgYW5kIGFuZCBsb2FkZWQgY3N2IGRhdGEuIAoKZnJpZW5kcyA9IHJlYWRfZXhjZWwoaGVyZSgnZGF0YS9mcmllbmRzX2V4Y2VsLnhsc3gnKSwgCiAgICAgICAgICAgICAgICAgICAgICBzaGVldD0xLCAKICAgICAgICAgICAgICAgICAgICAgIG5hPSJOQSIpCmZyaWVuZHNFTU8gPSByZWFkX2V4Y2VsKGhlcmUoJ2RhdGEvZnJpZW5kc19lbW90aW9uc19leGNlbC54bHN4JyksIAogICAgICAgICAgICAgICAgICAgICAgc2hlZXQ9MSwgCiAgICAgICAgICAgICAgICAgICAgICBuYT0iTkEiKQoKIyBEaXJlY3QgbGlua3MgZnJvbSB0aGUgcHJvdmlkZWQgd2Vic2l0ZQojZnJpZW5kcyA9IHJlYWRyOjpyZWFkX2NzdignaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3Jmb3JkYXRhc2NpZW5jZS90aWR5dHVlc2RheS9tYXN0ZXIvZGF0YS8yMDIwLzIwMjAtMDktMDgvZnJpZW5kcy5jc3YnKQojZnJpZW5kc19lbW90aW9ucyA9IHJlYWRyOjpyZWFkX2NzdignaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3Jmb3JkYXRhc2NpZW5jZS90aWR5dHVlc2RheS9tYXN0ZXIvZGF0YS8yMDIwLzIwMjAtMDktMDgvZnJpZW5kc19lbW90aW9ucy5jc3YnKQoKI2ZyaWVuZHNDU1YgPSByZWFkLmNzdigiZnJpZW5kcy5jc3YiKQojZnJpZW5kc0Vtb0NTViA9IHJlYWQuY3N2KCJmcmllbmRzX2Vtb3Rpb25zLmNzdiIpCmBgYAoKKioqICAKCmBgYHtyfQojIHRleHQgYW5kIHNwZWFrZXIgYXJlIGNoYXJhY3RlciB2YXJpYWJsZXMgYW5kIHNlYXNvbiwgZXBpc29kZSwgc2NlbmUgYW5kIHV0dGVyYW5jZSBhcmUgbnVtZXJpYyB2YXJpYWJsZS4KZHBseXI6OmdsaW1wc2UoZnJpZW5kcykKYGBgCgoqKiogIAoKYGBge3J9CnNraW1yOjpza2ltKGZyaWVuZHNFTU8pCmBgYAoKKioqICAKCmBgYHtyfQpzbGljZShmcmllbmRzRU1PKQpgYGAKCgoqKioKCiMjIyMgKipJZiB0aGVyZSBhcmUgYW55IHF1aXJrcyB0aGF0IHlvdSBoYXZlIHRvIGRlYWwgd2l0aCBgTkFgIGNvZGVkIGFzIHNvbWV0aGluZyBlbHNlLCBvciBpdCBpcyBtdWx0aXBsZSB0YWJsZXMsIHBsZWFzZSBtYWtlIHNvbWUgbm90ZXMgaGVyZSBhYm91dCB3aGF0IHlvdSBuZWVkIHRvIGRvIGJlZm9yZSB5b3Ugc3RhcnQgdHJhbnNmb3JtaW5nIHRoZSBkYXRhIGluIHRoZSBuZXh0IHNlY3Rpb24uKioKCioqKiAgCgo8c3R5bGU+CmRpdi5ibHVlIHsgYmFja2dyb3VuZC1jb2xvcjojZTZmMGZmOyBib3JkZXItcmFkaXVzOiA0cHg7IHBhZGRpbmc6IDEwcHg7fQo8L3N0eWxlPgo8ZGl2IGNsYXNzID0gImJsdWUiPgojIyMjIEkgY29udmVydGVkIHRoZSBDU1YgZmlsZXMgdG8gZXhjZWwsIGFuZCBhc3NpZ25lZCBtaXNzaW5nIHZhbHVlcyBhcyAiTkEiLiBJIHdhbnQgdGhlIGVtb3Rpb25zIHdpdGggY2hhcmFjdGVyIG5hbWVzIGluIGEgc2luZ2xlIGRhdGEgZnJhbWU7IGhlbmNlIEkgd2lsbCBiZSBtZXJnaW5nIHRoZSB0d28gZGF0YXNldHMgdXNpbmcgbGVmdF9qb2luLiAgCjwvZGl2PiAKCioqKiAgCgojIyMjICoqTWFrZSBzdXJlIHlvdXIgZGF0YSB0eXBlcyBhcmUgY29ycmVjdCEqKgoKKioqCgojIyAqKkRhdGEgVHJhbnNmb3JtaW5nKiogKDE1IHBvaW50cykKCioqKiAgCgojIyMjICoqSWYgdGhlIGRhdGEgbmVlZHMgdG8gYmUgdHJhbnNmb3JtZWQgaW4gYW55IHdheSAodmFsdWVzIHJlY29kZWQsIHBpdm90ZWQsIGV0YyksIGRvIGl0IGhlcmUuIEV4YW1wbGVzIGluY2x1ZGUgdHJhbnNmb3JtaW5nIGEgY29udGludW91cyB2YXJpYWJsZSBpbnRvIGEgY2F0ZWdvcmljYWwgdXNpbmcgYGNhc2Vfd2hlbigpYCwgZXRjLioqCgoqKiogIAoKYGBge3J9CiMgSSBkb250IG5lZWQgdG8gdHJhbnNmb3JtIHZhbHVlcyBidXQgbmVlZCB0byBtZXJnZSB0aGUgdHdvIG1haW4gZGF0YXNldCBiZWNhdXNlIG9uZSBoYXMgdGhlIGVtb3Rpb25hbCByZXNwb25zZXMgYW5kIHRoZSBvdGhlciBoYXMgdGhlIGNoYXJhY3RlciBuYW1lcy4KZnJpZW5kc01FUkdFID0gZnJpZW5kc0VNTyAlPiUKICBsZWZ0X2pvaW4oeSA9IGZyaWVuZHMsIAogICAgICAgICAgICAgYnkgPSBjKCJzZWFzb24iID0gInNlYXNvbiIsICJlcGlzb2RlIiA9ICJlcGlzb2RlIiwgCiAgICAgICAgICAgICAgICAgICAgInNjZW5lIiA9ICJzY2VuZSIsICJ1dHRlcmFuY2UiID0gInV0dGVyYW5jZSIpKQojbnJvdyhmcmllbmRzTUVSR0UpCiNmcmllbmRzTUVSR0Vpbm5lciA9IGZyaWVuZHNFTU8gJT4lCiMgIGlubmVyX2pvaW4oeSA9IGZyaWVuZHMsIAojICAgICAgICAgICAgIGJ5ID0gYygic2Vhc29uIiA9ICJzZWFzb24iLCAiZXBpc29kZSIgPSAiZXBpc29kZSIsIAojICAgICAgICAgICAgICAgICAgICAic2NlbmUiID0gInNjZW5lIiwgInV0dGVyYW5jZSIgPSAidXR0ZXJhbmNlIikpCiNucm93KGZyaWVuZHNNRVJHRWlubmVyKQoKZnJpZW5kc01FUkdFID0gZnJpZW5kc01FUkdFICU+JSAKICBzZWxlY3Qoc2Vhc29uLCBlbW90aW9uLCBzcGVha2VyKSAKCiMhaXMubmEoZnJpZW5kc01FUkdFKSB0b28gbWFueSByb3dzIHRvIGNoZWNrCnZpc19kYXQoZnJpZW5kc01FUkdFKQpgYGAKCgoqKiogICAgCgojIyMjICoqQm9udXMgcG9pbnRzICg1IHBvaW50cykgZm9yIGRhdGFzZXRzIHRoYXQgcmVxdWlyZSBtZXJnaW5nIG9mIHRhYmxlcywgYnV0IG9ubHkgaWYgeW91IHJlYXNvbiB0aHJvdWdoIHdoZXRoZXIgeW91IHNob3VsZCB1c2UgYGxlZnRfam9pbmAsIGBpbm5lcl9qb2luYCwgb3IgYHJpZ2h0X2pvaW5gIG9uIHRoZXNlIHRhYmxlcy4gTm8gY3JlZGl0IHdpbGwgYmUgcHJvdmlkZWQgaWYgeW91IGRvbid0LioqCgoqKiogIAoKPHN0eWxlPgpkaXYuYmx1ZSB7IGJhY2tncm91bmQtY29sb3I6I2U2ZjBmZjsgYm9yZGVyLXJhZGl1czogNHB4OyBwYWRkaW5nOiAxMHB4O30KPC9zdHlsZT4KPGRpdiBjbGFzcyA9ICJibHVlIj4KIyMjIyBMZWZ0X2pvaW4gYWRkcyBjb2x1bW5zIHRvIHRoZSByaWdodCBldmVuIGlmIHRoZXkgZG8gbm90IGhhdmUgdmFsdWVzIGluIGZldyByb3dzIGZvciB0aGUgY29uZGl0aW9ucyBJIGFtIGpvaW5pbmcgdGhlbS4gSW5uZXJfam9pbiByZXR1cm5zIHJvd3Mgd2hlbiBib3RoIG1lcmdpbmcgdGFibGVzIGhhdmUgbWFjaGluZyB2YWx1ZXMuSSBhbSB1c2luZyBsZWZ0X2pvaW4gaGVyZSBiZWNhdXNlIHRvIG1lIGl0IGlzIG1vcmUgaW50dWl0aXZlIChJIGhhdmUgYSB0YWJsZSBJIGxpa2UgSSB3YW50IHRvIGFkZCBjb2x1bW5zIGluIHRoYXQgdGFibGUpLiBIb3dldmVyLCBJIGRpZCB0ZXN0IGlubmVyX2pvaW4gYW5kIGl0IGRvZXMgbm90IGdpdmUgYSBkaWZmZXJlbnQgcm93IG51bWJlcnMsIGFuZCBhbHNvIEkgd2FudCB0aGUgZW1vdGlvbmFsIHJlc3BvbnNlcyBmb3IgdGhlIHJvd3Mgd2l0aCBjaGFyYWN0ZXIgbmFtZXMgYW5kIG5vIGVtb3Rpb25hbCByZXNwb25zZSB2YWx1ZSB3b3VsZCBoYXZlIGJlZW4gbm8gdXNlIGZvciB0aGlzIHByb2plY3QuCjwvZGl2PiAKCioqKiAgCgojIyMjICoqU2hvdyB5b3VyIHRyYW5zZm9ybWVkIHRhYmxlIGhlcmUuIFVzZSB0b29scyBzdWNoIGFzIGBnbGltcHNlKClgLCBgc2tpbSgpYCBvciBgaGVhZCgpYCB0byBpbGx1c3RyYXRlIHlvdXIgcG9pbnQuKiogCgoqKiogIAoKYGBge3J9CnNsaWNlKGZyaWVuZHNNRVJHRSkKYGBgCgoqKiogIAoKIyMjIyAgKipBcmUgdGhlIHZhbHVlcyB3aGF0IHlvdSBleHBlY3RlZCBmb3IgdGhlIHZhcmlhYmxlcz8gV2h5IG9yIFdoeSBub3Q/KioKCioqKiAgCgo8c3R5bGU+CmRpdi5ibHVlIHtiYWNrZ3JvdW5kLWNvbG9yOiNlNmYwZmY7IGJvcmRlci1yYWRpdXM6IDRweDsgcGFkZGluZzogMTBweDt9Cjwvc3R5bGU+CjxkaXYgY2xhc3MgPSAiYmx1ZSI+CiMjIyMgSSBiZWxpZXZlIEkgZ290IHRoZSByaWdodCB2YWx1ZXMgZm9yIHRoZSB2YXJpYWJsZXMuIEkgd2lsbCBvbmx5IGJlIGxvb2tpbmcgYXQgc2Vhc29uIG9uZSB0aHJvdWdoIGZvdXIsIGVtb3Rpb25hbCByZXNwb25zZXMgYW5kIHRoZSBtYWluIHNpeCBjaGFyYWN0ZXJzLiBJIGhhdmUgbW9yZSB0aGFuIHRoZSBmb3VyIHNlYXNvbnMgSSBuZWVkLCBtb3JlIGVtb3Rpb25hbCByZXNwb25zZXMgdGhhbiBJIG5lZWQgYW5kIG1vcmUgY2hhcmFjdGVycyB0aGFuIEkgbmVlZCB3aGljaCBJIHdpbGwgYmUgZmlsdGVyaW5nIHRocm91Z2ggaW4gdGhlIG5leHQgc3RlcC4gCjwvZGl2PiAKCioqKgoKIyMgKipWaXN1YWxpemluZyBhbmQgU3VtbWFyaXppbmcqKiAoMTUgcG9pbnRzKQoKKioqICAKCiMjIyMgKipVc2UgYGdyb3VwX2J5KCkvc3VtbWFyaXplKClgIHRvIG1ha2UgYSBzdW1tYXJ5IG9mIHRoZSBkYXRhIGhlcmUuIFRoZSBzdW1tYXJ5IHNob3VsZCBiZSByZWxldmFudCB0byB5b3VyIHJlc2VhcmNoIHF1ZXN0aW9uKioKCioqKiAgCgpgYGB7cn0KIyBIZXJlIEkgYW0gZmlsdGVyaW5nIHRoZSB0aGUgZW1vdGlvbnMgSSBuZWVkIGFuZCBmb3IgdGhlIG1haW4gc2l4IGNoYXJhY3RlcnMuIFdlIGhhdmUgZW1vdGlvbnMgZGF0YSBvbmx5IGZvciBmb3VyIHNlYXNvbnMuIApmcmllbmRzRmluYWwgPSBmcmllbmRzTUVSR0UgJT4lCiAgICBmaWx0ZXIoZW1vdGlvbiAlaW4lIGMoIkpveWZ1bCIsICJTYWQiLCAiUG93ZXJmdWwiLCAiTWFkIikpICU+JQogICAgZmlsdGVyKHNwZWFrZXIgJWluJSBjKCJDaGFuZGxlciBCaW5nIiwgIkpvZXkgVHJpYmJpYW5pIiwKICAgICAgICAgICAiUm9zcyBHZWxsZXIiLCAiUGhvZWJlIEJ1ZmZheSIsICJNb25pY2EgR2VsbGVyIiwKICAgICAgICAgICAiUmFjaGVsIEdyZWVuIikpICU+JQogICAgZmlsdGVyKHNlYXNvbiAlaW4lIGMoMSwgMiwgMywgNCkpICU+JQogICAgZ3JvdXBfYnkoc3BlYWtlciwgZW1vdGlvbiwgc2Vhc29uKSAlPiUKICAgIHN1bW1hcml6ZShFbW9Db3VudCA9IG4oKSkgCgpnbGltcHNlKGZyaWVuZHNGaW5hbCkKc2xpY2UoZnJpZW5kc0ZpbmFsKQpgYGAKCgoqKiogIAoKIyMjIyAqKldoYXQgYXJlIHlvdXIgZmluZGluZ3MgYWJvdXQgdGhlIHN1bW1hcnk/IEFyZSB0aGV5IHdoYXQgeW91IGV4cGVjdGVkPyoqCgoqKiogIAoKPHN0eWxlPgpkaXYuYmx1ZSB7YmFja2dyb3VuZC1jb2xvcjojZTZmMGZmOyBib3JkZXItcmFkaXVzOiA0cHg7IHBhZGRpbmc6IDEwcHg7fQo8L3N0eWxlPgo8ZGl2IGNsYXNzID0gImJsdWUiPgojIyMjIFRoZSBzdW1tYXJ5IHN1Y2Nlc3NmdWxseSBmaWx0ZXJlZCBvdXQgZmlyc3QgZm91ciBzZWFzb25zIGFuZCBmZXcgZW1vdGlvbnMgdGhhdCBJIHdpbGwgYmUgbG9va2luZyBhdC4gVGhpcyB0YWJsZSBpcyBleGFjdGx5IHdoYXQgSSBuZWVkZWQgZm9yIGZ1cnRoZXIgYW5hbHlzaXMuCjwvZGl2PiAKCgoqKiogIAoKIyMjIyAqKk1ha2UgYXQgbGVhc3QgdHdvIHBsb3RzIHRoYXQgaGVscCB5b3UgYW5zd2VyIHlvdXIgcXVlc3Rpb24gb24gdGhlIHRyYW5zZm9ybWVkIG9yIHN1bW1hcml6ZWQgZGF0YS4qKgoKKioqICAKCmBgYHtyfQojIEJhciBwbG90IGJ5IGVhY2ggZm91ciBpbnRlcmVzdGVkIGVtb3Rpb25zIApnZ3Bsb3QoZGF0YSA9IGZyaWVuZHNGaW5hbCwKICAgICAgIGFlcyh4ID0gc3BlYWtlciwKICAgICAgICAgICB5ID0gRW1vQ291bnQsIAogICAgICAgICAgIGZpbGwgPSBmYWN0b3Ioc2Vhc29uKSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsKICAgIGZhY2V0X3dyYXAodmFycyhlbW90aW9uKSkgKyAgCiAgICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWUgPSAiU2Vhc29ucyIpICsKICAgIGxhYnMoeCA9ICJjaGFyYWN0ZXIgTmFtZXMiLCAgCiAgICAgICB5ID0gIkVtb3Rpb25hbCBSZXNwb25zZSBDb3VudCIsICAKICAgICAgIHRpdGxlID0gIkJhcnBsb3Qgb2YgRW1vdGlvbnMgYnkgU2Vhc29ucyIpICsgIAogICAgdGhlbWVfYncoKSArICAKICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gLTMwLCBoanVzdCA9IDApLCAKICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArICAKICAgIHNjYWxlX2ZpbGxfdmlyaWRpc19kKG5hbWUgPSAiU2Vhc29ucyIpICsKICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSB3ZXNfcGFsZXR0ZSgiQm90dGxlUm9ja2V0MiIpKQpgYGAKCioqKiAgCgoKYGBge3J9CiMgQmFyIHBsb3QgZm9yIGFsbCBlbW90aW9uYWwgcmVzcG9uc2UgYnkgc2Vhc29uCmdncGxvdChkYXRhID0gZnJpZW5kc0ZpbmFsLAogICAgICAgYWVzKHggPSBzZWFzb24sCiAgICAgICAgICAgeSA9IEVtb0NvdW50LCAKICAgICAgICAgICBmaWxsID0gZmFjdG9yKHNwZWFrZXIpKSkgKwogICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKwogICAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lID0gIlNlYXNvbnMiKSArCiAgICBsYWJzKHggPSAiU2Vhc29ucyIsICAKICAgICAgIHkgPSAiRW1vdGlvbmFsIFJlc3BvbnNlIENvdW50IiwgIAogICAgICAgdGl0bGUgPSAiQmFycGxvdCBvZiBFbW90aW9ucyBieSBTZWFzb25zIikgKyAgCiAgICB0aGVtZV9idygpICsgIAogICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAtMzAsIGhqdXN0ID0gMCksIAogICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsgIAogICAgc2NhbGVfZmlsbF92aXJpZGlzX2QobmFtZSA9ICJjaGFyYWN0ZXIgTmFtZXMiKSArCiAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gd2VzX3BhbGV0dGUoIkJvdHRsZVJvY2tldDEiKSkKYGBgCgoKKioqICAKCiMjICoqRmluYWwgU3VtbWFyeSoqICgxMCBwb2ludHMpCgoqKiogIAoKIyMjIyAqKlN1bW1hcml6ZSB5b3VyIHJlc2VhcmNoIHF1ZXN0aW9uIGFuZCBmaW5kaW5ncyBiZWxvdy4qKgoKKioqICAKCjxzdHlsZT4KZGl2LmJsdWUge2JhY2tncm91bmQtY29sb3I6I2U2ZjBmZjsgYm9yZGVyLXJhZGl1czogNHB4OyBwYWRkaW5nOiAxMHB4O30KPC9zdHlsZT4KPGRpdiBjbGFzcyA9ICJibHVlIj4KIyMjIyBJIHdhcyBsb29raW5nIGF0IGVtb3Rpb25hbCByZXNwb25zZSBjaGFuZ2Ugb3ZlciB0aGUgZmlyc3QgZm91ciBzZWFzb25zIG9mIHRoZSBmcmllbmRzIHNlcmllcy4gVGhlIGJhcnBsb3Qgc2hvd3MgZWFjaCBmb3VyIGVtb3Rpb25zIHRoYXQgd2VyZSBmb2N1c2VkIGluIHRoaXMgcHJvamVjdCBpbiBmb3VyIHNlcGFyYXRlIGdyYXBocyBhbmQgbmFtZWQgYWNjb3JkaW5nbHksIHNlYXNvbnMgYXJlIHJlcHJlc2VudGVkIGJ5IGNvbG9ycyBhbmQgbm90ZWQgYmVsb3cgdGhlIGdyYXBoLCBhbmQgY2hhcmFjdGVyIG5hbWVzIGFyZSBzaG93cyBiZWxvdyB0aGUgZ3JhcGhzIHdoaWNoIGFsc28gYXBwbGllcyBmb3IgdGhlIGFib3ZlIHR3byBiYXIgcGxvdHMuIEZyb20gdGhlIHBsb3QgYWJvdmUgd2Ugc2VlIHRoYXQgam95ZnVsIHNjZW5lcyBhcmUgbW9zdCBwcmV2ZWxlbnQgYW1vbmcgYWxsIHNpeCBjaGFyYWN0ZXJzIGFsbCB0aG91Z2hvdXQgdGhlIGZvdXIgc2Vhc29ucy4gVGhlIGNoYXJhY3RlcnMgQ2hhbmRsZXIsIE1vbmljYSBhbmQgUmFjaGVsIHNlZW0gdG8gYmUgbW9yZSBwcmV2ZWxlbnQgdG8gc2hvdyBtYWQgZW1vdGlvbnMgdGhhbiBvdGhlcnMuIFBvd2VyZnVsIGVtb3Rpb25hbCBzY2VuZXMgaW5jcmVhc2VkIGZvciBhbGwgY2hhcmFjdGVycyBvdmVyIHRoZSBmaXJzdCBmZXcgZmV3IHNlYXNvbnMgYW5kIGFyZSBtb3N0IHByZXZlbGFudCBpbiB0aGUgZm91cnRoIHNlYXNvbi4gVGhlIGNoYXJhY3RlciBQaG9lYmUgc2VlbXMgdG8gaGF2ZSBtb3JlIHNhZCBzY2VuZXMgaW4gc2Vhc29uIHRocmVlOyBob3dldmVyLCBSYWNoZWwgc3RhcnRlZCB0aGUgc2VyaWVzIHBlcmZvcm1pbmcgaW4gbW9yZSBzYWQgc2NlbmVzIHRoYW4gb3RoZXJzLiAKPC9kaXY+IAoKKioqICAKCiMjIyMgKipBcmUgeW91ciBmaW5kaW5ncyB3aGF0IHlvdSBleHBlY3RlZD8gV2h5IG9yIFdoeSBub3Q/KioKCioqKiAgCgo8c3R5bGU+CmRpdi5ibHVlIHtiYWNrZ3JvdW5kLWNvbG9yOiNlNmYwZmY7IGJvcmRlci1yYWRpdXM6IDRweDsgcGFkZGluZzogMTBweDt9Cjwvc3R5bGU+CjxkaXYgY2xhc3MgPSAiYmx1ZSI+CiMjIyMgSSBleHBlY3RlZCBkcmVzdGljIGNoYW5nZSBpbiBhbGwgY2hhcmFjdGVycycgZW1vdGlvbmFsIHJlc3BvbnNlIG92ZXIgdGhlIHllYXJzOyBob3dldmVyLCBvbmx5IHBvd2VyZnVsIGVtb3Rpb25hbCBzY2VuZXMgaW5jcmVhc2VkIHNpZ25pZmljYW50bHkgaW4gc2Vhc29uIGZvdXIuIEFsc28sIG1hZCBlbW90aW9uYWwgcmVzcG9uc2VzIGRpZCBpbmNyZWFzZSBzdGVhZGlseSBmb3IgdGhyZWUgY2hhcmFjdGVycy4gVG90YWwgZW1vdGlvbmFsIHJlc3BvbnNlIHdpc2Ugc2Vhc29uIHRocmVlIGFuZCBmb3VyIHNob3dlZCBtb3JlIHJlc3BvbnNlcyB0aGFuIHRoZSBmaXJzdCB0d28gZm9yIGFsbCBzaXggY2hhcmFjdGVycy4gQWxsIHNlYXNvbnMnIGRhdGEgb24gZW1vdGlvbmFsIHJlc3BvbnNlcyBtaWdodCBoYXZlIHNob3duIG1vcmUgcHJvbWluZW50IHRyZW5kIHRoYW4gd2hhdCB3ZSBhcmUgc2VlaW5nIGhlcmUuCjwvZGl2PiAKCioqKiAgCgojIyMjICoqRnVuY3Rpb25zKioKCioqKiAgCgpgYGB7cn0KIyBJIGZvbGxvd2VkIHRoZSBjbGFzcyBub3RlcyBhbmQgdGhpcyB3ZWJzaXRlIHRvIHdyaXRlIHRoZSBmdW5jdGlvbnMgaHR0cHM6Ly93d3cuc3RhdG1ldGhvZHMubmV0L21hbmFnZW1lbnQvdXNlcmZ1bmN0aW9ucy5odG1sCgpndWJsYSA9IGZ1bmN0aW9uKGRmLCBlbW8sIHNlYXMpewogIG91dERGICA9IGRmICU+JQogICAgZmlsdGVyKGVtb3Rpb24gJWluJSBjKGVtbykpICU+JQogICAgZmlsdGVyKHNlYXNvbiA9PSBzZWFzKSAlPiUKICAgIGZpbHRlcihzcGVha2VyICVpbiUgYygiQ2hhbmRsZXIgQmluZyIsICJKb2V5IFRyaWJiaWFuaSIsCiAgICAgICAgICAgIlJvc3MgR2VsbGVyIiwgIlBob2ViZSBCdWZmYXkiLCAiTW9uaWNhIEdlbGxlciIsCiAgICAgICAgICAgIlJhY2hlbCBHcmVlbiIpKSAjIEkgb25seSB3YW50IHRoZSBtYWluIHNpeCBjaGFyYWN0ZXJzJyBlbW90aW9uYWwgcmVzcG9uc2VzCiAgcmV0dXJuKG91dERGKQp9CgpwaXByYSA9IGZ1bmN0aW9uKGRmLCBlbW8pewogIG91dERGICA9IGRmICU+JQogICAgZ3JvdXBfYnkoc3BlYWtlcikgJT4lCiAgICBzdW1tYXJpemUoZW1vID0gbigpKQogIHJldHVybihvdXRERikKfQoKIyBUaGlzIGlzIGhvdyBJIHBsYW5uZWQgdG8gdXNlIHRoZW0KI0pveVMxID0gZ3VibGEoZGYgPSBmcmllbmRzTUVSR0UsIGVtbyA9ICJKb3lmdWwiLCBzZWFzID0gMSkKI1NhZFMxID0gZ3VibGEoZGYgPSBmcmllbmRzTUVSR0UsIGVtbyA9ICJTYWQiLCBzZWFzID0gMSkKI0pveVMxc3VtbWFyeSA9IHBpcHJhKGRmID0gSm95UzEpCiNTYWRTMXN1bW1hcnkgPSBwaXByYShkZiA9IFNhZFMxKQojTUVSR0VlbW9TMSA9IEpveVMxc3VtbWFyeSU+JQojICBsZWZ0X2pvaW4oeSA9IFNhZFMxc3VtbWFyeSwgCiMgICAgICAgICAgICAgYnkgPSBjKCJzcGVha2VyIiA9ICJzcGVha2VyIikpCiNzbGljZShNRVJHRWVtb1MxKQpgYGAKCioqKgoKCgoKCgoKCgo=