GIỚI THIỆU

Bộ dữ liệu DIAMONS là bộ dữ liệu nằm trong packages tidyverse với 53940 quan sát và 10 biến về các

loại kim cương

Các biến bao gồm:

carat: Trọng lượng của kim cương.

cut: Loại cắt của kim cương (Fair, Good, Very Good, Premium, Ideal).

color: Màu sắc của kim cương, được mã hóa từ D (tốt nhất) đến J (kém nhất).

clarity: Độ trong suốt của kim cương (IF, VVS1, VVS2, VS1, VS2, SI1, SI2, I1).

depth: Độ sâu của kim cương, được đo từ mặt bên dưới đến mặt trên, chia cho chiều dài.

table: Chiều rộng của mặt bên trên của kim cương so với điểm cắt, chia cho chiều rộng lớn nhất.

price: Giá của kim cương (đơn vị: USD).

x: Chiều dài của kim cương (đơn vị: mm).

y: Chiều rộng của kim cương (đơn vị: mm).

z: Chiều sâu của kim cương (đơn vị: mm).

Và dưới đây là các biểu đồ biểu diễn những thông tin của bộ dữ liệu để dễ dàng thống kê và phân tích

library(ggplot2)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ lubridate 1.9.3     ✔ tibble    3.2.1
## ✔ purrr     1.0.2     ✔ tidyr     1.3.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(scales)
## 
## Attaching package: 'scales'
## 
## The following object is masked from 'package:purrr':
## 
##     discard
## 
## The following object is masked from 'package:readr':
## 
##     col_factor
p <- diamonds

I. Tổng hợp số lượng kim cương theo các biến khác nhau

1. Hình 1.1: Biểu đồ thể hiện số lượng kim cương theo chất lượng

p %>% ggplot(aes(x = cut)) +
    geom_bar() +
    labs(x = 'Loại', y = 'Số lượng')+
    coord_flip()

Biểu đồ trên ta có thể thấy được: số lượng kim cương tăng dần theo mức độ chất lượng từ thấp đến cao, cột cao nhất với chất lượng Ideal có hơn 20000 đơn vị kim cương; cột thấp nhất với chất lượng Fair chiếm khoảng 2300 đơn vị

2. Hình 1.2

p %>% group_by(cut ) %>% summarise(n = n()) %>%
  ggplot(aes(cut,n)) +
    geom_col(fill='orange') +
    geom_text(aes(label = n),vjust = 2, color = 'yellow') +
    labs(x = 'Loại ', y = 'Số lượng')

Cũng như loại biểu đồ trên biểu đồ dưới đây tổng hợp số lương kim cương theo chất lương nhưng được cụ thể hơn:

  • Kim cương có chất lượng Fair thấp nhất chiếm 1610
  • Chất lượng Good chiếm 4906
  • Chất lượng Very Good chiếm 12082
  • Chất lượng Premium chiếm 13791 và cuối cùng vị trí cao nhất là Ideal chiếm 21551 đơn vị

3. Hình 1.3: Biểu đồ thể hiện số lượng kim cương theo độ trong suốt

p %>% ggplot(aes(x = clarity)) +
    geom_bar() +
    labs(x = 'Loại', y = 'Số lượng') +
    coord_flip()

Qua biểu đồ ta thấy được số lượng kim cương theo từng loại cụ thể:

  • Kim cương loại SI1 có số lương cao nhất khoảng hơn 15000 đơn vị
  • Kim cương loại I1 thấp nhất chiếm khoảng 1200 đơn vị.

4. Hình 1.4

p %>% group_by(clarity ) %>% summarise(n = n()) %>%
  ggplot(aes(clarity,n)) +
    geom_col(fill='salmon') +
    geom_text(aes(label = n),vjust = 2, color = 'navy') +
    labs(x = 'Loại ', y = 'Số lượng')

Biểu đồ 1.4 cho ta thấy kim cương có độ trong suốt cụ thể:

  • I1 thấp nhất chiếm 741 đơn vị, SI2 chiếm 9194 đơn vị
  • SI1 cao nhất chiếm 13065 đơn vị, VS2 chiếm 12258
  • VS1 chiếm 8171, VVS2 chiếm 5066
  • VVS1 chiếm 3655, IF chiếm 1790

II. Khối lượng carat trung bình của kim cương

1. Hình 2.1: Biểu đồ khối lượng carat trung bình theo chất lượng

p %>% group_by(cut) %>% summarise(m= mean(carat)) %>%
  ggplot(aes(x = cut,y = m)) +
    geom_col(fill='pink') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'red') +
    labs(x = 'Loại', y = 'Mean')

Biểu đồ 2.1 thể hiện khối lượng carat trung bình của các viên kim cương theo chất lượng được cụ thể:

  • Chất lượng Fair khối lượng carat trung bình cao nhất là 1.05
  • Chất lượng Good khối lượng carat trung bình là 0.85
  • Chất lượng Very Good khối lượng carat trung bình là 0.81
  • Chất lượng Premium khối lượng carat trung bình là 0.89; cuối cùng chất lượng Ideal khối lượng carat trung bình thấp nhất là 0.7

2. Hình 2.2: Biểu đồ khối lượng carat trung bình theo độ trong suốt

p %>% group_by(clarity) %>% summarise(m= mean(carat)) %>%
  ggplot(aes(x = clarity,y = m)) +
    geom_col(fill='orchid') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'brown') +
    labs(x = 'Độ trong suốt', y = 'Mean')

Độ trong suốt của kim cương có khối lượng carat trung bình được biểu diễn bằng số liệu cụ thể:

  • Kim cương có độ trong suốt I1 cao nhất với khối lượng carat trung bình là 1.28
  • SI2 có khối lượng carat trung bình là 1.08
  • VS2 có khối lượng trung bình là 0.76
  • VS1 có khối lượng trung bình là 0.73
  • VVS2 có khối lượng trung bình là 0.6
  • Kim cương có độ trong suốt VVS1 thấp nhất với khối lượng carat trung bình là 0.5. Cuối cùng là IF chiếm 0.51

3. Hình 2.3: Biểu đồ khối lượng carat trung bình theo màu

p %>% group_by(color) %>% summarise(m= mean(carat)) %>%
  ggplot(aes(x = color,y = m)) +
    geom_col(fill='yellow') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'black') +
    labs(x = 'Color', y = 'Mean')

Biểu đồ 2.3 cho thấy khối lượng carat trung bình theo màu J cao nhất chiếm 1.16, khối lượng carat trung bình D và E thấp nhất chiếm 0.66

4. Hình 2.4: Biểu đồ khối lượng carat trung bình theo chiều sâu vết cắt

p %>% group_by(depth) %>% summarise(n = n()) %>%
  ggplot(aes(depth,n)) +
    geom_col(fill='blue') +
    labs(x = 'Loại', y = 'Số lượng')

III. Phân tích biểu đồ chỉ phần trăm số lượng theo biến cut

1. Hình 3.1

p %>% group_by(cut) %>% summarise(n = n()) %>%
  ggplot(aes(cut,n)) +
    geom_col(fill='salmon') +
    geom_text(aes(label = percent(n/length(p$carat))),vjust = 2, color = 'black') +
    labs(x = 'Loại', y = 'Số lượng')

  • Fair : 3% (chiếm tỉ trọng nhỏ nhất)
  • Good : 9,1%
  • Very Good : 22,4%
  • Premium : 25,6%
  • Ideal : 40% (chiếm tỉ trọng lớn nhất )

2. Hình 3.2: Phân tích biểu đồ chỉ phần trăm số lượng theo biến color

p %>% group_by(color) %>% summarise(n = n()) %>%
  ggplot(aes(color,n)) +
    geom_col(fill='pink') +
    geom_text(aes(label = percent(n/length(p$carat))),vjust = 2, color = 'red') +
    labs(x = 'Màu sắc', y = 'Số lượng')

Biểu đồ trên được chia theo biến ‘color’và gồm 7 loại lần lượt là ’D’,‘E’,‘F’,‘G’,‘H’,‘I’,‘G’ trục tung là số lượng kim cương ở từng loại . Từ đồ thị ta thấy được tỉ trọng của từng loại kim cương :

  • D : 12,56%
  • E : 18,16%
  • F : 17,69%
  • G : 20,93%
  • H : 15,39% (chiếm tỉ trọng lớn nhất )
  • I : 10,05%
  • J : 5,21% (chiếm tỉ trọng nhỏ nhất)

3. Hình 3.3: Phân tích đồ biểu đồ chỉ phần trăm số lượng theo biến clarity

p %>% group_by(clarity) %>% summarise(n = n()) %>%
  ggplot(aes(clarity,n)) +
    geom_col(fill='yellow') +
    geom_text(aes(label = percent(n/length(p$carat))),vjust = 2, color = 'red') +
    labs(x = 'Màu sắc', y = 'Số lượng')

Trục tung thể hiện cột số lượng

Trục hoành (màu sắc) gồm I1,SI2,SI1,VS2,VS1,VVS2,VVS1,IF là độ trong suốt của viên kim cương

Các cột thể hiện phần trăm sồ lượng từng loại trên tổng số kim cương

Biểu đồ 3.3 cho ta thấy kim cương loại:

  • I1 chiếm % thấp nhất là 1.4%
  • SI2 chiếm 17%
  • SI1 cao nhất chiếm 24.2%
  • VS2 chiếm 22.7%
  • VS1 chiếm 15.1%
  • VVS2 chiếm 9.4%
  • VVS1 chiếm 6.8%
  • IF chiếm 3.3%

IV. So sánh số lượng giữa các loại kim cương ngẫu nhiên

1. Hình 4.1: Biểu đồ so sánh số lượng kim cương theo chất tác có màu D và J

p3 <- p %>% group_by(cut, color) %>% summarise(n = n()) 
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.
p3 %>% ggplot(aes(x = cut, y = n)) +
  geom_col(data = p3 %>% filter(color == 'D'), fill = 'red') +
  geom_col(data = p3 %>% filter(color == 'J'), fill = 'blue')

Trục tung (n) thể hiện số lượng kim cương

Trục hoành (cut) thể hiện chất lượng gồm Fair,Good,Very Good,Premium,Ideal

Cột màu đỏ thể hiện màu D

Cột màu xanh thể hiện màu J

Qua biểu đồ ta thấy có sự chênh lệch khá lớn giữa hai màu kim cương ,cột màu đỏ là kim cương màu D có số lượng gấp đôi kim cương màu J là cột màu xanh

2. Hình 4.2: Biểu đồ so sánh số lượng kim cương theo chất lượng chế tác có độ trong suốt VS2 và I1

p1 <- p %>% group_by(cut, clarity) %>% summarise(n = n()) 
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.
p1 %>% ggplot(aes(x = cut, y = n)) +
  geom_col(data = p1 %>% filter(clarity == 'VS2'), fill = 'yellow') +
  geom_col(data = p1 %>% filter(clarity == 'I1'), fill = 'red')

Trục tung (n) số lượng

Trục hoành (cut) gồm Fair,Good,Very Good,Premium,Ideal

