1 Mulai dari sebuah pertanyaan

Bayangkan kita diminta membaca peta kriminalitas suatu kota. Beberapa wilayah tampak memiliki angka tinggi dan letaknya berdekatan. Apakah pengelompokan itu cukup kuat untuk dibedakan dari susunan nilai yang acak? Setelah menjawabnya, kita memperluas pertanyaan: apakah kriminalitas suatu wilayah berkaitan dengan pendapatan wilayah di sekitarnya?

Kita akan mengikuti satu kasus dari awal sampai akhir: 49 lingkungan di Columbus, Ohio, menggunakan data tahun 1980 yang sudah tersedia dalam paket R. Ini contoh historis untuk belajar metode, bukan gambaran kondisi kota saat ini.

Alur berpikir praktikum
Pahami data → lihat peta → tentukan tetangga → buat bobot → uji pola global → cari pola lokal → perluas ke dua variabel → tulis kesimpulan.

install.packages(c("sf", "spdep", "spData", "ggplot2", "knitr", "rmarkdown"))

Internet diperlukan saat memasang paket. Datanya berasal dari paket lokal setelah instalasi. Instalasi sengaja tidak berjalan otomatis ketika Knit.

paket <- c("sf", "spdep", "spData", "ggplot2", "knitr", "rmarkdown")
belum_ada <- paket[!vapply(paket, requireNamespace, logical(1), quietly = TRUE)]
if (length(belum_ada) > 0) {
  stop("Pasang paket berikut melalui Console: ", paste(belum_ada, collapse = ", "))
}

library(sf)
library(spdep)
library(ggplot2)

B <- as.integer(params$nsim)
alpha <- params$alpha
stopifnot(B >= 99, alpha > 0, alpha < 1)
set.seed(2026)
spdep::set.coresOption(NULL)  # eksekusi berurutan; tidak memerlukan cluster

theme_set(theme_minimal(base_size = 12))
fmt <- function(x) formatC(as.numeric(x), digits = 3, format = "f")
fp <- function(p) format.pval(as.numeric(p), digits = 3, eps = 0.0001)
putusan <- function(p) {
  if (p < alpha) "menolak H0" else "belum dapat menolak H0"
}

library() membuka paket; B menyimpan banyaknya permutasi; alpha menjadi ambang pengujian. fmt() dan fp() hanya merapikan tampilan angka. Nilai alpha ditetapkan sebelum melihat hasil.

2 Mengenal data Columbus

Dataset Columbus merupakan data spasial mengenai 49 wilayah lingkungan (neighbourhoods) di Kota Columbus, Ohio, Amerika Serikat, pada tahun 1980. Data ini tersedia dalam paket R spData dan dapat digunakan untuk mempelajari pola suatu variabel serta hubungannya dengan kondisi wilayah di sekitarnya. Dokumentasi data Columbus.

Satu baris data mewakili satu wilayah, bukan satu penduduk atau satu rumah tangga. Setiap wilayah memiliki informasi karakteristik wilayah dan geometri berupa poligon yang menggambarkan batasnya. Jadi, kita dapat mengetahui bukan hanya nilai variabelnya, tetapi juga posisi wilayah dan siapa saja tetangganya.

2.1 Membaca data dan mengenali unit pengamatan

Dalam dataset Columbus, unit pengamatannya adalah wilayah lingkungan (neighbourhood). Artinya, setiap baris data mewakili satu wilayah dan memuat karakteristik wilayah tersebut, seperti angka kriminalitas (CRIME), pendapatan rumah tangga (INC), dan nilai rumah (HOVAL). Karena terdapat 49 wilayah yang diamati, dataset ini memiliki 49 baris.

Sebagai contoh, nilai CRIME, INC, dan HOVAL pada baris pertama semuanya merujuk pada wilayah yang sama. Baris kedua memuat informasi untuk wilayah lain, demikian seterusnya. Dengan demikian, analisis yang kita lakukan membandingkan karakteristik antarwilayah, bukan antarindividu.

Selain informasi dalam tabel, setiap baris juga terhubung dengan geometri berupa poligon, yaitu bentuk batas wilayah pada peta. Geometri ini memungkinkan kita menampilkan nilai variabel dalam peta dan menentukan wilayah mana yang saling bertetangga.

Langkah pertama praktikum adalah membaca data spasial Columbus dari paket spData dan menyimpannya dalam objek bernama col. Selanjutnya, kita memeriksa kelengkapan data, menambahkan nomor urut id untuk memudahkan penyebutan wilayah, dan menampilkan enam baris pertama untuk mengenali susunan datanya.

lokasi_data <- system.file("shapes/columbus.gpkg", package = "spData")
stopifnot(nzchar(lokasi_data))
col <- st_read(lokasi_data, quiet = TRUE)

# Dataset ini memakai koordinat lokal dengan satuan tidak diketahui.
# Simpan metadata aslinya; lepaskan label CRS untuk menggambar bidang lokal.
# Angka koordinat tidak diubah dan tidak direproyeksi ke bujur/lintang.
crs_asli <- st_crs(col)
col <- st_set_crs(col, NA)

# ID mengikuti urutan geometri, bukan urutan nilai CRIME.
col$id <- seq_len(nrow(col))
stopifnot(nrow(col) == 49, all(st_is_valid(col)))
stopifnot(all(is.finite(col$CRIME)), all(is.finite(col$INC)))

knitr::kable(
  head(st_drop_geometry(col)[, c("id", "NEIG", "CRIME", "INC", "HOVAL")]),
  digits = 2, caption = "Enam wilayah pertama; ID dipakai pada tabel dan peta modul."
)
Enam wilayah pertama; ID dipakai pada tabel dan peta modul.
id NEIG CRIME INC HOVAL
1 5 15.73 19.53 80.47
2 1 18.80 21.23 44.57
3 6 30.63 15.96 26.35
4 2 32.39 4.48 33.20
5 7 50.73 11.25 23.23
6 8 26.07 16.03 28.75
Kolom Arti Satuan
CRIME Pencurian rumah dan kendaraan dalam wilayah Per 1.000 rumah tangga
INC Pendapatan rumah tangga Ribuan dolar AS
HOVAL Nilai rumah; dipakai pada latihan tambahan Ribuan dolar AS
geometry Bentuk dan posisi batas wilayah Poligon
id Nomor baris yang kita buat Penanda, bukan variabel analisis

CRIME tidak mencakup semua jenis kejahatan. Istilah tinggi/rendah di modul bersifat relatif terhadap data ini. Metadata Columbus juga tidak menyediakan dasar yang cukup untuk menafsirkan jarak koordinat sebagai kilometer; karena itu kita memakai persinggungan batas wilayah. Metadata data Columbus.

Sebagai ilustrasi, CRIME = 30 berarti terdapat 30 kejadian pencurian rumah dan kendaraan per 1.000 rumah tangga. Angka ini merupakan ukuran relatif terhadap jumlah rumah tangga, bukan berarti 30% rumah tangga menjadi korban. Sementara itu, INC = 15 menunjukkan nilai pendapatan rumah tangga sebesar 15 ribu dolar AS pada ukuran yang dicatat dalam dataset.

Kita akan menggunakan data ini untuk menjawab dua pertanyaan secara bertahap:

  1. Autokorelasi spasial univariat: apakah wilayah dengan CRIME tinggi cenderung bertetangga dengan wilayah yang CRIME-nya juga tinggi?
  2. Asosiasi spasial bivariat: apakah wilayah dengan CRIME tinggi cenderung bertetangga dengan wilayah yang memiliki INC rendah?

Pada pertanyaan pertama, kita membandingkan variabel yang sama antarwilayah. Pada pertanyaan kedua, kita membandingkan dua variabel berbeda antarwilayah. Perbedaan inilah yang menjadi dasar perpindahan dari analisis univariat ke bivariat.

summary(st_drop_geometry(col)[, c("CRIME", "INC", "HOVAL")])
#>      CRIME              INC             HOVAL      
#>  Min.   : 0.1783   Min.   : 4.477   Min.   :17.90  
#>  1st Qu.:20.0485   1st Qu.: 9.963   1st Qu.:25.70  
#>  Median :34.0008   Median :13.380   Median :33.50  
#>  Mean   :35.1288   Mean   :14.375   Mean   :38.44  
#>  3rd Qu.:48.5855   3rd Qu.:18.324   3rd Qu.:43.30  
#>  Max.   :68.8920   Max.   :31.070   Max.   :96.40

2.2 Lihat peta sebelum menghitung indeks

Sebelum menghitung autokorelasi spasial, kita memetakan nilai CRIME untuk melihat persebaran kriminalitas antarwilayah. Warna pada peta menunjukkan besar nilainya: semakin mendekati kuning, semakin tinggi angka kriminalitas; semakin mendekati biru tua, semakin rendah.

# Dua peta terpisah menjaga legenda sesuai satuan masing-masing.
ggplot(col) +
  geom_sf(aes(fill = CRIME), color = "white", linewidth = 0.3) +
  scale_fill_viridis_c(option = "C", name = "CRIME") +
  labs(title = "Di mana kriminalitas relatif tinggi?", subtitle = "Columbus, 1980") +
  coord_sf(datum = NA) +
  theme_void() + theme(legend.position = "right")
Peta awal: kedua variabel memiliki legenda dan satuan yang berbeda.

Peta awal: kedua variabel memiliki legenda dan satuan yang berbeda.

Cara membaca: warna menunjukkan besarnya nilai. Wilayah yang tampak berdekatan dan berwarna mirip memberi dugaan pengelompokan. Kita masih memerlukan aturan tetangga dan uji statistik untuk menilai dugaan tersebut.

Secara visual, wilayah dengan angka kriminalitas relatif tinggi tampak berdekatan di bagian tengah peta, sedangkan nilai yang lebih rendah banyak ditemukan di bagian tepi. Pola ini memberi dugaan awal adanya pengelompokan spasial, yang selanjutnya perlu diperiksa melalui uji autokorelasi spasial.

ggplot(col) +
  geom_sf(aes(fill = INC), color = "white", linewidth = 0.3) +
  scale_fill_viridis_c(option = "D", name = "INC") +
  labs(title = "Bagaimana pola pendapatan rumah tangga?", subtitle = "Columbus, 1980") +
  coord_sf(datum = NA) +
  theme_void() + theme(legend.position = "right")

Peta menunjukkan bahwa pendapatan rumah tangga (INC) relatif rendah, ditandai warna ungu hingga biru, banyak ditemukan di bagian tengah. Pendapatan relatif tinggi, ditandai warna hijau hingga kuning, tampak pada beberapa wilayah di bagian tepi, terutama sisi kanan peta.

Dibandingkan dengan peta CRIME, terlihat kecenderungan bahwa wilayah berpendapatan rendah memiliki kriminalitas lebih tinggi. Namun, pengamatan visual ini belum membuktikan hubungan statistik, khususnya antara kriminalitas suatu wilayah dan pendapatan wilayah tetangganya.

Berhenti sejenak. Pilih satu bagian peta dengan CRIME relatif tinggi. Apakah tetangganya tampak serupa? Simpan dugaanmu untuk dibandingkan dengan hasil Moran.

3 Apa arti “bertetangga”?

3.1 Queen contiguity dan bobot spasial

Analisis spasial memerlukan definisi ketetanggaan untuk menentukan hubungan antarwilayah. Salah satu pendekatannya adalah Queen contiguity, yaitu dua wilayah dianggap bertetangga apabila berbagi sisi atau titik sudut. Sebagai pembanding, Rook contiguity hanya menganggap dua wilayah bertetangga apabila berbagi sisi.

Dalam praktikum ini, hubungan ketetanggaan ditentukan menggunakan Queen contiguity, kemudian dinyatakan dalam bobot spasial. Bobot tersebut menentukan kontribusi setiap wilayah tetangga dalam perhitungan statistik spasial.

nb <- poly2nb(col, queen = TRUE, row.names = as.character(col$id))
jumlah_tetangga <- card(nb)
summary(jumlah_tetangga)
#>    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
#>   2.000   3.000   4.000   4.816   6.000  10.000
stopifnot(all(jumlah_tetangga > 0))

lw_B <- nb2listw(nb, style = "B", zero.policy = FALSE)
lw_W <- nb2listw(nb, style = "W", zero.policy = FALSE)
W <- listw2mat(lw_W)

stopifnot(all(diag(W) == 0), all(abs(rowSums(W) - 1) < 1e-10))
data.frame(
  wilayah = nrow(col),
  pasangan_tetangga_unik = sum(jumlah_tetangga) / 2,
  minimum_tetangga = min(jumlah_tetangga),
  maksimum_tetangga = max(jumlah_tetangga)
)
#>   wilayah pasangan_tetangga_unik minimum_tetangga maksimum_tetangga
#> 1      49                    118                2                10

Berdasarkan Queen contiguity, terdapat 118 pasangan wilayah bertetangga pada 49 wilayah Columbus. Setiap wilayah memiliki 2–10 tetangga, dengan rata-rata sekitar 4,82 tetangga. Dengan demikian, seluruh wilayah memiliki tetangga dan tidak terdapat wilayah yang terisolasi. Setiap pasangan dihitung sekali; hubungan wilayah A–B sama dengan B–A.

Daftar ketetanggaan disimpan dalam objek nb, kemudian digunakan untuk membentuk dua jenis bobot:

  • Bobot biner (lw_B): bernilai 1 untuk wilayah yang bertetangga dan 0 untuk wilayah yang tidak bertetangga.
  • Bobot terstandardisasi per baris (lw_W): bobot setiap tetangga dibagi dengan jumlah tetangga wilayah asal, sehingga total bobot pada setiap baris menjadi 1. Sebagai contoh, jika suatu wilayah memiliki empat tetangga, setiap tetangganya memperoleh bobot ¼.

Matriks W merupakan bentuk matriks dari lw_W. Elemen diagonalnya bernilai nol karena wilayah tidak dianggap sebagai tetangga bagi dirinya sendiri. Pemeriksaan melalui stopifnot() memastikan bahwa kondisi tersebut terpenuhi sebelum analisis dilanjutkan.

titik <- st_coordinates(st_centroid(st_geometry(col)))
plot(st_geometry(col), col = "#f0f5f7", border = "#8195a1", main = "Siapa bertetangga dengan siapa?")
plot(nb, titik, add = TRUE, col = "#25858e", pch = 19, cex = 0.45)
Garis menunjukkan hubungan Queen antarwilayah, bukan jaringan jalan.

Garis menunjukkan hubungan Queen antarwilayah, bukan jaringan jalan.

Gambar menunjukkan hubungan ketetanggaan antarwilayah berdasarkan Queen contiguity. Setiap titik mewakili pusat geometris (centroid) suatu wilayah, sedangkan garis menghubungkan dua wilayah yang berbagi sisi atau titik sudut.

Jumlah garis yang terhubung pada suatu titik menunjukkan banyaknya tetangga wilayah tersebut. Seluruh wilayah memiliki hubungan ketetanggaan sehingga tidak terdapat wilayah yang terisolasi. Garis pada gambar menunjukkan hubungan spasial, bukan jaringan jalan maupun kemiripan nilai kriminalitas.

3.2 Spatial lag: ringkasan nilai tetangga

Spatial lag digunakan untuk merangkum nilai suatu variabel di wilayah-wilayah tetangga. Pada contoh ini, kita menghitung rata-rata angka kriminalitas tetangga menggunakan bobot yang sudah dibuat.

Karena setiap tetangga mendapat bobot yang sama, perhitungannya cukup dengan merata-ratakan nilai CRIME seluruh tetangga. Nilai CRIME wilayah yang sedang diamati tidak ikut dihitung.

\[ (Wx)_i = \sum_j w_{ij}x_j. \]

x <- col$CRIME
y <- col$INC
n <- length(x)
lag_x <- lag.listw(lw_W, x)

i <- 1L
j <- nb[[i]]
knitr::kable(data.frame(
  id_tetangga = col$id[j], CRIME_tetangga = x[j], bobot = lw_W$weights[[i]]
), digits = 3, caption = paste("Tetangga wilayah ID", col$id[i]))
Tetangga wilayah ID 1
id_tetangga CRIME_tetangga bobot
2 18.802 0.5
3 30.627 0.5

c(CRIME_lokasi = x[i],
  rata_rata_manual = mean(x[j]),
  lag_dari_R = lag_x[i])
#>     CRIME_lokasi rata_rata_manual       lag_dari_R 
#>         15.72598         24.71427         24.71427
stopifnot(isTRUE(all.equal(mean(x[j]), lag_x[i])))

Wilayah ID 1 bertetangga dengan wilayah ID 2 dan ID 3. Angka kriminalitas kedua tetangganya adalah 18,802 dan 30,627, sehingga rata-ratanya sekitar 24,714 per 1.000 rumah tangga. Nilai rata-rata inilah yang disebut spatial lag CRIME untuk wilayah ID 1.

Sementara itu, angka kriminalitas wilayah ID 1 sendiri adalah 15,726 per 1.000 rumah tangga. Jadi, angka kriminalitas wilayah ID 1 lebih rendah daripada rata-rata tetangganya. Hasil perhitungan manual dan fungsi lag.listw() menunjukkan nilai yang sama.

4 Autokorelasi spasial global: satu variabel

Autokorelasi spasial global digunakan untuk melihat apakah nilai suatu variabel membentuk pola tertentu di seluruh wilayah yang diamati. Pada data Columbus, kita ingin mengetahui apakah wilayah dengan angka kriminalitas tinggi cenderung berdekatan dengan wilayah yang juga memiliki angka kriminalitas tinggi.

Pola hubungan antarwilayah dapat berupa:

  • Autokorelasi positif: wilayah dengan nilai tinggi cenderung bertetangga dengan wilayah bernilai tinggi, begitu pula wilayah bernilai rendah dengan wilayah bernilai rendah.
  • Autokorelasi negatif: wilayah dengan nilai tinggi cenderung bertetangga dengan wilayah bernilai rendah, dan sebaliknya.

Istilah global berarti hasil analisis menggambarkan pola secara keseluruhan, belum menunjukkan wilayah mana yang membentuk pola tersebut. Untuk menilai apakah pola yang terlihat didukung secara statistik, kita menggunakan uji autokorelasi spasial.

Beberapa metode yang dapat digunakan adalah Join Count, Moran’s I, Geary’s C, dan Getis–Ord G. Pemilihan metode disesuaikan dengan jenis data dan pertanyaan analisis, seperti dirangkum dalam tabel berikut.

Global berarti kita merangkum seluruh wilayah menjadi sebuah statistik. Berikut pertanyaan yang membedakan metodenya.

Metode Jenis nilai Pertanyaan utama Bagian output yang dibaca
Join Count Kategori Apakah kategori sama sering bertetangga? Jumlah pasangan dan p-value
Moran’s I Numerik Apakah nilai serupa mengelompok? I, nilai harapan, p-value
Geary’s C Numerik Apakah selisih nilai tetangga kecil? C, p-value
Getis–Ord G Numerik nonnegatif Apakah nilai tinggi/rendah mengelompok? G relatif nilai harapan, Z, p-value

4.1 A. Join Count: mulai dari kategori

Join Count digunakan untuk mengetahui apakah wilayah dengan kategori yang sama cenderung bertetangga. Pada contoh ini, nilai CRIME dibagi menjadi dua kategori: Tinggi jika nilainya melebihi median dan Rendah jika nilainya kurang dari atau sama dengan median.

Selanjutnya, kita menghitung pasangan wilayah bertetangga yang sama-sama berkategori Tinggi atau sama-sama berkategori Rendah. Jumlah pasangan tersebut dibandingkan dengan jumlah yang diharapkan jika kategori tersebar secara acak.

Hipotesis yang digunakan untuk setiap kategori adalah:

  • H₀: kategori tersebar secara acak, dengan jumlah wilayah pada setiap kategori tetap.
  • H₁: pasangan wilayah dengan kategori yang sama lebih banyak daripada yang diharapkan jika tersebar secara acak.

Argumen alternative = "greater" digunakan karena kita ingin menguji apakah jumlah pasangan tersebut lebih banyak dari harapan.

kategori <- factor(
  ifelse(x > median(x), "Tinggi", "Rendah"),
  levels = c("Rendah", "Tinggi")
)
table(kategori)
#> kategori
#> Rendah Tinggi 
#>     25     24
jc <- joincount.test(kategori, lw_B, alternative = "greater", sampling = "nonfree")
jc
#> 
#>  Join count test under nonfree sampling
#> 
#> data:  kategori 
#> weights: lw_B 
#> 
#> Std. deviate for Rendah = 1.1164, p-value = 0.1321
#> alternative hypothesis: greater
#> sample estimates:
#> Same colour statistic           Expectation              Variance 
#>              35.00000              30.10204              19.24708 
#> 
#> 
#>  Join count test under nonfree sampling
#> 
#> data:  kategori 
#> weights: lw_B 
#> 
#> Std. deviate for Tinggi = 6.163, p-value = 3.57e-10
#> alternative hypothesis: greater
#> sample estimates:
#> Same colour statistic           Expectation              Variance 
#>              54.00000              27.69388              18.21936

ringkas_jc <- data.frame(
  kategori = levels(kategori),
  pasangan_teramati = vapply(jc, function(a) unname(a$estimate[1]), numeric(1)),
  harapan_H0 = vapply(jc, function(a) unname(a$estimate[2]), numeric(1)),
  p_value = vapply(jc, function(a) a$p.value, numeric(1))
)
knitr::kable(ringkas_jc, digits = 4, row.names = FALSE)
kategori pasangan_teramati harapan_H0 p_value
Rendah 35 30.1020 0.1321
Tinggi 54 27.6939 0.0000

Hasil pembagian berdasarkan median menghasilkan 25 wilayah berkategori Rendah dan 24 wilayah berkategori Tinggi. Pada taraf signifikansi 5%, hasil Join Count menunjukkan:

  • Kategori Tinggi: terdapat 54 pasangan wilayah bertetangga, lebih banyak daripada harapan sekitar 27,694 pasangan. Nilai p sebesar 3,57 × 10⁻¹⁰, lebih kecil dari 0,05, sehingga H₀ ditolak. Artinya, wilayah dengan kriminalitas tinggi cenderung mengelompok.
  • Kategori Rendah: terdapat 35 pasangan wilayah bertetangga, dibandingkan harapan sekitar 30,102 pasangan. Nilai p sebesar 0,1321, lebih besar dari 0,05, sehingga H₀ belum dapat ditolak. Bukti pengelompokan wilayah dengan kriminalitas rendah belum cukup.

Angka 0,0000 pada tabel merupakan hasil pembulatan p-value yang sangat kecil, bukan berarti p-value tepat nol. Kategori Tinggi dan Rendah pada analisis ini bersifat relatif terhadap median data.

4.2 B. Moran’s I: apakah nilai serupa mengelompok?

Moran’s I digunakan untuk mengetahui apakah wilayah dengan nilai yang mirip cenderung bertetangga. Pada analisis ini, kita menggunakan nilai CRIME asli tanpa membaginya menjadi kategori.

Pertanyaan yang ingin dijawab adalah: apakah wilayah dengan kriminalitas tinggi cenderung berdekatan dengan wilayah yang juga memiliki kriminalitas tinggi, begitu pula untuk nilai yang rendah?

Hipotesis yang digunakan adalah:

  • H₀: nilai CRIME tersebar secara acak di antara wilayah.
  • H₁: terdapat autokorelasi spasial positif, yaitu nilai CRIME yang mirip cenderung mengelompok.

Pengujian dilakukan melalui dua pendekatan. Fungsi moran.test() menggunakan pendekatan distribusi teoretis, sedangkan moran.mc() membandingkan hasil pengamatan dengan hasil pengacakan nilai CRIME antarlokasi. Argumen alternative = "greater" digunakan untuk menguji pengelompokan nilai yang serupa.

\[ I=\frac{n}{S_0}\frac{\sum_i\sum_j w_{ij}(x_i-\bar{x})(x_j-\bar{x})} {\sum_i(x_i-\bar{x})^2},\qquad S_0=\sum_i\sum_jw_{ij}. \]

moran_analitik <- moran.test(x, lw_W, alternative = "greater", randomisation = TRUE)
set.seed(2026)
moran_perm <- moran.mc(x, lw_W, nsim = B, alternative = "greater")

moran_analitik
#> 
#>  Moran I test under randomisation
#> 
#> data:  x  
#> weights: lw_W    
#> 
#> Moran I statistic standard deviate = 5.5894, p-value = 1.139e-08
#> alternative hypothesis: greater
#> sample estimates:
#> Moran I statistic       Expectation          Variance 
#>       0.500188557      -0.020833333       0.008689289
moran_perm
#> 
#>  Monte-Carlo simulation of Moran I
#> 
#> data:  x 
#> weights: lw_W  
#> number of simulations + 1: 10000 
#> 
#> statistic = 0.50019, observed rank = 10000, p-value = 1e-04
#> alternative hypothesis: greater
I_obs <- unname(moran_perm$statistic)
EI <- -1 / (n - 1)

Hasil analisis menunjukkan Moran’s I sebesar 0,5002, lebih tinggi daripada nilai harapannya jika pola acak, yaitu −0,0208. Hasil ini menunjukkan kecenderungan wilayah dengan angka kriminalitas yang mirip untuk bertetangga.

P-value uji analitik sebesar 1,139 × 10⁻⁸, sedangkan p-value dari 9.999 permutasi sebesar 0,0001. Keduanya lebih kecil dari 0,05, sehingga H₀ ditolak.

Dengan demikian, terdapat bukti autokorelasi spasial positif pada CRIME: secara keseluruhan, wilayah dengan kriminalitas tinggi cenderung berdekatan dengan wilayah bernilai tinggi, dan wilayah bernilai rendah dengan wilayah bernilai rendah. Hasil global ini belum menunjukkan lokasi klaster tertentu; untuk mengetahuinya, diperlukan analisis lokal.

4.2.1 Mengapa memakai permutasi?

Uji permutasi membantu menilai apakah pengelompokan yang ditemukan dapat dijelaskan oleh penempatan nilai secara acak. Caranya, nilai CRIME dipindahkan secara acak antarwilayah, kemudian Moran’s I dihitung kembali. Nilai datanya tetap sama, sedangkan letaknya berubah; hubungan ketetanggaan juga tetap dipertahankan.

Proses ini diulang sebanyak 9.999 kali. Hasilnya digunakan sebagai pembanding untuk mengetahui apakah Moran’s I dari data asli jauh lebih tinggi daripada hasil pengacakan.

sim_I <- moran_perm$res[seq_len(B)]
hist(sim_I, breaks = 30, col = "#acd4dc", border = "white",
     main = "Apakah pola teramati lazim pada peta acak?",
     xlab = "Moran's I dari permutasi",
     xlim = range(c(sim_I, I_obs)))
abline(v = I_obs, col = "#b83248", lwd = 3)
legend("topright", legend = paste("I teramati =", fmt(I_obs)),
       col = "#b83248", lwd = 3, bty = "n")
Garis merah adalah Moran teramati; histogram adalah hasil pengacakan nilai CRIME.

Garis merah adalah Moran teramati; histogram adalah hasil pengacakan nilai CRIME.

Histogram menunjukkan sebaran Moran’s I dari hasil pengacakan, yang sebagian besar berada di sekitar nol. Garis merah menunjukkan Moran’s I data asli, yaitu sekitar 0,500, yang berada jauh di sebelah kanan sebaran tersebut.

Artinya, pengelompokan pada data asli jauh lebih kuat daripada yang dihasilkan oleh pengacakan. Hasil ini sejalan dengan p-value 0,0001, sehingga pada taraf signifikansi 5% terdapat bukti bahwa wilayah dengan nilai CRIME yang mirip cenderung mengelompok.

4.3 C. Geary’s C: lihat perbedaan antartetangga

Geary’s C digunakan untuk melihat kemiripan nilai antarwilayah yang bertetangga berdasarkan selisih nilainya. Jika angka kriminalitas suatu wilayah dan tetangganya hampir sama, selisihnya kecil dan nilai Geary’s C cenderung rendah.

Nilai C dibaca dengan acuan berikut:

  • C < 1: wilayah yang bertetangga cenderung memiliki nilai serupa.
  • C > 1: wilayah yang bertetangga cenderung memiliki nilai berbeda.
  • C mendekati 1: mendekati nilai yang diharapkan pada pola acak.

Pada contoh ini, H₀ menyatakan nilai CRIME tersebar secara acak, sedangkan H₁ menyatakan wilayah dengan nilai serupa cenderung mengelompok. P-value digunakan untuk menilai apakah bukti pengelompokan tersebut cukup kuat.

geary_hasil <- geary.test(x, lw_W, alternative = "greater", randomisation = TRUE)
geary_hasil
#> 
#>  Geary C test under randomisation
#> 
#> data:  x 
#> weights: lw_W   
#> 
#> Geary C statistic standard deviate = 4.7431, p-value = 1.053e-06
#> alternative hypothesis: Expectation greater than statistic
#> sample estimates:
#> Geary C statistic       Expectation          Variance 
#>       0.540528203       1.000000000       0.009384264
C_obs <- unname(geary_hasil$estimate[1])

Hasil analisis menunjukkan Geary’s C sebesar 0,541, lebih kecil dari nilai harapannya, yaitu 1. Artinya, angka kriminalitas antarwilayah yang bertetangga cenderung serupa.

P-value sebesar 1,053 × 10⁻⁶, lebih kecil dari 0,05, sehingga H₀ ditolak. Dengan demikian, terdapat bukti autokorelasi spasial positif pada CRIME. Kesimpulan ini sejalan dengan hasil Moran’s I sebelumnya, yaitu nilai kriminalitas yang serupa cenderung mengelompok.

Pada fungsi geary.test(), argumen alternative = "greater" digunakan untuk menguji autokorelasi positif, yang ditunjukkan oleh C lebih kecil dari 1. Jadi, argumen tersebut tidak berarti menguji apakah C lebih besar dari 1.

4.4 D. Getis–Ord G global: konsentrasi nilai tinggi

Getis–Ord G global digunakan untuk menilai pengelompokan nilai tinggi atau rendah secara keseluruhan. Pada contoh ini, kita ingin mengetahui apakah wilayah dengan angka kriminalitas tinggi cenderung saling berdekatan.

Analisis menggunakan nilai CRIME asli dan bobot biner, dengan hipotesis:

  • H₀: nilai CRIME tersebar secara acak antarwilayah.
  • H₁: nilai CRIME yang tinggi mengelompok lebih kuat daripada yang diharapkan pada pola acak.

Argumen alternative = "greater" digunakan karena pengujian difokuskan pada pengelompokan nilai tinggi.

stopifnot(all(x >= 0))
G_global <- globalG.test(x, lw_B, alternative = "greater")
G_global
#> 
#>  Getis-Ord global G statistic
#> 
#> data:  x 
#> weights: lw_B   
#> 
#> standard deviate = 4.6382, p-value = 1.758e-06
#> alternative hypothesis: greater
#> sample estimates:
#> Global G statistic        Expectation           Variance 
#>       1.278075e-01       1.003401e-01       3.507057e-05

Hasil analisis menunjukkan G sebesar 0,1278, lebih besar daripada nilai harapannya pada pola acak, yaitu 0,1003. Nilai Z sebesar 4,638 menunjukkan bahwa G teramati berada di atas nilai harapan tersebut.

P-value sebesar 1,758 × 10⁻⁶, lebih kecil dari 0,05, sehingga H₀ ditolak. Dengan demikian, terdapat bukti bahwa wilayah dengan angka kriminalitas tinggi cenderung saling berdekatan atau mengelompok.

Hasil ini menggambarkan pola secara keseluruhan. Untuk mengetahui wilayah mana yang membentuk pengelompokan tersebut, analisis perlu dilanjutkan dengan statistik lokal.

5 Autokorelasi spasial lokal: di mana polanya?

5.1 Local Moran’s I dan empat kuadran

Analisis global menunjukkan adanya pengelompokan kriminalitas secara keseluruhan. Selanjutnya, Local Moran’s I digunakan untuk menilai pola pada setiap wilayah dengan membandingkan angka kriminalitas wilayah tersebut dan tetangganya.

Sebagai langkah awal, nilai CRIME diubah menjadi skor baku (z). Nilai z positif berarti angka kriminalitas berada di atas rata-rata seluruh wilayah, sedangkan nilai z negatif berarti berada di bawah rata-rata. Kemudian, kita menghitung rata-rata skor baku tetangganya (spatial lag).

Berdasarkan kedua nilai tersebut, setiap wilayah dikelompokkan ke dalam empat kuadran: High–High (HH), Low–Low (LL), High–Low (HL), dan Low–High (LH). Pengelompokan ini membantu mengenali pola awal sebelum dilakukan uji signifikansi.

zx <- as.numeric(scale(x))
zy <- as.numeric(scale(y))
wzx <- lag.listw(lw_W, zx)
wzy <- lag.listw(lw_W, zy)

# Fungsi buatan modul; dipakai kembali untuk kasus bivariat.
kuadran <- function(nilai_lokasi, nilai_tetangga) {
  ifelse(nilai_lokasi == 0 | nilai_tetangga == 0, "Pada batas",
    ifelse(nilai_lokasi > 0 & nilai_tetangga > 0, "HH",
      ifelse(nilai_lokasi < 0 & nilai_tetangga < 0, "LL",
        ifelse(nilai_lokasi > 0 & nilai_tetangga < 0, "HL", "LH"))))
}
q_uni <- kuadran(zx, wzx)
table(q_uni)
#> q_uni
#> HH HL LH LL 
#> 21  3  5 20

Pada grafik, setiap titik mewakili satu wilayah. Sumbu horizontal menunjukkan skor baku CRIME wilayah tersebut, sedangkan sumbu vertikal menunjukkan rata-rata skor baku CRIME tetangganya. Garis nol memisahkan nilai di atas dan di bawah rata-rata.

Hasil pembagian kuadran menunjukkan:

