This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Execute a code chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.

Add a new chunk by clicking the Insert Chunk button on the tool-bar 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).

Useful References for R

A list of colours available in R can be found at

Section 1 - Histograms

However we do have some guidelines to help us:

Guidelines for Histograms

  1. The number of bars should be between 5 and 20.

  2. If the lowest and highest data points are not convenient numbers then we can do the following:

    • Round down the smallest data point to the next lowest convenient number.

    • Round up the largest data point toe the next highest convenient number.

  3. Find the length (or range) of this new interval by subtracting the lowest from the highest data values.

  4. If possible, choose the number of bars such that this number divides evenly into the range, to give us our interval.

  5. Starting with the smallest value, start marking off the horizontal axis in units of the interval, until the highest data point is reached.

  6. Categorise the data into theses intervals and construct a frequency (or relative frequency) table for this categorization

  • NOTE: If a data value falls within two consecutive intervals, place it in the upper interval.
  1. The height of each bar on the histogram corresponds to the frequency or relative frequency of the interval.

Example 1

The trees in an orchard were measured and found to have the following heights

  • 3.4m, 3.5m, 3.7m, 4.2m, 4.4m, 4.7m, 4.9m, 5.1m, 5.2m, 5.3m, 5.9m, 6.0m, 6.4m, 7.3m, 7.9m, 8.1m, 8.7m.

Construct a histogram to graph this data set.

Solution

  1. We may round off the highest and lowest values to more convenient numbers such as
  • 3.4 \(\to\) 3.
  • 8.7 \(\to\) 9.
  1. The new data range is given by range=9-3=6
  2. We choose a number between 5 and 20 which divides evenly into this range, and so an obvious choice is 6 bars for this histogram.
  3. We create a vector valued object to store the measured heights:
Heights <- c(3.4, 3.5, 3.7, 4.2, 4.4, 4.7, 4.9, 5.1, 5.2, 5.3, 5.9, 6.0, 6.4, 7.3, 7.9, 8.1, 8.7)
  1. We use the hist() function to plot a histogram of the vector Heights
hist(Heights, breaks=6, axes=T,col="skyblue4", main="Histogram of Tree Heights in an Orchard", ylab="Frequency", xlab="Tree heights (m)", freq=T)

  1. To print a PDF of this graph we use the pdf() and dev.off() commands
pdf("Histogram1.pdf")
hist(Heights,breaks=6, axes=T,col="skyblue4", main="Histogram of Tree Heights in an Orchard", ylab="Frequency", xlab="Tree heights (m)", freq=T)
dev.off()
null device 
          1 
  1. Unlike the barplot() command, the histogram plot automates a large amount of the work for us. Nevertheless, it is still possible to override most of these automatic choices by selecting various arguments for the hist() function.
  • Most of these arguments are explained in the R documentation available in the Help panel of the R Studio environment. Just type hist into the the search bar and press enter.

Skewed Data and Central Data

A collection of data is skewed left if its histogram displays a tail to the left. This means the at possess outliers at the lower end of the data set.

Example: Skewed-left data

Left<-c(1,8,8,8,9,9,9,10,10,11,11,11)
hist(Left,col="cornflowerblue",main="Left-Skewed Data", xlab="Left Data Values")

  • Notice, most of the data is concentrated to the right between 6 and 12. However, a small portion of the data forms a left-tail between 0 and 2. This tail is what skews the data to the left.

Conversely, the data is skewed right if the histogram displays a tail to the right, and likewise this indicates the presence of outlines at the upper end of the data set.

Example: Right-skewed data

Right<-c(1,1,2,3,3,3,4,4,5,5,5,12)
hist(Right,breaks=5, col="cornflowerblue",main="Right-Skewed Data", xlab="Right Data Values")

  • Most of the data is concentrated to the left between 0 and 6. However, a small portion of the data forms a right-tail between 10 and 12. This tail is what skews the data to the right.

Test for skewness

  • If the data is skewed right then \[ mean > median \]

  • If the data is skewed left then \[ mean < median \]

  • If the data is central then \[ mean = median \] and the histogram is symmetric.

Example: Test for skewness

We will test the data sets Left and Right for skewness.

Left Data:

mean(Left)
[1] 8.75
median(Left)
[1] 9
  • We see that the mean of the Left data is less than the median of the Left data, confirming it is skewed-left.

Right Data:

mean(Right)
[1] 4
median(Right)
[1] 3.5
  • We see that the mean of the Right data is greater than the median of the Right data, confirming it is skewed-right.

Skewness of Heights:

The histogram in Example 1 appears to display a tail to the right and so we expect the data to be skewed right.

To test this we can use the mean() and the median() functions and compare.

mean(Heights)
[1] 5.570588
median(Heights)
[1] 5.2

Since the mean is bigger than the median, this means the data is skewed right as we expect from the histogram above.

Example 2

The marks scored by a class in a test are as follows (not in order):

  • 50, 63, 29, 54, 56, 0, 53, 34, 45, 85, 65, 62, 60, 3, 71, 66, 63, 68, 69, 67, 79, 75, 72, 81, 87, 91, 52

Using this data, answer the following:

A. Use the sort() function to sort this data and the length() function to count the data points

B. Draw a histogram to represent this sorted data

C. From the histogram decide if the data is skewed left, skewed right or symmetric

D. Find the mean of this data

E. Find the median of this data set

F. Comparing the mean and the median, decide if the data is skewed left, skewed right or symmetric. Does this agree with the histogram?

Solution

Scores <- c(50, 63, 29, 54, 56, 0, 53, 34, 45, 85, 65, 62, 60, 3, 71, 66, 63, 68, 69, 67, 79, 75, 72, 81, 87, 91, 52)
sort(Scores)
 [1]  0  3 29 34 45 50 52 53 54 56 60 62 63 63 65 66 67 68 69 71 72 75 79 81 85 87 91
length(Scores)
[1] 27
hist(Scores, breaks=8, xlim=c(0,100),ylim=c(0,0.02),freq=F, xlab="Exam Scores", ylab="Relative Frequency", col="darkslategray4", main="Histogram of Exam Scores")

  1. From the histogram, the data appears to be skewed-left.

mean(Scores)
[1] 59.25926
median(Scores)
[1] 63

Since the mean is less than the median the data is skewed left. This agrees with the shape of the histogram for the data set.

Exercise 1

The journey times (in hours) for a train service between two cities were resumed on a given day, with the following data gathered

1.2, 1.22, 1.23, 1.25, 1.3, 1.34, 1.36, 1.39, 1.40, 1.42, 1.45, 1.48, 1.51, 1.56

Given this data, answer the following:

  1. Use the median() function to find the median of this data set

  2. Use the mean() function

  3. Comparing the mean and the median of the data set, is the data skewed-left, skewed-right or central

  4. Construct a histogram of this data set

  5. Using this histogram, decide if the data is skewed-left, skewed-right or central

  6. Does this agree with your answer from part 3?

Exercise 2

An electrical components manufacturer measures the resistance of a sample of 50 resistors produced during one production run. The resistances were measured as follows

51.20, 50.30, 52.40, 50.24, 51.25, 49.89, 51.63, 52.84, 53.01, 49.99

50.34, 50.61, 51.93, 52.25, 49.87, 50.13, 51.32, 50.43, 51.34, 52.13

52.11, 56.84, 57.81, 51.33, 52.36, 50.67, 51.89, 52.13, 52.18, 50.31

50.84, 51,12, 50.95, 49.98, 51.03, 52.01, 50.96, 51.02, 52.44, 51.95

