Overview

This work was a potential project idea that I entertained for my final ECON 2325 (Comparative Historical Economic Development) paper. I wanted to use datasets that were new to me and think about the evolution of attitudes in American society. One paper that had struck me during the class was “Persecution Perpetuated” by Voightlander + Voth (2012) on anti-semitism in Germany. They showed local continuity in Anti-semitic beliefs over 600 years within fine levels of geography. (Publishable due to micro-level geography and hundreds of years – the span of time and level of geographic detail made it interesting.) Basic idea: local historical sentiment predicts local modern sentiment to an impressive degree.

I wanted to do a similar thing for racial attitudes in the US. Do historical measures of racial animus predict modern measures of racial animus? We’d expect yes and it wouldn’t be too surprising if we found positive evidence. As my professor said, this wouldn’t move peoples’ priors (and so that’s why I didn’t expand on this project beyond the work in this notebook). But, even though this didn’t evolve into a final project, let’s explore some historical data and modern data on racial “animus.”

I use historical geographic variation in KKK locations (1915-1940) to see if that predicts racially charged google searches in 2004-2007.

Data

Historical (explanatory):

Modern (dependant):

Plot google search data

The hard part here is that I am mapping rates by DMA rather than by state, which would be simpler and there would be ample examples of doing that online. I try out code found here. Note: json files found here.

Some of code chunk below is via the StackOverflow link. It was altered slightly to include new merged data on racial animus.

library(sp)
library(rgdal)
library(maptools)
library(rgeos)
library(ggplot2)
library(ggalt)
library(ggthemes)
library(jsonlite)
library(purrr)
library(viridis)
library(scales)
neil <- readOGR("geo/nielsentopo.json", "nielsen_dma", stringsAsFactors=FALSE, 
                verbose=FALSE)
ne<-neil
# there are some techincal problems with the polygon that D3 glosses over
neil <- SpatialPolygonsDataFrame(gBuffer(neil, byid=TRUE, width=0),
                                  data=neil@data)
neil_map <- fortify(neil, region="id")
tv <- fromJSON("geo/tv.json", flatten=TRUE)
tv_df <- map_df(tv, as.data.frame, stringsAsFactors=FALSE, .id="id")
colnames(tv_df) <- c("id", "rank", "dma", "tv_homes_count", "pct", "dma_code")
tv_df$pct <- as.numeric(tv_df$pct)/100
write.csv(tv_df, 'tv-df.csv')
# manually merged ssd data on racial animus with DMA's in tv-df
tvnew<-read.csv('tv-df1.csv')
# drop if animus is NA
gg <- ggplot()
gg <- gg + geom_map(data=neil_map, map=neil_map,
                    aes(x=long, y=lat, map_id=id),
                    color="grey", size=0.08, fill=NA)
gg <- gg + geom_map(data=tvnew, map=neil_map,
                    aes(fill=animus, map_id=id),
                    color="grey", size=0.08)
gg <- gg + scale_fill_viridis(limits = c(25, 155), name = "")
gg <- gg + theme_map(base_size=12, base_family="Palatino")
gg <- gg + theme(legend.position="bottom") + ggtitle("Racially Charged Google Search Rate (2004-2007)", subtitle = "Data via Seth Stephens-Davidowitz | Visualization via Alex Albright") + labs(caption="Rates are by DMA (media market) region and acquired from Stephens-Davidowitz (2014).\nGray areas mean no data. Hawaii and Alaska are excluded from the visualization.")
gg <- gg + theme(legend.key.width=unit(2, "cm")) + theme(plot.title=element_text(size=20, face="bold"))
gg

ggsave("animusmap.png", width=12, height=8, dpi=900)

Plot klavern data

KKK data here. I fixed some formatting manually in the klaverns.csv (some columns were off).

klaverns<-read.csv('klaverns.csv')
klaverns$lat<-as.numeric(klaverns$lat)
klaverns$long<-as.numeric(klaverns$long)

Plot lat/long on a map… only keep those within map territory.

# long ranges from -125 to -66, lat ranges from 24.5 to 49.5
klaverns1 <- subset(klaverns, klaverns$lat >= 24.54424 & klaverns$lat <= 49.38436 & klaverns$long >= -124.733 & klaverns$long <= -66.94932)

Plot it!

Plot with dots

gg1 <- ggplot()
gg1 <- gg1 + geom_map(data=neil_map, map=neil_map,
                    aes(x=long, y=lat, map_id=id),
                    color="black", size=0.08, fill=NA)
gg1 <- gg1 + geom_point(data = klaverns1, aes(x = long, y = lat), color = "red", size = .5) 
gg1 <- gg1 + theme_map(base_size=12, base_family="Palatino")
gg1 <- gg1 + ggtitle("Klavern Locations (1915-1940)", subtitle = "Data via VCU Libraries | Visualization via Alex Albright") + labs(caption="Klavern locations are represented by red dots. Location data is from VCU's Mapping the Klan project.\nMap shows DMA (media market) regions. Hawaii and Alaska are excluded from the visualization.")
gg1 <- gg1 + theme(legend.key.width=unit(2, "cm")) + theme(plot.title=element_text(size=20, face="bold"))
gg1

ggsave("klavernmap_a.png", width=12, height=8, dpi=900)

Plot number of klaverns by DMA

Used steps from this tutorial!

# We only need the columns with the latitude and longitude
coords <- klaverns1[c("long", "lat")]
# Making sure we are working with rows that don't have any blanks
coords <- coords[complete.cases(coords),]
library(sp)
# Letting R know that these are specifically spatial coordinates
sp <- SpatialPoints(coords)
by_dma <- over(sp, neil)
library(dplyr)
by_dma <- by_dma %>%
  group_by(dma) %>%
  summarise(total=n())
by_dma <- by_dma[!is.na(by_dma$dma),]
colnames(by_dma) <- c("id", "total")
by_dma<-merge(by_dma, tvnew, all=T)
# set as 0 if NA
by_dma$total[is.na(by_dma$total)] <- 0

Now, plot it!

gg3 <- ggplot()
gg3 <- gg3 + geom_map(data=neil_map, map=neil_map,
                    aes(x=long, y=lat, map_id=id),
                    color="grey", size=0.08, fill=NA)
gg3 <- gg3 + geom_map(data=by_dma, map=neil_map,
                    aes(fill=total, map_id=id),
                    color="grey", size=0.08)
gg3 <- gg3 + scale_fill_viridis(limits = c(0, 82), name = "")
gg3 <- gg3 + theme_map(base_size=12, base_family="Palatino")
gg3 <- gg3 + theme(legend.position="bottom") + ggtitle("Number of Klaverns (1915-1940)", subtitle = "Data via VCU Libraries | Visualization via Alex Albright") + labs(caption="Color depicts number of Klavern locations per DMA area. Location data is from VCU's Mapping the Klan project.\nMap shows DMA (media market) regions. Hawaii and Alaska are excluded from the visualization.")
gg3 <- gg3 + theme(legend.key.width=unit(2, "cm")) + theme(plot.title=element_text(size=20, face="bold"))
gg3

ggsave("klavernmap_b.png", width=12, height=8, dpi=900)

Need to figure out population figures… we want to look at klaverns/capita as the metric of interest. (Care about size of the area…bigger places have more klaverns)

Plot klaverns/million by DMA

Get pop figures for counties and then use county to DMA crosswalk. Crosswalk should be here. get population county data and aggregate to DMA. Calculate klaverns/million people.

