Visualisasi Data

Assignment Week-4


Foto Kelompok 3

1 Pendahuluan

1.0.1 Tujuan

Tujuan dari visualisasi data ini adalah untuk menganalisis hubungan antara variabel-variabel akademik seperti nilai UAS, IPK, waktu belajar, dan kehadiran. Melalui visualisasi, dapat diketahui pola atau tren kinerja mahasiswa, membandingkan prestasi antar fakultas, serta mengidentifikasi faktor yang paling berpengaruh terhadap hasil belajar.

1.0.2 Dataset

library(knitr)

#membuat tabel deskripsi variabel

data_description <- data.frame(
  Column = c(
    "ID_Mahasiswa",
    "Fakultas",
    "Nilai_UAS",
    "Waktu_belajar",
    "Kehadiran",
    "IPK",
    "Gender",
    "Semester",
    "Kategori_IPK"
  ),
  Data_Type = c(
    "Categorical",
    "Categorical",
    "Numerical",
    "Numerical",
    "Numerical",
    "Numerical",
    "Categorical",
    "Numerical",
    "Categorical"
  ),
  Subtype = c(
    "Nominal",
    "Nominal",
    "Continuous",
    "Continuous",
    "Continuous",
    "Continuous",
    "Nominal",
    "Discrete",
    "Ordinal"
  ),
  Description = c(
    "Kode unik untuk setiap mahasiswa",
    "Fakultas tempat mahasiswa terdaftar (Teknik, Hukum, Kedokteran)",
    "Nilai ujian akhir semester yang diperoleh mahasiswa",
    "Jumlah jam belajar mandiri mahasiswa per minggu",
    "Persentase kehadiran mahasiswa selama perkuliahan",
    "Indeks Prestasi Kumulatif mahasiswa",
    "Jenis kelamin mahasiswa (L = Laki-laki, P = Perempuan)",
    "Semester yang sedang ditempuh oleh mahasiswa",
    "Kategori IPK adalah pengelompokan nilai IPK (Indeks Prestasi Kumulatif)"
  )
)

# Menampilkan tabel seperti di laporan akademik
kable(
  data_description,
  caption = "Table 1. Data Description Table for the Mahasiswa Dataset",
  align = "lccc"
)
Table 1. Data Description Table for the Mahasiswa Dataset
Column Data_Type Subtype Description
ID_Mahasiswa Categorical Nominal Kode unik untuk setiap mahasiswa
Fakultas Categorical Nominal Fakultas tempat mahasiswa terdaftar (Teknik, Hukum, Kedokteran)
Nilai_UAS Numerical Continuous Nilai ujian akhir semester yang diperoleh mahasiswa
Waktu_belajar Numerical Continuous Jumlah jam belajar mandiri mahasiswa per minggu
Kehadiran Numerical Continuous Persentase kehadiran mahasiswa selama perkuliahan
IPK Numerical Continuous Indeks Prestasi Kumulatif mahasiswa
Gender Categorical Nominal Jenis kelamin mahasiswa (L = Laki-laki, P = Perempuan)
Semester Numerical Discrete Semester yang sedang ditempuh oleh mahasiswa
Kategori_IPK Categorical Ordinal Kategori IPK adalah pengelompokan nilai IPK (Indeks Prestasi Kumulatif)

1.0.3 Konteks Kasus

Dalam kasus ini, pihak universitas ingin melakukan evaluasi terhadap kinerja mahasiswa dari beberapa fakultas, yaitu Teknik, Hukum, dan Kedokteran. Analisis dilakukan untuk melihat apakah tingkat kehadiran dan waktu belajar berhubungan dengan nilai UAS dan IPK mahasiswa. Hasil visualisasi diharapkan dapat membantu pihak akademik dalam menentukan strategi pembelajaran yang lebih efektif serta memberikan dukungan yang tepat bagi mahasiswa yang mengalami penurunan kinerja

2 Persiapan Data

data_mahasiswa <- data.frame(
  ID_Mahasiswa = c("M001", "M002", "M003", "M004", "M005", 
                   "M006", "M007", "M008", "M009", "M010", 
                   "M011", "M012"),
  Fakultas = c("Teknik", "Teknik", "Kedokteran", "Hukum", "Kedokteran", 
               "Hukum", "Teknik", "Hukum", "Kedokteran", "Hukum",
               "Teknik", "Kedokteran"),
  Nilai_UAS = c(85, 78, 92, 70, 88, 64, 94, 73, 81, 77, 90, 86),
  Waktu_belajar = c(10, 8, 15, 6, 12, 4, 16, 7, 10, 9, 13, 11),
  Kehadiran = c(95, 88, 98, 82, 97, 75, 99, 85, 91, 89, 96, 93),
  IPK = c(3.7, 3.4, 3.9, 2.9, 3.8, 2.6, 4.0, 3.3, 3.5, 3.2, 3.8, 3.6),
  Gender = c("L", "P", "L", "P", "L", "P", "L", "L", "L", "P", "P", "L"),
  Semester = c(5, 4, 3, 3, 5, 6, 6, 5, 4, 4, 3, 6)
)

# kolom kategori IPK
data_mahasiswa$Kategori_IPK <- cut(
  data_mahasiswa$IPK,
  breaks = c(0, 3.0, 3.5, 4.0), 
  labels = c("Cukup", "Baik", "Sangat Baik"),
  include.lowest = TRUE
)

# Cek hasil
print(data_mahasiswa)
##    ID_Mahasiswa   Fakultas Nilai_UAS Waktu_belajar Kehadiran IPK Gender
## 1          M001     Teknik        85            10        95 3.7      L
## 2          M002     Teknik        78             8        88 3.4      P
## 3          M003 Kedokteran        92            15        98 3.9      L
## 4          M004      Hukum        70             6        82 2.9      P
## 5          M005 Kedokteran        88            12        97 3.8      L
## 6          M006      Hukum        64             4        75 2.6      P
## 7          M007     Teknik        94            16        99 4.0      L
## 8          M008      Hukum        73             7        85 3.3      L
## 9          M009 Kedokteran        81            10        91 3.5      L
## 10         M010      Hukum        77             9        89 3.2      P
## 11         M011     Teknik        90            13        96 3.8      P
## 12         M012 Kedokteran        86            11        93 3.6      L
##    Semester Kategori_IPK
## 1         5  Sangat Baik
## 2         4         Baik
## 3         3  Sangat Baik
## 4         3        Cukup
## 5         5  Sangat Baik
## 6         6        Cukup
## 7         6  Sangat Baik
## 8         5         Baik
## 9         4         Baik
## 10        4         Baik
## 11        3  Sangat Baik
## 12        6  Sangat Baik

3 Visualisasi data

3.0.1 Bar Chart: Perbandingan Jumlah Mahasiswa per Kategori IPK di Tiap Fakultas

Definisi:

Bar chart digunakan untuk menampilkan dan membandingkan data kategori (kategorikal) dalam bentuk batang tegak atau mendatar. Setiap batang mewakili satu kategori (misalnya Fakultas, Jenis Kelamin, atau Mata Kuliah), dan panjang batang menggambarkan jumlah, rata-rata, atau nilai tertentu dari kategori tersebut.

Aturan Penggunaan:

  • Gunakan jika data bersifat kategorik atau diskrit.

  • Sumbu X (horizontal) → kategori.

  • Sumbu Y (vertikal) → nilai (jumlah, frekuensi, rata-rata, dll).

  • Hindari terlalu banyak kategori karena grafik bisa jadi sulit dibaca.

kelebihan:

  • Sangat mudah dipahami oleh semua orang.

  • Cocok untuk membandingkan nilai antar kategori.

  • Dapat digunakan dengan berbagai variasi (stacked bar, grouped bar, horizontal bar).

kekurangan:

  • Tidak cocok untuk data kontinu (angka yang bersambung).

  • Sulit dibaca jika jumlah kategori terlalu banyak atau label panjang.

