library(knitr)
library(tidyverse)
library(DT)
library(ggplot2)

Advertising metrics in Tableau calculations.

In tableau
In tableau
In tableau

In tableau

Benchmarking Sources

Facebook

AdWords

DoubleClick

Vendor <- c("Ad Words Search", "Ad Words Display", "Double Click Low Viewability", "Double Click High Viewability", "Facebook", "YouTube")
CTR <- c(2.2, 0.22, NA, NA, 0.73, .0056)
ClickRate <- c(NA, NA, 0.07, 0.14, NA, NA)
CPC <- c(1.74, 0.46, NA, NA, 1.06, NA)
AverageConversionRate <- c(NA, NA, NA, NA, .1358, NA)
CostPerAction <- c(NA, NA, NA, NA, 7.85, NA)
Benchmarks <- data.frame(Vendor, CTR, ClickRate, CPC, AverageConversionRate, CostPerAction)
kable(Benchmarks)

Vendor CTR ClickRate CPC AverageConversionRate CostPerAction
Ad Words Search 2.2000 NA 1.74 NA NA
Ad Words Display 0.2200 NA 0.46 NA NA
Double Click Low Viewability NA 0.07 NA NA NA
Double Click High Viewability NA 0.14 NA NA NA
Facebook 0.7300 NA 1.06 0.1358 7.85
YouTube 0.0056 NA NA NA NA

Benchmarks

DoubleClick

DC <- read.csv("DoubleClick_2017-10-24.csv", header = T, stringsAsFactors = F)
DC <- DC %>% rename(SiteDCM = Site..DCM., ViewableImp = Active.View..Viewable.Impressions, ClickRate = Click.Rate) %>% select(Date, Ad, SiteDCM, Ad.Type, Creative, Clicks, Impressions, ClickRate, ViewableImp)
DC$Date <- as.Date(DC$Date, format = "%m/%d/%Y")
DC <- DC %>% mutate(Click.Rate = round(((Clicks/Impressions)*100), digits = 2)) %>% arrange(desc(ViewableImp))

The DoubleClick Data

datatable(DC, options = list(
  columnDefs = list(list(className = 'dt-center', targets = 5)),
  pageLength = 5,
  hover = TRUE,
  lengthMenu = c(5, 10, 15, 20)
))

We would like to see which ads perform best on DoubleClick sites.

DoubleClick data for the Week starting 10-24-2017 grouped by site and Ad Type.

DC1 <- DC %>% group_by(Date, SiteDCM, Ad.Type) %>% summarise(ClickRate = round(mean(ClickRate), digits = 2)) %>% filter(SiteDCM!="Bangor Daily News") 
datatable(DC1, options = list(
  columnDefs = list(list(className = 'dt-center', targets = 3)),
  pageLength = 5,
  hover = TRUE,
  lengthMenu = c(5, 10, 15, 20)
))

Double Click

Looking at how the different sites perform against the benchmarks.

The benchmarks are demarcated by the horizontal black lines.

The benchmark line at Click Rate = 0.7 when all impressions are considered. When only the viewable impressions are used, the Click Rate benchmark = 0.14.

I have left the Bangor Daily News out of this plot because its clickrate is well above the benchmark and it overshadows the other sites.

Note the Maine Today and the doubleclick bid manager ads performed below goals this week.

ggplot(data=DC1, aes(x=Date, y=ClickRate, group=SiteDCM, color=SiteDCM)) +
    geom_smooth(se = FALSE) + theme_bw() + geom_hline(yintercept = 0.14) + geom_hline(yintercept = 0.07) + theme(axis.text.x = element_text(angle = 90, vjust = 1, hjust = 1))  

Ad Type

There are 4 ad types, Should ask Chris if default falls into one of these categories.

ggplot(data=DC1, aes(x=Date, y=ClickRate, group=Ad.Type, color=Ad.Type)) +
    geom_smooth(se = FALSE) + theme_bw() + geom_hline(yintercept = 0.14) + geom_hline(yintercept = 0.07) + theme(axis.text.x = element_text(angle = 90, vjust = 1, hjust = 1))

ggplot(data=DC1, aes(x=SiteDCM, y=ClickRate, fill=Ad.Type)) +
    geom_bar(stat="identity", position=position_dodge()) + theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) + geom_hline(yintercept = 0.14) + geom_hline(yintercept = 0.07) + theme_bw()

Creative

Do some ads get clicked more than others?

Creative <- DC %>% group_by(Date, Creative) %>% summarise(CR = mean(Click.Rate))
Creative1 <- Creative %>% filter(Creative != "USM_Nate_VIDEO")
Creative2 <-  Creative1 %>% filter(Creative != "USM_Veronica_VIDEO")
Creative3 <- Creative2 %>% filter(Creative != "USMFY18_Lauren_30sec")
exclusions <- c("USM_Nate_VIDEO", "USM_Veronica_VIDEO", "USMFY18_Lauren_30sec")
matchExpression <- paste(exclusions, collapse = "|")
EverythingElse <- Creative %>% filter(grepl(matchExpression, Creative))  
datatable(EverythingElse)

ggplot(Creative3, aes(x = Creative, y = CR)) + geom_bar(stat = "identity", fill = "darkblue")  + geom_hline(yintercept = 0.14) + geom_hline(yintercept = 0.07) + facet_wrap(~Date, ncol = 1)+ theme_bw() + theme(axis.text.x = element_text(angle = 90, vjust = 1, hjust = 1)) 

Which show most often?

Grouping by Ad, this table shows a summary of this weeks statistics.

DCTable <- DC %>% group_by(Ad) %>% summarise(Clicks = sum(Clicks), Impressions = sum(Impressions), ViewableImp = sum(ViewableImp)) %>% mutate(pctImpViewable = round(ViewableImp/Impressions, digits = 2), ClickRate = round(((Clicks/ViewableImp)*100), digits = 2), Difference = ClickRate - 0.14) %>%  arrange(desc(Clicks))
DCTableExclusions <- DCTable %>% filter(ViewableImp == 0)
datatable(DCTableExclusions, options = list(
  columnDefs = list(list(className = 'dt-center', targets = 5)),
  pageLength = 5,
  hover = TRUE,
  lengthMenu = c(5, 10, 15, 20)
))

Click Rates for DoubleClick Ads can be seen here. However, it’s skewed by a handful of ads.

ggplot(DCTable, aes(x = Ad, y = ClickRate)) + geom_bar(stat = "identity", fill = "darkblue") + theme_bw()+ theme(axis.text.x = element_text(angle = 90, vjust = 1, hjust = 1))+ geom_hline(yintercept = 0.14) + geom_hline(yintercept = 0.07) 

Ads skewing the DC report.

#To exclude
ToExclude <- c("Video_BDN_Veronica", "Video_BDN_Nate", "Video_BDN_Lauren", "640x640_Spotify_Tracker_Nate", "300x250_Pandora_Veronica",  "300x250_Pandora_Nate", "300x250 Default Web Ad")
matchExpression1 <- paste(ToExclude, collapse = "|")
Exclusions <- DCTable %>% filter(grepl(matchExpression1, Ad))
unique(Exclusions$Ad)
[1] "640x640_Spotify_Tracker_Nate" "Video_BDN_Nate"              
[3] "Video_BDN_Lauren"             "Video_BDN_Veronica"          
[5] "300x250 Default Web Ad"       "300x250_Pandora_Nate"        
[7] "300x250_Pandora_Veronica"    
ggplot(Exclusions, aes(x = Ad, y = ClickRate)) + geom_bar(stat = "identity", fill = "darkblue") + theme_bw()+ theme(axis.text.x = element_text(angle = 90, vjust = 1, hjust = 1))+ geom_hline(yintercept = 0.14) + geom_hline(yintercept = 0.07) + scale_y_continuous(limits = c(0, 60))

Click Rate is calculated with this formula: __(Clicks/ViewableImp)*100__

Turns out that 4 of the Ads that are skewing the report, have no viewable impressions. They

This plot shows the Ad Click Rates of the remaining ads that are not skewing the report.

datatable(EverythingElse)

DCTable <-  DCTable %>% filter(Ad!="Video_BDN_Veronica") 
DCTable <-  DCTable %>% filter(Ad!= "Video_BDN_Nate")
DCTable <-  DCTable %>% filter(Ad!= "Video_BDN_Lauren")
DCTable <-  DCTable %>% filter(Ad!= "640x640_Spotify_Tracker_Nate")
DCTable <-  DCTable %>% filter(Ad!= "300x250_Pandora_Veronica")
DCTable <-  DCTable %>% filter(Ad!= "300x250_Pandora_Nate")
DCTable <-  DCTable %>% filter(Ad!= "300x250 Default Web Ad")
head(DCTable)
ggplot(DCTable, aes(x = Ad, y = ClickRate)) + geom_bar(stat = "identity", fill = "darkblue") + theme_bw()+ theme(axis.text.x = element_text(angle = 90, vjust = 1, hjust = 1))+ geom_hline(yintercept = 0.14) + geom_hline(yintercept = 0.07)

ggplot(EverythingElse, aes(x = Ad, y = ClickRate)) + geom_bar(stat = "identity", fill = "darkblue") + theme_bw()+ theme(axis.text.x = element_text(angle = 90, vjust = 1, hjust = 1))+ geom_hline(yintercept = 0.14) + geom_hline(yintercept = 0.07)
Error in FUN(X[[i]], ...) : object 'Ad' not found

