1 S. cerevisiae sample estimation of all samples (old and new)

This document should make clear the suitability of our yeast data for differential expression analyses. It should also give some ideas about the depth and distribution of the data.

2 Gathering samples

merged_expt <- sm(create_expt(metadata="sample_sheets/all_samples.xlsx",
                              gene_info=sc_all_annotations,
                              file_column="allfile"))
## Don't forget, I need to change the condition names.
merged_nor <- subset_expt(merged_expt, subset="batch!='r'")
merged_nos <- subset_expt(merged_expt, subset="batch!='s'")

3 Visualizing raw data

There are lots of toys we have learned to use to play with with raw data and explore stuff like batch effects or non-canonical distributions or skewed counts. hpgltools provides some functionality to make this process easier. The graphs shown below and many more are generated with the wrapper ‘graph_metrics()’ but that takes away the chance to explain the graphs as I generate them.

merged_filt <- sm(normalize_expt(merged_expt, filter=TRUE))

merged_libsize <- plot_libsize(merged_expt)

##tt <- pp(file="illustrator_input/libsize.pdf", image=merged_libsize$plot)
##dev.off()
merged_libsize$plot

merged_nonzero <- plot_nonzero(merged_filt)
tt <- pp(file="illustrator_input/nonzero.pdf", image=merged_nonzero$plot)
## Wrote the image to: illustrator_input/nonzero.pdf
merged_density <- plot_density(merged_filt)
## This data will benefit from being displayed on the log scale.
## If this is not desired, set scale='raw'
## Some entries are 0.  We are on log scale, setting them to 0.5.
## Changed 1152 zero count features.
tt <- pp(file="illustrator_input/raw_density.pdf", image=merged_density$plot)
## Wrote the image to: illustrator_input/raw_density.pdf
merged_boxplot <- plot_boxplot(merged_filt)
## This data will benefit from being displayed on the log scale.
## If this is not desired, set scale='raw'
## Some entries are 0.  We are on log scale, adding 1 to the data.
## Changed 1152 zero count features.
tt <- pp(file="illustrator_input/raw_boxplot.pdf", image=merged_boxplot)
## Wrote the image to: illustrator_input/raw_boxplot.pdf
topn <- plot_topn(merged_filt)
tt <- pp(file="illustrator_input/topn.pdf", image=topn$plot)
## Wrote the image to: illustrator_input/topn.pdf
prepost <- plot_libsize_prepost(merged_expt)
tt <- pp(file="illustrator_input/libsize_changes_lowfilter.pdf", image=prepost$lowgene_plot)
## Wrote the image to: illustrator_input/libsize_changes_lowfilter.pdf

4 Normalize and visualize

merged_norm <- normalize_expt(merged_expt, transform="log2", convert="cpm", filter=TRUE)
## This function will replace the expt$expressionset slot with:
## log2(cpm(hpgl(data)))
## It backs up the current data into a slot named:
##  expt$backup_expressionset. It will also save copies of each step along the way
##  in expt$normalized with the corresponding libsizes. Keep the libsizes in mind
##  when invoking limma.  The appropriate libsize is the non-log(cpm(normalized)).
##  This is most likely kept at:
##  'new_expt$normalized$intermediate_counts$normalization$libsizes'
##  A copy of this may also be found at:
##  new_expt$best_libsize
## Leaving the data unnormalized.  This is necessary for DESeq, but
##  EdgeR/limma might benefit from normalization.  Good choices include quantile,
##  size-factor, tmm, etc.
## Not correcting the count-data for batch effects.  If batch is
##  included in EdgerR/limma's model, then this is probably wise; but in extreme
##  batch effects this is a good parameter to play with.
## Step 1: performing count filter with option: hpgl
## Removing 1030 low-count genes (6095 remaining).
## Step 2: not normalizing the data.
## Step 3: converting the data with cpm.
## Step 4: transforming the data with log2.
## transform_counts: Found 1152 values equal to 0, adding 1 to the matrix.
## Step 5: not doing batch correction.
merged_metrics <- graph_metrics(merged_norm)
## Closing the pdf, X11cairo, cairo_pdf, cairo_pdf, cairo_pdf, cairo_pdf, png, cairo_pdf, cairo_pdf, cairo_pdf, cairo_pdf, cairo_pdf plotting device(s) before printing plots.
## Graphing number of non-zero genes with respect to CPM by library.
## Graphing library sizes.
## Graphing a boxplot.
## Graphing a correlation heatmap.
## Graphing a standard median correlation.
## Performing correlation.
## Graphing a distance heatmap.
## Graphing a standard median distance.
## Performing distance.
## Graphing a PCA plot.
## Graphing a T-SNE plot.
## Plotting a density plot.
## Plotting the representation of the top-n genes.
## Printing a color to condition legend.

The data should now be normalized, lets view some metrics post-facto.

I think something is very wrong, this should be printing pictures but seems to not be. Hmm I ran it manually and everything looks fine. I wonder what is going on? Lets re-render this and see what happens? I wonder if I left a graphics device open and didn’t realize it?

tt <- pp(file="illustrator_input/norm_corheat.pdf", image=merged_metrics$corheat)
## Wrote the image to: illustrator_input/norm_corheat.pdf
dev.off()
## pdf 
##   2
merged_metrics$corheat

tt <- pp(file="illustrator_input/norm_disheat.pdf", image=merged_metrics$disheat)
## Wrote the image to: illustrator_input/norm_disheat.pdf
## It appears that just the normalization is sufficient to split the samples completely by type and deeply separate them from the heterologous samples

tt <- pp(file="illustrator_input/norm_smc.pdf", image=merged_metrics$smc)
## Wrote the image to: illustrator_input/norm_smc.pdf
tt <- pp(file="illustrator_input/norm_smd.pdf", image=merged_metrics$smd)
## Wrote the image to: illustrator_input/norm_smd.pdf
## The samples are very well behaved, none fall below the red line.

