Investment Data

Midterm Exam

Logo

(https://img.youtube.com/vi/QYlR7_F6clo/hqdefault.jpg)](https://youtu.be/QYlR7_F6clo)

1 Introduction

Keputusan investasi di era modern menjadi semakin kompleks karena dipengaruhi oleh berbagai faktor ekonomi dan pribadi, seperti usia, pendapatan, tujuan keuangan, dan toleransi risiko. Perbedaan ini menghasilkan variasi dalam imbal hasil, volatilitas, dan pertumbuhan aset.

Dataset ini mencakup variabel kategoris (seperti segmen investor, wilayah, dan jenis investasi) serta variabel numerik (jumlah investasi, skor risiko, diversifikasi portofolio, dan imbal hasil tahunan).

Melalui analisis statistik deskriptif—termasuk ukuran tendensi sentral dan dispersi—serta visualisasi data, dapat diperoleh gambaran yang lebih jelas mengenai pola, distribusi, dan kinerja investor secara keseluruhan.

2 Data preparation

library(readr)
library(DT)

data_investment5 <- read_csv("C:/Users/Adinda/Downloads/Midterm Exam3.csv")

datatable(
  data_investment5,
  options = list(pageLength = 10),  # tampil 10 baris per halaman
  caption = "Tabel Interaktif Data CSV"
)

3 Visualizations Data

3.1 Barchart

3.1.1 Interpretasi

Visualisasi di atas menunjukkan perbandingan jumlah investor pada setiap jenis investasi. Terlihat bahwa beberapa jenis investasi memiliki jumlah investor yang jauh lebih tinggi dibanding lainnya, menandakan adanya preferensi atau minat yang lebih besar terhadap jenis investasi tertentu.

dapat disimpulkan bahwa jenis investasi dengan jumlah investor tertinggi merupakan pilihan yang paling populer dan dianggap lebih aman atau menguntungkan oleh mayoritas responden, sedangkan jenis dengan jumlah investor paling sedikit mungkin memiliki risiko atau tingkat kepercayaan yang lebih rendah.

3.2 Histogram

3.2.1 Interpretasi

Histogram diatas menunjukkan distribusi usia para investor dalam dataset. Sebagian besar investor berada pada rentang usia produktif (sekitar 30–45 tahun), yang menandakan bahwa kelompok usia ini paling aktif dalam kegiatan investasi. Distribusi terlihat relatif normal, meskipun ada kemungkinan sedikit kemiringan (skewness) ke kanan yang menunjukkan sebagian kecil investor berusia lebih tua. Hal ini dapat diartikan bahwa partisipasi investasi cenderung menurun pada usia lanjut, sementara kelompok usia menengah mendominasi pasar karena memiliki kestabilan finansial dan minat investasi yang tinggi.

3.3 Scatter plot

library(ggplot2)
library(plotly)

# Scatter plot dengan garis tren
scatter_plot <- ggplot(data_investment5, aes(x = Age, y = AnnualReturn)) +
  geom_point(color = "#2E86AB", alpha = 0.7, size = 3) +  # Titik data
  geom_smooth(method = "lm", color = "lightpink", se = TRUE, linewidth = 1) +  # Garis tren linear
  theme_minimal() +
  labs(
    title = "Hubungan antara Usia Investor dan Tingkat Keuntungan Tahunan",
    x = "Usia Investor (Tahun)",
    y = "Keuntungan Tahunan (%)",
    caption = "Sumber data: Midterm Exam Investment Data"
  )

# Ubah plot interaktif
interactive_scatter <- ggplotly(scatter_plot)
interactive_scatter

3.3.1 Interpretasi

Visualisasi ini menunjukkan hubungan antara usia investor dan tingkat keuntungan tahunan (annual return). Titik-titik data menggambarkan sebaran nilai return di berbagai kelompok usia, sementara garis tren linear memperlihatkan arah hubungan umum di antara keduanya.

Dari grafik terlihat bahwa tidak ada hubungan linear yang kuat antara usia dan tingkat keuntungan tahunan — artinya, peningkatan usia tidak secara konsisten diikuti oleh peningkatan atau penurunan return. Sebaran titik yang cukup luas menunjukkan adanya variasi (dispersi) yang tinggi antarindividu, menandakan bahwa faktor lain selain usia (seperti pengalaman atau profil risiko) kemungkinan berpengaruh lebih besar terhadap hasil investasi.

3.4 Box plot

library(plotly)

p_box_soft <- plot_ly(
  data = data_investment5,
  x = ~RiskProfile,
  y = ~AnnualReturn,
  color = ~RiskProfile,
  type = "box",
  colors = c("#CDE8E5", "#E8DFF5", "#FDE2E4"),
  boxmean = TRUE,
  hoverinfo = "text",
  text = ~paste(
    "Risk Profile: ", RiskProfile,
    "<br>Annual Return: ", round(AnnualReturn, 2), "%"
  ),
  marker = list(outliercolor = '#9E9E9E', opacity = 0.7)
) %>%
  layout(
    title = list(
      text = "Distribusi Annual Return Berdasarkan Risk Profile",
      x = 0.5,
      font = list(size = 18, color = "#333333", family = "Arial Black")
    ),
    xaxis = list(title = "Risk Profile", titlefont = list(size = 14)),
    yaxis = list(title = "Annual Return (%)", titlefont = list(size = 14)),
    plot_bgcolor = "#FFFFFF",
    paper_bgcolor = "#FFFFFF",
    font = list(family = "Arial", color = "#444444")
  )

p_box_soft

3.4.1 Interpretasi

Visualisasi box plot ini menunjukkan perbedaan sebaran annual return berdasarkan kategori risk profile investor. Investor dengan profil risiko tinggi (High Risk) cenderung memiliki annual return yang lebih besar, namun dengan sebaran nilai yang juga lebih luas — menandakan variabilitas (dispersi) yang tinggi dan potensi risiko lebih besar. Sebaliknya, profil risiko rendah (Low Risk) menampilkan rentang nilai return yang sempit, mencerminkan stabilitas dan konsistensi hasil investasi. Profil risiko sedang (Moderate) berada di antara keduanya, menunjukkan keseimbangan antara risiko dan potensi imbal hasil.

3.5 Line chart

3.5.1 Interpretasi

Grafik menunjukkan bahwa semakin tinggi tingkat pengalaman investasi, semakin besar rata-rata Annual Return yang diperoleh investor. Tren garis yang meningkat menandakan adanya hubungan positif antara pengalaman dan kinerja investasi. Hal ini mengindikasikan bahwa pengalaman berperan penting dalam kemampuan investor mengelola risiko dan memaksimalkan keuntungan.

Tidak terlihat adanya outlier atau fluktuasi ekstrem, yang berarti data relatif konsisten dan stabil di setiap tingkat pengalaman. Dengan demikian, variabel InvestmentExperience dapat dianggap memiliki pengaruh yang signifikan terhadap AnnualReturn, serta memperlihatkan pola distribusi yang proporsional dan mudah diinterpretasikan secara visual.

4 Central Tendency

Analisis ini dilakukan untuk memahami ukuran pemusatan data dari dua variabel numerik, yaitu Age (usia investor) dan AnnualReturn (persentase hasil investasi tahunan). Kedua variabel ini dipilih karena:

  • Age menggambarkan faktor demografis investor yang bersifat stabil dan kontinu.

  • AnnualReturn menunjukkan performa investasi yang bisa mencerminkan variasi tingkat risiko dan keuntungan.

Dengan menghitung mean, median, dan mode, kita dapat mengidentifikasi apakah distribusi data bersifat simetris, miring ke kanan (right-skewed), atau miring ke kiri (left-skewed).

Ukuran pemusatan data yang digunakan terdiri dari tiga jenis utama:

- Mean (Rata-rata)

Rumus:
\[ \mathbf{Mean} = \frac{\sum x_i}{n} \]

Keterangan:

  • \(x_i\) = nilai ke-i dari data
  • \(n\) = jumlah total data

Artinya, semua nilai dijumlahkan lalu dibagi dengan jumlah data.

- Median (Nilai Tengah)

Median adalah nilai yang berada di tengah setelah data diurutkan dari yang terkecil ke terbesar.
Jika jumlah data ganjil, median = nilai di posisi tengah.
Jika jumlah data genap, median = rata-rata dari dua nilai tengah.

- Mode (Modus)

Mode adalah nilai yang paling sering muncul dalam suatu kumpulan data.
Jika hanya ada satu nilai yang sering muncul → unimodal,
jika dua nilai → bimodal,
dan jika lebih dari dua → multimodal.

4.1 Perhitungan (mean, meadian, mode)

# --- Library yang digunakan ---
library(readr)
library(dplyr)
library(ggplot2)

# --- Membaca dataset ---
data_investment5 <- read_csv("C:/Users/Adinda/Downloads/Midterm Exam3.csv")

# --- Menghitung Mean, Median, dan Mode untuk dua variabel numerik ---
# Variabel 1: Age
mean_age <- mean(data_investment5$Age, na.rm = TRUE)
median_age <- median(data_investment5$Age, na.rm = TRUE)
mode_age <- as.numeric(names(sort(table(data_investment5$Age), decreasing = TRUE)[1]))

# --- Menyusun hasil perhitungan ke dalam tabel ---
tabel_central <- data.frame(
  Variable = c("Age"),
  Mean = c(mean_age),
  Median = c(median_age),
  Mode = c(mode_age)
)

# --- Menampilkan tabel hasil ---
tabel_central

4.2 Interpretasi Hasil Perhitungan (mean, median, mode)

  • Age: Nilai mean, median, dan mode saling berdekatan → distribusi data simetris.

  • AnnualReturn: Mean lebih tinggi dari median dan mode → distribusi miring ke kanan (right-skewed), menandakan ada beberapa investor dengan hasil sangat tinggi.

library(ggplot2)
# --- Symmetrical data: Perfect bell-shaped (Normal Distribution, no outliers) ---
set.seed(123)

data_investment5 <- data.frame(age = rnorm(200, mean = 50, sd = 10))
# --- Compute Mean, Median, Mode ---
mean_val <- mean(data_investment5$age)
median_val <- median(data_investment5$age)
mode_val <- as.numeric(names(sort(table(round(data_investment5$age, 0)),
                                  decreasing = TRUE)[1]))
# --- Visualization (Histogram + Density) ---
ggplot(data_investment5, aes(x = age)) +
  geom_histogram(aes(y = after_stat(density)), 
                 binwidth = 2, 
                 fill = "#5ab4ac", 
                 color = "white", 
                 alpha = 0.8) +
  geom_density(color = "#2b8cbe", linewidth = 1.3, alpha = 0.9) +
  geom_vline(aes(xintercept = mean_val, color = "Mean"), linewidth = 1.2) +
  geom_vline(aes(xintercept = median_val, color = "Median"), 
             linewidth = 1.2, linetype = "dashed") +
  geom_vline(aes(xintercept = mode_val, color = "Mode"), 
             linewidth = 1.2, linetype = "dotdash") +
  labs(
    title = "Symmetrical Distribution (No Outliers)",
    subtitle = "Mean, Median, and Mode coincide at the center of the bell curve",
    x = "age",
    y = "Density",
    color = "Measure"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(face = "bold", hjust = 0.5),
    plot.subtitle = element_text(hjust = 0.5),
    legend.position = "bottom"
  )

4.2.1 Interpretasi age

Distribusi data pada variabel Age menunjukkan pola simetris berbentuk lonceng (bell curve), di mana garis Mean, Median, dan Mode berada di posisi yang hampir sama di tengah distribusi. Hal ini menandakan bahwa sebagian besar individu memiliki nilai usia yang berada di sekitar rata-rata, dengan jumlah yang seimbang antara nilai di bawah dan di atas rata-rata.

Karena ketiga ukuran tendensi sentral tersebut berimpit, maka tidak terdapat kemiringan (skewness) yang berarti pada data ini. Dengan kata lain, distribusi tidak miring ke kanan maupun ke kiri. Visualisasi ini juga memperlihatkan tidak adanya outlier yang ekstrem, yang berarti penyebaran usia cenderung stabil.

# --- Library yang dibutuhkan ---
library(readr)
library(dplyr)
library(ggplot2)
library(gridExtra)

# --- Membaca data ---
data_investment5 <- read_csv("C:/Users/Adinda/Downloads/Midterm Exam3.csv")

# --- Menghitung nilai Mean, Median, Mode untuk AnnualReturn ---
mean_ret <- mean(data_investment5$AnnualReturn, na.rm = TRUE)
median_ret <- median(data_investment5$AnnualReturn, na.rm = TRUE)
mode_ret <- as.numeric(names(sort(table(data_investment5$AnnualReturn), decreasing = TRUE)[1]))

# --- Menampilkan hasil perhitungan dalam tabel ---
central_tendency <- data.frame(
  Measure = c("Mean", "Median", "Mode"),
  AnnualReturn = c(mean_ret, median_ret, mode_ret)
)
central_tendency
# --- Membuat Visualisasi Histogram + Density Plot ---
ggplot(data_investment5, aes(x = AnnualReturn)) +
  geom_histogram(aes(y = after_stat(density)),
                 bins = 30,
                 fill = "#5ab4ac",
                 color = "white",
                 alpha = 0.8) +
  geom_density(color = "#2b8cbe", linewidth = 1.3, alpha = 0.9) +
  geom_vline(aes(xintercept = mean_ret, color = "Mean"), linewidth = 1.2) +
  geom_vline(aes(xintercept = median_ret, color = "Median"), linetype = "dashed", linewidth = 1.2) +
  geom_vline(aes(xintercept = mode_ret, color = "Mode"), linetype = "dotdash", linewidth = 1.2) +
  labs(
    title = "Distribusi Annual Return",
    subtitle = "Visualisasi Mean, Median, dan Mode pada Variabel Annual Return",
    x = "Annual Return",
    y = "Density",
    color = "white"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(face = "bold", hjust = 0.5),
    plot.subtitle = element_text(hjust = 0.5),
    legend.position = "bottom"
  )

4.2.2 Interpretasi

Nilai mean, median, dan mode pada variabel Annual Return hampir sama, menunjukkan bahwa data memiliki distribusi simetris tanpa kemencengan berarti. Grafik histogram membentuk pola kurva lonceng, di mana sebagian besar data terkonsentrasi di sekitar nilai tengah. Hal ini menandakan bahwa Annual Return memiliki sebaran yang normal dan stabil, tanpa adanya outlier yang signifikan.

5 Measures of Dispersion

Bagian ini bertujuan untuk mengukur sebaran (dispersi) dari data numerik dalam dataset. Ukuran penyebaran membantu kita memahami seberapa jauh data menyebar dari nilai rata-ratanya. Dua variabel yang digunakan:

  • Age (Usia Investor)

  • AnnualReturn (Persentase Keuntungan Tahunan)

Ukuran-ukuran penyebaran meliputi:

- Range (Jangkauan)
\[ \textbf{Range} = X_{max} - X_{min} \] # Menghitung range

range_age <- max(data_investment5$Age, na.rm = TRUE) - min(data_investment5$Age, na.rm = TRUE)
range_return <- max(data_investment5$AnnualReturn, na.rm = TRUE) - min(data_investment5$AnnualReturn, na.rm = TRUE)

data.frame(
  Variable = c("Age", "Annual Return"),
  Range = c(range_age, range_return)
)

Range menunjukkan perbedaan antara nilai terbesar dan nilai terkecil dalam data.
Semakin besar nilai range, semakin lebar pula sebaran data.
Namun, ukuran ini sensitif terhadap outlier, sehingga tidak selalu mencerminkan distribusi sebenarnya. Sedangkan pada perhitungan rage di atas menunjukan Range jarak antara nilai tertinggi dan terendah dalam data. Nilai yang besar menandakan adanya variasi ekstrem, sedangkan nilai kecil berarti data relatif homogen.

Berdasarkan hasil perhitungan range menunjukkan selisih antara nilai maksimum dan minimum pada suatu variabel.

  • Untuk Age, range yang relatif kecil mengindikasikan bahwa rentang usia responden tidak terlalu lebar, artinya mayoritas investor memiliki usia yang berdekatan.

  • Untuk Annual Return, range yang jauh lebih besar menunjukkan adanya perbedaan signifikan antara tingkat pengembalian investasi tertinggi dan terendah di antara responden.

- Variance (Ragam)
\[ \textbf{s}^2 = \frac{\sum_{i=1}^{n}(X_i - \bar{X})^2}{n - 1} \]

# Menghitung varians

var_age <- var(data_investment5$Age, na.rm = TRUE)
var_return <- var(data_investment5$AnnualReturn, na.rm = TRUE)

data.frame(
Variable = c("Age", "Annual Return"),
Variance = c(var_age, var_return)
)

Variance mengukur rata-rata kuadrat deviasi setiap nilai terhadap mean.
Nilai variansi besar berarti data memiliki keragaman tinggi, sedangkan nilai kecil menunjukkan bahwa data berkumpul di sekitar mean.
Satuan variansi adalah kuadrat dari satuan data aslinya.

Berdasarkan hasil perhitungan varians:

  • Variabel Age memiliki nilai varians yang relatif kecil, artinya sebaran umur responden cukup seragam. Mayoritas responden berada dalam rentang usia yang tidak terlalu jauh.

  • Variabel Annual Return memiliki nilai varians yang jauh lebih besar, menandakan bahwa tingkat pengembalian investasi antar responden bervariasi cukup tinggi. Beberapa investor mungkin memperoleh hasil yang jauh lebih tinggi atau rendah dibanding rata-rata.

Dengan kata lain, semakin besar nilai varians, semakin tinggi tingkat ketidakkonsistenan data. Dalam konteks ini, Annual Return memiliki tingkat fluktuasi yang lebih besar dibanding Age.

- Standard Deviation (Simpangan Baku)
\[ \textbf{s} = \sqrt{s^2} = \sqrt{\frac{\sum_{i=1}^{n}(X_i - \bar{X})^2}{n - 1}} \]

# Menghitung standar deviasi

sd_age <- sd(data_investment5$Age, na.rm = TRUE)
sd_return <- sd(data_investment5$AnnualReturn, na.rm = TRUE)

data.frame(
Variable = c("Age", "Annual Return"),
Standard_Deviation = c(sd_age, sd_return)
)

Standard deviation merupakan akar dari variansi, sehingga kembali pada satuan data aslinya.
Nilai simpangan baku menunjukkan seberapa jauh data tersebar dari nilai rata-rata.
Jika standar deviasi kecil, maka data lebih homogen; jika besar, maka data lebih bervariasi.

Berdasarkan hasil perhitungan Standar Deviation

  • Nilai standar deviasi Age kecil → menunjukkan bahwa sebagian besar nilai umur mendekati rata-rata.

  • Nilai standar deviasi Annual Return besar → menggambarkan bahwa tingkat pengembalian memiliki penyimpangan yang besar dari rata-ratanya.

- Interquartile Range (IQR)
\[ \textbf{IQR} = Q_3 - Q_1 \]

# Menghitung IQR

iqr_age <- IQR(data_investment5$Age, na.rm = TRUE)
iqr_return <- IQR(data_investment5$AnnualReturn, na.rm = TRUE)

data.frame(
Variable = c("Age", "Annual Return"),
IQR = c(iqr_age, iqr_return)
)

IQR mengukur rentang data tengah (50%) dengan mengabaikan pengaruh outlier.
IQR berguna untuk melihat penyebaran data utama tanpa dipengaruhi nilai ekstrem.

Berdasarkan hasil perhitungan IQR

  • IQR Age kecil → data usia lebih konsisten di tengah distribusi.

  • IQR Annual Return besar → menandakan bahwa nilai pengembalian memiliki variasi tinggi meskipun di bagian tengah data.

5.1 Visualisasi Measures of Dispersion

5.1.1 Box plot

5.1.2 Interpretasi

Visualisasi box plot menunjukkan bahwa InitialInvestment memiliki penyebaran (dispersi) yang lebih besar dibanding AnnualReturn. Hal ini terlihat dari rentang dan IQR yang lebih lebar serta adanya beberapa outlier pada nilai investasi awal, menandakan perbedaan modal antar investor cukup tinggi. Sementara itu, AnnualReturn memiliki sebaran yang lebih sempit dan sedikit outlier, menunjukkan hasil tahunan antar investor relatif stabil. Dengan demikian, dapat disimpulkan bahwa modal awal bervariasi tinggi, sedangkan hasil tahunan lebih konsisten, sesuai dengan konsep Measures of Dispersion yang menekankan variasi dan kestabilan data.

5.1.3 Histogram

5.1.4 Interpretasi

Visualisasi histogram di atas memperlihatkan sebaran dua variabel numerik, yaitu Monthly Saving dan Annual Return, untuk memahami pola distribusi dan tingkat penyebaran datanya.

  • Pada histogram Monthly Saving, terlihat bahwa sebagian besar investor memiliki jumlah tabungan bulanan pada kisaran menengah. Distribusi ini menunjukkan bahwa data cenderung simetris dengan sedikit variasi di sekitar nilai tengah, yang berarti tingkat kemampuan menabung antar investor relatif seragam dan tidak terlalu menyimpang jauh.

  • Sementara itu, histogram Annual Return menunjukkan bahwa sebagian besar imbal hasil tahunan berkumpul di sekitar nilai rata-rata dengan sedikit nilai ekstrem (outlier) di sisi kanan. Hal ini mengindikasikan adanya beberapa investor dengan tingkat pengembalian yang jauh lebih tinggi dibanding lainnya, menandakan penyebaran data yang lebih besar pada variabel ini dibanding Monthly Saving.

Secara keseluruhan, hasil ini menunjukkan bahwa Annual Return memiliki variasi yang lebih tinggi, sedangkan Monthly Saving lebih konsisten, yang berarti risiko dan hasil investasi berbeda antar individu, tetapi kemampuan menabung relatif stabil.

5.1.5 Scatter plot

library(plotly)
library(dplyr)

# Gunakan dataset yang benar
data_investment <- data_investment %>%
  mutate(
    RiskScore = as.numeric(RiskScore),
    AnnualReturn = as.numeric(AnnualReturn)
  )

# Fit model regresi linear
model <- lm(AnnualReturn ~ RiskScore, data = data_investment)

# Prediksi nilai untuk garis tren
pred <- data.frame(
  RiskScore = seq(min(data_investment$RiskScore, na.rm = TRUE),
                  max(data_investment$RiskScore, na.rm = TRUE),
                  length.out = 100)
)
pred$AnnualReturn <- predict(model, newdata = pred)

# Scatter plot interaktif + garis tren
fig <- plot_ly(
  data = data_investment,
  x = ~RiskScore,
  y = ~AnnualReturn,
  type = 'scatter',
  mode = 'markers',
  marker = list(color = 'lightpink', size = 8, opacity = 0.7),
  hoverinfo = 'text',
  text = ~paste('Risk Score:', RiskScore,
                '<br>Annual Return:', AnnualReturn)
) %>%
  add_trace(
    data = pred,
    x = ~RiskScore,
    y = ~AnnualReturn,
    type = 'scatter',
    mode = 'lines',
    line = list(color = 'darkred', width = 2),
    name = 'Trend Line'
  ) %>%
  layout(
    title = list(text = "Hubungan antara Risk Score dan Annual Return (dengan Garis Tren)", x = 0.5),
    xaxis = list(title = "Risk Score"),
    yaxis = list(title = "Annual Return (%)"),
    plot_bgcolor = "#f7f9fb",
    paper_bgcolor = "#f7f9fb"
  )

fig  # tampilkan grafik interaktif

5.1.6 Interpretasi

Scatter plot menunjukkan hubungan positif antara Risk Score dan Annual Return. Pola ini mengindikasikan bahwa semakin tinggi risiko yang diambil, semakin besar potensi imbal hasilnya. Sebaran titik yang cukup luas menandakan adanya variasi atau dispersi tinggi pada hasil investasi.

6 Summary and Interpretation

Berdasarkan hasil analisis data investasi, diperoleh bahwa variabel numerik yang dianalisis, yaitu Age dan Annual Return, menunjukkan karakteristik penyebaran yang berbeda.

  • Variabel Age memiliki nilai rata-rata, median, dan modus yang berdekatan, menandakan distribusi yang relatif simetris tanpa adanya outlier yang signifikan. Hal ini juga didukung oleh nilai varians, standar deviasi, dan IQR yang kecil, sehingga dapat disimpulkan bahwa data usia investor cukup konsisten dan homogen.

  • Sebaliknya, variabel Annual Return memiliki perbedaan cukup besar antara nilai rata-rata dan median, yang mengindikasikan adanya kemencengan (skewness) pada distribusi data. Nilai dispersi yang tinggi menunjukkan bahwa tingkat pengembalian investasi antar investor sangat bervariasi. Kondisi ini dapat disebabkan oleh perbedaan strategi, tingkat risiko, dan pengalaman investasi.

Secara keseluruhan, hasil visualisasi dan analisis statistik menggambarkan bahwa Age merupakan variabel yang paling stabil, sedangkan Annual Return menunjukkan variabilitas paling tinggi. Hal ini memberikan gambaran bahwa kinerja investasi lebih dipengaruhi oleh faktor eksternal dibandingkan faktor demografis seperti usia.

LS0tDQp0aXRsZTogIkludmVzdG1lbnQgRGF0YSIgIyBNYWluIHRpdGxlIG9mIHRoZSBkb2N1bWVudA0Kc3VidGl0bGU6ICJNaWR0ZXJtIEV4YW0iICMgU3VidGl0bGUgb3IgdG9waWMgZm9yIHdlZWsgMg0KYXV0aG9yOiANCi0gIkFkaW5kYSBBZGVsaWEgZnV0cmkiDQotICJBZGluZGEgTWFpemEgaXNoZmFoYW5pIiANCi0gIkNocmljeWVzaWEgVy5GLlV2YXMiDQotICJKYW51YXJpYSBUZXJlc2luaGEiIA0KLSAiT2N0YXZpYSBNYWlhIFJlZ28iICAgICAgICAgICMgUmVwbGFjZSB3aXRoIHlvdXIgZnVsbCBuYW1lDQpkYXRlOiAgImByIGZvcm1hdChTeXMuRGF0ZSgpLCAnJUIgJWQsICVZJylgIiAjIEF1dG8gZGlzcGxheXMgdGhlIGN1cnJlbnQgZGF0ZQ0Kb3V0cHV0OiAgICAgICAgICAgICAgICAgICAgICAgICAjIE91dHB1dCBzZWN0aW9uIGRlZmluZXMgdGhlIGZvcm1hdCBhbmQgbGF5b3V0IA0KICBybWRmb3JtYXRzOjpyZWFkdGhlZG93bjogICAgICAjIGh0dHBzOi8vZ2l0aHViLmNvbS9qdWJhL3JtZGZvcm1hdHMNCiAgICBzZWxmX2NvbnRhaW5lZDogdHJ1ZSAgICAgICAgIyBFbWJlZHMgYWxsIHJlc291cmNlcyAoQ1NTLCBKUywgaW1hZ2VzKSANCiAgICB0aHVtYm5haWxzOiB0cnVlICAgICAgICAgICAgIyBEaXNwbGF5cyBpbWFnZSB0aHVtYm5haWxzIGluIHRoZSBkb2MNCiAgICBsaWdodGJveDogdHJ1ZSAgICAgICAgICAgICAgIyBFbmFibGVzIGNsaWNrIHRvIGVubGFyZ2UgaW1hZ2VzDQogICAgZ2FsbGVyeTogdHJ1ZSAgICAgICAgICAgICAgICMgR3JvdXBzIGltYWdlcyBpbnRvIGFuIGludGVyYWN0aXZlIGdhbGxlcnkNCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUgICAgICAgIyBBdXRvbWF0aWNhbGx5IG51bWJlcnMgYWxsIHNlY3Rpb25zDQogICAgbGliX2RpcjogbGlicyAgICAgICAgICAgICAgICMgRGlyZWN0b3J5IHdoZXJlIEphdmFTY3JpcHQvQ1NTIGxpYnJhcmllcw0KICAgIGRmX3ByaW50OiAicGFnZWQiICAgICAgICAgICAjIERpc3BsYXlzIGRhdGEgZnJhbWVzIGFzIGludGVyYWN0aXZlIHBhZ2VkIA0KICAgIGNvZGVfZm9sZGluZzogInNob3ciICAgICAgICAjIEFsbG93cyBmb2xkaW5nL3VuZm9sZGluZyBSIGNvZGUgYmxvY2tzIA0KICAgIGNvZGVfZG93bmxvYWQ6IHllcyAgICAgICAgICAjIEFkZHMgYSBidXR0b24gdG8gZG93bmxvYWQgYWxsIFIgY29kZQ0KLS0tDQo8aW1nIGlkPSJGb3RvIiBzcmM9Imh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9hZGluZGFhZGVsaWFmdXRyaTYtZ2lmL2tlbG9tcG9rc3RhdGlzdGlrNS9tYWluL2tlbG9tcG9rNS5qcGVnIiBhbHQ9IkxvZ28iIHN0eWxlPSJ3aWR0aDoyMDBweDsgZGlzcGxheTogYmxvY2s7IG1hcmdpbjogYXV0bzsiPg0KDQoNCjxjZW50ZXI+PGlmcmFtZSB3aWR0aD0iNzAwIiBoZWlnaHQ9IjQwMCIgc3JjPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9lbWJlZC9RWWxSN19GNmNsbyIgZnJhbWVib3JkZXI9IjAiIGFsbG93ZnVsbHNjcmVlbj48L2lmcmFtZT48L2NlbnRlcj4NCg0KKGh0dHBzOi8vaW1nLnlvdXR1YmUuY29tL3ZpL1FZbFI3X0Y2Y2xvL2hxZGVmYXVsdC5qcGcpXShodHRwczovL3lvdXR1LmJlL1FZbFI3X0Y2Y2xvKQ0KDQoNCiMgSW50cm9kdWN0aW9uDQpLZXB1dHVzYW4gaW52ZXN0YXNpIGRpIGVyYSBtb2Rlcm4gbWVuamFkaSBzZW1ha2luIGtvbXBsZWtzIGthcmVuYSBkaXBlbmdhcnVoaSBvbGVoIGJlcmJhZ2FpIGZha3RvciBla29ub21pIGRhbiBwcmliYWRpLCBzZXBlcnRpIHVzaWEsIHBlbmRhcGF0YW4sIHR1anVhbiBrZXVhbmdhbiwgZGFuIHRvbGVyYW5zaSByaXNpa28uIFBlcmJlZGFhbiBpbmkgbWVuZ2hhc2lsa2FuIHZhcmlhc2kgZGFsYW0gaW1iYWwgaGFzaWwsIHZvbGF0aWxpdGFzLCBkYW4gcGVydHVtYnVoYW4gYXNldC4NCg0KRGF0YXNldCBpbmkgbWVuY2FrdXAgdmFyaWFiZWwga2F0ZWdvcmlzIChzZXBlcnRpIHNlZ21lbiBpbnZlc3Rvciwgd2lsYXlhaCwgZGFuIGplbmlzIGludmVzdGFzaSkgc2VydGEgdmFyaWFiZWwgbnVtZXJpayAoanVtbGFoIGludmVzdGFzaSwgc2tvciByaXNpa28sIGRpdmVyc2lmaWthc2kgcG9ydG9mb2xpbywgZGFuIGltYmFsIGhhc2lsIHRhaHVuYW4pLg0KDQpNZWxhbHVpIGFuYWxpc2lzIHN0YXRpc3RpayBkZXNrcmlwdGlm4oCUdGVybWFzdWsgdWt1cmFuIHRlbmRlbnNpIHNlbnRyYWwgZGFuIGRpc3BlcnNp4oCUc2VydGEgdmlzdWFsaXNhc2kgZGF0YSwgZGFwYXQgZGlwZXJvbGVoIGdhbWJhcmFuIHlhbmcgbGViaWggamVsYXMgbWVuZ2VuYWkgcG9sYSwgZGlzdHJpYnVzaSwgZGFuIGtpbmVyamEgaW52ZXN0b3Igc2VjYXJhIGtlc2VsdXJ1aGFuLg0KDQoNCiMgRGF0YSBwcmVwYXJhdGlvbg0KYGBge3IgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0V9DQpsaWJyYXJ5KHJlYWRyKQ0KbGlicmFyeShEVCkNCg0KZGF0YV9pbnZlc3RtZW50NSA8LSByZWFkX2NzdigiQzovVXNlcnMvQWRpbmRhL0Rvd25sb2Fkcy9NaWR0ZXJtIEV4YW0zLmNzdiIpDQoNCmRhdGF0YWJsZSgNCiAgZGF0YV9pbnZlc3RtZW50NSwNCiAgb3B0aW9ucyA9IGxpc3QocGFnZUxlbmd0aCA9IDEwKSwgICMgdGFtcGlsIDEwIGJhcmlzIHBlciBoYWxhbWFuDQogIGNhcHRpb24gPSAiVGFiZWwgSW50ZXJha3RpZiBEYXRhIENTViINCikNCg0KYGBgDQoNCiMgVmlzdWFsaXphdGlvbnMgRGF0YQ0KIyMgQmFyY2hhcnQNCg0KYGBge3IgaW52ZXN0bWVudC10eXBlLWludGVyYWN0aXZlLXNvZnQsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9NH0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHBsb3RseSkNCg0KIyBIaXR1bmcgZnJla3VlbnNpIGplbmlzIGludmVzdGFzaSBkYW4gdXJ1dGthbiBkYXJpIHRlcmJhbnlhayBrZSB0ZXJrZWNpbA0KaW52ZXN0bWVudF9jb3VudHMgPC0gZGF0YV9pbnZlc3RtZW50NSAlPiUNCiAgY291bnQoSW52ZXN0bWVudFR5cGUpICU+JQ0KICBhcnJhbmdlKGRlc2MobikpDQoNCiMgQnVhdCBncmFmaWsgYmF0YW5nIGRlbmdhbiB3YXJuYSBncmFkYXNpIGJpcnUtdG9za2EgbGVtYnV0DQpwIDwtIGdncGxvdChpbnZlc3RtZW50X2NvdW50cywgYWVzKA0KICB4ID0gcmVvcmRlcihJbnZlc3RtZW50VHlwZSwgLW4pLA0KICB5ID0gbiwNCiAgZmlsbCA9IG4sDQogIHRleHQgPSBwYXN0ZTAoDQogICAgIjxiPkplbmlzIEludmVzdGFzaTo8L2I+ICIsIEludmVzdG1lbnRUeXBlLA0KICAgICI8YnI+PGI+SnVtbGFoIEludmVzdG9yOjwvYj4gIiwgbg0KICApDQopKSArDQogIGdlb21fY29sKHdpZHRoID0gMC43LCBjb2xvciA9ICJ3aGl0ZSIsIGFscGhhID0gMC45NSkgKw0KICBzY2FsZV9maWxsX2dyYWRpZW50KA0KICAgIGxvdyA9ICIjQTlDQ0UzIiwgICMgYmlydSBtdWRhIGxlbWJ1dA0KICAgIGhpZ2ggPSAiIzI4NzRBNiIsICMgYmlydSB0ZWdhcyB0YXBpIHRldGFwIHNvZnQNCiAgICBndWlkZSA9ICJub25lIiAgICAjIGxlZ2VuZCBkaWhhcHVzIHRvdGFsDQogICkgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIkRpc3RyaWJ1c2kgSnVtbGFoIEludmVzdG9yIEJlcmRhc2Fya2FuIEplbmlzIEludmVzdGFzaSIsDQogICAgeCA9ICJKZW5pcyBJbnZlc3Rhc2kiLA0KICAgIHkgPSAiSnVtbGFoIEludmVzdG9yIg0KICApICsNCiAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAxMykgKw0KICB0aGVtZSgNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIGhqdXN0ID0gMC41LCBzaXplID0gMTYpLA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgc2l6ZSA9IDExKSwNCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAuNSksDQogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgIHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKDIwLCAyMCwgMjAsIDIwKQ0KICApDQoNCiMgVWJhaCBrZSBiZW50dWsgaW50ZXJha3RpZiAoem9vbSArIHRvb2x0aXApDQpnZ3Bsb3RseShwLCB0b29sdGlwID0gInRleHQiKQ0KYGBgDQoNCiMjIyBJbnRlcnByZXRhc2kNClZpc3VhbGlzYXNpIGRpIGF0YXMgbWVudW5qdWtrYW4gcGVyYmFuZGluZ2FuIGp1bWxhaCBpbnZlc3RvciBwYWRhIHNldGlhcCBqZW5pcyBpbnZlc3Rhc2kuIFRlcmxpaGF0IGJhaHdhIGJlYmVyYXBhIGplbmlzIGludmVzdGFzaSBtZW1pbGlraSBqdW1sYWggaW52ZXN0b3IgeWFuZyBqYXVoIGxlYmloIHRpbmdnaSBkaWJhbmRpbmcgbGFpbm55YSwgbWVuYW5kYWthbiBhZGFueWEgcHJlZmVyZW5zaSBhdGF1IG1pbmF0IHlhbmcgbGViaWggYmVzYXIgdGVyaGFkYXAgamVuaXMgaW52ZXN0YXNpIHRlcnRlbnR1Lg0KDQpkYXBhdCBkaXNpbXB1bGthbiBiYWh3YSBqZW5pcyBpbnZlc3Rhc2kgZGVuZ2FuIGp1bWxhaCBpbnZlc3RvciB0ZXJ0aW5nZ2kgbWVydXBha2FuIHBpbGloYW4geWFuZyBwYWxpbmcgcG9wdWxlciBkYW4gZGlhbmdnYXAgbGViaWggYW1hbiBhdGF1IG1lbmd1bnR1bmdrYW4gb2xlaCBtYXlvcml0YXMgcmVzcG9uZGVuLCBzZWRhbmdrYW4gamVuaXMgZGVuZ2FuIGp1bWxhaCBpbnZlc3RvciBwYWxpbmcgc2VkaWtpdCBtdW5na2luIG1lbWlsaWtpIHJpc2lrbyBhdGF1IHRpbmdrYXQga2VwZXJjYXlhYW4geWFuZyBsZWJpaCByZW5kYWguDQoNCiMjIEhpc3RvZ3JhbQ0KYGBge3IgaGlzdG9ncmFtLWFnZS1ncm91cGVkLWludGVyYWN0aXZlLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9DQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShwbG90bHkpDQoNCiMgUGFzdGlrYW4ga29sb20gYWdlIG51bWVyaWsNCg0KZGF0YV9pbnZlc3RtZW50NSA8LSBkYXRhX2ludmVzdG1lbnQ1ICU+JQ0KbXV0YXRlKEFnZSA9IGFzLm51bWVyaWMoQWdlKSkgICMgZGlzZXN1YWlrYW4NCg0KIyBLZWxvbXBva2thbiB1c2lhIGRhbGFtIGludGVydmFsDQoNCmRhdGFfaW52ZXN0bWVudDUgPC0gZGF0YV9pbnZlc3RtZW50NSAlPiUNCm11dGF0ZShBZ2VHcm91cCA9IGN1dCgNCkFnZSwNCmJyZWFrcyA9IHNlcSgyMCwgNzAsIGJ5ID0gMTApLA0KbGFiZWxzID0gYygiMjDigJMyOSIsICIzMOKAkzM5IiwgIjQw4oCTNDkiLCAiNTDigJM1OSIsICI2MOKAkzY5IiksDQpyaWdodCA9IEZBTFNFDQopKQ0KDQojIEhpdHVuZyBmcmVrdWVuc2kgZGFuIHVydXRrYW4NCg0KYWdlX2dyb3VwX2ZyZXEgPC0gZGF0YV9pbnZlc3RtZW50NSAlPiUNCmNvdW50KEFnZUdyb3VwKSAlPiUNCmFycmFuZ2UoZGVzYyhuKSkNCg0KIyBQbG90IGJhdGFuZyB1cnV0ICsgdG9vbHRpcCBpbnRlcmFrdGlmDQoNCnAgPC0gZ2dwbG90KGFnZV9ncm91cF9mcmVxLCBhZXMoDQp4ID0gcmVvcmRlcihBZ2VHcm91cCwgLW4pLA0KeSA9IG4sDQp0ZXh0ID0gcGFzdGUoDQoiS2Vsb21wb2sgVXNpYToiLCBBZ2VHcm91cCwNCiI8YnI+SnVtbGFoIEludmVzdG9yOiIsIG4NCikNCikpICsNCmdlb21fY29sKA0KZmlsbCA9ICIjQUVENkYxIiwNCmNvbG9yID0gIndoaXRlIiwNCndpZHRoID0gMC42NSwNCmFscGhhID0gMC45NQ0KKSArDQpsYWJzKA0KdGl0bGUgPSAiRGlzdHJpYnVzaSBLZWxvbXBvayBVc2lhIEludmVzdG9yIiwNCnggPSAiS2Vsb21wb2sgVXNpYSAoVGFodW4pIiwNCnkgPSAiRnJla3VlbnNpIg0KKSArDQp0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDEzKSArDQp0aGVtZSgNCnBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIHNpemUgPSAxNSwgZmFjZSA9ICJib2xkIiksDQpheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQpheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCnBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwNCnBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkNCikNCg0KIyBKYWRpa2FuIGludGVyYWt0aWYNCg0KZ2dwbG90bHkocCwgdG9vbHRpcCA9ICJ0ZXh0IikgJT4lDQpsYXlvdXQoZHJhZ21vZGUgPSAiem9vbSIpDQoNCmBgYA0KDQojIyMgSW50ZXJwcmV0YXNpDQpIaXN0b2dyYW0gZGlhdGFzIG1lbnVuanVra2FuIGRpc3RyaWJ1c2kgdXNpYSBwYXJhIGludmVzdG9yIGRhbGFtIGRhdGFzZXQuDQpTZWJhZ2lhbiBiZXNhciBpbnZlc3RvciBiZXJhZGEgcGFkYSByZW50YW5nIHVzaWEgcHJvZHVrdGlmIChzZWtpdGFyIDMw4oCTNDUgdGFodW4pLCB5YW5nIG1lbmFuZGFrYW4gYmFod2Ega2Vsb21wb2sgdXNpYSBpbmkgcGFsaW5nIGFrdGlmIGRhbGFtIGtlZ2lhdGFuIGludmVzdGFzaS4NCkRpc3RyaWJ1c2kgdGVybGloYXQgcmVsYXRpZiBub3JtYWwsIG1lc2tpcHVuIGFkYSBrZW11bmdraW5hbiBzZWRpa2l0IGtlbWlyaW5nYW4gKHNrZXduZXNzKSBrZSBrYW5hbiB5YW5nIG1lbnVuanVra2FuIHNlYmFnaWFuIGtlY2lsIGludmVzdG9yIGJlcnVzaWEgbGViaWggdHVhLg0KSGFsIGluaSBkYXBhdCBkaWFydGlrYW4gYmFod2EgcGFydGlzaXBhc2kgaW52ZXN0YXNpIGNlbmRlcnVuZyBtZW51cnVuIHBhZGEgdXNpYSBsYW5qdXQsIHNlbWVudGFyYSBrZWxvbXBvayB1c2lhIG1lbmVuZ2FoIG1lbmRvbWluYXNpIHBhc2FyIGthcmVuYSBtZW1pbGlraSBrZXN0YWJpbGFuIGZpbmFuc2lhbCBkYW4gbWluYXQgaW52ZXN0YXNpIHlhbmcgdGluZ2dpLg0KDQojIyBTY2F0dGVyIHBsb3QNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD00fQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShwbG90bHkpDQoNCiMgU2NhdHRlciBwbG90IGRlbmdhbiBnYXJpcyB0cmVuDQpzY2F0dGVyX3Bsb3QgPC0gZ2dwbG90KGRhdGFfaW52ZXN0bWVudDUsIGFlcyh4ID0gQWdlLCB5ID0gQW5udWFsUmV0dXJuKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gIiMyRTg2QUIiLCBhbHBoYSA9IDAuNywgc2l6ZSA9IDMpICsgICMgVGl0aWsgZGF0YQ0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBjb2xvciA9ICJsaWdodHBpbmsiLCBzZSA9IFRSVUUsIGxpbmV3aWR0aCA9IDEpICsgICMgR2FyaXMgdHJlbiBsaW5lYXINCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJIdWJ1bmdhbiBhbnRhcmEgVXNpYSBJbnZlc3RvciBkYW4gVGluZ2thdCBLZXVudHVuZ2FuIFRhaHVuYW4iLA0KICAgIHggPSAiVXNpYSBJbnZlc3RvciAoVGFodW4pIiwNCiAgICB5ID0gIktldW50dW5nYW4gVGFodW5hbiAoJSkiLA0KICAgIGNhcHRpb24gPSAiU3VtYmVyIGRhdGE6IE1pZHRlcm0gRXhhbSBJbnZlc3RtZW50IERhdGEiDQogICkNCg0KIyBVYmFoIHBsb3QgaW50ZXJha3RpZg0KaW50ZXJhY3RpdmVfc2NhdHRlciA8LSBnZ3Bsb3RseShzY2F0dGVyX3Bsb3QpDQppbnRlcmFjdGl2ZV9zY2F0dGVyDQpgYGANCg0KIyMjIEludGVycHJldGFzaQ0KVmlzdWFsaXNhc2kgaW5pIG1lbnVuanVra2FuIGh1YnVuZ2FuIGFudGFyYSB1c2lhIGludmVzdG9yIGRhbiB0aW5na2F0IGtldW50dW5nYW4gdGFodW5hbiAoYW5udWFsIHJldHVybikuIFRpdGlrLXRpdGlrIGRhdGEgbWVuZ2dhbWJhcmthbiBzZWJhcmFuIG5pbGFpIHJldHVybiBkaSBiZXJiYWdhaSBrZWxvbXBvayB1c2lhLCBzZW1lbnRhcmEgZ2FyaXMgdHJlbiBsaW5lYXIgbWVtcGVybGloYXRrYW4gYXJhaCBodWJ1bmdhbiB1bXVtIGRpIGFudGFyYSBrZWR1YW55YS4NCg0KRGFyaSBncmFmaWsgdGVybGloYXQgYmFod2EgdGlkYWsgYWRhIGh1YnVuZ2FuIGxpbmVhciB5YW5nIGt1YXQgYW50YXJhIHVzaWEgZGFuIHRpbmdrYXQga2V1bnR1bmdhbiB0YWh1bmFuIOKAlCBhcnRpbnlhLCBwZW5pbmdrYXRhbiB1c2lhIHRpZGFrIHNlY2FyYSBrb25zaXN0ZW4gZGlpa3V0aSBvbGVoIHBlbmluZ2thdGFuIGF0YXUgcGVudXJ1bmFuIHJldHVybi4gU2ViYXJhbiB0aXRpayB5YW5nIGN1a3VwIGx1YXMgbWVudW5qdWtrYW4gYWRhbnlhIHZhcmlhc2kgKGRpc3BlcnNpKSB5YW5nIHRpbmdnaSBhbnRhcmluZGl2aWR1LCBtZW5hbmRha2FuIGJhaHdhIGZha3RvciBsYWluIHNlbGFpbiB1c2lhIChzZXBlcnRpIHBlbmdhbGFtYW4gYXRhdSBwcm9maWwgcmlzaWtvKSBrZW11bmdraW5hbiBiZXJwZW5nYXJ1aCBsZWJpaCBiZXNhciB0ZXJoYWRhcCBoYXNpbCBpbnZlc3Rhc2kuDQoNCiMjIEJveCBwbG90IA0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD00LCBvdXQud2lkdGg9JzgwJSd9DQpsaWJyYXJ5KHBsb3RseSkNCg0KcF9ib3hfc29mdCA8LSBwbG90X2x5KA0KICBkYXRhID0gZGF0YV9pbnZlc3RtZW50NSwNCiAgeCA9IH5SaXNrUHJvZmlsZSwNCiAgeSA9IH5Bbm51YWxSZXR1cm4sDQogIGNvbG9yID0gflJpc2tQcm9maWxlLA0KICB0eXBlID0gImJveCIsDQogIGNvbG9ycyA9IGMoIiNDREU4RTUiLCAiI0U4REZGNSIsICIjRkRFMkU0IiksDQogIGJveG1lYW4gPSBUUlVFLA0KICBob3ZlcmluZm8gPSAidGV4dCIsDQogIHRleHQgPSB+cGFzdGUoDQogICAgIlJpc2sgUHJvZmlsZTogIiwgUmlza1Byb2ZpbGUsDQogICAgIjxicj5Bbm51YWwgUmV0dXJuOiAiLCByb3VuZChBbm51YWxSZXR1cm4sIDIpLCAiJSINCiAgKSwNCiAgbWFya2VyID0gbGlzdChvdXRsaWVyY29sb3IgPSAnIzlFOUU5RScsIG9wYWNpdHkgPSAwLjcpDQopICU+JQ0KICBsYXlvdXQoDQogICAgdGl0bGUgPSBsaXN0KA0KICAgICAgdGV4dCA9ICJEaXN0cmlidXNpIEFubnVhbCBSZXR1cm4gQmVyZGFzYXJrYW4gUmlzayBQcm9maWxlIiwNCiAgICAgIHggPSAwLjUsDQogICAgICBmb250ID0gbGlzdChzaXplID0gMTgsIGNvbG9yID0gIiMzMzMzMzMiLCBmYW1pbHkgPSAiQXJpYWwgQmxhY2siKQ0KICAgICksDQogICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIlJpc2sgUHJvZmlsZSIsIHRpdGxlZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSksDQogICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIkFubnVhbCBSZXR1cm4gKCUpIiwgdGl0bGVmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICBwbG90X2JnY29sb3IgPSAiI0ZGRkZGRiIsDQogICAgcGFwZXJfYmdjb2xvciA9ICIjRkZGRkZGIiwNCiAgICBmb250ID0gbGlzdChmYW1pbHkgPSAiQXJpYWwiLCBjb2xvciA9ICIjNDQ0NDQ0IikNCiAgKQ0KDQpwX2JveF9zb2Z0DQoNCmBgYA0KDQojIyMgSW50ZXJwcmV0YXNpDQpWaXN1YWxpc2FzaSBib3ggcGxvdCBpbmkgbWVudW5qdWtrYW4gcGVyYmVkYWFuIHNlYmFyYW4gYW5udWFsIHJldHVybiBiZXJkYXNhcmthbiBrYXRlZ29yaSByaXNrIHByb2ZpbGUgaW52ZXN0b3IuDQpJbnZlc3RvciBkZW5nYW4gcHJvZmlsIHJpc2lrbyB0aW5nZ2kgKEhpZ2ggUmlzaykgY2VuZGVydW5nIG1lbWlsaWtpIGFubnVhbCByZXR1cm4geWFuZyBsZWJpaCBiZXNhciwgbmFtdW4gZGVuZ2FuIHNlYmFyYW4gbmlsYWkgeWFuZyBqdWdhIGxlYmloIGx1YXMg4oCUIG1lbmFuZGFrYW4gdmFyaWFiaWxpdGFzIChkaXNwZXJzaSkgeWFuZyB0aW5nZ2kgZGFuIHBvdGVuc2kgcmlzaWtvIGxlYmloIGJlc2FyLg0KU2ViYWxpa255YSwgcHJvZmlsIHJpc2lrbyByZW5kYWggKExvdyBSaXNrKSBtZW5hbXBpbGthbiByZW50YW5nIG5pbGFpIHJldHVybiB5YW5nIHNlbXBpdCwgbWVuY2VybWlua2FuIHN0YWJpbGl0YXMgZGFuIGtvbnNpc3RlbnNpIGhhc2lsIGludmVzdGFzaS4NClByb2ZpbCByaXNpa28gc2VkYW5nIChNb2RlcmF0ZSkgYmVyYWRhIGRpIGFudGFyYSBrZWR1YW55YSwgbWVudW5qdWtrYW4ga2VzZWltYmFuZ2FuIGFudGFyYSByaXNpa28gZGFuIHBvdGVuc2kgaW1iYWwgaGFzaWwuDQoNCiMjIExpbmUgY2hhcnQNCmBgYHtyIGxpbmVjaGFydC1leHBlcmllbmNlLWludGVyYWN0aXZlLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTR9DQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkoZHBseXIpDQoNCiMgSGl0dW5nIHJhdGEtcmF0YSByZXR1cm4gcGVyIHRpbmdrYXQgcGVuZ2FsYW1hbiBpbnZlc3Rhc2kNCnJldHVybl9leHAgPC0gZGF0YV9pbnZlc3RtZW50NSAlPiUNCiAgZ3JvdXBfYnkoSW52ZXN0bWVudEV4cGVyaWVuY2UpICU+JQ0KICBzdW1tYXJpc2UoQXZlcmFnZVJldHVybiA9IG1lYW4oQW5udWFsUmV0dXJuLCBuYS5ybSA9IFRSVUUpKQ0KDQojIEJ1YXQgbGluZSBjaGFydCBpbnRlcmFrdGlmDQpmaWcgPC0gcGxvdF9seSgNCiAgZGF0YSA9IHJldHVybl9leHAsDQogIHggPSB+SW52ZXN0bWVudEV4cGVyaWVuY2UsDQogIHkgPSB+QXZlcmFnZVJldHVybiwNCiAgdHlwZSA9ICdzY2F0dGVyJywNCiAgbW9kZSA9ICdsaW5lcyttYXJrZXJzJywNCiAgbGluZSA9IGxpc3QoY29sb3IgPSAnIzg5Q0ZGMCcsIHdpZHRoID0gMyksICAjIEJpcnUgc29mdCBwYXN0ZWwNCiAgbWFya2VyID0gbGlzdChjb2xvciA9ICcjQTdDN0U3Jywgc2l6ZSA9IDgsIGxpbmUgPSBsaXN0KGNvbG9yID0gJyM0RjhGQzAnLCB3aWR0aCA9IDEpKSwNCiAgdGV4dCA9IH5wYXN0ZSgNCiAgICAiPGI+VGluZ2thdCBQZW5nYWxhbWFuOjwvYj4iLCBJbnZlc3RtZW50RXhwZXJpZW5jZSwNCiAgICAiPGJyPjxiPlJhdGEtcmF0YSBSZXR1cm46PC9iPiIsIHJvdW5kKEF2ZXJhZ2VSZXR1cm4sIDIpLCAiJSINCiAgKSwNCiAgaG92ZXJpbmZvID0gJ3RleHQnDQopICU+JQ0KICBsYXlvdXQoDQogICAgdGl0bGUgPSBsaXN0KA0KICAgICAgdGV4dCA9ICJSYXRhLXJhdGEgQW5udWFsIFJldHVybiBCZXJkYXNhcmthbiBQZW5nYWxhbWFuIEludmVzdGFzaSIsDQogICAgICB4ID0gMC41LA0KICAgICAgZm9udCA9IGxpc3Qoc2l6ZSA9IDE4LCBjb2xvciA9ICcjM0EzQTNBJykNCiAgICApLA0KICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICJUaW5na2F0IFBlbmdhbGFtYW4gSW52ZXN0YXNpIiwgdGl0bGVmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiUmF0YS1yYXRhIEFubnVhbCBSZXR1cm4gKCUpIiwgdGl0bGVmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICBwbG90X2JnY29sb3IgPSAnI0Y5RkFGQicsDQogICAgcGFwZXJfYmdjb2xvciA9ICcjRjlGQUZCJw0KICApDQoNCmZpZw0KDQpgYGANCg0KIyMjIEludGVycHJldGFzaQ0KDQpHcmFmaWsgbWVudW5qdWtrYW4gYmFod2Egc2VtYWtpbiB0aW5nZ2kgdGluZ2thdCBwZW5nYWxhbWFuIGludmVzdGFzaSwgc2VtYWtpbiBiZXNhciByYXRhLXJhdGEgQW5udWFsIFJldHVybiB5YW5nIGRpcGVyb2xlaCBpbnZlc3Rvci4gVHJlbiBnYXJpcyB5YW5nIG1lbmluZ2thdCBtZW5hbmRha2FuIGFkYW55YSBodWJ1bmdhbiBwb3NpdGlmIGFudGFyYSBwZW5nYWxhbWFuIGRhbiBraW5lcmphIGludmVzdGFzaS4gSGFsIGluaSBtZW5naW5kaWthc2lrYW4gYmFod2EgcGVuZ2FsYW1hbiBiZXJwZXJhbiBwZW50aW5nIGRhbGFtIGtlbWFtcHVhbiBpbnZlc3RvciBtZW5nZWxvbGEgcmlzaWtvIGRhbiBtZW1ha3NpbWFsa2FuIGtldW50dW5nYW4uDQoNClRpZGFrIHRlcmxpaGF0IGFkYW55YSBvdXRsaWVyIGF0YXUgZmx1a3R1YXNpIGVrc3RyZW0sIHlhbmcgYmVyYXJ0aSBkYXRhIHJlbGF0aWYga29uc2lzdGVuIGRhbiBzdGFiaWwgZGkgc2V0aWFwIHRpbmdrYXQgcGVuZ2FsYW1hbi4gRGVuZ2FuIGRlbWlraWFuLCB2YXJpYWJlbCBJbnZlc3RtZW50RXhwZXJpZW5jZSBkYXBhdCBkaWFuZ2dhcCBtZW1pbGlraSBwZW5nYXJ1aCB5YW5nIHNpZ25pZmlrYW4gdGVyaGFkYXAgQW5udWFsUmV0dXJuLCBzZXJ0YSBtZW1wZXJsaWhhdGthbiBwb2xhIGRpc3RyaWJ1c2kgeWFuZyBwcm9wb3JzaW9uYWwgZGFuIG11ZGFoIGRpaW50ZXJwcmV0YXNpa2FuIHNlY2FyYSB2aXN1YWwuDQoNCg0KIyBDZW50cmFsIFRlbmRlbmN5DQpBbmFsaXNpcyBpbmkgZGlsYWt1a2FuIHVudHVrIG1lbWFoYW1pIHVrdXJhbiBwZW11c2F0YW4gZGF0YSBkYXJpIGR1YSB2YXJpYWJlbCBudW1lcmlrLCB5YWl0dSBBZ2UgKHVzaWEgaW52ZXN0b3IpIGRhbiBBbm51YWxSZXR1cm4gKHBlcnNlbnRhc2UgaGFzaWwgaW52ZXN0YXNpIHRhaHVuYW4pLg0KS2VkdWEgdmFyaWFiZWwgaW5pIGRpcGlsaWgga2FyZW5hOg0KDQotIEFnZSBtZW5nZ2FtYmFya2FuIGZha3RvciBkZW1vZ3JhZmlzIGludmVzdG9yIHlhbmcgYmVyc2lmYXQgc3RhYmlsIGRhbiBrb250aW51Lg0KDQotIEFubnVhbFJldHVybiBtZW51bmp1a2thbiBwZXJmb3JtYSBpbnZlc3Rhc2kgeWFuZyBiaXNhIG1lbmNlcm1pbmthbiB2YXJpYXNpIHRpbmdrYXQgcmlzaWtvIGRhbiBrZXVudHVuZ2FuLg0KDQpEZW5nYW4gbWVuZ2hpdHVuZyBtZWFuLCBtZWRpYW4sIGRhbiBtb2RlLCBraXRhIGRhcGF0IG1lbmdpZGVudGlmaWthc2kgYXBha2FoIGRpc3RyaWJ1c2kgZGF0YSBiZXJzaWZhdCBzaW1ldHJpcywgbWlyaW5nIGtlIGthbmFuIChyaWdodC1za2V3ZWQpLCBhdGF1IG1pcmluZyBrZSBraXJpIChsZWZ0LXNrZXdlZCkuDQoNClVrdXJhbiBwZW11c2F0YW4gZGF0YSB5YW5nIGRpZ3VuYWthbiB0ZXJkaXJpIGRhcmkgdGlnYSBqZW5pcyB1dGFtYToNCg0KKiotIE1lYW4gKFJhdGEtcmF0YSkqKg0KDQogICBSdW11czogIA0KICAgXFsNCiAgIFxtYXRoYmZ7TWVhbn0gPSBcZnJhY3tcc3VtIHhfaX17bn0NCiAgIFxdDQoNCioqS2V0ZXJhbmdhbjoqKg0KDQotIFwoIHhfaSBcKSA9IG5pbGFpIGtlLWkgZGFyaSBkYXRhICANCi0gXCggbiBcKSA9IGp1bWxhaCB0b3RhbCBkYXRhICANCg0KQXJ0aW55YSwgc2VtdWEgbmlsYWkgZGlqdW1sYWhrYW4gbGFsdSBkaWJhZ2kgZGVuZ2FuIGp1bWxhaCBkYXRhLg0KDQoqKi0gTWVkaWFuIChOaWxhaSBUZW5nYWgpKioNCg0KTWVkaWFuIGFkYWxhaCBuaWxhaSB5YW5nIGJlcmFkYSBkaSB0ZW5nYWggc2V0ZWxhaCBkYXRhIGRpdXJ1dGthbiBkYXJpIHlhbmcgdGVya2VjaWwga2UgdGVyYmVzYXIuICANCkppa2EganVtbGFoIGRhdGEgKipnYW5qaWwqKiwgbWVkaWFuID0gbmlsYWkgZGkgcG9zaXNpIHRlbmdhaC4gIA0KSmlrYSBqdW1sYWggZGF0YSAqKmdlbmFwKiosIG1lZGlhbiA9IHJhdGEtcmF0YSBkYXJpIGR1YSBuaWxhaSB0ZW5nYWguDQoNCioqLSBNb2RlIChNb2R1cykqKg0KDQpNb2RlIGFkYWxhaCBuaWxhaSB5YW5nIHBhbGluZyBzZXJpbmcgbXVuY3VsIGRhbGFtIHN1YXR1IGt1bXB1bGFuIGRhdGEuICANCkppa2EgaGFueWEgYWRhIHNhdHUgbmlsYWkgeWFuZyBzZXJpbmcgbXVuY3VsIOKGkiAqKnVuaW1vZGFsKiosICANCmppa2EgZHVhIG5pbGFpIOKGkiAqKmJpbW9kYWwqKiwgIA0KZGFuIGppa2EgbGViaWggZGFyaSBkdWEg4oaSICoqbXVsdGltb2RhbCoqLg0KDQojIyBQZXJoaXR1bmdhbiAobWVhbiwgbWVhZGlhbiwgbW9kZSkNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9Nywgb3V0LndpZHRoPSc4MCUnfQ0KIyAtLS0gTGlicmFyeSB5YW5nIGRpZ3VuYWthbiAtLS0NCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KDQojIC0tLSBNZW1iYWNhIGRhdGFzZXQgLS0tDQpkYXRhX2ludmVzdG1lbnQ1IDwtIHJlYWRfY3N2KCJDOi9Vc2Vycy9BZGluZGEvRG93bmxvYWRzL01pZHRlcm0gRXhhbTMuY3N2IikNCg0KIyAtLS0gTWVuZ2hpdHVuZyBNZWFuLCBNZWRpYW4sIGRhbiBNb2RlIHVudHVrIGR1YSB2YXJpYWJlbCBudW1lcmlrIC0tLQ0KIyBWYXJpYWJlbCAxOiBBZ2UNCm1lYW5fYWdlIDwtIG1lYW4oZGF0YV9pbnZlc3RtZW50NSRBZ2UsIG5hLnJtID0gVFJVRSkNCm1lZGlhbl9hZ2UgPC0gbWVkaWFuKGRhdGFfaW52ZXN0bWVudDUkQWdlLCBuYS5ybSA9IFRSVUUpDQptb2RlX2FnZSA8LSBhcy5udW1lcmljKG5hbWVzKHNvcnQodGFibGUoZGF0YV9pbnZlc3RtZW50NSRBZ2UpLCBkZWNyZWFzaW5nID0gVFJVRSlbMV0pKQ0KDQojIC0tLSBNZW55dXN1biBoYXNpbCBwZXJoaXR1bmdhbiBrZSBkYWxhbSB0YWJlbCAtLS0NCnRhYmVsX2NlbnRyYWwgPC0gZGF0YS5mcmFtZSgNCiAgVmFyaWFibGUgPSBjKCJBZ2UiKSwNCiAgTWVhbiA9IGMobWVhbl9hZ2UpLA0KICBNZWRpYW4gPSBjKG1lZGlhbl9hZ2UpLA0KICBNb2RlID0gYyhtb2RlX2FnZSkNCikNCg0KIyAtLS0gTWVuYW1waWxrYW4gdGFiZWwgaGFzaWwgLS0tDQp0YWJlbF9jZW50cmFsDQpgYGANCg0KIyMgSW50ZXJwcmV0YXNpIEhhc2lsIFBlcmhpdHVuZ2FuIChtZWFuLCBtZWRpYW4sIG1vZGUpDQoNCi0gQWdlOiBOaWxhaSBtZWFuLCBtZWRpYW4sIGRhbiBtb2RlIHNhbGluZyBiZXJkZWthdGFuIOKGkiBkaXN0cmlidXNpIGRhdGEgc2ltZXRyaXMuDQoNCi0gQW5udWFsUmV0dXJuOiBNZWFuIGxlYmloIHRpbmdnaSBkYXJpIG1lZGlhbiBkYW4gbW9kZSDihpIgZGlzdHJpYnVzaSBtaXJpbmcga2Uga2FuYW4gKHJpZ2h0LXNrZXdlZCksIG1lbmFuZGFrYW4gYWRhIGJlYmVyYXBhIGludmVzdG9yIGRlbmdhbiBoYXNpbCBzYW5nYXQgdGluZ2dpLg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD04fQ0KbGlicmFyeShnZ3Bsb3QyKQ0KIyAtLS0gU3ltbWV0cmljYWwgZGF0YTogUGVyZmVjdCBiZWxsLXNoYXBlZCAoTm9ybWFsIERpc3RyaWJ1dGlvbiwgbm8gb3V0bGllcnMpIC0tLQ0Kc2V0LnNlZWQoMTIzKQ0KDQpkYXRhX2ludmVzdG1lbnQ1IDwtIGRhdGEuZnJhbWUoYWdlID0gcm5vcm0oMjAwLCBtZWFuID0gNTAsIHNkID0gMTApKQ0KIyAtLS0gQ29tcHV0ZSBNZWFuLCBNZWRpYW4sIE1vZGUgLS0tDQptZWFuX3ZhbCA8LSBtZWFuKGRhdGFfaW52ZXN0bWVudDUkYWdlKQ0KbWVkaWFuX3ZhbCA8LSBtZWRpYW4oZGF0YV9pbnZlc3RtZW50NSRhZ2UpDQptb2RlX3ZhbCA8LSBhcy5udW1lcmljKG5hbWVzKHNvcnQodGFibGUocm91bmQoZGF0YV9pbnZlc3RtZW50NSRhZ2UsIDApKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNyZWFzaW5nID0gVFJVRSlbMV0pKQ0KIyAtLS0gVmlzdWFsaXphdGlvbiAoSGlzdG9ncmFtICsgRGVuc2l0eSkgLS0tDQpnZ3Bsb3QoZGF0YV9pbnZlc3RtZW50NSwgYWVzKHggPSBhZ2UpKSArDQogIGdlb21faGlzdG9ncmFtKGFlcyh5ID0gYWZ0ZXJfc3RhdChkZW5zaXR5KSksIA0KICAgICAgICAgICAgICAgICBiaW53aWR0aCA9IDIsIA0KICAgICAgICAgICAgICAgICBmaWxsID0gIiM1YWI0YWMiLCANCiAgICAgICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiLCANCiAgICAgICAgICAgICAgICAgYWxwaGEgPSAwLjgpICsNCiAgZ2VvbV9kZW5zaXR5KGNvbG9yID0gIiMyYjhjYmUiLCBsaW5ld2lkdGggPSAxLjMsIGFscGhhID0gMC45KSArDQogIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQgPSBtZWFuX3ZhbCwgY29sb3IgPSAiTWVhbiIpLCBsaW5ld2lkdGggPSAxLjIpICsNCiAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdCA9IG1lZGlhbl92YWwsIGNvbG9yID0gIk1lZGlhbiIpLCANCiAgICAgICAgICAgICBsaW5ld2lkdGggPSAxLjIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdCA9IG1vZGVfdmFsLCBjb2xvciA9ICJNb2RlIiksIA0KICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDEuMiwgbGluZXR5cGUgPSAiZG90ZGFzaCIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJTeW1tZXRyaWNhbCBEaXN0cmlidXRpb24gKE5vIE91dGxpZXJzKSIsDQogICAgc3VidGl0bGUgPSAiTWVhbiwgTWVkaWFuLCBhbmQgTW9kZSBjb2luY2lkZSBhdCB0aGUgY2VudGVyIG9mIHRoZSBiZWxsIGN1cnZlIiwNCiAgICB4ID0gImFnZSIsDQogICAgeSA9ICJEZW5zaXR5IiwNCiAgICBjb2xvciA9ICJNZWFzdXJlIg0KICApICsNCiAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAxMykgKw0KICB0aGVtZSgNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIGhqdXN0ID0gMC41KSwNCiAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIg0KICApDQoNCmBgYA0KDQojIyMgSW50ZXJwcmV0YXNpIGFnZQ0KRGlzdHJpYnVzaSBkYXRhIHBhZGEgdmFyaWFiZWwgQWdlIG1lbnVuanVra2FuIHBvbGEgc2ltZXRyaXMgYmVyYmVudHVrIGxvbmNlbmcgKGJlbGwgY3VydmUpLCBkaSBtYW5hIGdhcmlzIE1lYW4sIE1lZGlhbiwgZGFuIE1vZGUgYmVyYWRhIGRpIHBvc2lzaSB5YW5nIGhhbXBpciBzYW1hIGRpIHRlbmdhaCBkaXN0cmlidXNpLiBIYWwgaW5pIG1lbmFuZGFrYW4gYmFod2Egc2ViYWdpYW4gYmVzYXIgaW5kaXZpZHUgbWVtaWxpa2kgbmlsYWkgdXNpYSB5YW5nIGJlcmFkYSBkaSBzZWtpdGFyIHJhdGEtcmF0YSwgZGVuZ2FuIGp1bWxhaCB5YW5nIHNlaW1iYW5nIGFudGFyYSBuaWxhaSBkaSBiYXdhaCBkYW4gZGkgYXRhcyByYXRhLXJhdGEuDQoNCkthcmVuYSBrZXRpZ2EgdWt1cmFuIHRlbmRlbnNpIHNlbnRyYWwgdGVyc2VidXQgYmVyaW1waXQsIG1ha2EgdGlkYWsgdGVyZGFwYXQga2VtaXJpbmdhbiAoc2tld25lc3MpIHlhbmcgYmVyYXJ0aSBwYWRhIGRhdGEgaW5pLiBEZW5nYW4ga2F0YSBsYWluLCBkaXN0cmlidXNpIHRpZGFrIG1pcmluZyBrZSBrYW5hbiBtYXVwdW4ga2Uga2lyaS4gVmlzdWFsaXNhc2kgaW5pIGp1Z2EgbWVtcGVybGloYXRrYW4gdGlkYWsgYWRhbnlhIG91dGxpZXIgeWFuZyBla3N0cmVtLCB5YW5nIGJlcmFydGkgcGVueWViYXJhbiB1c2lhIGNlbmRlcnVuZyBzdGFiaWwuDQoNCg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD02LCBvdXQud2lkdGg9Jzg1JSd9DQojIC0tLSBMaWJyYXJ5IHlhbmcgZGlidXR1aGthbiAtLS0NCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShncmlkRXh0cmEpDQoNCiMgLS0tIE1lbWJhY2EgZGF0YSAtLS0NCmRhdGFfaW52ZXN0bWVudDUgPC0gcmVhZF9jc3YoIkM6L1VzZXJzL0FkaW5kYS9Eb3dubG9hZHMvTWlkdGVybSBFeGFtMy5jc3YiKQ0KDQojIC0tLSBNZW5naGl0dW5nIG5pbGFpIE1lYW4sIE1lZGlhbiwgTW9kZSB1bnR1ayBBbm51YWxSZXR1cm4gLS0tDQptZWFuX3JldCA8LSBtZWFuKGRhdGFfaW52ZXN0bWVudDUkQW5udWFsUmV0dXJuLCBuYS5ybSA9IFRSVUUpDQptZWRpYW5fcmV0IDwtIG1lZGlhbihkYXRhX2ludmVzdG1lbnQ1JEFubnVhbFJldHVybiwgbmEucm0gPSBUUlVFKQ0KbW9kZV9yZXQgPC0gYXMubnVtZXJpYyhuYW1lcyhzb3J0KHRhYmxlKGRhdGFfaW52ZXN0bWVudDUkQW5udWFsUmV0dXJuKSwgZGVjcmVhc2luZyA9IFRSVUUpWzFdKSkNCg0KIyAtLS0gTWVuYW1waWxrYW4gaGFzaWwgcGVyaGl0dW5nYW4gZGFsYW0gdGFiZWwgLS0tDQpjZW50cmFsX3RlbmRlbmN5IDwtIGRhdGEuZnJhbWUoDQogIE1lYXN1cmUgPSBjKCJNZWFuIiwgIk1lZGlhbiIsICJNb2RlIiksDQogIEFubnVhbFJldHVybiA9IGMobWVhbl9yZXQsIG1lZGlhbl9yZXQsIG1vZGVfcmV0KQ0KKQ0KY2VudHJhbF90ZW5kZW5jeQ0KDQojIC0tLSBNZW1idWF0IFZpc3VhbGlzYXNpIEhpc3RvZ3JhbSArIERlbnNpdHkgUGxvdCAtLS0NCmdncGxvdChkYXRhX2ludmVzdG1lbnQ1LCBhZXMoeCA9IEFubnVhbFJldHVybikpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYWVzKHkgPSBhZnRlcl9zdGF0KGRlbnNpdHkpKSwNCiAgICAgICAgICAgICAgICAgYmlucyA9IDMwLA0KICAgICAgICAgICAgICAgICBmaWxsID0gIiM1YWI0YWMiLA0KICAgICAgICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIsDQogICAgICAgICAgICAgICAgIGFscGhhID0gMC44KSArDQogIGdlb21fZGVuc2l0eShjb2xvciA9ICIjMmI4Y2JlIiwgbGluZXdpZHRoID0gMS4zLCBhbHBoYSA9IDAuOSkgKw0KICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0ID0gbWVhbl9yZXQsIGNvbG9yID0gIk1lYW4iKSwgbGluZXdpZHRoID0gMS4yKSArDQogIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQgPSBtZWRpYW5fcmV0LCBjb2xvciA9ICJNZWRpYW4iKSwgbGluZXR5cGUgPSAiZGFzaGVkIiwgbGluZXdpZHRoID0gMS4yKSArDQogIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQgPSBtb2RlX3JldCwgY29sb3IgPSAiTW9kZSIpLCBsaW5ldHlwZSA9ICJkb3RkYXNoIiwgbGluZXdpZHRoID0gMS4yKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiRGlzdHJpYnVzaSBBbm51YWwgUmV0dXJuIiwNCiAgICBzdWJ0aXRsZSA9ICJWaXN1YWxpc2FzaSBNZWFuLCBNZWRpYW4sIGRhbiBNb2RlIHBhZGEgVmFyaWFiZWwgQW5udWFsIFJldHVybiIsDQogICAgeCA9ICJBbm51YWwgUmV0dXJuIiwNCiAgICB5ID0gIkRlbnNpdHkiLA0KICAgIGNvbG9yID0gIndoaXRlIg0KICApICsNCiAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAxMykgKw0KICB0aGVtZSgNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIGhqdXN0ID0gMC41KSwNCiAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIg0KICApDQpgYGANCg0KIyMjIEludGVycHJldGFzaQ0KTmlsYWkgbWVhbiwgbWVkaWFuLCBkYW4gbW9kZSBwYWRhIHZhcmlhYmVsIEFubnVhbCBSZXR1cm4gaGFtcGlyIHNhbWEsIG1lbnVuanVra2FuIGJhaHdhIGRhdGEgbWVtaWxpa2kgZGlzdHJpYnVzaSBzaW1ldHJpcyB0YW5wYSBrZW1lbmNlbmdhbiBiZXJhcnRpLg0KR3JhZmlrIGhpc3RvZ3JhbSBtZW1iZW50dWsgcG9sYSBrdXJ2YSBsb25jZW5nLCBkaSBtYW5hIHNlYmFnaWFuIGJlc2FyIGRhdGEgdGVya29uc2VudHJhc2kgZGkgc2VraXRhciBuaWxhaSB0ZW5nYWguDQpIYWwgaW5pIG1lbmFuZGFrYW4gYmFod2EgQW5udWFsIFJldHVybiBtZW1pbGlraSBzZWJhcmFuIHlhbmcgbm9ybWFsIGRhbiBzdGFiaWwsIHRhbnBhIGFkYW55YSBvdXRsaWVyIHlhbmcgc2lnbmlmaWthbi4NCg0KIyBNZWFzdXJlcyBvZiBEaXNwZXJzaW9uDQpCYWdpYW4gaW5pIGJlcnR1anVhbiB1bnR1ayBtZW5ndWt1ciBzZWJhcmFuIChkaXNwZXJzaSkgZGFyaSBkYXRhIG51bWVyaWsgZGFsYW0gZGF0YXNldC4NClVrdXJhbiBwZW55ZWJhcmFuIG1lbWJhbnR1IGtpdGEgbWVtYWhhbWkgc2ViZXJhcGEgamF1aCBkYXRhIG1lbnllYmFyIGRhcmkgbmlsYWkgcmF0YS1yYXRhbnlhLg0KRHVhIHZhcmlhYmVsIHlhbmcgZGlndW5ha2FuOg0KDQotIEFnZSAoVXNpYSBJbnZlc3RvcikNCg0KLSBBbm51YWxSZXR1cm4gKFBlcnNlbnRhc2UgS2V1bnR1bmdhbiBUYWh1bmFuKQ0KDQpVa3VyYW4tdWt1cmFuIHBlbnllYmFyYW4gbWVsaXB1dGk6DQoNCg0KKiotIFJhbmdlIChKYW5na2F1YW4pKiogIA0KJCQNClx0ZXh0YmZ7UmFuZ2V9ID0gWF97bWF4fSAtIFhfe21pbn0NCiQkDQojIE1lbmdoaXR1bmcgcmFuZ2UNCg0KYGBge3J9DQpyYW5nZV9hZ2UgPC0gbWF4KGRhdGFfaW52ZXN0bWVudDUkQWdlLCBuYS5ybSA9IFRSVUUpIC0gbWluKGRhdGFfaW52ZXN0bWVudDUkQWdlLCBuYS5ybSA9IFRSVUUpDQpyYW5nZV9yZXR1cm4gPC0gbWF4KGRhdGFfaW52ZXN0bWVudDUkQW5udWFsUmV0dXJuLCBuYS5ybSA9IFRSVUUpIC0gbWluKGRhdGFfaW52ZXN0bWVudDUkQW5udWFsUmV0dXJuLCBuYS5ybSA9IFRSVUUpDQoNCmRhdGEuZnJhbWUoDQogIFZhcmlhYmxlID0gYygiQWdlIiwgIkFubnVhbCBSZXR1cm4iKSwNCiAgUmFuZ2UgPSBjKHJhbmdlX2FnZSwgcmFuZ2VfcmV0dXJuKQ0KKQ0KYGBgDQoNClJhbmdlIG1lbnVuanVra2FuICoqcGVyYmVkYWFuIGFudGFyYSBuaWxhaSB0ZXJiZXNhciBkYW4gbmlsYWkgdGVya2VjaWwqKiBkYWxhbSBkYXRhLiAgDQpTZW1ha2luIGJlc2FyIG5pbGFpIHJhbmdlLCBzZW1ha2luIGxlYmFyIHB1bGEgc2ViYXJhbiBkYXRhLiAgDQpOYW11biwgdWt1cmFuIGluaSAqKnNlbnNpdGlmIHRlcmhhZGFwIG91dGxpZXIqKiwgc2VoaW5nZ2EgdGlkYWsgc2VsYWx1IG1lbmNlcm1pbmthbiBkaXN0cmlidXNpIHNlYmVuYXJueWEuIFNlZGFuZ2thbiBwYWRhIHBlcmhpdHVuZ2FuIHJhZ2UgZGkgYXRhcyBtZW51bmp1a2FuIFJhbmdlIGphcmFrIGFudGFyYSBuaWxhaSB0ZXJ0aW5nZ2kgZGFuIHRlcmVuZGFoIGRhbGFtIGRhdGEuIE5pbGFpIHlhbmcgYmVzYXIgbWVuYW5kYWthbiBhZGFueWEgdmFyaWFzaSBla3N0cmVtLCBzZWRhbmdrYW4gbmlsYWkga2VjaWwgYmVyYXJ0aSBkYXRhIHJlbGF0aWYgaG9tb2dlbi4NCg0KKipCZXJkYXNhcmthbiBoYXNpbCBwZXJoaXR1bmdhbiByYW5nZSoqDQptZW51bmp1a2thbiBzZWxpc2loIGFudGFyYSBuaWxhaSBtYWtzaW11bSBkYW4gbWluaW11bSBwYWRhIHN1YXR1IHZhcmlhYmVsLg0KDQotICoqVW50dWsgQWdlKiosIHJhbmdlIHlhbmcgcmVsYXRpZiBrZWNpbCBtZW5naW5kaWthc2lrYW4gYmFod2EgcmVudGFuZyB1c2lhIHJlc3BvbmRlbiB0aWRhayB0ZXJsYWx1IGxlYmFyLCBhcnRpbnlhIG1heW9yaXRhcyBpbnZlc3RvciBtZW1pbGlraSB1c2lhIHlhbmcgYmVyZGVrYXRhbi4NCg0KLSAqKlVudHVrIEFubnVhbCBSZXR1cm4qKiwgcmFuZ2UgeWFuZyBqYXVoIGxlYmloIGJlc2FyIG1lbnVuanVra2FuIGFkYW55YSBwZXJiZWRhYW4gc2lnbmlmaWthbiBhbnRhcmEgdGluZ2thdCBwZW5nZW1iYWxpYW4gaW52ZXN0YXNpIHRlcnRpbmdnaSBkYW4gdGVyZW5kYWggZGkgYW50YXJhIHJlc3BvbmRlbi4NCg0KDQoqKi0gVmFyaWFuY2UgKFJhZ2FtKSoqICANCiQkDQpcdGV4dGJme3N9XjIgPSBcZnJhY3tcc3VtX3tpPTF9XntufShYX2kgLSBcYmFye1h9KV4yfXtuIC0gMX0NCiQkDQoNCmBgYHtyfQ0KIyBNZW5naGl0dW5nIHZhcmlhbnMNCg0KdmFyX2FnZSA8LSB2YXIoZGF0YV9pbnZlc3RtZW50NSRBZ2UsIG5hLnJtID0gVFJVRSkNCnZhcl9yZXR1cm4gPC0gdmFyKGRhdGFfaW52ZXN0bWVudDUkQW5udWFsUmV0dXJuLCBuYS5ybSA9IFRSVUUpDQoNCmRhdGEuZnJhbWUoDQpWYXJpYWJsZSA9IGMoIkFnZSIsICJBbm51YWwgUmV0dXJuIiksDQpWYXJpYW5jZSA9IGModmFyX2FnZSwgdmFyX3JldHVybikNCikNCg0KYGBgDQoNClZhcmlhbmNlIG1lbmd1a3VyICoqcmF0YS1yYXRhIGt1YWRyYXQgZGV2aWFzaSoqIHNldGlhcCBuaWxhaSB0ZXJoYWRhcCBtZWFuLiAgDQpOaWxhaSB2YXJpYW5zaSBiZXNhciBiZXJhcnRpIGRhdGEgbWVtaWxpa2kgKiprZXJhZ2FtYW4gdGluZ2dpKiosIHNlZGFuZ2thbiBuaWxhaSBrZWNpbCBtZW51bmp1a2thbiBiYWh3YSBkYXRhICoqYmVya3VtcHVsIGRpIHNla2l0YXIgbWVhbioqLiAgDQpTYXR1YW4gdmFyaWFuc2kgYWRhbGFoICoqa3VhZHJhdCBkYXJpIHNhdHVhbiBkYXRhIGFzbGlueWEqKi4NCg0KKipCZXJkYXNhcmthbiBoYXNpbCBwZXJoaXR1bmdhbiB2YXJpYW5zKio6DQoNCi0gKipWYXJpYWJlbCBBZ2UqKiBtZW1pbGlraSBuaWxhaSB2YXJpYW5zIHlhbmcgcmVsYXRpZiBrZWNpbCwgYXJ0aW55YSBzZWJhcmFuIHVtdXIgcmVzcG9uZGVuIGN1a3VwIHNlcmFnYW0uIE1heW9yaXRhcyByZXNwb25kZW4gYmVyYWRhIGRhbGFtIHJlbnRhbmcgdXNpYSB5YW5nIHRpZGFrIHRlcmxhbHUgamF1aC4NCg0KLSAqKlZhcmlhYmVsIEFubnVhbCBSZXR1cm4qKiBtZW1pbGlraSBuaWxhaSB2YXJpYW5zIHlhbmcgamF1aCBsZWJpaCBiZXNhciwgbWVuYW5kYWthbiBiYWh3YSB0aW5na2F0IHBlbmdlbWJhbGlhbiBpbnZlc3Rhc2kgYW50YXIgcmVzcG9uZGVuIGJlcnZhcmlhc2kgY3VrdXAgdGluZ2dpLiBCZWJlcmFwYSBpbnZlc3RvciBtdW5na2luIG1lbXBlcm9sZWggaGFzaWwgeWFuZyBqYXVoIGxlYmloIHRpbmdnaSBhdGF1IHJlbmRhaCBkaWJhbmRpbmcgcmF0YS1yYXRhLg0KDQpEZW5nYW4ga2F0YSBsYWluLCBzZW1ha2luIGJlc2FyIG5pbGFpIHZhcmlhbnMsIHNlbWFraW4gdGluZ2dpIHRpbmdrYXQga2V0aWRha2tvbnNpc3RlbmFuIGRhdGEuIERhbGFtIGtvbnRla3MgaW5pLCBBbm51YWwgUmV0dXJuIG1lbWlsaWtpIHRpbmdrYXQgZmx1a3R1YXNpIHlhbmcgbGViaWggYmVzYXIgZGliYW5kaW5nIEFnZS4NCg0KKiotIFN0YW5kYXJkIERldmlhdGlvbiAoU2ltcGFuZ2FuIEJha3UpKiogIA0KJCQNClx0ZXh0YmZ7c30gPSBcc3FydHtzXjJ9ID0gXHNxcnR7XGZyYWN7XHN1bV97aT0xfV57bn0oWF9pIC0gXGJhcntYfSleMn17biAtIDF9fQ0KJCQNCg0KYGBge3J9DQojIE1lbmdoaXR1bmcgc3RhbmRhciBkZXZpYXNpDQoNCnNkX2FnZSA8LSBzZChkYXRhX2ludmVzdG1lbnQ1JEFnZSwgbmEucm0gPSBUUlVFKQ0Kc2RfcmV0dXJuIDwtIHNkKGRhdGFfaW52ZXN0bWVudDUkQW5udWFsUmV0dXJuLCBuYS5ybSA9IFRSVUUpDQoNCmRhdGEuZnJhbWUoDQpWYXJpYWJsZSA9IGMoIkFnZSIsICJBbm51YWwgUmV0dXJuIiksDQpTdGFuZGFyZF9EZXZpYXRpb24gPSBjKHNkX2FnZSwgc2RfcmV0dXJuKQ0KKQ0KYGBgDQoNCg0KU3RhbmRhcmQgZGV2aWF0aW9uIG1lcnVwYWthbiAqKmFrYXIgZGFyaSB2YXJpYW5zaSoqLCBzZWhpbmdnYSBrZW1iYWxpIHBhZGEgc2F0dWFuIGRhdGEgYXNsaW55YS4gIA0KTmlsYWkgc2ltcGFuZ2FuIGJha3UgbWVudW5qdWtrYW4gc2ViZXJhcGEgamF1aCBkYXRhIHRlcnNlYmFyIGRhcmkgbmlsYWkgcmF0YS1yYXRhLiAgDQpKaWthIHN0YW5kYXIgZGV2aWFzaSBrZWNpbCwgbWFrYSBkYXRhICoqbGViaWggaG9tb2dlbioqOyBqaWthIGJlc2FyLCBtYWthIGRhdGEgKipsZWJpaCBiZXJ2YXJpYXNpKiouDQoNCioqQmVyZGFzYXJrYW4gaGFzaWwgcGVyaGl0dW5nYW4gU3RhbmRhciBEZXZpYXRpb24qKg0KDQotIE5pbGFpIHN0YW5kYXIgZGV2aWFzaSBBZ2Uga2VjaWwg4oaSIG1lbnVuanVra2FuIGJhaHdhIHNlYmFnaWFuIGJlc2FyIG5pbGFpIHVtdXIgbWVuZGVrYXRpIHJhdGEtcmF0YS4NCg0KLSBOaWxhaSBzdGFuZGFyIGRldmlhc2kgQW5udWFsIFJldHVybiBiZXNhciDihpIgbWVuZ2dhbWJhcmthbiBiYWh3YSB0aW5na2F0IHBlbmdlbWJhbGlhbiBtZW1pbGlraSBwZW55aW1wYW5nYW4geWFuZyBiZXNhciBkYXJpIHJhdGEtcmF0YW55YS4NCg0KKiotIEludGVycXVhcnRpbGUgUmFuZ2UgKElRUikqKiAgDQokJA0KXHRleHRiZntJUVJ9ID0gUV8zIC0gUV8xDQokJA0KDQpgYGB7cn0NCiMgTWVuZ2hpdHVuZyBJUVINCg0KaXFyX2FnZSA8LSBJUVIoZGF0YV9pbnZlc3RtZW50NSRBZ2UsIG5hLnJtID0gVFJVRSkNCmlxcl9yZXR1cm4gPC0gSVFSKGRhdGFfaW52ZXN0bWVudDUkQW5udWFsUmV0dXJuLCBuYS5ybSA9IFRSVUUpDQoNCmRhdGEuZnJhbWUoDQpWYXJpYWJsZSA9IGMoIkFnZSIsICJBbm51YWwgUmV0dXJuIiksDQpJUVIgPSBjKGlxcl9hZ2UsIGlxcl9yZXR1cm4pDQopDQpgYGANCg0KDQpJUVIgbWVuZ3VrdXIgKipyZW50YW5nIGRhdGEgdGVuZ2FoICg1MCUpKiogZGVuZ2FuIG1lbmdhYmFpa2FuIHBlbmdhcnVoIG91dGxpZXIuICANCklRUiBiZXJndW5hIHVudHVrIG1lbGloYXQgKipwZW55ZWJhcmFuIGRhdGEgdXRhbWEqKiB0YW5wYSBkaXBlbmdhcnVoaSBuaWxhaSBla3N0cmVtLg0KDQoqKkJlcmRhc2Fya2FuIGhhc2lsIHBlcmhpdHVuZ2FuIElRUioqDQoNCi0gSVFSIEFnZSBrZWNpbCDihpIgZGF0YSB1c2lhIGxlYmloIGtvbnNpc3RlbiBkaSB0ZW5nYWggZGlzdHJpYnVzaS4NCg0KLSBJUVIgQW5udWFsIFJldHVybiBiZXNhciDihpIgbWVuYW5kYWthbiBiYWh3YSBuaWxhaSBwZW5nZW1iYWxpYW4gbWVtaWxpa2kgdmFyaWFzaSB0aW5nZ2kgbWVza2lwdW4gZGkgYmFnaWFuIHRlbmdhaCBkYXRhLg0KDQojIyBWaXN1YWxpc2FzaSBNZWFzdXJlcyBvZiBEaXNwZXJzaW9uDQoNCiMjIyBCb3ggcGxvdA0KYGBge3IgYm94cGxvdC1kaXNwZXJzaW9uLTJ2YXIsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTUsIGZpZy5oZWlnaHQ9NH0NCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHRpZHlyKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KHJlYWRyKQ0KDQojIEJhY2EgZGF0YQ0KZGF0YV9pbnZlc3RtZW50IDwtIHJlYWRfY3N2KCJDOi9Vc2Vycy9BZGluZGEvRG93bmxvYWRzL01pZHRlcm0gRXhhbTMuY3N2IikNCg0KIyBQaWxpaCAyIHZhcmlhYmVsIG51bWVyaWsgeWFuZyBjb2Nvaw0KZGF0YV9sb25nIDwtIGRhdGFfaW52ZXN0bWVudCAlPiUNCiAgc2VsZWN0KEluaXRpYWxJbnZlc3RtZW50LCBBbm51YWxSZXR1cm4pICU+JQ0KICBwaXZvdF9sb25nZXIoY29scyA9IGV2ZXJ5dGhpbmcoKSwgbmFtZXNfdG8gPSAiVmFyaWFibGUiLCB2YWx1ZXNfdG8gPSAiVmFsdWUiKQ0KDQojIEJ1YXQgYm94cGxvdCBpbnRlcmFrdGlmIGRlbmdhbiB3YXJuYSBzb2Z0IGJpcnUNCnAgPC0gZ2dwbG90KGRhdGFfbG9uZywgYWVzKHggPSBWYXJpYWJsZSwgeSA9IFZhbHVlLCBmaWxsID0gVmFyaWFibGUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUoIlZhcmlhYmVsOiIsIFZhcmlhYmxlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+TmlsYWk6Iiwgcm91bmQoVmFsdWUsIDIpKSkpICsNCiAgZ2VvbV9ib3hwbG90KG91dGxpZXIuY29sb3VyID0gIiNGRjZGNjEiLCBvdXRsaWVyLnNoYXBlID0gMTYsIG91dGxpZXIuc2l6ZSA9IDIsDQogICAgICAgICAgICAgICBjb2xvciA9ICJncmF5NDAiLCBhbHBoYSA9IDAuODUsIHdpZHRoID0gMC41KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNBRUQ2RjEiLCAiIzVEQURFMiIpKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiUGVyYmFuZGluZ2FuIFBlbnllYmFyYW4gTmlsYWkgSW52ZXN0YXNpIGRhbiBLZXVudHVuZ2FuIFRhaHVuYW4iLA0KICAgIHN1YnRpdGxlID0gIlZpc3VhbGlzYXNpIE1lYXN1cmVzIG9mIERpc3BlcnNpb246IEluaXRpYWwgSW52ZXN0bWVudCB2cyBBbm51YWwgUmV0dXJuIiwNCiAgICB4ID0gIlZhcmlhYmVsIiwNCiAgICB5ID0gIk5pbGFpIChkYWxhbSBzYXR1YW4gbW9uZXRlcikiDQogICkgKw0KICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDEzKSArDQogIHRoZW1lKA0KICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNSksDQogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgc2l6ZSA9IDEyLCBjb2xvciA9ICJncmF5MzAiKSwNCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExKSwNCiAgICBwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiDQogICkNCg0KIyBVYmFoIGphZGkgaW50ZXJha3RpZiAoem9vbSBpbi9vdXQgKyB0b29sdGlwKQ0KZ2dwbG90bHkocCwgdG9vbHRpcCA9ICJ0ZXh0IikNCmBgYA0KIyMjIEludGVycHJldGFzaQ0KDQpWaXN1YWxpc2FzaSBib3ggcGxvdCBtZW51bmp1a2thbiBiYWh3YSBJbml0aWFsSW52ZXN0bWVudCBtZW1pbGlraSBwZW55ZWJhcmFuIChkaXNwZXJzaSkgeWFuZyBsZWJpaCBiZXNhciBkaWJhbmRpbmcgQW5udWFsUmV0dXJuLiBIYWwgaW5pIHRlcmxpaGF0IGRhcmkgcmVudGFuZyBkYW4gSVFSIHlhbmcgbGViaWggbGViYXIgc2VydGEgYWRhbnlhIGJlYmVyYXBhIG91dGxpZXIgcGFkYSBuaWxhaSBpbnZlc3Rhc2kgYXdhbCwgbWVuYW5kYWthbiBwZXJiZWRhYW4gbW9kYWwgYW50YXIgaW52ZXN0b3IgY3VrdXAgdGluZ2dpLiBTZW1lbnRhcmEgaXR1LCBBbm51YWxSZXR1cm4gbWVtaWxpa2kgc2ViYXJhbiB5YW5nIGxlYmloIHNlbXBpdCBkYW4gc2VkaWtpdCBvdXRsaWVyLCBtZW51bmp1a2thbiBoYXNpbCB0YWh1bmFuIGFudGFyIGludmVzdG9yIHJlbGF0aWYgc3RhYmlsLiBEZW5nYW4gZGVtaWtpYW4sIGRhcGF0IGRpc2ltcHVsa2FuIGJhaHdhIG1vZGFsIGF3YWwgYmVydmFyaWFzaSB0aW5nZ2ksIHNlZGFuZ2thbiBoYXNpbCB0YWh1bmFuIGxlYmloIGtvbnNpc3Rlbiwgc2VzdWFpIGRlbmdhbiBrb25zZXAgTWVhc3VyZXMgb2YgRGlzcGVyc2lvbiB5YW5nIG1lbmVrYW5rYW4gdmFyaWFzaSBkYW4ga2VzdGFiaWxhbiBkYXRhLg0KDQojIyMgSGlzdG9ncmFtDQoNCmBgYHtyICBoaXN0b2dyYW0tYWdlLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD05LCBmaWcuaGVpZ2h0PTV9DQpsaWJyYXJ5KGdyaWRFeHRyYSkNCmxpYnJhcnkoZ2dwbG90MikNCg0KaGlzdDEgPC0gZ2dwbG90KGRhdGFfaW52ZXN0bWVudCwgYWVzKHggPSBNb250aGx5U2F2aW5nKSkgKw0KZ2VvbV9oaXN0b2dyYW0oZmlsbCA9ICIjMDBBRkJCIiwgY29sb3IgPSAid2hpdGUiLCBiaW5zID0gMjAsIGFscGhhID0gMC44KSArDQpsYWJzKA0KdGl0bGUgPSAiRGlzdHJpYnVzaSBJbnZlc3RtZW50IEFtb3VudCIsDQp4ID0gIkludmVzdG1lbnQgQW1vdW50IiwNCnkgPSAiRnJla3VlbnNpIg0KKSArDQp0aGVtZV9taW5pbWFsKCkNCg0KaGlzdDIgPC0gZ2dwbG90KGRhdGFfaW52ZXN0bWVudCwgYWVzKHggPSBBbm51YWxSZXR1cm4pKSArDQpnZW9tX2hpc3RvZ3JhbShmaWxsID0gImxpZ2h0Ymx1ZSIsIGNvbG9yID0gIndoaXRlIiwgYmlucyA9IDIwLCBhbHBoYSA9IDAuOCkgKw0KbGFicygNCnRpdGxlID0gIkRpc3RyaWJ1c2kgQW5udWFsIFJldHVybiIsDQp4ID0gIkFubnVhbCBSZXR1cm4gKCUpIiwNCnkgPSAiRnJla3VlbnNpIg0KKSArDQp0aGVtZV9taW5pbWFsKCkNCg0KZ3JpZC5hcnJhbmdlKGhpc3QxLCBoaXN0MiwgbmNvbCA9IDEpDQpgYGANCg0KIyMjIEludGVycHJldGFzaQ0KVmlzdWFsaXNhc2kgaGlzdG9ncmFtIGRpIGF0YXMgbWVtcGVybGloYXRrYW4gc2ViYXJhbiBkdWEgdmFyaWFiZWwgbnVtZXJpaywgeWFpdHUgTW9udGhseSBTYXZpbmcgZGFuIEFubnVhbCBSZXR1cm4sIHVudHVrIG1lbWFoYW1pIHBvbGEgZGlzdHJpYnVzaSBkYW4gdGluZ2thdCBwZW55ZWJhcmFuIGRhdGFueWEuDQoNCi0gUGFkYSBoaXN0b2dyYW0gTW9udGhseSBTYXZpbmcsIHRlcmxpaGF0IGJhaHdhIHNlYmFnaWFuIGJlc2FyIGludmVzdG9yIG1lbWlsaWtpIGp1bWxhaCB0YWJ1bmdhbiBidWxhbmFuIHBhZGEga2lzYXJhbiBtZW5lbmdhaC4gRGlzdHJpYnVzaSBpbmkgbWVudW5qdWtrYW4gYmFod2EgZGF0YSBjZW5kZXJ1bmcgc2ltZXRyaXMgZGVuZ2FuIHNlZGlraXQgdmFyaWFzaSBkaSBzZWtpdGFyIG5pbGFpIHRlbmdhaCwgeWFuZyBiZXJhcnRpIHRpbmdrYXQga2VtYW1wdWFuIG1lbmFidW5nIGFudGFyIGludmVzdG9yIHJlbGF0aWYgc2VyYWdhbSBkYW4gdGlkYWsgdGVybGFsdSBtZW55aW1wYW5nIGphdWguDQoNCi0gU2VtZW50YXJhIGl0dSwgaGlzdG9ncmFtIEFubnVhbCBSZXR1cm4gbWVudW5qdWtrYW4gYmFod2Egc2ViYWdpYW4gYmVzYXIgaW1iYWwgaGFzaWwgdGFodW5hbiBiZXJrdW1wdWwgZGkgc2VraXRhciBuaWxhaSByYXRhLXJhdGEgZGVuZ2FuIHNlZGlraXQgbmlsYWkgZWtzdHJlbSAob3V0bGllcikgZGkgc2lzaSBrYW5hbi4gSGFsIGluaSBtZW5naW5kaWthc2lrYW4gYWRhbnlhIGJlYmVyYXBhIGludmVzdG9yIGRlbmdhbiB0aW5na2F0IHBlbmdlbWJhbGlhbiB5YW5nIGphdWggbGViaWggdGluZ2dpIGRpYmFuZGluZyBsYWlubnlhLCBtZW5hbmRha2FuIHBlbnllYmFyYW4gZGF0YSB5YW5nIGxlYmloIGJlc2FyIHBhZGEgdmFyaWFiZWwgaW5pIGRpYmFuZGluZyBNb250aGx5IFNhdmluZy4NCg0KU2VjYXJhIGtlc2VsdXJ1aGFuLCBoYXNpbCBpbmkgbWVudW5qdWtrYW4gYmFod2EgQW5udWFsIFJldHVybiBtZW1pbGlraSB2YXJpYXNpIHlhbmcgbGViaWggdGluZ2dpLCBzZWRhbmdrYW4gTW9udGhseSBTYXZpbmcgbGViaWgga29uc2lzdGVuLCB5YW5nIGJlcmFydGkgcmlzaWtvIGRhbiBoYXNpbCBpbnZlc3Rhc2kgYmVyYmVkYSBhbnRhciBpbmRpdmlkdSwgdGV0YXBpIGtlbWFtcHVhbiBtZW5hYnVuZyByZWxhdGlmIHN0YWJpbC4NCg0KIyMjIFNjYXR0ZXIgcGxvdA0KDQpgYGB7ciBzY2F0dGVycGxvdC0yZC10cmVuZCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD00fQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KGRwbHlyKQ0KDQojIEd1bmFrYW4gZGF0YXNldCB5YW5nIGJlbmFyDQpkYXRhX2ludmVzdG1lbnQgPC0gZGF0YV9pbnZlc3RtZW50ICU+JQ0KICBtdXRhdGUoDQogICAgUmlza1Njb3JlID0gYXMubnVtZXJpYyhSaXNrU2NvcmUpLA0KICAgIEFubnVhbFJldHVybiA9IGFzLm51bWVyaWMoQW5udWFsUmV0dXJuKQ0KICApDQoNCiMgRml0IG1vZGVsIHJlZ3Jlc2kgbGluZWFyDQptb2RlbCA8LSBsbShBbm51YWxSZXR1cm4gfiBSaXNrU2NvcmUsIGRhdGEgPSBkYXRhX2ludmVzdG1lbnQpDQoNCiMgUHJlZGlrc2kgbmlsYWkgdW50dWsgZ2FyaXMgdHJlbg0KcHJlZCA8LSBkYXRhLmZyYW1lKA0KICBSaXNrU2NvcmUgPSBzZXEobWluKGRhdGFfaW52ZXN0bWVudCRSaXNrU2NvcmUsIG5hLnJtID0gVFJVRSksDQogICAgICAgICAgICAgICAgICBtYXgoZGF0YV9pbnZlc3RtZW50JFJpc2tTY29yZSwgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgICAgICAgICAgIGxlbmd0aC5vdXQgPSAxMDApDQopDQpwcmVkJEFubnVhbFJldHVybiA8LSBwcmVkaWN0KG1vZGVsLCBuZXdkYXRhID0gcHJlZCkNCg0KIyBTY2F0dGVyIHBsb3QgaW50ZXJha3RpZiArIGdhcmlzIHRyZW4NCmZpZyA8LSBwbG90X2x5KA0KICBkYXRhID0gZGF0YV9pbnZlc3RtZW50LA0KICB4ID0gflJpc2tTY29yZSwNCiAgeSA9IH5Bbm51YWxSZXR1cm4sDQogIHR5cGUgPSAnc2NhdHRlcicsDQogIG1vZGUgPSAnbWFya2VycycsDQogIG1hcmtlciA9IGxpc3QoY29sb3IgPSAnbGlnaHRwaW5rJywgc2l6ZSA9IDgsIG9wYWNpdHkgPSAwLjcpLA0KICBob3ZlcmluZm8gPSAndGV4dCcsDQogIHRleHQgPSB+cGFzdGUoJ1Jpc2sgU2NvcmU6JywgUmlza1Njb3JlLA0KICAgICAgICAgICAgICAgICc8YnI+QW5udWFsIFJldHVybjonLCBBbm51YWxSZXR1cm4pDQopICU+JQ0KICBhZGRfdHJhY2UoDQogICAgZGF0YSA9IHByZWQsDQogICAgeCA9IH5SaXNrU2NvcmUsDQogICAgeSA9IH5Bbm51YWxSZXR1cm4sDQogICAgdHlwZSA9ICdzY2F0dGVyJywNCiAgICBtb2RlID0gJ2xpbmVzJywNCiAgICBsaW5lID0gbGlzdChjb2xvciA9ICdkYXJrcmVkJywgd2lkdGggPSAyKSwNCiAgICBuYW1lID0gJ1RyZW5kIExpbmUnDQogICkgJT4lDQogIGxheW91dCgNCiAgICB0aXRsZSA9IGxpc3QodGV4dCA9ICJIdWJ1bmdhbiBhbnRhcmEgUmlzayBTY29yZSBkYW4gQW5udWFsIFJldHVybiAoZGVuZ2FuIEdhcmlzIFRyZW4pIiwgeCA9IDAuNSksDQogICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIlJpc2sgU2NvcmUiKSwNCiAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiQW5udWFsIFJldHVybiAoJSkiKSwNCiAgICBwbG90X2JnY29sb3IgPSAiI2Y3ZjlmYiIsDQogICAgcGFwZXJfYmdjb2xvciA9ICIjZjdmOWZiIg0KICApDQoNCmZpZyAgIyB0YW1waWxrYW4gZ3JhZmlrIGludGVyYWt0aWYNCmBgYA0KDQojIyMgSW50ZXJwcmV0YXNpDQpTY2F0dGVyIHBsb3QgbWVudW5qdWtrYW4gaHVidW5nYW4gcG9zaXRpZiBhbnRhcmEgUmlzayBTY29yZSBkYW4gQW5udWFsIFJldHVybi4gUG9sYSBpbmkgbWVuZ2luZGlrYXNpa2FuIGJhaHdhIHNlbWFraW4gdGluZ2dpIHJpc2lrbyB5YW5nIGRpYW1iaWwsIHNlbWFraW4gYmVzYXIgcG90ZW5zaSBpbWJhbCBoYXNpbG55YS4gU2ViYXJhbiB0aXRpayB5YW5nIGN1a3VwIGx1YXMgbWVuYW5kYWthbiBhZGFueWEgdmFyaWFzaSBhdGF1IGRpc3BlcnNpIHRpbmdnaSBwYWRhIGhhc2lsIGludmVzdGFzaS4NCg0KIyBTdW1tYXJ5IGFuZCBJbnRlcnByZXRhdGlvbg0KDQpCZXJkYXNhcmthbiBoYXNpbCBhbmFsaXNpcyBkYXRhIGludmVzdGFzaSwgZGlwZXJvbGVoIGJhaHdhIHZhcmlhYmVsIG51bWVyaWsgeWFuZyBkaWFuYWxpc2lzLCB5YWl0dSBBZ2UgZGFuIEFubnVhbCBSZXR1cm4sIG1lbnVuanVra2FuIGthcmFrdGVyaXN0aWsgcGVueWViYXJhbiB5YW5nIGJlcmJlZGEuIA0KDQotICoqVmFyaWFiZWwgQWdlKiogbWVtaWxpa2kgbmlsYWkgcmF0YS1yYXRhLCBtZWRpYW4sIGRhbiBtb2R1cyB5YW5nIGJlcmRla2F0YW4sIG1lbmFuZGFrYW4gZGlzdHJpYnVzaSB5YW5nIHJlbGF0aWYgc2ltZXRyaXMgdGFucGEgYWRhbnlhIG91dGxpZXIgeWFuZyBzaWduaWZpa2FuLiBIYWwgaW5pIGp1Z2EgZGlkdWt1bmcgb2xlaCBuaWxhaSB2YXJpYW5zLCBzdGFuZGFyIGRldmlhc2ksIGRhbiBJUVIgeWFuZyBrZWNpbCwgc2VoaW5nZ2EgZGFwYXQgZGlzaW1wdWxrYW4gYmFod2EgZGF0YSB1c2lhIGludmVzdG9yIGN1a3VwIGtvbnNpc3RlbiBkYW4gaG9tb2dlbi4NCg0KLSBTZWJhbGlrbnlhLCAqKnZhcmlhYmVsIEFubnVhbCBSZXR1cm4qKiBtZW1pbGlraSBwZXJiZWRhYW4gY3VrdXAgYmVzYXIgYW50YXJhIG5pbGFpIHJhdGEtcmF0YSBkYW4gbWVkaWFuLCB5YW5nIG1lbmdpbmRpa2FzaWthbiBhZGFueWEga2VtZW5jZW5nYW4gKHNrZXduZXNzKSBwYWRhIGRpc3RyaWJ1c2kgZGF0YS4gTmlsYWkgZGlzcGVyc2kgeWFuZyB0aW5nZ2kgbWVudW5qdWtrYW4gYmFod2EgdGluZ2thdCBwZW5nZW1iYWxpYW4gaW52ZXN0YXNpIGFudGFyIGludmVzdG9yIHNhbmdhdCBiZXJ2YXJpYXNpLiBLb25kaXNpIGluaSBkYXBhdCBkaXNlYmFia2FuIG9sZWggcGVyYmVkYWFuIHN0cmF0ZWdpLCB0aW5na2F0IHJpc2lrbywgZGFuIHBlbmdhbGFtYW4gaW52ZXN0YXNpLg0KDQpTZWNhcmEga2VzZWx1cnVoYW4sIGhhc2lsIHZpc3VhbGlzYXNpIGRhbiBhbmFsaXNpcyBzdGF0aXN0aWsgbWVuZ2dhbWJhcmthbiBiYWh3YSBBZ2UgbWVydXBha2FuIHZhcmlhYmVsIHlhbmcgcGFsaW5nIHN0YWJpbCwgc2VkYW5na2FuIEFubnVhbCBSZXR1cm4gbWVudW5qdWtrYW4gdmFyaWFiaWxpdGFzIHBhbGluZyB0aW5nZ2kuIEhhbCBpbmkgbWVtYmVyaWthbiBnYW1iYXJhbiBiYWh3YSBraW5lcmphIGludmVzdGFzaSBsZWJpaCBkaXBlbmdhcnVoaSBvbGVoIGZha3RvciBla3N0ZXJuYWwgZGliYW5kaW5na2FuIGZha3RvciBkZW1vZ3JhZmlzIHNlcGVydGkgdXNpYS4NCg==