Facebook

FB <- read.csv("Facebook_2017-10-24.csv", header = T, stringsAsFactors = F)
FB$Date <- as.Date(FB$Date, format = "%m/%d/%Y")
head(FB)
datatable(FB, options = list(
  columnDefs = list(list(className = 'dt-center', targets = 5)),
  pageLength = 5,
  hover = TRUE,
  lengthMenu = c(5, 10, 15, 20)
))

names(FB)
 [1] "Ad.Name"            "Platform"           "Placement"          "Device"            
 [5] "Date"               "AdSetName"          "Audience"           "TargetLocation"    
 [9] "Campaign.Name"      "Reach"              "Frequency"          "Impressions"       
[13] "Clicks.All."        "UniqueClicks.All."  "CTR.All."           "UniqueCTR.All."    
[17] "AmountSpent"        "CPM"                "CostPer1000Reached" "CPC.All."          
[21] "Actions"            "PeopleTakingAction" "Likes"              "LinkClicks"        
[25] "ViewPercentage"     "ViewTime"          

Impressions, Clicks(All), Unique Clicks (All), Amount Spent, CTR, Unique CTR, CPC, and CPM are the metrics that have been marked as the most informative.

In tableau

In tableau

names(FB)
 [1] "Ad.Name"            "Platform"           "Placement"          "Device"            
 [5] "Date"               "AdSetName"          "Audience"           "TargetLocation"    
 [9] "Campaign.Name"      "Reach"              "Frequency"          "Impressions"       
[13] "Clicks.All."        "UniqueClicks.All."  "CTR.All."           "UniqueCTR.All."    
[17] "AmountSpent"        "CPM"                "CostPer1000Reached" "CPC.All."          
[21] "Actions"            "PeopleTakingAction" "Likes"              "LinkClicks"        
[25] "ViewPercentage"     "ViewTime"          
FBBench <- FB %>% select(Date,Ad.Name, Placement, Platform, Audience, Clicks.All., UniqueClicks.All., CTR.All., UniqueCTR.All.,CPC.All., Impressions, Actions, AmountSpent, PeopleTakingAction) %>% mutate(CTR_BenchMk = 0.73, CTRDiff = CTR.All. - CTR_BenchMk, CPC_Bench = 1.06, CPCDiff = CPC_Bench - CPC.All., CPA = round((AmountSpent/Actions),2), CPA_Bench = 7.85, CPADiff = CPA_Bench-CPA)
head(FBBench)

Here is the CTR by Audience over time. The benchmark CTR is demarcated with a black line. The HS audience is the strongest.

ggplot(FBBench, aes(x = Date, y = CTR.All., group = Audience, color = Audience)) + geom_smooth(se = FALSE) + theme_bw()+ theme(axis.text.x = element_text(angle = 90, vjust = 1, hjust = 1)) + geom_hline(yintercept = 0.73)

The CPC Benchmark is $1.06. This plot shows what USM paid per click daily the week of 10-24-2017. Anything over the black line means we are performing worse than the benchmark. Here it looks like marketing to graduate students is costly.

ggplot(FBBench, aes(x = Date, y = CPC.All., group = Audience, color = Audience)) + geom_smooth(se = FALSE) + theme_bw()+ theme(axis.text.x = element_text(angle = 90, vjust = 1, hjust = 1)) + geom_hline(yintercept = 1.06)

Cost per Action: This is calculated by the amount spent/number of actions. This seems way off. We pay well below the benchmark.

ggplot(FBBench, aes(x = Date, y = , CPA, group = Audience, color = Audience)) + geom_smooth(se = FALSE) + theme_bw()+ theme(axis.text.x = element_text(angle = 90, vjust = 1, hjust = 1)) + geom_hline(yintercept = 7.85)

ggplot(FBBench, aes(x = Date, y = , PeopleTakingAction, group = Audience, color = Audience)) + geom_smooth(se = FALSE) + theme_bw()+ theme(axis.text.x = element_text(angle = 90, vjust = 1, hjust = 1))

datatable(FB %>% group_by(Date,AdSetName, Platform, Placement) %>% summarise(Imp = sum(Impressions), Clicks = sum(Clicks.All.), UniqueClicks = sum(UniqueClicks.All.), UniqueCTR = round(mean(UniqueCTR.All.), 2), CPC = round(mean(CPC.All.), 2), CPM = round(mean(CPM), 2)), options = list(
  columnDefs = list(list(className = 'dt-center', targets = 5)),
  pageLength = 5,
  hover = TRUE,
  lengthMenu = c(5, 10, 15, 20)
))

Number of records

ggplot(FB, aes(x = Audience, fill = Platform))+ geom_bar() + theme(axis.text.x = element_text(angle = 90, vjust = 1, hjust = 1)) + theme_bw()

Which audience clicks most per amout spent?

ClicksToSpent <- FB %>% group_by(Audience, Platform) %>% summarise(TotalSpent = sum(AmountSpent), Clicks = sum(Clicks.All.), Likes = sum(Likes)) %>% mutate(RatioClickToSpent = round(Clicks/TotalSpent, 2))
datatable(ClicksToSpent)

Here we look at number of clicks by audience, broken down by platform.

ggplot(ClicksToSpent, aes(x=Audience, y=Clicks, fill=Platform)) +
    geom_bar(stat="identity", position=position_dodge(), fill = "darkblue") + theme_bw()

Here we see the ratio of clicks to the total amount spent on each audience, by each platform.

ggplot(ClicksToSpent, aes(x = Audience, y = RatioClickToSpent, fill=Platform)) + 
    geom_bar(stat="identity", position=position_dodge(), fill = "darkblue") + theme_bw()

names(FB)
 [1] "Ad.Name"            "Platform"           "Placement"          "Device"            
 [5] "Date"               "AdSetName"          "Audience"           "TargetLocation"    
 [9] "Campaign.Name"      "Reach"              "Frequency"          "Impressions"       
[13] "Clicks.All."        "UniqueClicks.All."  "CTR.All."           "UniqueCTR.All."    
[17] "AmountSpent"        "CPM"                "CostPer1000Reached" "CPC.All."          
[21] "Actions"            "PeopleTakingAction" "Likes"              "LinkClicks"        
[25] "ViewPercentage"     "ViewTime"          
summary(FB)
   Ad.Name            Platform          Placement            Device         
 Length:540         Length:540         Length:540         Length:540        
 Class :character   Class :character   Class :character   Class :character  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character  
                                                                            
                                                                            
                                                                            
                                                                            
      Date             AdSetName           Audience         TargetLocation    
 Min.   :2017-10-24   Length:540         Length:540         Length:540        
 1st Qu.:2017-10-25   Class :character   Class :character   Class :character  
 Median :2017-10-27   Mode  :character   Mode  :character   Mode  :character  
 Mean   :2017-10-26                                                           
 3rd Qu.:2017-10-29                                                           
 Max.   :2017-10-30                                                           
                                                                              
 Campaign.Name          Reach          Frequency      Impressions       Clicks.All.    
 Length:540         Min.   :   1.0   Min.   :1.000   Min.   :   1.00   Min.   : 0.000  
 Class :character   1st Qu.:  15.0   1st Qu.:1.000   1st Qu.:  16.75   1st Qu.: 0.000  
 Mode  :character   Median :  64.5   Median :1.032   Median :  72.50   Median : 0.000  
                    Mean   : 297.1   Mean   :1.201   Mean   : 367.81   Mean   : 2.557  
                    3rd Qu.: 466.0   3rd Qu.:1.183   3rd Qu.: 548.00   3rd Qu.: 2.000  
                    Max.   :3692.0   Max.   :7.500   Max.   :3943.00   Max.   :51.000  
                                                                                       
 UniqueClicks.All.    CTR.All.     UniqueCTR.All.     AmountSpent     
 Min.   : 0.000    Min.   : 0.00   Min.   : 0.0000   Min.   :  0.000  
 1st Qu.: 0.000    1st Qu.: 0.00   1st Qu.: 0.0000   1st Qu.:  0.000  
 Median : 0.000    Median : 0.00   Median : 0.0000   Median :  0.275  
 Mean   : 2.465    Mean   : 0.52   Mean   : 0.6187   Mean   :  3.002  
 3rd Qu.: 2.000    3rd Qu.: 0.50   3rd Qu.: 0.5800   3rd Qu.:  4.140  
 Max.   :46.000    Max.   :33.33   Max.   :33.3300   Max.   :102.710  
                                                                      
      CPM           CostPer1000Reached    CPC.All.          Actions      
 Min.   :   0.000   Min.   :   0.000   Min.   : 0.0000   Min.   : 0.000  
 1st Qu.:   0.000   1st Qu.:   0.000   1st Qu.: 0.0000   1st Qu.: 0.000  
 Median :   4.750   Median :   5.155   Median : 0.0000   Median : 0.000  
 Mean   :  10.784   Mean   :  11.664   Mean   : 0.8845   Mean   : 4.459  
 3rd Qu.:   9.283   3rd Qu.:  10.230   3rd Qu.: 0.8725   3rd Qu.: 3.000  
 Max.   :1093.330   Max.   :1093.330   Max.   :13.4100   Max.   :66.000  
                                                                         
 PeopleTakingAction     Likes         LinkClicks     ViewPercentage    ViewTime
 Min.   : 0.000     Min.   :1.000   Min.   : 1.000   Min.   :0      Min.   :0  
 1st Qu.: 0.000     1st Qu.:1.000   1st Qu.: 1.000   1st Qu.:0      1st Qu.:0  
 Median : 0.000     Median :1.000   Median : 3.000   Median :0      Median :0  
 Mean   : 2.781     Mean   :1.182   Mean   : 8.783   Mean   :0      Mean   :0  
 3rd Qu.: 2.000     3rd Qu.:1.000   3rd Qu.:13.000   3rd Qu.:0      3rd Qu.:0  
 Max.   :46.000     Max.   :2.000   Max.   :51.000   Max.   :0      Max.   :0  
                    NA's   :529     NA's   :420                                
