Create some simulated data for us to work with

This is essentially the example used in Fry, B. 2013. Alternative approaches for solving under-determined isotope mixing problems. MEPS.

Here we use the package simmr to explore the two alternatives to aggregating sources in mixing models.

library(simmr, quietly = TRUE)
Linked to JAGS 4.3.2
Loaded modules: basemod,bugs

Attaching package: ‘R2jags’

The following object is masked from ‘package:coda’:

    traceplot
# Set the random seed so we get the same set of 
# random numbers each time we run this example.
set.seed(1)

# specify the sources
# sources <- data.frame(sources=c("A","B","C","D"),
#                         muC=c(-5,-5,5,5),sdC=c(1,1,1,1),
#                         muN=c(-5,5,5,-5),sdN=c(1,1,1,1))

# specify the source names
S_names = c("A","B","C","D")

# specify the source means by binding two vectors 
# together into a matrix by columns.
S_means = cbind(c(-5,-5,5,5), c(-5,5,5,-5))

# specify the source standard deviations
S_sds = cbind(c(1,1,1,1), c(1,1,1,1))

# speficy the consumer data at the origin
# Ten consumers for this example around 0 with small sd of error.
consumers <- cbind(dC = rnorm(n = 10, mean = 0, sd = 0.1),
                   dN = rnorm(n = 10, mean = 0, sd = 0.1) )

# and create the simmr object
# here we have no TDFs or concentration values
simmr_in <- simmr_load(mixtures = consumers,
                       source_names = S_names,
                       source_means = S_means,
                       source_sds = S_sds)

Now we can plot the data to visualise our system and the output,


plot(simmr_in)

Fit the SIMM

We can fit a simmr model using the defaults, and here suppress the output using the results='hide' option in the chunk.

simmr_out = simmr_mcmc(simmr_in)

And we should always check for convergence.

# a summary table of convergence diagnostics
summary(simmr_out,type='diagnostics')

Summary for 1

R-hat values - these values should all be close to 1.

If not, try a longer run of simmr_mcmc.
deviance        A        B        C        D   sd[dC]   sd[dN] 
    1.00     1.01     1.01     1.01     1.01     1.00     1.00 
# plot the posterior predictive power 
posterior_predictive(simmr_out)
Compiling model graph
   Resolving undeclared variables
   Allocating nodes
Graph information:
   Observed stochastic nodes: 20
   Unobserved stochastic nodes: 26
   Total graph size: 149

Initializing model


  |                                                        
  |                                                  |   0%
  |                                                        
  |++++++++++                                        |  20%
  |                                                        
  |++++++++++++++++++++                              |  40%
  |                                                        
  |++++++++++++++++++++++++++++++                    |  60%
  |                                                        
  |++++++++++++++++++++++++++++++++++++++++          |  80%
  |                                                        
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100%

  |                                                        
  |                                                  |   0%
  |                                                        
  |*                                                 |   2%
  |                                                        
  |**                                                |   4%
  |                                                        
  |***                                               |   7%
  |                                                        
  |****                                              |   9%
  |                                                        
  |******                                            |  11%
  |                                                        
  |*******                                           |  13%
  |                                                        
  |********                                          |  16%
  |                                                        
  |*********                                         |  18%
  |                                                        
  |**********                                        |  20%
  |                                                        
  |***********                                       |  22%
  |                                                        
  |************                                      |  24%
  |                                                        
  |*************                                     |  27%
  |                                                        
  |**************                                    |  29%
  |                                                        
  |****************                                  |  31%
  |                                                        
  |*****************                                 |  33%
  |                                                        
  |******************                                |  36%
  |                                                        
  |*******************                               |  38%
  |                                                        
  |********************                              |  40%
  |                                                        
  |*********************                             |  42%
  |                                                        
  |**********************                            |  44%
  |                                                        
  |***********************                           |  47%
  |                                                        
  |************************                          |  49%
  |                                                        
  |**************************                        |  51%
  |                                                        
  |***************************                       |  53%
  |                                                        
  |****************************                      |  56%
  |                                                        
  |*****************************                     |  58%
  |                                                        
  |******************************                    |  60%
  |                                                        
  |*******************************                   |  62%
  |                                                        
  |********************************                  |  64%
  |                                                        
  |*********************************                 |  67%
  |                                                        
  |**********************************                |  69%
  |                                                        
  |************************************              |  71%
  |                                                        
  |*************************************             |  73%
  |                                                        
  |**************************************            |  76%
  |                                                        
  |***************************************           |  78%
  |                                                        
  |****************************************          |  80%
  |                                                        
  |*****************************************         |  82%
  |                                                        
  |******************************************        |  84%
  |                                                        
  |*******************************************       |  87%
  |                                                        
  |********************************************      |  89%
  |                                                        
  |**********************************************    |  91%
  |                                                        
  |***********************************************   |  93%
  |                                                        
  |************************************************  |  96%
  |                                                        
  |************************************************* |  98%
  |                                                        
  |**************************************************| 100%

