This is an R Markdown
Notebook. When you execute code within the notebook, the results appear
beneath the code.
Try executing this chunk by clicking the Run button within
the chunk or by placing your cursor inside it and pressing
Ctrl+Shift+Enter.
#start
Add a new chunk by clicking the Insert Chunk button on the
toolbar or by pressing Ctrl+Alt+I.
When you save the notebook, an HTML file containing the code and
output will be saved alongside it (click the Preview button or
press Ctrl+Shift+K to preview the HTML file).
The preview shows you a rendered HTML copy of the contents of the
editor. Consequently, unlike Knit, Preview does not
run any R code chunks. Instead, the output of the chunk when it was last
run in the editor is displayed.
library(ggplot2)
library(dplyr)
# Load the dataset
crime_data <- read.csv("C:\\Users\\khush\\Downloads\\Crimes_-_2001_to_Present.csv\\Crimes_-_2001_to_Present.csv")
library(forcats)
# Create a bar chart for Primary Type, sorted by frequency
g <- ggplot(crime_data, aes(x = fct_infreq(Primary.Type))) +
geom_bar(fill = "skyblue") +
theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
labs(title = "Frequency of Primary Crime Types", x = "Crime Type", y = "Count")
# Print the bar chart
print(g)

Questions Answered:
- Which crime types are most frequent?
Observations:
The bar chart shows the frequency of each primary crime type,
sorted by the most common types first.
Theft, battery, criminal damage, narcotics are the most frequent
ones.
# Summarize the data by block
block_summary <- crime_data %>%
group_by(Block) %>%
summarise(Incident_Count = n(), .groups = 'drop') %>%
arrange(desc(Incident_Count))
# Get the top 15 blocks
top_15_blocks <- head(block_summary, 15)
# Create a bar chart
ggplot(top_15_blocks, aes(x = reorder(Block, Incident_Count), y = Incident_Count)) +
geom_bar(stat = "identity", fill = "skyblue") +
coord_flip() + # Flip coordinates for better readability
labs(title = "Top 15 Blocks with Most Incidents",
x = "Block",
y = "Number of Incidents") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Questions Answered:
- Which blocks have the highest number of incidents?
Observations:
Incident Distribution: The chart shows the blocks with the most
incidents, highlighting where criminal activities are
concentrated.
100XX W OHARE ST is the block with most number of
incidents.
# Summarize the data for Arrest
arrest_data <- table(crime_data$Arrest)
# Convert to a data frame and make sure 'Count' is numeric
arrest_df <- as.data.frame(arrest_data)
names(arrest_df) <- c("Arrest", "Count")
arrest_df$Count <- as.numeric(arrest_df$Count)
# Create a pie chart for Arrests
ggplot(arrest_df, aes(x = "", y = Count, fill = Arrest)) +
geom_bar(width = 1, stat = "identity") +
coord_polar(theta = "y") +
scale_fill_manual(values = c("red", "green")) +
labs(title = "Proportion of Arrests") +
theme_void() +
theme(legend.position = "right")

Questions Answered:
- What is the proportion of cases where arrests were made compared to
cases where no arrest was made?
Observations:
This pie chart shows the proportion of incidents with and without
arrests.
It shows that the number of incidents with arrests is less than
the number of incidents without arrests, highlighting a larger
proportion of cases where no arrest was made.
# Summarize the data for Domestic
domestic_data <- table(crime_data$Domestic)
# Convert to a data frame and make sure 'Count' is numeric
domestic_df <- as.data.frame(domestic_data)
names(domestic_df) <- c("Domestic", "Count")
domestic_df$Count <- as.numeric(domestic_df$Count)
# Create a pie chart for Domestic
ggplot(domestic_df, aes(x = "", y = Count, fill = Domestic)) +
geom_bar(width = 1, stat = "identity") +
coord_polar(theta = "y") +
labs(title = "Proportion of Domestic vs Non-Domestic Incidents") +
theme_void() +
theme(legend.position = "right")

Questions Answered:
- What is the proportion of domestic incidents compared to
non-domestic incidents?
Observations:
The pie chart provides a visual representation of the proportion
of domestic versus non-domestic incidents.
Domestic incidents are less frequent compared to non-domestic
incidents, indicating a larger proportion of non-domestic cases in the
dataset.
# Create a histogram for the 'Year' column
ggplot(crime_data, aes(x = Year)) +
geom_histogram(binwidth = 1, fill = "skyblue", color = "black") +
labs(title = "Distribution of Incidents by Year", x = "Year", y = "Count")

