Crime Statistics in the United States, 1979 - 2019

Introduction

Crime and Policing have a long and complex history in the United States. In this project we examine trends in different categories of crime since 1979.

Crime has tended to decrease over time in the United States, all the way back to Colonial times, however there have been intermitent disruptions to this trend. In particular, violent crime rates increased from the 1960s, and peaked in the early 1990s. In this project we will examine trends in different categories of crime since 1979. In particular, we will focus on the violent crime spike of the 1990s to try and develop a deeper understanding of events.

Description of Data

We will be examining the following U.S. Crimes dataset from Kaggle.com:

https://www.kaggle.com/tunguz/us-estimated-crimes

This data is derived from the FBI Summary Reporting System. It reflects the estimates that the FBI has traditionally included in its annual publications.

The dataset includes the following columns:

  • year

  • population

  • state_abbr

  • state_name

as well as yearly state-by-state and nationwide counts, from 1979-2019, for occurrences of crimes in the following categories:

  • violent crime

  • homicide

  • rape_legacy($)

  • rape_revised($)

  • robbery

  • aggravated_assault

  • property crime

  • burglary

  • larceny

  • motor_vehicle_theft

$ - In 2013, the FBI updated its working definition of rape from a “forcible” act to and act performed “without consent”. For more information see: https://ucr.fbi.gov/crime-in-the-u.s/2018/crime-in-the-u.s.-2018/topic-pages/rape

Preprocessing

library(tidyverse)
library(ggthemes)
library(scales)
library(RColorBrewer)
library(tools)
us_crimes <- readr::read_csv("estimated_crimes_1979_2019.csv")

The file has NA for the name and abbreviation columns for rows corresponding to the whole country, so we’ll fill that in:

us_crimes <- us_crimes %>% mutate(state_name = ifelse((is.na(state_name)), "United States", state_name))
us_crimes <- us_crimes %>% mutate(state_abbr = ifelse((is.na(state_abbr)), "US", state_abbr))

Where else is data missing?

sum(is.na(us_crimes$violent_crime))
[1] 0
sum(is.na(us_crimes$homicide))
[1] 0
sum(is.na(us_crimes$rape_legacy))
[1] 156
sum(is.na(us_crimes$rape_revised))
[1] 2116
sum(is.na(us_crimes$robbery))
[1] 0
sum(is.na(us_crimes$aggravated_assault))
[1] 0
sum(is.na(us_crimes$property_crime))
[1] 0
sum(is.na(us_crimes$burglary))
[1] 0
sum(is.na(us_crimes$larceny))
[1] 0
sum(is.na(us_crimes$motor_vehicle_theft))
[1] 0

Since the FBI updated its definition of rape, there are missing entries for these columns for years for which the definition was not in effect.

Rape statistics are also missing from 2017 onward:

us_crimes %>%
  select(year, rape_legacy, rape_revised) %>%
  filter(!((is.na(rape_legacy)) & (is.na(rape_revised)))) %>%
  arrange(desc(year)) %>%
  head(1)

With all that being said, this report will for the most part not be focused on the rape statistics. I do think that analyzing the consequences of this change would have made a great topic for the investigation; I was simply not aware of it when I began researching. However, I will definitely keep it in mind for a future project.

The dataset gives us total counts and the population, so we will divide these quantities to get the rate-per-person corresponding to each annual crime tally.

Divide by population to compute rates:

us_crimes <- us_crimes %>%
  mutate("aggravated_assault_rate" = aggravated_assault / population,
         "property_crime_rate" = property_crime / population,
         "violent_crime_rate" = violent_crime / population,
         "robbery_rate" = robbery / population,
         "motor_vehicle_theft_rate" = motor_vehicle_theft / population,
         "larceny_rate" = larceny / population,
         "homicide_rate" = homicide / population,
         "burglary_rate" = burglary / population,
         "rape_legacy_rate" = rape_legacy / population,
         "rape_revised_rate" = rape_revised / population)

We’ll look at this in tableau later, so we’ll save a new .csv file with the extra columns:

readr::write_csv(us_crimes, "us_crimes_with_rates.csv")

Exploratory plots

US Population 1979 - 2019

The population of the United States changed dramatically over the last few decades. Let’s take a quick look at how it changed, to put our data in a broader context:

whole_country <- us_crimes %>%
  filter(state_name != "United States") %>%
  group_by(year) %>%
  summarise(total_population = sum(population))

Here is how the population of the United States has changed since 1979:

whole_country %>%
  ggplot(aes(x = year, y = total_population)) +
  geom_line() +
  labs(title = "U.S. Population 1979-2019") +
  ylab("Population") +
  xlab("Year") +
  theme(plot.title = element_text(hjust = 0.5)) +
  theme_hc()

The population has increased substantially over the range of data in this set. It is interesting to note that decreasing crime rates have coincided with an increasing population. All else being equal, one might guess the opposite would be the case.

Incidence and Rate of Crime by Category

Let us now examine the trends in rates of each category of crime in the dataset:

whole_country_long <- us_crimes %>%
  filter(state_name != "United States") %>%
  pivot_longer(names_to = "category",
               values_to = "count",
               cols = c("violent_crime",
                        "homicide",
                        "rape_legacy",
                        "rape_revised",
                        "robbery",
                        "aggravated_assault",
                        "burglary",
                        "larceny",
                        "motor_vehicle_theft"))
whole_country_long <- whole_country_long %>%
  mutate(category = toTitleCase(str_replace_all(category, "_", " ")))
whole_country_long %>%
  ggplot(aes(x = year, y = count)) +
  geom_line(aes(group = category, color = category), stat = 'summary', size = 1.5) +
  labs(title = "U.S. Crime Incidents By Category, 19279 - 2019") +
  ylab("Total (raw count)") +
  scale_color_brewer(palette = "RdYlGn", name = "Category") +
  theme_hc()

We can observe a few things from this plot. Larceny and burglary have occurred consistently at higher numbers than violent crimes, which is perhaps not so surprising. Larceny is categorically more common than all other crimes across the years in our data, and has also decreased substantially since 1990.

However, if we focus on the line for violent crime, we can see that this category has been relatively consistent across the years in our data. Though it has decreased from the peak in the 1990s, it appears to have remained at the same rate or even increased slightly overall over the years.

whole_country_rates_long <- us_crimes %>%
  filter(state_name != "United States") %>%
  pivot_longer(names_to = "category",
               values_to = "rate",
               cols = c(
                        "violent_crime_rate",
                        "homicide_rate",
                        "rape_legacy_rate",
                        "rape_revised_rate",
                        "robbery_rate",
                        "aggravated_assault_rate",
                        "burglary_rate",
                        "larceny_rate",
                        "motor_vehicle_theft_rate"))

Plotting the rates over time for each category:

whole_country_rates_long <- whole_country_rates_long %>%
  mutate(category = toTitleCase(str_replace_all(category, "_", " ")))
