Cyclist MidBlock

Analysis for Cyclist MidBlock

This analysis focuses on mode: cyclist | intersection: no

Variable Level Injury p0 Non-Injury p1 OddsRatio Lower Upper P-Value
oneway No 167 0.9598 72 0.9863 1
Yes 7 0.0402 1 0.0137 0.3313 0.04 2.7424 0.4424
twoways No 6 0.0345 0 0 1
Yes 168 0.9655 73 1 Inf Inf 0.1837
clearzone No 174 1 71 0.9726 1
Yes 0 0 2 0.0274 Inf Inf 0.0865
onstreetparking No 97 0.5575 33 0.4521 1
Yes 77 0.4425 40 0.5479 1.527 0.8814 2.6452 0.1624
parkinglotgarage No 57 0.3276 31 0.4247 1
Yes 117 0.6724 42 0.5753 0.66 0.3764 1.1576 0.1491
concretebarrier No 172 0.9885 73 1 1
Yes 2 0.0115 0 0 0 0 1
laneofparkedcars No 170 0.977 73 1 1
Yes 4 0.023 0 0 0 0 0.3224
bikelanewithbarrier No 174 1 71 0.9726 1
Yes 0 0 2 0.0274 Inf Inf 0.0865
offroadbikepathcycletrack No 172 0.9885 73 1 1
Yes 2 0.0115 0 0 0 0 1
raisedbikelane No 171 0.9828 72 0.9863 1
Yes 3 0.0172 1 0.0137 0.7917 0.081 7.7388 1
twowayprotectedbicyclelane No 171 0.9828 72 0.9863 1
Yes 3 0.0172 1 0.0137 0.7917 0.081 7.7388 1
onewayprotectedbicyclelane No 174 1 72 0.9863 1
Yes 0 0 1 0.0137 Inf Inf 0.2955
bufferedbicyclelaneadjacenttocurb No 169 0.9713 72 0.9863 1
Yes 5 0.0287 1 0.0137 0.4694 0.0539 4.0897 0.6732
bufferedbicyclelaneoffsetfromcurb No 174 1 72 0.9863 1
Yes 0 0 1 0.0137 Inf Inf 0.2955
paintedbicyclelaneadjacenttocurb No 138 0.7931 57 0.7808 1
Yes 36 0.2069 16 0.2192 1.076 0.5535 2.092 0.8648
paintedbicyclelaneoffsetfromcurb No 165 0.9483 68 0.9315 1
Yes 9 0.0517 5 0.0685 1.348 0.4358 4.1694 0.5621
bikeaccessibleshoulder No 162 0.931 68 0.9315 1
Yes 12 0.069 5 0.0685 0.9926 0.3368 2.926 1
sharedlanewithmarkings No 166 0.954 72 0.9863 1
Yes 8 0.046 1 0.0137 0.2882 0.0354 2.3468 0.2884
NULL

if (nrow(odds_ratios_data) > 0) {
  

  odds_ratios_restructured <- odds_ratios_data %>%
    filter(!is.na(OddsRatio)) %>%  
    mutate(Reference = ifelse(Level == "No", "Yes", "No")) %>%  
    select(Variable, Level, Reference, OddsRatio, Lower, Upper, PValue)

  
  odds_ratios_restructured$Variable <- factor(odds_ratios_restructured$Variable, levels = unique(odds_ratios_restructured$Variable))
  
  
  restructured_table_html <- odds_ratios_restructured %>%
    kable("html", caption = "Restructured Odds Ratio Analysis for Medical Interpretation",
          col.names = c("Variable", "Level", "Reference", "Odds Ratio", "Lower 95% CI", "Upper 95% CI", "P-Value")) %>%
    kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = FALSE) %>%
    row_spec(0, bold = TRUE, background = "#333333", color = "white") %>%
    row_spec(1:nrow(odds_ratios_restructured), background = rep(c("#f9f9f9", "#ffffff"), length.out = nrow(odds_ratios_restructured))) %>%
    add_header_above(c(" " = 3, "Odds Ratio Analysis" = 5)) 

  print(restructured_table_html)
} else {
  cat("<p><strong>Warning:</strong> No data available for restructuring. Skipping this section.</p><br>")
}
Restructured Odds Ratio Analysis for Medical Interpretation
Odds Ratio Analysis
Variable Level Reference Odds Ratio Lower 95% CI Upper 95% CI P-Value
oneway.No oneway No Yes 1.0000 NA NA NA
oneway.Yes Yes No 0.3313 0.0400 2.7424 0.4424
twoways.No twoways No Yes 1.0000 NA NA NA
twoways.Yes Yes No Inf NaN Inf 0.1837
clearzone.No clearzone No Yes 1.0000 NA NA NA
clearzone.Yes Yes No Inf NaN Inf 0.0865
onstreetparking.No onstreetparking No Yes 1.0000 NA NA NA
onstreetparking.Yes Yes No 1.5270 0.8814 2.6452 0.1624
parkinglotgarage.No parkinglotgarage No Yes 1.0000 NA NA NA
parkinglotgarage.Yes Yes No 0.6600 0.3764 1.1576 0.1491
concretebarrier.No concretebarrier No Yes 1.0000 NA NA NA
concretebarrier.Yes Yes No 0.0000 0.0000 NaN 1.0000
laneofparkedcars.No laneofparkedcars No Yes 1.0000 NA NA NA
laneofparkedcars.Yes Yes No 0.0000 0.0000 NaN 0.3224
bikelanewithbarrier.No bikelanewithbarrier No Yes 1.0000 NA NA NA
bikelanewithbarrier.Yes Yes No Inf NaN Inf 0.0865
offroadbikepathcycletrack.No offroadbikepathcycletrack No Yes 1.0000 NA NA NA
offroadbikepathcycletrack.Yes Yes No 0.0000 0.0000 NaN 1.0000
raisedbikelane.No raisedbikelane No Yes 1.0000 NA NA NA
raisedbikelane.Yes Yes No 0.7917 0.0810 7.7388 1.0000
twowayprotectedbicyclelane.No twowayprotectedbicyclelane No Yes 1.0000 NA NA NA
twowayprotectedbicyclelane.Yes Yes No 0.7917 0.0810 7.7388 1.0000
onewayprotectedbicyclelane.No onewayprotectedbicyclelane No Yes 1.0000 NA NA NA
onewayprotectedbicyclelane.Yes Yes No Inf NaN Inf 0.2955
bufferedbicyclelaneadjacenttocurb.No bufferedbicyclelaneadjacenttocurb No Yes 1.0000 NA NA NA
bufferedbicyclelaneadjacenttocurb.Yes Yes No 0.4694 0.0539 4.0897 0.6732
bufferedbicyclelaneoffsetfromcurb.No bufferedbicyclelaneoffsetfromcurb No Yes 1.0000 NA NA NA
bufferedbicyclelaneoffsetfromcurb.Yes Yes No Inf NaN Inf 0.2955
paintedbicyclelaneadjacenttocurb.No paintedbicyclelaneadjacenttocurb No Yes 1.0000 NA NA NA
paintedbicyclelaneadjacenttocurb.Yes Yes No 1.0760 0.5535 2.0920 0.8648
paintedbicyclelaneoffsetfromcurb.No paintedbicyclelaneoffsetfromcurb No Yes 1.0000 NA NA NA
paintedbicyclelaneoffsetfromcurb.Yes Yes No 1.3480 0.4358 4.1694 0.5621
bikeaccessibleshoulder.No bikeaccessibleshoulder No Yes 1.0000 NA NA NA
bikeaccessibleshoulder.Yes Yes No 0.9926 0.3368 2.9260 1.0000
sharedlanewithmarkings.No sharedlanewithmarkings No Yes 1.0000 NA NA NA
sharedlanewithmarkings.Yes Yes No 0.2882 0.0354 2.3468 0.2884
NULL

if (nrow(odds_ratios_data) > 0) {
  
 
  odds_ratios_restructured <- odds_ratios_data %>%
    filter(!is.na(OddsRatio)) %>%  
    mutate(Reference = ifelse(Level == "No", "Yes", "No")) %>%  
    select(Variable, Level, Reference, OddsRatio, Lower, Upper, PValue)

  
  odds_ratios_restructured$Variable <- factor(odds_ratios_restructured$Variable, levels = unique(odds_ratios_restructured$Variable))
  
  
  restructured_table_html <- odds_ratios_restructured %>%
    kable("html", caption = "Restructured Odds Ratio Analysis for Medical Interpretation",
          col.names = c("Variable", "Level", "Reference", "Odds Ratio", "Lower 95% CI", "Upper 95% CI", "P-Value")) %>%
    kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = FALSE) %>%
    row_spec(0, bold = TRUE, background = "#333333", color = "white") %>%
    row_spec(1:nrow(odds_ratios_restructured), background = rep(c("#f9f9f9", "#ffffff"), length.out = nrow(odds_ratios_restructured)))

  print(restructured_table_html)
} else {
  cat("<p><strong>Warning:</strong> No data available for restructuring. Skipping this section.</p><br>")
}
Restructured Odds Ratio Analysis for Medical Interpretation
Variable Level Reference Odds Ratio Lower 95% CI Upper 95% CI P-Value
oneway.No oneway No Yes 1.0000 NA NA NA
oneway.Yes Yes No 0.3313 0.0400 2.7424 0.4424
twoways.No twoways No Yes 1.0000 NA NA NA
twoways.Yes Yes No Inf NaN Inf 0.1837
clearzone.No clearzone No Yes 1.0000 NA NA NA
clearzone.Yes Yes No Inf NaN Inf 0.0865
onstreetparking.No onstreetparking No Yes 1.0000 NA NA NA
onstreetparking.Yes Yes No 1.5270 0.8814 2.6452 0.1624
parkinglotgarage.No parkinglotgarage No Yes 1.0000 NA NA NA
parkinglotgarage.Yes Yes No 0.6600 0.3764 1.1576 0.1491
concretebarrier.No concretebarrier No Yes 1.0000 NA NA NA
concretebarrier.Yes Yes No 0.0000 0.0000 NaN 1.0000
laneofparkedcars.No laneofparkedcars No Yes 1.0000 NA NA NA
laneofparkedcars.Yes Yes No 0.0000 0.0000 NaN 0.3224
bikelanewithbarrier.No bikelanewithbarrier No Yes 1.0000 NA NA NA
bikelanewithbarrier.Yes Yes No Inf NaN Inf 0.0865
offroadbikepathcycletrack.No offroadbikepathcycletrack No Yes 1.0000 NA NA NA
offroadbikepathcycletrack.Yes Yes No 0.0000 0.0000 NaN 1.0000
raisedbikelane.No raisedbikelane No Yes 1.0000 NA NA NA
raisedbikelane.Yes Yes No 0.7917 0.0810 7.7388 1.0000
twowayprotectedbicyclelane.No twowayprotectedbicyclelane No Yes 1.0000 NA NA NA
twowayprotectedbicyclelane.Yes Yes No 0.7917 0.0810 7.7388 1.0000
onewayprotectedbicyclelane.No onewayprotectedbicyclelane No Yes 1.0000 NA NA NA
onewayprotectedbicyclelane.Yes Yes No Inf NaN Inf 0.2955
bufferedbicyclelaneadjacenttocurb.No bufferedbicyclelaneadjacenttocurb No Yes 1.0000 NA NA NA
bufferedbicyclelaneadjacenttocurb.Yes Yes No 0.4694 0.0539 4.0897 0.6732
bufferedbicyclelaneoffsetfromcurb.No bufferedbicyclelaneoffsetfromcurb No Yes 1.0000 NA NA NA
bufferedbicyclelaneoffsetfromcurb.Yes Yes No Inf NaN Inf 0.2955
paintedbicyclelaneadjacenttocurb.No paintedbicyclelaneadjacenttocurb No Yes 1.0000 NA NA NA
paintedbicyclelaneadjacenttocurb.Yes Yes No 1.0760 0.5535 2.0920 0.8648
paintedbicyclelaneoffsetfromcurb.No paintedbicyclelaneoffsetfromcurb No Yes 1.0000 NA NA NA
paintedbicyclelaneoffsetfromcurb.Yes Yes No 1.3480 0.4358 4.1694 0.5621
bikeaccessibleshoulder.No bikeaccessibleshoulder No Yes 1.0000 NA NA NA
bikeaccessibleshoulder.Yes Yes No 0.9926 0.3368 2.9260 1.0000
sharedlanewithmarkings.No sharedlanewithmarkings No Yes 1.0000 NA NA NA
sharedlanewithmarkings.Yes Yes No 0.2882 0.0354 2.3468 0.2884
NULL

