rm(list=ls()) install.packages(“ggplot2”, dependencies = TRUE) install.packages(“cli”, type=“binary”) library(ggplot2)

scatter plot ——————————————————————

ggplot(iris) +
  aes(Sepal.Length, Sepal.Width) +
  geom_point(color = "red", size = 1)

same action

ggplot(iris, aes(Sepal.Length, Sepal.Width)) + geom_point(color = “red”, size = 1) ggplot(iris) + geom_point(aes(Sepal.Length, Sepal.Width), color = “red”, size = 1) ggplot + geom_point(data = iris, aes(Sepal.Length, Sepal.Width), color = “red”, size = 1)

p <- ggplot(iris) + aes(Sepal.Length, Sepal.Width) p + geom_point(color = “red”, size = 1) + geom_point(data=, aes()) # also possible this way

Designate a group variable —————————————————

ggplot(iris) +
  aes(Sepal.Length, Sepal.Width, color=Species) +
  geom_point(size = 1)

# x limitation
ggplot(iris) +
  aes(Sepal.Length, Sepal.Width, color=Species) +
  geom_point(position = "jitter", alpha = 0.4) + 
  xlim(5,7)

Bar plot ———————————————————————-

?economics
data(economics)
str(economics)
spec_tbl_df [574 × 6] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
 $ date    : Date[1:574], format: "1967-07-01" "1967-08-01" "1967-09-01" ...
 $ pce     : num [1:574] 507 510 516 512 517 ...
 $ pop     : num [1:574] 198712 198911 199113 199311 199498 ...
 $ psavert : num [1:574] 12.6 12.6 11.9 12.9 12.8 11.8 11.7 12.3 11.7 12.3 ...
 $ uempmed : num [1:574] 4.5 4.7 4.6 4.9 4.7 4.8 5.1 4.5 4.1 4.6 ...
 $ unemploy: num [1:574] 2944 2945 2958 3143 3066 ...
ggplot(economics) +
  aes(date, unemploy) +
  geom_line() ->abs

ggplot(economics) +
  aes(date, unemploy/pop) +
  geom_line() ->rel

plot_grid(abs, rel, labels = c("abs", "rel"))

#specific year
ggplot(economics) +
  aes(date, unemploy/pop) +
  geom_line() + 
  xlim(as.Date("1967-07-01"), as.Date("1977-07-01"))

#ggplot step
ggplot(economics) +
  aes(date, unemploy/pop) +
  geom_step() + 
  xlim(as.Date("1967-07-01"), as.Date("1977-07-01"))

Practice the commend structure ————————————————


ggplot(economics) +
  aes(date, unemploy/pop) +
  geom_line() + 
  xlim(as.Date("1967-07-01"), as.Date("1977-07-01"))

# when filter situation put more option ; apply aes more
ggplot(economics) +
  aes(date, unemploy/pop) +
  geom_point(size=1) +
  xlim(as.Date("1967-07-01"), as.Date("1977-07-01")) -> def

ggplot(economics, aes(date, unemploy/pop)) +
  geom_point(size=1) +
  geom_line() +
  xlim(as.Date("1967-07-01"), as.Date("1977-07-01")) -> apl
  
plot_grid(def, apl, labels = c("def", "apl"))  
Warning: Removed 453 rows containing missing values (geom_point).Warning: Removed 453 rows containing missing values (geom_point).Warning: Removed 453 row(s) containing missing values (geom_path).

# when aes() and geom_object are designated seperatly  
ggplot(iris) +
  geom_point(aes(Sepal.Length, Sepal.Width), color = "red") +
  geom_point(aes(Sepal.Length, Petal.Length), color = "blue")  

# more grom_object  
ggplot(mpg) + aes(hwy) +geom_bar() -> bar
ggplot(mpg) + aes(hwy) +geom_histogram() -> hist
p <- ggplot(mpg) + aes(hwy) 
p + geom_dotplot() -> dot
p + geom_density() -> den
p + geom_freqpoly() -> fre
plot_grid(bar, hist, dot, den, fre, labels = c("AUTO")) 
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Bin width defaults to 1/30 of the range of the data. Pick better value with `binwidth`.
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

