Introduction

We have probably heard the ongoing debate of whether money can make people happy. For our part, money might not make someone happy yet a significant portion of the things that make people happy requires money. Therefore, the lack of wealth might be at the origin of depression of an individual as they do not have the means necessary to do what makes them happy. Do people who are living in poverty experience depression more than those who are not? To get an idea of this relationship, it would be good to answer the question of how does poverty affect depression?

Additionally, according to the American Journal of Preventive Medicine, 9.2% of Americans aged ≥12 years experienced a past-year major depressive episode. Particularly, the Covid-19 has impacted people’s mental health because of the social distancing rules, and the pandemic made it harder to workout. Thus, understanding some other unconventional factors that might have an effect on depression becomes crucial to act upon in at an individual and a collective level. Thus, we were wondering if there is relationship between exercising and depression? In fact, it would be interesting to explore if there is a relationship between physical activity and depression. Certainly, a person’s ability to exercise might depend on their financial situation. Those who are higher compared to the poverty guidelines can afford some time to workout while some who are not in such a privileged situation might need to work more and harder, and in doing so have less time to workout. From this observation, one can wonder whether being physically active has an impact on the relationship between wealth depression.

Our primary objective is to explore the variables related to depression by specifically looking at an individual’s physical activity levels and the socioeconomic conditions of participants. The former will help our team identify if physical activity promotes a healthier mind, while the latter variable will help identify a trend on if and how financial situations impact one’s mental health. In sum, our final goal is to better understand the relationship between these factors so as to identify potential risk factors or protective factors that could help indicate mental health outcomes.

Research Question

To explore these relationships stated in the introduction, we will try to answer the following question:

How does poverty and physical activity affect the odds of having depression?

To answer these questions, we will use the variables Poverty, Physical Active (PhysActive) and Depression. Further explanation will be provided later on how we chose these variables in the data section. The explanatory variables in our study are Poverty and Physical Active. The outcome variable is Depression and is a binary variable. The poverty variable is a ratio of family income to poverty guidelines. Smaller numbers indicate more poverty. This variable helps us to take into consideration the wealth of a person. The Physical Active (PhysActive) variable is used because it provides us information on whether a person is physically active or not. The depression variable indicates the depression status of a person.

Data

Context

The dataset NHANES contains 10000 units of observations or individuals of all ages from the “the non-institutionalized civilian population of the United States. This dataset includes 75 variables that include demographic, socioeconomic, dietary, and health related questions. In particular, the vast majority of the variables come from interviews, and the remaining variables are the results of medical, dental and physiological examinations.

As our research questions focus on predicting what variables might affect Depression of a person, we decided to explore the variable Physical Active (PhysActive) as our outcome variable. For the latter variable, study participants 12 years or older, responded as “Yes” or “No” if they did moderate or vigorous-intensity sports, fitness or recreational activities. In addition, we decided to use the variable for Poverty, which is the ratio of the family’s income to poverty guidelines. Moreover, this survey is executed by the National Health and Nutrition survey (NHANES), which is a comprehensive study designed to assess the health and nutritional status of adults and children in the United States for the 2009-2012 sample years. Furthermore, the data collected aims at identifying emerging health issues among the target population, which enables policymakers, researchers and public health organizations to analyze trends in health and nutritional status, and assess the effectiveness of public policies. It is important to emphasize that the survey is conducted by a team of trained health professionals and researchers, who travel to various locations across the US to obtain from a representative sample of the target population. This team includes physicians, nurses, laboratory technicians, who conduct physical examinations, collect biological specimens, and perform the interviews and questionnaires.

According to the NHANES website, they used a four-stage study to collect the data. The first stage consisted of selecting the Primary Sampling Units (PSUs) from a frame of all U.S. counties, and a total of 15 counties were chosen for the 2009-2012 period. The second stage consisted of selecting Secondary sampling units (SSUs), within each PSU, segments were chosen based on geographical boundaries, and a total of 130 segments were selected during the sampling period. The third stage involved the random selections of households from the latter SSUs, from which all these households were invited to participate in the survey. Lastly, in the fourth stage the focus was on the selection of all individuals regardless of their eligibility for all components of the study, for instance, not all participants were eligible for laboratory tests. It is relevant to mention that the study has been carried out since 1960, and every sampling period has been adjusted to make the study more representative of the US population. Specifically, the data undergoes a statistical weighting adjustment to undo oversampling and undersampling of some population subgroups, including non-Hispanic Black people, Mexican Americans, and low income individuals. This process ensures there are no biases in the representation and provides a more reliable analysis.

The original dataset can be found on the Center for Disease Control and Prevention (CDC) website by clicking on the Data & Stats button in the initial window displayed. To access the data, one could type “NHANES” on the search bar, and a link to the NHANES page will appear. Then, the user could click again on Survey Data and Documentation, and click on the dataset of interest (2009-2010 and 2011-2012), or by clicking on the following link: https://wwwn.cdc.gov/nchs/nhanes/Default.aspx. Nevertheless, the most straightforward method to obtain the clean data set is by downloading the R Package “NHANES”, and adding it to our R environment. This data set accounts for the period 2009-2012 with adjusted weighting, and it is the dataset that we used in the rest of our study.

Data Cleaning

Based on the NHANES dataset, we created a new dataset called depressed_data in which we selected only 3 variables we choose to examine for our research question: Depressed, Poverty, and PhysActive.

The Depressed variable–which is a self-reported range of days where participants felt down, depressed or hopeless–carries 3 values: None, Several, Most. We converted None values to 0,Several and Most to 1. This allows us to support our logistic regression model with Depressed as our response variable and predict it as a binary categorical variable with two possible outcome values be \(Y=0\) and \(Y=1\).

We then filtered out any NA values under Depressed in order not to cause too much data noise.

Exploratory Data Analysis

From this visualization, we can see that the median poverty values for people who are not physically active are lower (around 2.8 for not depressed and 1.5 for depressed) than the median poverty values for those who are physically active (around 3.5 for not depressed and 2.9 for depressed). The interquartile lengths and ranges between observations that are physically active and are not are noticeably different. While the bins describing those who are physically inactive have their interquartile ranges from about 1.3 to 4.3 for not depressed and from 1 to 2.0 for depressed, those of observations that reported physically active ranges from 1.9 to 5 for not depressed and from 1.4 to 5 for depressed. It is also significant to note that for batches of data under physically active are left-skewed, the batches for data under physically inactive are right-skewed for those that reported for depression yet left-skewed for those that reported for no depression.

Logistic Regression

Model Creation

As we wanted to predict the probability of an individual based on whether or not they are physically active and depending on their poverty status we decided to use a logistic regression model instead of a liner regression model. For convenience, we proceeded to use a logistic regression model as our final model since our outcome variable Depressed is a binary variable.

Moreover, at first we wanted to use the variables Poverty and Physical Activity as explanatory variables without an interaction term. However, during our EDA we noticed that poverty might have an interaction effect with the Physical Active variable. To elaborate on this, Figure 1 shows that the median of those individuals who are physically active, regardless of whether or not they are depressed seem to be concentrated in a higher number of the poverty level variable, which might suggest that physically active individuals may have a lower poverty. Hence, in order to account for these subtle differences, we allowed poverty to interact with the variable Physical Active.

Thus, our final model can be expressed as follows:

\[Odds[Depressed | PhysActive,Poverty] = 0.75 + 0.50 * PhysActiveYes + 0.72*Poverty + 1.14(PhysActiveYes * Poverty)\]

Fitted Model

The table below shows the exponentiated estimated coefficients for our model and the Standard Errors (Lower Bound and Upper Bound) using the Classical Approach:

Table 1: Final Model Estimated (Exponentiated) Coefficients and Standard Errors (SE)
Coefficients Estimates Standard_Errors
Intercept 0.75 0.08
Poverty 0.72 0.03
PhysActiveYes 0.50 0.12
Poverty:PhysActiveYes 1.14 0.04

Model Interpretation

Odds ratio

##           (Intercept)               Poverty         PhysActiveYes 
##             0.7497418             0.7207234             0.5048395 
## Poverty:PhysActiveYes 
##             1.1443316

Intercept Coefficient is approximately equal to 0.75.

The coefficient of 0.75 represents the odds of being depressed when an individual is not physically active and living in poverty (level 1) when all the other predictor variables are equal to zero.

The SE for the Intercept is 0.08: The standard error of the exponentiated intercept coefficient is significantly small. This value might indicate that we have a high precision in estimating the odds of being depressed for the individuals who are not physically active and are in poverty (level 1).

Poverty Coefficient: is approximately equal to 0.720.

Holding all other variables constant, the multiplicative change in estimated odds of being depressed is 0.72 for each unit increase in poverty. Because the odds ratio is less than 1, the odds of being depressed are less with each unit increase in poverty.

The SE for the Poverty Coefficient is 0.03.: The standard error of the poverty coefficient falls is a relatively small value. This value might indicate that there might a high precision in estimating the effect of poverty on the odds of being depressed.

PhysActiveYes Coefficient is approximately equal to 0.505.

Holding all other variables constant, the multiplicative change in estimated odds of being depressed for individuals who are physically active are about 0.505 times less than the estimated odds ratio of being depressed for individuals who are not physically active. In other words, because the odds ratio is less than 1, the estimated odds of being depressed is less with those who are physically active as compared to those who are not physically active.

The SE for the PhysActive Coefficient is 0.12: The standard error of the physical active coefficient falls in a relatively small value. Yet, it is roughly higher in comparison to the aforementioned values for the SE of the other coefficients. We can say that there might be some uncertainty in estimating the effects on physical activity on the odds of being depressed.

Poverty:PhysActiveYes Coefficient is approximately equal to 1.14.

The effect of physical activity on the odds of being depressed differs depending on the level of poverty.

1.14 is the multiplicative difference in estimated odds of being depressed between those who are physically active and physically inactive. In other words, 1.14 is the multiplicative change in the estimated effect of poverty on estimated odds of being depressed between those who are physically active and those who are not, where the effect of poverty on the estimated odds of being depressed is a one unit change in poverty, or the ratio between household income to poverty guidelines. This means that the estimated odds of depression are expected to increase by 114% among individuals who are physically active and living in poverty than those who are not physically active and not living in poverty.

The SE for the Poverty:PhysActive Coefficient is 0.04: The standard error of the interaction coefficient between poverty and physical activity is significantly small, suggesting that there might be a high precision in estimating the effect of the interaction between physical activity and poverty on the odds of being depressed.

95% Confidence Intervals

Table 2: 95 % Confidence Intervals
Coefficients Lower_Bound Upper_Bound
Intercept 0.64 0.88
Poverty 0.68 0.76
PhysActiveYes 0.40 0.64
Poverty:PhysActiveYes 1.06 1.24

The 95 % Confidence Interval (CI) for the Exponentiated Poverty Coefficient:

The CI for the poverty coefficient is (0.68, 0.76), which means that we are 95 % confident that the true population of odds ratio for the Poverty Coefficient is between 0.68 and 0.76. Since the interval does not include the null value of 1 and controlling for the other variables, we can say that Poverty is a significant predictor of the odds of being depressed, In other words, since the interval provided plausible values for the true odds ratio population, we have evidence that suggests that there is a true relationship between poverty and the odds of being depressed.

The 95 % Confidence Interval (CI) for the Exponentiated PhysActiveYes Coefficient:

The CI for the PhysActiveYes coefficient is (0.40, 0.64), indicating that we are 95 % confident that the true population of odds ration lies within (0.40, 0.64). As this interval does not include 1 and controlling for the other variables, we can say that the physical activity coefficient is a relevant variable at predicting the odds of being depressed, as it suggests that there is a true relationship between the Physical Activity and the odds of being depressed.

The 95 % Confidence Interval (CI) for the Exponentiated Poverty: PhysActiveYes Coefficient:

The CI for the Poverty:PhysActiveYes coefficient is (1.06, 1.24). This suggests that we are 95 % confident that the true population of the odds ratio lies within (1.06 and 1.24). Since the interval does not include 1, we can say that there is a true relationship between the effects of physical activity depending on the poverty status on the odds of being depressed.

Model Evaluation

As the first step for evaluating our fitted logistic regression model, we used the augment function to obtain these predicted probabilities for each individual from our dataset, based on the fitted model. Then, we created a box plot that compares our model’s predicted probabilities: one for people who actually self-reported as depressed, and one for people who did not self-report as depressed. Preferably, we would like to observe that our fitted logistic model predicts a higher probability of being depressed for people who actually self-reported as being depressed, and a lower probability of being depressed for those who did not self-report as depressed.

From the boxplot above, we can see that the median probability of the predicted outcome Depressed is higher for people who self-reported as Depressed, at around 0.24. As compared to the median of 0.17 for the predicted outcome of being Depressed for people who did not self-report as Depressed. Furthermore, we can observe that both boxplots are not significantly skewed, which could show that the predicted probabilities are relatively distributed around the median mentioned above. In particular, we can observe that most of the predicted probabilities are lower than 50 percent.

Selecting a Threshold

The next step in our model’s evaluation was to select a threshold that helped us to turn our model’s predicted probabilities into a binary decision. After considering the context of our data, and the significance of the outcomes of this fitted model, we opted to use a threshold of 0.20 which falls in between the two median predicted probabilities for both actual outcomes. Specifically, we acknowledge that it is our priority to have a low rate of false negatives, but also we want to be careful about not having a high number of false positives. For instance, we do not intend to have a high incidence of false negatives that will incorrectly classify many of the individuals as not depressed, when in fact they self-reported as depressed. By looking at it from a wider perspective, such misclassification by our model might have a further impact on the individual’s wellbeing, but also in the way they seek assistance or the type of support they receive. Conversely, we also aim to avoid any high incidence of false positives that will incorrectly classify individuals as depressed, when they actually self-reported otherwise, which might oppositely lead to unnecessary interventions.

The boxplot above shows the same predicted probabilities for both actual outcomes of Depressed and Not Depressed. The dashed line corresponds to the threshold of 0.20 set in between the medians of the predicted probabilities for both actual outcomes.

Calculating the Model Quality Metrics

After selecting the threshold, we moved onto computing the binary predictions from the logistic model. This process allowed us to classify each person in our dataset based on their predicted probability of being Depressed: our model predicted that everyone with a probability higher than our threshold is Depressed, while the rest are not. The contingency table below enables us to compare our model’s predictions to the true outcome, determining whether the individuals were indeed Depressed or not.

Predict Depressed Predict Not Depressed Total
Actually Depressed 821 487 1308
Actually Not Depressed 2064 2858 4922
Total 2885 3345 6230

Then, we proceeded to calculate the binary predictions, as shown by the table below:

Table 3: Quality Metrics
Measures Values
Accuracy 59.05 %
Sensitivity 62.77 %
Specificity 58.07 %
False Negative Rate (FNR) 37.23 %
False Positive Rate (FPR) 41.93 %

Interpreting the Model Quality Metrics

Accuracy: The model’s accuracy falls in a moderate range of 0.5905 that tells us that the model correctly predicted the presence or absence of depression in 59.05% of the cases.

Sensitivity: This is a moderate proportion of actual Depressed cases that were accurately identified as Depressed by the model. In this case, the sensitivity of 0.6277 means that the model correctly identified 62.77 % of the actual Depressed cases.

Specificity: This is the proportion of actual Not Depressed cases that were accurately predicted as Not Depressed by the model. Based on the results, the specificity of the model is somewhat average is 0.5807 meaning that the model correctly identified 58.07 % of the actual Not-Depressed cases.

False Negative Rate (FRN): The proportion of individuals who are actually Depressed but that are predicted by our model as Not Depressed. In this case, 0.3723, which means that among the cases predicted as Not Depressed by the model, 37.23% are actually Depressed. This still relatively high false negative rate means that the model is incorrectly classifying many individuals as Not Depressed, when indeed they self-reported as such.

False Positive Rate (FPR): The proportion of individuals who are actually Not Depressed but are classified as Depressed by the model. In this case, the false positive rate is 0.4193, which means that among the cases predicted as depressed by the model, 41.93 % are actually not depressed. This rate is roughly higher than the FPR, and in this context, this could indicate that the model is incorrectly classifying many individuals as depressed, when they are not, leading to unnecessary interventions or treatment.

Conclusions

General Takeaways

To conclude, our group decided to look at how the ratio between household incomes and national poverty guidelines and physical activity play into an individual’s mental health. We chose to look into this largely because of the current discussions on mental health and how external socioeconomic factors have a major role in impacting this. We decided to look into this curiosity by using the NHANEs data, and looking at the variables surrounding poverty, physical activity, and depression through the use of a logistical regression analysis. The two former of the three act as the explanatory variables, while the latter of the three is both the outcome variable and a binary variable. With this, we created a logistical regression model and analysis so as to better understand this issue, splitting our analysis into modeling and interpreting. We were able to see that the physical activity levels and poverty status of individuals do play a role in predicting if they do or do not suffer from depression. In sum, our logistical regression model shows that, when all other variables are constant, the odds of suffering from depression are higher when living closer to the poverty line. At the same time, the odds of being depressed are higher when there is a lack of physical activity. These two results were consistent with what we had expected to find; We initially think these results are due to the mental strain of financial stressors on top of a low physical activity, which is commonly accepted to lead to less depression. On another note, the interaction term shows that the odds of being depressed is higher for individuals who live further from the national poverty guidelines and who have a higher level of physical activity. Thus, it would be helpful to look at other potential explanatory variables from the dataset to better understand what causes this unexpected result.