The results of this toy example are not expected to be overly helpful or meaningful.

summary(simmr_out,type='statistics')

Summary for 1
           mean    sd
deviance 22.575 5.976
A         0.250 0.077
B         0.250 0.077
C         0.253 0.077
D         0.248 0.077
sd[dC]    0.394 0.224
sd[dN]    0.399 0.229
summary(simmr_out,type='quantiles')

Summary for 1
           2.5%    25%    50%    75%  97.5%
deviance 13.563 18.192 21.712 26.090 36.442
A         0.100  0.198  0.250  0.301  0.404
B         0.101  0.197  0.248  0.302  0.403
C         0.103  0.202  0.255  0.305  0.402
D         0.094  0.196  0.247  0.300  0.401
sd[dC]    0.100  0.238  0.351  0.499  0.940
sd[dN]    0.100  0.242  0.353  0.504  0.964

Plot the estimates of the dietary proportions

# Plot the a priori aggregated diet estimatess
plot(simmr_out, type = "density")

Plot the covariance between the estimated dietary proportions in the posterior.


plot(simmr_out, type = "matrix")

A priori aggregation

We combine the sources C and D before we run the model as is sometimes suggested. We do this by taking the mean of the means, and we square the SDs to make them variances, then add them, and then square-root them to turn them back into SDs again. We dont need to change the consumer data in any way.


# specify the source names
S_names_a_priori = c("A","B","CD")

# take the mean of the last two sources C and D
S_means_a_priori = rbind(S_means[1:2,],
                         colMeans(S_means[3:4,]) )

# square the sds for sources C and D to convert to variance,
# sum them and convert back to sd
S_sds_a_priori = rbind( S_sds[1:2,], colSums(S_sds[3:4,]^2) ^ 0.5 )

# and create the new simmr object
# here we have no TDFs or concentration values
simmr_in_a_priori <- simmr_load(mixtures = consumers,
                       source_names = S_names_a_priori,
                       source_means = S_means_a_priori,
                       source_sds = S_sds_a_priori)

Plot this newly combined data.

# plot the raw data for the a priori aggregated example
plot(simmr_in_a_priori)

Run the model on the a priori combined data.

# fit the a priori aggregated models
simmr_out_a_priori = simmr_mcmc(simmr_in_a_priori)
Compiling model graph
   Resolving undeclared variables
   Allocating nodes
Graph information:
   Observed stochastic nodes: 20
   Unobserved stochastic nodes: 5
   Total graph size: 115