tt <- pp(file="illustrator_input/norm_pca_test.pdf", image=merged_metrics$pcaplot)
## Wrote the image to: illustrator_input/norm_pca_test.pdf
tt <- pp(file="illustrator_input/norm_tsne.pdf", image=merged_metrics$tsneplot)
## Wrote the image to: illustrator_input/norm_tsne.pdf
## The homogeneous wt/mutant are nicely separated, and what is more, the exogeneous samples also split wt/mutant, that might prove to be quite useful.

tt <- pp(file="illustrator_input/legend.pdf", image=merged_metrics$legend)
## Wrote the image to: illustrator_input/legend.pdf

5 Now look at the data without batch ‘r’

nor_norm <- sm(normalize_expt(merged_nor, transform="log2", convert="cpm", norm="quant", filter=TRUE))
nor_plots <- sm(graph_metrics(nor_norm))
nor_batchnorm <- sm(normalize_expt(merged_nor, transform="log2", convert="cpm", norm="quant", filter=TRUE,
                                batch="fsva"))
nor_batchplots <- sm(graph_metrics(nor_batchnorm))
## Before fsva
tt <- pp(file="illustrator_input/nor_corheat.pdf", image=nor_plots$corheat)
## Wrote the image to: illustrator_input/nor_corheat.pdf
tt <- pp(file="illustrator_input/nor_pca.pdf", image=nor_plots$pcaplot)
## Wrote the image to: illustrator_input/nor_pca.pdf
## After fsva
tt <- pp(file="illustrator_input/norbatch_corheat.pdf", image=nor_batchplots$corheat)
## Wrote the image to: illustrator_input/norbatch_corheat.pdf
tt <- pp(file="illustrator_input/norbatch_pca.pdf", image=nor_batchplots$pcaplot)
## Wrote the image to: illustrator_input/norbatch_pca.pdf

6 Try many batch estimation methods to see what is up.

I do not think any of this information is currently being used, so I am going to stop running it for the moment but keep it here in case we decide to revive it.

merged_pcabatch <- sm(normalize_expt(merged_expt, transform="log2",
                                filter=TRUE, batch="pca", low_to_zero=TRUE))
merged_pcabatch_metrics <- sm(graph_metrics(merged_pcabatch))

merged_nor_pcabatch <- sm(normalize_expt(merged_nor, transform="log2",
                                filter=TRUE, batch="pca", low_to_zero=TRUE))
merged_nor_pcabatch_metrics <- sm(graph_metrics(merged_nor_pcabatch))

merged_nos_pcabatch <- sm(normalize_expt(merged_nos, transform="log2",
                                filter=TRUE, batch="pca", low_to_zero=TRUE))
merged_nos_pcabatch_metrics <- sm(graph_metrics(merged_nos_pcabatch))

merged_sva <- sm(normalize_expt(merged_expt, transform="log2",
                                filter=TRUE, batch="sva", low_to_zero=TRUE))
merged_sva_metrics <- sm(graph_metrics(merged_sva))

merged_nor_sva <- sm(normalize_expt(merged_nor, transform="log2",
                                filter=TRUE, batch="sva", low_to_zero=TRUE))
merged_nor_sva_metrics <- sm(graph_metrics(merged_nor_sva))

merged_nos_sva <- sm(normalize_expt(merged_nos, transform="log2",
                                filter=TRUE, batch="sva", low_to_zero=TRUE))
merged_nos_sva_metrics <- sm(graph_metrics(merged_nos_sva))

merged_combat <- sm(normalize_expt(merged_expt, transform="log2",
                                   filter=TRUE, batch="combat_scale", low_to_zero=TRUE))
merged_combat_metrics <- sm(graph_metrics(merged_combat))

merged_nor_combat <- sm(normalize_expt(merged_nor, transform="log2",
                                   filter=TRUE, batch="combat_scale", low_to_zero=TRUE))
merged_nor_combat_metrics <- sm(graph_metrics(merged_nor_combat))

merged_nos_combat <- sm(normalize_expt(merged_nos, transform="log2",
                                   filter=TRUE, batch="combat_scale", low_to_zero=TRUE))
merged_nos_combat_metrics <- sm(graph_metrics(merged_nos_combat))

merged_limma <- sm(normalize_expt(merged_expt, transform="log2",
                                   filter=TRUE, batch="limmaresid", low_to_zero=TRUE))
merged_limma_metrics <- sm(graph_metrics(merged_limma))

merged_nor_limma <- sm(normalize_expt(merged_nor, transform="log2",
                                   filter=TRUE, batch="limmaresid", low_to_zero=TRUE))
merged_nor_limma_metrics <- sm(graph_metrics(merged_nor_limma))

merged_nos_limma <- sm(normalize_expt(merged_nos, transform="log2",
                                   filter=TRUE, batch="limmaresid", low_to_zero=TRUE))
merged_nos_limma_metrics <- sm(graph_metrics(merged_nos_limma))

merged_fsva <- sm(normalize_expt(merged_expt, transform="log2",
                              filter=TRUE, batch="fsva", low_to_zero=TRUE))
merged_fsva_metrics <- sm(graph_metrics(merged_fsva))

merged_nor_fsva <- sm(normalize_expt(merged_nor, transform="log2",
                              filter=TRUE, batch="fsva", low_to_zero=TRUE))
merged_nor_fsva_metrics <- sm(graph_metrics(merged_nor_fsva))

merged_nos_fsva <- sm(normalize_expt(merged_nos, transform="log2",
                              filter=TRUE, batch="ssva", low_to_zero=TRUE))
