1 Introduction

For this assignment, we will be looking at a data set for a survey done on student experience and satisfaction. This survey asks students questions regarding their experience in college. These questions include gathering information on a student’s academic background, their year level and credit status, along with their engagement in learning their class material both inside and outside of school. This survey also asks students about which campus resources they have used throughout their time in college. The survey looks at the satisfaction rating students have regarding the college, along with their information to gather data about the students at the college and their opinions regarding their experience and their satisfaction level regarding their college.

For this project, we will take a look at this survey data and begin with analyzing the data set along with conducting some exploratory data analysis steps to start. Then, we will perform internal reliability analysis of the subscales in the survey. We will also perform principal component analysis for the two subsets of student experience and student satisfaction. We will consider some potential consulting questions which could be drawn from this survey data for future projects on this survey data set.

1.1 Data Description

Let’s read in the survey data set from GitHub. We will call the data set as “survey”.

survey <- read.csv("https://raw.githubusercontent.com/JosieGallop/STA490/refs/heads/main/student-satisfaction-survey.csv")

As we can see, the survey data set contains 332 observations of 121 variables. The variables represent the different questions within the survey.

2 Exploratory Data Analysis

We will perform some exploratory data analysis to gain a better understanding of the survey data set, and to further prepare the data for additional analysis related to reliability and validation of the survey data.

2.1 Dealing with the Missing Values

For the first step of our exploratory data analysis, we will check for and fix any missing value concerns within our data set. First, let’s check to see if there indeed are some missing values which we will need to fix.

colSums(is.na(survey))
     q1      q2      q3     q41     q42     q43     q44     q45     q46     q47 
      0       0       0       0       0       0       0       0       0       0 
    q48     q49    q410    q411    q412    q413    q414    q415    q416    q417 
      0       0       0       0       0       0       0       0       0       0 
   q418    q419    q420    q421     q51     q52     q53     q54     q55     q56 
      0       0       0       0       0       0       0       0       0       0 
    q61     q62     q63      q7     q81     q82     q83     q84     q85     q86 
      0       0       0       0       0       0       0       0       0       0 
    q87     q88     q89     q91     q92     q93     q94     q95     q96     q97 
      0       0       0       0       0       0       0       0       0       0 
   q101    q102    q103    q104    q105    q106    q107    q108    q109   q1010 
      0       0       0       0       0       0       0       0       0       0 
  q1011   q1012   q1013   q1014   q1015  q111.1  q111.2  q111.3  q112.1  q112.2 
      0       0       0       0       0       0       0       0       0       0 
 q112.3  q113.1  q113.2  q113.3  q114.1  q114.2  q114.3  q115.1  q115.2  q115.3 
      0       0       0       0       0       0       0       0       0       0 
 q116.1  q116.2  q116.3  q117.1  q117.2  q117.3  q118.1  q118.2  q118.3  q119.1 
      0       0       0       0       0       0       0       0       0       0 
 q119.2  q119.3 q1110.1 q1110.2 q1110.3 q1111.1 q1111.2 q1111.3    q121    q122 
      0       0       0       0       0       0       0       0       0       0 
   q123    q124    q125    q131    q132    q133    q134    q135    q136     q14 
      0       0       0       0       0       0       0       0       0       0 
    q15     q16     q17     q18     q19     q20     q21     q22     q23     q24 
      0       0       0       0       0       0       0       0       0       0 
    q25 
      0 

It turns out that there are exactly zero missing values in this survey data set, meaning that we do not have any missing values to worry about. So, we do not have to do any imputation to fix any missing values, because we do not have any missing values in the survey data set.

3 Splitting the Survey Data Set

We have two main components of our survey, the student experience portion and the student satisfaction portion. We will split these apart for our further analysis of the survey data set.

3.1 Student Experience Portion

First, let’s separate the student experience portion of the survey data set. The student experience portion looks at the personal and academic background of students at the college. This information gives some background details about the student along with their experience at the college. The goal of this survey is to see how these experience factors may affect a student’s college satisfaction.

The student experience portion takes up majority of the survey questionarre. So, this student experience portion will contain the majority of the questions within the survey data set.

experience = survey[, 1:112]

Now we have created the experience subset of our survey data.

3.2 Student Satisfaction Portion

The second portion of the survey data set is the student satisfaction questions. These questions look at a student’s overall satisfaction and feelings towards their college. There are only two questions within the survey questionarre which ask about student satisfaction related topics, so this subset portion of the data set will be much smaller than the student experience portion of the data set.

satisfaction = survey[, 113:114]

Now we have created the satisfaction subset of our survey data.

4 Reliability Analysis

Now that we have prepared the data set, we will perform internal reliability and validity assessments in order to further investigate the survey data set.

4.1 Student Experience Reliability Analysis

First, let’s look at the correlation plots for the student experience subset of our survey data set.

The experience portion of the survey is incredibly large, so let’s take a smaller subset of this portion in order to make our correlation plot easier to interpret. We will look at questions 5, 6, and 7 for this subset. We will call this subset “experience.1”.

experience.1 = survey[, 25:34]

Now, let’s look at the correlation plot for this subset of the student experience portion of the survey.

M=cor(experience.1)
corrplot.mixed(M, lower.col = "purple", upper = "ellipse", number.cex = .7, tl.cex = 0.7)

We can see some moderate correlation between the student experience survey datafrom how some of the ellipses do appear to be moderately long and stretched in their shape.

4.2 Student Satisfaction Reliability Analysis

Next, let’s look at the correlation plots for the student satisfaction subset of the survey data set.

M=cor(satisfaction)
corrplot.mixed(M, lower.col = "purple", upper = "ellipse", number.cex = .7, tl.cex = 0.7)

The satisfaction portion of the survey was so short compared to the student experience portion, that it is quite hard to judge the correlation due to the lack of entries on our plot. The ellipse does appear to be noticeably streched and long, indicating some moderate correlation does indeed exist.

5 Cronbach Alpha Levels

Next, we will calculate the Cronbach alpha levels for each of our two subsets, along with their 95% confidence intervals. This will allow us to assess the reliability of the two subsets.

5.1 Student Experience

First, let’s calculate the Cronbach alpha level for the student experience portion of the survey data set.

cronbach.e = as.numeric(alpha(experience.1)$total[1])
Some items ( q61 q62 q63 q7 ) were negatively correlated with the first principal component and 
probably should be reversed.  
To do this, run the function again with the 'check.keys=TRUE' option
CI.e = cronbach.alpha.CI(alpha=cronbach.e, n=332, items=10, conf.level = 0.95)
CI.comp = cbind(LCI = CI.e[1], alpha = cronbach.e, UCI =CI.e[2])
row.names(CI.comp) = ""
pander(CI.comp, caption="Confidence Interval of Cronbach Alpha")
Confidence Interval of Cronbach Alpha
LCI alpha UCI
0.4298 0.5119 0.5866

The Cronbach alpha level for the student experience portion of the survey data set is 0.5119, 95% CI [0.4298, 0.5866]. This value of 0.5119 is not that high, but it is not incredibly low either. This indicates that their is moderate, but not great, reliability.

5.2 Student Satisfaction

Next, let’s calculate the Cronbach alpha level for the student satisfaction portion of the survey data set.

cronbach.s = as.numeric(alpha(satisfaction)$total[1])
CI.s = cronbach.alpha.CI(alpha=cronbach.s, n=332, items=2, conf.level = 0.95)
CI.comp = cbind(LCI = CI.s[1], alpha = cronbach.s, UCI =CI.s[2])
row.names(CI.comp) = ""
pander(CI.comp, caption="Confidence Interval of Cronbach Alpha")
Confidence Interval of Cronbach Alpha
LCI alpha UCI
0.4854 0.5853 0.6658

The Cronbach alpha level for the student experience portion of the survey data set is 0.5853, 95% CI [0.4298, 0.6658]. TOnce again, this value of 0.5853 is not that high, but it is not incredibly low either. This indicates that their is moderate, but not great, reliability. This value is slightly higher than that of the student experience subset, indicating the student satisfaction subset has slightly better reliability of the two.

6 Principal Component Analysis

Now we will perform principal component analysis for the survey data set. We will find the PCA twice, for both the experience subset and the satisfaction subset of the student survey data.

We will define functions for our principal component analysis in order to allow us to create scree plots to help visualize our data.

This first function will allow us to begin with our principal component analysis, and to later create the plots we will use to further analyze our findings.

My.plotnScree = function(mat, legend = TRUE, method ="factors", main){

    ev <- eigen(cor(mat))    
    ap <- parallel(subject=nrow(mat),var=ncol(mat), rep=5000,cent=.05)
    nScree = nScree(x=ev$values, aparallel=ap$eigen$qevpea, model=method)  
    
    if (!inherits(nScree, "nScree")) 
        stop("Method is only for nScree objects")
    if (nScree$Model == "components") 
        nkaiser = "Eigenvalues > mean: n = "
    if (nScree$Model == "factors") 
      nkaiser = "Eigenvalues > zero: n = "
    
    xlab = nScree$Model
    ylab = "Eigenvalues"
    
    par(col = 1, pch = 18)
    par(mfrow = c(1, 1))
    eig <- nScree$Analysis$Eigenvalues
    k <- 1:length(eig)
    plot(1:length(eig), eig, type="b", main = main, 
        xlab = xlab, ylab = ylab, ylim=c(0, 1.2*max(eig)))
    #
    nk <- length(eig)
    noc <- nScree$Components$noc
    vp.p <- lm(eig[c(noc + 1, nk)] ~ k[c(noc + 1, nk)])
    x <- sum(c(1, 1) * coef(vp.p))
    y <- sum(c(1, nk) * coef(vp.p))
    par(col = 10)
    lines(k[c(1, nk)], c(x, y))
    par(col = 11, pch = 20)
    lines(1:nk, nScree$Analysis$Par.Analysis, type = "b")
    if (legend == TRUE) {
        leg.txt <- c(paste(nkaiser, nScree$Components$nkaiser), 
                   c(paste("Parallel Analysis: n = ", nScree$Components$nparallel)), 
                   c(paste("Optimal Coordinates: n = ", nScree$Components$noc)), 
                   c(paste("Acceleration Factor: n = ", nScree$Components$naf))
                   )
        legend("topright", legend = leg.txt, pch = c(18, 20, NA, NA), 
                           text.col = c(1, 3, 2, 4), 
                           col = c(1, 3, 2, 4), bty="n", cex=0.7)
    }
    naf <- nScree$Components$naf
    text(x = noc, y = eig[noc], label = " (OC)", cex = 0.7, 
        adj = c(0, 0), col = 2)
    text(x = naf + 1, y = eig[naf + 1], label = " (AF)", 
        cex = 0.7, adj = c(0, 0), col = 4)
}