Kuadran Jumlah wilayah Interpretasi
HH 21 Kriminalitas wilayah tinggi dan rata-rata kriminalitas tetangganya juga tinggi.
LL 20 Kriminalitas wilayah rendah dan rata-rata kriminalitas tetangganya juga rendah.
HL 3 Kriminalitas wilayah tinggi, tetapi rata-rata kriminalitas tetangganya rendah.
LH 5 Kriminalitas wilayah rendah, tetapi rata-rata kriminalitas tetangganya tinggi.

Sebagian besar wilayah berada pada kuadran HH dan LL, sehingga nilai kriminalitas wilayah cenderung sejalan dengan nilai tetangganya. Pola ini sesuai dengan garis yang menanjak dan hasil Moran’s I global yang positif.

Namun, posisi pada kuadran belum menunjukkan bahwa pola suatu wilayah signifikan. Uji Local Moran diperlukan untuk menilai apakah pola tersebut cukup kuat dibandingkan dengan hasil pengacakan.

ggplot(data.frame(zx, wzx, kuadran = q_uni), aes(zx, wzx, color = kuadran)) +
  geom_hline(yintercept = 0, color = "grey65") +
  geom_vline(xintercept = 0, color = "grey65") +
  geom_point(size = 2.5) +
  geom_abline(intercept = 0, slope = I_obs, color = "#183f56", linewidth = 0.8) +
  scale_color_manual(values = c(HH = "#b83248", LL = "#2878ad", HL = "#e8a23d", LH = "#58b6b1")) +
  labs(title = "Moran scatterplot: CRIME dengan CRIME tetangga",
       x = "z CRIME lokasi", y = "Wz CRIME tetangga", color = "Kuadran")

5.1.1 Jalankan uji lokal

Setelah mengenali kuadran setiap wilayah, kita melakukan uji Local Moran’s I untuk menilai apakah pola tersebut signifikan secara statistik.

Pengujian dilakukan dengan mempertahankan nilai CRIME wilayah yang sedang diperiksa, lalu mengacak nilai dari wilayah lain untuk mengisi posisi tetangganya. Hasil pengamatan dibandingkan dengan hasil pengacakan tersebut. Uji dua sisi digunakan agar dapat mendeteksi pola nilai yang serupa maupun berbeda dengan tetangga.

Karena pengujian dilakukan pada banyak wilayah sekaligus, p-value juga disesuaikan menggunakan metode Benjamini–Hochberg (BH). Penyesuaian ini membantu mengurangi temuan signifikan yang muncul secara kebetulan akibat banyaknya pengujian.

lisa <- localmoran_perm(
  x, lw_W, nsim = B, alternative = "two.sided",
  mlvar = FALSE, iseed = 2026, no_repeat_in_row = TRUE
)
colnames(lisa)
#> [1] "Ii"                 "E.Ii"               "Var.Ii"             "Z.Ii"              
#> [5] "Pr(z != E(Ii))"     "Pr(z != E(Ii)) Sim" "Pr(folded) Sim"     "Skewness"          
#> [9] "Kurtosis"
p_uni <- lisa[, "Pr(z != E(Ii)) Sim"]
p_uni_BH <- p.adjust(p_uni, method = "BH")
stopifnot(max(abs(lisa[, "Ii"] - zx * wzx)) < 1e-8)

hasil_uni <- data.frame(
  id = col$id, CRIME = x, lag_CRIME = lag_x,
  Ii = lisa[, "Ii"], kuadran = q_uni,
  p_permutasi = p_uni, p_BH = p_uni_BH
)
knitr::kable(head(hasil_uni[order(hasil_uni$p_permutasi), ], 8), digits = 4,
             caption = "Delapan p-value lokal terkecil; ini bukan peringkat risiko wilayah.")
Delapan p-value lokal terkecil; ini bukan peringkat risiko wilayah.
id CRIME lag_CRIME Ii kuadran p_permutasi p_BH
24 24 38.2979 54.9056 0.2239 HH 0.0006 0.0229
16 16 54.8387 52.3655 1.2135 HH 0.0010 0.0229
29 29 60.7504 51.7907 1.5249 HH 0.0014 0.0229
25 25 61.2992 49.9713 1.3874 HH 0.0032 0.0392
32 32 19.1456 13.8547 1.2146 LL 0.0050 0.0490
28 28 56.9198 47.4242 0.9570 HH 0.0088 0.0719
37 37 42.4451 50.9942 0.4146 HH 0.0114 0.0798
36 36 14.3056 18.7549 1.2179 LL 0.0136 0.0833

Tabel menampilkan delapan wilayah dengan p-value permutasi terkecil. Kolom Ii menunjukkan nilai Local Moran, kuadran menunjukkan jenis pola, sedangkan p_permutasi dan p_BH menunjukkan p-value sebelum dan sesudah penyesuaian BH.

Pada taraf signifikansi 5%, lima wilayah dalam tabel tetap signifikan setelah penyesuaian BH:

  • ID 24, 16, 29, dan 25 memiliki pola HH. Angka kriminalitas wilayah tersebut berada di atas rata-rata, begitu pula rata-rata angka kriminalitas tetangganya.
  • ID 32 memiliki pola LL. Angka kriminalitas wilayah tersebut berada di bawah rata-rata, begitu pula rata-rata angka kriminalitas tetangganya.

Sementara itu, ID 28, 37, dan 36 signifikan berdasarkan p-value awal, tetapi tidak lagi signifikan setelah penyesuaian BH karena p_BH > 0,05. Artinya, bukti pola lokal pada ketiga wilayah tersebut belum cukup setelah memperhitungkan banyaknya pengujian.

5.1.2 Banyak uji memerlukan perhatian

Uji Local Moran dilakukan pada 49 wilayah. Ketika banyak pengujian dilakukan sekaligus, sebagian hasil dapat terlihat signifikan hanya karena kebetulan. Oleh karena itu, p-value disesuaikan menggunakan metode Benjamini–Hochberg (BH) untuk membantu mengendalikan temuan tersebut.

Kita kemudian membandingkan dua peta: peta berdasarkan p-value awal dan peta berdasarkan p-value setelah penyesuaian BH. Wilayah diberi warna sesuai kuadrannya jika p-value yang digunakan lebih kecil dari 0,05. Wilayah lainnya ditampilkan dengan warna abu-abu. kontrol yang lebih konservatif terhadap ketergantungan umum.

warna_pola <- c(
  HH = "#b83248", LL = "#2878ad", HL = "#e8a23d", LH = "#58b6b1",
  "Belum signifikan" = "#e1e6e9", "Pada batas" = "#adb8bf"
)
label_signifikan <- function(q, p) {
  factor(ifelse(p < alpha, q, "Belum signifikan"), levels = names(warna_pola))
}
peta_pola <- function(q, p, judul, subjudul) {
  tmp <- col
  tmp$pola <- label_signifikan(q, p)
  ggplot(tmp) +
    geom_sf(aes(fill = pola), color = "white", linewidth = 0.3) +
    scale_fill_manual(values = warna_pola, drop = FALSE, name = "Pola") +
    labs(title = judul, subtitle = subjudul) +
    coord_sf(datum = NA) +
  theme_void() + theme(legend.position = "bottom", plot.title = element_text(size = 14))
}

peta_pola(q_uni, p_uni, "Local Moran: CRIME", "Eksplorasi | p permutasi mentah")

peta_pola(q_uni, p_uni_BH, "Local Moran: CRIME", "Pembanding | p disesuaikan BH")

Pada peta pertama, terdapat 15 wilayah dengan pola lokal yang signifikan berdasarkan p-value awal. Pola HH berwarna merah terutama terlihat di bagian tengah, sedangkan pola LL berwarna biru terlihat pada beberapa wilayah di bagian tepi.

Setelah penyesuaian BH, terdapat 5 wilayah yang tetap signifikan, yaitu 4 wilayah berpola HH dan 1 wilayah berpola LL. Artinya, bukti pengelompokan pada kelima wilayah tersebut tetap cukup kuat setelah memperhitungkan banyaknya pengujian.

Wilayah yang berubah menjadi abu-abu tidak berarti kehilangan pola atau mengalami perubahan kriminalitas. Yang berubah adalah keputusan statistiknya: bukti yang tersedia belum cukup untuk menyatakan pola lokalnya signifikan setelah penyesuaian BH.

5.2 Getis–Ord Gi: konsentrasi tinggi dan rendah secara lokal

Getis–Ord Gi digunakan untuk mencari wilayah yang lingkungan tetangganya memiliki konsentrasi nilai tinggi (hotspot) atau nilai rendah (coldspot). Pada contoh ini, kita memeriksa konsentrasi angka kriminalitas di sekitar setiap wilayah.

Fungsi localG() menghasilkan nilai Z. Z positif menunjukkan kecenderungan konsentrasi nilai tinggi, sedangkan Z negatif menunjukkan kecenderungan konsentrasi nilai rendah. Namun, penetapan hotspot atau coldspot juga harus mempertimbangkan p-value.

Pengujian menggunakan pendekatan normal dua sisi, kemudian p-value disesuaikan dengan metode BH karena banyak wilayah diuji sekaligus.

Gi_z <- as.numeric(localG(x, lw_B))
Gi_p <- 2 * pnorm(-abs(Gi_z))   # pendekatan normal, dua sisi
Gi_p_BH <- p.adjust(Gi_p, method = "BH")

col$Gi_pola <- factor(
  ifelse(Gi_p_BH >= alpha, "Belum signifikan",
         ifelse(Gi_z > 0, "Hotspot", "Coldspot")),
  levels = c("Hotspot", "Coldspot", "Belum signifikan")
)
ggplot(col) +
  geom_sf(aes(fill = Gi_pola), color = "white", linewidth = 0.3) +
  scale_fill_manual(values = c(Hotspot = "#b83248", Coldspot = "#2878ad",
                              "Belum signifikan" = "#e1e6e9"), drop = FALSE) +
  labs(title = "Getis–Ord Gi: konsentrasi CRIME di tetangga",
       subtitle = "Uji normal dua sisi; p disesuaikan BH", fill = "Pola") +
  coord_sf(datum = NA) +
  theme_void() + theme(legend.position = "bottom")


knitr::kable(head(data.frame(id = col$id, Z_Gi = Gi_z, p = Gi_p, p_BH = Gi_p_BH)), digits = 4)
id Z_Gi p p_BH
1 -0.9378 0.3483 0.5147
2 -0.9857 0.3243 0.4966
3 -0.7184 0.4725 0.6093
4 -0.0667 0.9469 0.9522
5 1.0471 0.2950 0.4819
6 0.4547 0.6493 0.8158

Pada taraf signifikansi 5%, terdapat 4 wilayah yang teridentifikasi sebagai hotspot setelah penyesuaian BH. Wilayah tersebut ditampilkan dengan warna merah di bagian tengah peta. Artinya, lingkungan tetangga keempat wilayah itu memiliki konsentrasi angka kriminalitas tinggi yang signifikan.

Tidak terdapat coldspot yang signifikan setelah penyesuaian BH. Wilayah berwarna abu-abu menunjukkan bahwa bukti konsentrasi nilai tinggi maupun rendah belum cukup, bukan berarti wilayah tersebut pasti memiliki kriminalitas rendah.

Tabel hanya menampilkan enam wilayah pertama. Seluruhnya memiliki p_BH > 0,05, sehingga belum dapat dinyatakan sebagai hotspot atau coldspot meskipun nilai Z-nya positif atau negatif.

Perbedaan Gi dan Gi* terletak pada nilai yang disertakan dalam perhitungan:

  • Gi hanya menggunakan nilai wilayah-wilayah tetangga.
  • Gi* menggunakan nilai wilayah-wilayah tetangga beserta nilai wilayah yang sedang diperiksa.

Fungsi include.self(nb) menambahkan wilayah itu sendiri ke dalam daftar tetangganya untuk menghitung Gi. Karena nilai yang disertakan berbeda, hasil Z pada kedua metode juga dapat berbeda. Untuk menentukan hotspot atau coldspot berdasarkan Gi, p-value dan penyesuaian BH perlu dihitung kembali menggunakan hasil Gi*.

lw_star <- nb2listw(include.self(nb), style = "B")
Gi_star_z <- as.numeric(localG(x, lw_star))
head(data.frame(id = col$id, Z_Gi = Gi_z, Z_Gi_star = Gi_star_z))
#>   id        Z_Gi   Z_Gi_star
#> 1  1 -0.93780765 -1.43277965
#> 2  2 -0.98565912 -1.34000810
#> 3  3 -0.71841891 -0.77199868
#> 4  4 -0.06666232 -0.13173336
#> 5  5  1.04713603  1.28536280
#> 6  6  0.45474575  0.06864804

Hasil kedua versi dapat berbeda karena definisi lingkungannya berbeda. Uji normal di contoh Gi juga berbeda dari inferensi permutasi Local Moran; alternatif permutasi Gi tersedia pada localG_perm(). Rujukan Gi dan Gi*.

6 Jembatan ke dua variabel

Pada analisis sebelumnya, kita membandingkan angka kriminalitas suatu wilayah dengan angka kriminalitas tetangganya. Analisis tersebut disebut univariat karena menggunakan satu variabel, yaitu CRIME.

Selanjutnya, kita mempelajari hubungan spasial antara dua variabel, yaitu kriminalitas (CRIME) dan pendapatan rumah tangga (INC). Analisis ini disebut bivariat, dengan pertanyaan:

Apakah wilayah dengan angka kriminalitas tinggi cenderung bertetangga dengan wilayah yang memiliki pendapatan rumah tangga rendah?

Dalam Moran bivariat, kita membandingkan CRIME suatu wilayah dengan rata-rata INC tetangganya. Sementara itu, korelasi Pearson membandingkan CRIME dan INC dalam wilayah yang sama.

Untuk menjaga kejelasan analisis, kita menetapkan X = CRIME dan Y = INC. Perbedaan pasangan yang dibandingkan pada setiap metode dirangkum dalam tabel berikut.

Analisis Pasangan yang dibandingkan Kalimat pertanyaan
Pearson \(X_i\) dengan \(Y_i\) Apakah dua variabel berkaitan dalam wilayah yang sama?
Moran univariat \(X_i\) dengan \((WX)_i\) Apakah nilai X mirip dengan X tetangga?
Moran bivariat \(X_i\) dengan \((WY)_i\) Apakah X berkaitan dengan Y tetangga?
Lee’s L Pola lag X dengan pola lag Y Apakah kedua variabel memiliki pola lingkungan yang sejalan?

6.1 Pearson sebagai pembanding deskriptif

Sebelum menganalisis hubungan spasial dua variabel, kita terlebih dahulu melihat hubungan antara pendapatan rumah tangga (INC) dan angka kriminalitas (CRIME) dalam wilayah yang sama menggunakan korelasi Pearson.

Koefisien Pearson menunjukkan arah dan kekuatan hubungan linear antara kedua variabel. Nilai positif menunjukkan hubungan searah, sedangkan nilai negatif menunjukkan hubungan berlawanan arah. Analisis ini belum memperhitungkan hubungan ketetanggaan antarwilayah.

r_xy <- cor(x, y)
r_xy
#> [1] -0.6955898

ggplot(col, aes(INC, CRIME)) +
  geom_point(color = "#25858e", size = 2.5) +
  geom_smooth(method = "lm", formula = y ~ x, se = FALSE, color = "#183f56") +
  labs(title = "Pendapatan dan kriminalitas dalam wilayah yang sama",
       subtitle = paste("Korelasi Pearson =", fmt(r_xy)),
       x = "INC | ribuan USD", y = "CRIME | per 1.000 rumah tangga")

Nilai korelasi Pearson sebesar −0,696 menunjukkan hubungan linear negatif antara pendapatan dan kriminalitas. Artinya, wilayah dengan pendapatan rumah tangga lebih tinggi cenderung memiliki angka kriminalitas lebih rendah. Kecenderungan ini terlihat dari sebaran titik dan garis yang menurun pada grafik.

Setiap titik mewakili pasangan nilai INC dan CRIME dalam satu wilayah yang sama. Hasil ini digunakan sebagai gambaran awal, belum menunjukkan hubungan dengan wilayah tetangga dan tidak membuktikan sebab-akibat. Selanjutnya, Moran bivariat digunakan untuk membandingkan kriminalitas suatu wilayah dengan pendapatan wilayah tetangganya.

7 Moran bivariat global

7.1 Apa yang dihitung?

Moran bivariat global digunakan untuk melihat hubungan antara nilai suatu variabel di sebuah wilayah dan nilai variabel lain pada tetangganya. Dalam contoh ini, kita membandingkan kriminalitas suatu wilayah (CRIME) dengan rata-rata pendapatan tetangganya (INC).

Kedua variabel terlebih dahulu diubah menjadi skor baku karena memiliki satuan berbeda. Selanjutnya, perhitungan dilakukan dalam dua arah: CRIME → INC tetangga dan INC → CRIME tetangga. Tanda panah menunjukkan urutan variabel yang dibandingkan, bukan hubungan sebab-akibat.

Dengan W yang jumlah setiap barisnya satu:

\[ I_{X\to Y} = \frac{\sum_i z_{Xi}(Wz_Y)_i}{\sum_i z_{Xi}^2}. \]

# Fungsi ringkas buatan modul; khusus bobot W tanpa wilayah terisolasi.
I_bivariat <- function(z_asal, z_tetangga, listw) {
  sum(z_asal * lag.listw(listw, z_tetangga)) / sum(z_asal^2)
}
I_xy <- I_bivariat(zx, zy, lw_W)
I_yx <- I_bivariat(zy, zx, lw_W)

knitr::kable(data.frame(
  ukuran = c("Pearson: CRIME dan INC satu wilayah",
             "Moran bivariat: CRIME -> INC tetangga",
             "Moran bivariat: INC -> CRIME tetangga"),
  nilai = c(r_xy, I_xy, I_yx)
), digits = 4)
ukuran nilai
Pearson: CRIME dan INC satu wilayah -0.6956
Moran bivariat: CRIME -> INC tetangga -0.4286
Moran bivariat: INC -> CRIME tetangga -0.4516

Hasil perhitungan menunjukkan:

  • Pearson = −0,6956: wilayah dengan pendapatan lebih tinggi cenderung memiliki kriminalitas lebih rendah dalam wilayah yang sama.
  • Moran CRIME → INC tetangga = −0,4286: wilayah dengan kriminalitas tinggi cenderung memiliki tetangga dengan rata-rata pendapatan rendah, dan sebaliknya.
  • Moran INC → CRIME tetangga = −0,4516: wilayah dengan pendapatan tinggi cenderung memiliki tetangga dengan rata-rata kriminalitas rendah, dan sebaliknya.

Kedua nilai Moran bivariat berbeda karena pertukaran variabel mengubah pasangan yang dibandingkan, sementara bobot dari satu wilayah ke tetangganya belum tentu sama dengan bobot arah sebaliknya.

Nilai negatif menunjukkan kecenderungan hubungan yang berlawanan arah. Namun, signifikansinya masih perlu diperiksa melalui uji permutasi. Nilai indeks tersebut juga tidak dapat diartikan sebagai persentase pengaruh. Rujukan definisi Moran bivariat.

7.2 Uji permutasi: nyatakan apa yang diacak

Untuk menilai apakah hubungan spasial yang ditemukan signifikan, kita melakukan uji permutasi. Nilai pendapatan (INC) diacak antarwilayah, sedangkan nilai kriminalitas (CRIME) dan bobot ketetanggaan tetap.

Setiap pengacakan menghasilkan nilai Moran bivariat baru. Proses ini diulang 9.999 kali, kemudian hasilnya dibandingkan dengan Moran bivariat dari data asli.

Hipotesis yang digunakan adalah:

  • H₀: penempatan nilai INC antarwilayah bersifat acak, dengan CRIME dan bobot spasial tetap.
  • H₁: hubungan yang diamati lebih kuat, baik ke arah positif maupun negatif, daripada yang diharapkan dari pengacakan tersebut.

Karena kedua arah diperiksa, pengujian menggunakan nilai absolut indeks untuk menghitung p-value dua sisi.

set.seed(2027)
I_xy_sim <- replicate(B, {
  zy_acak <- sample(zy, replace = FALSE)
  I_bivariat(zx, zy_acak, lw_W)
})
p_xy <- (1 + sum(abs(I_xy_sim) >= abs(I_xy))) / (B + 1)
data.frame(I_CRIME_INC = I_xy, p_dua_sisi = p_xy, permutasi = B)
#>   I_CRIME_INC p_dua_sisi permutasi
#> 1  -0.4286322      1e-04      9999

Moran bivariat CRIME terhadap INC tetangga sebesar −0,4286, dengan p-value 0,0001. Karena p-value lebih kecil dari 0,05, H₀ ditolak.

Hasil ini mendukung hubungan spasial yang berlawanan arah: wilayah dengan kriminalitas tinggi cenderung memiliki tetangga dengan rata-rata pendapatan rendah, sedangkan wilayah dengan kriminalitas rendah cenderung memiliki tetangga dengan rata-rata pendapatan tinggi.

Kesimpulan tersebut berlaku terhadap pengacakan INC yang digunakan. Pengujian ini belum mengendalikan pola spasial pendapatan maupun hubungan pendapatan–kriminalitas dalam wilayah yang sama, dan tidak membuktikan sebab-akibat.

7.3 Bivariate Moran scatterplot

Bivariate Moran scatterplot memperlihatkan hubungan antara kriminalitas suatu wilayah dan rata-rata pendapatan tetangganya. Setiap titik mewakili satu wilayah.

Sumbu horizontal menunjukkan skor baku CRIME wilayah tersebut, sedangkan sumbu vertikal menunjukkan rata-rata skor baku INC tetangganya. Garis nol membagi grafik menjadi empat kuadran. Huruf pertama menunjukkan kondisi kriminalitas wilayah, sedangkan huruf kedua menunjukkan kondisi pendapatan tetangganya.

q_bv <- kuadran(zx, wzy)
df_bv <- data.frame(id = col$id, zx = zx, wzy = wzy, kuadran = q_bv)
ggplot(df_bv, aes(zx, wzy, color = kuadran)) +
  geom_hline(yintercept = 0, color = "grey65") +
  geom_vline(xintercept = 0, color = "grey65") +
  geom_point(size = 2.6) +
  geom_abline(intercept = 0, slope = I_xy, color = "#183f56", linewidth = 0.9) +
  scale_color_manual(values = warna_pola, drop = FALSE) +
  labs(title = "Moran bivariat: kriminalitas wilayah dan pendapatan tetangga",
       subtitle = paste("Kemiringan garis melalui nol =", fmt(I_xy)),
       x = "z CRIME lokasi", y = "Wz INC tetangga", color = "Kuadran")

Kuadran Interpretasi spesifik kasus
HH CRIME wilayah tinggi, rata-rata INC tetangga tinggi
LL CRIME wilayah rendah, rata-rata INC tetangga rendah
HL CRIME wilayah tinggi, rata-rata INC tetangga rendah
LH CRIME wilayah rendah, rata-rata INC tetangga tinggi

Sebagian besar titik berada pada kuadran HL dan LH:

  • HL (kanan bawah): kriminalitas wilayah di atas rata-rata, sedangkan rata-rata pendapatan tetangganya di bawah rata-rata.
  • LH (kiri atas): kriminalitas wilayah di bawah rata-rata, sedangkan rata-rata pendapatan tetangganya di atas rata-rata.

Beberapa wilayah berada pada kuadran HH, yaitu kriminalitas wilayah dan rata-rata pendapatan tetangganya sama-sama tinggi, atau LL, yaitu keduanya sama-sama rendah. Tinggi dan rendah di sini dibandingkan dengan rata-rata masing-masing variabel di seluruh wilayah.

Garis yang menurun memiliki kemiringan sekitar −0,429, sesuai dengan Moran bivariat yang telah dihitung. Pola ini menunjukkan kecenderungan hubungan berlawanan arah antara kriminalitas wilayah dan pendapatan tetangganya.

Warna kuadran menunjukkan jenis pola, belum menunjukkan signifikansi setiap wilayah. Untuk menilainya, analisis dilanjutkan dengan Local Moran bivariat.

8 Local Moran bivariat

8.1 Dari pola keseluruhan ke wilayah tertentu

Local Moran bivariat digunakan untuk mengetahui wilayah mana yang menunjukkan hubungan antara kriminalitas wilayah tersebut dan rata-rata pendapatan tetangganya.

Pengujian dilakukan pada setiap wilayah dengan mempertahankan nilai CRIME wilayah tersebut, lalu membandingkan hasilnya dengan pengacakan nilai INC dari wilayah lain. Karena banyak wilayah diuji sekaligus, p-value disesuaikan menggunakan metode Benjamini–Hochberg (BH).

local_bv <- localmoran_bv(
  x, y, lw_W, nsim = B, scale = TRUE,
  alternative = "two.sided", iseed = 2028,
  no_repeat_in_row = TRUE
)
colnames(local_bv)
#> [1] "Ibvi"                 "E.Ibvi"               "Var.Ibvi"            
#> [4] "Z.Ibvi"               "Pr(z != E(Ibvi))"     "Pr(z != E(Ibvi)) Sim"
#> [7] "Pr(folded) Sim"

p_bv <- local_bv[, "Pr(z != E(Ibvi)) Sim"]
p_bv_BH <- p.adjust(p_bv, method = "BH")
stopifnot(max(abs(local_bv[, "Ibvi"] - zx * wzy)) < 1e-8)

hasil_bv <- data.frame(
  id = col$id, CRIME = x, INC = y,
  lag_INC = lag.listw(lw_W, y),
  Ibvi = local_bv[, "Ibvi"], kuadran = q_bv,
  p_permutasi = p_bv, p_BH = p_bv_BH
)
knitr::kable(head(hasil_bv[order(hasil_bv$p_permutasi), ], 10), digits = 4,
             caption = "Sepuluh p-value terkecil untuk CRIME lokasi dengan INC tetangga.")
Sepuluh p-value terkecil untuk CRIME lokasi dengan INC tetangga.
id CRIME INC lag_INC Ibvi kuadran p_permutasi p_BH
32 32 19.1456 18.942 26.0663 -1.9581 LH 0.0004 0.0196
8 8 38.4259 11.337 8.5385 -0.2016 HL 0.0008 0.0196
12 12 56.7057 10.048 9.0632 -1.2010 HL 0.0026 0.0425
40 40 16.2413 29.833 20.7966 -1.2710 LH 0.0060 0.0735
47 47 27.8229 18.950 26.0200 -0.8915 LH 0.0126 0.1225
16 16 54.8387 7.625 10.5606 -0.7878 HL 0.0150 0.1225
41 41 18.9051 22.207 22.5750 -1.3941 LH 0.0202 0.1263
28 28 56.9198 7.856 10.9571 -0.7804 HL 0.0224 0.1263
15 15 48.5855 9.873 10.0793 -0.6057 HL 0.0232 0.1263
14 14 57.0661 9.963 10.0772 -0.9880 HL 0.0280 0.1336

Pada taraf signifikansi 5%, wilayah ID 32, 8, dan 12 tetap signifikan setelah penyesuaian BH, karena nilai p_BH masing-masing kurang dari 0,05.

  • Wilayah ID 32 berpola LH: kriminalitasnya di bawah rata-rata, sedangkan rata-rata pendapatan tetangganya di atas rata-rata.
  • Wilayah ID 8 dan 12 berpola HL: kriminalitasnya di atas rata-rata, sedangkan rata-rata pendapatan tetangganya di bawah rata-rata.

Tinggi dan rendah ditentukan berdasarkan rata-rata masing-masing variabel di seluruh wilayah. Untuk membaca kondisi pendapatan tetangga, gunakan kolom lag_INC; kolom INC menunjukkan pendapatan wilayah itu sendiri.

Wilayah lain dalam tabel memiliki p_BH lebih dari 0,05 sehingga bukti pola lokalnya belum cukup setelah penyesuaian. Hasil ini menunjukkan keterkaitan antarwilayah, tetapi tidak membuktikan bahwa pendapatan tetangga menyebabkan tingkat kriminalitas suatu wilayah. Dokumentasi dan contoh fungsi.

8.2 Peta dan satu contoh interpretasi

Peta berikut menunjukkan lokasi pola hubungan antara kriminalitas suatu wilayah dan rata-rata pendapatan tetangganya. Peta pertama menggunakan p-value sebelum penyesuaian, sedangkan peta kedua menggunakan p-value setelah penyesuaian BH untuk memperhitungkan banyaknya pengujian. Perbandingan keduanya membantu kita melihat pola yang tetap signifikan setelah penyesuaian.

peta_pola(q_bv, p_bv, "Moran lokal bivariat: CRIME -> INC tetangga",
          "Eksplorasi | p permutasi mentah; huruf pertama CRIME, huruf kedua lag INC")

peta_pola(q_bv, p_bv_BH, "Moran lokal bivariat: CRIME -> INC tetangga",
          "Pembanding | p disesuaikan BH")


knitr::kable(as.data.frame(table(
  Kuadran = q_bv, Lolos_BH = ifelse(p_bv_BH < alpha, "Ya", "Belum")
)), caption = "Jumlah wilayah menurut kuadran dan hasil penyesuaian BH.")
Jumlah wilayah menurut kuadran dan hasil penyesuaian BH.
Kuadran Lolos_BH Freq
HH Belum 4
HL Belum 18
LH Belum 18
LL Belum 6
HH Ya 0
HL Ya 2
LH Ya 1
LL Ya 0

Pada taraf signifikansi 5%, terdapat 14 wilayah yang signifikan sebelum penyesuaian BH. Setelah penyesuaian, 3 wilayah tetap signifikan, yaitu:

  • Dua wilayah berpola HL (oranye): kriminalitas wilayah di atas rata-rata, sedangkan rata-rata pendapatan tetangganya di bawah rata-rata.
  • Satu wilayah berpola LH (hijau kebiruan): kriminalitas wilayah di bawah rata-rata, sedangkan rata-rata pendapatan tetangganya di atas rata-rata.

Tidak ada wilayah berpola HH atau LL yang tetap signifikan setelah penyesuaian BH. Wilayah berwarna abu-abu menunjukkan bahwa bukti statistiknya belum cukup untuk menyatakan adanya pola lokal yang signifikan.

Berkurangnya wilayah berwarna terjadi karena penyesuaian dalam menilai signifikansi; nilai kriminalitas dan pendapatannya tetap sama.

# Ambil satu wilayah untuk latihan membaca, bukan untuk mengubah aturan pengujian.
contoh <- hasil_bv[which.min(hasil_bv$p_permutasi), ]
knitr::kable(contoh, digits = 4, row.names = FALSE)
id CRIME INC lag_INC Ibvi kuadran p_permutasi p_BH
32 19.1456 18.942 26.0663 -1.9581 LH 4e-04 0.0196

Wilayah ID 32 memiliki CRIME sekitar 19,146 per 1.000 rumah tangga, sedangkan rata-rata INC tetangganya sekitar 26,066 ribu USD. Wilayah ini termasuk pola LH karena kriminalitasnya di bawah rata-rata seluruh wilayah, sementara rata-rata pendapatan tetangganya di atas rata-rata.

Nilai Local Moran bivariat sebesar −1,9581, dengan p-value permutasi 0,0004 dan p-value setelah penyesuaian BH 0,0196. Karena p-value BH kurang dari 0,05, pola LH tersebut tetap signifikan.

Pada peta lokasi, warna oranye menandai wilayah ID 32, sedangkan hijau muda menandai tetangganya, yaitu ID 20, 23, 40, dan 41. Nilai INC keempat tetangga inilah yang digunakan untuk menghitung lag_INC. Warna pada peta lokasi menunjukkan peran wilayah, bukan kategori HL atau LH.

lokator <- col
lokator$peran <- "Wilayah lain"
lokator$peran[nb[[contoh$id]]] <- "Tetangga contoh"
lokator$peran[contoh$id] <- "Wilayah contoh"
label_id <- data.frame(id = col$id, X = titik[, 1], Y = titik[, 2])
ggplot(lokator) +
  geom_sf(aes(fill = peran), color = "white", linewidth = 0.4) +
  geom_text(data = label_id, aes(X, Y, label = id), size = 2.5, color = "#183446") +
  scale_fill_manual(values = c("Wilayah contoh" = "#e8a23d",
                              "Tetangga contoh" = "#9edbd6",
                              "Wilayah lain" = "#e8edf0")) +
  labs(title = paste("Lokasi wilayah contoh: ID", contoh$id), fill = "Peran") +
  coord_sf(datum = NA) +
  theme_void() + theme(legend.position = "bottom")
Temukan wilayah contoh dan tetangganya; label menunjukkan ID modul.

Temukan wilayah contoh dan tetangganya; label menunjukkan ID modul.

9 Pengayaan: dua sudut pandang bivariat lain

Bagian ini menghubungkan praktikum dengan materi Geary bivariat dan Lee’s L dalam slide. Fokuskan pada pertanyaan dan interpretasinya; penurunan rumus dapat dibaca setelah kelas.

9.1 Geary bivariat: selisih lintas variabel

Geary bivariat dalam modul ini digunakan untuk melihat seberapa berbeda nilai kriminalitas suatu wilayah dan pendapatan wilayah tetangganya. Karena satuannya berbeda, CRIME dan INC terlebih dahulu diubah menjadi skor baku agar dapat dibandingkan.

Perhitungan menggunakan kuadrat selisih kedua skor tersebut pada pasangan wilayah yang bertetangga. Nilai yang lebih kecil menunjukkan skor yang lebih mirip. Hasilnya kemudian dibandingkan dengan hasil pengacakan lokasi nilai INC, sementara CRIME dan hubungan ketetanggaan tetap.

Dengan skor baku sampel, rumus pada bahan kuliah menyederhana menjadi:

\[ C_{XY}=\frac{1}{2S_0}\sum_i\sum_j w_{ij}(z_{Xi}-z_{Yj})^2. \]

C_bivariat <- function(za, zb, W) {
  sum(W * outer(za, zb, "-")^2) / (2 * sum(W))
}
C_xy <- C_bivariat(zx, zy, W)

set.seed(2029)
C_xy_sim <- replicate(B, C_bivariat(zx, sample(zy), W))
p_C_bawah <- (1 + sum(C_xy_sim <= C_xy)) / (B + 1)
p_C_atas <- (1 + sum(C_xy_sim >= C_xy)) / (B + 1)
p_C_xy <- min(1, 2 * min(p_C_bawah, p_C_atas))

