Urban Business

Midterm Exam

Logo

1 Introduction

Dalam ekonomi perkotaan yang dinamis, bisnis dipengaruhi oleh kepadatan penduduk, preferensi konsumen, teknologi, dan persaingan pasar. Memahami faktor penentu pendapatan bulanan—seperti pemasaran, harga, tenaga kerja, pengalaman manajerial, dan kepuasan pelanggan—penting untuk keputusan strategis. Kinerja bisnis berbeda antar kota dan sektor (ritel, teknologi, manufaktur, makanan & minuman), sehingga analisis deskriptif dan visualisasi data dibutuhkan untuk melihat pola pendapatan dan variasinya. Melalui analisis ini, organisasi dapat menemukan kesenjangan kinerja serta peluang untuk mengoptimalkan strategi pemasaran, harga, dan manajemen sumber daya manusia. Dari permasalah ini menggunakan tampilan visualisasi data

2 Data set

library(readr)
library(DT)

# 2️⃣ Baca file CSV dari lokasi kamu
data <- read_csv("C:/Users/Iyan/Downloads/Midterm Exam.csv")

# 3️⃣ Tampilkan tabel interaktif (10 baris per halaman)
datatable(
  data,
  options = list(pageLength = 10),  # tampil 10 baris per halaman
  caption = "Tabel Interaktif Data CSV"
)

3 Data Visualization

3.1 Bar Chart

library(ggplot2)
library(readr)
library(dplyr)
library(scales)
library(showtext)

#  Font Google agar tampilan profesional
font_add_google("Poppins", "poppins")
showtext_auto()

#  Baca data
data <- read_csv("C:/Users/Iyan/Downloads/Midterm Exam.csv")

#  Hitung rata-rata pendapatan per kota
avg_city <- data %>%
  group_by(City) %>%
  summarise(AvgRevenue = mean(MonthlyRevenue, na.rm = TRUE)) %>%
  arrange(desc(AvgRevenue))

# Bar chart 
ggplot(avg_city, aes(x = reorder(City, AvgRevenue), y = AvgRevenue, fill = AvgRevenue)) +
  geom_col(width = 0.65, show.legend = FALSE) +
  geom_text(
    aes(label = paste0("Rp ", format(round(AvgRevenue, 1), big.mark = ".", decimal.mark = ","))),
    vjust = -0.4, family = "poppins", size = 4.2, fontface = "bold", color = "black"
  ) +
  scale_fill_gradient(low = "cyan", high = "cornflowerblue") +
  scale_y_continuous(
    limits = c(0, 200),  # 🔹 Batasi sumbu Y sampai 200
    breaks = seq(0, 200, by = 25),
    labels = comma_format(big.mark = ".", decimal.mark = ",")
  ) +
  labs(
    title = "Rata-rata Pendapatan Bulanan per Kota",
    subtitle = "Visualisasi menunjukkan rata-rata kinerja bisnis di setiap kota",
    x = "Kota",
    y = "Rata-rata Pendapatan (Rp)",
    caption = "Sumber: Dataset Midterm Exam"
  ) +
  theme_minimal(base_family = "poppins") +
  theme(
    plot.title = element_text(size = 18, face = "bold", color = "#003566", hjust = 0.5),
    plot.subtitle = element_text(size = 13, color = "#555555", hjust = 0.5, margin = margin(b = 10)),
    axis.text.x = element_text(size = 12, face = "bold", color = "#003049"),
    axis.text.y = element_text(size = 11, color = "#555555"),
    axis.title.x = element_text(size = 12, face = "bold", margin = margin(t = 10)),
    axis.title.y = element_text(size = 12, face = "bold", margin = margin(r = 10)),
    panel.grid.major.x = element_blank(),
    panel.grid.minor = element_blank(),
    plot.caption = element_text(size = 9, color = "#777777", hjust = 1, margin = margin(t = 10))
  ) +
  coord_cartesian(ylim = c(0, 200))  # 🔹 Tambahan agar sumbu Y akurat dan tidak memotong data

Insight :

Kota Jakarta memiliki rata-rata pendapatan bulanan tertinggi, sementara Kota Makassar memiliki rata-rata pendapatan bulanan terendah. Namun, variasi pendapatan antarkota relatif kecil, menunjukkan distribusi pendapatan yang cukup seimbang di lima kota tersebut.

3.2 Histogram

library(readr)
library(ggplot2)
ggplot(data, aes(x = MonthlyRevenue)) +
  geom_histogram(
    bins = 20,
    fill = "darkseagreen", 
    color = "white",
    alpha = 0.85
  ) +
  labs(
    title = "Distribusi Pendapatan Bisnis (Monthly Revenue)",
    x = "Pendapatan Bulanan (Juta)",
    y = "Frekuensi"
  ) +
  theme_minimal(base_size = 13)

Insight :

Sebagian besar bisnis memiliki pendapatan bulanan sekitar 150-200 juta rupiah. Distribusi data tampak normal dan seimbang menunjukkan bahwa pendapatan bisnis relatif merata tanpa banyak nilai ekstrem.

3.3 Pie Chart

library(ggplot2)
library(readr)
library(dplyr)

# Hitung total pendapatan per jenis bisnis
data_pie <- data %>%
  group_by(BusinessType) %>%
  summarise(TotalRevenue = sum(MonthlyRevenue, na.rm = TRUE)) %>%
  mutate(Percentage = round(TotalRevenue / sum(TotalRevenue) * 100, 1))

# Buat Pie Chart
ggplot(data_pie, aes(x = "", y = TotalRevenue, fill = BusinessType)) +
  geom_bar(stat = "identity", width = 1, color = "white") +
  coord_polar("y", start = 0) +
  geom_text(aes(label = paste0(Percentage, "%")),
            position = position_stack(vjust = 0.5),
            color = "white", size = 4) +
  scale_fill_brewer(palette = "Set2") +
  labs(title = " Persentase Total Pendapatan per Jenis Bisnis",
       fill = "Jenis Bisnis") +
  theme_void() +
  theme(
    plot.title = element_text(
      hjust = 0.5, face = "bold", size = 15, color = "#2c3e50"),
    legend.position = "bottom"  # ← Tambahan ini saja untuk hilangkan legend
  )

Insight :

Persentase pendapatan per jenis bisnis relatif merata dengan perbedaan antar kategori yang kecil (sekitar 22-27%). Ini menunjukkan bahwa kontribusi tiap jenis bisnis terhadap total pendapatan cukup seimbang, tanpa satu sektor yang terlau dominan.

3.4 Scatter Plot

library(ggplot2)

# Scatter Plot
ggplot(data, aes(x = MarketingSpend, y = MonthlyRevenue)) +
  geom_point(color = "orange", alpha = 0.6) +
  geom_smooth(method = "lm", se = TRUE, color = "maroon", linetype = "dashed") +
  labs(
    title = "Marketing Spend vs Monthly Revenue",
    x = "Marketing Spend",
    y = "Monthly Revenue"
  ) +
  theme_minimal() +
  theme(panel.grid.major.y = element_line(color = "gray", linetype = "dashed"))

Insight :

Dapat disimpulkan bahwa terdapat hubungan positif antara pengeluaran pemasaran dan pendapatan bulanan. Semakin besar dana yang dialokasikan untuk kegiatan pemasaran, maka pendapatan bulanan cenderung meningkat. Hal ini terlihat dari sebaran titik data yang membentuk pola naik serta garis regresi yang memiliki kemiringan positif.

3.5 Boxplot

library(ggplot2)

# Boxplot
ggplot(data, aes(x = BusinessType, y = MonthlyRevenue, fill = BusinessType)) +
  geom_boxplot(outlier.color = "red", outlier.shape = 16) +
  labs(
    title = "Distribusi Pendapatan Bulanan per Jenis Usaha",
    x = "Business Type",
    y = "Monthly Revenue"
  ) +
  theme_minimal() +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1),
    legend.position = "none"
  )

Insight :

Secara umum, keempat jenis usaha memiliki tingkat pendapatan bulanan yang relatif mirip. Namun, Manufacturing dan Technology tampak memiliki median pendapatan sedikit lebih tinggi dibanding jenis usaha lainnya. Selain itu, sebaran data (rentang antar kuartil) menunjukkan bahwa variasi pendapatan cukup lebar di semua jenis usaha, menandakan adanya perbedaan performa antar perusahaan dalam tiap sektor.

4 Central Tendency

Central tendency adalah ukuran statistik yang digunakan untuk mengidentifikasi nilai tengah atau nilai yang paling representatif dalam suatu kumpulan data. Tujuannya adalah untuk memberikan gambaran tentang lokasi pusat dari distribusi data dengan satu nilai ringkasan. Tiga ukuran central tendency yang paling umum adalah mean (rata-rata, dihitung dengan menjumlahkan semua nilai lalu dibagi banyaknya data), median (nilai tengah setelah data diurutkan), dan mode (nilai yang paling sering muncul). Pemilihan ukuran mana yang paling tepat bergantung pada jenis data dan distribusinya, karena masing-masing ukuran memiliki kelebihan dan kelemahan dalam menggambarkan titik pemusatan data.

Mean (Rata-rata)

Rumus:
\[ \mathbf{Mean} = \frac{\sum x_i}{n} \]

Keterangan:

  • \(x_i\) = nilai ke-i dari data
  • \(n\) = jumlah total data

Artinya, semua nilai dijumlahkan lalu dibagi dengan jumlah data.

Median (Nilai Tengah)

Median adalah nilai yang berada di tengah setelah data diurutkan dari yang terkecil ke terbesar.
Jika jumlah data ganjil, median = nilai di posisi tengah.
Jika jumlah data genap, median = rata-rata dari dua nilai tengah.

Mode (Modus)

Mode adalah nilai yang paling sering muncul dalam suatu kumpulan data.
Jika hanya ada satu nilai yang sering muncul → unimodal,
jika dua nilai → bimodal,
dan jika lebih dari dua → multimodal.

4.1 Tabel Mean, Median, Mode

# --- Menghitung Mean, Median, Modus ---

# Fungsi untuk modus (karena R tidak punya fungsi bawaan)
get_mode <- function(x) {
  uniqx <- unique(x)
  uniqx[which.max(tabulate(match(x, uniqx)))]
}

# Mean
mean_spend <- mean(data$MarketingSpend)
mean_rev <- mean(data$MonthlyRevenue)

# Median
median_spend <- median(data$MarketingSpend)
median_rev <- median(data$MonthlyRevenue)

# Modus
mode_spend <- get_mode(data$MarketingSpend)
mode_rev <- get_mode(data$MonthlyRevenue)

# --- Menampilkan hasil dalam tabel ---
tabel_data <- data.frame(
  Variable = c("Marketing Spend", "Monthly Revenue"),
  Mean = c(mean_spend, mean_rev),
  Median = c(median_spend, median_rev),
  Mode = c(mode_spend, mode_rev)
)

# Menampilkan tabel
tabel_data

4.2 Interpretation Mean, Median, Mode

  1. Marketing Spend (Pengeluaran Pemasaran)

Mean (Rata-rata) dan Median (Nilai Tengah) = Sekitar 85. Ini adalah nilai pengeluaran yang paling umum atau normal. Mode (Nilai yang Paling Sering Muncul) = 148. Ini jauh lebih tinggi.Distribusi data ini tidak normal/tidak simetris. Ada kelompok pengeluaran yang jauh lebih sering terjadi di nilai yang tinggi (sekitar 148), meski rata-ratanya lebih rendah.

  1. Monthly Revenue (Pendapatan Bulanan)

Mean (Rata-rata), Median (Nilai Tengah), dan Mode (Nilai yang Paling Sering Muncul) = Semuanya sekitar 181 hingga 201. Nilai-nilai ini saling berdekatan. Distribusi data ini normal atau mendekati normal. Artinya, pendapatan bulanan tersebar secara simetris dan sebagian besar nilainya berada dekat rata-rata. Perbedaan Kunci Monthly Revenue memiliki pola yang teratur (seperti lonceng), sedangkan Marketing Spend memiliki pola yang tidak teratur dan sangat miring. Pada data yang normal (Revenue), Mean, Median, dan Mode mirip. Pada data yang tidak normal (Spend), Mode jauh berbeda dari Mean dan Median.

4.3 Visualization Histogram

library(ggplot2)
library(gridExtra)

# --- Fungsi untuk menghitung modus ---
get_mode <- function(x) {
  ux <- unique(x)
  ux[which.max(tabulate(match(x, ux)))]
}