Questions Answered:
Observations:
The histogram shows the distribution of incidents by
year.
It highlights how the number of incidents has varied from year to
year.
There is a noticeable decrease in the number of incidents in
recent years, suggesting a decline in overall incidents over
time.
# Convert 'Date' to Date type
crime_data$Date <- as.Date(crime_data$Date, format = "%m/%d/%Y %I:%M:%S %p")
# Group by year and count total cases and arrests per year
crime_summary <- crime_data %>%
group_by(Year) %>%
summarise(Total_Cases = n(),
Total_Arrests = sum(Arrest == "true", na.rm = TRUE))
# Create a timeline plot for Cases vs. Arrests
ggplot(crime_summary, aes(x = Year)) +
geom_line(aes(y = Total_Cases, color = "Total Cases"), size = 1) +
geom_line(aes(y = Total_Arrests, color = "Total Arrests"), size = 1) +
labs(title = "Timeline of Cases and Arrests", x = "Year", y = "Count") +
scale_color_manual(values = c("Total Cases" = "blue", "Total Arrests" = "red")) +
theme_minimal()

Questions Answered:
Observations:
There is a significant decline in the total number of cases over
time.
The number of arrests has shown a more consistent decrease,
indicating that while fewer cases are being reported, the rate of
arrests is not declining as sharply.
# Calculate total counts for each crime type
crime_counts <- crime_data %>%
group_by(Primary.Type) %>%
summarise(Total = n()) %>%
arrange(desc(Total))
# Get the top 5 most frequent crimes
top_5_crimes <- head(crime_counts, 5)
print(top_5_crimes)
# Filter dataset to include only the top 5 crimes
top_5_crimes_list <- top_5_crimes$Primary.Type
filtered_data <- crime_data %>%
filter(Primary.Type %in% top_5_crimes_list)
# Summarize the data by year and crime type
timeline_data <- filtered_data %>%
group_by(Year, Primary.Type) %>%
summarise(Count = n(), .groups = 'drop')
# Create a timeline plot for the top 5 crimes
ggplot(timeline_data, aes(x = Year, y = Count, color = Primary.Type)) +
geom_line() +
labs(title = "Number of Crimes by Year for the Top 5 Most Common Types",
x = "Year",
y = "Count of Crimes",
color = "Crime Type") +
theme_minimal()

Questions Answered:
Observations:
Narcotics, Theft, and Battery show a significant decline in the
number of reported cases over the years.
Assault has shown relative stability, with little change in its
frequency over time compared to the other crime types.
# Filter dataset to include only the top 5 crimes
top_5_crimes_list <- top_5_crimes$Primary.Type
filtered_data <- crime_data %>%
filter(Primary.Type %in% top_5_crimes_list)
# Summarize the data by year and crime type
summary_data <- filtered_data %>%
group_by(Year, Primary.Type) %>%
summarise(Cases = n(),
Arrests = sum(Arrest == "true"),.groups = 'drop')
# Create a scatter plot
ggplot(summary_data, aes(x = Cases, y = Arrests, color = Primary.Type)) +
geom_point(alpha = 0.7, size = 3) +
labs(title = "Number of Cases vs. Number of Arrests for Top 5 Crimes",
x = "Number of Cases",
y = "Number of Arrests",
color = "Primary Type") +
theme_minimal()