knitr::kable(data.frame(
  Cxy = C_xy, rerata_permutasi = mean(C_xy_sim),
  harapan_teoretis = (n - 1) / n, p_dua_sisi = p_C_xy
), digits = 4)
Cxy rerata_permutasi harapan_teoretis p_dua_sisi
1.5029 0.9801 0.9796 2e-04

Nilai Geary bivariat yang diperoleh adalah 1,5029, lebih besar daripada rata-rata hasil pengacakan sebesar 0,9801. Nilai p-value dua sisi sebesar 0,0002, lebih kecil dari 0,05, sehingga H0 ditolak.

Artinya, perbedaan skor baku kriminalitas wilayah dan pendapatan tetangganya lebih besar daripada yang biasanya muncul pada susunan acak. Hasil ini sejalan dengan temuan Moran bivariat sebelumnya yang menunjukkan kecenderungan hubungan berlawanan arah.

Pada perhitungan ini, nilai pembanding saat pengacakan sekitar 0,98. Oleh karena itu, interpretasi didasarkan pada hasil pengacakan dan p-value, bukan langsung memakai patokan angka 1 dari Geary univariat.

9.2 Lee’s L: pola lingkungan kedua variabel

Lee’s L digunakan untuk melihat hubungan antara rata-rata kriminalitas tetangga dan rata-rata pendapatan tetangga di sekitar setiap wilayah. Dengan demikian, kedua variabel sama-sama diringkas berdasarkan kondisi wilayah tetangganya.

Pengujian dilakukan dengan mengacak lokasi pasangan CRIME–INC secara bersama-sama, sementara hubungan ketetanggaan tetap. Cara ini mempertahankan pasangan nilai kriminalitas dan pendapatan dari wilayah yang sama, tetapi mengubah susunannya pada peta. Untuk W pada contoh ini:

\[ L=\frac{\sum_i (Wz_X)_i(Wz_Y)_i} {\sqrt{\sum_i z_{Xi}^2\sum_i z_{Yi}^2}}. \]

L_manual <- sum(wzx * wzy) / sqrt(sum(zx^2) * sum(zy^2))
L_paket <- lee(x, y, lw_W, n = n)$L
stopifnot(isTRUE(all.equal(as.numeric(L_paket), L_manual)))

set.seed(2030)
L_uji <- lee.mc(x, y, lw_W, nsim = B, alternative = "two.sided")
L_uji
#> 
#>  Monte-Carlo simulation of Lee's L
#> 
#> data:  x ,  y 
#> weights: lw_W  
#> number of simulations + 1: 10000 
#> 
#> statistic = -0.47031, observed rank = 1, p-value = 2e-04
#> alternative hypothesis: two.sided

Nilai Lee’s L sebesar −0,4703 menunjukkan bahwa pola lingkungan kedua variabel cenderung berlawanan arah. Lingkungan dengan rata-rata kriminalitas tetangga yang tinggi cenderung memiliki rata-rata pendapatan tetangga yang rendah, dan sebaliknya.

Hasil uji menghasilkan p-value 0,0002, lebih kecil dari 0,05, sehingga H0 ditolak. Artinya, pola yang diamati berbeda secara signifikan dari pola yang biasanya muncul ketika lokasi pasangan CRIME–INC diacak.

Nilai −0,4703 menunjukkan arah dan besarnya statistik hubungan spasial, bukan persentase pengaruh. Hasil ini juga tidak membuktikan hubungan sebab-akibat antara pendapatan dan kriminalitas.

9.3 Latihan penerapan

Latihan ini menggunakan data Columbus dan bobot ketetanggaan Queen yang telah dibuat. Gunakan taraf signifikansi 5% dan jelaskan setiap hasil dengan bahasa sendiri.

9.3.1 1. Memahami nilai wilayah dan nilai tetangganya

Pilih wilayah ID 16, kemudian:

  1. Tampilkan ID seluruh tetangganya.
  2. Tampilkan nilai CRIME wilayah tersebut dan nilai CRIME setiap tetangganya.
  3. Hitung rata-rata CRIME tetangganya secara manual, lalu bandingkan dengan hasil lag.listw().
  4. Jelaskan apakah kriminalitas wilayah ID 16 lebih tinggi atau lebih rendah daripada rata-rata kriminalitas tetangganya.

Hasil yang dikumpulkan: tabel tetangga, hasil perhitungan, dan interpretasi 2–3 kalimat.

9.3.2 2. Membaca pola kriminalitas secara keseluruhan

Gunakan hasil Moran’s I dan Geary’s C untuk variabel CRIME.

  1. Buat tabel berisi nama metode, nilai statistik, dan p-value. Untuk Moran’s I, gunakan p-value permutasi.
  2. Tentukan keputusan pengujian masing-masing metode pada taraf 5%.
  3. Jelaskan apakah kedua metode memberikan kesimpulan yang sejalan.
  4. Jelaskan mengapa Moran’s I yang positif dan Geary’s C yang kurang dari 1 dapat menunjukkan pola yang sama.

Hasil yang dikumpulkan: satu tabel perbandingan dan satu paragraf penjelasan.

9.3.3 3. Menilai pengaruh penyesuaian BH

Gunakan hasil Local Moran univariat untuk CRIME.

  1. Hitung jumlah wilayah yang signifikan sebelum dan setelah penyesuaian BH.
  2. Sebutkan ID dan kuadran wilayah yang tetap signifikan setelah penyesuaian.
  3. Pilih satu wilayah yang signifikan sebelum penyesuaian, tetapi tidak lagi signifikan setelah BH. Tuliskan kedua p-value-nya.
  4. Jelaskan mengapa perubahan status tersebut tidak berarti nilai kriminalitas wilayahnya berubah.

Hasil yang dikumpulkan: tabel ringkas dan interpretasi 3–4 kalimat.

9.3.4 4. Membandingkan dua pola lokal bivariat

Gunakan hasil Local Moran bivariat CRIME terhadap INC tetangga untuk wilayah ID 8 dan ID 32.

  1. Buat tabel berisi ID, CRIME, INC, lag_INC, kuadran, dan p-value BH.
  2. Jelaskan arti kuadran masing-masing wilayah.
  3. Tentukan apakah pola keduanya signifikan setelah penyesuaian BH.
  4. Jelaskan mengapa pembacaan huruf kedua pada kuadran menggunakan lag_INC.
  5. Tuliskan satu kesimpulan tentang hubungan kriminalitas wilayah dan pendapatan tetangganya tanpa menyatakan hubungan sebab-akibat.

Hasil yang dikumpulkan: satu tabel dan satu paragraf perbandingan.

9.3.5 5. Memeriksa apakah pilihan tetangga mengubah kesimpulan

Bentuk ketetanggaan Rook dengan mengganti queen = TRUE menjadi queen = FALSE pada poly2nb(). Buat kembali bobot dengan style = "W".

  1. Periksa apakah ada wilayah yang tidak memiliki tetangga.
  2. Bandingkan jumlah pasangan tetangga unik antara Queen dan Rook.
  3. Hitung kembali Moran’s I global untuk CRIME menggunakan bobot Rook.
  4. Jalankan uji permutasi dengan jumlah pengacakan dan arah pengujian yang sama seperti pada bobot Queen.
  5. Bandingkan nilai indeks, p-value, dan kesimpulan kedua bobot.

Hasil yang dikumpulkan: tabel perbandingan Queen–Rook dan jawaban singkat: Apakah kesimpulan pola kriminalitas tetap sama ketika definisi tetangga berubah?

Petunjuk: gunakan card(nb) untuk menghitung jumlah tetangga. Jumlah pasangan tetangga unik dapat dihitung dengan sum(card(nb)) / 2.

9.3.6 Ketentuan jawaban

Sertakan sintaks yang digunakan dan output yang relevan. Setiap interpretasi perlu menyebutkan variabel, wilayah atau cakupan analisis, serta bukti yang mendukung kesimpulan. Bedakan hasil yang menggambarkan seluruh wilayah dengan hasil untuk wilayah tertentu.

