1 M. musculus

This will be a very minimal analysis until we get some replicates.

1.2 Metadata

I am going to write a quick sample sheet in the current working directory called ‘all_samples.xlsx’ and put the names of the count tables in it.

1.3 Create expressionsets

Here I combine the metadata, count data, and annotations.

It is worth noting that the gene IDs from htseq-count probably do not match the annotations retrieved because they are likely exon-based rather than gene based. This is not really a problem, but don’t forget it!

## Reading the sample metadata.
## The sample definitions comprises: 8 rows(samples) and 8 columns(metadata fields).
## Reading count tables.
## Using the transcript to gene mapping.
## Reading salmon data with tximport.
## Finished reading count tables.
## Matched 6764 annotations and counts.
## Bringing together the count matrix and gene information.
## The mapped IDs are not the rownames of your gene information, changing them now.
## Some annotations were lost in merging, setting them to 'undefined'.
## The final expressionset has 6764 rows and 8 columns.
## Reading the sample metadata.
## The sample definitions comprises: 8 rows(samples) and 8 columns(metadata fields).
## Reading count tables.
## Reading salmon data with tximport.
## Finished reading count tables.
## Matched 6897 annotations and counts.
## Bringing together the count matrix and gene information.
## Some annotations were lost in merging, setting them to 'undefined'.
## The final expressionset has 56886 rows and 8 columns.

1.4 Query expressionsets

In this block I will calculate all the diagnostic plots, but not show them. I will show them next with a little annotation.

I will leave the output for the first of each invocation and silence it for the second.

## Graphing number of non-zero genes with respect to CPM by library.
## Graphing library sizes.
## Graphing a boxplot.
## 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 21398 zero count features.
## 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.
## 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 21398 zero count features.
## Plotting a CV plot.
## Naively calculating coefficient of variation/dispersion with respect to condition.
## Finished calculating dispersion estimates.
## Plotting the representation of the top-n genes.
## Plotting the expression of the top-n PC loaded genes.
## Printing a color to condition legend.
## This function will replace the expt$expressionset slot with:
## log2(cpm(quant(cbcb(data))))
## It will save copies of each step along the way
##  in expt$normalized with the corresponding libsizes. Keep libsizes in mind
##  when invoking limma.  The appropriate libsize is 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
## 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: cbcb
## Removing 2794 low-count genes (3970 remaining).
## Step 2: normalizing the data with quant.
## Step 3: converting the data with cpm.
## Step 4: transforming the data with log2.
## transform_counts: Found 1105 values equal to 0, adding 1 to the matrix.
## Step 5: not doing batch correction.

1.6 Do a simple DE

The only interesting DE I see in this is to compare the retinas to the dlgns. I can treat them as replicates and compare.

## This function will replace the expt$expressionset slot with:
## log2(cpm(quant(cbcb(data))))
## It will save copies of each step along the way
##  in expt$normalized with the corresponding libsizes. Keep libsizes in mind
##  when invoking limma.  The appropriate libsize is 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
## 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: cbcb
## Removing 2794 low-count genes (3970 remaining).
## Step 2: normalizing the data with quant.
## Step 3: converting the data with cpm.
## Step 4: transforming the data with log2.
## transform_counts: Found 1105 values equal to 0, adding 1 to the matrix.
## Step 5: not doing batch correction.
## This function will replace the expt$expressionset slot with:
## log2(cpm(quant(cbcb(data))))
## It will save copies of each step along the way
##  in expt$normalized with the corresponding libsizes. Keep libsizes in mind
##  when invoking limma.  The appropriate libsize is 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
## 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: cbcb
## Removing 2794 low-count genes (3970 remaining).
## Step 2: normalizing the data with quant.
## Step 3: converting the data with cpm.
## Step 4: transforming the data with log2.
## transform_counts: Found 1105 values equal to 0, adding 1 to the matrix.
## Step 5: not doing batch correction.
## Plotting a PCA before surrogates/batch inclusion.
## Not putting labels on the plot.
## Assuming no batch in model for testing pca.
## Not putting labels on the plot.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

