Algoritma & Struktur Data

~ Tugas 6 ~


Kontak : \(\downarrow\)
Email
Instagram https://www.instagram.com/diasary_nm/
RPubs https://rpubs.com/diyasarya/

Impor/Ekspor CSV

Cara 1

Proses impor/ekspor data csv dengan menggunakan fungsi read.csv(membaca atau mengimpor data) dan write.csv(menyimpan atau mengekspor data). Sedangkan, untuk merapihkan data csv bisa menggunakan format pemisah koma sep = "," dan pemisah semikolon sep = ";". Namun, langkah pertama dalam proses impor/ekspor data csv kita pastikan working directory sudah benar dengan menggunakan fungsi getwd(), lalu kita atur working directory baru dengan menggunakan fungsi setwd().

print(getwd())
## [1] "C:/Users/diyas/OneDrive/Documents/Semester 1 Matana University/AlogaritmadanStrukturData/Data"
getwd()                                             # mengetahui dimana alamat working directory yang digunakan
## [1] "C:/Users/diyas/OneDrive/Documents/Semester 1 Matana University/AlogaritmadanStrukturData/Data"
# Proses Impor Data CSV  
setwd(getwd())                                      # set working directory
datacsv1 <-read.csv("Input/input1.csv",sep = ",")   # membaca data csv dengan format pemisah koma 
datacsv2 <-read.csv("Input/input2.csv",sep = ";")   # membaca data csv dengan format pemisah titik koma

# Proses Ekspor Data CSV
write.csv(datacsv1,"Output/output1.csv", row.names = FALSE)  # menyimpan data di file Output
write.csv(datacsv2,"Output/output2.csv", row.names = FALSE)  # menyimpan data di file Output

Cara 2

Proses impor/ekspor data yang mendeteksi data null, jika true (null) maka data akan di setting menggunakan setwd(). Menggunakan file.path untuk memudahkan membuat jalur file yang diingikan.

misal "C:\Users\Diyas\Documents"