merged_nos_fsva_metrics <- sm(graph_metrics(merged_nos_fsva))

6.0.1 The resulting plots

Why is is suddenly printing stuff now and not before?

merged_pcabatch_metrics$pcaplot

merged_nor_pcabatch_metrics$pcaplot

merged_nos_pcabatch_metrics$pcaplot

merged_sva_metrics$pcaplot

merged_nor_sva_metrics$pcaplot

merged_nos_sva_metrics$pcaplot

merged_combat_metrics$pcaplot

merged_nor_combat_metrics$pcaplot

merged_nos_combat_metrics$pcaplot

merged_limma_metrics$pcaplot

merged_nor_limma_metrics$pcaplot

merged_nos_limma_metrics$pcaplot

merged_fsva_metrics$pcaplot

merged_nor_fsva_metrics$pcaplot

merged_nos_fsva_metrics$pcaplot

6.1 Look at specific normalizations via pca/tsne

merged_nor_fsva_metrics$pcaplot

7 Write the expt

## hmm I was going to silence this line, but looking at the report it seems to be missing some pictures.
fun_nor <- write_expt(merged_nor, excel=paste0("excel/samples_written_merged_nor-v", ver, ".xlsx"),
                      filter=TRUE, norm="raw", convert="cpm", batch="fsva", transform="log2")