range(FB$Likes)
[1] NA NA

SEM/AdWords

AdWords <- read.csv("Adwords_2017-10-241.csv", header = T, stringsAsFactors = F)
Adwords <- AdWords %>% rename(Date = Day, CampaignType = Campaign.type, AdGroup = Ad.group, CPC = Avg..CPC, CPM = Avg..CPM, AvgCost = Avg..Cost, AvgPosition = Avg..position, BounceRate = Bounce.rate, PagesSession = Pages...session, AvgDuration = Avg..session.duration..seconds., NewSessions = X..new.sessions)
Adwords$Date <- as.Date(Adwords$Date, format = "%d-%b-%y")
datatable(Adwords, options = list(
  columnDefs = list(list(className = 'dt-center', targets = 5)),
  pageLength = 5,
  hover = TRUE,
  lengthMenu = c(5, 10, 15, 20)
))

The report in Tableau looks like this:

In tableau

In tableau

Search

Adwords %>% group_by(CampaignType) %>% summarise(ClTh = round(mean(CTR), 2))
head(Adwords)
unique(Adwords$CampaignType)
[1] "Search"                           "Search Network w/ Display Select"
[3] "Video"                            "Display"                         
Search <- Adwords %>% filter(CampaignType == "Search")
Search <- Search %>% group_by(Date, Campaign) %>% summarise(CTRate = round(mean(CTR), 2), AvgCPC = round(mean(CPC), 2))
Search
Display <- Adwords %>% filter(CampaignType == "Display")
Display <- Display %>% group_by(Date, Campaign) %>% summarise(CTRate = round(mean(CTR), 2), AvgCPC = round(mean(CPC), 2))
Display
SearchDisplay <- Adwords %>% filter(CampaignType == "Search Network w/ Display Select")
Video <- Adwords %>% filter(CampaignType == "Video")

For Search, our overall performance is just above the benchmark.

ggplot(Search, aes(x = Date, y = CTRate)) + geom_smooth(se = FALSE, color = "darkblue") + theme_bw()+ theme(axis.text.x = element_text(angle = 90, vjust = 1, hjust = 1)) + geom_hline(yintercept = .022) + scale_y_continuous(limits = c(0, 0.075))

Search CPC

Overall, CPC for Search, costs less than the benchmark, however, when looked at by campaign, the Doctoral, Transfer, and Graduate campaigns cost more than the benchmark. Undergrad, courses, and Online camapaigns are less expensive.

ggplot(Search, aes(x = Date, y = AvgCPC)) + geom_smooth(se = FALSE) + theme_bw()+ theme(axis.text.x = element_text(angle = 90, vjust = 1, hjust = 1)) + geom_hline(yintercept = 1.74) + scale_y_continuous(limits = c(0, 2))

Search
ggplot(Search, aes(x = Date, y = AvgCPC, group = Campaign, color = Campaign)) + geom_smooth(se = FALSE) + theme_bw()+ theme(axis.text.x = element_text(angle = 90, vjust = 1, hjust = 1)) + geom_hline(yintercept = 1.74) + scale_y_continuous(limits = c(0, 4))

When we breaks down the campaigns, we see varying performance over time.

ggplot(Search, aes(x = Date, y = CTRate, group = Campaign, color = Campaign)) + geom_smooth(se = FALSE) + theme_bw()+ theme(axis.text.x = element_text(angle = 90, vjust = 1, hjust = 1)) + geom_hline(yintercept = .022) + scale_y_continuous(limits = c(0, 0.075))

Just looking at Campaign CTR, Online, Gmail Test, and Courses are the lower performers using AdWords Search.

Search1 <- Search %>% group_by(Campaign) %>% summarise(CTR = round(mean(CTRate), 2))
ggplot(Search1, aes(x = Campaign, y = CTR)) + geom_bar(stat = "identity", fill = "darkblue") + theme_bw()+ theme(axis.text.x = element_text(angle = 90, vjust = 1, hjust = 1)) + geom_hline(yintercept = .022) 

Display

Benchmark is 0.22

In terms of Display, we are performing well in Adwords.

Display2CPC <- Display %>% group_by(Campaign) %>% summarise(CPC = round(mean(AvgCPC), 2))
Display2CPC
Display1CTR
Display1CTR <- Display %>% group_by(Campaign) %>% summarise(CTR = round(mean(CTRate), 2))
head(Display1CTR)
ggplot(Display1CTR, aes(x = Campaign, y = CTR)) + geom_bar(stat = "identity", fill = "darkblue") + theme_bw()+ theme(axis.text.x = element_text(angle = 90, vjust = 1, hjust = 1)) + geom_hline(yintercept = .0022) 

Display

AdWords CPC

head(Display)
ggplot(Display, aes(x = Date, y = AvgCPC)) + geom_smooth(se = FALSE) + theme_bw()+ theme(axis.text.x = element_text(angle = 90, vjust = 1, hjust = 1)) + geom_hline(yintercept = .46) + scale_y_continuous(limits = c(0, 2))

Search
ggplot(Display, aes(x = Date, y = AvgCPC, group = Campaign, color = Campaign)) + geom_smooth(se = FALSE) + theme_bw()+ theme(axis.text.x = element_text(angle = 90, vjust = 1, hjust = 1)) + geom_hline(yintercept = 0.46) + scale_y_continuous(limits = c(0, 4))

datatable(Adwords, options = list(
  columnDefs = list(list(className = 'dt-center', targets = 5)),
  pageLength = 5,
  hover = TRUE,
  lengthMenu = c(5, 10, 15, 20)
))
library(chron)
GA <- read.csv("GoogleAnalytics_2017-10-24.csv", header = T, stringsAsFactors = F)
GA <- GA %>% mutate(MinutesOnPage = round(MinutesOnPage, 2))
head(GA)
#convert time, didn't work
#convert date
library(lubridate)
GA$Date <- ymd(GA$Date)
ggplot(GA, aes(x = Date, y = Unique.Pageviews))+ geom_smooth(se = FALSE) + theme_bw()

GAGroup <- GA %>% group_by(Date, Source) %>% summarise(Ave.Page.viewsDay = mean(Unique.Pageviews), AvgBounces = mean(Bounces) , bouncesToViews = Ave.Page.viewsDay/AvgBounces)
ggplot(GAGroup, aes(x = Date, y = bouncesToViews, group = Source, color = Source)) + geom_line() + theme_bw()+ theme(axis.text.x = element_text(angle = 90, vjust = 1, hjust = 1))

