Call in the SAH segmentation datasset.

library(readxl)
SAH_imaging_database <- read_excel("~/Documents/Job/Research /Bulters research/SAH imaging /Data/SAH imaging database.xlsx", 
    sheet = "Complete dataset")
Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900
View(SAH_imaging_database)

data_imaging <- SAH_imaging_database
Error in exists(cacheKey, where = .rs.WorkingDataEnv, inherits = FALSE) : 
  invalid first argument
Error in assign(cacheKey, frame, .rs.CachedDataEnv) : 
  attempt to use zero-length variable name

Cohort characteristic calcuations.

Firstly, calculate the median and IQR from symptom onset to scan.

na.omit(data_imaging$Time_until_scan_min)
 [1]  157  128  207  210  189 1165  113  163  769  340  147   13 1042  124  126  222  308   92   96  266 1200  117  148  347  934   96  652  513  144
[30]   90  637  208  276  294  533  129  155  998  330  337  149  125  244 1014  103  341  871  541  549  127  118   78  779  293  224  800  337  123
[59] 1256  225  482 1256  491  923  349  288  232 1351 1187  393  136  119 1320  261  385  728  113  175  371  117  119  671
attr(,"na.action")
 [1] 39 42 52 55 59 60 62 68 70 71 74 75 76 77 80
attr(,"class")
[1] "omit"
summary(data_imaging$Time_until_scan_min)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
   13.0   130.8   271.0   411.9   547.0  1351.0      15 
271/60 #Mediam
[1] 4.516667
130/60 #1st quartile 
[1] 2.166667
547/60 #3rd quartile
[1] 9.116667

Baseline characteristics table Unknown represents any missing data - 2 patients in the cohort did not have blood volumes collected.

library(gtsummary)
theme_gtsummary_compact()
Setting theme `Compact`
data_imaging %>% select("AGE", "SEX", "HTN", "ANEULOC", "SURGPROC", "Time_until_scan_min", "FISHGRDN", "SEBES", "Total blood", "SSV blood", "Non-SSV blood", "Total manual volume", "SSV Volume", "Ventricular volume", "Below SSV Volume", "WFNSGRDN") %>% tbl_summary()
Characteristic N = 971
AGE 55 (50, 62)
SEX
Β Β Β Β Female 75 (77%)
Β Β Β Β Male 22 (23%)
HTN
Β Β Β Β N 70 (72%)
Β Β Β Β Y 27 (28%)
ANEULOC
Β Β Β Β Anterior Circulation 80 (84%)
Β Β Β Β Posterior Circulation 15 (16%)
Β Β Β Β Unknown 2
SURGPROC
Β Β Β Β Clipping 22 (23%)
Β Β Β Β Coiling 73 (75%)
Β Β Β Β Not Done 2 (2.1%)
Time_until_scan_min 271 (131, 547)
Β Β Β Β Unknown 15
FISHGRDN
Β Β Β Β 3 37 (38%)
Β Β Β Β 4 60 (62%)
SEBES
Β Β Β Β 0 63 (65%)
Β Β Β Β 1 15 (15%)
Β Β Β Β 2 9 (9.3%)
Β Β Β Β 3 7 (7.2%)
Β Β Β Β 4 3 (3.1%)
Total blood 20 (9, 35)
SSV blood 0.00 (0.00, 1.50)
Β Β Β Β Unknown 2
Non-SSV blood 19 (9, 33)
Β Β Β Β Unknown 2
Total manual volume 158 (90, 283)
SSV Volume 37 (20, 75)
Ventricular volume 39 (23, 62)
Below SSV Volume 110 (59, 223)
WFNSGRDN
Β Β Β Β 1 44 (45%)
Β Β Β Β 2 16 (16%)
Β Β Β Β 3 5 (5.2%)
Β Β Β Β 4 27 (28%)
Β Β Β Β 5 5 (5.2%)
1 Median (IQR); n (%)

Blood distributions to check for the normality and see if transformations are required.

#Blood variables: Total Blood, SSV Blood and Non-SSV Blood

Total_blood <- SAH_imaging_database$`Total blood`
SSV_Blood <- SAH_imaging_database$`SSV blood`
Non_SSV_Blood <- SAH_imaging_database$`Non-SSV blood`

hist(Total_blood)

hist(SSV_Blood)

hist(Non_SSV_Blood)


library(moments)
d_total_blood <- density(Total_blood)# returns the density data
skewness(Total_blood, na.rm = TRUE) #Skewness
[1] 0.7766232
plot(d_total_blood, main = "Density plot Total Blood Volume (mls)", sub = "Skewness = 0.777") # plots the results


d_SSV_blood <- density(SSV_Blood, na.rm = TRUE)# returns the density data
skewness(SSV_Blood, na.rm = TRUE) #Skewness
[1] 3.526801
plot(d_SSV_blood, main = "Density plot SSV Blood Volume (mls)", sub = "Skewness = 3.53") # plots the results


d_Non_SSV_blood <- density(Non_SSV_Blood, na.rm = TRUE)# returns the density data
skewness(Non_SSV_Blood, na.rm = TRUE) #Skewness
[1] 0.7286446
plot(d_Non_SSV_blood, main = "Density plot Non-SSV Blood Volume (mls)", sub = "Skewness = 0.729") # plots the results

NA
NA

CSF distributions to check for skewness


#CSF variables: SEBES, Ventricular volume, SSV volume, Below SSV Volume

SEBES <- SAH_imaging_database$SEBES
Ventricle_CSF <- SAH_imaging_database$`Ventricular volume`
SSV_CSF <- SAH_imaging_database$`SSV Volume`
Below_SSV_CSF <- SAH_imaging_database$`Below SSV Volume`
Total_CSF <- SAH_imaging_database$`Total manual volume`

hist(SEBES)

hist(Ventricle_CSF)

hist(SSV_CSF)

hist(Below_SSV_CSF)

hist(Total_CSF)


library(moments)
d_SEBES <- density(SEBES)# returns the density data
skewness(SEBES, na.rm = TRUE) #Skewness
[1] 1.542407
plot(d_SEBES, main = "Density plot SEBES", sub = "Skewness = 1.542") # plots the results


d_Ventricle_CSF <- density(Ventricle_CSF, na.rm = TRUE)# returns the density data
skewness(Ventricle_CSF, na.rm = TRUE) #Skewness
[1] 1.590469
plot(d_Ventricle_CSF, main = "Density plot Ventricle CSF Volume (mls)", sub = "Skewness = 1.59") # plots the results


d_SSV_CSF <- density(SSV_CSF, na.rm = TRUE)# returns the density data
skewness(SSV_CSF, na.rm = TRUE) #Skewness
[1] 1.431467
plot(d_SSV_CSF, main = "Density plot SSV CSF Volume (mls)", sub = "Skewness = 1.43") # plots the results


d_Below_SSV_CSF <- density(Below_SSV_CSF, na.rm = TRUE)# returns the density data
skewness(Below_SSV_CSF, na.rm = TRUE) #Skewness
[1] 0.8290886
plot(d_Below_SSV_CSF, main = "Density plot Below SSV CSF Volume (mls)", sub = "Skewness = 0.829") # plots the results


d_Total_CSF <- density(Total_CSF, na.rm = TRUE)# returns the density data
skewness(Total_CSF, na.rm = TRUE) #Skewness
[1] 0.899855
plot(d_Total_CSF, main = "Density plot Total CSF Volume (mls)", sub = "Skewness = 0.9") # plots the results

Decision made not to transform the variables because they are generally normally distributed, with the exception of SSV blood which is not a clinically important variable anyway.

The next step is to identify through correlation matrices, how the imaging variables are related..


#For visualisation ensure that the variables have the correct names 

SAH_imaging_database$Age <- SAH_imaging_database$AGE
SAH_imaging_database$WFNS <- SAH_imaging_database$WFNSGRDN
SAH_imaging_database$Total_CSF <- SAH_imaging_database$`Total manual volume`
SAH_imaging_database$Ventricular_CSF <- SAH_imaging_database$`Ventricular volume`
SAH_imaging_database$SSV_CSF <- SAH_imaging_database$`SSV Volume`

data_imaging_correlation <- SAH_imaging_database[, c("Age", "WFNS",
                                        "Total blood", "SSV_CSF", "Ventricular_CSF",
                                        "Total_CSF")]

data_imaging_correlation <- na.omit(data_imaging_correlation)

remove.packages('Hmisc')
Removing package from β€˜/Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library’
(as β€˜lib’ is unspecified)
install.packages("Hmisc", repos="http://cran.rstudio.com/", dependencies=TRUE)
trying URL 'http://cran.rstudio.com/bin/macosx/big-sur-arm64/contrib/4.3/Hmisc_5.1-0.tgz'
Content type 'application/x-gzip' length 3515239 bytes (3.4 MB)
==================================================
downloaded 3.4 MB

The downloaded binary packages are in
    /var/folders/5q/zxkgc5yn685ffrcr6m2_f_4h0000gn/T//RtmpVnEbxd/downloaded_packages
install.packages("checkmate")
trying URL 'https://cran.rstudio.com/bin/macosx/big-sur-arm64/contrib/4.3/checkmate_2.2.0.tgz'
Content type 'application/x-gzip' length 772034 bytes (753 KB)
==================================================
downloaded 753 KB

The downloaded binary packages are in
    /var/folders/5q/zxkgc5yn685ffrcr6m2_f_4h0000gn/T//RtmpVnEbxd/downloaded_packages
library(Hmisc)
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     

Attaching package: β€˜Hmisc’

The following objects are masked from β€˜package:base’:

    format.pval, units
res2 <- rcorr(as.matrix(data_imaging_correlation), type = "spearman")
res2
                 Age  WFNS Total blood SSV_CSF Ventricular_CSF Total_CSF
Age             1.00  0.06        0.01    0.24            0.39      0.34
WFNS            0.06  1.00        0.46   -0.37           -0.03     -0.14
Total blood     0.01  0.46        1.00   -0.26           -0.28     -0.19
SSV_CSF         0.24 -0.37       -0.26    1.00            0.45      0.78
Ventricular_CSF 0.39 -0.03       -0.28    0.45            1.00      0.78
Total_CSF       0.34 -0.14       -0.19    0.78            0.78      1.00

n= 97 


P
                Age    WFNS   Total blood SSV_CSF Ventricular_CSF Total_CSF
Age                    0.5781 0.9249      0.0196  0.0000          0.0007   
WFNS            0.5781        0.0000      0.0002  0.7396          0.1653   
Total blood     0.9249 0.0000             0.0108  0.0051          0.0589   
SSV_CSF         0.0196 0.0002 0.0108              0.0000          0.0000   
Ventricular_CSF 0.0000 0.7396 0.0051      0.0000                  0.0000   
Total_CSF       0.0007 0.1653 0.0589      0.0000  0.0000                   
res2$r
                        Age        WFNS  Total blood    SSV_CSF Ventricular_CSF  Total_CSF
Age             1.000000000  0.05716434  0.009694334  0.2367181      0.38567391  0.3391306
WFNS            0.057164345  1.00000000  0.460972143 -0.3728866     -0.03418735 -0.1420047
Total blood     0.009694334  0.46097214  1.000000000 -0.2577188     -0.28217705 -0.1925100
SSV_CSF         0.236718130 -0.37288664 -0.257718809  1.0000000      0.44937408  0.7821244
Ventricular_CSF 0.385673908 -0.03418735 -0.282177046  0.4493741      1.00000000  0.7780086
Total_CSF       0.339130575 -0.14200467 -0.192509994  0.7821244      0.77800863  1.0000000
res2$P
                         Age         WFNS  Total blood      SSV_CSF Ventricular_CSF    Total_CSF
Age                       NA 5.781015e-01 9.249165e-01 1.957150e-02    9.569289e-05 0.0006787165
WFNS            5.781015e-01           NA 2.018435e-06 1.688910e-04    7.395581e-01 0.1652907303
Total blood     9.249165e-01 2.018435e-06           NA 1.081759e-02    5.106494e-03 0.0588736570
SSV_CSF         1.957150e-02 1.688910e-04 1.081759e-02           NA    3.889443e-06 0.0000000000
Ventricular_CSF 9.569289e-05 7.395581e-01 5.106494e-03 3.889443e-06              NA 0.0000000000
Total_CSF       6.787165e-04 1.652907e-01 5.887366e-02 0.000000e+00    0.000000e+00           NA
flattenCorrMatrix <- function(cormat, pmat) { #format correlation matrix 
  ut <- upper.tri(cormat)
  data.frame(
    row = rownames(cormat)[row(cormat)[ut]],
    column = rownames(cormat)[col(cormat)[ut]],
    cor  =(cormat)[ut],
    p = pmat[ut]
  )
}

correlation_matrix <- flattenCorrMatrix(res2$r, res2$P)
write.csv(correlation_matrix, "Correlation_matrix.csv", row.names = F) #export table 


library(corrplot) #visualise the correlation matrix
corrplot 0.92 loaded
res <- cor(data_imaging_correlation)
corrplot(res, type = "upper", order = "hclust", 
         tl.col = "black", tl.srt = 45)



corrplot(res2$r, type="upper", order="hclust", #insignificant correlations removed
         p.mat = res2$P, sig.level = 0.01, insig = "blank")
Error in data.frame(..., check.names = FALSE) : 
  arguments imply differing number of rows: 21, 15

Univariate analysis of variables

summary(Univariate)

Call:
glm(formula = data_imaging$SAHOT180_dich ~ data_imaging$Total_CSF, 
    family = binomial, data = data_imaging)

Coefficients:
                        Estimate Std. Error z value Pr(>|z|)
(Intercept)            -0.381248   0.379002  -1.006    0.314
data_imaging$Total_CSF -0.001276   0.001626  -0.785    0.433

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 122.70  on 94  degrees of freedom
Residual deviance: 122.07  on 93  degrees of freedom
AIC: 126.07

Number of Fisher Scoring iterations: 4

Dominance plots

To prevent overfitting of further predictive models, a dominance analysis was done by assessing each variable’s R2 when predicting mRS at day 28 and day 180. The mRS at day 28 and day 180 were used because mRS is used most widely in clinical practice to assess functional outcome. Day 28 was selected to reflect short term and day 180 long-term outcome. In addition, to demonstrate the difference between a general scale of functional outcome for stroke and a patient reported SAH specific scale of symptoms we undertook a dominance analysis of SAHOT on day 180.

Multivariate analysis

In order to investigate the additional benefit of blood and CSF volume measurements in models over conventional clinical features alone multivariate models were built using the previously reported SAHIT core variables to predict mRS at day 28 and 180 and repeated adding total blood volume, SSV CSF, ventricular CSF.

Core model= Age, Hypertension and Admission WFNS Neuroimaging model= Core model + Total Blood volume, SSV CSF and Ventricular CSF

For unknown reasons the below code did not work and therefore, I created the AUC graphs by adapting my previous analysed code.

legend("bottomright", title = "modified Rankin Scale", 
       legend = c("Neuroimaging Day 28", "Neuroimaging Day 180", "Clinical Day 28", "Clinical Day 180"), col = c("red", "black", "orange", "blue"), 
       lwd = 2, "Legend", cex=0.8)
