About

R can be used for basic visual analytics, which is very helpful in understanding the data holistically. Additionally, R can help find correlations between variables and create scatter plots.

Tableau is a tool more tailored for visual analytics, while R is a powerful tool for statistics and other advanced topics in data analytics. In this lab we will explore both capabilities using the two earlier sets of data for credist risk and marketing.

Setup

Remember to always set your working directory to the source file location. Go to ‘Session’, scroll down to ‘Set Working Directory’, and click ‘To Source File Location’. Read carefully the below and follow the instructions to complete the tasks and answer any questions. Submit your work in Sakai as detailed in previous notes.

Note

For your assignment you may be using different data sets than what is included here. Always read carefully the instructions provided, before executing any included code chunks and/or adding your own code. For clarity, tasks/questions to be completed/answered are highlighted in red color and numbered according to their particular placement in the task section. The red color is only apparent when in Preview mode. Quite often you will need to add your own code chunk.

Execute all code chunks (already included and own added), preview, check integrity, and submit final work (\(html\) file) in Sakai.


Task 1: Basic Visual Analytics in R

We start by reading the file marketing.csv and make sure all columns are read properly by viewing the first couple rows of the dataset.

mydata = read.csv("marketing.csv")
head(mydata)

Steps to create a bar chart using a categorical variable are shown below.

# Extract the State column from mydata
state = mydata$State
# Create a frequency table to extract the count for each state
state_table = table(state)
# Execute the  command 
barplot(state_table)

##### 1A) Use the code chunk below to repeat the above bar chart by adding proper labels to X and Y axis. (1pt)

# Add title and labels to plot by replacing the ?? with the proper wordings
barplot(state_table, main = 'Frequency of Ads in Each State', xlab= 'State of Ad', ylab = 'Frequency' )

A more elegant representation of the bar plot would be to order the bars by increasing value. This is shown in the code chunk below.

# Order and execute
barplot(state_table[order(state_table)])

Next we will create a histogram.

# Extract the TV column from the data and create a histogram by running the command hist(variable) 
# where variable corresponds to the extracted sales column variable
tv=mydata$tv
hist(tv)

As seen, the histogram differs from a barplot in two distinctive ways: the x-axis is numeric (although not always necessary) broken in continuous intervals called bins, and the y-axis is representative of number of observations or frequency. The number of bins can be adjusted to show a finer resolution or breakdown of intervals. This is demonstrated in the below example.

hist(tv, breaks=20)

hist(tv, breaks=40)

hist(tv, breaks=10)

##### 1B) Explain, in quantifiable terms, the major difference between the two histograms: lower and higher bin numbers. Show how can you obtain a more exact count of each occurence? (1pt) A histogram’s x-axis displays a range of numerical values, in this case the number of TV sales. These intervals, or bins, show the range of numbers. A lower bin number (as seen in break=10) means that each individual range is more broad. This shows less finely-tuned or specific data. A higher bin number (as seen in break=40) shows finer data. A higher break, or a higher bin number shows smaller continuous intervals of data. This shows a smaller range that each frequency can identify with. If you look at break=40, there are several sections of the histogram showing the frequency between 250 and 255. The total between this range is 6. In break=10, there is one section between 250 and 255, still showing a frequency of 6 between this range. Both histograms can be used to show the differences in bin size. As you can see, break=40 shows a more exact count of the data.

##### 1C) Create a new histogram plot for Sales. Explain what the x-axis and y-axis represent. Can one derive the total cummulative sales from the histogram? Explain your answer (1pt)

sales=mydata$sales
hist(sales)

No, you cannot derive the total number of sales from a histogram like this one. The x-axis shows continuous ranges of data, so the specifics of each sale amount cannot be found. Because the sales data is continuous, and the histogram only shows ranges of data, it would not be possible to sum the total number of sales. For example, if you were to sum the total data from the first bin you would get 1*anything in between 12000 and 10000. This is not an exact calculation, and shows it is not possible to find exact amounts.

How to create a pie chart

# The command to create a pie chart is pie(variable) where  variable is in reference to the particular column extracted from the file. In this example we define a variable called x. 
x = c(2,3,4,5)
pie(x)

##### 1D) Create a new pie chart for state count. Refer to earlier defined variable state_table to capture the frequency count (1pt)

state_table = table(state)
x = state_table
pie(x)

##### 1E) What does each slice of the pie represent? Compare the pie chart to earlier bar charts. Which type of charts is a better representation of the data and why so?(1pt) Each slice of the pie represents the proportion of total ads in each state. For example, there are 20 frequencies total. Arizona has 3 of those frequenies, so AZ has a proportion of 3/20 or 15% of total ads. The pie chart shows the data relative to other data. So AZ’s ads are shown relative to IL frequency. The pie chart does not show exact number of each state’s frequency. This makes the pie chart less usable in decision making, but it does make a nice visual. I think the bar plot is the better representaion of data. I think this because it shows the actual number of frequencies, and the size of each bar shows a visual of how the number of frequencies varies relative to each state. /———-

Task 2 Scatter Plots & Correlation

The previous task focused on visualizing one variable. A good way to visualize two variables, and also quite common, is a scatter plot. A scatter plot is a good way to study relationships, associations, and trends.

Follwoing is an example of a scatter plot, with a fitted line.

# Plot Sales vs. Radio
# Radio will be on the x-axis
# Sales will be on the y-axis

sales = mydata$sales
radio = mydata$radio
plot(radio,sales)


# It is easier to see the trend and possible relationship by including a line that fit through the points.
# This is done with the command 
scatter.smooth(radio,sales)

##### 2A) Create three separate scatter plots for Sales vs TV, Sales vs Paper, and Sales vs Pos. Label properly. Include the best fitting line in each plot. Pay attention to what variable goes on the x-axis and the y-axis (1pt)

# Plot Sales vs. TV
# TV will be on the x-axis
# Sales will be on the y-axis

sales = mydata$sales
tv = mydata$tv
plot(tv,sales)


# It is easier to see the trend and possible relationship by including a line that fit through the points.
# This is done with the command 
scatter.smooth(tv,sales)

# Plot Sales vs. Paper
# Paper will be on the x-axis
# Sales will be on the y-axis

sales = mydata$sales
paper = mydata$paper
plot(paper,sales)


# It is easier to see the trend and possible relationship by including a line that fit through the points.
# This is done with the command 
scatter.smooth(paper,sales)

# Plot Sales vs. Pos
# Radio will be on the x-axis
# Sales will be on the y-axis

sales = mydata$sales
pos = mydata$pos
plot(pos,sales)


# It is easier to see the trend and possible relationship by including a line that fit through the points.
# This is done with the command 
scatter.smooth(pos,sales)

##### 2B) Share your observations on trends and relationships. How do your observations reconcile with your findings from lab05? (1pt)

In Lab05, I said: Radio VS sales graph had a positive and very linear relationship. This means that the sales rank will increase as the expenditures on radio ads goes up. Because it is linear, each sales rank will increase proportionally with the increase of radio expenditures.

Paper VS sales graph shows a negative correllation. This means that as the sales rank decreases, the expenditure on news ads increases. This may mean that news ads are not as effective, but we cannot prove this. There is only a negative correlation.

TV VS Sales graph has a positive relationship.. This means as TV advertisement costs increase, the sales rank will also increase. This may mean that the money spent on TV ads helps to improve the sales amount, but this is not proven.

In the relationship model, it is obvious sales and radio, and sales and TV have a strong positive relationship. Sales and radio is very linear. Sales and paper have a negative relationship, but it is not perfectly linear. Overal, Sales and Radio had a very strong almost linear positive correlation, sales and TV had a stong positive correlation, and paper and sales had negative relationship. While lab 05 used scatterplots, we could not clearly identify the relationship. Now we have more data to use in our analysis.

As part of any data anlytics it is important to consider both qualitative and quantitative analysis. Scatter plots provide us with qualitative insights on possible trends and relationships. To quantify the strength of any relationships in the data, we need to look at the correlation between two variables.

To compute the correlation coefficient or strength between variables follow the below example.

cor(sales,radio)
[1] 0.9771381

##### 2C) Repeat the correlation calculation for the following pair of variables (sales,tv), (sales,paper), and (sales,pos) (1pt)

#correlation between sales and TV

cor(sales,tv)
[1] 0.9579703
#correlation between sales and paper
cor(sales,paper)
[1] -0.2830683
#corelation between sales and pos
pos=mydata$pos
cor(sales,pos)
[1] 0.0126486