library(foreign); library(stringr)
dmac<-read.dta('ICPSR_22720_2/DS0003/22720-0003-Data.dta')
#remove AK cause it's a mess later... basically no counties in DMAs...
dmac<-subset(dmac, dmac$STATE!="AK")
dmac$county<-str_trim(as.character(dmac$COUNTY))
dmac$county<-tolower(dmac$county)
dmac$state<-dmac$STATE
dmac<-dmac[,c("state", "county", "DMAINDEX")]
dmac$county<-gsub("\\.","", dmac$county) 
dmac$county<-gsub("'","", dmac$county) 
dmac$county<-gsub(" parish","", dmac$county)
dmac$county<-gsub(" borough","", dmac$county)
dmac$county<-gsub(" ","", dmac$county)

Merge this with census 1920 data on counties.

# get 1920 population data
cdata<-read.csv('countydata.csv')
cdata<-cdata[,c("STATE","COUNTY","epop1920")]
cdata$state <- state.abb[match(cdata$STATE, state.name)]
cdata$county<-tolower(str_trim(cdata$COUNTY))
cdata$state[cdata$county == "district of columbia"] <- "DC"
cdata$county[cdata$county == "miami-dade"] <- "dade"
cdata<-cdata[,c(3:5)]
cdata$county<-gsub("'","", cdata$county) 
cdata$county<-gsub(" ","", cdata$county)
dmac1<-merge(cdata, dmac, by=c("state", "county"), all=F)
#remove all of alaska
# exclude dma 67 (lost two counties in it... didnt have pop data)
dmac1<-subset(dmac1, dmac1$DMAINDEX!=67)
# generate total population by dma
dmac2<-aggregate(dmac1$epop1920, by=list(dmac1$DMAINDEX), FUN=sum)
dmac2$pop<-dmac2$x
dmac2$rank <- dmac2$Group.1
dmac2<-dmac2[,c(3:4)]

Bring back in by_dma

#bring back with other data sources
by_dma<-by_dma[,c("total", "rank", "id", "dma", "animus")]
by_dma$klaverns<-by_dma$total
by_dma<-by_dma[,c(2:6)]
klavern_dma<-merge(by_dma, dmac2, by="rank", all=T)
klavern_dma$kpml<-log((klavern_dma$klaverns/klavern_dma$pop)*1000000)
klavern_dma$kpm<-(klavern_dma$klaverns/klavern_dma$pop)*1000000
klavern_dma$kpml[klavern_dma$klaverns == 0] <- 0

Plot it! Note: Variation in klaverns/million is so large that if you use the raw rate then visually you can’t see the variation… The use of log (as done below) allows the colors to adequately display geographic variation.

gg4 <- ggplot()
gg4 <- gg4 + geom_map(data=neil_map, map=neil_map,
                    aes(x=long, y=lat, map_id=id),
                    color="grey", size=0.08, fill=NA)
gg4 <- gg4 + geom_map(data=klavern_dma, map=neil_map,
                    aes(fill=kpml, map_id=id),
                    color="grey", size=0.08)
gg4 <- gg4 + scale_fill_viridis(limits = c(0, 8), name = "")
gg4 <- gg4 + theme_map(base_size=12, base_family="Palatino")
gg4 <- gg4 + theme(legend.position="bottom") + ggtitle("Log of Klaverns per Million (1915-1940)", subtitle = "Data via VCU Libraries | Visualization via Alex Albright") + labs(caption="Color depicts log of Klaverns per 1 million residents for each DMA area. Location data is from VCU's Mapping the Klan project.\nMap shows DMA (media market) regions. Population data are from 1920 at the county level and aggregated up to the DMA level.\nSet log(Klaverns/Million)=0 if no klaverns. Gray areas mean no data. Hawaii and Alaska are excluded from the visualization.")
gg4 <- gg4 + theme(legend.key.width=unit(2, "cm")) + theme(plot.title=element_text(size=20, face="bold"))
gg4

ggsave("klavernmap_c.png", width=12, height=8, dpi=900)

Create final graphic

Combine two choropleths (the google one and the log(klaverns/million)) into one graphic

library(grid); library(gridExtra)

Attaching package: ‘gridExtra’

The following object is masked from ‘package:dplyr’:

    combine
pdf("map_both.pdf", width = 9.5, height = 14)
grid.arrange(gg4, gg, ncol=1)
dev.off()
null device 
          1 

Predicting modern sentiment with historical sentiment

Let’s look at the relationship between the two visually first.

klavern_dma0 <- klavern_dma[complete.cases(klavern_dma),]
# 190 observations
# Plot animus and klaverns per million.
qplot(klavern_dma0$animus, klavern_dma0$kpm)

qplot(klavern_dma0$animus, klavern_dma0$kpml)

The distribution of kpm is badly skewed, making a nonlinear relationship between animus and kpm. Can counter heteroskedasticity via transforming kpm to its log. (See second plot.)

Get LaTeX code for the linear-log regression. (Hey, stargazer is great!)

reg <- lm(animus ~ kpml, data=klavern_dma0)
library(stargazer)

Please cite as: 

 Hlavac, Marek (2015). stargazer: Well-Formatted Regression and Summary Statistics Tables.
 R package version 5.2. http://CRAN.R-project.org/package=stargazer 
star<-stargazer(reg, style="qje", 
          title            = "Predicting modern animus with past animus",
          covariate.labels = c("Log(Klaverns/Million)"), notes.append = FALSE, notes.align = "l",
          dep.var.labels   = "Racially Charged Google Search Rate", omit.stat=c("f", "ser"), notes = "To replace."
          )

% Table created by stargazer v.5.2 by Marek Hlavac, Harvard University. E-mail: hlavac at fas.harvard.edu
unknown timezone 'zone/tz/2018c.1.0/zoneinfo/America/New_York'
% Date and time: Mon, Jul 23, 2018 - 13:30:20
\begin{table}[!htbp] \centering 
  \caption{Predicting modern animus with past animus} 
  \label{} 
\begin{tabular}{@{\extracolsep{5pt}}lc} 
\\[-1.8ex]\hline 
\hline \\[-1.8ex] 
\\[-1.8ex] & Racially Charged Google Search Rate \\ 
\hline \\[-1.8ex] 
 Log(Klaverns/Million) & 2.645$^{***}$ \\ 
  & (0.980) \\ 
  & \\ 
 Constant & 55.343$^{***}$ \\ 
  & (3.040) \\ 
  & \\ 
\textit{N} & 190 \\ 
R$^{2}$ & 0.037 \\ 
Adjusted R$^{2}$ & 0.032 \\ 
\hline 
\hline \\[-1.8ex] 
\textit{Notes:} & \multicolumn{1}{l}{To replace.} \\ 
\end{tabular} 
\end{table} 
note.latex <- "\\multicolumn{2}{l} {\\parbox[t]{15cm}{ \\textit{Notes:} 190 DMA areas in regression based on data availability.\\Population for counties from 1920 summed up to comprise populations for DMAs.\\ $^{***}$Significant at the 1% level, $^{**}$Significant at the 5% level, $^{*}$Significant at the 10% level.}} \\\\"
star[grepl("Note",star)] <- note.latex
cat (star, sep = "\n")

% Table created by stargazer v.5.2 by Marek Hlavac, Harvard University. E-mail: hlavac at fas.harvard.edu
% Date and time: Mon, Jul 23, 2018 - 13:30:21
\begin{table}[!htbp] \centering 
  \caption{Predicting modern animus with past animus} 
  \label{} 