if (nrow(odds_ratios_data) > 0) {
  
  
  odds_ratios_restructured <- odds_ratios_data %>%
    filter(!is.na(OddsRatio)) %>% 
    mutate(
      Reference = ifelse(Level == "No", "Yes", "No"), 
      Significant = ifelse(PValue < 0.05, TRUE, FALSE),  
      CI_95 = ifelse(!is.na(Lower) & !is.na(Upper), paste0("(", round(Lower, 2), ", ", round(Upper, 2), ")"), "NA") 
    ) %>%
    select(Variable, Level, Reference, OddsRatio, CI_95, PValue, Significant)  

 
  odds_ratios_restructured_filtered <- odds_ratios_restructured %>%
    filter(!(OddsRatio == 1 & CI_95 == "NA"))

 
  odds_ratios_restructured_filtered$Variable <- factor(odds_ratios_restructured_filtered$Variable, levels = unique(odds_ratios_restructured_filtered$Variable))
  
 
  if (nrow(odds_ratios_restructured_filtered) > 0) {
    
    
    odds_ratios_restructured_filtered_for_table <- odds_ratios_restructured_filtered %>%
      select(-Significant)

    
    restructured_table_html <- odds_ratios_restructured_filtered_for_table %>%
      kable("html", caption = "Restructured Odds Ratio Analysis for Medical Interpretation",
            col.names = c("Variable", "Level", "Reference", "Odds Ratio", "CI (95%)", "P-Value")) %>%
      kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = FALSE) %>%
      row_spec(0, bold = TRUE, background = "#333333", color = "white")
    
   
    if (any(odds_ratios_restructured_filtered$Significant == TRUE)) {
      restructured_table_html <- restructured_table_html %>%
        row_spec(
          which(odds_ratios_restructured_filtered$Significant == TRUE), 
          background = "#ffcccc"  
        )
    }
    
   
    restructured_table_html <- restructured_table_html %>%
      row_spec(1:nrow(odds_ratios_restructured_filtered_for_table), background = rep(c("#f9f9f9", "#ffffff"), length.out = nrow(odds_ratios_restructured_filtered_for_table)))

    
    print(restructured_table_html)
  } else {
    cat("<p><strong>Warning:</strong> No data available for restructuring after filtering. Skipping this section.</p><br>")
  }
  
} else {
  cat("<p><strong>Warning:</strong> No data available for restructuring. Skipping this section.</p><br>")
}
Restructured Odds Ratio Analysis for Medical Interpretation
Variable Level Reference Odds Ratio CI (95%) P-Value
oneway.Yes Yes No 0.3313 (0.04, 2.74) 0.4424
twoways.Yes Yes No Inf NA 0.1837
clearzone.Yes Yes No Inf NA 0.0865
onstreetparking.Yes Yes No 1.5270 (0.88, 2.65) 0.1624
parkinglotgarage.Yes Yes No 0.6600 (0.38, 1.16) 0.1491
concretebarrier.Yes Yes No 0.0000 NA 1.0000
laneofparkedcars.Yes Yes No 0.0000 NA 0.3224
bikelanewithbarrier.Yes Yes No Inf NA 0.0865
offroadbikepathcycletrack.Yes Yes No 0.0000 NA 1.0000
raisedbikelane.Yes Yes No 0.7917 (0.08, 7.74) 1.0000
twowayprotectedbicyclelane.Yes Yes No 0.7917 (0.08, 7.74) 1.0000
onewayprotectedbicyclelane.Yes Yes No Inf NA 0.2955
bufferedbicyclelaneadjacenttocurb.Yes Yes No 0.4694 (0.05, 4.09) 0.6732
bufferedbicyclelaneoffsetfromcurb.Yes Yes No Inf NA 0.2955
paintedbicyclelaneadjacenttocurb.Yes Yes No 1.0760 (0.55, 2.09) 0.8648
paintedbicyclelaneoffsetfromcurb.Yes Yes No 1.3480 (0.44, 4.17) 0.5621
bikeaccessibleshoulder.Yes Yes No 0.9926 (0.34, 2.93) 1.0000
sharedlanewithmarkings.Yes Yes No 0.2882 (0.04, 2.35) 0.2884
NULL

if (nrow(odds_ratios_data) > 0) {
  
  
  odds_ratios_restructured <- odds_ratios_data %>%
    filter(!is.na(OddsRatio)) %>%  
    mutate(
      Reference = ifelse(Level == "No", "Yes", "No"), 
      Significant = ifelse(!is.na(PValue) & PValue < 0.05, TRUE, FALSE),  
      CI_95 = ifelse(!is.na(Lower) & !is.na(Upper), paste0("(", round(Lower, 2), ", ", round(Upper, 2), ")"), "NA")  
    ) %>%
    select(Variable, Level, Reference, OddsRatio, CI_95, PValue, Significant)  

  
  odds_ratios_restructured$Variable <- factor(odds_ratios_restructured$Variable, levels = unique(odds_ratios_restructured$Variable))
  
  if (nrow(odds_ratios_restructured) > 0) {
    
    
    odds_ratios_restructured_for_table <- odds_ratios_restructured %>%
      select(-Significant)

    
    restructured_table_html <- odds_ratios_restructured_for_table %>%
      kable("html", caption = "Restructured Odds Ratio Analysis for Medical Interpretation (Showing Both Levels)",
            col.names = c("Variable", "Level", "Reference", "Odds Ratio", "CI (95%)", "P-Value")) %>%
      kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = FALSE) %>%
      row_spec(0, bold = TRUE, background = "#333333", color = "white")
    
    
    if (any(odds_ratios_restructured$Significant == TRUE, na.rm = TRUE)) {
      restructured_table_html <- restructured_table_html %>%
        row_spec(
          which(odds_ratios_restructured$Significant == TRUE), 
          background = "#ffcccc" 
        )
    }
    
   
    restructured_table_html <- restructured_table_html %>%
      row_spec(1:nrow(odds_ratios_restructured_for_table), background = rep(c("#f9f9f9", "#ffffff"), length.out = nrow(odds_ratios_restructured_for_table)))

   
    print(restructured_table_html)
  } else {
    cat("<p><strong>Warning:</strong> No data available for restructuring after filtering. Skipping this section.</p><br>")
  }
  
} else {
  cat("<p><strong>Warning:</strong> No data available for restructuring. Skipping this section.</p><br>")
}
Restructured Odds Ratio Analysis for Medical Interpretation (Showing Both Levels)
Variable Level Reference Odds Ratio CI (95%) P-Value
oneway.No oneway No Yes 1.0000 NA NA
oneway.Yes Yes No 0.3313 (0.04, 2.74) 0.4424
twoways.No twoways No Yes 1.0000 NA NA
twoways.Yes Yes No Inf NA 0.1837
clearzone.No clearzone No Yes 1.0000 NA NA
clearzone.Yes Yes No Inf NA 0.0865
onstreetparking.No onstreetparking No Yes 1.0000 NA NA
onstreetparking.Yes Yes No 1.5270 (0.88, 2.65) 0.1624
parkinglotgarage.No parkinglotgarage No Yes 1.0000 NA NA
parkinglotgarage.Yes Yes No 0.6600 (0.38, 1.16) 0.1491
concretebarrier.No concretebarrier No Yes 1.0000 NA NA
concretebarrier.Yes Yes No 0.0000 NA 1.0000
laneofparkedcars.No laneofparkedcars No Yes 1.0000 NA NA
laneofparkedcars.Yes Yes No 0.0000 NA 0.3224
bikelanewithbarrier.No bikelanewithbarrier No Yes 1.0000 NA NA
bikelanewithbarrier.Yes Yes No Inf NA 0.0865
offroadbikepathcycletrack.No offroadbikepathcycletrack No Yes 1.0000 NA NA
offroadbikepathcycletrack.Yes Yes No 0.0000 NA 1.0000
raisedbikelane.No raisedbikelane No Yes 1.0000 NA NA
raisedbikelane.Yes Yes No 0.7917 (0.08, 7.74) 1.0000
twowayprotectedbicyclelane.No twowayprotectedbicyclelane No Yes 1.0000 NA NA
twowayprotectedbicyclelane.Yes Yes No 0.7917 (0.08, 7.74) 1.0000
onewayprotectedbicyclelane.No onewayprotectedbicyclelane No Yes 1.0000 NA NA
onewayprotectedbicyclelane.Yes Yes No Inf NA 0.2955
bufferedbicyclelaneadjacenttocurb.No bufferedbicyclelaneadjacenttocurb No Yes 1.0000 NA NA
bufferedbicyclelaneadjacenttocurb.Yes Yes No 0.4694 (0.05, 4.09) 0.6732
bufferedbicyclelaneoffsetfromcurb.No bufferedbicyclelaneoffsetfromcurb No Yes 1.0000 NA NA
bufferedbicyclelaneoffsetfromcurb.Yes Yes No Inf NA 0.2955
paintedbicyclelaneadjacenttocurb.No paintedbicyclelaneadjacenttocurb No Yes 1.0000 NA NA
paintedbicyclelaneadjacenttocurb.Yes Yes No 1.0760 (0.55, 2.09) 0.8648
paintedbicyclelaneoffsetfromcurb.No paintedbicyclelaneoffsetfromcurb No Yes 1.0000 NA NA
paintedbicyclelaneoffsetfromcurb.Yes Yes No 1.3480 (0.44, 4.17) 0.5621
bikeaccessibleshoulder.No bikeaccessibleshoulder No Yes 1.0000 NA NA
bikeaccessibleshoulder.Yes Yes No 0.9926 (0.34, 2.93) 1.0000
sharedlanewithmarkings.No sharedlanewithmarkings No Yes 1.0000 NA NA
sharedlanewithmarkings.Yes Yes No 0.2882 (0.04, 2.35) 0.2884
NULL

if (nrow(odds_ratios_data) > 0) {
  
  
  odds_ratios_restructured <- odds_ratios_data %>%
    filter(!is.na(OddsRatio)) %>% 
    mutate(
      Reference = ifelse(Level == "No", "Yes", "No"),  
      Significant = ifelse(!is.na(PValue) & PValue < 0.05, TRUE, FALSE),  
      CI_95 = ifelse(!is.na(Lower) & !is.na(Upper), paste0("(", round(Lower, 2), ", ", round(Upper, 2), ")"), "-"),  
      PValue = ifelse(is.na(PValue), "-", as.character(round(PValue, 4))),  
      OddsRatio = ifelse(is.na(OddsRatio), "-", as.character(round(OddsRatio, 4))),  
      NonInjury = ifelse(is.na(NonInjury), "-", as.character(NonInjury)), 
      p1 = ifelse(is.na(p1), "-", paste0(round(as.numeric(p1) * 100, 2), "%"))  
    ) %>%
    select(Variable, Level, Reference, NonInjury, p1, OddsRatio, CI_95, PValue, Significant)

  
  odds_ratios_grouped <- odds_ratios_restructured %>%
    arrange(Variable) %>%
    group_by(Variable) %>%
    mutate(
      Level_Grouped = paste(Level, collapse = " / "),  
      OddsRatio_Grouped = paste(OddsRatio, collapse = " / "),
      CI_95_Grouped = paste(CI_95, collapse = " / "),
      PValue_Grouped = paste(PValue, collapse = " / "),
      NonInjury_Grouped = paste(NonInjury, collapse = " / "),
      p1_Grouped = paste(p1, collapse = " / ")
    ) %>%
    slice(1) %>%  
    ungroup() %>%
    select(Variable, Level_Grouped, Reference, NonInjury_Grouped, p1_Grouped, OddsRatio_Grouped, CI_95_Grouped, PValue_Grouped, Significant)

 
  odds_ratios_grouped$Variable <- factor(odds_ratios_grouped$Variable, levels = unique(odds_ratios_grouped$Variable))
  
 
  if (nrow(odds_ratios_grouped) > 0) {
    
  
    odds_ratios_for_table <- odds_ratios_grouped %>%
      select(-Significant)

  
    restructured_table_html <- odds_ratios_for_table %>%
      kable("html", caption = "Restructured Odds Ratio Analysis for Medical Interpretation (Grouped Levels)",
            col.names = c("Variable", "Level (Yes / No)", "Reference", "Non-Injury (Count)", "Non-Injury (%)", "Odds Ratio (Yes / No)", "CI (95%) (Yes / No)", "P-Value (Yes / No)")) %>%
      kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = FALSE, position = "center") %>%
      row_spec(0, bold = TRUE, background = "#333333", color = "white") %>%
      column_spec(1:8, width = "5em", border_left = TRUE, border_right = TRUE)  

    
    if (any(odds_ratios_grouped$Significant == TRUE, na.rm = TRUE)) {
      restructured_table_html <- restructured_table_html %>%
        row_spec(
          which(odds_ratios_grouped$Significant == TRUE), 
          background = "#ffcccc"  
        )
    }
      
    restructured_table_html <- restructured_table_html %>%
      row_spec(1:nrow(odds_ratios_for_table), background = rep(c("#f9f9f9", "#ffffff"), length.out = nrow(odds_ratios_for_table)))

    
    print(restructured_table_html)
  } else {
    cat("<p><strong>Warning:</strong> No data available for restructuring after filtering. Skipping this section.</p><br>")
  }
  
} else {
  cat("<p><strong>Warning:</strong> No data available for restructuring. Skipping this section.</p><br>")
}
Error in `mutate()`:
ℹ In argument: `NonInjury = ifelse(is.na(NonInjury), "-", as.character(NonInjury))`.
Caused by error:
! object 'NonInjury' not found
Backtrace:
  1. ... %>% ...
 10. base::ifelse(is.na(NonInjury), "-", as.character(NonInjury))
Cyclist Intersection

pedestrian_midblock_data


Pedestrian Intersection



1

Odds ratio Interpretation
  1. OddsRatio:
  • This value measures the odds of the event (e.g., injury) occurring in the exposed group compared to the unexposed group.
    • An OR of 1 indicates no difference in odds between the groups.
    • An OR greater than 1 suggests that exposure is associated with higher odds of the event.
    • An OR less than 1 indicates that the exposure may be protective or reduce the odds of the event.
  1. Lower and Upper (Confidence Interval):
  • These values represent the confidence interval (typically 95%) around the odds ratio.
    • A 95% confidence interval means we are 95% confident that the true OR lies within this range.
    • If the confidence interval includes the value 1, the OR is not statistically significant (i.e., there is not enough evidence to state there’s a difference between the groups).
    • The Lower limit is the lower bound of the confidence interval, and the Upper limit is the upper bound.
  1. P-Value:
  • This value indicates the statistical significance of the association between exposure and the outcome.
    • A low p-value (usually less than 0.05) suggests that there is sufficient evidence to reject the null hypothesis, indicating a significant association between exposure and the outcome.
    • A high p-value implies that the association is not statistically significant.
  1. Injury (Cases with event) and Non-Injury (Cases without event):
  • These are the counts of cases in each category (exposed and unexposed) that have or do not have the event of interest (injury).
    • These values show the total number of observations in each group, are helpful in assessing the stability of the results since very low counts can indicate an insufficient sample size to estimate the OR accurately.
  1. p0 and p1:
  • These represent the proportions of cases with the event (injury) and without the event within each group.
    • p0 is the proportion of cases in the unexposed group that have the event of interest.
    • p1 is the proportion of cases in the exposed group that have the event of interest.
    • These proportions allow for a quick visualization of the difference in event rates between the groups.

Example Interpretation:

If you obtain an OR of 1.5 with a confidence interval of 1.2 to 1.8 and a p-value of 0.01, you could interpret this as: * There is a significant association (p-value < 0.05) between the exposure and the event. * The exposed group has a 50% higher chance of experiencing the event (injury) compared to the unexposed group. * Since the confidence interval does not include 1, this relationship is statistically significant.

On the other hand, if the OR is close to 1, the confidence interval includes 1 (e.g., OR = 1.1, CI = 0.9 to 1.3), and the p-value is high (> 0.05), then there is not enough evidence to conclude that there is an association between the exposure and the outcome.


  1. When using the epitab function from the epitools package in R to calculate odds ratios (OR), it generates several important statistics and measures that help interpret the relationship between an exposure (e.g., a particular road feature) and an outcome (e.g., injury).↩︎

LS0tCnRpdGxlOiAiQWNjaWRlbnQgQW5hbHlzaXM6IEN5Y2xpc3RzIGFuZCBQZWRlc3RyaWFucyIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICBkZl9wcmludDogcGFnZWQKICAgIHRvYzogdHJ1ZQogICAgdG9jX2RlcHRoOiAyCiAgICB0aGVtZTogY29zbW8KICBwZGZfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIHRvY19kZXB0aDogJzInCi0tLQoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KIyBMb2FkIG5lY2Vzc2FyeSBsaWJyYXJpZXMKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5cikKbGlicmFyeShrbml0cikKbGlicmFyeShrYWJsZUV4dHJhKQpsaWJyYXJ5KGVwaXRvb2xzKQpsaWJyYXJ5KGh0bWxUYWJsZSkKbGlicmFyeShodG1sdG9vbHMpCgpkYXRhIDwtIHJlYWQuY3N2KCIvVXNlcnMvbmF0YWxpb2Nob2EvUm9hZFNhZmV0eS9SZXN1bHRzSUNCQy5jc3YiKQpgYGAKCiMjIyMjIyBDeWNsaXN0IE1pZEJsb2NrCgpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQoKIyBGaWx0ZXIgZGF0YSBmb3IgQ3ljbGlzdCBNaWRCbG9jayAKZ3JvdXBfZGF0YSA8LSBkYXRhICU+JQogIGZpbHRlcihtb2RlID09ICJDeWNsaXN0IiwgaW50ZXJzZWN0aW9uID09ICJObyIpCgppZiAobnJvdyhncm91cF9kYXRhKSA+IDApIHsKICAjIFNwZWNpZnkgdGhlIHZhcmlhYmxlcyB0byBhbmFseXplIGZvciBDeWNsaXN0IE1pZEJsb2NrIAogIGdyb3VwX3ZhcnMgPC0gYygib25ld2F5IiwgInR3b3dheXMiLCAiY2xlYXJ6b25lIiwgIm9uc3RyZWV0cGFya2luZyIsIAogICAgICAgICAgICAgICAgICAicGFya2luZ2xvdGdhcmFnZSIsICJjb25jcmV0ZWJhcnJpZXIiLCAibGFuZW9mcGFya2VkY2FycyIsIAogICAgICAgICAgICAgICAgICAiYmlrZWxhbmV3aXRoYmFycmllciIsICJvZmZyb2FkYmlrZXBhdGhjeWNsZXRyYWNrIiwgCiAgICAgICAgICAgICAgICAgICJyYWlzZWRiaWtlbGFuZSIsICJ0d293YXlwcm90ZWN0ZWRiaWN5Y2xlbGFuZSIsIAogICAgICAgICAgICAgICAgICAib25ld2F5cHJvdGVjdGVkYmljeWNsZWxhbmUiLCAiYnVmZmVyZWRiaWN5Y2xlbGFuZWFkamFjZW50dG9jdXJiIiwgCiAgICAgICAgICAgICAgICAgICJidWZmZXJlZGJpY3ljbGVsYW5lb2Zmc2V0ZnJvbWN1cmIiLCAKICAgICAgICAgICAgICAgICAgInBhaW50ZWRiaWN5Y2xlbGFuZWFkamFjZW50dG9jdXJiIiwgCiAgICAgICAgICAgICAgICAgICJwYWludGVkYmljeWNsZWxhbmVvZmZzZXRmcm9tY3VyYiIsICJiaWtlYWNjZXNzaWJsZXNob3VsZGVyIiwgCiAgICAgICAgICAgICAgICAgICJzaGFyZWRsYW5ld2l0aG1hcmtpbmdzIikKCiAgb2Rkc19yYXRpb3NfbGlzdCA8LSBsaXN0KCkKICBzdGFuZGFyZF9jb2x1bW5zIDwtIGMoIlZhcmlhYmxlIiwgIkxldmVsIiwgIkluanVyeSIsICJwMCIsICJOb24tSW5qdXJ5IiwgInAxIiwgIk9kZHNSYXRpbyIsICJMb3dlciIsICJVcHBlciIsICJQVmFsdWUiKQoKICBmb3IgKHZhciBpbiBncm91cF92YXJzKSB7CiAgICBpZiAodmFyICVpbiUgbmFtZXMoZ3JvdXBfZGF0YSkpIHsKICAgICAgb2Rkc19yYXRpb19yZXN1bHQgPC0gdHJ5Q2F0Y2goewogICAgICAgIGlmIChuX2Rpc3RpbmN0KGdyb3VwX2RhdGFbW3Zhcl1dKSA9PSAyKSB7CiAgICAgICAgICBvZGRzX2RhdGEgPC0gZ3JvdXBfZGF0YSAlPiUKICAgICAgICAgICAgc2VsZWN0KGFsbF9vZih2YXIpLCBjcmFzaHNldmVyaXR5KSAlPiUKICAgICAgICAgICAgdGFibGUoKSAlPiUKICAgICAgICAgICAgYXMubWF0cml4KCkKICAgICAgICAgIAogICAgICAgICAgb2Rkc19yYXRpb190YWJsZSA8LSBhcy5kYXRhLmZyYW1lKGVwaXRhYihvZGRzX2RhdGEsIG1ldGhvZCA9ICJvZGRzcmF0aW8iKSR0YWIpICU+JQogICAgICAgICAgICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCByb3VuZCwgNCkpCiAgICAgICAgICAKICAgICAgICAgIG9kZHNfcmF0aW9fdGFibGUgPC0gY2JpbmQoVmFyaWFibGUgPSB2YXIsIExldmVsID0gcm93bmFtZXMob2Rkc19yYXRpb190YWJsZSksIG9kZHNfcmF0aW9fdGFibGUpCiAgICAgICAgICBuYW1lcyhvZGRzX3JhdGlvX3RhYmxlKSA8LSBzdGFuZGFyZF9jb2x1bW5zCiAgICAgICAgICBvZGRzX3JhdGlvX3RhYmxlCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGRhdGEuZnJhbWUoCiAgICAgICAgICAgIFZhcmlhYmxlID0gdmFyLCBMZXZlbCA9IE5BLCBJbmp1cnkgPSAiTm90IGFwcGxpY2FibGUiLCAKICAgICAgICAgICAgcDAgPSBOQSwgTm9uSW5qdXJ5ID0gTkEsIHAxID0gTkEsIE9kZHNSYXRpbyA9IE5BLCAKICAgICAgICAgICAgTG93ZXIgPSBOQSwgVXBwZXIgPSBOQSwgUFZhbHVlID0gTkEsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRQogICAgICAgICAgKQogICAgICAgIH0KICAgICAgfSwgZXJyb3IgPSBmdW5jdGlvbihlKSB7CiAgICAgICAgZGF0YS5mcmFtZSgKICAgICAgICAgIFZhcmlhYmxlID0gdmFyLCBMZXZlbCA9IE5BLCBJbmp1cnkgPSAiTm90IGFwcGxpY2FibGUiLCAKICAgICAgICAgIHAwID0gTkEsIE5vbkluanVyeSA9IE5BLCBwMSA9IE5BLCBPZGRzUmF0aW8gPSBOQSwgCiAgICAgICAgICBMb3dlciA9IE5BLCBVcHBlciA9IE5BLCBQVmFsdWUgPSBOQSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFCiAgICAgICAgKQogICAgICB9KQogICAgICAKICAgICAgb2Rkc19yYXRpb3NfbGlzdFtbdmFyXV0gPC0gb2Rkc19yYXRpb19yZXN1bHQKICAgIH0KICB9CiAgCiAgb2Rkc19yYXRpb3NfZGF0YSA8LSBkby5jYWxsKHJiaW5kLCBvZGRzX3JhdGlvc19saXN0KQogIHJvd19jb2xvcnMgPC0gcmVwKGMoIiNmOWY5ZjkiLCAiI2ZmZmZmZiIpLCBsZW5ndGgub3V0ID0gbnJvdyhvZGRzX3JhdGlvc19kYXRhKSkKICBvZGRzX3JhdGlvc19kYXRhJFZhcmlhYmxlIDwtIGlmZWxzZShkdXBsaWNhdGVkKG9kZHNfcmF0aW9zX2RhdGEkVmFyaWFibGUpLCAiIiwgb2Rkc19yYXRpb3NfZGF0YSRWYXJpYWJsZSkKCiAgZmluYWxfdGFibGVfaHRtbCA8LSBodG1sVGFibGUoCiAgICBvZGRzX3JhdGlvc19kYXRhLAogICAgaGVhZGVyID0gYygiVmFyaWFibGUiLCAiTGV2ZWwiLCAiSW5qdXJ5IiwgInAwIiwgIk5vbi1Jbmp1cnkiLCAicDEiLCAiT2Rkc1JhdGlvIiwgIkxvd2VyIiwgIlVwcGVyIiwgIlAtVmFsdWUiKSwKICAgIGFsaWduID0gJ2xjY2NjY2NjY2MnLAogICAgcm5hbWVzID0gRkFMU0UsCiAgICBjc3MuY2VsbCA9ICJ0ZXh0LWFsaWduOiBjZW50ZXI7IHBhZGRpbmc6IDEycHggMTVweDsgZm9udC1zaXplOiAxMnB4OyB3aGl0ZS1zcGFjZTogbm93cmFwOyIsCiAgICBjc3Mucm93ID0gc3ByaW50ZigiYmFja2dyb3VuZC1jb2xvcjogJXM7Iiwgcm93X2NvbG9ycyksCiAgICBoZWFkZXIuY3NzID0gImJhY2tncm91bmQtY29sb3I6ICMzMzMzMzM7IGZvbnQtc2l6ZTogMTRweDsgdGV4dC1hbGlnbjogY2VudGVyOyBjb2xvcjogd2hpdGU7IiwKICAgIGNhcHRpb24gPSAiPGgzIHN0eWxlPSd0ZXh0LWFsaWduOiBjZW50ZXI7Jz5BbmFseXNpcyBmb3IgQ3ljbGlzdCBNaWRCbG9jazwvaDM+CiAgICAgICAgICAgICAgIDxwIHN0eWxlPSd0ZXh0LWFsaWduOiBjZW50ZXI7Jz48ZW0+VGhpcyBhbmFseXNpcyBmb2N1c2VzIG9uIG1vZGU6IGN5Y2xpc3QgfCBpbnRlcnNlY3Rpb246IG5vPC9lbT48L3A+IgogICkKCiAgcHJpbnQoSFRNTChmaW5hbF90YWJsZV9odG1sKSkKfSBlbHNlIHsKICBjYXQoIjxwPjxzdHJvbmc+V2FybmluZzo8L3N0cm9uZz4gTm8gZGF0YSBhdmFpbGFibGUgZm9yIEN5Y2xpc3QgTWlkQmxvY2suIFNraXBwaW5nIGFuYWx5c2lzIGZvciB0aGlzIGdyb3VwLjwvcD48YnI+IikKfQoKYGBgCgpgYGB7cn0KCmlmIChucm93KG9kZHNfcmF0aW9zX2RhdGEpID4gMCkgewogIAoKICBvZGRzX3JhdGlvc19yZXN0cnVjdHVyZWQgPC0gb2Rkc19yYXRpb3NfZGF0YSAlPiUKICAgIGZpbHRlcighaXMubmEoT2Rkc1JhdGlvKSkgJT4lICAKICAgIG11dGF0ZShSZWZlcmVuY2UgPSBpZmVsc2UoTGV2ZWwgPT0gIk5vIiwgIlllcyIsICJObyIpKSAlPiUgIAogICAgc2VsZWN0KFZhcmlhYmxlLCBMZXZlbCwgUmVmZXJlbmNlLCBPZGRzUmF0aW8sIExvd2VyLCBVcHBlciwgUFZhbHVlKQoKICAKICBvZGRzX3JhdGlvc19yZXN0cnVjdHVyZWQkVmFyaWFibGUgPC0gZmFjdG9yKG9kZHNfcmF0aW9zX3Jlc3RydWN0dXJlZCRWYXJpYWJsZSwgbGV2ZWxzID0gdW5pcXVlKG9kZHNfcmF0aW9zX3Jlc3RydWN0dXJlZCRWYXJpYWJsZSkpCiAgCiAgCiAgcmVzdHJ1Y3R1cmVkX3RhYmxlX2h0bWwgPC0gb2Rkc19yYXRpb3NfcmVzdHJ1Y3R1cmVkICU+JQogICAga2FibGUoImh0bWwiLCBjYXB0aW9uID0gIlJlc3RydWN0dXJlZCBPZGRzIFJhdGlvIEFuYWx5c2lzIGZvciBNZWRpY2FsIEludGVycHJldGF0aW9uIiwKICAgICAgICAgIGNvbC5uYW1lcyA9IGMoIlZhcmlhYmxlIiwgIkxldmVsIiwgIlJlZmVyZW5jZSIsICJPZGRzIFJhdGlvIiwgIkxvd2VyIDk1JSBDSSIsICJVcHBlciA5NSUgQ0kiLCAiUC1WYWx1ZSIpKSAlPiUKICAgIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIsICJyZXNwb25zaXZlIiksIGZ1bGxfd2lkdGggPSBGQUxTRSkgJT4lCiAgICByb3dfc3BlYygwLCBib2xkID0gVFJVRSwgYmFja2dyb3VuZCA9ICIjMzMzMzMzIiwgY29sb3IgPSAid2hpdGUiKSAlPiUKICAgIHJvd19zcGVjKDE6bnJvdyhvZGRzX3JhdGlvc19yZXN0cnVjdHVyZWQpLCBiYWNrZ3JvdW5kID0gcmVwKGMoIiNmOWY5ZjkiLCAiI2ZmZmZmZiIpLCBsZW5ndGgub3V0ID0gbnJvdyhvZGRzX3JhdGlvc19yZXN0cnVjdHVyZWQpKSkgJT4lCiAgICBhZGRfaGVhZGVyX2Fib3ZlKGMoIiAiID0gMywgIk9kZHMgUmF0aW8gQW5hbHlzaXMiID0gNSkpIAoKICBwcmludChyZXN0cnVjdHVyZWRfdGFibGVfaHRtbCkKfSBlbHNlIHsKICBjYXQoIjxwPjxzdHJvbmc+V2FybmluZzo8L3N0cm9uZz4gTm8gZGF0YSBhdmFpbGFibGUgZm9yIHJlc3RydWN0dXJpbmcuIFNraXBwaW5nIHRoaXMgc2VjdGlvbi48L3A+PGJyPiIpCn0KCmBgYAoKYGBge3J9CgppZiAobnJvdyhvZGRzX3JhdGlvc19kYXRhKSA+IDApIHsKICAKIAogIG9kZHNfcmF0aW9zX3Jlc3RydWN0dXJlZCA8LSBvZGRzX3JhdGlvc19kYXRhICU+JQogICAgZmlsdGVyKCFpcy5uYShPZGRzUmF0aW8pKSAlPiUgIAogICAgbXV0YXRlKFJlZmVyZW5jZSA9IGlmZWxzZShMZXZlbCA9PSAiTm8iLCAiWWVzIiwgIk5vIikpICU+JSAgCiAgICBzZWxlY3QoVmFyaWFibGUsIExldmVsLCBSZWZlcmVuY2UsIE9kZHNSYXRpbywgTG93ZXIsIFVwcGVyLCBQVmFsdWUpCgogIAogIG9kZHNfcmF0aW9zX3Jlc3RydWN0dXJlZCRWYXJpYWJsZSA8LSBmYWN0b3Iob2Rkc19yYXRpb3NfcmVzdHJ1Y3R1cmVkJFZhcmlhYmxlLCBsZXZlbHMgPSB1bmlxdWUob2Rkc19yYXRpb3NfcmVzdHJ1Y3R1cmVkJFZhcmlhYmxlKSkKICAKICAKICByZXN0cnVjdHVyZWRfdGFibGVfaHRtbCA8LSBvZGRzX3JhdGlvc19yZXN0cnVjdHVyZWQgJT4lCiAgICBrYWJsZSgiaHRtbCIsIGNhcHRpb24gPSAiUmVzdHJ1Y3R1cmVkIE9kZHMgUmF0aW8gQW5hbHlzaXMgZm9yIE1lZGljYWwgSW50ZXJwcmV0YXRpb24iLAogICAgICAgICAgY29sLm5hbWVzID0gYygiVmFyaWFibGUiLCAiTGV2ZWwiLCAiUmVmZXJlbmNlIiwgIk9kZHMgUmF0aW8iLCAiTG93ZXIgOTUlIENJIiwgIlVwcGVyIDk1JSBDSSIsICJQLVZhbHVlIikpICU+JQogICAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiLCAiY29uZGVuc2VkIiwgInJlc3BvbnNpdmUiKSwgZnVsbF93aWR0aCA9IEZBTFNFKSAlPiUKICAgIHJvd19zcGVjKDAsIGJvbGQgPSBUUlVFLCBiYWNrZ3JvdW5kID0gIiMzMzMzMzMiLCBjb2xvciA9ICJ3aGl0ZSIpICU+JQogICAgcm93X3NwZWMoMTpucm93KG9kZHNfcmF0aW9zX3Jlc3RydWN0dXJlZCksIGJhY2tncm91bmQgPSByZXAoYygiI2Y5ZjlmOSIsICIjZmZmZmZmIiksIGxlbmd0aC5vdXQgPSBucm93KG9kZHNfcmF0aW9zX3Jlc3RydWN0dXJlZCkpKQoKICBwcmludChyZXN0cnVjdHVyZWRfdGFibGVfaHRtbCkKfSBlbHNlIHsKICBjYXQoIjxwPjxzdHJvbmc+V2FybmluZzo8L3N0cm9uZz4gTm8gZGF0YSBhdmFpbGFibGUgZm9yIHJlc3RydWN0dXJpbmcuIFNraXBwaW5nIHRoaXMgc2VjdGlvbi48L3A+PGJyPiIpCn0KCmBgYAoKCmBgYHtyfQoKaWYgKG5yb3cob2Rkc19yYXRpb3NfZGF0YSkgPiAwKSB7CiAgCiAgCiAgb2Rkc19yYXRpb3NfcmVzdHJ1Y3R1cmVkIDwtIG9kZHNfcmF0aW9zX2RhdGEgJT4lCiAgICBmaWx0ZXIoIWlzLm5hKE9kZHNSYXRpbykpICU+JSAKICAgIG11dGF0ZSgKICAgICAgUmVmZXJlbmNlID0gaWZlbHNlKExldmVsID09ICJObyIsICJZZXMiLCAiTm8iKSwgCiAgICAgIFNpZ25pZmljYW50ID0gaWZlbHNlKFBWYWx1ZSA8IDAuMDUsIFRSVUUsIEZBTFNFKSwgIAogICAgICBDSV85NSA9IGlmZWxzZSghaXMubmEoTG93ZXIpICYgIWlzLm5hKFVwcGVyKSwgcGFzdGUwKCIoIiwgcm91bmQoTG93ZXIsIDIpLCAiLCAiLCByb3VuZChVcHBlciwgMiksICIpIiksICJOQSIpIAogICAgKSAlPiUKICAgIHNlbGVjdChWYXJpYWJsZSwgTGV2ZWwsIFJlZmVyZW5jZSwgT2Rkc1JhdGlvLCBDSV85NSwgUFZhbHVlLCBTaWduaWZpY2FudCkgIAoKIAogIG9kZHNfcmF0aW9zX3Jlc3RydWN0dXJlZF9maWx0ZXJlZCA8LSBvZGRzX3JhdGlvc19yZXN0cnVjdHVyZWQgJT4lCiAgICBmaWx0ZXIoIShPZGRzUmF0aW8gPT0gMSAmIENJXzk1ID09ICJOQSIpKQoKIAogIG9kZHNfcmF0aW9zX3Jlc3RydWN0dXJlZF9maWx0ZXJlZCRWYXJpYWJsZSA8LSBmYWN0b3Iob2Rkc19yYXRpb3NfcmVzdHJ1Y3R1cmVkX2ZpbHRlcmVkJFZhcmlhYmxlLCBsZXZlbHMgPSB1bmlxdWUob2Rkc19yYXRpb3NfcmVzdHJ1Y3R1cmVkX2ZpbHRlcmVkJFZhcmlhYmxlKSkKICAKIAogIGlmIChucm93KG9kZHNfcmF0aW9zX3Jlc3RydWN0dXJlZF9maWx0ZXJlZCkgPiAwKSB7CiAgICAKICAgIAogICAgb2Rkc19yYXRpb3NfcmVzdHJ1Y3R1cmVkX2ZpbHRlcmVkX2Zvcl90YWJsZSA8LSBvZGRzX3JhdGlvc19yZXN0cnVjdHVyZWRfZmlsdGVyZWQgJT4lCiAgICAgIHNlbGVjdCgtU2lnbmlmaWNhbnQpCgogICAgCiAgICByZXN0cnVjdHVyZWRfdGFibGVfaHRtbCA8LSBvZGRzX3JhdGlvc19yZXN0cnVjdHVyZWRfZmlsdGVyZWRfZm9yX3RhYmxlICU+JQogICAgICBrYWJsZSgiaHRtbCIsIGNhcHRpb24gPSAiUmVzdHJ1Y3R1cmVkIE9kZHMgUmF0aW8gQW5hbHlzaXMgZm9yIE1lZGljYWwgSW50ZXJwcmV0YXRpb24iLAogICAgICAgICAgICBjb2wubmFtZXMgPSBjKCJWYXJpYWJsZSIsICJMZXZlbCIsICJSZWZlcmVuY2UiLCAiT2RkcyBSYXRpbyIsICJDSSAoOTUlKSIsICJQLVZhbHVlIikpICU+JQogICAgICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJjb25kZW5zZWQiLCAicmVzcG9uc2l2ZSIpLCBmdWxsX3dpZHRoID0gRkFMU0UpICU+JQogICAgICByb3dfc3BlYygwLCBib2xkID0gVFJVRSwgYmFja2dyb3VuZCA9ICIjMzMzMzMzIiwgY29sb3IgPSAid2hpdGUiKQogICAgCiAgIAogICAgaWYgKGFueShvZGRzX3JhdGlvc19yZXN0cnVjdHVyZWRfZmlsdGVyZWQkU2lnbmlmaWNhbnQgPT0gVFJVRSkpIHsKICAgICAgcmVzdHJ1Y3R1cmVkX3RhYmxlX2h0bWwgPC0gcmVzdHJ1Y3R1cmVkX3RhYmxlX2h0bWwgJT4lCiAgICAgICAgcm93X3NwZWMoCiAgICAgICAgICB3aGljaChvZGRzX3JhdGlvc19yZXN0cnVjdHVyZWRfZmlsdGVyZWQkU2lnbmlmaWNhbnQgPT0gVFJVRSksIAogICAgICAgICAgYmFja2dyb3VuZCA9ICIjZmZjY2NjIiAgCiAgICAgICAgKQogICAgfQogICAgCiAgIAogICAgcmVzdHJ1Y3R1cmVkX3RhYmxlX2h0bWwgPC0gcmVzdHJ1Y3R1cmVkX3RhYmxlX2h0bWwgJT4lCiAgICAgIHJvd19zcGVjKDE6bnJvdyhvZGRzX3JhdGlvc19yZXN0cnVjdHVyZWRfZmlsdGVyZWRfZm9yX3RhYmxlKSwgYmFja2dyb3VuZCA9IHJlcChjKCIjZjlmOWY5IiwgIiNmZmZmZmYiKSwgbGVuZ3RoLm91dCA9IG5yb3cob2Rkc19yYXRpb3NfcmVzdHJ1Y3R1cmVkX2ZpbHRlcmVkX2Zvcl90YWJsZSkpKQoKICAgIAogICAgcHJpbnQocmVzdHJ1Y3R1cmVkX3RhYmxlX2h0bWwpCiAgfSBlbHNlIHsKICAgIGNhdCgiPHA+PHN0cm9uZz5XYXJuaW5nOjwvc3Ryb25nPiBObyBkYXRhIGF2YWlsYWJsZSBmb3IgcmVzdHJ1Y3R1cmluZyBhZnRlciBmaWx0ZXJpbmcuIFNraXBwaW5nIHRoaXMgc2VjdGlvbi48L3A+PGJyPiIpCiAgfQogIAp9IGVsc2UgewogIGNhdCgiPHA+PHN0cm9uZz5XYXJuaW5nOjwvc3Ryb25nPiBObyBkYXRhIGF2YWlsYWJsZSBmb3IgcmVzdHJ1Y3R1cmluZy4gU2tpcHBpbmcgdGhpcyBzZWN0aW9uLjwvcD48YnI+IikKfQoKCmBgYApgYGB7cn0KCmlmIChucm93KG9kZHNfcmF0aW9zX2RhdGEpID4gMCkgewogIAogIAogIG9kZHNfcmF0aW9zX3Jlc3RydWN0dXJlZCA8LSBvZGRzX3JhdGlvc19kYXRhICU+JQogICAgZmlsdGVyKCFpcy5uYShPZGRzUmF0aW8pKSAlPiUgIAogICAgbXV0YXRlKAogICAgICBSZWZlcmVuY2UgPSBpZmVsc2UoTGV2ZWwgPT0gIk5vIiwgIlllcyIsICJObyIpLCAKICAgICAgU2lnbmlmaWNhbnQgPSBpZmVsc2UoIWlzLm5hKFBWYWx1ZSkgJiBQVmFsdWUgPCAwLjA1LCBUUlVFLCBGQUxTRSksICAKICAgICAgQ0lfOTUgPSBpZmVsc2UoIWlzLm5hKExvd2VyKSAmICFpcy5uYShVcHBlciksIHBhc3RlMCgiKCIsIHJvdW5kKExvd2VyLCAyKSwgIiwgIiwgcm91bmQoVXBwZXIsIDIpLCAiKSIpLCAiTkEiKSAgCiAgICApICU+JQogICAgc2VsZWN0KFZhcmlhYmxlLCBMZXZlbCwgUmVmZXJlbmNlLCBPZGRzUmF0aW8sIENJXzk1LCBQVmFsdWUsIFNpZ25pZmljYW50KSAgCgogIAogIG9kZHNfcmF0aW9zX3Jlc3RydWN0dXJlZCRWYXJpYWJsZSA8LSBmYWN0b3Iob2Rkc19yYXRpb3NfcmVzdHJ1Y3R1cmVkJFZhcmlhYmxlLCBsZXZlbHMgPSB1bmlxdWUob2Rkc19yYXRpb3NfcmVzdHJ1Y3R1cmVkJFZhcmlhYmxlKSkKICAKICBpZiAobnJvdyhvZGRzX3JhdGlvc19yZXN0cnVjdHVyZWQpID4gMCkgewogICAgCiAgICAKICAgIG9kZHNfcmF0aW9zX3Jlc3RydWN0dXJlZF9mb3JfdGFibGUgPC0gb2Rkc19yYXRpb3NfcmVzdHJ1Y3R1cmVkICU+JQogICAgICBzZWxlY3QoLVNpZ25pZmljYW50KQoKICAgIAogICAgcmVzdHJ1Y3R1cmVkX3RhYmxlX2h0bWwgPC0gb2Rkc19yYXRpb3NfcmVzdHJ1Y3R1cmVkX2Zvcl90YWJsZSAlPiUKICAgICAga2FibGUoImh0bWwiLCBjYXB0aW9uID0gIlJlc3RydWN0dXJlZCBPZGRzIFJhdGlvIEFuYWx5c2lzIGZvciBNZWRpY2FsIEludGVycHJldGF0aW9uIChTaG93aW5nIEJvdGggTGV2ZWxzKSIsCiAgICAgICAgICAgIGNvbC5uYW1lcyA9IGMoIlZhcmlhYmxlIiwgIkxldmVsIiwgIlJlZmVyZW5jZSIsICJPZGRzIFJhdGlvIiwgIkNJICg5NSUpIiwgIlAtVmFsdWUiKSkgJT4lCiAgICAgIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIsICJyZXNwb25zaXZlIiksIGZ1bGxfd2lkdGggPSBGQUxTRSkgJT4lCiAgICAgIHJvd19zcGVjKDAsIGJvbGQgPSBUUlVFLCBiYWNrZ3JvdW5kID0gIiMzMzMzMzMiLCBjb2xvciA9ICJ3aGl0ZSIpCiAgICAKICAgIAogICAgaWYgKGFueShvZGRzX3JhdGlvc19yZXN0cnVjdHVyZWQkU2lnbmlmaWNhbnQgPT0gVFJVRSwgbmEucm0gPSBUUlVFKSkgewogICAgICByZXN0cnVjdHVyZWRfdGFibGVfaHRtbCA8LSByZXN0cnVjdHVyZWRfdGFibGVfaHRtbCAlPiUKICAgICAgICByb3dfc3BlYygKICAgICAgICAgIHdoaWNoKG9kZHNfcmF0aW9zX3Jlc3RydWN0dXJlZCRTaWduaWZpY2FudCA9PSBUUlVFKSwgCiAgICAgICAgICBiYWNrZ3JvdW5kID0gIiNmZmNjY2MiIAogICAgICAgICkKICAgIH0KICAgIAogICAKICAgIHJlc3RydWN0dXJlZF90YWJsZV9odG1sIDwtIHJlc3RydWN0dXJlZF90YWJsZV9odG1sICU+JQogICAgICByb3dfc3BlYygxOm5yb3cob2Rkc19yYXRpb3NfcmVzdHJ1Y3R1cmVkX2Zvcl90YWJsZSksIGJhY2tncm91bmQgPSByZXAoYygiI2Y5ZjlmOSIsICIjZmZmZmZmIiksIGxlbmd0aC5vdXQgPSBucm93KG9kZHNfcmF0aW9zX3Jlc3RydWN0dXJlZF9mb3JfdGFibGUpKSkKCiAgIAogICAgcHJpbnQocmVzdHJ1Y3R1cmVkX3RhYmxlX2h0bWwpCiAgfSBlbHNlIHsKICAgIGNhdCgiPHA+PHN0cm9uZz5XYXJuaW5nOjwvc3Ryb25nPiBObyBkYXRhIGF2YWlsYWJsZSBmb3IgcmVzdHJ1Y3R1cmluZyBhZnRlciBmaWx0ZXJpbmcuIFNraXBwaW5nIHRoaXMgc2VjdGlvbi48L3A+PGJyPiIpCiAgfQogIAp9IGVsc2UgewogIGNhdCgiPHA+PHN0cm9uZz5XYXJuaW5nOjwvc3Ryb25nPiBObyBkYXRhIGF2YWlsYWJsZSBmb3IgcmVzdHJ1Y3R1cmluZy4gU2tpcHBpbmcgdGhpcyBzZWN0aW9uLjwvcD48YnI+IikKfQoKYGBgCgoKYGBge3J9CgppZiAobnJvdyhvZGRzX3JhdGlvc19kYXRhKSA+IDApIHsKICAKICAKICBvZGRzX3JhdGlvc19yZXN0cnVjdHVyZWQgPC0gb2Rkc19yYXRpb3NfZGF0YSAlPiUKICAgIGZpbHRlcighaXMubmEoT2Rkc1JhdGlvKSkgJT4lIAogICAgbXV0YXRlKAogICAgICBSZWZlcmVuY2UgPSBpZmVsc2UoTGV2ZWwgPT0gIk5vIiwgIlllcyIsICJObyIpLCAgCiAgICAgIFNpZ25pZmljYW50ID0gaWZlbHNlKCFpcy5uYShQVmFsdWUpICYgUFZhbHVlIDwgMC4wNSwgVFJVRSwgRkFMU0UpLCAgCiAgICAgIENJXzk1ID0gaWZlbHNlKCFpcy5uYShMb3dlcikgJiAhaXMubmEoVXBwZXIpLCBwYXN0ZTAoIigiLCByb3VuZChMb3dlciwgMiksICIsICIsIHJvdW5kKFVwcGVyLCAyKSwgIikiKSwgIi0iKSwgIAogICAgICBQVmFsdWUgPSBpZmVsc2UoaXMubmEoUFZhbHVlKSwgIi0iLCBhcy5jaGFyYWN0ZXIocm91bmQoUFZhbHVlLCA0KSkpLCAgCiAgICAgIE9kZHNSYXRpbyA9IGlmZWxzZShpcy5uYShPZGRzUmF0aW8pLCAiLSIsIGFzLmNoYXJhY3Rlcihyb3VuZChPZGRzUmF0aW8sIDQpKSksICAKICAgICAgTm9uSW5qdXJ5ID0gaWZlbHNlKGlzLm5hKE5vbkluanVyeSksICItIiwgYXMuY2hhcmFjdGVyKE5vbkluanVyeSkpLCAKICAgICAgcDEgPSBpZmVsc2UoaXMubmEocDEpLCAiLSIsIHBhc3RlMChyb3VuZChhcy5udW1lcmljKHAxKSAqIDEwMCwgMiksICIlIikpICAKICAgICkgJT4lCiAgICBzZWxlY3QoVmFyaWFibGUsIExldmVsLCBSZWZlcmVuY2UsIE5vbkluanVyeSwgcDEsIE9kZHNSYXRpbywgQ0lfOTUsIFBWYWx1ZSwgU2lnbmlmaWNhbnQpCgogIAogIG9kZHNfcmF0aW9zX2dyb3VwZWQgPC0gb2Rkc19yYXRpb3NfcmVzdHJ1Y3R1cmVkICU+JQogICAgYXJyYW5nZShWYXJpYWJsZSkgJT4lCiAgICBncm91cF9ieShWYXJpYWJsZSkgJT4lCiAgICBtdXRhdGUoCiAgICAgIExldmVsX0dyb3VwZWQgPSBwYXN0ZShMZXZlbCwgY29sbGFwc2UgPSAiIC8gIiksICAKICAgICAgT2Rkc1JhdGlvX0dyb3VwZWQgPSBwYXN0ZShPZGRzUmF0aW8sIGNvbGxhcHNlID0gIiAvICIpLAogICAgICBDSV85NV9Hcm91cGVkID0gcGFzdGUoQ0lfOTUsIGNvbGxhcHNlID0gIiAvICIpLAogICAgICBQVmFsdWVfR3JvdXBlZCA9IHBhc3RlKFBWYWx1ZSwgY29sbGFwc2UgPSAiIC8gIiksCiAgICAgIE5vbkluanVyeV9Hcm91cGVkID0gcGFzdGUoTm9uSW5qdXJ5LCBjb2xsYXBzZSA9ICIgLyAiKSwKICAgICAgcDFfR3JvdXBlZCA9IHBhc3RlKHAxLCBjb2xsYXBzZSA9ICIgLyAiKQogICAgKSAlPiUKICAgIHNsaWNlKDEpICU+JSAgCiAgICB1bmdyb3VwKCkgJT4lCiAgICBzZWxlY3QoVmFyaWFibGUsIExldmVsX0dyb3VwZWQsIFJlZmVyZW5jZSwgTm9uSW5qdXJ5X0dyb3VwZWQsIHAxX0dyb3VwZWQsIE9kZHNSYXRpb19Hcm91cGVkLCBDSV85NV9Hcm91cGVkLCBQVmFsdWVfR3JvdXBlZCwgU2lnbmlmaWNhbnQpCgogCiAgb2Rkc19yYXRpb3NfZ3JvdXBlZCRWYXJpYWJsZSA8LSBmYWN0b3Iob2Rkc19yYXRpb3NfZ3JvdXBlZCRWYXJpYWJsZSwgbGV2ZWxzID0gdW5pcXVlKG9kZHNfcmF0aW9zX2dyb3VwZWQkVmFyaWFibGUpKQogIAogCiAgaWYgKG5yb3cob2Rkc19yYXRpb3NfZ3JvdXBlZCkgPiAwKSB7CiAgICAKICAKICAgIG9kZHNfcmF0aW9zX2Zvcl90YWJsZSA8LSBvZGRzX3JhdGlvc19ncm91cGVkICU+JQogICAgICBzZWxlY3QoLVNpZ25pZmljYW50KQoKICAKICAgIHJlc3RydWN0dXJlZF90YWJsZV9odG1sIDwtIG9kZHNfcmF0aW9zX2Zvcl90YWJsZSAlPiUKICAgICAga2FibGUoImh0bWwiLCBjYXB0aW9uID0gIlJlc3RydWN0dXJlZCBPZGRzIFJhdGlvIEFuYWx5c2lzIGZvciBNZWRpY2FsIEludGVycHJldGF0aW9uIChHcm91cGVkIExldmVscykiLAogICAgICAgICAgICBjb2wubmFtZXMgPSBjKCJWYXJpYWJsZSIsICJMZXZlbCAoWWVzIC8gTm8pIiwgIlJlZmVyZW5jZSIsICJOb24tSW5qdXJ5IChDb3VudCkiLCAiTm9uLUluanVyeSAoJSkiLCAiT2RkcyBSYXRpbyAoWWVzIC8gTm8pIiwgIkNJICg5NSUpIChZZXMgLyBObykiLCAiUC1WYWx1ZSAoWWVzIC8gTm8pIikpICU+JQogICAgICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJjb25kZW5zZWQiLCAicmVzcG9uc2l2ZSIpLCBmdWxsX3dpZHRoID0gRkFMU0UsIHBvc2l0aW9uID0gImNlbnRlciIpICU+JQogICAgICByb3dfc3BlYygwLCBib2xkID0gVFJVRSwgYmFja2dyb3VuZCA9ICIjMzMzMzMzIiwgY29sb3IgPSAid2hpdGUiKSAlPiUKICAgICAgY29sdW1uX3NwZWMoMTo4LCB3aWR0aCA9ICI1ZW0iLCBib3JkZXJfbGVmdCA9IFRSVUUsIGJvcmRlcl9yaWdodCA9IFRSVUUpICAKCiAgICAKICAgIGlmIChhbnkob2Rkc19yYXRpb3NfZ3JvdXBlZCRTaWduaWZpY2FudCA9PSBUUlVFLCBuYS5ybSA9IFRSVUUpKSB7CiAgICAgIHJlc3RydWN0dXJlZF90YWJsZV9odG1sIDwtIHJlc3RydWN0dXJlZF90YWJsZV9odG1sICU+JQogICAgICAgIHJvd19zcGVjKAogICAgICAgICAgd2hpY2gob2Rkc19yYXRpb3NfZ3JvdXBlZCRTaWduaWZpY2FudCA9PSBUUlVFKSwgCiAgICAgICAgICBiYWNrZ3JvdW5kID0gIiNmZmNjY2MiICAKICAgICAgICApCiAgICB9CiAgICAgIAogICAgcmVzdHJ1Y3R1cmVkX3RhYmxlX2h0bWwgPC0gcmVzdHJ1Y3R1cmVkX3RhYmxlX2h0bWwgJT4lCiAgICAgIHJvd19zcGVjKDE6bnJvdyhvZGRzX3JhdGlvc19mb3JfdGFibGUpLCBiYWNrZ3JvdW5kID0gcmVwKGMoIiNmOWY5ZjkiLCAiI2ZmZmZmZiIpLCBsZW5ndGgub3V0ID0gbnJvdyhvZGRzX3JhdGlvc19mb3JfdGFibGUpKSkKCiAgICAKICAgIHByaW50KHJlc3RydWN0dXJlZF90YWJsZV9odG1sKQogIH0gZWxzZSB7CiAgICBjYXQoIjxwPjxzdHJvbmc+V2FybmluZzo8L3N0cm9uZz4gTm8gZGF0YSBhdmFpbGFibGUgZm9yIHJlc3RydWN0dXJpbmcgYWZ0ZXIgZmlsdGVyaW5nLiBTa2lwcGluZyB0aGlzIHNlY3Rpb24uPC9wPjxicj4iKQogIH0KICAKfSBlbHNlIHsKICBjYXQoIjxwPjxzdHJvbmc+V2FybmluZzo8L3N0cm9uZz4gTm8gZGF0YSBhdmFpbGFibGUgZm9yIHJlc3RydWN0dXJpbmcuIFNraXBwaW5nIHRoaXMgc2VjdGlvbi48L3A+PGJyPiIpCn0KCmBgYAoKYGBge3J9CgppZiAobnJvdyhvZGRzX3JhdGlvc19kYXRhKSA+IDApIHsKICAKIAogIG9kZHNfcmF0aW9zX3Jlc3RydWN0dXJlZCA8LSBvZGRzX3JhdGlvc19kYXRhICU+JQogICAgZmlsdGVyKCFpcy5uYShPZGRzUmF0aW8pKSAlPiUgIAogICAgbXV0YXRlKAogICAgICBSZWZlcmVuY2UgPSBpZmVsc2UoTGV2ZWwgPT0gIk5vIiwgIlllcyIsICJObyIpLCAgCiAgICAgIFNpZ25pZmljYW50ID0gaWZlbHNlKCFpcy5uYShQVmFsdWUpICYgUFZhbHVlIDwgMC4wNSwgVFJVRSwgRkFMU0UpLCAgCiAgICAgIENJXzk1ID0gaWZlbHNlKCFpcy5uYShMb3dlcikgJiAhaXMubmEoVXBwZXIpLCBwYXN0ZTAoIigiLCByb3VuZChMb3dlciwgMiksICIsICIsIHJvdW5kKFVwcGVyLCAyKSwgIikiKSwgIi0iKSwgIAogICAgICBQVmFsdWUgPSBpZmVsc2UoaXMubmEoUFZhbHVlKSwgIi0iLCBhcy5jaGFyYWN0ZXIocm91bmQoUFZhbHVlLCA0KSkpLCAKICAgICAgT2Rkc1JhdGlvID0gaWZlbHNlKGlzLm5hKE9kZHNSYXRpbyksICItIiwgYXMuY2hhcmFjdGVyKHJvdW5kKE9kZHNSYXRpbywgNCkpKSwgIAogICAgICBOb25Jbmp1cnkgPSBpZmVsc2UoaXMubmEoTm9uSW5qdXJ5KSwgIi0iLCBhcy5jaGFyYWN0ZXIoTm9uSW5qdXJ5KSksICAKICAgICAgcDEgPSBpZmVsc2UoaXMubmEocDEpLCAiLSIsIHBhc3RlMChyb3VuZChhcy5udW1lcmljKHAxKSAqIDEwMCwgMiksICIlIikpICAKICAgICkgJT4lCiAgICBzZWxlY3QoVmFyaWFibGUsIExldmVsLCBSZWZlcmVuY2UsIE5vbkluanVyeSwgcDEsIE9kZHNSYXRpbywgQ0lfOTUsIFBWYWx1ZSwgU2lnbmlmaWNhbnQpCgogIAogIG9kZHNfcmF0aW9zX2NsZWFuIDwtIG9kZHNfcmF0aW9zX3Jlc3RydWN0dXJlZCAlPiUKICAgIGFycmFuZ2UoVmFyaWFibGUsIExldmVsKSAlPiUKICAgIHNlbGVjdChWYXJpYWJsZSwgTGV2ZWwsIFJlZmVyZW5jZSwgTm9uSW5qdXJ5LCBwMSwgT2Rkc1JhdGlvLCBDSV85NSwgUFZhbHVlKQoKCiAgaWYgKG5yb3cob2Rkc19yYXRpb3NfY2xlYW4pID4gMCkgewoKICAgIHJlc3RydWN0dXJlZF90YWJsZV9odG1sIDwtIG9kZHNfcmF0aW9zX2NsZWFuICU+JQogICAgICBrYWJsZSgiaHRtbCIsIGNhcHRpb24gPSAiUmVzdHJ1Y3R1cmVkIE9kZHMgUmF0aW8gQW5hbHlzaXMgZm9yIE1lZGljYWwgSW50ZXJwcmV0YXRpb24gKFNlcGFyYXRlZCBZZXMgYW5kIE5vIExldmVscykiLAogICAgICAgICAgICBjb2wubmFtZXMgPSBjKCJWYXJpYWJsZSIsICJMZXZlbCIsICJSZWZlcmVuY2UiLCAiTm9uLUluanVyeSBDb3VudCIsICJOb24tSW5qdXJ5ICglKSIsICJPZGRzIFJhdGlvIiwgIkNJICg5NSUpIiwgIlAtVmFsdWUiKSkgJT4lCiAgICAgIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIsICJyZXNwb25zaXZlIiksIGZ1bGxfd2lkdGggPSBGQUxTRSwgcG9zaXRpb24gPSAiY2VudGVyIikgJT4lCiAgICAgIHJvd19zcGVjKDAsIGJvbGQgPSBUUlVFLCBiYWNrZ3JvdW5kID0gIiMzMzMzMzMiLCBjb2xvciA9ICJ3aGl0ZSIpICU+JQogICAgICBjb2x1bW5fc3BlYygxOjgsIHdpZHRoID0gIjVlbSIsIGJvcmRlcl9sZWZ0ID0gVFJVRSwgYm9yZGVyX3JpZ2h0ID0gVFJVRSkgICMKICAgIHNpZ25pZmljYW50X3Jvd3MgPC0gd2hpY2gob2Rkc19yYXRpb3NfcmVzdHJ1Y3R1cmVkJFNpZ25pZmljYW50ID09IFRSVUUpCiAgICBpZiAobGVuZ3RoKHNpZ25pZmljYW50X3Jvd3MpID4gMCkgewogICAgICByZXN0cnVjdHVyZWRfdGFibGVfaHRtbCA8LSByZXN0cnVjdHVyZWRfdGFibGVfaHRtbCAlPiUKICAgICAgICByb3dfc3BlYyhzaWduaWZpY2FudF9yb3dzLCBiYWNrZ3JvdW5kID0gIiNmZmNjY2MiKSAKICAgIH0KCiAgCiAgICByZXN0cnVjdHVyZWRfdGFibGVfaHRtbCA8LSByZXN0cnVjdHVyZWRfdGFibGVfaHRtbCAlPiUKICAgICAgcm93X3NwZWMoMTpucm93KG9kZHNfcmF0aW9zX2NsZWFuKSwgYmFja2dyb3VuZCA9IHJlcChjKCIjZjlmOWY5IiwgIiNmZmZmZmYiKSwgbGVuZ3RoLm91dCA9IG5yb3cob2Rkc19yYXRpb3NfY2xlYW4pKSkKCiAgCiAgICBwcmludChyZXN0cnVjdHVyZWRfdGFibGVfaHRtbCkKICB9IGVsc2UgewogICAgY2F0KCI8cD48c3Ryb25nPldhcm5pbmc6PC9zdHJvbmc+IE5vIGRhdGEgYXZhaWxhYmxlIGZvciByZXN0cnVjdHVyaW5nIGFmdGVyIGZpbHRlcmluZy4gU2tpcHBpbmcgdGhpcyBzZWN0aW9uLjwvcD48YnI+IikKICB9CiAgCn0gZWxzZSB7CiAgY2F0KCI8cD48c3Ryb25nPldhcm5pbmc6PC9zdHJvbmc+IE5vIGRhdGEgYXZhaWxhYmxlIGZvciByZXN0cnVjdHVyaW5nLiBTa2lwcGluZyB0aGlzIHNlY3Rpb24uPC9wPjxicj4iKQp9CgpgYGAKCgoKCgojIyMjIyMgQ3ljbGlzdCBJbnRlcnNlY3Rpb24KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KCmN5Y2xpc3RfaW50ZXJzZWN0aW9uX2RhdGEgPC0gZGF0YSAlPiUKICBmaWx0ZXIobW9kZSA9PSAiQ3ljbGlzdCIsIGludGVyc2VjdGlvbiA9PSAiWWVzIikKCmlmIChucm93KGN5Y2xpc3RfaW50ZXJzZWN0aW9uX2RhdGEpID4gMCkgewogIGN5Y2xpc3RfaW50ZXJzZWN0aW9uX3ZhcnMgPC0gYygic2lnbmFsaXplZCIsICJzdG9wc2lnbnMiLCAicm91bmRhYm91dCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGhyZWVsZWdzIiwgImZvdXJsZWdzIiwgImZvdXJtbGVncyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGVkaWNhdGVkc2lnbmFsZm9yY3ljbGlzdHMiLCAiYmlrZWJveGVzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0d29zdGFnZXR1cm5ib3giLCAicHJvdGVjdGVkb3JkZWRpY2F0ZWRpbnRlcnNlY3Rpb24iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1lZGlhbmlzbGFuZGRpdmVydGVyIiwgImNvbWJpbmVkYmlrZWxhbmV0dXJubGFuZSIsICJ0aHJvdWdoYmlrZWxhbmUiKQoKICBvZGRzX3JhdGlvc19saXN0IDwtIGxpc3QoKQogIHN0YW5kYXJkX2NvbHVtbnMgPC0gYygiVmFyaWFibGUiLCAiTGV2ZWwiLCAiSW5qdXJ5IiwgInAwIiwgIk5vbi1Jbmp1cnkiLCAicDEiLCAiT2Rkc1JhdGlvIiwgIkxvd2VyIiwgIlVwcGVyIiwgIlBWYWx1ZSIpCgogIGZvciAodmFyIGluIGN5Y2xpc3RfaW50ZXJzZWN0aW9uX3ZhcnMpIHsKICAgIGlmICh2YXIgJWluJSBuYW1lcyhjeWNsaXN0X2ludGVyc2VjdGlvbl9kYXRhKSkgewogICAgICBvZGRzX3JhdGlvX3Jlc3VsdCA8LSB0cnlDYXRjaCh7CiAgICAgICAgaWYgKG5fZGlzdGluY3QoY3ljbGlzdF9pbnRlcnNlY3Rpb25fZGF0YVtbdmFyXV0pID09IDIpIHsKICAgICAgICAgIG9kZHNfZGF0YSA8LSBjeWNsaXN0X2ludGVyc2VjdGlvbl9kYXRhICU+JQogICAgICAgICAgICBzZWxlY3QoYWxsX29mKHZhciksIGNyYXNoc2V2ZXJpdHkpICU+JQogICAgICAgICAgICB0YWJsZSgpICU+JQogICAgICAgICAgICBhcy5tYXRyaXgoKQogICAgICAgICAgCiAgICAgICAgICBvZGRzX3JhdGlvX3RhYmxlIDwtIGFzLmRhdGEuZnJhbWUoZXBpdGFiKG9kZHNfZGF0YSwgbWV0aG9kID0gIm9kZHNyYXRpbyIpJHRhYikgJT4lCiAgICAgICAgICAgIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIHJvdW5kLCA0KSkKICAgICAgICAgIAogICAgICAgICAgb2Rkc19yYXRpb190YWJsZSA8LSBjYmluZChWYXJpYWJsZSA9IHZhciwgTGV2ZWwgPSByb3duYW1lcyhvZGRzX3JhdGlvX3RhYmxlKSwgb2Rkc19yYXRpb190YWJsZSkKICAgICAgICAgIG5hbWVzKG9kZHNfcmF0aW9fdGFibGUpIDwtIHN0YW5kYXJkX2NvbHVtbnMKICAgICAgICAgIG9kZHNfcmF0aW9fdGFibGUKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZGF0YS5mcmFtZSgKICAgICAgICAgICAgVmFyaWFibGUgPSB2YXIsIExldmVsID0gTkEsIEluanVyeSA9ICJOb3QgYXBwbGljYWJsZSIsIAogICAgICAgICAgICBwMCA9IE5BLCBOb25Jbmp1cnkgPSBOQSwgcDEgPSBOQSwgT2Rkc1JhdGlvID0gTkEsIAogICAgICAgICAgICBMb3dlciA9IE5BLCBVcHBlciA9IE5BLCBQVmFsdWUgPSBOQSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFCiAgICAgICAgICApCiAgICAgICAgfQogICAgICB9LCBlcnJvciA9IGZ1bmN0aW9uKGUpIHsKICAgICAgICBkYXRhLmZyYW1lKAogICAgICAgICAgVmFyaWFibGUgPSB2YXIsIExldmVsID0gTkEsIEluanVyeSA9ICJOb3QgYXBwbGljYWJsZSIsIAogICAgICAgICAgcDAgPSBOQSwgTm9uSW5qdXJ5ID0gTkEsIHAxID0gTkEsIE9kZHNSYXRpbyA9IE5BLCAKICAgICAgICAgIExvd2VyID0gTkEsIFVwcGVyID0gTkEsIFBWYWx1ZSA9IE5BLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UKICAgICAgICApCiAgICAgIH0pCiAgICAgIAogICAgICBvZGRzX3JhdGlvc19saXN0W1t2YXJdXSA8LSBvZGRzX3JhdGlvX3Jlc3VsdAogICAgfQogIH0KICAKICBvZGRzX3JhdGlvc19kYXRhIDwtIGRvLmNhbGwocmJpbmQsIG9kZHNfcmF0aW9zX2xpc3QpCiAgcm93X2NvbG9ycyA8LSByZXAoYygiI2Y5ZjlmOSIsICIjZmZmZmZmIiksIGxlbmd0aC5vdXQgPSBucm93KG9kZHNfcmF0aW9zX2RhdGEpKQogIG9kZHNfcmF0aW9zX2RhdGEkVmFyaWFibGUgPC0gaWZlbHNlKGR1cGxpY2F0ZWQob2Rkc19yYXRpb3NfZGF0YSRWYXJpYWJsZSksICIiLCBvZGRzX3JhdGlvc19kYXRhJFZhcmlhYmxlKQoKICBmaW5hbF90YWJsZV9odG1sIDwtIGh0bWxUYWJsZSgKICAgIG9kZHNfcmF0aW9zX2RhdGEsCiAgICBoZWFkZXIgPSBjKCJWYXJpYWJsZSIsICJMZXZlbCIsICJJbmp1cnkiLCAicDAiLCAiTm9uLUluanVyeSIsICJwMSIsICJPZGRzUmF0aW8iLCAiTG93ZXIiLCAiVXBwZXIiLCAiUC1WYWx1ZSIpLAogICAgYWxpZ24gPSAnbGNjY2NjY2NjYycsCiAgICBybmFtZXMgPSBGQUxTRSwKICAgIGNzcy5jZWxsID0gInRleHQtYWxpZ246IGNlbnRlcjsgcGFkZGluZzogMTJweCAxNXB4OyBmb250LXNpemU6IDEycHg7IHdoaXRlLXNwYWNlOiBub3dyYXA7IiwKICAgIGNzcy5yb3cgPSBzcHJpbnRmKCJiYWNrZ3JvdW5kLWNvbG9yOiAlczsiLCByb3dfY29sb3JzKSwKICAgIGhlYWRlci5jc3MgPSAiYmFja2dyb3VuZC1jb2xvcjogIzAwMzM2NjsgZm9udC1zaXplOiAxNHB4OyB0ZXh0LWFsaWduOiBjZW50ZXI7IGNvbG9yOiB3aGl0ZTsiLAogICAgY2FwdGlvbiA9ICI8aDMgc3R5bGU9J3RleHQtYWxpZ246IGNlbnRlcjsnPkFuYWx5c2lzIGZvciBDeWNsaXN0IEludGVyc2VjdGlvbjwvaDM+CiAgICAgICAgICAgICAgIDxwIHN0eWxlPSd0ZXh0LWFsaWduOiBjZW50ZXI7Jz48ZW0+VGhpcyBhbmFseXNpcyBmb2N1c2VzIG9uIG1vZGU6IGN5Y2xpc3QgfCBpbnRlcnNlY3Rpb246IHllczwvZW0+PC9wPiIKICApCgogIHByaW50KEhUTUwoZmluYWxfdGFibGVfaHRtbCkpCn0gZWxzZSB7CiAgY2F0KCI8cD48c3Ryb25nPldhcm5pbmc6PC9zdHJvbmc+IE5vIGRhdGEgYXZhaWxhYmxlIGZvciBDeWNsaXN0IEludGVyc2VjdGlvbi4gU2tpcHBpbmcgYW5hbHlzaXMgZm9yIHRoaXMgZ3JvdXAuPC9wPjxicj4iKQp9CmBgYAoKIyMjIyMjIHBlZGVzdHJpYW5fbWlkYmxvY2tfZGF0YQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpwZWRlc3RyaWFuX21pZGJsb2NrX2RhdGEgPC0gZGF0YSAlPiUKICBmaWx0ZXIobW9kZSA9PSAiUGVkZXN0cmlhbiIsIGludGVyc2VjdGlvbiA9PSAiTm8iKQoKaWYgKG5yb3cocGVkZXN0cmlhbl9taWRibG9ja19kYXRhKSA+IDApIHsKICBwZWRlc3RyaWFuX21pZGJsb2NrX3ZhcnMgPC0gYygib25lbGFuZSIsICJ0d29sYW5lcyIsICJ0aHJlZWxhbmVzIiwgImZvdXJsYW5lcyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmaXZlbGFuZXMiLCAic2l4bGFuZXMiLCAib25ld2F5IiwgInR3b3dheXMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY2xlYXJ6b25lIiwgIm9uc3RyZWV0cGFya2luZyIsICJhY2Nlc3NpYmxlc2hvdWxkZXIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2lkZXdhbGtzIiwgInNwZWVkaHVtcCIsICJzdGFuZGFyZHBhaW50IiwgInNvbGlkcGFpbnQiLCAic3RyaXBlZCIpCgogIG9kZHNfcmF0aW9zX2xpc3QgPC0gbGlzdCgpCiAgc3RhbmRhcmRfY29sdW1ucyA8LSBjKCJWYXJpYWJsZSIsICJMZXZlbCIsICJJbmp1cnkiLCAicDAiLCAiTm9uLUluanVyeSIsICJwMSIsICJPZGRzUmF0aW8iLCAiTG93ZXIiLCAiVXBwZXIiLCAiUFZhbHVlIikKCiAgZm9yICh2YXIgaW4gcGVkZXN0cmlhbl9taWRibG9ja192YXJzKSB7CiAgICBpZiAodmFyICVpbiUgbmFtZXMocGVkZXN0cmlhbl9taWRibG9ja19kYXRhKSkgewogICAgICBvZGRzX3JhdGlvX3Jlc3VsdCA8LSB0cnlDYXRjaCh7CiAgICAgICAgaWYgKG5fZGlzdGluY3QocGVkZXN0cmlhbl9taWRibG9ja19kYXRhW1t2YXJdXSkgPT0gMikgewogICAgICAgICAgb2Rkc19kYXRhIDwtIHBlZGVzdHJpYW5fbWlkYmxvY2tfZGF0YSAlPiUKICAgICAgICAgICAgc2VsZWN0KGFsbF9vZih2YXIpLCBjcmFzaHNldmVyaXR5KSAlPiUKICAgICAgICAgICAgdGFibGUoKSAlPiUKICAgICAgICAgICAgYXMubWF0cml4KCkKICAgICAgICAgIAogICAgICAgICAgb2Rkc19yYXRpb190YWJsZSA8LSBhcy5kYXRhLmZyYW1lKGVwaXRhYihvZGRzX2RhdGEsIG1ldGhvZCA9ICJvZGRzcmF0aW8iKSR0YWIpICU+JQogICAgICAgICAgICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCByb3VuZCwgNCkpCiAgICAgICAgICAKICAgICAgICAgIG9kZHNfcmF0aW9fdGFibGUgPC0gY2JpbmQoVmFyaWFibGUgPSB2YXIsIExldmVsID0gcm93bmFtZXMob2Rkc19yYXRpb190YWJsZSksIG9kZHNfcmF0aW9fdGFibGUpCiAgICAgICAgICBuYW1lcyhvZGRzX3JhdGlvX3RhYmxlKSA8LSBzdGFuZGFyZF9jb2x1bW5zCiAgICAgICAgICBvZGRzX3JhdGlvX3RhYmxlCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGRhdGEuZnJhbWUoCiAgICAgICAgICAgIFZhcmlhYmxlID0gdmFyLCBMZXZlbCA9IE5BLCBJbmp1cnkgPSAiTm90IGFwcGxpY2FibGUiLCAKICAgICAgICAgICAgcDAgPSBOQSwgTm9uSW5qdXJ5ID0gTkEsIHAxID0gTkEsIE9kZHNSYXRpbyA9IE5BLCAKICAgICAgICAgICAgTG93ZXIgPSBOQSwgVXBwZXIgPSBOQSwgUFZhbHVlID0gTkEsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRQogICAgICAgICAgKQogICAgICAgIH0KICAgICAgfSwgZXJyb3IgPSBmdW5jdGlvbihlKSB7CiAgICAgICAgZGF0YS5mcmFtZSgKICAgICAgICAgIFZhcmlhYmxlID0gdmFyLCBMZXZlbCA9IE5BLCBJbmp1cnkgPSAiTm90IGFwcGxpY2FibGUiLCAKICAgICAgICAgIHAwID0gTkEsIE5vbkluanVyeSA9IE5BLCBwMSA9IE5BLCBPZGRzUmF0aW8gPSBOQSwgCiAgICAgICAgICBMb3dlciA9IE5BLCBVcHBlciA9IE5BLCBQVmFsdWUgPSBOQSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFCiAgICAgICAgKQogICAgICB9KQogICAgICAKICAgICAgb2Rkc19yYXRpb3NfbGlzdFtbdmFyXV0gPC0gb2Rkc19yYXRpb19yZXN1bHQKICAgIH0KICB9CiAgCiAgb2Rkc19yYXRpb3NfZGF0YSA8LSBkby5jYWxsKHJiaW5kLCBvZGRzX3JhdGlvc19saXN0KQogIHJvd19jb2xvcnMgPC0gcmVwKGMoIiNmOWY5ZjkiLCAiI2ZmZmZmZiIpLCBsZW5ndGgub3V0ID0gbnJvdyhvZGRzX3JhdGlvc19kYXRhKSkKICBvZGRzX3JhdGlvc19kYXRhJFZhcmlhYmxlIDwtIGlmZWxzZShkdXBsaWNhdGVkKG9kZHNfcmF0aW9zX2RhdGEkVmFyaWFibGUpLCAiIiwgb2Rkc19yYXRpb3NfZGF0YSRWYXJpYWJsZSkKCiAgZmluYWxfdGFibGVfaHRtbCA8LSBodG1sVGFibGUoCiAgICBvZGRzX3JhdGlvc19kYXRhLAogICAgaGVhZGVyID0gYygiVmFyaWFibGUiLCAiTGV2ZWwiLCAiSW5qdXJ5IiwgInAwIiwgIk5vbi1Jbmp1cnkiLCAicDEiLCAiT2Rkc1JhdGlvIiwgIkxvd2VyIiwgIlVwcGVyIiwgIlAtVmFsdWUiKSwKICAgIGFsaWduID0gJ2xjY2NjY2NjY2MnLAogICAgcm5hbWVzID0gRkFMU0UsCiAgICBjc3MuY2VsbCA9ICJ0ZXh0LWFsaWduOiBjZW50ZXI7IHBhZGRpbmc6IDEycHggMTVweDsgZm9udC1zaXplOiAxMnB4OyB3aGl0ZS1zcGFjZTogbm93cmFwOyIsCiAgICBjc3Mucm93ID0gc3ByaW50ZigiYmFja2dyb3VuZC1jb2xvcjogJXM7Iiwgcm93X2NvbG9ycyksCiAgICBoZWFkZXIuY3NzID0gImJhY2tncm91bmQtY29sb3I6ICMwMDMzNjY7IGZvbnQtc2l6ZTogMTRweDsgdGV4dC1hbGlnbjogY2VudGVyOyBjb2xvcjogd2hpdGU7IiwKICAgIGNhcHRpb24gPSAiPGgzIHN0eWxlPSd0ZXh0LWFsaWduOiBjZW50ZXI7Jz5BbmFseXNpcyBmb3IgUGVkZXN0cmlhbiBNaWRCbG9jazwvaDM+CiAgICAgICAgICAgICAgIDxwIHN0eWxlPSd0ZXh0LWFsaWduOiBjZW50ZXI7Jz48ZW0+VGhpcyBhbmFseXNpcyBmb2N1c2VzIG9uIG1vZGU6IHBlZGVzdHJpYW4gfCBpbnRlcnNlY3Rpb246IG5vPC9lbT48L3A+IgogICkKCiAgcHJpbnQoSFRNTChmaW5hbF90YWJsZV9odG1sKSkKfSBlbHNlIHsKICBjYXQoIjxwPjxzdHJvbmc+V2FybmluZzo8L3N0cm9uZz4gTm8gZGF0YSBhdmFpbGFibGUgZm9yIFBlZGVzdHJpYW4gTWlkQmxvY2suIFNraXBwaW5nIGFuYWx5c2lzIGZvciB0aGlzIGdyb3VwLjwvcD48YnI+IikKfQpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIyMjIFBlZGVzdHJpYW4gSW50ZXJzZWN0aW9uCgpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQoKcGVkZXN0cmlhbl9pbnRlcnNlY3Rpb25fZGF0YSA8LSBkYXRhICU+JQogIGZpbHRlcihtb2RlID09ICJQZWRlc3RyaWFuIiwgaW50ZXJzZWN0aW9uID09ICJZZXMiKQoKaWYgKG5yb3cocGVkZXN0cmlhbl9pbnRlcnNlY3Rpb25fZGF0YSkgPiAwKSB7CiAgcGVkZXN0cmlhbl9pbnRlcnNlY3Rpb25fdmFycyA8LSBjKCJzaWduYWxpemVkIiwgInN0b3BzaWducyIsICJyb3VuZGFib3V0IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0aHJlZWxlZ3MiLCAiZm91cmxlZ3MiLCAiZm91cm1sZWdzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1bnNpZ25hbGl6ZWRjcm9zc3dhbGsiLCAic2lnbmFsaXplZGNyb3Nzd2Fsa3N0cmVldCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic3RhbmRhcmRwYWludCIsICJzb2xpZHBhaW50IiwgInN0cmlwZWQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInBlZGVzdHJpYW5yZWZ1Z2VzdHJpcGVkIiwgInJhcGlkcmVjdGFuZ3VsYXJmbGFzaGluZ2JlYWNvbiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicGVkZXN0cmlhbmNyb3NzZWRzaWduYWwiKQoKICBvZGRzX3JhdGlvc19saXN0IDwtIGxpc3QoKQogIHN0YW5kYXJkX2NvbHVtbnMgPC0gYygiVmFyaWFibGUiLCAiTGV2ZWwiLCAiSW5qdXJ5IiwgInAwIiwgIk5vbi1Jbmp1cnkiLCAicDEiLCAiT2Rkc1JhdGlvIiwgIkxvd2VyIiwgIlVwcGVyIiwgIlBWYWx1ZSIpCgogIGZvciAodmFyIGluIHBlZGVzdHJpYW5faW50ZXJzZWN0aW9uX3ZhcnMpIHsKICAgIGlmICh2YXIgJWluJSBuYW1lcyhwZWRlc3RyaWFuX2ludGVyc2VjdGlvbl9kYXRhKSkgewogICAgICBvZGRzX3JhdGlvX3Jlc3VsdCA8LSB0cnlDYXRjaCh7CiAgICAgICAgaWYgKG5fZGlzdGluY3QocGVkZXN0cmlhbl9pbnRlcnNlY3Rpb25fZGF0YVtbdmFyXV0pID09IDIpIHsKICAgICAgICAgIG9kZHNfZGF0YSA8LSBwZWRlc3RyaWFuX2ludGVyc2VjdGlvbl9kYXRhICU+JQogICAgICAgICAgICBzZWxlY3QoYWxsX29mKHZhciksIGNyYXNoc2V2ZXJpdHkpICU+JQogICAgICAgICAgICB0YWJsZSgpICU+JQogICAgICAgICAgICBhcy5tYXRyaXgoKQogICAgICAgICAgCiAgICAgICAgICBvZGRzX3JhdGlvX3RhYmxlIDwtIGFzLmRhdGEuZnJhbWUoZXBpdGFiKG9kZHNfZGF0YSwgbWV0aG9kID0gIm9kZHNyYXRpbyIpJHRhYikgJT4lCiAgICAgICAgICAgIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIHJvdW5kLCA0KSkKICAgICAgICAgIAogICAgICAgICAgb2Rkc19yYXRpb190YWJsZSA8LSBjYmluZChWYXJpYWJsZSA9IHZhciwgTGV2ZWwgPSByb3duYW1lcyhvZGRzX3JhdGlvX3RhYmxlKSwgb2Rkc19yYXRpb190YWJsZSkKICAgICAgICAgIG5hbWVzKG9kZHNfcmF0aW9fdGFibGUpIDwtIHN0YW5kYXJkX2NvbHVtbnMKICAgICAgICAgIG9kZHNfcmF0aW9fdGFibGUKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZGF0YS5mcmFtZSgKICAgICAgICAgICAgVmFyaWFibGUgPSB2YXIsIExldmVsID0gTkEsIEluanVyeSA9ICJOb3QgYXBwbGljYWJsZSIsIAogICAgICAgICAgICBwMCA9IE5BLCBOb25Jbmp1cnkgPSBOQSwgcDEgPSBOQSwgT2Rkc1JhdGlvID0gTkEsIAogICAgICAgICAgICBMb3dlciA9IE5BLCBVcHBlciA9IE5BLCBQVmFsdWUgPSBOQSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFCiAgICAgICAgICApCiAgICAgICAgfQogICAgICB9LCBlcnJvciA9IGZ1bmN0aW9uKGUpIHsKICAgICAgICBkYXRhLmZyYW1lKAogICAgICAgICAgVmFyaWFibGUgPSB2YXIsIExldmVsID0gTkEsIEluanVyeSA9ICJOb3QgYXBwbGljYWJsZSIsIAogICAgICAgICAgcDAgPSBOQSwgTm9uSW5qdXJ5ID0gTkEsIHAxID0gTkEsIE9kZHNSYXRpbyA9IE5BLCAKICAgICAgICAgIExvd2VyID0gTkEsIFVwcGVyID0gTkEsIFBWYWx1ZSA9IE5BLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UKICAgICAgICApCiAgICAgIH0pCiAgICAgIAogICAgICBvZGRzX3JhdGlvc19saXN0W1t2YXJdXSA8LSBvZGRzX3JhdGlvX3Jlc3VsdAogICAgfQogIH0KICAKICBvZGRzX3JhdGlvc19kYXRhIDwtIGRvLmNhbGwocmJpbmQsIG9kZHNfcmF0aW9zX2xpc3QpCiAgcm93X2NvbG9ycyA8LSByZXAoYygiI2Y5ZjlmOSIsICIjZmZmZmZmIiksIGxlbmd0aC5vdXQgPSBucm93KG9kZHNfcmF0aW9zX2RhdGEpKQogIG9kZHNfcmF0aW9zX2RhdGEkVmFyaWFibGUgPC0gaWZlbHNlKGR1cGxpY2F0ZWQob2Rkc19yYXRpb3NfZGF0YSRWYXJpYWJsZSksICIiLCBvZGRzX3JhdGlvc19kYXRhJFZhcmlhYmxlKQoKICBmaW5hbF90YWJsZV9odG1sIDwtIGh0bWxUYWJsZSgKICAgIG9kZHNfcmF0aW9zX2RhdGEsCiAgICBoZWFkZXIgPSBjKCJWYXJpYWJsZSIsICJMZXZlbCIsICJJbmp1cnkiLCAicDAiLCAiTm9uLUluanVyeSIsICJwMSIsICJPZGRzUmF0aW8iLCAiTG93ZXIiLCAiVXBwZXIiLCAiUC1WYWx1ZSIpLAogICAgYWxpZ24gPSAnbGNjY2NjY2NjYycsCiAgICBybmFtZXMgPSBGQUxTRSwKICAgIGNzcy5jZWxsID0gInRleHQtYWxpZ246IGNlbnRlcjsgcGFkZGluZzogMTJweCAxNXB4OyBmb250LXNpemU6IDEycHg7IHdoaXRlLXNwYWNlOiBub3dyYXA7IiwKICAgIGNzcy5yb3cgPSBzcHJpbnRmKCJiYWNrZ3JvdW5kLWNvbG9yOiAlczsiLCByb3dfY29sb3JzKSwKICAgIGhlYWRlci5jc3MgPSAiYmFja2dyb3VuZC1jb2xvcjogIzAwMzM2NjsgZm9udC1zaXplOiAxNHB4OyB0ZXh0LWFsaWduOiBjZW50ZXI7IGNvbG9yOiB3aGl0ZTsiLAogICAgY2FwdGlvbiA9ICI8aDMgc3R5bGU9J3RleHQtYWxpZ246IGNlbnRlcjsnPkFuYWx5c2lzIGZvciBQZWRlc3RyaWFuIEludGVyc2VjdGlvbjwvaDM+CiAgICAgICAgICAgICAgIDxwIHN0eWxlPSd0ZXh0LWFsaWduOiBjZW50ZXI7Jz48ZW0+VGhpcyBhbmFseXNpcyBmb2N1c2VzIG9uIG1vZGU6IHBlZGVzdHJpYW4gfCBpbnRlcnNlY3Rpb246IHllczwvZW0+PC9wPiIKICApCgogIHByaW50KEhUTUwoZmluYWxfdGFibGVfaHRtbCkpCn0gZWxzZSB7IiIKfQpgYGAKClwKXApbXjFdCgpbXjFdOiBXaGVuIHVzaW5nIHRoZSBlcGl0YWIgZnVuY3Rpb24gZnJvbSB0aGUgZXBpdG9vbHMgcGFja2FnZSBpbiBSIHRvIGNhbGN1bGF0ZSBvZGRzIHJhdGlvcyAoT1IpLCBpdCBnZW5lcmF0ZXMgc2V2ZXJhbCBpbXBvcnRhbnQgc3RhdGlzdGljcyBhbmQgbWVhc3VyZXMgdGhhdCBoZWxwIGludGVycHJldCB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gYW4gZXhwb3N1cmUgKGUuZy4sIGEgcGFydGljdWxhciByb2FkIGZlYXR1cmUpIGFuZCBhbiBvdXRjb21lIChlLmcuLCBpbmp1cnkpLgoKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwp8IDEuICBPZGRzUmF0aW86ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAtICAgVGhpcyB2YWx1ZSBtZWFzdXJlcyB0aGUgb2RkcyBvZiB0aGUgZXZlbnQgKGUuZy4sIGluanVyeSkgb2NjdXJyaW5nIGluIHRoZSBleHBvc2VkIGdyb3VwIGNvbXBhcmVkIHRvIHRoZSB1bmV4cG9zZWQgZ3JvdXAuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAtICAgQW4gT1Igb2YgMSBpbmRpY2F0ZXMgbm8gZGlmZmVyZW5jZSBpbiBvZGRzIGJldHdlZW4gdGhlIGdyb3Vwcy4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgIC0gICBBbiBPUiBncmVhdGVyIHRoYW4gMSBzdWdnZXN0cyB0aGF0IGV4cG9zdXJlIGlzIGFzc29jaWF0ZWQgd2l0aCBoaWdoZXIgb2RkcyBvZiB0aGUgZXZlbnQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAp8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgLSAgIEFuIE9SIGxlc3MgdGhhbiAxIGluZGljYXRlcyB0aGF0IHRoZSBleHBvc3VyZSBtYXkgYmUgcHJvdGVjdGl2ZSBvciByZWR1Y2UgdGhlIG9kZHMgb2YgdGhlIGV2ZW50LiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCAyLiAgTG93ZXIgYW5kIFVwcGVyIChDb25maWRlbmNlIEludGVydmFsKTogICAgICAgICAgICAgICAgICAgICAgICAgIHwgLSAgIFRoZXNlIHZhbHVlcyByZXByZXNlbnQgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgKHR5cGljYWxseSA5NSUpIGFyb3VuZCB0aGUgb2RkcyByYXRpby4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAp8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgLSAgIEEgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgbWVhbnMgd2UgYXJlIDk1JSBjb25maWRlbnQgdGhhdCB0aGUgdHJ1ZSBPUiBsaWVzIHdpdGhpbiB0aGlzIHJhbmdlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAtICAgSWYgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaW5jbHVkZXMgdGhlIHZhbHVlIDEsIHRoZSBPUiBpcyBub3Qgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCAoaS5lLiwgdGhlcmUgaXMgbm90IGVub3VnaCBldmlkZW5jZSB0byBzdGF0ZSB0aGVyZeKAmXMgYSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGdyb3VwcykuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAp8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgLSAgIFRoZSBMb3dlciBsaW1pdCBpcyB0aGUgbG93ZXIgYm91bmQgb2YgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwsIGFuZCB0aGUgVXBwZXIgbGltaXQgaXMgdGhlIHVwcGVyIGJvdW5kLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCAzLiAgUC1WYWx1ZTogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgLSAgIFRoaXMgdmFsdWUgaW5kaWNhdGVzIHRoZSBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2Ugb2YgdGhlIGFzc29jaWF0aW9uIGJldHdlZW4gZXhwb3N1cmUgYW5kIHRoZSBvdXRjb21lLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAp8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgLSAgIEEgbG93IHAtdmFsdWUgKHVzdWFsbHkgbGVzcyB0aGFuIDAuMDUpIHN1Z2dlc3RzIHRoYXQgdGhlcmUgaXMgc3VmZmljaWVudCBldmlkZW5jZSB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcywgaW5kaWNhdGluZyBhIHNpZ25pZmljYW50IGFzc29jaWF0aW9uIGJldHdlZW4gZXhwb3N1cmUgYW5kIHRoZSBvdXRjb21lLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAtICAgQSBoaWdoIHAtdmFsdWUgaW1wbGllcyB0aGF0IHRoZSBhc3NvY2lhdGlvbiBpcyBub3Qgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwp8IDQuICBJbmp1cnkgKENhc2VzIHdpdGggZXZlbnQpIGFuZCBOb24tSW5qdXJ5IChDYXNlcyB3aXRob3V0IGV2ZW50KTogfCAtICAgVGhlc2UgYXJlIHRoZSBjb3VudHMgb2YgY2FzZXMgaW4gZWFjaCBjYXRlZ29yeSAoZXhwb3NlZCBhbmQgdW5leHBvc2VkKSB0aGF0IGhhdmUgb3IgZG8gbm90IGhhdmUgdGhlIGV2ZW50IG9mIGludGVyZXN0IChpbmp1cnkpLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAtICAgVGhlc2UgdmFsdWVzIHNob3cgdGhlIHRvdGFsIG51bWJlciBvZiBvYnNlcnZhdGlvbnMgaW4gZWFjaCBncm91cCwgYXJlIGhlbHBmdWwgaW4gYXNzZXNzaW5nIHRoZSBzdGFiaWxpdHkgb2YgdGhlIHJlc3VsdHMgc2luY2UgdmVyeSBsb3cgY291bnRzIGNhbiBpbmRpY2F0ZSBhbiBpbnN1ZmZpY2llbnQgc2FtcGxlIHNpemUgdG8gZXN0aW1hdGUgdGhlIE9SIGFjY3VyYXRlbHkuIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwp8IDUuICBwMCBhbmQgcDE6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAtICAgVGhlc2UgcmVwcmVzZW50IHRoZSBwcm9wb3J0aW9ucyBvZiBjYXNlcyB3aXRoIHRoZSBldmVudCAoaW5qdXJ5KSBhbmQgd2l0aG91dCB0aGUgZXZlbnQgd2l0aGluIGVhY2ggZ3JvdXAuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAtICAgcDAgaXMgdGhlIHByb3BvcnRpb24gb2YgY2FzZXMgaW4gdGhlIHVuZXhwb3NlZCBncm91cCB0aGF0IGhhdmUgdGhlIGV2ZW50IG9mIGludGVyZXN0LiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgIC0gICAgcDEgaXMgdGhlIHByb3BvcnRpb24gb2YgY2FzZXMgaW4gdGhlIGV4cG9zZWQgZ3JvdXAgdGhhdCBoYXZlIHRoZSBldmVudCBvZiBpbnRlcmVzdC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAp8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgLSAgICBUaGVzZSBwcm9wb3J0aW9ucyBhbGxvdyBmb3IgYSBxdWljayB2aXN1YWxpemF0aW9uIG9mIHRoZSBkaWZmZXJlbmNlIGluIGV2ZW50IHJhdGVzIGJldHdlZW4gdGhlIGdyb3Vwcy4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKCjogT2RkcyByYXRpbyBJbnRlcnByZXRhdGlvbgoKKkV4YW1wbGUgSW50ZXJwcmV0YXRpb246KgoKKklmIHlvdSBvYnRhaW4gYW4gT1Igb2YgMS41IHdpdGggYSBjb25maWRlbmNlIGludGVydmFsIG9mIDEuMiB0byAxLjggYW5kIGEgcC12YWx1ZSBvZiAwLjAxLCB5b3UgY291bGQgaW50ZXJwcmV0IHRoaXMgYXM6IFwqIFRoZXJlIGlzIGEgc2lnbmlmaWNhbnQgYXNzb2NpYXRpb24gKHAtdmFsdWUgXDwgMC4wNSkgYmV0d2VlbiB0aGUgZXhwb3N1cmUgYW5kIHRoZSBldmVudC4gXCogVGhlIGV4cG9zZWQgZ3JvdXAgaGFzIGEgNTAlIGhpZ2hlciBjaGFuY2Ugb2YgZXhwZXJpZW5jaW5nIHRoZSBldmVudCAoaW5qdXJ5KSBjb21wYXJlZCB0byB0aGUgdW5leHBvc2VkIGdyb3VwLiBcKiBTaW5jZSB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCBkb2VzIG5vdCBpbmNsdWRlIDEsIHRoaXMgcmVsYXRpb25zaGlwIGlzIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQuKgoKKk9uIHRoZSBvdGhlciBoYW5kLCBpZiB0aGUgT1IgaXMgY2xvc2UgdG8gMSwgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaW5jbHVkZXMgMSAoZS5nLiwgT1IgPSAxLjEsIENJID0gMC45IHRvIDEuMyksIGFuZCB0aGUgcC12YWx1ZSBpcyBoaWdoIChcPiAwLjA1KSwgdGhlbiB0aGVyZSBpcyBub3QgZW5vdWdoIGV2aWRlbmNlIHRvIGNvbmNsdWRlIHRoYXQgdGhlcmUgaXMgYW4gYXNzb2NpYXRpb24gYmV0d2VlbiB0aGUgZXhwb3N1cmUgYW5kIHRoZSBvdXRjb21lLipcCg==