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:
- The Identity Matrix for all sources
- Source Specific Co-variance Matrices for baseline sources, and then the Identity Matrix for extra sources
- Source Specific Co-variance Matrices for baseline sources, and then the Universal Co-variance Matrix for extra sources
- The Universal Co-variance Matrix for all sources
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