##### 2D) Which pair has the highest correlation? How do these results reconcile with your scatter plots observations? (1pt)

The correlation between sales and radio is the strongest. A perfect correlation would be when it equals 1 or -1. This correlation would be perfectly linear. This means that This means that the strongest correlation would be between sales and radio at 0.9771381. The scatterplots also reflect this. the sales and radio one shows a very linear relationship. This scatter plot shows the best linear relationship, visually. It reconciles the relationship found.

A more encompassing correlation calculation considers all variables in a data file to compute the equivalent of a correlation matrix. One way to visualize a correlation matrix is by using correlograms. A corrgram is an exploratory way to display a correlation matrix. In R this is done by installing a new package as demonstrated in the below code example.

# Code to install a package
install.packages("corrgram")
library("corrgram")
# Corrgram command showing the minmax and variable name aloong diagonal. Depth of shading indicates
corrgram(mydata, main="Marketing Data Correlation Matrix", lower.panel=panel.shade, diag.panel=panel.minmax, text.panel=panel.txt)

There are many other ways to do a corrgram in R. A quick Google search on the topic, can reveal some interesting options. You can check for example the Quick-R site at https://www.statmethods.net/advgraphs/correlograms.html

##### 2E) Select a corrgram of your choice and different from the one exhibited in this worksheet. Execute the code to display the output. Note that you don’t need to install the package again as long as it is executed once earlier (1pt)


corrgram(mydata, order=TRUE, main="Marketing Data Correlation Matrix", panel=panel.shade, text.panel=panel.txt)

NA
NA
NA

Task 3 - Basic Visual Analytics in Tableau

Follow the directions on the worksheet, download tableau academic on your personal computer or use one of the labs computers. Make sure to download the academic version and not the free limited trial version.

– Download Tableau academic here: https://www.tableau.com/academic/students

– Refer to file ‘creditrisk.csv’ in the data folder

– Start Tableau and enter your LUC email if prompted.

– Import the file into Tableau. Choose the Text File option when importing


– Under the dimensions tab located on the left side of the screen DOUBLE click on the ‘Loan Purpose’, then DOUBLE click on ‘Number of Records’ variable located under Measures on the bottom left of the screen.

– From the upper right corner of the screen select the horizontal bars view and note the new chart. Familiarize yourself with the tool by trying other views. Only valid views will be highlighted in the menu.

– Create a new sheet by clicking on the icon in the bottom next to your current sheet.

##### 3A) Double-click on the ‘Age’ variable in Measures and select the ‘Histogram’ view. Capture a screen shot and include here. Which age bin has the highest age count and what is the count? (2pts)

age bin with highest age count: 22 count: 97

3B) Drag-drop the variable ’Marital Status’found under Dimensions into the Marks Color box. Capture a screen shot and include here. Which age bin has the highest divorce count and what is the count? (2pts)

age bin with highest divorce count:22 count: 46

##### 3C) Create another new sheet. Double-click ‘Months Employed’ and then double-click ‘Age’. Make sure Age appears in the columns field as shown in the image below. From the Sum(Age) drop down menu select Dimension. Repeat for Sum(Months Employed). Add another variable to the scatter plot by drag-drop the dimension variable ‘Gender’ into the Marks Color box. Capture a screen shot and include here. Share insights on what the data is telling us (3pts)

This data shows age on the x axis, months of employment on the y axis, and the gender based on the color of the data point. The orange dots are male, and the blue dots are female. This visual shows the distribution of months employed, age, and gender. There is a lot of data close to the x axis, meaning the months of employment is close to 0, or a shorter period of time. There also appears to be more data points towards the origin of the graph. This means that the age skews towards younger people and that the employment length skews towards people who have not held the job as long. Also, there appears to be more orand dots, and this means that there may be more men in this data set. This means there may be more men applying for loans.

##### 3D) In a new sheet generate a view of Gender, Number of Records, and Marital Status. Choose the best fitting view of your choice for the intended scope. Capture a screen shot and include here. Share insights on what the data is telling us (3pts)

The data is to analyze number of records with marital status. Marital status is categorical data(x-axis), and number of records is quantifable (y-axis). Gender is being identfied by a color (orange is male, blue is female)in the data set. I used a graph that showed the number of records, not the relative size. This data shows that the number of records is highest in singles. Men are the only people that have applied for loans under the status of single. Females have only applied for loans when divorced. Out of each of the marital statuses, married individuals have applied for loans the least, and singles have applied for loans the most. Divorcees are in between singles and married people in the number of records. However, the majority of divorcees are women.