1.8 Contrasts of interest

Now that we have the 5 available ‘conditions’, perform the subtractions to query the data.

## Writing a legend of columns.
## Printing a pca plot before/after surrogates/batch estimation.
## Working on table 1/3: retina_vs_dlgn
## Working on table 2/3: scn_vs_dlgn
## Working on table 3/3: scn_vs_retina
## Adding venn plots for retina_vs_dlgn.

## Limma expression coefficients for retina_vs_dlgn; R^2: 0.934; equation: y = 0.967x + 0.0347
## Warning: Removed 1 rows containing missing values (geom_vline).
## Warning: Removed 1 rows containing missing values (geom_hline).
## Warning: Removed 1 rows containing missing values (geom_vline).
## Warning: Removed 1 rows containing missing values (geom_hline).
## Deseq expression coefficients for retina_vs_dlgn; R^2: 0.822; equation: y = 0.955x + 0.0956
## Edger expression coefficients for retina_vs_dlgn; R^2: 0.917; equation: y = 0.977x + 0.0265
## Warning: Removed 1 rows containing missing values (geom_hline).

## Warning: Removed 1 rows containing missing values (geom_hline).
## Adding venn plots for scn_vs_dlgn.

## Limma expression coefficients for scn_vs_dlgn; R^2: 0.934; equation: y = 0.967x + 0.0347
## Warning: Removed 1 rows containing missing values (geom_vline).

## Warning: Removed 1 rows containing missing values (geom_hline).
## Warning: Removed 1 rows containing missing values (geom_vline).
## Warning: Removed 1 rows containing missing values (geom_hline).
## Deseq expression coefficients for scn_vs_dlgn; R^2: 0.822; equation: y = 0.955x + 0.0956
## Edger expression coefficients for scn_vs_dlgn; R^2: 0.917; equation: y = 0.977x + 0.0265
## Warning: Removed 1 rows containing missing values (geom_hline).

## Warning: Removed 1 rows containing missing values (geom_hline).
## Adding venn plots for scn_vs_retina.

## Limma expression coefficients for scn_vs_retina; R^2: 0.934; equation: y = 0.967x + 0.0347
## Warning: Removed 1 rows containing missing values (geom_vline).

## Warning: Removed 1 rows containing missing values (geom_hline).
## Warning: Removed 1 rows containing missing values (geom_vline).
## Warning: Removed 1 rows containing missing values (geom_hline).
## Deseq expression coefficients for scn_vs_retina; R^2: 0.822; equation: y = 0.955x + 0.0956
## Edger expression coefficients for scn_vs_retina; R^2: 0.917; equation: y = 0.977x + 0.0265
## Warning: Removed 1 rows containing missing values (geom_hline).

## Warning: Removed 1 rows containing missing values (geom_hline).
## Writing summary information, compare_plot is: TRUE.
## Performing save of excel/20200109mm_tables.xlsx.

