Pemprogram Sains Data

UTS Pemprograman Sains Data

Logo

1 Operasi dan Tipe Data Dasar

Berikut adalah program sederhana R dalam Operasi dan Tie Data Dasar:

# Meminta input dari pengguna
bil1 <- as.numeric(readline(prompt = "Masukkan bilangan pertama: "))
## Masukkan bilangan pertama:
bil2 <- as.numeric(readline(prompt = "Masukkan bilangan kedua: "))
## Masukkan bilangan kedua:
# Operasi matematika
penjumlahan <- bil1 + bil2
perkalian <- bil1 * bil2
pembagian <- bil1 / bil2
pangkat <- bil1 ^ bil2

# Output sesuai permintaan
cat("Penjumlahan:", penjumlahan, "| Tipe:", class(penjumlahan), "\n")
## Penjumlahan: NA | Tipe: numeric
cat("Perkalian:", perkalian, "| Tipe:", class(perkalian), "\n")
## Perkalian: NA | Tipe: numeric
cat("Pembagian:", pembagian, "| Tipe:", class(pembagian), "\n")
## Pembagian: NA | Tipe: numeric
cat("Pangkat:", pangkat, "| Tipe:", class(pangkat), "\n")
## Pangkat: NA | Tipe: numeric

2 Struktur Kendali (Control Flow)

Berikut adalah program sederhana R dalam Control Flow:

# Menerima input dari pengguna
nilai <- as.numeric(readline(prompt = "Masukkan nilai ujian (0-100): "))
## Masukkan nilai ujian (0-100):
# Mengecek apakah input valid
if (is.na(nilai) || nilai < 0 || nilai > 100) {
  cat("Input tidak valid. Harap masukkan angka antara 0 dan 100.\n")
} else {
  # Menentukan keterangan berdasarkan nilai
  if (nilai >= 85) {
    keterangan <- "Sangat Baik"
  } else if (nilai >= 70) {
    keterangan <- "Baik"
  } else if (nilai >= 60) {
    keterangan <- "Cukup"
  } else {
    keterangan <- "Perlu Perbaikan"
  }

  # Menampilkan hasil
  cat("Nilai:", nilai, "\n")
  cat("Keterangan:", keterangan, "\n")
}
## Input tidak valid. Harap masukkan angka antara 0 dan 100.

3 Fungsi dan Perulangan

Berikut adalah program R sederhana dalam Fungsi dan Perulangan:

kelipatan_genap <- function(n) {
  # Validasi input: harus bilangan bulat positif
  if (is.na(n) || !is.numeric(n) || n <= 0 || n != floor(n)) {
    cat("Input harus berupa bilangan bulat positif.\n")
    return()
  }

  cat("Bilangan genap kelipatan 4 dari 1 hingga", n, ":\n")
  
  hasil <- c()  # vektor penampung hasil
  for (i in 1:n) {
    if (i %% 4 == 0) {
      hasil <- c(hasil, i)
    }
  }
  
  # Tampilkan hasil sebagai daftar angka yang dipisah koma
  cat(paste(hasil, collapse = ", "), "\n")
}

# Minta input dari pengguna
input <- readline(prompt = "Masukkan bilangan bulat positif: ")
## Masukkan bilangan bulat positif:
n <- as.numeric(input)

# Panggil fungsi
kelipatan_genap(n)
## Input harus berupa bilangan bulat positif.
## NULL

4 Studi Kasus

Sebuah perusahaan e-commerce ingin menganalisis performa penjualannya berdasarkan data transaksi selama 3 bulan terakhir. Namun, data yang tersedia berasal dari berbagai sumber dan memiliki kualitas yang beragam.

4.1 Data Collection

## Jumlah Baris: 150 
## Jumlah Kolom: 9

Setelah nggabungin data dari tiga file transaksi bulanan (Januari, Februari, dan Maret), totalnya ada 150 baris transaksi. Ini ngasih gambaran kalau tiap file isinya kira-kira 50 transaksi. Di dataset gabungan ini juga ada 9 kolom, yang nunjukin tiap transaksi punya sembilan info penting — kayak tanggal beli, nama produk, kategori, harga, jumlah yang dibeli, dan juga siapa pembelinya.

