Packages Needed

library(tidyverse)
library(readxl)

Import the Data

I saved the Excel file to a folder in my project called data. I removed the second row of the Excel file, since it contained no useful information, and I renamed the file to vets.xlsx.

Apparently we are interested in the first sheet. The R-function read_xlsx() reads in the first sheet by default.

We only want to read in the first six columns of that first sheet, ignoring all of the analysis stuck into subsequent columns, so we use the range parameter of the function, as follows:

vets <- read_xlsx(
  "data/vets.xlsx",
  range = "A1:F912"
)

Some Bar Graphs (One Variable)

Here is a quick bar graph of the ranks of the subjects:

ggplot(vets, aes(x = Rank)) +
  geom_bar(color = "black", fill = "skyblue")

The ranks, without the NA-values:

vets %>% 
  drop_na(Rank) %>% 
  ggplot(aes(x = Rank)) +
  geom_bar(color = "black", fill = "skyblue")

Suppose you want the Warrant officers to come in between the enlisted and commissioned officers. In that case, you need to order your ranks. First, find out what your ranks are:

vets %>% 
  pull(Rank) %>% 
  unique() %>% 
  sort()
##  [1] "E1" "E2" "E3" "E4" "E5" "E6" "E7" "E8" "E9" "O2" "O3" "O4" "W2" "W3" "W4"
## [16] "W5"

One approach to re-ordering is to make Rank into a factor variable, with the "levels of the factor in the order you want, like this:

vets2 <-
  vets %>% 
  mutate(
    ordered_rank = factor(
      Rank,
      levels = c(
        "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9",
        "W3", "W4", "W5",
        "O2", "O3", "O4"
      )
    )
  )

Now try the bar graph:

vets2 %>% 
  drop_na(Rank) %>% 
  ggplot(aes(x = ordered_rank)) +
  geom_bar(color = "black", fill = "skyblue") +
  labs(x = "Rank")

Note that when give a factor, ggplot2 takes account of the ordering on the levels.

Grouping, and Some Tables

You are interested in comparing officers with non-officers, and it seems you are willing to lump the officers into one group. For this, create a new variable:

vets2 <-
  vets2 %>% 
  mutate(rank_status = recode(
    Rank,
    E1 = "enlisted",
    E2 = "enlisted",
    E3 = "enlisted",
    E4 = "enlisted",
    E5 = "enlisted",
    E6 = "enlisted",
    E7 = "enlisted",
    E8 = "enlisted",
    E9 = "enlisted",
    O2 = "officer",
    O3 = "officer",
    O4 = "officer",
    W2 = "officer",
    W3 = "officer",
    W4 = "officer",
    W5 = "officer"
  )
)

Note: That’s kinda cumbersome. As you gain programming experience you’ll learn use case_when() with some regular expressions, like this:

vets2 <-
  vets2 %>% 
  mutate(rank_status = 
           case_when(
             str_detect(Rank, pattern = "[OW]") ~ "officer",
             str_detect(Rank, pattern = "E") ~ "enlisted"
           ))

Let’s tally that variable:

vets2 %>% 
  count(rank_status)
rank_status n
enlisted 811
officer 19
NA 81

You are right: not very many officers!

But let’s make a bar chart of the DiagA variable, broken down by rank status:

vets2 %>% 
  drop_na(rank_status, DiagA) %>% 
  ggplot(aes(x = rank_status)) +
  geom_bar(color = "black", aes(fill = DiagA))

You can improve the look of the bar graph in various ways:

vets2 %>% 
  drop_na(rank_status, DiagA) %>% 
  ggplot(aes(x = rank_status)) +
  geom_bar(color = "black", aes(fill = DiagA)) +
  labs(
    ## title for the x-axis:
    x = "Rank",
    ## title for the graph:
    title = "Hey, we can make a title!",
    ## subtitle for the graph:
    subtitle = "(and even a sub-title, if we like ...)",
    ## give the legend a better title:
    fill = "PTSD?"
  )
A jazzier bar graph!

A jazzier bar graph!

Another Version of Your Bar Graph

Make a variable that records whether or not the person was exposed to a blast:

