Introduction

This is our first lab when we are considering 2 dimensions and instead of calculating univariate statistics by groups (or factors) of other variable - we will measure their common relationships based on co-variance and correlation coefficients.

*Please be very careful when choosing the measure of correlation! In case of different measurument scales we have to recode one of the variables into weaker scale.

It would be nice to add some additional plots in the background. Feel free to add your own sections and use external packages.

Data

This time we are going to use a typical credit scoring data with predefined “default” variables and personal demografic and income data. Please take a look closer at headers and descriptions of each variable.

Scatterplots

First let’s visualize our quantitative relationships using scatterplots.

You can also normalize the skewed distribution of incomes using log:

You can also normalize the skewed distribution of incomes using log:

## `geom_smooth()` using formula = 'y ~ x'

Scatterplots by groups

We can finally see if there any differences between risk status:

## [1] "The 'def' variable does not contain more than two risk categories."

We can also see more closely if there any differences between those two distributions adding their estimated density plots:

We can also put those plots together:

Scatterplots with density curves

We can also see more closely if there any differences between those two distributions adding their estimated density plots:

Correlation coefficients - Pearson’s linear correlation

Ok, let’s move to some calculations. In R, we can use the cor() function. It takes three arguments and the method: cor(x, y, method) For 2 quantitative data, with all assumptions met, we can calculate simple Pearson’s coefficient of linear correlation:

## [1] 0.574346

Ok, what about the percentage of the explained variability?

## [1] "Percentage of explained variability: 32.99%"

So as we can see almost ??? of total log of incomes’ variability is explained by differences in age. The rest (???) is probably explained by other factors.

Partial and semipartial correlation

The partial and semi-partial (also known as part) correlations are used to express the specific portion of variance explained by eliminating the effect of other variables when assessing the correlation between two variables.

Partial correlation holds constant one variable when computing the relations to others. Suppose we want to know the correlation between X and Y holding Z constant for both X and Y. That would be the partial correlation between X and Y controlling for Z.

Semipartial correlation holds Z constant for either X or Y, but not both, so if we wanted to control X for Z, we could compute the semipartial correlation between X and Y holding Z constant for X.

Suppose we want to know the correlation between the log of income and age controlling for years of employment. How highly correlated are these after controlling for tenure?

**There can be more than one control variable.

## [1] "Semipartial correlation between age and logincome controlling for employ:  0.269564642587719"
## [1] "P-value for semipartial correlation:  4.20596105041443e-13"

How can we interpret the obtained partial correlation coefficient? What is the difference between that one and the semi-partial coefficient:

## [1] "Correlation coefficients not calculated. Please check earlier sections."

Rank correlation

For 2 different scales - like for example this pair of variables: income vs. education levels - we cannot use Pearson’s coefficient. The only possibility is to rank also incomes… and lose some more detailed information about them.

First, let’s see boxplots of income by education levels.

Now, let’s see Kendal’s coefficient of rank correlation (robust for ties).

## [1] 0.1577567

Point-biserial correlation

Let’s try to verify if there is a significant relationship between incomes and risk status. First, let’s take a look at the boxplot:

Point-biserial correlation

The point-biserial correlation is used to measure the strength and direction of the association that exists between one binary variable and one continuous variable. In this case, we are investigating the potential relationship between income levels and default status (whether a customer has defaulted or not).

Visualizing the Relationship with a Boxplot

First, let’s visually inspect the relationship between income and default status using a boxplot. This will provide a visual summary of the median, quartiles, and outliers for income categorized by default status.

If you would like to compare 1 quantitative variable (income) and 1 dychotomous variable (default status - binary), then you can use point-biserial coefficient:

## [1] 0.07096966

Nonlinear correlation - eta coefficient

If you would like to check if there are any nonlinearities between 2 variables, the only possibility (beside transformations and linear analysis) is to calculate “eta” coefficient and compare it with the Pearson’s linear coefficient.

## [1] "Eta squared:  0.00503669216065044" "Eta squared:  0.00503669216065044"

Correlation matrix

We can also prepare the correlation matrix for all quantitative variables stored in our data frame.

We can use ggcorr() function:

As you can see - the default correlation matrix is not the best idea for all measurement scales (including binary variable “default”).

That’s why now we can perform our bivariate analysis with ggpair with grouping.

Correlation matrix with scatterplots

Here is what we are about to calculate: - The correlation matrix between age, log_income, employ, address, debtinc, creddebt, and othdebt variable grouped by whether the person has a default status or not. - Plot the distribution of each variable by group - Display the scatter plot with the trend by group

## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Qualitative data

In case of two variables measured on nominal or ordinal&nominal scale - we are forced to organize so called “contingency” table with frequencies and calculate some kind of the correlation coefficient based on them. This is so called “contingency analysis”.

Let’s consider one example based on our data: verify, if there is any significant correlation between education level and credit risk.

#education_default_table <- table(bank$educ, bank$def)
#chisq.test(education_default_table)
## Warning in chisq.test(education_default_table): аппроксимация на основе
## хи-квадрат может быть неправильной
## 
##  Pearson's Chi-squared test
## 
## data:  education_default_table
## X-squared = 11.492, df = 4, p-value = 0.02155

Exercise 1. Contingency analysis.

Do you believe in the Afterlife? https://nationalpost.com/news/canada/millennials-do-you-believe-in-life-after-life A survey was conducted and a random sample of 1091 questionnaires is given in the form of the following contingency table:

##         Believe
## Gender   Yes  No
##   Female 435 375
##   Male   147 134

##         Believe
## Gender   Yes  No
##   Female 435 375
##   Male   147 134

Our task is to check if there is a significant relationship between the belief in the afterlife and gender. We can perform this procedure with the simple chi-square statistics and chosen qualitative correlation coefficient (two-way 2x2 table).

## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  dane
## X-squared = 0.11103, df = 1, p-value = 0.739
##         Believe
## Gender         Yes        No
##   Female 0.3987168 0.3437214
##   Male   0.1347388 0.1228231
##         Believe
## Gender   Yes  No
##   Female 435 147
##   Male   375 134
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  dane_table
## X-squared = 0.11103, df = 1, p-value = 0.739
##         Believe
## Gender         Yes        No
##   Female 0.7474227 0.2525773
##   Male   0.7367387 0.2632613

As you can see we can calculate our chi-square statistic really quickly for two-way tables or larger. Now we can standardize this contingency measure to see if the relationship is significant.

## [1] 0.01218871

## [1] "Phi Coefficient: 0.0121887076777122"
## [1] "Cramer's V: 0.0121887076777122"

Exercise 2. Contingency analysis for the ‘Titanic’ data.

Let’s consider the titanic dataset which contains a complete list of passengers and crew members on the RMS Titanic. It includes a variable indicating whether a person did survive the sinking of the RMS Titanic on April 15, 1912. A data frame contains 2456 observations on 14 variables.

The website http://www.encyclopedia-titanica.org/ offers detailed information about passengers and crew members on the RMS Titanic. According to the website 1317 passengers and 890 crew member were aboard.

8 musicians and 9 employees of the shipyard company are listed as passengers, but travelled with a free ticket, which is why they have NA values in fare. In addition to that, fare is truely missing for a few regular passengers.

