3.2.4 Exercises

library(tidyverse)
Loading tidyverse: ggplot2
Loading tidyverse: tibble
Loading tidyverse: tidyr
Loading tidyverse: readr
Loading tidyverse: purrr
Loading tidyverse: dplyr
Conflicts with tidy packages ------------------------------------------------------------------------------------
filter(): dplyr, stats
lag():    dplyr, stats

1. Run ggplot(data = mpg) what do you see?

Nothing plotted, but a canvas for a plot is shown.

2. How many rows are in mtcars? How many columns?

dim(mtcars)
[1] 32 11

3. What does the drv variable describe? Read the help for ?mpg to find out.

?mpg
# drv
# f = front-wheel drive, r = rear wheel drive, 4 = 4wd

4. Make a scatterplot of hwy vs cyl.

ggplot(data = mpg) + geom_point(mapping = aes(x = displ, y = hwy))

5. What happens if you make a scatterplot of class vs drv. Why is the plot not useful?

The class and drv attributes are categorical. Therefore the plot shows the mapping between these categories.

ggplot(data = mpg) + geom_point(mapping = aes(x = class, y = drv))

3.3.1 Exercises

1. What’s gone wrong with this code? Why are the points not blue?

ggplot(data = mpg) + geom_point(mapping = aes(x = displ, y = hwy, color = "blue"))

The points are not blue, because the color layer is specified within the aes mappings. Thus the framework tries to plot the color against an attribute “blue”, but this does not exist within the data. The correct code would be to set the color manually in the geom_point method.

ggplot(data = mpg) + geom_point(mapping = aes(x = displ, y = hwy), color = "blue")

2. Which variables in mpg are categorical? Which variables are continuous? (Hint: type ?mpg to read the documentation for the dataset). How can you see this information when you run mpg?

The information is shown directly under the column names: <chr> [characters] are likely to be categorical, whereas <dbl> [double] and <int> [integer] are likely to be continuous.

head(mpg, 1)

3. Map a continuous variable to color, size, and shape. How do these aesthetics behave differently for categorical vs. continuous variables?

For continuous variables a scale is shown, otherwise the category names.

ggplot(data = mpg) + geom_point(mapping = aes(x = displ, y = hwy, color = cyl, size = hwy, shape = drv))

4. What happens if you map the same variable to multiple aesthetics?

Simply both layers are applied.

ggplot(data = mpg) + geom_point(mapping = aes(x = displ, y = hwy, color = cyl, size = cyl))

5. What does the stroke aesthetic do? What shapes does it work with? (Hint: use ?geom_point)

The stroke aesthetic seems to adjust the plotted object thickness.

6. What happens if you map an aesthetic to something other than a variable name, like aes(colour = displ < 5)?

The aesthetic is applied to the evaluated value.

ggplot(data = mpg) + geom_point(mapping = aes(x = displ, y = hwy, colour = displ < 5))

3.5.1 Exercises

1. What happens if you facet on a continuous variable?

There is one facet for each value e.g. a facet on displ.

ggplot(data = mpg) + 
  geom_point(mapping = aes(x = cyl, y = hwy)) +
  facet_wrap(~ displ)

2. What do the empty cells in plot with facet_grid(drv ~ cyl) mean? How do they relate to this plot?

The facets are empty when there is no data for the according combination e.g. rear wheel drive (r) with 4 or 5 cylinder is not listed. The 7 cylinder factes are missed entirely.

ggplot(data = mpg) + 
  geom_point(mapping = aes(x = displ, y = hwy)) +
  facet_grid(drv ~ cyl)

ggplot(data = mpg) + 
  geom_point(mapping = aes(x = drv, y = cyl))

3. What plots does the following code make? What does . do?

The “attribute ~ dot” notation plots the attribute values without a column attribute, thus showing multiple row-wise plots for each attribute value. The y-axis is repeated. With “dot ~ attribute” the row attribute is missing, thus showing column-wise the plots. Then the x-axis is repeated.

ggplot(data = mpg) + 
  geom_point(mapping = aes(x = displ, y = hwy)) +
  facet_grid(drv ~ .)