whole_country_rates_long %>%
  ggplot(aes(x = year, y = rate)) +
  labs(title = "U.S. Crime Incidents By Category, 1979 - 2019") +
  ylab("Rate (per capita)") +
  geom_line(aes(group = category, color = category), stat = 'summary', size = 1.5) +
  scale_color_brewer(palette = "RdYlGn", name = "Category") +
  theme_hc()

This is similar to the last plot, but looking at the rates makes it a bit more clear that larceny and burglary have really trended down significantly over these years. The peak in violent crime in the 1990s is also a bit more obvious when looking at the rates as opposed to the counts.

Let’s visualize things from a slightly different perspective. Here is the bar chart of all crimes of each category in this dataset, for the whole dataset and time period:

whole_country_long %>%
  group_by(category) %>%
  summarise(total = sum(count)) %>%
  select(category, total) %>%
  ggplot(aes(x = category, y = total)) +
  geom_bar(stat="Identity", fill = "cadetblue4", color = "cadetblue4") +
  labs(title = "U.S. Crime Incidents By Category, 19279 - 2019 (total)") +
  ylab("Total (raw count)") +
  xlab("Category") +
  theme(axis.text.x = element_text(angle = 45, vjust = 0.5) ) + 
  theme_hc()

Violent Crime in the United States, 2015-2019

Histogram of States’ Average Violent Crime Rate, 2015-2019

It is important to understand the trends that have been taking place in our country, but we may also be interested in what is going on more recently. Let’s look at which states had the most violent crime over the last five years in the set; 2015-2019

violent_crime_last_5_years <- us_crimes %>%
  select(year, state_name, violent_crime_rate) %>%
  filter(year >= 2015) %>%
  filter(!(is.na(state_name))) %>%
  filter(state_name != "United States")

We will plot the average rate of violent crime over the five year period for all 50 states as a histogram:

last_5_dist <- violent_crime_last_5_years %>%
  group_by(state_name) %>%
  summarise(avg = mean(violent_crime_rate))

last_5_dist %>%
  ggplot(aes(x = avg)) +
  geom_histogram(bins = 15, fill = "cadetblue3", color = "cadetblue4") +
  labs(title = "Average Violent Crime Rate per State, 2015-2019") +
  ylab("No. of States") +
  xlab("Violent Crime Rate") + 
  theme_hc()

NA

Distribution and Outlier Analysis

The distribution is somewhat close to normal, but noticeably right-skewed.

Let’s see what the top states are:

last_5_dist %>%
  arrange(desc(avg))

Let’s see if D.C. and the other top states are outliers:

summary(last_5_dist$avg)
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
0.001203 0.002683 0.003633 0.003855 0.004564 0.011052 
Q3 <- 0.004564
Q1 <- 0.002683
IQR <- Q3 - Q1

lf <- Q1 - 1.5*IQR
uf <- Q3 + 1.5*IQR
lf
[1] -0.0001385
uf
[1] 0.0073855

D.C., Alaska, and New Mexico are all statistical outliers for violent crime over the last five years. In my opinion, D.C. does not really belong in this analysis because it is only one city. I suspect that while we observe very high crime rates in D.C. compared to the other states, we may see similar rates in say, Los Angeles and New York City as opposed to California and New York.

On the other hand, Alaska and New Mexico do not even include large urban centers, so I was initially surprised by this result. What I found upon researching it a bit is that violent crime rates are especially high among the Native American population; a very serious issue that seems to receive unfortunately little attention from the media and political leadership. [1]

Visualizing U.S. Violent Crime with Tableau

The following interactive tableau visualization shows quantity and rate of violent crime incidents for each state in the dataset.

https://public.tableau.com/profile/daniel.lefevre#!/vizhome/Data110Final2/Dashboard1

Looking at all states, we can easily identify DC as the outlier in terms of rate, and we can also see that it accounted for a relatively small overall quantity of violent crimes which took place.

We can turn individual states on and off using the filter on the right. Here is DC vs. New York for the years in the dataset:

Thoughts and Summary

I was aware going into this ahead of time that violent crime had decreased since the middle of the century, and that violent crime had a peak in the 1990’s. Still, as with many of these projects, I find it interesting to see these trends in a more concrete way.

One question that came to me while working on the project is: why are drug crimes not included in the dataset? If I had thought of this earlier in the project, I might have tried to access the SRS directly and see if the data was simply left out from the dataset or what the explanation is there. It is fairly well known that the U.S. prison population has grown drastically over the last few decades. In fact, our incarcerated population increased by a factor of about 7 from 1980 to 2018.[3] It seems difficult to square a decrease in crime with a drastic increase in the prison population.

In this project, we looked at crime statistics in the USA from 1979 to 2019. We focused mainly on violent crime, and examined the distribution of events as well as the surge in violent crime during the 1990s. We found that while Washington D.C. is a statistical outlier in terms of crime rate and was especially so during the early-to-mid nineties, the surge in violence largely occurred in states like California, New York, and a few others.

I also learned about violence among Native American populations, which is a very complex and tragic issue. I may try to investigate this as another topic for future research.

One thing I struggled with during this project was that I wanted to show the y- axis of the population charts in “00 million” format instead of scientific notation. I tried to figure this out for quite some time but could not get it to work. I also would have liked to display the state names on the tiles in the Tableau visualization, but it seemed that the issue here was just that the tiles are too small and Tableau will not show the label.

[1] https://www.lifedaily.com/story/high-crime-rates-ignored-cases-us-indian-reservation-force-residents-take-action/

[2] https://ucr.fbi.gov/crime-in-the-u.s/2013/crime-in-the-u.s.-2013/violent-crime/rape

[3] https://www.sentencingproject.org/wp-content/uploads/2020/08/Trends-in-US-Corrections.pdf

