Introduction
Clinical trial designs and analyses have generally favoured frequentist to Bayesian methods. However, Bayesian approaches are used, particularly in rare-diseases and the early trial phases, where sample sizes are generally small. For instance, when statistical models are used for dose-finding studies, Bayesian approaches are generally preferred. Two notable examples are the Continual Reassessment Method (CRM) by O’Quigley et al. (1990) and EffTox by Thall & Cook (2004).
One of the perennial challenges to implementing Bayesian methods in trials has been availability of software. Both of the methods mentioned above are supported by software (discussed below) but some other examples are not. The introduction of Stan has presented a welcome opportunity for a package of Bayesian clinical trial designs, implemented with a common look-and-feel in a state-of-the-art environment for Bayesian inference. trialr aims to do exactly that.
In this notebook, we walk through the CRM and EffTox designs for dose-finding implemented in Stan by trialr, and highlight some inferences that are facilitated by the posterior samples generated by rstan.
Dose-finding in a cytotoxic drug by the Continual Reassessment Method
The CRM (O’Quigley, Pepe & Fisher, 1990) is a design for conducting dose-finding trials that seek a maximum tolerable dose (MTD) in a cytotoxic drug. Chemotherapy is the classic example of a cytotoxic drug in that it kills cells, healthy and cancerous alike. A key assumption in this setting is that the probabilities of toxicity and efficacy increase monotonically with dose. The challenge to trialists is to maximise the opportunity for therapeutic benefit by escalating dose as high as possible, without arriving at a dose with undesirably high levels of toxicity. CRM has been a truly seminal design, with many variants appearing over the years to handle different clinical scenarios, such as efficacy and toxicity outcomes (Braun, 2002; Mandrekar et al., 2010), late-onset toxicity (Cheung & Chappell, 2000), drug combinations (Wages et al., 2011), and more.
Let \(x_i\) be a standardised dose-level. The probability of dose-limiting toxicity (DLT) at dose \(x_i\) is estimated to be \(F(x_i, \theta)\), where \(F\) is a smooth mathematical function, and \(\theta\) is a general vector of parameters. Even within this simple scenario, there are variants that use different forms for \(F\), and different distributions on \(\theta\). Four versions are currently implemented in trialr:
- the so-called empiric model (Cheung, 2011) with normal prior on the slope parameter;
- logistic model with fixed intercept and normal prior on the slope;
- logistic model with fixed intercept and gamma prior on the slope;
- logistic model with normal priors on the intercept and slope (Neuenschwander et al., 2008).
In the next section, we demonstrate the third of these with an example from the literature.
Example - Lévy et al. (2006)
Lévy et al. (2006) conducted a dose-finding trial of five doses of a drug called ssHHT in acute myeloid leukaemia patients. They use a one-parameter logistic CRM model:
\[F(x_i, \beta) = 1 / (1 + \exp{(-a_0 - \beta x_i)})\]
where a prior is specified on \(\beta\) and \(a_0\) is constant.
We are not told the exact values of the parameters used but we are told that software called BPCT is used to fit the model. From the publication that accompanies the software (Zohar, 2003), we learn that the software supports \(a_0 = 1, 2, 3\) or \(4\) and exponential or uniform priors on \(\beta\). Each of these priors ensures the slope is positive for increasing probabilities of toxicity. Through trial-and-error (not illustrated here), we discovered that \(a_0 = 4\) and an \(exponential(1)\) prior provide a close approximation to the posterior dose-toxicity curves they report. For illustration, we will replicate here their analysis for the end-of-trial dose-decision.
You will need to install the latest version of trialr from GitHub:
devtools::install_github('brockk/trialr')
Note: trial v0.0.1 on CRAN does not contain the CRM models but the latest github commit does. The package has dependencies including rstan and rstantools. In this tutorial, we will also assume that you have the tidyverse package installed.
Let us load trialr.
library(trialr)
Included in trial is a syntax for describing the outcomes of dose-finding trials using a character string. We use integers to represent the dose-levels given to patients or groups of patients. The Lévy trial investigated five doses so our possible dose-levels are 1, 2, 3, 4 or 5. We then string the letters T (for toxicity) and N (for no toxicity) to represent the outcomes for patients treated at that dose. These clusters of characters can be strewn together to represent the outcomes of many consecutive cohorts.
Using 6 cohorts of 3, they treated 18 patients at one of three doses and observed 5 DLTs (Table 1, Lévy et al., 2006):
| 1 |
1 |
1 |
0 |
| 2 |
1 |
1 |
0 |
| 3 |
1 |
1 |
0 |
| 4 |
2 |
3 |
0 |
| 5 |
2 |
3 |
0 |
| 6 |
2 |
3 |
1 |
| 7 |
3 |
4 |
0 |
| 8 |
3 |
4 |
0 |
| 9 |
3 |
4 |
1 |
| 10 |
4 |
4 |
0 |
| 11 |
4 |
4 |
0 |
| 12 |
4 |
4 |
0 |
| 13 |
5 |
4 |
0 |
| 14 |
5 |
4 |
1 |
| 15 |
5 |
4 |
0 |
| 16 |
6 |
4 |
1 |
| 17 |
6 |
4 |
0 |
| 18 |
6 |
4 |
1 |
They used the CRM model at the culmination of each cohort to suggest the dose for the next. Their outcomes can be represented in our syntax:
outcomes <- '1NNN 3NNT 4NNT 4NNN 4NTN 4TNT'
In CRM, the investigators must specify a skeleton, their prior beliefs on the probability of DLT at each dose, \(p_i = \text{Prob}({DLT}_i)\). This can be informed by pre-clinical studies or related clinical trials. The standardised doses are then solved to satisfy \(p_i = F(x_i, \theta_0)\), where \(\theta_0\) represents the prior parameter means. A full description is given by Cheung (2011). The investigators also specify a target toxicity rate, and this is largely driven by the clinical scenario. Lévy et al. chose:
skeleton <- c(0.05, 0.10, 0.15, 0.33, 0.5)
target <- 0.33
Fitting the model to the data:
mod1 <- stan_crm(outcomes, skeleton = skeleton, target = target,
model = 'logistic_gamma', a0 = 4,
beta_shape = 1, beta_inverse_scale = 1,
seed = 123, control = list(adapt_delta = 0.95))
The parameter model determines which CRM variant is fit to the data. Currently, it may take values:
empiric, for empiric model with normal prior on slope;
logistic, for one-parameter logistic model with normal prior on slope;
logistic_gamma, for one-parameter logistic model with gamma prior on slope;
logistic2, for two-parameter logistic model with normal priors on intercept and slope.
There is not a version explicitly for exponential priors; instead we exploit that \(exponential(1) \equiv gamma(1, 1)\). Different model variants require different parameters. The logistic-gamma model requires an intercept value \(a_0\) and two parameters for the gamma distribution. Parameters like seed and control are passed to rstan to control the sampling.
The returned crm_fit object contains useful summary information and implements S3 generic functions for convenient printing, for example:
mod1
Patient Dose Toxicity
1 1 1 0
2 2 1 0
3 3 1 0
4 4 3 0
5 5 3 0
6 6 3 1
7 7 4 0
8 8 4 0
9 9 4 1
10 10 4 0
11 11 4 0
12 12 4 0
13 13 4 0
14 14 4 1
15 15 4 0
16 16 4 1
17 17 4 0
18 18 4 1
DoseLevel Skeleton N Tox ProbTox ProbMTD
1 1 0.05 3 0 0.07598749 0.00650
2 2 0.10 0 0 0.13590569 0.04175
3 3 0.15 3 1 0.19060831 0.25825
4 4 0.33 12 4 0.36875770 0.52600
5 5 0.50 0 0 0.52691920 0.16750
The model targets a toxicity level of 0.33.
The dose with estimated toxicity probability closest to target is 4.
The dose most likely to be the MTD is 4.
ProbTox shows the posterior mean estimate of the probability of toxicity. The same values are accessible from the fit object:
mod1$prob_tox
[1] 0.07598749 0.13590569 0.19060831 0.36875770 0.52691920
These values are very close to the estimates given in Table 1 of Lévy et al. (2006). The CRM model suggests dose-level 4 has toxicity rate closest to the target of 33%.
Let’s visualise the posterior distributions. Plotting posterior dose-toxicity beliefs can be as simple as:
plot(mod1)
ci_level: 0.8 (80% intervals)
outer_level: 0.95 (95% intervals)

However, the underlying stanfit object containing the posterior samples is stored inside mod1 so all manner of visualisations are possible using ggplot2. For instance, a violin plot is a nice way of visualising this information:
library(magrittr)
library(ggplot2)
mod1 %>%
gather_samples.crm_fit %>%
ggplot(aes(x = DoseLevel, y = ProbTox, group = DoseLevel)) +
geom_violin(fill = 'orange') + ylim(0, 1) +
geom_hline(yintercept = target, col = 'red', linetype = 'dashed') +
labs(title = 'Pr(Toxicity) after 18 patients in Levy, et al. (2006)')

The dashed red line shows the target toxicity rate.
After these 18 patients, the investigators stopped the trial according to pre-specified stopping rules, recommending dose-level 4 for further investigation. The manuscript explains that the stopping rules scrutinised the estimated toxicity probability at the proposed dose and the precision of that estimate based on credible intervals. We can see from the plot above that dose-level 4 is much more plausible than neighbouring doses.
Another way of viewing the above information is to overplot many of the sampled dose-toxicity curves:
library(dplyr)
mod1 %>%
gather_samples.crm_fit %>%
filter(Draw <= 1000) %>%
ggplot(aes(x = DoseLevel, y = ProbTox, group = Draw)) +
geom_line(alpha = 0.03, col = 'orange') + ylim(0, 1) +
geom_hline(yintercept = target, col = 'red', linetype = 'dashed') +
labs(title = 'Sampled dose-toxicity curves after 18 patients in Levy, et al. (2006)')

A direct Bayesian way of quantifying our motivation to continue the trial or stop is to estimate the probability that each dose is the true MTD, i.e. by effectively calculating the dose closest to 33% in each of the sampled dose-toxicity curves above. This is calculated when the model is fit:
mod1$prob_mtd
[1] 0.00650 0.04175 0.25825 0.52600 0.16750
We see that 53% of curves advocate choosing dose-level 4, implying that this dose is more likely than not to be the MTD, given the stated prior beliefs and the observed trial data. The trialists’ decision to stop here was perhaps prescient because this was the first occasion in the trial after the first cohort that this condition was met.
Dose-finding by efficacy and toxicity outcomes using EffTox
Thall & Cook (2004) introduced the EffTox design for dose-finding in scenarios where both efficacy and toxicity events should guide dose selection. This is in contrast to methods like CRM where dose selection is determined by toxicity events only. This embellishment has become increasingly pertinent in recent years with the introduction of so-called cytostatic drugs like immunotherapies, which can exhibit non-monotonically-increasing efficacy by dose (e.g. Garon et al., 2015) In such a scenario, to escalate dose seeking a target level of toxicity would be an expensive mistake. We provide a brief recap of EffTox here, but full details are given in Thall (2004), Thall et al. (2006), and Thall et al. (2014).
For doses \(\boldsymbol{y} = (y_1, ..., y_n)\), the authors define doses \((x_1, ..., x_n)\) standardised by the geometric mean:
\(x_i = \log{y_i} - \sum_{j=1}^n \frac{\log{y_j}}{n}\)
The \(x_i\) are used as the sole explanatory variables in logit models for the marginal probabilities of toxicity and efficacy:
\(\text{logit } \pi_T = \alpha + \beta x\)
\(\text{logit } \pi_E = \gamma + \zeta x + \eta x^2\)
The presence of the quadratic term allows for non-linearity and potentially a turning point in the dose-efficacy relationship.
The joint probability of these two events is modelled using the Gumbel model:
\(\pi_{a,b} = (\pi_E)^a (1-\pi_E)^{1-a} (\pi_T)^b (1-\pi_T)^{1-b} + (-1)^{a+b} (\pi_E) (1-\pi_E) (\pi_T) (1-\pi_T) \frac{e^\psi-1}{e^\psi+1}\).
For a given patient, \(a=1\) implies that a patient experienced the efficacy event, and \(a=0\) implies they did not; \(b\) performs the analogous function for the toxicity event. The \(\psi\) parameter facilitates an association between efficacy and toxicity events. The fraction term involving \(\psi\) takes values on \((-1, 1)\) for real-valued \(\psi\). It is desirable that the possibility for association between the co-primary outcomes is present in the model to reflect potential clinical relationships. If a treatment is so toxic that patients discontinue, their potential to receive clinical benefit is naturally hindered. In contrast for some treatments, toxicity and efficacy are seen as two effects of some common mechanism of action. For instance, with stem-cell transplants, the presence of some toxicity like moderate graft-versus-host disease is taken as evidence that anti-tumour activity is also occurring
Normal priors are specified for the elements of the parameter vector \(\boldsymbol{\theta} = (\alpha, \beta, \gamma, \zeta, \eta, \psi)\). Thall et al. (2014) detail an algorithm to specify priors on the elements of \(\boldsymbol{\theta}\) that convey expected probabilities of efficacy and toxicity at the doses (analogous to the toxicity skeleton in the CRM example) that jointly contain information equal to an effective sample size. Note that this algorithm is implemented in the MD Anderson EffTox software (detailed below) but not yet implemented in trialr.
At each dose update decision, the dose \(x\) is acceptable if
\(\text{Pr}\left\{ \pi_T(x, \boldsymbol{\theta}) < \overline{\pi}_T | \mathcal{D} \right\} > p_T\)
and
\(\text{Pr}\left\{ \pi_E(x, \boldsymbol{\theta}) > \underline{\pi}_E | \mathcal{D} \right\} > p_E\)
\(\underline{\pi}_E, p_E, \overline{\pi}_T, p_T\) are provided by the investigators as the clinical scenario dictates. These criteria ensure that the doses considered for allocation to patients are sufficiently efficacious and tolerable. Ineffective or toxic doses are excluded. Furthermore, the design requires that untried doses are not skipped in escalation or de-escalation. That is, only doses that are no more than one position below the lowest dose-level already given and no more than one position above the highest dose-level already given are considered.
The utility of dose \(x\), with efficacy \(\pi_E(x, \boldsymbol{\theta})\) and toxicity \(\pi_T(x, \boldsymbol{\theta})\) is
\(u(\pi_E, \pi_T) = 1 - \left( \left(\frac{1-\pi_E}{1-\pi_{1,E}^*}\right)^p + \left(\frac{\pi_T}{\pi_{2,T}^*}\right)^p \right) ^ \frac{1}{p}\)
where \(p\) is calculated to intersect the points \((\pi_{1,E}^*, 0)\), \((1, \pi_{2,T}^*)\) and \((\pi_{3,E}^*, \pi_{3,T}^*)\). We will refer to these as hinge points but that is not nomenclature used by the authors. \(\pi_{1,E}^*\) is the rate of efficacy that is acceptable if toxicity is impossible. \(\pi_{2,T}^*\) is the rate of toxicity that is acceptable if efficacy is guaranteed. The third hinge point is selected in the general \((0, 1) \times (0, 1)\) prob(efficacy)-prob(toxicity) plain that is equally attractive as the other two hinge points. The three hinge points lay on the neutral utility contour where \(u(\pi_E, \pi_T) = 0\). The equations \(u(\pi_{1,E}^*, 0) = u(1, \pi_{2,T}^*) = u(\pi_{3,E}^*, \pi_{3,T}^*) = 0\) are solved to identify the curvature parameter, \(p\), for a family of curves that are parallel to the neutral contour. As the curves approach the point \((1, 0)\), the utility scores increase, and vice-versa.
At the dose selection decision, the dose-level from the acceptable set with maximal utility is selected to be given to the next patient or cohort. If there are no acceptable doses, the trial stops and no dose is recommended.
Example - Thall et al. (2014).
We will illustrate EffTox using the advanced prostate cancer example in Thall et al. (2014). They investigate the five doses 1, 2, 4, 6.6 and 10 mcL/kg, seeking the best dose with
\(\text{Pr}\left\{ \pi_T(x, \boldsymbol{\theta}) < 0.3 | \mathcal{D} \right\} > 0.1\)
and
\(\text{Pr}\left\{ \pi_E(x, \boldsymbol{\theta}) > 0.5 | \mathcal{D} \right\} > 0.1\)
Thus, we have \(p_T = p_E = 0.1, \overline{\pi}_T = 0.3\) and \(\underline{\pi}_E = 0.5\).
Similar to above, trialr implements a syntax for describing outcomes in phase I/II dose-finding designs like EffTox. We use the letters E to denote an outcome of efficacy only, T to denote toxicity only, B for both and N for neither. As before, we string these characters behind numerical dose-levels to represent the outcomes of patients in sequential dose cohorts. This method was first described in Brock et al. (2017).
For demonstration, we consider a scenario where two cohorts of three patients have been evaluated:
| 1 |
1 |
1 |
0 |
0 |
| 2 |
1 |
1 |
0 |
1 |
| 3 |
1 |
1 |
0 |
0 |
| 4 |
2 |
2 |
0 |
0 |
| 5 |
2 |
2 |
1 |
1 |
| 6 |
2 |
2 |
0 |
1 |
Using our syntax, these outcomes can be described:
outcomes <- '1NEN 2NBE'
The parameterisation for this advanced prostate cancer example is loaded by default in the MD Anderson EffTox app. The model can be fit to the observed outcomes in trialr using:
mod2 <- stan_efftox_demo(outcomes, seed = 123)
This is simply short-hand for:
mod2 <- stan_efftox(outcomes,
real_doses = c(1.0, 2.0, 4.0, 6.6, 10.0),
efficacy_hurdle = 0.5, toxicity_hurdle = 0.3,
p_e = 0.1, p_t = 0.1,
eff0 = 0.5, tox1 = 0.65,
eff_star = 0.7, tox_star = 0.25,
alpha_mean = -7.9593, alpha_sd = 3.5487,
beta_mean = 1.5482, beta_sd = 3.5018,
gamma_mean = 0.7367, gamma_sd = 2.5423,
zeta_mean = 3.4181, zeta_sd = 2.4406,
eta_mean = 0, eta_sd = 0.2,
psi_mean = 0, psi_sd = 1,
seed = 123)
Once again, parameters like seed etc are passed onwards to rstan::sampling. Please refer to Thall et al. (2014) for information on their priors.
The returned efftox_fit object also implements the generics print, plot, summary and as.data.frame.
mod2
Patient Dose Toxicity Efficacy
1 1 1 0 0
2 2 1 0 1
3 3 1 0 0
4 4 2 0 0
5 5 2 1 1
6 6 2 0 1
DoseLevel ProbEff ProbTox ProbAccEff ProbAccTox Utility Acceptable
1 1 0.3085323 0.08950037 0.18150 0.91725 -0.53154452 TRUE
2 2 0.6313915 0.10047276 0.76900 0.92100 0.09855067 TRUE
3 3 0.8342243 0.21505880 0.92375 0.72775 0.32686871 TRUE
4 4 0.8851502 0.30421263 0.93500 0.63025 0.29194532 FALSE
5 5 0.9045053 0.35935675 0.93700 0.58125 0.24623236 FALSE
The model recommends selecting dose-level 3.
We see that dose-levels 1 to 3 are acceptable because they satisfy the acceptability criteria. Dose-level 3 is recommended because it is the acceptable dose with the highest utility value. Dose-levels 4 and 5 are unacceptable. This is because dose-level 3 has not yet been given. No doses are inferred to be too toxic or inefficacious yet.
Slots in the returned fit contain the pertinent information:
mod2$recommended_dose
[1] 3
mod2$prob_eff
[1] 0.3085323 0.6313915 0.8342243 0.8851502 0.9045053
The default plot method shows the posterior distribution of the utility scores:
plot(mod2)
ci_level: 0.8 (80% intervals)
outer_level: 0.95 (95% intervals)