Biểu đồ thể hiện hai loại kim cương khác nhau: cột màu vàng thể hiện kim cương có độ trong suốt VS2, cột màu đỏ thể hiện kim cương có độ trong suốt I1 được thống kê theo chất lương chế tác

Quan sát biểu đồ cho ta thấy rõ sự cách biệt lớn về số lượng của hai loại kim cương trên: kim cương có độ trong suốt VS2 có số lương gấp nhiều lần so với số lượng kim cương có độ trong suốt I1 => chứng tỏ trên thị trường loại kim cương có độ trong suốt I1 không đc phổ biến chiếm thị phần nhỏ trên tổng số.

3. Hình 4.3: Biểu đồ so sánh số lượng kim cương theo màu có độ trong suốt SI1 và VVS1

p2 <- p %>% group_by(clarity, color) %>% summarise(n = n())
## `summarise()` has grouped output by 'clarity'. You can override using the
## `.groups` argument.
p2 %>% ggplot(aes(x = color, y = n)) +
  geom_col(data = p2 %>% filter(clarity == 'SI1'), fill = 'yellow') +
  geom_col(data = p2 %>% filter(clarity == 'VVS1'), fill = 'orange')

Trục tung(n) số lượng

Trục hoành (color) gồm các màu D,E,F,G,H,I,J

Biểu đồ thể hiện 2 loại kim cương:

  • Cột màu vàng thể hiện kim cương có độ trong suốt SI1
  • Cột màu cam thể hiện kim cương có độ trong suốt VVS1
  • Nhìn vào biểu đồ ta thấy được kim cương độ trong suốt SI1 chiếm số lượng nhiều hơn kim cương độ trong suốt VVS1

4. Hình 4.4: Biểu đồ so sánh số lượng kim cương theo màu có độ trong suốt VS1 và VS2

p2 %>% group_by(clarity, color) %>% summarise(n = n()) %>% 
ggplot(aes(x = color, y = n)) +
  geom_col(data = p2 %>% filter(clarity == 'VS2'), fill = 'yellow') +
  geom_col(data = p2 %>% filter(clarity == 'VS1'), fill = 'salmon')
## `summarise()` has grouped output by 'clarity'. You can override using the
## `.groups` argument.

Biểu đồ 4.4 gồm kim cương có độ trong suốt VS2 cột màu vàng, kim cương có độ trong suốt VS1 cột màu hồng đậm. Cho thấy kim cương loại VS1 chiếm số lượng nhiều hơn VS2 tuy nhiên số lượng nhiều hơn không đáng kể

V. So sánh theo nhóm kim cương theo số lượng

1. Hình 5.1: Biểu đồ so sánh nhóm kim cương theo màu và chất lượng chế tác

Ta có nhóm biểu đồ thể hiện số lượng kim cương theo từng loại chế tác khác nhau từ đó có thể dễ dàng quan sát so sánh giữa các màu của loại chế tác này gồm D,E,F,G,H,I,J cùng với các chất lượng Fair,Good, Very Good, Premium,Ideal

p %>% group_by(cut,color) %>% summarise(n=n(),.groups = 'drop') %>%
  ggplot(aes(x = color,y = n)) +
    geom_col(fill="black") +
    facet_wrap(~cut) +
    labs(x = 'Loại', y = 'Số lượng')

Cũng như biểu đồ trên biểu đồ dưới đây cũng giúp ta quan sát và so sánh những vần đề trên nhưng với câu lệnh geom_text(aes(label = n),vjust = 2, color = ‘yellow’) ta có thể thấy rõ số liệu một cách cụ thể.

p %>% group_by(cut,color) %>% summarise(n=n(),.groups = 'drop') %>%
  ggplot(aes(x = color,y = n)) +
    geom_col( fill= 'purple') +
    facet_wrap(~cut) +
    geom_text(aes(label = n),vjust = 2, color = 'yellow') +
    labs(x = 'Loại', y = 'Số lượng')

2. Hình 5.2: Biểu đồ so sánh nhóm kim cương theo độ trong suốt và chất lượng chế tác

Ta có nhóm biểu đồ thể hiện số lượng kim cương theo từng loại chế tác khác nhau từ đó có thể dễ dàng quan sát so sánh giữa các loại độ trong suốt kim cương của loại chế tác này gồm I1,SI2,SI1,VS2,VS1,VVS2,VVS1,IF cùng với các chất lượng Fair,Good, Very Good, Premium,Ideal

p %>% group_by(cut,clarity) %>% summarise(n=n(),.groups = 'drop') %>%
  ggplot(aes(x = clarity,y = n)) +
    geom_col(fill="turquoise") +
    facet_wrap(~cut) +
    labs(x = 'Loại', y = 'Số lượng')

Cũng như biểu đồ trên biểu đồ dưới đây cũng giúp ta quan sát và so sánh những vần đề trên nhưng với câu lệnh geom_text(aes(label = n),vjust = 2, color = ‘red’) ta có thể thấy rõ số liệu một cách cụ thể.

p %>% group_by(clarity,cut) %>% summarise(n=n(),.groups = 'drop') %>%
  ggplot(aes(x = clarity,y = n)) +
    geom_col( fill= 'green') +
    facet_wrap(~ cut) +
    geom_text(aes(label = n),vjust = 2, color = 'red') +
    labs(x = 'Loại', y = 'Số lượng')

3. Hình 5.3: Biểu đồ so sánh nhóm kim cương theo màu và độ trong suốt

Ta có nhóm biểu đồ thể hiện số lượng kim cương theo từng loại trong suốt khác nhau từ đó có thể dễ dàng quan sát so sánh giữa các màu của loại trong suốt này gồm D,E,F,G,H,I,J với từng loại trong suốt kia I1,SI2,SI1,VS2,VS1,VVS2,VVS1,IF

p %>% group_by(clarity,color) %>% summarise(n=n(),.groups = 'drop') %>%
  ggplot(aes(x = color,y = n)) +
    geom_col(fill="red") +
    facet_wrap(~clarity) +
    labs(x = 'Loại', y = 'Số lượng')

Cũng như biểu đồ trên biểu đồ dưới đây cũng giúp ta quan sát và so sánh những vần đề trên nhưng với câu lệnh geom_text(aes(label = n),vjust = 2, color = ‘white’) ta có thể thấy rõ số liệu một cách cụ thể.

p %>% group_by(clarity,color) %>% summarise(n=n(),.groups = 'drop') %>%
  ggplot(aes(x = color,y = n)) +
    geom_col( fill= 'brown') +
    facet_wrap(~clarity) +
    geom_text(aes(label = n),vjust = 2, color = 'white') +
    labs(x = 'Loại', y = 'Số lượng')

VI. So sánh nhóm kim cương theo mức giá trung bình

1. Hình 6.1: Biểu đồ so sánh nhóm kim cương (màu và chất lượng chế tác)

p %>% group_by(cut,color) %>% summarise(m = mean(price),.groups = 'drop') %>%
  ggplot(aes(x = color,y = m)) +
    geom_col(position = 'dodge') +
    facet_wrap(~cut ) +
    geom_text(aes(label = round(m))) +
    labs(x = 'Color ', y = 'Số lượng')

Trục tung thể hiện số lượng

Trục hoành biểu diễn các màu gồm D,E,F,G,H,I,J

Biểu đồ nhóm 6.1 là thống kê mức giá trung bình của từng loại kim cương chế tác theo tất cả các màu có đầy đủ số liệu trên từng biểu đồ

2. Hình 6.2: Biểu đồ so sánh nhóm kim cương (độ trong suốt và chất lượng chế tác)

p %>% group_by(cut,clarity) %>% summarise(m = mean(price), .groups = 'drop') %>%
  ggplot(aes(x = clarity,y = m)) +
    geom_col(position = 'dodge') +
    facet_wrap(~cut ) +
    geom_text(aes(label = round(m))) +
    labs(x = 'clarity ', y = 'Số lượng')

Biểu đồ 6.2 thể hiện sự so sánh mức giá trung bình của từng loại kim cương chế tác theo màu và độ

trong suốt

3. Hình 6.3: Biểu đồ so sánh nhóm kim cương (màu và độ trong suốt)

p %>% group_by(clarity,color) %>% summarise(m = mean(price), .groups='drop') %>%
  ggplot(aes(x = color,y = m)) +
    geom_col(position = 'dodge') +
    facet_wrap(~clarity) +
    geom_text(aes(label = round(m))) +
    labs(x = 'Color ', y = 'Số lượng')

Biểu đồ 6.3 thể hiện sự so sánh mức giá trung bình của từng loại kim cương chế tác theo tất cả các độ

trong suốt và màu

VII. Phân tích số lượng kim cương theo mức giá và khối lượng carat

1. Hình 7.1: BIểu đồ phân tích số lượng kim cương theo khối lượng

p <-p %>% mutate(Carat = cut(carat,5, label = c('rất nhỏ', 'nhỏ','vừa','lớn','rất lớn')))
p %>% ggplot(aes(x = Carat)) +
  geom_bar(fill = 'salmon')

Biểu đồ 7.1 cho thấy khối lượng carat được chia làm 5 loại: rất nhỏ, nhỏ, vừa,lớn,rất lớn. Loại rất nhỏ chiếm số lượng nhiều nhất, trong khi đó loại lớn và rất lớn hầu như là không có. Vậy trên thị trường carat loại lớn và rất lớn là cực kì hiếm so với các loại còn lại

2. Hình 7.2: BIểu đồ phân tích số lượng kim cương theo mức giá

p <- p %>% mutate(Price = cut(price,5, label = c('rất thấp ', 'thấp','tb','cao','rất cao')))
p %>% ggplot(aes(x = Price)) +
  geom_bar(fill = 'pink')

Trục tung(count) thể hiện mức giá

Trục hoành(price) gồm rất thấp, thấp, trung bình, cao, rất cao

Biểu đồ 7.2 cho ta thấy mức giá kim cương nằm ở trục tung thể hiện mức giá loại rất nhỏ thấp hơn các loại còn lại rất nhiều lần, kim cương loại rất lớn thì hiếm nên giá sẽ cao hơn

3. Hình 7.3

p <- p %>% mutate(color_code = case_when(
    color == "D" | color == "E" | color == "F" ~ 1,
    color == "G" | color == "H" | color == "I" | color == "J" ~ 2))

p <- mutate(p, colorC = cut(color_code, 2, label = c('không màu', 'gần như không màu')))

p %>% group_by(colorC) %>% summarise(n=n()) %>%
  ggplot(aes(colorC, n)) +
    geom_col(fill = 'red') +
    geom_text(aes(label = n), vjust = 0, color = 'black') +
    xlab('Màu sắc') +
    ylab('Số lượng (viên)') + 
    labs()

Trục tung thể hiện số lượng

Trục hoành thể hiện màu săc gồm không màu và gần như không màu

Ta thấy được số lượng viên gần như không màu chiếm số lượng nhiều hơn vì thế phần lớn carat có dạng trong suốt

4. Hình 7.4