Given this data, answer the following:

  1. Sort the data according to increasing measurements of resistance

  2. Use the median() function to find the median of this data set

  3. Use the mean() function

  4. Comparing the mean and the median of the data set, is the data skewed-left, skewed-right or central

  5. Construct a histogram of this data set

  6. Using this histogram, decide if the data is skewed-left, skewed-right or central

  7. Does this agree with your answer from part 4?

Exercise 3

The water quality at a water treatment facility is measured hourly by measuring the impurities present in the water in (measured in parterre-million). The following data was collected during in one 36 hour period:

18, 8, 25, 13, 7, 19

14, 5, 21, 23, 18, 5

13, 6, 15, 21, 17, 6

15, 7, 13, 5, 18, 11

12, 14, 15, 16, 12, 13

9, 17, 16, 19, 8, 10

Given this data, answer the following:

  1. Sort the data in order of increasing values of impurities measured

  2. Use the median() function to find the median of this data set

  3. Use the mean() function

  4. Comparing the mean and the median of the data set, is the data skewed-left, skewed-right or central

  5. Construct a histogram of this data set

  6. Using this histogram, decide if the data is skewed-left, skewed-right or central

  7. Does this agree with your answer from part 4?

Pareto Charts

A Pareto chart is a combination of a bar chart and a cumulative frequency chart

They are a useful diagnostic tool when one wishes to limit various defects, errors, delays, breakdowns in different circumstances.

Remark: To generate Pareto charts we need to import the qcc library as follows

  1. In the Tools tab above, select the option Install Packages…
  2. In the Install from option, select Repository(CRAN, CRANextra)
  3. In the Packages input line type qcc
  4. IN the Install to Library option select your own home directory (this should be the daffodils anyhow)
  5. Make sure Install all dependencies is checked

Once installed we call the library qcc as follows

library(qcc)
  __ _  ___ ___ 
 / _  |/ __/ __|  Quality Control Charts and 
