Introduction and data import

This R file generates the daily and weekly speech databases.

Speech database

Sentence-level database

Data import

We use the database 2b_cbdc_sentence_preds_with_author_desc.csv downloaded from the Kaggle notebook. We also use the countries2.csv file that merge the authors of speeches with their Central Bank and Countries. For some cases, there are multiple authors for a specific speech. Fortunately, these case are rare and they group authors from the same Central Banks and the same Countries. We manually retrieve their informations and add them directly.

We save the complete list of speeches in a .csv file (completelist.csv). Note that the database has loose keywords conditions, in order to capture all speeches related to CBDC. However, some sentences are linked to titles and/or references, or to crypto-assets exclusively (see for example the first observations above).

write.table(sent_pred2,
            file = "C:/Users/fkraus/Desktop/Articles/effects of CB speeches on stablecoins/2025/completelist.csv",
            sep = ";", dec = ".",
            row.names = FALSE, col.names = TRUE,
            fileEncoding = "UTF-8")

We manually note each title. The dataset list.csv is the same as completelist.csv, with an additional column cbdc_sentence that is equal to FALSE when sentences are related to keywords in title or in references. We then remove these “wrong” sentences, and add the corresponding currency to each Central Bank manually.

This filtering yields a total of 5,397 CBDC-related sentences (against 5,376 sentences in Zafar (2025) that applies the MLM on speeches up to 2024). These sentences appear in 652 speeches authored by 166 central bankers from 59 countries and 49 central banks.

Statistics on sentence-level data

We now have a sentence-level clean database that contains the type_label (retail, wholesale, general/unspecified), the sentiment_label (positive, negative, neutral), stance_label (Pro-CBDC, Anti-CBDC, Wait-and-See) and discourse_label (Risk-Benefit, Feature, Process) associated with each sentence measured by BERT.

Summary statistics of sentence-level database
Number of sentences Share within dimension
Discourse
Process 2,381 44.1%
Feature 1,543 28.6%
Risk-Benefit 1,473 27.3%
Sentiment
neutral 3,029 56.1%
positive 1,937 35.9%
negative 431 8.0%
Stance
Pro-CBDC 2,813 52.1%
Wait-and-See 2,051 38.0%
Anti-CBDC 533 9.9%
Type
Retail CBDC 2,854 52.9%
General/Unspecified 2,114 39.2%
Wholesale CBDC 429 7.9%

In total, there are 5397 uniques sentences, mostly about Retail CBDC (53% of speeches), while unspecified (39%) and wholesale (8%) are relatively marginally mentioned. Overall, the sentiment is essentially neutral yet pro-CBDC. In addition, we can see that there are less speeches about wholesale CBDC, but they tend to be more positive/Pro-CBDC :

In addition, we can observe that some Central Banks - and notably ECB - tend to communicate more than others :

Day/Week-level database

We have sentiment, stance, discourse and type of CBDC discussed at sentence-level. We transform the sentiments (positive, neutral et negative) and stances (Pro-CBDC, Wait-and-See et Anti-CBDC) in numeric values (1, 0, -1) at sentence-level.

As this table shows, the sentence “the bank of japan has no specific plan at present to issue digital currencies as a substitute for banknotes.” (second line) is associated with a negative stance towards CBDC.

There are some discrepancies between sentiment and score, yet they exhibit relatively high correlations at sentence-level:

All speeches

Then, for a given speech, we measure the average sentiment and stance as the average sentiment and stance across all sentences in a given speech.

Our results show a total of 652 speeches, consistent with our previous observations. We then aggregate the sentiment and stance daily-level as their average across all speeches that day. We find a total of 528 days in which there is at least one CBDC-related speech.

Here, we represent the 15-days moving average of stance in red and of sentiment in blue. The two series have similar dynamics overall. We also represent the sentiment from Auer & al. (2023) in orange.

Advantage of ML framework compared to expert scores : more observations, more consistent, granularity (sentence-level compared to speech-level) and easy to increase the number of observations.

We also decompose by type of CBDC discussed within each day :

Here, we represent the 15-days moving average of sentiment (the stance has a similar dynamics) decomposed by type of CBDC discussed. While speeches about wholesale CBDC starts relatively late compared to Unspecified and Retail CBDCs, the sentiment is also higher.

We also decompose by the discourse associated with the speech :

We also combine the type and discourse sentiment and stance

We also decompose between Central Banks. Because of data constraints, we procede to group from several ways. First, we distinguish between Developed Markets Central Banks and Emerging Markets Central Banks

Here, the 15-days moving average of sentiment shows some heterogeneity between developed and emerging markets. However, emerging markets tend to communicate more positively towards CBDC.

We also group three major Central Banks (European Central Bank, Fed and Bank of Japan)

and the ECB against the rest :

In a significant number of speeches, CBDC are only treated as a subject and - even though the sentiment or stance appears positive in a given speech - this may not be perceived by investors as an important signal. We thus also construct a database that only groups speeches that explicitely mention CBDC in their title, showing the relevance of this subject within the speech. This has been done by another paper (find reference).

And we merge everything in a single database :

Here, days without speech (speechday == 0) are treated as NAs. However, when combining speech data with stablecoins supply, we replace NAs by zeros.

Statistics of weekly speeches

Characteristic N = 3,398
Date (min, max) 2016-03-02, 2025-06-20
index_sent
    Mean (SD) 0.35 (0.42)
    Unknown 2,870
index_stance
    Mean (SD) 0.51 (0.43)
    Unknown 2,870
stance_auer
    -1 30 (9.9%)
    -0.5 1 (0.3%)
    0 96 (32%)
    0.333333333333333 1 (0.3%)
    0.5 13 (4.3%)
    0.666666666666667 5 (1.7%)
    1 156 (52%)
    Unknown 3,096
index_sent_type_general_unspecified
    Mean (SD) 0.19 (0.39)
    Unknown 2,870
index_sent_type_retail_cbdc
    Mean (SD) 0.20 (0.39)
    Unknown 2,870
index_sent_type_wholesale_cbdc
    Mean (SD) 0.23 (0.41)
    Unknown 2,870
index_stance_type_general_unspecified
    Mean (SD) 0.36 (0.44)
    Unknown 2,870
index_stance_type_retail_cbdc
    Mean (SD) 0.29 (0.46)
    Unknown 2,870
index_stance_type_wholesale_cbdc
    Mean (SD) 0.27 (0.43)
    Unknown 2,870
index_sent_disc_feature
    Mean (SD) 0.28 (0.39)
    Unknown 2,870
index_sent_disc_process
    Mean (SD) 0.24 (0.36)
    Unknown 2,870
index_sent_disc_risk_benefit
    Mean (SD) 0.16 (0.48)
    Unknown 2,870
index_stance_disc_feature
    Mean (SD) 0.40 (0.44)
    Unknown 2,870
index_stance_disc_process
    Mean (SD) 0.41 (0.41)
    Unknown 2,870
index_stance_disc_risk_benefit
    Mean (SD) 0.20 (0.50)
    Unknown 2,870
index_sent_type_disc_general_unspecified_feature
    Mean (SD) 0.09 (0.27)
    Unknown 2,870
index_sent_type_disc_general_unspecified_process
    Mean (SD) 0.16 (0.33)
    Unknown 2,870
index_sent_type_disc_general_unspecified_risk_benefit
    Mean (SD) 0.08 (0.39)
    Unknown 2,870
index_sent_type_disc_retail_cbdc_feature
    Mean (SD) 0.19 (0.34)
    Unknown 2,870
index_sent_type_disc_retail_cbdc_risk_benefit
    Mean (SD) 0.10 (0.45)
    Unknown 2,870
index_sent_type_disc_wholesale_cbdc_feature
    0 462 (88%)
    0.25 1 (0.2%)
    0.333333333333333 2 (0.4%)
    0.4 2 (0.4%)
    0.5 6 (1.1%)
    0.6 1 (0.2%)
    0.666666666666667 3 (0.6%)
    0.75 1 (0.2%)
    1 50 (9.5%)
    Unknown 2,870
index_sent_type_disc_retail_cbdc_process
    Mean (SD) 0.11 (0.27)
    Unknown 2,870
index_sent_type_disc_wholesale_cbdc_risk_benefit
    -1 2 (0.4%)
    0 487 (92%)
    0.333333333333333 3 (0.6%)
    0.5 1 (0.2%)
    0.666666666666667 2 (0.4%)
    0.75 1 (0.2%)
    1 32 (6.1%)
    Unknown 2,870
index_sent_type_disc_wholesale_cbdc_process
    0 440 (83%)
    0.0909090909090909 1 (0.2%)
    0.333333333333333 1 (0.2%)
    0.4 1 (0.2%)
    0.428571428571429 1 (0.2%)
    0.5 7 (1.3%)
    0.6 1 (0.2%)
    0.666666666666667 2 (0.4%)
    1 74 (14%)
    Unknown 2,870
index_stance_type_disc_general_unspecified_feature
    Mean (SD) 0.15 (0.34)
    Unknown 2,870
index_stance_type_disc_general_unspecified_process
    Mean (SD) 0.31 (0.41)
    Unknown 2,870
index_stance_type_disc_general_unspecified_risk_benefit
    Mean (SD) 0.11 (0.44)
    Unknown 2,870
index_stance_type_disc_retail_cbdc_feature
    Mean (SD) 0.27 (0.42)
    Unknown 2,870
index_stance_type_disc_retail_cbdc_risk_benefit
    Mean (SD) 0.12 (0.47)
    Unknown 2,870
index_stance_type_disc_wholesale_cbdc_feature
    0 444 (84%)
    0.333333333333333 4 (0.8%)
    0.5 2 (0.4%)
    0.666666666666667 4 (0.8%)
    0.7 1 (0.2%)
    0.75 4 (0.8%)
    1 69 (13%)
    Unknown 2,870
index_stance_type_disc_retail_cbdc_process
    Mean (SD) 0.19 (0.37)
    Unknown 2,870
index_stance_type_disc_wholesale_cbdc_risk_benefit
    -1 4 (0.8%)
    0 487 (92%)
    0.333333333333333 3 (0.6%)
    0.75 1 (0.2%)
    1 33 (6.3%)
    Unknown 2,870
index_stance_type_disc_wholesale_cbdc_process
    Mean (SD) 0.17 (0.37)
    Unknown 2,870
index_sent_deveme_developed
    Mean (SD) 0.22 (0.37)
    Unknown 2,870
index_sent_deveme_emerging
    Mean (SD) 0.16 (0.35)
    Unknown 2,870
index_stance_deveme_developed
    Mean (SD) 0.34 (0.41)
    Unknown 2,870
index_stance_deveme_emerging
    Mean (SD) 0.21 (0.39)
    Unknown 2,870
index_sent_cb_others
    Mean (SD) 0.19 (0.37)
    Unknown 2,870
index_sent_cb_ecb_fed_boj
    Mean (SD) 0.19 (0.35)
    Unknown 2,870
index_stance_cb_others
    Mean (SD) 0.27 (0.42)
    Unknown 2,870
index_stance_cb_ecb_fed_boj
    Mean (SD) 0.29 (0.40)
    Unknown 2,870
index_sent_cb_other
    Mean (SD) 0.19 (0.38)
    Unknown 2,870
index_sent_cb_ecb
    Mean (SD) 0.19 (0.35)
    Unknown 2,870
index_stance_cb_other
    Mean (SD) 0.29 (0.42)
    Unknown 2,870
index_stance_cb_ecb
    Mean (SD) 0.27 (0.39)
    Unknown 2,870
index_sent_cbdctitle
    Mean (SD) 0.25 (0.27)
    Unknown 3,312
index_stance_cbdctitle
    Mean (SD) 0.38 (0.31)
    Unknown 3,312
index_sent_type_cbdctitle_General/Unspecified
    Mean (SD) 0.12 (0.27)
    Unknown 3,312
index_sent_type_cbdctitle_Retail CBDC
    Mean (SD) 0.22 (0.34)
    Unknown 3,312
index_sent_type_cbdctitle_Wholesale CBDC
    Mean (SD) 0.25 (0.39)
    Unknown 3,312
index_stance_type_cbdctitle_General/Unspecified
    Mean (SD) 0.26 (0.37)
    Unknown 3,312
index_stance_type_cbdctitle_Retail CBDC
    Mean (SD) 0.37 (0.42)
    Unknown 3,312
index_stance_type_cbdctitle_Wholesale CBDC
    Mean (SD) 0.30 (0.42)
    Unknown 3,312
index_sent_discourse_cbdctitle_Feature
    Mean (SD) 0.39 (0.31)
    Unknown 3,312
index_sent_discourse_cbdctitle_Process
    Mean (SD) 0.15 (0.18)
    Unknown 3,312
index_sent_discourse_cbdctitle_Risk-Benefit
    Mean (SD) 0.21 (0.43)
    Unknown 3,312
index_stance_discourse_cbdctitle_Feature
    Mean (SD) 0.60 (0.32)
    Unknown 3,312
index_stance_discourse_cbdctitle_Process
    Mean (SD) 0.32 (0.27)
    Unknown 3,312
index_stance_discourse_cbdctitle_Risk-Benefit
    Mean (SD) 0.23 (0.48)
    Unknown 3,312
index_sent_disc_type_cbdctitle_Feature_General/Unspecified
    Mean (SD) 0.14 (0.31)
    Unknown 3,312
index_sent_disc_type_cbdctitle_Feature_Retail CBDC
    Mean (SD) 0.36 (0.35)
    Unknown 3,312
