Analysis on Weather and Economic Impact

NOTICE

Analysis on Weather and Economic Impact
Copyright © 2017 Michael Garcia. All Rights Reserved.
Inquiries: mgar_datascience at protonmail.com

This program is distributed  WITHOUT ANY WARRANTY; without even the 
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
PURPOSE.

"ggplot2"" is used under GNU GENERAL PUBLIC LICENSE Version 2 license.
See https://cran.r-project.org/web/licenses/GPL-2 for full text.
H. Wickham. ggplot2: Elegant Graphics for Data Analysis. Springer-Verlag New York, 2009.

Main Report Section

Synopsis

This report utilizes NOAA storm weather data to explain weather patterns. The weather in research are disastrous conditions, and the attributes of the weather. The analysis will also seek to answer cost and damage to the economy and people. The analysis reveals that the most frequent events are not necessarily the most damaging. Events that are most economically costly, are not the events that cause the most damage to population health.

Tornadoe, Heat, and Flash Floods are the top 3 causes of most fatalities. Hail, thunderstorms windws and tornadoes are the top 3 most frequent. Flood, Hurricane, and tornadoes are the top 3 most costly events.

Data Processing

The data was fetched from NOAA (see Citation for url). The source to pull process and retain the data can be see in the code below. The code for data tables and graphcs is provided within the R Chunks. There are a few values within my statements that are inline R chunks. The RMD file will show which sentences use inline calculations.

### Week 1 Project ###
#library(data.table)
webURL <- "https://d396qusza40orc.cloudfront.net/repdata%2Fdata%2FStormData.csv.bz2"
destURL <- file.path(getwd(),paste("repdata_data_StormData.csv",".bz2",sep = ""))
download.file(webURL,destfile = destURL)
trying URL 'https://d396qusza40orc.cloudfront.net/repdata%2Fdata%2FStormData.csv.bz2'
Content type 'application/bzip2' length 49177144 bytes (46.9 MB)
==================================================
downloaded 46.9 MB
#unzip(destURL)
#localFileURL <- file.path(getwd(),paste("repdata_data_StormData",".csv",sep = ""))
repdata <- read.csv(destURL)

Results

Summary of Each Variable.

Events most harmful to population health

This chunk transforms and prepares the data to sort by the frequency or quantity of events.

eventFreq <- aggregate(repdata$EVTYPE, list(repdata$EVTYPE), length)
names(eventFreq) <- c("EVTYPE","Qty")
eventFatal <- aggregate(repdata$FATALITIES, list(repdata$EVTYPE), sum)
names(eventFatal) <- c("EVTYPE","FATALITIES")
eventsInjur <- aggregate(repdata$INJURIES, list(repdata$EVTYPE), sum)
names(eventsInjur) <- c("EVTYPE","INJURIES")
#a <- eventFreq[order(eventFreq$Qty, decreasing = TRUE),]
eventDamag <- merge(eventFreq,eventFatal, by.x = "EVTYPE", all = TRUE)
eventDamag <- merge(eventDamag, eventsInjur, by.x = "EVTYPE", all = TRUE)
eventDamag <- eventDamag[order(eventDamag$"Qty", decreasing = TRUE),]
eventDamag
#plot(eventFreq$EVTYPE,eventFreq$Qty,type ="h")

This table shows the event types ordered by frequency. This depicts that the most frequent types HAIL at 288661 and WND at 1 are not the most frequent.

This table sorts all the events by the total deaths by event type.

ftl <- eventDamag[order(eventDamag$FATALITIES, decreasing = TRUE),]
ftl

TORNADO event is the top event causing fatalities at 5633 fatalities. WND is the event with the least number of fatalities at 0

This table displayes the top ten events that are most frequent. HAIL is the event that occurs the most at 288661 number of events. HEAVY SNOW is the least top frequent occuring event coming at 15708 number of events.

Events have the greatest economic consequences

This chunk tansforms the abbreviated Property Damage Cost and Crop Damage Cost to full dollar amounts. It uses the given Letter for how many zeros it will use. This then displays a table sorted by Total Damage Cost from Greatest to Least. This data frame is used farther down in code snippers.

#a <- head(eventDamag[order(eventDamag$"Qty", decreasing = TRUE),],5)
#plot(a$EVTYPE, as.numeric(a$Qty/1000), type = "h")
#   “K” for thousands, “M” for millions, and “B” for billions
#PROPDMG PROPDMGEXP CROPDMG CROPDMGEXP
      # totaldmg doesnt work since the exp is different for prop and crop
##totalDmg <- aggregate((repdata$PROPDMG+repdata$CROPDMG), list(repdata$EVTYPE,repdata$PROPDMGEXP), sum)
##colnames(totalDmg) <- c("EVTYPE","TOTALEXP","TOTALDMG")
# This chunk transforms the damage values into 
bil <- 1000000000
mil <- 1000000
thous <- 1000
repDataConv <- repdata
propDmg <- aggregate((ifelse(repdata$PROPDMGEXP == "B",repdata$PROPDMG*bil
                             ,ifelse(repdata$PROPDMGEXP == "M",repdata$PROPDMG*mil
                                     , ifelse(repdata$PROPDMGEXP == "K"
                                              ,repdata$PROPDMG*thous
                                              ,0
                                              )
                                     )
                          )
                      )
                             , list(repdata$EVTYPE
                                    #,repdata$PROPDMGEXP
                                    ), sum)
#colnames(propDmg) <- c("EVTYPE","EXP","PROPDMG")
colnames(propDmg) <- c("EVTYPE","PROPDMG")
cropDmg <- aggregate((ifelse(repdata$CROPDMGEXP == "B",repdata$CROPDMG*bil
                             ,ifelse(repdata$CROPDMGEXP == "M",repdata$CROPDMG*mil
                                     , ifelse(repdata$CROPDMGEXP == "K",repdata$CROPDMG*thous
                                              ,0
                                              )
                                     )
                          )
                      ), list(repdata$EVTYPE
                              #,repdata$CROPDMGEXP
                              ), sum)
#colnames(cropDmg) <- c("EVTYPE","EXP","CROPDMG")
colnames(cropDmg) <- c("EVTYPE","CROPDMG")
eventDamagProp <- merge(eventDamag, propDmg,by.x = "EVTYPE", all = TRUE)
eventDmgPrp <- merge(eventDamagProp, cropDmg,by.x = "EVTYPE", all = FALSE)
                                                  #c("EVTYPE","EXP")
