The Analysis

The following analysis pulled geochemistry data from the 2015 Reference Larvae data set, and tested the effects of larval source, and co-variance matrix prior, on the ability of the infinite mixture model (IMM) to correctly assign larvae to sources. During analysis, each larvae was removed from the overall data set, and the remaining larvae used as baseline data to train the IMM. The individual larvae removed from the data set was then assigned to a source based on the IMM, allowing for 7 possible extra, and untrained, source assignments, using each of four different co-variance matrix priors:

For each co-variance matrix prior for each larvae, the IMM was run for an initial 1000 adaptation and 2000 burn-in iterations. The posterior distribution of source assignments for a final 3000 iterations were retained and used for further analysis.

The Data Set

Data were \(Log(x+1)\) transformed, and centered (by elemental mean) and scaled (by elemental standard deviation) prior to analysis. Together, these transformations were meant to normalize the elemental data, and then standardize the center and variance so that unknown sources could be easily modeled in the IMM. Principal Component Analysis suggested a lot of overlap in the multivariate geochemical signals among sources along the first 2 principle components (accounting for 36 and 22 percent of total variation respectively). Of all elements, Mg accounted for the most variation among individual larvae, while La accounted for the least.

Importance of components:
                          PC1    PC2    PC3     PC4     PC5     PC6     PC7     PC8
Standard deviation     0.8440 0.6633 0.4559 0.43804 0.38877 0.34044 0.32125 0.20066
Proportion of Variance 0.3629 0.2242 0.1059 0.09778 0.07702 0.05906 0.05259 0.02052
Cumulative Proportion  0.3629 0.5871 0.6930 0.79082 0.86784 0.92689 0.97948 1.00000

Results by Individual

Below are the posterior distribution results of the IMM assignment for each individual larvae (color) to each potential source (x-axis; numbers represent possible extra sources). Results are separated by the actual larval source (panel rows) and the co-variance matrix prior used in the IMM (panel columns).

We can see that generally, individual sources assign most frequently to one source, which is usually the correct one. Sources like CHR, FBE and GB are more multi-modal and diffuse in their assignments though.

Results by Source

To summarize assignment results by site, we take the mode source assignment for each individual and use that as the IMM predicted source assignment. Then, for each co-variance matrix prior (panels), we plot the percent of individuals from each source (Actual Source) assigned to each possible source by the IMM (Predicted Source).

Just as before, when we looked at data on an individual level, we generally see IMM assignment to correct sources, but CHR is mostly confused with PHB and FBW, and GB and FBW are confused with each other. Maximum percentage correctly assigned was only 62% for FBE though.

Effects of Source and Coviariance Matrix Prior on Correct Assignment

To understand what is driving misclassification by the IMM, we test the effects of Actual Source, Co-variance Prior, and their interaction with a GLM (family=binomial, link=log), using individual nested within actual source as a random effect.

Analysis of Deviance Table (Type III Wald chisquare tests)

Response: Correct
                          Chisq Df Pr(>Chisq)    
(Intercept)             12.9177  1  0.0003255 ***
Actual_Source            7.9274  4  0.0942732 .  
Cov_Prior                4.9148  3  0.1781406    
Actual_Source:Cov_Prior 11.7227 12  0.4681974    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

We find that a larva’s actual source has the greatest, and only marginally insignificant, effect on correct classification.

We can use the regression coefficient summaries for a more in-depth look.

Generalized linear mixed model fit by maximum likelihood (Laplace Approximation) ['glmerMod']
 Family: binomial  ( logit )
Formula: Correct ~ Actual_Source * Cov_Prior + (1 | Actual_Source/Individual_Code)
   Data: leave.one.out.results.byind.assignment.table
Control: glmerControl(optimizer = "bobyqa", optCtrl = list(maxfun = 20000))

     AIC      BIC   logLik deviance df.resid 
   621.0    722.4   -288.5    577.0      722 

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-3.2871 -0.1157 -0.0579  0.1652  2.4500 

Random effects:
 Groups                        Name        Variance  Std.Dev. 
 Individual_Code:Actual_Source (Intercept) 4.722e+01 6.872e+00
 Actual_Source                 (Intercept) 1.018e-15 3.191e-08
Number of obs: 744, groups:  Individual_Code:Actual_Source, 186; Actual_Source, 5

Fixed effects:
                                               Estimate Std. Error z value Pr(>|z|)    
(Intercept)                                     -6.5205     1.8142  -3.594 0.000325 ***
Actual_SourceFBE                                 6.3633     2.9343   2.169 0.030117 *  
Actual_SourceFBW                                 4.9025     2.4853   1.973 0.048542 *  
Actual_SourceGB                                  3.5646     2.1834   1.633 0.102548    
Actual_SourcePHB                                 5.4763     2.2603   2.423 0.015399 *  
Cov_PriorSource_and_ID                           1.3127     1.1820   1.111 0.266759    
Cov_PriorSource_and_Universal                    1.8499     1.1897   1.555 0.119957    
Cov_PriorUniversal                              -0.7606     1.2383  -0.614 0.539071    
Actual_SourceFBE:Cov_PriorSource_and_ID          1.2209     1.7028   0.717 0.473394    
Actual_SourceFBW:Cov_PriorSource_and_ID         -0.2013     1.5930  -0.126 0.899459    
Actual_SourceGB:Cov_PriorSource_and_ID          -2.3905     1.4677  -1.629 0.103378    
Actual_SourcePHB:Cov_PriorSource_and_ID         -0.1891     1.4697  -0.129 0.897644    
Actual_SourceFBE:Cov_PriorSource_and_Universal   0.6837     1.7017   0.402 0.687865    
Actual_SourceFBW:Cov_PriorSource_and_Universal  -0.7385     1.5954  -0.463 0.643451    
Actual_SourceGB:Cov_PriorSource_and_Universal   -2.5551     1.4638  -1.746 0.080885 .  
Actual_SourcePHB:Cov_PriorSource_and_Universal  -0.7263     1.4709  -0.494 0.621479    
Actual_SourceFBE:Cov_PriorUniversal              1.9547     1.6763   1.166 0.243569    
Actual_SourceFBW:Cov_PriorUniversal              0.7606     1.6338   0.466 0.641565    
Actual_SourceGB:Cov_PriorUniversal               0.7606     1.4870   0.511 0.609020    
Actual_SourcePHB:Cov_PriorUniversal              1.1372     1.5158   0.750 0.453104    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Relative to the intercept (reflecting the CHR source and using the ID co-variance matrix), larvae from GB were the only ones to have a significantly similar frequency of correct assignments. This is pretty consistent with what we saw in the figures before - CHR and GB had low frequencies of correct assignments, while other sources were better.