# --- Fungsi membuat histogram dengan garis mean, median, mode ---
create_histogram <- function(column_data, column_name, fill_color) {
  df <- data.frame(value = column_data)
  
  mean_val <- mean(column_data, na.rm = TRUE)
  median_val <- median(column_data, na.rm = TRUE)
  mode_val <- get_mode(round(column_data, 0))
  
  ggplot(df, aes(x = value)) +
    geom_histogram(aes(y = ..density..), 
                   bins = 30, 
                   fill = fill_color, 
                   color = "white", 
                   alpha = 0.8) +
    geom_density(alpha = 0.3, fill = "gray90") +
    geom_vline(aes(xintercept = mean_val, color = "Mean"), linetype = "dashed", size = 1.2) +
    geom_vline(aes(xintercept = median_val, color = "Median"), linetype = "dotted", size = 1.2) +
    geom_vline(aes(xintercept = mode_val, color = "Mode"), linetype = "solid", size = 1.2) +
    scale_color_manual(
      name = "Keterangan Garis",
      values = c("Mean" = "red", "Median" = "green", "Mode" = "blue")
    ) +
    labs(
      title = paste("Distribusi", column_name),
      subtitle = paste("Mean:", round(mean_val, 2),
                       "| Median:", round(median_val, 2),
                       "| Mode:", round(mode_val, 2)),
      x = column_name,
      y = "Frequency"
    ) +
    theme_minimal() +
    theme(
      plot.title = element_text(face = "bold", size = 12),
      plot.subtitle = element_text(size = 9, color = "gray40"),
      legend.position = "bottom",
      panel.grid.major = element_line(color = "gray90"),
      panel.grid.minor = element_blank()
    )
}

# --- Buat dua histogram dari data yang sudah ada ---
hist1 <- create_histogram(data$MarketingSpend, "Marketing Spend", "skyblue")
hist2 <- create_histogram(data$MonthlyRevenue, "Monthly Revenue", "orange")

# --- Tampilkan berdampingan ---
grid.arrange(hist1, hist2, ncol = 2)

Insight :

  1. Marketing Spend menggambarkan besarnya biaya yang dikeluarkan untuk kegiatan pemasaran setiap bulan.
  2. Monthly Revenue menunjukkan jumlah pendapatan yang diperoleh perusahaan dalam periode yang sama. Kedua variabel ini memiliki hubungan logis semakin tinggi pengeluaran pemasaran, diharapkan pendapatan juga meningkat.

5 Measures of Dispersion

Measures of dispersion adalah serangkaian teknik statistik yang digunakan untuk mengukur sebaran atau variasi data dalam suatu dataset. Sementara measures of central tendency seperti mean dan median hanya memberikan informasi tentang nilai tengah, measures of dispersion mengungkap seberapa jauh titik data individual tersebar dari nilai pusat tersebut. Konsep ini sangat krusial dalam analisis data karena dua dataset dengan mean yang sama bisa memiliki karakteristik yang sangat berbeda - satu mungkin sangat konsisten dengan data yang mengelompok rapat, sementara lainnya memiliki variasi yang luas. Beberapa ukuran dispersi yang umum digunakan meliputi range, variance, standard deviation, dan interquartile range (IQR), yang masing-masing memberikan perspektif berbeda tentang konsistensi dan reliabilitas data yang dianalisis.

library(ggplot2)
library(dplyr)
library(tidyr)
library(gridExtra)
library(knitr)

# Memilih hanya kolom numerik untuk analisis dispersi
numeric_cols <- data %>% 
  select(where(is.numeric)) %>% 
  select(-1) # Menghapus kolom pertama (index)

# Menghitung measures of dispersion untuk setiap variabel numerik (DIBUAT TABEL)
dispersion_stats <- data.frame(
  Variable = names(numeric_cols),
  Mean = sapply(numeric_cols, mean, na.rm = TRUE),
  Median = sapply(numeric_cols, median, na.rm = TRUE),
  SD = sapply(numeric_cols, sd, na.rm = TRUE),
  Variance = sapply(numeric_cols, var, na.rm = TRUE),
  IQR = sapply(numeric_cols, IQR, na.rm = TRUE),
  Range = sapply(numeric_cols, function(x) max(x, na.rm = TRUE) - min(x, na.rm = TRUE)),
  CV = sapply(numeric_cols, function(x) sd(x, na.rm = TRUE)/mean(x, na.rm = TRUE)) # Coefficient of Variation
)

# Perbaiki fungsi histogram
discreate_histogram <- function(column_data, column_name, color) {
    df <- data.frame(value = column_data)
    
    # Hitung stats untuk annotasi (perbaiki typo)
    mean_val <- mean(column_data, na.rm = TRUE)
    sd_val <- sd(column_data, na.rm = TRUE)
    iqr_val <- IQR(column_data, na.rm = TRUE)
    
    # ... lanjutan kode plot
}

# Reset row names untuk tabel
rownames(dispersion_stats) <- NULL

# Buat tabel
kable(dispersion_stats, digits = 2, caption = "Summary Statistics untuk Variabel Numerik")
Summary Statistics untuk Variabel Numerik
Variable Mean Median SD Variance IQR Range CV
MarketingSpend 85.27 84.90 37.84 1432.17 66.12 129.90 0.44
ProductPrice 5.55 5.60 2.63 6.91 4.60 9.00 0.47
EmployeeCount 50.90 51.00 20.07 402.97 27.00 139.00 0.39
ManagerExperience 7.95 7.90 4.06 16.50 7.10 14.00 0.51
CustomerRating 80.15 80.00 8.01 64.15 11.00 49.00 0.10
MonthlyRevenue 180.83 181.18 47.25 2232.43 73.86 256.65 0.26

5.1 Histogram

# Fungsi untuk membuat histogram dengan annotasi measures of dispersion
create_histogram <- function(column_data, column_name, color) {
  df <- data.frame(value = column_data)
  
  # Menghitung stats untuk annotasi
  mean_val <- mean(column_data, na.rm = TRUE)
  sd_val <- sd(column_data, na.rm = TRUE)
  iqr_val <- IQR(column_data, na.rm = TRUE)
  cv_val <- sd_val / mean_val
  
  ggplot(df, aes(x = value)) +
    geom_histogram(aes(y = ..density..), 
                   fill = color, 
                   color = "white", 
                   alpha = 0.8, 
                   bins = 30) +
    geom_density(alpha = 0.5, fill = "darkblue") +
    geom_vline(xintercept = mean_val, color = "red", linetype = "dashed", size = 1) +
    geom_vline(xintercept = median(column_data, na.rm = TRUE), 
               color = "green", linetype = "dashed", size = 1) +
    labs(title = paste("Distribusi", column_name),
         subtitle = paste("Mean:", round(mean_val, 2), 
                         "| SD:", round(sd_val, 2),
                         "| IQR:", round(iqr_val, 2),
                         "| CV:", round(cv_val, 2)),
         x = column_name,
         y = "Density") +
    theme_minimal() +
    theme(
      plot.title = element_text(face = "bold", size = 12),
      plot.subtitle = element_text(size = 9, color = "darkgray"),
      panel.grid.major = element_line(color = "gray90"),
      panel.grid.minor = element_blank()
    )
}

# Membuat histogram untuk variabel numerik utama
histograms <- list()

# MarketingSpend
histograms[[1]] <- create_histogram(numeric_cols$MarketingSpend, "Marketing Spend", "#FF6B6B")

# ProductPrice
histograms[[2]] <- create_histogram(numeric_cols$ProductPrice, "Product Price", "#4ECDC4")

# EmployeeCount (filter nilai negatif)
employee_clean <- numeric_cols$EmployeeCount[numeric_cols$EmployeeCount >= 0]
histograms[[3]] <- create_histogram(employee_clean, "Employee Count", "#45B7D1")

# ManagerExperience
histograms[[4]] <- create_histogram(numeric_cols$ManagerExperience, "Manager Experience", "#96CEB4")

# CustomerRating
histograms[[5]] <- create_histogram(numeric_cols$CustomerRating, "Customer Rating", "#FFEAA7")

# MonthlyRevenue
histograms[[6]] <- create_histogram(numeric_cols$MonthlyRevenue, "Monthly Revenue", "#DDA0DD")

# Menggabungkan semua histogram
grid.arrange(grobs = histograms, ncol = 2, 
             top = "Analisis Distribusi dan Measures of Dispersion")

Insight :

Berdasarkan analisis histogram untuk setiap variabel, berikut insight ringkasnya :

  1. City · Data tersebar merata di 5 kota (Jakarta, Surabaya, Bandung, Medan, Makassar). · Tidak ada dominasi kota tertentu, menunjukkan representasi yang seimbang.

  2. BusinessType · “Food & Beverage” adalah tipe bisnis paling umum. · Diikuti oleh Retail, Technology, dan Manufacturing.

  3. SalesChannel · Distribusi hampir seimbang antara Online dan Offline. · Tren penjualan hybrid (daring & luring) tercermin dalam data.

  4. MarketingSpend · Sebagian besar berada di rentang menengah (≈50–120). · Ada beberapa outlier dengan anggaran sangat tinggi atau rendah.

  5. ProductPrice · Harga produk terkonsentrasi di rentang rendah hingga menengah (≈2–8). · Beberapa produk memiliki harga premium (>9).

  6. EmployeeCount · Mayoritas perusahaan memiliki 30–70 karyawan. · Beberapa outlier dengan jumlah karyawan ekstrem (sangat sedikit atau sangat banyak).

  7. ManagerExperience · Pengalaman manajer tersebar luas, dari pemula (<2 tahun) hingga sangat berpengalaman (>12 tahun). · Distribusi cenderung normal dengan sedikit condong ke pengalaman menengah.

  8. CustomerRating · Rating pelanggan umumnya tinggi (70–90). · Distribusi miring ke kiri, menunjukkan kepuasan pelanggan yang baik secara keseluruhan.

  9. MonthlyRevenue · Pendapatan bulanan beragam, dengan puncak di rentang ≈150–250. · Sebagian bisnis memiliki pendapatan sangat tinggi (>300), menunjukkan adanya performa unggulan.

Kesimpulan Umum: Data menunjukkan keragaman bisnis dengan performa yang variatif. F&B dominan, kepuasan pelanggan umumnya baik, dan pendapatan cenderung terkonsentrasi di rentang menengah.

5.2 Scatter Plot

df <- read.csv("C:/Users/Iyan/Downloads/Midterm Exam.csv")

library(ggplot2)

# scatterlot
ggplot(data = df, 
       aes(x = MarketingSpend, y = MonthlyRevenue)) +
  
  # Menambahkan titik-titik
  geom_point(alpha = 0.6, color = "darkseagreen3") +
  
  # Menambahkan garis tren linear (regresi)
  geom_smooth(method = "lm", se = FALSE, color = "darkolivegreen", linetype = "dashed") +
  
  # Menambahkan Judul dan Label
  labs(title = "Hubungan antara Pengeluaran Pemasaran dan Pendapatan Bulanan",
       x = "Pengeluaran Pemasaran (MarketingSpend)",
       y = "Pendapatan Bulanan (MonthlyRevenue)") +
  
  # Mengatur Tema Plot
  theme_minimal() + 
  
  # Menyesuaikan tampilan judul
  theme(plot.title = element_text(hjust = 0.5, size = 16, face = "bold"),
        axis.title = element_text(size = 12))

Insight :

Scatter plot tersebut menunjukkan adanya hubungan positif yang jelas antara pengeluaran Pemasaran dan Pendapatan Bulanan. Garis tren regresi linear akan miring ke atas. Hal ini mengindikasikan bahwa semakin tinggi dana yang dihabiskan untuk (MarketingSpend), cenderung semakin tinggi pula (MonthlyRevenue) yang dihasilkan. Visualisasi ini secara keseluruhan mendukung hipotesis bahwa investasi yang lebih besar dalam pemasaran merupakan faktor yang signifikan dalam mendorong pertumbuhan pendapatan bulanan. Namun, adanya dispersi menunjukkan bahwa efektivitas pemasaran tidak 100% dijamin dan dipengaruhi oleh faktor-faktor lain seperti kualitas produk atau harga.

5.3 Box Plot

library(gridExtra)
# Pilih dua variabel numerik untuk analisis (ubah sesuai dataset kamu)
num_var1 <- data$MarketingSpend   # <-- ubah sesuai nama kolom dataset kamu
num_var2 <- data$MonthlyRevenue # <-- ubah sesuai nama kolom dataset kamu

# Boxplot (Visualisasi utama untuk dispersion)
boxplot1 <- ggplot(data, aes(y = num_var1)) +
  geom_boxplot(fill = "cyan", color = "darkblue") +
  labs(title = "Marketing Spend", y = "Frequency") +
  theme_minimal()# Boxplot (Visualisasi utama untuk dispersion)

# Boxplot (Visualisasi utama untuk dispersion)
boxplot2 <- ggplot(data, aes(y = num_var2)) +
  geom_boxplot(fill = "cyan", color = "darkblue") +
  labs(title = "Monthly Revenue", y = "Frequency") +
  theme_minimal()

