Teknik Sampling and Survey
Pertemuan 11
Check Sheet
# Buat data check sheet
check_sheet <- data.frame(
No = 1:20,
Date = c("16/04/2025", "17/04/2025", "18/04/2025", "19/04/2025", "20/04/2025",
"21/04/2025", "22/04/2025", "23/04/2025", "24/04/2025", "25/04/2025",
"26/04/2025", "27/04/2025", "28/04/2025", "29/04/2025", "30/04/2025",
"01/05/2025", "02/05/2025", "03/05/2025", "04/05/2025", "05/05/2025"),
Jenis_Error = c("Login Failed", "Crash", "Crash", "Time", "UI Not Responding",
"Login Failed", "Time", "Crash", "Time", "UI Not Responding",
"Login Failed", "Time", "Crash", "Validation Error", "Login Failed",
"Login Failed", "Time", "Crash", "Validation Error", "UI Not Responding")
)
# Tampilkan tabel
datatable(check_sheet, options = list(pageLength = 5))# Count frequency of each errors
library(dplyr)
library(DT)
error_summary <- check_sheet %>%
count(Jenis_Error, sort = TRUE) %>%
rename(Frequency = n)
# Display summary table
datatable(
error_summary,
options = list(
scrollCollapse = TRUE,
searching = FALSE, # Remove search box
paging = FALSE # Remove pagination
),
rownames = FALSE,
caption = htmltools::tags$caption(
style = 'caption-side: top; text-align: left;
font-size: 18px; font-weight: bold;',
'Check Sheet: Summary of Error'
),
class = 'stripe hover compact'
)library(plotly)
# Interactive bar chart using plotly
plot_ly(error_summary,
x = ~Frequency,
y = ~reorder(Jenis_Error, Frequency),
type = 'bar',
orientation = 'h',
marker = list(
color = ~Frequency,
colorscale = 'Cividis', # Can also try: 'Bluered', '', 'YlOrRd'
showscale = TRUE
)
) %>%
layout(
title = list(text = "Check Sheet: Frequency of Erros", font = list(size = 18)),
xaxis = list(title = "Frequency"),
yaxis = list(title = "Error"),
margin = list(l = 120)
)Control Flow
# Load libraries
library(plotly)
library(dplyr)
# Buat data waktu loading aplikasi
loading_data <- data.frame(
Date = 1:30,
Loading_Time = c(
2.1, 2.0, 2.3, 1.9, 2.2, 2.0, 2.4, 2.1, 2.0, 2.5,
1.8, 2.3, 2.1, 2.0, 2.2, 2.6, 1.9, 2.1, 2.2, 2.0,
2.7, 2.3, 2.0, 2.1, 2.2, 2.0, 2.3, 1.8, 2.4, 2.1
)
)
# Tentukan batas kendali
CL <- 2.1
UCL <- 2.4
LCL <- 1.8
# Tandai outliers
loading_data <- loading_data %>%
mutate(Outlier = ifelse(Loading_Time > UCL | Loading_Time < LCL, "Ya", "Tidak"))
# Buat plot
plot_ly(loading_data, x = ~Date, y = ~Loading_Time, type = 'scatter', mode = 'lines+markers',
line = list(color = 'blue'),
marker = list(size = 8, color = ifelse(loading_data$Outlier == "Ya", "red", "blue")),
hoverinfo = 'text',
text = ~paste("Hari:", Date, "<br>Waktu Loading:", Loading_Time, "detik")) %>%
add_lines(y = rep(CL, 30), name = "CL", line = list(color = 'green', dash = 'dot')) %>%
add_lines(y = rep(UCL, 30), name = "UCL", line = list(color = 'red', dash = 'dot')) %>%
add_lines(y = rep(LCL, 30), name = "LCL", line = list(color = 'red', dash = 'dot')) %>%
layout(title = "Control Chart – Periodic Application Loading Time",
xaxis = list(title = "Hari"),
yaxis = list(title = "Waktu Loading (detik)"),
legend = list(orientation = 'h', x = 0.3, y = -0.2))Fishbone Diagram
# Load library
library(DiagrammeR)
# Create fishbone diagram
graph <- grViz("
digraph fishbone {
graph [layout = dot, rankdir = LR]
# Default node styles
node [fontname=Helvetica, fontsize=25, style=filled]
# Central problem
Problem [label='Main Causes of \\n System Crashes', shape=ellipse, fillcolor=lightcoral, width=5.0, height=1.2]
# Category nodes (shared style)
node [shape=diamond, width=2.5, height=1.0, fillcolor='#FFD700']
A1 [label='Man']
A2 [label='Method']
A3 [label='Machine']
A4 [label='Material']
A5 [label='Environment']
A6 [label='Measurement']
# Reset node style for sub-categories
node [shape=ellipse, width=2.5, height=0.6, fillcolor='#90EE90']
A1a [label='Human error']
A1b [label='Inadequate training']
A1c [label='Overloaded staff']
A2a [label='Poor coding practices']
A2b [label='Lack of testing']
A3a [label='Hardware failure']
A3b [label='Overheating']
A4a [label='Corrupted files']
A4b [label='Incompatible software']
A5a [label='Network instability']
A5b [label='Power outages']
A6a [label='Inaccurate logs']
A6b [label='Faulty monitoring tools']
# Relationships
A1 -> Problem
A2 -> Problem
A3 -> Problem
A4 -> Problem
A5 -> Problem
A6 -> Problem
A1a -> A1
A1b -> A1
A1c -> A1
A2a -> A2
A2b -> A2
A3a -> A3
A3b -> A3
A4a -> A4
A4b -> A4
A5a -> A5
A5b -> A5
A6a -> A6
A6b -> A6
}
")
# Tampilkan diagram langsung
graphFlowchart
# Load library
library(DiagrammeR)
# Create flowchart
graph <- grViz("
digraph development_flow {
graph [layout = dot, rankdir = TB]
# Default node styles
node [fontname=Helvetica, fontsize=12, style=filled]
# Start node
Start [label='Start', shape=circle, fillcolor=lightblue]
# Process nodes
Idea [label='Idea', shape=parallelogram, fillcolor=Blue, width=2.5]
Coding [label='Coding', shape=box, fillcolor=orange, width=2.5]
Testing [label='Testing', shape=box, fillcolor=orange, width=2.5]
Deploy [label='Deploy', shape=box, fillcolor=orange, width=2.5]
# Decision node
Decision1 [label='Code Passes Tests?', shape=diamond, fillcolor=lightcoral, width=2.5]
Decision2 [label='Deployment Successful?', shape=diamond, fillcolor=lightcoral, width=2.5]
# End node
Finish [label='Finish', shape=circle, fillcolor=lightgray]
# Relationships
Start -> Idea
Idea -> Coding
Coding -> Testing
Testing -> Decision1
Decision1 -> Deploy [label='Yes']
Decision1 -> Coding [label='No']
Deploy -> Decision2
Decision2 -> Finish [label='Yes']
Decision2 -> Testing [label='No']
# Optional note
Note [label='Note: Confirmed by QA Team', shape=note, fillcolor=lightyellow]
Decision2 -> Note
}
")
# Tampilkan diagram langsung
graphHistogram
# Load required library
library(plotly)
# Simulate Chrome-only error data
set.seed(123)
chrome_data <- data.frame(
Errors = rnorm(200, mean = 8, sd = 2)
)
# Plot interactive histogram using Plotly
plot_ly(
data = chrome_data,
x = ~Errors,
type = 'histogram',
nbinsx = 20,
marker = list(color = '#1f77b4', line = list(color = 'black', width = 1)),
opacity = 0.75
) %>%
layout(
title = "Histogram of Errors – Chrome Browser",
xaxis = list(title = "Number of Errors"),
yaxis = list(title = "Frequency"),
bargap = 0.1,
plot_bgcolor = 'white',
paper_bgcolor = 'white'
)Pareto Chart
# Load libraries
library(dplyr)
library(plotly)
# Create simulated data for bugs causing system disruptions
check_sheet <- data.frame(
Bug_Type = c(
rep("Memory Leak", 40), rep("Null Pointer", 30),
rep("API Failure", 15), rep("UI Freeze", 10),
rep("Database Error", 5)
)
)
# Summarize the number of disruptions by bug type
pareto_data <- check_sheet %>%
count(Bug_Type, sort = TRUE) %>%
mutate(
cum_freq = cumsum(n) / sum(n) * 100 # cumulative percentage
)
# Create different colors for each Bug Type
colors <- RColorBrewer::brewer.pal(n = length(pareto_data$Bug_Type), name = "Set3")
# Create Plotly Pareto Chart
fig <- plot_ly()
# Add Bar Chart (Count) - with different colors
fig <- fig %>% add_bars(
x = ~reorder(pareto_data$Bug_Type, -pareto_data$n),
y = ~pareto_data$n,
name = 'Number of Disruptions',
marker = list(color = colors),
yaxis = "y1"
)
# Add Cumulative Line
fig <- fig %>% add_lines(
x = ~reorder(pareto_data$Bug_Type, -pareto_data$n),
y = ~pareto_data$cum_freq,
name = 'Cumulative (%)',
yaxis = "y2",
line = list(color = 'red', dash = 'dash')
)
# Add Cut-off Line at 80%
fig <- fig %>% add_lines(
x = ~reorder(pareto_data$Bug_Type, -pareto_data$n),
y = rep(80, length(pareto_data$Bug_Type)),
name = 'Cut-off 80%',
yaxis = "y2",
line = list(color = 'green', dash = 'dot')
)
# Adjust layout
fig <- fig %>% layout(
title = "Pareto Chart - Bugs Causing System Disruptions",
xaxis = list(
title = "Bug Types",
tickangle = -45 # tilt 45 degrees
),
yaxis = list(title = "Number of Disruptions"),
yaxis2 = list(
title = "Cumulative (%)",
overlaying = "y",
side = "right",
range = c(0, 100)
),
legend = list(x = 0.8, y = 0.75),
shapes = list(
list(
type = "line",
x0 = -0.5,
x1 = length(pareto_data$Bug_Type) - 0.5,
y0 = 80,
y1 = 80,
yref = "y2",
line = list(color = "green", width = 2, dash = "dot")
)
)
)
# Show chart
figScatter Diagram
# Load the required library
library(plotly)
# Set seed for reproducibility
set.seed(123)
# Create data with strong positive correlation
data <- data.frame(
Active_Users = seq(100, 1000, by = 50),
Response_Time = seq(100, 300, length.out = 19) + rnorm(19, mean = 0, sd = 10)
)
# Calculate the correlation coefficient
correlation_value <- cor(data$Active_Users, data$Response_Time)
# Create scatter plot with regression line
fig <- plot_ly(data,
x = ~Active_Users,
y = ~Response_Time,
type = 'scatter',
mode = 'markers',
marker = list(color = 'darkblue', size = 10)) %>%
add_lines(x = data$Active_Users,
y = predict(lm(Response_Time ~ Active_Users, data = data)),
line = list(color = 'red', dash = 'solid', width = 2)) %>%
layout(title = paste("Scatter Diagram: Active Users vs Server Response Time\nCorrelation: ", round(correlation_value, 2)),
xaxis = list(title = "Number of Active Users"),
yaxis = list(title = "Server Response Time (ms)"))
# Show the plot
figLS0tDQp0aXRsZTogIlRla25payBTYW1wbGluZyBhbmQgU3VydmV5Ig0Kc3VidGl0bGU6ICJQZXJ0ZW11YW4gMTEiDQphdXRob3I6IA0KICAtICJaYWluIElxYmFsIFNhcHV0cmFfNTIyNDAwMTgiDQogIC0gIkNoZWxsbyBGcmhpbm8gTWlrZSBNXzUyMjQwMDMxIg0KZGF0ZTogICJTZW5pbiwgMDUvMDUvMjAyNSINCm91dHB1dDoNCiAgcm1kZm9ybWF0czo6cmVhZHRoZWRvd246ICAgDQogICAgc2VsZl9jb250YWluZWQ6IHRydWUNCiAgICB0aHVtYm5haWxzOiB0cnVlDQogICAgbGlnaHRib3g6IHRydWUNCiAgICBnYWxsZXJ5OiB0cnVlDQogICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQ0KICAgIGxpYl9kaXI6IGxpYnMNCiAgICAzZGZfcHJpbnQ6ICJwYWdlZCINCiAgICBjb2RlX2ZvbGRpbmc6ICJzaG93Ig0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KLS0tDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoRFQpDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkoc3RyaW5naSkNCmxpYnJhcnkobHVicmlkYXRlKQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkocmVhZHIpDQpgYGANCg0KIyBDaGVjayBTaGVldA0KDQpgYGB7cixtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0V9DQojIEJ1YXQgZGF0YSBjaGVjayBzaGVldA0KY2hlY2tfc2hlZXQgPC0gZGF0YS5mcmFtZSgNCiAgTm8gPSAxOjIwLA0KICBEYXRlID0gYygiMTYvMDQvMjAyNSIsICIxNy8wNC8yMDI1IiwgIjE4LzA0LzIwMjUiLCAiMTkvMDQvMjAyNSIsICIyMC8wNC8yMDI1IiwNCiAgICAgICAgICAgIjIxLzA0LzIwMjUiLCAiMjIvMDQvMjAyNSIsICIyMy8wNC8yMDI1IiwgIjI0LzA0LzIwMjUiLCAiMjUvMDQvMjAyNSIsDQogICAgICAgICAgICIyNi8wNC8yMDI1IiwgIjI3LzA0LzIwMjUiLCAiMjgvMDQvMjAyNSIsICIyOS8wNC8yMDI1IiwgIjMwLzA0LzIwMjUiLA0KICAgICAgICAgICAiMDEvMDUvMjAyNSIsICIwMi8wNS8yMDI1IiwgIjAzLzA1LzIwMjUiLCAiMDQvMDUvMjAyNSIsICIwNS8wNS8yMDI1IiksDQogIEplbmlzX0Vycm9yID0gYygiTG9naW4gRmFpbGVkIiwgIkNyYXNoIiwgIkNyYXNoIiwgIlRpbWUiLCAiVUkgTm90IFJlc3BvbmRpbmciLA0KICAgICAgICAgICAgICAgICAgIkxvZ2luIEZhaWxlZCIsICJUaW1lIiwgIkNyYXNoIiwgIlRpbWUiLCAiVUkgTm90IFJlc3BvbmRpbmciLA0KICAgICAgICAgICAgICAgICAgIkxvZ2luIEZhaWxlZCIsICJUaW1lIiwgIkNyYXNoIiwgIlZhbGlkYXRpb24gRXJyb3IiLCAiTG9naW4gRmFpbGVkIiwNCiAgICAgICAgICAgICAgICAgICJMb2dpbiBGYWlsZWQiLCAiVGltZSIsICJDcmFzaCIsICJWYWxpZGF0aW9uIEVycm9yIiwgIlVJIE5vdCBSZXNwb25kaW5nIikNCikNCg0KIyBUYW1waWxrYW4gdGFiZWwNCmRhdGF0YWJsZShjaGVja19zaGVldCwgb3B0aW9ucyA9IGxpc3QocGFnZUxlbmd0aCA9IDUpKQ0KYGBgDQoNCg0KYGBge3IsbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFfQ0KIyBDb3VudCBmcmVxdWVuY3kgb2YgZWFjaCBlcnJvcnMNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KERUKQ0KDQplcnJvcl9zdW1tYXJ5IDwtIGNoZWNrX3NoZWV0ICU+JQ0KICBjb3VudChKZW5pc19FcnJvciwgc29ydCA9IFRSVUUpICU+JQ0KICByZW5hbWUoRnJlcXVlbmN5ID0gbikNCg0KIyBEaXNwbGF5IHN1bW1hcnkgdGFibGUNCmRhdGF0YWJsZSgNCiAgZXJyb3Jfc3VtbWFyeSwNCiAgb3B0aW9ucyA9IGxpc3QoDQogICAgc2Nyb2xsQ29sbGFwc2UgPSBUUlVFLA0KICAgIHNlYXJjaGluZyA9IEZBTFNFLCAgICMgUmVtb3ZlIHNlYXJjaCBib3gNCiAgICBwYWdpbmcgPSBGQUxTRSAgICAgICAjIFJlbW92ZSBwYWdpbmF0aW9uDQogICksDQogIHJvd25hbWVzID0gRkFMU0UsDQogIGNhcHRpb24gPSBodG1sdG9vbHM6OnRhZ3MkY2FwdGlvbigNCiAgICBzdHlsZSA9ICdjYXB0aW9uLXNpZGU6IHRvcDsgdGV4dC1hbGlnbjogbGVmdDsgDQogICAgICAgICAgICAgZm9udC1zaXplOiAxOHB4OyBmb250LXdlaWdodDogYm9sZDsnLA0KICAgICdDaGVjayBTaGVldDogU3VtbWFyeSBvZiBFcnJvcicNCiAgKSwNCiAgY2xhc3MgPSAnc3RyaXBlIGhvdmVyIGNvbXBhY3QnDQopDQpgYGANCg0KYGBge3IsbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShwbG90bHkpDQoNCiMgSW50ZXJhY3RpdmUgYmFyIGNoYXJ0IHVzaW5nIHBsb3RseQ0KcGxvdF9seShlcnJvcl9zdW1tYXJ5LA0KICAgICAgICB4ID0gfkZyZXF1ZW5jeSwNCiAgICAgICAgeSA9IH5yZW9yZGVyKEplbmlzX0Vycm9yLCBGcmVxdWVuY3kpLA0KICAgICAgICB0eXBlID0gJ2JhcicsDQogICAgICAgIG9yaWVudGF0aW9uID0gJ2gnLA0KICAgICAgICBtYXJrZXIgPSBsaXN0KA0KICAgICAgICAgIGNvbG9yID0gfkZyZXF1ZW5jeSwNCiAgICAgICAgICBjb2xvcnNjYWxlID0gJ0NpdmlkaXMnLCAgIyBDYW4gYWxzbyB0cnk6ICdCbHVlcmVkJywgJycsICdZbE9yUmQnDQogICAgICAgICAgc2hvd3NjYWxlID0gVFJVRQ0KICAgICAgICApDQopICU+JQ0KICBsYXlvdXQoDQogICAgdGl0bGUgPSBsaXN0KHRleHQgPSAiQ2hlY2sgU2hlZXQ6IEZyZXF1ZW5jeSBvZiBFcnJvcyIsIGZvbnQgPSBsaXN0KHNpemUgPSAxOCkpLA0KICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICJGcmVxdWVuY3kiKSwNCiAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiRXJyb3IiKSwNCiAgICBtYXJnaW4gPSBsaXN0KGwgPSAxMjApDQogICkNCmBgYA0KDQojIENvbnRyb2wgRmxvdw0KDQpgYGB7cixtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0V9DQojIExvYWQgbGlicmFyaWVzDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkoZHBseXIpDQoNCiMgQnVhdCBkYXRhIHdha3R1IGxvYWRpbmcgYXBsaWthc2kNCmxvYWRpbmdfZGF0YSA8LSBkYXRhLmZyYW1lKA0KICBEYXRlID0gMTozMCwNCiAgTG9hZGluZ19UaW1lID0gYygNCiAgICAyLjEsIDIuMCwgMi4zLCAxLjksIDIuMiwgMi4wLCAyLjQsIDIuMSwgMi4wLCAyLjUsDQogICAgMS44LCAyLjMsIDIuMSwgMi4wLCAyLjIsIDIuNiwgMS45LCAyLjEsIDIuMiwgMi4wLA0KICAgIDIuNywgMi4zLCAyLjAsIDIuMSwgMi4yLCAyLjAsIDIuMywgMS44LCAyLjQsIDIuMQ0KICApDQopDQoNCiMgVGVudHVrYW4gYmF0YXMga2VuZGFsaQ0KQ0wgPC0gMi4xDQpVQ0wgPC0gMi40DQpMQ0wgPC0gMS44DQoNCiMgVGFuZGFpIG91dGxpZXJzDQpsb2FkaW5nX2RhdGEgPC0gbG9hZGluZ19kYXRhICU+JQ0KICBtdXRhdGUoT3V0bGllciA9IGlmZWxzZShMb2FkaW5nX1RpbWUgPiBVQ0wgfCBMb2FkaW5nX1RpbWUgPCBMQ0wsICJZYSIsICJUaWRhayIpKQ0KDQojIEJ1YXQgcGxvdA0KcGxvdF9seShsb2FkaW5nX2RhdGEsIHggPSB+RGF0ZSwgeSA9IH5Mb2FkaW5nX1RpbWUsIHR5cGUgPSAnc2NhdHRlcicsIG1vZGUgPSAnbGluZXMrbWFya2VycycsDQogICAgICAgIGxpbmUgPSBsaXN0KGNvbG9yID0gJ2JsdWUnKSwgDQogICAgICAgIG1hcmtlciA9IGxpc3Qoc2l6ZSA9IDgsIGNvbG9yID0gaWZlbHNlKGxvYWRpbmdfZGF0YSRPdXRsaWVyID09ICJZYSIsICJyZWQiLCAiYmx1ZSIpKSwNCiAgICAgICAgaG92ZXJpbmZvID0gJ3RleHQnLA0KICAgICAgICB0ZXh0ID0gfnBhc3RlKCJIYXJpOiIsIERhdGUsICI8YnI+V2FrdHUgTG9hZGluZzoiLCBMb2FkaW5nX1RpbWUsICJkZXRpayIpKSAlPiUNCiAgYWRkX2xpbmVzKHkgPSByZXAoQ0wsIDMwKSwgbmFtZSA9ICJDTCIsIGxpbmUgPSBsaXN0KGNvbG9yID0gJ2dyZWVuJywgZGFzaCA9ICdkb3QnKSkgJT4lDQogIGFkZF9saW5lcyh5ID0gcmVwKFVDTCwgMzApLCBuYW1lID0gIlVDTCIsIGxpbmUgPSBsaXN0KGNvbG9yID0gJ3JlZCcsIGRhc2ggPSAnZG90JykpICU+JQ0KICBhZGRfbGluZXMoeSA9IHJlcChMQ0wsIDMwKSwgbmFtZSA9ICJMQ0wiLCBsaW5lID0gbGlzdChjb2xvciA9ICdyZWQnLCBkYXNoID0gJ2RvdCcpKSAlPiUNCiAgbGF5b3V0KHRpdGxlID0gIkNvbnRyb2wgQ2hhcnQg4oCTIFBlcmlvZGljIEFwcGxpY2F0aW9uIExvYWRpbmcgVGltZSIsDQogICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiSGFyaSIpLA0KICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIldha3R1IExvYWRpbmcgKGRldGlrKSIpLA0KICAgICAgICAgbGVnZW5kID0gbGlzdChvcmllbnRhdGlvbiA9ICdoJywgeCA9IDAuMywgeSA9IC0wLjIpKQ0KYGBgDQoNCiMgRmlzaGJvbmUgRGlhZ3JhbQ0KDQpgYGB7cixtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0V9DQojIExvYWQgbGlicmFyeQ0KbGlicmFyeShEaWFncmFtbWVSKQ0KDQojIENyZWF0ZSBmaXNoYm9uZSBkaWFncmFtDQpncmFwaCA8LSBnclZpeigiDQpkaWdyYXBoIGZpc2hib25lIHsNCiAgZ3JhcGggW2xheW91dCA9IGRvdCwgcmFua2RpciA9IExSXQ0KDQogICMgRGVmYXVsdCBub2RlIHN0eWxlcw0KICBub2RlIFtmb250bmFtZT1IZWx2ZXRpY2EsIGZvbnRzaXplPTI1LCBzdHlsZT1maWxsZWRdDQoNCiAgIyBDZW50cmFsIHByb2JsZW0NCiAgUHJvYmxlbSBbbGFiZWw9J01haW4gQ2F1c2VzIG9mIFxcbiBTeXN0ZW0gQ3Jhc2hlcycsIHNoYXBlPWVsbGlwc2UsIGZpbGxjb2xvcj1saWdodGNvcmFsLCB3aWR0aD01LjAsIGhlaWdodD0xLjJdDQoNCiAgIyBDYXRlZ29yeSBub2RlcyAoc2hhcmVkIHN0eWxlKQ0KICBub2RlIFtzaGFwZT1kaWFtb25kLCB3aWR0aD0yLjUsIGhlaWdodD0xLjAsIGZpbGxjb2xvcj0nI0ZGRDcwMCddDQogIEExIFtsYWJlbD0nTWFuJ10NCiAgQTIgW2xhYmVsPSdNZXRob2QnXQ0KICBBMyBbbGFiZWw9J01hY2hpbmUnXQ0KICBBNCBbbGFiZWw9J01hdGVyaWFsJ10NCiAgQTUgW2xhYmVsPSdFbnZpcm9ubWVudCddDQogIEE2IFtsYWJlbD0nTWVhc3VyZW1lbnQnXQ0KDQogICMgUmVzZXQgbm9kZSBzdHlsZSBmb3Igc3ViLWNhdGVnb3JpZXMNCiAgbm9kZSBbc2hhcGU9ZWxsaXBzZSwgd2lkdGg9Mi41LCBoZWlnaHQ9MC42LCBmaWxsY29sb3I9JyM5MEVFOTAnXQ0KICBBMWEgW2xhYmVsPSdIdW1hbiBlcnJvciddDQogIEExYiBbbGFiZWw9J0luYWRlcXVhdGUgdHJhaW5pbmcnXQ0KICBBMWMgW2xhYmVsPSdPdmVybG9hZGVkIHN0YWZmJ10NCg0KICBBMmEgW2xhYmVsPSdQb29yIGNvZGluZyBwcmFjdGljZXMnXQ0KICBBMmIgW2xhYmVsPSdMYWNrIG9mIHRlc3RpbmcnXQ0KDQogIEEzYSBbbGFiZWw9J0hhcmR3YXJlIGZhaWx1cmUnXQ0KICBBM2IgW2xhYmVsPSdPdmVyaGVhdGluZyddDQoNCiAgQTRhIFtsYWJlbD0nQ29ycnVwdGVkIGZpbGVzJ10NCiAgQTRiIFtsYWJlbD0nSW5jb21wYXRpYmxlIHNvZnR3YXJlJ10NCg0KICBBNWEgW2xhYmVsPSdOZXR3b3JrIGluc3RhYmlsaXR5J10NCiAgQTViIFtsYWJlbD0nUG93ZXIgb3V0YWdlcyddDQoNCiAgQTZhIFtsYWJlbD0nSW5hY2N1cmF0ZSBsb2dzJ10NCiAgQTZiIFtsYWJlbD0nRmF1bHR5IG1vbml0b3JpbmcgdG9vbHMnXQ0KDQogICMgUmVsYXRpb25zaGlwcw0KICBBMSAtPiBQcm9ibGVtDQogIEEyIC0+IFByb2JsZW0NCiAgQTMgLT4gUHJvYmxlbQ0KICBBNCAtPiBQcm9ibGVtDQogIEE1IC0+IFByb2JsZW0NCiAgQTYgLT4gUHJvYmxlbQ0KDQogIEExYSAtPiBBMQ0KICBBMWIgLT4gQTENCiAgQTFjIC0+IEExDQoNCiAgQTJhIC0+IEEyDQogIEEyYiAtPiBBMg0KDQogIEEzYSAtPiBBMw0KICBBM2IgLT4gQTMNCg0KICBBNGEgLT4gQTQNCiAgQTRiIC0+IEE0DQoNCiAgQTVhIC0+IEE1DQogIEE1YiAtPiBBNQ0KDQogIEE2YSAtPiBBNg0KICBBNmIgLT4gQTYNCn0NCiIpDQoNCiMgVGFtcGlsa2FuIGRpYWdyYW0gbGFuZ3N1bmcNCmdyYXBoDQoNCiMgT3BzaW9uYWw6IFNpbXBhbiBzZWJhZ2FpIGZpbGUgSFRNTCBpbnRlcmFrdGlmDQojIGh0bWx3aWRnZXRzOjpzYXZlV2lkZ2V0KGdyYXBoLCAiZmlzaGJvbmVfc3lzdGVtX2NyYXNoZXMuaHRtbCIpDQpgYGANCg0KIyBGbG93Y2hhcnQNCg0KYGBge3IsbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFfQ0KIyBMb2FkIGxpYnJhcnkNCmxpYnJhcnkoRGlhZ3JhbW1lUikNCg0KIyBDcmVhdGUgZmxvd2NoYXJ0DQpncmFwaCA8LSBnclZpeigiDQpkaWdyYXBoIGRldmVsb3BtZW50X2Zsb3cgew0KICBncmFwaCBbbGF5b3V0ID0gZG90LCByYW5rZGlyID0gVEJdDQoNCiAgIyBEZWZhdWx0IG5vZGUgc3R5bGVzDQogIG5vZGUgW2ZvbnRuYW1lPUhlbHZldGljYSwgZm9udHNpemU9MTIsIHN0eWxlPWZpbGxlZF0NCg0KICAjIFN0YXJ0IG5vZGUNCiAgU3RhcnQgW2xhYmVsPSdTdGFydCcsIHNoYXBlPWNpcmNsZSwgZmlsbGNvbG9yPWxpZ2h0Ymx1ZV0NCg0KICAjIFByb2Nlc3Mgbm9kZXMNCiAgSWRlYSBbbGFiZWw9J0lkZWEnLCBzaGFwZT1wYXJhbGxlbG9ncmFtLCBmaWxsY29sb3I9Qmx1ZSwgd2lkdGg9Mi41XQ0KICBDb2RpbmcgW2xhYmVsPSdDb2RpbmcnLCBzaGFwZT1ib3gsIGZpbGxjb2xvcj1vcmFuZ2UsIHdpZHRoPTIuNV0NCiAgVGVzdGluZyBbbGFiZWw9J1Rlc3RpbmcnLCBzaGFwZT1ib3gsIGZpbGxjb2xvcj1vcmFuZ2UsIHdpZHRoPTIuNV0NCiAgRGVwbG95IFtsYWJlbD0nRGVwbG95Jywgc2hhcGU9Ym94LCBmaWxsY29sb3I9b3JhbmdlLCB3aWR0aD0yLjVdDQoNCiAgIyBEZWNpc2lvbiBub2RlDQogIERlY2lzaW9uMSBbbGFiZWw9J0NvZGUgUGFzc2VzIFRlc3RzPycsIHNoYXBlPWRpYW1vbmQsIGZpbGxjb2xvcj1saWdodGNvcmFsLCB3aWR0aD0yLjVdDQogIERlY2lzaW9uMiBbbGFiZWw9J0RlcGxveW1lbnQgU3VjY2Vzc2Z1bD8nLCBzaGFwZT1kaWFtb25kLCBmaWxsY29sb3I9bGlnaHRjb3JhbCwgd2lkdGg9Mi41XQ0KDQogICMgRW5kIG5vZGUNCiAgRmluaXNoIFtsYWJlbD0nRmluaXNoJywgc2hhcGU9Y2lyY2xlLCBmaWxsY29sb3I9bGlnaHRncmF5XQ0KDQogICMgUmVsYXRpb25zaGlwcw0KICBTdGFydCAtPiBJZGVhDQogIElkZWEgLT4gQ29kaW5nDQogIENvZGluZyAtPiBUZXN0aW5nDQogIFRlc3RpbmcgLT4gRGVjaXNpb24xDQogIERlY2lzaW9uMSAtPiBEZXBsb3kgW2xhYmVsPSdZZXMnXQ0KICBEZWNpc2lvbjEgLT4gQ29kaW5nIFtsYWJlbD0nTm8nXQ0KICBEZXBsb3kgLT4gRGVjaXNpb24yDQogIERlY2lzaW9uMiAtPiBGaW5pc2ggW2xhYmVsPSdZZXMnXQ0KICBEZWNpc2lvbjIgLT4gVGVzdGluZyBbbGFiZWw9J05vJ10NCg0KICAjIE9wdGlvbmFsIG5vdGUNCiAgTm90ZSBbbGFiZWw9J05vdGU6IENvbmZpcm1lZCBieSBRQSBUZWFtJywgc2hhcGU9bm90ZSwgZmlsbGNvbG9yPWxpZ2h0eWVsbG93XQ0KICBEZWNpc2lvbjIgLT4gTm90ZQ0KfQ0KIikNCg0KIyBUYW1waWxrYW4gZGlhZ3JhbSBsYW5nc3VuZw0KZ3JhcGgNCmBgYA0KDQojIEhpc3RvZ3JhbQ0KDQpgYGB7cixtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0V9DQojIExvYWQgcmVxdWlyZWQgbGlicmFyeQ0KbGlicmFyeShwbG90bHkpDQoNCiMgU2ltdWxhdGUgQ2hyb21lLW9ubHkgZXJyb3IgZGF0YQ0Kc2V0LnNlZWQoMTIzKQ0KY2hyb21lX2RhdGEgPC0gZGF0YS5mcmFtZSgNCiAgRXJyb3JzID0gcm5vcm0oMjAwLCBtZWFuID0gOCwgc2QgPSAyKQ0KKQ0KDQojIFBsb3QgaW50ZXJhY3RpdmUgaGlzdG9ncmFtIHVzaW5nIFBsb3RseQ0KcGxvdF9seSgNCiAgZGF0YSA9IGNocm9tZV9kYXRhLA0KICB4ID0gfkVycm9ycywNCiAgdHlwZSA9ICdoaXN0b2dyYW0nLA0KICBuYmluc3ggPSAyMCwNCiAgbWFya2VyID0gbGlzdChjb2xvciA9ICcjMWY3N2I0JywgbGluZSA9IGxpc3QoY29sb3IgPSAnYmxhY2snLCB3aWR0aCA9IDEpKSwNCiAgb3BhY2l0eSA9IDAuNzUNCikgJT4lDQogIGxheW91dCgNCiAgICB0aXRsZSA9ICJIaXN0b2dyYW0gb2YgRXJyb3JzIOKAkyBDaHJvbWUgQnJvd3NlciIsDQogICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIk51bWJlciBvZiBFcnJvcnMiKSwNCiAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiRnJlcXVlbmN5IiksDQogICAgYmFyZ2FwID0gMC4xLA0KICAgIHBsb3RfYmdjb2xvciA9ICd3aGl0ZScsDQogICAgcGFwZXJfYmdjb2xvciA9ICd3aGl0ZScNCiAgKQ0KYGBgDQoNCiMgUGFyZXRvIENoYXJ0DQoNCmBgYHtyLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRX0NCiMgTG9hZCBsaWJyYXJpZXMNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHBsb3RseSkNCg0KIyBDcmVhdGUgc2ltdWxhdGVkIGRhdGEgZm9yIGJ1Z3MgY2F1c2luZyBzeXN0ZW0gZGlzcnVwdGlvbnMNCmNoZWNrX3NoZWV0IDwtIGRhdGEuZnJhbWUoDQogIEJ1Z19UeXBlID0gYygNCiAgICByZXAoIk1lbW9yeSBMZWFrIiwgNDApLCByZXAoIk51bGwgUG9pbnRlciIsIDMwKSwgDQogICAgcmVwKCJBUEkgRmFpbHVyZSIsIDE1KSwgcmVwKCJVSSBGcmVlemUiLCAxMCksIA0KICAgIHJlcCgiRGF0YWJhc2UgRXJyb3IiLCA1KQ0KICApDQopDQoNCiMgU3VtbWFyaXplIHRoZSBudW1iZXIgb2YgZGlzcnVwdGlvbnMgYnkgYnVnIHR5cGUNCnBhcmV0b19kYXRhIDwtIGNoZWNrX3NoZWV0ICU+JQ0KICBjb3VudChCdWdfVHlwZSwgc29ydCA9IFRSVUUpICU+JQ0KICBtdXRhdGUoDQogICAgY3VtX2ZyZXEgPSBjdW1zdW0obikgLyBzdW0obikgKiAxMDAgICMgY3VtdWxhdGl2ZSBwZXJjZW50YWdlDQogICkNCg0KIyBDcmVhdGUgZGlmZmVyZW50IGNvbG9ycyBmb3IgZWFjaCBCdWcgVHlwZQ0KY29sb3JzIDwtIFJDb2xvckJyZXdlcjo6YnJld2VyLnBhbChuID0gbGVuZ3RoKHBhcmV0b19kYXRhJEJ1Z19UeXBlKSwgbmFtZSA9ICJTZXQzIikNCg0KIyBDcmVhdGUgUGxvdGx5IFBhcmV0byBDaGFydA0KZmlnIDwtIHBsb3RfbHkoKQ0KDQojIEFkZCBCYXIgQ2hhcnQgKENvdW50KSAtIHdpdGggZGlmZmVyZW50IGNvbG9ycw0KZmlnIDwtIGZpZyAlPiUgYWRkX2JhcnMoDQogIHggPSB+cmVvcmRlcihwYXJldG9fZGF0YSRCdWdfVHlwZSwgLXBhcmV0b19kYXRhJG4pLA0KICB5ID0gfnBhcmV0b19kYXRhJG4sDQogIG5hbWUgPSAnTnVtYmVyIG9mIERpc3J1cHRpb25zJywNCiAgbWFya2VyID0gbGlzdChjb2xvciA9IGNvbG9ycyksDQogIHlheGlzID0gInkxIg0KKQ0KDQojIEFkZCBDdW11bGF0aXZlIExpbmUNCmZpZyA8LSBmaWcgJT4lIGFkZF9saW5lcygNCiAgeCA9IH5yZW9yZGVyKHBhcmV0b19kYXRhJEJ1Z19UeXBlLCAtcGFyZXRvX2RhdGEkbiksDQogIHkgPSB+cGFyZXRvX2RhdGEkY3VtX2ZyZXEsDQogIG5hbWUgPSAnQ3VtdWxhdGl2ZSAoJSknLA0KICB5YXhpcyA9ICJ5MiIsDQogIGxpbmUgPSBsaXN0KGNvbG9yID0gJ3JlZCcsIGRhc2ggPSAnZGFzaCcpDQopDQoNCiMgQWRkIEN1dC1vZmYgTGluZSBhdCA4MCUNCmZpZyA8LSBmaWcgJT4lIGFkZF9saW5lcygNCiAgeCA9IH5yZW9yZGVyKHBhcmV0b19kYXRhJEJ1Z19UeXBlLCAtcGFyZXRvX2RhdGEkbiksDQogIHkgPSByZXAoODAsIGxlbmd0aChwYXJldG9fZGF0YSRCdWdfVHlwZSkpLA0KICBuYW1lID0gJ0N1dC1vZmYgODAlJywNCiAgeWF4aXMgPSAieTIiLA0KICBsaW5lID0gbGlzdChjb2xvciA9ICdncmVlbicsIGRhc2ggPSAnZG90JykNCikNCg0KIyBBZGp1c3QgbGF5b3V0DQpmaWcgPC0gZmlnICU+JSBsYXlvdXQoDQogIHRpdGxlID0gIlBhcmV0byBDaGFydCAtIEJ1Z3MgQ2F1c2luZyBTeXN0ZW0gRGlzcnVwdGlvbnMiLA0KICB4YXhpcyA9IGxpc3QoDQogICAgdGl0bGUgPSAiQnVnIFR5cGVzIiwNCiAgICB0aWNrYW5nbGUgPSAtNDUgICAjIHRpbHQgNDUgZGVncmVlcw0KICApLA0KICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiTnVtYmVyIG9mIERpc3J1cHRpb25zIiksDQogIHlheGlzMiA9IGxpc3QoDQogICAgdGl0bGUgPSAiQ3VtdWxhdGl2ZSAoJSkiLA0KICAgIG92ZXJsYXlpbmcgPSAieSIsDQogICAgc2lkZSA9ICJyaWdodCIsDQogICAgcmFuZ2UgPSBjKDAsIDEwMCkNCiAgKSwNCiAgbGVnZW5kID0gbGlzdCh4ID0gMC44LCB5ID0gMC43NSksDQogIHNoYXBlcyA9IGxpc3QoDQogICAgbGlzdCgNCiAgICAgIHR5cGUgPSAibGluZSIsDQogICAgICB4MCA9IC0wLjUsDQogICAgICB4MSA9IGxlbmd0aChwYXJldG9fZGF0YSRCdWdfVHlwZSkgLSAwLjUsDQogICAgICB5MCA9IDgwLA0KICAgICAgeTEgPSA4MCwNCiAgICAgIHlyZWYgPSAieTIiLA0KICAgICAgbGluZSA9IGxpc3QoY29sb3IgPSAiZ3JlZW4iLCB3aWR0aCA9IDIsIGRhc2ggPSAiZG90IikNCiAgICApDQogICkNCikNCg0KIyBTaG93IGNoYXJ0DQpmaWcNCmBgYA0KDQojIFNjYXR0ZXIgRGlhZ3JhbQ0KDQpgYGB7cixtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0V9DQojIExvYWQgdGhlIHJlcXVpcmVkIGxpYnJhcnkNCmxpYnJhcnkocGxvdGx5KQ0KDQojIFNldCBzZWVkIGZvciByZXByb2R1Y2liaWxpdHkNCnNldC5zZWVkKDEyMykNCg0KIyBDcmVhdGUgZGF0YSB3aXRoIHN0cm9uZyBwb3NpdGl2ZSBjb3JyZWxhdGlvbg0KZGF0YSA8LSBkYXRhLmZyYW1lKA0KICBBY3RpdmVfVXNlcnMgPSBzZXEoMTAwLCAxMDAwLCBieSA9IDUwKSwNCiAgUmVzcG9uc2VfVGltZSA9IHNlcSgxMDAsIDMwMCwgbGVuZ3RoLm91dCA9IDE5KSArIHJub3JtKDE5LCBtZWFuID0gMCwgc2QgPSAxMCkNCikNCg0KIyBDYWxjdWxhdGUgdGhlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50DQpjb3JyZWxhdGlvbl92YWx1ZSA8LSBjb3IoZGF0YSRBY3RpdmVfVXNlcnMsIGRhdGEkUmVzcG9uc2VfVGltZSkNCg0KIyBDcmVhdGUgc2NhdHRlciBwbG90IHdpdGggcmVncmVzc2lvbiBsaW5lDQpmaWcgPC0gcGxvdF9seShkYXRhLCANCiAgICAgICAgICAgICAgIHggPSB+QWN0aXZlX1VzZXJzLCANCiAgICAgICAgICAgICAgIHkgPSB+UmVzcG9uc2VfVGltZSwgDQogICAgICAgICAgICAgICB0eXBlID0gJ3NjYXR0ZXInLCANCiAgICAgICAgICAgICAgIG1vZGUgPSAnbWFya2VycycsDQogICAgICAgICAgICAgICBtYXJrZXIgPSBsaXN0KGNvbG9yID0gJ2RhcmtibHVlJywgc2l6ZSA9IDEwKSkgJT4lDQogIGFkZF9saW5lcyh4ID0gZGF0YSRBY3RpdmVfVXNlcnMsIA0KICAgICAgICAgICAgeSA9IHByZWRpY3QobG0oUmVzcG9uc2VfVGltZSB+IEFjdGl2ZV9Vc2VycywgZGF0YSA9IGRhdGEpKSwgDQogICAgICAgICAgICBsaW5lID0gbGlzdChjb2xvciA9ICdyZWQnLCBkYXNoID0gJ3NvbGlkJywgd2lkdGggPSAyKSkgJT4lDQogIGxheW91dCh0aXRsZSA9IHBhc3RlKCJTY2F0dGVyIERpYWdyYW06IEFjdGl2ZSBVc2VycyB2cyBTZXJ2ZXIgUmVzcG9uc2UgVGltZVxuQ29ycmVsYXRpb246ICIsIHJvdW5kKGNvcnJlbGF0aW9uX3ZhbHVlLCAyKSksDQogICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiTnVtYmVyIG9mIEFjdGl2ZSBVc2VycyIpLA0KICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIlNlcnZlciBSZXNwb25zZSBUaW1lIChtcykiKSkNCg0KIyBTaG93IHRoZSBwbG90DQpmaWcNCmBgYA==