LS0tDQp0aXRsZTogIk1vZHVsIFByYWt0aWt1bSINCnN1YnRpdGxlOiAiQXV0b2tvcmVsYXNpIFNwYXNpYWwgVW5pdmFyaWF0IGRhbiBCaXZhcmlhdCDigJQgU1RBMTM1MiBSZWdyZXNpIFNwYXNpYWwiDQphdXRob3I6ICJOYW1hIHBlbnl1c3VuIg0KZGF0ZTogIjMwIFNlcHRlbWJlciAyMDI2Ig0KbGFuZzogaWQNCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6DQogICAgICBjb2xsYXBzZWQ6IGZhbHNlDQogICAgICBzbW9vdGhfc2Nyb2xsOiB0cnVlDQogICAgdG9jX2RlcHRoOiAzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgdGhlbWU6IGZsYXRseQ0KICAgIGhpZ2hsaWdodDogdGFuZ28NCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgc2VsZl9jb250YWluZWQ6IHRydWUNCiAgICBmaWdfY2FwdGlvbjogdHJ1ZQ0KcGFyYW1zOg0KICBuc2ltOiA5OTk5DQogIGFscGhhOiAwLjA1DQotLS0NCg0KPHN0eWxlPg0KLyogVGVrcyBkYW4gbGViYXIgaGFsYW1hbiAqLw0KYm9keSB7DQogIGZvbnQtZmFtaWx5OiAiU2Vnb2UgVUkiLCBBcmlhbCwgc2Fucy1zZXJpZjsNCiAgZm9udC1zaXplOiAxNXB4Ow0KICBsaW5lLWhlaWdodDogMS44Ow0KICBjb2xvcjogIzI5NDY1YjsNCiAgYmFja2dyb3VuZDogI2ZmZmZmZjsNCn0NCi5tYWluLWNvbnRhaW5lciB7DQogIG1heC13aWR0aDogMTIwMHB4ICFpbXBvcnRhbnQ7DQp9DQpwIHsgbWFyZ2luLWJvdHRvbTogMTRweDsgfQ0KDQovKiBLYXJ0dSBqdWR1bCAqLw0KI2hlYWRlciB7DQogIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMTBkZWcsICMzNTVmNzAgMCUsICM2NTcwODcgNTIlLCAjYzQ1Njg5IDEwMCUpOw0KICBwYWRkaW5nOiA0MnB4IDM0cHggMzJweDsNCiAgbWFyZ2luOiAyMHB4IDAgMzRweDsNCiAgYm9yZGVyLXJhZGl1czogMTJweDsNCiAgYm94LXNoYWRvdzogMCA2cHggMThweCByZ2JhKDM1LCA1OCwgNzYsIDAuMTQpOw0KfQ0KI2hlYWRlciAudGl0bGUgew0KICBjb2xvcjogd2hpdGU7DQogIGZvbnQtc2l6ZTogMzRweDsNCiAgZm9udC13ZWlnaHQ6IDcwMDsNCiAgbGluZS1oZWlnaHQ6IDEuMjU7DQogIG1hcmdpbjogMThweCAwIDA7DQogIHBhZGRpbmctYm90dG9tOiAxMHB4Ow0KICBib3JkZXItYm90dG9tOiAzcHggc29saWQgcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjY1KTsNCn0NCiNoZWFkZXIgLnN1YnRpdGxlIHsNCiAgY29sb3I6IHdoaXRlOw0KICBmb250LXNpemU6IDIycHg7DQogIGZvbnQtd2VpZ2h0OiA2MDA7DQogIGxpbmUtaGVpZ2h0OiAxLjQ7DQogIG1hcmdpbjogNXB4IDAgMTJweDsNCn0NCiNoZWFkZXIgLmF1dGhvciwNCiNoZWFkZXIgLmRhdGUgew0KICBjb2xvcjogd2hpdGU7DQogIGZvbnQtc2l6ZTogMTRweDsNCiAgZm9udC13ZWlnaHQ6IDQwMDsNCiAgbWFyZ2luOiA2cHggMDsNCn0NCg0KLyogSnVkdWwgYmFnaWFuICovDQpoMSwgaDIsIGgzLCBoNCB7DQogIGNvbG9yOiAjMTczZTU5Ow0KICBmb250LXdlaWdodDogNjAwOw0KICBsaW5lLWhlaWdodDogMS4zNTsNCn0NCmgxOm5vdCgudGl0bGUpIHsNCiAgZm9udC1zaXplOiAzMnB4Ow0KICBtYXJnaW4tdG9wOiAzOHB4Ow0KICBwYWRkaW5nLWJvdHRvbTogOXB4Ow0KICBib3JkZXItYm90dG9tOiAzcHggc29saWQgI2VmYTJjMjsNCn0NCmgyOm5vdCguc3VidGl0bGUpIHsgZm9udC1zaXplOiAyNnB4OyBtYXJnaW4tdG9wOiAzMHB4OyB9DQpoMyB7IGZvbnQtc2l6ZTogMjFweDsgbWFyZ2luLXRvcDogMjRweDsgfQ0KaDQgeyBmb250LXNpemU6IDE3cHg7IH0NCg0KLyogRGFmdGFyIGlzaSAqLw0KI1RPQyB7DQogIGZvbnQtc2l6ZTogMTNweDsNCiAgbGluZS1oZWlnaHQ6IDEuNTU7DQogIGJvcmRlcjogMXB4IHNvbGlkICNlZmI2Y2Y7DQogIGJvcmRlci1yYWRpdXM6IDdweDsNCiAgYmFja2dyb3VuZDogd2hpdGU7DQp9DQoudG9jaWZ5IHsNCiAgbWF4LWhlaWdodDogODV2aDsNCiAgb3ZlcmZsb3cteTogYXV0bzsNCn0NCi50b2NpZnktaXRlbSB7IHBhZGRpbmctdG9wOiAzcHg7IHBhZGRpbmctYm90dG9tOiAzcHg7IH0NCi50b2NpZnktc3ViaGVhZGVyIHsgYmFja2dyb3VuZDogI2ZmZjdmYjsgfQ0KI1RPQyAudG9jaWZ5LWl0ZW0uYWN0aXZlLA0KI1RPQyAudG9jaWZ5LWl0ZW0uYWN0aXZlOmhvdmVyLA0KI1RPQyAubGlzdC1ncm91cC1pdGVtLmFjdGl2ZSB7DQogIGNvbG9yOiB3aGl0ZTsNCiAgYmFja2dyb3VuZDogI2JkNGM4MDsNCiAgYm9yZGVyLWNvbG9yOiAjYmQ0YzgwOw0KfQ0KLnRvYy1zZWN0aW9uLW51bWJlciB7IG1hcmdpbi1yaWdodDogMC4zNWVtOyB9DQoNCi8qIFRhdXRhbiBkYW4ga29kZSAqLw0KYSB7IGNvbG9yOiAjYTMzNzY4OyB9DQphOmhvdmVyIHsgY29sb3I6ICM3NjI0NDk7IH0NCnByZSB7DQogIGJhY2tncm91bmQ6ICNmN2Y5ZmI7DQogIGJvcmRlcjogMXB4IHNvbGlkICNkY2U1ZWM7DQogIGJvcmRlci1yYWRpdXM6IDhweDsNCiAgcGFkZGluZzogMTZweDsNCiAgZm9udC1zaXplOiAxM3B4Ow0KICBsaW5lLWhlaWdodDogMS41NTsNCn0NCnByZSBjb2RlIHsgd2hpdGUtc3BhY2U6IHByZTsgfQ0KcCBjb2RlLCBsaSBjb2RlLCB0ZCBjb2RlIHsNCiAgY29sb3I6ICM5MTQwNmE7DQogIGJhY2tncm91bmQ6ICNmOWVkZjM7DQogIGJvcmRlci1yYWRpdXM6IDRweDsNCn0NCi5jb2RlLWZvbGRpbmctYnRuIHsNCiAgbWFyZ2luLWJvdHRvbTogNnB4Ow0KICBib3JkZXItcmFkaXVzOiA0cHg7DQp9DQojaGVhZGVyIC5idG4gew0KICBjb2xvcjogIzE3M2U1OTsNCiAgYmFja2dyb3VuZDogI2ZmZmZmZjsNCiAgYm9yZGVyLWNvbG9yOiAjZmZmZmZmOw0KfQ0KDQovKiBUYWJlbCAqLw0KdGFibGUgew0KICB3aWR0aDogMTAwJTsNCiAgZm9udC1zaXplOiAxNHB4Ow0KICBtYXJnaW46IDE4cHggMCAyNHB4Ow0KfQ0KdGFibGUgdGggew0KICBiYWNrZ3JvdW5kOiAjZjVlNWVkOw0KICBjb2xvcjogIzE3M2U1OTsNCn0NCnRhYmxlIHRoLCB0YWJsZSB0ZCB7DQogIHBhZGRpbmc6IDEwcHggMTJweCAhaW1wb3J0YW50Ow0KICBib3JkZXItYm90dG9tOiAxcHggc29saWQgI2U2ZWJlZjsNCn0NCnRhYmxlIHRib2R5IHRyOm50aC1jaGlsZChldmVuKSB7IGJhY2tncm91bmQ6ICNmYWZiZmQ7IH0NCmNhcHRpb24sIC5jYXB0aW9uIHsNCiAgY29sb3I6ICM1MjY3Nzk7DQogIGZvbnQtc2l6ZTogMTNweDsNCn0NCg0KLyogS290YWsgcGVuamVsYXNhbiAqLw0KYmxvY2txdW90ZSB7DQogIGJhY2tncm91bmQ6ICNmMmY3ZmE7DQogIGJvcmRlci1sZWZ0OiA1cHggc29saWQgIzU0ODg5YjsNCiAgcGFkZGluZzogMTZweCAyMHB4Ow0KICBmb250LXNpemU6IDE1cHg7DQp9DQouY2FsbG91dCB7DQogIGJhY2tncm91bmQ6ICNmZGYwZjY7DQogIGJvcmRlci1sZWZ0OiA1cHggc29saWQgI2JkNGM4MDsNCiAgYm9yZGVyLXJhZGl1czogNnB4Ow0KICBwYWRkaW5nOiAxOHB4IDIycHg7DQogIG1hcmdpbjogMjJweCAwOw0KfQ0KLmNhbGxvdXQgc3Ryb25nIHsgY29sb3I6ICM5MjM0NWY7IH0NCi5wYXVzZSB7DQogIGJhY2tncm91bmQ6ICNmZmY4ZTk7DQogIGJvcmRlci1sZWZ0OiA1cHggc29saWQgI2Q5OWEyODsNCiAgcGFkZGluZzogMTZweCAyMHB4Ow0KICBtYXJnaW46IDIycHggMDsNCn0NCmRldGFpbHMgew0KICBib3JkZXI6IDFweCBzb2xpZCAjZTZjNmQ2Ow0KICBib3JkZXItcmFkaXVzOiA3cHg7DQogIHBhZGRpbmc6IDEycHggMThweDsNCiAgbWFyZ2luOiAyMHB4IDA7DQp9DQpzdW1tYXJ5IHsNCiAgY29sb3I6ICM5MjM0NWY7DQogIGZvbnQtd2VpZ2h0OiA2MDA7DQogIGN1cnNvcjogcG9pbnRlcjsNCn0NCmltZyB7IG1heC13aWR0aDogMTAwJTsgaGVpZ2h0OiBhdXRvOyB9DQoNCi8qIFRhbXBpbGFuIGxheWFyIGtlY2lsICovDQpAbWVkaWEgKG1heC13aWR0aDogNzY3cHgpIHsNCiAgI2hlYWRlciB7IHBhZGRpbmc6IDI2cHggMjBweDsgfQ0KICAjaGVhZGVyIC50aXRsZSB7IGZvbnQtc2l6ZTogMjhweDsgfQ0KICAjaGVhZGVyIC5zdWJ0aXRsZSB7IGZvbnQtc2l6ZTogMTlweDsgfQ0KICBoMTpub3QoLnRpdGxlKSB7IGZvbnQtc2l6ZTogMjdweDsgfQ0KICAudG9jaWZ5IHsgbWF4LWhlaWdodDogMzAwcHg7IH0NCn0NCg0KLyogVGFtcGlsYW4gY2V0YWsgKi8NCkBtZWRpYSBwcmludCB7DQogICNUT0MsIC5jb2RlLWZvbGRpbmctYnRuLCAuY29kZS10b29scyB7IGRpc3BsYXk6IG5vbmU7IH0NCiAgI2hlYWRlciB7DQogICAgYmFja2dyb3VuZDogd2hpdGUgIWltcG9ydGFudDsNCiAgICBib3gtc2hhZG93OiBub25lOw0KICAgIGJvcmRlcjogMXB4IHNvbGlkICNjY2NjY2M7DQogIH0NCiAgI2hlYWRlciAudGl0bGUsICNoZWFkZXIgLnN1YnRpdGxlLA0KICAjaGVhZGVyIC5hdXRob3IsICNoZWFkZXIgLmRhdGUgeyBjb2xvcjogIzE3M2U1OTsgfQ0KICAubWFpbi1jb250YWluZXIgeyBtYXgtd2lkdGg6IDEwMCUgIWltcG9ydGFudDsgfQ0KICBwcmUgeyB3aGl0ZS1zcGFjZTogcHJlLXdyYXA7IH0NCn0NCjwvc3R5bGU+DQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KA0KICBlY2hvID0gVFJVRSwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gVFJVRSwgZXJyb3IgPSBGQUxTRSwNCiAgZmlnLndpZHRoID0gOC41LCBmaWcuaGVpZ2h0ID0gNS40LCBkcGkgPSAxNDAsDQogIGZpZy5hbGlnbiA9ICJjZW50ZXIiLCBvdXQud2lkdGggPSAiMTAwJSIsIGNvbGxhcHNlID0gVFJVRSwNCiAgY29tbWVudCA9ICIjPiINCikNCm9wdGlvbnMod2lkdGggPSA5MCkNCmBgYA0KDQojIE11bGFpIGRhcmkgc2VidWFoIHBlcnRhbnlhYW4NCg0KQmF5YW5na2FuIGtpdGEgZGltaW50YSBtZW1iYWNhIHBldGEga3JpbWluYWxpdGFzIHN1YXR1IGtvdGEuIEJlYmVyYXBhIHdpbGF5YWggdGFtcGFrIG1lbWlsaWtpIGFuZ2thIHRpbmdnaSBkYW4gbGV0YWtueWEgYmVyZGVrYXRhbi4gKipBcGFrYWggcGVuZ2Vsb21wb2thbiBpdHUgY3VrdXAga3VhdCB1bnR1ayBkaWJlZGFrYW4gZGFyaSBzdXN1bmFuIG5pbGFpIHlhbmcgYWNhaz8qKiBTZXRlbGFoIG1lbmphd2FibnlhLCBraXRhIG1lbXBlcmx1YXMgcGVydGFueWFhbjogKiphcGFrYWgga3JpbWluYWxpdGFzIHN1YXR1IHdpbGF5YWggYmVya2FpdGFuIGRlbmdhbiBwZW5kYXBhdGFuIHdpbGF5YWggZGkgc2VraXRhcm55YT8qKg0KDQpLaXRhIGFrYW4gbWVuZ2lrdXRpIHNhdHUga2FzdXMgZGFyaSBhd2FsIHNhbXBhaSBha2hpcjogKio0OSBsaW5na3VuZ2FuIGRpIENvbHVtYnVzLCBPaGlvLCBtZW5nZ3VuYWthbiBkYXRhIHRhaHVuIDE5ODAqKiB5YW5nIHN1ZGFoIHRlcnNlZGlhIGRhbGFtIHBha2V0IFIuIEluaSBjb250b2ggaGlzdG9yaXMgdW50dWsgYmVsYWphciBtZXRvZGUsIGJ1a2FuIGdhbWJhcmFuIGtvbmRpc2kga290YSBzYWF0IGluaS4NCg0KPGRpdiBjbGFzcz0iY2FsbG91dCI+DQo8c3Ryb25nPkFsdXIgYmVycGlraXIgcHJha3Rpa3VtPC9zdHJvbmc+PGJyPg0KUGFoYW1pIGRhdGEg4oaSIGxpaGF0IHBldGEg4oaSIHRlbnR1a2FuIHRldGFuZ2dhIOKGkiBidWF0IGJvYm90IOKGkiB1amkgcG9sYSBnbG9iYWwg4oaSIGNhcmkgcG9sYSBsb2thbCDihpIgcGVybHVhcyBrZSBkdWEgdmFyaWFiZWwg4oaSIHR1bGlzIGtlc2ltcHVsYW4uDQo8L2Rpdj4NCg0KDQpgYGB7ciBpbnN0YWxhc2ksIGV2YWw9RkFMU0V9DQppbnN0YWxsLnBhY2thZ2VzKGMoInNmIiwgInNwZGVwIiwgInNwRGF0YSIsICJnZ3Bsb3QyIiwgImtuaXRyIiwgInJtYXJrZG93biIpKQ0KYGBgDQoNCkludGVybmV0IGRpcGVybHVrYW4gc2FhdCBtZW1hc2FuZyBwYWtldC4gRGF0YW55YSBiZXJhc2FsIGRhcmkgcGFrZXQgbG9rYWwgc2V0ZWxhaCBpbnN0YWxhc2kuIEluc3RhbGFzaSBzZW5nYWphIHRpZGFrIGJlcmphbGFuIG90b21hdGlzIGtldGlrYSBLbml0Lg0KDQpgYGB7ciBwYWtldC1kYW4tcGVuZ2F0dXJhbn0NCnBha2V0IDwtIGMoInNmIiwgInNwZGVwIiwgInNwRGF0YSIsICJnZ3Bsb3QyIiwgImtuaXRyIiwgInJtYXJrZG93biIpDQpiZWx1bV9hZGEgPC0gcGFrZXRbIXZhcHBseShwYWtldCwgcmVxdWlyZU5hbWVzcGFjZSwgbG9naWNhbCgxKSwgcXVpZXRseSA9IFRSVUUpXQ0KaWYgKGxlbmd0aChiZWx1bV9hZGEpID4gMCkgew0KICBzdG9wKCJQYXNhbmcgcGFrZXQgYmVyaWt1dCBtZWxhbHVpIENvbnNvbGU6ICIsIHBhc3RlKGJlbHVtX2FkYSwgY29sbGFwc2UgPSAiLCAiKSkNCn0NCg0KbGlicmFyeShzZikNCmxpYnJhcnkoc3BkZXApDQpsaWJyYXJ5KGdncGxvdDIpDQoNCkIgPC0gYXMuaW50ZWdlcihwYXJhbXMkbnNpbSkNCmFscGhhIDwtIHBhcmFtcyRhbHBoYQ0Kc3RvcGlmbm90KEIgPj0gOTksIGFscGhhID4gMCwgYWxwaGEgPCAxKQ0Kc2V0LnNlZWQoMjAyNikNCnNwZGVwOjpzZXQuY29yZXNPcHRpb24oTlVMTCkgICMgZWtzZWt1c2kgYmVydXJ1dGFuOyB0aWRhayBtZW1lcmx1a2FuIGNsdXN0ZXINCg0KdGhlbWVfc2V0KHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTIpKQ0KZm10IDwtIGZ1bmN0aW9uKHgpIGZvcm1hdEMoYXMubnVtZXJpYyh4KSwgZGlnaXRzID0gMywgZm9ybWF0ID0gImYiKQ0KZnAgPC0gZnVuY3Rpb24ocCkgZm9ybWF0LnB2YWwoYXMubnVtZXJpYyhwKSwgZGlnaXRzID0gMywgZXBzID0gMC4wMDAxKQ0KcHV0dXNhbiA8LSBmdW5jdGlvbihwKSB7DQogIGlmIChwIDwgYWxwaGEpICJtZW5vbGFrIEgwIiBlbHNlICJiZWx1bSBkYXBhdCBtZW5vbGFrIEgwIg0KfQ0KYGBgDQoNCmBsaWJyYXJ5KClgIG1lbWJ1a2EgcGFrZXQ7IGBCYCBtZW55aW1wYW4gYmFueWFrbnlhIHBlcm11dGFzaTsgYGFscGhhYCBtZW5qYWRpIGFtYmFuZyBwZW5ndWppYW4uIGBmbXQoKWAgZGFuIGBmcCgpYCBoYW55YSBtZXJhcGlrYW4gdGFtcGlsYW4gYW5na2EuIE5pbGFpIGBhbHBoYWAgZGl0ZXRhcGthbiBzZWJlbHVtIG1lbGloYXQgaGFzaWwuDQoNCiMgTWVuZ2VuYWwgZGF0YSBDb2x1bWJ1cw0KDQpEYXRhc2V0ICoqQ29sdW1idXMqKiBtZXJ1cGFrYW4gZGF0YSBzcGFzaWFsIG1lbmdlbmFpICoqNDkgd2lsYXlhaCBsaW5na3VuZ2FuICgqbmVpZ2hib3VyaG9vZHMqKSBkaSBLb3RhIENvbHVtYnVzLCBPaGlvLCBBbWVyaWthIFNlcmlrYXQsIHBhZGEgdGFodW4gMTk4MCoqLiBEYXRhIGluaSB0ZXJzZWRpYSBkYWxhbSBwYWtldCBSIGBzcERhdGFgIGRhbiBkYXBhdCBkaWd1bmFrYW4gdW50dWsgbWVtcGVsYWphcmkgcG9sYSBzdWF0dSB2YXJpYWJlbCBzZXJ0YSBodWJ1bmdhbm55YSBkZW5nYW4ga29uZGlzaSB3aWxheWFoIGRpIHNla2l0YXJueWEuIFtEb2t1bWVudGFzaSBkYXRhIENvbHVtYnVzXShodHRwczovL3NlYXJjaC5yLXByb2plY3Qub3JnL0NSQU4vcmVmbWFucy9zcERhdGEvaHRtbC9jb2x1bWJ1cy5odG1sKS4NCg0KKipTYXR1IGJhcmlzIGRhdGEgbWV3YWtpbGkgc2F0dSB3aWxheWFoKiosIGJ1a2FuIHNhdHUgcGVuZHVkdWsgYXRhdSBzYXR1IHJ1bWFoIHRhbmdnYS4gU2V0aWFwIHdpbGF5YWggbWVtaWxpa2kgaW5mb3JtYXNpIGthcmFrdGVyaXN0aWsgd2lsYXlhaCBkYW4gZ2VvbWV0cmkgYmVydXBhIHBvbGlnb24geWFuZyBtZW5nZ2FtYmFya2FuIGJhdGFzbnlhLiBKYWRpLCBraXRhIGRhcGF0IG1lbmdldGFodWkgYnVrYW4gaGFueWEgbmlsYWkgdmFyaWFiZWxueWEsIHRldGFwaSBqdWdhIHBvc2lzaSB3aWxheWFoIGRhbiBzaWFwYSBzYWphIHRldGFuZ2dhbnlhLg0KDQojIyBNZW1iYWNhIGRhdGEgZGFuIG1lbmdlbmFsaSB1bml0IHBlbmdhbWF0YW4NCg0KRGFsYW0gZGF0YXNldCBDb2x1bWJ1cywgKip1bml0IHBlbmdhbWF0YW5ueWEgYWRhbGFoIHdpbGF5YWggbGluZ2t1bmdhbiAoKm5laWdoYm91cmhvb2QqKSoqLiBBcnRpbnlhLCBzZXRpYXAgYmFyaXMgZGF0YSBtZXdha2lsaSBzYXR1IHdpbGF5YWggZGFuIG1lbXVhdCBrYXJha3RlcmlzdGlrIHdpbGF5YWggdGVyc2VidXQsIHNlcGVydGkgYW5na2Ega3JpbWluYWxpdGFzIChgQ1JJTUVgKSwgcGVuZGFwYXRhbiBydW1haCB0YW5nZ2EgKGBJTkNgKSwgZGFuIG5pbGFpIHJ1bWFoIChgSE9WQUxgKS4gS2FyZW5hIHRlcmRhcGF0IDQ5IHdpbGF5YWggeWFuZyBkaWFtYXRpLCBkYXRhc2V0IGluaSBtZW1pbGlraSA0OSBiYXJpcy4NCg0KU2ViYWdhaSBjb250b2gsIG5pbGFpIGBDUklNRWAsIGBJTkNgLCBkYW4gYEhPVkFMYCBwYWRhIGJhcmlzIHBlcnRhbWEgc2VtdWFueWEgbWVydWp1ayBwYWRhIHdpbGF5YWggeWFuZyBzYW1hLiBCYXJpcyBrZWR1YSBtZW11YXQgaW5mb3JtYXNpIHVudHVrIHdpbGF5YWggbGFpbiwgZGVtaWtpYW4gc2V0ZXJ1c255YS4gRGVuZ2FuIGRlbWlraWFuLCBhbmFsaXNpcyB5YW5nIGtpdGEgbGFrdWthbiBtZW1iYW5kaW5na2FuIGthcmFrdGVyaXN0aWsgKiphbnRhcndpbGF5YWgqKiwgYnVrYW4gYW50YXJpbmRpdmlkdS4NCg0KU2VsYWluIGluZm9ybWFzaSBkYWxhbSB0YWJlbCwgc2V0aWFwIGJhcmlzIGp1Z2EgdGVyaHVidW5nIGRlbmdhbiAqKmdlb21ldHJpIGJlcnVwYSBwb2xpZ29uKiosIHlhaXR1IGJlbnR1ayBiYXRhcyB3aWxheWFoIHBhZGEgcGV0YS4gR2VvbWV0cmkgaW5pIG1lbXVuZ2tpbmthbiBraXRhIG1lbmFtcGlsa2FuIG5pbGFpIHZhcmlhYmVsIGRhbGFtIHBldGEgZGFuIG1lbmVudHVrYW4gd2lsYXlhaCBtYW5hIHlhbmcgc2FsaW5nIGJlcnRldGFuZ2dhLg0KDQpMYW5na2FoIHBlcnRhbWEgcHJha3Rpa3VtIGFkYWxhaCBtZW1iYWNhIGRhdGEgc3Bhc2lhbCBDb2x1bWJ1cyBkYXJpIHBha2V0IGBzcERhdGFgIGRhbiBtZW55aW1wYW5ueWEgZGFsYW0gb2JqZWsgYmVybmFtYSBgY29sYC4gU2VsYW5qdXRueWEsIGtpdGEgbWVtZXJpa3NhIGtlbGVuZ2thcGFuIGRhdGEsIG1lbmFtYmFoa2FuIG5vbW9yIHVydXQgYGlkYCB1bnR1ayBtZW11ZGFoa2FuIHBlbnllYnV0YW4gd2lsYXlhaCwgZGFuIG1lbmFtcGlsa2FuIGVuYW0gYmFyaXMgcGVydGFtYSB1bnR1ayBtZW5nZW5hbGkgc3VzdW5hbiBkYXRhbnlhLg0KDQpgYGB7ciBiYWNhLWRhdGF9DQpsb2thc2lfZGF0YSA8LSBzeXN0ZW0uZmlsZSgic2hhcGVzL2NvbHVtYnVzLmdwa2ciLCBwYWNrYWdlID0gInNwRGF0YSIpDQpzdG9waWZub3QobnpjaGFyKGxva2FzaV9kYXRhKSkNCmNvbCA8LSBzdF9yZWFkKGxva2FzaV9kYXRhLCBxdWlldCA9IFRSVUUpDQoNCiMgRGF0YXNldCBpbmkgbWVtYWthaSBrb29yZGluYXQgbG9rYWwgZGVuZ2FuIHNhdHVhbiB0aWRhayBkaWtldGFodWkuDQojIFNpbXBhbiBtZXRhZGF0YSBhc2xpbnlhOyBsZXBhc2thbiBsYWJlbCBDUlMgdW50dWsgbWVuZ2dhbWJhciBiaWRhbmcgbG9rYWwuDQojIEFuZ2thIGtvb3JkaW5hdCB0aWRhayBkaXViYWggZGFuIHRpZGFrIGRpcmVwcm95ZWtzaSBrZSBidWp1ci9saW50YW5nLg0KY3JzX2FzbGkgPC0gc3RfY3JzKGNvbCkNCmNvbCA8LSBzdF9zZXRfY3JzKGNvbCwgTkEpDQoNCiMgSUQgbWVuZ2lrdXRpIHVydXRhbiBnZW9tZXRyaSwgYnVrYW4gdXJ1dGFuIG5pbGFpIENSSU1FLg0KY29sJGlkIDwtIHNlcV9sZW4obnJvdyhjb2wpKQ0Kc3RvcGlmbm90KG5yb3coY29sKSA9PSA0OSwgYWxsKHN0X2lzX3ZhbGlkKGNvbCkpKQ0Kc3RvcGlmbm90KGFsbChpcy5maW5pdGUoY29sJENSSU1FKSksIGFsbChpcy5maW5pdGUoY29sJElOQykpKQ0KDQprbml0cjo6a2FibGUoDQogIGhlYWQoc3RfZHJvcF9nZW9tZXRyeShjb2wpWywgYygiaWQiLCAiTkVJRyIsICJDUklNRSIsICJJTkMiLCAiSE9WQUwiKV0pLA0KICBkaWdpdHMgPSAyLCBjYXB0aW9uID0gIkVuYW0gd2lsYXlhaCBwZXJ0YW1hOyBJRCBkaXBha2FpIHBhZGEgdGFiZWwgZGFuIHBldGEgbW9kdWwuIg0KKQ0KYGBgDQoNCnwgS29sb20gfCBBcnRpIHwgU2F0dWFuIHwNCnw6LS18Oi0tfDotLXwNCnwgYENSSU1FYCB8IFBlbmN1cmlhbiBydW1haCBkYW4ga2VuZGFyYWFuIGRhbGFtIHdpbGF5YWggfCBQZXIgMS4wMDAgcnVtYWggdGFuZ2dhIHwNCnwgYElOQ2AgfCBQZW5kYXBhdGFuIHJ1bWFoIHRhbmdnYSB8IFJpYnVhbiBkb2xhciBBUyB8DQp8IGBIT1ZBTGAgfCBOaWxhaSBydW1haDsgZGlwYWthaSBwYWRhIGxhdGloYW4gdGFtYmFoYW4gfCBSaWJ1YW4gZG9sYXIgQVMgfA0KfCBgZ2VvbWV0cnlgIHwgQmVudHVrIGRhbiBwb3Npc2kgYmF0YXMgd2lsYXlhaCB8IFBvbGlnb24gfA0KfCBgaWRgIHwgTm9tb3IgYmFyaXMgeWFuZyBraXRhIGJ1YXQgfCBQZW5hbmRhLCBidWthbiB2YXJpYWJlbCBhbmFsaXNpcyB8DQoNCmBDUklNRWAgdGlkYWsgbWVuY2FrdXAgc2VtdWEgamVuaXMga2VqYWhhdGFuLiBJc3RpbGFoICoqdGluZ2dpL3JlbmRhaCoqIGRpIG1vZHVsIGJlcnNpZmF0IHJlbGF0aWYgdGVyaGFkYXAgZGF0YSBpbmkuIE1ldGFkYXRhIENvbHVtYnVzIGp1Z2EgdGlkYWsgbWVueWVkaWFrYW4gZGFzYXIgeWFuZyBjdWt1cCB1bnR1ayBtZW5hZnNpcmthbiBqYXJhayBrb29yZGluYXQgc2ViYWdhaSBraWxvbWV0ZXI7IGthcmVuYSBpdHUga2l0YSBtZW1ha2FpIHBlcnNpbmdndW5nYW4gYmF0YXMgd2lsYXlhaC4gW01ldGFkYXRhIGRhdGEgQ29sdW1idXNdKGh0dHBzOi8vc2VhcmNoLnItcHJvamVjdC5vcmcvQ1JBTi9yZWZtYW5zL3NwRGF0YS9odG1sL2NvbHVtYnVzLmh0bWwpLg0KDQpTZWJhZ2FpIGlsdXN0cmFzaSwgKipDUklNRSA9IDMwKiogYmVyYXJ0aSB0ZXJkYXBhdCAzMCBrZWphZGlhbiBwZW5jdXJpYW4gcnVtYWggZGFuIGtlbmRhcmFhbiBwZXIgMS4wMDAgcnVtYWggdGFuZ2dhLiBBbmdrYSBpbmkgbWVydXBha2FuIHVrdXJhbiByZWxhdGlmIHRlcmhhZGFwIGp1bWxhaCBydW1haCB0YW5nZ2EsIGJ1a2FuIGJlcmFydGkgMzAlIHJ1bWFoIHRhbmdnYSBtZW5qYWRpIGtvcmJhbi4gU2VtZW50YXJhIGl0dSwgKipJTkMgPSAxNSoqIG1lbnVuanVra2FuIG5pbGFpIHBlbmRhcGF0YW4gcnVtYWggdGFuZ2dhIHNlYmVzYXIgMTUgcmlidSBkb2xhciBBUyBwYWRhIHVrdXJhbiB5YW5nIGRpY2F0YXQgZGFsYW0gZGF0YXNldC4NCg0KS2l0YSBha2FuIG1lbmdndW5ha2FuIGRhdGEgaW5pIHVudHVrIG1lbmphd2FiIGR1YSBwZXJ0YW55YWFuIHNlY2FyYSBiZXJ0YWhhcDoNCg0KMS4gKipBdXRva29yZWxhc2kgc3Bhc2lhbCB1bml2YXJpYXQ6KiogYXBha2FoIHdpbGF5YWggZGVuZ2FuIENSSU1FIHRpbmdnaSBjZW5kZXJ1bmcgYmVydGV0YW5nZ2EgZGVuZ2FuIHdpbGF5YWggeWFuZyBDUklNRS1ueWEganVnYSB0aW5nZ2k/DQoyLiAqKkFzb3NpYXNpIHNwYXNpYWwgYml2YXJpYXQ6KiogYXBha2FoIHdpbGF5YWggZGVuZ2FuIENSSU1FIHRpbmdnaSBjZW5kZXJ1bmcgYmVydGV0YW5nZ2EgZGVuZ2FuIHdpbGF5YWggeWFuZyBtZW1pbGlraSBJTkMgcmVuZGFoPw0KDQpQYWRhIHBlcnRhbnlhYW4gcGVydGFtYSwga2l0YSBtZW1iYW5kaW5na2FuICoqdmFyaWFiZWwgeWFuZyBzYW1hIGFudGFyd2lsYXlhaCoqLiBQYWRhIHBlcnRhbnlhYW4ga2VkdWEsIGtpdGEgbWVtYmFuZGluZ2thbiAqKmR1YSB2YXJpYWJlbCBiZXJiZWRhIGFudGFyd2lsYXlhaCoqLiBQZXJiZWRhYW4gaW5pbGFoIHlhbmcgbWVuamFkaSBkYXNhciBwZXJwaW5kYWhhbiBkYXJpIGFuYWxpc2lzIHVuaXZhcmlhdCBrZSBiaXZhcmlhdC4NCg0KYGBge3IgcmluZ2thc2FuLWRhdGF9DQpzdW1tYXJ5KHN0X2Ryb3BfZ2VvbWV0cnkoY29sKVssIGMoIkNSSU1FIiwgIklOQyIsICJIT1ZBTCIpXSkNCmBgYA0KDQojIyBMaWhhdCBwZXRhIHNlYmVsdW0gbWVuZ2hpdHVuZyBpbmRla3MNCg0KU2ViZWx1bSBtZW5naGl0dW5nIGF1dG9rb3JlbGFzaSBzcGFzaWFsLCBraXRhIG1lbWV0YWthbiBuaWxhaSBgQ1JJTUVgIHVudHVrIG1lbGloYXQgcGVyc2ViYXJhbiBrcmltaW5hbGl0YXMgYW50YXJ3aWxheWFoLiBXYXJuYSBwYWRhIHBldGEgbWVudW5qdWtrYW4gYmVzYXIgbmlsYWlueWE6IHNlbWFraW4gbWVuZGVrYXRpIGt1bmluZywgc2VtYWtpbiB0aW5nZ2kgYW5na2Ega3JpbWluYWxpdGFzOyBzZW1ha2luIG1lbmRla2F0aSBiaXJ1IHR1YSwgc2VtYWtpbiByZW5kYWguDQoNCmBgYHtyIHBldGEtYXdhbCwgZmlnLmhlaWdodD00LjcsIGZpZy5jYXA9IlBldGEgYXdhbDoga2VkdWEgdmFyaWFiZWwgbWVtaWxpa2kgbGVnZW5kYSBkYW4gc2F0dWFuIHlhbmcgYmVyYmVkYS4ifQ0KIyBEdWEgcGV0YSB0ZXJwaXNhaCBtZW5qYWdhIGxlZ2VuZGEgc2VzdWFpIHNhdHVhbiBtYXNpbmctbWFzaW5nLg0KZ2dwbG90KGNvbCkgKw0KICBnZW9tX3NmKGFlcyhmaWxsID0gQ1JJTUUpLCBjb2xvciA9ICJ3aGl0ZSIsIGxpbmV3aWR0aCA9IDAuMykgKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfYyhvcHRpb24gPSAiQyIsIG5hbWUgPSAiQ1JJTUUiKSArDQogIGxhYnModGl0bGUgPSAiRGkgbWFuYSBrcmltaW5hbGl0YXMgcmVsYXRpZiB0aW5nZ2k/Iiwgc3VidGl0bGUgPSAiQ29sdW1idXMsIDE5ODAiKSArDQogIGNvb3JkX3NmKGRhdHVtID0gTkEpICsNCiAgdGhlbWVfdm9pZCgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikNCg0KYGBgDQoNCioqQ2FyYSBtZW1iYWNhOioqIHdhcm5hIG1lbnVuanVra2FuIGJlc2FybnlhIG5pbGFpLiBXaWxheWFoIHlhbmcgdGFtcGFrIGJlcmRla2F0YW4gZGFuIGJlcndhcm5hIG1pcmlwIG1lbWJlcmkgZHVnYWFuIHBlbmdlbG9tcG9rYW4uIEtpdGEgbWFzaWggbWVtZXJsdWthbiBhdHVyYW4gdGV0YW5nZ2EgZGFuIHVqaSBzdGF0aXN0aWsgdW50dWsgbWVuaWxhaSBkdWdhYW4gdGVyc2VidXQuDQoNClNlY2FyYSB2aXN1YWwsIHdpbGF5YWggZGVuZ2FuIGFuZ2thIGtyaW1pbmFsaXRhcyByZWxhdGlmIHRpbmdnaSB0YW1wYWsgYmVyZGVrYXRhbiBkaSBiYWdpYW4gdGVuZ2FoIHBldGEsIHNlZGFuZ2thbiBuaWxhaSB5YW5nIGxlYmloIHJlbmRhaCBiYW55YWsgZGl0ZW11a2FuIGRpIGJhZ2lhbiB0ZXBpLiBQb2xhIGluaSBtZW1iZXJpIGR1Z2FhbiBhd2FsIGFkYW55YSBwZW5nZWxvbXBva2FuIHNwYXNpYWwsIHlhbmcgc2VsYW5qdXRueWEgcGVybHUgZGlwZXJpa3NhIG1lbGFsdWkgdWppIGF1dG9rb3JlbGFzaSBzcGFzaWFsLg0KDQoNCmBgYHtyfQ0KZ2dwbG90KGNvbCkgKw0KICBnZW9tX3NmKGFlcyhmaWxsID0gSU5DKSwgY29sb3IgPSAid2hpdGUiLCBsaW5ld2lkdGggPSAwLjMpICsNCiAgc2NhbGVfZmlsbF92aXJpZGlzX2Mob3B0aW9uID0gIkQiLCBuYW1lID0gIklOQyIpICsNCiAgbGFicyh0aXRsZSA9ICJCYWdhaW1hbmEgcG9sYSBwZW5kYXBhdGFuIHJ1bWFoIHRhbmdnYT8iLCBzdWJ0aXRsZSA9ICJDb2x1bWJ1cywgMTk4MCIpICsNCiAgY29vcmRfc2YoZGF0dW0gPSBOQSkgKw0KICB0aGVtZV92b2lkKCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQ0KYGBgDQoNClBldGEgbWVudW5qdWtrYW4gYmFod2EgcGVuZGFwYXRhbiBydW1haCB0YW5nZ2EgKGBJTkNgKSByZWxhdGlmIHJlbmRhaCwgZGl0YW5kYWkgd2FybmEgdW5ndSBoaW5nZ2EgYmlydSwgYmFueWFrIGRpdGVtdWthbiBkaSBiYWdpYW4gdGVuZ2FoLiBQZW5kYXBhdGFuIHJlbGF0aWYgdGluZ2dpLCBkaXRhbmRhaSB3YXJuYSBoaWphdSBoaW5nZ2Ega3VuaW5nLCB0YW1wYWsgcGFkYSBiZWJlcmFwYSB3aWxheWFoIGRpIGJhZ2lhbiB0ZXBpLCB0ZXJ1dGFtYSBzaXNpIGthbmFuIHBldGEuDQoNCkRpYmFuZGluZ2thbiBkZW5nYW4gcGV0YSBgQ1JJTUVgLCB0ZXJsaWhhdCBrZWNlbmRlcnVuZ2FuIGJhaHdhIHdpbGF5YWggYmVycGVuZGFwYXRhbiByZW5kYWggbWVtaWxpa2kga3JpbWluYWxpdGFzIGxlYmloIHRpbmdnaS4gTmFtdW4sIHBlbmdhbWF0YW4gdmlzdWFsIGluaSBiZWx1bSBtZW1idWt0aWthbiBodWJ1bmdhbiBzdGF0aXN0aWssIGtodXN1c255YSBhbnRhcmEga3JpbWluYWxpdGFzIHN1YXR1IHdpbGF5YWggZGFuIHBlbmRhcGF0YW4gd2lsYXlhaCB0ZXRhbmdnYW55YS4NCg0KPGRpdiBjbGFzcz0icGF1c2UiPjxzdHJvbmc+QmVyaGVudGkgc2VqZW5hay48L3N0cm9uZz4gUGlsaWggc2F0dSBiYWdpYW4gcGV0YSBkZW5nYW4gQ1JJTUUgcmVsYXRpZiB0aW5nZ2kuIEFwYWthaCB0ZXRhbmdnYW55YSB0YW1wYWsgc2VydXBhPyBTaW1wYW4gZHVnYWFubXUgdW50dWsgZGliYW5kaW5na2FuIGRlbmdhbiBoYXNpbCBNb3Jhbi48L2Rpdj4NCg0KIyBBcGEgYXJ0aSDigJxiZXJ0ZXRhbmdnYeKAnT8NCg0KIyMgUXVlZW4gY29udGlndWl0eSBkYW4gYm9ib3Qgc3Bhc2lhbA0KDQpBbmFsaXNpcyBzcGFzaWFsIG1lbWVybHVrYW4gZGVmaW5pc2kga2V0ZXRhbmdnYWFuIHVudHVrIG1lbmVudHVrYW4gaHVidW5nYW4gYW50YXJ3aWxheWFoLiBTYWxhaCBzYXR1IHBlbmRla2F0YW5ueWEgYWRhbGFoICoqUXVlZW4gY29udGlndWl0eSoqLCB5YWl0dSBkdWEgd2lsYXlhaCBkaWFuZ2dhcCBiZXJ0ZXRhbmdnYSBhcGFiaWxhIGJlcmJhZ2kgc2lzaSBhdGF1IHRpdGlrIHN1ZHV0LiBTZWJhZ2FpIHBlbWJhbmRpbmcsICoqUm9vayBjb250aWd1aXR5KiogaGFueWEgbWVuZ2FuZ2dhcCBkdWEgd2lsYXlhaCBiZXJ0ZXRhbmdnYSBhcGFiaWxhIGJlcmJhZ2kgc2lzaS4NCg0KRGFsYW0gcHJha3Rpa3VtIGluaSwgaHVidW5nYW4ga2V0ZXRhbmdnYWFuIGRpdGVudHVrYW4gbWVuZ2d1bmFrYW4gUXVlZW4gY29udGlndWl0eSwga2VtdWRpYW4gZGlueWF0YWthbiBkYWxhbSBib2JvdCBzcGFzaWFsLiBCb2JvdCB0ZXJzZWJ1dCBtZW5lbnR1a2FuIGtvbnRyaWJ1c2kgc2V0aWFwIHdpbGF5YWggdGV0YW5nZ2EgZGFsYW0gcGVyaGl0dW5nYW4gc3RhdGlzdGlrIHNwYXNpYWwuDQoNCmBgYHtyIGJvYm90LXNwYXNpYWx9DQpuYiA8LSBwb2x5Mm5iKGNvbCwgcXVlZW4gPSBUUlVFLCByb3cubmFtZXMgPSBhcy5jaGFyYWN0ZXIoY29sJGlkKSkNCmp1bWxhaF90ZXRhbmdnYSA8LSBjYXJkKG5iKQ0Kc3VtbWFyeShqdW1sYWhfdGV0YW5nZ2EpDQpzdG9waWZub3QoYWxsKGp1bWxhaF90ZXRhbmdnYSA+IDApKQ0KDQpsd19CIDwtIG5iMmxpc3R3KG5iLCBzdHlsZSA9ICJCIiwgemVyby5wb2xpY3kgPSBGQUxTRSkNCmx3X1cgPC0gbmIybGlzdHcobmIsIHN0eWxlID0gIlciLCB6ZXJvLnBvbGljeSA9IEZBTFNFKQ0KVyA8LSBsaXN0dzJtYXQobHdfVykNCg0Kc3RvcGlmbm90KGFsbChkaWFnKFcpID09IDApLCBhbGwoYWJzKHJvd1N1bXMoVykgLSAxKSA8IDFlLTEwKSkNCmRhdGEuZnJhbWUoDQogIHdpbGF5YWggPSBucm93KGNvbCksDQogIHBhc2FuZ2FuX3RldGFuZ2dhX3VuaWsgPSBzdW0oanVtbGFoX3RldGFuZ2dhKSAvIDIsDQogIG1pbmltdW1fdGV0YW5nZ2EgPSBtaW4oanVtbGFoX3RldGFuZ2dhKSwNCiAgbWFrc2ltdW1fdGV0YW5nZ2EgPSBtYXgoanVtbGFoX3RldGFuZ2dhKQ0KKQ0KYGBgDQoNCkJlcmRhc2Fya2FuIFF1ZWVuIGNvbnRpZ3VpdHksIHRlcmRhcGF0ICoqMTE4IHBhc2FuZ2FuIHdpbGF5YWggYmVydGV0YW5nZ2EqKiBwYWRhIDQ5IHdpbGF5YWggQ29sdW1idXMuIFNldGlhcCB3aWxheWFoIG1lbWlsaWtpICoqMuKAkzEwIHRldGFuZ2dhKiosIGRlbmdhbiByYXRhLXJhdGEgc2VraXRhciAqKjQsODIgdGV0YW5nZ2EqKi4gRGVuZ2FuIGRlbWlraWFuLCBzZWx1cnVoIHdpbGF5YWggbWVtaWxpa2kgdGV0YW5nZ2EgZGFuIHRpZGFrIHRlcmRhcGF0IHdpbGF5YWggeWFuZyB0ZXJpc29sYXNpLiBTZXRpYXAgcGFzYW5nYW4gZGloaXR1bmcgc2VrYWxpOyBodWJ1bmdhbiB3aWxheWFoIEHigJNCIHNhbWEgZGVuZ2FuIELigJNBLg0KDQpEYWZ0YXIga2V0ZXRhbmdnYWFuIGRpc2ltcGFuIGRhbGFtIG9iamVrIGBuYmAsIGtlbXVkaWFuIGRpZ3VuYWthbiB1bnR1ayBtZW1iZW50dWsgZHVhIGplbmlzIGJvYm90Og0KDQotICoqQm9ib3QgYmluZXIgKGBsd19CYCkqKjogYmVybmlsYWkgMSB1bnR1ayB3aWxheWFoIHlhbmcgYmVydGV0YW5nZ2EgZGFuIDAgdW50dWsgd2lsYXlhaCB5YW5nIHRpZGFrIGJlcnRldGFuZ2dhLg0KLSAqKkJvYm90IHRlcnN0YW5kYXJkaXNhc2kgcGVyIGJhcmlzIChgbHdfV2ApKio6IGJvYm90IHNldGlhcCB0ZXRhbmdnYSBkaWJhZ2kgZGVuZ2FuIGp1bWxhaCB0ZXRhbmdnYSB3aWxheWFoIGFzYWwsIHNlaGluZ2dhIHRvdGFsIGJvYm90IHBhZGEgc2V0aWFwIGJhcmlzIG1lbmphZGkgMS4gU2ViYWdhaSBjb250b2gsIGppa2Egc3VhdHUgd2lsYXlhaCBtZW1pbGlraSBlbXBhdCB0ZXRhbmdnYSwgc2V0aWFwIHRldGFuZ2dhbnlhIG1lbXBlcm9sZWggYm9ib3QgwrwuDQoNCk1hdHJpa3MgYFdgIG1lcnVwYWthbiBiZW50dWsgbWF0cmlrcyBkYXJpIGBsd19XYC4gRWxlbWVuIGRpYWdvbmFsbnlhIGJlcm5pbGFpIG5vbCBrYXJlbmEgd2lsYXlhaCB0aWRhayBkaWFuZ2dhcCBzZWJhZ2FpIHRldGFuZ2dhIGJhZ2kgZGlyaW55YSBzZW5kaXJpLiBQZW1lcmlrc2FhbiBtZWxhbHVpIGBzdG9waWZub3QoKWAgbWVtYXN0aWthbiBiYWh3YSBrb25kaXNpIHRlcnNlYnV0IHRlcnBlbnVoaSBzZWJlbHVtIGFuYWxpc2lzIGRpbGFuanV0a2FuLg0KDQpgYGB7ciBnYW1iYXItdGV0YW5nZ2EsIGZpZy5oZWlnaHQ9NSwgZmlnLmNhcD0iR2FyaXMgbWVudW5qdWtrYW4gaHVidW5nYW4gUXVlZW4gYW50YXJ3aWxheWFoLCBidWthbiBqYXJpbmdhbiBqYWxhbi4ifQ0KdGl0aWsgPC0gc3RfY29vcmRpbmF0ZXMoc3RfY2VudHJvaWQoc3RfZ2VvbWV0cnkoY29sKSkpDQpwbG90KHN0X2dlb21ldHJ5KGNvbCksIGNvbCA9ICIjZjBmNWY3IiwgYm9yZGVyID0gIiM4MTk1YTEiLCBtYWluID0gIlNpYXBhIGJlcnRldGFuZ2dhIGRlbmdhbiBzaWFwYT8iKQ0KcGxvdChuYiwgdGl0aWssIGFkZCA9IFRSVUUsIGNvbCA9ICIjMjU4NThlIiwgcGNoID0gMTksIGNleCA9IDAuNDUpDQpgYGANCg0KR2FtYmFyIG1lbnVuanVra2FuIGh1YnVuZ2FuIGtldGV0YW5nZ2FhbiBhbnRhcndpbGF5YWggYmVyZGFzYXJrYW4gKipRdWVlbiBjb250aWd1aXR5KiouIFNldGlhcCB0aXRpayBtZXdha2lsaSBwdXNhdCBnZW9tZXRyaXMgKCpjZW50cm9pZCopIHN1YXR1IHdpbGF5YWgsIHNlZGFuZ2thbiBnYXJpcyBtZW5naHVidW5na2FuIGR1YSB3aWxheWFoIHlhbmcgYmVyYmFnaSBzaXNpIGF0YXUgdGl0aWsgc3VkdXQuDQoNCkp1bWxhaCBnYXJpcyB5YW5nIHRlcmh1YnVuZyBwYWRhIHN1YXR1IHRpdGlrIG1lbnVuanVra2FuIGJhbnlha255YSB0ZXRhbmdnYSB3aWxheWFoIHRlcnNlYnV0LiBTZWx1cnVoIHdpbGF5YWggbWVtaWxpa2kgaHVidW5nYW4ga2V0ZXRhbmdnYWFuIHNlaGluZ2dhIHRpZGFrIHRlcmRhcGF0IHdpbGF5YWggeWFuZyB0ZXJpc29sYXNpLiBHYXJpcyBwYWRhIGdhbWJhciBtZW51bmp1a2thbiBodWJ1bmdhbiBzcGFzaWFsLCBidWthbiBqYXJpbmdhbiBqYWxhbiBtYXVwdW4ga2VtaXJpcGFuIG5pbGFpIGtyaW1pbmFsaXRhcy4NCg0KIyMgU3BhdGlhbCBsYWc6IHJpbmdrYXNhbiBuaWxhaSB0ZXRhbmdnYQ0KDQoqKlNwYXRpYWwgbGFnKiogZGlndW5ha2FuIHVudHVrIG1lcmFuZ2t1bSBuaWxhaSBzdWF0dSB2YXJpYWJlbCBkaSB3aWxheWFoLXdpbGF5YWggdGV0YW5nZ2EuIFBhZGEgY29udG9oIGluaSwga2l0YSBtZW5naGl0dW5nIHJhdGEtcmF0YSBhbmdrYSBrcmltaW5hbGl0YXMgdGV0YW5nZ2EgbWVuZ2d1bmFrYW4gYm9ib3QgeWFuZyBzdWRhaCBkaWJ1YXQuDQoNCkthcmVuYSBzZXRpYXAgdGV0YW5nZ2EgbWVuZGFwYXQgYm9ib3QgeWFuZyBzYW1hLCBwZXJoaXR1bmdhbm55YSBjdWt1cCBkZW5nYW4gbWVyYXRhLXJhdGFrYW4gbmlsYWkgYENSSU1FYCBzZWx1cnVoIHRldGFuZ2dhLiBOaWxhaSBgQ1JJTUVgIHdpbGF5YWggeWFuZyBzZWRhbmcgZGlhbWF0aSB0aWRhayBpa3V0IGRpaGl0dW5nLg0KDQpcWw0KKFd4KV9pID0gXHN1bV9qIHdfe2lqfXhfai4NClxdDQoNCmBgYHtyIGxhZy1tYW51YWx9DQp4IDwtIGNvbCRDUklNRQ0KeSA8LSBjb2wkSU5DDQpuIDwtIGxlbmd0aCh4KQ0KbGFnX3ggPC0gbGFnLmxpc3R3KGx3X1csIHgpDQoNCmkgPC0gMUwNCmogPC0gbmJbW2ldXQ0Ka25pdHI6OmthYmxlKGRhdGEuZnJhbWUoDQogIGlkX3RldGFuZ2dhID0gY29sJGlkW2pdLCBDUklNRV90ZXRhbmdnYSA9IHhbal0sIGJvYm90ID0gbHdfVyR3ZWlnaHRzW1tpXV0NCiksIGRpZ2l0cyA9IDMsIGNhcHRpb24gPSBwYXN0ZSgiVGV0YW5nZ2Egd2lsYXlhaCBJRCIsIGNvbCRpZFtpXSkpDQoNCmMoQ1JJTUVfbG9rYXNpID0geFtpXSwNCiAgcmF0YV9yYXRhX21hbnVhbCA9IG1lYW4oeFtqXSksDQogIGxhZ19kYXJpX1IgPSBsYWdfeFtpXSkNCnN0b3BpZm5vdChpc1RSVUUoYWxsLmVxdWFsKG1lYW4oeFtqXSksIGxhZ194W2ldKSkpDQpgYGANCg0KV2lsYXlhaCBJRCAxIGJlcnRldGFuZ2dhIGRlbmdhbiB3aWxheWFoIElEIDIgZGFuIElEIDMuIEFuZ2thIGtyaW1pbmFsaXRhcyBrZWR1YSB0ZXRhbmdnYW55YSBhZGFsYWggKioxOCw4MDIqKiBkYW4gKiozMCw2MjcqKiwgc2VoaW5nZ2EgcmF0YS1yYXRhbnlhIHNla2l0YXIgKioyNCw3MTQgcGVyIDEuMDAwIHJ1bWFoIHRhbmdnYSoqLiBOaWxhaSByYXRhLXJhdGEgaW5pbGFoIHlhbmcgZGlzZWJ1dCAqKnNwYXRpYWwgbGFnIENSSU1FIHVudHVrIHdpbGF5YWggSUQgMSoqLg0KDQpTZW1lbnRhcmEgaXR1LCBhbmdrYSBrcmltaW5hbGl0YXMgd2lsYXlhaCBJRCAxIHNlbmRpcmkgYWRhbGFoICoqMTUsNzI2IHBlciAxLjAwMCBydW1haCB0YW5nZ2EqKi4gSmFkaSwgYW5na2Ega3JpbWluYWxpdGFzIHdpbGF5YWggSUQgMSBsZWJpaCByZW5kYWggZGFyaXBhZGEgcmF0YS1yYXRhIHRldGFuZ2dhbnlhLiBIYXNpbCBwZXJoaXR1bmdhbiBtYW51YWwgZGFuIGZ1bmdzaSBgbGFnLmxpc3R3KClgIG1lbnVuanVra2FuIG5pbGFpIHlhbmcgc2FtYS4NCg0KIyBBdXRva29yZWxhc2kgc3Bhc2lhbCBnbG9iYWw6IHNhdHUgdmFyaWFiZWwNCg0KKipBdXRva29yZWxhc2kgc3Bhc2lhbCBnbG9iYWwqKiBkaWd1bmFrYW4gdW50dWsgbWVsaWhhdCBhcGFrYWggbmlsYWkgc3VhdHUgdmFyaWFiZWwgbWVtYmVudHVrIHBvbGEgdGVydGVudHUgZGkgc2VsdXJ1aCB3aWxheWFoIHlhbmcgZGlhbWF0aS4gUGFkYSBkYXRhIENvbHVtYnVzLCBraXRhIGluZ2luIG1lbmdldGFodWkgYXBha2FoIHdpbGF5YWggZGVuZ2FuIGFuZ2thIGtyaW1pbmFsaXRhcyB0aW5nZ2kgY2VuZGVydW5nIGJlcmRla2F0YW4gZGVuZ2FuIHdpbGF5YWggeWFuZyBqdWdhIG1lbWlsaWtpIGFuZ2thIGtyaW1pbmFsaXRhcyB0aW5nZ2kuDQoNClBvbGEgaHVidW5nYW4gYW50YXJ3aWxheWFoIGRhcGF0IGJlcnVwYToNCg0KLSAqKkF1dG9rb3JlbGFzaSBwb3NpdGlmOioqIHdpbGF5YWggZGVuZ2FuIG5pbGFpIHRpbmdnaSBjZW5kZXJ1bmcgYmVydGV0YW5nZ2EgZGVuZ2FuIHdpbGF5YWggYmVybmlsYWkgdGluZ2dpLCBiZWdpdHUgcHVsYSB3aWxheWFoIGJlcm5pbGFpIHJlbmRhaCBkZW5nYW4gd2lsYXlhaCBiZXJuaWxhaSByZW5kYWguDQotICoqQXV0b2tvcmVsYXNpIG5lZ2F0aWY6Kiogd2lsYXlhaCBkZW5nYW4gbmlsYWkgdGluZ2dpIGNlbmRlcnVuZyBiZXJ0ZXRhbmdnYSBkZW5nYW4gd2lsYXlhaCBiZXJuaWxhaSByZW5kYWgsIGRhbiBzZWJhbGlrbnlhLg0KDQpJc3RpbGFoICoqZ2xvYmFsKiogYmVyYXJ0aSBoYXNpbCBhbmFsaXNpcyBtZW5nZ2FtYmFya2FuIHBvbGEgc2VjYXJhIGtlc2VsdXJ1aGFuLCBiZWx1bSBtZW51bmp1a2thbiB3aWxheWFoIG1hbmEgeWFuZyBtZW1iZW50dWsgcG9sYSB0ZXJzZWJ1dC4gVW50dWsgbWVuaWxhaSBhcGFrYWggcG9sYSB5YW5nIHRlcmxpaGF0IGRpZHVrdW5nIHNlY2FyYSBzdGF0aXN0aWssIGtpdGEgbWVuZ2d1bmFrYW4gdWppIGF1dG9rb3JlbGFzaSBzcGFzaWFsLg0KDQpCZWJlcmFwYSBtZXRvZGUgeWFuZyBkYXBhdCBkaWd1bmFrYW4gYWRhbGFoICoqSm9pbiBDb3VudCwgTW9yYW7igJlzIEksIEdlYXJ54oCZcyBDLCBkYW4gR2V0aXPigJNPcmQgRyoqLiBQZW1pbGloYW4gbWV0b2RlIGRpc2VzdWFpa2FuIGRlbmdhbiBqZW5pcyBkYXRhIGRhbiBwZXJ0YW55YWFuIGFuYWxpc2lzLCBzZXBlcnRpIGRpcmFuZ2t1bSBkYWxhbSB0YWJlbCBiZXJpa3V0Lg0KDQpHbG9iYWwgYmVyYXJ0aSBraXRhIG1lcmFuZ2t1bSBzZWx1cnVoIHdpbGF5YWggbWVuamFkaSBzZWJ1YWggc3RhdGlzdGlrLiBCZXJpa3V0IHBlcnRhbnlhYW4geWFuZyBtZW1iZWRha2FuIG1ldG9kZW55YS4NCg0KfCBNZXRvZGUgfCBKZW5pcyBuaWxhaSB8IFBlcnRhbnlhYW4gdXRhbWEgfCBCYWdpYW4gb3V0cHV0IHlhbmcgZGliYWNhIHwNCnw6LS18Oi0tfDotLXw6LS18DQp8IEpvaW4gQ291bnQgfCBLYXRlZ29yaSB8IEFwYWthaCBrYXRlZ29yaSBzYW1hIHNlcmluZyBiZXJ0ZXRhbmdnYT8gfCBKdW1sYWggcGFzYW5nYW4gZGFuIHAtdmFsdWUgfA0KfCBNb3JhbidzIEkgfCBOdW1lcmlrIHwgQXBha2FoIG5pbGFpIHNlcnVwYSBtZW5nZWxvbXBvaz8gfCBJLCBuaWxhaSBoYXJhcGFuLCBwLXZhbHVlIHwNCnwgR2VhcnkncyBDIHwgTnVtZXJpayB8IEFwYWthaCBzZWxpc2loIG5pbGFpIHRldGFuZ2dhIGtlY2lsPyB8IEMsIHAtdmFsdWUgfA0KfCBHZXRpc+KAk09yZCBHIHwgTnVtZXJpayBub25uZWdhdGlmIHwgQXBha2FoIG5pbGFpIHRpbmdnaS9yZW5kYWggbWVuZ2Vsb21wb2s/IHwgRyByZWxhdGlmIG5pbGFpIGhhcmFwYW4sIFosIHAtdmFsdWUgfA0KDQojIyBBLiBKb2luIENvdW50OiBtdWxhaSBkYXJpIGthdGVnb3JpDQoNCioqSm9pbiBDb3VudCoqIGRpZ3VuYWthbiB1bnR1ayBtZW5nZXRhaHVpIGFwYWthaCB3aWxheWFoIGRlbmdhbiBrYXRlZ29yaSB5YW5nIHNhbWEgY2VuZGVydW5nIGJlcnRldGFuZ2dhLiBQYWRhIGNvbnRvaCBpbmksIG5pbGFpIGBDUklNRWAgZGliYWdpIG1lbmphZGkgZHVhIGthdGVnb3JpOiAqKlRpbmdnaSoqIGppa2EgbmlsYWlueWEgbWVsZWJpaGkgbWVkaWFuIGRhbiAqKlJlbmRhaCoqIGppa2EgbmlsYWlueWEga3VyYW5nIGRhcmkgYXRhdSBzYW1hIGRlbmdhbiBtZWRpYW4uDQoNClNlbGFuanV0bnlhLCBraXRhIG1lbmdoaXR1bmcgcGFzYW5nYW4gd2lsYXlhaCBiZXJ0ZXRhbmdnYSB5YW5nIHNhbWEtc2FtYSBiZXJrYXRlZ29yaSBUaW5nZ2kgYXRhdSBzYW1hLXNhbWEgYmVya2F0ZWdvcmkgUmVuZGFoLiBKdW1sYWggcGFzYW5nYW4gdGVyc2VidXQgZGliYW5kaW5na2FuIGRlbmdhbiBqdW1sYWggeWFuZyBkaWhhcmFwa2FuIGppa2Ega2F0ZWdvcmkgdGVyc2ViYXIgc2VjYXJhIGFjYWsuDQoNCkhpcG90ZXNpcyB5YW5nIGRpZ3VuYWthbiB1bnR1ayBzZXRpYXAga2F0ZWdvcmkgYWRhbGFoOg0KDQotICoqSOKCgDoqKiBrYXRlZ29yaSB0ZXJzZWJhciBzZWNhcmEgYWNhaywgZGVuZ2FuIGp1bWxhaCB3aWxheWFoIHBhZGEgc2V0aWFwIGthdGVnb3JpIHRldGFwLg0KLSAqKkjigoE6KiogcGFzYW5nYW4gd2lsYXlhaCBkZW5nYW4ga2F0ZWdvcmkgeWFuZyBzYW1hIGxlYmloIGJhbnlhayBkYXJpcGFkYSB5YW5nIGRpaGFyYXBrYW4gamlrYSB0ZXJzZWJhciBzZWNhcmEgYWNhay4NCg0KQXJndW1lbiBgYWx0ZXJuYXRpdmUgPSAiZ3JlYXRlciJgIGRpZ3VuYWthbiBrYXJlbmEga2l0YSBpbmdpbiBtZW5ndWppIGFwYWthaCBqdW1sYWggcGFzYW5nYW4gdGVyc2VidXQgbGViaWggYmFueWFrIGRhcmkgaGFyYXBhbi4NCg0KYGBge3Igam9pbi1jb3VudH0NCmthdGVnb3JpIDwtIGZhY3RvcigNCiAgaWZlbHNlKHggPiBtZWRpYW4oeCksICJUaW5nZ2kiLCAiUmVuZGFoIiksDQogIGxldmVscyA9IGMoIlJlbmRhaCIsICJUaW5nZ2kiKQ0KKQ0KdGFibGUoa2F0ZWdvcmkpDQpqYyA8LSBqb2luY291bnQudGVzdChrYXRlZ29yaSwgbHdfQiwgYWx0ZXJuYXRpdmUgPSAiZ3JlYXRlciIsIHNhbXBsaW5nID0gIm5vbmZyZWUiKQ0KamMNCg0KcmluZ2thc19qYyA8LSBkYXRhLmZyYW1lKA0KICBrYXRlZ29yaSA9IGxldmVscyhrYXRlZ29yaSksDQogIHBhc2FuZ2FuX3RlcmFtYXRpID0gdmFwcGx5KGpjLCBmdW5jdGlvbihhKSB1bm5hbWUoYSRlc3RpbWF0ZVsxXSksIG51bWVyaWMoMSkpLA0KICBoYXJhcGFuX0gwID0gdmFwcGx5KGpjLCBmdW5jdGlvbihhKSB1bm5hbWUoYSRlc3RpbWF0ZVsyXSksIG51bWVyaWMoMSkpLA0KICBwX3ZhbHVlID0gdmFwcGx5KGpjLCBmdW5jdGlvbihhKSBhJHAudmFsdWUsIG51bWVyaWMoMSkpDQopDQprbml0cjo6a2FibGUocmluZ2thc19qYywgZGlnaXRzID0gNCwgcm93Lm5hbWVzID0gRkFMU0UpDQpgYGANCg0KSGFzaWwgcGVtYmFnaWFuIGJlcmRhc2Fya2FuIG1lZGlhbiBtZW5naGFzaWxrYW4gKioyNSB3aWxheWFoIGJlcmthdGVnb3JpIFJlbmRhaCoqIGRhbiAqKjI0IHdpbGF5YWggYmVya2F0ZWdvcmkgVGluZ2dpKiouIFBhZGEgdGFyYWYgc2lnbmlmaWthbnNpIDUlLCBoYXNpbCBKb2luIENvdW50IG1lbnVuanVra2FuOg0KDQotICoqS2F0ZWdvcmkgVGluZ2dpOioqIHRlcmRhcGF0ICoqNTQgcGFzYW5nYW4gd2lsYXlhaCBiZXJ0ZXRhbmdnYSoqLCBsZWJpaCBiYW55YWsgZGFyaXBhZGEgaGFyYXBhbiBzZWtpdGFyICoqMjcsNjk0IHBhc2FuZ2FuKiouIE5pbGFpIHAgc2ViZXNhciAqKjMsNTcgw5cgMTDigbvCueKBsCoqLCBsZWJpaCBrZWNpbCBkYXJpIDAsMDUsIHNlaGluZ2dhIEjigoAgZGl0b2xhay4gQXJ0aW55YSwgd2lsYXlhaCBkZW5nYW4ga3JpbWluYWxpdGFzIHRpbmdnaSBjZW5kZXJ1bmcgbWVuZ2Vsb21wb2suDQotICoqS2F0ZWdvcmkgUmVuZGFoOioqIHRlcmRhcGF0ICoqMzUgcGFzYW5nYW4gd2lsYXlhaCBiZXJ0ZXRhbmdnYSoqLCBkaWJhbmRpbmdrYW4gaGFyYXBhbiBzZWtpdGFyICoqMzAsMTAyIHBhc2FuZ2FuKiouIE5pbGFpIHAgc2ViZXNhciAqKjAsMTMyMSoqLCBsZWJpaCBiZXNhciBkYXJpIDAsMDUsIHNlaGluZ2dhIEjigoAgYmVsdW0gZGFwYXQgZGl0b2xhay4gQnVrdGkgcGVuZ2Vsb21wb2thbiB3aWxheWFoIGRlbmdhbiBrcmltaW5hbGl0YXMgcmVuZGFoIGJlbHVtIGN1a3VwLg0KDQpBbmdrYSAqKjAsMDAwMCoqIHBhZGEgdGFiZWwgbWVydXBha2FuIGhhc2lsIHBlbWJ1bGF0YW4gcC12YWx1ZSB5YW5nIHNhbmdhdCBrZWNpbCwgYnVrYW4gYmVyYXJ0aSBwLXZhbHVlIHRlcGF0IG5vbC4gS2F0ZWdvcmkgVGluZ2dpIGRhbiBSZW5kYWggcGFkYSBhbmFsaXNpcyBpbmkgYmVyc2lmYXQgcmVsYXRpZiB0ZXJoYWRhcCBtZWRpYW4gZGF0YS4NCg0KIyMgQi4gTW9yYW4ncyBJOiBhcGFrYWggbmlsYWkgc2VydXBhIG1lbmdlbG9tcG9rPw0KDQoqKk1vcmFu4oCZcyBJKiogZGlndW5ha2FuIHVudHVrIG1lbmdldGFodWkgYXBha2FoIHdpbGF5YWggZGVuZ2FuIG5pbGFpIHlhbmcgbWlyaXAgY2VuZGVydW5nIGJlcnRldGFuZ2dhLiBQYWRhIGFuYWxpc2lzIGluaSwga2l0YSBtZW5nZ3VuYWthbiBuaWxhaSBgQ1JJTUVgIGFzbGkgdGFucGEgbWVtYmFnaW55YSBtZW5qYWRpIGthdGVnb3JpLg0KDQpQZXJ0YW55YWFuIHlhbmcgaW5naW4gZGlqYXdhYiBhZGFsYWg6ICoqYXBha2FoIHdpbGF5YWggZGVuZ2FuIGtyaW1pbmFsaXRhcyB0aW5nZ2kgY2VuZGVydW5nIGJlcmRla2F0YW4gZGVuZ2FuIHdpbGF5YWggeWFuZyBqdWdhIG1lbWlsaWtpIGtyaW1pbmFsaXRhcyB0aW5nZ2ksIGJlZ2l0dSBwdWxhIHVudHVrIG5pbGFpIHlhbmcgcmVuZGFoPyoqDQoNCkhpcG90ZXNpcyB5YW5nIGRpZ3VuYWthbiBhZGFsYWg6DQoNCi0gKipI4oKAOioqIG5pbGFpIGBDUklNRWAgdGVyc2ViYXIgc2VjYXJhIGFjYWsgZGkgYW50YXJhIHdpbGF5YWguDQotICoqSOKCgToqKiB0ZXJkYXBhdCBhdXRva29yZWxhc2kgc3Bhc2lhbCBwb3NpdGlmLCB5YWl0dSBuaWxhaSBgQ1JJTUVgIHlhbmcgbWlyaXAgY2VuZGVydW5nIG1lbmdlbG9tcG9rLg0KDQpQZW5ndWppYW4gZGlsYWt1a2FuIG1lbGFsdWkgZHVhIHBlbmRla2F0YW4uIEZ1bmdzaSBgbW9yYW4udGVzdCgpYCBtZW5nZ3VuYWthbiBwZW5kZWthdGFuIGRpc3RyaWJ1c2kgdGVvcmV0aXMsIHNlZGFuZ2thbiBgbW9yYW4ubWMoKWAgbWVtYmFuZGluZ2thbiBoYXNpbCBwZW5nYW1hdGFuIGRlbmdhbiBoYXNpbCBwZW5nYWNha2FuIG5pbGFpIGBDUklNRWAgYW50YXJsb2thc2kuIEFyZ3VtZW4gYGFsdGVybmF0aXZlID0gImdyZWF0ZXIiYCBkaWd1bmFrYW4gdW50dWsgbWVuZ3VqaSBwZW5nZWxvbXBva2FuIG5pbGFpIHlhbmcgc2VydXBhLg0KDQpcWw0KST1cZnJhY3tufXtTXzB9XGZyYWN7XHN1bV9pXHN1bV9qIHdfe2lqfSh4X2ktXGJhcnt4fSkoeF9qLVxiYXJ7eH0pfQ0Ke1xzdW1faSh4X2ktXGJhcnt4fSleMn0sXHFxdWFkIFNfMD1cc3VtX2lcc3VtX2p3X3tpan0uDQpcXQ0KDQoNCmBgYHtyIG1vcmFuLWdsb2JhbH0NCm1vcmFuX2FuYWxpdGlrIDwtIG1vcmFuLnRlc3QoeCwgbHdfVywgYWx0ZXJuYXRpdmUgPSAiZ3JlYXRlciIsIHJhbmRvbWlzYXRpb24gPSBUUlVFKQ0Kc2V0LnNlZWQoMjAyNikNCm1vcmFuX3Blcm0gPC0gbW9yYW4ubWMoeCwgbHdfVywgbnNpbSA9IEIsIGFsdGVybmF0aXZlID0gImdyZWF0ZXIiKQ0KDQptb3Jhbl9hbmFsaXRpaw0KbW9yYW5fcGVybQ0KSV9vYnMgPC0gdW5uYW1lKG1vcmFuX3Blcm0kc3RhdGlzdGljKQ0KRUkgPC0gLTEgLyAobiAtIDEpDQpgYGANCg0KSGFzaWwgYW5hbGlzaXMgbWVudW5qdWtrYW4gKipNb3JhbuKAmXMgSSBzZWJlc2FyIDAsNTAwMioqLCBsZWJpaCB0aW5nZ2kgZGFyaXBhZGEgbmlsYWkgaGFyYXBhbm55YSBqaWthIHBvbGEgYWNhaywgeWFpdHUgKiriiJIwLDAyMDgqKi4gSGFzaWwgaW5pIG1lbnVuanVra2FuIGtlY2VuZGVydW5nYW4gd2lsYXlhaCBkZW5nYW4gYW5na2Ega3JpbWluYWxpdGFzIHlhbmcgbWlyaXAgdW50dWsgYmVydGV0YW5nZ2EuDQoNClAtdmFsdWUgdWppIGFuYWxpdGlrIHNlYmVzYXIgKioxLDEzOSDDlyAxMOKBu+KBuCoqLCBzZWRhbmdrYW4gcC12YWx1ZSBkYXJpICoqOS45OTkgcGVybXV0YXNpKiogc2ViZXNhciAqKjAsMDAwMSoqLiBLZWR1YW55YSBsZWJpaCBrZWNpbCBkYXJpIDAsMDUsIHNlaGluZ2dhICoqSOKCgCBkaXRvbGFrKiouDQoNCkRlbmdhbiBkZW1pa2lhbiwgdGVyZGFwYXQgYnVrdGkgYXV0b2tvcmVsYXNpIHNwYXNpYWwgcG9zaXRpZiBwYWRhIGBDUklNRWA6IHNlY2FyYSBrZXNlbHVydWhhbiwgd2lsYXlhaCBkZW5nYW4ga3JpbWluYWxpdGFzIHRpbmdnaSBjZW5kZXJ1bmcgYmVyZGVrYXRhbiBkZW5nYW4gd2lsYXlhaCBiZXJuaWxhaSB0aW5nZ2ksIGRhbiB3aWxheWFoIGJlcm5pbGFpIHJlbmRhaCBkZW5nYW4gd2lsYXlhaCBiZXJuaWxhaSByZW5kYWguIEhhc2lsIGdsb2JhbCBpbmkgYmVsdW0gbWVudW5qdWtrYW4gbG9rYXNpIGtsYXN0ZXIgdGVydGVudHU7IHVudHVrIG1lbmdldGFodWlueWEsIGRpcGVybHVrYW4gYW5hbGlzaXMgbG9rYWwuDQoNCiMjIyBNZW5nYXBhIG1lbWFrYWkgcGVybXV0YXNpPw0KDQoqKlVqaSBwZXJtdXRhc2kqKiBtZW1iYW50dSBtZW5pbGFpIGFwYWthaCBwZW5nZWxvbXBva2FuIHlhbmcgZGl0ZW11a2FuIGRhcGF0IGRpamVsYXNrYW4gb2xlaCBwZW5lbXBhdGFuIG5pbGFpIHNlY2FyYSBhY2FrLiBDYXJhbnlhLCBuaWxhaSBgQ1JJTUVgIGRpcGluZGFoa2FuIHNlY2FyYSBhY2FrIGFudGFyd2lsYXlhaCwga2VtdWRpYW4gTW9yYW7igJlzIEkgZGloaXR1bmcga2VtYmFsaS4gTmlsYWkgZGF0YW55YSB0ZXRhcCBzYW1hLCBzZWRhbmdrYW4gbGV0YWtueWEgYmVydWJhaDsgaHVidW5nYW4ga2V0ZXRhbmdnYWFuIGp1Z2EgdGV0YXAgZGlwZXJ0YWhhbmthbi4NCg0KUHJvc2VzIGluaSBkaXVsYW5nIHNlYmFueWFrICoqOS45OTkga2FsaSoqLiBIYXNpbG55YSBkaWd1bmFrYW4gc2ViYWdhaSBwZW1iYW5kaW5nIHVudHVrIG1lbmdldGFodWkgYXBha2FoIE1vcmFu4oCZcyBJIGRhcmkgZGF0YSBhc2xpIGphdWggbGViaWggdGluZ2dpIGRhcmlwYWRhIGhhc2lsIHBlbmdhY2FrYW4uDQoNCmBgYHtyIGhpc3RvZ3JhbS1tb3JhbiwgZmlnLmhlaWdodD00LjgsIGZpZy5jYXA9IkdhcmlzIG1lcmFoIGFkYWxhaCBNb3JhbiB0ZXJhbWF0aTsgaGlzdG9ncmFtIGFkYWxhaCBoYXNpbCBwZW5nYWNha2FuIG5pbGFpIENSSU1FLiJ9DQpzaW1fSSA8LSBtb3Jhbl9wZXJtJHJlc1tzZXFfbGVuKEIpXQ0KaGlzdChzaW1fSSwgYnJlYWtzID0gMzAsIGNvbCA9ICIjYWNkNGRjIiwgYm9yZGVyID0gIndoaXRlIiwNCiAgICAgbWFpbiA9ICJBcGFrYWggcG9sYSB0ZXJhbWF0aSBsYXppbSBwYWRhIHBldGEgYWNhaz8iLA0KICAgICB4bGFiID0gIk1vcmFuJ3MgSSBkYXJpIHBlcm11dGFzaSIsDQogICAgIHhsaW0gPSByYW5nZShjKHNpbV9JLCBJX29icykpKQ0KYWJsaW5lKHYgPSBJX29icywgY29sID0gIiNiODMyNDgiLCBsd2QgPSAzKQ0KbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IHBhc3RlKCJJIHRlcmFtYXRpID0iLCBmbXQoSV9vYnMpKSwNCiAgICAgICBjb2wgPSAiI2I4MzI0OCIsIGx3ZCA9IDMsIGJ0eSA9ICJuIikNCmBgYA0KDQpIaXN0b2dyYW0gbWVudW5qdWtrYW4gc2ViYXJhbiBNb3JhbuKAmXMgSSBkYXJpIGhhc2lsIHBlbmdhY2FrYW4sIHlhbmcgc2ViYWdpYW4gYmVzYXIgYmVyYWRhIGRpIHNla2l0YXIgbm9sLiBHYXJpcyBtZXJhaCBtZW51bmp1a2thbiBNb3JhbuKAmXMgSSBkYXRhIGFzbGksIHlhaXR1IHNla2l0YXIgKiowLDUwMCoqLCB5YW5nIGJlcmFkYSBqYXVoIGRpIHNlYmVsYWgga2FuYW4gc2ViYXJhbiB0ZXJzZWJ1dC4NCg0KQXJ0aW55YSwgcGVuZ2Vsb21wb2thbiBwYWRhIGRhdGEgYXNsaSBqYXVoIGxlYmloIGt1YXQgZGFyaXBhZGEgeWFuZyBkaWhhc2lsa2FuIG9sZWggcGVuZ2FjYWthbi4gSGFzaWwgaW5pIHNlamFsYW4gZGVuZ2FuICoqcC12YWx1ZSAwLDAwMDEqKiwgc2VoaW5nZ2EgcGFkYSB0YXJhZiBzaWduaWZpa2Fuc2kgNSUgdGVyZGFwYXQgYnVrdGkgYmFod2Egd2lsYXlhaCBkZW5nYW4gbmlsYWkgYENSSU1FYCB5YW5nIG1pcmlwIGNlbmRlcnVuZyBtZW5nZWxvbXBvay4NCg0KIyMgQy4gR2VhcnkncyBDOiBsaWhhdCBwZXJiZWRhYW4gYW50YXJ0ZXRhbmdnYQ0KDQoqKkdlYXJ54oCZcyBDKiogZGlndW5ha2FuIHVudHVrIG1lbGloYXQga2VtaXJpcGFuIG5pbGFpIGFudGFyd2lsYXlhaCB5YW5nIGJlcnRldGFuZ2dhIGJlcmRhc2Fya2FuIHNlbGlzaWggbmlsYWlueWEuIEppa2EgYW5na2Ega3JpbWluYWxpdGFzIHN1YXR1IHdpbGF5YWggZGFuIHRldGFuZ2dhbnlhIGhhbXBpciBzYW1hLCBzZWxpc2lobnlhIGtlY2lsIGRhbiBuaWxhaSBHZWFyeeKAmXMgQyBjZW5kZXJ1bmcgcmVuZGFoLg0KDQpOaWxhaSBDIGRpYmFjYSBkZW5nYW4gYWN1YW4gYmVyaWt1dDoNCg0KLSAqKkMgPCAxOioqIHdpbGF5YWggeWFuZyBiZXJ0ZXRhbmdnYSBjZW5kZXJ1bmcgbWVtaWxpa2kgbmlsYWkgc2VydXBhLg0KLSAqKkMgPiAxOioqIHdpbGF5YWggeWFuZyBiZXJ0ZXRhbmdnYSBjZW5kZXJ1bmcgbWVtaWxpa2kgbmlsYWkgYmVyYmVkYS4NCi0gKipDIG1lbmRla2F0aSAxOioqIG1lbmRla2F0aSBuaWxhaSB5YW5nIGRpaGFyYXBrYW4gcGFkYSBwb2xhIGFjYWsuDQoNClBhZGEgY29udG9oIGluaSwgKipI4oKAKiogbWVueWF0YWthbiBuaWxhaSBgQ1JJTUVgIHRlcnNlYmFyIHNlY2FyYSBhY2FrLCBzZWRhbmdrYW4gKipI4oKBKiogbWVueWF0YWthbiB3aWxheWFoIGRlbmdhbiBuaWxhaSBzZXJ1cGEgY2VuZGVydW5nIG1lbmdlbG9tcG9rLiBQLXZhbHVlIGRpZ3VuYWthbiB1bnR1ayBtZW5pbGFpIGFwYWthaCBidWt0aSBwZW5nZWxvbXBva2FuIHRlcnNlYnV0IGN1a3VwIGt1YXQuDQoNCmBgYHtyIGdlYXJ5LWdsb2JhbH0NCmdlYXJ5X2hhc2lsIDwtIGdlYXJ5LnRlc3QoeCwgbHdfVywgYWx0ZXJuYXRpdmUgPSAiZ3JlYXRlciIsIHJhbmRvbWlzYXRpb24gPSBUUlVFKQ0KZ2VhcnlfaGFzaWwNCkNfb2JzIDwtIHVubmFtZShnZWFyeV9oYXNpbCRlc3RpbWF0ZVsxXSkNCmBgYA0KDQpIYXNpbCBhbmFsaXNpcyBtZW51bmp1a2thbiAqKkdlYXJ54oCZcyBDIHNlYmVzYXIgMCw1NDEqKiwgbGViaWgga2VjaWwgZGFyaSBuaWxhaSBoYXJhcGFubnlhLCB5YWl0dSAxLiBBcnRpbnlhLCBhbmdrYSBrcmltaW5hbGl0YXMgYW50YXJ3aWxheWFoIHlhbmcgYmVydGV0YW5nZ2EgY2VuZGVydW5nIHNlcnVwYS4NCg0KUC12YWx1ZSBzZWJlc2FyICoqMSwwNTMgw5cgMTDigbvigbYqKiwgbGViaWgga2VjaWwgZGFyaSAwLDA1LCBzZWhpbmdnYSAqKkjigoAgZGl0b2xhayoqLiBEZW5nYW4gZGVtaWtpYW4sIHRlcmRhcGF0IGJ1a3RpIGF1dG9rb3JlbGFzaSBzcGFzaWFsIHBvc2l0aWYgcGFkYSBgQ1JJTUVgLiBLZXNpbXB1bGFuIGluaSBzZWphbGFuIGRlbmdhbiBoYXNpbCBNb3JhbuKAmXMgSSBzZWJlbHVtbnlhLCB5YWl0dSBuaWxhaSBrcmltaW5hbGl0YXMgeWFuZyBzZXJ1cGEgY2VuZGVydW5nIG1lbmdlbG9tcG9rLg0KDQpQYWRhIGZ1bmdzaSBgZ2VhcnkudGVzdCgpYCwgYXJndW1lbiBgYWx0ZXJuYXRpdmUgPSAiZ3JlYXRlciJgIGRpZ3VuYWthbiB1bnR1ayBtZW5ndWppIGF1dG9rb3JlbGFzaSBwb3NpdGlmLCB5YW5nIGRpdHVuanVra2FuIG9sZWggKipDIGxlYmloIGtlY2lsIGRhcmkgMSoqLiBKYWRpLCBhcmd1bWVuIHRlcnNlYnV0IHRpZGFrIGJlcmFydGkgbWVuZ3VqaSBhcGFrYWggQyBsZWJpaCBiZXNhciBkYXJpIDEuDQoNCiMjIEQuIEdldGlz4oCTT3JkIEcgZ2xvYmFsOiBrb25zZW50cmFzaSBuaWxhaSB0aW5nZ2kNCg0KKipHZXRpc+KAk09yZCBHIGdsb2JhbCoqIGRpZ3VuYWthbiB1bnR1ayBtZW5pbGFpIHBlbmdlbG9tcG9rYW4gbmlsYWkgdGluZ2dpIGF0YXUgcmVuZGFoIHNlY2FyYSBrZXNlbHVydWhhbi4gUGFkYSBjb250b2ggaW5pLCBraXRhIGluZ2luIG1lbmdldGFodWkgYXBha2FoICoqd2lsYXlhaCBkZW5nYW4gYW5na2Ega3JpbWluYWxpdGFzIHRpbmdnaSBjZW5kZXJ1bmcgc2FsaW5nIGJlcmRla2F0YW4qKi4NCg0KQW5hbGlzaXMgbWVuZ2d1bmFrYW4gbmlsYWkgYENSSU1FYCBhc2xpIGRhbiBib2JvdCBiaW5lciwgZGVuZ2FuIGhpcG90ZXNpczoNCg0KLSAqKkjigoA6KiogbmlsYWkgYENSSU1FYCB0ZXJzZWJhciBzZWNhcmEgYWNhayBhbnRhcndpbGF5YWguDQotICoqSOKCgToqKiBuaWxhaSBgQ1JJTUVgIHlhbmcgdGluZ2dpIG1lbmdlbG9tcG9rIGxlYmloIGt1YXQgZGFyaXBhZGEgeWFuZyBkaWhhcmFwa2FuIHBhZGEgcG9sYSBhY2FrLg0KDQpBcmd1bWVuIGBhbHRlcm5hdGl2ZSA9ICJncmVhdGVyImAgZGlndW5ha2FuIGthcmVuYSBwZW5ndWppYW4gZGlmb2t1c2thbiBwYWRhIHBlbmdlbG9tcG9rYW4gbmlsYWkgdGluZ2dpLg0KDQpgYGB7ciBnZXRpcy1nbG9iYWx9DQpzdG9waWZub3QoYWxsKHggPj0gMCkpDQpHX2dsb2JhbCA8LSBnbG9iYWxHLnRlc3QoeCwgbHdfQiwgYWx0ZXJuYXRpdmUgPSAiZ3JlYXRlciIpDQpHX2dsb2JhbA0KYGBgDQoNCkhhc2lsIGFuYWxpc2lzIG1lbnVuanVra2FuICoqRyBzZWJlc2FyIDAsMTI3OCoqLCBsZWJpaCBiZXNhciBkYXJpcGFkYSBuaWxhaSBoYXJhcGFubnlhIHBhZGEgcG9sYSBhY2FrLCB5YWl0dSAqKjAsMTAwMyoqLiBOaWxhaSAqKlogc2ViZXNhciA0LDYzOCoqIG1lbnVuanVra2FuIGJhaHdhIEcgdGVyYW1hdGkgYmVyYWRhIGRpIGF0YXMgbmlsYWkgaGFyYXBhbiB0ZXJzZWJ1dC4NCg0KUC12YWx1ZSBzZWJlc2FyICoqMSw3NTggw5cgMTDigbvigbYqKiwgbGViaWgga2VjaWwgZGFyaSAwLDA1LCBzZWhpbmdnYSAqKkjigoAgZGl0b2xhayoqLiBEZW5nYW4gZGVtaWtpYW4sIHRlcmRhcGF0IGJ1a3RpIGJhaHdhIHdpbGF5YWggZGVuZ2FuIGFuZ2thIGtyaW1pbmFsaXRhcyB0aW5nZ2kgY2VuZGVydW5nIHNhbGluZyBiZXJkZWthdGFuIGF0YXUgbWVuZ2Vsb21wb2suDQoNCkhhc2lsIGluaSBtZW5nZ2FtYmFya2FuIHBvbGEgc2VjYXJhIGtlc2VsdXJ1aGFuLiBVbnR1ayBtZW5nZXRhaHVpIHdpbGF5YWggbWFuYSB5YW5nIG1lbWJlbnR1ayBwZW5nZWxvbXBva2FuIHRlcnNlYnV0LCBhbmFsaXNpcyBwZXJsdSBkaWxhbmp1dGthbiBkZW5nYW4gc3RhdGlzdGlrIGxva2FsLg0KDQojIEF1dG9rb3JlbGFzaSBzcGFzaWFsIGxva2FsOiBkaSBtYW5hIHBvbGFueWE/DQoNCiMjIExvY2FsIE1vcmFuJ3MgSSBkYW4gZW1wYXQga3VhZHJhbg0KDQpBbmFsaXNpcyBnbG9iYWwgbWVudW5qdWtrYW4gYWRhbnlhIHBlbmdlbG9tcG9rYW4ga3JpbWluYWxpdGFzIHNlY2FyYSBrZXNlbHVydWhhbi4gU2VsYW5qdXRueWEsICoqTG9jYWwgTW9yYW7igJlzIEkqKiBkaWd1bmFrYW4gdW50dWsgbWVuaWxhaSBwb2xhIHBhZGEgc2V0aWFwIHdpbGF5YWggZGVuZ2FuIG1lbWJhbmRpbmdrYW4gYW5na2Ega3JpbWluYWxpdGFzIHdpbGF5YWggdGVyc2VidXQgZGFuIHRldGFuZ2dhbnlhLg0KDQpTZWJhZ2FpIGxhbmdrYWggYXdhbCwgbmlsYWkgYENSSU1FYCBkaXViYWggbWVuamFkaSAqKnNrb3IgYmFrdSAoeikqKi4gTmlsYWkgeiBwb3NpdGlmIGJlcmFydGkgYW5na2Ega3JpbWluYWxpdGFzIGJlcmFkYSBkaSBhdGFzIHJhdGEtcmF0YSBzZWx1cnVoIHdpbGF5YWgsIHNlZGFuZ2thbiBuaWxhaSB6IG5lZ2F0aWYgYmVyYXJ0aSBiZXJhZGEgZGkgYmF3YWggcmF0YS1yYXRhLiBLZW11ZGlhbiwga2l0YSBtZW5naGl0dW5nIHJhdGEtcmF0YSBza29yIGJha3UgdGV0YW5nZ2FueWEgKCpzcGF0aWFsIGxhZyopLg0KDQpCZXJkYXNhcmthbiBrZWR1YSBuaWxhaSB0ZXJzZWJ1dCwgc2V0aWFwIHdpbGF5YWggZGlrZWxvbXBva2thbiBrZSBkYWxhbSBlbXBhdCBrdWFkcmFuOiAqKkhpZ2jigJNIaWdoIChISCksIExvd+KAk0xvdyAoTEwpLCBIaWdo4oCTTG93IChITCksIGRhbiBMb3figJNIaWdoIChMSCkqKi4gUGVuZ2Vsb21wb2thbiBpbmkgbWVtYmFudHUgbWVuZ2VuYWxpIHBvbGEgYXdhbCBzZWJlbHVtIGRpbGFrdWthbiB1amkgc2lnbmlmaWthbnNpLg0KDQpgYGB7ciBza29yLWRhbi1rdWFkcmFufQ0KenggPC0gYXMubnVtZXJpYyhzY2FsZSh4KSkNCnp5IDwtIGFzLm51bWVyaWMoc2NhbGUoeSkpDQp3enggPC0gbGFnLmxpc3R3KGx3X1csIHp4KQ0Kd3p5IDwtIGxhZy5saXN0dyhsd19XLCB6eSkNCg0KIyBGdW5nc2kgYnVhdGFuIG1vZHVsOyBkaXBha2FpIGtlbWJhbGkgdW50dWsga2FzdXMgYml2YXJpYXQuDQprdWFkcmFuIDwtIGZ1bmN0aW9uKG5pbGFpX2xva2FzaSwgbmlsYWlfdGV0YW5nZ2EpIHsNCiAgaWZlbHNlKG5pbGFpX2xva2FzaSA9PSAwIHwgbmlsYWlfdGV0YW5nZ2EgPT0gMCwgIlBhZGEgYmF0YXMiLA0KICAgIGlmZWxzZShuaWxhaV9sb2thc2kgPiAwICYgbmlsYWlfdGV0YW5nZ2EgPiAwLCAiSEgiLA0KICAgICAgaWZlbHNlKG5pbGFpX2xva2FzaSA8IDAgJiBuaWxhaV90ZXRhbmdnYSA8IDAsICJMTCIsDQogICAgICAgIGlmZWxzZShuaWxhaV9sb2thc2kgPiAwICYgbmlsYWlfdGV0YW5nZ2EgPCAwLCAiSEwiLCAiTEgiKSkpKQ0KfQ0KcV91bmkgPC0ga3VhZHJhbih6eCwgd3p4KQ0KdGFibGUocV91bmkpDQpgYGANCg0KUGFkYSBncmFmaWssICoqc2V0aWFwIHRpdGlrIG1ld2FraWxpIHNhdHUgd2lsYXlhaCoqLiBTdW1idSBob3Jpem9udGFsIG1lbnVuanVra2FuIHNrb3IgYmFrdSBgQ1JJTUVgIHdpbGF5YWggdGVyc2VidXQsIHNlZGFuZ2thbiBzdW1idSB2ZXJ0aWthbCBtZW51bmp1a2thbiByYXRhLXJhdGEgc2tvciBiYWt1IGBDUklNRWAgdGV0YW5nZ2FueWEuIEdhcmlzIG5vbCBtZW1pc2Foa2FuIG5pbGFpIGRpIGF0YXMgZGFuIGRpIGJhd2FoIHJhdGEtcmF0YS4NCg0KSGFzaWwgcGVtYmFnaWFuIGt1YWRyYW4gbWVudW5qdWtrYW46DQoNCnwgS3VhZHJhbiB8IEp1bWxhaCB3aWxheWFoIHwgSW50ZXJwcmV0YXNpIHwNCnw6LS18LS06fDotLXwNCnwgKipISCoqIHwgMjEgfCBLcmltaW5hbGl0YXMgd2lsYXlhaCB0aW5nZ2kgZGFuIHJhdGEtcmF0YSBrcmltaW5hbGl0YXMgdGV0YW5nZ2FueWEganVnYSB0aW5nZ2kuIHwNCnwgKipMTCoqIHwgMjAgfCBLcmltaW5hbGl0YXMgd2lsYXlhaCByZW5kYWggZGFuIHJhdGEtcmF0YSBrcmltaW5hbGl0YXMgdGV0YW5nZ2FueWEganVnYSByZW5kYWguIHwNCnwgKipITCoqIHwgMyB8IEtyaW1pbmFsaXRhcyB3aWxheWFoIHRpbmdnaSwgdGV0YXBpIHJhdGEtcmF0YSBrcmltaW5hbGl0YXMgdGV0YW5nZ2FueWEgcmVuZGFoLiB8DQp8ICoqTEgqKiB8IDUgfCBLcmltaW5hbGl0YXMgd2lsYXlhaCByZW5kYWgsIHRldGFwaSByYXRhLXJhdGEga3JpbWluYWxpdGFzIHRldGFuZ2dhbnlhIHRpbmdnaS4gfA0KDQpTZWJhZ2lhbiBiZXNhciB3aWxheWFoIGJlcmFkYSBwYWRhIGt1YWRyYW4gKipISCBkYW4gTEwqKiwgc2VoaW5nZ2EgbmlsYWkga3JpbWluYWxpdGFzIHdpbGF5YWggY2VuZGVydW5nIHNlamFsYW4gZGVuZ2FuIG5pbGFpIHRldGFuZ2dhbnlhLiBQb2xhIGluaSBzZXN1YWkgZGVuZ2FuIGdhcmlzIHlhbmcgbWVuYW5qYWsgZGFuIGhhc2lsIE1vcmFu4oCZcyBJIGdsb2JhbCB5YW5nIHBvc2l0aWYuDQoNCk5hbXVuLCBwb3Npc2kgcGFkYSBrdWFkcmFuICoqYmVsdW0gbWVudW5qdWtrYW4gYmFod2EgcG9sYSBzdWF0dSB3aWxheWFoIHNpZ25pZmlrYW4qKi4gVWppIExvY2FsIE1vcmFuIGRpcGVybHVrYW4gdW50dWsgbWVuaWxhaSBhcGFrYWggcG9sYSB0ZXJzZWJ1dCBjdWt1cCBrdWF0IGRpYmFuZGluZ2thbiBkZW5nYW4gaGFzaWwgcGVuZ2FjYWthbi4NCg0KYGBge3Igc2NhdHRlcnBsb3QtdW5pdmFyaWF0LCBmaWcuaGVpZ2h0PTUuM30NCmdncGxvdChkYXRhLmZyYW1lKHp4LCB3engsIGt1YWRyYW4gPSBxX3VuaSksIGFlcyh6eCwgd3p4LCBjb2xvciA9IGt1YWRyYW4pKSArDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGNvbG9yID0gImdyZXk2NSIpICsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgY29sb3IgPSAiZ3JleTY1IikgKw0KICBnZW9tX3BvaW50KHNpemUgPSAyLjUpICsNCiAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSBJX29icywgY29sb3IgPSAiIzE4M2Y1NiIsIGxpbmV3aWR0aCA9IDAuOCkgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYyhISCA9ICIjYjgzMjQ4IiwgTEwgPSAiIzI4NzhhZCIsIEhMID0gIiNlOGEyM2QiLCBMSCA9ICIjNThiNmIxIikpICsNCiAgbGFicyh0aXRsZSA9ICJNb3JhbiBzY2F0dGVycGxvdDogQ1JJTUUgZGVuZ2FuIENSSU1FIHRldGFuZ2dhIiwNCiAgICAgICB4ID0gInogQ1JJTUUgbG9rYXNpIiwgeSA9ICJXeiBDUklNRSB0ZXRhbmdnYSIsIGNvbG9yID0gIkt1YWRyYW4iKQ0KYGBgDQoNCg0KIyMjIEphbGFua2FuIHVqaSBsb2thbA0KDQpTZXRlbGFoIG1lbmdlbmFsaSBrdWFkcmFuIHNldGlhcCB3aWxheWFoLCBraXRhIG1lbGFrdWthbiAqKnVqaSBMb2NhbCBNb3JhbuKAmXMgSSoqIHVudHVrIG1lbmlsYWkgYXBha2FoIHBvbGEgdGVyc2VidXQgc2lnbmlmaWthbiBzZWNhcmEgc3RhdGlzdGlrLg0KDQpQZW5ndWppYW4gZGlsYWt1a2FuIGRlbmdhbiBtZW1wZXJ0YWhhbmthbiBuaWxhaSBgQ1JJTUVgIHdpbGF5YWggeWFuZyBzZWRhbmcgZGlwZXJpa3NhLCBsYWx1IG1lbmdhY2FrIG5pbGFpIGRhcmkgd2lsYXlhaCBsYWluIHVudHVrIG1lbmdpc2kgcG9zaXNpIHRldGFuZ2dhbnlhLiBIYXNpbCBwZW5nYW1hdGFuIGRpYmFuZGluZ2thbiBkZW5nYW4gaGFzaWwgcGVuZ2FjYWthbiB0ZXJzZWJ1dC4gVWppIGR1YSBzaXNpIGRpZ3VuYWthbiBhZ2FyIGRhcGF0IG1lbmRldGVrc2kgcG9sYSBuaWxhaSB5YW5nIHNlcnVwYSBtYXVwdW4gYmVyYmVkYSBkZW5nYW4gdGV0YW5nZ2EuDQoNCkthcmVuYSBwZW5ndWppYW4gZGlsYWt1a2FuIHBhZGEgYmFueWFrIHdpbGF5YWggc2VrYWxpZ3VzLCBwLXZhbHVlIGp1Z2EgZGlzZXN1YWlrYW4gbWVuZ2d1bmFrYW4gbWV0b2RlICoqQmVuamFtaW5p4oCTSG9jaGJlcmcgKEJIKSoqLiBQZW55ZXN1YWlhbiBpbmkgbWVtYmFudHUgbWVuZ3VyYW5naSB0ZW11YW4gc2lnbmlmaWthbiB5YW5nIG11bmN1bCBzZWNhcmEga2ViZXR1bGFuIGFraWJhdCBiYW55YWtueWEgcGVuZ3VqaWFuLg0KDQpgYGB7ciBtb3Jhbi1sb2thbH0NCmxpc2EgPC0gbG9jYWxtb3Jhbl9wZXJtKA0KICB4LCBsd19XLCBuc2ltID0gQiwgYWx0ZXJuYXRpdmUgPSAidHdvLnNpZGVkIiwNCiAgbWx2YXIgPSBGQUxTRSwgaXNlZWQgPSAyMDI2LCBub19yZXBlYXRfaW5fcm93ID0gVFJVRQ0KKQ0KY29sbmFtZXMobGlzYSkNCnBfdW5pIDwtIGxpc2FbLCAiUHIoeiAhPSBFKElpKSkgU2ltIl0NCnBfdW5pX0JIIDwtIHAuYWRqdXN0KHBfdW5pLCBtZXRob2QgPSAiQkgiKQ0Kc3RvcGlmbm90KG1heChhYnMobGlzYVssICJJaSJdIC0genggKiB3engpKSA8IDFlLTgpDQoNCmhhc2lsX3VuaSA8LSBkYXRhLmZyYW1lKA0KICBpZCA9IGNvbCRpZCwgQ1JJTUUgPSB4LCBsYWdfQ1JJTUUgPSBsYWdfeCwNCiAgSWkgPSBsaXNhWywgIklpIl0sIGt1YWRyYW4gPSBxX3VuaSwNCiAgcF9wZXJtdXRhc2kgPSBwX3VuaSwgcF9CSCA9IHBfdW5pX0JIDQopDQprbml0cjo6a2FibGUoaGVhZChoYXNpbF91bmlbb3JkZXIoaGFzaWxfdW5pJHBfcGVybXV0YXNpKSwgXSwgOCksIGRpZ2l0cyA9IDQsDQogICAgICAgICAgICAgY2FwdGlvbiA9ICJEZWxhcGFuIHAtdmFsdWUgbG9rYWwgdGVya2VjaWw7IGluaSBidWthbiBwZXJpbmdrYXQgcmlzaWtvIHdpbGF5YWguIikNCmBgYA0KDQpUYWJlbCBtZW5hbXBpbGthbiBkZWxhcGFuIHdpbGF5YWggZGVuZ2FuIHAtdmFsdWUgcGVybXV0YXNpIHRlcmtlY2lsLiBLb2xvbSBgSWlgIG1lbnVuanVra2FuIG5pbGFpIExvY2FsIE1vcmFuLCBga3VhZHJhbmAgbWVudW5qdWtrYW4gamVuaXMgcG9sYSwgc2VkYW5na2FuIGBwX3Blcm11dGFzaWAgZGFuIGBwX0JIYCBtZW51bmp1a2thbiBwLXZhbHVlIHNlYmVsdW0gZGFuIHNlc3VkYWggcGVueWVzdWFpYW4gQkguDQoNClBhZGEgdGFyYWYgc2lnbmlmaWthbnNpICoqNSUqKiwgbGltYSB3aWxheWFoIGRhbGFtIHRhYmVsIHRldGFwIHNpZ25pZmlrYW4gc2V0ZWxhaCBwZW55ZXN1YWlhbiBCSDoNCg0KLSAqKklEIDI0LCAxNiwgMjksIGRhbiAyNSoqIG1lbWlsaWtpIHBvbGEgKipISCoqLiBBbmdrYSBrcmltaW5hbGl0YXMgd2lsYXlhaCB0ZXJzZWJ1dCBiZXJhZGEgZGkgYXRhcyByYXRhLXJhdGEsIGJlZ2l0dSBwdWxhIHJhdGEtcmF0YSBhbmdrYSBrcmltaW5hbGl0YXMgdGV0YW5nZ2FueWEuDQotICoqSUQgMzIqKiBtZW1pbGlraSBwb2xhICoqTEwqKi4gQW5na2Ega3JpbWluYWxpdGFzIHdpbGF5YWggdGVyc2VidXQgYmVyYWRhIGRpIGJhd2FoIHJhdGEtcmF0YSwgYmVnaXR1IHB1bGEgcmF0YS1yYXRhIGFuZ2thIGtyaW1pbmFsaXRhcyB0ZXRhbmdnYW55YS4NCg0KU2VtZW50YXJhIGl0dSwgKipJRCAyOCwgMzcsIGRhbiAzNioqIHNpZ25pZmlrYW4gYmVyZGFzYXJrYW4gcC12YWx1ZSBhd2FsLCB0ZXRhcGkgdGlkYWsgbGFnaSBzaWduaWZpa2FuIHNldGVsYWggcGVueWVzdWFpYW4gQkgga2FyZW5hIGBwX0JIID4gMCwwNWAuIEFydGlueWEsIGJ1a3RpIHBvbGEgbG9rYWwgcGFkYSBrZXRpZ2Egd2lsYXlhaCB0ZXJzZWJ1dCBiZWx1bSBjdWt1cCBzZXRlbGFoIG1lbXBlcmhpdHVuZ2thbiBiYW55YWtueWEgcGVuZ3VqaWFuLg0KDQojIyMgQmFueWFrIHVqaSBtZW1lcmx1a2FuIHBlcmhhdGlhbg0KDQpVamkgTG9jYWwgTW9yYW4gZGlsYWt1a2FuIHBhZGEgNDkgd2lsYXlhaC4gS2V0aWthIGJhbnlhayBwZW5ndWppYW4gZGlsYWt1a2FuIHNla2FsaWd1cywgc2ViYWdpYW4gaGFzaWwgZGFwYXQgdGVybGloYXQgc2lnbmlmaWthbiBoYW55YSBrYXJlbmEga2ViZXR1bGFuLiBPbGVoIGthcmVuYSBpdHUsIHAtdmFsdWUgZGlzZXN1YWlrYW4gbWVuZ2d1bmFrYW4gbWV0b2RlICoqQmVuamFtaW5p4oCTSG9jaGJlcmcgKEJIKSoqIHVudHVrIG1lbWJhbnR1IG1lbmdlbmRhbGlrYW4gdGVtdWFuIHRlcnNlYnV0Lg0KDQpLaXRhIGtlbXVkaWFuIG1lbWJhbmRpbmdrYW4gZHVhIHBldGE6IHBldGEgYmVyZGFzYXJrYW4gKipwLXZhbHVlIGF3YWwqKiBkYW4gcGV0YSBiZXJkYXNhcmthbiAqKnAtdmFsdWUgc2V0ZWxhaCBwZW55ZXN1YWlhbiBCSCoqLiBXaWxheWFoIGRpYmVyaSB3YXJuYSBzZXN1YWkga3VhZHJhbm55YSBqaWthIHAtdmFsdWUgeWFuZyBkaWd1bmFrYW4gbGViaWgga2VjaWwgZGFyaSAwLDA1LiBXaWxheWFoIGxhaW5ueWEgZGl0YW1waWxrYW4gZGVuZ2FuIHdhcm5hIGFidS1hYnUuIGtvbnRyb2wgeWFuZyBsZWJpaCBrb25zZXJ2YXRpZiB0ZXJoYWRhcCBrZXRlcmdhbnR1bmdhbiB1bXVtLg0KDQpgYGB7ciBmdW5nc2ktcGV0YS1sb2thbH0NCndhcm5hX3BvbGEgPC0gYygNCiAgSEggPSAiI2I4MzI0OCIsIExMID0gIiMyODc4YWQiLCBITCA9ICIjZThhMjNkIiwgTEggPSAiIzU4YjZiMSIsDQogICJCZWx1bSBzaWduaWZpa2FuIiA9ICIjZTFlNmU5IiwgIlBhZGEgYmF0YXMiID0gIiNhZGI4YmYiDQopDQpsYWJlbF9zaWduaWZpa2FuIDwtIGZ1bmN0aW9uKHEsIHApIHsNCiAgZmFjdG9yKGlmZWxzZShwIDwgYWxwaGEsIHEsICJCZWx1bSBzaWduaWZpa2FuIiksIGxldmVscyA9IG5hbWVzKHdhcm5hX3BvbGEpKQ0KfQ0KcGV0YV9wb2xhIDwtIGZ1bmN0aW9uKHEsIHAsIGp1ZHVsLCBzdWJqdWR1bCkgew0KICB0bXAgPC0gY29sDQogIHRtcCRwb2xhIDwtIGxhYmVsX3NpZ25pZmlrYW4ocSwgcCkNCiAgZ2dwbG90KHRtcCkgKw0KICAgIGdlb21fc2YoYWVzKGZpbGwgPSBwb2xhKSwgY29sb3IgPSAid2hpdGUiLCBsaW5ld2lkdGggPSAwLjMpICsNCiAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSB3YXJuYV9wb2xhLCBkcm9wID0gRkFMU0UsIG5hbWUgPSAiUG9sYSIpICsNCiAgICBsYWJzKHRpdGxlID0ganVkdWwsIHN1YnRpdGxlID0gc3VianVkdWwpICsNCiAgICBjb29yZF9zZihkYXR1bSA9IE5BKSArDQogIHRoZW1lX3ZvaWQoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLCBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCkpDQp9DQoNCnBldGFfcG9sYShxX3VuaSwgcF91bmksICJMb2NhbCBNb3JhbjogQ1JJTUUiLCAiRWtzcGxvcmFzaSB8IHAgcGVybXV0YXNpIG1lbnRhaCIpDQpwZXRhX3BvbGEocV91bmksIHBfdW5pX0JILCAiTG9jYWwgTW9yYW46IENSSU1FIiwgIlBlbWJhbmRpbmcgfCBwIGRpc2VzdWFpa2FuIEJIIikNCmBgYA0KDQpQYWRhIHBldGEgcGVydGFtYSwgdGVyZGFwYXQgKioxNSB3aWxheWFoIGRlbmdhbiBwb2xhIGxva2FsIHlhbmcgc2lnbmlmaWthbioqIGJlcmRhc2Fya2FuIHAtdmFsdWUgYXdhbC4gUG9sYSAqKkhIKiogYmVyd2FybmEgbWVyYWggdGVydXRhbWEgdGVybGloYXQgZGkgYmFnaWFuIHRlbmdhaCwgc2VkYW5na2FuIHBvbGEgKipMTCoqIGJlcndhcm5hIGJpcnUgdGVybGloYXQgcGFkYSBiZWJlcmFwYSB3aWxheWFoIGRpIGJhZ2lhbiB0ZXBpLg0KDQpTZXRlbGFoIHBlbnllc3VhaWFuIEJILCB0ZXJkYXBhdCAqKjUgd2lsYXlhaCB5YW5nIHRldGFwIHNpZ25pZmlrYW4qKiwgeWFpdHUgKio0IHdpbGF5YWggYmVycG9sYSBISCoqIGRhbiAqKjEgd2lsYXlhaCBiZXJwb2xhIExMKiouIEFydGlueWEsIGJ1a3RpIHBlbmdlbG9tcG9rYW4gcGFkYSBrZWxpbWEgd2lsYXlhaCB0ZXJzZWJ1dCB0ZXRhcCBjdWt1cCBrdWF0IHNldGVsYWggbWVtcGVyaGl0dW5na2FuIGJhbnlha255YSBwZW5ndWppYW4uDQoNCldpbGF5YWggeWFuZyBiZXJ1YmFoIG1lbmphZGkgYWJ1LWFidSB0aWRhayBiZXJhcnRpIGtlaGlsYW5nYW4gcG9sYSBhdGF1IG1lbmdhbGFtaSBwZXJ1YmFoYW4ga3JpbWluYWxpdGFzLiBZYW5nIGJlcnViYWggYWRhbGFoIGtlcHV0dXNhbiBzdGF0aXN0aWtueWE6IGJ1a3RpIHlhbmcgdGVyc2VkaWEgYmVsdW0gY3VrdXAgdW50dWsgbWVueWF0YWthbiBwb2xhIGxva2FsbnlhIHNpZ25pZmlrYW4gc2V0ZWxhaCBwZW55ZXN1YWlhbiBCSC4NCg0KIyMgR2V0aXPigJNPcmQgR2k6IGtvbnNlbnRyYXNpIHRpbmdnaSBkYW4gcmVuZGFoIHNlY2FyYSBsb2thbA0KDQoqKkdldGlz4oCTT3JkIEdpKiogZGlndW5ha2FuIHVudHVrIG1lbmNhcmkgd2lsYXlhaCB5YW5nIGxpbmdrdW5nYW4gdGV0YW5nZ2FueWEgbWVtaWxpa2kga29uc2VudHJhc2kgbmlsYWkgdGluZ2dpICgqaG90c3BvdCopIGF0YXUgbmlsYWkgcmVuZGFoICgqY29sZHNwb3QqKS4gUGFkYSBjb250b2ggaW5pLCBraXRhIG1lbWVyaWtzYSBrb25zZW50cmFzaSBhbmdrYSBrcmltaW5hbGl0YXMgZGkgc2VraXRhciBzZXRpYXAgd2lsYXlhaC4NCg0KRnVuZ3NpIGBsb2NhbEcoKWAgbWVuZ2hhc2lsa2FuIG5pbGFpICoqWioqLiBaIHBvc2l0aWYgbWVudW5qdWtrYW4ga2VjZW5kZXJ1bmdhbiBrb25zZW50cmFzaSBuaWxhaSB0aW5nZ2ksIHNlZGFuZ2thbiBaIG5lZ2F0aWYgbWVudW5qdWtrYW4ga2VjZW5kZXJ1bmdhbiBrb25zZW50cmFzaSBuaWxhaSByZW5kYWguIE5hbXVuLCBwZW5ldGFwYW4gaG90c3BvdCBhdGF1IGNvbGRzcG90IGp1Z2EgaGFydXMgbWVtcGVydGltYmFuZ2thbiBwLXZhbHVlLg0KDQpQZW5ndWppYW4gbWVuZ2d1bmFrYW4gcGVuZGVrYXRhbiBub3JtYWwgZHVhIHNpc2ksIGtlbXVkaWFuIHAtdmFsdWUgZGlzZXN1YWlrYW4gZGVuZ2FuIG1ldG9kZSAqKkJIKioga2FyZW5hIGJhbnlhayB3aWxheWFoIGRpdWppIHNla2FsaWd1cy4NCg0KYGBge3IgZ2V0aXMtbG9rYWx9DQpHaV96IDwtIGFzLm51bWVyaWMobG9jYWxHKHgsIGx3X0IpKQ0KR2lfcCA8LSAyICogcG5vcm0oLWFicyhHaV96KSkgICAjIHBlbmRla2F0YW4gbm9ybWFsLCBkdWEgc2lzaQ0KR2lfcF9CSCA8LSBwLmFkanVzdChHaV9wLCBtZXRob2QgPSAiQkgiKQ0KDQpjb2wkR2lfcG9sYSA8LSBmYWN0b3IoDQogIGlmZWxzZShHaV9wX0JIID49IGFscGhhLCAiQmVsdW0gc2lnbmlmaWthbiIsDQogICAgICAgICBpZmVsc2UoR2lfeiA+IDAsICJIb3RzcG90IiwgIkNvbGRzcG90IikpLA0KICBsZXZlbHMgPSBjKCJIb3RzcG90IiwgIkNvbGRzcG90IiwgIkJlbHVtIHNpZ25pZmlrYW4iKQ0KKQ0KZ2dwbG90KGNvbCkgKw0KICBnZW9tX3NmKGFlcyhmaWxsID0gR2lfcG9sYSksIGNvbG9yID0gIndoaXRlIiwgbGluZXdpZHRoID0gMC4zKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoSG90c3BvdCA9ICIjYjgzMjQ4IiwgQ29sZHNwb3QgPSAiIzI4NzhhZCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQmVsdW0gc2lnbmlmaWthbiIgPSAiI2UxZTZlOSIpLCBkcm9wID0gRkFMU0UpICsNCiAgbGFicyh0aXRsZSA9ICJHZXRpc+KAk09yZCBHaToga29uc2VudHJhc2kgQ1JJTUUgZGkgdGV0YW5nZ2EiLA0KICAgICAgIHN1YnRpdGxlID0gIlVqaSBub3JtYWwgZHVhIHNpc2k7IHAgZGlzZXN1YWlrYW4gQkgiLCBmaWxsID0gIlBvbGEiKSArDQogIGNvb3JkX3NmKGRhdHVtID0gTkEpICsNCiAgdGhlbWVfdm9pZCgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpDQoNCmtuaXRyOjprYWJsZShoZWFkKGRhdGEuZnJhbWUoaWQgPSBjb2wkaWQsIFpfR2kgPSBHaV96LCBwID0gR2lfcCwgcF9CSCA9IEdpX3BfQkgpKSwgZGlnaXRzID0gNCkNCmBgYA0KDQpQYWRhIHRhcmFmIHNpZ25pZmlrYW5zaSAqKjUlKiosIHRlcmRhcGF0ICoqNCB3aWxheWFoIHlhbmcgdGVyaWRlbnRpZmlrYXNpIHNlYmFnYWkgaG90c3BvdCoqIHNldGVsYWggcGVueWVzdWFpYW4gQkguIFdpbGF5YWggdGVyc2VidXQgZGl0YW1waWxrYW4gZGVuZ2FuIHdhcm5hIG1lcmFoIGRpIGJhZ2lhbiB0ZW5nYWggcGV0YS4gQXJ0aW55YSwgbGluZ2t1bmdhbiB0ZXRhbmdnYSBrZWVtcGF0IHdpbGF5YWggaXR1IG1lbWlsaWtpIGtvbnNlbnRyYXNpIGFuZ2thIGtyaW1pbmFsaXRhcyB0aW5nZ2kgeWFuZyBzaWduaWZpa2FuLg0KDQpUaWRhayB0ZXJkYXBhdCBjb2xkc3BvdCB5YW5nIHNpZ25pZmlrYW4gc2V0ZWxhaCBwZW55ZXN1YWlhbiBCSC4gV2lsYXlhaCBiZXJ3YXJuYSBhYnUtYWJ1IG1lbnVuanVra2FuIGJhaHdhIGJ1a3RpIGtvbnNlbnRyYXNpIG5pbGFpIHRpbmdnaSBtYXVwdW4gcmVuZGFoIGJlbHVtIGN1a3VwLCBidWthbiBiZXJhcnRpIHdpbGF5YWggdGVyc2VidXQgcGFzdGkgbWVtaWxpa2kga3JpbWluYWxpdGFzIHJlbmRhaC4NCg0KVGFiZWwgaGFueWEgbWVuYW1waWxrYW4gZW5hbSB3aWxheWFoIHBlcnRhbWEuIFNlbHVydWhueWEgbWVtaWxpa2kgKipwX0JIID4gMCwwNSoqLCBzZWhpbmdnYSBiZWx1bSBkYXBhdCBkaW55YXRha2FuIHNlYmFnYWkgaG90c3BvdCBhdGF1IGNvbGRzcG90IG1lc2tpcHVuIG5pbGFpIFotbnlhIHBvc2l0aWYgYXRhdSBuZWdhdGlmLg0KDQpQZXJiZWRhYW4gKipHaSoqIGRhbiAqKkdpXCoqKiB0ZXJsZXRhayBwYWRhIG5pbGFpIHlhbmcgZGlzZXJ0YWthbiBkYWxhbSBwZXJoaXR1bmdhbjoNCg0KLSAqKkdpKiogaGFueWEgbWVuZ2d1bmFrYW4gbmlsYWkgd2lsYXlhaC13aWxheWFoIHRldGFuZ2dhLg0KLSAqKkdpXCoqKiBtZW5nZ3VuYWthbiBuaWxhaSB3aWxheWFoLXdpbGF5YWggdGV0YW5nZ2EgKipiZXNlcnRhIG5pbGFpIHdpbGF5YWggeWFuZyBzZWRhbmcgZGlwZXJpa3NhKiouDQoNCkZ1bmdzaSBgaW5jbHVkZS5zZWxmKG5iKWAgbWVuYW1iYWhrYW4gd2lsYXlhaCBpdHUgc2VuZGlyaSBrZSBkYWxhbSBkYWZ0YXIgdGV0YW5nZ2FueWEgdW50dWsgbWVuZ2hpdHVuZyBHaSouIEthcmVuYSBuaWxhaSB5YW5nIGRpc2VydGFrYW4gYmVyYmVkYSwgaGFzaWwgWiBwYWRhIGtlZHVhIG1ldG9kZSBqdWdhIGRhcGF0IGJlcmJlZGEuIFVudHVrIG1lbmVudHVrYW4gaG90c3BvdCBhdGF1IGNvbGRzcG90IGJlcmRhc2Fya2FuIEdpKiwgcC12YWx1ZSBkYW4gcGVueWVzdWFpYW4gQkggcGVybHUgZGloaXR1bmcga2VtYmFsaSBtZW5nZ3VuYWthbiBoYXNpbCBHaSouDQoNCmBgYHtyIGdldGlzLXN0YXJ9DQpsd19zdGFyIDwtIG5iMmxpc3R3KGluY2x1ZGUuc2VsZihuYiksIHN0eWxlID0gIkIiKQ0KR2lfc3Rhcl96IDwtIGFzLm51bWVyaWMobG9jYWxHKHgsIGx3X3N0YXIpKQ0KaGVhZChkYXRhLmZyYW1lKGlkID0gY29sJGlkLCBaX0dpID0gR2lfeiwgWl9HaV9zdGFyID0gR2lfc3Rhcl96KSkNCmBgYA0KDQpIYXNpbCBrZWR1YSB2ZXJzaSBkYXBhdCBiZXJiZWRhIGthcmVuYSBkZWZpbmlzaSBsaW5na3VuZ2FubnlhIGJlcmJlZGEuIFVqaSBub3JtYWwgZGkgY29udG9oIEdpIGp1Z2EgYmVyYmVkYSBkYXJpIGluZmVyZW5zaSBwZXJtdXRhc2kgTG9jYWwgTW9yYW47IGFsdGVybmF0aWYgcGVybXV0YXNpIEdpIHRlcnNlZGlhIHBhZGEgYGxvY2FsR19wZXJtKClgLiBbUnVqdWthbiBHaSBkYW4gR2kqXShodHRwczovL3Itc3BhdGlhbC5naXRodWIuaW8vc3BkZXAvcmVmZXJlbmNlL2xvY2FsRy5odG1sKS4NCg0KIyBKZW1iYXRhbiBrZSBkdWEgdmFyaWFiZWwNCg0KUGFkYSBhbmFsaXNpcyBzZWJlbHVtbnlhLCBraXRhIG1lbWJhbmRpbmdrYW4gKiphbmdrYSBrcmltaW5hbGl0YXMgc3VhdHUgd2lsYXlhaCBkZW5nYW4gYW5na2Ega3JpbWluYWxpdGFzIHRldGFuZ2dhbnlhKiouIEFuYWxpc2lzIHRlcnNlYnV0IGRpc2VidXQgKip1bml2YXJpYXQqKiBrYXJlbmEgbWVuZ2d1bmFrYW4gc2F0dSB2YXJpYWJlbCwgeWFpdHUgYENSSU1FYC4NCg0KU2VsYW5qdXRueWEsIGtpdGEgbWVtcGVsYWphcmkgaHVidW5nYW4gc3Bhc2lhbCBhbnRhcmEgKipkdWEgdmFyaWFiZWwqKiwgeWFpdHUga3JpbWluYWxpdGFzIChgQ1JJTUVgKSBkYW4gcGVuZGFwYXRhbiBydW1haCB0YW5nZ2EgKGBJTkNgKS4gQW5hbGlzaXMgaW5pIGRpc2VidXQgKipiaXZhcmlhdCoqLCBkZW5nYW4gcGVydGFueWFhbjoNCg0KPiBBcGFrYWggd2lsYXlhaCBkZW5nYW4gYW5na2Ega3JpbWluYWxpdGFzIHRpbmdnaSBjZW5kZXJ1bmcgYmVydGV0YW5nZ2EgZGVuZ2FuIHdpbGF5YWggeWFuZyBtZW1pbGlraSBwZW5kYXBhdGFuIHJ1bWFoIHRhbmdnYSByZW5kYWg/DQoNCkRhbGFtIE1vcmFuIGJpdmFyaWF0LCBraXRhIG1lbWJhbmRpbmdrYW4gKipDUklNRSBzdWF0dSB3aWxheWFoIGRlbmdhbiByYXRhLXJhdGEgSU5DIHRldGFuZ2dhbnlhKiouIFNlbWVudGFyYSBpdHUsIGtvcmVsYXNpIFBlYXJzb24gbWVtYmFuZGluZ2thbiAqKkNSSU1FIGRhbiBJTkMgZGFsYW0gd2lsYXlhaCB5YW5nIHNhbWEqKi4NCg0KVW50dWsgbWVuamFnYSBrZWplbGFzYW4gYW5hbGlzaXMsIGtpdGEgbWVuZXRhcGthbiAqKlggPSBDUklNRSoqIGRhbiAqKlkgPSBJTkMqKi4gUGVyYmVkYWFuIHBhc2FuZ2FuIHlhbmcgZGliYW5kaW5na2FuIHBhZGEgc2V0aWFwIG1ldG9kZSBkaXJhbmdrdW0gZGFsYW0gdGFiZWwgYmVyaWt1dC4NCg0KfCBBbmFsaXNpcyB8IFBhc2FuZ2FuIHlhbmcgZGliYW5kaW5na2FuIHwgS2FsaW1hdCBwZXJ0YW55YWFuIHwNCnw6LS18Oi0tfDotLXwNCnwgUGVhcnNvbiB8ICRYX2kkIGRlbmdhbiAkWV9pJCB8IEFwYWthaCBkdWEgdmFyaWFiZWwgYmVya2FpdGFuIGRhbGFtIHdpbGF5YWggeWFuZyBzYW1hPyB8DQp8IE1vcmFuIHVuaXZhcmlhdCB8ICRYX2kkIGRlbmdhbiAkKFdYKV9pJCB8IEFwYWthaCBuaWxhaSBYIG1pcmlwIGRlbmdhbiBYIHRldGFuZ2dhPyB8DQp8IE1vcmFuIGJpdmFyaWF0IHwgJFhfaSQgZGVuZ2FuICQoV1kpX2kkIHwgQXBha2FoIFggYmVya2FpdGFuIGRlbmdhbiBZIHRldGFuZ2dhPyB8DQp8IExlZSdzIEwgfCBQb2xhIGxhZyBYIGRlbmdhbiBwb2xhIGxhZyBZIHwgQXBha2FoIGtlZHVhIHZhcmlhYmVsIG1lbWlsaWtpIHBvbGEgbGluZ2t1bmdhbiB5YW5nIHNlamFsYW4/IHwNCg0KIyMgUGVhcnNvbiBzZWJhZ2FpIHBlbWJhbmRpbmcgZGVza3JpcHRpZg0KDQpTZWJlbHVtIG1lbmdhbmFsaXNpcyBodWJ1bmdhbiBzcGFzaWFsIGR1YSB2YXJpYWJlbCwga2l0YSB0ZXJsZWJpaCBkYWh1bHUgbWVsaWhhdCBodWJ1bmdhbiBhbnRhcmEgKipwZW5kYXBhdGFuIHJ1bWFoIHRhbmdnYSAoYElOQ2ApIGRhbiBhbmdrYSBrcmltaW5hbGl0YXMgKGBDUklNRWApIGRhbGFtIHdpbGF5YWggeWFuZyBzYW1hKiogbWVuZ2d1bmFrYW4ga29yZWxhc2kgUGVhcnNvbi4NCg0KS29lZmlzaWVuIFBlYXJzb24gbWVudW5qdWtrYW4gYXJhaCBkYW4ga2VrdWF0YW4gaHVidW5nYW4gbGluZWFyIGFudGFyYSBrZWR1YSB2YXJpYWJlbC4gTmlsYWkgcG9zaXRpZiBtZW51bmp1a2thbiBodWJ1bmdhbiBzZWFyYWgsIHNlZGFuZ2thbiBuaWxhaSBuZWdhdGlmIG1lbnVuanVra2FuIGh1YnVuZ2FuIGJlcmxhd2FuYW4gYXJhaC4gQW5hbGlzaXMgaW5pIGJlbHVtIG1lbXBlcmhpdHVuZ2thbiBodWJ1bmdhbiBrZXRldGFuZ2dhYW4gYW50YXJ3aWxheWFoLg0KDQpgYGB7ciBwZWFyc29ufQ0Kcl94eSA8LSBjb3IoeCwgeSkNCnJfeHkNCg0KZ2dwbG90KGNvbCwgYWVzKElOQywgQ1JJTUUpKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAiIzI1ODU4ZSIsIHNpemUgPSAyLjUpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgZm9ybXVsYSA9IHkgfiB4LCBzZSA9IEZBTFNFLCBjb2xvciA9ICIjMTgzZjU2IikgKw0KICBsYWJzKHRpdGxlID0gIlBlbmRhcGF0YW4gZGFuIGtyaW1pbmFsaXRhcyBkYWxhbSB3aWxheWFoIHlhbmcgc2FtYSIsDQogICAgICAgc3VidGl0bGUgPSBwYXN0ZSgiS29yZWxhc2kgUGVhcnNvbiA9IiwgZm10KHJfeHkpKSwNCiAgICAgICB4ID0gIklOQyB8IHJpYnVhbiBVU0QiLCB5ID0gIkNSSU1FIHwgcGVyIDEuMDAwIHJ1bWFoIHRhbmdnYSIpDQpgYGANCg0KTmlsYWkga29yZWxhc2kgUGVhcnNvbiBzZWJlc2FyICoq4oiSMCw2OTYqKiBtZW51bmp1a2thbiBodWJ1bmdhbiBsaW5lYXIgbmVnYXRpZiBhbnRhcmEgcGVuZGFwYXRhbiBkYW4ga3JpbWluYWxpdGFzLiBBcnRpbnlhLCB3aWxheWFoIGRlbmdhbiBwZW5kYXBhdGFuIHJ1bWFoIHRhbmdnYSBsZWJpaCB0aW5nZ2kgY2VuZGVydW5nIG1lbWlsaWtpIGFuZ2thIGtyaW1pbmFsaXRhcyBsZWJpaCByZW5kYWguIEtlY2VuZGVydW5nYW4gaW5pIHRlcmxpaGF0IGRhcmkgc2ViYXJhbiB0aXRpayBkYW4gZ2FyaXMgeWFuZyBtZW51cnVuIHBhZGEgZ3JhZmlrLg0KDQpTZXRpYXAgdGl0aWsgbWV3YWtpbGkgcGFzYW5nYW4gbmlsYWkgYElOQ2AgZGFuIGBDUklNRWAgZGFsYW0gKipzYXR1IHdpbGF5YWggeWFuZyBzYW1hKiouIEhhc2lsIGluaSBkaWd1bmFrYW4gc2ViYWdhaSBnYW1iYXJhbiBhd2FsLCBiZWx1bSBtZW51bmp1a2thbiBodWJ1bmdhbiBkZW5nYW4gd2lsYXlhaCB0ZXRhbmdnYSBkYW4gdGlkYWsgbWVtYnVrdGlrYW4gc2ViYWItYWtpYmF0LiBTZWxhbmp1dG55YSwgTW9yYW4gYml2YXJpYXQgZGlndW5ha2FuIHVudHVrIG1lbWJhbmRpbmdrYW4ga3JpbWluYWxpdGFzIHN1YXR1IHdpbGF5YWggZGVuZ2FuIHBlbmRhcGF0YW4gd2lsYXlhaCB0ZXRhbmdnYW55YS4NCg0KIyBNb3JhbiBiaXZhcmlhdCBnbG9iYWwNCg0KIyMgQXBhIHlhbmcgZGloaXR1bmc/DQoNCioqTW9yYW4gYml2YXJpYXQgZ2xvYmFsKiogZGlndW5ha2FuIHVudHVrIG1lbGloYXQgaHVidW5nYW4gYW50YXJhIG5pbGFpIHN1YXR1IHZhcmlhYmVsIGRpIHNlYnVhaCB3aWxheWFoIGRhbiBuaWxhaSB2YXJpYWJlbCBsYWluIHBhZGEgdGV0YW5nZ2FueWEuIERhbGFtIGNvbnRvaCBpbmksIGtpdGEgbWVtYmFuZGluZ2thbiAqKmtyaW1pbmFsaXRhcyBzdWF0dSB3aWxheWFoIChgQ1JJTUVgKSBkZW5nYW4gcmF0YS1yYXRhIHBlbmRhcGF0YW4gdGV0YW5nZ2FueWEgKGBJTkNgKSoqLg0KDQpLZWR1YSB2YXJpYWJlbCB0ZXJsZWJpaCBkYWh1bHUgZGl1YmFoIG1lbmphZGkgc2tvciBiYWt1IGthcmVuYSBtZW1pbGlraSBzYXR1YW4gYmVyYmVkYS4gU2VsYW5qdXRueWEsIHBlcmhpdHVuZ2FuIGRpbGFrdWthbiBkYWxhbSBkdWEgYXJhaDogKipDUklNRSDihpIgSU5DIHRldGFuZ2dhKiogZGFuICoqSU5DIOKGkiBDUklNRSB0ZXRhbmdnYSoqLiBUYW5kYSBwYW5haCBtZW51bmp1a2thbiB1cnV0YW4gdmFyaWFiZWwgeWFuZyBkaWJhbmRpbmdrYW4sIGJ1a2FuIGh1YnVuZ2FuIHNlYmFiLWFraWJhdC4NCg0KRGVuZ2FuIFcgeWFuZyBqdW1sYWggc2V0aWFwIGJhcmlzbnlhIHNhdHU6DQoNClxbDQpJX3tYXHRvIFl9ID0gXGZyYWN7XHN1bV9pIHpfe1hpfShXel9ZKV9pfXtcc3VtX2kgel97WGl9XjJ9Lg0KXF0NCg0KYGBge3IgbW9yYW4tYml2YXJpYXQtbmlsYWl9DQojIEZ1bmdzaSByaW5na2FzIGJ1YXRhbiBtb2R1bDsga2h1c3VzIGJvYm90IFcgdGFucGEgd2lsYXlhaCB0ZXJpc29sYXNpLg0KSV9iaXZhcmlhdCA8LSBmdW5jdGlvbih6X2FzYWwsIHpfdGV0YW5nZ2EsIGxpc3R3KSB7DQogIHN1bSh6X2FzYWwgKiBsYWcubGlzdHcobGlzdHcsIHpfdGV0YW5nZ2EpKSAvIHN1bSh6X2FzYWxeMikNCn0NCklfeHkgPC0gSV9iaXZhcmlhdCh6eCwgenksIGx3X1cpDQpJX3l4IDwtIElfYml2YXJpYXQoenksIHp4LCBsd19XKQ0KDQprbml0cjo6a2FibGUoZGF0YS5mcmFtZSgNCiAgdWt1cmFuID0gYygiUGVhcnNvbjogQ1JJTUUgZGFuIElOQyBzYXR1IHdpbGF5YWgiLA0KICAgICAgICAgICAgICJNb3JhbiBiaXZhcmlhdDogQ1JJTUUgLT4gSU5DIHRldGFuZ2dhIiwNCiAgICAgICAgICAgICAiTW9yYW4gYml2YXJpYXQ6IElOQyAtPiBDUklNRSB0ZXRhbmdnYSIpLA0KICBuaWxhaSA9IGMocl94eSwgSV94eSwgSV95eCkNCiksIGRpZ2l0cyA9IDQpDQpgYGANCkhhc2lsIHBlcmhpdHVuZ2FuIG1lbnVuanVra2FuOg0KDQotICoqUGVhcnNvbiA9IOKIkjAsNjk1NjoqKiB3aWxheWFoIGRlbmdhbiBwZW5kYXBhdGFuIGxlYmloIHRpbmdnaSBjZW5kZXJ1bmcgbWVtaWxpa2kga3JpbWluYWxpdGFzIGxlYmloIHJlbmRhaCBkYWxhbSB3aWxheWFoIHlhbmcgc2FtYS4NCi0gKipNb3JhbiBDUklNRSDihpIgSU5DIHRldGFuZ2dhID0g4oiSMCw0Mjg2OioqIHdpbGF5YWggZGVuZ2FuIGtyaW1pbmFsaXRhcyB0aW5nZ2kgY2VuZGVydW5nIG1lbWlsaWtpIHRldGFuZ2dhIGRlbmdhbiByYXRhLXJhdGEgcGVuZGFwYXRhbiByZW5kYWgsIGRhbiBzZWJhbGlrbnlhLg0KLSAqKk1vcmFuIElOQyDihpIgQ1JJTUUgdGV0YW5nZ2EgPSDiiJIwLDQ1MTY6Kiogd2lsYXlhaCBkZW5nYW4gcGVuZGFwYXRhbiB0aW5nZ2kgY2VuZGVydW5nIG1lbWlsaWtpIHRldGFuZ2dhIGRlbmdhbiByYXRhLXJhdGEga3JpbWluYWxpdGFzIHJlbmRhaCwgZGFuIHNlYmFsaWtueWEuDQoNCktlZHVhIG5pbGFpIE1vcmFuIGJpdmFyaWF0IGJlcmJlZGEga2FyZW5hIHBlcnR1a2FyYW4gdmFyaWFiZWwgbWVuZ3ViYWggcGFzYW5nYW4geWFuZyBkaWJhbmRpbmdrYW4sIHNlbWVudGFyYSBib2JvdCBkYXJpIHNhdHUgd2lsYXlhaCBrZSB0ZXRhbmdnYW55YSBiZWx1bSB0ZW50dSBzYW1hIGRlbmdhbiBib2JvdCBhcmFoIHNlYmFsaWtueWEuDQoNCk5pbGFpIG5lZ2F0aWYgbWVudW5qdWtrYW4ga2VjZW5kZXJ1bmdhbiBodWJ1bmdhbiB5YW5nIGJlcmxhd2FuYW4gYXJhaC4gTmFtdW4sICoqc2lnbmlmaWthbnNpbnlhIG1hc2loIHBlcmx1IGRpcGVyaWtzYSBtZWxhbHVpIHVqaSBwZXJtdXRhc2kqKi4gTmlsYWkgaW5kZWtzIHRlcnNlYnV0IGp1Z2EgdGlkYWsgZGFwYXQgZGlhcnRpa2FuIHNlYmFnYWkgcGVyc2VudGFzZSBwZW5nYXJ1aC4gW1J1anVrYW4gZGVmaW5pc2kgTW9yYW4gYml2YXJpYXRdKGh0dHBzOi8vci1zcGF0aWFsLmdpdGh1Yi5pby9zcGRlcC9yZWZlcmVuY2UvbW9yYW5fYnYuaHRtbCkuDQoNCiMjIFVqaSBwZXJtdXRhc2k6IG55YXRha2FuIGFwYSB5YW5nIGRpYWNhaw0KDQpVbnR1ayBtZW5pbGFpIGFwYWthaCBodWJ1bmdhbiBzcGFzaWFsIHlhbmcgZGl0ZW11a2FuIHNpZ25pZmlrYW4sIGtpdGEgbWVsYWt1a2FuICoqdWppIHBlcm11dGFzaSoqLiBOaWxhaSBwZW5kYXBhdGFuIChgSU5DYCkgZGlhY2FrIGFudGFyd2lsYXlhaCwgc2VkYW5na2FuIG5pbGFpIGtyaW1pbmFsaXRhcyAoYENSSU1FYCkgZGFuIGJvYm90IGtldGV0YW5nZ2FhbiB0ZXRhcC4NCg0KU2V0aWFwIHBlbmdhY2FrYW4gbWVuZ2hhc2lsa2FuIG5pbGFpIE1vcmFuIGJpdmFyaWF0IGJhcnUuIFByb3NlcyBpbmkgZGl1bGFuZyAqKjkuOTk5IGthbGkqKiwga2VtdWRpYW4gaGFzaWxueWEgZGliYW5kaW5na2FuIGRlbmdhbiBNb3JhbiBiaXZhcmlhdCBkYXJpIGRhdGEgYXNsaS4NCg0KSGlwb3Rlc2lzIHlhbmcgZGlndW5ha2FuIGFkYWxhaDoNCg0KLSAqKkjigoA6KiogcGVuZW1wYXRhbiBuaWxhaSBgSU5DYCBhbnRhcndpbGF5YWggYmVyc2lmYXQgYWNhaywgZGVuZ2FuIGBDUklNRWAgZGFuIGJvYm90IHNwYXNpYWwgdGV0YXAuDQotICoqSOKCgToqKiBodWJ1bmdhbiB5YW5nIGRpYW1hdGkgbGViaWgga3VhdCwgYmFpayBrZSBhcmFoIHBvc2l0aWYgbWF1cHVuIG5lZ2F0aWYsIGRhcmlwYWRhIHlhbmcgZGloYXJhcGthbiBkYXJpIHBlbmdhY2FrYW4gdGVyc2VidXQuDQoNCkthcmVuYSBrZWR1YSBhcmFoIGRpcGVyaWtzYSwgcGVuZ3VqaWFuIG1lbmdndW5ha2FuIG5pbGFpIGFic29sdXQgaW5kZWtzIHVudHVrIG1lbmdoaXR1bmcgcC12YWx1ZSBkdWEgc2lzaS4NCg0KYGBge3IgcGVybXV0YXNpLWJpdmFyaWF0fQ0Kc2V0LnNlZWQoMjAyNykNCklfeHlfc2ltIDwtIHJlcGxpY2F0ZShCLCB7DQogIHp5X2FjYWsgPC0gc2FtcGxlKHp5LCByZXBsYWNlID0gRkFMU0UpDQogIElfYml2YXJpYXQoengsIHp5X2FjYWssIGx3X1cpDQp9KQ0KcF94eSA8LSAoMSArIHN1bShhYnMoSV94eV9zaW0pID49IGFicyhJX3h5KSkpIC8gKEIgKyAxKQ0KZGF0YS5mcmFtZShJX0NSSU1FX0lOQyA9IElfeHksIHBfZHVhX3Npc2kgPSBwX3h5LCBwZXJtdXRhc2kgPSBCKQ0KYGBgDQoNCk1vcmFuIGJpdmFyaWF0ICoqQ1JJTUUgdGVyaGFkYXAgSU5DIHRldGFuZ2dhIHNlYmVzYXIg4oiSMCw0Mjg2KiosIGRlbmdhbiAqKnAtdmFsdWUgMCwwMDAxKiouIEthcmVuYSBwLXZhbHVlIGxlYmloIGtlY2lsIGRhcmkgMCwwNSwgKipI4oKAIGRpdG9sYWsqKi4NCg0KSGFzaWwgaW5pIG1lbmR1a3VuZyBodWJ1bmdhbiBzcGFzaWFsIHlhbmcgYmVybGF3YW5hbiBhcmFoOiB3aWxheWFoIGRlbmdhbiBrcmltaW5hbGl0YXMgdGluZ2dpIGNlbmRlcnVuZyBtZW1pbGlraSB0ZXRhbmdnYSBkZW5nYW4gcmF0YS1yYXRhIHBlbmRhcGF0YW4gcmVuZGFoLCBzZWRhbmdrYW4gd2lsYXlhaCBkZW5nYW4ga3JpbWluYWxpdGFzIHJlbmRhaCBjZW5kZXJ1bmcgbWVtaWxpa2kgdGV0YW5nZ2EgZGVuZ2FuIHJhdGEtcmF0YSBwZW5kYXBhdGFuIHRpbmdnaS4NCg0KS2VzaW1wdWxhbiB0ZXJzZWJ1dCBiZXJsYWt1IHRlcmhhZGFwIHBlbmdhY2FrYW4gYElOQ2AgeWFuZyBkaWd1bmFrYW4uIFBlbmd1amlhbiBpbmkgYmVsdW0gbWVuZ2VuZGFsaWthbiBwb2xhIHNwYXNpYWwgcGVuZGFwYXRhbiBtYXVwdW4gaHVidW5nYW4gcGVuZGFwYXRhbuKAk2tyaW1pbmFsaXRhcyBkYWxhbSB3aWxheWFoIHlhbmcgc2FtYSwgZGFuIHRpZGFrIG1lbWJ1a3Rpa2FuIHNlYmFiLWFraWJhdC4NCg0KIyMgQml2YXJpYXRlIE1vcmFuIHNjYXR0ZXJwbG90DQoNCioqQml2YXJpYXRlIE1vcmFuIHNjYXR0ZXJwbG90KiogbWVtcGVybGloYXRrYW4gaHVidW5nYW4gYW50YXJhIGtyaW1pbmFsaXRhcyBzdWF0dSB3aWxheWFoIGRhbiByYXRhLXJhdGEgcGVuZGFwYXRhbiB0ZXRhbmdnYW55YS4gU2V0aWFwIHRpdGlrIG1ld2FraWxpIHNhdHUgd2lsYXlhaC4NCg0KU3VtYnUgaG9yaXpvbnRhbCBtZW51bmp1a2thbiBza29yIGJha3UgYENSSU1FYCB3aWxheWFoIHRlcnNlYnV0LCBzZWRhbmdrYW4gc3VtYnUgdmVydGlrYWwgbWVudW5qdWtrYW4gcmF0YS1yYXRhIHNrb3IgYmFrdSBgSU5DYCB0ZXRhbmdnYW55YS4gR2FyaXMgbm9sIG1lbWJhZ2kgZ3JhZmlrIG1lbmphZGkgZW1wYXQga3VhZHJhbi4gSHVydWYgcGVydGFtYSBtZW51bmp1a2thbiBrb25kaXNpIGtyaW1pbmFsaXRhcyB3aWxheWFoLCBzZWRhbmdrYW4gaHVydWYga2VkdWEgbWVudW5qdWtrYW4ga29uZGlzaSBwZW5kYXBhdGFuIHRldGFuZ2dhbnlhLg0KDQpgYGB7ciBzY2F0dGVycGxvdC1iaXZhcmlhdCwgZmlnLmhlaWdodD01Ljd9DQpxX2J2IDwtIGt1YWRyYW4oengsIHd6eSkNCmRmX2J2IDwtIGRhdGEuZnJhbWUoaWQgPSBjb2wkaWQsIHp4ID0gengsIHd6eSA9IHd6eSwga3VhZHJhbiA9IHFfYnYpDQpnZ3Bsb3QoZGZfYnYsIGFlcyh6eCwgd3p5LCBjb2xvciA9IGt1YWRyYW4pKSArDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGNvbG9yID0gImdyZXk2NSIpICsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgY29sb3IgPSAiZ3JleTY1IikgKw0KICBnZW9tX3BvaW50KHNpemUgPSAyLjYpICsNCiAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSBJX3h5LCBjb2xvciA9ICIjMTgzZjU2IiwgbGluZXdpZHRoID0gMC45KSArDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSB3YXJuYV9wb2xhLCBkcm9wID0gRkFMU0UpICsNCiAgbGFicyh0aXRsZSA9ICJNb3JhbiBiaXZhcmlhdDoga3JpbWluYWxpdGFzIHdpbGF5YWggZGFuIHBlbmRhcGF0YW4gdGV0YW5nZ2EiLA0KICAgICAgIHN1YnRpdGxlID0gcGFzdGUoIktlbWlyaW5nYW4gZ2FyaXMgbWVsYWx1aSBub2wgPSIsIGZtdChJX3h5KSksDQogICAgICAgeCA9ICJ6IENSSU1FIGxva2FzaSIsIHkgPSAiV3ogSU5DIHRldGFuZ2dhIiwgY29sb3IgPSAiS3VhZHJhbiIpDQpgYGANCg0KfCBLdWFkcmFuIHwgSW50ZXJwcmV0YXNpIHNwZXNpZmlrIGthc3VzIHwNCnw6LS18Oi0tfA0KfCBISCB8IENSSU1FIHdpbGF5YWggdGluZ2dpLCByYXRhLXJhdGEgSU5DIHRldGFuZ2dhIHRpbmdnaSB8DQp8IExMIHwgQ1JJTUUgd2lsYXlhaCByZW5kYWgsIHJhdGEtcmF0YSBJTkMgdGV0YW5nZ2EgcmVuZGFoIHwNCnwgSEwgfCBDUklNRSB3aWxheWFoIHRpbmdnaSwgcmF0YS1yYXRhIElOQyB0ZXRhbmdnYSByZW5kYWggfA0KfCBMSCB8IENSSU1FIHdpbGF5YWggcmVuZGFoLCByYXRhLXJhdGEgSU5DIHRldGFuZ2dhIHRpbmdnaSB8DQoNClNlYmFnaWFuIGJlc2FyIHRpdGlrIGJlcmFkYSBwYWRhIGt1YWRyYW4gKipITCoqIGRhbiAqKkxIKio6DQoNCi0gKipITCAoa2FuYW4gYmF3YWgpOioqIGtyaW1pbmFsaXRhcyB3aWxheWFoIGRpIGF0YXMgcmF0YS1yYXRhLCBzZWRhbmdrYW4gcmF0YS1yYXRhIHBlbmRhcGF0YW4gdGV0YW5nZ2FueWEgZGkgYmF3YWggcmF0YS1yYXRhLg0KLSAqKkxIIChraXJpIGF0YXMpOioqIGtyaW1pbmFsaXRhcyB3aWxheWFoIGRpIGJhd2FoIHJhdGEtcmF0YSwgc2VkYW5na2FuIHJhdGEtcmF0YSBwZW5kYXBhdGFuIHRldGFuZ2dhbnlhIGRpIGF0YXMgcmF0YS1yYXRhLg0KDQpCZWJlcmFwYSB3aWxheWFoIGJlcmFkYSBwYWRhIGt1YWRyYW4gKipISCoqLCB5YWl0dSBrcmltaW5hbGl0YXMgd2lsYXlhaCBkYW4gcmF0YS1yYXRhIHBlbmRhcGF0YW4gdGV0YW5nZ2FueWEgc2FtYS1zYW1hIHRpbmdnaSwgYXRhdSAqKkxMKiosIHlhaXR1IGtlZHVhbnlhIHNhbWEtc2FtYSByZW5kYWguIFRpbmdnaSBkYW4gcmVuZGFoIGRpIHNpbmkgZGliYW5kaW5na2FuIGRlbmdhbiByYXRhLXJhdGEgbWFzaW5nLW1hc2luZyB2YXJpYWJlbCBkaSBzZWx1cnVoIHdpbGF5YWguDQoNCkdhcmlzIHlhbmcgbWVudXJ1biBtZW1pbGlraSBrZW1pcmluZ2FuIHNla2l0YXIgKiriiJIwLDQyOSoqLCBzZXN1YWkgZGVuZ2FuIE1vcmFuIGJpdmFyaWF0IHlhbmcgdGVsYWggZGloaXR1bmcuIFBvbGEgaW5pIG1lbnVuanVra2FuIGtlY2VuZGVydW5nYW4gaHVidW5nYW4gYmVybGF3YW5hbiBhcmFoIGFudGFyYSBrcmltaW5hbGl0YXMgd2lsYXlhaCBkYW4gcGVuZGFwYXRhbiB0ZXRhbmdnYW55YS4NCg0KV2FybmEga3VhZHJhbiBtZW51bmp1a2thbiBqZW5pcyBwb2xhLCAqKmJlbHVtIG1lbnVuanVra2FuIHNpZ25pZmlrYW5zaSBzZXRpYXAgd2lsYXlhaCoqLiBVbnR1ayBtZW5pbGFpbnlhLCBhbmFsaXNpcyBkaWxhbmp1dGthbiBkZW5nYW4gTG9jYWwgTW9yYW4gYml2YXJpYXQuDQoNCiMgTG9jYWwgTW9yYW4gYml2YXJpYXQNCg0KIyMgRGFyaSBwb2xhIGtlc2VsdXJ1aGFuIGtlIHdpbGF5YWggdGVydGVudHUNCg0KTG9jYWwgTW9yYW4gYml2YXJpYXQgZGlndW5ha2FuIHVudHVrIG1lbmdldGFodWkgd2lsYXlhaCBtYW5hIHlhbmcgbWVudW5qdWtrYW4gaHVidW5nYW4gYW50YXJhICoqa3JpbWluYWxpdGFzIHdpbGF5YWggdGVyc2VidXQgZGFuIHJhdGEtcmF0YSBwZW5kYXBhdGFuIHRldGFuZ2dhbnlhKiouDQoNClBlbmd1amlhbiBkaWxha3VrYW4gcGFkYSBzZXRpYXAgd2lsYXlhaCBkZW5nYW4gbWVtcGVydGFoYW5rYW4gbmlsYWkgQ1JJTUUgd2lsYXlhaCB0ZXJzZWJ1dCwgbGFsdSBtZW1iYW5kaW5na2FuIGhhc2lsbnlhIGRlbmdhbiBwZW5nYWNha2FuIG5pbGFpIElOQyBkYXJpIHdpbGF5YWggbGFpbi4gS2FyZW5hIGJhbnlhayB3aWxheWFoIGRpdWppIHNla2FsaWd1cywgcC12YWx1ZSBkaXNlc3VhaWthbiBtZW5nZ3VuYWthbiBtZXRvZGUgQmVuamFtaW5p4oCTSG9jaGJlcmcgKEJIKS4NCg0KYGBge3IgbW9yYW4tYml2YXJpYXQtbG9rYWx9DQpsb2NhbF9idiA8LSBsb2NhbG1vcmFuX2J2KA0KICB4LCB5LCBsd19XLCBuc2ltID0gQiwgc2NhbGUgPSBUUlVFLA0KICBhbHRlcm5hdGl2ZSA9ICJ0d28uc2lkZWQiLCBpc2VlZCA9IDIwMjgsDQogIG5vX3JlcGVhdF9pbl9yb3cgPSBUUlVFDQopDQpjb2xuYW1lcyhsb2NhbF9idikNCg0KcF9idiA8LSBsb2NhbF9idlssICJQcih6ICE9IEUoSWJ2aSkpIFNpbSJdDQpwX2J2X0JIIDwtIHAuYWRqdXN0KHBfYnYsIG1ldGhvZCA9ICJCSCIpDQpzdG9waWZub3QobWF4KGFicyhsb2NhbF9idlssICJJYnZpIl0gLSB6eCAqIHd6eSkpIDwgMWUtOCkNCg0KaGFzaWxfYnYgPC0gZGF0YS5mcmFtZSgNCiAgaWQgPSBjb2wkaWQsIENSSU1FID0geCwgSU5DID0geSwNCiAgbGFnX0lOQyA9IGxhZy5saXN0dyhsd19XLCB5KSwNCiAgSWJ2aSA9IGxvY2FsX2J2WywgIklidmkiXSwga3VhZHJhbiA9IHFfYnYsDQogIHBfcGVybXV0YXNpID0gcF9idiwgcF9CSCA9IHBfYnZfQkgNCikNCmtuaXRyOjprYWJsZShoZWFkKGhhc2lsX2J2W29yZGVyKGhhc2lsX2J2JHBfcGVybXV0YXNpKSwgXSwgMTApLCBkaWdpdHMgPSA0LA0KICAgICAgICAgICAgIGNhcHRpb24gPSAiU2VwdWx1aCBwLXZhbHVlIHRlcmtlY2lsIHVudHVrIENSSU1FIGxva2FzaSBkZW5nYW4gSU5DIHRldGFuZ2dhLiIpDQpgYGANCg0KUGFkYSB0YXJhZiBzaWduaWZpa2Fuc2kgNSUsICoqd2lsYXlhaCBJRCAzMiwgOCwgZGFuIDEyIHRldGFwIHNpZ25pZmlrYW4gc2V0ZWxhaCBwZW55ZXN1YWlhbiBCSCoqLCBrYXJlbmEgbmlsYWkgYHBfQkhgIG1hc2luZy1tYXNpbmcga3VyYW5nIGRhcmkgMCwwNS4NCg0KLSAqKldpbGF5YWggSUQgMzIgYmVycG9sYSBMSDoqKiBrcmltaW5hbGl0YXNueWEgZGkgYmF3YWggcmF0YS1yYXRhLCBzZWRhbmdrYW4gcmF0YS1yYXRhIHBlbmRhcGF0YW4gdGV0YW5nZ2FueWEgZGkgYXRhcyByYXRhLXJhdGEuDQotICoqV2lsYXlhaCBJRCA4IGRhbiAxMiBiZXJwb2xhIEhMOioqIGtyaW1pbmFsaXRhc255YSBkaSBhdGFzIHJhdGEtcmF0YSwgc2VkYW5na2FuIHJhdGEtcmF0YSBwZW5kYXBhdGFuIHRldGFuZ2dhbnlhIGRpIGJhd2FoIHJhdGEtcmF0YS4NCg0KVGluZ2dpIGRhbiByZW5kYWggZGl0ZW50dWthbiBiZXJkYXNhcmthbiByYXRhLXJhdGEgbWFzaW5nLW1hc2luZyB2YXJpYWJlbCBkaSBzZWx1cnVoIHdpbGF5YWguIFVudHVrIG1lbWJhY2Ega29uZGlzaSBwZW5kYXBhdGFuIHRldGFuZ2dhLCBndW5ha2FuIGtvbG9tIGBsYWdfSU5DYDsga29sb20gYElOQ2AgbWVudW5qdWtrYW4gcGVuZGFwYXRhbiB3aWxheWFoIGl0dSBzZW5kaXJpLg0KDQpXaWxheWFoIGxhaW4gZGFsYW0gdGFiZWwgbWVtaWxpa2kgYHBfQkhgIGxlYmloIGRhcmkgMCwwNSBzZWhpbmdnYSBidWt0aSBwb2xhIGxva2FsbnlhIGJlbHVtIGN1a3VwIHNldGVsYWggcGVueWVzdWFpYW4uIEhhc2lsIGluaSBtZW51bmp1a2thbiBrZXRlcmthaXRhbiBhbnRhcndpbGF5YWgsIHRldGFwaSB0aWRhayBtZW1idWt0aWthbiBiYWh3YSBwZW5kYXBhdGFuIHRldGFuZ2dhIG1lbnllYmFia2FuIHRpbmdrYXQga3JpbWluYWxpdGFzIHN1YXR1IHdpbGF5YWguIFtEb2t1bWVudGFzaSBkYW4gY29udG9oIGZ1bmdzaV0oaHR0cHM6Ly9yLXNwYXRpYWwuZ2l0aHViLmlvL3NwZGVwL3JlZmVyZW5jZS9sb2NhbG1vcmFuX2J2Lmh0bWwpLg0KDQojIyBQZXRhIGRhbiBzYXR1IGNvbnRvaCBpbnRlcnByZXRhc2kNCg0KUGV0YSBiZXJpa3V0IG1lbnVuanVra2FuIGxva2FzaSBwb2xhIGh1YnVuZ2FuIGFudGFyYSBrcmltaW5hbGl0YXMgc3VhdHUgd2lsYXlhaCBkYW4gcmF0YS1yYXRhIHBlbmRhcGF0YW4gdGV0YW5nZ2FueWEuIFBldGEgcGVydGFtYSBtZW5nZ3VuYWthbiBwLXZhbHVlIHNlYmVsdW0gcGVueWVzdWFpYW4sIHNlZGFuZ2thbiBwZXRhIGtlZHVhIG1lbmdndW5ha2FuIHAtdmFsdWUgc2V0ZWxhaCBwZW55ZXN1YWlhbiBCSCB1bnR1ayBtZW1wZXJoaXR1bmdrYW4gYmFueWFrbnlhIHBlbmd1amlhbi4gUGVyYmFuZGluZ2FuIGtlZHVhbnlhIG1lbWJhbnR1IGtpdGEgbWVsaWhhdCBwb2xhIHlhbmcgdGV0YXAgc2lnbmlmaWthbiBzZXRlbGFoIHBlbnllc3VhaWFuLg0KDQpgYGB7ciBwZXRhLWJpdmFyaWF0fQ0KcGV0YV9wb2xhKHFfYnYsIHBfYnYsICJNb3JhbiBsb2thbCBiaXZhcmlhdDogQ1JJTUUgLT4gSU5DIHRldGFuZ2dhIiwNCiAgICAgICAgICAiRWtzcGxvcmFzaSB8IHAgcGVybXV0YXNpIG1lbnRhaDsgaHVydWYgcGVydGFtYSBDUklNRSwgaHVydWYga2VkdWEgbGFnIElOQyIpDQpwZXRhX3BvbGEocV9idiwgcF9idl9CSCwgIk1vcmFuIGxva2FsIGJpdmFyaWF0OiBDUklNRSAtPiBJTkMgdGV0YW5nZ2EiLA0KICAgICAgICAgICJQZW1iYW5kaW5nIHwgcCBkaXNlc3VhaWthbiBCSCIpDQoNCmtuaXRyOjprYWJsZShhcy5kYXRhLmZyYW1lKHRhYmxlKA0KICBLdWFkcmFuID0gcV9idiwgTG9sb3NfQkggPSBpZmVsc2UocF9idl9CSCA8IGFscGhhLCAiWWEiLCAiQmVsdW0iKQ0KKSksIGNhcHRpb24gPSAiSnVtbGFoIHdpbGF5YWggbWVudXJ1dCBrdWFkcmFuIGRhbiBoYXNpbCBwZW55ZXN1YWlhbiBCSC4iKQ0KYGBgDQoNClBhZGEgdGFyYWYgc2lnbmlmaWthbnNpIDUlLCB0ZXJkYXBhdCAqKjE0IHdpbGF5YWggeWFuZyBzaWduaWZpa2FuIHNlYmVsdW0gcGVueWVzdWFpYW4gQkgqKi4gU2V0ZWxhaCBwZW55ZXN1YWlhbiwgKiozIHdpbGF5YWggdGV0YXAgc2lnbmlmaWthbioqLCB5YWl0dToNCg0KLSAqKkR1YSB3aWxheWFoIGJlcnBvbGEgSEwgKG9yYW55ZSk6Kioga3JpbWluYWxpdGFzIHdpbGF5YWggZGkgYXRhcyByYXRhLXJhdGEsIHNlZGFuZ2thbiByYXRhLXJhdGEgcGVuZGFwYXRhbiB0ZXRhbmdnYW55YSBkaSBiYXdhaCByYXRhLXJhdGEuDQotICoqU2F0dSB3aWxheWFoIGJlcnBvbGEgTEggKGhpamF1IGtlYmlydWFuKToqKiBrcmltaW5hbGl0YXMgd2lsYXlhaCBkaSBiYXdhaCByYXRhLXJhdGEsIHNlZGFuZ2thbiByYXRhLXJhdGEgcGVuZGFwYXRhbiB0ZXRhbmdnYW55YSBkaSBhdGFzIHJhdGEtcmF0YS4NCg0KVGlkYWsgYWRhIHdpbGF5YWggYmVycG9sYSBISCBhdGF1IExMIHlhbmcgdGV0YXAgc2lnbmlmaWthbiBzZXRlbGFoIHBlbnllc3VhaWFuIEJILiBXaWxheWFoIGJlcndhcm5hIGFidS1hYnUgbWVudW5qdWtrYW4gYmFod2EgYnVrdGkgc3RhdGlzdGlrbnlhIGJlbHVtIGN1a3VwIHVudHVrIG1lbnlhdGFrYW4gYWRhbnlhIHBvbGEgbG9rYWwgeWFuZyBzaWduaWZpa2FuLg0KDQpCZXJrdXJhbmdueWEgd2lsYXlhaCBiZXJ3YXJuYSB0ZXJqYWRpIGthcmVuYSBwZW55ZXN1YWlhbiBkYWxhbSBtZW5pbGFpIHNpZ25pZmlrYW5zaTsgbmlsYWkga3JpbWluYWxpdGFzIGRhbiBwZW5kYXBhdGFubnlhIHRldGFwIHNhbWEuDQoNCmBgYHtyIHBpbGloLWNvbnRvaC1sb2thbH0NCiMgQW1iaWwgc2F0dSB3aWxheWFoIHVudHVrIGxhdGloYW4gbWVtYmFjYSwgYnVrYW4gdW50dWsgbWVuZ3ViYWggYXR1cmFuIHBlbmd1amlhbi4NCmNvbnRvaCA8LSBoYXNpbF9idlt3aGljaC5taW4oaGFzaWxfYnYkcF9wZXJtdXRhc2kpLCBdDQprbml0cjo6a2FibGUoY29udG9oLCBkaWdpdHMgPSA0LCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KDQpXaWxheWFoICoqSUQgMzIgbWVtaWxpa2kgQ1JJTUUgc2VraXRhciAxOSwxNDYgcGVyIDEuMDAwIHJ1bWFoIHRhbmdnYSoqLCBzZWRhbmdrYW4gcmF0YS1yYXRhIElOQyB0ZXRhbmdnYW55YSBzZWtpdGFyICoqMjYsMDY2IHJpYnUgVVNEKiouIFdpbGF5YWggaW5pIHRlcm1hc3VrIHBvbGEgKipMSCoqIGthcmVuYSBrcmltaW5hbGl0YXNueWEgZGkgYmF3YWggcmF0YS1yYXRhIHNlbHVydWggd2lsYXlhaCwgc2VtZW50YXJhIHJhdGEtcmF0YSBwZW5kYXBhdGFuIHRldGFuZ2dhbnlhIGRpIGF0YXMgcmF0YS1yYXRhLg0KDQpOaWxhaSBMb2NhbCBNb3JhbiBiaXZhcmlhdCBzZWJlc2FyICoq4oiSMSw5NTgxKiosIGRlbmdhbiBwLXZhbHVlIHBlcm11dGFzaSAqKjAsMDAwNCoqIGRhbiBwLXZhbHVlIHNldGVsYWggcGVueWVzdWFpYW4gQkggKiowLDAxOTYqKi4gS2FyZW5hIHAtdmFsdWUgQkgga3VyYW5nIGRhcmkgMCwwNSwgcG9sYSBMSCB0ZXJzZWJ1dCB0ZXRhcCBzaWduaWZpa2FuLg0KDQpQYWRhIHBldGEgbG9rYXNpLCB3YXJuYSBvcmFueWUgbWVuYW5kYWkgd2lsYXlhaCBJRCAzMiwgc2VkYW5na2FuIGhpamF1IG11ZGEgbWVuYW5kYWkgdGV0YW5nZ2FueWEsIHlhaXR1ICoqSUQgMjAsIDIzLCA0MCwgZGFuIDQxKiouIE5pbGFpIElOQyBrZWVtcGF0IHRldGFuZ2dhIGluaWxhaCB5YW5nIGRpZ3VuYWthbiB1bnR1ayBtZW5naGl0dW5nIGBsYWdfSU5DYC4gV2FybmEgcGFkYSBwZXRhIGxva2FzaSBtZW51bmp1a2thbiBwZXJhbiB3aWxheWFoLCBidWthbiBrYXRlZ29yaSBITCBhdGF1IExILg0KDQpgYGB7ciBwZXRhLWxva2FzaS1jb250b2gsIGZpZy5oZWlnaHQ9NS4yLCBmaWcuY2FwPSJUZW11a2FuIHdpbGF5YWggY29udG9oIGRhbiB0ZXRhbmdnYW55YTsgbGFiZWwgbWVudW5qdWtrYW4gSUQgbW9kdWwuIn0NCmxva2F0b3IgPC0gY29sDQpsb2thdG9yJHBlcmFuIDwtICJXaWxheWFoIGxhaW4iDQpsb2thdG9yJHBlcmFuW25iW1tjb250b2gkaWRdXV0gPC0gIlRldGFuZ2dhIGNvbnRvaCINCmxva2F0b3IkcGVyYW5bY29udG9oJGlkXSA8LSAiV2lsYXlhaCBjb250b2giDQpsYWJlbF9pZCA8LSBkYXRhLmZyYW1lKGlkID0gY29sJGlkLCBYID0gdGl0aWtbLCAxXSwgWSA9IHRpdGlrWywgMl0pDQpnZ3Bsb3QobG9rYXRvcikgKw0KICBnZW9tX3NmKGFlcyhmaWxsID0gcGVyYW4pLCBjb2xvciA9ICJ3aGl0ZSIsIGxpbmV3aWR0aCA9IDAuNCkgKw0KICBnZW9tX3RleHQoZGF0YSA9IGxhYmVsX2lkLCBhZXMoWCwgWSwgbGFiZWwgPSBpZCksIHNpemUgPSAyLjUsIGNvbG9yID0gIiMxODM0NDYiKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIldpbGF5YWggY29udG9oIiA9ICIjZThhMjNkIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUZXRhbmdnYSBjb250b2giID0gIiM5ZWRiZDYiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIldpbGF5YWggbGFpbiIgPSAiI2U4ZWRmMCIpKSArDQogIGxhYnModGl0bGUgPSBwYXN0ZSgiTG9rYXNpIHdpbGF5YWggY29udG9oOiBJRCIsIGNvbnRvaCRpZCksIGZpbGwgPSAiUGVyYW4iKSArDQogIGNvb3JkX3NmKGRhdHVtID0gTkEpICsNCiAgdGhlbWVfdm9pZCgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpDQpgYGANCg0KIyBQZW5nYXlhYW46IGR1YSBzdWR1dCBwYW5kYW5nIGJpdmFyaWF0IGxhaW4NCg0KQmFnaWFuIGluaSBtZW5naHVidW5na2FuIHByYWt0aWt1bSBkZW5nYW4gbWF0ZXJpICoqR2VhcnkgYml2YXJpYXQqKiBkYW4gKipMZWUncyBMKiogZGFsYW0gc2xpZGUuIEZva3Vza2FuIHBhZGEgcGVydGFueWFhbiBkYW4gaW50ZXJwcmV0YXNpbnlhOyBwZW51cnVuYW4gcnVtdXMgZGFwYXQgZGliYWNhIHNldGVsYWgga2VsYXMuDQoNCiMjIEdlYXJ5IGJpdmFyaWF0OiBzZWxpc2loIGxpbnRhcyB2YXJpYWJlbA0KDQpHZWFyeSBiaXZhcmlhdCBkYWxhbSBtb2R1bCBpbmkgZGlndW5ha2FuIHVudHVrIG1lbGloYXQgc2ViZXJhcGEgYmVyYmVkYSAqKm5pbGFpIGtyaW1pbmFsaXRhcyBzdWF0dSB3aWxheWFoIGRhbiBwZW5kYXBhdGFuIHdpbGF5YWggdGV0YW5nZ2FueWEqKi4gS2FyZW5hIHNhdHVhbm55YSBiZXJiZWRhLCBDUklNRSBkYW4gSU5DIHRlcmxlYmloIGRhaHVsdSBkaXViYWggbWVuamFkaSBza29yIGJha3UgYWdhciBkYXBhdCBkaWJhbmRpbmdrYW4uDQoNClBlcmhpdHVuZ2FuIG1lbmdndW5ha2FuIGt1YWRyYXQgc2VsaXNpaCBrZWR1YSBza29yIHRlcnNlYnV0IHBhZGEgcGFzYW5nYW4gd2lsYXlhaCB5YW5nIGJlcnRldGFuZ2dhLiBOaWxhaSB5YW5nIGxlYmloIGtlY2lsIG1lbnVuanVra2FuIHNrb3IgeWFuZyBsZWJpaCBtaXJpcC4gSGFzaWxueWEga2VtdWRpYW4gZGliYW5kaW5na2FuIGRlbmdhbiBoYXNpbCBwZW5nYWNha2FuIGxva2FzaSBuaWxhaSBJTkMsIHNlbWVudGFyYSBDUklNRSBkYW4gaHVidW5nYW4ga2V0ZXRhbmdnYWFuIHRldGFwLg0KDQpEZW5nYW4gc2tvciBiYWt1IHNhbXBlbCwgcnVtdXMgcGFkYSBiYWhhbiBrdWxpYWggbWVueWVkZXJoYW5hIG1lbmphZGk6DQoNClxbDQpDX3tYWX09XGZyYWN7MX17MlNfMH1cc3VtX2lcc3VtX2ogd197aWp9KHpfe1hpfS16X3tZan0pXjIuDQpcXQ0KDQoNCmBgYHtyIGdlYXJ5LWJpdmFyaWF0fQ0KQ19iaXZhcmlhdCA8LSBmdW5jdGlvbih6YSwgemIsIFcpIHsNCiAgc3VtKFcgKiBvdXRlcih6YSwgemIsICItIileMikgLyAoMiAqIHN1bShXKSkNCn0NCkNfeHkgPC0gQ19iaXZhcmlhdCh6eCwgenksIFcpDQoNCnNldC5zZWVkKDIwMjkpDQpDX3h5X3NpbSA8LSByZXBsaWNhdGUoQiwgQ19iaXZhcmlhdCh6eCwgc2FtcGxlKHp5KSwgVykpDQpwX0NfYmF3YWggPC0gKDEgKyBzdW0oQ194eV9zaW0gPD0gQ194eSkpIC8gKEIgKyAxKQ0KcF9DX2F0YXMgPC0gKDEgKyBzdW0oQ194eV9zaW0gPj0gQ194eSkpIC8gKEIgKyAxKQ0KcF9DX3h5IDwtIG1pbigxLCAyICogbWluKHBfQ19iYXdhaCwgcF9DX2F0YXMpKQ0KDQprbml0cjo6a2FibGUoZGF0YS5mcmFtZSgNCiAgQ3h5ID0gQ194eSwgcmVyYXRhX3Blcm11dGFzaSA9IG1lYW4oQ194eV9zaW0pLA0KICBoYXJhcGFuX3Rlb3JldGlzID0gKG4gLSAxKSAvIG4sIHBfZHVhX3Npc2kgPSBwX0NfeHkNCiksIGRpZ2l0cyA9IDQpDQpgYGANCg0KTmlsYWkgR2VhcnkgYml2YXJpYXQgeWFuZyBkaXBlcm9sZWggYWRhbGFoICoqMSw1MDI5KiosIGxlYmloIGJlc2FyIGRhcmlwYWRhIHJhdGEtcmF0YSBoYXNpbCBwZW5nYWNha2FuIHNlYmVzYXIgKiowLDk4MDEqKi4gTmlsYWkgcC12YWx1ZSBkdWEgc2lzaSBzZWJlc2FyICoqMCwwMDAyKiosIGxlYmloIGtlY2lsIGRhcmkgMCwwNSwgc2VoaW5nZ2EgSDAgZGl0b2xhay4NCg0KQXJ0aW55YSwgKipwZXJiZWRhYW4gc2tvciBiYWt1IGtyaW1pbmFsaXRhcyB3aWxheWFoIGRhbiBwZW5kYXBhdGFuIHRldGFuZ2dhbnlhIGxlYmloIGJlc2FyIGRhcmlwYWRhIHlhbmcgYmlhc2FueWEgbXVuY3VsIHBhZGEgc3VzdW5hbiBhY2FrKiouIEhhc2lsIGluaSBzZWphbGFuIGRlbmdhbiB0ZW11YW4gTW9yYW4gYml2YXJpYXQgc2ViZWx1bW55YSB5YW5nIG1lbnVuanVra2FuIGtlY2VuZGVydW5nYW4gaHVidW5nYW4gYmVybGF3YW5hbiBhcmFoLg0KDQpQYWRhIHBlcmhpdHVuZ2FuIGluaSwgbmlsYWkgcGVtYmFuZGluZyBzYWF0IHBlbmdhY2FrYW4gc2VraXRhciAqKjAsOTgqKi4gT2xlaCBrYXJlbmEgaXR1LCBpbnRlcnByZXRhc2kgZGlkYXNhcmthbiBwYWRhIGhhc2lsIHBlbmdhY2FrYW4gZGFuIHAtdmFsdWUsIGJ1a2FuIGxhbmdzdW5nIG1lbWFrYWkgcGF0b2thbiBhbmdrYSAxIGRhcmkgR2VhcnkgdW5pdmFyaWF0Lg0KDQojIyBMZWUncyBMOiBwb2xhIGxpbmdrdW5nYW4ga2VkdWEgdmFyaWFiZWwNCg0KTGVl4oCZcyBMIGRpZ3VuYWthbiB1bnR1ayBtZWxpaGF0IGh1YnVuZ2FuIGFudGFyYSAqKnJhdGEtcmF0YSBrcmltaW5hbGl0YXMgdGV0YW5nZ2EgZGFuIHJhdGEtcmF0YSBwZW5kYXBhdGFuIHRldGFuZ2dhKiogZGkgc2VraXRhciBzZXRpYXAgd2lsYXlhaC4gRGVuZ2FuIGRlbWlraWFuLCBrZWR1YSB2YXJpYWJlbCBzYW1hLXNhbWEgZGlyaW5na2FzIGJlcmRhc2Fya2FuIGtvbmRpc2kgd2lsYXlhaCB0ZXRhbmdnYW55YS4NCg0KUGVuZ3VqaWFuIGRpbGFrdWthbiBkZW5nYW4gbWVuZ2FjYWsgbG9rYXNpIHBhc2FuZ2FuIENSSU1F4oCTSU5DIHNlY2FyYSBiZXJzYW1hLXNhbWEsIHNlbWVudGFyYSBodWJ1bmdhbiBrZXRldGFuZ2dhYW4gdGV0YXAuIENhcmEgaW5pIG1lbXBlcnRhaGFua2FuIHBhc2FuZ2FuIG5pbGFpIGtyaW1pbmFsaXRhcyBkYW4gcGVuZGFwYXRhbiBkYXJpIHdpbGF5YWggeWFuZyBzYW1hLCB0ZXRhcGkgbWVuZ3ViYWggc3VzdW5hbm55YSBwYWRhIHBldGEuIFVudHVrIFcgcGFkYSBjb250b2ggaW5pOg0KDQpcWw0KTD1cZnJhY3tcc3VtX2kgKFd6X1gpX2koV3pfWSlfaX0NCntcc3FydHtcc3VtX2kgel97WGl9XjJcc3VtX2kgel97WWl9XjJ9fS4NClxdDQoNCmBgYHtyIGxlZS1nbG9iYWx9DQpMX21hbnVhbCA8LSBzdW0od3p4ICogd3p5KSAvIHNxcnQoc3VtKHp4XjIpICogc3VtKHp5XjIpKQ0KTF9wYWtldCA8LSBsZWUoeCwgeSwgbHdfVywgbiA9IG4pJEwNCnN0b3BpZm5vdChpc1RSVUUoYWxsLmVxdWFsKGFzLm51bWVyaWMoTF9wYWtldCksIExfbWFudWFsKSkpDQoNCnNldC5zZWVkKDIwMzApDQpMX3VqaSA8LSBsZWUubWMoeCwgeSwgbHdfVywgbnNpbSA9IEIsIGFsdGVybmF0aXZlID0gInR3by5zaWRlZCIpDQpMX3VqaQ0KYGBgDQoNCk5pbGFpICoqTGVl4oCZcyBMIHNlYmVzYXIg4oiSMCw0NzAzKiogbWVudW5qdWtrYW4gYmFod2EgcG9sYSBsaW5na3VuZ2FuIGtlZHVhIHZhcmlhYmVsIGNlbmRlcnVuZyBiZXJsYXdhbmFuIGFyYWguIExpbmdrdW5nYW4gZGVuZ2FuIHJhdGEtcmF0YSBrcmltaW5hbGl0YXMgdGV0YW5nZ2EgeWFuZyB0aW5nZ2kgY2VuZGVydW5nIG1lbWlsaWtpIHJhdGEtcmF0YSBwZW5kYXBhdGFuIHRldGFuZ2dhIHlhbmcgcmVuZGFoLCBkYW4gc2ViYWxpa255YS4NCg0KSGFzaWwgdWppIG1lbmdoYXNpbGthbiAqKnAtdmFsdWUgMCwwMDAyKiosIGxlYmloIGtlY2lsIGRhcmkgMCwwNSwgc2VoaW5nZ2EgSDAgZGl0b2xhay4gQXJ0aW55YSwgcG9sYSB5YW5nIGRpYW1hdGkgYmVyYmVkYSBzZWNhcmEgc2lnbmlmaWthbiBkYXJpIHBvbGEgeWFuZyBiaWFzYW55YSBtdW5jdWwga2V0aWthIGxva2FzaSBwYXNhbmdhbiBDUklNReKAk0lOQyBkaWFjYWsuDQoNCk5pbGFpIOKIkjAsNDcwMyBtZW51bmp1a2thbiBhcmFoIGRhbiBiZXNhcm55YSBzdGF0aXN0aWsgaHVidW5nYW4gc3Bhc2lhbCwgYnVrYW4gcGVyc2VudGFzZSBwZW5nYXJ1aC4gSGFzaWwgaW5pIGp1Z2EgdGlkYWsgbWVtYnVrdGlrYW4gaHVidW5nYW4gc2ViYWItYWtpYmF0IGFudGFyYSBwZW5kYXBhdGFuIGRhbiBrcmltaW5hbGl0YXMuDQoNCiMjIExhdGloYW4gcGVuZXJhcGFuDQoNCkxhdGloYW4gaW5pIG1lbmdndW5ha2FuIGRhdGEgQ29sdW1idXMgZGFuIGJvYm90IGtldGV0YW5nZ2FhbiBRdWVlbiB5YW5nIHRlbGFoIGRpYnVhdC4gR3VuYWthbiB0YXJhZiBzaWduaWZpa2Fuc2kgKio1JSoqIGRhbiBqZWxhc2thbiBzZXRpYXAgaGFzaWwgZGVuZ2FuIGJhaGFzYSBzZW5kaXJpLg0KDQojIyMgMS4gTWVtYWhhbWkgbmlsYWkgd2lsYXlhaCBkYW4gbmlsYWkgdGV0YW5nZ2FueWENCg0KUGlsaWggKip3aWxheWFoIElEIDE2KiosIGtlbXVkaWFuOg0KDQoxLiBUYW1waWxrYW4gSUQgc2VsdXJ1aCB0ZXRhbmdnYW55YS4NCjIuIFRhbXBpbGthbiBuaWxhaSBDUklNRSB3aWxheWFoIHRlcnNlYnV0IGRhbiBuaWxhaSBDUklNRSBzZXRpYXAgdGV0YW5nZ2FueWEuDQozLiBIaXR1bmcgcmF0YS1yYXRhIENSSU1FIHRldGFuZ2dhbnlhIHNlY2FyYSBtYW51YWwsIGxhbHUgYmFuZGluZ2thbiBkZW5nYW4gaGFzaWwgYGxhZy5saXN0dygpYC4NCjQuIEplbGFza2FuIGFwYWthaCBrcmltaW5hbGl0YXMgd2lsYXlhaCBJRCAxNiBsZWJpaCB0aW5nZ2kgYXRhdSBsZWJpaCByZW5kYWggZGFyaXBhZGEgcmF0YS1yYXRhIGtyaW1pbmFsaXRhcyB0ZXRhbmdnYW55YS4NCg0KKipIYXNpbCB5YW5nIGRpa3VtcHVsa2FuOioqIHRhYmVsIHRldGFuZ2dhLCBoYXNpbCBwZXJoaXR1bmdhbiwgZGFuIGludGVycHJldGFzaSAy4oCTMyBrYWxpbWF0Lg0KDQojIyMgMi4gTWVtYmFjYSBwb2xhIGtyaW1pbmFsaXRhcyBzZWNhcmEga2VzZWx1cnVoYW4NCg0KR3VuYWthbiBoYXNpbCBNb3JhbuKAmXMgSSBkYW4gR2VhcnnigJlzIEMgdW50dWsgdmFyaWFiZWwgQ1JJTUUuDQoNCjEuIEJ1YXQgdGFiZWwgYmVyaXNpIG5hbWEgbWV0b2RlLCBuaWxhaSBzdGF0aXN0aWssIGRhbiBwLXZhbHVlLiBVbnR1ayBNb3JhbuKAmXMgSSwgZ3VuYWthbiBwLXZhbHVlIHBlcm11dGFzaS4NCjIuIFRlbnR1a2FuIGtlcHV0dXNhbiBwZW5ndWppYW4gbWFzaW5nLW1hc2luZyBtZXRvZGUgcGFkYSB0YXJhZiA1JS4NCjMuIEplbGFza2FuIGFwYWthaCBrZWR1YSBtZXRvZGUgbWVtYmVyaWthbiBrZXNpbXB1bGFuIHlhbmcgc2VqYWxhbi4NCjQuIEplbGFza2FuIG1lbmdhcGEgTW9yYW7igJlzIEkgeWFuZyBwb3NpdGlmIGRhbiBHZWFyeeKAmXMgQyB5YW5nIGt1cmFuZyBkYXJpIDEgZGFwYXQgbWVudW5qdWtrYW4gcG9sYSB5YW5nIHNhbWEuDQoNCioqSGFzaWwgeWFuZyBkaWt1bXB1bGthbjoqKiBzYXR1IHRhYmVsIHBlcmJhbmRpbmdhbiBkYW4gc2F0dSBwYXJhZ3JhZiBwZW5qZWxhc2FuLg0KDQojIyMgMy4gTWVuaWxhaSBwZW5nYXJ1aCBwZW55ZXN1YWlhbiBCSA0KDQpHdW5ha2FuIGhhc2lsICoqTG9jYWwgTW9yYW4gdW5pdmFyaWF0IHVudHVrIENSSU1FKiouDQoNCjEuIEhpdHVuZyBqdW1sYWggd2lsYXlhaCB5YW5nIHNpZ25pZmlrYW4gc2ViZWx1bSBkYW4gc2V0ZWxhaCBwZW55ZXN1YWlhbiBCSC4NCjIuIFNlYnV0a2FuIElEIGRhbiBrdWFkcmFuIHdpbGF5YWggeWFuZyB0ZXRhcCBzaWduaWZpa2FuIHNldGVsYWggcGVueWVzdWFpYW4uDQozLiBQaWxpaCBzYXR1IHdpbGF5YWggeWFuZyBzaWduaWZpa2FuIHNlYmVsdW0gcGVueWVzdWFpYW4sIHRldGFwaSB0aWRhayBsYWdpIHNpZ25pZmlrYW4gc2V0ZWxhaCBCSC4gVHVsaXNrYW4ga2VkdWEgcC12YWx1ZS1ueWEuDQo0LiBKZWxhc2thbiBtZW5nYXBhIHBlcnViYWhhbiBzdGF0dXMgdGVyc2VidXQgdGlkYWsgYmVyYXJ0aSBuaWxhaSBrcmltaW5hbGl0YXMgd2lsYXlhaG55YSBiZXJ1YmFoLg0KDQoqKkhhc2lsIHlhbmcgZGlrdW1wdWxrYW46KiogdGFiZWwgcmluZ2thcyBkYW4gaW50ZXJwcmV0YXNpIDPigJM0IGthbGltYXQuDQoNCiMjIyA0LiBNZW1iYW5kaW5na2FuIGR1YSBwb2xhIGxva2FsIGJpdmFyaWF0DQoNCkd1bmFrYW4gaGFzaWwgKipMb2NhbCBNb3JhbiBiaXZhcmlhdCBDUklNRSB0ZXJoYWRhcCBJTkMgdGV0YW5nZ2EqKiB1bnR1ayB3aWxheWFoICoqSUQgOCBkYW4gSUQgMzIqKi4NCg0KMS4gQnVhdCB0YWJlbCBiZXJpc2kgSUQsIENSSU1FLCBJTkMsIGBsYWdfSU5DYCwga3VhZHJhbiwgZGFuIHAtdmFsdWUgQkguDQoyLiBKZWxhc2thbiBhcnRpIGt1YWRyYW4gbWFzaW5nLW1hc2luZyB3aWxheWFoLg0KMy4gVGVudHVrYW4gYXBha2FoIHBvbGEga2VkdWFueWEgc2lnbmlmaWthbiBzZXRlbGFoIHBlbnllc3VhaWFuIEJILg0KNC4gSmVsYXNrYW4gbWVuZ2FwYSBwZW1iYWNhYW4gaHVydWYga2VkdWEgcGFkYSBrdWFkcmFuIG1lbmdndW5ha2FuIGBsYWdfSU5DYC4NCjUuIFR1bGlza2FuIHNhdHUga2VzaW1wdWxhbiB0ZW50YW5nIGh1YnVuZ2FuIGtyaW1pbmFsaXRhcyB3aWxheWFoIGRhbiBwZW5kYXBhdGFuIHRldGFuZ2dhbnlhIHRhbnBhIG1lbnlhdGFrYW4gaHVidW5nYW4gc2ViYWItYWtpYmF0Lg0KDQoqKkhhc2lsIHlhbmcgZGlrdW1wdWxrYW46Kiogc2F0dSB0YWJlbCBkYW4gc2F0dSBwYXJhZ3JhZiBwZXJiYW5kaW5nYW4uDQoNCiMjIyA1LiBNZW1lcmlrc2EgYXBha2FoIHBpbGloYW4gdGV0YW5nZ2EgbWVuZ3ViYWgga2VzaW1wdWxhbg0KDQpCZW50dWsga2V0ZXRhbmdnYWFuICoqUm9vayoqIGRlbmdhbiBtZW5nZ2FudGkgYHF1ZWVuID0gVFJVRWAgbWVuamFkaSBgcXVlZW4gPSBGQUxTRWAgcGFkYSBgcG9seTJuYigpYC4gQnVhdCBrZW1iYWxpIGJvYm90IGRlbmdhbiBgc3R5bGUgPSAiVyJgLg0KDQoxLiBQZXJpa3NhIGFwYWthaCBhZGEgd2lsYXlhaCB5YW5nIHRpZGFrIG1lbWlsaWtpIHRldGFuZ2dhLg0KMi4gQmFuZGluZ2thbiBqdW1sYWggcGFzYW5nYW4gdGV0YW5nZ2EgdW5payBhbnRhcmEgUXVlZW4gZGFuIFJvb2suDQozLiBIaXR1bmcga2VtYmFsaSBNb3JhbuKAmXMgSSBnbG9iYWwgdW50dWsgQ1JJTUUgbWVuZ2d1bmFrYW4gYm9ib3QgUm9vay4NCjQuIEphbGFua2FuIHVqaSBwZXJtdXRhc2kgZGVuZ2FuIGp1bWxhaCBwZW5nYWNha2FuIGRhbiBhcmFoIHBlbmd1amlhbiB5YW5nIHNhbWEgc2VwZXJ0aSBwYWRhIGJvYm90IFF1ZWVuLg0KNS4gQmFuZGluZ2thbiBuaWxhaSBpbmRla3MsIHAtdmFsdWUsIGRhbiBrZXNpbXB1bGFuIGtlZHVhIGJvYm90Lg0KDQoqKkhhc2lsIHlhbmcgZGlrdW1wdWxrYW46KiogdGFiZWwgcGVyYmFuZGluZ2FuIFF1ZWVu4oCTUm9vayBkYW4gamF3YWJhbiBzaW5na2F0OiAqQXBha2FoIGtlc2ltcHVsYW4gcG9sYSBrcmltaW5hbGl0YXMgdGV0YXAgc2FtYSBrZXRpa2EgZGVmaW5pc2kgdGV0YW5nZ2EgYmVydWJhaD8qDQoNCioqUGV0dW5qdWs6KiogZ3VuYWthbiBgY2FyZChuYilgIHVudHVrIG1lbmdoaXR1bmcganVtbGFoIHRldGFuZ2dhLiBKdW1sYWggcGFzYW5nYW4gdGV0YW5nZ2EgdW5payBkYXBhdCBkaWhpdHVuZyBkZW5nYW4gYHN1bShjYXJkKG5iKSkgLyAyYC4NCg0KIyMjIEtldGVudHVhbiBqYXdhYmFuDQoNClNlcnRha2FuIHNpbnRha3MgeWFuZyBkaWd1bmFrYW4gZGFuIG91dHB1dCB5YW5nIHJlbGV2YW4uIFNldGlhcCBpbnRlcnByZXRhc2kgcGVybHUgbWVueWVidXRrYW4gdmFyaWFiZWwsIHdpbGF5YWggYXRhdSBjYWt1cGFuIGFuYWxpc2lzLCBzZXJ0YSBidWt0aSB5YW5nIG1lbmR1a3VuZyBrZXNpbXB1bGFuLiBCZWRha2FuIGhhc2lsIHlhbmcgbWVuZ2dhbWJhcmthbiBzZWx1cnVoIHdpbGF5YWggZGVuZ2FuIGhhc2lsIHVudHVrIHdpbGF5YWggdGVydGVudHUuDQo=