This next function will help us with analyzing the various factors in the PCA. This will allow us to analyze the factor loadings and the proportion variance that can be explained by each factor. This will allow us to see the proportion of the total variation which can be explained by each principal component in the model.

My.loadings.var <- function(mat, nfct, method="fa"){
    if(method == "fa"){ 
     f1 <- factanal(mat, factors = nfct,  rotation = "varimax")
     x <- loadings(f1)
     vx <- colSums(x^2)
     varSS = rbind('SS loadings' = vx,
            'Proportion Var' = vx/nrow(x),
           'Cumulative Var' = cumsum(vx/nrow(x)))
     weight = f1$loadings[] 
   } else if (method == "pca"){
     pca <- prcomp(mat, center = TRUE, scale = TRUE)
     varSS = summary(pca)$importance[,1:nfct]
     weight = pca$rotation[,1:nfct]
  }
    list(Loadings = weight, Prop.Var = varSS)
}

6.1 Student Experience PCA

First, we will perform PCA for the student experience subset of the survey data set.

To avoid from having too many principal components since the studnt experience portion of the survey is so large, we will use the experience.1 subset of the student experience survey questions which was created earlier during the validity analysis.

Let’s calculate the principal components for the experience.1 data set.

experience.pca <- prcomp(experience.1, center = TRUE, scale = TRUE)

Now, we will find the factor loading of the PCA for the student experience survey questions.

kable(round(experience.pca$rotation, 2), caption="Factor Loadings of the PCA")
Factor Loadings of the PCA
PC1 PC2 PC3 PC4 PC5 PC6 PC7 PC8 PC9 PC10
q51 0.26 -0.09 -0.15 0.60 -0.57 0.29 0.18 -0.30 0.04 0.03
q52 0.41 -0.07 0.05 0.09 -0.16 -0.54 0.08 0.43 0.55 -0.09
q53 0.44 -0.09 -0.05 -0.01 -0.04 -0.32 0.07 0.10 -0.79 -0.24
q54 0.41 -0.02 -0.02 -0.28 0.18 -0.07 -0.18 -0.71 0.25 -0.35
q55 0.44 -0.10 -0.02 -0.21 0.10 0.05 -0.01 -0.07 -0.03 0.85
q56 0.39 -0.15 -0.08 -0.03 0.22 0.67 -0.23 0.44 0.07 -0.26
q61 -0.10 -0.66 -0.07 -0.04 0.30 0.03 0.66 -0.06 0.06 -0.07
q62 -0.01 -0.32 0.80 -0.27 -0.41 0.13 -0.07 -0.01 -0.04 -0.05
q63 -0.17 -0.60 -0.08 0.34 0.11 -0.22 -0.65 -0.05 -0.03 0.08
q7 -0.14 -0.22 -0.56 -0.56 -0.53 0.01 -0.09 0.08 0.03 -0.04

We can see that we have ten total principal components for the student experience data.

kable(summary(experience.pca)$importance, caption="The Importance of Each Principal Component")
The Importance of Each Principal Component
PC1 PC2 PC3 PC4 PC5 PC6 PC7 PC8 PC9 PC10
Standard deviation 1.903139 1.224847 0.9956294 0.9782884 0.9071515 0.7291144 0.7027027 0.6709049 0.5693246 0.5540031
Proportion of Variance 0.362190 0.150030 0.0991300 0.0957000 0.0822900 0.0531600 0.0493800 0.0450100 0.0324100 0.0306900
Cumulative Proportion 0.362190 0.512220 0.6113500 0.7070500 0.7893400 0.8425000 0.8918800 0.9369000 0.9693100 1.0000000

The first PC accounts for around 36.22% of the total variation. The first two PCs account for around 51.22% of the total variation. The first three PCs account for around 61.14% of the total variation.

6.1.1 Scree Plot

Let’s take a look at the scree plot for the student experience survey portion.

My.plotnScree(mat=experience.1, legend = TRUE, method ="components", 
              main="Determination of Number of Components\n Student Experience (Positive)")

As we can see, we have ten principal components just like we saw before in the analysis portion. The elbow of the scree plot appears to occur around when our components equals two. So this would be the ideal value of components to choose for further analysis on the student experience survey data.

6.1.2 Student Experience Distribution Histogram

Next, we can look at a historgram of the distribution of the student experience index.

pca <- prcomp(experience.1, center = TRUE, scale = TRUE)
se.idx = pca$x[,1]
hist(se.idx,
main="Distribution of Student Experience Index",
breaks = seq(min(se.idx), max(se.idx), length=9),
xlab="Self-compassion Index",
xlim=range(se.idx),
border="purple",
col="lightblue",
freq=FALSE
)

As we can see, the student experience index appears to be normally distributed without any skew or outliers present.

6.2 Student Satisfaction PCA

Now, we will perform PCA again, this time for the student satisfaction subset of the survey data set.

satisfaction.pca <- prcomp(satisfaction, center = TRUE, scale = TRUE)

Now, we will find the factor loading of the PCA for the student satisfaction survey questions.

kable(round(satisfaction.pca$rotation, 2), caption="Factor Loadings of the PCA")
Factor Loadings of the PCA
PC1 PC2
q17 0.71 -0.71
q18 0.71 0.71

We can see that we have two total principal components for the student experience data.

kable(summary(satisfaction.pca)$importance, caption="The Importance of Each Principal Component")
The Importance of Each Principal Component
PC1 PC2
Standard deviation 1.231695 0.6949298
Proportion of Variance 0.758540 0.2414600
Cumulative Proportion 0.758540 1.0000000

The first PC accounts for around 75.85% of the total variation. The first two PCs account for 100% of the total variation.

6.2.1 Student Satisfaction Distribution Histogram

Next, we can look at a historgram of the distribution of the student satisfaction index.

pca <- prcomp(satisfaction, center = TRUE, scale = TRUE)
sat.idx = pca$x[,1]
hist(sat.idx,
main="Distribution of Student Experience Index",
breaks = seq(min(sat.idx), max(sat.idx), length=9),
xlab="Self-compassion Index",
xlim=range(sat.idx),
border="purple",
col="lightblue",
freq=FALSE
)

As we can see, the student satisfaction index does not appear to be normally distributed. Instead, the distribution appears to be noticeably skewed to the right, with some potential outliers present on the right tail of the graph.

7 Concluslion and Recommendations

Overall, the principal component analysis allowed us to further analysis and better understand the survey data set. For further recommendations for this project, something which stood out is how long the student experience portion of the survey is in comparison to the student satisfaction portion of the survey. In the survey, there only appeared to be two questions which directly related to student satisfaction.

These two student satisfaction questions were questions 17 and 18, with those being: “17. Would you recommend our School of Business to a friend or family member? 1 -Yes, 2 - No.” and “18. How would you evaluate your entire educational experience at our school? 1 -Excellent, 2 - Good, 3 - Fair, 4 - Poor”.

This student satisfaction portion of the survey was incredibly short, and led to it being impossible to create a scree plot for the student satisfaction portion as we would need three or more prinicpal components in order to do so, but we only had two principal components for this subset of the survey data set.

So, the main recommendation I would make for future projects is to expand the student satisfaction portion of the data set to have more questions, in order to provide for further analysis of these survey questions.

8 Project Questions

Lastly, we will now look at some potential project questions based upon the analysis of the survey data set and the results that were found.

Some potential questions include:

  • Which factors of student experience showed the strongest influence on student satisfaction?

  • Did these particular factors with the strongest influence on satisfaction show stronger reliability when compared to the others?

  • Do students appear to be mostly satisfied with their school experience?

  • How can we analysis the relationship between the principal components in order to learn more about the revelant factors in relation to a student’s overall experience and satisfaction in college?

For this project, I would be interesting in looking into particularly the topic of which student experience factors have the greatest significance or effect on a student’s satisfaction with their college experience. This would be helpful because it would give specific factors for college faculty or advisors to look out for in their students in order to help them have a more positive and satisfactory experience during their time in college.

I think it would be interesting to see if these particular factors with stronger influence on a student’s satisfaction have stronger reliability. It would be interesting to compare the reliability results of these particular factors to see if their appears stronger or weaker than the average. This would help to see if these findings truly are reliable or not.

Additionally, we could use the findings in the principal component analysis to further investigate the survey data set. We could look into the relationships between the various principal components in order to learn more about the relationships between various factors in student experience and satisfaction. It would also be interesting to use which loading factors had the highest importance, in order to create models based upon these specific factors in order to see their importance and influence on overall student experience and satisfaction.

