1 Introduction

Knowledge of the frequency of disease is an important prerequisite for understanding population health, case finding, commissioning and planning services, and understanding variation in health and care. The most commonly used measure of disease frequency is prevalence which is an estimate of the number of cases of a given disease or risk factor in the population at a point in time (point prevalence) or over a given time period (period prevalence).

This short briefing summarizes the methods and results of work commissioned by Public Health England from Imperial College to estimate disease prevalences for:

  • cardiovascular disease
    • stroke
    • coronary heart disease (CHD)
    • peripheral arterial disease (PAD)
  • depression
  • chronic obstructive pulmonary disease (COPD)
  • hypertension (BP)

Work to calculate heart failure estimates is ongoing and national asthma age-sex prevalences have been produced.

These estimates are intended to:

  • update previously calculated values which are now several years out of date
  • complement recent estimates for

Estimates for hypertension as part of this analysis for have been published here.

They have been produced for use by PHE, local authorities and the NHS.

1.1 Where can I get the data?

We will be publishing the general practice level estimates as part of an update of the national general practice profiles, and as part of a new prevalence tool which pulls together all the prevalence estimates currently in fingertips.

We intend to publish the local authority estimates through the PHE Fingertips tool but the data is currently available from here.

1.2 Why estimate prevalence?

With the exception of cancer, complete population disease registers do not exist, so we cannot enumerate the number of cases of any given disease in the population. The Quality and Outcomes Framework (QOF) produces general practice estimates of common diseases but these are not published with age breakdowns, and are based on coded events in the GP record, not externally validated cases.

For this reason it is common practice to ‘fill in the gaps’ by creating estimates of disease prevalence - these are often referred to as modelled or synthetic estimates.

1.3 How were the estimates created?

There a number of ways of creating prevalences. The estimates outlined in this briefing were generated by statistical modelling. The details of the method varies depending on the disease and the daat sources but the basic principles are:

  1. Identify population based studies (cohort studies or surveys) with accurately measured cases of disease and predictor variables for example age, sex, ethnicity. Classify these cases as disease positive or negative.

  2. Construct the best predictive model based on the data in the study which maximizes the prediction of the presence or absence of disease. This gives a formula or algorithm which can then be applied to a population. The usual model is logistic regression.

  3. Assemble the data for local areas (target populations) to populate the algorithm for each predictor variable.

  4. For each population run the algorithm to produce a estimate.

Detailed technical reports for each disease are available from here. Where possible, the model development follows the TRIPOD guidelines for good practice for mutivariable prediction models.

1.3.1 Model summaries

Table x summarises the methods, model inputs, data sources used and model accuracy.

1.4 How do these estimates differ from previous estimates

These modelled values differ from previous estimates in a number of ways:

  • Different input data sources
  • Different age bands
  • Wider range of predictor variables
  • Inclusion of confidence intervals
  • Estimates produced for GP practices and Local Authority populations.

These are new estimates and cannot necessarily be directly compared with previously calculated values. The main differences are:

  1. Hypertension - these estimates are broadly comparable and have similar underlying methodology
  2. COPD - the methodology is different. The previous estimates using the Health Survey for England were based on spirometry defined COPD. This defintion changed in the Health Survey over successive surveys when spirometry was done. These estimates are based on clinical case defintions using GP data in the Clinical Practice Research Datalink (CPRD) dataset, enhanced with HES data.
  3. Cardiovascular disease - the new estimates have been developed using the Whitehall II studies with a case defintion based on clinical endpoints for diagnosing CVD such as morality, angiography and other clinical confirmation. The use of the Whitehall studies also means that the new estimates are restricted to the 55-79 age group. The previous estimates modelled from the Health Survey for England were based on self-reported doctor-diagnosed heart disease and stroke.
  4. Depression - these estimates are new - the estimates are a longer period prevalence than QOF and tend to be higher.

The models are also more technically sophisicated and have a wider range of input variables (see next section).

A more detailed comparison between new and old estimates is presented in section…

1.5 Which predictor variables are used to mode which disease?

This is summarised in the tables and figures below. All models include age, sex, ethnicity and deprivation as predictors. Smoking is included in the COPD and cardiovascular disease models. The cardiovascular models also include physical activity, diabetes and chronic kidney disease. BMI is included in all the models except COPD. The depression and hypertension models include occupation and long term limiting illness. Hypertension is the only model to include education.