Initializing model


  |                                                        
  |                                                  |   0%
  |                                                        
  |++++++++++                                        |  20%
  |                                                        
  |++++++++++++++++++++                              |  40%
  |                                                        
  |++++++++++++++++++++++++++++++                    |  60%
  |                                                        
  |++++++++++++++++++++++++++++++++++++++++          |  80%
  |                                                        
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100%

  |                                                        
  |                                                  |   0%
  |                                                        
  |*                                                 |   2%
  |                                                        
  |**                                                |   4%
  |                                                        
  |***                                               |   7%
  |                                                        
  |****                                              |   9%
  |                                                        
  |******                                            |  11%
  |                                                        
  |*******                                           |  13%
  |                                                        
  |********                                          |  16%
  |                                                        
  |*********                                         |  18%
  |                                                        
  |**********                                        |  20%
  |                                                        
  |***********                                       |  22%
  |                                                        
  |************                                      |  24%
  |                                                        
  |*************                                     |  27%
  |                                                        
  |**************                                    |  29%
  |                                                        
  |****************                                  |  31%
  |                                                        
  |*****************                                 |  33%
  |                                                        
  |******************                                |  36%
  |                                                        
  |*******************                               |  38%
  |                                                        
  |********************                              |  40%
  |                                                        
  |*********************                             |  42%
  |                                                        
  |**********************                            |  44%
  |                                                        
  |***********************                           |  47%
  |                                                        
  |************************                          |  49%
  |                                                        
  |**************************                        |  51%
  |                                                        
  |***************************                       |  53%
  |                                                        
  |****************************                      |  56%
  |                                                        
  |*****************************                     |  58%
  |                                                        
  |******************************                    |  60%
  |                                                        
  |*******************************                   |  62%
  |                                                        
  |********************************                  |  64%
  |                                                        
  |*********************************                 |  67%
  |                                                        
  |**********************************                |  69%
  |                                                        
  |************************************              |  71%
  |                                                        
  |*************************************             |  73%
  |                                                        
  |**************************************            |  76%
  |                                                        
  |***************************************           |  78%
  |                                                        
  |****************************************          |  80%
  |                                                        
  |*****************************************         |  82%
  |                                                        
  |******************************************        |  84%
  |                                                        
  |*******************************************       |  87%
  |                                                        
  |********************************************      |  89%
  |                                                        
  |**********************************************    |  91%
  |                                                        
  |***********************************************   |  93%
  |                                                        
  |************************************************  |  96%
  |                                                        
  |************************************************* |  98%
  |                                                        
  |**************************************************| 100%

And plot

# Plot the a priori aggregated diet estimatess
plot(simmr_out_a_priori, type = "density")

… and now apparently we are very sure about the contributions of all sources to the diet. There is some correlation between A and B since they need to balance each other out in combination to yield a dB value of 0. You would now incorrectly assume that CD represents pretty much a guaranteed 43% of the diet.


plot(simmr_out_a_priori, type = "matrix")

A posteriori aggregation

Far more honest is to fit the model as before, with the sources as we believe them to be a priori and then simply add our prortions together from the posterior distribution. This is made very easy in SIMMR and also MixSIAR with dedicated functions. In fact, MixSIAR also allows easier a priori aggregation by hiding the routine outlined in the preceding section.

# combine sources C and D which are in positions 3 and 4
simmr_out_a_posteriori <- 
  combine_sources(
    simmr_out, 
    to_combine = simmr_out$input$source_names[c(3,4)], 
    new_source_name = "CD")

# Plot the a posteriori aggregated diet estimatess
plot(simmr_out_a_posteriori, type = "density")

NA
NA
plot(simmr_out_a_posteriori, type = "matrix")

This result fits much better with what we would predict: that if the model is still not sure about the contribution of the four sources to the mixture, but that it is pretty sure that on average, 50% of the diet is comprised of both C and D. This concept continues until the model is entirely certain, with no error, that the diet is wholly 100% of A+B+C+D.

One thing to experiment with here is the use of the Jeffrey’s prior of c(0.25, 0.25, 0.25, 0.25) in place of the default vague prior c(1, 1, 1, 1). This is the nub of the criticism levelled at the SIMMs by Brett, M. 2016. Resource polygon geometry predicts Bayesian stable isotope mixing model bias. MEPS.