p <- diamonds 
p <- p %>% mutate(depthC = cut(depth,5, label = c('Sâu','Khá sâu','Trung bình','Khá nông','Nông')))
p %>% ggplot(aes(x = depthC)) +
  geom_bar(fill = 'red')

Biểu đồ 7.4 thể hiện độ nông sâu khi cắt viên kim cương

VIII. Biểu đồ các chỉ số cụ thể theo từng biến

1. Hình 8.1: Median(trung vị) của biến ‘carat’

p %>% group_by(cut) %>% summarise(m= median(carat)) %>%
  ggplot(aes(x = cut,y = m)) +
    geom_col(position = 'dodge') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'yellow') +
    labs(x = 'Loại', y = 'Median')

Câu lệnh trên cho ta một biểu đò dạng Bar Chart với trục hoành là các loại kim cương được chia theo biến ‘cut’ bao gồm 5 loại lần lượt là ‘Fair’,‘Good’,‘Very Good’,‘Premium’,‘Ideal’, trục tung là trung vị độ lớn của biến ‘Carat’ . Cụ thể như sau:

  • Trung vị carat của loại kim cương ’ Fair’ là 1 (50% số kim cương loại Fair có độ lớn carat dưới 1 và 50% còn lại có độ lớn carat lớn hơn 1 )
  • Trung vị carat của loại kim cương ’ Good’ là 0.82 (50% số kim cương loại Good có độ lớn carat dưới 0.82 và 50% còn lại có độ lớn carat lớn hơn 0.82 )
  • Trung vị carat của loại kim cương ’ Very Good’ là 0.71 (50% số kim cương loại Very Good có độ lớn carat dưới 0.71 và 50% còn lại có độ lớn carat lớn hơn 0.71 )
  • Trung vị carat của loại kim cương ‘Premium’ là 0.86 (50% số kim cương loại Premium có độ lớn carat dưới 0.86 và 50% còn lại có độ lớn carat lớn hơn 0.86 )
  • Trung vị carat của loại kim cương ‘Ideal’ là 0.54 (50% số kim cương loại Ideal có độ lớn carat dưới 0.54 và 50% còn lại có độ lớn carat lớn hơn 0.54 )

2. Hình 8.2: Mean (giá trị trung bình) của biến ‘price’

p %>% group_by(cut) %>% summarise(m= mean(price)) %>%
  ggplot(aes(x = cut,y = m)) +
    geom_col(position = 'dodge') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'yellow') +
    labs(x = 'Loại', y = 'Mean')

Câu lệnh trên cho ta một đồ thị dạng Bar Chart với trục hoành là các loại kim cương được chia theo biến ‘cut’ bao gồm 5 loại lần lượt là ‘Fair’,‘Good’,‘Very Good’,‘Premium’,‘Ideal’, trục tung là trung bình độ lớn của biến ‘Price’ . Cụ thể như sau:

  • Kim cương Fair có độ lớn trung bình của biến ‘Price’ là : 4358.76
  • Kim cương Good có độ lớn trung bình của biến ‘Price’ là : 3928.86
  • Kim cương Very Good có độ lớn trung bình của biến ‘Price’ là : 3981.76
  • Kim cương Premium có độ lớn trung bình của biến ‘Price’ là : 4584.26
  • Kim cương Ideal có độ lớn trung bình của biến ‘Price’ là : 3457.54