library(ggplot2)

ggplot(data_mahasiswa, aes(x = Fakultas, fill = Kategori_IPK)) +
  geom_bar(position = "dodge") +
  labs(title = "Jumlah Mahasiswa per Kategori IPK di Setiap Fakultas",
       x = "Fakultas", y = "Jumlah Mahasiswa") +
  theme_minimal()

# Tujuan: Mengetahui perbandingan jumlah mahasiswa berdasarkan kategori IPK di setiap fakultas

3.0.2 Histogram: Distribusi Nilai UAS

Definisi:

Histogram digunakan untuk menunjukkan distribusi frekuensi dari data numerik (misalnya nilai ujian, IPK, tinggi badan, dll). Berbeda dari bar chart, histogram tidak menampilkan kategori melainkan interval nilai (bin). Tiap batang mewakili jumlah data yang berada dalam rentang nilai tertentu.

Aturan Penggunaan:

  • Gunakan untuk data numerik kontinu.

  • Sumbu X → interval nilai.

  • Sumbu Y → frekuensi data dalam interval itu.

  • Jumlah bin (interval) dapat diatur untuk hasil yang lebih detail atau ringkas.

kelebihan:

  • Menunjukkan bentuk distribusi data (normal, miring, dll).

  • Dapat membantu menemukan outlier atau sebaran nilai yang tidak merata.

Kekurangan:

  • Hasil bisa berubah tergantung pengaturan jumlah bin.

  • Tidak cocok untuk data kategorik.

  • Tidak menunjukkan nilai individual.

ggplot(data_mahasiswa, aes(x = Nilai_UAS)) +
  geom_histogram(binwidth = 5, fill = "skyblue", color = "black") +
  labs(title = "Distribusi Nilai UAS", x = "Nilai UAS", y = "Frekuensi") +
  theme_minimal()

# Tujuan: Melihat distribusi data numerik (nilai UAS)

3.0.3 Boxplot: Distribusi Kehadiran per Fakultas

Definisi:

Boxplot (box-and-whisker plot) menampilkan sebaran data numerik melalui lima ukuran statistik utama: nilai minimum, kuartil pertama (Q1), median, kuartil ketiga (Q3), dan maksimum, serta menandai outlier (data ekstrem).

Aturan Penggunaan:

  • Gunakan untuk data numerik.

  • Cocok untuk membandingkan sebaran data antar kelompok (misalnya IPK per fakultas).

  • Median menunjukkan nilai tengah, panjang kotak menunjukkan tingkat variasi data.

Kelebihan:

  • Memberikan ringkasan sebaran data secara cepat.

  • Dapat mendeteksi outlier dengan mudah.

  • Ideal untuk membandingkan beberapa kelompok data sekaligus.

Kekurangan:

  • Tidak menunjukkan detail distribusi (seperti bentuk kurva).

  • Sulit dipahami oleh orang awam.

ggplot(data_mahasiswa, aes(x = Fakultas, y = Kehadiran, fill = Fakultas)) +
  geom_boxplot() +
  labs(title = "Distribusi Kehadiran per Fakultas", y = "Kehadiran (%)") +
  theme_minimal()

# Tujuan: Mengetahui penyebaran data dan mendeteksi outlier

3.0.4 Pie Chart: Proporsi Mahasiswa Berdasarkan Kategori IPK

Definisi:

Pie chart menggambarkan proporsi atau persentase dari setiap kategori terhadap total keseluruhan dalam bentuk irisan lingkaran. Setiap potongan (slice) menunjukkan seberapa besar kontribusi suatu kategori dibanding total.

Aturan Penggunaan:

  • Gunakan untuk data kategorik dengan total = 100%.

  • Gunakan maksimal 5–6 kategori agar grafik tetap jelas.

  • Gunakan label persentase agar mudah dibaca.

Kelebihan:

  • Menarik secara visual dan mudah dipahami.

  • Cocok untuk menunjukkan perbandingan bagian terhadap keseluruhan.

Kekurangan:

  • Tidak akurat untuk banyak kategori.

  • Sulit membandingkan ukuran antar irisan secara tepat.

  • Tidak menunjukkan nilai absolut.

pie_ipk <- as.data.frame(table(data_mahasiswa$Kategori_IPK))
colnames(pie_ipk) <- c("Kategori_IPK", "Jumlah")