\begin{tabular}{@{\extracolsep{5pt}}lc} 
\\[-1.8ex]\hline 
\hline \\[-1.8ex] 
\\[-1.8ex] & Racially Charged Google Search Rate \\ 
\hline \\[-1.8ex] 
 Log(Klaverns/Million) & 2.645$^{***}$ \\ 
  & (0.980) \\ 
  & \\ 
 Constant & 55.343$^{***}$ \\ 
  & (3.040) \\ 
  & \\ 
\textit{N} & 190 \\ 
R$^{2}$ & 0.037 \\ 
Adjusted R$^{2}$ & 0.032 \\ 
\hline 
\hline \\[-1.8ex] 
\multicolumn{2}{l} {\parbox[t]{15cm}{ \textit{Notes:} 190 DMA areas in regression based on data availability.\Population for counties from 1920 summed up to comprise populations for DMAs.\ $^{***}$Significant at the 1% level, $^{**}$Significant at the 5% level, $^{*}$Significant at the 10% level.}} \\
\end{tabular} 
\end{table} 

Sure, coefficient on indepedent variable is statistically significant… but variation in log(klaverns/million) only explains 3-4% of the variation in google search rates. Interpretation: 1% increase in klaverns/million is associated with a 2.645/100=0.02645 unit increase in racially charged google search rate. That is tiny considering that the rates range from 25-155. This is not economically meaningful whatsoever.

Not a meaningful predictor (as V&V got for in paper). Could be for a lot of reasons…

  1. KKK data not complete.
  2. KKK data is locations… not number of members! (Very important.) I suspect number of KKK members in a DMA region is more likely to be a useful predictor of animus visible via google search.
  3. How do we really interpret google data? Does it make any sense to expect language in searches to reveal historical locations of institutions?

That’s all on this idea. Onto the next one!