LS0tDQp0aXRsZTogIlN1cnZleSBBbmFseXNpczogUHJpbmNpcGFsIENvbXBvbmVudCBBbmFseXNpcyINCmF1dGhvcjogIkpvc2llIEdhbGxvcCINCmRhdGU6ICIyMDI1LTA0LTE2Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIHRvY19mbG9hdDogeWVzDQogICAgZmlnX3dpZHRoOiA2DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdG9jX2NvbGxhcHNlZDogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgc21vb3RoX3Njcm9sbDogeWVzDQogICAgdGhlbWU6IGx1bWVuDQogIHdvcmRfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIGtlZXBfbWQ6IHllcw0KICBwZGZfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlDQotLS0NCg0KYGBgez1odG1sfQ0KDQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KDQovKiBDYXNjYWRpbmcgU3R5bGUgU2hlZXRzIChDU1MpIGlzIGEgc3R5bGVzaGVldCBsYW5ndWFnZSB1c2VkIHRvIGRlc2NyaWJlIHRoZSBwcmVzZW50YXRpb24gb2YgYSBkb2N1bWVudCB3cml0dGVuIGluIEhUTUwgb3IgWE1MLiBpdCBpcyBhIHNpbXBsZSBtZWNoYW5pc20gZm9yIGFkZGluZyBzdHlsZSAoZS5nLiwgZm9udHMsIGNvbG9ycywgc3BhY2luZykgdG8gV2ViIGRvY3VtZW50cy4gKi8NCg0KaDEudGl0bGUgeyAgLyogVGl0bGUgLSBmb250IHNwZWNpZmljYXRpb25zIG9mIHRoZSByZXBvcnQgdGl0bGUgKi8NCiAgZm9udC1zaXplOiAyNHB4Ow0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQp9DQpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgZm9yIGF1dGhvcnMgICovDQogIGZvbnQtc2l6ZTogMjBweDsNCiAgZm9udC1mYW1pbHk6IHN5c3RlbS11aTsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmg0LmRhdGUgeyAvKiBIZWFkZXIgNCAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgZm9yIHRoZSBkYXRlICAqLw0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiBzeXN0ZW0tdWk7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDEgeyAvKiBIZWFkZXIgMSAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgZm9yIGxldmVsIDEgc2VjdGlvbiB0aXRsZSAgKi8NCiAgICBmb250LXNpemU6IDIycHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDIgeyAvKiBIZWFkZXIgMiAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgZm9yIGxldmVsIDIgc2VjdGlvbiB0aXRsZSAqLw0KICAgIGZvbnQtc2l6ZTogMjBweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IC8qIEhlYWRlciAzIC0gZm9udCBzcGVjaWZpY2F0aW9ucyBvZiBsZXZlbCAzIHNlY3Rpb24gdGl0bGUgICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmg0IHsgLyogSGVhZGVyIDQgLSBmb250IHNwZWNpZmljYXRpb25zIG9mIGxldmVsIDQgc2VjdGlvbiB0aXRsZSAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KYm9keSB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KLmhpZ2hsaWdodG1lIHsgYmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7IH0NCg0KcCB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KPC9zdHlsZT4NCmBgYA0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQojIERldGVjdCwgaW5zdGFsbCwgYW5kIGxvYWQgcGFja2FnZXMgaWYgbmVlZGVkLg0KaWYgKCFyZXF1aXJlKCJrbml0ciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpDQogICBsaWJyYXJ5KGtuaXRyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJsZWFmbGV0IikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImxlYWZsZXQiKQ0KICAgbGlicmFyeShsZWFmbGV0KQ0KfQ0KaWYgKCFyZXF1aXJlKCJFbnZTdGF0cyIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJFbnZTdGF0cyIpDQogICBsaWJyYXJ5KEVudlN0YXRzKQ0KfQ0KaWYgKCFyZXF1aXJlKCJNQVNTIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoIk1BU1MiKQ0KICAgbGlicmFyeShNQVNTKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwaHl0b29scyIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJwaHl0b29scyIpDQogICBsaWJyYXJ5KHBoeXRvb2xzKQ0KfQ0KaWYoIXJlcXVpcmUoImRwbHlyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImRwbHlyIikNCiAgIGxpYnJhcnkoZHBseXIpDQp9DQppZighcmVxdWlyZSgidGlkeXZlcnNlIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpDQogICBsaWJyYXJ5KHRpZHl2ZXJzZSkNCn0NCmlmKCFyZXF1aXJlKCJHR2FsbHkiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiR0dhbGx5IikNCiAgIGxpYnJhcnkoR0dhbGx5KQ0KfQ0KaWYgKCFyZXF1aXJlKCJHUEFyb3RhdGlvbiIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJHUEFyb3RhdGlvbiIpDQogICBsaWJyYXJ5KEdQQXJvdGF0aW9uKQ0KfQ0KaWYgKCFyZXF1aXJlKCJuRmFjdG9ycyIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJuRmFjdG9ycyIpDQogICBsaWJyYXJ5KG5GYWN0b3JzKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwYXJhbWV0ZXJzIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInBhcmFtZXRlcnMiKQ0KICAgbGlicmFyeShwYXJhbWV0ZXJzKQ0KfQ0KaWYgKCFyZXF1aXJlKCJjb3JycGxvdCIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJjb3JycGxvdCIpDQogICBsaWJyYXJ5KGNvcnJwbG90KQ0KfQ0KaWYgKCFyZXF1aXJlKCJnZ2NvcnJwbG90IikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImdnY29ycnBsb3QiKQ0KICAgbGlicmFyeShnZ2NvcnJwbG90KQ0KfQ0KaWYgKCFyZXF1aXJlKCJnZ2ZvcnRpZnkiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiZ2dmb3J0aWZ5IikNCiAgIGxpYnJhcnkoZ2dmb3J0aWZ5KQ0KfQ0KaWYgKCFyZXF1aXJlKCJnZ3Bsb3QyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQ0KICAgbGlicmFyeShnZ3Bsb3QyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJDQ0EiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiQ0NBIikNCiAgIGxpYnJhcnkoQ0NBKQ0KfQ0KaWYgKCFyZXF1aXJlKCJvbHNyciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJvbHNyciIpDQogICBsaWJyYXJ5KG9sc3JyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJjb2Nyb24iKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiY29jcm9uIikNCiAgIGxpYnJhcnkoY29jcm9uKQ0KfQ0KaWYoIXJlcXVpcmUoInBhbmRlciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJwYW5kZXIiKQ0KICAgbGlicmFyeShwYW5kZXIpDQp9DQppZighcmVxdWlyZSgibWljZSIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJtaWNlIikNCiAgIGxpYnJhcnkobWljZSkNCn0NCmlmKCFyZXF1aXJlKCJtbGJlbmNoIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoIm1sYmVuY2giKQ0KICAgbGlicmFyeShtbGJlbmNoKQ0KfQ0KaWYoIXJlcXVpcmUoInBzeWNoIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInBzeWNoIikNCiAgIGxpYnJhcnkocHN5Y2gpDQp9DQppZighcmVxdWlyZSgiYnJvb20ubWl4ZWQiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiYnJvb20ubWl4ZWQiKQ0KICAgbGlicmFyeShicm9vbS5taXhlZCkNCn0NCmlmKCFyZXF1aXJlKCJHR2FsbHkiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiR0dhbGx5IikNCiAgIGxpYnJhcnkoR0dhbGx5KQ0KfQ0KaWYoIXJlcXVpcmUoImNhcmV0IikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImNhcmV0IikNCiAgIGxpYnJhcnkoY2FyZXQpDQp9DQppZiAoIXJlcXVpcmUoInBST0MiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygicFJPQyIpDQogICBsaWJyYXJ5KHBST0MpDQp9DQojIFNwZWNpZmljYXRpb25zIG9mIG91dHB1dHMgb2YgY29kZSBpbiBjb2RlIGNodW5rcw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgIyBpbmNsdWRlIGNvZGUgY2h1bmsgaW4gdGhlIG91dHB1dCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlDQogICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLCAgIyBTb21ldGltZXMsIHlvdXIgY29kZSBtYXkgcHJvZHVjZSBhICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBtZXNzYWdlcywgeW91IGNhbiBjaG9vc2UgdG8gaW5jbHVkZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHdhcm5pbmcgbWVzc2FnZXMgaW4gdGhlIG91dHB1dCBmaWxlLiANCiAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsICANCiAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVFJVRSwgICAjIHlvdSBjYW4gYWxzbyBkZWNpZGUgd2hldGhlciB0byAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluY2x1ZGUgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0aGUgb3V0cHV0IGluIHRoZSBvdXRwdXQgZmlsZS4NCiAgICAgICAgICAgICAgICAgICBjb21tZW50ID0gTkEsICAgICAjIFN1cHByZXNzIGhhc2gtdGFncyBpbiB0aGUgb3V0cHV0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMuDQogICAgICAgICAgICAgICAgICAgZmlnLmFsaWduPSdjZW50ZXInLCANCiAgICAgICAgICAgICAgICAgICBmaWcucG9zID0gJ2h0Jw0KICAgICAgICAgICAgICAgICAgICAgICkgICANCmBgYA0KDQojIEludHJvZHVjdGlvbg0KDQpGb3IgdGhpcyBhc3NpZ25tZW50LCB3ZSB3aWxsIGJlIGxvb2tpbmcgYXQgYSBkYXRhIHNldCBmb3IgYSBzdXJ2ZXkgZG9uZSBvbiBzdHVkZW50IGV4cGVyaWVuY2UgYW5kIHNhdGlzZmFjdGlvbi4gVGhpcyBzdXJ2ZXkgYXNrcyBzdHVkZW50cyBxdWVzdGlvbnMgcmVnYXJkaW5nIHRoZWlyIGV4cGVyaWVuY2UgaW4gY29sbGVnZS4gVGhlc2UgcXVlc3Rpb25zIGluY2x1ZGUgZ2F0aGVyaW5nIGluZm9ybWF0aW9uIG9uIGEgc3R1ZGVudCdzIGFjYWRlbWljIGJhY2tncm91bmQsIHRoZWlyIHllYXIgbGV2ZWwgYW5kIGNyZWRpdCBzdGF0dXMsIGFsb25nIHdpdGggdGhlaXIgZW5nYWdlbWVudCBpbiBsZWFybmluZyB0aGVpciBjbGFzcyBtYXRlcmlhbCBib3RoIGluc2lkZSBhbmQgb3V0c2lkZSBvZiBzY2hvb2wuIFRoaXMgc3VydmV5IGFsc28gYXNrcyBzdHVkZW50cyBhYm91dCB3aGljaCBjYW1wdXMgcmVzb3VyY2VzIHRoZXkgaGF2ZSB1c2VkIHRocm91Z2hvdXQgdGhlaXIgdGltZSBpbiBjb2xsZWdlLiBUaGUgc3VydmV5IGxvb2tzIGF0IHRoZSBzYXRpc2ZhY3Rpb24gcmF0aW5nIHN0dWRlbnRzIGhhdmUgcmVnYXJkaW5nIHRoZSBjb2xsZWdlLCBhbG9uZyB3aXRoIHRoZWlyIGluZm9ybWF0aW9uIHRvIGdhdGhlciBkYXRhIGFib3V0IHRoZSBzdHVkZW50cyBhdCB0aGUgY29sbGVnZSBhbmQgdGhlaXIgb3BpbmlvbnMgcmVnYXJkaW5nIHRoZWlyIGV4cGVyaWVuY2UgYW5kIHRoZWlyIHNhdGlzZmFjdGlvbiBsZXZlbCByZWdhcmRpbmcgdGhlaXIgY29sbGVnZS4gDQoNCkZvciB0aGlzIHByb2plY3QsIHdlIHdpbGwgdGFrZSBhIGxvb2sgYXQgdGhpcyBzdXJ2ZXkgZGF0YSBhbmQgYmVnaW4gd2l0aCBhbmFseXppbmcgdGhlIGRhdGEgc2V0IGFsb25nIHdpdGggY29uZHVjdGluZyBzb21lIGV4cGxvcmF0b3J5IGRhdGEgYW5hbHlzaXMgc3RlcHMgdG8gc3RhcnQuIFRoZW4sIHdlIHdpbGwgcGVyZm9ybSBpbnRlcm5hbCByZWxpYWJpbGl0eSBhbmFseXNpcyBvZiB0aGUgc3Vic2NhbGVzIGluIHRoZSBzdXJ2ZXkuIFdlIHdpbGwgYWxzbyBwZXJmb3JtIHByaW5jaXBhbCBjb21wb25lbnQgYW5hbHlzaXMgZm9yIHRoZSB0d28gc3Vic2V0cyBvZiBzdHVkZW50IGV4cGVyaWVuY2UgYW5kIHN0dWRlbnQgc2F0aXNmYWN0aW9uLiBXZSB3aWxsIGNvbnNpZGVyIHNvbWUgcG90ZW50aWFsIGNvbnN1bHRpbmcgcXVlc3Rpb25zIHdoaWNoIGNvdWxkIGJlIGRyYXduIGZyb20gdGhpcyBzdXJ2ZXkgZGF0YSBmb3IgZnV0dXJlIHByb2plY3RzIG9uIHRoaXMgc3VydmV5IGRhdGEgc2V0LiANCg0KDQojIyBEYXRhIERlc2NyaXB0aW9uDQoNCkxldCdzIHJlYWQgaW4gdGhlIHN1cnZleSBkYXRhIHNldCBmcm9tIEdpdEh1Yi4gV2Ugd2lsbCBjYWxsIHRoZSBkYXRhIHNldCBhcyAic3VydmV5Ii4gDQoNCmBgYHtyfQ0Kc3VydmV5IDwtIHJlYWQuY3N2KCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vSm9zaWVHYWxsb3AvU1RBNDkwL3JlZnMvaGVhZHMvbWFpbi9zdHVkZW50LXNhdGlzZmFjdGlvbi1zdXJ2ZXkuY3N2IikNCmBgYA0KDQpBcyB3ZSBjYW4gc2VlLCB0aGUgc3VydmV5IGRhdGEgc2V0IGNvbnRhaW5zIDMzMiBvYnNlcnZhdGlvbnMgb2YgMTIxIHZhcmlhYmxlcy4gVGhlIHZhcmlhYmxlcyByZXByZXNlbnQgdGhlIGRpZmZlcmVudCBxdWVzdGlvbnMgd2l0aGluIHRoZSBzdXJ2ZXkuIA0KDQoNCg0KDQojIEV4cGxvcmF0b3J5IERhdGEgQW5hbHlzaXMNCg0KV2Ugd2lsbCBwZXJmb3JtIHNvbWUgZXhwbG9yYXRvcnkgZGF0YSBhbmFseXNpcyB0byBnYWluIGEgYmV0dGVyIHVuZGVyc3RhbmRpbmcgb2YgdGhlIHN1cnZleSBkYXRhIHNldCwgYW5kIHRvIGZ1cnRoZXIgcHJlcGFyZSB0aGUgZGF0YSBmb3IgYWRkaXRpb25hbCBhbmFseXNpcyByZWxhdGVkIHRvIHJlbGlhYmlsaXR5IGFuZCB2YWxpZGF0aW9uIG9mIHRoZSBzdXJ2ZXkgZGF0YS4gDQoNCg0KIyMgRGVhbGluZyB3aXRoIHRoZSBNaXNzaW5nIFZhbHVlcw0KDQpGb3IgdGhlIGZpcnN0IHN0ZXAgb2Ygb3VyIGV4cGxvcmF0b3J5IGRhdGEgYW5hbHlzaXMsIHdlIHdpbGwgY2hlY2sgZm9yIGFuZCBmaXggYW55IG1pc3NpbmcgdmFsdWUgY29uY2VybnMgd2l0aGluIG91ciBkYXRhIHNldC4gRmlyc3QsIGxldCdzIGNoZWNrIHRvIHNlZSBpZiB0aGVyZSBpbmRlZWQgYXJlIHNvbWUgbWlzc2luZyB2YWx1ZXMgd2hpY2ggd2Ugd2lsbCBuZWVkIHRvIGZpeC4NCg0KYGBge3J9DQpjb2xTdW1zKGlzLm5hKHN1cnZleSkpDQpgYGANCg0KSXQgdHVybnMgb3V0IHRoYXQgdGhlcmUgYXJlIGV4YWN0bHkgemVybyBtaXNzaW5nIHZhbHVlcyBpbiB0aGlzIHN1cnZleSBkYXRhIHNldCwgbWVhbmluZyB0aGF0IHdlIGRvIG5vdCBoYXZlIGFueSBtaXNzaW5nIHZhbHVlcyB0byB3b3JyeSBhYm91dC4gU28sIHdlIGRvIG5vdCBoYXZlIHRvIGRvIGFueSBpbXB1dGF0aW9uIHRvIGZpeCBhbnkgbWlzc2luZyB2YWx1ZXMsIGJlY2F1c2Ugd2UgZG8gbm90IGhhdmUgYW55IG1pc3NpbmcgdmFsdWVzIGluIHRoZSBzdXJ2ZXkgZGF0YSBzZXQuDQoNCg0KDQoNCiMgU3BsaXR0aW5nIHRoZSBTdXJ2ZXkgRGF0YSBTZXQNCg0KV2UgaGF2ZSB0d28gbWFpbiBjb21wb25lbnRzIG9mIG91ciBzdXJ2ZXksIHRoZSBzdHVkZW50IGV4cGVyaWVuY2UgcG9ydGlvbiBhbmQgdGhlIHN0dWRlbnQgc2F0aXNmYWN0aW9uIHBvcnRpb24uIFdlIHdpbGwgc3BsaXQgdGhlc2UgYXBhcnQgZm9yIG91ciBmdXJ0aGVyIGFuYWx5c2lzIG9mIHRoZSBzdXJ2ZXkgZGF0YSBzZXQuDQoNCg0KIyMgU3R1ZGVudCBFeHBlcmllbmNlIFBvcnRpb24NCg0KRmlyc3QsIGxldCdzIHNlcGFyYXRlIHRoZSBzdHVkZW50IGV4cGVyaWVuY2UgcG9ydGlvbiBvZiB0aGUgc3VydmV5IGRhdGEgc2V0LiBUaGUgc3R1ZGVudCBleHBlcmllbmNlIHBvcnRpb24gbG9va3MgYXQgdGhlIHBlcnNvbmFsIGFuZCBhY2FkZW1pYyBiYWNrZ3JvdW5kIG9mIHN0dWRlbnRzIGF0IHRoZSBjb2xsZWdlLiBUaGlzIGluZm9ybWF0aW9uIGdpdmVzIHNvbWUgYmFja2dyb3VuZCBkZXRhaWxzIGFib3V0IHRoZSBzdHVkZW50IGFsb25nIHdpdGggdGhlaXIgZXhwZXJpZW5jZSBhdCB0aGUgY29sbGVnZS4gVGhlIGdvYWwgb2YgdGhpcyBzdXJ2ZXkgaXMgdG8gc2VlIGhvdyB0aGVzZSBleHBlcmllbmNlIGZhY3RvcnMgbWF5IGFmZmVjdCBhIHN0dWRlbnQncyBjb2xsZWdlIHNhdGlzZmFjdGlvbi4gDQoNClRoZSBzdHVkZW50IGV4cGVyaWVuY2UgcG9ydGlvbiB0YWtlcyB1cCBtYWpvcml0eSBvZiB0aGUgc3VydmV5IHF1ZXN0aW9uYXJyZS4gU28sIHRoaXMgc3R1ZGVudCBleHBlcmllbmNlIHBvcnRpb24gd2lsbCBjb250YWluIHRoZSBtYWpvcml0eSBvZiB0aGUgcXVlc3Rpb25zIHdpdGhpbiB0aGUgc3VydmV5IGRhdGEgc2V0Lg0KDQpgYGB7cn0NCmV4cGVyaWVuY2UgPSBzdXJ2ZXlbLCAxOjExMl0NCmBgYA0KDQpOb3cgd2UgaGF2ZSBjcmVhdGVkIHRoZSBleHBlcmllbmNlIHN1YnNldCBvZiBvdXIgc3VydmV5IGRhdGEuIA0KDQoNCg0KIyMgU3R1ZGVudCBTYXRpc2ZhY3Rpb24gUG9ydGlvbg0KDQpUaGUgc2Vjb25kIHBvcnRpb24gb2YgdGhlIHN1cnZleSBkYXRhIHNldCBpcyB0aGUgc3R1ZGVudCBzYXRpc2ZhY3Rpb24gcXVlc3Rpb25zLiBUaGVzZSBxdWVzdGlvbnMgbG9vayBhdCBhIHN0dWRlbnQncyBvdmVyYWxsIHNhdGlzZmFjdGlvbiBhbmQgZmVlbGluZ3MgdG93YXJkcyB0aGVpciBjb2xsZWdlLiBUaGVyZSBhcmUgb25seSB0d28gcXVlc3Rpb25zIHdpdGhpbiB0aGUgc3VydmV5IHF1ZXN0aW9uYXJyZSB3aGljaCBhc2sgYWJvdXQgc3R1ZGVudCBzYXRpc2ZhY3Rpb24gcmVsYXRlZCB0b3BpY3MsIHNvIHRoaXMgc3Vic2V0IHBvcnRpb24gb2YgdGhlIGRhdGEgc2V0IHdpbGwgYmUgbXVjaCBzbWFsbGVyIHRoYW4gdGhlIHN0dWRlbnQgZXhwZXJpZW5jZSBwb3J0aW9uIG9mIHRoZSBkYXRhIHNldC4NCg0KYGBge3J9DQpzYXRpc2ZhY3Rpb24gPSBzdXJ2ZXlbLCAxMTM6MTE0XQ0KYGBgDQoNCk5vdyB3ZSBoYXZlIGNyZWF0ZWQgdGhlIHNhdGlzZmFjdGlvbiBzdWJzZXQgb2Ygb3VyIHN1cnZleSBkYXRhLiANCg0KDQoNCiMgUmVsaWFiaWxpdHkgQW5hbHlzaXMNCg0KTm93IHRoYXQgd2UgaGF2ZSBwcmVwYXJlZCB0aGUgZGF0YSBzZXQsIHdlIHdpbGwgcGVyZm9ybSBpbnRlcm5hbCByZWxpYWJpbGl0eSBhbmQgdmFsaWRpdHkgYXNzZXNzbWVudHMgaW4gb3JkZXIgdG8gZnVydGhlciBpbnZlc3RpZ2F0ZSB0aGUgc3VydmV5IGRhdGEgc2V0Lg0KDQoNCiMjIFN0dWRlbnQgRXhwZXJpZW5jZSBSZWxpYWJpbGl0eSBBbmFseXNpcw0KDQpGaXJzdCwgbGV0J3MgbG9vayBhdCB0aGUgY29ycmVsYXRpb24gcGxvdHMgZm9yIHRoZSBzdHVkZW50IGV4cGVyaWVuY2Ugc3Vic2V0IG9mIG91ciBzdXJ2ZXkgZGF0YSBzZXQuDQoNClRoZSBleHBlcmllbmNlIHBvcnRpb24gb2YgdGhlIHN1cnZleSBpcyBpbmNyZWRpYmx5IGxhcmdlLCBzbyBsZXQncyB0YWtlIGEgc21hbGxlciBzdWJzZXQgb2YgdGhpcyBwb3J0aW9uIGluIG9yZGVyIHRvIG1ha2Ugb3VyIGNvcnJlbGF0aW9uIHBsb3QgZWFzaWVyIHRvIGludGVycHJldC4gV2Ugd2lsbCBsb29rIGF0IHF1ZXN0aW9ucyA1LCA2LCBhbmQgNyBmb3IgdGhpcyBzdWJzZXQuIFdlIHdpbGwgY2FsbCB0aGlzIHN1YnNldCAiZXhwZXJpZW5jZS4xIi4NCg0KDQpgYGB7cn0NCmV4cGVyaWVuY2UuMSA9IHN1cnZleVssIDI1OjM0XQ0KYGBgDQoNCk5vdywgbGV0J3MgbG9vayBhdCB0aGUgY29ycmVsYXRpb24gcGxvdCBmb3IgdGhpcyBzdWJzZXQgb2YgdGhlIHN0dWRlbnQgZXhwZXJpZW5jZSBwb3J0aW9uIG9mIHRoZSBzdXJ2ZXkuDQoNCmBgYHtyfQ0KTT1jb3IoZXhwZXJpZW5jZS4xKQ0KY29ycnBsb3QubWl4ZWQoTSwgbG93ZXIuY29sID0gInB1cnBsZSIsIHVwcGVyID0gImVsbGlwc2UiLCBudW1iZXIuY2V4ID0gLjcsIHRsLmNleCA9IDAuNykNCmBgYA0KDQpXZSBjYW4gc2VlIHNvbWUgbW9kZXJhdGUgY29ycmVsYXRpb24gYmV0d2VlbiB0aGUgc3R1ZGVudCBleHBlcmllbmNlIHN1cnZleSBkYXRhZnJvbSBob3cgc29tZSBvZiB0aGUgZWxsaXBzZXMgZG8gYXBwZWFyIHRvIGJlIG1vZGVyYXRlbHkgbG9uZyBhbmQgc3RyZXRjaGVkIGluIHRoZWlyIHNoYXBlLg0KDQoNCg0KIyMgU3R1ZGVudCBTYXRpc2ZhY3Rpb24gUmVsaWFiaWxpdHkgQW5hbHlzaXMNCg0KTmV4dCwgbGV0J3MgbG9vayBhdCB0aGUgY29ycmVsYXRpb24gcGxvdHMgZm9yIHRoZSBzdHVkZW50IHNhdGlzZmFjdGlvbiBzdWJzZXQgb2YgdGhlIHN1cnZleSBkYXRhIHNldC4NCg0KYGBge3J9DQpNPWNvcihzYXRpc2ZhY3Rpb24pDQpjb3JycGxvdC5taXhlZChNLCBsb3dlci5jb2wgPSAicHVycGxlIiwgdXBwZXIgPSAiZWxsaXBzZSIsIG51bWJlci5jZXggPSAuNywgdGwuY2V4ID0gMC43KQ0KYGBgDQoNClRoZSBzYXRpc2ZhY3Rpb24gcG9ydGlvbiBvZiB0aGUgc3VydmV5IHdhcyBzbyBzaG9ydCBjb21wYXJlZCB0byB0aGUgc3R1ZGVudCBleHBlcmllbmNlIHBvcnRpb24sIHRoYXQgaXQgaXMgcXVpdGUgaGFyZCB0byBqdWRnZSB0aGUgY29ycmVsYXRpb24gZHVlIHRvIHRoZSBsYWNrIG9mIGVudHJpZXMgb24gb3VyIHBsb3QuIFRoZSBlbGxpcHNlIGRvZXMgYXBwZWFyIHRvIGJlIG5vdGljZWFibHkgc3RyZWNoZWQgYW5kIGxvbmcsIGluZGljYXRpbmcgc29tZSBtb2RlcmF0ZSBjb3JyZWxhdGlvbiBkb2VzIGluZGVlZCBleGlzdC4gDQoNCg0KDQojIENyb25iYWNoIEFscGhhIExldmVscw0KDQpOZXh0LCB3ZSB3aWxsIGNhbGN1bGF0ZSB0aGUgQ3JvbmJhY2ggYWxwaGEgbGV2ZWxzIGZvciBlYWNoIG9mIG91ciB0d28gc3Vic2V0cywgYWxvbmcgd2l0aCB0aGVpciA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbHMuIFRoaXMgd2lsbCBhbGxvdyB1cyB0byBhc3Nlc3MgdGhlIHJlbGlhYmlsaXR5IG9mIHRoZSB0d28gc3Vic2V0cy4NCg0KIyMgU3R1ZGVudCBFeHBlcmllbmNlDQoNCkZpcnN0LCBsZXQncyBjYWxjdWxhdGUgdGhlIENyb25iYWNoIGFscGhhIGxldmVsIGZvciB0aGUgc3R1ZGVudCBleHBlcmllbmNlIHBvcnRpb24gb2YgdGhlIHN1cnZleSBkYXRhIHNldC4NCg0KYGBge3J9DQpjcm9uYmFjaC5lID0gYXMubnVtZXJpYyhhbHBoYShleHBlcmllbmNlLjEpJHRvdGFsWzFdKQ0KQ0kuZSA9IGNyb25iYWNoLmFscGhhLkNJKGFscGhhPWNyb25iYWNoLmUsIG49MzMyLCBpdGVtcz0xMCwgY29uZi5sZXZlbCA9IDAuOTUpDQpDSS5jb21wID0gY2JpbmQoTENJID0gQ0kuZVsxXSwgYWxwaGEgPSBjcm9uYmFjaC5lLCBVQ0kgPUNJLmVbMl0pDQpyb3cubmFtZXMoQ0kuY29tcCkgPSAiIg0KcGFuZGVyKENJLmNvbXAsIGNhcHRpb249IkNvbmZpZGVuY2UgSW50ZXJ2YWwgb2YgQ3JvbmJhY2ggQWxwaGEiKQ0KYGBgDQoNClRoZSBDcm9uYmFjaCBhbHBoYSBsZXZlbCBmb3IgdGhlIHN0dWRlbnQgZXhwZXJpZW5jZSBwb3J0aW9uIG9mIHRoZSBzdXJ2ZXkgZGF0YSBzZXQgaXMgMC41MTE5LCA5NSUgQ0kgWzAuNDI5OCwgMC41ODY2XS4gVGhpcyB2YWx1ZSBvZiAwLjUxMTkgaXMgbm90IHRoYXQgaGlnaCwgYnV0IGl0IGlzIG5vdCBpbmNyZWRpYmx5IGxvdyBlaXRoZXIuIFRoaXMgaW5kaWNhdGVzIHRoYXQgdGhlaXIgaXMgbW9kZXJhdGUsIGJ1dCBub3QgZ3JlYXQsIHJlbGlhYmlsaXR5LiANCg0KDQoNCiMjIFN0dWRlbnQgU2F0aXNmYWN0aW9uDQoNCk5leHQsIGxldCdzIGNhbGN1bGF0ZSB0aGUgQ3JvbmJhY2ggYWxwaGEgbGV2ZWwgZm9yIHRoZSBzdHVkZW50IHNhdGlzZmFjdGlvbiBwb3J0aW9uIG9mIHRoZSBzdXJ2ZXkgZGF0YSBzZXQuDQoNCmBgYHtyfQ0KY3JvbmJhY2gucyA9IGFzLm51bWVyaWMoYWxwaGEoc2F0aXNmYWN0aW9uKSR0b3RhbFsxXSkNCkNJLnMgPSBjcm9uYmFjaC5hbHBoYS5DSShhbHBoYT1jcm9uYmFjaC5zLCBuPTMzMiwgaXRlbXM9MiwgY29uZi5sZXZlbCA9IDAuOTUpDQpDSS5jb21wID0gY2JpbmQoTENJID0gQ0kuc1sxXSwgYWxwaGEgPSBjcm9uYmFjaC5zLCBVQ0kgPUNJLnNbMl0pDQpyb3cubmFtZXMoQ0kuY29tcCkgPSAiIg0KcGFuZGVyKENJLmNvbXAsIGNhcHRpb249IkNvbmZpZGVuY2UgSW50ZXJ2YWwgb2YgQ3JvbmJhY2ggQWxwaGEiKQ0KYGBgDQoNClRoZSBDcm9uYmFjaCBhbHBoYSBsZXZlbCBmb3IgdGhlIHN0dWRlbnQgZXhwZXJpZW5jZSBwb3J0aW9uIG9mIHRoZSBzdXJ2ZXkgZGF0YSBzZXQgaXMgMC41ODUzLCA5NSUgQ0kgWzAuNDI5OCwgMC42NjU4XS4gVE9uY2UgYWdhaW4sIHRoaXMgdmFsdWUgb2YgMC41ODUzIGlzIG5vdCB0aGF0IGhpZ2gsIGJ1dCBpdCBpcyBub3QgaW5jcmVkaWJseSBsb3cgZWl0aGVyLiBUaGlzIGluZGljYXRlcyB0aGF0IHRoZWlyIGlzIG1vZGVyYXRlLCBidXQgbm90IGdyZWF0LCByZWxpYWJpbGl0eS4gVGhpcyB2YWx1ZSBpcyBzbGlnaHRseSBoaWdoZXIgdGhhbiB0aGF0IG9mIHRoZSBzdHVkZW50IGV4cGVyaWVuY2Ugc3Vic2V0LCBpbmRpY2F0aW5nIHRoZSBzdHVkZW50IHNhdGlzZmFjdGlvbiBzdWJzZXQgaGFzIHNsaWdodGx5IGJldHRlciByZWxpYWJpbGl0eSBvZiB0aGUgdHdvLg0KDQoNCg0KDQoNCiMgUHJpbmNpcGFsIENvbXBvbmVudCBBbmFseXNpcw0KDQpOb3cgd2Ugd2lsbCBwZXJmb3JtIHByaW5jaXBhbCBjb21wb25lbnQgYW5hbHlzaXMgZm9yIHRoZSBzdXJ2ZXkgZGF0YSBzZXQuIFdlIHdpbGwgZmluZCB0aGUgUENBIHR3aWNlLCBmb3IgYm90aCB0aGUgZXhwZXJpZW5jZSBzdWJzZXQgYW5kIHRoZSBzYXRpc2ZhY3Rpb24gc3Vic2V0IG9mIHRoZSBzdHVkZW50IHN1cnZleSBkYXRhLiANCg0KV2Ugd2lsbCBkZWZpbmUgZnVuY3Rpb25zIGZvciBvdXIgcHJpbmNpcGFsIGNvbXBvbmVudCBhbmFseXNpcyBpbiBvcmRlciB0byBhbGxvdyB1cyB0byBjcmVhdGUgc2NyZWUgcGxvdHMgdG8gaGVscCB2aXN1YWxpemUgb3VyIGRhdGEuDQoNClRoaXMgZmlyc3QgZnVuY3Rpb24gd2lsbCBhbGxvdyB1cyB0byBiZWdpbiB3aXRoIG91ciBwcmluY2lwYWwgY29tcG9uZW50IGFuYWx5c2lzLCBhbmQgdG8gbGF0ZXIgY3JlYXRlIHRoZSBwbG90cyB3ZSB3aWxsIHVzZSB0byBmdXJ0aGVyIGFuYWx5emUgb3VyIGZpbmRpbmdzLg0KDQpgYGB7cn0NCk15LnBsb3RuU2NyZWUgPSBmdW5jdGlvbihtYXQsIGxlZ2VuZCA9IFRSVUUsIG1ldGhvZCA9ImZhY3RvcnMiLCBtYWluKXsNCg0KICAgIGV2IDwtIGVpZ2VuKGNvcihtYXQpKSAgICANCiAgICBhcCA8LSBwYXJhbGxlbChzdWJqZWN0PW5yb3cobWF0KSx2YXI9bmNvbChtYXQpLCByZXA9NTAwMCxjZW50PS4wNSkNCiAgICBuU2NyZWUgPSBuU2NyZWUoeD1ldiR2YWx1ZXMsIGFwYXJhbGxlbD1hcCRlaWdlbiRxZXZwZWEsIG1vZGVsPW1ldGhvZCkgIA0KICAgIA0KICAgIGlmICghaW5oZXJpdHMoblNjcmVlLCAiblNjcmVlIikpIA0KICAgICAgICBzdG9wKCJNZXRob2QgaXMgb25seSBmb3IgblNjcmVlIG9iamVjdHMiKQ0KICAgIGlmIChuU2NyZWUkTW9kZWwgPT0gImNvbXBvbmVudHMiKSANCiAgICAgICAgbmthaXNlciA9ICJFaWdlbnZhbHVlcyA+IG1lYW46IG4gPSAiDQogICAgaWYgKG5TY3JlZSRNb2RlbCA9PSAiZmFjdG9ycyIpIA0KICAgICAgbmthaXNlciA9ICJFaWdlbnZhbHVlcyA+IHplcm86IG4gPSAiDQogICAgDQogICAgeGxhYiA9IG5TY3JlZSRNb2RlbA0KICAgIHlsYWIgPSAiRWlnZW52YWx1ZXMiDQogICAgDQogICAgcGFyKGNvbCA9IDEsIHBjaCA9IDE4KQ0KICAgIHBhcihtZnJvdyA9IGMoMSwgMSkpDQogICAgZWlnIDwtIG5TY3JlZSRBbmFseXNpcyRFaWdlbnZhbHVlcw0KICAgIGsgPC0gMTpsZW5ndGgoZWlnKQ0KICAgIHBsb3QoMTpsZW5ndGgoZWlnKSwgZWlnLCB0eXBlPSJiIiwgbWFpbiA9IG1haW4sIA0KICAgICAgICB4bGFiID0geGxhYiwgeWxhYiA9IHlsYWIsIHlsaW09YygwLCAxLjIqbWF4KGVpZykpKQ0KICAgICMNCiAgICBuayA8LSBsZW5ndGgoZWlnKQ0KICAgIG5vYyA8LSBuU2NyZWUkQ29tcG9uZW50cyRub2MNCiAgICB2cC5wIDwtIGxtKGVpZ1tjKG5vYyArIDEsIG5rKV0gfiBrW2Mobm9jICsgMSwgbmspXSkNCiAgICB4IDwtIHN1bShjKDEsIDEpICogY29lZih2cC5wKSkNCiAgICB5IDwtIHN1bShjKDEsIG5rKSAqIGNvZWYodnAucCkpDQogICAgcGFyKGNvbCA9IDEwKQ0KICAgIGxpbmVzKGtbYygxLCBuayldLCBjKHgsIHkpKQ0KICAgIHBhcihjb2wgPSAxMSwgcGNoID0gMjApDQogICAgbGluZXMoMTpuaywgblNjcmVlJEFuYWx5c2lzJFBhci5BbmFseXNpcywgdHlwZSA9ICJiIikNCiAgICBpZiAobGVnZW5kID09IFRSVUUpIHsNCiAgICAgICAgbGVnLnR4dCA8LSBjKHBhc3RlKG5rYWlzZXIsIG5TY3JlZSRDb21wb25lbnRzJG5rYWlzZXIpLCANCiAgICAgICAgICAgICAgICAgICBjKHBhc3RlKCJQYXJhbGxlbCBBbmFseXNpczogbiA9ICIsIG5TY3JlZSRDb21wb25lbnRzJG5wYXJhbGxlbCkpLCANCiAgICAgICAgICAgICAgICAgICBjKHBhc3RlKCJPcHRpbWFsIENvb3JkaW5hdGVzOiBuID0gIiwgblNjcmVlJENvbXBvbmVudHMkbm9jKSksIA0KICAgICAgICAgICAgICAgICAgIGMocGFzdGUoIkFjY2VsZXJhdGlvbiBGYWN0b3I6IG4gPSAiLCBuU2NyZWUkQ29tcG9uZW50cyRuYWYpKQ0KICAgICAgICAgICAgICAgICAgICkNCiAgICAgICAgbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGxlZy50eHQsIHBjaCA9IGMoMTgsIDIwLCBOQSwgTkEpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQuY29sID0gYygxLCAzLCAyLCA0KSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wgPSBjKDEsIDMsIDIsIDQpLCBidHk9Im4iLCBjZXg9MC43KQ0KICAgIH0NCiAgICBuYWYgPC0gblNjcmVlJENvbXBvbmVudHMkbmFmDQogICAgdGV4dCh4ID0gbm9jLCB5ID0gZWlnW25vY10sIGxhYmVsID0gIiAoT0MpIiwgY2V4ID0gMC43LCANCiAgICAgICAgYWRqID0gYygwLCAwKSwgY29sID0gMikNCiAgICB0ZXh0KHggPSBuYWYgKyAxLCB5ID0gZWlnW25hZiArIDFdLCBsYWJlbCA9ICIgKEFGKSIsIA0KICAgICAgICBjZXggPSAwLjcsIGFkaiA9IGMoMCwgMCksIGNvbCA9IDQpDQp9DQpgYGANCg0KVGhpcyBuZXh0IGZ1bmN0aW9uIHdpbGwgaGVscCB1cyB3aXRoIGFuYWx5emluZyB0aGUgdmFyaW91cyBmYWN0b3JzIGluIHRoZSBQQ0EuIFRoaXMgd2lsbCBhbGxvdyB1cyB0byBhbmFseXplIHRoZSBmYWN0b3IgbG9hZGluZ3MgYW5kIHRoZSBwcm9wb3J0aW9uIHZhcmlhbmNlIHRoYXQgY2FuIGJlIGV4cGxhaW5lZCBieSBlYWNoIGZhY3Rvci4gVGhpcyB3aWxsIGFsbG93IHVzIHRvIHNlZSB0aGUgcHJvcG9ydGlvbiBvZiB0aGUgdG90YWwgdmFyaWF0aW9uIHdoaWNoIGNhbiBiZSBleHBsYWluZWQgYnkgZWFjaCBwcmluY2lwYWwgY29tcG9uZW50IGluIHRoZSBtb2RlbC4gDQoNCmBgYHtyfQ0KTXkubG9hZGluZ3MudmFyIDwtIGZ1bmN0aW9uKG1hdCwgbmZjdCwgbWV0aG9kPSJmYSIpew0KICAgIGlmKG1ldGhvZCA9PSAiZmEiKXsgDQogICAgIGYxIDwtIGZhY3RhbmFsKG1hdCwgZmFjdG9ycyA9IG5mY3QsICByb3RhdGlvbiA9ICJ2YXJpbWF4IikNCiAgICAgeCA8LSBsb2FkaW5ncyhmMSkNCiAgICAgdnggPC0gY29sU3Vtcyh4XjIpDQogICAgIHZhclNTID0gcmJpbmQoJ1NTIGxvYWRpbmdzJyA9IHZ4LA0KICAgICAgICAgICAgJ1Byb3BvcnRpb24gVmFyJyA9IHZ4L25yb3coeCksDQogICAgICAgICAgICdDdW11bGF0aXZlIFZhcicgPSBjdW1zdW0odngvbnJvdyh4KSkpDQogICAgIHdlaWdodCA9IGYxJGxvYWRpbmdzW10gDQogICB9IGVsc2UgaWYgKG1ldGhvZCA9PSAicGNhIil7DQogICAgIHBjYSA8LSBwcmNvbXAobWF0LCBjZW50ZXIgPSBUUlVFLCBzY2FsZSA9IFRSVUUpDQogICAgIHZhclNTID0gc3VtbWFyeShwY2EpJGltcG9ydGFuY2VbLDE6bmZjdF0NCiAgICAgd2VpZ2h0ID0gcGNhJHJvdGF0aW9uWywxOm5mY3RdDQogIH0NCiAgICBsaXN0KExvYWRpbmdzID0gd2VpZ2h0LCBQcm9wLlZhciA9IHZhclNTKQ0KfQ0KYGBgDQoNCg0KIyMgU3R1ZGVudCBFeHBlcmllbmNlIFBDQQ0KDQpGaXJzdCwgd2Ugd2lsbCBwZXJmb3JtIFBDQSBmb3IgdGhlIHN0dWRlbnQgZXhwZXJpZW5jZSBzdWJzZXQgb2YgdGhlIHN1cnZleSBkYXRhIHNldC4NCg0KVG8gYXZvaWQgZnJvbSBoYXZpbmcgdG9vIG1hbnkgcHJpbmNpcGFsIGNvbXBvbmVudHMgc2luY2UgdGhlIHN0dWRudCBleHBlcmllbmNlIHBvcnRpb24gb2YgdGhlIHN1cnZleSBpcyBzbyBsYXJnZSwgd2Ugd2lsbCB1c2UgdGhlIGV4cGVyaWVuY2UuMSBzdWJzZXQgb2YgdGhlIHN0dWRlbnQgZXhwZXJpZW5jZSBzdXJ2ZXkgcXVlc3Rpb25zIHdoaWNoIHdhcyBjcmVhdGVkIGVhcmxpZXIgZHVyaW5nIHRoZSB2YWxpZGl0eSBhbmFseXNpcy4gDQoNCkxldCdzIGNhbGN1bGF0ZSB0aGUgcHJpbmNpcGFsIGNvbXBvbmVudHMgZm9yIHRoZSBleHBlcmllbmNlLjEgZGF0YSBzZXQuIA0KDQpgYGB7cn0NCmV4cGVyaWVuY2UucGNhIDwtIHByY29tcChleHBlcmllbmNlLjEsIGNlbnRlciA9IFRSVUUsIHNjYWxlID0gVFJVRSkNCmBgYA0KDQpOb3csIHdlIHdpbGwgZmluZCB0aGUgZmFjdG9yIGxvYWRpbmcgb2YgdGhlIFBDQSBmb3IgdGhlIHN0dWRlbnQgZXhwZXJpZW5jZSBzdXJ2ZXkgcXVlc3Rpb25zLiANCg0KYGBge3J9DQprYWJsZShyb3VuZChleHBlcmllbmNlLnBjYSRyb3RhdGlvbiwgMiksIGNhcHRpb249IkZhY3RvciBMb2FkaW5ncyBvZiB0aGUgUENBIikNCmBgYA0KDQpXZSBjYW4gc2VlIHRoYXQgd2UgaGF2ZSB0ZW4gdG90YWwgcHJpbmNpcGFsIGNvbXBvbmVudHMgZm9yIHRoZSBzdHVkZW50IGV4cGVyaWVuY2UgZGF0YS4NCg0KDQpgYGB7cn0NCmthYmxlKHN1bW1hcnkoZXhwZXJpZW5jZS5wY2EpJGltcG9ydGFuY2UsIGNhcHRpb249IlRoZSBJbXBvcnRhbmNlIG9mIEVhY2ggUHJpbmNpcGFsIENvbXBvbmVudCIpDQpgYGANCg0KVGhlIGZpcnN0IFBDIGFjY291bnRzIGZvciBhcm91bmQgMzYuMjIlIG9mIHRoZSB0b3RhbCB2YXJpYXRpb24uIFRoZSBmaXJzdCB0d28gUENzIGFjY291bnQgZm9yIGFyb3VuZCA1MS4yMiUgb2YgdGhlIHRvdGFsIHZhcmlhdGlvbi4gVGhlIGZpcnN0IHRocmVlIFBDcyBhY2NvdW50IGZvciBhcm91bmQgNjEuMTQlIG9mIHRoZSB0b3RhbCB2YXJpYXRpb24uIA0KDQoNCiMjIyBTY3JlZSBQbG90DQoNCkxldCdzIHRha2UgYSBsb29rIGF0IHRoZSBzY3JlZSBwbG90IGZvciB0aGUgc3R1ZGVudCBleHBlcmllbmNlIHN1cnZleSBwb3J0aW9uLiANCg0KYGBge3J9DQpNeS5wbG90blNjcmVlKG1hdD1leHBlcmllbmNlLjEsIGxlZ2VuZCA9IFRSVUUsIG1ldGhvZCA9ImNvbXBvbmVudHMiLCANCiAgICAgICAgICAgICAgbWFpbj0iRGV0ZXJtaW5hdGlvbiBvZiBOdW1iZXIgb2YgQ29tcG9uZW50c1xuIFN0dWRlbnQgRXhwZXJpZW5jZSAoUG9zaXRpdmUpIikNCmBgYA0KDQpBcyB3ZSBjYW4gc2VlLCB3ZSBoYXZlIHRlbiBwcmluY2lwYWwgY29tcG9uZW50cyBqdXN0IGxpa2Ugd2Ugc2F3IGJlZm9yZSBpbiB0aGUgYW5hbHlzaXMgcG9ydGlvbi4gVGhlIGVsYm93IG9mIHRoZSBzY3JlZSBwbG90IGFwcGVhcnMgdG8gb2NjdXIgYXJvdW5kIHdoZW4gb3VyIGNvbXBvbmVudHMgZXF1YWxzIHR3by4gU28gdGhpcyB3b3VsZCBiZSB0aGUgaWRlYWwgdmFsdWUgb2YgY29tcG9uZW50cyB0byBjaG9vc2UgZm9yIGZ1cnRoZXIgYW5hbHlzaXMgb24gdGhlIHN0dWRlbnQgZXhwZXJpZW5jZSBzdXJ2ZXkgZGF0YS4gIA0KDQojIyMgU3R1ZGVudCBFeHBlcmllbmNlIERpc3RyaWJ1dGlvbiBIaXN0b2dyYW0NCg0KTmV4dCwgd2UgY2FuIGxvb2sgYXQgYSBoaXN0b3JncmFtIG9mIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHN0dWRlbnQgZXhwZXJpZW5jZSBpbmRleC4NCg0KYGBge3J9DQpwY2EgPC0gcHJjb21wKGV4cGVyaWVuY2UuMSwgY2VudGVyID0gVFJVRSwgc2NhbGUgPSBUUlVFKQ0Kc2UuaWR4ID0gcGNhJHhbLDFdDQpoaXN0KHNlLmlkeCwNCm1haW49IkRpc3RyaWJ1dGlvbiBvZiBTdHVkZW50IEV4cGVyaWVuY2UgSW5kZXgiLA0KYnJlYWtzID0gc2VxKG1pbihzZS5pZHgpLCBtYXgoc2UuaWR4KSwgbGVuZ3RoPTkpLA0KeGxhYj0iU2VsZi1jb21wYXNzaW9uIEluZGV4IiwNCnhsaW09cmFuZ2Uoc2UuaWR4KSwNCmJvcmRlcj0icHVycGxlIiwNCmNvbD0ibGlnaHRibHVlIiwNCmZyZXE9RkFMU0UNCikNCmBgYA0KDQpBcyB3ZSBjYW4gc2VlLCB0aGUgc3R1ZGVudCBleHBlcmllbmNlIGluZGV4IGFwcGVhcnMgdG8gYmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgd2l0aG91dCBhbnkgc2tldyBvciBvdXRsaWVycyBwcmVzZW50LiANCg0KDQoNCg0KIyMgU3R1ZGVudCBTYXRpc2ZhY3Rpb24gUENBDQoNCk5vdywgd2Ugd2lsbCBwZXJmb3JtIFBDQSBhZ2FpbiwgdGhpcyB0aW1lIGZvciB0aGUgc3R1ZGVudCBzYXRpc2ZhY3Rpb24gc3Vic2V0IG9mIHRoZSBzdXJ2ZXkgZGF0YSBzZXQuDQoNCmBgYHtyfQ0Kc2F0aXNmYWN0aW9uLnBjYSA8LSBwcmNvbXAoc2F0aXNmYWN0aW9uLCBjZW50ZXIgPSBUUlVFLCBzY2FsZSA9IFRSVUUpDQpgYGANCg0KTm93LCB3ZSB3aWxsIGZpbmQgdGhlIGZhY3RvciBsb2FkaW5nIG9mIHRoZSBQQ0EgZm9yIHRoZSBzdHVkZW50IHNhdGlzZmFjdGlvbiBzdXJ2ZXkgcXVlc3Rpb25zLiANCg0KYGBge3J9DQprYWJsZShyb3VuZChzYXRpc2ZhY3Rpb24ucGNhJHJvdGF0aW9uLCAyKSwgY2FwdGlvbj0iRmFjdG9yIExvYWRpbmdzIG9mIHRoZSBQQ0EiKQ0KYGBgDQoNCldlIGNhbiBzZWUgdGhhdCB3ZSBoYXZlIHR3byB0b3RhbCBwcmluY2lwYWwgY29tcG9uZW50cyBmb3IgdGhlIHN0dWRlbnQgZXhwZXJpZW5jZSBkYXRhLg0KDQpgYGB7cn0NCmthYmxlKHN1bW1hcnkoc2F0aXNmYWN0aW9uLnBjYSkkaW1wb3J0YW5jZSwgY2FwdGlvbj0iVGhlIEltcG9ydGFuY2Ugb2YgRWFjaCBQcmluY2lwYWwgQ29tcG9uZW50IikNCmBgYA0KDQpUaGUgZmlyc3QgUEMgYWNjb3VudHMgZm9yIGFyb3VuZCA3NS44NSUgb2YgdGhlIHRvdGFsIHZhcmlhdGlvbi4gVGhlIGZpcnN0IHR3byBQQ3MgYWNjb3VudCBmb3IgMTAwJSBvZiB0aGUgdG90YWwgdmFyaWF0aW9uLiANCg0KDQojIyMgU3R1ZGVudCBTYXRpc2ZhY3Rpb24gRGlzdHJpYnV0aW9uIEhpc3RvZ3JhbQ0KDQpOZXh0LCB3ZSBjYW4gbG9vayBhdCBhIGhpc3RvcmdyYW0gb2YgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc3R1ZGVudCBzYXRpc2ZhY3Rpb24gaW5kZXguDQoNCmBgYHtyfQ0KcGNhIDwtIHByY29tcChzYXRpc2ZhY3Rpb24sIGNlbnRlciA9IFRSVUUsIHNjYWxlID0gVFJVRSkNCnNhdC5pZHggPSBwY2EkeFssMV0NCmhpc3Qoc2F0LmlkeCwNCm1haW49IkRpc3RyaWJ1dGlvbiBvZiBTdHVkZW50IEV4cGVyaWVuY2UgSW5kZXgiLA0KYnJlYWtzID0gc2VxKG1pbihzYXQuaWR4KSwgbWF4KHNhdC5pZHgpLCBsZW5ndGg9OSksDQp4bGFiPSJTZWxmLWNvbXBhc3Npb24gSW5kZXgiLA0KeGxpbT1yYW5nZShzYXQuaWR4KSwNCmJvcmRlcj0icHVycGxlIiwNCmNvbD0ibGlnaHRibHVlIiwNCmZyZXE9RkFMU0UNCikNCmBgYA0KDQpBcyB3ZSBjYW4gc2VlLCB0aGUgc3R1ZGVudCBzYXRpc2ZhY3Rpb24gaW5kZXggZG9lcyBub3QgYXBwZWFyIHRvIGJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLiBJbnN0ZWFkLCB0aGUgZGlzdHJpYnV0aW9uIGFwcGVhcnMgdG8gYmUgbm90aWNlYWJseSBza2V3ZWQgdG8gdGhlIHJpZ2h0LCB3aXRoIHNvbWUgcG90ZW50aWFsIG91dGxpZXJzIHByZXNlbnQgb24gdGhlIHJpZ2h0IHRhaWwgb2YgdGhlIGdyYXBoLg0KDQoNCg0KIyBDb25jbHVzbGlvbiBhbmQgUmVjb21tZW5kYXRpb25zDQoNCk92ZXJhbGwsIHRoZSBwcmluY2lwYWwgY29tcG9uZW50IGFuYWx5c2lzIGFsbG93ZWQgdXMgdG8gZnVydGhlciBhbmFseXNpcyBhbmQgYmV0dGVyIHVuZGVyc3RhbmQgdGhlIHN1cnZleSBkYXRhIHNldC4gRm9yIGZ1cnRoZXIgcmVjb21tZW5kYXRpb25zIGZvciB0aGlzIHByb2plY3QsIHNvbWV0aGluZyB3aGljaCBzdG9vZCBvdXQgaXMgaG93IGxvbmcgdGhlIHN0dWRlbnQgZXhwZXJpZW5jZSBwb3J0aW9uIG9mIHRoZSBzdXJ2ZXkgaXMgaW4gY29tcGFyaXNvbiB0byB0aGUgc3R1ZGVudCBzYXRpc2ZhY3Rpb24gcG9ydGlvbiBvZiB0aGUgc3VydmV5LiBJbiB0aGUgc3VydmV5LCB0aGVyZSBvbmx5IGFwcGVhcmVkIHRvIGJlIHR3byBxdWVzdGlvbnMgd2hpY2ggZGlyZWN0bHkgcmVsYXRlZCB0byBzdHVkZW50IHNhdGlzZmFjdGlvbi4gDQoNClRoZXNlIHR3byBzdHVkZW50IHNhdGlzZmFjdGlvbiBxdWVzdGlvbnMgd2VyZSBxdWVzdGlvbnMgMTcgYW5kIDE4LCB3aXRoIHRob3NlIGJlaW5nOiANCiIxNy4gV291bGQgeW91IHJlY29tbWVuZCBvdXIgU2Nob29sIG9mIEJ1c2luZXNzIHRvIGEgZnJpZW5kIG9yIGZhbWlseSBtZW1iZXI/IDEgLVllcywgMiAtIE5vLiIgYW5kICIxOC4gSG93IHdvdWxkIHlvdSBldmFsdWF0ZSB5b3VyIGVudGlyZSBlZHVjYXRpb25hbCBleHBlcmllbmNlIGF0IG91ciBzY2hvb2w/IDEgLUV4Y2VsbGVudCwgMiAtIEdvb2QsIDMgLSBGYWlyLCA0IC0gUG9vciIuIA0KDQpUaGlzIHN0dWRlbnQgc2F0aXNmYWN0aW9uIHBvcnRpb24gb2YgdGhlIHN1cnZleSB3YXMgaW5jcmVkaWJseSBzaG9ydCwgYW5kIGxlZCB0byBpdCBiZWluZyBpbXBvc3NpYmxlIHRvIGNyZWF0ZSBhIHNjcmVlIHBsb3QgZm9yIHRoZSBzdHVkZW50IHNhdGlzZmFjdGlvbiBwb3J0aW9uIGFzIHdlIHdvdWxkIG5lZWQgdGhyZWUgb3IgbW9yZSBwcmluaWNwYWwgY29tcG9uZW50cyBpbiBvcmRlciB0byBkbyBzbywgYnV0IHdlIG9ubHkgaGFkIHR3byBwcmluY2lwYWwgY29tcG9uZW50cyBmb3IgdGhpcyBzdWJzZXQgb2YgdGhlIHN1cnZleSBkYXRhIHNldC4gDQoNClNvLCB0aGUgbWFpbiByZWNvbW1lbmRhdGlvbiBJIHdvdWxkIG1ha2UgZm9yIGZ1dHVyZSBwcm9qZWN0cyBpcyB0byBleHBhbmQgdGhlIHN0dWRlbnQgc2F0aXNmYWN0aW9uIHBvcnRpb24gb2YgdGhlIGRhdGEgc2V0IHRvIGhhdmUgbW9yZSBxdWVzdGlvbnMsIGluIG9yZGVyIHRvIHByb3ZpZGUgZm9yIGZ1cnRoZXIgYW5hbHlzaXMgb2YgdGhlc2Ugc3VydmV5IHF1ZXN0aW9ucy4gDQoNCg0KDQoNCiMgUHJvamVjdCBRdWVzdGlvbnMNCg0KTGFzdGx5LCB3ZSB3aWxsIG5vdyBsb29rIGF0IHNvbWUgcG90ZW50aWFsIHByb2plY3QgcXVlc3Rpb25zIGJhc2VkIHVwb24gdGhlIGFuYWx5c2lzIG9mIHRoZSBzdXJ2ZXkgZGF0YSBzZXQgYW5kIHRoZSByZXN1bHRzIHRoYXQgd2VyZSBmb3VuZC4NCg0KU29tZSBwb3RlbnRpYWwgcXVlc3Rpb25zIGluY2x1ZGU6DQoNCiogV2hpY2ggZmFjdG9ycyBvZiBzdHVkZW50IGV4cGVyaWVuY2Ugc2hvd2VkIHRoZSBzdHJvbmdlc3QgaW5mbHVlbmNlIG9uIHN0dWRlbnQgc2F0aXNmYWN0aW9uPyANCg0KKiBEaWQgdGhlc2UgcGFydGljdWxhciBmYWN0b3JzIHdpdGggdGhlIHN0cm9uZ2VzdCBpbmZsdWVuY2Ugb24gc2F0aXNmYWN0aW9uIHNob3cgc3Ryb25nZXIgcmVsaWFiaWxpdHkgd2hlbiBjb21wYXJlZCB0byB0aGUgb3RoZXJzPw0KDQoqIERvIHN0dWRlbnRzIGFwcGVhciB0byBiZSBtb3N0bHkgc2F0aXNmaWVkIHdpdGggdGhlaXIgc2Nob29sIGV4cGVyaWVuY2U/DQoNCiogSG93IGNhbiB3ZSBhbmFseXNpcyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIHByaW5jaXBhbCBjb21wb25lbnRzIGluIG9yZGVyIHRvIGxlYXJuIG1vcmUgYWJvdXQgdGhlIHJldmVsYW50IGZhY3RvcnMgaW4gcmVsYXRpb24gdG8gYSBzdHVkZW50J3Mgb3ZlcmFsbCBleHBlcmllbmNlIGFuZCBzYXRpc2ZhY3Rpb24gaW4gY29sbGVnZT8NCg0KDQpGb3IgdGhpcyBwcm9qZWN0LCBJIHdvdWxkIGJlIGludGVyZXN0aW5nIGluIGxvb2tpbmcgaW50byBwYXJ0aWN1bGFybHkgdGhlIHRvcGljIG9mIHdoaWNoIHN0dWRlbnQgZXhwZXJpZW5jZSBmYWN0b3JzIGhhdmUgdGhlIGdyZWF0ZXN0IHNpZ25pZmljYW5jZSBvciBlZmZlY3Qgb24gYSBzdHVkZW50J3Mgc2F0aXNmYWN0aW9uIHdpdGggdGhlaXIgY29sbGVnZSBleHBlcmllbmNlLiBUaGlzIHdvdWxkIGJlIGhlbHBmdWwgYmVjYXVzZSBpdCB3b3VsZCBnaXZlIHNwZWNpZmljIGZhY3RvcnMgZm9yIGNvbGxlZ2UgZmFjdWx0eSBvciBhZHZpc29ycyB0byBsb29rIG91dCBmb3IgaW4gdGhlaXIgc3R1ZGVudHMgaW4gb3JkZXIgdG8gaGVscCB0aGVtIGhhdmUgYSBtb3JlIHBvc2l0aXZlIGFuZCBzYXRpc2ZhY3RvcnkgZXhwZXJpZW5jZSBkdXJpbmcgdGhlaXIgdGltZSBpbiBjb2xsZWdlLg0KDQpJIHRoaW5rIGl0IHdvdWxkIGJlIGludGVyZXN0aW5nIHRvIHNlZSBpZiB0aGVzZSBwYXJ0aWN1bGFyIGZhY3RvcnMgd2l0aCBzdHJvbmdlciBpbmZsdWVuY2Ugb24gYSBzdHVkZW50J3Mgc2F0aXNmYWN0aW9uIGhhdmUgc3Ryb25nZXIgcmVsaWFiaWxpdHkuIEl0IHdvdWxkIGJlIGludGVyZXN0aW5nIHRvIGNvbXBhcmUgdGhlIHJlbGlhYmlsaXR5IHJlc3VsdHMgb2YgdGhlc2UgcGFydGljdWxhciBmYWN0b3JzIHRvIHNlZSBpZiB0aGVpciBhcHBlYXJzIHN0cm9uZ2VyIG9yIHdlYWtlciB0aGFuIHRoZSBhdmVyYWdlLiBUaGlzIHdvdWxkIGhlbHAgdG8gc2VlIGlmIHRoZXNlIGZpbmRpbmdzIHRydWx5IGFyZSByZWxpYWJsZSBvciBub3QuIA0KDQpBZGRpdGlvbmFsbHksIHdlIGNvdWxkIHVzZSB0aGUgZmluZGluZ3MgaW4gdGhlIHByaW5jaXBhbCBjb21wb25lbnQgYW5hbHlzaXMgdG8gZnVydGhlciBpbnZlc3RpZ2F0ZSB0aGUgc3VydmV5IGRhdGEgc2V0LiBXZSBjb3VsZCBsb29rIGludG8gdGhlIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiB0aGUgdmFyaW91cyBwcmluY2lwYWwgY29tcG9uZW50cyBpbiBvcmRlciB0byBsZWFybiBtb3JlIGFib3V0IHRoZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gdmFyaW91cyBmYWN0b3JzIGluIHN0dWRlbnQgZXhwZXJpZW5jZSBhbmQgc2F0aXNmYWN0aW9uLiBJdCB3b3VsZCBhbHNvIGJlIGludGVyZXN0aW5nIHRvIHVzZSB3aGljaCBsb2FkaW5nIGZhY3RvcnMgaGFkIHRoZSBoaWdoZXN0IGltcG9ydGFuY2UsIGluIG9yZGVyIHRvIGNyZWF0ZSBtb2RlbHMgYmFzZWQgdXBvbiB0aGVzZSBzcGVjaWZpYyBmYWN0b3JzIGluIG9yZGVyIHRvIHNlZSB0aGVpciBpbXBvcnRhbmNlIGFuZCBpbmZsdWVuY2Ugb24gb3ZlcmFsbCBzdHVkZW50IGV4cGVyaWVuY2UgYW5kIHNhdGlzZmFjdGlvbi4gDQoNCg==