This notebook provides a simple example of how one can create barplots easily from Fcirc data exported from TraceBase.

First, we load our required libraries.

# Load required libraries
library(readr, quietly = TRUE)
library(ggplot2, quietly = TRUE)
library(Rmisc, quietly = TRUE)
library(dplyr, quietly = TRUE)

Glucose Ra (Fcirc) - Serine Sythesis Study

Load Fcirc data

The PeakGroup data was downloaded from TraceBase by:

  1. View a specific study Serine synthesis from glucose in control vs ser/gly-free diet
  2. Click the “Fcirc Data” link at the top
  3. Click on the “Export Data” button
serinesyn_fcirc_data_table <-
  "data/serine_synthesis/Fcirc_10.02.2023.16.29.36.tsv"
serinesyn_fcirc_data <-
  readr::read_tsv(serinesyn_fcirc_data_table, comment = "#")
Rows: 21 Columns: 22── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: "\t"
chr (10): Animal, Studies, Genotype, Age (weeks), Sex, Diet, Feeding Status, Treatment, Tracer Compound, Labeled Element
dbl (12): Body Weight (g), Infusion Rate (ul/min/g), Tracer Concentration (mM), Time Collected (m), Average Ra (nmol/min/g), Average Rd (nmol/min...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
serinesyn_fcirc_data

Plot average Ra by tracer compound

For this example, we are going to plot the average “Rate of Appearance (Ra)” for glucose, split by “Feeding Status”.

Select data

First, we select the columns we want from the data

serinesyn_fcirc_plot_data <- serinesyn_fcirc_data %>%
  # Select maximum time collected for each animal
  group_by(Animal) %>%
  slice(which.max(`Time Collected (m)`))

Calculate summary statistics

We use the summarySE function to calculate the average along with the standard deviation (sd), standard error (se), and confidence interval (ci).

serinesyn_fcirc_summary_data <- serinesyn_fcirc_plot_data %>%
  Rmisc::summarySE(
    measurevar = "Average Ra (nmol/min/g)",
    groupvars = c("`Tracer Compound`", "`Feeding Status`")
  )
serinesyn_fcirc_summary_data

Generate the bar plot

Now we setup the plotting parameters. Note we use standard deviation here for the error bars, but you are free to use whichever statistic is most appropriate.

# Setup the plot
serinesyn_fcirc_plot <- ggplot(
  data = serinesyn_fcirc_summary_data,
  aes(
    x = `Tracer Compound`,
    y = `Average Ra (nmol/min/g)`,
    fill = `Feeding Status`
  )
) +
  geom_bar(stat = "identity", position = position_dodge()) +
  geom_errorbar(aes(
    ymin = `Average Ra (nmol/min/g)` - sd,
    ymax = `Average Ra (nmol/min/g)` + sd
  ),
  width = .2,
  position = position_dodge(.9)
  ) +
  ggtitle("Glucose Average Rate of Appearance (Fcirc) - Serine Synthesis Study")

# Display the plot
serinesyn_fcirc_plot

Glucose Ra (Fcirc) - Multiple Studies

Load Fcirc data

The Fcirc data was downloaded from TraceBase by using the Advanced Search, selecting the “Fcirc” Output Format, and matching on “glucose” as the Tracer Compound.

Fcirc Glucose Tracer Search

glucose_fcirc_data_table <-
  "data/Fcirc-glucose-all-studies_10.02.2023.16.32.27.tsv"
glucose_fcirc_data <- readr::read_tsv(glucose_fcirc_data_table,
  comment = "#",
  na = c("", "NA", "None")
)
Rows: 158 Columns: 22── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: "\t"
chr  (9): Animal, Studies, Genotype, Sex, Diet, Feeding Status, Treatment, Tracer Compound, Labeled Element
dbl (13): Body Weight (g), Age (weeks), Infusion Rate (ul/min/g), Tracer Concentration (mM), Time Collected (m), Average Ra (nmol/min/g), Average...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
glucose_fcirc_data

Plot average Ra by tracer compound

For this example, we are going to plot the average “Rate of Appearance (Ra)” for glucose, split by “Feeding Status” and “Study”.

Select data

First, we select the columns we want from the data

glucose_fcirc_plot_data <- glucose_fcirc_data %>%
  # Select maximum time collected for each animal
  group_by(Animal) %>%
  slice(which.max(`Time Collected (m)`))

Calculate summary statistics

We use the summarySE function to calculate the standard error.

glucose_fcirc_summary_data <- glucose_fcirc_plot_data %>%
  Rmisc::summarySE(
    measurevar = "Average Ra (nmol/min/g)",
    groupvars = c("Studies", "`Feeding Status`"),
    na.rm = TRUE
  ) %>%
  # Rename some studies
  mutate(Studies = recode(Studies,
    "fluxomics 2020" = "Fluxomics 2020",
    "Serine synthesis from glucose in control vs ser/gly-free diet" =
      "Serine synthesis"
  ))
glucose_fcirc_summary_data

Generate the bar plot

Now we setup the plotting parameters.

# Setup the plot
glucose_fcirc_plot <- ggplot(
  data = glucose_fcirc_summary_data,
  aes(
    x = Studies,
    y = `Average Ra (nmol/min/g)`,
    fill = `Feeding Status`
  )
) +
  geom_bar(stat = "identity", position = position_dodge()) +
  geom_errorbar(aes(
    ymin = `Average Ra (nmol/min/g)` - sd,
    ymax = `Average Ra (nmol/min/g)` + sd
  ),
  width = .2,
  position = position_dodge(.9)
  ) +
  ggtitle("Glucose Average Rate of Appearance (Fcirc)")

# Display the plot
glucose_fcirc_plot

Glucose Ra Over Time - Serine Synthesis Study

Calculate summary statistics

For this example, we are going to plot the average “Rate of Appearance (Ra)” for glucose over time, split by “Feeding Status”.

Calculate summary statistics

We use the summarySE function to calculate the standard error.

serinesyn_ratime_summary_data <- serinesyn_fcirc_data %>%
  # Change Time Collected to a factor (not a number)
  mutate_at(vars(`Time Collected (m)`), list(factor)) %>%
  Rmisc::summarySE(
    measurevar = "Average Ra (nmol/min/g)",
    groupvars = c("`Time Collected (m)`", "`Feeding Status`")
  )
serinesyn_ratime_summary_data

Generate the plot

Now we setup the plotting parameters.

# Setup the plot
serinesyn_ratime_plot <- ggplot(
  data = serinesyn_ratime_summary_data,
  aes(
    x = `Feeding Status`,
    y = `Average Ra (nmol/min/g)`,
    fill = `Time Collected (m)`
  )
) +
  geom_bar(stat = "identity", position = position_dodge()) +
  geom_errorbar(aes(
    ymin = `Average Ra (nmol/min/g)` - sd,
    ymax = `Average Ra (nmol/min/g)` + sd
  ),
  width = .2,
  position = position_dodge(.9)
  ) +
  ggtitle("Glucose Ra over time - Serine Synthesis Study")

# Display the plot
serinesyn_ratime_plot

LS0tCnRpdGxlOiAiVHJhY2VCYXNlIEZjaXJjIFBsb3R0aW5nIgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKLS0tCgpUaGlzIG5vdGVib29rIHByb3ZpZGVzIGEgc2ltcGxlIGV4YW1wbGUgb2YgaG93IG9uZSBjYW4gY3JlYXRlIGJhcnBsb3RzIGVhc2lseSBmcm9tIEZjaXJjIGRhdGEgZXhwb3J0ZWQgZnJvbSBUcmFjZUJhc2UuCgpGaXJzdCwgd2UgbG9hZCBvdXIgcmVxdWlyZWQgbGlicmFyaWVzLgpgYGB7ciwgbWVzc2FnZT1GQUxTRX0KIyBMb2FkIHJlcXVpcmVkIGxpYnJhcmllcwpsaWJyYXJ5KHJlYWRyLCBxdWlldGx5ID0gVFJVRSkKbGlicmFyeShnZ3Bsb3QyLCBxdWlldGx5ID0gVFJVRSkKbGlicmFyeShSbWlzYywgcXVpZXRseSA9IFRSVUUpCmxpYnJhcnkoZHBseXIsIHF1aWV0bHkgPSBUUlVFKQpgYGAKCiMjIEdsdWNvc2UgUmEgKEZjaXJjKSAtIFNlcmluZSBTeXRoZXNpcyBTdHVkeQoKIyMjIExvYWQgRmNpcmMgZGF0YQoKVGhlIFBlYWtHcm91cCBkYXRhIHdhcyBkb3dubG9hZGVkIGZyb20gVHJhY2VCYXNlIGJ5OgoKMS4gVmlldyBhIHNwZWNpZmljIHN0dWR5IFtTZXJpbmUgc3ludGhlc2lzIGZyb20gZ2x1Y29zZSBpbiBjb250cm9sIHZzIHNlci9nbHktZnJlZSBkaWV0XShodHRwczovL3RyYWNlYmFzZS5wcmluY2V0b24uZWR1L0RhdGFSZXBvL3N0dWRpZXMvMi8pCjIuIENsaWNrIHRoZSAiRmNpcmMgRGF0YSIgbGluayBhdCB0aGUgdG9wCjMuIENsaWNrIG9uIHRoZSAiRXhwb3J0IERhdGEiIGJ1dHRvbgoKYGBge3IgTG9hZCBGY2lyYyBEYXRhfQpzZXJpbmVzeW5fZmNpcmNfZGF0YV90YWJsZSA8LQogICJkYXRhL3NlcmluZV9zeW50aGVzaXMvRmNpcmNfMTAuMDIuMjAyMy4xNi4yOS4zNi50c3YiCnNlcmluZXN5bl9mY2lyY19kYXRhIDwtCiAgcmVhZHI6OnJlYWRfdHN2KHNlcmluZXN5bl9mY2lyY19kYXRhX3RhYmxlLCBjb21tZW50ID0gIiMiKQpzZXJpbmVzeW5fZmNpcmNfZGF0YQpgYGAKCiMjIyBQbG90IGF2ZXJhZ2UgUmEgYnkgdHJhY2VyIGNvbXBvdW5kCgpGb3IgdGhpcyBleGFtcGxlLCB3ZSBhcmUgZ29pbmcgdG8gcGxvdCB0aGUgYXZlcmFnZSAiUmF0ZSBvZiBBcHBlYXJhbmNlICgqUmEqKSIgZm9yIGdsdWNvc2UsIHNwbGl0IGJ5ICJGZWVkaW5nIFN0YXR1cyIuCgojIyMjIFNlbGVjdCBkYXRhCgpGaXJzdCwgd2Ugc2VsZWN0IHRoZSBjb2x1bW5zIHdlIHdhbnQgZnJvbSB0aGUgZGF0YQpgYGB7ciBTZWxlY3QgUGxvdCBEYXRhfQpzZXJpbmVzeW5fZmNpcmNfcGxvdF9kYXRhIDwtIHNlcmluZXN5bl9mY2lyY19kYXRhICU+JQogICMgU2VsZWN0IG1heGltdW0gdGltZSBjb2xsZWN0ZWQgZm9yIGVhY2ggYW5pbWFsCiAgZ3JvdXBfYnkoQW5pbWFsKSAlPiUKICBzbGljZSh3aGljaC5tYXgoYFRpbWUgQ29sbGVjdGVkIChtKWApKQpgYGAKCiMjIyMgQ2FsY3VsYXRlIHN1bW1hcnkgc3RhdGlzdGljcwoKV2UgdXNlIHRoZSBgc3VtbWFyeVNFYCBmdW5jdGlvbiB0byBjYWxjdWxhdGUgdGhlIGF2ZXJhZ2UgYWxvbmcgd2l0aCB0aGUKc3RhbmRhcmQgZGV2aWF0aW9uIChzZCksIHN0YW5kYXJkIGVycm9yIChzZSksIGFuZCBjb25maWRlbmNlIGludGVydmFsIChjaSkuCmBgYHtyIENhbGN1bGF0ZSBTdW1tYXJ5IFN0YXRzfQpzZXJpbmVzeW5fZmNpcmNfc3VtbWFyeV9kYXRhIDwtIHNlcmluZXN5bl9mY2lyY19wbG90X2RhdGEgJT4lCiAgUm1pc2M6OnN1bW1hcnlTRSgKICAgIG1lYXN1cmV2YXIgPSAiQXZlcmFnZSBSYSAobm1vbC9taW4vZykiLAogICAgZ3JvdXB2YXJzID0gYygiYFRyYWNlciBDb21wb3VuZGAiLCAiYEZlZWRpbmcgU3RhdHVzYCIpCiAgKQpzZXJpbmVzeW5fZmNpcmNfc3VtbWFyeV9kYXRhCmBgYAoKIyMjIyBHZW5lcmF0ZSB0aGUgYmFyIHBsb3QKCk5vdyB3ZSBzZXR1cCB0aGUgcGxvdHRpbmcgcGFyYW1ldGVycy4gTm90ZSB3ZSB1c2Ugc3RhbmRhcmQgZGV2aWF0aW9uIGhlcmUgZm9yCnRoZSBlcnJvciBiYXJzLCBidXQgeW91IGFyZSBmcmVlIHRvIHVzZSB3aGljaGV2ZXIgc3RhdGlzdGljIGlzIG1vc3QKYXBwcm9wcmlhdGUuCmBgYHtyIEZjaXJjIEJhcnBsb3R9CiMgU2V0dXAgdGhlIHBsb3QKc2VyaW5lc3luX2ZjaXJjX3Bsb3QgPC0gZ2dwbG90KAogIGRhdGEgPSBzZXJpbmVzeW5fZmNpcmNfc3VtbWFyeV9kYXRhLAogIGFlcygKICAgIHggPSBgVHJhY2VyIENvbXBvdW5kYCwKICAgIHkgPSBgQXZlcmFnZSBSYSAobm1vbC9taW4vZylgLAogICAgZmlsbCA9IGBGZWVkaW5nIFN0YXR1c2AKICApCikgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKCkpICsKICBnZW9tX2Vycm9yYmFyKGFlcygKICAgIHltaW4gPSBgQXZlcmFnZSBSYSAobm1vbC9taW4vZylgIC0gc2QsCiAgICB5bWF4ID0gYEF2ZXJhZ2UgUmEgKG5tb2wvbWluL2cpYCArIHNkCiAgKSwKICB3aWR0aCA9IC4yLAogIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoLjkpCiAgKSArCiAgZ2d0aXRsZSgiR2x1Y29zZSBBdmVyYWdlIFJhdGUgb2YgQXBwZWFyYW5jZSAoRmNpcmMpIC0gU2VyaW5lIFN5bnRoZXNpcyBTdHVkeSIpCgojIERpc3BsYXkgdGhlIHBsb3QKc2VyaW5lc3luX2ZjaXJjX3Bsb3QKYGBgCgojIyBHbHVjb3NlIFJhIChGY2lyYykgLSBNdWx0aXBsZSBTdHVkaWVzCgojIyMgTG9hZCBGY2lyYyBkYXRhCgpUaGUgRmNpcmMgZGF0YSB3YXMgZG93bmxvYWRlZCBmcm9tIFRyYWNlQmFzZSBieSB1c2luZyB0aGUgQWR2YW5jZWQgU2VhcmNoLCBzZWxlY3RpbmcgdGhlICJGY2lyYyIgT3V0cHV0IEZvcm1hdCwgYW5kIG1hdGNoaW5nIG9uICJnbHVjb3NlIiBhcyB0aGUgVHJhY2VyIENvbXBvdW5kLgoKIVtGY2lyYyBHbHVjb3NlIFRyYWNlciBTZWFyY2hdKGZjaXJjX2dsdWNvc2Vfc2VhcmNoLnBuZykKCmBgYHtyIExvYWQgTXVsdGlwbGUgU3R1ZHkgRmNpcmMgRGF0YX0KZ2x1Y29zZV9mY2lyY19kYXRhX3RhYmxlIDwtCiAgImRhdGEvRmNpcmMtZ2x1Y29zZS1hbGwtc3R1ZGllc18xMC4wMi4yMDIzLjE2LjMyLjI3LnRzdiIKZ2x1Y29zZV9mY2lyY19kYXRhIDwtIHJlYWRyOjpyZWFkX3RzdihnbHVjb3NlX2ZjaXJjX2RhdGFfdGFibGUsCiAgY29tbWVudCA9ICIjIiwKICBuYSA9IGMoIiIsICJOQSIsICJOb25lIikKKQpnbHVjb3NlX2ZjaXJjX2RhdGEKYGBgCgojIyMgUGxvdCBhdmVyYWdlIFJhIGJ5IHRyYWNlciBjb21wb3VuZAoKRm9yIHRoaXMgZXhhbXBsZSwgd2UgYXJlIGdvaW5nIHRvIHBsb3QgdGhlIGF2ZXJhZ2UgIlJhdGUgb2YgQXBwZWFyYW5jZSAoKlJhKikiIGZvciBnbHVjb3NlLCBzcGxpdCBieSAiRmVlZGluZyBTdGF0dXMiIGFuZCAiU3R1ZHkiLgoKIyMjIyBTZWxlY3QgZGF0YQoKRmlyc3QsIHdlIHNlbGVjdCB0aGUgY29sdW1ucyB3ZSB3YW50IGZyb20gdGhlIGRhdGEKYGBge3IgU2VsZWN0IE11bHRpLVN0dWR5IFBsb3QgRGF0YX0KZ2x1Y29zZV9mY2lyY19wbG90X2RhdGEgPC0gZ2x1Y29zZV9mY2lyY19kYXRhICU+JQogICMgU2VsZWN0IG1heGltdW0gdGltZSBjb2xsZWN0ZWQgZm9yIGVhY2ggYW5pbWFsCiAgZ3JvdXBfYnkoQW5pbWFsKSAlPiUKICBzbGljZSh3aGljaC5tYXgoYFRpbWUgQ29sbGVjdGVkIChtKWApKQpgYGAKCiMjIyMgQ2FsY3VsYXRlIHN1bW1hcnkgc3RhdGlzdGljcwoKV2UgdXNlIHRoZSBgc3VtbWFyeVNFYCBmdW5jdGlvbiB0byBjYWxjdWxhdGUgdGhlIHN0YW5kYXJkIGVycm9yLgpgYGB7ciBDYWxjdWxhdGUgTXVsdGktU3R1ZHkgU3VtbWFyeSBTdGF0c30KZ2x1Y29zZV9mY2lyY19zdW1tYXJ5X2RhdGEgPC0gZ2x1Y29zZV9mY2lyY19wbG90X2RhdGEgJT4lCiAgUm1pc2M6OnN1bW1hcnlTRSgKICAgIG1lYXN1cmV2YXIgPSAiQXZlcmFnZSBSYSAobm1vbC9taW4vZykiLAogICAgZ3JvdXB2YXJzID0gYygiU3R1ZGllcyIsICJgRmVlZGluZyBTdGF0dXNgIiksCiAgICBuYS5ybSA9IFRSVUUKICApICU+JQogICMgUmVuYW1lIHNvbWUgc3R1ZGllcwogIG11dGF0ZShTdHVkaWVzID0gcmVjb2RlKFN0dWRpZXMsCiAgICAiZmx1eG9taWNzIDIwMjAiID0gIkZsdXhvbWljcyAyMDIwIiwKICAgICJTZXJpbmUgc3ludGhlc2lzIGZyb20gZ2x1Y29zZSBpbiBjb250cm9sIHZzIHNlci9nbHktZnJlZSBkaWV0IiA9CiAgICAgICJTZXJpbmUgc3ludGhlc2lzIgogICkpCmdsdWNvc2VfZmNpcmNfc3VtbWFyeV9kYXRhCmBgYAoKIyMjIyBHZW5lcmF0ZSB0aGUgYmFyIHBsb3QKCk5vdyB3ZSBzZXR1cCB0aGUgcGxvdHRpbmcgcGFyYW1ldGVycy4KYGBge3IgRmNpcmMgTXVsdGktU3R1ZHkgQmFycGxvdCwgZmlnLndpZHRoPTEwfQojIFNldHVwIHRoZSBwbG90CmdsdWNvc2VfZmNpcmNfcGxvdCA8LSBnZ3Bsb3QoCiAgZGF0YSA9IGdsdWNvc2VfZmNpcmNfc3VtbWFyeV9kYXRhLAogIGFlcygKICAgIHggPSBTdHVkaWVzLAogICAgeSA9IGBBdmVyYWdlIFJhIChubW9sL21pbi9nKWAsCiAgICBmaWxsID0gYEZlZWRpbmcgU3RhdHVzYAogICkKKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoKSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKAogICAgeW1pbiA9IGBBdmVyYWdlIFJhIChubW9sL21pbi9nKWAgLSBzZCwKICAgIHltYXggPSBgQXZlcmFnZSBSYSAobm1vbC9taW4vZylgICsgc2QKICApLAogIHdpZHRoID0gLjIsCiAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSguOSkKICApICsKICBnZ3RpdGxlKCJHbHVjb3NlIEF2ZXJhZ2UgUmF0ZSBvZiBBcHBlYXJhbmNlIChGY2lyYykiKQoKIyBEaXNwbGF5IHRoZSBwbG90CmdsdWNvc2VfZmNpcmNfcGxvdApgYGAKCiMjIEdsdWNvc2UgUmEgT3ZlciBUaW1lIC0gU2VyaW5lIFN5bnRoZXNpcyBTdHVkeQoKIyMjIENhbGN1bGF0ZSBzdW1tYXJ5IHN0YXRpc3RpY3MKCkZvciB0aGlzIGV4YW1wbGUsIHdlIGFyZSBnb2luZyB0byBwbG90IHRoZSBhdmVyYWdlICJSYXRlIG9mIEFwcGVhcmFuY2UgKCpSYSopIiBmb3IgZ2x1Y29zZSBvdmVyIHRpbWUsIHNwbGl0IGJ5ICJGZWVkaW5nIFN0YXR1cyIuCgojIyMjIENhbGN1bGF0ZSBzdW1tYXJ5IHN0YXRpc3RpY3MKCldlIHVzZSB0aGUgYHN1bW1hcnlTRWAgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIHRoZSBzdGFuZGFyZCBlcnJvci4KYGBge3J9CnNlcmluZXN5bl9yYXRpbWVfc3VtbWFyeV9kYXRhIDwtIHNlcmluZXN5bl9mY2lyY19kYXRhICU+JQogICMgQ2hhbmdlIFRpbWUgQ29sbGVjdGVkIHRvIGEgZmFjdG9yIChub3QgYSBudW1iZXIpCiAgbXV0YXRlX2F0KHZhcnMoYFRpbWUgQ29sbGVjdGVkIChtKWApLCBsaXN0KGZhY3RvcikpICU+JQogIFJtaXNjOjpzdW1tYXJ5U0UoCiAgICBtZWFzdXJldmFyID0gIkF2ZXJhZ2UgUmEgKG5tb2wvbWluL2cpIiwKICAgIGdyb3VwdmFycyA9IGMoImBUaW1lIENvbGxlY3RlZCAobSlgIiwgImBGZWVkaW5nIFN0YXR1c2AiKQogICkKc2VyaW5lc3luX3JhdGltZV9zdW1tYXJ5X2RhdGEKYGBgCiMjIyBHZW5lcmF0ZSB0aGUgcGxvdAoKTm93IHdlIHNldHVwIHRoZSBwbG90dGluZyBwYXJhbWV0ZXJzLgpgYGB7cn0KIyBTZXR1cCB0aGUgcGxvdApzZXJpbmVzeW5fcmF0aW1lX3Bsb3QgPC0gZ2dwbG90KAogIGRhdGEgPSBzZXJpbmVzeW5fcmF0aW1lX3N1bW1hcnlfZGF0YSwKICBhZXMoCiAgICB4ID0gYEZlZWRpbmcgU3RhdHVzYCwKICAgIHkgPSBgQXZlcmFnZSBSYSAobm1vbC9taW4vZylgLAogICAgZmlsbCA9IGBUaW1lIENvbGxlY3RlZCAobSlgCiAgKQopICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgpKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoCiAgICB5bWluID0gYEF2ZXJhZ2UgUmEgKG5tb2wvbWluL2cpYCAtIHNkLAogICAgeW1heCA9IGBBdmVyYWdlIFJhIChubW9sL21pbi9nKWAgKyBzZAogICksCiAgd2lkdGggPSAuMiwKICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKC45KQogICkgKwogIGdndGl0bGUoIkdsdWNvc2UgUmEgb3ZlciB0aW1lIC0gU2VyaW5lIFN5bnRoZXNpcyBTdHVkeSIpCgojIERpc3BsYXkgdGhlIHBsb3QKc2VyaW5lc3luX3JhdGltZV9wbG90CmBgYAo=