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
graph
# Opsional: Simpan sebagai file HTML interaktif
# htmlwidgets::saveWidget(graph, "fishbone_system_crashes.html")

Flowchart

# 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
graph

Histogram

# 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
fig

Scatter 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
fig
LS0tDQp0aXRsZTogIlRla25payBTYW1wbGluZyBhbmQgU3VydmV5Ig0Kc3VidGl0bGU6ICJQZXJ0ZW11YW4gMTEiDQphdXRob3I6IA0KICAtICJaYWluIElxYmFsIFNhcHV0cmFfNTIyNDAwMTgiDQogIC0gIkNoZWxsbyBGcmhpbm8gTWlrZSBNXzUyMjQwMDMxIg0KZGF0ZTogICJTZW5pbiwgMDUvMDUvMjAyNSINCm91dHB1dDoNCiAgcm1kZm9ybWF0czo6cmVhZHRoZWRvd246ICAgDQogICAgc2VsZl9jb250YWluZWQ6IHRydWUNCiAgICB0aHVtYm5haWxzOiB0cnVlDQogICAgbGlnaHRib3g6IHRydWUNCiAgICBnYWxsZXJ5OiB0cnVlDQogICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQ0KICAgIGxpYl9kaXI6IGxpYnMNCiAgICAzZGZfcHJpbnQ6ICJwYWdlZCINCiAgICBjb2RlX2ZvbGRpbmc6ICJzaG93Ig0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KLS0tDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoRFQpDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkoc3RyaW5naSkNCmxpYnJhcnkobHVicmlkYXRlKQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkocmVhZHIpDQpgYGANCg0KIyBDaGVjayBTaGVldA0KDQpgYGB7cixtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0V9DQojIEJ1YXQgZGF0YSBjaGVjayBzaGVldA0KY2hlY2tfc2hlZXQgPC0gZGF0YS5mcmFtZSgNCiAgTm8gPSAxOjIwLA0KICBEYXRlID0gYygiMTYvMDQvMjAyNSIsICIxNy8wNC8yMDI1IiwgIjE4LzA0LzIwMjUiLCAiMTkvMDQvMjAyNSIsICIyMC8wNC8yMDI1IiwNCiAgICAgICAgICAgIjIxLzA0LzIwMjUiLCAiMjIvMDQvMjAyNSIsICIyMy8wNC8yMDI1IiwgIjI0LzA0LzIwMjUiLCAiMjUvMDQvMjAyNSIsDQogICAgICAgICAgICIyNi8wNC8yMDI1IiwgIjI3LzA0LzIwMjUiLCAiMjgvMDQvMjAyNSIsICIyOS8wNC8yMDI1IiwgIjMwLzA0LzIwMjUiLA0KICAgICAgICAgICAiMDEvMDUvMjAyNSIsICIwMi8wNS8yMDI1IiwgIjAzLzA1LzIwMjUiLCAiMDQvMDUvMjAyNSIsICIwNS8wNS8yMDI1IiksDQogIEplbmlzX0Vycm9yID0gYygiTG9naW4gRmFpbGVkIiwgIkNyYXNoIiwgIkNyYXNoIiwgIlRpbWUiLCAiVUkgTm90IFJlc3BvbmRpbmciLA0KICAgICAgICAgICAgICAgICAgIkxvZ2luIEZhaWxlZCIsICJUaW1lIiwgIkNyYXNoIiwgIlRpbWUiLCAiVUkgTm90IFJlc3BvbmRpbmciLA0KICAgICAgICAgICAgICAgICAgIkxvZ2luIEZhaWxlZCIsICJUaW1lIiwgIkNyYXNoIiwgIlZhbGlkYXRpb24gRXJyb3IiLCAiTG9naW4gRmFpbGVkIiwNCiAgICAgICAgICAgICAgICAgICJMb2dpbiBGYWlsZWQiLCAiVGltZSIsICJDcmFzaCIsICJWYWxpZGF0aW9uIEVycm9yIiwgIlVJIE5vdCBSZXNwb25kaW5nIikNCikNCg0KIyBUYW1waWxrYW4gdGFiZWwNCmRhdGF0YWJsZShjaGVja19zaGVldCwgb3B0aW9ucyA9IGxpc3QocGFnZUxlbmd0aCA9IDUpKQ0KYGBgDQoNCg0KYGBge3IsbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFfQ0KIyBDb3VudCBmcmVxdWVuY3kgb2YgZWFjaCBlcnJvcnMNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KERUKQ0KDQplcnJvcl9zdW1tYXJ5IDwtIGNoZWNrX3NoZWV0ICU+JQ0KICBjb3VudChKZW5pc19FcnJvciwgc29ydCA9IFRSVUUpICU+JQ0KICByZW5hbWUoRnJlcXVlbmN5ID0gbikNCg0KIyBEaXNwbGF5IHN1bW1hcnkgdGFibGUNCmRhdGF0YWJsZSgNCiAgZXJyb3Jfc3VtbWFyeSwNCiAgb3B0aW9ucyA9IGxpc3QoDQogICAgc2Nyb2xsQ29sbGFwc2UgPSBUUlVFLA0KICAgIHNlYXJjaGluZyA9IEZBTFNFLCAgICMgUmVtb3ZlIHNlYXJjaCBib3gNCiAgICBwYWdpbmcgPSBGQUxTRSAgICAgICAjIFJlbW92ZSBwYWdpbmF0aW9uDQogICksDQogIHJvd25hbWVzID0gRkFMU0UsDQogIGNhcHRpb24gPSBodG1sdG9vbHM6OnRhZ3MkY2FwdGlvbigNCiAgICBzdHlsZSA9ICdjYXB0aW9uLXNpZGU6IHRvcDsgdGV4dC1hbGlnbjogbGVmdDsgDQogICAgICAgICAgICAgZm9udC1zaXplOiAxOHB4OyBmb250LXdlaWdodDogYm9sZDsnLA0KICAgICdDaGVjayBTaGVldDogU3VtbWFyeSBvZiBFcnJvcicNCiAgKSwNCiAgY2xhc3MgPSAnc3RyaXBlIGhvdmVyIGNvbXBhY3QnDQopDQpgYGANCg0KYGBge3IsbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShwbG90bHkpDQoNCiMgSW50ZXJhY3RpdmUgYmFyIGNoYXJ0IHVzaW5nIHBsb3RseQ0KcGxvdF9seShlcnJvcl9zdW1tYXJ5LA0KICAgICAgICB4ID0gfkZyZXF1ZW5jeSwNCiAgICAgICAgeSA9IH5yZW9yZGVyKEplbmlzX0Vycm9yLCBGcmVxdWVuY3kpLA0KICAgICAgICB0eXBlID0gJ2JhcicsDQogICAgICAgIG9yaWVudGF0aW9uID0gJ2gnLA0KICAgICAgICBtYXJrZXIgPSBsaXN0KA0KICAgICAgICAgIGNvbG9yID0gfkZyZXF1ZW5jeSwNCiAgICAgICAgICBjb2xvcnNjYWxlID0gJ0NpdmlkaXMnLCAgIyBDYW4gYWxzbyB0cnk6ICdCbHVlcmVkJywgJycsICdZbE9yUmQnDQogICAgICAgICAgc2hvd3NjYWxlID0gVFJVRQ0KICAgICAgICApDQopICU+JQ0KICBsYXlvdXQoDQogICAgdGl0bGUgPSBsaXN0KHRleHQgPSAiQ2hlY2sgU2hlZXQ6IEZyZXF1ZW5jeSBvZiBFcnJvcyIsIGZvbnQgPSBsaXN0KHNpemUgPSAxOCkpLA0KICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICJGcmVxdWVuY3kiKSwNCiAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiRXJyb3IiKSwNCiAgICBtYXJnaW4gPSBsaXN0KGwgPSAxMjApDQogICkNCmBgYA0KDQojIENvbnRyb2wgRmxvdw0KDQpgYGB7cixtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0V9DQojIExvYWQgbGlicmFyaWVzDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkoZHBseXIpDQoNCiMgQnVhdCBkYXRhIHdha3R1IGxvYWRpbmcgYXBsaWthc2kNCmxvYWRpbmdfZGF0YSA8LSBkYXRhLmZyYW1lKA0KICBEYXRlID0gMTozMCwNCiAgTG9hZGluZ19UaW1lID0gYygNCiAgICAyLjEsIDIuMCwgMi4zLCAxLjksIDIuMiwgMi4wLCAyLjQsIDIuMSwgMi4wLCAyLjUsDQogICAgMS44LCAyLjMsIDIuMSwgMi4wLCAyLjIsIDIuNiwgMS45LCAyLjEsIDIuMiwgMi4wLA0KICAgIDIuNywgMi4zLCAyLjAsIDIuMSwgMi4yLCAyLjAsIDIuMywgMS44LCAyLjQsIDIuMQ0KICApDQopDQoNCiMgVGVudHVrYW4gYmF0YXMga2VuZGFsaQ0KQ0wgPC0gMi4xDQpVQ0wgPC0gMi40DQpMQ0wgPC0gMS44DQoNCiMgVGFuZGFpIG91dGxpZXJzDQpsb2FkaW5nX2RhdGEgPC0gbG9hZGluZ19kYXRhICU+JQ0KICBtdXRhdGUoT3V0bGllciA9IGlmZWxzZShMb2FkaW5nX1RpbWUgPiBVQ0wgfCBMb2FkaW5nX1RpbWUgPCBMQ0wsICJZYSIsICJUaWRhayIpKQ0KDQojIEJ1YXQgcGxvdA0KcGxvdF9seShsb2FkaW5nX2RhdGEsIHggPSB+RGF0ZSwgeSA9IH5Mb2FkaW5nX1RpbWUsIHR5cGUgPSAnc2NhdHRlcicsIG1vZGUgPSAnbGluZXMrbWFya2VycycsDQogICAgICAgIGxpbmUgPSBsaXN0KGNvbG9yID0gJ2JsdWUnKSwgDQogICAgICAgIG1hcmtlciA9IGxpc3Qoc2l6ZSA9IDgsIGNvbG9yID0gaWZlbHNlKGxvYWRpbmdfZGF0YSRPdXRsaWVyID09ICJZYSIsICJyZWQiLCAiYmx1ZSIpKSwNCiAgICAgICAgaG92ZXJpbmZvID0gJ3RleHQnLA0KICAgICAgICB0ZXh0ID0gfnBhc3RlKCJIYXJpOiIsIERhdGUsICI8YnI+V2FrdHUgTG9hZGluZzoiLCBMb2FkaW5nX1RpbWUsICJkZXRpayIpKSAlPiUNCiAgYWRkX2xpbmVzKHkgPSByZXAoQ0wsIDMwKSwgbmFtZSA9ICJDTCIsIGxpbmUgPSBsaXN0KGNvbG9yID0gJ2dyZWVuJywgZGFzaCA9ICdkb3QnKSkgJT4lDQogIGFkZF9saW5lcyh5ID0gcmVwKFVDTCwgMzApLCBuYW1lID0gIlVDTCIsIGxpbmUgPSBsaXN0KGNvbG9yID0gJ3JlZCcsIGRhc2ggPSAnZG90JykpICU+JQ0KICBhZGRfbGluZXMoeSA9IHJlcChMQ0wsIDMwKSwgbmFtZSA9ICJMQ0wiLCBsaW5lID0gbGlzdChjb2xvciA9ICdyZWQnLCBkYXNoID0gJ2RvdCcpKSAlPiUNCiAgbGF5b3V0KHRpdGxlID0gIkNvbnRyb2wgQ2hhcnQg4oCTIFBlcmlvZGljIEFwcGxpY2F0aW9uIExvYWRpbmcgVGltZSIsDQogICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiSGFyaSIpLA0KICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIldha3R1IExvYWRpbmcgKGRldGlrKSIpLA0KICAgICAgICAgbGVnZW5kID0gbGlzdChvcmllbnRhdGlvbiA9ICdoJywgeCA9IDAuMywgeSA9IC0wLjIpKQ0KYGBgDQoNCiMgRmlzaGJvbmUgRGlhZ3JhbQ0KDQpgYGB7cixtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0V9DQojIExvYWQgbGlicmFyeQ0KbGlicmFyeShEaWFncmFtbWVSKQ0KDQojIENyZWF0ZSBmaXNoYm9uZSBkaWFncmFtDQpncmFwaCA8LSBnclZpeigiDQpkaWdyYXBoIGZpc2hib25lIHsNCiAgZ3JhcGggW2xheW91dCA9IGRvdCwgcmFua2RpciA9IExSXQ0KDQogICMgRGVmYXVsdCBub2RlIHN0eWxlcw0KICBub2RlIFtmb250bmFtZT1IZWx2ZXRpY2EsIGZvbnRzaXplPTI1LCBzdHlsZT1maWxsZWRdDQoNCiAgIyBDZW50cmFsIHByb2JsZW0NCiAgUHJvYmxlbSBbbGFiZWw9J01haW4gQ2F1c2VzIG9mIFxcbiBTeXN0ZW0gQ3Jhc2hlcycsIHNoYXBlPWVsbGlwc2UsIGZpbGxjb2xvcj1saWdodGNvcmFsLCB3aWR0aD01LjAsIGhlaWdodD0xLjJdDQoNCiAgIyBDYXRlZ29yeSBub2RlcyAoc2hhcmVkIHN0eWxlKQ0KICBub2RlIFtzaGFwZT1kaWFtb25kLCB3aWR0aD0yLjUsIGhlaWdodD0xLjAsIGZpbGxjb2xvcj0nI0ZGRDcwMCddDQogIEExIFtsYWJlbD0nTWFuJ10NCiAgQTIgW2xhYmVsPSdNZXRob2QnXQ0KICBBMyBbbGFiZWw9J01hY2hpbmUnXQ0KICBBNCBbbGFiZWw9J01hdGVyaWFsJ10NCiAgQTUgW2xhYmVsPSdFbnZpcm9ubWVudCddDQogIEE2IFtsYWJlbD0nTWVhc3VyZW1lbnQnXQ0KDQogICMgUmVzZXQgbm9kZSBzdHlsZSBmb3Igc3ViLWNhdGVnb3JpZXMNCiAgbm9kZSBbc2hhcGU9ZWxsaXBzZSwgd2lkdGg9Mi41LCBoZWlnaHQ9MC42LCBmaWxsY29sb3I9JyM5MEVFOTAnXQ0KICBBMWEgW2xhYmVsPSdIdW1hbiBlcnJvciddDQogIEExYiBbbGFiZWw9J0luYWRlcXVhdGUgdHJhaW5pbmcnXQ0KICBBMWMgW2xhYmVsPSdPdmVybG9hZGVkIHN0YWZmJ10NCg0KICBBMmEgW2xhYmVsPSdQb29yIGNvZGluZyBwcmFjdGljZXMnXQ0KICBBMmIgW2xhYmVsPSdMYWNrIG9mIHRlc3RpbmcnXQ0KDQogIEEzYSBbbGFiZWw9J0hhcmR3YXJlIGZhaWx1cmUnXQ0KICBBM2IgW2xhYmVsPSdPdmVyaGVhdGluZyddDQoNCiAgQTRhIFtsYWJlbD0nQ29ycnVwdGVkIGZpbGVzJ10NCiAgQTRiIFtsYWJlbD0nSW5jb21wYXRpYmxlIHNvZnR3YXJlJ10NCg0KICBBNWEgW2xhYmVsPSdOZXR3b3JrIGluc3RhYmlsaXR5J10NCiAgQTViIFtsYWJlbD0nUG93ZXIgb3V0YWdlcyddDQoNCiAgQTZhIFtsYWJlbD0nSW5hY2N1cmF0ZSBsb2dzJ10NCiAgQTZiIFtsYWJlbD0nRmF1bHR5IG1vbml0b3JpbmcgdG9vbHMnXQ0KDQogICMgUmVsYXRpb25zaGlwcw0KICBBMSAtPiBQcm9ibGVtDQogIEEyIC0+IFByb2JsZW0NCiAgQTMgLT4gUHJvYmxlbQ0KICBBNCAtPiBQcm9ibGVtDQogIEE1IC0+IFByb2JsZW0NCiAgQTYgLT4gUHJvYmxlbQ0KDQogIEExYSAtPiBBMQ0KICBBMWIgLT4gQTENCiAgQTFjIC0+IEExDQoNCiAgQTJhIC0+IEEyDQogIEEyYiAtPiBBMg0KDQogIEEzYSAtPiBBMw0KICBBM2IgLT4gQTMNCg0KICBBNGEgLT4gQTQNCiAgQTRiIC0+IEE0DQoNCiAgQTVhIC0+IEE1DQogIEE1YiAtPiBBNQ0KDQogIEE2YSAtPiBBNg0KICBBNmIgLT4gQTYNCn0NCiIpDQoNCiMgVGFtcGlsa2FuIGRpYWdyYW0gbGFuZ3N1bmcNCmdyYXBoDQoNCiMgT3BzaW9uYWw6IFNpbXBhbiBzZWJhZ2FpIGZpbGUgSFRNTCBpbnRlcmFrdGlmDQojIGh0bWx3aWRnZXRzOjpzYXZlV2lkZ2V0KGdyYXBoLCAiZmlzaGJvbmVfc3lzdGVtX2NyYXNoZXMuaHRtbCIpDQpgYGANCg0KIyBGbG93Y2hhcnQNCg0KYGBge3IsbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFfQ0KIyBMb2FkIGxpYnJhcnkNCmxpYnJhcnkoRGlhZ3JhbW1lUikNCg0KIyBDcmVhdGUgZmxvd2NoYXJ0DQpncmFwaCA8LSBnclZpeigiDQpkaWdyYXBoIGRldmVsb3BtZW50X2Zsb3cgew0KICBncmFwaCBbbGF5b3V0ID0gZG90LCByYW5rZGlyID0gVEJdDQoNCiAgIyBEZWZhdWx0IG5vZGUgc3R5bGVzDQogIG5vZGUgW2ZvbnRuYW1lPUhlbHZldGljYSwgZm9udHNpemU9MTIsIHN0eWxlPWZpbGxlZF0NCg0KICAjIFN0YXJ0IG5vZGUNCiAgU3RhcnQgW2xhYmVsPSdTdGFydCcsIHNoYXBlPWNpcmNsZSwgZmlsbGNvbG9yPWxpZ2h0Ymx1ZV0NCg0KICAjIFByb2Nlc3Mgbm9kZXMNCiAgSWRlYSBbbGFiZWw9J0lkZWEnLCBzaGFwZT1wYXJhbGxlbG9ncmFtLCBmaWxsY29sb3I9Qmx1ZSwgd2lkdGg9Mi41XQ0KICBDb2RpbmcgW2xhYmVsPSdDb2RpbmcnLCBzaGFwZT1ib3gsIGZpbGxjb2xvcj1vcmFuZ2UsIHdpZHRoPTIuNV0NCiAgVGVzdGluZyBbbGFiZWw9J1Rlc3RpbmcnLCBzaGFwZT1ib3gsIGZpbGxjb2xvcj1vcmFuZ2UsIHdpZHRoPTIuNV0NCiAgRGVwbG95IFtsYWJlbD0nRGVwbG95Jywgc2hhcGU9Ym94LCBmaWxsY29sb3I9b3JhbmdlLCB3aWR0aD0yLjVdDQoNCiAgIyBEZWNpc2lvbiBub2RlDQogIERlY2lzaW9uMSBbbGFiZWw9J0NvZGUgUGFzc2VzIFRlc3RzPycsIHNoYXBlPWRpYW1vbmQsIGZpbGxjb2xvcj1saWdodGNvcmFsLCB3aWR0aD0yLjVdDQogIERlY2lzaW9uMiBbbGFiZWw9J0RlcGxveW1lbnQgU3VjY2Vzc2Z1bD8nLCBzaGFwZT1kaWFtb25kLCBmaWxsY29sb3I9bGlnaHRjb3JhbCwgd2lkdGg9Mi41XQ0KDQogICMgRW5kIG5vZGUNCiAgRmluaXNoIFtsYWJlbD0nRmluaXNoJywgc2hhcGU9Y2lyY2xlLCBmaWxsY29sb3I9bGlnaHRncmF5XQ0KDQogICMgUmVsYXRpb25zaGlwcw0KICBTdGFydCAtPiBJZGVhDQogIElkZWEgLT4gQ29kaW5nDQogIENvZGluZyAtPiBUZXN0aW5nDQogIFRlc3RpbmcgLT4gRGVjaXNpb24xDQogIERlY2lzaW9uMSAtPiBEZXBsb3kgW2xhYmVsPSdZZXMnXQ0KICBEZWNpc2lvbjEgLT4gQ29kaW5nIFtsYWJlbD0nTm8nXQ0KICBEZXBsb3kgLT4gRGVjaXNpb24yDQogIERlY2lzaW9uMiAtPiBGaW5pc2ggW2xhYmVsPSdZZXMnXQ0KICBEZWNpc2lvbjIgLT4gVGVzdGluZyBbbGFiZWw9J05vJ10NCg0KICAjIE9wdGlvbmFsIG5vdGUNCiAgTm90ZSBbbGFiZWw9J05vdGU6IENvbmZpcm1lZCBieSBRQSBUZWFtJywgc2hhcGU9bm90ZSwgZmlsbGNvbG9yPWxpZ2h0eWVsbG93XQ0KICBEZWNpc2lvbjIgLT4gTm90ZQ0KfQ0KIikNCg0KIyBUYW1waWxrYW4gZGlhZ3JhbSBsYW5nc3VuZw0KZ3JhcGgNCmBgYA0KDQojIEhpc3RvZ3JhbQ0KDQpgYGB7cixtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0V9DQojIExvYWQgcmVxdWlyZWQgbGlicmFyeQ0KbGlicmFyeShwbG90bHkpDQoNCiMgU2ltdWxhdGUgQ2hyb21lLW9ubHkgZXJyb3IgZGF0YQ0Kc2V0LnNlZWQoMTIzKQ0KY2hyb21lX2RhdGEgPC0gZGF0YS5mcmFtZSgNCiAgRXJyb3JzID0gcm5vcm0oMjAwLCBtZWFuID0gOCwgc2QgPSAyKQ0KKQ0KDQojIFBsb3QgaW50ZXJhY3RpdmUgaGlzdG9ncmFtIHVzaW5nIFBsb3RseQ0KcGxvdF9seSgNCiAgZGF0YSA9IGNocm9tZV9kYXRhLA0KICB4ID0gfkVycm9ycywNCiAgdHlwZSA9ICdoaXN0b2dyYW0nLA0KICBuYmluc3ggPSAyMCwNCiAgbWFya2VyID0gbGlzdChjb2xvciA9ICcjMWY3N2I0JywgbGluZSA9IGxpc3QoY29sb3IgPSAnYmxhY2snLCB3aWR0aCA9IDEpKSwNCiAgb3BhY2l0eSA9IDAuNzUNCikgJT4lDQogIGxheW91dCgNCiAgICB0aXRsZSA9ICJIaXN0b2dyYW0gb2YgRXJyb3JzIOKAkyBDaHJvbWUgQnJvd3NlciIsDQogICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIk51bWJlciBvZiBFcnJvcnMiKSwNCiAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiRnJlcXVlbmN5IiksDQogICAgYmFyZ2FwID0gMC4xLA0KICAgIHBsb3RfYmdjb2xvciA9ICd3aGl0ZScsDQogICAgcGFwZXJfYmdjb2xvciA9ICd3aGl0ZScNCiAgKQ0KYGBgDQoNCiMgUGFyZXRvIENoYXJ0DQoNCmBgYHtyLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRX0NCiMgTG9hZCBsaWJyYXJpZXMNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHBsb3RseSkNCg0KIyBDcmVhdGUgc2ltdWxhdGVkIGRhdGEgZm9yIGJ1Z3MgY2F1c2luZyBzeXN0ZW0gZGlzcnVwdGlvbnMNCmNoZWNrX3NoZWV0IDwtIGRhdGEuZnJhbWUoDQogIEJ1Z19UeXBlID0gYygNCiAgICByZXAoIk1lbW9yeSBMZWFrIiwgNDApLCByZXAoIk51bGwgUG9pbnRlciIsIDMwKSwgDQogICAgcmVwKCJBUEkgRmFpbHVyZSIsIDE1KSwgcmVwKCJVSSBGcmVlemUiLCAxMCksIA0KICAgIHJlcCgiRGF0YWJhc2UgRXJyb3IiLCA1KQ0KICApDQopDQoNCiMgU3VtbWFyaXplIHRoZSBudW1iZXIgb2YgZGlzcnVwdGlvbnMgYnkgYnVnIHR5cGUNCnBhcmV0b19kYXRhIDwtIGNoZWNrX3NoZWV0ICU+JQ0KICBjb3VudChCdWdfVHlwZSwgc29ydCA9IFRSVUUpICU+JQ0KICBtdXRhdGUoDQogICAgY3VtX2ZyZXEgPSBjdW1zdW0obikgLyBzdW0obikgKiAxMDAgICMgY3VtdWxhdGl2ZSBwZXJjZW50YWdlDQogICkNCg0KIyBDcmVhdGUgZGlmZmVyZW50IGNvbG9ycyBmb3IgZWFjaCBCdWcgVHlwZQ0KY29sb3JzIDwtIFJDb2xvckJyZXdlcjo6YnJld2VyLnBhbChuID0gbGVuZ3RoKHBhcmV0b19kYXRhJEJ1Z19UeXBlKSwgbmFtZSA9ICJTZXQzIikNCg0KIyBDcmVhdGUgUGxvdGx5IFBhcmV0byBDaGFydA0KZmlnIDwtIHBsb3RfbHkoKQ0KDQojIEFkZCBCYXIgQ2hhcnQgKENvdW50KSAtIHdpdGggZGlmZmVyZW50IGNvbG9ycw0KZmlnIDwtIGZpZyAlPiUgYWRkX2JhcnMoDQogIHggPSB+cmVvcmRlcihwYXJldG9fZGF0YSRCdWdfVHlwZSwgLXBhcmV0b19kYXRhJG4pLA0KICB5ID0gfnBhcmV0b19kYXRhJG4sDQogIG5hbWUgPSAnTnVtYmVyIG9mIERpc3J1cHRpb25zJywNCiAgbWFya2VyID0gbGlzdChjb2xvciA9IGNvbG9ycyksDQogIHlheGlzID0gInkxIg0KKQ0KDQojIEFkZCBDdW11bGF0aXZlIExpbmUNCmZpZyA8LSBmaWcgJT4lIGFkZF9saW5lcygNCiAgeCA9IH5yZW9yZGVyKHBhcmV0b19kYXRhJEJ1Z19UeXBlLCAtcGFyZXRvX2RhdGEkbiksDQogIHkgPSB+cGFyZXRvX2RhdGEkY3VtX2ZyZXEsDQogIG5hbWUgPSAnQ3VtdWxhdGl2ZSAoJSknLA0KICB5YXhpcyA9ICJ5MiIsDQogIGxpbmUgPSBsaXN0KGNvbG9yID0gJ3JlZCcsIGRhc2ggPSAnZGFzaCcpDQopDQoNCiMgQWRkIEN1dC1vZmYgTGluZSBhdCA4MCUNCmZpZyA8LSBmaWcgJT4lIGFkZF9saW5lcygNCiAgeCA9IH5yZW9yZGVyKHBhcmV0b19kYXRhJEJ1Z19UeXBlLCAtcGFyZXRvX2RhdGEkbiksDQogIHkgPSByZXAoODAsIGxlbmd0aChwYXJldG9fZGF0YSRCdWdfVHlwZSkpLA0KICBuYW1lID0gJ0N1dC1vZmYgODAlJywNCiAgeWF4aXMgPSAieTIiLA0KICBsaW5lID0gbGlzdChjb2xvciA9ICdncmVlbicsIGRhc2ggPSAnZG90JykNCikNCg0KIyBBZGp1c3QgbGF5b3V0DQpmaWcgPC0gZmlnICU+JSBsYXlvdXQoDQogIHRpdGxlID0gIlBhcmV0byBDaGFydCAtIEJ1Z3MgQ2F1c2luZyBTeXN0ZW0gRGlzcnVwdGlvbnMiLA0KICB4YXhpcyA9IGxpc3QoDQogICAgdGl0bGUgPSAiQnVnIFR5cGVzIiwNCiAgICB0aWNrYW5nbGUgPSAtNDUgICAjIHRpbHQgNDUgZGVncmVlcw0KICApLA0KICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiTnVtYmVyIG9mIERpc3J1cHRpb25zIiksDQogIHlheGlzMiA9IGxpc3QoDQogICAgdGl0bGUgPSAiQ3VtdWxhdGl2ZSAoJSkiLA0KICAgIG92ZXJsYXlpbmcgPSAieSIsDQogICAgc2lkZSA9ICJyaWdodCIsDQogICAgcmFuZ2UgPSBjKDAsIDEwMCkNCiAgKSwNCiAgbGVnZW5kID0gbGlzdCh4ID0gMC44LCB5ID0gMC43NSksDQogIHNoYXBlcyA9IGxpc3QoDQogICAgbGlzdCgNCiAgICAgIHR5cGUgPSAibGluZSIsDQogICAgICB4MCA9IC0wLjUsDQogICAgICB4MSA9IGxlbmd0aChwYXJldG9fZGF0YSRCdWdfVHlwZSkgLSAwLjUsDQogICAgICB5MCA9IDgwLA0KICAgICAgeTEgPSA4MCwNCiAgICAgIHlyZWYgPSAieTIiLA0KICAgICAgbGluZSA9IGxpc3QoY29sb3IgPSAiZ3JlZW4iLCB3aWR0aCA9IDIsIGRhc2ggPSAiZG90IikNCiAgICApDQogICkNCikNCg0KIyBTaG93IGNoYXJ0DQpmaWcNCmBgYA0KDQojIFNjYXR0ZXIgRGlhZ3JhbQ0KDQpgYGB7cixtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0V9DQojIExvYWQgdGhlIHJlcXVpcmVkIGxpYnJhcnkNCmxpYnJhcnkocGxvdGx5KQ0KDQojIFNldCBzZWVkIGZvciByZXByb2R1Y2liaWxpdHkNCnNldC5zZWVkKDEyMykNCg0KIyBDcmVhdGUgZGF0YSB3aXRoIHN0cm9uZyBwb3NpdGl2ZSBjb3JyZWxhdGlvbg0KZGF0YSA8LSBkYXRhLmZyYW1lKA0KICBBY3RpdmVfVXNlcnMgPSBzZXEoMTAwLCAxMDAwLCBieSA9IDUwKSwNCiAgUmVzcG9uc2VfVGltZSA9IHNlcSgxMDAsIDMwMCwgbGVuZ3RoLm91dCA9IDE5KSArIHJub3JtKDE5LCBtZWFuID0gMCwgc2QgPSAxMCkNCikNCg0KIyBDYWxjdWxhdGUgdGhlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50DQpjb3JyZWxhdGlvbl92YWx1ZSA8LSBjb3IoZGF0YSRBY3RpdmVfVXNlcnMsIGRhdGEkUmVzcG9uc2VfVGltZSkNCg0KIyBDcmVhdGUgc2NhdHRlciBwbG90IHdpdGggcmVncmVzc2lvbiBsaW5lDQpmaWcgPC0gcGxvdF9seShkYXRhLCANCiAgICAgICAgICAgICAgIHggPSB+QWN0aXZlX1VzZXJzLCANCiAgICAgICAgICAgICAgIHkgPSB+UmVzcG9uc2VfVGltZSwgDQogICAgICAgICAgICAgICB0eXBlID0gJ3NjYXR0ZXInLCANCiAgICAgICAgICAgICAgIG1vZGUgPSAnbWFya2VycycsDQogICAgICAgICAgICAgICBtYXJrZXIgPSBsaXN0KGNvbG9yID0gJ2RhcmtibHVlJywgc2l6ZSA9IDEwKSkgJT4lDQogIGFkZF9saW5lcyh4ID0gZGF0YSRBY3RpdmVfVXNlcnMsIA0KICAgICAgICAgICAgeSA9IHByZWRpY3QobG0oUmVzcG9uc2VfVGltZSB+IEFjdGl2ZV9Vc2VycywgZGF0YSA9IGRhdGEpKSwgDQogICAgICAgICAgICBsaW5lID0gbGlzdChjb2xvciA9ICdyZWQnLCBkYXNoID0gJ3NvbGlkJywgd2lkdGggPSAyKSkgJT4lDQogIGxheW91dCh0aXRsZSA9IHBhc3RlKCJTY2F0dGVyIERpYWdyYW06IEFjdGl2ZSBVc2VycyB2cyBTZXJ2ZXIgUmVzcG9uc2UgVGltZVxuQ29ycmVsYXRpb246ICIsIHJvdW5kKGNvcnJlbGF0aW9uX3ZhbHVlLCAyKSksDQogICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiTnVtYmVyIG9mIEFjdGl2ZSBVc2VycyIpLA0KICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIlNlcnZlciBSZXNwb25zZSBUaW1lIChtcykiKSkNCg0KIyBTaG93IHRoZSBwbG90DQpmaWcNCmBgYA==