grid.arrange(boxplot1, boxplot2, ncol = 2)

Insight:

Boxplot menampilkan distribusi dua variabel: Marketing Spend dan Monthly Revenue. Warna cyan menunjukkan rentang Q1–Q3, garis hitam median, dan whisker batas nilai wajar.

  • Marketing Spend Median sekitar 80–85, rentang data sempit → pengeluaran stabil tanpa outlier. Kesimpulan: Pengeluaran pemasaran relatif konsisten.

  • Monthly Revenue Median 180–200, variasi lebih besar, cenderung miring ke bawah. Kesimpulan: Pendapatan bulanan lebih fluktuatif.

  • Hubungan Marketing spend stabil, revenue lebih bervariasi. Analisis lanjut dapat dilakukan dengan korelasi atau scatterplot untuk melihat hubungan keduanya.

5.4 Interpretation

  • Histogram -> terlihat bahwa Marketing Spend memiliki sebaran data yang paling lebar dibandingkan variabel lainnya. Sementara itu, Monthly Revenue menyebar mengikuti pola tertentu. Variabel dengan variabilitas besar yaitu Marketing Spend karena batangnya menyebar paling lebar menandakan nilai sangat bervariasi.

  • Scatterplot -> Titik titik data menyebar cukup luas dan tidak membentuk garis yang rapat. Ini menunjukkan adanya variasi besar antara pengeluaran pemasaran dan pendapatan yang didapat, Variabilitas terbesar terlihat di Monthly Revenue karena sebaran titik di sumbu-X nya paling luas.

  • Boxplot -> Kotak(IQR) Marketing Spend tampak paling panjang dan memiliki beberapa outlier yang berarti data lebih bervariasi dan tidak seragam. Variabel Monthly Revenue menunjukkan penyebaran sedang. Dengan demikian, Marketing Spend menunjukkan variabilitas terbesar karena nilai-nilainya tesebar jauh dari rata-rata dan memiliki rentang yang luas.

6 Summary and Interpretation

Berdasarkan analisis data, dapat disimpulkan bahwa pendapatan bulanan suatu bisnis dipengaruhi oleh beberapa faktor utama, seperti pengeluaran pemasaran, pengalaman manager dan penilaian pelanggan. Berikut kesimpulan dan penjelasannya :

  • Variabel yang paling konsisten (Dispersi Rendah) : Customer Rating, karena nilainya dalam jumlah kecil yang saling berdekatan maka penyebarannya cenderung rendah. Penilaian pelanggan di berbagai kota dan jenis bisnis relatif stabil yang berarti kepuasan pelanggan tidak terlalu berbeda jauh antar wilayah.

  • Variabel dengan Variasi terbesar (Dispersi Tinggi) : Monthly Revenue dan Marketing Spend, karena kedua variabel tersebut menunjukkan perbedaan besar antar bisnis. Beberapa bisnis mungkin sangat agresif dalam pemasaran dan menghasilkan pendapatan tinggi, sementara yang lain beroperasi dengan sumber daya terbatas.

  • Pola atau Wawasan dari visualisasi :

  1. Pengeluaran pemasaran mendorong kenaikan pendapatan.
  2. Pengalaman manager berhubungan dengan kepuasan pelanggan.
  3. Perbedaan pendapatan muncul berdasarkan kota dan jenis bisnis.