| (_| | (_| (__   Statistical Process Control
 \__  |\___\___|
    |_|           version 2.7
Type 'citation("qcc")' for citing this R package in publications.

Example 1

The employees of a company were asked the reasons for late arrivals at work. The data collected were as follows:

  • Child Care 22

  • Emergency 8

  • Overslept 12

  • Public transport 15

  • Traffic 36

  • Weather 27

Using this data answer the following:

  1. Create an appropriate vector to represent this data.

  2. Use the function pareto.chart() to generate a Pareto chart for this data.

  3. From the Pareto chart, determine which causes could reasonable be addressed to reduce late arrivals by at least 35%.

  4. We first create an appropriate vector of numbers to represent the data, in the usual way:

Employees <- c(22,8,12,15,36,27)
Employees
[1] 22  8 12 15 36 27

Now we create an appropriate vector of names, corresponding the these numbers as follows:

Reasons <- c("Child Care", "Emergency", "Overslept", "Public Transport", "Traffic", "Weather")
Reasons
[1] "Child Care"       "Emergency"        "Overslept"        "Public Transport" "Traffic"         
[6] "Weather"         
  • Now we re-create the Employees vector by assigning it the names in the vector Reasons as follows:
names(Employees)<-Reasons

i.e. each entry has now been given a corresponding name.

  • The new Employees vector is
Employees
      Child Care        Emergency        Overslept Public Transport          Traffic          Weather 
              22                8               12               15               36               27 

and so we see each number has been assigned a corresponding reason.

  1. The Pareto Chart for this data is given by
pareto.chart(Employees,col="skyblue2", cumperc=seq(0,100,by=10), main="Pareto chart giving reasons for late arrivals at work")
                  
Pareto chart analysis for Employees
                    Frequency  Cum.Freq. Percentage Cum.Percent.
  Traffic           36.000000  36.000000  30.000000    30.000000
  Weather           27.000000  63.000000  22.500000    52.500000
  Child Care        22.000000  85.000000  18.333333    70.833333
  Public Transport  15.000000 100.000000  12.500000    83.333333
  Overslept         12.000000 112.000000  10.000000    93.333333
  Emergency          8.000000 120.000000   6.666667   100.000000

  • We notice that the pareto.chart() function plots the frequency of each class, as opposed to the relative frequency of each class. This is easily modified by summing all frequencies in the Employees vector and dividing the the vector by this number to give the frequency density of each class.
Total=sum(Employees)
Total
[1] 120
Employees <- Employees/Total
Employees
      Child Care        Emergency        Overslept Public Transport          Traffic          Weather 
      0.18333333       0.06666667       0.10000000       0.12500000       0.30000000       0.22500000 
pareto.chart(Employees,col="skyblue2", cumperc=seq(0,100,by=10), ylab="Relative Frequency", main="Pareto chart giving reasons for late arrivals at work")
                  
Pareto chart analysis for Employees
                      Frequency    Cum.Freq.   Percentage Cum.Percent.
  Traffic            0.30000000   0.30000000  30.00000000  30.00000000
  Weather            0.22500000   0.52500000  22.50000000  52.50000000
  Child Care         0.18333333   0.70833333  18.33333333  70.83333333
  Public Transport   0.12500000   0.83333333  12.50000000  83.33333333
  Overslept          0.10000000   0.93333333  10.00000000  93.33333333
  Emergency          0.06666667   1.00000000   6.66666667 100.00000000

Exercise 4

A mobile phone repair shop categorized the type of repair work it carried out over a year and found the following data:

  • Cracked Screen 125
  • Scratched Screen 228
  • Forgotten Pass code 91
  • Water Damage 188
  • Battery Replacement 111
  • Software Virus 82
  • Phone Bricking 188
  • Damaged Connector 41

Given this data, answer the following:

  1. Find the total number of repairs in the year.

  2. Construct a vector to represent the relative frequencies of each of these classes.

  3. Use this vector of relative frequencies to construct a Pareto chart of this data.

  4. From the Pareto chart determine the causes of phone damage owners should address to reduce repairs by at lease 25%.

Exercise 5

A newly built apartment complex was inspected to prepare a snag list for each apartment. After inspection of apartment the complex, the following issues were found to occur with the frequency indicated:

List of Damages

  • Cooker Disconnected 4
  • Windows Not Closing 18
  • Bathroom Ventilator Broken 9
  • Damaged Plug Sockets 51
  • Broken Light 29
  • Damaged Paintwork 47
  • Doors Not Locking 14
  • Dampness 2
  • Scratched Flooring 21

Using this data answer the following:

  1. Identify the data type given.

  2. Construct a vector to represent the frequencies.

  3. Using this vector, evaluate the number of damages to be repaired in the apartment complex.

  4. Using the vector of frequency values, construct a Pareto chart for this data.

  5. From this data determine how which issues should be addressed to ensure at least 75% of damages are repaired.

LS0tCnRpdGxlOiAnIERhdGEgVmlzdWFsaXNhdGlvbiAyMDE5IC0gQXNzaWdubWVudCAxJwpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAogIHBkZl9kb2N1bWVudDogZGVmYXVsdAotLS0KClRoaXMgaXMgYW4gW1IgTWFya2Rvd25dKGh0dHA6Ly9ybWFya2Rvd24ucnN0dWRpby5jb20pIE5vdGVib29rLiBXaGVuIHlvdSBleGVjdXRlIGNvZGUgd2l0aGluIHRoZSBub3RlYm9vaywgdGhlIHJlc3VsdHMgYXBwZWFyIGJlbmVhdGggdGhlIGNvZGUuIAoKRXhlY3V0ZSBhIGNvZGUgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ3RybCtTaGlmdCtFbnRlciouIAoKQWRkIGEgbmV3IGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqSW5zZXJ0IENodW5rKiBidXR0b24gb24gdGhlIHRvb2wtYmFyIG9yIGJ5IHByZXNzaW5nICpDdHJsK0FsdCtJKi4KCldoZW4geW91IHNhdmUgdGhlIG5vdGVib29rLCBhbiBIVE1MIGZpbGUgY29udGFpbmluZyB0aGUgY29kZSBhbmQgb3V0cHV0IHdpbGwgYmUgc2F2ZWQgYWxvbmdzaWRlIGl0IChjbGljayB0aGUgKlByZXZpZXcqIGJ1dHRvbiBvciBwcmVzcyAqQ3RybCtTaGlmdCtLKiB0byBwcmV2aWV3IHRoZSBIVE1MIGZpbGUpLgoKIyMgVXNlZnVsIFJlZmVyZW5jZXMgZm9yIF9fUl9fCkEgbGlzdCBvZiBjb2xvdXJzIGF2YWlsYWJsZSBpbiAqKlIqKiBjYW4gYmUgZm91bmQgYXQKCiogaHR0cDovL3d3dy5zdGF0LmNvbHVtYmlhLmVkdS9+dHpoZW5nL2ZpbGVzL1Jjb2xvci5wZGYKCiMgU2VjdGlvbiAxIC0gSGlzdG9ncmFtcwoKICogQSBfX0hpc3RvZ3JhbV9fIGlzIGEgdHlwZSBvZiBiYXItY2hhcnQgd2hlcmUgdGhlIGNhdGVnb3JpZXMgYXJlIG51bWJlciBpbnRlcnZhbHMgYXMgb3Bwb3NlZCB0byBub21pbmFsIGNhdGVnb3JpZXMuCgoKICogSW4gdGhpcyBzZWN0aW9uIHdlIGFyZSBnb2luZyB0byB1c2UgX19SX18gdG8gcGxvdCBhIGhpc3RvZ3JhbSBmb3IgYSBnaXZlbiBkYXRhIHNldC4gCiAKICogRHVyaW5nIGxlY3R1cmVzIHdlIHdpbGwgZmluZCB0aGF0IHRoZXJlIGlzIGEgY2VydGFpbiBhbW91bnQgb2YgYW1iaWd1aXR5IGluIGhvdyB3ZSBncmFwaCBhIGhpc3RvZ3JhbSwgaW4gdGhhdCB0aGUgbnVtYmVyIG9mIGJhcnMgICAgYW5kIGNvbnNlcXVlbnRseSB0aGUgYmFyLXdpZHRocyBhcmUgbm90IGZpeGVkLCBidXQgY2FuIGJlIGNob3Nlbi4gCiAKSG93ZXZlciB3ZSBkbyBoYXZlIHNvbWUgZ3VpZGVsaW5lcyB0byBoZWxwIHVzOgoKIyMjIEd1aWRlbGluZXMgZm9yIEhpc3RvZ3JhbXMKCjEuIFRoZSBudW1iZXIgb2YgYmFycyBzaG91bGQgYmUgYmV0d2VlbiBfXzVfXyBhbmQgX18yMF9fLgoKMi4gSWYgdGhlIGxvd2VzdCBhbmQgaGlnaGVzdCBkYXRhIHBvaW50cyBhcmUgX19ub3QgY29udmVuaWVudCBudW1iZXJzX18gdGhlbiB3ZSBjYW4gZG8gdGhlIGZvbGxvd2luZzoKICAgIAogICAgKiBfX1JvdW5kIGRvd25fXyB0aGUgc21hbGxlc3QgZGF0YSBwb2ludCB0byB0aGUgbmV4dCBsb3dlc3QgY29udmVuaWVudCBudW1iZXIuCiAgICAKICAgICogX19Sb3VuZCB1cF9fIHRoZSBsYXJnZXN0IGRhdGEgcG9pbnQgdG9lIHRoZSBuZXh0IGhpZ2hlc3QgY29udmVuaWVudCBudW1iZXIuCiAgICAKMy4gRmluZCB0aGUgX19sZW5ndGhfXyAob3IgX19yYW5nZV9fKSBvZiB0aGlzIG5ldyBpbnRlcnZhbCBieSBzdWJ0cmFjdGluZyB0aGUgbG93ZXN0IGZyb20gdGhlIGhpZ2hlc3QgZGF0YSB2YWx1ZXMuCgo0LiBJZiBwb3NzaWJsZSwgY2hvb3NlIHRoZSBudW1iZXIgb2YgYmFycyBzdWNoIHRoYXQgdGhpcyBudW1iZXIgZGl2aWRlcyBldmVubHkgaW50byB0aGUgX19yYW5nZV9fLCB0byBnaXZlIHVzIG91ciBfX2ludGVydmFsX18uCgoKNS4gU3RhcnRpbmcgd2l0aCB0aGUgc21hbGxlc3QgdmFsdWUsIHN0YXJ0IG1hcmtpbmcgb2ZmIHRoZSBob3Jpem9udGFsIGF4aXMgaW4gdW5pdHMgb2YgdGhlIGludGVydmFsLCB1bnRpbCB0aGUgaGlnaGVzdCBkYXRhIHBvaW50IGlzIHJlYWNoZWQuCgo2LiBDYXRlZ29yaXNlIHRoZSBkYXRhIGludG8gdGhlc2VzIGludGVydmFscyBhbmQgY29uc3RydWN0IGEgIGZyZXF1ZW5jeSAob3IgcmVsYXRpdmUgZnJlcXVlbmN5KSB0YWJsZSBmb3IgdGhpcyBjYXRlZ29yaXphdGlvbgogIAogKiBfX05PVEU6X18gSWYgYSBkYXRhIHZhbHVlIGZhbGxzIHdpdGhpbiB0d28gY29uc2VjdXRpdmUgaW50ZXJ2YWxzLCBwbGFjZSBpdCBpbiB0aGUgX191cHBlciBpbnRlcnZhbF9fLiAgCiAgCjcuIFRoZSBoZWlnaHQgb2YgZWFjaCBiYXIgb24gdGhlIGhpc3RvZ3JhbSBjb3JyZXNwb25kcyB0byB0aGUgZnJlcXVlbmN5IG9yIHJlbGF0aXZlIGZyZXF1ZW5jeSBvZiB0aGUgaW50ZXJ2YWwuCgojIyMgRXhhbXBsZSAxCgpUaGUgdHJlZXMgaW4gYW4gb3JjaGFyZCB3ZXJlIG1lYXN1cmVkIGFuZCBmb3VuZCB0byBoYXZlIHRoZSBmb2xsb3dpbmcgaGVpZ2h0cwoKKiAzLjRtLCAzLjVtLCAzLjdtLCA0LjJtLCA0LjRtLCA0LjdtLCA0LjltLCA1LjFtLCA1LjJtLCA1LjNtLCA1LjltLCA2LjBtLCA2LjRtLCA3LjNtLCA3LjltLCA4LjFtLCA4LjdtLgoKQ29uc3RydWN0IGEgaGlzdG9ncmFtIHRvIGdyYXBoIHRoaXMgZGF0YSBzZXQuCgojIyMgU29sdXRpb24gCjEuIFdlIG1heSBfX3JvdW5kIG9mZl9fIHRoZSBoaWdoZXN0IGFuZCBsb3dlc3QgdmFsdWVzIHRvIG1vcmUgY29udmVuaWVudCBudW1iZXJzIHN1Y2ggYXMKICAqIF9fMy40ICRcdG8kIDNfXy4KICAqIF9fOC43ICRcdG8kIDlfXy4KMi4gVGhlIG5ldyBkYXRhIF9fcmFuZ2VfXyBpcyBnaXZlbiBieSBfX3JhbmdlX189OS0zPTYKMy4gV2UgY2hvb3NlIGEgbnVtYmVyIGJldHdlZW4gX181X18gYW5kIF9fMjBfXyB3aGljaCBfX2RpdmlkZXNfXyBldmVubHkgaW50byB0aGlzIF9fcmFuZ2VfXywgYW5kIHNvIGFuIG9idmlvdXMgY2hvaWNlIGlzIF9fNiBiYXJzX18gZm9yIHRoaXMgaGlzdG9ncmFtLgo0LiBXZSBjcmVhdGUgYSBfX3ZlY3Rvcl9fIHZhbHVlZCBvYmplY3QgdG8gc3RvcmUgdGhlIG1lYXN1cmVkIGhlaWdodHM6IAoKYGBge3J9CkhlaWdodHMgPC0gYygzLjQsIDMuNSwgMy43LCA0LjIsIDQuNCwgNC43LCA0LjksIDUuMSwgNS4yLCA1LjMsIDUuOSwgNi4wLCA2LjQsIDcuMywgNy45LCA4LjEsIDguNykKYGBgCgo1LiBXZSB1c2UgdGhlIF9faGlzdCgpX18gZnVuY3Rpb24gdG8gcGxvdCBhIGhpc3RvZ3JhbSBvZiB0aGUgdmVjdG9yIF9fSGVpZ2h0c19fCgpgYGB7cn0KaGlzdChIZWlnaHRzLCBicmVha3M9NiwgYXhlcz1ULGNvbD0ic2t5Ymx1ZTQiLCBtYWluPSJIaXN0b2dyYW0gb2YgVHJlZSBIZWlnaHRzIGluIGFuIE9yY2hhcmQiLCB5bGFiPSJGcmVxdWVuY3kiLCB4bGFiPSJUcmVlIGhlaWdodHMgKG0pIiwgZnJlcT1UKQpgYGAKCjYuIFRvIHByaW50IGEgUERGIG9mIHRoaXMgZ3JhcGggd2UgdXNlIHRoZSBfX3BkZigpX18gYW5kIF9fZGV2Lm9mZigpX18gY29tbWFuZHMKYGBge3J9CnBkZigiSGlzdG9ncmFtMS5wZGYiKQpoaXN0KEhlaWdodHMsYnJlYWtzPTYsIGF4ZXM9VCxjb2w9InNreWJsdWU0IiwgbWFpbj0iSGlzdG9ncmFtIG9mIFRyZWUgSGVpZ2h0cyBpbiBhbiBPcmNoYXJkIiwgeWxhYj0iRnJlcXVlbmN5IiwgeGxhYj0iVHJlZSBoZWlnaHRzIChtKSIsIGZyZXE9VCkKZGV2Lm9mZigpCmBgYAo3LiBVbmxpa2UgdGhlIF9fYmFycGxvdCgpX18gY29tbWFuZCwgdGhlIGhpc3RvZ3JhbSBwbG90IGF1dG9tYXRlcyBhIGxhcmdlIGFtb3VudCBvZiB0aGUgd29yayBmb3IgdXMuIE5ldmVydGhlbGVzcywgaXQgaXMgc3RpbGwgcG9zc2libGUgdG8gb3ZlcnJpZGUgbW9zdCBvZiB0aGVzZSBhdXRvbWF0aWMgY2hvaWNlcyBieSBzZWxlY3RpbmcgdmFyaW91cyBhcmd1bWVudHMgZm9yIHRoZSBfX2hpc3QoKV9fIGZ1bmN0aW9uLiAKCiogTW9zdCBvZiB0aGVzZSBhcmd1bWVudHMgYXJlIGV4cGxhaW5lZCBpbiB0aGUgX19SX18gZG9jdW1lbnRhdGlvbiBhdmFpbGFibGUgaW4gdGhlIF9fSGVscF9fIHBhbmVsIG9mIHRoZSBfX1IgU3R1ZGlvX18gZW52aXJvbm1lbnQuIEp1c3QgdHlwZSBoaXN0IGludG8gdGhlIHRoZSBzZWFyY2ggYmFyIGFuZCBwcmVzcyBlbnRlci4gIAoKIyMgU2tld2VkIERhdGEgYW5kIENlbnRyYWwgRGF0YQoKQSBjb2xsZWN0aW9uIG9mIGRhdGEgaXMgX19za2V3ZWQgbGVmdF9fIGlmIGl0cyBoaXN0b2dyYW0gZGlzcGxheXMgYSB0YWlsIHRvIHRoZSBsZWZ0LiBUaGlzIG1lYW5zIHRoZSBhdCBwb3NzZXNzIF9fb3V0bGllcnNfXyBhdCB0aGUgbG93ZXIgZW5kICBvZiB0aGUgZGF0YSBzZXQuCgojIyMgRXhhbXBsZTogU2tld2VkLWxlZnQgZGF0YQoKYGBge3J9CkxlZnQ8LWMoMSw4LDgsOCw5LDksOSwxMCwxMCwxMSwxMSwxMSkKaGlzdChMZWZ0LGNvbD0iY29ybmZsb3dlcmJsdWUiLG1haW49IkxlZnQtU2tld2VkIERhdGEiLCB4bGFiPSJMZWZ0IERhdGEgVmFsdWVzIikKYGBgCiogTm90aWNlLCBtb3N0IG9mIHRoZSBkYXRhIGlzIGNvbmNlbnRyYXRlZCB0byB0aGUgcmlnaHQgYmV0d2VlbiA2IGFuZCAxMi4gSG93ZXZlciwgYSBzbWFsbCBwb3J0aW9uIG9mIHRoZSBkYXRhIGZvcm1zIGEgX19sZWZ0LXRhaWxfXyBiZXR3ZWVuIDAgYW5kIDIuIFRoaXMgdGFpbCBpcyB3aGF0IHNrZXdzIHRoZSBkYXRhIHRvIHRoZSBsZWZ0LgoKCgpDb252ZXJzZWx5LCB0aGUgZGF0YSBpcyBfX3NrZXdlZCByaWdodF9fIGlmIHRoZSBoaXN0b2dyYW0gZGlzcGxheXMgYSB0YWlsIHRvIHRoZSByaWdodCwgYW5kIGxpa2V3aXNlIHRoaXMgaW5kaWNhdGVzIHRoZSBwcmVzZW5jZSBvZiBvdXRsaW5lcyBhdCB0aGUgdXBwZXIgZW5kIG9mIHRoZSBkYXRhIHNldC4KCiMjIyBFeGFtcGxlOiBSaWdodC1za2V3ZWQgZGF0YQpgYGB7cn0KUmlnaHQ8LWMoMSwxLDIsMywzLDMsNCw0LDUsNSw1LDEyKQpoaXN0KFJpZ2h0LGJyZWFrcz01LCBjb2w9ImNvcm5mbG93ZXJibHVlIixtYWluPSJSaWdodC1Ta2V3ZWQgRGF0YSIsIHhsYWI9IlJpZ2h0IERhdGEgVmFsdWVzIikKYGBgCiogTW9zdCBvZiB0aGUgZGF0YSBpcyBjb25jZW50cmF0ZWQgdG8gdGhlIGxlZnQgYmV0d2VlbiAwIGFuZCA2LiBIb3dldmVyLCBhIHNtYWxsIHBvcnRpb24gb2YgdGhlIGRhdGEgZm9ybXMgYSBfX3JpZ2h0LXRhaWxfXyBiZXR3ZWVuIDEwIGFuZCAxMi4gVGhpcyB0YWlsIGlzIHdoYXQgc2tld3MgdGhlIGRhdGEgdG8gdGhlIHJpZ2h0LgoKIyMjIFRlc3QgZm9yIHNrZXduZXNzCgoqIElmIHRoZSBkYXRhIGlzIF9fc2tld2VkIHJpZ2h0X18gdGhlbgpcXFsKICAgbWVhbiA+IG1lZGlhbgpcXF0KCgoqIElmIHRoZSBkYXRhIGlzIF9fc2tld2VkIGxlZnRfXyB0aGVuClxcWwogIG1lYW4gPCBtZWRpYW4KXFxdCgoqIElmIHRoZSBkYXRhIGlzIF9fY2VudHJhbF9fIHRoZW4KXFxbCiAgbWVhbiA9IG1lZGlhbgpcXF0KICBhbmQgdGhlIGhpc3RvZ3JhbSBpcyBzeW1tZXRyaWMuCiAgCiMjIyBFeGFtcGxlOiBUZXN0IGZvciBza2V3bmVzcwpXZSB3aWxsIHRlc3QgdGhlIGRhdGEgc2V0cyBfX0xlZnRfXyBhbmQgX19SaWdodF9fIGZvciBza2V3bmVzcy4KCiMjIyMgTGVmdCBEYXRhOgpgYGB7cn0KbWVhbihMZWZ0KQpgYGAKYGBge3J9Cm1lZGlhbihMZWZ0KQpgYGAKCiogV2Ugc2VlIHRoYXQgdGhlIG1lYW4gb2YgdGhlIF9fTGVmdF9fIGRhdGEgaXMgbGVzcyB0aGFuIHRoZSBtZWRpYW4gb2YgdGhlIF9fTGVmdF9fIGRhdGEsIGNvbmZpcm1pbmcgaXQgaXMgc2tld2VkLWxlZnQuCgoKIyMjIyBSaWdodCBEYXRhOgpgYGB7cn0KbWVhbihSaWdodCkKYGBgCgpgYGB7cn0KbWVkaWFuKFJpZ2h0KQpgYGAKCiogV2Ugc2VlIHRoYXQgdGhlIG1lYW4gb2YgdGhlIF9fUmlnaHRfXyBkYXRhIGlzIGdyZWF0ZXIgdGhhbiB0aGUgbWVkaWFuIG9mIHRoZSBfX1JpZ2h0X18gZGF0YSwgY29uZmlybWluZyBpdCBpcyBza2V3ZWQtcmlnaHQuCgoKIyMjIyBTa2V3bmVzcyBvZiBIZWlnaHRzOgoKVGhlIGhpc3RvZ3JhbSBpbiBfX0V4YW1wbGUgMV9fIGFwcGVhcnMgdG8gZGlzcGxheSBhIHRhaWwgdG8gdGhlIHJpZ2h0IGFuZCBzbyB3ZSBleHBlY3QgdGhlIGRhdGEgdG8gYmUgX19za2V3ZWQgcmlnaHRfXy4gCgpUbyB0ZXN0IHRoaXMgd2UgY2FuIHVzZSB0aGUgX19tZWFuKClfXyBhbmQgdGhlIF9fbWVkaWFuKClfXyBmdW5jdGlvbnMgYW5kIGNvbXBhcmUuCgpgYGB7cn0KbWVhbihIZWlnaHRzKQptZWRpYW4oSGVpZ2h0cykKYGBgClNpbmNlIHRoZSBtZWFuIGlzIGJpZ2dlciB0aGFuIHRoZSBtZWRpYW4sIHRoaXMgbWVhbnMgdGhlIGRhdGEgaXMgX19za2V3ZWQgcmlnaHRfXyBhcyB3ZSBleHBlY3QgZnJvbSB0aGUgaGlzdG9ncmFtIGFib3ZlLgoKIyMgRXhhbXBsZSAyClRoZSBtYXJrcyBzY29yZWQgYnkgYSBjbGFzcyBpbiBhIHRlc3QgYXJlIGFzIGZvbGxvd3MgKG5vdCBpbiBvcmRlcik6CgogKiA1MCwgNjMsIDI5LCA1NCwgNTYsIDAsIDUzLCAzNCwgNDUsIDg1LCA2NSwgNjIsIDYwLCAzLCA3MSwgNjYsIDYzLCA2OCwgNjksIDY3LCA3OSwgNzUsIDcyLCA4MSwgODcsIDkxLCA1MiAKClVzaW5nIHRoaXMgZGF0YSwgYW5zd2VyIHRoZSBmb2xsb3dpbmc6CgpBLiBVc2UgdGhlIF9fc29ydCgpX18gZnVuY3Rpb24gdG8gc29ydCB0aGlzIGRhdGEgYW5kIHRoZSBfX2xlbmd0aCgpX18gZnVuY3Rpb24gdG8gY291bnQgdGhlIGRhdGEgcG9pbnRzCgpCLiBEcmF3IGEgaGlzdG9ncmFtIHRvIHJlcHJlc2VudCB0aGlzIHNvcnRlZCBkYXRhCgpDLiBGcm9tIHRoZSBoaXN0b2dyYW0gZGVjaWRlIGlmIHRoZSBkYXRhIGlzIF9fc2tld2VkIGxlZnRfXywgX19za2V3ZWQgcmlnaHRfXyBvciBfX3N5bW1ldHJpY19fCgpELiBGaW5kIHRoZSBtZWFuIG9mIHRoaXMgZGF0YQoKRS4gRmluZCB0aGUgbWVkaWFuIG9mIHRoaXMgZGF0YSBzZXQKCkYuIENvbXBhcmluZyB0aGUgbWVhbiBhbmQgdGhlIG1lZGlhbiwgZGVjaWRlIGlmIHRoZSBkYXRhIGlzIF9fc2tld2VkIGxlZnRfXywgX19za2V3ZWQgcmlnaHRfXyBvciBfX3N5bW1ldHJpY19fLiBEb2VzIHRoaXMgYWdyZWUgd2l0aCB0aGUgaGlzdG9ncmFtPwoKIyMjIFNvbHV0aW9uCkEuCmBgYHtyfQpTY29yZXMgPC0gYyg1MCwgNjMsIDI5LCA1NCwgNTYsIDAsIDUzLCAzNCwgNDUsIDg1LCA2NSwgNjIsIDYwLCAzLCA3MSwgNjYsIDYzLCA2OCwgNjksIDY3LCA3OSwgNzUsIDcyLCA4MSwgODcsIDkxLCA1MikKc29ydChTY29yZXMpCmBgYApgYGB7cn0KbGVuZ3RoKFNjb3JlcykKYGBgCkIuCmBgYHtyfQpoaXN0KFNjb3JlcywgYnJlYWtzPTgsIHhsaW09YygwLDEwMCkseWxpbT1jKDAsMC4wMiksZnJlcT1GLCB4bGFiPSJFeGFtIFNjb3JlcyIsIHlsYWI9IlJlbGF0aXZlIEZyZXF1ZW5jeSIsIGNvbD0iZGFya3NsYXRlZ3JheTQiLCBtYWluPSJIaXN0b2dyYW0gb2YgRXhhbSBTY29yZXMiKQpgYGAKCkMuIApGcm9tIHRoZSBoaXN0b2dyYW0sIHRoZSBkYXRhIGFwcGVhcnMgdG8gYmUgc2tld2VkLWxlZnQuCgoKRC4KYGBge3J9Cm1lYW4oU2NvcmVzKQpgYGAKCmBgYHtyfQptZWRpYW4oU2NvcmVzKQpgYGAKU2luY2UgdGhlIG1lYW4gaXMgbGVzcyB0aGFuIHRoZSBtZWRpYW4gdGhlIGRhdGEgaXMgc2tld2VkIGxlZnQuIFRoaXMgYWdyZWVzIHdpdGggdGhlIHNoYXBlIG9mIHRoZSBoaXN0b2dyYW0gZm9yIHRoZSBkYXRhIHNldC4KCiMjIyBFeGVyY2lzZSAxCgpUaGUgam91cm5leSB0aW1lcyAoaW4gaG91cnMpIGZvciBhIHRyYWluIHNlcnZpY2UgYmV0d2VlbiB0d28gY2l0aWVzIHdlcmUgcmVzdW1lZCBvbiBhIGdpdmVuIGRheSwgd2l0aCB0aGUgZm9sbG93aW5nIGRhdGEgZ2F0aGVyZWQKCjEuMiwgMS4yMiwgMS4yMywgMS4yNSwgMS4zLCAxLjM0LCAxLjM2LCAxLjM5LCAxLjQwLCAxLjQyLCAxLjQ1LCAxLjQ4LCAxLjUxLCAxLjU2CgpHaXZlbiB0aGlzIGRhdGEsIGFuc3dlciB0aGUgZm9sbG93aW5nOgoKMS4gVXNlIHRoZSBfX21lZGlhbigpX18gZnVuY3Rpb24gdG8gZmluZCB0aGUgbWVkaWFuIG9mIHRoaXMgZGF0YSBzZXQKCjIuIFVzZSB0aGUgX19tZWFuKClfXyBmdW5jdGlvbgoKMy4gQ29tcGFyaW5nIHRoZSBtZWFuIGFuZCB0aGUgbWVkaWFuIG9mIHRoZSBkYXRhIHNldCwgaXMgdGhlIGRhdGEgc2tld2VkLWxlZnQsIHNrZXdlZC1yaWdodCBvciBjZW50cmFsCgo0LiBDb25zdHJ1Y3QgYSBoaXN0b2dyYW0gb2YgdGhpcyBkYXRhIHNldAoKNS4gVXNpbmcgdGhpcyBoaXN0b2dyYW0sIGRlY2lkZSBpZiB0aGUgZGF0YSBpcyBza2V3ZWQtbGVmdCwgc2tld2VkLXJpZ2h0IG9yIGNlbnRyYWwKCjYuIERvZXMgdGhpcyBhZ3JlZSB3aXRoIHlvdXIgYW5zd2VyIGZyb20gcGFydCAzPwoKCiMjIyBFeGVyY2lzZSAyCgpBbiBlbGVjdHJpY2FsIGNvbXBvbmVudHMgbWFudWZhY3R1cmVyIG1lYXN1cmVzIHRoZSByZXNpc3RhbmNlIG9mIGEgc2FtcGxlIG9mIDUwIHJlc2lzdG9ycyBwcm9kdWNlZCBkdXJpbmcgb25lIHByb2R1Y3Rpb24gcnVuLiBUaGUgcmVzaXN0YW5jZXMgd2VyZSBtZWFzdXJlZCBhcyBmb2xsb3dzCgo1MS4yMCwgNTAuMzAsIDUyLjQwLCA1MC4yNCwgNTEuMjUsIDQ5Ljg5LCA1MS42MywgNTIuODQsIDUzLjAxLCA0OS45OQoKNTAuMzQsIDUwLjYxLCA1MS45MywgNTIuMjUsIDQ5Ljg3LCA1MC4xMywgNTEuMzIsIDUwLjQzLCA1MS4zNCwgNTIuMTMKCjUyLjExLCA1Ni44NCwgNTcuODEsIDUxLjMzLCA1Mi4zNiwgNTAuNjcsIDUxLjg5LCA1Mi4xMywgNTIuMTgsIDUwLjMxCgo1MC44NCwgNTEsMTIsIDUwLjk1LCA0OS45OCwgNTEuMDMsIDUyLjAxLCA1MC45NiwgNTEuMDIsIDUyLjQ0LCA1MS45NQoKR2l2ZW4gdGhpcyBkYXRhLCBhbnN3ZXIgdGhlIGZvbGxvd2luZzoKCjEuIFNvcnQgdGhlIGRhdGEgYWNjb3JkaW5nIHRvIGluY3JlYXNpbmcgbWVhc3VyZW1lbnRzIG9mIHJlc2lzdGFuY2UKCjIuIFVzZSB0aGUgX19tZWRpYW4oKV9fIGZ1bmN0aW9uIHRvIGZpbmQgdGhlIG1lZGlhbiBvZiB0aGlzIGRhdGEgc2V0CgozLiBVc2UgdGhlIF9fbWVhbigpX18gZnVuY3Rpb24KCjQuIENvbXBhcmluZyB0aGUgbWVhbiBhbmQgdGhlIG1lZGlhbiBvZiB0aGUgZGF0YSBzZXQsIGlzIHRoZSBkYXRhIHNrZXdlZC1sZWZ0LCBza2V3ZWQtcmlnaHQgb3IgY2VudHJhbAoKNS4gQ29uc3RydWN0IGEgaGlzdG9ncmFtIG9mIHRoaXMgZGF0YSBzZXQKCjYuIFVzaW5nIHRoaXMgaGlzdG9ncmFtLCBkZWNpZGUgaWYgdGhlIGRhdGEgaXMgc2tld2VkLWxlZnQsIHNrZXdlZC1yaWdodCBvciBjZW50cmFsCgo3LiBEb2VzIHRoaXMgYWdyZWUgd2l0aCB5b3VyIGFuc3dlciBmcm9tIHBhcnQgND8KCiMjIyBFeGVyY2lzZSAzIApUaGUgd2F0ZXIgcXVhbGl0eSBhdCBhIHdhdGVyIHRyZWF0bWVudCBmYWNpbGl0eSBpcyBtZWFzdXJlZCBob3VybHkgYnkgbWVhc3VyaW5nIHRoZSBpbXB1cml0aWVzIHByZXNlbnQgaW4gdGhlIHdhdGVyIGluIChtZWFzdXJlZCBpbiBwYXJ0ZXJyZS1taWxsaW9uKS4gVGhlIGZvbGxvd2luZyBkYXRhIHdhcyBjb2xsZWN0ZWQgZHVyaW5nIGluIG9uZSAzNiBob3VyIHBlcmlvZDoKCgoKMTgsIDgsIDI1LCAxMywgNywgMTkKCjE0LCA1LCAyMSwgMjMsIDE4LCA1CgoxMywgNiwgMTUsIDIxLCAxNywgNgoKMTUsIDcsIDEzLCA1LCAxOCwgMTEKCjEyLCAxNCwgMTUsIDE2LCAxMiwgMTMKCjksIDE3LCAxNiwgMTksIDgsIDEwCgpHaXZlbiB0aGlzIGRhdGEsIGFuc3dlciB0aGUgZm9sbG93aW5nOgoKMS4gU29ydCB0aGUgZGF0YSBpbiBvcmRlciBvZiBpbmNyZWFzaW5nIHZhbHVlcyBvZiBpbXB1cml0aWVzIG1lYXN1cmVkCgoyLiBVc2UgdGhlIF9fbWVkaWFuKClfXyBmdW5jdGlvbiB0byBmaW5kIHRoZSBtZWRpYW4gb2YgdGhpcyBkYXRhIHNldAoKMy4gVXNlIHRoZSBfX21lYW4oKV9fIGZ1bmN0aW9uCgo0LiBDb21wYXJpbmcgdGhlIG1lYW4gYW5kIHRoZSBtZWRpYW4gb2YgdGhlIGRhdGEgc2V0LCBpcyB0aGUgZGF0YSBza2V3ZWQtbGVmdCwgc2tld2VkLXJpZ2h0IG9yIGNlbnRyYWwKCjUuIENvbnN0cnVjdCBhIGhpc3RvZ3JhbSBvZiB0aGlzIGRhdGEgc2V0Cgo2LiBVc2luZyB0aGlzIGhpc3RvZ3JhbSwgZGVjaWRlIGlmIHRoZSBkYXRhIGlzIHNrZXdlZC1sZWZ0LCBza2V3ZWQtcmlnaHQgb3IgY2VudHJhbAoKNy4gRG9lcyB0aGlzIGFncmVlIHdpdGggeW91ciBhbnN3ZXIgZnJvbSBwYXJ0IDQ/CgoKIyBQYXJldG8gQ2hhcnRzCgpBIFBhcmV0byBjaGFydCBpcyBhIGNvbWJpbmF0aW9uIG9mIGEgX19iYXIgY2hhcnRfXyBhbmQgYSBfX2N1bXVsYXRpdmUgZnJlcXVlbmN5IGNoYXJ0X18KClRoZXkgYXJlIGEgdXNlZnVsIGRpYWdub3N0aWMgdG9vbCB3aGVuIG9uZSB3aXNoZXMgdG8gbGltaXQgdmFyaW91cyBkZWZlY3RzLCBlcnJvcnMsIGRlbGF5cywgYnJlYWtkb3ducyBpbiBkaWZmZXJlbnQgY2lyY3Vtc3RhbmNlcy4KCl9fUmVtYXJrOl9fIFRvIGdlbmVyYXRlIFBhcmV0byBjaGFydHMgd2UgbmVlZCB0byBpbXBvcnQgdGhlIF9fcWNjX18gbGlicmFyeSBhcyBmb2xsb3dzCgogIDEuIEluIHRoZSBfX1Rvb2xzX18gdGFiIGFib3ZlLCBzZWxlY3QgdGhlIG9wdGlvbiBfX0luc3RhbGwgUGFja2FnZXMuLi5fXwogIDIuIEluIHRoZSBfX0luc3RhbGwgZnJvbV9fIG9wdGlvbiwgc2VsZWN0IF9fUmVwb3NpdG9yeShDUkFOLCBDUkFOZXh0cmEpX18KICAzLiBJbiB0aGUgX19QYWNrYWdlc19fIGlucHV0IGxpbmUgdHlwZSBfX3FjY19fCiAgNC4gSU4gdGhlIF9fSW5zdGFsbCB0byBMaWJyYXJ5X18gb3B0aW9uIHNlbGVjdCB5b3VyIG93biBob21lIGRpcmVjdG9yeSAodGhpcyBzaG91bGQgYmUgdGhlIGRhZmZvZGlscyBhbnlob3cpCiAgNS4gTWFrZSBzdXJlIF9fSW5zdGFsbCBhbGwgZGVwZW5kZW5jaWVzX18gaXMgY2hlY2tlZAogIApPbmNlIGluc3RhbGxlZCB3ZSBjYWxsIHRoZSBsaWJyYXJ5IF9fcWNjX18gYXMgZm9sbG93cwpgYGB7cn0KbGlicmFyeShxY2MpCmBgYAoKCiMjIyBFeGFtcGxlIDEKIFRoZSBlbXBsb3llZXMgb2YgYSBjb21wYW55IHdlcmUgYXNrZWQgdGhlIHJlYXNvbnMgZm9yIGxhdGUgYXJyaXZhbHMgYXQgd29yay4gVGhlIGRhdGEgY29sbGVjdGVkIHdlcmUgYXMgZm9sbG93czoKIAogKiBfX0NoaWxkIENhcmVfXyAyMgogCiAqIF9fRW1lcmdlbmN5X18gOAogCiAqIF9fT3ZlcnNsZXB0X18gMTIKIAogKiBfX1B1YmxpYyB0cmFuc3BvcnRfXyAxNQogCiAqIF9fVHJhZmZpY19fIDM2CiAKICogX19XZWF0aGVyX18gMjcKIAogVXNpbmcgdGhpcyBkYXRhIGFuc3dlciB0aGUgZm9sbG93aW5nOgogCiAxLiBDcmVhdGUgYW4gYXBwcm9wcmlhdGUgdmVjdG9yIHRvIHJlcHJlc2VudCB0aGlzIGRhdGEuCiAKIDIuIFVzZSB0aGUgZnVuY3Rpb24gX19wYXJldG8uY2hhcnQoKV9fIHRvIGdlbmVyYXRlIGEgUGFyZXRvIGNoYXJ0IGZvciB0aGlzIGRhdGEuCiAKIDMuIEZyb20gdGhlIFBhcmV0byBjaGFydCwgZGV0ZXJtaW5lIHdoaWNoIGNhdXNlcyBjb3VsZCByZWFzb25hYmxlIGJlIGFkZHJlc3NlZCB0byByZWR1Y2UgbGF0ZSBhcnJpdmFscyBieSBhdCBsZWFzdCAzNSUuCiAKMS4gV2UgZmlyc3QgY3JlYXRlIGFuIGFwcHJvcHJpYXRlIHZlY3RvciBvZiBudW1iZXJzIHRvIHJlcHJlc2VudCB0aGUgZGF0YSwgaW4gdGhlIHVzdWFsIHdheToKYGBge3J9CkVtcGxveWVlcyA8LSBjKDIyLDgsMTIsMTUsMzYsMjcpCkVtcGxveWVlcwpgYGAKTm93IHdlIGNyZWF0ZSBhbiBhcHByb3ByaWF0ZSB2ZWN0b3Igb2YgbmFtZXMsIGNvcnJlc3BvbmRpbmcgdGhlIHRoZXNlIG51bWJlcnMgYXMgZm9sbG93czoKYGBge3J9ClJlYXNvbnMgPC0gYygiQ2hpbGQgQ2FyZSIsICJFbWVyZ2VuY3kiLCAiT3ZlcnNsZXB0IiwgIlB1YmxpYyBUcmFuc3BvcnQiLCAiVHJhZmZpYyIsICJXZWF0aGVyIikKUmVhc29ucwpgYGAKCiogTm93IHdlIHJlLWNyZWF0ZSB0aGUgX19FbXBsb3llZXNfXyB2ZWN0b3IgYnkgYXNzaWduaW5nIGl0IHRoZSBuYW1lcyBpbiB0aGUgdmVjdG9yIF9fUmVhc29uc19fIGFzIGZvbGxvd3M6CmBgYHtyfQpuYW1lcyhFbXBsb3llZXMpPC1SZWFzb25zCmBgYAppLmUuIGVhY2ggZW50cnkgaGFzIG5vdyBiZWVuIGdpdmVuIGEgY29ycmVzcG9uZGluZyBuYW1lLgoKKiBUaGUgbmV3IF9fRW1wbG95ZWVzX18gdmVjdG9yIGlzIAoKYGBge3J9CkVtcGxveWVlcwpgYGAKYW5kIHNvIHdlIHNlZSBlYWNoIG51bWJlciBoYXMgYmVlbiBhc3NpZ25lZCBhIGNvcnJlc3BvbmRpbmcgcmVhc29uLgoKMi4gVGhlIF9fUGFyZXRvIENoYXJ0X18gZm9yIHRoaXMgZGF0YSBpcyBnaXZlbiBieQoKYGBge3J9CnBhcmV0by5jaGFydChFbXBsb3llZXMsY29sPSJza3libHVlMiIsIGN1bXBlcmM9c2VxKDAsMTAwLGJ5PTEwKSwgbWFpbj0iUGFyZXRvIGNoYXJ0IGdpdmluZyByZWFzb25zIGZvciBsYXRlIGFycml2YWxzIGF0IHdvcmsiKQpgYGAKCiogV2Ugbm90aWNlIHRoYXQgdGhlIF9fcGFyZXRvLmNoYXJ0KClfXyBmdW5jdGlvbiBwbG90cyB0aGUgZnJlcXVlbmN5IG9mIGVhY2ggY2xhc3MsIGFzIG9wcG9zZWQgdG8gdGhlIHJlbGF0aXZlIGZyZXF1ZW5jeSBvZiBlYWNoIGNsYXNzLiBUaGlzIGlzIGVhc2lseSBtb2RpZmllZCBieSBzdW1taW5nIGFsbCBmcmVxdWVuY2llcyBpbiB0aGUgX19FbXBsb3llZXNfXyB2ZWN0b3IgYW5kIGRpdmlkaW5nIHRoZSB0aGUgdmVjdG9yIGJ5IHRoaXMgbnVtYmVyIHRvIGdpdmUgdGhlIF9fZnJlcXVlbmN5IGRlbnNpdHlfXyBvZiBlYWNoIGNsYXNzLgoKYGBge3J9ClRvdGFsPXN1bShFbXBsb3llZXMpClRvdGFsCmBgYAoKYGBge3J9CkVtcGxveWVlcyA8LSBFbXBsb3llZXMvVG90YWwKRW1wbG95ZWVzCmBgYApgYGB7cn0KcGFyZXRvLmNoYXJ0KEVtcGxveWVlcyxjb2w9InNreWJsdWUyIiwgY3VtcGVyYz1zZXEoMCwxMDAsYnk9MTApLCB5bGFiPSJSZWxhdGl2ZSBGcmVxdWVuY3kiLCBtYWluPSJQYXJldG8gY2hhcnQgZ2l2aW5nIHJlYXNvbnMgZm9yIGxhdGUgYXJyaXZhbHMgYXQgd29yayIpCmBgYAoKCiMjIEV4ZXJjaXNlIDQKCkEgbW9iaWxlIHBob25lIHJlcGFpciBzaG9wIGNhdGVnb3JpemVkIHRoZSB0eXBlIG9mIHJlcGFpciB3b3JrIGl0IGNhcnJpZWQgb3V0IG92ZXIgYSB5ZWFyIGFuZCBmb3VuZCB0aGUgZm9sbG93aW5nIGRhdGE6CiAgCiogX19DcmFja2VkIFNjcmVlbl9fIDEyNQoqIF9fU2NyYXRjaGVkIFNjcmVlbl9fIDIyOAoqIF9fRm9yZ290dGVuIFBhc3MgY29kZV9fIDkxCiogX19XYXRlciBEYW1hZ2VfXyAxODgKKiBfX0JhdHRlcnkgUmVwbGFjZW1lbnRfXyAxMTEKKiBfX1NvZnR3YXJlIFZpcnVzX18gODIKKiBfX1Bob25lIEJyaWNraW5nX18gMTg4CiogX19EYW1hZ2VkIENvbm5lY3Rvcl9fIDQxCiAgCkdpdmVuIHRoaXMgZGF0YSwgYW5zd2VyIHRoZSBmb2xsb3dpbmc6CgoxLiBGaW5kIHRoZSB0b3RhbCBudW1iZXIgb2YgcmVwYWlycyBpbiB0aGUgeWVhci4KCjIuIENvbnN0cnVjdCBhIHZlY3RvciB0byByZXByZXNlbnQgdGhlIHJlbGF0aXZlIGZyZXF1ZW5jaWVzIG9mIGVhY2ggb2YgdGhlc2UgY2xhc3Nlcy4KCjMuIFVzZSB0aGlzIHZlY3RvciBvZiByZWxhdGl2ZSBmcmVxdWVuY2llcyB0byBjb25zdHJ1Y3QgYSBQYXJldG8gY2hhcnQgb2YgdGhpcyBkYXRhLgoKNC4gRnJvbSB0aGUgUGFyZXRvIGNoYXJ0IGRldGVybWluZSB0aGUgY2F1c2VzIG9mIHBob25lIGRhbWFnZSBvd25lcnMgc2hvdWxkIGFkZHJlc3MgdG8gcmVkdWNlIHJlcGFpcnMgYnkgYXQgbGVhc2UgMjUlLgoKCgojIyBFeGVyY2lzZSA1CgpBIG5ld2x5IGJ1aWx0IGFwYXJ0bWVudCBjb21wbGV4IHdhcyBpbnNwZWN0ZWQgdG8gcHJlcGFyZSBhIHNuYWcgbGlzdCBmb3IgZWFjaCBhcGFydG1lbnQuIEFmdGVyIGluc3BlY3Rpb24gb2YgYXBhcnRtZW50IHRoZSBjb21wbGV4LCB0aGUgZm9sbG93aW5nIGlzc3VlcyB3ZXJlIGZvdW5kIHRvIG9jY3VyIHdpdGggdGhlIGZyZXF1ZW5jeSBpbmRpY2F0ZWQ6CgojIyMgTGlzdCBvZiBEYW1hZ2VzCiogX19Db29rZXIgRGlzY29ubmVjdGVkX18gNAoqIF9fV2luZG93cyBOb3QgQ2xvc2luZ19fIDE4CiogX19CYXRocm9vbSBWZW50aWxhdG9yIEJyb2tlbl9fIDkKKiBfX0RhbWFnZWQgUGx1ZyBTb2NrZXRzX18gNTEKKiBfX0Jyb2tlbiBMaWdodF9fIDI5CiogX19EYW1hZ2VkIFBhaW50d29ya19fIDQ3CiogX19Eb29ycyBOb3QgTG9ja2luZ19fIDE0CiogX19EYW1wbmVzc19fIDIKKiBfX1NjcmF0Y2hlZCBGbG9vcmluZ19fIDIxCgpVc2luZyB0aGlzIGRhdGEgYW5zd2VyIHRoZSBmb2xsb3dpbmc6CgoxLiBJZGVudGlmeSB0aGUgZGF0YSB0eXBlIGdpdmVuLgoKMi4gQ29uc3RydWN0IGEgdmVjdG9yIHRvIHJlcHJlc2VudCB0aGUgZnJlcXVlbmNpZXMuCgozLiBVc2luZyB0aGlzIHZlY3RvciwgZXZhbHVhdGUgdGhlIG51bWJlciBvZiBkYW1hZ2VzIHRvIGJlIHJlcGFpcmVkIGluIHRoZSBhcGFydG1lbnQgY29tcGxleC4KCjQuIFVzaW5nIHRoZSB2ZWN0b3Igb2YgZnJlcXVlbmN5IHZhbHVlcywgY29uc3RydWN0IGEgUGFyZXRvIGNoYXJ0IGZvciB0aGlzIGRhdGEuCgo1LiBGcm9tIHRoaXMgZGF0YSBkZXRlcm1pbmUgaG93IHdoaWNoIGlzc3VlcyBzaG91bGQgYmUgYWRkcmVzc2VkIHRvIGVuc3VyZSBhdCBsZWFzdCA3NSUgb2YgZGFtYWdlcyBhcmUgcmVwYWlyZWQuCg==