Error in (function (s, units = "user", cex = NULL, font = NULL, vfont = NULL,  : 
  plot.new has not been called yet

SSV dichotomisation from the literature

Choi et al.: SSV not normally distributed and subjects separated into equal quartiles for measuring odds ratios in examining associations with GCE as well as clinical outcomes. FINDINGS: compared to patients in the highest quartile for SSV, the OR for poor outcome at discharge increased in a dose dependent manner in the lower quartiles after adjusting for age, sex, smoking hypertension and HH score

Yuan et al.: SSV taken as continuous variable and in sensitivity analysis dichotomisation at <5.2ml was done. FINDINGS early SSV defined as lowest SSV volume in first 72hrs but not admission SSV was predictive of outcome

Create two new variables, SSV_quantiles and SSV_dich

levels(SSV_dich)
NULL

Currently have several CSF volumes including - total CSF, SSV CSF, ventricular CSF and below SSV CSF. However, one volume that is missing, is a non-SSV, non-ventricular CSF.

Create non_SSV_non_vent_CSF variable

summary(Univariate)

Call:
glm(formula = SAHOT180_dich ~ non_SSV_non_vent_CSF, family = binomial, 
    data = data_imaging)

Coefficients:
                      Estimate Std. Error z value Pr(>|z|)  
(Intercept)          -0.658236   0.338537  -1.944   0.0519 .
non_SSV_non_vent_CSF  0.000288   0.002716   0.106   0.9155  
---
Signif. codes:  0 β€˜***’ 0.001 β€˜**’ 0.01 β€˜*’ 0.05 β€˜.’ 0.1 β€˜ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 122.70  on 94  degrees of freedom
Residual deviance: 122.69  on 93  degrees of freedom
  (2 observations deleted due to missingness)
AIC: 126.69

Number of Fisher Scoring iterations: 4

Before multivariate analysis, let’s see if the new SSV cut-offs make it a significant predictor of day 30 and 180 outcome in a univariate analysis

summary(Univariate)

Call:
glm(formula = SAHOT180_dich ~ SSV_dich, family = binomial, data = data_imaging)

Coefficients:
            Estimate Std. Error z value Pr(>|z|)   
(Intercept)  -0.7357     0.2536  -2.901  0.00372 **
SSV_dichlow   0.3992     0.4855   0.822  0.41093   
---
Signif. codes:  0 β€˜***’ 0.001 β€˜**’ 0.01 β€˜*’ 0.05 β€˜.’ 0.1 β€˜ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 122.70  on 94  degrees of freedom
Residual deviance: 122.03  on 93  degrees of freedom
  (2 observations deleted due to missingness)
AIC: 126.03

Number of Fisher Scoring iterations: 4

Repeat regressions:

Before we make that major restructure we wanted to see the outcomes of the regressions for

  1. WFNS, TBV and SSV to predict outcome (MRS and SAHOT at day 30 and 180)
  2. WFNS, TBV and ventricular volume to predict outcome

If the latter does not give a clear result then we wanted to try it again but:

  1. add presence of an EVD as a covariate and an interaction between ventricular volume and an EVD
  2. add an interaction between TBV and ventricular volume

# Regression 1: WFNS, TBV and SSV regression

Multivariate <- glm(as.factor(mRS28) ~ WFNS+Total_blood_volume+SSV_CSF, family = binomial, data = data_imaging)
summary(Multivariate)

Call:
glm(formula = as.factor(mRS28) ~ WFNS + Total_blood_volume + 
    SSV_CSF, family = binomial, data = data_imaging)

Coefficients:
                    Estimate Std. Error z value Pr(>|z|)    
(Intercept)        -3.010329   0.784551  -3.837 0.000125 ***
WFNS                0.856655   0.209192   4.095 4.22e-05 ***
Total_blood_volume  0.014721   0.015629   0.942 0.346263    
SSV_CSF            -0.004514   0.006311  -0.715 0.474383    
---
Signif. codes:  0 β€˜***’ 0.001 β€˜**’ 0.01 β€˜*’ 0.05 β€˜.’ 0.1 β€˜ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 124.387  on 96  degrees of freedom
Residual deviance:  89.964  on 93  degrees of freedom
AIC: 97.964

Number of Fisher Scoring iterations: 4
Multivariate <- glm(as.factor(mRS180) ~ WFNS+Total_blood_volume+SSV_CSF, family = binomial, data = data_imaging)
summary(Multivariate)

Call:
glm(formula = as.factor(mRS180) ~ WFNS + Total_blood_volume + 
    SSV_CSF, family = binomial, data = data_imaging)

Coefficients:
                    Estimate Std. Error z value Pr(>|z|)    
(Intercept)        -3.415511   0.984158  -3.470  0.00052 ***
WFNS                0.525937   0.238247   2.208  0.02728 *  
Total_blood_volume  0.018970   0.016313   1.163  0.24489    
SSV_CSF            -0.004060   0.007936  -0.512  0.60894    
---
Signif. codes:  0 β€˜***’ 0.001 β€˜**’ 0.01 β€˜*’ 0.05 β€˜.’ 0.1 β€˜ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 86.870  on 96  degrees of freedom
Residual deviance: 74.307  on 93  degrees of freedom
AIC: 82.307

Number of Fisher Scoring iterations: 5
Multivariate <- glm(as.factor(SAHOT28_dich) ~ WFNS+Total_blood_volume+SSV_CSF, family = binomial, data = data_imaging)
summary(Multivariate)

Call:
glm(formula = as.factor(SAHOT28_dich) ~ WFNS + Total_blood_volume + 
    SSV_CSF, family = binomial, data = data_imaging)

Coefficients:
                    Estimate Std. Error z value Pr(>|z|)  
(Intercept)        -0.469845   0.589470  -0.797   0.4254  
WFNS                0.213558   0.180917   1.180   0.2378  
Total_blood_volume  0.024086   0.014551   1.655   0.0979 .
SSV_CSF            -0.008032   0.005332  -1.506   0.1320  
---
Signif. codes:  0 β€˜***’ 0.001 β€˜**’ 0.01 β€˜*’ 0.05 β€˜.’ 0.1 β€˜ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 131.18  on 94  degrees of freedom
Residual deviance: 117.88  on 91  degrees of freedom
  (2 observations deleted due to missingness)
AIC: 125.88

Number of Fisher Scoring iterations: 4
Multivariate <- glm(as.factor(SAHOT180_dich) ~ WFNS+Total_blood_volume+SSV_CSF, family = binomial, data = data_imaging)
summary(Multivariate)

Call:
glm(formula = as.factor(SAHOT180_dich) ~ WFNS + Total_blood_volume + 
    SSV_CSF, family = binomial, data = data_imaging)

Coefficients:
                    Estimate Std. Error z value Pr(>|z|)  
(Intercept)        -0.936754   0.645685  -1.451   0.1468  
WFNS               -0.014991   0.187351  -0.080   0.9362  
Total_blood_volume  0.030589   0.014152   2.161   0.0307 *
SSV_CSF            -0.009022   0.006394  -1.411   0.1582  
---
Signif. codes:  0 β€˜***’ 0.001 β€˜**’ 0.01 β€˜*’ 0.05 β€˜.’ 0.1 β€˜ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 122.70  on 94  degrees of freedom
Residual deviance: 112.25  on 91  degrees of freedom
  (2 observations deleted due to missingness)
AIC: 120.25

Number of Fisher Scoring iterations: 4
# For mRS, WFNS is a significant predictor, for SAHOT, TBV is significant.Substitute in new SSV variables to see if this makes a difference. 

#SSV_quantile first

Multivariate <- glm(as.factor(mRS28) ~ WFNS+Total_blood_volume+SSV_quantiles, family = binomial, data = data_imaging)
summary(Multivariate)

Call:
glm(formula = as.factor(mRS28) ~ WFNS + Total_blood_volume + 
    SSV_quantiles, family = binomial, data = data_imaging)

Coefficients:
                   Estimate Std. Error z value Pr(>|z|)    
(Intercept)        -3.44386    0.95249  -3.616 0.000300 ***
WFNS                0.91927    0.23636   3.889 0.000101 ***
Total_blood_volume  0.01880    0.01655   1.136 0.255768    
SSV_quantiles2     -0.36984    0.78129  -0.473 0.635952    
SSV_quantiles3      0.62358    0.78633   0.793 0.427768    
SSV_quantiles4     -0.72274    0.81935  -0.882 0.377732    
---
Signif. codes:  0 β€˜***’ 0.001 β€˜**’ 0.01 β€˜*’ 0.05 β€˜.’ 0.1 β€˜ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 124.387  on 96  degrees of freedom
Residual deviance:  87.279  on 91  degrees of freedom
AIC: 99.279

Number of Fisher Scoring iterations: 5
Multivariate <- glm(as.factor(mRS180) ~ WFNS+Total_blood_volume+SSV_quantiles, family = binomial, data = data_imaging)
summary(Multivariate)

Call:
glm(formula = as.factor(mRS180) ~ WFNS + Total_blood_volume + 
    SSV_quantiles, family = binomial, data = data_imaging)

Coefficients:
                   Estimate Std. Error z value Pr(>|z|)    
(Intercept)        -4.62012    1.16642  -3.961 7.47e-05 ***
WFNS                0.70936    0.26454   2.681  0.00733 ** 
Total_blood_volume  0.01309    0.01801   0.727  0.46708    
SSV_quantiles2      1.10257    0.85530   1.289  0.19736    
SSV_quantiles3      1.23702    0.91902   1.346  0.17829    
SSV_quantiles4      0.23181    1.00954   0.230  0.81838    
---
Signif. codes:  0 β€˜***’ 0.001 β€˜**’ 0.01 β€˜*’ 0.05 β€˜.’ 0.1 β€˜ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 86.870  on 96  degrees of freedom
Residual deviance: 71.709  on 91  degrees of freedom
AIC: 83.709

Number of Fisher Scoring iterations: 5
Multivariate <- glm(as.factor(SAHOT28_dich) ~ WFNS+Total_blood_volume+SSV_quantiles, family = binomial, data = data_imaging)
summary(Multivariate)

Call:
glm(formula = as.factor(SAHOT28_dich) ~ WFNS + Total_blood_volume + 
    SSV_quantiles, family = binomial, data = data_imaging)

Coefficients:
                   Estimate Std. Error z value Pr(>|z|)
(Intercept)        -0.56706    0.74665  -0.759    0.448
WFNS                0.22010    0.20052   1.098    0.272
Total_blood_volume  0.02143    0.01498   1.431    0.152
SSV_quantiles2      0.35846    0.70441   0.509    0.611
SSV_quantiles3     -0.59282    0.66883  -0.886    0.375
SSV_quantiles4     -0.84778    0.68353  -1.240    0.215

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 131.18  on 94  degrees of freedom
Residual deviance: 116.03  on 89  degrees of freedom
  (2 observations deleted due to missingness)
AIC: 128.03

Number of Fisher Scoring iterations: 4
Multivariate <- glm(as.factor(SAHOT180_dich) ~ WFNS+Total_blood_volume+SSV_quantiles, family = binomial, data = data_imaging)
summary(Multivariate)

Call:
glm(formula = as.factor(SAHOT180_dich) ~ WFNS + Total_blood_volume + 
    SSV_quantiles, family = binomial, data = data_imaging)

Coefficients:
                     Estimate Std. Error z value Pr(>|z|)  
(Intercept)        -1.1602876  0.7493937  -1.548   0.1215  
WFNS               -0.0006619  0.2018584  -0.003   0.9974  
Total_blood_volume  0.0305582  0.0147357   2.074   0.0381 *
SSV_quantiles2      0.0063719  0.6535923   0.010   0.9922  
SSV_quantiles3     -0.1591029  0.6770875  -0.235   0.8142  
SSV_quantiles4     -1.0107826  0.7590549  -1.332   0.1830  
---
Signif. codes:  0 β€˜***’ 0.001 β€˜**’ 0.01 β€˜*’ 0.05 β€˜.’ 0.1 β€˜ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 122.70  on 94  degrees of freedom
Residual deviance: 111.88  on 89  degrees of freedom
  (2 observations deleted due to missingness)
AIC: 123.88

Number of Fisher Scoring iterations: 4
#Makes no difference. How about SSV_dich

Multivariate <- glm(as.factor(mRS28) ~ WFNS+Total_blood_volume+SSV_dich, family = binomial, data = data_imaging)
summary(Multivariate)

Call:
glm(formula = as.factor(mRS28) ~ WFNS + Total_blood_volume + 
    SSV_dich, family = binomial, data = data_imaging)

Coefficients:
                   Estimate Std. Error z value Pr(>|z|)    
(Intercept)        -3.35505    0.64610  -5.193 2.07e-07 ***
WFNS                0.86463    0.22327   3.873 0.000108 ***
Total_blood_volume  0.01661    0.01556   1.067 0.285778    
SSV_dichlow         0.16214    0.61914   0.262 0.793417    
---
Signif. codes:  0 β€˜***’ 0.001 β€˜**’ 0.01 β€˜*’ 0.05 β€˜.’ 0.1 β€˜ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 124.387  on 96  degrees of freedom
Residual deviance:  90.424  on 93  degrees of freedom
AIC: 98.424

Number of Fisher Scoring iterations: 4
Multivariate <- glm(as.factor(mRS180) ~ WFNS+Total_blood_volume+SSV_dich, family = binomial, data = data_imaging)
summary(Multivariate)

Call:
glm(formula = as.factor(mRS180) ~ WFNS + Total_blood_volume + 
    SSV_dich, family = binomial, data = data_imaging)

Coefficients:
                   Estimate Std. Error z value Pr(>|z|)    
(Intercept)        -3.74949    0.81003  -4.629 3.68e-06 ***
WFNS                0.69899    0.26084   2.680  0.00737 ** 
Total_blood_volume  0.01566    0.01677   0.934  0.35020    
SSV_dichlow        -0.90681    0.74110  -1.224  0.22111    
---
Signif. codes:  0 β€˜***’ 0.001 β€˜**’ 0.01 β€˜*’ 0.05 β€˜.’ 0.1 β€˜ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 86.870  on 96  degrees of freedom
Residual deviance: 72.985  on 93  degrees of freedom
AIC: 80.985

Number of Fisher Scoring iterations: 5
Multivariate <- glm(as.factor(SAHOT28_dich) ~ WFNS+Total_blood_volume+SSV_dich, family = binomial, data = data_imaging)
summary(Multivariate)

Call:
glm(formula = as.factor(SAHOT28_dich) ~ WFNS + Total_blood_volume + 
    SSV_dich, family = binomial, data = data_imaging)

Coefficients:
                   Estimate Std. Error z value Pr(>|z|)  
(Intercept)        -1.06198    0.44665  -2.378   0.0174 *
WFNS                0.20878    0.19555   1.068   0.2857  
Total_blood_volume  0.02790    0.01457   1.915   0.0555 .
SSV_dichlow         0.37694    0.57273   0.658   0.5104  
---
Signif. codes:  0 β€˜***’ 0.001 β€˜**’ 0.01 β€˜*’ 0.05 β€˜.’ 0.1 β€˜ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 131.18  on 94  degrees of freedom
Residual deviance: 119.86  on 91  degrees of freedom
  (2 observations deleted due to missingness)
AIC: 127.86

Number of Fisher Scoring iterations: 4
Multivariate <- glm(as.factor(SAHOT180_dich) ~ WFNS+Total_blood_volume+SSV_dich, family = binomial, data = data_imaging)
summary(Multivariate)

Call:
glm(formula = as.factor(SAHOT180_dich) ~ WFNS + Total_blood_volume + 
    SSV_dich, family = binomial, data = data_imaging)

Coefficients:
                    Estimate Std. Error z value Pr(>|z|)   
(Intercept)        -1.583066   0.483300  -3.276  0.00105 **
WFNS                0.008426   0.200301   0.042  0.96645   
Total_blood_volume  0.033597   0.014236   2.360  0.01827 * 
SSV_dichlow         0.308950   0.565281   0.547  0.58469   
---
Signif. codes:  0 β€˜***’ 0.001 β€˜**’ 0.01 β€˜*’ 0.05 β€˜.’ 0.1 β€˜ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 122.70  on 94  degrees of freedom
Residual deviance: 114.23  on 91  degrees of freedom
  (2 observations deleted due to missingness)
AIC: 122.23

Number of Fisher Scoring iterations: 4
#Again no difference made. 

# Regression 2: WFNS, TBV and ventricular volume to predict outcome

Multivariate <- glm(as.factor(mRS28) ~ WFNS+Total_blood_volume+Ventricular_CSF, family = binomial, data = data_imaging)
summary(Multivariate)

Call:
glm(formula = as.factor(mRS28) ~ WFNS + Total_blood_volume + 
    Ventricular_CSF, family = binomial, data = data_imaging)

Coefficients:
                    Estimate Std. Error z value Pr(>|z|)    
(Intercept)        -4.396700   0.877685  -5.009 5.46e-07 ***
WFNS                0.882108   0.213980   4.122 3.75e-05 ***
Total_blood_volume  0.026610   0.016492   1.614   0.1066    
Ventricular_CSF     0.014472   0.006771   2.137   0.0326 *  
---
Signif. codes:  0 β€˜***’ 0.001 β€˜**’ 0.01 β€˜*’ 0.05 β€˜.’ 0.1 β€˜ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 124.39  on 96  degrees of freedom
Residual deviance:  85.55  on 93  degrees of freedom
AIC: 93.55

Number of Fisher Scoring iterations: 5
Multivariate <- glm(as.factor(mRS180) ~ WFNS+Total_blood_volume+Ventricular_CSF, family = binomial, data = data_imaging)
summary(Multivariate)

Call:
glm(formula = as.factor(mRS180) ~ WFNS + Total_blood_volume + 
    Ventricular_CSF, family = binomial, data = data_imaging)

Coefficients:
                    Estimate Std. Error z value Pr(>|z|)    
(Intercept)        -4.688721   1.031167  -4.547 5.44e-06 ***
WFNS                0.535981   0.241497   2.219   0.0265 *  
Total_blood_volume  0.030422   0.017492   1.739   0.0820 .  
Ventricular_CSF     0.012876   0.006733   1.912   0.0558 .  
---
Signif. codes:  0 β€˜***’ 0.001 β€˜**’ 0.01 β€˜*’ 0.05 β€˜.’ 0.1 β€˜ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 86.870  on 96  degrees of freedom
Residual deviance: 70.991  on 93  degrees of freedom
AIC: 78.991

Number of Fisher Scoring iterations: 5
Multivariate <- glm(as.factor(SAHOT28_dich) ~ WFNS+Total_blood_volume+Ventricular_CSF, family = binomial, data = data_imaging)
summary(Multivariate)

Call:
glm(formula = as.factor(SAHOT28_dich) ~ WFNS + Total_blood_volume + 
    Ventricular_CSF, family = binomial, data = data_imaging)

Coefficients:
                    Estimate Std. Error z value Pr(>|z|)  
(Intercept)        -1.309795   0.552306  -2.372   0.0177 *
WFNS                0.242631   0.177250   1.369   0.1710  
Total_blood_volume  0.029947   0.015179   1.973   0.0485 *
Ventricular_CSF     0.004223   0.005557   0.760   0.4473  
---
Signif. codes:  0 β€˜***’ 0.001 β€˜**’ 0.01 β€˜*’ 0.05 β€˜.’ 0.1 β€˜ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 131.18  on 94  degrees of freedom
Residual deviance: 119.71  on 91  degrees of freedom
  (2 observations deleted due to missingness)
AIC: 127.71

Number of Fisher Scoring iterations: 4
Multivariate <- glm(as.factor(SAHOT180_dich) ~ WFNS+Total_blood_volume+Ventricular_CSF, family = binomial, data = data_imaging)
summary(Multivariate)

Call:
glm(formula = as.factor(SAHOT180_dich) ~ WFNS + Total_blood_volume + 
    Ventricular_CSF, family = binomial, data = data_imaging)

Coefficients:
                     Estimate Std. Error z value Pr(>|z|)   
(Intercept)        -1.586e+00  5.821e-01  -2.725  0.00644 **
WFNS                5.660e-02  1.822e-01   0.311  0.75604   
Total_blood_volume  3.239e-02  1.463e-02   2.213  0.02688 * 
Ventricular_CSF     5.209e-05  5.813e-03   0.009  0.99285   
---
Signif. codes:  0 β€˜***’ 0.001 β€˜**’ 0.01 β€˜*’ 0.05 β€˜.’ 0.1 β€˜ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 122.70  on 94  degrees of freedom
Residual deviance: 114.53  on 91  degrees of freedom
  (2 observations deleted due to missingness)
AIC: 122.53

Number of Fisher Scoring iterations: 4
# Ventricular CSF significant at 30 day mRS and almost significant for mRS 180. However, not significant for SAHOT. 

The above regressions demonstrate several observations with the dataset:

  1. WFNS is a highly significant predictor of functional outcome at 30 days and 180 days
  2. When using a more specific outcome tool for SAH (SAHOT), TBV is shown to be a highly significant predictor
  3. Univariate analysis of SSV using cut offs, which isolate cases with β€˜low’ SSV, makes it a significant variable at early timepoints
  4. Multivariate analyse shows that SSV is not an independent predictor of outcome when TBV and WFNS are included. However, Ventricular volume is an independent predictor of outcome using mRS

I think the above gives a clear result. Firstly, it shows that we have been able to replicate previous findings in the literature, that at early timepoints SSV predicts outcome. However, we have shown that this affect is not maintained at later timepoints or when combined with other significant predictors of outcome. Instead, imaging predictors of TBV, and to a lesser extent ventricular CSF are more important.

The narrative of the paper is clearer to me now and I think should be presented something like this:

  1. Basic demographics
  2. Regression 1 and Regression 2 from above
  3. Interaction plots
  4. Inclusion of β€˜other’ imaging variables to show they are less relevant

For completeness, below I will include:

  1. add presence of an EVD as a covariate and an interaction between ventricular volume and an EVD
  2. add an interaction between TBV and ventricular volume
summary(Multivariate)

Call:
glm(formula = as.factor(mRS180) ~ WFNS + Total_blood_volume + 
    Ventricular_CSF * EVD, family = binomial, data = data_imaging)

Coefficients:
                     Estimate Std. Error z value Pr(>|z|)    
(Intercept)          -5.17723    1.23504  -4.192 2.77e-05 ***
WFNS                  0.35852    0.29083   1.233   0.2177    
Total_blood_volume    0.02756    0.01767   1.560   0.1188    
Ventricular_CSF       0.02031    0.01024   1.983   0.0474 *  
EVDY                  2.12353    1.11352   1.907   0.0565 .  
Ventricular_CSF:EVDY -0.01595    0.01299  -1.227   0.2197    
---
Signif. codes:  0 β€˜***’ 0.001 β€˜**’ 0.01 β€˜*’ 0.05 β€˜.’ 0.1 β€˜ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 86.870  on 96  degrees of freedom
Residual deviance: 66.859  on 91  degrees of freedom
AIC: 78.859

Number of Fisher Scoring iterations: 6

Another thing we should check is whether the model fit is better if we use just: -WFNS and blood vol -WFNS and CSF vol -Blood and CSF vol

summary(Multivariate)

Call:
glm(formula = as.factor(mRS180) ~ WFNS + Total_blood_volume + 
    Total_CSF, family = binomial, data = data_imaging)

Coefficients:
                    Estimate Std. Error z value Pr(>|z|)    
(Intercept)        -4.399267   1.094137  -4.021  5.8e-05 ***
WFNS                0.609560   0.242768   2.511    0.012 *  
Total_blood_volume  0.022004   0.016296   1.350    0.177    
Total_CSF           0.002316   0.002224   1.041    0.298    
---
Signif. codes:  0 β€˜***’ 0.001 β€˜**’ 0.01 β€˜*’ 0.05 β€˜.’ 0.1 β€˜ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 86.870  on 96  degrees of freedom
Residual deviance: 73.526  on 93  degrees of freedom
AIC: 81.526

Number of Fisher Scoring iterations: 5

SAHOT as linear to see if this changes significance of variables. SAHOT is a 9 part scale 1 (Best outcome), 9 (death).

Repeat regressions Univariate SSV analyses:

As SAHOT as a linear 9 point scale,

Repeat regressions SAHOT at D28 and D180: 1) WFNS, TBV and SSV to predict outcome (MRS and SAHOT at day 30 and 180) 2) WFNS, TBV and ventricular volume to predict outcome