LS0tCnRpdGxlOiAiVGVzdGluZyBmb3IgTG9jYWwgQ29udGludWl0eSBpbiBSYWNpYWwgQW5pbXVzIgphdXRob3I6IEFsZXggQWxicmlnaHQKZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJUIgJWQsICVZJylgIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojIE92ZXJ2aWV3CgpUaGlzIHdvcmsgd2FzIGEgcG90ZW50aWFsIHByb2plY3QgaWRlYSB0aGF0IEkgZW50ZXJ0YWluZWQgZm9yIG15IGZpbmFsIEVDT04gMjMyNSAoQ29tcGFyYXRpdmUgSGlzdG9yaWNhbCBFY29ub21pYyBEZXZlbG9wbWVudCkgcGFwZXIuIEkgd2FudGVkIHRvIHVzZSBkYXRhc2V0cyB0aGF0IHdlcmUgbmV3IHRvIG1lIGFuZCB0aGluayBhYm91dCB0aGUgZXZvbHV0aW9uIG9mIGF0dGl0dWRlcyBpbiBBbWVyaWNhbiBzb2NpZXR5LiBPbmUgcGFwZXIgdGhhdCBoYWQgc3RydWNrIG1lIGR1cmluZyB0aGUgY2xhc3Mgd2FzICJQZXJzZWN1dGlvbiBQZXJwZXR1YXRlZCIgYnkgVm9pZ2h0bGFuZGVyICsgVm90aCAoMjAxMikgb24gYW50aS1zZW1pdGlzbSBpbiBHZXJtYW55LiBUaGV5IHNob3dlZCBsb2NhbCBjb250aW51aXR5IGluIEFudGktc2VtaXRpYyBiZWxpZWZzIG92ZXIgNjAwIHllYXJzIHdpdGhpbiBmaW5lIGxldmVscyBvZiBnZW9ncmFwaHkuIChQdWJsaXNoYWJsZSBkdWUgdG8gbWljcm8tbGV2ZWwgZ2VvZ3JhcGh5IGFuZCBodW5kcmVkcyBvZiB5ZWFycyAtLSB0aGUgc3BhbiBvZiB0aW1lIGFuZCBsZXZlbCBvZiBnZW9ncmFwaGljIGRldGFpbCBtYWRlIGl0IGludGVyZXN0aW5nLikgQmFzaWMgaWRlYTogbG9jYWwgaGlzdG9yaWNhbCBzZW50aW1lbnQgcHJlZGljdHMgbG9jYWwgbW9kZXJuIHNlbnRpbWVudCB0byBhbiBpbXByZXNzaXZlIGRlZ3JlZS4KCkkgd2FudGVkIHRvIGRvIGEgc2ltaWxhciB0aGluZyBmb3IgcmFjaWFsIGF0dGl0dWRlcyBpbiB0aGUgVVMuIERvIGhpc3RvcmljYWwgbWVhc3VyZXMgb2YgcmFjaWFsIGFuaW11cyBwcmVkaWN0IG1vZGVybiBtZWFzdXJlcyBvZiByYWNpYWwgYW5pbXVzPyBXZSdkIGV4cGVjdCB5ZXMgYW5kIGl0IHdvdWxkbid0IGJlIHRvbyBzdXJwcmlzaW5nIGlmIHdlIGZvdW5kIHBvc2l0aXZlIGV2aWRlbmNlLiBBcyBteSBwcm9mZXNzb3Igc2FpZCwgdGhpcyB3b3VsZG4ndCBtb3ZlIHBlb3BsZXMnIHByaW9ycyAoYW5kIHNvIHRoYXQncyB3aHkgSSBkaWRuJ3QgZXhwYW5kIG9uIHRoaXMgcHJvamVjdCBiZXlvbmQgdGhlIHdvcmsgaW4gdGhpcyBub3RlYm9vaykuIEJ1dCwgZXZlbiB0aG91Z2ggdGhpcyBkaWRuJ3QgZXZvbHZlIGludG8gYSBmaW5hbCBwcm9qZWN0LCBsZXQncyBleHBsb3JlIHNvbWUgaGlzdG9yaWNhbCBkYXRhIGFuZCBtb2Rlcm4gZGF0YSBvbiByYWNpYWwgImFuaW11cy4iCgpJIHVzZSBoaXN0b3JpY2FsIGdlb2dyYXBoaWMgdmFyaWF0aW9uIGluIEtLSyBsb2NhdGlvbnMgKDE5MTUtMTk0MCkgdG8gc2VlIGlmIHRoYXQgcHJlZGljdHMgcmFjaWFsbHkgY2hhcmdlZCBnb29nbGUgc2VhcmNoZXMgaW4gMjAwNC0yMDA3LiAKCiMgRGF0YQoKSGlzdG9yaWNhbCAoZXhwbGFuYXRvcnkpOgoKLSBLS0sgZGF0YSAobG9uZy9sYXQpIGlzIGZyb20gVkNVICJNYXBwaW5nIHRoZSBTZWNvbmQgS3UgS2x1eCBLbGFuLCAxOTE5LTE5NDAiIFByb2plY3QuIEF2YWlsYWJsZSBmb3IgZG93bmxvYWQgW2hlcmUuXShodHRwOi8vc2Nob2xhcnNjb21wYXNzLnZjdS5lZHUvaGlzdF9kYXRhLzEvKSBNb3JlIFtoZXJlXShodHRwczovL25ld3MudmN1LmVkdS9hcnRpY2xlL0RpZ2l0YWxfbWFwX3Nob3dzX3NwcmVhZF9vZl9LS0tfYWNyb3NzX1VuaXRlZF9TdGF0ZXNfbGlrZV9hX2NvbnRhZ2lvbikKQ2F2ZWF0czogKDEpIE5vIGRhdGEgb24gbnVtYmVyIG9mIG1lbWJlcnMsIGp1c3QgZGF0YSBvbiBsb2NhdGlvbnMuICgyKSBOb3QgbmVjZXNzYXJpbHkgYSBmdWxsIGRhdGFzZXQuIERvbid0IGtub3cgbG9jYXRpb24gb2YgYWxsIGtsYXZlcm5zLgoKTW9kZXJuIChkZXBlbmRhbnQpOgoKLSBHb29nbGUgc2VhcmNoIGRhdGEgb24gcmFjaWFsbHkgY2hhcmdlZCBzZWFyY2ggcmF0ZXMgZm9yIERNQSBhcmVhcyAoMjAwNC0yMDA3KSBpcyBmcm9tIFNldGggU3RlcGhlbnMtRGF2aWRvd2l0ei4gQXZhaWxhYmxlIG9uIGhpcyB3ZWJzaXRlIFtoZXJlLl0oaHR0cDovL3NldGhzZC5jb20vcmVzZWFyY2gvKSAobmljZSBiZWNhdXNlIGRvZXNuJ3Qgc3VmZmVyIGZyb20gcmVwb3J0aW5nIGlzc3VlcykKCiMgUGxvdCBnb29nbGUgc2VhcmNoIGRhdGEKClRoZSBoYXJkIHBhcnQgaGVyZSBpcyB0aGF0IEkgYW0gbWFwcGluZyByYXRlcyBieSBETUEgcmF0aGVyIHRoYW4gYnkgc3RhdGUsIHdoaWNoIHdvdWxkIGJlIHNpbXBsZXIgYW5kIHRoZXJlIHdvdWxkIGJlIGFtcGxlIGV4YW1wbGVzIG9mIGRvaW5nIHRoYXQgb25saW5lLiBJIHRyeSBvdXQgY29kZSBmb3VuZCBbaGVyZV0oaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzU0OTM1ODUvci1pbXBvcnQtaHRtbC1qc29uLW1hcC1maWxlLXRvLXVzZS1mb3ItaGVhdG1hcCkuIE5vdGU6IGpzb24gZmlsZXMgZm91bmQgW2hlcmUuXShodHRwczovL2dpc3QuZ2l0aHViLmNvbS9zaW16b3UvNjQ1OTg4OSNmaWxlLW5pZWxzZW50b3BvLWpzb24pCgpTb21lIG9mIGNvZGUgY2h1bmsgYmVsb3cgaXMgdmlhIHRoZSBTdGFja092ZXJmbG93IGxpbmsuIEl0IHdhcyBhbHRlcmVkIHNsaWdodGx5IHRvIGluY2x1ZGUgbmV3IG1lcmdlZCBkYXRhIG9uIHJhY2lhbCBhbmltdXMuCgpgYGB7ciwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShzcCkKbGlicmFyeShyZ2RhbCkKbGlicmFyeShtYXB0b29scykKbGlicmFyeShyZ2VvcykKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdnYWx0KQpsaWJyYXJ5KGdndGhlbWVzKQpsaWJyYXJ5KGpzb25saXRlKQpsaWJyYXJ5KHB1cnJyKQpsaWJyYXJ5KHZpcmlkaXMpCmxpYnJhcnkoc2NhbGVzKQoKbmVpbCA8LSByZWFkT0dSKCJnZW8vbmllbHNlbnRvcG8uanNvbiIsICJuaWVsc2VuX2RtYSIsIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UsIAogICAgICAgICAgICAgICAgdmVyYm9zZT1GQUxTRSkKbmU8LW5laWwKIyB0aGVyZSBhcmUgc29tZSB0ZWNoaW5jYWwgcHJvYmxlbXMgd2l0aCB0aGUgcG9seWdvbiB0aGF0IEQzIGdsb3NzZXMgb3ZlcgpuZWlsIDwtIFNwYXRpYWxQb2x5Z29uc0RhdGFGcmFtZShnQnVmZmVyKG5laWwsIGJ5aWQ9VFJVRSwgd2lkdGg9MCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPW5laWxAZGF0YSkKbmVpbF9tYXAgPC0gZm9ydGlmeShuZWlsLCByZWdpb249ImlkIikKCnR2IDwtIGZyb21KU09OKCJnZW8vdHYuanNvbiIsIGZsYXR0ZW49VFJVRSkKdHZfZGYgPC0gbWFwX2RmKHR2LCBhcy5kYXRhLmZyYW1lLCBzdHJpbmdzQXNGYWN0b3JzPUZBTFNFLCAuaWQ9ImlkIikKY29sbmFtZXModHZfZGYpIDwtIGMoImlkIiwgInJhbmsiLCAiZG1hIiwgInR2X2hvbWVzX2NvdW50IiwgInBjdCIsICJkbWFfY29kZSIpCnR2X2RmJHBjdCA8LSBhcy5udW1lcmljKHR2X2RmJHBjdCkvMTAwCgp3cml0ZS5jc3YodHZfZGYsICd0di1kZi5jc3YnKQojIG1hbnVhbGx5IG1lcmdlZCBzc2QgZGF0YSBvbiByYWNpYWwgYW5pbXVzIHdpdGggRE1BJ3MgaW4gdHYtZGYKdHZuZXc8LXJlYWQuY3N2KCd0di1kZjEuY3N2JykKIyBkcm9wIGlmIGFuaW11cyBpcyBOQQoKZ2cgPC0gZ2dwbG90KCkKZ2cgPC0gZ2cgKyBnZW9tX21hcChkYXRhPW5laWxfbWFwLCBtYXA9bmVpbF9tYXAsCiAgICAgICAgICAgICAgICAgICAgYWVzKHg9bG9uZywgeT1sYXQsIG1hcF9pZD1pZCksCiAgICAgICAgICAgICAgICAgICAgY29sb3I9ImdyZXkiLCBzaXplPTAuMDgsIGZpbGw9TkEpCmdnIDwtIGdnICsgZ2VvbV9tYXAoZGF0YT10dm5ldywgbWFwPW5laWxfbWFwLAogICAgICAgICAgICAgICAgICAgIGFlcyhmaWxsPWFuaW11cywgbWFwX2lkPWlkKSwKICAgICAgICAgICAgICAgICAgICBjb2xvcj0iZ3JleSIsIHNpemU9MC4wOCkKZ2cgPC0gZ2cgKyBzY2FsZV9maWxsX3ZpcmlkaXMobGltaXRzID0gYygyNSwgMTU1KSwgbmFtZSA9ICIiKQpnZyA8LSBnZyArIHRoZW1lX21hcChiYXNlX3NpemU9MTIsIGJhc2VfZmFtaWx5PSJQYWxhdGlubyIpCmdnIDwtIGdnICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJib3R0b20iKSArIGdndGl0bGUoIlJhY2lhbGx5IENoYXJnZWQgR29vZ2xlIFNlYXJjaCBSYXRlICgyMDA0LTIwMDcpIiwgc3VidGl0bGUgPSAiRGF0YSB2aWEgU2V0aCBTdGVwaGVucy1EYXZpZG93aXR6IHwgVmlzdWFsaXphdGlvbiB2aWEgQWxleCBBbGJyaWdodCIpICsgbGFicyhjYXB0aW9uPSJSYXRlcyBhcmUgYnkgRE1BIChtZWRpYSBtYXJrZXQpIHJlZ2lvbiBhbmQgYWNxdWlyZWQgZnJvbSBTdGVwaGVucy1EYXZpZG93aXR6ICgyMDE0KS5cbkdyYXkgYXJlYXMgbWVhbiBubyBkYXRhLiBIYXdhaWkgYW5kIEFsYXNrYSBhcmUgZXhjbHVkZWQgZnJvbSB0aGUgdmlzdWFsaXphdGlvbi4iKQpnZyA8LSBnZyArIHRoZW1lKGxlZ2VuZC5rZXkud2lkdGg9dW5pdCgyLCAiY20iKSkgKyB0aGVtZShwbG90LnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTIwLCBmYWNlPSJib2xkIikpCmdnCmdnc2F2ZSgiYW5pbXVzbWFwLnBuZyIsIHdpZHRoPTEyLCBoZWlnaHQ9OCwgZHBpPTkwMCkKYGBgCgojIFBsb3Qga2xhdmVybiBkYXRhCgpLS0sgZGF0YSBbaGVyZS5dKGh0dHBzOi8vbGFicy5saWJyYXJ5LnZjdS5lZHUva2xhbi9sZWFybikgSSBmaXhlZCBzb21lIGZvcm1hdHRpbmcgbWFudWFsbHkgaW4gdGhlIGBrbGF2ZXJucy5jc3ZgIChzb21lIGNvbHVtbnMgd2VyZSBvZmYpLgpgYGB7cn0Ka2xhdmVybnM8LXJlYWQuY3N2KCdrbGF2ZXJucy5jc3YnKQprbGF2ZXJucyRsYXQ8LWFzLm51bWVyaWMoa2xhdmVybnMkbGF0KQprbGF2ZXJucyRsb25nPC1hcy5udW1lcmljKGtsYXZlcm5zJGxvbmcpCmBgYApQbG90IGxhdC9sb25nIG9uIGEgbWFwLi4uIG9ubHkga2VlcCB0aG9zZSB3aXRoaW4gbWFwIHRlcnJpdG9yeS4KYGBge3J9CiMgbG9uZyByYW5nZXMgZnJvbSAtMTI1IHRvIC02NiwgbGF0IHJhbmdlcyBmcm9tIDI0LjUgdG8gNDkuNQprbGF2ZXJuczEgPC0gc3Vic2V0KGtsYXZlcm5zLCBrbGF2ZXJucyRsYXQgPj0gMjQuNTQ0MjQgJiBrbGF2ZXJucyRsYXQgPD0gNDkuMzg0MzYgJiBrbGF2ZXJucyRsb25nID49IC0xMjQuNzMzICYga2xhdmVybnMkbG9uZyA8PSAtNjYuOTQ5MzIpCmBgYApQbG90IGl0IQoKIyMgUGxvdCB3aXRoIGRvdHMKCmBgYHtyLCBmaWcuaGVpZ2h0PTMsIGZpZy53aWR0aD01LCB3YXJuaW5nPUZBTFNFfQpnZzEgPC0gZ2dwbG90KCkKZ2cxIDwtIGdnMSArIGdlb21fbWFwKGRhdGE9bmVpbF9tYXAsIG1hcD1uZWlsX21hcCwKICAgICAgICAgICAgICAgICAgICBhZXMoeD1sb25nLCB5PWxhdCwgbWFwX2lkPWlkKSwKICAgICAgICAgICAgICAgICAgICBjb2xvcj0iYmxhY2siLCBzaXplPTAuMDgsIGZpbGw9TkEpCmdnMSA8LSBnZzEgKyBnZW9tX3BvaW50KGRhdGEgPSBrbGF2ZXJuczEsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCksIGNvbG9yID0gInJlZCIsIHNpemUgPSAuNSkgCmdnMSA8LSBnZzEgKyB0aGVtZV9tYXAoYmFzZV9zaXplPTEyLCBiYXNlX2ZhbWlseT0iUGFsYXRpbm8iKQpnZzEgPC0gZ2cxICsgZ2d0aXRsZSgiS2xhdmVybiBMb2NhdGlvbnMgKDE5MTUtMTk0MCkiLCBzdWJ0aXRsZSA9ICJEYXRhIHZpYSBWQ1UgTGlicmFyaWVzIHwgVmlzdWFsaXphdGlvbiB2aWEgQWxleCBBbGJyaWdodCIpICsgbGFicyhjYXB0aW9uPSJLbGF2ZXJuIGxvY2F0aW9ucyBhcmUgcmVwcmVzZW50ZWQgYnkgcmVkIGRvdHMuIExvY2F0aW9uIGRhdGEgaXMgZnJvbSBWQ1UncyBNYXBwaW5nIHRoZSBLbGFuIHByb2plY3QuXG5NYXAgc2hvd3MgRE1BIChtZWRpYSBtYXJrZXQpIHJlZ2lvbnMuIEhhd2FpaSBhbmQgQWxhc2thIGFyZSBleGNsdWRlZCBmcm9tIHRoZSB2aXN1YWxpemF0aW9uLiIpCmdnMSA8LSBnZzEgKyB0aGVtZShsZWdlbmQua2V5LndpZHRoPXVuaXQoMiwgImNtIikpICsgdGhlbWUocGxvdC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT0yMCwgZmFjZT0iYm9sZCIpKQpnZzEKZ2dzYXZlKCJrbGF2ZXJubWFwX2EucG5nIiwgd2lkdGg9MTIsIGhlaWdodD04LCBkcGk9OTAwKQpgYGAKCiMjIFBsb3QgbnVtYmVyIG9mIGtsYXZlcm5zIGJ5IERNQSAKClVzZWQgc3RlcHMgZnJvbSBbdGhpcyB0dXRvcmlhbF0oaHR0cHM6Ly9hbmRyZXdidHJhbi5naXRodWIuaW8vTklDQVIvMjAxNy9tYXBzL21hcHBpbmctY2Vuc3VzLWRhdGEuaHRtbCNwb2ludHNfaW5fYV9wb2x5Z29uKSEKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIFdlIG9ubHkgbmVlZCB0aGUgY29sdW1ucyB3aXRoIHRoZSBsYXRpdHVkZSBhbmQgbG9uZ2l0dWRlCmNvb3JkcyA8LSBrbGF2ZXJuczFbYygibG9uZyIsICJsYXQiKV0KCiMgTWFraW5nIHN1cmUgd2UgYXJlIHdvcmtpbmcgd2l0aCByb3dzIHRoYXQgZG9uJ3QgaGF2ZSBhbnkgYmxhbmtzCmNvb3JkcyA8LSBjb29yZHNbY29tcGxldGUuY2FzZXMoY29vcmRzKSxdCgpsaWJyYXJ5KHNwKQojIExldHRpbmcgUiBrbm93IHRoYXQgdGhlc2UgYXJlIHNwZWNpZmljYWxseSBzcGF0aWFsIGNvb3JkaW5hdGVzCnNwIDwtIFNwYXRpYWxQb2ludHMoY29vcmRzKQpieV9kbWEgPC0gb3ZlcihzcCwgbmVpbCkKCmxpYnJhcnkoZHBseXIpCmJ5X2RtYSA8LSBieV9kbWEgJT4lCiAgZ3JvdXBfYnkoZG1hKSAlPiUKICBzdW1tYXJpc2UodG90YWw9bigpKQoKYnlfZG1hIDwtIGJ5X2RtYVshaXMubmEoYnlfZG1hJGRtYSksXQpjb2xuYW1lcyhieV9kbWEpIDwtIGMoImlkIiwgInRvdGFsIikKCmJ5X2RtYTwtbWVyZ2UoYnlfZG1hLCB0dm5ldywgYWxsPVQpCiMgc2V0IGFzIDAgaWYgTkEKYnlfZG1hJHRvdGFsW2lzLm5hKGJ5X2RtYSR0b3RhbCldIDwtIDAKYGBgCk5vdywgcGxvdCBpdCEKYGBge3IsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTYsIHdhcm5pbmc9RkFMU0V9CmdnMyA8LSBnZ3Bsb3QoKQpnZzMgPC0gZ2czICsgZ2VvbV9tYXAoZGF0YT1uZWlsX21hcCwgbWFwPW5laWxfbWFwLAogICAgICAgICAgICAgICAgICAgIGFlcyh4PWxvbmcsIHk9bGF0LCBtYXBfaWQ9aWQpLAogICAgICAgICAgICAgICAgICAgIGNvbG9yPSJncmV5Iiwgc2l6ZT0wLjA4LCBmaWxsPU5BKQpnZzMgPC0gZ2czICsgZ2VvbV9tYXAoZGF0YT1ieV9kbWEsIG1hcD1uZWlsX21hcCwKICAgICAgICAgICAgICAgICAgICBhZXMoZmlsbD10b3RhbCwgbWFwX2lkPWlkKSwKICAgICAgICAgICAgICAgICAgICBjb2xvcj0iZ3JleSIsIHNpemU9MC4wOCkKZ2czIDwtIGdnMyArIHNjYWxlX2ZpbGxfdmlyaWRpcyhsaW1pdHMgPSBjKDAsIDgyKSwgbmFtZSA9ICIiKQpnZzMgPC0gZ2czICsgdGhlbWVfbWFwKGJhc2Vfc2l6ZT0xMiwgYmFzZV9mYW1pbHk9IlBhbGF0aW5vIikKZ2czIDwtIGdnMyArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIikgKyBnZ3RpdGxlKCJOdW1iZXIgb2YgS2xhdmVybnMgKDE5MTUtMTk0MCkiLCBzdWJ0aXRsZSA9ICJEYXRhIHZpYSBWQ1UgTGlicmFyaWVzIHwgVmlzdWFsaXphdGlvbiB2aWEgQWxleCBBbGJyaWdodCIpICsgbGFicyhjYXB0aW9uPSJDb2xvciBkZXBpY3RzIG51bWJlciBvZiBLbGF2ZXJuIGxvY2F0aW9ucyBwZXIgRE1BIGFyZWEuIExvY2F0aW9uIGRhdGEgaXMgZnJvbSBWQ1UncyBNYXBwaW5nIHRoZSBLbGFuIHByb2plY3QuXG5NYXAgc2hvd3MgRE1BIChtZWRpYSBtYXJrZXQpIHJlZ2lvbnMuIEhhd2FpaSBhbmQgQWxhc2thIGFyZSBleGNsdWRlZCBmcm9tIHRoZSB2aXN1YWxpemF0aW9uLiIpCmdnMyA8LSBnZzMgKyB0aGVtZShsZWdlbmQua2V5LndpZHRoPXVuaXQoMiwgImNtIikpICsgdGhlbWUocGxvdC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT0yMCwgZmFjZT0iYm9sZCIpKQpnZzMKZ2dzYXZlKCJrbGF2ZXJubWFwX2IucG5nIiwgd2lkdGg9MTIsIGhlaWdodD04LCBkcGk9OTAwKQpgYGAKTmVlZCB0byBmaWd1cmUgb3V0IHBvcHVsYXRpb24gZmlndXJlcy4uLiB3ZSB3YW50IHRvIGxvb2sgYXQga2xhdmVybnMvY2FwaXRhIGFzIHRoZSBtZXRyaWMgb2YgaW50ZXJlc3QuIChDYXJlIGFib3V0IHNpemUgb2YgdGhlIGFyZWEuLi5iaWdnZXIgcGxhY2VzIGhhdmUgbW9yZSBrbGF2ZXJucykKCiMjIFBsb3Qga2xhdmVybnMvbWlsbGlvbiBieSBETUEKCkdldCBwb3AgZmlndXJlcyBmb3IgY291bnRpZXMgYW5kIHRoZW4gdXNlIGNvdW50eSB0byBETUEgY3Jvc3N3YWxrLiBbQ3Jvc3N3YWxrIHNob3VsZCBiZSBoZXJlLl0oaHR0cHM6Ly93d3cuaWNwc3IudW1pY2guZWR1L2ljcHNyd2ViL0lDUFNSL3N0dWRpZXMvMjI3MjAjKSAKZ2V0IHBvcHVsYXRpb24gY291bnR5IGRhdGEgYW5kIGFnZ3JlZ2F0ZSB0byBETUEuIENhbGN1bGF0ZSBrbGF2ZXJucy9taWxsaW9uIHBlb3BsZS4KCmBgYHtyfQpsaWJyYXJ5KGZvcmVpZ24pOyBsaWJyYXJ5KHN0cmluZ3IpCmRtYWM8LXJlYWQuZHRhKCdJQ1BTUl8yMjcyMF8yL0RTMDAwMy8yMjcyMC0wMDAzLURhdGEuZHRhJykKI3JlbW92ZSBBSyBjYXVzZSBpdCdzIGEgbWVzcyBsYXRlci4uLiBiYXNpY2FsbHkgbm8gY291bnRpZXMgaW4gRE1Bcy4uLgpkbWFjPC1zdWJzZXQoZG1hYywgZG1hYyRTVEFURSE9IkFLIikKCmRtYWMkY291bnR5PC1zdHJfdHJpbShhcy5jaGFyYWN0ZXIoZG1hYyRDT1VOVFkpKQpkbWFjJGNvdW50eTwtdG9sb3dlcihkbWFjJGNvdW50eSkKZG1hYyRzdGF0ZTwtZG1hYyRTVEFURQpkbWFjPC1kbWFjWyxjKCJzdGF0ZSIsICJjb3VudHkiLCAiRE1BSU5ERVgiKV0KZG1hYyRjb3VudHk8LWdzdWIoIlxcLiIsIiIsIGRtYWMkY291bnR5KSAKZG1hYyRjb3VudHk8LWdzdWIoIiciLCIiLCBkbWFjJGNvdW50eSkgCmRtYWMkY291bnR5PC1nc3ViKCIgcGFyaXNoIiwiIiwgZG1hYyRjb3VudHkpCmRtYWMkY291bnR5PC1nc3ViKCIgYm9yb3VnaCIsIiIsIGRtYWMkY291bnR5KQpkbWFjJGNvdW50eTwtZ3N1YigiICIsIiIsIGRtYWMkY291bnR5KQpgYGAKTWVyZ2UgdGhpcyB3aXRoIGNlbnN1cyAxOTIwIGRhdGEgb24gY291bnRpZXMuCgpgYGB7cn0KIyBnZXQgMTkyMCBwb3B1bGF0aW9uIGRhdGEKY2RhdGE8LXJlYWQuY3N2KCdjb3VudHlkYXRhLmNzdicpCmNkYXRhPC1jZGF0YVssYygiU1RBVEUiLCJDT1VOVFkiLCJlcG9wMTkyMCIpXQpjZGF0YSRzdGF0ZSA8LSBzdGF0ZS5hYmJbbWF0Y2goY2RhdGEkU1RBVEUsIHN0YXRlLm5hbWUpXQpjZGF0YSRjb3VudHk8LXRvbG93ZXIoc3RyX3RyaW0oY2RhdGEkQ09VTlRZKSkKY2RhdGEkc3RhdGVbY2RhdGEkY291bnR5ID09ICJkaXN0cmljdCBvZiBjb2x1bWJpYSJdIDwtICJEQyIKY2RhdGEkY291bnR5W2NkYXRhJGNvdW50eSA9PSAibWlhbWktZGFkZSJdIDwtICJkYWRlIgpjZGF0YTwtY2RhdGFbLGMoMzo1KV0KY2RhdGEkY291bnR5PC1nc3ViKCInIiwiIiwgY2RhdGEkY291bnR5KSAKY2RhdGEkY291bnR5PC1nc3ViKCIgIiwiIiwgY2RhdGEkY291bnR5KQpkbWFjMTwtbWVyZ2UoY2RhdGEsIGRtYWMsIGJ5PWMoInN0YXRlIiwgImNvdW50eSIpLCBhbGw9RikKI3JlbW92ZSBhbGwgb2YgYWxhc2thCiMgZXhjbHVkZSBkbWEgNjcgKGxvc3QgdHdvIGNvdW50aWVzIGluIGl0Li4uIGRpZG50IGhhdmUgcG9wIGRhdGEpCmRtYWMxPC1zdWJzZXQoZG1hYzEsIGRtYWMxJERNQUlOREVYIT02NykKCiMgZ2VuZXJhdGUgdG90YWwgcG9wdWxhdGlvbiBieSBkbWEKZG1hYzI8LWFnZ3JlZ2F0ZShkbWFjMSRlcG9wMTkyMCwgYnk9bGlzdChkbWFjMSRETUFJTkRFWCksIEZVTj1zdW0pCmRtYWMyJHBvcDwtZG1hYzIkeApkbWFjMiRyYW5rIDwtIGRtYWMyJEdyb3VwLjEKZG1hYzI8LWRtYWMyWyxjKDM6NCldCmBgYApCcmluZyBiYWNrIGluIGBieV9kbWFgCmBgYHtyfQojYnJpbmcgYmFjayB3aXRoIG90aGVyIGRhdGEgc291cmNlcwpieV9kbWE8LWJ5X2RtYVssYygidG90YWwiLCAicmFuayIsICJpZCIsICJkbWEiLCAiYW5pbXVzIildCmJ5X2RtYSRrbGF2ZXJuczwtYnlfZG1hJHRvdGFsCmJ5X2RtYTwtYnlfZG1hWyxjKDI6NildCmtsYXZlcm5fZG1hPC1tZXJnZShieV9kbWEsIGRtYWMyLCBieT0icmFuayIsIGFsbD1UKQprbGF2ZXJuX2RtYSRrcG1sPC1sb2coKGtsYXZlcm5fZG1hJGtsYXZlcm5zL2tsYXZlcm5fZG1hJHBvcCkqMTAwMDAwMCkKa2xhdmVybl9kbWEka3BtPC0oa2xhdmVybl9kbWEka2xhdmVybnMva2xhdmVybl9kbWEkcG9wKSoxMDAwMDAwCmtsYXZlcm5fZG1hJGtwbWxba2xhdmVybl9kbWEka2xhdmVybnMgPT0gMF0gPC0gMApgYGAKUGxvdCBpdCEgTm90ZTogVmFyaWF0aW9uIGluIGtsYXZlcm5zL21pbGxpb24gaXMgc28gbGFyZ2UgdGhhdCBpZiB5b3UgdXNlIHRoZSByYXcgcmF0ZSB0aGVuIHZpc3VhbGx5IHlvdSBjYW4ndCBzZWUgdGhlIHZhcmlhdGlvbi4uLiBUaGUgdXNlIG9mIGxvZyAoYXMgZG9uZSBiZWxvdykgYWxsb3dzIHRoZSBjb2xvcnMgdG8gYWRlcXVhdGVseSBkaXNwbGF5IGdlb2dyYXBoaWMgdmFyaWF0aW9uLgoKYGBge3IsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTYsIHdhcm5pbmc9RkFMU0V9CmdnNCA8LSBnZ3Bsb3QoKQpnZzQgPC0gZ2c0ICsgZ2VvbV9tYXAoZGF0YT1uZWlsX21hcCwgbWFwPW5laWxfbWFwLAogICAgICAgICAgICAgICAgICAgIGFlcyh4PWxvbmcsIHk9bGF0LCBtYXBfaWQ9aWQpLAogICAgICAgICAgICAgICAgICAgIGNvbG9yPSJncmV5Iiwgc2l6ZT0wLjA4LCBmaWxsPU5BKQpnZzQgPC0gZ2c0ICsgZ2VvbV9tYXAoZGF0YT1rbGF2ZXJuX2RtYSwgbWFwPW5laWxfbWFwLAogICAgICAgICAgICAgICAgICAgIGFlcyhmaWxsPWtwbWwsIG1hcF9pZD1pZCksCiAgICAgICAgICAgICAgICAgICAgY29sb3I9ImdyZXkiLCBzaXplPTAuMDgpCmdnNCA8LSBnZzQgKyBzY2FsZV9maWxsX3ZpcmlkaXMobGltaXRzID0gYygwLCA4KSwgbmFtZSA9ICIiKQpnZzQgPC0gZ2c0ICsgdGhlbWVfbWFwKGJhc2Vfc2l6ZT0xMiwgYmFzZV9mYW1pbHk9IlBhbGF0aW5vIikKZ2c0IDwtIGdnNCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIikgKyBnZ3RpdGxlKCJMb2cgb2YgS2xhdmVybnMgcGVyIE1pbGxpb24gKDE5MTUtMTk0MCkiLCBzdWJ0aXRsZSA9ICJEYXRhIHZpYSBWQ1UgTGlicmFyaWVzIHwgVmlzdWFsaXphdGlvbiB2aWEgQWxleCBBbGJyaWdodCIpICsgbGFicyhjYXB0aW9uPSJDb2xvciBkZXBpY3RzIGxvZyBvZiBLbGF2ZXJucyBwZXIgMSBtaWxsaW9uIHJlc2lkZW50cyBmb3IgZWFjaCBETUEgYXJlYS4gTG9jYXRpb24gZGF0YSBpcyBmcm9tIFZDVSdzIE1hcHBpbmcgdGhlIEtsYW4gcHJvamVjdC5cbk1hcCBzaG93cyBETUEgKG1lZGlhIG1hcmtldCkgcmVnaW9ucy4gUG9wdWxhdGlvbiBkYXRhIGFyZSBmcm9tIDE5MjAgYXQgdGhlIGNvdW50eSBsZXZlbCBhbmQgYWdncmVnYXRlZCB1cCB0byB0aGUgRE1BIGxldmVsLlxuU2V0IGxvZyhLbGF2ZXJucy9NaWxsaW9uKT0wIGlmIG5vIGtsYXZlcm5zLiBHcmF5IGFyZWFzIG1lYW4gbm8gZGF0YS4gSGF3YWlpIGFuZCBBbGFza2EgYXJlIGV4Y2x1ZGVkIGZyb20gdGhlIHZpc3VhbGl6YXRpb24uIikKZ2c0IDwtIGdnNCArIHRoZW1lKGxlZ2VuZC5rZXkud2lkdGg9dW5pdCgyLCAiY20iKSkgKyB0aGVtZShwbG90LnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTIwLCBmYWNlPSJib2xkIikpCmdnNApnZ3NhdmUoImtsYXZlcm5tYXBfYy5wbmciLCB3aWR0aD0xMiwgaGVpZ2h0PTgsIGRwaT05MDApCmBgYAoKIyBDcmVhdGUgZmluYWwgZ3JhcGhpYyAKQ29tYmluZSB0d28gY2hvcm9wbGV0aHMgKHRoZSBnb29nbGUgb25lIGFuZCB0aGUgbG9nKGtsYXZlcm5zL21pbGxpb24pKSBpbnRvIG9uZSBncmFwaGljCmBgYHtyfQpsaWJyYXJ5KGdyaWQpOyBsaWJyYXJ5KGdyaWRFeHRyYSkKcGRmKCJtYXBfYm90aC5wZGYiLCB3aWR0aCA9IDkuNSwgaGVpZ2h0ID0gMTQpCmdyaWQuYXJyYW5nZShnZzQsIGdnLCBuY29sPTEpCmRldi5vZmYoKQpgYGAKCgojIFByZWRpY3RpbmcgbW9kZXJuIHNlbnRpbWVudCB3aXRoIGhpc3RvcmljYWwgc2VudGltZW50CkxldCdzIGxvb2sgYXQgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSB0d28gdmlzdWFsbHkgZmlyc3QuCmBgYHtyfQprbGF2ZXJuX2RtYTAgPC0ga2xhdmVybl9kbWFbY29tcGxldGUuY2FzZXMoa2xhdmVybl9kbWEpLF0KIyAxOTAgb2JzZXJ2YXRpb25zCiMgUGxvdCBhbmltdXMgYW5kIGtsYXZlcm5zIHBlciBtaWxsaW9uLgpxcGxvdChrbGF2ZXJuX2RtYTAkYW5pbXVzLCBrbGF2ZXJuX2RtYTAka3BtKQpxcGxvdChrbGF2ZXJuX2RtYTAkYW5pbXVzLCBrbGF2ZXJuX2RtYTAka3BtbCkKYGBgClRoZSBkaXN0cmlidXRpb24gb2Yga3BtIGlzIGJhZGx5IHNrZXdlZCwgbWFraW5nIGEgbm9ubGluZWFyIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGFuaW11cyBhbmQga3BtLiBDYW4gY291bnRlciBoZXRlcm9za2VkYXN0aWNpdHkgdmlhIHRyYW5zZm9ybWluZyBrcG0gdG8gaXRzIGxvZy4gKFNlZSBzZWNvbmQgcGxvdC4pCgpHZXQgTGFUZVggY29kZSBmb3IgdGhlIGxpbmVhci1sb2cgcmVncmVzc2lvbi4gKEhleSwgYHN0YXJnYXplcmAgaXMgZ3JlYXQhKQpgYGB7cn0KcmVnIDwtIGxtKGFuaW11cyB+IGtwbWwsIGRhdGE9a2xhdmVybl9kbWEwKQpsaWJyYXJ5KHN0YXJnYXplcikKc3Rhcjwtc3RhcmdhemVyKHJlZywgc3R5bGU9InFqZSIsIAogICAgICAgICAgdGl0bGUgICAgICAgICAgICA9ICJQcmVkaWN0aW5nIG1vZGVybiBhbmltdXMgd2l0aCBwYXN0IGFuaW11cyIsCiAgICAgICAgICBjb3ZhcmlhdGUubGFiZWxzID0gYygiTG9nKEtsYXZlcm5zL01pbGxpb24pIiksIG5vdGVzLmFwcGVuZCA9IEZBTFNFLCBub3Rlcy5hbGlnbiA9ICJsIiwKICAgICAgICAgIGRlcC52YXIubGFiZWxzICAgPSAiUmFjaWFsbHkgQ2hhcmdlZCBHb29nbGUgU2VhcmNoIFJhdGUiLCBvbWl0LnN0YXQ9YygiZiIsICJzZXIiKSwgbm90ZXMgPSAiVG8gcmVwbGFjZS4iCiAgICAgICAgICApCgpub3RlLmxhdGV4IDwtICJcXG11bHRpY29sdW1uezJ9e2x9IHtcXHBhcmJveFt0XXsxNWNtfXsgXFx0ZXh0aXR7Tm90ZXM6fSAxOTAgRE1BIGFyZWFzIGluIHJlZ3Jlc3Npb24gYmFzZWQgb24gZGF0YSBhdmFpbGFiaWxpdHkuXFxQb3B1bGF0aW9uIGZvciBjb3VudGllcyBmcm9tIDE5MjAgc3VtbWVkIHVwIHRvIGNvbXByaXNlIHBvcHVsYXRpb25zIGZvciBETUFzLlxcICReeyoqKn0kU2lnbmlmaWNhbnQgYXQgdGhlIDElIGxldmVsLCAkXnsqKn0kU2lnbmlmaWNhbnQgYXQgdGhlIDUlIGxldmVsLCAkXnsqfSRTaWduaWZpY2FudCBhdCB0aGUgMTAlIGxldmVsLn19IFxcXFwiCnN0YXJbZ3JlcGwoIk5vdGUiLHN0YXIpXSA8LSBub3RlLmxhdGV4CmNhdCAoc3Rhciwgc2VwID0gIlxuIikKYGBgClN1cmUsIGNvZWZmaWNpZW50IG9uIGluZGVwZWRlbnQgdmFyaWFibGUgaXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4uLiBidXQgdmFyaWF0aW9uIGluIGxvZyhrbGF2ZXJucy9taWxsaW9uKSBvbmx5IGV4cGxhaW5zIDMtNCUgb2YgdGhlIHZhcmlhdGlvbiBpbiBnb29nbGUgc2VhcmNoIHJhdGVzLiBJbnRlcnByZXRhdGlvbjogMSUgaW5jcmVhc2UgaW4ga2xhdmVybnMvbWlsbGlvbiBpcyBhc3NvY2lhdGVkIHdpdGggYSAyLjY0NS8xMDA9MC4wMjY0NSB1bml0IGluY3JlYXNlIGluIHJhY2lhbGx5IGNoYXJnZWQgZ29vZ2xlIHNlYXJjaCByYXRlLiBUaGF0IGlzIHRpbnkgY29uc2lkZXJpbmcgdGhhdCB0aGUgcmF0ZXMgcmFuZ2UgZnJvbSAyNS0xNTUuIFRoaXMgaXMgbm90IGVjb25vbWljYWxseSBtZWFuaW5nZnVsIHdoYXRzb2V2ZXIuCgpOb3QgYSBtZWFuaW5nZnVsIHByZWRpY3RvciAoYXMgViZWIGdvdCBmb3IgaW4gcGFwZXIpLiBDb3VsZCBiZSBmb3IgYSBsb3Qgb2YgcmVhc29ucy4uLiAKCigxKSBLS0sgZGF0YSBub3QgY29tcGxldGUuIAooMikgS0tLIGRhdGEgaXMgbG9jYXRpb25zLi4uIG5vdCBudW1iZXIgb2YgbWVtYmVycyEgKFZlcnkgaW1wb3J0YW50LikgSSBzdXNwZWN0IG51bWJlciBvZiBLS0sgbWVtYmVycyBpbiBhIERNQSByZWdpb24gaXMgbW9yZSBsaWtlbHkgdG8gYmUgYSB1c2VmdWwgcHJlZGljdG9yIG9mIGFuaW11cyB2aXNpYmxlIHZpYSBnb29nbGUgc2VhcmNoLgooMykgSG93IGRvIHdlIHJlYWxseSBpbnRlcnByZXQgZ29vZ2xlIGRhdGE/IERvZXMgaXQgbWFrZSBhbnkgc2Vuc2UgdG8gZXhwZWN0IGxhbmd1YWdlIGluIHNlYXJjaGVzIHRvIHJldmVhbCBoaXN0b3JpY2FsIGxvY2F0aW9ucyBvZiBpbnN0aXR1dGlvbnM/CgojIFRoYXQncyBhbGwgb24gdGhpcyBpZGVhLiBPbnRvIHRoZSBuZXh0IG9uZSE=