
Studi Kasus 1 (Simulasi Kesalahan Sampling di
Lapangan)
Andikan Anda adalah bagian dari tim riset lapangan yang diminta untuk
melakukan survei tingkat penggunaan aplikasi transportasi online di
3 kota menengah di Sumatera. Target sampel total adalah
600 responden, masing-masing 200 per kota. Tetapi,
setelah 2 minggu melakukan survei anda menemukan:
- Di Kota A, tim berhasil mendapatkan 250 responden.
- Di Kota B, hanya 120 responden yang dapat diwawancarai.
- Di Kota C, 180 responden.
Instruksi:
Jelaskan dua jenis kesalahan sampling yang
terjadi berdasarkan situasi ini.
Jika Anda harus menyesuaikan bobot untuk mengembalikan
representasi proporsional, bagaimana Anda akan menghitungnya?
Kesalahan Sampling
Berdasarkan situasi yang diberikan, berikut adalah dua jenis
kesalahan sampling yang terjadi:
1. Kesalahan Representasi (Representation
Error)
Jumlah responden yang terkumpul tidak sesuai dengan target awal per
kota, yaitu 200 responden per kota. Situasi ini menyebabkan:
- Kota A memiliki 250 responden, yang berarti kelebihan 50 responden
(+25% dari target).
- Kota B hanya memiliki 120 responden, yang berarti kekurangan 80
responden (-40% dari target).
- Kota C memiliki 180 responden, yang berarti kekurangan 20 responden
(-10% dari target).
Karena distribusi jumlah responden tidak seimbang, hasil survei
menjadi tidak mewakili proporsi yang diinginkan. Kota A yang kelebihan
responden akan memiliki pengaruh yang lebih besar terhadap hasil
survei.
2. Kesalahan Sampling Non-Respons (Non-Response
Error)
Kesalahan ini terjadi karena di Kota B hanya 120 orang yang berhasil
diwawancarai, jauh di bawah target 200. Kemungkinan ada faktor-faktor
tertentu yang membuat responden di Kota B tidak mau atau tidak bisa
berpartisipasi, seperti kurangnya waktu, ketidakpercayaan terhadap
survei, atau alasan lain. Jika karakteristik mereka berbeda dari yang
berpartisipasi, hasil survei akan bias.
Menghitung Bobot Responden
Untuk mengembalikan representasi proporsional ke target awal (200
responden per kota dari total 600), bobot untuk masing-masing kota
dihitung sebagai berikut:
- Proporsi Target:
- Kota A: \(\frac{200}{600} =
0.3333\)
- Kota B: \(\frac{200}{600} =
0.3333\)
- Kota C: \(\frac{200}{600} =
0.3333\)
- Proporsi Aktual:
- Kota A: \(\frac{250}{550} \approx
0.4545\)
- Kota B: \(\frac{120}{550} \approx
0.2182\)
- Kota C: \(\frac{180}{550} \approx
0.3273\)
- Bobot:
- Kota A: \(\frac{0.3333}{0.4545} \approx
0.733\)
- Kota B: \(\frac{0.3333}{0.2182} \approx
1.528\)
- Kota C: \(\frac{0.3333}{0.3273} \approx
1.018\)
Implementasi Perhitungan dengan R
Berikut adalah implementasi kode untuk menghitung bobot menggunakan
R:
## Warning: package 'knitr' was built under R version 4.4.2
# Data jumlah target dan aktual per kota
kota <- c("Kota A", "Kota B", "Kota C")
target <- c(200, 200, 200)
aktual <- c(250, 120, 180)
# Total
total_target <- sum(target)
total_aktual <- sum(aktual)
# Hitung proporsi target dan aktual
proporsi_target <- target / total_target
proporsi_aktual <- aktual / total_aktual
# Hitung bobot
bobot <- round(proporsi_target / proporsi_aktual, 3)
# Buat data frame hasil
hasil <- data.frame(
Kota = kota,
Target = target,
Aktual = aktual,
`Proporsi Target` = round(proporsi_target, 4),
`Proporsi Aktual` = round(proporsi_aktual, 4),
`Bobot Penyesuaian` = bobot
)
# Tampilkan hasil
kable(hasil, caption = "Tabel Penyesuaian Bobot Responden per Kota")
Tabel Penyesuaian Bobot Responden per Kota
Kota A |
200 |
250 |
0.3333 |
0.4545 |
0.733 |
Kota B |
200 |
120 |
0.3333 |
0.2182 |
1.528 |
Kota C |
200 |
180 |
0.3333 |
0.3273 |
1.019 |
Studi Kasus 2 (Mendesain Survei dengan Pembobotan Waktu
Puncak)
Buatlah desain rancangan survei tentang persepsi kenyamanan
pengguna ojek online saat jam sibuk (07.00–09.00 dan
17.00–19.00).
Instruksi:
Desain pendekatan sampling yang memungkinkan Anda
menangkap persepsi pengguna secara representatif pada jam
sibuk, tanpa melakukan survei sepanjang hari.
Sertakan rancangan waktu, metode pemilihan responden, dan
justifikasi pemilihan unit sampling.
Jelaskan bagaimana Anda akan menyesuaikan hasil survei jika 60%
responden berasal dari pagi hari, sementara 40% dari sore hari,
sedangkan data historis menunjukkan pengguna ojek online saat sore hari
dua kali lebih banyak dibanding pagi.
Desain Pendekatan Sampling
Untuk memastikan survei yang representatif, pendekatan yang digunakan
adalah stratified time sampling, dengan pembagian dua
strata waktu:
- Pagi (07.00–09.00): Fokus pada jam berangkat
kerja/sekolah.
- Sore (17.00–19.00): Fokus pada jam pulang
kerja/sekolah.
Dengan pendekatan ini, survei hanya dilakukan pada jam sibuk yang
relevan, sehingga efisien dan tetap representatif tanpa harus
mengumpulkan data sepanjang hari. Masing-masing strata waktu
merepresentasikan pola penggunaan ojek online yang berbeda.
Rancangan Waktu, Metode, dan Justifikasi
Rancangan Waktu: - Survei dilaksanakan pada hari
kerja (Senin-Jumat) selama dua waktu sibuk: pagi (07.00–09.00) dan sore
(17.00–19.00).
Metode Pemilihan Responden: - Systematic
intercept sampling: Responden dipilih secara sistematis pada
lokasi-lokasi strategis, seperti stasiun, terminal, atau kawasan
perkantoran. - Contoh: Setiap 10 menit, satu pengguna ojek online yang
baru turun diwawancarai.
Justifikasi Pemilihan Unit Sampling: - Unit sampling
adalah pengguna aktif ojek online pada jam sibuk.
Mereka dipilih karena berada di lokasi dan waktu yang relevan untuk
menggambarkan persepsi kenyamanan secara langsung.
Penyesuaian Hasil Survei Berdasarkan Data Historis
Dalam survei ini: - 60% responden berasal dari pagi hari
(07.00–09.00). - 40% responden berasal dari sore hari
(17.00–19.00).
Namun, data historis menunjukkan bahwa: - Pengguna ojek online di
sore hari dua kali lebih banyak dibandingkan pagi hari.
Proporsi Aktual Berdasarkan Data Historis:
- Pagi: 1 bagian (1/3 atau 0.33)
- Sore: 2 bagian (2/3 atau 0.67)
Penyesuaian Bobot:
Untuk menghindari bias akibat ketidakseimbangan jumlah responden,
dilakukan penyesuaian bobot berdasarkan proporsi aktual dan proporsi
survei.
Rumus Bobot: \[
\text{Bobot waktu} = \frac{\text{Proporsi sebenarnya}}{\text{Proporsi
hasil survei}}
\]
Perhitungan Bobot: - Bobot pagi:
\(0.33 / 0.60 \approx 0.56\) -
Bobot sore: \(0.67 / 0.40
\approx 1.67\)
library(knitr)
# Data pembobotan
pembobotan_data <- data.frame(
Waktu = c("Pagi", "Sore"),
Proporsi_Survei = c(0.60, 0.40),
Proporsi_Aktual = c(1/3, 2/3),
Bobot = c((1/3)/0.60, (2/3)/0.40)
)
# Tabel pembobotan
kable(pembobotan_data, caption = "Pembobotan Berdasarkan Proporsi Historis Pengguna")
Pembobotan Berdasarkan Proporsi Historis Pengguna
Pagi |
0.6 |
0.3333333 |
0.5555556 |
Sore |
0.4 |
0.6666667 |
1.6666667 |
Simulasi Data dan Analisis
Data Simulasi
Kita buat data simulasi untuk 100 responden:
set.seed(123) # For reproducibility
# Membuat data untuk 100 responden
data <- data.frame(
respondent_id = 1:100,
time_period = c(rep("Pagi", 60), rep("Sore", 40)),
satisfaction_score = c(rnorm(60, mean = 7, sd = 1.5), rnorm(40, mean = 8, sd = 1.2))
)
head(data)
Terapkan Bobot
Tambahkan bobot ke data berdasarkan waktu:
## Warning: package 'dplyr' was built under R version 4.4.3
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
data <- data %>%
left_join(pembobotan_data %>% select(Waktu, Bobot), by = c("time_period" = "Waktu")) %>%
mutate(weighted_score = satisfaction_score * Bobot)
head(data)
Perhitungan Rata-rata Berbobot
Hitung rata-rata berbobot:
weighted_mean <- sum(data$weighted_score) / sum(data$Bobot)
weighted_mean
## [1] 7.801546
Studi Kasus 3 (Evaluasi Kepuasan Mahasiswa terhadap Layanan
Akademik)
Anda ditugaskan oleh biro akademik kampus untuk merancang instrumen
survei yang bertujuan mengevaluasi kepuasan mahasiswa terhadap layanan
akademik, yang mencakup layanan seperti: KRS online, bimbingan akademik,
pelayanan administrasi, akses informasi akademik, dan bantuan
penyelesaian studi.
Tim peneliti meminta Anda untuk:
Merancang 25 pertanyaan utama dengan variasi skala dan
bentuk pertanyaan.
Merancang sistem validasi instrumen.
Menentukan metode distribusi dan pengujian kuesioner secara
statistik.
Menyiapkan simulasi strategi pengambilan sampel dan pengolahan
data awal.
Output Laporan yang diharapkan dalam bentuk naratif, mencakup:
• Desain pertanyaan
• Skema validasi
• Strategi distribusi dan sampling
• Simulasi data dan analisis awal
1. Desain Pertanyaan
Berikut adalah desain 25 pertanyaan yang terbagi dalam lima aspek
layanan akademik:
- KRS Online
- Bimbingan Akademik
- Pelayanan Administrasi
- Akses Informasi Akademik
- Bantuan Penyelesaian Studi
Link Pertanyaan Google Form:
Google
Form
2. Skema validasi
2.1 Validasi Isi (Content Validity)
Proses validasi isi dilakukan dengan melibatkan pakar atau dosen di
bidang pendidikan untuk menilai relevansi setiap pertanyaan terhadap
aspek yang dievaluasi. Penilaian dilakukan dengan tiga kategori:
Sangat relevan
Cukup relevan
Tidak relevan
Hasil penilaian dihitung menggunakan Content Validity Ratio (CVR).
Jika CVR dari suatu pertanyaan berada di atas ambang batas yang
ditentukan, maka pertanyaan tersebut dianggap valid secara isi.
Sebaliknya, jika CVR rendah, pertanyaan tersebut perlu direvisi atau
dihapus.
2.2 Validasi Statistik
Setelah validasi isi selesai, dilakukan uji coba kuesioner kepada 30
mahasiswa sebagai tahap awal pengujian statistik.
2.2.1 Uji Validitas Konstruk (Construct Validity)
Uji ini bertujuan untuk memastikan bahwa setiap pertanyaan dalam
kuesioner benar-benar mengukur aspek yang sesuai. Pendekatan yang
digunakan:
Korelasi Item-Total: Menghitung korelasi antara setiap item
dengan total skor dari aspek terkait. Korelasi > 0.3 menunjukkan
validitas yang baik.
Analisis Faktor: Dilakukan eksplorasi menggunakan metode Analisis
Faktor Eksploratori (EFA) untuk memastikan bahwa kelompok pertanyaan
membentuk faktor yang diharapkan.
2.2.2 Uji Reliabilitas
Reliabilitas instrumen diuji menggunakan Cronbach’s Alpha untuk
mengevaluasi konsistensi internal antaritem. Kriteria:
3. Strategi Distribusi dan Sampling
3.1 Strategi Distribusi
Kuesioner akan disebarkan secara daring menggunakan platform Google
Forms. Langkah distribusi meliputi:
Email Kampus: Kuesioner dikirim melalui sistem email resmi kepada
seluruh mahasiswa aktif.
Grup Media Sosial: Tautan kuesioner disebarkan melalui grup
WhatsApp, Telegram, dan platform komunikasi lainnya.
LMS Kampus: Kuesioner juga akan tersedia di Learning Management
System (LMS) kampus untuk meningkatkan aksesibilitas.
Pengingat akan dikirimkan secara berkala untuk meningkatkan tingkat
respons. Selain itu, insentif berupa sertifikat partisipasi atau hadiah
kecil dapat diberikan kepada responden sebagai bentuk apresiasi.
3.2 Strategi Sampling
3.2.1 Populasi dan Teknik Sampling
Populasi target adalah seluruh mahasiswa aktif di kampus. Metode
sampling yang digunakan adalah Stratified Random Sampling dengan strata
berdasarkan:
Stratifikasi ini bertujuan untuk memastikan bahwa setiap kelompok
terwakili dalam survei.
3.2.2 Ukuran Sampel
Mengacu pada populasi mahasiswa aktif sebanyak 10.000 orang,
diperlukan minimal 384 responden untuk tingkat kepercayaan 95% dan
margin of error 5%. Untuk tahap uji coba, 30 responden awal akan
digunakan untuk memvalidasi instrumen secara statistik.
3.2.3 Alokasi Sampel
Responden dari setiap strata akan diambil secara proporsional.
Misalnya, jika Program Studi A memiliki 20% populasi, maka 20% dari
total sampel akan diambil dari program studi tersebut.
3.2.4 Peningkatan Respons
Strategi untuk meningkatkan tingkat respons meliputi:
Mengirimkan pengingat secara berkala kepada mahasiswa yang belum
mengisi kuesioner.
Melibatkan organisasi mahasiswa dan dosen untuk mempromosikan
survei.
Memberikan insentif kepada responden yang
berpartisipasi.
4. Simulasi Data dan analisis awal
# Simulasi Data Survei Kepuasan Mahasiswa
set.seed(123)
# Membuat data untuk 5 kategori layanan
data_krs <- data.frame(
KRS_akses = sample(1:5, 100, replace = TRUE),
KRS_masalah = sample(1:5, 100, replace = TRUE),
KRS_efisiensi = sample(c("Ya", "Tidak"), 100, replace = TRUE)
)
# Gabungkan data untuk 5 kategori lainnya
data_bimbingan <- data.frame(
Bimbingan_frekuensi = sample(1:10, 100, replace = TRUE),
Bimbingan_kualitas = sample(1:5, 100, replace = TRUE)
)
data_administrasi <- data.frame(
Administrasi_respons = sample(1:5, 100, replace = TRUE),
Administrasi_kemudahan = sample(c("Ya", "Tidak"), 100, replace = TRUE)
)
data_akses <- data.frame(
Akses_frekuensi = sample(1:10, 100, replace = TRUE),
Akses_informatif = sample(1:5, 100, replace = TRUE)
)
data_bantuan <- data.frame(
Bantuan_studi = sample(1:5, 100, replace = TRUE),
Bantuan_tersedia = sample(c("Ya", "Tidak"), 100, replace = TRUE)
)
# Gabungkan semua data menjadi satu data frame
data_survei <- cbind(data_krs, data_bimbingan, data_administrasi, data_akses, data_bantuan)
head(data_survei)
4.1 Deskripsi Statistik Awal
Kita akan menghitung beberapa deskripsi statistik untuk melihat
distribusi data dari setiap kategori.
library(dplyr)
summary_statistics <- data_survei %>%
summarise_all(list(mean = ~mean(as.numeric(as.character(.)), na.rm = TRUE),
sd = ~sd(as.numeric(as.character(.)), na.rm = TRUE),
median = ~median(as.numeric(as.character(.)), na.rm = TRUE)))
## Warning: There were 9 warnings in `summarise()`.
## The first warning was:
## ℹ In argument: `KRS_efisiensi_mean = (structure(function (..., .x = ..1, .y =
## ..2, . = ..1) ...`.
## Caused by warning in `mean()`:
## ! NAs introduced by coercion
## ℹ Run `dplyr::last_dplyr_warnings()` to see the 8 remaining warnings.
knitr::kable(summary_statistics, caption = "Deskripsi Statistik Awal")
Deskripsi Statistik Awal
2.93 |
2.95 |
NaN |
5.55 |
2.99 |
3.02 |
NaN |
5.48 |
3.1 |
3.12 |
NaN |
1.408882 |
1.5333 |
NA |
2.952058 |
1.374332 |
1.456299 |
NA |
2.945567 |
1.438995 |
1.49936 |
NA |
3 |
3 |
NA |
5.5 |
3 |
3 |
NA |
6 |
3 |
3 |
NA |
4.2 Uji Validitas dan Reliabilitas
4.2.1 Korelasi Item-Total
Untuk memeriksa validitas konstruk, kita akan menghitung korelasi
antara item dan total skor untuk setiap kategori.
# Menghitung korelasi item-total untuk kategori KRS
cor_krs <- cor(data_krs$KRS_akses, data_krs$KRS_masalah, use = "complete.obs")
cor_krs
## [1] 0.08720506
4.2.2 Cronbach’s Alpha
Kita akan mengukur reliabilitas setiap kategori menggunakan
Cronbach’s Alpha.
## Warning: package 'psych' was built under R version 4.4.3
# Fungsi untuk menghitung Cronbach's Alpha
cronbach_alpha <- function(data) {
numeric_data <- data[sapply(data, is.numeric)]
data_clean <- na.omit(numeric_data)
alpha_result <- psych::alpha(data_clean)
return(alpha_result$total$raw_alpha)
}
# Menghitung Cronbach's Alpha untuk kategori KRS
cronbach_krs <- cronbach_alpha(data_krs)
cronbach_krs
## [1] 0.1598937
4.3 Penyajian Grafik
Kita akan menggunakan grafik untuk menggambarkan distribusi jawaban
dari beberapa pertanyaan.
2.3.1 Histogram untuk KRS_akses
# Membuat histogram untuk melihat distribusi frekuensi untuk KRS_akses
library(ggplot2)
##
## Attaching package: 'ggplot2'
## The following objects are masked from 'package:psych':
##
## %+%, alpha
ggplot(data_survei, aes(x = KRS_akses)) +
geom_bar(fill = "skyblue", color = "black") +
labs(title = "Distribusi Jawaban KRS Akses", x = "Skala KRS Akses", y = "Frekuensi")