LS0tCnRpdGxlOiAiTS4gbXVzY3VsdXMgMyBjZWxsIHR5cGVzLCAxIHRpbWVwb2ludCwgMyBnZW5vdHlwZXMsIGFuZCAxIHJlcGxpY2F0ZS4iCmF1dGhvcjogImF0YiBhYmVsZXdAZ21haWwuY29tIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgZmlnX2hlaWdodDogNwogICAgZmlnX3dpZHRoOiA3CiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICBrZWVwX21kOiBmYWxzZQogICAgbW9kZTogc2VsZmNvbnRhaW5lZAogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQogICAgdGhlbWU6IHJlYWRhYmxlCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiBmYWxzZQogICAgICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQogIHJtZGZvcm1hdHM6OnJlYWR0aGVkb3duOgogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBkZl9wcmludDogcGFnZWQKICAgIGZpZ19jYXB0aW9uOiB0cnVlCiAgICBmaWdfaGVpZ2h0OiA3CiAgICBmaWdfd2lkdGg6IDcKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIHdpZHRoOiAzMDAKICAgIGtlZXBfbWQ6IGZhbHNlCiAgICBtb2RlOiBzZWxmY29udGFpbmVkCiAgICB0b2NfZmxvYXQ6IHRydWUKICBCaW9jU3R5bGU6Omh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGZpZ19jYXB0aW9uOiB0cnVlCiAgICBmaWdfaGVpZ2h0OiA3CiAgICBmaWdfd2lkdGg6IDcKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIGtlZXBfbWQ6IGZhbHNlCiAgICBtb2RlOiBzZWxmY29udGFpbmVkCiAgICB0b2NfZmxvYXQ6IHRydWUKLS0tCgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgpib2R5LCB0ZCB7CiAgZm9udC1zaXplOiAxNnB4Owp9CmNvZGUucnsKICBmb250LXNpemU6IDE2cHg7Cn0KcHJlIHsKIGZvbnQtc2l6ZTogMTZweAp9Cjwvc3R5bGU+CgpgYGB7ciBvcHRpb25zLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KCJocGdsdG9vbHMiKQp0dCA8LSBkZXZ0b29sczo6bG9hZF9hbGwoIi9kYXRhL2hwZ2x0b29scyIpCmtuaXRyOjpvcHRzX2tuaXQkc2V0KHdpZHRoPTEyMCwKICAgICAgICAgICAgICAgICAgICAgcHJvZ3Jlc3M9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgdmVyYm9zZT1UUlVFLAogICAgICAgICAgICAgICAgICAgICBlY2hvPVRSVUUpCmtuaXRyOjpvcHRzX2NodW5rJHNldChlcnJvcj1UUlVFLAogICAgICAgICAgICAgICAgICAgICAgZHBpPTk2KQpvbGRfb3B0aW9ucyA8LSBvcHRpb25zKGRpZ2l0cz00LAogICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAga25pdHIuZHVwbGljYXRlLmxhYmVsPSJhbGxvdyIpCmdncGxvdDI6OnRoZW1lX3NldChnZ3Bsb3QyOjp0aGVtZV9idyhiYXNlX3NpemU9MTApKQpydW5kYXRlIDwtIGZvcm1hdChTeXMuRGF0ZSgpLCBmb3JtYXQ9IiVZJW0lZCIpCnByZXZpb3VzX2ZpbGUgPC0gInVuZGVmaW5lZC5SbWQiCnZlciA8LSAiMjAxOTEyMTYiCgojI3RtcCA8LSBzbShsb2FkbWUoZmlsZW5hbWU9cGFzdGUwKGdzdWIocGF0dGVybj0iXFwuUm1kIiwgcmVwbGFjZT0iIiwgeD1wcmV2aW91c19maWxlKSwgIi12IiwgdmVyLCAiLnJkYS54eiIpKSkKcm1kX2ZpbGUgPC0gImluZGV4LlJtZCIKYGBgCgojIE0uIG11c2N1bHVzCgpUaGlzIHdpbGwgYmUgYSB2ZXJ5IG1pbmltYWwgYW5hbHlzaXMgdW50aWwgd2UgZ2V0IHNvbWUgcmVwbGljYXRlcy4KCiMjIEFubm90YXRpb25zCgpJIGFtIHVzaW5nIG1tMzhfOTUuCgpgYGB7ciBhbm5vdGF0aW9uc30KIyMgTXkgbG9hZF9iaW9tYXJ0X2Fubm90YXRpb25zKCkgZnVuY3Rpb24gZGVmYXVsdHMgdG8gaHVtYW4sIHNvIHRoYXQgd2lsbCBiZSBxdWljay4KbW1fYW5ub3QgPC0gbG9hZF9iaW9tYXJ0X2Fubm90YXRpb25zKHNwZWNpZXM9Im1tdXNjdWx1cyIpCm1tX2Fubm90IDwtIG1tX2Fubm90W1siYW5ub3RhdGlvbiJdXQptbV9hbm5vdFtbInR4aWQiXV0gPC0gcGFzdGUwKG1tX2Fubm90W1siZW5zZW1ibF90cmFuc2NyaXB0X2lkIl1dLCAiLiIsIG1tX2Fubm90W1sidmVyc2lvbiJdXSkKcm93bmFtZXMobW1fYW5ub3QpIDwtIG1ha2UubmFtZXMobW1fYW5ub3RbWyJlbnNlbWJsX2dlbmVfaWQiXV0sIHVuaXF1ZT1UUlVFKQoKdHhfZ2VuZV9tYXAgPC0gbW1fYW5ub3RbLCBjKCJ0eGlkIiwgImVuc2VtYmxfZ2VuZV9pZCIpXQpgYGAKClNvLCBJIG5vdyBoYXZlIDIgZGF0YSBmcmFtZXMgb2YgcGFyYXNpdGUgYW5ub3RhdGlvbnMgYW5kIDEgaHVtYW4uCgojIyBNZXRhZGF0YQoKSSBhbSBnb2luZyB0byB3cml0ZSBhIHF1aWNrIHNhbXBsZSBzaGVldCBpbiB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSBjYWxsZWQKJ2FsbF9zYW1wbGVzLnhsc3gnIGFuZCBwdXQgdGhlIG5hbWVzIG9mIHRoZSBjb3VudCB0YWJsZXMgaW4gaXQuCgojIyBDcmVhdGUgZXhwcmVzc2lvbnNldHMKCkhlcmUgSSBjb21iaW5lIHRoZSBtZXRhZGF0YSwgY291bnQgZGF0YSwgYW5kIGFubm90YXRpb25zLgoKSXQgaXMgd29ydGggbm90aW5nIHRoYXQgdGhlIGdlbmUgSURzIGZyb20gaHRzZXEtY291bnQgcHJvYmFibHkgZG8gbm90IG1hdGNoIHRoZQphbm5vdGF0aW9ucyByZXRyaWV2ZWQgYmVjYXVzZSB0aGV5IGFyZSBsaWtlbHkgZXhvbi1iYXNlZCByYXRoZXIgdGhhbiBnZW5lCmJhc2VkLiAgVGhpcyBpcyBub3QgcmVhbGx5IGEgcHJvYmxlbSwgYnV0IGRvbid0IGZvcmdldCBpdCEKCmBgYHtyIGV4cHR9Cm1tMzhfc2FsbW9uIDwtIGNyZWF0ZV9leHB0KCJzYW1wbGVfc2hlZXRzL2FsbF9zYW1wbGVzLnhsc3giLCB0eF9nZW5lX21hcD10eF9nZW5lX21hcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuZV9pbmZvPW1tX2Fubm90LCBmaWxlX2NvbHVtbj0ic2FsbW9uZmlsZSIpCgptbXR4X2Fubm90IDwtIG1tX2Fubm90CnJvd25hbWVzKG1tdHhfYW5ub3QpIDwtIG1tX2Fubm90W1sidHhpZCJdXQptbTM4X3NhbHR4IDwtIGNyZWF0ZV9leHB0KCJzYW1wbGVfc2hlZXRzL2FsbF9zYW1wbGVzLnhsc3giLAogICAgICAgICAgICAgICAgICAgICAgIGdlbmVfaW5mbz1tbXR4X2Fubm90LCBmaWxlX2NvbHVtbj0ic2FsbW9uZmlsZSIpCgpoaXNhdF9hbm5vdCA8LSBtbV9hbm5vdAojI21tMzhfaGlzYXQgPC0gY3JlYXRlX2V4cHQoInNhbXBsZV9zaGVldHMvYWxsX3NhbXBsZXMueGxzeCIsCiMjICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5lX2luZm89aGlzYXRfYW5ub3QpCmBgYAoKIyMgUXVlcnkgZXhwcmVzc2lvbnNldHMKCkluIHRoaXMgYmxvY2sgSSB3aWxsIGNhbGN1bGF0ZSBhbGwgdGhlIGRpYWdub3N0aWMgcGxvdHMsIGJ1dCBub3Qgc2hvdyB0aGVtLiAgSQp3aWxsIHNob3cgdGhlbSBuZXh0IHdpdGggYSBsaXR0bGUgYW5ub3RhdGlvbi4KCkkgd2lsbCBsZWF2ZSB0aGUgb3V0cHV0IGZvciB0aGUgZmlyc3Qgb2YgZWFjaCBpbnZvY2F0aW9uIGFuZCBzaWxlbmNlIGl0IGZvciB0aGUgc2Vjb25kLgoKYGBge3IgcXVlcnksIGZpZy5zaG93PSJoaWRlIn0KbW0zOF9wbG90cyA8LSBncmFwaF9tZXRyaWNzKG1tMzhfc2FsbW9uKQoKbW0zOF9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KG1tMzhfc2FsbW9uLCBub3JtPSJxdWFudCIsIGNvbnZlcnQ9ImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm09ImxvZzIiLCBmaWx0ZXI9VFJVRSkKCm1tMzhuX3Bsb3RzIDwtIHNtKGdyYXBoX21ldHJpY3MobW0zOF9ub3JtKSkKYGBgCgojIyBTaG93IHNvbWUgcGxvdHMKCmBgYHtyIHNob3dfcGxvdHN9Cm1tMzhfcGxvdHMkbGVnZW5kCm1tMzhfcGxvdHMkbGlic2l6ZQptbTM4X3Bsb3RzJG5vbnplcm8KbW0zOG5fcGxvdHMkZGVuc2l0eQptbTM4bl9wbG90cyRwY19wbG90CmBgYAoKIyMgRG8gYSBzaW1wbGUgREUKClRoZSBvbmx5IGludGVyZXN0aW5nIERFIEkgc2VlIGluIHRoaXMgaXMgdG8gY29tcGFyZSB0aGUgcmV0aW5hcyB0byB0aGUgZGxnbnMuCkkgY2FuIHRyZWF0IHRoZW0gYXMgcmVwbGljYXRlcyBhbmQgY29tcGFyZS4KCmBgYHtyIGRlLCBmaWcuc2hvdz0iaGlkZSJ9Cm1tIDwtIHNldF9leHB0X2NvbmRpdGlvbnMobW0zOF9zYWxtb24sIGZhY3Q9ImNlbGx0eXBlIikKbW1fbm9ybSA8LSBub3JtYWxpemVfZXhwdChtbSwgbm9ybT0icXVhbnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnQ9ImNwbSIsIHRyYW5zZm9ybT0ibG9nMiIsIGZpbHRlcj1UUlVFKQpwbG90X3BjYShtbV9ub3JtKSRwbG90CgptbV9kZSA8LSBhbGxfcGFpcndpc2UobW0sIG1vZGVsX2JhdGNoPUZBTFNFKQpgYGAKCiMjIFNldCB1cCBmb3IgaW5pdGlhbCBhbmFseXNpcwoKU2luY2Ugd2UgZG9uJ3QgaGF2ZSByZXBsaWNhdGVzLCBJIGFtIGdvaW5nIHRvIGRvIHNpbXBsZSBzdWJ0cmFjdGlvbnMuICBUaGUgbW9zdCBpbXBvcnRhbnQgY2F2ZWF0CmlzIHRoYXQgSSBtdXN0IHN1YnRyYWN0IGVhY2ggYmFzZWxpbmUgZnJvbSBpdHMgaHQva28gc2FtcGxlcyBiZWZvcmUgY29uc2lkZXJpbmcgdGhlIGNvbnRyYXN0cwpvZiBpbnRlcmVzdC4KCmBgYHtyIGRlX3NldHVwfQpkbGduYmFzZWxpbmUgPC0gImlwcmdjXzAxIgpzY25iYXNlbGluZSA8LSAiaXByZ2NfMDMiCnJldGJhc2VsaW5lIDwtICJpcHJnY18wMiIKCmRsZ25rbyA8LSAiaXByZ2NfMDYiCmRsZ25odCA8LSAiaXByZ2NfMDQiCnNjbmh0IDwtIE5VTEwgICMjIERvZXMgbm90IHlldCBleGlzdC4Kc2Nua28gPC0gImlwcmdjXzA4IgpyZXRrbyA8LSAiaXByZ2NfMDciCnJldGh0IDwtICJpcHJnY18wNSIKCmhldHJldCA8LSBleHBycyhtbTM4X25vcm0pWywgcmV0aHRdIC0gZXhwcnMobW0zOF9ub3JtKVssIHJldGJhc2VsaW5lXQprb3JldCA8LSBleHBycyhtbTM4X25vcm0pWywgcmV0a29dIC0gZXhwcnMobW0zOF9ub3JtKVssIHJldGJhc2VsaW5lXQprb3NjbiA8LSBleHBycyhtbTM4X25vcm0pWywgc2Nua29dIC0gZXhwcnMobW0zOF9ub3JtKVssIHNjbmJhc2VsaW5lXQpoZXRkbGduIDwtIGV4cHJzKG1tMzhfbm9ybSlbLCBkbGduaHRdIC0gZXhwcnMobW0zOF9ub3JtKVssIGRsZ25iYXNlbGluZV0Ka29kbGduIDwtIGV4cHJzKG1tMzhfbm9ybSlbLCBkbGdua29dIC0gZXhwcnMobW0zOF9ub3JtKVssIGRsZ25iYXNlbGluZV0KYGBgCgojIyBDb250cmFzdHMgb2YgaW50ZXJlc3QKCk5vdyB0aGF0IHdlIGhhdmUgdGhlIDUgYXZhaWxhYmxlICdjb25kaXRpb25zJywgcGVyZm9ybSB0aGUgc3VidHJhY3Rpb25zIHRvIHF1ZXJ5IHRoZSBkYXRhLgoKYGBge3Igc3VidHJhY3RfaW50ZXJlc3Rpbmd9CiMjIGhldCB2cyBoZXQKaGV0cmV0X3ZzX2hldGRsZ24gPC0gaGV0cmV0IC0gaGV0ZGxnbgoKIyMga28gdnMga28Ka29yZXRfdnNfa29kbGduIDwtIGtvcmV0IC0ga29zY24Ka29yZXRfdnNfa29zY24gPC0ga29yZXQgLSBrb3Njbgprb2RsZ25fdnNfa29zY24gPC0ga29kbGduIC0ga29zY24KCiMjIGtvIHZzIGhldAprb3JldF92c19oZXRyZXQgPC0ga29yZXQgLSBoZXRyZXQKa29kbGduX3ZzX2hldGRsZ24gPC0ga29kbGduIC0gaGV0ZGxnbgprb3Njbl92c19oZXRkbGduIDwtIGtvc2NuIC0gaGV0ZGxnbgoKIyMgcmF0aW8gb2YgcmF0aW9zCnJldGhldF92c19kbGduaGV0X292ZXJfcmV0a29fdnNfZGxnbmtvIDwtIChoZXRyZXQgLSBoZXRkbGduKSAtIChrb3JldCAtIGtvZGxnbikKCnBhaXJfbXRyeCA8LSBjYmluZCgKICAjIyBCYXNlbGluZSBzdWJ0cmFjdGlvbnMKICBoZXRyZXQsIGtvcmV0LCBrb3NjbiwgaGV0ZGxnbiwga29kbGduLAogICMjIGhldF92c19oZXQsIG9mIHdoaWNoIHRoZXJlIGlzIG9ubHkgMSBiZWNhdXNlIHdlIGRvIG5vdCBoYXZlIGhldHNjbgogIGhldHJldF92c19oZXRkbGduLAogICMjIGtvX3ZzX2tvLCBvZiB3aGljaCB3ZSBoYXZlIDMKICBrb3JldF92c19rb2RsZ24sIGtvcmV0X3ZzX2tvc2NuLCBrb2RsZ25fdnNfa29zY24sCiAgIyMga29fdnNfaGV0LCAzIGluY2x1ZGluZyBvbmUgZ2V0dGluZyBhcm91bmQgbWlzc2luZyBoZXRzY24KICBrb3JldF92c19oZXRyZXQsIGtvZGxnbl92c19oZXRkbGduLCBrb3Njbl92c19oZXRkbGduLAogICMjIHJhdGlvIG9mIHJhdGlvcwogIHJldGhldF92c19kbGduaGV0X292ZXJfcmV0a29fdnNfZGxnbmtvKQoKbW1fdGFibGVzIDwtIGNvbWJpbmVfZGVfdGFibGVzKG1tX2RlLCBleHRyYV9hbm5vdD1wYWlyX210cngsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGNlbD1nbHVlOjpnbHVlKCJleGNlbC97cnVuZGF0ZX1tbV90YWJsZXMueGxzeCIpKQpgYGAKCiMgU29tZSBwaWN0dXJlcwoKQXMgSSB1bmRlcnN0YW5kIGl0LCB0aGVyZSBpcyBzb21lIGludGVyZXN0IGluIGFuIG9udG9sb2d5IHNlYXJjaCB1c2luZyB0aGUgcmF0aW8gb2YgcmF0aW9zLgoKYGBge3Igb3RoZXJfY29udHJhc3RzfQpyb3IgPC0gcmV0aGV0X3ZzX2RsZ25oZXRfb3Zlcl9yZXRrb192c19kbGdua28KdXBfaWR4IDwtIHJvciA+PSAxCmRvd25faWR4IDwtIHJvciA8PSAtMQpyb3JfdXAgPC0gcm9yW3VwX2lkeF0KbGVuZ3RoKHJvcl91cCkKcm9yX2Rvd24gPC0gcm9yW2Rvd25faWR4XQpsZW5ndGgocm9yX2Rvd24pCgpyb3JfZ3Byb2ZpbGVyIDwtIHNpbXBsZV9ncHJvZmlsZXIoc2lnX2dlbmVzPXJvcl91cCwgc3BlY2llcz0ibW11c2N1bHVzIikKcm9yX2dwcm9maWxlciRwdmFsdWVfcGxvdHMkbWZwX3Bsb3Rfb3Zlcgpyb3JfZ3Byb2ZpbGVyJHB2YWx1ZV9wbG90cyRicHBfcGxvdF9vdmVyCnJvcl9ncHJvZmlsZXIkcHZhbHVlX3Bsb3RzJGNjcF9wbG90X292ZXIKcm9yX2dwcm9maWxlciRwdmFsdWVfcGxvdHMkdGZfcGxvdF9vdmVyCnJvcl9ncHJvZmlsZXIkcHZhbHVlX3Bsb3RzJGhwX3Bsb3Rfb3ZlcmAKYGAKCmBgYHtyIHNhdmVtZSwgZXZhbD1GQUxTRX0KcGFuZGVyOjpwYW5kZXIoc2Vzc2lvbkluZm8oKSkKbWVzc2FnZShwYXN0ZTAoIlRoaXMgaXMgaHBnbHRvb2xzIGNvbW1pdDogIiwgZ2V0X2dpdF9jb21taXQoKSkpCnRoaXNfc2F2ZSA8LSBwYXN0ZTAoZ3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSIiLCB4PXJtZF9maWxlKSwgIi12IiwgdmVyLCAiLnJkYS54eiIpCm1lc3NhZ2UocGFzdGUwKCJTYXZpbmcgdG8gIiwgdGhpc19zYXZlKSkKdG1wIDwtIHNtKHNhdmVtZShmaWxlbmFtZT10aGlzX3NhdmUpKQpgYGAKCmBgYHtyIGxvYWRtZSwgZXZhbD1GQUxTRX0KbG9hZG1lKGZpbGVuYW1lPXRoaXNfc2F2ZSkKYGBgCg==