ggplot(data = mpg) + 
  geom_point(mapping = aes(x = displ, y = hwy)) +
  facet_grid(. ~ cyl)

4. Take the first faceted plot in this section. What are the advantages to using faceting instead of the colour aesthetic? What are the disadvantages? How might the balance change if you had a larger dataset?

With faceting it is easier to examine the indivual classes. With coloring it is easier to see how the classes are clustered overall. With larger datasets it’s more likely that you want to see the overall clustering instead of the individual point clouds.

ggplot(data = mpg) + 
  geom_point(mapping = aes(x = displ, y = hwy, color = class))

ggplot(data = mpg) + 
  geom_point(mapping = aes(x = displ, y = hwy)) + 
  facet_wrap(~ class, nrow = 2)

5. Read ?facet_wrap. What does nrow do? What does ncol do? What other options control the layout of the individual panels? Why doesn’t facet_grid() have nrow and ncol variables?

Facet grids do not have these configuration because the rows and cols are determined by the specified attributes.

?facet_wrap
#nrow, ncol:    Number of rows and columns.
#scales:    should Scales be fixed ("fixed", the default), free ("free"), or free in one dimension ("free_x", "free_y").
#shrink:    If TRUE, will shrink scales to fit output of statistics, not raw data. If FALSE, will be range of raw data before statistical summary.

6. When using facet_grid() you should usually put the variable with more unique levels in the columns. Why?

When putting the more levels on the row axis, then the y-axis would shrink so that it is harder to see which actual values are at the points as shown in the plot.

ggplot(data = mpg) + 
  geom_point(mapping = aes(x = displ, y = hwy)) + 
  facet_grid(class ~ drv)

3.6.1 Exercises

1. What geom would you use to draw a line chart? A boxplot? A histogram? An area chart?

ggplot(data = mpg) +
  geom_line(mapping = aes(x = displ, y = hwy)) +
  geom_point(mapping = aes(x = displ, y = hwy))

2. Run this code in your head and predict what the output will look like. Then, run the code in R and check your predictions.

ggplot(data = mpg, mapping = aes(x = displ, y = hwy, color = drv)) + 
  geom_point() + 
  geom_smooth(se = FALSE)

Didn’t expected that there would be multiple lines. Maybe because grouped by “color = drv”.

3. What does show.legend = FALSE do? What happens if you remove it? Why do you think I used it earlier in the chapter?

Actually, never used before, but in 3.9 coordinate systems.

4. What does the se argument to geom_smooth() do?

Shows the confidence interval around the line. (the grey area)

5. Will these two graphs look different? Why/why not?

No, because the layers inherit the configuration from ggplot.

ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) + 
  geom_point() + 
  geom_smooth()

ggplot() + 
  geom_point(data = mpg, mapping = aes(x = displ, y = hwy)) + 
  geom_smooth(data = mpg, mapping = aes(x = displ, y = hwy))

6. Recreate the R code necessary to generate the following graphs

Notice: These packages seem to erase the background.

#install.packages("gridExtra")
#install.packages("cowplot")
library(cowplot)

Attaching package: 㤼㸱cowplot㤼㸲

The following object is masked from 㤼㸱package:ggplot2㤼㸲:

    ggsave
p1 <- ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) + 
  geom_point() +
  geom_smooth(se = FALSE)
p2 <- ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) + 
  geom_point() +
  geom_smooth(mapping = aes(group = drv), se = FALSE)
p3 <- ggplot(data = mpg, mapping = aes(x = displ, y = hwy, color=drv)) + 
  geom_point() +
  geom_smooth(se = FALSE)
p4 <- ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) + 
  geom_point(mapping = aes(color=drv)) +
  geom_smooth(se = FALSE)
p5 <- ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) + 
  geom_point(mapping = aes(color=drv)) +
  geom_smooth(se = FALSE, mapping = aes(linetype = drv))
p6 <- ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) + 
  geom_point(mapping = aes(color=drv)) + 
  geom_point(shape = 21, color = "white", stroke = 1)