N.B because simmr no longer uses the Dirichlet prior, this is more difficult and need more thought about how to specify a Jeffries-like or similar specialist prior. The code below won’t work and the prior_control needs to be added.


# simmr_out_specialist_prior = simmr_mcmc(simmr_in,
#                                         prior_control = XYZ)
LS0tCnRpdGxlOiAiU291cmNlIEFnZ3JlZ2F0aW9uIgphdXRob3I6ICJBbmRyZXcgTCBKYWNrc29uIgpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiwgJVknKWAiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAoKIyMgQ3JlYXRlIHNvbWUgc2ltdWxhdGVkIGRhdGEgZm9yIHVzIHRvIHdvcmsgd2l0aApUaGlzIGlzIGVzc2VudGlhbGx5IHRoZSBleGFtcGxlIHVzZWQgaW4gRnJ5LCBCLiAyMDEzLiBBbHRlcm5hdGl2ZSBhcHByb2FjaGVzIGZvciBzb2x2aW5nIHVuZGVyLWRldGVybWluZWQgaXNvdG9wZSBtaXhpbmcgcHJvYmxlbXMuICpNRVBTKi4KCkhlcmUgd2UgdXNlIHRoZSBwYWNrYWdlIGBzaW1tcmAgdG8gZXhwbG9yZSB0aGUgdHdvIGFsdGVybmF0aXZlcyB0byBhZ2dyZWdhdGluZyBzb3VyY2VzIGluIG1peGluZyBtb2RlbHMuIAoKYGBge3Igc2ltdWxhdGUtZGF0YX0KbGlicmFyeShzaW1tciwgcXVpZXRseSA9IFRSVUUpCgojIFNldCB0aGUgcmFuZG9tIHNlZWQgc28gd2UgZ2V0IHRoZSBzYW1lIHNldCBvZiAKIyByYW5kb20gbnVtYmVycyBlYWNoIHRpbWUgd2UgcnVuIHRoaXMgZXhhbXBsZS4Kc2V0LnNlZWQoMSkKCiMgc3BlY2lmeSB0aGUgc291cmNlcwojIHNvdXJjZXMgPC0gZGF0YS5mcmFtZShzb3VyY2VzPWMoIkEiLCJCIiwiQyIsIkQiKSwKIyAgICAgICAgICAgICAgICAgICAgICAgICBtdUM9YygtNSwtNSw1LDUpLHNkQz1jKDEsMSwxLDEpLAojICAgICAgICAgICAgICAgICAgICAgICAgIG11Tj1jKC01LDUsNSwtNSksc2ROPWMoMSwxLDEsMSkpCgojIHNwZWNpZnkgdGhlIHNvdXJjZSBuYW1lcwpTX25hbWVzID0gYygiQSIsIkIiLCJDIiwiRCIpCgojIHNwZWNpZnkgdGhlIHNvdXJjZSBtZWFucyBieSBiaW5kaW5nIHR3byB2ZWN0b3JzIAojIHRvZ2V0aGVyIGludG8gYSBtYXRyaXggYnkgY29sdW1ucy4KU19tZWFucyA9IGNiaW5kKGMoLTUsLTUsNSw1KSwgYygtNSw1LDUsLTUpKQoKIyBzcGVjaWZ5IHRoZSBzb3VyY2Ugc3RhbmRhcmQgZGV2aWF0aW9ucwpTX3NkcyA9IGNiaW5kKGMoMSwxLDEsMSksIGMoMSwxLDEsMSkpCgojIHNwZWNpZnkgdGhlIGNvbnN1bWVyIGRhdGEgYXQgdGhlIG9yaWdpbgojIFRlbiBjb25zdW1lcnMgZm9yIHRoaXMgZXhhbXBsZSBhcm91bmQgMCB3aXRoIHNtYWxsIHNkIG9mIGVycm9yLgpjb25zdW1lcnMgPC0gY2JpbmQoZEMgPSBybm9ybShuID0gMTAsIG1lYW4gPSAwLCBzZCA9IDAuMSksCiAgICAgICAgICAgICAgICAgICBkTiA9IHJub3JtKG4gPSAxMCwgbWVhbiA9IDAsIHNkID0gMC4xKSApCgojIGFuZCBjcmVhdGUgdGhlIHNpbW1yIG9iamVjdAojIGhlcmUgd2UgaGF2ZSBubyBUREZzIG9yIGNvbmNlbnRyYXRpb24gdmFsdWVzCnNpbW1yX2luIDwtIHNpbW1yX2xvYWQobWl4dHVyZXMgPSBjb25zdW1lcnMsCiAgICAgICAgICAgICAgICAgICAgICAgc291cmNlX25hbWVzID0gU19uYW1lcywKICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2VfbWVhbnMgPSBTX21lYW5zLAogICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZV9zZHMgPSBTX3NkcykKCmBgYAoKTm93IHdlIGNhbiBwbG90IHRoZSBkYXRhIHRvIHZpc3VhbGlzZSBvdXIgc3lzdGVtIGFuZCB0aGUgb3V0cHV0LAoKYGBge3IgcGxvdC1pc290b3BlLWRhdGF9CgpwbG90KHNpbW1yX2luKQoKYGBgCgojIyBGaXQgdGhlIFNJTU0KCldlIGNhbiBmaXQgYSBzaW1tciBtb2RlbCB1c2luZyB0aGUgZGVmYXVsdHMsIGFuZCBoZXJlIHN1cHByZXNzIHRoZSBvdXRwdXQgdXNpbmcgdGhlIGByZXN1bHRzPSdoaWRlJ2Agb3B0aW9uIGluIHRoZSBjaHVuay4KCmBgYHtyLCByZXN1bHRzPSdoaWRlJ30Kc2ltbXJfb3V0ID0gc2ltbXJfbWNtYyhzaW1tcl9pbikKYGBgCgpBbmQgd2Ugc2hvdWxkIGFsd2F5cyBjaGVjayBmb3IgY29udmVyZ2VuY2UuCgpgYGB7cn0KIyBhIHN1bW1hcnkgdGFibGUgb2YgY29udmVyZ2VuY2UgZGlhZ25vc3RpY3MKc3VtbWFyeShzaW1tcl9vdXQsdHlwZT0nZGlhZ25vc3RpY3MnKQoKIyBwbG90IHRoZSBwb3N0ZXJpb3IgcHJlZGljdGl2ZSBwb3dlciAKcG9zdGVyaW9yX3ByZWRpY3RpdmUoc2ltbXJfb3V0KQpgYGAKClRoZSByZXN1bHRzIG9mIHRoaXMgdG95IGV4YW1wbGUgYXJlIG5vdCBleHBlY3RlZCB0byBiZSBvdmVybHkgaGVscGZ1bCBvciBtZWFuaW5nZnVsLgoKYGBge3J9CnN1bW1hcnkoc2ltbXJfb3V0LHR5cGU9J3N0YXRpc3RpY3MnKQpzdW1tYXJ5KHNpbW1yX291dCx0eXBlPSdxdWFudGlsZXMnKQpgYGAKClBsb3QgdGhlIGVzdGltYXRlcyBvZiB0aGUgZGlldGFyeSBwcm9wb3J0aW9ucwoKYGBge3J9CiMgUGxvdCB0aGUgYSBwcmlvcmkgYWdncmVnYXRlZCBkaWV0IGVzdGltYXRlc3MKcGxvdChzaW1tcl9vdXQsIHR5cGUgPSAiZGVuc2l0eSIpCmBgYAoKClBsb3QgdGhlIGNvdmFyaWFuY2UgYmV0d2VlbiB0aGUgZXN0aW1hdGVkIGRpZXRhcnkgcHJvcG9ydGlvbnMgaW4gdGhlIHBvc3Rlcmlvci4KCmBgYHtyIHBsb3QtcG9zdGVyaW9yLWNvdn0KCnBsb3Qoc2ltbXJfb3V0LCB0eXBlID0gIm1hdHJpeCIpCgpgYGAKCgoKIyMgX18qQSBwcmlvcmkqX18gYWdncmVnYXRpb24KCldlIGNvbWJpbmUgdGhlIHNvdXJjZXMgQyBhbmQgRCBiZWZvcmUgd2UgcnVuIHRoZSBtb2RlbCBhcyBpcyBzb21ldGltZXMgc3VnZ2VzdGVkLiBXZSBkbyB0aGlzIGJ5IHRha2luZyB0aGUgbWVhbiBvZiB0aGUgbWVhbnMsIGFuZCB3ZSBzcXVhcmUgdGhlIFNEcyB0byBtYWtlIHRoZW0gdmFyaWFuY2VzLCB0aGVuIGFkZCB0aGVtLCBhbmQgdGhlbiBzcXVhcmUtcm9vdCB0aGVtIHRvIHR1cm4gdGhlbSBiYWNrIGludG8gU0RzIGFnYWluLiBXZSBkb250IG5lZWQgdG8gY2hhbmdlIHRoZSBjb25zdW1lciBkYXRhIGluIGFueSB3YXkuCgpgYGB7ciBhLXByaW9yaX0KCiMgc3BlY2lmeSB0aGUgc291cmNlIG5hbWVzClNfbmFtZXNfYV9wcmlvcmkgPSBjKCJBIiwiQiIsIkNEIikKCiMgdGFrZSB0aGUgbWVhbiBvZiB0aGUgbGFzdCB0d28gc291cmNlcyBDIGFuZCBEClNfbWVhbnNfYV9wcmlvcmkgPSByYmluZChTX21lYW5zWzE6MixdLAogICAgICAgICAgICAgICAgICAgICAgICAgY29sTWVhbnMoU19tZWFuc1szOjQsXSkgKQoKIyBzcXVhcmUgdGhlIHNkcyBmb3Igc291cmNlcyBDIGFuZCBEIHRvIGNvbnZlcnQgdG8gdmFyaWFuY2UsCiMgc3VtIHRoZW0gYW5kIGNvbnZlcnQgYmFjayB0byBzZApTX3Nkc19hX3ByaW9yaSA9IHJiaW5kKCBTX3Nkc1sxOjIsXSwgY29sU3VtcyhTX3Nkc1szOjQsXV4yKSBeIDAuNSApCgojIGFuZCBjcmVhdGUgdGhlIG5ldyBzaW1tciBvYmplY3QKIyBoZXJlIHdlIGhhdmUgbm8gVERGcyBvciBjb25jZW50cmF0aW9uIHZhbHVlcwpzaW1tcl9pbl9hX3ByaW9yaSA8LSBzaW1tcl9sb2FkKG1peHR1cmVzID0gY29uc3VtZXJzLAogICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZV9uYW1lcyA9IFNfbmFtZXNfYV9wcmlvcmksCiAgICAgICAgICAgICAgICAgICAgICAgc291cmNlX21lYW5zID0gU19tZWFuc19hX3ByaW9yaSwKICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2Vfc2RzID0gU19zZHNfYV9wcmlvcmkpCgoKCgpgYGAKClBsb3QgdGhpcyBuZXdseSBjb21iaW5lZCBkYXRhLiAKCmBgYHtyfQojIHBsb3QgdGhlIHJhdyBkYXRhIGZvciB0aGUgYSBwcmlvcmkgYWdncmVnYXRlZCBleGFtcGxlCnBsb3Qoc2ltbXJfaW5fYV9wcmlvcmkpCmBgYAoKUnVuIHRoZSBtb2RlbCBvbiB0aGUgYSBwcmlvcmkgY29tYmluZWQgZGF0YS4KCmBgYHtyfQojIGZpdCB0aGUgYSBwcmlvcmkgYWdncmVnYXRlZCBtb2RlbHMKc2ltbXJfb3V0X2FfcHJpb3JpID0gc2ltbXJfbWNtYyhzaW1tcl9pbl9hX3ByaW9yaSkKCmBgYApBbmQgcGxvdAoKYGBge3J9CiMgUGxvdCB0aGUgYSBwcmlvcmkgYWdncmVnYXRlZCBkaWV0IGVzdGltYXRlc3MKcGxvdChzaW1tcl9vdXRfYV9wcmlvcmksIHR5cGUgPSAiZGVuc2l0eSIpCmBgYAoKLi4uIGFuZCBub3cgYXBwYXJlbnRseSB3ZSBhcmUgdmVyeSBzdXJlIGFib3V0IHRoZSBjb250cmlidXRpb25zIG9mIGFsbCBzb3VyY2VzIHRvIHRoZSBkaWV0LiBUaGVyZSBpcyBzb21lIGNvcnJlbGF0aW9uIGJldHdlZW4gQSBhbmQgQiBzaW5jZSB0aGV5IG5lZWQgdG8gYmFsYW5jZSBlYWNoIG90aGVyIG91dCBpbiBjb21iaW5hdGlvbiB0byB5aWVsZCBhIGRCIHZhbHVlIG9mIDAuIFlvdSB3b3VsZCBub3cgaW5jb3JyZWN0bHkgYXNzdW1lIHRoYXQgIENEIHJlcHJlc2VudHMgcHJldHR5IG11Y2ggYSBndWFyYW50ZWVkIDQzJSBvZiB0aGUgZGlldC4KCmBgYHtyIHBsb3QtcG9zdGVyaW9yLWNvdi1wcmlvci1hZ2d9CgpwbG90KHNpbW1yX291dF9hX3ByaW9yaSwgdHlwZSA9ICJtYXRyaXgiKQoKYGBgCgojIyBfXypBIHBvc3RlcmlvcmkqX18gYWdncmVnYXRpb24KRmFyIG1vcmUgaG9uZXN0IGlzIHRvIGZpdCB0aGUgbW9kZWwgYXMgYmVmb3JlLCB3aXRoIHRoZSBzb3VyY2VzIGFzIHdlIGJlbGlldmUgdGhlbSB0byBiZSAqYSBwcmlvcmkqIGFuZCB0aGVuIHNpbXBseSBhZGQgb3VyIHByb3J0aW9ucyB0b2dldGhlciBmcm9tIHRoZSBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9uLiBUaGlzIGlzIG1hZGUgdmVyeSBlYXN5IGluIFNJTU1SIGFuZCBhbHNvIE1peFNJQVIgd2l0aCBkZWRpY2F0ZWQgZnVuY3Rpb25zLiBJbiBmYWN0LCBNaXhTSUFSIGFsc28gYWxsb3dzIGVhc2llciBhIHByaW9yaSBhZ2dyZWdhdGlvbiBieSBoaWRpbmcgdGhlIHJvdXRpbmUgb3V0bGluZWQgaW4gdGhlIHByZWNlZGluZyBzZWN0aW9uLgoKYGBge3IgYS1wb3N0ZXJpb3JpfQojIGNvbWJpbmUgc291cmNlcyBDIGFuZCBEIHdoaWNoIGFyZSBpbiBwb3NpdGlvbnMgMyBhbmQgNApzaW1tcl9vdXRfYV9wb3N0ZXJpb3JpIDwtIAogIGNvbWJpbmVfc291cmNlcyhzaW1tcl9vdXQsIAogICAgICAgICAgICAgICAgICB0b19jb21iaW5lID0gc2ltbXJfb3V0JGlucHV0JHNvdXJjZV9uYW1lc1tjKDMsNCldLCAKICAgICAgICAgICAgICAgICAgbmV3X3NvdXJjZV9uYW1lID0gIkNEIikKCiMgUGxvdCB0aGUgYSBwb3N0ZXJpb3JpIGFnZ3JlZ2F0ZWQgZGlldCBlc3RpbWF0ZXNzCnBsb3Qoc2ltbXJfb3V0X2FfcG9zdGVyaW9yaSwgdHlwZSA9ICJkZW5zaXR5IikKCgpgYGAKCmBgYHtyfQpwbG90KHNpbW1yX291dF9hX3Bvc3RlcmlvcmksIHR5cGUgPSAibWF0cml4IikKYGBgCgpUaGlzIHJlc3VsdCBmaXRzIG11Y2ggYmV0dGVyIHdpdGggd2hhdCB3ZSB3b3VsZCBwcmVkaWN0OiB0aGF0IGlmIHRoZSBtb2RlbCBpcyBzdGlsbCBub3Qgc3VyZSBhYm91dCB0aGUgY29udHJpYnV0aW9uIG9mIHRoZSBmb3VyIHNvdXJjZXMgdG8gdGhlIG1peHR1cmUsIGJ1dCB0aGF0IGl0IGlzIHByZXR0eSBzdXJlIHRoYXQgb24gYXZlcmFnZSwgNTAlIG9mIHRoZSBkaWV0IGlzIGNvbXByaXNlZCBvZiBib3RoIEMgYW5kIEQuIFRoaXMgY29uY2VwdCBjb250aW51ZXMgdW50aWwgdGhlIG1vZGVsIGlzIGVudGlyZWx5IGNlcnRhaW4sIHdpdGggbm8gZXJyb3IsIHRoYXQgdGhlIGRpZXQgaXMgd2hvbGx5IDEwMCUgb2YgQStCK0MrRC4KCk9uZSB0aGluZyB0byBleHBlcmltZW50IHdpdGggaGVyZSBpcyB0aGUgdXNlIG9mIHRoZSBKZWZmcmV5J3MgcHJpb3Igb2YgYGMoMC4yNSwgMC4yNSwgMC4yNSwgMC4yNSlgIGluIHBsYWNlIG9mIHRoZSBkZWZhdWx0IHZhZ3VlIHByaW9yIGBjKDEsIDEsIDEsIDEpYC4gVGhpcyBpcyB0aGUgbnViIG9mIHRoZSBjcml0aWNpc20gbGV2ZWxsZWQgYXQgdGhlIFNJTU1zIGJ5IEJyZXR0LCBNLiAyMDE2LiBSZXNvdXJjZSBwb2x5Z29uIGdlb21ldHJ5IHByZWRpY3RzIEJheWVzaWFuIHN0YWJsZSBpc290b3BlIG1peGluZyBtb2RlbCBiaWFzLiBNRVBTLgoKKk4uQiogYmVjYXVzZSBzaW1tciBubyBsb25nZXIgdXNlcyB0aGUgRGlyaWNobGV0IHByaW9yLCB0aGlzIGlzIG1vcmUgZGlmZmljdWx0IGFuZCBuZWVkIG1vcmUgdGhvdWdodCBhYm91dCBob3cgdG8gc3BlY2lmeSBhIEplZmZyaWVzLWxpa2Ugb3Igc2ltaWxhciBzcGVjaWFsaXN0IHByaW9yLiBUaGUgY29kZSBiZWxvdyB3b24ndCB3b3JrIGFuZCB0aGUgcHJpb3JfY29udHJvbCBuZWVkcyB0byBiZSBhZGRlZC4KCmBgYHtyIGplZmZyaWVzLXByaW9yLCBldmFsdWF0ZSA9IEZBTFNFfQoKIyBzaW1tcl9vdXRfc3BlY2lhbGlzdF9wcmlvciA9IHNpbW1yX21jbWMoc2ltbXJfaW4sCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW9yX2NvbnRyb2wgPSBYWVopCgpgYGAKCg==