summary(Multivariate)

Call:
lm(formula = sahot180 ~ WFNS + Total_blood_volume + Ventricular_CSF, 
    data = data_imaging)

Residuals:
    Min      1Q  Median      3Q     Max 
-3.4973 -1.7656 -0.4125  1.5223  5.1628 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)        2.2918313  0.5470922   4.189 6.47e-05 ***
WFNS               0.2250422  0.1820884   1.236  0.21968    
Total_blood_volume 0.0416388  0.0143432   2.903  0.00464 ** 
Ventricular_CSF    0.0008862  0.0056270   0.157  0.87520    
---
Signif. codes:  0 β€˜***’ 0.001 β€˜**’ 0.01 β€˜*’ 0.05 β€˜.’ 0.1 β€˜ ’ 1

Residual standard error: 2.149 on 91 degrees of freedom
  (2 observations deleted due to missingness)
Multiple R-squared:  0.1658,    Adjusted R-squared:  0.1383 
F-statistic: 6.028 on 3 and 91 DF,  p-value: 0.0008604

Reasoning why a variable in a univariate analysis is not significant but becomes significant in a multivariate analysis:

The case of two predictors that are truly orthogonal: there is absolutely no collinearity among them. A remarkable change in significance can still happen.

Designate the predictor variables 𝑋1 and 𝑋2 and let π‘Œ name the predictor. The regression of π‘Œ against 𝑋1 will fail to be significant when the variation in π‘Œ around its mean is not appreciably reduced when 𝑋1 is used as the independent variable. When that variation is strongly associated with a second variable 𝑋2, however, the situation changes. Recall that multiple regression of π‘Œ against 𝑋1 and 𝑋2 is equivalent to separately regress π‘Œ and 𝑋1 against 𝑋2.

Regress the π‘Œ residuals against the 𝑋1 residuals.

The residuals from the first step have removed the effect of 𝑋2. When 𝑋2 is closely correlated with π‘Œ, this can expose a relatively small amount of variation that had previously been masked. If this variation is associated with 𝑋1, we obtain a significant result.

Further info from: https://stats.stackexchange.com/questions/28474/how-can-adding-a-2nd-iv-make-the-1st-iv-significant

In the analyses done WFNS and ventricular volume are not colinear, but blood volume and ventricular volume are colinear in a negative direction. WFNS and ventricular volume, therefore represent the above finding:

#Ventricular volume only

Univariate <- glm(as.factor(mRS180) ~ Ventricular_CSF, family = binomial, data = data_imaging) summary(Univariate)

#Ventricular volume is not significant on its own

#WFNS and ventricular volume

Multivariate <- glm(as.factor(mRS180) ~ WFNS+Ventricular_CSF, family = binomial, data = data_imaging) summary(Multivariate)

##AIC: 94.269 #WFNS significant, ventricular volume is almost significant

#Blood and ventricular volume

Multivariate <- glm(as.factor(mRS180) ~ Total_blood_volume+Ventricular_CSF, family = binomial, data = data_imaging) summary(Multivariate)

##AIC: 112.16 #Total blood very significant and ventricular volume significant - probably due to collinarity

Shapley plots

Complex predictive models are not easy to interpret. By complex I mean: random forest, xgboost, deep learning, etc.

Shapley values calculate the importance of a feature by comparing what a model predicts with and without the feature. However, since the order in which a model sees features can affect its predictions, this is done in every possible order, so that the features are fairly compared.

How to interpret the shap summary plot?

The y-axis indicates the variable name, in order of importance from top to bottom. The value next to them is the mean SHAP value. On the x-axis is the SHAP value. Indicates how much is the change in log-odds. From this number we can extract the probability of success. Gradient color indicates the original value for that variable. In booleans, it will take two colors, but in number it can contain the whole spectrum. Each point represents a row from the original dataset.

fit_xgb <- xgb.train(
  params,
  data = dtrain,
  watchlist = list(valid = dvalid),
  early_stopping_rounds = 20,
  print_every_n = 100,
  nrounds = 10000 # early stopping
)
Error in xgb.iter.update(bst$handle, dtrain, iteration - 1, obj) : 
  [15:53:06] src/objective/regression_obj.cu:43: Check failed: info.labels.Shape(0) == info.num_row_ (0 vs. 97) : Invalid shape of labels.
Stack trace:
  [bt] (0) 1   xgboost.so                          0x000000013580bd3c dmlc::LogMessageFatal::~LogMessageFatal() + 124
  [bt] (1) 2   xgboost.so                          0x0000000135836b10 xgboost::obj::(anonymous namespace)::CheckInitInputs(xgboost::MetaInfo const&) + 208
  [bt] (2) 3   xgboost.so                          0x00000001358368dc xgboost::obj::(anonymous namespace)::CheckRegInputs(xgboost::MetaInfo const&, xgboost::HostDeviceVector<float> const&) + 28
  [bt] (3) 4   xgboost.so                          0x0000000135835c3c xgboost::obj::RegLossObj<xgboost::obj::LinearSquareLoss>::GetGradient(xgboost::HostDeviceVector<float> const&, xgboost::MetaInfo const&, int, xgboost::HostDeviceVector<xgboost::detail::GradientPairInternal<float> >*) + 60
  [bt] (4) 5   xgboost.so                          0x00000001359610fc xgboost::Lea

Create a comparative AUC graph for the β€˜final’ model that includes WFNS, total blood volume and ventricular CSF volume in the prediction of mRS 180

legend("bottomright", title = "modified Rankin Scale", 
       legend = c("WFNS+Blood", "WFNS+VentricularCSF", "Final model", "WFNS+SSV_CSF", "WFNS+TotalCSF"), col = c("red", "black", "orange", "blue", "forestgreen"), 
       lwd = 2, "Legend", cex=0.8)