index_sent_disc_type_cbdctitle_Feature_Wholesale CBDC
    0 72 (84%)
    0.25 1 (1.2%)
    0.4 2 (2.3%)
    0.5 1 (1.2%)
    0.666666666666667 1 (1.2%)
    0.75 1 (1.2%)
    1 8 (9.3%)
    Unknown 3,312
index_sent_disc_type_cbdctitle_Process_General/Unspecified
    Mean (SD) 0.08 (0.17)
    Unknown 3,312
index_sent_disc_type_cbdctitle_Risk-Benefit_General/Unspecified
    Mean (SD) 0.14 (0.45)
    Unknown 3,312
index_sent_disc_type_cbdctitle_Risk-Benefit_Retail CBDC
    Mean (SD) 0.15 (0.55)
    Unknown 3,312
index_sent_disc_type_cbdctitle_Process_Retail CBDC
    Mean (SD) 0.13 (0.20)
    Unknown 3,312
index_sent_disc_type_cbdctitle_Process_Wholesale CBDC
    0 66 (77%)
    0.0909090909090909 1 (1.2%)
    0.333333333333333 1 (1.2%)
    0.4 1 (1.2%)
    0.428571428571429 1 (1.2%)
    0.5 3 (3.5%)
    0.666666666666667 1 (1.2%)
    1 12 (14%)
    Unknown 3,312
index_sent_disc_type_cbdctitle_Risk-Benefit_Wholesale CBDC
    0 74 (86%)
    0.333333333333333 2 (2.3%)
    0.5 1 (1.2%)
    1 9 (10%)
    Unknown 3,312
index_stance_disc_type_cbdctitle_Feature_General/Unspecified
    Mean (SD) 0.21 (0.38)
    Unknown 3,312
index_stance_disc_type_cbdctitle_Feature_Retail CBDC
    Mean (SD) 0.59 (0.37)
    Unknown 3,312
index_stance_disc_type_cbdctitle_Feature_Wholesale CBDC
    0 67 (78%)
    0.333333333333333 1 (1.2%)
    0.5 1 (1.2%)
    0.666666666666667 2 (2.3%)
    0.75 1 (1.2%)
    1 14 (16%)
    Unknown 3,312
index_stance_disc_type_cbdctitle_Process_General/Unspecified
    Mean (SD) 0.29 (0.36)
    Unknown 3,312
index_stance_disc_type_cbdctitle_Risk-Benefit_General/Unspecified
    Mean (SD) 0.12 (0.51)
    Unknown 3,312
index_stance_disc_type_cbdctitle_Risk-Benefit_Retail CBDC
    Mean (SD) 0.20 (0.59)
    Unknown 3,312
index_stance_disc_type_cbdctitle_Process_Retail CBDC
    Mean (SD) 0.27 (0.29)
    Unknown 3,312
index_stance_disc_type_cbdctitle_Process_Wholesale CBDC
    0 62 (72%)
    0.0909090909090909 1 (1.2%)
    0.428571428571429 1 (1.2%)
    0.5 3 (3.5%)
    0.666666666666667 2 (2.3%)
    1 17 (20%)
    Unknown 3,312
index_stance_disc_type_cbdctitle_Risk-Benefit_Wholesale CBDC
    -1 2 (2.3%)
    0 72 (84%)
    0.333333333333333 2 (2.3%)
    1 10 (12%)
    Unknown 3,312
index_sent_cb_cbdctitle_Other
    Mean (SD) 0.03 (0.14)
    Unknown 3,312
index_sent_cb_cbdctitle_ECB
    Mean (SD) 0.22 (0.25)
    Unknown 3,312
index_stance_cb_cbdctitle_Other
    Mean (SD) 0.08 (0.23)
    Unknown 3,312