LS0tDQp0aXRsZTogIlVyYmFuIEJ1c2luZXNzIg0Kc3VidGl0bGU6ICJNaWR0ZXJtIEV4YW0iDQphdXRob3I6DQotICAgIktlbG9tcG9rIDMiDQotICAgIkZyaXp6eSBMaXRobWVudHN5YWgiDQotICAgIkFuZ2VsaWNhIEZsb3JlbnRpbmEgTSINCi0gICAiQWRhbSBSaWNoaWUgV2lqYXlhIg0KLSAgICJBbmRyZSINCi0gICAiTXVoYW1tYWQgTmFiaWwgS2hhaXJpbCBBbmFtIg0KLSAgICJDaGFuZHJhIFJpemFsIEFMYW1zeWFoIg0KDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy5EYXRlKCksICclQiAlZCwgJVknKWAiDQpvdXRwdXQ6DQogIHJtZGZvcm1hdHM6OnJlYWR0aGVkb3duOg0KICAgIHNlbGZfY29udGFpbmVkOiB0cnVlDQogICAgdGh1bWJuYWlsczogdHJ1ZQ0KICAgIGxpZ2h0Ym94OiB0cnVlDQogICAgZ2FsbGVyeTogdHJ1ZQ0KICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQ0KICAgIGxpYl9kaXI6IGxpYnMNCiAgICBkZl9wcmludDogInBhZ2VkIg0KICAgIGNvZGVfZm9sZGluZzogInNob3ciDQogICAgY29kZV9kb3dubG9hZDogeWVzDQotLS0NCg0KPGltZyBpZD0iRm90byIgc3JjPSJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vYW5nZWxpaWVlL0tlbG9tcG9rMy9tYWluL2ZvdG9rZWxvbXBvay5qcGciIGFsdD0iTG9nbyIgc3R5bGU9IndpZHRoOjIwMHB4OyBkaXNwbGF5OiBibG9jazsgbWFyZ2luOiBhdXRvOyI+DQoNCg0KYGBge3IsIGVjaG89RkFMU0V9DQprbml0cjo6aW5jbHVkZV91cmwoImh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2VtYmVkL25pYmdtWkpoRmpjIikNCmBgYA0KDQoNCg0KDQojICBJbnRyb2R1Y3Rpb24NCg0KIERhbGFtIGVrb25vbWkgcGVya290YWFuIHlhbmcgZGluYW1pcywgYmlzbmlzIGRpcGVuZ2FydWhpIG9sZWgga2VwYWRhdGFuIHBlbmR1ZHVrLCBwcmVmZXJlbnNpIGtvbnN1bWVuLCB0ZWtub2xvZ2ksIGRhbiBwZXJzYWluZ2FuIHBhc2FyLiBNZW1haGFtaSBmYWt0b3IgcGVuZW50dSBwZW5kYXBhdGFuIGJ1bGFuYW7igJRzZXBlcnRpIHBlbWFzYXJhbiwgaGFyZ2EsIHRlbmFnYSBrZXJqYSwgcGVuZ2FsYW1hbiBtYW5hamVyaWFsLCBkYW4ga2VwdWFzYW4gcGVsYW5nZ2Fu4oCUcGVudGluZyB1bnR1ayBrZXB1dHVzYW4gc3RyYXRlZ2lzLg0KS2luZXJqYSBiaXNuaXMgYmVyYmVkYSBhbnRhciBrb3RhIGRhbiBzZWt0b3IgKHJpdGVsLCB0ZWtub2xvZ2ksIG1hbnVmYWt0dXIsIG1ha2FuYW4gJiBtaW51bWFuKSwgc2VoaW5nZ2EgYW5hbGlzaXMgZGVza3JpcHRpZiBkYW4gdmlzdWFsaXNhc2kgZGF0YSBkaWJ1dHVoa2FuIHVudHVrIG1lbGloYXQgcG9sYSBwZW5kYXBhdGFuIGRhbiB2YXJpYXNpbnlhLiBNZWxhbHVpIGFuYWxpc2lzIGluaSwgb3JnYW5pc2FzaSBkYXBhdCBtZW5lbXVrYW4ga2VzZW5qYW5nYW4ga2luZXJqYSBzZXJ0YSBwZWx1YW5nIHVudHVrIG1lbmdvcHRpbWFsa2FuIHN0cmF0ZWdpIHBlbWFzYXJhbiwgaGFyZ2EsIGRhbiBtYW5hamVtZW4gc3VtYmVyIGRheWEgbWFudXNpYS4NCkRhcmkgcGVybWFzYWxhaCBpbmkgbWVuZ2d1bmFrYW4gdGFtcGlsYW4gdmlzdWFsaXNhc2kgZGF0YQ0KDQojICBEYXRhIHNldA0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KHJlYWRyKQ0KbGlicmFyeShEVCkNCg0KIyAy77iP4oOjIEJhY2EgZmlsZSBDU1YgZGFyaSBsb2thc2kga2FtdQ0KZGF0YSA8LSByZWFkX2NzdigiQzovVXNlcnMvSXlhbi9Eb3dubG9hZHMvTWlkdGVybSBFeGFtLmNzdiIpDQoNCiMgM++4j+KDoyBUYW1waWxrYW4gdGFiZWwgaW50ZXJha3RpZiAoMTAgYmFyaXMgcGVyIGhhbGFtYW4pDQpkYXRhdGFibGUoDQogIGRhdGEsDQogIG9wdGlvbnMgPSBsaXN0KHBhZ2VMZW5ndGggPSAxMCksICAjIHRhbXBpbCAxMCBiYXJpcyBwZXIgaGFsYW1hbg0KICBjYXB0aW9uID0gIlRhYmVsIEludGVyYWt0aWYgRGF0YSBDU1YiDQopDQpgYGANCiMgRGF0YSBWaXN1YWxpemF0aW9uDQojIyBCYXIgQ2hhcnQNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHJlYWRyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoc2NhbGVzKQ0KbGlicmFyeShzaG93dGV4dCkNCg0KIyAgRm9udCBHb29nbGUgYWdhciB0YW1waWxhbiBwcm9mZXNpb25hbA0KZm9udF9hZGRfZ29vZ2xlKCJQb3BwaW5zIiwgInBvcHBpbnMiKQ0Kc2hvd3RleHRfYXV0bygpDQoNCiMgIEJhY2EgZGF0YQ0KZGF0YSA8LSByZWFkX2NzdigiQzovVXNlcnMvSXlhbi9Eb3dubG9hZHMvTWlkdGVybSBFeGFtLmNzdiIpDQoNCiMgIEhpdHVuZyByYXRhLXJhdGEgcGVuZGFwYXRhbiBwZXIga290YQ0KYXZnX2NpdHkgPC0gZGF0YSAlPiUNCiAgZ3JvdXBfYnkoQ2l0eSkgJT4lDQogIHN1bW1hcmlzZShBdmdSZXZlbnVlID0gbWVhbihNb250aGx5UmV2ZW51ZSwgbmEucm0gPSBUUlVFKSkgJT4lDQogIGFycmFuZ2UoZGVzYyhBdmdSZXZlbnVlKSkNCg0KIyBCYXIgY2hhcnQgDQpnZ3Bsb3QoYXZnX2NpdHksIGFlcyh4ID0gcmVvcmRlcihDaXR5LCBBdmdSZXZlbnVlKSwgeSA9IEF2Z1JldmVudWUsIGZpbGwgPSBBdmdSZXZlbnVlKSkgKw0KICBnZW9tX2NvbCh3aWR0aCA9IDAuNjUsIHNob3cubGVnZW5kID0gRkFMU0UpICsNCiAgZ2VvbV90ZXh0KA0KICAgIGFlcyhsYWJlbCA9IHBhc3RlMCgiUnAgIiwgZm9ybWF0KHJvdW5kKEF2Z1JldmVudWUsIDEpLCBiaWcubWFyayA9ICIuIiwgZGVjaW1hbC5tYXJrID0gIiwiKSkpLA0KICAgIHZqdXN0ID0gLTAuNCwgZmFtaWx5ID0gInBvcHBpbnMiLCBzaXplID0gNC4yLCBmb250ZmFjZSA9ICJib2xkIiwgY29sb3IgPSAiYmxhY2siDQogICkgKw0KICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJjeWFuIiwgaGlnaCA9ICJjb3JuZmxvd2VyYmx1ZSIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKA0KICAgIGxpbWl0cyA9IGMoMCwgMjAwKSwgICMg8J+UuSBCYXRhc2kgc3VtYnUgWSBzYW1wYWkgMjAwDQogICAgYnJlYWtzID0gc2VxKDAsIDIwMCwgYnkgPSAyNSksDQogICAgbGFiZWxzID0gY29tbWFfZm9ybWF0KGJpZy5tYXJrID0gIi4iLCBkZWNpbWFsLm1hcmsgPSAiLCIpDQogICkgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlJhdGEtcmF0YSBQZW5kYXBhdGFuIEJ1bGFuYW4gcGVyIEtvdGEiLA0KICAgIHN1YnRpdGxlID0gIlZpc3VhbGlzYXNpIG1lbnVuanVra2FuIHJhdGEtcmF0YSBraW5lcmphIGJpc25pcyBkaSBzZXRpYXAga290YSIsDQogICAgeCA9ICJLb3RhIiwNCiAgICB5ID0gIlJhdGEtcmF0YSBQZW5kYXBhdGFuIChScCkiLA0KICAgIGNhcHRpb24gPSAiU3VtYmVyOiBEYXRhc2V0IE1pZHRlcm0gRXhhbSINCiAgKSArDQogIHRoZW1lX21pbmltYWwoYmFzZV9mYW1pbHkgPSAicG9wcGlucyIpICsNCiAgdGhlbWUoDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgsIGZhY2UgPSAiYm9sZCIsIGNvbG9yID0gIiMwMDM1NjYiLCBoanVzdCA9IDAuNSksDQogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTMsIGNvbG9yID0gIiM1NTU1NTUiLCBoanVzdCA9IDAuNSwgbWFyZ2luID0gbWFyZ2luKGIgPSAxMCkpLA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgZmFjZSA9ICJib2xkIiwgY29sb3IgPSAiIzAwMzA0OSIpLA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSwgY29sb3IgPSAiIzU1NTU1NSIpLA0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGZhY2UgPSAiYm9sZCIsIG1hcmdpbiA9IG1hcmdpbih0ID0gMTApKSwNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyLCBmYWNlID0gImJvbGQiLCBtYXJnaW4gPSBtYXJnaW4ociA9IDEwKSksDQogICAgcGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KHNpemUgPSA5LCBjb2xvciA9ICIjNzc3Nzc3IiwgaGp1c3QgPSAxLCBtYXJnaW4gPSBtYXJnaW4odCA9IDEwKSkNCiAgKSArDQogIGNvb3JkX2NhcnRlc2lhbih5bGltID0gYygwLCAyMDApKSAgIyDwn5S5IFRhbWJhaGFuIGFnYXIgc3VtYnUgWSBha3VyYXQgZGFuIHRpZGFrIG1lbW90b25nIGRhdGENCmBgYA0KDQpJbnNpZ2h0IDoNCg0KS290YSBKYWthcnRhIG1lbWlsaWtpIHJhdGEtcmF0YSBwZW5kYXBhdGFuIGJ1bGFuYW4gdGVydGluZ2dpLCBzZW1lbnRhcmEgS290YSBNYWthc3NhciBtZW1pbGlraSByYXRhLXJhdGEgcGVuZGFwYXRhbiBidWxhbmFuIHRlcmVuZGFoLiBOYW11biwgdmFyaWFzaSBwZW5kYXBhdGFuIGFudGFya290YSByZWxhdGlmIGtlY2lsLCBtZW51bmp1a2thbiBkaXN0cmlidXNpIHBlbmRhcGF0YW4geWFuZyBjdWt1cCBzZWltYmFuZyBkaSBsaW1hIGtvdGEgdGVyc2VidXQuDQoNCg0KIyMgSGlzdG9ncmFtDQoNCmBgYHtyfQ0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkoZ2dwbG90MikNCmdncGxvdChkYXRhLCBhZXMoeCA9IE1vbnRobHlSZXZlbnVlKSkgKw0KICBnZW9tX2hpc3RvZ3JhbSgNCiAgICBiaW5zID0gMjAsDQogICAgZmlsbCA9ICJkYXJrc2VhZ3JlZW4iLCANCiAgICBjb2xvciA9ICJ3aGl0ZSIsDQogICAgYWxwaGEgPSAwLjg1DQogICkgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIkRpc3RyaWJ1c2kgUGVuZGFwYXRhbiBCaXNuaXMgKE1vbnRobHkgUmV2ZW51ZSkiLA0KICAgIHggPSAiUGVuZGFwYXRhbiBCdWxhbmFuIChKdXRhKSIsDQogICAgeSA9ICJGcmVrdWVuc2kiDQogICkgKw0KICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDEzKQ0KDQpgYGANCg0KSW5zaWdodCA6DQoNClNlYmFnaWFuIGJlc2FyIGJpc25pcyBtZW1pbGlraSBwZW5kYXBhdGFuIGJ1bGFuYW4gc2VraXRhciAxNTAtMjAwIGp1dGEgcnVwaWFoLiBEaXN0cmlidXNpIGRhdGEgdGFtcGFrIG5vcm1hbCBkYW4gc2VpbWJhbmcgbWVudW5qdWtrYW4gYmFod2EgcGVuZGFwYXRhbiBiaXNuaXMgcmVsYXRpZiBtZXJhdGEgdGFucGEgYmFueWFrIG5pbGFpIGVrc3RyZW0uDQoNCiMjIFBpZSBDaGFydA0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KGRwbHlyKQ0KDQojIEhpdHVuZyB0b3RhbCBwZW5kYXBhdGFuIHBlciBqZW5pcyBiaXNuaXMNCmRhdGFfcGllIDwtIGRhdGEgJT4lDQogIGdyb3VwX2J5KEJ1c2luZXNzVHlwZSkgJT4lDQogIHN1bW1hcmlzZShUb3RhbFJldmVudWUgPSBzdW0oTW9udGhseVJldmVudWUsIG5hLnJtID0gVFJVRSkpICU+JQ0KICBtdXRhdGUoUGVyY2VudGFnZSA9IHJvdW5kKFRvdGFsUmV2ZW51ZSAvIHN1bShUb3RhbFJldmVudWUpICogMTAwLCAxKSkNCg0KIyBCdWF0IFBpZSBDaGFydA0KZ2dwbG90KGRhdGFfcGllLCBhZXMoeCA9ICIiLCB5ID0gVG90YWxSZXZlbnVlLCBmaWxsID0gQnVzaW5lc3NUeXBlKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAxLCBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgY29vcmRfcG9sYXIoInkiLCBzdGFydCA9IDApICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlMChQZXJjZW50YWdlLCAiJSIpKSwNCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLA0KICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiLCBzaXplID0gNCkgKw0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSArDQogIGxhYnModGl0bGUgPSAiIFBlcnNlbnRhc2UgVG90YWwgUGVuZGFwYXRhbiBwZXIgSmVuaXMgQmlzbmlzIiwNCiAgICAgICBmaWxsID0gIkplbmlzIEJpc25pcyIpICsNCiAgdGhlbWVfdm9pZCgpICsNCiAgdGhlbWUoDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dCgNCiAgICAgIGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiLCBzaXplID0gMTUsIGNvbG9yID0gIiMyYzNlNTAiKSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiAgIyDihpAgVGFtYmFoYW4gaW5pIHNhamEgdW50dWsgaGlsYW5na2FuIGxlZ2VuZA0KICApDQoNCmBgYA0KDQpJbnNpZ2h0IDoNCg0KUGVyc2VudGFzZSBwZW5kYXBhdGFuIHBlciBqZW5pcyBiaXNuaXMgcmVsYXRpZiBtZXJhdGEgZGVuZ2FuIHBlcmJlZGFhbiBhbnRhciBrYXRlZ29yaSB5YW5nIGtlY2lsIChzZWtpdGFyIDIyLTI3JSkuIEluaSBtZW51bmp1a2thbiBiYWh3YSBrb250cmlidXNpIHRpYXAgamVuaXMgYmlzbmlzIHRlcmhhZGFwIHRvdGFsIHBlbmRhcGF0YW4gY3VrdXAgc2VpbWJhbmcsIHRhbnBhIHNhdHUgc2VrdG9yIHlhbmcgdGVybGF1IGRvbWluYW4uDQoNCg0KIyMgU2NhdHRlciBQbG90DQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KDQojIFNjYXR0ZXIgUGxvdA0KZ2dwbG90KGRhdGEsIGFlcyh4ID0gTWFya2V0aW5nU3BlbmQsIHkgPSBNb250aGx5UmV2ZW51ZSkpICsNCiAgZ2VvbV9wb2ludChjb2xvciA9ICJvcmFuZ2UiLCBhbHBoYSA9IDAuNikgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IFRSVUUsIGNvbG9yID0gIm1hcm9vbiIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJNYXJrZXRpbmcgU3BlbmQgdnMgTW9udGhseSBSZXZlbnVlIiwNCiAgICB4ID0gIk1hcmtldGluZyBTcGVuZCIsDQogICAgeSA9ICJNb250aGx5IFJldmVudWUiDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JheSIsIGxpbmV0eXBlID0gImRhc2hlZCIpKQ0KYGBgDQoNCkluc2lnaHQgOg0KDQpEYXBhdCBkaXNpbXB1bGthbiBiYWh3YSB0ZXJkYXBhdCBodWJ1bmdhbiBwb3NpdGlmIGFudGFyYSBwZW5nZWx1YXJhbiBwZW1hc2FyYW4gZGFuIHBlbmRhcGF0YW4gYnVsYW5hbi4gU2VtYWtpbiBiZXNhciBkYW5hIHlhbmcgZGlhbG9rYXNpa2FuIHVudHVrIGtlZ2lhdGFuIHBlbWFzYXJhbiwgbWFrYSBwZW5kYXBhdGFuIGJ1bGFuYW4gY2VuZGVydW5nIG1lbmluZ2thdC4gSGFsIGluaSB0ZXJsaWhhdCBkYXJpIHNlYmFyYW4gdGl0aWsgZGF0YSB5YW5nIG1lbWJlbnR1ayBwb2xhIG5haWsgc2VydGEgZ2FyaXMgcmVncmVzaSB5YW5nIG1lbWlsaWtpIGtlbWlyaW5nYW4gcG9zaXRpZi4NCg0KIyMgQm94cGxvdA0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxpYnJhcnkoZ2dwbG90MikNCg0KIyBCb3hwbG90DQpnZ3Bsb3QoZGF0YSwgYWVzKHggPSBCdXNpbmVzc1R5cGUsIHkgPSBNb250aGx5UmV2ZW51ZSwgZmlsbCA9IEJ1c2luZXNzVHlwZSkpICsNCiAgZ2VvbV9ib3hwbG90KG91dGxpZXIuY29sb3IgPSAicmVkIiwgb3V0bGllci5zaGFwZSA9IDE2KSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiRGlzdHJpYnVzaSBQZW5kYXBhdGFuIEJ1bGFuYW4gcGVyIEplbmlzIFVzYWhhIiwNCiAgICB4ID0gIkJ1c2luZXNzIFR5cGUiLA0KICAgIHkgPSAiTW9udGhseSBSZXZlbnVlIg0KICApICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoDQogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSINCiAgKQ0KDQpgYGANCg0KSW5zaWdodCA6IA0KDQpTZWNhcmEgdW11bSwga2VlbXBhdCBqZW5pcyB1c2FoYSBtZW1pbGlraSB0aW5na2F0IHBlbmRhcGF0YW4gYnVsYW5hbiB5YW5nIHJlbGF0aWYgbWlyaXAuIE5hbXVuLCBNYW51ZmFjdHVyaW5nIGRhbiBUZWNobm9sb2d5IHRhbXBhayBtZW1pbGlraSBtZWRpYW4gcGVuZGFwYXRhbiBzZWRpa2l0IGxlYmloIHRpbmdnaSBkaWJhbmRpbmcgamVuaXMgdXNhaGEgbGFpbm55YS4gU2VsYWluIGl0dSwgc2ViYXJhbiBkYXRhIChyZW50YW5nIGFudGFyIGt1YXJ0aWwpIG1lbnVuanVra2FuIGJhaHdhIHZhcmlhc2kgcGVuZGFwYXRhbiBjdWt1cCBsZWJhciBkaSBzZW11YSBqZW5pcyB1c2FoYSwgbWVuYW5kYWthbiBhZGFueWEgcGVyYmVkYWFuIHBlcmZvcm1hIGFudGFyIHBlcnVzYWhhYW4gZGFsYW0gdGlhcCBzZWt0b3IuDQoNCg0KIyBDZW50cmFsIFRlbmRlbmN5DQoNCkNlbnRyYWwgdGVuZGVuY3kgYWRhbGFoIHVrdXJhbiBzdGF0aXN0aWsgeWFuZyBkaWd1bmFrYW4gdW50dWsgbWVuZ2lkZW50aWZpa2FzaSBuaWxhaSB0ZW5nYWggYXRhdSBuaWxhaSB5YW5nIHBhbGluZyByZXByZXNlbnRhdGlmIGRhbGFtIHN1YXR1IGt1bXB1bGFuIGRhdGEuIFR1anVhbm55YSBhZGFsYWggdW50dWsgbWVtYmVyaWthbiBnYW1iYXJhbiB0ZW50YW5nIGxva2FzaSBwdXNhdCBkYXJpIGRpc3RyaWJ1c2kgZGF0YSBkZW5nYW4gc2F0dSBuaWxhaSByaW5na2FzYW4uIFRpZ2EgdWt1cmFuIGNlbnRyYWwgdGVuZGVuY3kgeWFuZyBwYWxpbmcgdW11bSBhZGFsYWggbWVhbiAocmF0YS1yYXRhLCBkaWhpdHVuZyBkZW5nYW4gbWVuanVtbGFoa2FuIHNlbXVhIG5pbGFpIGxhbHUgZGliYWdpIGJhbnlha255YSBkYXRhKSwgbWVkaWFuIChuaWxhaSB0ZW5nYWggc2V0ZWxhaCBkYXRhIGRpdXJ1dGthbiksIGRhbiBtb2RlIChuaWxhaSB5YW5nIHBhbGluZyBzZXJpbmcgbXVuY3VsKS4gUGVtaWxpaGFuIHVrdXJhbiBtYW5hIHlhbmcgcGFsaW5nIHRlcGF0IGJlcmdhbnR1bmcgcGFkYSBqZW5pcyBkYXRhIGRhbiBkaXN0cmlidXNpbnlhLCBrYXJlbmEgbWFzaW5nLW1hc2luZyB1a3VyYW4gbWVtaWxpa2kga2VsZWJpaGFuIGRhbiBrZWxlbWFoYW4gZGFsYW0gbWVuZ2dhbWJhcmthbiB0aXRpayBwZW11c2F0YW4gZGF0YS4NCg0KDQoqKk1lYW4gKFJhdGEtcmF0YSkqKg0KDQogICBSdW11czogIA0KICAgXFsNCiAgIFxtYXRoYmZ7TWVhbn0gPSBcZnJhY3tcc3VtIHhfaX17bn0NCiAgIFxdDQoNCioqS2V0ZXJhbmdhbjoqKg0KDQotIFwoIHhfaSBcKSA9IG5pbGFpIGtlLWkgZGFyaSBkYXRhICANCi0gXCggbiBcKSA9IGp1bWxhaCB0b3RhbCBkYXRhICANCg0KQXJ0aW55YSwgc2VtdWEgbmlsYWkgZGlqdW1sYWhrYW4gbGFsdSBkaWJhZ2kgZGVuZ2FuIGp1bWxhaCBkYXRhLg0KDQoqKk1lZGlhbiAoTmlsYWkgVGVuZ2FoKSoqDQoNCk1lZGlhbiBhZGFsYWggbmlsYWkgeWFuZyBiZXJhZGEgZGkgdGVuZ2FoIHNldGVsYWggZGF0YSBkaXVydXRrYW4gZGFyaSB5YW5nIHRlcmtlY2lsIGtlIHRlcmJlc2FyLiAgDQpKaWthIGp1bWxhaCBkYXRhICpnYW5qaWwqLCBtZWRpYW4gPSBuaWxhaSBkaSBwb3Npc2kgdGVuZ2FoLiAgDQpKaWthIGp1bWxhaCBkYXRhICpnZW5hcCosIG1lZGlhbiA9IHJhdGEtcmF0YSBkYXJpIGR1YSBuaWxhaSB0ZW5nYWguDQoNCioqTW9kZSAoTW9kdXMpKioNCg0KTW9kZSBhZGFsYWggbmlsYWkgeWFuZyBwYWxpbmcgc2VyaW5nIG11bmN1bCBkYWxhbSBzdWF0dSBrdW1wdWxhbiBkYXRhLiAgDQpKaWthIGhhbnlhIGFkYSBzYXR1IG5pbGFpIHlhbmcgc2VyaW5nIG11bmN1bCDihpIgKnVuaW1vZGFsKiwgIA0KamlrYSBkdWEgbmlsYWkg4oaSICpiaW1vZGFsKiwgIA0KZGFuIGppa2EgbGViaWggZGFyaSBkdWEg4oaSICptdWx0aW1vZGFsKi4NCg0KIyMgVGFiZWwgTWVhbiwgTWVkaWFuLCBNb2RlDQoNCmBgYHtyfQ0KDQojIC0tLSBNZW5naGl0dW5nIE1lYW4sIE1lZGlhbiwgTW9kdXMgLS0tDQoNCiMgRnVuZ3NpIHVudHVrIG1vZHVzIChrYXJlbmEgUiB0aWRhayBwdW55YSBmdW5nc2kgYmF3YWFuKQ0KZ2V0X21vZGUgPC0gZnVuY3Rpb24oeCkgew0KICB1bmlxeCA8LSB1bmlxdWUoeCkNCiAgdW5pcXhbd2hpY2gubWF4KHRhYnVsYXRlKG1hdGNoKHgsIHVuaXF4KSkpXQ0KfQ0KDQojIE1lYW4NCm1lYW5fc3BlbmQgPC0gbWVhbihkYXRhJE1hcmtldGluZ1NwZW5kKQ0KbWVhbl9yZXYgPC0gbWVhbihkYXRhJE1vbnRobHlSZXZlbnVlKQ0KDQojIE1lZGlhbg0KbWVkaWFuX3NwZW5kIDwtIG1lZGlhbihkYXRhJE1hcmtldGluZ1NwZW5kKQ0KbWVkaWFuX3JldiA8LSBtZWRpYW4oZGF0YSRNb250aGx5UmV2ZW51ZSkNCg0KIyBNb2R1cw0KbW9kZV9zcGVuZCA8LSBnZXRfbW9kZShkYXRhJE1hcmtldGluZ1NwZW5kKQ0KbW9kZV9yZXYgPC0gZ2V0X21vZGUoZGF0YSRNb250aGx5UmV2ZW51ZSkNCg0KIyAtLS0gTWVuYW1waWxrYW4gaGFzaWwgZGFsYW0gdGFiZWwgLS0tDQp0YWJlbF9kYXRhIDwtIGRhdGEuZnJhbWUoDQogIFZhcmlhYmxlID0gYygiTWFya2V0aW5nIFNwZW5kIiwgIk1vbnRobHkgUmV2ZW51ZSIpLA0KICBNZWFuID0gYyhtZWFuX3NwZW5kLCBtZWFuX3JldiksDQogIE1lZGlhbiA9IGMobWVkaWFuX3NwZW5kLCBtZWRpYW5fcmV2KSwNCiAgTW9kZSA9IGMobW9kZV9zcGVuZCwgbW9kZV9yZXYpDQopDQoNCiMgTWVuYW1waWxrYW4gdGFiZWwNCnRhYmVsX2RhdGENCmBgYA0KDQojIyBJbnRlcnByZXRhdGlvbiBNZWFuLCBNZWRpYW4sIE1vZGUNCg0KMS4gTWFya2V0aW5nIFNwZW5kIChQZW5nZWx1YXJhbiBQZW1hc2FyYW4pDQoNCk1lYW4gKFJhdGEtcmF0YSkgZGFuIE1lZGlhbiAoTmlsYWkgVGVuZ2FoKSA9IFNla2l0YXIgODUuIEluaSBhZGFsYWggbmlsYWkgcGVuZ2VsdWFyYW4geWFuZyBwYWxpbmcgdW11bSBhdGF1IG5vcm1hbC4gTW9kZSAoTmlsYWkgeWFuZyBQYWxpbmcgU2VyaW5nIE11bmN1bCkgPSAxNDguIEluaSBqYXVoIGxlYmloIHRpbmdnaS5EaXN0cmlidXNpIGRhdGEgaW5pIHRpZGFrIG5vcm1hbC90aWRhayBzaW1ldHJpcy4gQWRhIGtlbG9tcG9rIHBlbmdlbHVhcmFuIHlhbmcgamF1aCBsZWJpaCBzZXJpbmcgdGVyamFkaSBkaSBuaWxhaSB5YW5nIHRpbmdnaSAoc2VraXRhciAxNDgpLCBtZXNraSByYXRhLXJhdGFueWEgbGViaWggcmVuZGFoLg0KDQoyLiBNb250aGx5IFJldmVudWUgKFBlbmRhcGF0YW4gQnVsYW5hbikNCg0KTWVhbiAoUmF0YS1yYXRhKSwgTWVkaWFuIChOaWxhaSBUZW5nYWgpLCBkYW4gTW9kZSAoTmlsYWkgeWFuZyBQYWxpbmcgU2VyaW5nIE11bmN1bCkgPSBTZW11YW55YSBzZWtpdGFyIDE4MSBoaW5nZ2EgMjAxLiBOaWxhaS1uaWxhaSBpbmkgc2FsaW5nIGJlcmRla2F0YW4uIERpc3RyaWJ1c2kgZGF0YSBpbmkgbm9ybWFsIGF0YXUgbWVuZGVrYXRpIG5vcm1hbC4gQXJ0aW55YSwgcGVuZGFwYXRhbiBidWxhbmFuIHRlcnNlYmFyIHNlY2FyYSBzaW1ldHJpcyBkYW4gc2ViYWdpYW4gYmVzYXIgbmlsYWlueWEgYmVyYWRhIGRla2F0IHJhdGEtcmF0YS4NClBlcmJlZGFhbiBLdW5jaQ0KTW9udGhseSBSZXZlbnVlIG1lbWlsaWtpIHBvbGEgeWFuZyB0ZXJhdHVyIChzZXBlcnRpIGxvbmNlbmcpLCBzZWRhbmdrYW4gTWFya2V0aW5nIFNwZW5kIG1lbWlsaWtpIHBvbGEgeWFuZyB0aWRhayB0ZXJhdHVyIGRhbiBzYW5nYXQgbWlyaW5nLg0KUGFkYSBkYXRhIHlhbmcgbm9ybWFsIChSZXZlbnVlKSwgTWVhbiwgTWVkaWFuLCBkYW4gTW9kZSBtaXJpcC4NClBhZGEgZGF0YSB5YW5nIHRpZGFrIG5vcm1hbCAoU3BlbmQpLCBNb2RlIGphdWggYmVyYmVkYSBkYXJpIE1lYW4gZGFuIE1lZGlhbi4NCg0KDQojIyBWaXN1YWxpemF0aW9uIEhpc3RvZ3JhbQ0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZ3JpZEV4dHJhKQ0KDQojIC0tLSBGdW5nc2kgdW50dWsgbWVuZ2hpdHVuZyBtb2R1cyAtLS0NCmdldF9tb2RlIDwtIGZ1bmN0aW9uKHgpIHsNCiAgdXggPC0gdW5pcXVlKHgpDQogIHV4W3doaWNoLm1heCh0YWJ1bGF0ZShtYXRjaCh4LCB1eCkpKV0NCn0NCg0KIyAtLS0gRnVuZ3NpIG1lbWJ1YXQgaGlzdG9ncmFtIGRlbmdhbiBnYXJpcyBtZWFuLCBtZWRpYW4sIG1vZGUgLS0tDQpjcmVhdGVfaGlzdG9ncmFtIDwtIGZ1bmN0aW9uKGNvbHVtbl9kYXRhLCBjb2x1bW5fbmFtZSwgZmlsbF9jb2xvcikgew0KICBkZiA8LSBkYXRhLmZyYW1lKHZhbHVlID0gY29sdW1uX2RhdGEpDQogIA0KICBtZWFuX3ZhbCA8LSBtZWFuKGNvbHVtbl9kYXRhLCBuYS5ybSA9IFRSVUUpDQogIG1lZGlhbl92YWwgPC0gbWVkaWFuKGNvbHVtbl9kYXRhLCBuYS5ybSA9IFRSVUUpDQogIG1vZGVfdmFsIDwtIGdldF9tb2RlKHJvdW5kKGNvbHVtbl9kYXRhLCAwKSkNCiAgDQogIGdncGxvdChkZiwgYWVzKHggPSB2YWx1ZSkpICsNCiAgICBnZW9tX2hpc3RvZ3JhbShhZXMoeSA9IC4uZGVuc2l0eS4uKSwgDQogICAgICAgICAgICAgICAgICAgYmlucyA9IDMwLCANCiAgICAgICAgICAgICAgICAgICBmaWxsID0gZmlsbF9jb2xvciwgDQogICAgICAgICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiLCANCiAgICAgICAgICAgICAgICAgICBhbHBoYSA9IDAuOCkgKw0KICAgIGdlb21fZGVuc2l0eShhbHBoYSA9IDAuMywgZmlsbCA9ICJncmF5OTAiKSArDQogICAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdCA9IG1lYW5fdmFsLCBjb2xvciA9ICJNZWFuIiksIGxpbmV0eXBlID0gImRhc2hlZCIsIHNpemUgPSAxLjIpICsNCiAgICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0ID0gbWVkaWFuX3ZhbCwgY29sb3IgPSAiTWVkaWFuIiksIGxpbmV0eXBlID0gImRvdHRlZCIsIHNpemUgPSAxLjIpICsNCiAgICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0ID0gbW9kZV92YWwsIGNvbG9yID0gIk1vZGUiKSwgbGluZXR5cGUgPSAic29saWQiLCBzaXplID0gMS4yKSArDQogICAgc2NhbGVfY29sb3JfbWFudWFsKA0KICAgICAgbmFtZSA9ICJLZXRlcmFuZ2FuIEdhcmlzIiwNCiAgICAgIHZhbHVlcyA9IGMoIk1lYW4iID0gInJlZCIsICJNZWRpYW4iID0gImdyZWVuIiwgIk1vZGUiID0gImJsdWUiKQ0KICAgICkgKw0KICAgIGxhYnMoDQogICAgICB0aXRsZSA9IHBhc3RlKCJEaXN0cmlidXNpIiwgY29sdW1uX25hbWUpLA0KICAgICAgc3VidGl0bGUgPSBwYXN0ZSgiTWVhbjoiLCByb3VuZChtZWFuX3ZhbCwgMiksDQogICAgICAgICAgICAgICAgICAgICAgICJ8IE1lZGlhbjoiLCByb3VuZChtZWRpYW5fdmFsLCAyKSwNCiAgICAgICAgICAgICAgICAgICAgICAgInwgTW9kZToiLCByb3VuZChtb2RlX3ZhbCwgMikpLA0KICAgICAgeCA9IGNvbHVtbl9uYW1lLA0KICAgICAgeSA9ICJGcmVxdWVuY3kiDQogICAgKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICB0aGVtZSgNCiAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDEyKSwNCiAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDksIGNvbG9yID0gImdyYXk0MCIpLA0KICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsDQogICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGNvbG9yID0gImdyYXk5MCIpLA0KICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKQ0KICAgICkNCn0NCg0KIyAtLS0gQnVhdCBkdWEgaGlzdG9ncmFtIGRhcmkgZGF0YSB5YW5nIHN1ZGFoIGFkYSAtLS0NCmhpc3QxIDwtIGNyZWF0ZV9oaXN0b2dyYW0oZGF0YSRNYXJrZXRpbmdTcGVuZCwgIk1hcmtldGluZyBTcGVuZCIsICJza3libHVlIikNCmhpc3QyIDwtIGNyZWF0ZV9oaXN0b2dyYW0oZGF0YSRNb250aGx5UmV2ZW51ZSwgIk1vbnRobHkgUmV2ZW51ZSIsICJvcmFuZ2UiKQ0KDQojIC0tLSBUYW1waWxrYW4gYmVyZGFtcGluZ2FuIC0tLQ0KZ3JpZC5hcnJhbmdlKGhpc3QxLCBoaXN0MiwgbmNvbCA9IDIpDQogICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgDQpgYGANCg0KSW5zaWdodCA6DQoNCjEuIE1hcmtldGluZyBTcGVuZCBtZW5nZ2FtYmFya2FuIGJlc2FybnlhIGJpYXlhIHlhbmcgZGlrZWx1YXJrYW4gdW50dWsga2VnaWF0YW4gcGVtYXNhcmFuIHNldGlhcCBidWxhbi4NCjIuIE1vbnRobHkgUmV2ZW51ZSBtZW51bmp1a2thbiBqdW1sYWggcGVuZGFwYXRhbiB5YW5nIGRpcGVyb2xlaCBwZXJ1c2FoYWFuIGRhbGFtIHBlcmlvZGUgeWFuZyBzYW1hLg0KS2VkdWEgdmFyaWFiZWwgaW5pIG1lbWlsaWtpIGh1YnVuZ2FuIGxvZ2lzIHNlbWFraW4gdGluZ2dpIHBlbmdlbHVhcmFuIHBlbWFzYXJhbiwgZGloYXJhcGthbiBwZW5kYXBhdGFuIGp1Z2EgbWVuaW5na2F0Lg0KDQoNCiMgTWVhc3VyZXMgb2YgRGlzcGVyc2lvbg0KTWVhc3VyZXMgb2YgZGlzcGVyc2lvbiBhZGFsYWggc2VyYW5na2FpYW4gdGVrbmlrIHN0YXRpc3RpayB5YW5nIGRpZ3VuYWthbiB1bnR1ayBtZW5ndWt1ciBzZWJhcmFuIGF0YXUgdmFyaWFzaSBkYXRhIGRhbGFtIHN1YXR1IGRhdGFzZXQuIFNlbWVudGFyYSBtZWFzdXJlcyBvZiBjZW50cmFsIHRlbmRlbmN5IHNlcGVydGkgbWVhbiBkYW4gbWVkaWFuIGhhbnlhIG1lbWJlcmlrYW4gaW5mb3JtYXNpIHRlbnRhbmcgbmlsYWkgdGVuZ2FoLCBtZWFzdXJlcyBvZiBkaXNwZXJzaW9uIG1lbmd1bmdrYXAgc2ViZXJhcGEgamF1aCB0aXRpayBkYXRhIGluZGl2aWR1YWwgdGVyc2ViYXIgZGFyaSBuaWxhaSBwdXNhdCB0ZXJzZWJ1dC4gS29uc2VwIGluaSBzYW5nYXQga3J1c2lhbCBkYWxhbSBhbmFsaXNpcyBkYXRhIGthcmVuYSBkdWEgZGF0YXNldCBkZW5nYW4gbWVhbiB5YW5nIHNhbWEgYmlzYSBtZW1pbGlraSBrYXJha3RlcmlzdGlrIHlhbmcgc2FuZ2F0IGJlcmJlZGEgLSBzYXR1IG11bmdraW4gc2FuZ2F0IGtvbnNpc3RlbiBkZW5nYW4gZGF0YSB5YW5nIG1lbmdlbG9tcG9rIHJhcGF0LCBzZW1lbnRhcmEgbGFpbm55YSBtZW1pbGlraSB2YXJpYXNpIHlhbmcgbHVhcy4gQmViZXJhcGEgdWt1cmFuIGRpc3BlcnNpIHlhbmcgdW11bSBkaWd1bmFrYW4gbWVsaXB1dGkgcmFuZ2UsIHZhcmlhbmNlLCBzdGFuZGFyZCBkZXZpYXRpb24sIGRhbiBpbnRlcnF1YXJ0aWxlIHJhbmdlIChJUVIpLCB5YW5nIG1hc2luZy1tYXNpbmcgbWVtYmVyaWthbiBwZXJzcGVrdGlmIGJlcmJlZGEgdGVudGFuZyBrb25zaXN0ZW5zaSBkYW4gcmVsaWFiaWxpdGFzIGRhdGEgeWFuZyBkaWFuYWxpc2lzLg0KDQpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHRpZHlyKQ0KbGlicmFyeShncmlkRXh0cmEpDQpsaWJyYXJ5KGtuaXRyKQ0KDQojIE1lbWlsaWggaGFueWEga29sb20gbnVtZXJpayB1bnR1ayBhbmFsaXNpcyBkaXNwZXJzaQ0KbnVtZXJpY19jb2xzIDwtIGRhdGEgJT4lIA0KICBzZWxlY3Qod2hlcmUoaXMubnVtZXJpYykpICU+JSANCiAgc2VsZWN0KC0xKSAjIE1lbmdoYXB1cyBrb2xvbSBwZXJ0YW1hIChpbmRleCkNCg0KIyBNZW5naGl0dW5nIG1lYXN1cmVzIG9mIGRpc3BlcnNpb24gdW50dWsgc2V0aWFwIHZhcmlhYmVsIG51bWVyaWsgKERJQlVBVCBUQUJFTCkNCmRpc3BlcnNpb25fc3RhdHMgPC0gZGF0YS5mcmFtZSgNCiAgVmFyaWFibGUgPSBuYW1lcyhudW1lcmljX2NvbHMpLA0KICBNZWFuID0gc2FwcGx5KG51bWVyaWNfY29scywgbWVhbiwgbmEucm0gPSBUUlVFKSwNCiAgTWVkaWFuID0gc2FwcGx5KG51bWVyaWNfY29scywgbWVkaWFuLCBuYS5ybSA9IFRSVUUpLA0KICBTRCA9IHNhcHBseShudW1lcmljX2NvbHMsIHNkLCBuYS5ybSA9IFRSVUUpLA0KICBWYXJpYW5jZSA9IHNhcHBseShudW1lcmljX2NvbHMsIHZhciwgbmEucm0gPSBUUlVFKSwNCiAgSVFSID0gc2FwcGx5KG51bWVyaWNfY29scywgSVFSLCBuYS5ybSA9IFRSVUUpLA0KICBSYW5nZSA9IHNhcHBseShudW1lcmljX2NvbHMsIGZ1bmN0aW9uKHgpIG1heCh4LCBuYS5ybSA9IFRSVUUpIC0gbWluKHgsIG5hLnJtID0gVFJVRSkpLA0KICBDViA9IHNhcHBseShudW1lcmljX2NvbHMsIGZ1bmN0aW9uKHgpIHNkKHgsIG5hLnJtID0gVFJVRSkvbWVhbih4LCBuYS5ybSA9IFRSVUUpKSAjIENvZWZmaWNpZW50IG9mIFZhcmlhdGlvbg0KKQ0KDQojIFBlcmJhaWtpIGZ1bmdzaSBoaXN0b2dyYW0NCmRpc2NyZWF0ZV9oaXN0b2dyYW0gPC0gZnVuY3Rpb24oY29sdW1uX2RhdGEsIGNvbHVtbl9uYW1lLCBjb2xvcikgew0KICAgIGRmIDwtIGRhdGEuZnJhbWUodmFsdWUgPSBjb2x1bW5fZGF0YSkNCiAgICANCiAgICAjIEhpdHVuZyBzdGF0cyB1bnR1ayBhbm5vdGFzaSAocGVyYmFpa2kgdHlwbykNCiAgICBtZWFuX3ZhbCA8LSBtZWFuKGNvbHVtbl9kYXRhLCBuYS5ybSA9IFRSVUUpDQogICAgc2RfdmFsIDwtIHNkKGNvbHVtbl9kYXRhLCBuYS5ybSA9IFRSVUUpDQogICAgaXFyX3ZhbCA8LSBJUVIoY29sdW1uX2RhdGEsIG5hLnJtID0gVFJVRSkNCiAgICANCiAgICAjIC4uLiBsYW5qdXRhbiBrb2RlIHBsb3QNCn0NCg0KIyBSZXNldCByb3cgbmFtZXMgdW50dWsgdGFiZWwNCnJvd25hbWVzKGRpc3BlcnNpb25fc3RhdHMpIDwtIE5VTEwNCg0KIyBCdWF0IHRhYmVsDQprYWJsZShkaXNwZXJzaW9uX3N0YXRzLCBkaWdpdHMgPSAyLCBjYXB0aW9uID0gIlN1bW1hcnkgU3RhdGlzdGljcyB1bnR1ayBWYXJpYWJlbCBOdW1lcmlrIikNCg0KYGBgDQoNCiMjIEhpc3RvZ3JhbQ0KDQpgYGB7cixtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KIyBGdW5nc2kgdW50dWsgbWVtYnVhdCBoaXN0b2dyYW0gZGVuZ2FuIGFubm90YXNpIG1lYXN1cmVzIG9mIGRpc3BlcnNpb24NCmNyZWF0ZV9oaXN0b2dyYW0gPC0gZnVuY3Rpb24oY29sdW1uX2RhdGEsIGNvbHVtbl9uYW1lLCBjb2xvcikgew0KICBkZiA8LSBkYXRhLmZyYW1lKHZhbHVlID0gY29sdW1uX2RhdGEpDQogIA0KICAjIE1lbmdoaXR1bmcgc3RhdHMgdW50dWsgYW5ub3Rhc2kNCiAgbWVhbl92YWwgPC0gbWVhbihjb2x1bW5fZGF0YSwgbmEucm0gPSBUUlVFKQ0KICBzZF92YWwgPC0gc2QoY29sdW1uX2RhdGEsIG5hLnJtID0gVFJVRSkNCiAgaXFyX3ZhbCA8LSBJUVIoY29sdW1uX2RhdGEsIG5hLnJtID0gVFJVRSkNCiAgY3ZfdmFsIDwtIHNkX3ZhbCAvIG1lYW5fdmFsDQogIA0KICBnZ3Bsb3QoZGYsIGFlcyh4ID0gdmFsdWUpKSArDQogICAgZ2VvbV9oaXN0b2dyYW0oYWVzKHkgPSAuLmRlbnNpdHkuLiksIA0KICAgICAgICAgICAgICAgICAgIGZpbGwgPSBjb2xvciwgDQogICAgICAgICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiLCANCiAgICAgICAgICAgICAgICAgICBhbHBoYSA9IDAuOCwgDQogICAgICAgICAgICAgICAgICAgYmlucyA9IDMwKSArDQogICAgZ2VvbV9kZW5zaXR5KGFscGhhID0gMC41LCBmaWxsID0gImRhcmtibHVlIikgKw0KICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IG1lYW5fdmFsLCBjb2xvciA9ICJyZWQiLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBzaXplID0gMSkgKw0KICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IG1lZGlhbihjb2x1bW5fZGF0YSwgbmEucm0gPSBUUlVFKSwgDQogICAgICAgICAgICAgICBjb2xvciA9ICJncmVlbiIsIGxpbmV0eXBlID0gImRhc2hlZCIsIHNpemUgPSAxKSArDQogICAgbGFicyh0aXRsZSA9IHBhc3RlKCJEaXN0cmlidXNpIiwgY29sdW1uX25hbWUpLA0KICAgICAgICAgc3VidGl0bGUgPSBwYXN0ZSgiTWVhbjoiLCByb3VuZChtZWFuX3ZhbCwgMiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICJ8IFNEOiIsIHJvdW5kKHNkX3ZhbCwgMiksDQogICAgICAgICAgICAgICAgICAgICAgICAgInwgSVFSOiIsIHJvdW5kKGlxcl92YWwsIDIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICJ8IENWOiIsIHJvdW5kKGN2X3ZhbCwgMikpLA0KICAgICAgICAgeCA9IGNvbHVtbl9uYW1lLA0KICAgICAgICAgeSA9ICJEZW5zaXR5IikgKw0KICAgIHRoZW1lX21pbmltYWwoKSArDQogICAgdGhlbWUoDQogICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxMiksDQogICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA5LCBjb2xvciA9ICJkYXJrZ3JheSIpLA0KICAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJncmF5OTAiKSwNCiAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkNCiAgICApDQp9DQoNCiMgTWVtYnVhdCBoaXN0b2dyYW0gdW50dWsgdmFyaWFiZWwgbnVtZXJpayB1dGFtYQ0KaGlzdG9ncmFtcyA8LSBsaXN0KCkNCg0KIyBNYXJrZXRpbmdTcGVuZA0KaGlzdG9ncmFtc1tbMV1dIDwtIGNyZWF0ZV9oaXN0b2dyYW0obnVtZXJpY19jb2xzJE1hcmtldGluZ1NwZW5kLCAiTWFya2V0aW5nIFNwZW5kIiwgIiNGRjZCNkIiKQ0KDQojIFByb2R1Y3RQcmljZQ0KaGlzdG9ncmFtc1tbMl1dIDwtIGNyZWF0ZV9oaXN0b2dyYW0obnVtZXJpY19jb2xzJFByb2R1Y3RQcmljZSwgIlByb2R1Y3QgUHJpY2UiLCAiIzRFQ0RDNCIpDQoNCiMgRW1wbG95ZWVDb3VudCAoZmlsdGVyIG5pbGFpIG5lZ2F0aWYpDQplbXBsb3llZV9jbGVhbiA8LSBudW1lcmljX2NvbHMkRW1wbG95ZWVDb3VudFtudW1lcmljX2NvbHMkRW1wbG95ZWVDb3VudCA+PSAwXQ0KaGlzdG9ncmFtc1tbM11dIDwtIGNyZWF0ZV9oaXN0b2dyYW0oZW1wbG95ZWVfY2xlYW4sICJFbXBsb3llZSBDb3VudCIsICIjNDVCN0QxIikNCg0KIyBNYW5hZ2VyRXhwZXJpZW5jZQ0KaGlzdG9ncmFtc1tbNF1dIDwtIGNyZWF0ZV9oaXN0b2dyYW0obnVtZXJpY19jb2xzJE1hbmFnZXJFeHBlcmllbmNlLCAiTWFuYWdlciBFeHBlcmllbmNlIiwgIiM5NkNFQjQiKQ0KDQojIEN1c3RvbWVyUmF0aW5nDQpoaXN0b2dyYW1zW1s1XV0gPC0gY3JlYXRlX2hpc3RvZ3JhbShudW1lcmljX2NvbHMkQ3VzdG9tZXJSYXRpbmcsICJDdXN0b21lciBSYXRpbmciLCAiI0ZGRUFBNyIpDQoNCiMgTW9udGhseVJldmVudWUNCmhpc3RvZ3JhbXNbWzZdXSA8LSBjcmVhdGVfaGlzdG9ncmFtKG51bWVyaWNfY29scyRNb250aGx5UmV2ZW51ZSwgIk1vbnRobHkgUmV2ZW51ZSIsICIjRERBMEREIikNCg0KIyBNZW5nZ2FidW5na2FuIHNlbXVhIGhpc3RvZ3JhbQ0KZ3JpZC5hcnJhbmdlKGdyb2JzID0gaGlzdG9ncmFtcywgbmNvbCA9IDIsIA0KICAgICAgICAgICAgIHRvcCA9ICJBbmFsaXNpcyBEaXN0cmlidXNpIGRhbiBNZWFzdXJlcyBvZiBEaXNwZXJzaW9uIikNCg0KDQpgYGANCg0KSW5zaWdodCA6DQoNCkJlcmRhc2Fya2FuIGFuYWxpc2lzIGhpc3RvZ3JhbSB1bnR1ayBzZXRpYXAgdmFyaWFiZWwsIGJlcmlrdXQgaW5zaWdodCByaW5na2FzbnlhIDoNCg0KMS4gQ2l0eQ0KwrcgRGF0YSB0ZXJzZWJhciBtZXJhdGEgZGkgNSBrb3RhIChKYWthcnRhLCBTdXJhYmF5YSwgQmFuZHVuZywgTWVkYW4sIE1ha2Fzc2FyKS4NCsK3IFRpZGFrIGFkYSBkb21pbmFzaSBrb3RhIHRlcnRlbnR1LCBtZW51bmp1a2thbiByZXByZXNlbnRhc2kgeWFuZyBzZWltYmFuZy4NCg0KMi4gQnVzaW5lc3NUeXBlDQrCtyAiRm9vZCAmIEJldmVyYWdlIiBhZGFsYWggdGlwZSBiaXNuaXMgcGFsaW5nIHVtdW0uDQrCtyBEaWlrdXRpIG9sZWggUmV0YWlsLCBUZWNobm9sb2d5LCBkYW4gTWFudWZhY3R1cmluZy4NCg0KMy4gU2FsZXNDaGFubmVsDQrCtyBEaXN0cmlidXNpIGhhbXBpciBzZWltYmFuZyBhbnRhcmEgT25saW5lIGRhbiBPZmZsaW5lLg0KwrcgVHJlbiBwZW5qdWFsYW4gaHlicmlkIChkYXJpbmcgJiBsdXJpbmcpIHRlcmNlcm1pbiBkYWxhbSBkYXRhLg0KDQo0LiBNYXJrZXRpbmdTcGVuZA0KwrcgU2ViYWdpYW4gYmVzYXIgYmVyYWRhIGRpIHJlbnRhbmcgbWVuZW5nYWggKOKJiDUw4oCTMTIwKS4NCsK3IEFkYSBiZWJlcmFwYSBvdXRsaWVyIGRlbmdhbiBhbmdnYXJhbiBzYW5nYXQgdGluZ2dpIGF0YXUgcmVuZGFoLg0KDQo1LiBQcm9kdWN0UHJpY2UNCsK3IEhhcmdhIHByb2R1ayB0ZXJrb25zZW50cmFzaSBkaSByZW50YW5nIHJlbmRhaCBoaW5nZ2EgbWVuZW5nYWggKOKJiDLigJM4KS4NCsK3IEJlYmVyYXBhIHByb2R1ayBtZW1pbGlraSBoYXJnYSBwcmVtaXVtICg+OSkuDQoNCjYuIEVtcGxveWVlQ291bnQNCsK3IE1heW9yaXRhcyBwZXJ1c2FoYWFuIG1lbWlsaWtpIDMw4oCTNzAga2FyeWF3YW4uDQrCtyBCZWJlcmFwYSBvdXRsaWVyIGRlbmdhbiBqdW1sYWgga2FyeWF3YW4gZWtzdHJlbSAoc2FuZ2F0IHNlZGlraXQgYXRhdSBzYW5nYXQgYmFueWFrKS4NCg0KNy4gTWFuYWdlckV4cGVyaWVuY2UNCsK3IFBlbmdhbGFtYW4gbWFuYWplciB0ZXJzZWJhciBsdWFzLCBkYXJpIHBlbXVsYSAoPDIgdGFodW4pIGhpbmdnYSBzYW5nYXQgYmVycGVuZ2FsYW1hbiAoPjEyIHRhaHVuKS4NCsK3IERpc3RyaWJ1c2kgY2VuZGVydW5nIG5vcm1hbCBkZW5nYW4gc2VkaWtpdCBjb25kb25nIGtlIHBlbmdhbGFtYW4gbWVuZW5nYWguDQoNCjguIEN1c3RvbWVyUmF0aW5nDQrCtyBSYXRpbmcgcGVsYW5nZ2FuIHVtdW1ueWEgdGluZ2dpICg3MOKAkzkwKS4NCsK3IERpc3RyaWJ1c2kgbWlyaW5nIGtlIGtpcmksIG1lbnVuanVra2FuIGtlcHVhc2FuIHBlbGFuZ2dhbiB5YW5nIGJhaWsgc2VjYXJhIGtlc2VsdXJ1aGFuLg0KDQo5LiBNb250aGx5UmV2ZW51ZQ0KwrcgUGVuZGFwYXRhbiBidWxhbmFuIGJlcmFnYW0sIGRlbmdhbiBwdW5jYWsgZGkgcmVudGFuZyDiiYgxNTDigJMyNTAuDQrCtyBTZWJhZ2lhbiBiaXNuaXMgbWVtaWxpa2kgcGVuZGFwYXRhbiBzYW5nYXQgdGluZ2dpICg+MzAwKSwgbWVudW5qdWtrYW4gYWRhbnlhIHBlcmZvcm1hIHVuZ2d1bGFuLg0KDQpLZXNpbXB1bGFuIFVtdW06DQpEYXRhIG1lbnVuanVra2FuIGtlcmFnYW1hbiBiaXNuaXMgZGVuZ2FuIHBlcmZvcm1hIHlhbmcgdmFyaWF0aWYuIEYmQiBkb21pbmFuLCBrZXB1YXNhbiBwZWxhbmdnYW4gdW11bW55YSBiYWlrLCBkYW4gcGVuZGFwYXRhbiBjZW5kZXJ1bmcgdGVya29uc2VudHJhc2kgZGkgcmVudGFuZyBtZW5lbmdhaC4NCg0KIyMgU2NhdHRlciBQbG90DQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZGYgPC0gcmVhZC5jc3YoIkM6L1VzZXJzL0l5YW4vRG93bmxvYWRzL01pZHRlcm0gRXhhbS5jc3YiKQ0KDQpsaWJyYXJ5KGdncGxvdDIpDQoNCiMgc2NhdHRlcmxvdA0KZ2dwbG90KGRhdGEgPSBkZiwgDQogICAgICAgYWVzKHggPSBNYXJrZXRpbmdTcGVuZCwgeSA9IE1vbnRobHlSZXZlbnVlKSkgKw0KICANCiAgIyBNZW5hbWJhaGthbiB0aXRpay10aXRpaw0KICBnZW9tX3BvaW50KGFscGhhID0gMC42LCBjb2xvciA9ICJkYXJrc2VhZ3JlZW4zIikgKw0KICANCiAgIyBNZW5hbWJhaGthbiBnYXJpcyB0cmVuIGxpbmVhciAocmVncmVzaSkNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAiZGFya29saXZlZ3JlZW4iLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIA0KICAjIE1lbmFtYmFoa2FuIEp1ZHVsIGRhbiBMYWJlbA0KICBsYWJzKHRpdGxlID0gIkh1YnVuZ2FuIGFudGFyYSBQZW5nZWx1YXJhbiBQZW1hc2FyYW4gZGFuIFBlbmRhcGF0YW4gQnVsYW5hbiIsDQogICAgICAgeCA9ICJQZW5nZWx1YXJhbiBQZW1hc2FyYW4gKE1hcmtldGluZ1NwZW5kKSIsDQogICAgICAgeSA9ICJQZW5kYXBhdGFuIEJ1bGFuYW4gKE1vbnRobHlSZXZlbnVlKSIpICsNCiAgDQogICMgTWVuZ2F0dXIgVGVtYSBQbG90DQogIHRoZW1lX21pbmltYWwoKSArIA0KICANCiAgIyBNZW55ZXN1YWlrYW4gdGFtcGlsYW4ganVkdWwNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgc2l6ZSA9IDE2LCBmYWNlID0gImJvbGQiKSwNCiAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpKQ0KICAgICAgICANCmBgYA0KDQpJbnNpZ2h0IDogDQoNClNjYXR0ZXIgcGxvdCB0ZXJzZWJ1dCBtZW51bmp1a2thbiBhZGFueWEgaHVidW5nYW4gcG9zaXRpZiB5YW5nIGplbGFzIGFudGFyYSBwZW5nZWx1YXJhbiBQZW1hc2FyYW4gZGFuIFBlbmRhcGF0YW4gQnVsYW5hbi4gR2FyaXMgdHJlbiByZWdyZXNpIGxpbmVhciBha2FuIG1pcmluZyBrZSBhdGFzLiBIYWwgaW5pIG1lbmdpbmRpa2FzaWthbiBiYWh3YSBzZW1ha2luIHRpbmdnaSBkYW5hIHlhbmcgZGloYWJpc2thbiB1bnR1ayAoTWFya2V0aW5nU3BlbmQpLCBjZW5kZXJ1bmcgc2VtYWtpbiB0aW5nZ2kgcHVsYSAoTW9udGhseVJldmVudWUpIHlhbmcgZGloYXNpbGthbi4gVmlzdWFsaXNhc2kgaW5pIHNlY2FyYSBrZXNlbHVydWhhbiBtZW5kdWt1bmcgaGlwb3Rlc2lzIGJhaHdhIGludmVzdGFzaSB5YW5nIGxlYmloIGJlc2FyIGRhbGFtIHBlbWFzYXJhbiBtZXJ1cGFrYW4gZmFrdG9yIHlhbmcgc2lnbmlmaWthbiBkYWxhbSBtZW5kb3JvbmcgcGVydHVtYnVoYW4gcGVuZGFwYXRhbiBidWxhbmFuLiBOYW11biwgYWRhbnlhIGRpc3BlcnNpIG1lbnVuanVra2FuIGJhaHdhIGVmZWt0aXZpdGFzIHBlbWFzYXJhbiB0aWRhayAxMDAlIGRpamFtaW4gZGFuIGRpcGVuZ2FydWhpIG9sZWggZmFrdG9yLWZha3RvciBsYWluIHNlcGVydGkga3VhbGl0YXMgcHJvZHVrIGF0YXUgaGFyZ2EuDQoNCg0KIyMgQm94IFBsb3QNCg0KYGBge3J9DQpsaWJyYXJ5KGdyaWRFeHRyYSkNCiMgUGlsaWggZHVhIHZhcmlhYmVsIG51bWVyaWsgdW50dWsgYW5hbGlzaXMgKHViYWggc2VzdWFpIGRhdGFzZXQga2FtdSkNCm51bV92YXIxIDwtIGRhdGEkTWFya2V0aW5nU3BlbmQgICAjIDwtLSB1YmFoIHNlc3VhaSBuYW1hIGtvbG9tIGRhdGFzZXQga2FtdQ0KbnVtX3ZhcjIgPC0gZGF0YSRNb250aGx5UmV2ZW51ZSAjIDwtLSB1YmFoIHNlc3VhaSBuYW1hIGtvbG9tIGRhdGFzZXQga2FtdQ0KDQojIEJveHBsb3QgKFZpc3VhbGlzYXNpIHV0YW1hIHVudHVrIGRpc3BlcnNpb24pDQpib3hwbG90MSA8LSBnZ3Bsb3QoZGF0YSwgYWVzKHkgPSBudW1fdmFyMSkpICsNCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAiY3lhbiIsIGNvbG9yID0gImRhcmtibHVlIikgKw0KICBsYWJzKHRpdGxlID0gIk1hcmtldGluZyBTcGVuZCIsIHkgPSAiRnJlcXVlbmN5IikgKw0KICB0aGVtZV9taW5pbWFsKCkjIEJveHBsb3QgKFZpc3VhbGlzYXNpIHV0YW1hIHVudHVrIGRpc3BlcnNpb24pDQoNCiMgQm94cGxvdCAoVmlzdWFsaXNhc2kgdXRhbWEgdW50dWsgZGlzcGVyc2lvbikNCmJveHBsb3QyIDwtIGdncGxvdChkYXRhLCBhZXMoeSA9IG51bV92YXIyKSkgKw0KICBnZW9tX2JveHBsb3QoZmlsbCA9ICJjeWFuIiwgY29sb3IgPSAiZGFya2JsdWUiKSArDQogIGxhYnModGl0bGUgPSAiTW9udGhseSBSZXZlbnVlIiwgeSA9ICJGcmVxdWVuY3kiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQpncmlkLmFycmFuZ2UoYm94cGxvdDEsIGJveHBsb3QyLCBuY29sID0gMikNCg0KYGBgDQoNCkluc2lnaHQ6DQoNCkJveHBsb3QgbWVuYW1waWxrYW4gZGlzdHJpYnVzaSBkdWEgdmFyaWFiZWw6IE1hcmtldGluZyBTcGVuZCBkYW4gTW9udGhseSBSZXZlbnVlLg0KV2FybmEgY3lhbiBtZW51bmp1a2thbiByZW50YW5nIFEx4oCTUTMsIGdhcmlzIGhpdGFtIG1lZGlhbiwgZGFuIHdoaXNrZXIgYmF0YXMgbmlsYWkgd2FqYXIuDQoNCi0gTWFya2V0aW5nIFNwZW5kDQpNZWRpYW4gc2VraXRhciA4MOKAkzg1LCByZW50YW5nIGRhdGEgc2VtcGl0IOKGkiBwZW5nZWx1YXJhbiBzdGFiaWwgdGFucGEgb3V0bGllci4NCktlc2ltcHVsYW46IFBlbmdlbHVhcmFuIHBlbWFzYXJhbiByZWxhdGlmIGtvbnNpc3Rlbi4NCg0KLSBNb250aGx5IFJldmVudWUNCk1lZGlhbiAxODDigJMyMDAsIHZhcmlhc2kgbGViaWggYmVzYXIsIGNlbmRlcnVuZyBtaXJpbmcga2UgYmF3YWguDQpLZXNpbXB1bGFuOiBQZW5kYXBhdGFuIGJ1bGFuYW4gbGViaWggZmx1a3R1YXRpZi4NCg0KLSBIdWJ1bmdhbiANCk1hcmtldGluZyBzcGVuZCBzdGFiaWwsIHJldmVudWUgbGViaWggYmVydmFyaWFzaS4NCkFuYWxpc2lzIGxhbmp1dCBkYXBhdCBkaWxha3VrYW4gZGVuZ2FuIGtvcmVsYXNpIGF0YXUgc2NhdHRlcnBsb3QgdW50dWsgbWVsaWhhdCBodWJ1bmdhbiBrZWR1YW55YS4NCg0KDQojIyBJbnRlcnByZXRhdGlvbg0KDQotIEhpc3RvZ3JhbSAtPiB0ZXJsaWhhdCBiYWh3YSBNYXJrZXRpbmcgU3BlbmQgbWVtaWxpa2kgc2ViYXJhbiBkYXRhIHlhbmcgcGFsaW5nIGxlYmFyIGRpYmFuZGluZ2thbiB2YXJpYWJlbCBsYWlubnlhLiBTZW1lbnRhcmEgaXR1LCBNb250aGx5IFJldmVudWUgbWVueWViYXIgbWVuZ2lrdXRpIHBvbGEgdGVydGVudHUuIFZhcmlhYmVsIGRlbmdhbiB2YXJpYWJpbGl0YXMgYmVzYXIgeWFpdHUgTWFya2V0aW5nIFNwZW5kIGthcmVuYSBiYXRhbmdueWEgbWVueWViYXIgcGFsaW5nIGxlYmFyIG1lbmFuZGFrYW4gbmlsYWkgc2FuZ2F0IGJlcnZhcmlhc2kuIA0KDQotIFNjYXR0ZXJwbG90IC0+IFRpdGlrIHRpdGlrIGRhdGEgbWVueWViYXIgY3VrdXAgbHVhcyBkYW4gdGlkYWsgbWVtYmVudHVrIGdhcmlzIHlhbmcgcmFwYXQuIEluaSBtZW51bmp1a2thbiBhZGFueWEgdmFyaWFzaSBiZXNhciBhbnRhcmEgcGVuZ2VsdWFyYW4gcGVtYXNhcmFuIGRhbiBwZW5kYXBhdGFuIHlhbmcgZGlkYXBhdCwgVmFyaWFiaWxpdGFzIHRlcmJlc2FyIHRlcmxpaGF0IGRpIE1vbnRobHkgUmV2ZW51ZSBrYXJlbmEgc2ViYXJhbiB0aXRpayBkaSBzdW1idS1YIG55YSBwYWxpbmcgbHVhcy4NCg0KLSBCb3hwbG90IC0+IEtvdGFrKElRUikgTWFya2V0aW5nIFNwZW5kIHRhbXBhayBwYWxpbmcgcGFuamFuZyBkYW4gbWVtaWxpa2kgYmViZXJhcGEgb3V0bGllciB5YW5nIGJlcmFydGkgZGF0YSBsZWJpaCBiZXJ2YXJpYXNpIGRhbiB0aWRhayBzZXJhZ2FtLiBWYXJpYWJlbCBNb250aGx5IFJldmVudWUgbWVudW5qdWtrYW4gcGVueWViYXJhbiBzZWRhbmcuIERlbmdhbiBkZW1pa2lhbiwgTWFya2V0aW5nIFNwZW5kIG1lbnVuanVra2FuIHZhcmlhYmlsaXRhcyB0ZXJiZXNhciBrYXJlbmEgbmlsYWktbmlsYWlueWEgdGVzZWJhciBqYXVoIGRhcmkgcmF0YS1yYXRhIGRhbiBtZW1pbGlraSByZW50YW5nIHlhbmcgbHVhcy4NCg0KDQojIFN1bW1hcnkgYW5kIEludGVycHJldGF0aW9uDQoNCkJlcmRhc2Fya2FuIGFuYWxpc2lzIGRhdGEsIGRhcGF0IGRpc2ltcHVsa2FuIGJhaHdhIHBlbmRhcGF0YW4gYnVsYW5hbiBzdWF0dSBiaXNuaXMgZGlwZW5nYXJ1aGkgb2xlaCBiZWJlcmFwYSBmYWt0b3IgdXRhbWEsIHNlcGVydGkgcGVuZ2VsdWFyYW4gcGVtYXNhcmFuLCBwZW5nYWxhbWFuIG1hbmFnZXIgZGFuIHBlbmlsYWlhbiBwZWxhbmdnYW4uIA0KQmVyaWt1dCBrZXNpbXB1bGFuIGRhbiBwZW5qZWxhc2FubnlhIDoNCg0KLSBWYXJpYWJlbCB5YW5nIHBhbGluZyBrb25zaXN0ZW4gKERpc3BlcnNpIFJlbmRhaCkgOg0KQ3VzdG9tZXIgUmF0aW5nLCBrYXJlbmEgbmlsYWlueWEgZGFsYW0ganVtbGFoIGtlY2lsIHlhbmcgc2FsaW5nIGJlcmRla2F0YW4gbWFrYSBwZW55ZWJhcmFubnlhIGNlbmRlcnVuZyByZW5kYWguIFBlbmlsYWlhbiBwZWxhbmdnYW4gZGkgYmVyYmFnYWkga290YSBkYW4gamVuaXMgYmlzbmlzIHJlbGF0aWYgc3RhYmlsIHlhbmcgYmVyYXJ0aSBrZXB1YXNhbiBwZWxhbmdnYW4gdGlkYWsgdGVybGFsdSBiZXJiZWRhIGphdWggYW50YXIgd2lsYXlhaC4NCg0KLSBWYXJpYWJlbCBkZW5nYW4gVmFyaWFzaSB0ZXJiZXNhciAoRGlzcGVyc2kgVGluZ2dpKSA6DQpNb250aGx5IFJldmVudWUgZGFuIE1hcmtldGluZyBTcGVuZCwga2FyZW5hIGtlZHVhIHZhcmlhYmVsIHRlcnNlYnV0IG1lbnVuanVra2FuIHBlcmJlZGFhbiBiZXNhciBhbnRhciBiaXNuaXMuIEJlYmVyYXBhIGJpc25pcyBtdW5na2luIHNhbmdhdCBhZ3Jlc2lmIGRhbGFtIHBlbWFzYXJhbiBkYW4gbWVuZ2hhc2lsa2FuIHBlbmRhcGF0YW4gdGluZ2dpLCBzZW1lbnRhcmEgeWFuZyBsYWluIGJlcm9wZXJhc2kgZGVuZ2FuIHN1bWJlciBkYXlhIHRlcmJhdGFzLg0KDQotIFBvbGEgYXRhdSBXYXdhc2FuIGRhcmkgdmlzdWFsaXNhc2kgOg0KMS4gUGVuZ2VsdWFyYW4gcGVtYXNhcmFuIG1lbmRvcm9uZyBrZW5haWthbiBwZW5kYXBhdGFuLg0KMi4gUGVuZ2FsYW1hbiBtYW5hZ2VyIGJlcmh1YnVuZ2FuIGRlbmdhbiBrZXB1YXNhbiBwZWxhbmdnYW4uDQozLiBQZXJiZWRhYW4gcGVuZGFwYXRhbiBtdW5jdWwgYmVyZGFzYXJrYW4ga290YSBkYW4gamVuaXMgYmlzbmlzLg==