Summary
I decided to use 5 clusters.
Cluster 1 comprises of the countries with the most total cases and deaths per capita. Despite this, it is by far the group that has had the best vaccination policy. Some of the countries that belong to this group are: Italy, United States, Sweden, and Chile.
Cluster 2 is quite diverse in its composition. There are countries with low mortality and cases, such as New Zealand and Laos, and others with many cases and deaths, such as Bolivia and Andorra. What is particular about this group is that the vaccination and testing policy has not been very good.
Cluster 3 contains countries with many cases and total deaths, although not as many as cluster 1. However, it is the group that as of September 2021 has the most cases and deaths per capita. When it comes to testing it has been by far the worst of all clusters. It is also the group with the most stringent mobility restrictions. It contains countries such as Peru, Mexico, Brazil and the Philippines.
Cluster 4 consists of countries that had very few COVID cases and low mortality. It is composed mainly of African countries, although there are also countries like Haiti, Afghanistan and Syria. This is also the group with the lowest vaccination rate.
Cluster 5 include the countries that have been the least affected by COVID. Most the countries of Oceania are in this group: Vanuatu, Palau, Solomon Islands, Micronesia, etc. As well as, other small countries such as Bhutan, The Vatican and Hong Kong. Furthermore, they are the group with highest vaccionation rate during the month of September 2021.
From the Principal Component Analysis (PCA) I found that PC1 explains 48.29% of the variation in available data, while PC2 explains 16.32%.
The countries that have a high score in PC1 are those that have had a lot of infections, deaths, hospitalizations and a good vaccination policy. But at the same time they have also had very few tests per case. These countries include: Israel, the United States, the United Kingdom, and Serbia.
The countries that have a high score in PC2 are those that have had few infections and deaths, and a good vaccination policy. They have also had a very low positive rate and many tests per case. Examples of these countries are Hong-Kong, Iceland, Palau, Bhutan, Samoa.
Intro
Some time ago, I came across the data from ourworldindata.org for COVID 19. I decided to download it and use it to do some analysis. My goal is to analyze the current (September 2021) situation of COVID in the world. With that objective, I am going to use clustering in order to catalog the countries into different groups. The data can be downloaded from here: https://ourworldindata.org/coronavirus. For the analysis I will use the data between September 1 and September 27, 2021. Additionally, I will use Principal Component Analysis (PCA), to analyze the data.
Variables
Here are the variable that I’ll use in this analysis. The original database has more variables.Which can be read here.
| Variable |
Description |
| total_cases_per_million |
Total confirmed cases of COVID-19 per 1,000,000 people |
| new_cases_per_million |
New confirmed cases of COVID-19 per 1,000,000 people |
| total_deaths_per_million |
Total deaths attributed to COVID-19 per 1,000,000 people |
| new_deaths_per_million |
New deaths attributed to COVID-19 per 1,000,000 people |
| icu_patients_per_million |
Number of COVID-19 patients in intensive care units (ICUs) on a given day per 1,000,000 people |
| weekly_hosp_admissions_per_million |
Number of COVID-19 patients newly admitted to hospitals in a given week per 1,000,000 people |
| stringency_index |
Government Response Stringency Index: composite measure based on 9 response indicators including school closures, workplace closures, and travel bans, rescaled to a value from 0 to 100 (100 = strictest response) |
| reproduction_rate |
Real-time estimate of the effective reproduction rate (R) of COVID-19. See https://github.com/crondonm/TrackingR/tree/main/Estimates-Database |
| new_tests_per_thousand |
New tests for COVID-19 per 1,000 people |
| positive_rate |
The share of COVID-19 tests that are positive, given as a rolling 7-day average (this is the inverse of tests_per_case) |
| tests_per_case |
Tests conducted per new confirmed case of COVID-19, given as a rolling 7-day average (this is the inverse of positive_rate) |
| total_vaccinations_per_hundred |
Total number of COVID-19 vaccination doses administered per 100 people in the total population |
| people_vaccinated_per_hundred |
Total number of people who received at least one vaccine dose per 100 people in the total population |
| people_fully_vaccinated_per_hundred |
Total number of people who received all doses prescribed by the vaccination protocol per 100 people in the total population |
| total_boosters_per_hundred |
Total number of COVID-19 vaccination booster doses administered per 100 people in the total population |
| new_vaccinations_per_million |
New COVID-19 vaccination doses administered per 1,000,000 people in the total population |
From the original base I decided to keep all the variables that were controlled for the population per country. Furthermore, due to the fact that they had many missing values or that the data was not very up-to-date, I did not keep the variables related to excess mortality.
Variable Treatment
For the variables new_cases_per_million, new_vaccionations_per_million, new_test_per-thousand, new_cases_per_million and new_deaths_per_million I added all the values reported in September 2021. On the other hand, for stringency_index, tests_per_case, icu_patients_per_million, weekly_hosp_admissions_per_million and reproduction_rate I calculated the mean of the values for September 2021. For the rest of the variables, the maximum value reported in the data was used.
The data contained many missing values; therefore, I decided to impute the variables that had less than 10 missing values with the median. For the rest of the variables, the imputation was made in two steps. First I used random forest, with 100 trees, to know which variables were related to each other. Then, I used those variables to impute the missing data with the k-nearest neighbors (knn) method, with k = 10. Finally, a logarithmic transformation was applied to the data and then variables were scaled.
Exploratory Analysis
I’m going to start by plotting a correlation matrix of the variables.

If one analyzes this correlation matrix, the number of total cases is related to the number of total deaths, hospitalizations, ICU patients and to a lesser extent to the number of tests, and people vaccinated. On the other hand, the number of deaths per capita is also connected to the number of hospitalizations and ICU patients. To a lesser extent it is linked to the positivity rate and is negatively associated with the number of test per case.
The number of ICU patients is obviously related to the number of hospital admissions. However, the coefficient is also high for the total tests per capita and for the variables linked to vaccination, which is intriguing, since one would expect that countries with more vaccinations would have fewer ICU patients. Finally, hospitalizations are only connected to the number of total tests.
Other things that can be noticed is that the tests per case have a negative relationship with the positive rate. All variables associated to vaccination are related to each other. Lastly, I find it interesting that the stringency index does not have any kind of relationship with any variable. Let’s now look at the distribution of the variables with a boxplot.

What this plot shows is that many variables have outliers. Another interesting thing is the distribution of the variable total_booster_per_hundred. Most of the values are 0 since there are very few countries that are using booster doses.
Analysis
I used two methods to decide the number of clusters. Let’s begin with the silhouette analysis.

Looking at the results it seems that the optimal number of clusters is 2. However, I think that separating the world in two is perhaps not a good idea. Now we are going to do an elbow analysis.

I don’t see a major “elbow” but I’d say that k = 5 looks pretty reasonable.
Using these 2 axes (cases and total deaths per million) it seems that the clusters are not clearly separated. However, it seems that 1 and 3 belong to countries more affected by covid than 4 and 5. Another way to visualize the clusters in a way that is clearer is by using the Principal Component Analysis:
In this plot the clusters are clearly separated. PC1 explains 48.29% of the variation in our data, while PC2 explains 16.32%. To better understand what each dimension means, let’s look at a graph that demostrates the important variables for each one.

The countries that have a high PC1 score are those that have had many cases, deaths, hospitalizations and, at the same time, an effective vaccination policy. But, in addition, they have also had very few tests per case. These countries include: Israel, United States, United Kingdom, and Serbia.