rpivotTable(Adwords ,c("Campaign","CampaignType","Clicks","Impressions", "CTR", "CTC", "CPM"))
LS0tDQp0aXRsZTogIldlZWtseSBBZHZlcnRpc2luZyBhbmQgTWV0cmljcyINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KICBodG1sX2RvY3VtZW50OiBkZWZhdWx0DQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IEZBTFNFKQ0KYGBgDQoNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KERUKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KYGBgDQoNCkFkdmVydGlzaW5nIG1ldHJpY3MgaW4gVGFibGVhdSBjYWxjdWxhdGlvbnMuIA0KDQo8ZGl2IHN0eWxlPSJ3aWR0aDo0MDBweDsgaGVpZ2h0PTMwMHB4Ij4NCiFbSW4gdGFibGVhdV0oQ29weU9mQ1RSQWQucG5nKQ0KPGRpdiBzdHlsZT0id2lkdGg6NDAwcHg7IGhlaWdodD0zMDBweCI+DQohW0luIHRhYmxlYXVdKENvcHlPZkNQQ0FkLnBuZykNCjxkaXYgc3R5bGU9IndpZHRoOjQwMHB4OyBoZWlnaHQ9MzAwcHgiPg0KIVtJbiB0YWJsZWF1XShDb3B5T2ZDUE1BZC5wbmcpDQoNCl9fQmVuY2htYXJraW5nIFNvdXJjZXNfXw0KDQpbRmFjZWJvb2tdKGh0dHA6Ly93d3cud29yZHN0cmVhbS5jb20vYmxvZy93cy8yMDE3LzAyLzI4L2ZhY2Vib29rLWFkdmVydGlzaW5nLWJlbmNobWFya3MpDQoNCltBZFdvcmRzXShodHRwOi8vd3d3LndvcmRzdHJlYW0uY29tL2Jsb2cvd3MvMjAxNi8wMi8yOS9nb29nbGUtYWR3b3Jkcy1pbmR1c3RyeS1iZW5jaG1hcmtzKQ0KDQpbRG91YmxlQ2xpY2tdKGh0dHBzOi8vZGRtLmdvb2dsZS5jb20vYW5hbHl0aWNzL2RmYS8/ZGVmYXVsdERzPTIyNDk3MjglM0E5NTE1I2luc2lnaHRzL2Rhc2hib2FyZC8yMjQ5NzI4JTNBOTUxNS8lM0ZfLmlTdGFydERhdGUlM0QyMDE3MTAyMiUyNl8uaUVuZERhdGUlM0QyMDE3MTEwNCUyNl8ueGFuaC1hY3Rpdml0eS1maWx0ZXJlZE9uJTNEeGFuaC5hY3Rpdml0eV9pZCUyNl8ueGFuaC1hY3Rpdml0eS1pZHMlM0QlNUIlNUQlMjZfLmRyaWxsJTNEJTVCJTVCJTIyeGFuaC5hZHZlcnRpc2VyJTIyJTJDJTIyeGFuaC5hZHZlcnRpc2VyX2lkJTIyJTJDJTIyNDkzMzUyNCUyMiU1RCU1RCUyNl8uaW5zaWdodHNDYW1wYWlnbklkJTNEMjAyMjUyMTAlMjZfLmluc2lnaHRzQWR2ZXJ0aXNlcklkJTNENDkzMzUyNCUyNmNhbXBhaWduUGlja2VyLmZpbHRlcmVkT24lM0R4YW5oLmNhbXBhaWduX2lkJTI2Y2FtcGFpZ25QaWNrZXIuaWRzJTNEJTVCJTIyMjAyMjUyMTAlMjIlNUQlMjZjYXJkX2Jyb3dzZXJBbmRQbGF0Zm9ybVR5cGUuZGltJTNEeGFuaC5wbGF0Zm9ybV90eXBlLykNCg0KDQpgYGB7cn0NClZlbmRvciA8LSBjKCJBZCBXb3JkcyBTZWFyY2giLCAiQWQgV29yZHMgRGlzcGxheSIsICJEb3VibGUgQ2xpY2sgTG93IFZpZXdhYmlsaXR5IiwgIkRvdWJsZSBDbGljayBIaWdoIFZpZXdhYmlsaXR5IiwgIkZhY2Vib29rIiwgIllvdVR1YmUiKQ0KDQpDVFIgPC0gYygyLjIsIDAuMjIsIE5BLCBOQSwgMC43MywgLjAwNTYpDQpDbGlja1JhdGUgPC0gYyhOQSwgTkEsIDAuMDcsIDAuMTQsIE5BLCBOQSkNCkNQQyA8LSBjKDEuNzQsIDAuNDYsIE5BLCBOQSwgMS4wNiwgTkEpDQpBdmVyYWdlQ29udmVyc2lvblJhdGUgPC0gYyhOQSwgTkEsIE5BLCBOQSwgLjEzNTgsIE5BKQ0KQ29zdFBlckFjdGlvbiA8LSBjKE5BLCBOQSwgTkEsIE5BLCA3Ljg1LCBOQSkNCg0KQmVuY2htYXJrcyA8LSBkYXRhLmZyYW1lKFZlbmRvciwgQ1RSLCBDbGlja1JhdGUsIENQQywgQXZlcmFnZUNvbnZlcnNpb25SYXRlLCBDb3N0UGVyQWN0aW9uKQ0Ka2FibGUoQmVuY2htYXJrcykNCg0KQmVuY2htYXJrcw0KYGBgDQoNCioqRG91YmxlQ2xpY2sqKg0KDQpgYGB7cn0NCkRDIDwtIHJlYWQuY3N2KCJEb3VibGVDbGlja18yMDE3LTEwLTI0LmNzdiIsIGhlYWRlciA9IFQsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGKQ0KREMgPC0gREMgJT4lIHJlbmFtZShTaXRlRENNID0gU2l0ZS4uRENNLiwgVmlld2FibGVJbXAgPSBBY3RpdmUuVmlldy4uVmlld2FibGUuSW1wcmVzc2lvbnMsIENsaWNrUmF0ZSA9IENsaWNrLlJhdGUpICU+JSBzZWxlY3QoRGF0ZSwgQWQsIFNpdGVEQ00sIEFkLlR5cGUsIENyZWF0aXZlLCBDbGlja3MsIEltcHJlc3Npb25zLCBDbGlja1JhdGUsIFZpZXdhYmxlSW1wKQ0KREMkRGF0ZSA8LSBhcy5EYXRlKERDJERhdGUsIGZvcm1hdCA9ICIlbS8lZC8lWSIpDQpEQyA8LSBEQyAlPiUgbXV0YXRlKENsaWNrLlJhdGUgPSByb3VuZCgoKENsaWNrcy9JbXByZXNzaW9ucykqMTAwKSwgZGlnaXRzID0gMikpICU+JSBhcnJhbmdlKGRlc2MoVmlld2FibGVJbXApKQ0KDQpgYGANCg0KVGhlIERvdWJsZUNsaWNrIERhdGENCg0KYGBge3J9DQpkYXRhdGFibGUoREMsIG9wdGlvbnMgPSBsaXN0KA0KICBjb2x1bW5EZWZzID0gbGlzdChsaXN0KGNsYXNzTmFtZSA9ICdkdC1jZW50ZXInLCB0YXJnZXRzID0gNSkpLA0KICBwYWdlTGVuZ3RoID0gNSwNCiAgaG92ZXIgPSBUUlVFLA0KICBsZW5ndGhNZW51ID0gYyg1LCAxMCwgMTUsIDIwKQ0KKSkNCmBgYA0KDQpXZSB3b3VsZCBsaWtlIHRvIHNlZSB3aGljaCBhZHMgcGVyZm9ybSBiZXN0IG9uIERvdWJsZUNsaWNrIHNpdGVzLiANCg0KRG91YmxlQ2xpY2sgZGF0YSBmb3IgdGhlIFdlZWsgc3RhcnRpbmcgMTAtMjQtMjAxNyBncm91cGVkIGJ5IHNpdGUgYW5kIEFkIFR5cGUuIA0KDQpgYGB7cn0NCg0KREMxIDwtIERDICU+JSBncm91cF9ieShEYXRlLCBTaXRlRENNLCBBZC5UeXBlKSAlPiUgc3VtbWFyaXNlKENsaWNrUmF0ZSA9IHJvdW5kKG1lYW4oQ2xpY2tSYXRlKSwgZGlnaXRzID0gMikpICU+JSBmaWx0ZXIoU2l0ZURDTSE9IkJhbmdvciBEYWlseSBOZXdzIikgDQpkYXRhdGFibGUoREMxLCBvcHRpb25zID0gbGlzdCgNCiAgY29sdW1uRGVmcyA9IGxpc3QobGlzdChjbGFzc05hbWUgPSAnZHQtY2VudGVyJywgdGFyZ2V0cyA9IDMpKSwNCiAgcGFnZUxlbmd0aCA9IDUsDQogIGhvdmVyID0gVFJVRSwNCiAgbGVuZ3RoTWVudSA9IGMoNSwgMTAsIDE1LCAyMCkNCikpDQpgYGANCg0KX19Eb3VibGUgQ2xpY2tfXw0KDQpMb29raW5nIGF0IGhvdyB0aGUgZGlmZmVyZW50IHNpdGVzIHBlcmZvcm0gYWdhaW5zdCB0aGUgYmVuY2htYXJrcy4gDQoNClRoZSBiZW5jaG1hcmtzIGFyZSBkZW1hcmNhdGVkIGJ5IHRoZSBob3Jpem9udGFsIGJsYWNrIGxpbmVzLiANCg0KVGhlIGJlbmNobWFyayBsaW5lIGF0IENsaWNrIFJhdGUgPSAwLjcgd2hlbiBhbGwgaW1wcmVzc2lvbnMgYXJlIGNvbnNpZGVyZWQuIFdoZW4gb25seSB0aGUgdmlld2FibGUgaW1wcmVzc2lvbnMgYXJlIHVzZWQsIHRoZSBDbGljayBSYXRlIGJlbmNobWFyayA9IDAuMTQuDQoNCkkgaGF2ZSBsZWZ0IHRoZSBCYW5nb3IgRGFpbHkgTmV3cyBvdXQgb2YgdGhpcyBwbG90IGJlY2F1c2UgaXRzIGNsaWNrcmF0ZSBpcyB3ZWxsIGFib3ZlIHRoZSBiZW5jaG1hcmsgYW5kIGl0IG92ZXJzaGFkb3dzIHRoZSBvdGhlciBzaXRlcy4gDQoNCk5vdGUgdGhlIE1haW5lIFRvZGF5IGFuZCB0aGUgZG91YmxlY2xpY2sgYmlkIG1hbmFnZXIgYWRzIHBlcmZvcm1lZCBiZWxvdyBnb2FscyB0aGlzIHdlZWsuDQoNCmBgYHtyfQ0KZ2dwbG90KGRhdGE9REMxLCBhZXMoeD1EYXRlLCB5PUNsaWNrUmF0ZSwgZ3JvdXA9U2l0ZURDTSwgY29sb3I9U2l0ZURDTSkpICsNCiAgICBnZW9tX3Ntb290aChzZSA9IEZBTFNFKSArIHRoZW1lX2J3KCkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLjE0KSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAuMDcpICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAxLCBoanVzdCA9IDEpKSAgDQpgYGANCg0KDQpfX0FkIFR5cGVfXw0KDQpUaGVyZSBhcmUgNCBhZCB0eXBlcywgU2hvdWxkIGFzayBDaHJpcyBpZiBkZWZhdWx0IGZhbGxzIGludG8gb25lIG9mIHRoZXNlIGNhdGVnb3JpZXMuDQoNCg0KYGBge3J9DQpnZ3Bsb3QoZGF0YT1EQzEsIGFlcyh4PURhdGUsIHk9Q2xpY2tSYXRlLCBncm91cD1BZC5UeXBlLCBjb2xvcj1BZC5UeXBlKSkgKw0KICAgIGdlb21fc21vb3RoKHNlID0gRkFMU0UpICsgdGhlbWVfYncoKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAuMTQpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMC4wNykgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDEsIGhqdXN0ID0gMSkpDQpgYGANCg0KYGBge3J9DQpnZ3Bsb3QoZGF0YT1EQzEsIGFlcyh4PVNpdGVEQ00sIHk9Q2xpY2tSYXRlLCBmaWxsPUFkLlR5cGUpKSArDQogICAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgpKSArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIHZqdXN0ID0gMSwgaGp1c3QgPSAxKSkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLjE0KSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAuMDcpICsgdGhlbWVfYncoKQ0KDQpgYGANCg0KX19DcmVhdGl2ZV9fDQoNCkRvIHNvbWUgYWRzIGdldCBjbGlja2VkIG1vcmUgdGhhbiBvdGhlcnM/DQoNCmBgYHtyLCBmaWcuaGVpZ2h0PTIwLCBmaWcud2lkdGg9N30NCg0KQ3JlYXRpdmUgPC0gREMgJT4lIGdyb3VwX2J5KERhdGUsIENyZWF0aXZlKSAlPiUgc3VtbWFyaXNlKENSID0gbWVhbihDbGljay5SYXRlKSkNCkNyZWF0aXZlMSA8LSBDcmVhdGl2ZSAlPiUgZmlsdGVyKENyZWF0aXZlICE9ICJVU01fTmF0ZV9WSURFTyIpDQpDcmVhdGl2ZTIgPC0gIENyZWF0aXZlMSAlPiUgZmlsdGVyKENyZWF0aXZlICE9ICJVU01fVmVyb25pY2FfVklERU8iKQ0KQ3JlYXRpdmUzIDwtIENyZWF0aXZlMiAlPiUgZmlsdGVyKENyZWF0aXZlICE9ICJVU01GWTE4X0xhdXJlbl8zMHNlYyIpDQpleGNsdXNpb25zIDwtIGMoIlVTTV9OYXRlX1ZJREVPIiwgIlVTTV9WZXJvbmljYV9WSURFTyIsICJVU01GWTE4X0xhdXJlbl8zMHNlYyIpDQoNCg0KbWF0Y2hFeHByZXNzaW9uIDwtIHBhc3RlKGV4Y2x1c2lvbnMsIGNvbGxhcHNlID0gInwiKQ0KRXZlcnl0aGluZ0Vsc2UgPC0gQ3JlYXRpdmUgJT4lIGZpbHRlcihncmVwbChtYXRjaEV4cHJlc3Npb24sIENyZWF0aXZlKSkgIA0KZGF0YXRhYmxlKEV2ZXJ5dGhpbmdFbHNlKQ0KZ2dwbG90KENyZWF0aXZlMywgYWVzKHggPSBDcmVhdGl2ZSwgeSA9IENSKSkgKyBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICJkYXJrYmx1ZSIpICArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAuMTQpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMC4wNykgKyBmYWNldF93cmFwKH5EYXRlLCBuY29sID0gMSkrIHRoZW1lX2J3KCkgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDEsIGhqdXN0ID0gMSkpIA0KYGBgDQoNCmBgYHtyLCBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KDQpTcGxpdFVwIDwtIERDICU+JQ0KICBzZXBhcmF0ZShDcmVhdGl2ZSwgYygiYSIsICJiIiwgImMiLCAiZCIpLCAiXyIpDQprYWJsZShTcGxpdFVwKQ0KdW5pcXVlKFNwbGl0VXAkYSkNCiANCmBgYA0KDQoNCldoaWNoIHNob3cgbW9zdCBvZnRlbj8NCg0KR3JvdXBpbmcgYnkgQWQsIHRoaXMgdGFibGUgc2hvd3MgYSBzdW1tYXJ5IG9mIHRoaXMgd2Vla3Mgc3RhdGlzdGljcy4NCg0KYGBge3J9DQpEQ1RhYmxlIDwtIERDICU+JSBncm91cF9ieShBZCkgJT4lIHN1bW1hcmlzZShDbGlja3MgPSBzdW0oQ2xpY2tzKSwgSW1wcmVzc2lvbnMgPSBzdW0oSW1wcmVzc2lvbnMpLCBWaWV3YWJsZUltcCA9IHN1bShWaWV3YWJsZUltcCkpICU+JSBtdXRhdGUocGN0SW1wVmlld2FibGUgPSByb3VuZChWaWV3YWJsZUltcC9JbXByZXNzaW9ucywgZGlnaXRzID0gMiksIENsaWNrUmF0ZSA9IHJvdW5kKCgoQ2xpY2tzL1ZpZXdhYmxlSW1wKSoxMDApLCBkaWdpdHMgPSAyKSwgRGlmZmVyZW5jZSA9IENsaWNrUmF0ZSAtIDAuMTQpICU+JSAgYXJyYW5nZShkZXNjKENsaWNrcykpDQoNCkRDVGFibGVFeGNsdXNpb25zIDwtIERDVGFibGUgJT4lIGZpbHRlcihWaWV3YWJsZUltcCA9PSAwKQ0KDQpkYXRhdGFibGUoRENUYWJsZUV4Y2x1c2lvbnMsIG9wdGlvbnMgPSBsaXN0KA0KICBjb2x1bW5EZWZzID0gbGlzdChsaXN0KGNsYXNzTmFtZSA9ICdkdC1jZW50ZXInLCB0YXJnZXRzID0gNSkpLA0KICBwYWdlTGVuZ3RoID0gNSwNCiAgaG92ZXIgPSBUUlVFLA0KICBsZW5ndGhNZW51ID0gYyg1LCAxMCwgMTUsIDIwKQ0KKSkNCmBgYA0KDQpDbGljayBSYXRlcyBmb3IgRG91YmxlQ2xpY2sgQWRzIGNhbiBiZSBzZWVuIGhlcmUuIEhvd2V2ZXIsIGl0J3Mgc2tld2VkIGJ5IGEgaGFuZGZ1bCBvZiBhZHMuIA0KDQpgYGB7cn0NCmdncGxvdChEQ1RhYmxlLCBhZXMoeCA9IEFkLCB5ID0gQ2xpY2tSYXRlKSkgKyBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICJkYXJrYmx1ZSIpICsgdGhlbWVfYncoKSsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAxLCBoanVzdCA9IDEpKSsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMC4xNCkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLjA3KSANCmBgYA0KDQpBZHMgc2tld2luZyB0aGUgREMgcmVwb3J0LiANCg0KYGBge3J9DQojVG8gZXhjbHVkZQ0KVG9FeGNsdWRlIDwtIGMoIlZpZGVvX0JETl9WZXJvbmljYSIsICJWaWRlb19CRE5fTmF0ZSIsICJWaWRlb19CRE5fTGF1cmVuIiwgIjY0MHg2NDBfU3BvdGlmeV9UcmFja2VyX05hdGUiLCAiMzAweDI1MF9QYW5kb3JhX1Zlcm9uaWNhIiwgICIzMDB4MjUwX1BhbmRvcmFfTmF0ZSIsICIzMDB4MjUwIERlZmF1bHQgV2ViIEFkIikNCg0KbWF0Y2hFeHByZXNzaW9uMSA8LSBwYXN0ZShUb0V4Y2x1ZGUsIGNvbGxhcHNlID0gInwiKQ0KDQpFeGNsdXNpb25zIDwtIERDVGFibGUgJT4lIGZpbHRlcihncmVwbChtYXRjaEV4cHJlc3Npb24xLCBBZCkpDQp1bmlxdWUoRXhjbHVzaW9ucyRBZCkNCg0KZ2dwbG90KEV4Y2x1c2lvbnMsIGFlcyh4ID0gQWQsIHkgPSBDbGlja1JhdGUpKSArIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gImRhcmtibHVlIikgKyB0aGVtZV9idygpKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDEsIGhqdXN0ID0gMSkpKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLjE0KSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAuMDcpICsgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgNjApKQ0KYGBgDQoNCkNsaWNrIFJhdGUgaXMgY2FsY3VsYXRlZCB3aXRoIHRoaXMgZm9ybXVsYTogX18oQ2xpY2tzL1ZpZXdhYmxlSW1wKSoxMDBfXw0KDQpUdXJucyBvdXQgdGhhdCA0IG9mIHRoZSBBZHMgdGhhdCBhcmUgc2tld2luZyB0aGUgcmVwb3J0LCBoYXZlIG5vIHZpZXdhYmxlIGltcHJlc3Npb25zLiBUaGV5ICANCg0KVGhpcyBwbG90IHNob3dzIHRoZSBBZCBDbGljayBSYXRlcyBvZiB0aGUgcmVtYWluaW5nIGFkcyB0aGF0IGFyZSBub3Qgc2tld2luZyB0aGUgcmVwb3J0LiANCg0KYGBge3J9DQpkYXRhdGFibGUoRXZlcnl0aGluZ0Vsc2UpDQpEQ1RhYmxlIDwtICBEQ1RhYmxlICU+JSBmaWx0ZXIoQWQhPSJWaWRlb19CRE5fVmVyb25pY2EiKSANCkRDVGFibGUgPC0gIERDVGFibGUgJT4lIGZpbHRlcihBZCE9ICJWaWRlb19CRE5fTmF0ZSIpDQpEQ1RhYmxlIDwtICBEQ1RhYmxlICU+JSBmaWx0ZXIoQWQhPSAiVmlkZW9fQkROX0xhdXJlbiIpDQpEQ1RhYmxlIDwtICBEQ1RhYmxlICU+JSBmaWx0ZXIoQWQhPSAiNjQweDY0MF9TcG90aWZ5X1RyYWNrZXJfTmF0ZSIpDQpEQ1RhYmxlIDwtICBEQ1RhYmxlICU+JSBmaWx0ZXIoQWQhPSAiMzAweDI1MF9QYW5kb3JhX1Zlcm9uaWNhIikNCkRDVGFibGUgPC0gIERDVGFibGUgJT4lIGZpbHRlcihBZCE9ICIzMDB4MjUwX1BhbmRvcmFfTmF0ZSIpDQpEQ1RhYmxlIDwtICBEQ1RhYmxlICU+JSBmaWx0ZXIoQWQhPSAiMzAweDI1MCBEZWZhdWx0IFdlYiBBZCIpDQpgYGANCg0KDQpgYGB7cn0NCmhlYWQoRENUYWJsZSkNCg0KZ2dwbG90KERDVGFibGUsIGFlcyh4ID0gQWQsIHkgPSBDbGlja1JhdGUpKSArIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gImRhcmtibHVlIikgKyB0aGVtZV9idygpKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDEsIGhqdXN0ID0gMSkpKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLjE0KSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAuMDcpDQpgYGANCg0KYGBge3J9DQpnZ3Bsb3QoRXZlcnl0aGluZ0Vsc2UsIGFlcyh4ID0gQWQsIHkgPSBDbGlja1JhdGUpKSArIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gImRhcmtibHVlIikgKyB0aGVtZV9idygpKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDEsIGhqdXN0ID0gMSkpKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLjE0KSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAuMDcpDQoNCmBgYA0KDQoNCioqRmFjZWJvb2sqKg0KDQpgYGB7cn0NCkZCIDwtIHJlYWQuY3N2KCJGYWNlYm9va18yMDE3LTEwLTI0LmNzdiIsIGhlYWRlciA9IFQsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGKQ0KRkIkRGF0ZSA8LSBhcy5EYXRlKEZCJERhdGUsIGZvcm1hdCA9ICIlbS8lZC8lWSIpDQpoZWFkKEZCKQ0KZGF0YXRhYmxlKEZCLCBvcHRpb25zID0gbGlzdCgNCiAgY29sdW1uRGVmcyA9IGxpc3QobGlzdChjbGFzc05hbWUgPSAnZHQtY2VudGVyJywgdGFyZ2V0cyA9IDUpKSwNCiAgcGFnZUxlbmd0aCA9IDUsDQogIGhvdmVyID0gVFJVRSwNCiAgbGVuZ3RoTWVudSA9IGMoNSwgMTAsIDE1LCAyMCkNCikpDQpuYW1lcyhGQikNCmBgYA0KDQpJbXByZXNzaW9ucywgQ2xpY2tzKEFsbCksIFVuaXF1ZSBDbGlja3MgKEFsbCksIEFtb3VudCBTcGVudCwgQ1RSLCBVbmlxdWUgQ1RSLCBDUEMsIGFuZCBDUE0gYXJlIHRoZSBtZXRyaWNzIHRoYXQgaGF2ZSBiZWVuIG1hcmtlZCBhcyB0aGUgbW9zdCBpbmZvcm1hdGl2ZS4gDQoNCjxkaXYgc3R5bGU9IndpZHRoOjQwMHB4OyBoZWlnaHQ9MzAwcHgiPg0KIVtJbiB0YWJsZWF1XShGQi5wbmcpDQoNCg0KYGBge3J9DQpuYW1lcyhGQikNCkZCQmVuY2ggPC0gRkIgJT4lIHNlbGVjdChEYXRlLEFkLk5hbWUsIFBsYWNlbWVudCwgUGxhdGZvcm0sIEF1ZGllbmNlLCBDbGlja3MuQWxsLiwgVW5pcXVlQ2xpY2tzLkFsbC4sIENUUi5BbGwuLCBVbmlxdWVDVFIuQWxsLixDUEMuQWxsLiwgSW1wcmVzc2lvbnMsIEFjdGlvbnMsIEFtb3VudFNwZW50LCBQZW9wbGVUYWtpbmdBY3Rpb24pICU+JSBtdXRhdGUoQ1RSX0JlbmNoTWsgPSAwLjczLCBDVFJEaWZmID0gQ1RSLkFsbC4gLSBDVFJfQmVuY2hNaywgQ1BDX0JlbmNoID0gMS4wNiwgQ1BDRGlmZiA9IENQQ19CZW5jaCAtIENQQy5BbGwuLCBDUEEgPSByb3VuZCgoQW1vdW50U3BlbnQvQWN0aW9ucyksMiksIENQQV9CZW5jaCA9IDcuODUsIENQQURpZmYgPSBDUEFfQmVuY2gtQ1BBKQ0KaGVhZChGQkJlbmNoKQ0KYGBgDQoNCg0KSGVyZSBpcyB0aGUgQ1RSIGJ5IEF1ZGllbmNlIG92ZXIgdGltZS4gVGhlIGJlbmNobWFyayBDVFIgaXMgZGVtYXJjYXRlZCB3aXRoIGEgYmxhY2sgbGluZS4gVGhlIEhTIGF1ZGllbmNlIGlzIHRoZSBzdHJvbmdlc3QuDQoNCmBgYHtyfQ0KZ2dwbG90KEZCQmVuY2gsIGFlcyh4ID0gRGF0ZSwgeSA9IENUUi5BbGwuLCBncm91cCA9IEF1ZGllbmNlLCBjb2xvciA9IEF1ZGllbmNlKSkgKyBnZW9tX3Ntb290aChzZSA9IEZBTFNFKSArIHRoZW1lX2J3KCkrIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMSwgaGp1c3QgPSAxKSkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLjczKQ0KYGBgDQoNClRoZSBDUEMgQmVuY2htYXJrIGlzICQxLjA2LiBUaGlzIHBsb3Qgc2hvd3Mgd2hhdCBVU00gcGFpZCBwZXIgY2xpY2sgZGFpbHkgdGhlIHdlZWsgb2YgMTAtMjQtMjAxNy4gQW55dGhpbmcgb3ZlciB0aGUgYmxhY2sgbGluZSBtZWFucyB3ZSBhcmUgcGVyZm9ybWluZyB3b3JzZSB0aGFuIHRoZSBiZW5jaG1hcmsuIEhlcmUgaXQgbG9va3MgbGlrZSBtYXJrZXRpbmcgdG8gZ3JhZHVhdGUgc3R1ZGVudHMgaXMgY29zdGx5LiANCg0KYGBge3J9DQpnZ3Bsb3QoRkJCZW5jaCwgYWVzKHggPSBEYXRlLCB5ID0gQ1BDLkFsbC4sIGdyb3VwID0gQXVkaWVuY2UsIGNvbG9yID0gQXVkaWVuY2UpKSArIGdlb21fc21vb3RoKHNlID0gRkFMU0UpICsgdGhlbWVfYncoKSsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAxLCBoanVzdCA9IDEpKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDEuMDYpDQpgYGANCg0KX19Db3N0IHBlciBBY3Rpb25fXzogVGhpcyBpcyBjYWxjdWxhdGVkIGJ5IHRoZSBhbW91bnQgc3BlbnQvbnVtYmVyIG9mIGFjdGlvbnMuIFRoaXMgc2VlbXMgd2F5IG9mZi4gV2UgcGF5IHdlbGwgYmVsb3cgdGhlIGJlbmNobWFyay4gDQoNCg0KYGBge3J9DQpnZ3Bsb3QoRkJCZW5jaCwgYWVzKHggPSBEYXRlLCB5ID0gLCBDUEEsIGdyb3VwID0gQXVkaWVuY2UsIGNvbG9yID0gQXVkaWVuY2UpKSArIGdlb21fc21vb3RoKHNlID0gRkFMU0UpICsgdGhlbWVfYncoKSsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAxLCBoanVzdCA9IDEpKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDcuODUpDQpgYGANCg0KDQpgYGB7cn0NCmdncGxvdChGQkJlbmNoLCBhZXMoeCA9IERhdGUsIHkgPSAsIFBlb3BsZVRha2luZ0FjdGlvbiwgZ3JvdXAgPSBBdWRpZW5jZSwgY29sb3IgPSBBdWRpZW5jZSkpICsgZ2VvbV9zbW9vdGgoc2UgPSBGQUxTRSkgKyB0aGVtZV9idygpKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDEsIGhqdXN0ID0gMSkpDQpgYGANCg0KYGBge3J9DQpkYXRhdGFibGUoRkIgJT4lIGdyb3VwX2J5KERhdGUsQWRTZXROYW1lLCBQbGF0Zm9ybSwgUGxhY2VtZW50KSAlPiUgc3VtbWFyaXNlKEltcCA9IHN1bShJbXByZXNzaW9ucyksIENsaWNrcyA9IHN1bShDbGlja3MuQWxsLiksIFVuaXF1ZUNsaWNrcyA9IHN1bShVbmlxdWVDbGlja3MuQWxsLiksIFVuaXF1ZUNUUiA9IHJvdW5kKG1lYW4oVW5pcXVlQ1RSLkFsbC4pLCAyKSwgQ1BDID0gcm91bmQobWVhbihDUEMuQWxsLiksIDIpLCBDUE0gPSByb3VuZChtZWFuKENQTSksIDIpKSwgb3B0aW9ucyA9IGxpc3QoDQogIGNvbHVtbkRlZnMgPSBsaXN0KGxpc3QoY2xhc3NOYW1lID0gJ2R0LWNlbnRlcicsIHRhcmdldHMgPSA1KSksDQogIHBhZ2VMZW5ndGggPSA1LA0KICBob3ZlciA9IFRSVUUsDQogIGxlbmd0aE1lbnUgPSBjKDUsIDEwLCAxNSwgMjApDQopKQ0KYGBgDQoNCk51bWJlciBvZiByZWNvcmRzDQoNCmBgYHtyfQ0KZ2dwbG90KEZCLCBhZXMoeCA9IEF1ZGllbmNlLCBmaWxsID0gUGxhdGZvcm0pKSsgZ2VvbV9iYXIoKSArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMSwgaGp1c3QgPSAxKSkgKyB0aGVtZV9idygpDQpgYGANCg0KV2hpY2ggYXVkaWVuY2UgY2xpY2tzIG1vc3QgcGVyIGFtb3V0IHNwZW50Pw0KDQpgYGB7cn0NCkNsaWNrc1RvU3BlbnQgPC0gRkIgJT4lIGdyb3VwX2J5KEF1ZGllbmNlLCBQbGF0Zm9ybSkgJT4lIHN1bW1hcmlzZShUb3RhbFNwZW50ID0gc3VtKEFtb3VudFNwZW50KSwgQ2xpY2tzID0gc3VtKENsaWNrcy5BbGwuKSwgTGlrZXMgPSBzdW0oTGlrZXMpKSAlPiUgbXV0YXRlKFJhdGlvQ2xpY2tUb1NwZW50ID0gcm91bmQoQ2xpY2tzL1RvdGFsU3BlbnQsIDIpKQ0KZGF0YXRhYmxlKENsaWNrc1RvU3BlbnQpDQpgYGANCg0KSGVyZSB3ZSBsb29rIGF0IG51bWJlciBvZiBjbGlja3MgYnkgYXVkaWVuY2UsIGJyb2tlbiBkb3duIGJ5IHBsYXRmb3JtLiANCg0KYGBge3J9DQpnZ3Bsb3QoQ2xpY2tzVG9TcGVudCwgYWVzKHg9QXVkaWVuY2UsIHk9Q2xpY2tzLCBmaWxsPVBsYXRmb3JtKSkgKw0KICAgIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2UoKSwgZmlsbCA9ICJkYXJrYmx1ZSIpICsgdGhlbWVfYncoKQ0KYGBgDQoNCkhlcmUgd2Ugc2VlIHRoZSByYXRpbyBvZiBjbGlja3MgdG8gdGhlIHRvdGFsIGFtb3VudCBzcGVudCBvbiBlYWNoIGF1ZGllbmNlLCBieSBlYWNoIHBsYXRmb3JtLiANCg0KYGBge3J9DQpnZ3Bsb3QoQ2xpY2tzVG9TcGVudCwgYWVzKHggPSBBdWRpZW5jZSwgeSA9IFJhdGlvQ2xpY2tUb1NwZW50LCBmaWxsPVBsYXRmb3JtKSkgKyANCiAgICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKCksIGZpbGwgPSAiZGFya2JsdWUiKSArIHRoZW1lX2J3KCkNCg0KYGBgDQoNCmBgYHtyfQ0KbmFtZXMoRkIpDQpzdW1tYXJ5KEZCKQ0KcmFuZ2UoRkIkTGlrZXMpDQpgYGANCg0KDQoqKlNFTS9BZFdvcmRzKioNCg0KYGBge3J9DQpBZFdvcmRzIDwtIHJlYWQuY3N2KCJBZHdvcmRzXzIwMTctMTAtMjQxLmNzdiIsIGhlYWRlciA9IFQsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGKQ0KQWR3b3JkcyA8LSBBZFdvcmRzICU+JSByZW5hbWUoRGF0ZSA9IERheSwgQ2FtcGFpZ25UeXBlID0gQ2FtcGFpZ24udHlwZSwgQWRHcm91cCA9IEFkLmdyb3VwLCBDUEMgPSBBdmcuLkNQQywgQ1BNID0gQXZnLi5DUE0sIEF2Z0Nvc3QgPSBBdmcuLkNvc3QsIEF2Z1Bvc2l0aW9uID0gQXZnLi5wb3NpdGlvbiwgQm91bmNlUmF0ZSA9IEJvdW5jZS5yYXRlLCBQYWdlc1Nlc3Npb24gPSBQYWdlcy4uLnNlc3Npb24sIEF2Z0R1cmF0aW9uID0gQXZnLi5zZXNzaW9uLmR1cmF0aW9uLi5zZWNvbmRzLiwgTmV3U2Vzc2lvbnMgPSBYLi5uZXcuc2Vzc2lvbnMpDQpBZHdvcmRzJERhdGUgPC0gYXMuRGF0ZShBZHdvcmRzJERhdGUsIGZvcm1hdCA9ICIlZC0lYi0leSIpDQoNCmRhdGF0YWJsZShBZHdvcmRzLCBvcHRpb25zID0gbGlzdCgNCiAgY29sdW1uRGVmcyA9IGxpc3QobGlzdChjbGFzc05hbWUgPSAnZHQtY2VudGVyJywgdGFyZ2V0cyA9IDUpKSwNCiAgcGFnZUxlbmd0aCA9IDUsDQogIGhvdmVyID0gVFJVRSwNCiAgbGVuZ3RoTWVudSA9IGMoNSwgMTAsIDE1LCAyMCkNCikpDQpgYGANClRoZSByZXBvcnQgaW4gVGFibGVhdSBsb29rcyBsaWtlIHRoaXM6DQoNCjxkaXYgc3R5bGU9IndpZHRoOjQwMHB4OyBoZWlnaHQ9MzAwcHgiPg0KIVtJbiB0YWJsZWF1XShBZHcucG5nKQ0KDQoqKlNlYXJjaCoqDQoNCmBgYHtyfQ0KQWR3b3JkcyAlPiUgZ3JvdXBfYnkoQ2FtcGFpZ25UeXBlKSAlPiUgc3VtbWFyaXNlKENsVGggPSByb3VuZChtZWFuKENUUiksIDIpKQ0KYGBgDQoNCg0KYGBge3J9DQpoZWFkKEFkd29yZHMpDQp1bmlxdWUoQWR3b3JkcyRDYW1wYWlnblR5cGUpDQpTZWFyY2ggPC0gQWR3b3JkcyAlPiUgZmlsdGVyKENhbXBhaWduVHlwZSA9PSAiU2VhcmNoIikNClNlYXJjaCA8LSBTZWFyY2ggJT4lIGdyb3VwX2J5KERhdGUsIENhbXBhaWduKSAlPiUgc3VtbWFyaXNlKENUUmF0ZSA9IHJvdW5kKG1lYW4oQ1RSKSwgMiksIEF2Z0NQQyA9IHJvdW5kKG1lYW4oQ1BDKSwgMikpDQpTZWFyY2gNCg0KDQpEaXNwbGF5IDwtIEFkd29yZHMgJT4lIGZpbHRlcihDYW1wYWlnblR5cGUgPT0gIkRpc3BsYXkiKQ0KRGlzcGxheSA8LSBEaXNwbGF5ICU+JSBncm91cF9ieShEYXRlLCBDYW1wYWlnbikgJT4lIHN1bW1hcmlzZShDVFJhdGUgPSByb3VuZChtZWFuKENUUiksIDIpLCBBdmdDUEMgPSByb3VuZChtZWFuKENQQyksIDIpKQ0KRGlzcGxheQ0KDQoNCg0KDQpTZWFyY2hEaXNwbGF5IDwtIEFkd29yZHMgJT4lIGZpbHRlcihDYW1wYWlnblR5cGUgPT0gIlNlYXJjaCBOZXR3b3JrIHcvIERpc3BsYXkgU2VsZWN0IikNClZpZGVvIDwtIEFkd29yZHMgJT4lIGZpbHRlcihDYW1wYWlnblR5cGUgPT0gIlZpZGVvIikNCmBgYA0KDQpGb3IgU2VhcmNoLCBvdXIgb3ZlcmFsbCBwZXJmb3JtYW5jZSBpcyBqdXN0IGFib3ZlIHRoZSBiZW5jaG1hcmsuIA0KDQpgYGB7cn0NCmdncGxvdChTZWFyY2gsIGFlcyh4ID0gRGF0ZSwgeSA9IENUUmF0ZSkpICsgZ2VvbV9zbW9vdGgoc2UgPSBGQUxTRSwgY29sb3IgPSAiZGFya2JsdWUiKSArIHRoZW1lX2J3KCkrIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMSwgaGp1c3QgPSAxKSkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAuMDIyKSArIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDAuMDc1KSkNCg0KYGBgDQoNClNlYXJjaCBDUEMNCg0KT3ZlcmFsbCwgQ1BDIGZvciBTZWFyY2gsIGNvc3RzIGxlc3MgdGhhbiB0aGUgYmVuY2htYXJrLCBob3dldmVyLCB3aGVuIGxvb2tlZCBhdCBieSBjYW1wYWlnbiwgdGhlIERvY3RvcmFsLCBUcmFuc2ZlciwgYW5kIEdyYWR1YXRlIGNhbXBhaWducyBjb3N0IG1vcmUgdGhhbiB0aGUgYmVuY2htYXJrLiBVbmRlcmdyYWQsIGNvdXJzZXMsIGFuZCBPbmxpbmUgY2FtYXBhaWducyBhcmUgbGVzcyBleHBlbnNpdmUuDQoNCmBgYHtyfQ0KZ2dwbG90KFNlYXJjaCwgYWVzKHggPSBEYXRlLCB5ID0gQXZnQ1BDKSkgKyBnZW9tX3Ntb290aChzZSA9IEZBTFNFKSArIHRoZW1lX2J3KCkrIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMSwgaGp1c3QgPSAxKSkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxLjc0KSArIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDIpKQ0KDQpTZWFyY2gNCmdncGxvdChTZWFyY2gsIGFlcyh4ID0gRGF0ZSwgeSA9IEF2Z0NQQywgZ3JvdXAgPSBDYW1wYWlnbiwgY29sb3IgPSBDYW1wYWlnbikpICsgZ2VvbV9zbW9vdGgoc2UgPSBGQUxTRSkgKyB0aGVtZV9idygpKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDEsIGhqdXN0ID0gMSkpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMS43NCkgKyBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCA0KSkNCmBgYA0KDQoNCldoZW4gd2UgYnJlYWtzIGRvd24gdGhlIGNhbXBhaWducywgd2Ugc2VlIHZhcnlpbmcgcGVyZm9ybWFuY2Ugb3ZlciB0aW1lLiANCg0KYGBge3J9DQpnZ3Bsb3QoU2VhcmNoLCBhZXMoeCA9IERhdGUsIHkgPSBDVFJhdGUsIGdyb3VwID0gQ2FtcGFpZ24sIGNvbG9yID0gQ2FtcGFpZ24pKSArIGdlb21fc21vb3RoKHNlID0gRkFMU0UpICsgdGhlbWVfYncoKSsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAxLCBoanVzdCA9IDEpKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IC4wMjIpICsgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgMC4wNzUpKQ0KDQpgYGANCkp1c3QgbG9va2luZyBhdCBDYW1wYWlnbiBDVFIsIE9ubGluZSwgR21haWwgVGVzdCwgYW5kIENvdXJzZXMgYXJlIHRoZSBsb3dlciBwZXJmb3JtZXJzIHVzaW5nIEFkV29yZHMgU2VhcmNoLiANCg0KYGBge3J9DQpTZWFyY2gxIDwtIFNlYXJjaCAlPiUgZ3JvdXBfYnkoQ2FtcGFpZ24pICU+JSBzdW1tYXJpc2UoQ1RSID0gcm91bmQobWVhbihDVFJhdGUpLCAyKSkNCg0KZ2dwbG90KFNlYXJjaDEsIGFlcyh4ID0gQ2FtcGFpZ24sIHkgPSBDVFIpKSArIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gImRhcmtibHVlIikgKyB0aGVtZV9idygpKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDEsIGhqdXN0ID0gMSkpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gLjAyMikgDQpgYGANCg0KKipEaXNwbGF5KioNCg0KQmVuY2htYXJrIGlzIDAuMjINCg0KYGBge3J9DQoNCmBgYA0KDQpgYGB7cn0NCg0KYGBgDQoNCkluIHRlcm1zIG9mIERpc3BsYXksIHdlIGFyZSBwZXJmb3JtaW5nIHdlbGwgaW4gQWR3b3Jkcy4gDQoNCmBgYHtyfQ0KRGlzcGxheTJDUEMgPC0gRGlzcGxheSAlPiUgZ3JvdXBfYnkoQ2FtcGFpZ24pICU+JSBzdW1tYXJpc2UoQ1BDID0gcm91bmQobWVhbihBdmdDUEMpLCAyKSkNCkRpc3BsYXkyQ1BDDQpEaXNwbGF5MUNUUg0KRGlzcGxheTFDVFIgPC0gRGlzcGxheSAlPiUgZ3JvdXBfYnkoQ2FtcGFpZ24pICU+JSBzdW1tYXJpc2UoQ1RSID0gcm91bmQobWVhbihDVFJhdGUpLCAyKSkNCmhlYWQoRGlzcGxheTFDVFIpDQoNCmdncGxvdChEaXNwbGF5MUNUUiwgYWVzKHggPSBDYW1wYWlnbiwgeSA9IENUUikpICsgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAiZGFya2JsdWUiKSArIHRoZW1lX2J3KCkrIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMSwgaGp1c3QgPSAxKSkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAuMDAyMikgDQpgYGANCkRpc3BsYXkNCg0KQWRXb3JkcyBDUEMNCg0KYGBge3J9DQoNCmhlYWQoRGlzcGxheSkNCmdncGxvdChEaXNwbGF5LCBhZXMoeCA9IERhdGUsIHkgPSBBdmdDUEMpKSArIGdlb21fc21vb3RoKHNlID0gRkFMU0UpICsgdGhlbWVfYncoKSsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAxLCBoanVzdCA9IDEpKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IC40NikgKyBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCAyKSkNCg0KU2VhcmNoDQpnZ3Bsb3QoRGlzcGxheSwgYWVzKHggPSBEYXRlLCB5ID0gQXZnQ1BDLCBncm91cCA9IENhbXBhaWduLCBjb2xvciA9IENhbXBhaWduKSkgKyBnZW9tX3Ntb290aChzZSA9IEZBTFNFKSArIHRoZW1lX2J3KCkrIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMSwgaGp1c3QgPSAxKSkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLjQ2KSArIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDQpKQ0KYGBgDQpgYGB7cn0NCmRhdGF0YWJsZShBZHdvcmRzLCBvcHRpb25zID0gbGlzdCgNCiAgY29sdW1uRGVmcyA9IGxpc3QobGlzdChjbGFzc05hbWUgPSAnZHQtY2VudGVyJywgdGFyZ2V0cyA9IDUpKSwNCiAgcGFnZUxlbmd0aCA9IDUsDQogIGhvdmVyID0gVFJVRSwNCiAgbGVuZ3RoTWVudSA9IGMoNSwgMTAsIDE1LCAyMCkNCikpDQpgYGANCmBgYHtyfQ0KbGlicmFyeShjaHJvbikNCkdBIDwtIHJlYWQuY3N2KCJHb29nbGVBbmFseXRpY3NfMjAxNy0xMC0yNC5jc3YiLCBoZWFkZXIgPSBULCBzdHJpbmdzQXNGYWN0b3JzID0gRikNCkdBIDwtIEdBICU+JSBtdXRhdGUoTWludXRlc09uUGFnZSA9IHJvdW5kKE1pbnV0ZXNPblBhZ2UsIDIpKQ0KaGVhZChHQSkNCiNjb252ZXJ0IHRpbWUsIGRpZG4ndCB3b3JrDQojY29udmVydCBkYXRlDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCkdBJERhdGUgPC0geW1kKEdBJERhdGUpDQoNCmBgYA0KYGBge3J9DQpnZ3Bsb3QoR0EsIGFlcyh4ID0gRGF0ZSwgeSA9IFVuaXF1ZS5QYWdldmlld3MpKSsgZ2VvbV9zbW9vdGgoc2UgPSBGQUxTRSkgKyB0aGVtZV9idygpDQoNCg0KR0FHcm91cCA8LSBHQSAlPiUgZ3JvdXBfYnkoRGF0ZSwgU291cmNlKSAlPiUgc3VtbWFyaXNlKEF2ZS5QYWdlLnZpZXdzRGF5ID0gbWVhbihVbmlxdWUuUGFnZXZpZXdzKSwgQXZnQm91bmNlcyA9IG1lYW4oQm91bmNlcykgLCBib3VuY2VzVG9WaWV3cyA9IEF2ZS5QYWdlLnZpZXdzRGF5L0F2Z0JvdW5jZXMpDQpnZ3Bsb3QoR0FHcm91cCwgYWVzKHggPSBEYXRlLCB5ID0gYm91bmNlc1RvVmlld3MsIGdyb3VwID0gU291cmNlLCBjb2xvciA9IFNvdXJjZSkpICsgZ2VvbV9saW5lKCkgKyB0aGVtZV9idygpKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDEsIGhqdXN0ID0gMSkpDQpgYGANCg0KDQoNCg0KDQoNCg0KDQoNCmBgYHtyLCBlY2hvPVRSVUV9DQpycGl2b3RUYWJsZShBZHdvcmRzICxjKCJDYW1wYWlnbiIsIkNhbXBhaWduVHlwZSIsIkNsaWNrcyIsIkltcHJlc3Npb25zIiwgIkNUUiIsICJDVEMiLCAiQ1BNIikpDQpgYGANCg0K