LS0tDQp0aXRsZTogIk5oaeG7h20gduG7pSA0Ig0KYXV0aG9yOiAiTMOqIFRo4buLIFRoYW5oIFBow7oiDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclSDolTTolUywgJWQgLSAlbSAtICVZJylgIg0Kb3V0cHV0Og0KICAgIGh0bWxfZG9jdW1lbnQ6IA0KICAgICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICAgICB0b2M6IHRydWUNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCmBgYA0KDQojIyAqKkdJ4buaSSBUSEnhu4ZVKiogDQpC4buZIGThu68gbGnhu4d1ICBESUFNT05TIGzDoCBi4buZIGThu68gbGnhu4d1IG7hurFtIHRyb25nIHBhY2thZ2VzIHRpZHl2ZXJzZSB24bubaSA1Mzk0MCBxdWFuIHPDoXQgdsOgIDEwIGJp4bq/biB24buBIGPDoWMNCg0KbG/huqFpIGtpbSBjxrDGoW5nDQoNCkPDoWMgYmnhur9uIGJhbyBn4buTbToNCg0KY2FyYXQ6IFRy4buNbmcgbMaw4bujbmcgY+G7p2Ega2ltIGPGsMahbmcuDQoNCmN1dDogTG/huqFpIGPhuq90IGPhu6dhIGtpbSBjxrDGoW5nIChGYWlyLCBHb29kLCBWZXJ5IEdvb2QsIFByZW1pdW0sIElkZWFsKS4NCg0KY29sb3I6IE3DoHUgc+G6r2MgY+G7p2Ega2ltIGPGsMahbmcsIMSRxrDhu6NjIG3DoyBow7NhIHThu6sgRCAodOG7kXQgbmjhuqV0KSDEkeG6v24gSiAoa8OpbSBuaOG6pXQpLg0KDQpjbGFyaXR5OiDEkOG7mSB0cm9uZyBzdeG7kXQgY+G7p2Ega2ltIGPGsMahbmcgKElGLCBWVlMxLCBWVlMyLCBWUzEsIFZTMiwgU0kxLCBTSTIsIEkxKS4NCg0KZGVwdGg6IMSQ4buZIHPDonUgY+G7p2Ega2ltIGPGsMahbmcsIMSRxrDhu6NjIMSRbyB04burIG3hurd0IGLDqm4gZMaw4bubaSDEkeG6v24gbeG6t3QgdHLDqm4sIGNoaWEgY2hvIGNoaeG7gXUgZMOgaS4NCg0KdGFibGU6IENoaeG7gXUgcuG7mW5nIGPhu6dhIG3hurd0IGLDqm4gdHLDqm4gY+G7p2Ega2ltIGPGsMahbmcgc28gduG7m2kgxJFp4buDbSBj4bqvdCwgY2hpYSBjaG8gY2hp4buBdSBy4buZbmcgbOG7m24gbmjhuqV0Lg0KDQpwcmljZTogR2nDoSBj4bunYSBraW0gY8awxqFuZyAoxJHGoW4gduG7izogVVNEKS4NCg0KeDogQ2hp4buBdSBkw6BpIGPhu6dhIGtpbSBjxrDGoW5nICjEkcahbiB24buLOiBtbSkuDQoNCnk6IENoaeG7gXUgcuG7mW5nIGPhu6dhIGtpbSBjxrDGoW5nICjEkcahbiB24buLOiBtbSkuDQoNCno6IENoaeG7gXUgc8OidSBj4bunYSBraW0gY8awxqFuZyAoxJHGoW4gduG7izogbW0pLg0KDQpWw6AgZMaw4bubaSDEkcOieSBsw6AgY8OhYyBiaeG7g3UgxJHhu5MgYmnhu4N1IGRp4buFbiBuaOG7r25nIHRow7RuZyB0aW4gY+G7p2EgYuG7mSBk4buvIGxp4buHdSDEkeG7gyBk4buFIGTDoG5nIHRo4buRbmcga8OqIHbDoCBwaMOibiB0w61jaCANCg0KYGBge3J9DQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoc2NhbGVzKQ0KcCA8LSBkaWFtb25kcw0KYGBgDQoNCiMjICoqSS4gVOG7lW5nIGjhu6NwIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyBjw6FjIGJp4bq/biBraMOhYyBuaGF1KioNCg0KIyMjICoqMS4gSMOsbmggMS4xOiBCaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyBjaOG6pXQgbMaw4bujbmcgKioNCg0KYGBge3IsIGVjaG8gPSBUUlVFfQ0KcCAlPiUgZ2dwbG90KGFlcyh4ID0gY3V0KSkgKw0KICAgIGdlb21fYmFyKCkgKw0KICAgIGxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ1Phu5EgbMaw4bujbmcnKSsNCiAgICBjb29yZF9mbGlwKCkNCmBgYCANCg0KDQoNCkJp4buDdSDEkeG7kyB0csOqbiB0YSBjw7MgdGjhu4MgdGjhuqV5IMSRxrDhu6NjOiBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHTEg25nIGThuqduIHRoZW8gbeG7qWMgxJHhu5kgY2jhuqV0IGzGsOG7o25nICB04burIHRo4bqlcCDEkeG6v24gY2FvLCBj4buZdCBjYW8gbmjhuqV0IHbhu5tpIGNo4bqldCBsxrDhu6NuZyBJZGVhbCBjw7MgaMahbiAgMjAwMDAgxJHGoW4gduG7iyBraW0gY8awxqFuZzsgY+G7mXQgdGjhuqVwIG5o4bqldCB24bubaSBjaOG6pXQgbMaw4bujbmcgRmFpciBjaGnhur9tIGtob+G6o25nIDIzMDAgxJHGoW4gduG7iw0KDQojIyMgKioyLiBIw6xuaCAxLjIqKg0KDQpgYGB7ciwgZWNobyA9IFRSVUV9DQpwICU+JSBncm91cF9ieShjdXQgKSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpICU+JQ0KICBnZ3Bsb3QoYWVzKGN1dCxuKSkgKw0KICAgIGdlb21fY29sKGZpbGw9J29yYW5nZScpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksdmp1c3QgPSAyLCBjb2xvciA9ICd5ZWxsb3cnKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaSAnLCB5ID0gJ1Phu5EgbMaw4bujbmcnKQ0KYGBgDQoNCg0KDQpDxaluZyBuaMawIGxv4bqhaSBiaeG7g3UgxJHhu5MgdHLDqm4gYmnhu4N1IMSR4buTIGTGsOG7m2kgxJHDonkgdOG7lW5nIGjhu6NwIHPhu5EgbMawxqFuZyBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDGoW5nIG5oxrBuZyDEkcaw4bujYyBj4bulIHRo4buDIGjGoW46DQoNCisgS2ltIGPGsMahbmcgY8OzIGNo4bqldCBsxrDhu6NuZyBGYWlyIHRo4bqlcCBuaOG6pXQgY2hp4bq/bSAxNjEwICANCisgQ2jhuqV0IGzGsOG7o25nIEdvb2QgY2hp4bq/bSA0OTA2ICANCisgQ2jhuqV0IGzGsOG7o25nIFZlcnkgR29vZCBjaGnhur9tIDEyMDgyICANCisgQ2jhuqV0IGzGsOG7o25nIFByZW1pdW0gY2hp4bq/bSAxMzc5MSB2w6AgY3Xhu5FpIGPDuW5nIHbhu4sgdHLDrSBjYW8gbmjhuqV0IGzDoCBJZGVhbCBjaGnhur9tIDIxNTUxIMSRxqFuIHbhu4sgIA0KDQoNCiMjIyAqKjMuIEjDrG5oIDEuMzogQmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gxJHhu5kgdHJvbmcgc3Xhu5F0KioNCg0KYGBge3IsIGVjaG8gPSBUUlVFfQ0KcCAlPiUgZ2dwbG90KGFlcyh4ID0gY2xhcml0eSkpICsNCiAgICBnZW9tX2JhcigpICsNCiAgICBsYWJzKHggPSAnTG/huqFpJywgeSA9ICdT4buRIGzGsOG7o25nJykgKw0KICAgIGNvb3JkX2ZsaXAoKQ0KYGBgIA0KDQoNCg0KUXVhIGJp4buDdSDEkeG7kyB0YSB0aOG6pXkgxJHGsOG7o2Mgc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIHThu6tuZyBsb+G6oWkgY+G7pSB0aOG7gzoNCg0KKyBLaW0gY8awxqFuZyBsb+G6oWkgU0kxIGPDsyBz4buRIGzGsMahbmcgY2FvIG5o4bqldCBraG/huqNuZyBoxqFuIDE1MDAwIMSRxqFuIHbhu4sNCisgS2ltIGPGsMahbmcgbG/huqFpIEkxIHRo4bqlcCBuaOG6pXQgY2hp4bq/bSBraG/huqNuZyAxMjAwIMSRxqFuIHbhu4suDQoNCiMjIyAqKjQuIEjDrG5oIDEuNCoqDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCnAgJT4lIGdyb3VwX2J5KGNsYXJpdHkgKSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpICU+JQ0KICBnZ3Bsb3QoYWVzKGNsYXJpdHksbikpICsNCiAgICBnZW9tX2NvbChmaWxsPSdzYWxtb24nKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMiwgY29sb3IgPSAnbmF2eScpICsNCiAgICBsYWJzKHggPSAnTG/huqFpICcsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KDQoNCkJp4buDdSDEkeG7kyAxLjQgY2hvIHRhIHRo4bqleSBraW0gY8awxqFuZyBjw7MgxJHhu5kgdHJvbmcgc3Xhu5F0IGPhu6UgdGjhu4M6DQoNCisgSTEgdGjhuqVwIG5o4bqldCBjaGnhur9tIDc0MSDEkcahbiB24buLLCBTSTIgY2hp4bq/bSA5MTk0IMSRxqFuIHbhu4sNCisgU0kxIGNhbyBuaOG6pXQgY2hp4bq/bSAxMzA2NSDEkcahbiB24buLLCBWUzIgY2hp4bq/bSAxMjI1OA0KKyBWUzEgY2hp4bq/bSA4MTcxLCBWVlMyIGNoaeG6v20gNTA2Ng0KKyBWVlMxIGNoaeG6v20gMzY1NSwgSUYgY2hp4bq/bSAxNzkwDQoNCiMjICoqSUkuIEto4buRaSBsxrDhu6NuZyBjYXJhdCB0cnVuZyBiw6xuaCBj4bunYSBraW0gY8awxqFuZyAqKg0KDQojIyMgKioxLiBIw6xuaCAyLjE6IEJp4buDdSDEkeG7kyBraOG7kWkgbMaw4bujbmcgY2FyYXQgdHJ1bmcgYsOsbmggdGhlbyBjaOG6pXQgbMaw4bujbmcgKiogDQoNCmBgYHtyfQ0KcCAlPiUgZ3JvdXBfYnkoY3V0KSAlPiUgc3VtbWFyaXNlKG09IG1lYW4oY2FyYXQpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY3V0LHkgPSBtKSkgKw0KICAgIGdlb21fY29sKGZpbGw9J3BpbmsnKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG0sMikpLCB2anVzdCA9IDIsIGNvbG9yID0gJ3JlZCcpICsNCiAgICBsYWJzKHggPSAnTG/huqFpJywgeSA9ICdNZWFuJykNCmBgYA0KDQoNCg0KQmnhu4N1IMSR4buTIDIuMSB0aOG7gyBoaeG7h24ga2jhu5FpIGzGsOG7o25nIGNhcmF0IHRydW5nIGLDrG5oIGPhu6dhIGPDoWMgdmnDqm4ga2ltIGPGsMahbmcgdGhlbyBjaOG6pXQgbMaw4bujbmcgxJHGsOG7o2MgY+G7pSB0aOG7gzoNCg0KKyBDaOG6pXQgbMaw4bujbmcgRmFpciBraOG7kWkgbMaw4bujbmcgY2FyYXQgdHJ1bmcgYsOsbmggY2FvIG5o4bqldCBsw6AgMS4wNSAgDQorIENo4bqldCBsxrDhu6NuZyBHb29kIGto4buRaSBsxrDhu6NuZyBjYXJhdCB0cnVuZyBiw6xuaCBsw6AgMC44NQ0KKyBDaOG6pXQgbMaw4bujbmcgVmVyeSBHb29kIGto4buRaSBsxrDhu6NuZyBjYXJhdCB0cnVuZyBiw6xuaCBsw6AgMC44MQ0KKyBDaOG6pXQgbMaw4bujbmcgUHJlbWl1bSBraOG7kWkgbMaw4bujbmcgY2FyYXQgdHJ1bmcgYsOsbmggbMOgIDAuODk7IGN14buRaSBjw7luZyBjaOG6pXQgbMaw4bujbmcgSWRlYWwga2jhu5FpIGzGsOG7o25nIGNhcmF0IHRydW5nIGLDrG5oIHRo4bqlcCBuaOG6pXQgbMOgIDAuNw0KDQojIyMgKioyLiBIw6xuaCAyLjI6IEJp4buDdSDEkeG7kyBraOG7kWkgbMaw4bujbmcgY2FyYXQgdHJ1bmcgYsOsbmggdGhlbyDEkeG7mSB0cm9uZyBzdeG7kXQgKioNCg0KYGBge3J9DQpwICU+JSBncm91cF9ieShjbGFyaXR5KSAlPiUgc3VtbWFyaXNlKG09IG1lYW4oY2FyYXQpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY2xhcml0eSx5ID0gbSkpICsNCiAgICBnZW9tX2NvbChmaWxsPSdvcmNoaWQnKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG0sMikpLCB2anVzdCA9IDIsIGNvbG9yID0gJ2Jyb3duJykgKw0KICAgIGxhYnMoeCA9ICfEkOG7mSB0cm9uZyBzdeG7kXQnLCB5ID0gJ01lYW4nKQ0KYGBgDQoNCg0KDQrEkOG7mSB0cm9uZyBzdeG7kXQgY+G7p2Ega2ltIGPGsMahbmcgY8OzIGto4buRaSBsxrDhu6NuZyBjYXJhdCB0cnVuZyBiw6xuaCDEkcaw4bujYyBiaeG7g3UgZGnhu4VuIGLhurFuZyBz4buRIGxp4buHdSBj4bulIHRo4buDOg0KDQorIEtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgSTEgY2FvIG5o4bqldCB24bubaSBraOG7kWkgbMaw4bujbmcgY2FyYXQgdHJ1bmcgYsOsbmggbMOgIDEuMjgNCisgU0kyIGPDsyBraOG7kWkgbMaw4bujbmcgY2FyYXQgdHJ1bmcgYsOsbmggbMOgIDEuMDgNCisgVlMyIGPDsyBraOG7kWkgbMaw4bujbmcgdHJ1bmcgYsOsbmggbMOgIDAuNzYNCisgVlMxIGPDsyBraOG7kWkgbMaw4bujbmcgdHJ1bmcgYsOsbmggbMOgIDAuNzMNCisgVlZTMiBjw7Mga2jhu5FpIGzGsOG7o25nIHRydW5nIGLDrG5oIGzDoCAwLjYNCisgS2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBWVlMxIHRo4bqlcCBuaOG6pXQgduG7m2kga2jhu5FpIGzGsOG7o25nIGNhcmF0IHRydW5nIGLDrG5oIGzDoCAwLjUuIEN14buRaSBjw7luZyBsw6AgSUYgY2hp4bq/bSAwLjUxDQoNCiMjIyAqKjMuIEjDrG5oIDIuMzogQmnhu4N1IMSR4buTIGto4buRaSBsxrDhu6NuZyBjYXJhdCB0cnVuZyBiw6xuaCB0aGVvIG3DoHUgKioNCmBgYHtyfQ0KcCAlPiUgZ3JvdXBfYnkoY29sb3IpICU+JSBzdW1tYXJpc2UobT0gbWVhbihjYXJhdCkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBjb2xvcix5ID0gbSkpICsNCiAgICBnZW9tX2NvbChmaWxsPSd5ZWxsb3cnKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG0sMikpLCB2anVzdCA9IDIsIGNvbG9yID0gJ2JsYWNrJykgKw0KICAgIGxhYnMoeCA9ICdDb2xvcicsIHkgPSAnTWVhbicpDQpgYGANCg0KDQpCaeG7g3UgxJHhu5MgMi4zIGNobyB0aOG6pXkga2jhu5FpIGzGsOG7o25nIGNhcmF0IHRydW5nIGLDrG5oIHRoZW8gbcOgdSBKIGNhbyBuaOG6pXQgY2hp4bq/bSAxLjE2LCBraOG7kWkgbMaw4bujbmcgY2FyYXQgdHJ1bmcgYsOsbmggRCB2w6AgRSB0aOG6pXAgbmjhuqV0IGNoaeG6v20gMC42Ng0KDQojIyMgKio0LiBIw6xuaCAyLjQ6IEJp4buDdSDEkeG7kyBraOG7kWkgbMaw4bujbmcgY2FyYXQgdHJ1bmcgYsOsbmggdGhlbyBjaGnhu4F1IHPDonUgduG6v3QgY+G6r3QgKioNCmBgYHtyfQ0KcCAlPiUgZ3JvdXBfYnkoZGVwdGgpICU+JSBzdW1tYXJpc2UobiA9IG4oKSkgJT4lDQogIGdncGxvdChhZXMoZGVwdGgsbikpICsNCiAgICBnZW9tX2NvbChmaWxsPSdibHVlJykgKw0KICAgIGxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ1Phu5EgbMaw4bujbmcnKQ0KYGBgDQoNCiMjICoqSUlJLiBQaMOibiB0w61jaCBiaeG7g3UgxJHhu5MgY2jhu4kgcGjhuqduIHRyxINtIHPhu5EgbMaw4bujbmcgdGhlbyBiaeG6v24gY3V0KioNCg0KIyMjICoqMS4gSMOsbmggMy4xKioNCmBgYHtyfQ0KcCAlPiUgZ3JvdXBfYnkoY3V0KSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpICU+JQ0KICBnZ3Bsb3QoYWVzKGN1dCxuKSkgKw0KICAgIGdlb21fY29sKGZpbGw9J3NhbG1vbicpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGVyY2VudChuL2xlbmd0aChwJGNhcmF0KSkpLHZqdXN0ID0gMiwgY29sb3IgPSAnYmxhY2snKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KKyBGYWlyIDogMyUgKGNoaeG6v20gdOG7iSB0cuG7jW5nIG5o4buPIG5o4bqldCkNCisgR29vZCA6IDksMSUNCisgVmVyeSBHb29kIDogMjIsNCUNCisgUHJlbWl1bSA6IDI1LDYlDQorIElkZWFsIDogNDAlIChjaGnhur9tIHThu4kgdHLhu41uZyBs4bubbiBuaOG6pXQgKQ0KDQojIyMgKioyLiBIw6xuaCAzLjI6IFBow6JuIHTDrWNoIGJp4buDdSDEkeG7kyBjaOG7iSBwaOG6p24gdHLEg20gc+G7kSBsxrDhu6NuZyB0aGVvIGJp4bq/biBjb2xvcioqDQoNCmBgYHtyfQ0KcCAlPiUgZ3JvdXBfYnkoY29sb3IpICU+JSBzdW1tYXJpc2UobiA9IG4oKSkgJT4lDQogIGdncGxvdChhZXMoY29sb3IsbikpICsNCiAgICBnZW9tX2NvbChmaWxsPSdwaW5rJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBwZXJjZW50KG4vbGVuZ3RoKHAkY2FyYXQpKSksdmp1c3QgPSAyLCBjb2xvciA9ICdyZWQnKSArDQogICAgbGFicyh4ID0gJ03DoHUgc+G6r2MnLCB5ID0gJ1Phu5EgbMaw4bujbmcnKQ0KYGBgDQoNCg0KDQpCaeG7g3UgxJHhu5MgdHLDqm4gxJHGsOG7o2MgY2hpYSB0aGVvIGJp4bq/biDigJhjb2xvcuKAmXbDoCBn4buTbSA3IGxv4bqhaSBs4bqnbiBsxrDhu6N0IGzDoCDigJlE4oCZLOKAmEXigJks4oCYRuKAmSzigJhH4oCZLOKAmEjigJks4oCYSeKAmSzigJhH4oCZIHRy4bulYyB0dW5nIGzDoCBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIOG7nyB04burbmcgbG/huqFpIC4gVOG7qyDEkeG7kyB0aOG7iyB0YSB0aOG6pXkgxJHGsOG7o2MgdOG7iSB0cuG7jW5nIGPhu6dhIHThu6tuZyBsb+G6oWkga2ltIGPGsMahbmcgOg0KDQorIEQgOiAxMiw1NiUNCisgRSA6IDE4LDE2JQ0KKyBGIDogMTcsNjklDQorIEcgOiAyMCw5MyUNCisgSCA6IDE1LDM5JSAoY2hp4bq/bSB04buJIHRy4buNbmcgbOG7m24gbmjhuqV0ICkNCisgSSA6IDEwLDA1JQ0KKyBKIDogNSwyMSUgKGNoaeG6v20gdOG7iSB0cuG7jW5nIG5o4buPIG5o4bqldCkNCg0KIyMjICoqMy4gSMOsbmggMy4zOiBQaMOibiB0w61jaCDEkeG7kyBiaeG7g3UgxJHhu5MgY2jhu4kgcGjhuqduIHRyxINtIHPhu5EgbMaw4bujbmcgdGhlbyBiaeG6v24gY2xhcml0eSoqDQpgYGB7cn0NCnAgJT4lIGdyb3VwX2J5KGNsYXJpdHkpICU+JSBzdW1tYXJpc2UobiA9IG4oKSkgJT4lDQogIGdncGxvdChhZXMoY2xhcml0eSxuKSkgKw0KICAgIGdlb21fY29sKGZpbGw9J3llbGxvdycpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGVyY2VudChuL2xlbmd0aChwJGNhcmF0KSkpLHZqdXN0ID0gMiwgY29sb3IgPSAncmVkJykgKw0KICAgIGxhYnMoeCA9ICdNw6B1IHPhuq9jJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQpUcuG7pWMgdHVuZyB0aOG7gyBoaeG7h24gY+G7mXQgc+G7kSBsxrDhu6NuZw0KDQpUcuG7pWMgaG/DoG5oIChtw6B1IHPhuq9jKSBn4buTbSBJMSxTSTIsU0kxLFZTMixWUzEsVlZTMixWVlMxLElGIGzDoCDEkeG7mSB0cm9uZyBzdeG7kXQgY+G7p2EgdmnDqm4ga2ltIGPGsMahbmcNCg0KQ8OhYyBj4buZdCB0aOG7gyBoaeG7h24gcGjhuqduIHRyxINtIHPhu5MgbMaw4bujbmcgdOG7q25nIGxv4bqhaSB0csOqbiB04buVbmcgc+G7kSBraW0gY8awxqFuZw0KDQpCaeG7g3UgxJHhu5MgMy4zIGNobyB0YSB0aOG6pXkga2ltIGPGsMahbmcgbG/huqFpOg0KDQorIEkxIGNoaeG6v20gJSB0aOG6pXAgbmjhuqV0IGzDoCAxLjQlDQorIFNJMiBjaGnhur9tIDE3JQ0KKyBTSTEgY2FvIG5o4bqldCBjaGnhur9tIDI0LjIlDQorIFZTMiBjaGnhur9tIDIyLjclDQorIFZTMSBjaGnhur9tIDE1LjElDQorIFZWUzIgY2hp4bq/bSA5LjQlDQorIFZWUzEgY2hp4bq/bSA2LjglDQorIElGIGNoaeG6v20gMy4zJQ0KDQojIyAqKklWLiBTbyBzw6FuaCBz4buRIGzGsOG7o25nIGdp4buvYSBjw6FjIGxv4bqhaSAga2ltIGPGsMahbmcgbmfhuqt1IG5oacOqbioqDQoNCiMjIyAqKjEuIEjDrG5oIDQuMTogQmnhu4N1IMSR4buTIHNvIHPDoW5oIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyBjaOG6pXQgdMOhYyBjw7MgbcOgdSBEIHbDoCBKKioNCg0KYGBge3J9DQpwMyA8LSBwICU+JSBncm91cF9ieShjdXQsIGNvbG9yKSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpIA0KcDMgJT4lIGdncGxvdChhZXMoeCA9IGN1dCwgeSA9IG4pKSArDQogIGdlb21fY29sKGRhdGEgPSBwMyAlPiUgZmlsdGVyKGNvbG9yID09ICdEJyksIGZpbGwgPSAncmVkJykgKw0KICBnZW9tX2NvbChkYXRhID0gcDMgJT4lIGZpbHRlcihjb2xvciA9PSAnSicpLCBmaWxsID0gJ2JsdWUnKQ0KYGBgDQoNClRy4bulYyB0dW5nIChuKSB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZw0KDQpUcuG7pWMgaG/DoG5oIChjdXQpIHRo4buDIGhp4buHbiBjaOG6pXQgbMaw4bujbmcgZ+G7k20gRmFpcixHb29kLFZlcnkgR29vZCxQcmVtaXVtLElkZWFsDQoNCkPhu5l0IG3DoHUgxJHhu48gdGjhu4MgaGnhu4duIG3DoHUgRA0KDQpD4buZdCBtw6B1IHhhbmggdGjhu4MgaGnhu4duIG3DoHUgSg0KDQoNClF1YSBiaeG7g3UgxJHhu5MgdGEgdGjhuqV5IGPDsyBz4buxIGNow6puaCBs4buHY2gga2jDoSBs4bubbiBnaeG7r2EgaGFpIG3DoHUga2ltIGPGsMahbmcgLGPhu5l0IG3DoHUgxJHhu48gbMOgIGtpbSBjxrDGoW5nIG3DoHUgRCBjw7Mgc+G7kSBsxrDhu6NuZyBn4bqlcCDEkcO0aSBraW0gY8awxqFuZyAgbcOgdSBKIGzDoCBj4buZdCBtw6B1IHhhbmggDQoNCiMjIyAqKjIuIEjDrG5oIDQuMjogQmnhu4N1IMSR4buTIHNvIHPDoW5oIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyBjaOG6pXQgbMaw4bujbmcgY2jhur8gdMOhYyBjw7MgxJHhu5kgdHJvbmcgc3Xhu5F0IFZTMiB2w6AgSTEqKg0KYGBge3IsIGVjaG8gPSBUUlVFfQ0KcDEgPC0gcCAlPiUgZ3JvdXBfYnkoY3V0LCBjbGFyaXR5KSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpIA0KcDEgJT4lIGdncGxvdChhZXMoeCA9IGN1dCwgeSA9IG4pKSArDQogIGdlb21fY29sKGRhdGEgPSBwMSAlPiUgZmlsdGVyKGNsYXJpdHkgPT0gJ1ZTMicpLCBmaWxsID0gJ3llbGxvdycpICsNCiAgZ2VvbV9jb2woZGF0YSA9IHAxICU+JSBmaWx0ZXIoY2xhcml0eSA9PSAnSTEnKSwgZmlsbCA9ICdyZWQnKQ0KYGBgDQoNClRy4bulYyB0dW5nIChuKSBz4buRIGzGsOG7o25nDQoNClRy4bulYyBob8OgbmggKGN1dCkgZ+G7k20gRmFpcixHb29kLFZlcnkgR29vZCxQcmVtaXVtLElkZWFsDQoNCkJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gaGFpIGxv4bqhaSBraW0gY8awxqFuZyBraMOhYyBuaGF1OiBj4buZdCBtw6B1IHbDoG5nIHRo4buDIGhp4buHbiBraW0gY8awxqFuZyBjw7MgxJHhu5kgdHJvbmcgc3Xhu5F0IFZTMiwgY+G7mXQgbcOgdSDEkeG7jyB0aOG7gyBoaeG7h24ga2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBJMSDEkcaw4bujYyB0aOG7kW5nIGvDqiB0aGVvIGNo4bqldCBsxrDGoW5nIGNo4bq/IHTDoWMgDQoNClF1YW4gc8OhdCBiaeG7g3UgxJHhu5MgY2hvIHRhIHRo4bqleSByw7Ugc+G7sSBjw6FjaCBiaeG7h3QgbOG7m24gduG7gSBz4buRIGzGsOG7o25nIGPhu6dhIGhhaSBsb+G6oWkga2ltIGPGsMahbmcgdHLDqm46IGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgVlMyIGPDsyBz4buRIGzGsMahbmcgZ+G6pXAgbmhp4buBdSBs4bqnbiBzbyB24bubaSBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgSTEgPT4gY2jhu6luZyB04buPIHRyw6puIHRo4buLIHRyxrDhu51uZyBsb+G6oWkga2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBJMSBraMO0bmcgxJFjIHBo4buVIGJp4bq/biBjaGnhur9tIHRo4buLIHBo4bqnbiBuaOG7jyB0csOqbiB04buVbmcgc+G7kS4NCg0KIyMjICoqMy4gSMOsbmggNC4zOiBCaeG7g3UgxJHhu5Mgc28gc8Ohbmggc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIG3DoHUgY8OzIMSR4buZIHRyb25nIHN14buRdCBTSTEgdsOgIFZWUzEqKg0KDQpgYGB7ciwgZWNobyA9IFRSVUV9DQpwMiA8LSBwICU+JSBncm91cF9ieShjbGFyaXR5LCBjb2xvcikgJT4lIHN1bW1hcmlzZShuID0gbigpKQ0KcDIgJT4lIGdncGxvdChhZXMoeCA9IGNvbG9yLCB5ID0gbikpICsNCiAgZ2VvbV9jb2woZGF0YSA9IHAyICU+JSBmaWx0ZXIoY2xhcml0eSA9PSAnU0kxJyksIGZpbGwgPSAneWVsbG93JykgKw0KICBnZW9tX2NvbChkYXRhID0gcDIgJT4lIGZpbHRlcihjbGFyaXR5ID09ICdWVlMxJyksIGZpbGwgPSAnb3JhbmdlJykNCmBgYA0KDQpUcuG7pWMgdHVuZyhuKSBz4buRIGzGsOG7o25nDQoNClRy4bulYyBob8OgbmggKGNvbG9yKSBn4buTbSBjw6FjIG3DoHUgRCxFLEYsRyxILEksSg0KDQpCaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIDIgbG/huqFpIGtpbSBjxrDGoW5nOg0KDQorIEPhu5l0IG3DoHUgdsOgbmcgdGjhu4MgaGnhu4duIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgU0kxDQorIEPhu5l0IG3DoHUgY2FtIHRo4buDIGhp4buHbiBraW0gY8awxqFuZyBjw7MgxJHhu5kgdHJvbmcgc3Xhu5F0IFZWUzENCisgTmjDrG4gdsOgbyBiaeG7g3UgxJHhu5MgdGEgdGjhuqV5IMSRxrDhu6NjIGtpbSBjxrDGoW5nIMSR4buZIHRyb25nIHN14buRdCBTSTEgY2hp4bq/bSBz4buRIGzGsOG7o25nIG5oaeG7gXUgaMahbiBraW0gY8awxqFuZyDEkeG7mSB0cm9uZyBzdeG7kXQgVlZTMQ0KDQojIyMgKio0LiBIw6xuaCA0LjQ6IEJp4buDdSDEkeG7kyBzbyBzw6FuaCBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gbcOgdSBjw7MgxJHhu5kgdHJvbmcgc3Xhu5F0IFZTMSB2w6AgVlMyKioNCg0KYGBge3IsIGVjaG8gPSBUUlVFfQ0KcDIgJT4lIGdyb3VwX2J5KGNsYXJpdHksIGNvbG9yKSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpICU+JSANCmdncGxvdChhZXMoeCA9IGNvbG9yLCB5ID0gbikpICsNCiAgZ2VvbV9jb2woZGF0YSA9IHAyICU+JSBmaWx0ZXIoY2xhcml0eSA9PSAnVlMyJyksIGZpbGwgPSAneWVsbG93JykgKw0KICBnZW9tX2NvbChkYXRhID0gcDIgJT4lIGZpbHRlcihjbGFyaXR5ID09ICdWUzEnKSwgZmlsbCA9ICdzYWxtb24nKQ0KYGBgDQoNCg0KDQpCaeG7g3UgxJHhu5MgNC40IGfhu5NtIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgVlMyIGPhu5l0IG3DoHUgdsOgbmcsIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgVlMxIGPhu5l0IG3DoHUgaOG7k25nIMSR4bqtbS4gQ2hvIHRo4bqleSBraW0gY8awxqFuZyBsb+G6oWkgVlMxIGNoaeG6v20gc+G7kSBsxrDhu6NuZyBuaGnhu4F1IGjGoW4gVlMyIHR1eSBuaGnDqm4gc+G7kSBsxrDhu6NuZyBuaGnhu4F1IGjGoW4ga2jDtG5nIMSRw6FuZyBr4buDDQoNCiMjICoqVi4gU28gc8OhbmggdGhlbyBuaMOzbSBraW0gY8awxqFuZyB0aGVvIHPhu5EgbMaw4bujbmcqKg0KDQojIyMgKioxLiBIw6xuaCA1LjE6IEJp4buDdSDEkeG7kyBzbyBzw6FuaCBuaMOzbSBraW0gY8awxqFuZyB0aGVvIG3DoHUgdsOgIGNo4bqldCBsxrDhu6NuZyBjaOG6vyB0w6FjKioNCg0KVGEgY8OzIG5ow7NtIGJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIHThu6tuZyBsb+G6oWkgY2jhur8gdMOhYyBraMOhYyBuaGF1IHThu6sgxJHDsyBjw7MgdGjhu4MgZOG7hSBkw6BuZyBxdWFuIHPDoXQgc28gc8OhbmggZ2nhu69hIGPDoWMgbcOgdSBj4bunYSBsb+G6oWkgY2jhur8gdMOhYyBuw6B5IGfhu5NtIEQsRSxGLEcsSCxJLEogY8O5bmcgduG7m2kgY8OhYyBjaOG6pXQgbMaw4bujbmcgRmFpcixHb29kLCBWZXJ5IEdvb2QsIFByZW1pdW0sSWRlYWwNCg0KYGBge3IsIGVjaG8gPSBUUlVFfQ0KcCAlPiUgZ3JvdXBfYnkoY3V0LGNvbG9yKSAlPiUgc3VtbWFyaXNlKG49bigpLC5ncm91cHMgPSAnZHJvcCcpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBjb2xvcix5ID0gbikpICsNCiAgICBnZW9tX2NvbChmaWxsPSJibGFjayIpICsNCiAgICBmYWNldF93cmFwKH5jdXQpICsNCiAgICBsYWJzKHggPSAnTG/huqFpJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQoNCg0KQ8WpbmcgbmjGsCBiaeG7g3UgxJHhu5MgdHLDqm4gYmnhu4N1IMSR4buTIGTGsOG7m2kgxJHDonkgY8WpbmcgZ2nDunAgdGEgcXVhbiBzw6F0IHbDoCBzbyBzw6FuaCBuaOG7r25nIHbhuqduIMSR4buBIHRyw6puIG5oxrBuZyB24bubaSBjw6J1IGzhu4duaCAqKmdlb21fdGV4dChhZXMobGFiZWwgPSBuKSx2anVzdCA9IDIsIGNvbG9yID0gJ3llbGxvdycpKiogdGEgY8OzIHRo4buDIHRo4bqleSByw7Ugc+G7kSBsaeG7h3UgbeG7mXQgY8OhY2ggY+G7pSB0aOG7gy4NCg0KYGBge3IsIGVjaG8gPSBUUlVFfQ0KcCAlPiUgZ3JvdXBfYnkoY3V0LGNvbG9yKSAlPiUgc3VtbWFyaXNlKG49bigpLC5ncm91cHMgPSAnZHJvcCcpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBjb2xvcix5ID0gbikpICsNCiAgICBnZW9tX2NvbCggZmlsbD0gJ3B1cnBsZScpICsNCiAgICBmYWNldF93cmFwKH5jdXQpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksdmp1c3QgPSAyLCBjb2xvciA9ICd5ZWxsb3cnKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KDQojIyMgKioyLiBIw6xuaCA1LjI6IEJp4buDdSDEkeG7kyBzbyBzw6FuaCBuaMOzbSBraW0gY8awxqFuZyB0aGVvIMSR4buZIHRyb25nIHN14buRdCB2w6AgY2jhuqV0IGzGsOG7o25nIGNo4bq/IHTDoWMqKg0KDQpUYSBjw7MgbmjDs20gYmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gdOG7q25nIGxv4bqhaSBjaOG6vyB0w6FjIGtow6FjIG5oYXUgdOG7qyDEkcOzIGPDsyB0aOG7gyBk4buFIGTDoG5nIHF1YW4gc8OhdCBzbyBzw6FuaCBnaeG7r2EgY8OhYyBsb+G6oWkgxJHhu5kgdHJvbmcgc3Xhu5F0IGtpbSBjxrDGoW5nIGPhu6dhIGxv4bqhaSBjaOG6vyB0w6FjIG7DoHkgZ+G7k20gSTEsU0kyLFNJMSxWUzIsVlMxLFZWUzIsVlZTMSxJRiBjw7luZyB24bubaSBjw6FjIGNo4bqldCBsxrDhu6NuZyBGYWlyLEdvb2QsIFZlcnkgR29vZCwgUHJlbWl1bSxJZGVhbA0KDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCnAgJT4lIGdyb3VwX2J5KGN1dCxjbGFyaXR5KSAlPiUgc3VtbWFyaXNlKG49bigpLC5ncm91cHMgPSAnZHJvcCcpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBjbGFyaXR5LHkgPSBuKSkgKw0KICAgIGdlb21fY29sKGZpbGw9InR1cnF1b2lzZSIpICsNCiAgICBmYWNldF93cmFwKH5jdXQpICsNCiAgICBsYWJzKHggPSAnTG/huqFpJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQoNCg0KQ8WpbmcgbmjGsCBiaeG7g3UgxJHhu5MgdHLDqm4gYmnhu4N1IMSR4buTIGTGsOG7m2kgxJHDonkgY8WpbmcgZ2nDunAgdGEgcXVhbiBzw6F0IHbDoCBzbyBzw6FuaCBuaOG7r25nIHbhuqduIMSR4buBIHRyw6puIG5oxrBuZyB24bubaSBjw6J1IGzhu4duaCAqKmdlb21fdGV4dChhZXMobGFiZWwgPSBuKSx2anVzdCA9IDIsIGNvbG9yID0gJ3JlZCcpKiogdGEgY8OzIHRo4buDIHRo4bqleSByw7Ugc+G7kSBsaeG7h3UgbeG7mXQgY8OhY2ggY+G7pSB0aOG7gy4NCg0KYGBge3IsIGVjaG8gPSBUUlVFfQ0KcCAlPiUgZ3JvdXBfYnkoY2xhcml0eSxjdXQpICU+JSBzdW1tYXJpc2Uobj1uKCksLmdyb3VwcyA9ICdkcm9wJykgJT4lDQogIGdncGxvdChhZXMoeCA9IGNsYXJpdHkseSA9IG4pKSArDQogICAgZ2VvbV9jb2woIGZpbGw9ICdncmVlbicpICsNCiAgICBmYWNldF93cmFwKH4gY3V0KSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMiwgY29sb3IgPSAncmVkJykgKw0KICAgIGxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ1Phu5EgbMaw4bujbmcnKQ0KYGBgDQoNCiMjIyAqKjMuIEjDrG5oIDUuMzogQmnhu4N1IMSR4buTIHNvIHPDoW5oIG5ow7NtIGtpbSBjxrDGoW5nIHRoZW8gbcOgdSB2w6AgxJHhu5kgdHJvbmcgc3Xhu5F0KioNCg0KVGEgY8OzIG5ow7NtIGJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIHThu6tuZyBsb+G6oWkgdHJvbmcgc3Xhu5F0IGtow6FjIG5oYXUgdOG7qyDEkcOzIGPDsyB0aOG7gyBk4buFIGTDoG5nIHF1YW4gc8OhdCBzbyBzw6FuaCBnaeG7r2EgY8OhYyBtw6B1IGPhu6dhIGxv4bqhaSB0cm9uZyBzdeG7kXQgbsOgeSBn4buTbSBELEUsRixHLEgsSSxKIHbhu5tpIHThu6tuZyBsb+G6oWkgdHJvbmcgc3Xhu5F0IGtpYSBJMSxTSTIsU0kxLFZTMixWUzEsVlZTMixWVlMxLElGDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCnAgJT4lIGdyb3VwX2J5KGNsYXJpdHksY29sb3IpICU+JSBzdW1tYXJpc2Uobj1uKCksLmdyb3VwcyA9ICdkcm9wJykgJT4lDQogIGdncGxvdChhZXMoeCA9IGNvbG9yLHkgPSBuKSkgKw0KICAgIGdlb21fY29sKGZpbGw9InJlZCIpICsNCiAgICBmYWNldF93cmFwKH5jbGFyaXR5KSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KQ8WpbmcgbmjGsCBiaeG7g3UgxJHhu5MgdHLDqm4gYmnhu4N1IMSR4buTIGTGsOG7m2kgxJHDonkgY8WpbmcgZ2nDunAgdGEgcXVhbiBzw6F0IHbDoCBzbyBzw6FuaCBuaOG7r25nIHbhuqduIMSR4buBIHRyw6puIG5oxrBuZyB24bubaSBjw6J1IGzhu4duaCAqKmdlb21fdGV4dChhZXMobGFiZWwgPSBuKSx2anVzdCA9IDIsIGNvbG9yID0gJ3doaXRlJykqKiB0YSBjw7MgdGjhu4MgdGjhuqV5IHLDtSBz4buRIGxp4buHdSBt4buZdCBjw6FjaCBj4bulIHRo4buDLiANCg0KYGBge3IsIGVjaG8gPSBUUlVFfQ0KcCAlPiUgZ3JvdXBfYnkoY2xhcml0eSxjb2xvcikgJT4lIHN1bW1hcmlzZShuPW4oKSwuZ3JvdXBzID0gJ2Ryb3AnKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY29sb3IseSA9IG4pKSArDQogICAgZ2VvbV9jb2woIGZpbGw9ICdicm93bicpICsNCiAgICBmYWNldF93cmFwKH5jbGFyaXR5KSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMiwgY29sb3IgPSAnd2hpdGUnKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KIyMgKipWSS4gU28gc8OhbmggbmjDs20ga2ltIGPGsMahbmcgdGhlbyBt4bupYyBnacOhIHRydW5nIGLDrG5oKioNCg0KIyMjICoqMS4gSMOsbmggNi4xOiBCaeG7g3UgxJHhu5Mgc28gc8OhbmggbmjDs20ga2ltIGPGsMahbmcgKG3DoHUgdsOgIGNo4bqldCBsxrDhu6NuZyBjaOG6vyB0w6FjKSoqDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCnAgJT4lIGdyb3VwX2J5KGN1dCxjb2xvcikgJT4lIHN1bW1hcmlzZShtID0gbWVhbihwcmljZSksLmdyb3VwcyA9ICdkcm9wJykgJT4lDQogIGdncGxvdChhZXMoeCA9IGNvbG9yLHkgPSBtKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJykgKw0KICAgIGZhY2V0X3dyYXAofmN1dCApICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobSkpKSArDQogICAgbGFicyh4ID0gJ0NvbG9yICcsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KVHLhu6VjIHR1bmcgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcNCg0KVHLhu6VjIGhvw6BuaCBiaeG7g3UgZGnhu4VuIGPDoWMgbcOgdSBn4buTbSBELEUsRixHLEgsSSxKDQoNCkJp4buDdSDEkeG7kyBuaMOzbSA2LjEgbMOgIHRo4buRbmcga8OqIG3hu6ljIGdpw6EgdHJ1bmcgYsOsbmggY+G7p2EgdOG7q25nIGxv4bqhaSBraW0gY8awxqFuZyBjaOG6vyB0w6FjIHRoZW8gdOG6pXQgY+G6oyBjw6FjIG3DoHUgY8OzIMSR4bqneSDEkeG7pyBz4buRIGxp4buHdSAgdHLDqm4gdOG7q25nIGJp4buDdSDEkeG7kw0KDQojIyMgKioyLiBIw6xuaCA2LjI6IEJp4buDdSDEkeG7kyBzbyBzw6FuaCBuaMOzbSBraW0gY8awxqFuZyAoxJHhu5kgdHJvbmcgc3Xhu5F0IHbDoCBjaOG6pXQgbMaw4bujbmcgY2jhur8gdMOhYykqKg0KDQpgYGB7ciwgZWNobyA9IFRSVUV9DQpwICU+JSBncm91cF9ieShjdXQsY2xhcml0eSkgJT4lIHN1bW1hcmlzZShtID0gbWVhbihwcmljZSksIC5ncm91cHMgPSAnZHJvcCcpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBjbGFyaXR5LHkgPSBtKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJykgKw0KICAgIGZhY2V0X3dyYXAofmN1dCApICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobSkpKSArDQogICAgbGFicyh4ID0gJ2NsYXJpdHkgJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQoNCg0KQmnhu4N1IMSR4buTIDYuMiB0aOG7gyBoaeG7h24gc+G7sSBzbyBzw6FuaCBt4bupYyBnacOhIHRydW5nIGLDrG5oIGPhu6dhIHThu6tuZyBsb+G6oWkga2ltIGPGsMahbmcgY2jhur8gdMOhYyB0aGVvIG3DoHUgdsOgIMSR4buZDQoNCnRyb25nIHN14buRdA0KDQojIyMgKiozLiBIw6xuaCA2LjM6IEJp4buDdSDEkeG7kyBzbyBzw6FuaCBuaMOzbSBraW0gY8awxqFuZyAobcOgdSB2w6AgxJHhu5kgdHJvbmcgc3Xhu5F0KSoqDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCnAgJT4lIGdyb3VwX2J5KGNsYXJpdHksY29sb3IpICU+JSBzdW1tYXJpc2UobSA9IG1lYW4ocHJpY2UpLCAuZ3JvdXBzPSdkcm9wJykgJT4lDQogIGdncGxvdChhZXMoeCA9IGNvbG9yLHkgPSBtKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJykgKw0KICAgIGZhY2V0X3dyYXAofmNsYXJpdHkpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobSkpKSArDQogICAgbGFicyh4ID0gJ0NvbG9yICcsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KDQoNCkJp4buDdSDEkeG7kyA2LjMgdGjhu4MgaGnhu4duIHPhu7Egc28gc8OhbmggbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCBj4bunYSB04burbmcgbG/huqFpIGtpbSBjxrDGoW5nIGNo4bq/IHTDoWMgdGhlbyB04bqldCBj4bqjIGPDoWMgxJHhu5kNCg0KdHJvbmcgc3Xhu5F0IHbDoCBtw6B1ICANCg0KIyMgKipWSUkuIFBow6JuIHTDrWNoIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyAgbeG7qWMgZ2nDoSB2w6Aga2jhu5FpIGzGsOG7o25nIGNhcmF0KioNCg0KIyMjICoqMS4gSMOsbmggNy4xOiBCSeG7g3UgxJHhu5MgcGjDom4gdMOtY2ggc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGto4buRaSBsxrDhu6NuZyoqDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCnAgPC1wICU+JSBtdXRhdGUoQ2FyYXQgPSBjdXQoY2FyYXQsNSwgbGFiZWwgPSBjKCdy4bqldCBuaOG7jycsICduaOG7jycsJ3bhu6thJywnbOG7m24nLCdy4bqldCBs4bubbicpKSkNCnAgJT4lIGdncGxvdChhZXMoeCA9IENhcmF0KSkgKw0KICBnZW9tX2JhcihmaWxsID0gJ3NhbG1vbicpDQpgYGANCg0KDQoNCkJp4buDdSDEkeG7kyA3LjEgY2hvIHRo4bqleSBraOG7kWkgbMaw4bujbmcgY2FyYXQgxJHGsOG7o2MgY2hpYSBsw6BtIDUgbG/huqFpOiBy4bqldCBuaOG7jywgbmjhu48sIHbhu6thLGzhu5tuLHLhuqV0IGzhu5tuLiBMb+G6oWkgcuG6pXQgbmjhu48gY2hp4bq/bSBz4buRIGzGsOG7o25nIG5oaeG7gXUgbmjhuqV0LCB0cm9uZyBraGkgxJHDsyBsb+G6oWkgbOG7m24gdsOgIHLhuqV0IGzhu5tuIGjhuqd1IG5oxrAgbMOgIGtow7RuZyBjw7MuIFbhuq15IHRyw6puIHRo4buLIHRyxrDhu51uZyBjYXJhdCBsb+G6oWkgbOG7m24gdsOgIHLhuqV0IGzhu5tuIGzDoCBj4buxYyBrw6wgaGnhur9tIHNvIHbhu5tpIGPDoWMgbG/huqFpIGPDsm4gbOG6oWkNCg0KIyMjICoqMi4gSMOsbmggNy4yOiBCSeG7g3UgxJHhu5MgcGjDom4gdMOtY2ggc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIG3hu6ljIGdpw6EqKg0KDQpgYGB7ciwgZWNobyA9IFRSVUV9DQpwIDwtIHAgJT4lIG11dGF0ZShQcmljZSA9IGN1dChwcmljZSw1LCBsYWJlbCA9IGMoJ3LhuqV0IHRo4bqlcCAnLCAndGjhuqVwJywndGInLCdjYW8nLCdy4bqldCBjYW8nKSkpDQpwICU+JSBnZ3Bsb3QoYWVzKHggPSBQcmljZSkpICsNCiAgZ2VvbV9iYXIoZmlsbCA9ICdwaW5rJykNCmBgYA0KDQpUcuG7pWMgdHVuZyhjb3VudCkgdGjhu4MgaGnhu4duIG3hu6ljIGdpw6ENCg0KVHLhu6VjIGhvw6BuaChwcmljZSkgZ+G7k20gcuG6pXQgdGjhuqVwLCB0aOG6pXAsIHRydW5nIGLDrG5oLCBjYW8sIHLhuqV0IGNhbw0KDQpCaeG7g3UgxJHhu5MgNy4yIGNobyB0YSB0aOG6pXkgbeG7qWMgZ2nDoSBraW0gY8awxqFuZyBu4bqxbSDhu58gdHLhu6VjIHR1bmcgdGjhu4MgaGnhu4duIG3hu6ljIGdpw6EgbG/huqFpIHLhuqV0IG5o4buPIHRo4bqlcCBoxqFuIGPDoWMgbG/huqFpIGPDsm4gbOG6oWkgcuG6pXQgbmhp4buBdSBs4bqnbiwga2ltIGPGsMahbmcgbG/huqFpIHLhuqV0IGzhu5tuIHRow6wgaGnhur9tIG7Dqm4gZ2nDoSBz4bq9IGNhbyBoxqFuDQoNCiMjIyAqKjMuIEjDrG5oIDcuMyoqDQoNCmBgYHtyIGVjaG89VFJVRSwgd2FybmluZz1GQUxTRX0NCnAgPC0gcCAlPiUgbXV0YXRlKGNvbG9yX2NvZGUgPSBjYXNlX3doZW4oDQogICAgY29sb3IgPT0gIkQiIHwgY29sb3IgPT0gIkUiIHwgY29sb3IgPT0gIkYiIH4gMSwNCiAgICBjb2xvciA9PSAiRyIgfCBjb2xvciA9PSAiSCIgfCBjb2xvciA9PSAiSSIgfCBjb2xvciA9PSAiSiIgfiAyKSkNCg0KcCA8LSBtdXRhdGUocCwgY29sb3JDID0gY3V0KGNvbG9yX2NvZGUsIDIsIGxhYmVsID0gYygna2jDtG5nIG3DoHUnLCAnZ+G6p24gbmjGsCBraMO0bmcgbcOgdScpKSkNCg0KcCAlPiUgZ3JvdXBfYnkoY29sb3JDKSAlPiUgc3VtbWFyaXNlKG49bigpKSAlPiUNCiAgZ2dwbG90KGFlcyhjb2xvckMsIG4pKSArDQogICAgZ2VvbV9jb2woZmlsbCA9ICdyZWQnKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLCB2anVzdCA9IDAsIGNvbG9yID0gJ2JsYWNrJykgKw0KICAgIHhsYWIoJ03DoHUgc+G6r2MnKSArDQogICAgeWxhYignU+G7kSBsxrDhu6NuZyAodmnDqm4pJykgKyANCiAgICBsYWJzKCkNCmBgYA0KDQpUcuG7pWMgdHVuZyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZw0KDQpUcuG7pWMgaG/DoG5oIHRo4buDIGhp4buHbiBtw6B1IHPEg2MgZ+G7k20ga2jDtG5nIG3DoHUgdsOgIGfhuqduIG5oxrAga2jDtG5nIG3DoHUNCg0KVGEgdGjhuqV5IMSRxrDhu6NjIHPhu5EgbMaw4bujbmcgdmnDqm4gZ+G6p24gbmjGsCBraMO0bmcgbcOgdSBjaGnhur9tIHPhu5EgbMaw4bujbmcgbmhp4buBdSBoxqFuIHbDrCB0aOG6vyBwaOG6p24gbOG7m24gY2FyYXQgY8OzIGThuqFuZyB0cm9uZyBzdeG7kXQNCg0KIyMjICoqNC4gSMOsbmggNy40KioNCg0KYGBge3J9DQpwIDwtIGRpYW1vbmRzIA0KcCA8LSBwICU+JSBtdXRhdGUoZGVwdGhDID0gY3V0KGRlcHRoLDUsIGxhYmVsID0gYygnU8OidScsJ0tow6Egc8OidScsJ1RydW5nIGLDrG5oJywnS2jDoSBuw7RuZycsJ07DtG5nJykpKQ0KcCAlPiUgZ2dwbG90KGFlcyh4ID0gZGVwdGhDKSkgKw0KICBnZW9tX2JhcihmaWxsID0gJ3JlZCcpDQpgYGANCg0KDQpCaeG7g3UgxJHhu5MgNy40IHRo4buDIGhp4buHbiDEkeG7mSBuw7RuZyBzw6J1IGtoaSBj4bqvdCB2acOqbiBraW0gY8awxqFuZw0KDQojIyAqKlZJSUkuIEJp4buDdSDEkeG7kyBjw6FjIGNo4buJIHPhu5EgY+G7pSB0aOG7gyB0aGVvIHThu6tuZyBiaeG6v24qKg0KDQojIyMgKioxLiBIw6xuaCA4LjE6IE1lZGlhbih0cnVuZyB24buLKSBj4bunYSBiaeG6v24g4oCYY2FyYXTigJkqKg0KDQpgYGB7cn0NCnAgJT4lIGdyb3VwX2J5KGN1dCkgJT4lIHN1bW1hcmlzZShtPSBtZWRpYW4oY2FyYXQpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY3V0LHkgPSBtKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChtLDIpKSwgdmp1c3QgPSAyLCBjb2xvciA9ICd5ZWxsb3cnKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnTWVkaWFuJykNCmBgYA0KDQoNCg0KQ8OidSBs4buHbmggdHLDqm4gY2hvIHRhIG3hu5l0IGJp4buDdSDEkcOyIGThuqFuZyBCYXIgQ2hhcnQgduG7m2kgdHLhu6VjIGhvw6BuaCBsw6AgY8OhYyBsb+G6oWkga2ltIGPGsMahbmcgxJHGsOG7o2MgY2hpYSB0aGVvIGJp4bq/biDigJhjdXTigJkgYmFvIGfhu5NtIDUgbG/huqFpIGzhuqduIGzGsOG7o3QgbMOgIOKAmEZhaXLigJks4oCYR29vZOKAmSzigJhWZXJ5IEdvb2TigJks4oCYUHJlbWl1beKAmSzigJhJZGVhbOKAmSwgdHLhu6VjIHR1bmcgbMOgIHRydW5nIHbhu4sgxJHhu5kgbOG7m24gY+G7p2EgYmnhur9uIOKAmENhcmF04oCZIC4gQ+G7pSB0aOG7gyBuaMawIHNhdToNCg0KKyBUcnVuZyB24buLIGNhcmF0IGPhu6dhIGxv4bqhaSBraW0gY8awxqFuZyDigJkgRmFpcuKAmSBsw6AgMSAoNTAlIHPhu5Ega2ltIGPGsMahbmcgbG/huqFpIEZhaXIgY8OzIMSR4buZIGzhu5tuIGNhcmF0IGTGsOG7m2kgMSB2w6AgNTAlIGPDsm4gbOG6oWkgY8OzIMSR4buZIGzhu5tuIGNhcmF0IGzhu5tuIGjGoW4gMSApDQorIFRydW5nIHbhu4sgY2FyYXQgY+G7p2EgbG/huqFpIGtpbSBjxrDGoW5nIOKAmSBHb29k4oCZIGzDoCAwLjgyICg1MCUgc+G7kSBraW0gY8awxqFuZyBsb+G6oWkgR29vZCBjw7MgxJHhu5kgbOG7m24gY2FyYXQgZMaw4bubaSAwLjgyIHbDoCA1MCUgY8OybiBs4bqhaSBjw7MgxJHhu5kgbOG7m24gY2FyYXQgbOG7m24gaMahbiAwLjgyICkNCisgVHJ1bmcgduG7iyBjYXJhdCBj4bunYSBsb+G6oWkga2ltIGPGsMahbmcg4oCZIFZlcnkgR29vZOKAmSBsw6AgMC43MSAoNTAlIHPhu5Ega2ltIGPGsMahbmcgbG/huqFpIFZlcnkgR29vZCBjw7MgxJHhu5kgbOG7m24gY2FyYXQgZMaw4bubaSAwLjcxIHbDoCA1MCUgY8OybiBs4bqhaSBjw7MgxJHhu5kgbOG7m24gY2FyYXQgbOG7m24gaMahbiAwLjcxICkNCisgVHJ1bmcgduG7iyBjYXJhdCBj4bunYSBsb+G6oWkga2ltIGPGsMahbmcg4oCYUHJlbWl1beKAmSBsw6AgMC44NiAoNTAlIHPhu5Ega2ltIGPGsMahbmcgbG/huqFpIFByZW1pdW0gY8OzIMSR4buZIGzhu5tuIGNhcmF0IGTGsOG7m2kgMC44NiB2w6AgNTAlIGPDsm4gbOG6oWkgY8OzIMSR4buZIGzhu5tuIGNhcmF0IGzhu5tuIGjGoW4gMC44NiApDQorIFRydW5nIHbhu4sgY2FyYXQgY+G7p2EgbG/huqFpIGtpbSBjxrDGoW5nIOKAmElkZWFs4oCZIGzDoCAwLjU0ICg1MCUgc+G7kSBraW0gY8awxqFuZyBsb+G6oWkgSWRlYWwgY8OzIMSR4buZIGzhu5tuIGNhcmF0IGTGsOG7m2kgMC41NCB2w6AgNTAlIGPDsm4gbOG6oWkgY8OzIMSR4buZIGzhu5tuIGNhcmF0IGzhu5tuIGjGoW4gMC41NCApIA0KDQojIyMgKioyLiBIw6xuaCA4LjI6IE1lYW4gKGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmgpIGPhu6dhIGJp4bq/biDigJhwcmljZeKAmSoqDQpgYGB7cn0NCnAgJT4lIGdyb3VwX2J5KGN1dCkgJT4lIHN1bW1hcmlzZShtPSBtZWFuKHByaWNlKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGN1dCx5ID0gbSkpICsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobSwyKSksIHZqdXN0ID0gMiwgY29sb3IgPSAneWVsbG93JykgKw0KICAgIGxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ01lYW4nKQ0KYGBgDQoNCg0KDQpDw6J1IGzhu4duaCB0csOqbiBjaG8gdGEgbeG7mXQgxJHhu5MgdGjhu4sgZOG6oW5nIEJhciBDaGFydCB24bubaSB0cuG7pWMgaG/DoG5oIGzDoCBjw6FjIGxv4bqhaSBraW0gY8awxqFuZyDEkcaw4bujYyBjaGlhIHRoZW8gYmnhur9uIOKAmGN1dOKAmSBiYW8gZ+G7k20gNSBsb+G6oWkgbOG6p24gbMaw4bujdCBsw6Ag4oCYRmFpcuKAmSzigJhHb29k4oCZLOKAmFZlcnkgR29vZOKAmSzigJhQcmVtaXVt4oCZLOKAmElkZWFs4oCZLCB0cuG7pWMgdHVuZyBsw6AgdHJ1bmcgYsOsbmggxJHhu5kgbOG7m24gY+G7p2EgYmnhur9uIOKAmFByaWNl4oCZIC4gQ+G7pSB0aOG7gyBuaMawIHNhdToNCg0KKyBLaW0gY8awxqFuZyBGYWlyIGPDsyDEkeG7mSBs4bubbiB0cnVuZyBiw6xuaCBj4bunYSBiaeG6v24g4oCYUHJpY2XigJkgbMOgIDogNDM1OC43Ng0KKyBLaW0gY8awxqFuZyBHb29kIGPDsyDEkeG7mSBs4bubbiB0cnVuZyBiw6xuaCBj4bunYSBiaeG6v24g4oCYUHJpY2XigJkgbMOgIDogMzkyOC44Ng0KKyBLaW0gY8awxqFuZyBWZXJ5IEdvb2QgY8OzIMSR4buZIGzhu5tuIHRydW5nIGLDrG5oIGPhu6dhIGJp4bq/biDigJhQcmljZeKAmSBsw6AgOiAzOTgxLjc2DQorIEtpbSBjxrDGoW5nIFByZW1pdW0gY8OzIMSR4buZIGzhu5tuIHRydW5nIGLDrG5oIGPhu6dhIGJp4bq/biDigJhQcmljZeKAmSBsw6AgOiA0NTg0LjI2DQorIEtpbSBjxrDGoW5nIElkZWFsIGPDsyDEkeG7mSBs4bubbiB0cnVuZyBiw6xuaCBj4bunYSBiaeG6v24g4oCYUHJpY2XigJkgbMOgIDogMzQ1Ny41NA0KDQo=