The values of each predictor are for the most part derived from the census, or calculated from surveys. The method used to derived the predicted values of prevalence for each unit of analysis is inverse probabiity weighting. The full technicalities of the method are beyond the scope of this report but it is a form of direct standardisation (see [here] (https://en.wikipedia.org/wiki/Inverse_probability_weighting)).

2 What do the data show?

This section is split into 2 parts:

  1. Local authority summaries
  2. General practice summaries

2.1 Local authority data

2.1.1 Missing data

Note that there are some missing values for LA estimates for hypertension, COPD and depression which we are working with Imperial College to fill.

2.1.2 Summary statistics

Summary statistics for LA data
disease mean median minimum 10th centile 90th centile maximum
bp 20.65 21.23 12.42 16.75 23.59 27.63
chd 7.92 7.87 6.66 7.15 8.72 10.53
copd 2.61 2.63 1.05 1.79 3.34 4.19
depression 15.19 15.38 8.63 13.14 17.22 18.40
pad 1.15 1.14 0.95 1.04 1.27 1.71
stroke 3.71 3.70 3.04 3.43 4.00 4.34

2.2 Plots

2.3 Maps

2.3.1 CHD

2.3.2 Depression

2.3.3 COPD

2.3.4 Stroke

2.3.5 Hypertension

2.3.6 Peripheral arterial disease

3 GP data

Error: object 'indicator' not found

We have been able to estimate prevalence for 60504 practices.

Fig x shows the variation in practice level disease estimates by region. This suggests disease prevalence tends to be lowest in London and highest in the North East and the North West.

3.0.1 Hypertension

The average estimated prevalence of hypertension is 20.85% and varies from 2% in in the practice with the lowest value to 50.62% in the practice with the highest.

3.0.2 COPD

The average estimated prevalence of COPD is 2.42% and varies from 0.13% in in the practice with the lowest value to 13.6% in the practice with the highest.

3.0.3 Depresssion

The average estimated prevalence of depression is 20.85% and varies from 2% in in the practice with the lowest value to 50.62% in the practice with the highest.

3.0.4 Coronary heart disease

The average estimated prevalence of CHD is 7.37% and varies from 3.81% in in the practice with the lowest value to 12.15% in the practice with the highest.

3.0.5 Stroke

The average estimated prevalence of stroke is 3.7% and varies from 2.23% in in the practice with the lowest value to 6.02% in the practice with the highest.

3.0.6 Peripheral arterial disease

The average estimated prevalence of PAD is 1% and varies from 0.57% in in the practice with the lowest value to 1.82% in the practice with the highest.

3.0.7 Overall comparisons with QOF

The relationship between QOF estimates and these new prevalence estimates can be captured in a number of ways. One way is to plot a correlogram which shows the correlation between all the variables. This is shown in figure. This shows correlations both numerically, and graphically as filled circles. The darker and larger the circle the stronger the relationship. Positive correlations are shown in blue; negative in red. Correlations greater than +/- 0.7 are generally considered to represent a strong relationship (where 1 is the strongest possible relationship). From this chart we can see that:

  • For hypertension there is a strong correlation between the prevalence estimates and QOF
  • For other diseases the relationship between modeled value and QOF is weaker
  • There are also strong relationships between modeled values for hypertension and COPD and cardiovascular estimates

3.1 Comparison with previous estimates

Joining, by = "practice_code"

Joining, by = "practice_code"

Of those practices with a previous estimate, 166 are not included in the updates. These are:

,

LS0tCnRpdGxlOiAnUHJldmFsZW5jZSBtb2RlbHM6IGJyaWVmaW5nIG5vdGUnCmF1dGhvcjogIkp1bGlhbiBGbG93ZXJzIgpkYXRlOiAiMTN0aCBKYW51YXJ5IDIwMTciCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgZmlnX2NhcHRpb246IHllcwogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogIGh0bWxfZG9jdW1lbnQ6CiAgICBmaWdfY2FwdGlvbjogeWVzCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogICAgdG9jOiB5ZXMKICAgIHRvY19mbG9hdDogeWVzCiAgcGRmX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICB3b3JkX2RvY3VtZW50OgogICAgZmlnX2NhcHRpb246IHllcwogICAgdG9jOiB5ZXMKLS0tCgpgYGB7cn0KbGlicmFyeShrbml0cikKb3B0c19jaHVuayRzZXQoY2FjaGUgPSBUUlVFLCBlY2hvID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFKQpvcHRpb25zKGRpZ2l0cyA9IDQpCgpgYGAKCmBgYHtyIGxvYWQgbGlicmFyaWVzLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpzZXR3ZCgifi9Eb2N1bWVudHMvUl9wcm9qZWN0cy9wcmV2YWxlbmNlX2VzdGltYXRlcyIpCgpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeShkYXRhLnRhYmxlKSkKc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKGxpYnJhcnkoZHBseXIpKQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeShnZ3Bsb3QyKSkKc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKGxpYnJhcnkocmVhZHhsKSkKc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKGxpYnJhcnkocmVhZHIpKQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeShtb2RlbHIpKQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeSh0aWR5cikpCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KGtuaXRyKSkKc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKGxpYnJhcnkoaGF2ZW4pKQoKYGBgCgoKYGBge3IgaW1wb3J0IGZpbGVzICwgaW5jbHVkZT1GQUxTRSwgY2FjaGU9VFJVRX0KbGEgPC0gcmVhZF9jc3YoIkRhdGEvbGFfZXN0aW1hdGVzX2xvbmcyMDE3LTAxLTExLmNzdiIpCmdwIDwtIHJlYWRfY3N2KCJEYXRhL2dwLmVzdGltYXRlc19sb25nMjAxNi0xMC0yNy5jc3YiKQoKbGFfcGFyYW0gPC0gcmVhZF9jc3YoIkRhdGEvbGFfcGFyYW1ldGVycy56aXAiKQpncF9wYXJhbSA8LSByZWFkX2NzdigiRGF0YS9ncF9wYXJhbWV0ZXJzLmNzdiIpCgpvbGRfZXN0cyA8LSByZWFkX2NzdigiRGF0YS9vbGRfZXN0cy5jc3YiKQoKYGBgCgojIEludHJvZHVjdGlvbgoKS25vd2xlZGdlIG9mIHRoZSBmcmVxdWVuY3kgb2YgZGlzZWFzZSBpcyBhbiBpbXBvcnRhbnQgcHJlcmVxdWlzaXRlIGZvciB1bmRlcnN0YW5kaW5nIHBvcHVsYXRpb24gaGVhbHRoLCBjYXNlIGZpbmRpbmcsIGNvbW1pc3Npb25pbmcgYW5kIHBsYW5uaW5nIHNlcnZpY2VzLCBhbmQgdW5kZXJzdGFuZGluZyB2YXJpYXRpb24gaW4gaGVhbHRoIGFuZCBjYXJlLiBUaGUgbW9zdCBjb21tb25seSB1c2VkIG1lYXN1cmUgb2YgZGlzZWFzZSBmcmVxdWVuY3kgaXMgKnByZXZhbGVuY2UqIHdoaWNoIGlzIGFuIGVzdGltYXRlIG9mIHRoZSBudW1iZXIgb2YgY2FzZXMgb2YgYSBnaXZlbiBkaXNlYXNlIG9yIHJpc2sgZmFjdG9yIGluIHRoZSBwb3B1bGF0aW9uIGF0IGEgcG9pbnQgaW4gdGltZSAoKnBvaW50IHByZXZhbGVuY2UqKSBvciBvdmVyIGEgZ2l2ZW4gdGltZSBwZXJpb2QgKCpwZXJpb2QgcHJldmFsZW5jZSopLiAKClRoaXMgc2hvcnQgYnJpZWZpbmcgc3VtbWFyaXplcyB0aGUgbWV0aG9kcyBhbmQgcmVzdWx0cyBvZiB3b3JrIGNvbW1pc3Npb25lZCBieSBQdWJsaWMgSGVhbHRoIEVuZ2xhbmQgZnJvbSBJbXBlcmlhbCBDb2xsZWdlIHRvIGVzdGltYXRlIGRpc2Vhc2UgcHJldmFsZW5jZXMgZm9yOgogCi0gY2FyZGlvdmFzY3VsYXIgZGlzZWFzZSAKICAgICsgICAgIHN0cm9rZSAKICAgICsgICAgIGNvcm9uYXJ5IGhlYXJ0IGRpc2Vhc2UgKENIRCkKICAgICsgICAgIHBlcmlwaGVyYWwgYXJ0ZXJpYWwgZGlzZWFzZSAoUEFEKQotIGRlcHJlc3Npb24KLSBjaHJvbmljIG9ic3RydWN0aXZlIHB1bG1vbmFyeSBkaXNlYXNlIChDT1BEKQotIGh5cGVydGVuc2lvbiAoQlApCgpXb3JrIHRvIGNhbGN1bGF0ZSBoZWFydCBmYWlsdXJlIGVzdGltYXRlcyBpcyBvbmdvaW5nIGFuZCBuYXRpb25hbCBhc3RobWEgYWdlLXNleCBwcmV2YWxlbmNlcyBoYXZlIGJlZW4gcHJvZHVjZWQuCgpUaGVzZSBlc3RpbWF0ZXMgYXJlIGludGVuZGVkIHRvOgoKLSB1cGRhdGUgcHJldmlvdXNseSBjYWxjdWxhdGVkIHZhbHVlcyB3aGljaCBhcmUgbm93IHNldmVyYWwgeWVhcnMgb3V0IG9mIGRhdGUKLSBjb21wbGVtZW50IHJlY2VudCBlc3RpbWF0ZXMgZm9yIAogICAgKyBbZGlhYmV0ZXNdKGh0dHA6Ly93d3cueWhwaG8ub3JnLnVrL3Jlc291cmNlL3ZpZXcuYXNweD9SSUQ9MTU0MDQ5KQogICAgKyBbY2FuY2VyXShodHRwOi8vd3d3Lm5jaW4ub3JnLnVrL1ByZXZhbGVuY2UvMV81XzEwX1llYXIvYXRsYXMuaHRtbCkKICAgICsgW2RlbWVudGlhXShodHRwczovL2ZpbmdlcnRpcHMucGhlLm9yZy51ay9wcm9maWxlLWdyb3VwL21lbnRhbC1oZWFsdGgvcHJvZmlsZS9kZW1lbnRpYS9kYXRhI3BhZ2UvMC9naWQvMTkzODEzMjgxMS9wYXQvNi9wYXIvRTEyMDAwMDA0L2F0aS8xMDIvYXJlL0UwNjAwMDAxNSkKICAgIApFc3RpbWF0ZXMgZm9yIGh5cGVydGVuc2lvbiBhcyBwYXJ0IG9mIHRoaXMgYW5hbHlzaXMgZm9yIGhhdmUgYmVlbiBwdWJsaXNoZWQgW2hlcmVdKGh0dHA6Ly93d3cueWhwaG8ub3JnLnVrL3Jlc291cmNlL3ZpZXcuYXNweD9SSUQ9MjQ0MzE4KS4gICAgCiAgICAKVGhleSBoYXZlIGJlZW4gcHJvZHVjZWQgZm9yIHVzZSBieSBQSEUsIGxvY2FsIGF1dGhvcml0aWVzIGFuZCB0aGUgTkhTLgoKIyMgV2hlcmUgY2FuIEkgZ2V0IHRoZSBkYXRhPwoKV2Ugd2lsbCBiZSBwdWJsaXNoaW5nIHRoZSBnZW5lcmFsIHByYWN0aWNlIGxldmVsIGVzdGltYXRlcyBhcyBwYXJ0IG9mIGFuIHVwZGF0ZSBvZiB0aGUgW25hdGlvbmFsIGdlbmVyYWwgcHJhY3RpY2UgcHJvZmlsZXNdKGh0dHBzOi8vZmluZ2VydGlwcy5waGUub3JnLnVrL3Byb2ZpbGUvZ2VuZXJhbC1wcmFjdGljZSksIGFuZCBhcyBwYXJ0IG9mIGEgbmV3IHByZXZhbGVuY2UgdG9vbCB3aGljaCBwdWxscyB0b2dldGhlciBhbGwgdGhlIHByZXZhbGVuY2UgZXN0aW1hdGVzIGN1cnJlbnRseSBpbiBmaW5nZXJ0aXBzLgoKV2UgaW50ZW5kIHRvIHB1Ymxpc2ggdGhlIGxvY2FsIGF1dGhvcml0eSBlc3RpbWF0ZXMgdGhyb3VnaCB0aGUgW1BIRSBGaW5nZXJ0aXBzIHRvb2xdKGh0dHBzOi8vZmluZ2V0aXBzLnBoZS5vcmcudWspIGJ1dCB0aGUgZGF0YSBpcyBjdXJyZW50bHkgYXZhaWxhYmxlIGZyb20gW2hlcmVdKGh0dHBzOi8vZ2l0aHViLmNvbS9qdWxpYW5mbG93ZXJzL3ByZXZhbGVuY2VfZXN0aW1hdGVzKS4KCiMjIFdoeSBlc3RpbWF0ZSBwcmV2YWxlbmNlPwoKV2l0aCB0aGUgZXhjZXB0aW9uIG9mIGNhbmNlciwgY29tcGxldGUgcG9wdWxhdGlvbiBkaXNlYXNlIHJlZ2lzdGVycyBkbyBub3QgZXhpc3QsIHNvIHdlIGNhbm5vdCBlbnVtZXJhdGUgdGhlIG51bWJlciBvZiBjYXNlcyBvZiBhbnkgZ2l2ZW4gZGlzZWFzZSBpbiB0aGUgcG9wdWxhdGlvbi4gVGhlIFF1YWxpdHkgYW5kIE91dGNvbWVzIEZyYW1ld29yayAoUU9GKSBwcm9kdWNlcyBnZW5lcmFsIHByYWN0aWNlIGVzdGltYXRlcyBvZiBjb21tb24gZGlzZWFzZXMgYnV0IHRoZXNlIGFyZSBub3QgcHVibGlzaGVkIHdpdGggYWdlIGJyZWFrZG93bnMsIGFuZCBhcmUgYmFzZWQgb24gY29kZWQgZXZlbnRzIGluIHRoZSBHUCByZWNvcmQsIG5vdCBleHRlcm5hbGx5IHZhbGlkYXRlZCBjYXNlcy4KCkZvciB0aGlzIHJlYXNvbiBpdCBpcyBjb21tb24gcHJhY3RpY2UgdG8gJ2ZpbGwgaW4gdGhlIGdhcHMnIGJ5IGNyZWF0aW5nIGVzdGltYXRlcyBvZiBkaXNlYXNlIHByZXZhbGVuY2UgLSB0aGVzZSBhcmUgb2Z0ZW4gcmVmZXJyZWQgdG8gYXMgbW9kZWxsZWQgb3Igc3ludGhldGljIGVzdGltYXRlcy4KCiMjIEhvdyB3ZXJlIHRoZSBlc3RpbWF0ZXMgY3JlYXRlZD8KClRoZXJlIGEgbnVtYmVyIG9mIHdheXMgb2YgY3JlYXRpbmcgcHJldmFsZW5jZXMuIFRoZSBlc3RpbWF0ZXMgb3V0bGluZWQgaW4gdGhpcyBicmllZmluZyB3ZXJlIGdlbmVyYXRlZCBieSBzdGF0aXN0aWNhbCBtb2RlbGxpbmcuIFRoZSBkZXRhaWxzIG9mIHRoZSBtZXRob2QgdmFyaWVzIGRlcGVuZGluZyBvbiB0aGUgZGlzZWFzZSBhbmQgdGhlIGRhYXQgc291cmNlcyBidXQgdGhlIGJhc2ljIHByaW5jaXBsZXMgYXJlOgoKMS4gSWRlbnRpZnkgcG9wdWxhdGlvbiBiYXNlZCBzdHVkaWVzIChjb2hvcnQgc3R1ZGllcyBvciBzdXJ2ZXlzKSB3aXRoIGFjY3VyYXRlbHkgbWVhc3VyZWQgY2FzZXMgb2YgZGlzZWFzZSBhbmQgcHJlZGljdG9yIHZhcmlhYmxlcyBmb3IgZXhhbXBsZSBhZ2UsIHNleCwgZXRobmljaXR5LiBDbGFzc2lmeSB0aGVzZSBjYXNlcyBhcyBkaXNlYXNlIHBvc2l0aXZlIG9yIG5lZ2F0aXZlLgoKMi4gQ29uc3RydWN0IHRoZSBiZXN0IHByZWRpY3RpdmUgbW9kZWwgYmFzZWQgb24gdGhlIGRhdGEgaW4gdGhlIHN0dWR5IHdoaWNoIG1heGltaXplcyB0aGUgcHJlZGljdGlvbiBvZiB0aGUgcHJlc2VuY2Ugb3IgYWJzZW5jZSBvZiBkaXNlYXNlLiBUaGlzIGdpdmVzIGEgZm9ybXVsYSBvciBhbGdvcml0aG0gd2hpY2ggY2FuIHRoZW4gYmUgYXBwbGllZCB0byBhIHBvcHVsYXRpb24uIFRoZSB1c3VhbCBtb2RlbCBpcyBsb2dpc3RpYyByZWdyZXNzaW9uLgoKMy4gQXNzZW1ibGUgdGhlIGRhdGEgZm9yIGxvY2FsIGFyZWFzICh0YXJnZXQgcG9wdWxhdGlvbnMpIHRvIHBvcHVsYXRlIHRoZSBhbGdvcml0aG0gZm9yIGVhY2ggcHJlZGljdG9yIHZhcmlhYmxlLiAKCjQuIEZvciBlYWNoIHBvcHVsYXRpb24gcnVuIHRoZSBhbGdvcml0aG0gdG8gcHJvZHVjZSBhICBlc3RpbWF0ZS4KCkRldGFpbGVkIHRlY2huaWNhbCByZXBvcnRzIGZvciBlYWNoIGRpc2Vhc2UgYXJlIGF2YWlsYWJsZSBmcm9tIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vanVsaWFuZmxvd2Vycy9wcmV2YWxlbmNlX2VzdGltYXRlcykuIFdoZXJlIHBvc3NpYmxlLCB0aGUgbW9kZWwgZGV2ZWxvcG1lbnQgZm9sbG93cyB0aGUgW1RSSVBPRF0oaHR0cHM6Ly93d3cuZXF1YXRvci1uZXR3b3JrLm9yZy9yZXBvcnRpbmctZ3VpZGVsaW5lcy90cmlwb2Qtc3RhdGVtZW50LykgZ3VpZGVsaW5lcyBmb3IgZ29vZCBwcmFjdGljZSBmb3IgbXV0aXZhcmlhYmxlIHByZWRpY3Rpb24gbW9kZWxzLgoKIyMjIE1vZGVsIHN1bW1hcmllcwoKVGFibGUgeCBzdW1tYXJpc2VzIHRoZSBtZXRob2RzLCBtb2RlbCBpbnB1dHMsIGRhdGEgc291cmNlcyB1c2VkIGFuZCBtb2RlbCBhY2N1cmFjeS4KCgoKCgoKIyMgSG93IGRvIHRoZXNlIGVzdGltYXRlcyBkaWZmZXIgZnJvbSBwcmV2aW91cyBlc3RpbWF0ZXMKClRoZXNlIG1vZGVsbGVkIHZhbHVlcyBkaWZmZXIgZnJvbSBwcmV2aW91cyBlc3RpbWF0ZXMgaW4gYSBudW1iZXIgb2Ygd2F5czoKCi0gRGlmZmVyZW50IGlucHV0IGRhdGEgc291cmNlcwotIERpZmZlcmVudCBhZ2UgYmFuZHMKLSBXaWRlciByYW5nZSBvZiBwcmVkaWN0b3IgdmFyaWFibGVzCi0gSW5jbHVzaW9uIG9mIGNvbmZpZGVuY2UgaW50ZXJ2YWxzCi0gRXN0aW1hdGVzIHByb2R1Y2VkIGZvciBHUCBwcmFjdGljZXMgYW5kIExvY2FsIEF1dGhvcml0eSBwb3B1bGF0aW9ucy4KClRoZXNlIGFyZSBuZXcgZXN0aW1hdGVzIGFuZCBjYW5ub3QgbmVjZXNzYXJpbHkgYmUgZGlyZWN0bHkgY29tcGFyZWQgd2l0aCBwcmV2aW91c2x5IGNhbGN1bGF0ZWQgdmFsdWVzLiBUaGUgbWFpbiBkaWZmZXJlbmNlcyBhcmU6CgoxLiBIeXBlcnRlbnNpb24gLSB0aGVzZSBlc3RpbWF0ZXMgYXJlIGJyb2FkbHkgY29tcGFyYWJsZSBhbmQgaGF2ZSBzaW1pbGFyIHVuZGVybHlpbmcgbWV0aG9kb2xvZ3kKMi4gQ09QRCAgLSB0aGUgbWV0aG9kb2xvZ3kgaXMgZGlmZmVyZW50LiBUaGUgcHJldmlvdXMgZXN0aW1hdGVzIHVzaW5nIHRoZSBIZWFsdGggU3VydmV5IGZvciBFbmdsYW5kIHdlcmUgYmFzZWQgb24gc3Bpcm9tZXRyeSBkZWZpbmVkIENPUEQuIFRoaXMgZGVmaW50aW9uIGNoYW5nZWQgaW4gdGhlIEhlYWx0aCBTdXJ2ZXkgb3ZlciBzdWNjZXNzaXZlIHN1cnZleXMgd2hlbiBzcGlyb21ldHJ5IHdhcyBkb25lLiBUaGVzZSBlc3RpbWF0ZXMgYXJlIGJhc2VkIG9uIGNsaW5pY2FsIGNhc2UgZGVmaW50aW9ucyB1c2luZyBHUCBkYXRhIGluIHRoZSBDbGluaWNhbCBQcmFjdGljZSBSZXNlYXJjaCBEYXRhbGluayAoQ1BSRCkgZGF0YXNldCwgZW5oYW5jZWQgd2l0aCBIRVMgZGF0YS4KMy4gQ2FyZGlvdmFzY3VsYXIgZGlzZWFzZSAtIHRoZSBuZXcgZXN0aW1hdGVzIGhhdmUgYmVlbiBkZXZlbG9wZWQgdXNpbmcgdGhlIFdoaXRlaGFsbCBJSSBzdHVkaWVzIHdpdGggYSBjYXNlIGRlZmludGlvbiBiYXNlZCBvbiBjbGluaWNhbCBlbmRwb2ludHMgZm9yIGRpYWdub3NpbmcgQ1ZEIHN1Y2ggYXMgbW9yYWxpdHksIGFuZ2lvZ3JhcGh5IGFuZCBvdGhlciBjbGluaWNhbCBjb25maXJtYXRpb24uIFRoZSB1c2Ugb2YgdGhlIFdoaXRlaGFsbCBzdHVkaWVzIGFsc28gbWVhbnMgdGhhdCB0aGUgbmV3IGVzdGltYXRlcyBhcmUgcmVzdHJpY3RlZCB0byB0aGUgNTUtNzkgYWdlIGdyb3VwLiBUaGUgcHJldmlvdXMgZXN0aW1hdGVzIG1vZGVsbGVkIGZyb20gdGhlIEhlYWx0aCBTdXJ2ZXkgZm9yIEVuZ2xhbmQgd2VyZSBiYXNlZCBvbiBzZWxmLXJlcG9ydGVkIGRvY3Rvci1kaWFnbm9zZWQgaGVhcnQgZGlzZWFzZSBhbmQgc3Ryb2tlLgo0LiBEZXByZXNzaW9uIC0gdGhlc2UgZXN0aW1hdGVzIGFyZSBuZXcgLSB0aGUgZXN0aW1hdGVzIGFyZSBhIGxvbmdlciBwZXJpb2QgcHJldmFsZW5jZSB0aGFuIFFPRiBhbmQgdGVuZCB0byBiZSBoaWdoZXIuCgpUaGUgbW9kZWxzIGFyZSBhbHNvIG1vcmUgdGVjaG5pY2FsbHkgc29waGlzaWNhdGVkIGFuZCBoYXZlIGEgd2lkZXIgcmFuZ2Ugb2YgaW5wdXQgdmFyaWFibGVzIChzZWUgbmV4dCBzZWN0aW9uKS4KCkEgbW9yZSBkZXRhaWxlZCBjb21wYXJpc29uIGJldHdlZW4gbmV3IGFuZCBvbGQgZXN0aW1hdGVzIGlzIHByZXNlbnRlZCBpbiBzZWN0aW9uLi4uCgojIyBXaGljaCBwcmVkaWN0b3IgdmFyaWFibGVzIGFyZSB1c2VkIHRvIG1vZGUgd2hpY2ggZGlzZWFzZT8KClRoaXMgaXMgc3VtbWFyaXNlZCBpbiB0aGUgdGFibGVzIGFuZCBmaWd1cmVzIGJlbG93LiBBbGwgbW9kZWxzIGluY2x1ZGUgYWdlLCBzZXgsIGV0aG5pY2l0eSBhbmQgZGVwcml2YXRpb24gYXMgcHJlZGljdG9ycy4gU21va2luZyBpcyBpbmNsdWRlZCBpbiB0aGUgQ09QRCBhbmQgY2FyZGlvdmFzY3VsYXIgZGlzZWFzZSBtb2RlbHMuIFRoZSBjYXJkaW92YXNjdWxhciBtb2RlbHMgYWxzbyBpbmNsdWRlIHBoeXNpY2FsIGFjdGl2aXR5LCBkaWFiZXRlcyBhbmQgY2hyb25pYyBraWRuZXkgZGlzZWFzZS4gQk1JIGlzIGluY2x1ZGVkIGluIGFsbCB0aGUgbW9kZWxzIGV4Y2VwdCBDT1BELiBUaGUgZGVwcmVzc2lvbiBhbmQgaHlwZXJ0ZW5zaW9uIG1vZGVscyBpbmNsdWRlIG9jY3VwYXRpb24gYW5kIGxvbmcgdGVybSBsaW1pdGluZyBpbGxuZXNzLiBIeXBlcnRlbnNpb24gaXMgdGhlIG9ubHkgbW9kZWwgdG8gaW5jbHVkZSBlZHVjYXRpb24uCgpUaGUgdmFsdWVzIG9mIGVhY2ggcHJlZGljdG9yIGFyZSBmb3IgdGhlIG1vc3QgcGFydCBkZXJpdmVkIGZyb20gdGhlIGNlbnN1cywgb3IgY2FsY3VsYXRlZCBmcm9tIHN1cnZleXMuIFRoZSBtZXRob2QgdXNlZCB0byBkZXJpdmVkIHRoZSBwcmVkaWN0ZWQgdmFsdWVzIG9mIHByZXZhbGVuY2UgZm9yIGVhY2ggdW5pdCBvZiBhbmFseXNpcyBpcyAqaW52ZXJzZSBwcm9iYWJpaXR5IHdlaWdodGluZyouIFRoZSBmdWxsIHRlY2huaWNhbGl0aWVzIG9mIHRoZSBtZXRob2QgYXJlIGJleW9uZCB0aGUgc2NvcGUgb2YgdGhpcyByZXBvcnQgYnV0IGl0IGlzIGEgZm9ybSBvZiBkaXJlY3Qgc3RhbmRhcmRpc2F0aW9uIChzZWUgW2hlcmVdIChodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JbnZlcnNlX3Byb2JhYmlsaXR5X3dlaWdodGluZykpLgoKYGBge3IgaW5jbHVkZWQgdmFyaWFibGVzLCBmaWcuaGVpZ2h0PTEyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQoKbGFfcGFyYW0gJT4lCiAgc2VsZWN0KC1Mb2NhbC5BdXRob3JpdHkuQ29kZSkgJT4lCiAgZ3JvdXBfYnkoZGlzZWFzZSwgaW5kaWNhdG9yKSAlPiUKICBzdW1tYXJpc2UoaW5jID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkgJT4lCiAgc3ByZWFkKGRpc2Vhc2UsIGluYykgJT4lIAogIGdhdGhlcihkaXNlYXNlLCB2YWx1ZSwgMjo2KSAlPiUKICBtdXRhdGUodmFsdWUgPSBpZmVsc2UoaXMubmEodmFsdWUpLCAiTm90IGluY2x1ZGVkIiwiSW5jbHVkZWQiKSkgJT4lCiAgZ2dwbG90KGFlcyhpbmRpY2F0b3IsIHZhbHVlKSkgKwogIGdlb21fcG9pbnQoYWVzKHNoYXBlID0gdmFsdWUsIGNvbG91ciA9IHZhbHVlLCBzaXplID0gMTIpKSArCiAgY29vcmRfZmxpcCgpICsKICBmYWNldF93cmFwKH5kaXNlYXNlLCBucm93ID0gMSkgKwogIGxhYnMoeCA9ICIiLCB5ID0gIiIsIHRpdGxlID0gIlZhcmlhYmxlcyBpbmNsdWRlZCBpbiBlYWNoIGRpc2Vhc2UgbW9kZWwiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIiIsIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApKSArCiAgdGhlbWVfYncoKQpgYGAKCgojIFdoYXQgZG8gdGhlIGRhdGEgc2hvdz8KClRoaXMgc2VjdGlvbiBpcyBzcGxpdCBpbnRvIDIgcGFydHM6CgoxLiBMb2NhbCBhdXRob3JpdHkgc3VtbWFyaWVzCjIuIEdlbmVyYWwgcHJhY3RpY2Ugc3VtbWFyaWVzCgoKIyMgTG9jYWwgYXV0aG9yaXR5IGRhdGEKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGNhY2hlPVRSVUV9CgojIyBMb2FkIGxpYnJhcmllcwoKCiMjIExBIGRhdGEgLSBleHRyYWN0LCBjb21iaW5lLCB0aWR5CgpkZXByZXNzLkxBIDwtIHJlYWRfc3RhdGEoIn4vRG9jdW1lbnRzL1JfcHJvamVjdHMvcHJldmFsZW5jZV9lc3RpbWF0ZXMvRGlhZy1kZXByZXNzaW9uLXByZXYtTEEtbGV2ZWwuZHRhIikKCmNoZC5MQSA8LSByZWFkX2V4Y2VsKCJ+L0RvY3VtZW50cy9SX3Byb2plY3RzL3ByZXZhbGVuY2VfZXN0aW1hdGVzL0NWRC13b3JrYm9vay0yMDE2LUxBLXYxLnhsc3giLCAxKSAKY2hkLkxBIDwtIGNoZC5MQSAlPiUgcmVuYW1lKGxhX2NvZGUgPSBgTEEgY29kZWAsIGVzdGltYXRlID0gYFByZXZhbGVuY2UgZXN0aW1hdGVzYCkKCnN0cm9rZS5MQSA8LSByZWFkX2V4Y2VsKCJ+L0RvY3VtZW50cy9SX3Byb2plY3RzL3ByZXZhbGVuY2VfZXN0aW1hdGVzL0NWRC13b3JrYm9vay0yMDE2LUxBLXYxLnhsc3giLCAyKSAKc3Ryb2tlLkxBIDwtIHN0cm9rZS5MQSAlPiUgcmVuYW1lKGxhX2NvZGUgPSBgTEEgY29kZWAsIGVzdGltYXRlID0gYFByZXZhbGVuY2UgZXN0aW1hdGVzYCkKCmR4YnAuTEEgPC0gcmVhZF9leGNlbCgifi9Eb2N1bWVudHMvUl9wcm9qZWN0cy9wcmV2YWxlbmNlX2VzdGltYXRlcy9EaWFnbm9zZWQtaHlwZXJ0ZW5zaW9uLWVzdGltYXRlcy1MQS1sZXZlbC54bHN4IikgCgojIHFvZmJwLkxBIDwtIHJlYWRfZXhjZWwoIn4vRG9jdW1lbnRzL1JfcHJvamVjdHMvcHJldmFsZW5jZV9lc3RpbWF0ZXMvRGlhZ25vc2VkLWh5cGVydGVuc2lvbi1lc3RpbWF0ZXMtcHJhY3RpY2UtbGV2ZWwueGxzeCIsMSkKCiMgdW5keGJwLkxBIDwtIHJlYWRfZXhjZWwoIn4vRG9jdW1lbnRzL1JfcHJvamVjdHMvcHJldmFsZW5jZV9lc3RpbWF0ZXMvVW5kaWFnbm9zZWQtaHlwZXJ0ZW5zaW9uLWVzdGltYXRlcy1wcmFjdGljZS1sZXZlbC54bHN4IikKCiMgc3Ryb2tlMS5MQSA8LSByZWFkX2V4Y2VsKCJ+L0RvY3VtZW50cy9SX3Byb2plY3RzL3ByZXZhbGVuY2VfZXN0aW1hdGVzL1N0cm9rZS1lc3RpbWF0ZWQtcHJldmFsZW5jZS1wcmFjLWxldmVsLXdpdGgtSU1ELnhsc3giKQoKcGFkMWltZC5MQSA8LSByZWFkX2V4Y2VsKCJ+L0RvY3VtZW50cy9SX3Byb2plY3RzL3ByZXZhbGVuY2VfZXN0aW1hdGVzL0NWRC13b3JrYm9vay0yMDE2LUxBLXYxLnhsc3giLCAzKQpwYWQxaW1kLkxBIDwtIHBhZDFpbWQuTEEgJT4lIHJlbmFtZShsYV9jb2RlID0gYExBIGNvZGVgLCBlc3RpbWF0ZSA9IGBQcmV2YWxlbmNlIGVzdGltYXRlc2ApCgpwYWQxX2ltZC5MQSA8LSByZWFkX2V4Y2VsKCJ+L0RvY3VtZW50cy9SX3Byb2plY3RzL3ByZXZhbGVuY2VfZXN0aW1hdGVzL1BBRC1wcmV2YWxlbmNlIGVzdGltYXRlcy9QQUQtcHJldmFsZW5jZS1lc3RpbWF0ZXMtTEEtbGV2ZWwtd2l0aC1JTUQueGxzeCIpCgpjb3BkLkxBIDwtIHJlYWRfZXhjZWwoIn4vRG9jdW1lbnRzL1JfcHJvamVjdHMvcHJldmFsZW5jZV9lc3RpbWF0ZXMvQ09QRC1lc3RpbWF0ZWQtcHJldmFsZW5jZS1MQS1sZXZlbC54bHN4IikKCmxpc3QgPC0gbGlzdChkZXByZXNzLkxBLCBjaGQuTEEsIHN0cm9rZS5MQSwgZHhicC5MQSwgcGFkMV9pbWQuTEEsIHBhZDFpbWQuTEEsIGNvcGQuTEEgKQoKIyMgTG9vayBhdCB0YWJsZSBkaW1lbnN0aW9ucwoKCgpsX2RlcHJlc3MuTEEgPC0gZ2F0aGVyKGRlcHJlc3MuTEEsIGluZGljYXRvciwgdmFsdWUsIDQ6bmNvbChkZXByZXNzLkxBKSkKbF9jaGQuTEEgPC0gZ2F0aGVyKGNoZC5MQSwgaW5kaWNhdG9yLCB2YWx1ZSwgNDpuY29sKGNoZC5MQSkpCmxfc3Ryb2tlLkxBIDwtIGdhdGhlcihzdHJva2UuTEEsIGluZGljYXRvciwgdmFsdWUsIDQ6bmNvbChzdHJva2UuTEEpKQpsX2R4YnAuTEEgPC0gZ2F0aGVyKGR4YnAuTEEsIGluZGljYXRvciwgdmFsdWUsIDQ6bmNvbChkeGJwLkxBKSkKIyBsX3VuZHhicC5MQSA8LSBnYXRoZXIodW5keGJwLkxBLCBpbmRpY2F0b3IsIHZhbHVlLCAyOm5jb2wodW5keGJwLkxBKSkKIyBsX3FvZmJwLkxBIDwtIGdhdGhlcihxb2ZicC5MQSwgaW5kaWNhdG9yLHZhbHVlLCA0Om5jb2wocW9mYnAuTEEpKQojIGxfc3Ryb2tlMS5MQSA8LSBnYXRoZXIoc3Ryb2tlMS5MQSwgaW5kaWNhdG9yLCB2YWx1ZSwgMjpuY29sKHN0cm9rZS5MQSkpCgpsX3BhZDFfaW1kLkxBIDwtIGdhdGhlcihwYWQxX2ltZC5MQSwgaW5kaWNhdG9yLCB2YWx1ZSwgNDpuY29sKHBhZDFfaW1kLkxBKSkKbF9wYWRpbWQxLkxBIDwtIGdhdGhlcihwYWQxaW1kLkxBLCBpbmRpY2F0b3IsIHZhbHVlLCA0Om5jb2wocGFkMWltZC5MQSkpCmxfY29wZC5MQSA8LSBnYXRoZXIoY29wZC5MQSwgaW5kaWNhdG9yLCB2YWx1ZSwgNDpuY29sKGNvcGQuTEEpKQoKIyMgTGFiZWxzCgpsX2RlcHJlc3MuTEEkZGlzZWFzZSA8LSAiZGVwcmVzc2lvbiIKbF9jaGQuTEEkZGlzZWFzZSA8LSAiY2hkIgpsX3N0cm9rZS5MQSRkaXNlYXNlIDwtICJzdHJva2UiCiMgbF9zdHJva2UxLkxBJGRpc2Vhc2UgPC0gInN0cm9rZV9JTUQiCmxfZHhicC5MQSRkaXNlYXNlIDwtICJicCIKIyBsX3VuZHhicC5MQSRkaXNlYXNlIDwtICJ1bmR4X2JwIgojIGxfcW9mYnAuTEEkZGlzZWFzZSA8LSAiYnAiCmxfcGFkMV9pbWQuTEEkZGlzZWFzZSA8LSAicGFkIgpsX3BhZGltZDEuTEEkZGlzZWFzZSA8LSAicGFkX0lNRCIKbF9jb3BkLkxBJGRpc2Vhc2UgPC0gImNvcGQiCgpsaXN0MSA8LSBsaXN0KGxfZGVwcmVzcy5MQSwgbF9jaGQuTEEsIGxfc3Ryb2tlLkxBLCBsX2R4YnAuTEEsIGxfcGFkMV9pbWQuTEEsIGxfcGFkaW1kMS5MQSwgbF9jb3BkLkxBKQoKIyMgQnVpbGQgdGhlIGNvbWJpbmVkIExBIHZhbHVlIHRhYmxlCgoKbGFfYWxsIDwtIGJpbmRfcm93cyhsaXN0MSkKCgpsYV9hbGwkdmFsdWUgPC0gcm91bmQoYXMubnVtZXJpYyhsYV9hbGwkdmFsdWUpLDIpICMjIGNoZWNrIGFuZCByb3VuZCBudW1lcmljIGRhdGEKCiMjIFRoaXMgaXMgYSBsb25nIGZpbGUgd2l0aCBsYSBjb2RlLCB2YWx1ZXMsIGRpc2Vhc2VzIGFuZCBpbmRpY2F0b3JzLiBDaXR5IG9mIExvbmRvbiBpcyBleGNsdWRlZAoKbGFfYWxsIDwtICBsYV9hbGwgJT4lIGZpbHRlcihsYV9jb2RlICE9IkUwOTAwMDAwMSIpICMjIGV4Y2x1ZGUgY2l0eSBvZiBsb25kb24KCgoKIyMgd3JpdGUgZmlsZQoKd3JpdGUuY3N2KGxhX2FsbCwgZmlsZSA9IHBhc3RlMCgibGFfZXN0aW1hdGVzX2xvbmciLCBsdWJyaWRhdGU6OnRvZGF5KCksICIuY3N2IikpCmBgYAoKYGBge3IgY3JlYXRlIHdpZGUgdmVyc2lvbiBhbmQgcHVibGljYXRpb24gc3ByZWFkc2hlZXQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoZHBseXIpCgojIyBJZGVudGlmeSBpbmRpY2F0b3JzIAoKcyA8LSBzcGxpdChsYV9hbGwsIGZhY3RvcihsYV9hbGwkZGlzZWFzZSkpCnMxIDwtIGFzLmRhdGEuZnJhbWUodW5saXN0KGxhcHBseShzLCBmdW5jdGlvbih4KSBsZXZlbHMoZmFjdG9yKHgkaW5kaWNhdG9yKSkpKSkKY29sbmFtZXMoczEpIDwtICJtZWFzdXJlIgoKCiMjIENyZWF0ZSB3aWRlIHZlcnNpb24gb2YganVzdCBlc3RpbWF0ZXMKCmxhX2FsbHcgPC0gbGFfYWxsICU+JSBmaWx0ZXIoaW5kaWNhdG9yID09ICJlc3RpbWF0ZSIpICU+JSBzZWxlY3QobGFfY29kZSwgdmFsdWUsIGRpc2Vhc2UpCgpsYV9hbGx3IDwtIGxhX2FsbHcgJT4lIAogIHRpZHlyOjpzcHJlYWQoZGlzZWFzZSwgdmFsdWUpCgojIyBwcmludCBlc3RpbWF0ZXMKbGFfYWxsdyA8LSBsYV9hbGx3ICU+JQogIHJlbmFtZShIeXBlcnRlbnNpb24gPSBicCwgQ0hEID0gY2hkLCBDT1BEID0gY29wZCwgRGVwcmVzc2lvbiA9IGRlcHJlc3Npb24sIGBQZXJpcGhlcmFsIGFydGVyaWFsIGRpc2Vhc2VgID0gcGFkX0lNRCwgU3Ryb2tlID0gc3Ryb2tlKSAlPiUKICBzZWxlY3QoLXBhZCkKCiMjIHdyaXRlIGZpbGUKCndyaXRlLmNzdihsYV9hbGx3LCBmaWxlID0gcGFzdGUwKCJsYS5lc3RpbWF0ZXMiLCBsdWJyaWRhdGU6OnRvZGF5KCksICIuY3N2IikpCgojIyByZWNvZGVzCgpsYV9hbGwgPC0gbGFfYWxsICU+JSAKICBtdXRhdGUoaW5kaWNhdG9yID0gaWZlbHNlKGluZGljYXRvciA9PSAiTWF4Ljk1JSBDSSJ8IGluZGljYXRvciA9PSAibWF4OTUiLCAibWF4OTUiLCBpbmRpY2F0b3IpKSAlPiUKICBtdXRhdGUoaW5kaWNhdG9yID0gaWZlbHNlKGluZGljYXRvciA9PSAiTWluLjk1JSBDSSJ8IGluZGljYXRvciA9PSAibWluOTUiLCAibWluOTUiLCBpbmRpY2F0b3IpKSU+JQogIGZpbHRlcihpbmRpY2F0b3IgIT0gIjAiKSAlPiUKICBzZWxlY3QoLXBhcm1zZXEsIC1wYXJtKQoKbGExIDwtIGxhX2FsbCAlPiUgCiAgdGlkeXI6OnNwcmVhZChpbmRpY2F0b3IsIHZhbHVlKSAlPiUKICBhcnJhbmdlKGRpc2Vhc2UsIGxhX2NvZGUpICU+JQogIHNlbGVjdCgtYyhkb2YsIHAsIHN0ZGVyciwgdCwgeikpCgojIyBTYXZlIGZpbGUgd2l0aCBjb25maWRlbmNlIGludGVydmFscwp3cml0ZS5jc3YobGExLCBmaWxlID0gcGFzdGUoImxhLmVzdGltYXRlcy53aXRoLmNpIiwgbHVicmlkYXRlOjp0b2RheSgpLCAiLmNzdiIsIHNlcCA9ICJfIikpCgpgYGAKCgojIyMgTWlzc2luZyBkYXRhCgpOb3RlIHRoYXQgdGhlcmUgYXJlIHNvbWUgbWlzc2luZyB2YWx1ZXMgZm9yIExBIGVzdGltYXRlcyBmb3IgaHlwZXJ0ZW5zaW9uLCBDT1BEIGFuZCBkZXByZXNzaW9uIHdoaWNoIHdlIGFyZSB3b3JraW5nIHdpdGggSW1wZXJpYWwgQ29sbGVnZSB0byBmaWxsLgoKCiMjIyBTdW1tYXJ5IHN0YXRpc3RpY3MKCgpgYGB7ciBTdW1tYXJ5IHN0YXRpc3RpY3MsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHM9J2FzaXMnfQpsaWJyYXJ5KGRwbHlyKQpvcHRpb25zKGRpZ2l0cyA9IDMpCmxhX2FsbCAlPiUgCiAgZ3JvdXBfYnkoZGlzZWFzZSkgJT4lCiAgZmlsdGVyKGluZGljYXRvciA9PSAiZXN0aW1hdGUiKSAlPiUKICBzdW1tYXJpc2UobWVhbiA9IHJvdW5kKG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSksIDIpLCAKICAgICAgICAgICAgbWVkaWFuID0gbWVkaWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpLCAKICAgICAgICAgICAgbWluaW11bSAgPSBtaW4odmFsdWUsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIGAxMHRoIGNlbnRpbGVgID0gcm91bmQocXVhbnRpbGUodmFsdWUsIDAuMSwgbmEucm0gPSBUUlVFKSwyKSwgCiAgICAgICAgICAgIGA5MHRoIGNlbnRpbGVgID0gcXVhbnRpbGUodmFsdWUsIDAuOSwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgbWF4aW11bSAgPSBtYXgodmFsdWUsIG5hLnJtID0gVFJVRSkpICU+JQogIGZpbHRlcihkaXNlYXNlICE9ICJwYWRfSU1EIikgJT4lCiAga25pdHI6OmthYmxlKGZvcm1hdCA9ICJwYW5kb2MiLCBjYXB0aW9uICA9ICJTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIExBIGRhdGEiKQoKYGBgCgoKIyMgUGxvdHMKCmBgYHtyIENhdGVycGlsbGFyIHBsb3RzLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD02LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIyBQbG90IGVzaW1hdGVzIGFzIGNhdGVycGlsbGFyIHBsb3RzCgpsaWJyYXJ5KGdncGxvdDIpCgpnMSA8LSBnZ3Bsb3QoZmlsdGVyKGxhMSwgZGlzZWFzZSA9PSAiY2hkIiksIGFlcyhyZW9yZGVyKGxhX2NvZGUsIGVzdGltYXRlKSwgZXN0aW1hdGUpKSArIAogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBtaW45NSwgeW1heD0gbWF4OTUpLCBjb2xvdXIgPSAibGlnaHRncmV5IikgKwogICAgZ2VvbV9wb2ludChjb2xvdXIgPSAiYmxhY2siKSArICAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBzaXplID0gMCkpICsKICBsYWJzKHkgPSAiUHJldmFsZW5jZSAlIiwgeD0gIiIpICsKICBnZ3RpdGxlKCJDSEQiKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSkKCmcyIDwtIGdncGxvdChmaWx0ZXIobGExLCBkaXNlYXNlID09ICJzdHJva2UiKSwgYWVzKHJlb3JkZXIobGFfY29kZSwgZXN0aW1hdGUpLCBlc3RpbWF0ZSkpICsgICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gbWluOTUsIHltYXg9IG1heDk1KSwgY29sb3VyID0gImxpZ2h0Z3JleSIpICsKICAgIGdlb21fcG9pbnQoY29sb3VyID0gImJsYWNrIikgKyAgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgc2l6ZSA9IDApKSArCiAgbGFicyh5ID0gIlByZXZhbGVuY2UgJSIsIHg9ICIiKSArCiAgZ2d0aXRsZSgiU3Ryb2tlIikgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCkpCgpnMyA8LSBnZ3Bsb3QoZmlsdGVyKGxhMSwgZGlzZWFzZSA9PSAicGFkIiksIGFlcyhyZW9yZGVyKGxhX2NvZGUsIGVzdGltYXRlKSwgZXN0aW1hdGUpKSArIAogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBtaW45NSwgeW1heD0gbWF4OTUpLCBjb2xvdXIgPSAibGlnaHRncmV5IikgKwogICAgZ2VvbV9wb2ludChjb2xvdXIgPSAiYmxhY2siKSArICAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBzaXplID0gMCkpICsKICBsYWJzKHkgPSAiUHJldmFsZW5jZSAlIiwgeD0gIiIpICsKICBnZ3RpdGxlKCJQZXJpcGhlcmFsIGFydGVyaWFsIGRpc2Vhc2UiKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSkKCmc0IDwtIGdncGxvdChmaWx0ZXIobGExLCBkaXNlYXNlID09ICJicCIpLCBhZXMocmVvcmRlcihsYV9jb2RlLCBlc3RpbWF0ZSksIGVzdGltYXRlKSkgKyAKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gbWluOTUsIHltYXg9IG1heDk1KSwgY29sb3VyID0gImxpZ2h0Z3JleSIpICsKICAgIGdlb21fcG9pbnQoY29sb3VyID0gImJsYWNrIikgKyAgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgc2l6ZSA9IDApKSArCiAgbGFicyh5ID0gIlByZXZhbGVuY2UgJSIsIHg9ICIiKSArCiAgZ2d0aXRsZSgiSHlwZXJ0ZW5zaW9uIikgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCkpCgpnNSA8LSBnZ3Bsb3QoZmlsdGVyKGxhMSwgZGlzZWFzZSA9PSAiY29wZCIpLCBhZXMocmVvcmRlcihsYV9jb2RlLCBlc3RpbWF0ZSksIGVzdGltYXRlKSkgKyAKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gbWluOTUsIHltYXg9IG1heDk1KSwgY29sb3VyID0gImxpZ2h0Z3JleSIpICsKICAgIGdlb21fcG9pbnQoY29sb3VyID0gImJsYWNrIikgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIHNpemUgPSAwKSkgKwogIGxhYnMoeSA9ICJQcmV2YWxlbmNlICUiLCB4PSAiTG9jYWwgYXV0aG9yaXR5IikgKwogIGdndGl0bGUoIkNPUEQiKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSkKCmc2IDwtIGdncGxvdChmaWx0ZXIobGExLCBkaXNlYXNlID09ICJkZXByZXNzaW9uIiksIGFlcyhyZW9yZGVyKGxhX2NvZGUsIGVzdGltYXRlKSwgZXN0aW1hdGUpKSArIAogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBtaW45NSwgeW1heD0gbWF4OTUpLCBjb2xvdXIgPSAibGlnaHRncmV5IikgKwogICAgZ2VvbV9wb2ludChjb2xvdXIgPSAiYmxhY2siKSArICAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBzaXplID0gMCkpICsKICBsYWJzKHkgPSAiUHJldmFsZW5jZSAlIiwgeD0gIkxvY2FsIGF1dGhvcml0eSIpICsKICBnZ3RpdGxlKCJEZXByZXNzaW9uIikgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCkpCgpncmlkRXh0cmE6OmdyaWQuYXJyYW5nZShnMSwgZzIsIGczLCBnNCwgZzUsIGc2LCBuY29sID0gMikKYGBgCgoKIyMgTWFwcwoKCgpgYGB7ciBNYXBzLCBldmFsID0gRkFMU0UsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KHRtYXApKQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeShyZ2RhbCkpCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KHJnZW9zKSkKCnRlbXAgPC0gdGVtcGZpbGUoKQpkb3dubG9hZC5maWxlKCJodHRwOi8vZ2VvcG9ydGFsLnN0YXRpc3RpY3MuZ292LnVrL2RhdGFzZXRzLzhlZGFmYmUzMjc2ZDRiNTZhZWM2MDk5MWNiZGRkYTUwXzMuemlwIiwgdGVtcCwgbW9kZSA9ICJ3YiIpCnVuemlwKHRlbXAsIGV4ZGlyID0gZ2V0d2QoKSkKCnMgPC0gcmVhZE9HUihkc24gPSAiTG9jYWxfQXV0aG9yaXR5X0Rpc3RyaWN0c19EZWNlbWJlcl8yMDE1X1N1cGVyX0dlbmVyYWxpc2VkX0NsaXBwZWRfQm91bmRhcmllc19pbl9HcmVhdF9Ccml0YWluLnNocCIsIGxheWVyID0gIkxvY2FsX0F1dGhvcml0eV9EaXN0cmljdHNfRGVjZW1iZXJfMjAxNV9TdXBlcl9HZW5lcmFsaXNlZF9DbGlwcGVkX0JvdW5kYXJpZXNfaW5fR3JlYXRfQnJpdGFpbiIsIHZlcmJvc2UgPSBGQUxTRSkKCmBgYAoKCiMjIyBDSEQKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQoKCnNlbmcgPC0gc3Vic2V0KHMsIHN1YnN0cihsYWQxNWNkLCAxLCAxKSA9PSAiRSIpCnNlbmdAZGF0YSA8LSBsZWZ0X2pvaW4oc2VuZ0BkYXRhLCBjaGQuTEEsIGJ5PWMoImxhZDE1Y2QiID0gImxhX2NvZGUiKSkKc2VuZ0BkYXRhJGNvdW50cnkgPC0gIkVuZyIKCiMjIEdldCBvdXRsaW5lCkVuZyA8LSBnVW5hcnlVbmlvbihzZW5nLCBpZCA9IHNlbmdAZGF0YSRjb3VudHJ5KQpidWYgPC0gZ0J1ZmZlcihFbmcsIHdpZHRoID0gMC4wMDEpCgpncmlkIDwtICIraW5pdD1lcHNnOjI3NzAwIgpsYXRsb25nIDwtICIraW5pdD1lcHNnOjQzMjYiCgojIyBDSEQKdG1fc2hhcGUoc2VuZykgKwogIHRtX2ZpbGwoImVzdGltYXRlIiwgc3R5bGUgPSAicXVhbnRpbGUiLCBuID0gMTAsCiAgICAgICAgICBwYWxldHRlID0gIkdyZWVucyIsIHRpdGxlID0gIlByZXZhbGVuY2U6IENIRCAoJSkiKSArCiAgdG1fYm9yZGVycyhjb2wgPSAid2hpdGUiKSArCiAgdG1fbGF5b3V0KCJDSEQiLCAKICAgICAgICAgICAgbGVnZW5kLm91dHNpZGUgPSBUUlVFLCAKICAgICAgICAgICAgZnJhbWUgPSBGQUxTRSkgKwogIHRtX2NyZWRpdHMoIkNvbnRhaW5zIG9yZG5hbmNlIHN1cnZleSBkYXRhIChjKSBcbkNyb3duIGNvcHlyaWdodCBhbmQgZGF0YWJhc2UgcmlnaHQgMjAxNiIsIHNpemUgPSAwLjcsIGFsaWduID0gInJpZ2h0IikKCgpybShzZW5nKQpgYGAKCiMjIyBEZXByZXNzaW9uCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpzZW5nIDwtIHN1YnNldChzLCBzdWJzdHIobGFkMTVjZCwgMSwgMSkgPT0gIkUiKQpzZW5nQGRhdGEgPC0gbGVmdF9qb2luKHNlbmdAZGF0YSwgZGVwcmVzcy5MQSwgYnk9YygibGFkMTVjZCIgPSAibGFfY29kZSIpKQpzZW5nQGRhdGEkY291bnRyeSA8LSAiRW5nIgoKIyMgR2V0IG91dGxpbmUKRW5nIDwtIGdVbmFyeVVuaW9uKHNlbmcsIGlkID0gc2VuZ0BkYXRhJGNvdW50cnkpCmJ1ZiA8LSBnQnVmZmVyKEVuZywgd2lkdGggPSAwLjAwMSkKCmdyaWQgPC0gIitpbml0PWVwc2c6Mjc3MDAiCmxhdGxvbmcgPC0gIitpbml0PWVwc2c6NDMyNiIKCiMgQ1JTKCIraW5pdD1lcHNnOjI3NzAwIikKIyBDUlMoIitpbml0PWVwc2c6NDMyNiIpCgp0bV9zaGFwZShzZW5nKSArCiAgdG1fZmlsbCgiZXN0aW1hdGUiLCBzdHlsZSA9ICJxdWFudGlsZSIsIG4gPSAxMCwKICAgICAgICAgIHBhbGV0dGUgPSAiR3JlZW5zIiwgdGl0bGUgPSAiRGVwcmVzc2lvbiAoJSkiKSArCiAgdG1fYm9yZGVycyhjb2wgPSAid2hpdGUiKSArCiAgdG1fbGF5b3V0KCJEZXByZXNzaW9uIiwgCiAgICAgICAgICAgIGxlZ2VuZC5vdXRzaWRlID0gVFJVRSwKICAgICAgICAgICAgZnJhbWUgPSBGQUxTRSkgKwogIHRtX2NyZWRpdHMoIkNvbnRhaW5zIG9yZG5hbmNlIHN1cnZleSBkYXRhIChjKSBcbkNyb3duIGNvcHlyaWdodCBhbmQgZGF0YWJhc2UgcmlnaHQgMjAxNiIsIHNpemUgPSAwLjcsIGFsaWduID0gInJpZ2h0IikKCgpybShzZW5nKQpgYGAKCiMjIyBDT1BECgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0Kc2VuZyA8LSBzdWJzZXQocywgc3Vic3RyKGxhZDE1Y2QsIDEsIDEpID09ICJFIikKc2VuZ0BkYXRhIDwtIGxlZnRfam9pbihzZW5nQGRhdGEsIGNvcGQuTEEsIGJ5PWMoImxhZDE1Y2QiID0gImxhX2NvZGUiKSkKc2VuZ0BkYXRhJGNvdW50cnkgPC0gIkVuZyIKCiMjIEdldCBvdXRsaW5lCkVuZyA8LSBnVW5hcnlVbmlvbihzZW5nLCBpZCA9IHNlbmdAZGF0YSRjb3VudHJ5KQoKYnVmIDwtIGdCdWZmZXIoRW5nLCB3aWR0aCA9IDAuMDAxKQoKIyBDUlMoIitpbml0PWVwc2c6Mjc3MDAiKQojIENSUygiK2luaXQ9ZXBzZzo0MzI2IikKCnRtX3NoYXBlKHNlbmcpICsKICB0bV9maWxsKCJlc3RpbWF0ZSIsIHN0eWxlID0gInF1YW50aWxlIiwgbiA9IDEwLCAKICAgICAgICAgIHBhbGV0dGUgPSAiR3JlZW5zIiwgdGl0bGUgPSAiUHJldmFsZW5jZTogQ09QRCAoJSkiKSArCiAgdG1fYm9yZGVycyhjb2wgPSAid2hpdGUiKSArCiAgdG1fbGF5b3V0KCJDT1BEIiwgCiAgICAgICAgICAgIGxlZ2VuZC5vdXRzaWRlID0gVFJVRSwgCiAgICBmcmFtZSA9IEZBTFNFKSArCiAgdG1fY3JlZGl0cygiQ29udGFpbnMgb3JkbmFuY2Ugc3VydmV5IGRhdGEgKGMpIFxuQ3Jvd24gY29weXJpZ2h0IGFuZCBkYXRhYmFzZSByaWdodCAyMDE2Iiwgc2l6ZSA9IDAuNywgYWxpZ24gPSAicmlnaHQiKQoKCnJtKHNlbmcpCmBgYAoKCiMjIyBTdHJva2UKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpzZW5nIDwtIHN1YnNldChzLCBzdWJzdHIobGFkMTVjZCwgMSwgMSkgPT0gIkUiKQpzZW5nQGRhdGEgPC0gbGVmdF9qb2luKHNlbmdAZGF0YSwgc3Ryb2tlLkxBLCBieT1jKCJsYWQxNWNkIiA9ICJsYV9jb2RlIikpCnNlbmdAZGF0YSRjb3VudHJ5IDwtICJFbmciCgojIyBHZXQgb3V0bGluZQpFbmcgPC0gZ1VuYXJ5VW5pb24oc2VuZywgaWQgPSBzZW5nQGRhdGEkY291bnRyeSkKYnVmIDwtIGdCdWZmZXIoRW5nLCB3aWR0aCA9IDAuMDAxKQoKIyBDUlMoIitpbml0PWVwc2c6Mjc3MDAiKQojIENSUygiK2luaXQ9ZXBzZzo0MzI2IikKCnRtX3NoYXBlKHNlbmcpICsKICB0bV9maWxsKCJlc3RpbWF0ZSIsIHN0eWxlID0gInF1YW50aWxlIiwgbiA9MTAsIAogICAgICAgICAgcGFsZXR0ZSA9ICJHcmVlbnMiLCB0aXRsZSA9ICJQcmV2YWxlbmNlOiBTdHJva2UgKCUpIikgKwogIHRtX2JvcmRlcnMoY29sID0gIndoaXRlIikgKwogIHRtX2xheW91dCgiU3Ryb2tlIiwKICAgICAgICAgICAgbGVnZW5kLm91dHNpZGUgPSBUUlVFLCAKICAgICAgICAgICAgZnJhbWUgPSBGQUxTRSkgKwogIHRtX2NyZWRpdHMoIkNvbnRhaW5zIG9yZG5hbmNlIHN1cnZleSBkYXRhIChjKSBcbkNyb3duIGNvcHlyaWdodCBhbmQgZGF0YWJhc2UgcmlnaHQgMjAxNiIsIHNpemUgPSAwLjcsIGFsaWduID0gInJpZ2h0IikKCgoKcm0oc2VuZykKYGBgCgojIyMgSHlwZXJ0ZW5zaW9uCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0Kc2VuZyA8LSBzdWJzZXQocywgc3Vic3RyKGxhZDE1Y2QsIDEsIDEpID09ICJFIikKc2VuZ0BkYXRhIDwtIGxlZnRfam9pbihzZW5nQGRhdGEsIGR4YnAuTEEsIGJ5PWMoImxhZDE1Y2QiID0gImxhX2NvZGUiKSkKc2VuZ0BkYXRhJGNvdW50cnkgPC0gIkVuZyIKCiMjIEdldCBvdXRsaW5lCkVuZyA8LSBnVW5hcnlVbmlvbihzZW5nLCBpZCA9IHNlbmdAZGF0YSRjb3VudHJ5KQpidWYgPC0gZ0J1ZmZlcihFbmcsIHdpZHRoID0gMC4wMDEpCgojIENSUygiK2luaXQ9ZXBzZzoyNzcwMCIpCiMgQ1JTKCIraW5pdD1lcHNnOjQzMjYiKQoKdG1fc2hhcGUoc2VuZykgKwogIHRtX2ZpbGwoImVzdGltYXRlIiwgc3R5bGUgPSAicXVhbnRpbGUiLCBuID0gMTAsIAogICAgICAgICAgcGFsZXR0ZSA9ICJHcmVlbnMiLCB0aXRsZSA9ICJQcmV2YWxlbmNlOiBIeXBlcnRlbnNpb24gKCUpIikgKwogIHRtX2JvcmRlcnMoY29sID0gIndoaXRlIikgKwogIHRtX2xheW91dCgiSHlwZXJ0ZW5zaW9uIiwKICAgICAgICAgICAgbGVnZW5kLnRpdGxlLnNpemUgPSAwLjUsIAogICAgICAgICAgICBmcmFtZSA9IEZBTFNFLCAKICAgICAgICAgICAgbGVnZW5kLm91dHNpZGUgPSBUUlVFKSArCiAgdG1fY3JlZGl0cygiQ29udGFpbnMgb3JkbmFuY2Ugc3VydmV5IGRhdGEgKGMpIFxuQ3Jvd24gY29weXJpZ2h0IGFuZCBkYXRhYmFzZSByaWdodCAyMDE2Iiwgc2l6ZSA9IDAuNSwgYWxpZ24gPSAicmlnaHQiKQoKcm0oc2VuZykKYGBgCgoKIyMjIFBlcmlwaGVyYWwgYXJ0ZXJpYWwgZGlzZWFzZQoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CgpzZW5nIDwtIHN1YnNldChzLCBzdWJzdHIobGFkMTVjZCwgMSwgMSkgPT0gIkUiKQpzZW5nQGRhdGEgPC0gbGVmdF9qb2luKHNlbmdAZGF0YSwgcGFkMWltZC5MQSwgYnk9YygibGFkMTVjZCIgPSAibGFfY29kZSIpKQpzZW5nQGRhdGEkY291bnRyeSA8LSAiRW5nIgoKCkVuZyA8LSBnVW5hcnlVbmlvbihzZW5nLCBpZCA9IHNlbmdAZGF0YSRjb3VudHJ5KQpidWYgPC0gZ0J1ZmZlcihFbmcsIHdpZHRoID0gMC4wMDEpCgojIENSUygiK2luaXQ9ZXBzZzoyNzcwMCIpCiMgQ1JTKCIraW5pdD1lcHNnOjQzMjYiKQoKdG1fc2hhcGUoc2VuZykgKwogIHRtX2ZpbGwoImVzdGltYXRlIiwgc3R5bGUgPSAicXVhbnRpbGUiLCBuID0gMTAsIAogICAgICAgICAgcGFsZXR0ZSA9ICJHcmVlbnMiLCB0aXRsZSA9ICJQcmV2YWxlbmNlOiBQQUQgKCUpIikgKwogIHRtX2JvcmRlcnMoY29sID0gIndoaXRlIikgKwogIHRtX2xheW91dChmcmFtZSA9IEZBTFNFLCAKICAgICAgICAgICAgbGVnZW5kLm91dHNpZGUgPSBUUlVFLAogICAgICAgICAgICAiUGVyaXBoZXJhbCBhcnRlcmlhbCBcbmRpc2Vhc2UiKSArCiAgdG1fY3JlZGl0cygiQ29udGFpbnMgb3JkbmFuY2Ugc3VydmV5IGRhdGEgKGMpIFxuQ3Jvd24gY29weXJpZ2h0IGFuZCBkYXRhYmFzZSByaWdodCAyMDE2Iiwgc2l6ZSA9IDAuNSwgYWxpZ24gPSAicmlnaHQiKQoKIyB0bGV0NQojIAojIGdyaWRFeHRyYTo6Z3JpZC5hcnJhbmdlKHRsZXQsIHRsZXQxLCB0bGV0MiwgdGxldDMsIHRsZXQ0LCB0bGV0NSwgbmNvbCA9IDIpCgoKcm0oc2VuZykKYGBgCgoKCiMgR1AgZGF0YQoKYGBge3IgR1AgZGF0YSBpbXBvcnQsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTYsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGNhY2hlPSBUUlVFfQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KGRhdGEudGFibGUpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShkcGx5cikKbGlicmFyeShzdHJpbmdyKQpsaWJyYXJ5KGdnYmVlc3dhcm0pCmxpYnJhcnkoamFuaXRvcikKCmdwMSA8LSAgcmVhZF9jc3YoImdwLmVzdGltYXRlczIwMTYtMTAtMjcuY3N2IikgJT4lIGNsZWFuX25hbWVzKCkKIyNncDIgPC0gcmVhZF9jc3YoImdwLmVzdGltYXRlc19sb25nMjAxNi0xMC0yNy5jc3YiKSAlPiUgY2xlYW5fbmFtZXMoKQoKCiMgZ3AkaW5kaWNhdG9yIDwtIHN0cl9yZXBsYWNlKGdwJGluZGljYXRvciwgInVuZHhfIiwgInVuZHgiKQojIGdwJGluZGljYXRvciA8LSBzdHJfcmVwbGFjZShncCRpbmRpY2F0b3IsICJzdHJva2VfIiwgInN0cm9rZSIpCgojIGdwIDwtIGdwICU+JSAKIyAgIGZpbHRlcihpbmRpY2F0b3IgIT0gIkNDR2dlb2djb2RlIikgJT4lCiMgICBzZXBhcmF0ZShpbmRpY2F0b3IsIGMoImRpc2Vhc2UiLCAibWV0cmljIikpIAojIAojIGdwJHZhbHVlIDwtIGFzLm51bWVyaWMoZ3AkdmFsdWUpCgpncCAlPiUKICBzcHJlYWQobWV0cmljLCB2YWx1ZSkgJT4lCiAgbXV0YXRlKHFvZnByZXYgPSAxMDAgKiBxb2ZwcmV2KSAtPiBncDJfd2lkZQoKd3JpdGVfY3N2KGdwMl93aWRlLCAiZ3AyX3dpZGUuY3N2IikKCmBgYAoKV2UgaGF2ZSBiZWVuIGFibGUgdG8gZXN0aW1hdGUgcHJldmFsZW5jZSBmb3IgIGByIG5yb3coZ3AyX3dpZGUpYCBwcmFjdGljZXMuCgpGaWcgeCBzaG93cyB0aGUgdmFyaWF0aW9uIGluIHByYWN0aWNlIGxldmVsIGRpc2Vhc2UgZXN0aW1hdGVzIGJ5IHJlZ2lvbi4gVGhpcyBzdWdnZXN0cyBkaXNlYXNlIHByZXZhbGVuY2UgdGVuZHMgdG8gYmUgbG93ZXN0IGluIExvbmRvbiBhbmQgaGlnaGVzdCBpbiB0aGUgTm9ydGggRWFzdCBhbmQgdGhlIE5vcnRoIFdlc3QuCgpgYGB7ciByZWdpb25hbCB2YXJpYXRpb24sIGZpZy5oZWlnaHQ9NiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KCmdwMl93aWRlICU+JQogIGZpbHRlcighZGlzZWFzZSAlaW4lIGMoInN0cm9rZUlNRCIsICJ1bmR4YnAiKSAmICFpcy5uYShgMjAxMXJlZ2lvbm5hbWVgKSkgJT4lIAogIGdncGxvdChhZXMoYDIwMTFyZWdpb25uYW1lYCwgZXN0aW1hdGUsIGZpbGwgPSBkaXNlYXNlKSkgKyAKICBnZW9tX2JveHBsb3QoKSArIAogIGNvb3JkX2ZsaXAoKSArCiAgbGFicyh4ID0gIiIpKyAKICBmYWNldF93cmFwKH5kaXNlYXNlLCBzY2FsZXMgPSAiZnJlZSIpICsKICBsYWJzKHRpdGxlID0gIlZhcmlhdGlvbiBpbiBwcmFjdGljZSBsZXZlbCBlc3RpbWF0ZXMgZm9yIGVhY2ggZGllc2FzZSBhcmVhIGJ5IHJlZ2lvbiIsIAogICAgICAgeSA9ICJQcmV2YWxlbmNlICglKSIpCiAgCgpgYGAKCgojIyMgSHlwZXJ0ZW5zaW9uCgpUaGUgYXZlcmFnZSBlc3RpbWF0ZWQgcHJldmFsZW5jZSBvZiBoeXBlcnRlbnNpb24gaXMgYHIgcm91bmQoZ3AyX3dpZGUgJT4lIGZpbHRlcihkaXNlYXNlID09ICdicCcpICU+JSBzdW1tYXJpc2UobWVhbihlc3RpbWF0ZSwgbmEucm0gPSBUUlVFKSksMikgJT4lIGxpc3RgJSBhbmQgdmFyaWVzIGZyb20gYHIgcm91bmQoZ3AyX3dpZGUgJT4lIGZpbHRlcihkaXNlYXNlID09ICdicCcpICU+JSBzdW1tYXJpc2UobWluKGVzdGltYXRlLCBuYS5ybSA9IFRSVUUpKSwyKSAlPiUgbGlzdGAlIGluIGluIHRoZSBwcmFjdGljZSB3aXRoIHRoZSBsb3dlc3QgdmFsdWUgdG8gYHIgcm91bmQoZ3AyX3dpZGUgJT4lIGZpbHRlcihkaXNlYXNlID09ICdicCcpICU+JSBzdW1tYXJpc2UobWF4KGVzdGltYXRlLCBuYS5ybSA9IFRSVUUpKSwyKSAlPiUgbGlzdGAlIGluIHRoZSBwcmFjdGljZSB3aXRoIHRoZSBoaWdoZXN0LgoKCmBgYHtyIEh5cGVydGVuc2lvbiB2cyBRT0YsIGZpZy5jYXBzID0gVFJVRSwgIGNhY2hlPSBUUlVFfQoKbGlicmFyeShCbGFuZEFsdG1hbkxlaCkKbGlicmFyeShqYW5pdG9yKQoKYSA8LSBncDJfd2lkZSAlPiUKICBmaWx0ZXIoZGlzZWFzZSA9PSAiYnAiKSAlPiUKICBnZ3Bsb3QoYWVzKHJlb3JkZXIocHJhY3RpY2VfY29kZSwgZXN0aW1hdGUpLCBlc3RpbWF0ZSkpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gbWluOTUsIHltYXggPSBtYXg5NSksIGNvbG91ciA9ICJsaWdodGdyZXkiLCBhbHBoYSA9IDAuNCkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9wb2ludChhZXMoeSA9IHFvZnByZXYpLCBjb2xvdXIgPSAicmVkIiwgc2l6ZSA9IDAuNSwgYWxwaGEgPSAwLjUpICsKICBsYWJzKHggPSAiIiwgCiAgICAgICB5ID0gIlByZXZhbGVuY2UgZXN0aW1hdGUgKCUpIikrCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBOVUxMKSArCiAgdGhlbWUoYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpKQoKYiA8LSBxcGxvdChkYXRhID0gZ3AxLCBicF9lc3RpbWF0ZSwgMTAwICogYnBfcW9mcHJldiwgZ2VvbSA9ICJwb2ludCIpICsgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikKCmMgPC0gYmxhbmQuYWx0bWFuLnBsb3QoZ3AxJGJwX2VzdGltYXRlLCAxMDAqZ3AxJGJwX3FvZnByZXYsIGdyYXBoLnN5cyA9ICJnZ3Bsb3QyIikgCmdyaWRFeHRyYTo6Z3JpZC5hcnJhbmdlKGEsYixjLCBuY29sID0gMikKCiAgCmBgYAoKCiMjIyBDT1BECgoKVGhlIGF2ZXJhZ2UgZXN0aW1hdGVkIHByZXZhbGVuY2Ugb2YgQ09QRCBpcyBgciByb3VuZChncDJfd2lkZSAlPiUgZmlsdGVyKGRpc2Vhc2UgPT0gJ2NvcGQnKSAlPiUgc3VtbWFyaXNlKG1lYW4oZXN0aW1hdGUsIG5hLnJtID0gVFJVRSkpLDIpICU+JSBsaXN0YCUgYW5kIHZhcmllcyBmcm9tIGByIHJvdW5kKGdwMl93aWRlICU+JSBmaWx0ZXIoZGlzZWFzZSA9PSAnY29wZCcpICU+JSBzdW1tYXJpc2UobWluKGVzdGltYXRlLCBuYS5ybSA9IFRSVUUpKSwyKSAlPiUgbGlzdGAlIGluIGluIHRoZSBwcmFjdGljZSB3aXRoIHRoZSBsb3dlc3QgdmFsdWUgdG8gYHIgcm91bmQoZ3AyX3dpZGUgJT4lIGZpbHRlcihkaXNlYXNlID09ICdjb3BkJykgJT4lIHN1bW1hcmlzZShtYXgoZXN0aW1hdGUsIG5hLnJtID0gVFJVRSkpLDIpICU+JSBsaXN0YCUgaW4gdGhlIHByYWN0aWNlIHdpdGggdGhlIGhpZ2hlc3QuCgoKYGBge3IgQ09QRCB2cyBRT0YsIGZpZy5jYXBzID0gVFJVRSwgIGNhY2hlPSBUUlVFfQoKbGlicmFyeShCbGFuZEFsdG1hbkxlaCkKbGlicmFyeShqYW5pdG9yKQoKYSA8LSBncDJfd2lkZSAlPiUKICBmaWx0ZXIoZGlzZWFzZSA9PSAiY29wZCIpICU+JQogIGdncGxvdChhZXMocmVvcmRlcihwcmFjdGljZV9jb2RlLCBlc3RpbWF0ZSksIGVzdGltYXRlKSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBtaW45NSwgeW1heCA9IG1heDk1KSwgY29sb3VyID0gImxpZ2h0Z3JleSIsIGFscGhhID0gMC40KSArCiAgZ2VvbV9wb2ludChzaXplID0gMC41KSArCiAgZ2VvbV9wb2ludChhZXMoeSA9IHFvZnByZXYvMTAwKSwgY29sb3VyID0gInJlZCIsIHNpemUgPSAwLjUsIGFscGhhID0gMC4xKSArCiAgbGFicyh4ID0gIiIsIAogICAgICAgeSA9ICJQcmV2YWxlbmNlIGVzdGltYXRlICglKSIpKwogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gTlVMTCkgKwogIHRoZW1lKGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSkKCmIgPC0gcXBsb3QoZGF0YSA9IGdwMSwgY29wZF9lc3RpbWF0ZSwgY29wZF9xb2ZwcmV2LCBnZW9tID0gInBvaW50IikgKyBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKQoKYyA8LSBibGFuZC5hbHRtYW4ucGxvdChncDEkY29wZF9lc3RpbWF0ZSwgZ3AxJGNvcGRfcW9mcHJldiwgZ3JhcGguc3lzID0gImdncGxvdDIiKSAKZ3JpZEV4dHJhOjpncmlkLmFycmFuZ2UoYSxiLGMsIG5jb2wgPSAyKQoKICAKYGBgCgojIyMgRGVwcmVzc3Npb24KClRoZSBhdmVyYWdlIGVzdGltYXRlZCBwcmV2YWxlbmNlIG9mIGRlcHJlc3Npb24gaXMgYHIgcm91bmQoZ3AyX3dpZGUgJT4lIGZpbHRlcihkaXNlYXNlID09ICdicCcpICU+JSBzdW1tYXJpc2UobWVhbihlc3RpbWF0ZSwgbmEucm0gPSBUUlVFKSksMikgJT4lIGxpc3RgJSBhbmQgdmFyaWVzIGZyb20gYHIgcm91bmQoZ3AyX3dpZGUgJT4lIGZpbHRlcihkaXNlYXNlID09ICdicCcpICU+JSBzdW1tYXJpc2UobWluKGVzdGltYXRlLCBuYS5ybSA9IFRSVUUpKSwyKSAlPiUgbGlzdGAlIGluIGluIHRoZSBwcmFjdGljZSB3aXRoIHRoZSBsb3dlc3QgdmFsdWUgdG8gYHIgcm91bmQoZ3AyX3dpZGUgJT4lIGZpbHRlcihkaXNlYXNlID09ICdicCcpICU+JSBzdW1tYXJpc2UobWF4KGVzdGltYXRlLCBuYS5ybSA9IFRSVUUpKSwyKSAlPiUgbGlzdGAlIGluIHRoZSBwcmFjdGljZSB3aXRoIHRoZSBoaWdoZXN0LgoKYGBge3IgZGVwcmVzc2lvbiB2cyBRT0YsIGZpZy5jYXBzID0gVFJVRSwgIGNhY2hlPSBUUlVFfQoKbGlicmFyeShCbGFuZEFsdG1hbkxlaCkKbGlicmFyeShqYW5pdG9yKQoKYSA8LSBncDJfd2lkZSAlPiUKICBmaWx0ZXIoZGlzZWFzZSA9PSAiZGVwcmVzc2lvbiIpICU+JQogIGdncGxvdChhZXMocmVvcmRlcihwcmFjdGljZV9jb2RlLCBlc3RpbWF0ZSksIGVzdGltYXRlKSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBtaW45NSwgeW1heCA9IG1heDk1KSwgY29sb3VyID0gImxpZ2h0Z3JleSIsIGFscGhhID0gMC40KSArCiAgZ2VvbV9wb2ludChzaXplID0gMC41KSArCiAgZ2VvbV9wb2ludChhZXMoeSA9IHFvZnByZXYvMTAwKSwgY29sb3VyID0gInJlZCIsIHNpemUgPSAwLjUsIGFscGhhID0gMC4xKSArCiAgbGFicyh4ID0gIiIsIAogICAgICAgeSA9ICJQcmV2YWxlbmNlIGVzdGltYXRlICglKSIpKwogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gTlVMTCkgKwogIHRoZW1lKGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSkKCmIgPC0gcXBsb3QoZGF0YSA9IGdwMSwgZGVwcmVzc2lvbl9lc3RpbWF0ZSwgZGVwcmVzc2lvbl9xb2ZwcmV2LCBnZW9tID0gInBvaW50IikgKyBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKQoKYyA8LSBibGFuZC5hbHRtYW4ucGxvdChncDEkZGVwcmVzc2lvbl9lc3RpbWF0ZSwgZ3AxJGRlcHJlc3Npb25fcW9mcHJldiwgZ3JhcGguc3lzID0gImdncGxvdDIiKSAKZ3JpZEV4dHJhOjpncmlkLmFycmFuZ2UoYSxiLGMsIG5jb2wgPSAyKQoKICAKYGBgCgojIyMgQ29yb25hcnkgaGVhcnQgZGlzZWFzZQoKVGhlIGF2ZXJhZ2UgZXN0aW1hdGVkIHByZXZhbGVuY2Ugb2YgQ0hEIGlzIGByIHJvdW5kKGdwMl93aWRlICU+JSBmaWx0ZXIoZGlzZWFzZSA9PSAnY2hkJykgJT4lIHN1bW1hcmlzZShtZWFuKGVzdGltYXRlLCBuYS5ybSA9IFRSVUUpKSwyKSAlPiUgbGlzdGAlIGFuZCB2YXJpZXMgZnJvbSBgciByb3VuZChncDJfd2lkZSAlPiUgZmlsdGVyKGRpc2Vhc2UgPT0gJ2NoZCcpICU+JSBzdW1tYXJpc2UobWluKGVzdGltYXRlLCBuYS5ybSA9IFRSVUUpKSwyKSAlPiUgbGlzdGAlIGluIGluIHRoZSBwcmFjdGljZSB3aXRoIHRoZSBsb3dlc3QgdmFsdWUgdG8gYHIgcm91bmQoZ3AyX3dpZGUgJT4lIGZpbHRlcihkaXNlYXNlID09ICdjaGQnKSAlPiUgc3VtbWFyaXNlKG1heChlc3RpbWF0ZSwgbmEucm0gPSBUUlVFKSksMikgJT4lIGxpc3RgJSBpbiB0aGUgcHJhY3RpY2Ugd2l0aCB0aGUgaGlnaGVzdC4KCmBgYHtyIGNoZCB2cyBRT0YsIGZpZy5jYXBzID0gVFJVRSwgIGNhY2hlPSBUUlVFfQoKbGlicmFyeShCbGFuZEFsdG1hbkxlaCkKbGlicmFyeShqYW5pdG9yKQoKYSA8LSBncDJfd2lkZSAlPiUKICBmaWx0ZXIoZGlzZWFzZSA9PSAiY2hkIikgJT4lCiAgZ2dwbG90KGFlcyhyZW9yZGVyKHByYWN0aWNlX2NvZGUsIGVzdGltYXRlKSwgZXN0aW1hdGUpKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IG1pbjk1LCB5bWF4ID0gbWF4OTUpLCBjb2xvdXIgPSAibGlnaHRncmV5IiwgYWxwaGEgPSAwLjQpICsKICBnZW9tX3BvaW50KHNpemUgPSAwLjUpICsKICBnZW9tX3BvaW50KGFlcyh5ID0gcW9mcHJldi8xMDApLCBjb2xvdXIgPSAicmVkIiwgc2l6ZSA9IDAuNSwgYWxwaGEgPSAwLjEpICsKICBsYWJzKHggPSAiIiwgCiAgICAgICB5ID0gIlByZXZhbGVuY2UgZXN0aW1hdGUgKCUpIikrCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBOVUxMKSArCiAgdGhlbWUoYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpKQoKYiA8LSBxcGxvdChkYXRhID0gZ3AxLCBjaGRfZXN0aW1hdGUsIGNoZF9xb2ZwcmV2LCBnZW9tID0gInBvaW50IikgKyBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKQoKYyA8LSBibGFuZC5hbHRtYW4ucGxvdChncDEkY2hkX2VzdGltYXRlLCBncDEkY2hkX3FvZnByZXYsIGdyYXBoLnN5cyA9ICJnZ3Bsb3QyIikgCmdyaWRFeHRyYTo6Z3JpZC5hcnJhbmdlKGEsYixjLCBuY29sID0gMikKCiAgCmBgYAoKCiMjIyBTdHJva2UKClRoZSBhdmVyYWdlIGVzdGltYXRlZCBwcmV2YWxlbmNlIG9mIHN0cm9rZSBpcyBgciByb3VuZChncDJfd2lkZSAlPiUgZmlsdGVyKGRpc2Vhc2UgPT0gJ3N0cm9rZScpICU+JSBzdW1tYXJpc2UobWVhbihlc3RpbWF0ZSwgbmEucm0gPSBUUlVFKSksMikgJT4lIGxpc3RgJSBhbmQgdmFyaWVzIGZyb20gYHIgcm91bmQoZ3AyX3dpZGUgJT4lIGZpbHRlcihkaXNlYXNlID09ICdzdHJva2UnKSAlPiUgc3VtbWFyaXNlKG1pbihlc3RpbWF0ZSwgbmEucm0gPSBUUlVFKSksMikgJT4lIGxpc3RgJSBpbiBpbiB0aGUgcHJhY3RpY2Ugd2l0aCB0aGUgbG93ZXN0IHZhbHVlIHRvIGByIHJvdW5kKGdwMl93aWRlICU+JSBmaWx0ZXIoZGlzZWFzZSA9PSAnc3Ryb2tlJykgJT4lIHN1bW1hcmlzZShtYXgoZXN0aW1hdGUsIG5hLnJtID0gVFJVRSkpLDIpICU+JSBsaXN0YCUgaW4gdGhlIHByYWN0aWNlIHdpdGggdGhlIGhpZ2hlc3QuCgpgYGB7ciBzdHJva2UgdnMgUU9GLCBmaWcuY2FwcyA9IFRSVUUsICBjYWNoZT0gVFJVRX0KCmxpYnJhcnkoQmxhbmRBbHRtYW5MZWgpCmxpYnJhcnkoamFuaXRvcikKCmEgPC0gZ3AyX3dpZGUgJT4lCiAgZmlsdGVyKGRpc2Vhc2UgPT0gInN0cm9rZSIpICU+JQogIGdncGxvdChhZXMocmVvcmRlcihwcmFjdGljZV9jb2RlLCBlc3RpbWF0ZSksIGVzdGltYXRlKSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBtaW45NSwgeW1heCA9IG1heDk1KSwgY29sb3VyID0gImxpZ2h0Z3JleSIsIGFscGhhID0gMC40KSArCiAgZ2VvbV9wb2ludChzaXplID0gMC41KSArCiAgZ2VvbV9wb2ludChhZXMoeSA9IHFvZnByZXYvMTAwKSwgY29sb3VyID0gInJlZCIsIHNpemUgPSAwLjUsIGFscGhhID0gMC4xKSArCiAgbGFicyh4ID0gIiIsIAogICAgICAgeSA9ICJQcmV2YWxlbmNlIGVzdGltYXRlICglKSIpKwogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gTlVMTCkgKwogIHRoZW1lKGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSkKCmIgPC0gcXBsb3QoZGF0YSA9IGdwMSwgc3Ryb2tlX2VzdGltYXRlLCBzdHJva2VfcW9mcHJldiwgZ2VvbSA9ICJwb2ludCIpICsgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikKCmMgPC0gYmxhbmQuYWx0bWFuLnBsb3QoZ3AxJHN0cm9rZV9lc3RpbWF0ZSwgZ3AxJHN0cm9rZV9xb2ZwcmV2LCBncmFwaC5zeXMgPSAiZ2dwbG90MiIpIApncmlkRXh0cmE6OmdyaWQuYXJyYW5nZShhLGIsYywgbmNvbCA9IDIpCgogIApgYGAKCgojIyMgUGVyaXBoZXJhbCBhcnRlcmlhbCBkaXNlYXNlCgpUaGUgYXZlcmFnZSBlc3RpbWF0ZWQgcHJldmFsZW5jZSBvZiBQQUQgaXMgYHIgcm91bmQoZ3AyX3dpZGUgJT4lIGZpbHRlcihkaXNlYXNlID09ICdwYWQnKSAlPiUgc3VtbWFyaXNlKG1lYW4oZXN0aW1hdGUsIG5hLnJtID0gVFJVRSkpLDIpICU+JSBsaXN0YCUgYW5kIHZhcmllcyBmcm9tIGByIHJvdW5kKGdwMl93aWRlICU+JSBmaWx0ZXIoZGlzZWFzZSA9PSAncGFkJykgJT4lIHN1bW1hcmlzZShtaW4oZXN0aW1hdGUsIG5hLnJtID0gVFJVRSkpLDIpICU+JSBsaXN0YCUgaW4gaW4gdGhlIHByYWN0aWNlIHdpdGggdGhlIGxvd2VzdCB2YWx1ZSB0byBgciByb3VuZChncDJfd2lkZSAlPiUgZmlsdGVyKGRpc2Vhc2UgPT0gJ3BhZCcpICU+JSBzdW1tYXJpc2UobWF4KGVzdGltYXRlLCBuYS5ybSA9IFRSVUUpKSwyKSAlPiUgbGlzdGAlIGluIHRoZSBwcmFjdGljZSB3aXRoIHRoZSBoaWdoZXN0LgoKYGBge3IgcGFkIHZzIFFPRiwgZmlnLmNhcHMgPSBUUlVFLCAgY2FjaGU9IFRSVUV9CgpsaWJyYXJ5KEJsYW5kQWx0bWFuTGVoKQpsaWJyYXJ5KGphbml0b3IpCgphIDwtIGdwMl93aWRlICU+JQogIGZpbHRlcihkaXNlYXNlID09ICJwYWQiKSAlPiUKICBnZ3Bsb3QoYWVzKHJlb3JkZXIocHJhY3RpY2VfY29kZSwgZXN0aW1hdGUpLCBlc3RpbWF0ZSkpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gbWluOTUsIHltYXggPSBtYXg5NSksIGNvbG91ciA9ICJsaWdodGdyZXkiLCBhbHBoYSA9IDAuNCkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDAuNSkgKwogIGdlb21fcG9pbnQoYWVzKHkgPSBxb2ZwcmV2LzEwMCksIGNvbG91ciA9ICJyZWQiLCBzaXplID0gMC41LCBhbHBoYSA9IDAuMSkgKwogIHRoZW1lX2dyYXkoKSArCiAgbGFicyh4ID0gIiIsIAogICAgICAgeSA9ICJQcmV2YWxlbmNlIGVzdGltYXRlICglKSIpKwogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gTlVMTCkgKwogIHRoZW1lKGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSkKCmIgPC0gcXBsb3QoZGF0YSA9IGdwMSwgcGFkX2VzdGltYXRlLCBwYWRfcW9mcHJldiwgZ2VvbSA9ICJwb2ludCIpICsgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikKCmMgPC0gYmxhbmQuYWx0bWFuLnBsb3QoZ3AxJHBhZF9lc3RpbWF0ZSwgZ3AxJHBhZF9xb2ZwcmV2LCBncmFwaC5zeXMgPSAiZ2dwbG90MiIpIAoKZCA8LSBncDJfd2lkZSAlPiUKICBmaWx0ZXIoZGlzZWFzZSA9PSAicGFkIiAmICFpcy5uYShgMjAxMXJlZ2lvbm5hbWVgKSkgJT4lIAogIGdncGxvdChhZXMoYDIwMTFyZWdpb25uYW1lYCwgZXN0aW1hdGUpKSArIAogIGdlb21fYm94cGxvdCgpICsgCiAgY29vcmRfZmxpcCgpICsKICBsYWJzKHggPSAiIikKCmdyaWRFeHRyYTo6Z3JpZC5hcnJhbmdlKGEsZCwgYixjLCBuY29sID0gMiwgdG9wID0gIkxhYmVsIikKCiAgCmBgYAoKCiMjIyBPdmVyYWxsIGNvbXBhcmlzb25zIHdpdGggUU9GCgpUaGUgcmVsYXRpb25zaGlwIGJldHdlZW4gUU9GIGVzdGltYXRlcyBhbmQgdGhlc2UgbmV3IHByZXZhbGVuY2UgZXN0aW1hdGVzIGNhbiBiZSBjYXB0dXJlZCBpbiBhIG51bWJlciBvZiB3YXlzLiBPbmUgd2F5IGlzIHRvIHBsb3QgYSBjb3JyZWxvZ3JhbSB3aGljaCBzaG93cyB0aGUgY29ycmVsYXRpb24gYmV0d2VlbiBhbGwgdGhlIHZhcmlhYmxlcy4gVGhpcyBpcyBzaG93biBpbiBmaWd1cmUuIFRoaXMgc2hvd3MgY29ycmVsYXRpb25zIGJvdGggbnVtZXJpY2FsbHksIGFuZCBncmFwaGljYWxseSBhcyBmaWxsZWQgY2lyY2xlcy4gVGhlIGRhcmtlciBhbmQgbGFyZ2VyIHRoZSBjaXJjbGUgdGhlIHN0cm9uZ2VyIHRoZSByZWxhdGlvbnNoaXAuIFBvc2l0aXZlIGNvcnJlbGF0aW9ucyBhcmUgc2hvd24gaW4gYmx1ZTsgbmVnYXRpdmUgaW4gcmVkLiBDb3JyZWxhdGlvbnMgZ3JlYXRlciB0aGFuICsvLSAwLjcgYXJlIGdlbmVyYWxseSBjb25zaWRlcmVkIHRvIHJlcHJlc2VudCBhIHN0cm9uZyByZWxhdGlvbnNoaXAgKHdoZXJlIDEgaXMgdGhlIHN0cm9uZ2VzdCBwb3NzaWJsZSByZWxhdGlvbnNoaXApLiBGcm9tIHRoaXMgY2hhcnQgd2UgY2FuIHNlZSB0aGF0OgoKKiBGb3IgaHlwZXJ0ZW5zaW9uIHRoZXJlIGlzIGEgc3Ryb25nIGNvcnJlbGF0aW9uIGJldHdlZW4gdGhlIHByZXZhbGVuY2UgZXN0aW1hdGVzIGFuZCBRT0YKKiBGb3Igb3RoZXIgZGlzZWFzZXMgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIG1vZGVsZWQgdmFsdWUgYW5kIFFPRiBpcyB3ZWFrZXIKKiBUaGVyZSBhcmUgYWxzbyBzdHJvbmcgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIG1vZGVsZWQgdmFsdWVzIGZvciBoeXBlcnRlbnNpb24gYW5kIENPUEQgYW5kIGNhcmRpb3Zhc2N1bGFyIGVzdGltYXRlcwoKCmBgYHtyIGNvcnJlbG9ncmFtLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQojIyBpbXB1dGUgbWlzc2luZyBkYXRhCmdwMyA8LSBncDEgJT4lIAogIHNlbGVjdCg0OjM0KSAlPiUgCiAgaW1wdXRlTWlzc2luZ3M6OmltcHV0ZShtZXRob2QgPSAibWVkaWFuL21vZGUiKSAKCiMjIGNhbGN1bGF0ZSBjb3JyZWxhdGlvbnMKCmNvciA8LSBjb3IoZ3AzWywgYygyLCA1LCA2LCA5LCAxMCwgMTMsIDE0LCAxNywgMTgsIDIxLCAyNSwgMjgpXSkKCiMjIGNvcnJlbG9ncmFtCmNvcnJwbG90Ojpjb3JycGxvdC5taXhlZChjb3IsdGwuY2V4ID0gMC41LCB0bC5jb2wgPSAiYmxhY2siLCB0aXRsZSA9ICJDb3JyZWxhdGlvbiBiZXR3ZWVuIG5ldyBtb2RlbGxlZCBlc3RpbWF0ZXMgYW5kIFFPRiBwcmV2YWxlbmNlIikKCmBgYAoKCiMjIENvbXBhcmlzb24gd2l0aCBwcmV2aW91cyBlc3RpbWF0ZXMKCmBgYHtyIENvbXBhcmluZyB3aXRoIHByZXZpb3VzIGVzdGltYXRlcywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgY2FjaGUgPSBUUlVFfQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KGphbml0b3IpCmxpYnJhcnkoc3RyaW5ncikKbGlicmFyeSh2aXJpZGlzKQpsaWJyYXJ5KG1vZGVscikKCiMjIFJlYWQgaW4gcHJldmlvdXMgZXN0aW1hdGVzCm9sZGRhdGEgPC0gb2xkX2VzdHMgJT4lCiAgY2xlYW5fbmFtZXMoKSAlPiUKICBzZWxlY3QoaW5kaWNhdG9yLCBwYXJlbnRfY29kZSwgYXJlYV9uYW1lLCBwcmFjdGljZV9jb2RlID0gYXJlYV9jb2RlLCBjb3VudCkgJT4lCiAgZmlsdGVyKGluZGljYXRvciE9IkVzdGltYXRlZCBwZXJjZW50YWdlIG9mIGRldGVjdGVkIGRpYWJldGVzIHByZXZhbGVuY2UiKSAlPiUKICByZW5hbWUob2xkZXN0cyA9IGNvdW50KSAlPiUKICBzcHJlYWQoaW5kaWNhdG9yLCBvbGRlc3RzKQogCmdwMl93aWRlICU+JQogIHNlbGVjdChwcmFjdGljZV9jb2RlLCBkaXNlYXNlLCBlc3RpbWF0ZSkgJT4lCiAgc3ByZWFkKGRpc2Vhc2UsIGVzdGltYXRlKSAlPiUKICBsZWZ0X2pvaW4ob2xkZGF0YSkgJT4lCiAgc2VsZWN0KHByYWN0aWNlX2NvZGUsIGFyZWFfbmFtZSwgcGFyZW50X2NvZGUsIGV2ZXJ5dGhpbmcoKSkgJT4lCiAgZ2F0aGVyKGRpc2Vhc2UsIHZhbHVlLCA0OjE1KSAlPiUKICBmaWx0ZXIoIWRpc2Vhc2UgJWluJSBjKCJkZXByZXNzaW9uIiwgInBhZCIsICJzdHJva2VJTUQiLCAidW5keGJwIikpJT4lCiAgc3ByZWFkKGRpc2Vhc2UsIHZhbHVlKSAlPiUKICByZW5hbWUoc3Ryb2tlX29sZCA9IGBFc3RpbWF0ZWQgcGVyY2VudGFnZSBvZiBkZXRlY3RlZCBzdHJva2UgcHJldmFsZW5jZWAsIAogICAgICAgICBjaGRfb2xkID0gYEVzdGltYXRlZCBwZXJjZW50YWdlIG9mIGRldGVjdGVkIENIRCBwcmV2YWxlbmNlYCwKICAgICAgICAgY29wZF9vbGQgPSBgRXN0aW1hdGVkIHBlcmNlbnRhZ2Ugb2YgZGV0ZWN0ZWQgQ09QRCBwcmV2YWxlbmNlYCwKICAgICAgICAgYnBfb2xkID0gYEVzdGltYXRlZCBwZXJjZW50YWdlIG9mIGRldGVjdGVkIGh5cGVydGVuc2lvbiBwcmV2YWxlbmNlYCwKICAgICAgICAgYnBfbmV3ID0gYnAsIAogICAgICAgICBjaGRfbmV3ID0gY2hkLCAKICAgICAgICAgc3Ryb2tlX25ldyA9IHN0cm9rZSwgCiAgICAgICAgIGNvcGRfbmV3ID0gY29wZCkgJT4lCiAgZ2F0aGVyKGRpc2Vhc2UsIHZhbHVlLCA0OjExKSAlPiUKICBzZXBhcmF0ZShkaXNlYXNlLCBjKCJkaXNlYXNlIiwgInZlcnNpb24iKSwgc2VwID0gIl8iKSAlPiUKICBzcHJlYWQodmVyc2lvbiwgdmFsdWUpICU+JSAKICBtdXRhdGUoZGlmZiA9IG5ldyAtIG9sZCkgJT4lCiAgZ2dwbG90KGFlcyhuZXcsIG9sZCwgY29sb3VyID0gZGlzZWFzZSkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGNvbG91ciA9ICJibGFjayIpKwogIGZhY2V0X3dyYXAofmRpc2Vhc2UsIHNjYWxlcz0iZnJlZSIpICsKICBsYWJzKHggPSAiTmV3IHByZXZhbGVuY2UgZXN0aW1hdGVzICglKSIsCiAgICAgICB5ID0gIlByZXZpb3VzIHByZXZhbGVuY2UgZXN0aW1hdGVzIiwgCiAgICAgICB0aXRsZSA9ICJSZWxhdGlvbnNoaXAgYmV0d2VlbiBuZXcgYW5kIHByZXZpb3VzIHByZXZhbGVuY2UgZXN0aW1hdGVzIiwgCiAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogUHJldmFsZW5jZSBlc3RpbWF0ZXMgMjAxMSBhbmQgMjAxNS0xNiIpICsKc2NhbGVfY29sb3JfdmlyaWRpcyhvcHRpb24gPSAiQyIsIGRpc2NyZXRlID0gVFJVRSkKCmdnc2F2ZSgibmV3X3ZzX29sZF9wcmV2LnBuZyIpCmBgYAoKCmBgYHtyIHJlbGF0aXZlIGRpZmZlcmVuY2VzfQpncDJfd2lkZSAlPiUKICBzZWxlY3QocHJhY3RpY2VfY29kZSwgZGlzZWFzZSwgZXN0aW1hdGUpICU+JQogIHNwcmVhZChkaXNlYXNlLCBlc3RpbWF0ZSkgJT4lCiAgbGVmdF9qb2luKG9sZGRhdGEpICU+JQogIHNlbGVjdChwcmFjdGljZV9jb2RlLCBhcmVhX25hbWUsIHBhcmVudF9jb2RlLCBldmVyeXRoaW5nKCkpICU+JQogIGdhdGhlcihkaXNlYXNlLCB2YWx1ZSwgNDoxNSkgJT4lCiAgZmlsdGVyKCFkaXNlYXNlICVpbiUgYygiZGVwcmVzc2lvbiIsICJwYWQiLCAic3Ryb2tlSU1EIiwgInVuZHhicCIpKSU+JQogIHNwcmVhZChkaXNlYXNlLCB2YWx1ZSkgJT4lCiAgcmVuYW1lKHN0cm9rZV9vbGQgPSBgRXN0aW1hdGVkIHBlcmNlbnRhZ2Ugb2YgZGV0ZWN0ZWQgc3Ryb2tlIHByZXZhbGVuY2VgLCAKICAgICAgICAgY2hkX29sZCA9IGBFc3RpbWF0ZWQgcGVyY2VudGFnZSBvZiBkZXRlY3RlZCBDSEQgcHJldmFsZW5jZWAsCiAgICAgICAgIGNvcGRfb2xkID0gYEVzdGltYXRlZCBwZXJjZW50YWdlIG9mIGRldGVjdGVkIENPUEQgcHJldmFsZW5jZWAsCiAgICAgICAgIGJwX29sZCA9IGBFc3RpbWF0ZWQgcGVyY2VudGFnZSBvZiBkZXRlY3RlZCBoeXBlcnRlbnNpb24gcHJldmFsZW5jZWAsCiAgICAgICAgIGJwX25ldyA9IGJwLCAKICAgICAgICAgY2hkX25ldyA9IGNoZCwgCiAgICAgICAgIHN0cm9rZV9uZXcgPSBzdHJva2UsIAogICAgICAgICBjb3BkX25ldyA9IGNvcGQpICU+JQogIGdhdGhlcihkaXNlYXNlLCB2YWx1ZSwgNDoxMSkgJT4lCiAgc2VwYXJhdGUoZGlzZWFzZSwgYygiZGlzZWFzZSIsICJ2ZXJzaW9uIiksIHNlcCA9ICJfIikgJT4lCiAgc3ByZWFkKHZlcnNpb24sIHZhbHVlKSAlPiUgCiAgbXV0YXRlKGRpZmYgPSBuZXcgLSBvbGQsIHJlbGRpZmYgPSBuZXcvb2xkKSAlPiUKICBnZ3Bsb3QoYWVzKHJlb3JkZXIocHJhY3RpY2VfY29kZSwgcmVsZGlmZiksIHJlbGRpZmYsICBjb2xvdXIgPSBkaXNlYXNlKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgZmFjZXRfd3JhcCh+ZGlzZWFzZSwgbnJvdyA9IDEpICsKICBsYWJzKHggPSAiTmV3IHByZXZhbGVuY2UgZXN0aW1hdGVzICglKSIsCiAgICAgICB5ID0gIlByZXZpb3VzIHByZXZhbGVuY2UgZXN0aW1hdGVzIiwgCiAgICAgICB0aXRsZSA9ICJSZWxhdGl2ZSBkaWZmZXJlbmNlIGJldHdlZW4gbmV3IGFuZCBwcmV2aW91cyBwcmV2YWxlbmNlIGVzdGltYXRlcyIsIAogICAgICAgc3VidGl0bGUgPSAiTmV3IGVzdGltYXRlcyBhcmUgZ2VuZXJhbGx5IGhpZ2hlciB0aGFuIHByZXZpb3VzIGZpZ3VyZXMiLAogICAgICAgY2FwdGlvbiA9ICJTb3VyY2U6IFByZXZhbGVuY2UgZXN0aW1hdGVzIDIwMTEgYW5kIDIwMTUtMTYiKSArCiAgY29vcmRfZmxpcCgpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiIiwgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSkrCnNjYWxlX2NvbG9yX3ZpcmlkaXMob3B0aW9uID0gIkMiLCBkaXNjcmV0ZSA9IFRSVUUpICsKICBzY2FsZV95X2xvZzEwKCkKCmBgYAoKCmBgYHtyIEZ1cnRoZXIgYW5hbHlzaXN9CgpncF9hbmFsIDwtIGdwMl93aWRlICU+JQogIHNlbGVjdChwcmFjdGljZV9jb2RlLCBkaXNlYXNlLCBlc3RpbWF0ZSkgJT4lCiAgc3ByZWFkKGRpc2Vhc2UsIGVzdGltYXRlKSAlPiUKICBsZWZ0X2pvaW4ob2xkZGF0YSkgJT4lCiAgc2VsZWN0KHByYWN0aWNlX2NvZGUsIGFyZWFfbmFtZSwgcGFyZW50X2NvZGUsIGV2ZXJ5dGhpbmcoKSkgJT4lCiAgZ2F0aGVyKGRpc2Vhc2UsIHZhbHVlLCA0OjE1KSAlPiUKICBmaWx0ZXIoIWRpc2Vhc2UgJWluJSBjKCJkZXByZXNzaW9uIiwgInBhZCIsICJzdHJva2VJTUQiLCAidW5keGJwIikpJT4lCiAgc3ByZWFkKGRpc2Vhc2UsIHZhbHVlKSAlPiUKICByZW5hbWUoc3Ryb2tlX29sZCA9IGBFc3RpbWF0ZWQgcGVyY2VudGFnZSBvZiBkZXRlY3RlZCBzdHJva2UgcHJldmFsZW5jZWAsIAogICAgICAgICBjaGRfb2xkID0gYEVzdGltYXRlZCBwZXJjZW50YWdlIG9mIGRldGVjdGVkIENIRCBwcmV2YWxlbmNlYCwKICAgICAgICAgY29wZF9vbGQgPSBgRXN0aW1hdGVkIHBlcmNlbnRhZ2Ugb2YgZGV0ZWN0ZWQgQ09QRCBwcmV2YWxlbmNlYCwKICAgICAgICAgYnBfb2xkID0gYEVzdGltYXRlZCBwZXJjZW50YWdlIG9mIGRldGVjdGVkIGh5cGVydGVuc2lvbiBwcmV2YWxlbmNlYCwKICAgICAgICAgYnBfbmV3ID0gYnAsIAogICAgICAgICBjaGRfbmV3ID0gY2hkLCAKICAgICAgICAgc3Ryb2tlX25ldyA9IHN0cm9rZSwgCiAgICAgICAgIGNvcGRfbmV3ID0gY29wZCkgJT4lCiAgZ2F0aGVyKGRpc2Vhc2UsIHZhbHVlLCA0OjExKSAlPiUKICBzZXBhcmF0ZShkaXNlYXNlLCBjKCJkaXNlYXNlIiwgInZlcnNpb24iKSwgc2VwID0gIl8iKSAlPiUKICBzcHJlYWQodmVyc2lvbiwgdmFsdWUpICU+JSAKICBtdXRhdGUoZGlmZiA9IG5ldyAtIG9sZCwgcmVsZGlmZiA9IG5ldy9vbGQpIAoKYGBgCgogIApPZiB0aG9zZSBwcmFjdGljZXMgd2l0aCBhIHByZXZpb3VzIGVzdGltYXRlLCBgciBncF9hbmFsICU+JSBmaWx0ZXIoaXMubmEobmV3KSkgJT4lIGRpc3RpbmN0ICU+JSBucm93YCBhcmUgbm90IGluY2x1ZGVkIGluIHRoZSB1cGRhdGVzLiBUaGVzZSBhcmU6IGByIGdwX2FuYWwgJT4lIGZpbHRlcihpcy5uYShuZXcpKSAlPiUKICBncm91cF9ieShkaXNlYXNlKSAlPiUKICBzZWxlY3QocHJhY3RpY2VfY29kZSwgYXJlYV9uYW1lLCBkaXNlYXNlKSAlPiUKICBEVDo6ZGF0YXRhYmxlKGNhcHRpb24gPSAiUHJhY3RpY2VzIG5vdCB1cGRhdGVkIilgLAoKCg==