This is a course catelogue of R programming and Data Science course offer by Iskulghar. This webpage is created by R programming which only consists of 25% of the course! So imagine how much will you learn from this single course. Visit: https://www.facebook.com/iskulghar For more information.

Data Frame (Example)

Dataset summary

       ID        Name                Age         Score   
 Min.   :1   Length:5           Min.   :22   Min.   :78  
 1st Qu.:2   Class :character   1st Qu.:25   1st Qu.:81  
 Median :3   Mode  :character   Median :28   Median :85  
 Mean   :3                      Mean   :28   Mean   :85  
 3rd Qu.:4                      3rd Qu.:30   3rd Qu.:89  
 Max.   :5                      Max.   :35   Max.   :92  

Basic plot of the dataset

Real world dataset - IRIS

Summary of iris dataset

  Sepal.Length    Sepal.Width     Petal.Length    Petal.Width          Species  
 Min.   :4.300   Min.   :2.000   Min.   :1.000   Min.   :0.100   setosa    :50  
 1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300   versicolor:50  
 Median :5.800   Median :3.000   Median :4.350   Median :1.300   virginica :50  
 Mean   :5.843   Mean   :3.057   Mean   :3.758   Mean   :1.199                  
 3rd Qu.:6.400   3rd Qu.:3.300   3rd Qu.:5.100   3rd Qu.:1.800                  
 Max.   :7.900   Max.   :4.400   Max.   :6.900   Max.   :2.500                  

Histrogram - Distribution

Scatter plot

Box plot

Violine plot

Correlation Matrix

             Sepal.Length Sepal.Width Petal.Length Petal.Width
Sepal.Length    1.0000000  -0.1175698    0.8717538   0.8179411
Sepal.Width    -0.1175698   1.0000000   -0.4284401  -0.3661259
Petal.Length    0.8717538  -0.4284401    1.0000000   0.9628654
Petal.Width     0.8179411  -0.3661259    0.9628654   1.0000000

Heat map of correlation matrix

Heat map of correlation matrix (version 2)

Heat map of correlation matrix (version 3)

Pari plot

Regression

Linear Regression

Linear Regression Analaysis


Call:
lm(formula = Sepal.Length ~ Petal.Length, data = iris)

Residuals:
     Min       1Q   Median       3Q      Max 
-1.24675 -0.29657 -0.01515  0.27676  1.00269 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept)   4.30660    0.07839   54.94   <2e-16 ***
Petal.Length  0.40892    0.01889   21.65   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.4071 on 148 degrees of freedom
Multiple R-squared:   0.76, Adjusted R-squared:  0.7583 
F-statistic: 468.6 on 1 and 148 DF,  p-value: < 2.2e-16

Polynomial Regression

Polynomial Regression analysis


Call:
lm(formula = y ~ x + I(x^2) + I(x^3))

Residuals:
     Min       1Q   Median       3Q      Max 
-1.06434 -0.24523  0.00707  0.19869  0.92755 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  4.64817    0.45873  10.133   <2e-16 ***
x            0.27811    0.48046   0.579    0.564    
I(x^2)      -0.04428    0.13454  -0.329    0.743    
I(x^3)       0.01055    0.01123   0.939    0.349    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.364 on 146 degrees of freedom
Multiple R-squared:  0.8106,    Adjusted R-squared:  0.8067 
F-statistic: 208.3 on 3 and 146 DF,  p-value: < 2.2e-16

Multivariate Polynomial Regression


Call:
lm(formula = Sepal.Length ~ poly(Sepal.Width, 2) + poly(Petal.Length, 
    2) + poly(Petal.Width, 2), data = iris)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.85830 -0.21065  0.00061  0.19278  0.77325 

Coefficients:
                       Estimate Std. Error t value Pr(>|t|)    
(Intercept)             5.84333    0.02509 232.877  < 2e-16 ***
poly(Sepal.Width, 2)1   2.99803    0.40359   7.428 9.12e-12 ***
poly(Sepal.Width, 2)2   0.34547    0.31951   1.081  0.28141    
poly(Petal.Length, 2)1 12.74168    1.78665   7.132 4.54e-11 ***
poly(Petal.Length, 2)2  1.59442    0.58991   2.703  0.00771 ** 
poly(Petal.Width, 2)1  -2.82015    1.72498  -1.635  0.10427    
poly(Petal.Width, 2)2  -0.95176    0.67450  -1.411  0.16040    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.3073 on 143 degrees of freedom
Multiple R-squared:  0.8678,    Adjusted R-squared:  0.8623 
F-statistic: 156.5 on 6 and 143 DF,  p-value: < 2.2e-16

Clustering

Clustering result analysis

K-means clustering with 3 clusters of sizes 62, 38, 50

Cluster means:
  Sepal.Length Sepal.Width Petal.Length Petal.Width
1     5.901613    2.748387     4.393548    1.433871
2     6.850000    3.073684     5.742105    2.071053
3     5.006000    3.428000     1.462000    0.246000

Clustering vector:
  [1] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 2 1 1 1
 [57] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 2 2 2 2 1 2 2 2 2 2
[113] 2 1 1 2 2 2 2 1 2 1 2 1 2 2 1 1 2 2 2 2 2 1 2 2 2 2 1 2 2 2 1 2 2 2 1 2 2 1

Within cluster sum of squares by cluster:
[1] 39.82097 23.87947 15.15100
 (between_SS / total_SS =  88.4 %)

Available components:

[1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss" "betweenss"    "size"        
[8] "iter"         "ifault"      

Classification

SVM Model

[1] "Confusion Matrix:"
Confusion Matrix and Statistics

            Reference
Prediction   setosa versicolor virginica
  setosa         10          0         0
  versicolor      0         10         1
  virginica       0          0         9

Overall Statistics
                                          
               Accuracy : 0.9667          
                 95% CI : (0.8278, 0.9992)
    No Information Rate : 0.3333          
    P-Value [Acc > NIR] : 2.963e-13       
                                          
                  Kappa : 0.95            
                                          
 Mcnemar's Test P-Value : NA              

Statistics by Class:

                     Class: setosa Class: versicolor Class: virginica
Sensitivity                 1.0000            1.0000           0.9000
Specificity                 1.0000            0.9500           1.0000
Pos Pred Value              1.0000            0.9091           1.0000
Neg Pred Value              1.0000            1.0000           0.9524
Prevalence                  0.3333            0.3333           0.3333
Detection Rate              0.3333            0.3333           0.3000
Detection Prevalence        0.3333            0.3667           0.3000
Balanced Accuracy           1.0000            0.9750           0.9500
[1] "Accuracy: 0.966666666666667"

SVM Classification confusion matrix

Statistical Analysis

Data Distribution

T-test


    Welch Two Sample t-test

data:  setosa and virginica
t = -15.386, df = 76.516, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -1.78676 -1.37724
sample estimates:
mean of x mean of y 
    5.006     6.588 

ANOVA


    Welch Two Sample t-test

data:  setosa and virginica
t = -15.386, df = 76.516, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -1.78676 -1.37724
sample estimates:
mean of x mean of y 
    5.006     6.588 

Tukey’s posthoc test

  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Sepal.Length ~ Species, data = iris)