4.3.2 Boxplot untuk Bimbingan_kualitas
# Membuat boxplot untuk Bimbingan_kualitas
ggplot(data_survei, aes(y = Bimbingan_kualitas, x = 1)) +
geom_boxplot(fill = "lightgreen", color = "black") +
labs(title = "Distribusi Kepuasan Terhadap Bimbingan Akademik", y = "Kualitas Bimbingan", x = "")

4.4 Kesimpulan
Berdasarkan analisis data awal, kita dapat menyimpulkan bahwa:
Layanan KRS Online cenderung memiliki tingkat kepuasan yang
bervariasi, dengan sebagian besar mahasiswa merasa kesulitan mengakses
atau mengalami masalah teknis.
Bimbingan Akademik menunjukkan kepuasan yang cukup baik, namun
terdapat kendala dalam hal waktu dan akses.
Pelayanan administrasi umumnya dianggap cepat, meskipun ada
beberapa laporan keterlambatan.
Akses informasi akademik juga bervariasi, dengan beberapa
mahasiswa merasa kesulitan menemukan informasi yang diperlukan.
LS0tDQp0aXRsZTogIlVUUyBUZWtuaWsgU2FtcGxpbmcgZGFuIFN1cnZlaSINCnN1YnRpdGxlOiAiVGVrbmlrIFNhbXBsaW5nIGRhbiBTdXJ2ZWkiDQphdXRob3I6ICJKT0FOUyBIRU5LWSBTRVJWQVRJVVMgU0lNQU5VTExBTkciDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy5EYXRlKCksICclQiAlZCwgJVknKWAiDQpvdXRwdXQ6DQogIHJtZGZvcm1hdHM6OnJlYWR0aGVkb3duOg0KICAgIHNlbGZfY29udGFpbmVkOiB0cnVlDQogICAgdGh1bWJuYWlsczogdHJ1ZQ0KICAgIGxpZ2h0Ym94OiB0cnVlDQogICAgZ2FsbGVyeTogdHJ1ZQ0KICAgIGxpYl9kaXI6IGxpYnMNCiAgICBkZl9wcmludDogInBhZ2VkIg0KICAgIGNvZGVfZm9sZGluZzogInNob3ciDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgY3NzOiAic3R5bGUgMS5jc3MiDQotLS0NCjxpbWcgc3JjPSJmb3RvLmpwZWciIHN0eWxlPSJkaXNwbGF5OiBibG9jazsgbWFyZ2luOiBhdXRvOyB3aWR0aDogMzYwcHg7IGhlaWdodDogNDgwcHg7IiBhbHQ9IiI+DQoNCg0KIyBTdHVkaSBLYXN1cyAxICgqKlNpbXVsYXNpIEtlc2FsYWhhbiBTYW1wbGluZyBkaSBMYXBhbmdhbioqKQ0KDQpBbmRpa2FuIEFuZGEgYWRhbGFoIGJhZ2lhbiBkYXJpIHRpbSByaXNldCBsYXBhbmdhbiB5YW5nIGRpbWludGEgdW50dWsgbWVsYWt1a2FuDQpzdXJ2ZWkgdGluZ2thdCBwZW5nZ3VuYWFuIGFwbGlrYXNpIHRyYW5zcG9ydGFzaSBvbmxpbmUgZGkgKiozIGtvdGEgbWVuZW5nYWgqKiBkaSBTdW1hdGVyYS4NClRhcmdldCBzYW1wZWwgdG90YWwgYWRhbGFoICoqNjAwIHJlc3BvbmRlbioqLCBtYXNpbmctbWFzaW5nIDIwMCBwZXIga290YS4gVGV0YXBpLCBzZXRlbGFoDQoyIG1pbmdndSBtZWxha3VrYW4gc3VydmVpIGFuZGEgbWVuZW11a2FuOg0KDQotIERpIEtvdGEgQSwgdGltIGJlcmhhc2lsIG1lbmRhcGF0a2FuIDI1MCByZXNwb25kZW4uDQotIERpIEtvdGEgQiwgaGFueWEgMTIwIHJlc3BvbmRlbiB5YW5nIGRhcGF0IGRpd2F3YW5jYXJhaS4NCi0gRGkgS290YSBDLCAxODAgcmVzcG9uZGVuLg0KDQoqSW5zdHJ1a3NpOioNCg0KYS4gSmVsYXNrYW4gKipkdWEgamVuaXMga2VzYWxhaGFuIHNhbXBsaW5nKiogeWFuZyB0ZXJqYWRpIGJlcmRhc2Fya2FuIHNpdHVhc2kgaW5pLg0KDQpiLiBKaWthIEFuZGEgaGFydXMgbWVueWVzdWFpa2FuIGJvYm90IHVudHVrIG1lbmdlbWJhbGlrYW4gcmVwcmVzZW50YXNpIHByb3BvcnNpb25hbCwgYmFnYWltYW5hIEFuZGEgYWthbiBtZW5naGl0dW5nbnlhPw0KDQotLS0NCg0KIyMgS2VzYWxhaGFuIFNhbXBsaW5nDQoNCkJlcmRhc2Fya2FuIHNpdHVhc2kgeWFuZyBkaWJlcmlrYW4sIGJlcmlrdXQgYWRhbGFoIGR1YSBqZW5pcyBrZXNhbGFoYW4gc2FtcGxpbmcgeWFuZyB0ZXJqYWRpOg0KDQojIyMgKioxLiBLZXNhbGFoYW4gUmVwcmVzZW50YXNpIChSZXByZXNlbnRhdGlvbiBFcnJvcikqKg0KDQpKdW1sYWggcmVzcG9uZGVuIHlhbmcgdGVya3VtcHVsIHRpZGFrIHNlc3VhaSBkZW5nYW4gdGFyZ2V0IGF3YWwgcGVyIGtvdGEsIHlhaXR1IDIwMCByZXNwb25kZW4gcGVyIGtvdGEuIFNpdHVhc2kgaW5pIG1lbnllYmFia2FuOg0KDQotIEtvdGEgQSBtZW1pbGlraSAyNTAgcmVzcG9uZGVuLCB5YW5nIGJlcmFydGkga2VsZWJpaGFuIDUwIHJlc3BvbmRlbiAoKzI1JSBkYXJpIHRhcmdldCkuDQotIEtvdGEgQiBoYW55YSBtZW1pbGlraSAxMjAgcmVzcG9uZGVuLCB5YW5nIGJlcmFydGkga2VrdXJhbmdhbiA4MCByZXNwb25kZW4gKC00MCUgZGFyaSB0YXJnZXQpLg0KLSBLb3RhIEMgbWVtaWxpa2kgMTgwIHJlc3BvbmRlbiwgeWFuZyBiZXJhcnRpIGtla3VyYW5nYW4gMjAgcmVzcG9uZGVuICgtMTAlIGRhcmkgdGFyZ2V0KS4NCg0KS2FyZW5hIGRpc3RyaWJ1c2kganVtbGFoIHJlc3BvbmRlbiB0aWRhayBzZWltYmFuZywgaGFzaWwgc3VydmVpIG1lbmphZGkgdGlkYWsgbWV3YWtpbGkgcHJvcG9yc2kgeWFuZyBkaWluZ2lua2FuLiBLb3RhIEEgeWFuZyBrZWxlYmloYW4gcmVzcG9uZGVuIGFrYW4gbWVtaWxpa2kgcGVuZ2FydWggeWFuZyBsZWJpaCBiZXNhciB0ZXJoYWRhcCBoYXNpbCBzdXJ2ZWkuDQoNCiMjIyAqKjIuIEtlc2FsYWhhbiBTYW1wbGluZyBOb24tUmVzcG9ucyAoTm9uLVJlc3BvbnNlIEVycm9yKSoqDQoNCktlc2FsYWhhbiBpbmkgdGVyamFkaSBrYXJlbmEgZGkgS290YSBCIGhhbnlhIDEyMCBvcmFuZyB5YW5nIGJlcmhhc2lsIGRpd2F3YW5jYXJhaSwgamF1aCBkaSBiYXdhaCB0YXJnZXQgMjAwLiBLZW11bmdraW5hbiBhZGEgZmFrdG9yLWZha3RvciB0ZXJ0ZW50dSB5YW5nIG1lbWJ1YXQgcmVzcG9uZGVuIGRpIEtvdGEgQiB0aWRhayBtYXUgYXRhdSB0aWRhayBiaXNhIGJlcnBhcnRpc2lwYXNpLCBzZXBlcnRpIGt1cmFuZ255YSB3YWt0dSwga2V0aWRha3BlcmNheWFhbiB0ZXJoYWRhcCBzdXJ2ZWksIGF0YXUgYWxhc2FuIGxhaW4uIEppa2Ega2FyYWt0ZXJpc3RpayBtZXJla2EgYmVyYmVkYSBkYXJpIHlhbmcgYmVycGFydGlzaXBhc2ksIGhhc2lsIHN1cnZlaSBha2FuIGJpYXMuDQoNCi0tLQ0KDQojIyBNZW5naGl0dW5nIEJvYm90IFJlc3BvbmRlbg0KDQpVbnR1ayBtZW5nZW1iYWxpa2FuIHJlcHJlc2VudGFzaSBwcm9wb3JzaW9uYWwga2UgdGFyZ2V0IGF3YWwgKDIwMCByZXNwb25kZW4gcGVyIGtvdGEgZGFyaSB0b3RhbCA2MDApLCBib2JvdCB1bnR1ayBtYXNpbmctbWFzaW5nIGtvdGEgZGloaXR1bmcgc2ViYWdhaSBiZXJpa3V0Og0KDQoxLiAqKlByb3BvcnNpIFRhcmdldDoqKg0KICAgLSBLb3RhIEE6IFwoIFxmcmFjezIwMH17NjAwfSA9IDAuMzMzMyBcKQ0KICAgLSBLb3RhIEI6IFwoIFxmcmFjezIwMH17NjAwfSA9IDAuMzMzMyBcKQ0KICAgLSBLb3RhIEM6IFwoIFxmcmFjezIwMH17NjAwfSA9IDAuMzMzMyBcKQ0KDQoyLiAqKlByb3BvcnNpIEFrdHVhbDoqKg0KICAgLSBLb3RhIEE6IFwoIFxmcmFjezI1MH17NTUwfSBcYXBwcm94IDAuNDU0NSBcKQ0KICAgLSBLb3RhIEI6IFwoIFxmcmFjezEyMH17NTUwfSBcYXBwcm94IDAuMjE4MiBcKQ0KICAgLSBLb3RhIEM6IFwoIFxmcmFjezE4MH17NTUwfSBcYXBwcm94IDAuMzI3MyBcKQ0KDQozLiAqKkJvYm90OioqDQogICAtIEtvdGEgQTogXCggXGZyYWN7MC4zMzMzfXswLjQ1NDV9IFxhcHByb3ggMC43MzMgXCkNCiAgIC0gS290YSBCOiBcKCBcZnJhY3swLjMzMzN9ezAuMjE4Mn0gXGFwcHJveCAxLjUyOCBcKQ0KICAgLSBLb3RhIEM6IFwoIFxmcmFjezAuMzMzM317MC4zMjczfSBcYXBwcm94IDEuMDE4IFwpDQoNCi0tLQ0KDQojIyBJbXBsZW1lbnRhc2kgUGVyaGl0dW5nYW4gZGVuZ2FuIFINCg0KQmVyaWt1dCBhZGFsYWggaW1wbGVtZW50YXNpIGtvZGUgdW50dWsgbWVuZ2hpdHVuZyBib2JvdCBtZW5nZ3VuYWthbiBSOg0KDQpgYGB7ciwgZWNobz1UUlVFfQ0KbGlicmFyeShrbml0cikNCg0KIyBEYXRhIGp1bWxhaCB0YXJnZXQgZGFuIGFrdHVhbCBwZXIga290YQ0Ka290YSA8LSBjKCJLb3RhIEEiLCAiS290YSBCIiwgIktvdGEgQyIpDQp0YXJnZXQgPC0gYygyMDAsIDIwMCwgMjAwKQ0KYWt0dWFsIDwtIGMoMjUwLCAxMjAsIDE4MCkNCg0KIyBUb3RhbA0KdG90YWxfdGFyZ2V0IDwtIHN1bSh0YXJnZXQpDQp0b3RhbF9ha3R1YWwgPC0gc3VtKGFrdHVhbCkNCg0KIyBIaXR1bmcgcHJvcG9yc2kgdGFyZ2V0IGRhbiBha3R1YWwNCnByb3BvcnNpX3RhcmdldCA8LSB0YXJnZXQgLyB0b3RhbF90YXJnZXQNCnByb3BvcnNpX2FrdHVhbCA8LSBha3R1YWwgLyB0b3RhbF9ha3R1YWwNCg0KIyBIaXR1bmcgYm9ib3QNCmJvYm90IDwtIHJvdW5kKHByb3BvcnNpX3RhcmdldCAvIHByb3BvcnNpX2FrdHVhbCwgMykNCg0KIyBCdWF0IGRhdGEgZnJhbWUgaGFzaWwNCmhhc2lsIDwtIGRhdGEuZnJhbWUoDQogIEtvdGEgPSBrb3RhLA0KICBUYXJnZXQgPSB0YXJnZXQsDQogIEFrdHVhbCA9IGFrdHVhbCwNCiAgYFByb3BvcnNpIFRhcmdldGAgPSByb3VuZChwcm9wb3JzaV90YXJnZXQsIDQpLA0KICBgUHJvcG9yc2kgQWt0dWFsYCA9IHJvdW5kKHByb3BvcnNpX2FrdHVhbCwgNCksDQogIGBCb2JvdCBQZW55ZXN1YWlhbmAgPSBib2JvdA0KKQ0KDQojIFRhbXBpbGthbiBoYXNpbA0Ka2FibGUoaGFzaWwsIGNhcHRpb24gPSAiVGFiZWwgUGVueWVzdWFpYW4gQm9ib3QgUmVzcG9uZGVuIHBlciBLb3RhIikNCmBgYA0KDQojIFN0dWRpIEthc3VzIDIgKCoqTWVuZGVzYWluIFN1cnZlaSBkZW5nYW4gUGVtYm9ib3RhbiBXYWt0dSBQdW5jYWsqKikNCg0KQnVhdGxhaCBkZXNhaW4gcmFuY2FuZ2FuIHN1cnZlaSB0ZW50YW5nICoqcGVyc2Vwc2kga2VueWFtYW5hbiBwZW5nZ3VuYSBvamVrIG9ubGluZSBzYWF0IGphbSBzaWJ1ayAoMDcuMDDigJMwOS4wMCBkYW4gMTcuMDDigJMxOS4wMCkuKioNCg0KKkluc3RydWtzaToqDQoNCmEuIERlc2FpbiBwZW5kZWthdGFuIHNhbXBsaW5nIHlhbmcgKiptZW11bmdraW5rYW4gQW5kYSBtZW5hbmdrYXAgcGVyc2Vwc2kgcGVuZ2d1bmEgc2VjYXJhIHJlcHJlc2VudGF0aWYgcGFkYSBqYW0gc2lidWssKiogdGFucGEgbWVsYWt1a2FuIHN1cnZlaSBzZXBhbmphbmcgaGFyaS4NCg0KYi4gU2VydGFrYW4gKipyYW5jYW5nYW4gd2FrdHUsIG1ldG9kZSBwZW1pbGloYW4gcmVzcG9uZGVuLCBkYW4ganVzdGlmaWthc2kgcGVtaWxpaGFuIHVuaXQgc2FtcGxpbmcqKi4NCg0KYy4gSmVsYXNrYW4gYmFnYWltYW5hIEFuZGEgYWthbiBtZW55ZXN1YWlrYW4gaGFzaWwgc3VydmVpIGppa2EgNjAlIHJlc3BvbmRlbiBiZXJhc2FsIGRhcmkgcGFnaSBoYXJpLCBzZW1lbnRhcmEgNDAlIGRhcmkgc29yZSBoYXJpLCBzZWRhbmdrYW4gZGF0YSBoaXN0b3JpcyBtZW51bmp1a2thbiBwZW5nZ3VuYSBvamVrIG9ubGluZSBzYWF0IHNvcmUgaGFyaSBkdWEga2FsaSBsZWJpaCBiYW55YWsgZGliYW5kaW5nIHBhZ2kuDQoNCi0tLQ0KDQojIyBEZXNhaW4gUGVuZGVrYXRhbiBTYW1wbGluZw0KDQpVbnR1ayBtZW1hc3Rpa2FuIHN1cnZlaSB5YW5nIHJlcHJlc2VudGF0aWYsIHBlbmRla2F0YW4geWFuZyBkaWd1bmFrYW4gYWRhbGFoICoqc3RyYXRpZmllZCB0aW1lIHNhbXBsaW5nKiosIGRlbmdhbiBwZW1iYWdpYW4gZHVhIHN0cmF0YSB3YWt0dToNCg0KLSAqKlBhZ2kgKDA3LjAw4oCTMDkuMDApOioqIEZva3VzIHBhZGEgamFtIGJlcmFuZ2thdCBrZXJqYS9zZWtvbGFoLg0KLSAqKlNvcmUgKDE3LjAw4oCTMTkuMDApOioqIEZva3VzIHBhZGEgamFtIHB1bGFuZyBrZXJqYS9zZWtvbGFoLg0KDQpEZW5nYW4gcGVuZGVrYXRhbiBpbmksIHN1cnZlaSBoYW55YSBkaWxha3VrYW4gcGFkYSBqYW0gc2lidWsgeWFuZyByZWxldmFuLCBzZWhpbmdnYSBlZmlzaWVuIGRhbiB0ZXRhcCByZXByZXNlbnRhdGlmIHRhbnBhIGhhcnVzIG1lbmd1bXB1bGthbiBkYXRhIHNlcGFuamFuZyBoYXJpLiBNYXNpbmctbWFzaW5nIHN0cmF0YSB3YWt0dSBtZXJlcHJlc2VudGFzaWthbiBwb2xhIHBlbmdndW5hYW4gb2playBvbmxpbmUgeWFuZyBiZXJiZWRhLg0KDQotLS0NCg0KIyMgUmFuY2FuZ2FuIFdha3R1LCBNZXRvZGUsIGRhbiBKdXN0aWZpa2FzaQ0KDQoqKlJhbmNhbmdhbiBXYWt0dToqKg0KLSBTdXJ2ZWkgZGlsYWtzYW5ha2FuIHBhZGEgaGFyaSBrZXJqYSAoU2VuaW4tSnVtYXQpIHNlbGFtYSBkdWEgd2FrdHUgc2lidWs6IHBhZ2kgKDA3LjAw4oCTMDkuMDApIGRhbiBzb3JlICgxNy4wMOKAkzE5LjAwKS4NCg0KKipNZXRvZGUgUGVtaWxpaGFuIFJlc3BvbmRlbjoqKg0KLSAqKlN5c3RlbWF0aWMgaW50ZXJjZXB0IHNhbXBsaW5nOioqIFJlc3BvbmRlbiBkaXBpbGloIHNlY2FyYSBzaXN0ZW1hdGlzIHBhZGEgbG9rYXNpLWxva2FzaSBzdHJhdGVnaXMsIHNlcGVydGkgc3Rhc2l1biwgdGVybWluYWwsIGF0YXUga2F3YXNhbiBwZXJrYW50b3Jhbi4NCi0gQ29udG9oOiBTZXRpYXAgMTAgbWVuaXQsIHNhdHUgcGVuZ2d1bmEgb2playBvbmxpbmUgeWFuZyBiYXJ1IHR1cnVuIGRpd2F3YW5jYXJhaS4NCg0KKipKdXN0aWZpa2FzaSBQZW1pbGloYW4gVW5pdCBTYW1wbGluZzoqKg0KLSBVbml0IHNhbXBsaW5nIGFkYWxhaCAqKnBlbmdndW5hIGFrdGlmIG9qZWsgb25saW5lIHBhZGEgamFtIHNpYnVrKiouIE1lcmVrYSBkaXBpbGloIGthcmVuYSBiZXJhZGEgZGkgbG9rYXNpIGRhbiB3YWt0dSB5YW5nIHJlbGV2YW4gdW50dWsgbWVuZ2dhbWJhcmthbiBwZXJzZXBzaSBrZW55YW1hbmFuIHNlY2FyYSBsYW5nc3VuZy4NCg0KLS0tDQoNCiMjIFBlbnllc3VhaWFuIEhhc2lsIFN1cnZlaSBCZXJkYXNhcmthbiBEYXRhIEhpc3RvcmlzDQoNCkRhbGFtIHN1cnZlaSBpbmk6DQotICoqNjAlIHJlc3BvbmRlbiBiZXJhc2FsIGRhcmkgcGFnaSBoYXJpICgwNy4wMOKAkzA5LjAwKS4qKg0KLSAqKjQwJSByZXNwb25kZW4gYmVyYXNhbCBkYXJpIHNvcmUgaGFyaSAoMTcuMDDigJMxOS4wMCkuKioNCg0KTmFtdW4sIGRhdGEgaGlzdG9yaXMgbWVudW5qdWtrYW4gYmFod2E6DQotIFBlbmdndW5hIG9qZWsgb25saW5lIGRpIHNvcmUgaGFyaSBkdWEga2FsaSBsZWJpaCBiYW55YWsgZGliYW5kaW5na2FuIHBhZ2kgaGFyaS4NCg0KIyMjIFByb3BvcnNpIEFrdHVhbCBCZXJkYXNhcmthbiBEYXRhIEhpc3RvcmlzOg0KLSAqKlBhZ2k6KiogMSBiYWdpYW4gKDEvMyBhdGF1IDAuMzMpDQotICoqU29yZToqKiAyIGJhZ2lhbiAoMi8zIGF0YXUgMC42NykNCg0KIyMjIFBlbnllc3VhaWFuIEJvYm90Og0KVW50dWsgbWVuZ2hpbmRhcmkgYmlhcyBha2liYXQga2V0aWRha3NlaW1iYW5nYW4ganVtbGFoIHJlc3BvbmRlbiwgZGlsYWt1a2FuIHBlbnllc3VhaWFuIGJvYm90IGJlcmRhc2Fya2FuIHByb3BvcnNpIGFrdHVhbCBkYW4gcHJvcG9yc2kgc3VydmVpLg0KDQoqKlJ1bXVzIEJvYm90OioqDQokJA0KXHRleHR7Qm9ib3Qgd2FrdHV9ID0gXGZyYWN7XHRleHR7UHJvcG9yc2kgc2ViZW5hcm55YX19e1x0ZXh0e1Byb3BvcnNpIGhhc2lsIHN1cnZlaX19DQokJA0KDQoqKlBlcmhpdHVuZ2FuIEJvYm90OioqDQotICoqQm9ib3QgcGFnaToqKiBcKCAwLjMzIC8gMC42MCBcYXBwcm94IDAuNTYgXCkNCi0gKipCb2JvdCBzb3JlOioqIFwoIDAuNjcgLyAwLjQwIFxhcHByb3ggMS42NyBcKQ0KDQpgYGB7cn0NCmxpYnJhcnkoa25pdHIpDQoNCiMgRGF0YSBwZW1ib2JvdGFuDQpwZW1ib2JvdGFuX2RhdGEgPC0gZGF0YS5mcmFtZSgNCiAgV2FrdHUgPSBjKCJQYWdpIiwgIlNvcmUiKSwNCiAgUHJvcG9yc2lfU3VydmVpID0gYygwLjYwLCAwLjQwKSwNCiAgUHJvcG9yc2lfQWt0dWFsID0gYygxLzMsIDIvMyksDQogIEJvYm90ID0gYygoMS8zKS8wLjYwLCAoMi8zKS8wLjQwKQ0KKQ0KDQojIFRhYmVsIHBlbWJvYm90YW4NCmthYmxlKHBlbWJvYm90YW5fZGF0YSwgY2FwdGlvbiA9ICJQZW1ib2JvdGFuIEJlcmRhc2Fya2FuIFByb3BvcnNpIEhpc3RvcmlzIFBlbmdndW5hIikNCmBgYA0KDQotLS0NCg0KIyMgU2ltdWxhc2kgRGF0YSBkYW4gQW5hbGlzaXMNCg0KIyMjIERhdGEgU2ltdWxhc2kNCg0KS2l0YSBidWF0IGRhdGEgc2ltdWxhc2kgdW50dWsgMTAwIHJlc3BvbmRlbjoNCg0KYGBge3J9DQpzZXQuc2VlZCgxMjMpICAjIEZvciByZXByb2R1Y2liaWxpdHkNCg0KIyBNZW1idWF0IGRhdGEgdW50dWsgMTAwIHJlc3BvbmRlbg0KZGF0YSA8LSBkYXRhLmZyYW1lKA0KICByZXNwb25kZW50X2lkID0gMToxMDAsDQogIHRpbWVfcGVyaW9kID0gYyhyZXAoIlBhZ2kiLCA2MCksIHJlcCgiU29yZSIsIDQwKSksDQogIHNhdGlzZmFjdGlvbl9zY29yZSA9IGMocm5vcm0oNjAsIG1lYW4gPSA3LCBzZCA9IDEuNSksIHJub3JtKDQwLCBtZWFuID0gOCwgc2QgPSAxLjIpKQ0KKQ0KDQpoZWFkKGRhdGEpDQoNCmBgYA0KDQojIyMgVGVyYXBrYW4gQm9ib3QNCg0KVGFtYmFoa2FuIGJvYm90IGtlIGRhdGEgYmVyZGFzYXJrYW4gd2FrdHU6DQoNCmBgYHtyfQ0KbGlicmFyeShkcGx5cikNCg0KZGF0YSA8LSBkYXRhICU+JQ0KICBsZWZ0X2pvaW4ocGVtYm9ib3Rhbl9kYXRhICU+JSBzZWxlY3QoV2FrdHUsIEJvYm90KSwgYnkgPSBjKCJ0aW1lX3BlcmlvZCIgPSAiV2FrdHUiKSkgJT4lDQogIG11dGF0ZSh3ZWlnaHRlZF9zY29yZSA9IHNhdGlzZmFjdGlvbl9zY29yZSAqIEJvYm90KQ0KDQpoZWFkKGRhdGEpDQpgYGANCg0KIyMjIFBlcmhpdHVuZ2FuIFJhdGEtcmF0YSBCZXJib2JvdA0KDQpIaXR1bmcgcmF0YS1yYXRhIGJlcmJvYm90Og0KDQpgYGB7cn0NCndlaWdodGVkX21lYW4gPC0gc3VtKGRhdGEkd2VpZ2h0ZWRfc2NvcmUpIC8gc3VtKGRhdGEkQm9ib3QpDQp3ZWlnaHRlZF9tZWFuDQpgYGANCg0KIyBTdHVkaSBLYXN1cyAzICgqKkV2YWx1YXNpIEtlcHVhc2FuIE1haGFzaXN3YSB0ZXJoYWRhcCBMYXlhbmFuIEFrYWRlbWlrKiopDQpBbmRhIGRpdHVnYXNrYW4gb2xlaCBiaXJvIGFrYWRlbWlrIGthbXB1cyB1bnR1ayBtZXJhbmNhbmcgaW5zdHJ1bWVuIHN1cnZlaSB5YW5nDQpiZXJ0dWp1YW4gbWVuZ2V2YWx1YXNpIGtlcHVhc2FuIG1haGFzaXN3YSB0ZXJoYWRhcCBsYXlhbmFuIGFrYWRlbWlrLCB5YW5nDQptZW5jYWt1cCBsYXlhbmFuIHNlcGVydGk6IEtSUyBvbmxpbmUsIGJpbWJpbmdhbiBha2FkZW1paywgcGVsYXlhbmFuIGFkbWluaXN0cmFzaSwgYWtzZXMNCmluZm9ybWFzaSBha2FkZW1paywgZGFuIGJhbnR1YW4gcGVueWVsZXNhaWFuIHN0dWRpLg0KDQpUaW0gcGVuZWxpdGkgbWVtaW50YSBBbmRhIHVudHVrOg0KDQotIE1lcmFuY2FuZyAyNSBwZXJ0YW55YWFuIHV0YW1hIGRlbmdhbiAqKnZhcmlhc2kgc2thbGEgZGFuIGJlbnR1ayBwZXJ0YW55YWFuKiouDQoNCi0gTWVyYW5jYW5nIHNpc3RlbSB2YWxpZGFzaSBpbnN0cnVtZW4uDQoNCi0gTWVuZW50dWthbiBtZXRvZGUgZGlzdHJpYnVzaSBkYW4gcGVuZ3VqaWFuIGt1ZXNpb25lciBzZWNhcmEgc3RhdGlzdGlrLg0KDQotIE1lbnlpYXBrYW4gc2ltdWxhc2kgc3RyYXRlZ2kgcGVuZ2FtYmlsYW4gc2FtcGVsIGRhbiBwZW5nb2xhaGFuIGRhdGEgYXdhbC4NCg0KT3V0cHV0IExhcG9yYW4geWFuZyBkaWhhcmFwa2FuIGRhbGFtIGJlbnR1ayBuYXJhdGlmLCBtZW5jYWt1cDoNCg0K4oCiIERlc2FpbiBwZXJ0YW55YWFuDQoNCuKAoiBTa2VtYSB2YWxpZGFzaQ0KDQrigKIgU3RyYXRlZ2kgZGlzdHJpYnVzaSBkYW4gc2FtcGxpbmcNCg0K4oCiIFNpbXVsYXNpIGRhdGEgZGFuIGFuYWxpc2lzIGF3YWwNCg0KLS0tDQoNCiMjIDEuIERlc2FpbiBQZXJ0YW55YWFuDQpCZXJpa3V0IGFkYWxhaCBkZXNhaW4gMjUgcGVydGFueWFhbiB5YW5nIHRlcmJhZ2kgZGFsYW0gbGltYSBhc3BlayBsYXlhbmFuIGFrYWRlbWlrOg0KDQotICoqS1JTIE9ubGluZSoqDQotICoqQmltYmluZ2FuIEFrYWRlbWlrKioNCi0gKipQZWxheWFuYW4gQWRtaW5pc3RyYXNpKioNCi0gKipBa3NlcyBJbmZvcm1hc2kgQWthZGVtaWsqKg0KLSAqKkJhbnR1YW4gUGVueWVsZXNhaWFuIFN0dWRpKioNCg0KTGluayBQZXJ0YW55YWFuIEdvb2dsZSBGb3JtOiA8YSBocmVmPSJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9mb3Jtcy9kL2UvMUZBSXBRTFNjZE5lOTN1NkhLUW9VYVZtXzVLTzN3MGhHWVRTX2pHSG10cHEzdU45TmNDR2lWZGcvdmlld2Zvcm0/dXNwPXNoYXJpbmciPkdvb2dsZSBGb3JtPC9hPg0KDQotLS0NCg0KIyMgMi4gU2tlbWEgdmFsaWRhc2kNCg0KIyMjIDIuMSBWYWxpZGFzaSBJc2kgKENvbnRlbnQgVmFsaWRpdHkpDQoNClByb3NlcyB2YWxpZGFzaSBpc2kgZGlsYWt1a2FuIGRlbmdhbiBtZWxpYmF0a2FuIHBha2FyIGF0YXUgZG9zZW4gZGkgYmlkYW5nIHBlbmRpZGlrYW4gdW50dWsgbWVuaWxhaSByZWxldmFuc2kgc2V0aWFwIHBlcnRhbnlhYW4gdGVyaGFkYXAgYXNwZWsgeWFuZyBkaWV2YWx1YXNpLiBQZW5pbGFpYW4gZGlsYWt1a2FuIGRlbmdhbiB0aWdhIGthdGVnb3JpOg0KDQotIFNhbmdhdCByZWxldmFuDQoNCi0gQ3VrdXAgcmVsZXZhbg0KDQotIFRpZGFrIHJlbGV2YW4NCg0KSGFzaWwgcGVuaWxhaWFuIGRpaGl0dW5nIG1lbmdndW5ha2FuIENvbnRlbnQgVmFsaWRpdHkgUmF0aW8gKENWUikuIEppa2EgQ1ZSIGRhcmkgc3VhdHUgcGVydGFueWFhbiBiZXJhZGEgZGkgYXRhcyBhbWJhbmcgYmF0YXMgeWFuZyBkaXRlbnR1a2FuLCBtYWthIHBlcnRhbnlhYW4gdGVyc2VidXQgZGlhbmdnYXAgdmFsaWQgc2VjYXJhIGlzaS4gU2ViYWxpa255YSwgamlrYSBDVlIgcmVuZGFoLCBwZXJ0YW55YWFuIHRlcnNlYnV0IHBlcmx1IGRpcmV2aXNpIGF0YXUgZGloYXB1cy4NCg0KIyMjIDIuMiBWYWxpZGFzaSBTdGF0aXN0aWsNCg0KU2V0ZWxhaCB2YWxpZGFzaSBpc2kgc2VsZXNhaSwgZGlsYWt1a2FuIHVqaSBjb2JhIGt1ZXNpb25lciBrZXBhZGEgMzAgbWFoYXNpc3dhIHNlYmFnYWkgdGFoYXAgYXdhbCBwZW5ndWppYW4gc3RhdGlzdGlrLg0KDQojIyMjIDIuMi4xIFVqaSBWYWxpZGl0YXMgS29uc3RydWsgKENvbnN0cnVjdCBWYWxpZGl0eSkNCg0KVWppIGluaSBiZXJ0dWp1YW4gdW50dWsgbWVtYXN0aWthbiBiYWh3YSBzZXRpYXAgcGVydGFueWFhbiBkYWxhbSBrdWVzaW9uZXIgYmVuYXItYmVuYXIgbWVuZ3VrdXIgYXNwZWsgeWFuZyBzZXN1YWkuIFBlbmRla2F0YW4geWFuZyBkaWd1bmFrYW46DQoNCi0gS29yZWxhc2kgSXRlbS1Ub3RhbDogTWVuZ2hpdHVuZyBrb3JlbGFzaSBhbnRhcmEgc2V0aWFwIGl0ZW0gZGVuZ2FuIHRvdGFsIHNrb3IgZGFyaSBhc3BlayB0ZXJrYWl0LiBLb3JlbGFzaSA+IDAuMyBtZW51bmp1a2thbiB2YWxpZGl0YXMgeWFuZyBiYWlrLg0KDQotIEFuYWxpc2lzIEZha3RvcjogRGlsYWt1a2FuIGVrc3Bsb3Jhc2kgbWVuZ2d1bmFrYW4gbWV0b2RlIEFuYWxpc2lzIEZha3RvciBFa3NwbG9yYXRvcmkgKEVGQSkgdW50dWsgbWVtYXN0aWthbiBiYWh3YSBrZWxvbXBvayBwZXJ0YW55YWFuIG1lbWJlbnR1ayBmYWt0b3IgeWFuZyBkaWhhcmFwa2FuLg0KDQojIyMjIDIuMi4yIFVqaSBSZWxpYWJpbGl0YXMNCg0KUmVsaWFiaWxpdGFzIGluc3RydW1lbiBkaXVqaSBtZW5nZ3VuYWthbiBDcm9uYmFjaOKAmXMgQWxwaGEgdW50dWsgbWVuZ2V2YWx1YXNpIGtvbnNpc3RlbnNpIGludGVybmFsIGFudGFyaXRlbS4gS3JpdGVyaWE6DQoNCi0gQWxwaGEgPiAwLjc6IEluc3RydW1lbiBkaWFuZ2dhcCByZWxpYWJlbC4NCg0KLSBBbHBoYSA8IDAuNzogUGVybHUgZGlsYWt1a2FuIHJldmlzaSBwYWRhIGl0ZW0gdGVydGVudHUgeWFuZyBtZW5ndXJhbmdpIHJlbGlhYmlsaXRhcy4NCg0KDQotLS0NCg0KIyMgMy4gU3RyYXRlZ2kgRGlzdHJpYnVzaSBkYW4gU2FtcGxpbmcNCg0KIyMjIDMuMSBTdHJhdGVnaSBEaXN0cmlidXNpDQoNCkt1ZXNpb25lciBha2FuIGRpc2ViYXJrYW4gc2VjYXJhIGRhcmluZyBtZW5nZ3VuYWthbiBwbGF0Zm9ybSBHb29nbGUgRm9ybXMuIExhbmdrYWggZGlzdHJpYnVzaSBtZWxpcHV0aToNCg0KLSBFbWFpbCBLYW1wdXM6IEt1ZXNpb25lciBkaWtpcmltIG1lbGFsdWkgc2lzdGVtIGVtYWlsIHJlc21pIGtlcGFkYSBzZWx1cnVoIG1haGFzaXN3YSBha3RpZi4NCg0KLSBHcnVwIE1lZGlhIFNvc2lhbDogVGF1dGFuIGt1ZXNpb25lciBkaXNlYmFya2FuIG1lbGFsdWkgZ3J1cCBXaGF0c0FwcCwgVGVsZWdyYW0sIGRhbiBwbGF0Zm9ybSBrb211bmlrYXNpIGxhaW5ueWEuDQoNCi0gTE1TIEthbXB1czogS3Vlc2lvbmVyIGp1Z2EgYWthbiB0ZXJzZWRpYSBkaSBMZWFybmluZyBNYW5hZ2VtZW50IFN5c3RlbSAoTE1TKSBrYW1wdXMgdW50dWsgbWVuaW5na2F0a2FuIGFrc2VzaWJpbGl0YXMuDQoNClBlbmdpbmdhdCBha2FuIGRpa2lyaW1rYW4gc2VjYXJhIGJlcmthbGEgdW50dWsgbWVuaW5na2F0a2FuIHRpbmdrYXQgcmVzcG9ucy4gU2VsYWluIGl0dSwgaW5zZW50aWYgYmVydXBhIHNlcnRpZmlrYXQgcGFydGlzaXBhc2kgYXRhdSBoYWRpYWgga2VjaWwgZGFwYXQgZGliZXJpa2FuIGtlcGFkYSByZXNwb25kZW4gc2ViYWdhaSBiZW50dWsgYXByZXNpYXNpLg0KDQojIyMgMy4yIFN0cmF0ZWdpIFNhbXBsaW5nDQoNCiMjIyMgMy4yLjEgUG9wdWxhc2kgZGFuIFRla25payBTYW1wbGluZw0KDQpQb3B1bGFzaSB0YXJnZXQgYWRhbGFoIHNlbHVydWggbWFoYXNpc3dhIGFrdGlmIGRpIGthbXB1cy4gTWV0b2RlIHNhbXBsaW5nIHlhbmcgZGlndW5ha2FuIGFkYWxhaCBTdHJhdGlmaWVkIFJhbmRvbSBTYW1wbGluZyBkZW5nYW4gc3RyYXRhIGJlcmRhc2Fya2FuOg0KDQotIFByb2dyYW0gU3R1ZGkNCg0KLSBBbmdrYXRhbiAobWlzYWxueWEgMjAyMC0yMDIzKQ0KDQpTdHJhdGlmaWthc2kgaW5pIGJlcnR1anVhbiB1bnR1ayBtZW1hc3Rpa2FuIGJhaHdhIHNldGlhcCBrZWxvbXBvayB0ZXJ3YWtpbGkgZGFsYW0gc3VydmVpLg0KDQojIyMjIDMuMi4yIFVrdXJhbiBTYW1wZWwNCg0KTWVuZ2FjdSBwYWRhIHBvcHVsYXNpIG1haGFzaXN3YSBha3RpZiBzZWJhbnlhayAxMC4wMDAgb3JhbmcsIGRpcGVybHVrYW4gbWluaW1hbCAzODQgcmVzcG9uZGVuIHVudHVrIHRpbmdrYXQga2VwZXJjYXlhYW4gOTUlIGRhbiBtYXJnaW4gb2YgZXJyb3IgNSUuIFVudHVrIHRhaGFwIHVqaSBjb2JhLCAzMCByZXNwb25kZW4gYXdhbCBha2FuIGRpZ3VuYWthbiB1bnR1ayBtZW12YWxpZGFzaSBpbnN0cnVtZW4gc2VjYXJhIHN0YXRpc3Rpay4NCg0KIyMjIyAzLjIuMyBBbG9rYXNpIFNhbXBlbA0KDQpSZXNwb25kZW4gZGFyaSBzZXRpYXAgc3RyYXRhIGFrYW4gZGlhbWJpbCBzZWNhcmEgcHJvcG9yc2lvbmFsLiBNaXNhbG55YSwgamlrYSBQcm9ncmFtIFN0dWRpIEEgbWVtaWxpa2kgMjAlIHBvcHVsYXNpLCBtYWthIDIwJSBkYXJpIHRvdGFsIHNhbXBlbCBha2FuIGRpYW1iaWwgZGFyaSBwcm9ncmFtIHN0dWRpIHRlcnNlYnV0Lg0KDQojIyMjIDMuMi40IFBlbmluZ2thdGFuIFJlc3BvbnMNCg0KU3RyYXRlZ2kgdW50dWsgbWVuaW5na2F0a2FuIHRpbmdrYXQgcmVzcG9ucyBtZWxpcHV0aToNCg0KLSBNZW5naXJpbWthbiBwZW5naW5nYXQgc2VjYXJhIGJlcmthbGEga2VwYWRhIG1haGFzaXN3YSB5YW5nIGJlbHVtIG1lbmdpc2kga3Vlc2lvbmVyLg0KDQotIE1lbGliYXRrYW4gb3JnYW5pc2FzaSBtYWhhc2lzd2EgZGFuIGRvc2VuIHVudHVrIG1lbXByb21vc2lrYW4gc3VydmVpLg0KDQotIE1lbWJlcmlrYW4gaW5zZW50aWYga2VwYWRhIHJlc3BvbmRlbiB5YW5nIGJlcnBhcnRpc2lwYXNpLg0KDQotLS0NCg0KIyMgNC4gU2ltdWxhc2kgRGF0YSBkYW4gYW5hbGlzaXMgYXdhbA0KDQpgYGB7ciwgZWNobz1UUlVFfQ0KIyBTaW11bGFzaSBEYXRhIFN1cnZlaSBLZXB1YXNhbiBNYWhhc2lzd2ENCnNldC5zZWVkKDEyMykNCg0KIyBNZW1idWF0IGRhdGEgdW50dWsgNSBrYXRlZ29yaSBsYXlhbmFuDQpkYXRhX2tycyA8LSBkYXRhLmZyYW1lKA0KICBLUlNfYWtzZXMgPSBzYW1wbGUoMTo1LCAxMDAsIHJlcGxhY2UgPSBUUlVFKSwNCiAgS1JTX21hc2FsYWggPSBzYW1wbGUoMTo1LCAxMDAsIHJlcGxhY2UgPSBUUlVFKSwNCiAgS1JTX2VmaXNpZW5zaSA9IHNhbXBsZShjKCJZYSIsICJUaWRhayIpLCAxMDAsIHJlcGxhY2UgPSBUUlVFKQ0KKQ0KDQojIEdhYnVuZ2thbiBkYXRhIHVudHVrIDUga2F0ZWdvcmkgbGFpbm55YQ0KZGF0YV9iaW1iaW5nYW4gPC0gZGF0YS5mcmFtZSgNCiAgQmltYmluZ2FuX2ZyZWt1ZW5zaSA9IHNhbXBsZSgxOjEwLCAxMDAsIHJlcGxhY2UgPSBUUlVFKSwNCiAgQmltYmluZ2FuX2t1YWxpdGFzID0gc2FtcGxlKDE6NSwgMTAwLCByZXBsYWNlID0gVFJVRSkNCikNCg0KZGF0YV9hZG1pbmlzdHJhc2kgPC0gZGF0YS5mcmFtZSgNCiAgQWRtaW5pc3RyYXNpX3Jlc3BvbnMgPSBzYW1wbGUoMTo1LCAxMDAsIHJlcGxhY2UgPSBUUlVFKSwNCiAgQWRtaW5pc3RyYXNpX2tlbXVkYWhhbiA9IHNhbXBsZShjKCJZYSIsICJUaWRhayIpLCAxMDAsIHJlcGxhY2UgPSBUUlVFKQ0KKQ0KDQpkYXRhX2Frc2VzIDwtIGRhdGEuZnJhbWUoDQogIEFrc2VzX2ZyZWt1ZW5zaSA9IHNhbXBsZSgxOjEwLCAxMDAsIHJlcGxhY2UgPSBUUlVFKSwNCiAgQWtzZXNfaW5mb3JtYXRpZiA9IHNhbXBsZSgxOjUsIDEwMCwgcmVwbGFjZSA9IFRSVUUpDQopDQoNCmRhdGFfYmFudHVhbiA8LSBkYXRhLmZyYW1lKA0KICBCYW50dWFuX3N0dWRpID0gc2FtcGxlKDE6NSwgMTAwLCByZXBsYWNlID0gVFJVRSksDQogIEJhbnR1YW5fdGVyc2VkaWEgPSBzYW1wbGUoYygiWWEiLCAiVGlkYWsiKSwgMTAwLCByZXBsYWNlID0gVFJVRSkNCikNCg0KIyBHYWJ1bmdrYW4gc2VtdWEgZGF0YSBtZW5qYWRpIHNhdHUgZGF0YSBmcmFtZQ0KZGF0YV9zdXJ2ZWkgPC0gY2JpbmQoZGF0YV9rcnMsIGRhdGFfYmltYmluZ2FuLCBkYXRhX2FkbWluaXN0cmFzaSwgZGF0YV9ha3NlcywgZGF0YV9iYW50dWFuKQ0KaGVhZChkYXRhX3N1cnZlaSkNCmBgYA0KDQoNCiMjIyA0LjEgRGVza3JpcHNpIFN0YXRpc3RpayBBd2FsDQpLaXRhIGFrYW4gbWVuZ2hpdHVuZyBiZWJlcmFwYSBkZXNrcmlwc2kgc3RhdGlzdGlrIHVudHVrIG1lbGloYXQgZGlzdHJpYnVzaSBkYXRhIGRhcmkgc2V0aWFwIGthdGVnb3JpLg0KYGBge3J9DQpsaWJyYXJ5KGRwbHlyKQ0Kc3VtbWFyeV9zdGF0aXN0aWNzIDwtIGRhdGFfc3VydmVpICU+JQ0KICBzdW1tYXJpc2VfYWxsKGxpc3QobWVhbiA9IH5tZWFuKGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKC4pKSwgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgICAgICAgICAgICAgIHNkID0gfnNkKGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKC4pKSwgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgICAgICAgICAgICAgIG1lZGlhbiA9IH5tZWRpYW4oYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoLikpLCBuYS5ybSA9IFRSVUUpKSkNCg0Ka25pdHI6OmthYmxlKHN1bW1hcnlfc3RhdGlzdGljcywgY2FwdGlvbiA9ICJEZXNrcmlwc2kgU3RhdGlzdGlrIEF3YWwiKQ0KYGBgDQoNCiMjIyA0LjIgVWppIFZhbGlkaXRhcyBkYW4gUmVsaWFiaWxpdGFzDQoNCiMjIyMgNC4yLjEgS29yZWxhc2kgSXRlbS1Ub3RhbA0KVW50dWsgbWVtZXJpa3NhIHZhbGlkaXRhcyBrb25zdHJ1aywga2l0YSBha2FuIG1lbmdoaXR1bmcga29yZWxhc2kgYW50YXJhIGl0ZW0gZGFuIHRvdGFsIHNrb3IgdW50dWsgc2V0aWFwIGthdGVnb3JpLg0KDQpgYGB7cn0NCiMgTWVuZ2hpdHVuZyBrb3JlbGFzaSBpdGVtLXRvdGFsIHVudHVrIGthdGVnb3JpIEtSUw0KY29yX2tycyA8LSBjb3IoZGF0YV9rcnMkS1JTX2Frc2VzLCBkYXRhX2tycyRLUlNfbWFzYWxhaCwgdXNlID0gImNvbXBsZXRlLm9icyIpDQpjb3Jfa3JzDQpgYGANCg0KIyMjIyA0LjIuMiBDcm9uYmFjaCdzIEFscGhhDQpLaXRhIGFrYW4gbWVuZ3VrdXIgcmVsaWFiaWxpdGFzIHNldGlhcCBrYXRlZ29yaSBtZW5nZ3VuYWthbiBDcm9uYmFjaCdzIEFscGhhLg0KYGBge3J9DQpsaWJyYXJ5KHBzeWNoKQ0KDQojIEZ1bmdzaSB1bnR1ayBtZW5naGl0dW5nIENyb25iYWNoJ3MgQWxwaGENCmNyb25iYWNoX2FscGhhIDwtIGZ1bmN0aW9uKGRhdGEpIHsNCiAgbnVtZXJpY19kYXRhIDwtIGRhdGFbc2FwcGx5KGRhdGEsIGlzLm51bWVyaWMpXQ0KICBkYXRhX2NsZWFuIDwtIG5hLm9taXQobnVtZXJpY19kYXRhKQ0KICBhbHBoYV9yZXN1bHQgPC0gcHN5Y2g6OmFscGhhKGRhdGFfY2xlYW4pDQogIHJldHVybihhbHBoYV9yZXN1bHQkdG90YWwkcmF3X2FscGhhKQ0KfQ0KDQojIE1lbmdoaXR1bmcgQ3JvbmJhY2gncyBBbHBoYSB1bnR1ayBrYXRlZ29yaSBLUlMNCmNyb25iYWNoX2tycyA8LSBjcm9uYmFjaF9hbHBoYShkYXRhX2tycykNCmNyb25iYWNoX2tycw0KYGBgDQoNCiMjIyA0LjMgUGVueWFqaWFuIEdyYWZpaw0KS2l0YSBha2FuIG1lbmdndW5ha2FuIGdyYWZpayB1bnR1ayBtZW5nZ2FtYmFya2FuIGRpc3RyaWJ1c2kgamF3YWJhbiBkYXJpIGJlYmVyYXBhIHBlcnRhbnlhYW4uDQoNCiMjIyMgMi4zLjEgSGlzdG9ncmFtIHVudHVrIEtSU19ha3Nlcw0KYGBge3J9DQojIE1lbWJ1YXQgaGlzdG9ncmFtIHVudHVrIG1lbGloYXQgZGlzdHJpYnVzaSBmcmVrdWVuc2kgdW50dWsgS1JTX2Frc2VzDQpsaWJyYXJ5KGdncGxvdDIpDQoNCmdncGxvdChkYXRhX3N1cnZlaSwgYWVzKHggPSBLUlNfYWtzZXMpKSArDQogIGdlb21fYmFyKGZpbGwgPSAic2t5Ymx1ZSIsIGNvbG9yID0gImJsYWNrIikgKw0KICBsYWJzKHRpdGxlID0gIkRpc3RyaWJ1c2kgSmF3YWJhbiBLUlMgQWtzZXMiLCB4ID0gIlNrYWxhIEtSUyBBa3NlcyIsIHkgPSAiRnJla3VlbnNpIikNCmBgYA0KDQojIyMjIDQuMy4yIEJveHBsb3QgdW50dWsgQmltYmluZ2FuX2t1YWxpdGFzDQpgYGB7cn0NCiMgTWVtYnVhdCBib3hwbG90IHVudHVrIEJpbWJpbmdhbl9rdWFsaXRhcw0KZ2dwbG90KGRhdGFfc3VydmVpLCBhZXMoeSA9IEJpbWJpbmdhbl9rdWFsaXRhcywgeCA9IDEpKSArDQogIGdlb21fYm94cGxvdChmaWxsID0gImxpZ2h0Z3JlZW4iLCBjb2xvciA9ICJibGFjayIpICsNCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidXNpIEtlcHVhc2FuIFRlcmhhZGFwIEJpbWJpbmdhbiBBa2FkZW1payIsIHkgPSAiS3VhbGl0YXMgQmltYmluZ2FuIiwgeCA9ICIiKQ0KYGBgDQoNCiMjIyA0LjQgS2VzaW1wdWxhbg0KQmVyZGFzYXJrYW4gYW5hbGlzaXMgZGF0YSBhd2FsLCBraXRhIGRhcGF0IG1lbnlpbXB1bGthbiBiYWh3YToNCg0KLSBMYXlhbmFuIEtSUyBPbmxpbmUgY2VuZGVydW5nIG1lbWlsaWtpIHRpbmdrYXQga2VwdWFzYW4geWFuZyBiZXJ2YXJpYXNpLCBkZW5nYW4gc2ViYWdpYW4gYmVzYXIgbWFoYXNpc3dhIG1lcmFzYSBrZXN1bGl0YW4gbWVuZ2Frc2VzIGF0YXUgbWVuZ2FsYW1pIG1hc2FsYWggdGVrbmlzLg0KDQotIEJpbWJpbmdhbiBBa2FkZW1payBtZW51bmp1a2thbiBrZXB1YXNhbiB5YW5nIGN1a3VwIGJhaWssIG5hbXVuIHRlcmRhcGF0IGtlbmRhbGEgZGFsYW0gaGFsIHdha3R1IGRhbiBha3Nlcy4NCg0KLSBQZWxheWFuYW4gYWRtaW5pc3RyYXNpIHVtdW1ueWEgZGlhbmdnYXAgY2VwYXQsIG1lc2tpcHVuIGFkYSBiZWJlcmFwYSBsYXBvcmFuIGtldGVybGFtYmF0YW4uDQoNCi0gQWtzZXMgaW5mb3JtYXNpIGFrYWRlbWlrIGp1Z2EgYmVydmFyaWFzaSwgZGVuZ2FuIGJlYmVyYXBhIG1haGFzaXN3YSBtZXJhc2Ega2VzdWxpdGFuIG1lbmVtdWthbiBpbmZvcm1hc2kgeWFuZyBkaXBlcmx1a2FuLg==