ggplot(pie_ipk, aes(x = "", y = Jumlah, fill = Kategori_IPK)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y") +
  labs(title = "Proporsi Mahasiswa Berdasarkan Kategori IPK") +
  theme_void()

# Tujuan: Mengetahui proporsi keseluruhan mahasiswa berdasarkan kategori IPK

3.0.5 Scatter Plot: Hubungan antara Waktu Belajar dan Nilai UAS berdasarkan Kategori IPK

Definisi:

Scatter plot menampilkan hubungan antara dua variabel numerik dalam bentuk titik-titik pada bidang koordinat. Setiap titik mewakili satu data (misalnya satu mahasiswa), dengan posisi X dan Y mewakili dua nilai variabel.

Aturan Penggunaan:

  • Gunakan untuk menunjukkan korelasi atau hubungan antara dua variabel numerik (misal: Waktu Belajar vs Nilai UAS).

  • Bisa ditambah warna/shape untuk membedakan kelompok (misalnya fakultas).

Kelebihan:

  • Menunjukkan hubungan atau pola (positif, negatif, acak).

  • Bisa mendeteksi outlier.

  • Cocok untuk analisis korelasi.

Kekurangan:

  • Tidak cocok untuk data kategorik.

  • Jika data terlalu banyak, titik bisa saling menumpuk.

ggplot(data_mahasiswa, aes(x = Waktu_belajar, y = Nilai_UAS, color = Kategori_IPK)) +
  geom_point(size = 3) +
  geom_smooth(method = "lm", se = FALSE, linetype = "dashed") +
  labs(title = "Hubungan Waktu Belajar dan Nilai UAS berdasarkan Kategori IPK") +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

# Tujuan: Melihat hubungan antara waktu belajar dan nilai UAS, serta apakah kategori IPK memengaruhi hubungan itu

3.0.6 Line Plot: Tren nilai UAS mahasiswa berdasarkan kategori IPK

Definisi:

Line plot digunakan untuk menunjukkan perubahan data secara berurutan, biasanya berdasarkan waktu atau urutan tertentu (misalnya tren nilai per semester). Setiap titik data dihubungkan dengan garis, sehingga kita bisa melihat pola tren naik atau turun.

Aturan Penggunaan:

  • Gunakan untuk data berurutan atau time series.

  • Sumbu X → waktu atau urutan.

  • Sumbu Y → nilai yang diukur.

  • Gunakan warna berbeda jika membandingkan beberapa seri.

Kelebihan:

  • Sangat bagus untuk menampilkan tren dan perubahan dari waktu ke waktu.

  • Mudah dibaca dan dimengerti.

  • Dapat menampilkan beberapa seri data sekaligus.

Kekurangan:

  • Tidak cocok untuk data yang tidak berurutan.

  • Bisa membingungkan jika terlalu banyak garis.

ggplot(data_mahasiswa, aes(x = ID_Mahasiswa, y = Nilai_UAS, group = 1, color = Kategori_IPK)) +
  geom_line() +
  geom_point(size = 3) +
  labs(title = "Nilai UAS per Mahasiswa berdasarkan Kategori IPK") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Tujuan: Menampilkan urutan nilai UAS setiap mahasiswa serta perbandingannya antar kategori IPK.

3.0.7 Density Plot: Estimasi distribusi IPK

Definisi:

Density plot adalah grafik yang menunjukkan bentuk distribusi data numerik secara halus (smooth). Mirip histogram, tapi menggantikan batang dengan kurva halus yang memperkirakan kepadatan data. Kurva yang tinggi menunjukkan banyak data di area tersebut.

Aturan Penggunaan:

  • Gunakan untuk data numerik kontinu.

  • Cocok untuk membandingkan beberapa kelompok (misalnya distribusi IPK per fakultas).

  • Biasanya dibuat dengan fungsi geom_density() di R.

Kelebihan:

  • Menunjukkan bentuk distribusi dengan lebih lembut.

  • Cocok untuk perbandingan antar kelompok.

  • Terlihat lebih estetis daripada histogram.

Kekurangan:

  • Kurang akurat untuk dataset kecil.

  • Tidak menunjukkan jumlah data secara langsung.

ggplot(data_mahasiswa, aes(x = IPK, fill = Fakultas)) +
  geom_density(alpha = 0.5) +
  labs(title = "Density Plot IPK per Fakultas", x = "IPK", y = "Density") +
  theme_minimal()

# Tujuan: Mengestimasi distribusi probabilitas variabel numerik

3.0.8 Ridgeline Plot: Distribusi Nilai UAS per Fakultas

Definisi:

Ridgeline plot (atau joyplot) adalah kumpulan dari beberapa density plot yang ditumpuk secara vertikal, digunakan untuk membandingkan distribusi data antar kategori. Setiap “gelombang” (ridge) mewakili satu kelompok, dan bentuknya menunjukkan pola sebaran nilai dalam kelompok tersebut.

Aturan Penggunaan:

  • Gunakan untuk membandingkan distribusi data numerik antar kategori (misalnya Nilai UAS per Fakultas).

  • Biasanya dibuat dengan paket ggridges di R.

Kelebihan:

  • Visualnya menarik dan informatif.

  • Mudah melihat perbedaan pola distribusi antar kategori.

  • Cocok untuk dataset dengan banyak kelompok.

Kekurangan:

  • Bisa sulit dibaca kalau kategori terlalu banyak.

  • Tidak menunjukkan nilai numerik yang spesifik.

library(ggridges)

ggplot(data_mahasiswa, aes(x = Nilai_UAS, y = Fakultas, fill = Fakultas)) +
  geom_density_ridges(alpha = 0.7) +
  labs(title = "Ridgeline Plot Nilai UAS per Fakultas", x = "Nilai UAS", y = "Fakultas") +
  theme_ridges() +
  theme(legend.position = "none")
## Picking joint bandwidth of 2.97

# Tujuan: Membandingkan distribusi beberapa kelompok sekaligus

4 Kesimpulan

Berdasarkan visualisasi:

  • Mahasiswa secara umum berprestasi baik, dengan mayoritas berada pada kategori IPK tinggi.

  • Nilai UAS mahasiswa berbeda antar fakultas, beberapa fakultas memiliki nilai rata-rata lebih tinggi.

  • Sebaran nilai umumnya normal, tapi ada beberapa outlier.

  • Mahasiswa dengan waktu belajar lebih tinggi cenderung memperoleh nilai UAS lebih baik.

  • Ridgeline dan Boxplot membantu membandingkan distribusi dan proporsi antar fakultas.

  • Visualisasi ini mempermudah pemahaman pola akademik mahasiswa dan hubungan antar variabel dengan cepat.

LS0tDQp0aXRsZTogIlZpc3VhbGlzYXNpIERhdGEiDQpzdWJ0aXRsZTogIkFzc2lnbm1lbnQgV2Vlay00Ig0KYXV0aG9yOg0KLSAiS2Vsb21wb2sgMyIgDQotICJOYWlmYWggRWRyaWEgQXJ0YSAoNTIyNTAwNTYpIg0KLSAiRnJpenp5IExpdGhtZW5zeWFoICg1MjI1MDA2MikiDQotICJMdWx1IE5hamxhIFNhbHNhYmlsYSAoNTIyNTAwNjkpIg0KLSAiTmFpbGEgU3lhaHJhbmkgUHV0cmkgKDUyMjUwMDcwKSINCi0gIk5pLiBNZCBBdXJvcmEgU2VrYXJuaW5ncnVtICg1MjI1MDA3MikiDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy5EYXRlKCksICclQiAlZCwgJVknKWAiDQpvdXRwdXQ6DQogIHJtZGZvcm1hdHM6OnJlYWR0aGVkb3duOg0KICAgIHNlbGZfY29udGFpbmVkOiB0cnVlDQogICAgdGh1bWJuYWlsczogdHJ1ZQ0KICAgIGxpZ2h0Ym94OiB0cnVlDQogICAgZ2FsbGVyeTogdHJ1ZQ0KICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQ0KICAgIGxpYl9kaXI6IGxpYnMNCiAgICBkZl9wcmludDogInBhZ2VkIg0KICAgIGNvZGVfZm9sZGluZzogInNob3ciDQogICAgY29kZV9kb3dubG9hZDogeWVzDQotLS0NCg0KPGNlbnRlcj4NCjxpbWcgc3JjPSJDOi9Vc2Vycy9hY2VyL0RvY3VtZW50cy9XaGF0c0FwcCBJbWFnZSAyMDI1LTEwLTE2IGF0IDE4LjQyLjA2X2Y1NGNiNzliLmpwZyIgd2lkdGg9IjMwMCI+PGJyPg0KPGI+Rm90byBLZWxvbXBvayAzPC9iPg0KPC9jZW50ZXI+DQoNCg0KLS0tDQoNCiMgUGVuZGFodWx1YW4NCg0KIyMjIFR1anVhbg0KDQpUdWp1YW4gZGFyaSB2aXN1YWxpc2FzaSBkYXRhIGluaSBhZGFsYWggdW50dWsgbWVuZ2FuYWxpc2lzIGh1YnVuZ2FuIGFudGFyYSB2YXJpYWJlbC12YXJpYWJlbCBha2FkZW1payBzZXBlcnRpIG5pbGFpIFVBUywgSVBLLCB3YWt0dSBiZWxhamFyLCBkYW4ga2VoYWRpcmFuLiBNZWxhbHVpIHZpc3VhbGlzYXNpLCBkYXBhdCBkaWtldGFodWkgcG9sYSBhdGF1IHRyZW4ga2luZXJqYSBtYWhhc2lzd2EsIG1lbWJhbmRpbmdrYW4gcHJlc3Rhc2kgYW50YXIgZmFrdWx0YXMsIHNlcnRhIG1lbmdpZGVudGlmaWthc2kgZmFrdG9yIHlhbmcgcGFsaW5nIGJlcnBlbmdhcnVoIHRlcmhhZGFwIGhhc2lsIGJlbGFqYXIuDQoNCiMjIyBEYXRhc2V0DQpgYGB7cn0NCg0KbGlicmFyeShrbml0cikNCg0KI21lbWJ1YXQgdGFiZWwgZGVza3JpcHNpIHZhcmlhYmVsDQoNCmRhdGFfZGVzY3JpcHRpb24gPC0gZGF0YS5mcmFtZSgNCiAgQ29sdW1uID0gYygNCiAgICAiSURfTWFoYXNpc3dhIiwNCiAgICAiRmFrdWx0YXMiLA0KICAgICJOaWxhaV9VQVMiLA0KICAgICJXYWt0dV9iZWxhamFyIiwNCiAgICAiS2VoYWRpcmFuIiwNCiAgICAiSVBLIiwNCiAgICAiR2VuZGVyIiwNCiAgICAiU2VtZXN0ZXIiLA0KICAgICJLYXRlZ29yaV9JUEsiDQogICksDQogIERhdGFfVHlwZSA9IGMoDQogICAgIkNhdGVnb3JpY2FsIiwNCiAgICAiQ2F0ZWdvcmljYWwiLA0KICAgICJOdW1lcmljYWwiLA0KICAgICJOdW1lcmljYWwiLA0KICAgICJOdW1lcmljYWwiLA0KICAgICJOdW1lcmljYWwiLA0KICAgICJDYXRlZ29yaWNhbCIsDQogICAgIk51bWVyaWNhbCIsDQogICAgIkNhdGVnb3JpY2FsIg0KICApLA0KICBTdWJ0eXBlID0gYygNCiAgICAiTm9taW5hbCIsDQogICAgIk5vbWluYWwiLA0KICAgICJDb250aW51b3VzIiwNCiAgICAiQ29udGludW91cyIsDQogICAgIkNvbnRpbnVvdXMiLA0KICAgICJDb250aW51b3VzIiwNCiAgICAiTm9taW5hbCIsDQogICAgIkRpc2NyZXRlIiwNCiAgICAiT3JkaW5hbCINCiAgKSwNCiAgRGVzY3JpcHRpb24gPSBjKA0KICAgICJLb2RlIHVuaWsgdW50dWsgc2V0aWFwIG1haGFzaXN3YSIsDQogICAgIkZha3VsdGFzIHRlbXBhdCBtYWhhc2lzd2EgdGVyZGFmdGFyIChUZWtuaWssIEh1a3VtLCBLZWRva3RlcmFuKSIsDQogICAgIk5pbGFpIHVqaWFuIGFraGlyIHNlbWVzdGVyIHlhbmcgZGlwZXJvbGVoIG1haGFzaXN3YSIsDQogICAgIkp1bWxhaCBqYW0gYmVsYWphciBtYW5kaXJpIG1haGFzaXN3YSBwZXIgbWluZ2d1IiwNCiAgICAiUGVyc2VudGFzZSBrZWhhZGlyYW4gbWFoYXNpc3dhIHNlbGFtYSBwZXJrdWxpYWhhbiIsDQogICAgIkluZGVrcyBQcmVzdGFzaSBLdW11bGF0aWYgbWFoYXNpc3dhIiwNCiAgICAiSmVuaXMga2VsYW1pbiBtYWhhc2lzd2EgKEwgPSBMYWtpLWxha2ksIFAgPSBQZXJlbXB1YW4pIiwNCiAgICAiU2VtZXN0ZXIgeWFuZyBzZWRhbmcgZGl0ZW1wdWggb2xlaCBtYWhhc2lzd2EiLA0KICAgICJLYXRlZ29yaSBJUEsgYWRhbGFoIHBlbmdlbG9tcG9rYW4gbmlsYWkgSVBLIChJbmRla3MgUHJlc3Rhc2kgS3VtdWxhdGlmKSINCiAgKQ0KKQ0KDQojIE1lbmFtcGlsa2FuIHRhYmVsIHNlcGVydGkgZGkgbGFwb3JhbiBha2FkZW1paw0Ka2FibGUoDQogIGRhdGFfZGVzY3JpcHRpb24sDQogIGNhcHRpb24gPSAiVGFibGUgMS4gRGF0YSBEZXNjcmlwdGlvbiBUYWJsZSBmb3IgdGhlIE1haGFzaXN3YSBEYXRhc2V0IiwNCiAgYWxpZ24gPSAibGNjYyINCikNCmBgYA0KDQojIyMgS29udGVrcyBLYXN1cw0KDQpEYWxhbSBrYXN1cyBpbmksIHBpaGFrIHVuaXZlcnNpdGFzIGluZ2luIG1lbGFrdWthbiBldmFsdWFzaSB0ZXJoYWRhcCBraW5lcmphIG1haGFzaXN3YSBkYXJpIGJlYmVyYXBhIGZha3VsdGFzLCB5YWl0dSBUZWtuaWssIEh1a3VtLCBkYW4gS2Vkb2t0ZXJhbi4gQW5hbGlzaXMgZGlsYWt1a2FuIHVudHVrIG1lbGloYXQgYXBha2FoIHRpbmdrYXQga2VoYWRpcmFuIGRhbiB3YWt0dSBiZWxhamFyIGJlcmh1YnVuZ2FuIGRlbmdhbiBuaWxhaSBVQVMgZGFuIElQSyBtYWhhc2lzd2EuIEhhc2lsIHZpc3VhbGlzYXNpIGRpaGFyYXBrYW4gZGFwYXQgbWVtYmFudHUgcGloYWsgYWthZGVtaWsgZGFsYW0gbWVuZW50dWthbiBzdHJhdGVnaSBwZW1iZWxhamFyYW4geWFuZyBsZWJpaCBlZmVrdGlmIHNlcnRhIG1lbWJlcmlrYW4gZHVrdW5nYW4geWFuZyB0ZXBhdCBiYWdpIG1haGFzaXN3YSB5YW5nIG1lbmdhbGFtaSBwZW51cnVuYW4ga2luZXJqYQ0KDQoNCiMgUGVyc2lhcGFuIERhdGENCg0KYGBge3J9DQpkYXRhX21haGFzaXN3YSA8LSBkYXRhLmZyYW1lKA0KICBJRF9NYWhhc2lzd2EgPSBjKCJNMDAxIiwgIk0wMDIiLCAiTTAwMyIsICJNMDA0IiwgIk0wMDUiLCANCiAgICAgICAgICAgICAgICAgICAiTTAwNiIsICJNMDA3IiwgIk0wMDgiLCAiTTAwOSIsICJNMDEwIiwgDQogICAgICAgICAgICAgICAgICAgIk0wMTEiLCAiTTAxMiIpLA0KICBGYWt1bHRhcyA9IGMoIlRla25payIsICJUZWtuaWsiLCAiS2Vkb2t0ZXJhbiIsICJIdWt1bSIsICJLZWRva3RlcmFuIiwgDQogICAgICAgICAgICAgICAiSHVrdW0iLCAiVGVrbmlrIiwgIkh1a3VtIiwgIktlZG9rdGVyYW4iLCAiSHVrdW0iLA0KICAgICAgICAgICAgICAgIlRla25payIsICJLZWRva3RlcmFuIiksDQogIE5pbGFpX1VBUyA9IGMoODUsIDc4LCA5MiwgNzAsIDg4LCA2NCwgOTQsIDczLCA4MSwgNzcsIDkwLCA4NiksDQogIFdha3R1X2JlbGFqYXIgPSBjKDEwLCA4LCAxNSwgNiwgMTIsIDQsIDE2LCA3LCAxMCwgOSwgMTMsIDExKSwNCiAgS2VoYWRpcmFuID0gYyg5NSwgODgsIDk4LCA4MiwgOTcsIDc1LCA5OSwgODUsIDkxLCA4OSwgOTYsIDkzKSwNCiAgSVBLID0gYygzLjcsIDMuNCwgMy45LCAyLjksIDMuOCwgMi42LCA0LjAsIDMuMywgMy41LCAzLjIsIDMuOCwgMy42KSwNCiAgR2VuZGVyID0gYygiTCIsICJQIiwgIkwiLCAiUCIsICJMIiwgIlAiLCAiTCIsICJMIiwgIkwiLCAiUCIsICJQIiwgIkwiKSwNCiAgU2VtZXN0ZXIgPSBjKDUsIDQsIDMsIDMsIDUsIDYsIDYsIDUsIDQsIDQsIDMsIDYpDQopDQoNCiMga29sb20ga2F0ZWdvcmkgSVBLDQpkYXRhX21haGFzaXN3YSRLYXRlZ29yaV9JUEsgPC0gY3V0KA0KICBkYXRhX21haGFzaXN3YSRJUEssDQogIGJyZWFrcyA9IGMoMCwgMy4wLCAzLjUsIDQuMCksIA0KICBsYWJlbHMgPSBjKCJDdWt1cCIsICJCYWlrIiwgIlNhbmdhdCBCYWlrIiksDQogIGluY2x1ZGUubG93ZXN0ID0gVFJVRQ0KKQ0KDQojIENlayBoYXNpbA0KcHJpbnQoZGF0YV9tYWhhc2lzd2EpDQpgYGANCg0KIyBWaXN1YWxpc2FzaSBkYXRhDQoNCiMjIyBCYXIgQ2hhcnQ6IFBlcmJhbmRpbmdhbiBKdW1sYWggTWFoYXNpc3dhIHBlciBLYXRlZ29yaSBJUEsgZGkgVGlhcCBGYWt1bHRhcw0KDQoqKipEZWZpbmlzaToqKioNCg0KQmFyIGNoYXJ0IGRpZ3VuYWthbiB1bnR1ayBtZW5hbXBpbGthbiBkYW4gbWVtYmFuZGluZ2thbiBkYXRhIGthdGVnb3JpIChrYXRlZ29yaWthbCkgZGFsYW0gYmVudHVrIGJhdGFuZyB0ZWdhayBhdGF1IG1lbmRhdGFyLg0KU2V0aWFwIGJhdGFuZyBtZXdha2lsaSBzYXR1IGthdGVnb3JpIChtaXNhbG55YSBGYWt1bHRhcywgSmVuaXMgS2VsYW1pbiwgYXRhdSBNYXRhIEt1bGlhaCksIGRhbiBwYW5qYW5nIGJhdGFuZyBtZW5nZ2FtYmFya2FuIGp1bWxhaCwgcmF0YS1yYXRhLCBhdGF1IG5pbGFpIHRlcnRlbnR1IGRhcmkga2F0ZWdvcmkgdGVyc2VidXQuDQoNCioqKkF0dXJhbiBQZW5nZ3VuYWFuOioqKg0KDQotIEd1bmFrYW4gamlrYSBkYXRhIGJlcnNpZmF0IGthdGVnb3JpayBhdGF1IGRpc2tyaXQuDQoNCi0gU3VtYnUgWCAoaG9yaXpvbnRhbCkg4oaSIGthdGVnb3JpLg0KDQotIFN1bWJ1IFkgKHZlcnRpa2FsKSDihpIgbmlsYWkgKGp1bWxhaCwgZnJla3VlbnNpLCByYXRhLXJhdGEsIGRsbCkuDQoNCi0gSGluZGFyaSB0ZXJsYWx1IGJhbnlhayBrYXRlZ29yaSBrYXJlbmEgZ3JhZmlrIGJpc2EgamFkaSBzdWxpdCBkaWJhY2EuDQoNCioqKmtlbGViaWhhbjoqKioNCg0KLSBTYW5nYXQgbXVkYWggZGlwYWhhbWkgb2xlaCBzZW11YSBvcmFuZy4NCg0KLSBDb2NvayB1bnR1ayBtZW1iYW5kaW5na2FuIG5pbGFpIGFudGFyIGthdGVnb3JpLg0KDQotIERhcGF0IGRpZ3VuYWthbiBkZW5nYW4gYmVyYmFnYWkgdmFyaWFzaSAoc3RhY2tlZCBiYXIsIGdyb3VwZWQgYmFyLCBob3Jpem9udGFsIGJhcikuDQoNCioqKmtla3VyYW5nYW46KioqDQoNCi0gVGlkYWsgY29jb2sgdW50dWsgZGF0YSBrb250aW51IChhbmdrYSB5YW5nIGJlcnNhbWJ1bmcpLg0KDQotIFN1bGl0IGRpYmFjYSBqaWthIGp1bWxhaCBrYXRlZ29yaSB0ZXJsYWx1IGJhbnlhayBhdGF1IGxhYmVsIHBhbmphbmcuDQoNCg0KYGBge3J9DQpsaWJyYXJ5KGdncGxvdDIpDQoNCmdncGxvdChkYXRhX21haGFzaXN3YSwgYWVzKHggPSBGYWt1bHRhcywgZmlsbCA9IEthdGVnb3JpX0lQSykpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGxhYnModGl0bGUgPSAiSnVtbGFoIE1haGFzaXN3YSBwZXIgS2F0ZWdvcmkgSVBLIGRpIFNldGlhcCBGYWt1bHRhcyIsDQogICAgICAgeCA9ICJGYWt1bHRhcyIsIHkgPSAiSnVtbGFoIE1haGFzaXN3YSIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCiMgVHVqdWFuOiBNZW5nZXRhaHVpIHBlcmJhbmRpbmdhbiBqdW1sYWggbWFoYXNpc3dhIGJlcmRhc2Fya2FuIGthdGVnb3JpIElQSyBkaSBzZXRpYXAgZmFrdWx0YXMNCg0KYGBgDQoNCg0KIyMjIEhpc3RvZ3JhbTogRGlzdHJpYnVzaSBOaWxhaSBVQVMNCg0KKioqRGVmaW5pc2k6KioqDQoNCkhpc3RvZ3JhbSBkaWd1bmFrYW4gdW50dWsgbWVudW5qdWtrYW4gZGlzdHJpYnVzaSBmcmVrdWVuc2kgZGFyaSBkYXRhIG51bWVyaWsgKG1pc2FsbnlhIG5pbGFpIHVqaWFuLCBJUEssIHRpbmdnaSBiYWRhbiwgZGxsKS4NCkJlcmJlZGEgZGFyaSBiYXIgY2hhcnQsIGhpc3RvZ3JhbSB0aWRhayBtZW5hbXBpbGthbiBrYXRlZ29yaSBtZWxhaW5rYW4gaW50ZXJ2YWwgbmlsYWkgKGJpbikuIFRpYXAgYmF0YW5nIG1ld2FraWxpIGp1bWxhaCBkYXRhIHlhbmcgYmVyYWRhIGRhbGFtIHJlbnRhbmcgbmlsYWkgdGVydGVudHUuDQoNCioqKkF0dXJhbiBQZW5nZ3VuYWFuOioqKg0KDQotIEd1bmFrYW4gdW50dWsgZGF0YSBudW1lcmlrIGtvbnRpbnUuDQoNCi0gU3VtYnUgWCDihpIgaW50ZXJ2YWwgbmlsYWkuDQoNCi0gU3VtYnUgWSDihpIgZnJla3VlbnNpIGRhdGEgZGFsYW0gaW50ZXJ2YWwgaXR1Lg0KDQotIEp1bWxhaCBiaW4gKGludGVydmFsKSBkYXBhdCBkaWF0dXIgdW50dWsgaGFzaWwgeWFuZyBsZWJpaCBkZXRhaWwgYXRhdSByaW5na2FzLg0KDQoqKiprZWxlYmloYW46KioqDQoNCi0gTWVudW5qdWtrYW4gYmVudHVrIGRpc3RyaWJ1c2kgZGF0YSAobm9ybWFsLCBtaXJpbmcsIGRsbCkuDQoNCi0gRGFwYXQgbWVtYmFudHUgbWVuZW11a2FuIG91dGxpZXIgYXRhdSBzZWJhcmFuIG5pbGFpIHlhbmcgdGlkYWsgbWVyYXRhLg0KDQoqKipLZWt1cmFuZ2FuOioqKg0KDQotIEhhc2lsIGJpc2EgYmVydWJhaCB0ZXJnYW50dW5nIHBlbmdhdHVyYW4ganVtbGFoIGJpbi4NCg0KLSBUaWRhayBjb2NvayB1bnR1ayBkYXRhIGthdGVnb3Jpay4NCg0KLSBUaWRhayBtZW51bmp1a2thbiBuaWxhaSBpbmRpdmlkdWFsLg0KDQpgYGB7cn0NCmdncGxvdChkYXRhX21haGFzaXN3YSwgYWVzKHggPSBOaWxhaV9VQVMpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gNSwgZmlsbCA9ICJza3libHVlIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGxhYnModGl0bGUgPSAiRGlzdHJpYnVzaSBOaWxhaSBVQVMiLCB4ID0gIk5pbGFpIFVBUyIsIHkgPSAiRnJla3VlbnNpIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KIyBUdWp1YW46IE1lbGloYXQgZGlzdHJpYnVzaSBkYXRhIG51bWVyaWsgKG5pbGFpIFVBUykNCmBgYA0KDQoNCiMjIyBCb3hwbG90OiBEaXN0cmlidXNpIEtlaGFkaXJhbiBwZXIgRmFrdWx0YXMNCg0KKioqRGVmaW5pc2k6KioqDQoNCkJveHBsb3QgKGJveC1hbmQtd2hpc2tlciBwbG90KSBtZW5hbXBpbGthbiBzZWJhcmFuIGRhdGEgbnVtZXJpayBtZWxhbHVpIGxpbWEgdWt1cmFuIHN0YXRpc3RpayB1dGFtYToNCm5pbGFpIG1pbmltdW0sIGt1YXJ0aWwgcGVydGFtYSAoUTEpLCBtZWRpYW4sIGt1YXJ0aWwga2V0aWdhIChRMyksIGRhbiBtYWtzaW11bSwgc2VydGEgbWVuYW5kYWkgb3V0bGllciAoZGF0YSBla3N0cmVtKS4NCg0KKioqQXR1cmFuIFBlbmdndW5hYW46KioqDQoNCi0gR3VuYWthbiB1bnR1ayBkYXRhIG51bWVyaWsuDQoNCi0gQ29jb2sgdW50dWsgbWVtYmFuZGluZ2thbiBzZWJhcmFuIGRhdGEgYW50YXIga2Vsb21wb2sgKG1pc2FsbnlhIElQSyBwZXIgZmFrdWx0YXMpLg0KDQotIE1lZGlhbiBtZW51bmp1a2thbiBuaWxhaSB0ZW5nYWgsIHBhbmphbmcga290YWsgbWVudW5qdWtrYW4gdGluZ2thdCB2YXJpYXNpIGRhdGEuDQoNCioqKktlbGViaWhhbjoqKioNCg0KLSBNZW1iZXJpa2FuIHJpbmdrYXNhbiBzZWJhcmFuIGRhdGEgc2VjYXJhIGNlcGF0Lg0KDQotIERhcGF0IG1lbmRldGVrc2kgb3V0bGllciBkZW5nYW4gbXVkYWguDQoNCi0gSWRlYWwgdW50dWsgbWVtYmFuZGluZ2thbiBiZWJlcmFwYSBrZWxvbXBvayBkYXRhIHNla2FsaWd1cy4NCg0KKioqS2VrdXJhbmdhbjoqKioNCg0KLSBUaWRhayBtZW51bmp1a2thbiBkZXRhaWwgZGlzdHJpYnVzaSAoc2VwZXJ0aSBiZW50dWsga3VydmEpLg0KDQotIFN1bGl0IGRpcGFoYW1pIG9sZWggb3JhbmcgYXdhbS4NCg0KDQpgYGB7cn0NCmdncGxvdChkYXRhX21haGFzaXN3YSwgYWVzKHggPSBGYWt1bHRhcywgeSA9IEtlaGFkaXJhbiwgZmlsbCA9IEZha3VsdGFzKSkgKw0KICBnZW9tX2JveHBsb3QoKSArDQogIGxhYnModGl0bGUgPSAiRGlzdHJpYnVzaSBLZWhhZGlyYW4gcGVyIEZha3VsdGFzIiwgeSA9ICJLZWhhZGlyYW4gKCUpIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KIyBUdWp1YW46IE1lbmdldGFodWkgcGVueWViYXJhbiBkYXRhIGRhbiBtZW5kZXRla3NpIG91dGxpZXINCmBgYA0KDQoNCg0KIyMjIFBpZSBDaGFydDogUHJvcG9yc2kgTWFoYXNpc3dhIEJlcmRhc2Fya2FuIEthdGVnb3JpIElQSw0KDQoqKipEZWZpbmlzaToqKioNCg0KUGllIGNoYXJ0IG1lbmdnYW1iYXJrYW4gcHJvcG9yc2kgYXRhdSBwZXJzZW50YXNlIGRhcmkgc2V0aWFwIGthdGVnb3JpIHRlcmhhZGFwIHRvdGFsIGtlc2VsdXJ1aGFuIGRhbGFtIGJlbnR1ayBpcmlzYW4gbGluZ2thcmFuLg0KU2V0aWFwIHBvdG9uZ2FuIChzbGljZSkgbWVudW5qdWtrYW4gc2ViZXJhcGEgYmVzYXIga29udHJpYnVzaSBzdWF0dSBrYXRlZ29yaSBkaWJhbmRpbmcgdG90YWwuDQoNCioqKkF0dXJhbiBQZW5nZ3VuYWFuOioqKg0KDQotIEd1bmFrYW4gdW50dWsgZGF0YSBrYXRlZ29yaWsgZGVuZ2FuIHRvdGFsID0gMTAwJS4NCg0KLSBHdW5ha2FuIG1ha3NpbWFsIDXigJM2IGthdGVnb3JpIGFnYXIgZ3JhZmlrIHRldGFwIGplbGFzLg0KDQotIEd1bmFrYW4gbGFiZWwgcGVyc2VudGFzZSBhZ2FyIG11ZGFoIGRpYmFjYS4NCg0KKioqS2VsZWJpaGFuOioqKg0KDQotIE1lbmFyaWsgc2VjYXJhIHZpc3VhbCBkYW4gbXVkYWggZGlwYWhhbWkuDQoNCi0gQ29jb2sgdW50dWsgbWVudW5qdWtrYW4gcGVyYmFuZGluZ2FuIGJhZ2lhbiB0ZXJoYWRhcCBrZXNlbHVydWhhbi4NCg0KKioqS2VrdXJhbmdhbjoqKioNCg0KLSBUaWRhayBha3VyYXQgdW50dWsgYmFueWFrIGthdGVnb3JpLg0KDQotIFN1bGl0IG1lbWJhbmRpbmdrYW4gdWt1cmFuIGFudGFyIGlyaXNhbiBzZWNhcmEgdGVwYXQuDQoNCi0gVGlkYWsgbWVudW5qdWtrYW4gbmlsYWkgYWJzb2x1dC4NCg0KYGBge3J9DQpwaWVfaXBrIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoZGF0YV9tYWhhc2lzd2EkS2F0ZWdvcmlfSVBLKSkNCmNvbG5hbWVzKHBpZV9pcGspIDwtIGMoIkthdGVnb3JpX0lQSyIsICJKdW1sYWgiKQ0KDQpnZ3Bsb3QocGllX2lwaywgYWVzKHggPSAiIiwgeSA9IEp1bWxhaCwgZmlsbCA9IEthdGVnb3JpX0lQSykpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMSkgKw0KICBjb29yZF9wb2xhcigieSIpICsNCiAgbGFicyh0aXRsZSA9ICJQcm9wb3JzaSBNYWhhc2lzd2EgQmVyZGFzYXJrYW4gS2F0ZWdvcmkgSVBLIikgKw0KICB0aGVtZV92b2lkKCkNCg0KIyBUdWp1YW46IE1lbmdldGFodWkgcHJvcG9yc2kga2VzZWx1cnVoYW4gbWFoYXNpc3dhIGJlcmRhc2Fya2FuIGthdGVnb3JpIElQSw0KYGBgDQoNCg0KIyMjIFNjYXR0ZXIgUGxvdDogSHVidW5nYW4gYW50YXJhIFdha3R1IEJlbGFqYXIgZGFuIE5pbGFpIFVBUyBiZXJkYXNhcmthbiBLYXRlZ29yaSBJUEsNCg0KKioqRGVmaW5pc2k6KioqDQoNClNjYXR0ZXIgcGxvdCBtZW5hbXBpbGthbiBodWJ1bmdhbiBhbnRhcmEgZHVhIHZhcmlhYmVsIG51bWVyaWsgZGFsYW0gYmVudHVrIHRpdGlrLXRpdGlrIHBhZGEgYmlkYW5nIGtvb3JkaW5hdC4NClNldGlhcCB0aXRpayBtZXdha2lsaSBzYXR1IGRhdGEgKG1pc2FsbnlhIHNhdHUgbWFoYXNpc3dhKSwgZGVuZ2FuIHBvc2lzaSBYIGRhbiBZIG1ld2FraWxpIGR1YSBuaWxhaSB2YXJpYWJlbC4NCg0KKioqQXR1cmFuIFBlbmdndW5hYW46KioqDQoNCi0gR3VuYWthbiB1bnR1ayBtZW51bmp1a2thbiBrb3JlbGFzaSBhdGF1IGh1YnVuZ2FuIGFudGFyYSBkdWEgdmFyaWFiZWwgbnVtZXJpayAobWlzYWw6IFdha3R1IEJlbGFqYXIgdnMgTmlsYWkgVUFTKS4NCg0KLSBCaXNhIGRpdGFtYmFoIHdhcm5hL3NoYXBlIHVudHVrIG1lbWJlZGFrYW4ga2Vsb21wb2sgKG1pc2FsbnlhIGZha3VsdGFzKS4NCg0KKioqS2VsZWJpaGFuOioqKg0KDQotIE1lbnVuanVra2FuIGh1YnVuZ2FuIGF0YXUgcG9sYSAocG9zaXRpZiwgbmVnYXRpZiwgYWNhaykuDQoNCi0gQmlzYSBtZW5kZXRla3NpIG91dGxpZXIuDQoNCi0gQ29jb2sgdW50dWsgYW5hbGlzaXMga29yZWxhc2kuDQoNCioqKktla3VyYW5nYW46KioqDQoNCi0gVGlkYWsgY29jb2sgdW50dWsgZGF0YSBrYXRlZ29yaWsuDQoNCi0gSmlrYSBkYXRhIHRlcmxhbHUgYmFueWFrLCB0aXRpayBiaXNhIHNhbGluZyBtZW51bXB1ay4NCg0KYGBge3J9DQpnZ3Bsb3QoZGF0YV9tYWhhc2lzd2EsIGFlcyh4ID0gV2FrdHVfYmVsYWphciwgeSA9IE5pbGFpX1VBUywgY29sb3IgPSBLYXRlZ29yaV9JUEspKSArDQogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBsYWJzKHRpdGxlID0gIkh1YnVuZ2FuIFdha3R1IEJlbGFqYXIgZGFuIE5pbGFpIFVBUyBiZXJkYXNhcmthbiBLYXRlZ29yaSBJUEsiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQojIFR1anVhbjogTWVsaWhhdCBodWJ1bmdhbiBhbnRhcmEgd2FrdHUgYmVsYWphciBkYW4gbmlsYWkgVUFTLCBzZXJ0YSBhcGFrYWgga2F0ZWdvcmkgSVBLIG1lbWVuZ2FydWhpIGh1YnVuZ2FuIGl0dQ0KYGBgDQoNCg0KIyMjIExpbmUgUGxvdDogVHJlbiBuaWxhaSBVQVMgbWFoYXNpc3dhIGJlcmRhc2Fya2FuIGthdGVnb3JpIElQSw0KDQoqKipEZWZpbmlzaToqKioNCg0KTGluZSBwbG90IGRpZ3VuYWthbiB1bnR1ayBtZW51bmp1a2thbiBwZXJ1YmFoYW4gZGF0YSBzZWNhcmEgYmVydXJ1dGFuLCBiaWFzYW55YSBiZXJkYXNhcmthbiB3YWt0dSBhdGF1IHVydXRhbiB0ZXJ0ZW50dSAobWlzYWxueWEgdHJlbiBuaWxhaSBwZXIgc2VtZXN0ZXIpLg0KU2V0aWFwIHRpdGlrIGRhdGEgZGlodWJ1bmdrYW4gZGVuZ2FuIGdhcmlzLCBzZWhpbmdnYSBraXRhIGJpc2EgbWVsaWhhdCBwb2xhIHRyZW4gbmFpayBhdGF1IHR1cnVuLg0KDQoqKipBdHVyYW4gUGVuZ2d1bmFhbjoqKioNCg0KLSBHdW5ha2FuIHVudHVrIGRhdGEgYmVydXJ1dGFuIGF0YXUgdGltZSBzZXJpZXMuDQoNCi0gU3VtYnUgWCDihpIgd2FrdHUgYXRhdSB1cnV0YW4uDQoNCi0gU3VtYnUgWSDihpIgbmlsYWkgeWFuZyBkaXVrdXIuDQoNCi0gR3VuYWthbiB3YXJuYSBiZXJiZWRhIGppa2EgbWVtYmFuZGluZ2thbiBiZWJlcmFwYSBzZXJpLg0KDQoqKipLZWxlYmloYW46KioqDQoNCi0gU2FuZ2F0IGJhZ3VzIHVudHVrIG1lbmFtcGlsa2FuIHRyZW4gZGFuIHBlcnViYWhhbiBkYXJpIHdha3R1IGtlIHdha3R1Lg0KDQotIE11ZGFoIGRpYmFjYSBkYW4gZGltZW5nZXJ0aS4NCg0KLSBEYXBhdCBtZW5hbXBpbGthbiBiZWJlcmFwYSBzZXJpIGRhdGEgc2VrYWxpZ3VzLg0KDQoqKipLZWt1cmFuZ2FuOioqKg0KDQotIFRpZGFrIGNvY29rIHVudHVrIGRhdGEgeWFuZyB0aWRhayBiZXJ1cnV0YW4uDQoNCi0gQmlzYSBtZW1iaW5ndW5na2FuIGppa2EgdGVybGFsdSBiYW55YWsgZ2FyaXMuDQoNCmBgYHtyfQ0KZ2dwbG90KGRhdGFfbWFoYXNpc3dhLCBhZXMoeCA9IElEX01haGFzaXN3YSwgeSA9IE5pbGFpX1VBUywgZ3JvdXAgPSAxLCBjb2xvciA9IEthdGVnb3JpX0lQSykpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBnZW9tX3BvaW50KHNpemUgPSAzKSArDQogIGxhYnModGl0bGUgPSAiTmlsYWkgVUFTIHBlciBNYWhhc2lzd2EgYmVyZGFzYXJrYW4gS2F0ZWdvcmkgSVBLIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KDQojIFR1anVhbjogTWVuYW1waWxrYW4gdXJ1dGFuIG5pbGFpIFVBUyBzZXRpYXAgbWFoYXNpc3dhIHNlcnRhIHBlcmJhbmRpbmdhbm55YSBhbnRhciBrYXRlZ29yaSBJUEsuDQoNCmBgYA0KDQoNCg0KIyMjIERlbnNpdHkgUGxvdDogRXN0aW1hc2kgZGlzdHJpYnVzaSBJUEsNCg0KKioqRGVmaW5pc2k6KioqDQoNCkRlbnNpdHkgcGxvdCBhZGFsYWggZ3JhZmlrIHlhbmcgbWVudW5qdWtrYW4gYmVudHVrIGRpc3RyaWJ1c2kgZGF0YSBudW1lcmlrIHNlY2FyYSBoYWx1cyAoc21vb3RoKS4NCk1pcmlwIGhpc3RvZ3JhbSwgdGFwaSBtZW5nZ2FudGlrYW4gYmF0YW5nIGRlbmdhbiBrdXJ2YSBoYWx1cyB5YW5nIG1lbXBlcmtpcmFrYW4ga2VwYWRhdGFuIGRhdGEuDQpLdXJ2YSB5YW5nIHRpbmdnaSBtZW51bmp1a2thbiBiYW55YWsgZGF0YSBkaSBhcmVhIHRlcnNlYnV0Lg0KDQoqKipBdHVyYW4gUGVuZ2d1bmFhbjoqKioNCg0KLSBHdW5ha2FuIHVudHVrIGRhdGEgbnVtZXJpayBrb250aW51Lg0KDQotIENvY29rIHVudHVrIG1lbWJhbmRpbmdrYW4gYmViZXJhcGEga2Vsb21wb2sgKG1pc2FsbnlhIGRpc3RyaWJ1c2kgSVBLIHBlciBmYWt1bHRhcykuDQoNCi0gQmlhc2FueWEgZGlidWF0IGRlbmdhbiBmdW5nc2kgZ2VvbV9kZW5zaXR5KCkgZGkgUi4NCg0KKioqS2VsZWJpaGFuOioqKg0KDQotIE1lbnVuanVra2FuIGJlbnR1ayBkaXN0cmlidXNpIGRlbmdhbiBsZWJpaCBsZW1idXQuDQoNCi0gQ29jb2sgdW50dWsgcGVyYmFuZGluZ2FuIGFudGFyIGtlbG9tcG9rLg0KDQotIFRlcmxpaGF0IGxlYmloIGVzdGV0aXMgZGFyaXBhZGEgaGlzdG9ncmFtLg0KDQoqKipLZWt1cmFuZ2FuOioqKg0KDQotIEt1cmFuZyBha3VyYXQgdW50dWsgZGF0YXNldCBrZWNpbC4NCg0KLSBUaWRhayBtZW51bmp1a2thbiBqdW1sYWggZGF0YSBzZWNhcmEgbGFuZ3N1bmcuDQoNCg0KYGBge3J9DQpnZ3Bsb3QoZGF0YV9tYWhhc2lzd2EsIGFlcyh4ID0gSVBLLCBmaWxsID0gRmFrdWx0YXMpKSArDQogIGdlb21fZGVuc2l0eShhbHBoYSA9IDAuNSkgKw0KICBsYWJzKHRpdGxlID0gIkRlbnNpdHkgUGxvdCBJUEsgcGVyIEZha3VsdGFzIiwgeCA9ICJJUEsiLCB5ID0gIkRlbnNpdHkiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQojIFR1anVhbjogTWVuZ2VzdGltYXNpIGRpc3RyaWJ1c2kgcHJvYmFiaWxpdGFzIHZhcmlhYmVsIG51bWVyaWsNCmBgYA0KDQoNCiMjIyAgUmlkZ2VsaW5lIFBsb3Q6IERpc3RyaWJ1c2kgTmlsYWkgVUFTIHBlciBGYWt1bHRhcw0KDQoqKipEZWZpbmlzaToqKioNCg0KUmlkZ2VsaW5lIHBsb3QgKGF0YXUgam95cGxvdCkgYWRhbGFoIGt1bXB1bGFuIGRhcmkgYmViZXJhcGEgZGVuc2l0eSBwbG90IHlhbmcgZGl0dW1wdWsgc2VjYXJhIHZlcnRpa2FsLCBkaWd1bmFrYW4gdW50dWsgbWVtYmFuZGluZ2thbiBkaXN0cmlidXNpIGRhdGEgYW50YXIga2F0ZWdvcmkuDQpTZXRpYXAg4oCcZ2Vsb21iYW5n4oCdIChyaWRnZSkgbWV3YWtpbGkgc2F0dSBrZWxvbXBvaywgZGFuIGJlbnR1a255YSBtZW51bmp1a2thbiBwb2xhIHNlYmFyYW4gbmlsYWkgZGFsYW0ga2Vsb21wb2sgdGVyc2VidXQuDQoNCioqKkF0dXJhbiBQZW5nZ3VuYWFuOioqKg0KDQotIEd1bmFrYW4gdW50dWsgbWVtYmFuZGluZ2thbiBkaXN0cmlidXNpIGRhdGEgbnVtZXJpayBhbnRhciBrYXRlZ29yaSAobWlzYWxueWEgTmlsYWkgVUFTIHBlciBGYWt1bHRhcykuDQoNCi0gQmlhc2FueWEgZGlidWF0IGRlbmdhbiBwYWtldCBnZ3JpZGdlcyBkaSBSLg0KDQoqKipLZWxlYmloYW46KioqDQoNCi0gVmlzdWFsbnlhIG1lbmFyaWsgZGFuIGluZm9ybWF0aWYuDQoNCi0gTXVkYWggbWVsaWhhdCBwZXJiZWRhYW4gcG9sYSBkaXN0cmlidXNpIGFudGFyIGthdGVnb3JpLg0KDQotIENvY29rIHVudHVrIGRhdGFzZXQgZGVuZ2FuIGJhbnlhayBrZWxvbXBvay4NCg0KKioqS2VrdXJhbmdhbjoqKioNCg0KLSBCaXNhIHN1bGl0IGRpYmFjYSBrYWxhdSBrYXRlZ29yaSB0ZXJsYWx1IGJhbnlhay4NCg0KLSBUaWRhayBtZW51bmp1a2thbiBuaWxhaSBudW1lcmlrwqB5YW5nwqBzcGVzaWZpay4NCmBgYHtyfQ0KbGlicmFyeShnZ3JpZGdlcykNCg0KZ2dwbG90KGRhdGFfbWFoYXNpc3dhLCBhZXMoeCA9IE5pbGFpX1VBUywgeSA9IEZha3VsdGFzLCBmaWxsID0gRmFrdWx0YXMpKSArDQogIGdlb21fZGVuc2l0eV9yaWRnZXMoYWxwaGEgPSAwLjcpICsNCiAgbGFicyh0aXRsZSA9ICJSaWRnZWxpbmUgUGxvdCBOaWxhaSBVQVMgcGVyIEZha3VsdGFzIiwgeCA9ICJOaWxhaSBVQVMiLCB5ID0gIkZha3VsdGFzIikgKw0KICB0aGVtZV9yaWRnZXMoKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCg0KIyBUdWp1YW46IE1lbWJhbmRpbmdrYW4gZGlzdHJpYnVzaSBiZWJlcmFwYSBrZWxvbXBva8Kgc2VrYWxpZ3VzDQpgYGANCg0KDQojIEtlc2ltcHVsYW4NCkJlcmRhc2Fya2FuIHZpc3VhbGlzYXNpOg0KDQotIE1haGFzaXN3YSBzZWNhcmEgdW11bSBiZXJwcmVzdGFzaSBiYWlrLCBkZW5nYW4gbWF5b3JpdGFzIGJlcmFkYSBwYWRhIGthdGVnb3JpIElQSyB0aW5nZ2kuDQoNCi0gTmlsYWkgVUFTIG1haGFzaXN3YSBiZXJiZWRhIGFudGFyIGZha3VsdGFzLCBiZWJlcmFwYSBmYWt1bHRhcyBtZW1pbGlraSBuaWxhaSByYXRhLXJhdGEgbGViaWggdGluZ2dpLg0KDQotIFNlYmFyYW4gbmlsYWkgdW11bW55YSBub3JtYWwsIHRhcGkgYWRhIGJlYmVyYXBhIG91dGxpZXIuDQoNCi0gTWFoYXNpc3dhIGRlbmdhbiB3YWt0dSBiZWxhamFyIGxlYmloIHRpbmdnaSBjZW5kZXJ1bmcgbWVtcGVyb2xlaCBuaWxhaSBVQVMgbGViaWggYmFpay4NCg0KLSBSaWRnZWxpbmUgZGFuIEJveHBsb3QgbWVtYmFudHUgbWVtYmFuZGluZ2thbiBkaXN0cmlidXNpIGRhbiBwcm9wb3JzaSBhbnRhciBmYWt1bHRhcy4NCg0KLSBWaXN1YWxpc2FzaSBpbmkgbWVtcGVybXVkYWggcGVtYWhhbWFuIHBvbGEgYWthZGVtaWsgbWFoYXNpc3dhIGRhbiBodWJ1bmdhbiBhbnRhciB2YXJpYWJlbCBkZW5nYW4gY2VwYXQu