The countries that have a high score in PC2 are those that have had the fewest cases and deaths. They have also had a very low positive rate, which may be associated with the fact that these countries have many tests per case. Finally, like the countries that have high PC1 scores, they have also had a good vaccination policy. Examples of these countries are Hong Kong, Iceland, Palau, Bhutan, and Samoa.
Clusters Characterization
Let’s look at the variable values per cluster to better understand them.
Cluster 1 comprises the countries that have had the most total cases and deaths per capita throughout the pandemic. During September 2021, they have the highest number of ICU patients and tests per population. Furthermore, they are by far the group with the best vaccination policy, almost all the countries where booster doses have been administered are contained in this cluster. However, the same does not happen with vaccination in September 2021, the only group that does it worse than them is cluster number 4. One reason may be that the countries of cluster 1, having already vaccinated much of their population, have a smaller margin to increase the number of vaccines per inhabitant. Some of the countries in this group are: Italy, United States, Sweden, Chile, etc.
Cluster 2 is quite diverse in its composition. There are countries with low mortality and cases, such as New Zealand and Laos, and others with many cases and deaths, such as Bolivia and Andorra. It is the second group with fewer tests per case, total tests per thousand inhabitants and vaccinations per inhabitants. Furthermore, during September 2021 they were the second group with the most stringent mobility restrictions.
Cluster 3 has countries with many cases and total deaths, although not as many as those of cluster 1. However, they are the group that currently (September 2021) has more cases and deaths per capita. Which causes this to be the cluster with the highest reproduction rate and hospitalizations per inhabitant. In addition, it has been by far the worst of all, in tests per case. Finally, it is the group with the most stringent mobility restrictions. It contains countries such as Peru, Mexico, Brazil or the Philippines.
Cluster 4 consists of countries that had very few infections and low mortality. Most of the African countries are in this cluster although there are also countries like Haiti, Afghanistan and Syria. Even if they are not the cluster with the fewest cases and deaths, they are the group with the fewest icu patients and weekly hospital admission per million during the month of September 2021. They are the ones with the fewest tests per thousand and vaccinated people per population. It may be due in large part to the low level of development of these countries. In any case, we must be aware that these countries may not have the necessary infrastructure to be able to obtain reliable numbers. Even so, last year there were people surprised by the low mortality of covid in Africa, as can be seen in this article: https://www.bbc.com/news/world-africa-54418613
As can be seen in the graph below, the mortality of the virus in Africa has been lower than in the world throughout the pandemic. When we make the comparison with the European Union, the differences are gigantic, which surprises us even more due to the differences in development that exist in these areas.
Cluster number 5 consists of the countries that have been the least affected by COVID. Here are most of the countries of Oceania: Vanuatu, Palau, Solomon Islands, Micronesia, etc. In addition to other small countries such as Bhutan, The Vatican and Hong Kong. There are two countries that stand out in this group, since they are very different from the rest: China and Taiwan. This is not the group with the least amount of hospitalizations and ICU patients, since they are marginally surpassed by the countries of cluster 4. Furthermore, during the month of September 2021 they were the cluster with the most vaccinated people per million inhabitants. Finally, they are the second group with the the least stringent mobility restrictions after cluster 4.
Final Thoughts
It must considered that I choose 5 clusters in a totally arbitrary way. It could have been more or less. Therefore, there is no reason to think that the 5 clusters are something definitive that cannot be changed or questioned. Having said this, there are 3 surprises that I came across during this analysis: First, noticing the little impact that COVID has had in Africa, the few cases and deaths in China and seeing how many high-income countries were greatly affected, being the only exceptions: Australia, New Zealand and South Korea. On the first point, the explanations can be varied, from the median age of the population or the low population density in Africa, in this link some hypotheses are explored.
About the cases and deaths in China, there are also many theories. One is that since the virus happened so early in that country they didn’t have it identified or named at the beginning, and there was no way of testing for it. So there’s a huge chance that the cases and deaths are way higher. Another explanation is that the political response was very good in China, especially the strict lockdowns. About the last point, I think it is interesting to analyze why certain developed countries had fewer cases and deaths. Is it due to any public policy or demographic factor?
Clustering is generally used for customer segmentation, targeted marketing or recommendation systems. I think that using it to find patterns in a group of territorial units can be very important for public policy, since it can help to plan different types of interventions and policies depending on the characteristics that each cluster has.
LS0tDQp0aXRsZTogIkNsdXN0ZXJzIGluIHRoZSBJbXBhY3QgYW5kIFJlc3BvbnNlIG9mIHRoZSBDT1ZJRC0xOSBQYW5kZW1pYyINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQo8c3R5bGU+DQoNCmJvZHl7DQogdGV4dC1hbGlnbjoganVzdGlmeTsNCn0NCg0KPC9zdHlsZT4NCg0KIyMgU3VtbWFyeQ0KDQoxKSBJIGRlY2lkZWQgdG8gdXNlIDUgY2x1c3RlcnMuDQoNCjIpIENsdXN0ZXIgMSBjb21wcmlzZXMgb2YgdGhlIGNvdW50cmllcyB3aXRoIHRoZSBtb3N0IHRvdGFsIGNhc2VzIGFuZCBkZWF0aHMgcGVyIGNhcGl0YS4gRGVzcGl0ZSB0aGlzLCBpdCBpcyBieSBmYXIgdGhlIGdyb3VwIHRoYXQgaGFzIGhhZCB0aGUgYmVzdCB2YWNjaW5hdGlvbiBwb2xpY3kuIFNvbWUgb2YgdGhlIGNvdW50cmllcyB0aGF0IGJlbG9uZyB0byB0aGlzIGdyb3VwIGFyZTogSXRhbHksIFVuaXRlZCBTdGF0ZXMsIFN3ZWRlbiwgYW5kICBDaGlsZS4NCg0KMykgQ2x1c3RlciAyIGlzIHF1aXRlIGRpdmVyc2UgaW4gaXRzIGNvbXBvc2l0aW9uLiBUaGVyZSBhcmUgY291bnRyaWVzIHdpdGggbG93IG1vcnRhbGl0eSBhbmQgY2FzZXMsIHN1Y2ggYXMgTmV3IFplYWxhbmQgYW5kIExhb3MsIGFuZCBvdGhlcnMgd2l0aCBtYW55IGNhc2VzIGFuZCBkZWF0aHMsIHN1Y2ggYXMgQm9saXZpYSBhbmQgQW5kb3JyYS4gV2hhdCBpcyBwYXJ0aWN1bGFyIGFib3V0IHRoaXMgZ3JvdXAgaXMgdGhhdCB0aGUgdmFjY2luYXRpb24gYW5kIHRlc3RpbmcgcG9saWN5IGhhcyBub3QgYmVlbiB2ZXJ5IGdvb2QuDQoNCjQpIENsdXN0ZXIgMyBjb250YWlucyBjb3VudHJpZXMgd2l0aCBtYW55IGNhc2VzIGFuZCB0b3RhbCBkZWF0aHMsIGFsdGhvdWdoIG5vdCBhcyBtYW55IGFzIGNsdXN0ZXIgMS4gSG93ZXZlciwgaXQgaXMgdGhlIGdyb3VwIHRoYXQgYXMgb2YgU2VwdGVtYmVyIDIwMjEgaGFzIHRoZSBtb3N0IGNhc2VzIGFuZCBkZWF0aHMgcGVyIGNhcGl0YS4gV2hlbiBpdCBjb21lcyB0byB0ZXN0aW5nIGl0IGhhcyBiZWVuIGJ5IGZhciB0aGUgd29yc3Qgb2YgYWxsIGNsdXN0ZXJzLiBJdCBpcyBhbHNvIHRoZSBncm91cCB3aXRoIHRoZSBtb3N0IHN0cmluZ2VudCBtb2JpbGl0eSByZXN0cmljdGlvbnMuIEl0IGNvbnRhaW5zIGNvdW50cmllcyBzdWNoIGFzIFBlcnUsIE1leGljbywgQnJhemlsIGFuZCB0aGUgUGhpbGlwcGluZXMuDQoNCjUpIENsdXN0ZXIgNCBjb25zaXN0cyBvZiBjb3VudHJpZXMgdGhhdCBoYWQgdmVyeSBmZXcgQ09WSUQgY2FzZXMgYW5kIGxvdyBtb3J0YWxpdHkuIEl0IGlzIGNvbXBvc2VkIG1haW5seSBvZiBBZnJpY2FuIGNvdW50cmllcywgYWx0aG91Z2ggdGhlcmUgYXJlIGFsc28gY291bnRyaWVzIGxpa2UgSGFpdGksIEFmZ2hhbmlzdGFuIGFuZCBTeXJpYS4gVGhpcyBpcyBhbHNvIHRoZSBncm91cCB3aXRoIHRoZSBsb3dlc3QgdmFjY2luYXRpb24gcmF0ZS4NCg0KNikgQ2x1c3RlciA1IGluY2x1ZGUgdGhlIGNvdW50cmllcyB0aGF0IGhhdmUgYmVlbiB0aGUgbGVhc3QgYWZmZWN0ZWQgYnkgQ09WSUQuIE1vc3QgdGhlIGNvdW50cmllcyBvZiBPY2VhbmlhIGFyZSBpbiB0aGlzIGdyb3VwOiBWYW51YXR1LCBQYWxhdSwgU29sb21vbiBJc2xhbmRzLCBNaWNyb25lc2lhLCBldGMuIEFzIHdlbGwgYXMsIG90aGVyIHNtYWxsIGNvdW50cmllcyBzdWNoIGFzIEJodXRhbiwgVGhlIFZhdGljYW4gYW5kIEhvbmcgS29uZy4gRnVydGhlcm1vcmUsIHRoZXkgYXJlIHRoZSBncm91cCB3aXRoIGhpZ2hlc3QgdmFjY2lvbmF0aW9uIHJhdGUgZHVyaW5nIHRoZSBtb250aCBvZiBTZXB0ZW1iZXIgMjAyMS4NCg0KNykgRnJvbSB0aGUgUHJpbmNpcGFsIENvbXBvbmVudCBBbmFseXNpcyAoUENBKSBJIGZvdW5kIHRoYXQgUEMxIGV4cGxhaW5zIDQ4LjI5JSBvZiB0aGUgdmFyaWF0aW9uIGluIGF2YWlsYWJsZSBkYXRhLCB3aGlsZSBQQzIgZXhwbGFpbnMgMTYuMzIlLiANCg0KOCkgVGhlIGNvdW50cmllcyB0aGF0IGhhdmUgYSBoaWdoIHNjb3JlIGluIFBDMSBhcmUgdGhvc2UgdGhhdCBoYXZlIGhhZCBhIGxvdCBvZiBpbmZlY3Rpb25zLCBkZWF0aHMsIGhvc3BpdGFsaXphdGlvbnMgYW5kIGEgZ29vZCB2YWNjaW5hdGlvbiBwb2xpY3kuIEJ1dCBhdCB0aGUgc2FtZSB0aW1lIHRoZXkgaGF2ZSBhbHNvIGhhZCB2ZXJ5IGZldyB0ZXN0cyBwZXIgY2FzZS4gVGhlc2UgY291bnRyaWVzIGluY2x1ZGU6IElzcmFlbCwgdGhlIFVuaXRlZCBTdGF0ZXMsIHRoZSBVbml0ZWQgS2luZ2RvbSwgYW5kIFNlcmJpYS4NCg0KOSkgVGhlIGNvdW50cmllcyB0aGF0IGhhdmUgYSBoaWdoIHNjb3JlIGluIFBDMiBhcmUgdGhvc2UgdGhhdCBoYXZlIGhhZCBmZXcgaW5mZWN0aW9ucyBhbmQgZGVhdGhzLCBhbmQgYSBnb29kIHZhY2NpbmF0aW9uIHBvbGljeS4gVGhleSBoYXZlIGFsc28gaGFkIGEgdmVyeSBsb3cgcG9zaXRpdmUgcmF0ZSBhbmQgbWFueSB0ZXN0cyBwZXIgY2FzZS4gRXhhbXBsZXMgb2YgdGhlc2UgY291bnRyaWVzIGFyZSBIb25nLUtvbmcsIEljZWxhbmQsIFBhbGF1LCBCaHV0YW4sIFNhbW9hLg0KDQoNCiMjIEludHJvDQoNClNvbWUgdGltZSBhZ28sIEkgY2FtZSBhY3Jvc3MgdGhlIGRhdGEgZnJvbSAqKm91cndvcmxkaW5kYXRhLm9yZyoqIGZvciBDT1ZJRCAxOS4gSSBkZWNpZGVkIHRvIGRvd25sb2FkIGl0IGFuZCB1c2UgaXQgdG8gZG8gc29tZSBhbmFseXNpcy4gTXkgZ29hbCBpcyB0byBhbmFseXplIHRoZSBjdXJyZW50IChTZXB0ZW1iZXIgMjAyMSkgc2l0dWF0aW9uIG9mIENPVklEIGluIHRoZSB3b3JsZC4gV2l0aCB0aGF0IG9iamVjdGl2ZSwgSSBhbSBnb2luZyB0byB1c2UgY2x1c3RlcmluZyBpbiBvcmRlciB0byBjYXRhbG9nIHRoZSBjb3VudHJpZXMgaW50byBkaWZmZXJlbnQgZ3JvdXBzLiBUaGUgZGF0YSBjYW4gYmUgZG93bmxvYWRlZCBmcm9tIGhlcmU6IGh0dHBzOi8vb3Vyd29ybGRpbmRhdGEub3JnL2Nvcm9uYXZpcnVzLiBGb3IgdGhlIGFuYWx5c2lzIEkgd2lsbCB1c2UgdGhlIGRhdGEgYmV0d2VlbiBTZXB0ZW1iZXIgMSBhbmQgU2VwdGVtYmVyIDI3LCAyMDIxLiBBZGRpdGlvbmFsbHksIEkgd2lsbCB1c2UgUHJpbmNpcGFsIENvbXBvbmVudCBBbmFseXNpcyAoUENBKSwgdG8gYW5hbHl6ZSB0aGUgZGF0YS4NCg0KIyMgVmFyaWFibGVzDQoNCkhlcmUgYXJlIHRoZSB2YXJpYWJsZSB0aGF0IEknbGwgdXNlIGluIHRoaXMgYW5hbHlzaXMuIFRoZSBvcmlnaW5hbCBkYXRhYmFzZSBoYXMgbW9yZSB2YXJpYWJsZXMuV2hpY2ggY2FuIGJlIHJlYWQgW2hlcmVdKGh0dHBzOi8vZ2l0aHViLmNvbS9vd2lkL2NvdmlkLTE5LWRhdGEvdHJlZS9tYXN0ZXIvcHVibGljL2RhdGEpLiANCg0KDQpgYGB7cixlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRX0NCmxpYnJhcnkoa2FibGVFeHRyYSkNCg0KbGlicmFyeShrbml0cikNCg0KDQp4PC10aWJibGUoDQogICJWYXJpYWJsZSIgPSBjKCJ0b3RhbF9jYXNlc19wZXJfbWlsbGlvbiIsIm5ld19jYXNlc19wZXJfbWlsbGlvbiIsInRvdGFsX2RlYXRoc19wZXJfbWlsbGlvbiIsIm5ld19kZWF0aHNfcGVyX21pbGxpb24iLCJpY3VfcGF0aWVudHNfcGVyX21pbGxpb24iLCJ3ZWVrbHlfaG9zcF9hZG1pc3Npb25zX3Blcl9taWxsaW9uIiwic3RyaW5nZW5jeV9pbmRleCIsInJlcHJvZHVjdGlvbl9yYXRlIiwibmV3X3Rlc3RzX3Blcl90aG91c2FuZCIsInBvc2l0aXZlX3JhdGUiLCJ0ZXN0c19wZXJfY2FzZSIsInRvdGFsX3ZhY2NpbmF0aW9uc19wZXJfaHVuZHJlZCIsInBlb3BsZV92YWNjaW5hdGVkX3Blcl9odW5kcmVkIiwicGVvcGxlX2Z1bGx5X3ZhY2NpbmF0ZWRfcGVyX2h1bmRyZWQiLCJ0b3RhbF9ib29zdGVyc19wZXJfaHVuZHJlZCIsIm5ld192YWNjaW5hdGlvbnNfcGVyX21pbGxpb24iKSwgDQogIA0KICAiRGVzY3JpcHRpb24iID0gYygiVG90YWwgY29uZmlybWVkIGNhc2VzIG9mIENPVklELTE5IHBlciAxLDAwMCwwMDAgcGVvcGxlIiwiTmV3IGNvbmZpcm1lZCBjYXNlcyBvZiBDT1ZJRC0xOSBwZXIgMSwwMDAsMDAwIHBlb3BsZSIsIlRvdGFsIGRlYXRocyBhdHRyaWJ1dGVkIHRvIENPVklELTE5IHBlciAxLDAwMCwwMDAgcGVvcGxlIiwiTmV3IGRlYXRocyBhdHRyaWJ1dGVkIHRvIENPVklELTE5IHBlciAxLDAwMCwwMDAgcGVvcGxlIiwiTnVtYmVyIG9mIENPVklELTE5IHBhdGllbnRzIGluIGludGVuc2l2ZSBjYXJlIHVuaXRzIChJQ1VzKSBvbiBhIGdpdmVuIGRheSBwZXIgMSwwMDAsMDAwIHBlb3BsZSIsIk51bWJlciBvZiBDT1ZJRC0xOSBwYXRpZW50cyBuZXdseSBhZG1pdHRlZCB0byBob3NwaXRhbHMgaW4gYSBnaXZlbiB3ZWVrIHBlciAxLDAwMCwwMDAgcGVvcGxlIiwiR292ZXJubWVudCBSZXNwb25zZSBTdHJpbmdlbmN5IEluZGV4OiBjb21wb3NpdGUgbWVhc3VyZSBiYXNlZCBvbiA5IHJlc3BvbnNlIGluZGljYXRvcnMgaW5jbHVkaW5nIHNjaG9vbCBjbG9zdXJlcywgd29ya3BsYWNlIGNsb3N1cmVzLCBhbmQgdHJhdmVsIGJhbnMsIHJlc2NhbGVkIHRvIGEgdmFsdWUgZnJvbSAwIHRvIDEwMCAoMTAwID0gc3RyaWN0ZXN0IHJlc3BvbnNlKSIsIlJlYWwtdGltZSBlc3RpbWF0ZSBvZiB0aGUgZWZmZWN0aXZlIHJlcHJvZHVjdGlvbiByYXRlIChSKSBvZiBDT1ZJRC0xOS4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jcm9uZG9ubS9UcmFja2luZ1IvdHJlZS9tYWluL0VzdGltYXRlcy1EYXRhYmFzZSIsIk5ldyB0ZXN0cyBmb3IgQ09WSUQtMTkgcGVyIDEsMDAwIHBlb3BsZSIsIlRoZSBzaGFyZSBvZiBDT1ZJRC0xOSB0ZXN0cyB0aGF0IGFyZSBwb3NpdGl2ZSwgZ2l2ZW4gYXMgYSByb2xsaW5nIDctZGF5IGF2ZXJhZ2UgKHRoaXMgaXMgdGhlIGludmVyc2Ugb2YgdGVzdHNfcGVyX2Nhc2UpIiwiVGVzdHMgY29uZHVjdGVkIHBlciBuZXcgY29uZmlybWVkIGNhc2Ugb2YgQ09WSUQtMTksIGdpdmVuIGFzIGEgcm9sbGluZyA3LWRheSBhdmVyYWdlICh0aGlzIGlzIHRoZSBpbnZlcnNlIG9mIHBvc2l0aXZlX3JhdGUpIiwiVG90YWwgbnVtYmVyIG9mIENPVklELTE5IHZhY2NpbmF0aW9uIGRvc2VzIGFkbWluaXN0ZXJlZCBwZXIgMTAwIHBlb3BsZSBpbiB0aGUgdG90YWwgcG9wdWxhdGlvbiIsIglUb3RhbCBudW1iZXIgb2YgcGVvcGxlIHdobyByZWNlaXZlZCBhdCBsZWFzdCBvbmUgdmFjY2luZSBkb3NlIHBlciAxMDAgcGVvcGxlIGluIHRoZSB0b3RhbCBwb3B1bGF0aW9uIiwiVG90YWwgbnVtYmVyIG9mIHBlb3BsZSB3aG8gcmVjZWl2ZWQgYWxsIGRvc2VzIHByZXNjcmliZWQgYnkgdGhlIHZhY2NpbmF0aW9uIHByb3RvY29sIHBlciAxMDAgcGVvcGxlIGluIHRoZSB0b3RhbCBwb3B1bGF0aW9uIiwiVG90YWwgbnVtYmVyIG9mIENPVklELTE5IHZhY2NpbmF0aW9uIGJvb3N0ZXIgZG9zZXMgYWRtaW5pc3RlcmVkIHBlciAxMDAgcGVvcGxlIGluIHRoZSB0b3RhbCBwb3B1bGF0aW9uIiwiCU5ldyBDT1ZJRC0xOSB2YWNjaW5hdGlvbiBkb3NlcyBhZG1pbmlzdGVyZWQgcGVyIDEsMDAwLDAwMCBwZW9wbGUgaW4gdGhlIHRvdGFsIHBvcHVsYXRpb24iKQ0KKQ0KDQp4ICU+JSBrYmwoYWxpZ249ImxsIikgJT4lDQogIGthYmxlX3BhcGVyKCJob3ZlciIsIGZ1bGxfd2lkdGggPSBUKQ0KDQpgYGANCg0KRnJvbSB0aGUgb3JpZ2luYWwgYmFzZSBJIGRlY2lkZWQgdG8ga2VlcCBhbGwgdGhlIHZhcmlhYmxlcyB0aGF0IHdlcmUgY29udHJvbGxlZCBmb3IgdGhlIHBvcHVsYXRpb24gcGVyIGNvdW50cnkuIEZ1cnRoZXJtb3JlLCBkdWUgdG8gdGhlIGZhY3QgdGhhdCB0aGV5IGhhZCBtYW55IG1pc3NpbmcgdmFsdWVzIG9yIHRoYXQgdGhlIGRhdGEgd2FzIG5vdCB2ZXJ5IHVwLXRvLWRhdGUsIEkgZGlkIG5vdCBrZWVwIHRoZSB2YXJpYWJsZXMgcmVsYXRlZCB0byBleGNlc3MgbW9ydGFsaXR5Lg0KDQojIyBWYXJpYWJsZSBUcmVhdG1lbnQNCg0KRm9yIHRoZSB2YXJpYWJsZXMgYG5ld19jYXNlc19wZXJfbWlsbGlvbmAsIGBuZXdfdmFjY2lvbmF0aW9uc19wZXJfbWlsbGlvbmAsIGBuZXdfdGVzdF9wZXItdGhvdXNhbmRgLCBgbmV3X2Nhc2VzX3Blcl9taWxsaW9uYCBhbmQgYG5ld19kZWF0aHNfcGVyX21pbGxpb25gIEkgYWRkZWQgYWxsIHRoZSB2YWx1ZXMgcmVwb3J0ZWQgaW4gU2VwdGVtYmVyIDIwMjEuIE9uIHRoZSBvdGhlciBoYW5kLCBmb3IgYHN0cmluZ2VuY3lfaW5kZXhgLCBgdGVzdHNfcGVyX2Nhc2VgLCBgaWN1X3BhdGllbnRzX3Blcl9taWxsaW9uYCwgYHdlZWtseV9ob3NwX2FkbWlzc2lvbnNfcGVyX21pbGxpb25gIGFuZCBgcmVwcm9kdWN0aW9uX3JhdGVgIEkgY2FsY3VsYXRlZCB0aGUgbWVhbiBvZiB0aGUgdmFsdWVzIGZvciBTZXB0ZW1iZXIgMjAyMS4gRm9yIHRoZSByZXN0IG9mIHRoZSB2YXJpYWJsZXMsIHRoZSBtYXhpbXVtIHZhbHVlIHJlcG9ydGVkIGluIHRoZSBkYXRhIHdhcyB1c2VkLg0KDQpUaGUgZGF0YSBjb250YWluZWQgbWFueSBtaXNzaW5nIHZhbHVlczsgdGhlcmVmb3JlLCBJIGRlY2lkZWQgdG8gaW1wdXRlIHRoZSB2YXJpYWJsZXMgdGhhdCBoYWQgbGVzcyB0aGFuIDEwIG1pc3NpbmcgdmFsdWVzIHdpdGggdGhlIG1lZGlhbi4gRm9yIHRoZSByZXN0IG9mIHRoZSB2YXJpYWJsZXMsIHRoZSBpbXB1dGF0aW9uIHdhcyBtYWRlIGluIHR3byBzdGVwcy4gRmlyc3QgSSB1c2VkIHJhbmRvbSBmb3Jlc3QsIHdpdGggMTAwIHRyZWVzLCB0byBrbm93IHdoaWNoIHZhcmlhYmxlcyB3ZXJlIHJlbGF0ZWQgdG8gZWFjaCBvdGhlci4gVGhlbiwgSSB1c2VkIHRob3NlIHZhcmlhYmxlcyB0byBpbXB1dGUgdGhlIG1pc3NpbmcgZGF0YSB3aXRoIHRoZSAqKmstbmVhcmVzdCBuZWlnaGJvcnMqKiAoa25uKSBtZXRob2QsIHdpdGggayA9IDEwLiBGaW5hbGx5LCBhIGxvZ2FyaXRobWljIHRyYW5zZm9ybWF0aW9uIHdhcyBhcHBsaWVkIHRvIHRoZSBkYXRhIGFuZCB0aGVuIHZhcmlhYmxlcyB3ZXJlIHNjYWxlZC4NCg0KIyMgRXhwbG9yYXRvcnkgQW5hbHlzaXMNCg0KSSdtIGdvaW5nIHRvIHN0YXJ0IGJ5IHBsb3R0aW5nIGEgY29ycmVsYXRpb24gbWF0cml4IG9mIHRoZSB2YXJpYWJsZXMuIA0KDQpgYGB7cixlY2hvPUZBTFNFLHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsZmlnLndpZHRoPTEwLGZpZy5oZWlnaHQ9MTB9DQoNCmxpYnJhcnkoY29ycnBsb3QpDQoNCg0KY292aWQuMTwtbm9ybWFsaXplZCU+JSBzZWxlY3QodG90YWxfY2FzZXNfcGVyX21pbGxpb246dG90YWxfdGVzdHNfcGVyX3Rob3VzYW5kLG5ld192YWNjaW5hdGlvbnNfcGVyX21pbGxpb25zOnBlb3BsZV9mdWxseV92YWNjaW5hdGVkX3Blcl9odW5kcmVkLHRvdGFsX3Rlc3RzKSAlPiUgamFuaXRvcjo6Y2xlYW5fbmFtZXMoY2FzZT0ic25ha2UiKQ0KDQpNID0gY29yKGNvdmlkLjEpDQoNCmdnY29ycnBsb3QoTSwgdHlwZSA9ICd1cHBlcicsIG91dGxpbmUuY29sID0gIndoaXRlIiwNCiAgICAgICAgICBjb2xvcnMgPSBjKCIjMTY3OWExIiwgIndoaXRlIiwgIiNmODc2NmQiKSwNCiAgICAgICAgICBsYWIgPSBUUlVFKQ0KYGBgDQoNCklmIG9uZSBhbmFseXplcyB0aGlzIGNvcnJlbGF0aW9uIG1hdHJpeCwgdGhlIG51bWJlciBvZiB0b3RhbCBjYXNlcyBpcyByZWxhdGVkIHRvIHRoZSBudW1iZXIgb2YgdG90YWwgZGVhdGhzLCBob3NwaXRhbGl6YXRpb25zLCBJQ1UgcGF0aWVudHMgYW5kIHRvIGEgbGVzc2VyIGV4dGVudCB0byB0aGUgbnVtYmVyIG9mIHRlc3RzLCBhbmQgcGVvcGxlIHZhY2NpbmF0ZWQuIE9uIHRoZSBvdGhlciBoYW5kLCB0aGUgbnVtYmVyIG9mIGRlYXRocyBwZXIgY2FwaXRhIGlzIGFsc28gY29ubmVjdGVkIHRvIHRoZSBudW1iZXIgb2YgaG9zcGl0YWxpemF0aW9ucyBhbmQgSUNVIHBhdGllbnRzLiBUbyBhIGxlc3NlciBleHRlbnQgaXQgaXMgbGlua2VkIHRvIHRoZSBwb3NpdGl2aXR5IHJhdGUgYW5kIGlzIG5lZ2F0aXZlbHkgYXNzb2NpYXRlZCB3aXRoIHRoZSBudW1iZXIgb2YgdGVzdCBwZXIgY2FzZS4NCg0KVGhlIG51bWJlciBvZiBJQ1UgcGF0aWVudHMgaXMgb2J2aW91c2x5IHJlbGF0ZWQgdG8gdGhlIG51bWJlciBvZiBob3NwaXRhbCBhZG1pc3Npb25zLiBIb3dldmVyLCB0aGUgY29lZmZpY2llbnQgaXMgYWxzbyBoaWdoIGZvciB0aGUgdG90YWwgdGVzdHMgcGVyIGNhcGl0YSBhbmQgZm9yIHRoZSB2YXJpYWJsZXMgbGlua2VkIHRvIHZhY2NpbmF0aW9uLCB3aGljaCBpcyBpbnRyaWd1aW5nLCBzaW5jZSBvbmUgd291bGQgZXhwZWN0IHRoYXQgY291bnRyaWVzIHdpdGggbW9yZSB2YWNjaW5hdGlvbnMgd291bGQgaGF2ZSBmZXdlciBJQ1UgcGF0aWVudHMuIEZpbmFsbHksIGhvc3BpdGFsaXphdGlvbnMgYXJlIG9ubHkgY29ubmVjdGVkIHRvIHRoZSBudW1iZXIgb2YgdG90YWwgdGVzdHMuDQoNCk90aGVyIHRoaW5ncyB0aGF0IGNhbiBiZSBub3RpY2VkIGlzIHRoYXQgdGhlIHRlc3RzIHBlciBjYXNlIGhhdmUgYSBuZWdhdGl2ZSByZWxhdGlvbnNoaXAgd2l0aCB0aGUgcG9zaXRpdmUgcmF0ZS4gQWxsIHZhcmlhYmxlcyBhc3NvY2lhdGVkIHRvIHZhY2NpbmF0aW9uIGFyZSByZWxhdGVkIHRvIGVhY2ggb3RoZXIuIExhc3RseSwgSSBmaW5kIGl0IGludGVyZXN0aW5nIHRoYXQgdGhlIHN0cmluZ2VuY3kgaW5kZXggZG9lcyBub3QgaGF2ZSBhbnkga2luZCBvZiByZWxhdGlvbnNoaXAgd2l0aCBhbnkgdmFyaWFibGUuIExldCdzIG5vdyBsb29rIGF0IHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHZhcmlhYmxlcyB3aXRoIGEgYm94cGxvdC4NCg0KYGBge3IsZWNobz1GQUxTRSx3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KDQpub3JtYWxpemVkMTwtaW1wdXRlZCAlPiVhc190aWJibGUoKSAlPiUgDQogICAgIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIH5sb2coLisxKSkpDQoNCmNvdmlkLjI8LW5vcm1hbGl6ZWQxJT4lIHNlbGVjdCh0b3RhbF9jYXNlc19wZXJfbWlsbGlvbjp0b3RhbF90ZXN0c19wZXJfdGhvdXNhbmQsbmV3X3ZhY2NpbmF0aW9uc19wZXJfbWlsbGlvbnM6cGVvcGxlX2Z1bGx5X3ZhY2NpbmF0ZWRfcGVyX2h1bmRyZWQsLXRvdGFsX3Rlc3RzKSAlPiUgamFuaXRvcjo6Y2xlYW5fbmFtZXMoY2FzZT0ic25ha2UiKQ0KDQpjb3ZpZC4yICU+JQ0KICBnYXRoZXIoQXR0cmlidXRlcywgdmFsdWVzKSAlPiUNCiAgZ2dwbG90KGFlcyh4PXJlb3JkZXIoQXR0cmlidXRlcywgdmFsdWVzLCBGVU49bWVkaWFuKSwgeT12YWx1ZXMpKSArDQogIGdlb21fYm94cGxvdChzaG93LmxlZ2VuZD1GQUxTRSkgKw0KICBsYWJzKHRpdGxlPSJEYXRhIEJ5IENvdW50cnkiKSArDQogIHRoZW1lX2xpZ2h0KCkgKw0KICB0aGVtZShheGlzLnRpdGxlLnk9ZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpKSArDQogIGNvb3JkX2ZsaXAoKQ0KDQpgYGANCg0KV2hhdCB0aGlzIHBsb3Qgc2hvd3MgaXMgdGhhdCBtYW55IHZhcmlhYmxlcyBoYXZlIG91dGxpZXJzLiBBbm90aGVyIGludGVyZXN0aW5nIHRoaW5nIGlzIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHZhcmlhYmxlICoqdG90YWxfYm9vc3Rlcl9wZXJfaHVuZHJlZCoqLiBNb3N0IG9mIHRoZSB2YWx1ZXMgYXJlIDAgc2luY2UgdGhlcmUgYXJlIHZlcnkgZmV3IGNvdW50cmllcyB0aGF0IGFyZSB1c2luZyBib29zdGVyIGRvc2VzLg0KDQoNCiMjIEFuYWx5c2lzDQoNCkkgdXNlZCB0d28gbWV0aG9kcyB0byBkZWNpZGUgdGhlIG51bWJlciBvZiBjbHVzdGVycy4gTGV0J3MgYmVnaW4gd2l0aCB0aGUgc2lsaG91ZXR0ZSBhbmFseXNpcy4NCg0KYGBge3IsZWNobz1GQUxTRSx3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KZnZpel9uYmNsdXN0KGRhdGFfZGYsIEZVTiA9IGhjdXQsIG1ldGhvZCA9ICJzaWxob3VldHRlIikNCg0KYGBgDQoNCkxvb2tpbmcgYXQgdGhlIHJlc3VsdHMgaXQgc2VlbXMgdGhhdCB0aGUgb3B0aW1hbCBudW1iZXIgb2YgY2x1c3RlcnMgaXMgMi4gSG93ZXZlciwgSSB0aGluayB0aGF0IHNlcGFyYXRpbmcgdGhlIHdvcmxkIGluIHR3byBpcyBwZXJoYXBzIG5vdCBhIGdvb2QgaWRlYS4gTm93IHdlIGFyZSBnb2luZyB0byBkbyBhbiBlbGJvdyBhbmFseXNpcy4NCg0KYGBge3IsZWNobz1GQUxTRSx3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KDQpjb3ZpZC4yPC1ub3JtYWxpemVkICU+JSBzZWxlY3QobG9jYXRpb246dG90YWxfdGVzdHNfcGVyX3Rob3VzYW5kLG5ld192YWNjaW5hdGlvbnNfcGVyX21pbGxpb25zOnBlb3BsZV9mdWxseV92YWNjaW5hdGVkX3Blcl9odW5kcmVkLC10b3RhbF90ZXN0cykNCg0Ka2NsdXN0cyA8LQ0KICB0aWJibGUoayA9IDE6OSkgJT4lDQogIG11dGF0ZSgNCiAgICBrY2x1c3QgPSBtYXAoaywgfiBrbWVhbnMoc2VsZWN0KGNvdmlkLjIsIC1sb2NhdGlvbiksIC54KSksDQogICAgZ2xhbmNlZCA9IG1hcChrY2x1c3QsIGdsYW5jZSksDQogICkNCg0Ka2NsdXN0cyAlPiUNCiAgdW5uZXN0KGNvbHMgPSBjKGdsYW5jZWQpKSAlPiUNCiAgZ2dwbG90KGFlcyhrLCB0b3Qud2l0aGluc3MpKSArDQogIGdlb21fbGluZShhbHBoYSA9IDAuNSwgc2l6ZSA9IDEuMiwgY29sb3IgPSAibWlkbmlnaHRibHVlIikgKw0KICBnZW9tX3BvaW50KHNpemUgPSAyLCBjb2xvciA9ICJtaWRuaWdodGJsdWUiKSt0aGVtZV9saWdodCgpDQpgYGANCg0KDQpJIGRvbuKAmXQgc2VlIGEgbWFqb3Ig4oCcZWxib3figJ0gYnV0IEnigJlkIHNheSB0aGF0IGsgPSA1IGxvb2tzIHByZXR0eSByZWFzb25hYmxlLiANCg0KDQpgYGB7cixlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBmaWcud2lkdGg9Ny41LCBmaWcuaGVpZ2h0PTQuNSx3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShwbG90bHkpDQoNCg0Kc2V0LnNlZWQoMjM0NikNCg0KY292aWRfY2x1c3QgPC0ga21lYW5zKChjb3ZpZC4xKSwgY2VudGVycyA9IDUpDQoNCmNvdmlkLjMgPC0gdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oY292aWQuMSwgImxvY2F0aW9uIikNCg0KcCA8LSBhdWdtZW50KGNvdmlkX2NsdXN0LCBjb3ZpZC4zKSAlPiUgIG11dGF0ZSh0ZXh0ID0gcGFzdGUoIkNvdW50cnk6ICIsIGxvY2F0aW9uKSkgJT4lDQogIGdncGxvdChhZXModG90YWxfY2FzZXNfcGVyX21pbGxpb24sIHRvdGFsX2RlYXRoc19wZXJfbWlsbGlvbiwgY29sb3IgPSAuY2x1c3Rlcix0ZXh0PXRleHQpKSArDQogIGdlb21fcG9pbnQoKSt0aGVtZV9saWdodCgpK2dndGl0bGUoIkNsdXN0ZXJzIG9mIENvdW50cmllcyBieSBDT1ZJRCAxOSBDYXNlcyBhbmQgRGVhdGhzIikNCg0KZ2dwbG90bHkocCwgdG9vbHRpcD0idGV4dCIsIGhlaWdodCA9IDUwMCkNCmBgYA0KDQoNClVzaW5nIHRoZXNlIDIgYXhlcyAoY2FzZXMgYW5kIHRvdGFsIGRlYXRocyBwZXIgbWlsbGlvbikgaXQgc2VlbXMgdGhhdCB0aGUgY2x1c3RlcnMgYXJlIG5vdCBjbGVhcmx5IHNlcGFyYXRlZC4gSG93ZXZlciwgaXQgc2VlbXMgdGhhdCAxIGFuZCAzIGJlbG9uZyB0byBjb3VudHJpZXMgbW9yZSBhZmZlY3RlZCBieSBjb3ZpZCB0aGFuIDQgYW5kIDUuIEFub3RoZXIgd2F5IHRvIHZpc3VhbGl6ZSB0aGUgY2x1c3RlcnMgaW4gYSB3YXkgdGhhdCBpcyBjbGVhcmVyIGlzIGJ5IHVzaW5nIHRoZSBQcmluY2lwYWwgQ29tcG9uZW50IEFuYWx5c2lzOg0KDQpgYGB7cixlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBmaWcud2lkdGg9Ny41LCBmaWcuaGVpZ2h0PTQuNSx3YXJuaW5nPUZBTFNFfQ0KDQpwYzwtYXV0b3Bsb3Qoa21lYW5zKGNvdmlkLjEsIDUpLCBkYXRhID0gY292aWQuMSkNCg0KeTwtcGNbWzFdXQ0KDQp5LjEgPC0gdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oeSwgImxvY2F0aW9uIikNCg0KDQpwIDwtIGF1Z21lbnQoY292aWRfY2x1c3QsIHkuMSkgJT4lICBtdXRhdGUodGV4dCA9IHBhc3RlKCJDb3VudHJ5OiAiLCBsb2NhdGlvbikpICU+JQ0KICBnZ3Bsb3QoYWVzKFBDMSwgUEMyLCBjb2xvciA9IC5jbHVzdGVyLHRleHQ9dGV4dCkpICsNCiAgZ2VvbV9wb2ludCgpK3RoZW1lX2xpZ2h0KCkrZ2d0aXRsZSgiQ2x1c3RlciBvZiBDb3VudHJpZXMgVXNpbmcgUHJpbmNpcGFsIENvbXBvbmVudCBBbmFseXNpcyIpDQoNCmdncGxvdGx5KHAsIHRvb2x0aXA9InRleHQiLCBoZWlnaHQgPSA1MDApDQpgYGANCg0KSW4gdGhpcyBwbG90IHRoZSBjbHVzdGVycyBhcmUgY2xlYXJseSBzZXBhcmF0ZWQuIFBDMSBleHBsYWlucyA0OC4yOSUgb2YgdGhlIHZhcmlhdGlvbiBpbiBvdXIgZGF0YSwgd2hpbGUgUEMyIGV4cGxhaW5zIDE2LjMyJS4gVG8gYmV0dGVyIHVuZGVyc3RhbmQgd2hhdCBlYWNoIGRpbWVuc2lvbiBtZWFucywgbGV0J3MgbG9vayBhdCBhIGdyYXBoIHRoYXQgZGVtb3N0cmF0ZXMgdGhlIGltcG9ydGFudCB2YXJpYWJsZXMgZm9yIGVhY2ggb25lLg0KDQpgYGB7cixlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0V9DQpnZ3Bsb3QoZGF0YSA9IG1lbHRlZFttZWx0ZWQkVmFyMiA9PSAiUEMxIixdKSArdGhlbWVfbGlnaHQoKSsNCiAgICAgICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgDQogICAgICAgICAgICAgICBheGlzLnRleHQueD0gZWxlbWVudF90ZXh0KGFuZ2xlPTQ1LCBoanVzdCA9IDEpLCANCiAgICAgICAgICAgICAgIGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSkgKyANCiAgICAgICAgIHhsYWIoIkNPVklEIDE5IGluZGljYXRvciBtZWFzdXJlbWVudHMiKSArDQogICAgICAgICB5bGFiKCJSZWxhdGl2ZSBpbXBvcnRhbmNlIGluIHByaW5jaXBsZSBjb21wb25lbnQiKSArDQogICAgICAgICBnZ3RpdGxlKCJWYXJpYWJsZXMgaW4gUEMxIikgKw0KICAgICAgICAgZ2VvbV9iYXIoYWVzKHg9VmFyMSwgeT12YWx1ZSwgZmlsbD1WYXIxKSwgc3RhdD0iaWRlbnRpdHkiKQ0KYGBgDQoNClRoZSBjb3VudHJpZXMgdGhhdCBoYXZlIGEgaGlnaCBQQzEgc2NvcmUgYXJlIHRob3NlIHRoYXQgaGF2ZSBoYWQgbWFueSBjYXNlcywgZGVhdGhzLCBob3NwaXRhbGl6YXRpb25zIGFuZCwgYXQgdGhlIHNhbWUgdGltZSwgYW4gZWZmZWN0aXZlIHZhY2NpbmF0aW9uIHBvbGljeS4gQnV0LCBpbiBhZGRpdGlvbiwgdGhleSBoYXZlIGFsc28gaGFkIHZlcnkgZmV3IHRlc3RzIHBlciBjYXNlLiBUaGVzZSBjb3VudHJpZXMgaW5jbHVkZTogSXNyYWVsLCBVbml0ZWQgU3RhdGVzLCBVbml0ZWQgS2luZ2RvbSwgYW5kIFNlcmJpYS4NCg0KDQoNCmBgYHtyLGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRX0NCmdncGxvdChkYXRhID0gbWVsdGVkW21lbHRlZCRWYXIyID09ICJQQzIiLF0pICt0aGVtZV9saWdodCgpKw0KICAgICAgICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCANCiAgICAgICAgICAgICAgIGF4aXMudGV4dC54PSBlbGVtZW50X3RleHQoYW5nbGU9NDUsIGhqdXN0ID0gMSksIA0KICAgICAgICAgICAgICAgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpKSArIA0KICAgICAgICAgeGxhYigiQ09WSUQgMTkgaW5kaWNhdG9yIG1lYXN1cmVtZW50cyIpICsNCiAgICAgICAgIHlsYWIoIlJlbGF0aXZlIGltcG9ydGFuY2UgaW4gcHJpbmNpcGxlIGNvbXBvbmVudCIpICsNCiAgICAgICAgIGdndGl0bGUoIlZhcmlhYmxlcyBpbiBQQzIiKSArDQogICAgICAgICBnZW9tX2JhcihhZXMoeD1WYXIxLCB5PXZhbHVlLCBmaWxsPVZhcjEpLCBzdGF0PSJpZGVudGl0eSIpDQpgYGANCg0KVGhlIGNvdW50cmllcyB0aGF0IGhhdmUgYSBoaWdoIHNjb3JlIGluIFBDMiBhcmUgdGhvc2UgdGhhdCBoYXZlIGhhZCB0aGUgZmV3ZXN0IGNhc2VzIGFuZCBkZWF0aHMuIFRoZXkgaGF2ZSBhbHNvIGhhZCBhIHZlcnkgbG93IHBvc2l0aXZlIHJhdGUsIHdoaWNoIG1heSBiZSBhc3NvY2lhdGVkIHdpdGggdGhlIGZhY3QgdGhhdCB0aGVzZSBjb3VudHJpZXMgaGF2ZSBtYW55IHRlc3RzIHBlciBjYXNlLiBGaW5hbGx5LCBsaWtlIHRoZSBjb3VudHJpZXMgdGhhdCBoYXZlIGhpZ2ggUEMxIHNjb3JlcywgdGhleSBoYXZlIGFsc28gaGFkIGEgZ29vZCB2YWNjaW5hdGlvbiBwb2xpY3kuIEV4YW1wbGVzIG9mIHRoZXNlIGNvdW50cmllcyBhcmUgSG9uZyBLb25nLCBJY2VsYW5kLCBQYWxhdSwgQmh1dGFuLCBhbmQgU2Ftb2EuDQoNCiMjIyBDbHVzdGVycyBDaGFyYWN0ZXJpemF0aW9uDQoNCkxldCdzIGxvb2sgYXQgdGhlIHZhcmlhYmxlIHZhbHVlcyBwZXIgY2x1c3RlciB0byBiZXR0ZXIgdW5kZXJzdGFuZCB0aGVtLg0KDQpgYGB7cixlY2hvPUZBTFNFfQ0KbGlicmFyeShicm9vbSkNCnRpZHkoY292aWRfY2x1c3QpDQpgYGANCg0KDQoNCkNsdXN0ZXIgMSBjb21wcmlzZXMgdGhlIGNvdW50cmllcyB0aGF0IGhhdmUgaGFkIHRoZSBtb3N0IHRvdGFsIGNhc2VzIGFuZCBkZWF0aHMgcGVyIGNhcGl0YSB0aHJvdWdob3V0IHRoZSBwYW5kZW1pYy4gRHVyaW5nIFNlcHRlbWJlciAyMDIxLCB0aGV5IGhhdmUgdGhlIGhpZ2hlc3QgbnVtYmVyIG9mIElDVSBwYXRpZW50cyBhbmQgdGVzdHMgcGVyIHBvcHVsYXRpb24uIEZ1cnRoZXJtb3JlLCB0aGV5IGFyZSBieSBmYXIgdGhlIGdyb3VwIHdpdGggdGhlIGJlc3QgdmFjY2luYXRpb24gcG9saWN5LCBhbG1vc3QgYWxsIHRoZSBjb3VudHJpZXMgd2hlcmUgYm9vc3RlciBkb3NlcyBoYXZlIGJlZW4gYWRtaW5pc3RlcmVkIGFyZSBjb250YWluZWQgaW4gdGhpcyBjbHVzdGVyLiBIb3dldmVyLCB0aGUgc2FtZSBkb2VzIG5vdCBoYXBwZW4gd2l0aCB2YWNjaW5hdGlvbiBpbiBTZXB0ZW1iZXIgMjAyMSwgdGhlIG9ubHkgZ3JvdXAgdGhhdCBkb2VzIGl0IHdvcnNlIHRoYW4gdGhlbSBpcyBjbHVzdGVyIG51bWJlciA0LiBPbmUgcmVhc29uIG1heSBiZSB0aGF0IHRoZSBjb3VudHJpZXMgb2YgY2x1c3RlciAxLCBoYXZpbmcgYWxyZWFkeSB2YWNjaW5hdGVkIG11Y2ggb2YgdGhlaXIgcG9wdWxhdGlvbiwgaGF2ZSBhIHNtYWxsZXIgbWFyZ2luIHRvIGluY3JlYXNlIHRoZSBudW1iZXIgb2YgdmFjY2luZXMgcGVyIGluaGFiaXRhbnQuIFNvbWUgb2YgdGhlIGNvdW50cmllcyBpbiB0aGlzIGdyb3VwIGFyZTogSXRhbHksIFVuaXRlZCBTdGF0ZXMsIFN3ZWRlbiwgQ2hpbGUsIGV0Yy4NCg0KQ2x1c3RlciAyIGlzIHF1aXRlIGRpdmVyc2UgaW4gaXRzIGNvbXBvc2l0aW9uLiBUaGVyZSBhcmUgY291bnRyaWVzIHdpdGggbG93IG1vcnRhbGl0eSBhbmQgY2FzZXMsIHN1Y2ggYXMgTmV3IFplYWxhbmQgYW5kIExhb3MsIGFuZCBvdGhlcnMgd2l0aCBtYW55IGNhc2VzIGFuZCBkZWF0aHMsIHN1Y2ggYXMgQm9saXZpYSBhbmQgQW5kb3JyYS4gSXQgaXMgdGhlIHNlY29uZCBncm91cCB3aXRoIGZld2VyIHRlc3RzIHBlciBjYXNlLCB0b3RhbCB0ZXN0cyBwZXIgdGhvdXNhbmQgaW5oYWJpdGFudHMgYW5kIHZhY2NpbmF0aW9ucyBwZXIgaW5oYWJpdGFudHMuIEZ1cnRoZXJtb3JlLCBkdXJpbmcgU2VwdGVtYmVyIDIwMjEgdGhleSB3ZXJlIHRoZSBzZWNvbmQgZ3JvdXAgd2l0aCB0aGUgbW9zdCBzdHJpbmdlbnQgbW9iaWxpdHkgcmVzdHJpY3Rpb25zLg0KDQpDbHVzdGVyIDMgaGFzIGNvdW50cmllcyB3aXRoIG1hbnkgY2FzZXMgYW5kIHRvdGFsIGRlYXRocywgYWx0aG91Z2ggbm90IGFzIG1hbnkgYXMgdGhvc2Ugb2YgY2x1c3RlciAxLiBIb3dldmVyLCB0aGV5IGFyZSB0aGUgZ3JvdXAgdGhhdCBjdXJyZW50bHkgKFNlcHRlbWJlciAyMDIxKSBoYXMgbW9yZSBjYXNlcyBhbmQgZGVhdGhzIHBlciBjYXBpdGEuIFdoaWNoIGNhdXNlcyB0aGlzIHRvIGJlIHRoZSBjbHVzdGVyIHdpdGggdGhlIGhpZ2hlc3QgcmVwcm9kdWN0aW9uIHJhdGUgYW5kIGhvc3BpdGFsaXphdGlvbnMgcGVyIGluaGFiaXRhbnQuIEluIGFkZGl0aW9uLCBpdCBoYXMgYmVlbiBieSBmYXIgdGhlIHdvcnN0IG9mIGFsbCwgaW4gdGVzdHMgcGVyIGNhc2UuIEZpbmFsbHksIGl0IGlzIHRoZSBncm91cCB3aXRoIHRoZSBtb3N0IHN0cmluZ2VudCBtb2JpbGl0eSByZXN0cmljdGlvbnMuIEl0IGNvbnRhaW5zIGNvdW50cmllcyBzdWNoIGFzIFBlcnUsIE1leGljbywgQnJhemlsIG9yIHRoZSBQaGlsaXBwaW5lcy4NCg0KQ2x1c3RlciA0IGNvbnNpc3RzIG9mIGNvdW50cmllcyB0aGF0IGhhZCB2ZXJ5IGZldyBpbmZlY3Rpb25zIGFuZCBsb3cgbW9ydGFsaXR5LiBNb3N0IG9mIHRoZSBBZnJpY2FuIGNvdW50cmllcyBhcmUgaW4gdGhpcyBjbHVzdGVyIGFsdGhvdWdoIHRoZXJlIGFyZSBhbHNvIGNvdW50cmllcyBsaWtlIEhhaXRpLCBBZmdoYW5pc3RhbiBhbmQgU3lyaWEuIEV2ZW4gaWYgdGhleSBhcmUgbm90IHRoZSBjbHVzdGVyIHdpdGggdGhlIGZld2VzdCBjYXNlcyBhbmQgZGVhdGhzLCB0aGV5IGFyZSB0aGUgZ3JvdXAgd2l0aCB0aGUgZmV3ZXN0IGljdSBwYXRpZW50cyBhbmQgd2Vla2x5IGhvc3BpdGFsIGFkbWlzc2lvbiBwZXIgbWlsbGlvbiBkdXJpbmcgdGhlIG1vbnRoIG9mIFNlcHRlbWJlciAyMDIxLiBUaGV5IGFyZSB0aGUgb25lcyB3aXRoIHRoZSBmZXdlc3QgdGVzdHMgcGVyIHRob3VzYW5kIGFuZCB2YWNjaW5hdGVkIHBlb3BsZSBwZXIgcG9wdWxhdGlvbi4gSXQgbWF5IGJlIGR1ZSBpbiBsYXJnZSBwYXJ0IHRvIHRoZSBsb3cgbGV2ZWwgb2YgZGV2ZWxvcG1lbnQgb2YgdGhlc2UgY291bnRyaWVzLiBJbiBhbnkgY2FzZSwgd2UgbXVzdCBiZSBhd2FyZSB0aGF0IHRoZXNlIGNvdW50cmllcyBtYXkgbm90IGhhdmUgdGhlIG5lY2Vzc2FyeSBpbmZyYXN0cnVjdHVyZSB0byBiZSBhYmxlIHRvIG9idGFpbiByZWxpYWJsZSBudW1iZXJzLiBFdmVuIHNvLCBsYXN0IHllYXIgdGhlcmUgd2VyZSBwZW9wbGUgc3VycHJpc2VkIGJ5IHRoZSBsb3cgbW9ydGFsaXR5IG9mIGNvdmlkIGluIEFmcmljYSwgYXMgY2FuIGJlIHNlZW4gaW4gdGhpcyBhcnRpY2xlOiBodHRwczovL3d3dy5iYmMuY29tL25ld3Mvd29ybGQtYWZyaWNhLTU0NDE4NjEzDQoNCkFzIGNhbiBiZSBzZWVuIGluIHRoZSBncmFwaCBiZWxvdywgdGhlIG1vcnRhbGl0eSBvZiB0aGUgdmlydXMgaW4gQWZyaWNhIGhhcyBiZWVuIGxvd2VyIHRoYW4gaW4gdGhlIHdvcmxkIHRocm91Z2hvdXQgdGhlIHBhbmRlbWljLiBXaGVuIHdlIG1ha2UgdGhlIGNvbXBhcmlzb24gd2l0aCB0aGUgRXVyb3BlYW4gVW5pb24sIHRoZSBkaWZmZXJlbmNlcyBhcmUgZ2lnYW50aWMsIHdoaWNoIHN1cnByaXNlcyB1cyBldmVuIG1vcmUgZHVlIHRvIHRoZSBkaWZmZXJlbmNlcyBpbiBkZXZlbG9wbWVudCB0aGF0IGV4aXN0IGluIHRoZXNlIGFyZWFzLg0KDQoNCmBgYHtyLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRSwgZmlnLndpZHRoPTcuNSwgZmlnLmhlaWdodD00LjUsd2FybmluZz1GQUxTRX0NCg0KbGlicmFyeShsdWJyaWRhdGUpDQpsaWJyYXJ5KHBsb3RseSkNCg0KZGF0YTwtY292aWQgJT4lIGZpbHRlcihsb2NhdGlvbiVpbiUoYygiQWZyaWNhIiwiV29ybGQiLCJFdXJvcGVhbiBVbmlvbiIpKSklPiUgbXV0YXRlKGRhdGU9eW1kKGRhdGUpKSAlPiUgZ3JvdXBfYnkod2Vlaz1mbG9vcl9kYXRlKGRhdGUsICJ3ZWVrIiksbG9jYXRpb24pJT4lDQogIHN1bW1hcml6ZShuZXdfZGVhdGhzX3Blcl9taWxsaW9uPW1lYW4obmV3X2RlYXRoc19wZXJfbWlsbGlvbixuYS5ybT1UUlVFKSkgJT4ldW5ncm91cCgpICU+JSAgbXV0YXRlKG5ld19kZWF0aHNfcGVyX21pbGxpb249aWZlbHNlKGlzLm5hKG5ld19kZWF0aHNfcGVyX21pbGxpb24pPT1UUlVFLDAsbmV3X2RlYXRoc19wZXJfbWlsbGlvbikpICU+JSAgDQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBsb2NhdGlvbiwgdmFsdWVzX2Zyb20gPSBuZXdfZGVhdGhzX3Blcl9taWxsaW9uKSAlPiUgcmVuYW1lKCJVRSI9IkV1cm9wZWFuIFVuaW9uIikgDQoNCnBsb3RfbHkoZGF0YSwgeCA9IH53ZWVrKSAlPiUgYWRkX3RyYWNlKHkgPSB+V29ybGQsIG5hbWUgPSAnV29ybGQnLG1vZGUgPSAnbGluZXMnKSU+JSANCiAgbGF5b3V0KHRpdGxlID0gIkRhaWx5IG5ldyBjb25maXJtZWQgQ09WSUQtMTkgZGVhdGhzIHBlciBtaWxsaW9uIHBlb3BsZSIpICU+JSBhZGRfdHJhY2UoeSA9IH5BZnJpY2EsIG5hbWUgPSAnQWZyaWNhJyxtb2RlID0gJ2xpbmVzJykgJT4lIGFkZF90cmFjZSh5ID0gflVFLCBuYW1lID0gJ0V1cm9wZWFuIFVuaW9uJyxtb2RlID0gJ2xpbmVzJykgJT4lIGxheW91dCh5YXhpcyA9IGxpc3QodGl0bGUgPSAnTmV3IERlYXRocyBQZXIgTWlsbGlvbicpKQ0KDQpgYGANCg0KQ2x1c3RlciBudW1iZXIgNSBjb25zaXN0cyBvZiB0aGUgY291bnRyaWVzIHRoYXQgaGF2ZSBiZWVuIHRoZSBsZWFzdCBhZmZlY3RlZCBieSBDT1ZJRC4gSGVyZSBhcmUgbW9zdCBvZiB0aGUgY291bnRyaWVzIG9mIE9jZWFuaWE6IFZhbnVhdHUsIFBhbGF1LCBTb2xvbW9uIElzbGFuZHMsIE1pY3JvbmVzaWEsIGV0Yy4gSW4gYWRkaXRpb24gdG8gb3RoZXIgc21hbGwgY291bnRyaWVzIHN1Y2ggYXMgQmh1dGFuLCBUaGUgVmF0aWNhbiBhbmQgSG9uZyBLb25nLiBUaGVyZSBhcmUgdHdvIGNvdW50cmllcyB0aGF0IHN0YW5kIG91dCBpbiB0aGlzIGdyb3VwLCBzaW5jZSB0aGV5IGFyZSB2ZXJ5IGRpZmZlcmVudCBmcm9tIHRoZSByZXN0OiBDaGluYSBhbmQgVGFpd2FuLiBUaGlzIGlzIG5vdCB0aGUgZ3JvdXAgd2l0aCB0aGUgbGVhc3QgYW1vdW50IG9mIGhvc3BpdGFsaXphdGlvbnMgYW5kIElDVSBwYXRpZW50cywgc2luY2UgdGhleSBhcmUgbWFyZ2luYWxseSBzdXJwYXNzZWQgYnkgdGhlIGNvdW50cmllcyBvZiBjbHVzdGVyIDQuIEZ1cnRoZXJtb3JlLCBkdXJpbmcgdGhlIG1vbnRoIG9mIFNlcHRlbWJlciAyMDIxIHRoZXkgd2VyZSB0aGUgY2x1c3RlciB3aXRoIHRoZSBtb3N0IHZhY2NpbmF0ZWQgcGVvcGxlIHBlciBtaWxsaW9uIGluaGFiaXRhbnRzLiBGaW5hbGx5LCB0aGV5IGFyZSB0aGUgc2Vjb25kIGdyb3VwIHdpdGggdGhlIHRoZSBsZWFzdCBzdHJpbmdlbnQgbW9iaWxpdHkgcmVzdHJpY3Rpb25zIGFmdGVyIGNsdXN0ZXIgNC4gDQoNCiMjIEZpbmFsIFRob3VnaHRzDQoNCkl0IG11c3QgY29uc2lkZXJlZCB0aGF0IEkgY2hvb3NlIDUgY2x1c3RlcnMgaW4gYSB0b3RhbGx5IGFyYml0cmFyeSB3YXkuIEl0IGNvdWxkIGhhdmUgYmVlbiBtb3JlIG9yIGxlc3MuIFRoZXJlZm9yZSwgdGhlcmUgaXMgbm8gcmVhc29uIHRvIHRoaW5rIHRoYXQgdGhlIDUgY2x1c3RlcnMgYXJlIHNvbWV0aGluZyBkZWZpbml0aXZlIHRoYXQgY2Fubm90IGJlIGNoYW5nZWQgb3IgcXVlc3Rpb25lZC4gSGF2aW5nIHNhaWQgdGhpcywgdGhlcmUgYXJlIDMgc3VycHJpc2VzIHRoYXQgSSBjYW1lIGFjcm9zcyBkdXJpbmcgdGhpcyBhbmFseXNpczogRmlyc3QsIG5vdGljaW5nIHRoZSBsaXR0bGUgaW1wYWN0IHRoYXQgQ09WSUQgaGFzIGhhZCBpbiBBZnJpY2EsIHRoZSBmZXcgY2FzZXMgYW5kIGRlYXRocyBpbiBDaGluYSBhbmQgc2VlaW5nIGhvdyBtYW55IGhpZ2gtaW5jb21lIGNvdW50cmllcyB3ZXJlIGdyZWF0bHkgYWZmZWN0ZWQsIGJlaW5nIHRoZSBvbmx5IGV4Y2VwdGlvbnM6IEF1c3RyYWxpYSwgTmV3IFplYWxhbmQgYW5kIFNvdXRoIEtvcmVhLiBPbiB0aGUgZmlyc3QgcG9pbnQsIHRoZSBleHBsYW5hdGlvbnMgY2FuIGJlIHZhcmllZCwgZnJvbSB0aGUgbWVkaWFuIGFnZSBvZiB0aGUgcG9wdWxhdGlvbiBvciB0aGUgbG93IHBvcHVsYXRpb24gZGVuc2l0eSBpbiBBZnJpY2EsIGluIHRoaXMgW2xpbmtdKGh0dHBzOi8vd3d3LmJiYy5jb20vbmV3cy93b3JsZC1hZnJpY2EtNTQ0MTg2MTMpIHNvbWUgaHlwb3RoZXNlcyBhcmUgZXhwbG9yZWQuDQoNCkFib3V0IHRoZSBjYXNlcyBhbmQgZGVhdGhzIGluIENoaW5hLCB0aGVyZSBhcmUgYWxzbyBtYW55IHRoZW9yaWVzLiBPbmUgaXMgdGhhdCBzaW5jZSB0aGUgdmlydXMgaGFwcGVuZWQgc28gZWFybHkgaW4gdGhhdCBjb3VudHJ5IHRoZXkgZGlkbid0IGhhdmUgaXQgaWRlbnRpZmllZCBvciBuYW1lZCBhdCB0aGUgYmVnaW5uaW5nLCBhbmQgdGhlcmUgd2FzIG5vIHdheSBvZiB0ZXN0aW5nIGZvciBpdC4gU28gdGhlcmUncyBhIGh1Z2UgY2hhbmNlIHRoYXQgdGhlIGNhc2VzIGFuZCBkZWF0aHMgYXJlIHdheSBoaWdoZXIuIEFub3RoZXIgZXhwbGFuYXRpb24gaXMgdGhhdCB0aGUgcG9saXRpY2FsIHJlc3BvbnNlIHdhcyB2ZXJ5IGdvb2QgaW4gQ2hpbmEsIGVzcGVjaWFsbHkgdGhlIHN0cmljdCBsb2NrZG93bnMuIEFib3V0IHRoZSBsYXN0IHBvaW50LCBJIHRoaW5rIGl0IGlzIGludGVyZXN0aW5nIHRvIGFuYWx5emUgd2h5IGNlcnRhaW4gZGV2ZWxvcGVkIGNvdW50cmllcyBoYWQgZmV3ZXIgY2FzZXMgYW5kIGRlYXRocy4gSXMgaXQgZHVlIHRvIGFueSBwdWJsaWMgcG9saWN5IG9yIGRlbW9ncmFwaGljIGZhY3Rvcj8NCg0KQ2x1c3RlcmluZyBpcyBnZW5lcmFsbHkgdXNlZCBmb3IgY3VzdG9tZXIgc2VnbWVudGF0aW9uLCB0YXJnZXRlZCBtYXJrZXRpbmcgb3IgcmVjb21tZW5kYXRpb24gc3lzdGVtcy4gSSB0aGluayB0aGF0IHVzaW5nIGl0IHRvIGZpbmQgcGF0dGVybnMgaW4gYSBncm91cCBvZiB0ZXJyaXRvcmlhbCB1bml0cyBjYW4gYmUgdmVyeSBpbXBvcnRhbnQgZm9yIHB1YmxpYyBwb2xpY3ksIHNpbmNlIGl0IGNhbiBoZWxwIHRvIHBsYW4gZGlmZmVyZW50IHR5cGVzIG9mIGludGVydmVudGlvbnMgYW5kIHBvbGljaWVzIGRlcGVuZGluZyBvbiB0aGUgY2hhcmFjdGVyaXN0aWNzIHRoYXQgZWFjaCBjbHVzdGVyIGhhcy4NCg0KDQoNCg==