Error in (function (s, units = "user", cex = NULL, font = NULL, vfont = NULL,  : 
  plot.new has not been called yet

Stepwise regresssional analysis for the development of the multivariate model.

Variables: age, WFNS, TBV, SSV, Ventricular CSF, total CSF

summary(step.model)

Call:
glm(formula = mRS180 ~ WFNS + Total_blood + Ventricular_CSF, 
    family = binomial, data = data_imaging)

Coefficients:
                 Estimate Std. Error z value Pr(>|z|)    
(Intercept)     -4.688721   1.031167  -4.547 5.44e-06 ***
WFNS             0.535981   0.241497   2.219   0.0265 *  
Total_blood      0.030422   0.017492   1.739   0.0820 .  
Ventricular_CSF  0.012876   0.006733   1.912   0.0558 .  
---
Signif. codes:  0 β€˜***’ 0.001 β€˜**’ 0.01 β€˜*’ 0.05 β€˜.’ 0.1 β€˜ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 86.870  on 96  degrees of freedom
Residual deviance: 70.991  on 93  degrees of freedom
AIC: 78.991

Number of Fisher Scoring iterations: 5
LS0tCnRpdGxlOiAiU0FIIFNlZ21lbnRhdGlvbiBQcm9qZWN0IgphdXRob3I6ICJKYW1lcyBCb29rZXIiCmRhdGE6IDI2dGggQXByaWwgMjAyMwpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAogIGh0bWxfZG9jdW1lbnQ6CiAgICBkZl9wcmludDogcGFnZWQKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKLS0tCgpDYWxsIGluIHRoZSBTQUggc2VnbWVudGF0aW9uIGRhdGFzc2V0LiAKCmBgYHtyfQpsaWJyYXJ5KHJlYWR4bCkKU0FIX2ltYWdpbmdfZGF0YWJhc2UgPC0gcmVhZF9leGNlbCgifi9Eb2N1bWVudHMvSm9iL1Jlc2VhcmNoIC9CdWx0ZXJzIHJlc2VhcmNoL1NBSCBpbWFnaW5nIC9EYXRhL1NBSCBpbWFnaW5nIGRhdGFiYXNlLnhsc3giLCAKICAgIHNoZWV0ID0gIkNvbXBsZXRlIGRhdGFzZXQiKQpWaWV3KFNBSF9pbWFnaW5nX2RhdGFiYXNlKQoKZGF0YV9pbWFnaW5nIDwtIFNBSF9pbWFnaW5nX2RhdGFiYXNlCmBgYAoKQ29ob3J0IGNoYXJhY3RlcmlzdGljIGNhbGN1YXRpb25zLiAKCkZpcnN0bHksIGNhbGN1bGF0ZSB0aGUgbWVkaWFuIGFuZCBJUVIgZnJvbSBzeW1wdG9tIG9uc2V0IHRvIHNjYW4uIAoKYGBge3J9Cm5hLm9taXQoZGF0YV9pbWFnaW5nJFRpbWVfdW50aWxfc2Nhbl9taW4pCnN1bW1hcnkoZGF0YV9pbWFnaW5nJFRpbWVfdW50aWxfc2Nhbl9taW4pCjI3MS82MCAjTWVkaWFtCjEzMC82MCAjMXN0IHF1YXJ0aWxlIAo1NDcvNjAgIzNyZCBxdWFydGlsZQpgYGAKQmFzZWxpbmUgY2hhcmFjdGVyaXN0aWNzIHRhYmxlIApVbmtub3duIHJlcHJlc2VudHMgYW55IG1pc3NpbmcgZGF0YSAtIDIgcGF0aWVudHMgaW4gdGhlIGNvaG9ydCBkaWQgbm90IGhhdmUgYmxvb2Qgdm9sdW1lcyBjb2xsZWN0ZWQuICAKCmBgYHtyfQpsaWJyYXJ5KGd0c3VtbWFyeSkKdGhlbWVfZ3RzdW1tYXJ5X2NvbXBhY3QoKQpkYXRhX2ltYWdpbmcgJT4lIHNlbGVjdCgiQUdFIiwgIlNFWCIsICJIVE4iLCAiQU5FVUxPQyIsICJTVVJHUFJPQyIsICJUaW1lX3VudGlsX3NjYW5fbWluIiwgIkZJU0hHUkROIiwgIlNFQkVTIiwgIlRvdGFsIGJsb29kIiwgIlNTViBibG9vZCIsICJOb24tU1NWIGJsb29kIiwgIlRvdGFsIG1hbnVhbCB2b2x1bWUiLCAiU1NWIFZvbHVtZSIsICJWZW50cmljdWxhciB2b2x1bWUiLCAiQmVsb3cgU1NWIFZvbHVtZSIsICJXRk5TR1JETiIpICU+JSB0Ymxfc3VtbWFyeSgpCmBgYAoKQmxvb2QgZGlzdHJpYnV0aW9ucyB0byBjaGVjayBmb3IgdGhlIG5vcm1hbGl0eSBhbmQgc2VlIGlmIHRyYW5zZm9ybWF0aW9ucyBhcmUgcmVxdWlyZWQuCgpgYGB7cn0KI0Jsb29kIHZhcmlhYmxlczogVG90YWwgQmxvb2QsIFNTViBCbG9vZCBhbmQgTm9uLVNTViBCbG9vZAoKVG90YWxfYmxvb2QgPC0gU0FIX2ltYWdpbmdfZGF0YWJhc2UkYFRvdGFsIGJsb29kYApTU1ZfQmxvb2QgPC0gU0FIX2ltYWdpbmdfZGF0YWJhc2UkYFNTViBibG9vZGAKTm9uX1NTVl9CbG9vZCA8LSBTQUhfaW1hZ2luZ19kYXRhYmFzZSRgTm9uLVNTViBibG9vZGAKCmhpc3QoVG90YWxfYmxvb2QpCmhpc3QoU1NWX0Jsb29kKQpoaXN0KE5vbl9TU1ZfQmxvb2QpCgpsaWJyYXJ5KG1vbWVudHMpCmRfdG90YWxfYmxvb2QgPC0gZGVuc2l0eShUb3RhbF9ibG9vZCkjIHJldHVybnMgdGhlIGRlbnNpdHkgZGF0YQpza2V3bmVzcyhUb3RhbF9ibG9vZCwgbmEucm0gPSBUUlVFKSAjU2tld25lc3MKcGxvdChkX3RvdGFsX2Jsb29kLCBtYWluID0gIkRlbnNpdHkgcGxvdCBUb3RhbCBCbG9vZCBWb2x1bWUgKG1scykiLCBzdWIgPSAiU2tld25lc3MgPSAwLjc3NyIpICMgcGxvdHMgdGhlIHJlc3VsdHMKCmRfU1NWX2Jsb29kIDwtIGRlbnNpdHkoU1NWX0Jsb29kLCBuYS5ybSA9IFRSVUUpIyByZXR1cm5zIHRoZSBkZW5zaXR5IGRhdGEKc2tld25lc3MoU1NWX0Jsb29kLCBuYS5ybSA9IFRSVUUpICNTa2V3bmVzcwpwbG90KGRfU1NWX2Jsb29kLCBtYWluID0gIkRlbnNpdHkgcGxvdCBTU1YgQmxvb2QgVm9sdW1lIChtbHMpIiwgc3ViID0gIlNrZXduZXNzID0gMy41MyIpICMgcGxvdHMgdGhlIHJlc3VsdHMKCmRfTm9uX1NTVl9ibG9vZCA8LSBkZW5zaXR5KE5vbl9TU1ZfQmxvb2QsIG5hLnJtID0gVFJVRSkjIHJldHVybnMgdGhlIGRlbnNpdHkgZGF0YQpza2V3bmVzcyhOb25fU1NWX0Jsb29kLCBuYS5ybSA9IFRSVUUpICNTa2V3bmVzcwpwbG90KGRfTm9uX1NTVl9ibG9vZCwgbWFpbiA9ICJEZW5zaXR5IHBsb3QgTm9uLVNTViBCbG9vZCBWb2x1bWUgKG1scykiLCBzdWIgPSAiU2tld25lc3MgPSAwLjcyOSIpICMgcGxvdHMgdGhlIHJlc3VsdHMKCgpgYGAKQ1NGIGRpc3RyaWJ1dGlvbnMgdG8gY2hlY2sgZm9yIHNrZXduZXNzIAoKYGBge3J9CgojQ1NGIHZhcmlhYmxlczogU0VCRVMsIFZlbnRyaWN1bGFyIHZvbHVtZSwgU1NWIHZvbHVtZSwgQmVsb3cgU1NWIFZvbHVtZQoKU0VCRVMgPC0gU0FIX2ltYWdpbmdfZGF0YWJhc2UkU0VCRVMKVmVudHJpY2xlX0NTRiA8LSBTQUhfaW1hZ2luZ19kYXRhYmFzZSRgVmVudHJpY3VsYXIgdm9sdW1lYApTU1ZfQ1NGIDwtIFNBSF9pbWFnaW5nX2RhdGFiYXNlJGBTU1YgVm9sdW1lYApCZWxvd19TU1ZfQ1NGIDwtIFNBSF9pbWFnaW5nX2RhdGFiYXNlJGBCZWxvdyBTU1YgVm9sdW1lYApUb3RhbF9DU0YgPC0gU0FIX2ltYWdpbmdfZGF0YWJhc2UkYFRvdGFsIG1hbnVhbCB2b2x1bWVgCgpoaXN0KFNFQkVTKQpoaXN0KFZlbnRyaWNsZV9DU0YpCmhpc3QoU1NWX0NTRikKaGlzdChCZWxvd19TU1ZfQ1NGKQpoaXN0KFRvdGFsX0NTRikKCmxpYnJhcnkobW9tZW50cykKZF9TRUJFUyA8LSBkZW5zaXR5KFNFQkVTKSMgcmV0dXJucyB0aGUgZGVuc2l0eSBkYXRhCnNrZXduZXNzKFNFQkVTLCBuYS5ybSA9IFRSVUUpICNTa2V3bmVzcwpwbG90KGRfU0VCRVMsIG1haW4gPSAiRGVuc2l0eSBwbG90IFNFQkVTIiwgc3ViID0gIlNrZXduZXNzID0gMS41NDIiKSAjIHBsb3RzIHRoZSByZXN1bHRzCgpkX1ZlbnRyaWNsZV9DU0YgPC0gZGVuc2l0eShWZW50cmljbGVfQ1NGLCBuYS5ybSA9IFRSVUUpIyByZXR1cm5zIHRoZSBkZW5zaXR5IGRhdGEKc2tld25lc3MoVmVudHJpY2xlX0NTRiwgbmEucm0gPSBUUlVFKSAjU2tld25lc3MKcGxvdChkX1ZlbnRyaWNsZV9DU0YsIG1haW4gPSAiRGVuc2l0eSBwbG90IFZlbnRyaWNsZSBDU0YgVm9sdW1lIChtbHMpIiwgc3ViID0gIlNrZXduZXNzID0gMS41OSIpICMgcGxvdHMgdGhlIHJlc3VsdHMKCmRfU1NWX0NTRiA8LSBkZW5zaXR5KFNTVl9DU0YsIG5hLnJtID0gVFJVRSkjIHJldHVybnMgdGhlIGRlbnNpdHkgZGF0YQpza2V3bmVzcyhTU1ZfQ1NGLCBuYS5ybSA9IFRSVUUpICNTa2V3bmVzcwpwbG90KGRfU1NWX0NTRiwgbWFpbiA9ICJEZW5zaXR5IHBsb3QgU1NWIENTRiBWb2x1bWUgKG1scykiLCBzdWIgPSAiU2tld25lc3MgPSAxLjQzIikgIyBwbG90cyB0aGUgcmVzdWx0cwoKZF9CZWxvd19TU1ZfQ1NGIDwtIGRlbnNpdHkoQmVsb3dfU1NWX0NTRiwgbmEucm0gPSBUUlVFKSMgcmV0dXJucyB0aGUgZGVuc2l0eSBkYXRhCnNrZXduZXNzKEJlbG93X1NTVl9DU0YsIG5hLnJtID0gVFJVRSkgI1NrZXduZXNzCnBsb3QoZF9CZWxvd19TU1ZfQ1NGLCBtYWluID0gIkRlbnNpdHkgcGxvdCBCZWxvdyBTU1YgQ1NGIFZvbHVtZSAobWxzKSIsIHN1YiA9ICJTa2V3bmVzcyA9IDAuODI5IikgIyBwbG90cyB0aGUgcmVzdWx0cwoKZF9Ub3RhbF9DU0YgPC0gZGVuc2l0eShUb3RhbF9DU0YsIG5hLnJtID0gVFJVRSkjIHJldHVybnMgdGhlIGRlbnNpdHkgZGF0YQpza2V3bmVzcyhUb3RhbF9DU0YsIG5hLnJtID0gVFJVRSkgI1NrZXduZXNzCnBsb3QoZF9Ub3RhbF9DU0YsIG1haW4gPSAiRGVuc2l0eSBwbG90IFRvdGFsIENTRiBWb2x1bWUgKG1scykiLCBzdWIgPSAiU2tld25lc3MgPSAwLjkiKSAjIHBsb3RzIHRoZSByZXN1bHRzCgpgYGAKCkRlY2lzaW9uIG1hZGUgbm90IHRvIHRyYW5zZm9ybSB0aGUgdmFyaWFibGVzIGJlY2F1c2UgdGhleSBhcmUgZ2VuZXJhbGx5IG5vcm1hbGx5IGRpc3RyaWJ1dGVkLCB3aXRoIHRoZSBleGNlcHRpb24gb2YgU1NWIGJsb29kIHdoaWNoIGlzIG5vdCBhIGNsaW5pY2FsbHkgaW1wb3J0YW50IHZhcmlhYmxlIGFueXdheS4gCgpUaGUgbmV4dCBzdGVwIGlzIHRvIGlkZW50aWZ5IHRocm91Z2ggY29ycmVsYXRpb24gbWF0cmljZXMsIGhvdyB0aGUgaW1hZ2luZyB2YXJpYWJsZXMgYXJlIHJlbGF0ZWQuLiAKCmBgYHtyfQoKI0ZvciB2aXN1YWxpc2F0aW9uIGVuc3VyZSB0aGF0IHRoZSB2YXJpYWJsZXMgaGF2ZSB0aGUgY29ycmVjdCBuYW1lcyAKClNBSF9pbWFnaW5nX2RhdGFiYXNlJEFnZSA8LSBTQUhfaW1hZ2luZ19kYXRhYmFzZSRBR0UKU0FIX2ltYWdpbmdfZGF0YWJhc2UkV0ZOUyA8LSBTQUhfaW1hZ2luZ19kYXRhYmFzZSRXRk5TR1JETgpTQUhfaW1hZ2luZ19kYXRhYmFzZSRUb3RhbF9DU0YgPC0gU0FIX2ltYWdpbmdfZGF0YWJhc2UkYFRvdGFsIG1hbnVhbCB2b2x1bWVgClNBSF9pbWFnaW5nX2RhdGFiYXNlJFZlbnRyaWN1bGFyX0NTRiA8LSBTQUhfaW1hZ2luZ19kYXRhYmFzZSRgVmVudHJpY3VsYXIgdm9sdW1lYApTQUhfaW1hZ2luZ19kYXRhYmFzZSRTU1ZfQ1NGIDwtIFNBSF9pbWFnaW5nX2RhdGFiYXNlJGBTU1YgVm9sdW1lYAoKZGF0YV9pbWFnaW5nX2NvcnJlbGF0aW9uIDwtIFNBSF9pbWFnaW5nX2RhdGFiYXNlWywgYygiQWdlIiwgIldGTlMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRvdGFsIGJsb29kIiwgIlNTVl9DU0YiLCAiVmVudHJpY3VsYXJfQ1NGIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUb3RhbF9DU0YiKV0KCmRhdGFfaW1hZ2luZ19jb3JyZWxhdGlvbiA8LSBuYS5vbWl0KGRhdGFfaW1hZ2luZ19jb3JyZWxhdGlvbikKCnJlbW92ZS5wYWNrYWdlcygnSG1pc2MnKQppbnN0YWxsLnBhY2thZ2VzKCJIbWlzYyIsIHJlcG9zPSJodHRwOi8vY3Jhbi5yc3R1ZGlvLmNvbS8iLCBkZXBlbmRlbmNpZXM9VFJVRSkKaW5zdGFsbC5wYWNrYWdlcygiY2hlY2ttYXRlIikKbGlicmFyeShIbWlzYykKCnJlczIgPC0gcmNvcnIoYXMubWF0cml4KGRhdGFfaW1hZ2luZ19jb3JyZWxhdGlvbiksIHR5cGUgPSAic3BlYXJtYW4iKQpyZXMyCgpyZXMyJHIKcmVzMiRQCgpmbGF0dGVuQ29yck1hdHJpeCA8LSBmdW5jdGlvbihjb3JtYXQsIHBtYXQpIHsgI2Zvcm1hdCBjb3JyZWxhdGlvbiBtYXRyaXggCiAgdXQgPC0gdXBwZXIudHJpKGNvcm1hdCkKICBkYXRhLmZyYW1lKAogICAgcm93ID0gcm93bmFtZXMoY29ybWF0KVtyb3coY29ybWF0KVt1dF1dLAogICAgY29sdW1uID0gcm93bmFtZXMoY29ybWF0KVtjb2woY29ybWF0KVt1dF1dLAogICAgY29yICA9KGNvcm1hdClbdXRdLAogICAgcCA9IHBtYXRbdXRdCiAgKQp9Cgpjb3JyZWxhdGlvbl9tYXRyaXggPC0gZmxhdHRlbkNvcnJNYXRyaXgocmVzMiRyLCByZXMyJFApCndyaXRlLmNzdihjb3JyZWxhdGlvbl9tYXRyaXgsICJDb3JyZWxhdGlvbl9tYXRyaXguY3N2Iiwgcm93Lm5hbWVzID0gRikgI2V4cG9ydCB0YWJsZSAKCgpsaWJyYXJ5KGNvcnJwbG90KSAjdmlzdWFsaXNlIHRoZSBjb3JyZWxhdGlvbiBtYXRyaXgKcmVzIDwtIGNvcihkYXRhX2ltYWdpbmdfY29ycmVsYXRpb24pCmNvcnJwbG90KHJlcywgdHlwZSA9ICJ1cHBlciIsIG9yZGVyID0gImhjbHVzdCIsIAogICAgICAgICB0bC5jb2wgPSAiYmxhY2siLCB0bC5zcnQgPSA0NSkKCgpjb3JycGxvdChyZXMyJHIsIHR5cGU9InVwcGVyIiwgb3JkZXI9ImhjbHVzdCIsICNpbnNpZ25pZmljYW50IGNvcnJlbGF0aW9ucyByZW1vdmVkCiAgICAgICAgIHAubWF0ID0gcmVzMiRQLCBzaWcubGV2ZWwgPSAwLjAxLCBpbnNpZyA9ICJibGFuayIpCgpgYGAKClVuaXZhcmlhdGUgYW5hbHlzaXMgb2YgdmFyaWFibGVzIAoKYGBge3J9CiNVbml2YXJpYXRlIGFuYWx5c2lzIGxvZ2lzdGljIHJlZ3Jlc3Npb24gCgpkYXRhX2ltYWdpbmcgPC0gU0FIX2ltYWdpbmdfZGF0YWJhc2UKCiMjbVJTIAoKbVJTNyA8LSBkYXRhX2ltYWdpbmckTVJTN19kaWNoCm1SU2RpcyA8LSBkYXRhX2ltYWdpbmckTVJTRElTX2RpY2gKbVJTMjggPC0gZGF0YV9pbWFnaW5nJE1SUzI4X2RpY2gKbVJTOTAgPC0gZGF0YV9pbWFnaW5nJE1SUzkwX2RpY2gKbVJTMTgwIDwtIGRhdGFfaW1hZ2luZyRNUlMxODBfZGljaAoKbGlicmFyeSh0aWR5dmVyc2UpCm1SUzI4IDwtIGFzLmZhY3RvcihyZWNvZGUobVJTMjgsICIwIj0iR29vZCBvdXRjb21lIiwgIjEiID0gIkJhZCBvdXRjb21lIikpCmNvbnRyYXN0cyhhcy5mYWN0b3IobVJTMjgpKQptUlMyOCA8LSBmYWN0b3IobVJTMjgsIGxldmVscyA9IGMoIkdvb2Qgb3V0Y29tZSIsICJCYWQgb3V0Y29tZSIpKQpjb250cmFzdHMoYXMuZmFjdG9yKG1SUzI4KSkKCgpVbml2YXJpYXRlIDwtIGdsbShtUlMxODAgfiBkYXRhX2ltYWdpbmckVG90YWxfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoVW5pdmFyaWF0ZSkKZXhwKGNiaW5kKGNvZWYoVW5pdmFyaWF0ZSksIGNvbmZpbnQoVW5pdmFyaWF0ZSkpKSAgCgojI0dPU0UgCmRhdGFfaW1hZ2luZyA8LSBTQUhfaW1hZ2luZ19kYXRhYmFzZQpkYXRhX2ltYWdpbmcgPC0gZGF0YV9pbWFnaW5nW2NvbXBsZXRlLmNhc2VzKGRhdGFfaW1hZ2luZyRHT1NFMjhfZGljaCksXQpTU1YgPC0gZGF0YV9pbWFnaW5nCmRhdGFfaW1hZ2luZyRTU1ZfZ2NlIDwtIHJlYyhTU1YsIHJlYyA9ICJtaW46MC44NT0xOyAwLjk6bWF4PTAiKSAjU3BsaXQgU1NWIGF0IDAuODUgbWwKU1NWX2djZSA8LSBkYXRhX2ltYWdpbmckU1NWX2djZQpTU1ZfZ2NlIDwtIGFzLmZhY3RvcihyZWNvZGUoU1NWX2djZSwgIjAiPSJObyIsICIxIiA9ICJZZXMiKSkKdGFibGUoU1NWX2djZSkKCkdPU0UyOF9kaWNoIDwtIGRhdGFfaW1hZ2luZyRHT1NFMjhfZGljaApHT1NFOTBfZGljaCA8LSBkYXRhX2ltYWdpbmckR09TRTkwX2RpY2gKR09TRTE4MF9kaWNoIDwtIGRhdGFfaW1hZ2luZyRHT1NFMTgwX2RpY2gKClVuaXZhcmlhdGUgPC0gZ2xtKGRhdGFfaW1hZ2luZyRHT1NFMTgwX2RpY2ggfiBkYXRhX2ltYWdpbmckYFRvdGFsIGJsb29kYCwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoVW5pdmFyaWF0ZSkKCiMjU0FIT1QgCmRhdGFfaW1hZ2luZyA8LSBkYXRhX2ltYWdpbmdbY29tcGxldGUuY2FzZXMoZGF0YV9pbWFnaW5nJFNBSE9UMjhfZGljaCksXQoKU0FIT1QyOF9kaWNoIDwtIGRhdGFfaW1hZ2luZyRTQUhPVDI4X2RpY2gKU0FIT1Q5MF9kaWNoIDwtIGRhdGFfaW1hZ2luZyRTQUhPVDkwX2RpY2gKU0FIT1QxODBfZGljaCA8LSBkYXRhX2ltYWdpbmckU0FIT1QxODBfZGljaAoKVW5pdmFyaWF0ZSA8LSBnbG0oZGF0YV9pbWFnaW5nJFNBSE9UMTgwX2RpY2ggfiBkYXRhX2ltYWdpbmckVG90YWxfQ1NGICwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoVW5pdmFyaWF0ZSkKCmBgYAoKRG9taW5hbmNlIHBsb3RzIAoKVG8gcHJldmVudCBvdmVyZml0dGluZyBvZiBmdXJ0aGVyIHByZWRpY3RpdmUgbW9kZWxzLCBhIGRvbWluYW5jZSBhbmFseXNpcyB3YXMgZG9uZSBieSBhc3Nlc3NpbmcgZWFjaCB2YXJpYWJsZeKAmXMgUjIgd2hlbiBwcmVkaWN0aW5nIG1SUyBhdCBkYXkgMjggYW5kIGRheSAxODAuIFRoZSBtUlMgYXQgZGF5IDI4IGFuZCBkYXkgMTgwIHdlcmUgdXNlZCBiZWNhdXNlIG1SUyBpcyB1c2VkIG1vc3Qgd2lkZWx5IGluIGNsaW5pY2FsIHByYWN0aWNlIHRvIGFzc2VzcyBmdW5jdGlvbmFsIG91dGNvbWUuIERheSAyOCB3YXMgc2VsZWN0ZWQgdG8gcmVmbGVjdCBzaG9ydCB0ZXJtIGFuZCBkYXkgMTgwIGxvbmctdGVybSBvdXRjb21lLiBJbiBhZGRpdGlvbiwgdG8gZGVtb25zdHJhdGUgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBhIGdlbmVyYWwgc2NhbGUgb2YgZnVuY3Rpb25hbCBvdXRjb21lIGZvciBzdHJva2UgYW5kIGEgcGF0aWVudCByZXBvcnRlZCBTQUggc3BlY2lmaWMgc2NhbGUgb2Ygc3ltcHRvbXMgd2UgdW5kZXJ0b29rIGEgZG9taW5hbmNlIGFuYWx5c2lzIG9mIFNBSE9UIG9uIGRheSAxODAuCgpgYGB7cn0KCiNSZWNvZGUgdmFyaWFibGVzCgpBZ2UgPC0gZGF0YV9pbWFnaW5nJEFHRQpIeXBlcnRlbnNpb24gPC0gZGF0YV9pbWFnaW5nJEhUTgpXRk5TIDwtIGRhdGFfaW1hZ2luZyRXRk5TR1JETgpUb3RhbF9ibG9vZF92b2x1bWUgPC0gZGF0YV9pbWFnaW5nJGBUb3RhbCBibG9vZGAKU1NWX0NTRiA8LSBkYXRhX2ltYWdpbmckYFNTViBWb2x1bWVgClZlbnRyaWN1bGFyX0NTRiA8LSBkYXRhX2ltYWdpbmckYFZlbnRyaWN1bGFyIHZvbHVtZWAKCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMyOCkgfiBBZ2UrV0ZOUysKICAgICAgICAgICAgICAgICAgICAgIFRvdGFsX2Jsb29kX3ZvbHVtZStTU1ZfQ1NGK1ZlbnRyaWN1bGFyX0NTRiwgCiAgICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQpjb2VmKE11bHRpdmFyaWF0ZSkKCmFub3ZhKE11bHRpdmFyaWF0ZSwgdGVzdCA9ICJDaGlzcSIpCgpsaWJyYXJ5KHBzY2wpCgpwUjIoTXVsdGl2YXJpYXRlKQoKYXYgPC0gYXZhaWxhYmxlLnBhY2thZ2VzKGZpbHRlcnM9bGlzdCgpKQphdlthdlssICJQYWNrYWdlIl0gPT0gZG9taW5hbmNlYW5hbHlzaXMsIF0KCmluc3RhbGwucGFja2FnZXMoJ2RvbWluYW5jZWFuYWx5c2lzJykKbGlicmFyeShkb21pbmFuY2VhbmFseXNpcykKCmRhLmdsbS5maXQoKSgibmFtZXMiKQoKZGFwcmVzPC1kb21pbmFuY2VBbmFseXNpcyhNdWx0aXZhcmlhdGUpCgpnZXRGaXRzKGRhcHJlcywicjIubSIpCgpkb21pbmFuY2VNYXRyaXgoZGFwcmVzLCB0eXBlPSJjb21wbGV0ZSIsZml0LmZ1bmN0aW9ucyA9ICJyMi5tIiwgb3JkZXJlZD1UUlVFKSAjY29tcGxldGUgZG9taW5hbmNlID0gMSwgY29tcGxldGUgZG9taW5hbmNlIG5vdCBlc3RhYmxpc2hlZCA9IDAuNQoKY29udHJpYnV0aW9uQnlMZXZlbChkYXByZXMsZml0LmZ1bmN0aW9ucz0icjIubSIpCgpsaWJyYXJ5KHJlc2hhcGUyKQoKcGxvdChkYXByZXMsIHdoaWNoLmdyYXBoID0iY29uZGl0aW9uYWwiLGZpdC5mdW5jdGlvbiA9ICJyMi5tIikgI0NvbmRpdGlvbmFsIGRvbWluYW5jZSBwbG90IAoKZG9taW5hbmNlTWF0cml4KGRhcHJlcywgdHlwZT0iY29uZGl0aW9uYWwiLGZpdC5mdW5jdGlvbnMgPSAicjIubSIsIG9yZGVyZWQ9VFJVRSkKCmF2ZXJhZ2VDb250cmlidXRpb24oZGFwcmVzLGZpdC5mdW5jdGlvbnMgPSAicjIubSIpCgpwbG90KGRhcHJlcywgd2hpY2guZ3JhcGggPSJnZW5lcmFsIixmaXQuZnVuY3Rpb24gPSAicjIubSIpICNHZW5lcmFsIGRvbWluYW5jZSBwbG90Cgpib290bW9kcHJlczEwMCA8LSBib290RG9taW5hbmNlQW5hbHlzaXMoTXVsdGl2YXJpYXRlLCBSPTEwMCkgIyBCb290c3RyYXAgYW5hbHlzaXMgZm9yIGRvbWluYW5jZSBhbmFseXNpcyAKc3VtbWFyeShib290bW9kcHJlczEwMCxmaXQuZnVuY3Rpb25zPSJyMi5tIikKCmJvb3RhdmVtb2RwcmVzMTAwPC1ib290QXZlcmFnZURvbWluYW5jZUFuYWx5c2lzKE11bHRpdmFyaWF0ZSxSPTEwMCkgIyBCb290c3RyYXAgYW5hbHlzaXMgZm9yIGdlbmVyYWwgZG9taW5hbmNlIGFuYWx5c2lzIApzdW1tYXJ5KGJvb3RhdmVtb2RwcmVzMTAwLGZpdC5mdW5jdGlvbnM9YygicjIubSIpKQoKYGBgCk11bHRpdmFyaWF0ZSBhbmFseXNpcyAKCkluIG9yZGVyIHRvIGludmVzdGlnYXRlIHRoZSBhZGRpdGlvbmFsIGJlbmVmaXQgb2YgYmxvb2QgYW5kIENTRiB2b2x1bWUgbWVhc3VyZW1lbnRzIGluIG1vZGVscyBvdmVyIGNvbnZlbnRpb25hbCBjbGluaWNhbCBmZWF0dXJlcyBhbG9uZSBtdWx0aXZhcmlhdGUgbW9kZWxzIHdlcmUgYnVpbHQgdXNpbmcgdGhlIHByZXZpb3VzbHkgcmVwb3J0ZWQgU0FISVQgY29yZSB2YXJpYWJsZXMgdG8gcHJlZGljdCBtUlMgYXQgZGF5IDI4IGFuZCAxODAgYW5kIHJlcGVhdGVkIGFkZGluZyB0b3RhbCBibG9vZCB2b2x1bWUsIFNTViBDU0YsIHZlbnRyaWN1bGFyIENTRi4KCkNvcmUgbW9kZWw9IEFnZSwgSHlwZXJ0ZW5zaW9uIGFuZCBBZG1pc3Npb24gV0ZOUyAKTmV1cm9pbWFnaW5nIG1vZGVsPSBDb3JlIG1vZGVsICsgVG90YWwgQmxvb2Qgdm9sdW1lLCBTU1YgQ1NGIGFuZCBWZW50cmljdWxhciBDU0YgCgpGb3IgdW5rbm93biByZWFzb25zIHRoZSBiZWxvdyBjb2RlIGRpZCBub3Qgd29yayBhbmQgdGhlcmVmb3JlLCBJIGNyZWF0ZWQgdGhlIEFVQyBncmFwaHMgYnkgYWRhcHRpbmcgbXkgcHJldmlvdXMgYW5hbHlzZWQgY29kZS4gCgpgYGB7cn0KI0NvcmUgbW9kZWwgCgphZ2UgPC0gZGF0YV9pbWFnaW5nJEFHRSAKSFROIDwtIGRhdGFfaW1hZ2luZyRIVE4KV0ZOUyA8LSBkYXRhX2ltYWdpbmckV0ZOU0dSRE4KCiMjIG1SUwoKCm1SUzI4IDwtIGFzLmZhY3RvcihyZWNvZGUobVJTMjgsICIwIj0iR29vZCBvdXRjb21lIiwgIjEiID0gIkJhZCBvdXRjb21lIikpCmNvbnRyYXN0cyhhcy5mYWN0b3IobVJTMjgpKQptUlMyOCA8LSBmYWN0b3IobVJTMjgsIGxldmVscyA9IGMoIkdvb2Qgb3V0Y29tZSIsICJCYWQgb3V0Y29tZSIpKQpjb250cmFzdHMoYXMuZmFjdG9yKG1SUzI4KSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0obVJTMTgwIH4gYWdlK0hUTitXRk5TLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCmNvZWYoTXVsdGl2YXJpYXRlKQoKIyMjIE1jRmFkZGVuJ3MgUHNldWRvIFIyIAoKbGwubnVsbCA8LSBNdWx0aXZhcmlhdGUkbnVsbC5kZXZpYW5jZS8tMgpsbC5wcm9wb3NlZCA8LSBNdWx0aXZhcmlhdGUkZGV2aWFuY2UvLTIKKGxsLm51bGwgLSBsbC5wcm9wb3NlZCkvbGwubnVsbAoxIC0gcGNoaXNxKDIqKGxsLnByb3Bvc2VkIC0gbGwubnVsbCksIGRmID0gbGVuZ3RoKE11bHRpdmFyaWF0ZSRjb2VmZmljaWVudHMpLTEpCgojIyBBVUMgCgpsaWJyYXJ5KFJPQ1IpCmxpYnJhcnkocFJPQykKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKG1SUzE4MCkgfiBhZ2UrSFROK1dGTlMsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCnJvYzEgPC0gcm9jKG1SUzE4MCwgTXVsdGl2YXJpYXRlJGZpdHRlZC52YWx1ZXMsIHBsb3QgPSBUUlVFKQpyb2MxCmNpKHJvYzEpCnBhcihwdHkgPSAicyIpCgpyb2MobVJTMjgsIE11bHRpdmFyaWF0ZSRmaXR0ZWQudmFsdWVzLCBwbG90ID0gVFJVRSwgbGVnYWN5LmF4ZXMgPSBUUlVFLCBwZXJjZW50ID0gVFJVRSwKICAgIHhsYWI9ICJGYWxzZSBQb3NpdGl2ZSBQZXJjZW50YWdlIiwgeWxhYiA9ICJUcnVlIFBvc2l0aXZlIFBlcmNlbnRhZ2UiLCBjb2wgPSAiYmxhY2siLCBsd2QgPSAyLCBwcmludC5hdWMgPSA2MCkKbGVnZW5kKCJib3R0b21yaWdodCIsIGxlZ2VuZCA9IGMoIm1SUyBkYXkgMTgwIiksIGNvbCA9IGMoImJsYWNrIiksIGx3ZCA9IDQpCgpjaShyb2MxKQoKIyBOZXVyb2ltYWdpbmcgbW9kZWwgCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKG1SUzE4MCB+IGFnZStIVE4rV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrU1NWX0NTRitWZW50cmljdWxhcl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKY29lZihNdWx0aXZhcmlhdGUpCgojIyMgTWNGYWRkZW4ncyBQc2V1ZG8gUjIgCgpsbC5udWxsIDwtIE11bHRpdmFyaWF0ZSRudWxsLmRldmlhbmNlLy0yCmxsLnByb3Bvc2VkIDwtIE11bHRpdmFyaWF0ZSRkZXZpYW5jZS8tMgoobGwubnVsbCAtIGxsLnByb3Bvc2VkKS9sbC5udWxsCjEgLSBwY2hpc3EoMioobGwucHJvcG9zZWQgLSBsbC5udWxsKSwgZGYgPSBsZW5ndGgoTXVsdGl2YXJpYXRlJGNvZWZmaWNpZW50cyktMSkKCiMjIEFVQyAKCmxpYnJhcnkoUk9DUikKbGlicmFyeShwUk9DKQoKCnBsb3QoeCA9IFdGTlMsIHkgPSBtUlMxODApCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKG1SUzE4MCkgfiBhZ2UrSFROK1dGTlMsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCnJvYzEgPC0gcm9jKG1SUzE4MCwgTXVsdGl2YXJpYXRlJGZpdHRlZC52YWx1ZXMsIHBsb3QgPSBUUlVFKQpyb2MxCmNpKHJvYzEpCnBhcihwdHkgPSAicyIpCgpyb2MobVJTMTgwLCBNdWx0aXZhcmlhdGUkZml0dGVkLnZhbHVlcywgcGxvdCA9IFRSVUUsIGxlZ2FjeS5heGVzID0gVFJVRSwgcGVyY2VudCA9IFRSVUUsCiAgICB4bGFiPSAiRmFsc2UgUG9zaXRpdmUgUGVyY2VudGFnZSIsIHlsYWIgPSAiVHJ1ZSBQb3NpdGl2ZSBQZXJjZW50YWdlIiwgY29sID0gImJsYWNrIiwgbHdkID0gMiwgcHJpbnQuYXVjID0gNjApCmxlZ2VuZCgiYm90dG9tcmlnaHQiLCBsZWdlbmQgPSBjKCJtUlMgZGF5IDE4MCIpLCBjb2wgPSBjKCJibGFjayIpLCBsd2QgPSA0KQoKY2kocm9jMSkKCiMgT3ZlcmxhcCBBVUMgCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMyOCkgfiBhZ2UrSFROK1dGTlMrVG90YWxfYmxvb2Rfdm9sdW1lK1NTVl9DU0YrVmVudHJpY3VsYXJfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgpyb2MobVJTMjgsIE11bHRpdmFyaWF0ZSRmaXR0ZWQudmFsdWVzLCBwbG90ID0gVFJVRSwgbGVnYWN5LmF4ZXMgPSBUUlVFLCBwZXJjZW50ID0gVFJVRSwKICAgIHhsYWI9ICJGYWxzZSBQb3NpdGl2ZSBQZXJjZW50YWdlIiwgeWxhYiA9ICJUcnVlIFBvc2l0aXZlIFBlcmNlbnRhZ2UiLCBjb2wgPSAiYmxhY2siLCBsd2QgPSAyLCBwcmludC5hdWMgPSA2MCkKcGFyKHB0eSA9ICJzIikKTXVsdGl2YXJpYXRlMiA8LSBnbG0oYXMuZmFjdG9yKG1SUzI4KSB+IGFnZStIVE4rV0ZOUywgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCk11bHRpdmFyaWF0ZTMgPC0gZ2xtKGFzLmZhY3RvcihtUlMxODApIH4gYWdlK0hUTitXRk5TLCBUb3RhbF9ibG9vZF92b2x1bWUrU1NWX0NTRitWZW50cmljdWxhcl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpNdWx0aXZhcmlhdGU0IDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IGFnZStIVE4rV0ZOUywgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCgpyb2MobVJTMjgsIE11bHRpdmFyaWF0ZSRmaXR0ZWQudmFsdWVzLCBwbG90ID0gVFJVRSwgbGVnYWN5LmF4ZXMgPSBUUlVFLCBwZXJjZW50ID0gVFJVRSwKICAgIHhsYWI9ICJGYWxzZSBQb3NpdGl2ZSBQZXJjZW50YWdlIiwgeWxhYiA9ICJUcnVlIFBvc2l0aXZlIFBlcmNlbnRhZ2UiLCBjb2wgPSAib3JhbmdlIiwgbHdkID0gMSwgcHJpbnQuYXVjID0gVFJVRSwgcHJpbnQuYXVjLnkgPSA3MCwgcHJpbnQuYXVjLnggPSA0MCkKcGxvdC5yb2MobVJTMjgsIE11bHRpdmFyaWF0ZTIkZml0dGVkLnZhbHVlcywgcGVyY2VudCA9IFRSVUUsIGNvbCA9ICJyZWQiLCBsd2QgPSAxLCBhZGQgPSBUUlVFLCBwcmludC5hdWMgPSBUUlVFLCBwcmludC5hdWMueSA9IDkwLCBwcmludC5hdWMueCA9IDQwKQpwbG90LnJvYyhtUlMxODAsIE11bHRpdmFyaWF0ZTMkZml0dGVkLnZhbHVlcywgcGVyY2VudCA9IFRSVUUsIGNvbCA9ICJibHVlIiwgbHdkID0gMSwgYWRkID0gVFJVRSwgcHJpbnQuYXVjID0gVFJVRSwgcHJpbnQuYXVjLnkgPSA2MCwgcHJpbnQuYXVjLnggPSA0MCkKcGxvdC5yb2MobVJTMTgwLCBNdWx0aXZhcmlhdGU0JGZpdHRlZC52YWx1ZXMsIHBlcmNlbnQgPSBUUlVFLCBjb2wgPSAiYmxhY2siLCBsd2QgPSAxLCBhZGQgPSBUUlVFLCBwcmludC5hdWMgPSBUUlVFLCBwcmludC5hdWMueSA9IDgwLCBwcmludC5hdWMueCA9IDQwKQoKbGVnZW5kKCJib3R0b21yaWdodCIsIHRpdGxlID0gIm1vZGlmaWVkIFJhbmtpbiBTY2FsZSIsIAogICAgICAgbGVnZW5kID0gYygiTmV1cm9pbWFnaW5nIERheSAyOCIsICJOZXVyb2ltYWdpbmcgRGF5IDE4MCIsICJDbGluaWNhbCBEYXkgMjgiLCAiQ2xpbmljYWwgRGF5IDE4MCIpLCBjb2wgPSBjKCJyZWQiLCAiYmxhY2siLCAib3JhbmdlIiwgImJsdWUiKSwgCiAgICAgICBsd2QgPSAyLCAiTGVnZW5kIiwgY2V4PTAuOCkKYGBgCgpgYGB7cn0KIyBFeHBsb3JlIHRoZSBpbnRlcmFjdGlvbiBiZXR3ZWVuIGFnZSwgQ1NGIGFuZCBibG9vZCB2b2x1bWUgCmRhdGFfaW1hZ2luZyA8LSBTQUhfaW1hZ2luZ19kYXRhYmFzZQoKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKG1SUzE4MCkgfiBWZW50cmljdWxhcl9DU0YgKiBUb3RhbF9ibG9vZCAqIGFnZSwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQpjb2VmKE11bHRpdmFyaWF0ZSkKCiNQbG90cwoKbGlicmFyeShzalBsb3QpCmxpYnJhcnkoc2ptaXNjKQpsaWJyYXJ5KGdncGxvdDIpCnRoZW1lX3NldCh0aGVtZV9zanBsb3QoKSkKCmludGVyYWN0aW9uX21vZGVsIDwtICBwbG90X21vZGVsKE11bHRpdmFyaWF0ZSwgdHlwZSA9ICJwcmVkIiwgCiAgICAgICAgICAgYXhpcy50aXRsZSA9IGMoIlZlbnRyaWN1bGFyIENTRiBWb2x1bWUgKG1scykiLCAiUHJvYmFiaWxpdHkgb2YgcG9vciBvdXRjb21lICglKSIpLCB0aXRsZSA9ICIiLCB0ZXJtcyA9IGMoIlZlbnRyaWN1bGFyX0NTRiIsICJUb3RhbF9ibG9vZCIsICJhZ2UgWzQwLDYwLDgwXSIpKQoKaW50ZXJhY3Rpb25fbW9kZWwgKyB4bGltKDAsMTAwKQoKIiIsIHRlcm1zID0gYygiVmVudHJpY3VsYXJfQ1NGIiwiVG90YWxfYmxvb2Rfdm9sdW1lIiwiYWdlIFs0MCw2MCw4MF0iKSkgCmBgYApTU1YgZGljaG90b21pc2F0aW9uIGZyb20gdGhlIGxpdGVyYXR1cmUgCgpDaG9pIGV0IGFsLjogU1NWIG5vdCBub3JtYWxseSBkaXN0cmlidXRlZCBhbmQgc3ViamVjdHMgc2VwYXJhdGVkIGludG8gZXF1YWwgcXVhcnRpbGVzIGZvciBtZWFzdXJpbmcgb2RkcyByYXRpb3MgaW4gZXhhbWluaW5nIGFzc29jaWF0aW9ucyB3aXRoIEdDRSBhcyB3ZWxsIGFzIGNsaW5pY2FsIG91dGNvbWVzLiBGSU5ESU5HUzogY29tcGFyZWQgdG8gcGF0aWVudHMgaW4gdGhlIGhpZ2hlc3QgcXVhcnRpbGUgZm9yIFNTViwgdGhlIE9SIGZvciBwb29yIG91dGNvbWUgYXQgZGlzY2hhcmdlIGluY3JlYXNlZCBpbiBhIGRvc2UgZGVwZW5kZW50IG1hbm5lciBpbiB0aGUgbG93ZXIgcXVhcnRpbGVzIGFmdGVyIGFkanVzdGluZyBmb3IgYWdlLCBzZXgsIHNtb2tpbmcgaHlwZXJ0ZW5zaW9uIGFuZCBISCBzY29yZQoKWXVhbiBldCBhbC46IFNTViB0YWtlbiBhcyBjb250aW51b3VzIHZhcmlhYmxlIGFuZCBpbiBzZW5zaXRpdml0eSBhbmFseXNpcyBkaWNob3RvbWlzYXRpb24gYXQgPDUuMm1sIHdhcyBkb25lLiBGSU5ESU5HUyBlYXJseSBTU1YgZGVmaW5lZCBhcyBsb3dlc3QgU1NWIHZvbHVtZSBpbiBmaXJzdCA3MmhycyBidXQgbm90IGFkbWlzc2lvbiBTU1Ygd2FzIHByZWRpY3RpdmUgb2Ygb3V0Y29tZQoKQ3JlYXRlIHR3byBuZXcgdmFyaWFibGVzLCBTU1ZfcXVhbnRpbGVzIGFuZCBTU1ZfZGljaCAKYGBge3J9CiNJZGVudGlmeSB0aGUgcXVhcnRpbGVzIGZvciBTU1YgCgpxdWFudGlsZShTU1ZfQ1NGKQpoaXN0KFNTVl9DU0YpCm1pbihTU1ZfQ1NGKQptYXgoU1NWX0NTRikKCiMgMTw9MjAuMjUwNzgxLCAyPjIwLjI1MDc4MSwgMjw9MzcuMDk4ODQ5LCAzPjM3LjA5ODg0OSwgMzw9NzUuMTI4MzAzLCA0Pjc1LjEyODMwMwoKZGF0YV9pbWFnaW5nJFNTVl9xdWFudGlsZXMgPC0gY3V0KGRhdGFfaW1hZ2luZyRgU1NWIFZvbHVtZWAsCiAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzPWMoMy40ODEwNzMsIDIwLjI1MDc4MSwgMzcuMDk4ODQ5LCA3NS4xMjgzMDMsIDIzNi43Mzg0MjYpLAogICAgICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCcxJywgJzInLCAnMycsICc0JykpCgpkYXRhX2ltYWdpbmckU1NWX3F1YW50aWxlcwpTU1ZfcXVhbnRpbGVzIDwtIGRhdGFfaW1hZ2luZyRTU1ZfcXVhbnRpbGVzCmNsYXNzKFNTVl9xdWFudGlsZXMpClNTVl9xdWFudGlsZXMgPC0gcmVsZXZlbChTU1ZfcXVhbnRpbGVzLCByZWYgPSAiNCIpClNTVl9xdWFudGlsZXMKCmdncGxvdChkYXRhID0gZGF0YV9pbWFnaW5nLCBtYXBwaW5nID0gYWVzKHggPSBTU1ZfcXVhbnRpbGVzKSkgKwogIGdlb21fYmFyKCkKCiNTcGxpdCBieSBkaWNob3RvbWlzYXRpb24gb2YgNS4ybWwgaW50byBoaWdoIGFuZCBsb3cgCgpkYXRhX2ltYWdpbmckU1NWX2RpY2hbZGF0YV9pbWFnaW5nJGBTU1YgVm9sdW1lYCA8IDUuMl0gPC0gImxvdyIKZGF0YV9pbWFnaW5nJFNTVl9kaWNoW2RhdGFfaW1hZ2luZyRgU1NWIFZvbHVtZWAgPiA1LjJdIDwtICJoaWdoIgoKZGF0YV9pbWFnaW5nJFNTVl9kaWNoClNTVl9kaWNoIDwtIGRhdGFfaW1hZ2luZyRTU1ZfZGljaAoKI05vdCBhIHN1aXRhYmxlIGN1dC1vZmYgaW4gdGhlIGRhdGFzZXQsIGluc3RlYWQgZGljaG90b21pc2UgYXQgbG93ZXIgcXVhbnRpbGUgCgpkYXRhX2ltYWdpbmckU1NWX2RpY2hbZGF0YV9pbWFnaW5nJGBTU1YgVm9sdW1lYCA8IDIwLjI1MDc4MV0gPC0gImxvdyIKZGF0YV9pbWFnaW5nJFNTVl9kaWNoW2RhdGFfaW1hZ2luZyRgU1NWIFZvbHVtZWAgPiAyMC4yNTA3ODFdIDwtICJoaWdoIgoKZGF0YV9pbWFnaW5nJFNTVl9kaWNoCgoKZ2dwbG90KGRhdGEgPSBkYXRhX2ltYWdpbmcsIG1hcHBpbmcgPSBhZXMoeCA9IFNTVl9kaWNoKSkgKwogIGdlb21fYmFyKCkKCmBgYApDdXJyZW50bHkgaGF2ZSBzZXZlcmFsIENTRiB2b2x1bWVzIGluY2x1ZGluZyAtIHRvdGFsIENTRiwgU1NWIENTRiwgdmVudHJpY3VsYXIgQ1NGIGFuZCBiZWxvdyBTU1YgQ1NGLiBIb3dldmVyLCBvbmUgdm9sdW1lIHRoYXQgaXMgbWlzc2luZywgaXMgYSBub24tU1NWLCBub24tdmVudHJpY3VsYXIgQ1NGLiAKCkNyZWF0ZSBub25fU1NWX25vbl92ZW50X0NTRiB2YXJpYWJsZSAKCmBgYHtyfQoKbXV0YXRlKGRhdGFfaW1hZ2luZywgbm9uX1NTVl9ub25fdmVudCA9IEJlbG93X1NTVl9DU0YgLSBWZW50cmljdWxhcl9DU0YpCgpkYXRhX2ltYWdpbmckbm9uX1NTVl9ub25fdmVudF9DU0YgPC0gQmVsb3dfU1NWX0NTRiAtIFZlbnRyaWN1bGFyX0NTRgoKZGF0YV9pbWFnaW5nJG5vbl9TU1Zfbm9uX3ZlbnRfQ1NGCm5vbl9TU1Zfbm9uX3ZlbnRfQ1NGICA8LSBkYXRhX2ltYWdpbmckbm9uX1NTVl9ub25fdmVudF9DU0YKCm5vbl9TU1Zfbm9uX3ZlbnRfQ1NGICA8LSBub25fU1NWX25vbl92ZW50X0NTRiBbbm9uX1NTVl9ub25fdmVudF9DU0YgID49IDBdCgpoaXN0KG5vbl9TU1Zfbm9uX3ZlbnRfQ1NGKQoKI1VuaXZhcmF0ZSBub24tc3N2IG5vbi12ZW50cmljdWxhciBDU0YKClVuaXZhcmlhdGUgPC0gZ2xtKFNBSE9UMTgwX2RpY2ggfiBub25fU1NWX25vbl92ZW50X0NTRiwgZmFtaWx5ID0gYmlub21pYWwsICBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KFVuaXZhcmlhdGUpCgpgYGAKQmVmb3JlIG11bHRpdmFyaWF0ZSBhbmFseXNpcywgbGV0J3Mgc2VlIGlmIHRoZSBuZXcgU1NWIGN1dC1vZmZzIG1ha2UgaXQgYSBzaWduaWZpY2FudCBwcmVkaWN0b3Igb2YgZGF5IDMwIGFuZCAxODAgb3V0Y29tZSBpbiBhIHVuaXZhcmlhdGUgYW5hbHlzaXMgCgoKYGBge3J9CiNQcmVwYXJlIG91dGNvbWUgdmFyaWFibGVzIAptUlM3IDwtIGRhdGFfaW1hZ2luZyRNUlM3X2RpY2gKbVJTZGlzIDwtIGRhdGFfaW1hZ2luZyRNUlNESVNfZGljaAptUlMyOCA8LSBkYXRhX2ltYWdpbmckTVJTMjhfZGljaAptUlM5MCA8LSBkYXRhX2ltYWdpbmckTVJTOTBfZGljaAptUlMxODAgPC0gZGF0YV9pbWFnaW5nJE1SUzE4MF9kaWNoCgpsaWJyYXJ5KHRpZHl2ZXJzZSkKbVJTNyA8LSBhcy5mYWN0b3IocmVjb2RlKG1SUzcsICIwIj0iR29vZCBvdXRjb21lIiwgIjEiID0gIkJhZCBvdXRjb21lIikpCmNvbnRyYXN0cyhhcy5mYWN0b3IobVJTNykpCm1SUzcgPC0gZmFjdG9yKG1SUzcsIGxldmVscyA9IGMoIkdvb2Qgb3V0Y29tZSIsICJCYWQgb3V0Y29tZSIpKQpjb250cmFzdHMoYXMuZmFjdG9yKG1SUzcpKQoKU0FIT1QyOF9kaWNoIDwtIGRhdGFfaW1hZ2luZyRTQUhPVDI4X2RpY2gKU0FIT1Q5MF9kaWNoIDwtIGRhdGFfaW1hZ2luZyRTQUhPVDkwX2RpY2gKU0FIT1QxODBfZGljaCA8LSBkYXRhX2ltYWdpbmckU0FIT1QxODBfZGljaAoKI1NTVl9xdWFudGlsZSB0aGUgQ2hvaSBldCBhbC4gY3V0LW9mZgoKI0NoYW5nZSB0aGUgbGV2ZWxzIG9mIFNTViBxdWFudGlsZXMKClNTVl9xdWFudGlsZXMKU1NWX3F1YW50aWxlc19tb2QgPC0gZmFjdG9yKFNTVl9xdWFudGlsZXMsIGxldmVscyA9IGMoIjQiLCAiMyIsICIyIiwgIjEiKSkKU1NWX3F1YW50aWxlc19tb2QKClVuaXZhcmlhdGUgPC0gZ2xtKFNBSE9UMTgwX2RpY2ggfiBTU1ZfZGljaCwgZmFtaWx5ID0gYmlub21pYWwsICBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KFVuaXZhcmlhdGUpCmV4cChjYmluZChjb2VmKFVuaXZhcmlhdGUpLCBjb25maW50KFVuaXZhcmlhdGUpKSkgIAo/Z2xtCgpVbml2YXJpYXRlIDwtIGdsbShtUlMxODAgfiBkYXRhX2ltYWdpbmckU1NWX3F1YW50aWxlcywgZmFtaWx5ID0gYmlub21pYWwsICBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KFVuaXZhcmlhdGUpCmV4cChjYmluZChjb2VmKFVuaXZhcmlhdGUpLCBjb25maW50KFVuaXZhcmlhdGUpKSkgIAoKVW5pdmFyaWF0ZSA8LSBnbG0oU0FIT1QyOF9kaWNoIH4gZGF0YV9pbWFnaW5nJFNTVl9xdWFudGlsZXMsIGZhbWlseSA9IGJpbm9taWFsLCAgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShVbml2YXJpYXRlKQpleHAoY2JpbmQoY29lZihVbml2YXJpYXRlKSwgY29uZmludChVbml2YXJpYXRlKSkpICAKClVuaXZhcmlhdGUgPC0gZ2xtKFNBSE9UMTgwX2RpY2ggfiBkYXRhX2ltYWdpbmckU1NWX3F1YW50aWxlcywgZmFtaWx5ID0gYmlub21pYWwsICBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KFVuaXZhcmlhdGUpCmV4cChjYmluZChjb2VmKFVuaXZhcmlhdGUpLCBjb25maW50KFVuaXZhcmlhdGUpKSkgIAoKI1RoZSBhYm92ZSBhbmFseXNpcyByZXBsaWNhdGVzIHNob3dzIHRoYXQgYXQgdGhlIGVhcmxpZXIgdGltZXBvaW50IGxvdyBTU1YgcHJlZGljdHMgcG9vciBvdXRjb21lIHVzaW5nIG1SUyBhbmQgU0FIT1QuIEhvd2V2ZXIsIFNTViBkb2VzIG5vdCByZWFjaCBzaWduaWZpY2FuY2UgYXQgdGhlIDE4MCB0aW1lcG9pbnQuIAoKI1VzZSBkaWNob3RvbWlzYXRpb24gZnJvbSBZdWFuLCBsb3dlc3QgcXVhbnRpbGUgZGVmaW5lZCBhcyAnbG93JyAKClVuaXZhcmlhdGUgPC0gZ2xtKG1SUzI4IH4gZGF0YV9pbWFnaW5nJFNTVl9kaWNoLCBmYW1pbHkgPSBiaW5vbWlhbCwgIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoVW5pdmFyaWF0ZSkKZXhwKGNiaW5kKGNvZWYoVW5pdmFyaWF0ZSksIGNvbmZpbnQoVW5pdmFyaWF0ZSkpKSAgCgpVbml2YXJpYXRlIDwtIGdsbShtUlMxODAgfiBkYXRhX2ltYWdpbmckU1NWX2RpY2gsIGZhbWlseSA9IGJpbm9taWFsLCAgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShVbml2YXJpYXRlKQpleHAoY2JpbmQoY29lZihVbml2YXJpYXRlKSwgY29uZmludChVbml2YXJpYXRlKSkpICAKClVuaXZhcmlhdGUgPC0gZ2xtKFNBSE9UMjhfZGljaCB+IGRhdGFfaW1hZ2luZyRTU1ZfZGljaCwgZmFtaWx5ID0gYmlub21pYWwsICBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KFVuaXZhcmlhdGUpCmV4cChjYmluZChjb2VmKFVuaXZhcmlhdGUpLCBjb25maW50KFVuaXZhcmlhdGUpKSkgIAoKVW5pdmFyaWF0ZSA8LSBnbG0oU0FIT1QxODBfZGljaCB+IGRhdGFfaW1hZ2luZyRTU1ZfZGljaCwgZmFtaWx5ID0gYmlub21pYWwsICBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KFVuaXZhcmlhdGUpCmV4cChjYmluZChjb2VmKFVuaXZhcmlhdGUpLCBjb25maW50KFVuaXZhcmlhdGUpKSkKCiNUaGUgZWFybHkgbVJTIG91dGNvbWUgaXMgdGhlIG9ubHkgdGltZXBvaW50IGluIHdoaWNoIHRoZSAnbG93JyBTU1YgbGVhZHMgdG8gd29ya3Mgb3V0Y29tZS4gCgpgYGAKUmVwZWF0IHJlZ3Jlc3Npb25zOgoKQmVmb3JlIHdlIG1ha2UgdGhhdCBtYWpvciByZXN0cnVjdHVyZSB3ZSB3YW50ZWQgdG8gc2VlIHRoZSBvdXRjb21lcyBvZiB0aGUgcmVncmVzc2lvbnMgZm9yIAoKMSkgV0ZOUywgVEJWIGFuZCBTU1YgdG8gcHJlZGljdCBvdXRjb21lIChNUlMgYW5kIFNBSE9UIGF0IGRheSAzMCBhbmQgMTgwKQoyKSBXRk5TLCBUQlYgYW5kIHZlbnRyaWN1bGFyIHZvbHVtZSB0byBwcmVkaWN0IG91dGNvbWUKCklmIHRoZSBsYXR0ZXIgZG9lcyBub3QgZ2l2ZSBhIGNsZWFyIHJlc3VsdCB0aGVuIHdlIHdhbnRlZCB0byB0cnkgaXQgYWdhaW4gYnV0OgoKYSkgYWRkIHByZXNlbmNlIG9mIGFuIEVWRCBhcyBhIGNvdmFyaWF0ZSBhbmQgYW4gaW50ZXJhY3Rpb24gYmV0d2VlbiB2ZW50cmljdWxhciB2b2x1bWUgYW5kIGFuIEVWRApiKSBhZGQgYW4gaW50ZXJhY3Rpb24gYmV0d2VlbiBUQlYgYW5kIHZlbnRyaWN1bGFyIHZvbHVtZQpgYGB7cn0KCiMgUmVncmVzc2lvbiAxOiBXRk5TLCBUQlYgYW5kIFNTViByZWdyZXNzaW9uCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMyOCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStTU1ZfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMxODApIH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrU1NWX0NTRiwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IoU0FIT1QyOF9kaWNoKSB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lK1NTVl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKFNBSE9UMTgwX2RpY2gpIH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrU1NWX0NTRiwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKIyBGb3IgbVJTLCBXRk5TIGlzIGEgc2lnbmlmaWNhbnQgcHJlZGljdG9yLCBmb3IgU0FIT1QsIFRCViBpcyBzaWduaWZpY2FudC4gU3Vic3RpdHV0ZSBpbiBuZXcgU1NWIHZhcmlhYmxlcyB0byBzZWUgaWYgdGhpcyBtYWtlcyBhIGRpZmZlcmVuY2UuIAoKI1NTVl9xdWFudGlsZSBmaXJzdAoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IobVJTMjgpIH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrU1NWX3F1YW50aWxlcywgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lK1NTVl9xdWFudGlsZXMsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKFNBSE9UMjhfZGljaCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStTU1ZfcXVhbnRpbGVzLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihTQUhPVDE4MF9kaWNoKSB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lK1NTVl9xdWFudGlsZXMsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCiNNYWtlcyBubyBkaWZmZXJlbmNlLiBIb3cgYWJvdXQgU1NWX2RpY2gKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKG1SUzI4KSB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lK1NTVl9kaWNoLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMxODApIH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrU1NWX2RpY2gsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKFNBSE9UMjhfZGljaCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStTU1ZfZGljaCwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IoU0FIT1QxODBfZGljaCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStTU1ZfZGljaCwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKI0FnYWluIG5vIGRpZmZlcmVuY2UgbWFkZS4gCgojIFJlZ3Jlc3Npb24gMjogV0ZOUywgVEJWIGFuZCB2ZW50cmljdWxhciB2b2x1bWUgdG8gcHJlZGljdCBvdXRjb21lCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMyOCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStWZW50cmljdWxhcl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKG1SUzE4MCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStWZW50cmljdWxhcl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKFNBSE9UMjhfZGljaCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStWZW50cmljdWxhcl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKFNBSE9UMTgwX2RpY2gpIH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrVmVudHJpY3VsYXJfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgojIFZlbnRyaWN1bGFyIENTRiBzaWduaWZpY2FudCBhdCAzMCBkYXkgbVJTIGFuZCBhbG1vc3Qgc2lnbmlmaWNhbnQgZm9yIG1SUyAxODAuIEhvd2V2ZXIsIG5vdCBzaWduaWZpY2FudCBmb3IgU0FIT1QuIAoKYGBgClRoZSBhYm92ZSByZWdyZXNzaW9ucyBkZW1vbnN0cmF0ZSBzZXZlcmFsIG9ic2VydmF0aW9ucyB3aXRoIHRoZSBkYXRhc2V0OgoKKDEpIFdGTlMgaXMgYSBoaWdobHkgc2lnbmlmaWNhbnQgcHJlZGljdG9yIG9mIGZ1bmN0aW9uYWwgb3V0Y29tZSBhdCAzMCBkYXlzIGFuZCAxODAgZGF5cyAKKDIpIFdoZW4gdXNpbmcgYSBtb3JlIHNwZWNpZmljIG91dGNvbWUgdG9vbCBmb3IgU0FIIChTQUhPVCksIFRCViBpcyBzaG93biB0byBiZSBhIGhpZ2hseSBzaWduaWZpY2FudCBwcmVkaWN0b3IgCigzKSBVbml2YXJpYXRlIGFuYWx5c2lzIG9mIFNTViB1c2luZyBjdXQgb2Zmcywgd2hpY2ggaXNvbGF0ZSBjYXNlcyB3aXRoICdsb3cnIFNTViwgbWFrZXMgaXQgYSBzaWduaWZpY2FudCB2YXJpYWJsZSBhdCBlYXJseSB0aW1lcG9pbnRzCig0KSBNdWx0aXZhcmlhdGUgYW5hbHlzZSBzaG93cyB0aGF0IFNTViBpcyBub3QgYW4gaW5kZXBlbmRlbnQgcHJlZGljdG9yIG9mIG91dGNvbWUgd2hlbiBUQlYgYW5kIFdGTlMgYXJlIGluY2x1ZGVkLiBIb3dldmVyLCBWZW50cmljdWxhciB2b2x1bWUgaXMgYW4gaW5kZXBlbmRlbnQgcHJlZGljdG9yIG9mIG91dGNvbWUgdXNpbmcgbVJTIAoKSSB0aGluayB0aGUgYWJvdmUgZ2l2ZXMgYSBjbGVhciByZXN1bHQuIEZpcnN0bHksIGl0IHNob3dzIHRoYXQgd2UgaGF2ZSBiZWVuIGFibGUgdG8gcmVwbGljYXRlIHByZXZpb3VzIGZpbmRpbmdzIGluIHRoZSBsaXRlcmF0dXJlLCB0aGF0IGF0IGVhcmx5IHRpbWVwb2ludHMgU1NWIHByZWRpY3RzIG91dGNvbWUuIEhvd2V2ZXIsIHdlIGhhdmUgc2hvd24gdGhhdCB0aGlzIGFmZmVjdCBpcyBub3QgbWFpbnRhaW5lZCBhdCBsYXRlciB0aW1lcG9pbnRzIG9yIHdoZW4gY29tYmluZWQgd2l0aCBvdGhlciBzaWduaWZpY2FudCBwcmVkaWN0b3JzIG9mIG91dGNvbWUuIEluc3RlYWQsIGltYWdpbmcgcHJlZGljdG9ycyBvZiBUQlYsIGFuZCB0byBhIGxlc3NlciBleHRlbnQgdmVudHJpY3VsYXIgQ1NGIGFyZSBtb3JlIGltcG9ydGFudC4gCgpUaGUgbmFycmF0aXZlIG9mIHRoZSBwYXBlciBpcyBjbGVhcmVyIHRvIG1lIG5vdyBhbmQgSSB0aGluayBzaG91bGQgYmUgcHJlc2VudGVkIHNvbWV0aGluZyBsaWtlIHRoaXM6IAoKKDEpIEJhc2ljIGRlbW9ncmFwaGljcyAKKDIpIFJlZ3Jlc3Npb24gMSBhbmQgUmVncmVzc2lvbiAyIGZyb20gYWJvdmUgCigzKSBJbnRlcmFjdGlvbiBwbG90cyAKKDQpIEluY2x1c2lvbiBvZiAnb3RoZXInIGltYWdpbmcgdmFyaWFibGVzIHRvIHNob3cgdGhleSBhcmUgbGVzcyByZWxldmFudCAKCkZvciBjb21wbGV0ZW5lc3MsIGJlbG93IEkgd2lsbCBpbmNsdWRlOiAKCmEpIGFkZCBwcmVzZW5jZSBvZiBhbiBFVkQgYXMgYSBjb3ZhcmlhdGUgYW5kIGFuIGludGVyYWN0aW9uIGJldHdlZW4gdmVudHJpY3VsYXIgdm9sdW1lIGFuZCBhbiBFVkQKYikgYWRkIGFuIGludGVyYWN0aW9uIGJldHdlZW4gVEJWIGFuZCB2ZW50cmljdWxhciB2b2x1bWUKCmBgYHtyfQojIGFkZCBwcmVzZW5jZSBvZiBhbiBFVkQgYXMgYSBjb3ZhcmlhdGUgYW5kIGFuIGludGVyYWN0aW9uIGJldHdlZW4gdmVudHJpY3VsYXIgdm9sdW1lIGFuZCBhbiBFVkQKCmNvbG5hbWVzKGRhdGFfaW1hZ2luZykKRVZEIDwtIGRhdGFfaW1hZ2luZyRFVkRGTApFVkQKZ2dwbG90KGRhdGEgPSBkYXRhX2ltYWdpbmcsIG1hcHBpbmcgPSBhZXMoeCA9IEVWRCkpKwogIGdlb21fYmFyKCkKCiNJbmNsdWRlIEVWRCBhcyBjb3ZhcmlhdGUgCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMyOCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStWZW50cmljdWxhcl9DU0YrRVZELCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMxODApIH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrVmVudHJpY3VsYXJfQ1NGK0VWRCwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IoU0FIT1QyOF9kaWNoKSB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lK1ZlbnRyaWN1bGFyX0NTRitFVkQsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKFNBSE9UMTgwX2RpY2gpIH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrVmVudHJpY3VsYXJfQ1NGK0VWRCwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKI0VWRCBpbnNlcnRpb24gaXMgaGlnaGx5IHNpZ25pZmljYW50IG9mIGVhcmx5IG91dGNvbWUgdXNpbmcgbVJTIGFuZCBzbGlnaHRseSByZWR1Y2VzIHRoZSBzaWduaWZpY2FuY2Ugb2YgdmVudHJpY3VsYXIgdm9sdW1lcyAKCiNJbmNsdWRlIEVWRCBhcyBpbnRlcmFjdGlvbiBmb3IgVmVudHJpY3VsYXIgQ1NGIHZvbHVtZSAKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKG1SUzI4KSB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lK1ZlbnRyaWN1bGFyX0NTRipFVkQsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKG1SUzE4MCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStWZW50cmljdWxhcl9DU0YqRVZELCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihTQUhPVDI4X2RpY2gpIH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrVmVudHJpY3VsYXJfQ1NGKkVWRCwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IoU0FIT1QxODBfZGljaCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStWZW50cmljdWxhcl9DU0YqRVZELCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgojV2hlbiBFVkQgaXMgYWRkZWQgYXMgYW4gaW50ZXJhY3Rpb24gdGVybSBmb3IgdmVudHJpY3VsYXIgdm9sdW1lLCB0aGVyZSBpcyBpbmNyZWFzZWQgc2lnbmlmaWNhbmNlIG9mIHRoZSB2YXJpYWJsZXMgYXQgMTgwIG1SUy4gCgojIGFkZCBhbiBpbnRlcmFjdGlvbiBiZXR3ZWVuIFRCViBhbmQgdmVudHJpY3VsYXIgdm9sdW1lCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMyOCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZSpWZW50cmljdWxhcl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKG1SUzE4MCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZSpWZW50cmljdWxhcl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKFNBSE9UMjhfZGljaCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZSpWZW50cmljdWxhcl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKFNBSE9UMTgwX2RpY2gpIH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUqVmVudHJpY3VsYXJfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCmBgYApBbm90aGVyIHRoaW5nIHdlIHNob3VsZCBjaGVjayBpcyB3aGV0aGVyIHRoZSBtb2RlbCBmaXQgaXMgYmV0dGVyIGlmIHdlIHVzZSBqdXN0OgotV0ZOUyBhbmQgYmxvb2Qgdm9sCi1XRk5TIGFuZCBDU0Ygdm9sCi1CbG9vZCBhbmQgQ1NGIHZvbAoKYGBge3J9CgoKI011bHRpdmFyYXRlIAoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lK1NTVl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCiNXRk5TLCBTU1YgYW5kIFRCVgojQUlDID0gODIuMwoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lK1RvdGFsX0NTRiwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKG1SUzE4MCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStWZW50cmljdWxhcl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCiMjQUlDOiA3OC45OTEKI1dGTlMsIGJsb29kIHZvbHVtZSAgdmVudHJpY3VsYXIgdm9sdW1lIHNpZ25pZmljYW50CgojV0ZOUyBhbmQgYmxvb2Qgdm9sdW1lIAoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgojI0FJQzogODAuNTg2CiNXRk5TIHNpZ25pZmljYW50IGJsb29kIHZvbHVtZSBpc24ndAoKI1dGTlMgYW5kIHZlbnRyaWN1bGFyIHZvbHVtZQoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFdGTlMrVmVudHJpY3VsYXJfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgojI0FJQzogODAuMDk5CiNXRk5TIHNpZ25pZmljYW50LCB2ZW50cmljdWxhciB2b2x1bWUgaXMgYWxtb3N0IHNpZ25pZmljYW50CgojV0ZOUyBhbmQgdG90YWwgQ1NGIHZvbHVtZQoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFdGTlMrVG90YWxfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgojI0FJQzogODEuMzY5CiNXRk5TIHNpZ25pZmljYW50LCB2ZW50cmljdWxhciB2b2x1bWUgaXMgYWxtb3N0IHNpZ25pZmljYW50CgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMxODApIH4gV0ZOUytTU1ZfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgojI0FJQzogODEuNjY2CiNXRk5TIHNpZ25pZmljYW50LCB2ZW50cmljdWxhciB2b2x1bWUgaXMgYWxtb3N0IHNpZ25pZmljYW50CgoKI0Jsb29kIGFuZCB2ZW50cmljdWxhciB2b2x1bWUgCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMxODApIH4gVG90YWxfYmxvb2Rfdm9sdW1lK1ZlbnRyaWN1bGFyX0NTRiwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKIyNBSUM6IDExMi4xNgojVG90YWwgYmxvb2QgdmVyeSBzaWduaWZpY2FudCBhbmQgdmVudHJpY3VsYXIgdm9sdW1lIHNpZ25pZmljYW50IAoKI1ZlbnRyaWN1bGFyIHZvbHVtZSBvbmx5IAoKVW5pdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKG1SUzE4MCkgfiBWZW50cmljdWxhcl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KFVuaXZhcmlhdGUpCiNWZW50cmljdWxhciB2b2x1bWUgaXMgbm90IHNpZ25pZmljYW50IG9uIGl0cyBvd24KCiNXRk5TIG9ubHkgCgpVbml2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFdGTlMsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KFVuaXZhcmlhdGUpCgojI0FJQzogOTUuNTk0CiNXRk5TIGlzIGhpZ2hseSBzaWduaWZpY2FudCAKCiNUQlYgb25seSAKClVuaXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMxODApIH4gVG90YWxfYmxvb2Rfdm9sdW1lLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShVbml2YXJpYXRlKQoKIyNBSUM6IDg0LjgyCiNUQlYgaXMgaGlnaGx5IHNpZ25pZmljYW50CgojV0ZOUywgYWdlIGFuZCBIVE4gCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMxODApIH4gV0ZOUysgYWdlK0hUTiwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFRvdGFsX2Jsb29kX3ZvbHVtZStWZW50cmljdWxhcl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCiNWZW50cmljdWxhciB2b2x1bWUgdnMgb3V0Y29tZSAKCmdncGxvdChkYXRhID0gZGF0YV9pbWFnaW5nLCBtYXBwaW5nID0gYWVzKHggPSBUb3RhbF9ibG9vZF92b2x1bWUsIHkgPSBkYXRhX2ltYWdpbmckTVJTMTgwKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKCkKCmdncGxvdChkYXRhID0gZGF0YV9pbWFnaW5nLCBtYXBwaW5nID0gYWVzKHggPSBWZW50cmljdWxhcl9DU0YsIHkgPSBkYXRhX2ltYWdpbmckTVJTMTgwKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKCkKCmdncGxvdChkYXRhID0gZGF0YV9pbWFnaW5nLCBtYXBwaW5nID0gYWVzKHggPSBkYXRhX2ltYWdpbmckYEJlbG93IFNTViBWb2x1bWVgLCB5ID0gZGF0YV9pbWFnaW5nJE1SUzE4MCkpKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aCgpCgpgYGAKU0FIT1QgYXMgbGluZWFyIHRvIHNlZSBpZiB0aGlzIGNoYW5nZXMgc2lnbmlmaWNhbmNlIG9mIHZhcmlhYmxlcy4gClNBSE9UIGlzIGEgOSBwYXJ0IHNjYWxlIDEgKEJlc3Qgb3V0Y29tZSksIDkgKGRlYXRoKS4KClJlcGVhdCByZWdyZXNzaW9ucyBVbml2YXJpYXRlIFNTViBhbmFseXNlczogCgpgYGB7cn0Kc2Fob3QyOCA8LSBkYXRhX2ltYWdpbmckU0FIT1QyOExPQ0YKc2Fob3Q5MCA8LSBkYXRhX2ltYWdpbmckU0FIT1Q5MExPQ0YKc2Fob3QxODAgPC0gZGF0YV9pbWFnaW5nJFNBSE9UMTgwTE9DRgoKc2Fob3QyOCAjMk5BcwpzYWhvdDkwICMyTkFzCnNhaG90MTgwICMyTkFzCgpzdHIoc2Fob3QyOCkKc3RyKHNhaG90MTgwKQoKI1Zpc3VhbGlzZSB0aGUgc3ByZWFkIG9mIFNBSE9UIAoKZ2dwbG90KGRhdGEgPSBkYXRhX2ltYWdpbmcsIG1hcHBpbmcgPSBhZXMoeCA9IHNhaG90MjgpKSsKICBnZW9tX2JhcigpCgpnZ3Bsb3QoZGF0YSA9IGRhdGFfaW1hZ2luZywgbWFwcGluZyA9IGFlcyh4ID0gc2Fob3QyOCwgeSA9IFdGTlMpKSsKICBnZW9tX3BvaW50KCkrCiAgZ2VvbV9zbW9vdGgoKSsKICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMjUpCgpnZ3Bsb3QoZGF0YSA9IGRhdGFfaW1hZ2luZywgbWFwcGluZyA9IGFlcyh4ID0gc2Fob3QxODApKSsKICBnZW9tX2JhcigpCgpnZ3Bsb3QoZGF0YSA9IGRhdGFfaW1hZ2luZywgbWFwcGluZyA9IGFlcyh4ID0gc2Fob3QxODAsIHkgPSBXRk5TKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKCkrCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjI1KQoKI1NTVl9xdWFudGlsZSB0aGUgQ2hvaSBldCBhbC4gY3V0LW9mZgojIDE8PTIwLjI1MDc4MSwgMj4yMC4yNTA3ODEsIDI8PTM3LjA5ODg0OSwgMz4zNy4wOTg4NDksIDM8PTc1LjEyODMwMywgND43NS4xMjgzMDMgKHVuaXRzID0gbWxzKQoKVW5pdmFyaWF0ZSA8LSBsbShzYWhvdDI4IH4gZGF0YV9pbWFnaW5nJFNTVl9xdWFudGlsZXMsICBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KFVuaXZhcmlhdGUpCmV4cChjYmluZChjb2VmKFVuaXZhcmlhdGUpLCBjb25maW50KFVuaXZhcmlhdGUpKSkgIAoKVW5pdmFyaWF0ZSA8LSBsbShzYWhvdDE4MCB+IGRhdGFfaW1hZ2luZyRTU1ZfcXVhbnRpbGVzLCAgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShVbml2YXJpYXRlKQpleHAoY2JpbmQoY29lZihVbml2YXJpYXRlKSwgY29uZmludChVbml2YXJpYXRlKSkpICAKCiNUaGUgYWJvdmUgYW5hbHlzaXMgcmVwbGljYXRlcyBzaG93cyB0aGF0IGF0IHRoZSBlYXJsaWVyIHRpbWVwb2ludCBsb3cgU1NWIHByZWRpY3RzIHBvb3Igb3V0Y29tZSB1c2luZyBtUlMgYW5kIFNBSE9ULiBIb3dldmVyLCBTU1YgZG9lcyBub3QgcmVhY2ggc2lnbmlmaWNhbmNlIGF0IHRoZSAxODAgdGltZXBvaW50LgojVmVyeSBzaW1pbGFyIHJlc3VsdHMgaW4gY29tcGFyaXNvbiB0byB3aGVuIFNBSE9UIHdhcyB0cmVhdGVkIGFzIGEgZGljaG90b21pc2VkIHZhcmlhYmxlIAoKI1VzZSBkaWNob3RvbWlzYXRpb24gZnJvbSBZdWFuLCBsb3dlc3QgcXVhbnRpbGUgZGVmaW5lZCBhcyAnbG93JyAKClVuaXZhcmlhdGUgPC0gbG0oc2Fob3QyOCB+IGRhdGFfaW1hZ2luZyRTU1ZfZGljaCwgIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoVW5pdmFyaWF0ZSkKZXhwKGNiaW5kKGNvZWYoVW5pdmFyaWF0ZSksIGNvbmZpbnQoVW5pdmFyaWF0ZSkpKSAgCgpVbml2YXJpYXRlIDwtIGdsbShzYWhvdDE4MCB+IGRhdGFfaW1hZ2luZyRTU1ZfZGljaCwgIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoVW5pdmFyaWF0ZSkKZXhwKGNiaW5kKGNvZWYoVW5pdmFyaWF0ZSksIGNvbmZpbnQoVW5pdmFyaWF0ZSkpKQoKI0F0IG5laXRoZXIgdGltZXBvaW50IGxvdyBTU1YgaXMgc2lnbmlmaWNhbnQuLiAKCiNVc2UgbGluZWFyIFNBSE9UIGZvciB1bml2YXJhdGUgYW5hbHlzaXMgCgpVbml2YXJpYXRlIDwtIGdsbShzYWhvdDE4MCB+IGRhdGFfaW1hZ2luZyRgVG90YWwgbWFudWFsIHZvbHVtZWAsICBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KFVuaXZhcmlhdGUpCgpgYGAKQXMgU0FIT1QgYXMgYSBsaW5lYXIgOSBwb2ludCBzY2FsZSwKClJlcGVhdCByZWdyZXNzaW9ucyBTQUhPVCBhdCBEMjggYW5kIEQxODA6IAoxKSBXRk5TLCBUQlYgYW5kIFNTViB0byBwcmVkaWN0IG91dGNvbWUgKE1SUyBhbmQgU0FIT1QgYXQgZGF5IDMwIGFuZCAxODApCjIpIFdGTlMsIFRCViBhbmQgdmVudHJpY3VsYXIgdm9sdW1lIHRvIHByZWRpY3Qgb3V0Y29tZQoKYGBge3J9CgojUmVncmVzc2lvbiAxOiAKCk11bHRpdmFyaWF0ZSA8LSBsbShzYWhvdDI4IH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrU1NWX0NTRiwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgpNdWx0aXZhcmlhdGUgPC0gbG0oc2Fob3QxODAgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStTU1ZfQ1NGLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCiNmb3IgU0FIT1QsIFdGTlMgaXMgc2lnLiBEMjggYW5kIFRCViBpcyBzaWduaWZpY2FudCBhdCBsYXRlIHRpbXBvaW50CgojUmVncmVzc2lvbiAyOgoKTXVsdGl2YXJpYXRlIDwtIGxtKHNhaG90MjggfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStWZW50cmljdWxhcl9DU0YsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKTXVsdGl2YXJpYXRlIDwtIGxtKHNhaG90MTgwIH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrVmVudHJpY3VsYXJfQ1NGLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCiNObyBjaGFuZ2Ugc3Vic3RpdHVpdGluZyB2ZW50cmljdWxhciBDU0Ygdm9sdW1lIC0gV0ZOUyBpcyBzaWcuIEQyOCBhbmQgVEJWIGlzIHNpZ25pZmljYW50IGF0IGxhdGUgdGltcG9pbnQKCmBgYApSZWFzb25pbmcgd2h5IGEgdmFyaWFibGUgaW4gYSB1bml2YXJpYXRlIGFuYWx5c2lzIGlzIG5vdCBzaWduaWZpY2FudCBidXQgYmVjb21lcyBzaWduaWZpY2FudCBpbiBhIG11bHRpdmFyaWF0ZSBhbmFseXNpczogCgpUaGUgY2FzZSBvZiB0d28gcHJlZGljdG9ycyB0aGF0IGFyZSB0cnVseSBvcnRob2dvbmFsOiB0aGVyZSBpcyBhYnNvbHV0ZWx5IG5vIGNvbGxpbmVhcml0eSBhbW9uZyB0aGVtLiBBIHJlbWFya2FibGUgY2hhbmdlIGluIHNpZ25pZmljYW5jZSBjYW4gc3RpbGwgaGFwcGVuLgoKRGVzaWduYXRlIHRoZSBwcmVkaWN0b3IgdmFyaWFibGVzIPCdkYsxIGFuZCDwnZGLMiBhbmQgbGV0IPCdkYwgbmFtZSB0aGUgcHJlZGljdG9yLiBUaGUgcmVncmVzc2lvbiBvZiDwnZGMCiBhZ2FpbnN0IPCdkYsxIHdpbGwgZmFpbCB0byBiZSBzaWduaWZpY2FudCB3aGVuIHRoZSB2YXJpYXRpb24gaW4g8J2RjCBhcm91bmQgaXRzIG1lYW4gaXMgbm90IGFwcHJlY2lhYmx5IHJlZHVjZWQgd2hlbiDwnZGLMQogaXMgdXNlZCBhcyB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGUuIFdoZW4gdGhhdCB2YXJpYXRpb24gaXMgc3Ryb25nbHkgYXNzb2NpYXRlZCB3aXRoIGEgc2Vjb25kIHZhcmlhYmxlIPCdkYsyLAogaG93ZXZlciwgdGhlIHNpdHVhdGlvbiBjaGFuZ2VzLiBSZWNhbGwgdGhhdCBtdWx0aXBsZSByZWdyZXNzaW9uIG9mIPCdkYwgYWdhaW5zdCDwnZGLMSBhbmQg8J2RizIgaXMgZXF1aXZhbGVudCB0bwogc2VwYXJhdGVseSByZWdyZXNzIPCdkYwgYW5kIPCdkYsxIGFnYWluc3Qg8J2RizIuCgpSZWdyZXNzIHRoZSDwnZGMIHJlc2lkdWFscyBhZ2FpbnN0IHRoZSDwnZGLMSByZXNpZHVhbHMuCgpUaGUgcmVzaWR1YWxzIGZyb20gdGhlIGZpcnN0IHN0ZXAgaGF2ZSByZW1vdmVkIHRoZSBlZmZlY3Qgb2Yg8J2RizIuIFdoZW4g8J2RizIgaXMgY2xvc2VseSBjb3JyZWxhdGVkIHdpdGgg8J2RjCwgdGhpcyBjYW4gZXhwb3NlIAphIHJlbGF0aXZlbHkgc21hbGwgYW1vdW50IG9mIHZhcmlhdGlvbiB0aGF0IGhhZCBwcmV2aW91c2x5IGJlZW4gbWFza2VkLiBJZiB0aGlzIHZhcmlhdGlvbiBpcyBhc3NvY2lhdGVkIHdpdGgg8J2RizEsIHdlIG9idGFpbiBhIHNpZ25pZmljYW50IHJlc3VsdC4KCkZ1cnRoZXIgaW5mbyBmcm9tOiBodHRwczovL3N0YXRzLnN0YWNrZXhjaGFuZ2UuY29tL3F1ZXN0aW9ucy8yODQ3NC9ob3ctY2FuLWFkZGluZy1hLTJuZC1pdi1tYWtlLXRoZS0xc3QtaXYtc2lnbmlmaWNhbnQKCkluIHRoZSBhbmFseXNlcyBkb25lIFdGTlMgYW5kIHZlbnRyaWN1bGFyIHZvbHVtZSBhcmUgbm90IGNvbGluZWFyLCBidXQgYmxvb2Qgdm9sdW1lIGFuZCB2ZW50cmljdWxhciB2b2x1bWUgYXJlIGNvbGluZWFyIGluIGEgbmVnYXRpdmUgZGlyZWN0aW9uLiAKV0ZOUyBhbmQgdmVudHJpY3VsYXIgdm9sdW1lLCB0aGVyZWZvcmUgcmVwcmVzZW50IHRoZSBhYm92ZSBmaW5kaW5nOiAKCiNWZW50cmljdWxhciB2b2x1bWUgb25seSAKClVuaXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMxODApIH4gVmVudHJpY3VsYXJfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShVbml2YXJpYXRlKQoKI1ZlbnRyaWN1bGFyIHZvbHVtZSBpcyBub3Qgc2lnbmlmaWNhbnQgb24gaXRzIG93bgoKI1dGTlMgYW5kIHZlbnRyaWN1bGFyIHZvbHVtZQoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFdGTlMrVmVudHJpY3VsYXJfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgojI0FJQzogOTQuMjY5CiNXRk5TIHNpZ25pZmljYW50LCB2ZW50cmljdWxhciB2b2x1bWUgaXMgYWxtb3N0IHNpZ25pZmljYW50CgojQmxvb2QgYW5kIHZlbnRyaWN1bGFyIHZvbHVtZSAKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKG1SUzE4MCkgfiBUb3RhbF9ibG9vZF92b2x1bWUrVmVudHJpY3VsYXJfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgojI0FJQzogMTEyLjE2CiNUb3RhbCBibG9vZCB2ZXJ5IHNpZ25pZmljYW50IGFuZCB2ZW50cmljdWxhciB2b2x1bWUgc2lnbmlmaWNhbnQgLSBwcm9iYWJseSBkdWUgdG8gY29sbGluYXJpdHkgCgoKU2hhcGxleSBwbG90cyAKCkNvbXBsZXggcHJlZGljdGl2ZSBtb2RlbHMgYXJlIG5vdCBlYXN5IHRvIGludGVycHJldC4gQnkgY29tcGxleCBJIG1lYW46IHJhbmRvbSBmb3Jlc3QsIHhnYm9vc3QsIGRlZXAgbGVhcm5pbmcsIGV0Yy4KClNoYXBsZXkgdmFsdWVzIGNhbGN1bGF0ZSB0aGUgaW1wb3J0YW5jZSBvZiBhIGZlYXR1cmUgYnkgY29tcGFyaW5nIHdoYXQgYSBtb2RlbCBwcmVkaWN0cyB3aXRoIGFuZCB3aXRob3V0IHRoZSBmZWF0dXJlLiBIb3dldmVyLCBzaW5jZSB0aGUgb3JkZXIgaW4gd2hpY2ggYSBtb2RlbCBzZWVzIGZlYXR1cmVzIGNhbiBhZmZlY3QgaXRzIHByZWRpY3Rpb25zLCB0aGlzIGlzIGRvbmUgaW4gZXZlcnkgcG9zc2libGUgb3JkZXIsIHNvIHRoYXQgdGhlIGZlYXR1cmVzIGFyZSBmYWlybHkgY29tcGFyZWQuCgpIb3cgdG8gaW50ZXJwcmV0IHRoZSBzaGFwIHN1bW1hcnkgcGxvdD8KClRoZSB5LWF4aXMgaW5kaWNhdGVzIHRoZSB2YXJpYWJsZSBuYW1lLCBpbiBvcmRlciBvZiBpbXBvcnRhbmNlIGZyb20gdG9wIHRvIGJvdHRvbS4gVGhlIHZhbHVlIG5leHQgdG8gdGhlbSBpcyB0aGUgbWVhbiBTSEFQIHZhbHVlLgpPbiB0aGUgeC1heGlzIGlzIHRoZSBTSEFQIHZhbHVlLiBJbmRpY2F0ZXMgaG93IG11Y2ggaXMgdGhlIGNoYW5nZSBpbiBsb2ctb2Rkcy4gRnJvbSB0aGlzIG51bWJlciB3ZSBjYW4gZXh0cmFjdCB0aGUgcHJvYmFiaWxpdHkgb2Ygc3VjY2Vzcy4KR3JhZGllbnQgY29sb3IgaW5kaWNhdGVzIHRoZSBvcmlnaW5hbCB2YWx1ZSBmb3IgdGhhdCB2YXJpYWJsZS4gSW4gYm9vbGVhbnMsIGl0IHdpbGwgdGFrZSB0d28gY29sb3JzLCBidXQgaW4gbnVtYmVyIGl0IGNhbiBjb250YWluIHRoZSB3aG9sZSBzcGVjdHJ1bS4KRWFjaCBwb2ludCByZXByZXNlbnRzIGEgcm93IGZyb20gdGhlIG9yaWdpbmFsIGRhdGFzZXQuCgpgYGB7cn0KaW5zdGFsbC5wYWNrYWdlcygic2hhcHIiKSAjQ2FsbCBpbiBwYWNrYWdlcwppbnN0YWxsLnBhY2thZ2VzKCJ4Z2Jvb3N0IikKaW5zdGFsbC5wYWNrYWdlcygiU0hBUGZvcnhnYm9vc3QiKQoKbGlicmFyeShzaGFwcikKbGlicmFyeSh4Z2Jvb3N0KQpsaWJyYXJ5KFNIQVBmb3J4Z2Jvb3N0KQoKCj9zaGFwcgoKI0RlZmluZSB0aGUgcmVzcG9uc2UgYW5kIGZlYXR1cmVzIApjb2xuYW1lcyhkYXRhX2ltYWdpbmcpCgojUHJlcGFyZSBkYXRhIAoKZGF0YV9pbWFnaW5nX3N1YnNldCA8LSBkYXRhX2ltYWdpbmdbLCBjKCJBR0UiLCAiV0ZOU0dSRE4iLCAiVG90YWwgYmxvb2QiLCAiU1NWIFZvbHVtZSIsCiAgICAgICAiVmVudHJpY3VsYXIgdm9sdW1lIiwgIlRvdGFsIG1hbnVhbCB2b2x1bWUiLCAiTVJTMTgwX2RpY2giKV0KCnZpZXcoZGF0YV9pbWFnaW5nX3N1YnNldCkKCnkgPC0gIk1SUzE4MF9kaWNoIgp4IDwtIGMoIkFHRSIsICJXRk5TR1JETiIsICJUb3RhbCBibG9vZCIsICJTU1YgVm9sdW1lIiwKICAgICAgICJWZW50cmljdWxhciB2b2x1bWUiLCAiVG90YWwgbWFudWFsIHZvbHVtZSIpCgpkYXRhX2ltYWdpbmdfc3Vic2V0IDwtIG5hLm9taXQoZGF0YV9pbWFnaW5nX3N1YnNldCkKCiNGaXQgYSBtYW51YWxseSB0dW5lZCBYR0Jvb3N0IG1vZGVsIHRvIHRoZSBkYXRhLgoKZHRyYWluIDwtIHhnYi5ETWF0cml4KGRhdGEubWF0cml4KGRhdGFfaW1hZ2luZ19zdWJzZXQpKQpkdmFsaWQgPC0geGdiLkRNYXRyaXgoZGF0YS5tYXRyaXgoZGF0YV9pbWFnaW5nX3N1YnNldCkpCgpwYXJhbXMgPC0gbGlzdCgKICBvYmplY3RpdmUgPSAicmVnOnNxdWFyZWRlcnJvciIsCiAgbGVhcm5pbmdfcmF0ZSA9IDAuMDUsCiAgc3Vic2FtcGxlID0gMC45LAogIGNvbHNhbXBsZV9ieW5vZGUgPSAxLAogIHJlZ19sYW1iZGEgPSAyLAogIG1heF9kZXB0aCA9IDUKKQpmaXRfeGdiIDwtIHhnYi50cmFpbigKICBwYXJhbXMsCiAgZGF0YSA9IGR0cmFpbiwKICB3YXRjaGxpc3QgPSBsaXN0KHZhbGlkID0gZHZhbGlkKSwKICBlYXJseV9zdG9wcGluZ19yb3VuZHMgPSAyMCwKICBwcmludF9ldmVyeV9uID0gMTAwLAogIG5yb3VuZHMgPSAxMDAwMCAjIGVhcmx5IHN0b3BwaW5nCikKCmBgYApDcmVhdGUgYSBjb21wYXJhdGl2ZSBBVUMgZ3JhcGggZm9yIHRoZSAnZmluYWwnIG1vZGVsIHRoYXQgaW5jbHVkZXMgV0ZOUywgdG90YWwgYmxvb2Qgdm9sdW1lIGFuZCB2ZW50cmljdWxhciBDU0Ygdm9sdW1lIGluIHRoZSBwcmVkaWN0aW9uIG9mIG1SUyAxODAKYGBge3J9CiNGaW5hbCBtb2RlbCAKCldGTlMKVG90YWxfYmxvb2Rfdm9sdW1lClZlbnRyaWN1bGFyX0NTRgptUlMxODAKCiMjIG1SUwoKbVJTMTgwIDwtIGFzLmZhY3RvcihyZWNvZGUobVJTMTgwLCAiMCI9Ikdvb2Qgb3V0Y29tZSIsICIxIiA9ICJCYWQgb3V0Y29tZSIpKQpjb250cmFzdHMoYXMuZmFjdG9yKG1SUzI4KSkKbVJTMTgwIDwtIGZhY3RvcihtUlMxODAsIGxldmVscyA9IGMoIkdvb2Qgb3V0Y29tZSIsICJCYWQgb3V0Y29tZSIpKQpjb250cmFzdHMoYXMuZmFjdG9yKG1SUzE4MCkpCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKG1SUzE4MCB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lK1ZlbnRyaWN1bGFyX0NTRiwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQpjb2VmKE11bHRpdmFyaWF0ZSkKCgojIyBDb21iaW5lZCBBVUMgCgpsaWJyYXJ5KFJPQ1IpCmxpYnJhcnkocFJPQykKCgpwbG90KHggPSBXRk5TLCB5ID0gbVJTMTgwKQpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMxODApIH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrVmVudHJpY3VsYXJfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgpyb2MxIDwtIHJvYyhtUlMxODAsIE11bHRpdmFyaWF0ZSRmaXR0ZWQudmFsdWVzLCBwbG90ID0gVFJVRSkKcm9jMQpjaShyb2MxKQpwYXIocHR5ID0gInMiKQoKcm9jKG1SUzE4MCwgTXVsdGl2YXJpYXRlJGZpdHRlZC52YWx1ZXMsIHBsb3QgPSBUUlVFLCBsZWdhY3kuYXhlcyA9IFRSVUUsIHBlcmNlbnQgPSBUUlVFLAogICAgeGxhYj0gIkZhbHNlIFBvc2l0aXZlIFBlcmNlbnRhZ2UiLCB5bGFiID0gIlRydWUgUG9zaXRpdmUgUGVyY2VudGFnZSIsIGNvbCA9ICJibGFjayIsIGx3ZCA9IDIsIHByaW50LmF1YyA9IDYwKQpsZWdlbmQoImJvdHRvbXJpZ2h0IiwgbGVnZW5kID0gYygibVJTIGRheSAxODAiKSwgY29sID0gYygiYmxhY2siKSwgbHdkID0gNCkKCmNpKHJvYzEpCgojIE92ZXJsYXAgQVVDIAoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lK1ZlbnRyaWN1bGFyX0NTRiwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKcm9jKG1SUzE4MCwgTXVsdGl2YXJpYXRlJGZpdHRlZC52YWx1ZXMsIHBsb3QgPSBUUlVFLCBsZWdhY3kuYXhlcyA9IFRSVUUsIHBlcmNlbnQgPSBUUlVFLAogICAgeGxhYj0gIkZhbHNlIFBvc2l0aXZlIFBlcmNlbnRhZ2UiLCB5bGFiID0gIlRydWUgUG9zaXRpdmUgUGVyY2VudGFnZSIsIGNvbCA9ICJibGFjayIsIGx3ZCA9IDIsIHByaW50LmF1YyA9IDYwKQpwYXIocHR5ID0gInMiKQpNdWx0aXZhcmlhdGUyIDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKTXVsdGl2YXJpYXRlMyA8LSBnbG0oYXMuZmFjdG9yKG1SUzE4MCkgfiBXRk5TK1NTVl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpNdWx0aXZhcmlhdGU0IDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFdGTlMrVmVudHJpY3VsYXJfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKTXVsdGl2YXJpYXRlNSA8LSBnbG0oYXMuZmFjdG9yKG1SUzE4MCkgfiBXRk5TK1RvdGFsX0NTRiwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCgoKcm9jKG1SUzE4MCwgTXVsdGl2YXJpYXRlJGZpdHRlZC52YWx1ZXMsIHBsb3QgPSBUUlVFLCBsZWdhY3kuYXhlcyA9IFRSVUUsIHBlcmNlbnQgPSBUUlVFLAogICAgeGxhYj0gIkZhbHNlIFBvc2l0aXZlIFBlcmNlbnRhZ2UiLCB5bGFiID0gIlRydWUgUG9zaXRpdmUgUGVyY2VudGFnZSIsIGNvbCA9ICJvcmFuZ2UiLCBsd2QgPSAxLCBwcmludC5hdWMgPSBUUlVFLCBwcmludC5hdWMueSA9IDcwLCBwcmludC5hdWMueCA9IDQwKQpwbG90LnJvYyhtUlMxODAsIE11bHRpdmFyaWF0ZTIkZml0dGVkLnZhbHVlcywgcGVyY2VudCA9IFRSVUUsIGNvbCA9ICJyZWQiLCBsd2QgPSAxLCBhZGQgPSBUUlVFLCBwcmludC5hdWMgPSBUUlVFLCBwcmludC5hdWMueSA9IDkwLCBwcmludC5hdWMueCA9IDQwKQpwbG90LnJvYyhtUlMxODAsIE11bHRpdmFyaWF0ZTMkZml0dGVkLnZhbHVlcywgcGVyY2VudCA9IFRSVUUsIGNvbCA9ICJibHVlIiwgbHdkID0gMSwgYWRkID0gVFJVRSwgcHJpbnQuYXVjID0gVFJVRSwgcHJpbnQuYXVjLnkgPSA2MCwgcHJpbnQuYXVjLnggPSA0MCkKcGxvdC5yb2MobVJTMTgwLCBNdWx0aXZhcmlhdGU0JGZpdHRlZC52YWx1ZXMsIHBlcmNlbnQgPSBUUlVFLCBjb2wgPSAiYmxhY2siLCBsd2QgPSAxLCBhZGQgPSBUUlVFLCBwcmludC5hdWMgPSBUUlVFLCBwcmludC5hdWMueSA9IDgwLCBwcmludC5hdWMueCA9IDQwKQpwbG90LnJvYyhtUlMxODAsIE11bHRpdmFyaWF0ZTUkZml0dGVkLnZhbHVlcywgcGVyY2VudCA9IFRSVUUsIGNvbCA9ICJmb3Jlc3RncmVlbiIsIGx3ZCA9IDEsIGFkZCA9IFRSVUUsIHByaW50LmF1YyA9IFRSVUUsIHByaW50LmF1Yy55ID0gODAsIHByaW50LmF1Yy54ID0gNDApCgpsZWdlbmQoImJvdHRvbXJpZ2h0IiwgdGl0bGUgPSAibW9kaWZpZWQgUmFua2luIFNjYWxlIiwgCiAgICAgICBsZWdlbmQgPSBjKCJXRk5TK0Jsb29kIiwgIldGTlMrVmVudHJpY3VsYXJDU0YiLCAiRmluYWwgbW9kZWwiLCAiV0ZOUytTU1ZfQ1NGIiwgIldGTlMrVG90YWxDU0YiKSwgY29sID0gYygicmVkIiwgImJsYWNrIiwgIm9yYW5nZSIsICJibHVlIiwgImZvcmVzdGdyZWVuIiksIAogICAgICAgbHdkID0gMiwgIkxlZ2VuZCIsIGNleD0wLjgpCmBgYApTdGVwd2lzZSByZWdyZXNzc2lvbmFsIGFuYWx5c2lzIGZvciB0aGUgZGV2ZWxvcG1lbnQgb2YgdGhlIG11bHRpdmFyaWF0ZSBtb2RlbC4gCgpWYXJpYWJsZXM6IGFnZSwgV0ZOUywgVEJWLCBTU1YsIFZlbnRyaWN1bGFyIENTRiwgdG90YWwgQ1NGIAoKYGBge3J9CgojUGFja2FnZXMgCgpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShjYXJldCkKbGlicmFyeShsZWFwcykKbGlicmFyeShNQVNTKQoKI0ZpdCBmdWxsIG1vZGVsIAoKZnVsbC5tb2RlbCA8LSAgZ2xtKG1SUzE4MCB+IGFnZStXRk5TK1RvdGFsX2Jsb29kK1NTVl9DU0YrVmVudHJpY3VsYXJfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShmdWxsLm1vZGVsKQoKI1N0ZXB3aXNlIG1vZGVsCgpzdGVwLm1vZGVsIDwtIHN0ZXBBSUMoZnVsbC5tb2RlbCwgZGlyZWN0aW9uID0gImJvdGgiLCB0cmFjZSA9IEZBTFNFKQpzdW1tYXJ5KHN0ZXAubW9kZWwpCmBgYAoK