$Species
                      diff       lwr       upr p adj
versicolor-setosa    0.930 0.6862273 1.1737727     0
virginica-setosa     1.582 1.3382273 1.8257727     0
virginica-versicolor 0.652 0.4082273 0.8957727     0

Chi-square test

Warning: Chi-squared approximation may be incorrect

    Pearson's Chi-squared test

data:  table(iris$Species, cut(iris$Petal.Length, breaks = c(1, 2, 3,     4, 5)))
X-squared = 114.49, df = 6, p-value < 2.2e-16

Principal component analysis

Standard deviations (1, .., p=4):
[1] 1.7083611 0.9560494 0.3830886 0.1439265

Rotation (n x k) = (4 x 4):
                    PC1         PC2        PC3        PC4
sepal.length  0.5210659 -0.37741762  0.7195664  0.2612863
sepal.width  -0.2693474 -0.92329566 -0.2443818 -0.1235096
petal.length  0.5804131 -0.02449161 -0.1421264 -0.8014492
petal.width   0.5648565 -0.06694199 -0.6342727  0.5235971
Importance of components:
                          PC1    PC2     PC3     PC4
Standard deviation     1.7084 0.9560 0.38309 0.14393
Proportion of Variance 0.7296 0.2285 0.03669 0.00518
Cumulative Proportion  0.7296 0.9581 0.99482 1.00000

PCA Dimension Contribution

PCA Dimension Contribution (Heat map)

PCA Dimension Contribution (Vector map)

PCA 2D plot (scatter with marked data point)

PCA Clustering

Interactive plots

Bonus!

3D sine curve

Support Vector Regression Surface Curve

Our next course

Certificate