theme_set(theme_gray())
plot_grid(p1, p2, p3, p4, p5, p6, labels=c("1","2","3", "4","5","6"), ncol=2, nrow = 3)
`geom_smooth()` using method = 'loess'
`geom_smooth()` using method = 'loess'
`geom_smooth()` using method = 'loess'
`geom_smooth()` using method = 'loess'
`geom_smooth()` using method = 'loess'

ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) + 
  geom_point(mapping = aes(color=drv)) +
  geom_point(shape = 21, color = "white", stroke = 2)

LS0tDQp0aXRsZTogJ1IgZm9yIERhdGEgU2NpZW5jZTogRGF0YSB2aXN1YWxpc2F0aW9uJw0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOiBkZWZhdWx0DQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KLS0tDQoNCiMjIyAzLjIuNCBFeGVyY2lzZXMNCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpgYGANCg0KDQojIyMjIDEuIFJ1biBnZ3Bsb3QoZGF0YSA9IG1wZykgd2hhdCBkbyB5b3Ugc2VlPw0KDQpOb3RoaW5nIHBsb3R0ZWQsIGJ1dCBhIGNhbnZhcyBmb3IgYSBwbG90IGlzIHNob3duLg0KDQojIyMjIDIuIEhvdyBtYW55IHJvd3MgYXJlIGluIG10Y2Fycz8gSG93IG1hbnkgY29sdW1ucz8NCmBgYHtyfQ0KZGltKG10Y2FycykNCmBgYA0KDQojIyMjICAzLiBXaGF0IGRvZXMgdGhlIGRydiB2YXJpYWJsZSBkZXNjcmliZT8gUmVhZCB0aGUgaGVscCBmb3IgP21wZyB0byBmaW5kIG91dC4NCmBgYHtyfQ0KP21wZw0KIyBkcnYNCiMgZiA9IGZyb250LXdoZWVsIGRyaXZlLCByID0gcmVhciB3aGVlbCBkcml2ZSwgNCA9IDR3ZA0KYGBgDQoNCiMjIyMgNC4gTWFrZSBhIHNjYXR0ZXJwbG90IG9mIGh3eSB2cyBjeWwuDQpgYGB7cn0NCmdncGxvdChkYXRhID0gbXBnKSArIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gZGlzcGwsIHkgPSBod3kpKQ0KYGBgDQoNCiMjIyMgNS4gV2hhdCBoYXBwZW5zIGlmIHlvdSBtYWtlIGEgc2NhdHRlcnBsb3Qgb2YgY2xhc3MgdnMgZHJ2LiBXaHkgaXMgdGhlIHBsb3Qgbm90IHVzZWZ1bD8NCg0KVGhlIGNsYXNzIGFuZCBkcnYgYXR0cmlidXRlcyBhcmUgY2F0ZWdvcmljYWwuIFRoZXJlZm9yZSB0aGUgcGxvdCBzaG93cyB0aGUgbWFwcGluZyBiZXR3ZWVuIHRoZXNlIGNhdGVnb3JpZXMuDQoNCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBtcGcpICsgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSBjbGFzcywgeSA9IGRydikpDQpgYGANCg0KIyMjIDMuMy4xIEV4ZXJjaXNlcw0KIyMjIyAxLiBXaGF04oCZcyBnb25lIHdyb25nIHdpdGggdGhpcyBjb2RlPyBXaHkgYXJlIHRoZSBwb2ludHMgbm90IGJsdWU/DQoNCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBtcGcpICsgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSwgY29sb3IgPSAiYmx1ZSIpKQ0KYGBgDQoNClRoZSBwb2ludHMgYXJlIG5vdCBibHVlLCBiZWNhdXNlIHRoZSBjb2xvciBsYXllciBpcyBzcGVjaWZpZWQgd2l0aGluIHRoZSBhZXMgbWFwcGluZ3MuIFRodXMgdGhlIGZyYW1ld29yayB0cmllcyB0byBwbG90IHRoZSBjb2xvciBhZ2FpbnN0IGFuIGF0dHJpYnV0ZSAiYmx1ZSIsIGJ1dCB0aGlzIGRvZXMgbm90IGV4aXN0IHdpdGhpbiB0aGUgZGF0YS4gVGhlIGNvcnJlY3QgY29kZSB3b3VsZCBiZSB0byBzZXQgdGhlIGNvbG9yIG1hbnVhbGx5IGluIHRoZSBnZW9tX3BvaW50IG1ldGhvZC4NCg0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IG1wZykgKyBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IGRpc3BsLCB5ID0gaHd5KSwgY29sb3IgPSAiYmx1ZSIpDQpgYGANCg0KDQojIyMjIDIuIFdoaWNoIHZhcmlhYmxlcyBpbiBtcGcgYXJlIGNhdGVnb3JpY2FsPyBXaGljaCB2YXJpYWJsZXMgYXJlIGNvbnRpbnVvdXM/IChIaW50OiB0eXBlID9tcGcgdG8gcmVhZCB0aGUgZG9jdW1lbnRhdGlvbiBmb3IgdGhlIGRhdGFzZXQpLiBIb3cgY2FuIHlvdSBzZWUgdGhpcyBpbmZvcm1hdGlvbiB3aGVuIHlvdSBydW4gbXBnPw0KDQpUaGUgaW5mb3JtYXRpb24gaXMgc2hvd24gZGlyZWN0bHkgdW5kZXIgdGhlIGNvbHVtbiBuYW1lczogJmx0O2Nocj4gW2NoYXJhY3RlcnNdIGFyZSBsaWtlbHkgdG8gYmUgY2F0ZWdvcmljYWwsIHdoZXJlYXMgJmx0O2RibD4gW2RvdWJsZV0gYW5kICZsdDtpbnQ+IFtpbnRlZ2VyXSBhcmUgbGlrZWx5IHRvIGJlIGNvbnRpbnVvdXMuDQoNCmBgYHtyfQ0KaGVhZChtcGcsIDEpDQpgYGANCg0KIyMjIyAzLiBNYXAgYSBjb250aW51b3VzIHZhcmlhYmxlIHRvIGNvbG9yLCBzaXplLCBhbmQgc2hhcGUuIEhvdyBkbyB0aGVzZSBhZXN0aGV0aWNzIGJlaGF2ZSBkaWZmZXJlbnRseSBmb3IgY2F0ZWdvcmljYWwgdnMuIGNvbnRpbnVvdXMgdmFyaWFibGVzPw0KDQpGb3IgY29udGludW91cyB2YXJpYWJsZXMgYSBzY2FsZSBpcyBzaG93biwgb3RoZXJ3aXNlIHRoZSBjYXRlZ29yeSBuYW1lcy4NCg0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IG1wZykgKyBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IGRpc3BsLCB5ID0gaHd5LCBjb2xvciA9IGN5bCwgc2l6ZSA9IGh3eSwgc2hhcGUgPSBkcnYpKQ0KYGBgDQoNCg0KIyMjIyA0LiBXaGF0IGhhcHBlbnMgaWYgeW91IG1hcCB0aGUgc2FtZSB2YXJpYWJsZSB0byBtdWx0aXBsZSBhZXN0aGV0aWNzPw0KDQpTaW1wbHkgYm90aCBsYXllcnMgYXJlIGFwcGxpZWQuDQoNCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBtcGcpICsgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSwgY29sb3IgPSBjeWwsIHNpemUgPSBjeWwpKQ0KYGBgDQoNCiMjIyMgNS4gV2hhdCBkb2VzIHRoZSBzdHJva2UgYWVzdGhldGljIGRvPyBXaGF0IHNoYXBlcyBkb2VzIGl0IHdvcmsgd2l0aD8gKEhpbnQ6IHVzZSA/Z2VvbV9wb2ludCkNCg0KVGhlIHN0cm9rZSBhZXN0aGV0aWMgc2VlbXMgdG8gYWRqdXN0IHRoZSBwbG90dGVkIG9iamVjdCB0aGlja25lc3MuDQoNCiMjIyMgNi4gV2hhdCBoYXBwZW5zIGlmIHlvdSBtYXAgYW4gYWVzdGhldGljIHRvIHNvbWV0aGluZyBvdGhlciB0aGFuIGEgdmFyaWFibGUgbmFtZSwgbGlrZSBhZXMoY29sb3VyID0gZGlzcGwgPCA1KT8NCg0KVGhlIGFlc3RoZXRpYyBpcyBhcHBsaWVkIHRvIHRoZSBldmFsdWF0ZWQgdmFsdWUuDQoNCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBtcGcpICsgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSwgY29sb3VyID0gZGlzcGwgPCA1KSkNCmBgYA0KIyMjIDMuNS4xIEV4ZXJjaXNlcw0KDQojIyMjIDEuIFdoYXQgaGFwcGVucyBpZiB5b3UgZmFjZXQgb24gYSBjb250aW51b3VzIHZhcmlhYmxlPw0KDQpUaGVyZSBpcyBvbmUgZmFjZXQgZm9yIGVhY2ggdmFsdWUgZS5nLiBhIGZhY2V0IG9uIGRpc3BsLg0KDQpgYGB7cn0NCmdncGxvdChkYXRhID0gbXBnKSArIA0KICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IGN5bCwgeSA9IGh3eSkpICsNCiAgZmFjZXRfd3JhcCh+IGRpc3BsKQ0KYGBgDQoNCg0KIyMjIyAyLiBXaGF0IGRvIHRoZSBlbXB0eSBjZWxscyBpbiBwbG90IHdpdGggZmFjZXRfZ3JpZChkcnYgfiBjeWwpIG1lYW4/IEhvdyBkbyB0aGV5IHJlbGF0ZSB0byB0aGlzIHBsb3Q/DQoNClRoZSBmYWNldHMgYXJlIGVtcHR5IHdoZW4gdGhlcmUgaXMgbm8gZGF0YSBmb3IgdGhlIGFjY29yZGluZyBjb21iaW5hdGlvbiBlLmcuIHJlYXIgd2hlZWwgZHJpdmUgKHIpIHdpdGggNCBvciA1IGN5bGluZGVyIGlzIG5vdCBsaXN0ZWQuIFRoZSA3IGN5bGluZGVyIGZhY3RlcyBhcmUgbWlzc2VkIGVudGlyZWx5Lg0KDQpgYGB7cn0NCmdncGxvdChkYXRhID0gbXBnKSArIA0KICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IGRpc3BsLCB5ID0gaHd5KSkgKw0KICBmYWNldF9ncmlkKGRydiB+IGN5bCkNCmBgYA0KDQoNCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBtcGcpICsgDQogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gZHJ2LCB5ID0gY3lsKSkNCmBgYA0KDQoNCiMjIyMgMy4gV2hhdCBwbG90cyBkb2VzIHRoZSBmb2xsb3dpbmcgY29kZSBtYWtlPyBXaGF0IGRvZXMgLiBkbz8NCg0KVGhlICJhdHRyaWJ1dGUgfiBkb3QiIG5vdGF0aW9uIHBsb3RzIHRoZSBhdHRyaWJ1dGUgdmFsdWVzIHdpdGhvdXQgYSBjb2x1bW4gYXR0cmlidXRlLCB0aHVzIHNob3dpbmcgbXVsdGlwbGUgcm93LXdpc2UgcGxvdHMgZm9yIGVhY2ggYXR0cmlidXRlIHZhbHVlLiBUaGUgeS1heGlzIGlzIHJlcGVhdGVkLiBXaXRoICJkb3QgfiBhdHRyaWJ1dGUiIHRoZSByb3cgYXR0cmlidXRlIGlzIG1pc3NpbmcsIHRodXMgc2hvd2luZyBjb2x1bW4td2lzZSB0aGUgcGxvdHMuIFRoZW4gdGhlIHgtYXhpcyBpcyByZXBlYXRlZC4NCg0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IG1wZykgKyANCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSkpICsNCiAgZmFjZXRfZ3JpZChkcnYgfiAuKQ0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBtcGcpICsgDQogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gZGlzcGwsIHkgPSBod3kpKSArDQogIGZhY2V0X2dyaWQoLiB+IGN5bCkNCmBgYA0KDQojIyMjIDQuIFRha2UgdGhlIGZpcnN0IGZhY2V0ZWQgcGxvdCBpbiB0aGlzIHNlY3Rpb24uIFdoYXQgYXJlIHRoZSBhZHZhbnRhZ2VzIHRvIHVzaW5nIGZhY2V0aW5nIGluc3RlYWQgb2YgdGhlIGNvbG91ciBhZXN0aGV0aWM/IFdoYXQgYXJlIHRoZSBkaXNhZHZhbnRhZ2VzPyBIb3cgbWlnaHQgdGhlIGJhbGFuY2UgY2hhbmdlIGlmIHlvdSBoYWQgYSBsYXJnZXIgZGF0YXNldD8NCg0KV2l0aCBmYWNldGluZyBpdCBpcyBlYXNpZXIgdG8gZXhhbWluZSB0aGUgaW5kaXZ1YWwgY2xhc3Nlcy4gV2l0aCBjb2xvcmluZyBpdCBpcyBlYXNpZXIgdG8gc2VlIGhvdyB0aGUgY2xhc3NlcyBhcmUgY2x1c3RlcmVkIG92ZXJhbGwuIFdpdGggbGFyZ2VyIGRhdGFzZXRzIGl0J3MgbW9yZSBsaWtlbHkgdGhhdCB5b3Ugd2FudCB0byBzZWUgdGhlIG92ZXJhbGwgY2x1c3RlcmluZyBpbnN0ZWFkIG9mIHRoZSBpbmRpdmlkdWFsIHBvaW50IGNsb3Vkcy4NCg0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IG1wZykgKyANCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSwgY29sb3IgPSBjbGFzcykpDQpgYGANCg0KDQpgYGB7cn0NCmdncGxvdChkYXRhID0gbXBnKSArIA0KICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IGRpc3BsLCB5ID0gaHd5KSkgKyANCiAgZmFjZXRfd3JhcCh+IGNsYXNzLCBucm93ID0gMikNCmBgYA0KDQojIyMjIDUuIFJlYWQgP2ZhY2V0X3dyYXAuIFdoYXQgZG9lcyBucm93IGRvPyBXaGF0IGRvZXMgbmNvbCBkbz8gV2hhdCBvdGhlciBvcHRpb25zIGNvbnRyb2wgdGhlIGxheW91dCBvZiB0aGUgaW5kaXZpZHVhbCBwYW5lbHM/IFdoeSBkb2VzbuKAmXQgZmFjZXRfZ3JpZCgpIGhhdmUgbnJvdyBhbmQgbmNvbCB2YXJpYWJsZXM/DQoNCkZhY2V0IGdyaWRzIGRvIG5vdCBoYXZlIHRoZXNlIGNvbmZpZ3VyYXRpb24gYmVjYXVzZSB0aGUgcm93cyBhbmQgY29scyBhcmUgZGV0ZXJtaW5lZCBieSB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZXMuDQoNCmBgYHtyfQ0KP2ZhY2V0X3dyYXANCiNucm93LCBuY29sOglOdW1iZXIgb2Ygcm93cyBhbmQgY29sdW1ucy4NCiNzY2FsZXM6CXNob3VsZCBTY2FsZXMgYmUgZml4ZWQgKCJmaXhlZCIsIHRoZSBkZWZhdWx0KSwgZnJlZSAoImZyZWUiKSwgb3IgZnJlZSBpbiBvbmUgZGltZW5zaW9uICgiZnJlZV94IiwgImZyZWVfeSIpLg0KI3NocmluazoJSWYgVFJVRSwgd2lsbCBzaHJpbmsgc2NhbGVzIHRvIGZpdCBvdXRwdXQgb2Ygc3RhdGlzdGljcywgbm90IHJhdyBkYXRhLiBJZiBGQUxTRSwgd2lsbCBiZSByYW5nZSBvZiByYXcgZGF0YSBiZWZvcmUgc3RhdGlzdGljYWwgc3VtbWFyeS4NCmBgYA0KDQoNCiMjIyMgNi4gV2hlbiB1c2luZyBmYWNldF9ncmlkKCkgeW91IHNob3VsZCB1c3VhbGx5IHB1dCB0aGUgdmFyaWFibGUgd2l0aCBtb3JlIHVuaXF1ZSBsZXZlbHMgaW4gdGhlIGNvbHVtbnMuIFdoeT8NCg0KV2hlbiBwdXR0aW5nIHRoZSBtb3JlIGxldmVscyBvbiB0aGUgcm93IGF4aXMsIHRoZW4gdGhlIHktYXhpcyB3b3VsZCBzaHJpbmsgc28gdGhhdCBpdCBpcyBoYXJkZXIgdG8gc2VlIHdoaWNoIGFjdHVhbCB2YWx1ZXMgYXJlIGF0IHRoZSBwb2ludHMgYXMgc2hvd24gaW4gdGhlIHBsb3QuDQoNCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBtcGcpICsgDQogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gZGlzcGwsIHkgPSBod3kpKSArIA0KICBmYWNldF9ncmlkKGNsYXNzIH4gZHJ2KQ0KYGBgDQoNCiMjIyAzLjYuMSBFeGVyY2lzZXMNCg0KIyMjIyAxLiBXaGF0IGdlb20gd291bGQgeW91IHVzZSB0byBkcmF3IGEgbGluZSBjaGFydD8gQSBib3hwbG90PyBBIGhpc3RvZ3JhbT8gQW4gYXJlYSBjaGFydD8NCg0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IG1wZykgKw0KICBnZW9tX2xpbmUobWFwcGluZyA9IGFlcyh4ID0gZGlzcGwsIHkgPSBod3kpKSArDQogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gZGlzcGwsIHkgPSBod3kpKQ0KYGBgDQoNCg0KIyMjIyAyLiBSdW4gdGhpcyBjb2RlIGluIHlvdXIgaGVhZCBhbmQgcHJlZGljdCB3aGF0IHRoZSBvdXRwdXQgd2lsbCBsb29rIGxpa2UuIFRoZW4sIHJ1biB0aGUgY29kZSBpbiBSIGFuZCBjaGVjayB5b3VyIHByZWRpY3Rpb25zLg0KDQpgYGB7cn0NCmdncGxvdChkYXRhID0gbXBnLCBtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSwgY29sb3IgPSBkcnYpKSArIA0KICBnZW9tX3BvaW50KCkgKyANCiAgZ2VvbV9zbW9vdGgoc2UgPSBGQUxTRSkNCmBgYA0KDQpEaWRuJ3QgZXhwZWN0ZWQgdGhhdCB0aGVyZSB3b3VsZCBiZSBtdWx0aXBsZSBsaW5lcy4gTWF5YmUgYmVjYXVzZSBncm91cGVkIGJ5ICJjb2xvciA9IGRydiIuDQoNCiMjIyMgMy4gV2hhdCBkb2VzIHNob3cubGVnZW5kID0gRkFMU0UgZG8/IFdoYXQgaGFwcGVucyBpZiB5b3UgcmVtb3ZlIGl0PyBXaHkgZG8geW91IHRoaW5rIEkgdXNlZCBpdCBlYXJsaWVyIGluIHRoZSBjaGFwdGVyPw0KDQpBY3R1YWxseSwgbmV2ZXIgdXNlZCBiZWZvcmUsIGJ1dCBpbiAzLjkgY29vcmRpbmF0ZSBzeXN0ZW1zLg0KDQojIyMjIDQuIFdoYXQgZG9lcyB0aGUgc2UgYXJndW1lbnQgdG8gZ2VvbV9zbW9vdGgoKSBkbz8NCg0KU2hvd3MgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgYXJvdW5kIHRoZSBsaW5lLiAodGhlIGdyZXkgYXJlYSkNCg0KIyMjIyA1LiBXaWxsIHRoZXNlIHR3byBncmFwaHMgbG9vayBkaWZmZXJlbnQ/IFdoeS93aHkgbm90Pw0KDQpObywgYmVjYXVzZSB0aGUgbGF5ZXJzIGluaGVyaXQgdGhlIGNvbmZpZ3VyYXRpb24gZnJvbSBnZ3Bsb3QuDQoNCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBtcGcsIG1hcHBpbmcgPSBhZXMoeCA9IGRpc3BsLCB5ID0gaHd5KSkgKyANCiAgZ2VvbV9wb2ludCgpICsgDQogIGdlb21fc21vb3RoKCkNCmBgYA0KDQpgYGB7cn0NCmdncGxvdCgpICsgDQogIGdlb21fcG9pbnQoZGF0YSA9IG1wZywgbWFwcGluZyA9IGFlcyh4ID0gZGlzcGwsIHkgPSBod3kpKSArIA0KICBnZW9tX3Ntb290aChkYXRhID0gbXBnLCBtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSkpDQpgYGANCg0KIyMjIyA2LiBSZWNyZWF0ZSB0aGUgUiBjb2RlIG5lY2Vzc2FyeSB0byBnZW5lcmF0ZSB0aGUgZm9sbG93aW5nIGdyYXBocw0KDQpOb3RpY2U6IFRoZXNlIHBhY2thZ2VzIHNlZW0gdG8gZXJhc2UgdGhlIGJhY2tncm91bmQuIA0KDQpgYGB7cn0NCiNpbnN0YWxsLnBhY2thZ2VzKCJncmlkRXh0cmEiKQ0KI2luc3RhbGwucGFja2FnZXMoImNvd3Bsb3QiKQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShjb3dwbG90KQ0KcDEgPC0gZ2dwbG90KGRhdGEgPSBtcGcsIG1hcHBpbmcgPSBhZXMoeCA9IGRpc3BsLCB5ID0gaHd5KSkgKyANCiAgZ2VvbV9wb2ludCgpICsNCiAgZ2VvbV9zbW9vdGgoc2UgPSBGQUxTRSkNCg0KcDIgPC0gZ2dwbG90KGRhdGEgPSBtcGcsIG1hcHBpbmcgPSBhZXMoeCA9IGRpc3BsLCB5ID0gaHd5KSkgKyANCiAgZ2VvbV9wb2ludCgpICsNCiAgZ2VvbV9zbW9vdGgobWFwcGluZyA9IGFlcyhncm91cCA9IGRydiksIHNlID0gRkFMU0UpDQoNCnAzIDwtIGdncGxvdChkYXRhID0gbXBnLCBtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSwgY29sb3I9ZHJ2KSkgKyANCiAgZ2VvbV9wb2ludCgpICsNCiAgZ2VvbV9zbW9vdGgoc2UgPSBGQUxTRSkNCg0KcDQgPC0gZ2dwbG90KGRhdGEgPSBtcGcsIG1hcHBpbmcgPSBhZXMoeCA9IGRpc3BsLCB5ID0gaHd5KSkgKyANCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKGNvbG9yPWRydikpICsNCiAgZ2VvbV9zbW9vdGgoc2UgPSBGQUxTRSkNCg0KcDUgPC0gZ2dwbG90KGRhdGEgPSBtcGcsIG1hcHBpbmcgPSBhZXMoeCA9IGRpc3BsLCB5ID0gaHd5KSkgKyANCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKGNvbG9yPWRydikpICsNCiAgZ2VvbV9zbW9vdGgoc2UgPSBGQUxTRSwgbWFwcGluZyA9IGFlcyhsaW5ldHlwZSA9IGRydikpDQoNCnA2IDwtIGdncGxvdChkYXRhID0gbXBnLCBtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSkpICsgDQogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyhjb2xvcj1kcnYpKSArIA0KICBnZW9tX3BvaW50KHNoYXBlID0gMjEsIGNvbG9yID0gIndoaXRlIiwgc3Ryb2tlID0gMSkNCg0KdGhlbWVfc2V0KHRoZW1lX2dyYXkoKSkNCnBsb3RfZ3JpZChwMSwgcDIsIHAzLCBwNCwgcDUsIHA2LCBsYWJlbHM9YygiMSIsIjIiLCIzIiwgIjQiLCI1IiwiNiIpLCBuY29sPTIsIG5yb3cgPSAzKQ0KYGBgDQoNCg0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IG1wZywgbWFwcGluZyA9IGFlcyh4ID0gZGlzcGwsIHkgPSBod3kpKSArIA0KICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoY29sb3I9ZHJ2KSkgKw0KICBnZW9tX3BvaW50KHNoYXBlID0gMjEsIGNvbG9yID0gIndoaXRlIiwgc3Ryb2tlID0gMikNCmBgYA0KDQo=