# depends on the class
ggplot(mpg) + aes(hwy, fill = class) -> p
p + geom_bar() -> bar
p + geom_histogram() -> hist
p + geom_dotplot() -> dot
p + geom_density() -> den
# p + geom_freqpoly() -> fre ; has to use to color
ggplot(mpg) + aes(hwy, color = class) + geom_freqpoly() -> fre
plot_grid(bar, hist, dot, den, fre, labels = c("AUTO")) 
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Bin width defaults to 1/30 of the range of the data. Pick better value with `binwidth`.
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

geom_histogram() ————————————————————–

data(mtcars)
head(mtcars)
?mtcars

ggplot(mtcars) + 
  aes(mpg) +
  geom_histogram(bineidth=1) -> width
Warning: Ignoring unknown parameters: bineidth
ggplot(mtcars) + 
  aes(mpg) +
  geom_histogram(bins=10) -> bins

plot_grid(width, bins, labels = c("width", "bins")) 
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

ggplot(mpg) + aes(hwy) + geom_histogram() -> a
ggplot(mpg) + aes(hwy) + geom_histogram(bins = 10, color = "white", fill = "navy") -> b

plot_grid(a, b, labels = c("width", "bins")) 
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

geom_bar() ——————————————————————–

ggplot(mpg) + aes(hwy, fill = class) + geom_bar() -> stack
ggplot(mpg) + aes(hwy, fill = class) + geom_bar(position="dodge") -> dodge
ggplot(mpg) + aes(hwy, fill = class) + geom_bar(position="fill") -> fill


plot_grid(stack, dodge, fill, labels = c("stack", "dodge", "fill")) 

geom_density() —————————————————————-

ggplot(mpg) + aes(hwy, fill = class) + geom_density() -> a 
ggplot(mpg) + aes(hwy, fill = class) + geom_density(alpha=0.5) -> b 

plot_grid(a, b, labels = "AUTO") 

geom_dotplot() —————————————————————-

ggplot(iris) + aes(Sepal.Length) + geom_dotplot() -> a
ggplot(iris) + aes(Sepal.Length) + geom_dotplot(binwidth = 0.1) -> c 
ggplot(iris) + aes(Sepal.Length) + geom_dotplot(binwidth = 0.1, stackdir = "centerwhole") -> d 
ggplot(iris) + aes(Species, Sepal.Length) + geom_dotplot(binaxis = "y") -> e
ggplot(iris) + aes(Species, Sepal.Length) + geom_dotplot(binaxis = "y", stackdir = "centerwhole") -> f
ggplot(iris) + aes(Species, Sepal.Length, fill = Species) + geom_dotplot(binaxis = "y", stackdir = "centerwhole") -> g

plot_grid(a, c, d, e, f, g, labels = "AUTO") 
Bin width defaults to 1/30 of the range of the data. Pick better value with `binwidth`.
Bin width defaults to 1/30 of the range of the data. Pick better value with `binwidth`.
Bin width defaults to 1/30 of the range of the data. Pick better value with `binwidth`.
Bin width defaults to 1/30 of the range of the data. Pick better value with `binwidth`.

geom_violin() —————————————————————-

ggplot(iris) + aes(Species, Sepal.Length) + geom_violin() -> a 
ggplot(iris) + aes(Species, Sepal.Length) +  geom_violin() + geom_dotplot(aes(fill = Species), binaxis = "y", stackdir = "centerwhole") -> b 

plot_grid(a, b, labels = "AUTO") 
Bin width defaults to 1/30 of the range of the data. Pick better value with `binwidth`.

geom_jitter() —————————————————————–

ggplot(iris) + 
  aes(Species, Sepal.Length, color = Species) + 
  geom_point() -> a 

ggplot(iris) + 
  aes(Species, Sepal.Length, color = Species) + 
  geom_jitter() -> b 