We provide certificate upon course completion
We provide certificate upon course completion
LS0tCnRpdGxlOiAiUiBDb3Vyc2UgQ2F0YWxvZ3VlIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAogIHBkZl9kb2N1bWVudDogZGVmYXVsdAogIGh0bWxfZG9jdW1lbnQ6CiAgICBkZl9wcmludDogcGFnZWQKLS0tCgpUaGlzIGlzIGEgY291cnNlIGNhdGVsb2d1ZSBvZiBSIHByb2dyYW1taW5nIGFuZCBEYXRhIFNjaWVuY2UgY291cnNlIG9mZmVyIGJ5IElza3VsZ2hhci4gVGhpcyB3ZWJwYWdlIGlzIGNyZWF0ZWQgYnkgUiBwcm9ncmFtbWluZyB3aGljaCBvbmx5IGNvbnNpc3RzIG9mIDI1JSBvZiB0aGUgY291cnNlISBTbyBpbWFnaW5lIGhvdyBtdWNoIHdpbGwgeW91IGxlYXJuIGZyb20gdGhpcyBzaW5nbGUgY291cnNlLiAKVmlzaXQ6IGh0dHBzOi8vd3d3LmZhY2Vib29rLmNvbS9pc2t1bGdoYXIgCkZvciBtb3JlIGluZm9ybWF0aW9uLiAKCiMjIERhdGEgRnJhbWUgKEV4YW1wbGUpCmBgYHtyLCBlY2hvID0gRkFMU0V9CiMgR2l2ZW4gZGF0YSBmcmFtZQpkYXRhIDwtIGRhdGEuZnJhbWUoCiAgSUQgPSBjKDEsIDIsIDMsIDQsIDUpLAogIE5hbWUgPSBjKCJBbGljZSIsICJCb2IiLCAiQ2hhcmxpZSIsICJEYXZpZCIsICJFdmEiKSwKICBBZ2UgPSBjKDI1LCAzMCwgMjIsIDI4LCAzNSksCiAgU2NvcmUgPSBjKDg1LCA5MiwgNzgsIDg5LCA4MSkKKQoKcHJpbnQoZGF0YSkKCmBgYAojIyMgRGF0YXNldCBzdW1tYXJ5CmBgYHtyLCBlY2hvID0gRkFMU0V9CnN1bW1hcnkoZGF0YSkKYGBgCgojIyMgQmFzaWMgcGxvdCBvZiB0aGUgZGF0YXNldApgYGB7ciwgZWNobyA9IEZBTFNFfQojIENyZWF0ZSBhIHNjYXR0ZXIgcGxvdCBvZiBBZ2UgdnMuIFNjb3JlCnBsb3QoZGF0YSRBZ2UsIGRhdGEkU2NvcmUsIHhsYWIgPSAiQWdlIiwgeWxhYiA9ICJTY29yZSIsIG1haW4gPSAiQWdlIHZzLiBTY29yZSIpCgojIENyZWF0ZSBhIGxpbmUgcGxvdCBvZiBJRCB2cy4gU2NvcmUKcGxvdChkYXRhJElELCBkYXRhJFNjb3JlLCB0eXBlID0gImwiLCB4bGFiID0gIklEIiwgeWxhYiA9ICJTY29yZSIsIG1haW4gPSAiSUQgdnMuIFNjb3JlIikKCiMgQ3JlYXRlIGEgaGlzdG9ncmFtIG9mIEFnZSBkaXN0cmlidXRpb24KaGlzdChkYXRhJEFnZSwgeGxhYiA9ICJBZ2UiLCB5bGFiID0gIkZyZXF1ZW5jeSIsIG1haW4gPSAiQWdlIERpc3RyaWJ1dGlvbiIpCgojIENyZWF0ZSBhIHBpZSBjaGFydCBvZiBBZ2UgZGlzdHJpYnV0aW9uCmFnZV9mcmVxIDwtIHRhYmxlKGN1dChkYXRhJEFnZSwgYnJlYWtzID0gYygyMCwgMjUsIDMwLCA0MCkpKQpwaWUoYWdlX2ZyZXEsIGxhYmVscyA9IGMoIjIwLTI1IiwgIjI2LTMwIiwgIjMxLTQwIiksIG1haW4gPSAiQWdlIERpc3RyaWJ1dGlvbiIpCgojIENyZWF0ZSBhIGJveHBsb3Qgb2YgU2NvcmVzCmJveHBsb3QoZGF0YSRTY29yZSwgeGxhYiA9ICJTY29yZXMiLCBtYWluID0gIlNjb3JlIERpc3RyaWJ1dGlvbiIpCgojIENyZWF0ZSBhIGJhciBwbG90IG9mIFNjb3JlcyBieSBOYW1lCmJhcnBsb3QoZGF0YSRTY29yZSwgbmFtZXMuYXJnID0gZGF0YSROYW1lLCB4bGFiID0gIk5hbWUiLCB5bGFiID0gIlNjb3JlIiwgbWFpbiA9ICJJbmRpdmlkdWFsIFNjb3JlcyIpCgoKYGBgCgoKCiMjIFJlYWwgd29ybGQgZGF0YXNldCAtIElSSVMKYGBge3IsIGVjaG89RkFMU0V9CmlyaXMgPSByZWFkLmNzdignZGF0YXNldHMvaXJpcy5jc3YnKQppcmlzX2RhdGFzZXQgPSBpcmlzCmlyaXMKYGBgCgoKIyMgU3VtbWFyeSBvZiBpcmlzIGRhdGFzZXQKYGBge3IsIGVjaG8gPSBGQUxTRX0Kc3VtbWFyeShpcmlzKQpgYGAKCgoKCiMjIyBIaXN0cm9ncmFtIC0gRGlzdHJpYnV0aW9uCmBgYHtyLCBlY2hvPUZBTFNFfQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkocGxvdGx5KQojIGluc3RhbGwgaW5zdGFsbC5wYWNrYWdlcygiY29sb3JzcGFjZSIpIGlmIGVycm9yIG9jY3VycyAtPiBjb3VsZCBub3QgZmluZCBmdW5jdGlvbiAiZ2dwbG90IgoKcCA9IGdncGxvdChpcmlzLCBhZXMoeCA9IHNlcGFsLmxlbmd0aCkpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMSwgZmlsbCA9ICJsaWdodGJsdWUiLCBjb2xvciA9ICJibGFjayIpICsKICB0aGVtZV9taW5pbWFsKCkrCiAgbGFicyh0aXRsZSA9ICJIaXN0b2dyYW0gb2YgU2VwYWwgTGVuZ3RoIiwKICAgICAgIHggPSAiU2VwYWwgTGVuZ3RoIiwKICAgICAgIHkgPSAiRnJlcXVlbmN5IikKCiNnZ3Bsb3RseShwKQpwCmBgYAoKCiMjIFNjYXR0ZXIgcGxvdAoKYGBge3IsIGVjaG89RkFMU0V9CmdncGxvdChpcmlzLCBhZXMoeCA9IHNlcGFsLmxlbmd0aCwgeSA9IHNlcGFsLndpZHRoLCBjb2xvciA9IHZhcmlldHkpKSArCiAgZ2VvbV9wb2ludCgpICsKICBsYWJzKHRpdGxlID0gIlNjYXR0ZXIgUGxvdCBvZiBTZXBhbCBMZW5ndGggdnMuIFNlcGFsIFdpZHRoIiwKICAgICAgIHggPSAiU2VwYWwgTGVuZ3RoIiwKICAgICAgIHkgPSAiU2VwYWwgV2lkdGgiKQoKYGBgCgoKCgoKCgojIyBCb3ggcGxvdApgYGB7ciwgZWNobz1GQUxTRX0KCmRhdGEoaXJpcykKZ2dwbG90KGlyaXMsIGFlcyh4ID0gU3BlY2llcywgeSA9IFNlcGFsLkxlbmd0aCwgZmlsbCA9IFNwZWNpZXMpKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGxhYnModGl0bGUgPSAiQm94IFBsb3Qgb2YgU2VwYWwgTGVuZ3RoIGJ5IFNwZWNpZXMiLAogICAgICAgeCA9ICJTcGVjaWVzIiwKICAgICAgIHkgPSAiU2VwYWwgTGVuZ3RoIikKYGBgCgoKIyMgVmlvbGluZSBwbG90CmBgYHtyLCBlY2hvPUZBTFNFfQpnZ3Bsb3QoaXJpcywgYWVzKHggPSBTcGVjaWVzLCB5ID0gUGV0YWwuTGVuZ3RoLCBmaWxsID0gU3BlY2llcykpICsKICBnZW9tX3Zpb2xpbigpICsKICBsYWJzKHRpdGxlID0gIlZpb2xpbiBQbG90IG9mIFBldGFsIExlbmd0aCBieSBTcGVjaWVzIiwKICAgICAgIHggPSAiU3BlY2llcyIsCiAgICAgICB5ID0gIlBldGFsIExlbmd0aCIpCgpgYGAKCgojIyMgQ29ycmVsYXRpb24gTWF0cml4CmBgYHtyLCBlY2hvPUZBTFNFfQpjb3JfbWF0cml4IDwtIGNvcihpcmlzWywgMTo0XSkKcHJpbnQoY29yX21hdHJpeCkKCmBgYAojIyBIZWF0IG1hcCBvZiBjb3JyZWxhdGlvbiBtYXRyaXgKYGBge3IsIGVjaG89RkFMU0V9CmdnY29ycnBsb3QoY29yX21hdHJpeCwKICAgICAgICAgICBjb2xvcnMgPSBjKCIjNkQ5RUMxIiwgIndoaXRlIiwgIiNFNDY3MjYiKSwKICAgICAgICAgICBsYWIgPSBUUlVFKQpgYGAKCiMjIEhlYXQgbWFwIG9mIGNvcnJlbGF0aW9uIG1hdHJpeCAodmVyc2lvbiAyKQpgYGB7ciwgZWNobz1GQUxTRX0KbGlicmFyeShnZ2NvcnJwbG90KQoKZ2djb3JycGxvdChjb3JfbWF0cml4LCB0eXBlID0gImxvd2VyIiwgbGFiID0gVFJVRSkKCiMgcmVmOiBodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvZ2djb3JycGxvdC9yZWFkbWUvUkVBRE1FLmh0bWwKYGBgCgoKCiMjIEhlYXQgbWFwIG9mIGNvcnJlbGF0aW9uIG1hdHJpeCAodmVyc2lvbiAzKQoKYGBge3IsIGVjaG89RkFMU0V9CmdnY29ycnBsb3QoY29yX21hdHJpeCwgCiAgICAgICAgICAgdHlwZSA9ICJ1cHBlciIsCiAgICAgICAgICAgY29sb3JzID0gYygiIzZEOUVDMSIsICJ3aGl0ZSIsICIjRTQ2NzI2IiksCiAgICAgICAgICAgbGFiID0gVFJVRSkKYGBgCgojIyBQYXJpIHBsb3QKYGBge3IsIGVjaG89RkFMU0V9CmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShHR2FsbHkpCmdncGFpcnMoaXJpcywgYWVzKGNvbG91ciA9IFNwZWNpZXMpKQoKIyBodHRwczovL2dnb2JpLmdpdGh1Yi5pby9nZ2FsbHkvcmVmZXJlbmNlL2dncGFpcnMuaHRtbApgYGAKCiMgUmVncmVzc2lvbgoKIyMgTGluZWFyIFJlZ3Jlc3Npb24KCmBgYHtyLCBlY2hvPUZBTFNFfQpnZ3Bsb3QoaXJpcywgYWVzKHggPSBQZXRhbC5MZW5ndGgsIHkgPSBTZXBhbC5MZW5ndGgpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IFRSVUUsIGNvbG9yID0gImJsdWUiKSArCiAgbGFicyh0aXRsZSA9ICJMaW5lYXIgUmVncmVzc2lvbjogU2VwYWwgTGVuZ3RoIHZzLiBQZXRhbCBMZW5ndGgiLAogICAgICAgeCA9ICJQZXRhbCBMZW5ndGgiLAogICAgICAgeSA9ICJTZXBhbCBMZW5ndGgiKQoKYGBgCgojIyBMaW5lYXIgUmVncmVzc2lvbiBBbmFsYXlzaXMKYGBge3IsIGVjaG89RkFMU0V9CmxtX21vZGVsIDwtIGxtKFNlcGFsLkxlbmd0aCB+IFBldGFsLkxlbmd0aCwgZGF0YSA9IGlyaXMpCnN1bW1hcnkobG1fbW9kZWwpCgojIGh0dHBzOi8vZmVsaXBlcmVnby5naXRodWIuaW8vYmxvZy8yMDE1LzEwLzIzL0ludGVycHJldGluZy1Nb2RlbC1PdXRwdXQtSW4tUgpgYGAKCgoKIyMgUG9seW5vbWlhbCBSZWdyZXNzaW9uCgpgYGB7ciwgZWNobz1GQUxTRX0KZ2dwbG90KGlyaXMsIGFlcyh4ID0gUGV0YWwuTGVuZ3RoLCB5ID0gU2VwYWwuTGVuZ3RoLCBjb2xvcj1TcGVjaWVzKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgZm9ybXVsYT15fnBvbHkoeCwgMiksIGxldmVsPTAuOTUsIHNlID0gVFJVRSwgY29sb3IgPSAiYmx1ZSIsIGZpbGw9J2xpZ2h0Ymx1ZScpICsKICBsYWJzKHRpdGxlID0gIlBvbHlub21pYWwgUmVncmVzc2lvbjogU2VwYWwgTGVuZ3RoIHZzLiBQZXRhbCBMZW5ndGgiLAogICAgICAgeCA9ICJQZXRhbCBMZW5ndGgiLAogICAgICAgeSA9ICJTZXBhbCBMZW5ndGgiKQoKYGBgCgojIyBQb2x5bm9taWFsIFJlZ3Jlc3Npb24gYW5hbHlzaXMKYGBge3IsIGVjaG89RkFMU0V9CiNkZWZpbmUgZGF0YQp4IDwtIGlyaXMkUGV0YWwuTGVuZ3RoCnkgPC0gaXJpcyRTZXBhbC5MZW5ndGgKIAogCiNmaXQgcG9seW5vbWlhbCByZWdyZXNzaW9uIG1vZGVsCmZpdCA8LSBsbSh5IH4geCArIEkoeF4yKSArIEkoeF4zKSkKc3VtbWFyeShmaXQpIAoKYGBgCgojIyBNdWx0aXZhcmlhdGUgUG9seW5vbWlhbCBSZWdyZXNzaW9uCmBgYHtyLCBlY2hvPUZBTFNFfQojIExvYWQgbmVjZXNzYXJ5IGxpYnJhcmllcwpsaWJyYXJ5KHN0YXRzKQoKIyBMb2FkIHRoZSBpcmlzIGRhdGFzZXQgKGl0J3MgYnVpbHQtaW4pCmRhdGEoaXJpcykKCiMgUGVyZm9ybSBwb2x5bm9taWFsIHJlZ3Jlc3Npb24gKHF1YWRyYXRpYyBtb2RlbCkKcG9seV9tb2RlbCA8LSBsbShTZXBhbC5MZW5ndGggfiBwb2x5KFNlcGFsLldpZHRoLCAyKSArIHBvbHkoUGV0YWwuTGVuZ3RoLCAyKSArIHBvbHkoUGV0YWwuV2lkdGgsIDIpLCBkYXRhID0gaXJpcykKCiMgUHJpbnQgc3VtbWFyeSBvZiBwb2x5bm9taWFsIHJlZ3Jlc3Npb24Kc3VtbWFyeShwb2x5X21vZGVsKQoKYGBgCgoKCiMgQ2x1c3RlcmluZwoKCmBgYHtyLCBlY2hvPUZBTFNFfQojIExvYWQgbmVjZXNzYXJ5IGxpYnJhcmllcwpsaWJyYXJ5KHN0YXRzKQpsaWJyYXJ5KGdncGxvdDIpICAjIEZvciBkYXRhIHZpc3VhbGl6YXRpb24KCiMgTG9hZCB0aGUgaXJpcyBkYXRhc2V0IChpdCdzIGJ1aWx0LWluKQpkYXRhKGlyaXMpCgojIFNlbGVjdCBvbmx5IHRoZSBudW1lcmljIGNvbHVtbnMgZm9yIGNsdXN0ZXJpbmcKZGF0YV9mb3JfY2x1c3RlcmluZyA8LSBpcmlzWywgYygiU2VwYWwuTGVuZ3RoIiwgIlNlcGFsLldpZHRoIiwgIlBldGFsLkxlbmd0aCIsICJQZXRhbC5XaWR0aCIpXQoKIyBQZXJmb3JtIEstTWVhbnMgY2x1c3RlcmluZyB3aXRoIDMgY2x1c3RlcnMKayA8LSAzICAjIE51bWJlciBvZiBjbHVzdGVycwprbWVhbnNfcmVzdWx0IDwtIGttZWFucyhkYXRhX2Zvcl9jbHVzdGVyaW5nLCBjZW50ZXJzID0gaykKCgpgYGAKCgpgYGB7ciwgZWNobz1GQUxTRX0KbGlicmFyeShjbHVzdGVyKQpjbHVzcGxvdChpcmlzLCBrbWVhbnNfcmVzdWx0JGNsdXN0ZXIsIGNvbG9yPVQsIHNoYWRlPVQsIGxhYmVscz0wLCBsaW5lcz0wKQpgYGAKIyMjIENsdXN0ZXJpbmcgcmVzdWx0IGFuYWx5c2lzCmBgYHtyLCBlY2hvPUZBTFNFfQpwcmludChrbWVhbnNfcmVzdWx0KQpgYGAKCiMgQ2xhc3NpZmljYXRpb24KCiMjIFNWTSBNb2RlbApgYGB7ciwgZWNobz1GQUxTRX0KIyBMb2FkIG5lY2Vzc2FyeSBsaWJyYXJpZXMKbGlicmFyeShlMTA3MSkgICMgRm9yIFNWTQpsaWJyYXJ5KGNhcmV0KSAgICMgRm9yIG1vZGVsIGV2YWx1YXRpb24KbGlicmFyeShnZ3Bsb3QyKSAKbGlicmFyeShsYXR0aWNlKQoKIyBMb2FkIHRoZSBpcmlzIGRhdGFzZXQgKGl0J3MgYnVpbHQtaW4pCmRhdGEoaXJpcykKCiMgU3BsaXQgdGhlIGRhdGEgaW50byB0cmFpbmluZyBhbmQgdGVzdGluZyBzZXRzCnNldC5zZWVkKDEyMykKdHJhaW5faW5kaWNlcyA8LSBjcmVhdGVEYXRhUGFydGl0aW9uKGlyaXMkU3BlY2llcywgcCA9IDAuOCwgbGlzdCA9IEZBTFNFKQp0cmFpbl9kYXRhIDwtIGlyaXNbdHJhaW5faW5kaWNlcywgXQp0ZXN0X2RhdGEgPC0gaXJpc1stdHJhaW5faW5kaWNlcywgXQoKIyBUcmFpbiBhbiBTVk0gY2xhc3NpZmllciB3aXRoIGEgbGluZWFyIGtlcm5lbApzdm1fbW9kZWwgPC0gc3ZtKFNwZWNpZXMgfiBTZXBhbC5MZW5ndGggKyBTZXBhbC5XaWR0aCArIFBldGFsLkxlbmd0aCArIFBldGFsLldpZHRoLCBkYXRhID0gdHJhaW5fZGF0YSwga2VybmVsID0gImxpbmVhciIpCgojIFByZWRpY3QgdXNpbmcgdGhlIHRyYWluZWQgbW9kZWwKcHJlZGljdGlvbnMgPC0gcHJlZGljdChzdm1fbW9kZWwsIG5ld2RhdGEgPSB0ZXN0X2RhdGEpCgojIENvbmZ1c2lvbiBtYXRyaXgKY29uZl9tYXRyaXggPC0gY29uZnVzaW9uTWF0cml4KHByZWRpY3Rpb25zLCB0ZXN0X2RhdGEkU3BlY2llcykKCiMgUHJpbnQgY29uZnVzaW9uIG1hdHJpeApwcmludCgiQ29uZnVzaW9uIE1hdHJpeDoiKQpwcmludChjb25mX21hdHJpeCkKCiMgQWNjdXJhY3kKYWNjdXJhY3kgPC0gY29uZl9tYXRyaXgkb3ZlcmFsbFsiQWNjdXJhY3kiXQpwcmludChwYXN0ZSgiQWNjdXJhY3k6IiwgYWNjdXJhY3kpKQoKCmBgYAoKCiMjIyBTVk0gQ2xhc3NpZmljYXRpb24gY29uZnVzaW9uIG1hdHJpeApgYGB7ciwgZWNobz1GQUxTRX0KY20gPSBjb25mX21hdHJpeAoKcGx0IDwtIGFzLmRhdGEuZnJhbWUoY20kdGFibGUpCnBsdCRQcmVkaWN0aW9uIDwtIGZhY3RvcihwbHQkUHJlZGljdGlvbiwgbGV2ZWxzPXJldihsZXZlbHMocGx0JFByZWRpY3Rpb24pKSkKCmdncGxvdChwbHQsIGFlcyhQcmVkaWN0aW9uLFJlZmVyZW5jZSwgZmlsbD0gRnJlcSkpICsKICAgICAgICBnZW9tX3RpbGUoKSArIAogICAgICAgIGdlb21fdGV4dChhZXMobGFiZWw9RnJlcSkpICsKICAgICAgICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdz0id2hpdGUiLCBoaWdoPSJza3libHVlIikgKwogICAgICAgIGxhYnMoeCA9ICJSZWZlcmVuY2UiLAogICAgICAgICAgICAgeSA9ICJQcmVkaWN0aW9uIikgCgpgYGAKCgoKCgoKCiMgU3RhdGlzdGljYWwgQW5hbHlzaXMKCiMjIERhdGEgRGlzdHJpYnV0aW9uCmBgYHtyLCBlY2hvPUZBTFNFfQojIE5vcm1hbCBkaXN0cmlidXRpb24KaGlzdChpcmlzJFNlcGFsLkxlbmd0aCwgcHJvYmFiaWxpdHkgPSBUUlVFLCBtYWluID0gIkhpc3RvZ3JhbSBvZiBTZXBhbCBMZW5ndGgiKQpsaW5lcyhkZW5zaXR5KGlyaXMkU2VwYWwuTGVuZ3RoKSwgY29sID0gImJsdWUiKQpgYGAKCiMjIFQtdGVzdApgYGB7ciwgZWNobz1GQUxTRX0Kc2V0b3NhIDwtIGlyaXMkU2VwYWwuTGVuZ3RoW2lyaXMkU3BlY2llcyA9PSAic2V0b3NhIl0KdmlyZ2luaWNhIDwtIGlyaXMkU2VwYWwuTGVuZ3RoW2lyaXMkU3BlY2llcyA9PSAidmlyZ2luaWNhIl0KdF90ZXN0X3Jlc3VsdCA8LSB0LnRlc3Qoc2V0b3NhLCB2aXJnaW5pY2EpCnByaW50KHRfdGVzdF9yZXN1bHQpCgojIGh0dHBzOi8vd3d3LnN0YXRvbG9neS5vcmcvaW50ZXJwcmV0LXQtdGVzdC1yZXN1bHRzLWluLXIvCmBgYAoKCgojIyBBTk9WQQpgYGB7ciwgZWNobz1GQUxTRX0KYW5vdmFfcmVzdWx0IDwtIGFvdihTZXBhbC5MZW5ndGggfiBTcGVjaWVzLCBkYXRhID0gaXJpcykKc3VtbWFyeShhbm92YV9yZXN1bHQpCgpgYGAKCiMjIFR1a2V5J3MgcG9zdGhvYyB0ZXN0CmBgYHtyLCBlY2hvPUZBTFNFfQpwb3N0aG9jIDwtIFR1a2V5SFNEKGFub3ZhX3Jlc3VsdCkKcHJpbnQocG9zdGhvYykKCmBgYAojIyMgQ2hpLXNxdWFyZSB0ZXN0CmBgYHtyLCBlY2hvPUZBTFNFfQojIExvYWQgbmVjZXNzYXJ5IGxpYnJhcmllcwpsaWJyYXJ5KHN0YXRzKQoKIyBMb2FkIHRoZSBpcmlzIGRhdGFzZXQgKGl0J3MgYnVpbHQtaW4pCmRhdGEoaXJpcykKCiMgQ2hpLXNxdWFyZSB0ZXN0ICh0ZXN0aW5nIGluZGVwZW5kZW5jZSBiZXR3ZWVuIHNwZWNpZXMgYW5kIHBldGFsIGxlbmd0aCkKY2hpc3EudGVzdCh0YWJsZShpcmlzJFNwZWNpZXMsIGN1dChpcmlzJFBldGFsLkxlbmd0aCwgYnJlYWtzID0gYygxLCAyLCAzLCA0LCA1KSkpKQoKYGBgCgojIyBQcmluY2lwYWwgY29tcG9uZW50IGFuYWx5c2lzCmBgYHtyLCBlY2hvPUZBTFNFfQojIExvYWQgcmVxdWlyZWQgbGlicmFyeQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoc3RhdHMpCgppcmlzID0gcmVhZC5jc3YoJ0NsYXNzIDQvaXJpcy5jc3YnKQoKIyBBcHBseSBQQ0EKaXJpc19wY2EgPC0gcHJjb21wKGlyaXNbLCAtNV0sIGNlbnRlciA9IFRSVUUsIHNjYWxlID0gVFJVRSkKaXJpc19wY2EKc3VtbWFyeShpcmlzX3BjYSkKCiMgRXh0cmFjdCBQQyBzY29yZXMKcGNfc2NvcmVzIDwtIGFzLmRhdGEuZnJhbWUoaXJpc19wY2EkeFssIDE6Ml0pCgoKIyBDb21iaW5lIFBDIHNjb3JlcyB3aXRoIFNwZWNpZXMKcGNfZGF0YSA8LSBjYmluZChwY19zY29yZXMsIFNwZWNpZXMgPSBpcmlzJHZhcmlldHkpCgoKIyBQbG90IFBDQSAoMkQpCmdncGxvdChwY19kYXRhLCBhZXMoUEMxLCBQQzIsIGNvbG9yID0gU3BlY2llcykpICsKICBnZW9tX3BvaW50KCkgKwogIGxhYnModGl0bGUgPSAiUENBICgyRCkgb2YgSXJpcyBEYXRhc2V0IiwKICAgICAgIHggPSAiUHJpbmNpcGFsIENvbXBvbmVudCAxIiwKICAgICAgIHkgPSAiUHJpbmNpcGFsIENvbXBvbmVudCAyIikgKwogIHRoZW1lX21pbmltYWwoKQoKIyBodHRwOi8vd3d3LnN0aGRhLmNvbS9lbmdsaXNoL2FydGljbGVzLzMxLXByaW5jaXBhbC1jb21wb25lbnQtbWV0aG9kcy1pbi1yLXByYWN0aWNhbC1ndWlkZS8xMTgtcHJpbmNpcGFsLWNvbXBvbmVudC1hbmFseXNpcy1pbi1yLXByY29tcC12cy1wcmluY29tcC8KIyBodHRwczovL3d3dy5kYXRhY2FtcC5jb20vdHV0b3JpYWwvcGNhLWFuYWx5c2lzLXIKIyBodHRwOi8vd3d3LnN0aGRhLmNvbS9lbmdsaXNoL2FydGljbGVzLzMxLXByaW5jaXBhbC1jb21wb25lbnQtbWV0aG9kcy1pbi1yLXByYWN0aWNhbC1ndWlkZS8xMTItcGNhLXByaW5jaXBhbC1jb21wb25lbnQtYW5hbHlzaXMtZXNzZW50aWFscy8KYGBgCiMjIyBQQ0EgRGltZW5zaW9uIENvbnRyaWJ1dGlvbgpgYGB7ciwgZWNobz1GQUxTRX0KbGlicmFyeShmYWN0b2V4dHJhKQpmdml6X2VpZyhpcmlzX3BjYSwgYWRkbGFiZWxzID0gVFJVRSkKYGBgCgpgYGB7ciwgZWNobz1GQUxTRX0KIyBDb250cmlidXRpb25zIG9mIHZhcmlhYmxlcyB0byBQQzEKZnZpel9jb250cmliKGlyaXNfcGNhLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDEpCiMgQ29udHJpYnV0aW9ucyBvZiB2YXJpYWJsZXMgdG8gUEMyCmZ2aXpfY29udHJpYihpcmlzX3BjYSwgY2hvaWNlID0gInZhciIsIGF4ZXMgPSAyKQpgYGAKCiMjIyBQQ0EgRGltZW5zaW9uIENvbnRyaWJ1dGlvbiAoSGVhdCBtYXApCmBgYHtyLCBlY2hvPUZBTFNFfQp2YXIgPC0gZ2V0X3BjYV92YXIoaXJpc19wY2EpCgpsaWJyYXJ5KCJjb3JycGxvdCIpCmNvcnJwbG90KHZhciRjb3MyLCBpcy5jb3JyPUZBTFNFKQoKYGBgCgoKIyMjIFBDQSBEaW1lbnNpb24gQ29udHJpYnV0aW9uIChWZWN0b3IgbWFwKQpgYGB7ciwgZWNobz1GQUxTRX0KIyBHcmFwaCBvZiB0aGUgdmFyaWFibGVzCmZ2aXpfcGNhX3ZhcihpcmlzX3BjYSwgY29sLnZhciA9ICJjb250cmliIiwgIyBDb2xvciBieSBjb250cmlidXRpb25zIHRvIHRoZSBQQwogICAgICAgICAgICAgZ3JhZGllbnQuY29scyA9IGMoIiMwMEFGQkIiLCAiI0U3QjgwMCIsICIjRkM0RTA3IiksCiAgICAgICAgICAgICByZXBlbCA9IFRSVUUgKSAgICAjIEF2b2lkIHRleHQgb3ZlcmxhcHBpbmcpCmBgYAoKIyMjIFBDQSAyRCBwbG90IChzY2F0dGVyIHdpdGggbWFya2VkIGRhdGEgcG9pbnQpCmBgYHtyLCBlY2hvPUZBTFNFfQpmdml6X3BjYV9pbmQoaXJpc19wY2EsCiAgICAgICAgICAgICBjb2wuaW5kID0gImNvczIiLCAjIENvbG9yIGJ5IHRoZSBxdWFsaXR5IG9mIHJlcHJlc2VudGF0aW9uCiAgICAgICAgICAgICBncmFkaWVudC5jb2xzID0gYygiIzAwQUZCQiIsICIjRTdCODAwIiwgIiNGQzRFMDciKSwKICAgICAgICAgICAgIHJlcGVsID0gVFJVRSAgICAgIyBBdm9pZCB0ZXh0IG92ZXJsYXBwaW5nCiAgICAgICAgICAgICApCmBgYAoKCgojIyMgUENBIENsdXN0ZXJpbmcKCmBgYHtyLCBlY2hvPUZBTFNFfQpmdml6X3BjYV9pbmQoaXJpc19wY2EsCiAgICAgICAgICAgICBnZW9tLmluZCA9ICJwb2ludCIsICMgc2hvdyBwb2ludHMgb25seSAobmJ1dCBub3QgInRleHQiKQogICAgICAgICAgICAgY29sLmluZCA9IGlyaXMkdmFyaWV0eSwgIyBjb2xvciBieSBncm91cHMKICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjMDBBRkJCIiwgIiNFN0I4MDAiLCAiI0ZDNEUwNyIpLAogICAgICAgICAgICAgYWRkRWxsaXBzZXMgPSBUUlVFLCAjIENvbmNlbnRyYXRpb24gZWxsaXBzZXMKICAgICAgICAgICAgIGxlZ2VuZC50aXRsZSA9ICJHcm91cHMiCiAgICAgICAgICAgICApCmBgYAoKCgojIEludGVyYWN0aXZlIHBsb3RzCgpgYGB7ciwgZWNobz1GQUxTRX0KIyBMb2FkIHJlcXVpcmVkIGxpYnJhcnkKbGlicmFyeShwbG90bHkpCmlyaXMgPSByZWFkLmNzdignZGF0YXNldHMvaXJpcy5jc3YnKQoKIyBQbG90IDNEIFNjYXR0ZXIgUGxvdApwbG90X2x5KGRhdGEgPSBpcmlzLCB4ID0gfnNlcGFsLmxlbmd0aCwgeSA9IH5zZXBhbC53aWR0aCwgeiA9IH5wZXRhbC5sZW5ndGgsIGNvbG9yID0gfnZhcmlldHksCiAgICAgICAgdHlwZSA9ICJzY2F0dGVyM2QiLCBtb2RlID0gIm1hcmtlcnMiKSAlPiUKICBsYXlvdXQoc2NlbmUgPSBsaXN0KHhheGlzID0gbGlzdCh0aXRsZSA9ICdTZXBhbCBMZW5ndGgnKSwKICAgICAgICAgICAgICAgICAgICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICdTZXBhbCBXaWR0aCcpLAogICAgICAgICAgICAgICAgICAgICAgemF4aXMgPSBsaXN0KHRpdGxlID0gJ1BldGFsIExlbmd0aCcpKSwKICAgICAgICAgbWFyZ2luID0gbGlzdChsID0gMCwgciA9IDAsIGIgPSAwLCB0ID0gMCkpCgpgYGAKCgoKCgpgYGB7ciwgZWNobz1GQUxTRX0KIyBMb2FkIHJlcXVpcmVkIGxpYnJhcnkKbGlicmFyeShwbG90bHkpCgojIExvYWQgSXJpcyBkYXRhc2V0CmRhdGEoaXJpcykKCiMgMS4gU2NhdHRlciBQbG90CnNjYXR0ZXJfcGxvdCA8LSBwbG90X2x5KGlyaXMsIHggPSB+U2VwYWwuTGVuZ3RoLCB5ID0gflNlcGFsLldpZHRoLCBjb2xvciA9IH5TcGVjaWVzLCB0eXBlID0gInNjYXR0ZXIiLCBtb2RlID0gIm1hcmtlcnMiKSAlPiUKICBsYXlvdXQoeGF4aXMgPSBsaXN0KHRpdGxlID0gIlNlcGFsIExlbmd0aCIpLCB5YXhpcyA9IGxpc3QodGl0bGUgPSAiU2VwYWwgV2lkdGgiKSwgdGl0bGUgPSAiU2NhdHRlciBQbG90IikKc2NhdHRlcl9wbG90CgoKIyAyLiBCb3ggUGxvdApib3hfcGxvdCA8LSBwbG90X2x5KGlyaXMsIHggPSB+U3BlY2llcywgeSA9IH5QZXRhbC5MZW5ndGgsIHR5cGUgPSAiYm94IikgJT4lCiAgbGF5b3V0KHhheGlzID0gbGlzdCh0aXRsZSA9ICJTcGVjaWVzIiksIHlheGlzID0gbGlzdCh0aXRsZSA9ICJQZXRhbCBMZW5ndGgiKSwgdGl0bGUgPSAiQm94IFBsb3QiKQpib3hfcGxvdAoKCiMgMy4gVmlvbGluIFBsb3QKdmlvbGluX3Bsb3QgPC0gcGxvdF9seShpcmlzLCB4ID0gflNwZWNpZXMsIHkgPSB+UGV0YWwuV2lkdGgsIHR5cGUgPSAidmlvbGluIikgJT4lCiAgbGF5b3V0KHhheGlzID0gbGlzdCh0aXRsZSA9ICJTcGVjaWVzIiksIHlheGlzID0gbGlzdCh0aXRsZSA9ICJQZXRhbCBXaWR0aCIpLCB0aXRsZSA9ICJWaW9saW4gUGxvdCIpCnZpb2xpbl9wbG90CgoKIyA0LiBIaXN0b2dyYW0KaGlzdG9ncmFtX3Bsb3QgPC0gcGxvdF9seShpcmlzLCB4ID0gflNlcGFsLkxlbmd0aCwgdHlwZSA9ICJoaXN0b2dyYW0iKSAlPiUKICBsYXlvdXQoeGF4aXMgPSBsaXN0KHRpdGxlID0gIlNlcGFsIExlbmd0aCIpLCB5YXhpcyA9IGxpc3QodGl0bGUgPSAiRnJlcXVlbmN5IiksIHRpdGxlID0gIkhpc3RvZ3JhbSIpCmhpc3RvZ3JhbV9wbG90CgoKIyA1LiBIZWF0bWFwIG9mIENvcnJlbGF0aW9uIE1hdHJpeApjb3JyZWxhdGlvbl9tYXRyaXggPC0gY29yKGlyaXNbLCBjKCJTZXBhbC5MZW5ndGgiLCAiU2VwYWwuV2lkdGgiLCAiUGV0YWwuTGVuZ3RoIiwgIlBldGFsLldpZHRoIildKQpoZWF0bWFwX3Bsb3QgPC0gcGxvdF9seSh6ID0gY29ycmVsYXRpb25fbWF0cml4LCB0eXBlID0gImhlYXRtYXAiLCBjb2xvcnNjYWxlID0gIlZpcmlkaXMiKSAlPiUKICBsYXlvdXQoeGF4aXMgPSBsaXN0KHRpdGxlID0gY29sbmFtZXMoY29ycmVsYXRpb25fbWF0cml4KSksIHlheGlzID0gbGlzdCh0aXRsZSA9IGNvbG5hbWVzKGNvcnJlbGF0aW9uX21hdHJpeCkpLCB0aXRsZSA9ICJDb3JyZWxhdGlvbiBIZWF0bWFwIikKaGVhdG1hcF9wbG90CgoKCiMgNy4gTGluZSBQbG90IGFmdGVyIFNvcnRpbmcgYSBDb2x1bW4Kc29ydGVkX2RhdGEgPC0gaXJpc1tvcmRlcihpcmlzJFNlcGFsLkxlbmd0aCksIF0KbGluZV9wbG90IDwtIHBsb3RfbHkoc29ydGVkX2RhdGEsIHggPSB+U2VwYWwuTGVuZ3RoLCB5ID0gflNlcGFsLldpZHRoLCB0eXBlID0gInNjYXR0ZXIiLCBtb2RlID0gImxpbmVzIikgJT4lCiAgbGF5b3V0KHhheGlzID0gbGlzdCh0aXRsZSA9ICJTZXBhbCBMZW5ndGggKFNvcnRlZCkiKSwgeWF4aXMgPSBsaXN0KHRpdGxlID0gIlNlcGFsIFdpZHRoIiksIHRpdGxlID0gIkxpbmUgUGxvdCAoU29ydGVkKSIpCmxpbmVfcGxvdAoKCiMgRGlzcGxheSBwbG90cwojc3VicGxvdChzY2F0dGVyX3Bsb3QsIGJveF9wbG90LCB2aW9saW5fcGxvdCwgaGlzdG9ncmFtX3Bsb3QsIGhlYXRtYXBfcGxvdCwgYmFyX3Bsb3QsIGxpbmVfcGxvdCwgbnJvd3MgPSA0KQoKYGBgCgoKIyBCb251cyEKCiMjIDNEIHNpbmUgY3VydmUKCmBgYHtyLCBlY2hvID0gRkFMU0V9CiMgTG9hZCByZXF1aXJlZCBsaWJyYXJpZXMKbGlicmFyeShwbG90bHkpCgojIENyZWF0ZSBzYW1wbGUgZGF0YSBmb3IgdGhlIHN1cmZhY2UgcGxvdAp4IDwtIHNlcSgtNSwgNSwgbGVuZ3RoLm91dCA9IDEwMCkKeSA8LSBzZXEoLTUsIDUsIGxlbmd0aC5vdXQgPSAxMDApCnogPC0gb3V0ZXIoeCwgeSwgZnVuY3Rpb24oeCwgeSkgc2luKHNxcnQoeF4yICsgeV4yKSkgLyBzcXJ0KHheMiArIHleMikpCgojIERlZmluZSBhIGN1c3RvbSBjb2xvciBzY2FsZQpjb2xvcl9zY2FsZSA8LSBjKCIjNDQwMTU0IiwgIiM0ODI4NzgiLCAiIzNFNDk4OSIsICIjMzE2ODhFIiwgIiMyNjgzOEUiLCAiIzFGOUU4OSIsICIjMzVCNzc5IiwgIiM2RENENTkiLCAiI0I0REUyQyIsICIjRkRFNzI1IikKCiMgQ3JlYXRlIGEgM0Qgc3VyZmFjZSBwbG90CnBsb3RfbHkoeiA9IH56LCB4ID0gfngsIHkgPSB+eSwgdHlwZSA9ICJzdXJmYWNlIiwgY29sb3JzID0gY29sb3Jfc2NhbGUpICU+JQogIGxheW91dChzY2VuZSA9IGxpc3QoCiAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAnWC1heGlzJyksCiAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAnWS1heGlzJyksCiAgICB6YXhpcyA9IGxpc3QodGl0bGUgPSAnWi1heGlzJykKICApKQoKYGBgCgojIyBTdXBwb3J0IFZlY3RvciBSZWdyZXNzaW9uIFN1cmZhY2UgQ3VydmUKCmBgYHtyLCBlY2hvID0gRkFMU0V9CmxpYnJhcnkocmVzaGFwZTIpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHRpZHltb2RlbHMpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KGtlcm5sYWIpCmxpYnJhcnkocHJhY21hKSAjRm9yIG1lc2hncmlkKCkKCgpkYXRhKGlyaXMpCgptZXNoX3NpemUgPC0gLjAyCm1hcmdpbiA8LSAwCgpYIDwtIGlyaXMgJT4lIHNlbGVjdChTZXBhbC5XaWR0aCwgU2VwYWwuTGVuZ3RoKQoKeSA8LSBpcmlzICU+JSBzZWxlY3QoUGV0YWwuV2lkdGgpCgptb2RlbCA8LSBzdm1fcmJmKGNvc3QgPSAxLjApICU+JSAKICBzZXRfZW5naW5lKCJrZXJubGFiIikgJT4lIAogIHNldF9tb2RlKCJyZWdyZXNzaW9uIikgJT4lIAogIGZpdChQZXRhbC5XaWR0aCB+IFNlcGFsLldpZHRoICsgU2VwYWwuTGVuZ3RoLCBkYXRhID0gaXJpcykKCnhfbWluIDwtIG1pbihYJFNlcGFsLldpZHRoKSAtIG1hcmdpbgp4X21heCA8LSBtYXgoWCRTZXBhbC5XaWR0aCkgLSBtYXJnaW4KeV9taW4gPC0gbWluKFgkU2VwYWwuTGVuZ3RoKSAtIG1hcmdpbgp5X21heCA8LSBtYXgoWCRTZXBhbC5MZW5ndGgpIC0gbWFyZ2luCnhyYW5nZSA8LSBzZXEoeF9taW4sIHhfbWF4LCBtZXNoX3NpemUpCnlyYW5nZSA8LSBzZXEoeV9taW4sIHlfbWF4LCBtZXNoX3NpemUpCnh5IDwtIG1lc2hncmlkKHggPSB4cmFuZ2UsIHkgPSB5cmFuZ2UpCnh4IDwtIHh5JFgKeXkgPC0geHkkWQpkaW1fdmFsIDwtIGRpbSh4eCkKeHgxIDwtIG1hdHJpeCh4eCwgbGVuZ3RoKHh4KSwgMSkKeXkxIDwtIG1hdHJpeCh5eSwgbGVuZ3RoKHl5KSwgMSkKZmluYWwgPC0gY2JpbmQoeHgxLCB5eTEpCnByZWQgPC0gbW9kZWwgJT4lCiAgcHJlZGljdChmaW5hbCkKCnByZWQgPC0gcHJlZCQucHJlZApwcmVkIDwtIG1hdHJpeChwcmVkLCBkaW1fdmFsWzFdLCBkaW1fdmFsWzJdKQoKZmlnIDwtIHBsb3RfbHkoaXJpcywgeCA9IH5TZXBhbC5XaWR0aCwgeSA9IH5TZXBhbC5MZW5ndGgsIHogPSB+UGV0YWwuV2lkdGggKSAlPiUgCiAgYWRkX21hcmtlcnMoc2l6ZSA9IDUpICU+JSAKICBhZGRfc3VyZmFjZSh4PXhyYW5nZSwgeT15cmFuZ2UsIHo9cHJlZCwgYWxwaGEgPSAwLjY1LCB0eXBlID0gJ21lc2gzZCcsIG5hbWUgPSAncHJlZF9zdXJmYWNlJykKZmlnCgoKYGBgCgoKIyBPdXIgbmV4dCBjb3Vyc2UKCiFbUmVnaXN0ZXI6IGh0dHBzOi8vZm9ybXMuZ2xlL1JWTnRTNVh3cFQ1VXVIUnM3XShDb3Vyc2VzIEZseWVyLnBuZykKCiMgQ2VydGlmaWNhdGUKIVtXZSBwcm92aWRlIGNlcnRpZmljYXRlIHVwb24gY291cnNlIGNvbXBsZXRpb25dKENlcnRpZmljYXRlIFIucG5nKQoKCg==