We interpreted our confidence intervals to reaffirm that, when alone, conditions of poverty and levels of physical activity are correlated with the odds of an individual suffering from depression. However, we were also able to reaffirm that the state of depression is still largely influenced by the poverty status of the individual as well as their physical activity status interactively. At the same time, our box-plot showed that the median probability of being depressed was higher for those who actually self-reported depression. When adding a threshold to account for the medians of the predicted probabilities for both actual outcomes, we were able to compute that the model was 59% accurate, 63% sensitive and 58% specific. However, the model unfortunately provided many false positives as well as false negatives, falsely classifying many individuals as both depressed and not depressed.

All in all, the NHANEs data can be utilized to conclude that an individual’s proximity to poverty and their level of physical activity clearly play major roles in determining their mental health outcomes as indicated by self-reported depression.

Limitations

After working with the NHANES data set, we identified some limitations that might have an effect on our model. Although this survey strives to collect data from a representative sample of the US population, the sample size is still small in comparison to the actual population, which limits to some extent the scope of our model predictions. Hence, some groups might still be underrepresented. In addition, two of the variables we used to fit our model: Physical Active and Depression are self-reported variables. Indeed, these types of variables are prompt self-biases as the survey respondents might over-report or under-report their behaviors, affecting the accuracy of the data. To illustrate this, some people might have different perspectives on differences in levels, frequency or intensity of physical activity. Furthermore, while self-reporting depression, there might be some stigma or cultural biases associated with mental health which might impact how individuals report their symptoms. In a similar way, there might be a lack of knowledge of the symptoms of depression that contribute to the under-report of depression. Overall, it is important to consider the aforementioned limitations while drawing conclusions from our findings.

Regarding the model quality metrics, we can say that these values are moderate. However, they are not relatively high to conclude that our model can accurately provide a perfect fit to the data given that the predicted probabilities are not closely matching the actual outcomes. For instance, our fitted model performs adequately, but not exceptionally in terms of accuracy, which is the metric that determines how well our model can predict the case for depression and not depression. Furthermore, we acknowledge that when choosing the threshold we aimed at reducing the false negatives produced by our model. Hence, we can say that there are further implications in doing so. An example of this is that the False Positive Rate is moderately high, which indicates that among the individuals who self-reported as not depressed, there is 41.93 % of individuals who are predicted as Depressed by our model.

Therefore, from a personal point of view, this might impact their well-being by creating unnecessary stress on the individuals and the way they seek assistance. Moreover, this effect might potentially put a strain on the healthcare system, which might lead to overburdening of the healthcare system, and it might decrease the quality for those who actually need it.

Lastly, our model did not account for important variables such as gender, age and ethnicity/race. Therefore, for future work it would be interesting to explore other explanatory variables, and see how this might affect the outcome of Depression. As an example, age can have an effect on depression. In fact, a study published by the Journal of Abnormal Psychology found that U.S teens and young adults’ depression has risen significantly over the past decade in comparison with adults 26 or older. Thus, having age as another explanatory variable might improve the metrics of our model.

Appendix

Works Cited

Centers for Disease Control and Prevention. (n.d.). Nhanes questionnaires, datasets, and related documentation. Centers for Disease Control and Prevention. Retrieved April 7, 2023, from https://wwwn.cdc.gov/nchs/nhanes/Default.aspx

Goodwin, R. D., Dierker, L. C., Wu, M., Galea, S., Hoven, C. W., & Weinberger, A. H. (2022, September 19). Trends in U.S. depression prevalence from 2015 to 2020: The widening treatment gap. American Journal of Preventive Medicine. Retrieved April 8, 2023, from https://www.ajpmonline.org/article/S0749-3797(22)00333-6/fulltext#:~:text=An%20increase%20in%20depression%20from,SE%3D0.31%5D%20to%202019%3A

Neighmond, P. (2019, March 14). A rise in depression among teens and young adults could be linked to social media use. NPR. Retrieved April 8, 2023, from https://www.npr.org/sections/health-shots/2019/03/14/703170892/a-rise-in-depression-among-teens-and-young-adults-could-be-linked-to-social-medi

R Code

# Cleaning data
depressed_data <- 
  NHANES %>% 
  select(PhysActive, Depressed, Poverty) %>% 
  mutate(Depressed=case_when(
    Depressed == "Several" | Depressed== "Most" ~ 1,
    Depressed == "None" ~ 0) 
  ) %>% 
  filter(Depressed !="NA") 
# Exploratory Visualization 
depressed_data %>% ggplot(aes(y=PhysActive,x=Poverty,fill=factor(Depressed))) +
  geom_boxplot() +
  labs(y="Physically Active")+
  scale_fill_discrete(name="Depressed")+
  theme_classic()
# Fitted Model

mod <- depressed_data %>%
  with(glm(Depressed ~ Poverty * PhysActive, family = binomial))
coef(mod) %>%
  exp()


confint(mod)%>%
  exp()
# Create table for fitted model
df1 <- data.frame(Coefficients= c("Intercept", "Poverty", "PhysActiveYes", "Poverty:PhysActiveYes"),
                  Estimates = c("0.75", "0.72", "0.50", "1.14"), Standard_Errors = c("(0.64, 0.88)", "(0.68, 0.76)", "(0.4, 0.64)", "(1.05, 1.24)"))

# Output the table using kable()
knitr::kable(df1, align = c("l", "c"), caption = "Final Model Estimated (Exponentiated) Coefficients")
# Model coefficients for model interpretations
mod <- depressed_data %>%
  with(glm(Depressed ~ Poverty * PhysActive, family = binomial))
coef(mod) %>%
  exp()
# Create 95% confidence intervals for coefficients
confint(mod, level = 0.95, type = "Wald") %>% 
  exp()
df2 <- data.frame(Coefficients= c("Intercept", "Poverty", "PhysActiveYes", "Poverty:PhysActiveYes"),
                  Lower_Bound = c("0.64", "0.68", "0.40", "1.06"), Upper_Bound = c("0.88", "0.76", "0.64", "1.24"))

# Output the table using kable()
knitr::kable(df2, align = c("l", "c"), caption = "95 % Confidence Intervals")
threshold <- 0.20

# Boxplots Without Threshold:
mod %>%
  augment(type.predict = 'response') %>% ## get predicted probabilities from model
  ggplot(aes(y = .fitted, x = factor(Depressed))) + ## compare predicted probabilites to actual outcome
  geom_boxplot()  +
  ggtitle('Predictions from Logistic Model') +
  xlab("Actual Outcome (0 = Not Depressed, 1 = Depressed)") +
ylab("Predicted Probability of the Outcome Depressed") +
  theme_minimal()
# Boxplots With threshold:
mod %>%
  augment(type.predict = 'response') %>% ## get predicted probabilities from model
  ggplot(aes(y = .fitted, x = factor(Depressed))) + ## compare predicted probabilites to actual outcome
  geom_boxplot() +
  scale_fill_manual(values=c("#FFB4B4", "#DAFFEA")) +
  ggtitle('Predictions from Logistic Model') +
  labs(subtitle = "The Red Line Represents the Selected Threshold of 0.20") +
  xlab("Actual Outcome (0 = Not Depressed, 1 = Depressed)") +
ylab("Predicted Probability of the Outcome `Depressed`") +
  geom_hline(yintercept = threshold, color = 'red', linetype = 2)  +
  theme_minimal() 
# get binary predictions for mod1
threshold <- 0.20
mod %>%
  augment(type.predict = 'response') %>% ## get predicted probability of callback
  mutate(predictDepressed = .fitted >= threshold) %>% ## predict callback if probability bigger than threshold
  count(Depressed, predictDepressed)
# Create a data frame with the binary predictions: 
df <- data.frame(Measures= c("Accuracy", "Sensitivity", "Specificity", "False Negative Rate (FNR)", "False Positive Rate (FPR)"),
                 Values = c("59.05 %", "62.77 %", "58.07 %", "37.23 %", "41.93 %"))