Results by Covariance Matrix Prior

If we wanted to look at the effect of different co-variance priors, we see that, generally, using the source specific co-variance matrices leads to the best assignments.

Taken together, the results suggest that for best assignment, we should run the IMM with source specific and universal co-variance priors. Taking these IMM assignments and projecting the correct and incorrect assignments onto the PCA from before, we see that there is no clear pattern, geochemically, for why individuals are misassigned.

Overall, we learn that source specific and universal co-variance matrices produce marginally better IMM results when assigning larvae, but that the greatest influence on IMM misclassifications is source-specific geochemistry.

LS0tCnRpdGxlOiAiSW5maW5pdGUgTWl4dHVyZSBNb2RlbCBMZWF2ZS1PbmUtT3V0IEFuYWx5c2lzIGZvciAqTXl0aWx1cyBlZHVsaXMqIExhcnZhZSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoInBseXIiKQpsaWJyYXJ5KCJhYmluZCIpCmxpYnJhcnkoInJlc2hhcGUiKQpsaWJyYXJ5KCJnZ3Bsb3QyIikKbGlicmFyeSgiY2FyIikKbGlicmFyeSgibG1lNCIpCmxpYnJhcnkoImdnZm9ydGlmeSIpCgojIyMgc29tZSBlbGVtZW50IGRhdGEKCklDUE1TLmFsbC4yMDE1LmRhdDwtcmVhZC5jc3YoIi9Vc2Vycy9zY290dG1vcmVsbG8vRHJvcGJveC9BcmNoaXZlcy9BY2FkZW1pYy9VTWFzcyBCb3N0b24vRXR0ZXIgTGFiL1Byb2plY3RzL1RyYWNlIEVsZW1lbnQgTXVzc2VsIENvbm5lY3Rpdml0eS8yMDE1IElDUE1TIERhdGFzZXRzLzIwMTUuQWxsLkRhdGEuY3N2IikKCklDUE1TLmFsbC4yMDE1Lmp1dmRhdDwtc3Vic2V0KElDUE1TLmFsbC4yMDE1LmRhdCxUeXBlPT0iTGFydmFlIikKdG9wLnNvdXJjZXM8LW5hbWVzKHNvcnQoc3VtbWFyeShJQ1BNUy5hbGwuMjAxNS5qdXZkYXQkU2l0ZSksZGVjcmVhc2luZyA9IFRSVUUpKVsxOjVdCklDUE1TLmFsbC4yMDE1Lmp1dmRhdDwtc3Vic2V0KElDUE1TLmFsbC4yMDE1Lmp1dmRhdCxTaXRlPT10b3Auc291cmNlc1sxXXxTaXRlPT10b3Auc291cmNlc1syXXxTaXRlPT10b3Auc291cmNlc1szXXxTaXRlPT10b3Auc291cmNlc1s0XXxTaXRlPT10b3Auc291cmNlc1s1XSkKSUNQTVMuYWxsLjIwMTUuanV2ZGF0JFNpdGU8LWZhY3RvcihJQ1BNUy5hbGwuMjAxNS5qdXZkYXQkU2l0ZSkKSUNQTVMuYWxsLjIwMTUuanV2ZGF0LmVudjwtSUNQTVMuYWxsLjIwMTUuanV2ZGF0WyxjKDE6NCldCklDUE1TLmFsbC4yMDE1Lmp1dmRhdC52YWw8LUlDUE1TLmFsbC4yMDE1Lmp1dmRhdFssLWMoMTo0KV0KSUNQTVMuYWxsLjIwMTUuanV2ZGF0LnZhbC50cmFuczwtbG9nKElDUE1TLmFsbC4yMDE1Lmp1dmRhdC52YWwrMSwxMCkKCgpsZWF2ZS5vbmUub3V0LnJlc3VsdHM8LXJlYWRSRFMoIi9Vc2Vycy9zY290dG1vcmVsbG8vRHJvcGJveC9BcmNoaXZlcy9BY2FkZW1pYy9VTWFzcyBCb3N0b24vRXR0ZXIgTGFiL1Byb2plY3RzL1RyYWNlIEVsZW1lbnQgTXVzc2VsIENvbm5lY3Rpdml0eS9SIFdvcmsvSW5maW5pdGUgTWl4dHVyZSBNb2RlbCBpbiBSL0phZ3NfV29yay9sZWF2ZW9uZW91dHJlc3VsdHMucmRzIikKCmBgYAojIyBUaGUgQW5hbHlzaXMKICBUaGUgZm9sbG93aW5nIGFuYWx5c2lzIHB1bGxlZCBnZW9jaGVtaXN0cnkgZGF0YSBmcm9tIHRoZSAyMDE1IFJlZmVyZW5jZSBMYXJ2YWUgZGF0YSBzZXQsIGFuZCB0ZXN0ZWQgdGhlIGVmZmVjdHMgb2YgbGFydmFsIHNvdXJjZSwgYW5kIGNvLXZhcmlhbmNlIG1hdHJpeCBwcmlvciwgb24gdGhlIGFiaWxpdHkgb2YgdGhlIGluZmluaXRlIG1peHR1cmUgbW9kZWwgKElNTSkgdG8gY29ycmVjdGx5IGFzc2lnbiBsYXJ2YWUgdG8gc291cmNlcy4gRHVyaW5nIGFuYWx5c2lzLCBlYWNoIGxhcnZhZSB3YXMgcmVtb3ZlZCBmcm9tIHRoZSBvdmVyYWxsIGRhdGEgc2V0LCBhbmQgdGhlIHJlbWFpbmluZyBsYXJ2YWUgdXNlZCBhcyBiYXNlbGluZSBkYXRhIHRvIHRyYWluIHRoZSBJTU0uIFRoZSBpbmRpdmlkdWFsIGxhcnZhZSByZW1vdmVkIGZyb20gdGhlIGRhdGEgc2V0IHdhcyB0aGVuIGFzc2lnbmVkIHRvIGEgc291cmNlIGJhc2VkIG9uIHRoZSBJTU0sIGFsbG93aW5nIGZvciA3IHBvc3NpYmxlIGV4dHJhLCBhbmQgdW50cmFpbmVkLCBzb3VyY2UgYXNzaWdubWVudHMsIHVzaW5nIGVhY2ggb2YgZm91ciBkaWZmZXJlbnQgY28tdmFyaWFuY2UgbWF0cml4IHByaW9yczoKCiogVGhlIElkZW50aXR5IE1hdHJpeCBmb3IgYWxsIHNvdXJjZXMKKiBTb3VyY2UgU3BlY2lmaWMgQ28tdmFyaWFuY2UgTWF0cmljZXMgZm9yIGJhc2VsaW5lIHNvdXJjZXMsIGFuZCB0aGVuIHRoZSBJZGVudGl0eSBNYXRyaXggZm9yIGV4dHJhIHNvdXJjZXMKKiBTb3VyY2UgU3BlY2lmaWMgQ28tdmFyaWFuY2UgTWF0cmljZXMgZm9yIGJhc2VsaW5lIHNvdXJjZXMsIGFuZCB0aGVuIHRoZSBVbml2ZXJzYWwgQ28tdmFyaWFuY2UgTWF0cml4IGZvciBleHRyYSBzb3VyY2VzCiogVGhlIFVuaXZlcnNhbCBDby12YXJpYW5jZSBNYXRyaXggZm9yIGFsbCBzb3VyY2VzCgpGb3IgZWFjaCBjby12YXJpYW5jZSBtYXRyaXggcHJpb3IgZm9yIGVhY2ggbGFydmFlLCB0aGUgSU1NIHdhcyBydW4gZm9yIGFuIGluaXRpYWwgMTAwMCBhZGFwdGF0aW9uIGFuZCAyMDAwIGJ1cm4taW4gaXRlcmF0aW9ucy4gVGhlIHBvc3RlcmlvciBkaXN0cmlidXRpb24gb2Ygc291cmNlIGFzc2lnbm1lbnRzIGZvciBhIGZpbmFsIDMwMDAgaXRlcmF0aW9ucyB3ZXJlIHJldGFpbmVkIGFuZCB1c2VkIGZvciBmdXJ0aGVyIGFuYWx5c2lzLgoKCiMjIFRoZSBEYXRhIFNldAoKICBEYXRhIHdlcmUgJExvZyh4KzEpJCB0cmFuc2Zvcm1lZCwgYW5kIGNlbnRlcmVkIChieSBlbGVtZW50YWwgbWVhbikgYW5kIHNjYWxlZCAoYnkgZWxlbWVudGFsIHN0YW5kYXJkIGRldmlhdGlvbikgcHJpb3IgdG8gYW5hbHlzaXMuIFRvZ2V0aGVyLCB0aGVzZSB0cmFuc2Zvcm1hdGlvbnMgd2VyZSBtZWFudCB0byBub3JtYWxpemUgdGhlIGVsZW1lbnRhbCBkYXRhLCBhbmQgdGhlbiBzdGFuZGFyZGl6ZSB0aGUgY2VudGVyIGFuZCB2YXJpYW5jZSBzbyB0aGF0IHVua25vd24gc291cmNlcyBjb3VsZCBiZSBlYXNpbHkgbW9kZWxlZCBpbiB0aGUgSU1NLiBQcmluY2lwYWwgQ29tcG9uZW50IEFuYWx5c2lzIHN1Z2dlc3RlZCBhIGxvdCBvZiBvdmVybGFwIGluIHRoZSBtdWx0aXZhcmlhdGUgZ2VvY2hlbWljYWwgc2lnbmFscyBhbW9uZyBzb3VyY2VzIGFsb25nIHRoZSBmaXJzdCAyIHByaW5jaXBsZSBjb21wb25lbnRzIChhY2NvdW50aW5nIGZvciAzNiBhbmQgMjIgcGVyY2VudCBvZiB0b3RhbCB2YXJpYXRpb24gcmVzcGVjdGl2ZWx5KS4gT2YgYWxsIGVsZW1lbnRzLCAqKk1nKiogYWNjb3VudGVkIGZvciB0aGUgbW9zdCB2YXJpYXRpb24gYW1vbmcgaW5kaXZpZHVhbCBsYXJ2YWUsIHdoaWxlICoqTGEqKiBhY2NvdW50ZWQgZm9yIHRoZSBsZWFzdC4KYGBge3IsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9MiwgZmlnLndpZHRoPTMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CgphdXRvcGxvdChwcmNvbXAoSUNQTVMuYWxsLjIwMTUuanV2ZGF0LnZhbC50cmFucyksIAogICAgICAgICBkYXRhID0gSUNQTVMuYWxsLjIwMTUuanV2ZGF0LmVudiwgCiAgICAgICAgIGNvbG91ciA9ICJTaXRlIiwKICAgICAgICAgbG9hZGluZ3MgPSBUUlVFLAogICAgICAgICBsb2FkaW5ncy5sYWJlbCA9IFRSVUUsCiAgICAgICAgIGZyYW1lID0gVFJVRSwgCiAgICAgICAgIGZyYW1lLnR5cGUgPSAnbm9ybScpKwogIHRoZW1lX2J3KCkKYGBgCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpzdW1tYXJ5KHByY29tcChJQ1BNUy5hbGwuMjAxNS5qdXZkYXQudmFsLnRyYW5zKSkKYGBgCgoKIyMgUmVzdWx0cyBieSBJbmRpdmlkdWFsCgogIEJlbG93IGFyZSB0aGUgcG9zdGVyaW9yIGRpc3RyaWJ1dGlvbiByZXN1bHRzIG9mIHRoZSBJTU0gYXNzaWdubWVudCBmb3IgZWFjaCBpbmRpdmlkdWFsIGxhcnZhZSAoY29sb3IpIHRvIGVhY2ggcG90ZW50aWFsIHNvdXJjZSAoeC1heGlzOyBudW1iZXJzIHJlcHJlc2VudCBwb3NzaWJsZSBleHRyYSBzb3VyY2VzKS4gUmVzdWx0cyBhcmUgc2VwYXJhdGVkIGJ5IHRoZSBhY3R1YWwgbGFydmFsIHNvdXJjZSAocGFuZWwgcm93cykgYW5kIHRoZSBjby12YXJpYW5jZSBtYXRyaXggcHJpb3IgdXNlZCBpbiB0aGUgSU1NIChwYW5lbCBjb2x1bW5zKS4KYGBge3IsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9MywgZmlnLndpZHRoPTQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxlYXZlLm9uZS5vdXQucmVzdWx0cy5ieWluZC50YWJsZTwtbWVsdChsZWF2ZS5vbmUub3V0LnJlc3VsdHMsaWQudmFycz1jKCJJbmRpdmlkdWFsIiwiQ292X1ByaW9yIiwiQWN0dWFsIikpCmNvbG5hbWVzKGxlYXZlLm9uZS5vdXQucmVzdWx0cy5ieWluZC50YWJsZSlbMzo1XTwtYygiQWN0dWFsX1NvdXJjZSIsIlByZWRpY3RlZF9Tb3VyY2UiLCJQZXJjZW50X0Fzc2lnbm1lbnQiKQoKbGVhdmUub25lLm91dC5yZXN1bHRzLmJ5aW5kLnRhYmxlJFByZWRpY3RlZF9Tb3VyY2U8LWZhY3RvcihsZWF2ZS5vbmUub3V0LnJlc3VsdHMuYnlpbmQudGFibGUkUHJlZGljdGVkX1NvdXJjZSkKbGV2ZWxzKGxlYXZlLm9uZS5vdXQucmVzdWx0cy5ieWluZC50YWJsZSRQcmVkaWN0ZWRfU291cmNlKTwtYyhsZXZlbHMoSUNQTVMuYWxsLjIwMTUuanV2ZGF0LmVudltzYW1waW5kLCJTaXRlIl0pLGMocmVmc2l0ZS5uKzE6ZXh0cmFzaXRlLm4pKQoKbGVhdmUub25lLm91dC5yZXN1bHRzLmJ5aW5kLnRhYmxlJEFjdHVhbF9Tb3VyY2U8LWZhY3RvcihsZWF2ZS5vbmUub3V0LnJlc3VsdHMuYnlpbmQudGFibGUkQWN0dWFsX1NvdXJjZSkKbGV2ZWxzKGxlYXZlLm9uZS5vdXQucmVzdWx0cy5ieWluZC50YWJsZSRBY3R1YWxfU291cmNlKTwtYyhsZXZlbHMoSUNQTVMuYWxsLjIwMTUuanV2ZGF0LmVudltzYW1waW5kLCJTaXRlIl0pLGMocmVmc2l0ZS5uKzE6ZXh0cmFzaXRlLm4pKQoKCmNvbG91ci52ZWM8LXJhaW5ib3cobWF4KGxlYXZlLm9uZS5vdXQucmVzdWx0cy5ieWluZC50YWJsZSRJbmRpdmlkdWFsKSwgcz0uNiwgdj0uOSlbc2FtcGxlKGMoMTptYXgobGVhdmUub25lLm91dC5yZXN1bHRzLmJ5aW5kLnRhYmxlJEluZGl2aWR1YWwpKSxtYXgobGVhdmUub25lLm91dC5yZXN1bHRzLmJ5aW5kLnRhYmxlJEluZGl2aWR1YWwpKV0KY29sb3VyLnZlYzwtY29sb3VyLnZlY1ttYXRjaChsZWF2ZS5vbmUub3V0LnJlc3VsdHMuYnlpbmQudGFibGUkSW5kaXZpZHVhbCxjKDE6bWF4KGxlYXZlLm9uZS5vdXQucmVzdWx0cy5ieWluZC50YWJsZSRJbmRpdmlkdWFsKSkpXQoKCmdncGxvdChsZWF2ZS5vbmUub3V0LnJlc3VsdHMuYnlpbmQudGFibGUsYWVzKHg9UHJlZGljdGVkX1NvdXJjZSxncm91cD1JbmRpdmlkdWFsLHk9UGVyY2VudF9Bc3NpZ25tZW50LGNvbG91cj1mYWN0b3IoSW5kaXZpZHVhbCkpKSsKICAgIGZhY2V0X2dyaWQoQWN0dWFsX1NvdXJjZX5Db3ZfUHJpb3IpKwogICAgZ2VvbV9saW5lKCkgKyAKICAgIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gY29sb3VyLnZlYykrCiAgICB0aGVtZV9idygpKwogICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSxsZWdlbmQucG9zaXRpb249Im5vbmUiKQpgYGAKV2UgY2FuIHNlZSB0aGF0IGdlbmVyYWxseSwgaW5kaXZpZHVhbCBzb3VyY2VzIGFzc2lnbiBtb3N0IGZyZXF1ZW50bHkgdG8gb25lIHNvdXJjZSwgd2hpY2ggaXMgdXN1YWxseSB0aGUgY29ycmVjdCBvbmUuIFNvdXJjZXMgbGlrZSBDSFIsIEZCRSBhbmQgR0IgYXJlIG1vcmUgbXVsdGktbW9kYWwgYW5kIGRpZmZ1c2UgaW4gdGhlaXIgYXNzaWdubWVudHMgdGhvdWdoLgoKCiMjIFJlc3VsdHMgYnkgU291cmNlCgpUbyBzdW1tYXJpemUgYXNzaWdubWVudCByZXN1bHRzIGJ5IHNpdGUsIHdlIHRha2UgdGhlIG1vZGUgc291cmNlIGFzc2lnbm1lbnQgZm9yIGVhY2ggaW5kaXZpZHVhbCBhbmQgdXNlIHRoYXQgYXMgdGhlIElNTSBwcmVkaWN0ZWQgc291cmNlIGFzc2lnbm1lbnQuIFRoZW4sIGZvciBlYWNoIGNvLXZhcmlhbmNlIG1hdHJpeCBwcmlvciAocGFuZWxzKSwgd2UgcGxvdCB0aGUgcGVyY2VudCBvZiBpbmRpdmlkdWFscyBmcm9tIGVhY2ggc291cmNlIChBY3R1YWwgU291cmNlKSBhc3NpZ25lZCB0byBlYWNoIHBvc3NpYmxlIHNvdXJjZSBieSB0aGUgSU1NIChQcmVkaWN0ZWQgU291cmNlKS4KYGBge3IsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9MSwgZmlnLndpZHRoPTQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxlYXZlLm9uZS5vdXQucmVzdWx0cy5ieWluZC5hc3NpZ25tZW50PC1kZHBseShsZWF2ZS5vbmUub3V0LnJlc3VsdHMuYnlpbmQudGFibGUsLihJbmRpdmlkdWFsLENvdl9QcmlvcixBY3R1YWxfU291cmNlKSxzdW1tYXJpemUsUHJlZGljdGVkX1NvdXJjZT13aGljaC5tYXgoUGVyY2VudF9Bc3NpZ25tZW50KSkKbGVhdmUub25lLm91dC5yZXN1bHRzLmJ5aW5kLmFzc2lnbm1lbnQkUHJlZGljdGVkX1NvdXJjZTwtZmFjdG9yKGxlYXZlLm9uZS5vdXQucmVzdWx0cy5ieWluZC5hc3NpZ25tZW50JFByZWRpY3RlZF9Tb3VyY2UpCmxldmVscyhsZWF2ZS5vbmUub3V0LnJlc3VsdHMuYnlpbmQuYXNzaWdubWVudCRQcmVkaWN0ZWRfU291cmNlKTwtYyhsZXZlbHMoSUNQTVMuYWxsLjIwMTUuanV2ZGF0LmVudltzYW1waW5kLCJTaXRlIl0pLGMocmVmc2l0ZS5uKzE6ZXh0cmFzaXRlLm4pKVsxOmxlbmd0aCh1bmlxdWUobGVhdmUub25lLm91dC5yZXN1bHRzLmJ5aW5kLmFzc2lnbm1lbnQkUHJlZGljdGVkX1NvdXJjZSkpXQoKI0lECklELmFzc2lnbi50YWJsZTwtKHRhYmxlKHN1YnNldChsZWF2ZS5vbmUub3V0LnJlc3VsdHMuYnlpbmQuYXNzaWdubWVudCxDb3ZfUHJpb3I9PSJJRCIpWyxjKDM6NCldKS9yb3dTdW1zKHRhYmxlKHN1YnNldChsZWF2ZS5vbmUub3V0LnJlc3VsdHMuYnlpbmQuYXNzaWdubWVudCxDb3ZfUHJpb3I9PSJJRCIpWyxjKDM6NCldKSkpW2MoMTo1KSxdCgojU291cmNlX2FuZF9JRApTb3VyY2VfYW5kX0lELmFzc2lnbi50YWJsZTwtKHRhYmxlKHN1YnNldChsZWF2ZS5vbmUub3V0LnJlc3VsdHMuYnlpbmQuYXNzaWdubWVudCxDb3ZfUHJpb3I9PSJTb3VyY2VfYW5kX0lEIilbLGMoMzo0KV0pL3Jvd1N1bXModGFibGUoc3Vic2V0KGxlYXZlLm9uZS5vdXQucmVzdWx0cy5ieWluZC5hc3NpZ25tZW50LENvdl9Qcmlvcj09IlNvdXJjZV9hbmRfSUQiKVssYygzOjQpXSkpKVtjKDE6NSksXQoKI1NvdXJjZV9hbmRfVW5pdmVyc2FsClNvdXJjZV9hbmRfVW5pdmVyc2FsLmFzc2lnbi50YWJsZTwtKHRhYmxlKHN1YnNldChsZWF2ZS5vbmUub3V0LnJlc3VsdHMuYnlpbmQuYXNzaWdubWVudCxDb3ZfUHJpb3I9PSJTb3VyY2VfYW5kX1VuaXZlcnNhbCIpWyxjKDM6NCldKS9yb3dTdW1zKHRhYmxlKHN1YnNldChsZWF2ZS5vbmUub3V0LnJlc3VsdHMuYnlpbmQuYXNzaWdubWVudCxDb3ZfUHJpb3I9PSJTb3VyY2VfYW5kX1VuaXZlcnNhbCIpWyxjKDM6NCldKSkpW2MoMTo1KSxdCgojVW5pdmVyc2FsClVuaXZlcnNhbC5hc3NpZ24udGFibGU8LSh0YWJsZShzdWJzZXQobGVhdmUub25lLm91dC5yZXN1bHRzLmJ5aW5kLmFzc2lnbm1lbnQsQ292X1ByaW9yPT0iVW5pdmVyc2FsIilbLGMoMzo0KV0pL3Jvd1N1bXModGFibGUoc3Vic2V0KGxlYXZlLm9uZS5vdXQucmVzdWx0cy5ieWluZC5hc3NpZ25tZW50LENvdl9Qcmlvcj09IlVuaXZlcnNhbCIpWyxjKDM6NCldKSkpW2MoMTo1KSxdCgpsZWF2ZS5vbmUub3V0LnJlc3VsdHMuYWxsLmFzc2lnbm1lbnQ8LWNiaW5kKGRhdGEuZnJhbWUoQ292X1ByaW9yPXJlcChjKCJJRCIsIlNvdXJjZV9hbmRfSUQiLCJTb3VyY2VfYW5kX1VuaXZlcnNhbCIsIlVuaXZlcnNhbCIpLGVhY2g9NSksQWN0dWFsX1NvdXJjZT1yZXAocm93Lm5hbWVzKElELmFzc2lnbi50YWJsZSksNCkpLHJiaW5kKElELmFzc2lnbi50YWJsZSxTb3VyY2VfYW5kX0lELmFzc2lnbi50YWJsZSxTb3VyY2VfYW5kX1VuaXZlcnNhbC5hc3NpZ24udGFibGUsVW5pdmVyc2FsLmFzc2lnbi50YWJsZSkpCmxlYXZlLm9uZS5vdXQucmVzdWx0cy5hbGwuYXNzaWdubWVudDwtbWVsdChsZWF2ZS5vbmUub3V0LnJlc3VsdHMuYWxsLmFzc2lnbm1lbnQpCmNvbG5hbWVzKGxlYXZlLm9uZS5vdXQucmVzdWx0cy5hbGwuYXNzaWdubWVudClbMzo0XTwtYygiUHJlZGljdGVkX1NvdXJjZSIsIlBlcmNlbnRfQXNzaWduZWQiKQoKCmdncGxvdChsZWF2ZS5vbmUub3V0LnJlc3VsdHMuYWxsLmFzc2lnbm1lbnQsYWVzKHg9UHJlZGljdGVkX1NvdXJjZSx5PUFjdHVhbF9Tb3VyY2UsZmlsbD1QZXJjZW50X0Fzc2lnbmVkKSkrCiAgZmFjZXRfd3JhcCh+Q292X1ByaW9yLG5jb2w9NCkrCiAgZ2VvbV90aWxlKGNvbG91ciA9ICJ3aGl0ZSIpICsgCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAid2hpdGUiLCBoaWdoID0gInJlZCIsbGltaXRzPWMoMCwxKSkrCiAgdGhlbWVfYncoKSsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKQpgYGAKSnVzdCBhcyBiZWZvcmUsIHdoZW4gd2UgbG9va2VkIGF0IGRhdGEgb24gYW4gaW5kaXZpZHVhbCBsZXZlbCwgd2UgZ2VuZXJhbGx5IHNlZSBJTU0gYXNzaWdubWVudCB0byBjb3JyZWN0IHNvdXJjZXMsIGJ1dCBDSFIgaXMgbW9zdGx5IGNvbmZ1c2VkIHdpdGggUEhCIGFuZCBGQlcsIGFuZCBHQiBhbmQgRkJXIGFyZSBjb25mdXNlZCB3aXRoIGVhY2ggb3RoZXIuIE1heGltdW0gcGVyY2VudGFnZSBjb3JyZWN0bHkgYXNzaWduZWQgd2FzIG9ubHkgNjIlIGZvciBGQkUgdGhvdWdoLgoKCiMjIEVmZmVjdHMgb2YgU291cmNlIGFuZCBDb3ZpYXJpYW5jZSBNYXRyaXggUHJpb3Igb24gQ29ycmVjdCBBc3NpZ25tZW50CgpUbyB1bmRlcnN0YW5kIHdoYXQgaXMgZHJpdmluZyBtaXNjbGFzc2lmaWNhdGlvbiBieSB0aGUgSU1NLCB3ZSB0ZXN0IHRoZSBlZmZlY3RzIG9mIEFjdHVhbCBTb3VyY2UsIENvLXZhcmlhbmNlIFByaW9yLCBhbmQgdGhlaXIgaW50ZXJhY3Rpb24gd2l0aCBhIEdMTSAoZmFtaWx5PWJpbm9taWFsLCBsaW5rPWxvZyksIHVzaW5nIGluZGl2aWR1YWwgbmVzdGVkIHdpdGhpbiBhY3R1YWwgc291cmNlIGFzIGEgcmFuZG9tIGVmZmVjdC4KYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxlYXZlLm9uZS5vdXQucmVzdWx0cy5ieWluZC5hc3NpZ25tZW50LnRhYmxlPC1sZWF2ZS5vbmUub3V0LnJlc3VsdHMuYnlpbmQuYXNzaWdubWVudApsZWF2ZS5vbmUub3V0LnJlc3VsdHMuYnlpbmQuYXNzaWdubWVudC50YWJsZSRDb3JyZWN0PC1hcy5udW1lcmljKGFzLmNoYXJhY3RlcihsZWF2ZS5vbmUub3V0LnJlc3VsdHMuYnlpbmQuYXNzaWdubWVudC50YWJsZSRBY3R1YWxfU291cmNlKT09YXMuY2hhcmFjdGVyKGxlYXZlLm9uZS5vdXQucmVzdWx0cy5ieWluZC5hc3NpZ25tZW50LnRhYmxlJFByZWRpY3RlZF9Tb3VyY2UpKQpsZWF2ZS5vbmUub3V0LnJlc3VsdHMuYnlpbmQuYXNzaWdubWVudC50YWJsZSRJbmRpdmlkdWFsX0NvZGU8LXBhc3RlMChsZWF2ZS5vbmUub3V0LnJlc3VsdHMuYnlpbmQuYXNzaWdubWVudC50YWJsZSRBY3R1YWxfU291cmNlLGxlYXZlLm9uZS5vdXQucmVzdWx0cy5ieWluZC5hc3NpZ25tZW50LnRhYmxlJEluZGl2aWR1YWwpCgpsZWF2ZS5vbmUub3V0LnJlc3VsdHMuY29ycmVjdC5hc3NpZ25tZW50LmxtMjwtZ2xtZXIoQ29ycmVjdH5BY3R1YWxfU291cmNlKkNvdl9QcmlvcisoMXxBY3R1YWxfU291cmNlL0luZGl2aWR1YWxfQ29kZSksZGF0YT1sZWF2ZS5vbmUub3V0LnJlc3VsdHMuYnlpbmQuYXNzaWdubWVudC50YWJsZSxmYW1pbHk9Ymlub21pYWwpCnNzIDwtIGdldE1FKGxlYXZlLm9uZS5vdXQucmVzdWx0cy5jb3JyZWN0LmFzc2lnbm1lbnQubG0yLGMoInRoZXRhIiwiZml4ZWYiKSkKbGVhdmUub25lLm91dC5yZXN1bHRzLmNvcnJlY3QuYXNzaWdubWVudC5sbTwtdXBkYXRlKGxlYXZlLm9uZS5vdXQucmVzdWx0cy5jb3JyZWN0LmFzc2lnbm1lbnQubG0yLHN0YXJ0PXNzLGNvbnRyb2w9Z2xtZXJDb250cm9sKG9wdGltaXplcj0iYm9ieXFhIixvcHRDdHJsPWxpc3QobWF4ZnVuPTJlNCkpKQpBbm92YShsZWF2ZS5vbmUub3V0LnJlc3VsdHMuY29ycmVjdC5hc3NpZ25tZW50LmxtLHR5cGU9MykKYGBgCldlIGZpbmQgdGhhdCBhIGxhcnZhJ3MgYWN0dWFsIHNvdXJjZSBoYXMgdGhlIGdyZWF0ZXN0LCBhbmQgb25seSBtYXJnaW5hbGx5IGluc2lnbmlmaWNhbnQsIGVmZmVjdCBvbiBjb3JyZWN0IGNsYXNzaWZpY2F0aW9uLgoKV2UgY2FuIHVzZSB0aGUgcmVncmVzc2lvbiBjb2VmZmljaWVudCBzdW1tYXJpZXMgZm9yIGEgbW9yZSBpbi1kZXB0aCBsb29rLgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0Kc3VtbWFyeShsZWF2ZS5vbmUub3V0LnJlc3VsdHMuY29ycmVjdC5hc3NpZ25tZW50LmxtKQpgYGAKUmVsYXRpdmUgdG8gdGhlIGludGVyY2VwdCAocmVmbGVjdGluZyB0aGUgQ0hSIHNvdXJjZSBhbmQgdXNpbmcgdGhlIElEIGNvLXZhcmlhbmNlIG1hdHJpeCksIGxhcnZhZSBmcm9tIEdCIHdlcmUgdGhlIG9ubHkgb25lcyB0byBoYXZlIGEgc2lnbmlmaWNhbnRseSBzaW1pbGFyIGZyZXF1ZW5jeSBvZiBjb3JyZWN0IGFzc2lnbm1lbnRzLiBUaGlzIGlzIHByZXR0eSBjb25zaXN0ZW50IHdpdGggd2hhdCB3ZSBzYXcgaW4gdGhlIGZpZ3VyZXMgYmVmb3JlIC0gQ0hSIGFuZCBHQiBoYWQgbG93IGZyZXF1ZW5jaWVzIG9mIGNvcnJlY3QgYXNzaWdubWVudHMsIHdoaWxlIG90aGVyIHNvdXJjZXMgd2VyZSBiZXR0ZXIuCgoKIyMgUmVzdWx0cyBieSBDb3ZhcmlhbmNlIE1hdHJpeCBQcmlvcgpJZiB3ZSB3YW50ZWQgdG8gbG9vayBhdCB0aGUgZWZmZWN0IG9mIGRpZmZlcmVudCBjby12YXJpYW5jZSBwcmlvcnMsIHdlIHNlZSB0aGF0LCBnZW5lcmFsbHksIHVzaW5nIHRoZSBzb3VyY2Ugc3BlY2lmaWMgY28tdmFyaWFuY2UgbWF0cmljZXMgbGVhZHMgdG8gdGhlIGJlc3QgYXNzaWdubWVudHMuCmBgYHtyLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTIsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsZWF2ZS5vbmUub3V0LnJlc3VsdHMuY29ycmVjdC5hc3NpZ25tZW50PC1kZHBseShsZWF2ZS5vbmUub3V0LnJlc3VsdHMuYnlpbmQuYXNzaWdubWVudC50YWJsZSwuKENvdl9QcmlvcixBY3R1YWxfU291cmNlKSxzdW1tYXJpemUsQ29ycmVjdGx5X0Fzc2lnbmVkPXN1bShDb3JyZWN0KSxUb3RhbD1sZW5ndGgoQ29ycmVjdCkpCmxlYXZlLm9uZS5vdXQucmVzdWx0cy5jb3JyZWN0LmFzc2lnbm1lbnQkUGVyY2VudF9Db3JyZWN0PC1sZWF2ZS5vbmUub3V0LnJlc3VsdHMuY29ycmVjdC5hc3NpZ25tZW50JENvcnJlY3RseV9Bc3NpZ25lZC9sZWF2ZS5vbmUub3V0LnJlc3VsdHMuY29ycmVjdC5hc3NpZ25tZW50JFRvdGFsCgoKZ2dwbG90KGxlYXZlLm9uZS5vdXQucmVzdWx0cy5jb3JyZWN0LmFzc2lnbm1lbnQsYWVzKHg9QWN0dWFsX1NvdXJjZSx5PVBlcmNlbnRfQ29ycmVjdCxmaWxsPUNvdl9QcmlvcikpKwogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5Iixwb3NpdGlvbj0iZG9kZ2UiKSsKICBzY2FsZV9maWxsX2JyZXdlcihuYW1lPSJDb3ZhcmlhbmNlIFByaW9yIixicmVha3M9YygiSUQiLCAiU291cmNlX2FuZF9JRCIsIlNvdXJjZV9hbmRfVW5pdmVyc2FsIiwiVW5pdmVyc2FsIiksbGFiZWxzPWMoIklkZW50aXR5IE1hdHJpeCIsICJTb3VyY2UgU3BlY2lmaWMgQ292YXJpYW5jZSxcbnRoZW4gSWRlbnRpdHkgTWF0cmljZXMiLCJTb3VyY2UgU3BlY2lmaWMgQ292YXJpYW5jZSxcbnRoZW4gVW5pdmVyc2FsIENvdmFyaWFuY2UgTWF0cmljZXMiLCJVbml2ZXJzYWwgQ292YXJpYW5jZSBNYXRyaXgiKSkrCiAgeGxhYigiQWN0dWFsIFNvdXJjZSIpKwogIHlsYWIoIlBlcmNlbnQgQ29ycmVjdGx5IEFzc2lnbmVkIikrCiAgdGhlbWVfYncoKQpgYGAKClRha2VuIHRvZ2V0aGVyLCB0aGUgcmVzdWx0cyBzdWdnZXN0IHRoYXQgZm9yIGJlc3QgYXNzaWdubWVudCwgd2Ugc2hvdWxkIHJ1biB0aGUgSU1NIHdpdGggc291cmNlIHNwZWNpZmljIGFuZCB1bml2ZXJzYWwgY28tdmFyaWFuY2UgcHJpb3JzLiBUYWtpbmcgdGhlc2UgSU1NIGFzc2lnbm1lbnRzIGFuZCBwcm9qZWN0aW5nIHRoZSBjb3JyZWN0IGFuZCBpbmNvcnJlY3QgYXNzaWdubWVudHMgb250byB0aGUgUENBIGZyb20gYmVmb3JlLCB3ZSBzZWUgdGhhdCB0aGVyZSBpcyBubyBjbGVhciBwYXR0ZXJuLCBnZW9jaGVtaWNhbGx5LCBmb3Igd2h5IGluZGl2aWR1YWxzIGFyZSBtaXNhc3NpZ25lZC4KYGBge3IsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9MiwgZmlnLndpZHRoPTMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxlYXZlLm9uZS5vdXQucmVzdWx0cy5ieWluZC5hc3NpZ25tZW50LmNvcnJlY3Q8LXN1YnNldChsZWF2ZS5vbmUub3V0LnJlc3VsdHMuYnlpbmQuYXNzaWdubWVudC50YWJsZSxDb3ZfUHJpb3I9PSJTb3VyY2VfYW5kX1VuaXZlcnNhbCIpCmxlYXZlLm9uZS5vdXQucmVzdWx0cy5ieWluZC5hc3NpZ25tZW50LmNvcnJlY3QkQ29ycmVjdFt3aGljaChsZWF2ZS5vbmUub3V0LnJlc3VsdHMuYnlpbmQuYXNzaWdubWVudC5jb3JyZWN0JENvcnJlY3Q9PTEpXTwtIkNvcnJlY3QiCmxlYXZlLm9uZS5vdXQucmVzdWx0cy5ieWluZC5hc3NpZ25tZW50LmNvcnJlY3QkQ29ycmVjdFstd2hpY2gobGVhdmUub25lLm91dC5yZXN1bHRzLmJ5aW5kLmFzc2lnbm1lbnQuY29ycmVjdCRDb3JyZWN0PT0iQ29ycmVjdCIpXTwtIkluY29ycmVjdCIKCgpJQ1BNUy5hbGwuMjAxNS5qdXZkYXQuZW52MjwtSUNQTVMuYWxsLjIwMTUuanV2ZGF0LmVudgpJQ1BNUy5hbGwuMjAxNS5qdXZkYXQuZW52MiRDb3JyZWN0PC1mYWN0b3IobGVhdmUub25lLm91dC5yZXN1bHRzLmJ5aW5kLmFzc2lnbm1lbnQuY29ycmVjdCRDb3JyZWN0KQoKYXV0b3Bsb3QocHJjb21wKElDUE1TLmFsbC4yMDE1Lmp1dmRhdC52YWwudHJhbnMpLCAKICAgICAgICAgZGF0YSA9IElDUE1TLmFsbC4yMDE1Lmp1dmRhdC5lbnYyLCAKICAgICAgICAgY29sb3VyID0gIlNpdGUiLAogICAgICAgICBzaGFwZT0iQ29ycmVjdCIsCiAgICAgICAgIGxvYWRpbmdzID0gVFJVRSwKICAgICAgICAgbG9hZGluZ3MubGFiZWwgPSBUUlVFLAogICAgICAgICBmcmFtZSA9IFRSVUUsIAogICAgICAgICBmcmFtZS50eXBlID0gJ25vcm0nKSsKICB0aGVtZV9idygpCmBgYAoKT3ZlcmFsbCwgd2UgbGVhcm4gdGhhdCBzb3VyY2Ugc3BlY2lmaWMgYW5kIHVuaXZlcnNhbCBjby12YXJpYW5jZSBtYXRyaWNlcyBwcm9kdWNlIG1hcmdpbmFsbHkgYmV0dGVyIElNTSByZXN1bHRzIHdoZW4gYXNzaWduaW5nIGxhcnZhZSwgYnV0IHRoYXQgdGhlIGdyZWF0ZXN0IGluZmx1ZW5jZSBvbiBJTU0gbWlzY2xhc3NpZmljYXRpb25zIGlzIHNvdXJjZS1zcGVjaWZpYyBnZW9jaGVtaXN0cnku