Questions Answered:
Observations:
There is a general trend where the number of arrests increases
with the number of cases for most crime types.
Narcotics shows the strongest correlation, with a notable
increase in arrests corresponding to a higher number of cases.
Other crime types also exhibit an increase in arrests with more
cases, but the correlation is less pronounced compared to
narcotics.
# Summarize the data by year and crime type
summary_data <- filtered_data %>%
group_by(Year, Primary.Type) %>%
summarise(Cases = n(),
Arrests = sum(Arrest == "true"), # Summarize the number of arrests
.groups = 'drop')
# Create a bubble plot
ggplot(summary_data, aes(x = Year, y = Cases, size = Arrests, color = Primary.Type)) +
geom_point(alpha = 0.7) +
scale_size_continuous(range = c(2, 10), name = "Number of Arrests") +
labs(title = "Bubble Plot of Number of Cases and Arrests for Top 5 Crimes",
x = "Year",
y = "Number of Cases",
color = "Primary Type") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Questions Answered:
- What is the relationship between the number of cases and the number
of arrests for different crime types over the years?
Observations:
Bubble Size reflects the number of arrests. Larger bubbles
indicate a higher number of arrests.
Color Coding allows comparison of different crime types and their
trends.
Narcotics shows consistently larger bubbles and a significant
drop in the number of cases over the years.
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpUaGlzIGlzIGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLg0KDQpUcnkgZXhlY3V0aW5nIHRoaXMgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ3RybCtTaGlmdCtFbnRlciouDQoNCmBgYHtyfQ0KI3N0YXJ0DQpgYGANCg0KQWRkIGEgbmV3IGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqSW5zZXJ0IENodW5rKiBidXR0b24gb24gdGhlIHRvb2xiYXIgb3IgYnkgcHJlc3NpbmcgKkN0cmwrQWx0K0kqLg0KDQpXaGVuIHlvdSBzYXZlIHRoZSBub3RlYm9vaywgYW4gSFRNTCBmaWxlIGNvbnRhaW5pbmcgdGhlIGNvZGUgYW5kIG91dHB1dCB3aWxsIGJlIHNhdmVkIGFsb25nc2lkZSBpdCAoY2xpY2sgdGhlICpQcmV2aWV3KiBidXR0b24gb3IgcHJlc3MgKkN0cmwrU2hpZnQrSyogdG8gcHJldmlldyB0aGUgSFRNTCBmaWxlKS4NCg0KVGhlIHByZXZpZXcgc2hvd3MgeW91IGEgcmVuZGVyZWQgSFRNTCBjb3B5IG9mIHRoZSBjb250ZW50cyBvZiB0aGUgZWRpdG9yLiBDb25zZXF1ZW50bHksIHVubGlrZSAqS25pdCosICpQcmV2aWV3KiBkb2VzIG5vdCBydW4gYW55IFIgY29kZSBjaHVua3MuIEluc3RlYWQsIHRoZSBvdXRwdXQgb2YgdGhlIGNodW5rIHdoZW4gaXQgd2FzIGxhc3QgcnVuIGluIHRoZSBlZGl0b3IgaXMgZGlzcGxheWVkLg0KDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZHBseXIpDQpgYGANCg0KYGBge3J9DQojIExvYWQgdGhlIGRhdGFzZXQNCmNyaW1lX2RhdGEgPC0gcmVhZC5jc3YoIkM6XFxVc2Vyc1xca2h1c2hcXERvd25sb2Fkc1xcQ3JpbWVzXy1fMjAwMV90b19QcmVzZW50LmNzdlxcQ3JpbWVzXy1fMjAwMV90b19QcmVzZW50LmNzdiIpDQoNCmxpYnJhcnkoZm9yY2F0cykNCiMgQ3JlYXRlIGEgYmFyIGNoYXJ0IGZvciBQcmltYXJ5IFR5cGUsIHNvcnRlZCBieSBmcmVxdWVuY3kNCmcgPC0gZ2dwbG90KGNyaW1lX2RhdGEsIGFlcyh4ID0gZmN0X2luZnJlcShQcmltYXJ5LlR5cGUpKSkgKw0KICBnZW9tX2JhcihmaWxsID0gInNreWJsdWUiKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpICsNCiAgbGFicyh0aXRsZSA9ICJGcmVxdWVuY3kgb2YgUHJpbWFyeSBDcmltZSBUeXBlcyIsIHggPSAiQ3JpbWUgVHlwZSIsIHkgPSAiQ291bnQiKQ0KDQojIFByaW50IHRoZSBiYXIgY2hhcnQNCnByaW50KGcpDQoNCmBgYA0KDQoqKlF1ZXN0aW9ucyBBbnN3ZXJlZDoqKg0KDQotICAgV2hpY2ggY3JpbWUgdHlwZXMgYXJlIG1vc3QgZnJlcXVlbnQ/DQoNCioqT2JzZXJ2YXRpb25zOioqDQoNCi0gICBUaGUgYmFyIGNoYXJ0IHNob3dzIHRoZSBmcmVxdWVuY3kgb2YgZWFjaCBwcmltYXJ5IGNyaW1lIHR5cGUsIHNvcnRlZCBieSB0aGUgbW9zdCBjb21tb24gdHlwZXMgZmlyc3QuDQoNCi0gICBUaGVmdCwgYmF0dGVyeSwgY3JpbWluYWwgZGFtYWdlLCBuYXJjb3RpY3MgYXJlIHRoZSBtb3N0IGZyZXF1ZW50IG9uZXMuDQoNCmBgYHtyfQ0KIyBTdW1tYXJpemUgdGhlIGRhdGEgYnkgYmxvY2sNCmJsb2NrX3N1bW1hcnkgPC0gY3JpbWVfZGF0YSAlPiUNCiAgZ3JvdXBfYnkoQmxvY2spICU+JQ0KICBzdW1tYXJpc2UoSW5jaWRlbnRfQ291bnQgPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpICU+JQ0KICBhcnJhbmdlKGRlc2MoSW5jaWRlbnRfQ291bnQpKQ0KDQojIEdldCB0aGUgdG9wIDE1IGJsb2Nrcw0KdG9wXzE1X2Jsb2NrcyA8LSBoZWFkKGJsb2NrX3N1bW1hcnksIDE1KQ0KDQojIENyZWF0ZSBhIGJhciBjaGFydA0KZ2dwbG90KHRvcF8xNV9ibG9ja3MsIGFlcyh4ID0gcmVvcmRlcihCbG9jaywgSW5jaWRlbnRfQ291bnQpLCB5ID0gSW5jaWRlbnRfQ291bnQpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gInNreWJsdWUiKSArDQogIGNvb3JkX2ZsaXAoKSArICAjIEZsaXAgY29vcmRpbmF0ZXMgZm9yIGJldHRlciByZWFkYWJpbGl0eQ0KICBsYWJzKHRpdGxlID0gIlRvcCAxNSBCbG9ja3Mgd2l0aCBNb3N0IEluY2lkZW50cyIsDQogICAgICAgeCA9ICJCbG9jayIsDQogICAgICAgeSA9ICJOdW1iZXIgb2YgSW5jaWRlbnRzIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KYGBgDQoNCioqUXVlc3Rpb25zIEFuc3dlcmVkOioqDQoNCi0gICBXaGljaCBibG9ja3MgaGF2ZSB0aGUgaGlnaGVzdCBudW1iZXIgb2YgaW5jaWRlbnRzPw0KDQoqKk9ic2VydmF0aW9uczoqKg0KDQotICAgSW5jaWRlbnQgRGlzdHJpYnV0aW9uOiBUaGUgY2hhcnQgc2hvd3MgdGhlIGJsb2NrcyB3aXRoIHRoZSBtb3N0IGluY2lkZW50cywgaGlnaGxpZ2h0aW5nIHdoZXJlIGNyaW1pbmFsIGFjdGl2aXRpZXMgYXJlIGNvbmNlbnRyYXRlZC4NCg0KLSAgIDEwMFhYIFcgT0hBUkUgU1QgaXMgdGhlIGJsb2NrIHdpdGggbW9zdCBudW1iZXIgb2YgaW5jaWRlbnRzLg0KDQpgYGB7cn0NCiMgU3VtbWFyaXplIHRoZSBkYXRhIGZvciBBcnJlc3QNCmFycmVzdF9kYXRhIDwtIHRhYmxlKGNyaW1lX2RhdGEkQXJyZXN0KQ0KDQojIENvbnZlcnQgdG8gYSBkYXRhIGZyYW1lIGFuZCBtYWtlIHN1cmUgJ0NvdW50JyBpcyBudW1lcmljDQphcnJlc3RfZGYgPC0gYXMuZGF0YS5mcmFtZShhcnJlc3RfZGF0YSkNCm5hbWVzKGFycmVzdF9kZikgPC0gYygiQXJyZXN0IiwgIkNvdW50IikNCmFycmVzdF9kZiRDb3VudCA8LSBhcy5udW1lcmljKGFycmVzdF9kZiRDb3VudCkgDQoNCiMgQ3JlYXRlIGEgcGllIGNoYXJ0IGZvciBBcnJlc3RzDQpnZ3Bsb3QoYXJyZXN0X2RmLCBhZXMoeCA9ICIiLCB5ID0gQ291bnQsIGZpbGwgPSBBcnJlc3QpKSArDQogIGdlb21fYmFyKHdpZHRoID0gMSwgc3RhdCA9ICJpZGVudGl0eSIpICsgDQogIGNvb3JkX3BvbGFyKHRoZXRhID0gInkiKSArIA0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJyZWQiLCAiZ3JlZW4iKSkgKyANCiAgbGFicyh0aXRsZSA9ICJQcm9wb3J0aW9uIG9mIEFycmVzdHMiKSArDQogIHRoZW1lX3ZvaWQoKSArIA0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKSANCmBgYA0KDQoqKlF1ZXN0aW9ucyBBbnN3ZXJlZDoqKg0KDQotICAgV2hhdCBpcyB0aGUgcHJvcG9ydGlvbiBvZiBjYXNlcyB3aGVyZSBhcnJlc3RzIHdlcmUgbWFkZSBjb21wYXJlZCB0byBjYXNlcyB3aGVyZSBubyBhcnJlc3Qgd2FzIG1hZGU/DQoNCioqT2JzZXJ2YXRpb25zOioqDQoNCi0gICBUaGlzIHBpZSBjaGFydCBzaG93cyB0aGUgcHJvcG9ydGlvbiBvZiBpbmNpZGVudHMgd2l0aCBhbmQgd2l0aG91dCBhcnJlc3RzLg0KDQotICAgSXQgc2hvd3MgdGhhdCB0aGUgbnVtYmVyIG9mIGluY2lkZW50cyB3aXRoIGFycmVzdHMgaXMgbGVzcyB0aGFuIHRoZSBudW1iZXIgb2YgaW5jaWRlbnRzIHdpdGhvdXQgYXJyZXN0cywgaGlnaGxpZ2h0aW5nIGEgbGFyZ2VyIHByb3BvcnRpb24gb2YgY2FzZXMgd2hlcmUgbm8gYXJyZXN0IHdhcyBtYWRlLg0KDQpgYGB7cn0NCiMgU3VtbWFyaXplIHRoZSBkYXRhIGZvciBEb21lc3RpYw0KZG9tZXN0aWNfZGF0YSA8LSB0YWJsZShjcmltZV9kYXRhJERvbWVzdGljKQ0KDQojIENvbnZlcnQgdG8gYSBkYXRhIGZyYW1lIGFuZCBtYWtlIHN1cmUgJ0NvdW50JyBpcyBudW1lcmljDQpkb21lc3RpY19kZiA8LSBhcy5kYXRhLmZyYW1lKGRvbWVzdGljX2RhdGEpDQpuYW1lcyhkb21lc3RpY19kZikgPC0gYygiRG9tZXN0aWMiLCAiQ291bnQiKQ0KZG9tZXN0aWNfZGYkQ291bnQgPC0gYXMubnVtZXJpYyhkb21lc3RpY19kZiRDb3VudCkgIA0KDQojIENyZWF0ZSBhIHBpZSBjaGFydCBmb3IgRG9tZXN0aWMNCmdncGxvdChkb21lc3RpY19kZiwgYWVzKHggPSAiIiwgeSA9IENvdW50LCBmaWxsID0gRG9tZXN0aWMpKSArDQogIGdlb21fYmFyKHdpZHRoID0gMSwgc3RhdCA9ICJpZGVudGl0eSIpICsgDQogIGNvb3JkX3BvbGFyKHRoZXRhID0gInkiKSArIA0KICBsYWJzKHRpdGxlID0gIlByb3BvcnRpb24gb2YgRG9tZXN0aWMgdnMgTm9uLURvbWVzdGljIEluY2lkZW50cyIpICsNCiAgdGhlbWVfdm9pZCgpICsgIA0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKSANCmBgYA0KDQoqKlF1ZXN0aW9ucyBBbnN3ZXJlZDoqKg0KDQotICAgV2hhdCBpcyB0aGUgcHJvcG9ydGlvbiBvZiBkb21lc3RpYyBpbmNpZGVudHMgY29tcGFyZWQgdG8gbm9uLWRvbWVzdGljIGluY2lkZW50cz8NCg0KKipPYnNlcnZhdGlvbnM6KioNCg0KLSAgIFRoZSBwaWUgY2hhcnQgcHJvdmlkZXMgYSB2aXN1YWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIHByb3BvcnRpb24gb2YgZG9tZXN0aWMgdmVyc3VzIG5vbi1kb21lc3RpYyBpbmNpZGVudHMuDQoNCi0gICBEb21lc3RpYyBpbmNpZGVudHMgYXJlIGxlc3MgZnJlcXVlbnQgY29tcGFyZWQgdG8gbm9uLWRvbWVzdGljIGluY2lkZW50cywgaW5kaWNhdGluZyBhIGxhcmdlciBwcm9wb3J0aW9uIG9mIG5vbi1kb21lc3RpYyBjYXNlcyBpbiB0aGUgZGF0YXNldC4NCg0KYGBge3J9DQojIENyZWF0ZSBhIGhpc3RvZ3JhbSBmb3IgdGhlICdZZWFyJyBjb2x1bW4NCmdncGxvdChjcmltZV9kYXRhLCBhZXMoeCA9IFllYXIpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMSwgZmlsbCA9ICJza3libHVlIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGxhYnModGl0bGUgPSAiRGlzdHJpYnV0aW9uIG9mIEluY2lkZW50cyBieSBZZWFyIiwgeCA9ICJZZWFyIiwgeSA9ICJDb3VudCIpDQpgYGANCg0KKipRdWVzdGlvbnMgQW5zd2VyZWQ6KioNCg0KLSAgIEhvdyBhcmUgaW5jaWRlbnRzIGRpc3RyaWJ1dGVkIG92ZXIgdGhlIHllYXJzPw0KDQotICAgQXJlIHRoZXJlIGFueSB0cmVuZHMgb3IgcGF0dGVybnMgaW4gdGhlIG51bWJlciBvZiBpbmNpZGVudHMgcGVyIHllYXI/DQoNCioqT2JzZXJ2YXRpb25zOioqDQoNCi0gICBUaGUgaGlzdG9ncmFtIHNob3dzIHRoZSBkaXN0cmlidXRpb24gb2YgaW5jaWRlbnRzIGJ5IHllYXIuDQoNCi0gICBJdCBoaWdobGlnaHRzIGhvdyB0aGUgbnVtYmVyIG9mIGluY2lkZW50cyBoYXMgdmFyaWVkIGZyb20geWVhciB0byB5ZWFyLg0KDQotICAgVGhlcmUgaXMgYSBub3RpY2VhYmxlIGRlY3JlYXNlIGluIHRoZSBudW1iZXIgb2YgaW5jaWRlbnRzIGluIHJlY2VudCB5ZWFycywgc3VnZ2VzdGluZyBhIGRlY2xpbmUgaW4gb3ZlcmFsbCBpbmNpZGVudHMgb3ZlciB0aW1lLg0KDQpgYGB7cn0NCiMgQ29udmVydCAnRGF0ZScgdG8gRGF0ZSB0eXBlIA0KY3JpbWVfZGF0YSREYXRlIDwtIGFzLkRhdGUoY3JpbWVfZGF0YSREYXRlLCBmb3JtYXQgPSAiJW0vJWQvJVkgJUk6JU06JVMgJXAiKQ0KDQojIEdyb3VwIGJ5IHllYXIgYW5kIGNvdW50IHRvdGFsIGNhc2VzIGFuZCBhcnJlc3RzIHBlciB5ZWFyDQpjcmltZV9zdW1tYXJ5IDwtIGNyaW1lX2RhdGEgJT4lDQogIGdyb3VwX2J5KFllYXIpICU+JQ0KICBzdW1tYXJpc2UoVG90YWxfQ2FzZXMgPSBuKCksDQogICAgICAgICAgICBUb3RhbF9BcnJlc3RzID0gc3VtKEFycmVzdCA9PSAidHJ1ZSIsIG5hLnJtID0gVFJVRSkpDQoNCiMgQ3JlYXRlIGEgdGltZWxpbmUgcGxvdCBmb3IgQ2FzZXMgdnMuIEFycmVzdHMNCmdncGxvdChjcmltZV9zdW1tYXJ5LCBhZXMoeCA9IFllYXIpKSArDQogIGdlb21fbGluZShhZXMoeSA9IFRvdGFsX0Nhc2VzLCBjb2xvciA9ICJUb3RhbCBDYXNlcyIpLCBzaXplID0gMSkgKw0KICBnZW9tX2xpbmUoYWVzKHkgPSBUb3RhbF9BcnJlc3RzLCBjb2xvciA9ICJUb3RhbCBBcnJlc3RzIiksIHNpemUgPSAxKSArDQogIGxhYnModGl0bGUgPSAiVGltZWxpbmUgb2YgQ2FzZXMgYW5kIEFycmVzdHMiLCB4ID0gIlllYXIiLCB5ID0gIkNvdW50IikgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiVG90YWwgQ2FzZXMiID0gImJsdWUiLCAiVG90YWwgQXJyZXN0cyIgPSAicmVkIikpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KKipRdWVzdGlvbnMgQW5zd2VyZWQ6KioNCg0KLSAgIEhvdyBoYXZlIHRoZSBudW1iZXIgb2YgdG90YWwgY2FzZXMgYW5kIHRvdGFsIGFycmVzdHMgY2hhbmdlZCBvdmVyIHRoZSB5ZWFycz8NCg0KLSAgIEFyZSB0aGVyZSBhbnkgbm90aWNlYWJsZSB0cmVuZHMgb3IgcGF0dGVybnMgaW4gdGhlIHRvdGFsIG51bWJlciBvZiBjYXNlcyBhbmQgYXJyZXN0cz8NCg0KKipPYnNlcnZhdGlvbnM6KioNCg0KLSAgIFRoZXJlIGlzIGEgc2lnbmlmaWNhbnQgZGVjbGluZSBpbiB0aGUgdG90YWwgbnVtYmVyIG9mIGNhc2VzIG92ZXIgdGltZS4NCg0KLSAgIFRoZSBudW1iZXIgb2YgYXJyZXN0cyBoYXMgc2hvd24gYSBtb3JlIGNvbnNpc3RlbnQgZGVjcmVhc2UsIGluZGljYXRpbmcgdGhhdCB3aGlsZSBmZXdlciBjYXNlcyBhcmUgYmVpbmcgcmVwb3J0ZWQsIHRoZSByYXRlIG9mIGFycmVzdHMgaXMgbm90IGRlY2xpbmluZyBhcyBzaGFycGx5Lg0KDQpgYGB7cn0NCiMgQ2FsY3VsYXRlIHRvdGFsIGNvdW50cyBmb3IgZWFjaCBjcmltZSB0eXBlDQpjcmltZV9jb3VudHMgPC0gY3JpbWVfZGF0YSAlPiUNCiAgZ3JvdXBfYnkoUHJpbWFyeS5UeXBlKSAlPiUNCiAgc3VtbWFyaXNlKFRvdGFsID0gbigpKSAlPiUNCiAgYXJyYW5nZShkZXNjKFRvdGFsKSkNCg0KIyBHZXQgdGhlIHRvcCA1IG1vc3QgZnJlcXVlbnQgY3JpbWVzDQp0b3BfNV9jcmltZXMgPC0gaGVhZChjcmltZV9jb3VudHMsIDUpDQpwcmludCh0b3BfNV9jcmltZXMpDQpgYGANCg0KYGBge3J9DQojIEZpbHRlciBkYXRhc2V0IHRvIGluY2x1ZGUgb25seSB0aGUgdG9wIDUgY3JpbWVzDQp0b3BfNV9jcmltZXNfbGlzdCA8LSB0b3BfNV9jcmltZXMkUHJpbWFyeS5UeXBlDQpmaWx0ZXJlZF9kYXRhIDwtIGNyaW1lX2RhdGEgJT4lDQogIGZpbHRlcihQcmltYXJ5LlR5cGUgJWluJSB0b3BfNV9jcmltZXNfbGlzdCkNCg0KIyBTdW1tYXJpemUgdGhlIGRhdGEgYnkgeWVhciBhbmQgY3JpbWUgdHlwZQ0KdGltZWxpbmVfZGF0YSA8LSBmaWx0ZXJlZF9kYXRhICU+JQ0KICBncm91cF9ieShZZWFyLCBQcmltYXJ5LlR5cGUpICU+JQ0KICBzdW1tYXJpc2UoQ291bnQgPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpDQoNCiMgQ3JlYXRlIGEgdGltZWxpbmUgcGxvdCBmb3IgdGhlIHRvcCA1IGNyaW1lcw0KZ2dwbG90KHRpbWVsaW5lX2RhdGEsIGFlcyh4ID0gWWVhciwgeSA9IENvdW50LCBjb2xvciA9IFByaW1hcnkuVHlwZSkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBsYWJzKHRpdGxlID0gIk51bWJlciBvZiBDcmltZXMgYnkgWWVhciBmb3IgdGhlIFRvcCA1IE1vc3QgQ29tbW9uIFR5cGVzIiwNCiAgICAgICB4ID0gIlllYXIiLA0KICAgICAgIHkgPSAiQ291bnQgb2YgQ3JpbWVzIiwNCiAgICAgICBjb2xvciA9ICJDcmltZSBUeXBlIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQoNCioqUXVlc3Rpb25zIEFuc3dlcmVkOioqDQoNCi0gICBXaGF0IGFyZSB0aGUgdHJlbmRzIGluIHRoZSBudW1iZXIgb2YgY2FzZXMgZm9yIHRoZSB0b3AgNSBtb3N0IGNvbW1vbiBjcmltZSB0eXBlcyBvdmVyIHRoZSB5ZWFycz8NCg0KLSAgIEhvdyBkbyB0aGUgZnJlcXVlbmNpZXMgb2YgdGhlc2UgdG9wIDUgY3JpbWVzIGNoYW5nZSBhbm51YWxseT8NCg0KKipPYnNlcnZhdGlvbnM6KioNCg0KLSAgIE5hcmNvdGljcywgVGhlZnQsIGFuZCBCYXR0ZXJ5IHNob3cgYSBzaWduaWZpY2FudCBkZWNsaW5lIGluIHRoZSBudW1iZXIgb2YgcmVwb3J0ZWQgY2FzZXMgb3ZlciB0aGUgeWVhcnMuDQoNCi0gICBBc3NhdWx0IGhhcyBzaG93biByZWxhdGl2ZSBzdGFiaWxpdHksIHdpdGggbGl0dGxlIGNoYW5nZSBpbiBpdHMgZnJlcXVlbmN5IG92ZXIgdGltZSBjb21wYXJlZCB0byB0aGUgb3RoZXIgY3JpbWUgdHlwZXMuDQoNCmBgYHtyfQ0KIyBGaWx0ZXIgZGF0YXNldCB0byBpbmNsdWRlIG9ubHkgdGhlIHRvcCA1IGNyaW1lcw0KdG9wXzVfY3JpbWVzX2xpc3QgPC0gdG9wXzVfY3JpbWVzJFByaW1hcnkuVHlwZQ0KZmlsdGVyZWRfZGF0YSA8LSBjcmltZV9kYXRhICU+JQ0KICBmaWx0ZXIoUHJpbWFyeS5UeXBlICVpbiUgdG9wXzVfY3JpbWVzX2xpc3QpDQoNCiMgU3VtbWFyaXplIHRoZSBkYXRhIGJ5IHllYXIgYW5kIGNyaW1lIHR5cGUNCnN1bW1hcnlfZGF0YSA8LSBmaWx0ZXJlZF9kYXRhICU+JQ0KICBncm91cF9ieShZZWFyLCBQcmltYXJ5LlR5cGUpICU+JQ0KICBzdW1tYXJpc2UoQ2FzZXMgPSBuKCksDQogICAgICAgICAgICBBcnJlc3RzID0gc3VtKEFycmVzdCA9PSAidHJ1ZSIpLC5ncm91cHMgPSAnZHJvcCcpDQoNCiMgQ3JlYXRlIGEgc2NhdHRlciBwbG90DQpnZ3Bsb3Qoc3VtbWFyeV9kYXRhLCBhZXMoeCA9IENhc2VzLCB5ID0gQXJyZXN0cywgY29sb3IgPSBQcmltYXJ5LlR5cGUpKSArDQogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjcsIHNpemUgPSAzKSArDQogIGxhYnModGl0bGUgPSAiTnVtYmVyIG9mIENhc2VzIHZzLiBOdW1iZXIgb2YgQXJyZXN0cyBmb3IgVG9wIDUgQ3JpbWVzIiwNCiAgICAgICB4ID0gIk51bWJlciBvZiBDYXNlcyIsDQogICAgICAgeSA9ICJOdW1iZXIgb2YgQXJyZXN0cyIsDQogICAgICAgY29sb3IgPSAiUHJpbWFyeSBUeXBlIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQoNCioqUXVlc3Rpb25zIEFuc3dlcmVkOioqDQoNCi0gICBXaGF0IGlzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgbnVtYmVyIG9mIGNhc2VzIGFuZCB0aGUgbnVtYmVyIG9mIGFycmVzdHMgZm9yIHRoZSB0b3AgNSBjcmltZXM/DQoNCi0gICBBcmUgdGhlcmUgYW55IHBhdHRlcm5zIGluIGhvdyBhcnJlc3RzIGNvcnJlc3BvbmQgdG8gdGhlIG51bWJlciBvZiBjYXNlcyBmb3IgZGlmZmVyZW50IGNyaW1lIHR5cGVzPw0KDQoqKk9ic2VydmF0aW9uczoqKg0KDQotICAgVGhlcmUgaXMgYSBnZW5lcmFsIHRyZW5kIHdoZXJlIHRoZSBudW1iZXIgb2YgYXJyZXN0cyBpbmNyZWFzZXMgd2l0aCB0aGUgbnVtYmVyIG9mIGNhc2VzIGZvciBtb3N0IGNyaW1lIHR5cGVzLg0KDQotICAgTmFyY290aWNzIHNob3dzIHRoZSBzdHJvbmdlc3QgY29ycmVsYXRpb24sIHdpdGggYSBub3RhYmxlIGluY3JlYXNlIGluIGFycmVzdHMgY29ycmVzcG9uZGluZyB0byBhIGhpZ2hlciBudW1iZXIgb2YgY2FzZXMuDQoNCi0gICBPdGhlciBjcmltZSB0eXBlcyBhbHNvIGV4aGliaXQgYW4gaW5jcmVhc2UgaW4gYXJyZXN0cyB3aXRoIG1vcmUgY2FzZXMsIGJ1dCB0aGUgY29ycmVsYXRpb24gaXMgbGVzcyBwcm9ub3VuY2VkIGNvbXBhcmVkIHRvIG5hcmNvdGljcy4NCg0KYGBge3J9DQojIFN1bW1hcml6ZSB0aGUgZGF0YSBieSB5ZWFyIGFuZCBjcmltZSB0eXBlDQpzdW1tYXJ5X2RhdGEgPC0gZmlsdGVyZWRfZGF0YSAlPiUNCiAgZ3JvdXBfYnkoWWVhciwgUHJpbWFyeS5UeXBlKSAlPiUNCiAgc3VtbWFyaXNlKENhc2VzID0gbigpLA0KICAgICAgICAgICAgQXJyZXN0cyA9IHN1bShBcnJlc3QgPT0gInRydWUiKSwgICMgU3VtbWFyaXplIHRoZSBudW1iZXIgb2YgYXJyZXN0cw0KICAgICAgICAgICAgLmdyb3VwcyA9ICdkcm9wJykNCg0KIyBDcmVhdGUgYSBidWJibGUgcGxvdA0KZ2dwbG90KHN1bW1hcnlfZGF0YSwgYWVzKHggPSBZZWFyLCB5ID0gQ2FzZXMsIHNpemUgPSBBcnJlc3RzLCBjb2xvciA9IFByaW1hcnkuVHlwZSkpICsNCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNykgKw0KICBzY2FsZV9zaXplX2NvbnRpbnVvdXMocmFuZ2UgPSBjKDIsIDEwKSwgbmFtZSA9ICJOdW1iZXIgb2YgQXJyZXN0cyIpICsNCiAgbGFicyh0aXRsZSA9ICJCdWJibGUgUGxvdCBvZiBOdW1iZXIgb2YgQ2FzZXMgYW5kIEFycmVzdHMgZm9yIFRvcCA1IENyaW1lcyIsDQogICAgICAgeCA9ICJZZWFyIiwNCiAgICAgICB5ID0gIk51bWJlciBvZiBDYXNlcyIsDQogICAgICAgY29sb3IgPSAiUHJpbWFyeSBUeXBlIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KYGBgDQoNCioqUXVlc3Rpb25zIEFuc3dlcmVkOioqDQoNCi0gICBXaGF0IGlzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgbnVtYmVyIG9mIGNhc2VzIGFuZCB0aGUgbnVtYmVyIG9mIGFycmVzdHMgZm9yIGRpZmZlcmVudCBjcmltZSB0eXBlcyBvdmVyIHRoZSB5ZWFycz8NCg0KKipPYnNlcnZhdGlvbnM6KioNCg0KLSAgIEJ1YmJsZSBTaXplIHJlZmxlY3RzIHRoZSBudW1iZXIgb2YgYXJyZXN0cy4gTGFyZ2VyIGJ1YmJsZXMgaW5kaWNhdGUgYSBoaWdoZXIgbnVtYmVyIG9mIGFycmVzdHMuDQoNCi0gICBDb2xvciBDb2RpbmcgYWxsb3dzIGNvbXBhcmlzb24gb2YgZGlmZmVyZW50IGNyaW1lIHR5cGVzIGFuZCB0aGVpciB0cmVuZHMuDQoNCi0gICBOYXJjb3RpY3Mgc2hvd3MgY29uc2lzdGVudGx5IGxhcmdlciBidWJibGVzIGFuZCBhIHNpZ25pZmljYW50IGRyb3AgaW4gdGhlIG51bWJlciBvZiBjYXNlcyBvdmVyIHRoZSB5ZWFycy4NCg==