vets3 <-
  vets2 %>% 
  mutate(Blast = ifelse(
    Ref == "B",
    "blast",
    "non-blast")
  )

Now a table:

vets3 %>% 
  drop_na(rank_status, DiagA, Blast) %>% 
  count(rank_status, DiagA, Blast)
rank_status DiagA Blast n
enlisted No PTSD blast 233
enlisted No PTSD non-blast 130
enlisted PTSD blast 379
enlisted PTSD non-blast 69
officer No PTSD blast 10
officer No PTSD non-blast 2
officer PTSD blast 6
officer PTSD non-blast 1

Now for a bar chart:

vets3 %>% 
  drop_na(rank_status, DiagA, Blast) %>% 
  ggplot(aes(x = rank_status)) +
  geom_bar(color = "black", aes(fill = DiagA)) +
  facet_wrap(~ Blast) +
  labs(x = "Rank", fill = "PTSD?")

But you might want to show percentages:

ptsd_table <-
  vets3 %>% 
  drop_na(rank_status, DiagA, Blast) %>% 
  group_by(rank_status, Blast) %>% 
  count(DiagA) %>% 
  mutate(perc = n / sum(n) * 100)
ptsd_table
Percentages of PTSD or not, grouped
Diagnosis Count Percentage
Enlisted, exposed to blast
No PTSD 233 38.07190
PTSD 379 61.92810
Enlisted, not exposed to blast
No PTSD 130 65.32663
PTSD 69 34.67337
Officer, exposed to blast
No PTSD 10 62.50000
PTSD 6 37.50000
Officer, exposed to blast
No PTSD 2 66.66667
PTSD 1 33.33333

Now make the bar graph from the table, instead of making it from the original data. The key is to use the argument stat = "identity" to make the height of the bars equal to the percentages:

ptsd_table %>% 
  ggplot(aes(x = Blast, y = perc)) +
  geom_bar(
    color = "black", 
    aes(fill = DiagA),
    position = "dodge",
    stat = "identity") +
  facet_wrap(~ rank_status) +
  labs(x = "Whether or not exposed to blast", 
       y = "Percentage", fill = "PTSD?")

Making This Document

Reproducing the Document

This file was made with R Markdown. For more on R Markdown, consult the following two resources:

This file was made from the material template provided by the `rmdformats`` package. In order to reproduce it:

  • Press the Code button near the top of the document and download the .Rmd file, saving it to your project directory at the same level as your data folder.

  • Modify your Excel file as I described above.

  • Install some packages that the file uses:

    install.packages(c("tidyverse", "readxl")) ## you already did thid
    install.packages("kableExtra")
    install.packages("remotes")
    remotes::install_github("juba/rmdformats")
  • Open the file in RStudio and press the Knit button.

Suggestion: There are settings for knitting: press the down arrow next to the cog above the source file to see them. Choose the option Preview in Viewer Pane. Then whenever you knit, the document shows up in a Viewer Pane in the lower right of RStudio. If you want to pop it up into your browser for a larger view, there is a button to do so.

Publishing Documents

You can publish your documents for to RPubs:

  • Visit RPubs and set up your free account.
  • Open your R Markdown document and knit it.
  • Looking at the preview of the knitted version, you should see a Publish button. (It is blue and looks like an eye, and the tooltip “Publish the application or document” appears when you hover over it.)
  • Press this button and follow the steps. Choose a nice short name for the “slug”, as this will make the URL for your document easy for others to remember.
  • Your browser will open a new tab, showing the published document.

You can always update the document by pressing the publish button on a future version.

LS0tCnRpdGxlOiAiRXhwbG9yYXRvcnkgV29yayIKZGF0ZTogImByIFN5cy5EYXRlKClgIgphdXRob3I6ICBIb21lciBXaGl0ZQpvdXRwdXQ6CiAgcm1kZm9ybWF0czo6bWF0ZXJpYWw6CiAgICAjdG9jX2RlcHRoOiAyCiAgICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQogICAgaGlnaGxpZ2h0OiAgdGFuZ28KICAgIGxpZ2h0Ym94OiB0cnVlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCi0tLQoKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShyZWFkeGwpCmxpYnJhcnkoa2FibGVFeHRyYSkKIyMgR2xvYmFsIG9wdGlvbnMKb3B0aW9ucyhkcGx5ci5pbmZvcm0uc3VtbWFyaXplID0gRkFMU0UpCmtuaXRyOjpvcHRzX2NodW5rJHNldCgKICBvdXQud2lkdGggPSAiOTAlIiwKICBmaWcuYWxpZ24gPSAiY2VudGVyIiwKICB0aWR5ID0gRkFMU0UsCiAgd2FybmluZyA9IEZBTFNFLAogIG1lc3NhZ2UgPSBGQUxTRQopCmBgYAoKCiMgUGFja2FnZXMgTmVlZGVkCgpgYGB7ciBldmFsID0gRkFMU0V9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHJlYWR4bCkKYGBgCgojIEltcG9ydCB0aGUgRGF0YQoKSSBzYXZlZCB0aGUgRXhjZWwgZmlsZSB0byBhIGZvbGRlciBpbiBteSBwcm9qZWN0IGNhbGxlZCBgZGF0YWAuICBJIHJlbW92ZWQgdGhlIHNlY29uZCByb3cgb2YgdGhlIEV4Y2VsIGZpbGUsIHNpbmNlIGl0IGNvbnRhaW5lZCBubyB1c2VmdWwgaW5mb3JtYXRpb24sIGFuZCBJIHJlbmFtZWQgdGhlIGZpbGUgdG8gYHZldHMueGxzeGAuCgpBcHBhcmVudGx5IHdlIGFyZSBpbnRlcmVzdGVkIGluIHRoZSBmaXJzdCBzaGVldC4gIFRoZSBSLWZ1bmN0aW9uIGByZWFkX3hsc3goKWAgcmVhZHMgaW4gdGhlIGZpcnN0IHNoZWV0IGJ5IGRlZmF1bHQuCgpXZSBvbmx5IHdhbnQgdG8gcmVhZCBpbiB0aGUgZmlyc3Qgc2l4IGNvbHVtbnMgb2YgdGhhdCBmaXJzdCBzaGVldCwgaWdub3JpbmcgYWxsIG9mIHRoZSBhbmFseXNpcyBzdHVjayBpbnRvIHN1YnNlcXVlbnQgY29sdW1ucywgc28gd2UgdXNlIHRoZSBgcmFuZ2VgIHBhcmFtZXRlciBvZiB0aGUgZnVuY3Rpb24sIGFzIGZvbGxvd3M6CgpgYGB7cn0KdmV0cyA8LSByZWFkX3hsc3goCiAgImRhdGEvdmV0cy54bHN4IiwKICByYW5nZSA9ICJBMTpGOTEyIgopCmBgYAoKIyBTb21lIEJhciBHcmFwaHMgKE9uZSBWYXJpYWJsZSkKCkhlcmUgaXMgYSBxdWljayBiYXIgZ3JhcGggb2YgdGhlIHJhbmtzIG9mIHRoZSBzdWJqZWN0czoKCmBgYHtyfQpnZ3Bsb3QodmV0cywgYWVzKHggPSBSYW5rKSkgKwogIGdlb21fYmFyKGNvbG9yID0gImJsYWNrIiwgZmlsbCA9ICJza3libHVlIikKYGBgCgpUaGUgcmFua3MsIHdpdGhvdXQgdGhlIE5BLXZhbHVlczoKCmBgYHtyfQp2ZXRzICU+JSAKICBkcm9wX25hKFJhbmspICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBSYW5rKSkgKwogIGdlb21fYmFyKGNvbG9yID0gImJsYWNrIiwgZmlsbCA9ICJza3libHVlIikKYGBgCgpTdXBwb3NlIHlvdSB3YW50IHRoZSBXYXJyYW50IG9mZmljZXJzIHRvIGNvbWUgaW4gYmV0d2VlbiB0aGUgZW5saXN0ZWQgYW5kIGNvbW1pc3Npb25lZCBvZmZpY2Vycy4gIEluIHRoYXQgY2FzZSwgeW91IG5lZWQgdG8gKm9yZGVyKiB5b3VyIHJhbmtzLiAgRmlyc3QsIGZpbmQgb3V0IHdoYXQgeW91ciByYW5rcyBhcmU6CgpgYGB7cn0KdmV0cyAlPiUgCiAgcHVsbChSYW5rKSAlPiUgCiAgdW5pcXVlKCkgJT4lIAogIHNvcnQoKQpgYGAKCk9uZSBhcHByb2FjaCB0byByZS1vcmRlcmluZyBpcyB0byBtYWtlIFJhbmsgaW50byBhIGZhY3RvciB2YXJpYWJsZSwgd2l0aCB0aGUgImxldmVscyBvZiB0aGUgZmFjdG9yIGluIHRoZSBvcmRlciB5b3Ugd2FudCwgbGlrZSB0aGlzOgoKYGBge3J9CnZldHMyIDwtCiAgdmV0cyAlPiUgCiAgbXV0YXRlKAogICAgb3JkZXJlZF9yYW5rID0gZmFjdG9yKAogICAgICBSYW5rLAogICAgICBsZXZlbHMgPSBjKAogICAgICAgICJFMSIsICJFMiIsICJFMyIsICJFNCIsICJFNSIsICJFNiIsICJFNyIsICJFOCIsICJFOSIsCiAgICAgICAgIlczIiwgIlc0IiwgIlc1IiwKICAgICAgICAiTzIiLCAiTzMiLCAiTzQiCiAgICAgICkKICAgICkKICApCmBgYAoKTm93IHRyeSB0aGUgYmFyIGdyYXBoOgoKYGBge3J9CnZldHMyICU+JSAKICBkcm9wX25hKFJhbmspICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBvcmRlcmVkX3JhbmspKSArCiAgZ2VvbV9iYXIoY29sb3IgPSAiYmxhY2siLCBmaWxsID0gInNreWJsdWUiKSArCiAgbGFicyh4ID0gIlJhbmsiKQpgYGAKCk5vdGUgdGhhdCB3aGVuIGdpdmUgYSBmYWN0b3IsICoqZ2dwbG90MioqIHRha2VzIGFjY291bnQgb2YgdGhlIG9yZGVyaW5nIG9uIHRoZSBsZXZlbHMuCgojIEdyb3VwaW5nLCBhbmQgU29tZSBUYWJsZXMKCllvdSBhcmUgaW50ZXJlc3RlZCBpbiBjb21wYXJpbmcgb2ZmaWNlcnMgd2l0aCBub24tb2ZmaWNlcnMsIGFuZCBpdCBzZWVtcyB5b3UgYXJlIHdpbGxpbmcgdG8gbHVtcCB0aGUgb2ZmaWNlcnMgaW50byBvbmUgZ3JvdXAuICBGb3IgdGhpcywgY3JlYXRlIGEgbmV3IHZhcmlhYmxlOgoKYGBge3J9CnZldHMyIDwtCiAgdmV0czIgJT4lIAogIG11dGF0ZShyYW5rX3N0YXR1cyA9IHJlY29kZSgKICAgIFJhbmssCiAgICBFMSA9ICJlbmxpc3RlZCIsCiAgICBFMiA9ICJlbmxpc3RlZCIsCiAgICBFMyA9ICJlbmxpc3RlZCIsCiAgICBFNCA9ICJlbmxpc3RlZCIsCiAgICBFNSA9ICJlbmxpc3RlZCIsCiAgICBFNiA9ICJlbmxpc3RlZCIsCiAgICBFNyA9ICJlbmxpc3RlZCIsCiAgICBFOCA9ICJlbmxpc3RlZCIsCiAgICBFOSA9ICJlbmxpc3RlZCIsCiAgICBPMiA9ICJvZmZpY2VyIiwKICAgIE8zID0gIm9mZmljZXIiLAogICAgTzQgPSAib2ZmaWNlciIsCiAgICBXMiA9ICJvZmZpY2VyIiwKICAgIFczID0gIm9mZmljZXIiLAogICAgVzQgPSAib2ZmaWNlciIsCiAgICBXNSA9ICJvZmZpY2VyIgogICkKKQpgYGAKCioqTm90ZSoqOiAgVGhhdCdzIGtpbmRhIGN1bWJlcnNvbWUuICBBcyB5b3UgZ2FpbiBwcm9ncmFtbWluZyBleHBlcmllbmNlIHlvdSdsbCBsZWFybiB1c2UgYGNhc2Vfd2hlbigpYCB3aXRoIHNvbWUgKnJlZ3VsYXIgZXhwcmVzc2lvbnMqLCBsaWtlIHRoaXM6CgpgYGB7cn0KdmV0czIgPC0KICB2ZXRzMiAlPiUgCiAgbXV0YXRlKHJhbmtfc3RhdHVzID0gCiAgICAgICAgICAgY2FzZV93aGVuKAogICAgICAgICAgICAgc3RyX2RldGVjdChSYW5rLCBwYXR0ZXJuID0gIltPV10iKSB+ICJvZmZpY2VyIiwKICAgICAgICAgICAgIHN0cl9kZXRlY3QoUmFuaywgcGF0dGVybiA9ICJFIikgfiAiZW5saXN0ZWQiCiAgICAgICAgICAgKSkKYGBgCgoKTGV0J3MgdGFsbHkgdGhhdCB2YXJpYWJsZToKCmBgYHtyIGV2YWwgPSBGQUxTRX0KdmV0czIgJT4lIAogIGNvdW50KHJhbmtfc3RhdHVzKQpgYGAKCmBgYHtyIGVjaG8gPSBGQUxTRX0KdmV0czIgJT4lIAogIGNvdW50KHJhbmtfc3RhdHVzKSAlPiUgCiAga2JsKCkgJT4lCiAga2FibGVfcGFwZXIoImhvdmVyIiwgZnVsbF93aWR0aCA9IEZBTFNFKQpgYGAKCgpZb3UgYXJlIHJpZ2h0OiBub3QgdmVyeSBtYW55IG9mZmljZXJzIQoKQnV0IGxldCdzIG1ha2UgYSBiYXIgY2hhcnQgb2YgdGhlIGBEaWFnQWAgdmFyaWFibGUsIGJyb2tlbiBkb3duIGJ5IHJhbmsgc3RhdHVzOgoKYGBge3J9CnZldHMyICU+JSAKICBkcm9wX25hKHJhbmtfc3RhdHVzLCBEaWFnQSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHJhbmtfc3RhdHVzKSkgKwogIGdlb21fYmFyKGNvbG9yID0gImJsYWNrIiwgYWVzKGZpbGwgPSBEaWFnQSkpCmBgYAoKWW91IGNhbiBpbXByb3ZlIHRoZSBsb29rIG9mIHRoZSBiYXIgZ3JhcGggaW4gdmFyaW91cyB3YXlzOgoKYGBge3IgZmlnLmNhcD0iQSBqYXp6aWVyIGJhciBncmFwaCEifQp2ZXRzMiAlPiUgCiAgZHJvcF9uYShyYW5rX3N0YXR1cywgRGlhZ0EpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSByYW5rX3N0YXR1cykpICsKICBnZW9tX2Jhcihjb2xvciA9ICJibGFjayIsIGFlcyhmaWxsID0gRGlhZ0EpKSArCiAgbGFicygKICAgICMjIHRpdGxlIGZvciB0aGUgeC1heGlzOgogICAgeCA9ICJSYW5rIiwKICAgICMjIHRpdGxlIGZvciB0aGUgZ3JhcGg6CiAgICB0aXRsZSA9ICJIZXksIHdlIGNhbiBtYWtlIGEgdGl0bGUhIiwKICAgICMjIHN1YnRpdGxlIGZvciB0aGUgZ3JhcGg6CiAgICBzdWJ0aXRsZSA9ICIoYW5kIGV2ZW4gYSBzdWItdGl0bGUsIGlmIHdlIGxpa2UgLi4uKSIsCiAgICAjIyBnaXZlIHRoZSBsZWdlbmQgYSBiZXR0ZXIgdGl0bGU6CiAgICBmaWxsID0gIlBUU0Q/IgogICkKYGBgCgoKIyBBbm90aGVyIFZlcnNpb24gb2YgWW91ciBCYXIgR3JhcGgKCk1ha2UgYSB2YXJpYWJsZSB0aGF0IHJlY29yZHMgd2hldGhlciBvciBub3QgdGhlIHBlcnNvbiB3YXMgZXhwb3NlZCB0byBhIGJsYXN0OgoKYGBge3J9CnZldHMzIDwtCiAgdmV0czIgJT4lIAogIG11dGF0ZShCbGFzdCA9IGlmZWxzZSgKICAgIFJlZiA9PSAiQiIsCiAgICAiYmxhc3QiLAogICAgIm5vbi1ibGFzdCIpCiAgKQpgYGAKCk5vdyBhIHRhYmxlOgoKYGBge3IgZXZhbCA9IEZBTFNFfQp2ZXRzMyAlPiUgCiAgZHJvcF9uYShyYW5rX3N0YXR1cywgRGlhZ0EsIEJsYXN0KSAlPiUgCiAgY291bnQocmFua19zdGF0dXMsIERpYWdBLCBCbGFzdCkKYGBgCgpgYGB7ciBlY2hvID0gRkFMU0V9CnZldHMzICU+JSAKICBkcm9wX25hKHJhbmtfc3RhdHVzLCBEaWFnQSwgQmxhc3QpICU+JSAKICBjb3VudChyYW5rX3N0YXR1cywgRGlhZ0EsIEJsYXN0KSAlPiUgCiAga2JsKCkgJT4lIAogIGthYmxlX3BhcGVyKCJob3ZlciIsIGZ1bGxfd2lkdGggPSBGQUxTRSkKYGBgCgoKTm93IGZvciBhIGJhciBjaGFydDoKCmBgYHtyfQp2ZXRzMyAlPiUgCiAgZHJvcF9uYShyYW5rX3N0YXR1cywgRGlhZ0EsIEJsYXN0KSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gcmFua19zdGF0dXMpKSArCiAgZ2VvbV9iYXIoY29sb3IgPSAiYmxhY2siLCBhZXMoZmlsbCA9IERpYWdBKSkgKwogIGZhY2V0X3dyYXAofiBCbGFzdCkgKwogIGxhYnMoeCA9ICJSYW5rIiwgZmlsbCA9ICJQVFNEPyIpCmBgYAoKQnV0IHlvdSBtaWdodCB3YW50IHRvIHNob3cgcGVyY2VudGFnZXM6CgpgYGB7cn0KcHRzZF90YWJsZSA8LQogIHZldHMzICU+JSAKICBkcm9wX25hKHJhbmtfc3RhdHVzLCBEaWFnQSwgQmxhc3QpICU+JSAKICBncm91cF9ieShyYW5rX3N0YXR1cywgQmxhc3QpICU+JSAKICBjb3VudChEaWFnQSkgJT4lIAogIG11dGF0ZShwZXJjID0gbiAvIHN1bShuKSAqIDEwMCkKYGBgCgpgYGB7ciBldmFsID0gRkFMU0V9CnB0c2RfdGFibGUKYGBgCgpgYGB7ciBlY2hvID0gRkFMU0V9CnB0c2RfdGFibGUgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgc2VsZWN0KERpYWdBLCBuLCBwZXJjKSAlPiUgCiAgcmVuYW1lKERpYWdub3NpcyA9IERpYWdBLAogICAgICAgICBDb3VudCA9IG4sCiAgICAgICAgIFBlcmNlbnRhZ2UgPSBwZXJjKSAlPiUgCiAga2JsKGNhcHRpb24gPSAiUGVyY2VudGFnZXMgb2YgUFRTRCBvciBub3QsIGdyb3VwZWQiKSAlPiUKICBrYWJsZV9jbGFzc2ljKGZ1bGxfd2lkdGggPSBGQUxTRSkgJT4lCiAgcGFja19yb3dzKCJFbmxpc3RlZCwgZXhwb3NlZCB0byBibGFzdCIsIDEsIDIpICU+JQogIHBhY2tfcm93cygiRW5saXN0ZWQsIG5vdCBleHBvc2VkIHRvIGJsYXN0IiwgMyw0KSAlPiUKICBwYWNrX3Jvd3MoIk9mZmljZXIsIGV4cG9zZWQgdG8gYmxhc3QiLCA1LCA2KSAlPiUKICBwYWNrX3Jvd3MoIk9mZmljZXIsIGV4cG9zZWQgdG8gYmxhc3QiLCA3LCA4KQpgYGAKCgoKCgpOb3cgbWFrZSB0aGUgYmFyIGdyYXBoIGZyb20gdGhlIHRhYmxlLCBpbnN0ZWFkIG9mIG1ha2luZyBpdCBmcm9tIHRoZSBvcmlnaW5hbCBkYXRhLiAgVGhlIGtleSBpcyB0byB1c2UgdGhlIGFyZ3VtZW50IGBzdGF0ID0gImlkZW50aXR5ImAgdG8gbWFrZSB0aGUgaGVpZ2h0IG9mIHRoZSBiYXJzIGVxdWFsIHRvIHRoZSBwZXJjZW50YWdlczoKCmBgYHtyfQpwdHNkX3RhYmxlICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBCbGFzdCwgeSA9IHBlcmMpKSArCiAgZ2VvbV9iYXIoCiAgICBjb2xvciA9ICJibGFjayIsIAogICAgYWVzKGZpbGwgPSBEaWFnQSksCiAgICBwb3NpdGlvbiA9ICJkb2RnZSIsCiAgICBzdGF0ID0gImlkZW50aXR5IikgKwogIGZhY2V0X3dyYXAofiByYW5rX3N0YXR1cykgKwogIGxhYnMoeCA9ICJXaGV0aGVyIG9yIG5vdCBleHBvc2VkIHRvIGJsYXN0IiwgCiAgICAgICB5ID0gIlBlcmNlbnRhZ2UiLCBmaWxsID0gIlBUU0Q/IikKYGBgCgoKIyBNYWtpbmcgVGhpcyBEb2N1bWVudAoKIyMgUmVwcm9kdWNpbmcgdGhlIERvY3VtZW50CgpUaGlzIGZpbGUgd2FzIG1hZGUgd2l0aCBSIE1hcmtkb3duLiAgRm9yIG1vcmUgb24gUiBNYXJrZG93biwgY29uc3VsdCB0aGUgZm9sbG93aW5nIHR3byByZXNvdXJjZXM6CgoqIFtSU3R1ZGlvJ3MgUiBNYXJrZG93biBzaXRlXShodHRwczovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbS8pCiogW19SIE1hcmtkb3duOiAgdGhlIERlZmluaXRpdmUgR3VpZGVfXShodHRwczovL2Jvb2tkb3duLm9yZy95aWh1aS9ybWFya2Rvd24vKQoKVGhpcyBmaWxlIHdhcyBtYWRlIGZyb20gdGhlICoqbWF0ZXJpYWwqKiB0ZW1wbGF0ZSBwcm92aWRlZCBieSB0aGUgW2BybWRmb3JtYXRzYGAgcGFja2FnZV0oaHR0cHM6Ly9naXRodWIuY29tL2p1YmEvcm1kZm9ybWF0cykuICBJbiBvcmRlciB0byByZXByb2R1Y2UgaXQ6CgoqIFByZXNzIHRoZSBDb2RlIGJ1dHRvbiBuZWFyIHRoZSB0b3Agb2YgdGhlIGRvY3VtZW50IGFuZCBkb3dubG9hZCB0aGUgLlJtZCBmaWxlLCBzYXZpbmcgaXQgdG8geW91ciBwcm9qZWN0IGRpcmVjdG9yeSBhdCB0aGUgc2FtZSBsZXZlbCBhcyB5b3VyIGRhdGEgZm9sZGVyLgoqIE1vZGlmeSB5b3VyIEV4Y2VsIGZpbGUgYXMgSSBkZXNjcmliZWQgYWJvdmUuCiogSW5zdGFsbCBzb21lIHBhY2thZ2VzIHRoYXQgdGhlIGZpbGUgdXNlczoKCiAgICBgYGB7ciBldmFsID0gRkFMU0V9CiAgICBpbnN0YWxsLnBhY2thZ2VzKGMoInRpZHl2ZXJzZSIsICJyZWFkeGwiKSkgIyMgeW91IGFscmVhZHkgZGlkIHRoaWQKICAgIGluc3RhbGwucGFja2FnZXMoImthYmxlRXh0cmEiKQogICAgaW5zdGFsbC5wYWNrYWdlcygicmVtb3RlcyIpCiAgICByZW1vdGVzOjppbnN0YWxsX2dpdGh1YigianViYS9ybWRmb3JtYXRzIikKICAgIGBgYAoqIE9wZW4gdGhlIGZpbGUgaW4gUlN0dWRpbyBhbmQgcHJlc3MgdGhlIEtuaXQgYnV0dG9uLgoKX19TdWdnZXN0aW9uOl9fICBUaGVyZSBhcmUgc2V0dGluZ3MgZm9yIGtuaXR0aW5nOiAgcHJlc3MgdGhlIGRvd24gYXJyb3cgbmV4dCB0byB0aGUgY29nIGFib3ZlIHRoZSBzb3VyY2UgZmlsZSB0byBzZWUgdGhlbS4gIENob29zZSB0aGUgb3B0aW9uIF9QcmV2aWV3IGluIFZpZXdlciBQYW5lXy4gIFRoZW4gd2hlbmV2ZXIgeW91IGtuaXQsIHRoZSBkb2N1bWVudCBzaG93cyB1cCBpbiBhIFZpZXdlciBQYW5lIGluIHRoZSBsb3dlciByaWdodCBvZiBSU3R1ZGlvLiAgSWYgeW91IHdhbnQgdG8gcG9wIGl0IHVwIGludG8geW91ciBicm93c2VyIGZvciBhIGxhcmdlciB2aWV3LCB0aGVyZSBpcyBhIGJ1dHRvbiB0byBkbyBzby4KCiMjIFB1Ymxpc2hpbmcgRG9jdW1lbnRzCgpZb3UgY2FuIHB1Ymxpc2ggeW91ciBkb2N1bWVudHMgZm9yIHRvIFtSUHVic10oaHR0cHM6Ly9ycHVicy5jb20pOgoKKiBWaXNpdCBbUlB1YnNdKGh0dHBzOi8vcnB1YnMuY29tKSBhbmQgc2V0IHVwIHlvdXIgZnJlZSBhY2NvdW50LgoqIE9wZW4geW91ciBSIE1hcmtkb3duIGRvY3VtZW50IGFuZCBrbml0IGl0LgoqIExvb2tpbmcgYXQgdGhlIHByZXZpZXcgb2YgdGhlIGtuaXR0ZWQgdmVyc2lvbiwgeW91IHNob3VsZCBzZWUgYSBQdWJsaXNoIGJ1dHRvbi4gIChJdCBpcyBibHVlIGFuZCBsb29rcyBsaWtlIGFuIGV5ZSwgYW5kIHRoZSB0b29sdGlwICJQdWJsaXNoIHRoZSBhcHBsaWNhdGlvbiBvciBkb2N1bWVudCIgYXBwZWFycyB3aGVuIHlvdSBob3ZlciBvdmVyIGl0LikKKiBQcmVzcyB0aGlzIGJ1dHRvbiBhbmQgZm9sbG93IHRoZSBzdGVwcy4gIENob29zZSBhIG5pY2Ugc2hvcnQgbmFtZSBmb3IgdGhlICJzbHVnIiwgYXMgdGhpcyB3aWxsIG1ha2UgdGhlIFVSTCBmb3IgeW91ciBkb2N1bWVudCBlYXN5IGZvciBvdGhlcnMgdG8gcmVtZW1iZXIuCiogWW91ciBicm93c2VyIHdpbGwgb3BlbiBhIG5ldyB0YWIsIHNob3dpbmcgdGhlIHB1Ymxpc2hlZCBkb2N1bWVudC4KCllvdSBjYW4gYWx3YXlzIHVwZGF0ZSB0aGUgZG9jdW1lbnQgYnkgcHJlc3NpbmcgdGhlIHB1Ymxpc2ggYnV0dG9uIG9uIGEgZnV0dXJlIHZlcnNpb24uCgoKCgoKCgoKCgoKCgoKCgoKCg==