4.2 Data Cleaning

Pada tahap ini data nya di bersihkan. Data yang tadinya berantakan sekarang udah dibersihin. Tanggal semua udah disamain jadi format YYYY-MM-DD, harga dan jumlah barang yang tadinya masih ada tulisan kayak “Rp” atau “dua” udah diganti jadi angka.

Kolom Total juga udah dihitung otomatis dari Harga × Jumlah. Kalau ada data yang aneh atau kosong, langsung diganti NA. Produk yang nggak ada namanya juga dihapus.

Sekarang datanya udah rapi dan siap dipakai buat analisis.

4.3 Data Transformasi

Total Penjualan per Kategori
Kategori Total Penjualan
123009750
Aksesoris 331762000
Elektronik 167006750
Fashion 225006750
Jumlah Transaksi per Kota
Kota Jumlah Transaksi
- 30
Bandung 33
Jakarta 29
Surabaya 30
Ringkasan Penjualan per Bulan
Bulan Total Penjualan
2024-01 195757500
2024-02 286761250
2024-03 318008250
2024-04 46258250

4.4 Visualisasi

LS0tDQp0aXRsZTogIlBlbXByb2dyYW0gU2FpbnMgRGF0YSINCnN1YnRpdGxlOiAiVVRTIFBlbXByb2dyYW1hbiBTYWlucyBEYXRhIg0KYXV0aG9yOiANCiAgLSAiTm92YSBTaXRvcnVzIDUyMjQwMDIzIg0KZGF0ZTogICJgciBmb3JtYXQoU3lzLkRhdGUoKSwgJyVCICVkLCAlWScpYCINCm91dHB1dDoNCiAgcm1kZm9ybWF0czo6cmVhZHRoZWRvd246ICAgIyBodHRwczovL2dpdGh1Yi5jb20vanViYS9ybWRmb3JtYXRzDQogICAgc2VsZl9jb250YWluZWQ6IHRydWUNCiAgICB0aHVtYm5haWxzOiB0cnVlDQogICAgbGlnaHRib3g6IHRydWUNCiAgICBnYWxsZXJ5OiB0cnVlDQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgbGliX2RpcjogbGlicw0KICAgIGRmX3ByaW50OiAicGFnZWQiDQogICAgY29kZV9mb2xkaW5nOiAic2hvdyINCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBjc3M6ICJzdHlsZS9zdHlsZSBjc3MuY3NzIg0KLS0tDQoNCjxzdHlsZT4NCiAgYm9keSB7DQogICAgdGV4dC1hbGlnbjoganVzdGlmeTsNCiAgfQ0KPC9zdHlsZT4NCg0KPGltZyBzcmM9Ik5PVkEuanBnIiBhbHQ9IkxvZ28iIHN0eWxlPSJ3aWR0aDo1MDBweDsgZGlzcGxheTogYmxvY2s7IG1hcmdpbjogYXV0bzsiLz4NCg0KIyAqKk9wZXJhc2kgZGFuIFRpcGUgRGF0YSBEYXNhcioqDQoNCkJlcmlrdXQgYWRhbGFoIHByb2dyYW0gc2VkZXJoYW5hIFIgZGFsYW0gT3BlcmFzaSBkYW4gVGllIERhdGEgRGFzYXI6DQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPVRSVUV9DQojIE1lbWludGEgaW5wdXQgZGFyaSBwZW5nZ3VuYQ0KYmlsMSA8LSBhcy5udW1lcmljKHJlYWRsaW5lKHByb21wdCA9ICJNYXN1a2thbiBiaWxhbmdhbiBwZXJ0YW1hOiAiKSkNCmJpbDIgPC0gYXMubnVtZXJpYyhyZWFkbGluZShwcm9tcHQgPSAiTWFzdWtrYW4gYmlsYW5nYW4ga2VkdWE6ICIpKQ0KDQojIE9wZXJhc2kgbWF0ZW1hdGlrYQ0KcGVuanVtbGFoYW4gPC0gYmlsMSArIGJpbDINCnBlcmthbGlhbiA8LSBiaWwxICogYmlsMg0KcGVtYmFnaWFuIDwtIGJpbDEgLyBiaWwyDQpwYW5na2F0IDwtIGJpbDEgXiBiaWwyDQoNCiMgT3V0cHV0IHNlc3VhaSBwZXJtaW50YWFuDQpjYXQoIlBlbmp1bWxhaGFuOiIsIHBlbmp1bWxhaGFuLCAifCBUaXBlOiIsIGNsYXNzKHBlbmp1bWxhaGFuKSwgIlxuIikNCmNhdCgiUGVya2FsaWFuOiIsIHBlcmthbGlhbiwgInwgVGlwZToiLCBjbGFzcyhwZXJrYWxpYW4pLCAiXG4iKQ0KY2F0KCJQZW1iYWdpYW46IiwgcGVtYmFnaWFuLCAifCBUaXBlOiIsIGNsYXNzKHBlbWJhZ2lhbiksICJcbiIpDQpjYXQoIlBhbmdrYXQ6IiwgcGFuZ2thdCwgInwgVGlwZToiLCBjbGFzcyhwYW5na2F0KSwgIlxuIikNCg0KYGBgDQoNCiMgKipTdHJ1a3R1ciBLZW5kYWxpIChDb250cm9sIEZsb3cpKioNCg0KQmVyaWt1dCBhZGFsYWggcHJvZ3JhbSBzZWRlcmhhbmEgUiBkYWxhbSBDb250cm9sIEZsb3c6DQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPVRSVUV9DQojIE1lbmVyaW1hIGlucHV0IGRhcmkgcGVuZ2d1bmENCm5pbGFpIDwtIGFzLm51bWVyaWMocmVhZGxpbmUocHJvbXB0ID0gIk1hc3Vra2FuIG5pbGFpIHVqaWFuICgwLTEwMCk6ICIpKQ0KDQojIE1lbmdlY2VrIGFwYWthaCBpbnB1dCB2YWxpZA0KaWYgKGlzLm5hKG5pbGFpKSB8fCBuaWxhaSA8IDAgfHwgbmlsYWkgPiAxMDApIHsNCiAgY2F0KCJJbnB1dCB0aWRhayB2YWxpZC4gSGFyYXAgbWFzdWtrYW4gYW5na2EgYW50YXJhIDAgZGFuIDEwMC5cbiIpDQp9IGVsc2Ugew0KICAjIE1lbmVudHVrYW4ga2V0ZXJhbmdhbiBiZXJkYXNhcmthbiBuaWxhaQ0KICBpZiAobmlsYWkgPj0gODUpIHsNCiAgICBrZXRlcmFuZ2FuIDwtICJTYW5nYXQgQmFpayINCiAgfSBlbHNlIGlmIChuaWxhaSA+PSA3MCkgew0KICAgIGtldGVyYW5nYW4gPC0gIkJhaWsiDQogIH0gZWxzZSBpZiAobmlsYWkgPj0gNjApIHsNCiAgICBrZXRlcmFuZ2FuIDwtICJDdWt1cCINCiAgfSBlbHNlIHsNCiAgICBrZXRlcmFuZ2FuIDwtICJQZXJsdSBQZXJiYWlrYW4iDQogIH0NCg0KICAjIE1lbmFtcGlsa2FuIGhhc2lsDQogIGNhdCgiTmlsYWk6IiwgbmlsYWksICJcbiIpDQogIGNhdCgiS2V0ZXJhbmdhbjoiLCBrZXRlcmFuZ2FuLCAiXG4iKQ0KfQ0KDQpgYGANCg0KIyAqKkZ1bmdzaSBkYW4gUGVydWxhbmdhbioqDQoNCkJlcmlrdXQgYWRhbGFoIHByb2dyYW0gUiBzZWRlcmhhbmEgZGFsYW0gRnVuZ3NpIGRhbiBQZXJ1bGFuZ2FuOg0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1UUlVFfQ0Ka2VsaXBhdGFuX2dlbmFwIDwtIGZ1bmN0aW9uKG4pIHsNCiAgIyBWYWxpZGFzaSBpbnB1dDogaGFydXMgYmlsYW5nYW4gYnVsYXQgcG9zaXRpZg0KICBpZiAoaXMubmEobikgfHwgIWlzLm51bWVyaWMobikgfHwgbiA8PSAwIHx8IG4gIT0gZmxvb3IobikpIHsNCiAgICBjYXQoIklucHV0IGhhcnVzIGJlcnVwYSBiaWxhbmdhbiBidWxhdCBwb3NpdGlmLlxuIikNCiAgICByZXR1cm4oKQ0KICB9DQoNCiAgY2F0KCJCaWxhbmdhbiBnZW5hcCBrZWxpcGF0YW4gNCBkYXJpIDEgaGluZ2dhIiwgbiwgIjpcbiIpDQogIA0KICBoYXNpbCA8LSBjKCkgICMgdmVrdG9yIHBlbmFtcHVuZyBoYXNpbA0KICBmb3IgKGkgaW4gMTpuKSB7DQogICAgaWYgKGkgJSUgNCA9PSAwKSB7DQogICAgICBoYXNpbCA8LSBjKGhhc2lsLCBpKQ0KICAgIH0NCiAgfQ0KICANCiAgIyBUYW1waWxrYW4gaGFzaWwgc2ViYWdhaSBkYWZ0YXIgYW5na2EgeWFuZyBkaXBpc2FoIGtvbWENCiAgY2F0KHBhc3RlKGhhc2lsLCBjb2xsYXBzZSA9ICIsICIpLCAiXG4iKQ0KfQ0KDQojIE1pbnRhIGlucHV0IGRhcmkgcGVuZ2d1bmENCmlucHV0IDwtIHJlYWRsaW5lKHByb21wdCA9ICJNYXN1a2thbiBiaWxhbmdhbiBidWxhdCBwb3NpdGlmOiAiKQ0KbiA8LSBhcy5udW1lcmljKGlucHV0KQ0KDQojIFBhbmdnaWwgZnVuZ3NpDQprZWxpcGF0YW5fZ2VuYXAobikNCmBgYA0KDQojIFN0dWRpIEthc3VzDQoNClNlYnVhaCBwZXJ1c2FoYWFuIGUtY29tbWVyY2UgaW5naW4gbWVuZ2FuYWxpc2lzIHBlcmZvcm1hIHBlbmp1YWxhbm55YSBiZXJkYXNhcmthbg0KZGF0YSB0cmFuc2Frc2kgc2VsYW1hIDMgYnVsYW4gdGVyYWtoaXIuIE5hbXVuLCBkYXRhIHlhbmcgdGVyc2VkaWEgYmVyYXNhbCBkYXJpIGJlcmJhZ2FpDQpzdW1iZXIgZGFuIG1lbWlsaWtpIGt1YWxpdGFzIHlhbmcgYmVyYWdhbS4NCg0KIyMgRGF0YSBDb2xsZWN0aW9uDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQ0KIyBNZW1iYWNhIGRhbiBtZW5nZ2FidW5na2FuIGtldGlnYSBmaWxlDQppZiAoZmlsZS5leGlzdHMoIkphbnVhcmkuY3N2IikgJiYgZmlsZS5leGlzdHMoIkZlYnJ1YXJpLmNzdiIpICYmIGZpbGUuZXhpc3RzKCJNYXJldC5jc3YiKSkgew0KICBkYXRhX2phbnVhcmkgPC0gcmVhZC5jc3YoIkphbnVhcmkuY3N2Iiwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KICBkYXRhX2ZlYnJ1YXJpIDwtIHJlYWQuY3N2KCJGZWJydWFyaS5jc3YiLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQogIGRhdGFfbWFyZXQgPC0gcmVhZC5jc3YoIk1hcmV0LmNzdiIsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkNCg0KICBkYXRhX2dhYnVuZ2FuIDwtIHJiaW5kKGRhdGFfamFudWFyaSwgZGF0YV9mZWJydWFyaSwgZGF0YV9tYXJldCkNCg0KICBjYXQoIkp1bWxhaCBCYXJpczoiLCBucm93KGRhdGFfZ2FidW5nYW4pLCAiXG4iKQ0KICBjYXQoIkp1bWxhaCBLb2xvbToiLCBuY29sKGRhdGFfZ2FidW5nYW4pLCAiXG4iKQ0KDQogIGhlYWQoZGF0YV9nYWJ1bmdhbiwgMTApDQp9IGVsc2Ugew0KICBjYXQoIlNhdHUgYXRhdSBsZWJpaCBmaWxlIENTViB0aWRhayBkaXRlbXVrYW4uXG4iKQ0KfQ0KDQpgYGANClNldGVsYWggbmdnYWJ1bmdpbiBkYXRhIGRhcmkgdGlnYSBmaWxlIHRyYW5zYWtzaSBidWxhbmFuIChKYW51YXJpLCBGZWJydWFyaSwgZGFuIE1hcmV0KSwgdG90YWxueWEgYWRhIDE1MCBiYXJpcyB0cmFuc2Frc2kuIEluaSBuZ2FzaWggZ2FtYmFyYW4ga2FsYXUgdGlhcCBmaWxlIGlzaW55YSBraXJhLWtpcmEgNTAgdHJhbnNha3NpLiBEaSBkYXRhc2V0IGdhYnVuZ2FuIGluaSBqdWdhIGFkYSA5IGtvbG9tLCB5YW5nIG51bmp1a2luIHRpYXAgdHJhbnNha3NpIHB1bnlhIHNlbWJpbGFuIGluZm8gcGVudGluZyDigJQga2F5YWsgdGFuZ2dhbCBiZWxpLCBuYW1hIHByb2R1aywga2F0ZWdvcmksIGhhcmdhLCBqdW1sYWggeWFuZyBkaWJlbGksIGRhbiBqdWdhIHNpYXBhIHBlbWJlbGlueWEuDQoNCiMjIERhdGEgQ2xlYW5pbmcNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkoc3RyaW5ncikNCmxpYnJhcnkoRFQpDQoNCiMgYS4gU3RhbmRhcmthbiBmb3JtYXQgdGFuZ2dhbCBrZSBZWVlZLU1NLUREDQpkYXRhX2dhYnVuZ2FuJFRhbmdnYWwgPC0gYXMuRGF0ZShkYXRhX2dhYnVuZ2FuJFRhbmdnYWwsIGZvcm1hdCA9ICIlZC0lbS0lWSIpDQoNCiMgYi4gVWJhaCBrb2xvbSBIYXJnYSBkYW4gSnVtbGFoIG1lbmphZGkgbnVtZXJpaw0KIyBGdW5nc2kgdW50dWsgbWVtYmVyc2loa2FuIGRhdGEgbnVtZXJpaw0KY2xlYW5fbnVtZXJpYyA8LSBmdW5jdGlvbih4KSB7DQogIHggPC0gYXMuY2hhcmFjdGVyKHgpDQogIHggPC0gc3RyX3JlcGxhY2VfYWxsKHgsICJScHwsfFxcLXxkdWF8YW5vbnltb3VzfF9hbm9ueW1vdXNffCAiLCAiIikNCiAgaWYgKHRvbG93ZXIoeCkgJWluJSBjKCIiLCAibmEiLCAibmFuIikpIHJldHVybihOQV9yZWFsXykNCiAgc3VwcHJlc3NXYXJuaW5ncyhhcy5udW1lcmljKHgpKQ0KfQ0KDQpkYXRhX2dhYnVuZ2FuIDwtIGRhdGFfZ2FidW5nYW4gJT4lDQogIG11dGF0ZSgNCiAgICBIYXJnYSA9IHNhcHBseShIYXJnYSwgY2xlYW5fbnVtZXJpYyksDQogICAgSnVtbGFoID0gc2FwcGx5KEp1bWxhaCwgY2xlYW5fbnVtZXJpYykNCiAgKQ0KDQojIGMuIEhpdHVuZyB1bGFuZyBuaWxhaSBrb2xvbSBUb3RhbCA9IEhhcmdhICogSnVtbGFoDQpkYXRhX2dhYnVuZ2FuIDwtIGRhdGFfZ2FidW5nYW4gJT4lDQogIG11dGF0ZShUb3RhbCA9IEhhcmdhICogSnVtbGFoKQ0KDQojIGQuIEdhbnRpIG5pbGFpIHlhbmcgdGlkYWsgdmFsaWQgKC0sICJkdWEiLCAiUnAiLCAiX2Fub255bW91c18iKSBzdWRhaCBkaXRhbmdhbmkgZGkgZnVuZ3NpIGNsZWFuX251bWVyaWMNCg0KIyBlLiBIYXB1cyBiYXJpcyB5YW5nIHRpZGFrIG1lbWlsaWtpIG5hbWEgcHJvZHVrIChQcm9kdWsga29zb25nIGF0YXUgIi0iKQ0KZGF0YV9nYWJ1bmdhbiA8LSBkYXRhX2dhYnVuZ2FuICU+JQ0KICBmaWx0ZXIoIShQcm9kdWsgJWluJSBjKCIiLCAiLSIsIE5BKSkpDQoNCiMgVGFtcGlsa2FuIGhhc2lsIHNlYmFnYWkgdGFiZWwgaW50ZXJha3RpZg0KZGF0YXRhYmxlKGhlYWQoZGF0YV9nYWJ1bmdhbiwgMTApLCBjYXB0aW9uID0gIlRhYmVsIEludGVyYWt0aWY6IDEwIEJhcmlzIFBlcnRhbWEgRGF0YSBTZXRlbGFoIFBlbWJlcnNpaGFuIikNCmBgYA0KUGFkYSB0YWhhcCBpbmkgZGF0YSBueWEgZGkgYmVyc2loa2FuLiBEYXRhIHlhbmcgdGFkaW55YSBiZXJhbnRha2FuIHNla2FyYW5nIHVkYWggZGliZXJzaWhpbi4gVGFuZ2dhbCBzZW11YSB1ZGFoIGRpc2FtYWluIGphZGkgZm9ybWF0IFlZWVktTU0tREQsIGhhcmdhIGRhbiBqdW1sYWggYmFyYW5nIHlhbmcgdGFkaW55YSBtYXNpaCBhZGEgdHVsaXNhbiBrYXlhayAiUnAiIGF0YXUgImR1YSIgdWRhaCBkaWdhbnRpIGphZGkgYW5na2EuDQoNCktvbG9tIFRvdGFsIGp1Z2EgdWRhaCBkaWhpdHVuZyBvdG9tYXRpcyBkYXJpIEhhcmdhIMOXIEp1bWxhaC4gS2FsYXUgYWRhIGRhdGEgeWFuZyBhbmVoIGF0YXUga29zb25nLCBsYW5nc3VuZyBkaWdhbnRpIE5BLiBQcm9kdWsgeWFuZyBuZ2dhayBhZGEgbmFtYW55YSBqdWdhIGRpaGFwdXMuDQoNClNla2FyYW5nIGRhdGFueWEgdWRhaCByYXBpIGRhbiBzaWFwIGRpcGFrYWkgYnVhdCBhbmFsaXNpcy4NCg0KIyMgRGF0YSBUcmFuc2Zvcm1hc2kNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0V9DQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShsdWJyaWRhdGUpDQpsaWJyYXJ5KHJlYWRyKQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkoRFQpDQoNCiMgUGFzdGlrYW4ga29sb20gJ1RhbmdnYWwnIHN1ZGFoIGRhbGFtIGZvcm1hdCBEYXRlDQpkYXRhX2dhYnVuZ2FuJFRhbmdnYWwgPC0gYXMuRGF0ZShkYXRhX2dhYnVuZ2FuJFRhbmdnYWwpDQoNCiMgYS4gQnVhdCBrb2xvbSBCdWxhbg0KZGF0YV9nYWJ1bmdhbiRCdWxhbiA8LSBmb3JtYXQoZGF0YV9nYWJ1bmdhbiRUYW5nZ2FsLCAiJVktJW0iKQ0KDQojIGIuIFRvdGFsIHBlbmp1YWxhbiBwZXIga2F0ZWdvcmkNCmlmIChhbGwoYygiS2F0ZWdvcmkiLCAiVG90YWwiKSAlaW4lIG5hbWVzKGRhdGFfZ2FidW5nYW4pKSkgew0KICB0b3RhbF9wZXJfa2F0ZWdvcmkgPC0gZGF0YV9nYWJ1bmdhbiAlPiUNCiAgICBncm91cF9ieShLYXRlZ29yaSkgJT4lDQogICAgc3VtbWFyaXNlKGBUb3RhbCBQZW5qdWFsYW5gID0gc3VtKFRvdGFsLCBuYS5ybSA9IFRSVUUpKQ0KfSBlbHNlIHsNCiAgdG90YWxfcGVyX2thdGVnb3JpIDwtIGRhdGEuZnJhbWUoKQ0KfQ0KDQojIGMuIEp1bWxhaCB0cmFuc2Frc2kgcGVyIGtvdGENCmlmICgiS290YSIgJWluJSBuYW1lcyhkYXRhX2dhYnVuZ2FuKSkgew0KICB0cmFuc2Frc2lfcGVyX2tvdGEgPC0gZGF0YV9nYWJ1bmdhbiAlPiUNCiAgICBjb3VudChLb3RhLCBuYW1lID0gIkp1bWxhaCBUcmFuc2Frc2kiKQ0KfSBlbHNlIHsNCiAgdHJhbnNha3NpX3Blcl9rb3RhIDwtIGRhdGEuZnJhbWUoKQ0KfQ0KDQojIGQuIFJpbmdrYXNhbiBwZW5qdWFsYW4gcGVyIGJ1bGFuDQppZiAoYWxsKGMoIkJ1bGFuIiwgIlRvdGFsIikgJWluJSBuYW1lcyhkYXRhX2dhYnVuZ2FuKSkpIHsNCiAgcGVuanVhbGFuX3Blcl9idWxhbiA8LSBkYXRhX2dhYnVuZ2FuICU+JQ0KICAgIGdyb3VwX2J5KEJ1bGFuKSAlPiUNCiAgICBzdW1tYXJpc2UoYFRvdGFsIFBlbmp1YWxhbmAgPSBzdW0oVG90YWwsIG5hLnJtID0gVFJVRSkpDQp9IGVsc2Ugew0KICBwZW5qdWFsYW5fcGVyX2J1bGFuIDwtIGRhdGEuZnJhbWUoKQ0KfQ0KDQojIFRhbXBpbGthbiBzZWJhZ2FpIHRhYmVsIHN0YXRpcw0Ka2FibGUodG90YWxfcGVyX2thdGVnb3JpLCBjYXB0aW9uID0gIlRvdGFsIFBlbmp1YWxhbiBwZXIgS2F0ZWdvcmkiKQ0Ka2FibGUodHJhbnNha3NpX3Blcl9rb3RhLCBjYXB0aW9uID0gIkp1bWxhaCBUcmFuc2Frc2kgcGVyIEtvdGEiKQ0Ka2FibGUocGVuanVhbGFuX3Blcl9idWxhbiwgY2FwdGlvbiA9ICJSaW5na2FzYW4gUGVuanVhbGFuIHBlciBCdWxhbiIpDQpgYGANCg0KIyMgKipWaXN1YWxpc2FzaSoqDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQ0KbGlicmFyeShwbG90bHkpDQoNCiMgR3JhZmlrIEJhdGFuZyAtIFBlbmp1YWxhbiBwZXIgQnVsYW4gKHdhcm5hIG5hdnkpDQppZiAobnJvdyhwZW5qdWFsYW5fcGVyX2J1bGFuKSA+IDApIHsNCiAgZmlnMSA8LSBwbG90X2x5KA0KICAgIHBlbmp1YWxhbl9wZXJfYnVsYW4sDQogICAgeCA9IH5CdWxhbiwNCiAgICB5ID0gfmBUb3RhbCBQZW5qdWFsYW5gLA0KICAgIHR5cGUgPSAnYmFyJywNCiAgICBtYXJrZXIgPSBsaXN0KGNvbG9yID0gJ2JsdWUnKSANCiAgKSAlPiUNCiAgICBsYXlvdXQoDQogICAgICB0aXRsZSA9ICJUb3RhbCBQZW5qdWFsYW4gcGVyIEJ1bGFuIChHcmFmaWsgQmF0YW5nKSIsDQogICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiQnVsYW4iKSwNCiAgICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICJUb3RhbCBQZW5qdWFsYW4iKQ0KICAgICkNCiAgDQogIGZpZzENCn0NCg0KYGBgDQo=