We can produce more specialised plots, like a plot of the utility contours and our posterior beliefs:
efftox_contour_plot(mod2$dat, prob_eff = mod2$prob_eff,
prob_tox = mod2$prob_tox, use_ggplot = TRUE) +
ggtitle('EffTox utility contours')

The blue triangles show the location of the hinge points. The red numbers show the posterior means of the five dose-levels. Doses that are closer to the lower-right corner have higher utility. We see that dose-level 3 has the highest utility, but only just.
We can also produce posterior density plots of the dose utilities. For illustration, we will just plot the densities of the three highest doses.
mod2 %>%
gather_samples.efftox_fit('utility') %>%
filter(DoseLevel %in% 3:5) %>%
ggplot(aes(x = Value, group = DoseLevel)) +
geom_density(aes(fill = as.factor(DoseLevel))) +
labs(fill = 'Dose', title = 'EffTox dose utility densities')

The three posterior distributions are largely coincident, highlighting the lack of certainty at this early stage in the trial. To further facilitate the analysis of dose utility, we provide means of calculating the dose superiority matrix.
knitr::kable(efftox_superiority(mod2$fit), digits = 2, row.names = TRUE)
| 1 |
NA |
0.92 |
0.86 |
0.82 |
0.80 |
| 2 |
0.08 |
NA |
0.75 |
0.68 |
0.64 |
| 3 |
0.14 |
0.25 |
NA |
0.58 |
0.54 |
| 4 |
0.18 |
0.32 |
0.42 |
NA |
0.52 |
| 5 |
0.20 |
0.36 |
0.46 |
0.48 |
NA |
The element in row \(i\) and column \(j\) shows \(\text{Prob(}u_j > u_i | \text{data)}\), where \(u_k\) is the utility of dose \(k\). We can be quite confident that dose 3 has higher utility than doses 1 and 2. In contrast, the model is much more vague about which is the superior of doses 3, 4 and 5. That is plenty of motivation to continue the clinical trial.
Discussion
In CRM, prior information is conveyed not just through prior distributions on the parameters. When using a CRM design, the trialists specify their initial guesses for the dose-prob(toxicity) relationship, referred to as the skeleton, and this object conveys material prior information. This information is typically informed by data on this drug in other patient groups, similar drugs in this or related patient groups, and pre-clinical data. The provision of prior information is desirable, for example, when you consider that appropriate dose selections must be made at all times yet a dose-finding trial design will typically be invoked on a very small amount of data. In early cohorts, dose selections are driven materially by investigators’ prior beliefs. In latter cohorts when more data is available, the decisions should increasingly be driven by the observed outcomes. The goal is a parameterisation that will be expected to perform well whether the investigators’ prior beliefs are correct or not. Thus, simulation studies are generally used to derive a design that delivers acceptable operating characteristics over a range of scenarios. Methods for conducting CRM simuation studies are not currently provided in trialr but will be added in future.
In the Levy CRM example, the intercept was fixed. This is a fairly strong constraint on the model. Some authors including Neuenschwander et al. (2008) have advocated a two-parameter model because it is more flexible. However, the lead author of CRM is critical of this approach:
Although a two-parameter model may appear more flexible, the convergence property of CRM means that ultimately we will not obtain information needed to fit two parameters. (O’Quigley et al. , 2013)
, advocating the single parameter approach instead. There are examples of both in the literature and variants of each are provided in trialr.
In many instances, cancer patients receive a combination of drugs to combat their disease. Often, a new drug is experimentally added to an established standard of care and the dose-finding scenario can be approached in one of two ways. Where the dose of the standard therapy is regarded as fixed, a dose for the new therapy to be given in combination with the standard therapy is sought, effectively making the dose-finding exercise a one-dimensional problem. In this setting, designs like CRM are helpful. In contrast, if the dose of more than one drug is to be varied in pursuit of a tolerable combination, dose-finding methods for drug combinations are required. There are variants of this approach that have arisen from the CRM (e.g. Wages et al., 2011) and others that have arisen independently (e.g. Mander & Sweeting, 2015).
It is important to stress that dose-finding clinical trial designs are merely statistical tools that provide insight and imply recommendations. They are not robots that decide what dose a patient will receive; the physician and the patient retain that responsibility. When assessing dose escalation and de-escalation, trialists typically consider many factors like the nature of the specific patient population, laboratory test values, biomarkers and overall adverse event profile in addition to the presence or absence of formal dose-limiting toxicity. Dose escalation is not undertaken just because it is advocated by a model. That said, statistical dose-finding designs have an important role to play in the efficient analysis of outcomes and the promotion of rational decision making. In this regard, they are superior to rule-based designs like 3+3 that have little statistical justification.
trialr
Software is available from https://github.com/brockk/trialr It is currently under development. The introduction of rstanarm and brms have perhaps removed the need to pre-compile many experimental designs. This package will continue to focus on implementing Bayesian clinical trial designs, particularly those with non-standard likelihood functions or those that are non-trivial to implement in rstanarm and brms.
Alternative software
CRM
There are several R-packages that implement CRM:
dfcrm uses numerical integration to estimate posterior parameter means, and plugs those into \(F\) to estimate the expected Prob(DLT). This package does not use MCMC or produce posterior draws. This package accompanies the book by Cheung (2011).
bcrm uses numerical integration or MCMC via BUGS or JAGS to fit the model.
crmPack is more recent than the other two and appears to be very comprehensive. It too offers MCMC sampling via BUGS and JAGS.
To our knowledge, trialr is the first to implement CRM in Stan.
EffTox
EffTox software is available from the MD Anderson website. It is a .Net application so only runs on Windows. Source-code is not generally available, but I have never requested it. I was motivated to create an open-source implementation of EffTox whilst working on a trial that used the design (Brock et al., 2017). Situations arose where we wanted to adjust the behaviour of the design.
To our knowledge, trialr is the first to implement EffTox in R or Stan.
Acknowledgements
We extend sincere thanks to the two anonymous reviewers for their valuable suggestions.
References
Braun, T. M. (2002). The bivariate continual reassessment method: Extending the CRM to phase I trials of two competing outcomes. Controlled Clinical Trials, 23(3), 240–256. https://doi.org/10.1016/S0197-2456(01)00205-7
Brock, K., Billingham, L., Copland, M., Siddique, S., Sirovica, M., & Yap, C. (2017). Implementing the EffTox dose-finding design in the Matchpoint trial. BMC Medical Research Methodology, 17(1), 112. https://doi.org/10.1186/s12874-017-0381-x
Cheung, Y. K. (2011). Dose Finding by the Continual Reassessment Method. New York: Chapman & Hall / CRC Press.
Cheung, Y. K., & Chappell, R. (2000). Sequential designs for phase I clinical trials with late-onset toxicities. Biometrics, 56(4), 1177–1182.
Garon, E. B., Rizvi, N. a, Hui, R., Leighl, N., Balmanoukian, A. S., Eder, J. P., … KEYNOTE-001 Investigators. (2015). Pembrolizumab for the treatment of non-small-cell lung cancer. The New England Journal of Medicine, 372(21), 2018–28. https://doi.org/10.1056/NEJMoa1501824
Lévy, V., Zohar, S., Bardin, C., Vekhoff, A., Chaoui, D., Rio, B., … Marie, J. P. (2006). A phase I dose-finding and pharmacokinetic study of subcutaneous semisynthetic homoharringtonine (ssHHT) in patients with advanced acute myeloid leukaemia. British Journal of Cancer, 95(3), 253–259. https://doi.org/10.1038/sj.bjc.6603265
Mander, A. P., & Sweeting, M. J. (2015). A product of independent beta probabilities dose escalation design for dual-agent phase I trials. Statistics in Medicine. https://doi.org/10.1002/sim.6434
Mandrekar, S. J., Qin, R., & Sargent, D. J. (2010). Model-based phase I designs incorporating toxicity and efficacy for single and dual agent drug combinations: Methods and challenges. Statistics in Medicine, 29(10), 1077–1083. https://doi.org/10.1002/sim.3706
Neuenschwander, B., Branson, M., & Gsponer, T. (2008). Critical aspects of the Bayesian approach to phase I cancer trials. Statistics in Medicine, 27(13), 2420–2439. https://doi.org/10.1002/sim.3230
O’Quigley, J., Pepe, M., & Fisher, L. (1990). Continual reassessment method: a practical design for phase 1 clinical trials in cancer. Biometrics, 46(1), 33–48. https://doi.org/10.2307/2531628
O’Quigley, J., & Conaway, M. (2011). Continual Reassessment and Related Dose-Finding Designs. Statistical Science, 25(2), 202–216. https://doi.org/10.1214/10-STS332.Continual
Thall, P., & Cook, J. (2004). Dose-Finding Based on Efficacy-Toxicity Trade-Offs. Biometrics, 60(3), 684–693.
Thall, P., Cook, J., & Estey, E. (2006). Adaptive dose selection using efficacy-toxicity trade-offs: illustrations and practical considerations. Journal of Biopharmaceutical Statistics, 16(5), 623–638. https://doi.org/10.1080/10543400600860394
Thall, P., Herrick, R., Nguyen, H., Venier, J., & Norris, J. (2014). Effective sample size for computing prior hyperparameters in Bayesian phase I-II dose-finding. Clinical Trials, 11(6), 657–666. https://doi.org/10.1177/1740774514547397
Wages, N. A., Conaway, M. R., & O’Quigley, J. (2011). Dose-finding design for multi-drug combinations. Clinical Trials (London, England), 8(4), 380–389. https://doi.org/10.1177/1740774511408748
Zohar, S., Latouche, A., Taconnet, M., & Chevret, S. (2003). Software to compute and conduct sequential Bayesian phase I or II dose-ranging clinical trials with stopping rules. Computer Methods and Programs in Biomedicine, 72(2), 117–125. https://doi.org/10.1016/S0169-2607(02)00120-7
Session Info
sessionInfo()
R version 3.5.0 (2018-04-23)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS High Sierra 10.13.5
Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.5/Resources/lib/libRlapack.dylib
locale:
[1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] trialr_0.0.2 Rcpp_0.12.17 dplyr_0.7.5 magrittr_1.5 rstan_2.17.3
[6] StanHeaders_2.17.2 ggplot2_2.2.1
loaded via a namespace (and not attached):
[1] pillar_1.2.2 compiler_3.5.0 plyr_1.8.4 bindr_0.1.1 base64enc_0.1-3
[6] tools_3.5.0 digest_0.6.15 jsonlite_1.5 evaluate_0.10.1 tibble_1.4.2
[11] gtable_0.2.0 pkgconfig_2.0.1 rlang_0.2.1 yaml_2.1.19 parallel_3.5.0
[16] loo_2.0.0 bindrcpp_0.2.2 gridExtra_2.3 stringr_1.3.1 knitr_1.20
[21] rprojroot_1.3-2 stats4_3.5.0 grid_3.5.0 tidyselect_0.2.4 inline_0.3.14
[26] glue_1.2.0 R6_2.2.2 rmarkdown_1.10 purrr_0.2.5 backports_1.1.2
[31] scales_0.5.0 codetools_0.2-15 matrixStats_0.53.1 htmltools_0.3.6 rstantools_1.5.0
[36] rsconnect_0.8.8 assertthat_0.2.0 colorspace_1.3-2 stringi_1.2.3 lazyeval_0.2.1
[41] munsell_0.4.3
LS0tCnRpdGxlOiAiRG9zZS1maW5kaW5nIGNsaW5pY2FsIHRyaWFsIGRlc2lnbnMgaW4gU3RhbiB3aXRoIGB0cmlhbHJgIgphdXRob3I6IHwKICB8IEtyaXN0aWFuIEJyb2NrLCBrcmlzdGlhbi5icm9ja0BnbWFpbC5jb20KICB8IENhbmNlciBSZXNlYXJjaCBVSyBDbGluaWNhbCBUcmlhbHMgVW5pdCwgVW5pdmVyc2l0eSBvZiBCaXJtaW5naGFtLCBVSwpkYXRlOiAxMi1KdWwtMjAxOApvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojIEludHJvZHVjdGlvbgpDbGluaWNhbCB0cmlhbCBkZXNpZ25zIGFuZCBhbmFseXNlcyBoYXZlIGdlbmVyYWxseSBmYXZvdXJlZCBmcmVxdWVudGlzdCB0byBCYXllc2lhbiBtZXRob2RzLgpIb3dldmVyLCBCYXllc2lhbiBhcHByb2FjaGVzIGFyZSB1c2VkLCBwYXJ0aWN1bGFybHkgaW4gcmFyZS1kaXNlYXNlcyBhbmQgdGhlIGVhcmx5IHRyaWFsIHBoYXNlcywgd2hlcmUgIHNhbXBsZSBzaXplcyBhcmUgZ2VuZXJhbGx5IHNtYWxsLgpGb3IgaW5zdGFuY2UsIHdoZW4gc3RhdGlzdGljYWwgbW9kZWxzIGFyZSB1c2VkIGZvciBkb3NlLWZpbmRpbmcgc3R1ZGllcywgQmF5ZXNpYW4gYXBwcm9hY2hlcyBhcmUgZ2VuZXJhbGx5IHByZWZlcnJlZC4KVHdvIG5vdGFibGUgZXhhbXBsZXMgYXJlIHRoZSBDb250aW51YWwgUmVhc3Nlc3NtZW50IE1ldGhvZCAoQ1JNKSBieSBPJ1F1aWdsZXkgX2V0IGFsLl8gKDE5OTApIGFuZCBFZmZUb3ggYnkgVGhhbGwgJiBDb29rICgyMDA0KS4KCk9uZSBvZiB0aGUgcGVyZW5uaWFsIGNoYWxsZW5nZXMgdG8gaW1wbGVtZW50aW5nIEJheWVzaWFuIG1ldGhvZHMgaW4gdHJpYWxzIGhhcyBiZWVuIGF2YWlsYWJpbGl0eSBvZiBzb2Z0d2FyZS4KQm90aCBvZiB0aGUgbWV0aG9kcyBtZW50aW9uZWQgYWJvdmUgYXJlIHN1cHBvcnRlZCBieSBzb2Z0d2FyZSAoZGlzY3Vzc2VkIGJlbG93KSBidXQgc29tZSBvdGhlciBleGFtcGxlcyBhcmUgbm90LgpUaGUgaW50cm9kdWN0aW9uIG9mIFN0YW4gaGFzIHByZXNlbnRlZCBhIHdlbGNvbWUgb3Bwb3J0dW5pdHkgZm9yIGEgcGFja2FnZSBvZiBCYXllc2lhbiBjbGluaWNhbCB0cmlhbCBkZXNpZ25zLCBpbXBsZW1lbnRlZCB3aXRoIGEgY29tbW9uIGxvb2stYW5kLWZlZWwgaW4gYSBzdGF0ZS1vZi10aGUtYXJ0IGVudmlyb25tZW50IGZvciBCYXllc2lhbiBpbmZlcmVuY2UuCltgdHJpYWxyYF0oaHR0cHM6Ly9naXRodWIuY29tL2Jyb2Nray90cmlhbHIpIGFpbXMgdG8gZG8gZXhhY3RseSB0aGF0LgoKSW4gdGhpcyBub3RlYm9vaywgd2Ugd2FsayB0aHJvdWdoIHRoZSBDUk0gYW5kIEVmZlRveCBkZXNpZ25zIGZvciBkb3NlLWZpbmRpbmcgaW1wbGVtZW50ZWQgaW4gU3RhbiBieSBgdHJpYWxyYCwgYW5kIGhpZ2hsaWdodCBzb21lIGluZmVyZW5jZXMgdGhhdCBhcmUgZmFjaWxpdGF0ZWQgYnkgdGhlIHBvc3RlcmlvciBzYW1wbGVzIGdlbmVyYXRlZCBieSBgcnN0YW5gLiAKCgojIERvc2UtZmluZGluZyBpbiBhIGN5dG90b3hpYyBkcnVnIGJ5IHRoZSBDb250aW51YWwgUmVhc3Nlc3NtZW50IE1ldGhvZApUaGUgQ1JNIChPJ1F1aWdsZXksIFBlcGUgJiBGaXNoZXIsIDE5OTApIGlzIGEgZGVzaWduIGZvciBjb25kdWN0aW5nIGRvc2UtZmluZGluZyB0cmlhbHMgdGhhdCBzZWVrIGEgX21heGltdW0gdG9sZXJhYmxlIGRvc2VfIChNVEQpIGluIGEgY3l0b3RveGljIGRydWcuCkNoZW1vdGhlcmFweSBpcyB0aGUgY2xhc3NpYyBleGFtcGxlIG9mIGEgY3l0b3RveGljIGRydWcgaW4gdGhhdCBpdCBraWxscyBjZWxscywgaGVhbHRoeSBhbmQgY2FuY2Vyb3VzIGFsaWtlLgpBIGtleSBhc3N1bXB0aW9uIGluIHRoaXMgc2V0dGluZyBpcyB0aGF0IHRoZSBwcm9iYWJpbGl0aWVzIG9mIHRveGljaXR5IGFuZCBlZmZpY2FjeSBpbmNyZWFzZSBtb25vdG9uaWNhbGx5IHdpdGggZG9zZS4KVGhlIGNoYWxsZW5nZSB0byB0cmlhbGlzdHMgaXMgdG8gbWF4aW1pc2UgdGhlIG9wcG9ydHVuaXR5IGZvciB0aGVyYXBldXRpYyBiZW5lZml0IGJ5IGVzY2FsYXRpbmcgZG9zZSBhcyBoaWdoIGFzIHBvc3NpYmxlLCB3aXRob3V0IGFycml2aW5nIGF0IGEgZG9zZSB3aXRoIHVuZGVzaXJhYmx5IGhpZ2ggbGV2ZWxzIG9mIHRveGljaXR5LgpDUk0gaGFzIGJlZW4gYSB0cnVseSBzZW1pbmFsIGRlc2lnbiwgd2l0aCBtYW55IHZhcmlhbnRzIGFwcGVhcmluZyBvdmVyIHRoZSB5ZWFycyB0byBoYW5kbGUgZGlmZmVyZW50IGNsaW5pY2FsIHNjZW5hcmlvcywgc3VjaCBhcyBlZmZpY2FjeSBhbmQgdG94aWNpdHkgb3V0Y29tZXMgKEJyYXVuLCAyMDAyOyBNYW5kcmVrYXIgX2V0IGFsLl8sIDIwMTApLCBsYXRlLW9uc2V0IHRveGljaXR5IChDaGV1bmcgJiBDaGFwcGVsbCwgMjAwMCksIGRydWcgY29tYmluYXRpb25zIChXYWdlcyBfZXQgYWwuXywgMjAxMSksIGFuZCBtb3JlLgoKTGV0ICR4X2kkIGJlIGEgc3RhbmRhcmRpc2VkIGRvc2UtbGV2ZWwuIApUaGUgcHJvYmFiaWxpdHkgb2YgX2Rvc2UtbGltaXRpbmcgdG94aWNpdHlfIChETFQpIGF0IGRvc2UgJHhfaSQgaXMgZXN0aW1hdGVkIHRvIGJlICRGKHhfaSwgXHRoZXRhKSQsIHdoZXJlICRGJCBpcyBhIHNtb290aCBtYXRoZW1hdGljYWwgZnVuY3Rpb24sIGFuZCAkXHRoZXRhJCBpcyBhIGdlbmVyYWwgdmVjdG9yIG9mIHBhcmFtZXRlcnMuCkV2ZW4gd2l0aGluIHRoaXMgc2ltcGxlIHNjZW5hcmlvLCB0aGVyZSBhcmUgdmFyaWFudHMgdGhhdCB1c2UgZGlmZmVyZW50IGZvcm1zIGZvciAkRiQsIGFuZCBkaWZmZXJlbnQgZGlzdHJpYnV0aW9ucyBvbiAkXHRoZXRhJC4KRm91ciB2ZXJzaW9ucyBhcmUgY3VycmVudGx5IGltcGxlbWVudGVkIGluIGB0cmlhbHJgOgoKLSB0aGUgc28tY2FsbGVkIF9lbXBpcmljXyBtb2RlbCAoQ2hldW5nLCAyMDExKSB3aXRoIG5vcm1hbCBwcmlvciBvbiB0aGUgc2xvcGUgcGFyYW1ldGVyOwotIGxvZ2lzdGljIG1vZGVsIHdpdGggZml4ZWQgaW50ZXJjZXB0IGFuZCBub3JtYWwgcHJpb3Igb24gdGhlIHNsb3BlOwotIGxvZ2lzdGljIG1vZGVsIHdpdGggZml4ZWQgaW50ZXJjZXB0IGFuZCBnYW1tYSBwcmlvciBvbiB0aGUgc2xvcGU7Ci0gbG9naXN0aWMgbW9kZWwgd2l0aCBub3JtYWwgcHJpb3JzIG9uIHRoZSBpbnRlcmNlcHQgYW5kIHNsb3BlIChOZXVlbnNjaHdhbmRlciBfZXQgYWwuXywgMjAwOCkuCgpJbiB0aGUgbmV4dCBzZWN0aW9uLCB3ZSBkZW1vbnN0cmF0ZSB0aGUgdGhpcmQgb2YgdGhlc2Ugd2l0aCBhbiBleGFtcGxlIGZyb20gdGhlIGxpdGVyYXR1cmUuCgojIyMgRXhhbXBsZSAtIEzDqXZ5IF9ldCBhbC5fICgyMDA2KSAKTMOpdnkgX2V0IGFsLl8gKDIwMDYpIGNvbmR1Y3RlZCBhIGRvc2UtZmluZGluZyB0cmlhbCBvZiBmaXZlIGRvc2VzIG9mIGEgZHJ1ZyBjYWxsZWQgc3NISFQgaW4gYWN1dGUgbXllbG9pZCBsZXVrYWVtaWEgcGF0aWVudHMuClRoZXkgdXNlIGEgb25lLXBhcmFtZXRlciBsb2dpc3RpYyBDUk0gbW9kZWw6CgokJEYoeF9pLCBcYmV0YSkgPSAxIC8gKDEgKyBcZXhweygtYV8wIC0gXGJldGEgeF9pKX0pJCQKCndoZXJlIGEgcHJpb3IgaXMgc3BlY2lmaWVkIG9uICRcYmV0YSQgYW5kICRhXzAkIGlzIGNvbnN0YW50LgoKV2UgYXJlIG5vdCB0b2xkIHRoZSBleGFjdCB2YWx1ZXMgb2YgdGhlIHBhcmFtZXRlcnMgdXNlZCBidXQgd2UgYXJlIHRvbGQgdGhhdCBzb2Z0d2FyZSBjYWxsZWQgX0JQQ1RfIGlzIHVzZWQgdG8gZml0IHRoZSBtb2RlbC4KRnJvbSB0aGUgcHVibGljYXRpb24gdGhhdCBhY2NvbXBhbmllcyB0aGUgc29mdHdhcmUgKFpvaGFyLCAyMDAzKSwgd2UgbGVhcm4gdGhhdCB0aGUgc29mdHdhcmUgc3VwcG9ydHMgJGFfMCA9IDEsIDIsIDMkIG9yICQ0JCBhbmQgZXhwb25lbnRpYWwgb3IgdW5pZm9ybSBwcmlvcnMgb24gJFxiZXRhJC4KRWFjaCBvZiB0aGVzZSBwcmlvcnMgZW5zdXJlcyB0aGUgc2xvcGUgaXMgcG9zaXRpdmUgZm9yIGluY3JlYXNpbmcgcHJvYmFiaWxpdGllcyBvZiB0b3hpY2l0eS4KVGhyb3VnaCB0cmlhbC1hbmQtZXJyb3IgKG5vdCBpbGx1c3RyYXRlZCBoZXJlKSwgd2UgZGlzY292ZXJlZCB0aGF0ICRhXzAgPSA0JCBhbmQgYW4gJGV4cG9uZW50aWFsKDEpJCBwcmlvciBwcm92aWRlIGEgY2xvc2UgYXBwcm94aW1hdGlvbiB0byB0aGUgcG9zdGVyaW9yIGRvc2UtdG94aWNpdHkgY3VydmVzIHRoZXkgcmVwb3J0LgpGb3IgaWxsdXN0cmF0aW9uLCB3ZSB3aWxsIHJlcGxpY2F0ZSBoZXJlIHRoZWlyIGFuYWx5c2lzIGZvciB0aGUgZW5kLW9mLXRyaWFsIGRvc2UtZGVjaXNpb24uCgpZb3Ugd2lsbCBuZWVkIHRvIGluc3RhbGwgdGhlIGxhdGVzdCB2ZXJzaW9uIG9mIGB0cmlhbHJgIGZyb20gR2l0SHViOgpgYGB7ciwgZXZhbD1GQUxTRX0KZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCdicm9ja2svdHJpYWxyJykKYGBgCgpOb3RlOiBgdHJpYWxgIHYwLjAuMSBvbiBDUkFOIGRvZXMgbm90IGNvbnRhaW4gdGhlIENSTSBtb2RlbHMgYnV0IHRoZSBsYXRlc3QgZ2l0aHViIGNvbW1pdCBkb2VzLgpUaGUgcGFja2FnZSBoYXMgZGVwZW5kZW5jaWVzIGluY2x1ZGluZyBgcnN0YW5gIGFuZCBgcnN0YW50b29sc2AuCkluIHRoaXMgdHV0b3JpYWwsIHdlIHdpbGwgYWxzbyBhc3N1bWUgdGhhdCB5b3UgaGF2ZSB0aGUgYHRpZHl2ZXJzZWAgcGFja2FnZSBpbnN0YWxsZWQuCgpMZXQgdXMgbG9hZCBgdHJpYWxyYC4KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkodHJpYWxyKQpgYGAKCkluY2x1ZGVkIGluIGB0cmlhbGAgaXMgYSBzeW50YXggZm9yIGRlc2NyaWJpbmcgdGhlIG91dGNvbWVzIG9mIGRvc2UtZmluZGluZyB0cmlhbHMgdXNpbmcgYSBjaGFyYWN0ZXIgc3RyaW5nLgpXZSB1c2UgaW50ZWdlcnMgdG8gcmVwcmVzZW50IHRoZSBkb3NlLWxldmVscyBnaXZlbiB0byBwYXRpZW50cyBvciBncm91cHMgb2YgcGF0aWVudHMuClRoZSBMw6l2eSB0cmlhbCBpbnZlc3RpZ2F0ZWQgZml2ZSBkb3NlcyBzbyBvdXIgcG9zc2libGUgZG9zZS1sZXZlbHMgYXJlIDEsIDIsIDMsIDQgb3IgNS4KV2UgdGhlbiBzdHJpbmcgdGhlIGxldHRlcnMgYFRgIChmb3IgdG94aWNpdHkpIGFuZCBgTmAgKGZvciBubyB0b3hpY2l0eSkgdG8gcmVwcmVzZW50IHRoZSBvdXRjb21lcyBmb3IgcGF0aWVudHMgdHJlYXRlZCBhdCB0aGF0IGRvc2UuClRoZXNlIGNsdXN0ZXJzIG9mIGNoYXJhY3RlcnMgY2FuIGJlIHN0cmV3biB0b2dldGhlciB0byByZXByZXNlbnQgdGhlIG91dGNvbWVzIG9mIG1hbnkgY29uc2VjdXRpdmUgY29ob3J0cy4KClVzaW5nIDYgY29ob3J0cyBvZiAzLCB0aGV5IHRyZWF0ZWQgMTggcGF0aWVudHMgYXQgb25lIG9mIHRocmVlIGRvc2VzIGFuZCBvYnNlcnZlZCA1IERMVHMgKFRhYmxlIDEsIEzDqXZ5IF9ldCBhbC5fLCAyMDA2KToKCnwgUGF0aWVudCB8IENvaG9ydCB8IERvc2UtbGV2ZWwgfCBUb3hpY2l0eSB8Cnw6LS0tLS0tLTp8Oi0tLS0tLTp8Oi0tLS0tLS0tLS06fDotLS0tLS0tLTp8CnwgICAgMSAgICB8ICAgMSAgICB8ICAgICAgMSAgICAgfCAgICAgMCAgICB8CnwgICAgMiAgICB8ICAgMSAgICB8ICAgICAgMSAgICAgfCAgICAgMCAgICB8CnwgICAgMyAgICB8ICAgMSAgICB8ICAgICAgMSAgICAgfCAgICAgMCAgICB8CnwgICAgNCAgICB8ICAgMiAgICB8ICAgICAgMyAgICAgfCAgICAgMCAgICB8CnwgICAgNSAgICB8ICAgMiAgICB8ICAgICAgMyAgICAgfCAgICAgMCAgICB8CnwgICAgNiAgICB8ICAgMiAgICB8ICAgICAgMyAgICAgfCAgICAgMSAgICB8CnwgICAgNyAgICB8ICAgMyAgICB8ICAgICAgNCAgICAgfCAgICAgMCAgICB8CnwgICAgOCAgICB8ICAgMyAgICB8ICAgICAgNCAgICAgfCAgICAgMCAgICB8CnwgICAgOSAgICB8ICAgMyAgICB8ICAgICAgNCAgICAgfCAgICAgMSAgICB8CnwgICAgMTAgICB8ICAgNCAgICB8ICAgICAgNCAgICAgfCAgICAgMCAgICB8CnwgICAgMTEgICB8ICAgNCAgICB8ICAgICAgNCAgICAgfCAgICAgMCAgICB8CnwgICAgMTIgICB8ICAgNCAgICB8ICAgICAgNCAgICAgfCAgICAgMCAgICB8CnwgICAgMTMgICB8ICAgNSAgICB8ICAgICAgNCAgICAgfCAgICAgMCAgICB8CnwgICAgMTQgICB8ICAgNSAgICB8ICAgICAgNCAgICAgfCAgICAgMSAgICB8CnwgICAgMTUgICB8ICAgNSAgICB8ICAgICAgNCAgICAgfCAgICAgMCAgICB8CnwgICAgMTYgICB8ICAgNiAgICB8ICAgICAgNCAgICAgfCAgICAgMSAgICB8CnwgICAgMTcgICB8ICAgNiAgICB8ICAgICAgNCAgICAgfCAgICAgMCAgICB8CnwgICAgMTggICB8ICAgNiAgICB8ICAgICAgNCAgICAgfCAgICAgMSAgICB8CgpUaGV5IHVzZWQgdGhlIENSTSBtb2RlbCBhdCB0aGUgY3VsbWluYXRpb24gb2YgZWFjaCBjb2hvcnQgdG8gc3VnZ2VzdCB0aGUgZG9zZSBmb3IgdGhlIG5leHQuClRoZWlyIG91dGNvbWVzIGNhbiBiZSByZXByZXNlbnRlZCBpbiBvdXIgc3ludGF4OgoKYGBge3J9Cm91dGNvbWVzIDwtICcxTk5OIDNOTlQgNE5OVCA0Tk5OIDROVE4gNFROVCcKYGBgCgoKSW4gQ1JNLCB0aGUgaW52ZXN0aWdhdG9ycyBtdXN0IHNwZWNpZnkgYSBfc2tlbGV0b25fLCB0aGVpciBwcmlvciBiZWxpZWZzIG9uIHRoZSBwcm9iYWJpbGl0eSBvZiBETFQgYXQgZWFjaCBkb3NlLCAkcF9pID0gXHRleHR7UHJvYn0oe0RMVH1faSkkLgpUaGlzIGNhbiBiZSBpbmZvcm1lZCBieSBwcmUtY2xpbmljYWwgc3R1ZGllcyBvciByZWxhdGVkIGNsaW5pY2FsIHRyaWFscy4KVGhlIHN0YW5kYXJkaXNlZCBkb3NlcyBhcmUgdGhlbiBzb2x2ZWQgdG8gc2F0aXNmeSAkcF9pID0gRih4X2ksIFx0aGV0YV8wKSQsIHdoZXJlICRcdGhldGFfMCQgcmVwcmVzZW50cyB0aGUgcHJpb3IgcGFyYW1ldGVyIG1lYW5zLgpBIGZ1bGwgZGVzY3JpcHRpb24gaXMgZ2l2ZW4gYnkgQ2hldW5nICgyMDExKS4KVGhlIGludmVzdGlnYXRvcnMgYWxzbyBzcGVjaWZ5IGEgdGFyZ2V0IHRveGljaXR5IHJhdGUsIGFuZCB0aGlzIGlzIGxhcmdlbHkgZHJpdmVuIGJ5IHRoZSBjbGluaWNhbCBzY2VuYXJpby4KTMOpdnkgX2V0IGFsLl8gY2hvc2U6CgpgYGB7cn0Kc2tlbGV0b24gPC0gYygwLjA1LCAwLjEwLCAwLjE1LCAwLjMzLCAwLjUpCnRhcmdldCA8LSAwLjMzCmBgYAoKRml0dGluZyB0aGUgbW9kZWwgdG8gdGhlIGRhdGE6CgpgYGB7ciwgcmVzdWx0cyA9ICJoaWRlIiwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KbW9kMSA8LSBzdGFuX2NybShvdXRjb21lcywgc2tlbGV0b24gPSBza2VsZXRvbiwgdGFyZ2V0ID0gdGFyZ2V0LAogICAgICAgICAgICAgICAgIG1vZGVsID0gJ2xvZ2lzdGljX2dhbW1hJywgYTAgPSA0LCAKICAgICAgICAgICAgICAgICBiZXRhX3NoYXBlID0gMSwgYmV0YV9pbnZlcnNlX3NjYWxlID0gMSwKICAgICAgICAgICAgICAgICBzZWVkID0gMTIzLCBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOTUpKQpgYGAKClRoZSBwYXJhbWV0ZXIgYG1vZGVsYCBkZXRlcm1pbmVzIHdoaWNoIENSTSB2YXJpYW50IGlzIGZpdCB0byB0aGUgZGF0YS4KQ3VycmVudGx5LCBpdCBtYXkgdGFrZSB2YWx1ZXM6CgotIGBlbXBpcmljYCwgZm9yIGVtcGlyaWMgbW9kZWwgd2l0aCBub3JtYWwgcHJpb3Igb24gc2xvcGU7Ci0gYGxvZ2lzdGljYCwgZm9yIG9uZS1wYXJhbWV0ZXIgbG9naXN0aWMgbW9kZWwgd2l0aCBub3JtYWwgcHJpb3Igb24gc2xvcGU7Ci0gYGxvZ2lzdGljX2dhbW1hYCwgZm9yIG9uZS1wYXJhbWV0ZXIgbG9naXN0aWMgbW9kZWwgd2l0aCBnYW1tYSBwcmlvciBvbiBzbG9wZTsKLSBgbG9naXN0aWMyYCwgZm9yIHR3by1wYXJhbWV0ZXIgbG9naXN0aWMgbW9kZWwgd2l0aCBub3JtYWwgcHJpb3JzIG9uIGludGVyY2VwdCBhbmQgc2xvcGUuCgpUaGVyZSBpcyBub3QgYSB2ZXJzaW9uIGV4cGxpY2l0bHkgZm9yIGV4cG9uZW50aWFsIHByaW9yczsgaW5zdGVhZCB3ZSBleHBsb2l0IHRoYXQgJGV4cG9uZW50aWFsKDEpIFxlcXVpdiBnYW1tYSgxLCAxKSQuCkRpZmZlcmVudCBtb2RlbCB2YXJpYW50cyByZXF1aXJlIGRpZmZlcmVudCBwYXJhbWV0ZXJzLgpUaGUgbG9naXN0aWMtZ2FtbWEgbW9kZWwgcmVxdWlyZXMgYW4gaW50ZXJjZXB0IHZhbHVlICRhXzAkIGFuZCB0d28gcGFyYW1ldGVycyBmb3IgdGhlIGdhbW1hIGRpc3RyaWJ1dGlvbi4KUGFyYW1ldGVycyBsaWtlIGBzZWVkYCBhbmQgYGNvbnRyb2xgIGFyZSBwYXNzZWQgdG8gYHJzdGFuYCB0byBjb250cm9sIHRoZSBzYW1wbGluZy4KCgoKVGhlIHJldHVybmVkIGBjcm1fZml0YCBvYmplY3QgY29udGFpbnMgdXNlZnVsIHN1bW1hcnkgaW5mb3JtYXRpb24gYW5kIGltcGxlbWVudHMgUzMgZ2VuZXJpYyBmdW5jdGlvbnMgZm9yIGNvbnZlbmllbnQgcHJpbnRpbmcsIGZvciBleGFtcGxlOgoKYGBge3J9Cm1vZDEKYGBgCgpQcm9iVG94IHNob3dzIHRoZSBwb3N0ZXJpb3IgbWVhbiBlc3RpbWF0ZSBvZiB0aGUgcHJvYmFiaWxpdHkgb2YgdG94aWNpdHkuClRoZSBzYW1lIHZhbHVlcyBhcmUgYWNjZXNzaWJsZSBmcm9tIHRoZSBmaXQgb2JqZWN0OgpgYGB7cn0KbW9kMSRwcm9iX3RveApgYGAKClRoZXNlIHZhbHVlcyBhcmUgdmVyeSBjbG9zZSB0byB0aGUgZXN0aW1hdGVzIGdpdmVuIGluIFRhYmxlIDEgb2YgTMOpdnkgX2V0IGFsLl8gKDIwMDYpLgpUaGUgQ1JNIG1vZGVsIHN1Z2dlc3RzIGRvc2UtbGV2ZWwgNCBoYXMgdG94aWNpdHkgcmF0ZSBjbG9zZXN0IHRvIHRoZSB0YXJnZXQgb2YgMzMlLgoKTGV0J3MgdmlzdWFsaXNlIHRoZSBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9ucy4gClBsb3R0aW5nIHBvc3RlcmlvciBkb3NlLXRveGljaXR5IGJlbGllZnMgY2FuIGJlIGFzIHNpbXBsZSBhczoKYGBge3J9CnBsb3QobW9kMSkKYGBgCgpIb3dldmVyLCB0aGUgdW5kZXJseWluZyBgc3RhbmZpdGAgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIHBvc3RlcmlvciBzYW1wbGVzIGlzIHN0b3JlZCBpbnNpZGUgYG1vZDFgIHNvIGFsbCBtYW5uZXIgb2YgdmlzdWFsaXNhdGlvbnMgYXJlIHBvc3NpYmxlIHVzaW5nIGBnZ3Bsb3QyYC4KRm9yIGluc3RhbmNlLCBhIHZpb2xpbiBwbG90IGlzIGEgbmljZSB3YXkgb2YgdmlzdWFsaXNpbmcgdGhpcyBpbmZvcm1hdGlvbjoKCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpsaWJyYXJ5KG1hZ3JpdHRyKQpsaWJyYXJ5KGdncGxvdDIpCm1vZDEgJT4lCiAgZ2F0aGVyX3NhbXBsZXMuY3JtX2ZpdCAlPiUKICBnZ3Bsb3QoYWVzKHggPSBEb3NlTGV2ZWwsIHkgPSBQcm9iVG94LCBncm91cCA9IERvc2VMZXZlbCkpICsKICBnZW9tX3Zpb2xpbihmaWxsID0gJ29yYW5nZScpICsgeWxpbSgwLCAxKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gdGFyZ2V0LCBjb2wgPSAncmVkJywgbGluZXR5cGUgPSAnZGFzaGVkJykgKwogIGxhYnModGl0bGUgPSAnUHIoVG94aWNpdHkpIGFmdGVyIDE4IHBhdGllbnRzIGluIExldnksIGV0IGFsLiAoMjAwNiknKQpgYGAKVGhlIGRhc2hlZCByZWQgbGluZSBzaG93cyB0aGUgdGFyZ2V0IHRveGljaXR5IHJhdGUuCgpBZnRlciB0aGVzZSAxOCBwYXRpZW50cywgdGhlIGludmVzdGlnYXRvcnMgc3RvcHBlZCB0aGUgdHJpYWwgYWNjb3JkaW5nIHRvIHByZS1zcGVjaWZpZWQgc3RvcHBpbmcgcnVsZXMsIHJlY29tbWVuZGluZyBkb3NlLWxldmVsIDQgZm9yIGZ1cnRoZXIgaW52ZXN0aWdhdGlvbi4KVGhlIG1hbnVzY3JpcHQgZXhwbGFpbnMgdGhhdCB0aGUgc3RvcHBpbmcgcnVsZXMgc2NydXRpbmlzZWQgdGhlIGVzdGltYXRlZCB0b3hpY2l0eSBwcm9iYWJpbGl0eSBhdCB0aGUgcHJvcG9zZWQgZG9zZSBhbmQgdGhlIHByZWNpc2lvbiBvZiB0aGF0IGVzdGltYXRlIGJhc2VkIG9uIGNyZWRpYmxlIGludGVydmFscy4KV2UgY2FuIHNlZSBmcm9tIHRoZSBwbG90IGFib3ZlIHRoYXQgZG9zZS1sZXZlbCA0IGlzIG11Y2ggbW9yZSBwbGF1c2libGUgdGhhbiBuZWlnaGJvdXJpbmcgZG9zZXMuCgpBbm90aGVyIHdheSBvZiB2aWV3aW5nIHRoZSBhYm92ZSBpbmZvcm1hdGlvbiBpcyB0byBvdmVycGxvdCBtYW55IG9mIHRoZSBzYW1wbGVkIGRvc2UtdG94aWNpdHkgY3VydmVzOgoKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkoZHBseXIpCgptb2QxICU+JQogIGdhdGhlcl9zYW1wbGVzLmNybV9maXQgJT4lCiAgZmlsdGVyKERyYXcgPD0gMTAwMCkgJT4lIAogIGdncGxvdChhZXMoeCA9IERvc2VMZXZlbCwgeSA9IFByb2JUb3gsIGdyb3VwID0gRHJhdykpICsKICBnZW9tX2xpbmUoYWxwaGEgPSAwLjAzLCBjb2wgPSAnb3JhbmdlJykgKyB5bGltKDAsIDEpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSB0YXJnZXQsIGNvbCA9ICdyZWQnLCBsaW5ldHlwZSA9ICdkYXNoZWQnKSArCiAgbGFicyh0aXRsZSA9ICdTYW1wbGVkIGRvc2UtdG94aWNpdHkgY3VydmVzIGFmdGVyIDE4IHBhdGllbnRzIGluIExldnksIGV0IGFsLiAoMjAwNiknKQpgYGAKCkEgZGlyZWN0IEJheWVzaWFuIHdheSBvZiBxdWFudGlmeWluZyBvdXIgbW90aXZhdGlvbiB0byBjb250aW51ZSB0aGUgdHJpYWwgb3Igc3RvcCBpcyB0byBlc3RpbWF0ZSB0aGUgcHJvYmFiaWxpdHkgdGhhdCBlYWNoIGRvc2UgaXMgdGhlIHRydWUgTVRELCBpLmUuIGJ5IGVmZmVjdGl2ZWx5IGNhbGN1bGF0aW5nIHRoZSBkb3NlIGNsb3Nlc3QgdG8gMzMlIGluIGVhY2ggb2YgdGhlIHNhbXBsZWQgZG9zZS10b3hpY2l0eSBjdXJ2ZXMgYWJvdmUuClRoaXMgaXMgY2FsY3VsYXRlZCB3aGVuIHRoZSBtb2RlbCBpcyBmaXQ6CgpgYGB7cn0KbW9kMSRwcm9iX210ZApgYGAKCldlIHNlZSB0aGF0IDUzJSBvZiBjdXJ2ZXMgYWR2b2NhdGUgY2hvb3NpbmcgZG9zZS1sZXZlbCA0LCBpbXBseWluZyB0aGF0IHRoaXMgZG9zZSBpcyBtb3JlIGxpa2VseSB0aGFuIG5vdCB0byBiZSB0aGUgTVRELCBnaXZlbiB0aGUgc3RhdGVkIHByaW9yIGJlbGllZnMgYW5kIHRoZSBvYnNlcnZlZCB0cmlhbCBkYXRhLgpUaGUgdHJpYWxpc3RzJyBkZWNpc2lvbiB0byBzdG9wIGhlcmUgd2FzIHBlcmhhcHMgcHJlc2NpZW50IGJlY2F1c2UgdGhpcyB3YXMgdGhlIGZpcnN0IG9jY2FzaW9uIGluIHRoZSB0cmlhbCBhZnRlciB0aGUgZmlyc3QgY29ob3J0IHRoYXQgdGhpcyBjb25kaXRpb24gd2FzIG1ldC4KCgoKIyBEb3NlLWZpbmRpbmcgYnkgZWZmaWNhY3kgYW5kIHRveGljaXR5IG91dGNvbWVzIHVzaW5nIEVmZlRveApUaGFsbCAmIENvb2sgKDIwMDQpIGludHJvZHVjZWQgdGhlIF9FZmZUb3hfIGRlc2lnbiBmb3IgZG9zZS1maW5kaW5nIGluIHNjZW5hcmlvcyB3aGVyZSBib3RoIGVmZmljYWN5IGFuZCB0b3hpY2l0eSBldmVudHMgc2hvdWxkIGd1aWRlIGRvc2Ugc2VsZWN0aW9uLgpUaGlzIGlzIGluIGNvbnRyYXN0IHRvIG1ldGhvZHMgbGlrZSBDUk0gd2hlcmUgZG9zZSBzZWxlY3Rpb24gaXMgZGV0ZXJtaW5lZCBieSB0b3hpY2l0eSBldmVudHMgb25seS4KVGhpcyBlbWJlbGxpc2htZW50IGhhcyBiZWNvbWUgaW5jcmVhc2luZ2x5IHBlcnRpbmVudCBpbiByZWNlbnQgeWVhcnMgd2l0aCB0aGUgaW50cm9kdWN0aW9uIG9mIHNvLWNhbGxlZCBfY3l0b3N0YXRpY18gZHJ1Z3MgbGlrZSBpbW11bm90aGVyYXBpZXMsIHdoaWNoIGNhbiBleGhpYml0IG5vbi1tb25vdG9uaWNhbGx5LWluY3JlYXNpbmcgZWZmaWNhY3kgYnkgZG9zZSAoZS5nLiBHYXJvbiBfZXQgYWwuXywgMjAxNSkKSW4gc3VjaCBhIHNjZW5hcmlvLCB0byBlc2NhbGF0ZSBkb3NlIHNlZWtpbmcgYSB0YXJnZXQgbGV2ZWwgb2YgdG94aWNpdHkgd291bGQgYmUgYW4gZXhwZW5zaXZlIG1pc3Rha2UuCldlIHByb3ZpZGUgYSBicmllZiByZWNhcCBvZiBFZmZUb3ggaGVyZSwgYnV0IGZ1bGwgZGV0YWlscyBhcmUgZ2l2ZW4gaW4gVGhhbGwgKDIwMDQpLCBUaGFsbCBfZXQgYWwuXyAoMjAwNiksIGFuZCBUaGFsbCBfZXQgYWwuXyAoMjAxNCkuCgpGb3IgZG9zZXMgJFxib2xkc3ltYm9se3l9ID0gKHlfMSwgLi4uLCB5X24pJCwgdGhlIGF1dGhvcnMgZGVmaW5lIGRvc2VzICQoeF8xLCAuLi4sIHhfbikkIHN0YW5kYXJkaXNlZCBieSB0aGUgZ2VvbWV0cmljIG1lYW46IAoKJHhfaSA9IFxsb2d7eV9pfSAtIFxzdW1fe2o9MX1ebiBcZnJhY3tcbG9ne3lfan19e259JAoKVGhlICR4X2kkIGFyZSB1c2VkIGFzIHRoZSBzb2xlIGV4cGxhbmF0b3J5IHZhcmlhYmxlcyBpbiBsb2dpdCBtb2RlbHMgZm9yIHRoZSBtYXJnaW5hbCBwcm9iYWJpbGl0aWVzIG9mIHRveGljaXR5IGFuZCBlZmZpY2FjeToKCiRcdGV4dHtsb2dpdCB9IFxwaV9UID0gXGFscGhhICsgXGJldGEgeCQKCiRcdGV4dHtsb2dpdCB9IFxwaV9FID0gXGdhbW1hICsgXHpldGEgeCArIFxldGEgeF4yJAoKVGhlIHByZXNlbmNlIG9mIHRoZSBxdWFkcmF0aWMgdGVybSBhbGxvd3MgZm9yIG5vbi1saW5lYXJpdHkgYW5kIHBvdGVudGlhbGx5IGEgdHVybmluZyBwb2ludCBpbiB0aGUgZG9zZS1lZmZpY2FjeSByZWxhdGlvbnNoaXAuCgpUaGUgam9pbnQgcHJvYmFiaWxpdHkgb2YgdGhlc2UgdHdvIGV2ZW50cyBpcyBtb2RlbGxlZCB1c2luZyB0aGUgX0d1bWJlbCBtb2RlbF86CgokXHBpX3thLGJ9ID0gKFxwaV9FKV5hICgxLVxwaV9FKV57MS1hfSAoXHBpX1QpXmIgKDEtXHBpX1QpXnsxLWJ9ICsgKC0xKV57YStifSAoXHBpX0UpICgxLVxwaV9FKSAoXHBpX1QpICgxLVxwaV9UKSBcZnJhY3tlXlxwc2ktMX17ZV5ccHNpKzF9JC4KCkZvciBhIGdpdmVuIHBhdGllbnQsICRhPTEkIGltcGxpZXMgdGhhdCBhIHBhdGllbnQgZXhwZXJpZW5jZWQgdGhlIGVmZmljYWN5IGV2ZW50LCBhbmQgJGE9MCQgaW1wbGllcyB0aGV5IGRpZCBub3Q7ICRiJCBwZXJmb3JtcyB0aGUgYW5hbG9nb3VzIGZ1bmN0aW9uIGZvciB0aGUgdG94aWNpdHkgZXZlbnQuClRoZSAkXHBzaSQgcGFyYW1ldGVyIGZhY2lsaXRhdGVzIGFuIGFzc29jaWF0aW9uIGJldHdlZW4gZWZmaWNhY3kgYW5kIHRveGljaXR5IGV2ZW50cy4KVGhlIGZyYWN0aW9uIHRlcm0gaW52b2x2aW5nICRccHNpJCB0YWtlcyB2YWx1ZXMgb24gJCgtMSwgMSkkIGZvciByZWFsLXZhbHVlZCAkXHBzaSQuCkl0IGlzIGRlc2lyYWJsZSB0aGF0IHRoZSBwb3NzaWJpbGl0eSBmb3IgYXNzb2NpYXRpb24gYmV0d2VlbiB0aGUgY28tcHJpbWFyeSBvdXRjb21lcyBpcyBwcmVzZW50IGluIHRoZSBtb2RlbCB0byByZWZsZWN0IHBvdGVudGlhbCBjbGluaWNhbCByZWxhdGlvbnNoaXBzLgpJZiBhIHRyZWF0bWVudCBpcyBzbyB0b3hpYyB0aGF0IHBhdGllbnRzIGRpc2NvbnRpbnVlLCB0aGVpciBwb3RlbnRpYWwgdG8gcmVjZWl2ZSBjbGluaWNhbCBiZW5lZml0IGlzIG5hdHVyYWxseSBoaW5kZXJlZC4gCkluIGNvbnRyYXN0IGZvciBzb21lIHRyZWF0bWVudHMsIHRveGljaXR5IGFuZCBlZmZpY2FjeSBhcmUgc2VlbiBhcyB0d28gZWZmZWN0cyBvZiBzb21lIGNvbW1vbiBtZWNoYW5pc20gb2YgYWN0aW9uLgpGb3IgaW5zdGFuY2UsIHdpdGggc3RlbS1jZWxsIHRyYW5zcGxhbnRzLCB0aGUgcHJlc2VuY2Ugb2Ygc29tZSB0b3hpY2l0eSBsaWtlIG1vZGVyYXRlIGdyYWZ0LXZlcnN1cy1ob3N0IGRpc2Vhc2UgaXMgdGFrZW4gYXMgZXZpZGVuY2UgdGhhdCBhbnRpLXR1bW91ciBhY3Rpdml0eSBpcyBhbHNvIG9jY3VycmluZwoKTm9ybWFsIHByaW9ycyBhcmUgc3BlY2lmaWVkIGZvciB0aGUgZWxlbWVudHMgb2YgdGhlIHBhcmFtZXRlciB2ZWN0b3IgJFxib2xkc3ltYm9se1x0aGV0YX0gPSAoXGFscGhhLCBcYmV0YSwgXGdhbW1hLCBcemV0YSwgXGV0YSwgXHBzaSkkLiAKVGhhbGwgX2V0IGFsLl8gKDIwMTQpIGRldGFpbCBhbiBhbGdvcml0aG0gdG8gc3BlY2lmeSBwcmlvcnMgb24gdGhlIGVsZW1lbnRzIG9mICRcYm9sZHN5bWJvbHtcdGhldGF9JCB0aGF0IGNvbnZleSBleHBlY3RlZCBwcm9iYWJpbGl0aWVzIG9mIGVmZmljYWN5IGFuZCB0b3hpY2l0eSBhdCB0aGUgZG9zZXMgKGFuYWxvZ291cyB0byB0aGUgdG94aWNpdHkgc2tlbGV0b24gaW4gdGhlIENSTSBleGFtcGxlKSB0aGF0IGpvaW50bHkgY29udGFpbiBpbmZvcm1hdGlvbiBlcXVhbCB0byBhbiBfZWZmZWN0aXZlIHNhbXBsZSBzaXplXy4KTm90ZSB0aGF0IHRoaXMgYWxnb3JpdGhtIGlzIGltcGxlbWVudGVkIGluIHRoZSBNRCBBbmRlcnNvbiBFZmZUb3ggc29mdHdhcmUgKGRldGFpbGVkIGJlbG93KSBidXQgbm90IHlldCBpbXBsZW1lbnRlZCBpbiBgdHJpYWxyYC4KCkF0IGVhY2ggZG9zZSB1cGRhdGUgZGVjaXNpb24sIHRoZSBkb3NlICR4JCBpcyBhY2NlcHRhYmxlIGlmCgokXHRleHR7UHJ9XGxlZnRceyBccGlfVCh4LCBcYm9sZHN5bWJvbHtcdGhldGF9KSA8IFxvdmVybGluZXtccGl9X1QgfCBcbWF0aGNhbHtEfSBccmlnaHRcfSA+IHBfVCQKCmFuZAoKJFx0ZXh0e1ByfVxsZWZ0XHsgXHBpX0UoeCwgXGJvbGRzeW1ib2x7XHRoZXRhfSkgPiBcdW5kZXJsaW5le1xwaX1fRSB8IFxtYXRoY2Fse0R9IFxyaWdodFx9ID4gcF9FJAoKJFx1bmRlcmxpbmV7XHBpfV9FLCBwX0UsIFxvdmVybGluZXtccGl9X1QsIHBfVCQgYXJlIHByb3ZpZGVkIGJ5IHRoZSBpbnZlc3RpZ2F0b3JzIGFzIHRoZSBjbGluaWNhbCBzY2VuYXJpbyBkaWN0YXRlcy4KVGhlc2UgY3JpdGVyaWEgZW5zdXJlIHRoYXQgdGhlIGRvc2VzIGNvbnNpZGVyZWQgZm9yIGFsbG9jYXRpb24gdG8gcGF0aWVudHMgYXJlIHN1ZmZpY2llbnRseSBlZmZpY2FjaW91cyBhbmQgdG9sZXJhYmxlLgpJbmVmZmVjdGl2ZSBvciB0b3hpYyBkb3NlcyBhcmUgZXhjbHVkZWQuCkZ1cnRoZXJtb3JlLCB0aGUgZGVzaWduIHJlcXVpcmVzIHRoYXQgdW50cmllZCBkb3NlcyBhcmUgbm90IHNraXBwZWQgaW4gZXNjYWxhdGlvbiBvciBkZS1lc2NhbGF0aW9uLgpUaGF0IGlzLCBvbmx5IGRvc2VzIHRoYXQgYXJlIG5vIG1vcmUgdGhhbiBvbmUgcG9zaXRpb24gYmVsb3cgdGhlIGxvd2VzdCBkb3NlLWxldmVsIGFscmVhZHkgZ2l2ZW4gYW5kIG5vIG1vcmUgdGhhbiBvbmUgcG9zaXRpb24gYWJvdmUgdGhlIGhpZ2hlc3QgZG9zZS1sZXZlbCBhbHJlYWR5IGdpdmVuIGFyZSBjb25zaWRlcmVkLgoKVGhlIHV0aWxpdHkgb2YgZG9zZSAkeCQsIHdpdGggZWZmaWNhY3kgJFxwaV9FKHgsIFxib2xkc3ltYm9se1x0aGV0YX0pJCBhbmQgdG94aWNpdHkgJFxwaV9UKHgsIFxib2xkc3ltYm9se1x0aGV0YX0pJCBpcyAKCiR1KFxwaV9FLCBccGlfVCkgPSAxIC0gXGxlZnQoIFxsZWZ0KFxmcmFjezEtXHBpX0V9ezEtXHBpX3sxLEV9Xip9XHJpZ2h0KV5wICsgXGxlZnQoXGZyYWN7XHBpX1R9e1xwaV97MixUfV4qfVxyaWdodClecCBccmlnaHQpIF4gXGZyYWN7MX17cH0kCgp3aGVyZSAkcCQgaXMgY2FsY3VsYXRlZCB0byBpbnRlcnNlY3QgdGhlIHBvaW50cyAkKFxwaV97MSxFfV4qLCAwKSQsICQoMSwgXHBpX3syLFR9XiopJCBhbmQgJChccGlfezMsRX1eKiwgXHBpX3szLFR9XiopJC4KV2Ugd2lsbCByZWZlciB0byB0aGVzZSBhcyBfaGluZ2UgcG9pbnRzXyBidXQgdGhhdCBpcyBub3Qgbm9tZW5jbGF0dXJlIHVzZWQgYnkgdGhlIGF1dGhvcnMuCiRccGlfezEsRX1eKiQgaXMgdGhlIHJhdGUgb2YgZWZmaWNhY3kgdGhhdCBpcyBhY2NlcHRhYmxlIGlmIHRveGljaXR5IGlzIGltcG9zc2libGUuCiRccGlfezIsVH1eKiQgaXMgdGhlIHJhdGUgb2YgdG94aWNpdHkgdGhhdCBpcyBhY2NlcHRhYmxlIGlmIGVmZmljYWN5IGlzIGd1YXJhbnRlZWQuClRoZSB0aGlyZCBoaW5nZSBwb2ludCBpcyBzZWxlY3RlZCBpbiB0aGUgZ2VuZXJhbCAkKDAsIDEpIFx0aW1lcyAoMCwgMSkkIHByb2IoZWZmaWNhY3kpLXByb2IodG94aWNpdHkpIHBsYWluIHRoYXQgaXMgZXF1YWxseSBhdHRyYWN0aXZlIGFzIHRoZSBvdGhlciB0d28gaGluZ2UgcG9pbnRzLgpUaGUgdGhyZWUgaGluZ2UgcG9pbnRzIGxheSBvbiB0aGUgbmV1dHJhbCB1dGlsaXR5IGNvbnRvdXIgd2hlcmUgJHUoXHBpX0UsIFxwaV9UKSA9IDAkLgpUaGUgZXF1YXRpb25zICR1KFxwaV97MSxFfV4qLCAwKSA9IHUoMSwgXHBpX3syLFR9XiopID0gdShccGlfezMsRX1eKiwgXHBpX3szLFR9XiopID0gMCQgYXJlIHNvbHZlZCB0byBpZGVudGlmeSB0aGUgY3VydmF0dXJlIHBhcmFtZXRlciwgJHAkLCBmb3IgYSBmYW1pbHkgb2YgY3VydmVzIHRoYXQgYXJlIHBhcmFsbGVsIHRvIHRoZSBuZXV0cmFsIGNvbnRvdXIuCkFzIHRoZSBjdXJ2ZXMgYXBwcm9hY2ggdGhlIHBvaW50ICQoMSwgMCkkLCB0aGUgdXRpbGl0eSBzY29yZXMgaW5jcmVhc2UsIGFuZCB2aWNlLXZlcnNhLgoKQXQgdGhlIGRvc2Ugc2VsZWN0aW9uIGRlY2lzaW9uLCB0aGUgZG9zZS1sZXZlbCBmcm9tIHRoZSBhY2NlcHRhYmxlIHNldCB3aXRoIG1heGltYWwgdXRpbGl0eSBpcyBzZWxlY3RlZCB0byBiZSBnaXZlbiB0byB0aGUgbmV4dCBwYXRpZW50IG9yIGNvaG9ydC4KSWYgdGhlcmUgYXJlIG5vIGFjY2VwdGFibGUgZG9zZXMsIHRoZSB0cmlhbCBzdG9wcyBhbmQgbm8gZG9zZSBpcyByZWNvbW1lbmRlZC4KCiMjIyBFeGFtcGxlIC0gVGhhbGwgX2V0IGFsLl8gKDIwMTQpLgpXZSB3aWxsIGlsbHVzdHJhdGUgRWZmVG94IHVzaW5nIHRoZSBhZHZhbmNlZCBwcm9zdGF0ZSBjYW5jZXIgZXhhbXBsZSBpbiBUaGFsbCBfZXQgYWwuXyAoMjAxNCkuClRoZXkgaW52ZXN0aWdhdGUgdGhlIGZpdmUgZG9zZXMgMSwgMiwgNCwgNi42IGFuZCAxMCBtY0wva2csIHNlZWtpbmcgdGhlIGJlc3QgZG9zZSB3aXRoIAoKJFx0ZXh0e1ByfVxsZWZ0XHsgXHBpX1QoeCwgXGJvbGRzeW1ib2x7XHRoZXRhfSkgPCAwLjMgfCBcbWF0aGNhbHtEfSBccmlnaHRcfSA+IDAuMSQgCgphbmQgCgokXHRleHR7UHJ9XGxlZnRceyBccGlfRSh4LCBcYm9sZHN5bWJvbHtcdGhldGF9KSA+IDAuNSB8IFxtYXRoY2Fse0R9IFxyaWdodFx9ID4gMC4xJCAKClRodXMsIHdlIGhhdmUgJHBfVCA9IHBfRSA9IDAuMSwgXG92ZXJsaW5le1xwaX1fVCA9IDAuMyQgYW5kICRcdW5kZXJsaW5le1xwaX1fRSA9IDAuNSQuCgpTaW1pbGFyIHRvIGFib3ZlLCBgdHJpYWxyYCBpbXBsZW1lbnRzIGEgc3ludGF4IGZvciBkZXNjcmliaW5nIG91dGNvbWVzIGluIHBoYXNlIEkvSUkgZG9zZS1maW5kaW5nIGRlc2lnbnMgbGlrZSBFZmZUb3guCldlIHVzZSB0aGUgbGV0dGVycyBFIHRvIGRlbm90ZSBhbiBvdXRjb21lIG9mIGVmZmljYWN5IG9ubHksIFQgdG8gZGVub3RlIHRveGljaXR5IG9ubHksIEIgZm9yIGJvdGggYW5kIE4gZm9yIG5laXRoZXIuCkFzIGJlZm9yZSwgd2Ugc3RyaW5nIHRoZXNlIGNoYXJhY3RlcnMgYmVoaW5kIG51bWVyaWNhbCBkb3NlLWxldmVscyB0byByZXByZXNlbnQgdGhlIG91dGNvbWVzIG9mIHBhdGllbnRzIGluIHNlcXVlbnRpYWwgZG9zZSBjb2hvcnRzLgpUaGlzIG1ldGhvZCB3YXMgZmlyc3QgZGVzY3JpYmVkIGluIEJyb2NrIF9ldCBhbC5fICgyMDE3KS4KCkZvciBkZW1vbnN0cmF0aW9uLCB3ZSBjb25zaWRlciBhIHNjZW5hcmlvIHdoZXJlIHR3byBjb2hvcnRzIG9mIHRocmVlIHBhdGllbnRzIGhhdmUgYmVlbiBldmFsdWF0ZWQ6Cgp8IFBhdGllbnQgfCBDb2hvcnQgfCBEb3NlLWxldmVsIHwgVG94aWNpdHkgfCBFZmZpY2FjeSB8Cnw6LS0tLS0tLTp8Oi0tLS0tLTp8Oi0tLS0tLS0tLS06fDotLS0tLS0tLTp8Oi0tLS0tLS0tOnwKfCAgICAxICAgIHwgICAxICAgIHwgICAgICAxICAgICB8ICAgICAwICAgIHwgICAgIDAgICAgfAp8ICAgIDIgICAgfCAgIDEgICAgfCAgICAgIDEgICAgIHwgICAgIDAgICAgfCAgICAgMSAgICB8CnwgICAgMyAgICB8ICAgMSAgICB8ICAgICAgMSAgICAgfCAgICAgMCAgICB8ICAgICAwICAgIHwKfCAgICA0ICAgIHwgICAyICAgIHwgICAgICAyICAgICB8ICAgICAwICAgIHwgICAgIDAgICAgfAp8ICAgIDUgICAgfCAgIDIgICAgfCAgICAgIDIgICAgIHwgICAgIDEgICAgfCAgICAgMSAgICB8CnwgICAgNiAgICB8ICAgMiAgICB8ICAgICAgMiAgICAgfCAgICAgMCAgICB8ICAgICAxICAgIHwKClVzaW5nIG91ciBzeW50YXgsIHRoZXNlIG91dGNvbWVzIGNhbiBiZSBkZXNjcmliZWQ6CmBgYHtyfQpvdXRjb21lcyA8LSAnMU5FTiAyTkJFJwpgYGAKClRoZSBwYXJhbWV0ZXJpc2F0aW9uIGZvciB0aGlzIGFkdmFuY2VkIHByb3N0YXRlIGNhbmNlciBleGFtcGxlIGlzIGxvYWRlZCBieSBkZWZhdWx0IGluIHRoZSBNRCBBbmRlcnNvbiBFZmZUb3ggYXBwLgpUaGUgbW9kZWwgY2FuIGJlIGZpdCB0byB0aGUgb2JzZXJ2ZWQgb3V0Y29tZXMgaW4gYHRyaWFscmAgdXNpbmc6CgpgYGB7ciwgcmVzdWx0cyA9ICJoaWRlIiwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KbW9kMiA8LSBzdGFuX2VmZnRveF9kZW1vKG91dGNvbWVzLCBzZWVkID0gMTIzKQpgYGAKClRoaXMgaXMgc2ltcGx5IHNob3J0LWhhbmQgZm9yOiAKYGBge3IsIHJlc3VsdHMgPSAiaGlkZSIsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9Cm1vZDIgPC0gc3Rhbl9lZmZ0b3gob3V0Y29tZXMsCiAgICAgICAgICAgICAgICAgICAgcmVhbF9kb3NlcyA9IGMoMS4wLCAyLjAsIDQuMCwgNi42LCAxMC4wKSwKICAgICAgICAgICAgICAgICAgICBlZmZpY2FjeV9odXJkbGUgPSAwLjUsIHRveGljaXR5X2h1cmRsZSA9IDAuMywKICAgICAgICAgICAgICAgICAgICBwX2UgPSAwLjEsIHBfdCA9IDAuMSwKICAgICAgICAgICAgICAgICAgICBlZmYwID0gMC41LCB0b3gxID0gMC42NSwKICAgICAgICAgICAgICAgICAgICBlZmZfc3RhciA9IDAuNywgdG94X3N0YXIgPSAwLjI1LAogICAgICAgICAgICAgICAgICAgIGFscGhhX21lYW4gPSAtNy45NTkzLCBhbHBoYV9zZCA9IDMuNTQ4NywKICAgICAgICAgICAgICAgICAgICBiZXRhX21lYW4gPSAxLjU0ODIsIGJldGFfc2QgPSAzLjUwMTgsCiAgICAgICAgICAgICAgICAgICAgZ2FtbWFfbWVhbiA9IDAuNzM2NywgZ2FtbWFfc2QgPSAyLjU0MjMsCiAgICAgICAgICAgICAgICAgICAgemV0YV9tZWFuID0gMy40MTgxLCB6ZXRhX3NkID0gMi40NDA2LAogICAgICAgICAgICAgICAgICAgIGV0YV9tZWFuID0gMCwgZXRhX3NkID0gMC4yLAogICAgICAgICAgICAgICAgICAgIHBzaV9tZWFuID0gMCwgcHNpX3NkID0gMSwKICAgICAgICAgICAgICAgICAgICBzZWVkID0gMTIzKQpgYGAKT25jZSBhZ2FpbiwgcGFyYW1ldGVycyBsaWtlIGBzZWVkYCBldGMgYXJlIHBhc3NlZCBvbndhcmRzIHRvIGByc3Rhbjo6c2FtcGxpbmdgLgpQbGVhc2UgcmVmZXIgdG8gVGhhbGwgX2V0IGFsLl8gKDIwMTQpIGZvciBpbmZvcm1hdGlvbiBvbiB0aGVpciBwcmlvcnMuIAoKVGhlIHJldHVybmVkIGBlZmZ0b3hfZml0YCBvYmplY3QgYWxzbyBpbXBsZW1lbnRzIHRoZSBnZW5lcmljcyBgcHJpbnRgLCBgcGxvdGAsIGBzdW1tYXJ5YCBhbmQgYGFzLmRhdGEuZnJhbWVgLgpgYGB7cn0KbW9kMgpgYGAKV2Ugc2VlIHRoYXQgZG9zZS1sZXZlbHMgMSB0byAzIGFyZSBhY2NlcHRhYmxlIGJlY2F1c2UgdGhleSBzYXRpc2Z5IHRoZSBhY2NlcHRhYmlsaXR5IGNyaXRlcmlhLgpEb3NlLWxldmVsIDMgaXMgcmVjb21tZW5kZWQgYmVjYXVzZSBpdCBpcyB0aGUgYWNjZXB0YWJsZSBkb3NlIHdpdGggdGhlIGhpZ2hlc3QgdXRpbGl0eSB2YWx1ZS4KRG9zZS1sZXZlbHMgNCBhbmQgNSBhcmUgdW5hY2NlcHRhYmxlLiAKVGhpcyBpcyBiZWNhdXNlIGRvc2UtbGV2ZWwgMyBoYXMgbm90IHlldCBiZWVuIGdpdmVuLgpObyBkb3NlcyBhcmUgaW5mZXJyZWQgdG8gYmUgdG9vIHRveGljIG9yIGluZWZmaWNhY2lvdXMgeWV0LgoKU2xvdHMgaW4gdGhlIHJldHVybmVkIGZpdCBjb250YWluIHRoZSBwZXJ0aW5lbnQgaW5mb3JtYXRpb246CgpgYGB7cn0KbW9kMiRyZWNvbW1lbmRlZF9kb3NlCmBgYAoKYGBge3J9Cm1vZDIkcHJvYl9lZmYKYGBgCgpUaGUgZGVmYXVsdCBgcGxvdGAgbWV0aG9kIHNob3dzIHRoZSBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9uIG9mIHRoZSB1dGlsaXR5IHNjb3JlczoKYGBge3J9CnBsb3QobW9kMikKYGBgCgpXZSBjYW4gcHJvZHVjZSBtb3JlIHNwZWNpYWxpc2VkIHBsb3RzLCBsaWtlIGEgcGxvdCBvZiB0aGUgdXRpbGl0eSBjb250b3VycyBhbmQgb3VyIHBvc3RlcmlvciBiZWxpZWZzOgoKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGZpZy5jYXAgPSAiVXRpbGl0eSBjb250b3VycyBhZnRlciBvYnNlcnZpbmcgb3V0Y29tZXMgMU5FTiAyTkJFLiJ9CmVmZnRveF9jb250b3VyX3Bsb3QobW9kMiRkYXQsIHByb2JfZWZmID0gbW9kMiRwcm9iX2VmZiwgCiAgICAgICAgICAgICAgICAgICAgcHJvYl90b3ggPSBtb2QyJHByb2JfdG94LCB1c2VfZ2dwbG90ID0gVFJVRSkgKyAKICBnZ3RpdGxlKCdFZmZUb3ggdXRpbGl0eSBjb250b3VycycpCmBgYAoKVGhlIGJsdWUgdHJpYW5nbGVzIHNob3cgdGhlIGxvY2F0aW9uIG9mIHRoZSBoaW5nZSBwb2ludHMuClRoZSByZWQgbnVtYmVycyBzaG93IHRoZSBwb3N0ZXJpb3IgbWVhbnMgb2YgdGhlIGZpdmUgZG9zZS1sZXZlbHMuCkRvc2VzIHRoYXQgYXJlIGNsb3NlciB0byB0aGUgbG93ZXItcmlnaHQgY29ybmVyIGhhdmUgaGlnaGVyIHV0aWxpdHkuCldlIHNlZSB0aGF0IGRvc2UtbGV2ZWwgMyBoYXMgdGhlIGhpZ2hlc3QgdXRpbGl0eSwgYnV0IG9ubHkganVzdC4KCldlIGNhbiBhbHNvIHByb2R1Y2UgcG9zdGVyaW9yIGRlbnNpdHkgcGxvdHMgb2YgdGhlIGRvc2UgdXRpbGl0aWVzLgpGb3IgaWxsdXN0cmF0aW9uLCB3ZSB3aWxsIGp1c3QgcGxvdCB0aGUgZGVuc2l0aWVzIG9mIHRoZSB0aHJlZSBoaWdoZXN0IGRvc2VzLgoKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGZpZy5jYXAgPSAiVXRpbGl0eSBkZW5zaXRpZXMgYWZ0ZXIgb2JzZXJ2aW5nIG91dGNvbWVzIDFORU4gMk5CRS4ifQptb2QyICU+JQogIGdhdGhlcl9zYW1wbGVzLmVmZnRveF9maXQoJ3V0aWxpdHknKSAlPiUKICBmaWx0ZXIoRG9zZUxldmVsICVpbiUgMzo1KSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBWYWx1ZSwgZ3JvdXAgPSBEb3NlTGV2ZWwpKSArCiAgZ2VvbV9kZW5zaXR5KGFlcyhmaWxsID0gYXMuZmFjdG9yKERvc2VMZXZlbCkpKSArIAogIGxhYnMoZmlsbCA9ICdEb3NlJywgdGl0bGUgPSAnRWZmVG94IGRvc2UgdXRpbGl0eSBkZW5zaXRpZXMnKQpgYGAKClRoZSB0aHJlZSBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9ucyBhcmUgbGFyZ2VseSBjb2luY2lkZW50LCBoaWdobGlnaHRpbmcgdGhlIGxhY2sgb2YgY2VydGFpbnR5IGF0IHRoaXMgZWFybHkgc3RhZ2UgaW4gdGhlIHRyaWFsLgpUbyBmdXJ0aGVyIGZhY2lsaXRhdGUgdGhlIGFuYWx5c2lzIG9mIGRvc2UgdXRpbGl0eSwgd2UgcHJvdmlkZSBtZWFucyBvZiBjYWxjdWxhdGluZyB0aGUgZG9zZSBzdXBlcmlvcml0eSBtYXRyaXguCmBgYHtyLCByZXN1bHRzPSdhc2lzJ30Ka25pdHI6OmthYmxlKGVmZnRveF9zdXBlcmlvcml0eShtb2QyJGZpdCksIGRpZ2l0cyA9IDIsIHJvdy5uYW1lcyA9IFRSVUUpCmBgYAoKVGhlIGVsZW1lbnQgaW4gcm93ICRpJCBhbmQgY29sdW1uICRqJCBzaG93cyAkXHRleHR7UHJvYih9dV9qID4gdV9pIHwgXHRleHR7ZGF0YSl9JCwgd2hlcmUgJHVfayQgaXMgdGhlIHV0aWxpdHkgb2YgZG9zZSAkayQuCldlIGNhbiBiZSBxdWl0ZSBjb25maWRlbnQgdGhhdCBkb3NlIDMgaGFzIGhpZ2hlciB1dGlsaXR5IHRoYW4gZG9zZXMgMSBhbmQgMi4KSW4gY29udHJhc3QsIHRoZSBtb2RlbCBpcyBtdWNoIG1vcmUgdmFndWUgYWJvdXQgd2hpY2ggaXMgdGhlIHN1cGVyaW9yIG9mIGRvc2VzIDMsIDQgYW5kIDUuClRoYXQgaXMgcGxlbnR5IG9mIG1vdGl2YXRpb24gdG8gY29udGludWUgdGhlIGNsaW5pY2FsIHRyaWFsLgoKIyBEaXNjdXNzaW9uCkluIENSTSwgcHJpb3IgaW5mb3JtYXRpb24gaXMgY29udmV5ZWQgbm90IGp1c3QgdGhyb3VnaCBwcmlvciBkaXN0cmlidXRpb25zIG9uIHRoZSBwYXJhbWV0ZXJzLgpXaGVuIHVzaW5nIGEgQ1JNIGRlc2lnbiwgdGhlIHRyaWFsaXN0cyBzcGVjaWZ5IHRoZWlyIGluaXRpYWwgZ3Vlc3NlcyBmb3IgdGhlIGRvc2UtcHJvYih0b3hpY2l0eSkgcmVsYXRpb25zaGlwLCByZWZlcnJlZCB0byBhcyB0aGUgX3NrZWxldG9uXywgYW5kIHRoaXMgb2JqZWN0IGNvbnZleXMgbWF0ZXJpYWwgcHJpb3IgaW5mb3JtYXRpb24uClRoaXMgaW5mb3JtYXRpb24gaXMgdHlwaWNhbGx5IGluZm9ybWVkIGJ5IGRhdGEgb24gdGhpcyBkcnVnIGluIG90aGVyIHBhdGllbnQgZ3JvdXBzLCBzaW1pbGFyIGRydWdzIGluIHRoaXMgb3IgcmVsYXRlZCBwYXRpZW50IGdyb3VwcywgYW5kIHByZS1jbGluaWNhbCBkYXRhLgpUaGUgcHJvdmlzaW9uIG9mIHByaW9yIGluZm9ybWF0aW9uIGlzIGRlc2lyYWJsZSwgZm9yIGV4YW1wbGUsIHdoZW4geW91IGNvbnNpZGVyIHRoYXQgYXBwcm9wcmlhdGUgZG9zZSBzZWxlY3Rpb25zIG11c3QgYmUgbWFkZSBhdCBhbGwgdGltZXMgeWV0IGEgZG9zZS1maW5kaW5nIHRyaWFsIGRlc2lnbiB3aWxsIHR5cGljYWxseSBiZSBpbnZva2VkIG9uIGEgdmVyeSBzbWFsbCBhbW91bnQgb2YgZGF0YS4KSW4gZWFybHkgY29ob3J0cywgZG9zZSBzZWxlY3Rpb25zIGFyZSBkcml2ZW4gbWF0ZXJpYWxseSBieSBpbnZlc3RpZ2F0b3JzJyBwcmlvciBiZWxpZWZzLgpJbiBsYXR0ZXIgY29ob3J0cyB3aGVuIG1vcmUgZGF0YSBpcyBhdmFpbGFibGUsIHRoZSBkZWNpc2lvbnMgc2hvdWxkIGluY3JlYXNpbmdseSBiZSBkcml2ZW4gYnkgdGhlIG9ic2VydmVkIG91dGNvbWVzLgpUaGUgZ29hbCBpcyBhIHBhcmFtZXRlcmlzYXRpb24gdGhhdCB3aWxsIGJlIGV4cGVjdGVkIHRvIHBlcmZvcm0gd2VsbCB3aGV0aGVyIHRoZSBpbnZlc3RpZ2F0b3JzJyBwcmlvciBiZWxpZWZzIGFyZSBjb3JyZWN0IG9yIG5vdC4KVGh1cywgc2ltdWxhdGlvbiBzdHVkaWVzIGFyZSBnZW5lcmFsbHkgdXNlZCB0byBkZXJpdmUgYSBkZXNpZ24gdGhhdCBkZWxpdmVycyBhY2NlcHRhYmxlIG9wZXJhdGluZyBjaGFyYWN0ZXJpc3RpY3Mgb3ZlciBhIHJhbmdlIG9mIHNjZW5hcmlvcy4KTWV0aG9kcyBmb3IgY29uZHVjdGluZyBDUk0gc2ltdWF0aW9uIHN0dWRpZXMgYXJlIG5vdCBjdXJyZW50bHkgcHJvdmlkZWQgaW4gYHRyaWFscmAgYnV0IHdpbGwgYmUgYWRkZWQgaW4gZnV0dXJlLgoKSW4gdGhlIExldnkgQ1JNIGV4YW1wbGUsIHRoZSBpbnRlcmNlcHQgd2FzIGZpeGVkLgpUaGlzIGlzIGEgZmFpcmx5IHN0cm9uZyBjb25zdHJhaW50IG9uIHRoZSBtb2RlbC4KU29tZSBhdXRob3JzIGluY2x1ZGluZyBOZXVlbnNjaHdhbmRlciBfZXQgYWwuXyAoMjAwOCkgaGF2ZSBhZHZvY2F0ZWQgYSB0d28tcGFyYW1ldGVyIG1vZGVsIGJlY2F1c2UgaXQgaXMgbW9yZSBmbGV4aWJsZS4KSG93ZXZlciwgdGhlIGxlYWQgYXV0aG9yIG9mIENSTSBpcyBjcml0aWNhbCBvZiB0aGlzIGFwcHJvYWNoOiAKCj4gQWx0aG91Z2ggYSB0d28tcGFyYW1ldGVyIG1vZGVsIG1heSBhcHBlYXIgbW9yZSBmbGV4aWJsZSwgdGhlIGNvbnZlcmdlbmNlIHByb3BlcnR5IG9mIENSTSBtZWFucyB0aGF0IHVsdGltYXRlbHkgd2Ugd2lsbCBub3Qgb2J0YWluIGluZm9ybWF0aW9uIG5lZWRlZCB0byBmaXQgdHdvIHBhcmFtZXRlcnMuIChPJ1F1aWdsZXkgX2V0IGFsLl8gLCAyMDEzKQoKLCBhZHZvY2F0aW5nIHRoZSBzaW5nbGUgcGFyYW1ldGVyIGFwcHJvYWNoIGluc3RlYWQuClRoZXJlIGFyZSBleGFtcGxlcyBvZiBib3RoIGluIHRoZSBsaXRlcmF0dXJlIGFuZCB2YXJpYW50cyBvZiBlYWNoIGFyZSBwcm92aWRlZCBpbiBgdHJpYWxyYC4KCkluIG1hbnkgaW5zdGFuY2VzLCBjYW5jZXIgcGF0aWVudHMgcmVjZWl2ZSBhIGNvbWJpbmF0aW9uIG9mIGRydWdzIHRvIGNvbWJhdCB0aGVpciBkaXNlYXNlLgpPZnRlbiwgYSBuZXcgZHJ1ZyBpcyBleHBlcmltZW50YWxseSBhZGRlZCB0byBhbiBlc3RhYmxpc2hlZCBzdGFuZGFyZCBvZiBjYXJlIGFuZCB0aGUgZG9zZS1maW5kaW5nIHNjZW5hcmlvIGNhbiBiZSBhcHByb2FjaGVkIGluIG9uZSBvZiB0d28gd2F5cy4KV2hlcmUgdGhlIGRvc2Ugb2YgdGhlIHN0YW5kYXJkIHRoZXJhcHkgaXMgcmVnYXJkZWQgYXMgZml4ZWQsIGEgZG9zZSBmb3IgdGhlIG5ldyB0aGVyYXB5IF90byBiZSBnaXZlbiBpbiBjb21iaW5hdGlvbiB3aXRoIHRoZSBzdGFuZGFyZCB0aGVyYXB5XyBpcyBzb3VnaHQsIGVmZmVjdGl2ZWx5IG1ha2luZyB0aGUgZG9zZS1maW5kaW5nIGV4ZXJjaXNlIGEgb25lLWRpbWVuc2lvbmFsIHByb2JsZW0uCkluIHRoaXMgc2V0dGluZywgZGVzaWducyBsaWtlIENSTSBhcmUgaGVscGZ1bC4KSW4gY29udHJhc3QsIGlmIHRoZSBkb3NlIG9mIG1vcmUgdGhhbiBvbmUgZHJ1ZyBpcyB0byBiZSB2YXJpZWQgaW4gcHVyc3VpdCBvZiBhIHRvbGVyYWJsZSBjb21iaW5hdGlvbiwgZG9zZS1maW5kaW5nIG1ldGhvZHMgZm9yIGRydWcgY29tYmluYXRpb25zIGFyZSByZXF1aXJlZC4KVGhlcmUgYXJlIHZhcmlhbnRzIG9mIHRoaXMgYXBwcm9hY2ggdGhhdCBoYXZlIGFyaXNlbiBmcm9tIHRoZSBDUk0gKGUuZy4gV2FnZXMgX2V0IGFsLl8sIDIwMTEpIGFuZCBvdGhlcnMgdGhhdCBoYXZlIGFyaXNlbiBpbmRlcGVuZGVudGx5IChlLmcuIE1hbmRlciAmIFN3ZWV0aW5nLCAyMDE1KS4KCkl0IGlzIGltcG9ydGFudCB0byBzdHJlc3MgdGhhdCBkb3NlLWZpbmRpbmcgY2xpbmljYWwgdHJpYWwgZGVzaWducyBhcmUgbWVyZWx5IHN0YXRpc3RpY2FsIHRvb2xzIHRoYXQgcHJvdmlkZSBpbnNpZ2h0IGFuZCBpbXBseSByZWNvbW1lbmRhdGlvbnMuClRoZXkgYXJlIG5vdCByb2JvdHMgdGhhdCBkZWNpZGUgd2hhdCBkb3NlIGEgcGF0aWVudCB3aWxsIHJlY2VpdmU7IHRoZSBwaHlzaWNpYW4gYW5kIHRoZSBwYXRpZW50IHJldGFpbiB0aGF0IHJlc3BvbnNpYmlsaXR5LgpXaGVuIGFzc2Vzc2luZyBkb3NlIGVzY2FsYXRpb24gYW5kIGRlLWVzY2FsYXRpb24sIHRyaWFsaXN0cyB0eXBpY2FsbHkgY29uc2lkZXIgbWFueSBmYWN0b3JzIGxpa2UgdGhlIG5hdHVyZSBvZiB0aGUgc3BlY2lmaWMgcGF0aWVudCBwb3B1bGF0aW9uLCBsYWJvcmF0b3J5IHRlc3QgdmFsdWVzLCBiaW9tYXJrZXJzIGFuZCBvdmVyYWxsIGFkdmVyc2UgZXZlbnQgcHJvZmlsZSBpbiBhZGRpdGlvbiB0byB0aGUgcHJlc2VuY2Ugb3IgYWJzZW5jZSBvZiBmb3JtYWwgX2Rvc2UtbGltaXRpbmcgdG94aWNpdHlfLgpEb3NlIGVzY2FsYXRpb24gaXMgbm90IHVuZGVydGFrZW4ganVzdCBiZWNhdXNlIGl0IGlzIGFkdm9jYXRlZCBieSBhIG1vZGVsLgpUaGF0IHNhaWQsIHN0YXRpc3RpY2FsIGRvc2UtZmluZGluZyBkZXNpZ25zIGhhdmUgYW4gaW1wb3J0YW50IHJvbGUgdG8gcGxheSBpbiB0aGUgZWZmaWNpZW50IGFuYWx5c2lzIG9mIG91dGNvbWVzIGFuZCB0aGUgcHJvbW90aW9uIG9mIHJhdGlvbmFsIGRlY2lzaW9uIG1ha2luZy4KSW4gdGhpcyByZWdhcmQsIHRoZXkgYXJlIHN1cGVyaW9yIHRvIHJ1bGUtYmFzZWQgZGVzaWducyBsaWtlIDMrMyB0aGF0IGhhdmUgbGl0dGxlIHN0YXRpc3RpY2FsIGp1c3RpZmljYXRpb24uCgojIGB0cmlhbHJgClNvZnR3YXJlIGlzIGF2YWlsYWJsZSBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9icm9ja2svdHJpYWxyCkl0IGlzIGN1cnJlbnRseSB1bmRlciBkZXZlbG9wbWVudC4KVGhlIGludHJvZHVjdGlvbiBvZiBgcnN0YW5hcm1gIGFuZCBgYnJtc2AgaGF2ZSBwZXJoYXBzIHJlbW92ZWQgdGhlIG5lZWQgdG8gcHJlLWNvbXBpbGUgbWFueSBleHBlcmltZW50YWwgZGVzaWducy4KVGhpcyBwYWNrYWdlIHdpbGwgY29udGludWUgdG8gZm9jdXMgb24gaW1wbGVtZW50aW5nIEJheWVzaWFuIGNsaW5pY2FsIHRyaWFsIGRlc2lnbnMsIHBhcnRpY3VsYXJseSB0aG9zZSB3aXRoIG5vbi1zdGFuZGFyZCBsaWtlbGlob29kIGZ1bmN0aW9ucyBvciB0aG9zZSB0aGF0IGFyZSBub24tdHJpdmlhbCB0byBpbXBsZW1lbnQgaW4gYHJzdGFuYXJtYCBhbmQgYGJybXNgLgoKIyBBbHRlcm5hdGl2ZSBzb2Z0d2FyZQoKIyMjIENSTQoKVGhlcmUgYXJlIHNldmVyYWwgUi1wYWNrYWdlcyB0aGF0IGltcGxlbWVudCBDUk06CgoqIGBkZmNybWAgdXNlcyBudW1lcmljYWwgaW50ZWdyYXRpb24gdG8gZXN0aW1hdGUgcG9zdGVyaW9yIHBhcmFtZXRlciBtZWFucywgYW5kIHBsdWdzIHRob3NlIGludG8gJEYkIHRvIGVzdGltYXRlIHRoZSBleHBlY3RlZCBQcm9iKERMVCkuIFRoaXMgcGFja2FnZSBkb2VzIG5vdCB1c2UgTUNNQyBvciBwcm9kdWNlIHBvc3RlcmlvciBkcmF3cy4gVGhpcyBwYWNrYWdlIGFjY29tcGFuaWVzIHRoZSBib29rIGJ5IENoZXVuZyAoMjAxMSkuCiogYGJjcm1gIHVzZXMgbnVtZXJpY2FsIGludGVncmF0aW9uIG9yIE1DTUMgdmlhIEJVR1Mgb3IgSkFHUyB0byBmaXQgdGhlIG1vZGVsLgoqIGBjcm1QYWNrYCBpcyBtb3JlIHJlY2VudCB0aGFuIHRoZSBvdGhlciB0d28gYW5kIGFwcGVhcnMgdG8gYmUgdmVyeSBjb21wcmVoZW5zaXZlLiBJdCB0b28gb2ZmZXJzIE1DTUMgc2FtcGxpbmcgdmlhIEJVR1MgYW5kIEpBR1MuCgpUbyBvdXIga25vd2xlZGdlLCBgdHJpYWxyYCBpcyB0aGUgZmlyc3QgdG8gaW1wbGVtZW50IENSTSBpbiBTdGFuLgoKCiMjIyAgRWZmVG94CgpFZmZUb3ggc29mdHdhcmUgaXMgYXZhaWxhYmxlIGZyb20gW3RoZSBNRCBBbmRlcnNvbiB3ZWJzaXRlXShodHRwczovL2Jpb3N0YXRpc3RpY3MubWRhbmRlcnNvbi5vcmcvc29mdHdhcmVkb3dubG9hZC9TaW5nbGVTb2Z0d2FyZS5hc3B4P1NvZnR3YXJlX0lkPTIpLgpJdCBpcyBhIC5OZXQgYXBwbGljYXRpb24gc28gb25seSBydW5zIG9uIFdpbmRvd3MuClNvdXJjZS1jb2RlIGlzIG5vdCBnZW5lcmFsbHkgYXZhaWxhYmxlLCBidXQgSSBoYXZlIG5ldmVyIHJlcXVlc3RlZCBpdC4KSSB3YXMgbW90aXZhdGVkIHRvIGNyZWF0ZSBhbiBvcGVuLXNvdXJjZSBpbXBsZW1lbnRhdGlvbiBvZiBFZmZUb3ggd2hpbHN0IHdvcmtpbmcgb24gYSB0cmlhbCB0aGF0IHVzZWQgdGhlIGRlc2lnbiAoQnJvY2sgX2V0IGFsLl8sIDIwMTcpLgpTaXR1YXRpb25zIGFyb3NlIHdoZXJlIHdlIHdhbnRlZCB0byBhZGp1c3QgdGhlIGJlaGF2aW91ciBvZiB0aGUgZGVzaWduLgoKVG8gb3VyIGtub3dsZWRnZSwgYHRyaWFscmAgaXMgdGhlIGZpcnN0IHRvIGltcGxlbWVudCBFZmZUb3ggaW4gUiBvciBTdGFuLgoKCiMgQWNrbm93bGVkZ2VtZW50cwpXZSBleHRlbmQgc2luY2VyZSB0aGFua3MgdG8gdGhlIHR3byBhbm9ueW1vdXMgcmV2aWV3ZXJzIGZvciB0aGVpciB2YWx1YWJsZSBzdWdnZXN0aW9ucy4KCiMgUmVmZXJlbmNlcwoKQnJhdW4sIFQuIE0uICgyMDAyKS4gVGhlIGJpdmFyaWF0ZSBjb250aW51YWwgcmVhc3Nlc3NtZW50IG1ldGhvZDogRXh0ZW5kaW5nIHRoZSBDUk0gdG8gcGhhc2UgSSB0cmlhbHMgb2YgdHdvIGNvbXBldGluZyBvdXRjb21lcy4gQ29udHJvbGxlZCBDbGluaWNhbCBUcmlhbHMsIDIzKDMpLCAyNDDigJMyNTYuIGh0dHBzOi8vZG9pLm9yZy8xMC4xMDE2L1MwMTk3LTI0NTYoMDEpMDAyMDUtNwoKQnJvY2ssIEsuLCBCaWxsaW5naGFtLCBMLiwgQ29wbGFuZCwgTS4sIFNpZGRpcXVlLCBTLiwgU2lyb3ZpY2EsIE0uLCAmIFlhcCwgQy4gKDIwMTcpLiBJbXBsZW1lbnRpbmcgdGhlIEVmZlRveCBkb3NlLWZpbmRpbmcgZGVzaWduIGluIHRoZSBNYXRjaHBvaW50IHRyaWFsLiBCTUMgTWVkaWNhbCBSZXNlYXJjaCBNZXRob2RvbG9neSwgMTcoMSksIDExMi4gaHR0cHM6Ly9kb2kub3JnLzEwLjExODYvczEyODc0LTAxNy0wMzgxLXgKCkNoZXVuZywgWS4gSy4gKDIwMTEpLiBEb3NlIEZpbmRpbmcgYnkgdGhlIENvbnRpbnVhbCBSZWFzc2Vzc21lbnQgTWV0aG9kLiBOZXcgWW9yazogX0NoYXBtYW4gJiBIYWxsIC8gQ1JDIFByZXNzXy4KCkNoZXVuZywgWS4gSy4sICYgQ2hhcHBlbGwsIFIuICgyMDAwKS4gU2VxdWVudGlhbCBkZXNpZ25zIGZvciBwaGFzZSBJIGNsaW5pY2FsIHRyaWFscyB3aXRoIGxhdGUtb25zZXQgdG94aWNpdGllcy4gQmlvbWV0cmljcywgNTYoNCksIDExNzfigJMxMTgyLgoKR2Fyb24sIEUuIEIuLCBSaXp2aSwgTi4gYSwgSHVpLCBSLiwgTGVpZ2hsLCBOLiwgQmFsbWFub3VraWFuLCBBLiBTLiwgRWRlciwgSi4gUC4sIOKApiBLRVlOT1RFLTAwMSBJbnZlc3RpZ2F0b3JzLiAoMjAxNSkuIFBlbWJyb2xpenVtYWIgZm9yIHRoZSB0cmVhdG1lbnQgb2Ygbm9uLXNtYWxsLWNlbGwgbHVuZyBjYW5jZXIuIFRoZSBOZXcgRW5nbGFuZCBKb3VybmFsIG9mIE1lZGljaW5lLCAzNzIoMjEpLCAyMDE44oCTMjguIGh0dHBzOi8vZG9pLm9yZy8xMC4xMDU2L05FSk1vYTE1MDE4MjQKCkzDqXZ5LCBWLiwgWm9oYXIsIFMuLCBCYXJkaW4sIEMuLCBWZWtob2ZmLCBBLiwgQ2hhb3VpLCBELiwgUmlvLCBCLiwg4oCmIE1hcmllLCBKLiBQLiAoMjAwNikuIEEgcGhhc2UgSSBkb3NlLWZpbmRpbmcgYW5kIHBoYXJtYWNva2luZXRpYyBzdHVkeSBvZiBzdWJjdXRhbmVvdXMgc2VtaXN5bnRoZXRpYyBob21vaGFycmluZ3RvbmluZSAoc3NISFQpIGluIHBhdGllbnRzIHdpdGggYWR2YW5jZWQgYWN1dGUgbXllbG9pZCBsZXVrYWVtaWEuIF9Ccml0aXNoIEpvdXJuYWwgb2YgQ2FuY2VyXywgOTUoMyksIDI1M+KAkzI1OS4gaHR0cHM6Ly9kb2kub3JnLzEwLjEwMzgvc2ouYmpjLjY2MDMyNjUKCk1hbmRlciwgQS4gUC4sICYgU3dlZXRpbmcsIE0uIEouICgyMDE1KS4gQSBwcm9kdWN0IG9mIGluZGVwZW5kZW50IGJldGEgcHJvYmFiaWxpdGllcyBkb3NlIGVzY2FsYXRpb24gZGVzaWduIGZvciBkdWFsLWFnZW50IHBoYXNlIEkgdHJpYWxzLiBTdGF0aXN0aWNzIGluIE1lZGljaW5lLiBodHRwczovL2RvaS5vcmcvMTAuMTAwMi9zaW0uNjQzNAoKTWFuZHJla2FyLCBTLiBKLiwgUWluLCBSLiwgJiBTYXJnZW50LCBELiBKLiAoMjAxMCkuIE1vZGVsLWJhc2VkIHBoYXNlIEkgZGVzaWducyBpbmNvcnBvcmF0aW5nIHRveGljaXR5IGFuZCBlZmZpY2FjeSBmb3Igc2luZ2xlIGFuZCBkdWFsIGFnZW50IGRydWcgY29tYmluYXRpb25zOiBNZXRob2RzIGFuZCBjaGFsbGVuZ2VzLiBTdGF0aXN0aWNzIGluIE1lZGljaW5lLCAyOSgxMCksIDEwNzfigJMxMDgzLiBodHRwczovL2RvaS5vcmcvMTAuMTAwMi9zaW0uMzcwNgoKTmV1ZW5zY2h3YW5kZXIsIEIuLCBCcmFuc29uLCBNLiwgJiBHc3BvbmVyLCBULiAoMjAwOCkuIENyaXRpY2FsIGFzcGVjdHMgb2YgdGhlIEJheWVzaWFuIGFwcHJvYWNoIHRvIHBoYXNlIEkgY2FuY2VyIHRyaWFscy4gU3RhdGlzdGljcyBpbiBNZWRpY2luZSwgMjcoMTMpLCAyNDIw4oCTMjQzOS4gaHR0cHM6Ly9kb2kub3JnLzEwLjEwMDIvc2ltLjMyMzAKCk/igJlRdWlnbGV5LCBKLiwgUGVwZSwgTS4sICYgRmlzaGVyLCBMLiAoMTk5MCkuIApDb250aW51YWwgcmVhc3Nlc3NtZW50IG1ldGhvZDogYSBwcmFjdGljYWwgZGVzaWduIGZvciBwaGFzZSAxIGNsaW5pY2FsIHRyaWFscyBpbiBjYW5jZXIuIF9CaW9tZXRyaWNzXywgNDYoMSksIDMz4oCTNDguIGh0dHBzOi8vZG9pLm9yZy8xMC4yMzA3LzI1MzE2MjgKCk/igJlRdWlnbGV5LCBKLiwgJiBDb25hd2F5LCBNLiAoMjAxMSkuIENvbnRpbnVhbCBSZWFzc2Vzc21lbnQgYW5kIFJlbGF0ZWQgRG9zZS1GaW5kaW5nIERlc2lnbnMuIFN0YXRpc3RpY2FsIFNjaWVuY2UsIDI1KDIpLCAyMDLigJMyMTYuIGh0dHBzOi8vZG9pLm9yZy8xMC4xMjE0LzEwLVNUUzMzMi5Db250aW51YWwKClRoYWxsLCBQLiwgJiBDb29rLCBKLiAoMjAwNCkuIERvc2UtRmluZGluZyBCYXNlZCBvbiBFZmZpY2FjeS1Ub3hpY2l0eSBUcmFkZS1PZmZzLiBfQmlvbWV0cmljc18sIDYwKDMpLCA2ODTigJM2OTMuCgpUaGFsbCwgUC4sIENvb2ssIEouLCAmIEVzdGV5LCBFLiAoMjAwNikuIEFkYXB0aXZlIGRvc2Ugc2VsZWN0aW9uIHVzaW5nIGVmZmljYWN5LXRveGljaXR5IHRyYWRlLW9mZnM6IGlsbHVzdHJhdGlvbnMgYW5kIHByYWN0aWNhbCBjb25zaWRlcmF0aW9ucy4gSm91cm5hbCBvZiBCaW9waGFybWFjZXV0aWNhbCBTdGF0aXN0aWNzLCAxNig1KSwgNjIz4oCTNjM4LiBodHRwczovL2RvaS5vcmcvMTAuMTA4MC8xMDU0MzQwMDYwMDg2MDM5NAoKVGhhbGwsIFAuLCBIZXJyaWNrLCBSLiwgTmd1eWVuLCBILiwgVmVuaWVyLCBKLiwgJiBOb3JyaXMsIEouICgyMDE0KS4gRWZmZWN0aXZlIHNhbXBsZSBzaXplIGZvciBjb21wdXRpbmcgcHJpb3IgaHlwZXJwYXJhbWV0ZXJzIGluIEJheWVzaWFuIHBoYXNlIEktSUkgZG9zZS1maW5kaW5nLiBDbGluaWNhbCBUcmlhbHMsIDExKDYpLCA2NTfigJM2NjYuIGh0dHBzOi8vZG9pLm9yZy8xMC4xMTc3LzE3NDA3NzQ1MTQ1NDczOTcKCldhZ2VzLCBOLiBBLiwgQ29uYXdheSwgTS4gUi4sICYgT+KAmVF1aWdsZXksIEouICgyMDExKS4gRG9zZS1maW5kaW5nIGRlc2lnbiBmb3IgbXVsdGktZHJ1ZyBjb21iaW5hdGlvbnMuIENsaW5pY2FsIFRyaWFscyAoTG9uZG9uLCBFbmdsYW5kKSwgOCg0KSwgMzgw4oCTMzg5LiBodHRwczovL2RvaS5vcmcvMTAuMTE3Ny8xNzQwNzc0NTExNDA4NzQ4Cgpab2hhciwgUy4sIExhdG91Y2hlLCBBLiwgVGFjb25uZXQsIE0uLCAmIENoZXZyZXQsIFMuICgyMDAzKS4gU29mdHdhcmUgdG8gY29tcHV0ZSBhbmQgY29uZHVjdCBzZXF1ZW50aWFsIEJheWVzaWFuIHBoYXNlIEkgb3IgSUkgZG9zZS1yYW5naW5nIGNsaW5pY2FsIHRyaWFscyB3aXRoIHN0b3BwaW5nIHJ1bGVzLiBDb21wdXRlciBNZXRob2RzIGFuZCBQcm9ncmFtcyBpbiBCaW9tZWRpY2luZSwgNzIoMiksIDExN+KAkzEyNS4gaHR0cHM6Ly9kb2kub3JnLzEwLjEwMTYvUzAxNjktMjYwNygwMikwMDEyMC03CgoKCiMgU2Vzc2lvbiBJbmZvCmBgYHtyfQpzZXNzaW9uSW5mbygpCmBgYAoK