ggplot(iris) + 
  aes(Species, Sepal.Length, color = Species) + 
  geom_jitter(width = 0.25, alpha = 0.5) -> c

plot_grid(a, b, c, labels = "AUTO") 

geom_boxplot() —————————————————————–

ggplot(iris) + 
  aes(Species, Sepal.Length, color = Species) + 
  geom_boxplot() -> a 

ggplot(iris) + 
  aes(Species, Sepal.Length, fill = Species) + 
  geom_boxplot() -> a 

plot_grid(a, b, labels = "AUTO") 

LS0tCnRpdGxlOiAiQ2hhcHRlci4zLTIiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCnJtKGxpc3Q9bHMoKSkKaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIsIGRlcGVuZGVuY2llcyA9IFRSVUUpCmluc3RhbGwucGFja2FnZXMoImNsaSIsIHR5cGU9ImJpbmFyeSIpCmxpYnJhcnkoZ2dwbG90MikKCiMgc2NhdHRlciBwbG90IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpgYGB7cn0KZ2dwbG90KGlyaXMpICsKICBhZXMoU2VwYWwuTGVuZ3RoLCBTZXBhbC5XaWR0aCkgKwogIGdlb21fcG9pbnQoY29sb3IgPSAicmVkIiwgc2l6ZSA9IDEpCmBgYAoKIyBzYW1lIGFjdGlvbgpnZ3Bsb3QoaXJpcywgYWVzKFNlcGFsLkxlbmd0aCwgU2VwYWwuV2lkdGgpKSArIGdlb21fcG9pbnQoY29sb3IgPSAicmVkIiwgc2l6ZSA9IDEpCmdncGxvdChpcmlzKSArIGdlb21fcG9pbnQoYWVzKFNlcGFsLkxlbmd0aCwgU2VwYWwuV2lkdGgpLCBjb2xvciA9ICJyZWQiLCBzaXplID0gMSkKZ2dwbG90ICsgZ2VvbV9wb2ludChkYXRhID0gaXJpcywgYWVzKFNlcGFsLkxlbmd0aCwgU2VwYWwuV2lkdGgpLCBjb2xvciA9ICJyZWQiLCBzaXplID0gMSkKCnAgPC0gZ2dwbG90KGlyaXMpICsgYWVzKFNlcGFsLkxlbmd0aCwgU2VwYWwuV2lkdGgpCnAgKyBnZW9tX3BvaW50KGNvbG9yID0gInJlZCIsIHNpemUgPSAxKSArIGdlb21fcG9pbnQoZGF0YT0sIGFlcygpKSAjIGFsc28gcG9zc2libGUgdGhpcyB3YXkKCgojIERlc2lnbmF0ZSBhIGdyb3VwIHZhcmlhYmxlICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KYGBge3J9CmdncGxvdChpcmlzKSArCiAgYWVzKFNlcGFsLkxlbmd0aCwgU2VwYWwuV2lkdGgsIGNvbG9yPVNwZWNpZXMpICsKICBnZW9tX3BvaW50KHNpemUgPSAxKQpgYGAKYGBge3J9CiMgaml0dGVyIDsgcmFtZG9tCmdncGxvdChpcmlzKSArCiAgYWVzKFNlcGFsLkxlbmd0aCwgU2VwYWwuV2lkdGgsIGNvbG9yPVNwZWNpZXMpICsKICBnZW9tX3BvaW50KHBvc2l0aW9uID0gImppdHRlciIsIGFscGhhID0gMC41KQpgYGAKCmBgYHtyfQojIHggbGltaXRhdGlvbgpnZ3Bsb3QoaXJpcykgKwogIGFlcyhTZXBhbC5MZW5ndGgsIFNlcGFsLldpZHRoLCBjb2xvcj1TcGVjaWVzKSArCiAgZ2VvbV9wb2ludChwb3NpdGlvbiA9ICJqaXR0ZXIiLCBhbHBoYSA9IDAuNCkgKyAKICB4bGltKDUsNykKYGBgCgojIEJhciBwbG90IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KYGBge3J9CmdncGxvdChtcGcpICsKICBhZXMoY2xhc3MpICsKICBnZW9tX2JhcigpCmBgYAoKYGBge3IsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTV9CiNpbnN0YWxsLnBhY2thZ2VzKCJjb3dwbG90IiwgZGVwZW5kZW5jaWVzID0gVFJVRSkKbGlicmFyeShjb3dwbG90KQojcGFyKG1mcm93ID0gYygxLCAyKSkKY29sb3IgPC0gZ2dwbG90KG1wZykgKwogIGFlcyhjbGFzcywgY29sb3IgPSBjbGFzcykgKwogIGdlb21fYmFyKCkKIyBiYXIgY29sb3IgY2hhbmdlIChub3QgdGhlIGJhciBsaW5lKQpmaWxsIDwtIGdncGxvdChtcGcpICsKICBhZXMoY2xhc3MsIGZpbGwgPSBjbGFzcykgKwogIGdlb21fYmFyKCkKcGxvdF9ncmlkKGNvbG9yLCBmaWxsLCBsYWJlbHMgPSBjKCJjb2xvciIsICJmaWxsIikpCmBgYAoKYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKI3JlYWR5IHRvIGF2ZXJhZ2UgIApzdW0gPC0gZ2dwbG90KG1wZykgKwogIGFlcyhjbGFzcywgZGlzcGwpICsKICBnZW9tX2NvbCgpICNzdW0KCiNpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIsIGRlcGVuZGVuY2llcyA9IFRSVUUpCmxpYnJhcnkoZHBseXIpCm1wZyAlPiUgCiAgZ3JvdXBfYnkoY2xhc3MpICU+JSAKICBzdW1tYXJpc2UobWVhbl9kaXNwbCA9IG1lYW4oZGlzcGwpKSAtPiBkZgoKYXZnIDwtIGdncGxvdChkZikgKwogIGFlcyhjbGFzcywgbWVhbl9kaXNwbCkgKwogIGdlb21fY29sKCkKCnBsb3RfZ3JpZChzdW0sIGF2ZywgbGFiZWxzID0gYygic3VtIiwgImF2ZyIpKQpgYGAKCmBgYHtyfQo/ZWNvbm9taWNzCmRhdGEoZWNvbm9taWNzKQpzdHIoZWNvbm9taWNzKQoKZ2dwbG90KGVjb25vbWljcykgKwogIGFlcyhkYXRlLCB1bmVtcGxveSkgKwogIGdlb21fbGluZSgpIC0+YWJzCgpnZ3Bsb3QoZWNvbm9taWNzKSArCiAgYWVzKGRhdGUsIHVuZW1wbG95L3BvcCkgKwogIGdlb21fbGluZSgpIC0+cmVsCgpwbG90X2dyaWQoYWJzLCByZWwsIGxhYmVscyA9IGMoImFicyIsICJyZWwiKSkKYGBgCgpgYGB7cn0KI3NwZWNpZmljIHllYXIKZ2dwbG90KGVjb25vbWljcykgKwogIGFlcyhkYXRlLCB1bmVtcGxveS9wb3ApICsKICBnZW9tX2xpbmUoKSArIAogIHhsaW0oYXMuRGF0ZSgiMTk2Ny0wNy0wMSIpLCBhcy5EYXRlKCIxOTc3LTA3LTAxIikpCmBgYAoKYGBge3J9CiNnZ3Bsb3Qgc3RlcApnZ3Bsb3QoZWNvbm9taWNzKSArCiAgYWVzKGRhdGUsIHVuZW1wbG95L3BvcCkgKwogIGdlb21fc3RlcCgpICsgCiAgeGxpbShhcy5EYXRlKCIxOTY3LTA3LTAxIiksIGFzLkRhdGUoIjE5NzctMDctMDEiKSkKYGBgCgojIFByYWN0aWNlIHRoZSBjb21tZW5kIHN0cnVjdHVyZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KYGBge3J9CmdncGxvdChlY29ub21pY3MpICsKICBhZXMoZGF0ZSwgdW5lbXBsb3kvcG9wKSArCiAgZ2VvbV9saW5lKCkgKyAKICB4bGltKGFzLkRhdGUoIjE5NjctMDctMDEiKSwgYXMuRGF0ZSgiMTk3Ny0wNy0wMSIpKQpgYGAKCmBgYHtyfQojIHdoZW4gZmlsdGVyIHNpdHVhdGlvbiBwdXQgbW9yZSBvcHRpb24gOyBhcHBseSBhZXMgbW9yZQpnZ3Bsb3QoZWNvbm9taWNzKSArCiAgYWVzKGRhdGUsIHVuZW1wbG95L3BvcCkgKwogIGdlb21fcG9pbnQoc2l6ZT0xKSArCiAgeGxpbShhcy5EYXRlKCIxOTY3LTA3LTAxIiksIGFzLkRhdGUoIjE5NzctMDctMDEiKSkgLT4gZGVmCgpnZ3Bsb3QoZWNvbm9taWNzLCBhZXMoZGF0ZSwgdW5lbXBsb3kvcG9wKSkgKwogIGdlb21fcG9pbnQoc2l6ZT0xKSArCiAgZ2VvbV9saW5lKCkgKwogIHhsaW0oYXMuRGF0ZSgiMTk2Ny0wNy0wMSIpLCBhcy5EYXRlKCIxOTc3LTA3LTAxIikpIC0+IGFwbAogIApwbG90X2dyaWQoZGVmLCBhcGwsIGxhYmVscyA9IGMoImRlZiIsICJhcGwiKSkgIApgYGAKCmBgYHtyfQojIHdoZW4gYWVzKCkgYW5kIGdlb21fb2JqZWN0IGFyZSBkZXNpZ25hdGVkIHNlcGVyYXRseSAgCmdncGxvdChpcmlzKSArCiAgZ2VvbV9wb2ludChhZXMoU2VwYWwuTGVuZ3RoLCBTZXBhbC5XaWR0aCksIGNvbG9yID0gInJlZCIpICsKICBnZW9tX3BvaW50KGFlcyhTZXBhbC5MZW5ndGgsIFBldGFsLkxlbmd0aCksIGNvbG9yID0gImJsdWUiKSAgCmBgYAoKYGBge3J9CiMgbW9yZSBnZW9tX29iamVjdCAgCmdncGxvdChtcGcpICsgYWVzKGh3eSkgKyBnZW9tX2JhcigpIC0+IGJhcgpnZ3Bsb3QobXBnKSArIGFlcyhod3kpICsgZ2VvbV9oaXN0b2dyYW0oKSAtPiBoaXN0CnAgPC0gZ2dwbG90KG1wZykgKyBhZXMoaHd5KSAKcCArIGdlb21fZG90cGxvdCgpIC0+IGRvdApwICsgZ2VvbV9kZW5zaXR5KCkgLT4gZGVuCnAgKyBnZW9tX2ZyZXFwb2x5KCkgLT4gZnJlCnBsb3RfZ3JpZChiYXIsIGhpc3QsIGRvdCwgZGVuLCBmcmUsIGxhYmVscyA9IGMoIkFVVE8iKSkgCmBgYAoKYGBge3J9CiMgZGVwZW5kcyBvbiB0aGUgY2xhc3MKZ2dwbG90KG1wZykgKyBhZXMoaHd5LCBmaWxsID0gY2xhc3MpIC0+IHAKcCArIGdlb21fYmFyKCkgLT4gYmFyCnAgKyBnZW9tX2hpc3RvZ3JhbSgpIC0+IGhpc3QKcCArIGdlb21fZG90cGxvdCgpIC0+IGRvdApwICsgZ2VvbV9kZW5zaXR5KCkgLT4gZGVuCiMgcCArIGdlb21fZnJlcXBvbHkoKSAtPiBmcmUgOyBoYXMgdG8gdXNlIHRvIGNvbG9yCmdncGxvdChtcGcpICsgYWVzKGh3eSwgY29sb3IgPSBjbGFzcykgKyBnZW9tX2ZyZXFwb2x5KCkgLT4gZnJlCnBsb3RfZ3JpZChiYXIsIGhpc3QsIGRvdCwgZGVuLCBmcmUsIGxhYmVscyA9IGMoIkFVVE8iKSkgCmBgYAoKIyBnZW9tX2hpc3RvZ3JhbSgpIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmBgYHtyfQpkYXRhKG10Y2FycykKaGVhZChtdGNhcnMpCj9tdGNhcnMKCmdncGxvdChtdGNhcnMpICsgCiAgYWVzKG1wZykgKwogIGdlb21faGlzdG9ncmFtKGJpbmVpZHRoPTEpIC0+IHdpZHRoCgpnZ3Bsb3QobXRjYXJzKSArIAogIGFlcyhtcGcpICsKICBnZW9tX2hpc3RvZ3JhbShiaW5zPTEwKSAtPiBiaW5zCgpwbG90X2dyaWQod2lkdGgsIGJpbnMsIGxhYmVscyA9IGMoIndpZHRoIiwgImJpbnMiKSkgCmBgYAoKYGBge3J9CmdncGxvdChtcGcpICsgYWVzKGh3eSkgKyBnZW9tX2hpc3RvZ3JhbSgpIC0+IGEKZ2dwbG90KG1wZykgKyBhZXMoaHd5KSArIGdlb21faGlzdG9ncmFtKGJpbnMgPSAxMCwgY29sb3IgPSAid2hpdGUiLCBmaWxsID0gIm5hdnkiKSAtPiBiCgpwbG90X2dyaWQoYSwgYiwgbGFiZWxzID0gYygid2lkdGgiLCAiYmlucyIpKSAKYGBgCgojIGdlb21fYmFyKCkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KYGBge3J9CmdncGxvdChtcGcpICsgYWVzKGh3eSwgZmlsbCA9IGNsYXNzKSArIGdlb21fYmFyKCkgLT4gc3RhY2sKZ2dwbG90KG1wZykgKyBhZXMoaHd5LCBmaWxsID0gY2xhc3MpICsgZ2VvbV9iYXIocG9zaXRpb249ImRvZGdlIikgLT4gZG9kZ2UKZ2dwbG90KG1wZykgKyBhZXMoaHd5LCBmaWxsID0gY2xhc3MpICsgZ2VvbV9iYXIocG9zaXRpb249ImZpbGwiKSAtPiBmaWxsCgpwbG90X2dyaWQoc3RhY2ssIGRvZGdlLCBmaWxsLCBsYWJlbHMgPSBjKCJzdGFjayIsICJkb2RnZSIsICJmaWxsIikpIApgYGAKCiMgZ2VvbV9kZW5zaXR5KCkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpgYGB7cn0KZ2dwbG90KG1wZykgKyBhZXMoaHd5LCBmaWxsID0gY2xhc3MpICsgZ2VvbV9kZW5zaXR5KCkgLT4gYSAKZ2dwbG90KG1wZykgKyBhZXMoaHd5LCBmaWxsID0gY2xhc3MpICsgZ2VvbV9kZW5zaXR5KGFscGhhPTAuNSkgLT4gYiAKCnBsb3RfZ3JpZChhLCBiLCBsYWJlbHMgPSAiQVVUTyIpIApgYGAKCiMgZ2VvbV9kb3RwbG90KCkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpgYGB7cn0KZ2dwbG90KGlyaXMpICsgYWVzKFNlcGFsLkxlbmd0aCkgKyBnZW9tX2RvdHBsb3QoKSAtPiBhCmdncGxvdChpcmlzKSArIGFlcyhTZXBhbC5MZW5ndGgpICsgZ2VvbV9kb3RwbG90KGJpbndpZHRoID0gMC4xKSAtPiBjIApnZ3Bsb3QoaXJpcykgKyBhZXMoU2VwYWwuTGVuZ3RoKSArIGdlb21fZG90cGxvdChiaW53aWR0aCA9IDAuMSwgc3RhY2tkaXIgPSAiY2VudGVyd2hvbGUiKSAtPiBkIApnZ3Bsb3QoaXJpcykgKyBhZXMoU3BlY2llcywgU2VwYWwuTGVuZ3RoKSArIGdlb21fZG90cGxvdChiaW5heGlzID0gInkiKSAtPiBlCmdncGxvdChpcmlzKSArIGFlcyhTcGVjaWVzLCBTZXBhbC5MZW5ndGgpICsgZ2VvbV9kb3RwbG90KGJpbmF4aXMgPSAieSIsIHN0YWNrZGlyID0gImNlbnRlcndob2xlIikgLT4gZgpnZ3Bsb3QoaXJpcykgKyBhZXMoU3BlY2llcywgU2VwYWwuTGVuZ3RoLCBmaWxsID0gU3BlY2llcykgKyBnZW9tX2RvdHBsb3QoYmluYXhpcyA9ICJ5Iiwgc3RhY2tkaXIgPSAiY2VudGVyd2hvbGUiKSAtPiBnCgpwbG90X2dyaWQoYSwgYywgZCwgZSwgZiwgZywgbGFiZWxzID0gIkFVVE8iKSAKYGBgCgojIGdlb21fdmlvbGluKCkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpgYGB7cn0KZ2dwbG90KGlyaXMpICsgYWVzKFNwZWNpZXMsIFNlcGFsLkxlbmd0aCkgKyBnZW9tX3Zpb2xpbigpIC0+IGEgCmdncGxvdChpcmlzKSArIGFlcyhTcGVjaWVzLCBTZXBhbC5MZW5ndGgpICsgIGdlb21fdmlvbGluKCkgKyBnZW9tX2RvdHBsb3QoYWVzKGZpbGwgPSBTcGVjaWVzKSwgYmluYXhpcyA9ICJ5Iiwgc3RhY2tkaXIgPSAiY2VudGVyd2hvbGUiKSAtPiBiIAoKcGxvdF9ncmlkKGEsIGIsIGxhYmVscyA9ICJBVVRPIikgCmBgYAoKIyBnZW9tX2ppdHRlcigpIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmBgYHtyfQpnZ3Bsb3QoaXJpcykgKyAKICBhZXMoU3BlY2llcywgU2VwYWwuTGVuZ3RoLCBjb2xvciA9IFNwZWNpZXMpICsgCiAgZ2VvbV9wb2ludCgpIC0+IGEgCgpnZ3Bsb3QoaXJpcykgKyAKICBhZXMoU3BlY2llcywgU2VwYWwuTGVuZ3RoLCBjb2xvciA9IFNwZWNpZXMpICsgCiAgZ2VvbV9qaXR0ZXIoKSAtPiBiIAoKZ2dwbG90KGlyaXMpICsgCiAgYWVzKFNwZWNpZXMsIFNlcGFsLkxlbmd0aCwgY29sb3IgPSBTcGVjaWVzKSArIAogIGdlb21faml0dGVyKHdpZHRoID0gMC4yNSwgYWxwaGEgPSAwLjUpIC0+IGMKCnBsb3RfZ3JpZChhLCBiLCBjLCBsYWJlbHMgPSAiQVVUTyIpIApgYGAKCiMgZ2VvbV9ib3hwbG90KCkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KYGBge3J9CmdncGxvdChpcmlzKSArIAogIGFlcyhTcGVjaWVzLCBTZXBhbC5MZW5ndGgsIGNvbG9yID0gU3BlY2llcykgKyAKICBnZW9tX2JveHBsb3QoKSAtPiBhIAoKZ2dwbG90KGlyaXMpICsgCiAgYWVzKFNwZWNpZXMsIFNlcGFsLkxlbmd0aCwgZmlsbCA9IFNwZWNpZXMpICsgCiAgZ2VvbV9ib3hwbG90KCkgLT4gYSAKCnBsb3RfZ3JpZChhLCBiLCBsYWJlbHMgPSAiQVVUTyIpIApgYGA=