## 'data.frame':    2456 obs. of  16 variables:
##  $ Status                          : chr  "" "" "" "" ...
##  $ Disembarked.at                  : chr  "Cherbourg" "Cherbourg" "Cherbourg" "Cherbourg" ...
##  $ Home.Country                    : chr  "" "" "" "" ...
##  $ Age                             : num  NA NA NA 54 NA NA NA 29 25 36 ...
##  $ Year.of.Birth                   : int  NA NA NA 1858 NA NA NA 1883 1887 1876 ...
##  $ Crew.or.Passenger.              : chr  "Passenger" "Passenger" "Passenger" "Passenger" ...
##  $ Gender                          : chr  "Male" "Female" "Female" "Male" ...
##  $ Class...Department              : chr  "2nd Class" "2nd Class" "2nd Class" "1st Class" ...
##  $ Embarked                        : chr  "Southampton" "Southampton" "Southampton" "Southampton" ...
##  $ Job                             : chr  "" "" "" "Butcher" ...
##  $ Job.details                     : chr  "" "" "" "Butcher's Shop Proprietor" ...
##  $ Ticket.Number                   : chr  "761" "88" "404" "86" ...
##  $ Fare.Price                      : chr  "P1" "P1" "P1" "P1 10s" ...
##  $ Fare_GBP                        : num  1 1 1 1.5 1.5 1.5 1.5 10.5 10.5 10.5 ...
##  $ Fare_today                      : num  82.1 82.1 82.1 123.2 123.2 ...
##  $ Profile.on.Encyclopedia.Titanica: chr  "http://www.encyclopedia-titanica.org/titanic-biography/j-de-grasse.html" "http://www.encyclopedia-titanica.org/titanic-biography/evans.html" "http://www.encyclopedia-titanica.org/titanic-biography/mullen.html" "http://www.encyclopedia-titanica.org/titanic-cross-channel-passenger/henry-swaffin-wotton.html" ...
##                          Status Disembarked.at Home.Country Age Year.of.Birth
## DE GRASSE, Mr J.                     Cherbourg               NA            NA
## EVANS, Miss                          Cherbourg               NA            NA
## MULLEN,                              Cherbourg               NA            NA
## WOTTON, Mr Henry Swaffin             Cherbourg               54          1858
## BRAND, Mr                            Cherbourg               NA            NA
## FLETCHER, Miss N.                    Cherbourg               NA            NA
##                          Crew.or.Passenger. Gender Class...Department
## DE GRASSE, Mr J.                  Passenger   Male          2nd Class
## EVANS, Miss                       Passenger Female          2nd Class
## MULLEN,                           Passenger Female          2nd Class
## WOTTON, Mr Henry Swaffin          Passenger   Male          1st Class
## BRAND, Mr                         Passenger   Male          1st Class
## FLETCHER, Miss N.                 Passenger Female          1st Class
##                             Embarked     Job               Job.details
## DE GRASSE, Mr J.         Southampton                                  
## EVANS, Miss              Southampton                                  
## MULLEN,                  Southampton                                  
## WOTTON, Mr Henry Swaffin Southampton Butcher Butcher's Shop Proprietor
## BRAND, Mr                Southampton                                  
## FLETCHER, Miss N.        Southampton                                  
##                          Ticket.Number Fare.Price Fare_GBP Fare_today
## DE GRASSE, Mr J.                   761         P1      1.0     82.110
## EVANS, Miss                         88         P1      1.0     82.110
## MULLEN,                            404         P1      1.0     82.110
## WOTTON, Mr Henry Swaffin            86     P1 10s      1.5    123.165
## BRAND, Mr                            8     P1 10s      1.5    123.165
## FLETCHER, Miss N.                  405     P1 10s      1.5    123.165
##                                                                                        Profile.on.Encyclopedia.Titanica
## DE GRASSE, Mr J.                                http://www.encyclopedia-titanica.org/titanic-biography/j-de-grasse.html
## EVANS, Miss                                           http://www.encyclopedia-titanica.org/titanic-biography/evans.html
## MULLEN,                                              http://www.encyclopedia-titanica.org/titanic-biography/mullen.html
## WOTTON, Mr Henry Swaffin http://www.encyclopedia-titanica.org/titanic-cross-channel-passenger/henry-swaffin-wotton.html
## BRAND, Mr                                             http://www.encyclopedia-titanica.org/titanic-biography/brand.html
## FLETCHER, Miss N.                                http://www.encyclopedia-titanica.org/titanic-biography/n-fletcher.html
##  [1] "Status"                           "Disembarked.at"                  
##  [3] "Home.Country"                     "Age"                             
##  [5] "Year.of.Birth"                    "Crew.or.Passenger."              
##  [7] "Gender"                           "Class...Department"              
##  [9] "Embarked"                         "Job"                             
## [11] "Job.details"                      "Ticket.Number"                   
## [13] "Fare.Price"                       "Fare_GBP"                        
## [15] "Fare_today"                       "Profile.on.Encyclopedia.Titanica"
##     Status          Disembarked.at     Home.Country            Age       
##  Length:2456        Length:2456        Length:2456        Min.   : 0.17  
##  Class :character   Class :character   Class :character   1st Qu.:23.00  
##  Mode  :character   Mode  :character   Mode  :character   Median :29.00  
##                                                           Mean   :30.59  
##                                                           3rd Qu.:38.00  
##                                                           Max.   :74.00  
##                                                           NA's   :32     
##  Year.of.Birth  Crew.or.Passenger.    Gender          Class...Department
##  Min.   :1837   Length:2456        Length:2456        Length:2456       
##  1st Qu.:1874   Class :character   Class :character   Class :character  
##  Median :1882   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :1881                                                           
##  3rd Qu.:1889                                                           
##  Max.   :1973                                                           
##  NA's   :32                                                             
##    Embarked             Job            Job.details        Ticket.Number     
##  Length:2456        Length:2456        Length:2456        Length:2456       
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##                                                                             
##   Fare.Price           Fare_GBP        Fare_today      
##  Length:2456        Min.   :  1.00   Min.   :   82.11  
##  Class :character   1st Qu.:  7.90   1st Qu.:  648.33  
##  Mode  :character   Median : 14.45   Median : 1186.83  
##                     Mean   : 33.16   Mean   : 2722.71  
##                     3rd Qu.: 31.07   3rd Qu.: 2551.06  
##                     Max.   :512.33   Max.   :42067.35  
##                     NA's   :1136     NA's   :1136      
##  Profile.on.Encyclopedia.Titanica
##  Length:2456                     
##  Class :character                
##  Mode  :character                
##                                  
##                                  
##                                  
## 
## < table of extent 0 x 0 >
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  dane_table
## X-squared = 0.11103, df = 1, p-value = 0.739
LS0tDQp0aXRsZTogIkRlc2NyaXB0aXZlIFN0YXRpc3RpY3MiDQphdXRob3I6ICJUZW1pcmxhbiBPc3Bhbm92KDIwMTYzOSksIFJhbWF6YW4gU2FneW55c2goMjAxODczKSwgSmFrdWIgUGFwcm9ja2koMTk4MjI5KSINCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0aGVtZTogY2VydWxlYW4NCiAgICBoaWdobGlnaHQ6IHRleHRtYXRlDQogICAgZm9udHNpemU6IDEwcHQNCiAgICB0b2M6IHRydWUNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgdG9jX2Zsb2F0Og0KICAgICAgY29sbGFwc2VkOiBmYWxzZQ0KICAgIGRmX3ByaW50OiBkZWZhdWx0DQogICAgdG9jX2RlcHRoOiA1DQogIHBkZl9kb2N1bWVudDoNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZGVwdGg6ICc1Jw0Kc3VidGl0bGU6IEJpdmFyaWF0ZSBBbmFseXNpcw0KZWRpdG9yX29wdGlvbnM6DQogIG1hcmtkb3duOg0KICAgIHdyYXA6IDcyDQotLS0NCg0KYGBge3Igc2V0dXAsCW1lc3NhZ2UgPSBGQUxTRSwJd2FybmluZyA9IEZBTFNFLAlpbmNsdWRlID0gRkFMU0V9DQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KEhTQVVSMykNCmxpYnJhcnkoaGF2ZW4pDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGdyaWRFeHRyYSkNCmxpYnJhcnkocHBjb3IpICMgdGhpcyBwYWNrYWdlIGNvbXB1dGVzIHBhcnRpYWwgYW5kIHNlbWlwYXJ0aWFsIGNvcnJlbGF0aW9ucy4NCmxpYnJhcnkobHRtKSAjIHRoaXMgcGFja2FnZSBjb21wdXRlcyBwb2ludC1iaXNlcmlhbCBjb3JyZWxhdGlvbnMuDQpsaWJyYXJ5KGRldnRvb2xzKSANCiNpbnN0YWxsX2dpdGh1YigibWFya2hlY2ttYW5uL3J5b3VyZWFkeSIpICMgcGxlYXNlIGluc3RhbGwgcGFja2FnZSAicnlvdXJlYWR5IiBmcm9tIGdpdGh1YiEgKHRoZW4gIyBpdCkNCmxpYnJhcnkocnlvdXJlYWR5KSAjIHRoaXMgcGFja2FnZSBjb21wdXRlcyBub25saW5lYXIgImV0YSIgY29ycmVsYXRpb25zLg0KbGlicmFyeShHR2FsbHkpICMgdGhpcyBwYWNrYWdlIGNvbXB1dGVzIGNvcnJlbGF0aW9uIG1hdHJpeC4NCmxpYnJhcnkocHN5Y2gpICMgdGhpcyBwYWNrYWdlIGNvbXB1dGVzIHF1YWxpdGF0aXZlIGNvcnJlbGF0aW9ucy4NCmxpYnJhcnkoRGVzY1Rvb2xzKSAjIHRoaXMgcGFja2FnZSBjb21wdXRlcyBxdWFsaXRhdGl2ZSBjb3JyZWxhdGlvbnMuDQpsaWJyYXJ5KGdyaWQpICAjIExvYWQgdGhlIGdyaWQgcGFja2FnZSBleHBsaWNpdGx5DQpgYGANCg0KDQojIyBJbnRyb2R1Y3Rpb24NCg0KVGhpcyBpcyBvdXIgZmlyc3QgbGFiIHdoZW4gd2UgYXJlIGNvbnNpZGVyaW5nIDIgZGltZW5zaW9ucyBhbmQgaW5zdGVhZCBvZiBjYWxjdWxhdGluZyB1bml2YXJpYXRlIHN0YXRpc3RpY3MgYnkgZ3JvdXBzIChvciBmYWN0b3JzKSBvZiBvdGhlciB2YXJpYWJsZSAtIHdlIHdpbGwgbWVhc3VyZSB0aGVpciBjb21tb24gcmVsYXRpb25zaGlwcyBiYXNlZCBvbiBjby12YXJpYW5jZSBhbmQgY29ycmVsYXRpb24gY29lZmZpY2llbnRzLiANCg0KKlBsZWFzZSBiZSB2ZXJ5IGNhcmVmdWwgd2hlbiBjaG9vc2luZyB0aGUgbWVhc3VyZSBvZiBjb3JyZWxhdGlvbiEgSW4gY2FzZSBvZiBkaWZmZXJlbnQgbWVhc3VydW1lbnQgc2NhbGVzIHdlIGhhdmUgdG8gcmVjb2RlIG9uZSBvZiB0aGUgdmFyaWFibGVzIGludG8gd2Vha2VyIHNjYWxlLg0KDQpJdCB3b3VsZCBiZSBuaWNlIHRvIGFkZCBzb21lIGFkZGl0aW9uYWwgcGxvdHMgaW4gdGhlIGJhY2tncm91bmQuIEZlZWwgZnJlZSB0byBhZGQgeW91ciBvd24gc2VjdGlvbnMgYW5kIHVzZSBleHRlcm5hbCBwYWNrYWdlcy4NCg0KIyMgRGF0YQ0KDQpUaGlzIHRpbWUgd2UgYXJlIGdvaW5nIHRvIHVzZSBhIHR5cGljYWwgY3JlZGl0IHNjb3JpbmcgZGF0YSB3aXRoIHByZWRlZmluZWQgImRlZmF1bHQiIHZhcmlhYmxlcyBhbmQgcGVyc29uYWwgZGVtb2dyYWZpYyBhbmQgaW5jb21lIGRhdGEuIFBsZWFzZSB0YWtlIGEgbG9vayBjbG9zZXIgYXQgaGVhZGVycyBhbmQgZGVzY3JpcHRpb25zIG9mIGVhY2ggdmFyaWFibGUuDQoNCmBgYHtyIGxvYWQtZGF0YSwgd2FybmluZz1UUlVFLCBpbmNsdWRlPUZBTFNFfQ0KZG93bmxvYWQuZmlsZSgiaHR0cHM6Ly9naXRodWIuY29tL2tmbGlzaWtvd3NraS9kcy9ibG9iL21hc3Rlci9iYW5rX2RlZmF1bHRzLnNhdj9yYXc9dHJ1ZSIsIGRlc3RmaWxlID0iYmFua19kZWZhdWx0cy5zYXYiLG1vZGU9IndiIikNCmJhbmtfZGVmYXVsdHMgPC0gcmVhZF9zYXYoImJhbmtfZGVmYXVsdHMuc2F2IikNCmJhbms8LW5hLm9taXQoYmFua19kZWZhdWx0cykNCmJhbmskZGVmPC1hcy5mYWN0b3IoYmFuayRkZWZhdWx0KQ0KYmFuayRlZHVjPC1hcy5mYWN0b3IoYmFuayRlZCkNCmBgYA0KDQojIyBTY2F0dGVycGxvdHMNCg0KRmlyc3QgbGV0J3MgdmlzdWFsaXplIG91ciBxdWFudGl0YXRpdmUgcmVsYXRpb25zaGlwcyB1c2luZyBzY2F0dGVycGxvdHMuIA0KDQpgYGB7ciBlY2hvPUZBTFNFLCB3YXJuaW5nPVRSVUV9DQpsaWJyYXJ5KGdncGxvdDIpDQoNCmJhbmskbG9naW5jb21lIDwtIGxvZyhiYW5rJGluY29tZSkgIA0KDQpnZ3Bsb3QoYmFuaywgYWVzKHggPSBhZ2UsIHkgPSBsb2dpbmNvbWUpKSArDQogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gZGVmKSwgc2l6ZSA9IDMsIHNoYXBlID0gMTkpICsgIA0KICBsYWJzKHRpdGxlID0gIlNjYXR0ZXIgUGxvdCBvZiBBZ2UgdnMuIExvZyhJbmNvbWUpIiwNCiAgICAgICB4ID0gIkFnZSIsDQogICAgICAgeSA9ICJMb2cgb2YgSW5jb21lIikgKw0KICB0aGVtZV9taW5pbWFsKCkgIA0KDQppZiAoImVtcGxveSIgJWluJSBuYW1lcyhiYW5rKSkgew0KICBnZ3Bsb3QoYmFuaywgYWVzKHggPSBhZ2UsIHkgPSBsb2dpbmNvbWUpKSArDQogICAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBkZWYsIHNpemUgPSBlbXBsb3kpLCBzaGFwZSA9IDIxKSArICANCiAgICBzY2FsZV9zaXplX2NvbnRpbnVvdXMocmFuZ2UgPSBjKDEsIDYpKSArICANCiAgICBsYWJzKHRpdGxlID0gIlNjYXR0ZXIgUGxvdCBvZiBBZ2UgdnMuIExvZyhJbmNvbWUpIGJ5IEVtcGxveW1lbnQgTGVuZ3RoIiwNCiAgICAgICAgIHggPSAiQWdlIiwNCiAgICAgICAgIHkgPSAiTG9nIG9mIEluY29tZSIsDQogICAgICAgICBzaXplID0gIkVtcGxveW1lbnQgTGVuZ3RoIikgKw0KICAgIHRoZW1lX21pbmltYWwoKSAgIyBDb25zaXN0ZW50IHRoZW1lIGZvciBjbGFyaXR5DQp9IGVsc2Ugew0KICBwcmludCgiVGhlIHZhcmlhYmxlICdlbXBsb3knIGRvZXMgbm90IGV4aXN0IGluIHRoZSBkYXRhc2V0LiBBZGp1c3QgdGhlIHZhcmlhYmxlIG5hbWUgYWNjb3JkaW5nbHkuIikNCn0NCg0KDQpgYGANCg0KWW91IGNhbiBhbHNvIG5vcm1hbGl6ZSB0aGUgc2tld2VkIGRpc3RyaWJ1dGlvbiBvZiBpbmNvbWVzIHVzaW5nIGxvZzoNCg0KWW91IGNhbiBhbHNvIG5vcm1hbGl6ZSB0aGUgc2tld2VkIGRpc3RyaWJ1dGlvbiBvZiBpbmNvbWVzIHVzaW5nIGxvZzoNCg0KYGBge3IgZWNobz1GQUxTRSwgd2FybmluZz1UUlVFfQ0KIyBMb2FkIHJlcXVpcmVkIHBhY2thZ2VzDQpsaWJyYXJ5KGdncGxvdDIpDQoNCiMgQXNzdW1pbmcgJ2JhbmsnIGlzIHlvdXIgZGF0YWZyYW1lIGFuZCBpbmNsdWRlcyAnYWdlJyBhbmQgJ2luY29tZScNCiMgVmVyaWZ5IG9yIGNyZWF0ZSB0aGUgbG9nLXRyYW5zZm9ybWVkIGluY29tZSBpZiBub3QgcHJldmlvdXNseSBjcmVhdGVkDQppZighImxvZ2luY29tZSIgJWluJSBuYW1lcyhiYW5rKSkgew0KICBiYW5rJGxvZ2luY29tZSA8LSBsb2coYmFuayRpbmNvbWUgKyAxKSAgIyBBZGRpbmcgMSB0byBhdm9pZCBsb2coMCkgaXNzdWVzDQp9DQoNCiMgU2NhdHRlciBwbG90IHVzaW5nIGxvZy10cmFuc2Zvcm1lZCBpbmNvbWUNCmdncGxvdChiYW5rLCBhZXMoeCA9IGFnZSwgeSA9IGxvZ2luY29tZSkpICsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBkZWYpLCBhbHBoYSA9IDAuNikgKyAgIyBBZGRpbmcgdHJhbnNwYXJlbmN5IHRvIHBvaW50cw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEZBTFNFLCBjb2xvciA9ICJibHVlIikgKyAgIyBBZGRpbmcgYSBsaW5lYXIgbW9kZWwgZml0IGxpbmUgd2l0aG91dCBjb25maWRlbmNlIGludGVydmFsDQogIGxhYnModGl0bGUgPSAiQWdlIHZzIExvZy10cmFuc2Zvcm1lZCBJbmNvbWUiLA0KICAgICAgIHggPSAiQWdlIiwNCiAgICAgICB5ID0gIkxvZyBvZiBJbmNvbWUiKSArDQogIHRoZW1lX21pbmltYWwoKSAgIyBDbGVhbiB0aGVtZSBmb3IgYmV0dGVyIHZpc3VhbCBpbnRlcnByZXRhdGlvbg0KDQoNCmBgYA0KDQojIyBTY2F0dGVycGxvdHMgYnkgZ3JvdXBzIA0KDQpXZSBjYW4gZmluYWxseSBzZWUgaWYgdGhlcmUgYW55IGRpZmZlcmVuY2VzIGJldHdlZW4gcmlzayBzdGF0dXM6DQoNCmBgYHtyIGVjaG89RkFMU0UsIHdhcm5pbmc9VFJVRX0NCiMgQXNzdW1pbmcgJ2JhbmsnIGlzIGFscmVhZHkgbG9hZGVkIHdpdGggJ2RlZicgYXMgdGhlIHJpc2sgc3RhdHVzIGFuZCAnYWdlJyBhbmQgJ2xvZ2luY29tZScgYXMgdmFyaWFibGVzDQojIEVuc3VyZSAnbG9naW5jb21lJyBpcyBsb2ctdHJhbnNmb3JtZWQgaW5jb21lOyBpZiBub3QsIGNvbXB1dGUgaXQNCmlmKCEibG9naW5jb21lIiAlaW4lIG5hbWVzKGJhbmspKSB7DQogIGJhbmskbG9naW5jb21lIDwtIGxvZyhiYW5rJGluY29tZSArIDEpICAjIExvZyB0cmFuc2Zvcm1hdGlvbiBvZiBpbmNvbWUgdG8gbm9ybWFsaXplIGRpc3RyaWJ1dGlvbg0KfQ0KDQojIFNjYXR0ZXJwbG90IG9mIEFnZSB2cyBMb2cgSW5jb21lIGJ5IGRlZmF1bHQgc3RhdHVzDQpnZ3Bsb3QoYmFuaywgYWVzKHggPSBhZ2UsIHkgPSBsb2dpbmNvbWUsIGNvbG9yID0gZGVmKSkgKw0KICBnZW9tX3BvaW50KGFscGhhID0gMC42KSArICAjIFNlbWktdHJhbnNwYXJlbnQgcG9pbnRzIHRvIG1hbmFnZSBvdmVycGxvdHRpbmcNCiAgbGFicyh0aXRsZSA9ICJTY2F0dGVycGxvdCBvZiBBZ2UgdnMuIExvZyBJbmNvbWUgYnkgRGVmYXVsdCBTdGF0dXMiLA0KICAgICAgIHggPSAiQWdlIiwNCiAgICAgICB5ID0gIkxvZyBvZiBJbmNvbWUiLA0KICAgICAgIGNvbG9yID0gIkRlZmF1bHQgU3RhdHVzIikgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygicmVkIiwgImdyZWVuIikpICsgICMgUmVkIGZvciBkZWZhdWx0LCBncmVlbiBmb3Igbm9uLWRlZmF1bHQNCiAgdGhlbWVfbWluaW1hbCgpICAjIE1pbmltYWwgdGhlbWUgZm9yIGEgY2xlYW4gbG9vaw0KDQojIEZvciBhbiBhZHZhbmNlZCB2aXN1YWxpemF0aW9uLCBhZGQgZmFjZXRzIGlmIHRoZSBkYXRhc2V0IGluY2x1ZGVzIG1vcmUgdGhhbiB0d28gY2F0ZWdvcmllcyBvZiByaXNrIHN0YXR1cw0KaWYobGVuZ3RoKHVuaXF1ZShiYW5rJGRlZikpID4gMikgew0KICBnZ3Bsb3QoYmFuaywgYWVzKHggPSBhZ2UsIHkgPSBsb2dpbmNvbWUsIGNvbG9yID0gZGVmKSkgKw0KICAgIGdlb21fcG9pbnQoYWxwaGEgPSAwLjYpICsNCiAgICBmYWNldF93cmFwKH5kZWYsIHNjYWxlcyA9ICJmcmVlX3kiKSArICAjIEZhY2V0aW5nIGJ5IGRlZmF1bHQgc3RhdHVzIHRvIHNlZSBkaWZmZXJlbnQgcGxvdHMgZm9yIGVhY2ggY2F0ZWdvcnkNCiAgICBsYWJzKHRpdGxlID0gIkFnZSB2cy4gTG9nIEluY29tZSBieSBEZWZhdWx0IFN0YXR1cyIsDQogICAgICAgICB4ID0gIkFnZSIsDQogICAgICAgICB5ID0gIkxvZyBvZiBJbmNvbWUiLA0KICAgICAgICAgY29sb3IgPSAiRGVmYXVsdCBTdGF0dXMiKSArDQogICAgdGhlbWVfbWluaW1hbCgpDQp9IGVsc2Ugew0KICBwcmludCgiVGhlICdkZWYnIHZhcmlhYmxlIGRvZXMgbm90IGNvbnRhaW4gbW9yZSB0aGFuIHR3byByaXNrIGNhdGVnb3JpZXMuIikNCn0NCg0KDQoNCg0KYGBgDQoNCldlIGNhbiBhbHNvIHNlZSBtb3JlIGNsb3NlbHkgaWYgdGhlcmUgYW55IGRpZmZlcmVuY2VzIGJldHdlZW4gdGhvc2UgdHdvIGRpc3RyaWJ1dGlvbnMgYWRkaW5nIHRoZWlyIGVzdGltYXRlZCBkZW5zaXR5IHBsb3RzOg0KDQpgYGB7ciBlY2hvPUZBTFNFLCB3YXJuaW5nPVRSVUV9DQojIEFzc3VtaW5nICdiYW5rJyBpcyBhbHJlYWR5IGxvYWRlZCB3aXRoICdhZ2UnLCAnbG9naW5jb21lJywgYW5kICdkZWYnIGFzIHRoZSByaXNrIHN0YXR1cw0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShncmlkRXh0cmEpICAjIEZvciBhcnJhbmdpbmcgZ2dwbG90cw0KDQojIENyZWF0ZSBhIGNvbWJpbmVkIHNjYXR0ZXIgYW5kIGRlbnNpdHkgcGxvdCBmb3IgQWdlIGFuZCBMb2cgSW5jb21lIGNvbG9yZWQgYnkgRGVmYXVsdCBTdGF0dXMNCnNjYXR0ZXJfcGxvdCA8LSBnZ3Bsb3QoYmFuaywgYWVzKHggPSBhZ2UsIHkgPSBsb2dpbmNvbWUsIGNvbG9yID0gZGVmKSkgKw0KICBnZW9tX3BvaW50KGFscGhhID0gMC41KSArICAjIFVzZSBzZW1pLXRyYW5zcGFyZW5jeSBmb3IgcG9pbnRzDQogIGdlb21fZGVuc2l0eV8yZCgpICsgICMgQWRkIDJEIGRlbnNpdHkgY29udG91cnMNCiAgbGFicyh0aXRsZSA9ICJTY2F0dGVyIGFuZCBEZW5zaXR5IFBsb3Qgb2YgQWdlIHZzLiBMb2cgSW5jb21lIGJ5IERlZmF1bHQgU3RhdHVzIiwNCiAgICAgICB4ID0gIkFnZSIsDQogICAgICAgeSA9ICJMb2cgb2YgSW5jb21lIikNCg0KIyBNYXJnaW5hbCBkZW5zaXR5IHBsb3Qgb2YgYWdlICh0b3AgcGFuZWwpDQpkZW5zaXR5X2FnZSA8LSBnZ3Bsb3QoYmFuaywgYWVzKHggPSBhZ2UsIGZpbGwgPSBkZWYpKSArDQogIGdlb21fZGVuc2l0eShhbHBoYSA9IDAuNSkgKyAgIyBBZGp1c3QgdHJhbnNwYXJlbmN5DQogIGxhYnModGl0bGUgPSAiRGVuc2l0eSBQbG90IG9mIEFnZSBieSBEZWZhdWx0IFN0YXR1cyIsDQogICAgICAgeCA9ICJBZ2UiLA0KICAgICAgIHkgPSAiRGVuc2l0eSIpDQoNCiMgTWFyZ2luYWwgZGVuc2l0eSBwbG90IG9mIGxvZyBpbmNvbWUgKHJpZ2h0IHBhbmVsKQ0KZGVuc2l0eV9pbmNvbWUgPC0gZ2dwbG90KGJhbmssIGFlcyh4ID0gbG9naW5jb21lLCBmaWxsID0gZGVmKSkgKw0KICBnZW9tX2RlbnNpdHkoYWxwaGEgPSAwLjUpICsgICMgQWRqdXN0IHRyYW5zcGFyZW5jeQ0KICBsYWJzKHRpdGxlID0gIkRlbnNpdHkgUGxvdCBvZiBMb2cgSW5jb21lIGJ5IERlZmF1bHQgU3RhdHVzIiwNCiAgICAgICB4ID0gIkxvZyBvZiBJbmNvbWUiLA0KICAgICAgIHkgPSAiRGVuc2l0eSIpDQoNCiMgQXJyYW5nZSB0aGUgcGxvdHMgdXNpbmcgZ3JpZEV4dHJhIGZvciBhIGNvaGVzaXZlIHZpc3VhbCBwcmVzZW50YXRpb24NCmdyaWQuYXJyYW5nZShzY2F0dGVyX3Bsb3QsIGRlbnNpdHlfYWdlLCBkZW5zaXR5X2luY29tZSwgbmNvbCA9IDIsIG5yb3cgPSAyLCBsYXlvdXRfbWF0cml4ID0gbWF0cml4KGMoMiwgMSwgMywgMSksIDIsIDIsIGJ5cm93ID0gVFJVRSkpDQoNCmBgYA0KDQpXZSBjYW4gYWxzbyBwdXQgdGhvc2UgcGxvdHMgdG9nZXRoZXI6DQoNCmBgYHtyIGVjaG89RkFMU0UsIHdhcm5pbmc9VFJVRX0NCiMgQXNzdW1pbmcgJ2JhbmsnIGlzIGFscmVhZHkgbG9hZGVkIHdpdGggJ2FnZScsICdsb2dpbmNvbWUnLCBhbmQgJ2RlZicgYXMgdGhlIHJpc2sgc3RhdHVzDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGdyaWRFeHRyYSkgICMgRm9yIGFycmFuZ2luZyBnZ3Bsb3RzDQoNCiMgQ3JlYXRlIHRoZSBtYWluIHNjYXR0ZXIgcGxvdCB3aXRoIGRpZmZlcmVudCBjb2xvcnMgZm9yIGVhY2ggJ2RlZicgY2F0ZWdvcnkNCm1haW5fcGxvdCA8LSBnZ3Bsb3QoYmFuaywgYWVzKHggPSBhZ2UsIHkgPSBsb2dpbmNvbWUsIGNvbG9yID0gZGVmKSkgKw0KICBnZW9tX3BvaW50KGFscGhhID0gMC42KSArDQogIGxhYnMoeCA9ICJBZ2UiLCB5ID0gIkxvZyBJbmNvbWUiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQojIENyZWF0ZSB0aGUgdG9wIG1hcmdpbmFsIGRlbnNpdHkgcGxvdCBmb3IgJ2FnZScNCnRvcF9kZW5zaXR5IDwtIGdncGxvdChiYW5rLCBhZXMoeCA9IGFnZSwgZmlsbCA9IGRlZikpICsNCiAgZ2VvbV9kZW5zaXR5KGFscGhhID0gMC41KSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpKQ0KDQojIENyZWF0ZSB0aGUgcmlnaHQgbWFyZ2luYWwgZGVuc2l0eSBwbG90IGZvciAnbG9naW5jb21lJw0KcmlnaHRfZGVuc2l0eSA8LSBnZ3Bsb3QoYmFuaywgYWVzKHggPSBsb2dpbmNvbWUsIGZpbGwgPSBkZWYpKSArDQogIGdlb21fZGVuc2l0eShhbHBoYSA9IDAuNSkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSkNCg0KIyBDb21iaW5lIHRoZSBwbG90cyB1c2luZyBncmlkRXh0cmENCmdyaWQuYXJyYW5nZSgNCiAgdG9wX2RlbnNpdHksIG51bGxHcm9iKCksDQogIG1haW5fcGxvdCwgcmlnaHRfZGVuc2l0eSwNCiAgbnJvdyA9IDIsIG5jb2wgPSAyLA0KICB3aWR0aHMgPSBjKDQsIDEpLCBoZWlnaHRzID0gYygxLCA0KQ0KKQ0KDQoNCg0KYGBgDQoNCiMjIFNjYXR0ZXJwbG90cyB3aXRoIGRlbnNpdHkgY3VydmVzIA0KDQpXZSBjYW4gYWxzbyBzZWUgbW9yZSBjbG9zZWx5IGlmIHRoZXJlIGFueSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRob3NlIHR3byBkaXN0cmlidXRpb25zIGFkZGluZyB0aGVpciBlc3RpbWF0ZWQgZGVuc2l0eSBwbG90czoNCg0KYGBge3IgZWNobz1GQUxTRSwgd2FybmluZz1UUlVFfQ0KIyBMb2FkIG5lY2Vzc2FyeSBsaWJyYXJpZXMNCmxpYnJhcnkoZ2dwbG90MikNCg0KIyBBc3N1bWluZyB0aGUgJ2JhbmsnIGRhdGFzZXQgaXMgcHJlbG9hZGVkIHdpdGggJ2FnZScsICdsb2dpbmNvbWUnLCBhbmQgJ2RlZicgKGRlZmF1bHQgc3RhdHVzKQ0KIyBFbnN1cmUgJ2xvZ2luY29tZScgaXMgYXZhaWxhYmxlOyBpZiBub3QsIGNhbGN1bGF0ZSBpdA0KaWYgKCEibG9naW5jb21lIiAlaW4lIG5hbWVzKGJhbmspKSB7DQogIGJhbmskbG9naW5jb21lIDwtIGxvZyhiYW5rJGluY29tZSArIDEpICAjIEF2b2lkIGxvZygwKSBpc3N1ZSBieSBhZGRpbmcgMQ0KfQ0KDQojIFNjYXR0ZXIgcGxvdCB3aXRoIGRlbnNpdHkgY3VydmVzIGZvciB2aXN1YWxpemluZyB0aGUgZGlzdHJpYnV0aW9uIGFuZCBkZW5zaXR5IG9mIGRhdGEgcG9pbnRzDQojIFRoaXMgaGVscHMgaW4gaWRlbnRpZnlpbmcgY2x1c3RlcnMgYW5kIHBhdHRlcm5zIG1vcmUgZWZmZWN0aXZlbHkNCmdncGxvdChiYW5rLCBhZXMoeCA9IGFnZSwgeSA9IGxvZ2luY29tZSwgY29sb3IgPSBkZWYpKSArDQogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUpICsgICMgVXNpbmcgc2VtaS10cmFuc3BhcmVuY3kgZm9yIHRoZSBwb2ludHMNCiAgZ2VvbV9kZW5zaXR5XzJkKCkgKyAgIyBBZGRzIGRlbnNpdHkgY29udG91cnMNCiAgbGFicyh0aXRsZSA9ICJTY2F0dGVyIFBsb3Qgb2YgQWdlIHZzLiBMb2cgSW5jb21lIHdpdGggRGVuc2l0eSBDdXJ2ZXMiLA0KICAgICAgIHggPSAiQWdlIiwNCiAgICAgICB5ID0gIkxvZyBvZiBJbmNvbWUiLA0KICAgICAgIGNvbG9yID0gIkRlZmF1bHQgU3RhdHVzIikgKw0KICB0aGVtZV9taW5pbWFsKCkgICMgVXNpbmcgYSBtaW5pbWFsIHRoZW1lIGZvciBiZXR0ZXIgdmlzdWFsaXphdGlvbg0KDQoNCmBgYA0KDQojIyBDb3JyZWxhdGlvbiBjb2VmZmljaWVudHMgLSBQZWFyc29uJ3MgbGluZWFyIGNvcnJlbGF0aW9uDQoNCk9rLCBsZXQncyBtb3ZlIHRvIHNvbWUgY2FsY3VsYXRpb25zLg0KSW4gUiwgd2UgY2FuIHVzZSB0aGUgY29yKCkgZnVuY3Rpb24uIEl0IHRha2VzIHRocmVlIGFyZ3VtZW50cyBhbmQgdGhlIG1ldGhvZDogY29yKHgsIHksIG1ldGhvZCkNCkZvciAyIHF1YW50aXRhdGl2ZSBkYXRhLCB3aXRoIGFsbCBhc3N1bXB0aW9ucyBtZXQsIHdlIGNhbiBjYWxjdWxhdGUgc2ltcGxlIFBlYXJzb24ncyBjb2VmZmljaWVudCBvZiBsaW5lYXIgY29ycmVsYXRpb246DQoNCmBgYHtyIGVjaG89RkFMU0UsIHdhcm5pbmc9VFJVRX0NCg0KIyBDaGVjayB0aGF0IHRoZSBuZWNlc3NhcnkgZGF0YSBleGlzdHMNCmlmKCJhZ2UiICVpbiUgbmFtZXMoYmFuaykgJiYgImxvZ2luY29tZSIgJWluJSBuYW1lcyhiYW5rKSkgew0KICAjIENhbGN1bGF0ZSBQZWFyc29uJ3MgY29ycmVsYXRpb24gY29lZmZpY2llbnQgZm9yIGFnZSBhbmQgbG9nLXRyYW5zZm9ybWVkIGluY29tZQ0KICBjb3JyZWxhdGlvbl9jb2VmZmljaWVudCA8LSBjb3IoYmFuayRhZ2UsIGJhbmskbG9naW5jb21lLCBtZXRob2QgPSAicGVhcnNvbiIpDQogICMgT3V0cHV0IHRoZSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudA0KICBwcmludChjb3JyZWxhdGlvbl9jb2VmZmljaWVudCkNCn0gZWxzZSB7DQogIHByaW50KCJOZWNlc3NhcnkgZGF0YSBub3QgZm91bmQgaW4gdGhlIGRhdGFzZXQuIFBsZWFzZSBjaGVjayB5b3VyIGRhdGEuIikNCn0NCg0KDQpgYGANCg0KT2ssIHdoYXQgYWJvdXQgdGhlIHBlcmNlbnRhZ2Ugb2YgdGhlIGV4cGxhaW5lZCB2YXJpYWJpbGl0eT8NCg0KYGBge3IgZWNobz1GQUxTRSwgd2FybmluZz1UUlVFfQ0KaWYgKGV4aXN0cygiY29ycmVsYXRpb25fY29lZmZpY2llbnQiKSkgew0KICAjIENhbGN1bGF0ZSB0aGUgY29lZmZpY2llbnQgb2YgZGV0ZXJtaW5hdGlvbg0KICByX3NxdWFyZWQgPC0gY29ycmVsYXRpb25fY29lZmZpY2llbnReMg0KICAjIE91dHB1dCB0aGUgUi1zcXVhcmVkIHZhbHVlDQogIHByaW50KHBhc3RlKCJQZXJjZW50YWdlIG9mIGV4cGxhaW5lZCB2YXJpYWJpbGl0eTogIiwgcm91bmQocl9zcXVhcmVkICogMTAwLCAyKSwgIiUiLCBzZXAgPSAiIikpDQp9IGVsc2Ugew0KICBwcmludCgiQ29ycmVsYXRpb24gY29lZmZpY2llbnQgbm90IGZvdW5kLiBQbGVhc2UgY2FsY3VsYXRlIHRoZSBQZWFyc29uJ3MgY29ycmVsYXRpb24gY29lZmZpY2llbnQgZmlyc3QuIikNCn0NCg0KDQpgYGANClNvIGFzIHdlIGNhbiBzZWUgYWxtb3N0ID8/PyBvZiB0b3RhbCBsb2cgb2YgaW5jb21lcycgdmFyaWFiaWxpdHkgaXMgZXhwbGFpbmVkIGJ5IGRpZmZlcmVuY2VzIGluIGFnZS4gVGhlIHJlc3QgKD8/PykgaXMgcHJvYmFibHkgZXhwbGFpbmVkIGJ5IG90aGVyIGZhY3RvcnMuDQoNCiMjIFBhcnRpYWwgYW5kIHNlbWlwYXJ0aWFsIGNvcnJlbGF0aW9uIA0KDQpUaGUgcGFydGlhbCBhbmQgc2VtaS1wYXJ0aWFsIChhbHNvIGtub3duIGFzIHBhcnQpIGNvcnJlbGF0aW9ucyBhcmUgdXNlZCB0byBleHByZXNzIHRoZSBzcGVjaWZpYyBwb3J0aW9uIG9mIHZhcmlhbmNlIGV4cGxhaW5lZCBieSBlbGltaW5hdGluZyB0aGUgZWZmZWN0IG9mIG90aGVyIHZhcmlhYmxlcyB3aGVuIGFzc2Vzc2luZyB0aGUgY29ycmVsYXRpb24gYmV0d2VlbiB0d28gdmFyaWFibGVzLg0KDQpQYXJ0aWFsIGNvcnJlbGF0aW9uIGhvbGRzIGNvbnN0YW50IG9uZSB2YXJpYWJsZSB3aGVuIGNvbXB1dGluZyB0aGUgcmVsYXRpb25zIHRvIG90aGVycy4gU3VwcG9zZSB3ZSB3YW50IHRvIGtub3cgdGhlIGNvcnJlbGF0aW9uIGJldHdlZW4gWCBhbmQgWSBob2xkaW5nIFogY29uc3RhbnQgZm9yIGJvdGggWCBhbmQgWS4gVGhhdCB3b3VsZCBiZSB0aGUgcGFydGlhbCBjb3JyZWxhdGlvbiBiZXR3ZWVuIFggYW5kIFkgY29udHJvbGxpbmcgZm9yIFouIA0KDQpTZW1pcGFydGlhbCBjb3JyZWxhdGlvbiBob2xkcyBaIGNvbnN0YW50IGZvciBlaXRoZXIgWCBvciBZLCBidXQgbm90IGJvdGgsIHNvIGlmIHdlIHdhbnRlZCB0byBjb250cm9sIFggZm9yIFosIHdlIGNvdWxkIGNvbXB1dGUgdGhlIHNlbWlwYXJ0aWFsIGNvcnJlbGF0aW9uIGJldHdlZW4gWCBhbmQgWSBob2xkaW5nIFogY29uc3RhbnQgZm9yIFguDQoNClN1cHBvc2Ugd2Ugd2FudCB0byBrbm93IHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRoZSBsb2cgb2YgaW5jb21lIGFuZCBhZ2UgY29udHJvbGxpbmcgZm9yIHllYXJzIG9mIGVtcGxveW1lbnQuIEhvdyBoaWdobHkgY29ycmVsYXRlZCBhcmUgdGhlc2UgYWZ0ZXIgY29udHJvbGxpbmcgZm9yIHRlbnVyZT8gDQoNCioqVGhlcmUgY2FuIGJlIG1vcmUgdGhhbiBvbmUgY29udHJvbCB2YXJpYWJsZS4NCg0KYGBge3IgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiMgQ2FsY3VsYXRlIHRoZSBzZW1pcGFydGlhbCBjb3JyZWxhdGlvbiB1c2luZyBwcGNvciBwYWNrYWdlDQppZiAoInBwY29yIiAlaW4lIHJvd25hbWVzKGluc3RhbGxlZC5wYWNrYWdlcygpKSkgew0KICBsaWJyYXJ5KHBwY29yKQ0KICAjIEVuc3VyZSB0aGUgdmFyaWFibGVzIGFyZSBjb3JyZWN0bHkgcmVmZXJlbmNlZCBhbmQgZXhpc3QgaW4gdGhlIGRhdGEgZnJhbWUNCiAgaWYgKGFsbChjKCJhZ2UiLCAibG9naW5jb21lIiwgImVtcGxveSIpICVpbiUgbmFtZXMoYmFuaykpKSB7DQogICAgIyBDb3JyZWN0IGZ1bmN0aW9uIHVzYWdlDQogICAgcmVzdWx0IDwtIHNwY29yKGJhbmtbLCBjKCJhZ2UiLCAibG9naW5jb21lIiwgImVtcGxveSIpXSwgbWV0aG9kID0gInBlYXJzb24iKQ0KICAgIA0KICAgICMgRXh0cmFjdGluZyB0aGUgc2VtaXBhcnRpYWwgY29ycmVsYXRpb24gdmFsdWUNCiAgICBzZW1pcGFydGlhbF9jb3JyZWxhdGlvbiA8LSByZXN1bHQkZXN0aW1hdGVbMSwgMl0gIyBBZGp1c3QgaW5kaWNlcyBiYXNlZCBvbiB5b3VyIG91dHB1dA0KICAgIHNlbWlwYXJ0aWFsX3BfdmFsdWUgPC0gcmVzdWx0JHAudmFsdWVbMSwgMl0NCiAgICANCiAgICAjIFByaW50IHRoZSByZXN1bHRzDQogICAgcHJpbnQocGFzdGUoIlNlbWlwYXJ0aWFsIGNvcnJlbGF0aW9uIGJldHdlZW4gYWdlIGFuZCBsb2dpbmNvbWUgY29udHJvbGxpbmcgZm9yIGVtcGxveTogIiwgc2VtaXBhcnRpYWxfY29ycmVsYXRpb24pKQ0KICAgIHByaW50KHBhc3RlKCJQLXZhbHVlIGZvciBzZW1pcGFydGlhbCBjb3JyZWxhdGlvbjogIiwgc2VtaXBhcnRpYWxfcF92YWx1ZSkpDQogIH0gZWxzZSB7DQogICAgcHJpbnQoIk9uZSBvciBtb3JlIHZhcmlhYmxlcyBhcmUgbm90IHByZXNlbnQgaW4gdGhlIGRhdGFzZXQuIikNCiAgfQ0KfSBlbHNlIHsNCiAgcHJpbnQoInBwY29yIHBhY2thZ2UgaXMgbm90IGluc3RhbGxlZC4gSW5zdGFsbCBpdCB1c2luZyBpbnN0YWxsLnBhY2thZ2VzKCdwcGNvcicpIikNCn0NCg0KDQpgYGANCg0KSG93IGNhbiB3ZSBpbnRlcnByZXQgdGhlIG9idGFpbmVkIHBhcnRpYWwgY29ycmVsYXRpb24gY29lZmZpY2llbnQ/IFdoYXQgaXMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGF0IG9uZSBhbmQgdGhlIHNlbWktcGFydGlhbCBjb2VmZmljaWVudDoNCg0KYGBge3IgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0KIyBBc3N1bWluZyB0aGUgcmVzdWx0cyBoYXZlIGJlZW4gc3RvcmVkIGluIHZhcmlhYmxlcyBgcGFydGlhbF9jb3JyZWxhdGlvbmAgYW5kIGBzZW1pcGFydGlhbF9jb3JyZWxhdGlvbmANCmlmIChleGlzdHMoInBhcnRpYWxfY29ycmVsYXRpb24iKSAmJiBleGlzdHMoInNlbWlwYXJ0aWFsX2NvcnJlbGF0aW9uIikpIHsNCiAgcHJpbnQocGFzdGUoIlBhcnRpYWwgQ29ycmVsYXRpb24gQ29lZmZpY2llbnQ6ICIsIHBhcnRpYWxfY29ycmVsYXRpb24pKQ0KICBwcmludChwYXN0ZSgiU2VtaS1QYXJ0aWFsIENvcnJlbGF0aW9uIENvZWZmaWNpZW50OiAiLCBzZW1pcGFydGlhbF9jb3JyZWxhdGlvbikpDQogIA0KICAjIEJhc2ljIGludGVycHJldGF0aW9uIHByb21wdHMgYmFzZWQgb24gdGhlIHZhbHVlcw0KICBpZiAocGFydGlhbF9jb3JyZWxhdGlvbiA+IDApIHsNCiAgICBwcmludCgiUG9zaXRpdmUgZGlyZWN0IHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGFnZSBhbmQgbG9nIGluY29tZSwgaW5kZXBlbmRlbnQgb2YgZW1wbG95bWVudC4iKQ0KICB9IGVsc2UgaWYgKHBhcnRpYWxfY29ycmVsYXRpb24gPCAwKSB7DQogICAgcHJpbnQoIk5lZ2F0aXZlIGRpcmVjdCByZWxhdGlvbnNoaXAgYmV0d2VlbiBhZ2UgYW5kIGxvZyBpbmNvbWUsIGluZGVwZW5kZW50IG9mIGVtcGxveW1lbnQuIikNCiAgfSBlbHNlIHsNCiAgICBwcmludCgiTm8gZGlyZWN0IHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGFnZSBhbmQgbG9nIGluY29tZSB3aGVuIGNvbnRyb2xsaW5nIGZvciBlbXBsb3ltZW50LiIpDQogIH0NCg0KICBpZiAoc2VtaXBhcnRpYWxfY29ycmVsYXRpb24gPiAwKSB7DQogICAgcHJpbnQoIkFnZSB1bmlxdWVseSBleHBsYWlucyBhIHBvc2l0aXZlIHZhcmlhbmNlIGluIGxvZyBpbmNvbWUsIGFmdGVyIGFjY291bnRpbmcgZm9yIGVtcGxveW1lbnQuIikNCiAgfSBlbHNlIGlmIChzZW1pcGFydGlhbF9jb3JyZWxhdGlvbiA8IDApIHsNCiAgICBwcmludCgiQWdlIHVuaXF1ZWx5IGV4cGxhaW5zIGEgbmVnYXRpdmUgdmFyaWFuY2UgaW4gbG9nIGluY29tZSwgYWZ0ZXIgYWNjb3VudGluZyBmb3IgZW1wbG95bWVudC4iKQ0KICB9IGVsc2Ugew0KICAgIHByaW50KCJBZ2UgZG9lcyBub3QgdW5pcXVlbHkgZXhwbGFpbiB0aGUgdmFyaWFuY2UgaW4gbG9nIGluY29tZSB3aGVuIGNvbnNpZGVyaW5nIGVtcGxveW1lbnQuIikNCiAgfQ0KfSBlbHNlIHsNCiAgcHJpbnQoIkNvcnJlbGF0aW9uIGNvZWZmaWNpZW50cyBub3QgY2FsY3VsYXRlZC4gUGxlYXNlIGNoZWNrIGVhcmxpZXIgc2VjdGlvbnMuIikNCn0NCg0KDQoNCmBgYA0KDQojIyBSYW5rIGNvcnJlbGF0aW9uIA0KDQpGb3IgMiBkaWZmZXJlbnQgc2NhbGVzIC0gbGlrZSBmb3IgZXhhbXBsZSB0aGlzIHBhaXIgb2YgdmFyaWFibGVzOiBpbmNvbWUgdnMuIGVkdWNhdGlvbiBsZXZlbHMgLSB3ZSBjYW5ub3QgdXNlIFBlYXJzb24ncyBjb2VmZmljaWVudC4gVGhlIG9ubHkgcG9zc2liaWxpdHkgaXMgdG8gcmFuayBhbHNvIGluY29tZXMuLi4gYW5kIGxvc2Ugc29tZSBtb3JlIGRldGFpbGVkIGluZm9ybWF0aW9uIGFib3V0IHRoZW0uIA0KDQpGaXJzdCwgbGV0J3Mgc2VlIGJveHBsb3RzIG9mIGluY29tZSBieSBlZHVjYXRpb24gbGV2ZWxzLg0KDQpgYGB7ciBlY2hvPUZBTFNFLCB3YXJuaW5nPVRSVUV9DQoNCmxpYnJhcnkoZ2dwbG90MikNCg0KIyBBc3N1bWluZyAnYmFuaycgaGFzICdpbmNvbWUnIGFzIGEgbnVtZXJpYyB2YXJpYWJsZSBhbmQgJ2VkdWMnIGFzIGEgZmFjdG9yIHJlcHJlc2VudGluZyBlZHVjYXRpb24gbGV2ZWxzDQpnZ3Bsb3QoYmFuaywgYWVzKHggPSBlZHVjLCB5ID0gaW5jb21lKSkgKw0KICBnZW9tX2JveHBsb3QoYWVzKGZpbGwgPSBlZHVjKSkgKyAgIyBVc2luZyAnZmlsbCcgZm9yIGFlc3RoZXRpYyBkaXN0aW5jdGlvbg0KICBsYWJzKHRpdGxlID0gIkJveHBsb3Qgb2YgSW5jb21lIGJ5IEVkdWNhdGlvbiBMZXZlbHMiLCB4ID0gIkVkdWNhdGlvbiBMZXZlbHMiLCB5ID0gIkluY29tZSIpICsNCiAgdGhlbWVfbWluaW1hbCgpICAjIENsZWFuIGFuZCBtaW5pbWFsIHRoZW1lIGZvciBiZXR0ZXIgcmVhZGFiaWxpdHkNCg0KDQoNCmBgYA0KDQpOb3csIGxldCdzIHNlZSBLZW5kYWwncyBjb2VmZmljaWVudCBvZiByYW5rIGNvcnJlbGF0aW9uIChyb2J1c3QgZm9yIHRpZXMpLg0KDQpgYGB7ciBlY2hvPUZBTFNFLCB3YXJuaW5nPVRSVUV9DQoNCmlmKGlzLmZhY3RvcihiYW5rJGVkdWMpKSB7DQogIGJhbmskZWR1Y19udW1lcmljIDwtIGFzLm51bWVyaWMoYXMuZmFjdG9yKGJhbmskZWR1YykpDQp9IGVsc2Ugew0KICBiYW5rJGVkdWNfbnVtZXJpYyA8LSBhcy5udW1lcmljKGJhbmskZWR1YykNCn0NCg0KIyBDYWxjdWxhdGUgS2VuZGFsbCdzIFRhdSB1c2luZyB0aGUgY29yKCkgZnVuY3Rpb24gZnJvbSB0aGUgc3RhdHMgcGFja2FnZQ0Ka2VuZGFsbHNfdGF1IDwtIGNvcihiYW5rJGluY29tZSwgYmFuayRlZHVjX251bWVyaWMsIG1ldGhvZCA9ICJrZW5kYWxsIikNCmtlbmRhbGxzX3RhdQ0KDQoNCmBgYA0KDQoNCiMjIFBvaW50LWJpc2VyaWFsIGNvcnJlbGF0aW9uDQoNCkxldCdzIHRyeSB0byB2ZXJpZnkgaWYgdGhlcmUgaXMgYSBzaWduaWZpY2FudCByZWxhdGlvbnNoaXAgYmV0d2VlbiBpbmNvbWVzIGFuZCByaXNrIHN0YXR1cy4gRmlyc3QsIGxldCdzIHRha2UgYSBsb29rIGF0IHRoZSBib3hwbG90Og0KDQojIyBQb2ludC1iaXNlcmlhbCBjb3JyZWxhdGlvbg0KDQpUaGUgcG9pbnQtYmlzZXJpYWwgY29ycmVsYXRpb24gaXMgdXNlZCB0byBtZWFzdXJlIHRoZSBzdHJlbmd0aCBhbmQgZGlyZWN0aW9uIG9mIHRoZSBhc3NvY2lhdGlvbiB0aGF0IGV4aXN0cyBiZXR3ZWVuIG9uZSBiaW5hcnkgdmFyaWFibGUgYW5kIG9uZSBjb250aW51b3VzIHZhcmlhYmxlLiBJbiB0aGlzIGNhc2UsIHdlIGFyZSBpbnZlc3RpZ2F0aW5nIHRoZSBwb3RlbnRpYWwgcmVsYXRpb25zaGlwIGJldHdlZW4gaW5jb21lIGxldmVscyBhbmQgZGVmYXVsdCBzdGF0dXMgKHdoZXRoZXIgYSBjdXN0b21lciBoYXMgZGVmYXVsdGVkIG9yIG5vdCkuDQoNCiMjIyBWaXN1YWxpemluZyB0aGUgUmVsYXRpb25zaGlwIHdpdGggYSBCb3hwbG90DQoNCkZpcnN0LCBsZXQncyB2aXN1YWxseSBpbnNwZWN0IHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBpbmNvbWUgYW5kIGRlZmF1bHQgc3RhdHVzIHVzaW5nIGEgYm94cGxvdC4gVGhpcyB3aWxsIHByb3ZpZGUgYSB2aXN1YWwgc3VtbWFyeSBvZiB0aGUgbWVkaWFuLCBxdWFydGlsZXMsIGFuZCBvdXRsaWVycyBmb3IgaW5jb21lIGNhdGVnb3JpemVkIGJ5IGRlZmF1bHQgc3RhdHVzLg0KDQpgYGB7ciBlY2hvPUZBTFNFLCB3YXJuaW5nPVRSVUV9DQoNCmxpYnJhcnkoZ2dwbG90MikNCg0KIyBDcmVhdGUgYSBib3hwbG90IG9mIGluY29tZSBieSBkZWZhdWx0IHN0YXR1cw0KZ2dwbG90KGJhbmssIGFlcyh4ID0gZGVmLCB5ID0gaW5jb21lKSkgKw0KICBnZW9tX2JveHBsb3QoYWVzKGZpbGwgPSBkZWYpKSArICAjIFVzZSBmaWxsIHRvIGRpZmZlcmVudGlhdGUgdGhlIGNhdGVnb3JpZXMgdmlzdWFsbHkNCiAgbGFicyh0aXRsZSA9ICJCb3hwbG90IG9mIEluY29tZSBieSBEZWZhdWx0IFN0YXR1cyIsIHggPSAiRGVmYXVsdCBTdGF0dXMiLCB5ID0gIkluY29tZSIpICsNCiAgdGhlbWVfbWluaW1hbCgpICAjIFVzZSBhIG1pbmltYWwgdGhlbWUgZm9yIGJldHRlciB2aXN1YWwgY2xhcml0eQ0KDQoNCg0KYGBgDQoNCklmIHlvdSB3b3VsZCBsaWtlIHRvIGNvbXBhcmUgMSBxdWFudGl0YXRpdmUgdmFyaWFibGUgKGluY29tZSkgYW5kIDEgZHljaG90b21vdXMgdmFyaWFibGUgKGRlZmF1bHQgc3RhdHVzIC0gYmluYXJ5KSwgdGhlbiB5b3UgY2FuIHVzZSBwb2ludC1iaXNlcmlhbCBjb2VmZmljaWVudDoNCg0KYGBge3IgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0KbGlicmFyeShwc3ljaCkNCg0KDQppZihpcy5mYWN0b3IoYmFuayRkZWYpKSB7DQogIGJhbmskZGVmX251bWVyaWMgPC0gYXMubnVtZXJpYyhiYW5rJGRlZikgLSAxDQp9IGVsc2Ugew0KICBiYW5rJGRlZl9udW1lcmljIDwtIGJhbmskZGVmIC0gMQ0KfQ0KDQpwb2ludF9iaXNlcmlhbF9yZXN1bHQgPC0gYmlzZXJpYWwuY29yKGJhbmskaW5jb21lLCBiYW5rJGRlZl9udW1lcmljKQ0KcG9pbnRfYmlzZXJpYWxfcmVzdWx0DQoNCiNiaXNlcmlhbC5jb3IoYmFuayRpbmNvbWUsIGFzLm51bWVyaWMoYmFuayRkZWYpIC0gMSkNCmBgYA0KDQoNCiMjIE5vbmxpbmVhciBjb3JyZWxhdGlvbiAtIGV0YSBjb2VmZmljaWVudA0KDQpJZiB5b3Ugd291bGQgbGlrZSB0byBjaGVjayBpZiB0aGVyZSBhcmUgYW55IG5vbmxpbmVhcml0aWVzIGJldHdlZW4gMiB2YXJpYWJsZXMsIHRoZSBvbmx5IHBvc3NpYmlsaXR5IChiZXNpZGUgdHJhbnNmb3JtYXRpb25zIGFuZCBsaW5lYXIgYW5hbHlzaXMpIGlzIHRvIGNhbGN1bGF0ZSAiZXRhIiBjb2VmZmljaWVudCBhbmQgY29tcGFyZSBpdCB3aXRoIHRoZSBQZWFyc29uJ3MgbGluZWFyIGNvZWZmaWNpZW50LiANCg0KYGBge3IgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiNldGFfc3F1YXJlZCA8LSBEZXNjVG9vbHM6OkV0YVNxKGFvdihpbmNvbWUgfiBkZWYsIGRhdGEgPSBiYW5rKSkNCiNldGFfc3F1YXJlZA0KIyBMb2FkIG5lY2Vzc2FyeSBwYWNrYWdlIGZvciB0aGUgYW5hbHlzaXMNCmxpYnJhcnkoRGVzY1Rvb2xzKQ0KDQojIEVuc3VyZSB0aGF0ICdkZWYnIGlzIGEgZmFjdG9yIGFuZCAnaW5jb21lJyBpcyBhcHByb3ByaWF0ZSBmb3IgYW5hbHlzaXMNCmJhbmskZGVmIDwtIGFzLmZhY3RvcihiYW5rJGRlZikNCg0KIyBQZXJmb3JtIGFuIEFuYWx5c2lzIG9mIFZhcmlhbmNlIChBTk9WQSkgYW5kIGNhbGN1bGF0ZSBFdGEgc3F1YXJlZA0KZXRhX3NxdWFyZWRfcmVzdWx0IDwtIEV0YVNxKGFvdihpbmNvbWUgfiBkZWYsIGRhdGEgPSBiYW5rKSkNCnByaW50KHBhc3RlKCJFdGEgc3F1YXJlZDogIiwgZXRhX3NxdWFyZWRfcmVzdWx0KSkNCg0KDQpgYGANCg0KIyMgQ29ycmVsYXRpb24gbWF0cml4DQoNCldlIGNhbiBhbHNvIHByZXBhcmUgdGhlIGNvcnJlbGF0aW9uIG1hdHJpeCBmb3IgYWxsIHF1YW50aXRhdGl2ZSB2YXJpYWJsZXMgc3RvcmVkIGluIG91ciBkYXRhIGZyYW1lLiANCg0KV2UgY2FuIHVzZSBnZ2NvcnIoKSBmdW5jdGlvbjoNCg0KYGBge3IgZWNobz1GQUxTRSwgd2FybmluZz1UUlVFfQ0KI2dnY29ycihiYW5rWywgc2FwcGx5KGJhbmssIGlzLm51bWVyaWMpXSwgbGFiZWwgPSBUUlVFLCBsYWJlbF9yb3VuZCA9IDIpDQoNCmxpYnJhcnkoR0dhbGx5KQ0KDQoNCmlmICgiYmFuayIgJWluJSBscygpICYmIGFueShzYXBwbHkoYmFuaywgaXMubnVtZXJpYykpKSB7DQogIG51bWVyaWNfZGF0YSA8LSBiYW5rWywgc2FwcGx5KGJhbmssIGlzLm51bWVyaWMpXQ0KICBjb3JyZWxhdGlvbl9tYXRyaXggPC0gZ2djb3JyKG51bWVyaWNfZGF0YSwgbGFiZWwgPSBUUlVFLCBsYWJlbF9yb3VuZCA9IDIpDQogIHByaW50KGNvcnJlbGF0aW9uX21hdHJpeCkNCn0gZWxzZSB7DQogIHByaW50KCJObyBudW1lcmljIGRhdGEgYXZhaWxhYmxlIGluIHRoZSAnYmFuaycgZGF0YXNldCBvciAnYmFuaycgbm90IGxvYWRlZC4iKQ0KfQ0KDQoNCmBgYA0KICANCkFzIHlvdSBjYW4gc2VlIC0gdGhlIGRlZmF1bHQgY29ycmVsYXRpb24gbWF0cml4IGlzIG5vdCB0aGUgYmVzdCBpZGVhIGZvciBhbGwgbWVhc3VyZW1lbnQgc2NhbGVzIChpbmNsdWRpbmcgYmluYXJ5IHZhcmlhYmxlICJkZWZhdWx0IikuIA0KDQpUaGF0J3Mgd2h5IG5vdyB3ZSBjYW4gcGVyZm9ybSBvdXIgYml2YXJpYXRlIGFuYWx5c2lzIHdpdGggZ2dwYWlyIHdpdGggZ3JvdXBpbmcuDQoNCiMjIENvcnJlbGF0aW9uIG1hdHJpeCB3aXRoIHNjYXR0ZXJwbG90cyANCg0KSGVyZSBpcyB3aGF0IHdlIGFyZSBhYm91dCB0byBjYWxjdWxhdGU6DQotIFRoZSBjb3JyZWxhdGlvbiBtYXRyaXggYmV0d2VlbiBhZ2UsIGxvZ19pbmNvbWUsIGVtcGxveSwgYWRkcmVzcywgZGVidGluYywgY3JlZGRlYnQsIGFuZCBvdGhkZWJ0IHZhcmlhYmxlIGdyb3VwZWQgYnkgd2hldGhlciB0aGUgcGVyc29uIGhhcyBhIGRlZmF1bHQgc3RhdHVzIG9yIG5vdC4NCi0gUGxvdCB0aGUgZGlzdHJpYnV0aW9uIG9mIGVhY2ggdmFyaWFibGUgYnkgZ3JvdXANCi0gRGlzcGxheSB0aGUgc2NhdHRlciBwbG90IHdpdGggdGhlIHRyZW5kIGJ5IGdyb3VwDQoNCmBgYHtyIGVjaG89RkFMU0UsIHdhcm5pbmc9VFJVRX0NCg0KIyBDcmVhdGUgYSBuZXcgZGF0YSBmcmFtZSB3aXRoIHRoZSBuZWNlc3NhcnkgY29sdW1ucw0KYmFuayA8LSBiYW5rICU+JQ0KICBtdXRhdGUobG9nX2luY29tZSA9IGxvZyhpbmNvbWUpKQ0KDQpzZWxlY3RlZF92YXJzIDwtIGJhbmtbLCBjKCJhZ2UiLCAibG9nX2luY29tZSIsICJlbXBsb3kiLCAiZGVmIildDQoNCiMgR2VuZXJhdGUgdGhlIGdncGFpcnMgcGxvdA0KZ2dwYWlycyhzZWxlY3RlZF92YXJzLCANCiAgICAgICAgbWFwcGluZyA9IGFlcyhjb2xvciA9IGRlZiksIA0KICAgICAgICB1cHBlciA9IGxpc3QoY29udGludW91cyA9ICJjb3IiKSwNCiAgICAgICAgbG93ZXIgPSBsaXN0KGNvbnRpbnVvdXMgPSAic21vb3RoIiksDQogICAgICAgIGRpYWcgPSBsaXN0KGNvbnRpbnVvdXMgPSAiZGVuc2l0eURpYWciKSkgKw0KICBsYWJzKHRpdGxlID0gIlNpbXBsaWZpZWQgQ29ycmVsYXRpb24gTWF0cml4IHdpdGggU2NhdHRlcnBsb3RzIGJ5IERlZmF1bHQgU3RhdHVzIikNCg0KDQoNCg0KYGBgDQoNCg0KYGBge3IgZWNobz1GQUxTRSwgd2FybmluZz1UUlVFfQ0KDQpsaWJyYXJ5KEdHYWxseSkNCmxpYnJhcnkoZHBseXIpDQoNCg0KaWYoImluY29tZSIgJWluJSBuYW1lcyhiYW5rKSkgew0KICANCiAgYmFuayA8LSBiYW5rICU+JQ0KICAgIG11dGF0ZShsb2dfaW5jb21lID0gbG9nKGluY29tZSArIDEpKSAgIyBBZGRpbmcgMSB0byBhdm9pZCBsb2coMCkgaXNzdWVzDQogIA0KICANCiAgc2VsZWN0ZWRfdmFycyA8LSBiYW5rWywgYygiYWdlIiwgImxvZ19pbmNvbWUiLCAiZW1wbG95IiwgImRlZiIpXQ0KDQogIA0KICBpZihhbGwoYygiYWdlIiwgImxvZ19pbmNvbWUiLCAiZW1wbG95IiwgImRlZiIpICVpbiUgbmFtZXMoc2VsZWN0ZWRfdmFycykpKSB7DQogICAgDQogICAgZ2dwYWlyc19wbG90IDwtIGdncGFpcnMoc2VsZWN0ZWRfdmFycywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwcGluZyA9IGFlcyhjb2xvciA9IGRlZiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwcGVyID0gbGlzdChjb250aW51b3VzID0gImNvciIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvd2VyID0gbGlzdChjb250aW51b3VzID0gd3JhcCgic21vb3RoIiwgbWV0aG9kID0gImxtIiwgc2UgPSBUUlVFKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlhZyA9IGxpc3QoY29udGludW91cyA9ICJkZW5zaXR5RGlhZyIpKQ0KICAgIHByaW50KGdncGFpcnNfcGxvdCkNCiAgfSBlbHNlIHsNCiAgICBwcmludCgiT25lIG9yIG1vcmUgdmFyaWFibGVzIGFyZSBtaXNzaW5nIGZyb20gJ3NlbGVjdGVkX3ZhcnMnLiBQbGVhc2UgY2hlY2sgdGhlIGRhdGFzZXQuIikNCiAgfQ0KfSBlbHNlIHsNCiAgcHJpbnQoIkluY29tZSB2YXJpYWJsZSBpcyBtaXNzaW5nIGZyb20gdGhlICdiYW5rJyBkYXRhc2V0LiIpDQp9DQoNCmBgYA0KDQojIyBRdWFsaXRhdGl2ZSBkYXRhDQoNCkluIGNhc2Ugb2YgdHdvIHZhcmlhYmxlcyBtZWFzdXJlZCBvbiBub21pbmFsIG9yIG9yZGluYWwmbm9taW5hbCBzY2FsZSAtIHdlIGFyZSBmb3JjZWQgdG8gb3JnYW5pemUgc28gY2FsbGVkICJjb250aW5nZW5jeSIgdGFibGUgd2l0aCBmcmVxdWVuY2llcyBhbmQgY2FsY3VsYXRlIHNvbWUga2luZCBvZiB0aGUgY29ycmVsYXRpb24gY29lZmZpY2llbnQgYmFzZWQgb24gdGhlbS4gVGhpcyBpcyBzbyBjYWxsZWQgImNvbnRpbmdlbmN5IGFuYWx5c2lzIi4gDQoNCkxldCdzIGNvbnNpZGVyIG9uZSBleGFtcGxlIGJhc2VkIG9uIG91ciBkYXRhOiB2ZXJpZnksIGlmIHRoZXJlIGlzIGFueSBzaWduaWZpY2FudCBjb3JyZWxhdGlvbiBiZXR3ZWVuIGVkdWNhdGlvbiBsZXZlbCBhbmQgY3JlZGl0IHJpc2suDQoNCmBgYHtyfQ0KI2VkdWNhdGlvbl9kZWZhdWx0X3RhYmxlIDwtIHRhYmxlKGJhbmskZWR1YywgYmFuayRkZWYpDQojY2hpc3EudGVzdChlZHVjYXRpb25fZGVmYXVsdF90YWJsZSkNCg0KDQpgYGANCmBgYHtyIGVjaG89RkFMU0UsIHdhcm5pbmc9VFJVRX0NCg0KbGlicmFyeShkcGx5cikNCg0KDQppZihhbGwoYygiZWR1YyIsICJkZWYiKSAlaW4lIG5hbWVzKGJhbmspKSAmJiBpcy5mYWN0b3IoYmFuayRlZHVjKSAmJiBpcy5mYWN0b3IoYmFuayRkZWYpKSB7DQogICMgQ3JlYXRlIGEgY29udGluZ2VuY3kgdGFibGUgb2YgZWR1Y2F0aW9uIGxldmVscyBhbmQgZGVmYXVsdCBzdGF0dXMNCiAgZWR1Y2F0aW9uX2RlZmF1bHRfdGFibGUgPC0gdGFibGUoYmFuayRlZHVjLCBiYW5rJGRlZikNCg0KICANCiAgY2hpX3NxdWFyZWRfcmVzdWx0cyA8LSBjaGlzcS50ZXN0KGVkdWNhdGlvbl9kZWZhdWx0X3RhYmxlKQ0KDQogIA0KICBwcmludChjaGlfc3F1YXJlZF9yZXN1bHRzKQ0KfSBlbHNlIHsNCiAgcHJpbnQoIk9uZSBvciBtb3JlIHJlcXVpcmVkIHZhcmlhYmxlcyBhcmUgbWlzc2luZyBvciBub3QgZm9ybWF0dGVkIGFzIGZhY3RvcnMuIikNCn0NCg0KYGBgDQoNCg0KIyMgRXhlcmNpc2UgMS4gQ29udGluZ2VuY3kgYW5hbHlzaXMuDQoNCkRvIHlvdSBiZWxpZXZlIGluIHRoZSBBZnRlcmxpZmU/DQpodHRwczovL25hdGlvbmFscG9zdC5jb20vbmV3cy9jYW5hZGEvbWlsbGVubmlhbHMtZG8teW91LWJlbGlldmUtaW4tbGlmZS1hZnRlci1saWZlDQpBIHN1cnZleSB3YXMgY29uZHVjdGVkIGFuZCBhIHJhbmRvbSBzYW1wbGUgb2YgMTA5MSBxdWVzdGlvbm5haXJlcyBpcyBnaXZlbiBpbiB0aGUgZm9ybSBvZiB0aGUgZm9sbG93aW5nIGNvbnRpbmdlbmN5IHRhYmxlOg0KDQpgYGB7ciBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KeD1jKDQzNSwxNDcsMzc1LDEzNCkNCmRpbSh4KT1jKDIsMikNCmRhbmU8LWFzLnRhYmxlKHgpDQpkaW1uYW1lcyhkYW5lKT1saXN0KEdlbmRlcj1jKCdGZW1hbGUnLCdNYWxlJyksQmVsaWV2ZT1jKCdZZXMnLCdObycpKQ0KZGFuZQ0KZm91cmZvbGRwbG90KGRhbmUpDQpgYGANCmBgYHtyIGVjaG89RkFMU0UsIHdhcm5pbmc9VFJVRX0NCg0KeCA8LSBjKDQzNSwgMTQ3LCAzNzUsIDEzNCkNCmRpbSh4KSA8LSBjKDIsIDIpICAjIFNldCB0aGUgZGltZW5zaW9ucyBmb3IgdGhlIG1hdHJpeA0KZGFuZSA8LSBhcy50YWJsZSh4KSAgIyBDb252ZXJ0IHRoZSBtYXRyaXggdG8gYSB0YWJsZQ0KZGltbmFtZXMoZGFuZSkgPC0gbGlzdChHZW5kZXIgPSBjKCdGZW1hbGUnLCAnTWFsZScpLCBCZWxpZXZlID0gYygnWWVzJywgJ05vJykpDQoNCg0KcHJpbnQoZGFuZSkNCg0KDQpmb3VyZm9sZHBsb3QoZGFuZSwgY29sb3IgPSBjKCIjQ0M2NjY2IiwgIiM5OTk5Q0MiKSwgY29uZi5sZXZlbCA9IDAuOTUsIG1hcmdpbiA9IDEpDQpgYGANCg0KT3VyIHRhc2sgaXMgdG8gY2hlY2sgaWYgdGhlcmUgaXMgYSBzaWduaWZpY2FudCByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgYmVsaWVmIGluIHRoZSBhZnRlcmxpZmUgYW5kIGdlbmRlci4gV2UgY2FuIHBlcmZvcm0gdGhpcyBwcm9jZWR1cmUgd2l0aCB0aGUgc2ltcGxlIGNoaS1zcXVhcmUgc3RhdGlzdGljcyBhbmQgY2hvc2VuIHF1YWxpdGF0aXZlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50ICh0d28td2F5IDJ4MiB0YWJsZSkuDQoNCmBgYHtyIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQp5ZXM8LWMoNDM1LDE0NykNCm5vPC1jKDM3NSwxMzQpDQojY29oZW4ua2FwcGEoY2JpbmQoeWVzLG5vKSkNCmNoaXNxLnRlc3QoZGFuZSkNCnByb3AudGFibGUoZGFuZSkNCmBgYA0KYGBge3IgZWNobz1GQUxTRSwgd2FybmluZz1UUlVFfQ0KeWVzIDwtIGMoNDM1LCAxNDcpICAjIENvdW50cyBvZiAnWWVzJyByZXNwb25zZXMgZm9yIEZlbWFsZSBhbmQgTWFsZQ0Kbm8gPC0gYygzNzUsIDEzNCkgICAjIENvdW50cyBvZiAnTm8nIHJlc3BvbnNlcyBmb3IgRmVtYWxlIGFuZCBNYWxlDQpkYW5lIDwtIG1hdHJpeChjKHllcywgbm8pLCBuY29sID0gMiwgYnlyb3cgPSBUUlVFKSAgIyBDcmVhdGUgYSBtYXRyaXggZm9yIHRoZSBjb250aW5nZW5jeSB0YWJsZQ0KZGltbmFtZXMoZGFuZSkgPC0gbGlzdChHZW5kZXIgPSBjKCdGZW1hbGUnLCAnTWFsZScpLCBCZWxpZXZlID0gYygnWWVzJywgJ05vJykpDQoNCmRhbmVfdGFibGUgPC0gYXMudGFibGUoZGFuZSkNCnByaW50KGRhbmVfdGFibGUpDQojIENoaS1zcXVhcmUgdGVzdA0KY2hpX3Jlc3VsdHMgPC0gY2hpc3EudGVzdChkYW5lX3RhYmxlKQ0KcHJpbnQoY2hpX3Jlc3VsdHMpDQojIFByb3BvcnRpb24gdGFibGUgdG8gc2hvdyByZWxhdGl2ZSBmcmVxdWVuY2llcw0KcHJvcF90YWJsZSA8LSBwcm9wLnRhYmxlKGRhbmVfdGFibGUsIG1hcmdpbiA9IDEpICAjIENhbGN1bGF0ZSBwcm9wb3J0aW9ucyByb3ctd2lzZQ0KcHJpbnQocHJvcF90YWJsZSkNCmBgYA0KDQpBcyB5b3UgY2FuIHNlZSB3ZSBjYW4gY2FsY3VsYXRlIG91ciBjaGktc3F1YXJlIHN0YXRpc3RpYyByZWFsbHkgcXVpY2tseSBmb3IgdHdvLXdheSB0YWJsZXMgb3IgbGFyZ2VyLiANCk5vdyB3ZSBjYW4gc3RhbmRhcmRpemUgdGhpcyBjb250aW5nZW5jeSBtZWFzdXJlIHRvIHNlZSBpZiB0aGUgcmVsYXRpb25zaGlwIGlzIHNpZ25pZmljYW50Lg0KDQpgYGB7ciBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KUGhpKGRhbmUpDQojP0NvbnRDb2VmDQojQ29udENvZWYoZGFuZSkNCiNDcmFtZXJWKGRhbmUpDQojVHNjaHVwcm93VChkYW5lKQ0KbW9zYWljcGxvdChkYW5lKQ0KYmFycGxvdChkYW5lKQ0KYGBgDQpgYGB7ciBlY2hvPUZBTFNFLCB3YXJuaW5nPVRSVUV9DQpsaWJyYXJ5KERlc2NUb29scykNCg0KIyBQaGkgY29lZmZpY2llbnQgLSBtZWFzdXJlcyB0aGUgc3RyZW5ndGggb2YgYXNzb2NpYXRpb24gaW4gYSAyeDIgY29udGluZ2VuY3kgdGFibGUNCnBoaV9jb2VmZmljaWVudCA8LSBQaGkoZGFuZSkNCnByaW50KHBhc3RlKCJQaGkgQ29lZmZpY2llbnQ6IiwgcGhpX2NvZWZmaWNpZW50KSkNCg0KIyBDcmFtZXIncyBWIC0gc3VpdGFibGUgZm9yIHRhYmxlcyBsYXJnZXIgdGhhbiAyeDIsIGJ1dCBzdGlsbCBhcHBsaWNhYmxlIGhlcmUNCmNyYW1lcl92IDwtIENyYW1lclYoZGFuZSkNCnByaW50KHBhc3RlKCJDcmFtZXIncyBWOiIsIGNyYW1lcl92KSkNCg0KIyBUc2NodXByb3cncyBUIC0gYSBub3JtYWxpemVkIG1lYXN1cmUgb2YgYXNzb2NpYXRpb24gZm9yIGxhcmdlciB0YWJsZXMNCiMgVW5jb21tZW50IGlmIGRhbmUgaGFzIG1vcmUgdGhhbiB0d28gbGV2ZWxzIHBlciBmYWN0b3INCiMgdHNjaHVwcm93X3QgPC0gVHNjaHVwcm93VChkYW5lKQ0KIyBwcmludChwYXN0ZSgiVHNjaHVwcm93J3MgVDoiLCB0c2NodXByb3dfdCkpDQojIE1vc2FpYyBwbG90IHRvIHZpc3VhbGl6ZSB0aGUgYXNzb2NpYXRpb24NCm1vc2FpY3Bsb3QoZGFuZSwgbWFpbiA9ICJNb3NhaWMgUGxvdCBvZiBHZW5kZXIgdnMuIEJlbGllZiBpbiBBZnRlcmxpZmUiLCBjb2wgPSBjKCIjRTY5RjAwIiwgIiM1NkI0RTkiKSkNCg0KIyBCYXIgcGxvdCB0byBzaG93IGZyZXF1ZW5jaWVzDQpiYXJwbG90KGFzLm1hdHJpeChkYW5lKSwgYmVzaWRlID0gVFJVRSwgbGVnZW5kID0gVFJVRSwgYXJncy5sZWdlbmQgPSBsaXN0KHRpdGxlID0gIkJlbGlldmUgaW4gQWZ0ZXJsaWZlIiksIGNvbCA9IGMoIiNFNjlGMDAiLCAiIzU2QjRFOSIpLCBtYWluID0gIkJhciBQbG90IG9mIFJlc3BvbnNlcyBieSBHZW5kZXIiKQ0KYGBgDQoNCg0KDQojIyBFeGVyY2lzZSAyLiBDb250aW5nZW5jeSBhbmFseXNpcyBmb3IgdGhlICdUaXRhbmljJyBkYXRhLg0KDQpMZXQncyBjb25zaWRlciB0aGUgdGl0YW5pYyBkYXRhc2V0IHdoaWNoIGNvbnRhaW5zIGEgY29tcGxldGUgbGlzdCBvZiBwYXNzZW5nZXJzIGFuZCBjcmV3IG1lbWJlcnMgb24gdGhlIFJNUyBUaXRhbmljLiBJdCBpbmNsdWRlcyBhIHZhcmlhYmxlIGluZGljYXRpbmcgd2hldGhlciBhIHBlcnNvbiBkaWQgc3Vydml2ZSB0aGUgc2lua2luZyBvZiB0aGUgUk1TIFRpdGFuaWMgb24gQXByaWwgMTUsIDE5MTIuDQpBIGRhdGEgZnJhbWUgY29udGFpbnMgMjQ1NiBvYnNlcnZhdGlvbnMgb24gMTQgdmFyaWFibGVzLg0KDQpgYGB7ciBsb2FkLWRhdGEyLCB3YXJuaW5nPVRSVUUsIGluY2x1ZGU9RkFMU0V9DQpkb3dubG9hZC5maWxlKCJodHRwczovL2dpdGh1Yi5jb20va2ZsaXNpa293c2tpL2RzL2Jsb2IvbWFzdGVyL3RpdGFuaWMuY3N2P3Jhdz10cnVlIiwgZGVzdGZpbGUgPSJ0aXRhbmljLmNzdiIsbW9kZT0id2IiKQ0KdGl0YW5pYyA8LSByZWFkLmNzdigidGl0YW5pYy5jc3YiLHJvdy5uYW1lcz0xLHNlcD0iOyIpDQpgYGANCg0KDQpUaGUgd2Vic2l0ZSBodHRwOi8vd3d3LmVuY3ljbG9wZWRpYS10aXRhbmljYS5vcmcvIG9mZmVycyBkZXRhaWxlZCBpbmZvcm1hdGlvbiBhYm91dCBwYXNzZW5nZXJzIGFuZCBjcmV3IG1lbWJlcnMgb24gdGhlIFJNUyBUaXRhbmljLiBBY2NvcmRpbmcgdG8gdGhlIHdlYnNpdGUgMTMxNyBwYXNzZW5nZXJzIGFuZCA4OTAgY3JldyBtZW1iZXIgd2VyZSBhYm9hcmQuDQoNCjggbXVzaWNpYW5zIGFuZCA5IGVtcGxveWVlcyBvZiB0aGUgc2hpcHlhcmQgY29tcGFueSBhcmUgbGlzdGVkIGFzIHBhc3NlbmdlcnMsIGJ1dCB0cmF2ZWxsZWQgd2l0aCBhIGZyZWUgdGlja2V0LCB3aGljaCBpcyB3aHkgdGhleSBoYXZlIE5BIHZhbHVlcyBpbiBmYXJlLiBJbiBhZGRpdGlvbiB0byB0aGF0LCBmYXJlIGlzIHRydWVseSBtaXNzaW5nIGZvciBhIGZldyByZWd1bGFyIHBhc3NlbmdlcnMuIA0KDQpgYGB7ciBlY2hvPUZBTFNFLCB3YXJuaW5nPVRSVUV9DQojdGFibGUodGl0YW5pYyRTdXJ2aXZlZCwgdGl0YW5pYyRTZXgpDQojY2hpc3EudGVzdCh0YWJsZSh0aXRhbmljJFN1cnZpdmVkLCB0aXRhbmljJFNleCkpDQpgYGANCmBgYHtyIGVjaG89RkFMU0UsIHdhcm5pbmc9VFJVRX0NCiMgRG93bmxvYWQgYW5kIGxvYWQgdGhlIFRpdGFuaWMgZGF0YXNldA0KZG93bmxvYWQuZmlsZSgiaHR0cHM6Ly9naXRodWIuY29tL2tmbGlzaWtvd3NraS9kcy9ibG9iL21hc3Rlci90aXRhbmljLmNzdj9yYXc9dHJ1ZSIsIA0KICAgICAgICAgICAgICBkZXN0ZmlsZSA9ICJ0aXRhbmljLmNzdiIsIG1vZGUgPSAid2IiKQ0KdGl0YW5pYyA8LSByZWFkLmNzdigidGl0YW5pYy5jc3YiLCByb3cubmFtZXMgPSAxLCBzZXAgPSAiOyIpDQojIERpc3BsYXkgdGhlIHN0cnVjdHVyZSBvZiB0aGUgZGF0YXNldA0Kc3RyKHRpdGFuaWMpDQoNCiMgRGlzcGxheSB0aGUgZmlyc3QgZmV3IHJvd3MgdG8gZ2V0IGEgc2Vuc2Ugb2YgdGhlIGRhdGENCmhlYWQodGl0YW5pYykNCmBgYA0KYGBge3IgZWNobz1GQUxTRSwgd2FybmluZz1UUlVFfQ0KcHJpbnQoY29sbmFtZXModGl0YW5pYykpDQoNCmlmKCJTdXJ2aXZlZCIgJWluJSBjb2xuYW1lcyh0aXRhbmljKSAmJiAhaXMuZmFjdG9yKHRpdGFuaWMkU3Vydml2ZWQpKSB7DQogICAgdGl0YW5pYyRTdXJ2aXZlZCA8LSBhcy5mYWN0b3IodGl0YW5pYyRTdXJ2aXZlZCkNCiAgICBwcmludCgiU3Vydml2ZWQgY29sdW1uIGNvbnZlcnRlZCB0byBmYWN0b3IuIikNCn0NCg0KaWYoIlNleCIgJWluJSBjb2xuYW1lcyh0aXRhbmljKSAmJiAhaXMuZmFjdG9yKHRpdGFuaWMkU2V4KSkgew0KICAgIHRpdGFuaWMkU2V4IDwtIGFzLmZhY3Rvcih0aXRhbmljJFNleCkNCiAgICBwcmludCgiU2V4IGNvbHVtbiBjb252ZXJ0ZWQgdG8gZmFjdG9yLiIpDQp9DQojIENoZWNrIGZvciBtaXNzaW5nIGRhdGENCnN1bW1hcnkodGl0YW5pYykNCg0KIyBPcHRpb24gdG8gcmVtb3ZlIHJvd3Mgd2l0aCBOQXMgaWYgaXQgbWFrZXMgc2Vuc2UgZm9yIHlvdXIgYW5hbHlzaXMNCnRpdGFuaWMgPC0gbmEub21pdCh0aXRhbmljKQ0KDQoNCmBgYA0KDQpgYGB7ciBlY2hvPUZBTFNFLCB3YXJuaW5nPVRSVUV9DQoNCnN1cnZpdmFsX2dlbmRlcl90YWJsZSA8LSB0YWJsZSh0aXRhbmljJFN1cnZpdmVkLCB0aXRhbmljJFNleCkNCg0KDQpzdXJ2aXZhbF9nZW5kZXJfdGFibGUgPC0gdGFibGUodGl0YW5pYyRTdXJ2aXZlZCwgdGl0YW5pYyRTZXgpDQpwcmludChzdXJ2aXZhbF9nZW5kZXJfdGFibGUpDQoNCg0KDQpwcmludChjaGlfcmVzdWx0cykNCg0KDQoNCmBgYA0KDQo=