LS0tDQp0aXRsZTogIkJhc2ljIFZpc3VhbCBBbmFseXRpY3MgKGxhYjA2KSINCmF1dGhvcjogIkxhdXJlbiBLcm9sbCINCmRhdGU6ICIyLzI3LzIwMjAiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQNCiAgaHRtbF9kb2N1bWVudDogZGVmYXVsdA0Kc3VidGl0bGU6IEJTQUQgMzQzLCBCdXNpbmVzcyBBbmFseXRpY3MsIFNwcmluZyAyMDIwDQotLS0NCg0KIyMjIEFib3V0DQoNClIgY2FuIGJlIHVzZWQgZm9yIGJhc2ljIHZpc3VhbCBhbmFseXRpY3MsIHdoaWNoIGlzIHZlcnkgaGVscGZ1bCBpbiB1bmRlcnN0YW5kaW5nIHRoZSBkYXRhIGhvbGlzdGljYWxseS4gQWRkaXRpb25hbGx5LCBSIGNhbiBoZWxwIGZpbmQgY29ycmVsYXRpb25zIGJldHdlZW4gdmFyaWFibGVzIGFuZCBjcmVhdGUgc2NhdHRlciBwbG90cy4gDQoNClRhYmxlYXUgaXMgYSB0b29sIG1vcmUgdGFpbG9yZWQgZm9yIHZpc3VhbCBhbmFseXRpY3MsIHdoaWxlIFIgaXMgYSAgcG93ZXJmdWwgdG9vbCBmb3Igc3RhdGlzdGljcyBhbmQgb3RoZXIgYWR2YW5jZWQgdG9waWNzIGluIGRhdGEgYW5hbHl0aWNzLiBJbiB0aGlzIGxhYiAgd2Ugd2lsbCBleHBsb3JlIGJvdGggY2FwYWJpbGl0aWVzIHVzaW5nIHRoZSB0d28gZWFybGllciBzZXRzIG9mIGRhdGEgZm9yIGNyZWRpc3QgcmlzayBhbmQgbWFya2V0aW5nLiANCg0KIyMjIFNldHVwDQoNClJlbWVtYmVyIHRvIGFsd2F5cyBzZXQgeW91ciB3b3JraW5nIGRpcmVjdG9yeSB0byB0aGUgc291cmNlIGZpbGUgbG9jYXRpb24uIEdvIHRvICdTZXNzaW9uJywgc2Nyb2xsIGRvd24gdG8gJ1NldCBXb3JraW5nIERpcmVjdG9yeScsIGFuZCBjbGljayAnVG8gU291cmNlIEZpbGUgTG9jYXRpb24nLiBSZWFkIGNhcmVmdWxseSB0aGUgYmVsb3cgYW5kIGZvbGxvdyB0aGUgaW5zdHJ1Y3Rpb25zIHRvIGNvbXBsZXRlIHRoZSB0YXNrcyBhbmQgYW5zd2VyIGFueSBxdWVzdGlvbnMuICBTdWJtaXQgeW91ciB3b3JrIGluIFNha2FpIGFzIGRldGFpbGVkIGluIHByZXZpb3VzIG5vdGVzLiANCg0KIyMjIE5vdGUNCg0KRm9yIHlvdXIgYXNzaWdubWVudCB5b3UgbWF5IGJlIHVzaW5nIGRpZmZlcmVudCBkYXRhIHNldHMgdGhhbiB3aGF0IGlzIGluY2x1ZGVkIGhlcmUuIEFsd2F5cyByZWFkIGNhcmVmdWxseSB0aGUgaW5zdHJ1Y3Rpb25zIHByb3ZpZGVkLCBiZWZvcmUgZXhlY3V0aW5nIGFueSBpbmNsdWRlZCBjb2RlIGNodW5rcyBhbmQvb3IgYWRkaW5nIHlvdXIgb3duIGNvZGUuICBGb3IgY2xhcml0eSwgdGFza3MvcXVlc3Rpb25zIHRvIGJlIGNvbXBsZXRlZC9hbnN3ZXJlZCBhcmUgaGlnaGxpZ2h0ZWQgaW4gcmVkIGNvbG9yIGFuZCBudW1iZXJlZCBhY2NvcmRpbmcgdG8gdGhlaXIgcGFydGljdWxhciBwbGFjZW1lbnQgaW4gdGhlIHRhc2sgc2VjdGlvbi4gIFRoZSByZWQgY29sb3IgaXMgb25seSBhcHBhcmVudCB3aGVuIGluIFByZXZpZXcgbW9kZS4gUXVpdGUgb2Z0ZW4geW91IHdpbGwgbmVlZCB0byBhZGQgeW91ciBvd24gY29kZSBjaHVuay4NCg0KRXhlY3V0ZSBhbGwgY29kZSBjaHVua3MgKGFscmVhZHkgaW5jbHVkZWQgYW5kIG93biBhZGRlZCksIHByZXZpZXcsIGNoZWNrIGludGVncml0eSwgYW5kIHN1Ym1pdCBmaW5hbCB3b3JrICgkaHRtbCQgZmlsZSkgaW4gU2FrYWkuDQoNCi0tLS0tLS0tLS0tLS0tDQoNCg0KIyMjIFRhc2sgMTogQmFzaWMgVmlzdWFsIEFuYWx5dGljcyBpbiBSDQoNCldlIHN0YXJ0IGJ5IHJlYWRpbmcgdGhlIGZpbGUgYG1hcmtldGluZy5jc3ZgIGFuZCBtYWtlIHN1cmUgYWxsIGNvbHVtbnMgYXJlIHJlYWQgcHJvcGVybHkgYnkgdmlld2luZyB0aGUgZmlyc3QgY291cGxlIHJvd3Mgb2YgdGhlIGRhdGFzZXQuIA0KDQpgYGB7cn0NCm15ZGF0YSA9IHJlYWQuY3N2KCJtYXJrZXRpbmcuY3N2IikNCmhlYWQobXlkYXRhKQ0KYGBgDQoNClN0ZXBzIHRvIGNyZWF0ZSBhIGJhciBjaGFydCB1c2luZyBhIGNhdGVnb3JpY2FsIHZhcmlhYmxlIGFyZSBzaG93biBiZWxvdy4NCg0KYGBge3J9DQojIEV4dHJhY3QgdGhlIFN0YXRlIGNvbHVtbiBmcm9tIG15ZGF0YQ0Kc3RhdGUgPSBteWRhdGEkU3RhdGUNCiMgQ3JlYXRlIGEgZnJlcXVlbmN5IHRhYmxlIHRvIGV4dHJhY3QgdGhlIGNvdW50IGZvciBlYWNoIHN0YXRlDQpzdGF0ZV90YWJsZSA9IHRhYmxlKHN0YXRlKQ0KIyBFeGVjdXRlIHRoZSAgY29tbWFuZCANCmJhcnBsb3Qoc3RhdGVfdGFibGUpDQpgYGANCg0KPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+DQojIyMjIyAxQSkgVXNlIHRoZSBjb2RlIGNodW5rIGJlbG93IHRvIHJlcGVhdCB0aGUgYWJvdmUgYmFyIGNoYXJ0IGJ5IGFkZGluZyBwcm9wZXIgbGFiZWxzIHRvIFggYW5kIFkgYXhpcy4gKDFwdCkNCjwvc3Bhbj4NCg0KYGBge3J9DQojIEFkZCB0aXRsZSBhbmQgbGFiZWxzIHRvIHBsb3QgYnkgcmVwbGFjaW5nIHRoZSA/PyB3aXRoIHRoZSBwcm9wZXIgd29yZGluZ3MNCmJhcnBsb3Qoc3RhdGVfdGFibGUsIG1haW4gPSAnRnJlcXVlbmN5IG9mIEFkcyBpbiBFYWNoIFN0YXRlJywgeGxhYj0gJ1N0YXRlIG9mIEFkJywgeWxhYiA9ICdGcmVxdWVuY3knICkNCmBgYA0KDQpBIG1vcmUgZWxlZ2FudCByZXByZXNlbnRhdGlvbiBvZiB0aGUgYmFyIHBsb3Qgd291bGQgYmUgdG8gb3JkZXIgdGhlIGJhcnMgYnkgaW5jcmVhc2luZyB2YWx1ZS4gIFRoaXMgaXMgc2hvd24gaW4gdGhlIGNvZGUgY2h1bmsgYmVsb3cuDQoNCmBgYHtyfQ0KIyBPcmRlciBhbmQgZXhlY3V0ZQ0KYmFycGxvdChzdGF0ZV90YWJsZVtvcmRlcihzdGF0ZV90YWJsZSldKQ0KYGBgDQoNCg0KTmV4dCB3ZSB3aWxsIGNyZWF0ZSBhIGhpc3RvZ3JhbS4NCg0KYGBge3J9DQojIEV4dHJhY3QgdGhlIFRWIGNvbHVtbiBmcm9tIHRoZSBkYXRhIGFuZCBjcmVhdGUgYSBoaXN0b2dyYW0gYnkgcnVubmluZyB0aGUgY29tbWFuZCBoaXN0KHZhcmlhYmxlKSANCiMgd2hlcmUgdmFyaWFibGUgY29ycmVzcG9uZHMgdG8gdGhlIGV4dHJhY3RlZCBzYWxlcyBjb2x1bW4gdmFyaWFibGUNCnR2PW15ZGF0YSR0dg0KaGlzdCh0dikNCmBgYA0KDQpBcyBzZWVuLCB0aGUgaGlzdG9ncmFtIGRpZmZlcnMgZnJvbSBhIGJhcnBsb3QgaW4gdHdvIGRpc3RpbmN0aXZlIHdheXM6IHRoZSB4LWF4aXMgaXMgbnVtZXJpYyAoYWx0aG91Z2ggbm90IGFsd2F5cyBuZWNlc3NhcnkpIGJyb2tlbiBpbiBjb250aW51b3VzIGludGVydmFscyBjYWxsZWQgYmlucywgYW5kIHRoZSB5LWF4aXMgaXMgcmVwcmVzZW50YXRpdmUgb2YgbnVtYmVyIG9mIG9ic2VydmF0aW9ucyBvciBmcmVxdWVuY3kuICBUaGUgbnVtYmVyIG9mIGJpbnMgY2FuIGJlIGFkanVzdGVkIHRvIHNob3cgYSBmaW5lciByZXNvbHV0aW9uIG9yIGJyZWFrZG93biBvZiBpbnRlcnZhbHMuICBUaGlzIGlzIGRlbW9uc3RyYXRlZCBpbiB0aGUgYmVsb3cgZXhhbXBsZS4NCg0KYGBge3J9DQpoaXN0KHR2LCBicmVha3M9MjApDQpgYGANCmBgYHtyfQ0KaGlzdCh0diwgYnJlYWtzPTQwKQ0KYGBgDQpgYGB7cn0NCmhpc3QodHYsIGJyZWFrcz0xMCkNCmBgYA0KDQo8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj4NCiMjIyMjIDFCKSBFeHBsYWluLCBpbiBxdWFudGlmaWFibGUgdGVybXMsICB0aGUgbWFqb3IgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSB0d28gaGlzdG9ncmFtczogbG93ZXIgYW5kIGhpZ2hlciBiaW4gbnVtYmVycy4gIFNob3cgaG93IGNhbiB5b3Ugb2J0YWluIGEgbW9yZSBleGFjdCBjb3VudCBvZiBlYWNoIG9jY3VyZW5jZT8gKDFwdCkNCjwvc3Bhbj4NCiBBIGhpc3RvZ3JhbSdzIHgtYXhpcyBkaXNwbGF5cyBhIHJhbmdlIG9mIG51bWVyaWNhbCB2YWx1ZXMsIGluIHRoaXMgY2FzZSB0aGUgbnVtYmVyIG9mIFRWIHNhbGVzLiBUaGVzZSBpbnRlcnZhbHMsIG9yIGJpbnMsIHNob3cgdGhlIHJhbmdlIG9mIG51bWJlcnMuICBBIGxvd2VyIGJpbiBudW1iZXIgKGFzIHNlZW4gaW4gYnJlYWs9MTApIG1lYW5zIHRoYXQgZWFjaCBpbmRpdmlkdWFsIHJhbmdlIGlzIG1vcmUgYnJvYWQuIFRoaXMgc2hvd3MgbGVzcyBmaW5lbHktdHVuZWQgb3Igc3BlY2lmaWMgZGF0YS4gIEEgaGlnaGVyIGJpbiBudW1iZXIgKGFzIHNlZW4gaW4gYnJlYWs9NDApIHNob3dzIGZpbmVyIGRhdGEuIEEgaGlnaGVyIGJyZWFrLCBvciBhIGhpZ2hlciBiaW4gbnVtYmVyIHNob3dzIHNtYWxsZXIgY29udGludW91cyBpbnRlcnZhbHMgb2YgZGF0YS4gVGhpcyBzaG93cyBhIHNtYWxsZXIgcmFuZ2UgdGhhdCBlYWNoIGZyZXF1ZW5jeSBjYW4gaWRlbnRpZnkgd2l0aC4gSWYgeW91IGxvb2sgYXQgYnJlYWs9NDAsIHRoZXJlIGFyZSBzZXZlcmFsIHNlY3Rpb25zIG9mIHRoZSBoaXN0b2dyYW0gc2hvd2luZyB0aGUgZnJlcXVlbmN5IGJldHdlZW4gMjUwIGFuZCAyNTUuIFRoZSB0b3RhbCBiZXR3ZWVuIHRoaXMgcmFuZ2UgaXMgNi4gIEluIGJyZWFrPTEwLCB0aGVyZSBpcyBvbmUgc2VjdGlvbiBiZXR3ZWVuIDI1MCBhbmQgMjU1LCBzdGlsbCBzaG93aW5nIGEgZnJlcXVlbmN5IG9mIDYgYmV0d2VlbiB0aGlzIHJhbmdlLiAgQm90aCBoaXN0b2dyYW1zIGNhbiBiZSB1c2VkIHRvIHNob3cgdGhlIGRpZmZlcmVuY2VzIGluIGJpbiBzaXplLiAgQXMgeW91IGNhbiBzZWUsIGJyZWFrPTQwIHNob3dzIGEgbW9yZSBleGFjdCBjb3VudCBvZiB0aGUgZGF0YS4gDQoNCjxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPg0KIyMjIyMgMUMpIENyZWF0ZSBhIG5ldyBoaXN0b2dyYW0gcGxvdCBmb3IgU2FsZXMuIEV4cGxhaW4gd2hhdCB0aGUgeC1heGlzIGFuZCB5LWF4aXMgcmVwcmVzZW50LiBDYW4gb25lIGRlcml2ZSB0aGUgdG90YWwgY3VtbXVsYXRpdmUgc2FsZXMgZnJvbSB0aGUgaGlzdG9ncmFtPyBFeHBsYWluIHlvdXIgYW5zd2VyICgxcHQpDQo8L3NwYW4+DQoNCmBgYHtyfQ0Kc2FsZXM9bXlkYXRhJHNhbGVzDQpoaXN0KHNhbGVzKQ0KYGBgDQoNCk5vLCB5b3UgY2Fubm90IGRlcml2ZSB0aGUgdG90YWwgbnVtYmVyIG9mIHNhbGVzIGZyb20gYSBoaXN0b2dyYW0gbGlrZSB0aGlzIG9uZS4gIFRoZSB4LWF4aXMgc2hvd3MgY29udGludW91cyByYW5nZXMgb2YgZGF0YSwgc28gdGhlIHNwZWNpZmljcyBvZiBlYWNoIHNhbGUgYW1vdW50IGNhbm5vdCBiZSBmb3VuZC4gQmVjYXVzZSB0aGUgc2FsZXMgZGF0YSBpcyBjb250aW51b3VzLCBhbmQgdGhlIGhpc3RvZ3JhbSBvbmx5IHNob3dzIHJhbmdlcyBvZiBkYXRhLCBpdCB3b3VsZCBub3QgYmUgcG9zc2libGUgdG8gc3VtIHRoZSB0b3RhbCBudW1iZXIgb2Ygc2FsZXMuIA0KRm9yIGV4YW1wbGUsIGlmIHlvdSB3ZXJlIHRvIHN1bSB0aGUgdG90YWwgZGF0YSBmcm9tIHRoZSBmaXJzdCBiaW4geW91IHdvdWxkIGdldCAxKmFueXRoaW5nIGluIGJldHdlZW4gMTIwMDAgYW5kIDEwMDAwLiBUaGlzIGlzIG5vdCBhbiBleGFjdCBjYWxjdWxhdGlvbiwgYW5kIHNob3dzIGl0IGlzIG5vdCBwb3NzaWJsZSB0byBmaW5kIGV4YWN0IGFtb3VudHMuIA0KDQpIb3cgdG8gY3JlYXRlIGEgcGllIGNoYXJ0DQpgYGB7cn0NCiMgVGhlIGNvbW1hbmQgdG8gY3JlYXRlIGEgcGllIGNoYXJ0IGlzIHBpZSh2YXJpYWJsZSkgd2hlcmUgIHZhcmlhYmxlIGlzIGluIHJlZmVyZW5jZSB0byB0aGUgcGFydGljdWxhciBjb2x1bW4gZXh0cmFjdGVkIGZyb20gdGhlIGZpbGUuIEluIHRoaXMgZXhhbXBsZSB3ZSBkZWZpbmUgYSB2YXJpYWJsZSBjYWxsZWQgeC4gDQp4ID0gYygyLDMsNCw1KQ0KcGllKHgpDQpgYGANCg0KPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+DQojIyMjIyAxRCkgQ3JlYXRlIGEgbmV3IHBpZSBjaGFydCBmb3Igc3RhdGUgY291bnQuIFJlZmVyIHRvIGVhcmxpZXIgZGVmaW5lZCB2YXJpYWJsZSBgc3RhdGVfdGFibGVgIHRvIGNhcHR1cmUgdGhlIGZyZXF1ZW5jeSBjb3VudCAoMXB0KQ0KPC9zcGFuPg0KYGBge3J9DQpzdGF0ZV90YWJsZSA9IHRhYmxlKHN0YXRlKQ0KeCA9IHN0YXRlX3RhYmxlDQpwaWUoeCkNCmBgYA0KDQo8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj4NCiMjIyMjIDFFKSBXaGF0IGRvZXMgZWFjaCBzbGljZSBvZiB0aGUgcGllIHJlcHJlc2VudD8gQ29tcGFyZSB0aGUgcGllIGNoYXJ0IHRvIGVhcmxpZXIgYmFyIGNoYXJ0cy4gV2hpY2ggdHlwZSBvZiBjaGFydHMgaXMgYSBiZXR0ZXIgcmVwcmVzZW50YXRpb24gb2YgdGhlIGRhdGEgYW5kIHdoeSBzbz8oMXB0KQ0KPC9zcGFuPg0KRWFjaCBzbGljZSBvZiB0aGUgcGllIHJlcHJlc2VudHMgdGhlIHByb3BvcnRpb24gb2YgdG90YWwgYWRzIGluIGVhY2ggc3RhdGUuIEZvciBleGFtcGxlLCB0aGVyZSBhcmUgMjAgZnJlcXVlbmNpZXMgdG90YWwuIEFyaXpvbmEgaGFzIDMgb2YgdGhvc2UgZnJlcXVlbmllcywgc28gQVogaGFzIGEgcHJvcG9ydGlvbiBvZiAzLzIwIG9yIDE1JSBvZiB0b3RhbCBhZHMuIFRoZSBwaWUgY2hhcnQgc2hvd3MgdGhlIGRhdGEgcmVsYXRpdmUgdG8gb3RoZXIgZGF0YS4gU28gQVoncyBhZHMgYXJlIHNob3duIHJlbGF0aXZlIHRvIElMIGZyZXF1ZW5jeS4gIFRoZSBwaWUgY2hhcnQgZG9lcyBub3Qgc2hvdyBleGFjdCBudW1iZXIgb2YgZWFjaCBzdGF0ZSdzIGZyZXF1ZW5jeS4gIFRoaXMgbWFrZXMgdGhlIHBpZSBjaGFydCBsZXNzIHVzYWJsZSBpbiBkZWNpc2lvbiBtYWtpbmcsIGJ1dCBpdCBkb2VzIG1ha2UgYSBuaWNlIHZpc3VhbC4gIEkgdGhpbmsgdGhlIGJhciBwbG90IGlzIHRoZSBiZXR0ZXIgcmVwcmVzZW50YWlvbiBvZiBkYXRhLiAgSSB0aGluayB0aGlzIGJlY2F1c2UgaXQgc2hvd3MgdGhlIGFjdHVhbCBudW1iZXIgb2YgZnJlcXVlbmNpZXMsIGFuZCB0aGUgc2l6ZSBvZiBlYWNoIGJhciBzaG93cyBhIHZpc3VhbCBvZiBob3cgdGhlIG51bWJlciBvZiBmcmVxdWVuY2llcyB2YXJpZXMgcmVsYXRpdmUgdG8gZWFjaCBzdGF0ZS4gDQovLS0tLS0tLS0tLQ0KDQojIyMgVGFzayAyIFNjYXR0ZXIgUGxvdHMgJiBDb3JyZWxhdGlvbiANCg0KVGhlIHByZXZpb3VzIHRhc2sgZm9jdXNlZCBvbiB2aXN1YWxpemluZyBvbmUgdmFyaWFibGUuIEEgZ29vZCB3YXkgdG8gdmlzdWFsaXplIHR3byB2YXJpYWJsZXMsIGFuZCBhbHNvIHF1aXRlIGNvbW1vbiwgaXMgYSBzY2F0dGVyIHBsb3QuIEEgc2NhdHRlciBwbG90IGlzIGEgZ29vZCB3YXkgdG8gc3R1ZHkgcmVsYXRpb25zaGlwcywgYXNzb2NpYXRpb25zLCBhbmQgdHJlbmRzLg0KDQpGb2xsd29pbmcgaXMgYW4gZXhhbXBsZSBvZiBhIHNjYXR0ZXIgcGxvdCwgd2l0aCBhIGZpdHRlZCBsaW5lLg0KDQpgYGB7cn0NCiMgUGxvdCBTYWxlcyB2cy4gUmFkaW8NCiMgUmFkaW8gd2lsbCBiZSBvbiB0aGUgeC1heGlzDQojIFNhbGVzIHdpbGwgYmUgb24gdGhlIHktYXhpcw0KDQpzYWxlcyA9IG15ZGF0YSRzYWxlcw0KcmFkaW8gPSBteWRhdGEkcmFkaW8NCnBsb3QocmFkaW8sc2FsZXMpDQoNCiMgSXQgaXMgZWFzaWVyIHRvIHNlZSB0aGUgdHJlbmQgYW5kIHBvc3NpYmxlIHJlbGF0aW9uc2hpcCBieSBpbmNsdWRpbmcgYSBsaW5lIHRoYXQgZml0IHRocm91Z2ggdGhlIHBvaW50cy4NCiMgVGhpcyBpcyBkb25lIHdpdGggdGhlIGNvbW1hbmQgDQpzY2F0dGVyLnNtb290aChyYWRpbyxzYWxlcykNCmBgYA0KDQo8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj4NCiMjIyMjIDJBKSBDcmVhdGUgdGhyZWUgc2VwYXJhdGUgc2NhdHRlciBwbG90cyBmb3IgU2FsZXMgdnMgVFYsIFNhbGVzIHZzIFBhcGVyLCBhbmQgU2FsZXMgdnMgUG9zLiBMYWJlbCBwcm9wZXJseS4gSW5jbHVkZSB0aGUgYmVzdCBmaXR0aW5nIGxpbmUgaW4gZWFjaCBwbG90LiBQYXkgYXR0ZW50aW9uIHRvIHdoYXQgdmFyaWFibGUgZ29lcyBvbiB0aGUgeC1heGlzIGFuZCB0aGUgeS1heGlzICgxcHQpDQo8L3NwYW4+DQoNCmBgYHtyfQ0KIyBQbG90IFNhbGVzIHZzLiBUVg0KIyBUViB3aWxsIGJlIG9uIHRoZSB4LWF4aXMNCiMgU2FsZXMgd2lsbCBiZSBvbiB0aGUgeS1heGlzDQoNCnNhbGVzID0gbXlkYXRhJHNhbGVzDQp0diA9IG15ZGF0YSR0dg0KcGxvdCh0dixzYWxlcykNCg0KIyBJdCBpcyBlYXNpZXIgdG8gc2VlIHRoZSB0cmVuZCBhbmQgcG9zc2libGUgcmVsYXRpb25zaGlwIGJ5IGluY2x1ZGluZyBhIGxpbmUgdGhhdCBmaXQgdGhyb3VnaCB0aGUgcG9pbnRzLg0KIyBUaGlzIGlzIGRvbmUgd2l0aCB0aGUgY29tbWFuZCANCnNjYXR0ZXIuc21vb3RoKHR2LHNhbGVzKQ0KYGBgDQoNCg0KYGBge3J9DQojIFBsb3QgU2FsZXMgdnMuIFBhcGVyDQojIFBhcGVyIHdpbGwgYmUgb24gdGhlIHgtYXhpcw0KIyBTYWxlcyB3aWxsIGJlIG9uIHRoZSB5LWF4aXMNCg0Kc2FsZXMgPSBteWRhdGEkc2FsZXMNCnBhcGVyID0gbXlkYXRhJHBhcGVyDQpwbG90KHBhcGVyLHNhbGVzKQ0KDQojIEl0IGlzIGVhc2llciB0byBzZWUgdGhlIHRyZW5kIGFuZCBwb3NzaWJsZSByZWxhdGlvbnNoaXAgYnkgaW5jbHVkaW5nIGEgbGluZSB0aGF0IGZpdCB0aHJvdWdoIHRoZSBwb2ludHMuDQojIFRoaXMgaXMgZG9uZSB3aXRoIHRoZSBjb21tYW5kIA0Kc2NhdHRlci5zbW9vdGgocGFwZXIsc2FsZXMpDQpgYGANCmBgYHtyfQ0KIyBQbG90IFNhbGVzIHZzLiBQb3MNCiMgUmFkaW8gd2lsbCBiZSBvbiB0aGUgeC1heGlzDQojIFNhbGVzIHdpbGwgYmUgb24gdGhlIHktYXhpcw0KDQpzYWxlcyA9IG15ZGF0YSRzYWxlcw0KcG9zID0gbXlkYXRhJHBvcw0KcGxvdChwb3Msc2FsZXMpDQoNCiMgSXQgaXMgZWFzaWVyIHRvIHNlZSB0aGUgdHJlbmQgYW5kIHBvc3NpYmxlIHJlbGF0aW9uc2hpcCBieSBpbmNsdWRpbmcgYSBsaW5lIHRoYXQgZml0IHRocm91Z2ggdGhlIHBvaW50cy4NCiMgVGhpcyBpcyBkb25lIHdpdGggdGhlIGNvbW1hbmQgDQpzY2F0dGVyLnNtb290aChwb3Msc2FsZXMpDQpgYGANCg0KDQo8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj4NCiMjIyMjIDJCKSBTaGFyZSB5b3VyIG9ic2VydmF0aW9ucyBvbiB0cmVuZHMgYW5kIHJlbGF0aW9uc2hpcHMuIEhvdyBkbyB5b3VyIG9ic2VydmF0aW9ucyByZWNvbmNpbGUgd2l0aCB5b3VyIGZpbmRpbmdzIGZyb20gbGFiMDU/ICgxcHQpDQo8L3NwYW4+DQoNCkluIExhYjA1LCBJIHNhaWQ6IA0KUmFkaW8gVlMgc2FsZXMgZ3JhcGggaGFkIGEgcG9zaXRpdmUgYW5kIHZlcnkgbGluZWFyIHJlbGF0aW9uc2hpcC4gVGhpcyBtZWFucyB0aGF0IHRoZSBzYWxlcyByYW5rIHdpbGwgaW5jcmVhc2UgYXMgdGhlIGV4cGVuZGl0dXJlcyBvbiByYWRpbyBhZHMgZ29lcyB1cC4gIEJlY2F1c2UgaXQgaXMgbGluZWFyLCBlYWNoIHNhbGVzIHJhbmsgd2lsbCBpbmNyZWFzZSBwcm9wb3J0aW9uYWxseSB3aXRoIHRoZSBpbmNyZWFzZSBvZiByYWRpbyBleHBlbmRpdHVyZXMuDQoNClBhcGVyIFZTIHNhbGVzIGdyYXBoIHNob3dzIGEgbmVnYXRpdmUgY29ycmVsbGF0aW9uLiBUaGlzIG1lYW5zIHRoYXQgYXMgdGhlIHNhbGVzIHJhbmsgZGVjcmVhc2VzLCB0aGUgZXhwZW5kaXR1cmUgb24gbmV3cyBhZHMgaW5jcmVhc2VzLiBUaGlzIG1heSBtZWFuIHRoYXQgbmV3cyBhZHMgYXJlIG5vdCBhcyBlZmZlY3RpdmUsIGJ1dCB3ZSBjYW5ub3QgcHJvdmUgdGhpcy4gIFRoZXJlIGlzIG9ubHkgYSBuZWdhdGl2ZSBjb3JyZWxhdGlvbi4NCg0KVFYgVlMgU2FsZXMgZ3JhcGggaGFzIGEgcG9zaXRpdmUgcmVsYXRpb25zaGlwLi4gVGhpcyBtZWFucyBhcyBUViBhZHZlcnRpc2VtZW50IGNvc3RzIGluY3JlYXNlLCB0aGUgc2FsZXMgcmFuayB3aWxsIGFsc28gaW5jcmVhc2UuICBUaGlzIG1heSBtZWFuIHRoYXQgdGhlIG1vbmV5IHNwZW50IG9uIFRWIGFkcyBoZWxwcyB0byBpbXByb3ZlIHRoZSBzYWxlcyBhbW91bnQsIGJ1dCB0aGlzIGlzIG5vdCBwcm92ZW4uDQoNCkluIHRoZSByZWxhdGlvbnNoaXAgbW9kZWwsIGl0IGlzIG9idmlvdXMgc2FsZXMgYW5kIHJhZGlvLCBhbmQgc2FsZXMgYW5kIFRWIGhhdmUgYSBzdHJvbmcgcG9zaXRpdmUgcmVsYXRpb25zaGlwLiBTYWxlcyBhbmQgcmFkaW8gaXMgdmVyeSBsaW5lYXIuIFNhbGVzIGFuZCBwYXBlciBoYXZlIGEgbmVnYXRpdmUgcmVsYXRpb25zaGlwLCBidXQgaXQgaXMgbm90IHBlcmZlY3RseSBsaW5lYXIuIE92ZXJhbCwgU2FsZXMgYW5kIFJhZGlvIGhhZCBhIHZlcnkgc3Ryb25nIGFsbW9zdCBsaW5lYXIgcG9zaXRpdmUgY29ycmVsYXRpb24sIHNhbGVzIGFuZCBUViBoYWQgYSBzdG9uZyBwb3NpdGl2ZSBjb3JyZWxhdGlvbiwgYW5kIHBhcGVyIGFuZCBzYWxlcyBoYWQgbmVnYXRpdmUgcmVsYXRpb25zaGlwLiBXaGlsZSBsYWIgMDUgdXNlZCBzY2F0dGVycGxvdHMsIHdlIGNvdWxkIG5vdCBjbGVhcmx5IGlkZW50aWZ5IHRoZSByZWxhdGlvbnNoaXAuIE5vdyB3ZSBoYXZlIG1vcmUgZGF0YSB0byB1c2UgaW4gb3VyIGFuYWx5c2lzLg0KDQoNCkFzIHBhcnQgb2YgYW55IGRhdGEgYW5seXRpY3MgaXQgaXMgaW1wb3J0YW50IHRvIGNvbnNpZGVyIGJvdGggcXVhbGl0YXRpdmUgYW5kIHF1YW50aXRhdGl2ZSBhbmFseXNpcy4gIFNjYXR0ZXIgcGxvdHMgcHJvdmlkZSB1cyB3aXRoIHF1YWxpdGF0aXZlIGluc2lnaHRzIG9uIHBvc3NpYmxlIHRyZW5kcyBhbmQgcmVsYXRpb25zaGlwcy4gIFRvIHF1YW50aWZ5IHRoZSBzdHJlbmd0aCBvZiBhbnkgcmVsYXRpb25zaGlwcyBpbiB0aGUgZGF0YSwgd2UgbmVlZCB0byBsb29rIGF0IHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIHR3byB2YXJpYWJsZXMuDQoNClRvIGNvbXB1dGUgdGhlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IG9yIHN0cmVuZ3RoIGJldHdlZW4gdmFyaWFibGVzIGZvbGxvdyB0aGUgYmVsb3cgZXhhbXBsZS4NCg0KYGBge3J9DQpjb3Ioc2FsZXMscmFkaW8pDQpgYGANCg0KDQoNCjxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPg0KIyMjIyMgMkMpIFJlcGVhdCB0aGUgY29ycmVsYXRpb24gY2FsY3VsYXRpb24gZm9yIHRoZSBmb2xsb3dpbmcgcGFpciBvZiB2YXJpYWJsZXMgIChzYWxlcyx0diksIChzYWxlcyxwYXBlciksIGFuZCAoc2FsZXMscG9zKSAoMXB0KQ0KPC9zcGFuPg0KYGBge3J9DQojY29ycmVsYXRpb24gYmV0d2VlbiBzYWxlcyBhbmQgVFYNCg0KY29yKHNhbGVzLHR2KQ0KDQojY29ycmVsYXRpb24gYmV0d2VlbiBzYWxlcyBhbmQgcGFwZXINCmNvcihzYWxlcyxwYXBlcikNCg0KI2NvcmVsYXRpb24gYmV0d2VlbiBzYWxlcyBhbmQgcG9zDQpwb3M9bXlkYXRhJHBvcw0KY29yKHNhbGVzLHBvcykNCmBgYA0KDQo8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj4NCiMjIyMjIDJEKSBXaGljaCBwYWlyIGhhcyB0aGUgaGlnaGVzdCBjb3JyZWxhdGlvbj8gIEhvdyBkbyB0aGVzZSByZXN1bHRzIHJlY29uY2lsZSB3aXRoIHlvdXIgc2NhdHRlciBwbG90cyBvYnNlcnZhdGlvbnM/ICgxcHQpDQo8L3NwYW4+DQoNClRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIHNhbGVzIGFuZCByYWRpbyBpcyB0aGUgc3Ryb25nZXN0LiBBIHBlcmZlY3QgY29ycmVsYXRpb24gd291bGQgYmUgd2hlbiBpdCBlcXVhbHMgMSBvciAtMS4gVGhpcyBjb3JyZWxhdGlvbiB3b3VsZCBiZSBwZXJmZWN0bHkgbGluZWFyLiBUaGlzIG1lYW5zIHRoYXQgVGhpcyBtZWFucyB0aGF0IHRoZSBzdHJvbmdlc3QgY29ycmVsYXRpb24gd291bGQgYmUgYmV0d2VlbiBzYWxlcyBhbmQgcmFkaW8gYXQgMC45NzcxMzgxLiBUaGUgc2NhdHRlcnBsb3RzIGFsc28gcmVmbGVjdCB0aGlzLiAgdGhlIHNhbGVzIGFuZCByYWRpbyBvbmUgc2hvd3MgYSB2ZXJ5IGxpbmVhciByZWxhdGlvbnNoaXAuIFRoaXMgc2NhdHRlciBwbG90IHNob3dzIHRoZSBiZXN0IGxpbmVhciByZWxhdGlvbnNoaXAsIHZpc3VhbGx5LiBJdCByZWNvbmNpbGVzIHRoZSByZWxhdGlvbnNoaXAgZm91bmQuDQoNCkEgbW9yZSBlbmNvbXBhc3NpbmcgY29ycmVsYXRpb24gY2FsY3VsYXRpb24gY29uc2lkZXJzIGFsbCB2YXJpYWJsZXMgaW4gYSBkYXRhIGZpbGUgdG8gY29tcHV0ZSB0aGUgZXF1aXZhbGVudCBvZiBhIGNvcnJlbGF0aW9uIG1hdHJpeC4gT25lIHdheSB0byB2aXN1YWxpemUgYSBjb3JyZWxhdGlvbiBtYXRyaXggaXMgYnkgdXNpbmcgY29ycmVsb2dyYW1zLiBBIGNvcnJncmFtIGlzIGFuIGV4cGxvcmF0b3J5IHdheSB0byBkaXNwbGF5IGEgY29ycmVsYXRpb24gbWF0cml4LiAgSW4gUiB0aGlzIGlzIGRvbmUgYnkgaW5zdGFsbGluZyBhIG5ldyBwYWNrYWdlIGFzIGRlbW9uc3RyYXRlZCBpbiB0aGUgYmVsb3cgY29kZSBleGFtcGxlLg0KDQoNCmBgYHtyIGV2YWw9RkFMU0V9DQojIENvZGUgdG8gaW5zdGFsbCBhIHBhY2thZ2UNCmluc3RhbGwucGFja2FnZXMoImNvcnJncmFtIikNCmxpYnJhcnkoImNvcnJncmFtIikNCmBgYA0KDQpgYGB7cn0NCiMgQ29ycmdyYW0gY29tbWFuZCBzaG93aW5nIHRoZSBtaW5tYXggYW5kIHZhcmlhYmxlIG5hbWUgYWxvb25nIGRpYWdvbmFsLiBEZXB0aCBvZiBzaGFkaW5nIGluZGljYXRlcw0KY29ycmdyYW0obXlkYXRhLCBtYWluPSJNYXJrZXRpbmcgRGF0YSBDb3JyZWxhdGlvbiBNYXRyaXgiLCBsb3dlci5wYW5lbD1wYW5lbC5zaGFkZSwgZGlhZy5wYW5lbD1wYW5lbC5taW5tYXgsIHRleHQucGFuZWw9cGFuZWwudHh0KQ0KYGBgDQoNClRoZXJlIGFyZSBtYW55IG90aGVyIHdheXMgdG8gZG8gYSBjb3JyZ3JhbSBpbiBSLiBBIHF1aWNrIEdvb2dsZSBzZWFyY2ggb24gdGhlIHRvcGljLCBjYW4gcmV2ZWFsIHNvbWUgaW50ZXJlc3Rpbmcgb3B0aW9ucy4gIFlvdSBjYW4gY2hlY2sgZm9yIGV4YW1wbGUgdGhlIFF1aWNrLVIgc2l0ZSBhdCBodHRwczovL3d3dy5zdGF0bWV0aG9kcy5uZXQvYWR2Z3JhcGhzL2NvcnJlbG9ncmFtcy5odG1sDQoNCjxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPg0KIyMjIyMgMkUpIFNlbGVjdCBhIGNvcnJncmFtIG9mIHlvdXIgY2hvaWNlIGFuZCBkaWZmZXJlbnQgZnJvbSB0aGUgb25lIGV4aGliaXRlZCBpbiB0aGlzIHdvcmtzaGVldC4gIEV4ZWN1dGUgdGhlIGNvZGUgdG8gZGlzcGxheSB0aGUgb3V0cHV0LiAgTm90ZSB0aGF0IHlvdSBkb24ndCBuZWVkIHRvIGluc3RhbGwgdGhlIHBhY2thZ2UgYWdhaW4gYXMgbG9uZyBhcyBpdCBpcyBleGVjdXRlZCBvbmNlIGVhcmxpZXIgKDFwdCkNCjwvc3Bhbj4NCmBgYHtyfQ0KDQpjb3JyZ3JhbShteWRhdGEsIG9yZGVyPVRSVUUsIG1haW49Ik1hcmtldGluZyBEYXRhIENvcnJlbGF0aW9uIE1hdHJpeCIsIHBhbmVsPXBhbmVsLnNoYWRlLCB0ZXh0LnBhbmVsPXBhbmVsLnR4dCkNCg0KDQoNCmBgYA0KDQoNCg0KLS0tLS0tLS0tLQ0KDQojIyMgVGFzayAzIC0gQmFzaWMgVmlzdWFsIEFuYWx5dGljcyBpbiBUYWJsZWF1DQoNCkZvbGxvdyB0aGUgZGlyZWN0aW9ucyBvbiB0aGUgd29ya3NoZWV0LCBkb3dubG9hZCB0YWJsZWF1IGFjYWRlbWljIG9uIHlvdXIgcGVyc29uYWwgY29tcHV0ZXIgb3IgdXNlIG9uZSBvZiB0aGUgbGFicyBjb21wdXRlcnMuIE1ha2Ugc3VyZSB0byBkb3dubG9hZCB0aGUgYWNhZGVtaWMgdmVyc2lvbiBhbmQgbm90IHRoZSBmcmVlIGxpbWl0ZWQgdHJpYWwgdmVyc2lvbi4NCg0KLS0gRG93bmxvYWQgVGFibGVhdSBhY2FkZW1pYyBoZXJlOiBodHRwczovL3d3dy50YWJsZWF1LmNvbS9hY2FkZW1pYy9zdHVkZW50cw0KDQotLSBSZWZlciB0byBmaWxlICdjcmVkaXRyaXNrLmNzdicgaW4gdGhlIGRhdGEgZm9sZGVyDQoNCi0tIFN0YXJ0IFRhYmxlYXUgYW5kIGVudGVyIHlvdXIgTFVDIGVtYWlsIGlmIHByb21wdGVkLg0KDQotLSBJbXBvcnQgdGhlIGZpbGUgaW50byBUYWJsZWF1LiBDaG9vc2UgdGhlIFRleHQgRmlsZSBvcHRpb24gd2hlbiBpbXBvcnRpbmcNCg0KIVtdKHRhYmxlYXVfaW1wb3J0ZmlsZS5wbmcpDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KLS0gVW5kZXIgdGhlIGRpbWVuc2lvbnMgdGFiIGxvY2F0ZWQgb24gdGhlIGxlZnQgc2lkZSBvZiB0aGUgc2NyZWVuIERPVUJMRSBjbGljayBvbiB0aGUgJ0xvYW4gUHVycG9zZScsIHRoZW4gRE9VQkxFIGNsaWNrIG9uICdOdW1iZXIgb2YgUmVjb3JkcycgdmFyaWFibGUgbG9jYXRlZCB1bmRlciBNZWFzdXJlcyBvbiB0aGUgYm90dG9tIGxlZnQgb2YgdGhlIHNjcmVlbi4gDQoNCiFbXSh0YWJsZWF1X3ZhcmlhYmxlcy5wbmcpDQoNCg0KDQotLSBGcm9tIHRoZSB1cHBlciByaWdodCBjb3JuZXIgb2YgdGhlIHNjcmVlbiBzZWxlY3QgdGhlIGhvcml6b250YWwgYmFycyB2aWV3IGFuZCBub3RlIHRoZSBuZXcgY2hhcnQuICBGYW1pbGlhcml6ZSB5b3Vyc2VsZiB3aXRoIHRoZSB0b29sIGJ5IHRyeWluZyBvdGhlciB2aWV3cy4gT25seSB2YWxpZCB2aWV3cyB3aWxsIGJlIGhpZ2hsaWdodGVkIGluIHRoZSBtZW51LiAgDQoNCiFbXSh0YWJsZWF1X3Nob3dtZS5wbmcpDQoNCg0KLS0gQ3JlYXRlIGEgbmV3IHNoZWV0IGJ5IGNsaWNraW5nIG9uIHRoZSBpY29uIGluIHRoZSBib3R0b20gbmV4dCB0byB5b3VyIGN1cnJlbnQgc2hlZXQuDQoNCg0KIVtdKHRhYmxlYXVfbmV3c2hlZXQucG5nKQ0KDQo8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj4NCiMjIyMjIDNBKSBEb3VibGUtY2xpY2sgb24gdGhlICdBZ2UnIHZhcmlhYmxlIGluIE1lYXN1cmVzIGFuZCBzZWxlY3QgdGhlICdIaXN0b2dyYW0nIHZpZXcuICBDYXB0dXJlIGEgc2NyZWVuIHNob3QgYW5kIGluY2x1ZGUgaGVyZS4gIFdoaWNoIGFnZSBiaW4gaGFzIHRoZSBoaWdoZXN0IGFnZSBjb3VudCBhbmQgd2hhdCBpcyB0aGUgY291bnQ/ICgycHRzKQ0KDQphZ2UgYmluIHdpdGggaGlnaGVzdCBhZ2UgY291bnQ6IDIyDQpjb3VudDogOTcNCg0KIVtdKGFnZS5QTkcpDQoNCg0KPC9zcGFuPg0KDQo8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj4NCg0KDQojIyMjIyAzQikgRHJhZy1kcm9wIHRoZSB2YXJpYWJsZSAnTWFyaXRhbCBTdGF0dXMnZm91bmQgdW5kZXIgRGltZW5zaW9ucyBpbnRvIHRoZSBNYXJrcyBDb2xvciBib3guICBDYXB0dXJlIGEgc2NyZWVuIHNob3QgYW5kIGluY2x1ZGUgaGVyZS4gIFdoaWNoIGFnZSBiaW4gaGFzIHRoZSBoaWdoZXN0IGRpdm9yY2UgY291bnQgYW5kIHdoYXQgaXMgdGhlIGNvdW50PyAgKDJwdHMpDQphZ2UgYmluIHdpdGggaGlnaGVzdCBkaXZvcmNlIGNvdW50OjIyDQpjb3VudDogNDYNCiFbXShkaXZvcmNlLlBORykNCg0KPC9zcGFuPg0KDQohW10odGFibGVhdV9tYXJrcy5wbmcpDQoNCg0KPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+DQojIyMjIyAzQykgQ3JlYXRlIGFub3RoZXIgbmV3IHNoZWV0LiBEb3VibGUtY2xpY2sgJ01vbnRocyBFbXBsb3llZCcgYW5kIHRoZW4gZG91YmxlLWNsaWNrICdBZ2UnLiBNYWtlIHN1cmUgQWdlIGFwcGVhcnMgaW4gdGhlIGNvbHVtbnMgZmllbGQgYXMgc2hvd24gaW4gdGhlIGltYWdlIGJlbG93LiBGcm9tIHRoZSBTdW0oQWdlKSBkcm9wIGRvd24gbWVudSBzZWxlY3QgRGltZW5zaW9uLiBSZXBlYXQgZm9yIFN1bShNb250aHMgRW1wbG95ZWQpLiBBZGQgYW5vdGhlciB2YXJpYWJsZSB0byB0aGUgc2NhdHRlciBwbG90IGJ5IGRyYWctZHJvcCB0aGUgZGltZW5zaW9uIHZhcmlhYmxlICdHZW5kZXInIGludG8gdGhlIE1hcmtzIENvbG9yIGJveC4gQ2FwdHVyZSBhIHNjcmVlbiBzaG90IGFuZCBpbmNsdWRlIGhlcmUuIFNoYXJlIGluc2lnaHRzIG9uIHdoYXQgdGhlIGRhdGEgaXMgdGVsbGluZyB1cyAoM3B0cykNCjwvc3Bhbj4NCg0KVGhpcyBkYXRhIHNob3dzIGFnZSBvbiB0aGUgeCBheGlzLCBtb250aHMgb2YgZW1wbG95bWVudCBvbiB0aGUgeSBheGlzLCBhbmQgdGhlIGdlbmRlciBiYXNlZCBvbiB0aGUgY29sb3Igb2YgdGhlIGRhdGEgcG9pbnQuIFRoZSBvcmFuZ2UgZG90cyBhcmUgbWFsZSwgYW5kIHRoZSBibHVlIGRvdHMgYXJlIGZlbWFsZS4gIFRoaXMgdmlzdWFsIHNob3dzIHRoZSBkaXN0cmlidXRpb24gb2YgbW9udGhzIGVtcGxveWVkLCBhZ2UsIGFuZCBnZW5kZXIuIFRoZXJlIGlzIGEgbG90IG9mIGRhdGEgY2xvc2UgdG8gdGhlIHggYXhpcywgbWVhbmluZyB0aGUgbW9udGhzIG9mIGVtcGxveW1lbnQgaXMgY2xvc2UgdG8gMCwgb3IgYSBzaG9ydGVyIHBlcmlvZCBvZiB0aW1lLiBUaGVyZSBhbHNvIGFwcGVhcnMgdG8gYmUgbW9yZSBkYXRhIHBvaW50cyB0b3dhcmRzIHRoZSBvcmlnaW4gb2YgdGhlIGdyYXBoLiBUaGlzIG1lYW5zIHRoYXQgdGhlIGFnZSBza2V3cyB0b3dhcmRzIHlvdW5nZXIgcGVvcGxlIGFuZCB0aGF0IHRoZSBlbXBsb3ltZW50IGxlbmd0aCBza2V3cyB0b3dhcmRzIHBlb3BsZSB3aG8gaGF2ZSBub3QgaGVsZCB0aGUgam9iIGFzIGxvbmcuICBBbHNvLCB0aGVyZSBhcHBlYXJzIHRvIGJlIG1vcmUgb3JhbmQgZG90cywgYW5kIHRoaXMgbWVhbnMgdGhhdCB0aGVyZSBtYXkgYmUgbW9yZSBtZW4gaW4gdGhpcyBkYXRhIHNldC4gVGhpcyBtZWFucyB0aGVyZSBtYXkgYmUgbW9yZSBtZW4gYXBwbHlpbmcgZm9yIGxvYW5zLg0KIVtdKGxhc3QuUE5HKQ0KIVtdKHRhYmxlYXVfZGltZW5zaW9uLnBuZykNCg0KDQoNCg0KPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+DQojIyMjIyAzRCkgSW4gYSBuZXcgc2hlZXQgZ2VuZXJhdGUgYSB2aWV3IG9mIEdlbmRlciwgTnVtYmVyIG9mIFJlY29yZHMsIGFuZCBNYXJpdGFsIFN0YXR1cy4gQ2hvb3NlIHRoZSBiZXN0IGZpdHRpbmcgdmlldyBvZiB5b3VyIGNob2ljZSBmb3IgdGhlIGludGVuZGVkIHNjb3BlLiAgIENhcHR1cmUgYSBzY3JlZW4gc2hvdCBhbmQgaW5jbHVkZSBoZXJlLiBTaGFyZSBpbnNpZ2h0cyBvbiB3aGF0IHRoZSBkYXRhIGlzIHRlbGxpbmcgdXMgKDNwdHMpDQo8L3NwYW4+DQoNClRoZSBkYXRhIGlzIHRvIGFuYWx5emUgbnVtYmVyIG9mIHJlY29yZHMgd2l0aCBtYXJpdGFsIHN0YXR1cy4gTWFyaXRhbCBzdGF0dXMgaXMgY2F0ZWdvcmljYWwgZGF0YSh4LWF4aXMpLCBhbmQgbnVtYmVyIG9mIHJlY29yZHMgaXMgcXVhbnRpZmFibGUgKHktYXhpcykuIEdlbmRlciBpcyBiZWluZyBpZGVudGZpZWQgYnkgYSBjb2xvciAob3JhbmdlIGlzIG1hbGUsIGJsdWUgaXMgZmVtYWxlKWluIHRoZSBkYXRhIHNldC4gSSB1c2VkIGEgZ3JhcGggdGhhdCBzaG93ZWQgdGhlIG51bWJlciBvZiByZWNvcmRzLCBub3QgdGhlIHJlbGF0aXZlIHNpemUuDQpUaGlzIGRhdGEgc2hvd3MgdGhhdCB0aGUgbnVtYmVyIG9mIHJlY29yZHMgaXMgaGlnaGVzdCBpbiBzaW5nbGVzLiBNZW4gYXJlIHRoZSBvbmx5IHBlb3BsZSB0aGF0IGhhdmUgYXBwbGllZCBmb3IgbG9hbnMgdW5kZXIgdGhlIHN0YXR1cyBvZiBzaW5nbGUuIEZlbWFsZXMgaGF2ZSBvbmx5IGFwcGxpZWQgZm9yIGxvYW5zIHdoZW4gZGl2b3JjZWQuIE91dCBvZiBlYWNoIG9mIHRoZSBtYXJpdGFsIHN0YXR1c2VzLCBtYXJyaWVkIGluZGl2aWR1YWxzIGhhdmUgYXBwbGllZCBmb3IgbG9hbnMgdGhlIGxlYXN0LCBhbmQgc2luZ2xlcyBoYXZlIGFwcGxpZWQgZm9yIGxvYW5zIHRoZSBtb3N0LiBEaXZvcmNlZXMgYXJlIGluIGJldHdlZW4gc2luZ2xlcyBhbmQgbWFycmllZCBwZW9wbGUgaW4gdGhlIG51bWJlciBvZiByZWNvcmRzLiBIb3dldmVyLCB0aGUgbWFqb3JpdHkgb2YgZGl2b3JjZWVzIGFyZSB3b21lbi4NCiFbXShyZWNvcmQuUE5HKQ0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCg0K