index_stance_cb_cbdctitle_ECB
    Mean (SD) 0.30 (0.31)
    Unknown 3,312
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2s6IENCREMgU3BlZWNoZXMiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IA0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19kZXB0aDogMw0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KICBodG1sX2RvY3VtZW50Og0KICAgIGRmX3ByaW50OiBwYWdlZA0KICB3b3JkX2RvY3VtZW50OiBkZWZhdWx0DQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KLS0tDQoNCg0KIyBJbnRyb2R1Y3Rpb24gYW5kIGRhdGEgaW1wb3J0DQoNClRoaXMgUiBmaWxlIGdlbmVyYXRlcyB0aGUgZGFpbHkgYW5kIHdlZWtseSBzcGVlY2ggZGF0YWJhc2VzLg0KDQoNCg0KYGBge3Igc2V0dXAsIGNvbGxhcHNlPVRSVUUsIGluY2x1ZGU9RkFMU0V9DQpzZXR3ZCgiQzovVXNlcnMvZmtyYXVzL0Rlc2t0b3AvQXJ0aWNsZXMvZWZmZWN0cyBvZiBDQiBzcGVlY2hlcyBvbiBzdGFibGVjb2lucy8yMDI1IikNCg0KIyBQYWNrYWdlcw0KcmVxdWlyZShndCkNCnJlcXVpcmUoem9vKQ0KcmVxdWlyZShndHN1bW1hcnkpDQpsaWJyYXJ5KGRwbHlyKQ0KcmVxdWlyZShscGlyZnMpDQpsaWJyYXJ5KHRpZHlyKQ0KbGlicmFyeShleHRyYWZvbnQpDQpsaWJyYXJ5KHN0cmluZ3IpDQpyZXF1aXJlKHBhdGNod29yaykNCmxpYnJhcnkobHVicmlkYXRlKQ0KcmVxdWlyZShmb3JjYXRzKQ0KbGlicmFyeShicm9vbSkNCg0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkocHVycnIpDQpsaWJyYXJ5KGh0dHIpDQpsaWJyYXJ5KGpzb25saXRlKQ0KbGlicmFyeShkYXRhLnRhYmxlKSAgDQpsaWJyYXJ5KGZpeGVzdCkNCmxpYnJhcnkoZ2dwbG90MikNCnJlcXVpcmUoc2NhbGVzKQ0KDQpvcHRpb25zKGRwbHlyLnN1bW1hcmlzZS5pbmZvcm0gPSBGQUxTRSkNCnRoZW1lX3NldCh0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDEyKSkNCg0Kc2VudF9wcmVkIDwtICAgcmVhZC5jc3YoZmlsZT0iQzovVXNlcnMvZmtyYXVzL0Rlc2t0b3AvQXJ0aWNsZXMvZWZmZWN0cyBvZiBDQiBzcGVlY2hlcyBvbiBzdGFibGVjb2lucy8yMDI1LzJiX2NiZGNfc2VudGVuY2VfcHJlZHNfd2l0aF9hdXRob3JfZGVzYy5jc3YiKSANCmNvdW50cmllcyA8LSAgIHJlYWQuY3N2KGZpbGU9IkM6L1VzZXJzL2ZrcmF1cy9EZXNrdG9wL0FydGljbGVzL2VmZmVjdHMgb2YgQ0Igc3BlZWNoZXMgb24gc3RhYmxlY29pbnMvMjAyNS9jb3VudHJpZXMyLmNzdiIsIHNlcD0iOyIpDQp0aXRsZXMgPC0gICByZWFkLmNzdihmaWxlPSJDOi9Vc2Vycy9ma3JhdXMvRGVza3RvcC9BcnRpY2xlcy9lZmZlY3RzIG9mIENCIHNwZWVjaGVzIG9uIHN0YWJsZWNvaW5zLzIwMjUvY2JkY190aXRsZV9mbGFnc19mcm9tX21hdGNoZXMuY3N2IikNCmBgYA0KDQojIFNwZWVjaCBkYXRhYmFzZQ0KDQojIyBTZW50ZW5jZS1sZXZlbCBkYXRhYmFzZQ0KDQojIyMgRGF0YSBpbXBvcnQNCg0KV2UgdXNlIHRoZSBkYXRhYmFzZSBgMmJfY2JkY19zZW50ZW5jZV9wcmVkc193aXRoX2F1dGhvcl9kZXNjLmNzdmAgZG93bmxvYWRlZCBmcm9tIHRoZSBLYWdnbGUgbm90ZWJvb2suIFdlIGFsc28gdXNlIHRoZSBgY291bnRyaWVzMi5jc3ZgIGZpbGUgdGhhdCBtZXJnZSB0aGUgYXV0aG9ycyBvZiBzcGVlY2hlcyB3aXRoIHRoZWlyIENlbnRyYWwgQmFuayBhbmQgQ291bnRyaWVzLiBGb3Igc29tZSBjYXNlcywgdGhlcmUgYXJlIG11bHRpcGxlIGF1dGhvcnMgZm9yIGEgc3BlY2lmaWMgc3BlZWNoLiBGb3J0dW5hdGVseSwgdGhlc2UgY2FzZSBhcmUgcmFyZSBhbmQgdGhleSBncm91cCBhdXRob3JzIGZyb20gdGhlIHNhbWUgQ2VudHJhbCBCYW5rcyBhbmQgdGhlIHNhbWUgQ291bnRyaWVzLiBXZSBtYW51YWxseSByZXRyaWV2ZSB0aGVpciBpbmZvcm1hdGlvbnMgYW5kIGFkZCB0aGVtIGRpcmVjdGx5Lg0KDQoNCmBgYHtyLCBlY2hvPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGNvbGxhcHNlPVRSVUUsIGluY2x1ZGU9RkFMU0V9DQpzZW50X3ByZWQyIDwtIHNlbnRfcHJlZCAlPiUNCiAgc2VsZWN0KC1jKGNvdW50cnksZGVzY3JpcHRpb24pICklPiUNCiAgZGlzdGluY3QoKSU+JQ0KICBsZWZ0X2pvaW4oY291bnRyaWVzJT4ldW5pcXVlKCksIGJ5PWMoImF1dGhvciIpKSU+JQ0KICBtdXRhdGUoQ291bnRyeSA9Y2FzZV93aGVuKA0KICAgIGF1dGhvcj09IkphY3F1ZWxpbmUgTG9oOyBCZW5vw650IEPFk3Vyw6kiIH4gIkVDQiBCb2FyZCIsIA0KICAgIGF1dGhvcj09IlRob21hcyBKb3JkYW47IE1hcnRpbiBTY2hsZWdlbDsgQW50b2luZSBNYXJ0aW4ifiJTd2l0emVybGFuZCIsIA0KICAgIGF1dGhvcj09IlBldHJhIFRzY2h1ZGluOyBUaG9tYXMgTW9zZXIifiJTd2l0emVybGFuZCIsDQogICAgYXV0aG9yPT0iT2xhZiBTbGVpanBlbjsgS2xhYXMgS25vdDsgU3RldmVuIE1haWpvb3IiIH4gIk5ldGhlcmxhbmRzIiwNCiAgICBUUlVFIH4gQ291bnRyeSkpJT4lIA0KICBtdXRhdGUoQ2VudHJhbF9CYW5rID1jYXNlX3doZW4oDQogICAgYXV0aG9yPT0iSmFjcXVlbGluZSBMb2g7IEJlbm/DrnQgQ8WTdXLDqSIgfiAiRXVyb3BlYW4gQ2VudHJhbCBCYW5rIiwgDQogICAgYXV0aG9yPT0iVGhvbWFzIEpvcmRhbjsgTWFydGluIFNjaGxlZ2VsOyBBbnRvaW5lIE1hcnRpbiJ+IlN3aXNzIE5hdGlvbmFsIEJhbmsiLCANCiAgICBhdXRob3I9PSJQZXRyYSBUc2NodWRpbjsgVGhvbWFzIE1vc2VyIn4iU3dpc3MgTmF0aW9uYWwgQmFuayIsDQogICAgYXV0aG9yPT0iT2xhZiBTbGVpanBlbjsgS2xhYXMgS25vdDsgU3RldmVuIE1haWpvb3IiIH4gIkV1cm9wZWFuIENlbnRyYWwgQmFuayIsDQogICAgVFJVRSB+IENlbnRyYWxfQmFuaykpJT4lDQogIG11dGF0ZSgNCiAgICBkYXRldGltZSA9IHBhcnNlX2RhdGVfdGltZSgNCiAgICAgIGRhdGUsDQogICAgICBvcmRlcnMgPSBjKCJkL20vWSBIOk06UyIsICJkL20vWSBIOk0iLCAiWS1tLWQgSDpNOlMiLCAiWS1tLWQgSDpNIiksDQogICAgICB0eiA9ICJVVEMiICANCiAgICApLA0KICAgIGRhdGUgPSBhc19kYXRlKGRhdGV0aW1lKSAgIyBrZWVwIGEgcHVyZSBEYXRlIHRvbyAob3B0aW9uYWwpDQogICklPiVzZWxlY3QoLWRhdGV0aW1lKSU+JQ0KICBmaWx0ZXIoZGF0ZSA+PSBhcy5EYXRlKCIyMDE1LTAxLTAxIikpJT4lIHNlbGVjdCgtWCkNCg0KYGBgDQoNCldlIHNhdmUgdGhlIGNvbXBsZXRlIGxpc3Qgb2Ygc3BlZWNoZXMgaW4gYSBgLmNzdmAgZmlsZSAoYGNvbXBsZXRlbGlzdC5jc3ZgKS4gTm90ZSB0aGF0IHRoZSBkYXRhYmFzZSBoYXMgbG9vc2Uga2V5d29yZHMgY29uZGl0aW9ucywgaW4gb3JkZXIgdG8gY2FwdHVyZSBhbGwgc3BlZWNoZXMgcmVsYXRlZCB0byBDQkRDLiBIb3dldmVyLCBzb21lIHNlbnRlbmNlcyBhcmUgbGlua2VkIHRvIHRpdGxlcyBhbmQvb3IgcmVmZXJlbmNlcywgb3IgdG8gY3J5cHRvLWFzc2V0cyBleGNsdXNpdmVseSAoc2VlIGZvciBleGFtcGxlIHRoZSBmaXJzdCBvYnNlcnZhdGlvbnMgYWJvdmUpLg0KDQoNCmBgYHtyLCBlY2hvPVRSVUUsIGNvbGxhcHNlPVRSVUV9DQp3cml0ZS50YWJsZShzZW50X3ByZWQyLA0KICAgICAgICAgICAgZmlsZSA9ICJDOi9Vc2Vycy9ma3JhdXMvRGVza3RvcC9BcnRpY2xlcy9lZmZlY3RzIG9mIENCIHNwZWVjaGVzIG9uIHN0YWJsZWNvaW5zLzIwMjUvY29tcGxldGVsaXN0LmNzdiIsDQogICAgICAgICAgICBzZXAgPSAiOyIsIGRlYyA9ICIuIiwNCiAgICAgICAgICAgIHJvdy5uYW1lcyA9IEZBTFNFLCBjb2wubmFtZXMgPSBUUlVFLA0KICAgICAgICAgICAgZmlsZUVuY29kaW5nID0gIlVURi04IikNCmBgYA0KDQpXZSBtYW51YWxseSBub3RlIGVhY2ggdGl0bGUuIFRoZSBkYXRhc2V0IGBsaXN0LmNzdmAgaXMgdGhlIHNhbWUgYXMgYGNvbXBsZXRlbGlzdC5jc3ZgLCB3aXRoIGFuIGFkZGl0aW9uYWwgY29sdW1uIGBjYmRjX3NlbnRlbmNlYCB0aGF0IGlzIGVxdWFsIHRvIGBGQUxTRWAgd2hlbiBzZW50ZW5jZXMgYXJlIHJlbGF0ZWQgdG8ga2V5d29yZHMgaW4gdGl0bGUgb3IgaW4gcmVmZXJlbmNlcy4gV2UgdGhlbiByZW1vdmUgdGhlc2UgIndyb25nIiBzZW50ZW5jZXMsIGFuZCBhZGQgdGhlIGNvcnJlc3BvbmRpbmcgY3VycmVuY3kgdG8gZWFjaCBDZW50cmFsIEJhbmsgbWFudWFsbHkuDQoNCg0KYGBge3IsIGVjaG89VFJVRSwgY29sbGFwc2U9VFJVRSwgaW5jbHVkZT1GQUxTRX0NCmF1ZXJfZGF0YSA8LSByZWFkeGw6OnJlYWRfZXhjZWwoIkM6L3VzZXJzL2ZrcmF1cy9EZXNrdG9wL0FydGljbGVzL2VmZmVjdHMgb2YgQ0Igc3BlZWNoZXMgb24gc3RhYmxlY29pbnMvc3BlZWNoZXNzdGFuY2VzLnhsc3giKSU+JWZpbHRlcihzb3VyY2U9PSJhdWVyIikNCg0Kc2VudGVuY2VfYmFzZSA8LSByZWFkLmNzdjIoIkM6L1VzZXJzL2ZrcmF1cy9EZXNrdG9wL0FydGljbGVzL2VmZmVjdHMgb2YgQ0Igc3BlZWNoZXMgb24gc3RhYmxlY29pbnMvMjAyNS9saXN0LmNzdiIsDQogICAgICAgICAgICAgICAgICAgICAgICBmaWxlRW5jb2RpbmcgPSAiVVRGLTgiLA0KICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKSU+JQ0KICBsZWZ0X2pvaW4odGl0bGVzICU+JSBzZWxlY3QodXJsLCBjYmRjX2luX3RpdGxlKSwgYnk9J3VybCcpJT4lDQogIHVuaXF1ZSgpJT4lDQogIG11dGF0ZShjYmRjX3NlbnRlbmNlID0gaWZlbHNlKGlzLm5hKGNiZGNfc2VudGVuY2UpLCAiVFJVRSIsY2JkY19zZW50ZW5jZSkpJT4lDQogIGZpbHRlcighY2JkY19zZW50ZW5jZT09IkZBTFNFIiklPiUgIyB3ZSBvbmx5IGtlZXAgdGhlIHRydWUgQ0JEQy1yZWxhdGVkIHNlbnRlbmNlcw0KICBtdXRhdGUoDQogICAgZGF0ZXRpbWUgPSBwYXJzZV9kYXRlX3RpbWUoDQogICAgICBkYXRlLA0KICAgICAgb3JkZXJzID0gYygiZC9tL1kgSDpNOlMiLCAiZC9tL1kgSDpNIiwgIlktbS1kIEg6TTpTIiwgIlktbS1kIEg6TSIpLA0KICAgICAgdHogPSAiVVRDIiAgIA0KICAgICksDQogICAgZGF0ZSA9IGFzX2RhdGUoZGF0ZXRpbWUpICANCiAgKSU+JXNlbGVjdCgtZGF0ZXRpbWUpICU+JQ0Kc2VsZWN0KC1jKG1hdGNoX3R5cGUsICBrZXl3b3JkLHNvdXJjZSwgIGNiZGNfc2VudGVuY2UpKSU+JQ0KICBtdXRhdGUoZGF0ZSA9IGFzLkRhdGUoZGF0ZSkpICU+JQ0KICBkaXN0aW5jdCgpJT4lDQogIG11dGF0ZShDdXJyZW5jeSA9IGNhc2Vfd2hlbigNCiAgICBDZW50cmFsX0JhbmsgPT0gIkJhbmsgb2YgRW5nbGFuZCIgfiAiR0JQIiwgDQogICAgQ2VudHJhbF9CYW5rID09ICJFdXJvcGVhbiBDZW50cmFsIEJhbmsiIH4gIkVVUiIsIA0KICAgIENlbnRyYWxfQmFuayA9PSAiQmFuayBvZiBKYXBhbiIgfiAiSlBZIiwgDQogICAgQ2VudHJhbF9CYW5rID09ICJCYW5rIG9mIENhbmFkYSIgfiAiQ0FEIiwgDQogICAgQ2VudHJhbF9CYW5rID09ICJSZXNlcnZlIEJhbmsgb2YgQXVzdHJhbGlhIiB+ICJBVUQiLCANCiAgICBDZW50cmFsX0JhbmsgPT0gIk1vbmV0YXJ5IEF1dGhvcml0eSBvZiBTaW5nYXBvcmUiIH4gIlNHRCIsIA0KICAgIENlbnRyYWxfQmFuayA9PSAiU3ZlcmlnZXMgUmlrc2JhbmsiIH4gIlNFSyIsIA0KICAgIENlbnRyYWxfQmFuayA9PSAiQmFuayBvZiBLb3JlYSIgfiAiS1JXIiwgDQogICAgQ2VudHJhbF9CYW5rID09ICJGZWQiIH4gIlVTRCIsIA0KICAgIENlbnRyYWxfQmFuayA9PSAiQ2VudHJhbCBCYW5rIG9mIE1hbGF5c2lhIiB+ICJNWVIiLCANCiAgICBDZW50cmFsX0JhbmsgPT0gIkNlbnRyYWwgQmFuayBvZiBDaGlsZSIgfiAiQ0xQIiwgDQogICAgQ2VudHJhbF9CYW5rID09ICJOYXRpb25hbCBCYW5rIG9mIHRoZSBSZXB1YmxpYyBvZiAoTm9ydGgpIE1hY2Vkb25pYSIgfiAiTUtEIiwgDQogICAgQ2VudHJhbF9CYW5rID09ICJDemVjaCBOYXRpb25hbCBCYW5rIiB+ICJDWksiLCANCiAgICBDZW50cmFsX0JhbmsgPT0gIlNvdXRoIEFmcmljYW4gUmVzZXJ2ZSBCYW5rIiB+ICJaQVIiLCANCiAgICBDZW50cmFsX0JhbmsgPT0gIkJhbmsgb2YgQm90c3dhbmEiIH4gIkJXUCIsIA0KICAgIENlbnRyYWxfQmFuayA9PSAiQ2VudHJhbCBCYW5rIG9mIEJhcmJhZG9zIiB+ICJCQkQiLCANCiAgICBDZW50cmFsX0JhbmsgPT0gIk5hdGlvbmFsIEJhbmsgb2YgRGVubWFyayIgfiAiREtLIiwgDQogICAgQ2VudHJhbF9CYW5rID09ICJCYW5rIG9mIE1hdXJpdGl1cyIgfiAiTVVSIiwgDQogICAgQ2VudHJhbF9CYW5rID09ICJTdGF0ZSBCYW5rIG9mIFBha2lzdGFuIiB+ICJQS1IiLCANCiAgICBDZW50cmFsX0JhbmsgPT0gIkNlbnRyYWwgQmFuayBvZiBTcmkgTGFua2EiICAgIH4gIkxLUiIsIA0KICAgIENlbnRyYWxfQmFuayA9PSAgIlN3aXNzIE5hdGlvbmFsIEJhbmsiICB+ICJDSEYiLCANCiAgICBDZW50cmFsX0JhbmsgPT0gICJDZW50cmFsIEJhbmsgb2YgdGhlIFBoaWxpcHBpbmVzIiAgfiAiUEhQIiwgDQogICAgQ2VudHJhbF9CYW5rID09ICJDZW50cmFsIEJhbmsgb2YgSWNlbGFuZCIgIH4gIklTSyIsIA0KICAgIENlbnRyYWxfQmFuayA9PSAgIkJhbmsgb2YgVGhhaWxhbmQiICB+ICJUSEIiLCANCiAgICBDZW50cmFsX0JhbmsgPT0gICJSZXNlcnZlIEJhbmsgb2YgTmV3IFplYWxhbmQiIH4gIk5aRCIsIA0KICAgIENlbnRyYWxfQmFuayA9PSAiRWFzdGVybiBDYXJpYmJlYW4gQ2VudHJhbCBCYW5rIiB+ICJYQ0QiLCANCiAgICBDZW50cmFsX0JhbmsgPT0gIkNlbnRyYWwgQmFuayBvZiBUaGUgQmFoYW1hcyIgIH4gIkJTRCIsIA0KICAgIENlbnRyYWxfQmFuayA9PSAiSG9uZyBLb25nIE1vbmV0YXJ5IEF1dGhvcml0eSIgfiAiSEtEIiwgDQogICAgQ2VudHJhbF9CYW5rID09ICAiTm9yZ2VzIEJhbmsiICAgfiAiTk9LIiwgDQogICAgQ2VudHJhbF9CYW5rID09ICAgIkNlbnRyYWwgQmFuayBvZiBCb3NuaWEgYW5kIEhlcnplZ292aW5hIiAgICAgfiAiQkFNIiwgDQogICAgQ2VudHJhbF9CYW5rID09ICAiQ2VudHJhbCBCYW5rIG9mIEt1d2FpdCIgIH4gIktXRCIsIA0KICAgIENlbnRyYWxfQmFuayA9PSAiQ2VudHJhbCBCYW5rIG9mIE1vcm9jY28iICB+ICJNQUQiLCANCiAgICBDZW50cmFsX0JhbmsgPT0gICAiQmFuayBvZiBNZXhpY28iICB+ICJNWE4iLCANCiAgICBDZW50cmFsX0JhbmsgPT0gIkJhbmsgb2YgQWxiYW5pYSIgICB+ICJBTEwiLCANCiAgICBDZW50cmFsX0JhbmsgPT0gICAiQmFuayBvZiBSdXNzaWEiICB+ICJSVUIiLCANCiAgICBDZW50cmFsX0JhbmsgPT0gIlJlc2VydmUgQmFuayBvZiBJbmRpYSIgIH4gIklOUiIsIA0KICAgIENlbnRyYWxfQmFuayA9PSAiUGVvcGxlJ3MgQmFuayBvZiBDaGluYSIgfiAiQ05ZIiwgDQogICAgQ2VudHJhbF9CYW5rID09ICJCYW5rIEluZG9uZXNpYSIgICAgIH4gIklEUiIsIA0KICAgIENlbnRyYWxfQmFuayA9PSAgICJDZW50cmFsIEJhbmsgb2YgS2VueWEifiAiS0VTIiwgDQogICAgQ2VudHJhbF9CYW5rID09ICAiQ2VudHJhbCBCYW5rIG9mIE5pZ2VyaWEiICAgICB+ICJOR04iLCANCiAgICBDZW50cmFsX0JhbmsgPT0gICJOYXRpb25hbCBCYW5rIG9mIFNlcmJpYSIgICAgfiAiUlNEIiwgDQogICAgQ2VudHJhbF9CYW5rID09ICJCYW5rIG9mIElzcmFlbCIgICB+ICJJTFMiLCANCiAgICBDZW50cmFsX0JhbmsgPT0gIkNlbnRyYWwgQmFuayBvZiB0aGUgUmVwdWJsaWMgb2YgS29zb3ZvIiAgfiAiRVVSIiwgDQogICAgQ2VudHJhbF9CYW5rID09ICJCYW5rIG9mIEZpbmxhbmQiICB+ICJFVVIiLCANCiAgICBDZW50cmFsX0JhbmsgPT0gICJDZW50cmFsIEJhbmsgb2YgTmVwYWwiICB+ICJOUFIiLCANCiAgICBDZW50cmFsX0JhbmsgPT0gICJDZW50cmFsIEJhbmsgb2YgQ3lwcnVzIiAgfiAiRVVSIiwgDQogICAgQ2VudHJhbF9CYW5rID09ICJDZW50cmFsIEJhbmsgb2YgRXN3YXRpbmkiICB+ICJTWkwiLCANCiAgICBDZW50cmFsX0JhbmsgPT0gIkJhbmsgb2YgU2xvdmVuaWEiIH4gIkVVUiIsIA0KICAgIFRSVUV+Ik90aGVyIg0KICAgICkpJT4lDQogIHNlbGVjdCgtYyhYLCBYLjEpKQ0KDQpzZW50ZW5jZV9iYXNlMiA8LSBzZW50ZW5jZV9iYXNlJT4lDQogIHNlbGVjdCh1cmwsIGRhdGUpJT4lDQogIGRpc3RpbmN0KHVybCwgZGF0ZSklPiUNCiAgaW5uZXJfam9pbihhdWVyX2RhdGElPiVzZWxlY3QoVVJMX3RleHQsIHNwZWVjaF9zdGFuY2UpLCBieT1jKCJ1cmwiPSJVUkxfdGV4dCIpKSU+JQ0KICBncm91cF9ieShkYXRlKSU+JQ0KICBzdW1tYXJpemUoc3RhbmNlX2F1ZXIgPSBtZWFuKHNwZWVjaF9zdGFuY2UpKQ0KYGBgDQoNCg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCnNlbnRlbmNlX2Jhc2UlPiUNCiAgc3VtbWFyaXplKENvdW50cnkgPSBuX2Rpc3RpbmN0KENvdW50cnkpLCANCiAgICAgICAgICAgIENlbnRyYWxCYW5rID0gbl9kaXN0aW5jdChDZW50cmFsX0JhbmspLCANCiAgICAgICAgICAgIEF1dGhvcj1uX2Rpc3RpbmN0KGF1dGhvciksDQogICAgICAgICAgICBTcGVlY2hlcyA9IG5fZGlzdGluY3QodXJsKSwgDQogICAgICAgICAgICBTZW50ZW5jZXMgPSBuKCkNCiAgICAgICAgICAgICkNCmBgYA0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCnNlbnRlbmNlX2Jhc2UgJT4lIHNlbGVjdChzZW50ZW5jZSwgdHlwZV9sYWJlbCwgZGlzY291cnNlX2xhYmVsLCBzdGFuY2VfbGFiZWwsIHNlbnRpbWVudF9sYWJlbCklPiUNCiAgZmlsdGVyKHR5cGVfbGFiZWwgPT0gIkdlbmVyYWwvVW5zcGVjaWZpZWQiIyAmIA0KICAgICAgICAgICMgc3RhbmNlX2xhYmVsPT0iUHJvLUNCREMiICYgDQogICAgICAgICAgIyBzZW50aW1lbnRfbGFiZWwgPT0icG9zaXRpdmUiICYgICAgICAgICAgDQogICAgICAgICAgIyBkaXNjb3Vyc2VfbGFiZWwgPT0gIlByb2Nlc3MiDQogICAgICAgICAgICklPiUNCiAgc2VsZWN0KHNlbnRlbmNlKQ0KYGBgDQoNCg0KVGhpcyBmaWx0ZXJpbmcgeWllbGRzIGEgdG90YWwgb2YgNSwzOTcgQ0JEQy1yZWxhdGVkIHNlbnRlbmNlcyAoYWdhaW5zdCA1LDM3NiBzZW50ZW5jZXMgaW4gWmFmYXIgKDIwMjUpIHRoYXQgYXBwbGllcyB0aGUgTUxNIG9uIHNwZWVjaGVzIHVwIHRvIDIwMjQpLiBUaGVzZSBzZW50ZW5jZXMgYXBwZWFyIGluIDY1MiBzcGVlY2hlcyBhdXRob3JlZCBieSAxNjYgY2VudHJhbCBiYW5rZXJzIGZyb20gNTkgY291bnRyaWVzIGFuZCA0OSBjZW50cmFsIGJhbmtzLg0KDQojIyMgU3RhdGlzdGljcyBvbiBzZW50ZW5jZS1sZXZlbCBkYXRhIA0KDQpXZSBub3cgaGF2ZSBhIHNlbnRlbmNlLWxldmVsIGNsZWFuIGRhdGFiYXNlIHRoYXQgY29udGFpbnMgdGhlIGB0eXBlX2xhYmVsYCAocmV0YWlsLCB3aG9sZXNhbGUsIGdlbmVyYWwvdW5zcGVjaWZpZWQpLCB0aGUgYHNlbnRpbWVudF9sYWJlbGAgKHBvc2l0aXZlLCBuZWdhdGl2ZSwgbmV1dHJhbCksIGBzdGFuY2VfbGFiZWxgIChQcm8tQ0JEQywgQW50aS1DQkRDLCBXYWl0LWFuZC1TZWUpIGFuZCBgZGlzY291cnNlX2xhYmVsYCAoUmlzay1CZW5lZml0LCBGZWF0dXJlLCBQcm9jZXNzKSBhc3NvY2lhdGVkIHdpdGggZWFjaCBzZW50ZW5jZSBtZWFzdXJlZCBieSBCRVJULg0KDQpgYGB7ciwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnRvdGFsX3NlbnRlbmNlcyA8LSBucm93KHNlbnRlbmNlX2Jhc2UpDQoNCnN1bW1hcnlfc3RhdHNfc2VudGVuY2UgPC0gYmluZF9yb3dzKA0KICBzZW50ZW5jZV9iYXNlICU+JQ0KICAgIGNvdW50KGxldmVsID0gdHlwZV9sYWJlbCwgbmFtZSA9ICJuIikgJT4lDQogICAgbXV0YXRlKGRpbWVuc2lvbiA9ICJUeXBlIiksDQogIA0KICBzZW50ZW5jZV9iYXNlICU+JQ0KICAgIGNvdW50KGxldmVsID0gc2VudGltZW50X2xhYmVsLCBuYW1lID0gIm4iKSAlPiUNCiAgICBtdXRhdGUoZGltZW5zaW9uID0gIlNlbnRpbWVudCIpLA0KICANCiAgc2VudGVuY2VfYmFzZSAlPiUNCiAgICBjb3VudChsZXZlbCA9IHN0YW5jZV9sYWJlbCwgbmFtZSA9ICJuIikgJT4lDQogICAgbXV0YXRlKGRpbWVuc2lvbiA9ICJTdGFuY2UiKSwNCiAgDQogIHNlbnRlbmNlX2Jhc2UgJT4lDQogICAgY291bnQobGV2ZWwgPSBkaXNjb3Vyc2VfbGFiZWwsIG5hbWUgPSAibiIpICU+JQ0KICAgIG11dGF0ZShkaW1lbnNpb24gPSAiRGlzY291cnNlIikNCikgJT4lDQogIGdyb3VwX2J5KGRpbWVuc2lvbikgJT4lDQogIG11dGF0ZShzaGFyZSA9IG4gLyBzdW0obikpICU+JQ0KICB1bmdyb3VwKCkNCg0Kc3VtbWFyeV9zdGF0c19zZW50ZW5jZSAlPiUNCiAgYXJyYW5nZShkaW1lbnNpb24sIGRlc2MobikpICU+JQ0KICBtdXRhdGUoc2hhcmUgPSBzY2FsZXM6OnBlcmNlbnQoc2hhcmUsIGFjY3VyYWN5ID0gMC4xKSkgJT4lDQogIGd0KHJvd25hbWVfY29sID0gImxldmVsIiwgZ3JvdXBuYW1lX2NvbCA9ICJkaW1lbnNpb24iKSAlPiUNCiAgICB0YWJfc3R5bGUoDQogICAgc3R5bGUgPSBjZWxsX3RleHQod2VpZ2h0ID0gImJvbGQiKSwNCiAgICBsb2NhdGlvbnMgPSBjZWxsc19yb3dfZ3JvdXBzKCkNCiAgKSAlPiUNCiAgdGFiX2hlYWRlcigNCiAgICB0aXRsZSA9IHBhc3RlMCgNCiAgICAgICJTdW1tYXJ5IHN0YXRpc3RpY3Mgb2Ygc2VudGVuY2UtbGV2ZWwgZGF0YWJhc2UiDQogICAgKQ0KICApICU+JQ0KICBjb2xzX2xhYmVsKA0KICAgIGxldmVsID0gIkNhdGVnb3J5IiwNCiAgICBuICAgICA9ICJOdW1iZXIgb2Ygc2VudGVuY2VzIiwNCiAgICBzaGFyZSA9ICJTaGFyZSB3aXRoaW4gZGltZW5zaW9uIg0KICApICU+JQ0KICBmbXRfbnVtYmVyKGNvbHVtbnMgPSBuLCBkZWNpbWFscyA9IDApICU+JQ0KICBjb2xzX2FsaWduKA0KICAgIGFsaWduICAgPSAiY2VudGVyIiwNCiAgICBjb2x1bW5zID0gYyhuLCBzaGFyZSkNCiAgKQ0KYGBgDQpJbiB0b3RhbCwgdGhlcmUgYXJlICoqNTM5NyB1bmlxdWVzIHNlbnRlbmNlcyoqLCAqKm1vc3RseSBhYm91dCBSZXRhaWwgQ0JEQyoqICg1MyUgb2Ygc3BlZWNoZXMpLCB3aGlsZSB1bnNwZWNpZmllZCAoMzklKSBhbmQgd2hvbGVzYWxlICg4JSkgYXJlIHJlbGF0aXZlbHkgbWFyZ2luYWxseSBtZW50aW9uZWQuIE92ZXJhbGwsIHRoZSBzZW50aW1lbnQgaXMgZXNzZW50aWFsbHkgKipuZXV0cmFsKiogeWV0ICoqcHJvLUNCREMqKi4gSW4gYWRkaXRpb24sIHdlIGNhbiBzZWUgdGhhdCB0aGVyZSBhcmUgKipsZXNzIHNwZWVjaGVzIGFib3V0IHdob2xlc2FsZSBDQkRDKiosIGJ1dCB0aGV5IHRlbmQgdG8gYmUgbW9yZSBwb3NpdGl2ZS9Qcm8tQ0JEQyA6DQoNCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQ0Kc2VudGltZW50X2J5X3R5cGUgPC0gc2VudGVuY2VfYmFzZSAlPiUNCiAgZ3JvdXBfYnkodHlwZV9sYWJlbCwgc2VudGltZW50X2xhYmVsKSU+JQ0KICBzdW1tYXJpemUoY291bnQ9bigpKSU+JQ0KICBtdXRhdGUoDQogICAgdHlwZV9sYWJlbCAgICAgID0gZmFjdG9yKHR5cGVfbGFiZWwsIGxldmVscyA9IGMoIkdlbmVyYWwvVW5zcGVjaWZpZWQiLCJSZXRhaWwgQ0JEQyIsIldob2xlc2FsZSBDQkRDIikpLA0KICAgIHNlbnRpbWVudF9sYWJlbCA9IGZhY3RvcihzZW50aW1lbnRfbGFiZWwsIGxldmVscyA9IGMoIm5lZ2F0aXZlIiwibmV1dHJhbCIsInBvc2l0aXZlIikpDQogICkgJT4lDQogIGdncGxvdChhZXMoeCA9IHR5cGVfbGFiZWwsIHkgPSBjb3VudCwgZmlsbCA9IHNlbnRpbWVudF9sYWJlbCkpICsNCiAgZ2VvbV9jb2woKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMobmVnYXRpdmUgPSAiI2Q3MzAyNyIsIG5ldXRyYWwgPSAiI2JkYmRiZCIsIHBvc2l0aXZlID0gIiMxYTk4NTAiKSwNCiAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICJTZW50aW1lbnQiKSArDQogIGxhYnMoeCA9IE5VTEwsIHkgPSAiQ291bnQiLCB0aXRsZT0iU2VudGVuY2UtbGV2ZWwgc2VudGltZW50IGJ5IHR5cGUiKSArDQogIHRoZW1lX2J3KCkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikrDQogIHRoZW1lKCAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwub250b3AgPSBGLA0KICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSwgdmp1c3QgPSAwLjUsIHNpemUgPSAyMCwgZmFtaWx5ID0gIkNhbGlicmkiKSwNCiAgICAgICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJDYWxpYnJpIiwgc2l6ZSA9IDIwKSwNCiAgICAgICAgICAgICB0aXRsZSA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiQ2FsaWJyaSIpLA0KICAgICAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2UgPSAiYm9sZCIsIHNpemU9MjAsIGZhbWlseSA9ICJDYWxpYnJpIiksDQogICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsDQogICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJDYWxpYnJpIiwgZmFjZSA9ICJib2xkIiksDQogICAgICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gIkNhbGlicmkiLCBzaXplID0gMjApLA0KICAgICAgICAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIikpDQoNCg0Kc3RhbmNlX2J5X3R5cGUgPC0gc2VudGVuY2VfYmFzZSAlPiUNCiAgZ3JvdXBfYnkodHlwZV9sYWJlbCwgc3RhbmNlX2xhYmVsKSU+JQ0KICBzdW1tYXJpemUoY291bnQ9bigpKSU+JQ0KICBtdXRhdGUoDQogICAgdHlwZV9sYWJlbCAgICAgID0gZmFjdG9yKHR5cGVfbGFiZWwsIGxldmVscyA9IGMoIkdlbmVyYWwvVW5zcGVjaWZpZWQiLCJSZXRhaWwgQ0JEQyIsIldob2xlc2FsZSBDQkRDIikpLA0KICAgIHN0YW5jZV9sYWJlbCA9IGZhY3RvcihzdGFuY2VfbGFiZWwsIGxldmVscyA9IGMoIkFudGktQ0JEQyIsIldhaXQtYW5kLVNlZSIsIlByby1DQkRDIikpDQogICkgJT4lDQogIGdncGxvdChhZXMoeCA9IHR5cGVfbGFiZWwsIHkgPSBjb3VudCwgZmlsbCA9IHN0YW5jZV9sYWJlbCkpICsNCiAgZ2VvbV9jb2woKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIkFudGktQ0JEQyIgPSAiI2Q3MzAyNyIsICJXYWl0LWFuZC1TZWUiID0gIiNiZGJkYmQiLCAiUHJvLUNCREMiID0gIiMxYTk4NTAiKSwNCiAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICJTdGFuY2UiKSArDQogIGxhYnMoeCA9IE5VTEwsIHkgPSAiIiwgdGl0bGU9IlNlbnRlbmNlLWxldmVsIHN0YW5jZSBieSB0eXBlIikgKw0KICB0aGVtZV9idygpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpKw0KICB0aGVtZSggICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLm9udG9wID0gRiwNCiAgICAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEsIHZqdXN0ID0gMC41LCBzaXplID0gMjAsIGZhbWlseSA9ICJDYWxpYnJpIiksDQogICAgICAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiQ2FsaWJyaSIsIHNpemUgPSAyMCksDQogICAgICAgICAgICAgdGl0bGUgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gIkNhbGlicmkiKSwNCiAgICAgICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiLCBzaXplPTIwLCBmYW1pbHkgPSAiQ2FsaWJyaSIpLA0KICAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLA0KICAgICAgICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiQ2FsaWJyaSIsIGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJDYWxpYnJpIiwgc2l6ZSA9IDIwKSwNCiAgICAgICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIpKQ0KDQpwbG90X3NlbnRlbmNlcyA8LSBzZW50aW1lbnRfYnlfdHlwZSArIHN0YW5jZV9ieV90eXBlDQpwbG90X3NlbnRlbmNlcw0KI2dnc2F2ZSgicGxvdF9zZW50ZW5jZXMucG5nIiwgcGxvdF9zZW50ZW5jZXMsIGhlaWdodD0xMCwgd2lkdGg9MjApDQpgYGANCg0KSW4gYWRkaXRpb24sIHdlIGNhbiBvYnNlcnZlIHRoYXQgc29tZSBDZW50cmFsIEJhbmtzIC0gYW5kIG5vdGFibHkgRUNCIC0gdGVuZCB0byBjb21tdW5pY2F0ZSBtb3JlIHRoYW4gb3RoZXJzIDoNCg0KYGBge3IsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0V9DQoNCnBsb3RfbnNlbnRlbmNlcyA8LSBzZW50ZW5jZV9iYXNlICU+JQ0KICBjb3VudChDZW50cmFsX0JhbmssIG5hbWUgPSAiY291bnQiKSAlPiUNCiAgbXV0YXRlKENlbnRyYWxfQmFuayA9IGZjdF9yZW9yZGVyKENlbnRyYWxfQmFuaywgY291bnQsIC5kZXNjID0gVFJVRSkpICU+JQ0KICBmaWx0ZXIoIWNvdW50PDIwKSU+JQ0KICBnZ3Bsb3QoYWVzKENlbnRyYWxfQmFuaywgY291bnQpKSArDQogIGdlb21fY29sKCkgKw0KICBjb29yZF9mbGlwKCkgKyAgIyBlYXNpZXIgdG8gcmVhZCBsb25nIGxhYmVsczsgcmVtb3ZlIGlmIHlvdSBwcmVmZXIgdmVydGljYWwNCiAgbGFicyh4ID0gTlVMTCwgeSA9ICJDb3VudCIsIHRpdGxlPSJOdW1iZXIgb2Ygc2VudGVuY2VzIHJlbGF0ZWQgdG8gQ0JEQyBieSBDZW50cmFsIEJhbmsqIiwNCiAgICAgICBjYXB0aW9uPSIqUmVtb3ZlZCBjZW50cmFsIGJhbmtzIHdpdGggbGVzcyB0aGFuIDIwIHNlbnRlbmNlcyBhYm91dCBDQkRDIikgKw0KICB0aGVtZV9taW5pbWFsKCkrDQogIHRoZW1lKCAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwub250b3AgPSBGLA0KICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSwgdmp1c3QgPSAwLjUsIHNpemUgPSAyMCwgZmFtaWx5ID0gIkNhbGlicmkiKSwNCiAgICAgICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJDYWxpYnJpIiwgc2l6ZSA9IDIwKSwNCiAgICAgICAgICAgICB0aXRsZSA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiQ2FsaWJyaSIpLA0KICAgICAgICAgICAgIGNhcHRpb24gPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gIkNhbGlicmkiLCBzaXplID0gMjApLA0KICAgICAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2UgPSAiYm9sZCIsIHNpemU9MjAsIGZhbWlseSA9ICJDYWxpYnJpIiksDQogICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsDQogICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJDYWxpYnJpIiwgZmFjZSA9ICJib2xkIiksDQogICAgICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gIkNhbGlicmkiLCBzaXplID0gMjApLA0KICAgICAgICAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIikNCiAgKQ0KDQoNCg0KcGxvdF9uc2VudGVuY2VzDQojZ2dzYXZlKCJwbG90X25zZW50ZW5jZXMucG5nIiwgcGxvdF9uc2VudGVuY2VzLCBoZWlnaHQ9MTAsIHdpZHRoPTIwKQ0KYGBgDQoNCg0KIyMgRGF5L1dlZWstbGV2ZWwgZGF0YWJhc2UNCg0KV2UgaGF2ZSBzZW50aW1lbnQsIHN0YW5jZSwgZGlzY291cnNlIGFuZCB0eXBlIG9mIENCREMgZGlzY3Vzc2VkIGF0IHNlbnRlbmNlLWxldmVsLiBXZSB0cmFuc2Zvcm0gdGhlIHNlbnRpbWVudHMgKGBwb3NpdGl2ZWAsIGBuZXV0cmFsYCBldCBgbmVnYXRpdmVgKSBhbmQgc3RhbmNlcyAoYFByby1DQkRDYCwgYFdhaXQtYW5kLVNlZWAgZXQgYEFudGktQ0JEQ2ApIGluIG51bWVyaWMgdmFsdWVzICgxLCAwLCAtMSkgYXQgc2VudGVuY2UtbGV2ZWwuDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0Kc2lnbl9mcm9tX3NlbnRpbWVudCA8LSBmdW5jdGlvbihsYmwpIHsNCiAgeCA8LSBzdHJfdG9fbG93ZXIobGJsKQ0KICBjYXNlX3doZW4oDQogICAgc3RyX2RldGVjdCh4LCAicG9zaXRpdmUiKSB+ICAxTCwNCiAgICBzdHJfZGV0ZWN0KHgsICJuZWdhdGl2ZSIpIH4gLTFMLA0KICAgIFRSVUUgfiAwTCAgIyBuZXV0cmFsLCBvdGhlcg0KICApDQp9DQpzaWduX2Zyb21fc3RhbmNlIDwtIGZ1bmN0aW9uKGxibCkgew0KICB4IDwtIHN0cl90b19sb3dlcihsYmwpDQogIGNhc2Vfd2hlbigNCiAgICBzdHJfZGV0ZWN0KHgsICJwcm8iKSAgICAgICAgICAgIH4gIDFMLCAgIyBwcm8tY2JkYw0KICAgIHN0cl9kZXRlY3QoeCwgImFudGkiKSAgICAgICAgICAgfiAtMUwsICAjIGFudGktY2JkYw0KICAgIHN0cl9kZXRlY3QoeCwgIndhaXQiKSAgICAgICAgICAgfiAgMEwsICAjIHdhaXQtYW5kLXNlZQ0KICAgIFRSVUUgfiAwTA0KICApDQp9DQoNCnNlbnRlbmNlX3NpZ25zIDwtIHNlbnRlbmNlX2Jhc2UgJT4lDQogIG11dGF0ZSgNCiAgICBzZW50X3NpZ24gICA9IHNpZ25fZnJvbV9zZW50aW1lbnQoc2VudGltZW50X2xhYmVsKSwNCiAgICBzdGFuY2Vfc2lnbiA9IHNpZ25fZnJvbV9zdGFuY2Uoc3RhbmNlX2xhYmVsKQ0KICApDQoNCmhlYWQoc2VudGVuY2Vfc2lnbnMgJT4lIHNlbGVjdChkYXRlLCB0aXRsZSwgc2VudGVuY2UsIHNlbnRfc2lnbiwgc3RhbmNlX3NpZ24gKSkNCg0KYGBgDQpBcyB0aGlzIHRhYmxlIHNob3dzLCB0aGUgc2VudGVuY2UgInRoZSBiYW5rIG9mIGphcGFuIGhhcyBubyBzcGVjaWZpYyBwbGFuIGF0IHByZXNlbnQgdG8gaXNzdWUgZGlnaXRhbCBjdXJyZW5jaWVzIGFzIGEgc3Vic3RpdHV0ZSBmb3IgYmFua25vdGVzLiIgKHNlY29uZCBsaW5lKSBpcyBhc3NvY2lhdGVkIHdpdGggYSBuZWdhdGl2ZSBzdGFuY2UgdG93YXJkcyBDQkRDLiANCg0KVGhlcmUgYXJlIHNvbWUgZGlzY3JlcGFuY2llcyBiZXR3ZWVuIHNlbnRpbWVudCBhbmQgc2NvcmUsIHlldCB0aGV5IGV4aGliaXQgcmVsYXRpdmVseSBoaWdoIGNvcnJlbGF0aW9ucyBhdCBzZW50ZW5jZS1sZXZlbDoNCg0KYGBge3IsIGVjaG89RkFMU0V9DQpzZW50ZW5jZV9zaWducyU+JQ0KICBzZWxlY3Qoc2VudF9zaWduLCBzdGFuY2Vfc2lnbiklPiUNCiAgc3VtbWFyaXplKCJDb3JyZWxhdGlvbiBTZW50aW1lbnQgLSBTdGFuY2UiPSBjb3Ioc2VudF9zaWduLCBzdGFuY2Vfc2lnbikpDQpgYGANCg0KDQojIyMgQWxsIHNwZWVjaGVzDQpUaGVuLCBmb3IgYSBnaXZlbiBzcGVlY2gsIHdlIG1lYXN1cmUgdGhlIGF2ZXJhZ2Ugc2VudGltZW50IGFuZCBzdGFuY2UgYXMgdGhlIGF2ZXJhZ2Ugc2VudGltZW50IGFuZCBzdGFuY2UgYWNyb3NzIGFsbCBzZW50ZW5jZXMgaW4gYSBnaXZlbiBzcGVlY2guIA0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCnNwZWVjaF9sZXZlbCA8LSBzZW50ZW5jZV9zaWducyAlPiUNCiAgZ3JvdXBfYnkodXJsLCBkYXRlKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIGluZGV4X3NlbnQgICA9IG1lYW4oc2VudF9zaWduLCAgIG5hLnJtID0gVFJVRSksDQogICAgaW5kZXhfc3RhbmNlID0gbWVhbihzdGFuY2Vfc2lnbiwgbmEucm0gPSBUUlVFKSwNCiAgICAuZ3JvdXBzID0gImRyb3AiDQogICkgDQoNCmhlYWQoc3BlZWNoX2xldmVsKQ0KYGBgDQoNCk91ciByZXN1bHRzIHNob3cgYSB0b3RhbCBvZiA2NTIgc3BlZWNoZXMsIGNvbnNpc3RlbnQgd2l0aCBvdXIgcHJldmlvdXMgb2JzZXJ2YXRpb25zLg0KV2UgdGhlbiBhZ2dyZWdhdGUgdGhlIHNlbnRpbWVudCBhbmQgc3RhbmNlIGRhaWx5LWxldmVsIGFzIHRoZWlyIGF2ZXJhZ2UgYWNyb3NzIGFsbCBzcGVlY2hlcyB0aGF0IGRheS4gV2UgZmluZCBhIHRvdGFsIG9mIDUyOCBkYXlzIGluIHdoaWNoIHRoZXJlIGlzIGF0IGxlYXN0IG9uZSBDQkRDLXJlbGF0ZWQgc3BlZWNoLiANCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlY2hvPUZBTFNFfQ0KZGF5X2xldmVsIDwtIHNlbnRlbmNlX3NpZ25zICU+JQ0KICBncm91cF9ieSggZGF0ZSkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBpbmRleF9zZW50ICAgPSBtZWFuKHNlbnRfc2lnbiwgICBuYS5ybSA9IFRSVUUpLA0KICAgIGluZGV4X3N0YW5jZSA9IG1lYW4oc3RhbmNlX3NpZ24sIG5hLnJtID0gVFJVRSksDQogICAgLmdyb3VwcyA9ICJkcm9wIg0KICApJT4lDQogIGxlZnRfam9pbihzZW50ZW5jZV9iYXNlMiwgYnk9ImRhdGUiKSU+JQ0KICBtdXRhdGUoc3BlZWNoZGF5ID0gMSkgJT4lDQogIGFycmFuZ2UoZGF0ZSkNCg0KDQpkYXlfbGV2ZWwlPiUgDQogIG11dGF0ZShzZW50X21hID0gcm9sbGFwcGx5KGluZGV4X3NlbnQsIEZVTj1tZWFuLCBmaWxsPU5BLCBuYS5ybT1ULCB3aWR0aD0xNSksIA0KICAgICAgICAgc3RhbmNlX21hID0gcm9sbGFwcGx5KGluZGV4X3N0YW5jZSwgRlVOPW1lYW4sIGZpbGw9TkEsIG5hLnJtPVQsIHdpZHRoPTE1KSwgDQogICAgICAgICBhdWVyX21hID0gcm9sbGFwcGx5KHN0YW5jZV9hdWVyLCBGVU49bWVhbiwgZmlsbD1OQSwgbmEucm09VCwgd2lkdGg9MTUpKSU+JQ0KICBnZ3Bsb3QoYWVzKHg9ZGF0ZSwgeT1zZW50X21hKSkrDQogIGdlb21fbGluZShsd2Q9MSwgY29sb3I9IiMxZjc3YjQiKSsNCiAgZ2VvbV9saW5lKGFlcyh5PXN0YW5jZV9tYSksIGx3ZD0xLCBjb2xvcj0iI2Q2MjcyOCIpKw0KICAgZ2VvbV9saW5lKGFlcyh5PWF1ZXJfbWEpLCBsd2Q9MSwgbHR5PTIsIGNvbG9yPSIjZDk1ZjAyIikrDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGx0eT0yLCBjb2xvcj0iZ3JleTUwIikNCg0KDQoNCmBgYA0KSGVyZSwgd2UgcmVwcmVzZW50IHRoZSAxNS1kYXlzIG1vdmluZyBhdmVyYWdlIG9mIHN0YW5jZSBpbiByZWQgYW5kIG9mIHNlbnRpbWVudCBpbiBibHVlLiBUaGUgdHdvIHNlcmllcyBoYXZlIHNpbWlsYXIgZHluYW1pY3Mgb3ZlcmFsbC4gV2UgYWxzbyByZXByZXNlbnQgdGhlIHNlbnRpbWVudCBmcm9tIEF1ZXIgJiBhbC4gKDIwMjMpIGluIG9yYW5nZS4NCg0KQWR2YW50YWdlIG9mIE1MIGZyYW1ld29yayBjb21wYXJlZCB0byBleHBlcnQgc2NvcmVzIDogbW9yZSBvYnNlcnZhdGlvbnMsIG1vcmUgY29uc2lzdGVudCwgZ3JhbnVsYXJpdHkgKHNlbnRlbmNlLWxldmVsIGNvbXBhcmVkIHRvIHNwZWVjaC1sZXZlbCkgYW5kIGVhc3kgdG8gaW5jcmVhc2UgdGhlIG51bWJlciBvZiBvYnNlcnZhdGlvbnMuDQoNCldlIGFsc28gZGVjb21wb3NlIGJ5IHR5cGUgb2YgQ0JEQyBkaXNjdXNzZWQgd2l0aGluIGVhY2ggZGF5IDoNCg0KYGBge3IsIGVjaG89RkFMU0V9DQp0eXBlX2RhaWx5IDwtIHNlbnRlbmNlX3NpZ25zICU+JQ0KICBncm91cF9ieShkYXRlLCB0eXBlX2xhYmVsKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIGluZGV4X3NlbnRfdHlwZSAgID0gbWVhbihzZW50X3NpZ24sICAgbmEucm0gPSBUUlVFKSwNCiAgICBpbmRleF9zdGFuY2VfdHlwZSA9IG1lYW4oc3RhbmNlX3NpZ24sIG5hLnJtID0gVFJVRSksDQogICAgLmdyb3VwcyA9ICJkcm9wIg0KICApDQoNCnR5cGVfZGFpbHkgJT4lDQogIGdyb3VwX2J5KHR5cGVfbGFiZWwpJT4lDQogIG11dGF0ZSh0eXBlX3NlbnRfbWEzMCA9IHJvbGxhcHBseShpbmRleF9zZW50X3R5cGUsIEZVTj1tZWFuLCB3aWR0aD0xNSwgZmlsbD1OQSxuYS5ybT1UKSwgDQogICAgICAgICB0eXBlX3N0YW5jZV9tYTMwID0gcm9sbGFwcGx5KGluZGV4X3N0YW5jZV90eXBlLCBGVU49bWVhbiwgd2lkdGg9MTUsIGZpbGw9TkEsbmEucm09VCkpJT4lDQogIGdncGxvdChhZXMoeD1kYXRlLCB5PXR5cGVfc2VudF9tYTMwLCBjb2xvcj10eXBlX2xhYmVsKSkrDQogIGdlb21fbGluZShsd2Q9MSkrDQogIGZhY2V0X3dyYXAofnR5cGVfbGFiZWwpKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb249ImJvdHRvbSIpDQoNCnR5cGVfZGFpbHkgPC0gdHlwZV9kYWlseSAlPiUNCiAgcGl2b3Rfd2lkZXIoDQogICAgaWRfY29scyAgID0gZGF0ZSwNCiAgICBuYW1lc19mcm9tICA9IHR5cGVfbGFiZWwsICAgICAgICAgICAgICANCiAgICB2YWx1ZXNfZnJvbSA9IGMoaW5kZXhfc2VudF90eXBlLCBpbmRleF9zdGFuY2VfdHlwZSksDQogICAgbmFtZXNfZ2x1ZSAgPSAiey52YWx1ZX1fe3R5cGVfbGFiZWx9IiwgDQogICAgdmFsdWVzX2ZpbGwgPSBsaXN0KGluZGV4X3NlbnRfdHlwZSA9IDAsIGluZGV4X3N0YW5jZV90eXBlID0gMCkNCiAgKSU+JQ0KICAgamFuaXRvcjo6Y2xlYW5fbmFtZXMoKQ0KDQoNCg0KDQpgYGANCkhlcmUsIHdlIHJlcHJlc2VudCB0aGUgMTUtZGF5cyBtb3ZpbmcgYXZlcmFnZSBvZiBzZW50aW1lbnQgKHRoZSBzdGFuY2UgaGFzIGEgc2ltaWxhciBkeW5hbWljcykgZGVjb21wb3NlZCBieSB0eXBlIG9mIENCREMgZGlzY3Vzc2VkLiBXaGlsZSBzcGVlY2hlcyBhYm91dCB3aG9sZXNhbGUgQ0JEQyBzdGFydHMgcmVsYXRpdmVseSBsYXRlIGNvbXBhcmVkIHRvIFVuc3BlY2lmaWVkIGFuZCBSZXRhaWwgQ0JEQ3MsIHRoZSBzZW50aW1lbnQgaXMgYWxzbyBoaWdoZXIuIA0KDQpXZSBhbHNvIGRlY29tcG9zZSBieSB0aGUgZGlzY291cnNlIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlZWNoIDoNCg0KYGBge3IsIGVjaG89RkFMU0V9DQpkaXNjb3Vyc2VfZGFpbHkgIDwtIHNlbnRlbmNlX3NpZ25zICU+JQ0KICBncm91cF9ieShkYXRlLCBkaXNjb3Vyc2VfbGFiZWwpJT4lDQogIHN1bW1hcml6ZSgNCiAgICBpbmRleF9zZW50X2Rpc2MgPSBtZWFuKHNlbnRfc2lnbiwgbmEucm09VCksIA0KICAgIGluZGV4X3N0YW5jZV9kaXNjID0gbWVhbihzdGFuY2Vfc2lnbiwgbmEucm09VCksIA0KICAgIC5ncm91cHM9ImRyb3AiIA0KICApDQoNCmRpc2NvdXJzZV9kYWlseSAlPiUgZ3JvdXBfYnkoZGlzY291cnNlX2xhYmVsKSU+JQ0KICBtdXRhdGUodHlwZV9zZW50X21hMzAgPSByb2xsYXBwbHkoaW5kZXhfc2VudF9kaXNjLCBGVU49bWVhbiwgd2lkdGg9MTUsIGZpbGw9TkEsbmEucm09VCksIA0KICAgICAgICAgdHlwZV9zdGFuY2VfbWEzMCA9IHJvbGxhcHBseShpbmRleF9zdGFuY2VfZGlzYywgRlVOPW1lYW4sIHdpZHRoPTE1LCBmaWxsPU5BLG5hLnJtPVQpKSU+JQ0KICBnZ3Bsb3QoYWVzKHg9ZGF0ZSwgeT10eXBlX3NlbnRfbWEzMCwgY29sb3I9ZGlzY291cnNlX2xhYmVsKSkrDQogIGdlb21fbGluZShsd2Q9MSkrDQogIGZhY2V0X3dyYXAofmRpc2NvdXJzZV9sYWJlbCkrDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIikNCg0KZGlzY291cnNlX2RhaWx5IDwtIGRpc2NvdXJzZV9kYWlseSAlPiUNCiAgcGl2b3Rfd2lkZXIoDQogICAgaWRfY29scyAgID0gZGF0ZSwNCiAgICBuYW1lc19mcm9tICA9IGRpc2NvdXJzZV9sYWJlbCwgICAgICAgICAgICAgIA0KICAgIHZhbHVlc19mcm9tID0gYyhpbmRleF9zZW50X2Rpc2MsIGluZGV4X3N0YW5jZV9kaXNjKSwNCiAgICBuYW1lc19nbHVlICA9ICJ7LnZhbHVlfV97ZGlzY291cnNlX2xhYmVsfSIsIA0KICAgIHZhbHVlc19maWxsID0gbGlzdChpbmRleF9zZW50X2Rpc2MgPSAwLCBpbmRleF9zdGFuY2VfZGlzYyA9IDApDQogICklPiUNCiAgIGphbml0b3I6OmNsZWFuX25hbWVzKCkNCg0KDQpgYGANCg0KV2UgYWxzbyBjb21iaW5lIHRoZSB0eXBlIGFuZCBkaXNjb3Vyc2Ugc2VudGltZW50IGFuZCBzdGFuY2UNCg0KYGBge3IsIGVjaG89RkFMU0V9DQpkaXNjb3Vyc2V0eXBlX2RhaWx5ICA8LSBzZW50ZW5jZV9zaWducyAlPiUNCiAgZ3JvdXBfYnkoZGF0ZSwgdHlwZV9sYWJlbCwgZGlzY291cnNlX2xhYmVsKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIGluZGV4X3NlbnRfdHlwZV9kaXNjICAgPSBtZWFuKHNlbnRfc2lnbiwgICBuYS5ybSA9IFRSVUUpLA0KICAgIGluZGV4X3N0YW5jZV90eXBlX2Rpc2MgPSBtZWFuKHN0YW5jZV9zaWduLCBuYS5ybSA9IFRSVUUpLA0KICAgIC5ncm91cHMgPSAiZHJvcCINCiAgKSU+JQ0KICBtdXRhdGUodHlwZV9kaXNjID0gcGFzdGUwKHR5cGVfbGFiZWwsICJfIiwgZGlzY291cnNlX2xhYmVsKSkNCg0KDQpkaXNjb3Vyc2V0eXBlX2RhaWx5JT4lIA0KICBncm91cF9ieSh0eXBlX2xhYmVsLCBkaXNjb3Vyc2VfbGFiZWwpICU+JQ0KICBtdXRhdGUodHlwZV9zZW50X21hMzAgPSByb2xsYXBwbHkoaW5kZXhfc2VudF90eXBlX2Rpc2MsIEZVTj1tZWFuLCB3aWR0aD0xNSwgZmlsbD1OQSxuYS5ybT1UKSklPiUNCiAgZ2dwbG90KGFlcyh4PWRhdGUsIHk9dHlwZV9zZW50X21hMzAsIGNvbG9yPWRpc2NvdXJzZV9sYWJlbCkpKw0KICBnZW9tX2xpbmUobHdkPTEpKw0KICBmYWNldF93cmFwKH50eXBlX2xhYmVsKSsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJib3R0b20iKQ0KICANCiBkaXNjb3Vyc2V0eXBlX2RhaWx5IDwtIGRpc2NvdXJzZXR5cGVfZGFpbHkgJT4lDQogIHBpdm90X3dpZGVyKA0KICAgIGlkX2NvbHMgICA9IGRhdGUsDQogICAgbmFtZXNfZnJvbSAgPSB0eXBlX2Rpc2MsICAgICAgICAgICAgICAjICJEZXZlbG9wZWQiLCAiRW1lcmdpbmciDQogICAgdmFsdWVzX2Zyb20gPSBjKGluZGV4X3NlbnRfdHlwZV9kaXNjLCBpbmRleF9zdGFuY2VfdHlwZV9kaXNjKSwNCiAgICBuYW1lc19nbHVlICA9ICJ7LnZhbHVlfV97dHlwZV9kaXNjfSIsICAjIHNlbnRfRGV2ZWxvcGVkLCBzdGFuY2VfRGV2ZWxvcGVkLCBldGMuDQogICAgdmFsdWVzX2ZpbGwgPSBsaXN0KGluZGV4X3NlbnRfdHlwZV9kaXNjID0gMCwgaW5kZXhfc3RhbmNlX3R5cGVfZGlzYyA9IDApDQogICklPiUNCiAgIGphbml0b3I6OmNsZWFuX25hbWVzKCkNCiANCg0KDQpgYGANCg0KV2UgYWxzbyBkZWNvbXBvc2UgYmV0d2VlbiBDZW50cmFsIEJhbmtzLiBCZWNhdXNlIG9mIGRhdGEgY29uc3RyYWludHMsIHdlIHByb2NlZGUgdG8gZ3JvdXAgZnJvbSBzZXZlcmFsIHdheXMuIEZpcnN0LCB3ZSBkaXN0aW5ndWlzaCBiZXR3ZWVuIERldmVsb3BlZCBNYXJrZXRzIENlbnRyYWwgQmFua3MgYW5kIEVtZXJnaW5nIE1hcmtldHMgQ2VudHJhbCBCYW5rcw0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCmJhbmtfZGFpbHkgPC0gc2VudGVuY2Vfc2lnbnMgJT4lDQogIGdyb3VwX2J5KGRhdGUsIENlbnRyYWxfQmFuaykgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBpbmRleF9zZW50X2NiICAgPSBtZWFuKHNlbnRfc2lnbiwgICBuYS5ybSA9IFRSVUUpLA0KICAgIGluZGV4X3N0YW5jZV9jYiA9IG1lYW4oc3RhbmNlX3NpZ24sIG5hLnJtID0gVFJVRSksDQogICAgLmdyb3VwcyA9ICJkcm9wIg0KICApDQoNCmRldmVtZV9kYWlseSA8LSBiYW5rX2RhaWx5ICU+JQ0KICBtdXRhdGUoZGV2ZW1lID0gY2FzZV93aGVuKENlbnRyYWxfQmFuayAlaW4lIGMoIkJhbmsgb2YgRW5nbGFuZCIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRXVyb3BlYW4gQ2VudHJhbCBCYW5rIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGZWQiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkJhbmsgb2YgSmFwYW4iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkJhbmsgb2YgQ2FuYWRhIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZXNlcnZlIEJhbmsgb2YgQXVzdHJhbGlhIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdmVyaWdlcyBSaWtzYmFuayIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3dpc3MgTmF0aW9uYWwgQmFuayIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ2VudHJhbCBCYW5rIG9mIEljZWxhbmQiLCAiTm9yZ2VzIEJhbmsiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5hdGlvbmFsIEJhbmsgb2YgRGVubWFyayIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZXNlcnZlIEJhbmsgb2YgTmV3IFplYWxhbmQiLCAiQmFuayBvZiBGaW5sYW5kIikgIH4iRGV2ZWxvcGVkIiwgDQogICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiJFbWVyZ2luZyIpKSU+JQ0KICBncm91cF9ieShkZXZlbWUsIGRhdGUpJT4lDQogIHN1bW1hcmlzZShpbmRleF9zZW50X2RldmVtZSA9IG1lYW4oaW5kZXhfc2VudF9jYixuYS5ybSA9IFRSVUUpLCANCiAgICAgICAgICAgICAgaW5kZXhfc3RhbmNlX2RldmVtZT1tZWFuKGluZGV4X3N0YW5jZV9jYixuYS5ybSA9IFRSVUUpKSU+JQ0KICBhcnJhbmdlKGRhdGUpDQoNCmRldmVtZV9kYWlseSAlPiUNCiAgZ3JvdXBfYnkoZGV2ZW1lKSU+JQ0KICBtdXRhdGUoc2VudF9tYSA9IHJvbGxhcHBseShpbmRleF9zZW50X2RldmVtZSwgRlVOPW1lYW4sIHdpZHRoPTE1LCBmaWxsPU5BLCBuYS5ybT1UKSklPiUNCiAgZ2dwbG90KGFlcyh4PWRhdGUsIHk9c2VudF9tYSwgY29sb3I9ZGV2ZW1lKSkrDQogIGdlb21fbGluZShsd2Q9MSkrDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIikNCg0KDQpkZXZlbWVfZGFpbHkgPC0gZGV2ZW1lX2RhaWx5ICU+JQ0KICBwaXZvdF93aWRlcigNCiAgICBpZF9jb2xzICAgPSBkYXRlLA0KICAgIG5hbWVzX2Zyb20gID0gZGV2ZW1lLCAgICAgICAgICAgICAgIyAiRGV2ZWxvcGVkIiwgIkVtZXJnaW5nIg0KICAgIHZhbHVlc19mcm9tID0gYyhpbmRleF9zZW50X2RldmVtZSwgaW5kZXhfc3RhbmNlX2RldmVtZSksDQogICAgbmFtZXNfZ2x1ZSAgPSAiey52YWx1ZX1fe2RldmVtZX0iLCAgIyBzZW50X0RldmVsb3BlZCwgc3RhbmNlX0RldmVsb3BlZCwgZXRjLg0KICAgIHZhbHVlc19maWxsID0gbGlzdChpbmRleF9zZW50X2RldmVtZSA9IDAsIGluZGV4X3N0YW5jZV9kZXZlbWUgPSAwKQ0KICApJT4lDQogICBqYW5pdG9yOjpjbGVhbl9uYW1lcygpDQoNCg0KDQoNCg0KYGBgDQpIZXJlLCB0aGUgMTUtZGF5cyBtb3ZpbmcgYXZlcmFnZSBvZiBzZW50aW1lbnQgc2hvd3Mgc29tZSBoZXRlcm9nZW5laXR5IGJldHdlZW4gZGV2ZWxvcGVkIGFuZCBlbWVyZ2luZyBtYXJrZXRzLiBIb3dldmVyLCBlbWVyZ2luZyBtYXJrZXRzIHRlbmQgdG8gY29tbXVuaWNhdGUgbW9yZSBwb3NpdGl2ZWx5IHRvd2FyZHMgQ0JEQy4gDQoNCldlIGFsc28gZ3JvdXAgdGhyZWUgbWFqb3IgQ2VudHJhbCBCYW5rcyAoRXVyb3BlYW4gQ2VudHJhbCBCYW5rLCBGZWQgYW5kIEJhbmsgb2YgSmFwYW4pDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KDQptYWpvcl9jYiA8LSBiYW5rX2RhaWx5ICU+JQ0KICBtdXRhdGUoQ0IgPSBjYXNlX3doZW4oQ2VudHJhbF9CYW5rICVpbiUgYygNCiAgICAiRXVyb3BlYW4gQ2VudHJhbCBCYW5rIiwgIkZlZCIsICJCYW5rIG9mIEphcGFuIikgfiAiRUNCL0ZlZC9Cb2oiLCANCiAgICBUUlVFIH4gIk90aGVycyIpKSU+JQ0KICBncm91cF9ieShDQiwgZGF0ZSklPiUNCiAgc3VtbWFyaXNlKGluZGV4X3NlbnRfY2IgPSBtZWFuKGluZGV4X3NlbnRfY2IsbmEucm0gPSBUUlVFKSwgDQogICAgICAgICAgICBpbmRleF9zdGFuY2VfY2I9bWVhbihpbmRleF9zdGFuY2VfY2IsbmEucm0gPSBUUlVFKSklPiUNCiAgYXJyYW5nZShkYXRlKQ0KDQptYWpvcl9jYiAlPiUNCiAgZ3JvdXBfYnkoQ0IpJT4lDQogIG11dGF0ZShzZW50X21hID0gcm9sbGFwcGx5KGluZGV4X3NlbnRfY2IsIEZVTj1tZWFuLCB3aWR0aD0xNSwgZmlsbD1OQSwgbmEucm09VCkpJT4lDQogIGdncGxvdChhZXMoeD1kYXRlLCB5PXNlbnRfbWEsIGNvbG9yPUNCKSkrDQogIGdlb21fbGluZShsd2Q9MSkrDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIikNCg0KbWFqb3JfY2IgPC0gbWFqb3JfY2IgJT4lDQogIHBpdm90X3dpZGVyKA0KICAgIGlkX2NvbHMgICA9IGRhdGUsDQogICAgbmFtZXNfZnJvbSAgPSBDQiwgICAgICAgICAgICAgICMgIkRldmVsb3BlZCIsICJFbWVyZ2luZyINCiAgICB2YWx1ZXNfZnJvbSA9IGMoaW5kZXhfc2VudF9jYiwgaW5kZXhfc3RhbmNlX2NiKSwNCiAgICBuYW1lc19nbHVlICA9ICJ7LnZhbHVlfV97Q0J9IiwgICMgc2VudF9EZXZlbG9wZWQsIHN0YW5jZV9EZXZlbG9wZWQsIGV0Yy4NCiAgICB2YWx1ZXNfZmlsbCA9IGxpc3QoaW5kZXhfc2VudF9jYiA9IDAsIGluZGV4X3N0YW5jZV9jYiA9IDApDQogICklPiUNCiAgIGphbml0b3I6OmNsZWFuX25hbWVzKCkNCg0KDQoNCmBgYA0KDQphbmQgdGhlIEVDQiBhZ2FpbnN0IHRoZSByZXN0IDoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KDQplY2JfZGFpbHkgPC0gYmFua19kYWlseSAlPiUNCiAgbXV0YXRlKENCID0gY2FzZV93aGVuKENlbnRyYWxfQmFuayAlaW4lIGMoDQogICAgIkV1cm9wZWFuIENlbnRyYWwgQmFuayIpIH4gIkVDQiIsIA0KICAgIFRSVUUgfiAiT3RoZXIiKSklPiUNCiAgZ3JvdXBfYnkoQ0IsIGRhdGUpJT4lDQogIHN1bW1hcmlzZShpbmRleF9zZW50X2NiID0gbWVhbihpbmRleF9zZW50X2NiLG5hLnJtID0gVFJVRSksIA0KICAgICAgICAgICAgaW5kZXhfc3RhbmNlX2NiPW1lYW4oaW5kZXhfc3RhbmNlX2NiLG5hLnJtID0gVFJVRSkpJT4lDQogIGFycmFuZ2UoZGF0ZSkNCg0KDQplY2JfZGFpbHklPiUNCiAgZ3JvdXBfYnkoQ0IpJT4lDQogIG11dGF0ZShzZW50X21hID0gcm9sbGFwcGx5KGluZGV4X3NlbnRfY2IsIEZVTj1tZWFuLCB3aWR0aD0xNSwgZmlsbD1OQSwgbmEucm09VCkpJT4lDQogIGdncGxvdChhZXMoeD1kYXRlLCB5PXNlbnRfbWEsIGNvbG9yPUNCKSkrDQogIGdlb21fbGluZShsd2Q9MSkrDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIikNCg0KZWNiX2RhaWx5IDwtIGVjYl9kYWlseSAlPiUNCiAgcGl2b3Rfd2lkZXIoDQogICAgaWRfY29scyAgID0gZGF0ZSwNCiAgICBuYW1lc19mcm9tICA9IENCLCAgICAgICAgICAgICAgIyAiRGV2ZWxvcGVkIiwgIkVtZXJnaW5nIg0KICAgIHZhbHVlc19mcm9tID0gYyhpbmRleF9zZW50X2NiLCBpbmRleF9zdGFuY2VfY2IpLA0KICAgIG5hbWVzX2dsdWUgID0gInsudmFsdWV9X3tDQn0iLCAgIyBzZW50X0RldmVsb3BlZCwgc3RhbmNlX0RldmVsb3BlZCwgZXRjLg0KICAgIHZhbHVlc19maWxsID0gbGlzdChpbmRleF9zZW50X2NiID0gMCwgaW5kZXhfc3RhbmNlX2NiID0gMCkNCiAgKSU+JQ0KICAgamFuaXRvcjo6Y2xlYW5fbmFtZXMoKQ0KDQoNCg0KYGBgDQoNCkluIGEgc2lnbmlmaWNhbnQgbnVtYmVyIG9mIHNwZWVjaGVzLCBDQkRDIGFyZSBvbmx5IHRyZWF0ZWQgYXMgYSBzdWJqZWN0IGFuZCAtIGV2ZW4gdGhvdWdoIHRoZSBzZW50aW1lbnQgb3Igc3RhbmNlIGFwcGVhcnMgcG9zaXRpdmUgaW4gYSBnaXZlbiBzcGVlY2ggLSB0aGlzIG1heSBub3QgYmUgcGVyY2VpdmVkIGJ5IGludmVzdG9ycyBhcyBhbiBpbXBvcnRhbnQgc2lnbmFsLiBXZSB0aHVzIGFsc28gY29uc3RydWN0IGEgZGF0YWJhc2UgdGhhdCBvbmx5IGdyb3VwcyBzcGVlY2hlcyB0aGF0IGV4cGxpY2l0ZWx5IG1lbnRpb24gQ0JEQyBpbiB0aGVpciB0aXRsZSwgc2hvd2luZyB0aGUgcmVsZXZhbmNlIG9mIHRoaXMgc3ViamVjdCB3aXRoaW4gdGhlIHNwZWVjaC4gVGhpcyBoYXMgYmVlbiBkb25lIGJ5IGFub3RoZXIgcGFwZXIgKGZpbmQgcmVmZXJlbmNlKS4NCg0KYGBge3IsIGVjaG89RkFMU0V9DQoNCnNwZWVjaGVzX2NiZGN0aXRsZSA8LSBzZW50ZW5jZV9zaWducyAlPiUNCiAgZmlsdGVyKGNiZGNfaW5fdGl0bGUgPT0gIlRydWUiKSU+JQ0KICBncm91cF9ieSh1cmwsIGRhdGUsIENlbnRyYWxfQmFuaywgdHlwZV9sYWJlbCkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBzZW50X3NpZ24gICA9IG1lYW4oc2VudF9zaWduLCAgIG5hLnJtID0gVFJVRSksDQogICAgc3RhbmNlX3NpZ24gPSBtZWFuKHN0YW5jZV9zaWduLCBuYS5ybSA9IFRSVUUpLA0KICAgIC5ncm91cHMgPSAiZHJvcCINCiAgKQ0KDQpkYXlfbGV2ZWxfY2JkY3RpdGxlIDwtIHNlbnRlbmNlX3NpZ25zICU+JQ0KICBmaWx0ZXIoY2JkY19pbl90aXRsZSA9PSAiVHJ1ZSIpICU+JQ0KICBncm91cF9ieSggZGF0ZSkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBpbmRleF9zZW50X2NiZGN0aXRsZSAgID0gbWVhbihzZW50X3NpZ24sICAgbmEucm0gPSBUUlVFKSwNCiAgICBpbmRleF9zdGFuY2VfY2JkY3RpdGxlID0gbWVhbihzdGFuY2Vfc2lnbiwgbmEucm0gPSBUUlVFKSwNCiAgICAuZ3JvdXBzID0gImRyb3AiKSU+JQ0KICBhcnJhbmdlKGRhdGUpDQoNCnR5cGVfY2JkY3RpdGxlPC0gc2VudGVuY2Vfc2lnbnMgJT4lDQogIGZpbHRlcihjYmRjX2luX3RpdGxlID09ICJUcnVlIikgJT4lDQogIGdyb3VwX2J5KCBkYXRlLCB0eXBlX2xhYmVsKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIGluZGV4X3NlbnRfdHlwZV9jYmRjdGl0bGUgICA9IG1lYW4oc2VudF9zaWduLCAgIG5hLnJtID0gVFJVRSksDQogICAgaW5kZXhfc3RhbmNlX3R5cGVfY2JkY3RpdGxlID0gbWVhbihzdGFuY2Vfc2lnbiwgbmEucm0gPSBUUlVFKSwNCiAgICAuZ3JvdXBzID0gImRyb3AiKSU+JQ0KICBhcnJhbmdlKGRhdGUpJT4lDQogIHBpdm90X3dpZGVyKA0KICAgIGlkX2NvbHMgICA9IGRhdGUsDQogICAgbmFtZXNfZnJvbSAgPSB0eXBlX2xhYmVsLCAgICAgICAgICAgICAgIyAiRGV2ZWxvcGVkIiwgIkVtZXJnaW5nIg0KICAgIHZhbHVlc19mcm9tID0gYyhpbmRleF9zZW50X3R5cGVfY2JkY3RpdGxlLCBpbmRleF9zdGFuY2VfdHlwZV9jYmRjdGl0bGUpLA0KICAgIG5hbWVzX2dsdWUgID0gInsudmFsdWV9X3t0eXBlX2xhYmVsfSIsICAjIHNlbnRfRGV2ZWxvcGVkLCBzdGFuY2VfRGV2ZWxvcGVkLCBldGMuDQogICAgdmFsdWVzX2ZpbGwgPSBsaXN0KGluZGV4X3NlbnRfdHlwZV9jYmRjdGl0bGUgPSAwLCBpbmRleF9zdGFuY2VfdHlwZV9jYmRjdGl0bGUgPSAwKQ0KICApDQogIA0KDQoNCmRpc2NvdXJzZV9jYmRjdGl0bGU8LSBzZW50ZW5jZV9zaWducyAlPiUNCiAgZmlsdGVyKGNiZGNfaW5fdGl0bGUgPT0gIlRydWUiKSAlPiUNCiAgZ3JvdXBfYnkoIGRhdGUsIGRpc2NvdXJzZV9sYWJlbCkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBpbmRleF9zZW50X2Rpc2NvdXJzZV9jYmRjdGl0bGUgICA9IG1lYW4oc2VudF9zaWduLCAgIG5hLnJtID0gVFJVRSksDQogICAgaW5kZXhfc3RhbmNlX2Rpc2NvdXJzZV9jYmRjdGl0bGUgPSBtZWFuKHN0YW5jZV9zaWduLCBuYS5ybSA9IFRSVUUpLA0KICAgIC5ncm91cHMgPSAiZHJvcCIpJT4lDQogIGFycmFuZ2UoZGF0ZSklPiUNCiAgcGl2b3Rfd2lkZXIoDQogICAgaWRfY29scyAgID0gZGF0ZSwNCiAgICBuYW1lc19mcm9tICA9IGRpc2NvdXJzZV9sYWJlbCwgICAgICAgICAgICAgICMgIkRldmVsb3BlZCIsICJFbWVyZ2luZyINCiAgICB2YWx1ZXNfZnJvbSA9IGMoaW5kZXhfc2VudF9kaXNjb3Vyc2VfY2JkY3RpdGxlLCBpbmRleF9zdGFuY2VfZGlzY291cnNlX2NiZGN0aXRsZSksDQogICAgbmFtZXNfZ2x1ZSAgPSAiey52YWx1ZX1fe2Rpc2NvdXJzZV9sYWJlbH0iLCAgIyBzZW50X0RldmVsb3BlZCwgc3RhbmNlX0RldmVsb3BlZCwgZXRjLg0KICAgIHZhbHVlc19maWxsID0gbGlzdChpbmRleF9zZW50X2Rpc2NvdXJzZV9jYmRjdGl0bGUgPSAwLCBpbmRleF9zdGFuY2VfZGlzY291cnNlX2NiZGN0aXRsZSA9IDApDQogICkNCiAgDQoNCmRpc2NvdXJzZV90eXBlX2NiZGN0aXRsZTwtIHNlbnRlbmNlX3NpZ25zICU+JQ0KICBmaWx0ZXIoY2JkY19pbl90aXRsZSA9PSAiVHJ1ZSIpICU+JQ0KICBtdXRhdGUoZGlzY190eXBlID0gcGFzdGUwKGRpc2NvdXJzZV9sYWJlbCwgIl8iLCB0eXBlX2xhYmVsKSklPiUNCiAgZ3JvdXBfYnkoIGRhdGUsIGRpc2NfdHlwZSkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBpbmRleF9zZW50X2Rpc2NfdHlwZV9jYmRjdGl0bGUgICA9IG1lYW4oc2VudF9zaWduLCAgIG5hLnJtID0gVFJVRSksDQogICAgaW5kZXhfc3RhbmNlX2Rpc2NfdHlwZV9jYmRjdGl0bGUgPSBtZWFuKHN0YW5jZV9zaWduLCBuYS5ybSA9IFRSVUUpLA0KICAgIC5ncm91cHMgPSAiZHJvcCIpJT4lDQogIGFycmFuZ2UoZGF0ZSklPiUNCiAgcGl2b3Rfd2lkZXIoDQogICAgaWRfY29scyAgID0gZGF0ZSwNCiAgICBuYW1lc19mcm9tICA9IGRpc2NfdHlwZSwgICAgICAgICAgICAgDQogICAgdmFsdWVzX2Zyb20gPSBjKGluZGV4X3NlbnRfZGlzY190eXBlX2NiZGN0aXRsZSwgaW5kZXhfc3RhbmNlX2Rpc2NfdHlwZV9jYmRjdGl0bGUpLA0KICAgIG5hbWVzX2dsdWUgID0gInsudmFsdWV9X3tkaXNjX3R5cGV9IiwgICMgc2VudF9EZXZlbG9wZWQsIHN0YW5jZV9EZXZlbG9wZWQsIGV0Yy4NCiAgICB2YWx1ZXNfZmlsbCA9IGxpc3QoaW5kZXhfc2VudF9kaXNjX3R5cGVfY2JkY3RpdGxlID0gMCwgaW5kZXhfc3RhbmNlX2Rpc2NfdHlwZV9jYmRjdGl0bGUgPSAwKQ0KICApDQoNCg0KZWNiX290aGVyIDwtIHNlbnRlbmNlX3NpZ25zICU+JQ0KICBmaWx0ZXIoY2JkY19pbl90aXRsZSA9PSAiVHJ1ZSIpICU+JQ0KICBtdXRhdGUoQ0IgPSBpZmVsc2UoQ2VudHJhbF9CYW5rID09ICJFdXJvcGVhbiBDZW50cmFsIEJhbmsiLCAiRUNCIiwgIk90aGVyIikpJT4lDQoNCiAgICBncm91cF9ieSggZGF0ZSwgQ0IpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgaW5kZXhfc2VudF9jYl9jYmRjdGl0bGUgICA9IG1lYW4oc2VudF9zaWduLCAgIG5hLnJtID0gVFJVRSksDQogICAgaW5kZXhfc3RhbmNlX2NiX2NiZGN0aXRsZSA9IG1lYW4oc3RhbmNlX3NpZ24sIG5hLnJtID0gVFJVRSksDQogICAgLmdyb3VwcyA9ICJkcm9wIiklPiUNCiAgYXJyYW5nZShkYXRlKSU+JQ0KICBwaXZvdF93aWRlcigNCiAgICBpZF9jb2xzICAgPSBkYXRlLA0KICAgIG5hbWVzX2Zyb20gID0gQ0IsICAgICAgICAgICAgIA0KICAgIHZhbHVlc19mcm9tID0gYyhpbmRleF9zZW50X2NiX2NiZGN0aXRsZSwgaW5kZXhfc3RhbmNlX2NiX2NiZGN0aXRsZSksDQogICAgbmFtZXNfZ2x1ZSAgPSAiey52YWx1ZX1fe0NCfSIsICAjIHNlbnRfRGV2ZWxvcGVkLCBzdGFuY2VfRGV2ZWxvcGVkLCBldGMuDQogICAgdmFsdWVzX2ZpbGwgPSBsaXN0KGluZGV4X3NlbnRfY2JfY2JkY3RpdGxlID0gMCwgaW5kZXhfc3RhbmNlX2NiX2NiZGN0aXRsZSA9IDApDQogICkNCg0KYGBgDQoNCg0KDQpBbmQgd2UgbWVyZ2UgZXZlcnl0aGluZyBpbiBhIHNpbmdsZSBkYXRhYmFzZSA6DQpgYGB7ciwgZWNobz1GQUxTRX0NCg0KDQphbGxfZGF5cyA8LSB0aWJibGUoZGF0ZSA9IHNlcShtaW4oc2VudGVuY2VfYmFzZSRkYXRlLCBuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4KHNlbnRlbmNlX2Jhc2UkZGF0ZSwgbmEucm0gPSBUUlVFKSwgYnkgPSAiZGF5IikpDQoNCg0KZGF0YWJhc2VfZGFpbHkgPC0gYWxsX2RheXMgJT4lDQogIGxlZnRfam9pbihkYXlfbGV2ZWwsIGJ5PSJkYXRlIikgJT4lDQogIGxlZnRfam9pbih0eXBlX2RhaWx5LCBieT0iZGF0ZSIpICU+JQ0KICBsZWZ0X2pvaW4oZGlzY291cnNlX2RhaWx5LCBieT0iZGF0ZSIpJT4lDQogIGxlZnRfam9pbihkaXNjb3Vyc2V0eXBlX2RhaWx5LCBieT0iZGF0ZSIpJT4lDQogIGxlZnRfam9pbihkZXZlbWVfZGFpbHksIGJ5PSJkYXRlIiklPiUNCiAgbGVmdF9qb2luKG1ham9yX2NiLCBieT0iZGF0ZSIpJT4lDQogIGxlZnRfam9pbihlY2JfZGFpbHksIGJ5PSJkYXRlIiklPiUNCiAgbXV0YXRlKHNwZWVjaGRheSA9IGlmZWxzZSggaXMubmEoc3BlZWNoZGF5KT09VFJVRSwgMCwgMSkpJT4lDQogIGxlZnRfam9pbihkYXlfbGV2ZWxfY2JkY3RpdGxlLCBieT0iZGF0ZSIpJT4lDQogIGxlZnRfam9pbih0eXBlX2NiZGN0aXRsZSwgYnk9ImRhdGUiKSU+JQ0KICBsZWZ0X2pvaW4oZGlzY291cnNlX2NiZGN0aXRsZSwgYnk9ImRhdGUiKSU+JQ0KICBsZWZ0X2pvaW4oZGlzY291cnNlX3R5cGVfY2JkY3RpdGxlLCBieT0iZGF0ZSIpJT4lDQogIGxlZnRfam9pbihlY2Jfb3RoZXIsIGJ5PSJkYXRlIikNCg0KZGF0YWJhc2VfZGFpbHkNCg0KDQoNCmBgYA0KDQpIZXJlLCBkYXlzIHdpdGhvdXQgc3BlZWNoIChzcGVlY2hkYXkgPT0gMCkgYXJlIHRyZWF0ZWQgYXMgTkFzLiBIb3dldmVyLCB3aGVuIGNvbWJpbmluZyBzcGVlY2ggZGF0YSB3aXRoIHN0YWJsZWNvaW5zIHN1cHBseSwgd2UgcmVwbGFjZSBOQXMgYnkgemVyb3MuDQoNCg0KDQojIyMgU3RhdGlzdGljcyBvZiB3ZWVrbHkgc3BlZWNoZXMNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KZGF0YWJhc2VfZGFpbHklPiUNCiAgZ3JvdXBfYnkoZGF0ZSklPiUNCiAgc3VtbWFyaXNlKGFjcm9zcyh3aGVyZShpcy5udW1lcmljKSwgfiBtZWFuKC54LCBuYS5ybSA9IFRSVUUpKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIHNlbGVjdCgtc3BlZWNoZGF5KSU+JQ0KICB0Ymxfc3VtbWFyeSgNCiAgICB0eXBlID0gbGlzdCgNCiAgICAgIGFsbF9jb250aW51b3VzKCkgfiAiY29udGludW91czIiLCAgIyB0b3VzIGxlcyBjb250aW51cw0KICAgICAgZGF0ZSB+ICJjb250aW51b3VzIiAgICAgICAgICAgICAgICMgc2F1ZiB3ZWVrDQogICAgKSwNCiAgICBzdGF0aXN0aWMgPSBsaXN0KA0KICAgICAgYWxsX2NvbnRpbnVvdXMoKSB+IGMoInttZWFufSAoe3NkfSkiKSwNCiAgICAgIGRhdGUgfiAie21pbn0sIHttYXh9IiAgICAgICAgICAgICAjIHNldWxlbWVudCBtaW4vbWF4IHBvdXIgd2Vlaw0KICAgICksDQogICAgbGFiZWwgPSBkYXRlIH4gIkRhdGUgKG1pbiwgbWF4KSINCiAgKSU+JQ0KICBtb2RpZnlfZm9vdG5vdGUoZXZlcnl0aGluZygpIH4gTkFfY2hhcmFjdGVyXykNCmBgYA0KDQoNCg==