LS0tCnRpdGxlOiAiUy4gY2VyZXZpc2lhZSBzYW1wbGUgZXN0aW1hdGlvbiwgbWVyZ2VkIHNhbXBsZSBlZGl0aW9uLiIKYXV0aG9yOiAiYXRiIGFiZWxld0BnbWFpbC5jb20iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogaHRtbF9kb2N1bWVudDoKICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgY29kZV9mb2xkaW5nOiBzaG93CiAgZmlnX2NhcHRpb246IHRydWUKICBmaWdfaGVpZ2h0OiA3CiAgZmlnX3dpZHRoOiA3CiAgaGlnaGxpZ2h0OiBkZWZhdWx0CiAga2VlcF9tZDogZmFsc2UKICBtb2RlOiBzZWxmY29udGFpbmVkCiAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgc2VsZl9jb250YWluZWQ6IHRydWUKICB0aGVtZTogcmVhZGFibGUKICB0b2M6IHRydWUKICB0b2NfZmxvYXQ6CiAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQotLS0KCjxzdHlsZT4KICBib2R5IC5tYWluLWNvbnRhaW5lciB7CiAgICBtYXgtd2lkdGg6IDE2MDBweDsKICB9Cjwvc3R5bGU+CgpgYGB7ciBvcHRpb25zLCBpbmNsdWRlPUZBTFNFfQppZiAoIWlzVFJVRShnZXQwKCJza2lwX2xvYWQiKSkpIHsKICBsaWJyYXJ5KCJocGdsdG9vbHMiKQogIHR0IDwtIGRldnRvb2xzOjpsb2FkX2FsbCgifi9ocGdsdG9vbHMiKQogIGtuaXRyOjpvcHRzX2tuaXQkc2V0KHByb2dyZXNzPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgdmVyYm9zZT1UUlVFLAogICAgICAgICAgICAgICAgICAgICAgIHdpZHRoPTkwLAogICAgICAgICAgICAgICAgICAgICAgIGVjaG89VFJVRSkKICBrbml0cjo6b3B0c19jaHVuayRzZXQoZXJyb3I9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgZmlnLndpZHRoPTgsCiAgICAgICAgICAgICAgICAgICAgICAgIGZpZy5oZWlnaHQ9OCwKICAgICAgICAgICAgICAgICAgICAgICAgZHBpPTk2KQogIG9sZF9vcHRpb25zIDwtIG9wdGlvbnMoZGlnaXRzPTQsCiAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdzQXNGYWN0b3JzPUZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAga25pdHIuZHVwbGljYXRlLmxhYmVsPSJhbGxvdyIpCiAgIyNnZ3Bsb3QyOjp0aGVtZV9zZXQoZ2dwbG90Mjo6dGhlbWVfYncoYmFzZV9zaXplPTEwKSkKICBzZXQuc2VlZCgxKQogIHZlciA8LSAiMjAxODAyMTIiCiAgcHJldmlvdXNfZmlsZSA8LSAiMDFfYW5ub3RhdGlvbi5SbWQiCgogIHRtcCA8LSB0cnkoc20obG9hZG1lKGZpbGVuYW1lPXBhc3RlMChnc3ViKHBhdHRlcm49IlxcLlJtZCIsIHJlcGxhY2U9IiIsIHg9cHJldmlvdXNfZmlsZSksICItdiIsIHZlciwgIi5yZGEueHoiKSkpKQogIHJtZF9maWxlIDwtICIwMl9zYW1wbGVfZXN0aW1hdGlvbl9tZXJnZWQuUm1kIgp9CmBgYAoKUy4gY2VyZXZpc2lhZSBzYW1wbGUgZXN0aW1hdGlvbiBvZiBhbGwgc2FtcGxlcyAob2xkIGFuZCBuZXcpCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKVGhpcyBkb2N1bWVudCBzaG91bGQgbWFrZSBjbGVhciB0aGUgc3VpdGFiaWxpdHkgb2Ygb3VyIHllYXN0IGRhdGEgZm9yIGRpZmZlcmVudGlhbCBleHByZXNzaW9uCmFuYWx5c2VzLiAgSXQgc2hvdWxkIGFsc28gZ2l2ZSBzb21lIGlkZWFzIGFib3V0IHRoZSBkZXB0aCBhbmQgZGlzdHJpYnV0aW9uIG9mCnRoZSBkYXRhLgoKIyBHYXRoZXJpbmcgc2FtcGxlcwoKYGBge3IgZ2F0aGVyX2FsbH0KbWVyZ2VkX2V4cHQgPC0gc20oY3JlYXRlX2V4cHQobWV0YWRhdGE9InNhbXBsZV9zaGVldHMvYWxsX3NhbXBsZXMueGxzeCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVfaW5mbz1zY19hbGxfYW5ub3RhdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVfY29sdW1uPSJhbGxmaWxlIikpCiMjIERvbid0IGZvcmdldCwgSSBuZWVkIHRvIGNoYW5nZSB0aGUgY29uZGl0aW9uIG5hbWVzLgptZXJnZWRfbm9yIDwtIHN1YnNldF9leHB0KG1lcmdlZF9leHB0LCBzdWJzZXQ9ImJhdGNoIT0nciciKQptZXJnZWRfbm9zIDwtIHN1YnNldF9leHB0KG1lcmdlZF9leHB0LCBzdWJzZXQ9ImJhdGNoIT0ncyciKQpgYGAKCiMgVmlzdWFsaXppbmcgcmF3IGRhdGEKClRoZXJlIGFyZSBsb3RzIG9mIHRveXMgd2UgaGF2ZSBsZWFybmVkIHRvIHVzZSB0byBwbGF5IHdpdGggd2l0aCByYXcgZGF0YSBhbmQgZXhwbG9yZSBzdHVmZiBsaWtlCmJhdGNoIGVmZmVjdHMgb3Igbm9uLWNhbm9uaWNhbCBkaXN0cmlidXRpb25zIG9yIHNrZXdlZCBjb3VudHMuICBocGdsdG9vbHMgcHJvdmlkZXMgc29tZSBmdW5jdGlvbmFsaXR5CnRvIG1ha2UgdGhpcyBwcm9jZXNzIGVhc2llci4gIFRoZSBncmFwaHMgc2hvd24gYmVsb3cgYW5kIG1hbnkgbW9yZSBhcmUgZ2VuZXJhdGVkIHdpdGggdGhlIHdyYXBwZXIKJ2dyYXBoX21ldHJpY3MoKScgYnV0IHRoYXQgdGFrZXMgYXdheSB0aGUgY2hhbmNlIHRvIGV4cGxhaW4gdGhlIGdyYXBocyBhcyBJIGdlbmVyYXRlIHRoZW0uCgpgYGB7ciByYXdfZXhwbG9yZX0KbWVyZ2VkX2ZpbHQgPC0gc20obm9ybWFsaXplX2V4cHQobWVyZ2VkX2V4cHQsIGZpbHRlcj1UUlVFKSkKCm1lcmdlZF9saWJzaXplIDwtIHBsb3RfbGlic2l6ZShtZXJnZWRfZXhwdCkKCiMjdHQgPC0gcHAoZmlsZT0iaWxsdXN0cmF0b3JfaW5wdXQvbGlic2l6ZS5wZGYiLCBpbWFnZT1tZXJnZWRfbGlic2l6ZSRwbG90KQojI2Rldi5vZmYoKQptZXJnZWRfbGlic2l6ZSRwbG90CgptZXJnZWRfbm9uemVybyA8LSBwbG90X25vbnplcm8obWVyZ2VkX2ZpbHQpCnR0IDwtIHBwKGZpbGU9ImlsbHVzdHJhdG9yX2lucHV0L25vbnplcm8ucGRmIiwgaW1hZ2U9bWVyZ2VkX25vbnplcm8kcGxvdCkKCm1lcmdlZF9kZW5zaXR5IDwtIHBsb3RfZGVuc2l0eShtZXJnZWRfZmlsdCkKdHQgPC0gcHAoZmlsZT0iaWxsdXN0cmF0b3JfaW5wdXQvcmF3X2RlbnNpdHkucGRmIiwgaW1hZ2U9bWVyZ2VkX2RlbnNpdHkkcGxvdCkKCm1lcmdlZF9ib3hwbG90IDwtIHBsb3RfYm94cGxvdChtZXJnZWRfZmlsdCkKdHQgPC0gcHAoZmlsZT0iaWxsdXN0cmF0b3JfaW5wdXQvcmF3X2JveHBsb3QucGRmIiwgaW1hZ2U9bWVyZ2VkX2JveHBsb3QpCgp0b3BuIDwtIHBsb3RfdG9wbihtZXJnZWRfZmlsdCkKdHQgPC0gcHAoZmlsZT0iaWxsdXN0cmF0b3JfaW5wdXQvdG9wbi5wZGYiLCBpbWFnZT10b3BuJHBsb3QpCgpwcmVwb3N0IDwtIHBsb3RfbGlic2l6ZV9wcmVwb3N0KG1lcmdlZF9leHB0KQp0dCA8LSBwcChmaWxlPSJpbGx1c3RyYXRvcl9pbnB1dC9saWJzaXplX2NoYW5nZXNfbG93ZmlsdGVyLnBkZiIsIGltYWdlPXByZXBvc3QkbG93Z2VuZV9wbG90KQpgYGAKCiMgTm9ybWFsaXplIGFuZCB2aXN1YWxpemUKCmBgYHtyIG5vcm1hbGl6ZX0KbWVyZ2VkX25vcm0gPC0gbm9ybWFsaXplX2V4cHQobWVyZ2VkX2V4cHQsIHRyYW5zZm9ybT0ibG9nMiIsIGNvbnZlcnQ9ImNwbSIsIGZpbHRlcj1UUlVFKQptZXJnZWRfbWV0cmljcyA8LSBncmFwaF9tZXRyaWNzKG1lcmdlZF9ub3JtKQpgYGAKClRoZSBkYXRhIHNob3VsZCBub3cgYmUgbm9ybWFsaXplZCwgbGV0cyB2aWV3IHNvbWUgbWV0cmljcyBwb3N0LWZhY3RvLgoKSSB0aGluayBzb21ldGhpbmcgaXMgdmVyeSB3cm9uZywgdGhpcyBzaG91bGQgYmUgcHJpbnRpbmcgcGljdHVyZXMgYnV0IHNlZW1zIHRvIG5vdCBiZS4KSG1tIEkgcmFuIGl0IG1hbnVhbGx5IGFuZCBldmVyeXRoaW5nIGxvb2tzIGZpbmUuIEkgd29uZGVyIHdoYXQgaXMgZ29pbmcgb24/CkxldHMgcmUtcmVuZGVyIHRoaXMgYW5kIHNlZSB3aGF0IGhhcHBlbnM/Ckkgd29uZGVyIGlmIEkgbGVmdCBhIGdyYXBoaWNzIGRldmljZSBvcGVuIGFuZCBkaWRuJ3QgcmVhbGl6ZSBpdD8KCmBgYHtyIG5vcm12aXp9CnR0IDwtIHBwKGZpbGU9ImlsbHVzdHJhdG9yX2lucHV0L25vcm1fY29yaGVhdC5wZGYiLCBpbWFnZT1tZXJnZWRfbWV0cmljcyRjb3JoZWF0KQpkZXYub2ZmKCkKbWVyZ2VkX21ldHJpY3MkY29yaGVhdAoKdHQgPC0gcHAoZmlsZT0iaWxsdXN0cmF0b3JfaW5wdXQvbm9ybV9kaXNoZWF0LnBkZiIsIGltYWdlPW1lcmdlZF9tZXRyaWNzJGRpc2hlYXQpCiMjIEl0IGFwcGVhcnMgdGhhdCBqdXN0IHRoZSBub3JtYWxpemF0aW9uIGlzIHN1ZmZpY2llbnQgdG8gc3BsaXQgdGhlIHNhbXBsZXMgY29tcGxldGVseSBieSB0eXBlIGFuZCBkZWVwbHkgc2VwYXJhdGUgdGhlbSBmcm9tIHRoZSBoZXRlcm9sb2dvdXMgc2FtcGxlcwoKdHQgPC0gcHAoZmlsZT0iaWxsdXN0cmF0b3JfaW5wdXQvbm9ybV9zbWMucGRmIiwgaW1hZ2U9bWVyZ2VkX21ldHJpY3Mkc21jKQp0dCA8LSBwcChmaWxlPSJpbGx1c3RyYXRvcl9pbnB1dC9ub3JtX3NtZC5wZGYiLCBpbWFnZT1tZXJnZWRfbWV0cmljcyRzbWQpCiMjIFRoZSBzYW1wbGVzIGFyZSB2ZXJ5IHdlbGwgYmVoYXZlZCwgbm9uZSBmYWxsIGJlbG93IHRoZSByZWQgbGluZS4KCnR0IDwtIHBwKGZpbGU9ImlsbHVzdHJhdG9yX2lucHV0L25vcm1fcGNhX3Rlc3QucGRmIiwgaW1hZ2U9bWVyZ2VkX21ldHJpY3MkcGNhcGxvdCkKdHQgPC0gcHAoZmlsZT0iaWxsdXN0cmF0b3JfaW5wdXQvbm9ybV90c25lLnBkZiIsIGltYWdlPW1lcmdlZF9tZXRyaWNzJHRzbmVwbG90KQojIyBUaGUgaG9tb2dlbmVvdXMgd3QvbXV0YW50IGFyZSBuaWNlbHkgc2VwYXJhdGVkLCBhbmQgd2hhdCBpcyBtb3JlLCB0aGUgZXhvZ2VuZW91cyBzYW1wbGVzIGFsc28gc3BsaXQgd3QvbXV0YW50LCB0aGF0IG1pZ2h0IHByb3ZlIHRvIGJlIHF1aXRlIHVzZWZ1bC4KCnR0IDwtIHBwKGZpbGU9ImlsbHVzdHJhdG9yX2lucHV0L2xlZ2VuZC5wZGYiLCBpbWFnZT1tZXJnZWRfbWV0cmljcyRsZWdlbmQpCmBgYAoKIyMgUHJpbnQgc29tZSB2YXJpYW5jZSBwYXJ0aXRpb24gaW5mb3JtYXRpb24KClRoaXMgaXMgYW4gaW50ZXJlc3RpbmcgYXNpZGUgd2hpY2ggY2FtZSB1cCBsYXN0IHdlZWsgZm9yIHNvbWUgb3RoZXIgZGF0YS4gIEl0Cm1pZ2h0IGJlIGdvb2QgdG8gaW5jbHVkZSB0aGUgJSB2YXJpYW5jZSBjb3JyZWxhdGVkIHdpdGggJ2NvbmRpdGlvbicgYXMgYSBjb2x1bW4KaW4gdGhlIGFubm90YXRpb24gZGF0YSBmb3IgdGhlIGV4cHJlc3Npb25zZXQuICBUaHVzLCB3aGVuIHdlIGRvIHRoZSBkaWZmZXJlbnRpYWwKZXhwcmVzc2lvbiBhbmFseXNpcyBsYXRlciwgd2UgY2FuIGxvb2sgYW5kIHNlZSBpZiBhICdzaWduaWZpY2FudCcgZ2VuZSBoYXMKdmFyaWFuY2Ugd2hpY2ggaXMgYWN0dWFsbHkgY29ycmVsYXRlZCB3aXRoIGNvbmRpdGlvbi4gIEkgc3RhcnRlZCB0byBpbXBsZW1lbnQKdGhpcyBpZGVhLCBidXQgaXQgaXNuJ3QgZmluaXNoZWQsIHBlcmhhcHMgaXQgc2hvdWxkIGJlIGluY2x1ZGVkIGluIHRoaXM/CgoKYGBge3IgdmFyaWFuY2VfcGFydGl0aW9ucywgZXZhbD1GQUxTRX0KdnAgPC0gdmFycGFydChtZXJnZWRfZXhwdCwgcHJlZGljdG9yPU5VTEwsIGZhY3RvcnM9YygiY29uZGl0aW9uIiwgImJhdGNoIikpCnR0IDwtIHBwKGZpbGU9ImltYWdlcy92YXJpYW5jZV9wYXJ0aXRpb25zLnBuZyIsIGltYWdlPXZwJHBhcnRpdGlvbl9wbG90KQptZXJnZWRfc3ZhIDwtIHNtKG5vcm1hbGl6ZV9leHB0KG1lcmdlZF9leHB0LCB0cmFuc2Zvcm09ImxvZzIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcj1UUlVFLCBiYXRjaD0ic3ZhIiwgbG93X3RvX3plcm89VFJVRSkpCnZwc3ZhIDwtIHZhcnBhcnQobWVyZ2VkX3N2YSwgcHJlZGljdG9yPU5VTEwsIGZhY3RvcnM9YygiY29uZGl0aW9uIiwgImJhdGNoIikpCnR0IDwtIHBwKGZpbGU9ImltYWdlcy92YXJpYW5jZV9wYXJ0aXRpb25zX3N2YS5wbmciLCBpbWFnZT12cHN2YSRwYXJ0aXRpb25fcGxvdCkKYGBgCgojIE5vdyBsb29rIGF0IHRoZSBkYXRhIHdpdGhvdXQgYmF0Y2ggJ3InCgpgYGB7ciBub3J9Cm5vcl9ub3JtIDwtIHNtKG5vcm1hbGl6ZV9leHB0KG1lcmdlZF9ub3IsIHRyYW5zZm9ybT0ibG9nMiIsIGNvbnZlcnQ9ImNwbSIsIG5vcm09InF1YW50IiwgZmlsdGVyPVRSVUUpKQpub3JfcGxvdHMgPC0gc20oZ3JhcGhfbWV0cmljcyhub3Jfbm9ybSkpCm5vcl9iYXRjaG5vcm0gPC0gc20obm9ybWFsaXplX2V4cHQobWVyZ2VkX25vciwgdHJhbnNmb3JtPSJsb2cyIiwgY29udmVydD0iY3BtIiwgbm9ybT0icXVhbnQiLCBmaWx0ZXI9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaD0iZnN2YSIpKQpub3JfYmF0Y2hwbG90cyA8LSBzbShncmFwaF9tZXRyaWNzKG5vcl9iYXRjaG5vcm0pKQpgYGAKCmBgYHtyIG5vcl9zaG93fQojIyBCZWZvcmUgZnN2YQp0dCA8LSBwcChmaWxlPSJpbGx1c3RyYXRvcl9pbnB1dC9ub3JfY29yaGVhdC5wZGYiLCBpbWFnZT1ub3JfcGxvdHMkY29yaGVhdCkKdHQgPC0gcHAoZmlsZT0iaWxsdXN0cmF0b3JfaW5wdXQvbm9yX3BjYS5wZGYiLCBpbWFnZT1ub3JfcGxvdHMkcGNhcGxvdCkKIyMgQWZ0ZXIgZnN2YQp0dCA8LSBwcChmaWxlPSJpbGx1c3RyYXRvcl9pbnB1dC9ub3JiYXRjaF9jb3JoZWF0LnBkZiIsIGltYWdlPW5vcl9iYXRjaHBsb3RzJGNvcmhlYXQpCnR0IDwtIHBwKGZpbGU9ImlsbHVzdHJhdG9yX2lucHV0L25vcmJhdGNoX3BjYS5wZGYiLCBpbWFnZT1ub3JfYmF0Y2hwbG90cyRwY2FwbG90KQpgYGAKCiMgVHJ5IG1hbnkgYmF0Y2ggZXN0aW1hdGlvbiBtZXRob2RzIHRvIHNlZSB3aGF0IGlzIHVwLgoKSSBkbyBub3QgdGhpbmsgYW55IG9mIHRoaXMgaW5mb3JtYXRpb24gaXMgY3VycmVudGx5IGJlaW5nIHVzZWQsIHNvIEkgYW0gZ29pbmcgdG8Kc3RvcCBydW5uaW5nIGl0IGZvciB0aGUgbW9tZW50IGJ1dCBrZWVwIGl0IGhlcmUgaW4gY2FzZSB3ZSBkZWNpZGUgdG8gcmV2aXZlIGl0LgoKYGBge3IgYmF0Y2hfZXhvLCBldmFsPUZBTFNFfQptZXJnZWRfcGNhYmF0Y2ggPC0gc20obm9ybWFsaXplX2V4cHQobWVyZ2VkX2V4cHQsIHRyYW5zZm9ybT0ibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyPVRSVUUsIGJhdGNoPSJwY2EiLCBsb3dfdG9femVybz1UUlVFKSkKbWVyZ2VkX3BjYWJhdGNoX21ldHJpY3MgPC0gc20oZ3JhcGhfbWV0cmljcyhtZXJnZWRfcGNhYmF0Y2gpKQoKbWVyZ2VkX25vcl9wY2FiYXRjaCA8LSBzbShub3JtYWxpemVfZXhwdChtZXJnZWRfbm9yLCB0cmFuc2Zvcm09ImxvZzIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcj1UUlVFLCBiYXRjaD0icGNhIiwgbG93X3RvX3plcm89VFJVRSkpCm1lcmdlZF9ub3JfcGNhYmF0Y2hfbWV0cmljcyA8LSBzbShncmFwaF9tZXRyaWNzKG1lcmdlZF9ub3JfcGNhYmF0Y2gpKQoKbWVyZ2VkX25vc19wY2FiYXRjaCA8LSBzbShub3JtYWxpemVfZXhwdChtZXJnZWRfbm9zLCB0cmFuc2Zvcm09ImxvZzIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcj1UUlVFLCBiYXRjaD0icGNhIiwgbG93X3RvX3plcm89VFJVRSkpCm1lcmdlZF9ub3NfcGNhYmF0Y2hfbWV0cmljcyA8LSBzbShncmFwaF9tZXRyaWNzKG1lcmdlZF9ub3NfcGNhYmF0Y2gpKQoKbWVyZ2VkX3N2YSA8LSBzbShub3JtYWxpemVfZXhwdChtZXJnZWRfZXhwdCwgdHJhbnNmb3JtPSJsb2cyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXI9VFJVRSwgYmF0Y2g9InN2YSIsIGxvd190b196ZXJvPVRSVUUpKQptZXJnZWRfc3ZhX21ldHJpY3MgPC0gc20oZ3JhcGhfbWV0cmljcyhtZXJnZWRfc3ZhKSkKCm1lcmdlZF9ub3Jfc3ZhIDwtIHNtKG5vcm1hbGl6ZV9leHB0KG1lcmdlZF9ub3IsIHRyYW5zZm9ybT0ibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyPVRSVUUsIGJhdGNoPSJzdmEiLCBsb3dfdG9femVybz1UUlVFKSkKbWVyZ2VkX25vcl9zdmFfbWV0cmljcyA8LSBzbShncmFwaF9tZXRyaWNzKG1lcmdlZF9ub3Jfc3ZhKSkKCm1lcmdlZF9ub3Nfc3ZhIDwtIHNtKG5vcm1hbGl6ZV9leHB0KG1lcmdlZF9ub3MsIHRyYW5zZm9ybT0ibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyPVRSVUUsIGJhdGNoPSJzdmEiLCBsb3dfdG9femVybz1UUlVFKSkKbWVyZ2VkX25vc19zdmFfbWV0cmljcyA8LSBzbShncmFwaF9tZXRyaWNzKG1lcmdlZF9ub3Nfc3ZhKSkKCm1lcmdlZF9jb21iYXQgPC0gc20obm9ybWFsaXplX2V4cHQobWVyZ2VkX2V4cHQsIHRyYW5zZm9ybT0ibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyPVRSVUUsIGJhdGNoPSJjb21iYXRfc2NhbGUiLCBsb3dfdG9femVybz1UUlVFKSkKbWVyZ2VkX2NvbWJhdF9tZXRyaWNzIDwtIHNtKGdyYXBoX21ldHJpY3MobWVyZ2VkX2NvbWJhdCkpCgptZXJnZWRfbm9yX2NvbWJhdCA8LSBzbShub3JtYWxpemVfZXhwdChtZXJnZWRfbm9yLCB0cmFuc2Zvcm09ImxvZzIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcj1UUlVFLCBiYXRjaD0iY29tYmF0X3NjYWxlIiwgbG93X3RvX3plcm89VFJVRSkpCm1lcmdlZF9ub3JfY29tYmF0X21ldHJpY3MgPC0gc20oZ3JhcGhfbWV0cmljcyhtZXJnZWRfbm9yX2NvbWJhdCkpCgptZXJnZWRfbm9zX2NvbWJhdCA8LSBzbShub3JtYWxpemVfZXhwdChtZXJnZWRfbm9zLCB0cmFuc2Zvcm09ImxvZzIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcj1UUlVFLCBiYXRjaD0iY29tYmF0X3NjYWxlIiwgbG93X3RvX3plcm89VFJVRSkpCm1lcmdlZF9ub3NfY29tYmF0X21ldHJpY3MgPC0gc20oZ3JhcGhfbWV0cmljcyhtZXJnZWRfbm9zX2NvbWJhdCkpCgptZXJnZWRfbGltbWEgPC0gc20obm9ybWFsaXplX2V4cHQobWVyZ2VkX2V4cHQsIHRyYW5zZm9ybT0ibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyPVRSVUUsIGJhdGNoPSJsaW1tYXJlc2lkIiwgbG93X3RvX3plcm89VFJVRSkpCm1lcmdlZF9saW1tYV9tZXRyaWNzIDwtIHNtKGdyYXBoX21ldHJpY3MobWVyZ2VkX2xpbW1hKSkKCm1lcmdlZF9ub3JfbGltbWEgPC0gc20obm9ybWFsaXplX2V4cHQobWVyZ2VkX25vciwgdHJhbnNmb3JtPSJsb2cyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXI9VFJVRSwgYmF0Y2g9ImxpbW1hcmVzaWQiLCBsb3dfdG9femVybz1UUlVFKSkKbWVyZ2VkX25vcl9saW1tYV9tZXRyaWNzIDwtIHNtKGdyYXBoX21ldHJpY3MobWVyZ2VkX25vcl9saW1tYSkpCgptZXJnZWRfbm9zX2xpbW1hIDwtIHNtKG5vcm1hbGl6ZV9leHB0KG1lcmdlZF9ub3MsIHRyYW5zZm9ybT0ibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyPVRSVUUsIGJhdGNoPSJsaW1tYXJlc2lkIiwgbG93X3RvX3plcm89VFJVRSkpCm1lcmdlZF9ub3NfbGltbWFfbWV0cmljcyA8LSBzbShncmFwaF9tZXRyaWNzKG1lcmdlZF9ub3NfbGltbWEpKQoKbWVyZ2VkX2ZzdmEgPC0gc20obm9ybWFsaXplX2V4cHQobWVyZ2VkX2V4cHQsIHRyYW5zZm9ybT0ibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcj1UUlVFLCBiYXRjaD0iZnN2YSIsIGxvd190b196ZXJvPVRSVUUpKQptZXJnZWRfZnN2YV9tZXRyaWNzIDwtIHNtKGdyYXBoX21ldHJpY3MobWVyZ2VkX2ZzdmEpKQoKbWVyZ2VkX25vcl9mc3ZhIDwtIHNtKG5vcm1hbGl6ZV9leHB0KG1lcmdlZF9ub3IsIHRyYW5zZm9ybT0ibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcj1UUlVFLCBiYXRjaD0iZnN2YSIsIGxvd190b196ZXJvPVRSVUUpKQptZXJnZWRfbm9yX2ZzdmFfbWV0cmljcyA8LSBzbShncmFwaF9tZXRyaWNzKG1lcmdlZF9ub3JfZnN2YSkpCgptZXJnZWRfbm9zX2ZzdmEgPC0gc20obm9ybWFsaXplX2V4cHQobWVyZ2VkX25vcywgdHJhbnNmb3JtPSJsb2cyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyPVRSVUUsIGJhdGNoPSJzc3ZhIiwgbG93X3RvX3plcm89VFJVRSkpCm1lcmdlZF9ub3NfZnN2YV9tZXRyaWNzIDwtIHNtKGdyYXBoX21ldHJpY3MobWVyZ2VkX25vc19mc3ZhKSkKYGBgCgojIyMgVGhlIHJlc3VsdGluZyBwbG90cwoKV2h5IGlzIGlzIHN1ZGRlbmx5IHByaW50aW5nIHN0dWZmIG5vdyBhbmQgbm90IGJlZm9yZT8KCmBgYHtyIGJhdGNoX2VzdGltYXRpb25fcGxvdHN9Cm1lcmdlZF9wY2FiYXRjaF9tZXRyaWNzJHBjYXBsb3QKbWVyZ2VkX25vcl9wY2FiYXRjaF9tZXRyaWNzJHBjYXBsb3QKbWVyZ2VkX25vc19wY2FiYXRjaF9tZXRyaWNzJHBjYXBsb3QKbWVyZ2VkX3N2YV9tZXRyaWNzJHBjYXBsb3QKbWVyZ2VkX25vcl9zdmFfbWV0cmljcyRwY2FwbG90Cm1lcmdlZF9ub3Nfc3ZhX21ldHJpY3MkcGNhcGxvdAptZXJnZWRfY29tYmF0X21ldHJpY3MkcGNhcGxvdAptZXJnZWRfbm9yX2NvbWJhdF9tZXRyaWNzJHBjYXBsb3QKbWVyZ2VkX25vc19jb21iYXRfbWV0cmljcyRwY2FwbG90Cm1lcmdlZF9saW1tYV9tZXRyaWNzJHBjYXBsb3QKbWVyZ2VkX25vcl9saW1tYV9tZXRyaWNzJHBjYXBsb3QKbWVyZ2VkX25vc19saW1tYV9tZXRyaWNzJHBjYXBsb3QKbWVyZ2VkX2ZzdmFfbWV0cmljcyRwY2FwbG90Cm1lcmdlZF9ub3JfZnN2YV9tZXRyaWNzJHBjYXBsb3QKbWVyZ2VkX25vc19mc3ZhX21ldHJpY3MkcGNhcGxvdApgYGAKCiMjIExvb2sgYXQgc3BlY2lmaWMgbm9ybWFsaXphdGlvbnMgdmlhIHBjYS90c25lCgpgYGB7ciBjb21wYXJlX25vcm1zX25vcn0KbWVyZ2VkX25vcl9mc3ZhX21ldHJpY3MkcGNhcGxvdApgYGAKCiMgV3JpdGUgdGhlIGV4cHQKCmBgYHtyIGZzdmFfd3JpdHRlbiwgZXZhbD1GQUxTRX0KIyMgaG1tIEkgd2FzIGdvaW5nIHRvIHNpbGVuY2UgdGhpcyBsaW5lLCBidXQgbG9va2luZyBhdCB0aGUgcmVwb3J0IGl0IHNlZW1zIHRvIGJlIG1pc3Npbmcgc29tZSBwaWN0dXJlcy4KZnVuX25vciA8LSB3cml0ZV9leHB0KG1lcmdlZF9ub3IsIGV4Y2VsPXBhc3RlMCgiZXhjZWwvc2FtcGxlc193cml0dGVuX21lcmdlZF9ub3ItdiIsIHZlciwgIi54bHN4IiksCiAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXI9VFJVRSwgbm9ybT0icmF3IiwgY29udmVydD0iY3BtIiwgYmF0Y2g9ImZzdmEiLCB0cmFuc2Zvcm09ImxvZzIiKQpgYGAKCmBgYHtyIHNhdmVtZSwgaW5jbHVkZT1GQUxTRX0KaWYgKCFpc1RSVUUoZ2V0MCgic2tpcF9sb2FkIikpKSB7CiAgcGFuZGVyOjpwYW5kZXIoc2Vzc2lvbkluZm8oKSkKICBtZXNzYWdlKHBhc3RlMCgiVGhpcyBpcyBocGdsdG9vbHMgY29tbWl0OiAiLCBnZXRfZ2l0X2NvbW1pdCgpKSkKICB0aGlzX3NhdmUgPC0gcGFzdGUwKGdzdWIocGF0dGVybj0iXFwuUm1kIiwgcmVwbGFjZT0iIiwgeD1ybWRfZmlsZSksICItdiIsIHZlciwgIi5yZGEueHoiKQogIHRtcCA8LSBzbShzYXZlbWUoZmlsZW5hbWU9dGhpc19zYXZlKSkKfQpgYGAK