LS0tCnRpdGxlOiAiREFUQSAxMTAgLSBGaW5hbCBQcm9qZWN0IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojIENyaW1lIFN0YXRpc3RpY3MgaW4gdGhlIFVuaXRlZCBTdGF0ZXMsIDE5NzkgLSAyMDE5CgojIyBJbnRyb2R1Y3Rpb24KCkNyaW1lIGFuZCBQb2xpY2luZyBoYXZlIGEgbG9uZyBhbmQgY29tcGxleCBoaXN0b3J5IGluIHRoZSBVbml0ZWQgU3RhdGVzLiBJbiAKdGhpcyBwcm9qZWN0IHdlIGV4YW1pbmUgdHJlbmRzIGluIGRpZmZlcmVudCBjYXRlZ29yaWVzIG9mIGNyaW1lIHNpbmNlIDE5NzkuCgpDcmltZSBoYXMgdGVuZGVkIHRvIGRlY3JlYXNlIG92ZXIgdGltZSBpbiB0aGUgVW5pdGVkIFN0YXRlcywgYWxsIHRoZSB3YXkgYmFjayB0byAKQ29sb25pYWwgdGltZXMsIGhvd2V2ZXIgdGhlcmUgaGF2ZSBiZWVuIGludGVybWl0ZW50IGRpc3J1cHRpb25zIHRvIHRoaXMgdHJlbmQuIApJbiBwYXJ0aWN1bGFyLCB2aW9sZW50IGNyaW1lIHJhdGVzIGluY3JlYXNlZCBmcm9tIHRoZSAxOTYwcywgYW5kIHBlYWtlZCBpbiB0aGUgCmVhcmx5IDE5OTBzLiBJbiB0aGlzIHByb2plY3Qgd2Ugd2lsbCBleGFtaW5lIHRyZW5kcyBpbiBkaWZmZXJlbnQgY2F0ZWdvcmllcyBvZgpjcmltZSBzaW5jZSAxOTc5LiBJbiBwYXJ0aWN1bGFyLCB3ZSB3aWxsIGZvY3VzIG9uIHRoZSB2aW9sZW50IGNyaW1lIHNwaWtlIG9mIAp0aGUgMTk5MHMgdG8gdHJ5IGFuZCBkZXZlbG9wIGEgZGVlcGVyIHVuZGVyc3RhbmRpbmcgb2YgZXZlbnRzLgoKIyMgRGVzY3JpcHRpb24gb2YgRGF0YQoKV2Ugd2lsbCBiZSBleGFtaW5pbmcgdGhlIGZvbGxvd2luZyBVLlMuIENyaW1lcyBkYXRhc2V0IGZyb20gS2FnZ2xlLmNvbToKCmh0dHBzOi8vd3d3LmthZ2dsZS5jb20vdHVuZ3V6L3VzLWVzdGltYXRlZC1jcmltZXMKClRoaXMgZGF0YSBpcyBkZXJpdmVkIGZyb20gdGhlIEZCSSBTdW1tYXJ5IFJlcG9ydGluZyBTeXN0ZW0uIEl0IHJlZmxlY3RzIHRoZSAKZXN0aW1hdGVzIHRoYXQgdGhlIEZCSSBoYXMgdHJhZGl0aW9uYWxseSBpbmNsdWRlZCBpbiBpdHMgYW5udWFsIHB1YmxpY2F0aW9ucy4KClRoZSBkYXRhc2V0IGluY2x1ZGVzIHRoZSBmb2xsb3dpbmcgY29sdW1uczoKCjxiPgoKKiB5ZWFyCgoqIHBvcHVsYXRpb24KCiogc3RhdGVfYWJicgoKKiBzdGF0ZV9uYW1lCgo8L2I+CgphcyB3ZWxsIGFzIHllYXJseSBzdGF0ZS1ieS1zdGF0ZSBhbmQgbmF0aW9ud2lkZSBjb3VudHMsIGZyb20KMTk3OS0yMDE5LCBmb3Igb2NjdXJyZW5jZXMgb2YgY3JpbWVzIGluIHRoZSBmb2xsb3dpbmcgY2F0ZWdvcmllczoKCjxiPgoKKiB2aW9sZW50IGNyaW1lCgoqIGhvbWljaWRlCgoqIHJhcGVfbGVnYWN5KCQpCgoqIHJhcGVfcmV2aXNlZCgkKQoKKiByb2JiZXJ5CgoqIGFnZ3JhdmF0ZWRfYXNzYXVsdAoKKiBwcm9wZXJ0eSBjcmltZQoKKiBidXJnbGFyeQoKKiBsYXJjZW55CgoqIG1vdG9yX3ZlaGljbGVfdGhlZnQKCjwvYj4KCiQgLSBJbiAyMDEzLCB0aGUgRkJJIHVwZGF0ZWQgaXRzIHdvcmtpbmcgZGVmaW5pdGlvbiBvZiAqcmFwZSogZnJvbSBhICJmb3JjaWJsZSIgCmFjdCB0byBhbmQgYWN0IHBlcmZvcm1lZCAid2l0aG91dCBjb25zZW50Ii4gRm9yIG1vcmUgaW5mb3JtYXRpb24gc2VlOiAKaHR0cHM6Ly91Y3IuZmJpLmdvdi9jcmltZS1pbi10aGUtdS5zLzIwMTgvY3JpbWUtaW4tdGhlLXUucy4tMjAxOC90b3BpYy1wYWdlcy9yYXBlCgojIyBQcmVwcm9jZXNzaW5nCgpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShnZ3RoZW1lcykKbGlicmFyeShzY2FsZXMpCmxpYnJhcnkoUkNvbG9yQnJld2VyKQpsaWJyYXJ5KHRvb2xzKQpgYGAKCmBgYHtyLCBtZXNzYWdlID0gRiwgd2FybmluZz1GQUxTRX0KdXNfY3JpbWVzIDwtIHJlYWRyOjpyZWFkX2NzdigiZXN0aW1hdGVkX2NyaW1lc18xOTc5XzIwMTkuY3N2IikKYGBgCgpUaGUgZmlsZSBoYXMgTkEgZm9yIHRoZSBuYW1lIGFuZCBhYmJyZXZpYXRpb24gY29sdW1ucyBmb3Igcm93cyBjb3JyZXNwb25kaW5nIHRvCnRoZSB3aG9sZSBjb3VudHJ5LCBzbyB3ZSdsbCBmaWxsIHRoYXQgaW46CgpgYGB7cn0KdXNfY3JpbWVzIDwtIHVzX2NyaW1lcyAlPiUgbXV0YXRlKHN0YXRlX25hbWUgPSBpZmVsc2UoKGlzLm5hKHN0YXRlX25hbWUpKSwgIlVuaXRlZCBTdGF0ZXMiLCBzdGF0ZV9uYW1lKSkKdXNfY3JpbWVzIDwtIHVzX2NyaW1lcyAlPiUgbXV0YXRlKHN0YXRlX2FiYnIgPSBpZmVsc2UoKGlzLm5hKHN0YXRlX2FiYnIpKSwgIlVTIiwgc3RhdGVfYWJicikpCmBgYAoKV2hlcmUgZWxzZSBpcyBkYXRhIG1pc3Npbmc/CgpgYGB7cn0Kc3VtKGlzLm5hKHVzX2NyaW1lcyR2aW9sZW50X2NyaW1lKSkKc3VtKGlzLm5hKHVzX2NyaW1lcyRob21pY2lkZSkpCnN1bShpcy5uYSh1c19jcmltZXMkcmFwZV9sZWdhY3kpKQpzdW0oaXMubmEodXNfY3JpbWVzJHJhcGVfcmV2aXNlZCkpCnN1bShpcy5uYSh1c19jcmltZXMkcm9iYmVyeSkpCnN1bShpcy5uYSh1c19jcmltZXMkYWdncmF2YXRlZF9hc3NhdWx0KSkKc3VtKGlzLm5hKHVzX2NyaW1lcyRwcm9wZXJ0eV9jcmltZSkpCnN1bShpcy5uYSh1c19jcmltZXMkYnVyZ2xhcnkpKQpzdW0oaXMubmEodXNfY3JpbWVzJGxhcmNlbnkpKQpzdW0oaXMubmEodXNfY3JpbWVzJG1vdG9yX3ZlaGljbGVfdGhlZnQpKQoKYGBgCgpTaW5jZSB0aGUgRkJJIHVwZGF0ZWQgaXRzIGRlZmluaXRpb24gb2YgcmFwZSwgdGhlcmUgYXJlIG1pc3NpbmcgZW50cmllcyBmb3IgCnRoZXNlIGNvbHVtbnMgZm9yIAp5ZWFycyBmb3Igd2hpY2ggdGhlIGRlZmluaXRpb24gd2FzIG5vdCBpbiBlZmZlY3QuCgpSYXBlIHN0YXRpc3RpY3MgYXJlIGFsc28gbWlzc2luZyBmcm9tIDIwMTcgb253YXJkOgoKYGBge3J9CnVzX2NyaW1lcyAlPiUKICBzZWxlY3QoeWVhciwgcmFwZV9sZWdhY3ksIHJhcGVfcmV2aXNlZCkgJT4lCiAgZmlsdGVyKCEoKGlzLm5hKHJhcGVfbGVnYWN5KSkgJiAoaXMubmEocmFwZV9yZXZpc2VkKSkpKSAlPiUKICBhcnJhbmdlKGRlc2MoeWVhcikpICU+JQogIGhlYWQoMSkKYGBgCgpXaXRoIGFsbCB0aGF0IGJlaW5nIHNhaWQsIHRoaXMgcmVwb3J0IHdpbGwgZm9yIHRoZSBtb3N0IHBhcnQgbm90IGJlIGZvY3VzZWQgb24gCnRoZSByYXBlIHN0YXRpc3RpY3MuIEkgZG8gdGhpbmsgdGhhdCBhbmFseXppbmcgdGhlIGNvbnNlcXVlbmNlcyBvZiB0aGlzIGNoYW5nZQp3b3VsZCBoYXZlIG1hZGUgYSBncmVhdCB0b3BpYyBmb3IgdGhlIAppbnZlc3RpZ2F0aW9uOyBJIHdhcyBzaW1wbHkgbm90IGF3YXJlIG9mIGl0IHdoZW4gSSAKYmVnYW4gcmVzZWFyY2hpbmcuIEhvd2V2ZXIsIEkgd2lsbCBkZWZpbml0ZWx5IGtlZXAgaXQgaW4gbWluZCBmb3IgYSBmdXR1cmUgCnByb2plY3QuCgoKVGhlIGRhdGFzZXQgZ2l2ZXMgdXMgdG90YWwgY291bnRzIGFuZCB0aGUgcG9wdWxhdGlvbiwgc28gd2Ugd2lsbCBkaXZpZGUgdGhlc2UgCnF1YW50aXRpZXMgdG8gZ2V0IHRoZSByYXRlLXBlci1wZXJzb24gY29ycmVzcG9uZGluZyB0byBlYWNoIGFubnVhbCBjcmltZSB0YWxseS4KCkRpdmlkZSBieSBwb3B1bGF0aW9uIHRvIGNvbXB1dGUgcmF0ZXM6CgpgYGB7cn0KdXNfY3JpbWVzIDwtIHVzX2NyaW1lcyAlPiUKICBtdXRhdGUoImFnZ3JhdmF0ZWRfYXNzYXVsdF9yYXRlIiA9IGFnZ3JhdmF0ZWRfYXNzYXVsdCAvIHBvcHVsYXRpb24sCiAgICAgICAgICJwcm9wZXJ0eV9jcmltZV9yYXRlIiA9IHByb3BlcnR5X2NyaW1lIC8gcG9wdWxhdGlvbiwKICAgICAgICAgInZpb2xlbnRfY3JpbWVfcmF0ZSIgPSB2aW9sZW50X2NyaW1lIC8gcG9wdWxhdGlvbiwKICAgICAgICAgInJvYmJlcnlfcmF0ZSIgPSByb2JiZXJ5IC8gcG9wdWxhdGlvbiwKICAgICAgICAgIm1vdG9yX3ZlaGljbGVfdGhlZnRfcmF0ZSIgPSBtb3Rvcl92ZWhpY2xlX3RoZWZ0IC8gcG9wdWxhdGlvbiwKICAgICAgICAgImxhcmNlbnlfcmF0ZSIgPSBsYXJjZW55IC8gcG9wdWxhdGlvbiwKICAgICAgICAgImhvbWljaWRlX3JhdGUiID0gaG9taWNpZGUgLyBwb3B1bGF0aW9uLAogICAgICAgICAiYnVyZ2xhcnlfcmF0ZSIgPSBidXJnbGFyeSAvIHBvcHVsYXRpb24sCiAgICAgICAgICJyYXBlX2xlZ2FjeV9yYXRlIiA9IHJhcGVfbGVnYWN5IC8gcG9wdWxhdGlvbiwKICAgICAgICAgInJhcGVfcmV2aXNlZF9yYXRlIiA9IHJhcGVfcmV2aXNlZCAvIHBvcHVsYXRpb24pCmBgYAoKV2UnbGwgbG9vayBhdCB0aGlzIGluIHRhYmxlYXUgbGF0ZXIsIHNvIHdlJ2xsIHNhdmUgYSBuZXcgLmNzdiBmaWxlIHdpdGggdGhlIApleHRyYSBjb2x1bW5zOgoKYGBge3J9CnJlYWRyOjp3cml0ZV9jc3YodXNfY3JpbWVzLCAidXNfY3JpbWVzX3dpdGhfcmF0ZXMuY3N2IikKYGBgCgojIyBFeHBsb3JhdG9yeSBwbG90cwoKIyMjIFVTIFBvcHVsYXRpb24gMTk3OSAtIDIwMTkKClRoZSBwb3B1bGF0aW9uIG9mIHRoZSBVbml0ZWQgU3RhdGVzIGNoYW5nZWQgZHJhbWF0aWNhbGx5IG92ZXIgdGhlIGxhc3QgZmV3IApkZWNhZGVzLiBMZXQncyB0YWtlIGEgcXVpY2sgbG9vayBhdCBob3cgaXQgY2hhbmdlZCwgdG8gcHV0IG91ciBkYXRhIGluIGEgCmJyb2FkZXIgY29udGV4dDoKCmBgYHtyfQp3aG9sZV9jb3VudHJ5IDwtIHVzX2NyaW1lcyAlPiUKICBmaWx0ZXIoc3RhdGVfbmFtZSAhPSAiVW5pdGVkIFN0YXRlcyIpICU+JQogIGdyb3VwX2J5KHllYXIpICU+JQogIHN1bW1hcmlzZSh0b3RhbF9wb3B1bGF0aW9uID0gc3VtKHBvcHVsYXRpb24pKQpgYGAKCkhlcmUgaXMgaG93IHRoZSBwb3B1bGF0aW9uIG9mIHRoZSBVbml0ZWQgU3RhdGVzIGhhcyBjaGFuZ2VkIHNpbmNlIDE5Nzk6CgpgYGB7cn0Kd2hvbGVfY291bnRyeSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gdG90YWxfcG9wdWxhdGlvbikpICsKICBnZW9tX2xpbmUoKSArCiAgbGFicyh0aXRsZSA9ICJVLlMuIFBvcHVsYXRpb24gMTk3OS0yMDE5IikgKwogIHlsYWIoIlBvcHVsYXRpb24iKSArCiAgeGxhYigiWWVhciIpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkgKwogIHRoZW1lX2hjKCkKYGBgCgpUaGUgcG9wdWxhdGlvbiBoYXMgaW5jcmVhc2VkIHN1YnN0YW50aWFsbHkgb3ZlciB0aGUgcmFuZ2Ugb2YgZGF0YSBpbiB0aGlzIHNldC4gCkl0IGlzIGludGVyZXN0aW5nIHRvIG5vdGUgdGhhdCBkZWNyZWFzaW5nIGNyaW1lIHJhdGVzIGhhdmUgY29pbmNpZGVkIHdpdGggYW4gCmluY3JlYXNpbmcgcG9wdWxhdGlvbi4gQWxsIGVsc2UgYmVpbmcgZXF1YWwsIG9uZSBtaWdodCBndWVzcyB0aGUgb3Bwb3NpdGUgd291bGQgCmJlIHRoZSBjYXNlLgoKIyMjIEluY2lkZW5jZSBhbmQgUmF0ZSBvZiBDcmltZSBieSBDYXRlZ29yeQoKTGV0IHVzIG5vdyBleGFtaW5lIHRoZSB0cmVuZHMgaW4gcmF0ZXMgb2YgZWFjaCBjYXRlZ29yeSBvZiBjcmltZSBpbiB0aGUgCmRhdGFzZXQ6CgpgYGB7cn0Kd2hvbGVfY291bnRyeV9sb25nIDwtIHVzX2NyaW1lcyAlPiUKICBmaWx0ZXIoc3RhdGVfbmFtZSAhPSAiVW5pdGVkIFN0YXRlcyIpICU+JQogIHBpdm90X2xvbmdlcihuYW1lc190byA9ICJjYXRlZ29yeSIsCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJjb3VudCIsCiAgICAgICAgICAgICAgIGNvbHMgPSBjKCJ2aW9sZW50X2NyaW1lIiwKICAgICAgICAgICAgICAgICAgICAgICAgImhvbWljaWRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgInJhcGVfbGVnYWN5IiwKICAgICAgICAgICAgICAgICAgICAgICAgInJhcGVfcmV2aXNlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJyb2JiZXJ5IiwKICAgICAgICAgICAgICAgICAgICAgICAgImFnZ3JhdmF0ZWRfYXNzYXVsdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJidXJnbGFyeSIsCiAgICAgICAgICAgICAgICAgICAgICAgICJsYXJjZW55IiwKICAgICAgICAgICAgICAgICAgICAgICAgIm1vdG9yX3ZlaGljbGVfdGhlZnQiKSkKYGBgCgpgYGB7cn0Kd2hvbGVfY291bnRyeV9sb25nIDwtIHdob2xlX2NvdW50cnlfbG9uZyAlPiUKICBtdXRhdGUoY2F0ZWdvcnkgPSB0b1RpdGxlQ2FzZShzdHJfcmVwbGFjZV9hbGwoY2F0ZWdvcnksICJfIiwgIiAiKSkpCmBgYAoKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9Cndob2xlX2NvdW50cnlfbG9uZyAlPiUKICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gY291bnQpKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IGNhdGVnb3J5LCBjb2xvciA9IGNhdGVnb3J5KSwgc3RhdCA9ICdzdW1tYXJ5Jywgc2l6ZSA9IDEuNSkgKwogIGxhYnModGl0bGUgPSAiVS5TLiBDcmltZSBJbmNpZGVudHMgQnkgQ2F0ZWdvcnksIDE5Mjc5IC0gMjAxOSIpICsKICB5bGFiKCJUb3RhbCAocmF3IGNvdW50KSIpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJSZFlsR24iLCBuYW1lID0gIkNhdGVnb3J5IikgKwogIHRoZW1lX2hjKCkKYGBgCgpXZSBjYW4gb2JzZXJ2ZSBhIGZldyB0aGluZ3MgZnJvbSB0aGlzIHBsb3QuIExhcmNlbnkgYW5kIGJ1cmdsYXJ5IGhhdmUgb2NjdXJyZWQgCmNvbnNpc3RlbnRseSBhdCBoaWdoZXIgbnVtYmVycyB0aGFuIHZpb2xlbnQgY3JpbWVzLCB3aGljaCBpcyBwZXJoYXBzIG5vdCBzbyAKc3VycHJpc2luZy4gTGFyY2VueSBpcyBjYXRlZ29yaWNhbGx5IG1vcmUgY29tbW9uIHRoYW4gYWxsIG90aGVyIGNyaW1lcyBhY3Jvc3MgCnRoZSB5ZWFycyBpbiBvdXIgZGF0YSwgYW5kIGhhcyBhbHNvIGRlY3JlYXNlZCBzdWJzdGFudGlhbGx5IHNpbmNlIDE5OTAuCgpIb3dldmVyLCBpZiB3ZSBmb2N1cyBvbiB0aGUgbGluZSBmb3IgdmlvbGVudCBjcmltZSwgd2UgY2FuIHNlZSB0aGF0IHRoaXMgCmNhdGVnb3J5IGhhcyBiZWVuIHJlbGF0aXZlbHkgY29uc2lzdGVudCBhY3Jvc3MgdGhlIHllYXJzIGluIG91ciBkYXRhLiBUaG91Z2ggaXQgCmhhcyBkZWNyZWFzZWQgZnJvbSB0aGUgcGVhayBpbiB0aGUgMTk5MHMsIGl0IGFwcGVhcnMgdG8gaGF2ZSByZW1haW5lZCBhdCB0aGUgCnNhbWUgcmF0ZSBvciBldmVuIGluY3JlYXNlZCBzbGlnaHRseSBvdmVyYWxsIG92ZXIgdGhlIHllYXJzLiAKCmBgYHtyfQp3aG9sZV9jb3VudHJ5X3JhdGVzX2xvbmcgPC0gdXNfY3JpbWVzICU+JQogIGZpbHRlcihzdGF0ZV9uYW1lICE9ICJVbml0ZWQgU3RhdGVzIikgJT4lCiAgcGl2b3RfbG9uZ2VyKG5hbWVzX3RvID0gImNhdGVnb3J5IiwKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInJhdGUiLAogICAgICAgICAgICAgICBjb2xzID0gYygKICAgICAgICAgICAgICAgICAgICAgICAgInZpb2xlbnRfY3JpbWVfcmF0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICJob21pY2lkZV9yYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgInJhcGVfbGVnYWN5X3JhdGUiLAogICAgICAgICAgICAgICAgICAgICAgICAicmFwZV9yZXZpc2VkX3JhdGUiLAogICAgICAgICAgICAgICAgICAgICAgICAicm9iYmVyeV9yYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgImFnZ3JhdmF0ZWRfYXNzYXVsdF9yYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgImJ1cmdsYXJ5X3JhdGUiLAogICAgICAgICAgICAgICAgICAgICAgICAibGFyY2VueV9yYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgIm1vdG9yX3ZlaGljbGVfdGhlZnRfcmF0ZSIpKQpgYGAKClBsb3R0aW5nIHRoZSByYXRlcyBvdmVyIHRpbWUgZm9yIGVhY2ggY2F0ZWdvcnk6CgpgYGB7cn0Kd2hvbGVfY291bnRyeV9yYXRlc19sb25nIDwtIHdob2xlX2NvdW50cnlfcmF0ZXNfbG9uZyAlPiUKICBtdXRhdGUoY2F0ZWdvcnkgPSB0b1RpdGxlQ2FzZShzdHJfcmVwbGFjZV9hbGwoY2F0ZWdvcnksICJfIiwgIiAiKSkpCmBgYAoKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQp3aG9sZV9jb3VudHJ5X3JhdGVzX2xvbmcgJT4lCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IHJhdGUpKSArCiAgbGFicyh0aXRsZSA9ICJVLlMuIENyaW1lIEluY2lkZW50cyBCeSBDYXRlZ29yeSwgMTk3OSAtIDIwMTkiKSArCiAgeWxhYigiUmF0ZSAocGVyIGNhcGl0YSkiKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IGNhdGVnb3J5LCBjb2xvciA9IGNhdGVnb3J5KSwgc3RhdCA9ICdzdW1tYXJ5Jywgc2l6ZSA9IDEuNSkgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlJkWWxHbiIsIG5hbWUgPSAiQ2F0ZWdvcnkiKSArCiAgdGhlbWVfaGMoKQpgYGAKClRoaXMgaXMgc2ltaWxhciB0byB0aGUgbGFzdCBwbG90LCBidXQgbG9va2luZyBhdCB0aGUgcmF0ZXMgbWFrZXMgaXQgYSBiaXQgbW9yZSAKY2xlYXIgdGhhdCBsYXJjZW55IGFuZCBidXJnbGFyeSBoYXZlIHJlYWxseSB0cmVuZGVkIGRvd24gc2lnbmlmaWNhbnRseSBvdmVyIAp0aGVzZSB5ZWFycy4gVGhlIHBlYWsgaW4gdmlvbGVudCBjcmltZSBpbiB0aGUgMTk5MHMgaXMgYWxzbyBhIGJpdCBtb3JlIG9idmlvdXMgCndoZW4gbG9va2luZyBhdCB0aGUgcmF0ZXMgYXMgb3Bwb3NlZCB0byB0aGUgY291bnRzLgoKTGV0J3MgdmlzdWFsaXplIHRoaW5ncyBmcm9tIGEgc2xpZ2h0bHkgZGlmZmVyZW50IHBlcnNwZWN0aXZlLiAKSGVyZSBpcyB0aGUgYmFyIGNoYXJ0IG9mIAphbGwgY3JpbWVzIG9mIGVhY2ggY2F0ZWdvcnkgaW4gdGhpcyBkYXRhc2V0LCBmb3IgdGhlIHdob2xlIGRhdGFzZXQgYW5kIHRpbWUgCnBlcmlvZDoKCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQp3aG9sZV9jb3VudHJ5X2xvbmcgJT4lCiAgZ3JvdXBfYnkoY2F0ZWdvcnkpICU+JQogIHN1bW1hcmlzZSh0b3RhbCA9IHN1bShjb3VudCkpICU+JQogIHNlbGVjdChjYXRlZ29yeSwgdG90YWwpICU+JQogIGdncGxvdChhZXMoeCA9IGNhdGVnb3J5LCB5ID0gdG90YWwpKSArCiAgZ2VvbV9iYXIoc3RhdD0iSWRlbnRpdHkiLCBmaWxsID0gImNhZGV0Ymx1ZTQiLCBjb2xvciA9ICJjYWRldGJsdWU0IikgKwogIGxhYnModGl0bGUgPSAiVS5TLiBDcmltZSBJbmNpZGVudHMgQnkgQ2F0ZWdvcnksIDE5Mjc5IC0gMjAxOSAodG90YWwpIikgKwogIHlsYWIoIlRvdGFsIChyYXcgY291bnQpIikgKwogIHhsYWIoIkNhdGVnb3J5IikgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIHZqdXN0ID0gMC41KSApICsgCiAgdGhlbWVfaGMoKQpgYGAKCiMjIFZpb2xlbnQgQ3JpbWUgaW4gdGhlIFVuaXRlZCBTdGF0ZXMsIDIwMTUtMjAxOQoKIyBIaXN0b2dyYW0gb2YgU3RhdGVzJyBBdmVyYWdlIFZpb2xlbnQgQ3JpbWUgUmF0ZSwgMjAxNS0yMDE5CgpJdCBpcyBpbXBvcnRhbnQgdG8gdW5kZXJzdGFuZCB0aGUgdHJlbmRzIHRoYXQgaGF2ZSBiZWVuIHRha2luZyBwbGFjZSBpbiBvdXIgCmNvdW50cnksIGJ1dCB3ZSBtYXkgYWxzbyBiZSBpbnRlcmVzdGVkIGluIHdoYXQgaXMgZ29pbmcgb24gbW9yZSByZWNlbnRseS4gTGV0J3MKbG9vayBhdCB3aGljaCBzdGF0ZXMgaGFkIHRoZSBtb3N0IHZpb2xlbnQgY3JpbWUgb3ZlciB0aGUgbGFzdCBmaXZlIHllYXJzIGluIHRoZSAKc2V0OyAyMDE1LTIwMTkKCmBgYHtyfQp2aW9sZW50X2NyaW1lX2xhc3RfNV95ZWFycyA8LSB1c19jcmltZXMgJT4lCiAgc2VsZWN0KHllYXIsIHN0YXRlX25hbWUsIHZpb2xlbnRfY3JpbWVfcmF0ZSkgJT4lCiAgZmlsdGVyKHllYXIgPj0gMjAxNSkgJT4lCiAgZmlsdGVyKCEoaXMubmEoc3RhdGVfbmFtZSkpKSAlPiUKICBmaWx0ZXIoc3RhdGVfbmFtZSAhPSAiVW5pdGVkIFN0YXRlcyIpCmBgYAoKV2Ugd2lsbCBwbG90IHRoZSBhdmVyYWdlIHJhdGUgb2YgdmlvbGVudCBjcmltZSBvdmVyIHRoZSBmaXZlIHllYXIgcGVyaW9kIGZvciAKYWxsIDUwIHN0YXRlcyBhcyBhIGhpc3RvZ3JhbToKCmBgYHtyLCBtZXNzYWdlID0gRkFMU0V9Cmxhc3RfNV9kaXN0IDwtIHZpb2xlbnRfY3JpbWVfbGFzdF81X3llYXJzICU+JQogIGdyb3VwX2J5KHN0YXRlX25hbWUpICU+JQogIHN1bW1hcmlzZShhdmcgPSBtZWFuKHZpb2xlbnRfY3JpbWVfcmF0ZSkpCgpsYXN0XzVfZGlzdCAlPiUKICBnZ3Bsb3QoYWVzKHggPSBhdmcpKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDE1LCBmaWxsID0gImNhZGV0Ymx1ZTMiLCBjb2xvciA9ICJjYWRldGJsdWU0IikgKwogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBWaW9sZW50IENyaW1lIFJhdGUgcGVyIFN0YXRlLCAyMDE1LTIwMTkiKSArCiAgeWxhYigiTm8uIG9mIFN0YXRlcyIpICsKICB4bGFiKCJWaW9sZW50IENyaW1lIFJhdGUiKSArIAogIHRoZW1lX2hjKCkKICAKYGBgCgojIyMgRGlzdHJpYnV0aW9uIGFuZCBPdXRsaWVyIEFuYWx5c2lzCgpUaGUgZGlzdHJpYnV0aW9uIGlzIHNvbWV3aGF0IGNsb3NlIHRvIG5vcm1hbCwgYnV0IG5vdGljZWFibHkgcmlnaHQtc2tld2VkLgoKTGV0J3Mgc2VlIHdoYXQgdGhlIHRvcCBzdGF0ZXMgYXJlOgoKYGBge3J9Cmxhc3RfNV9kaXN0ICU+JQogIGFycmFuZ2UoZGVzYyhhdmcpKQpgYGAKCkxldCdzIHNlZSBpZiBELkMuIGFuZCB0aGUgb3RoZXIgdG9wIHN0YXRlcyBhcmUgb3V0bGllcnM6CgpgYGB7cn0Kc3VtbWFyeShsYXN0XzVfZGlzdCRhdmcpCmBgYAoKIApgYGB7cn0KUTMgPC0gMC4wMDQ1NjQKUTEgPC0gMC4wMDI2ODMKSVFSIDwtIFEzIC0gUTEKCmxmIDwtIFExIC0gMS41KklRUgp1ZiA8LSBRMyArIDEuNSpJUVIKbGYKdWYKCmBgYAogCiBELkMuLCBBbGFza2EsIGFuZCBOZXcgTWV4aWNvIGFyZSBhbGwgc3RhdGlzdGljYWwgb3V0bGllcnMgZm9yIHZpb2xlbnQgY3JpbWUgCiBvdmVyIHRoZSBsYXN0IGZpdmUgeWVhcnMuIEluIG15IG9waW5pb24sIEQuQy4gZG9lcyBub3QgcmVhbGx5IGJlbG9uZyBpbiB0aGlzIAogYW5hbHlzaXMgYmVjYXVzZSBpdCBpcyBvbmx5IG9uZSBjaXR5LiBJIHN1c3BlY3QgdGhhdCB3aGlsZSB3ZSBvYnNlcnZlIHZlcnkgaGlnaCAKIGNyaW1lIHJhdGVzIGluIEQuQy4gY29tcGFyZWQgdG8gdGhlIG90aGVyIHN0YXRlcywgd2UgbWF5IHNlZSBzaW1pbGFyIHJhdGVzIGluIAogc2F5LCBMb3MgQW5nZWxlcyBhbmQgTmV3IFlvcmsgQ2l0eSBhcyBvcHBvc2VkIHRvIENhbGlmb3JuaWEgYW5kIE5ldyBZb3JrLgogCiBPbiB0aGUgb3RoZXIgaGFuZCwgQWxhc2thIGFuZCBOZXcgTWV4aWNvIGRvIG5vdCBldmVuIGluY2x1ZGUgbGFyZ2UgdXJiYW4gCiBjZW50ZXJzLCBzbyBJIHdhcyBpbml0aWFsbHkgc3VycHJpc2VkIGJ5IHRoaXMgcmVzdWx0LiBXaGF0IEkgZm91bmQgdXBvbiAKIHJlc2VhcmNoaW5nIGl0IGEgYml0IGlzIHRoYXQgdmlvbGVudCBjcmltZSByYXRlcyBhcmUgZXNwZWNpYWxseSBoaWdoIGFtb25nCiB0aGUgTmF0aXZlIEFtZXJpY2FuIHBvcHVsYXRpb247IGEgdmVyeSBzZXJpb3VzIGlzc3VlIHRoYXQgc2VlbXMgdG8gcmVjZWl2ZSAKIHVuZm9ydHVuYXRlbHkgbGl0dGxlIGF0dGVudGlvbiBmcm9tIHRoZSBtZWRpYSBhbmQgcG9saXRpY2FsIGxlYWRlcnNoaXAuIFsxXQoKIAogCiMjIyBWaXN1YWxpemluZyBVLlMuIFZpb2xlbnQgQ3JpbWUgd2l0aCBUYWJsZWF1CgpUaGUgZm9sbG93aW5nIGludGVyYWN0aXZlIHRhYmxlYXUgdmlzdWFsaXphdGlvbiBzaG93cyBxdWFudGl0eSBhbmQgcmF0ZSBvZiB2aW9sZW50IApjcmltZSBpbmNpZGVudHMgZm9yIGVhY2ggc3RhdGUgaW4gdGhlIGRhdGFzZXQuCgpodHRwczovL3B1YmxpYy50YWJsZWF1LmNvbS9wcm9maWxlL2RhbmllbC5sZWZldnJlIyEvdml6aG9tZS9EYXRhMTEwRmluYWwyL0Rhc2hib2FyZDEKCiFbXSh0YWJsZWF1X2J5c3RhdGUucG5nKQoKTG9va2luZyBhdCBhbGwgc3RhdGVzLCB3ZSBjYW4gZWFzaWx5IGlkZW50aWZ5IERDIGFzIHRoZSBvdXRsaWVyIGluIHRlcm1zIG9mIApyYXRlLCBhbmQgd2UgY2FuIGFsc28gc2VlIHRoYXQgaXQgYWNjb3VudGVkIGZvciBhIHJlbGF0aXZlbHkgc21hbGwgb3ZlcmFsbApxdWFudGl0eSBvZiB2aW9sZW50IGNyaW1lcyB3aGljaCB0b29rIHBsYWNlLiAKCldlIGNhbiB0dXJuIGluZGl2aWR1YWwgc3RhdGVzIG9uIGFuZCBvZmYgdXNpbmcgdGhlIGZpbHRlciBvbiB0aGUgcmlnaHQuIEhlcmUgaXMKREMgdnMuIE5ldyBZb3JrIGZvciB0aGUgeWVhcnMgaW4gdGhlIGRhdGFzZXQ6CgohW10odGFibGVhdV9EQ19OWS5wbmcpCgojIyMgVGhvdWdodHMgYW5kIFN1bW1hcnkKCkkgd2FzIGF3YXJlIGdvaW5nIGludG8gdGhpcyBhaGVhZCBvZiB0aW1lIHRoYXQgdmlvbGVudCBjcmltZSBoYWQgZGVjcmVhc2VkIApzaW5jZSB0aGUgbWlkZGxlIG9mIHRoZSBjZW50dXJ5LCBhbmQgdGhhdCB2aW9sZW50IGNyaW1lIGhhZCBhIHBlYWsgaW4gdGhlIAoxOTkwJ3MuIFN0aWxsLCBhcyB3aXRoIG1hbnkgb2YgdGhlc2UgcHJvamVjdHMsIEkgZmluZCBpdCBpbnRlcmVzdGluZyB0byBzZWUgCnRoZXNlIHRyZW5kcyBpbiBhIG1vcmUgY29uY3JldGUgd2F5LgoKT25lIHF1ZXN0aW9uIHRoYXQgY2FtZSB0byBtZSB3aGlsZSB3b3JraW5nIG9uIHRoZSBwcm9qZWN0IGlzOiB3aHkgYXJlIGRydWcKY3JpbWVzIG5vdCBpbmNsdWRlZCBpbiB0aGUgZGF0YXNldD8gSWYgSSBoYWQgdGhvdWdodCBvZiB0aGlzIGVhcmxpZXIgaW4gdGhlIApwcm9qZWN0LCBJIG1pZ2h0IGhhdmUgdHJpZWQgdG8gYWNjZXNzIHRoZSBTUlMgZGlyZWN0bHkgYW5kIHNlZSBpZiB0aGUgZGF0YSAKd2FzIHNpbXBseSBsZWZ0IG91dCBmcm9tIHRoZSBkYXRhc2V0IG9yIHdoYXQgdGhlIGV4cGxhbmF0aW9uIGlzIHRoZXJlLiBJdCAKaXMgZmFpcmx5IHdlbGwga25vd24gdGhhdCB0aGUgVS5TLiBwcmlzb24gcG9wdWxhdGlvbiBoYXMgZ3Jvd24gZHJhc3RpY2FsbHkgb3ZlciAKdGhlIGxhc3QgZmV3IGRlY2FkZXMuIEluIGZhY3QsIG91ciBpbmNhcmNlcmF0ZWQgcG9wdWxhdGlvbiBpbmNyZWFzZWQgYnkgYSAKZmFjdG9yIG9mIGFib3V0IDcgZnJvbSAxOTgwIHRvIDIwMTguWzNdIEl0IHNlZW1zIGRpZmZpY3VsdCB0byBzcXVhcmUgYSAKZGVjcmVhc2UgaW4gY3JpbWUgd2l0aCBhIGRyYXN0aWMgaW5jcmVhc2UgaW4gdGhlIHByaXNvbiBwb3B1bGF0aW9uLgoKSW4gdGhpcyBwcm9qZWN0LCB3ZSBsb29rZWQgYXQgY3JpbWUgc3RhdGlzdGljcyBpbiB0aGUgVVNBIGZyb20gMTk3OSB0byAyMDE5LgpXZSBmb2N1c2VkIG1haW5seSBvbiB2aW9sZW50IGNyaW1lLCBhbmQgZXhhbWluZWQgdGhlIGRpc3RyaWJ1dGlvbiBvZiBldmVudHMgCmFzIHdlbGwgYXMgdGhlIHN1cmdlIGluIHZpb2xlbnQgY3JpbWUgZHVyaW5nIHRoZSAxOTkwcy4gV2UgZm91bmQgdGhhdCB3aGlsZSAKV2FzaGluZ3RvbiBELkMuIGlzIGEgc3RhdGlzdGljYWwgb3V0bGllciBpbiB0ZXJtcyBvZiBjcmltZSByYXRlIGFuZCB3YXMgCmVzcGVjaWFsbHkgc28gZHVyaW5nIHRoZSBlYXJseS10by1taWQgbmluZXRpZXMsIHRoZSBzdXJnZSBpbiB2aW9sZW5jZSAKbGFyZ2VseSBvY2N1cnJlZCBpbiBzdGF0ZXMgbGlrZSBDYWxpZm9ybmlhLCBOZXcgWW9yaywgYW5kIGEgZmV3IG90aGVycy4KCkkgYWxzbyBsZWFybmVkIGFib3V0IHZpb2xlbmNlIGFtb25nIE5hdGl2ZSBBbWVyaWNhbiBwb3B1bGF0aW9ucywgd2hpY2ggaXMgYSAKdmVyeSBjb21wbGV4IGFuZCB0cmFnaWMgaXNzdWUuIEkgbWF5IHRyeSB0byBpbnZlc3RpZ2F0ZSB0aGlzIGFzIGFub3RoZXIgdG9waWMgCmZvciBmdXR1cmUgcmVzZWFyY2guCgpPbmUgdGhpbmcgSSBzdHJ1Z2dsZWQgd2l0aCBkdXJpbmcgdGhpcyBwcm9qZWN0IHdhcyB0aGF0IEkgd2FudGVkIHRvIHNob3cgdGhlIHktCmF4aXMgb2YgdGhlIHBvcHVsYXRpb24gY2hhcnRzIGluICI8eT4wMCBtaWxsaW9uIiBmb3JtYXQgaW5zdGVhZCBvZiBzY2llbnRpZmljIApub3RhdGlvbi4gSSB0cmllZCB0byBmaWd1cmUgdGhpcyBvdXQgZm9yIHF1aXRlIHNvbWUgdGltZSBidXQgY291bGQgbm90IGdldCBpdCAKdG8gd29yay4gSSBhbHNvIHdvdWxkIGhhdmUgbGlrZWQgdG8gZGlzcGxheSB0aGUgc3RhdGUgbmFtZXMgb24gdGhlIHRpbGVzIGluIHRoZSAKVGFibGVhdSB2aXN1YWxpemF0aW9uLCBidXQgaXQgc2VlbWVkIHRoYXQgdGhlIGlzc3VlIGhlcmUgd2FzIGp1c3QgdGhhdCB0aGUgdGlsZXMgCmFyZSB0b28gc21hbGwgYW5kIFRhYmxlYXUgd2lsbCBub3Qgc2hvdyB0aGUgbGFiZWwuCgoKWzFdIGh0dHBzOi8vd3d3LmxpZmVkYWlseS5jb20vc3RvcnkvaGlnaC1jcmltZS1yYXRlcy1pZ25vcmVkLWNhc2VzLXVzLWluZGlhbi1yZXNlcnZhdGlvbi1mb3JjZS1yZXNpZGVudHMtdGFrZS1hY3Rpb24vCgpbMl0gaHR0cHM6Ly91Y3IuZmJpLmdvdi9jcmltZS1pbi10aGUtdS5zLzIwMTMvY3JpbWUtaW4tdGhlLXUucy4tMjAxMy92aW9sZW50LWNyaW1lL3JhcGUKClszXSBodHRwczovL3d3dy5zZW50ZW5jaW5ncHJvamVjdC5vcmcvd3AtY29udGVudC91cGxvYWRzLzIwMjAvMDgvVHJlbmRzLWluLVVTLUNvcnJlY3Rpb25zLnBkZg==