eventDmgPrp$TOTLDMG <- (eventDmgPrp$PROPDMG + eventDmgPrp$CROPDMG)
# this is the Millions
 #a <- eventDmgPrp[which(eventDmgPrp$EXP == "B"),]
# head(a[order(a$TOTLDMG, decreasing = TRUE),],10)
 #head(eventDmgPrp[order(eventDmgPrp$TOTLDMG, decreasing = TRUE),],10)
eventDmgPrp$PROPDMG <- round(eventDmgPrp$PROPDMG/1000,1)
eventDmgPrp$CROPDMG <- round(eventDmgPrp$CROPDMG/1000,1)
eventDmgPrp$TOTLDMG <- round(eventDmgPrp$TOTLDMG/1000,1)
eventDmgPrp[order(eventDmgPrp$TOTLDMG, decreasing = TRUE),]

This table is sorted by the total property damage cost from most to least and represented in thousands (’000). The values were converted to full dollar amount based on the EXP value.

This chart shows the top 10 most economically damaging events, from most to least. The Flood is the most costly and the Ice Storm is the least.

This chunk aggregates the results for plotting by injury and fatalities into a panel plot. The final data frame in this chunk is used for the codes in time plots further down.

Results

This chunk prepares the data to panel plot Fatalities and Injuries by Month and Year.

BGN_DATEP <- as.POSIXct(unlist(tmEventFtlInj$BGN_DATE), tz = "GMT")
BGN_MONTH <- strftime(BGN_DATEP, "%m")
BGN_YEAR <- strftime(BGN_DATEP, "%Y")
BGN_DATES <- data.frame(BGN_MONTH,BGN_YEAR,BGN_DATEP)
tmeventSeries <- cbind(BGN_DATES ,tmEventFtlInj)
tmSeriesAgF <- aggregate(FATALITIES~ BGN_MONTH+ BGN_YEAR, tmeventSeries, FUN = sum)
tmSeriesAgI <- aggregate(INJURIES~ BGN_MONTH+ BGN_YEAR, tmeventSeries, FUN = sum)
tmSeriesAg <- merge(tmSeriesAgF,tmSeriesAgI, by = c("BGN_MONTH", "BGN_YEAR"))
tmSeriesAg$MOYR <- as.POSIXct(paste(tmSeriesAg$BGN_YEAR, tmSeriesAg$BGN_MONTH, "01", sep = "-"))
#plot(tmSeriesAg$MOYR[order(tmSeriesAg$MOYR)], tmSeriesAg$INJURIES, col = "green", type = "l",pch = 20
#       , xlab = "Event Date", ylab = "Qty of People")
# lines(tmSeriesAg$MOYR[order(tmSeriesAg$MOYR)],tmSeriesAg$FATALITIES, col = "red",type = "l", pch = 20)
 
 #par(mfrow=c(1,2), mai = c(.5, .5, 0.2, 0.1))
 par(mfrow=c(2,1), mai = c(0.80, 0.80, 0.2, 0.1))
 plot(tmSeriesAg$MOYR[order(tmSeriesAg$MOYR)], tmSeriesAg$INJURIES, col = "dodger blue", type = "l",pch = 20
       , xlab = "", ylab = "Number Injuries")
 plot(tmSeriesAg$MOYR[order(tmSeriesAg$MOYR)], tmSeriesAg$FATALITIES, col = "green", type = "l",pch = 20
       , xlab = "Event Date", ylab = "Number Fatalities")
 #plot(tmSeriesAg$MOYR[order(tmSeriesAg$MOYR)], tmSeriesAg$INJURIES, col = "green", type = "l",pch = 20
#       , xlab = "Event Date", ylab = "Injuries and Fatalities")
# lines(tmSeriesAg$MOYR[order(tmSeriesAg$MOYR)],tmSeriesAg$FATALITIES, col = "red",type = "l", pch = 20)
 
 mtext("Fatalities and Injuries", side=3, outer=TRUE, line=-1, col = "blue",font = 2) 

This plot presents top 10 costly events.

pl <- head(eventDmgPrp[order(eventDmgPrp$TOTLDMG, decreasing = TRUE),],10)
pl$TOTLDMG <- as.numeric(pl$TOTLDMG)
pl$EVTYPE <- factor(pl$EVTYPE)
#plot(pl$EVTYPE,(pl$TOTLDMG/1000), type = "h", xlab = "EVTYPE", ylab = "Total Damage Amount")
library(ggplot2)
 ggplot(pl, aes(x=reorder(EVTYPE, -TOTLDMG), y=format(TOTLDMG, scientific = FALSE), group=1)) +
          ggtitle("Top 10 Costly Events")+
          geom_bar(stat = "identity", fill = "#0099FF")+ 
            theme(axis.text.x = element_text(angle = 45, hjust = 1)
                               ,axis.title.x = element_text(face="bold", size=12)
                               ,legend.position="none")+ 
                                    labs(x="Event Type",y="Damage Amount (000's)") 

                                    
# plot(activityWkend$interval, activityWkend$avgSteps, type = "l",xlab = "interval", ylab = "WkEnd Avg Steps")

This plot displays the top 10 occuring events

dm <- head(eventDamag[order(eventDamag$Qty, decreasing = TRUE),],10)
dm$Qty <- as.numeric(dm$Qty)
dm$EVTYPE <- factor(dm$EVTYPE)
#plot(pl$EVTYPE,(pl$TOTLDMG/1000), type = "h", xlab = "EVTYPE", ylab = "Total Damage Amount")
library(ggplot2)
ggplot(dm, aes(x=reorder(EVTYPE, -Qty), y=format(Qty, scientific = FALSE), group=1)) + 
            ggtitle("Top 10 Frequent Events")+
            geom_bar(stat = "identity", fill = "#0099FF")+ 
            theme(axis.text.x = element_text(angle = 45, hjust = 1)
                               ,axis.title.x = element_text(face="bold", size=12)
                               ,legend.position="none")+
                                    labs(x="Event Type",y="Event Frequency") 

This depicts that the most frequent types HAIL at 288661 and WND at 1 are not the most frequent.

TORNADO event is the top event causing fatalities at 5633 fatalities. WND is the event with the least number of fatalities at 0

This table displayes the top ten events that are most frequent. HAIL is the event that occurs the most at 288661 number of events. HEAVY SNOW is the least top frequent occuring event coming at 15708 number of events.

Source Citation and Resource:

NATIONAL WEATHER SERVICE INSTRUCTION  10-1605 
AUGUST 17, 2007 
Operations and Services 
Performance, NWSPD 10-16
STORM DATA PREPARATION


Storm Data Documentation: https://d396qusza40orc.cloudfront.net/repdata%2Fpeer2_doc%2Fpd01016005curr.pdf
FAQ: https://d396qusza40orc.cloudfront.net/repdata%2Fpeer2_doc%2FNCDC%20Storm%20Events-FAQ%20Page.pdf

LS0tCnRpdGxlOiAiQW5hbHlzaXMgb24gV2VhdGhlciBhbmQgRWNvbm9taWMgSW1wYWN0IgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAogIGh0bWxfZG9jdW1lbnQ6IGRlZmF1bHQKICBtZF9kb2N1bWVudDoKICAgIHZhcmlhbnQ6IG1hcmtkb3duX2dpdGh1YgotLS0KCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKCiMjIEFuYWx5c2lzIG9uIFdlYXRoZXIgYW5kIEVjb25vbWljIEltcGFjdCB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxsc30KIyMjIE5PVElDRQogICAgQW5hbHlzaXMgb24gV2VhdGhlciBhbmQgRWNvbm9taWMgSW1wYWN0CiAgICBDb3B5cmlnaHQgwqkgMjAxNyBNaWNoYWVsIEdhcmNpYS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICAgIElucXVpcmllczogbWdhcl9kYXRhc2NpZW5jZSBhdCBwcm90b25tYWlsLmNvbQogICAgCiAgICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgIFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIAogICAgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIAogICAgUFVSUE9TRS4KICAgIAogICAgImdncGxvdDIiIiBpcyB1c2VkIHVuZGVyIEdOVSBHRU5FUkFMIFBVQkxJQyBMSUNFTlNFIFZlcnNpb24gMiBsaWNlbnNlLgogICAgU2VlIGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9saWNlbnNlcy9HUEwtMiBmb3IgZnVsbCB0ZXh0LgogICAgSC4gV2lja2hhbS4gZ2dwbG90MjogRWxlZ2FudCBHcmFwaGljcyBmb3IgRGF0YSBBbmFseXNpcy4gU3ByaW5nZXItVmVybGFnIE5ldyBZb3JrLCAyMDA5LgogICAgCgojIyMgTWFpbiBSZXBvcnQgU2VjdGlvbgoKIyMjIyMgU3lub3BzaXMKClRoaXMgcmVwb3J0IHV0aWxpemVzIE5PQUEgc3Rvcm0gd2VhdGhlciBkYXRhIHRvIGV4cGxhaW4gd2VhdGhlciBwYXR0ZXJucy4gVGhlIHdlYXRoZXIgaW4gcmVzZWFyY2ggYXJlIGRpc2FzdHJvdXMgY29uZGl0aW9ucywgYW5kIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSB3ZWF0aGVyLiBUaGUgYW5hbHlzaXMgd2lsbCBhbHNvIHNlZWsgdG8gYW5zd2VyIGNvc3QgYW5kIGRhbWFnZSB0byB0aGUgZWNvbm9teSBhbmQgcGVvcGxlLiBUaGUgYW5hbHlzaXMgcmV2ZWFscyB0aGF0IHRoZSBtb3N0IGZyZXF1ZW50IGV2ZW50cyBhcmUgbm90IG5lY2Vzc2FyaWx5IHRoZSBtb3N0IGRhbWFnaW5nLiBFdmVudHMgdGhhdCBhcmUgbW9zdCBlY29ub21pY2FsbHkgY29zdGx5LCBhcmUgbm90IHRoZSBldmVudHMgdGhhdCBjYXVzZSB0aGUgbW9zdCBkYW1hZ2UgdG8gcG9wdWxhdGlvbiBoZWFsdGguIAoKVG9ybmFkb2UsIEhlYXQsIGFuZCBGbGFzaCBGbG9vZHMgYXJlIHRoZSB0b3AgIDMgY2F1c2VzIG9mIG1vc3QgZmF0YWxpdGllcy4gSGFpbCwgdGh1bmRlcnN0b3JtcyB3aW5kd3MgYW5kIHRvcm5hZG9lcyBhcmUgdGhlIHRvcCAzIG1vc3QgZnJlcXVlbnQuIEZsb29kLCBIdXJyaWNhbmUsIGFuZCB0b3JuYWRvZXMgYXJlIHRoZSB0b3AgMyBtb3N0IGNvc3RseSBldmVudHMuCgojIyMjIyBEYXRhIFByb2Nlc3NpbmcKClRoZSBkYXRhIHdhcyBmZXRjaGVkIGZyb20gTk9BQSAoc2VlIENpdGF0aW9uIGZvciB1cmwpLiBUaGUgc291cmNlIHRvIHB1bGwgcHJvY2VzcyBhbmQgcmV0YWluIHRoZSBkYXRhIGNhbiBiZSBzZWUgaW4gdGhlIGNvZGUgYmVsb3cuIFRoZSBjb2RlIGZvciBkYXRhIHRhYmxlcyBhbmQgZ3JhcGhjcyBpcyBwcm92aWRlZCB3aXRoaW4gdGhlIFIgQ2h1bmtzLiBUaGVyZSBhcmUgYSBmZXcgdmFsdWVzIHdpdGhpbiBteSBzdGF0ZW1lbnRzIHRoYXQgYXJlIGlubGluZSBSIGNodW5rcy4gVGhlIFJNRCBmaWxlIHdpbGwgc2hvdyB3aGljaCBzZW50ZW5jZXMgIHVzZSBpbmxpbmUgY2FsY3VsYXRpb25zLgoKYGBge3IgRGF0YSBQcm9jZXNzaW5nLCBpbmNsdWRlPVRSVUUsIGVjaG89VFJVRX0KIyMjIFdlZWsgMSBQcm9qZWN0ICMjIwojbGlicmFyeShkYXRhLnRhYmxlKQp3ZWJVUkwgPC0gImh0dHBzOi8vZDM5NnF1c3phNDBvcmMuY2xvdWRmcm9udC5uZXQvcmVwZGF0YSUyRmRhdGElMkZTdG9ybURhdGEuY3N2LmJ6MiIKZGVzdFVSTCA8LSBmaWxlLnBhdGgoZ2V0d2QoKSxwYXN0ZSgicmVwZGF0YV9kYXRhX1N0b3JtRGF0YS5jc3YiLCIuYnoyIixzZXAgPSAiIikpCmRvd25sb2FkLmZpbGUod2ViVVJMLGRlc3RmaWxlID0gZGVzdFVSTCkKCiN1bnppcChkZXN0VVJMKQojbG9jYWxGaWxlVVJMIDwtIGZpbGUucGF0aChnZXR3ZCgpLHBhc3RlKCJyZXBkYXRhX2RhdGFfU3Rvcm1EYXRhIiwiLmNzdiIsc2VwID0gIiIpKQpyZXBkYXRhIDwtIHJlYWQuY3N2KGRlc3RVUkwpCmBgYAoKCiMjIyMgUmVzdWx0cwoKClN1bW1hcnkgb2YgRWFjaCBWYXJpYWJsZS4KCmBgYHtyIHN1bW1hcnksIGluY2x1ZGUgPSBUUlVFLCBlY2hvPUZBTFNFfQojYXMudGFibGUoc3VtbWFyeShyZXBkYXRhKSkKCiMjIHJtYXJrZG93bjo6cGFnZWRfdGFibGUoKQpgYGAKCiMjIyMjIEV2ZW50cyBtb3N0IGhhcm1mdWwgdG8gcG9wdWxhdGlvbiBoZWFsdGgKClRoaXMgY2h1bmsgdHJhbnNmb3JtcyBhbmQgcHJlcGFyZXMgdGhlIGRhdGEgdG8gc29ydCBieSB0aGUgZnJlcXVlbmN5IG9yIHF1YW50aXR5IG9mIGV2ZW50cy4gCgpgYGB7ciBldmVudHlwZXMsaW5jbHVkZSA9ICBUUlVFLCBlY2hvID0gVFJVRX0KZXZlbnRGcmVxIDwtIGFnZ3JlZ2F0ZShyZXBkYXRhJEVWVFlQRSwgbGlzdChyZXBkYXRhJEVWVFlQRSksIGxlbmd0aCkKbmFtZXMoZXZlbnRGcmVxKSA8LSBjKCJFVlRZUEUiLCJRdHkiKQpldmVudEZhdGFsIDwtIGFnZ3JlZ2F0ZShyZXBkYXRhJEZBVEFMSVRJRVMsIGxpc3QocmVwZGF0YSRFVlRZUEUpLCBzdW0pCm5hbWVzKGV2ZW50RmF0YWwpIDwtIGMoIkVWVFlQRSIsIkZBVEFMSVRJRVMiKQpldmVudHNJbmp1ciA8LSBhZ2dyZWdhdGUocmVwZGF0YSRJTkpVUklFUywgbGlzdChyZXBkYXRhJEVWVFlQRSksIHN1bSkKbmFtZXMoZXZlbnRzSW5qdXIpIDwtIGMoIkVWVFlQRSIsIklOSlVSSUVTIikKI2EgPC0gZXZlbnRGcmVxW29yZGVyKGV2ZW50RnJlcSRRdHksIGRlY3JlYXNpbmcgPSBUUlVFKSxdCmV2ZW50RGFtYWcgPC0gbWVyZ2UoZXZlbnRGcmVxLGV2ZW50RmF0YWwsIGJ5LnggPSAiRVZUWVBFIiwgYWxsID0gVFJVRSkKZXZlbnREYW1hZyA8LSBtZXJnZShldmVudERhbWFnLCBldmVudHNJbmp1ciwgYnkueCA9ICJFVlRZUEUiLCBhbGwgPSBUUlVFKQpldmVudERhbWFnIDwtIGV2ZW50RGFtYWdbb3JkZXIoZXZlbnREYW1hZyQiUXR5IiwgZGVjcmVhc2luZyA9IFRSVUUpLF0KZXZlbnREYW1hZwojcGxvdChldmVudEZyZXEkRVZUWVBFLGV2ZW50RnJlcSRRdHksdHlwZSA9ImgiKQpgYGAKClRoaXMgdGFibGUgc2hvd3MgdGhlIGV2ZW50IHR5cGVzIG9yZGVyZWQgYnkgZnJlcXVlbmN5LiBUaGlzIGRlcGljdHMgdGhhdCB0aGUgbW9zdCBmcmVxdWVudCB0eXBlcyBgciBldmVudERhbWFnWzEsMV1gIGF0IGByIGV2ZW50RGFtYWdbMSwyXWAgYW5kIGByIGV2ZW50RGFtYWdbbnJvdyhldmVudERhbWFnKSwxXWAgYXQgYHIgZXZlbnREYW1hZ1tucm93KGV2ZW50RGFtYWcpLDJdYCBhcmUgbm90IHRoZSBtb3N0IGZyZXF1ZW50LgoKVGhpcyB0YWJsZSBzb3J0cyBhbGwgdGhlIGV2ZW50cyBieSB0aGUgdG90YWwgZGVhdGhzIGJ5IGV2ZW50IHR5cGUuCgpgYGB7ciBpbmp1cnlfZmF0YWxpdGllcywgaW5jbHVkZT0gVFJVRSxlY2hvPSBUUlVFfQpmdGwgPC0gZXZlbnREYW1hZ1tvcmRlcihldmVudERhbWFnJEZBVEFMSVRJRVMsIGRlY3JlYXNpbmcgPSBUUlVFKSxdCmZ0bAoKYGBgCmByIGZ0bFsxLDFdYCBldmVudCBpcyB0aGUgdG9wIGV2ZW50IGNhdXNpbmcgZmF0YWxpdGllcyBhdCBgciBmdGxbMSwzXWAgZmF0YWxpdGllcy4gYHIgZnRsW25yb3coZnRsKSwxXWAgaXMgdGhlIGV2ZW50IHdpdGggdGhlIGxlYXN0IG51bWJlciBvZiBmYXRhbGl0aWVzIGF0IGByIGZ0bFtucm93KGZ0bCksM11gCgogCmBgYHtyIGluY2x1ZGU9IEZBTFNFLCBlY2hvPUZBTFNFfQojIyMgIFRoaXMgYmFyIGdyYXBoIGRpc3BsYXlzIHRoZSB0b3AgMTAgZXZlbnRzIHRoYXQgY2F1c2UgdGhlIG1vc3QgZmF0YWxpdGllcy4KYGBgCgoKVGhpcyB0YWJsZSBkaXNwbGF5ZXMgdGhlIHRvcCB0ZW4gZXZlbnRzIHRoYXQgYXJlIG1vc3QgZnJlcXVlbnQuIGByIGhlYWQoZG0kRVZUWVBFLDEpYCBpcyB0aGUgZXZlbnQgdGhhdCBvY2N1cnMgdGhlIG1vc3QgYXQgYHIgZm9ybWF0KGhlYWQoZG0kUXR5LDEpLCBzY2llbnRpZmljID0gRkFMU0UpYCBudW1iZXIgb2YgZXZlbnRzLiBgciBkbVsxMCwxXWAgaXMgdGhlIGxlYXN0IHRvcCBmcmVxdWVudCBvY2N1cmluZyBldmVudCBjb21pbmcgYXQgYHIgZm9ybWF0KGRtWzEwLDJdLCBzY2llbnRpZmljID0gRkFMU0UpYCBudW1iZXIgb2YgZXZlbnRzLgoKCgojIyMjIyAgRXZlbnRzIGhhdmUgdGhlIGdyZWF0ZXN0IGVjb25vbWljIGNvbnNlcXVlbmNlcwoKVGhpcyBjaHVuayB0YW5zZm9ybXMgdGhlIGFiYnJldmlhdGVkIFByb3BlcnR5IERhbWFnZSBDb3N0IGFuZCBDcm9wIERhbWFnZSBDb3N0IHRvIGZ1bGwgZG9sbGFyIGFtb3VudHMuIEl0IHVzZXMgdGhlIGdpdmVuIExldHRlciBmb3IgaG93IG1hbnkgemVyb3MgaXQgd2lsbCB1c2UuIFRoaXMgdGhlbiBkaXNwbGF5cyBhIHRhYmxlIHNvcnRlZCBieSBUb3RhbCBEYW1hZ2UgQ29zdCBmcm9tIEdyZWF0ZXN0IHRvIExlYXN0LiBUaGlzIGRhdGEgZnJhbWUgaXMgdXNlZCBmYXJ0aGVyIGRvd24gaW4gY29kZSBzbmlwcGVycy4KYGBge3IgZXZlbnQgaGlzdG9ncmFtLGluY2x1ZGUgPSAgVFJVRSwgZWNobyA9IFRSVUV9CiNhIDwtIGhlYWQoZXZlbnREYW1hZ1tvcmRlcihldmVudERhbWFnJCJRdHkiLCBkZWNyZWFzaW5nID0gVFJVRSksXSw1KQojcGxvdChhJEVWVFlQRSwgYXMubnVtZXJpYyhhJFF0eS8xMDAwKSwgdHlwZSA9ICJoIikKIyAgIOKAnEvigJ0gZm9yIHRob3VzYW5kcywg4oCcTeKAnSBmb3IgbWlsbGlvbnMsIGFuZCDigJxC4oCdIGZvciBiaWxsaW9ucwojUFJPUERNRyBQUk9QRE1HRVhQIENST1BETUcgQ1JPUERNR0VYUAogICAgICAjIHRvdGFsZG1nIGRvZXNudCB3b3JrIHNpbmNlIHRoZSBleHAgaXMgZGlmZmVyZW50IGZvciBwcm9wIGFuZCBjcm9wCiMjdG90YWxEbWcgPC0gYWdncmVnYXRlKChyZXBkYXRhJFBST1BETUcrcmVwZGF0YSRDUk9QRE1HKSwgbGlzdChyZXBkYXRhJEVWVFlQRSxyZXBkYXRhJFBST1BETUdFWFApLCBzdW0pCiMjY29sbmFtZXModG90YWxEbWcpIDwtIGMoIkVWVFlQRSIsIlRPVEFMRVhQIiwiVE9UQUxETUciKQojIFRoaXMgY2h1bmsgdHJhbnNmb3JtcyB0aGUgZGFtYWdlIHZhbHVlcyBpbnRvIApiaWwgPC0gMTAwMDAwMDAwMAptaWwgPC0gMTAwMDAwMAp0aG91cyA8LSAxMDAwCgpyZXBEYXRhQ29udiA8LSByZXBkYXRhCnByb3BEbWcgPC0gYWdncmVnYXRlKChpZmVsc2UocmVwZGF0YSRQUk9QRE1HRVhQID09ICJCIixyZXBkYXRhJFBST1BETUcqYmlsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLGlmZWxzZShyZXBkYXRhJFBST1BETUdFWFAgPT0gIk0iLHJlcGRhdGEkUFJPUERNRyptaWwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICwgaWZlbHNlKHJlcGRhdGEkUFJPUERNR0VYUCA9PSAiSyIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICxyZXBkYXRhJFBST1BETUcqdGhvdXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICwwCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICwgbGlzdChyZXBkYXRhJEVWVFlQRQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjLHJlcGRhdGEkUFJPUERNR0VYUAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLCBzdW0pCiNjb2xuYW1lcyhwcm9wRG1nKSA8LSBjKCJFVlRZUEUiLCJFWFAiLCJQUk9QRE1HIikKY29sbmFtZXMocHJvcERtZykgPC0gYygiRVZUWVBFIiwiUFJPUERNRyIpCgpjcm9wRG1nIDwtIGFnZ3JlZ2F0ZSgoaWZlbHNlKHJlcGRhdGEkQ1JPUERNR0VYUCA9PSAiQiIscmVwZGF0YSRDUk9QRE1HKmJpbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICxpZmVsc2UocmVwZGF0YSRDUk9QRE1HRVhQID09ICJNIixyZXBkYXRhJENST1BETUcqbWlsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAsIGlmZWxzZShyZXBkYXRhJENST1BETUdFWFAgPT0gIksiLHJlcGRhdGEkQ1JPUERNRyp0aG91cwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLDAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICApLCBsaXN0KHJlcGRhdGEkRVZUWVBFCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMscmVwZGF0YSRDUk9QRE1HRVhQCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksIHN1bSkKI2NvbG5hbWVzKGNyb3BEbWcpIDwtIGMoIkVWVFlQRSIsIkVYUCIsIkNST1BETUciKQpjb2xuYW1lcyhjcm9wRG1nKSA8LSBjKCJFVlRZUEUiLCJDUk9QRE1HIikKCmV2ZW50RGFtYWdQcm9wIDwtIG1lcmdlKGV2ZW50RGFtYWcsIHByb3BEbWcsYnkueCA9ICJFVlRZUEUiLCBhbGwgPSBUUlVFKQpldmVudERtZ1BycCA8LSBtZXJnZShldmVudERhbWFnUHJvcCwgY3JvcERtZyxieS54ID0gIkVWVFlQRSIsIGFsbCA9IEZBTFNFKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNjKCJFVlRZUEUiLCJFWFAiKQpldmVudERtZ1BycCRUT1RMRE1HIDwtIChldmVudERtZ1BycCRQUk9QRE1HICsgZXZlbnREbWdQcnAkQ1JPUERNRykKCiMgdGhpcyBpcyB0aGUgTWlsbGlvbnMKICNhIDwtIGV2ZW50RG1nUHJwW3doaWNoKGV2ZW50RG1nUHJwJEVYUCA9PSAiQiIpLF0KIyBoZWFkKGFbb3JkZXIoYSRUT1RMRE1HLCBkZWNyZWFzaW5nID0gVFJVRSksXSwxMCkKICNoZWFkKGV2ZW50RG1nUHJwW29yZGVyKGV2ZW50RG1nUHJwJFRPVExETUcsIGRlY3JlYXNpbmcgPSBUUlVFKSxdLDEwKQpldmVudERtZ1BycCRQUk9QRE1HIDwtIHJvdW5kKGV2ZW50RG1nUHJwJFBST1BETUcvMTAwMCwxKQpldmVudERtZ1BycCRDUk9QRE1HIDwtIHJvdW5kKGV2ZW50RG1nUHJwJENST1BETUcvMTAwMCwxKQpldmVudERtZ1BycCRUT1RMRE1HIDwtIHJvdW5kKGV2ZW50RG1nUHJwJFRPVExETUcvMTAwMCwxKQpldmVudERtZ1BycFtvcmRlcihldmVudERtZ1BycCRUT1RMRE1HLCBkZWNyZWFzaW5nID0gVFJVRSksXQpgYGAKVGhpcyB0YWJsZSBpcyBzb3J0ZWQgYnkgdGhlIHRvdGFsIHByb3BlcnR5IGRhbWFnZSBjb3N0IGZyb20gbW9zdCB0byBsZWFzdCBhbmQgcmVwcmVzZW50ZWQgaW4gdGhvdXNhbmRzICgnMDAwKS4gVGhlIHZhbHVlcyB3ZXJlIGNvbnZlcnRlZCB0byBmdWxsIGRvbGxhciBhbW91bnQgYmFzZWQgb24gdGhlIEVYUCB2YWx1ZS4KCgoKCgpUaGlzIGNoYXJ0IHNob3dzIHRoZSB0b3AgMTAgbW9zdCBlY29ub21pY2FsbHkgZGFtYWdpbmcgZXZlbnRzLCBmcm9tIG1vc3QgdG8gbGVhc3QuIFRoZSBGbG9vZCBpcyB0aGUgbW9zdCBjb3N0bHkgYW5kIHRoZSBJY2UgU3Rvcm0gaXMgdGhlIGxlYXN0LgoKVGhpcyBjaHVuayBhZ2dyZWdhdGVzIHRoZSByZXN1bHRzIGZvciBwbG90dGluZyBieSBpbmp1cnkgYW5kIGZhdGFsaXRpZXMgaW50byBhIHBhbmVsIHBsb3QuIFRoZSBmaW5hbCBkYXRhIGZyYW1lIGluIHRoaXMgY2h1bmsgaXMgdXNlZCBmb3IgdGhlIGNvZGVzIGluIHRpbWUgcGxvdHMgZnVydGhlciBkb3duLgoKYGBge3IgaW5jbHVkZT0gRkFMU0UsIGVjaG89IEZBTFNFfQoKdG1FdmVudCA8LSByZXBkYXRhW3doaWNoKGlzLm5hKHJlcGRhdGEkQkdOX0RBVEUpID09IEZBTFNFKSxdCnRtRXZlbnQkQkdOX0RBVEUgPC0gIGFzLkRhdGUodG1FdmVudCRCR05fREFURSwgZm9ybWF0ID0gIiVtLyVkLyVZIikKCnRtRXZlbnRBZyA8LSBhZ2dyZWdhdGUodG1FdmVudCRGQVRBTElUSUVTLCBsaXN0KHRtRXZlbnQkQkdOX0RBVEUpLCBzdW0sIG5hLnJtID0gVFJVRSkgICAgICAjIHJlcGRhdGEkQkdOX0RBVEUKY29sbmFtZXModG1FdmVudEFnKSA8LSBjKCJCR05fREFURSIsIkZBVEFMSVRJRVMiKQp0bUV2ZW50TWVhbiA8LSBhZ2dyZWdhdGUodG1FdmVudCRGQVRBTElUSUVTLCBsaXN0KHRtRXZlbnQkQkdOX0RBVEUpLCBtZWFuLCBuYS5ybSA9IFRSVUUpICAgICAgIyByZXBkYXRhJEJHTl9EQVRFCmNvbG5hbWVzKHRtRXZlbnRBZykgPC0gYygiQkdOX0RBVEUiLCJGQVRBTElUSUVTIikKIyB0bUV2ZW50QWcgPC0gdG1FdmVudEFnW3doaWNoKHRtRXZlbnRBZyRCR05fREFURSA+PSAiMTk5MC0wMS0wMSIpLF0KdG1FdmVudEluaiA8LSBhZ2dyZWdhdGUodG1FdmVudCRJTkpVUklFUywgbGlzdCh0bUV2ZW50JEJHTl9EQVRFKSwgc3VtLCBuYS5ybSA9IFRSVUUpIApjb2xuYW1lcyh0bUV2ZW50SW5qKSA8LSBjKCJCR05fREFURSIsIklOSlVSSUVTIikKCiNwbG90KHRtRXZlbnRBZyRCR05fREFURSwgICh0bUV2ZW50QWckRkFUQUxJVElFUyksIHR5cGUgPSAiaCIsIHhsYWIgPSAiRXZlbnQgRGF0ZSIsIHlsYWIgPSAiRmF0YWxpdGllcyIpCnRtRXZlbnRGdGxJbmogPC0gbWVyZ2UodG1FdmVudEFnLHRtRXZlbnRJbmosIGJ5ID0gIkJHTl9EQVRFIikKCmBgYAoKCiMjIyMgUmVzdWx0cwoKVGhpcyBjaHVuayBwcmVwYXJlcyB0aGUgZGF0YSB0byBwYW5lbCBwbG90IEZhdGFsaXRpZXMgYW5kIEluanVyaWVzIGJ5IE1vbnRoIGFuZCBZZWFyLgpgYGB7ciB0aW1lc2VyaWVzLCBpbmNsdWRlPSBUUlVFLGVjaG89VFJVRX0KQkdOX0RBVEVQIDwtIGFzLlBPU0lYY3QodW5saXN0KHRtRXZlbnRGdGxJbmokQkdOX0RBVEUpLCB0eiA9ICJHTVQiKQpCR05fTU9OVEggPC0gc3RyZnRpbWUoQkdOX0RBVEVQLCAiJW0iKQpCR05fWUVBUiA8LSBzdHJmdGltZShCR05fREFURVAsICIlWSIpCkJHTl9EQVRFUyA8LSBkYXRhLmZyYW1lKEJHTl9NT05USCxCR05fWUVBUixCR05fREFURVApCnRtZXZlbnRTZXJpZXMgPC0gY2JpbmQoQkdOX0RBVEVTICx0bUV2ZW50RnRsSW5qKQoKdG1TZXJpZXNBZ0YgPC0gYWdncmVnYXRlKEZBVEFMSVRJRVN+IEJHTl9NT05USCsgQkdOX1lFQVIsIHRtZXZlbnRTZXJpZXMsIEZVTiA9IHN1bSkKdG1TZXJpZXNBZ0kgPC0gYWdncmVnYXRlKElOSlVSSUVTfiBCR05fTU9OVEgrIEJHTl9ZRUFSLCB0bWV2ZW50U2VyaWVzLCBGVU4gPSBzdW0pCnRtU2VyaWVzQWcgPC0gbWVyZ2UodG1TZXJpZXNBZ0YsdG1TZXJpZXNBZ0ksIGJ5ID0gYygiQkdOX01PTlRIIiwgIkJHTl9ZRUFSIikpCnRtU2VyaWVzQWckTU9ZUiA8LSBhcy5QT1NJWGN0KHBhc3RlKHRtU2VyaWVzQWckQkdOX1lFQVIsIHRtU2VyaWVzQWckQkdOX01PTlRILCAiMDEiLCBzZXAgPSAiLSIpKQojcGxvdCh0bVNlcmllc0FnJE1PWVJbb3JkZXIodG1TZXJpZXNBZyRNT1lSKV0sIHRtU2VyaWVzQWckSU5KVVJJRVMsIGNvbCA9ICJncmVlbiIsIHR5cGUgPSAibCIscGNoID0gMjAKIyAgICAgICAsIHhsYWIgPSAiRXZlbnQgRGF0ZSIsIHlsYWIgPSAiUXR5IG9mIFBlb3BsZSIpCiMgbGluZXModG1TZXJpZXNBZyRNT1lSW29yZGVyKHRtU2VyaWVzQWckTU9ZUildLHRtU2VyaWVzQWckRkFUQUxJVElFUywgY29sID0gInJlZCIsdHlwZSA9ICJsIiwgcGNoID0gMjApCiAKICNwYXIobWZyb3c9YygxLDIpLCBtYWkgPSBjKC41LCAuNSwgMC4yLCAwLjEpKQogcGFyKG1mcm93PWMoMiwxKSwgbWFpID0gYygwLjgwLCAwLjgwLCAwLjIsIDAuMSkpCiBwbG90KHRtU2VyaWVzQWckTU9ZUltvcmRlcih0bVNlcmllc0FnJE1PWVIpXSwgdG1TZXJpZXNBZyRJTkpVUklFUywgY29sID0gImRvZGdlciBibHVlIiwgdHlwZSA9ICJsIixwY2ggPSAyMAogICAgICAgLCB4bGFiID0gIiIsIHlsYWIgPSAiTnVtYmVyIEluanVyaWVzIikKIHBsb3QodG1TZXJpZXNBZyRNT1lSW29yZGVyKHRtU2VyaWVzQWckTU9ZUildLCB0bVNlcmllc0FnJEZBVEFMSVRJRVMsIGNvbCA9ICJncmVlbiIsIHR5cGUgPSAibCIscGNoID0gMjAKICAgICAgICwgeGxhYiA9ICJFdmVudCBEYXRlIiwgeWxhYiA9ICJOdW1iZXIgRmF0YWxpdGllcyIpCiAjcGxvdCh0bVNlcmllc0FnJE1PWVJbb3JkZXIodG1TZXJpZXNBZyRNT1lSKV0sIHRtU2VyaWVzQWckSU5KVVJJRVMsIGNvbCA9ICJncmVlbiIsIHR5cGUgPSAibCIscGNoID0gMjAKIyAgICAgICAsIHhsYWIgPSAiRXZlbnQgRGF0ZSIsIHlsYWIgPSAiSW5qdXJpZXMgYW5kIEZhdGFsaXRpZXMiKQojIGxpbmVzKHRtU2VyaWVzQWckTU9ZUltvcmRlcih0bVNlcmllc0FnJE1PWVIpXSx0bVNlcmllc0FnJEZBVEFMSVRJRVMsIGNvbCA9ICJyZWQiLHR5cGUgPSAibCIsIHBjaCA9IDIwKQogCiBtdGV4dCgiRmF0YWxpdGllcyBhbmQgSW5qdXJpZXMiLCBzaWRlPTMsIG91dGVyPVRSVUUsIGxpbmU9LTEsIGNvbCA9ICJibHVlIixmb250ID0gMikgCgpgYGAKCgpUaGlzIHBsb3QgcHJlc2VudHMgdG9wIDEwIGNvc3RseSBldmVudHMuCmBgYHtyIGRhbWFnZXBsb3QsIGluY2x1ZGU9IFRSVUUsIGVjaG8gPSBUUlVFfQpwbCA8LSBoZWFkKGV2ZW50RG1nUHJwW29yZGVyKGV2ZW50RG1nUHJwJFRPVExETUcsIGRlY3JlYXNpbmcgPSBUUlVFKSxdLDEwKQpwbCRUT1RMRE1HIDwtIGFzLm51bWVyaWMocGwkVE9UTERNRykKcGwkRVZUWVBFIDwtIGZhY3RvcihwbCRFVlRZUEUpCiNwbG90KHBsJEVWVFlQRSwocGwkVE9UTERNRy8xMDAwKSwgdHlwZSA9ICJoIiwgeGxhYiA9ICJFVlRZUEUiLCB5bGFiID0gIlRvdGFsIERhbWFnZSBBbW91bnQiKQoKbGlicmFyeShnZ3Bsb3QyKQogZ2dwbG90KHBsLCBhZXMoeD1yZW9yZGVyKEVWVFlQRSwgLVRPVExETUcpLCB5PWZvcm1hdChUT1RMRE1HLCBzY2llbnRpZmljID0gRkFMU0UpLCBncm91cD0xKSkgKwogICAgICAgICAgZ2d0aXRsZSgiVG9wIDEwIENvc3RseSBFdmVudHMiKSsKICAgICAgICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gIiMwMDk5RkYiKSsgCiAgICAgICAgICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICxheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoZmFjZT0iYm9sZCIsIHNpemU9MTIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAsbGVnZW5kLnBvc2l0aW9uPSJub25lIikrIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJzKHg9IkV2ZW50IFR5cGUiLHk9IkRhbWFnZSBBbW91bnQgKDAwMCdzKSIpIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKIyBwbG90KGFjdGl2aXR5V2tlbmQkaW50ZXJ2YWwsIGFjdGl2aXR5V2tlbmQkYXZnU3RlcHMsIHR5cGUgPSAibCIseGxhYiA9ICJpbnRlcnZhbCIsIHlsYWIgPSAiV2tFbmQgQXZnIFN0ZXBzIikKYGBgCgoKVGhpcyBwbG90IGRpc3BsYXlzIHRoZSB0b3AgMTAgb2NjdXJpbmcgZXZlbnRzIApgYGB7ciBkYW1hZ2VxdHksIGluY2x1ZGUgPSBUUlVFLCBlY2hvID0gVFJVRX0KZG0gPC0gaGVhZChldmVudERhbWFnW29yZGVyKGV2ZW50RGFtYWckUXR5LCBkZWNyZWFzaW5nID0gVFJVRSksXSwxMCkKZG0kUXR5IDwtIGFzLm51bWVyaWMoZG0kUXR5KQpkbSRFVlRZUEUgPC0gZmFjdG9yKGRtJEVWVFlQRSkKI3Bsb3QocGwkRVZUWVBFLChwbCRUT1RMRE1HLzEwMDApLCB0eXBlID0gImgiLCB4bGFiID0gIkVWVFlQRSIsIHlsYWIgPSAiVG90YWwgRGFtYWdlIEFtb3VudCIpCgpsaWJyYXJ5KGdncGxvdDIpCmdncGxvdChkbSwgYWVzKHg9cmVvcmRlcihFVlRZUEUsIC1RdHkpLCB5PWZvcm1hdChRdHksIHNjaWVudGlmaWMgPSBGQUxTRSksIGdyb3VwPTEpKSArIAogICAgICAgICAgICBnZ3RpdGxlKCJUb3AgMTAgRnJlcXVlbnQgRXZlbnRzIikrCiAgICAgICAgICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gIiMwMDk5RkYiKSsgCiAgICAgICAgICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICxheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoZmFjZT0iYm9sZCIsIHNpemU9MTIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAsbGVnZW5kLnBvc2l0aW9uPSJub25lIikrCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYnMoeD0iRXZlbnQgVHlwZSIseT0iRXZlbnQgRnJlcXVlbmN5IikgCmBgYAoKClRoaXMgZGVwaWN0cyB0aGF0IHRoZSBtb3N0IGZyZXF1ZW50IHR5cGVzIGByIGV2ZW50RGFtYWdbMSwxXWAgYXQgYHIgZXZlbnREYW1hZ1sxLDJdYCBhbmQgYHIgZXZlbnREYW1hZ1tucm93KGV2ZW50RGFtYWcpLDFdYCBhdCBgciBldmVudERhbWFnW25yb3coZXZlbnREYW1hZyksMl1gIGFyZSBub3QgdGhlIG1vc3QgZnJlcXVlbnQuCgoKYHIgZnRsWzEsMV1gIGV2ZW50IGlzIHRoZSB0b3AgZXZlbnQgY2F1c2luZyBmYXRhbGl0aWVzIGF0IGByIGZ0bFsxLDNdYCBmYXRhbGl0aWVzLiBgciBmdGxbbnJvdyhmdGwpLDFdYCBpcyB0aGUgZXZlbnQgd2l0aCB0aGUgbGVhc3QgbnVtYmVyIG9mIGZhdGFsaXRpZXMgYXQgYHIgZnRsW25yb3coZnRsKSwzXWAKClRoaXMgdGFibGUgZGlzcGxheWVzIHRoZSB0b3AgdGVuIGV2ZW50cyB0aGF0IGFyZSBtb3N0IGZyZXF1ZW50LiBgciBoZWFkKGRtJEVWVFlQRSwxKWAgaXMgdGhlIGV2ZW50IHRoYXQgb2NjdXJzIHRoZSBtb3N0IGF0IGByIGZvcm1hdChoZWFkKGRtJFF0eSwxKSwgc2NpZW50aWZpYyA9IEZBTFNFKWAgbnVtYmVyIG9mIGV2ZW50cy4gYHIgZG1bMTAsMV1gIGlzIHRoZSBsZWFzdCB0b3AgZnJlcXVlbnQgb2NjdXJpbmcgZXZlbnQgY29taW5nIGF0IGByIGZvcm1hdChkbVsxMCwyXSwgc2NpZW50aWZpYyA9IEZBTFNFKWAgbnVtYmVyIG9mIGV2ZW50cy4KCgojIyMgU291cmNlIENpdGF0aW9uIGFuZCBSZXNvdXJjZToKICAgIE5BVElPTkFMIFdFQVRIRVIgU0VSVklDRSBJTlNUUlVDVElPTiAgMTAtMTYwNSAKICAgIEFVR1VTVCAxNywgMjAwNyAKICAgIE9wZXJhdGlvbnMgYW5kIFNlcnZpY2VzIAogICAgUGVyZm9ybWFuY2UsIE5XU1BEIDEwLTE2CiAgICBTVE9STSBEQVRBIFBSRVBBUkFUSU9OCgoKICAgIFN0b3JtIERhdGEgRG9jdW1lbnRhdGlvbjogaHR0cHM6Ly9kMzk2cXVzemE0MG9yYy5jbG91ZGZyb250Lm5ldC9yZXBkYXRhJTJGcGVlcjJfZG9jJTJGcGQwMTAxNjAwNWN1cnIucGRmCiAgICBGQVE6IGh0dHBzOi8vZDM5NnF1c3phNDBvcmMuY2xvdWRmcm9udC5uZXQvcmVwZGF0YSUyRnBlZXIyX2RvYyUyRk5DREMlMjBTdG9ybSUyMEV2ZW50cy1GQVElMjBQYWdlLnBkZgogICAgCiMjCg==