# Output the table using kable()
knitr::kable(df, align = c("l", "c"), caption = "Quality Metrics")
LS0tCnRpdGxlOiAiRGVwcmVzc2lvbiwgUG92ZXJ0eSwgYW5kIFBoeXNpY2FsIEFjdGl2aXR5ICIKYXV0aG9yOiAiSmFtZXMgSGVybmFuZGV6LCBKb3JkeSBNYXJpbiBVcmJpbmEsIE5hIE5ndXllbiwgYW5kIFN5bHZhaW4gWm9uZy1OYWJhIgpkYXRlOiAiMjAyMy0wMi0yMCIKb3V0cHV0OgogIGJvb2tkb3duOjpodG1sX2RvY3VtZW50MjoKICAgIHNwbGl0X2J5OiBOT05FCiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiAzCiAgICB0b2NfZmxvYXQ6CiAgICAgIHRvY19jb2xsYXBzZWQ6IHRydWUKICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKLS0tCgo8IS0tLSBCZWdpbiBzdHlsaW5nIGNvZGUuIC0tLT4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KLyogV2hvbGUgZG9jdW1lbnQ6ICovCmJvZHl7CiAgZm9udC1mYW1pbHk6ICJQYWxhdGlubyBMaW5vdHlwZSIsICJCb29rIEFudGlxdWEiLCBQYWxhdGlubywgc2VyaWY7CiAgZm9udC1zaXplOiAxMnB0Owp9CmgxLnRpdGxlIHsKICBmb250LXNpemU6IDM4cHg7CiAgdGV4dC1hbGlnbjogY2VudGVyOwp9Cmg0LmF1dGhvciB7CiAgZm9udC1zaXplOiAxOHB4OwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQpoNC5kYXRlIHsKICBmb250LXNpemU6IDE4cHg7CiAgdGV4dC1hbGlnbjogY2VudGVyOwp9Cjwvc3R5bGU+CjwhLS0tIEVuZCBzdHlsaW5nIGNvZGUuIC0tLT4KCmBgYHtyIGxvYWQtcGFja2FnZXMsIG1lc3NhZ2U9RkFMU0UsZWNobz1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoTkhBTkVTKQpsaWJyYXJ5KGJyb29tKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoa25pdHIpCmxpYnJhcnkoZHBseXIpCmBgYAoKCiMgSW50cm9kdWN0aW9uCgogV2UgaGF2ZSBwcm9iYWJseSBoZWFyZCB0aGUgb25nb2luZyBkZWJhdGUgb2Ygd2hldGhlciBtb25leSBjYW4gbWFrZSBwZW9wbGUgaGFwcHkuIEZvciBvdXIgcGFydCwgbW9uZXkgbWlnaHQgbm90IG1ha2Ugc29tZW9uZSBoYXBweSB5ZXQgYSBzaWduaWZpY2FudCBwb3J0aW9uIG9mIHRoZSB0aGluZ3MgdGhhdCBtYWtlIHBlb3BsZSBoYXBweSByZXF1aXJlcyBtb25leS4gVGhlcmVmb3JlLCB0aGUgbGFjayBvZiB3ZWFsdGggbWlnaHQgYmUgYXQgdGhlIG9yaWdpbiBvZiBkZXByZXNzaW9uIG9mIGFuIGluZGl2aWR1YWwgYXMgdGhleSBkbyBub3QgaGF2ZSB0aGUgbWVhbnMgbmVjZXNzYXJ5IHRvIGRvIHdoYXQgbWFrZXMgdGhlbSBoYXBweS4gRG8gcGVvcGxlIHdobyBhcmUgbGl2aW5nIGluIHBvdmVydHkgZXhwZXJpZW5jZSBkZXByZXNzaW9uIG1vcmUgdGhhbiB0aG9zZSB3aG8gYXJlIG5vdD8gVG8gZ2V0IGFuIGlkZWEgb2YgdGhpcyByZWxhdGlvbnNoaXAsIGl0IHdvdWxkIGJlIGdvb2QgdG8gYW5zd2VyIHRoZSBxdWVzdGlvbiBvZiBob3cgZG9lcyBwb3ZlcnR5IGFmZmVjdCBkZXByZXNzaW9uPyAKIApBZGRpdGlvbmFsbHksIGFjY29yZGluZyB0byB0aGUgQW1lcmljYW4gSm91cm5hbCBvZiBQcmV2ZW50aXZlIE1lZGljaW5lLCA5LjIlIG9mIEFtZXJpY2FucyBhZ2VkIOKJpTEyIHllYXJzIGV4cGVyaWVuY2VkIGEgcGFzdC15ZWFyIG1ham9yIGRlcHJlc3NpdmUgZXBpc29kZS4gUGFydGljdWxhcmx5LCB0aGUgQ292aWQtMTkgaGFzIGltcGFjdGVkIHBlb3BsZeKAmXMgbWVudGFsIGhlYWx0aCBiZWNhdXNlIG9mIHRoZSBzb2NpYWwgZGlzdGFuY2luZyBydWxlcywgYW5kIHRoZSBwYW5kZW1pYyBtYWRlIGl0IGhhcmRlciB0byB3b3Jrb3V0LiBUaHVzLCB1bmRlcnN0YW5kaW5nIHNvbWUgb3RoZXIgdW5jb252ZW50aW9uYWwgZmFjdG9ycyB0aGF0IG1pZ2h0IGhhdmUgYW4gZWZmZWN0IG9uIGRlcHJlc3Npb24gYmVjb21lcyBjcnVjaWFsIHRvIGFjdCB1cG9uIGluIGF0IGFuIGluZGl2aWR1YWwgYW5kIGEgY29sbGVjdGl2ZSBsZXZlbC4gVGh1cywgd2Ugd2VyZSB3b25kZXJpbmcgaWYgdGhlcmUgaXMgcmVsYXRpb25zaGlwIGJldHdlZW4gZXhlcmNpc2luZyBhbmQgZGVwcmVzc2lvbj8gSW4gZmFjdCwgaXQgd291bGQgYmUgaW50ZXJlc3RpbmcgdG8gZXhwbG9yZSBpZiB0aGVyZSBpcyBhIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHBoeXNpY2FsIGFjdGl2aXR5IGFuZCBkZXByZXNzaW9uLiBDZXJ0YWlubHksIGEgcGVyc29uJ3MgYWJpbGl0eSB0byBleGVyY2lzZSBtaWdodCBkZXBlbmQgb24gdGhlaXIgZmluYW5jaWFsIHNpdHVhdGlvbi4gVGhvc2Ugd2hvIGFyZSBoaWdoZXIgY29tcGFyZWQgdG8gdGhlIHBvdmVydHkgZ3VpZGVsaW5lcyBjYW4gYWZmb3JkIHNvbWUgdGltZSB0byB3b3Jrb3V0IHdoaWxlIHNvbWUgd2hvIGFyZSBub3QgaW4gc3VjaCBhIHByaXZpbGVnZWQgc2l0dWF0aW9uIG1pZ2h0IG5lZWQgdG8gd29yayBtb3JlIGFuZCBoYXJkZXIsIGFuZCBpbiBkb2luZyBzbyBoYXZlIGxlc3MgdGltZSB0byB3b3Jrb3V0LiBGcm9tIHRoaXMgb2JzZXJ2YXRpb24sIG9uZSBjYW4gd29uZGVyIHdoZXRoZXIgYmVpbmcgcGh5c2ljYWxseSBhY3RpdmUgaGFzIGFuIGltcGFjdCBvbiB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gd2VhbHRoIGRlcHJlc3Npb24uIAoKT3VyIHByaW1hcnkgb2JqZWN0aXZlIGlzIHRvIGV4cGxvcmUgdGhlIHZhcmlhYmxlcyByZWxhdGVkIHRvIGRlcHJlc3Npb24gYnkgc3BlY2lmaWNhbGx5IGxvb2tpbmcgYXQgYW4gaW5kaXZpZHVhbCdzIHBoeXNpY2FsIGFjdGl2aXR5IGxldmVscyBhbmQgdGhlIHNvY2lvZWNvbm9taWMgY29uZGl0aW9ucyBvZiBwYXJ0aWNpcGFudHMuIFRoZSBmb3JtZXIgd2lsbCBoZWxwIG91ciB0ZWFtIGlkZW50aWZ5IGlmIHBoeXNpY2FsIGFjdGl2aXR5IHByb21vdGVzIGEgaGVhbHRoaWVyIG1pbmQsIHdoaWxlIHRoZSBsYXR0ZXIgdmFyaWFibGUgd2lsbCBoZWxwIGlkZW50aWZ5IGEgdHJlbmQgb24gaWYgYW5kIGhvdyBmaW5hbmNpYWwgc2l0dWF0aW9ucyBpbXBhY3Qgb25l4oCZcyBtZW50YWwgaGVhbHRoLiBJbiBzdW0sIG91ciBmaW5hbCBnb2FsIGlzIHRvIGJldHRlciB1bmRlcnN0YW5kIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGVzZSBmYWN0b3JzIHNvIGFzIHRvIGlkZW50aWZ5IHBvdGVudGlhbCByaXNrIGZhY3RvcnMgb3IgcHJvdGVjdGl2ZSBmYWN0b3JzIHRoYXQgY291bGQgaGVscCBpbmRpY2F0ZSBtZW50YWwgaGVhbHRoIG91dGNvbWVzLiAKIAoKIyBSZXNlYXJjaCBRdWVzdGlvbiAKClRvIGV4cGxvcmUgdGhlc2UgcmVsYXRpb25zaGlwcyBzdGF0ZWQgaW4gdGhlIGludHJvZHVjdGlvbiwgd2Ugd2lsbCB0cnkgdG8gYW5zd2VyIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb246IAoKSG93IGRvZXMgcG92ZXJ0eSBhbmQgcGh5c2ljYWwgYWN0aXZpdHkgYWZmZWN0IHRoZSBvZGRzIG9mIGhhdmluZyBkZXByZXNzaW9uPyAKClRvIGFuc3dlciB0aGVzZSBxdWVzdGlvbnMsIHdlIHdpbGwgdXNlIHRoZSB2YXJpYWJsZXMgUG92ZXJ0eSwgUGh5c2ljYWwgQWN0aXZlIChQaHlzQWN0aXZlKSBhbmQgRGVwcmVzc2lvbi4gRnVydGhlciBleHBsYW5hdGlvbiB3aWxsIGJlIHByb3ZpZGVkIGxhdGVyIG9uIGhvdyB3ZSBjaG9zZSB0aGVzZSB2YXJpYWJsZXMgaW4gdGhlIGRhdGEgc2VjdGlvbi4gVGhlIGV4cGxhbmF0b3J5IHZhcmlhYmxlcyBpbiBvdXIgc3R1ZHkgYXJlIFBvdmVydHkgYW5kIFBoeXNpY2FsIEFjdGl2ZS4gVGhlIG91dGNvbWUgdmFyaWFibGUgaXMgRGVwcmVzc2lvbiBhbmQgaXMgYSBiaW5hcnkgdmFyaWFibGUuIApUaGUgcG92ZXJ0eSB2YXJpYWJsZSBpcyBhIHJhdGlvIG9mIGZhbWlseSBpbmNvbWUgdG8gcG92ZXJ0eSBndWlkZWxpbmVzLiBTbWFsbGVyIG51bWJlcnMgaW5kaWNhdGUgbW9yZSBwb3ZlcnR5LiBUaGlzIHZhcmlhYmxlIGhlbHBzIHVzIHRvIHRha2UgaW50byBjb25zaWRlcmF0aW9uIHRoZSB3ZWFsdGggb2YgYSBwZXJzb24uIFRoZSBQaHlzaWNhbCBBY3RpdmUgKFBoeXNBY3RpdmUpIHZhcmlhYmxlIGlzIHVzZWQgYmVjYXVzZSBpdCBwcm92aWRlcyB1cyBpbmZvcm1hdGlvbiBvbiB3aGV0aGVyIGEgcGVyc29uIGlzIHBoeXNpY2FsbHkgYWN0aXZlIG9yIG5vdC4gIFRoZSBkZXByZXNzaW9uIHZhcmlhYmxlIGluZGljYXRlcyB0aGUgZGVwcmVzc2lvbiBzdGF0dXMgb2YgYSBwZXJzb24uIAoKIyBEYXRhCgojIyBDb250ZXh0CgpUaGUgZGF0YXNldCBOSEFORVMgY29udGFpbnMgMTAwMDAgdW5pdHMgb2Ygb2JzZXJ2YXRpb25zIG9yIGluZGl2aWR1YWxzIG9mIGFsbCBhZ2VzIGZyb20gdGhlIOKAnHRoZSBub24taW5zdGl0dXRpb25hbGl6ZWQgY2l2aWxpYW4gcG9wdWxhdGlvbiBvZiB0aGUgVW5pdGVkIFN0YXRlcy4gVGhpcyBkYXRhc2V0IGluY2x1ZGVzIDc1IHZhcmlhYmxlcyB0aGF0IGluY2x1ZGUgZGVtb2dyYXBoaWMsIHNvY2lvZWNvbm9taWMsIGRpZXRhcnksIGFuZCBoZWFsdGggcmVsYXRlZCBxdWVzdGlvbnMuIEluIHBhcnRpY3VsYXIsIHRoZSB2YXN0IG1ham9yaXR5IG9mIHRoZSB2YXJpYWJsZXMgY29tZSBmcm9tIGludGVydmlld3MsIGFuZCB0aGUgcmVtYWluaW5nIHZhcmlhYmxlcyBhcmUgdGhlIHJlc3VsdHMgb2YgbWVkaWNhbCwgZGVudGFsIGFuZCBwaHlzaW9sb2dpY2FsIGV4YW1pbmF0aW9ucy4KCkFzIG91ciByZXNlYXJjaCBxdWVzdGlvbnMgZm9jdXMgb24gcHJlZGljdGluZyB3aGF0IHZhcmlhYmxlcyBtaWdodCBhZmZlY3QgRGVwcmVzc2lvbiBvZiBhIHBlcnNvbiwgd2UgZGVjaWRlZCB0byBleHBsb3JlIHRoZSB2YXJpYWJsZSBQaHlzaWNhbCBBY3RpdmUgKFBoeXNBY3RpdmUpIGFzIG91ciBvdXRjb21lIHZhcmlhYmxlLiBGb3IgdGhlIGxhdHRlciB2YXJpYWJsZSwgc3R1ZHkgcGFydGljaXBhbnRzIDEyIHllYXJzIG9yIG9sZGVyLCByZXNwb25kZWQgYXMg4oCcWWVz4oCdIG9yIOKAnE5v4oCdIGlmIHRoZXkgZGlkIG1vZGVyYXRlIG9yIHZpZ29yb3VzLWludGVuc2l0eSBzcG9ydHMsIGZpdG5lc3Mgb3IgcmVjcmVhdGlvbmFsIGFjdGl2aXRpZXMuIEluIGFkZGl0aW9uLCB3ZSBkZWNpZGVkIHRvIHVzZSAgdGhlIHZhcmlhYmxlIGZvciBQb3ZlcnR5LCB3aGljaCBpcyB0aGUgcmF0aW8gb2YgdGhlIGZhbWlseeKAmXMgaW5jb21lIHRvIHBvdmVydHkgZ3VpZGVsaW5lcy4gCk1vcmVvdmVyLCB0aGlzIHN1cnZleSBpcyBleGVjdXRlZCBieSB0aGUgTmF0aW9uYWwgSGVhbHRoIGFuZCBOdXRyaXRpb24gc3VydmV5IChOSEFORVMpLCB3aGljaCBpcyBhIGNvbXByZWhlbnNpdmUgc3R1ZHkgZGVzaWduZWQgdG8gYXNzZXNzIHRoZSBoZWFsdGggYW5kIG51dHJpdGlvbmFsIHN0YXR1cyBvZiBhZHVsdHMgYW5kIGNoaWxkcmVuIGluIHRoZSBVbml0ZWQgU3RhdGVzIGZvciB0aGUgMjAwOS0yMDEyIHNhbXBsZSB5ZWFycy4gRnVydGhlcm1vcmUsIHRoZSBkYXRhIGNvbGxlY3RlZCBhaW1zIGF0IGlkZW50aWZ5aW5nIGVtZXJnaW5nIGhlYWx0aCBpc3N1ZXMgYW1vbmcgdGhlIHRhcmdldCBwb3B1bGF0aW9uLCB3aGljaCBlbmFibGVzIHBvbGljeW1ha2VycywgcmVzZWFyY2hlcnMgYW5kIHB1YmxpYyBoZWFsdGggb3JnYW5pemF0aW9ucyB0byBhbmFseXplIHRyZW5kcyBpbiBoZWFsdGggYW5kIG51dHJpdGlvbmFsIHN0YXR1cywgYW5kIGFzc2VzcyB0aGUgZWZmZWN0aXZlbmVzcyBvZiBwdWJsaWMgcG9saWNpZXMuIEl0IGlzIGltcG9ydGFudCB0byBlbXBoYXNpemUgdGhhdCB0aGUgc3VydmV5IGlzIGNvbmR1Y3RlZCBieSBhIHRlYW0gb2YgdHJhaW5lZCBoZWFsdGggcHJvZmVzc2lvbmFscyBhbmQgcmVzZWFyY2hlcnMsIHdobyB0cmF2ZWwgdG8gdmFyaW91cyBsb2NhdGlvbnMgYWNyb3NzIHRoZSBVUyB0byBvYnRhaW4gZnJvbSBhIHJlcHJlc2VudGF0aXZlIHNhbXBsZSBvZiB0aGUgdGFyZ2V0IHBvcHVsYXRpb24uIFRoaXMgdGVhbSBpbmNsdWRlcyBwaHlzaWNpYW5zLCBudXJzZXMsIGxhYm9yYXRvcnkgdGVjaG5pY2lhbnMsIHdobyBjb25kdWN0IHBoeXNpY2FsIGV4YW1pbmF0aW9ucywgY29sbGVjdCBiaW9sb2dpY2FsIHNwZWNpbWVucywgYW5kIHBlcmZvcm0gdGhlIGludGVydmlld3MgYW5kIHF1ZXN0aW9ubmFpcmVzLgoKQWNjb3JkaW5nIHRvIHRoZSBOSEFORVMgd2Vic2l0ZSwgdGhleSB1c2VkIGEgZm91ci1zdGFnZSBzdHVkeSB0byBjb2xsZWN0IHRoZSBkYXRhLiBUaGUgZmlyc3Qgc3RhZ2UgY29uc2lzdGVkIG9mIHNlbGVjdGluZyB0aGUgUHJpbWFyeSBTYW1wbGluZyBVbml0cyAoUFNVcykgZnJvbSBhIGZyYW1lIG9mIGFsbCBVLlMuIGNvdW50aWVzLCBhbmQgYSB0b3RhbCBvZiAxNSBjb3VudGllcyB3ZXJlIGNob3NlbiBmb3IgdGhlIDIwMDktMjAxMiBwZXJpb2QuIFRoZSBzZWNvbmQgc3RhZ2UgY29uc2lzdGVkIG9mIHNlbGVjdGluZyBTZWNvbmRhcnkgc2FtcGxpbmcgdW5pdHMgKFNTVXMpLCB3aXRoaW4gZWFjaCBQU1UsIHNlZ21lbnRzIHdlcmUgY2hvc2VuIGJhc2VkIG9uIGdlb2dyYXBoaWNhbCBib3VuZGFyaWVzLCBhbmQgYSB0b3RhbCBvZiAxMzAgc2VnbWVudHMgd2VyZSBzZWxlY3RlZCBkdXJpbmcgdGhlIHNhbXBsaW5nIHBlcmlvZC4gVGhlIHRoaXJkIHN0YWdlIGludm9sdmVkIHRoZSByYW5kb20gc2VsZWN0aW9ucyBvZiBob3VzZWhvbGRzIGZyb20gdGhlIGxhdHRlciBTU1VzLCBmcm9tIHdoaWNoIGFsbCB0aGVzZSBob3VzZWhvbGRzIHdlcmUgaW52aXRlZCB0byBwYXJ0aWNpcGF0ZSBpbiB0aGUgc3VydmV5LiBMYXN0bHksIGluIHRoZSBmb3VydGggc3RhZ2UgdGhlIGZvY3VzIHdhcyBvbiB0aGUgc2VsZWN0aW9uIG9mIGFsbCBpbmRpdmlkdWFscyByZWdhcmRsZXNzIG9mIHRoZWlyIGVsaWdpYmlsaXR5IGZvciBhbGwgY29tcG9uZW50cyBvZiB0aGUgc3R1ZHksIGZvciBpbnN0YW5jZSwgbm90IGFsbCBwYXJ0aWNpcGFudHMgd2VyZSBlbGlnaWJsZSBmb3IgbGFib3JhdG9yeSB0ZXN0cy4gSXQgaXMgcmVsZXZhbnQgdG8gbWVudGlvbiB0aGF0IHRoZSBzdHVkeSBoYXMgYmVlbiBjYXJyaWVkIG91dCBzaW5jZSAxOTYwLCBhbmQgZXZlcnkgc2FtcGxpbmcgcGVyaW9kIGhhcyBiZWVuIGFkanVzdGVkIHRvIG1ha2UgdGhlIHN0dWR5IG1vcmUgcmVwcmVzZW50YXRpdmUgb2YgdGhlIFVTIHBvcHVsYXRpb24uIFNwZWNpZmljYWxseSwgdGhlIGRhdGEgdW5kZXJnb2VzIGEgc3RhdGlzdGljYWwgd2VpZ2h0aW5nIGFkanVzdG1lbnQgdG8gdW5kbyBvdmVyc2FtcGxpbmcgYW5kIHVuZGVyc2FtcGxpbmcgb2Ygc29tZSBwb3B1bGF0aW9uIHN1Ymdyb3VwcywgaW5jbHVkaW5nIG5vbi1IaXNwYW5pYyBCbGFjayBwZW9wbGUsIE1leGljYW4gQW1lcmljYW5zLCBhbmQgbG93IGluY29tZSBpbmRpdmlkdWFscy4gVGhpcyBwcm9jZXNzIGVuc3VyZXMgdGhlcmUgYXJlIG5vIGJpYXNlcyBpbiB0aGUgcmVwcmVzZW50YXRpb24gYW5kIHByb3ZpZGVzIGEgbW9yZSByZWxpYWJsZSBhbmFseXNpcy4gCgpUaGUgb3JpZ2luYWwgZGF0YXNldCBjYW4gYmUgZm91bmQgb24gdGhlIENlbnRlciBmb3IgRGlzZWFzZSBDb250cm9sIGFuZCBQcmV2ZW50aW9uIChDREMpIHdlYnNpdGUgYnkgY2xpY2tpbmcgb24gdGhlIERhdGEgJiBTdGF0cyBidXR0b24gaW4gdGhlIGluaXRpYWwgd2luZG93IGRpc3BsYXllZC4gVG8gYWNjZXNzIHRoZSBkYXRhLCBvbmUgY291bGQgdHlwZSDigJxOSEFORVPigJ0gb24gdGhlIHNlYXJjaCBiYXIsIGFuZCBhIGxpbmsgdG8gdGhlIE5IQU5FUyBwYWdlIHdpbGwgYXBwZWFyLiBUaGVuLCB0aGUgdXNlciBjb3VsZCBjbGljayBhZ2FpbiBvbiBTdXJ2ZXkgRGF0YSBhbmQgRG9jdW1lbnRhdGlvbiwgYW5kIGNsaWNrIG9uIHRoZSBkYXRhc2V0IG9mIGludGVyZXN0ICgyMDA5LTIwMTAgYW5kIDIwMTEtMjAxMiksIG9yIGJ5IGNsaWNraW5nIG9uIHRoZSBmb2xsb3dpbmcgbGluazogaHR0cHM6Ly93d3duLmNkYy5nb3YvbmNocy9uaGFuZXMvRGVmYXVsdC5hc3B4LiBOZXZlcnRoZWxlc3MsIHRoZSBtb3N0IHN0cmFpZ2h0Zm9yd2FyZCBtZXRob2QgdG8gb2J0YWluIHRoZSBjbGVhbiBkYXRhIHNldCBpcyBieSBkb3dubG9hZGluZyB0aGUgUiBQYWNrYWdlIOKAnE5IQU5FU+KAnSwgYW5kIGFkZGluZyBpdCB0byBvdXIgUiBlbnZpcm9ubWVudC4gVGhpcyBkYXRhIHNldCBhY2NvdW50cyBmb3IgdGhlIHBlcmlvZCAyMDA5LTIwMTIgd2l0aCBhZGp1c3RlZCB3ZWlnaHRpbmcsIGFuZCBpdCBpcyB0aGUgZGF0YXNldCB0aGF0IHdlIHVzZWQgaW4gdGhlIHJlc3Qgb2Ygb3VyIHN0dWR5LiAKCgojIyBEYXRhIENsZWFuaW5nCgpCYXNlZCBvbiB0aGUgTkhBTkVTIGRhdGFzZXQsIHdlIGNyZWF0ZWQgYSBuZXcgZGF0YXNldCBjYWxsZWQgYGRlcHJlc3NlZF9kYXRhYCBpbiB3aGljaCB3ZSBzZWxlY3RlZCBvbmx5IDMgdmFyaWFibGVzIHdlIGNob29zZSB0byBleGFtaW5lIGZvciBvdXIgcmVzZWFyY2ggcXVlc3Rpb246IGBEZXByZXNzZWRgLCBgUG92ZXJ0eWAsIGFuZCBgUGh5c0FjdGl2ZWAuIAoKVGhlIGBEZXByZXNzZWRgIHZhcmlhYmxlLS13aGljaCBpcyBhIHNlbGYtcmVwb3J0ZWQgcmFuZ2Ugb2YgZGF5cyB3aGVyZSBwYXJ0aWNpcGFudHMgZmVsdCBkb3duLCBkZXByZXNzZWQgb3IgaG9wZWxlc3MtLWNhcnJpZXMgMyB2YWx1ZXM6IGBOb25lYCwgYFNldmVyYWxgLCBgTW9zdGAuIFdlIGNvbnZlcnRlZCBgTm9uZWAgdmFsdWVzIHRvIDAsYFNldmVyYWxgIGFuZCBgTW9zdGAgdG8gMS4gVGhpcyBhbGxvd3MgdXMgdG8gc3VwcG9ydCBvdXIgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbCB3aXRoIGBEZXByZXNzZWRgIGFzIG91ciByZXNwb25zZSB2YXJpYWJsZSBhbmQgcHJlZGljdCBpdCBhcyBhIGJpbmFyeSBjYXRlZ29yaWNhbCB2YXJpYWJsZSB3aXRoIHR3byBwb3NzaWJsZSBvdXRjb21lIHZhbHVlcyBiZSAkWT0wJCBhbmQgJFk9MSQuCgpXZSB0aGVuIGZpbHRlcmVkIG91dCBhbnkgTkEgdmFsdWVzIHVuZGVyIGBEZXByZXNzZWRgIGluIG9yZGVyIG5vdCB0byBjYXVzZSB0b28gbXVjaCBkYXRhIG5vaXNlLgoKYGBge3IsZWNobz1GQUxTRSxtZXNzYWdlID0gRkFMU0V9CmRlcHJlc3NlZF9kYXRhIDwtIAogIE5IQU5FUyAlPiUgCiAgc2VsZWN0KFBoeXNBY3RpdmUsIERlcHJlc3NlZCwgUG92ZXJ0eSkgJT4lIAogIG11dGF0ZShEZXByZXNzZWQ9Y2FzZV93aGVuKAogICAgRGVwcmVzc2VkID09ICJTZXZlcmFsIiB8IERlcHJlc3NlZD09ICJNb3N0IiB+IDEsCiAgICBEZXByZXNzZWQgPT0gIk5vbmUiIH4gMCkgCiAgKSAlPiUgCiAgZmlsdGVyKERlcHJlc3NlZCAhPSJOQSIpIAoKYGBgCgoKCiMgRXhwbG9yYXRvcnkgRGF0YSBBbmFseXNpcyAKCmBgYHtyLGVjaG89RkFMU0UsbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nPUZBTFNFfQpkZXByZXNzZWRfZGF0YSAlPiUgZ2dwbG90KGFlcyh5PVBvdmVydHkseD1mYWN0b3IoRGVwcmVzc2VkKSwgZmlsbCA9ZmFjdG9yKERlcHJlc3NlZCkgKSkgKwogIGdnZGlzdDo6c3RhdF9oYWxmZXllKGNvbG9yID0gTkEsIHdpZHRoID0gMSwgYWxwaGEgPSAuOSkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9LjMsIGFscGhhID0gLjgpICsgCiAgZmFjZXRfZ3JpZCh+UGh5c0FjdGl2ZSkgKwogIGxhYnModGl0bGUgPSAiRmlndXJlIDE6IFJlbGF0aW9uc2hpcCBCZXR3ZWVuIFBvdmVydHksIFBoeXNpY2FsIEFjdGl2aXR5IGFuZCBEZXByZXNzaW9uIiwKICAgICAgIHkgPSAiTGV2ZWwgb2YgUG92ZXJ0eSIsCiAgICAgICBzdWJ0aXRsZT0gIlBoeXNBY3RpdmUiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJEZXByZXNzZWQiKSsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gLjUpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksICkKCmBgYAoKRnJvbSB0aGlzIHZpc3VhbGl6YXRpb24sIHdlIGNhbiBzZWUgdGhhdCB0aGUgbWVkaWFuIHBvdmVydHkgdmFsdWVzIGZvciBwZW9wbGUgd2hvIGFyZSBub3QgcGh5c2ljYWxseSBhY3RpdmUgYXJlIGxvd2VyIChhcm91bmQgMi44IGZvciBub3QgZGVwcmVzc2VkIGFuZCAxLjUgZm9yIGRlcHJlc3NlZCkgdGhhbiB0aGUgbWVkaWFuIHBvdmVydHkgdmFsdWVzIGZvciB0aG9zZSB3aG8gYXJlIHBoeXNpY2FsbHkgYWN0aXZlIChhcm91bmQgMy41IGZvciBub3QgZGVwcmVzc2VkIGFuZCAyLjkgZm9yIGRlcHJlc3NlZCkuIFRoZSBpbnRlcnF1YXJ0aWxlIGxlbmd0aHMgYW5kIHJhbmdlcyBiZXR3ZWVuIG9ic2VydmF0aW9ucyB0aGF0IGFyZSBwaHlzaWNhbGx5IGFjdGl2ZSBhbmQgYXJlIG5vdCBhcmUgbm90aWNlYWJseSBkaWZmZXJlbnQuIFdoaWxlIHRoZSBiaW5zIGRlc2NyaWJpbmcgdGhvc2Ugd2hvIGFyZSBwaHlzaWNhbGx5IGluYWN0aXZlIGhhdmUgdGhlaXIgaW50ZXJxdWFydGlsZSByYW5nZXMgZnJvbSBhYm91dCAxLjMgdG8gNC4zIGZvciBub3QgZGVwcmVzc2VkIGFuZCBmcm9tIDEgdG8gMi4wIGZvciBkZXByZXNzZWQsIHRob3NlIG9mIG9ic2VydmF0aW9ucyB0aGF0IHJlcG9ydGVkIHBoeXNpY2FsbHkgYWN0aXZlIHJhbmdlcyBmcm9tIDEuOSB0byA1IGZvciBub3QgZGVwcmVzc2VkIGFuZCBmcm9tIDEuNCB0byA1IGZvciBkZXByZXNzZWQuIEl0IGlzIGFsc28gc2lnbmlmaWNhbnQgdG8gbm90ZSB0aGF0IGZvciBiYXRjaGVzIG9mIGRhdGEgdW5kZXIgcGh5c2ljYWxseSBhY3RpdmUgYXJlIGxlZnQtc2tld2VkLCB0aGUgYmF0Y2hlcyBmb3IgZGF0YSB1bmRlciBwaHlzaWNhbGx5IGluYWN0aXZlIGFyZSByaWdodC1za2V3ZWQgZm9yIHRob3NlIHRoYXQgcmVwb3J0ZWQgZm9yIGRlcHJlc3Npb24geWV0IGxlZnQtc2tld2VkIGZvciB0aG9zZSB0aGF0IHJlcG9ydGVkIGZvciBubyBkZXByZXNzaW9uLiAKCgojIExvZ2lzdGljIFJlZ3Jlc3Npb24KCiMjIE1vZGVsIENyZWF0aW9uCgpBcyB3ZSB3YW50ZWQgdG8gcHJlZGljdCB0aGUgcHJvYmFiaWxpdHkgb2YgYW4gaW5kaXZpZHVhbCBiYXNlZCBvbiB3aGV0aGVyIG9yIG5vdCB0aGV5IGFyZSBwaHlzaWNhbGx5IGFjdGl2ZSBhbmQgZGVwZW5kaW5nIG9uIHRoZWlyIHBvdmVydHkgc3RhdHVzIHdlIGRlY2lkZWQgdG8gdXNlIGEgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbCBpbnN0ZWFkIG9mIGEgbGluZXIgcmVncmVzc2lvbiBtb2RlbC4gRm9yIGNvbnZlbmllbmNlLCB3ZSBwcm9jZWVkZWQgdG8gdXNlIGEgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbCBhcyBvdXIgZmluYWwgbW9kZWwgc2luY2Ugb3VyIG91dGNvbWUgdmFyaWFibGUgYERlcHJlc3NlZGAgaXMgYSBiaW5hcnkgdmFyaWFibGUuIAoKTW9yZW92ZXIsIGF0IGZpcnN0IHdlIHdhbnRlZCB0byB1c2UgdGhlIHZhcmlhYmxlcyBQb3ZlcnR5IGFuZCBQaHlzaWNhbCBBY3Rpdml0eSBhcyBleHBsYW5hdG9yeSB2YXJpYWJsZXMgd2l0aG91dCBhbiBpbnRlcmFjdGlvbiB0ZXJtLiBIb3dldmVyLCBkdXJpbmcgb3VyIEVEQSB3ZSBub3RpY2VkIHRoYXQgcG92ZXJ0eSBtaWdodCBoYXZlIGFuIGludGVyYWN0aW9uIGVmZmVjdCB3aXRoIHRoZSBQaHlzaWNhbCBBY3RpdmUgdmFyaWFibGUuIFRvIGVsYWJvcmF0ZSBvbiB0aGlzLCBGaWd1cmUgMSBzaG93cyB0aGF0IHRoZSBtZWRpYW4gb2YgdGhvc2UgaW5kaXZpZHVhbHMgd2hvIGFyZSBwaHlzaWNhbGx5IGFjdGl2ZSwgcmVnYXJkbGVzcyBvZiB3aGV0aGVyIG9yIG5vdCB0aGV5IGFyZSBkZXByZXNzZWQgc2VlbSB0byBiZSBjb25jZW50cmF0ZWQgaW4gYSBoaWdoZXIgbnVtYmVyIG9mIHRoZSBwb3ZlcnR5IGxldmVsIHZhcmlhYmxlLCB3aGljaCBtaWdodCBzdWdnZXN0IHRoYXQgcGh5c2ljYWxseSBhY3RpdmUgaW5kaXZpZHVhbHMgbWF5IGhhdmUgYSBsb3dlciBwb3ZlcnR5LiBIZW5jZSwgaW4gb3JkZXIgdG8gYWNjb3VudCBmb3IgdGhlc2Ugc3VidGxlIGRpZmZlcmVuY2VzLCB3ZSBhbGxvd2VkIHBvdmVydHkgdG8gaW50ZXJhY3Qgd2l0aCB0aGUgdmFyaWFibGUgUGh5c2ljYWwgQWN0aXZlLiAKClRodXMsIG91ciBmaW5hbCBtb2RlbCBjYW4gYmUgZXhwcmVzc2VkIGFzIGZvbGxvd3M6CgoKJCRPZGRzW0RlcHJlc3NlZCB8IFBoeXNBY3RpdmUsUG92ZXJ0eV0gPSAwLjc1ICsgMC41MCAqIFBoeXNBY3RpdmVZZXMgKyAwLjcyKlBvdmVydHkgKyAxLjE0KFBoeXNBY3RpdmVZZXMgKiBQb3ZlcnR5KSQkCgojIyBGaXR0ZWQgTW9kZWwKYGBge3IsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFLCBldmFsID0gRkFMU0V9Cm1vZCA8LSBkZXByZXNzZWRfZGF0YSAlPiUKICB3aXRoKGdsbShEZXByZXNzZWQgfiBQb3ZlcnR5ICogUGh5c0FjdGl2ZSwgZmFtaWx5ID0gYmlub21pYWwpKQpjb2VmKG1vZCkgJT4lCiAgZXhwKCkKIyBDYWxjdWxhdGluZyB0aGUgc3RhbmRhcmQgZXJyb3JzOgoKc3RkZXJyb3JzIDwtICB0aWR5KG1vZCwgZXhwb25lbnRpYXRlID0gIFRSVUUpCgpgYGAKClRoZSB0YWJsZSBiZWxvdyBzaG93cyB0aGUgZXhwb25lbnRpYXRlZCBlc3RpbWF0ZWQgY29lZmZpY2llbnRzIGZvciBvdXIgbW9kZWwgYW5kIHRoZSBTdGFuZGFyZCBFcnJvcnMgKExvd2VyIEJvdW5kIGFuZCBVcHBlciBCb3VuZCkgdXNpbmcgdGhlIENsYXNzaWNhbCBBcHByb2FjaDoKCmBgYHtyLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRX0KZGYxIDwtIGRhdGEuZnJhbWUoQ29lZmZpY2llbnRzPSBjKCJJbnRlcmNlcHQiLCAiUG92ZXJ0eSIsICJQaHlzQWN0aXZlWWVzIiwgIlBvdmVydHk6UGh5c0FjdGl2ZVllcyIpLAogICAgICAgICAgICAgICAgICBFc3RpbWF0ZXMgPSBjKCIwLjc1IiwgIjAuNzIiLCAiMC41MCIsICIxLjE0IiksIFN0YW5kYXJkX0Vycm9ycyA9IGMoIjAuMDgiLCAiMC4wMyIsICIwLjEyIiwgIjAuMDQiKSkKCiMgT3V0cHV0IHRoZSB0YWJsZSB1c2luZyBrYWJsZSgpCmtuaXRyOjprYWJsZShkZjEsIGFsaWduID0gYygibCIsICJjIiksIGNhcHRpb24gPSAiRmluYWwgTW9kZWwgRXN0aW1hdGVkIChFeHBvbmVudGlhdGVkKSBDb2VmZmljaWVudHMgYW5kIFN0YW5kYXJkIEVycm9ycyAoU0UpIikKYGBgCgoKIyMgTW9kZWwgSW50ZXJwcmV0YXRpb24KCiMjIyBPZGRzIHJhdGlvCmBgYHtyLGVjaG89RkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0KbW9kIDwtIGRlcHJlc3NlZF9kYXRhICU+JQogIHdpdGgoZ2xtKERlcHJlc3NlZCB+IFBvdmVydHkgKiBQaHlzQWN0aXZlLCBmYW1pbHkgPSBiaW5vbWlhbCkpCmNvZWYobW9kKSAlPiUKICBleHAoKQpgYGAKCj4gSW50ZXJjZXB0IENvZWZmaWNpZW50IGlzIGFwcHJveGltYXRlbHkgZXF1YWwgdG8gMC43NS4KClRoZSBjb2VmZmljaWVudCBvZiAwLjc1IHJlcHJlc2VudHMgdGhlIG9kZHMgb2YgYmVpbmcgZGVwcmVzc2VkIHdoZW4gYW4gaW5kaXZpZHVhbCBpcyBub3QgcGh5c2ljYWxseSBhY3RpdmUgYW5kIGxpdmluZyBpbiBwb3ZlcnR5IChsZXZlbCAxKSB3aGVuIGFsbCB0aGUgb3RoZXIgcHJlZGljdG9yIHZhcmlhYmxlcyBhcmUgZXF1YWwgdG8gemVyby4gIAoKVGhlIFNFIGZvciB0aGUgSW50ZXJjZXB0IGlzIDAuMDg6IFRoZSBzdGFuZGFyZCBlcnJvciBvZiB0aGUgZXhwb25lbnRpYXRlZCBpbnRlcmNlcHQgY29lZmZpY2llbnQgaXMgc2lnbmlmaWNhbnRseSBzbWFsbC4gVGhpcyB2YWx1ZSBtaWdodCBpbmRpY2F0ZSB0aGF0IHdlIGhhdmUgYSBoaWdoIHByZWNpc2lvbiBpbiBlc3RpbWF0aW5nIHRoZSBvZGRzIG9mIGJlaW5nIGRlcHJlc3NlZCBmb3IgdGhlIGluZGl2aWR1YWxzIHdobyBhcmUgbm90IHBoeXNpY2FsbHkgYWN0aXZlIGFuZCBhcmUgaW4gcG92ZXJ0eSAobGV2ZWwgMSkuCgo+UG92ZXJ0eSBDb2VmZmljaWVudDogaXMgYXBwcm94aW1hdGVseSBlcXVhbCB0byAwLjcyMC4gCgpIb2xkaW5nIGFsbCBvdGhlciB2YXJpYWJsZXMgY29uc3RhbnQsIHRoZSBtdWx0aXBsaWNhdGl2ZSBjaGFuZ2UgaW4gZXN0aW1hdGVkIG9kZHMgb2YgYmVpbmcgZGVwcmVzc2VkIGlzIDAuNzIgZm9yIGVhY2ggdW5pdCBpbmNyZWFzZSBpbiBwb3ZlcnR5LiBCZWNhdXNlIHRoZSBvZGRzIHJhdGlvIGlzIGxlc3MgdGhhbiAxLCB0aGUgb2RkcyBvZiBiZWluZyBkZXByZXNzZWQgYXJlIGxlc3Mgd2l0aCBlYWNoIHVuaXQgaW5jcmVhc2UgaW4gcG92ZXJ0eS4KClRoZSBTRSBmb3IgdGhlIFBvdmVydHkgQ29lZmZpY2llbnQgaXMgMC4wMy46IFRoZSBzdGFuZGFyZCBlcnJvciBvZiB0aGUgcG92ZXJ0eSBjb2VmZmljaWVudCBmYWxscyBpcyBhIHJlbGF0aXZlbHkgc21hbGwgdmFsdWUuIFRoaXMgdmFsdWUgbWlnaHQgaW5kaWNhdGUgdGhhdCB0aGVyZSBtaWdodCBhIGhpZ2ggcHJlY2lzaW9uIGluIGVzdGltYXRpbmcgdGhlIGVmZmVjdCBvZiBwb3ZlcnR5IG9uIHRoZSBvZGRzIG9mIGJlaW5nIGRlcHJlc3NlZC4gCgo+UGh5c0FjdGl2ZVllcyBDb2VmZmljaWVudCBpcyBhcHByb3hpbWF0ZWx5IGVxdWFsIHRvIDAuNTA1LiAKCkhvbGRpbmcgYWxsIG90aGVyIHZhcmlhYmxlcyBjb25zdGFudCwgdGhlIG11bHRpcGxpY2F0aXZlIGNoYW5nZSBpbiBlc3RpbWF0ZWQgb2RkcyBvZiBiZWluZyBkZXByZXNzZWQgZm9yIGluZGl2aWR1YWxzIHdobyBhcmUgcGh5c2ljYWxseSBhY3RpdmUgYXJlIGFib3V0IDAuNTA1IHRpbWVzIGxlc3MgdGhhbiB0aGUgZXN0aW1hdGVkIG9kZHMgcmF0aW8gb2YgYmVpbmcgZGVwcmVzc2VkIGZvciBpbmRpdmlkdWFscyB3aG8gYXJlIG5vdCBwaHlzaWNhbGx5IGFjdGl2ZS4gSW4gb3RoZXIgd29yZHMsIGJlY2F1c2UgdGhlIG9kZHMgcmF0aW8gaXMgbGVzcyB0aGFuIDEsIHRoZSBlc3RpbWF0ZWQgb2RkcyBvZiBiZWluZyBkZXByZXNzZWQgaXMgbGVzcyB3aXRoIHRob3NlIHdobyBhcmUgcGh5c2ljYWxseSBhY3RpdmUgYXMgY29tcGFyZWQgdG8gdGhvc2Ugd2hvIGFyZSBub3QgcGh5c2ljYWxseSBhY3RpdmUuCgpUaGUgU0UgZm9yIHRoZSBQaHlzQWN0aXZlIENvZWZmaWNpZW50IGlzIDAuMTI6IFRoZSBzdGFuZGFyZCBlcnJvciBvZiB0aGUgcGh5c2ljYWwgYWN0aXZlIGNvZWZmaWNpZW50IGZhbGxzIGluIGEgcmVsYXRpdmVseSBzbWFsbCB2YWx1ZS4gWWV0LCBpdCBpcyByb3VnaGx5IGhpZ2hlciBpbiBjb21wYXJpc29uIHRvIHRoZSBhZm9yZW1lbnRpb25lZCB2YWx1ZXMgZm9yIHRoZSBTRSBvZiB0aGUgb3RoZXIgY29lZmZpY2llbnRzLiBXZSBjYW4gc2F5IHRoYXQgdGhlcmUgbWlnaHQgYmUgc29tZSB1bmNlcnRhaW50eSBpbiBlc3RpbWF0aW5nIHRoZSBlZmZlY3RzIG9uIHBoeXNpY2FsIGFjdGl2aXR5IG9uIHRoZSBvZGRzIG9mIGJlaW5nIGRlcHJlc3NlZC4gCgo+UG92ZXJ0eTpQaHlzQWN0aXZlWWVzIENvZWZmaWNpZW50IGlzIGFwcHJveGltYXRlbHkgZXF1YWwgdG8gMS4xNC4gCgpUaGUgZWZmZWN0IG9mIHBoeXNpY2FsIGFjdGl2aXR5IG9uIHRoZSBvZGRzIG9mIGJlaW5nIGRlcHJlc3NlZCBkaWZmZXJzIGRlcGVuZGluZyBvbiB0aGUgbGV2ZWwgb2YgcG92ZXJ0eS4gCgoxLjE0IGlzIHRoZSBtdWx0aXBsaWNhdGl2ZSBkaWZmZXJlbmNlIGluIGVzdGltYXRlZCBvZGRzIG9mIGJlaW5nIGRlcHJlc3NlZCBiZXR3ZWVuIHRob3NlIHdobyBhcmUgcGh5c2ljYWxseSBhY3RpdmUgYW5kIHBoeXNpY2FsbHkgaW5hY3RpdmUuIEluIG90aGVyIHdvcmRzLCAxLjE0IGlzIHRoZSBtdWx0aXBsaWNhdGl2ZSBjaGFuZ2UgaW4gdGhlIGVzdGltYXRlZCBlZmZlY3Qgb2YgcG92ZXJ0eSBvbiBlc3RpbWF0ZWQgb2RkcyBvZiBiZWluZyBkZXByZXNzZWQgYmV0d2VlbiB0aG9zZSB3aG8gYXJlIHBoeXNpY2FsbHkgYWN0aXZlIGFuZCB0aG9zZSB3aG8gYXJlIG5vdCwgd2hlcmUgdGhlIGVmZmVjdCBvZiBwb3ZlcnR5IG9uIHRoZSBlc3RpbWF0ZWQgb2RkcyBvZiBiZWluZyBkZXByZXNzZWQgaXMgYSBvbmUgdW5pdCBjaGFuZ2UgaW4gcG92ZXJ0eSwgb3IgdGhlIHJhdGlvIGJldHdlZW4gaG91c2Vob2xkIGluY29tZSB0byBwb3ZlcnR5IGd1aWRlbGluZXMuIFRoaXMgbWVhbnMgdGhhdCB0aGUgZXN0aW1hdGVkIG9kZHMgb2YgZGVwcmVzc2lvbiBhcmUgZXhwZWN0ZWQgdG8gaW5jcmVhc2UgYnkgMTE0JSBhbW9uZyBpbmRpdmlkdWFscyB3aG8gYXJlIHBoeXNpY2FsbHkgYWN0aXZlIGFuZCBsaXZpbmcgaW4gcG92ZXJ0eSB0aGFuIHRob3NlIHdobyBhcmUgbm90IHBoeXNpY2FsbHkgYWN0aXZlIGFuZCBub3QgbGl2aW5nIGluIHBvdmVydHkuIAoKVGhlIFNFIGZvciB0aGUgUG92ZXJ0eTpQaHlzQWN0aXZlIENvZWZmaWNpZW50IGlzIDAuMDQ6IFRoZSBzdGFuZGFyZCBlcnJvciBvZiB0aGUgaW50ZXJhY3Rpb24gY29lZmZpY2llbnQgYmV0d2VlbiBwb3ZlcnR5IGFuZCBwaHlzaWNhbCBhY3Rpdml0eSBpcyBzaWduaWZpY2FudGx5IHNtYWxsLCBzdWdnZXN0aW5nIHRoYXQgdGhlcmUgbWlnaHQgYmUgYSBoaWdoIHByZWNpc2lvbiBpbiBlc3RpbWF0aW5nIHRoZSBlZmZlY3Qgb2YgdGhlIGludGVyYWN0aW9uIGJldHdlZW4gcGh5c2ljYWwgYWN0aXZpdHkgYW5kIHBvdmVydHkgb24gdGhlIG9kZHMgb2YgYmVpbmcgZGVwcmVzc2VkLiAKCiMjIyA5NSUgQ29uZmlkZW5jZSBJbnRlcnZhbHMKCmBgYHtyLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRSwgZXZhbCA9IEZBTFNFfQojIENyZWF0ZSA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbHMgZm9yIGNvZWZmaWNpZW50cwpjb25maW50KG1vZCwgbGV2ZWwgPSAwLjk1LCB0eXBlID0gIldhbGQiKSAlPiUgCiAgZXhwKCkKYGBgCgpgYGB7ciwgZWNobz1GQUxTRX0KZGYyIDwtIGRhdGEuZnJhbWUoQ29lZmZpY2llbnRzPSBjKCJJbnRlcmNlcHQiLCAiUG92ZXJ0eSIsICJQaHlzQWN0aXZlWWVzIiwgIlBvdmVydHk6UGh5c0FjdGl2ZVllcyIpLAogICAgICAgICAgICAgICAgICBMb3dlcl9Cb3VuZCA9IGMoIjAuNjQiLCAiMC42OCIsICIwLjQwIiwgIjEuMDYiKSwgVXBwZXJfQm91bmQgPSBjKCIwLjg4IiwgIjAuNzYiLCAiMC42NCIsICIxLjI0IikpCgojIE91dHB1dCB0aGUgdGFibGUgdXNpbmcga2FibGUoKQprbml0cjo6a2FibGUoZGYyLCBhbGlnbiA9IGMoImwiLCAiYyIpLCBjYXB0aW9uID0gIjk1ICUgQ29uZmlkZW5jZSBJbnRlcnZhbHMiKQpgYGAKCj4gVGhlIDk1ICUgQ29uZmlkZW5jZSBJbnRlcnZhbCAoQ0kpIGZvciB0aGUgRXhwb25lbnRpYXRlZCBQb3ZlcnR5IENvZWZmaWNpZW50OgoKVGhlIENJIGZvciB0aGUgcG92ZXJ0eSBjb2VmZmljaWVudCBpcyAoMC42OCwgMC43NiksIHdoaWNoIG1lYW5zIHRoYXQgd2UgYXJlIDk1ICUgY29uZmlkZW50IHRoYXQgdGhlIHRydWUgcG9wdWxhdGlvbiBvZiBvZGRzIHJhdGlvIGZvciB0aGUgUG92ZXJ0eSBDb2VmZmljaWVudCBpcyBiZXR3ZWVuIDAuNjggYW5kIDAuNzYuIFNpbmNlIHRoZSBpbnRlcnZhbCBkb2VzIG5vdCBpbmNsdWRlIHRoZSBudWxsIHZhbHVlIG9mIDEgYW5kIGNvbnRyb2xsaW5nIGZvciB0aGUgb3RoZXIgdmFyaWFibGVzLCB3ZSBjYW4gc2F5IHRoYXQgUG92ZXJ0eSBpcyBhIHNpZ25pZmljYW50IHByZWRpY3RvciBvZiB0aGUgb2RkcyBvZiBiZWluZyBkZXByZXNzZWQsIEluIG90aGVyIHdvcmRzLCBzaW5jZSB0aGUgaW50ZXJ2YWwgcHJvdmlkZWQgcGxhdXNpYmxlIHZhbHVlcyBmb3IgdGhlIHRydWUgb2RkcyByYXRpbyBwb3B1bGF0aW9uLCB3ZSBoYXZlIGV2aWRlbmNlIHRoYXQgc3VnZ2VzdHMgdGhhdCB0aGVyZSBpcyBhIHRydWUgcmVsYXRpb25zaGlwIGJldHdlZW4gcG92ZXJ0eSBhbmQgdGhlIG9kZHMgb2YgYmVpbmcgZGVwcmVzc2VkLiAKCj5UaGUgOTUgJSBDb25maWRlbmNlIEludGVydmFsIChDSSkgZm9yIHRoZSBFeHBvbmVudGlhdGVkIFBoeXNBY3RpdmVZZXMgQ29lZmZpY2llbnQ6CgpUaGUgQ0kgZm9yIHRoZSBQaHlzQWN0aXZlWWVzIGNvZWZmaWNpZW50IGlzICgwLjQwLCAwLjY0KSwgaW5kaWNhdGluZyB0aGF0IHdlIGFyZSA5NSAlIGNvbmZpZGVudCB0aGF0IHRoZSB0cnVlIHBvcHVsYXRpb24gb2Ygb2RkcyByYXRpb24gbGllcyB3aXRoaW4gKDAuNDAsIDAuNjQpLiBBcyB0aGlzIGludGVydmFsIGRvZXMgbm90IGluY2x1ZGUgMSBhbmQgY29udHJvbGxpbmcgZm9yIHRoZSBvdGhlciB2YXJpYWJsZXMsIHdlIGNhbiBzYXkgdGhhdCB0aGUgcGh5c2ljYWwgYWN0aXZpdHkgY29lZmZpY2llbnQgaXMgYSByZWxldmFudCB2YXJpYWJsZSBhdCBwcmVkaWN0aW5nIHRoZSBvZGRzIG9mIGJlaW5nIGRlcHJlc3NlZCwgYXMgaXQgc3VnZ2VzdHMgdGhhdCB0aGVyZSBpcyBhIHRydWUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIFBoeXNpY2FsIEFjdGl2aXR5IGFuZCB0aGUgb2RkcyBvZiBiZWluZyBkZXByZXNzZWQuIAoKPlRoZSA5NSAlIENvbmZpZGVuY2UgSW50ZXJ2YWwgKENJKSBmb3IgdGhlIEV4cG9uZW50aWF0ZWQgUG92ZXJ0eTogUGh5c0FjdGl2ZVllcyBDb2VmZmljaWVudDoKClRoZSBDSSBmb3IgdGhlIFBvdmVydHk6UGh5c0FjdGl2ZVllcyBjb2VmZmljaWVudCBpcyAoMS4wNiwgMS4yNCkuIFRoaXMgc3VnZ2VzdHMgdGhhdCB3ZSBhcmUgOTUgJSBjb25maWRlbnQgdGhhdCB0aGUgdHJ1ZSBwb3B1bGF0aW9uIG9mIHRoZSBvZGRzIHJhdGlvIGxpZXMgd2l0aGluICgxLjA2IGFuZCAxLjI0KS4gU2luY2UgdGhlIGludGVydmFsIGRvZXMgbm90IGluY2x1ZGUgMSwgd2UgY2FuIHNheSB0aGF0IHRoZXJlIGlzIGEgdHJ1ZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgZWZmZWN0cyBvZiBwaHlzaWNhbCBhY3Rpdml0eSBkZXBlbmRpbmcgb24gdGhlIHBvdmVydHkgc3RhdHVzIG9uIHRoZSBvZGRzIG9mIGJlaW5nIGRlcHJlc3NlZC4gIAoKCiMjIE1vZGVsIEV2YWx1YXRpb24KCkFzIHRoZSBmaXJzdCBzdGVwIGZvciBldmFsdWF0aW5nIG91ciBmaXR0ZWQgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbCwgd2UgdXNlZCB0aGUgYXVnbWVudCBmdW5jdGlvbiB0byBvYnRhaW4gdGhlc2UgcHJlZGljdGVkIHByb2JhYmlsaXRpZXMgZm9yIGVhY2ggaW5kaXZpZHVhbCBmcm9tIG91ciBkYXRhc2V0LCBiYXNlZCBvbiB0aGUgZml0dGVkIG1vZGVsLiBUaGVuLCB3ZSBjcmVhdGVkIGEgYm94IHBsb3QgdGhhdCBjb21wYXJlcyBvdXIgbW9kZWzigJlzIHByZWRpY3RlZCBwcm9iYWJpbGl0aWVzOiBvbmUgZm9yIHBlb3BsZSB3aG8gYWN0dWFsbHkgc2VsZi1yZXBvcnRlZCBhcyBkZXByZXNzZWQsIGFuZCBvbmUgZm9yIHBlb3BsZSB3aG8gZGlkIG5vdCBzZWxmLXJlcG9ydCBhcyBkZXByZXNzZWQuIFByZWZlcmFibHksIHdlIHdvdWxkIGxpa2UgdG8gb2JzZXJ2ZSB0aGF0IG91ciBmaXR0ZWQgbG9naXN0aWMgbW9kZWwgcHJlZGljdHMgYSBoaWdoZXIgcHJvYmFiaWxpdHkgb2YgYmVpbmcgZGVwcmVzc2VkIGZvciBwZW9wbGUgd2hvIGFjdHVhbGx5IHNlbGYtcmVwb3J0ZWQgYXMgYmVpbmcgZGVwcmVzc2VkLCBhbmQgYSBsb3dlciBwcm9iYWJpbGl0eSBvZiBiZWluZyBkZXByZXNzZWQgZm9yIHRob3NlIHdobyBkaWQgbm90IHNlbGYtcmVwb3J0IGFzIGRlcHJlc3NlZC4gIAoKYGBge3IsZWNobz1GQUxTRX0KdGhyZXNob2xkIDwtIDAuMjAKCiMgQm94cGxvdHMgV2l0aG91dCBUaHJlc2hvbGQ6Cm1vZCAlPiUKICBhdWdtZW50KHR5cGUucHJlZGljdCA9ICdyZXNwb25zZScpICU+JSAjIyBnZXQgcHJlZGljdGVkIHByb2JhYmlsaXRpZXMgZnJvbSBtb2RlbAogIGdncGxvdChhZXMoeSA9IC5maXR0ZWQsIHggPSBmYWN0b3IoRGVwcmVzc2VkKSkpICsgIyMgY29tcGFyZSBwcmVkaWN0ZWQgcHJvYmFiaWxpdGVzIHRvIGFjdHVhbCBvdXRjb21lCiAgZ2VvbV9ib3hwbG90KCkgKyAKICBnZ3RpdGxlKCdGaWd1cmUgMjogUHJlZGljdGlvbnMgZnJvbSBMb2dpc3RpYyBNb2RlbCcpICsKICB4bGFiKCJBY3R1YWwgT3V0Y29tZSAoMCA9IE5vdCBEZXByZXNzZWQsIDEgPSBEZXByZXNzZWQpIikgKwp5bGFiKCJQcmVkaWN0ZWQgUHJvYmFiaWxpdHkgb2YgdGhlIE91dGNvbWUgRGVwcmVzc2VkIikgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCkZyb20gdGhlIGJveHBsb3QgYWJvdmUsIHdlIGNhbiBzZWUgdGhhdCB0aGUgbWVkaWFuIHByb2JhYmlsaXR5IG9mIHRoZSBwcmVkaWN0ZWQgb3V0Y29tZSBgRGVwcmVzc2VkYCBpcyBoaWdoZXIgZm9yIHBlb3BsZSB3aG8gc2VsZi1yZXBvcnRlZCBhcyBEZXByZXNzZWQsIGF0IGFyb3VuZCAwLjI0LiBBcyBjb21wYXJlZCB0byB0aGUgbWVkaWFuIG9mIDAuMTcgZm9yIHRoZSBwcmVkaWN0ZWQgb3V0Y29tZSBvZiBiZWluZyBgRGVwcmVzc2VkYCBmb3IgcGVvcGxlIHdobyBkaWQgbm90IHNlbGYtcmVwb3J0IGFzIGBEZXByZXNzZWRgLiBGdXJ0aGVybW9yZSwgd2UgY2FuIG9ic2VydmUgdGhhdCBib3RoIGJveHBsb3RzIGFyZSBub3Qgc2lnbmlmaWNhbnRseSBza2V3ZWQsIHdoaWNoIGNvdWxkIHNob3cgdGhhdCB0aGUgcHJlZGljdGVkIHByb2JhYmlsaXRpZXMgYXJlIHJlbGF0aXZlbHkgZGlzdHJpYnV0ZWQgYXJvdW5kIHRoZSBtZWRpYW4gbWVudGlvbmVkIGFib3ZlLiBJbiBwYXJ0aWN1bGFyLCB3ZSBjYW4gb2JzZXJ2ZSB0aGF0IG1vc3Qgb2YgdGhlIHByZWRpY3RlZCBwcm9iYWJpbGl0aWVzIGFyZSBsb3dlciB0aGFuIDUwIHBlcmNlbnQuCgoKIyMjIFNlbGVjdGluZyBhIFRocmVzaG9sZAoKVGhlIG5leHQgc3RlcCBpbiBvdXIgbW9kZWzigJlzIGV2YWx1YXRpb24gd2FzIHRvIHNlbGVjdCBhIHRocmVzaG9sZCB0aGF0IGhlbHBlZCB1cyB0byB0dXJuIG91ciBtb2RlbOKAmXMgcHJlZGljdGVkIHByb2JhYmlsaXRpZXMgaW50byBhIGJpbmFyeSBkZWNpc2lvbi4gQWZ0ZXIgY29uc2lkZXJpbmcgdGhlIGNvbnRleHQgb2Ygb3VyIGRhdGEsIGFuZCB0aGUgc2lnbmlmaWNhbmNlIG9mIHRoZSBvdXRjb21lcyBvZiB0aGlzIGZpdHRlZCBtb2RlbCwgd2Ugb3B0ZWQgdG8gdXNlIGEgdGhyZXNob2xkIG9mIDAuMjAgd2hpY2ggZmFsbHMgaW4gYmV0d2VlbiB0aGUgdHdvIG1lZGlhbiBwcmVkaWN0ZWQgcHJvYmFiaWxpdGllcyBmb3IgYm90aCBhY3R1YWwgb3V0Y29tZXMuIFNwZWNpZmljYWxseSwgd2UgYWNrbm93bGVkZ2UgdGhhdCBpdCBpcyBvdXIgcHJpb3JpdHkgdG8gaGF2ZSBhIGxvdyByYXRlIG9mIGZhbHNlIG5lZ2F0aXZlcywgYnV0IGFsc28gd2Ugd2FudCB0byBiZSBjYXJlZnVsIGFib3V0IG5vdCBoYXZpbmcgYSBoaWdoIG51bWJlciBvZiBmYWxzZSBwb3NpdGl2ZXMuIEZvciBpbnN0YW5jZSwgd2UgZG8gbm90IGludGVuZCB0byBoYXZlIGEgaGlnaCBpbmNpZGVuY2Ugb2YgZmFsc2UgbmVnYXRpdmVzIHRoYXQgd2lsbCBpbmNvcnJlY3RseSBjbGFzc2lmeSBtYW55IG9mIHRoZSBpbmRpdmlkdWFscyBhcyBub3QgZGVwcmVzc2VkLCB3aGVuIGluIGZhY3QgdGhleSBzZWxmLXJlcG9ydGVkIGFzIGRlcHJlc3NlZC4gQnkgbG9va2luZyBhdCBpdCBmcm9tIGEgd2lkZXIgcGVyc3BlY3RpdmUsIHN1Y2ggbWlzY2xhc3NpZmljYXRpb24gYnkgb3VyIG1vZGVsIG1pZ2h0IGhhdmUgYSBmdXJ0aGVyIGltcGFjdCBvbiB0aGUgaW5kaXZpZHVhbOKAmXMgd2VsbGJlaW5nLCBidXQgYWxzbyBpbiB0aGUgd2F5IHRoZXkgc2VlayBhc3Npc3RhbmNlIG9yIHRoZSB0eXBlIG9mIHN1cHBvcnQgdGhleSByZWNlaXZlLiBDb252ZXJzZWx5LCB3ZSBhbHNvIGFpbSB0byBhdm9pZCBhbnkgaGlnaCBpbmNpZGVuY2Ugb2YgZmFsc2UgcG9zaXRpdmVzIHRoYXQgd2lsbCBpbmNvcnJlY3RseSBjbGFzc2lmeSBpbmRpdmlkdWFscyBhcyBkZXByZXNzZWQsIHdoZW4gdGhleSBhY3R1YWxseSBzZWxmLXJlcG9ydGVkIG90aGVyd2lzZSwgd2hpY2ggbWlnaHQgb3Bwb3NpdGVseSBsZWFkIHRvIHVubmVjZXNzYXJ5IGludGVydmVudGlvbnMuIAoKCmBgYHtyLGVjaG89RkFMU0V9CiMgQm94cGxvdHMgV2l0aCB0aHJlc2hvbGQ6Cm1vZCAlPiUKICBhdWdtZW50KHR5cGUucHJlZGljdCA9ICdyZXNwb25zZScpICU+JSAjIyBnZXQgcHJlZGljdGVkIHByb2JhYmlsaXRpZXMgZnJvbSBtb2RlbAogIGdncGxvdChhZXMoeSA9IC5maXR0ZWQsIHggPSBmYWN0b3IoRGVwcmVzc2VkKSkpICsgIyMgY29tcGFyZSBwcmVkaWN0ZWQgcHJvYmFiaWxpdGVzIHRvIGFjdHVhbCBvdXRjb21lCiAgZ2VvbV9ib3hwbG90KCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjRkZCNEI0IiwgIiNEQUZGRUEiKSkgKwogIGdndGl0bGUoJ0ZpZ3VyZSAzOiBQcmVkaWN0aW9ucyBmcm9tIExvZ2lzdGljIE1vZGVsJykgKwogIGxhYnMoc3VidGl0bGUgPSAiVGhlIFJlZCBMaW5lIFJlcHJlc2VudHMgdGhlIFNlbGVjdGVkIFRocmVzaG9sZCBvZiAwLjIwIikgKwogIHhsYWIoIkFjdHVhbCBPdXRjb21lICgwID0gTm90IERlcHJlc3NlZCwgMSA9IERlcHJlc3NlZCkiKSArCnlsYWIoIlByZWRpY3RlZCBQcm9iYWJpbGl0eSBvZiB0aGUgT3V0Y29tZSBgRGVwcmVzc2VkYCIpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSB0aHJlc2hvbGQsIGNvbG9yID0gJ3JlZCcsIGxpbmV0eXBlID0gMikgICsKICB0aGVtZV9taW5pbWFsKCkgCgpgYGAKClRoZSBib3hwbG90IGFib3ZlIHNob3dzIHRoZSBzYW1lIHByZWRpY3RlZCBwcm9iYWJpbGl0aWVzIGZvciBib3RoIGFjdHVhbCBvdXRjb21lcyBvZiBgRGVwcmVzc2VkYCBhbmQgYE5vdCBEZXByZXNzZWRgLiBUaGUgZGFzaGVkIGxpbmUgY29ycmVzcG9uZHMgdG8gdGhlIHRocmVzaG9sZCBvZiAwLjIwIHNldCBpbiBiZXR3ZWVuIHRoZSBtZWRpYW5zIG9mIHRoZSBwcmVkaWN0ZWQgcHJvYmFiaWxpdGllcyBmb3IgYm90aCBhY3R1YWwgb3V0Y29tZXMuIAoKCiMjIyBDYWxjdWxhdGluZyB0aGUgTW9kZWwgUXVhbGl0eSBNZXRyaWNzCgpBZnRlciBzZWxlY3RpbmcgdGhlIHRocmVzaG9sZCwgd2UgbW92ZWQgb250byBjb21wdXRpbmcgdGhlIGJpbmFyeSBwcmVkaWN0aW9ucyBmcm9tIHRoZSBsb2dpc3RpYyBtb2RlbC4gVGhpcyBwcm9jZXNzIGFsbG93ZWQgdXMgdG8gY2xhc3NpZnkgZWFjaCBwZXJzb24gaW4gb3VyIGRhdGFzZXQgYmFzZWQgb24gdGhlaXIgcHJlZGljdGVkIHByb2JhYmlsaXR5IG9mIGJlaW5nIGBEZXByZXNzZWRgOiBvdXIgbW9kZWwgcHJlZGljdGVkIHRoYXQgZXZlcnlvbmUgd2l0aCBhIHByb2JhYmlsaXR5IGhpZ2hlciB0aGFuIG91ciB0aHJlc2hvbGQgaXMgYERlcHJlc3NlZGAsIHdoaWxlIHRoZSByZXN0IGFyZSBub3QuIFRoZSBjb250aW5nZW5jeSB0YWJsZSBiZWxvdyBlbmFibGVzIHVzIHRvIGNvbXBhcmUgb3VyIG1vZGVs4oCZcyBwcmVkaWN0aW9ucyB0byB0aGUgdHJ1ZSBvdXRjb21lLCBkZXRlcm1pbmluZyB3aGV0aGVyIHRoZSBpbmRpdmlkdWFscyB3ZXJlIGluZGVlZCBgRGVwcmVzc2VkYCBvciBub3QuIAoKYGBge3IsZWNobz1GQUxTRSwgbWVzc2FnZSA9IEZBTFNFLCBldmFsID0gRkFMU0V9CiMgZ2V0IGJpbmFyeSBwcmVkaWN0aW9ucyBmb3IgbW9kMQp0aHJlc2hvbGQgPC0gMC4yMAptb2QgJT4lCiAgYXVnbWVudCh0eXBlLnByZWRpY3QgPSAncmVzcG9uc2UnKSAlPiUgIyMgZ2V0IHByZWRpY3RlZCBwcm9iYWJpbGl0eSBvZiBjYWxsYmFjawogIG11dGF0ZShwcmVkaWN0RGVwcmVzc2VkID0gLmZpdHRlZCA+PSB0aHJlc2hvbGQpICU+JSAjIyBwcmVkaWN0IGNhbGxiYWNrIGlmIHByb2JhYmlsaXR5IGJpZ2dlciB0aGFuIHRocmVzaG9sZAogIGNvdW50KERlcHJlc3NlZCwgcHJlZGljdERlcHJlc3NlZCkKYGBgCgogICAgICAgICAgICAgICAgICAgICAgICAgIFByZWRpY3QgRGVwcmVzc2VkICAgUHJlZGljdCBOb3QgRGVwcmVzc2VkICAgIFRvdGFsCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICAtLS0tLS0tLS0tLS0tLS0tLS0gIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICAtLS0tLS0tCkFjdHVhbGx5IERlcHJlc3NlZCAgICAgICAgICAgICAgODIxICAgICAgICAgICAgICAgNDg3ICAgICAgICAgICAgICAgICAgMTMwOApBY3R1YWxseSBOb3QgRGVwcmVzc2VkICAgICAgICAgIDIwNjQgICAgICAgICAgICAgIDI4NTggICAgICAgICAgICAgICAgIDQ5MjIKVG90YWwgICAgICAgICAgICAgICAgICAgICAgICAgICAyODg1ICAgICAgICAgICAgICAzMzQ1ICAgICAgICAgICAgICAgICA2MjMwCgoKVGhlbiwgd2UgcHJvY2VlZGVkIHRvIGNhbGN1bGF0ZSB0aGUgYmluYXJ5IHByZWRpY3Rpb25zLCBhcyBzaG93biBieSB0aGUgdGFibGUgYmVsb3c6CgpgYGB7ciwgZWNobz1GQUxTRX0KIyBDcmVhdGUgYSBkYXRhIGZyYW1lIHdpdGggdGhlIGJpbmFyeSBwcmVkaWN0aW9uczogCmRmIDwtIGRhdGEuZnJhbWUoTWVhc3VyZXM9IGMoIkFjY3VyYWN5IiwgIlNlbnNpdGl2aXR5IiwgIlNwZWNpZmljaXR5IiwgIkZhbHNlIE5lZ2F0aXZlIFJhdGUgKEZOUikiLCAiRmFsc2UgUG9zaXRpdmUgUmF0ZSAoRlBSKSIpLAogICAgICAgICAgICAgICAgIFZhbHVlcyA9IGMoIjU5LjA1ICUiLCAiNjIuNzcgJSIsICI1OC4wNyAlIiwgIjM3LjIzICUiLCAiNDEuOTMgJSIpKQpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFfQojIE91dHB1dCB0aGUgdGFibGUgdXNpbmcga2FibGUoKQprbml0cjo6a2FibGUoZGYsIGFsaWduID0gYygibCIsICJjIiksIGNhcHRpb24gPSAiUXVhbGl0eSBNZXRyaWNzIikKYGBgCgojIyMgSW50ZXJwcmV0aW5nIHRoZSBNb2RlbCBRdWFsaXR5IE1ldHJpY3MgCgpBY2N1cmFjeTogVGhlIG1vZGVs4oCZcyBhY2N1cmFjeSBmYWxscyBpbiBhIG1vZGVyYXRlIHJhbmdlIG9mIDAuNTkwNSB0aGF0IHRlbGxzIHVzIHRoYXQgdGhlIG1vZGVsIGNvcnJlY3RseSBwcmVkaWN0ZWQgdGhlIHByZXNlbmNlIG9yIGFic2VuY2Ugb2YgZGVwcmVzc2lvbiBpbiA1OS4wNSUgb2YgdGhlIGNhc2VzLiAKClNlbnNpdGl2aXR5OiBUaGlzIGlzIGEgbW9kZXJhdGUgcHJvcG9ydGlvbiBvZiBhY3R1YWwgYERlcHJlc3NlZGAgY2FzZXMgdGhhdCB3ZXJlIGFjY3VyYXRlbHkgaWRlbnRpZmllZCBhcyBgRGVwcmVzc2VkYCBieSB0aGUgbW9kZWwuIEluIHRoaXMgY2FzZSwgdGhlIHNlbnNpdGl2aXR5ICBvZiAwLjYyNzcgbWVhbnMgdGhhdCB0aGUgbW9kZWwgY29ycmVjdGx5IGlkZW50aWZpZWQgNjIuNzcgJSBvZiB0aGUgYWN0dWFsIGBEZXByZXNzZWRgIGNhc2VzLiAKClNwZWNpZmljaXR5OiBUaGlzIGlzIHRoZSBwcm9wb3J0aW9uIG9mIGFjdHVhbCBgTm90IERlcHJlc3NlZGAgY2FzZXMgdGhhdCB3ZXJlIGFjY3VyYXRlbHkgcHJlZGljdGVkIGFzIGBOb3QgRGVwcmVzc2VkYCBieSB0aGUgbW9kZWwuIEJhc2VkIG9uIHRoZSByZXN1bHRzLCB0aGUgc3BlY2lmaWNpdHkgb2YgdGhlIG1vZGVsIGlzIHNvbWV3aGF0IGF2ZXJhZ2UgaXMgMC41ODA3IG1lYW5pbmcgdGhhdCB0aGUgbW9kZWwgY29ycmVjdGx5IGlkZW50aWZpZWQgNTguMDcgJSBvZiB0aGUgYWN0dWFsIGBOb3QtRGVwcmVzc2VkYCBjYXNlcy4gCgpGYWxzZSBOZWdhdGl2ZSBSYXRlIChGUk4pOiBUaGUgcHJvcG9ydGlvbiBvZiBpbmRpdmlkdWFscyB3aG8gYXJlIGFjdHVhbGx5IGBEZXByZXNzZWRgIGJ1dCB0aGF0IGFyZSBwcmVkaWN0ZWQgYnkgb3VyIG1vZGVsIGFzIGBOb3QgRGVwcmVzc2VkYC4gSW4gdGhpcyBjYXNlLCAwLjM3MjMsIHdoaWNoIG1lYW5zIHRoYXQgYW1vbmcgdGhlIGNhc2VzIHByZWRpY3RlZCBhcyBgTm90IERlcHJlc3NlZGAgYnkgdGhlIG1vZGVsLCAzNy4yMyUgYXJlIGFjdHVhbGx5IGBEZXByZXNzZWRgLiBUaGlzIHN0aWxsIHJlbGF0aXZlbHkgaGlnaCBmYWxzZSBuZWdhdGl2ZSByYXRlIG1lYW5zIHRoYXQgdGhlIG1vZGVsIGlzIGluY29ycmVjdGx5IGNsYXNzaWZ5aW5nIG1hbnkgaW5kaXZpZHVhbHMgYXMgYE5vdCBEZXByZXNzZWRgLCB3aGVuIGluZGVlZCB0aGV5IHNlbGYtcmVwb3J0ZWQgYXMgc3VjaC4gCgpGYWxzZSBQb3NpdGl2ZSBSYXRlIChGUFIpOiBUaGUgcHJvcG9ydGlvbiBvZiBpbmRpdmlkdWFscyB3aG8gYXJlIGFjdHVhbGx5IGBOb3QgRGVwcmVzc2VkYCBidXQgYXJlIGNsYXNzaWZpZWQgYXMgYERlcHJlc3NlZGAgYnkgdGhlIG1vZGVsLiBJbiB0aGlzIGNhc2UsIHRoZSBmYWxzZSBwb3NpdGl2ZSByYXRlIGlzIDAuNDE5Mywgd2hpY2ggbWVhbnMgdGhhdCBhbW9uZyB0aGUgY2FzZXMgcHJlZGljdGVkIGFzIGRlcHJlc3NlZCBieSB0aGUgbW9kZWwsIDQxLjkzICUgYXJlIGFjdHVhbGx5IG5vdCBkZXByZXNzZWQuIFRoaXMgcmF0ZSBpcyByb3VnaGx5IGhpZ2hlciB0aGFuIHRoZSBGUFIsIGFuZCBpbiB0aGlzIGNvbnRleHQsIHRoaXMgY291bGQgaW5kaWNhdGUgdGhhdCB0aGUgbW9kZWwgaXMgaW5jb3JyZWN0bHkgY2xhc3NpZnlpbmcgbWFueSBpbmRpdmlkdWFscyBhcyBkZXByZXNzZWQsIHdoZW4gdGhleSBhcmUgbm90LCBsZWFkaW5nIHRvIHVubmVjZXNzYXJ5IGludGVydmVudGlvbnMgb3IgdHJlYXRtZW50LiAKCiMgQ29uY2x1c2lvbnMKCiMjIEdlbmVyYWwgVGFrZWF3YXlzCgpUbyBjb25jbHVkZSwgb3VyIGdyb3VwIGRlY2lkZWQgdG8gbG9vayBhdCBob3cgdGhlIHJhdGlvIGJldHdlZW4gaG91c2Vob2xkIGluY29tZXMgYW5kIG5hdGlvbmFsIHBvdmVydHkgZ3VpZGVsaW5lcyBhbmQgcGh5c2ljYWwgYWN0aXZpdHkgcGxheSBpbnRvIGFuIGluZGl2aWR1YWwncyBtZW50YWwgaGVhbHRoLiBXZSBjaG9zZSB0byBsb29rIGludG8gdGhpcyBsYXJnZWx5IGJlY2F1c2Ugb2YgdGhlIGN1cnJlbnQgZGlzY3Vzc2lvbnMgb24gbWVudGFsIGhlYWx0aCBhbmQgaG93IGV4dGVybmFsIHNvY2lvZWNvbm9taWMgZmFjdG9ycyBoYXZlIGEgbWFqb3Igcm9sZSBpbiBpbXBhY3RpbmcgdGhpcy4gV2UgZGVjaWRlZCB0byBsb29rIGludG8gdGhpcyBjdXJpb3NpdHkgYnkgdXNpbmcgdGhlIE5IQU5FcyBkYXRhLCBhbmQgbG9va2luZyBhdCB0aGUgdmFyaWFibGVzIHN1cnJvdW5kaW5nIHBvdmVydHksIHBoeXNpY2FsIGFjdGl2aXR5LCBhbmQgZGVwcmVzc2lvbiB0aHJvdWdoIHRoZSB1c2Ugb2YgYSBsb2dpc3RpY2FsIHJlZ3Jlc3Npb24gYW5hbHlzaXMuIFRoZSB0d28gZm9ybWVyIG9mIHRoZSB0aHJlZSBhY3QgYXMgdGhlIGV4cGxhbmF0b3J5IHZhcmlhYmxlcywgd2hpbGUgdGhlIGxhdHRlciBvZiB0aGUgdGhyZWUgaXMgYm90aCB0aGUgb3V0Y29tZSB2YXJpYWJsZSBhbmQgYSBiaW5hcnkgdmFyaWFibGUuIFdpdGggdGhpcywgd2UgY3JlYXRlZCBhIGxvZ2lzdGljYWwgcmVncmVzc2lvbiBtb2RlbCBhbmQgYW5hbHlzaXMgc28gYXMgdG8gYmV0dGVyIHVuZGVyc3RhbmQgdGhpcyBpc3N1ZSwgc3BsaXR0aW5nIG91ciBhbmFseXNpcyBpbnRvIG1vZGVsaW5nIGFuZCBpbnRlcnByZXRpbmcuIFdlIHdlcmUgYWJsZSB0byBzZWUgdGhhdCB0aGUgcGh5c2ljYWwgYWN0aXZpdHkgbGV2ZWxzIGFuZCBwb3ZlcnR5IHN0YXR1cyBvZiBpbmRpdmlkdWFscyBkbyBwbGF5IGEgcm9sZSBpbiBwcmVkaWN0aW5nIGlmIHRoZXkgZG8gb3IgZG8gbm90IHN1ZmZlciBmcm9tIGRlcHJlc3Npb24uIEluIHN1bSwgb3VyIGxvZ2lzdGljYWwgcmVncmVzc2lvbiBtb2RlbCBzaG93cyB0aGF0LCB3aGVuIGFsbCBvdGhlciB2YXJpYWJsZXMgYXJlIGNvbnN0YW50LCB0aGUgb2RkcyBvZiBzdWZmZXJpbmcgZnJvbSBkZXByZXNzaW9uIGFyZSBoaWdoZXIgd2hlbiBsaXZpbmcgY2xvc2VyIHRvIHRoZSBwb3ZlcnR5IGxpbmUuIEF0IHRoZSBzYW1lIHRpbWUsIHRoZSBvZGRzIG9mIGJlaW5nIGRlcHJlc3NlZCBhcmUgaGlnaGVyIHdoZW4gdGhlcmUgaXMgYSBsYWNrIG9mIHBoeXNpY2FsIGFjdGl2aXR5LiBUaGVzZSB0d28gcmVzdWx0cyB3ZXJlIGNvbnNpc3RlbnQgd2l0aCB3aGF0IHdlIGhhZCBleHBlY3RlZCB0byBmaW5kOyBXZSBpbml0aWFsbHkgdGhpbmsgdGhlc2UgcmVzdWx0cyBhcmUgZHVlIHRvIHRoZSBtZW50YWwgc3RyYWluIG9mIGZpbmFuY2lhbCBzdHJlc3NvcnMgb24gdG9wIG9mIGEgbG93IHBoeXNpY2FsIGFjdGl2aXR5LCB3aGljaCBpcyBjb21tb25seSBhY2NlcHRlZCB0byBsZWFkIHRvIGxlc3MgZGVwcmVzc2lvbi4gT24gYW5vdGhlciBub3RlLCB0aGUgaW50ZXJhY3Rpb24gdGVybSBzaG93cyB0aGF0IHRoZSBvZGRzIG9mIGJlaW5nIGRlcHJlc3NlZCBpcyBoaWdoZXIgZm9yIGluZGl2aWR1YWxzIHdobyBsaXZlIGZ1cnRoZXIgZnJvbSB0aGUgbmF0aW9uYWwgcG92ZXJ0eSBndWlkZWxpbmVzIGFuZCB3aG8gaGF2ZSBhIGhpZ2hlciBsZXZlbCBvZiBwaHlzaWNhbCBhY3Rpdml0eS4gVGh1cywgaXQgd291bGQgYmUgaGVscGZ1bCB0byBsb29rIGF0IG90aGVyIHBvdGVudGlhbCBleHBsYW5hdG9yeSB2YXJpYWJsZXMgZnJvbSB0aGUgZGF0YXNldCB0byBiZXR0ZXIgdW5kZXJzdGFuZCB3aGF0IGNhdXNlcyB0aGlzIHVuZXhwZWN0ZWQgcmVzdWx0LiAKCldlIGludGVycHJldGVkIG91ciBjb25maWRlbmNlIGludGVydmFscyB0byByZWFmZmlybSB0aGF0LCB3aGVuIGFsb25lLCBjb25kaXRpb25zIG9mIHBvdmVydHkgYW5kIGxldmVscyBvZiBwaHlzaWNhbCBhY3Rpdml0eSBhcmUgY29ycmVsYXRlZCB3aXRoIHRoZSBvZGRzIG9mIGFuIGluZGl2aWR1YWwgc3VmZmVyaW5nIGZyb20gZGVwcmVzc2lvbi4gSG93ZXZlciwgd2Ugd2VyZSBhbHNvIGFibGUgdG8gcmVhZmZpcm0gdGhhdCB0aGUgc3RhdGUgb2YgZGVwcmVzc2lvbiBpcyBzdGlsbCBsYXJnZWx5IGluZmx1ZW5jZWQgYnkgdGhlIHBvdmVydHkgc3RhdHVzIG9mIHRoZSBpbmRpdmlkdWFsIGFzIHdlbGwgYXMgdGhlaXIgcGh5c2ljYWwgYWN0aXZpdHkgc3RhdHVzIGludGVyYWN0aXZlbHkuIEF0IHRoZSBzYW1lIHRpbWUsIG91ciBib3gtcGxvdCBzaG93ZWQgdGhhdCB0aGUgbWVkaWFuIHByb2JhYmlsaXR5IG9mIGJlaW5nIGRlcHJlc3NlZCB3YXMgaGlnaGVyIGZvciB0aG9zZSB3aG8gYWN0dWFsbHkgc2VsZi1yZXBvcnRlZCBkZXByZXNzaW9uLiBXaGVuIGFkZGluZyBhIHRocmVzaG9sZCB0byBhY2NvdW50IGZvciB0aGUgbWVkaWFucyBvZiB0aGUgcHJlZGljdGVkIHByb2JhYmlsaXRpZXMgZm9yIGJvdGggYWN0dWFsIG91dGNvbWVzLCB3ZSB3ZXJlIGFibGUgdG8gY29tcHV0ZSB0aGF0IHRoZSBtb2RlbCB3YXMgNTklIGFjY3VyYXRlLCA2MyUgc2Vuc2l0aXZlIGFuZCA1OCUgc3BlY2lmaWMuIEhvd2V2ZXIsIHRoZSBtb2RlbCB1bmZvcnR1bmF0ZWx5IHByb3ZpZGVkIG1hbnkgZmFsc2UgcG9zaXRpdmVzIGFzIHdlbGwgYXMgZmFsc2UgbmVnYXRpdmVzLCBmYWxzZWx5IGNsYXNzaWZ5aW5nIG1hbnkgaW5kaXZpZHVhbHMgYXMgYm90aCBkZXByZXNzZWQgYW5kIG5vdCBkZXByZXNzZWQuICAKCkFsbCBpbiBhbGwsIHRoZSBOSEFORXMgZGF0YSBjYW4gYmUgdXRpbGl6ZWQgdG8gY29uY2x1ZGUgdGhhdCBhbiBpbmRpdmlkdWFsJ3MgcHJveGltaXR5IHRvIHBvdmVydHkgYW5kIHRoZWlyIGxldmVsIG9mIHBoeXNpY2FsIGFjdGl2aXR5IGNsZWFybHkgcGxheSBtYWpvciByb2xlcyBpbiBkZXRlcm1pbmluZyB0aGVpciBtZW50YWwgaGVhbHRoIG91dGNvbWVzIGFzIGluZGljYXRlZCBieSBzZWxmLXJlcG9ydGVkIGRlcHJlc3Npb24uIAoKCiMjIExpbWl0YXRpb25zCgpBZnRlciB3b3JraW5nIHdpdGggdGhlIE5IQU5FUyBkYXRhIHNldCwgd2UgaWRlbnRpZmllZCBzb21lIGxpbWl0YXRpb25zIHRoYXQgbWlnaHQgaGF2ZSBhbiBlZmZlY3Qgb24gb3VyIG1vZGVsLiBBbHRob3VnaCB0aGlzIHN1cnZleSBzdHJpdmVzIHRvIGNvbGxlY3QgZGF0YSBmcm9tIGEgcmVwcmVzZW50YXRpdmUgc2FtcGxlIG9mIHRoZSBVUyBwb3B1bGF0aW9uLCB0aGUgc2FtcGxlIHNpemUgaXMgc3RpbGwgc21hbGwgaW4gY29tcGFyaXNvbiB0byB0aGUgYWN0dWFsIHBvcHVsYXRpb24sIHdoaWNoIGxpbWl0cyB0byBzb21lIGV4dGVudCB0aGUgc2NvcGUgb2Ygb3VyIG1vZGVsIHByZWRpY3Rpb25zLiBIZW5jZSwgc29tZSBncm91cHMgbWlnaHQgc3RpbGwgYmUgdW5kZXJyZXByZXNlbnRlZC4gSW4gYWRkaXRpb24sIHR3byBvZiB0aGUgdmFyaWFibGVzIHdlIHVzZWQgdG8gZml0IG91ciBtb2RlbDogUGh5c2ljYWwgQWN0aXZlIGFuZCBEZXByZXNzaW9uIGFyZSBzZWxmLXJlcG9ydGVkIHZhcmlhYmxlcy4gSW5kZWVkLCB0aGVzZSB0eXBlcyBvZiB2YXJpYWJsZXMgYXJlIHByb21wdCBzZWxmLWJpYXNlcyBhcyB0aGUgc3VydmV5IHJlc3BvbmRlbnRzIG1pZ2h0IG92ZXItcmVwb3J0IG9yIHVuZGVyLXJlcG9ydCB0aGVpciBiZWhhdmlvcnMsIGFmZmVjdGluZyB0aGUgYWNjdXJhY3kgb2YgdGhlIGRhdGEuIFRvIGlsbHVzdHJhdGUgdGhpcywgc29tZSBwZW9wbGUgbWlnaHQgaGF2ZSBkaWZmZXJlbnQgcGVyc3BlY3RpdmVzIG9uIGRpZmZlcmVuY2VzIGluIGxldmVscywgZnJlcXVlbmN5IG9yIGludGVuc2l0eSBvZiBwaHlzaWNhbCBhY3Rpdml0eS4gRnVydGhlcm1vcmUsIHdoaWxlIHNlbGYtcmVwb3J0aW5nIGRlcHJlc3Npb24sIHRoZXJlIG1pZ2h0IGJlIHNvbWUgc3RpZ21hIG9yIGN1bHR1cmFsIGJpYXNlcyBhc3NvY2lhdGVkIHdpdGggbWVudGFsIGhlYWx0aCB3aGljaCBtaWdodCBpbXBhY3QgaG93IGluZGl2aWR1YWxzIHJlcG9ydCB0aGVpciBzeW1wdG9tcy4gSW4gYSBzaW1pbGFyIHdheSwgdGhlcmUgbWlnaHQgYmUgYSBsYWNrIG9mIGtub3dsZWRnZSBvZiB0aGUgc3ltcHRvbXMgb2YgZGVwcmVzc2lvbiB0aGF0IGNvbnRyaWJ1dGUgdG8gdGhlIHVuZGVyLXJlcG9ydCBvZiBkZXByZXNzaW9uLiBPdmVyYWxsLCBpdCBpcyBpbXBvcnRhbnQgdG8gY29uc2lkZXIgdGhlIGFmb3JlbWVudGlvbmVkIGxpbWl0YXRpb25zIHdoaWxlIGRyYXdpbmcgY29uY2x1c2lvbnMgZnJvbSBvdXIgZmluZGluZ3MuIAoKUmVnYXJkaW5nIHRoZSBtb2RlbCBxdWFsaXR5IG1ldHJpY3MsIHdlIGNhbiBzYXkgdGhhdCB0aGVzZSB2YWx1ZXMgYXJlIG1vZGVyYXRlLiBIb3dldmVyLCB0aGV5IGFyZSBub3QgcmVsYXRpdmVseSBoaWdoIHRvIGNvbmNsdWRlIHRoYXQgb3VyIG1vZGVsIGNhbiBhY2N1cmF0ZWx5IHByb3ZpZGUgYSBwZXJmZWN0IGZpdCB0byB0aGUgZGF0YSBnaXZlbiB0aGF0IHRoZSBwcmVkaWN0ZWQgcHJvYmFiaWxpdGllcyBhcmUgbm90IGNsb3NlbHkgbWF0Y2hpbmcgdGhlIGFjdHVhbCBvdXRjb21lcy4gRm9yIGluc3RhbmNlLCBvdXIgZml0dGVkIG1vZGVsIHBlcmZvcm1zIGFkZXF1YXRlbHksIGJ1dCBub3QgZXhjZXB0aW9uYWxseSBpbiB0ZXJtcyBvZiBhY2N1cmFjeSwgd2hpY2ggaXMgdGhlIG1ldHJpYyB0aGF0IGRldGVybWluZXMgaG93IHdlbGwgb3VyIG1vZGVsIGNhbiBwcmVkaWN0IHRoZSBjYXNlIGZvciBkZXByZXNzaW9uIGFuZCBub3QgZGVwcmVzc2lvbi4gRnVydGhlcm1vcmUsIHdlIGFja25vd2xlZGdlIHRoYXQgd2hlbiBjaG9vc2luZyB0aGUgdGhyZXNob2xkIHdlIGFpbWVkIGF0IHJlZHVjaW5nIHRoZSBmYWxzZSBuZWdhdGl2ZXMgcHJvZHVjZWQgYnkgb3VyIG1vZGVsLiBIZW5jZSwgd2UgY2FuIHNheSB0aGF0IHRoZXJlIGFyZSBmdXJ0aGVyIGltcGxpY2F0aW9ucyBpbiBkb2luZyBzby4gQW4gZXhhbXBsZSBvZiB0aGlzIGlzIHRoYXQgdGhlIEZhbHNlIFBvc2l0aXZlIFJhdGUgaXMgbW9kZXJhdGVseSBoaWdoLCB3aGljaCBpbmRpY2F0ZXMgdGhhdCBhbW9uZyB0aGUgaW5kaXZpZHVhbHMgd2hvIHNlbGYtcmVwb3J0ZWQgYXMgbm90IGRlcHJlc3NlZCwgdGhlcmUgaXMgNDEuOTMgJSBvZiBpbmRpdmlkdWFscyB3aG8gYXJlIHByZWRpY3RlZCBhcyBgRGVwcmVzc2VkYCBieSBvdXIgbW9kZWwuCgpUaGVyZWZvcmUsIGZyb20gYSBwZXJzb25hbCBwb2ludCBvZiB2aWV3LCB0aGlzIG1pZ2h0IGltcGFjdCB0aGVpciB3ZWxsLWJlaW5nIGJ5IGNyZWF0aW5nIHVubmVjZXNzYXJ5IHN0cmVzcyBvbiB0aGUgaW5kaXZpZHVhbHMgYW5kIHRoZSB3YXkgdGhleSBzZWVrIGFzc2lzdGFuY2UuIE1vcmVvdmVyLCB0aGlzIGVmZmVjdCBtaWdodCBwb3RlbnRpYWxseSBwdXQgYSBzdHJhaW4gb24gdGhlIGhlYWx0aGNhcmUgc3lzdGVtLCB3aGljaCBtaWdodCBsZWFkIHRvIG92ZXJidXJkZW5pbmcgb2YgdGhlIGhlYWx0aGNhcmUgc3lzdGVtLCBhbmQgaXQgbWlnaHQgZGVjcmVhc2UgdGhlIHF1YWxpdHkgZm9yIHRob3NlIHdobyBhY3R1YWxseSBuZWVkIGl0LiAKCkxhc3RseSwgb3VyIG1vZGVsIGRpZCBub3QgYWNjb3VudCBmb3IgaW1wb3J0YW50IHZhcmlhYmxlcyBzdWNoIGFzIGdlbmRlciwgYWdlIGFuZCBldGhuaWNpdHkvcmFjZS4gVGhlcmVmb3JlLCBmb3IgZnV0dXJlIHdvcmsgaXQgd291bGQgYmUgaW50ZXJlc3RpbmcgdG8gZXhwbG9yZSBvdGhlciBleHBsYW5hdG9yeSB2YXJpYWJsZXMsIGFuZCBzZWUgaG93IHRoaXMgbWlnaHQgYWZmZWN0IHRoZSBvdXRjb21lIG9mIERlcHJlc3Npb24uIEFzIGFuIGV4YW1wbGUsIGFnZSBjYW4gaGF2ZSBhbiBlZmZlY3Qgb24gZGVwcmVzc2lvbi4gSW4gZmFjdCwgYSBzdHVkeSBwdWJsaXNoZWQgYnkgdGhlIEpvdXJuYWwgb2YgQWJub3JtYWwgUHN5Y2hvbG9neSBmb3VuZCB0aGF0IFUuUyB0ZWVucyBhbmQgeW91bmcgYWR1bHRzJyBkZXByZXNzaW9uIGhhcyByaXNlbiBzaWduaWZpY2FudGx5IG92ZXIgdGhlIHBhc3QgZGVjYWRlIGluIGNvbXBhcmlzb24gd2l0aCBhZHVsdHMgMjYgb3Igb2xkZXIuIFRodXMsIGhhdmluZyBhZ2UgYXMgYW5vdGhlciBleHBsYW5hdG9yeSB2YXJpYWJsZSBtaWdodCBpbXByb3ZlIHRoZSBtZXRyaWNzIG9mIG91ciBtb2RlbC4gCgojIEFwcGVuZGl4CgojIyBXb3JrcyBDaXRlZAoKQ2VudGVycyBmb3IgRGlzZWFzZSBDb250cm9sIGFuZCBQcmV2ZW50aW9uLiAobi5kLikuIE5oYW5lcyBxdWVzdGlvbm5haXJlcywgZGF0YXNldHMsIGFuZCByZWxhdGVkIGRvY3VtZW50YXRpb24uIENlbnRlcnMgZm9yIERpc2Vhc2UgQ29udHJvbCBhbmQgUHJldmVudGlvbi4gUmV0cmlldmVkIEFwcmlsIDcsIDIwMjMsIGZyb20gaHR0cHM6Ly93d3duLmNkYy5nb3YvbmNocy9uaGFuZXMvRGVmYXVsdC5hc3B4IAoKR29vZHdpbiwgUi4gRC4sIERpZXJrZXIsIEwuIEMuLCBXdSwgTS4sIEdhbGVhLCBTLiwgSG92ZW4sIEMuIFcuLCAmIFdlaW5iZXJnZXIsIEEuIEguICgyMDIyLCBTZXB0ZW1iZXIgMTkpLiBUcmVuZHMgaW4gVS5TLiBkZXByZXNzaW9uIHByZXZhbGVuY2UgZnJvbSAyMDE1IHRvIDIwMjA6IFRoZSB3aWRlbmluZyB0cmVhdG1lbnQgZ2FwLiBBbWVyaWNhbiBKb3VybmFsIG9mIFByZXZlbnRpdmUgTWVkaWNpbmUuIFJldHJpZXZlZCBBcHJpbCA4LCAyMDIzLCBmcm9tIGh0dHBzOi8vd3d3LmFqcG1vbmxpbmUub3JnL2FydGljbGUvUzA3NDktMzc5NygyMikwMDMzMy02L2Z1bGx0ZXh0Izp+OnRleHQ9QW4lMjBpbmNyZWFzZSUyMGluJTIwZGVwcmVzc2lvbiUyMGZyb20sU0UlM0QwLjMxJTVEJTIwdG8lMjAyMDE5JTNBIAoKTmVpZ2htb25kLCBQLiAoMjAxOSwgTWFyY2ggMTQpLiBBIHJpc2UgaW4gZGVwcmVzc2lvbiBhbW9uZyB0ZWVucyBhbmQgeW91bmcgYWR1bHRzIGNvdWxkIGJlIGxpbmtlZCB0byBzb2NpYWwgbWVkaWEgdXNlLiBOUFIuIFJldHJpZXZlZCBBcHJpbCA4LCAyMDIzLCBmcm9tIGh0dHBzOi8vd3d3Lm5wci5vcmcvc2VjdGlvbnMvaGVhbHRoLXNob3RzLzIwMTkvMDMvMTQvNzAzMTcwODkyL2EtcmlzZS1pbi1kZXByZXNzaW9uLWFtb25nLXRlZW5zLWFuZC15b3VuZy1hZHVsdHMtY291bGQtYmUtbGlua2VkLXRvLXNvY2lhbC1tZWRpIAoKIyMgUiBDb2RlCgoKYGBge3IsZXZhbD1GQUxTRSxtZXNzYWdlID0gRkFMU0V9CiMgQ2xlYW5pbmcgZGF0YQpkZXByZXNzZWRfZGF0YSA8LSAKICBOSEFORVMgJT4lIAogIHNlbGVjdChQaHlzQWN0aXZlLCBEZXByZXNzZWQsIFBvdmVydHkpICU+JSAKICBtdXRhdGUoRGVwcmVzc2VkPWNhc2Vfd2hlbigKICAgIERlcHJlc3NlZCA9PSAiU2V2ZXJhbCIgfCBEZXByZXNzZWQ9PSAiTW9zdCIgfiAxLAogICAgRGVwcmVzc2VkID09ICJOb25lIiB+IDApIAogICkgJT4lIAogIGZpbHRlcihEZXByZXNzZWQgIT0iTkEiKSAKCmBgYAoKYGBge3IsZXZhbD1GQUxTRSxtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgRXhwbG9yYXRvcnkgVmlzdWFsaXphdGlvbiAKZGVwcmVzc2VkX2RhdGEgJT4lIGdncGxvdChhZXMoeT1QaHlzQWN0aXZlLHg9UG92ZXJ0eSxmaWxsPWZhY3RvcihEZXByZXNzZWQpKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBsYWJzKHk9IlBoeXNpY2FsbHkgQWN0aXZlIikrCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJEZXByZXNzZWQiKSsKICB0aGVtZV9jbGFzc2ljKCkKYGBgCgpgYGB7cixldmFsPUZBTFNFfQojIEZpdHRlZCBNb2RlbAoKbW9kIDwtIGRlcHJlc3NlZF9kYXRhICU+JQogIHdpdGgoZ2xtKERlcHJlc3NlZCB+IFBvdmVydHkgKiBQaHlzQWN0aXZlLCBmYW1pbHkgPSBiaW5vbWlhbCkpCmNvZWYobW9kKSAlPiUKICBleHAoKQoKCmNvbmZpbnQobW9kKSU+JQogIGV4cCgpCmBgYAoKYGBge3IsZXZhbD1GQUxTRX0KIyBDcmVhdGUgdGFibGUgZm9yIGZpdHRlZCBtb2RlbApkZjEgPC0gZGF0YS5mcmFtZShDb2VmZmljaWVudHM9IGMoIkludGVyY2VwdCIsICJQb3ZlcnR5IiwgIlBoeXNBY3RpdmVZZXMiLCAiUG92ZXJ0eTpQaHlzQWN0aXZlWWVzIiksCiAgICAgICAgICAgICAgICAgIEVzdGltYXRlcyA9IGMoIjAuNzUiLCAiMC43MiIsICIwLjUwIiwgIjEuMTQiKSwgU3RhbmRhcmRfRXJyb3JzID0gYygiKDAuNjQsIDAuODgpIiwgIigwLjY4LCAwLjc2KSIsICIoMC40LCAwLjY0KSIsICIoMS4wNSwgMS4yNCkiKSkKCiMgT3V0cHV0IHRoZSB0YWJsZSB1c2luZyBrYWJsZSgpCmtuaXRyOjprYWJsZShkZjEsIGFsaWduID0gYygibCIsICJjIiksIGNhcHRpb24gPSAiRmluYWwgTW9kZWwgRXN0aW1hdGVkIChFeHBvbmVudGlhdGVkKSBDb2VmZmljaWVudHMiKQpgYGAKCmBgYHtyLGV2YWw9RkFMU0V9CiMgTW9kZWwgY29lZmZpY2llbnRzIGZvciBtb2RlbCBpbnRlcnByZXRhdGlvbnMKbW9kIDwtIGRlcHJlc3NlZF9kYXRhICU+JQogIHdpdGgoZ2xtKERlcHJlc3NlZCB+IFBvdmVydHkgKiBQaHlzQWN0aXZlLCBmYW1pbHkgPSBiaW5vbWlhbCkpCmNvZWYobW9kKSAlPiUKICBleHAoKQpgYGAKCmBgYHtyLGV2YWw9RkFMU0V9CiMgQ3JlYXRlIDk1JSBjb25maWRlbmNlIGludGVydmFscyBmb3IgY29lZmZpY2llbnRzCmNvbmZpbnQobW9kLCBsZXZlbCA9IDAuOTUsIHR5cGUgPSAiV2FsZCIpICU+JSAKICBleHAoKQpgYGAKCmBgYHtyLCBldmFsPUZBTFNFfQpkZjIgPC0gZGF0YS5mcmFtZShDb2VmZmljaWVudHM9IGMoIkludGVyY2VwdCIsICJQb3ZlcnR5IiwgIlBoeXNBY3RpdmVZZXMiLCAiUG92ZXJ0eTpQaHlzQWN0aXZlWWVzIiksCiAgICAgICAgICAgICAgICAgIExvd2VyX0JvdW5kID0gYygiMC42NCIsICIwLjY4IiwgIjAuNDAiLCAiMS4wNiIpLCBVcHBlcl9Cb3VuZCA9IGMoIjAuODgiLCAiMC43NiIsICIwLjY0IiwgIjEuMjQiKSkKCiMgT3V0cHV0IHRoZSB0YWJsZSB1c2luZyBrYWJsZSgpCmtuaXRyOjprYWJsZShkZjIsIGFsaWduID0gYygibCIsICJjIiksIGNhcHRpb24gPSAiOTUgJSBDb25maWRlbmNlIEludGVydmFscyIpCmBgYAoKYGBge3IsZXZhbD1GQUxTRX0KdGhyZXNob2xkIDwtIDAuMjAKCiMgQm94cGxvdHMgV2l0aG91dCBUaHJlc2hvbGQ6Cm1vZCAlPiUKICBhdWdtZW50KHR5cGUucHJlZGljdCA9ICdyZXNwb25zZScpICU+JSAjIyBnZXQgcHJlZGljdGVkIHByb2JhYmlsaXRpZXMgZnJvbSBtb2RlbAogIGdncGxvdChhZXMoeSA9IC5maXR0ZWQsIHggPSBmYWN0b3IoRGVwcmVzc2VkKSkpICsgIyMgY29tcGFyZSBwcmVkaWN0ZWQgcHJvYmFiaWxpdGVzIHRvIGFjdHVhbCBvdXRjb21lCiAgZ2VvbV9ib3hwbG90KCkgICsKICBnZ3RpdGxlKCdQcmVkaWN0aW9ucyBmcm9tIExvZ2lzdGljIE1vZGVsJykgKwogIHhsYWIoIkFjdHVhbCBPdXRjb21lICgwID0gTm90IERlcHJlc3NlZCwgMSA9IERlcHJlc3NlZCkiKSArCnlsYWIoIlByZWRpY3RlZCBQcm9iYWJpbGl0eSBvZiB0aGUgT3V0Y29tZSBEZXByZXNzZWQiKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKYGBge3IsZXZhbD1GQUxTRX0KIyBCb3hwbG90cyBXaXRoIHRocmVzaG9sZDoKbW9kICU+JQogIGF1Z21lbnQodHlwZS5wcmVkaWN0ID0gJ3Jlc3BvbnNlJykgJT4lICMjIGdldCBwcmVkaWN0ZWQgcHJvYmFiaWxpdGllcyBmcm9tIG1vZGVsCiAgZ2dwbG90KGFlcyh5ID0gLmZpdHRlZCwgeCA9IGZhY3RvcihEZXByZXNzZWQpKSkgKyAjIyBjb21wYXJlIHByZWRpY3RlZCBwcm9iYWJpbGl0ZXMgdG8gYWN0dWFsIG91dGNvbWUKICBnZW9tX2JveHBsb3QoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiNGRkI0QjQiLCAiI0RBRkZFQSIpKSArCiAgZ2d0aXRsZSgnUHJlZGljdGlvbnMgZnJvbSBMb2dpc3RpYyBNb2RlbCcpICsKICBsYWJzKHN1YnRpdGxlID0gIlRoZSBSZWQgTGluZSBSZXByZXNlbnRzIHRoZSBTZWxlY3RlZCBUaHJlc2hvbGQgb2YgMC4yMCIpICsKICB4bGFiKCJBY3R1YWwgT3V0Y29tZSAoMCA9IE5vdCBEZXByZXNzZWQsIDEgPSBEZXByZXNzZWQpIikgKwp5bGFiKCJQcmVkaWN0ZWQgUHJvYmFiaWxpdHkgb2YgdGhlIE91dGNvbWUgYERlcHJlc3NlZGAiKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gdGhyZXNob2xkLCBjb2xvciA9ICdyZWQnLCBsaW5ldHlwZSA9IDIpICArCiAgdGhlbWVfbWluaW1hbCgpIAoKYGBgCgpgYGB7cixldmFsPUZBTFNFfQojIGdldCBiaW5hcnkgcHJlZGljdGlvbnMgZm9yIG1vZDEKdGhyZXNob2xkIDwtIDAuMjAKbW9kICU+JQogIGF1Z21lbnQodHlwZS5wcmVkaWN0ID0gJ3Jlc3BvbnNlJykgJT4lICMjIGdldCBwcmVkaWN0ZWQgcHJvYmFiaWxpdHkgb2YgY2FsbGJhY2sKICBtdXRhdGUocHJlZGljdERlcHJlc3NlZCA9IC5maXR0ZWQgPj0gdGhyZXNob2xkKSAlPiUgIyMgcHJlZGljdCBjYWxsYmFjayBpZiBwcm9iYWJpbGl0eSBiaWdnZXIgdGhhbiB0aHJlc2hvbGQKICBjb3VudChEZXByZXNzZWQsIHByZWRpY3REZXByZXNzZWQpCmBgYAoKYGBge3IsZXZhbD1GQUxTRX0KIyBDcmVhdGUgYSBkYXRhIGZyYW1lIHdpdGggdGhlIGJpbmFyeSBwcmVkaWN0aW9uczogCmRmIDwtIGRhdGEuZnJhbWUoTWVhc3VyZXM9IGMoIkFjY3VyYWN5IiwgIlNlbnNpdGl2aXR5IiwgIlNwZWNpZmljaXR5IiwgIkZhbHNlIE5lZ2F0aXZlIFJhdGUgKEZOUikiLCAiRmFsc2UgUG9zaXRpdmUgUmF0ZSAoRlBSKSIpLAogICAgICAgICAgICAgICAgIFZhbHVlcyA9IGMoIjU5LjA1ICUiLCAiNjIuNzcgJSIsICI1OC4wNyAlIiwgIjM3LjIzICUiLCAiNDEuOTMgJSIpKQpgYGAKCmBgYHtyLGV2YWw9RkFMU0V9CiMgT3V0cHV0IHRoZSB0YWJsZSB1c2luZyBrYWJsZSgpCmtuaXRyOjprYWJsZShkZiwgYWxpZ24gPSBjKCJsIiwgImMiKSwgY2FwdGlvbiA9ICJRdWFsaXR5IE1ldHJpY3MiKQpgYGA=