jalur yang berbeda yaitu file.path("C:", "Users", "Diyas", "Documents", fsep = "\")

x <- getwd()
if(!is.null(x)) setwd(x)                                   # mengecek apakah data itu berupa null
# FALSE

# Proses Impor Data CSV 
datacsv1 <- read.csv(file.path(x, "Input", "input1.csv"))  # impor data dengan menggunakan jalur file.path
datacsv2 <- read.csv(file.path(x, "Input", "input2.csv"))  # impor data dengan menggunakan jalur file.path

# Proses Ekspor Data CSV
write.csv(datacsv1, file.path(x, "Output", "output1.csv"), row.names = FALSE)  # menyimpan data
write.csv(datacsv2, file.path(x, "Output", "output2.csv"), row.names = FALSE)  # menyimpan data

Cara 3

Menggunakan file.choose untuk memudahkan dalam proses impor/ekspor. Function file.choose hanya memilih file yang sudah tersimpan di komputer tanpa harus setting working directory.

datacsv01 <- read.csv(file.choose())
datacsv02 <- read.csv(file.choose())

datacsv01
datacsv02

Impor/Ekspor Excel

Untuk melakukan proses impor/ekspor data excel kita harus menginstall readxl(impor) dan writexl(ekspor) packages, serta menginstall pacman packages menggambungkan fungsi dasar secara bersamaan melakukan beberapa tindakan.

# install.packages(c("readxl", "writexl"))       # install `readxl & writexl` 
pacman::p_load(readxl, writexl)                  # load `readxl & writexl`

# Proses Impor Data Excel
dataexcel1 <- read_excel("Input/input3.xls")          # impor data xls (97-2003)
dataexcel2 <- read_excel("Input/input4.xlsx",sheet=1) # impor data xlsx (2003-up)

# Proses Ekspor Data Excel
write_xlsx(dataexcel1,"Output/output3.xls") 
write_xlsx(dataexcel2,"Output/output4.xlsx")

Impor/Ekspor TXT dan RDS

Format TXT dan RDS adalah ukuran file yang tidak besar maka untuk memudahkan dalam proses impor/ekspor lebih mudah dan efisien menggunakan format ini.

# Proses Impor Data TXT dan RDS
datatxt1 <- read.table("Input/input5.txt")       # impor data TXT (notepad)
datatxt2 <- source("Input/input6.Rdmpd")         # impor data TXT (Rdmpd)
datards1 <- readRDS("Input/input7.rds")          # impor data RDS (notepad)
datards2 <- readRDS("Input/input8.ascii")        # impor data RDS (ASCII)

# Proses Ekspor Data TXT dan RDS
write.table(datatxt1, "Output/output5.txt")
dump("datatxt2", "Output/output6.rdmpd")
saveRDS(datards1, "Output/output7.rds")
saveRDS(datards2, "Output/output8.ascii", ascii = TRUE)

Impor/Ekpor XML

XML(eXtensible Markup Language) adalah salah satu kumpulan format file dan data yang mirip dengan HTML. Proses impor/ekspor data XML dengan menggunakan XML(impor data XML dengan function xmlParse()) dan kulife(ekspor data XML) packages. Sedangkan, untuk mengubah data xml ke data frame bisa menggunakan Methods packages.

# install.packages(c("XML", "kulife", "methods"))     # instal XML, kulife, methods
library("XML")                                        # memanggil XML
library("kulife")                                     # memanggil kulife
library("methods")                                    # kondisional

# Proses Impor Data XML
dataxml <- xmlParse("Input/input9.xml")               # impor data XML

# konvert data
xml <- xmlToDataFrame(dataxml)                        # ubah dataxml ke data frame

# Proses Ekspor Data XML
write.xml(xml, "Output/output9.xml")                  # ekspor data XML

Impor/Ekspor JSON

JSON(JavaScript Object Notation) adalah suatu format ringkas pertukaran data komputer. Proses impor/ekspor data JSON dengan menggunakan jsonlite packages.

# install.packages("jsonlite")                       # install jsonlite
library("jsonlite")                                  # memanggil jsonlite

# Proses Impor Data JSON
datajson <- fromJSON("Input/input10.json")           # impor data JSON

# konvert data
json <- as.data.frame(datajson)                      # ubah datajson ke data frame

# Proses Ekspor Data JSON
write_json(datajson, "Output/output10.json")         # eskpor data JSON

Impor Data dari Web

Ada banyak data yang tersebar di berbagai website bertujuan untuk digunakan oleh banyak orang. Nah untuk mengekstrak data tersebut dengan program R. Berikut cara nya:

CSV

datawebcsv <- read.csv("http://dgrtwo.github.io/pages/lahman/Salaries.csv")

XLSX

library(rio)
install_formats()
## [1] TRUE
datawebxlsx <- rio::import("http://dgrtwo.github.io/pages/lahman/Salaries.csv")

Basis Data R

Basis Data adalah kumpulan informasi yang disimpan dalam komputer secara sistematik sehingga dapat diperiksa menggunakan suatu program komputer untuk memperoleh informasi dari database. Software yang digunakan untuk mengelola dan permintaan panggilan (query) basis data yang disebut sistem manajemen database (database management system, DBMS).

Menambang Data Web

Menambang Data dari Web adalah kegiatan mengumpulkan atau mengekstrak sebuah data dari suatu website yang kemudian akan disimpan dalam format tertentu. Kegiatan tersebut merupakan salah satu teknik yang dikenal dengan Web Scraping Data. Kegiatan ini akan menganalisis data sebelum diekstrak, data yang dianalisis biasanya menggunakan bahasa markup seperti HTML atau XHTML.

LS0tDQp0aXRsZTogIkFsZ29yaXRtYSAmIFN0cnVrdHVyIERhdGEiDQpzdWJ0aXRsZTogIn4gVHVnYXMgNiB+Ig0KYXV0aG9yOiAiRGl5YXMgQXJ5YSBOdWdyb2hvIg0KZGF0ZTogICJgciBmb3JtYXQoU3lzLkRhdGUoKSwgJyVCICVkLCAlWScpYCINCm91dHB1dDoNCiAgcm1kZm9ybWF0czo6cm9ib2Jvb2s6ICAgIyBodHRwczovL2dpdGh1Yixjb20vanViYS9ybWRmb3JtYXRzDQogICAgc2VsZl9jb250YWluZWQ6IHRydWUNCiAgICB0aHVtYm5haWxzOiB0cnVlDQogICAgbGlnaHRib3g6IHRydWUNCiAgICBnYWxsZXJ5OiB0cnVlDQogICAgbGliX2RpcjogbGlicw0KICAgIGRmX3ByaW50OiAicGFnZWQiDQogICAgY29kZV9mb2xkaW5nOiAic2hvdyINCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBjc3M6ICJzdHlsZS5jc3MiDQoNCi0tLQ0KDQpgYGB7ciBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGNsYXNzLHNvdXJjZSA9ICJub2NvcHkiLA0KICAgICAgICAgICAgICAgICAgICAgIGNsYXNzLG91dHB1dCA9ICJub2NvcHkiLA0KICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGLA0KICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGKQ0KbGlicmFyeShyZXRpY3VsYXRlKQ0KbGlicmFyeShSY3BwKQ0KdXNlX2NvbmRhZW52KCJweTM4IiwgcmVxdWlyZWQgPSBUUlVFKQ0KYGBgDQoNCjxicj4NCg0KPGltZyBzdHlsZT0iZmxvYXQ6IHJpZ2h0OyBtYXJnaW46IC01MHB4IDUwcHggMHB4IDUwcHg7IHdpZHRoOjMwJSIgc3JjPSJQcm9maWwucG5nIi8+DQoNCg0KfA0KOi0tLS0gfDotLS0tDQoqKktvbnRhayoqfCAqKjogJFxkb3duYXJyb3ckKioNCkVtYWlsIHwgZGl5YXNhcnlhbnVncm9ob0BnbWFpbC5jb20NCkluc3RhZ3JhbSB8IGh0dHBzOi8vd3d3Lmluc3RhZ3JhbS5jb20vZGlhc2FyeV9ubS8gDQpSUHVicyAgfCBodHRwczovL3JwdWJzLmNvbS9kaXlhc2FyeWEvIA0KDQoqKioNCg0KDQojIEltcG9yL0Vrc3BvciBDU1Ygey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KIyMgQ2FyYSAxDQoNClByb3NlcyBpbXBvci9la3Nwb3IgZGF0YSBjc3YgZGVuZ2FuIG1lbmdndW5ha2FuIGZ1bmdzaSBgYGByZWFkLmNzdmBgYChtZW1iYWNhIGF0YXUgbWVuZ2ltcG9yIGRhdGEpIGRhbiBgYGB3cml0ZS5jc3ZgYGAobWVueWltcGFuIGF0YXUgbWVuZ2Vrc3BvciBkYXRhKS4gU2VkYW5na2FuLCB1bnR1ayBtZXJhcGloa2FuIGRhdGEgY3N2IGJpc2EgbWVuZ2d1bmFrYW4gZm9ybWF0IHBlbWlzYWgga29tYSBgYGBzZXAgPSAiLCJgYGAgZGFuIHBlbWlzYWggc2VtaWtvbG9uIGBgYHNlcCA9ICI7ImBgYC4gTmFtdW4sIGxhbmdrYWggcGVydGFtYSBkYWxhbSBwcm9zZXMgaW1wb3IvZWtzcG9yIGRhdGEgY3N2IGtpdGEgcGFzdGlrYW4gd29ya2luZyBkaXJlY3Rvcnkgc3VkYWggYmVuYXIgZGVuZ2FuIG1lbmdndW5ha2FuIGZ1bmdzaSBgYGBnZXR3ZCgpYGBgLCBsYWx1IGtpdGEgYXR1ciB3b3JraW5nIGRpcmVjdG9yeSBiYXJ1IGRlbmdhbiBtZW5nZ3VuYWthbiBmdW5nc2kgYGBgc2V0d2QoKWBgYC4NCg0KYGBge3J9DQpwcmludChnZXR3ZCgpKQ0KZ2V0d2QoKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbWVuZ2V0YWh1aSBkaW1hbmEgYWxhbWF0IHdvcmtpbmcgZGlyZWN0b3J5IHlhbmcgZGlndW5ha2FuDQoNCiMgUHJvc2VzIEltcG9yIERhdGEgQ1NWICANCnNldHdkKGdldHdkKCkpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHNldCB3b3JraW5nIGRpcmVjdG9yeQ0KZGF0YWNzdjEgPC1yZWFkLmNzdigiSW5wdXQvaW5wdXQxLmNzdiIsc2VwID0gIiwiKSAgICMgbWVtYmFjYSBkYXRhIGNzdiBkZW5nYW4gZm9ybWF0IHBlbWlzYWgga29tYSANCmRhdGFjc3YyIDwtcmVhZC5jc3YoIklucHV0L2lucHV0Mi5jc3YiLHNlcCA9ICI7IikgICAjIG1lbWJhY2EgZGF0YSBjc3YgZGVuZ2FuIGZvcm1hdCBwZW1pc2FoIHRpdGlrIGtvbWENCg0KIyBQcm9zZXMgRWtzcG9yIERhdGEgQ1NWDQp3cml0ZS5jc3YoZGF0YWNzdjEsIk91dHB1dC9vdXRwdXQxLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKSAgIyBtZW55aW1wYW4gZGF0YSBkaSBmaWxlIE91dHB1dA0Kd3JpdGUuY3N2KGRhdGFjc3YyLCJPdXRwdXQvb3V0cHV0Mi5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkgICMgbWVueWltcGFuIGRhdGEgZGkgZmlsZSBPdXRwdXQNCmBgYA0KDQojIyBDYXJhIDINCg0KUHJvc2VzIGltcG9yL2Vrc3BvciBkYXRhIHlhbmcgbWVuZGV0ZWtzaSBkYXRhIG51bGwsIGppa2EgdHJ1ZSAobnVsbCkgbWFrYSBkYXRhIGFrYW4gZGkgc2V0dGluZyBtZW5nZ3VuYWthbiBgYGBzZXR3ZCgpYGBgLiBNZW5nZ3VuYWthbiBgYGBmaWxlLnBhdGhgYGAgdW50dWsgbWVtdWRhaGthbiBtZW1idWF0IGphbHVyIGZpbGUgeWFuZyBkaWluZ2lrYW4uDQoNCm1pc2FsIGBgYCJDOlxVc2Vyc1xEaXlhc1xEb2N1bWVudHMiYGBgDQoNCmphbHVyIHlhbmcgYmVyYmVkYSB5YWl0dSBgYGBmaWxlLnBhdGgoIkM6IiwgIlVzZXJzIiwgIkRpeWFzIiwgIkRvY3VtZW50cyIsIGZzZXAgPSAiXCIpYGBgDQoNCmBgYHtyfQ0KeCA8LSBnZXR3ZCgpDQppZighaXMubnVsbCh4KSkgc2V0d2QoeCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbWVuZ2VjZWsgYXBha2FoIGRhdGEgaXR1IGJlcnVwYSBudWxsDQojIEZBTFNFDQoNCiMgUHJvc2VzIEltcG9yIERhdGEgQ1NWIA0KZGF0YWNzdjEgPC0gcmVhZC5jc3YoZmlsZS5wYXRoKHgsICJJbnB1dCIsICJpbnB1dDEuY3N2IikpICAjIGltcG9yIGRhdGEgZGVuZ2FuIG1lbmdndW5ha2FuIGphbHVyIGZpbGUucGF0aA0KZGF0YWNzdjIgPC0gcmVhZC5jc3YoZmlsZS5wYXRoKHgsICJJbnB1dCIsICJpbnB1dDIuY3N2IikpICAjIGltcG9yIGRhdGEgZGVuZ2FuIG1lbmdndW5ha2FuIGphbHVyIGZpbGUucGF0aA0KDQojIFByb3NlcyBFa3Nwb3IgRGF0YSBDU1YNCndyaXRlLmNzdihkYXRhY3N2MSwgZmlsZS5wYXRoKHgsICJPdXRwdXQiLCAib3V0cHV0MS5jc3YiKSwgcm93Lm5hbWVzID0gRkFMU0UpICAjIG1lbnlpbXBhbiBkYXRhDQp3cml0ZS5jc3YoZGF0YWNzdjIsIGZpbGUucGF0aCh4LCAiT3V0cHV0IiwgIm91dHB1dDIuY3N2IiksIHJvdy5uYW1lcyA9IEZBTFNFKSAgIyBtZW55aW1wYW4gZGF0YQ0KYGBgDQoNCg0KIyMgQ2FyYSAzDQoNCk1lbmdndW5ha2FuIGBgYGZpbGUuY2hvb3NlYGBgIHVudHVrIG1lbXVkYWhrYW4gZGFsYW0gcHJvc2VzIGltcG9yL2Vrc3Bvci4gRnVuY3Rpb24gYGBgZmlsZS5jaG9vc2VgYGAgaGFueWEgbWVtaWxpaCBmaWxlIHlhbmcgc3VkYWggdGVyc2ltcGFuIGRpIGtvbXB1dGVyIHRhbnBhIGhhcnVzIHNldHRpbmcgd29ya2luZyBkaXJlY3RvcnkuDQoNCmBgYHtyfQ0KZGF0YWNzdjAxIDwtIHJlYWQuY3N2KGZpbGUuY2hvb3NlKCkpDQpkYXRhY3N2MDIgPC0gcmVhZC5jc3YoZmlsZS5jaG9vc2UoKSkNCg0KZGF0YWNzdjAxDQpkYXRhY3N2MDINCmBgYA0KDQoNCg0KDQojIEltcG9yL0Vrc3BvciBFeGNlbCANCg0KVW50dWsgbWVsYWt1a2FuIHByb3NlcyBpbXBvci9la3Nwb3IgZGF0YSBleGNlbCBraXRhIGhhcnVzIG1lbmdpbnN0YWxsIGBgYHJlYWR4bGBgYChpbXBvcikgZGFuIGBgYHdyaXRleGxgYGAoZWtzcG9yKSBwYWNrYWdlcywgc2VydGEgbWVuZ2luc3RhbGwgYGBgcGFjbWFuYGBgIHBhY2thZ2VzIG1lbmdnYW1idW5na2FuIGZ1bmdzaSBkYXNhciBzZWNhcmEgYmVyc2FtYWFuIG1lbGFrdWthbiBiZWJlcmFwYSB0aW5kYWthbi4NCg0KYGBge3J9DQojIGluc3RhbGwucGFja2FnZXMoYygicmVhZHhsIiwgIndyaXRleGwiKSkgICAgICAgIyBpbnN0YWxsIGByZWFkeGwgJiB3cml0ZXhsYCANCnBhY21hbjo6cF9sb2FkKHJlYWR4bCwgd3JpdGV4bCkgICAgICAgICAgICAgICAgICAjIGxvYWQgYHJlYWR4bCAmIHdyaXRleGxgDQoNCiMgUHJvc2VzIEltcG9yIERhdGEgRXhjZWwNCmRhdGFleGNlbDEgPC0gcmVhZF9leGNlbCgiSW5wdXQvaW5wdXQzLnhscyIpICAgICAgICAgICMgaW1wb3IgZGF0YSB4bHMgKDk3LTIwMDMpDQpkYXRhZXhjZWwyIDwtIHJlYWRfZXhjZWwoIklucHV0L2lucHV0NC54bHN4IixzaGVldD0xKSAjIGltcG9yIGRhdGEgeGxzeCAoMjAwMy11cCkNCg0KIyBQcm9zZXMgRWtzcG9yIERhdGEgRXhjZWwNCndyaXRlX3hsc3goZGF0YWV4Y2VsMSwiT3V0cHV0L291dHB1dDMueGxzIikgDQp3cml0ZV94bHN4KGRhdGFleGNlbDIsIk91dHB1dC9vdXRwdXQ0Lnhsc3giKQ0KYGBgDQoNCiMgSW1wb3IvRWtzcG9yIFRYVCBkYW4gUkRTDQoNCkZvcm1hdCBUWFQgZGFuIFJEUyBhZGFsYWggdWt1cmFuIGZpbGUgeWFuZyB0aWRhayBiZXNhciBtYWthIHVudHVrIG1lbXVkYWhrYW4gZGFsYW0gcHJvc2VzIGltcG9yL2Vrc3BvciBsZWJpaCBtdWRhaCBkYW4gZWZpc2llbiBtZW5nZ3VuYWthbiBmb3JtYXQgaW5pLg0KDQpgYGB7cn0NCiMgUHJvc2VzIEltcG9yIERhdGEgVFhUIGRhbiBSRFMNCmRhdGF0eHQxIDwtIHJlYWQudGFibGUoIklucHV0L2lucHV0NS50eHQiKSAgICAgICAjIGltcG9yIGRhdGEgVFhUIChub3RlcGFkKQ0KZGF0YXR4dDIgPC0gc291cmNlKCJJbnB1dC9pbnB1dDYuUmRtcGQiKSAgICAgICAgICMgaW1wb3IgZGF0YSBUWFQgKFJkbXBkKQ0KZGF0YXJkczEgPC0gcmVhZFJEUygiSW5wdXQvaW5wdXQ3LnJkcyIpICAgICAgICAgICMgaW1wb3IgZGF0YSBSRFMgKG5vdGVwYWQpDQpkYXRhcmRzMiA8LSByZWFkUkRTKCJJbnB1dC9pbnB1dDguYXNjaWkiKSAgICAgICAgIyBpbXBvciBkYXRhIFJEUyAoQVNDSUkpDQoNCiMgUHJvc2VzIEVrc3BvciBEYXRhIFRYVCBkYW4gUkRTDQp3cml0ZS50YWJsZShkYXRhdHh0MSwgIk91dHB1dC9vdXRwdXQ1LnR4dCIpDQpkdW1wKCJkYXRhdHh0MiIsICJPdXRwdXQvb3V0cHV0Ni5yZG1wZCIpDQpzYXZlUkRTKGRhdGFyZHMxLCAiT3V0cHV0L291dHB1dDcucmRzIikNCnNhdmVSRFMoZGF0YXJkczIsICJPdXRwdXQvb3V0cHV0OC5hc2NpaSIsIGFzY2lpID0gVFJVRSkNCmBgYA0KDQojIEltcG9yL0VrcG9yIFhNTA0KDQpYTUwoZVh0ZW5zaWJsZSBNYXJrdXAgTGFuZ3VhZ2UpIGFkYWxhaCBzYWxhaCBzYXR1IGt1bXB1bGFuIGZvcm1hdCBmaWxlIGRhbiBkYXRhIHlhbmcgbWlyaXAgZGVuZ2FuIEhUTUwuIFByb3NlcyBpbXBvci9la3Nwb3IgZGF0YSBYTUwgZGVuZ2FuIG1lbmdndW5ha2FuIGBgYFhNTGBgYChpbXBvciBkYXRhIFhNTCBkZW5nYW4gZnVuY3Rpb24gYGBgeG1sUGFyc2UoKWBgYCkgZGFuIGBgYGt1bGlmZWBgYChla3Nwb3IgZGF0YSBYTUwpIHBhY2thZ2VzLiBTZWRhbmdrYW4sIHVudHVrIG1lbmd1YmFoIGRhdGEgeG1sIGtlIGRhdGEgZnJhbWUgYmlzYSBtZW5nZ3VuYWthbiBgYGBNZXRob2RzYGBgIHBhY2thZ2VzLg0KDQpgYGB7cn0NCiMgaW5zdGFsbC5wYWNrYWdlcyhjKCJYTUwiLCAia3VsaWZlIiwgIm1ldGhvZHMiKSkgICAgICMgaW5zdGFsIFhNTCwga3VsaWZlLCBtZXRob2RzDQpsaWJyYXJ5KCJYTUwiKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIG1lbWFuZ2dpbCBYTUwNCmxpYnJhcnkoImt1bGlmZSIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbWVtYW5nZ2lsIGt1bGlmZQ0KbGlicmFyeSgibWV0aG9kcyIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBrb25kaXNpb25hbA0KDQojIFByb3NlcyBJbXBvciBEYXRhIFhNTA0KZGF0YXhtbCA8LSB4bWxQYXJzZSgiSW5wdXQvaW5wdXQ5LnhtbCIpICAgICAgICAgICAgICAgIyBpbXBvciBkYXRhIFhNTA0KDQojIGtvbnZlcnQgZGF0YQ0KeG1sIDwtIHhtbFRvRGF0YUZyYW1lKGRhdGF4bWwpICAgICAgICAgICAgICAgICAgICAgICAgIyB1YmFoIGRhdGF4bWwga2UgZGF0YSBmcmFtZQ0KDQojIFByb3NlcyBFa3Nwb3IgRGF0YSBYTUwNCndyaXRlLnhtbCh4bWwsICJPdXRwdXQvb3V0cHV0OS54bWwiKSAgICAgICAgICAgICAgICAgICMgZWtzcG9yIGRhdGEgWE1MDQpgYGANCg0KIyBJbXBvci9Fa3Nwb3IgSlNPTg0KDQoNCkpTT04oSmF2YVNjcmlwdCBPYmplY3QgTm90YXRpb24pIGFkYWxhaCBzdWF0dSBmb3JtYXQgcmluZ2thcyBwZXJ0dWthcmFuIGRhdGEga29tcHV0ZXIuIFByb3NlcyBpbXBvci9la3Nwb3IgZGF0YSBKU09OIGRlbmdhbiBtZW5nZ3VuYWthbiBgYGBqc29ubGl0ZWBgYCBwYWNrYWdlcy4gDQoNCmBgYHtyfQ0KIyBpbnN0YWxsLnBhY2thZ2VzKCJqc29ubGl0ZSIpICAgICAgICAgICAgICAgICAgICAgICAjIGluc3RhbGwganNvbmxpdGUNCmxpYnJhcnkoImpzb25saXRlIikgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBtZW1hbmdnaWwganNvbmxpdGUNCg0KIyBQcm9zZXMgSW1wb3IgRGF0YSBKU09ODQpkYXRhanNvbiA8LSBmcm9tSlNPTigiSW5wdXQvaW5wdXQxMC5qc29uIikgICAgICAgICAgICMgaW1wb3IgZGF0YSBKU09ODQoNCiMga29udmVydCBkYXRhDQpqc29uIDwtIGFzLmRhdGEuZnJhbWUoZGF0YWpzb24pICAgICAgICAgICAgICAgICAgICAgICMgdWJhaCBkYXRhanNvbiBrZSBkYXRhIGZyYW1lDQoNCiMgUHJvc2VzIEVrc3BvciBEYXRhIEpTT04NCndyaXRlX2pzb24oZGF0YWpzb24sICJPdXRwdXQvb3V0cHV0MTAuanNvbiIpICAgICAgICAgIyBlc2twb3IgZGF0YSBKU09ODQpgYGANCg0KIyBJbXBvciBEYXRhIGRhcmkgV2ViIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCkFkYSBiYW55YWsgZGF0YSB5YW5nIHRlcnNlYmFyIGRpIGJlcmJhZ2FpIHdlYnNpdGUgYmVydHVqdWFuIHVudHVrIGRpZ3VuYWthbiBvbGVoIGJhbnlhayBvcmFuZy4gTmFoIHVudHVrIG1lbmdla3N0cmFrIGRhdGEgdGVyc2VidXQgZGVuZ2FuIHByb2dyYW0gUi4gQmVyaWt1dCBjYXJhIG55YToNCg0KIyMgQ1NWDQoNCmBgYHtyfQ0KZGF0YXdlYmNzdiA8LSByZWFkLmNzdigiaHR0cDovL2RncnR3by5naXRodWIuaW8vcGFnZXMvbGFobWFuL1NhbGFyaWVzLmNzdiIpDQpgYGANCg0KIyMgWExTWA0KDQpgYGB7cn0NCmxpYnJhcnkocmlvKQ0KaW5zdGFsbF9mb3JtYXRzKCkNCg0KZGF0YXdlYnhsc3ggPC0gcmlvOjppbXBvcnQoImh0dHA6Ly9kZ3J0d28uZ2l0aHViLmlvL3BhZ2VzL2xhaG1hbi9TYWxhcmllcy5jc3YiKQ0KYGBgDQoNCiMgQmFzaXMgRGF0YSBSDQoNCkJhc2lzIERhdGEgYWRhbGFoIGt1bXB1bGFuIGluZm9ybWFzaSB5YW5nIGRpc2ltcGFuIGRhbGFtIGtvbXB1dGVyIHNlY2FyYSBzaXN0ZW1hdGlrIHNlaGluZ2dhIGRhcGF0IGRpcGVyaWtzYSBtZW5nZ3VuYWthbiBzdWF0dSBwcm9ncmFtIGtvbXB1dGVyIHVudHVrIG1lbXBlcm9sZWggaW5mb3JtYXNpIGRhcmkgZGF0YWJhc2UuIFNvZnR3YXJlIHlhbmcgZGlndW5ha2FuIHVudHVrIG1lbmdlbG9sYSBkYW4gcGVybWludGFhbiBwYW5nZ2lsYW4gKHF1ZXJ5KSBiYXNpcyBkYXRhIHlhbmcgZGlzZWJ1dCBzaXN0ZW0gbWFuYWplbWVuIGRhdGFiYXNlIChkYXRhYmFzZSBtYW5hZ2VtZW50IHN5c3RlbSwgREJNUykuDQoNCiMgTWVuYW1iYW5nIERhdGEgV2ViDQoNCk1lbmFtYmFuZyBEYXRhIGRhcmkgV2ViIGFkYWxhaCBrZWdpYXRhbiBtZW5ndW1wdWxrYW4gYXRhdSBtZW5nZWtzdHJhayBzZWJ1YWggZGF0YSBkYXJpIHN1YXR1IHdlYnNpdGUgeWFuZyBrZW11ZGlhbiBha2FuIGRpc2ltcGFuIGRhbGFtIGZvcm1hdCB0ZXJ0ZW50dS4gS2VnaWF0YW4gdGVyc2VidXQgbWVydXBha2FuIHNhbGFoIHNhdHUgdGVrbmlrIHlhbmcgZGlrZW5hbCBkZW5nYW4gV2ViIFNjcmFwaW5nIERhdGEuIEtlZ2lhdGFuIGluaSBha2FuIG1lbmdhbmFsaXNpcyBkYXRhIHNlYmVsdW0gZGlla3N0cmFrLCBkYXRhIHlhbmcgZGlhbmFsaXNpcyBiaWFzYW55YSBtZW5nZ3VuYWthbiBiYWhhc2EgbWFya3VwIHNlcGVydGkgSFRNTCBhdGF1IFhIVE1MLiANCg0KDQoNCg0KDQoNCg0KDQo=