1 Introduction

The subject of mathematics causes fear and difficulty for a wide range of students. We often hear students claim, “I don’t like math”, “I’m just not good at math”, “I’m not a math person”, or “I wasn’t born with the math gene”, etc. Although these claims are not perfect indicators of math anxiety, students who have these fixed mindsets will be more likely to experience math anxiety.

While math anxiety can have a serious impact on academic performance, it does not mean a lack of mathematics ability. Prof. Laurent Schwartz experienced math anxiety in the 11th grade, but this did not prevent him from becoming a prominent mathematician. In fact, he won the Fields Model (the mathematician’s Nobel Prize) in 1950. Effectively managing math anxiety requires a deep understanding of math anxiety.

This project aims to identify factors that are strongly associated with math anxiety and use them to reduce math anxiety and, consequently, improve academic performance. Specifically:

  1. The results of this project will contribute to the body of existing knowledge.

  2. Identification of environmental factors aids the development of intervention tools for educators and support staff to help students reduce math anxiety and improve their academic performance.

  3. The outcomes of this project can be used to implicitly improve retention.

2 Literature Review

Mathematics anxiety involves feelings of fear, tension, apprehension, and physiological reactivity interfering when individuals engage with number manipulation and mathematical problem-solving (see, for example, Pletzer et al. 2016). In the U.S., an estimated 25% of four-year college students and up to 80% of community college students suffer from a moderate to a high degree of mathematics anxiety (Chang & Beilock, 2016). The frequency of negative effects of math anxiety on college students is increasing.

The earliest research on math anxiety can be traced back to Gough (1954) who used the term mathemaphobia. The term math anxiety was first used by Dreger and Aiken (1957). The first definition of math anxiety is credited to Richardson and Suinn (1972), who described math anxiety as “feelings of tension and anxiety that interfere with the manipulation of numbers and solving of mathematical problems in a wide variety of ordinary life and academic situations”.

In the past 70 years, numerous authors conducted extensive research on math anxiety. Particularly, in the past 20 years, researchers from different disciplines including mathematics have investigated the association between math anxiety and math achievement, the causes of math anxiety, characteristics of students that increase susceptibility to math anxiety, and efforts that educators can take to remedy it.

Math anxiety is real. Its negative impact on students’ academic performance and their future professional life is profound. Extensive research publications since 2000 have shown that math anxiety relates inversely to positive attitudes toward mathematics and is bound directly to avoidance of the subject (see for example, Segool et al., 2013). It affects both math and overall academic performance since math anxiety leads to the drainage of cognitive resources, motivation reduction, and strategy impairment (Klee et al., 2022).

Math anxiety can also lead to poor academic performance and course withdrawal, putting students behind schedule and increasing the risk of drop out, which reduces student retention rates. Wilson (2013) studied math anxiety of mature-age pre-service teachers as a potential contributing factor that impacts student retention. Daker et al. (2021) recently studied the impact of math anxiety on first-year STEM students and concluded that math anxiety predicts STEM avoidance and underperformance throughout the university, independently of math ability.

A wealth of empirical studies on various aspects of math anxiety have been conducted since Dreger & Aiken’s (1957) seminal work. Due to the complex pathways toward the development of math anxiety and its links with achievements and confounders, the origins and outcomes of math anxiety are still not fully understood.

Recent and ongoing research focuses on the development and dynamic interplay between factors that cause math anxiety. Most of the research can be classified into three categories: situational, dispositional, and environmental (O’Leary et al., 2017). The current project will explore all three types of factors, but the primary focus is on the environmental factors such as prior perceptions, attitudes, and experiences that have affected the individual.

3 Research Objectives

Since lower mathematics achievement predicts higher subsequent math anxiety and higher math anxiety predicts lower future achievement, reducing math anxiety will help students develop a positive attitude to mathematics, build confidence, boost motivation, and consequently improve their achievements. This study aimed to identify the factors that can reduce math anxiety in college students. Specific objectives are

Objective 1: Adopting well-established psychometric survey instruments AMAS and self-efficacy instruments to collect math anxiety and self-efficacy data.

Objective 2: Include some demographic characteristics such as age and gender to compare the results with that of existing research and use them as a baseline.

Objective 3: Teaching strategies can reduce math anxiety and improve learning outcomes. We will investigate several different strategies in mathematics teaching such as conceptual, procedure, etc., to see if these strategies affect the level of math anxiety.

Objective 4: Effectively using the technologies can reduce math anxiety. The recently developed educational technologies during the pandemic have not been discussed in the literature on math anxiety. We will investigate how these new technologies affect math anxiety.

Objective 5: Learning modalities and styles are also associated with math anxiety. Most of the research in this direction is based on high school students. We will explore how these learning modalities and styles affect math anxiety among college students.

Objective 6: Creating and using campus learning resources can reduce math anxiety and improve their academic performance (Moliner & Alegre, 2020). We will explore whether and how learning resources on college campuses reduce anxiety.

4 Materials

4.1 Participants

The survey was approved by WCU’s IRB. We invite all WCU students who take their first WCU mathematics and statistics class in the fall semesters of 2024 and the spring semester of 2025. Participation in the study are voluntary and responses remain anonymous. The data was collected in the spring and fall semesters of 2024 based on the protocols set by WCU’s Institutional Research. Via Qualtrics, we sent an invitation email to all qualified students spring and fall mid-semester. A reminder email was sent at the end of the semester to non-responding students to boost the participation rate. A $10 Amazon gift card was offered to survey completers and distributed through Qualtrics so anonymity is guaranteed.

The study population in this study is defined as WCU students aged 18 years or older who took their first MAT class at WCU. The results in this study can be generalized to similar regional universities and those recently reclassified R2 institutions.

4.2 Survey Instruments

The survey will have three components:

  1. Multi-item Survey Instrument Math Anxiety: AMAS. We will use the frequently used AMAS with nine items contributing to two scales: Math Learning and Math Testing. AMAS originates from a reanalysis of a MARS-R by Hopko et al. (2003). AMAS is short (completion takes about 5 minutes) and has good psychometric properties: high reliability as measured by internal consistency and test-retest method, construct validity as measured by exploratory and confirmatory factor analyses, and convergent and discriminant validity. (Numerous subsequent studies have confirmed these results.) We will use AMAS to measure math anxiety in this project.

  2. Multi-item Survey Instrument for Math Self-efficacy. Math anxiety and math self-efficacy are negatively correlated. The three-item short version of math self-efficacy questionnaires: (1) I usually understand a mathematical idea quickly; (2) I have to work very hard to understand mathematics; (3) I can connect mathematical ideas that I have learned; used by Rozgonjuk et al. (2020).

  3. Multi-item Survey Instrument for Student’s Perception on Faculty Teaching Strategies: Students’ mathematics anxiety is directly influenced by their instructors’ teaching strategies. This study employs the Teaching Strategies Inventory used by Cardino Jr. and Ortega-Dela Cruz (2020) to assess students’ perceptions of these strategies. The inventory comprises eight distinct dimensions (subscales).

  4. Multi-item Survey Instrument for Student Learning Modalities: AVID (Advancement Via Individual Determination) is a program introduced by Meadowlark Elementary School that aims to close the achievement gap by preparing all students for college readiness and success in a global society. We used AVID’s Student Learning Modality Inventory to identify student learning styles (auditory, visual, and kinesthetic) in this study. The inventory can be found at https://pengdsci.github.io/MathAnxiety/AVID_Learning_Style_Inventory.pdf.

  5. Multi-item Survey Instrument for Student’s Engagement: We select 12 questionnaires from the NSSE (National Survey of Student Engagement) to assess students in-class and after-class engagement and use of learning resources. The The core NSSE survey for a first-year or senior student consists of approximately 40 to 50 required items, but the total bank of potential questions is much larger. The complet instrument can be found at https://nsse.indiana.edu/nsse/survey-instruments/us-english.html.

  6. Single-item questions: These questions capture demographic information.

5 Raw Data Processing

At the end of data collection, we received 895 responses. Of these, 199 participants did not complete the main survey subscales. The analysis is based on the remaining 696 responses for which the main subscales were completed, which contained only a few missing values. Several redundant variables were removed from the raw data. In addition, some original categorical variables were recategorized to avoid sparse groups and improve interpretability.

5.1 Missing Value Imputation

To main this sample size, we use random imputation approach to fill in the missing values. Since all multi-item sub-scales were measured using a Likert scale, the scores follows a multinomial distribution. The empirical distribution will be used in the random imputation to main the probability distribution of the observed data. The following code imputes the missing values in all multi-item subscales.

Imputation = function(DataName){
  for (i in 1:(dim(DataName)[2])){
    vec = as.vector(DataName[, i])
    na.id = which(is.na(vec))
    n0 = length(na.id)
    prob0 = table(vec)/length(vec)
    imput.val = NULL
      for (j in 1:n0){
      imput.val[j] = sample(1:length(prob0), size = 1, prob = prob0)
    }
    DataName[na.id, i] = imput.val
  }
   DataName
}

5.2 Reverse Scoring

Reverse scoring is a crucial data preparation step for multi-item surveys where some items are worded in the opposite direction to prevent response bias. After item-wise review of all instruments along with statistical procedures of correlation and confirmatory factor analysis (CFA), item 2 in the Self-efficacy Instrument and all questions except items 5 and 7 in the Technology Instrument were negatively worded. The scores of these items were reversed.

In addition, all questions regarding engagement and resource use were reverse-worded, so their scores were reversed for the subsequent analysis.

5.3 Sparse Category Regrouping

Two variables need to be regrouped in the following: course level and ethnicity.

  • MathCourseLevel
    • Math.I: MATQ30, MAT100, MAT101, MAT102,
    • Math.II: MAT193, MAT104, MAT112, MAT113, MAT115, MAT131
    • Math.III: MAT143, MAT145, MAT151, MAT161
    • Math.IV: MAT162-MAT480
    • Stats: MAT121, MAT125, STA200
    • Other: All courses not listed above
  • Ethnicity
    • White
    • Black: Black and African American
    • Asian
    • Other: Native Hawaiian or Pacific Islander, Multiple Ethnicity or Other, Prefer Not To Answer
  • Learning Modalities
df_with_freq <- Comp.Modality %>%
  rowwise() %>%
  mutate(
    freq_A = sum(c_across(MS.1:MS.12) == "1"),
    freq_B = sum(c_across(MS.1:MS.12) == "2"),
    freq_C = sum(c_across(MS.1:MS.12) == "3")
  ) %>%
  ungroup()
###
df_with_freq$max_freq_col <- names(df_with_freq)[max.col(df_with_freq[, c("freq_A", "freq_B", "freq_C")]) + 1]
df_with_freq$max_freq_value <- apply(df_with_freq[, c("freq_A", "freq_B", "freq_C")], 1, max)
df_with_freq$modality <- ifelse(df_with_freq$max_freq_col=="MS.1", "Auditory", 
                                ifelse(df_with_freq$max_freq_col=="MS.2", "Visual", "Kinesthetic"))

5.4 Exploratory Factor Analysis (EFA) on Anxiety

The abbreviated mathematical anxiety (MA) instrument developed by Hopko et al. (2003) is characterized by a two-factor structure that divides into two subscales: mathematics evaluation anxiety (MEA) and mathematics learning anxiety (MLA). The subsequent exploratory factor analysis serves to validate this construct.

# Check correlations (visually)
n = dim(Comp.Anxiety[,-1])[1]
cor_matrix <- cor(Comp.Anxiety[,-1])
#corPlot(cor_matrix, upper = FALSE)
# Bartlett's Test of Sphericity (we want a significant p-value, p < .05)
cortest.bartlett(cor_matrix, n = n)

# KMO Measure of Sampling Adequacy (MSA) (We want overall MSA > 0.6, ideally > 0.8)
KMO(cor_matrix)

Bartlett’s test of sphericity produced a statistically significant result (p < .001), confirming that the variables are sufficiently correlated to proceed with factor analysis. The Kaiser-Meyer-Olkin (KMO) Measure of Sampling Adequacy, with both overall and item-level values exceeding 0.80, indicates that the data contain adequate common variance to warrant factor analysis. Furthermore, the scree plot clearly demonstrates the anticipated two-factor structure of the construct.

# Get eigenvalues
fa_result <- fa(Comp.Anxiety[,-1], nfactors = ncol(Comp.Anxiety[,-1]), rotate = "none")
eigenvalues <- fa_result$e.values

# Scree plot with horizontal line using shapes
scree_plot <- plot_ly(x = 1:length(eigenvalues), y = eigenvalues,
                      type = 'scatter', mode = 'lines+markers',
                      line = list(width = 3),
                      marker = list(size = 8)) %>%
  layout(
    title = "Scree Plot with Kaiser Criterion (Eigenvalue)",
    xaxis = list(title = "Factor Number"),
    yaxis = list(title = "Eigenvalue"),
    shapes = list(
      list(
        type = "line",
        x0 = 0,
        x1 = length(eigenvalues),
        y0 = 1,
        y1 = 1,
        line = list(color = "red", width = 2, dash = "dash")
      )
    ),
    annotations = list(
      list(
        x = length(eigenvalues) * 0.8,
        y = 1.1,
        text = "Kaiser Criterion (λ = 1)",
        showarrow = FALSE,
        font = list(color = "red")
      )
    ),
     margin = list(
                  t = 100,  # Adjust this value to increase or decrease the top margin
                  b = 50,
                  l = 50,
                  r = 50)
  )

scree_plot

Next, we perform EFA to identify the items of MEA and MLA through factor loadings.

## two-factor aEFA
efa_2factor <- fa(Comp.Anxiety[,-1], nfactors = 2, rotate = "oblimin", 
                  fm = "pa", scores = "regression")
# Create a clean loadings table
loadings_table <- fa.sort(efa_2factor$loadings[])
pander(loadings_table, digits = 2, cutoff = 0.3)
  PA1 PA2
AMAS.2 0.81 0.071
AMAS.4 0.8 0.057
AMAS.8 0.79 -0.14
AMAS.5 0.57 0.12
AMAS.3 -0.026 0.75
AMAS.7 -0.059 0.71
AMAS.6 0.056 0.68
AMAS.9 0.13 0.64
AMAS.1 0.017 0.5

As shown in the table above, items 2, 4, 5, and 8 load onto the evaluation anxiety factor, whereas the remaining items load onto the learning anxiety factor. Two distinct subscales will be established for subsequent analyses.

Anxiety.mea <- Comp.Anxiety[, c("ID",  "AMAS.2", "AMAS.4", "AMAS.5",  "AMAS.8")]
Anxiety.mla <- Comp.Anxiety[, c("ID", "AMAS.1", "AMAS.3", "AMAS.6", "AMAS.7", "AMAS.9")]

6 Validation and Reliability

The major multi-item instruments used in this study are well-established and have been used in various published research. In practice, the validity and reliability of such established instruments must be confirmed before any statistical analysis. We next perform reliability and validity analyses to warrant the credibility of the overall survey design and the quality of the collected data.

6.1 Validity Analysis

Validity of a multi-item survey instrument answers the question: “Am I actually measuring what I intend to measure?” It’s about the soundness of the interpretation of the scores. In psychometrics, validity refers to the degree to which a scale measures what it claims to measure. For a single-factor instrument, this means all items are indicators of one underlying construct such as maths anxiety, self-efficacy, engagement, etc. in this comprehensive survey. The CFA has been used in survey research widely, see Watson, et al (1988) and Marsh (1996).

Confirmatory Factor Analysis (CFA) is a powerful statistical technique used to test a pre-specified theory about the structure of your instrument. We use CFA to confirm that your hypothesized single-factor model is consistent with the observed data. It provides rigorous evidence for construct validity in a list of conventional measures:

  • Factor Loadings are the standardized weights from the Confirmatory Factor Analysis (CFA). The suggested guidelines are:

    • A loading magnitude greater than 0.5 indicates that the item shares at least 25% of its variance with the latent factor. In the following table, we report the minimum loading for each instrument under the column std.all.min.
    • All loadings must be statistically significant (p < 0.05). We report the maximum p-value for each instrument under the column pval.max.
  • Standardized Root Mean Square Residual (SRMR) measures the goodness-of-fit of the CFA model. It represents the average standardized residual between the observed and predicted correlation matrices. A lower value indicates a better fit, with a suggested cutoff of less than 0.08.

  • Comparative Fit Index (CFI) is another goodness-of-fit measure for the CFA. It compares the specified model to a null (independence) model. A higher value indicates a better fit, with a suggested cutoff of greater than 0.9.

  • Tucker-Lewis Index (TLI) also measures the goodness-of-fit of the CFA. Its interpretation and usage are similar to those of the CFI.

After some exploratory analysis, we dropped a few items from the Technology Instrument and defined two sucscales of the initial resource instruments: use of resource and student engagement.

The final results on the struct validity measures are summarized in the following table.

cfa.analysis <- function(dataset){
  #dataset <- Comp.Anxiety
  predictors <- names(dataset[, -1])  
  n0 <- length(predictors)
  cfa.model <-  paste("latent =~", paste(predictors, collapse = " + "))
  cfa.fit <- cfa(cfa.model, data = dataset[, -1], estimator = "MLM")
  results <- summary(cfa.fit, standardized = TRUE, fit.measures = TRUE, rsquare = TRUE)
  std.all.min <- min(results$pe$std.lv[1:n0])
  pval.max <- max(results$pe$pvalue[2:n0])
  srmr <- results$fit["srmr"]
  cfi <- results$fit["cfi"]
  tli <- results$fit["tli"]
  #rmsea <- results$fit["rmsea"]
  cbind(std.all.min = std.all.min, pval.max = pval.max, srmr = srmr, cfi = cfi,  tli = tli)
}
anxiety.mea.vlid <-cfa.analysis(Anxiety.mea)
anxiety.mla.vlid <-cfa.analysis(Anxiety.mla)
anxiety.vlid <-cfa.analysis(Comp.Anxiety)
efficacy.vlid <-cfa.analysis(Comp.SelfEfficacy)
tech.vlid <-cfa.analysis(Comp.Technology)
cooperative.vlid <-cfa.analysis(Comp.Cooporative)
deductive.vlid <-cfa.analysis(Comp.Deductive)
demo.vlid <-cfa.analysis(Comp.Demonstration)
inductive.vlid <-cfa.analysis(Comp.Inductive)
integrate.vlid <-cfa.analysis(Comp.Integrative)
lecture.vlid <-cfa.analysis(Comp.LectureType)
repetive.vlid <-cfa.analysis(Comp.Repetitive)
engage.vlid <-cfa.analysis(Comp.Engage)
resource.vlid <-cfa.analysis(Comp.Resource)
##
vlid.table <-rbind(anxiety.mea = anxiety.mea.vlid, anxiety.mla = anxiety.mla.vlid, 
                  anxiety = anxiety.vlid, self.efficacy = efficacy.vlid,
                  technology = tech.vlid, cooperative = cooperative.vlid,
                  deductive = deductive.vlid, demonstration = demo.vlid,
                  inductive = inductive.vlid, integrate = integrate.vlid,
                  lecture = lecture.vlid, repetitive = repetive.vlid, 
                  engage = engage.vlid, resource = resource.vlid)
row.name <- c("anxiety.mea", "anxiety.mla", "anxiety", "self.efficacy", 
              "technology", "cooperative",
              "deductive", "demonstration", "inductive", "integrate",
              "lecture", "repetitive", "engage", "resource")
col.name <- c("std.all.min", "pval.max", "srmr", "cfi",  "tli")
rownames(vlid.table) <- row.name
colnames(vlid.table) <- col.name
pander(vlid.table)
  std.all.min pval.max srmr cfi tli
anxiety.mea 0.7348 0 0.04196 0.9714 0.9141
anxiety.mla 0.4819 0 0.02203 0.9882 0.9763
anxiety 0.4217 0 0.08434 0.8168 0.7558
self.efficacy 0.4799 2.466e-06 1.937e-08 1 1
technology 0.5035 0 0.08292 0.8219 0.771
cooperative 0.8884 0 0.04313 0.936 0.8933
deductive 0.754 0 0.0473 0.945 0.9174
demonstration 0.7043 0 0.03764 0.9564 0.9347
inductive 0.7384 0 0.02923 0.9731 0.9597
integrate 0.494 0 0.05401 0.9241 0.8861
lecture 0.7185 0 0.02601 0.9778 0.9667
repetitive 0.5746 0 0.05582 0.908 0.862
engage 0.6802 0 3.802e-09 1 1
resource 0.4246 0 0.0787 0.8623 0.5869

The construct validity of all multi-item instruments was assessed using Confirmatory Factor Analysis (CFI). The results confirmed that most scales meet established psychometric standards. The mojprity of the key fit indices, including CFI and TLI, exceeded the recommended threshold of 0.90, while the SRMR fell below the 0.08 cutoff, indicating a good model fit. Furthermore, all factor loadings were statistically significant (p < .05) and substantial in magnitude (exceeding 0.4), demonstrating strong relationships between the items and their intended latent constructs. In summary, the validity analysis confirms that the instruments used in this study are robust and appropriate for measuring their respective concepts.

Remarks: (1). The above validity measures based on the items follow multi-variate normal distribution, This is a strong assumption. The items in each instrument are not continous. This influences some of the validity measure. (2). In practice, we can use some descriptive approaches to visual check with assuming multi-variate normality.

6.2 Relianbility Analysis

Reliability of a multi-item survey instrument answers the question: “If I measure the same thing multiple times, will I get a consistent result?” It measures how well the items that are supposed to measure the same construct hang together.

Internal Consistency is the most common assessment for a survey administered once. It measures the degree to which items in a scale are correlated with each other. Two well-known internal consistency measures are Cronbach’s Alpha (Cronabck, 1951) and McDonald’s Omega (1999). McDonald’s Omega is more robust than Cronbach’s Alpha.

Cronbach’s Alpha and McDonald’s Omega typically range from 0 to 1. The suggested cut-offs are given below.

  • > 0.9: Excellent

  • 0.8 - 0.9: Good

  • 0.7 - 0.8: Acceptable

  • < 0.7: Poor (may have items that don’t “belong”)

anxiety.mea.rel <- Reliability.fun(Anxiety.mea)
anxiety.mla.rel <- Reliability.fun(Anxiety.mla)
anxiety.rel <- Reliability.fun(Comp.Anxiety)
efficacy.rel <- Reliability.fun(Comp.SelfEfficacy)
tech.rel <- Reliability.fun(Comp.Technology)
cooperative.rel <- Reliability.fun(Comp.Cooporative)
deductive.rel <- Reliability.fun(Comp.Deductive)
demo.rel <- Reliability.fun(Comp.Demonstration)
inductive.rel <- Reliability.fun(Comp.Inductive)
integrate.rel <- Reliability.fun(Comp.Integrative)
lecture.rel <- Reliability.fun(Comp.LectureType)
repetive.rel <- Reliability.fun(Comp.Repetitive)
#after.rel <- Reliability.fun(Comp.AfterClass)
#in.class.rel <- Reliability.fun(Comp.InClass)
engage.rel <- Reliability.fun(Comp.Engage)
resource.rel <- Reliability.fun(Comp.Resource)
##
Rel.table <-rbind(anxiety.mea = anxiety.mea.rel, anxiety.mla = anxiety.mla.rel,
                  anxiety = anxiety.rel, self.efficacy = efficacy.rel,
                  technology = tech.rel, cooperative = cooperative.rel,
                  deductive = deductive.rel, demonstration = demo.rel,
                  inductive = inductive.rel, integrate = integrate.rel,
                  lecture = lecture.rel, repetitive = repetive.rel, 
                  engage = engage.rel, resource = resource.rel)
row.name <- c("anxiety.mea", "anxiety.mla",
              "anxiety", "self.efficacy", "technology", "cooperative",
              "deductive", "demonstration", "inductive", "integrate",
              "lecture", "repetitive", "engage", "resource")
col.name <- c("Cronbach alpha", "McDonald's Omega")
rownames(Rel.table) <- row.name
colnames(Rel.table) <- col.name
pander(Rel.table)
  Cronbach alpha McDonald’s Omega
anxiety.mea 0.842 0.8465
anxiety.mla 0.8035 0.8066
anxiety 0.8646 0.8668
self.efficacy 0.6619 0.7156
technology 0.9253 0.9275
cooperative 0.8878 0.8878
deductive 0.8775 0.8785
demonstration 0.8819 0.8824
inductive 0.8907 0.8911
integrate 0.8274 0.8311
lecture 0.8994 0.9011
repetitive 0.8866 0.8881
engage 0.8335 0.8337
resource 0.7472 0.7515

We can see from the above table that all calculated coefficients exceeded the recommended threshold of 0.7, indicating good reliability. The results confirm that the instruments used in this study demonstrate strong internal consistency, meaning the items within each scale reliably measure the same underlying construct.

7 Composite Scoring

The core purpose of constructing multi-item surveys is to measure complex concepts with greater accuracy, reliability, and depth than a single question ever could. All instruments used in this study are based on a single-factor construct using the Likert scales. The commonly used methods for defining single index to capture the information of the single-factor construct are classified in three categories

7.1 Summing the Raw Likert Scores

The simplest approach is to sum the raw Likert scores into a composite score that represents a single factor within the survey construct. This method is valid provided that all questionnaire items are equally important, as each captures a similar amount of information about the underlying factor.

However, this approach is violated in several critical scenarios, leading to a biased and unreliable composite score. For example, Violation of Equal Importance: The core assumption is that each item is a equally strong indicator of the construct. In reality, items often have different levels of importance. Summing items with high and low levels of importance equally gives undue weight to weaker indicators, effectively diluting the composite score with noise and reducing its validity.

7.2 FA Approach

Confirmatory Factor Analysis (CFA) is a very common and often practical approach to validating survey instruments and create (weighted) composite score. It is a distribution dependent statistical method. However, it comes with a set of distinct some disadvantages particularly the assumption of multi-variate normal distribution. Factor loadings in CFA are estimated based on the maximum likelihood which is defined based on multivariate normal distribution.

We have used CFA to validate the instrument. Since all instruments in this study are single-factor constructs, we will calculate the single composite score for each instrument using CFA.

7.3 PCA Approach

PCA is a distribution-free method which uses a mathematical transformation (orthogonal rotation) to obtain a new coordinate system such that the first new axis (Principal Component 1) points in the direction of the maximum variance in the data. The second axis is orthogonal to the first and points in the direction of the next greatest variance, and so on. The new axes (components) are linear combinations of the original variables. Consequently, a k-item instrument will generate k principal components.

Although there debates on using PCA in psychometrics, the earliest applications of PCA in survey research can be traced back to 1950s (Stouffer et al., 1950; Cattell, 1952; Duncan, 19 ). The goal was consistently the same as it is today: to uncover the simple, latent structures that underlie the complex correlations among many observed survey questions.

Adjusting Direction of PCs

Principal Components (PCs) are new, uncorrelated axes, whereas Likert scores are ordinal rating scales. When using PCs to represent these rating scales, their direction must be aligned. A simple method to determine if a PC’s direction needs to be reversed is to examine the correlation coefficients between the naive composite average scores and the PC scores. If the correlation is negative, the corresponding PC should be reversed; otherwise, the default axis should be retained.

Composite Scoring Using The first Principal Component (PC1)

This approach has been employed since the 1950s (e.g., Guttman, 1954; Hirschberg & Standish, 1959; Duncan, 1961). The rationale for using the first principal component is that it accounts for the maximum variance in the data and constitutes a linear combination of all items. Much like in confirmatory factor analysis (CFA), the first principal component can be interpreted as a weighted average of individual item scores.

Composite Scoring Using Weighted Average of Item Scores Across All PCs: Doubly Weighted Average

In many real-world datasets, the underlying constructs are inherently multidimensional. Consequently, limiting the analysis to the first principal component means discarding structured information captured by subsequent components (PC2, PC3, etc.). A composite score that integrates all significant components offers a more holistic and accurate summary measure. The primary barrier to the widespread adoption of this method is the challenge associated with interpreting the composite index’s structure.

7.4 Composite Scores To Be Created

We will generate four types of composite scores for each of the 11 instruments for the purpose of empirical comparison.

  • avg: The average of the raw item scores.
  • cfa: The extract confirmatory factor analysis (cfa) score (all instruments are based on the single-factor construct).
  • pca1: The first principal component scores.
  • pca.wt: The weighted average of pca scores across all principal components.
#####
 scores = function(df, dn){
  ###############
  # mean score
  ##############
  df.mean <- rowMeans(df[, -1])
  ###########################
  ## single factor score
  ##########################
  x.var <- names(df[, -1])
  n0 <- length(x.var)
  cfa.model <-  paste("latent =~", paste(x.var, collapse = " + "))
  cfa.fit <- cfa(cfa.model, data = df[, -1], estimator = "MLM")
  composite.cfa <- lavPredict(cfa.fit)
  ##########################
  # pca analysis
  ##########################
  pca.mdl <- prcomp(df[,-1], scale = TRUE)
  pca0 <- pca.mdl$x[, 1]
  r0 = cor(pca0, df.mean)
  if(r0 < 0) {
     pca.all <- -pca.mdl$x
  }else{
    pca.all <- pca.mdl$x
  }
  first.pca = pca.all[,1]
  ##########################
  # weighted pca score
  ##########################
  var.explained <-((pca.mdl$sdev)^2) / sum((pca.mdl$sdev)^2) #
  composite_weighted_pca <- as.matrix(pca.all) %*% (var.explained)

  outdata <- as.data.frame(cbind(avg = df.mean, 
                           pca1 = first.pca, 
                           wt.pca = as.vector(composite_weighted_pca), 
                           cfa = as.vector(composite.cfa)))
  names(outdata) <- paste0(dn,".", names(outdata), sep = "")
  outdata
  }
###
Anxiety.mea.score = scores(Anxiety.mea, "Anxiety.mea")
Anxiety.mla.score = scores(Anxiety.mla, "Anxiety.mla")
Anxiety.score = scores(Comp.Anxiety, "Anxiety")
SelfEfficacy.score = scores(Comp.SelfEfficacy0, "SelfEfficacy")
Technology.score = scores(Comp.Technology, "Technology")
Cooporative.score = scores(Comp.Cooporative, "Cooporative")
Deductive.score = scores(Comp.Deductive, "Deductive")
Demonstration.score = scores(Comp.Demonstration, "Demonstration")
Inductive.score = scores(Comp.Inductive, "Inductive")
Integrative.score = scores(Comp.Integrative, "Integrative")
LectureType.score = scores(Comp.LectureType, "LectureType")
Repetitive.score = scores(Comp.Repetitive, "Repetitive")
Engage.score = scores(Comp.Engage, "Engage")
Resource.score = scores(Comp.Resource, "Resource")
##
finalDat <- cbind(demographics, Anxiety.score, Anxiety.mea.score,
                  Anxiety.mla.score, SelfEfficacy.score, Technology.score,
                  Cooporative.score, Deductive.score, Demonstration.score,Inductive.score,
                  Integrative.score, LectureType.score, Repetitive.score,
                  Engage.score, Resource.score)

8 Some Graphical Exploration

We next explore the distributions of the created composite scores and perform some empirical comparisons. The primary goal of this survey study is to investigate factors that are associated with mathematics anxiety (MA) levels. To this end, we also look the distributions each individual items in the MA instrument.

8.1 Distributions of Composite Scores

The following are distributions of four generated composite scores across all instruments. The purpose is to examine the behaviors of these composite scores, especially the doubly weighted composite score based on the principal component analysis.

plotly.fun <- function(in.data){
   in.avg <- density(in.data[,1])
   in.pc1 <- density(in.data[,2])
   in.pcw <- density(in.data[,3])
   in.cfa <- density(in.data[, 4])
   dat.name <- sub("\\..*", "",names(in.data)[1])  #sub( text)
   # plot density curves
  fig <- plot_ly(x = ~in.avg$x, y = ~in.avg$y, 
               type = 'scatter', 
               mode = 'lines', 
               name = 'avg', 
               fill = 'tozeroy')  %>% 
           # adding more density curves
       add_trace(x = ~in.pc1$x, y = ~in.pc1$y, 
                 name = 'pca1', 
                 fill = 'tozeroy')  %>% 
       add_trace(x = ~in.pcw$x, y = ~in.pcw$y, 
                 name = 'pca.wt', 
                 fill = 'tozeroy')  %>% 
       add_trace(x = ~in.cfa$x, y = ~in.cfa$y, 
                 name = 'cfa', 
                 fill = 'tozeroy')  %>% 
       layout(xaxis = list(title = 'scores'),
              yaxis = list(title = 'Density'),
              #title = dat.name,
               margin = list(
                  t = 100,  # Adjust this value to increase or decrease the top margin
                  b = 50,
                  l = 50,
                  r = 50)
             )
     fig
     }
####
in.anxiety.mea = final.anxiety.dat[, c( "Anxiety.mea.avg", "Anxiety.mea.pca1", "Anxiety.mea.wt.pca","Anxiety.mea.cfa")]
in.anxiety.mla = final.anxiety.dat[, c("Anxiety.mla.avg","Anxiety.mla.pca1", "Anxiety.mla.wt.pca","Anxiety.mla.cfa")]
###
in.anxiety = final.anxiety.dat[, c( "Anxiety.avg", "Anxiety.pca1", "Anxiety.wt.pca", "Anxiety.cfa")]
in.efficacy = final.anxiety.dat[, c( "SelfEfficacy.avg", "SelfEfficacy.pca1","SelfEfficacy.wt.pca","SelfEfficacy.cfa")]
in.technology = final.anxiety.dat[, c( "Technology.avg","Technology.pca1", "Technology.wt.pca","Technology.cfa")]
in.cooporative = final.anxiety.dat[, c("Cooporative.avg","Cooporative.pca1", "Cooporative.wt.pca","Cooporative.cfa")]
in.deductive = final.anxiety.dat[, c("Deductive.avg","Deductive.pca1","Deductive.wt.pca","Deductive.cfa")]
in.demonstration = final.anxiety.dat[, c("Demonstration.avg","Demonstration.pca1","Demonstration.wt.pca","Demonstration.cfa")]
in.inductive = final.anxiety.dat[, c( "Inductive.avg","Inductive.pca1","Inductive.wt.pca","Inductive.cfa")]
in.integrative = final.anxiety.dat[, c( "Integrative.avg", "Integrative.pca1","Integrative.wt.pca","Integrative.cfa")]
in.lectureType = final.anxiety.dat[, c( "LectureType.avg", "LectureType.pca1", "LectureType.wt.pca","LectureType.cfa")]
in.repetitive = final.anxiety.dat[, c( "Repetitive.avg", "Repetitive.pca1", "Repetitive.wt.pca","Repetitive.cfa")]
in.engage = final.anxiety.dat[, c(  "Engage.avg", "Engage.pca1", "Engage.wt.pca","Engage.cfa")]
in.resource = final.anxiety.dat[, c( "Resource.avg", "Resource.pca1", "Resource.wt.pca", "Resource.cfa")]
p.mea <- plotly.fun(in.anxiety.mea)
p.mla <- plotly.fun(in.anxiety.mla)
# Arrange in 1x2 grid
subplot(p.mea, p.mla, nrows = 1, titleX = TRUE, titleY = TRUE, margin = 0.1) %>%
  layout(
    annotations = list(
      list(x = 0.05, y = .99, text = "Anxiety.mea", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.75, y = 0.99, text = "Anxiety.mla", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
    ),
    showlegend = FALSE
  )
p1 <- plotly.fun(in.anxiety)
p2 <- plotly.fun(in.efficacy)
p3 <- plotly.fun(in.technology)
p4 <- plotly.fun(in.cooporative)
# Arrange in 2x2 grid
subplot(p1, p2, p2, p4, nrows = 2, titleX = TRUE, titleY = TRUE, margin = 0.1) %>%
  layout(
    annotations = list(
      list(x = 0.05, y = .99, text = "Anxiety", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.75, y = 0.99, text = "Self-efficacy", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.05, y = 0.4, text = "Technology", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.75, y = 0.4, text = "Coorporative", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
    ),
    showlegend = FALSE
  )
p1 <- plotly.fun(in.deductive)
p2 <- plotly.fun(in.demonstration)
p3 <- plotly.fun(in.inductive)
p4 <- plotly.fun(in.integrative)
# Arrange in 2x2 grid
subplot(p1, p2, p2, p4, nrows = 2, titleX = TRUE, titleY = TRUE, margin = 0.1) %>%
  layout(
    annotations = list(
      list(x = 0.05, y = .99, text = "Deductive", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.75, y = 0.99, text = "Demonstrative", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.05, y = 0.4, text = "Inductive", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.75, y = 0.4, text = "Intergrative", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
    ),
    showlegend = FALSE
  )
p1 <- plotly.fun(in.lectureType)
p2 <- plotly.fun(in.repetitive)
p3 <- plotly.fun(in.engage)
p4 <- plotly.fun(in.resource)
# Arrange in 2x2 grid
subplot(p1, p2, p2, p4, nrows = 2, titleX = TRUE, titleY = TRUE, margin = 0.1) %>%
  layout(
    annotations = list(
      list(x = 0.05, y = .99, text = "Lecture Type", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.75, y = 0.99, text = "Repetative", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.05, y = 0.4, text = "Engagement", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.75, y = 0.4, text = "Resource", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
    ),
    showlegend = FALSE
  )

These density curves illustrate the distributions of the four composite scores (avg, cfa, pc1, and pca.wt) for all single-factor instruments in the survey. The avg is a naive measure, derived from the arithmetic mean of the item scores. The cfa and pc1 composites are weighted averages, where the weights (loadings) are derived from distinct latent variable models. The pca.wt composite is a doubly weighted average, based on both the original item scores and all of the resulting principal components.

  • Three model-based composite scores (cfa, pc1, and pca.wt) are centered at 0 but exhibit different behaviors:
    • pc1 has the largest variance.
    • cfa has the smallest variance.
  • avg and pca.wt behave similarly, differing primarily in their locations.

The composite score avg serves as a reference point, analogous to an empirical distribution, as it uses all item scores directly. In contrast, pca.wt uses a doubly weighted average of all item scores without imposing complex distributional assumptions. This demonstrates that pca.wt is a reliable and robust composite score. For the remainder of this report, the pca.wt score will be used, with cfa occasionally employed for illustrative purposes for some special cases.

8.2 Distribution of Demographics

The distribution of demographic factors are reported in the following figures.

# Enhanced hover information
Demographic.bar <-function(in.cat, varname){
  freq.tbl <- table(in.cat)
  df <- data.frame(
      category <- names(freq.tbl),
      values <- as.vector(freq.tbl)
  )
  # High-contrast colors (manually defined)
  accessible_colors <- c(
  '#D55E00',  # Vermillion
  '#0072B2',  # Blue
  '#F0E442',  # Yellow
  '#009E73',  # Green
  '#56B4E9',  # Sky Blue
  '#E69F00',  # Orange
  '#CC79A7'   # Pink
  )
  fig <- plot_ly(df, x = ~category, y = ~values, type = 'bar',
                hoverinfo = 'text',
               text = ~paste('Category:', category, '<br>Value:', values, '<br>Percentage:', round(values/sum(values)*100, 1), '%'),
               #text = ~paste("Value:", values), 
               textposition = 'auto',
               marker = list(
                 color = accessible_colors[1:nrow(df)],
                 line = list(color = 'black', width = 2)
               ),
               textfont = list(color = 'white', size = 12)) %>%
   layout(
   # title = list(text = varname, 
                # font = list(size = 18, color = 'black')),
    xaxis = list(title = "Categories", 
                 tickfont = list(color = 'black')),
    yaxis = list(title = "Values", 
                 gridcolor = 'lightgray',
                 tickfont = list(color = 'black')),
    plot_bgcolor = 'white',
    paper_bgcolor = 'white',
    showlegend = FALSE,
    margin = list(
                  t = 100,  # Adjust this value to increase or decrease the top margin
                  b = 50,
                  l = 50,
                  r = 50)
  )
fig
}
in.cat.sex <-  final.anxiety.dat$sex
in.cat.race <-  final.anxiety.dat$race
in.cat.class <-  final.anxiety.dat$class
in.cat.major <-  final.anxiety.dat$major
in.cat.math.level <-  final.anxiety.dat$math.level
in.cat.modality <-  final.anxiety.dat$modality
##
g.sex <- Demographic.bar(in.cat.sex, "Gender Distribution")
g.race <- Demographic.bar(in.cat.race, "Racial Distribution")
g.class <- Demographic.bar(in.cat.class, "Class Distribution")
g.major <- Demographic.bar(in.cat.major, "Major Distribution")
g.math.level <- Demographic.bar(in.cat.math.level, "Math Course Level")
g.modality <- Demographic.bar(in.cat.modality, "Learning Modality")
# Arrange in 2x2 grid
subplot(g.sex, g.race, g.class, g.major, nrows = 2, titleX = FALSE, titleY = TRUE, margin = 0.1) %>%
  layout(
    annotations = list(
      list(x = 0.35, y = .99, text = "Gender", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.75, y = 0.99, text = "Race", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.35, y = 0.4, text = "Class Level", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.75, y = 0.4, text = "Major", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
    ),
    showlegend = FALSE
  )
# Arrange in 2x2 grid
subplot(g.math.level, g.modality, nrows = 1, titleX = FALSE, titleY = TRUE, margin = 0.1) %>%
  layout(
    annotations = list(
      list(x = 0.35, y = .99, text = "Math Course Level", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.75, y = 0.99, text = "Learning Modality", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
    ),
    showlegend = FALSE
  )

Only one category in variable class is less than 3% with 21 observations. Other variables don’t have issues on sparse categories.

8.3 Relationship Between Math Anxiety and Demographic Factors

A student’s demographic profile doesn’t determine their math anxiety, but it significantly influences which type of anxiety they are most vulnerable to and why. The next subsections present visual explorations of the relationship between demographic factors and the two dimensions of mathematical anxiety.

8.3.1 Mathematical Evaluation Anxiety

This is the anxiety a student feels when their mathematical ability is being formally or informally assessed. The primary fear is not of the math itself, but of the negative consequences of performing poorly. It’s performance-oriented. The stress comes from the situation of being evaluated, not necessarily from the content.

## plotly for anxiety vs gender and other categorical demographic factor
gender.plotly <- function(in.var1, in.var2){
      gender.anxiety <- plot_ly(final.anxiety.dat, 
                              x = ~sex, 
                              y = ~Anxiety.mea.wt.pca, 
                              color = as.formula(paste0("~",in.var1)),
                              type = "box",
                              boxpoints = "no",
                              jitter = 0.3,
                              pointpos = 0,
                              hoverinfo = "y + x + name",
                              hovertext = ~paste("Group:", in.var1,
                                                "<br>Factor:", sex,
                                                "<br>Score:", round(Anxiety.mea.wt.pca, 2)),
                              marker = list(size = 5, opacity = 0.7)) %>%
    layout(title = paste("Math Evaluation Anxiety (wt.PCA): Gender vs ", in.var2,""),
         xaxis = list(title = ""),
         yaxis = list(title = "Evaluation Anxiety Score"),
         boxmode = "group",
         hoverlabel = list(bgcolor = "white", font = list(size = 12)),
         margin = list(
                  t = 100,  # Adjust this value to increase or decrease the top margin
                  b = 50,
                  l = 50,
                  r = 50)
         )

 gender.anxiety 
}
gender.math.level = gender.plotly("math.level", "Math Course Level")
gender.math.level
gender.race = gender.plotly("race", "Race")
gender.race
gender.class = gender.plotly("class", "Class")
gender.class
gender.major = gender.plotly("major", "Major")
gender.major
gender.modality = gender.plotly("modality", "Modality")
gender.modality

Some of the patterns observed in this study are consistent with the existing literature.

  • Female students have relatively higher evaluation anxiety level than male students.
  • The discrepancy of evaluation anxiety level across ethnic groups also consistent with what reported in the existing literature.

8.3.2 Mathematical Learning Anxiety

Mathematical learning anxiety stems directly from the subject matter, where the primary source of distress is the act of engaging with mathematical concepts. This engagement triggers an internal state of confusion, frustration, and cognitive overload.

The next few figures examine the relationship between mathematical learning anxiety and demographic factors, using the same visual approach as we did for mathematical evaluation anxiety.

## plotly for anxiety vs gender and other categorical demographic factor
gender.plotly <- function(in.var1, in.var2){
      gender.anxiety <- plot_ly(final.anxiety.dat, 
                              x = ~sex, 
                              y = ~Anxiety.mla.wt.pca, 
                              color = as.formula(paste0("~",in.var1)),
                              type = "box",
                              boxpoints = "no",
                              jitter = 0.3,
                              pointpos = 0,
                              hoverinfo = "y + x + name",
                              hovertext = ~paste("Group:", in.var1,
                                                "<br>Factor:", sex,
                                                "<br>Score:", round(Anxiety.mla.wt.pca, 2)),
                              marker = list(size = 5, opacity = 0.7)) %>%
    layout(title = paste("Math Learning Anxiety (wt.PCA): Gender vs ", in.var2,""),
         xaxis = list(title = ""),
         yaxis = list(title = "Learning Anxiety Score"),
         boxmode = "group",
         hoverlabel = list(bgcolor = "white", font = list(size = 12)),
         margin = list(
                  t = 100,  # Adjust this value to increase or decrease the top margin
                  b = 50,
                  l = 50,
                  r = 50)
         )

 gender.anxiety 
}
gender.math.level.mla = gender.plotly("math.level", "Math Course Level")
gender.math.level.mla
gender.race.mla = gender.plotly("race", "Race")
gender.race.mla
gender.class.mla = gender.plotly("class", "Class")
gender.class.mla
gender.major.mla = gender.plotly("major", "Major")
gender.major.mla
gender.modality.mla = gender.plotly("modality", "Modality")
gender.modality.mla

8.4 The Gender Gap in Evaluation and Learning Anxiety

It turns out that, comparing to math learning anxiety, evaluation anxiety manifests the gender gap. This observation is supported by academic research. The key insight is that the gender gap in math performance is more strongly linked to the anxiety generated by the testing situation than by anxiety toward the subject matter itself (leading potential learning anxiety).

A robust body of evidence, from foundational meta-analyses (Hembree, 1990) to contemporary studies (Devine et al., 2012; Goetz et al., 2013), establishes that female students experience disproportionately high levels of math test anxiety—a factor more predictive of academic outcomes than learning anxiety. This finding illuminates the work of Else-Quest et al. (2010), demonstrating that the gender gap in math performance is profoundly shaped by anxiety in evaluative environments. Therefore, addressing the specific pressures of testing situations is essential for closing this gap.

The following figure illustrates the relationship between gender and the two types of math anxiety: learning anxiety and evaluation anxiety.

mea0 <- final.anxiety.dat[, c("sex", "Anxiety.mea.wt.pca")]
mla0 <- final.anxiety.dat[, c("sex", "Anxiety.mla.wt.pca")]
names(mea0) = c("sex", "anxiety.score")
names(mla0) = c("sex", "anxiety.score")
mea.mla <- rbind(mea0, mla0)
anxiety.type <- c(rep("mea", dim(mea0)[1]), rep("mla", dim(mea0)[1]))
mea.mla$anxiety.type <- anxiety.type
####
df = na.omit(mea.mla)
# Create more complex grouped boxplot with statistical annotations
# Custom hover information
fig <- plot_ly(df, 
               x = ~anxiety.type, 
               y = ~anxiety.score, 
               color = ~sex,
               type = "box",
               hoverinfo = "y+x+name",
               hovertemplate = paste(
                 "Gender: %{x}<br>",
                 "Anxiety Type: %{fullData.name}<br>",
                 "Anxiety Score: %{y:.2f}<br>",
                 "<extra></extra>"
               )) %>%
  layout(
    title = "Gender Disparities in Math Evaluation and Learning Anxiety",
    xaxis = list(title = ""),
    yaxis = list(title = "Anxiety Score"),
    boxmode = "group",
    hoverlabel = list(bgcolor = "white", font = list(size = 12)),
    margin = list( t = 100,  # Adjust this value to increase or decrease the top margin
                  b = 50,
                  l = 50,
                  r = 50)
  )

fig

Our results are also consistent with existing results in literature.

9 Student Perceived Teaching Strategies, Math Anxiety, and Self-efficicay

The following heatmap illustrates the pairwise correlations between anxiety levels, student-perceived teaching strategies, and other associated cognitive factors. A negative correlation between anxiety and another composite score (shown in blue) indicates that anxiety decreases as that composite score increases.

var.name <-c( "Anxiety.mea.wt.pca", "Anxiety.mla.wt.pca", "SelfEfficacy.wt.pca", "Technology.wt.pca",
              "Cooporative.wt.pca", "Deductive.wt.pca", "Demonstration.wt.pca",
              "Inductive.wt.pca", "Integrative.wt.pca", "LectureType.wt.pca",
              "Repetitive.wt.pca", "Engage.wt.pca", "Resource.wt.pca")
all.composite.scores <- final.anxiety.dat[, var.name]
names(all.composite.scores) <- c( "Anxiety.mea", "Anxiety.mla", "SelfEfficacy", "Technology",
              "Cooporative", "Deductive.", "Demonstration",
              "Inductive", "Integrative", "LectureType",
              "Repetitive", "Engage", "Resource.")

# Calculate correlation matrix
cor_matrix <- cor(all.composite.scores, use = "complete.obs")

# Convert to long format using melt
cor_long <- melt(cor_matrix)
names(cor_long) <- c("x", "y", "r")

# Remove self-correlations and upper triangle if desired
cor_long <- cor_long[cor_long$x != cor_long$y, ]

# Create interactive heatmap
plot_ly(cor_long, x = ~x, y = ~y, z = ~r, type = "heatmap",
        colorscale = "RdBu", zmin = -1, zmax = 1,
        hoverinfo = "text",
        text = ~paste("X:", x, "<br>Y:", y, "<br>r =", round(r, 3))) %>%
  layout(title = "Correlation Matrix",
         xaxis = list(title = ""),
         yaxis = list(title = ""),
         margin = list(l = 100, r = 50, b = 100, t = 50))

The figure above shows that all perceived teaching strategies are negatively correlated with both types of anxiety. In addition, students with high levels of self-efficacy tend to have low levels of math anxiety. Furthermore, the composite score for technology use is negatively correlated with both learning and evaluation anxiety, implying that technology can help reduce math anxiety. Conversely, we also see that students who use more learning resources tend to have higher learning anxiety.

In the next few subsections, we analyze relationships between the scales in this survey and compare our results with those in the existing literature.

9.1 Interrelationship Between Evaluation and Learning Anxieties

A positive correlation was found between mathematics evaluation anxiety and mathematics learning anxiety, which is consistent with previous research.

Mathematics learning anxiety is often the broader, foundational issue, stemming from negative experiences and beliefs about one’s own mathematical ability. Mathematics test anxiety is a more specific, situational manifestation of this broader anxiety, triggered by the evaluative pressure of exams.

The primary relationship is cyclical: learning anxiety fosters test anxiety, and a negative test experience reinforces learning anxiety. Gierl and Bisanz (1995) highlighted this cyclical nature. They suggested that early negative experiences with math (leading to learning anxiety) set the stage for later test anxiety. Conversely, a single traumatic test experience (e.g., a disastrous final exam) can generalize to a long-lasting, pervasive anxiety toward all math-related activities, solidifying learning anxiety. Zakaria et al. (2012) found a significant positive correlation between general mathematics anxiety and test anxiety. Students who are already anxious in daily math classes are primed for heightened anxiety when the stakes are raised in a test.

Both anxieties often stem from common roots, which explains their high positive inter-relationship.

  • Negative Past Experiences: Repeated failure or humiliation in math classes during K-12 education is a powerful predictor for both types of anxiety in college (Maloney & Beilock, 2012).

  • Societal and Environmental Factors: Cultural stereotypes (e.g., “math is for boys,” “some people just aren’t math people”) and teacher anxiety can be transmitted to students, fostering a general sense of apprehension toward the subject.

  • Fixed Mindset: The work of Carol Dweck (2006) on mindset is highly relevant. Students with a “fixed mindset” (the belief that math ability is an innate, unchangeable trait) are more vulnerable to both learning and test anxiety. Any struggle is seen as evidence of a lack of ability, causing them to avoid challenging learning and to crumble under the evaluative pressure of tests.

9.2 Student Perceived Teaching Strategies

We can see from the above correlation matrix (heatmap) that the seven dimesions of student perceived teaching strategies are highly positively correlated. This positive correlation among diverse teaching strategies like cooperative, deductive, and lecture-type methods suggests that students do not necessarily view these approaches as mutually exclusive. Instead, they may perceive them as complementary tools within an effective instructor’s repertoire. The reasons for this observed intercorrelation can be attributed to several factors.

  • Instructor Versatility and Strategic Blending: A single lesson might begin with a brief lecture to introduce a concept, use a demonstrative example, and then engage students in a cooperative problem-solving activity to apply the concept inductively. Students perceive this blending, leading to positive correlations among the strategies they observe.

  • Student Recognition of a Coherent Learning Cycle: Students may perceive that different strategies serve different, but interconnected, purposes in their learning journey. For instance, a repetitive practice session might logically follow a deductive explanation of a formula to build fluency, and an integrative project might cap a unit to show real-world application. When these strategies are sequenced effectively, students see them as parts of a whole, coherent experience, leading to positive ratings across the board (Boaler, 2016).

  • The Halo Effect of Pedagogical Richness: A classroom environment rich with varied pedagogical approaches is often more engaging. The positive affect generated by one engaging strategy (e.g., a fun cooperative activity) can create a “halo effect,” leading students to rate all the strategies used in that positive context more highly, even the more traditional ones like lecture-type instruction (Hattie, 2012).

However, these correlations can also be inflated by generalized student attitudes rather than precise reflections of discrete teaching acts. For example, the correlations might not reflect the actual frequency of use but a generalized student perception of their instructor. A student who holds a positive overall view of the teacher might rate all teaching strategies highly, regardless of how effectively each was individually deployed. This is a common form of response bias in student evaluations (Spooren et al., 2013).

The correlation might also be confounded due to lack of discriminant validity in perception. For ewxample, students, especially those without pedagogical training, may not finely discriminate between the nuanced definitions of each strategy. They might broadly perceive “the teacher explains things clearly,” which could lead them to rate deductive, demonstrative, and integrative strategies similarly because they all contribute to that overarching feeling of clarity.

9.3 The Triad of Anxiety, Self-Efficacy, and Teaching Strategies

Math self-efficacy, a concept derived from Albert Bandura’s social cognitive theory, refers to an individual’s conviction in their ability to successfully perform specific mathematical tasks. It is not a general feeling of confidence but a situation-specific belief and a robust predictor of perseverance, engagement, and academic success in mathematics (Bandura, 1997).

Conversely, math anxiety is a state of tension, apprehension, or fear that interferes with math performance. It is more than a simple dislike; it is a debilitating emotional reaction that can create a vicious cycle: anxiety leads to avoidance, which leads to poorer skills, which in turn heightens anxiety (Ashcraft, 2002).

These two constructs are typically strongly and inversely correlated. A student with high self-efficacy is less likely to experience anxiety when faced with a math problem, while a student with high anxiety will likely have their sense of efficacy eroded.

Critically, teaching strategies are not merely methods of content delivery; they are powerful environmental forces that directly shape students’ emotional and self-evaluative landscapes. Together, the triad of Perceived Teaching Strategies, Math Anxiety, and Math Self-Efficacy forms a dynamic, interconnected system that significantly influences a student’s math achievement and overall relationship with the subject.

The relationships within this triad are reciprocal. A student with high math self-efficacy may thrive in a fast-paced lecture, viewing it as an efficient way to acquire information. An anxious student in the same environment, however, may become overwhelmed and disengaged. Furthermore, students with high anxiety may actively avoid participating in cooperative groups for fear of being judged, thereby missing out on the very experiences that could build their confidence. In this way, a student’s pre-existing anxiety and self-efficacy directly shape their perception of and response to the learning environment itself.

include_graphics("TechingStrategies-Anxiety-Self-efficacy.png")

9.4 Grouping Teaching Strategies

The following density curves represent naive composite scores derived from the average of item scores for each of the seven teaching strategies. These curves illustrate the students’ perceptions of their instructors’ teaching strategies. A higher score indicates that students were more likely to perceive the use of that strategy.

var.name <-c( "Cooporative.avg", "Deductive.avg", "Demonstration.avg",
              "Inductive.avg", "Integrative.avg", "LectureType.avg",
              "Repetitive.avg")
all.composite.scores <- final.anxiety.dat[, var.name]
names(all.composite.scores) <- c("Cooperative", "Deductive", "Demonstrative",
              "Inductive", "Integrative", "Lecture",   "Repetitive")

# For older versions of tidyr
long_data <- all.composite.scores %>%
  pivot_longer(
    cols = c( Cooperative, Deductive, Demonstrative, Inductive, Integrative, Lecture, Repetitive),  # Columns to reshape
    names_to = "variable",          # New column name for variable names
    values_to = "value"             # New column name for values
  )

## Summarized stats

summary_stats <- long_data %>%
  group_by(variable) %>%
  summarise(
    mean_val = mean(value),
    median_val = median(value),
    sd_val = sd(value),
    n = n(),
    .groups = 'drop'
  )

# Create ridge plot with ggridges and convert to plotly
ridge_gg <- ggplot(long_data, aes(x = value, y = variable, fill = variable
  )) +
  geom_density_ridges(
    alpha = 0.7,
    scale = 2,  # Adjust overlap
    color = "white",
    size = 0.5,
     ) +
  scale_fill_brewer(palette = "Set1") +
  #theme(plot.title = element_text(hjust = 0)) +
  theme_ridges() +
  labs(
    title = "Distributions of Students' Perceived \n Teaching Strategy Indices",
    x = "Perceived Teaching Strategy Score",
    y = ""
  ) +
  theme(legend.position = "none",
        plot.title = element_text(hjust = 0.5),
        plot.margin = margin(t = 1.2, unit = "cm"))

# Convert to plotly
ggplotly(ridge_gg)

As shown in the figure, the repetitive, lecture-type, inductive, and demonstrative approaches were perceived as more popular than the integrative, deductive, and cooperative approaches. This observation aligns with the established classification of teaching styles in educational and psychological research and classic textbooks.

Teacher-centered Student-centered
Deductive (Teacher provides rules and examples: Joyce et al., 2015) Cooperative (Students work together: Johnson, 2014)
Lecture Type (Teacher transmits information: Brown,2007) Inductive (Students discover rules: Bruner, 1961; Prince & Felder, 2006)
Demonstrative (Teacher shows how: Borich, 2017) Integrative (Students connect ideas: Jacobs, 1989; Fogarty,1991)
Repetitive (Teacher drills the information: Ormrod, 2020)

The above classification is consistent with the one based on cognitive demand (Bloom’s Taxonomy), which categorizes strategies as requiring either lower-level thinking (remember, understand) or higher-level thinking (apply, analyze, evaluate, create).

Note: The Demonstrative Approach sub-scale in this survey measures constructs associated with both Traditional Teacher-Centered and Student-Centered Strategies. It encompasses not only the teacher’s direct demonstration of knowledge but also the use of these demonstrations to facilitate student-led solution building, characterizing it as a hybrid teaching strategy.

This classification demonstrates a spectrum of pedagogical approaches, from traditional, highly structured methods like Lecture and Deductive teaching, to modern, student-driven methods like Inductive, Cooperative, and Integrative learning. Demonstration and Repetitive practice serve specific, often complementary, roles within this spectrum.

9.5 Teaching Strategies Modulate the Triad

Teaching strategies are not merely methods of content delivery; they are powerful environmental forces that directly shape students’ emotional and self-evaluative landscapes.

Teacher-Centered Strategies

  • Lecture-type and Deductive Approaches: These methods, where the instructor presents established rules and procedures first (deductive) in a largely one-way format (lecture), can inadvertently exacerbate the triad’s negative potential. For a student with low self-efficacy or high anxiety, the rapid, impersonal pace of a lecture can reinforce feelings of inadequacy and inability to keep up. The focus on a single “correct” method can stifle the exploratory behaviors that build genuine understanding and confidence.

  • Repetitive (Drill-and-Practice) Approach: While necessary for developing procedural fluency, an over-reliance on repetitive practice can be a double-edged sword. For highly efficacious students, it can solidify skills. However, for anxious students, it can become a source of immense stress, framing mathematics as a monotonous, performance-oriented subject where mistakes are failures. This can directly undermine self-efficacy, as noted by researchers who found that environments overly focused on speed and correct answers increase anxiety (Ramirez et al., 2018).

Student-Centered Strategies

  • Inductive and Demonstrative Approaches: These strategies, which involve presenting specific examples or phenomena from which students derive patterns and rules (inductive) or visually illustrating a concept (demonstrative), actively engage students in the process of “doing mathematics.” By discovering relationships themselves, students build a more robust and personal understanding. This process of successful discovery is a potent source of mastery experience, the most influential source of self-efficacy (Bandura, 1997). As understanding deepens, anxiety often diminishes because the subject feels less mysterious and more manageable.

  • Cooperative Learning: This is perhaps one of the most powerful strategies for positively influencing the triad. Working in small groups on meaningful tasks provides multiple psychological benefits:

    • Vicarious Experience: Students observe peers, who they perceive as similar to themselves, successfully solving problems. This is a key source of self-efficacy, showing them that “if they can do it, so can I.”
    • Verbal Persuasion: Peers and the teacher can offer encouragement and feedback within a supportive, low-stakes setting.
    • Reduced Anxiety: The burden of performance is shared, mitigating the fear of public failure that can occur when a student is called on alone in a whole-class setting. Studies consistently show that cooperative learning environments are associated with lower levels of math anxiety and higher levels of self-efficacy and achievement.
  • Integrative Approach: Connecting mathematics to real-world problems and other disciplines makes the subject feel relevant and meaningful. This can help students reframe math from a set of abstract, intimidating rules to a useful tool for understanding the world. This perceived utility can increase motivation and engagement, which in turn can bolster self-efficacy and reduce anxiety by providing a compelling reason to persist through challenges.

9.6 Create Single Composite Score for the Classification

We next define two single indices to represent the teaching strategies based on the above classification. We conceptualize teacher-centered and student-centered strategies as two single-factor constructs. The indices are defined using a doubly weighted average of the principal components. Following common practice, we report the validity and reliability measures before calculating the composite scores for the two classified teaching strategies.

Validity Measures

var.name <-c("Cooporative.cfa", "Deductive.cfa", "Demonstration.cfa",
              "Inductive.cfa", "Integrative.cfa", "LectureType.cfa",
              "Repetitive.cfa")
Stratege.wt.pca <- final.anxiety.dat[, var.name]
names(Stratege.wt.pca) <- c("Cooperative", "Deductive", "Demonstrative",
              "Inductive", "Integrative", "Lecture",   "Repetitive")



teacher0 <- Stratege.wt.pca[,c("Deductive", "Demonstrative", "Lecture", "Repetitive")]
student0 <- Stratege.wt.pca[,c("Cooperative", "Inductive", "Integrative", "Deductive")]
###
###
teacher.vlid <-cfa.analysis(teacher0)
student.vlid <-cfa.analysis(student0)
##
vlid.table <-rbind(teacher.ctrd = teacher.vlid, student.ctrd = student.vlid)
row.name <- c("teacher.ctrd", "student.ctrd")
rownames(vlid.table) <- row.name
colnames(vlid.table) <- c("std.all.min",    "pval.max", "srmr", "cfi",  "tli")
pander(vlid.table)
  std.all.min pval.max srmr cfi tli
teacher.ctrd 0.561 0 1.582e-09 1 1
student.ctrd 0.4888 0 1.526e-08 1 1

Reliability Measures

teacher <- Stratege.wt.pca[,c("Deductive", "Demonstrative", "Lecture", "Repetitive")]
student <- Stratege.wt.pca[,c("Cooperative", "Inductive", "Integrative")]
##
teacher.reliability <- Reliability.fun(teacher)
student.reliability <- Reliability.fun(student)
##
Rel.table <-rbind(teach = anxiety.mea.rel, anxiety.mla = anxiety.mla.rel)
row.name <- c("Teacher", "Student")
col.name <- c("Cronbach alpha", "McDonald's Omega")
rownames(Rel.table) <- row.name
colnames(Rel.table) <- col.name
pander(Rel.table)
  Cronbach alpha McDonald’s Omega
Teacher 0.842 0.8465
Student 0.8035 0.8066

The above goodness-of-fit and reliability measures exceed the required thresholds of validity and reliability of an instrument. The doubly weighted average of the original composite scores of teaching strategies and appended to the analytic dataset.

###################################### 
##### 
scores = function(df, dn){
  ###########################
  ## single factor score
  ##########################
  x.var <- names(df)
  n0 <- length(x.var)
  cfa.model <-  paste("latent =~", paste(x.var, collapse = " + "))
  cfa.fit <- cfa(cfa.model, data = df, estimator = "MLM")
  composite.cfa <- lavPredict(cfa.fit)
  ##########################
  # pca analysis
  ##########################
  pca.mdl <- prcomp(df, scale = TRUE)
  pca0 <- pca.mdl$x[, 1]
  r0 = cor(pca0, composite.cfa)
  if(r0 < 0) {
     pca.all <- -pca.mdl$x
  }else{
    pca.all <- pca.mdl$x
  }
  first.pca = pca.all[,1]
  ##########################
  # weighted pca score
  ##########################
  var.explained <-((pca.mdl$sdev)^2) / sum((pca.mdl$sdev)^2) #
  composite_weighted_pca <- as.matrix(pca.all) %*% (var.explained)

  outdata <- as.data.frame(cbind(pca1 = first.pca, 
                           wt.pca = as.vector(composite_weighted_pca), 
                           cfa = as.vector(composite.cfa)))
  names(outdata) <- paste0(dn,".", names(outdata), sep = "")
  outdata
 }
###
teacher <- scores(teacher, "Teacher.ctrd")
student <- scores(student, "Student.ctrd")
Anxiety.Analytic.Data <- cbind(finalDat, teacher, student)

10 Linear Regression Analysis

This section moves from the previous descriptive analyses to a regression analysis of the association between math anxiety and related factors. We examine two distinct but interconnected types of math anxiety, evaluation anxiety and learning anxiety, while temporarily setting aside their interconnection.

The regression model also incorporates the two teaching strategies as predictor variables. We also realized that the two variables are correlated.

10.1 Factors Associated with Evaluation Anxiety

For the association analysis, we will build two regression models. Both models include a common set of demographic predictors. The first model uses individual teaching strategies as additional predictors, while the second uses grouped teaching strategies.

10.1.1 Using Individual Teaching Strategies

The analysis begins with a regression model incorporating all individual teaching approaches alongside demographic and related variables as predictors.

BestSubsetsReg <- function(best.subset.model){
   # View the results
   reg.summary <- summary(best.subset.model)
 
   # Plotting the results (optional, for visualization)
   # plot(best.subset.model, scale = "adjr2", col = "skyblue") # or "bic", "cp", etc.
   par(mfrow = c(2,2))
   plot(reg.summary$rss, xlab = "Number of Variables", ylab = "RSS", type = "l", col = "navy")
   plot(reg.summary$adjr2, xlab = "Number of Variables", ylab = "Adjusted RSq", type = "l", col = "navy")
   # We will now plot a red dot to indicate the model with the largest adjusted R^2 statistic.
   # The which.max() function can be used to identify the location of the maximum point of a vector
   adj.r2.max = which.max(reg.summary$adjr2) 

   # The points() command works like the plot() command, except that it puts points 
   # on a plot that has already been created instead of creating a new plot
   points(adj.r2.max, reg.summary$adjr2[adj.r2.max], col ="darkred", cex = 2, pch = 20)
   # We'll do the same for C_p and BIC, this time looking for the models with the SMALLEST statistic
   plot(reg.summary$cp, xlab = "Number of Variables", ylab = "Cp", type = "l")
   cp.min = which.min(reg.summary$cp) # 10
   points(cp.min, reg.summary$cp[cp.min], col = "darkred", cex = 2, pch = 20)

   plot(reg.summary$bic, xlab = "Number of Variables", ylab = "BIC", type = "l")
   bic.min = which.min(reg.summary$bic) # 6
   points(bic.min, reg.summary$bic[bic.min], col = "darkred", cex = 2, pch = 20)
}

We use the best subset approach to model identification. The following are plots of a few performance measures agaist the number of predictor variables to be retained in the final model.

mea.lm.data <- anxiety.reg.data[,-c(2,20,21)]
mea.best.subsets.lm <- regsubsets(MEA ~., data = mea.lm.data, nvmax = 8,  method = "backward" )
BestSubsetsReg(mea.best.subsets.lm)

The above figure indicates that the 6-predictor model is the optimal choice. The results obtained from this subset selection method are identical to those obtained via stepwise variable selection.

mea.lm.data <- anxiety.reg.data[,-c(2,20,21)]
mea.lm <- lm(MEA ~SelfEfficacy + Inductive + Integrative + math.level + sex +
    Technology, data = mea.lm.data)
stepwise.mea.model <- stepAIC(mea.lm, direction = "both", trace = 0)
#summary(stepwise.mea.model)
par(mfrow = c(2,2))
plot(stepwise.mea.model )

The figure above reveals a clear pattern of non-constant residual variance (heteroscedasticity) as the fitted values increase. Because the response variable includes negative values, a standard Box-Cox transformation is not applicable for identifying a power transformation. Instead, we will use bootstrap confidence intervals for all regression coefficients to assess their significance, thereby maintaining the response variable on its original scale.

### Bootstrap confidence intervals
boot.coef <- function(data, indices) {
  d <- data[indices, ]  # resample rows
  fit <- lm(MEA ~ SelfEfficacy + Integrative + math.level + 
    sex + Technology, data = d)
  return(coef(fit))      # return coefficients
}
######
# Extract CIs for all coefficients
get.all.boot.cis <- function(boot.output, type = "perc") {
  n.coef <- ncol(boot.output$t)
  ci.matrix <- matrix(NA, nrow = n.coef, ncol = 2)
  rownames(ci.matrix) <- colnames(boot.output$t)
  colnames(ci.matrix) <- c("bt.low.95%", "bt.up.95%")
  
  for (i in 1:n.coef) {
    ci.obj <- boot.ci(boot.output, type = type, index = i)
    if (type == "perc") {
      ci.matrix[i, ] <- ci.obj$percent[4:5]
    }
  }
  
  return(ci.matrix)
}

# Perform bootstrap (R = number of resamples)
set.seed(311)  # for reproducibility
boot.results <- boot(mea.lm.data, boot.coef, R = 1000)
## bootstrap CI
all.cis <- get.all.boot.cis(boot.results)
InferenceTable <- round(cbind(summary(stepwise.mea.model)$coef, all.cis),4)
print(InferenceTable) 
                 Estimate Std. Error  t value Pr(>|t|) bt.low.95% bt.up.95%
(Intercept)       -0.0210     0.1041  -0.2016   0.8403    -0.2418    0.2075
SelfEfficacy      -0.6110     0.0428 -14.2851   0.0000    -0.6856   -0.5308
Integrative       -0.1767     0.0375  -4.7053   0.0000    -0.2567   -0.0986
math.levelmath02   0.1455     0.1250   1.1642   0.2448    -0.1218    0.3904
math.levelmath03   0.3499     0.1326   2.6393   0.0085     0.0589    0.6198
math.levelmath04   0.3729     0.1569   2.3776   0.0177     0.0453    0.6864
math.levelother   -0.0103     0.1584  -0.0650   0.9482    -0.3461    0.2985
math.levelstats   -0.0529     0.1261  -0.4199   0.6747    -0.3230    0.1945
sexmale           -0.3431     0.0800  -4.2867   0.0000    -0.5067   -0.1820
Technology        -0.1221     0.0248  -4.9314   0.0000    -0.1745   -0.0645

The above table revealed several significant predictors of math evaluation anxiety. Higher self-efficacy was strongly associated with lower anxiety (\(\beta = -0.577, p < 0.001\)), indicating that students who are more confident in their mathematical abilities experience less evaluation-related stress. Similarly, integrative instruction approach showed a negative relationship with anxiety (\(\beta = -0.178, p < 0.001\)), implying that this teaching method may help reduce student anxiety. Course level also played a role: students enrolled in math03 (calc A and brief Calc) (\(\beta = 0.276, p = 0.040\)) and math04 (above Calc A) (\(\beta = 0.363, p = 0.023\)) courses exhibited higher anxiety compared to the reference group, while other course levels were not significant. Gender was a significant factor, with male students reporting lower anxiety than females (\(\beta = -0.344, p < 0.001\)). Finally, technology use was negatively associated with anxiety (\(\beta = -0.137, p < 0.001\)), indicating that greater engagement with technology corresponds to reduced math evaluation anxiety.

In summary, math evaluation anxiety was significantly lower among students with higher self-efficacy. An integrative teaching approach and appropriate use of technology may help reduce math evaluation anxiety. Male students tended to experience less stress. Conversely, students enrolled in higher-level math courses (math03 and math04) reported slightly higher anxiety.

10.1.2 Using Grouped Teaching Strategies

Next, we build a regression model using the aggregated teaching styles: teacher-centered and student-centered, plus some demographic factors. We will still use the best subset selection method jointly with other related methods to identify the final model.

# Perform best subset selection
# 'nvmax' specifies the maximum number of variables to consider in a subset
best.subset.model.ctrd <- regsubsets(MEA~ sex+ race+ class+ major+ math.level+ modality+ SelfEfficacy+ Technology + TeacherCtrd+ StudentCtrd, data = anxiety.reg.data, nvmax = 10,  method = "backward" )
BestSubsetsReg(best.subset.model.ctrd)

The following residual diagnostic plots indicate abnormal patterns. Particular, non-constant variance of the residual variance.

# The final model
best.subset.ctrd <- lm(MEA~ sex+ math.level+  SelfEfficacy+ Technology + StudentCtrd, data = anxiety.reg.data)
#summary(best.subset.ctrd)$coef
par(mfrow = c(2,2))
plot(best.subset.ctrd)

We next perform Bootstrap regression to construct robust confidence intervals for the regression coefficients.

### Bootstrap confidence intervals
boot.coef.ctrd <- function(data, indices) {
  d <- data[indices, ]  # resample rows
  fit <- lm(MEA~ sex+ math.level+  SelfEfficacy+ Technology + StudentCtrd, data = d)
  return(coef(fit))      # return coefficients
}

# Perform bootstrap (R = number of resamples)
set.seed(312)  # for reproducibility
boot.results.ctrd <- boot(anxiety.reg.data, boot.coef.ctrd, R = 1000)
# Combine the linear regression output with the bootstrap CI
all.ctrd.cis <- get.all.boot.cis(boot.results.ctrd )
InferenceTable <- round(cbind(summary(best.subset.ctrd)$coef, all.ctrd.cis ),4)
print(InferenceTable) 
                 Estimate Std. Error  t value Pr(>|t|) bt.low.95% bt.up.95%
(Intercept)       -0.0121     0.1045  -0.1156   0.9080    -0.2168    0.2161
sexmale           -0.3591     0.0800  -4.4912   0.0000    -0.5276   -0.1960
math.levelmath02   0.1471     0.1253   1.1740   0.2408    -0.1139    0.3998
math.levelmath03   0.3304     0.1336   2.4726   0.0137     0.0588    0.5984
math.levelmath04   0.3859     0.1571   2.4571   0.0143     0.1000    0.6858
math.levelother   -0.0023     0.1587  -0.0146   0.9883    -0.3427    0.3427
math.levelstats   -0.0619     0.1264  -0.4894   0.6248    -0.3389    0.1990
SelfEfficacy      -0.5969     0.0432 -13.8248   0.0000    -0.6815   -0.5190
Technology        -0.1144     0.0248  -4.6145   0.0000    -0.1682   -0.0552
StudentCtrd       -0.1438     0.0329  -4.3650   0.0000    -0.2142   -0.0763

The results above are consistent with the previous regression that used individual teaching strategies as predictors. The key difference is that the integrative teaching approach was significant in the former model, whereas student-centered teaching strategies are significant in the current one. However, since an integrative approach is a specific type of student-centered strategy, the models ultimately yield congruent findings.

10.2 Factors Associated with Learning Anxiety

Unlike math evaluation anxiety, which is fueled more by emotional and environmental factors, math learning anxiety is a direct response to the learning ecosystem. It is closely linked to the density of the learning materials, the significant cognitive load required for problem-solving, and critical external factors such as instructors’ teaching strategies.

The next regression model aims to identify factors that are directly associated with the math learning anxiety. We still take the best subset selection approach to identifying the best model.

10.2.1 Using Individual Teaching Strategies

The following model uses individual teaching strategies as predictors. This will help identify particular teaching strategies that are significantly associated with the leaning anxiety.

mla.lm.data <- anxiety.reg.data[,-c(1,20,21)]
mla.full.lm <- lm(MLA ~., data = mla.lm.data)
par(mfrow = c(2,2))
plot(mla.full.lm)

#summary(mla.full.lm)

This initial model’s residual diagnostic plot shows non-constant variance. We will not perform any power transformations on the response variable for the same reasons stated in the previous subsection. The inference on the regression coefficients will based on nonparametric Bootstrap and the classical t-tests.

We next use best subset model selection approach to identify the optimal model using various performance measures such as Cp, BIC, Adjusted coefficient of determination and the list of the significant predictors in the initial model with most of the candidate predictor variables.

mla.best.subsets.lm <- regsubsets(MLA ~., data = mla.lm.data, nvmax = 16,  method = "backward" )
BestSubsetsReg(mla.best.subsets.lm)

Since there are some pattern’s in the residual plots. we also report a non-parametric bootstrap method to construct percentile-based boostrap confidence intervals of each regression coefficients. The results are summarized in the following table.

pred.var <- names(coef(mla.best.subsets.lm ,7))[-(1:2)]
acutal.var <-c("race", pred.var)
formula.str <- paste("MLA", "~", paste(acutal.var, collapse = " + "))
MLA.model.formula <- as.formula(formula.str)
MLA.model <- lm(MLA.model.formula , data = mla.lm.data)
#summary(MLA.model )
### Bootstrap confidence intervals
boot.coef.mla <- function(data, indices) {
  d <- data[indices, ]  # resample rows
  fit <- lm(MLA.model.formula, data = d)
  return(coef(fit))      # return coefficients
}

# Perform bootstrap (R = number of resamples)
set.seed(312)  # for reproducibility
boot.results.mla<- boot(mla.lm.data, boot.coef.mla, R = 1000)
## combine regular regression output and the bootstrap CI
all.cis.mla <- get.all.boot.cis(boot.results.mla)
InferenceTable <- round(cbind(summary(MLA.model)$coef, all.cis.mla),4)
print(InferenceTable) 
              Estimate Std. Error  t value Pr(>|t|) bt.low.95% bt.up.95%
(Intercept)    -0.0333     0.1313  -0.2536   0.7999    -0.2688    0.2300
raceBlack       0.3390     0.1686   2.0106   0.0448    -0.0224    0.7130
raceother      -0.0020     0.1673  -0.0119   0.9905    -0.3513    0.3234
racewhite       0.0063     0.1357   0.0468   0.9627    -0.2549    0.2428
SelfEfficacy   -0.4001     0.0374 -10.7115   0.0000    -0.4843   -0.3207
Technology     -0.1039     0.0206  -5.0359   0.0000    -0.1458   -0.0602
Cooporative     0.0714     0.0326   2.1893   0.0289     0.0087    0.1355
Demonstration  -0.1046     0.0364  -2.8705   0.0042    -0.1820   -0.0194
Lecture        -0.1384     0.0389  -3.5579   0.0004    -0.2199   -0.0586
Resource        0.0831     0.0341   2.4373   0.0151     0.0129    0.1532

The above results indicate that Self-Efficacy, Technology use, Demonstration, and Lecture-based teaching strategies are significant negative predictors of anxiety. Specifically, higher self-efficacy (\(\beta = -0.40, p < .001\)) and greater use of technology in learning (\(\beta = -0.11, p < .001\)) are associated with lower levels of math learning anxiety. Similarly, more frequent use of demonstrative (\(\beta = -0.10, p = .006\)) and lecture approaches (\(\beta = -0.14, p < .001\)) correspond with decreased anxiety.

Conversely, the perceived Cooperative teaching approach is positively associated with learning anxiety (\(\beta = 0.07, p = .031\)). Resource-based learning (\(\beta = 0.08, p = .013\)) is also positively associated with anxiety, suggesting that student used learning resources tended to have higher anxiety in math contexts.

The race variable approached marginal significance (p =0.058), indicating that Black students tended to have higher learning anxiety (\(\beta = 0.3202, p = .058\)).

Overall, these results highlight that students’ confidence in their math abilities and certain instructional practices play a key role in reducing math learning anxiety, while others may inadvertently increase it.

10.2.2 Using Grouped Teaching Strategies

We next build a regression similar to the above one but replace the individual teaching strategy variables with the two grouped teaching strategy variables: teacher-centered amd student-centered approaches.

mla.lm.data.ctrd <- anxiety.reg.data[,-c(1, 11:17)]
mla.full.ctrd <- lm(MLA ~., data = mla.lm.data.ctrd)
par(mfrow = c(2,2))
plot(mla.full.ctrd)

# summary(mla.full.ctrd)

The same non-constant variance patterns was observed in the above residual plot. We still use subset selection procedure to identify the final model.

mla.best.subsets.ctrd <- regsubsets(MLA ~., data = mla.lm.data.ctrd, nvmax = 16,  method = "backward" )
BestSubsetsReg(mla.best.subsets.ctrd)

## final model
pred.var.ctrd <- names(coef(mla.best.subsets.ctrd,7))[-(1:4)]
acutal.var.ctrd <-c("race", "major", pred.var.ctrd)
formula.str.ctrd <- paste("MLA", "~", paste(acutal.var.ctrd, collapse = " + "))
MLA.model.formula <- as.formula(formula.str.ctrd)
MLA.model.ctrd <- lm(MLA.model.formula , data = mla.lm.data.ctrd)
#summary(MLA.model.ctrd)$coef
### Bootstrap confidence intervals
boot.coef.mla.ctrd <- function(data, indices) {
  d <- data[indices, ]  # resample rows
  fit <- lm(MLA.model.formula , data = d)
  return(coef(fit))      # return coefficients
}
# Perform bootstrap (R = number of resamples)
set.seed(312)  # for reproducibility
boot.results.ctrd <- boot(mla.lm.data.ctrd, boot.coef.mla.ctrd, R = 1000)
## combining bootstrap CIs with the default output in the lm()
all.ctrd.cis <- get.all.boot.cis(boot.results.ctrd )
InferenceTable <- round(cbind(summary(MLA.model.ctrd)$coef, all.ctrd.cis ),4)
print(InferenceTable) 
             Estimate Std. Error  t value Pr(>|t|) bt.low.95% bt.up.95%
(Intercept)    0.0680     0.1460   0.4660   0.6414    -0.2114    0.3688
raceBlack      0.3761     0.1695   2.2191   0.0268     0.0054    0.7743
raceother      0.0007     0.1677   0.0041   0.9967    -0.3602    0.3154
racewhite      0.0059     0.1361   0.0436   0.9652    -0.2763    0.2462
majorHealth   -0.0488     0.1094  -0.4455   0.6561    -0.2714    0.1970
majorOther    -0.1029     0.0866  -1.1880   0.2352    -0.2812    0.0768
majorSTEM     -0.1786     0.0817  -2.1862   0.0291    -0.3458   -0.0241
SelfEfficacy  -0.3991     0.0374 -10.6633   0.0000    -0.4757   -0.3191
Technology    -0.1049     0.0212  -4.9554   0.0000    -0.1492   -0.0570
Resource       0.0954     0.0342   2.7859   0.0055     0.0225    0.1675
TeacherCtrd   -0.1582     0.0228  -6.9261   0.0000    -0.2093   -0.1062

The overall model was statistically significant, indicating that the set of predictors meaningfully explained variance in math learning anxiety.

Among demographic variables, race was a significant predictor. Specifically, Black students reported significantly higher anxiety than the reference Asian group (\(\beta = 0.34, p = .043\)), whereas students identifying as White or Other racial groups did not differ significantly from the reference group (\(p > .05\)). Additionally, students majoring in STEM fields reported significantly lower anxiety compared to those outside STEM majors (\(\beta = −0.17, p = .039\)). Academic majors categorized as Health or Other did not show significant relationships with anxiety (\(p > .05\)).

Psychological and instructional factors demonstrated notable associations with math learning anxiety. Higher levels of self-efficacy were strongly associated with lower anxiety (\(\beta = −0.39, p < .001\)), representing the largest effect in the model. More frequent use of technology-supported learning (\(\beta = −0.10, p < .001\)) and teacher-centered approaches (\(\beta = −0.18, p < .001\)) will help reduce anxiety levels. In contrast, increased reliance on resource-based learning strategies was positively associated with anxiety (\(\beta = 0.09, p = .011\)). Although student-centered instruction showed a positive association with anxiety, this effect did not reach statistical significance (\(\beta = 0.06, p = .074\)).

Together, these results demonstrate that confidence in one’s mathematical ability and specific instructional methods play an important role in shaping students’ math learning anxiety. Approaches that provide structured guidance—such as teacher-centered delivery and technology integration—appear to reduce anxiety, whereas greater emphasis on independent resource-based learning may contribute to increased anxiety.

11 Structural Equation Modeling Approach

When working with multiple constructs, each measured by multiple survey items, we are working with latent variables. Structural equation modeling (SEM) is ideal because it explicitly models the measurement (relationships between items and their latent construct) and structural (relationships between the constructs) parts simultaneously. Models such as linear regression, multivariate regression, path analysis, confirmatory factor analysis, and structural regression can be thought of as special cases of SEM. The following relationships are possible in SEM:

  • observed to observed variables (\(\gamma\), e.g., regression)
  • latent to observed variables (\(\lambda\), e.g., confirmatory factor analysis)
  • latent to latent variables (\(\gamma, \beta\), e.g., structural regression)

SEM uniquely encompasses both measurement and structural models. The measurement model relates observed to latent variables and the structural model relates latent to latent variables. Kline’s (2023) is a classic and modern text covers up-to-date methods and applications. The estimation of model parameters in SEM is based on the maximum likelihood function with the assumption that all observed variables following multivariate normal distribution.

11.1 Notations and Technical Terms in SEM

Some Technical Terms in SEM:

  • observed variable: a variable that exists in the data, a.k.a item or manifest variable

  • latent variable: a variable that is constructed and does not exist in the data

  • exogenous variable: an independent variable either observed (x) or latent (\(\xi\)) that explains an endogenous variable

  • endogenous variable: a dependent variable, either observed (y) or latent (\(\eta\)) that has a causal path leading to it

  • measurement model: a model that links observed variables with latent variables

  • indicator: an observed variable in a measurement model (can be exogenous or endogenous)

  • factor: a latent variable defined by its indicators (can be exogenous or endogenous)

  • loading: a path between an indicator and a factor

  • structural model: a model that specifies causal relationships among exogenous variables to endogenous variables (can be observed or latent)

  • regression path: a path between exogenous and endogenous variables (can be observed or latent)

11.2 SEM Path Model

A path model serves as the visual and mathematical blueprint for a Structural Equation Model (SEM). This diagram employs a standardized notation to represent hypothesized relationships between variables. The specific model to be tested, which examines the complex structural relationships between endogenous and exogenous variables, has the following structure:

include_graphics("HypotheticalSEM.png")

To better understand the advantages and disadvantages of Structural Equation Modeling (SEM) for analyzing complex relationships—such as those between latent variables like math evaluation and learning anxiety. we will briefly describe its mathematical formulation and MLE of all model parameters using the above hypothetical SEM path model in the appendix.

11.3 SEM Implementation

We use the R lavaan library to implement the SEM to assess the relationship between math evaluation, learning anxiety, and related exogenous variables. The output presents results based on standardized variables. The interpretation of the regression coefficients is similar to that in a regular regression model, indicating the change in the outcome (in standard deviations) for a one-standard-deviation increase in a predictor.

Quick Reference of lavaan Syntax

  • ~ predict, used for regression of observed outcome to observed predictors (e.g., y ~ x)
  • 1=~ indicator1, used for latent variable to observed indicator in factor analysis measurement models (e.g., f =~ q + r + s)
  • `~~ covariance (e.g., x ~~ x)
  • ~1 intercept or mean (e.g., x ~ 1 estimates the mean of variable x)
  • 1* fixes parameter or loading to one (e.g., f =~ 1*q)
  • NA* frees parameter or loading (useful to override default marker method, (e.g., f =~ NA*q)
  • a* labels the parameter ‘a’, used for model constraints (e.g., f =~ a*q)
set.seed(12321)
Anxiety.mea <- Comp.Anxiety[, c("AMAS.2", "AMAS.4", "AMAS.5",  "AMAS.8")]
Anxiety.mla <- Comp.Anxiety[, c("AMAS.1", "AMAS.3", "AMAS.6", "AMAS.7", "AMAS.9")]
names(Anxiety.mea) <- c("MEA2", "MEA4", "MEA5",  "MEA8")  
names(Anxiety.mla) <- c("MLA1", "MLA3", "MLA6", "MLA7", "MLA9")
factor.names <- c("Technology.wt.pca", "SelfEfficacy.wt.pca", "Engage.wt.pca", "sex",
                  "Teacher.ctrd.wt.pca", "Student.ctrd.wt.pca", "Resource.wt.pca")
##
factor.var <- Anxiety.Analytic.Data[, factor.names]
names(factor.var) <- c("Tech", "Efficacy", "Engage", "gender",
                  "Teacher.ctrd", "Student.ctrd", "Resource")

### strategies var
stratgy.var <-c("Cooporative.wt.pca", "Deductive.wt.pca", "Demonstration.wt.pca", "Inductive.wt.pca","Integrative.wt.pca" ,"LectureType.wt.pca", "Repetitive.wt.pca" )
strategy.name <- c("Coop", "Deduc", "Demon", "Induc","Integ" ,"Lect", "Repet" )
teachingstrategy <- Anxiety.Analytic.Data[, stratgy.var]
names(teachingstrategy) <- strategy.name 
SEM.data <- cbind(Anxiety.mea, Anxiety.mla, factor.var,teachingstrategy )

###  SEM models

SEMModel <-
' Eval.Anxiety =~  MEA2 + MEA4 + MEA5 + MEA8  ## measurement model for Eval.Anxiety
  Learn.Anxiety =~ MLA1 + MLA3 + MLA6 + MLA7 + MLA9   ## measurement model for Learn.Anxiety 
  TeacherCtrd =~ Deduc + Lect + Demon + Repet  # Teacher centered
  StudentCtrd =~ Coop + Induc + Integ  # Student centered
  Eval.Anxiety ~ Tech + Efficacy + Engage + gender + TeacherCtrd + StudentCtrd + Resource    ## Eval.Anxiety as an outcome
  Learn.Anxiety ~ Tech + Efficacy + Engage + gender + TeacherCtrd+ StudentCtrd + Resource    ## Learn.Anxiety as an outcome
  Eval.Anxiety ~~ Learn.Anxiety     ## correlation between Eval.Anxiety and Learn.Anxiety 
'
 
output <- sem(model = SEMModel, data = SEM.data, std.lv = TRUE,  estimator = "WLSMV",
              mimic = "Mplus")
results <- summary(output, standardized = TRUE, fit.measures = TRUE)

The component regression and latent models in the SEM are specified in the following.

  ## measurement model for Eval.Anxiety
  Eval.Anxiety =~  MEA2 + MEA4 + MEA5 + MEA8            
  ## measurement model for Learn.Anxiety 
  Learn.Anxiety =~ MLA1 + MLA3 + MLA6 + MLA7 + MLA9  
  # Latent regression of teaching Strategies
  TeacherCtrd =~ Deduc + Lect + Demon + Repet  # Teacher centered
  StudentCtrd =~ Coop + Induc + Integ  # Student centered
  ## Eval.Anxiety as an outcome
  Eval.Anxiety ~ Tech + Efficacy + Engage + gender + Teacher.ctrd + Student.ctrd + Resource + race   
  ## Learn.Anxiety as an outcome
  Learn.Anxiety ~ Tech + Efficacy + Engage + gender + Teacher.ctrd + Student.ctrd + Resource + race  
  Eval.Anxiety ~~ Learn.Anxiety     ## correlation between Eval.Anxiety and Learn.Anxiety 

The key goodness-of-fit statistics and estimated parameters are summarized in the following.

The regression coefficients and factor loadings in the above table are summarized in the following SEM path diagram generated using lavaanPlot function.

lavaanPlot(model = output,
           coefs = TRUE,
           stand = TRUE,
           stars = c("regress"))  # Add significance stars

The path diagram generated by R for the SEM analysis is not easy to read. Therefore, we sketched a new path diagram that includes only the significant regression coefficients and factor loadings.

include_graphics("FittedlSEM.png")

11.4 Results and Discussion of SEM Anlysis

A structural equation model (SEM) was estimated to examine the effects of perceived teaching strategies and student characteristics on two dimensions of mathematics anxiety: Math Evaluation Anxiety (MEA) and Math Learning Anxiety (MLA). The model demonstrated excellent fit to the data:

\[ \chi^2(168) = 542.75, \, p < .001, \, \text{CFI} = .968, \, \text{TLI} = .962, \, \text{RMSEA} = .057 \, [90\% \text{CI } .051, .062], \, \text{SRMR} = .059. \]


Measurement Model

Standardized loadings were consistently strong across latent factors (\(\lambda = .53\)–.89), supporting reliability and convergent validity. The model explained 42.9% of the variance in MEA and 29.7% in MLA.

Table 1. Standardized Factor Loadings and Variance Explained for Latent Constructs
Latent_Variable Indicator Lambda R2
Math Evaluation Anxiety MEA2 0.88 0.77
MEA4 0.84 0.70
MEA5 0.67 0.45
MEA8 0.65 0.42
Math Learning Anxiety MLA1 0.53 0.28
MLA3 0.71 0.51
MLA6 0.74 0.54
MLA7 0.64 0.40
MLA9 0.73 0.54
Teacher-Centered Deductive 0.88 0.78
Lecture Type 0.89 0.79
Demonstration 0.80 0.64
Repetitive 0.75 0.56
Student-Centered Cooperative 0.73 0.54
Inductive 0.87 0.76
Integrative 0.68 0.46

Structural Model

Standardized regression coefficients are shown in Table 2. Negative coefficients indicate reduced anxiety.

Table2 <- data.frame(
Predictor = c("Technology Use","Self-Efficacy","Gender",
"Technology Use","Self-Efficacy","Engagement",
"Teacher-Centered Strategies","Student-Centered Strategies","Resource Availability"),
Outcome = c("Evaluation Anxiety","Evaluation Anxiety","Evaluation Anxiety",
"Learning Anxiety","Learning Anxiety","Learning Anxiety",
"Learning Anxiety","Learning Anxiety","Learning Anxiety"),
Beta = c(-.16,-.49,-.14,
-.22,-.45,-.09,
1.54,-1.87,.13),
SE = c(.04,.03,.04,
.04,.04,.04,
.82,.82,.04),
z = c(-3.91,-14.56,-3.88,
-5.14,-12.58,-2.50,
1.88,-2.29,3.07),
p = c("< .001","< .001","< .001",
"< .001","< .001",".012",
".060",".022",".002")
)

kable(Table2, caption = "Table 2. Standardized Structural Regression Paths Predicting Math Anxiety")
Table 2. Standardized Structural Regression Paths Predicting Math Anxiety
Predictor Outcome Beta SE z p
Technology Use Evaluation Anxiety -0.16 0.04 -3.91 < .001
Self-Efficacy Evaluation Anxiety -0.49 0.03 -14.56 < .001
Gender Evaluation Anxiety -0.14 0.04 -3.88 < .001
Technology Use Learning Anxiety -0.22 0.04 -5.14 < .001
Self-Efficacy Learning Anxiety -0.45 0.04 -12.58 < .001
Engagement Learning Anxiety -0.09 0.04 -2.50 .012
Teacher-Centered Strategies Learning Anxiety 1.54 0.82 1.88 .060
Student-Centered Strategies Learning Anxiety -1.87 0.82 -2.29 .022
Resource Availability Learning Anxiety 0.13 0.04 3.07 .002

Consistent with expectations, * More effectively using technology reduced MEA (\(\beta = -0.16\), \(p < .001\)) and MLA (\(\beta = -0.22\), \(p < .001\)). * Higher Self-efficacy students tended to have lower MEA (\(\beta = -0.49\), \(p < .001\)) and MLA (\(\beta = -0.45\), \(p < .001\)). * More Engagement reduced MLA (\(\beta = -0.09\), \(p = .012\)), and * **gender* was significant. Male students tended to have lower MEA (\(\beta = -0.14\), \(p < .001\)).

Regarding teaching approaches, * student-centered strategies significantly reduced MLA (\(\beta = -1.87\), \(p = .022\)). * Teacher-centered strategies showed a marginally positive association with MLA (\(\beta = 1.54\), \(p = .060\)); however, confidence intervals included zero. Neither strategy significantly predicted MEA (\(p > .10\)).

A moderate, positive covariance remained between MEA and MLA:

\[ \phi_{MEA,MLA} = 0.50. \]

indicating that students who experienced anxiety during learning also tended to experience anxiety in evaluative situations. This is consistent with eixting research as reviewed earlier.

These findings suggest that supportive instructional approaches—particularly those emphasizing collaboration, inquiry, and student participation—play an important role in reducing students’ emotional barriers to mathematics learning.


11.5 Discussion

The purpose of this study was to examine how perceived teaching strategies, self-efficacy, technology use, engagement, and resource availability relate to two forms of mathematics anxiety: Math Evaluation Anxiety (MEA) and Math Learning Anxiety (MLA). The results of the structural equation model (SEM) provided strong support for the hypothesized associations and highlighted instructional practices that may be particularly effective for reducing students’ emotional challenges in mathematics contexts.

11.5.1 Interpretation of Key Findings

Consistent with previous research, student-centered strategies significantly reduced learning-related anxiety, suggesting that learning environments promoting collaboration, inquiry, and active engagement can mitigate negative emotional responses. Such practices may help students feel more competent and supported, reducing anxiety during math learning.

Teacher-centered approaches showed a marginally positive association with learning anxiety. While direct instruction may provide clarity and structure, excessive emphasis on performance and correctness may inadvertently heighten pressure and lead to increased anxiety (Ramirez et al., 2018). These results suggest that although teacher guidance remains important, balanced instructional approaches may be necessary to prevent adverse emotional effects.

Both self-efficacy and technology use consistently predicted lower MEA and MLA. Students who believe in their ability to succeed tend to approach math tasks with more confidence and persistence, which protects against anxiety (Bandura, 1997; Usher et al., 2019). Technology-enhanced learning opportunities—such as immediate feedback and interactive practice—may also increase comfort and control when engaging with math content.

Although smaller in magnitude, engagement also contributed to reduced anxiety during learning. When students are emotionally and behaviorally invested in math activities, they may experience increased enjoyment and reduced avoidance tendencies (Dowker et al., 2016). In contrast, resource availability was associated with slightly higher learning anxiety. This may reflect heightened expectations or perceived pressure to meet academic standards when more supports are available.

Finally, the positive covariance between MEA and MLA indicated meaningful overlap between the two constructs, consistent with the literature showing shared emotional, cognitive, and motivational underpinnings of different forms of math anxiety (Ashcraft & Moore, 2009). Together, these findings emphasize the importance of instructional and motivational factors in shaping students’ math-related emotional experiences.

11.5.2 Implications

These findings suggest that educators should foster environments that promote student autonomy and confidence, while using instructional supports that enhance understanding without increasing perceived pressure. Professional learning programs may benefit from emphasizing strategies that build emotional safety and support students’ belief in their mathematical capability (Hembree, 1990). Additionally, technology tools should be leveraged strategically to promote active participation and self-paced engagement, rather than as stand-alone resources.

11.5.3 Limitations and Future Directions

The cross-sectional design limits the ability to draw causal conclusions. Longitudinal and intervention-based research could strengthen understanding of how the identified factors contribute to anxiety reduction over time. Self-report survey methods may introduce social desirability or recall bias; therefore, multimethod approaches incorporating observational or physiological data could further validate findings. Future work may also explore instructional context, such as classroom climate or teacher attitudes, as moderators of the anxiety–strategy relationship.

11.5.4 Conclusion

Overall, this study demonstrates that math anxiety is shaped by a combination of instructional practices and personal beliefs. Encouraging student-centered instruction, self-efficacy building, technology integration, and high-quality engagement can substantially reduce both learning-related and evaluation-related anxiety. These results underscore the importance of supporting students’ emotional well-being as a foundation for their mathematical success.


12 References

Ashcraft, M. H. (2002). Math anxiety: Personal, educational, and cognitive consequences. Current directions in psychological science, 11(5), 181-185.

Ashcraft, M. H., & Moore, A. M. (2009). Mathematics anxiety and the affective drop in performance. Journal of Psychoeducational assessment, 27(3), 197-205.

Asparouhov, T., & Muthén, B. (2005, November). Multivariate statistical modeling with survey data. In Proceedings of the Federal Committee on Statistical Methodology (FCSM) research conference (pp. 14-16).

Bandalos, D. L. (2018). Measurement theory and applications for the social sciences. Guilford Publications.

Bandura, A. (1997). Self-efficacy: The exercise of control (Vol. 11). Freeman.

Boaler, J. (2015). Mathematical mindsets: Unleashing students’ potential through creative math, inspiring messages and innovative teaching. John Wiley & Sons.

Borich, G. D. (2017). Effective Teaching Methods: Research-Based Practice (9th ed.). Pearson.

Brown, H. D., & Lee, H. (1994). Teaching by principles: An interactive approach to language pedagogy (Vol. 1, p. 994). Englewood Cliffs, NJ: Prentice Hall Regents.

Brown, T. A. (2015). Confirmatory factor analysis for applied research. Guilford publications.

Bruner, J. S. (1961). The act of discovery. Harvard educational review. Cattell, R. B. (1952). Factor analysis: an introduction and manual for the psychologist and social scientist.

Chang, H., & Beilock, S. L. (2016). The math anxiety-math performance link and its relation to individual and environmental factors: A review of current behavioral and psychophysiological research. Current Opinion in Behavioral Sciences, 10, 33–38.

Cronbach, L. J. (1951). Coefficient alpha and the internal structure of tests. Biometrika, 16, 297–335.

Daker, R. J., Gattas, S. U., Sokolowski, H. M., Green, A. E., & Lyons, I. M. (2021). First-year students’ math anxiety predicts STEM avoidance and underperformance throughout university, independently of math ability. Npj Science of Learning, 6(1), 17.

Devine, A., Fawcett, K., Szűcs, D., & Dowker, A. (2012). Gender differences in mathematics anxiety and the relation to mathematics performance while controlling for test anxiety. Behavioral and brain functions, 8(1), 33.

DiStefano, C., Zhu, M., & Mindrila, D. (2009). Understanding and using factor scores: Considerations for the applied researcher. Practical assessment, research, and evaluation, 14(1).

Dowker, A., Sarkar, A., & Looi, C. Y. (2016). Mathematics anxiety: What have we learned in 60 years?. Frontiers in psychology, 7, 508.

Dreger, R. M., & Aiken Jr, L. R. (1957). The identification of number anxiety in a college population. Journal of Educational Psychology, 48(6), 344.

Duncan, O. D. (1961). A socioeconomic index for all occupations. Occupations and social status..

Dweck, C. S. (2006). Mindset: The new psychology of success. Random house.

Else-Quest, N. M., Hyde, J. S., & Linn, M. C. (2010). Cross-national patterns of gender differences in mathematics: a meta-analysis. Psychological bulletin, 136(1), 103.

Finney, S. J., & DiStefano, C. (2006). Non-normal and categorical data in structural equation modeling. Structural equation modeling: A second course, 10(6), 269-314.

Flora, D. B. (2017). Statistical Methods for the Social and Behavioural Sciences: A Model-Based Approach. SAGE.

Fogarty, R. (1991). The mindful school: How to integrate the curricula. Palatine, IL. SkyLight Publishing, Inc. Retrieved February, 22, 2002.

Gierl, M. J., & Bisanz, J. (1995). Anxieties and attitudes related to mathematics in grades 3 and 6. The Journal of experimental education, 63(2), 139-158.

Goetz, T., Bieg, M., Lüdtke, O., Pekrun, R., & Hall, N. C. (2013). Do girls really experience more anxiety in mathematics?. Psychological science, 24(10), 2079-2087.

Gough, Mary O. (1954). Why failures in mathematics? Mathemaphobia: Causes and treatments. The Clearing House: A Journal of Educational Strategies, Issues and Ideas, 28(5), 290–294.

Guttman, L. (1954). Some necessary conditions for common-factor analysis. Psychometrika, 19(2), 149-161.

Hattie, J. (2012). Visible learning for teachers: Maximizing impact on learning. Routledge.

Hembree, R. (1990). The nature, effects, and relief of mathematics anxiety. Journal for research in mathematics education, 21(1), 33-46.

Hopko, D. R., Mahadevan, R., Bare, R. L., & Hunt, M. K. (2003). The abbreviated math anxiety scale (AMAS) construction, validity, and reliability. Assessment, 10(2), 178–182.

Hirschberg, E., & Standish, C. V. (1959). A method of deriving a stratification score by using the principal components of the correlation matrix. American Statistical Association, Proceedings of the Social Statistics Section, 1959, 220-225.

Jacobs, H. H. (1989). Interdisciplinary curriculum: Design and implementation. Association for Supervision and Curriculum Development, 1250 N. Pitt Street, Alexandria, VA 22314.

Jolliffe, I. T., & Cadima, J. (2016). Principal Component Analysis: A Review and Recent Developments. Philosophical Transactions of the Royal Society A, 374(2065), 20150202.

Johnson, D. W., Johnson, R. T., & Smith, K. A. (2014). Cooperative learning: Improving university instruction by basing practice on validated theory. Journal on excellence in college teaching, 25(3&4).

Jose M. Cardino Jr. and Ruth A. Ortega-Dela Cruz, Understanding of learning styles and teaching strategies towards improving the teaching and learning of mathematics, LUMAT General Issue, Vol 8 No 1 (2020), 19–43. Doi: 10.31129/ LUMAT.8.1.1348

Joyce, B., Weil, M., & Calhoun, E. (2015). Models of Teaching (9th ed.). Pearson.

Klee, H. L., Buehl, M. M., & Miller, A. D. (2022). Strategies for alleviating students’ math anxiety: Control-value theory in practice. Theory Into Practice, 61(1), 49–61.

Kline, R. B. (2023). Principles and practice of structural equation modeling. Guilford publications.

Lazarsfeld, P. F., Stouffer, S. A., Guttman, L., & Suchman, E. A. (1950). Measurement and prediction. SA Stouffer (éd.) Studies in social psychology in world war II, 4.

Li, C. H. (2016). The performance of ML, DWLS, and ULS estimation with robust corrections in structural equation models with ordinal variables. Psychological methods, 21(3), 369.

López-Bonilla, J. M.l and López-Bonilla, L. M. (2012), Validation of an information technology anxiety scale in undergraduates, British Journal of Educational Technology Vol 43. No 2. E56–E58. doi:10.1111/j.1467-8535.2011.01256.x

Maloney, E. A., & Beilock, S. L. (2012). Math anxiety: Who has it, why it develops, and how to guard against it. Trends in cognitive sciences, 16(8), 404-406.

Marsh, H. W. (1996). Positive and negative self-esteem: A substantively meaningful distinction or artifactors? Journal of Personality and Social Psychology, 70(4), 810–819.

McDonald, R. P. (1999). Test theory: A unified treatment. Mahwah: Erlbaum.

Moliner, L., & Alegre, F. (2020). Peer tutoring effects on students’ mathematics anxiety: A middle school experience. Frontiers in Psychology, 11, 1610.

Muthén, B. (1984). A general structural equation model with dichotomous, ordered categorical, and continuous latent variable indicators. Psychometrika, 49(1), 115-132.

O’Leary, K., Fitzpatrick, C. L., & Hallett, D. (2017). Math anxiety is related to some, but not all, experiences with math. Frontiers in Psychology, 8, 2067.

Ormrod, J. E. (2020). Human Learning (8th ed.). Pearson

Olsson, U. (1979). Maximum likelihood estimation of the polychoric correlation coefficient. Psychometrika, 44(4), 443-460.

Pletzer, B., Wood, G., Scherndl, T., Kerschbaum, H. H., & Nuerk, H.C. (2016). Components of mathematics anxiety: Factor modeling of the MARS30-brief. Frontiers in Psychology, 7, 91.

Prince, M. J., & Felder, R. M. (2006). Inductive teaching and learning methods: Definitions, comparisons, and research bases. Journal of engineering education, 95(2), 123-138.

Ramirez, G., Shaw, S. T., & Maloney, E. A. (2018). Math anxiety: Past research, promising interventions, and a new interpretation framework. Educational psychologist, 53(3), 145-164.

Richardson, F. C., & Suinn, R. M. (1972). The mathematics anxiety rating scale: Psychometric data. Journal of Counseling Psychology, 19(6), 551.

Rozgonjuk, D., Kraav, T., Mikkor, K., Orav-Puurand, K., & Täht, K. (2020). Mathematics anxiety among STEM and social science students: The roles of mathematics self-efficacy, and deep and surface approach to learning. International Journal of STEM Education, 7(1), 1–11.

Segool, N. K., Carlson, J. S., Goforth, A. N., Von Der Embse, N., & Barterian, J. A. (2013). Heightened test anxiety among young children: Elementary school students’ anxious responses to high-stakes testing. Psychology in the Schools, 50(5), 489–499.

Spooren, P., Brockx, B., & Mortelmans, D. (2013). On the validity of student evaluation of teaching: The state of the art. Review of Educational Research, 83(4), 598-642.

Usher, E. L., Li, C. R., Butz, A. R., & Rojas, J. P. (2019). Perseverant grit and self-efficacy: Are both essential for children’s academic success?. Journal of Educational Psychology, 111(5), 877.

Watson, D., Clark, L. A., & Tellegen, A. (1988). Development and validation of brief measures of positive and negative affect: The PANAS scales. Journal of Personality and Social Psychology, 54(6), 1063–1070.

Wilson, S. (2013). Mature age pre-service teachers’ mathematics anxiety and factors impacting on university retention. Mathematics Education: Yesterday, Today and Tomorrow (MERGA36), 666–673.

Zakaria, E., Zain, N. M., Ahmad, N. A., & Erlina, A. (2012). Mathematics anxiety and achievement among secondary school students. American Journal of Applied Sciences, 9(11), 1828.


13 Appendices

13.1 Mathematics of PCA

1. Problem Definition

We will use a questionnaire with four items that assess math evaluation anxiety to demonstrate the procedure.

  • \(x_1\): Thinking about a math test the day before you take it.
  • \(x_2\): Taking a math test.
  • \(x_3\): Being given a homework assignment of many difficult problems that is due for the next class meeting.
  • \(x_4\): Being given a quiz on math without knowing in advance.

Let \(\mathbf{x} = [x_1, x_2, x_3, x_4]^T\) be a random vector representing the responses of a randomly selected individual to the four items. We assume \(\mathbf{x}\) has a population mean vector \(\boldsymbol{\mu}\) and population covariance matrix \(\boldsymbol{\Sigma}\).

We collect a sample of \(n\) individuals. The data matrix is \(\mathbf{X}_{n \times 4}\), where each row is an individual’s response vector. The sample mean vector is \(\bar{\mathbf{x}}\), and the sample covariance matrix is \(\mathbf{S}\).

2. Preprocessing: Centering the Data

The first step is to center the data. We subtract the mean of each variable, creating a new data matrix \(\mathbf{Y}\):

\[ \mathbf{Y} = \mathbf{X} - \mathbf{1}\bar{\mathbf{x}}^T \]

where \(\mathbf{1}\) is an \(n \times 1\) vector of ones. The elements of \(\mathbf{Y}\) are \(y_{ij} = x_{ij} - \bar{x}_j\). From this point forward, we work with the centered data \(\mathbf{Y}\), ensuring \(E[\mathbf{y}] = \mathbf{0}\).

3. Goal of Principal Component Analysis (PCA)

The goal of PCA is to find a new set of uncorrelated variables \(\mathbf{z} = [z_1, z_2, z_3, z_4]^T\), called the (PCs), which are linear combinations of the original centered variables \(\mathbf{y}\).

\[ \mathbf{z} = \mathbf{W}^T\mathbf{y} \]

The matrix \(\mathbf{W}\) is an orthogonal matrix (\(\mathbf{W}^T\mathbf{W} = \mathbf{I}\)) whose columns \(\mathbf{w}_i\) are the . The components must satisfy:

  • The first component, \(z_1 = \mathbf{w}_1^T \mathbf{y}\), has the maximum possible variance.
  • The \(k\)-th component, \(z_k = \mathbf{w}_k^T \mathbf{y}\), has the maximum possible variance subject to being uncorrelated with (orthogonal to) all previous components \(z_1, \dots, z_{k-1}\).

4. Derivation of the First Principal Component

Let \(\mathbf{w}_1\) be the vector of weights for the first PC, \(z_1 = \mathbf{w}_1^T \mathbf{y}\). The sample variance of \(z_1\) is given by:

\[ \begin{align*} \text{Var}(z_1) &= \text{Var}(\mathbf{w}_1^T \mathbf{y}) \\ &= E[(\mathbf{w}_1^T \mathbf{y})(\mathbf{w}_1^T \mathbf{y})^T] \quad \text{(since} E[\mathbf{y}]=\mathbf{0}) \\ &= E[\mathbf{w}_1^T \mathbf{y} \mathbf{y}^T \mathbf{w}_1] \\ &= \mathbf{w}_1^T E[\mathbf{y} \mathbf{y}^T] \mathbf{w}_1 \\ &= \mathbf{w}_1^T \boldsymbol{\Sigma} \mathbf{w}_1 \end{align*} \]

In practice, we use the sample covariance matrix \(\mathbf{S} = \frac{1}{n-1} \mathbf{Y}^T \mathbf{Y}\).

We wish to maximize \(\mathbf{w}_1^T \mathbf{S} \mathbf{w}_1\) subject to the normalization constraint \(\mathbf{w}_1^T \mathbf{w}_1 = 1\) (to prevent the variance from growing arbitrarily large). We solve this using the method of Lagrange multipliers.

The Lagrangian is:

\[ \mathcal{L}(\mathbf{w}_1, \lambda_1) = \mathbf{w}_1^T \mathbf{S} \mathbf{w}_1 - \lambda_1 (\mathbf{w}_1^T \mathbf{w}_1 - 1) \]

Taking the gradient with respect to \(\mathbf{w}_1\) and setting it to zero:

\[ \frac{\partial \mathcal{L}}{\partial \mathbf{w}_1} = 2\mathbf{S}\mathbf{w}_1 - 2\lambda_1 \mathbf{w}_1 = 0 \]

This yields the key :

\[ \begin{equation} \mathbf{S} \mathbf{w}_1 = \lambda_1 \mathbf{w}_1 \end{equation} \]

Substituting the above equation back into the variance expression:

\[ \text{Var}(z_1) = \mathbf{w}_1^T \mathbf{S} \mathbf{w}_1 = \mathbf{w}_1^T (\lambda_1 \mathbf{w}_1) = \lambda_1 \mathbf{w}_1^T \mathbf{w}_1 = \lambda_1 \]

Thus, the variance of the first principal component \(z_1\) is the eigenvalue \(\lambda_1\). To maximize the variance, we must choose the .

5. Derivation of the Second Principal Component

We now seek the second component \(z_2 = \mathbf{w}_2^T \mathbf{y}\) that has maximum variance, subject to \(\mathbf{w}_2^T \mathbf{w}_2 = 1\) and \(\mathbf{w}_2^T \mathbf{w}_1 = 0\) (ensuring \(z_2\) is uncorrelated with \(z_1\)).

The Lagrangian for this problem is:

\[ \mathcal{L}(\mathbf{w}_2, \lambda_2, \phi) = \mathbf{w}_2^T \mathbf{S} \mathbf{w}_2 - \lambda_2 (\mathbf{w}_2^T \mathbf{w}_2 - 1) - \phi (\mathbf{w}_2^T \mathbf{w}_1) \]

Taking the gradient with respect to \(\mathbf{w}_2\) and setting it to zero:

\[ \frac{\partial \mathcal{L}}{\partial \mathbf{w}_2} = 2\mathbf{S}\mathbf{w}_2 - 2\lambda_2 \mathbf{w}_2 - \phi \mathbf{w}_1 = 0 \]

Multiply this equation on the left by \(\mathbf{w}_1^T\):

\[ 2\mathbf{w}_1^T\mathbf{S}\mathbf{w}_2 - 2\lambda_2 \mathbf{w}_1^T\mathbf{w}_2 - \phi \mathbf{w}_1^T\mathbf{w}_1 = 0 \]

From the eigenvalue equation for \(\mathbf{w}_1\), we know \(\mathbf{w}_1^T\mathbf{S} = \lambda_1 \mathbf{w}_1^T\). The orthogonality constraint gives \(\mathbf{w}_1^T\mathbf{w}_2=0\). Substituting these:

\[ 2\lambda_1 \mathbf{w}_1^T\mathbf{w}_2 - 0 - \phi (1) = 0 \implies 2\lambda_1 (0) - \phi = 0 \implies \phi = 0 \]

With \(\phi=0\), the gradient equation simplifies to:

\[ 2\mathbf{S}\mathbf{w}_2 - 2\lambda_2 \mathbf{w}_2 = 0 \implies \mathbf{S} \mathbf{w}_2 = \lambda_2 \mathbf{w}_2 \]

This is again an eigenvalue equation. The variance of \(z_2\) is \(\lambda_2\). To maximize the variance, we choose the eigenvector \(\mathbf{w}_2\) corresponding to the \(\lambda_2\). The orthogonality \(\mathbf{w}_2^T \mathbf{w}_1 = 0\) is automatically satisfied for distinct eigenvalues since \(\mathbf{S}\) is symmetric.

6. Subsequent Components and Full Solution

This process continues for all four components. The solution to the PCA problem is found by performing the eigendecomposition of the sample covariance matrix \(\mathbf{S}\):

\[ \mathbf{S} = \mathbf{W} \boldsymbol{\Lambda} \mathbf{W}^T \]

where:

  • \(\boldsymbol{\Lambda}\) is a diagonal matrix containing the eigenvalues in descending order: \(\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge \lambda_4 \ge 0\).
  • \(\mathbf{W} = [\mathbf{w}_1, \mathbf{w}_2, \mathbf{w}_3, \mathbf{w}_4]\) is an orthogonal matrix whose columns are the corresponding eigenvectors.

The principal components for an individual with centered response vector \(\mathbf{y}\) are then computed as:

\[ \mathbf{z} = \mathbf{W}^T \mathbf{y} \]

The \(k\)-th PC score is \(z_k = \mathbf{w}_k^T \mathbf{y}\).

7. Variance Explained

The total variance in the original data is the sum of the variances of the centered variables, which is the trace of \(\mathbf{S}\).

\[ \text{Total Variance} = \text{tr}(\mathbf{S}) = s_{11}^2 + s_{22}^2 + s_{33}^2 + s_{44}^2 \]

For a symmetric matrix, this is also equal to the sum of its eigenvalues:

\[ \text{Total Variance} = \lambda_1 + \lambda_2 + \lambda_3 + \lambda_4 \] The proportion of total variance explained by the \(k\)-th principal component is:

\[ \text{Proportion}_k = \frac{\lambda_k}{\sum_{i=1}^{4} \lambda_i} \]

The cumulative variance explained by the first \(m\) components is:

\[ \text{Cumulative}_m = \frac{\sum_{i=1}^{m} \lambda_i}{\sum_{i=1}^{4} \lambda_i} \]

8. Interpretation in our Context

In the context of our math evaluation anxiety questionnaire:

  • The loading vector \(\mathbf{w}_1 = [w_{11}, w_{12}, w_{13}, w_{14}]^T\) reveals how the original items combine to form the primary latent dimension of anxiety. For example, if all loadings are positive and similar, \(z_1\) might represent general Math Evaluation Anxiety.

  • The second component \(\mathbf{w}_2\) might contrast different types of anxiety. For instance, if \(w_{21}\) and \(w_{22}\) (test-related) are positive while \(w_{23}\) and \(w_{24}\) (pop quiz/homework) are negative, \(z_2\) might represent Test Anxiety vs. Spontaneous Evaluation Anxiety.

  • By examining the loadings, we can interpret the underlying psychological constructs that drive the correlations between the four questionnaire items.


13.2 Confirmative Factor Analysis (CFA)

This appendix provides a detailed mathematical derivation of a Confirmatory Factor Analysis (CFA) model. The observed variables are nine items related to mathematical anxiety, which are hypothesized to load onto two latent factors: Test Anxiety (TA) and Learning Anxiety (LA).

1. Latent Factors and Observed Variables

We define two latent factors:

  • \(\eta_1\): Test Anxiety (TA)
  • \(\eta_2\): Learning Anxiety (LA)

We have nine observed variables (items/questions), \(y_1\) to \(y_9\):

  • \(y_1\): Having to use tables in the back of a math book.
  • \(y_2\): Thinking about a math test the day before you take it.
  • \(y_3\): Watching the teacher work out a math problem on the board.
  • \(y_4\): Taking a math test.
  • \(y_5\): Being given a homework assignment of many difficult problems that is due for the next class meeting.
  • \(y_6\): Listening to a lecture in math class.
  • \(y_7\): Listening to another student explain how to do a math problem.
  • \(y_8\): Being given a quiz on math without knowing in advance.
  • \(y_9\): Starting a new chapter in a math book.

2. Factor Loadings and Model Structure

We hypothesize the following factor structure:

  • Factor \(\eta_1\) (Test Anxiety) loads on items \(y_2\), \(y_4\), \(y_5\), and \(y_8\).
  • Factor \(\eta_2\) (Learning Anxiety) loads on items \(y_1\), \(y_3\), \(y_6\), \(y_7\), and \(y_9\).

The fundamental equation for a CFA model for a single observed variable \(y_i\) is:

\[ y_i = \nu_i + \lambda_{i1} \eta_1 + \lambda_{i2} \eta_2 + \epsilon_i \]

where:

  • \(\nu_i\) is the intercept for observed variable \(y_i\).
  • \(\lambda_{i1}\) is the factor loading of \(y_i\) on latent factor \(\eta_1\).
  • \(\lambda_{i2}\) is the factor loading of \(y_i\) on latent factor \(\eta_2\).
  • \(\epsilon_i\) is the unique factor (measurement error) for \(y_i\).

3. The Measurement Model in Matrix Form

The model for all nine observed variables can be written compactly in matrix form. We define the following vectors and matrices:

  • \(\mathbf{y} = (y_1, y_2, \dots, y_9)^T\) is a \(9 \times 1\) vector of observed variables.
  • \(\boldsymbol{\nu} = (\nu_1, \nu_2, \dots, \nu_9)^T\) is a \(9 \times 1\) vector of intercepts.
  • \(\boldsymbol{\eta} = (\eta_1, \eta_2)^T\) is a \(2 \times 1\) vector of latent factors.
  • \(\boldsymbol{\Lambda}\) is a \(9 \times 2\) matrix of factor loadings \(\lambda_{ij}\).
  • \(\boldsymbol{\epsilon} = (\epsilon_1, \epsilon_2, \dots, \epsilon_9)^T\) is a \(9 \times 1\) vector of measurement errors.

The full measurement model is:

\[ \mathbf{y} = \boldsymbol{\nu} + \boldsymbol{\Lambda} \boldsymbol{\eta} + \boldsymbol{\epsilon} \]

Given our hypothesized factor structure, the loading matrix \(\boldsymbol{\Lambda}\) has a specific form with many elements fixed to zero. To ensure model identification, we need to set the scale of each latent variable. This is typically done by factor standardization, where the variance of the latent factor is fixed to 1, or by marker variable method, where one loading per factor is fixed to 1. We will use the latter.

Let us define:

  • \(y_2\) as the marker variable for \(\eta_1\) (Test Anxiety), so \(\lambda_{21} = 1\).
  • \(y_1\) as the marker variable for \(\eta_2\) (Learning Anxiety), so \(\lambda_{12} = 1\).

The \(\boldsymbol{\Lambda}\) matrix is then:

\[ \boldsymbol{\Lambda} = \begin{bmatrix} 0 & 1 \\ % y1 loads on eta2 (LA) 1 & 0 \\ % y2 loads on eta1 (TA) 0 & \lambda_{32} \\ % y3 loads on eta2 (LA) \lambda_{41} & 0 \\ % y4 loads on eta1 (TA) \lambda_{51} & 0 \\ % y5 loads on eta1 (TA) 0 & \lambda_{62} \\ % y6 loads on eta2 (LA) 0 & \lambda_{72} \\ % y7 loads on eta2 (LA) \lambda_{81} & 0 \\ % y8 loads on eta1 (TA) 0 & \lambda_{92} \\ % y9 loads on eta2 (LA) \end{bmatrix} \]

4. Model Assumptions

The CFA model relies on several key assumptions:

  • The latent factors and errors are multivariate normally distributed: \(\boldsymbol{\eta} \sim N(\mathbf{0}, \boldsymbol{\Psi})\) and \(\boldsymbol{\epsilon} \sim N(\mathbf{0}, \boldsymbol{\Theta}_\epsilon)\).

  • The errors and factors are independent: \(\mathrm{Cov}(\boldsymbol{\eta}, \boldsymbol{\epsilon}) = \mathbf{0}\).

  • The observed variables, being linear combinations of normal random variables, are therefore also multivariate normal: \(\mathbf{y} \sim N(\boldsymbol{\nu}, \boldsymbol{\Sigma})\).

5. Derivation of the Implied Covariance Matrix

The core of CFA is to model the population covariance matrix of the observed variables, \(\boldsymbol{\Sigma}\). The model-implied covariance matrix, denoted \(\boldsymbol{\Sigma}(\boldsymbol{\theta})\), is a function of the model parameters \(\boldsymbol{\theta}\) (loadings, factor variances/covariances, error variances).

Let \(\boldsymbol{\Psi}\) be the \(2 \times 2\) covariance matrix of the latent factors:

\[ \boldsymbol{\Psi} = \mathrm{Cov}(\boldsymbol{\eta}) = \begin{bmatrix} \psi_{11} & \psi_{12} \\ \psi_{21} & \psi_{22} \end{bmatrix} = \begin{bmatrix} \mathrm{Var}(\eta_1) & \mathrm{Cov}(\eta_1, \eta_2) \\ \mathrm{Cov}(\eta_1, \eta_2) & \mathrm{Var}(\eta_2) \end{bmatrix} \]

The implied covariance matrix \(\boldsymbol{\Sigma}(\boldsymbol{\theta})\) is derived as follows:

\[ \begin{align*} \boldsymbol{\Sigma}(\boldsymbol{\theta}) &= \mathrm{Cov}(\mathbf{y}) \\ &= \mathrm{Cov}(\boldsymbol{\nu} + \boldsymbol{\Lambda}\boldsymbol{\eta} + \boldsymbol{\epsilon}) \\ &= \mathrm{Cov}(\boldsymbol{\Lambda}\boldsymbol{\eta} + \boldsymbol{\epsilon}) \quad \text{(since } \boldsymbol{\nu} \text{ is a constant)} \\ &= \mathrm{Cov}(\boldsymbol{\Lambda}\boldsymbol{\eta}) + \mathrm{Cov}(\boldsymbol{\epsilon}) + \mathrm{Cov}(\boldsymbol{\Lambda}\boldsymbol{\eta}, \boldsymbol{\epsilon}) + \mathrm{Cov}(\boldsymbol{\epsilon}, \boldsymbol{\Lambda}\boldsymbol{\eta}) \end{align*} \]

Using assumption 2 (\(\mathrm{Cov}(\boldsymbol{\eta}, \boldsymbol{\epsilon}) = \mathbf{0}\)), the cross-terms vanish:

\[ \mathrm{Cov}(\boldsymbol{\Lambda}\boldsymbol{\eta}, \boldsymbol{\epsilon}) = \boldsymbol{\Lambda} \mathrm{Cov}(\boldsymbol{\eta}, \boldsymbol{\epsilon}) = \mathbf{0}, \quad \mathrm{Cov}(\boldsymbol{\epsilon}, \boldsymbol{\Lambda}\boldsymbol{\eta}) = \mathbf{0} \]

Therefore,

\[ \begin{align*} \boldsymbol{\Sigma}(\boldsymbol{\theta}) &= \mathrm{Cov}(\boldsymbol{\Lambda}\boldsymbol{\eta}) + \mathrm{Cov}(\boldsymbol{\epsilon}) \\ &= \boldsymbol{\Lambda} \mathrm{Cov}(\boldsymbol{\eta}) \boldsymbol{\Lambda}^T + \boldsymbol{\Theta}_{\epsilon} \\ &= \boldsymbol{\Lambda} \boldsymbol{\Psi} \boldsymbol{\Lambda}^T + \boldsymbol{\Theta}_{\epsilon} \end{align*} \]

This is the fundamental equation for the implied covariance matrix in CFA:

\[ \boxed{\boldsymbol{\Sigma}(\boldsymbol{\theta}) = \boldsymbol{\Lambda} \boldsymbol{\Psi} \boldsymbol{\Lambda}^T + \boldsymbol{\Theta}_{\epsilon}} \]

6. Parameter Estimation and Model Identification

The goal of estimation is to find parameter values \(\hat{\boldsymbol{\theta}}\) such that \(\boldsymbol{\Sigma}(\hat{\boldsymbol{\theta}})\) is as close as possible to the sample covariance matrix \(\mathbf{S}\) obtained from the data.

For identification, the number of free parameters \(t\) must be less than or equal to the number of non-redundant elements in \(\mathbf{S}\), which is \(\frac{p(p+1)}{2}\) where \(p\) is the number of observed variables (\(p=9\)).

Let’s count our free parameters \(t\):

  • Factor Loadings (\(\boldsymbol{\Lambda}\))}: We fixed \(\lambda_{21}\) and \(\lambda_{12}\) to 1. We have 7 free loadings: \(\lambda_{32}\), \(\lambda_{41}\), \(\lambda_{51}\), \(\lambda_{62}\), \(\lambda_{72}\), \(\lambda_{81}\), \(\lambda_{92}\).

  • Latent Factor Covariances (\(\boldsymbol{\Psi}\))}: We have 3 free parameters: \(\psi_{11}\) (variance of TA), \(\psi_{22}\) (variance of LA), and \(\psi_{12}\) (covariance between TA and LA).

  • Error Variances (\(\boldsymbol{\Theta}_{\epsilon}\))}: We have 9 free parameters: \(\theta_{11}, \theta_{22}, \dots, \theta_{99}\).

Total free parameters: \(t = 7 + 3 + 9 = 19\).

The number of non-redundant elements in \(\mathbf{S}\) is \(\frac{9 \times (9+1)}{2} = 45\).

Since \(45 > 19\), the model is over-identified with \(df = 45 - 19 = 26\) degrees of freedom. This is a necessary condition for identification, and with the scaling constraints we placed, the model is identified.

7. Maximum Likelihood Estimation of Parameters

This derivation has outlined the complete mathematical setup for a two-factor CFA model of mathematical anxiety. The model posits that the covariation among the nine observed items can be explained by two correlated latent factors. The next step would be to use an estimation algorithm (e.g., Maximum Likelihood) to find the parameter values that minimize the difference between \(\boldsymbol{\Sigma}(\boldsymbol{\theta})\) and the sample covariance matrix \(\mathbf{S}\), and then assess the model’s fit to the data.

The goal is to find the parameter values \(\hat{\boldsymbol{\theta}}\) that make the model-implied covariance matrix \(\boldsymbol{\Sigma}(\boldsymbol{\theta})\) most likely to have produced the observed sample data.

Given a sample of \(N\) independent and identically distributed (i.i.d.) observations \(\mathbf{y}_1, \mathbf{y}_2, \dots, \mathbf{y}_N\), the likelihood function \(L(\boldsymbol{\theta})\) is the joint probability density of observing all the data, given the parameters. Under the i.i.d. assumption, this is the product of the individual probability density functions (PDFs):

\[ L(\boldsymbol{\theta}) = \prod_{i=1}^{N} f(\mathbf{y}_i | \boldsymbol{\theta}) \]

Where \(f(\mathbf{y}_i | \boldsymbol{\theta})\) is the multivariate normal PDF for a single observation vector \(\mathbf{y}_i\):

\[ f(\mathbf{y}_i | \boldsymbol{\theta}) = \frac{1}{(2\pi)^{p/2} |\boldsymbol{\Sigma}(\boldsymbol{\theta})|^{1/2}} \exp\left[ -\frac{1}{2} (\mathbf{y}_i - \boldsymbol{\nu})^T \boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} (\mathbf{y}_i - \boldsymbol{\nu}) \right] \]

Thus, the full likelihood function is:

\[ L(\boldsymbol{\theta}) = \prod_{i=1}^{N} \left[ \frac{1}{(2\pi)^{p/2} |\boldsymbol{\Sigma}(\boldsymbol{\theta})|^{1/2}} \exp\left( -\frac{1}{2} (\mathbf{y}_i - \boldsymbol{\nu})^T \boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} (\mathbf{y}_i - \boldsymbol{\nu}) \right) \right] \]

7.1 The Log-Likelihood Function

It is computationally easier to work with the natural logarithm of the likelihood function, the log-likelihood \(\ell(\boldsymbol{\theta}) = \ln L(\boldsymbol{\theta})\). Converting the product into a sum simplifies the expression:

\[ \begin{align*} \ell(\boldsymbol{\theta}) &= \sum_{i=1}^{N} \ln f(\mathbf{y}_i | \boldsymbol{\theta}) \\ &= \sum_{i=1}^{N} \left[ -\frac{p}{2} \ln(2\pi) - \frac{1}{2} \ln |\boldsymbol{\Sigma}(\boldsymbol{\theta})| - \frac{1}{2} (\mathbf{y}_i - \boldsymbol{\nu})^T \boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} (\mathbf{y}_i - \boldsymbol{\nu}) \right] \end{align*} \]

We can factor out the terms that do not depend on the summation index \(i\):

\[ \ell(\boldsymbol{\theta}) = -\frac{Np}{2} \ln(2\pi) - \frac{N}{2} \ln |\boldsymbol{\Sigma}(\boldsymbol{\theta})| - \frac{1}{2} \sum_{i=1}^{N} \left[ (\mathbf{y}_i - \boldsymbol{\nu})^T \boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} (\mathbf{y}_i - \boldsymbol{\nu}) \right] \]

7.2. Simplifying with the Sample Covariance Matrix

The summation term is related to the sample covariance matrix. Let’s define the sample mean vector as \(\bar{\mathbf{y}} = \frac{1}{N} \sum_{i=1}^N \mathbf{y}_i\). It can be shown that:

\[ \sum_{i=1}^{N} (\mathbf{y}_i - \boldsymbol{\nu})^T \boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} (\mathbf{y}_i - \boldsymbol{\nu}) = N \cdot \mathrm{tr}\left( \boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} \mathbf{S} \right) + N (\bar{\mathbf{y}} - \boldsymbol{\nu})^T \boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} (\bar{\mathbf{y}} - \boldsymbol{\nu}) \]

where \(\mathbf{S}\) is the unbiased sample covariance matrix:

\[ \mathbf{S} = \frac{1}{N-1} \sum_{i=1}^{N} (\mathbf{y}_i - \bar{\mathbf{y}})(\mathbf{y}_i - \bar{\mathbf{y}})^T \]

and \(\mathrm{tr}(\cdot)\) is the trace operator.

In the typical setup where the model for the means is saturated (i.e., we set \(\boldsymbol{\nu} = \bar{\mathbf{y}}\)), the last term vanishes. Furthermore, for simplicity in derivation, if we use the Maximum Likelihood estimator for the covariance matrix \(\mathbf{S}_{ML} = \frac{1}{N} \sum_{i=1}^{N} (\mathbf{y}_i - \bar{\mathbf{y}})(\mathbf{y}_i - \bar{\mathbf{y}})^T\), the expression simplifies significantly.

With \(\boldsymbol{\nu} = \bar{\mathbf{y}}\), we get:

\[ \sum_{i=1}^{N} (\mathbf{y}_i - \boldsymbol{\nu})^T \boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} (\mathbf{y}_i - \boldsymbol{\nu}) = N \cdot \mathrm{tr}\left( \boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} \mathbf{S}_{ML} \right) \]

Substituting this back into the log-likelihood function, and ignoring the constant term \(-\frac{Np}{2} \ln(2\pi)\) as it does not affect optimization, we arrive at the core function minimized in ML-CFA:

\[ \boxed{\ell(\boldsymbol{\theta}) = -\frac{N}{2} \left[ \ln |\boldsymbol{\Sigma}(\boldsymbol{\theta})| + \mathrm{tr}\left( \mathbf{S}_{ML} \boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} \right) \right] + \text{constant}} \]

7.3. Maximum Likelihood Estimation

The Maximum Likelihood estimates \(\hat{\boldsymbol{\theta}}\) are found by maximizing the log-likelihood function:

\[ \hat{\boldsymbol{\theta}}_{ML} = \underset{\boldsymbol{\theta}}{\arg\max} \ \ell(\boldsymbol{\theta}) \]

In practice, this is done using iterative numerical algorithms (e.g., Newton-Raphson, Fisher Scoring) because the function \(\ell(\boldsymbol{\theta})\) is highly nonlinear in the parameters \(\boldsymbol{\theta}\).

The value of the likelihood at the maximum is also used to compute goodness-of-fit statistics, most notably the likelihood ratio test (or chi-square test of model fit), which compares the fitted model to a saturated model:

\[ \chi^2 = (N-1) F_{ML} \]

where \(F_{ML}\) is the minimum value of the discrepancy function, derived from the log-likelihood:

\[ F_{ML} = \ln |\boldsymbol{\Sigma}(\hat{\boldsymbol{\theta}})| + \mathrm{tr}\left( \mathbf{S} \boldsymbol{\Sigma}(\hat{\boldsymbol{\theta}})^{-1} \right) - \ln |\mathbf{S}| - p \]


13.3 Mathematical Formulation of SEM Model

1. Model Specification

Let the model consist of the following components:

  • Exogenous latent variables: \(\boldsymbol{\xi} = (\xi_1, \xi_2)^T\), where:
    • \(\xi_1\): Teacher-centered
    • \(\xi_2\): Student-centered
  • Endogenous latent variables: \(\boldsymbol{\eta} = (\eta_1, \eta_2)^T\), where:
    • \(\eta_1\): Math Evaluation Anxiety (MEA)
    • \(\eta_2\): Math Learning Anxiety (MLA)
  • Observed indicators for Teacher-centered: \(\mathbf{x}_1 = (x_1, x_2, x_3, x_4)^T\) where:
    • \(x_1\): Deductive
    • \(x_2\): Lecture
    • \(x_3\): Demonstration
    • \(x_4\): Repetitive
  • Observed indicators for Student-centered: \(\mathbf{x}_2 = (x_5, x_6, x_7)^T\) where:
    • \(x_5\): Cooperative
    • \(x_6\): Inductive
    • \(x_7\): Integrative
  • Observed indicators for MEA: \(\mathbf{y}_1 = (y_1, y_2, y_3, y_4)^T\) (MEA1-MEA4)
  • Observed indicators for MLA: \(\mathbf{y}_2 = (y_5, y_6, y_7, y_8, y_9)^T\) (MLA1, MLA3, MLA6, MLA7, MLA9)
  • Exogenous observed variables: \(\mathbf{w} = (w_1, w_2, w_3, w_4, w_5)^T\) where:
    • \(w_1\): Self-efficacy
    • \(w_2\): Technology
    • \(w_3\): Engagement
    • \(w_4\): Gender
    • \(w_5\): Resource

2. Measurement Models

For exogenous latent variables:

\[ \begin{align*} \mathbf{x} &= \boldsymbol{\Lambda}_x \boldsymbol{\xi} + \boldsymbol{\delta} \\ \begin{bmatrix} x_1 \\ x_2 \\ x_3 \\ x_4 \\ x_5 \\ x_6 \\ x_7 \end{bmatrix} &= \begin{bmatrix} \lambda_{1,1} & 0 \\ \lambda_{2,1} & 0 \\ \lambda_{3,1} & 0 \\ \lambda_{4,1} & 0 \\ 0 & \lambda_{5,2} \\ 0 & \lambda_{6,2} \\ 0 & \lambda_{7,2} \end{bmatrix} \begin{bmatrix} \xi_1 \\ \xi_2 \end{bmatrix} + \begin{bmatrix} \delta_1 \\ \delta_2 \\ \delta_3 \\ \delta_4 \\ \delta_5 \\ \delta_6 \\ \delta_7 \end{bmatrix} \end{align*} \]

For endogenous latent variables:

\[ \begin{align*} \mathbf{y} &= \boldsymbol{\Lambda}_y \boldsymbol{\eta} + \boldsymbol{\epsilon} \\ \begin{bmatrix} y_1 \\ y_2 \\ y_3 \\ y_4 \\ y_5 \\ y_6 \\ y_7 \\ y_8 \\ y_9 \end{bmatrix} &= \begin{bmatrix} \lambda_{1,1}^y & 0 \\ \lambda_{2,1}^y & 0 \\ \lambda_{3,1}^y & 0 \\ \lambda_{4,1}^y & 0 \\ 0 & \lambda_{5,2}^y \\ 0 & \lambda_{6,2}^y \\ 0 & \lambda_{7,2}^y \\ 0 & \lambda_{8,2}^y \\ 0 & \lambda_{9,2}^y \end{bmatrix} \begin{bmatrix} \eta_1 \\ \eta_2 \end{bmatrix} + \begin{bmatrix} \epsilon_1 \\ \epsilon_2 \\ \epsilon_3 \\ \epsilon_4 \\ \epsilon_5 \\ \epsilon_6 \\ \epsilon_7 \\ \epsilon_8 \\ \epsilon_9 \end{bmatrix} \end{align*} \]

3. Structural Model

The relationships between latent and observed variables:

\[ \begin{align*} \boldsymbol{\eta} &= \mathbf{B} \boldsymbol{\eta} + \boldsymbol{\Gamma} \boldsymbol{\xi} + \boldsymbol{\Gamma}_w \mathbf{w} + \boldsymbol{\zeta} \\ \begin{bmatrix} \eta_1 \\ \eta_2 \end{bmatrix} &= \begin{bmatrix} 0 & 0 \\ \beta_{21} & 0 \end{bmatrix} \begin{bmatrix} \eta_1 \\ \eta_2 \end{bmatrix} + \begin{bmatrix} \gamma_{11} & \gamma_{12} \\ \gamma_{21} & \gamma_{22} \end{bmatrix} \begin{bmatrix} \xi_1 \\ \xi_2 \end{bmatrix} + \begin{bmatrix} \gamma_{13} & \gamma_{14} & \gamma_{15} & \gamma_{16} & \gamma_{17} \\ \gamma_{23} & \gamma_{24} & \gamma_{25} & \gamma_{26} & \gamma_{27} \end{bmatrix} \begin{bmatrix} w_1 \\ w_2 \\ w_3 \\ w_4 \\ w_5 \end{bmatrix} + \begin{bmatrix} \zeta_1 \\ \zeta_2 \end{bmatrix} \end{align*} \]

4. Assumptions

  • The measurement errors are uncorrelated with the latent variables:

\[ \begin{align*} E(\boldsymbol{\delta}|\boldsymbol{\xi}) = \mathbf{0}, \quad E(\boldsymbol{\epsilon}|\boldsymbol{\eta}) = \mathbf{0} \end{align*} \]

  • The structural disturbances have zero mean and are uncorrelated with the exogenous variables:

\[ \begin{align*} E(\boldsymbol{\zeta}) = \mathbf{0}, \quad \text{Cov}(\boldsymbol{\zeta}, \boldsymbol{\xi}) = \mathbf{0}, \quad \text{Cov}(\boldsymbol{\zeta}, \mathbf{w}) = \mathbf{0} \end{align*} \]

  • The measurement errors and structural disturbances are mutually uncorrelated:

\[ \begin{align*} \text{Cov}(\boldsymbol{\delta}, \boldsymbol{\epsilon}) = \mathbf{0}, \quad \text{Cov}(\boldsymbol{\delta}, \boldsymbol{\zeta}) = \mathbf{0}, \quad \text{Cov}(\boldsymbol{\epsilon}, \boldsymbol{\zeta}) = \mathbf{0} \end{align*} \]

  • The measurement errors are mutually uncorrelated:

\[ \begin{align*} \text{Cov}(\boldsymbol{\delta}) = \boldsymbol{\Theta}_{\delta} = \text{diag}(\theta_{\delta,1}, \dots, \theta_{\delta,7}) \end{align*} \]

\[ \begin{align*} \text{Cov}(\boldsymbol{\epsilon}) = \boldsymbol{\Theta}_{\epsilon} = \text{diag}(\theta_{\epsilon,1}, \dots, \theta_{\epsilon,9}) \end{align*} \]

  • The structural disturbances have covariance matrix:

\[ \begin{align*} \text{Cov}(\boldsymbol{\zeta}) = \boldsymbol{\Psi} = \begin{bmatrix} \psi_{11} & \psi_{12} \\ \psi_{21} & \psi_{22} \end{bmatrix} \end{align*} \]

  • The exogenous latent variables have covariance matrix:

\[ \begin{align*} \text{Cov}(\boldsymbol{\xi}) = \boldsymbol{\Phi} = \begin{bmatrix} \phi_{11} & \phi_{12} \\ \phi_{21} & \phi_{22} \end{bmatrix} \end{align*} \]

  • The exogenous observed variables have covariance matrix:

\[ \begin{align*} \text{Cov}(\mathbf{w}) = \boldsymbol{\Phi}_w \end{align*} \]

  • All variables are multivariate normally distributed.

5. Implied Covariance Matrix

Let \(\boldsymbol{\theta}\) represent all model parameters. The implied covariance matrix of the observed variables \(\mathbf{z} = (\mathbf{x}^T, \mathbf{y}^T, \mathbf{w}^T)^T\) is:

\[ \begin{align*} \boldsymbol{\Sigma}(\boldsymbol{\theta}) = \begin{bmatrix} \boldsymbol{\Sigma}_{xx}(\boldsymbol{\theta}) & \boldsymbol{\Sigma}_{xy}(\boldsymbol{\theta}) & \boldsymbol{\Sigma}_{xw}(\boldsymbol{\theta}) \\ \boldsymbol{\Sigma}_{yx}(\boldsymbol{\theta}) & \boldsymbol{\Sigma}_{yy}(\boldsymbol{\theta}) & \boldsymbol{\Sigma}_{yw}(\boldsymbol{\theta}) \\ \boldsymbol{\Sigma}_{wx}(\boldsymbol{\theta}) & \boldsymbol{\Sigma}_{wy}(\boldsymbol{\theta}) & \boldsymbol{\Sigma}_{ww}(\boldsymbol{\theta}) \end{bmatrix} \end{align*} \]

where:

\[ \begin{align*} \boldsymbol{\Sigma}_{xx}(\boldsymbol{\theta}) &= \boldsymbol{\Lambda}_x \boldsymbol{\Phi} \boldsymbol{\Lambda}_x^T + \boldsymbol{\Theta}_{\delta} \\ \boldsymbol{\Sigma}_{yy}(\boldsymbol{\theta}) &= \boldsymbol{\Lambda}_y (\mathbf{I}-\mathbf{B})^{-1} (\boldsymbol{\Gamma} \boldsymbol{\Phi} \boldsymbol{\Gamma}^T + \boldsymbol{\Gamma}_w \boldsymbol{\Phi}_w \boldsymbol{\Gamma}_w^T + \boldsymbol{\Psi}) [(\mathbf{I}-\mathbf{B})^{-1}]^T \boldsymbol{\Lambda}_y^T + \boldsymbol{\Theta}_{\epsilon} \\ \boldsymbol{\Sigma}_{ww}(\boldsymbol{\theta}) &= \boldsymbol{\Phi}_w \\ \boldsymbol{\Sigma}_{xy}(\boldsymbol{\theta}) &= \boldsymbol{\Lambda}_x \boldsymbol{\Phi} \boldsymbol{\Gamma}^T [(\mathbf{I}-\mathbf{B})^{-1}]^T \boldsymbol{\Lambda}_y^T \\ \boldsymbol{\Sigma}_{xw}(\boldsymbol{\theta}) &= \boldsymbol{\Lambda}_x \text{Cov}(\boldsymbol{\xi}, \mathbf{w}) \\ \boldsymbol{\Sigma}_{yw}(\boldsymbol{\theta}) &= \boldsymbol{\Lambda}_y (\mathbf{I}-\mathbf{B})^{-1} (\boldsymbol{\Gamma} \text{Cov}(\boldsymbol{\xi}, \mathbf{w}) + \boldsymbol{\Gamma}_w \boldsymbol{\Phi}_w) \end{align*} \]

6. Likelihood Function

Assuming multivariate normality of the observed variables \(\mathbf{z} \sim N(\boldsymbol{\mu}, \boldsymbol{\Sigma}(\boldsymbol{\theta}))\), the likelihood function for a sample of \(n\) independent observations is:

\[ \begin{align*} L(\boldsymbol{\theta}) &= \prod_{i=1}^n (2\pi)^{-p/2} |\boldsymbol{\Sigma}(\boldsymbol{\theta})|^{-1/2} \exp\left[-\frac{1}{2}(\mathbf{z}_i - \boldsymbol{\mu})^T \boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} (\mathbf{z}_i - \boldsymbol{\mu})\right] \end{align*} \]

where \(p = 7 + 9 + 5 = 21\) is the total number of observed variables.

The log-likelihood function is:

\[ \begin{align*} \ell(\boldsymbol{\theta}) &= -\frac{np}{2} \log(2\pi) - \frac{n}{2} \log|\boldsymbol{\Sigma}(\boldsymbol{\theta})| \\ &\quad - \frac{1}{2} \sum_{i=1}^n (\mathbf{z}_i - \boldsymbol{\mu})^T \boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} (\mathbf{z}_i - \boldsymbol{\mu}) \end{align*} \]

For estimation, we typically use the discrepancy function:

\[ \begin{align*} F_{ML}(\boldsymbol{\theta}) &= \log|\boldsymbol{\Sigma}(\boldsymbol{\theta})| + \text{tr}(\mathbf{S} \boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1}) - \log|\mathbf{S}| - p \end{align*} \]

where \(\mathbf{S}\) is the sample covariance matrix.

7. Parameters to Estimate

The model parameters include:

  • Factor loadings: \(\lambda_{ij}\) in \(\boldsymbol{\Lambda}_x\) and \(\boldsymbol{\Lambda}_y\)
  • Structural coefficients: \(\beta_{ij}\) in \(\mathbf{B}\), \(\gamma_{ij}\) in \(\boldsymbol{\Gamma}\), \(\gamma_{ij}^w\) in \(\boldsymbol{\Gamma}_w\)
  • Variances and covariances: \(\phi_{ij}\) in \(\boldsymbol{\Phi}\), \(\psi_{ij}\) in \(\boldsymbol{\Psi}\), \(\phi_{w,ij}\) in \(\boldsymbol{\Phi}_w\)
  • Measurement error variances: \(\theta_{\delta,i}\) in \(\boldsymbol{\Theta}_{\delta}\), \(\theta_{\epsilon,i}\) in \(\boldsymbol{\Theta}_{\epsilon}\)

Typically, we set one loading per latent variable to 1 for identification.

8. Model Identification

The model is identified if:

  • Each latent variable has at least 3 indicators (satisfied)
  • The scale of each latent variable is set by fixing one loading to 1
  • The model meets the order condition and rank condition for identification

13.4 WLSMV for Likert Data in SEM

The Weighted Least Squares Mean and Variance Adjusted (WLSMV) estimator is a robust estimation method designed specifically for structural equation modeling (SEM) with categorical or ordinal data, particularly multi-item Likert scales. When working with ordered categorical indicators (e.g., Likert-type items with 2-7 response categories), traditional maximum likelihood (ML) estimation assumes continuous normally distributed variables, which violates the discrete nature of ordinal data.

13.4.1 Mathematical Foundation

Let \(\mathbf{x}^*\) represent the latent continuous variables underlying the observed ordinal responses \(\mathbf{x}\). The measurement model can be expressed as:

\[ \mathbf{x}^* = \boldsymbol{\Lambda} \boldsymbol{\xi} + \boldsymbol{\delta} \]

where \(\boldsymbol{\Lambda}\) is the factor loading matrix, \(\boldsymbol{\xi}\) represents latent variables, and \(\boldsymbol{\delta}\) denotes measurement errors.

The WLSMV estimator minimizes the discrepancy function:

\[ F_{WLSMV} = (\mathbf{s} - \boldsymbol{\sigma}(\boldsymbol{\theta}))' \mathbf{W}^{-1} (\mathbf{s} - \boldsymbol{\sigma}(\boldsymbol{\theta})) \]

  • \(\mathbf{s}\) is the vector of sample polychoric correlations and threshold estimates
  • \(\boldsymbol{\sigma}(\boldsymbol{\theta})\) contains the model-implied correlations and thresholds
  • \(\mathbf{W}\) is the consistent asymptotic covariance matrix of \(\mathbf{s}\)

Key Features for Multi-item Likert Data

  • Polychoric Correlations: WLSMV utilizes polychoric correlations that estimate the linear relationship between underlying continuous variables, providing more accurate estimates than Pearson correlations for ordinal data.
  • Threshold Estimation: The method estimates thresholds \(\boldsymbol{\tau}\) that define the boundaries between response categories:

\[ x_i = k \quad \text{if} \quad \tau_{k-1} < x_i^* \leq \tau_k \]

  • Diagonal Weight Matrix: WLSMV employs a diagonal weight matrix containing asymptotic variances of polychoric correlations, making it computationally efficient while maintaining robustness.

  • Mean and Variance Adjustment: The estimator incorporates scaling corrections to the test statistics, providing better approximation to \(\chi^2\) distributions with small to moderate sample sizes.

Introduction to the Estimator

The Weighted Least Squares Mean and Variance adjusted (WLSMV) estimator is a robust estimation method developed for structural equation modeling (SEM) with categorical, and in particular, ordinal observed variables. It is the recommended estimator for confirmatory factor analysis (CFA) and SEM when the indicators are measured on an ordinal scale, such as multi-item Likert scales common in social and behavioral sciences (Brown, 2015, Flora, 2022).

The need for WLSMV arises from the violation of assumptions underlying maximum likelihood (ML) estimation when observed variables are ordinal. ML assumes continuous, multivariate normal data. Likert-scale items are discrete, have limited scale points, and their distributions are often non-normal, leading to:

  • Inflated Chi-square (\(\chi^2\)) test statistics.
  • Biased standard errors.
  • Incorrect model fit indices .

13.4.2 Computational Procedure

The WLSMV estimator is part of a family of diagonally weighted least squares (DWLS) estimators. Its computation involves a specific sequence of steps to handle the categorical nature of the data.

Step 1: Estimation of Polychoric Correlations

Since the ordinal categories are manifestations of an assumed continuous, latent response distribution underlying each item, the first step involves estimating the polychoric correlation matrix. A polychoric correlation estimates the linear relationship between two assumed continuous latent response variables based on the observed ordinal data (Olsson, 1979). For each pair of items, a two-step threshold estimation is performed, followed by the estimation of their correlation.

Step 2: Estimation of the Asymptotic Covariance Matrix

The next step is to compute the full asymptotic covariance matrix of the polychoric correlation coefficients. This matrix contains the variances and covariances of the estimated polychoric correlations. It is a large matrix of dimension \(p^*(p^*-1)/2\) (where \(p\) is the number of items) and accounts for the precision of each correlation estimate. This matrix is used as the weight matrix in the fitting function (Muthen, 1984).

Step 3: The Fitting Function and Mean-Variance Adjustment

The parameter estimates are obtained by minimizing the DWLS fitting function:

\[ F_{\text{DWLS}} = (\mathbf{s} - \boldsymbol{\sigma}(\boldsymbol{\theta}))' \mathbf{W}^{-1} (\mathbf{s} - \boldsymbol{\sigma}(\boldsymbol{\theta})) \]

where \(\mathbf{s}\) is the vector of estimated polychoric correlations, \(\boldsymbol{\sigma}(\boldsymbol{\theta})\) is the vector of model-implied correlations, and \(\mathbf{W}^{-1}\) is the diagonal of the inverse of the asymptotic covariance matrix from Step 2. Using only the diagonal makes the computation more stable and feasible with smaller sample sizes compared to the full WLS estimator which uses the full matrix.

The “Mean and Variance” adjustment (MV) is the crucial final step that makes WLSMV superior to plain WLS or DWLS. Instead of using the \(\chi^2\) statistic and standard errors derived directly from the DWLS fitting function, WLSMV applies a correction:

  • The test statistic is scaled (mean-adjusted) and shifted (variance-adjusted) to more closely approximate a central \(\chi^2\) distribution.
  • Standard errors for parameter estimates are computed using a robust method (e.g., the sandwich estimator) that does not rely on the assumption of correct model specification (Asparouhov, 2005).

This adjustment makes the WLSMV estimator far more robust in small to moderate sample sizes and with large models where the asymptotic assumptions of plain WLS are not met.

13.4.3 Advantages for Multi-Item Likert Data

The WLSMV estimator provides specific advantages for modeling multi-item Likert scale data:

  • Realistic Assumptions: It does not assume continuous normality for the observed Likert items, instead leveraging the underlying continuous variable formulation.
  • Accuracy: It generally produces the most accurate parameter estimates, model fit statistics, and standard errors for ordinal data compared to ML with a robust correction or plain DWLS (Li, 2016).
  • Efficiency with Common Scales: It performs well with the typical 5- to 7-point Likert scales ubiquitous in psychological and survey research.
  • Robustness to Sample Size: While larger samples are always preferable, WLSMV performs adequately with smaller samples (e.g., \(N > 200\)) than what is required for the full WLS estimator (Bandalos, 2014).

In conclusion, WLSMV is a robust, diagonally weighted least squares estimator that uses a polychoric correlation matrix and applies a mean- and variance-adjustment to the test statistics and standard errors, making it the gold-standard choice for SEM with ordinal multi-item Likert data.

13.5 Survey Instruments

13.5.1 Abbreviated Math Anxiety Scale (AMAS)

Please rate your feelings during different activities on a scale from 1 to 5. Try not to spend too much time on any one item. There are no right or wrong answers.

1 = No bad feelings, 2 = Somewhat bad, 3 = nervous, 4 = Very bad feelings, 5 = Worst feelings


  1. Having to use tables in the back of a math book.

  2. Thinking about a math test the day before you take it.

  3. Watching the teacher work out a math problem on the board.

  4. Taking a math test.

  5. Being given a homework assignment of many difficult problems that is due for the next class meeting.

  6. Listening to a lecture in math class. [Listening to the teacher talk for a long time in math]

  7. Listening to another student explain how to do a math problem.

  8. Being given a quiz on math without knowing in advance.

  9. Starting a new chapter in a math book. [Starting a new topic in math]

13.5.2 Math Self-efficacy Scale

Select the response that matches how much you now agree with each statement. Try not to spend too much time on any one item. There are no right or wrong answers.

1 = Strongly disagree 2 = disagree 3 = neutral 4 = agree 5 = Strongly agree


  1. I usually understand a mathematical idea quickly.

  2. I have to work very hard to understand mathematics.

  3. I can connect the mathematical ideas that I have learned.

13.5.3 Teaching Strategies Questionnaire

The following statements are the ways your teacher teaches mathematics. Respond to the items listed below:

5 – Always, 4 – Often, 3 – Sometimes, 2 – Seldom, 1 – Never

Cooperative-Approach

  1. The teacher encourages students to work with others to generate as many alternatives as they can for the problem discussed.

  2. The teacher gives students enough time to think and to investigate with others to achieve a desirable result.

  3. The teacher gives students a chance to generate new concepts.

  4. The teacher applies group work in the class to serve desired objectives.

  5. The teacher distributes different teaching-learning tasks to students.

  6. The teacher lets students have their own conversations positively.

Lecture Type

  1. The teacher provides students with feedback regarding their answers at all times.

  2. The teacher ends the teaching-learning situation by clarifying and discussing diagrams suitable for students.

  3. The teacher trains students on generating specific answers to the questions raised to them.

  4. Teachers’ cognitive teaching strategies harmonize with students’ learning strategies.

  5. The teacher allows students to have more clarifications and explanations on a certain topic.

  6. The teacher trains students to solve their problems in a comfortable way.

  7. The teacher makes students take part in different roles.

Deductive Approach

  1. The teacher trains students to determine the whole idea of the topic.

  2. The teacher provides students with a chance to apply new knowledge in new real-life situations.

  3. The teacher trains students on learning the whole concept before the specific idea.

  4. Students tend to generate new information by making comparisons between their previous knowledge and the new information.

  5. The teacher moves from the abstract to the concrete examples.

  6. The teacher asks students to do written or verbal summaries of the information they get.

  7. The teacher distributes different teaching-learning tasks to students.

Inductive Approach

  1. The teacher uses specific questions to discuss the whole topic.

  2. The teacher disassembles the teaching-learning material into specific tasks that need specific responses.

  3. The teacher trains his students on distinguishing between different characteristics of the same concept.

  4. The teacher begins by presenting the main ideas of the topic at the beginning of the class.

  5. The teacher uses specific problem-solving strategies in the teaching process.

  6. The teacher assigns students a specific task within a general task.

  7. The teacher helps students to analyze the main idea to be used in discussing the topic as a whole.

Demonstration

  1. The teacher uses direct presentation to provide students with information.

  2. The teacher helps his students imitate desired models by showing them.

  3. The teacher begins the teaching-learning situation by presenting a problem to students.

  4. The teacher trains students to plan, observe, and evaluate their teaching activities.

  5. The teacher shows students how to verify information and facts before making judgments.

  6. The teacher begins with examples of the concept in the teaching-learning situation.

  7. The teacher teaches students the way to identify those simple tricks to understand the lesson.

Repetitive Exercises

  1. The teacher takes advantage of providing different activities to secure the teaching-learning process.

  2. The teacher cares about correcting students by providing many worksheets.

  3. The teacher gives similar examples during the discussion to secure the mastery of the topic.

  4. The teacher takes part in training students by providing different learning activities.

  5. The teacher helps students identify their own mistakes by doing similar worksheets.

  6. The teacher gives students the chance to correct their mistakes by answering similar questions.

  7. The teacher trains students by providing different sets of worksheets.

Integrative Approach

  1. The teacher awards students for their correct answer.

  2. Teacher depends on criteria in evaluating their students.

  3. The teacher neglects undesired behaviors in teaching-learning situations.

  4. The teacher makes use of concept maps during the teaching-learning process.

  5. The teacher facilitates students to make use of the procedures that organize memory potentials (symbolizing information).

  6. The teacher guides students to references such as dictionaries, encyclopedias, internet sites, etc.

  7. The teacher supports students in using different learning tools for the purpose of teaching the learning process.

13.5.4 Use of technologies Scale

1: strongly disagree, 2: disagree, 3. Neutral, 4 agree, 5. Strongly agree


  1. I feel apprehensive about using information technologies (ITs)

  2. Technological information sounds like confusing jargon to me

  3. I have avoided ITs because it is unfamiliar to me

  4. I hesitate to use ITs for fear of making mistakes I cannot correct

  5. ITs do not scare me at all

  6. Working with ITs would make me very nervous

  7. I do not feel threatened when others talk about ITs

  8. I feel aggressive and hostile toward ITs

  9. IT makes me feel uncomfortable

  10. I get a sinking feeling when I think of trying to use ITs

  11. IT makes me feel uneasy

  12. IT makes me feel confused

13.5.5 Learning modalities

  1. When I listen to a class lecture…
  1. I listen very closely.
  2. I try to be close to the speaker and watch the speaker.
  3. I take notes during the lecture.
  1. I like to solve word problems by…
  1. talking to a friend or to myself.
  2. using an organized approach with lists or charts.
  3. walking, pacing, or doing something active.
  1. When someone tells me numbers, but I am unable to write them down, I…
  1. Repeat the numbers to myself out loud.
  2. visualize or see the numbers in my mind.
  3. Write the numbers in the air or on the table.
  1. I learn something new by…
  1. having someone explain it to me while I listen.
  2. having someone do it for me while I watch.
  3. doing it myself.
  1. When I watch a movie, I remember…
  1. everything (what was said, music, background noises).
  2. the costumes, environment, and scenery.
  3. how it made me feel.
  1. When I am trying to remember something, I…
  1. hear what was said or what sounds were around me.
  2. visualize it happening again in my mind.
  3. feel the way I did when it happened.
  1. When I do not know how to spell a word, I…
  1. sound it out.
  2. see the word in my mind.
  3. Write the word on paper until it looks right.
  1. I enjoy reading when the story has…
  1. a lot of dialogue (characters talking to each other).
  2. a lot of descriptive words.
  3. a lot of action.
  1. I remember new people by…
  1. their names.
  2. their faces.
  3. their actions.
  1. I have a hard time concentrating when…
  1. There is a lot of noise.
  2. There are a lot of people.
  3. I am uncomfortable (too hot, too cold, uncomfortable chair, etc.).
  1. When it comes to clothes, I prefer to dress…
  1. in any way, since clothes are not that important to me.
  2. well – and I have a particular style.
  3. comfortably, so I can move around easily.
  1. If I cannot read aloud or get up and move around, I…
  1. Talk with a friend.
  2. look out a window.
  3. rock in my chair, tap my foot, drum my fingers, or jiggle my pencil.

13.5.6 Engagement and Resources

During the current school year at school, how often have you done the following: 1 - Very often, 2 - Often, 3 - Sometimes, 4 – Never

Engagement

  1. Asked questions in class.

  2. Answered questions from professors or peers in class.

  3. Contributed to class or group discussions.

  4. Practice exercises/examples.

  5. Took detailed class notes.

  6. Previewed the content before class.

  7. Reviewed class notes and other recommended exercises

  8. Worked with other students on the course materials.

Use of Resources

  1. Got help from professors via email.

  2. Went to the professor’s in-person/Zoom office hours.

  3. Used free peer tutoring through the Math Learning Center

  4. Used private tutoring services.

LS0tDQp0aXRsZTogIk1hdGhlbWF0aWNzIEFueGlldHkgU3VydmV5IFJlcG9ydCINCmF1dGhvcjogIkNoZW5nIFBlbmcgJiBMYXVyYSBQeWF0dCINCmRhdGU6ICJXZXN0IENoZXN0ZXIgVW5pdmVyc2l0eSINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdG9jX2NvbGxhcHNlZDogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgc21vb3RoX3Njcm9sbDogeWVzDQogICAgdGhlbWU6IGx1bWVuDQogIHBkZl9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICBmaWdfd2lkdGg6IDMNCiAgICBmaWdfaGVpZ2h0OiAzDQogIHdvcmRfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIGtlZXBfbWQ6IHllcw0KZWRpdG9yX29wdGlvbnM6IA0KICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lDQotLS0NCg0KYGBge2NzcywgZWNobyA9IEZBTFNFfQ0KI1RPQzo6YmVmb3JlIHsNCiAgY29udGVudDogIlRhYmxlIG9mIENvbnRlbnRzIjsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtc2l6ZTogMS4yZW07DQogIGRpc3BsYXk6IGJsb2NrOw0KICBjb2xvcjogbmF2eTsNCiAgbWFyZ2luLWJvdHRvbTogMTBweDsNCn0NCg0KDQpkaXYjVE9DIGxpIHsgICAgIC8qIHRhYmxlIG9mIGNvbnRlbnQgICovDQogICAgbGlzdC1zdHlsZTp1cHBlci1yb21hbjsNCiAgICBiYWNrZ3JvdW5kLWltYWdlOm5vbmU7DQogICAgYmFja2dyb3VuZC1yZXBlYXQ6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOjA7DQp9DQoNCmgxLnRpdGxlIHsgICAgLyogbGV2ZWwgMSBoZWFkZXIgb2YgdGl0bGUgICovDQogIGZvbnQtc2l6ZTogMjJweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGNvbG9yOiBEYXJrUmVkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQogIGZvbnQtZmFtaWx5OiAiR2lsbCBTYW5zIiwgc2Fucy1zZXJpZjsNCn0NCg0KaDQuYXV0aG9yIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxNXB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6IHN5c3RlbS11aTsNCiAgY29sb3I6IG5hdnk7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDQuZGF0ZSB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogIGZvbnQtc2l6ZTogMThweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtZmFtaWx5OiAiR2lsbCBTYW5zIiwgc2Fucy1zZXJpZjsNCiAgY29sb3I6IERhcmtCbHVlOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmgxIHsgLyogSGVhZGVyIDEgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDIwcHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoMiB7IC8qIEhlYWRlciAyIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmgzIHsgLyogSGVhZGVyIDMgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE2cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDQgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTRweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KLyogQWRkIGRvdHMgYWZ0ZXIgbnVtYmVyZWQgaGVhZGVycyAqLw0KLmhlYWRlci1zZWN0aW9uLW51bWJlcjo6YWZ0ZXIgew0KICBjb250ZW50OiAiLiI7DQoNCmJvZHkgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9DQoNCi5oaWdobGlnaHRtZSB7IGJhY2tncm91bmQtY29sb3I6eWVsbG93OyB9DQoNCnAgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9DQoNCn0NCmBgYA0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMgY29kZSBjaHVuayBzcGVjaWZpZXMgd2hldGhlciB0aGUgUiBjb2RlLCB3YXJuaW5ncywgYW5kIG91dHB1dCANCiMgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IGZpbGVzLg0KaWYgKCFyZXF1aXJlKCJrbml0ciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpDQogICBsaWJyYXJ5KGtuaXRyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwYW5kZXIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygicGFuZGVyIikNCiAgIGxpYnJhcnkocGFuZGVyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KfQ0KaWYgKCFyZXF1aXJlKCJHR2FsbHkiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiR0dhbGx5IikNCmxpYnJhcnkoR0dhbGx5KQ0KfQ0KIyBJbnN0YWxsIGFuZCBsb2FkIHRoZSBwYWNrYWdlDQppZiAoIXJlcXVpcmUoImljYSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoImljYSIpDQpsaWJyYXJ5KGljYSkNCn0NCmlmICghcmVxdWlyZSgiZmFzdElDQSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoImZhc3RJQ0EiKQ0KICBsaWJyYXJ5KGZhc3RJQ0EpDQp9DQppZiAoIXJlcXVpcmUoIk1BU1MiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJNQVNTIikNCiAgbGlicmFyeShNQVNTKQ0KfQ0KaWYgKCFyZXF1aXJlKCJnZ3Bsb3QyIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpDQogIGxpYnJhcnkoZ2dwbG90MikNCn0gDQppZiAoIXJlcXVpcmUoInBsb3RseSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInBsb3RseSIpDQogIGxpYnJhcnkocGxvdGx5KQ0KfSANCmlmICghcmVxdWlyZSgibGF2YWFuIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygibGF2YWFuIikNCiAgbGlicmFyeShsYXZhYW4pDQp9IA0KaWYgKCFyZXF1aXJlKCJzZW1Ub29scyIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInNlbVRvb2xzIikNCiAgbGlicmFyeShzZW1Ub29scykNCn0NCmlmICghcmVxdWlyZSgic3RyaW5nciIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInN0cmluZ3IiKQ0KICBsaWJyYXJ5KHN0cmluZ3IpDQp9DQppZiAoIXJlcXVpcmUoInJlc2hhcGUyIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygicmVzaGFwZTIiKQ0KICBsaWJyYXJ5KHJlc2hhcGUyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwc3ljaCIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInBzeWNoIikNCiAgbGlicmFyeShwc3ljaCkNCn0NCmlmICghcmVxdWlyZSgiZ2dyaWRnZXMiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3JpZGdlcyIpDQogIGxpYnJhcnkoZ2dyaWRnZXMpDQp9DQppZiAoIXJlcXVpcmUoIlJDb2xvckJyZXdlciIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoIlJDb2xvckJyZXdlciIpDQogIGxpYnJhcnkoUkNvbG9yQnJld2VyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJoZWF0bWFwbHkiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJoZWF0bWFwbHkiKQ0KICBsaWJyYXJ5KGhlYXRtYXBseSkNCn0NCmlmICghcmVxdWlyZSgic2VtUGxvdCIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInNlbVBsb3QiKQ0KICBsaWJyYXJ5KHNlbVBsb3QpDQp9DQppZiAoIXJlcXVpcmUoImxhdmFhblBsb3QiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJsYXZhYW5QbG90IikNCiAgbGlicmFyeShsYXZhYW5QbG90KQ0KfQ0KaWYgKCFyZXF1aXJlKCJib290IikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygiYm9vdCIpDQogIGxpYnJhcnkoYm9vdCkNCn0NCmlmICghcmVxdWlyZSgibGVhcHMiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJsZWFwcyIpDQogIGxpYnJhcnkobGVhcHMpDQp9DQojIyBsaWJyYXJ5KGxlYXBzKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICAjIGluY2x1ZGUgY29kZSBjaHVuayBpbiB0aGUgb3V0cHV0IGZpbGUNCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgIyBzb21ldGltZXMsIHlvdSBjb2RlIG1heSBwcm9kdWNlIHdhcm5pbmcgbWVzc2FnZXMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgeW91IGNhbiBjaG9vc2UgdG8gaW5jbHVkZSB0aGUgd2FybmluZyBtZXNzYWdlcyBpbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRoZSBvdXRwdXQgZmlsZS4gDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFRSVUUsICAgICMgeW91IGNhbiBhbHNvIGRlY2lkZSB3aGV0aGVyIHRvIGluY2x1ZGUgdGhlIG91dHB1dA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluIHRoZSBvdXRwdXQgZmlsZS4NCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BDQogICAgICAgICAgICAgICAgICAgICAgKSAgDQpgYGANCg0KXA0KDQojIEludHJvZHVjdGlvbg0KDQpUaGUgc3ViamVjdCBvZiBtYXRoZW1hdGljcyBjYXVzZXMgZmVhciBhbmQgZGlmZmljdWx0eSBmb3IgYSB3aWRlIHJhbmdlIG9mIHN0dWRlbnRzLiBXZSBvZnRlbiBoZWFyIHN0dWRlbnRzIGNsYWltLCAiSSBkb24ndCBsaWtlIG1hdGgiLCAiSSdtIGp1c3Qgbm90IGdvb2QgYXQgbWF0aCIsICJJJ20gbm90IGEgbWF0aCBwZXJzb24iLCBvciAiSSB3YXNuJ3QgYm9ybiB3aXRoIHRoZSBtYXRoIGdlbmUiLCBldGMuIEFsdGhvdWdoIHRoZXNlIGNsYWltcyBhcmUgbm90IHBlcmZlY3QgaW5kaWNhdG9ycyBvZiBtYXRoIGFueGlldHksIHN0dWRlbnRzIHdobyBoYXZlIHRoZXNlIGZpeGVkIG1pbmRzZXRzIHdpbGwgYmUgbW9yZSBsaWtlbHkgdG8gZXhwZXJpZW5jZSBtYXRoIGFueGlldHkuDQoNCldoaWxlIG1hdGggYW54aWV0eSBjYW4gaGF2ZSBhIHNlcmlvdXMgaW1wYWN0IG9uIGFjYWRlbWljIHBlcmZvcm1hbmNlLCBpdCBkb2VzIG5vdCBtZWFuIGEgbGFjayBvZiBtYXRoZW1hdGljcyBhYmlsaXR5LiBQcm9mLiBMYXVyZW50IFNjaHdhcnR6IGV4cGVyaWVuY2VkIG1hdGggYW54aWV0eSBpbiB0aGUgMTF0aCBncmFkZSwgYnV0IHRoaXMgZGlkIG5vdCBwcmV2ZW50IGhpbSBmcm9tIGJlY29taW5nIGEgcHJvbWluZW50IG1hdGhlbWF0aWNpYW4uIEluIGZhY3QsIGhlIHdvbiB0aGUgRmllbGRzIE1vZGVsICh0aGUgbWF0aGVtYXRpY2lhbidzIE5vYmVsIFByaXplKSBpbiAxOTUwLiBFZmZlY3RpdmVseSBtYW5hZ2luZyBtYXRoIGFueGlldHkgcmVxdWlyZXMgYSBkZWVwIHVuZGVyc3RhbmRpbmcgb2YgbWF0aCBhbnhpZXR5Lg0KDQpUaGlzIHByb2plY3QgYWltcyB0byBpZGVudGlmeSBmYWN0b3JzIHRoYXQgYXJlIHN0cm9uZ2x5IGFzc29jaWF0ZWQgd2l0aCBtYXRoIGFueGlldHkgYW5kIHVzZSB0aGVtIHRvIHJlZHVjZSBtYXRoIGFueGlldHkgYW5kLCBjb25zZXF1ZW50bHksIGltcHJvdmUgYWNhZGVtaWMgcGVyZm9ybWFuY2UuIFNwZWNpZmljYWxseToNCg0KMS4gIFRoZSByZXN1bHRzIG9mIHRoaXMgcHJvamVjdCB3aWxsIGNvbnRyaWJ1dGUgdG8gdGhlIGJvZHkgb2YgZXhpc3Rpbmcga25vd2xlZGdlLg0KDQoyLiAgSWRlbnRpZmljYXRpb24gb2YgZW52aXJvbm1lbnRhbCBmYWN0b3JzIGFpZHMgdGhlIGRldmVsb3BtZW50IG9mIGludGVydmVudGlvbiB0b29scyBmb3IgZWR1Y2F0b3JzIGFuZCBzdXBwb3J0IHN0YWZmIHRvIGhlbHAgc3R1ZGVudHMgcmVkdWNlIG1hdGggYW54aWV0eSBhbmQgaW1wcm92ZSB0aGVpciBhY2FkZW1pYyBwZXJmb3JtYW5jZS4NCg0KMy4gIFRoZSBvdXRjb21lcyBvZiB0aGlzIHByb2plY3QgY2FuIGJlIHVzZWQgdG8gaW1wbGljaXRseSBpbXByb3ZlIHJldGVudGlvbi4NCg0KIyBMaXRlcmF0dXJlIFJldmlldw0KDQpNYXRoZW1hdGljcyBhbnhpZXR5IGludm9sdmVzIGZlZWxpbmdzIG9mIGZlYXIsIHRlbnNpb24sIGFwcHJlaGVuc2lvbiwgYW5kIHBoeXNpb2xvZ2ljYWwgcmVhY3Rpdml0eSBpbnRlcmZlcmluZyB3aGVuIGluZGl2aWR1YWxzIGVuZ2FnZSB3aXRoIG51bWJlciBtYW5pcHVsYXRpb24gYW5kIG1hdGhlbWF0aWNhbCBwcm9ibGVtLXNvbHZpbmcgKHNlZSwgZm9yIGV4YW1wbGUsIFBsZXR6ZXIgZXQgYWwuIDIwMTYpLiBJbiB0aGUgVS5TLiwgYW4gZXN0aW1hdGVkIDI1JSBvZiBmb3VyLXllYXIgY29sbGVnZSBzdHVkZW50cyBhbmQgdXAgdG8gODAlIG9mIGNvbW11bml0eSBjb2xsZWdlIHN0dWRlbnRzIHN1ZmZlciBmcm9tIGEgbW9kZXJhdGUgdG8gYSBoaWdoIGRlZ3JlZSBvZiBtYXRoZW1hdGljcyBhbnhpZXR5IChDaGFuZyAmIEJlaWxvY2ssIDIwMTYpLiBUaGUgZnJlcXVlbmN5IG9mIG5lZ2F0aXZlIGVmZmVjdHMgb2YgbWF0aCBhbnhpZXR5IG9uIGNvbGxlZ2Ugc3R1ZGVudHMgaXMgaW5jcmVhc2luZy4NCg0KVGhlIGVhcmxpZXN0IHJlc2VhcmNoIG9uIG1hdGggYW54aWV0eSBjYW4gYmUgdHJhY2VkIGJhY2sgdG8gR291Z2ggKDE5NTQpIHdobyB1c2VkIHRoZSB0ZXJtIG1hdGhlbWFwaG9iaWEuIFRoZSB0ZXJtIG1hdGggYW54aWV0eSB3YXMgZmlyc3QgdXNlZCBieSBEcmVnZXIgYW5kIEFpa2VuICgxOTU3KS4gVGhlIGZpcnN0IGRlZmluaXRpb24gb2YgbWF0aCBhbnhpZXR5IGlzIGNyZWRpdGVkIHRvIFJpY2hhcmRzb24gYW5kIFN1aW5uICgxOTcyKSwgd2hvIGRlc2NyaWJlZCBtYXRoIGFueGlldHkgYXMgImZlZWxpbmdzIG9mIHRlbnNpb24gYW5kIGFueGlldHkgdGhhdCBpbnRlcmZlcmUgd2l0aCB0aGUgbWFuaXB1bGF0aW9uIG9mIG51bWJlcnMgYW5kIHNvbHZpbmcgb2YgbWF0aGVtYXRpY2FsIHByb2JsZW1zIGluIGEgd2lkZSB2YXJpZXR5IG9mIG9yZGluYXJ5IGxpZmUgYW5kIGFjYWRlbWljIHNpdHVhdGlvbnMiLg0KDQpJbiB0aGUgcGFzdCA3MCB5ZWFycywgbnVtZXJvdXMgYXV0aG9ycyBjb25kdWN0ZWQgZXh0ZW5zaXZlIHJlc2VhcmNoIG9uIG1hdGggYW54aWV0eS4gUGFydGljdWxhcmx5LCBpbiB0aGUgcGFzdCAyMCB5ZWFycywgcmVzZWFyY2hlcnMgZnJvbSBkaWZmZXJlbnQgZGlzY2lwbGluZXMgaW5jbHVkaW5nIG1hdGhlbWF0aWNzIGhhdmUgaW52ZXN0aWdhdGVkIHRoZSBhc3NvY2lhdGlvbiBiZXR3ZWVuIG1hdGggYW54aWV0eSBhbmQgbWF0aCBhY2hpZXZlbWVudCwgdGhlIGNhdXNlcyBvZiBtYXRoIGFueGlldHksIGNoYXJhY3RlcmlzdGljcyBvZiBzdHVkZW50cyB0aGF0IGluY3JlYXNlIHN1c2NlcHRpYmlsaXR5IHRvIG1hdGggYW54aWV0eSwgYW5kIGVmZm9ydHMgdGhhdCBlZHVjYXRvcnMgY2FuIHRha2UgdG8gcmVtZWR5IGl0Lg0KDQpNYXRoIGFueGlldHkgaXMgcmVhbC4gSXRzIG5lZ2F0aXZlIGltcGFjdCBvbiBzdHVkZW50cycgYWNhZGVtaWMgcGVyZm9ybWFuY2UgYW5kIHRoZWlyIGZ1dHVyZSBwcm9mZXNzaW9uYWwgbGlmZSBpcyBwcm9mb3VuZC4gRXh0ZW5zaXZlIHJlc2VhcmNoIHB1YmxpY2F0aW9ucyBzaW5jZSAyMDAwIGhhdmUgc2hvd24gdGhhdCBtYXRoIGFueGlldHkgcmVsYXRlcyBpbnZlcnNlbHkgdG8gcG9zaXRpdmUgYXR0aXR1ZGVzIHRvd2FyZCBtYXRoZW1hdGljcyBhbmQgaXMgYm91bmQgZGlyZWN0bHkgdG8gYXZvaWRhbmNlIG9mIHRoZSBzdWJqZWN0IChzZWUgZm9yIGV4YW1wbGUsIFNlZ29vbCBldCBhbC4sIDIwMTMpLiBJdCBhZmZlY3RzIGJvdGggbWF0aCBhbmQgb3ZlcmFsbCBhY2FkZW1pYyBwZXJmb3JtYW5jZSBzaW5jZSBtYXRoIGFueGlldHkgbGVhZHMgdG8gdGhlIGRyYWluYWdlIG9mIGNvZ25pdGl2ZSByZXNvdXJjZXMsIG1vdGl2YXRpb24gcmVkdWN0aW9uLCBhbmQgc3RyYXRlZ3kgaW1wYWlybWVudCAoS2xlZSBldCBhbC4sIDIwMjIpLg0KDQpNYXRoIGFueGlldHkgY2FuIGFsc28gbGVhZCB0byBwb29yIGFjYWRlbWljIHBlcmZvcm1hbmNlIGFuZCBjb3Vyc2Ugd2l0aGRyYXdhbCwgcHV0dGluZyBzdHVkZW50cyBiZWhpbmQgc2NoZWR1bGUgYW5kIGluY3JlYXNpbmcgdGhlIHJpc2sgb2YgZHJvcCBvdXQsIHdoaWNoIHJlZHVjZXMgc3R1ZGVudCByZXRlbnRpb24gcmF0ZXMuIFdpbHNvbiAoMjAxMykgc3R1ZGllZCBtYXRoIGFueGlldHkgb2YgbWF0dXJlLWFnZSBwcmUtc2VydmljZSB0ZWFjaGVycyBhcyBhIHBvdGVudGlhbCBjb250cmlidXRpbmcgZmFjdG9yIHRoYXQgaW1wYWN0cyBzdHVkZW50IHJldGVudGlvbi4gRGFrZXIgZXQgYWwuICgyMDIxKSByZWNlbnRseSBzdHVkaWVkIHRoZSBpbXBhY3Qgb2YgbWF0aCBhbnhpZXR5IG9uIGZpcnN0LXllYXIgU1RFTSBzdHVkZW50cyBhbmQgY29uY2x1ZGVkIHRoYXQgbWF0aCBhbnhpZXR5IHByZWRpY3RzIFNURU0gYXZvaWRhbmNlIGFuZCB1bmRlcnBlcmZvcm1hbmNlIHRocm91Z2hvdXQgdGhlIHVuaXZlcnNpdHksIGluZGVwZW5kZW50bHkgb2YgbWF0aCBhYmlsaXR5Lg0KDQpBIHdlYWx0aCBvZiBlbXBpcmljYWwgc3R1ZGllcyBvbiB2YXJpb3VzIGFzcGVjdHMgb2YgbWF0aCBhbnhpZXR5IGhhdmUgYmVlbiBjb25kdWN0ZWQgc2luY2UgRHJlZ2VyICYgQWlrZW4ncyAoMTk1Nykgc2VtaW5hbCB3b3JrLiBEdWUgdG8gdGhlIGNvbXBsZXggcGF0aHdheXMgdG93YXJkIHRoZSBkZXZlbG9wbWVudCBvZiBtYXRoIGFueGlldHkgYW5kIGl0cyBsaW5rcyB3aXRoIGFjaGlldmVtZW50cyBhbmQgY29uZm91bmRlcnMsIHRoZSBvcmlnaW5zIGFuZCBvdXRjb21lcyBvZiBtYXRoIGFueGlldHkgYXJlIHN0aWxsIG5vdCBmdWxseSB1bmRlcnN0b29kLg0KDQpSZWNlbnQgYW5kIG9uZ29pbmcgcmVzZWFyY2ggZm9jdXNlcyBvbiB0aGUgZGV2ZWxvcG1lbnQgYW5kIGR5bmFtaWMgaW50ZXJwbGF5IGJldHdlZW4gZmFjdG9ycyB0aGF0IGNhdXNlIG1hdGggYW54aWV0eS4gTW9zdCBvZiB0aGUgcmVzZWFyY2ggY2FuIGJlIGNsYXNzaWZpZWQgaW50byB0aHJlZSBjYXRlZ29yaWVzOiBzaXR1YXRpb25hbCwgZGlzcG9zaXRpb25hbCwgYW5kIGVudmlyb25tZW50YWwgKE8nTGVhcnkgZXQgYWwuLCAyMDE3KS4gVGhlIGN1cnJlbnQgcHJvamVjdCB3aWxsIGV4cGxvcmUgYWxsIHRocmVlIHR5cGVzIG9mIGZhY3RvcnMsIGJ1dCB0aGUgcHJpbWFyeSBmb2N1cyBpcyBvbiB0aGUgZW52aXJvbm1lbnRhbCBmYWN0b3JzIHN1Y2ggYXMgcHJpb3IgcGVyY2VwdGlvbnMsIGF0dGl0dWRlcywgYW5kIGV4cGVyaWVuY2VzIHRoYXQgaGF2ZSBhZmZlY3RlZCB0aGUgaW5kaXZpZHVhbC4NCg0KIyBSZXNlYXJjaCBPYmplY3RpdmVzDQoNClNpbmNlIGxvd2VyIG1hdGhlbWF0aWNzIGFjaGlldmVtZW50IHByZWRpY3RzIGhpZ2hlciBzdWJzZXF1ZW50IG1hdGggYW54aWV0eSBhbmQgaGlnaGVyIG1hdGggYW54aWV0eSBwcmVkaWN0cyBsb3dlciBmdXR1cmUgYWNoaWV2ZW1lbnQsIHJlZHVjaW5nIG1hdGggYW54aWV0eSB3aWxsIGhlbHAgc3R1ZGVudHMgZGV2ZWxvcCBhIHBvc2l0aXZlIGF0dGl0dWRlIHRvIG1hdGhlbWF0aWNzLCBidWlsZCBjb25maWRlbmNlLCBib29zdCBtb3RpdmF0aW9uLCBhbmQgY29uc2VxdWVudGx5IGltcHJvdmUgdGhlaXIgYWNoaWV2ZW1lbnRzLiBUaGlzIHN0dWR5IGFpbWVkIHRvIGlkZW50aWZ5IHRoZSBmYWN0b3JzIHRoYXQgY2FuIHJlZHVjZSBtYXRoIGFueGlldHkgaW4gY29sbGVnZSBzdHVkZW50cy4gU3BlY2lmaWMgb2JqZWN0aXZlcyBhcmUNCg0KKipPYmplY3RpdmUgMSoqOiBBZG9wdGluZyB3ZWxsLWVzdGFibGlzaGVkIHBzeWNob21ldHJpYyBzdXJ2ZXkgaW5zdHJ1bWVudHMgQU1BUyBhbmQgc2VsZi1lZmZpY2FjeSBpbnN0cnVtZW50cyB0byBjb2xsZWN0IG1hdGggYW54aWV0eSBhbmQgc2VsZi1lZmZpY2FjeSBkYXRhLg0KDQoqKk9iamVjdGl2ZSAyKio6IEluY2x1ZGUgc29tZSBkZW1vZ3JhcGhpYyBjaGFyYWN0ZXJpc3RpY3Mgc3VjaCBhcyBhZ2UgYW5kIGdlbmRlciB0byBjb21wYXJlIHRoZSByZXN1bHRzIHdpdGggdGhhdCBvZiBleGlzdGluZyByZXNlYXJjaCBhbmQgdXNlIHRoZW0gYXMgYSBiYXNlbGluZS4NCg0KKipPYmplY3RpdmUgMyoqOiBUZWFjaGluZyBzdHJhdGVnaWVzIGNhbiByZWR1Y2UgbWF0aCBhbnhpZXR5IGFuZCBpbXByb3ZlIGxlYXJuaW5nIG91dGNvbWVzLiBXZSB3aWxsIGludmVzdGlnYXRlIHNldmVyYWwgZGlmZmVyZW50IHN0cmF0ZWdpZXMgaW4gbWF0aGVtYXRpY3MgdGVhY2hpbmcgc3VjaCBhcyBjb25jZXB0dWFsLCBwcm9jZWR1cmUsIGV0Yy4sIHRvIHNlZSBpZiB0aGVzZSBzdHJhdGVnaWVzIGFmZmVjdCB0aGUgbGV2ZWwgb2YgbWF0aCBhbnhpZXR5Lg0KDQoqKk9iamVjdGl2ZSA0Kio6IEVmZmVjdGl2ZWx5IHVzaW5nIHRoZSB0ZWNobm9sb2dpZXMgY2FuIHJlZHVjZSBtYXRoIGFueGlldHkuIFRoZSByZWNlbnRseSBkZXZlbG9wZWQgZWR1Y2F0aW9uYWwgdGVjaG5vbG9naWVzIGR1cmluZyB0aGUgcGFuZGVtaWMgaGF2ZSBub3QgYmVlbiBkaXNjdXNzZWQgaW4gdGhlIGxpdGVyYXR1cmUgb24gbWF0aCBhbnhpZXR5LiBXZSB3aWxsIGludmVzdGlnYXRlIGhvdyB0aGVzZSBuZXcgdGVjaG5vbG9naWVzIGFmZmVjdCBtYXRoIGFueGlldHkuDQoNCioqT2JqZWN0aXZlIDUqKjogTGVhcm5pbmcgbW9kYWxpdGllcyBhbmQgc3R5bGVzIGFyZSBhbHNvIGFzc29jaWF0ZWQgd2l0aCBtYXRoIGFueGlldHkuIE1vc3Qgb2YgdGhlIHJlc2VhcmNoIGluIHRoaXMgZGlyZWN0aW9uIGlzIGJhc2VkIG9uIGhpZ2ggc2Nob29sIHN0dWRlbnRzLiBXZSB3aWxsIGV4cGxvcmUgaG93IHRoZXNlIGxlYXJuaW5nIG1vZGFsaXRpZXMgYW5kIHN0eWxlcyBhZmZlY3QgbWF0aCBhbnhpZXR5IGFtb25nIGNvbGxlZ2Ugc3R1ZGVudHMuDQoNCioqT2JqZWN0aXZlIDYqKjogQ3JlYXRpbmcgYW5kIHVzaW5nIGNhbXB1cyBsZWFybmluZyByZXNvdXJjZXMgY2FuIHJlZHVjZSBtYXRoIGFueGlldHkgYW5kIGltcHJvdmUgdGhlaXIgYWNhZGVtaWMgcGVyZm9ybWFuY2UgKE1vbGluZXIgJiBBbGVncmUsIDIwMjApLiBXZSB3aWxsIGV4cGxvcmUgd2hldGhlciBhbmQgaG93IGxlYXJuaW5nIHJlc291cmNlcyBvbiBjb2xsZWdlIGNhbXB1c2VzIHJlZHVjZSBhbnhpZXR5Lg0KDQojIE1hdGVyaWFscw0KDQojIyBQYXJ0aWNpcGFudHMNCg0KVGhlIHN1cnZleSB3YXMgYXBwcm92ZWQgYnkgV0NVJ3MgSVJCLiBXZSBpbnZpdGUgYWxsIFdDVSBzdHVkZW50cyB3aG8gdGFrZSB0aGVpciBmaXJzdCBXQ1UgbWF0aGVtYXRpY3MgYW5kIHN0YXRpc3RpY3MgY2xhc3MgaW4gdGhlIGZhbGwgc2VtZXN0ZXJzIG9mIDIwMjQgYW5kIHRoZSBzcHJpbmcgc2VtZXN0ZXIgb2YgMjAyNS4gUGFydGljaXBhdGlvbiBpbiB0aGUgc3R1ZHkgYXJlIHZvbHVudGFyeSBhbmQgcmVzcG9uc2VzIHJlbWFpbiBhbm9ueW1vdXMuIFRoZSBkYXRhIHdhcyBjb2xsZWN0ZWQgaW4gdGhlIHNwcmluZyBhbmQgZmFsbCBzZW1lc3RlcnMgb2YgMjAyNCBiYXNlZCBvbiB0aGUgcHJvdG9jb2xzIHNldCBieSBXQ1UncyBJbnN0aXR1dGlvbmFsIFJlc2VhcmNoLiBWaWEgUXVhbHRyaWNzLCB3ZSBzZW50IGFuIGludml0YXRpb24gZW1haWwgdG8gYWxsIHF1YWxpZmllZCBzdHVkZW50cyBzcHJpbmcgYW5kIGZhbGwgbWlkLXNlbWVzdGVyLiBBIHJlbWluZGVyIGVtYWlsIHdhcyBzZW50IGF0IHRoZSBlbmQgb2YgdGhlIHNlbWVzdGVyIHRvIG5vbi1yZXNwb25kaW5nIHN0dWRlbnRzIHRvIGJvb3N0IHRoZSBwYXJ0aWNpcGF0aW9uIHJhdGUuIEEgXCQxMCBBbWF6b24gZ2lmdCBjYXJkIHdhcyBvZmZlcmVkIHRvIHN1cnZleSBjb21wbGV0ZXJzIGFuZCBkaXN0cmlidXRlZCB0aHJvdWdoIFF1YWx0cmljcyBzbyBhbm9ueW1pdHkgaXMgZ3VhcmFudGVlZC4NCg0KVGhlIHN0dWR5IHBvcHVsYXRpb24gaW4gdGhpcyBzdHVkeSBpcyBkZWZpbmVkIGFzIFdDVSBzdHVkZW50cyBhZ2VkIDE4IHllYXJzIG9yIG9sZGVyIHdobyB0b29rIHRoZWlyIGZpcnN0IE1BVCBjbGFzcyBhdCBXQ1UuIFRoZSByZXN1bHRzIGluIHRoaXMgc3R1ZHkgY2FuIGJlIGdlbmVyYWxpemVkIHRvIHNpbWlsYXIgcmVnaW9uYWwgdW5pdmVyc2l0aWVzIGFuZCB0aG9zZSByZWNlbnRseSByZWNsYXNzaWZpZWQgUjIgaW5zdGl0dXRpb25zLg0KDQojIyBTdXJ2ZXkgSW5zdHJ1bWVudHMNCg0KVGhlIHN1cnZleSB3aWxsIGhhdmUgdGhyZWUgY29tcG9uZW50czoNCg0KMS4gICoqTXVsdGktaXRlbSBTdXJ2ZXkgSW5zdHJ1bWVudCBNYXRoIEFueGlldHkqKjogQU1BUy4gV2Ugd2lsbCB1c2UgdGhlIGZyZXF1ZW50bHkgdXNlZCBBTUFTIHdpdGggbmluZSBpdGVtcyBjb250cmlidXRpbmcgdG8gdHdvIHNjYWxlczogTWF0aCBMZWFybmluZyBhbmQgTWF0aCBUZXN0aW5nLiBBTUFTIG9yaWdpbmF0ZXMgZnJvbSBhIHJlYW5hbHlzaXMgb2YgYSBNQVJTLVIgYnkgSG9wa28gZXQgYWwuICgyMDAzKS4gQU1BUyBpcyBzaG9ydCAoY29tcGxldGlvbiB0YWtlcyBhYm91dCA1IG1pbnV0ZXMpIGFuZCBoYXMgZ29vZCBwc3ljaG9tZXRyaWMgcHJvcGVydGllczogaGlnaCByZWxpYWJpbGl0eSBhcyBtZWFzdXJlZCBieSBpbnRlcm5hbCBjb25zaXN0ZW5jeSBhbmQgdGVzdC1yZXRlc3QgbWV0aG9kLCBjb25zdHJ1Y3QgdmFsaWRpdHkgYXMgbWVhc3VyZWQgYnkgZXhwbG9yYXRvcnkgYW5kIGNvbmZpcm1hdG9yeSBmYWN0b3IgYW5hbHlzZXMsIGFuZCBjb252ZXJnZW50IGFuZCBkaXNjcmltaW5hbnQgdmFsaWRpdHkuIChOdW1lcm91cyBzdWJzZXF1ZW50IHN0dWRpZXMgaGF2ZSBjb25maXJtZWQgdGhlc2UgcmVzdWx0cy4pIFdlIHdpbGwgdXNlIEFNQVMgdG8gbWVhc3VyZSBtYXRoIGFueGlldHkgaW4gdGhpcyBwcm9qZWN0Lg0KDQoyLiAgKipNdWx0aS1pdGVtIFN1cnZleSBJbnN0cnVtZW50IGZvciBNYXRoIFNlbGYtZWZmaWNhY3kqKi4gTWF0aCBhbnhpZXR5IGFuZCBtYXRoIHNlbGYtZWZmaWNhY3kgYXJlIG5lZ2F0aXZlbHkgY29ycmVsYXRlZC4gVGhlIHRocmVlLWl0ZW0gc2hvcnQgdmVyc2lvbiBvZiBtYXRoIHNlbGYtZWZmaWNhY3kgcXVlc3Rpb25uYWlyZXM6ICgxKSBJIHVzdWFsbHkgdW5kZXJzdGFuZCBhIG1hdGhlbWF0aWNhbCBpZGVhIHF1aWNrbHk7ICgyKSBJIGhhdmUgdG8gd29yayB2ZXJ5IGhhcmQgdG8gdW5kZXJzdGFuZCBtYXRoZW1hdGljczsgKDMpIEkgY2FuIGNvbm5lY3QgbWF0aGVtYXRpY2FsIGlkZWFzIHRoYXQgSSBoYXZlIGxlYXJuZWQ7IHVzZWQgYnkgUm96Z29uanVrIGV0IGFsLiAoMjAyMCkuDQoNCjMuICAqKk11bHRpLWl0ZW0gU3VydmV5IEluc3RydW1lbnQgZm9yIFN0dWRlbnQncyBQZXJjZXB0aW9uIG9uIEZhY3VsdHkgVGVhY2hpbmcgU3RyYXRlZ2llcyoqOiBTdHVkZW50cycgbWF0aGVtYXRpY3MgYW54aWV0eSBpcyBkaXJlY3RseSBpbmZsdWVuY2VkIGJ5IHRoZWlyIGluc3RydWN0b3JzJyB0ZWFjaGluZyBzdHJhdGVnaWVzLiBUaGlzIHN0dWR5IGVtcGxveXMgdGhlIFRlYWNoaW5nIFN0cmF0ZWdpZXMgSW52ZW50b3J5IHVzZWQgYnkgQ2FyZGlubyBKci4gYW5kIE9ydGVnYS1EZWxhIENydXogKDIwMjApIHRvIGFzc2VzcyBzdHVkZW50cycgcGVyY2VwdGlvbnMgb2YgdGhlc2Ugc3RyYXRlZ2llcy4gVGhlIGludmVudG9yeSBjb21wcmlzZXMgZWlnaHQgZGlzdGluY3QgZGltZW5zaW9ucyAoc3Vic2NhbGVzKS4NCg0KNC4gICoqTXVsdGktaXRlbSBTdXJ2ZXkgSW5zdHJ1bWVudCBmb3IgU3R1ZGVudCBMZWFybmluZyBNb2RhbGl0aWVzKio6IEFWSUQgKEFkdmFuY2VtZW50IFZpYSBJbmRpdmlkdWFsIERldGVybWluYXRpb24pIGlzIGEgcHJvZ3JhbSBpbnRyb2R1Y2VkIGJ5IE1lYWRvd2xhcmsgRWxlbWVudGFyeSBTY2hvb2wgdGhhdCBhaW1zIHRvIGNsb3NlIHRoZSBhY2hpZXZlbWVudCBnYXAgYnkgcHJlcGFyaW5nIGFsbCBzdHVkZW50cyBmb3IgY29sbGVnZSByZWFkaW5lc3MgYW5kIHN1Y2Nlc3MgaW4gYSBnbG9iYWwgc29jaWV0eS4gV2UgdXNlZCBBVklEJ3MgU3R1ZGVudCBMZWFybmluZyBNb2RhbGl0eSBJbnZlbnRvcnkgdG8gaWRlbnRpZnkgc3R1ZGVudCBsZWFybmluZyBzdHlsZXMgKGF1ZGl0b3J5LCB2aXN1YWwsIGFuZCBraW5lc3RoZXRpYykgaW4gdGhpcyBzdHVkeS4gVGhlIGludmVudG9yeSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcGVuZ2RzY2kuZ2l0aHViLmlvL01hdGhBbnhpZXR5L0FWSURfTGVhcm5pbmdfU3R5bGVfSW52ZW50b3J5LnBkZj4uDQoNCjUuICAqKk11bHRpLWl0ZW0gU3VydmV5IEluc3RydW1lbnQgZm9yIFN0dWRlbnQncyBFbmdhZ2VtZW50Kio6IFdlIHNlbGVjdCAxMiBxdWVzdGlvbm5haXJlcyBmcm9tIHRoZSBOU1NFIChOYXRpb25hbCBTdXJ2ZXkgb2YgU3R1ZGVudCBFbmdhZ2VtZW50KSB0byBhc3Nlc3Mgc3R1ZGVudHMgaW4tY2xhc3MgYW5kIGFmdGVyLWNsYXNzIGVuZ2FnZW1lbnQgYW5kIHVzZSBvZiBsZWFybmluZyByZXNvdXJjZXMuIFRoZSBUaGUgY29yZSBOU1NFIHN1cnZleSBmb3IgYSBmaXJzdC15ZWFyIG9yIHNlbmlvciBzdHVkZW50IGNvbnNpc3RzIG9mIGFwcHJveGltYXRlbHkgNDAgdG8gNTAgcmVxdWlyZWQgaXRlbXMsIGJ1dCB0aGUgdG90YWwgYmFuayBvZiBwb3RlbnRpYWwgcXVlc3Rpb25zIGlzIG11Y2ggbGFyZ2VyLiBUaGUgY29tcGxldCBpbnN0cnVtZW50IGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9uc3NlLmluZGlhbmEuZWR1L25zc2Uvc3VydmV5LWluc3RydW1lbnRzL3VzLWVuZ2xpc2guaHRtbD4uDQoNCjYuICAqKlNpbmdsZS1pdGVtIHF1ZXN0aW9ucyoqOiBUaGVzZSBxdWVzdGlvbnMgY2FwdHVyZSBkZW1vZ3JhcGhpYyBpbmZvcm1hdGlvbi4NCg0KIyBSYXcgRGF0YSBQcm9jZXNzaW5nDQoNCkF0IHRoZSBlbmQgb2YgZGF0YSBjb2xsZWN0aW9uLCB3ZSByZWNlaXZlZCA4OTUgcmVzcG9uc2VzLiBPZiB0aGVzZSwgMTk5IHBhcnRpY2lwYW50cyBkaWQgbm90IGNvbXBsZXRlIHRoZSBtYWluIHN1cnZleSBzdWJzY2FsZXMuIFRoZSBhbmFseXNpcyBpcyBiYXNlZCBvbiB0aGUgcmVtYWluaW5nIDY5NiByZXNwb25zZXMgZm9yIHdoaWNoIHRoZSBtYWluIHN1YnNjYWxlcyB3ZXJlIGNvbXBsZXRlZCwgd2hpY2ggY29udGFpbmVkIG9ubHkgYSBmZXcgbWlzc2luZyB2YWx1ZXMuIFNldmVyYWwgcmVkdW5kYW50IHZhcmlhYmxlcyB3ZXJlIHJlbW92ZWQgZnJvbSB0aGUgcmF3IGRhdGEuIEluIGFkZGl0aW9uLCBzb21lIG9yaWdpbmFsIGNhdGVnb3JpY2FsIHZhcmlhYmxlcyB3ZXJlIHJlY2F0ZWdvcml6ZWQgdG8gYXZvaWQgc3BhcnNlIGdyb3VwcyBhbmQgaW1wcm92ZSBpbnRlcnByZXRhYmlsaXR5Lg0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGV2YWwgPSBUUlVFfQ0KV29ya2luZ0RhdGEgPC0gcmVhZC5jc3YoIkM6XFxVc2Vyc1xcNzVDUEVOR1xcT25lRHJpdmUgLSBXZXN0IENoZXN0ZXIgVW5pdmVyc2l0eSBvZiBQQVxcRGVza3RvcFxcY3BlbmdcXFdDVS1UZWFjaGluZ1xcMjAyNUZhbGxcXE1hdGhBeGlldHlcXFdvcmtpbmdEYXRhU2V0Tm9NaXNzaW5nczAyLmNzdiIpDQpXb3JraW5nRGF0YSRJRCA8LSAxOmRpbShXb3JraW5nRGF0YSlbMV0NCiMgRGVtb2dyYXBoaWNzDQpEZW1vZ3JhcGhpY3MgPC0gV29ya2luZ0RhdGFbLCBjKCJJRCIsICJTZXgiLCAiR2VuZGVyIiwgIkNsYXNzIiwgIk1ham9yIiwgIkV0aG5pY2l0eSIsICJDb3Vyc2UyIildDQojIE1hdGggQW54aWV0eQ0KQW54aWV0eSA8LSBXb3JraW5nRGF0YVssIGMoIklEIiwgIkFNQVMuMSIsICJBTUFTLjIiLCAiQU1BUy4zIiwgIkFNQVMuNCIsICJBTUFTLjUiLCAiQU1BUy42IiwgIkFNQVMuNyIsICJBTUFTLjgiLCAiQU1BUy45IildDQojIFNlbGYtZWZmaWNhY3kNClNlbGZFZmZpY2FjeSA8LSBXb3JraW5nRGF0YVssIGMoIklEIiwgICJNU0VTLjEiLCAiTVNFUy4yIiwgIk1TRVMuMyIgKV0NCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KIyAgIFRlYWNoaW5nIFN0cmF0ZWdpZXMNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KIyMgQ29vcGVyYXRpdmUNCkNvb3BvcmF0aXZlIDwtIFdvcmtpbmdEYXRhWywgYygiSUQiLCAgIlMuQ0EuMSIsICJTLkNBLjIiLCAiUy5DQS4zIiwgIlMuQ0EuNCIsICJTLkNBLjUiLCAiUy5DQS42IildDQojIyBMZWN0dXJlIFR5cGUNCkxlY3R1cmVUeXBlIDwtIFdvcmtpbmdEYXRhWywgYygiSUQiLCAgIlMuTFQuMSIsICJTLkxULjIiLCAiUy5MVC4zIiwgICJTLkxULjQiLCAgIlMuTFQuNSIsICJTLkxULjYiLCAiUy5MVC43IildDQojIyBEZWR1Y3RpdmUgQXBwcm9hY2gNCkRlZHVjdGl2ZSA8LSBXb3JraW5nRGF0YVssIGMoIklEIiwgICJTLkRBLjEiICwgIlMuREEuMiIsICJTLkRBLjMiLCAiUy5EQS40IiwgIlMuREEuNSIsICJTLkRBLjYiLCAiUy5EQS43IildDQojIyBJbmR1Y3RpdmUgQXBwcm9hY2gNCkluZHVjdGl2ZSA8LSBXb3JraW5nRGF0YVssIGMoIklEIiwgIlMuSUEuMSIsICJTLklBLjIiLCAgIlMuSUEuMyIsICAiUy5JQS40IiwgIlMuSUEuNSIsIlMuSUEuNiIsICJTLklBLjciKV0NCiMjIERlbW9uc3RyYXRpb24NCkRlbW9uc3RyYXRpb24gPC1Xb3JraW5nRGF0YVssIGMoIklEIiwgIlMuRC4xIiwgIlMuRC4yIiwgIlMuRC4zIiwgIlMuRC40IiwgIlMuRC41IiwgICJTLkQuNiIsICJTLkQuNyIpXQ0KIyMgUmVwZXRpdGl2ZSBFeGVyY2lzZXMNClJlcGV0aXRpdmUgPC0gV29ya2luZ0RhdGFbLCBjKCJJRCIsICJTLlJFLjEiLCAgIlMuUkUuMiIsICJTLlJFLjMiLCAiUy5SRS40IiwgIlMuUkUuNSIsICJTLlJFLjYiLCAiUy5SRS43IildDQojIyBJbnRlZ3JhdGl2ZSBBcHByb2FjaA0KSW50ZWdyYXRpdmUgPC0gV29ya2luZ0RhdGFbLCBjKCJJRCIsICJTLklBLjEuMSIsICJTLklBLjIuMSIsICJTLklBLjMuMSIsICJTLklBLjQuMSIsICJTLklBLjUuMSIsICJTLklBLjYuMSIsICJTLklBLjcuMSIpXQ0KIyBVc2luZyBUZWNobm9sb2d5OiBkcm9wIFQxIGFuZCBUNw0KVGVjaG5vbG9neSA8LSBXb3JraW5nRGF0YVssIGMoIklEIiwgIlQuMiIsICJULjMiLCAiVC40IiwgIlQuNSIsICJULjYiLCAiVC44IiwgIlQuOSIsICJULjEwIiwgIlQuMTEiLCJULjEyIildDQojIExlYXJuaW5nIE1vZGFsaXRpZXMNCk1vZGFsaXR5IDwtIFdvcmtpbmdEYXRhWywgYygiSUQiLCAgIk1TLjEiLCAiTVMuMiIsICJNUy4zIiwgIk1TLjQiLCAiTVMuNSIsICJNUy42IiwgIk1TLjciLCAiTVMuOCIsICJNUy45IiwgIk1TLjEwIiwgIk1TLjExIiwgIk1TLjEyIildDQojIEVuZ2FnZW1lbnQ6IGtlZXAgb25seSBmaXJzdCB0aHJlZSBpdGVtcw0KRW5nYWdlIDwtIFdvcmtpbmdEYXRhWywgYygiSUQiLCAgIkNSLjEiLCAiQ1IuMiIsICJDUi4zIildDQojIFJlc291cmNlcw0KUmVzb3VyY2UgPC0gV29ya2luZ0RhdGFbLCBjKCJJRCIsICJDUi45IiwgIkNSLjEwIiwgIkNSLjExIiwgIkNSLjEyIildDQpgYGANCg0KIyMgTWlzc2luZyBWYWx1ZSBJbXB1dGF0aW9uDQoNClRvIG1haW4gdGhpcyBzYW1wbGUgc2l6ZSwgd2UgdXNlIHJhbmRvbSBpbXB1dGF0aW9uIGFwcHJvYWNoIHRvIGZpbGwgaW4gdGhlIG1pc3NpbmcgdmFsdWVzLiBTaW5jZSBhbGwgbXVsdGktaXRlbSBzdWItc2NhbGVzIHdlcmUgbWVhc3VyZWQgdXNpbmcgYSBMaWtlcnQgc2NhbGUsIHRoZSBzY29yZXMgZm9sbG93cyBhIG11bHRpbm9taWFsIGRpc3RyaWJ1dGlvbi4gVGhlIGVtcGlyaWNhbCBkaXN0cmlidXRpb24gd2lsbCBiZSB1c2VkIGluIHRoZSByYW5kb20gaW1wdXRhdGlvbiB0byBtYWluIHRoZSBwcm9iYWJpbGl0eSBkaXN0cmlidXRpb24gb2YgdGhlIG9ic2VydmVkIGRhdGEuIFRoZSBmb2xsb3dpbmcgY29kZSBpbXB1dGVzIHRoZSBtaXNzaW5nIHZhbHVlcyBpbiBhbGwgbXVsdGktaXRlbSBzdWJzY2FsZXMuDQoNCmBgYHtyLCBldmFsID0gVFJVRX0NCkltcHV0YXRpb24gPSBmdW5jdGlvbihEYXRhTmFtZSl7DQogIGZvciAoaSBpbiAxOihkaW0oRGF0YU5hbWUpWzJdKSl7DQogICAgdmVjID0gYXMudmVjdG9yKERhdGFOYW1lWywgaV0pDQogICAgbmEuaWQgPSB3aGljaChpcy5uYSh2ZWMpKQ0KICAgIG4wID0gbGVuZ3RoKG5hLmlkKQ0KICAgIHByb2IwID0gdGFibGUodmVjKS9sZW5ndGgodmVjKQ0KICAgIGltcHV0LnZhbCA9IE5VTEwNCiAgICAgIGZvciAoaiBpbiAxOm4wKXsNCiAgICAgIGltcHV0LnZhbFtqXSA9IHNhbXBsZSgxOmxlbmd0aChwcm9iMCksIHNpemUgPSAxLCBwcm9iID0gcHJvYjApDQogICAgfQ0KICAgIERhdGFOYW1lW25hLmlkLCBpXSA9IGltcHV0LnZhbA0KICB9DQogICBEYXRhTmFtZQ0KfQ0KYGBgDQoNCmBgYHtyIGVjaG8gPSBGQUxTRSwgZXZhbCA9IFRSVUV9DQpDb21wLkFueGlldHkgPSBJbXB1dGF0aW9uKEFueGlldHkpDQpDb21wLlNlbGZFZmZpY2FjeTAgPSBJbXB1dGF0aW9uKFNlbGZFZmZpY2FjeSkNCiMgcmV2ZXJzZSBjb2RpbmcgaW4gU2VsZi1FZmZpY2FjeQ0KQ29tcC5TZWxmRWZmaWNhY3kgPSBDb21wLlNlbGZFZmZpY2FjeTANCkNvbXAuU2VsZkVmZmljYWN5JE1TRVMuMSA9Ni0gQ29tcC5TZWxmRWZmaWNhY3kwJE1TRVMuMQ0KQ29tcC5TZWxmRWZmaWNhY3kkTVNFUy4zID02LSBDb21wLlNlbGZFZmZpY2FjeTAkTVNFUy4zDQojIw0KQ29tcC5Db29wb3JhdGl2ZSA9IEltcHV0YXRpb24oQ29vcG9yYXRpdmUpDQpDb21wLkxlY3R1cmVUeXBlID0gSW1wdXRhdGlvbihMZWN0dXJlVHlwZSkNCkNvbXAuRGVkdWN0aXZlID0gSW1wdXRhdGlvbihEZWR1Y3RpdmUpDQpDb21wLkluZHVjdGl2ZSA9IEltcHV0YXRpb24oSW5kdWN0aXZlKQ0KQ29tcC5EZW1vbnN0cmF0aW9uID0gSW1wdXRhdGlvbihEZW1vbnN0cmF0aW9uKQ0KQ29tcC5SZXBldGl0aXZlID0gSW1wdXRhdGlvbihSZXBldGl0aXZlKQ0KQ29tcC5JbnRlZ3JhdGl2ZSA9IEltcHV0YXRpb24oSW50ZWdyYXRpdmUpDQojIyByZXZlcnNlIGNvZGluZyBpbiA1IGFuZCA3IGluIFRlY2hub2xvZ3kNCkNvbXAuVGVjaG5vbG9neTAgPSBJbXB1dGF0aW9uKFRlY2hub2xvZ3kpDQpDb21wLlRlY2hub2xvZ3kxID0gQ29tcC5UZWNobm9sb2d5MA0KQ29tcC5UZWNobm9sb2d5MSRULjUgPTYtIENvbXAuVGVjaG5vbG9neTAkVC41DQojIw0KQ29tcC5UZWNobm9sb2d5ID0gNiAtIENvbXAuVGVjaG5vbG9neTENCiMjDQpDb21wLkVuZ2FnZSA9IDUtSW1wdXRhdGlvbihFbmdhZ2UpDQpDb21wLlJlc291cmNlID0gNS1JbXB1dGF0aW9uKFJlc291cmNlKQ0KIyMgTW9kYWxpdHkNCkNvbXAuTW9kYWxpdHkgPSBJbXB1dGF0aW9uKE1vZGFsaXR5KQ0KYGBgDQoNCiMjIFJldmVyc2UgU2NvcmluZw0KDQoqKlJldmVyc2Ugc2NvcmluZyoqIGlzIGEgY3J1Y2lhbCBkYXRhIHByZXBhcmF0aW9uIHN0ZXAgZm9yIG11bHRpLWl0ZW0gc3VydmV5cyB3aGVyZSBzb21lIGl0ZW1zIGFyZSB3b3JkZWQgaW4gdGhlIG9wcG9zaXRlIGRpcmVjdGlvbiB0byBwcmV2ZW50IHJlc3BvbnNlIGJpYXMuIEFmdGVyIGl0ZW0td2lzZSByZXZpZXcgb2YgYWxsIGluc3RydW1lbnRzIGFsb25nIHdpdGggc3RhdGlzdGljYWwgcHJvY2VkdXJlcyBvZiBjb3JyZWxhdGlvbiBhbmQgY29uZmlybWF0b3J5IGZhY3RvciBhbmFseXNpcyAoQ0ZBKSwgaXRlbSAyIGluIHRoZSAqU2VsZi1lZmZpY2FjeSBJbnN0cnVtZW50KiBhbmQgKiphbGwgcXVlc3Rpb25zKiogZXhjZXB0IGl0ZW1zIDUgYW5kIDcgaW4gdGhlICpUZWNobm9sb2d5IEluc3RydW1lbnQqIHdlcmUgbmVnYXRpdmVseSB3b3JkZWQuIFRoZSBzY29yZXMgb2YgdGhlc2UgaXRlbXMgd2VyZSByZXZlcnNlZC4NCg0KSW4gYWRkaXRpb24sIGFsbCBxdWVzdGlvbnMgcmVnYXJkaW5nIGVuZ2FnZW1lbnQgYW5kIHJlc291cmNlIHVzZSB3ZXJlIHJldmVyc2Utd29yZGVkLCBzbyB0aGVpciBzY29yZXMgd2VyZSByZXZlcnNlZCBmb3IgdGhlIHN1YnNlcXVlbnQgYW5hbHlzaXMuDQoNCiMjIFNwYXJzZSBDYXRlZ29yeSBSZWdyb3VwaW5nDQoNClR3byB2YXJpYWJsZXMgbmVlZCB0byBiZSByZWdyb3VwZWQgaW4gdGhlIGZvbGxvd2luZzogY291cnNlIGxldmVsIGFuZCBldGhuaWNpdHkuDQoNCi0gICAqKk1hdGhDb3Vyc2VMZXZlbCoqDQogICAgLSAgICpNYXRoLkkqOiBNQVRRMzAsIE1BVDEwMCwgTUFUMTAxLCBNQVQxMDIsDQogICAgLSAgICpNYXRoLklJKjogTUFUMTkzLCBNQVQxMDQsIE1BVDExMiwgTUFUMTEzLCBNQVQxMTUsIE1BVDEzMQ0KICAgIC0gICAqTWF0aC5JSUkqOiBNQVQxNDMsIE1BVDE0NSwgTUFUMTUxLCBNQVQxNjENCiAgICAtICAgKk1hdGguSVYqOiBNQVQxNjItTUFUNDgwDQogICAgLSAgICpTdGF0cyo6IE1BVDEyMSwgTUFUMTI1LCBTVEEyMDANCiAgICAtICAgKk90aGVyKjogQWxsIGNvdXJzZXMgbm90IGxpc3RlZCBhYm92ZQ0KLSAgICoqRXRobmljaXR5KioNCiAgICAtICAgKldoaXRlKg0KICAgIC0gICAqQmxhY2sqOiBCbGFjayBhbmQgQWZyaWNhbiBBbWVyaWNhbg0KICAgIC0gICAqQXNpYW4qDQogICAgLSAgICpPdGhlcio6IE5hdGl2ZSBIYXdhaWlhbiBvciBQYWNpZmljIElzbGFuZGVyLCBNdWx0aXBsZSBFdGhuaWNpdHkgb3IgT3RoZXIsIFByZWZlciBOb3QgVG8gQW5zd2VyDQotICAgKipMZWFybmluZyBNb2RhbGl0aWVzKioNCg0KYGBge3J9DQpkZl93aXRoX2ZyZXEgPC0gQ29tcC5Nb2RhbGl0eSAlPiUNCiAgcm93d2lzZSgpICU+JQ0KICBtdXRhdGUoDQogICAgZnJlcV9BID0gc3VtKGNfYWNyb3NzKE1TLjE6TVMuMTIpID09ICIxIiksDQogICAgZnJlcV9CID0gc3VtKGNfYWNyb3NzKE1TLjE6TVMuMTIpID09ICIyIiksDQogICAgZnJlcV9DID0gc3VtKGNfYWNyb3NzKE1TLjE6TVMuMTIpID09ICIzIikNCiAgKSAlPiUNCiAgdW5ncm91cCgpDQojIyMNCmRmX3dpdGhfZnJlcSRtYXhfZnJlcV9jb2wgPC0gbmFtZXMoZGZfd2l0aF9mcmVxKVttYXguY29sKGRmX3dpdGhfZnJlcVssIGMoImZyZXFfQSIsICJmcmVxX0IiLCAiZnJlcV9DIildKSArIDFdDQpkZl93aXRoX2ZyZXEkbWF4X2ZyZXFfdmFsdWUgPC0gYXBwbHkoZGZfd2l0aF9mcmVxWywgYygiZnJlcV9BIiwgImZyZXFfQiIsICJmcmVxX0MiKV0sIDEsIG1heCkNCmRmX3dpdGhfZnJlcSRtb2RhbGl0eSA8LSBpZmVsc2UoZGZfd2l0aF9mcmVxJG1heF9mcmVxX2NvbD09Ik1TLjEiLCAiQXVkaXRvcnkiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGRmX3dpdGhfZnJlcSRtYXhfZnJlcV9jb2w9PSJNUy4yIiwgIlZpc3VhbCIsICJLaW5lc3RoZXRpYyIpKQ0KDQpgYGANCg0KYGBge3IsIGVjaG8gPSBGQUxTRSwgZXZhbCA9IFRSVUV9DQpEZW1vZ3JhcGhpY3MkbWF0aC5sZXZlbCA9IGlmZWxzZShEZW1vZ3JhcGhpY3MkQ291cnNlMiAlaW4lIGMoMSwgMiwgMywgNCksICJtYXRoMDEiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShEZW1vZ3JhcGhpY3MkQ291cnNlMiAlaW4lIGMoNSwgNiwgNywgOCwgOSwgMTIpLCAibWF0aDAyIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKERlbW9ncmFwaGljcyRDb3Vyc2UyICVpbiUgYygxMywgMTQsIDE1LCAxNiksICJtYXRoMDMiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKERlbW9ncmFwaGljcyRDb3Vyc2UyICVpbiUgYygxMCwgMTEsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyKSwgInN0YXRzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShEZW1vZ3JhcGhpY3MkQ291cnNlMiAlaW4lIGMoNDMsIDQ0KSwgIm90aGVyIiwgIm1hdGgwNCIpKSkpKSANCkRlbW9ncmFwaGljcyRyYWNlID0gaWZlbHNlKERlbW9ncmFwaGljcyRFdGhuaWNpdHkgPT0gMSwgIndoaXRlIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoRGVtb2dyYXBoaWNzJEV0aG5pY2l0eSA9PSAyLCAiQmxhY2siLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoRGVtb2dyYXBoaWNzJEV0aG5pY2l0eSA9PSA0LCAiQXNpYW4iLCAib3RoZXIiKSkpDQpEZW1vZ3JhcGhpY3Mkc2V4ID0gaWZlbHNlKERlbW9ncmFwaGljcyRTZXggPT0gMSwgImZlbWFsZSIsICJtYWxlIikNCkRlbW9ncmFwaGljcyRtYWpvciA9IGlmZWxzZShEZW1vZ3JhcGhpY3MkTWFqb3IgPT0gMSwgIlNURU0iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoRGVtb2dyYXBoaWNzJE1ham9yID09IDIsICJCdXNpbmVzcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShEZW1vZ3JhcGhpY3MkTWFqb3IgPT0gMywgIkhlYWx0aCIsICJPdGhlciIpKSkNCkRlbW9ncmFwaGljcyRjbGFzcyA9IGlmZWxzZShEZW1vZ3JhcGhpY3MkQ2xhc3MgPT0gMSwgInlyMSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShEZW1vZ3JhcGhpY3MkQ2xhc3MgPT0gMiwgInlyMiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShEZW1vZ3JhcGhpY3MkQ2xhc3MgPT0gMywgInlyMyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKERlbW9ncmFwaGljcyRNYWpvciA9PSA0LCAieXI0IiwgInlyNSsiKSkpKQ0KRGVtb2dyYXBoaWNzJG1vZGFsaXR5IDwtIGRmX3dpdGhfZnJlcSRtb2RhbGl0eQ0KDQpkZW1vZ3JhcGhpY3MgPSBEZW1vZ3JhcGhpY3NbLCBjKCJJRCIsICJzZXgiLCAicmFjZSIsICJjbGFzcyIsICJtYWpvciIsICJtYXRoLmxldmVsIiwgIm1vZGFsaXR5IildDQpgYGANCg0KIyMgRXhwbG9yYXRvcnkgRmFjdG9yIEFuYWx5c2lzIChFRkEpIG9uIEFueGlldHkNCg0KVGhlIGFiYnJldmlhdGVkIG1hdGhlbWF0aWNhbCBhbnhpZXR5IChNQSkgaW5zdHJ1bWVudCBkZXZlbG9wZWQgYnkgSG9wa28gZXQgYWwuICgyMDAzKSBpcyBjaGFyYWN0ZXJpemVkIGJ5IGEgdHdvLWZhY3RvciBzdHJ1Y3R1cmUgdGhhdCBkaXZpZGVzIGludG8gdHdvIHN1YnNjYWxlczogbWF0aGVtYXRpY3MgZXZhbHVhdGlvbiBhbnhpZXR5IChNRUEpIGFuZCBtYXRoZW1hdGljcyBsZWFybmluZyBhbnhpZXR5IChNTEEpLiBUaGUgc3Vic2VxdWVudCBleHBsb3JhdG9yeSBmYWN0b3IgYW5hbHlzaXMgc2VydmVzIHRvIHZhbGlkYXRlIHRoaXMgY29uc3RydWN0Lg0KDQpgYGB7ciByZXN1bHRzID0gRkFMU0V9DQojIENoZWNrIGNvcnJlbGF0aW9ucyAodmlzdWFsbHkpDQpuID0gZGltKENvbXAuQW54aWV0eVssLTFdKVsxXQ0KY29yX21hdHJpeCA8LSBjb3IoQ29tcC5BbnhpZXR5WywtMV0pDQojY29yUGxvdChjb3JfbWF0cml4LCB1cHBlciA9IEZBTFNFKQ0KIyBCYXJ0bGV0dCdzIFRlc3Qgb2YgU3BoZXJpY2l0eSAod2Ugd2FudCBhIHNpZ25pZmljYW50IHAtdmFsdWUsIHAgPCAuMDUpDQpjb3J0ZXN0LmJhcnRsZXR0KGNvcl9tYXRyaXgsIG4gPSBuKQ0KDQojIEtNTyBNZWFzdXJlIG9mIFNhbXBsaW5nIEFkZXF1YWN5IChNU0EpIChXZSB3YW50IG92ZXJhbGwgTVNBID4gMC42LCBpZGVhbGx5ID4gMC44KQ0KS01PKGNvcl9tYXRyaXgpDQpgYGANCg0KQmFydGxldHQncyB0ZXN0IG9mIHNwaGVyaWNpdHkgcHJvZHVjZWQgYSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IHJlc3VsdCAocCBcPCAuMDAxKSwgY29uZmlybWluZyB0aGF0IHRoZSB2YXJpYWJsZXMgYXJlIHN1ZmZpY2llbnRseSBjb3JyZWxhdGVkIHRvIHByb2NlZWQgd2l0aCBmYWN0b3IgYW5hbHlzaXMuIFRoZSBLYWlzZXItTWV5ZXItT2xraW4gKEtNTykgTWVhc3VyZSBvZiBTYW1wbGluZyBBZGVxdWFjeSwgd2l0aCBib3RoIG92ZXJhbGwgYW5kIGl0ZW0tbGV2ZWwgdmFsdWVzIGV4Y2VlZGluZyAwLjgwLCBpbmRpY2F0ZXMgdGhhdCB0aGUgZGF0YSBjb250YWluIGFkZXF1YXRlIGNvbW1vbiB2YXJpYW5jZSB0byB3YXJyYW50IGZhY3RvciBhbmFseXNpcy4gRnVydGhlcm1vcmUsIHRoZSBzY3JlZSBwbG90IGNsZWFybHkgZGVtb25zdHJhdGVzIHRoZSBhbnRpY2lwYXRlZCB0d28tZmFjdG9yIHN0cnVjdHVyZSBvZiB0aGUgY29uc3RydWN0Lg0KDQpgYGB7cn0NCg0KIyBHZXQgZWlnZW52YWx1ZXMNCmZhX3Jlc3VsdCA8LSBmYShDb21wLkFueGlldHlbLC0xXSwgbmZhY3RvcnMgPSBuY29sKENvbXAuQW54aWV0eVssLTFdKSwgcm90YXRlID0gIm5vbmUiKQ0KZWlnZW52YWx1ZXMgPC0gZmFfcmVzdWx0JGUudmFsdWVzDQoNCiMgU2NyZWUgcGxvdCB3aXRoIGhvcml6b250YWwgbGluZSB1c2luZyBzaGFwZXMNCnNjcmVlX3Bsb3QgPC0gcGxvdF9seSh4ID0gMTpsZW5ndGgoZWlnZW52YWx1ZXMpLCB5ID0gZWlnZW52YWx1ZXMsDQogICAgICAgICAgICAgICAgICAgICAgdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdsaW5lcyttYXJrZXJzJywNCiAgICAgICAgICAgICAgICAgICAgICBsaW5lID0gbGlzdCh3aWR0aCA9IDMpLA0KICAgICAgICAgICAgICAgICAgICAgIG1hcmtlciA9IGxpc3Qoc2l6ZSA9IDgpKSAlPiUNCiAgbGF5b3V0KA0KICAgIHRpdGxlID0gIlNjcmVlIFBsb3Qgd2l0aCBLYWlzZXIgQ3JpdGVyaW9uIChFaWdlbnZhbHVlKSIsDQogICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIkZhY3RvciBOdW1iZXIiKSwNCiAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiRWlnZW52YWx1ZSIpLA0KICAgIHNoYXBlcyA9IGxpc3QoDQogICAgICBsaXN0KA0KICAgICAgICB0eXBlID0gImxpbmUiLA0KICAgICAgICB4MCA9IDAsDQogICAgICAgIHgxID0gbGVuZ3RoKGVpZ2VudmFsdWVzKSwNCiAgICAgICAgeTAgPSAxLA0KICAgICAgICB5MSA9IDEsDQogICAgICAgIGxpbmUgPSBsaXN0KGNvbG9yID0gInJlZCIsIHdpZHRoID0gMiwgZGFzaCA9ICJkYXNoIikNCiAgICAgICkNCiAgICApLA0KICAgIGFubm90YXRpb25zID0gbGlzdCgNCiAgICAgIGxpc3QoDQogICAgICAgIHggPSBsZW5ndGgoZWlnZW52YWx1ZXMpICogMC44LA0KICAgICAgICB5ID0gMS4xLA0KICAgICAgICB0ZXh0ID0gIkthaXNlciBDcml0ZXJpb24gKM67ID0gMSkiLA0KICAgICAgICBzaG93YXJyb3cgPSBGQUxTRSwNCiAgICAgICAgZm9udCA9IGxpc3QoY29sb3IgPSAicmVkIikNCiAgICAgICkNCiAgICApLA0KICAgICBtYXJnaW4gPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgdCA9IDEwMCwgICMgQWRqdXN0IHRoaXMgdmFsdWUgdG8gaW5jcmVhc2Ugb3IgZGVjcmVhc2UgdGhlIHRvcCBtYXJnaW4NCiAgICAgICAgICAgICAgICAgIGIgPSA1MCwNCiAgICAgICAgICAgICAgICAgIGwgPSA1MCwNCiAgICAgICAgICAgICAgICAgIHIgPSA1MCkNCiAgKQ0KDQpzY3JlZV9wbG90DQpgYGANCg0KTmV4dCwgd2UgcGVyZm9ybSBFRkEgdG8gaWRlbnRpZnkgdGhlIGl0ZW1zIG9mIE1FQSBhbmQgTUxBIHRocm91Z2ggZmFjdG9yIGxvYWRpbmdzLg0KDQpgYGB7cn0NCiMjIHR3by1mYWN0b3IgYUVGQQ0KZWZhXzJmYWN0b3IgPC0gZmEoQ29tcC5BbnhpZXR5WywtMV0sIG5mYWN0b3JzID0gMiwgcm90YXRlID0gIm9ibGltaW4iLCANCiAgICAgICAgICAgICAgICAgIGZtID0gInBhIiwgc2NvcmVzID0gInJlZ3Jlc3Npb24iKQ0KIyBDcmVhdGUgYSBjbGVhbiBsb2FkaW5ncyB0YWJsZQ0KbG9hZGluZ3NfdGFibGUgPC0gZmEuc29ydChlZmFfMmZhY3RvciRsb2FkaW5nc1tdKQ0KcGFuZGVyKGxvYWRpbmdzX3RhYmxlLCBkaWdpdHMgPSAyLCBjdXRvZmYgPSAwLjMpDQpgYGANCg0KQXMgc2hvd24gaW4gdGhlIHRhYmxlIGFib3ZlLCBpdGVtcyAyLCA0LCA1LCBhbmQgOCBsb2FkIG9udG8gdGhlIGV2YWx1YXRpb24gYW54aWV0eSBmYWN0b3IsIHdoZXJlYXMgdGhlIHJlbWFpbmluZyBpdGVtcyBsb2FkIG9udG8gdGhlIGxlYXJuaW5nIGFueGlldHkgZmFjdG9yLiBUd28gZGlzdGluY3Qgc3Vic2NhbGVzIHdpbGwgYmUgZXN0YWJsaXNoZWQgZm9yIHN1YnNlcXVlbnQgYW5hbHlzZXMuDQoNCmBgYHtyfQ0KQW54aWV0eS5tZWEgPC0gQ29tcC5BbnhpZXR5WywgYygiSUQiLCAgIkFNQVMuMiIsICJBTUFTLjQiLCAiQU1BUy41IiwgICJBTUFTLjgiKV0NCkFueGlldHkubWxhIDwtIENvbXAuQW54aWV0eVssIGMoIklEIiwgIkFNQVMuMSIsICJBTUFTLjMiLCAiQU1BUy42IiwgIkFNQVMuNyIsICJBTUFTLjkiKV0NCmBgYA0KDQojIFZhbGlkYXRpb24gYW5kIFJlbGlhYmlsaXR5DQoNClRoZSBtYWpvciBtdWx0aS1pdGVtIGluc3RydW1lbnRzIHVzZWQgaW4gdGhpcyBzdHVkeSBhcmUgd2VsbC1lc3RhYmxpc2hlZCBhbmQgaGF2ZSBiZWVuIHVzZWQgaW4gdmFyaW91cyBwdWJsaXNoZWQgcmVzZWFyY2guIEluIHByYWN0aWNlLCB0aGUgdmFsaWRpdHkgYW5kIHJlbGlhYmlsaXR5IG9mIHN1Y2ggZXN0YWJsaXNoZWQgaW5zdHJ1bWVudHMgbXVzdCBiZSBjb25maXJtZWQgYmVmb3JlIGFueSBzdGF0aXN0aWNhbCBhbmFseXNpcy4gV2UgbmV4dCBwZXJmb3JtIHJlbGlhYmlsaXR5IGFuZCB2YWxpZGl0eSBhbmFseXNlcyB0byB3YXJyYW50IHRoZSBjcmVkaWJpbGl0eSBvZiB0aGUgb3ZlcmFsbCBzdXJ2ZXkgZGVzaWduIGFuZCB0aGUgcXVhbGl0eSBvZiB0aGUgY29sbGVjdGVkIGRhdGEuDQoNCiMjIFZhbGlkaXR5IEFuYWx5c2lzDQoNCioqVmFsaWRpdHkqKiBvZiBhIG11bHRpLWl0ZW0gc3VydmV5IGluc3RydW1lbnQgYW5zd2VycyB0aGUgcXVlc3Rpb246ICJBbSBJIGFjdHVhbGx5IG1lYXN1cmluZyB3aGF0IEkgaW50ZW5kIHRvIG1lYXN1cmU/IiBJdCdzIGFib3V0IHRoZSBzb3VuZG5lc3Mgb2YgdGhlIGludGVycHJldGF0aW9uIG9mIHRoZSBzY29yZXMuIEluIHBzeWNob21ldHJpY3MsICoqdmFsaWRpdHkqKiByZWZlcnMgdG8gdGhlIGRlZ3JlZSB0byB3aGljaCBhIHNjYWxlIG1lYXN1cmVzIHdoYXQgaXQgY2xhaW1zIHRvIG1lYXN1cmUuIEZvciBhIHNpbmdsZS1mYWN0b3IgaW5zdHJ1bWVudCwgdGhpcyBtZWFucyBhbGwgaXRlbXMgYXJlIGluZGljYXRvcnMgb2Ygb25lIHVuZGVybHlpbmcgY29uc3RydWN0IHN1Y2ggYXMgbWF0aHMgYW54aWV0eSwgc2VsZi1lZmZpY2FjeSwgZW5nYWdlbWVudCwgZXRjLiBpbiB0aGlzIGNvbXByZWhlbnNpdmUgc3VydmV5LiBUaGUgQ0ZBIGhhcyBiZWVuIHVzZWQgaW4gc3VydmV5IHJlc2VhcmNoIHdpZGVseSwgc2VlIFdhdHNvbiwgZXQgYWwgKDE5ODgpIGFuZCBNYXJzaCAoMTk5NikuDQoNCioqQ29uZmlybWF0b3J5IEZhY3RvciBBbmFseXNpcyAoQ0ZBKSoqIGlzIGEgcG93ZXJmdWwgc3RhdGlzdGljYWwgdGVjaG5pcXVlIHVzZWQgdG8gdGVzdCBhIHByZS1zcGVjaWZpZWQgdGhlb3J5IGFib3V0IHRoZSBzdHJ1Y3R1cmUgb2YgeW91ciBpbnN0cnVtZW50LiBXZSB1c2UgQ0ZBIHRvIGNvbmZpcm0gdGhhdCB5b3VyIGh5cG90aGVzaXplZCBzaW5nbGUtZmFjdG9yIG1vZGVsIGlzIGNvbnNpc3RlbnQgd2l0aCB0aGUgb2JzZXJ2ZWQgZGF0YS4gSXQgcHJvdmlkZXMgcmlnb3JvdXMgZXZpZGVuY2UgZm9yIGNvbnN0cnVjdCB2YWxpZGl0eSBpbiBhIGxpc3Qgb2YgY29udmVudGlvbmFsIG1lYXN1cmVzOg0KDQotICAgKipGYWN0b3IgTG9hZGluZ3MqKiBhcmUgdGhlIHN0YW5kYXJkaXplZCB3ZWlnaHRzIGZyb20gdGhlIENvbmZpcm1hdG9yeSBGYWN0b3IgQW5hbHlzaXMgKENGQSkuIFRoZSBzdWdnZXN0ZWQgZ3VpZGVsaW5lcyBhcmU6DQoNCiAgICAtICAgQSBsb2FkaW5nICoqbWFnbml0dWRlIGdyZWF0ZXIgdGhhbiAwLjUqKiBpbmRpY2F0ZXMgdGhhdCB0aGUgaXRlbSBzaGFyZXMgYXQgbGVhc3QgMjUlIG9mIGl0cyB2YXJpYW5jZSB3aXRoIHRoZSBsYXRlbnQgZmFjdG9yLiBJbiB0aGUgZm9sbG93aW5nIHRhYmxlLCB3ZSByZXBvcnQgdGhlIG1pbmltdW0gbG9hZGluZyBmb3IgZWFjaCBpbnN0cnVtZW50IHVuZGVyIHRoZSBjb2x1bW4gYHN0ZC5hbGwubWluYC4NCiAgICAtICAgQWxsIGxvYWRpbmdzIG11c3QgYmUgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCAocCBcPCAwLjA1KS4gV2UgcmVwb3J0IHRoZSBtYXhpbXVtIHAtdmFsdWUgZm9yIGVhY2ggaW5zdHJ1bWVudCB1bmRlciB0aGUgY29sdW1uIGBwdmFsLm1heGAuDQoNCi0gICAqKlN0YW5kYXJkaXplZCBSb290IE1lYW4gU3F1YXJlIFJlc2lkdWFsIChTUk1SKSoqIG1lYXN1cmVzIHRoZSBnb29kbmVzcy1vZi1maXQgb2YgdGhlIENGQSBtb2RlbC4gSXQgcmVwcmVzZW50cyB0aGUgYXZlcmFnZSBzdGFuZGFyZGl6ZWQgcmVzaWR1YWwgYmV0d2VlbiB0aGUgb2JzZXJ2ZWQgYW5kIHByZWRpY3RlZCBjb3JyZWxhdGlvbiBtYXRyaWNlcy4gQSBsb3dlciB2YWx1ZSBpbmRpY2F0ZXMgYSBiZXR0ZXIgZml0LCB3aXRoIGEgc3VnZ2VzdGVkIGN1dG9mZiBvZiAqKmxlc3MgdGhhbiAwLjA4KiouDQoNCi0gICAqKkNvbXBhcmF0aXZlIEZpdCBJbmRleCAoQ0ZJKSoqIGlzIGFub3RoZXIgZ29vZG5lc3Mtb2YtZml0IG1lYXN1cmUgZm9yIHRoZSBDRkEuIEl0IGNvbXBhcmVzIHRoZSBzcGVjaWZpZWQgbW9kZWwgdG8gYSBudWxsIChpbmRlcGVuZGVuY2UpIG1vZGVsLiBBIGhpZ2hlciB2YWx1ZSBpbmRpY2F0ZXMgYSBiZXR0ZXIgZml0LCB3aXRoIGEgc3VnZ2VzdGVkIGN1dG9mZiBvZiAqKmdyZWF0ZXIgdGhhbiAwLjkqKi4NCg0KLSAgICoqVHVja2VyLUxld2lzIEluZGV4IChUTEkpKiogYWxzbyBtZWFzdXJlcyB0aGUgZ29vZG5lc3Mtb2YtZml0IG9mIHRoZSBDRkEuIEl0cyBpbnRlcnByZXRhdGlvbiBhbmQgdXNhZ2UgYXJlIHNpbWlsYXIgdG8gdGhvc2Ugb2YgdGhlIENGSS4NCg0KQWZ0ZXIgc29tZSBleHBsb3JhdG9yeSBhbmFseXNpcywgd2UgZHJvcHBlZCBhIGZldyBpdGVtcyBmcm9tIHRoZSBUZWNobm9sb2d5IEluc3RydW1lbnQgYW5kIGRlZmluZWQgdHdvIHN1Y3NjYWxlcyBvZiB0aGUgaW5pdGlhbCByZXNvdXJjZSBpbnN0cnVtZW50czogKip1c2Ugb2YgcmVzb3VyY2UqKiBhbmQgKipzdHVkZW50IGVuZ2FnZW1lbnQqKi4NCg0KVGhlIGZpbmFsIHJlc3VsdHMgb24gdGhlIHN0cnVjdCB2YWxpZGl0eSBtZWFzdXJlcyBhcmUgc3VtbWFyaXplZCBpbiB0aGUgZm9sbG93aW5nIHRhYmxlLg0KDQpgYGB7ciBlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUV9DQpjZmEuYW5hbHlzaXMgPC0gZnVuY3Rpb24oZGF0YXNldCl7DQogICNkYXRhc2V0IDwtIENvbXAuQW54aWV0eQ0KICBwcmVkaWN0b3JzIDwtIG5hbWVzKGRhdGFzZXRbLCAtMV0pICANCiAgbjAgPC0gbGVuZ3RoKHByZWRpY3RvcnMpDQogIGNmYS5tb2RlbCA8LSAgcGFzdGUoImxhdGVudCA9fiIsIHBhc3RlKHByZWRpY3RvcnMsIGNvbGxhcHNlID0gIiArICIpKQ0KICBjZmEuZml0IDwtIGNmYShjZmEubW9kZWwsIGRhdGEgPSBkYXRhc2V0WywgLTFdLCBlc3RpbWF0b3IgPSAiTUxNIikNCiAgcmVzdWx0cyA8LSBzdW1tYXJ5KGNmYS5maXQsIHN0YW5kYXJkaXplZCA9IFRSVUUsIGZpdC5tZWFzdXJlcyA9IFRSVUUsIHJzcXVhcmUgPSBUUlVFKQ0KICBzdGQuYWxsLm1pbiA8LSBtaW4ocmVzdWx0cyRwZSRzdGQubHZbMTpuMF0pDQogIHB2YWwubWF4IDwtIG1heChyZXN1bHRzJHBlJHB2YWx1ZVsyOm4wXSkNCiAgc3JtciA8LSByZXN1bHRzJGZpdFsic3JtciJdDQogIGNmaSA8LSByZXN1bHRzJGZpdFsiY2ZpIl0NCiAgdGxpIDwtIHJlc3VsdHMkZml0WyJ0bGkiXQ0KICAjcm1zZWEgPC0gcmVzdWx0cyRmaXRbInJtc2VhIl0NCiAgY2JpbmQoc3RkLmFsbC5taW4gPSBzdGQuYWxsLm1pbiwgcHZhbC5tYXggPSBwdmFsLm1heCwgc3JtciA9IHNybXIsIGNmaSA9IGNmaSwgIHRsaSA9IHRsaSkNCn0NCmBgYA0KDQpgYGB7ciBlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZz1GQUxTRX0NCmFueGlldHkubWVhLnZsaWQgPC1jZmEuYW5hbHlzaXMoQW54aWV0eS5tZWEpDQphbnhpZXR5Lm1sYS52bGlkIDwtY2ZhLmFuYWx5c2lzKEFueGlldHkubWxhKQ0KYW54aWV0eS52bGlkIDwtY2ZhLmFuYWx5c2lzKENvbXAuQW54aWV0eSkNCmVmZmljYWN5LnZsaWQgPC1jZmEuYW5hbHlzaXMoQ29tcC5TZWxmRWZmaWNhY3kpDQp0ZWNoLnZsaWQgPC1jZmEuYW5hbHlzaXMoQ29tcC5UZWNobm9sb2d5KQ0KY29vcGVyYXRpdmUudmxpZCA8LWNmYS5hbmFseXNpcyhDb21wLkNvb3BvcmF0aXZlKQ0KZGVkdWN0aXZlLnZsaWQgPC1jZmEuYW5hbHlzaXMoQ29tcC5EZWR1Y3RpdmUpDQpkZW1vLnZsaWQgPC1jZmEuYW5hbHlzaXMoQ29tcC5EZW1vbnN0cmF0aW9uKQ0KaW5kdWN0aXZlLnZsaWQgPC1jZmEuYW5hbHlzaXMoQ29tcC5JbmR1Y3RpdmUpDQppbnRlZ3JhdGUudmxpZCA8LWNmYS5hbmFseXNpcyhDb21wLkludGVncmF0aXZlKQ0KbGVjdHVyZS52bGlkIDwtY2ZhLmFuYWx5c2lzKENvbXAuTGVjdHVyZVR5cGUpDQpyZXBldGl2ZS52bGlkIDwtY2ZhLmFuYWx5c2lzKENvbXAuUmVwZXRpdGl2ZSkNCmVuZ2FnZS52bGlkIDwtY2ZhLmFuYWx5c2lzKENvbXAuRW5nYWdlKQ0KcmVzb3VyY2UudmxpZCA8LWNmYS5hbmFseXNpcyhDb21wLlJlc291cmNlKQ0KIyMNCnZsaWQudGFibGUgPC1yYmluZChhbnhpZXR5Lm1lYSA9IGFueGlldHkubWVhLnZsaWQsIGFueGlldHkubWxhID0gYW54aWV0eS5tbGEudmxpZCwgDQogICAgICAgICAgICAgICAgICBhbnhpZXR5ID0gYW54aWV0eS52bGlkLCBzZWxmLmVmZmljYWN5ID0gZWZmaWNhY3kudmxpZCwNCiAgICAgICAgICAgICAgICAgIHRlY2hub2xvZ3kgPSB0ZWNoLnZsaWQsIGNvb3BlcmF0aXZlID0gY29vcGVyYXRpdmUudmxpZCwNCiAgICAgICAgICAgICAgICAgIGRlZHVjdGl2ZSA9IGRlZHVjdGl2ZS52bGlkLCBkZW1vbnN0cmF0aW9uID0gZGVtby52bGlkLA0KICAgICAgICAgICAgICAgICAgaW5kdWN0aXZlID0gaW5kdWN0aXZlLnZsaWQsIGludGVncmF0ZSA9IGludGVncmF0ZS52bGlkLA0KICAgICAgICAgICAgICAgICAgbGVjdHVyZSA9IGxlY3R1cmUudmxpZCwgcmVwZXRpdGl2ZSA9IHJlcGV0aXZlLnZsaWQsIA0KICAgICAgICAgICAgICAgICAgZW5nYWdlID0gZW5nYWdlLnZsaWQsIHJlc291cmNlID0gcmVzb3VyY2UudmxpZCkNCnJvdy5uYW1lIDwtIGMoImFueGlldHkubWVhIiwgImFueGlldHkubWxhIiwgImFueGlldHkiLCAic2VsZi5lZmZpY2FjeSIsIA0KICAgICAgICAgICAgICAidGVjaG5vbG9neSIsICJjb29wZXJhdGl2ZSIsDQogICAgICAgICAgICAgICJkZWR1Y3RpdmUiLCAiZGVtb25zdHJhdGlvbiIsICJpbmR1Y3RpdmUiLCAiaW50ZWdyYXRlIiwNCiAgICAgICAgICAgICAgImxlY3R1cmUiLCAicmVwZXRpdGl2ZSIsICJlbmdhZ2UiLCAicmVzb3VyY2UiKQ0KY29sLm5hbWUgPC0gYygic3RkLmFsbC5taW4iLCAicHZhbC5tYXgiLCAic3JtciIsICJjZmkiLCAgInRsaSIpDQpyb3duYW1lcyh2bGlkLnRhYmxlKSA8LSByb3cubmFtZQ0KY29sbmFtZXModmxpZC50YWJsZSkgPC0gY29sLm5hbWUNCnBhbmRlcih2bGlkLnRhYmxlKQ0KYGBgDQoNClRoZSBjb25zdHJ1Y3QgdmFsaWRpdHkgb2YgYWxsIG11bHRpLWl0ZW0gaW5zdHJ1bWVudHMgd2FzIGFzc2Vzc2VkIHVzaW5nIENvbmZpcm1hdG9yeSBGYWN0b3IgQW5hbHlzaXMgKENGSSkuIFRoZSByZXN1bHRzIGNvbmZpcm1lZCB0aGF0IG1vc3Qgc2NhbGVzIG1lZXQgZXN0YWJsaXNoZWQgcHN5Y2hvbWV0cmljIHN0YW5kYXJkcy4gVGhlIG1vanByaXR5IG9mIHRoZSBrZXkgZml0IGluZGljZXMsIGluY2x1ZGluZyBDRkkgYW5kIFRMSSwgZXhjZWVkZWQgdGhlIHJlY29tbWVuZGVkIHRocmVzaG9sZCBvZiAwLjkwLCB3aGlsZSB0aGUgU1JNUiBmZWxsIGJlbG93IHRoZSAwLjA4IGN1dG9mZiwgaW5kaWNhdGluZyBhIGdvb2QgbW9kZWwgZml0LiBGdXJ0aGVybW9yZSwgYWxsIGZhY3RvciBsb2FkaW5ncyB3ZXJlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgKHAgXDwgLjA1KSBhbmQgc3Vic3RhbnRpYWwgaW4gbWFnbml0dWRlIChleGNlZWRpbmcgMC40KSwgZGVtb25zdHJhdGluZyBzdHJvbmcgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIHRoZSBpdGVtcyBhbmQgdGhlaXIgaW50ZW5kZWQgbGF0ZW50IGNvbnN0cnVjdHMuIEluIHN1bW1hcnksIHRoZSB2YWxpZGl0eSBhbmFseXNpcyBjb25maXJtcyB0aGF0IHRoZSBpbnN0cnVtZW50cyB1c2VkIGluIHRoaXMgc3R1ZHkgYXJlIHJvYnVzdCBhbmQgYXBwcm9wcmlhdGUgZm9yIG1lYXN1cmluZyB0aGVpciByZXNwZWN0aXZlIGNvbmNlcHRzLg0KDQoqKlJlbWFya3MqKjogKDEpLiBUaGUgYWJvdmUgdmFsaWRpdHkgbWVhc3VyZXMgYmFzZWQgb24gdGhlIGl0ZW1zIGZvbGxvdyBtdWx0aS12YXJpYXRlIG5vcm1hbCBkaXN0cmlidXRpb24sIFRoaXMgaXMgYSBzdHJvbmcgYXNzdW1wdGlvbi4gVGhlIGl0ZW1zIGluIGVhY2ggaW5zdHJ1bWVudCBhcmUgbm90IGNvbnRpbm91cy4gVGhpcyBpbmZsdWVuY2VzIHNvbWUgb2YgdGhlIHZhbGlkaXR5IG1lYXN1cmUuICgyKS4gSW4gcHJhY3RpY2UsIHdlIGNhbiB1c2Ugc29tZSBkZXNjcmlwdGl2ZSBhcHByb2FjaGVzIHRvIHZpc3VhbCBjaGVjayB3aXRoIGFzc3VtaW5nIG11bHRpLXZhcmlhdGUgbm9ybWFsaXR5Lg0KDQojIyBSZWxpYW5iaWxpdHkgQW5hbHlzaXMNCg0KKipSZWxpYWJpbGl0eSoqIG9mIGEgbXVsdGktaXRlbSBzdXJ2ZXkgaW5zdHJ1bWVudCBhbnN3ZXJzIHRoZSBxdWVzdGlvbjogIklmIEkgbWVhc3VyZSB0aGUgc2FtZSB0aGluZyBtdWx0aXBsZSB0aW1lcywgd2lsbCBJIGdldCBhIGNvbnNpc3RlbnQgcmVzdWx0PyIgSXQgbWVhc3VyZXMgaG93IHdlbGwgdGhlIGl0ZW1zIHRoYXQgYXJlIHN1cHBvc2VkIHRvIG1lYXN1cmUgdGhlIHNhbWUgY29uc3RydWN0IGhhbmcgdG9nZXRoZXIuDQoNCioqSW50ZXJuYWwgQ29uc2lzdGVuY3kqKiBpcyB0aGUgbW9zdCBjb21tb24gYXNzZXNzbWVudCBmb3IgYSBzdXJ2ZXkgYWRtaW5pc3RlcmVkIG9uY2UuIEl0IG1lYXN1cmVzIHRoZSBkZWdyZWUgdG8gd2hpY2ggaXRlbXMgaW4gYSBzY2FsZSBhcmUgY29ycmVsYXRlZCB3aXRoIGVhY2ggb3RoZXIuIFR3byB3ZWxsLWtub3duIGludGVybmFsIGNvbnNpc3RlbmN5IG1lYXN1cmVzIGFyZSBDcm9uYmFjaCdzIEFscGhhIChDcm9uYWJjaywgMTk1MSkgYW5kIE1jRG9uYWxkJ3MgT21lZ2EgKDE5OTkpLiAqKk1jRG9uYWxkJ3MgT21lZ2EqKiBpcyBtb3JlIHJvYnVzdCB0aGFuICoqQ3JvbmJhY2gncyBBbHBoYSoqLg0KDQoqKkNyb25iYWNoJ3MgQWxwaGEqKiBhbmQgKipNY0RvbmFsZCdzIE9tZWdhKiogdHlwaWNhbGx5IHJhbmdlIGZyb20gMCB0byAxLiBUaGUgc3VnZ2VzdGVkIGN1dC1vZmZzIGFyZSBnaXZlbiBiZWxvdy4NCg0KLSAgIGA+IDAuOWA6IEV4Y2VsbGVudA0KDQotICAgYDAuOCAtIDAuOWA6IEdvb2QNCg0KLSAgIGAwLjcgLSAwLjhgOiBBY2NlcHRhYmxlDQoNCi0gICBgPCAwLjdgOiBQb29yIChtYXkgaGF2ZSBpdGVtcyB0aGF0IGRvbid0ICJiZWxvbmciKQ0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGV2YWwgPSBUUlVFfQ0KUmVsaWFiaWxpdHkuZnVuID0gZnVuY3Rpb24oZGF0YWZyYW1lKXsNCiAgb21lZ2EgPC0gcHN5Y2g6Om9tZWdhKGRhdGFmcmFtZVssIC0xXSwgbmZhY3RvcnMgPSAxLCBwbG90ID0gRkFMU0UpDQogIHJlbGlhYiA8LWNiaW5kKG9tZWdhJGFscGhhLCBvbWVnYSRvbWVnYS50b3QpDQogIHJlbGlhYg0KICB9DQpgYGANCg0KYGBge3IgZWNobyA9IFRSVUUsIGV2YWwgPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmc9RkFMU0V9DQphbnhpZXR5Lm1lYS5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKEFueGlldHkubWVhKQ0KYW54aWV0eS5tbGEucmVsIDwtIFJlbGlhYmlsaXR5LmZ1bihBbnhpZXR5Lm1sYSkNCmFueGlldHkucmVsIDwtIFJlbGlhYmlsaXR5LmZ1bihDb21wLkFueGlldHkpDQplZmZpY2FjeS5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKENvbXAuU2VsZkVmZmljYWN5KQ0KdGVjaC5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKENvbXAuVGVjaG5vbG9neSkNCmNvb3BlcmF0aXZlLnJlbCA8LSBSZWxpYWJpbGl0eS5mdW4oQ29tcC5Db29wb3JhdGl2ZSkNCmRlZHVjdGl2ZS5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKENvbXAuRGVkdWN0aXZlKQ0KZGVtby5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKENvbXAuRGVtb25zdHJhdGlvbikNCmluZHVjdGl2ZS5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKENvbXAuSW5kdWN0aXZlKQ0KaW50ZWdyYXRlLnJlbCA8LSBSZWxpYWJpbGl0eS5mdW4oQ29tcC5JbnRlZ3JhdGl2ZSkNCmxlY3R1cmUucmVsIDwtIFJlbGlhYmlsaXR5LmZ1bihDb21wLkxlY3R1cmVUeXBlKQ0KcmVwZXRpdmUucmVsIDwtIFJlbGlhYmlsaXR5LmZ1bihDb21wLlJlcGV0aXRpdmUpDQojYWZ0ZXIucmVsIDwtIFJlbGlhYmlsaXR5LmZ1bihDb21wLkFmdGVyQ2xhc3MpDQojaW4uY2xhc3MucmVsIDwtIFJlbGlhYmlsaXR5LmZ1bihDb21wLkluQ2xhc3MpDQplbmdhZ2UucmVsIDwtIFJlbGlhYmlsaXR5LmZ1bihDb21wLkVuZ2FnZSkNCnJlc291cmNlLnJlbCA8LSBSZWxpYWJpbGl0eS5mdW4oQ29tcC5SZXNvdXJjZSkNCiMjDQpSZWwudGFibGUgPC1yYmluZChhbnhpZXR5Lm1lYSA9IGFueGlldHkubWVhLnJlbCwgYW54aWV0eS5tbGEgPSBhbnhpZXR5Lm1sYS5yZWwsDQogICAgICAgICAgICAgICAgICBhbnhpZXR5ID0gYW54aWV0eS5yZWwsIHNlbGYuZWZmaWNhY3kgPSBlZmZpY2FjeS5yZWwsDQogICAgICAgICAgICAgICAgICB0ZWNobm9sb2d5ID0gdGVjaC5yZWwsIGNvb3BlcmF0aXZlID0gY29vcGVyYXRpdmUucmVsLA0KICAgICAgICAgICAgICAgICAgZGVkdWN0aXZlID0gZGVkdWN0aXZlLnJlbCwgZGVtb25zdHJhdGlvbiA9IGRlbW8ucmVsLA0KICAgICAgICAgICAgICAgICAgaW5kdWN0aXZlID0gaW5kdWN0aXZlLnJlbCwgaW50ZWdyYXRlID0gaW50ZWdyYXRlLnJlbCwNCiAgICAgICAgICAgICAgICAgIGxlY3R1cmUgPSBsZWN0dXJlLnJlbCwgcmVwZXRpdGl2ZSA9IHJlcGV0aXZlLnJlbCwgDQogICAgICAgICAgICAgICAgICBlbmdhZ2UgPSBlbmdhZ2UucmVsLCByZXNvdXJjZSA9IHJlc291cmNlLnJlbCkNCnJvdy5uYW1lIDwtIGMoImFueGlldHkubWVhIiwgImFueGlldHkubWxhIiwNCiAgICAgICAgICAgICAgImFueGlldHkiLCAic2VsZi5lZmZpY2FjeSIsICJ0ZWNobm9sb2d5IiwgImNvb3BlcmF0aXZlIiwNCiAgICAgICAgICAgICAgImRlZHVjdGl2ZSIsICJkZW1vbnN0cmF0aW9uIiwgImluZHVjdGl2ZSIsICJpbnRlZ3JhdGUiLA0KICAgICAgICAgICAgICAibGVjdHVyZSIsICJyZXBldGl0aXZlIiwgImVuZ2FnZSIsICJyZXNvdXJjZSIpDQpjb2wubmFtZSA8LSBjKCJDcm9uYmFjaCBhbHBoYSIsICJNY0RvbmFsZCdzIE9tZWdhIikNCnJvd25hbWVzKFJlbC50YWJsZSkgPC0gcm93Lm5hbWUNCmNvbG5hbWVzKFJlbC50YWJsZSkgPC0gY29sLm5hbWUNCnBhbmRlcihSZWwudGFibGUpDQpgYGANCg0KV2UgY2FuIHNlZSBmcm9tIHRoZSBhYm92ZSB0YWJsZSB0aGF0IGFsbCBjYWxjdWxhdGVkIGNvZWZmaWNpZW50cyBleGNlZWRlZCB0aGUgcmVjb21tZW5kZWQgdGhyZXNob2xkIG9mIDAuNywgaW5kaWNhdGluZyBnb29kIHJlbGlhYmlsaXR5LiBUaGUgcmVzdWx0cyBjb25maXJtIHRoYXQgdGhlIGluc3RydW1lbnRzIHVzZWQgaW4gdGhpcyBzdHVkeSBkZW1vbnN0cmF0ZSBzdHJvbmcgaW50ZXJuYWwgY29uc2lzdGVuY3ksIG1lYW5pbmcgdGhlIGl0ZW1zIHdpdGhpbiBlYWNoIHNjYWxlIHJlbGlhYmx5IG1lYXN1cmUgdGhlIHNhbWUgdW5kZXJseWluZyBjb25zdHJ1Y3QuDQoNCiMgQ29tcG9zaXRlIFNjb3JpbmcNCg0KVGhlIGNvcmUgcHVycG9zZSBvZiBjb25zdHJ1Y3RpbmcgbXVsdGktaXRlbSBzdXJ2ZXlzIGlzIHRvIG1lYXN1cmUgY29tcGxleCBjb25jZXB0cyB3aXRoIGdyZWF0ZXIgYWNjdXJhY3ksIHJlbGlhYmlsaXR5LCBhbmQgZGVwdGggdGhhbiBhIHNpbmdsZSBxdWVzdGlvbiBldmVyIGNvdWxkLiBBbGwgaW5zdHJ1bWVudHMgdXNlZCBpbiB0aGlzIHN0dWR5IGFyZSBiYXNlZCBvbiBhIHNpbmdsZS1mYWN0b3IgY29uc3RydWN0IHVzaW5nIHRoZSBMaWtlcnQgc2NhbGVzLiBUaGUgY29tbW9ubHkgdXNlZCBtZXRob2RzIGZvciBkZWZpbmluZyBzaW5nbGUgaW5kZXggdG8gY2FwdHVyZSB0aGUgaW5mb3JtYXRpb24gb2YgdGhlIHNpbmdsZS1mYWN0b3IgY29uc3RydWN0IGFyZSBjbGFzc2lmaWVkIGluIHRocmVlIGNhdGVnb3JpZXMNCg0KIyMgU3VtbWluZyB0aGUgUmF3IExpa2VydCBTY29yZXMNCg0KVGhlIHNpbXBsZXN0IGFwcHJvYWNoIGlzIHRvIHN1bSB0aGUgcmF3IExpa2VydCBzY29yZXMgaW50byBhIGNvbXBvc2l0ZSBzY29yZSB0aGF0IHJlcHJlc2VudHMgYSBzaW5nbGUgZmFjdG9yIHdpdGhpbiB0aGUgc3VydmV5IGNvbnN0cnVjdC4gVGhpcyBtZXRob2QgaXMgdmFsaWQgcHJvdmlkZWQgdGhhdCBhbGwgcXVlc3Rpb25uYWlyZSBpdGVtcyBhcmUgZXF1YWxseSBpbXBvcnRhbnQsIGFzIGVhY2ggY2FwdHVyZXMgYSBzaW1pbGFyIGFtb3VudCBvZiBpbmZvcm1hdGlvbiBhYm91dCB0aGUgdW5kZXJseWluZyBmYWN0b3IuDQoNCkhvd2V2ZXIsIHRoaXMgYXBwcm9hY2ggaXMgdmlvbGF0ZWQgaW4gc2V2ZXJhbCBjcml0aWNhbCBzY2VuYXJpb3MsIGxlYWRpbmcgdG8gYSBiaWFzZWQgYW5kIHVucmVsaWFibGUgY29tcG9zaXRlIHNjb3JlLiBGb3IgZXhhbXBsZSwgKipWaW9sYXRpb24gb2YgRXF1YWwgSW1wb3J0YW5jZSoqOiBUaGUgY29yZSBhc3N1bXB0aW9uIGlzIHRoYXQgZWFjaCBpdGVtIGlzIGEgZXF1YWxseSBzdHJvbmcgaW5kaWNhdG9yIG9mIHRoZSBjb25zdHJ1Y3QuIEluIHJlYWxpdHksIGl0ZW1zIG9mdGVuIGhhdmUgZGlmZmVyZW50IGxldmVscyBvZiBpbXBvcnRhbmNlLiBTdW1taW5nIGl0ZW1zIHdpdGggaGlnaCBhbmQgbG93IGxldmVscyBvZiBpbXBvcnRhbmNlIGVxdWFsbHkgZ2l2ZXMgdW5kdWUgd2VpZ2h0IHRvIHdlYWtlciBpbmRpY2F0b3JzLCBlZmZlY3RpdmVseSBkaWx1dGluZyB0aGUgY29tcG9zaXRlIHNjb3JlIHdpdGggbm9pc2UgYW5kIHJlZHVjaW5nIGl0cyB2YWxpZGl0eS4NCg0KIyMgRkEgQXBwcm9hY2gNCg0KQ29uZmlybWF0b3J5IEZhY3RvciBBbmFseXNpcyAoQ0ZBKSBpcyBhIHZlcnkgY29tbW9uIGFuZCBvZnRlbiBwcmFjdGljYWwgYXBwcm9hY2ggdG8gdmFsaWRhdGluZyBzdXJ2ZXkgaW5zdHJ1bWVudHMgYW5kIGNyZWF0ZSAod2VpZ2h0ZWQpIGNvbXBvc2l0ZSBzY29yZS4gSXQgaXMgYSBkaXN0cmlidXRpb24gZGVwZW5kZW50IHN0YXRpc3RpY2FsIG1ldGhvZC4gSG93ZXZlciwgaXQgY29tZXMgd2l0aCBhIHNldCBvZiBkaXN0aW5jdCBzb21lIGRpc2FkdmFudGFnZXMgcGFydGljdWxhcmx5IHRoZSBhc3N1bXB0aW9uIG9mIG11bHRpLXZhcmlhdGUgbm9ybWFsIGRpc3RyaWJ1dGlvbi4gRmFjdG9yIGxvYWRpbmdzIGluIENGQSBhcmUgZXN0aW1hdGVkIGJhc2VkIG9uIHRoZSBtYXhpbXVtIGxpa2VsaWhvb2Qgd2hpY2ggaXMgZGVmaW5lZCBiYXNlZCBvbiBtdWx0aXZhcmlhdGUgbm9ybWFsIGRpc3RyaWJ1dGlvbi4NCg0KV2UgaGF2ZSB1c2VkIENGQSB0byB2YWxpZGF0ZSB0aGUgaW5zdHJ1bWVudC4gU2luY2UgYWxsIGluc3RydW1lbnRzIGluIHRoaXMgc3R1ZHkgYXJlIHNpbmdsZS1mYWN0b3IgY29uc3RydWN0cywgd2Ugd2lsbCBjYWxjdWxhdGUgdGhlIHNpbmdsZSBjb21wb3NpdGUgc2NvcmUgZm9yIGVhY2ggaW5zdHJ1bWVudCB1c2luZyBDRkEuDQoNCiMjIFBDQSBBcHByb2FjaA0KDQpQQ0EgaXMgYSBkaXN0cmlidXRpb24tZnJlZSBtZXRob2Qgd2hpY2ggdXNlcyBhIG1hdGhlbWF0aWNhbCB0cmFuc2Zvcm1hdGlvbiAob3J0aG9nb25hbCByb3RhdGlvbikgdG8gb2J0YWluIGEgbmV3IGNvb3JkaW5hdGUgc3lzdGVtIHN1Y2ggdGhhdCB0aGUgZmlyc3QgbmV3IGF4aXMgKFByaW5jaXBhbCBDb21wb25lbnQgMSkgcG9pbnRzIGluIHRoZSBkaXJlY3Rpb24gb2YgdGhlIG1heGltdW0gdmFyaWFuY2UgaW4gdGhlIGRhdGEuIFRoZSBzZWNvbmQgYXhpcyBpcyBvcnRob2dvbmFsIHRvIHRoZSBmaXJzdCBhbmQgcG9pbnRzIGluIHRoZSBkaXJlY3Rpb24gb2YgdGhlIG5leHQgZ3JlYXRlc3QgdmFyaWFuY2UsIGFuZCBzbyBvbi4gVGhlIG5ldyBheGVzIChjb21wb25lbnRzKSBhcmUgbGluZWFyIGNvbWJpbmF0aW9ucyBvZiB0aGUgb3JpZ2luYWwgdmFyaWFibGVzLiBDb25zZXF1ZW50bHksIGEgay1pdGVtIGluc3RydW1lbnQgd2lsbCBnZW5lcmF0ZSBrIHByaW5jaXBhbCBjb21wb25lbnRzLg0KDQpBbHRob3VnaCB0aGVyZSBkZWJhdGVzIG9uIHVzaW5nIFBDQSBpbiBwc3ljaG9tZXRyaWNzLCB0aGUgZWFybGllc3QgYXBwbGljYXRpb25zIG9mIFBDQSBpbiBzdXJ2ZXkgcmVzZWFyY2ggY2FuIGJlIHRyYWNlZCBiYWNrIHRvIDE5NTBzIChTdG91ZmZlciBldCBhbC4sIDE5NTA7IENhdHRlbGwsIDE5NTI7IER1bmNhbiwgMTkgKS4gVGhlIGdvYWwgd2FzIGNvbnNpc3RlbnRseSB0aGUgc2FtZSBhcyBpdCBpcyB0b2RheTogdG8gdW5jb3ZlciB0aGUgc2ltcGxlLCBsYXRlbnQgc3RydWN0dXJlcyB0aGF0IHVuZGVybGllIHRoZSBjb21wbGV4IGNvcnJlbGF0aW9ucyBhbW9uZyBtYW55IG9ic2VydmVkIHN1cnZleSBxdWVzdGlvbnMuDQoNCjxmb250IGNvbG9yID0gInJlZCI+KipBZGp1c3RpbmcgRGlyZWN0aW9uIG9mIFBDcyoqPC9mb250Pg0KDQpQcmluY2lwYWwgQ29tcG9uZW50cyAoUENzKSBhcmUgbmV3LCB1bmNvcnJlbGF0ZWQgYXhlcywgd2hlcmVhcyBMaWtlcnQgc2NvcmVzIGFyZSBvcmRpbmFsIHJhdGluZyBzY2FsZXMuIFdoZW4gdXNpbmcgUENzIHRvIHJlcHJlc2VudCB0aGVzZSByYXRpbmcgc2NhbGVzLCB0aGVpciBkaXJlY3Rpb24gbXVzdCBiZSBhbGlnbmVkLiBBIHNpbXBsZSBtZXRob2QgdG8gZGV0ZXJtaW5lIGlmIGEgUEMncyBkaXJlY3Rpb24gbmVlZHMgdG8gYmUgcmV2ZXJzZWQgaXMgdG8gZXhhbWluZSB0aGUgY29ycmVsYXRpb24gY29lZmZpY2llbnRzIGJldHdlZW4gdGhlIG5haXZlIGNvbXBvc2l0ZSBhdmVyYWdlIHNjb3JlcyBhbmQgdGhlIFBDIHNjb3Jlcy4gSWYgdGhlIGNvcnJlbGF0aW9uIGlzIG5lZ2F0aXZlLCB0aGUgY29ycmVzcG9uZGluZyBQQyBzaG91bGQgYmUgcmV2ZXJzZWQ7IG90aGVyd2lzZSwgdGhlIGRlZmF1bHQgYXhpcyBzaG91bGQgYmUgcmV0YWluZWQuDQoNCioqQ29tcG9zaXRlIFNjb3JpbmcgVXNpbmcgVGhlIGZpcnN0IFByaW5jaXBhbCBDb21wb25lbnQgKFBDMSkqKg0KDQpUaGlzIGFwcHJvYWNoIGhhcyBiZWVuIGVtcGxveWVkIHNpbmNlIHRoZSAxOTUwcyAoZS5nLiwgR3V0dG1hbiwgMTk1NDsgSGlyc2NoYmVyZyAmIFN0YW5kaXNoLCAxOTU5OyBEdW5jYW4sIDE5NjEpLiBUaGUgcmF0aW9uYWxlIGZvciB1c2luZyB0aGUgZmlyc3QgcHJpbmNpcGFsIGNvbXBvbmVudCBpcyB0aGF0IGl0IGFjY291bnRzIGZvciB0aGUgbWF4aW11bSB2YXJpYW5jZSBpbiB0aGUgZGF0YSBhbmQgY29uc3RpdHV0ZXMgYSBsaW5lYXIgY29tYmluYXRpb24gb2YgYWxsIGl0ZW1zLiBNdWNoIGxpa2UgaW4gY29uZmlybWF0b3J5IGZhY3RvciBhbmFseXNpcyAoQ0ZBKSwgdGhlIGZpcnN0IHByaW5jaXBhbCBjb21wb25lbnQgY2FuIGJlIGludGVycHJldGVkIGFzIGEgd2VpZ2h0ZWQgYXZlcmFnZSBvZiBpbmRpdmlkdWFsIGl0ZW0gc2NvcmVzLg0KDQoqKkNvbXBvc2l0ZSBTY29yaW5nIFVzaW5nIFdlaWdodGVkIEF2ZXJhZ2Ugb2YgSXRlbSBTY29yZXMgQWNyb3NzIEFsbCBQQ3M6KiogPGZvbnQgY29sb3IgPSAicmVkIj5Eb3VibHkgV2VpZ2h0ZWQgQXZlcmFnZTwvZm9udD4NCg0KSW4gbWFueSByZWFsLXdvcmxkIGRhdGFzZXRzLCB0aGUgdW5kZXJseWluZyBjb25zdHJ1Y3RzIGFyZSBpbmhlcmVudGx5IG11bHRpZGltZW5zaW9uYWwuIENvbnNlcXVlbnRseSwgbGltaXRpbmcgdGhlIGFuYWx5c2lzIHRvIHRoZSBmaXJzdCBwcmluY2lwYWwgY29tcG9uZW50IG1lYW5zIGRpc2NhcmRpbmcgc3RydWN0dXJlZCBpbmZvcm1hdGlvbiBjYXB0dXJlZCBieSBzdWJzZXF1ZW50IGNvbXBvbmVudHMgKFBDMiwgUEMzLCBldGMuKS4gQSBjb21wb3NpdGUgc2NvcmUgdGhhdCBpbnRlZ3JhdGVzIGFsbCBzaWduaWZpY2FudCBjb21wb25lbnRzIG9mZmVycyBhIG1vcmUgaG9saXN0aWMgYW5kIGFjY3VyYXRlIHN1bW1hcnkgbWVhc3VyZS4gVGhlIHByaW1hcnkgYmFycmllciB0byB0aGUgd2lkZXNwcmVhZCBhZG9wdGlvbiBvZiB0aGlzIG1ldGhvZCBpcyB0aGUgY2hhbGxlbmdlIGFzc29jaWF0ZWQgd2l0aCBpbnRlcnByZXRpbmcgdGhlIGNvbXBvc2l0ZSBpbmRleCdzIHN0cnVjdHVyZS4NCg0KIyMgQ29tcG9zaXRlIFNjb3JlcyBUbyBCZSBDcmVhdGVkDQoNCldlIHdpbGwgZ2VuZXJhdGUgZm91ciB0eXBlcyBvZiBjb21wb3NpdGUgc2NvcmVzIGZvciBlYWNoIG9mIHRoZSAxMSBpbnN0cnVtZW50cyBmb3IgdGhlIHB1cnBvc2Ugb2YgZW1waXJpY2FsIGNvbXBhcmlzb24uDQoNCi0gICAqKmF2ZyoqOiBUaGUgYXZlcmFnZSBvZiB0aGUgcmF3IGl0ZW0gc2NvcmVzLg0KLSAgICoqY2ZhKio6IFRoZSBleHRyYWN0IGNvbmZpcm1hdG9yeSBmYWN0b3IgYW5hbHlzaXMgKGNmYSkgc2NvcmUgKGFsbCBpbnN0cnVtZW50cyBhcmUgYmFzZWQgb24gdGhlIHNpbmdsZS1mYWN0b3IgY29uc3RydWN0KS4NCi0gICAqKnBjYTEqKjogVGhlIGZpcnN0IHByaW5jaXBhbCBjb21wb25lbnQgc2NvcmVzLg0KLSAgICoqcGNhLnd0Kio6IFRoZSB3ZWlnaHRlZCBhdmVyYWdlIG9mIHBjYSBzY29yZXMgYWNyb3NzIGFsbCBwcmluY2lwYWwgY29tcG9uZW50cy4NCg0KYGBge3IgZWNobyA9IFRSVUUsIGV2YWwgPSBUUlVFfQ0KIyMjIyMNCiBzY29yZXMgPSBmdW5jdGlvbihkZiwgZG4pew0KICAjIyMjIyMjIyMjIyMjIyMNCiAgIyBtZWFuIHNjb3JlDQogICMjIyMjIyMjIyMjIyMjDQogIGRmLm1lYW4gPC0gcm93TWVhbnMoZGZbLCAtMV0pDQogICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KICAjIyBzaW5nbGUgZmFjdG9yIHNjb3JlDQogICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQogIHgudmFyIDwtIG5hbWVzKGRmWywgLTFdKQ0KICBuMCA8LSBsZW5ndGgoeC52YXIpDQogIGNmYS5tb2RlbCA8LSAgcGFzdGUoImxhdGVudCA9fiIsIHBhc3RlKHgudmFyLCBjb2xsYXBzZSA9ICIgKyAiKSkNCiAgY2ZhLmZpdCA8LSBjZmEoY2ZhLm1vZGVsLCBkYXRhID0gZGZbLCAtMV0sIGVzdGltYXRvciA9ICJNTE0iKQ0KICBjb21wb3NpdGUuY2ZhIDwtIGxhdlByZWRpY3QoY2ZhLmZpdCkNCiAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiAgIyBwY2EgYW5hbHlzaXMNCiAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiAgcGNhLm1kbCA8LSBwcmNvbXAoZGZbLC0xXSwgc2NhbGUgPSBUUlVFKQ0KICBwY2EwIDwtIHBjYS5tZGwkeFssIDFdDQogIHIwID0gY29yKHBjYTAsIGRmLm1lYW4pDQogIGlmKHIwIDwgMCkgew0KICAgICBwY2EuYWxsIDwtIC1wY2EubWRsJHgNCiAgfWVsc2V7DQogICAgcGNhLmFsbCA8LSBwY2EubWRsJHgNCiAgfQ0KICBmaXJzdC5wY2EgPSBwY2EuYWxsWywxXQ0KICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KICAjIHdlaWdodGVkIHBjYSBzY29yZQ0KICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KICB2YXIuZXhwbGFpbmVkIDwtKChwY2EubWRsJHNkZXYpXjIpIC8gc3VtKChwY2EubWRsJHNkZXYpXjIpICMNCiAgY29tcG9zaXRlX3dlaWdodGVkX3BjYSA8LSBhcy5tYXRyaXgocGNhLmFsbCkgJSolICh2YXIuZXhwbGFpbmVkKQ0KDQogIG91dGRhdGEgPC0gYXMuZGF0YS5mcmFtZShjYmluZChhdmcgPSBkZi5tZWFuLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBjYTEgPSBmaXJzdC5wY2EsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgd3QucGNhID0gYXMudmVjdG9yKGNvbXBvc2l0ZV93ZWlnaHRlZF9wY2EpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNmYSA9IGFzLnZlY3Rvcihjb21wb3NpdGUuY2ZhKSkpDQogIG5hbWVzKG91dGRhdGEpIDwtIHBhc3RlMChkbiwiLiIsIG5hbWVzKG91dGRhdGEpLCBzZXAgPSAiIikNCiAgb3V0ZGF0YQ0KICB9DQojIyMNCkFueGlldHkubWVhLnNjb3JlID0gc2NvcmVzKEFueGlldHkubWVhLCAiQW54aWV0eS5tZWEiKQ0KQW54aWV0eS5tbGEuc2NvcmUgPSBzY29yZXMoQW54aWV0eS5tbGEsICJBbnhpZXR5Lm1sYSIpDQpBbnhpZXR5LnNjb3JlID0gc2NvcmVzKENvbXAuQW54aWV0eSwgIkFueGlldHkiKQ0KU2VsZkVmZmljYWN5LnNjb3JlID0gc2NvcmVzKENvbXAuU2VsZkVmZmljYWN5MCwgIlNlbGZFZmZpY2FjeSIpDQpUZWNobm9sb2d5LnNjb3JlID0gc2NvcmVzKENvbXAuVGVjaG5vbG9neSwgIlRlY2hub2xvZ3kiKQ0KQ29vcG9yYXRpdmUuc2NvcmUgPSBzY29yZXMoQ29tcC5Db29wb3JhdGl2ZSwgIkNvb3BvcmF0aXZlIikNCkRlZHVjdGl2ZS5zY29yZSA9IHNjb3JlcyhDb21wLkRlZHVjdGl2ZSwgIkRlZHVjdGl2ZSIpDQpEZW1vbnN0cmF0aW9uLnNjb3JlID0gc2NvcmVzKENvbXAuRGVtb25zdHJhdGlvbiwgIkRlbW9uc3RyYXRpb24iKQ0KSW5kdWN0aXZlLnNjb3JlID0gc2NvcmVzKENvbXAuSW5kdWN0aXZlLCAiSW5kdWN0aXZlIikNCkludGVncmF0aXZlLnNjb3JlID0gc2NvcmVzKENvbXAuSW50ZWdyYXRpdmUsICJJbnRlZ3JhdGl2ZSIpDQpMZWN0dXJlVHlwZS5zY29yZSA9IHNjb3JlcyhDb21wLkxlY3R1cmVUeXBlLCAiTGVjdHVyZVR5cGUiKQ0KUmVwZXRpdGl2ZS5zY29yZSA9IHNjb3JlcyhDb21wLlJlcGV0aXRpdmUsICJSZXBldGl0aXZlIikNCkVuZ2FnZS5zY29yZSA9IHNjb3JlcyhDb21wLkVuZ2FnZSwgIkVuZ2FnZSIpDQpSZXNvdXJjZS5zY29yZSA9IHNjb3JlcyhDb21wLlJlc291cmNlLCAiUmVzb3VyY2UiKQ0KIyMNCmZpbmFsRGF0IDwtIGNiaW5kKGRlbW9ncmFwaGljcywgQW54aWV0eS5zY29yZSwgQW54aWV0eS5tZWEuc2NvcmUsDQogICAgICAgICAgICAgICAgICBBbnhpZXR5Lm1sYS5zY29yZSwgU2VsZkVmZmljYWN5LnNjb3JlLCBUZWNobm9sb2d5LnNjb3JlLA0KICAgICAgICAgICAgICAgICAgQ29vcG9yYXRpdmUuc2NvcmUsIERlZHVjdGl2ZS5zY29yZSwgRGVtb25zdHJhdGlvbi5zY29yZSxJbmR1Y3RpdmUuc2NvcmUsDQogICAgICAgICAgICAgICAgICBJbnRlZ3JhdGl2ZS5zY29yZSwgTGVjdHVyZVR5cGUuc2NvcmUsIFJlcGV0aXRpdmUuc2NvcmUsDQogICAgICAgICAgICAgICAgICBFbmdhZ2Uuc2NvcmUsIFJlc291cmNlLnNjb3JlKQ0KYGBgDQoNCmBgYHtyIGVjaG8gPSBGQUxTRSwgZXZhbCA9IEZBTFNFfQ0Kd3JpdGUuY3N2KGZpbmFsRGF0LCAiQzpcXFVzZXJzXFw3NUNQRU5HXFxPbmVEcml2ZSAtIFdlc3QgQ2hlc3RlciBVbml2ZXJzaXR5IG9mIFBBXFxEZXNrdG9wXFxjcGVuZ1xcV0NVLVRlYWNoaW5nXFwyMDI1RmFsbFxcTWF0aEF4aWV0eVxcY29tcGxldGVBbnhpZXR5RGF0YS5jc3YiKQ0KYGBgDQoNCiMgU29tZSBHcmFwaGljYWwgRXhwbG9yYXRpb24NCg0KV2UgbmV4dCBleHBsb3JlIHRoZSBkaXN0cmlidXRpb25zIG9mIHRoZSBjcmVhdGVkIGNvbXBvc2l0ZSBzY29yZXMgYW5kIHBlcmZvcm0gc29tZSBlbXBpcmljYWwgY29tcGFyaXNvbnMuIFRoZSBwcmltYXJ5IGdvYWwgb2YgdGhpcyBzdXJ2ZXkgc3R1ZHkgaXMgdG8gaW52ZXN0aWdhdGUgZmFjdG9ycyB0aGF0IGFyZSBhc3NvY2lhdGVkIHdpdGggbWF0aGVtYXRpY3MgYW54aWV0eSAoTUEpIGxldmVscy4gVG8gdGhpcyBlbmQsIHdlIGFsc28gbG9vayB0aGUgZGlzdHJpYnV0aW9ucyBlYWNoIGluZGl2aWR1YWwgaXRlbXMgaW4gdGhlIE1BIGluc3RydW1lbnQuDQoNCiMjIERpc3RyaWJ1dGlvbnMgb2YgQ29tcG9zaXRlIFNjb3Jlcw0KDQpUaGUgZm9sbG93aW5nIGFyZSBkaXN0cmlidXRpb25zIG9mIGZvdXIgZ2VuZXJhdGVkIGNvbXBvc2l0ZSBzY29yZXMgYWNyb3NzIGFsbCBpbnN0cnVtZW50cy4gVGhlIHB1cnBvc2UgaXMgdG8gZXhhbWluZSB0aGUgYmVoYXZpb3JzIG9mIHRoZXNlIGNvbXBvc2l0ZSBzY29yZXMsIGVzcGVjaWFsbHkgdGhlIGRvdWJseSB3ZWlnaHRlZCBjb21wb3NpdGUgc2NvcmUgYmFzZWQgb24gdGhlIHByaW5jaXBhbCBjb21wb25lbnQgYW5hbHlzaXMuDQoNCmBgYHtyIGVjaG8gPSBGQUxTRX0NCiNmaW5hbC5hbnhpZXR5LmRhdCA8LSByZWFkLmNzdigiaHR0cHM6Ly9wZW5nZHNjaS5naXRodWIuaW8vTWF0aEFueGlldHkvY29tcGxldGVBbnhpZXR5RGF0YS5jc3YiKQ0KZmluYWwuYW54aWV0eS5kYXQgPC0gZmluYWxEYXQNCmBgYA0KDQpgYGB7cn0NCnBsb3RseS5mdW4gPC0gZnVuY3Rpb24oaW4uZGF0YSl7DQogICBpbi5hdmcgPC0gZGVuc2l0eShpbi5kYXRhWywxXSkNCiAgIGluLnBjMSA8LSBkZW5zaXR5KGluLmRhdGFbLDJdKQ0KICAgaW4ucGN3IDwtIGRlbnNpdHkoaW4uZGF0YVssM10pDQogICBpbi5jZmEgPC0gZGVuc2l0eShpbi5kYXRhWywgNF0pDQogICBkYXQubmFtZSA8LSBzdWIoIlxcLi4qIiwgIiIsbmFtZXMoaW4uZGF0YSlbMV0pICAjc3ViKCB0ZXh0KQ0KICAgIyBwbG90IGRlbnNpdHkgY3VydmVzDQogIGZpZyA8LSBwbG90X2x5KHggPSB+aW4uYXZnJHgsIHkgPSB+aW4uYXZnJHksIA0KICAgICAgICAgICAgICAgdHlwZSA9ICdzY2F0dGVyJywgDQogICAgICAgICAgICAgICBtb2RlID0gJ2xpbmVzJywgDQogICAgICAgICAgICAgICBuYW1lID0gJ2F2ZycsIA0KICAgICAgICAgICAgICAgZmlsbCA9ICd0b3plcm95JykgICU+JSANCiAgICAgICAgICAgIyBhZGRpbmcgbW9yZSBkZW5zaXR5IGN1cnZlcw0KICAgICAgIGFkZF90cmFjZSh4ID0gfmluLnBjMSR4LCB5ID0gfmluLnBjMSR5LCANCiAgICAgICAgICAgICAgICAgbmFtZSA9ICdwY2ExJywgDQogICAgICAgICAgICAgICAgIGZpbGwgPSAndG96ZXJveScpICAlPiUgDQogICAgICAgYWRkX3RyYWNlKHggPSB+aW4ucGN3JHgsIHkgPSB+aW4ucGN3JHksIA0KICAgICAgICAgICAgICAgICBuYW1lID0gJ3BjYS53dCcsIA0KICAgICAgICAgICAgICAgICBmaWxsID0gJ3RvemVyb3knKSAgJT4lIA0KICAgICAgIGFkZF90cmFjZSh4ID0gfmluLmNmYSR4LCB5ID0gfmluLmNmYSR5LCANCiAgICAgICAgICAgICAgICAgbmFtZSA9ICdjZmEnLCANCiAgICAgICAgICAgICAgICAgZmlsbCA9ICd0b3plcm95JykgICU+JSANCiAgICAgICBsYXlvdXQoeGF4aXMgPSBsaXN0KHRpdGxlID0gJ3Njb3JlcycpLA0KICAgICAgICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAnRGVuc2l0eScpLA0KICAgICAgICAgICAgICAjdGl0bGUgPSBkYXQubmFtZSwNCiAgICAgICAgICAgICAgIG1hcmdpbiA9IGxpc3QoDQogICAgICAgICAgICAgICAgICB0ID0gMTAwLCAgIyBBZGp1c3QgdGhpcyB2YWx1ZSB0byBpbmNyZWFzZSBvciBkZWNyZWFzZSB0aGUgdG9wIG1hcmdpbg0KICAgICAgICAgICAgICAgICAgYiA9IDUwLA0KICAgICAgICAgICAgICAgICAgbCA9IDUwLA0KICAgICAgICAgICAgICAgICAgciA9IDUwKQ0KICAgICAgICAgICAgICkNCiAgICAgZmlnDQogICAgIH0NCiMjIyMNCmluLmFueGlldHkubWVhID0gZmluYWwuYW54aWV0eS5kYXRbLCBjKCAiQW54aWV0eS5tZWEuYXZnIiwgIkFueGlldHkubWVhLnBjYTEiLCAiQW54aWV0eS5tZWEud3QucGNhIiwiQW54aWV0eS5tZWEuY2ZhIildDQppbi5hbnhpZXR5Lm1sYSA9IGZpbmFsLmFueGlldHkuZGF0WywgYygiQW54aWV0eS5tbGEuYXZnIiwiQW54aWV0eS5tbGEucGNhMSIsICJBbnhpZXR5Lm1sYS53dC5wY2EiLCJBbnhpZXR5Lm1sYS5jZmEiKV0NCiMjIw0KaW4uYW54aWV0eSA9IGZpbmFsLmFueGlldHkuZGF0WywgYyggIkFueGlldHkuYXZnIiwgIkFueGlldHkucGNhMSIsICJBbnhpZXR5Lnd0LnBjYSIsICJBbnhpZXR5LmNmYSIpXQ0KaW4uZWZmaWNhY3kgPSBmaW5hbC5hbnhpZXR5LmRhdFssIGMoICJTZWxmRWZmaWNhY3kuYXZnIiwgIlNlbGZFZmZpY2FjeS5wY2ExIiwiU2VsZkVmZmljYWN5Lnd0LnBjYSIsIlNlbGZFZmZpY2FjeS5jZmEiKV0NCmluLnRlY2hub2xvZ3kgPSBmaW5hbC5hbnhpZXR5LmRhdFssIGMoICJUZWNobm9sb2d5LmF2ZyIsIlRlY2hub2xvZ3kucGNhMSIsICJUZWNobm9sb2d5Lnd0LnBjYSIsIlRlY2hub2xvZ3kuY2ZhIildDQppbi5jb29wb3JhdGl2ZSA9IGZpbmFsLmFueGlldHkuZGF0WywgYygiQ29vcG9yYXRpdmUuYXZnIiwiQ29vcG9yYXRpdmUucGNhMSIsICJDb29wb3JhdGl2ZS53dC5wY2EiLCJDb29wb3JhdGl2ZS5jZmEiKV0NCmluLmRlZHVjdGl2ZSA9IGZpbmFsLmFueGlldHkuZGF0WywgYygiRGVkdWN0aXZlLmF2ZyIsIkRlZHVjdGl2ZS5wY2ExIiwiRGVkdWN0aXZlLnd0LnBjYSIsIkRlZHVjdGl2ZS5jZmEiKV0NCmluLmRlbW9uc3RyYXRpb24gPSBmaW5hbC5hbnhpZXR5LmRhdFssIGMoIkRlbW9uc3RyYXRpb24uYXZnIiwiRGVtb25zdHJhdGlvbi5wY2ExIiwiRGVtb25zdHJhdGlvbi53dC5wY2EiLCJEZW1vbnN0cmF0aW9uLmNmYSIpXQ0KaW4uaW5kdWN0aXZlID0gZmluYWwuYW54aWV0eS5kYXRbLCBjKCAiSW5kdWN0aXZlLmF2ZyIsIkluZHVjdGl2ZS5wY2ExIiwiSW5kdWN0aXZlLnd0LnBjYSIsIkluZHVjdGl2ZS5jZmEiKV0NCmluLmludGVncmF0aXZlID0gZmluYWwuYW54aWV0eS5kYXRbLCBjKCAiSW50ZWdyYXRpdmUuYXZnIiwgIkludGVncmF0aXZlLnBjYTEiLCJJbnRlZ3JhdGl2ZS53dC5wY2EiLCJJbnRlZ3JhdGl2ZS5jZmEiKV0NCmluLmxlY3R1cmVUeXBlID0gZmluYWwuYW54aWV0eS5kYXRbLCBjKCAiTGVjdHVyZVR5cGUuYXZnIiwgIkxlY3R1cmVUeXBlLnBjYTEiLCAiTGVjdHVyZVR5cGUud3QucGNhIiwiTGVjdHVyZVR5cGUuY2ZhIildDQppbi5yZXBldGl0aXZlID0gZmluYWwuYW54aWV0eS5kYXRbLCBjKCAiUmVwZXRpdGl2ZS5hdmciLCAiUmVwZXRpdGl2ZS5wY2ExIiwgIlJlcGV0aXRpdmUud3QucGNhIiwiUmVwZXRpdGl2ZS5jZmEiKV0NCmluLmVuZ2FnZSA9IGZpbmFsLmFueGlldHkuZGF0WywgYyggICJFbmdhZ2UuYXZnIiwgIkVuZ2FnZS5wY2ExIiwgIkVuZ2FnZS53dC5wY2EiLCJFbmdhZ2UuY2ZhIildDQppbi5yZXNvdXJjZSA9IGZpbmFsLmFueGlldHkuZGF0WywgYyggIlJlc291cmNlLmF2ZyIsICJSZXNvdXJjZS5wY2ExIiwgIlJlc291cmNlLnd0LnBjYSIsICJSZXNvdXJjZS5jZmEiKV0NCmBgYA0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTN9DQpwLm1lYSA8LSBwbG90bHkuZnVuKGluLmFueGlldHkubWVhKQ0KcC5tbGEgPC0gcGxvdGx5LmZ1bihpbi5hbnhpZXR5Lm1sYSkNCiMgQXJyYW5nZSBpbiAxeDIgZ3JpZA0Kc3VicGxvdChwLm1lYSwgcC5tbGEsIG5yb3dzID0gMSwgdGl0bGVYID0gVFJVRSwgdGl0bGVZID0gVFJVRSwgbWFyZ2luID0gMC4xKSAlPiUNCiAgbGF5b3V0KA0KICAgIGFubm90YXRpb25zID0gbGlzdCgNCiAgICAgIGxpc3QoeCA9IDAuMDUsIHkgPSAuOTksIHRleHQgPSAiQW54aWV0eS5tZWEiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSksDQogICAgICBsaXN0KHggPSAwLjc1LCB5ID0gMC45OSwgdGV4dCA9ICJBbnhpZXR5Lm1sYSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKQ0KICAgICksDQogICAgc2hvd2xlZ2VuZCA9IEZBTFNFDQogICkNCmBgYA0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTV9DQpwMSA8LSBwbG90bHkuZnVuKGluLmFueGlldHkpDQpwMiA8LSBwbG90bHkuZnVuKGluLmVmZmljYWN5KQ0KcDMgPC0gcGxvdGx5LmZ1bihpbi50ZWNobm9sb2d5KQ0KcDQgPC0gcGxvdGx5LmZ1bihpbi5jb29wb3JhdGl2ZSkNCiMgQXJyYW5nZSBpbiAyeDIgZ3JpZA0Kc3VicGxvdChwMSwgcDIsIHAyLCBwNCwgbnJvd3MgPSAyLCB0aXRsZVggPSBUUlVFLCB0aXRsZVkgPSBUUlVFLCBtYXJnaW4gPSAwLjEpICU+JQ0KICBsYXlvdXQoDQogICAgYW5ub3RhdGlvbnMgPSBsaXN0KA0KICAgICAgbGlzdCh4ID0gMC4wNSwgeSA9IC45OSwgdGV4dCA9ICJBbnhpZXR5IiwgDQogICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCB5cmVmID0gInBhcGVyIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxNCkpLA0KICAgICAgbGlzdCh4ID0gMC43NSwgeSA9IDAuOTksIHRleHQgPSAiU2VsZi1lZmZpY2FjeSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuMDUsIHkgPSAwLjQsIHRleHQgPSAiVGVjaG5vbG9neSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuNzUsIHkgPSAwLjQsIHRleHQgPSAiQ29vcnBvcmF0aXZlIiwgDQogICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCB5cmVmID0gInBhcGVyIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxNCkpDQogICAgKSwNCiAgICBzaG93bGVnZW5kID0gRkFMU0UNCiAgKQ0KYGBgDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NX0NCnAxIDwtIHBsb3RseS5mdW4oaW4uZGVkdWN0aXZlKQ0KcDIgPC0gcGxvdGx5LmZ1bihpbi5kZW1vbnN0cmF0aW9uKQ0KcDMgPC0gcGxvdGx5LmZ1bihpbi5pbmR1Y3RpdmUpDQpwNCA8LSBwbG90bHkuZnVuKGluLmludGVncmF0aXZlKQ0KIyBBcnJhbmdlIGluIDJ4MiBncmlkDQpzdWJwbG90KHAxLCBwMiwgcDIsIHA0LCBucm93cyA9IDIsIHRpdGxlWCA9IFRSVUUsIHRpdGxlWSA9IFRSVUUsIG1hcmdpbiA9IDAuMSkgJT4lDQogIGxheW91dCgNCiAgICBhbm5vdGF0aW9ucyA9IGxpc3QoDQogICAgICBsaXN0KHggPSAwLjA1LCB5ID0gLjk5LCB0ZXh0ID0gIkRlZHVjdGl2ZSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuNzUsIHkgPSAwLjk5LCB0ZXh0ID0gIkRlbW9uc3RyYXRpdmUiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSksDQogICAgICBsaXN0KHggPSAwLjA1LCB5ID0gMC40LCB0ZXh0ID0gIkluZHVjdGl2ZSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuNzUsIHkgPSAwLjQsIHRleHQgPSAiSW50ZXJncmF0aXZlIiwgDQogICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCB5cmVmID0gInBhcGVyIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxNCkpDQogICAgKSwNCiAgICBzaG93bGVnZW5kID0gRkFMU0UNCiAgKQ0KYGBgDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NX0NCnAxIDwtIHBsb3RseS5mdW4oaW4ubGVjdHVyZVR5cGUpDQpwMiA8LSBwbG90bHkuZnVuKGluLnJlcGV0aXRpdmUpDQpwMyA8LSBwbG90bHkuZnVuKGluLmVuZ2FnZSkNCnA0IDwtIHBsb3RseS5mdW4oaW4ucmVzb3VyY2UpDQojIEFycmFuZ2UgaW4gMngyIGdyaWQNCnN1YnBsb3QocDEsIHAyLCBwMiwgcDQsIG5yb3dzID0gMiwgdGl0bGVYID0gVFJVRSwgdGl0bGVZID0gVFJVRSwgbWFyZ2luID0gMC4xKSAlPiUNCiAgbGF5b3V0KA0KICAgIGFubm90YXRpb25zID0gbGlzdCgNCiAgICAgIGxpc3QoeCA9IDAuMDUsIHkgPSAuOTksIHRleHQgPSAiTGVjdHVyZSBUeXBlIiwgDQogICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCB5cmVmID0gInBhcGVyIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxNCkpLA0KICAgICAgbGlzdCh4ID0gMC43NSwgeSA9IDAuOTksIHRleHQgPSAiUmVwZXRhdGl2ZSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuMDUsIHkgPSAwLjQsIHRleHQgPSAiRW5nYWdlbWVudCIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuNzUsIHkgPSAwLjQsIHRleHQgPSAiUmVzb3VyY2UiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSkNCiAgICApLA0KICAgIHNob3dsZWdlbmQgPSBGQUxTRQ0KICApDQpgYGANCg0KVGhlc2UgZGVuc2l0eSBjdXJ2ZXMgaWxsdXN0cmF0ZSB0aGUgZGlzdHJpYnV0aW9ucyBvZiB0aGUgZm91ciBjb21wb3NpdGUgc2NvcmVzICgqKmF2ZywgY2ZhLCBwYzEqKiwgYW5kICoqcGNhLnd0KiopIGZvciBhbGwgc2luZ2xlLWZhY3RvciBpbnN0cnVtZW50cyBpbiB0aGUgc3VydmV5LiBUaGUgKiphdmcqKiBpcyBhIG5haXZlIG1lYXN1cmUsIGRlcml2ZWQgZnJvbSB0aGUgYXJpdGhtZXRpYyBtZWFuIG9mIHRoZSBpdGVtIHNjb3Jlcy4gVGhlICoqY2ZhKiogYW5kICoqcGMxKiogY29tcG9zaXRlcyBhcmUgd2VpZ2h0ZWQgYXZlcmFnZXMsIHdoZXJlIHRoZSB3ZWlnaHRzIChsb2FkaW5ncykgYXJlIGRlcml2ZWQgZnJvbSBkaXN0aW5jdCBsYXRlbnQgdmFyaWFibGUgbW9kZWxzLiBUaGUgKipwY2Eud3QgY29tcG9zaXQqKmUgaXMgYSA8Zm9udCBjb2xvcj0icmVkIj4qKmRvdWJseSB3ZWlnaHRlZCBhdmVyYWdlKio8L2ZvbnQ+LCBiYXNlZCBvbiBib3RoIHRoZSBvcmlnaW5hbCBpdGVtIHNjb3JlcyBhbmQgYWxsIG9mIHRoZSByZXN1bHRpbmcgcHJpbmNpcGFsIGNvbXBvbmVudHMuDQoNCi0gICBUaHJlZSBtb2RlbC1iYXNlZCBjb21wb3NpdGUgc2NvcmVzICgqKmNmYSwgcGMxKiosIGFuZCAqKnBjYS53dCoqKSBhcmUgY2VudGVyZWQgYXQgMCBidXQgZXhoaWJpdCBkaWZmZXJlbnQgYmVoYXZpb3JzOg0KICAgIC0gICAqKnBjMSoqIGhhcyB0aGUgbGFyZ2VzdCB2YXJpYW5jZS4NCiAgICAtICAgKipjZmEqKiBoYXMgdGhlIHNtYWxsZXN0IHZhcmlhbmNlLg0KLSAgICoqYXZnKiogYW5kICoqcGNhLnd0KiogYmVoYXZlIHNpbWlsYXJseSwgZGlmZmVyaW5nIHByaW1hcmlseSBpbiB0aGVpciBsb2NhdGlvbnMuDQoNClRoZSBjb21wb3NpdGUgc2NvcmUgKiphdmcqKiBzZXJ2ZXMgYXMgYSByZWZlcmVuY2UgcG9pbnQsIGFuYWxvZ291cyB0byBhbiBlbXBpcmljYWwgZGlzdHJpYnV0aW9uLCBhcyBpdCB1c2VzIGFsbCBpdGVtIHNjb3JlcyBkaXJlY3RseS4gSW4gY29udHJhc3QsICoqcGNhLnd0KiogdXNlcyBhIGRvdWJseSB3ZWlnaHRlZCBhdmVyYWdlIG9mIGFsbCBpdGVtIHNjb3JlcyB3aXRob3V0IGltcG9zaW5nIGNvbXBsZXggZGlzdHJpYnV0aW9uYWwgYXNzdW1wdGlvbnMuIFRoaXMgZGVtb25zdHJhdGVzIHRoYXQgKipwY2Eud3QqKiBpcyBhIHJlbGlhYmxlIGFuZCByb2J1c3QgY29tcG9zaXRlIHNjb3JlLiBGb3IgdGhlIHJlbWFpbmRlciBvZiB0aGlzIHJlcG9ydCwgdGhlICoqcGNhLnd0Kiogc2NvcmUgd2lsbCBiZSB1c2VkLCB3aXRoICoqY2ZhKiogb2NjYXNpb25hbGx5IGVtcGxveWVkIGZvciBpbGx1c3RyYXRpdmUgcHVycG9zZXMgZm9yIHNvbWUgc3BlY2lhbCBjYXNlcy4NCg0KIyMgRGlzdHJpYnV0aW9uIG9mIERlbW9ncmFwaGljcw0KDQpUaGUgZGlzdHJpYnV0aW9uIG9mIGRlbW9ncmFwaGljIGZhY3RvcnMgYXJlIHJlcG9ydGVkIGluIHRoZSBmb2xsb3dpbmcgZmlndXJlcy4NCg0KYGBge3J9DQojIEVuaGFuY2VkIGhvdmVyIGluZm9ybWF0aW9uDQpEZW1vZ3JhcGhpYy5iYXIgPC1mdW5jdGlvbihpbi5jYXQsIHZhcm5hbWUpew0KICBmcmVxLnRibCA8LSB0YWJsZShpbi5jYXQpDQogIGRmIDwtIGRhdGEuZnJhbWUoDQogICAgICBjYXRlZ29yeSA8LSBuYW1lcyhmcmVxLnRibCksDQogICAgICB2YWx1ZXMgPC0gYXMudmVjdG9yKGZyZXEudGJsKQ0KICApDQogICMgSGlnaC1jb250cmFzdCBjb2xvcnMgKG1hbnVhbGx5IGRlZmluZWQpDQogIGFjY2Vzc2libGVfY29sb3JzIDwtIGMoDQogICcjRDU1RTAwJywgICMgVmVybWlsbGlvbg0KICAnIzAwNzJCMicsICAjIEJsdWUNCiAgJyNGMEU0NDInLCAgIyBZZWxsb3cNCiAgJyMwMDlFNzMnLCAgIyBHcmVlbg0KICAnIzU2QjRFOScsICAjIFNreSBCbHVlDQogICcjRTY5RjAwJywgICMgT3JhbmdlDQogICcjQ0M3OUE3JyAgICMgUGluaw0KICApDQogIGZpZyA8LSBwbG90X2x5KGRmLCB4ID0gfmNhdGVnb3J5LCB5ID0gfnZhbHVlcywgdHlwZSA9ICdiYXInLA0KICAgICAgICAgICAgICAgIGhvdmVyaW5mbyA9ICd0ZXh0JywNCiAgICAgICAgICAgICAgIHRleHQgPSB+cGFzdGUoJ0NhdGVnb3J5OicsIGNhdGVnb3J5LCAnPGJyPlZhbHVlOicsIHZhbHVlcywgJzxicj5QZXJjZW50YWdlOicsIHJvdW5kKHZhbHVlcy9zdW0odmFsdWVzKSoxMDAsIDEpLCAnJScpLA0KICAgICAgICAgICAgICAgI3RleHQgPSB+cGFzdGUoIlZhbHVlOiIsIHZhbHVlcyksIA0KICAgICAgICAgICAgICAgdGV4dHBvc2l0aW9uID0gJ2F1dG8nLA0KICAgICAgICAgICAgICAgbWFya2VyID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgY29sb3IgPSBhY2Nlc3NpYmxlX2NvbG9yc1sxOm5yb3coZGYpXSwNCiAgICAgICAgICAgICAgICAgbGluZSA9IGxpc3QoY29sb3IgPSAnYmxhY2snLCB3aWR0aCA9IDIpDQogICAgICAgICAgICAgICApLA0KICAgICAgICAgICAgICAgdGV4dGZvbnQgPSBsaXN0KGNvbG9yID0gJ3doaXRlJywgc2l6ZSA9IDEyKSkgJT4lDQogICBsYXlvdXQoDQogICAjIHRpdGxlID0gbGlzdCh0ZXh0ID0gdmFybmFtZSwgDQogICAgICAgICAgICAgICAgIyBmb250ID0gbGlzdChzaXplID0gMTgsIGNvbG9yID0gJ2JsYWNrJykpLA0KICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICJDYXRlZ29yaWVzIiwgDQogICAgICAgICAgICAgICAgIHRpY2tmb250ID0gbGlzdChjb2xvciA9ICdibGFjaycpKSwNCiAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiVmFsdWVzIiwgDQogICAgICAgICAgICAgICAgIGdyaWRjb2xvciA9ICdsaWdodGdyYXknLA0KICAgICAgICAgICAgICAgICB0aWNrZm9udCA9IGxpc3QoY29sb3IgPSAnYmxhY2snKSksDQogICAgcGxvdF9iZ2NvbG9yID0gJ3doaXRlJywNCiAgICBwYXBlcl9iZ2NvbG9yID0gJ3doaXRlJywNCiAgICBzaG93bGVnZW5kID0gRkFMU0UsDQogICAgbWFyZ2luID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgIHQgPSAxMDAsICAjIEFkanVzdCB0aGlzIHZhbHVlIHRvIGluY3JlYXNlIG9yIGRlY3JlYXNlIHRoZSB0b3AgbWFyZ2luDQogICAgICAgICAgICAgICAgICBiID0gNTAsDQogICAgICAgICAgICAgICAgICBsID0gNTAsDQogICAgICAgICAgICAgICAgICByID0gNTApDQogICkNCmZpZw0KfQ0KYGBgDQoNCmBgYHtyfQ0KaW4uY2F0LnNleCA8LSAgZmluYWwuYW54aWV0eS5kYXQkc2V4DQppbi5jYXQucmFjZSA8LSAgZmluYWwuYW54aWV0eS5kYXQkcmFjZQ0KaW4uY2F0LmNsYXNzIDwtICBmaW5hbC5hbnhpZXR5LmRhdCRjbGFzcw0KaW4uY2F0Lm1ham9yIDwtICBmaW5hbC5hbnhpZXR5LmRhdCRtYWpvcg0KaW4uY2F0Lm1hdGgubGV2ZWwgPC0gIGZpbmFsLmFueGlldHkuZGF0JG1hdGgubGV2ZWwNCmluLmNhdC5tb2RhbGl0eSA8LSAgZmluYWwuYW54aWV0eS5kYXQkbW9kYWxpdHkNCiMjDQpnLnNleCA8LSBEZW1vZ3JhcGhpYy5iYXIoaW4uY2F0LnNleCwgIkdlbmRlciBEaXN0cmlidXRpb24iKQ0KZy5yYWNlIDwtIERlbW9ncmFwaGljLmJhcihpbi5jYXQucmFjZSwgIlJhY2lhbCBEaXN0cmlidXRpb24iKQ0KZy5jbGFzcyA8LSBEZW1vZ3JhcGhpYy5iYXIoaW4uY2F0LmNsYXNzLCAiQ2xhc3MgRGlzdHJpYnV0aW9uIikNCmcubWFqb3IgPC0gRGVtb2dyYXBoaWMuYmFyKGluLmNhdC5tYWpvciwgIk1ham9yIERpc3RyaWJ1dGlvbiIpDQpnLm1hdGgubGV2ZWwgPC0gRGVtb2dyYXBoaWMuYmFyKGluLmNhdC5tYXRoLmxldmVsLCAiTWF0aCBDb3Vyc2UgTGV2ZWwiKQ0KZy5tb2RhbGl0eSA8LSBEZW1vZ3JhcGhpYy5iYXIoaW4uY2F0Lm1vZGFsaXR5LCAiTGVhcm5pbmcgTW9kYWxpdHkiKQ0KYGBgDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9OH0NCiMgQXJyYW5nZSBpbiAyeDIgZ3JpZA0Kc3VicGxvdChnLnNleCwgZy5yYWNlLCBnLmNsYXNzLCBnLm1ham9yLCBucm93cyA9IDIsIHRpdGxlWCA9IEZBTFNFLCB0aXRsZVkgPSBUUlVFLCBtYXJnaW4gPSAwLjEpICU+JQ0KICBsYXlvdXQoDQogICAgYW5ub3RhdGlvbnMgPSBsaXN0KA0KICAgICAgbGlzdCh4ID0gMC4zNSwgeSA9IC45OSwgdGV4dCA9ICJHZW5kZXIiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSksDQogICAgICBsaXN0KHggPSAwLjc1LCB5ID0gMC45OSwgdGV4dCA9ICJSYWNlIiwgDQogICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCB5cmVmID0gInBhcGVyIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxNCkpLA0KICAgICAgbGlzdCh4ID0gMC4zNSwgeSA9IDAuNCwgdGV4dCA9ICJDbGFzcyBMZXZlbCIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuNzUsIHkgPSAwLjQsIHRleHQgPSAiTWFqb3IiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSkNCiAgICApLA0KICAgIHNob3dsZWdlbmQgPSBGQUxTRQ0KICApDQpgYGANCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD00fQ0KIyBBcnJhbmdlIGluIDJ4MiBncmlkDQpzdWJwbG90KGcubWF0aC5sZXZlbCwgZy5tb2RhbGl0eSwgbnJvd3MgPSAxLCB0aXRsZVggPSBGQUxTRSwgdGl0bGVZID0gVFJVRSwgbWFyZ2luID0gMC4xKSAlPiUNCiAgbGF5b3V0KA0KICAgIGFubm90YXRpb25zID0gbGlzdCgNCiAgICAgIGxpc3QoeCA9IDAuMzUsIHkgPSAuOTksIHRleHQgPSAiTWF0aCBDb3Vyc2UgTGV2ZWwiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSksDQogICAgICBsaXN0KHggPSAwLjc1LCB5ID0gMC45OSwgdGV4dCA9ICJMZWFybmluZyBNb2RhbGl0eSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKQ0KICAgICksDQogICAgc2hvd2xlZ2VuZCA9IEZBTFNFDQogICkNCmBgYA0KDQpPbmx5IG9uZSBjYXRlZ29yeSBpbiB2YXJpYWJsZSAqKmNsYXNzKiogaXMgbGVzcyB0aGFuIDMlIHdpdGggMjEgb2JzZXJ2YXRpb25zLiBPdGhlciB2YXJpYWJsZXMgZG9uJ3QgaGF2ZSBpc3N1ZXMgb24gc3BhcnNlIGNhdGVnb3JpZXMuDQoNCiMjIFJlbGF0aW9uc2hpcCBCZXR3ZWVuIE1hdGggQW54aWV0eSBhbmQgRGVtb2dyYXBoaWMgRmFjdG9ycw0KDQpBIHN0dWRlbnQncyBkZW1vZ3JhcGhpYyBwcm9maWxlIGRvZXNuJ3QgZGV0ZXJtaW5lIHRoZWlyIG1hdGggYW54aWV0eSwgYnV0IGl0IHNpZ25pZmljYW50bHkgaW5mbHVlbmNlcyB3aGljaCB0eXBlIG9mIGFueGlldHkgdGhleSBhcmUgbW9zdCB2dWxuZXJhYmxlIHRvIGFuZCB3aHkuIFRoZSBuZXh0IHN1YnNlY3Rpb25zIHByZXNlbnQgdmlzdWFsIGV4cGxvcmF0aW9ucyBvZiB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gZGVtb2dyYXBoaWMgZmFjdG9ycyBhbmQgdGhlIHR3byBkaW1lbnNpb25zIG9mIG1hdGhlbWF0aWNhbCBhbnhpZXR5Lg0KDQojIyMgTWF0aGVtYXRpY2FsIEV2YWx1YXRpb24gQW54aWV0eQ0KDQpUaGlzIGlzIHRoZSBhbnhpZXR5IGEgc3R1ZGVudCBmZWVscyB3aGVuIHRoZWlyIG1hdGhlbWF0aWNhbCBhYmlsaXR5IGlzIGJlaW5nIGZvcm1hbGx5IG9yIGluZm9ybWFsbHkgYXNzZXNzZWQuIFRoZSBwcmltYXJ5IGZlYXIgaXMgbm90IG9mIHRoZSBtYXRoIGl0c2VsZiwgYnV0IG9mIHRoZSBuZWdhdGl2ZSBjb25zZXF1ZW5jZXMgb2YgcGVyZm9ybWluZyBwb29ybHkuIEl0J3MgcGVyZm9ybWFuY2Utb3JpZW50ZWQuIFRoZSBzdHJlc3MgY29tZXMgZnJvbSB0aGUgc2l0dWF0aW9uIG9mIGJlaW5nIGV2YWx1YXRlZCwgbm90IG5lY2Vzc2FyaWx5IGZyb20gdGhlIGNvbnRlbnQuDQoNCmBgYHtyfQ0KIyMgcGxvdGx5IGZvciBhbnhpZXR5IHZzIGdlbmRlciBhbmQgb3RoZXIgY2F0ZWdvcmljYWwgZGVtb2dyYXBoaWMgZmFjdG9yDQpnZW5kZXIucGxvdGx5IDwtIGZ1bmN0aW9uKGluLnZhcjEsIGluLnZhcjIpew0KICAgICAgZ2VuZGVyLmFueGlldHkgPC0gcGxvdF9seShmaW5hbC5hbnhpZXR5LmRhdCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gfnNleCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gfkFueGlldHkubWVhLnd0LnBjYSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGFzLmZvcm11bGEocGFzdGUwKCJ+Iixpbi52YXIxKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gImJveCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3hwb2ludHMgPSAibm8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaml0dGVyID0gMC4zLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRwb3MgPSAwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG92ZXJpbmZvID0gInkgKyB4ICsgbmFtZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3ZlcnRleHQgPSB+cGFzdGUoIkdyb3VwOiIsIGluLnZhcjEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPkZhY3RvcjoiLCBzZXgsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPlNjb3JlOiIsIHJvdW5kKEFueGlldHkubWVhLnd0LnBjYSwgMikpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFya2VyID0gbGlzdChzaXplID0gNSwgb3BhY2l0eSA9IDAuNykpICU+JQ0KICAgIGxheW91dCh0aXRsZSA9IHBhc3RlKCJNYXRoIEV2YWx1YXRpb24gQW54aWV0eSAod3QuUENBKTogR2VuZGVyIHZzICIsIGluLnZhcjIsIiIpLA0KICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIiIpLA0KICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIkV2YWx1YXRpb24gQW54aWV0eSBTY29yZSIpLA0KICAgICAgICAgYm94bW9kZSA9ICJncm91cCIsDQogICAgICAgICBob3ZlcmxhYmVsID0gbGlzdChiZ2NvbG9yID0gIndoaXRlIiwgZm9udCA9IGxpc3Qoc2l6ZSA9IDEyKSksDQogICAgICAgICBtYXJnaW4gPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgdCA9IDEwMCwgICMgQWRqdXN0IHRoaXMgdmFsdWUgdG8gaW5jcmVhc2Ugb3IgZGVjcmVhc2UgdGhlIHRvcCBtYXJnaW4NCiAgICAgICAgICAgICAgICAgIGIgPSA1MCwNCiAgICAgICAgICAgICAgICAgIGwgPSA1MCwNCiAgICAgICAgICAgICAgICAgIHIgPSA1MCkNCiAgICAgICAgICkNCg0KIGdlbmRlci5hbnhpZXR5IA0KfQ0KDQpgYGANCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQ0KZ2VuZGVyLm1hdGgubGV2ZWwgPSBnZW5kZXIucGxvdGx5KCJtYXRoLmxldmVsIiwgIk1hdGggQ291cnNlIExldmVsIikNCmdlbmRlci5tYXRoLmxldmVsDQpgYGANCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQ0KZ2VuZGVyLnJhY2UgPSBnZW5kZXIucGxvdGx5KCJyYWNlIiwgIlJhY2UiKQ0KZ2VuZGVyLnJhY2UNCmBgYA0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9DQpnZW5kZXIuY2xhc3MgPSBnZW5kZXIucGxvdGx5KCJjbGFzcyIsICJDbGFzcyIpDQpnZW5kZXIuY2xhc3MNCmBgYA0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9DQpnZW5kZXIubWFqb3IgPSBnZW5kZXIucGxvdGx5KCJtYWpvciIsICJNYWpvciIpDQpnZW5kZXIubWFqb3INCmBgYA0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9DQpnZW5kZXIubW9kYWxpdHkgPSBnZW5kZXIucGxvdGx5KCJtb2RhbGl0eSIsICJNb2RhbGl0eSIpDQpnZW5kZXIubW9kYWxpdHkNCmBgYA0KDQpTb21lIG9mIHRoZSBwYXR0ZXJucyBvYnNlcnZlZCBpbiB0aGlzIHN0dWR5IGFyZSBjb25zaXN0ZW50IHdpdGggdGhlIGV4aXN0aW5nIGxpdGVyYXR1cmUuDQoNCi0gICBGZW1hbGUgc3R1ZGVudHMgaGF2ZSByZWxhdGl2ZWx5IGhpZ2hlciBldmFsdWF0aW9uIGFueGlldHkgbGV2ZWwgdGhhbiBtYWxlIHN0dWRlbnRzLg0KLSAgIFRoZSBkaXNjcmVwYW5jeSBvZiBldmFsdWF0aW9uIGFueGlldHkgbGV2ZWwgYWNyb3NzIGV0aG5pYyBncm91cHMgYWxzbyBjb25zaXN0ZW50IHdpdGggd2hhdCByZXBvcnRlZCBpbiB0aGUgZXhpc3RpbmcgbGl0ZXJhdHVyZS4NCg0KIyMjIE1hdGhlbWF0aWNhbCBMZWFybmluZyBBbnhpZXR5DQoNCk1hdGhlbWF0aWNhbCBsZWFybmluZyBhbnhpZXR5IHN0ZW1zIGRpcmVjdGx5IGZyb20gdGhlIHN1YmplY3QgbWF0dGVyLCB3aGVyZSB0aGUgcHJpbWFyeSBzb3VyY2Ugb2YgZGlzdHJlc3MgaXMgdGhlIGFjdCBvZiBlbmdhZ2luZyB3aXRoIG1hdGhlbWF0aWNhbCBjb25jZXB0cy4gVGhpcyBlbmdhZ2VtZW50IHRyaWdnZXJzIGFuIGludGVybmFsIHN0YXRlIG9mIGNvbmZ1c2lvbiwgZnJ1c3RyYXRpb24sIGFuZCBjb2duaXRpdmUgb3ZlcmxvYWQuDQoNClRoZSBuZXh0IGZldyBmaWd1cmVzIGV4YW1pbmUgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIG1hdGhlbWF0aWNhbCBsZWFybmluZyBhbnhpZXR5IGFuZCBkZW1vZ3JhcGhpYyBmYWN0b3JzLCB1c2luZyB0aGUgc2FtZSB2aXN1YWwgYXBwcm9hY2ggYXMgd2UgZGlkIGZvciBtYXRoZW1hdGljYWwgZXZhbHVhdGlvbiBhbnhpZXR5Lg0KDQpgYGB7cn0NCiMjIHBsb3RseSBmb3IgYW54aWV0eSB2cyBnZW5kZXIgYW5kIG90aGVyIGNhdGVnb3JpY2FsIGRlbW9ncmFwaGljIGZhY3Rvcg0KZ2VuZGVyLnBsb3RseSA8LSBmdW5jdGlvbihpbi52YXIxLCBpbi52YXIyKXsNCiAgICAgIGdlbmRlci5hbnhpZXR5IDwtIHBsb3RfbHkoZmluYWwuYW54aWV0eS5kYXQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9IH5zZXgsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IH5BbnhpZXR5Lm1sYS53dC5wY2EsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBhcy5mb3JtdWxhKHBhc3RlMCgifiIsaW4udmFyMSkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9ICJib3giLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm94cG9pbnRzID0gIm5vIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlciA9IDAuMywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50cG9zID0gMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvdmVyaW5mbyA9ICJ5ICsgeCArIG5hbWUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG92ZXJ0ZXh0ID0gfnBhc3RlKCJHcm91cDoiLCBpbi52YXIxLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5GYWN0b3I6Iiwgc2V4LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5TY29yZToiLCByb3VuZChBbnhpZXR5Lm1sYS53dC5wY2EsIDIpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmtlciA9IGxpc3Qoc2l6ZSA9IDUsIG9wYWNpdHkgPSAwLjcpKSAlPiUNCiAgICBsYXlvdXQodGl0bGUgPSBwYXN0ZSgiTWF0aCBMZWFybmluZyBBbnhpZXR5ICh3dC5QQ0EpOiBHZW5kZXIgdnMgIiwgaW4udmFyMiwiIiksDQogICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiIiksDQogICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiTGVhcm5pbmcgQW54aWV0eSBTY29yZSIpLA0KICAgICAgICAgYm94bW9kZSA9ICJncm91cCIsDQogICAgICAgICBob3ZlcmxhYmVsID0gbGlzdChiZ2NvbG9yID0gIndoaXRlIiwgZm9udCA9IGxpc3Qoc2l6ZSA9IDEyKSksDQogICAgICAgICBtYXJnaW4gPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgdCA9IDEwMCwgICMgQWRqdXN0IHRoaXMgdmFsdWUgdG8gaW5jcmVhc2Ugb3IgZGVjcmVhc2UgdGhlIHRvcCBtYXJnaW4NCiAgICAgICAgICAgICAgICAgIGIgPSA1MCwNCiAgICAgICAgICAgICAgICAgIGwgPSA1MCwNCiAgICAgICAgICAgICAgICAgIHIgPSA1MCkNCiAgICAgICAgICkNCg0KIGdlbmRlci5hbnhpZXR5IA0KfQ0KDQpgYGANCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQ0KZ2VuZGVyLm1hdGgubGV2ZWwubWxhID0gZ2VuZGVyLnBsb3RseSgibWF0aC5sZXZlbCIsICJNYXRoIENvdXJzZSBMZXZlbCIpDQpnZW5kZXIubWF0aC5sZXZlbC5tbGENCmBgYA0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9DQpnZW5kZXIucmFjZS5tbGEgPSBnZW5kZXIucGxvdGx5KCJyYWNlIiwgIlJhY2UiKQ0KZ2VuZGVyLnJhY2UubWxhDQpgYGANCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQ0KZ2VuZGVyLmNsYXNzLm1sYSA9IGdlbmRlci5wbG90bHkoImNsYXNzIiwgIkNsYXNzIikNCmdlbmRlci5jbGFzcy5tbGENCmBgYA0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9DQpnZW5kZXIubWFqb3IubWxhID0gZ2VuZGVyLnBsb3RseSgibWFqb3IiLCAiTWFqb3IiKQ0KZ2VuZGVyLm1ham9yLm1sYQ0KYGBgDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NH0NCmdlbmRlci5tb2RhbGl0eS5tbGEgPSBnZW5kZXIucGxvdGx5KCJtb2RhbGl0eSIsICJNb2RhbGl0eSIpDQpnZW5kZXIubW9kYWxpdHkubWxhDQpgYGANCg0KIyMgVGhlIEdlbmRlciBHYXAgaW4gRXZhbHVhdGlvbiBhbmQgTGVhcm5pbmcgQW54aWV0eQ0KDQpJdCB0dXJucyBvdXQgdGhhdCwgY29tcGFyaW5nIHRvIG1hdGggbGVhcm5pbmcgYW54aWV0eSwgZXZhbHVhdGlvbiBhbnhpZXR5IG1hbmlmZXN0cyB0aGUgZ2VuZGVyIGdhcC4gVGhpcyBvYnNlcnZhdGlvbiBpcyBzdXBwb3J0ZWQgYnkgYWNhZGVtaWMgcmVzZWFyY2guIFRoZSBrZXkgaW5zaWdodCBpcyB0aGF0IHRoZSBnZW5kZXIgZ2FwIGluIG1hdGggcGVyZm9ybWFuY2UgaXMgbW9yZSBzdHJvbmdseSBsaW5rZWQgdG8gdGhlIGFueGlldHkgZ2VuZXJhdGVkIGJ5IHRoZSB0ZXN0aW5nIHNpdHVhdGlvbiB0aGFuIGJ5IGFueGlldHkgdG93YXJkIHRoZSBzdWJqZWN0IG1hdHRlciBpdHNlbGYgKGxlYWRpbmcgcG90ZW50aWFsIGxlYXJuaW5nIGFueGlldHkpLg0KDQpBIHJvYnVzdCBib2R5IG9mIGV2aWRlbmNlLCBmcm9tIGZvdW5kYXRpb25hbCBtZXRhLWFuYWx5c2VzIChIZW1icmVlLCAxOTkwKSB0byBjb250ZW1wb3Jhcnkgc3R1ZGllcyAoRGV2aW5lIGV0IGFsLiwgMjAxMjsgR29ldHogZXQgYWwuLCAyMDEzKSwgZXN0YWJsaXNoZXMgdGhhdCBmZW1hbGUgc3R1ZGVudHMgZXhwZXJpZW5jZSBkaXNwcm9wb3J0aW9uYXRlbHkgaGlnaCBsZXZlbHMgb2YgbWF0aCB0ZXN0IGFueGlldHktLS1hIGZhY3RvciBtb3JlIHByZWRpY3RpdmUgb2YgYWNhZGVtaWMgb3V0Y29tZXMgdGhhbiBsZWFybmluZyBhbnhpZXR5LiBUaGlzIGZpbmRpbmcgaWxsdW1pbmF0ZXMgdGhlIHdvcmsgb2YgRWxzZS1RdWVzdCBldCBhbC4gKDIwMTApLCBkZW1vbnN0cmF0aW5nIHRoYXQgdGhlIGdlbmRlciBnYXAgaW4gbWF0aCBwZXJmb3JtYW5jZSBpcyBwcm9mb3VuZGx5IHNoYXBlZCBieSBhbnhpZXR5IGluIGV2YWx1YXRpdmUgZW52aXJvbm1lbnRzLiBUaGVyZWZvcmUsIGFkZHJlc3NpbmcgdGhlIHNwZWNpZmljIHByZXNzdXJlcyBvZiB0ZXN0aW5nIHNpdHVhdGlvbnMgaXMgZXNzZW50aWFsIGZvciBjbG9zaW5nIHRoaXMgZ2FwLg0KDQpUaGUgZm9sbG93aW5nIGZpZ3VyZSBpbGx1c3RyYXRlcyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gZ2VuZGVyIGFuZCB0aGUgdHdvIHR5cGVzIG9mIG1hdGggYW54aWV0eTogbGVhcm5pbmcgYW54aWV0eSBhbmQgZXZhbHVhdGlvbiBhbnhpZXR5Lg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTZ9DQptZWEwIDwtIGZpbmFsLmFueGlldHkuZGF0WywgYygic2V4IiwgIkFueGlldHkubWVhLnd0LnBjYSIpXQ0KbWxhMCA8LSBmaW5hbC5hbnhpZXR5LmRhdFssIGMoInNleCIsICJBbnhpZXR5Lm1sYS53dC5wY2EiKV0NCm5hbWVzKG1lYTApID0gYygic2V4IiwgImFueGlldHkuc2NvcmUiKQ0KbmFtZXMobWxhMCkgPSBjKCJzZXgiLCAiYW54aWV0eS5zY29yZSIpDQptZWEubWxhIDwtIHJiaW5kKG1lYTAsIG1sYTApDQphbnhpZXR5LnR5cGUgPC0gYyhyZXAoIm1lYSIsIGRpbShtZWEwKVsxXSksIHJlcCgibWxhIiwgZGltKG1lYTApWzFdKSkNCm1lYS5tbGEkYW54aWV0eS50eXBlIDwtIGFueGlldHkudHlwZQ0KIyMjIw0KZGYgPSBuYS5vbWl0KG1lYS5tbGEpDQojIENyZWF0ZSBtb3JlIGNvbXBsZXggZ3JvdXBlZCBib3hwbG90IHdpdGggc3RhdGlzdGljYWwgYW5ub3RhdGlvbnMNCiMgQ3VzdG9tIGhvdmVyIGluZm9ybWF0aW9uDQpmaWcgPC0gcGxvdF9seShkZiwgDQogICAgICAgICAgICAgICB4ID0gfmFueGlldHkudHlwZSwgDQogICAgICAgICAgICAgICB5ID0gfmFueGlldHkuc2NvcmUsIA0KICAgICAgICAgICAgICAgY29sb3IgPSB+c2V4LA0KICAgICAgICAgICAgICAgdHlwZSA9ICJib3giLA0KICAgICAgICAgICAgICAgaG92ZXJpbmZvID0gInkreCtuYW1lIiwNCiAgICAgICAgICAgICAgIGhvdmVydGVtcGxhdGUgPSBwYXN0ZSgNCiAgICAgICAgICAgICAgICAgIkdlbmRlcjogJXt4fTxicj4iLA0KICAgICAgICAgICAgICAgICAiQW54aWV0eSBUeXBlOiAle2Z1bGxEYXRhLm5hbWV9PGJyPiIsDQogICAgICAgICAgICAgICAgICJBbnhpZXR5IFNjb3JlOiAle3k6LjJmfTxicj4iLA0KICAgICAgICAgICAgICAgICAiPGV4dHJhPjwvZXh0cmE+Ig0KICAgICAgICAgICAgICAgKSkgJT4lDQogIGxheW91dCgNCiAgICB0aXRsZSA9ICJHZW5kZXIgRGlzcGFyaXRpZXMgaW4gTWF0aCBFdmFsdWF0aW9uIGFuZCBMZWFybmluZyBBbnhpZXR5IiwNCiAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiIiksDQogICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIkFueGlldHkgU2NvcmUiKSwNCiAgICBib3htb2RlID0gImdyb3VwIiwNCiAgICBob3ZlcmxhYmVsID0gbGlzdChiZ2NvbG9yID0gIndoaXRlIiwgZm9udCA9IGxpc3Qoc2l6ZSA9IDEyKSksDQogICAgbWFyZ2luID0gbGlzdCggdCA9IDEwMCwgICMgQWRqdXN0IHRoaXMgdmFsdWUgdG8gaW5jcmVhc2Ugb3IgZGVjcmVhc2UgdGhlIHRvcCBtYXJnaW4NCiAgICAgICAgICAgICAgICAgIGIgPSA1MCwNCiAgICAgICAgICAgICAgICAgIGwgPSA1MCwNCiAgICAgICAgICAgICAgICAgIHIgPSA1MCkNCiAgKQ0KDQpmaWcNCg0KYGBgDQoNCk91ciByZXN1bHRzIGFyZSBhbHNvIGNvbnNpc3RlbnQgd2l0aCBleGlzdGluZyByZXN1bHRzIGluIGxpdGVyYXR1cmUuDQoNCiMgU3R1ZGVudCBQZXJjZWl2ZWQgVGVhY2hpbmcgU3RyYXRlZ2llcywgTWF0aCBBbnhpZXR5LCBhbmQgU2VsZi1lZmZpY2ljYXkNCg0KVGhlIGZvbGxvd2luZyBoZWF0bWFwIGlsbHVzdHJhdGVzIHRoZSBwYWlyd2lzZSBjb3JyZWxhdGlvbnMgYmV0d2VlbiBhbnhpZXR5IGxldmVscywgc3R1ZGVudC1wZXJjZWl2ZWQgdGVhY2hpbmcgc3RyYXRlZ2llcywgYW5kIG90aGVyIGFzc29jaWF0ZWQgY29nbml0aXZlIGZhY3RvcnMuIEEgbmVnYXRpdmUgY29ycmVsYXRpb24gYmV0d2VlbiBhbnhpZXR5IGFuZCBhbm90aGVyIGNvbXBvc2l0ZSBzY29yZSAoc2hvd24gaW4gYmx1ZSkgaW5kaWNhdGVzIHRoYXQgYW54aWV0eSBkZWNyZWFzZXMgYXMgdGhhdCBjb21wb3NpdGUgc2NvcmUgaW5jcmVhc2VzLg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTZ9DQoNCnZhci5uYW1lIDwtYyggIkFueGlldHkubWVhLnd0LnBjYSIsICJBbnhpZXR5Lm1sYS53dC5wY2EiLCAiU2VsZkVmZmljYWN5Lnd0LnBjYSIsICJUZWNobm9sb2d5Lnd0LnBjYSIsDQogICAgICAgICAgICAgICJDb29wb3JhdGl2ZS53dC5wY2EiLCAiRGVkdWN0aXZlLnd0LnBjYSIsICJEZW1vbnN0cmF0aW9uLnd0LnBjYSIsDQogICAgICAgICAgICAgICJJbmR1Y3RpdmUud3QucGNhIiwgIkludGVncmF0aXZlLnd0LnBjYSIsICJMZWN0dXJlVHlwZS53dC5wY2EiLA0KICAgICAgICAgICAgICAiUmVwZXRpdGl2ZS53dC5wY2EiLCAiRW5nYWdlLnd0LnBjYSIsICJSZXNvdXJjZS53dC5wY2EiKQ0KYWxsLmNvbXBvc2l0ZS5zY29yZXMgPC0gZmluYWwuYW54aWV0eS5kYXRbLCB2YXIubmFtZV0NCm5hbWVzKGFsbC5jb21wb3NpdGUuc2NvcmVzKSA8LSBjKCAiQW54aWV0eS5tZWEiLCAiQW54aWV0eS5tbGEiLCAiU2VsZkVmZmljYWN5IiwgIlRlY2hub2xvZ3kiLA0KICAgICAgICAgICAgICAiQ29vcG9yYXRpdmUiLCAiRGVkdWN0aXZlLiIsICJEZW1vbnN0cmF0aW9uIiwNCiAgICAgICAgICAgICAgIkluZHVjdGl2ZSIsICJJbnRlZ3JhdGl2ZSIsICJMZWN0dXJlVHlwZSIsDQogICAgICAgICAgICAgICJSZXBldGl0aXZlIiwgIkVuZ2FnZSIsICJSZXNvdXJjZS4iKQ0KDQojIENhbGN1bGF0ZSBjb3JyZWxhdGlvbiBtYXRyaXgNCmNvcl9tYXRyaXggPC0gY29yKGFsbC5jb21wb3NpdGUuc2NvcmVzLCB1c2UgPSAiY29tcGxldGUub2JzIikNCg0KIyBDb252ZXJ0IHRvIGxvbmcgZm9ybWF0IHVzaW5nIG1lbHQNCmNvcl9sb25nIDwtIG1lbHQoY29yX21hdHJpeCkNCm5hbWVzKGNvcl9sb25nKSA8LSBjKCJ4IiwgInkiLCAiciIpDQoNCiMgUmVtb3ZlIHNlbGYtY29ycmVsYXRpb25zIGFuZCB1cHBlciB0cmlhbmdsZSBpZiBkZXNpcmVkDQpjb3JfbG9uZyA8LSBjb3JfbG9uZ1tjb3JfbG9uZyR4ICE9IGNvcl9sb25nJHksIF0NCg0KIyBDcmVhdGUgaW50ZXJhY3RpdmUgaGVhdG1hcA0KcGxvdF9seShjb3JfbG9uZywgeCA9IH54LCB5ID0gfnksIHogPSB+ciwgdHlwZSA9ICJoZWF0bWFwIiwNCiAgICAgICAgY29sb3JzY2FsZSA9ICJSZEJ1Iiwgem1pbiA9IC0xLCB6bWF4ID0gMSwNCiAgICAgICAgaG92ZXJpbmZvID0gInRleHQiLA0KICAgICAgICB0ZXh0ID0gfnBhc3RlKCJYOiIsIHgsICI8YnI+WToiLCB5LCAiPGJyPnIgPSIsIHJvdW5kKHIsIDMpKSkgJT4lDQogIGxheW91dCh0aXRsZSA9ICJDb3JyZWxhdGlvbiBNYXRyaXgiLA0KICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIiIpLA0KICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIiIpLA0KICAgICAgICAgbWFyZ2luID0gbGlzdChsID0gMTAwLCByID0gNTAsIGIgPSAxMDAsIHQgPSA1MCkpDQpgYGANCg0KVGhlIGZpZ3VyZSBhYm92ZSBzaG93cyB0aGF0IGFsbCBwZXJjZWl2ZWQgdGVhY2hpbmcgc3RyYXRlZ2llcyBhcmUgbmVnYXRpdmVseSBjb3JyZWxhdGVkIHdpdGggYm90aCB0eXBlcyBvZiBhbnhpZXR5LiBJbiBhZGRpdGlvbiwgc3R1ZGVudHMgd2l0aCBoaWdoIGxldmVscyBvZiBzZWxmLWVmZmljYWN5IHRlbmQgdG8gaGF2ZSBsb3cgbGV2ZWxzIG9mIG1hdGggYW54aWV0eS4gRnVydGhlcm1vcmUsIHRoZSBjb21wb3NpdGUgc2NvcmUgZm9yIHRlY2hub2xvZ3kgdXNlIGlzIG5lZ2F0aXZlbHkgY29ycmVsYXRlZCB3aXRoIGJvdGggbGVhcm5pbmcgYW5kIGV2YWx1YXRpb24gYW54aWV0eSwgaW1wbHlpbmcgdGhhdCB0ZWNobm9sb2d5IGNhbiBoZWxwIHJlZHVjZSBtYXRoIGFueGlldHkuIENvbnZlcnNlbHksIHdlIGFsc28gc2VlIHRoYXQgc3R1ZGVudHMgd2hvIHVzZSBtb3JlIGxlYXJuaW5nIHJlc291cmNlcyB0ZW5kIHRvIGhhdmUgaGlnaGVyIGxlYXJuaW5nIGFueGlldHkuDQoNCkluIHRoZSBuZXh0IGZldyBzdWJzZWN0aW9ucywgd2UgYW5hbHl6ZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gdGhlIHNjYWxlcyBpbiB0aGlzIHN1cnZleSBhbmQgY29tcGFyZSBvdXIgcmVzdWx0cyB3aXRoIHRob3NlIGluIHRoZSBleGlzdGluZyBsaXRlcmF0dXJlLg0KDQojIyBJbnRlcnJlbGF0aW9uc2hpcCBCZXR3ZWVuIEV2YWx1YXRpb24gYW5kIExlYXJuaW5nIEFueGlldGllcw0KDQpBIHBvc2l0aXZlIGNvcnJlbGF0aW9uIHdhcyBmb3VuZCBiZXR3ZWVuIG1hdGhlbWF0aWNzIGV2YWx1YXRpb24gYW54aWV0eSBhbmQgbWF0aGVtYXRpY3MgbGVhcm5pbmcgYW54aWV0eSwgd2hpY2ggaXMgY29uc2lzdGVudCB3aXRoIHByZXZpb3VzIHJlc2VhcmNoLg0KDQpNYXRoZW1hdGljcyBsZWFybmluZyBhbnhpZXR5IGlzIG9mdGVuIHRoZSBicm9hZGVyLCBmb3VuZGF0aW9uYWwgaXNzdWUsIHN0ZW1taW5nIGZyb20gbmVnYXRpdmUgZXhwZXJpZW5jZXMgYW5kIGJlbGllZnMgYWJvdXQgb25lJ3Mgb3duIG1hdGhlbWF0aWNhbCBhYmlsaXR5LiBNYXRoZW1hdGljcyB0ZXN0IGFueGlldHkgaXMgYSBtb3JlIHNwZWNpZmljLCBzaXR1YXRpb25hbCBtYW5pZmVzdGF0aW9uIG9mIHRoaXMgYnJvYWRlciBhbnhpZXR5LCB0cmlnZ2VyZWQgYnkgdGhlIGV2YWx1YXRpdmUgcHJlc3N1cmUgb2YgZXhhbXMuDQoNClRoZSBwcmltYXJ5IHJlbGF0aW9uc2hpcCBpcyBjeWNsaWNhbDogbGVhcm5pbmcgYW54aWV0eSBmb3N0ZXJzIHRlc3QgYW54aWV0eSwgYW5kIGEgbmVnYXRpdmUgdGVzdCBleHBlcmllbmNlIHJlaW5mb3JjZXMgbGVhcm5pbmcgYW54aWV0eS4gR2llcmwgYW5kIEJpc2FueiAoMTk5NSkgaGlnaGxpZ2h0ZWQgdGhpcyBjeWNsaWNhbCBuYXR1cmUuIFRoZXkgc3VnZ2VzdGVkIHRoYXQgZWFybHkgbmVnYXRpdmUgZXhwZXJpZW5jZXMgd2l0aCBtYXRoIChsZWFkaW5nIHRvIGxlYXJuaW5nIGFueGlldHkpIHNldCB0aGUgc3RhZ2UgZm9yIGxhdGVyIHRlc3QgYW54aWV0eS4gQ29udmVyc2VseSwgYSBzaW5nbGUgdHJhdW1hdGljIHRlc3QgZXhwZXJpZW5jZSAoZS5nLiwgYSBkaXNhc3Ryb3VzIGZpbmFsIGV4YW0pIGNhbiBnZW5lcmFsaXplIHRvIGEgbG9uZy1sYXN0aW5nLCBwZXJ2YXNpdmUgYW54aWV0eSB0b3dhcmQgYWxsIG1hdGgtcmVsYXRlZCBhY3Rpdml0aWVzLCBzb2xpZGlmeWluZyBsZWFybmluZyBhbnhpZXR5LiBaYWthcmlhIGV0IGFsLiAoMjAxMikgZm91bmQgYSBzaWduaWZpY2FudCBwb3NpdGl2ZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIGdlbmVyYWwgbWF0aGVtYXRpY3MgYW54aWV0eSBhbmQgdGVzdCBhbnhpZXR5LiBTdHVkZW50cyB3aG8gYXJlIGFscmVhZHkgYW54aW91cyBpbiBkYWlseSBtYXRoIGNsYXNzZXMgYXJlIHByaW1lZCBmb3IgaGVpZ2h0ZW5lZCBhbnhpZXR5IHdoZW4gdGhlIHN0YWtlcyBhcmUgcmFpc2VkIGluIGEgdGVzdC4NCg0KQm90aCBhbnhpZXRpZXMgb2Z0ZW4gc3RlbSBmcm9tIGNvbW1vbiByb290cywgd2hpY2ggZXhwbGFpbnMgdGhlaXIgaGlnaCBwb3NpdGl2ZSBpbnRlci1yZWxhdGlvbnNoaXAuDQoNCi0gICAqKk5lZ2F0aXZlIFBhc3QgRXhwZXJpZW5jZXMqKjogUmVwZWF0ZWQgZmFpbHVyZSBvciBodW1pbGlhdGlvbiBpbiBtYXRoIGNsYXNzZXMgZHVyaW5nIEstMTIgZWR1Y2F0aW9uIGlzIGEgcG93ZXJmdWwgcHJlZGljdG9yIGZvciBib3RoIHR5cGVzIG9mIGFueGlldHkgaW4gY29sbGVnZSAoTWFsb25leSAmIEJlaWxvY2ssIDIwMTIpLg0KDQotICAgKlNvY2lldGFsIGFuZCBFbnZpcm9ubWVudGFsIEZhY3RvcnMqOiBDdWx0dXJhbCBzdGVyZW90eXBlcyAoZS5nLiwgIm1hdGggaXMgZm9yIGJveXMsIiAic29tZSBwZW9wbGUganVzdCBhcmVuJ3QgbWF0aCBwZW9wbGUiKSBhbmQgdGVhY2hlciBhbnhpZXR5IGNhbiBiZSB0cmFuc21pdHRlZCB0byBzdHVkZW50cywgZm9zdGVyaW5nIGEgZ2VuZXJhbCBzZW5zZSBvZiBhcHByZWhlbnNpb24gdG93YXJkIHRoZSBzdWJqZWN0Lg0KDQotICAgKipGaXhlZCBNaW5kc2V0Kio6IFRoZSB3b3JrIG9mIENhcm9sIER3ZWNrICgyMDA2KSBvbiBtaW5kc2V0IGlzIGhpZ2hseSByZWxldmFudC4gU3R1ZGVudHMgd2l0aCBhICJmaXhlZCBtaW5kc2V0IiAodGhlIGJlbGllZiB0aGF0IG1hdGggYWJpbGl0eSBpcyBhbiBpbm5hdGUsIHVuY2hhbmdlYWJsZSB0cmFpdCkgYXJlIG1vcmUgdnVsbmVyYWJsZSB0byBib3RoIGxlYXJuaW5nIGFuZCB0ZXN0IGFueGlldHkuIEFueSBzdHJ1Z2dsZSBpcyBzZWVuIGFzIGV2aWRlbmNlIG9mIGEgbGFjayBvZiBhYmlsaXR5LCBjYXVzaW5nIHRoZW0gdG8gYXZvaWQgY2hhbGxlbmdpbmcgbGVhcm5pbmcgYW5kIHRvIGNydW1ibGUgdW5kZXIgdGhlIGV2YWx1YXRpdmUgcHJlc3N1cmUgb2YgdGVzdHMuDQoNCiMjIFN0dWRlbnQgUGVyY2VpdmVkIFRlYWNoaW5nIFN0cmF0ZWdpZXMNCg0KV2UgY2FuIHNlZSBmcm9tIHRoZSBhYm92ZSBjb3JyZWxhdGlvbiBtYXRyaXggKGhlYXRtYXApIHRoYXQgdGhlIHNldmVuIGRpbWVzaW9ucyBvZiBzdHVkZW50IHBlcmNlaXZlZCB0ZWFjaGluZyBzdHJhdGVnaWVzIGFyZSBoaWdobHkgcG9zaXRpdmVseSBjb3JyZWxhdGVkLiBUaGlzIHBvc2l0aXZlIGNvcnJlbGF0aW9uIGFtb25nIGRpdmVyc2UgdGVhY2hpbmcgc3RyYXRlZ2llcyBsaWtlIGNvb3BlcmF0aXZlLCBkZWR1Y3RpdmUsIGFuZCBsZWN0dXJlLXR5cGUgbWV0aG9kcyBzdWdnZXN0cyB0aGF0IHN0dWRlbnRzIGRvIG5vdCBuZWNlc3NhcmlseSB2aWV3IHRoZXNlIGFwcHJvYWNoZXMgYXMgbXV0dWFsbHkgZXhjbHVzaXZlLiBJbnN0ZWFkLCB0aGV5IG1heSBwZXJjZWl2ZSB0aGVtIGFzIGNvbXBsZW1lbnRhcnkgdG9vbHMgd2l0aGluIGFuIGVmZmVjdGl2ZSBpbnN0cnVjdG9yJ3MgcmVwZXJ0b2lyZS4gVGhlIHJlYXNvbnMgZm9yIHRoaXMgb2JzZXJ2ZWQgaW50ZXJjb3JyZWxhdGlvbiBjYW4gYmUgYXR0cmlidXRlZCB0byBzZXZlcmFsIGZhY3RvcnMuDQoNCi0gICAqKkluc3RydWN0b3IgVmVyc2F0aWxpdHkgYW5kIFN0cmF0ZWdpYyBCbGVuZGluZyoqOiBBIHNpbmdsZSBsZXNzb24gbWlnaHQgYmVnaW4gd2l0aCBhIGJyaWVmIGxlY3R1cmUgdG8gaW50cm9kdWNlIGEgY29uY2VwdCwgdXNlIGEgZGVtb25zdHJhdGl2ZSBleGFtcGxlLCBhbmQgdGhlbiBlbmdhZ2Ugc3R1ZGVudHMgaW4gYSBjb29wZXJhdGl2ZSBwcm9ibGVtLXNvbHZpbmcgYWN0aXZpdHkgdG8gYXBwbHkgdGhlIGNvbmNlcHQgaW5kdWN0aXZlbHkuIFN0dWRlbnRzIHBlcmNlaXZlIHRoaXMgYmxlbmRpbmcsIGxlYWRpbmcgdG8gcG9zaXRpdmUgY29ycmVsYXRpb25zIGFtb25nIHRoZSBzdHJhdGVnaWVzIHRoZXkgb2JzZXJ2ZS4NCg0KLSAgICoqU3R1ZGVudCBSZWNvZ25pdGlvbiBvZiBhIENvaGVyZW50IExlYXJuaW5nIEN5Y2xlKio6IFN0dWRlbnRzIG1heSBwZXJjZWl2ZSB0aGF0IGRpZmZlcmVudCBzdHJhdGVnaWVzIHNlcnZlIGRpZmZlcmVudCwgYnV0IGludGVyY29ubmVjdGVkLCBwdXJwb3NlcyBpbiB0aGVpciBsZWFybmluZyBqb3VybmV5LiBGb3IgaW5zdGFuY2UsIGEgcmVwZXRpdGl2ZSBwcmFjdGljZSBzZXNzaW9uIG1pZ2h0IGxvZ2ljYWxseSBmb2xsb3cgYSBkZWR1Y3RpdmUgZXhwbGFuYXRpb24gb2YgYSBmb3JtdWxhIHRvIGJ1aWxkIGZsdWVuY3ksIGFuZCBhbiBpbnRlZ3JhdGl2ZSBwcm9qZWN0IG1pZ2h0IGNhcCBhIHVuaXQgdG8gc2hvdyByZWFsLXdvcmxkIGFwcGxpY2F0aW9uLiBXaGVuIHRoZXNlIHN0cmF0ZWdpZXMgYXJlIHNlcXVlbmNlZCBlZmZlY3RpdmVseSwgc3R1ZGVudHMgc2VlIHRoZW0gYXMgcGFydHMgb2YgYSB3aG9sZSwgY29oZXJlbnQgZXhwZXJpZW5jZSwgbGVhZGluZyB0byBwb3NpdGl2ZSByYXRpbmdzIGFjcm9zcyB0aGUgYm9hcmQgKEJvYWxlciwgMjAxNikuDQoNCi0gICAqKlRoZSBIYWxvIEVmZmVjdCBvZiBQZWRhZ29naWNhbCBSaWNobmVzcyoqOiBBIGNsYXNzcm9vbSBlbnZpcm9ubWVudCByaWNoIHdpdGggdmFyaWVkIHBlZGFnb2dpY2FsIGFwcHJvYWNoZXMgaXMgb2Z0ZW4gbW9yZSBlbmdhZ2luZy4gVGhlIHBvc2l0aXZlIGFmZmVjdCBnZW5lcmF0ZWQgYnkgb25lIGVuZ2FnaW5nIHN0cmF0ZWd5IChlLmcuLCBhIGZ1biBjb29wZXJhdGl2ZSBhY3Rpdml0eSkgY2FuIGNyZWF0ZSBhICJoYWxvIGVmZmVjdCwiIGxlYWRpbmcgc3R1ZGVudHMgdG8gcmF0ZSBhbGwgdGhlIHN0cmF0ZWdpZXMgdXNlZCBpbiB0aGF0IHBvc2l0aXZlIGNvbnRleHQgbW9yZSBoaWdobHksIGV2ZW4gdGhlIG1vcmUgdHJhZGl0aW9uYWwgb25lcyBsaWtlIGxlY3R1cmUtdHlwZSBpbnN0cnVjdGlvbiAoSGF0dGllLCAyMDEyKS4NCg0KSG93ZXZlciwgdGhlc2UgY29ycmVsYXRpb25zIGNhbiBhbHNvIGJlIGluZmxhdGVkIGJ5IGdlbmVyYWxpemVkIHN0dWRlbnQgYXR0aXR1ZGVzIHJhdGhlciB0aGFuIHByZWNpc2UgcmVmbGVjdGlvbnMgb2YgZGlzY3JldGUgdGVhY2hpbmcgYWN0cy4gRm9yIGV4YW1wbGUsIHRoZSBjb3JyZWxhdGlvbnMgbWlnaHQgbm90IHJlZmxlY3QgdGhlIGFjdHVhbCBmcmVxdWVuY3kgb2YgdXNlIGJ1dCBhIGdlbmVyYWxpemVkIHN0dWRlbnQgcGVyY2VwdGlvbiBvZiB0aGVpciBpbnN0cnVjdG9yLiBBIHN0dWRlbnQgd2hvIGhvbGRzIGEgcG9zaXRpdmUgb3ZlcmFsbCB2aWV3IG9mIHRoZSB0ZWFjaGVyIG1pZ2h0IHJhdGUgYWxsIHRlYWNoaW5nIHN0cmF0ZWdpZXMgaGlnaGx5LCByZWdhcmRsZXNzIG9mIGhvdyBlZmZlY3RpdmVseSBlYWNoIHdhcyBpbmRpdmlkdWFsbHkgZGVwbG95ZWQuIFRoaXMgaXMgYSBjb21tb24gZm9ybSBvZiByZXNwb25zZSBiaWFzIGluIHN0dWRlbnQgZXZhbHVhdGlvbnMgKFNwb29yZW4gZXQgYWwuLCAyMDEzKS4NCg0KVGhlIGNvcnJlbGF0aW9uIG1pZ2h0IGFsc28gYmUgY29uZm91bmRlZCBkdWUgdG8gbGFjayBvZiBkaXNjcmltaW5hbnQgdmFsaWRpdHkgaW4gcGVyY2VwdGlvbi4gRm9yIGV3eGFtcGxlLCBzdHVkZW50cywgZXNwZWNpYWxseSB0aG9zZSB3aXRob3V0IHBlZGFnb2dpY2FsIHRyYWluaW5nLCBtYXkgbm90IGZpbmVseSBkaXNjcmltaW5hdGUgYmV0d2VlbiB0aGUgbnVhbmNlZCBkZWZpbml0aW9ucyBvZiBlYWNoIHN0cmF0ZWd5LiBUaGV5IG1pZ2h0IGJyb2FkbHkgcGVyY2VpdmUgInRoZSB0ZWFjaGVyIGV4cGxhaW5zIHRoaW5ncyBjbGVhcmx5LCIgd2hpY2ggY291bGQgbGVhZCB0aGVtIHRvIHJhdGUgZGVkdWN0aXZlLCBkZW1vbnN0cmF0aXZlLCBhbmQgaW50ZWdyYXRpdmUgc3RyYXRlZ2llcyBzaW1pbGFybHkgYmVjYXVzZSB0aGV5IGFsbCBjb250cmlidXRlIHRvIHRoYXQgb3ZlcmFyY2hpbmcgZmVlbGluZyBvZiBjbGFyaXR5Lg0KDQojIyBUaGUgVHJpYWQgb2YgQW54aWV0eSwgU2VsZi1FZmZpY2FjeSwgYW5kIFRlYWNoaW5nIFN0cmF0ZWdpZXMNCg0KTWF0aCBzZWxmLWVmZmljYWN5LCBhIGNvbmNlcHQgZGVyaXZlZCBmcm9tIEFsYmVydCBCYW5kdXJhJ3Mgc29jaWFsIGNvZ25pdGl2ZSB0aGVvcnksIHJlZmVycyB0byBhbiBpbmRpdmlkdWFsJ3MgY29udmljdGlvbiBpbiB0aGVpciBhYmlsaXR5IHRvIHN1Y2Nlc3NmdWxseSBwZXJmb3JtIHNwZWNpZmljIG1hdGhlbWF0aWNhbCB0YXNrcy4gSXQgaXMgbm90IGEgZ2VuZXJhbCBmZWVsaW5nIG9mIGNvbmZpZGVuY2UgYnV0IGEgc2l0dWF0aW9uLXNwZWNpZmljIGJlbGllZiBhbmQgYSByb2J1c3QgcHJlZGljdG9yIG9mIHBlcnNldmVyYW5jZSwgZW5nYWdlbWVudCwgYW5kIGFjYWRlbWljIHN1Y2Nlc3MgaW4gbWF0aGVtYXRpY3MgKEJhbmR1cmEsIDE5OTcpLg0KDQpDb252ZXJzZWx5LCBtYXRoIGFueGlldHkgaXMgYSBzdGF0ZSBvZiB0ZW5zaW9uLCBhcHByZWhlbnNpb24sIG9yIGZlYXIgdGhhdCBpbnRlcmZlcmVzIHdpdGggbWF0aCBwZXJmb3JtYW5jZS4gSXQgaXMgbW9yZSB0aGFuIGEgc2ltcGxlIGRpc2xpa2U7IGl0IGlzIGEgZGViaWxpdGF0aW5nIGVtb3Rpb25hbCByZWFjdGlvbiB0aGF0IGNhbiBjcmVhdGUgYSB2aWNpb3VzIGN5Y2xlOiBhbnhpZXR5IGxlYWRzIHRvIGF2b2lkYW5jZSwgd2hpY2ggbGVhZHMgdG8gcG9vcmVyIHNraWxscywgd2hpY2ggaW4gdHVybiBoZWlnaHRlbnMgYW54aWV0eSAoQXNoY3JhZnQsIDIwMDIpLg0KDQpUaGVzZSB0d28gY29uc3RydWN0cyBhcmUgdHlwaWNhbGx5IHN0cm9uZ2x5IGFuZCBpbnZlcnNlbHkgY29ycmVsYXRlZC4gQSBzdHVkZW50IHdpdGggaGlnaCBzZWxmLWVmZmljYWN5IGlzIGxlc3MgbGlrZWx5IHRvIGV4cGVyaWVuY2UgYW54aWV0eSB3aGVuIGZhY2VkIHdpdGggYSBtYXRoIHByb2JsZW0sIHdoaWxlIGEgc3R1ZGVudCB3aXRoIGhpZ2ggYW54aWV0eSB3aWxsIGxpa2VseSBoYXZlIHRoZWlyIHNlbnNlIG9mIGVmZmljYWN5IGVyb2RlZC4NCg0KQ3JpdGljYWxseSwgdGVhY2hpbmcgc3RyYXRlZ2llcyBhcmUgbm90IG1lcmVseSBtZXRob2RzIG9mIGNvbnRlbnQgZGVsaXZlcnk7IHRoZXkgYXJlIHBvd2VyZnVsIGVudmlyb25tZW50YWwgZm9yY2VzIHRoYXQgZGlyZWN0bHkgc2hhcGUgc3R1ZGVudHMnIGVtb3Rpb25hbCBhbmQgc2VsZi1ldmFsdWF0aXZlIGxhbmRzY2FwZXMuIFRvZ2V0aGVyLCB0aGUgdHJpYWQgb2YgUGVyY2VpdmVkIFRlYWNoaW5nIFN0cmF0ZWdpZXMsIE1hdGggQW54aWV0eSwgYW5kIE1hdGggU2VsZi1FZmZpY2FjeSBmb3JtcyBhIGR5bmFtaWMsIGludGVyY29ubmVjdGVkIHN5c3RlbSB0aGF0IHNpZ25pZmljYW50bHkgaW5mbHVlbmNlcyBhIHN0dWRlbnQncyBtYXRoIGFjaGlldmVtZW50IGFuZCBvdmVyYWxsIHJlbGF0aW9uc2hpcCB3aXRoIHRoZSBzdWJqZWN0Lg0KDQpUaGUgcmVsYXRpb25zaGlwcyB3aXRoaW4gdGhpcyB0cmlhZCBhcmUgcmVjaXByb2NhbC4gQSBzdHVkZW50IHdpdGggaGlnaCBtYXRoIHNlbGYtZWZmaWNhY3kgbWF5IHRocml2ZSBpbiBhIGZhc3QtcGFjZWQgbGVjdHVyZSwgdmlld2luZyBpdCBhcyBhbiBlZmZpY2llbnQgd2F5IHRvIGFjcXVpcmUgaW5mb3JtYXRpb24uIEFuIGFueGlvdXMgc3R1ZGVudCBpbiB0aGUgc2FtZSBlbnZpcm9ubWVudCwgaG93ZXZlciwgbWF5IGJlY29tZSBvdmVyd2hlbG1lZCBhbmQgZGlzZW5nYWdlZC4gRnVydGhlcm1vcmUsIHN0dWRlbnRzIHdpdGggaGlnaCBhbnhpZXR5IG1heSBhY3RpdmVseSBhdm9pZCBwYXJ0aWNpcGF0aW5nIGluIGNvb3BlcmF0aXZlIGdyb3VwcyBmb3IgZmVhciBvZiBiZWluZyBqdWRnZWQsIHRoZXJlYnkgbWlzc2luZyBvdXQgb24gdGhlIHZlcnkgZXhwZXJpZW5jZXMgdGhhdCBjb3VsZCBidWlsZCB0aGVpciBjb25maWRlbmNlLiBJbiB0aGlzIHdheSwgYSBzdHVkZW50J3MgcHJlLWV4aXN0aW5nIGFueGlldHkgYW5kIHNlbGYtZWZmaWNhY3kgZGlyZWN0bHkgc2hhcGUgdGhlaXIgcGVyY2VwdGlvbiBvZiBhbmQgcmVzcG9uc2UgdG8gdGhlIGxlYXJuaW5nIGVudmlyb25tZW50IGl0c2VsZi4NCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGg9IjcwJSJ9DQppbmNsdWRlX2dyYXBoaWNzKCJUZWNoaW5nU3RyYXRlZ2llcy1BbnhpZXR5LVNlbGYtZWZmaWNhY3kucG5nIikNCmBgYA0KDQojIyBHcm91cGluZyBUZWFjaGluZyBTdHJhdGVnaWVzDQoNClRoZSBmb2xsb3dpbmcgZGVuc2l0eSBjdXJ2ZXMgcmVwcmVzZW50ICpuYWl2ZSogY29tcG9zaXRlIHNjb3JlcyBkZXJpdmVkIGZyb20gdGhlIGF2ZXJhZ2Ugb2YgaXRlbSBzY29yZXMgZm9yIGVhY2ggb2YgdGhlIHNldmVuIHRlYWNoaW5nIHN0cmF0ZWdpZXMuIFRoZXNlIGN1cnZlcyBpbGx1c3RyYXRlIHRoZSBzdHVkZW50cycgcGVyY2VwdGlvbnMgb2YgdGhlaXIgaW5zdHJ1Y3RvcnMnIHRlYWNoaW5nIHN0cmF0ZWdpZXMuIEEgaGlnaGVyIHNjb3JlIGluZGljYXRlcyB0aGF0IHN0dWRlbnRzIHdlcmUgbW9yZSBsaWtlbHkgdG8gcGVyY2VpdmUgdGhlIHVzZSBvZiB0aGF0IHN0cmF0ZWd5Lg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTYsIHdhcm5pbmcgPSBGQUxTRX0NCnZhci5uYW1lIDwtYyggIkNvb3BvcmF0aXZlLmF2ZyIsICJEZWR1Y3RpdmUuYXZnIiwgIkRlbW9uc3RyYXRpb24uYXZnIiwNCiAgICAgICAgICAgICAgIkluZHVjdGl2ZS5hdmciLCAiSW50ZWdyYXRpdmUuYXZnIiwgIkxlY3R1cmVUeXBlLmF2ZyIsDQogICAgICAgICAgICAgICJSZXBldGl0aXZlLmF2ZyIpDQphbGwuY29tcG9zaXRlLnNjb3JlcyA8LSBmaW5hbC5hbnhpZXR5LmRhdFssIHZhci5uYW1lXQ0KbmFtZXMoYWxsLmNvbXBvc2l0ZS5zY29yZXMpIDwtIGMoIkNvb3BlcmF0aXZlIiwgIkRlZHVjdGl2ZSIsICJEZW1vbnN0cmF0aXZlIiwNCiAgICAgICAgICAgICAgIkluZHVjdGl2ZSIsICJJbnRlZ3JhdGl2ZSIsICJMZWN0dXJlIiwgICAiUmVwZXRpdGl2ZSIpDQoNCiMgRm9yIG9sZGVyIHZlcnNpb25zIG9mIHRpZHlyDQpsb25nX2RhdGEgPC0gYWxsLmNvbXBvc2l0ZS5zY29yZXMgJT4lDQogIHBpdm90X2xvbmdlcigNCiAgICBjb2xzID0gYyggQ29vcGVyYXRpdmUsIERlZHVjdGl2ZSwgRGVtb25zdHJhdGl2ZSwgSW5kdWN0aXZlLCBJbnRlZ3JhdGl2ZSwgTGVjdHVyZSwgUmVwZXRpdGl2ZSksICAjIENvbHVtbnMgdG8gcmVzaGFwZQ0KICAgIG5hbWVzX3RvID0gInZhcmlhYmxlIiwgICAgICAgICAgIyBOZXcgY29sdW1uIG5hbWUgZm9yIHZhcmlhYmxlIG5hbWVzDQogICAgdmFsdWVzX3RvID0gInZhbHVlIiAgICAgICAgICAgICAjIE5ldyBjb2x1bW4gbmFtZSBmb3IgdmFsdWVzDQogICkNCg0KIyMgU3VtbWFyaXplZCBzdGF0cw0KDQpzdW1tYXJ5X3N0YXRzIDwtIGxvbmdfZGF0YSAlPiUNCiAgZ3JvdXBfYnkodmFyaWFibGUpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgbWVhbl92YWwgPSBtZWFuKHZhbHVlKSwNCiAgICBtZWRpYW5fdmFsID0gbWVkaWFuKHZhbHVlKSwNCiAgICBzZF92YWwgPSBzZCh2YWx1ZSksDQogICAgbiA9IG4oKSwNCiAgICAuZ3JvdXBzID0gJ2Ryb3AnDQogICkNCg0KIyBDcmVhdGUgcmlkZ2UgcGxvdCB3aXRoIGdncmlkZ2VzIGFuZCBjb252ZXJ0IHRvIHBsb3RseQ0KcmlkZ2VfZ2cgPC0gZ2dwbG90KGxvbmdfZGF0YSwgYWVzKHggPSB2YWx1ZSwgeSA9IHZhcmlhYmxlLCBmaWxsID0gdmFyaWFibGUNCiAgKSkgKw0KICBnZW9tX2RlbnNpdHlfcmlkZ2VzKA0KICAgIGFscGhhID0gMC43LA0KICAgIHNjYWxlID0gMiwgICMgQWRqdXN0IG92ZXJsYXANCiAgICBjb2xvciA9ICJ3aGl0ZSIsDQogICAgc2l6ZSA9IDAuNSwNCiAgICAgKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsNCiAgI3RoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwKSkgKw0KICB0aGVtZV9yaWRnZXMoKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiRGlzdHJpYnV0aW9ucyBvZiBTdHVkZW50cycgUGVyY2VpdmVkIFxuIFRlYWNoaW5nIFN0cmF0ZWd5IEluZGljZXMiLA0KICAgIHggPSAiUGVyY2VpdmVkIFRlYWNoaW5nIFN0cmF0ZWd5IFNjb3JlIiwNCiAgICB5ID0gIiINCiAgKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksDQogICAgICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKHQgPSAxLjIsIHVuaXQgPSAiY20iKSkNCg0KIyBDb252ZXJ0IHRvIHBsb3RseQ0KZ2dwbG90bHkocmlkZ2VfZ2cpDQpgYGANCg0KQXMgc2hvd24gaW4gdGhlIGZpZ3VyZSwgdGhlICoqcmVwZXRpdGl2ZSoqLCAqKmxlY3R1cmUtdHlwZSoqLCAqKmluZHVjdGl2ZSoqLCBhbmQgKipkZW1vbnN0cmF0aXZlKiogYXBwcm9hY2hlcyB3ZXJlIHBlcmNlaXZlZCBhcyBtb3JlIHBvcHVsYXIgdGhhbiB0aGUgKippbnRlZ3JhdGl2ZSoqLCAqKmRlZHVjdGl2ZSoqLCBhbmQgKipjb29wZXJhdGl2ZSoqIGFwcHJvYWNoZXMuIFRoaXMgb2JzZXJ2YXRpb24gYWxpZ25zIHdpdGggdGhlIGVzdGFibGlzaGVkIGNsYXNzaWZpY2F0aW9uIG9mIHRlYWNoaW5nIHN0eWxlcyBpbiBlZHVjYXRpb25hbCBhbmQgcHN5Y2hvbG9naWNhbCByZXNlYXJjaCBhbmQgY2xhc3NpYyB0ZXh0Ym9va3MuDQoNCnwgVGVhY2hlci1jZW50ZXJlZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBTdHVkZW50LWNlbnRlcmVkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwNCnw6LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXw6LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfA0KfCAqKkRlZHVjdGl2ZSoqIChUZWFjaGVyIHByb3ZpZGVzIHJ1bGVzIGFuZCBleGFtcGxlczogSm95Y2UgZXQgYWwuLCAyMDE1KSB8ICoqQ29vcGVyYXRpdmUqKiAoU3R1ZGVudHMgd29yayB0b2dldGhlcjogSm9obnNvbiwgMjAxNCkgICAgICAgICAgICAgICAgICAgICAgfA0KfCAqKkxlY3R1cmUgVHlwZSoqIChUZWFjaGVyIHRyYW5zbWl0cyBpbmZvcm1hdGlvbjogQnJvd24sMjAwNykgICAgICAgICAgICB8ICoqSW5kdWN0aXZlKiogKFN0dWRlbnRzIGRpc2NvdmVyIHJ1bGVzOiBCcnVuZXIsIDE5NjE7IFByaW5jZSAmIEZlbGRlciwgMjAwNikgfA0KfCAqKkRlbW9uc3RyYXRpdmUqKiAoVGVhY2hlciBzaG93cyBob3c6IEJvcmljaCwgMjAxNykgICAgICAgICAgICAgICAgICAgICB8ICoqSW50ZWdyYXRpdmUqKiAoU3R1ZGVudHMgY29ubmVjdCBpZGVhczogSmFjb2JzLCAxOTg5OyBGb2dhcnR5LDE5OTEpICAgICAgICAgfA0KfCAqKlJlcGV0aXRpdmUqKiAoVGVhY2hlciBkcmlsbHMgdGhlIGluZm9ybWF0aW9uOiBPcm1yb2QsIDIwMjApICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KDQpUaGUgYWJvdmUgY2xhc3NpZmljYXRpb24gaXMgY29uc2lzdGVudCB3aXRoIHRoZSBvbmUgYmFzZWQgb24gY29nbml0aXZlIGRlbWFuZCAoQmxvb20ncyBUYXhvbm9teSksIHdoaWNoIGNhdGVnb3JpemVzIHN0cmF0ZWdpZXMgYXMgcmVxdWlyaW5nIGVpdGhlciBsb3dlci1sZXZlbCB0aGlua2luZyAocmVtZW1iZXIsIHVuZGVyc3RhbmQpIG9yIGhpZ2hlci1sZXZlbCB0aGlua2luZyAoYXBwbHksIGFuYWx5emUsIGV2YWx1YXRlLCBjcmVhdGUpLg0KDQoqKk5vdGUqKjogVGhlICoqRGVtb25zdHJhdGl2ZSBBcHByb2FjaCBzdWItc2NhbGUqKiBpbiB0aGlzIHN1cnZleSBtZWFzdXJlcyBjb25zdHJ1Y3RzIGFzc29jaWF0ZWQgd2l0aCBib3RoICoqVHJhZGl0aW9uYWwgVGVhY2hlci1DZW50ZXJlZCoqIGFuZCAqKlN0dWRlbnQtQ2VudGVyZWQgU3RyYXRlZ2llcyoqLiBJdCBlbmNvbXBhc3NlcyBub3Qgb25seSB0aGUgdGVhY2hlcidzIGRpcmVjdCBkZW1vbnN0cmF0aW9uIG9mIGtub3dsZWRnZSBidXQgYWxzbyB0aGUgdXNlIG9mIHRoZXNlIGRlbW9uc3RyYXRpb25zIHRvIGZhY2lsaXRhdGUgc3R1ZGVudC1sZWQgc29sdXRpb24gYnVpbGRpbmcsIGNoYXJhY3Rlcml6aW5nIGl0IGFzIGEgaHlicmlkIHRlYWNoaW5nIHN0cmF0ZWd5Lg0KDQpUaGlzIGNsYXNzaWZpY2F0aW9uIGRlbW9uc3RyYXRlcyBhIHNwZWN0cnVtIG9mIHBlZGFnb2dpY2FsIGFwcHJvYWNoZXMsIGZyb20gdHJhZGl0aW9uYWwsIGhpZ2hseSBzdHJ1Y3R1cmVkIG1ldGhvZHMgbGlrZSBMZWN0dXJlIGFuZCBEZWR1Y3RpdmUgdGVhY2hpbmcsIHRvIG1vZGVybiwgc3R1ZGVudC1kcml2ZW4gbWV0aG9kcyBsaWtlIEluZHVjdGl2ZSwgQ29vcGVyYXRpdmUsIGFuZCBJbnRlZ3JhdGl2ZSBsZWFybmluZy4gRGVtb25zdHJhdGlvbiBhbmQgUmVwZXRpdGl2ZSBwcmFjdGljZSBzZXJ2ZSBzcGVjaWZpYywgb2Z0ZW4gY29tcGxlbWVudGFyeSwgcm9sZXMgd2l0aGluIHRoaXMgc3BlY3RydW0uDQoNCiMjIFRlYWNoaW5nIFN0cmF0ZWdpZXMgTW9kdWxhdGUgdGhlIFRyaWFkDQoNClRlYWNoaW5nIHN0cmF0ZWdpZXMgYXJlIG5vdCBtZXJlbHkgbWV0aG9kcyBvZiBjb250ZW50IGRlbGl2ZXJ5OyB0aGV5IGFyZSBwb3dlcmZ1bCBlbnZpcm9ubWVudGFsIGZvcmNlcyB0aGF0IGRpcmVjdGx5IHNoYXBlIHN0dWRlbnRzJyBlbW90aW9uYWwgYW5kIHNlbGYtZXZhbHVhdGl2ZSBsYW5kc2NhcGVzLg0KDQoqKlRlYWNoZXItQ2VudGVyZWQgU3RyYXRlZ2llcyoqDQoNCi0gICAqKkxlY3R1cmUtdHlwZSBhbmQgRGVkdWN0aXZlIEFwcHJvYWNoZXMqKjogVGhlc2UgbWV0aG9kcywgd2hlcmUgdGhlIGluc3RydWN0b3IgcHJlc2VudHMgZXN0YWJsaXNoZWQgcnVsZXMgYW5kIHByb2NlZHVyZXMgZmlyc3QgKGRlZHVjdGl2ZSkgaW4gYSBsYXJnZWx5IG9uZS13YXkgZm9ybWF0IChsZWN0dXJlKSwgY2FuIGluYWR2ZXJ0ZW50bHkgZXhhY2VyYmF0ZSB0aGUgdHJpYWQncyBuZWdhdGl2ZSBwb3RlbnRpYWwuIEZvciBhIHN0dWRlbnQgd2l0aCBsb3cgc2VsZi1lZmZpY2FjeSBvciBoaWdoIGFueGlldHksIHRoZSByYXBpZCwgaW1wZXJzb25hbCBwYWNlIG9mIGEgbGVjdHVyZSBjYW4gcmVpbmZvcmNlIGZlZWxpbmdzIG9mIGluYWRlcXVhY3kgYW5kIGluYWJpbGl0eSB0byBrZWVwIHVwLiBUaGUgZm9jdXMgb24gYSBzaW5nbGUgImNvcnJlY3QiIG1ldGhvZCBjYW4gc3RpZmxlIHRoZSBleHBsb3JhdG9yeSBiZWhhdmlvcnMgdGhhdCBidWlsZCBnZW51aW5lIHVuZGVyc3RhbmRpbmcgYW5kIGNvbmZpZGVuY2UuDQoNCi0gICAqKlJlcGV0aXRpdmUgKERyaWxsLWFuZC1QcmFjdGljZSkgQXBwcm9hY2gqKjogV2hpbGUgbmVjZXNzYXJ5IGZvciBkZXZlbG9waW5nIHByb2NlZHVyYWwgZmx1ZW5jeSwgYW4gb3Zlci1yZWxpYW5jZSBvbiByZXBldGl0aXZlIHByYWN0aWNlIGNhbiBiZSBhIGRvdWJsZS1lZGdlZCBzd29yZC4gRm9yIGhpZ2hseSBlZmZpY2FjaW91cyBzdHVkZW50cywgaXQgY2FuIHNvbGlkaWZ5IHNraWxscy4gSG93ZXZlciwgZm9yIGFueGlvdXMgc3R1ZGVudHMsIGl0IGNhbiBiZWNvbWUgYSBzb3VyY2Ugb2YgaW1tZW5zZSBzdHJlc3MsIGZyYW1pbmcgbWF0aGVtYXRpY3MgYXMgYSBtb25vdG9ub3VzLCBwZXJmb3JtYW5jZS1vcmllbnRlZCBzdWJqZWN0IHdoZXJlIG1pc3Rha2VzIGFyZSBmYWlsdXJlcy4gVGhpcyBjYW4gZGlyZWN0bHkgdW5kZXJtaW5lIHNlbGYtZWZmaWNhY3ksIGFzIG5vdGVkIGJ5IHJlc2VhcmNoZXJzIHdobyBmb3VuZCB0aGF0IGVudmlyb25tZW50cyBvdmVybHkgZm9jdXNlZCBvbiBzcGVlZCBhbmQgY29ycmVjdCBhbnN3ZXJzIGluY3JlYXNlIGFueGlldHkgKFJhbWlyZXogZXQgYWwuLCAyMDE4KS4NCg0KKipTdHVkZW50LUNlbnRlcmVkIFN0cmF0ZWdpZXMqKg0KDQotICAgKipJbmR1Y3RpdmUgYW5kIERlbW9uc3RyYXRpdmUgQXBwcm9hY2hlcyoqOiBUaGVzZSBzdHJhdGVnaWVzLCB3aGljaCBpbnZvbHZlIHByZXNlbnRpbmcgc3BlY2lmaWMgZXhhbXBsZXMgb3IgcGhlbm9tZW5hIGZyb20gd2hpY2ggc3R1ZGVudHMgZGVyaXZlIHBhdHRlcm5zIGFuZCBydWxlcyAoaW5kdWN0aXZlKSBvciB2aXN1YWxseSBpbGx1c3RyYXRpbmcgYSBjb25jZXB0IChkZW1vbnN0cmF0aXZlKSwgYWN0aXZlbHkgZW5nYWdlIHN0dWRlbnRzIGluIHRoZSBwcm9jZXNzIG9mICJkb2luZyBtYXRoZW1hdGljcy4iIEJ5IGRpc2NvdmVyaW5nIHJlbGF0aW9uc2hpcHMgdGhlbXNlbHZlcywgc3R1ZGVudHMgYnVpbGQgYSBtb3JlIHJvYnVzdCBhbmQgcGVyc29uYWwgdW5kZXJzdGFuZGluZy4gVGhpcyBwcm9jZXNzIG9mIHN1Y2Nlc3NmdWwgZGlzY292ZXJ5IGlzIGEgcG90ZW50IHNvdXJjZSBvZiBtYXN0ZXJ5IGV4cGVyaWVuY2UsIHRoZSBtb3N0IGluZmx1ZW50aWFsIHNvdXJjZSBvZiBzZWxmLWVmZmljYWN5IChCYW5kdXJhLCAxOTk3KS4gQXMgdW5kZXJzdGFuZGluZyBkZWVwZW5zLCBhbnhpZXR5IG9mdGVuIGRpbWluaXNoZXMgYmVjYXVzZSB0aGUgc3ViamVjdCBmZWVscyBsZXNzIG15c3RlcmlvdXMgYW5kIG1vcmUgbWFuYWdlYWJsZS4NCg0KLSAgICoqQ29vcGVyYXRpdmUgTGVhcm5pbmc6KiogVGhpcyBpcyBwZXJoYXBzIG9uZSBvZiB0aGUgbW9zdCBwb3dlcmZ1bCBzdHJhdGVnaWVzIGZvciBwb3NpdGl2ZWx5IGluZmx1ZW5jaW5nIHRoZSB0cmlhZC4gV29ya2luZyBpbiBzbWFsbCBncm91cHMgb24gbWVhbmluZ2Z1bCB0YXNrcyBwcm92aWRlcyBtdWx0aXBsZSBwc3ljaG9sb2dpY2FsIGJlbmVmaXRzOg0KDQogICAgLSAgICpWaWNhcmlvdXMgRXhwZXJpZW5jZSo6IFN0dWRlbnRzIG9ic2VydmUgcGVlcnMsIHdobyB0aGV5IHBlcmNlaXZlIGFzIHNpbWlsYXIgdG8gdGhlbXNlbHZlcywgc3VjY2Vzc2Z1bGx5IHNvbHZpbmcgcHJvYmxlbXMuIFRoaXMgaXMgYSBrZXkgc291cmNlIG9mIHNlbGYtZWZmaWNhY3ksIHNob3dpbmcgdGhlbSB0aGF0ICJpZiB0aGV5IGNhbiBkbyBpdCwgc28gY2FuIEkuIg0KICAgIC0gICAqVmVyYmFsIFBlcnN1YXNpb24qOiBQZWVycyBhbmQgdGhlIHRlYWNoZXIgY2FuIG9mZmVyIGVuY291cmFnZW1lbnQgYW5kIGZlZWRiYWNrIHdpdGhpbiBhIHN1cHBvcnRpdmUsIGxvdy1zdGFrZXMgc2V0dGluZy4NCiAgICAtICAgKlJlZHVjZWQgQW54aWV0eSo6IFRoZSBidXJkZW4gb2YgcGVyZm9ybWFuY2UgaXMgc2hhcmVkLCBtaXRpZ2F0aW5nIHRoZSBmZWFyIG9mIHB1YmxpYyBmYWlsdXJlIHRoYXQgY2FuIG9jY3VyIHdoZW4gYSBzdHVkZW50IGlzIGNhbGxlZCBvbiBhbG9uZSBpbiBhIHdob2xlLWNsYXNzIHNldHRpbmcuIFN0dWRpZXMgY29uc2lzdGVudGx5IHNob3cgdGhhdCBjb29wZXJhdGl2ZSBsZWFybmluZyBlbnZpcm9ubWVudHMgYXJlIGFzc29jaWF0ZWQgd2l0aCBsb3dlciBsZXZlbHMgb2YgbWF0aCBhbnhpZXR5IGFuZCBoaWdoZXIgbGV2ZWxzIG9mIHNlbGYtZWZmaWNhY3kgYW5kIGFjaGlldmVtZW50Lg0KDQotICAgKipJbnRlZ3JhdGl2ZSBBcHByb2FjaCoqOiBDb25uZWN0aW5nIG1hdGhlbWF0aWNzIHRvIHJlYWwtd29ybGQgcHJvYmxlbXMgYW5kIG90aGVyIGRpc2NpcGxpbmVzIG1ha2VzIHRoZSBzdWJqZWN0IGZlZWwgcmVsZXZhbnQgYW5kIG1lYW5pbmdmdWwuIFRoaXMgY2FuIGhlbHAgc3R1ZGVudHMgcmVmcmFtZSBtYXRoIGZyb20gYSBzZXQgb2YgYWJzdHJhY3QsIGludGltaWRhdGluZyBydWxlcyB0byBhIHVzZWZ1bCB0b29sIGZvciB1bmRlcnN0YW5kaW5nIHRoZSB3b3JsZC4gVGhpcyBwZXJjZWl2ZWQgdXRpbGl0eSBjYW4gaW5jcmVhc2UgbW90aXZhdGlvbiBhbmQgZW5nYWdlbWVudCwgd2hpY2ggaW4gdHVybiBjYW4gYm9sc3RlciBzZWxmLWVmZmljYWN5IGFuZCByZWR1Y2UgYW54aWV0eSBieSBwcm92aWRpbmcgYSBjb21wZWxsaW5nIHJlYXNvbiB0byBwZXJzaXN0IHRocm91Z2ggY2hhbGxlbmdlcy4NCg0KIyMgQ3JlYXRlIFNpbmdsZSBDb21wb3NpdGUgU2NvcmUgZm9yIHRoZSBDbGFzc2lmaWNhdGlvbg0KDQpXZSBuZXh0IGRlZmluZSB0d28gc2luZ2xlIGluZGljZXMgdG8gcmVwcmVzZW50IHRoZSB0ZWFjaGluZyBzdHJhdGVnaWVzIGJhc2VkIG9uIHRoZSBhYm92ZSBjbGFzc2lmaWNhdGlvbi4gV2UgY29uY2VwdHVhbGl6ZSB0ZWFjaGVyLWNlbnRlcmVkIGFuZCBzdHVkZW50LWNlbnRlcmVkIHN0cmF0ZWdpZXMgYXMgdHdvIHNpbmdsZS1mYWN0b3IgY29uc3RydWN0cy4gVGhlIGluZGljZXMgYXJlIGRlZmluZWQgdXNpbmcgYSBkb3VibHkgd2VpZ2h0ZWQgYXZlcmFnZSBvZiB0aGUgcHJpbmNpcGFsIGNvbXBvbmVudHMuIEZvbGxvd2luZyBjb21tb24gcHJhY3RpY2UsIHdlIHJlcG9ydCB0aGUgdmFsaWRpdHkgYW5kIHJlbGlhYmlsaXR5IG1lYXN1cmVzIGJlZm9yZSBjYWxjdWxhdGluZyB0aGUgY29tcG9zaXRlIHNjb3JlcyBmb3IgdGhlIHR3byBjbGFzc2lmaWVkIHRlYWNoaW5nIHN0cmF0ZWdpZXMuDQoNCioqVmFsaWRpdHkgTWVhc3VyZXMqKg0KDQpgYGB7ciBlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZz1GQUxTRX0NCnZhci5uYW1lIDwtYygiQ29vcG9yYXRpdmUuY2ZhIiwgIkRlZHVjdGl2ZS5jZmEiLCAiRGVtb25zdHJhdGlvbi5jZmEiLA0KICAgICAgICAgICAgICAiSW5kdWN0aXZlLmNmYSIsICJJbnRlZ3JhdGl2ZS5jZmEiLCAiTGVjdHVyZVR5cGUuY2ZhIiwNCiAgICAgICAgICAgICAgIlJlcGV0aXRpdmUuY2ZhIikNClN0cmF0ZWdlLnd0LnBjYSA8LSBmaW5hbC5hbnhpZXR5LmRhdFssIHZhci5uYW1lXQ0KbmFtZXMoU3RyYXRlZ2Uud3QucGNhKSA8LSBjKCJDb29wZXJhdGl2ZSIsICJEZWR1Y3RpdmUiLCAiRGVtb25zdHJhdGl2ZSIsDQogICAgICAgICAgICAgICJJbmR1Y3RpdmUiLCAiSW50ZWdyYXRpdmUiLCAiTGVjdHVyZSIsICAgIlJlcGV0aXRpdmUiKQ0KDQoNCg0KdGVhY2hlcjAgPC0gU3RyYXRlZ2Uud3QucGNhWyxjKCJEZWR1Y3RpdmUiLCAiRGVtb25zdHJhdGl2ZSIsICJMZWN0dXJlIiwgIlJlcGV0aXRpdmUiKV0NCnN0dWRlbnQwIDwtIFN0cmF0ZWdlLnd0LnBjYVssYygiQ29vcGVyYXRpdmUiLCAiSW5kdWN0aXZlIiwgIkludGVncmF0aXZlIiwgIkRlZHVjdGl2ZSIpXQ0KIyMjDQojIyMNCnRlYWNoZXIudmxpZCA8LWNmYS5hbmFseXNpcyh0ZWFjaGVyMCkNCnN0dWRlbnQudmxpZCA8LWNmYS5hbmFseXNpcyhzdHVkZW50MCkNCiMjDQp2bGlkLnRhYmxlIDwtcmJpbmQodGVhY2hlci5jdHJkID0gdGVhY2hlci52bGlkLCBzdHVkZW50LmN0cmQgPSBzdHVkZW50LnZsaWQpDQpyb3cubmFtZSA8LSBjKCJ0ZWFjaGVyLmN0cmQiLCAic3R1ZGVudC5jdHJkIikNCnJvd25hbWVzKHZsaWQudGFibGUpIDwtIHJvdy5uYW1lDQpjb2xuYW1lcyh2bGlkLnRhYmxlKSA8LSBjKCJzdGQuYWxsLm1pbiIsCSJwdmFsLm1heCIsCSJzcm1yIiwJImNmaSIsCSJ0bGkiKQ0KcGFuZGVyKHZsaWQudGFibGUpDQpgYGANCg0KKipSZWxpYWJpbGl0eSBNZWFzdXJlcyoqDQoNCmBgYHtyIGVjaG8gPSBUUlVFLCBldmFsID0gVFJVRSwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KdGVhY2hlciA8LSBTdHJhdGVnZS53dC5wY2FbLGMoIkRlZHVjdGl2ZSIsICJEZW1vbnN0cmF0aXZlIiwgIkxlY3R1cmUiLCAiUmVwZXRpdGl2ZSIpXQ0Kc3R1ZGVudCA8LSBTdHJhdGVnZS53dC5wY2FbLGMoIkNvb3BlcmF0aXZlIiwgIkluZHVjdGl2ZSIsICJJbnRlZ3JhdGl2ZSIpXQ0KIyMNCnRlYWNoZXIucmVsaWFiaWxpdHkgPC0gUmVsaWFiaWxpdHkuZnVuKHRlYWNoZXIpDQpzdHVkZW50LnJlbGlhYmlsaXR5IDwtIFJlbGlhYmlsaXR5LmZ1bihzdHVkZW50KQ0KIyMNClJlbC50YWJsZSA8LXJiaW5kKHRlYWNoID0gYW54aWV0eS5tZWEucmVsLCBhbnhpZXR5Lm1sYSA9IGFueGlldHkubWxhLnJlbCkNCnJvdy5uYW1lIDwtIGMoIlRlYWNoZXIiLCAiU3R1ZGVudCIpDQpjb2wubmFtZSA8LSBjKCJDcm9uYmFjaCBhbHBoYSIsICJNY0RvbmFsZCdzIE9tZWdhIikNCnJvd25hbWVzKFJlbC50YWJsZSkgPC0gcm93Lm5hbWUNCmNvbG5hbWVzKFJlbC50YWJsZSkgPC0gY29sLm5hbWUNCnBhbmRlcihSZWwudGFibGUpDQpgYGANCg0KVGhlIGFib3ZlIGdvb2RuZXNzLW9mLWZpdCBhbmQgcmVsaWFiaWxpdHkgbWVhc3VyZXMgZXhjZWVkIHRoZSByZXF1aXJlZCB0aHJlc2hvbGRzIG9mIHZhbGlkaXR5IGFuZCByZWxpYWJpbGl0eSBvZiBhbiBpbnN0cnVtZW50LiBUaGUgKipkb3VibHkgd2VpZ2h0ZWQgYXZlcmFnZSoqIG9mIHRoZSBvcmlnaW5hbCBjb21wb3NpdGUgc2NvcmVzIG9mIHRlYWNoaW5nIHN0cmF0ZWdpZXMgYW5kIGFwcGVuZGVkIHRvIHRoZSBhbmFseXRpYyBkYXRhc2V0Lg0KDQpgYGB7cn0NCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIA0KIyMjIyMgDQpzY29yZXMgPSBmdW5jdGlvbihkZiwgZG4pew0KICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiAgIyMgc2luZ2xlIGZhY3RvciBzY29yZQ0KICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KICB4LnZhciA8LSBuYW1lcyhkZikNCiAgbjAgPC0gbGVuZ3RoKHgudmFyKQ0KICBjZmEubW9kZWwgPC0gIHBhc3RlKCJsYXRlbnQgPX4iLCBwYXN0ZSh4LnZhciwgY29sbGFwc2UgPSAiICsgIikpDQogIGNmYS5maXQgPC0gY2ZhKGNmYS5tb2RlbCwgZGF0YSA9IGRmLCBlc3RpbWF0b3IgPSAiTUxNIikNCiAgY29tcG9zaXRlLmNmYSA8LSBsYXZQcmVkaWN0KGNmYS5maXQpDQogICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQogICMgcGNhIGFuYWx5c2lzDQogICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQogIHBjYS5tZGwgPC0gcHJjb21wKGRmLCBzY2FsZSA9IFRSVUUpDQogIHBjYTAgPC0gcGNhLm1kbCR4WywgMV0NCiAgcjAgPSBjb3IocGNhMCwgY29tcG9zaXRlLmNmYSkNCiAgaWYocjAgPCAwKSB7DQogICAgIHBjYS5hbGwgPC0gLXBjYS5tZGwkeA0KICB9ZWxzZXsNCiAgICBwY2EuYWxsIDwtIHBjYS5tZGwkeA0KICB9DQogIGZpcnN0LnBjYSA9IHBjYS5hbGxbLDFdDQogICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQogICMgd2VpZ2h0ZWQgcGNhIHNjb3JlDQogICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQogIHZhci5leHBsYWluZWQgPC0oKHBjYS5tZGwkc2RldileMikgLyBzdW0oKHBjYS5tZGwkc2RldileMikgIw0KICBjb21wb3NpdGVfd2VpZ2h0ZWRfcGNhIDwtIGFzLm1hdHJpeChwY2EuYWxsKSAlKiUgKHZhci5leHBsYWluZWQpDQoNCiAgb3V0ZGF0YSA8LSBhcy5kYXRhLmZyYW1lKGNiaW5kKHBjYTEgPSBmaXJzdC5wY2EsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgd3QucGNhID0gYXMudmVjdG9yKGNvbXBvc2l0ZV93ZWlnaHRlZF9wY2EpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNmYSA9IGFzLnZlY3Rvcihjb21wb3NpdGUuY2ZhKSkpDQogIG5hbWVzKG91dGRhdGEpIDwtIHBhc3RlMChkbiwiLiIsIG5hbWVzKG91dGRhdGEpLCBzZXAgPSAiIikNCiAgb3V0ZGF0YQ0KIH0NCiMjIw0KdGVhY2hlciA8LSBzY29yZXModGVhY2hlciwgIlRlYWNoZXIuY3RyZCIpDQpzdHVkZW50IDwtIHNjb3JlcyhzdHVkZW50LCAiU3R1ZGVudC5jdHJkIikNCkFueGlldHkuQW5hbHl0aWMuRGF0YSA8LSBjYmluZChmaW5hbERhdCwgdGVhY2hlciwgc3R1ZGVudCkNCmBgYA0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGV2YWwgPSBGQUxTRX0NCndyaXRlLmNzdihBbnhpZXR5LkFuYWx5dGljLkRhdGEsICJDOlxcVXNlcnNcXDc1Q1BFTkdcXE9uZURyaXZlIC0gV2VzdCBDaGVzdGVyIFVuaXZlcnNpdHkgb2YgUEFcXERlc2t0b3BcXGNwZW5nXFxXQ1UtVGVhY2hpbmdcXDIwMjVGYWxsXFxNYXRoQXhpZXR5XFxBbnhpZXR5LkFuYWx5dGljLkRhdGEuY3N2IikNCmBgYA0KDQojIExpbmVhciBSZWdyZXNzaW9uIEFuYWx5c2lzDQoNClRoaXMgc2VjdGlvbiBtb3ZlcyBmcm9tIHRoZSBwcmV2aW91cyBkZXNjcmlwdGl2ZSBhbmFseXNlcyB0byBhIHJlZ3Jlc3Npb24gYW5hbHlzaXMgb2YgdGhlIGFzc29jaWF0aW9uIGJldHdlZW4gbWF0aCBhbnhpZXR5IGFuZCByZWxhdGVkIGZhY3RvcnMuIFdlIGV4YW1pbmUgdHdvIGRpc3RpbmN0IGJ1dCBpbnRlcmNvbm5lY3RlZCB0eXBlcyBvZiBtYXRoIGFueGlldHksIGV2YWx1YXRpb24gYW54aWV0eSBhbmQgbGVhcm5pbmcgYW54aWV0eSwgd2hpbGUgdGVtcG9yYXJpbHkgc2V0dGluZyBhc2lkZSB0aGVpciBpbnRlcmNvbm5lY3Rpb24uDQoNClRoZSByZWdyZXNzaW9uIG1vZGVsIGFsc28gaW5jb3Jwb3JhdGVzIHRoZSB0d28gdGVhY2hpbmcgc3RyYXRlZ2llcyBhcyBwcmVkaWN0b3IgdmFyaWFibGVzLiBXZSBhbHNvIHJlYWxpemVkIHRoYXQgdGhlIHR3byB2YXJpYWJsZXMgYXJlIGNvcnJlbGF0ZWQuDQoNCmBgYHtyIGVjaG8gPSBGQUxTRSwgZXZhbCA9IFRSVUV9DQphbnhpZXR5LmluZi5kYXRhMCA8LSByZWFkLmNzdigiaHR0cHM6Ly9wZW5nZHNjaS5naXRodWIuaW8vTWF0aEFueGlldHkvQW54aWV0eS5BbmFseXRpYy5EYXRhLmNzdiIpDQppbmYudmFyIDwtIGMoIkFueGlldHkubWVhLnd0LnBjYSIsICJBbnhpZXR5Lm1sYS53dC5wY2EiLCAic2V4IiwgInJhY2UiLCAiY2xhc3MiLCAibWFqb3IiLCAibWF0aC5sZXZlbCIsICJtb2RhbGl0eSIsICJTZWxmRWZmaWNhY3kud3QucGNhIiwgIlRlY2hub2xvZ3kud3QucGNhIiwNCiAiQ29vcG9yYXRpdmUud3QucGNhIiwgIkRlZHVjdGl2ZS53dC5wY2EiLCAiRGVtb25zdHJhdGlvbi53dC5wY2EiLCAiSW5kdWN0aXZlLnd0LnBjYSIsICAgICJJbnRlZ3JhdGl2ZS53dC5wY2EiLCAiTGVjdHVyZVR5cGUud3QucGNhIiwgIlJlcGV0aXRpdmUud3QucGNhIiwgIkVuZ2FnZS53dC5wY2EiLCAiUmVzb3VyY2Uud3QucGNhIiwiVGVhY2hlci5jdHJkLnd0LnBjYSIsICJTdHVkZW50LmN0cmQud3QucGNhIikNCiMjDQphbnhpZXR5LnJlZy5kYXRhIDwtIGFueGlldHkuaW5mLmRhdGEwWywgaW5mLnZhcl0NCnJlZy52YXIubmFtZSA8LSBjKCJNRUEiLCAiTUxBIiwgInNleCIsICJyYWNlIiwgImNsYXNzIiwgIm1ham9yIiwgIm1hdGgubGV2ZWwiLCAibW9kYWxpdHkiLCAiU2VsZkVmZmljYWN5IiwgIlRlY2hub2xvZ3kiLA0KICJDb29wb3JhdGl2ZSIsICJEZWR1Y3RpdmUiLCAiRGVtb25zdHJhdGlvbiIsICJJbmR1Y3RpdmUiLCAgICAiSW50ZWdyYXRpdmUiLCAiTGVjdHVyZSIsICJSZXBldGl0aXZlIiwgIkVuZ2FnZSIsICJSZXNvdXJjZSIsIlRlYWNoZXJDdHJkIiwgIlN0dWRlbnRDdHJkIikNCm5hbWVzKGFueGlldHkucmVnLmRhdGEpIDwtIHJlZy52YXIubmFtZSANCmBgYA0KDQojIyBGYWN0b3JzIEFzc29jaWF0ZWQgd2l0aCBFdmFsdWF0aW9uIEFueGlldHkNCg0KRm9yIHRoZSBhc3NvY2lhdGlvbiBhbmFseXNpcywgd2Ugd2lsbCBidWlsZCB0d28gcmVncmVzc2lvbiBtb2RlbHMuIEJvdGggbW9kZWxzIGluY2x1ZGUgYSBjb21tb24gc2V0IG9mIGRlbW9ncmFwaGljIHByZWRpY3RvcnMuIFRoZSBmaXJzdCBtb2RlbCB1c2VzIGluZGl2aWR1YWwgdGVhY2hpbmcgc3RyYXRlZ2llcyBhcyBhZGRpdGlvbmFsIHByZWRpY3RvcnMsIHdoaWxlIHRoZSBzZWNvbmQgdXNlcyBncm91cGVkIHRlYWNoaW5nIHN0cmF0ZWdpZXMuDQoNCiMjIyBVc2luZyBJbmRpdmlkdWFsIFRlYWNoaW5nIFN0cmF0ZWdpZXMNCg0KVGhlIGFuYWx5c2lzIGJlZ2lucyB3aXRoIGEgcmVncmVzc2lvbiBtb2RlbCBpbmNvcnBvcmF0aW5nIGFsbCBpbmRpdmlkdWFsIHRlYWNoaW5nIGFwcHJvYWNoZXMgYWxvbmdzaWRlIGRlbW9ncmFwaGljIGFuZCByZWxhdGVkIHZhcmlhYmxlcyBhcyBwcmVkaWN0b3JzLg0KDQpgYGB7cn0NCkJlc3RTdWJzZXRzUmVnIDwtIGZ1bmN0aW9uKGJlc3Quc3Vic2V0Lm1vZGVsKXsNCiAgICMgVmlldyB0aGUgcmVzdWx0cw0KICAgcmVnLnN1bW1hcnkgPC0gc3VtbWFyeShiZXN0LnN1YnNldC5tb2RlbCkNCiANCiAgICMgUGxvdHRpbmcgdGhlIHJlc3VsdHMgKG9wdGlvbmFsLCBmb3IgdmlzdWFsaXphdGlvbikNCiAgICMgcGxvdChiZXN0LnN1YnNldC5tb2RlbCwgc2NhbGUgPSAiYWRqcjIiLCBjb2wgPSAic2t5Ymx1ZSIpICMgb3IgImJpYyIsICJjcCIsIGV0Yy4NCiAgIHBhcihtZnJvdyA9IGMoMiwyKSkNCiAgIHBsb3QocmVnLnN1bW1hcnkkcnNzLCB4bGFiID0gIk51bWJlciBvZiBWYXJpYWJsZXMiLCB5bGFiID0gIlJTUyIsIHR5cGUgPSAibCIsIGNvbCA9ICJuYXZ5IikNCiAgIHBsb3QocmVnLnN1bW1hcnkkYWRqcjIsIHhsYWIgPSAiTnVtYmVyIG9mIFZhcmlhYmxlcyIsIHlsYWIgPSAiQWRqdXN0ZWQgUlNxIiwgdHlwZSA9ICJsIiwgY29sID0gIm5hdnkiKQ0KICAgIyBXZSB3aWxsIG5vdyBwbG90IGEgcmVkIGRvdCB0byBpbmRpY2F0ZSB0aGUgbW9kZWwgd2l0aCB0aGUgbGFyZ2VzdCBhZGp1c3RlZCBSXjIgc3RhdGlzdGljLg0KICAgIyBUaGUgd2hpY2gubWF4KCkgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gaWRlbnRpZnkgdGhlIGxvY2F0aW9uIG9mIHRoZSBtYXhpbXVtIHBvaW50IG9mIGEgdmVjdG9yDQogICBhZGoucjIubWF4ID0gd2hpY2gubWF4KHJlZy5zdW1tYXJ5JGFkanIyKSANCg0KICAgIyBUaGUgcG9pbnRzKCkgY29tbWFuZCB3b3JrcyBsaWtlIHRoZSBwbG90KCkgY29tbWFuZCwgZXhjZXB0IHRoYXQgaXQgcHV0cyBwb2ludHMgDQogICAjIG9uIGEgcGxvdCB0aGF0IGhhcyBhbHJlYWR5IGJlZW4gY3JlYXRlZCBpbnN0ZWFkIG9mIGNyZWF0aW5nIGEgbmV3IHBsb3QNCiAgIHBvaW50cyhhZGoucjIubWF4LCByZWcuc3VtbWFyeSRhZGpyMlthZGoucjIubWF4XSwgY29sID0iZGFya3JlZCIsIGNleCA9IDIsIHBjaCA9IDIwKQ0KICAgIyBXZSdsbCBkbyB0aGUgc2FtZSBmb3IgQ19wIGFuZCBCSUMsIHRoaXMgdGltZSBsb29raW5nIGZvciB0aGUgbW9kZWxzIHdpdGggdGhlIFNNQUxMRVNUIHN0YXRpc3RpYw0KICAgcGxvdChyZWcuc3VtbWFyeSRjcCwgeGxhYiA9ICJOdW1iZXIgb2YgVmFyaWFibGVzIiwgeWxhYiA9ICJDcCIsIHR5cGUgPSAibCIpDQogICBjcC5taW4gPSB3aGljaC5taW4ocmVnLnN1bW1hcnkkY3ApICMgMTANCiAgIHBvaW50cyhjcC5taW4sIHJlZy5zdW1tYXJ5JGNwW2NwLm1pbl0sIGNvbCA9ICJkYXJrcmVkIiwgY2V4ID0gMiwgcGNoID0gMjApDQoNCiAgIHBsb3QocmVnLnN1bW1hcnkkYmljLCB4bGFiID0gIk51bWJlciBvZiBWYXJpYWJsZXMiLCB5bGFiID0gIkJJQyIsIHR5cGUgPSAibCIpDQogICBiaWMubWluID0gd2hpY2gubWluKHJlZy5zdW1tYXJ5JGJpYykgIyA2DQogICBwb2ludHMoYmljLm1pbiwgcmVnLnN1bW1hcnkkYmljW2JpYy5taW5dLCBjb2wgPSAiZGFya3JlZCIsIGNleCA9IDIsIHBjaCA9IDIwKQ0KfQ0KYGBgDQoNCldlIHVzZSB0aGUgYmVzdCBzdWJzZXQgYXBwcm9hY2ggdG8gbW9kZWwgaWRlbnRpZmljYXRpb24uIFRoZSBmb2xsb3dpbmcgYXJlIHBsb3RzIG9mIGEgZmV3IHBlcmZvcm1hbmNlIG1lYXN1cmVzIGFnYWlzdCB0aGUgbnVtYmVyIG9mIHByZWRpY3RvciB2YXJpYWJsZXMgdG8gYmUgcmV0YWluZWQgaW4gdGhlIGZpbmFsIG1vZGVsLg0KDQpgYGB7ciBlY2hvID0gVFJVRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD02fQ0KbWVhLmxtLmRhdGEgPC0gYW54aWV0eS5yZWcuZGF0YVssLWMoMiwyMCwyMSldDQptZWEuYmVzdC5zdWJzZXRzLmxtIDwtIHJlZ3N1YnNldHMoTUVBIH4uLCBkYXRhID0gbWVhLmxtLmRhdGEsIG52bWF4ID0gOCwgIG1ldGhvZCA9ICJiYWNrd2FyZCIgKQ0KQmVzdFN1YnNldHNSZWcobWVhLmJlc3Quc3Vic2V0cy5sbSkNCmBgYA0KDQpUaGUgYWJvdmUgZmlndXJlIGluZGljYXRlcyB0aGF0IHRoZSA2LXByZWRpY3RvciBtb2RlbCBpcyB0aGUgb3B0aW1hbCBjaG9pY2UuIFRoZSByZXN1bHRzIG9idGFpbmVkIGZyb20gdGhpcyBzdWJzZXQgc2VsZWN0aW9uIG1ldGhvZCBhcmUgaWRlbnRpY2FsIHRvIHRob3NlIG9idGFpbmVkIHZpYSBzdGVwd2lzZSB2YXJpYWJsZSBzZWxlY3Rpb24uDQoNCmBgYHtyIGVjaG8gPSBUUlVFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTd9DQptZWEubG0uZGF0YSA8LSBhbnhpZXR5LnJlZy5kYXRhWywtYygyLDIwLDIxKV0NCm1lYS5sbSA8LSBsbShNRUEgflNlbGZFZmZpY2FjeSArIEluZHVjdGl2ZSArIEludGVncmF0aXZlICsgbWF0aC5sZXZlbCArIHNleCArDQogICAgVGVjaG5vbG9neSwgZGF0YSA9IG1lYS5sbS5kYXRhKQ0Kc3RlcHdpc2UubWVhLm1vZGVsIDwtIHN0ZXBBSUMobWVhLmxtLCBkaXJlY3Rpb24gPSAiYm90aCIsIHRyYWNlID0gMCkNCiNzdW1tYXJ5KHN0ZXB3aXNlLm1lYS5tb2RlbCkNCnBhcihtZnJvdyA9IGMoMiwyKSkNCnBsb3Qoc3RlcHdpc2UubWVhLm1vZGVsICkNCmBgYA0KDQpUaGUgZmlndXJlIGFib3ZlIHJldmVhbHMgYSBjbGVhciBwYXR0ZXJuIG9mIG5vbi1jb25zdGFudCByZXNpZHVhbCB2YXJpYW5jZSAoaGV0ZXJvc2NlZGFzdGljaXR5KSBhcyB0aGUgZml0dGVkIHZhbHVlcyBpbmNyZWFzZS4gQmVjYXVzZSB0aGUgcmVzcG9uc2UgdmFyaWFibGUgaW5jbHVkZXMgbmVnYXRpdmUgdmFsdWVzLCBhIHN0YW5kYXJkIEJveC1Db3ggdHJhbnNmb3JtYXRpb24gaXMgbm90IGFwcGxpY2FibGUgZm9yIGlkZW50aWZ5aW5nIGEgcG93ZXIgdHJhbnNmb3JtYXRpb24uIEluc3RlYWQsIHdlIHdpbGwgdXNlIGJvb3RzdHJhcCBjb25maWRlbmNlIGludGVydmFscyBmb3IgYWxsIHJlZ3Jlc3Npb24gY29lZmZpY2llbnRzIHRvIGFzc2VzcyB0aGVpciBzaWduaWZpY2FuY2UsIHRoZXJlYnkgbWFpbnRhaW5pbmcgdGhlIHJlc3BvbnNlIHZhcmlhYmxlIG9uIGl0cyBvcmlnaW5hbCBzY2FsZS4NCg0KYGBge3J9DQojIyMgQm9vdHN0cmFwIGNvbmZpZGVuY2UgaW50ZXJ2YWxzDQpib290LmNvZWYgPC0gZnVuY3Rpb24oZGF0YSwgaW5kaWNlcykgew0KICBkIDwtIGRhdGFbaW5kaWNlcywgXSAgIyByZXNhbXBsZSByb3dzDQogIGZpdCA8LSBsbShNRUEgfiBTZWxmRWZmaWNhY3kgKyBJbnRlZ3JhdGl2ZSArIG1hdGgubGV2ZWwgKyANCiAgICBzZXggKyBUZWNobm9sb2d5LCBkYXRhID0gZCkNCiAgcmV0dXJuKGNvZWYoZml0KSkgICAgICAjIHJldHVybiBjb2VmZmljaWVudHMNCn0NCiMjIyMjIw0KIyBFeHRyYWN0IENJcyBmb3IgYWxsIGNvZWZmaWNpZW50cw0KZ2V0LmFsbC5ib290LmNpcyA8LSBmdW5jdGlvbihib290Lm91dHB1dCwgdHlwZSA9ICJwZXJjIikgew0KICBuLmNvZWYgPC0gbmNvbChib290Lm91dHB1dCR0KQ0KICBjaS5tYXRyaXggPC0gbWF0cml4KE5BLCBucm93ID0gbi5jb2VmLCBuY29sID0gMikNCiAgcm93bmFtZXMoY2kubWF0cml4KSA8LSBjb2xuYW1lcyhib290Lm91dHB1dCR0KQ0KICBjb2xuYW1lcyhjaS5tYXRyaXgpIDwtIGMoImJ0Lmxvdy45NSUiLCAiYnQudXAuOTUlIikNCiAgDQogIGZvciAoaSBpbiAxOm4uY29lZikgew0KICAgIGNpLm9iaiA8LSBib290LmNpKGJvb3Qub3V0cHV0LCB0eXBlID0gdHlwZSwgaW5kZXggPSBpKQ0KICAgIGlmICh0eXBlID09ICJwZXJjIikgew0KICAgICAgY2kubWF0cml4W2ksIF0gPC0gY2kub2JqJHBlcmNlbnRbNDo1XQ0KICAgIH0NCiAgfQ0KICANCiAgcmV0dXJuKGNpLm1hdHJpeCkNCn0NCg0KIyBQZXJmb3JtIGJvb3RzdHJhcCAoUiA9IG51bWJlciBvZiByZXNhbXBsZXMpDQpzZXQuc2VlZCgzMTEpICAjIGZvciByZXByb2R1Y2liaWxpdHkNCmJvb3QucmVzdWx0cyA8LSBib290KG1lYS5sbS5kYXRhLCBib290LmNvZWYsIFIgPSAxMDAwKQ0KIyMgYm9vdHN0cmFwIENJDQphbGwuY2lzIDwtIGdldC5hbGwuYm9vdC5jaXMoYm9vdC5yZXN1bHRzKQ0KSW5mZXJlbmNlVGFibGUgPC0gcm91bmQoY2JpbmQoc3VtbWFyeShzdGVwd2lzZS5tZWEubW9kZWwpJGNvZWYsIGFsbC5jaXMpLDQpDQpwcmludChJbmZlcmVuY2VUYWJsZSkgDQpgYGANCg0KVGhlIGFib3ZlIHRhYmxlIHJldmVhbGVkIHNldmVyYWwgc2lnbmlmaWNhbnQgcHJlZGljdG9ycyBvZiBtYXRoIGV2YWx1YXRpb24gYW54aWV0eS4gSGlnaGVyICoqc2VsZi1lZmZpY2FjeSoqIHdhcyBzdHJvbmdseSBhc3NvY2lhdGVkIHdpdGggbG93ZXIgYW54aWV0eSAoJFxiZXRhID0gLTAuNTc3LCBwIDwgMC4wMDEkKSwgaW5kaWNhdGluZyB0aGF0IHN0dWRlbnRzIHdobyBhcmUgbW9yZSBjb25maWRlbnQgaW4gdGhlaXIgbWF0aGVtYXRpY2FsIGFiaWxpdGllcyBleHBlcmllbmNlIGxlc3MgKipldmFsdWF0aW9uLXJlbGF0ZWQgc3RyZXNzKiouIFNpbWlsYXJseSwgKippbnRlZ3JhdGl2ZSBpbnN0cnVjdGlvbiBhcHByb2FjaCoqIHNob3dlZCBhIG5lZ2F0aXZlIHJlbGF0aW9uc2hpcCB3aXRoIGFueGlldHkgKCRcYmV0YSA9IC0wLjE3OCwgcCA8IDAuMDAxJCksIGltcGx5aW5nIHRoYXQgdGhpcyB0ZWFjaGluZyBtZXRob2QgbWF5IGhlbHAgcmVkdWNlIHN0dWRlbnQgYW54aWV0eS4gKipDb3Vyc2UgbGV2ZWwqKiBhbHNvIHBsYXllZCBhIHJvbGU6IHN0dWRlbnRzIGVucm9sbGVkIGluIG1hdGgwMyAoY2FsYyBBIGFuZCBicmllZiBDYWxjKSAoJFxiZXRhID0gMC4yNzYsIHAgPSAwLjA0MCQpIGFuZCBtYXRoMDQgKGFib3ZlIENhbGMgQSkgKCRcYmV0YSA9IDAuMzYzLCBwID0gMC4wMjMkKSBjb3Vyc2VzIGV4aGliaXRlZCBoaWdoZXIgYW54aWV0eSBjb21wYXJlZCB0byB0aGUgcmVmZXJlbmNlIGdyb3VwLCB3aGlsZSBvdGhlciBjb3Vyc2UgbGV2ZWxzIHdlcmUgbm90IHNpZ25pZmljYW50LiAqKkdlbmRlcioqIHdhcyBhIHNpZ25pZmljYW50IGZhY3Rvciwgd2l0aCBtYWxlIHN0dWRlbnRzIHJlcG9ydGluZyBsb3dlciBhbnhpZXR5IHRoYW4gZmVtYWxlcyAoJFxiZXRhID0gLTAuMzQ0LCBwIDwgMC4wMDEkKS4gRmluYWxseSwgKip0ZWNobm9sb2d5IHVzZSoqIHdhcyBuZWdhdGl2ZWx5IGFzc29jaWF0ZWQgd2l0aCBhbnhpZXR5ICgkXGJldGEgPSAtMC4xMzcsIHAgPCAwLjAwMSQpLCBpbmRpY2F0aW5nIHRoYXQgZ3JlYXRlciBlbmdhZ2VtZW50IHdpdGggdGVjaG5vbG9neSBjb3JyZXNwb25kcyB0byByZWR1Y2VkIG1hdGggZXZhbHVhdGlvbiBhbnhpZXR5Lg0KDQpJbiBzdW1tYXJ5LCBtYXRoIGV2YWx1YXRpb24gYW54aWV0eSB3YXMgc2lnbmlmaWNhbnRseSBsb3dlciBhbW9uZyBzdHVkZW50cyB3aXRoIGhpZ2hlciAqKnNlbGYtZWZmaWNhY3kqKi4gQW4gKippbnRlZ3JhdGl2ZSB0ZWFjaGluZyBhcHByb2FjaCoqIGFuZCBhcHByb3ByaWF0ZSAqKnVzZSBvZiB0ZWNobm9sb2d5KiogbWF5IGhlbHAgcmVkdWNlIG1hdGggZXZhbHVhdGlvbiBhbnhpZXR5LiBNYWxlIHN0dWRlbnRzIHRlbmRlZCB0byBleHBlcmllbmNlIGxlc3Mgc3RyZXNzLiBDb252ZXJzZWx5LCBzdHVkZW50cyBlbnJvbGxlZCBpbiBoaWdoZXItbGV2ZWwgbWF0aCBjb3Vyc2VzIChtYXRoMDMgYW5kIG1hdGgwNCkgcmVwb3J0ZWQgc2xpZ2h0bHkgaGlnaGVyIGFueGlldHkuDQoNCiMjIyBVc2luZyBHcm91cGVkIFRlYWNoaW5nIFN0cmF0ZWdpZXMNCg0KTmV4dCwgd2UgYnVpbGQgYSByZWdyZXNzaW9uIG1vZGVsIHVzaW5nIHRoZSBhZ2dyZWdhdGVkIHRlYWNoaW5nIHN0eWxlczogdGVhY2hlci1jZW50ZXJlZCBhbmQgc3R1ZGVudC1jZW50ZXJlZCwgcGx1cyBzb21lIGRlbW9ncmFwaGljIGZhY3RvcnMuIFdlIHdpbGwgc3RpbGwgdXNlIHRoZSBiZXN0IHN1YnNldCBzZWxlY3Rpb24gbWV0aG9kIGpvaW50bHkgd2l0aCBvdGhlciByZWxhdGVkIG1ldGhvZHMgdG8gaWRlbnRpZnkgdGhlIGZpbmFsIG1vZGVsLg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTZ9DQojIFBlcmZvcm0gYmVzdCBzdWJzZXQgc2VsZWN0aW9uDQojICdudm1heCcgc3BlY2lmaWVzIHRoZSBtYXhpbXVtIG51bWJlciBvZiB2YXJpYWJsZXMgdG8gY29uc2lkZXIgaW4gYSBzdWJzZXQNCmJlc3Quc3Vic2V0Lm1vZGVsLmN0cmQgPC0gcmVnc3Vic2V0cyhNRUF+IHNleCsgcmFjZSsgY2xhc3MrIG1ham9yKyBtYXRoLmxldmVsKyBtb2RhbGl0eSsgU2VsZkVmZmljYWN5KyBUZWNobm9sb2d5ICsgVGVhY2hlckN0cmQrIFN0dWRlbnRDdHJkLCBkYXRhID0gYW54aWV0eS5yZWcuZGF0YSwgbnZtYXggPSAxMCwgIG1ldGhvZCA9ICJiYWNrd2FyZCIgKQ0KQmVzdFN1YnNldHNSZWcoYmVzdC5zdWJzZXQubW9kZWwuY3RyZCkNCmBgYA0KDQpUaGUgZm9sbG93aW5nIHJlc2lkdWFsIGRpYWdub3N0aWMgcGxvdHMgaW5kaWNhdGUgYWJub3JtYWwgcGF0dGVybnMuIFBhcnRpY3VsYXIsIG5vbi1jb25zdGFudCB2YXJpYW5jZSBvZiB0aGUgcmVzaWR1YWwgdmFyaWFuY2UuDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9Nn0NCiMgVGhlIGZpbmFsIG1vZGVsDQpiZXN0LnN1YnNldC5jdHJkIDwtIGxtKE1FQX4gc2V4KyBtYXRoLmxldmVsKyAgU2VsZkVmZmljYWN5KyBUZWNobm9sb2d5ICsgU3R1ZGVudEN0cmQsIGRhdGEgPSBhbnhpZXR5LnJlZy5kYXRhKQ0KI3N1bW1hcnkoYmVzdC5zdWJzZXQuY3RyZCkkY29lZg0KcGFyKG1mcm93ID0gYygyLDIpKQ0KcGxvdChiZXN0LnN1YnNldC5jdHJkKQ0KYGBgDQoNCldlIG5leHQgcGVyZm9ybSBCb290c3RyYXAgcmVncmVzc2lvbiB0byBjb25zdHJ1Y3Qgcm9idXN0IGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGZvciB0aGUgcmVncmVzc2lvbiBjb2VmZmljaWVudHMuDQoNCmBgYHtyfQ0KIyMjIEJvb3RzdHJhcCBjb25maWRlbmNlIGludGVydmFscw0KYm9vdC5jb2VmLmN0cmQgPC0gZnVuY3Rpb24oZGF0YSwgaW5kaWNlcykgew0KICBkIDwtIGRhdGFbaW5kaWNlcywgXSAgIyByZXNhbXBsZSByb3dzDQogIGZpdCA8LSBsbShNRUF+IHNleCsgbWF0aC5sZXZlbCsgIFNlbGZFZmZpY2FjeSsgVGVjaG5vbG9neSArIFN0dWRlbnRDdHJkLCBkYXRhID0gZCkNCiAgcmV0dXJuKGNvZWYoZml0KSkgICAgICAjIHJldHVybiBjb2VmZmljaWVudHMNCn0NCg0KIyBQZXJmb3JtIGJvb3RzdHJhcCAoUiA9IG51bWJlciBvZiByZXNhbXBsZXMpDQpzZXQuc2VlZCgzMTIpICAjIGZvciByZXByb2R1Y2liaWxpdHkNCmJvb3QucmVzdWx0cy5jdHJkIDwtIGJvb3QoYW54aWV0eS5yZWcuZGF0YSwgYm9vdC5jb2VmLmN0cmQsIFIgPSAxMDAwKQ0KIyBDb21iaW5lIHRoZSBsaW5lYXIgcmVncmVzc2lvbiBvdXRwdXQgd2l0aCB0aGUgYm9vdHN0cmFwIENJDQphbGwuY3RyZC5jaXMgPC0gZ2V0LmFsbC5ib290LmNpcyhib290LnJlc3VsdHMuY3RyZCApDQpJbmZlcmVuY2VUYWJsZSA8LSByb3VuZChjYmluZChzdW1tYXJ5KGJlc3Quc3Vic2V0LmN0cmQpJGNvZWYsIGFsbC5jdHJkLmNpcyApLDQpDQpwcmludChJbmZlcmVuY2VUYWJsZSkgDQpgYGANCg0KVGhlIHJlc3VsdHMgYWJvdmUgYXJlIGNvbnNpc3RlbnQgd2l0aCB0aGUgcHJldmlvdXMgcmVncmVzc2lvbiB0aGF0IHVzZWQgaW5kaXZpZHVhbCB0ZWFjaGluZyBzdHJhdGVnaWVzIGFzIHByZWRpY3RvcnMuIFRoZSBrZXkgZGlmZmVyZW5jZSBpcyB0aGF0IHRoZSAqKmludGVncmF0aXZlIHRlYWNoaW5nIGFwcHJvYWNoKiogd2FzIHNpZ25pZmljYW50IGluIHRoZSBmb3JtZXIgbW9kZWwsIHdoZXJlYXMgKipzdHVkZW50LWNlbnRlcmVkKiogdGVhY2hpbmcgc3RyYXRlZ2llcyBhcmUgc2lnbmlmaWNhbnQgaW4gdGhlIGN1cnJlbnQgb25lLiBIb3dldmVyLCBzaW5jZSBhbiBpbnRlZ3JhdGl2ZSBhcHByb2FjaCBpcyBhIHNwZWNpZmljIHR5cGUgb2Ygc3R1ZGVudC1jZW50ZXJlZCBzdHJhdGVneSwgdGhlIG1vZGVscyB1bHRpbWF0ZWx5IHlpZWxkIGNvbmdydWVudCBmaW5kaW5ncy4NCg0KIyMgRmFjdG9ycyBBc3NvY2lhdGVkIHdpdGggTGVhcm5pbmcgQW54aWV0eQ0KDQpVbmxpa2UgbWF0aCBldmFsdWF0aW9uIGFueGlldHksIHdoaWNoIGlzIGZ1ZWxlZCBtb3JlIGJ5IGVtb3Rpb25hbCBhbmQgZW52aXJvbm1lbnRhbCBmYWN0b3JzLCBtYXRoIGxlYXJuaW5nIGFueGlldHkgaXMgYSBkaXJlY3QgcmVzcG9uc2UgdG8gdGhlIGxlYXJuaW5nIGVjb3N5c3RlbS4gSXQgaXMgY2xvc2VseSBsaW5rZWQgdG8gdGhlIGRlbnNpdHkgb2YgdGhlIGxlYXJuaW5nIG1hdGVyaWFscywgdGhlIHNpZ25pZmljYW50IGNvZ25pdGl2ZSBsb2FkIHJlcXVpcmVkIGZvciBwcm9ibGVtLXNvbHZpbmcsIGFuZCBjcml0aWNhbCBleHRlcm5hbCBmYWN0b3JzIHN1Y2ggYXMgaW5zdHJ1Y3RvcnMnIHRlYWNoaW5nIHN0cmF0ZWdpZXMuDQoNClRoZSBuZXh0IHJlZ3Jlc3Npb24gbW9kZWwgYWltcyB0byBpZGVudGlmeSBmYWN0b3JzIHRoYXQgYXJlIGRpcmVjdGx5IGFzc29jaWF0ZWQgd2l0aCB0aGUgbWF0aCBsZWFybmluZyBhbnhpZXR5LiBXZSBzdGlsbCB0YWtlIHRoZSBiZXN0IHN1YnNldCBzZWxlY3Rpb24gYXBwcm9hY2ggdG8gaWRlbnRpZnlpbmcgdGhlIGJlc3QgbW9kZWwuDQoNCiMjIyBVc2luZyBJbmRpdmlkdWFsIFRlYWNoaW5nIFN0cmF0ZWdpZXMNCg0KVGhlIGZvbGxvd2luZyBtb2RlbCB1c2VzIGluZGl2aWR1YWwgdGVhY2hpbmcgc3RyYXRlZ2llcyBhcyBwcmVkaWN0b3JzLiBUaGlzIHdpbGwgaGVscCBpZGVudGlmeSBwYXJ0aWN1bGFyIHRlYWNoaW5nIHN0cmF0ZWdpZXMgdGhhdCBhcmUgc2lnbmlmaWNhbnRseSBhc3NvY2lhdGVkIHdpdGggdGhlIGxlYW5pbmcgYW54aWV0eS4NCg0KYGBge3IgZWNobyA9IFRSVUUsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9Nn0NCm1sYS5sbS5kYXRhIDwtIGFueGlldHkucmVnLmRhdGFbLC1jKDEsMjAsMjEpXQ0KbWxhLmZ1bGwubG0gPC0gbG0oTUxBIH4uLCBkYXRhID0gbWxhLmxtLmRhdGEpDQpwYXIobWZyb3cgPSBjKDIsMikpDQpwbG90KG1sYS5mdWxsLmxtKQ0KI3N1bW1hcnkobWxhLmZ1bGwubG0pDQpgYGANCg0KVGhpcyBpbml0aWFsIG1vZGVsJ3MgcmVzaWR1YWwgZGlhZ25vc3RpYyBwbG90IHNob3dzIG5vbi1jb25zdGFudCB2YXJpYW5jZS4gV2Ugd2lsbCBub3QgcGVyZm9ybSBhbnkgcG93ZXIgdHJhbnNmb3JtYXRpb25zIG9uIHRoZSByZXNwb25zZSB2YXJpYWJsZSBmb3IgdGhlIHNhbWUgcmVhc29ucyBzdGF0ZWQgaW4gdGhlIHByZXZpb3VzIHN1YnNlY3Rpb24uIFRoZSBpbmZlcmVuY2Ugb24gdGhlIHJlZ3Jlc3Npb24gY29lZmZpY2llbnRzIHdpbGwgYmFzZWQgb24gbm9ucGFyYW1ldHJpYyBCb290c3RyYXAgYW5kIHRoZSBjbGFzc2ljYWwgdC10ZXN0cy4NCg0KV2UgbmV4dCB1c2UgYmVzdCBzdWJzZXQgbW9kZWwgc2VsZWN0aW9uIGFwcHJvYWNoIHRvIGlkZW50aWZ5IHRoZSBvcHRpbWFsIG1vZGVsIHVzaW5nIHZhcmlvdXMgcGVyZm9ybWFuY2UgbWVhc3VyZXMgc3VjaCBhcyBDcCwgQklDLCBBZGp1c3RlZCBjb2VmZmljaWVudCBvZiBkZXRlcm1pbmF0aW9uIGFuZCB0aGUgbGlzdCBvZiB0aGUgc2lnbmlmaWNhbnQgcHJlZGljdG9ycyBpbiB0aGUgaW5pdGlhbCBtb2RlbCB3aXRoIG1vc3Qgb2YgdGhlIGNhbmRpZGF0ZSBwcmVkaWN0b3IgdmFyaWFibGVzLg0KDQpgYGB7ciBlY2hvID0gVFJVRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD02fQ0KbWxhLmJlc3Quc3Vic2V0cy5sbSA8LSByZWdzdWJzZXRzKE1MQSB+LiwgZGF0YSA9IG1sYS5sbS5kYXRhLCBudm1heCA9IDE2LCAgbWV0aG9kID0gImJhY2t3YXJkIiApDQpCZXN0U3Vic2V0c1JlZyhtbGEuYmVzdC5zdWJzZXRzLmxtKQ0KYGBgDQoNClNpbmNlIHRoZXJlIGFyZSBzb21lIHBhdHRlcm4ncyBpbiB0aGUgcmVzaWR1YWwgcGxvdHMuIHdlIGFsc28gcmVwb3J0IGEgbm9uLXBhcmFtZXRyaWMgYm9vdHN0cmFwIG1ldGhvZCB0byBjb25zdHJ1Y3QgcGVyY2VudGlsZS1iYXNlZCBib29zdHJhcCBjb25maWRlbmNlIGludGVydmFscyBvZiBlYWNoIHJlZ3Jlc3Npb24gY29lZmZpY2llbnRzLiBUaGUgcmVzdWx0cyBhcmUgc3VtbWFyaXplZCBpbiB0aGUgZm9sbG93aW5nIHRhYmxlLg0KDQpgYGB7cn0NCnByZWQudmFyIDwtIG5hbWVzKGNvZWYobWxhLmJlc3Quc3Vic2V0cy5sbSAsNykpWy0oMToyKV0NCmFjdXRhbC52YXIgPC1jKCJyYWNlIiwgcHJlZC52YXIpDQpmb3JtdWxhLnN0ciA8LSBwYXN0ZSgiTUxBIiwgIn4iLCBwYXN0ZShhY3V0YWwudmFyLCBjb2xsYXBzZSA9ICIgKyAiKSkNCk1MQS5tb2RlbC5mb3JtdWxhIDwtIGFzLmZvcm11bGEoZm9ybXVsYS5zdHIpDQpNTEEubW9kZWwgPC0gbG0oTUxBLm1vZGVsLmZvcm11bGEgLCBkYXRhID0gbWxhLmxtLmRhdGEpDQojc3VtbWFyeShNTEEubW9kZWwgKQ0KIyMjIEJvb3RzdHJhcCBjb25maWRlbmNlIGludGVydmFscw0KYm9vdC5jb2VmLm1sYSA8LSBmdW5jdGlvbihkYXRhLCBpbmRpY2VzKSB7DQogIGQgPC0gZGF0YVtpbmRpY2VzLCBdICAjIHJlc2FtcGxlIHJvd3MNCiAgZml0IDwtIGxtKE1MQS5tb2RlbC5mb3JtdWxhLCBkYXRhID0gZCkNCiAgcmV0dXJuKGNvZWYoZml0KSkgICAgICAjIHJldHVybiBjb2VmZmljaWVudHMNCn0NCg0KIyBQZXJmb3JtIGJvb3RzdHJhcCAoUiA9IG51bWJlciBvZiByZXNhbXBsZXMpDQpzZXQuc2VlZCgzMTIpICAjIGZvciByZXByb2R1Y2liaWxpdHkNCmJvb3QucmVzdWx0cy5tbGE8LSBib290KG1sYS5sbS5kYXRhLCBib290LmNvZWYubWxhLCBSID0gMTAwMCkNCiMjIGNvbWJpbmUgcmVndWxhciByZWdyZXNzaW9uIG91dHB1dCBhbmQgdGhlIGJvb3RzdHJhcCBDSQ0KYWxsLmNpcy5tbGEgPC0gZ2V0LmFsbC5ib290LmNpcyhib290LnJlc3VsdHMubWxhKQ0KSW5mZXJlbmNlVGFibGUgPC0gcm91bmQoY2JpbmQoc3VtbWFyeShNTEEubW9kZWwpJGNvZWYsIGFsbC5jaXMubWxhKSw0KQ0KcHJpbnQoSW5mZXJlbmNlVGFibGUpIA0KYGBgDQoNClRoZSBhYm92ZSByZXN1bHRzIGluZGljYXRlIHRoYXQgKipTZWxmLUVmZmljYWN5KiosICoqVGVjaG5vbG9neSB1c2UqKiwgKipEZW1vbnN0cmF0aW9uKiosIGFuZCAqKkxlY3R1cmUtYmFzZWQqKiB0ZWFjaGluZyBzdHJhdGVnaWVzIGFyZSBzaWduaWZpY2FudCBuZWdhdGl2ZSBwcmVkaWN0b3JzIG9mIGFueGlldHkuIFNwZWNpZmljYWxseSwgaGlnaGVyIHNlbGYtZWZmaWNhY3kgKCRcYmV0YSA9IC0wLjQwLCBwIDwgLjAwMSQpIGFuZCBncmVhdGVyIHVzZSBvZiAqKnRlY2hub2xvZ3kqKiBpbiBsZWFybmluZyAoJFxiZXRhID0gLTAuMTEsIHAgPCAuMDAxJCkgYXJlIGFzc29jaWF0ZWQgd2l0aCBsb3dlciBsZXZlbHMgb2YgbWF0aCBsZWFybmluZyBhbnhpZXR5LiBTaW1pbGFybHksIG1vcmUgZnJlcXVlbnQgdXNlIG9mICoqZGVtb25zdHJhdGl2ZSoqICgkXGJldGEgPSAtMC4xMCwgcCA9IC4wMDYkKSBhbmQgKipsZWN0dXJlIGFwcHJvYWNoZXMqKiAoJFxiZXRhID0gLTAuMTQsIHAgPCAuMDAxJCkgY29ycmVzcG9uZCB3aXRoIGRlY3JlYXNlZCBhbnhpZXR5Lg0KDQpDb252ZXJzZWx5LCB0aGUgcGVyY2VpdmVkICoqQ29vcGVyYXRpdmUqKiB0ZWFjaGluZyBhcHByb2FjaCBpcyBwb3NpdGl2ZWx5IGFzc29jaWF0ZWQgd2l0aCBsZWFybmluZyBhbnhpZXR5ICgkXGJldGEgPSAwLjA3LCBwID0gLjAzMSQpLiAqKlJlc291cmNlLWJhc2VkKiogbGVhcm5pbmcgKCRcYmV0YSA9IDAuMDgsIHAgPSAuMDEzJCkgaXMgYWxzbyBwb3NpdGl2ZWx5IGFzc29jaWF0ZWQgd2l0aCBhbnhpZXR5LCBzdWdnZXN0aW5nIHRoYXQgc3R1ZGVudCB1c2VkIGxlYXJuaW5nIHJlc291cmNlcyB0ZW5kZWQgdG8gaGF2ZSBoaWdoZXIgYW54aWV0eSBpbiBtYXRoIGNvbnRleHRzLg0KDQpUaGUgcmFjZSB2YXJpYWJsZSBhcHByb2FjaGVkIG1hcmdpbmFsIHNpZ25pZmljYW5jZSAocCA9MC4wNTgpLCBpbmRpY2F0aW5nIHRoYXQgQmxhY2sgc3R1ZGVudHMgdGVuZGVkIHRvIGhhdmUgaGlnaGVyIGxlYXJuaW5nIGFueGlldHkgKCRcYmV0YSA9IDAuMzIwMiwgcCA9IC4wNTgkKS4NCg0KT3ZlcmFsbCwgdGhlc2UgcmVzdWx0cyBoaWdobGlnaHQgdGhhdCBzdHVkZW50cycgY29uZmlkZW5jZSBpbiB0aGVpciBtYXRoIGFiaWxpdGllcyBhbmQgY2VydGFpbiBpbnN0cnVjdGlvbmFsIHByYWN0aWNlcyBwbGF5IGEga2V5IHJvbGUgaW4gcmVkdWNpbmcgbWF0aCBsZWFybmluZyBhbnhpZXR5LCB3aGlsZSBvdGhlcnMgbWF5IGluYWR2ZXJ0ZW50bHkgaW5jcmVhc2UgaXQuDQoNCiMjIyBVc2luZyBHcm91cGVkIFRlYWNoaW5nIFN0cmF0ZWdpZXMNCg0KV2UgbmV4dCBidWlsZCBhIHJlZ3Jlc3Npb24gc2ltaWxhciB0byB0aGUgYWJvdmUgb25lIGJ1dCByZXBsYWNlIHRoZSBpbmRpdmlkdWFsIHRlYWNoaW5nIHN0cmF0ZWd5IHZhcmlhYmxlcyB3aXRoIHRoZSB0d28gZ3JvdXBlZCB0ZWFjaGluZyBzdHJhdGVneSB2YXJpYWJsZXM6IHRlYWNoZXItY2VudGVyZWQgYW1kIHN0dWRlbnQtY2VudGVyZWQgYXBwcm9hY2hlcy4NCg0KYGBge3IgZWNobyA9IFRSVUUsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9Nn0NCm1sYS5sbS5kYXRhLmN0cmQgPC0gYW54aWV0eS5yZWcuZGF0YVssLWMoMSwgMTE6MTcpXQ0KbWxhLmZ1bGwuY3RyZCA8LSBsbShNTEEgfi4sIGRhdGEgPSBtbGEubG0uZGF0YS5jdHJkKQ0KcGFyKG1mcm93ID0gYygyLDIpKQ0KcGxvdChtbGEuZnVsbC5jdHJkKQ0KIyBzdW1tYXJ5KG1sYS5mdWxsLmN0cmQpDQpgYGANCg0KVGhlIHNhbWUgbm9uLWNvbnN0YW50IHZhcmlhbmNlIHBhdHRlcm5zIHdhcyBvYnNlcnZlZCBpbiB0aGUgYWJvdmUgcmVzaWR1YWwgcGxvdC4gV2Ugc3RpbGwgdXNlIHN1YnNldCBzZWxlY3Rpb24gcHJvY2VkdXJlIHRvIGlkZW50aWZ5IHRoZSBmaW5hbCBtb2RlbC4NCg0KYGBge3IgZWNobyA9IFRSVUUsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9NX0NCm1sYS5iZXN0LnN1YnNldHMuY3RyZCA8LSByZWdzdWJzZXRzKE1MQSB+LiwgZGF0YSA9IG1sYS5sbS5kYXRhLmN0cmQsIG52bWF4ID0gMTYsICBtZXRob2QgPSAiYmFja3dhcmQiICkNCkJlc3RTdWJzZXRzUmVnKG1sYS5iZXN0LnN1YnNldHMuY3RyZCkNCiMjIGZpbmFsIG1vZGVsDQpwcmVkLnZhci5jdHJkIDwtIG5hbWVzKGNvZWYobWxhLmJlc3Quc3Vic2V0cy5jdHJkLDcpKVstKDE6NCldDQphY3V0YWwudmFyLmN0cmQgPC1jKCJyYWNlIiwgIm1ham9yIiwgcHJlZC52YXIuY3RyZCkNCmZvcm11bGEuc3RyLmN0cmQgPC0gcGFzdGUoIk1MQSIsICJ+IiwgcGFzdGUoYWN1dGFsLnZhci5jdHJkLCBjb2xsYXBzZSA9ICIgKyAiKSkNCk1MQS5tb2RlbC5mb3JtdWxhIDwtIGFzLmZvcm11bGEoZm9ybXVsYS5zdHIuY3RyZCkNCk1MQS5tb2RlbC5jdHJkIDwtIGxtKE1MQS5tb2RlbC5mb3JtdWxhICwgZGF0YSA9IG1sYS5sbS5kYXRhLmN0cmQpDQojc3VtbWFyeShNTEEubW9kZWwuY3RyZCkkY29lZg0KIyMjIEJvb3RzdHJhcCBjb25maWRlbmNlIGludGVydmFscw0KYm9vdC5jb2VmLm1sYS5jdHJkIDwtIGZ1bmN0aW9uKGRhdGEsIGluZGljZXMpIHsNCiAgZCA8LSBkYXRhW2luZGljZXMsIF0gICMgcmVzYW1wbGUgcm93cw0KICBmaXQgPC0gbG0oTUxBLm1vZGVsLmZvcm11bGEgLCBkYXRhID0gZCkNCiAgcmV0dXJuKGNvZWYoZml0KSkgICAgICAjIHJldHVybiBjb2VmZmljaWVudHMNCn0NCiMgUGVyZm9ybSBib290c3RyYXAgKFIgPSBudW1iZXIgb2YgcmVzYW1wbGVzKQ0Kc2V0LnNlZWQoMzEyKSAgIyBmb3IgcmVwcm9kdWNpYmlsaXR5DQpib290LnJlc3VsdHMuY3RyZCA8LSBib290KG1sYS5sbS5kYXRhLmN0cmQsIGJvb3QuY29lZi5tbGEuY3RyZCwgUiA9IDEwMDApDQojIyBjb21iaW5pbmcgYm9vdHN0cmFwIENJcyB3aXRoIHRoZSBkZWZhdWx0IG91dHB1dCBpbiB0aGUgbG0oKQ0KYWxsLmN0cmQuY2lzIDwtIGdldC5hbGwuYm9vdC5jaXMoYm9vdC5yZXN1bHRzLmN0cmQgKQ0KSW5mZXJlbmNlVGFibGUgPC0gcm91bmQoY2JpbmQoc3VtbWFyeShNTEEubW9kZWwuY3RyZCkkY29lZiwgYWxsLmN0cmQuY2lzICksNCkNCnByaW50KEluZmVyZW5jZVRhYmxlKSANCmBgYA0KDQpUaGUgb3ZlcmFsbCBtb2RlbCB3YXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCwgaW5kaWNhdGluZyB0aGF0IHRoZSBzZXQgb2YgcHJlZGljdG9ycyBtZWFuaW5nZnVsbHkgZXhwbGFpbmVkIHZhcmlhbmNlIGluIG1hdGggbGVhcm5pbmcgYW54aWV0eS4NCg0KQW1vbmcgZGVtb2dyYXBoaWMgdmFyaWFibGVzLCAqKnJhY2UqKiB3YXMgYSBzaWduaWZpY2FudCBwcmVkaWN0b3IuIFNwZWNpZmljYWxseSwgQmxhY2sgc3R1ZGVudHMgcmVwb3J0ZWQgc2lnbmlmaWNhbnRseSBoaWdoZXIgYW54aWV0eSB0aGFuIHRoZSByZWZlcmVuY2UgQXNpYW4gZ3JvdXAgKCRcYmV0YSA9IDAuMzQsIHAgPSAuMDQzJCksIHdoZXJlYXMgc3R1ZGVudHMgaWRlbnRpZnlpbmcgYXMgV2hpdGUgb3IgT3RoZXIgcmFjaWFsIGdyb3VwcyBkaWQgbm90IGRpZmZlciBzaWduaWZpY2FudGx5IGZyb20gdGhlIHJlZmVyZW5jZSBncm91cCAoJHAgPiAuMDUkKS4gQWRkaXRpb25hbGx5LCBzdHVkZW50cyBtYWpvcmluZyBpbiAqKlNURU0qKiBmaWVsZHMgcmVwb3J0ZWQgc2lnbmlmaWNhbnRseSBsb3dlciBhbnhpZXR5IGNvbXBhcmVkIHRvIHRob3NlIG91dHNpZGUgU1RFTSBtYWpvcnMgKCRcYmV0YSA9IOKIkjAuMTcsIHAgPSAuMDM5JCkuIEFjYWRlbWljICoqbWFqb3JzKiogY2F0ZWdvcml6ZWQgYXMgSGVhbHRoIG9yIE90aGVyIGRpZCBub3Qgc2hvdyBzaWduaWZpY2FudCByZWxhdGlvbnNoaXBzIHdpdGggYW54aWV0eSAoJHAgPiAuMDUkKS4NCg0KUHN5Y2hvbG9naWNhbCBhbmQgaW5zdHJ1Y3Rpb25hbCBmYWN0b3JzIGRlbW9uc3RyYXRlZCBub3RhYmxlIGFzc29jaWF0aW9ucyB3aXRoIG1hdGggbGVhcm5pbmcgYW54aWV0eS4gSGlnaGVyIGxldmVscyBvZiAqKnNlbGYtZWZmaWNhY3kqKiB3ZXJlIHN0cm9uZ2x5IGFzc29jaWF0ZWQgd2l0aCBsb3dlciBhbnhpZXR5ICgkXGJldGEgPSDiiJIwLjM5LCBwIDwgLjAwMSQpLCByZXByZXNlbnRpbmcgdGhlIGxhcmdlc3QgZWZmZWN0IGluIHRoZSBtb2RlbC4gTW9yZSBmcmVxdWVudCB1c2Ugb2YgdGVjaG5vbG9neS1zdXBwb3J0ZWQgbGVhcm5pbmcgKCRcYmV0YSA9IOKIkjAuMTAsIHAgPCAuMDAxJCkgYW5kICoqdGVhY2hlci1jZW50ZXJlZCoqIGFwcHJvYWNoZXMgKCRcYmV0YSA9IOKIkjAuMTgsIHAgPCAuMDAxJCkgd2lsbCBoZWxwIHJlZHVjZSBhbnhpZXR5IGxldmVscy4gSW4gY29udHJhc3QsIGluY3JlYXNlZCByZWxpYW5jZSBvbiAqKnJlc291cmNlLWJhc2VkIGxlYXJuaW5nKiogc3RyYXRlZ2llcyB3YXMgcG9zaXRpdmVseSBhc3NvY2lhdGVkIHdpdGggYW54aWV0eSAoJFxiZXRhID0gMC4wOSwgcCA9IC4wMTEkKS4gQWx0aG91Z2ggKipzdHVkZW50LWNlbnRlcmVkKiogaW5zdHJ1Y3Rpb24gc2hvd2VkIGEgcG9zaXRpdmUgYXNzb2NpYXRpb24gd2l0aCBhbnhpZXR5LCB0aGlzIGVmZmVjdCBkaWQgbm90IHJlYWNoIHN0YXRpc3RpY2FsIHNpZ25pZmljYW5jZSAoJFxiZXRhID0gMC4wNiwgcCA9IC4wNzQkKS4NCg0KVG9nZXRoZXIsIHRoZXNlIHJlc3VsdHMgZGVtb25zdHJhdGUgdGhhdCBjb25maWRlbmNlIGluIG9uZSdzIG1hdGhlbWF0aWNhbCBhYmlsaXR5IGFuZCBzcGVjaWZpYyBpbnN0cnVjdGlvbmFsIG1ldGhvZHMgcGxheSBhbiBpbXBvcnRhbnQgcm9sZSBpbiBzaGFwaW5nIHN0dWRlbnRzJyBtYXRoIGxlYXJuaW5nIGFueGlldHkuIEFwcHJvYWNoZXMgdGhhdCBwcm92aWRlIHN0cnVjdHVyZWQgZ3VpZGFuY2UtLS1zdWNoIGFzIHRlYWNoZXItY2VudGVyZWQgZGVsaXZlcnkgYW5kIHRlY2hub2xvZ3kgaW50ZWdyYXRpb24tLS1hcHBlYXIgdG8gcmVkdWNlIGFueGlldHksIHdoZXJlYXMgZ3JlYXRlciBlbXBoYXNpcyBvbiBpbmRlcGVuZGVudCByZXNvdXJjZS1iYXNlZCBsZWFybmluZyBtYXkgY29udHJpYnV0ZSB0byBpbmNyZWFzZWQgYW54aWV0eS4NCg0KIyBTdHJ1Y3R1cmFsIEVxdWF0aW9uIE1vZGVsaW5nIEFwcHJvYWNoDQoNCldoZW4gd29ya2luZyB3aXRoIG11bHRpcGxlIGNvbnN0cnVjdHMsIGVhY2ggbWVhc3VyZWQgYnkgbXVsdGlwbGUgc3VydmV5IGl0ZW1zLCB3ZSBhcmUgd29ya2luZyB3aXRoIGxhdGVudCB2YXJpYWJsZXMuICoqU3RydWN0dXJhbCBlcXVhdGlvbiBtb2RlbGluZyAoU0VNKSoqIGlzIGlkZWFsIGJlY2F1c2UgaXQgZXhwbGljaXRseSBtb2RlbHMgdGhlIG1lYXN1cmVtZW50IChyZWxhdGlvbnNoaXBzIGJldHdlZW4gaXRlbXMgYW5kIHRoZWlyIGxhdGVudCBjb25zdHJ1Y3QpIGFuZCBzdHJ1Y3R1cmFsIChyZWxhdGlvbnNoaXBzIGJldHdlZW4gdGhlIGNvbnN0cnVjdHMpIHBhcnRzIHNpbXVsdGFuZW91c2x5LiBNb2RlbHMgc3VjaCBhcyBsaW5lYXIgcmVncmVzc2lvbiwgbXVsdGl2YXJpYXRlIHJlZ3Jlc3Npb24sIHBhdGggYW5hbHlzaXMsIGNvbmZpcm1hdG9yeSBmYWN0b3IgYW5hbHlzaXMsIGFuZCBzdHJ1Y3R1cmFsIHJlZ3Jlc3Npb24gY2FuIGJlIHRob3VnaHQgb2YgYXMgc3BlY2lhbCBjYXNlcyBvZiBTRU0uIFRoZSBmb2xsb3dpbmcgcmVsYXRpb25zaGlwcyBhcmUgcG9zc2libGUgaW4gU0VNOg0KDQotICAgKm9ic2VydmVkIHRvIG9ic2VydmVkIHZhcmlhYmxlcyogKCRcZ2FtbWEkLCBlLmcuLCByZWdyZXNzaW9uKQ0KLSAgICpsYXRlbnQgdG8gb2JzZXJ2ZWQgdmFyaWFibGVzKiAoJFxsYW1iZGEkLCBlLmcuLCBjb25maXJtYXRvcnkgZmFjdG9yIGFuYWx5c2lzKQ0KLSAgICpsYXRlbnQgdG8gbGF0ZW50IHZhcmlhYmxlcyogKCRcZ2FtbWEsIFxiZXRhJCwgZS5nLiwgc3RydWN0dXJhbCByZWdyZXNzaW9uKQ0KDQpTRU0gdW5pcXVlbHkgZW5jb21wYXNzZXMgYm90aCBtZWFzdXJlbWVudCBhbmQgc3RydWN0dXJhbCBtb2RlbHMuIFRoZSBtZWFzdXJlbWVudCBtb2RlbCByZWxhdGVzIG9ic2VydmVkIHRvIGxhdGVudCB2YXJpYWJsZXMgYW5kIHRoZSBzdHJ1Y3R1cmFsIG1vZGVsIHJlbGF0ZXMgbGF0ZW50IHRvIGxhdGVudCB2YXJpYWJsZXMuIEtsaW5lJ3MgKDIwMjMpIGlzIGEgY2xhc3NpYyBhbmQgbW9kZXJuIHRleHQgY292ZXJzIHVwLXRvLWRhdGUgbWV0aG9kcyBhbmQgYXBwbGljYXRpb25zLiBUaGUgZXN0aW1hdGlvbiBvZiBtb2RlbCBwYXJhbWV0ZXJzIGluIFNFTSBpcyBiYXNlZCBvbiB0aGUgbWF4aW11bSBsaWtlbGlob29kIGZ1bmN0aW9uIHdpdGggdGhlIGFzc3VtcHRpb24gdGhhdCBhbGwgb2JzZXJ2ZWQgdmFyaWFibGVzIGZvbGxvd2luZyBtdWx0aXZhcmlhdGUgbm9ybWFsIGRpc3RyaWJ1dGlvbi4NCg0KIyMgTm90YXRpb25zIGFuZCBUZWNobmljYWwgVGVybXMgaW4gU0VNDQoNCioqU29tZSBUZWNobmljYWwgVGVybXMgaW4gU0VNKio6DQoNCi0gICAqKm9ic2VydmVkIHZhcmlhYmxlKio6IGEgdmFyaWFibGUgdGhhdCBleGlzdHMgaW4gdGhlIGRhdGEsIGEuay5hIGl0ZW0gb3IgbWFuaWZlc3QgdmFyaWFibGUNCg0KLSAgICoqbGF0ZW50IHZhcmlhYmxlKio6IGEgdmFyaWFibGUgdGhhdCBpcyBjb25zdHJ1Y3RlZCBhbmQgZG9lcyBub3QgZXhpc3QgaW4gdGhlIGRhdGENCg0KLSAgICoqZXhvZ2Vub3VzIHZhcmlhYmxlKio6IGFuIGluZGVwZW5kZW50IHZhcmlhYmxlIGVpdGhlciBvYnNlcnZlZCAoeCkgb3IgbGF0ZW50ICgkXHhpJCkgdGhhdCBleHBsYWlucyBhbiBlbmRvZ2Vub3VzIHZhcmlhYmxlDQoNCi0gICAqKmVuZG9nZW5vdXMgdmFyaWFibGUqKjogYSBkZXBlbmRlbnQgdmFyaWFibGUsIGVpdGhlciBvYnNlcnZlZCAoeSkgb3IgbGF0ZW50ICgkXGV0YSQpIHRoYXQgaGFzIGEgY2F1c2FsIHBhdGggbGVhZGluZyB0byBpdA0KDQotICAgKiptZWFzdXJlbWVudCBtb2RlbCoqOiBhIG1vZGVsIHRoYXQgbGlua3Mgb2JzZXJ2ZWQgdmFyaWFibGVzIHdpdGggbGF0ZW50IHZhcmlhYmxlcw0KDQotICAgKippbmRpY2F0b3IqKjogYW4gb2JzZXJ2ZWQgdmFyaWFibGUgaW4gYSBtZWFzdXJlbWVudCBtb2RlbCAoY2FuIGJlIGV4b2dlbm91cyBvciBlbmRvZ2Vub3VzKQ0KDQotICAgKipmYWN0b3IqKjogYSBsYXRlbnQgdmFyaWFibGUgZGVmaW5lZCBieSBpdHMgaW5kaWNhdG9ycyAoY2FuIGJlIGV4b2dlbm91cyBvciBlbmRvZ2Vub3VzKQ0KDQotICAgKipsb2FkaW5nKio6IGEgcGF0aCBiZXR3ZWVuIGFuIGluZGljYXRvciBhbmQgYSBmYWN0b3INCg0KLSAgICoqc3RydWN0dXJhbCBtb2RlbCoqOiBhIG1vZGVsIHRoYXQgc3BlY2lmaWVzIGNhdXNhbCByZWxhdGlvbnNoaXBzIGFtb25nIGV4b2dlbm91cyB2YXJpYWJsZXMgdG8gZW5kb2dlbm91cyB2YXJpYWJsZXMgKGNhbiBiZSBvYnNlcnZlZCBvciBsYXRlbnQpDQoNCi0gICAqKnJlZ3Jlc3Npb24gcGF0aCoqOiBhIHBhdGggYmV0d2VlbiBleG9nZW5vdXMgYW5kIGVuZG9nZW5vdXMgdmFyaWFibGVzIChjYW4gYmUgb2JzZXJ2ZWQgb3IgbGF0ZW50KQ0KDQojIyBTRU0gUGF0aCBNb2RlbA0KDQpBIHBhdGggbW9kZWwgc2VydmVzIGFzIHRoZSB2aXN1YWwgYW5kIG1hdGhlbWF0aWNhbCBibHVlcHJpbnQgZm9yIGEgU3RydWN0dXJhbCBFcXVhdGlvbiBNb2RlbCAoU0VNKS4gVGhpcyBkaWFncmFtIGVtcGxveXMgYSBzdGFuZGFyZGl6ZWQgbm90YXRpb24gdG8gcmVwcmVzZW50IGh5cG90aGVzaXplZCByZWxhdGlvbnNoaXBzIGJldHdlZW4gdmFyaWFibGVzLiBUaGUgc3BlY2lmaWMgbW9kZWwgdG8gYmUgdGVzdGVkLCB3aGljaCBleGFtaW5lcyB0aGUgY29tcGxleCBzdHJ1Y3R1cmFsIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBlbmRvZ2Vub3VzIGFuZCBleG9nZW5vdXMgdmFyaWFibGVzLCBoYXMgdGhlIGZvbGxvd2luZyBzdHJ1Y3R1cmU6DQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoPSI3MCUifQ0KaW5jbHVkZV9ncmFwaGljcygiSHlwb3RoZXRpY2FsU0VNLnBuZyIpDQpgYGANCg0KVG8gYmV0dGVyIHVuZGVyc3RhbmQgdGhlIGFkdmFudGFnZXMgYW5kIGRpc2FkdmFudGFnZXMgb2YgU3RydWN0dXJhbCBFcXVhdGlvbiBNb2RlbGluZyAoU0VNKSBmb3IgYW5hbHl6aW5nIGNvbXBsZXggcmVsYXRpb25zaGlwcy0tLXN1Y2ggYXMgdGhvc2UgYmV0d2VlbiBsYXRlbnQgdmFyaWFibGVzIGxpa2UgbWF0aCBldmFsdWF0aW9uIGFuZCBsZWFybmluZyBhbnhpZXR5LiB3ZSB3aWxsIGJyaWVmbHkgZGVzY3JpYmUgaXRzIG1hdGhlbWF0aWNhbCBmb3JtdWxhdGlvbiBhbmQgTUxFIG9mIGFsbCBtb2RlbCBwYXJhbWV0ZXJzIHVzaW5nIHRoZSBhYm92ZSBoeXBvdGhldGljYWwgU0VNIHBhdGggbW9kZWwgaW4gdGhlIGFwcGVuZGl4Lg0KDQojIyBTRU0gSW1wbGVtZW50YXRpb24NCg0KV2UgdXNlIHRoZSBSIGBsYXZhYW5gIGxpYnJhcnkgdG8gaW1wbGVtZW50IHRoZSBTRU0gdG8gYXNzZXNzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBtYXRoIGV2YWx1YXRpb24sIGxlYXJuaW5nIGFueGlldHksIGFuZCByZWxhdGVkIGV4b2dlbm91cyB2YXJpYWJsZXMuIFRoZSBvdXRwdXQgcHJlc2VudHMgcmVzdWx0cyBiYXNlZCBvbiBzdGFuZGFyZGl6ZWQgdmFyaWFibGVzLiBUaGUgaW50ZXJwcmV0YXRpb24gb2YgdGhlIHJlZ3Jlc3Npb24gY29lZmZpY2llbnRzIGlzIHNpbWlsYXIgdG8gdGhhdCBpbiBhIHJlZ3VsYXIgcmVncmVzc2lvbiBtb2RlbCwgaW5kaWNhdGluZyB0aGUgY2hhbmdlIGluIHRoZSBvdXRjb21lIChpbiBzdGFuZGFyZCBkZXZpYXRpb25zKSBmb3IgYSBvbmUtc3RhbmRhcmQtZGV2aWF0aW9uIGluY3JlYXNlIGluIGEgcHJlZGljdG9yLg0KDQoqKlF1aWNrIFJlZmVyZW5jZSBvZiBgbGF2YWFuYCBTeW50YXgqKg0KDQotICAgYH4gcHJlZGljdGAsIHVzZWQgZm9yIHJlZ3Jlc3Npb24gb2Ygb2JzZXJ2ZWQgb3V0Y29tZSB0byBvYnNlcnZlZCBwcmVkaWN0b3JzIChlLmcuLCB5IFx+IHgpDQotICAgYDE9fiBpbmRpY2F0b3IxYCwgdXNlZCBmb3IgbGF0ZW50IHZhcmlhYmxlIHRvIG9ic2VydmVkIGluZGljYXRvciBpbiBmYWN0b3IgYW5hbHlzaXMgbWVhc3VyZW1lbnQgbW9kZWxzIChlLmcuLCBgZiA9fiBxICsgciArIHNgKQ0KLSAgIFxgYH5+YCBjb3ZhcmlhbmNlIChlLmcuLCBgeCB+fiB4YCkNCi0gICBgfjFgIGludGVyY2VwdCBvciBtZWFuIChlLmcuLCBgeCB+IDFgIGVzdGltYXRlcyB0aGUgbWVhbiBvZiB2YXJpYWJsZSB4KQ0KLSAgIGAxKmAgZml4ZXMgcGFyYW1ldGVyIG9yIGxvYWRpbmcgdG8gb25lIChlLmcuLCBgZiA9fiAxKnFgKQ0KLSAgIGBOQSpgIGZyZWVzIHBhcmFtZXRlciBvciBsb2FkaW5nICh1c2VmdWwgdG8gb3ZlcnJpZGUgZGVmYXVsdCBtYXJrZXIgbWV0aG9kLCAoZS5nLiwgYGYgPX4gTkEqcWApDQotICAgYGEqYCBsYWJlbHMgdGhlIHBhcmFtZXRlciAnYScsIHVzZWQgZm9yIG1vZGVsIGNvbnN0cmFpbnRzIChlLmcuLCBgZiA9fiBhKnFgKQ0KDQoNCg0KDQoNCmBgYHtyfQ0Kc2V0LnNlZWQoMTIzMjEpDQpBbnhpZXR5Lm1lYSA8LSBDb21wLkFueGlldHlbLCBjKCJBTUFTLjIiLCAiQU1BUy40IiwgIkFNQVMuNSIsICAiQU1BUy44IildDQpBbnhpZXR5Lm1sYSA8LSBDb21wLkFueGlldHlbLCBjKCJBTUFTLjEiLCAiQU1BUy4zIiwgIkFNQVMuNiIsICJBTUFTLjciLCAiQU1BUy45IildDQpuYW1lcyhBbnhpZXR5Lm1lYSkgPC0gYygiTUVBMiIsICJNRUE0IiwgIk1FQTUiLCAgIk1FQTgiKSAgDQpuYW1lcyhBbnhpZXR5Lm1sYSkgPC0gYygiTUxBMSIsICJNTEEzIiwgIk1MQTYiLCAiTUxBNyIsICJNTEE5IikNCmZhY3Rvci5uYW1lcyA8LSBjKCJUZWNobm9sb2d5Lnd0LnBjYSIsICJTZWxmRWZmaWNhY3kud3QucGNhIiwgIkVuZ2FnZS53dC5wY2EiLCAic2V4IiwNCiAgICAgICAgICAgICAgICAgICJUZWFjaGVyLmN0cmQud3QucGNhIiwgIlN0dWRlbnQuY3RyZC53dC5wY2EiLCAiUmVzb3VyY2Uud3QucGNhIikNCiMjDQpmYWN0b3IudmFyIDwtIEFueGlldHkuQW5hbHl0aWMuRGF0YVssIGZhY3Rvci5uYW1lc10NCm5hbWVzKGZhY3Rvci52YXIpIDwtIGMoIlRlY2giLCAiRWZmaWNhY3kiLCAiRW5nYWdlIiwgImdlbmRlciIsDQogICAgICAgICAgICAgICAgICAiVGVhY2hlci5jdHJkIiwgIlN0dWRlbnQuY3RyZCIsICJSZXNvdXJjZSIpDQoNCiMjIyBzdHJhdGVnaWVzIHZhcg0Kc3RyYXRneS52YXIgPC1jKCJDb29wb3JhdGl2ZS53dC5wY2EiLCAiRGVkdWN0aXZlLnd0LnBjYSIsICJEZW1vbnN0cmF0aW9uLnd0LnBjYSIsICJJbmR1Y3RpdmUud3QucGNhIiwiSW50ZWdyYXRpdmUud3QucGNhIiAsIkxlY3R1cmVUeXBlLnd0LnBjYSIsICJSZXBldGl0aXZlLnd0LnBjYSIgKQ0Kc3RyYXRlZ3kubmFtZSA8LSBjKCJDb29wIiwgIkRlZHVjIiwgIkRlbW9uIiwgIkluZHVjIiwiSW50ZWciICwiTGVjdCIsICJSZXBldCIgKQ0KdGVhY2hpbmdzdHJhdGVneSA8LSBBbnhpZXR5LkFuYWx5dGljLkRhdGFbLCBzdHJhdGd5LnZhcl0NCm5hbWVzKHRlYWNoaW5nc3RyYXRlZ3kpIDwtIHN0cmF0ZWd5Lm5hbWUgDQpTRU0uZGF0YSA8LSBjYmluZChBbnhpZXR5Lm1lYSwgQW54aWV0eS5tbGEsIGZhY3Rvci52YXIsdGVhY2hpbmdzdHJhdGVneSApDQoNCiMjIyAgU0VNIG1vZGVscw0KDQpTRU1Nb2RlbCA8LQ0KJyBFdmFsLkFueGlldHkgPX4gIE1FQTIgKyBNRUE0ICsgTUVBNSArIE1FQTggICMjIG1lYXN1cmVtZW50IG1vZGVsIGZvciBFdmFsLkFueGlldHkNCiAgTGVhcm4uQW54aWV0eSA9fiBNTEExICsgTUxBMyArIE1MQTYgKyBNTEE3ICsgTUxBOSAgICMjIG1lYXN1cmVtZW50IG1vZGVsIGZvciBMZWFybi5BbnhpZXR5IA0KICBUZWFjaGVyQ3RyZCA9fiBEZWR1YyArIExlY3QgKyBEZW1vbiArIFJlcGV0ICAjIFRlYWNoZXIgY2VudGVyZWQNCiAgU3R1ZGVudEN0cmQgPX4gQ29vcCArIEluZHVjICsgSW50ZWcgICMgU3R1ZGVudCBjZW50ZXJlZA0KICBFdmFsLkFueGlldHkgfiBUZWNoICsgRWZmaWNhY3kgKyBFbmdhZ2UgKyBnZW5kZXIgKyBUZWFjaGVyQ3RyZCArIFN0dWRlbnRDdHJkICsgUmVzb3VyY2UgICAgIyMgRXZhbC5BbnhpZXR5IGFzIGFuIG91dGNvbWUNCiAgTGVhcm4uQW54aWV0eSB+IFRlY2ggKyBFZmZpY2FjeSArIEVuZ2FnZSArIGdlbmRlciArIFRlYWNoZXJDdHJkKyBTdHVkZW50Q3RyZCArIFJlc291cmNlICAgICMjIExlYXJuLkFueGlldHkgYXMgYW4gb3V0Y29tZQ0KICBFdmFsLkFueGlldHkgfn4gTGVhcm4uQW54aWV0eSAgICAgIyMgY29ycmVsYXRpb24gYmV0d2VlbiBFdmFsLkFueGlldHkgYW5kIExlYXJuLkFueGlldHkgDQonDQogDQpvdXRwdXQgPC0gc2VtKG1vZGVsID0gU0VNTW9kZWwsIGRhdGEgPSBTRU0uZGF0YSwgc3RkLmx2ID0gVFJVRSwgIGVzdGltYXRvciA9ICJXTFNNViIsDQogICAgICAgICAgICAgIG1pbWljID0gIk1wbHVzIikNCnJlc3VsdHMgPC0gc3VtbWFyeShvdXRwdXQsIHN0YW5kYXJkaXplZCA9IFRSVUUsIGZpdC5tZWFzdXJlcyA9IFRSVUUpDQoNCmBgYA0KDQpUaGUgY29tcG9uZW50IHJlZ3Jlc3Npb24gYW5kIGxhdGVudCBtb2RlbHMgaW4gdGhlIFNFTSBhcmUgc3BlY2lmaWVkIGluIHRoZSBmb2xsb3dpbmcuDQoNCmBgYCAgICAgICAgIA0KICAjIyBtZWFzdXJlbWVudCBtb2RlbCBmb3IgRXZhbC5BbnhpZXR5DQogIEV2YWwuQW54aWV0eSA9fiAgTUVBMiArIE1FQTQgKyBNRUE1ICsgTUVBOCAgICAgICAgICAgIA0KICAjIyBtZWFzdXJlbWVudCBtb2RlbCBmb3IgTGVhcm4uQW54aWV0eSANCiAgTGVhcm4uQW54aWV0eSA9fiBNTEExICsgTUxBMyArIE1MQTYgKyBNTEE3ICsgTUxBOSAgDQogICMgTGF0ZW50IHJlZ3Jlc3Npb24gb2YgdGVhY2hpbmcgU3RyYXRlZ2llcw0KICBUZWFjaGVyQ3RyZCA9fiBEZWR1YyArIExlY3QgKyBEZW1vbiArIFJlcGV0ICAjIFRlYWNoZXIgY2VudGVyZWQNCiAgU3R1ZGVudEN0cmQgPX4gQ29vcCArIEluZHVjICsgSW50ZWcgICMgU3R1ZGVudCBjZW50ZXJlZA0KICAjIyBFdmFsLkFueGlldHkgYXMgYW4gb3V0Y29tZQ0KICBFdmFsLkFueGlldHkgfiBUZWNoICsgRWZmaWNhY3kgKyBFbmdhZ2UgKyBnZW5kZXIgKyBUZWFjaGVyLmN0cmQgKyBTdHVkZW50LmN0cmQgKyBSZXNvdXJjZSArIHJhY2UgICANCiAgIyMgTGVhcm4uQW54aWV0eSBhcyBhbiBvdXRjb21lDQogIExlYXJuLkFueGlldHkgfiBUZWNoICsgRWZmaWNhY3kgKyBFbmdhZ2UgKyBnZW5kZXIgKyBUZWFjaGVyLmN0cmQgKyBTdHVkZW50LmN0cmQgKyBSZXNvdXJjZSArIHJhY2UgIA0KICBFdmFsLkFueGlldHkgfn4gTGVhcm4uQW54aWV0eSAgICAgIyMgY29ycmVsYXRpb24gYmV0d2VlbiBFdmFsLkFueGlldHkgYW5kIExlYXJuLkFueGlldHkgDQpgYGANCg0KVGhlIGtleSBnb29kbmVzcy1vZi1maXQgc3RhdGlzdGljcyBhbmQgZXN0aW1hdGVkIHBhcmFtZXRlcnMgYXJlIHN1bW1hcml6ZWQgaW4gdGhlIGZvbGxvd2luZy4NCg0KYGBge3IgZWNobyA9IEZBTFNFfQ0KaW50ZXJwcmV0X2ZpdCA8LSBmdW5jdGlvbihmaXRfb2JqKSB7DQogIG1lYXN1cmVzIDwtIGZpdE1lYXN1cmVzKGZpdF9vYmopDQogIA0KICAjY2F0KCI9PT0gU0VNIE1PREVMIEZJVCBBU1NFU1NNRU5UID09PVxuIikNCiAgY2F0KHNwcmludGYoIkNoaS1TcXVhcmU6IM+HwrIoJWQpID0gJS4yZiwgcCA9ICUuM2ZcbiIsIA0KICAgICAgICAgICAgICBtZWFzdXJlc1siZGYiXSwgbWVhc3VyZXNbImNoaXNxIl0sIG1lYXN1cmVzWyJwdmFsdWUiXSkpDQogIGNhdChzcHJpbnRmKCJDRkk6ICUuM2YgJXNcbiIsIG1lYXN1cmVzWyJjZmkiXSwNCiAgICAgICAgICAgICAgaWZlbHNlKG1lYXN1cmVzWyJjZmkiXSA+PSAwLjk1LCAiKEV4Y2VsbGVudCkiLA0KICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKG1lYXN1cmVzWyJjZmkiXSA+PSAwLjkwLCAiKEFjY2VwdGFibGUpIiwgIihQb29yKSIpKSkpDQogIGNhdChzcHJpbnRmKCJUTEk6ICUuM2YgJXNcbiIsIG1lYXN1cmVzWyJ0bGkiXSwNCiAgICAgICAgICAgICAgaWZlbHNlKG1lYXN1cmVzWyJ0bGkiXSA+PSAwLjk1LCAiKEV4Y2VsbGVudCkiLA0KICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKG1lYXN1cmVzWyJ0bGkiXSA+PSAwLjkwLCAiKEFjY2VwdGFibGUpIiwgIihQb29yKSIpKSkpDQogIGNhdChzcHJpbnRmKCJSTVNFQTogJS4zZiBbOTAlJSBDSTogJS4zZiwgJS4zZl0gJXNcbiIsIA0KICAgICAgICAgICAgICBtZWFzdXJlc1sicm1zZWEiXSwgbWVhc3VyZXNbInJtc2VhLmNpLmxvd2VyIl0sIG1lYXN1cmVzWyJybXNlYS5jaS51cHBlciJdLA0KICAgICAgICAgICAgICBpZmVsc2UobWVhc3VyZXNbInJtc2VhIl0gPD0gMC4wNiwgIihFeGNlbGxlbnQpIiwNCiAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShtZWFzdXJlc1sicm1zZWEiXSA8PSAwLjA4LCAiKEFjY2VwdGFibGUpIiwgIihQb29yKSIpKSkpDQogIGNhdChzcHJpbnRmKCJTUk1SOiAlLjNmICVzXG4iLCBtZWFzdXJlc1sic3JtciJdLA0KICAgICAgICAgICAgICBpZmVsc2UobWVhc3VyZXNbInNybXIiXSA8PSAwLjA4LCAiKEV4Y2VsbGVudCkiLA0KICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKG1lYXN1cmVzWyJzcm1yIl0gPD0gMC4xMCwgIihBY2NlcHRhYmxlKSIsICIoUG9vcikiKSkpKQ0KfQ0KDQojIyMNCnJlcG9ydF9zZW0gPC0gZnVuY3Rpb24oZml0LCBtb2RlbF9uYW1lID0gIlRoZSBTRU0iKSB7DQogIA0KICAjIEZpdCBtZWFzdXJlcw0KICBmaXRfbWVhcyA8LSBmaXRNZWFzdXJlcyhmaXQsIGMoImNoaXNxIiwgImRmIiwgInB2YWx1ZSIsICJjZmkiLCAidGxpIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJybXNlYSIsICJybXNlYS5jaS5sb3dlciIsICJybXNlYS5jaS51cHBlciIsICJzcm1yIikpDQogIA0KICAjIFBhcmFtZXRlcnMNCiAgcGFyYW1zIDwtIHBhcmFtZXRlckVzdGltYXRlcyhmaXQpDQogIHN0ZF9wYXJhbXMgPC0gc3RhbmRhcmRpemVkU29sdXRpb24oZml0KQ0KICANCiAgY2F0KCI9PT0gU1RSVUNUVVJBTCBFUVVBVElPTiBNT0RFTElORyBSRVNVTFRTID09PVxuXG4iKQ0KICBjYXQoIk1PREVMIEZJVDpcbiIpDQogIA0KICAjIFVzZSB0aGUgZnVuY3Rpb24NCiAgaW50ZXJwcmV0X2ZpdChvdXRwdXQpDQogIGNhdCgiXG5cbiIpDQogICMgU2lnbmlmaWNhbnQgc3RydWN0dXJhbCBwYXRocw0KICBzaWdfcGF0aHMgPC0gc3RkX3BhcmFtc1tzdGRfcGFyYW1zJG9wID09ICJ+IiAmIHN0ZF9wYXJhbXMkcHZhbHVlIDwgMC4xLCBdDQogIGlmIChucm93KHNpZ19wYXRocykgPiAwKSB7DQogICAgY2F0KCJTSUdOSUZJQ0FOVCBTVFJVQ1RVUkFMIFBBVEhTOlxuIikNCiAgICBmb3IgKGkgaW4gMTpucm93KHNpZ19wYXRocykpIHsNCiAgICAgIGNhdChzcHJpbnRmKCItICVzIOKGkiAlczogzrIgPSAlLjJmLCBwID0gJS4zZlxuIiwNCiAgICAgICAgICAgICAgICAgIHNpZ19wYXRocyRyaHNbaV0sIHNpZ19wYXRocyRsaHNbaV0sDQogICAgICAgICAgICAgICAgICBzaWdfcGF0aHMkZXN0W2ldLCBzaWdfcGF0aHMkcHZhbHVlW2ldKSkNCiAgICB9DQogICAgY2F0KCJcbiIpDQogIH0NCiAgDQogICMgZmFjdG9yIGxvYWRpbmcgZm9yIGxhdGVudCB2YXJpYWJsZXMNCiAgY2F0KCJcblxuRkFDVE9SIExPQURJTkdTXG5cbiIpDQogIA0KICBwcmludChzdGRfcGFyYW1zW3N0ZF9wYXJhbXMkb3AgPT0gIj1+IiwgXSkNCiAgDQogICMjIyMjDQogICMgUi1zcXVhcmVkDQogIHIyIDwtIGluc3BlY3QoZml0LCAicjIiKQ0KICBpZiAobGVuZ3RoKHIyKSA+IDApIHsNCiAgICBjYXQoIlZBUklBTkNFIEVYUExBSU5FRCAoUsKyKTpcblxuIikNCiAgICBmb3IgKGkgaW4gMTpsZW5ndGgocjIpKSB7DQogICAgICBjYXQoc3ByaW50ZigiLSAlczogJS4xZiUlXG4iLCBuYW1lcyhyMilbaV0sIHIyW2ldICogMTAwKSkNCiAgICB9DQogIH0NCiAgDQogICMjIFJlZ3Jlc3Npb24gY29lZmZpY2llbnRzDQogIA0KICBjYXQoIlxuXG5DT0VGRklDSUVOVFMgT0YgUkVHUkVTU0lPTlxuXG4iKQ0KICANCiAgcHJpbnQoc3RkX3BhcmFtc1tzdGRfcGFyYW1zJG9wID09ICJ+IiwgXSkNCiAgDQogICAgICMgQ292YXJpYW5jZSBiZXR3ZWVuIE1hdGggQW54aWV0aWVzDQogICAgICAjcGFyYW1fZXN0IDwtIHBhcmFtZXRlckVzdGltYXRlcyhmaXQpDQogICAgIGNvdl9sYXRlbnQgPC0gc3RkX3BhcmFtc1sNCiAgICAgICAgICAgICAgc3RkX3BhcmFtcyRsaHMgPT0gIk1hdGhFdmFsIiAmIA0KICAgICAgICAgICAgICBzdGRfcGFyYW1zJHJocyA9PSAiTGVhcm5BbngiICYgDQogICAgICAgICAgICAgIHN0ZF9wYXJhbXMkb3AgPT0gIn5+IiwNCiAgICAgICAgICBdDQogICAgICMjIw0KICAgICBjYXQoIlxuXG5DT1ZBUklBTkNFIDpcbiIpDQogICAgIGxhdGVudF9jb3ZfbWF0cml4IDwtIGxhdkluc3BlY3QoZml0LCAiZXN0IikkcHNpDQogICAgIGNvdl9vdXQgPC0gbGF0ZW50X2Nvdl9tYXRyaXhbIkxlYXJuLkFueGlldHkiLCAiRXZhbC5BbnhpZXR5Il0NCiAgICAgY2F0KCItIExlYXJuLkFueGlldHkgYW5kIEV2YWwuQW54aWV0eToiLCBjb3Zfb3V0KQ0KfQ0KDQojIFVzZSB0aGUgZnVuY3Rpb24NCiNyZXBvcnRfc2VtKG91dHB1dCwgIk1hdGggQW54aWV0eSIpDQpgYGANCg0KVGhlIHJlZ3Jlc3Npb24gY29lZmZpY2llbnRzIGFuZCBmYWN0b3IgbG9hZGluZ3MgaW4gdGhlIGFib3ZlIHRhYmxlIGFyZSBzdW1tYXJpemVkIGluIHRoZSBmb2xsb3dpbmcgU0VNIHBhdGggZGlhZ3JhbSBnZW5lcmF0ZWQgdXNpbmcgYGxhdmFhblBsb3RgIGZ1bmN0aW9uLg0KDQpgYGB7cn0NCmxhdmFhblBsb3QobW9kZWwgPSBvdXRwdXQsDQogICAgICAgICAgIGNvZWZzID0gVFJVRSwNCiAgICAgICAgICAgc3RhbmQgPSBUUlVFLA0KICAgICAgICAgICBzdGFycyA9IGMoInJlZ3Jlc3MiKSkgICMgQWRkIHNpZ25pZmljYW5jZSBzdGFycw0KYGBgDQoNClRoZSBwYXRoIGRpYWdyYW0gZ2VuZXJhdGVkIGJ5IFIgZm9yIHRoZSBTRU0gYW5hbHlzaXMgaXMgbm90IGVhc3kgdG8gcmVhZC4gVGhlcmVmb3JlLCB3ZSBza2V0Y2hlZCBhIG5ldyBwYXRoIGRpYWdyYW0gdGhhdCBpbmNsdWRlcyBvbmx5IHRoZSBzaWduaWZpY2FudCByZWdyZXNzaW9uIGNvZWZmaWNpZW50cyBhbmQgZmFjdG9yIGxvYWRpbmdzLg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aD0iNzAlIn0NCmluY2x1ZGVfZ3JhcGhpY3MoIkZpdHRlZGxTRU0ucG5nIikNCmBgYA0KDQojIyBSZXN1bHRzIGFuZCBEaXNjdXNzaW9uIG9mIFNFTSBBbmx5c2lzDQoNCkEgc3RydWN0dXJhbCBlcXVhdGlvbiBtb2RlbCAoU0VNKSB3YXMgZXN0aW1hdGVkIHRvIGV4YW1pbmUgdGhlIGVmZmVjdHMgb2YgcGVyY2VpdmVkIHRlYWNoaW5nIHN0cmF0ZWdpZXMgYW5kIHN0dWRlbnQgY2hhcmFjdGVyaXN0aWNzIG9uIHR3byBkaW1lbnNpb25zIG9mIG1hdGhlbWF0aWNzIGFueGlldHk6ICoqTWF0aCBFdmFsdWF0aW9uIEFueGlldHkgKE1FQSkqKiBhbmQgKipNYXRoIExlYXJuaW5nIEFueGlldHkgKE1MQSkqKi4gVGhlIG1vZGVsIGRlbW9uc3RyYXRlZCBleGNlbGxlbnQgZml0IHRvIHRoZSBkYXRhOg0KDQokJA0KXGNoaV4yKDE2OCkgPSA1NDIuNzUsIFwsIHAgPCAuMDAxLCBcLA0KXHRleHR7Q0ZJfSA9IC45NjgsIFwsDQpcdGV4dHtUTEl9ID0gLjk2MiwgXCwNClx0ZXh0e1JNU0VBfSA9IC4wNTcgXCwgWzkwXCUgXHRleHR7Q0kgfSAuMDUxLCAuMDYyXSwgXCwNClx0ZXh0e1NSTVJ9ID0gLjA1OS4NCiQkDQoNClwNCg0KKipNZWFzdXJlbWVudCBNb2RlbCoqDQoNClN0YW5kYXJkaXplZCBsb2FkaW5ncyB3ZXJlIGNvbnNpc3RlbnRseSBzdHJvbmcgYWNyb3NzIGxhdGVudCBmYWN0b3JzICgkXGxhbWJkYSA9IC41MyTigJMuODkpLCBzdXBwb3J0aW5nIHJlbGlhYmlsaXR5IGFuZCBjb252ZXJnZW50IHZhbGlkaXR5LiBUaGUgbW9kZWwgZXhwbGFpbmVkIDQyLjklIG9mIHRoZSB2YXJpYW5jZSBpbiBNRUEgYW5kIDI5LjclIGluIE1MQS4NCg0KYGBge3IsIGVjaG89RkFMU0V9DQpsaWJyYXJ5KGtuaXRyKQ0KVGFibGUxIDwtIGRhdGEuZnJhbWUoDQogIExhdGVudF9WYXJpYWJsZSA9IGMoIk1hdGggRXZhbHVhdGlvbiBBbnhpZXR5IiwgIiIsICIiLCAiIiwNCiAgICAgICAgICAgICAgICAgICAgICAiTWF0aCBMZWFybmluZyBBbnhpZXR5IiwgIiIsICIiLCAiIiwgIiIsDQogICAgICAgICAgICAgICAgICAgICAgIlRlYWNoZXItQ2VudGVyZWQiLCAiIiwgIiIsICIiLA0KICAgICAgICAgICAgICAgICAgICAgICJTdHVkZW50LUNlbnRlcmVkIiwgIiIsICIiKSwNCiAgSW5kaWNhdG9yID0gYygiTUVBMiIsIk1FQTQiLCJNRUE1IiwiTUVBOCIsDQogICAgICAgICAgICAgICAgIk1MQTEiLCJNTEEzIiwiTUxBNiIsIk1MQTciLCJNTEE5IiwNCiAgICAgICAgICAgICAgICAiRGVkdWN0aXZlIiwiTGVjdHVyZSBUeXBlIiwiRGVtb25zdHJhdGlvbiIsIlJlcGV0aXRpdmUiLA0KICAgICAgICAgICAgICAgICJDb29wZXJhdGl2ZSIsIkluZHVjdGl2ZSIsIkludGVncmF0aXZlIiksDQogIExhbWJkYSA9IGMoLjg4LC44NCwuNjcsLjY1LA0KICAgICAgICAgICAgIC41MywuNzEsLjc0LC42NCwuNzMsDQogICAgICAgICAgICAgLjg4LC44OSwuODAsLjc1LA0KICAgICAgICAgICAgIC43MywuODcsLjY4KSwNCiAgUjIgPSBjKC43NywuNzAsLjQ1LC40MiwNCiAgICAgICAgIC4yOCwuNTEsLjU0LC40MCwuNTQsDQogICAgICAgICAuNzgsLjc5LC42NCwuNTYsDQogICAgICAgICAuNTQsLjc2LC40NikNCikNCg0Ka2FibGUoVGFibGUxLCBjYXB0aW9uID0gIlRhYmxlIDEuIFN0YW5kYXJkaXplZCBGYWN0b3IgTG9hZGluZ3MgYW5kIFZhcmlhbmNlIEV4cGxhaW5lZCBmb3IgTGF0ZW50IENvbnN0cnVjdHMiKQ0KYGBgDQoNCg0KKipTdHJ1Y3R1cmFsIE1vZGVsKioNCg0KDQpTdGFuZGFyZGl6ZWQgcmVncmVzc2lvbiBjb2VmZmljaWVudHMgYXJlIHNob3duIGluIFRhYmxlIDIuIE5lZ2F0aXZlIGNvZWZmaWNpZW50cyBpbmRpY2F0ZSByZWR1Y2VkIGFueGlldHkuDQoNCmBgYHtyfQ0KVGFibGUyIDwtIGRhdGEuZnJhbWUoDQpQcmVkaWN0b3IgPSBjKCJUZWNobm9sb2d5IFVzZSIsIlNlbGYtRWZmaWNhY3kiLCJHZW5kZXIiLA0KIlRlY2hub2xvZ3kgVXNlIiwiU2VsZi1FZmZpY2FjeSIsIkVuZ2FnZW1lbnQiLA0KIlRlYWNoZXItQ2VudGVyZWQgU3RyYXRlZ2llcyIsIlN0dWRlbnQtQ2VudGVyZWQgU3RyYXRlZ2llcyIsIlJlc291cmNlIEF2YWlsYWJpbGl0eSIpLA0KT3V0Y29tZSA9IGMoIkV2YWx1YXRpb24gQW54aWV0eSIsIkV2YWx1YXRpb24gQW54aWV0eSIsIkV2YWx1YXRpb24gQW54aWV0eSIsDQoiTGVhcm5pbmcgQW54aWV0eSIsIkxlYXJuaW5nIEFueGlldHkiLCJMZWFybmluZyBBbnhpZXR5IiwNCiJMZWFybmluZyBBbnhpZXR5IiwiTGVhcm5pbmcgQW54aWV0eSIsIkxlYXJuaW5nIEFueGlldHkiKSwNCkJldGEgPSBjKC0uMTYsLS40OSwtLjE0LA0KLS4yMiwtLjQ1LC0uMDksDQoxLjU0LC0xLjg3LC4xMyksDQpTRSA9IGMoLjA0LC4wMywuMDQsDQouMDQsLjA0LC4wNCwNCi44MiwuODIsLjA0KSwNCnogPSBjKC0zLjkxLC0xNC41NiwtMy44OCwNCi01LjE0LC0xMi41OCwtMi41MCwNCjEuODgsLTIuMjksMy4wNyksDQpwID0gYygiPCAuMDAxIiwiPCAuMDAxIiwiPCAuMDAxIiwNCiI8IC4wMDEiLCI8IC4wMDEiLCIuMDEyIiwNCiIuMDYwIiwiLjAyMiIsIi4wMDIiKQ0KKQ0KDQprYWJsZShUYWJsZTIsIGNhcHRpb24gPSAiVGFibGUgMi4gU3RhbmRhcmRpemVkIFN0cnVjdHVyYWwgUmVncmVzc2lvbiBQYXRocyBQcmVkaWN0aW5nIE1hdGggQW54aWV0eSIpDQpgYGANCg0KQ29uc2lzdGVudCB3aXRoIGV4cGVjdGF0aW9ucywgDQoqICoqTW9yZSBlZmZlY3RpdmVseSB1c2luZyB0ZWNobm9sb2d5KiogcmVkdWNlZCBNRUEgKCRcYmV0YSA9IC0wLjE2JCwgJHAgPCAuMDAxJCkgYW5kIE1MQSAoJFxiZXRhID0gLTAuMjIkLCAkcCA8IC4wMDEkKS4gDQoqICoqSGlnaGVyIFNlbGYtZWZmaWNhY3kqKiBzdHVkZW50cyB0ZW5kZWQgdG8gaGF2ZSBsb3dlciBNRUEgKCRcYmV0YSA9IC0wLjQ5JCwgJHAgPCAuMDAxJCkgYW5kIE1MQSAoJFxiZXRhID0gLTAuNDUkLCAkcCA8IC4wMDEkKS4gDQoqICoqTW9yZSBFbmdhZ2VtZW50KiogcmVkdWNlZCBNTEEgKCRcYmV0YSA9IC0wLjA5JCwgJHAgPSAuMDEyJCksIGFuZCANCiogKipnZW5kZXIqIHdhcyBzaWduaWZpY2FudC4gTWFsZSBzdHVkZW50cyB0ZW5kZWQgdG8gaGF2ZSBsb3dlciBNRUEgKCRcYmV0YSA9IC0wLjE0JCwgJHAgPCAuMDAxJCkuDQoNClJlZ2FyZGluZyB0ZWFjaGluZyBhcHByb2FjaGVzLCANCiogKipzdHVkZW50LWNlbnRlcmVkIHN0cmF0ZWdpZXMqKiBzaWduaWZpY2FudGx5IHJlZHVjZWQgTUxBICgkXGJldGEgPSAtMS44NyQsICRwID0gLjAyMiQpLiANCiogKipUZWFjaGVyLWNlbnRlcmVkIHN0cmF0ZWdpZXMqKiBzaG93ZWQgYSBtYXJnaW5hbGx5IHBvc2l0aXZlIGFzc29jaWF0aW9uIHdpdGggTUxBICgkXGJldGEgPSAxLjU0JCwgJHAgPSAuMDYwJCk7IGhvd2V2ZXIsIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGluY2x1ZGVkIHplcm8uIE5laXRoZXIgc3RyYXRlZ3kgc2lnbmlmaWNhbnRseSBwcmVkaWN0ZWQgTUVBICgkcCA+IC4xMCQpLg0KDQpBIG1vZGVyYXRlLCBwb3NpdGl2ZSBjb3ZhcmlhbmNlIHJlbWFpbmVkIGJldHdlZW4gTUVBIGFuZCBNTEE6DQoNCiQkDQpccGhpX3tNRUEsTUxBfSA9IDAuNTAuDQokJA0KICANCiAgDQppbmRpY2F0aW5nIHRoYXQgc3R1ZGVudHMgd2hvIGV4cGVyaWVuY2VkIGFueGlldHkgZHVyaW5nIGxlYXJuaW5nIGFsc28gdGVuZGVkIHRvIGV4cGVyaWVuY2UgYW54aWV0eSBpbiBldmFsdWF0aXZlIHNpdHVhdGlvbnMuIFRoaXMgaXMgY29uc2lzdGVudCB3aXRoIGVpeHRpbmcgcmVzZWFyY2ggYXMgcmV2aWV3ZWQgZWFybGllci4NCg0KVGhlc2UgZmluZGluZ3Mgc3VnZ2VzdCB0aGF0IHN1cHBvcnRpdmUgaW5zdHJ1Y3Rpb25hbCBhcHByb2FjaGVz4oCUcGFydGljdWxhcmx5IHRob3NlIGVtcGhhc2l6aW5nIGNvbGxhYm9yYXRpb24sIGlucXVpcnksIGFuZCBzdHVkZW50IHBhcnRpY2lwYXRpb27igJRwbGF5IGFuIGltcG9ydGFudCByb2xlIGluIHJlZHVjaW5nIHN0dWRlbnRz4oCZIGVtb3Rpb25hbCBiYXJyaWVycyB0byBtYXRoZW1hdGljcyBsZWFybmluZy4NCg0KXA0KDQojIyBEaXNjdXNzaW9uDQoNClRoZSBwdXJwb3NlIG9mIHRoaXMgc3R1ZHkgd2FzIHRvIGV4YW1pbmUgaG93IHBlcmNlaXZlZCB0ZWFjaGluZyBzdHJhdGVnaWVzLCBzZWxmLWVmZmljYWN5LCB0ZWNobm9sb2d5IHVzZSwgZW5nYWdlbWVudCwgYW5kIHJlc291cmNlIGF2YWlsYWJpbGl0eSByZWxhdGUgdG8gdHdvIGZvcm1zIG9mIG1hdGhlbWF0aWNzIGFueGlldHk6ICoqTWF0aCBFdmFsdWF0aW9uIEFueGlldHkgKE1FQSkqKiBhbmQgKipNYXRoIExlYXJuaW5nIEFueGlldHkgKE1MQSkqKi4gVGhlIHJlc3VsdHMgb2YgdGhlIHN0cnVjdHVyYWwgZXF1YXRpb24gbW9kZWwgKFNFTSkgcHJvdmlkZWQgc3Ryb25nIHN1cHBvcnQgZm9yIHRoZSBoeXBvdGhlc2l6ZWQgYXNzb2NpYXRpb25zIGFuZCBoaWdobGlnaHRlZCBpbnN0cnVjdGlvbmFsIHByYWN0aWNlcyB0aGF0IG1heSBiZSBwYXJ0aWN1bGFybHkgZWZmZWN0aXZlIGZvciByZWR1Y2luZyBzdHVkZW50c+KAmSBlbW90aW9uYWwgY2hhbGxlbmdlcyBpbiBtYXRoZW1hdGljcyBjb250ZXh0cy4NCg0KIyMjIEludGVycHJldGF0aW9uIG9mIEtleSBGaW5kaW5ncw0KDQpDb25zaXN0ZW50IHdpdGggcHJldmlvdXMgcmVzZWFyY2gsICoqc3R1ZGVudC1jZW50ZXJlZCBzdHJhdGVnaWVzKiogc2lnbmlmaWNhbnRseSByZWR1Y2VkIGxlYXJuaW5nLXJlbGF0ZWQgYW54aWV0eSwgc3VnZ2VzdGluZyB0aGF0IGxlYXJuaW5nIGVudmlyb25tZW50cyBwcm9tb3RpbmcgY29sbGFib3JhdGlvbiwgaW5xdWlyeSwgYW5kIGFjdGl2ZSBlbmdhZ2VtZW50IGNhbiBtaXRpZ2F0ZSBuZWdhdGl2ZSBlbW90aW9uYWwgcmVzcG9uc2VzLiBTdWNoIHByYWN0aWNlcyBtYXkgaGVscCBzdHVkZW50cyBmZWVsIG1vcmUgY29tcGV0ZW50IGFuZCBzdXBwb3J0ZWQsIHJlZHVjaW5nIGFueGlldHkgZHVyaW5nIG1hdGggbGVhcm5pbmcuDQoNCioqVGVhY2hlci1jZW50ZXJlZCBhcHByb2FjaGVzKiogc2hvd2VkIGEgbWFyZ2luYWxseSBwb3NpdGl2ZSBhc3NvY2lhdGlvbiB3aXRoIGxlYXJuaW5nIGFueGlldHkuIFdoaWxlIGRpcmVjdCBpbnN0cnVjdGlvbiBtYXkgcHJvdmlkZSBjbGFyaXR5IGFuZCBzdHJ1Y3R1cmUsIGV4Y2Vzc2l2ZSBlbXBoYXNpcyBvbiBwZXJmb3JtYW5jZSBhbmQgY29ycmVjdG5lc3MgbWF5IGluYWR2ZXJ0ZW50bHkgaGVpZ2h0ZW4gcHJlc3N1cmUgYW5kIGxlYWQgdG8gaW5jcmVhc2VkIGFueGlldHkgKFJhbWlyZXogZXQgYWwuLCAyMDE4KS4gVGhlc2UgcmVzdWx0cyBzdWdnZXN0IHRoYXQgYWx0aG91Z2ggdGVhY2hlciBndWlkYW5jZSByZW1haW5zIGltcG9ydGFudCwgYmFsYW5jZWQgaW5zdHJ1Y3Rpb25hbCBhcHByb2FjaGVzIG1heSBiZSBuZWNlc3NhcnkgdG8gcHJldmVudCBhZHZlcnNlIGVtb3Rpb25hbCBlZmZlY3RzLg0KDQpCb3RoICoqc2VsZi1lZmZpY2FjeSoqIGFuZCAqKnRlY2hub2xvZ3kgdXNlKiogY29uc2lzdGVudGx5IHByZWRpY3RlZCBsb3dlciBNRUEgYW5kIE1MQS4gU3R1ZGVudHMgd2hvIGJlbGlldmUgaW4gdGhlaXIgYWJpbGl0eSB0byBzdWNjZWVkIHRlbmQgdG8gYXBwcm9hY2ggbWF0aCB0YXNrcyB3aXRoIG1vcmUgY29uZmlkZW5jZSBhbmQgcGVyc2lzdGVuY2UsIHdoaWNoIHByb3RlY3RzIGFnYWluc3QgYW54aWV0eSAoQmFuZHVyYSwgMTk5NzsgVXNoZXIgZXQgYWwuLCAyMDE5KS4gVGVjaG5vbG9neS1lbmhhbmNlZCBsZWFybmluZyBvcHBvcnR1bml0aWVz4oCUc3VjaCBhcyBpbW1lZGlhdGUgZmVlZGJhY2sgYW5kIGludGVyYWN0aXZlIHByYWN0aWNl4oCUbWF5IGFsc28gaW5jcmVhc2UgY29tZm9ydCBhbmQgY29udHJvbCB3aGVuIGVuZ2FnaW5nIHdpdGggbWF0aCBjb250ZW50Lg0KDQpBbHRob3VnaCBzbWFsbGVyIGluIG1hZ25pdHVkZSwgKiplbmdhZ2VtZW50KiogYWxzbyBjb250cmlidXRlZCB0byByZWR1Y2VkIGFueGlldHkgZHVyaW5nIGxlYXJuaW5nLiBXaGVuIHN0dWRlbnRzIGFyZSBlbW90aW9uYWxseSBhbmQgYmVoYXZpb3JhbGx5IGludmVzdGVkIGluIG1hdGggYWN0aXZpdGllcywgdGhleSBtYXkgZXhwZXJpZW5jZSBpbmNyZWFzZWQgZW5qb3ltZW50IGFuZCByZWR1Y2VkIGF2b2lkYW5jZSB0ZW5kZW5jaWVzIChEb3drZXIgZXQgYWwuLCAyMDE2KS4gSW4gY29udHJhc3QsICoqcmVzb3VyY2UgYXZhaWxhYmlsaXR5Kiogd2FzIGFzc29jaWF0ZWQgd2l0aCBzbGlnaHRseSBoaWdoZXIgbGVhcm5pbmcgYW54aWV0eS4gVGhpcyBtYXkgcmVmbGVjdCBoZWlnaHRlbmVkIGV4cGVjdGF0aW9ucyBvciBwZXJjZWl2ZWQgcHJlc3N1cmUgdG8gbWVldCBhY2FkZW1pYyBzdGFuZGFyZHMgd2hlbiBtb3JlIHN1cHBvcnRzIGFyZSBhdmFpbGFibGUuDQoNCkZpbmFsbHksIHRoZSAqKnBvc2l0aXZlIGNvdmFyaWFuY2UqKiBiZXR3ZWVuIE1FQSBhbmQgTUxBIGluZGljYXRlZCBtZWFuaW5nZnVsIG92ZXJsYXAgYmV0d2VlbiB0aGUgdHdvIGNvbnN0cnVjdHMsIGNvbnNpc3RlbnQgd2l0aCB0aGUgbGl0ZXJhdHVyZSBzaG93aW5nIHNoYXJlZCBlbW90aW9uYWwsIGNvZ25pdGl2ZSwgYW5kIG1vdGl2YXRpb25hbCB1bmRlcnBpbm5pbmdzIG9mIGRpZmZlcmVudCBmb3JtcyBvZiBtYXRoIGFueGlldHkgKEFzaGNyYWZ0ICYgTW9vcmUsIDIwMDkpLiBUb2dldGhlciwgdGhlc2UgZmluZGluZ3MgZW1waGFzaXplIHRoZSBpbXBvcnRhbmNlIG9mIGluc3RydWN0aW9uYWwgYW5kIG1vdGl2YXRpb25hbCBmYWN0b3JzIGluIHNoYXBpbmcgc3R1ZGVudHPigJkgbWF0aC1yZWxhdGVkIGVtb3Rpb25hbCBleHBlcmllbmNlcy4NCg0KIyMjIEltcGxpY2F0aW9ucw0KDQpUaGVzZSBmaW5kaW5ncyBzdWdnZXN0IHRoYXQgZWR1Y2F0b3JzIHNob3VsZCBmb3N0ZXIgZW52aXJvbm1lbnRzIHRoYXQgcHJvbW90ZSBzdHVkZW50IGF1dG9ub215IGFuZCBjb25maWRlbmNlLCB3aGlsZSB1c2luZyBpbnN0cnVjdGlvbmFsIHN1cHBvcnRzIHRoYXQgZW5oYW5jZSB1bmRlcnN0YW5kaW5nIHdpdGhvdXQgaW5jcmVhc2luZyBwZXJjZWl2ZWQgcHJlc3N1cmUuIFByb2Zlc3Npb25hbCBsZWFybmluZyBwcm9ncmFtcyBtYXkgYmVuZWZpdCBmcm9tIGVtcGhhc2l6aW5nIHN0cmF0ZWdpZXMgdGhhdCBidWlsZCBlbW90aW9uYWwgc2FmZXR5IGFuZCBzdXBwb3J0IHN0dWRlbnRz4oCZIGJlbGllZiBpbiB0aGVpciBtYXRoZW1hdGljYWwgY2FwYWJpbGl0eSAoSGVtYnJlZSwgMTk5MCkuIEFkZGl0aW9uYWxseSwgdGVjaG5vbG9neSB0b29scyBzaG91bGQgYmUgbGV2ZXJhZ2VkIHN0cmF0ZWdpY2FsbHkgdG8gcHJvbW90ZSBhY3RpdmUgcGFydGljaXBhdGlvbiBhbmQgc2VsZi1wYWNlZCBlbmdhZ2VtZW50LCByYXRoZXIgdGhhbiBhcyBzdGFuZC1hbG9uZSByZXNvdXJjZXMuDQoNCiMjIyBMaW1pdGF0aW9ucyBhbmQgRnV0dXJlIERpcmVjdGlvbnMNCg0KVGhlIGNyb3NzLXNlY3Rpb25hbCBkZXNpZ24gbGltaXRzIHRoZSBhYmlsaXR5IHRvIGRyYXcgY2F1c2FsIGNvbmNsdXNpb25zLiBMb25naXR1ZGluYWwgYW5kIGludGVydmVudGlvbi1iYXNlZCByZXNlYXJjaCBjb3VsZCBzdHJlbmd0aGVuIHVuZGVyc3RhbmRpbmcgb2YgaG93IHRoZSBpZGVudGlmaWVkIGZhY3RvcnMgY29udHJpYnV0ZSB0byBhbnhpZXR5IHJlZHVjdGlvbiBvdmVyIHRpbWUuIFNlbGYtcmVwb3J0IHN1cnZleSBtZXRob2RzIG1heSBpbnRyb2R1Y2Ugc29jaWFsIGRlc2lyYWJpbGl0eSBvciByZWNhbGwgYmlhczsgdGhlcmVmb3JlLCBtdWx0aW1ldGhvZCBhcHByb2FjaGVzIGluY29ycG9yYXRpbmcgb2JzZXJ2YXRpb25hbCBvciBwaHlzaW9sb2dpY2FsIGRhdGEgY291bGQgZnVydGhlciB2YWxpZGF0ZSBmaW5kaW5ncy4gRnV0dXJlIHdvcmsgbWF5IGFsc28gZXhwbG9yZSBpbnN0cnVjdGlvbmFsIGNvbnRleHQsIHN1Y2ggYXMgY2xhc3Nyb29tIGNsaW1hdGUgb3IgdGVhY2hlciBhdHRpdHVkZXMsIGFzIG1vZGVyYXRvcnMgb2YgdGhlIGFueGlldHnigJNzdHJhdGVneSByZWxhdGlvbnNoaXAuDQoNCiMjIyBDb25jbHVzaW9uDQoNCk92ZXJhbGwsIHRoaXMgc3R1ZHkgZGVtb25zdHJhdGVzIHRoYXQgbWF0aCBhbnhpZXR5IGlzIHNoYXBlZCBieSBhIGNvbWJpbmF0aW9uIG9mIGluc3RydWN0aW9uYWwgcHJhY3RpY2VzIGFuZCBwZXJzb25hbCBiZWxpZWZzLiBFbmNvdXJhZ2luZyBzdHVkZW50LWNlbnRlcmVkIGluc3RydWN0aW9uLCBzZWxmLWVmZmljYWN5IGJ1aWxkaW5nLCB0ZWNobm9sb2d5IGludGVncmF0aW9uLCBhbmQgaGlnaC1xdWFsaXR5IGVuZ2FnZW1lbnQgY2FuIHN1YnN0YW50aWFsbHkgcmVkdWNlIGJvdGggbGVhcm5pbmctcmVsYXRlZCBhbmQgZXZhbHVhdGlvbi1yZWxhdGVkIGFueGlldHkuIFRoZXNlIHJlc3VsdHMgdW5kZXJzY29yZSB0aGUgaW1wb3J0YW5jZSBvZiBzdXBwb3J0aW5nIHN0dWRlbnRz4oCZIGVtb3Rpb25hbCB3ZWxsLWJlaW5nIGFzIGEgZm91bmRhdGlvbiBmb3IgdGhlaXIgbWF0aGVtYXRpY2FsIHN1Y2Nlc3MuDQoNCg0KXA0KDQojIFJlZmVyZW5jZXMNCg0KQXNoY3JhZnQsIE0uIEguICgyMDAyKS4gTWF0aCBhbnhpZXR5OiBQZXJzb25hbCwgZWR1Y2F0aW9uYWwsIGFuZCBjb2duaXRpdmUgY29uc2VxdWVuY2VzLiBDdXJyZW50IGRpcmVjdGlvbnMgaW4gcHN5Y2hvbG9naWNhbCBzY2llbmNlLCAxMSg1KSwgMTgxLTE4NS4NCg0KQXNoY3JhZnQsIE0uIEguLCAmIE1vb3JlLCBBLiBNLiAoMjAwOSkuIE1hdGhlbWF0aWNzIGFueGlldHkgYW5kIHRoZSBhZmZlY3RpdmUgZHJvcCBpbiBwZXJmb3JtYW5jZS4gSm91cm5hbCBvZiBQc3ljaG9lZHVjYXRpb25hbCBhc3Nlc3NtZW50LCAyNygzKSwgMTk3LTIwNS4NCg0KQXNwYXJvdWhvdiwgVC4sICYgTXV0aMOpbiwgQi4gKDIwMDUsIE5vdmVtYmVyKS4gTXVsdGl2YXJpYXRlIHN0YXRpc3RpY2FsIG1vZGVsaW5nIHdpdGggc3VydmV5IGRhdGEuIEluIFByb2NlZWRpbmdzIG9mIHRoZSBGZWRlcmFsIENvbW1pdHRlZSBvbiBTdGF0aXN0aWNhbCBNZXRob2RvbG9neSAoRkNTTSkgcmVzZWFyY2ggY29uZmVyZW5jZSAocHAuIDE0LTE2KS4NCg0KQmFuZGFsb3MsIEQuIEwuICgyMDE4KS4gTWVhc3VyZW1lbnQgdGhlb3J5IGFuZCBhcHBsaWNhdGlvbnMgZm9yIHRoZSBzb2NpYWwgc2NpZW5jZXMuIEd1aWxmb3JkIFB1YmxpY2F0aW9ucy4NCg0KQmFuZHVyYSwgQS4gKDE5OTcpLiBTZWxmLWVmZmljYWN5OiBUaGUgZXhlcmNpc2Ugb2YgY29udHJvbCAoVm9sLiAxMSkuIEZyZWVtYW4uDQoNCkJvYWxlciwgSi4gKDIwMTUpLiBNYXRoZW1hdGljYWwgbWluZHNldHM6IFVubGVhc2hpbmcgc3R1ZGVudHMnIHBvdGVudGlhbCB0aHJvdWdoIGNyZWF0aXZlIG1hdGgsIGluc3BpcmluZyBtZXNzYWdlcyBhbmQgaW5ub3ZhdGl2ZSB0ZWFjaGluZy4gSm9obiBXaWxleSAmIFNvbnMuDQoNCkJvcmljaCwgRy4gRC4gKDIwMTcpLiBFZmZlY3RpdmUgVGVhY2hpbmcgTWV0aG9kczogUmVzZWFyY2gtQmFzZWQgUHJhY3RpY2UgKDl0aCBlZC4pLiBQZWFyc29uLiANCg0KQnJvd24sIEguIEQuLCAmIExlZSwgSC4gKDE5OTQpLiBUZWFjaGluZyBieSBwcmluY2lwbGVzOiBBbiBpbnRlcmFjdGl2ZSBhcHByb2FjaCB0byBsYW5ndWFnZSBwZWRhZ29neSAoVm9sLiAxLCBwLiA5OTQpLiBFbmdsZXdvb2QgQ2xpZmZzLCBOSjogUHJlbnRpY2UgSGFsbCBSZWdlbnRzLg0KDQpCcm93biwgVC4gQS4gKDIwMTUpLiBDb25maXJtYXRvcnkgZmFjdG9yIGFuYWx5c2lzIGZvciBhcHBsaWVkIHJlc2VhcmNoLiBHdWlsZm9yZCBwdWJsaWNhdGlvbnMuDQoNCkJydW5lciwgSi4gUy4gKDE5NjEpLiBUaGUgYWN0IG9mIGRpc2NvdmVyeS4gSGFydmFyZCBlZHVjYXRpb25hbCByZXZpZXcuDQpDYXR0ZWxsLCBSLiBCLiAoMTk1MikuIEZhY3RvciBhbmFseXNpczogYW4gaW50cm9kdWN0aW9uIGFuZCBtYW51YWwgZm9yIHRoZSBwc3ljaG9sb2dpc3QgYW5kIHNvY2lhbCBzY2llbnRpc3QuDQoNCkNoYW5nLCBILiwgJiBCZWlsb2NrLCBTLiBMLiAoMjAxNikuIFRoZSBtYXRoIGFueGlldHktbWF0aCBwZXJmb3JtYW5jZSBsaW5rIGFuZCBpdHMgcmVsYXRpb24gdG8gaW5kaXZpZHVhbCBhbmQgZW52aXJvbm1lbnRhbCBmYWN0b3JzOiBBIHJldmlldyBvZiBjdXJyZW50IGJlaGF2aW9yYWwgYW5kIHBzeWNob3BoeXNpb2xvZ2ljYWwgcmVzZWFyY2guIEN1cnJlbnQgT3BpbmlvbiBpbiBCZWhhdmlvcmFsIFNjaWVuY2VzLCAxMCwgMzPigJMzOC4NCg0KQ3JvbmJhY2gsIEwuIEouICgxOTUxKS4gQ29lZmZpY2llbnQgYWxwaGEgYW5kIHRoZSBpbnRlcm5hbCBzdHJ1Y3R1cmUgb2YgdGVzdHMuIEJpb21ldHJpa2EsIDE2LCAyOTfigJMzMzUuDQoNCkRha2VyLCBSLiBKLiwgR2F0dGFzLCBTLiBVLiwgU29rb2xvd3NraSwgSC4gTS4sIEdyZWVuLCBBLiBFLiwgJiBMeW9ucywgSS4gTS4gKDIwMjEpLiBGaXJzdC15ZWFyIHN0dWRlbnRz4oCZIG1hdGggYW54aWV0eSBwcmVkaWN0cyBTVEVNIGF2b2lkYW5jZSBhbmQgdW5kZXJwZXJmb3JtYW5jZSB0aHJvdWdob3V0IHVuaXZlcnNpdHksIGluZGVwZW5kZW50bHkgb2YgbWF0aCBhYmlsaXR5LiBOcGogU2NpZW5jZSBvZiBMZWFybmluZywgNigxKSwgMTcuDQoNCkRldmluZSwgQS4sIEZhd2NldHQsIEsuLCBTesWxY3MsIEQuLCAmIERvd2tlciwgQS4gKDIwMTIpLiBHZW5kZXIgZGlmZmVyZW5jZXMgaW4gbWF0aGVtYXRpY3MgYW54aWV0eSBhbmQgdGhlIHJlbGF0aW9uIHRvIG1hdGhlbWF0aWNzIHBlcmZvcm1hbmNlIHdoaWxlIGNvbnRyb2xsaW5nIGZvciB0ZXN0IGFueGlldHkuIEJlaGF2aW9yYWwgYW5kIGJyYWluIGZ1bmN0aW9ucywgOCgxKSwgMzMuDQoNCkRpU3RlZmFubywgQy4sIFpodSwgTS4sICYgTWluZHJpbGEsIEQuICgyMDA5KS4gVW5kZXJzdGFuZGluZyBhbmQgdXNpbmcgZmFjdG9yIHNjb3JlczogQ29uc2lkZXJhdGlvbnMgZm9yIHRoZSBhcHBsaWVkIHJlc2VhcmNoZXIuIFByYWN0aWNhbCBhc3Nlc3NtZW50LCByZXNlYXJjaCwgYW5kIGV2YWx1YXRpb24sIDE0KDEpLg0KDQpEb3drZXIsIEEuLCBTYXJrYXIsIEEuLCAmIExvb2ksIEMuIFkuICgyMDE2KS4gTWF0aGVtYXRpY3MgYW54aWV0eTogV2hhdCBoYXZlIHdlIGxlYXJuZWQgaW4gNjAgeWVhcnM/LiBGcm9udGllcnMgaW4gcHN5Y2hvbG9neSwgNywgNTA4Lg0KDQpEcmVnZXIsIFIuIE0uLCAmIEFpa2VuIEpyLCBMLiBSLiAoMTk1NykuIFRoZSBpZGVudGlmaWNhdGlvbiBvZiBudW1iZXIgYW54aWV0eSBpbiBhIGNvbGxlZ2UgcG9wdWxhdGlvbi4gSm91cm5hbCBvZiBFZHVjYXRpb25hbCBQc3ljaG9sb2d5LCA0OCg2KSwgMzQ0Lg0KDQpEdW5jYW4sIE8uIEQuICgxOTYxKS4gQSBzb2Npb2Vjb25vbWljIGluZGV4IGZvciBhbGwgb2NjdXBhdGlvbnMuIE9jY3VwYXRpb25zIGFuZCBzb2NpYWwgc3RhdHVzLi4NCg0KRHdlY2ssIEMuIFMuICgyMDA2KS4gTWluZHNldDogVGhlIG5ldyBwc3ljaG9sb2d5IG9mIHN1Y2Nlc3MuIFJhbmRvbSBob3VzZS4NCg0KRWxzZS1RdWVzdCwgTi4gTS4sIEh5ZGUsIEouIFMuLCAmIExpbm4sIE0uIEMuICgyMDEwKS4gQ3Jvc3MtbmF0aW9uYWwgcGF0dGVybnMgb2YgZ2VuZGVyIGRpZmZlcmVuY2VzIGluIG1hdGhlbWF0aWNzOiBhIG1ldGEtYW5hbHlzaXMuIFBzeWNob2xvZ2ljYWwgYnVsbGV0aW4sIDEzNigxKSwgMTAzLg0KDQpGaW5uZXksIFMuIEouLCAmIERpU3RlZmFubywgQy4gKDIwMDYpLiBOb24tbm9ybWFsIGFuZCBjYXRlZ29yaWNhbCBkYXRhIGluIHN0cnVjdHVyYWwgZXF1YXRpb24gbW9kZWxpbmcuIFN0cnVjdHVyYWwgZXF1YXRpb24gbW9kZWxpbmc6IEEgc2Vjb25kIGNvdXJzZSwgMTAoNiksIDI2OS0zMTQuDQoNCkZsb3JhLCBELiBCLiAoMjAxNykuIFN0YXRpc3RpY2FsIE1ldGhvZHMgZm9yIHRoZSBTb2NpYWwgYW5kIEJlaGF2aW91cmFsIFNjaWVuY2VzOiBBIE1vZGVsLUJhc2VkIEFwcHJvYWNoLiBTQUdFLg0KDQpGb2dhcnR5LCBSLiAoMTk5MSkuIFRoZSBtaW5kZnVsIHNjaG9vbDogSG93IHRvIGludGVncmF0ZSB0aGUgY3VycmljdWxhLiBQYWxhdGluZSwgSUwuIFNreUxpZ2h0IFB1Ymxpc2hpbmcsIEluYy4gUmV0cmlldmVkIEZlYnJ1YXJ5LCAyMiwgMjAwMi4NCg0KR2llcmwsIE0uIEouLCAmIEJpc2FueiwgSi4gKDE5OTUpLiBBbnhpZXRpZXMgYW5kIGF0dGl0dWRlcyByZWxhdGVkIHRvIG1hdGhlbWF0aWNzIGluIGdyYWRlcyAzIGFuZCA2LiBUaGUgSm91cm5hbCBvZiBleHBlcmltZW50YWwgZWR1Y2F0aW9uLCA2MygyKSwgMTM5LTE1OC4NCg0KR29ldHosIFQuLCBCaWVnLCBNLiwgTMO8ZHRrZSwgTy4sIFBla3J1biwgUi4sICYgSGFsbCwgTi4gQy4gKDIwMTMpLiBEbyBnaXJscyByZWFsbHkgZXhwZXJpZW5jZSBtb3JlIGFueGlldHkgaW4gbWF0aGVtYXRpY3M/LiBQc3ljaG9sb2dpY2FsIHNjaWVuY2UsIDI0KDEwKSwgMjA3OS0yMDg3Lg0KDQpHb3VnaCwgTWFyeSBPLiAoMTk1NCkuIFdoeSBmYWlsdXJlcyBpbiBtYXRoZW1hdGljcz8gTWF0aGVtYXBob2JpYTogQ2F1c2VzIGFuZCB0cmVhdG1lbnRzLiBUaGUgQ2xlYXJpbmcgSG91c2U6IEEgSm91cm5hbCBvZiBFZHVjYXRpb25hbCBTdHJhdGVnaWVzLCBJc3N1ZXMgYW5kIElkZWFzLCAyOCg1KSwgMjkw4oCTMjk0LiANCg0KR3V0dG1hbiwgTC4gKDE5NTQpLiBTb21lIG5lY2Vzc2FyeSBjb25kaXRpb25zIGZvciBjb21tb24tZmFjdG9yIGFuYWx5c2lzLiBQc3ljaG9tZXRyaWthLCAxOSgyKSwgMTQ5LTE2MS4NCg0KSGF0dGllLCBKLiAoMjAxMikuIFZpc2libGUgbGVhcm5pbmcgZm9yIHRlYWNoZXJzOiBNYXhpbWl6aW5nIGltcGFjdCBvbiBsZWFybmluZy4gUm91dGxlZGdlLg0KDQpIZW1icmVlLCBSLiAoMTk5MCkuIFRoZSBuYXR1cmUsIGVmZmVjdHMsIGFuZCByZWxpZWYgb2YgbWF0aGVtYXRpY3MgYW54aWV0eS4gSm91cm5hbCBmb3IgcmVzZWFyY2ggaW4gbWF0aGVtYXRpY3MgZWR1Y2F0aW9uLCAyMSgxKSwgMzMtNDYuDQoNCkhvcGtvLCBELiBSLiwgTWFoYWRldmFuLCBSLiwgQmFyZSwgUi4gTC4sICYgSHVudCwgTS4gSy4gKDIwMDMpLiBUaGUgYWJicmV2aWF0ZWQgbWF0aCBhbnhpZXR5IHNjYWxlIChBTUFTKSBjb25zdHJ1Y3Rpb24sIHZhbGlkaXR5LCBhbmQgcmVsaWFiaWxpdHkuIEFzc2Vzc21lbnQsIDEwKDIpLCAxNzjigJMxODIuDQoNCiBIaXJzY2hiZXJnLCBFLiwgJiBTdGFuZGlzaCwgQy4gVi4gKDE5NTkpLiBBIG1ldGhvZCBvZiBkZXJpdmluZyBhIHN0cmF0aWZpY2F0aW9uIHNjb3JlIGJ5IHVzaW5nIHRoZSBwcmluY2lwYWwgY29tcG9uZW50cyBvZiB0aGUgY29ycmVsYXRpb24gbWF0cml4LiBBbWVyaWNhbiBTdGF0aXN0aWNhbCBBc3NvY2lhdGlvbiwgUHJvY2VlZGluZ3Mgb2YgdGhlIFNvY2lhbCBTdGF0aXN0aWNzIFNlY3Rpb24sIDE5NTksIDIyMC0yMjUuDQoNCkphY29icywgSC4gSC4gKDE5ODkpLiBJbnRlcmRpc2NpcGxpbmFyeSBjdXJyaWN1bHVtOiBEZXNpZ24gYW5kIGltcGxlbWVudGF0aW9uLiBBc3NvY2lhdGlvbiBmb3IgU3VwZXJ2aXNpb24gYW5kIEN1cnJpY3VsdW0gRGV2ZWxvcG1lbnQsIDEyNTAgTi4gUGl0dCBTdHJlZXQsIEFsZXhhbmRyaWEsIFZBIDIyMzE0Lg0KDQpKb2xsaWZmZSwgSS4gVC4sICYgQ2FkaW1hLCBKLiAoMjAxNikuIFByaW5jaXBhbCBDb21wb25lbnQgQW5hbHlzaXM6IEEgUmV2aWV3IGFuZCBSZWNlbnQgRGV2ZWxvcG1lbnRzLiBQaGlsb3NvcGhpY2FsIFRyYW5zYWN0aW9ucyBvZiB0aGUgUm95YWwgU29jaWV0eSBBLCAzNzQoMjA2NSksIDIwMTUwMjAyLg0KDQpKb2huc29uLCBELiBXLiwgSm9obnNvbiwgUi4gVC4sICYgU21pdGgsIEsuIEEuICgyMDE0KS4gQ29vcGVyYXRpdmUgbGVhcm5pbmc6IEltcHJvdmluZyB1bml2ZXJzaXR5IGluc3RydWN0aW9uIGJ5IGJhc2luZyBwcmFjdGljZSBvbiB2YWxpZGF0ZWQgdGhlb3J5LiBKb3VybmFsIG9uIGV4Y2VsbGVuY2UgaW4gY29sbGVnZSB0ZWFjaGluZywgMjUoMyY0KS4NCg0KSm9zZSBNLiBDYXJkaW5vIEpyLiBhbmQgUnV0aCBBLiBPcnRlZ2EtRGVsYSBDcnV6LCBVbmRlcnN0YW5kaW5nIG9mIGxlYXJuaW5nIHN0eWxlcyBhbmQgdGVhY2hpbmcgc3RyYXRlZ2llcyB0b3dhcmRzIGltcHJvdmluZyB0aGUgdGVhY2hpbmcgYW5kIGxlYXJuaW5nIG9mIG1hdGhlbWF0aWNzLCBMVU1BVCBHZW5lcmFsIElzc3VlLCAgVm9sIDggTm8gMSAoMjAyMCksIDE54oCTNDMuIERvaTogMTAuMzExMjkvIExVTUFULjguMS4xMzQ4DQoNCkpveWNlLCBCLiwgV2VpbCwgTS4sICYgQ2FsaG91biwgRS4gKDIwMTUpLiBNb2RlbHMgb2YgVGVhY2hpbmcgKDl0aCBlZC4pLiBQZWFyc29uLg0KDQpLbGVlLCBILiBMLiwgQnVlaGwsIE0uIE0uLCAmIE1pbGxlciwgQS4gRC4gKDIwMjIpLiBTdHJhdGVnaWVzIGZvciBhbGxldmlhdGluZyBzdHVkZW50c+KAmSBtYXRoIGFueGlldHk6IENvbnRyb2wtdmFsdWUgdGhlb3J5IGluIHByYWN0aWNlLiBUaGVvcnkgSW50byBQcmFjdGljZSwgNjEoMSksIDQ54oCTNjEuDQoNCktsaW5lLCBSLiBCLiAoMjAyMykuIFByaW5jaXBsZXMgYW5kIHByYWN0aWNlIG9mIHN0cnVjdHVyYWwgZXF1YXRpb24gbW9kZWxpbmcuIEd1aWxmb3JkIHB1YmxpY2F0aW9ucy4NCg0KTGF6YXJzZmVsZCwgUC4gRi4sIFN0b3VmZmVyLCBTLiBBLiwgR3V0dG1hbiwgTC4sICYgU3VjaG1hbiwgRS4gQS4gKDE5NTApLiBNZWFzdXJlbWVudCBhbmQgcHJlZGljdGlvbi4gU0EgU3RvdWZmZXIgKMOpZC4pIFN0dWRpZXMgaW4gc29jaWFsIHBzeWNob2xvZ3kgaW4gd29ybGQgd2FyIElJLCA0Lg0KDQpMaSwgQy4gSC4gKDIwMTYpLiBUaGUgcGVyZm9ybWFuY2Ugb2YgTUwsIERXTFMsIGFuZCBVTFMgZXN0aW1hdGlvbiB3aXRoIHJvYnVzdCBjb3JyZWN0aW9ucyBpbiBzdHJ1Y3R1cmFsIGVxdWF0aW9uIG1vZGVscyB3aXRoIG9yZGluYWwgdmFyaWFibGVzLiBQc3ljaG9sb2dpY2FsIG1ldGhvZHMsIDIxKDMpLCAzNjkuDQoNCkzDs3Blei1Cb25pbGxhLCBKLiBNLmwgYW5kIEzDs3Blei1Cb25pbGxhLCBMLiBNLiAoMjAxMiksIFZhbGlkYXRpb24gb2YgYW4gaW5mb3JtYXRpb24gdGVjaG5vbG9neSBhbnhpZXR5IHNjYWxlIGluIHVuZGVyZ3JhZHVhdGVzLCBCcml0aXNoIEpvdXJuYWwgb2YgRWR1Y2F0aW9uYWwgVGVjaG5vbG9neSBWb2wgNDMuIE5vIDIuICBFNTbigJNFNTguICBkb2k6MTAuMTExMS9qLjE0NjctODUzNS4yMDExLjAxMjU2LngNCg0KTWFsb25leSwgRS4gQS4sICYgQmVpbG9jaywgUy4gTC4gKDIwMTIpLiBNYXRoIGFueGlldHk6IFdobyBoYXMgaXQsIHdoeSBpdCBkZXZlbG9wcywgYW5kIGhvdyB0byBndWFyZCBhZ2FpbnN0IGl0LiBUcmVuZHMgaW4gY29nbml0aXZlIHNjaWVuY2VzLCAxNig4KSwgNDA0LTQwNi4NCg0KTWFyc2gsIEguIFcuICgxOTk2KS4gUG9zaXRpdmUgYW5kIG5lZ2F0aXZlIHNlbGYtZXN0ZWVtOiBBIHN1YnN0YW50aXZlbHkgbWVhbmluZ2Z1bCBkaXN0aW5jdGlvbiBvciBhcnRpZmFjdG9ycz8gSm91cm5hbCBvZiBQZXJzb25hbGl0eSBhbmQgU29jaWFsIFBzeWNob2xvZ3ksIDcwKDQpLCA4MTDigJM4MTkuDQoNCk1jRG9uYWxkLCBSLiBQLiAoMTk5OSkuIFRlc3QgdGhlb3J5OiBBIHVuaWZpZWQgdHJlYXRtZW50LiBNYWh3YWg6IEVybGJhdW0uDQoNCk1vbGluZXIsIEwuLCAmIEFsZWdyZSwgRi4gKDIwMjApLiBQZWVyIHR1dG9yaW5nIGVmZmVjdHMgb24gc3R1ZGVudHPigJkgbWF0aGVtYXRpY3MgYW54aWV0eTogQSBtaWRkbGUgc2Nob29sIGV4cGVyaWVuY2UuIEZyb250aWVycyBpbiBQc3ljaG9sb2d5LCAxMSwgMTYxMC4NCg0KTXV0aMOpbiwgQi4gKDE5ODQpLiBBIGdlbmVyYWwgc3RydWN0dXJhbCBlcXVhdGlvbiBtb2RlbCB3aXRoIGRpY2hvdG9tb3VzLCBvcmRlcmVkIGNhdGVnb3JpY2FsLCBhbmQgY29udGludW91cyBsYXRlbnQgdmFyaWFibGUgaW5kaWNhdG9ycy4gUHN5Y2hvbWV0cmlrYSwgNDkoMSksIDExNS0xMzIuDQoNCk/igJlMZWFyeSwgSy4sIEZpdHpwYXRyaWNrLCBDLiBMLiwgJiBIYWxsZXR0LCBELiAoMjAxNykuIE1hdGggYW54aWV0eSBpcyByZWxhdGVkIHRvIHNvbWUsIGJ1dCBub3QgYWxsLCBleHBlcmllbmNlcyB3aXRoIG1hdGguIEZyb250aWVycyBpbiBQc3ljaG9sb2d5LCA4LCAyMDY3Lg0KDQpPcm1yb2QsIEouIEUuICgyMDIwKS4gSHVtYW4gTGVhcm5pbmcgKDh0aCBlZC4pLiBQZWFyc29uDQoNCk9sc3NvbiwgVS4gKDE5NzkpLiBNYXhpbXVtIGxpa2VsaWhvb2QgZXN0aW1hdGlvbiBvZiB0aGUgcG9seWNob3JpYyBjb3JyZWxhdGlvbiBjb2VmZmljaWVudC4gIFBzeWNob21ldHJpa2EsIDQ0KDQpLCA0NDMtNDYwLg0KDQpQbGV0emVyLCBCLiwgV29vZCwgRy4sIFNjaGVybmRsLCBULiwgS2Vyc2NoYmF1bSwgSC4gSC4sICYgTnVlcmssIEguQy4gKDIwMTYpLiBDb21wb25lbnRzIG9mIG1hdGhlbWF0aWNzIGFueGlldHk6IEZhY3RvciBtb2RlbGluZyBvZiB0aGUgTUFSUzMwLWJyaWVmLiBGcm9udGllcnMgaW4gUHN5Y2hvbG9neSwgNywgOTEuDQoNClByaW5jZSwgTS4gSi4sICYgRmVsZGVyLCBSLiBNLiAoMjAwNikuIEluZHVjdGl2ZSB0ZWFjaGluZyBhbmQgbGVhcm5pbmcgbWV0aG9kczogRGVmaW5pdGlvbnMsIGNvbXBhcmlzb25zLCBhbmQgcmVzZWFyY2ggYmFzZXMuIEpvdXJuYWwgb2YgZW5naW5lZXJpbmcgZWR1Y2F0aW9uLCA5NSgyKSwgMTIzLTEzOC4NCg0KUmFtaXJleiwgRy4sIFNoYXcsIFMuIFQuLCAmIE1hbG9uZXksIEUuIEEuICgyMDE4KS4gTWF0aCBhbnhpZXR5OiBQYXN0IHJlc2VhcmNoLCBwcm9taXNpbmcgaW50ZXJ2ZW50aW9ucywgYW5kIGEgbmV3IGludGVycHJldGF0aW9uIGZyYW1ld29yay4gRWR1Y2F0aW9uYWwgcHN5Y2hvbG9naXN0LCA1MygzKSwgMTQ1LTE2NC4NCg0KUmljaGFyZHNvbiwgRi4gQy4sICYgU3Vpbm4sIFIuIE0uICgxOTcyKS4gVGhlIG1hdGhlbWF0aWNzIGFueGlldHkgcmF0aW5nIHNjYWxlOiBQc3ljaG9tZXRyaWMgZGF0YS4gSm91cm5hbCBvZiBDb3Vuc2VsaW5nIFBzeWNob2xvZ3ksIDE5KDYpLCA1NTEuDQoNClJvemdvbmp1aywgRC4sIEtyYWF2LCBULiwgTWlra29yLCBLLiwgT3Jhdi1QdXVyYW5kLCBLLiwgJiBUw6RodCwgSy4gKDIwMjApLiBNYXRoZW1hdGljcyBhbnhpZXR5IGFtb25nIFNURU0gYW5kIHNvY2lhbCBzY2llbmNlIHN0dWRlbnRzOiBUaGUgcm9sZXMgb2YgbWF0aGVtYXRpY3Mgc2VsZi1lZmZpY2FjeSwgYW5kIGRlZXAgYW5kIHN1cmZhY2UgYXBwcm9hY2ggdG8gbGVhcm5pbmcuIEludGVybmF0aW9uYWwgSm91cm5hbCBvZiBTVEVNIEVkdWNhdGlvbiwgNygxKSwgMeKAkzExLg0KDQpTZWdvb2wsIE4uIEsuLCBDYXJsc29uLCBKLiBTLiwgR29mb3J0aCwgQS4gTi4sIFZvbiBEZXIgRW1ic2UsIE4uLCAmIEJhcnRlcmlhbiwgSi4gQS4gKDIwMTMpLiBIZWlnaHRlbmVkIHRlc3QgYW54aWV0eSBhbW9uZyB5b3VuZyBjaGlsZHJlbjogRWxlbWVudGFyeSBzY2hvb2wgc3R1ZGVudHPigJkgYW54aW91cyByZXNwb25zZXMgdG8gaGlnaC1zdGFrZXMgdGVzdGluZy4gUHN5Y2hvbG9neSBpbiB0aGUgU2Nob29scywgNTAoNSksIDQ4OeKAkzQ5OS4NCg0KU3Bvb3JlbiwgUC4sIEJyb2NreCwgQi4sICYgTW9ydGVsbWFucywgRC4gKDIwMTMpLiBPbiB0aGUgdmFsaWRpdHkgb2Ygc3R1ZGVudCBldmFsdWF0aW9uIG9mIHRlYWNoaW5nOiBUaGUgc3RhdGUgb2YgdGhlIGFydC4gUmV2aWV3IG9mIEVkdWNhdGlvbmFsIFJlc2VhcmNoLCA4Myg0KSwgNTk4LTY0Mi4NCg0KVXNoZXIsIEUuIEwuLCBMaSwgQy4gUi4sIEJ1dHosIEEuIFIuLCAmIFJvamFzLCBKLiBQLiAoMjAxOSkuIFBlcnNldmVyYW50IGdyaXQgYW5kIHNlbGYtZWZmaWNhY3k6IEFyZSBib3RoIGVzc2VudGlhbCBmb3IgY2hpbGRyZW7igJlzIGFjYWRlbWljIHN1Y2Nlc3M/LiBKb3VybmFsIG9mIEVkdWNhdGlvbmFsIFBzeWNob2xvZ3ksIDExMSg1KSwgODc3Lg0KDQogV2F0c29uLCBELiwgQ2xhcmssIEwuIEEuLCAmIFRlbGxlZ2VuLCBBLiAoMTk4OCkuIERldmVsb3BtZW50IGFuZCB2YWxpZGF0aW9uIG9mIGJyaWVmIG1lYXN1cmVzIG9mIHBvc2l0aXZlIGFuZCBuZWdhdGl2ZSBhZmZlY3Q6IFRoZSBQQU5BUyBzY2FsZXMuIEpvdXJuYWwgb2YgUGVyc29uYWxpdHkgYW5kIFNvY2lhbCBQc3ljaG9sb2d5LCA1NCg2KSwgMTA2M+KAkzEwNzAuDQoNCldpbHNvbiwgUy4gKDIwMTMpLiBNYXR1cmUgYWdlIHByZS1zZXJ2aWNlIHRlYWNoZXJz4oCZIG1hdGhlbWF0aWNzIGFueGlldHkgYW5kIGZhY3RvcnMgaW1wYWN0aW5nIG9uIHVuaXZlcnNpdHkgcmV0ZW50aW9uLiBNYXRoZW1hdGljcyBFZHVjYXRpb246IFllc3RlcmRheSwgVG9kYXkgYW5kIFRvbW9ycm93IChNRVJHQTM2KSwgNjY24oCTNjczLg0KDQpaYWthcmlhLCBFLiwgWmFpbiwgTi4gTS4sIEFobWFkLCBOLiBBLiwgJiBFcmxpbmEsIEEuICgyMDEyKS4gTWF0aGVtYXRpY3MgYW54aWV0eSBhbmQgYWNoaWV2ZW1lbnQgYW1vbmcgc2Vjb25kYXJ5IHNjaG9vbCBzdHVkZW50cy4gQW1lcmljYW4gSm91cm5hbCBvZiBBcHBsaWVkIFNjaWVuY2VzLCA5KDExKSwgMTgyOC4NCg0KDQpcDQoNCiMgQXBwZW5kaWNlcw0KDQojIyBNYXRoZW1hdGljcyBvZiBQQ0ENCg0KKioxLiBQcm9ibGVtIERlZmluaXRpb24qKg0KDQpXZSB3aWxsIHVzZSBhIHF1ZXN0aW9ubmFpcmUgd2l0aCBmb3VyIGl0ZW1zIHRoYXQgYXNzZXNzIG1hdGggZXZhbHVhdGlvbiBhbnhpZXR5IHRvIGRlbW9uc3RyYXRlIHRoZSBwcm9jZWR1cmUuDQoNCiAgLSAgICR4XzEkOiBUaGlua2luZyBhYm91dCBhIG1hdGggdGVzdCB0aGUgZGF5IGJlZm9yZSB5b3UgdGFrZSBpdC4NCiAgLSAgICR4XzIkOiBUYWtpbmcgYSBtYXRoIHRlc3QuDQogIC0gICAkeF8zJDogQmVpbmcgZ2l2ZW4gYSBob21ld29yayBhc3NpZ25tZW50IG9mIG1hbnkgZGlmZmljdWx0IHByb2JsZW1zIHRoYXQgaXMgZHVlIGZvciB0aGUgbmV4dCBjbGFzcyBtZWV0aW5nLg0KICAtICAgJHhfNCQ6IEJlaW5nIGdpdmVuIGEgcXVpeiBvbiBtYXRoIHdpdGhvdXQga25vd2luZyBpbiBhZHZhbmNlLg0KDQpMZXQgJFxtYXRoYmZ7eH0gPSBbeF8xLCB4XzIsIHhfMywgeF80XV5UJCBiZSBhIHJhbmRvbSB2ZWN0b3IgcmVwcmVzZW50aW5nIHRoZSByZXNwb25zZXMgb2YgYSByYW5kb21seSBzZWxlY3RlZCBpbmRpdmlkdWFsIHRvIHRoZSBmb3VyIGl0ZW1zLiBXZSBhc3N1bWUgJFxtYXRoYmZ7eH0kIGhhcyBhIHBvcHVsYXRpb24gbWVhbiB2ZWN0b3IgJFxib2xkc3ltYm9se1xtdX0kIGFuZCBwb3B1bGF0aW9uIGNvdmFyaWFuY2UgbWF0cml4ICRcYm9sZHN5bWJvbHtcU2lnbWF9JC4NCg0KV2UgY29sbGVjdCBhIHNhbXBsZSBvZiAkbiQgaW5kaXZpZHVhbHMuIFRoZSBkYXRhIG1hdHJpeCBpcyAkXG1hdGhiZntYfV97biBcdGltZXMgNH0kLCB3aGVyZSBlYWNoIHJvdyBpcyBhbiBpbmRpdmlkdWFsJ3MgcmVzcG9uc2UgdmVjdG9yLiBUaGUgc2FtcGxlIG1lYW4gdmVjdG9yIGlzICRcYmFye1xtYXRoYmZ7eH19JCwgYW5kIHRoZSBzYW1wbGUgY292YXJpYW5jZSBtYXRyaXggaXMgJFxtYXRoYmZ7U30kLg0KDQoqKjIuIFByZXByb2Nlc3Npbmc6IENlbnRlcmluZyB0aGUgRGF0YSoqDQoNClRoZSBmaXJzdCBzdGVwIGlzIHRvIGNlbnRlciB0aGUgZGF0YS4gV2Ugc3VidHJhY3QgdGhlIG1lYW4gb2YgZWFjaCB2YXJpYWJsZSwgY3JlYXRpbmcgYSBuZXcgZGF0YSBtYXRyaXggJFxtYXRoYmZ7WX0kOg0KDQokJA0KXG1hdGhiZntZfSA9IFxtYXRoYmZ7WH0gLSBcbWF0aGJmezF9XGJhcntcbWF0aGJme3h9fV5UDQokJA0KDQp3aGVyZSAkXG1hdGhiZnsxfSQgaXMgYW4gJG4gXHRpbWVzIDEkIHZlY3RvciBvZiBvbmVzLiBUaGUgZWxlbWVudHMgb2YgJFxtYXRoYmZ7WX0kIGFyZSAkeV97aWp9ID0geF97aWp9IC0gXGJhcnt4fV9qJC4gRnJvbSB0aGlzIHBvaW50IGZvcndhcmQsIHdlIHdvcmsgd2l0aCB0aGUgY2VudGVyZWQgZGF0YSAkXG1hdGhiZntZfSQsIGVuc3VyaW5nICRFW1xtYXRoYmZ7eX1dID0gXG1hdGhiZnswfSQuDQoNCioqMy4gR29hbCBvZiBQcmluY2lwYWwgQ29tcG9uZW50IEFuYWx5c2lzIChQQ0EpKioNCg0KVGhlIGdvYWwgb2YgUENBIGlzIHRvIGZpbmQgYSBuZXcgc2V0IG9mIHVuY29ycmVsYXRlZCB2YXJpYWJsZXMgJFxtYXRoYmZ7en0gPSBbel8xLCB6XzIsIHpfMywgel80XV5UJCwgY2FsbGVkIHRoZSBcdGV4dGJme1ByaW5jaXBhbCBDb21wb25lbnRzfSAoUENzKSwgd2hpY2ggYXJlIGxpbmVhciBjb21iaW5hdGlvbnMgb2YgdGhlIG9yaWdpbmFsIGNlbnRlcmVkIHZhcmlhYmxlcyAkXG1hdGhiZnt5fSQuDQoNCiQkDQpcbWF0aGJme3p9ID0gXG1hdGhiZntXfV5UXG1hdGhiZnt5fQ0KJCQNCg0KVGhlIG1hdHJpeCAkXG1hdGhiZntXfSQgaXMgYW4gb3J0aG9nb25hbCBtYXRyaXggKCRcbWF0aGJme1d9XlRcbWF0aGJme1d9ID0gXG1hdGhiZntJfSQpIHdob3NlIGNvbHVtbnMgJFxtYXRoYmZ7d31faSQgYXJlIHRoZSBcdGV4dGJme2xvYWRpbmcgdmVjdG9yc30uIFRoZSBjb21wb25lbnRzIG11c3Qgc2F0aXNmeToNCg0KLSAgIFRoZSBmaXJzdCBjb21wb25lbnQsICR6XzEgPSBcbWF0aGJme3d9XzFeVCBcbWF0aGJme3l9JCwgaGFzIHRoZSBtYXhpbXVtIHBvc3NpYmxlIHZhcmlhbmNlLg0KLSAgIFRoZSAkayQtdGggY29tcG9uZW50LCAkel9rID0gXG1hdGhiZnt3fV9rXlQgXG1hdGhiZnt5fSQsIGhhcyB0aGUgbWF4aW11bSBwb3NzaWJsZSB2YXJpYW5jZSBzdWJqZWN0IHRvIGJlaW5nIHVuY29ycmVsYXRlZCB3aXRoIChvcnRob2dvbmFsIHRvKSBhbGwgcHJldmlvdXMgY29tcG9uZW50cyAkel8xLCBcZG90cywgel97ay0xfSQuDQoNCioqNC4gRGVyaXZhdGlvbiBvZiB0aGUgRmlyc3QgUHJpbmNpcGFsIENvbXBvbmVudCoqDQoNCkxldCAkXG1hdGhiZnt3fV8xJCBiZSB0aGUgdmVjdG9yIG9mIHdlaWdodHMgZm9yIHRoZSBmaXJzdCBQQywgJHpfMSA9IFxtYXRoYmZ7d31fMV5UIFxtYXRoYmZ7eX0kLiBUaGUgc2FtcGxlIHZhcmlhbmNlIG9mICR6XzEkIGlzIGdpdmVuIGJ5Og0KDQokJA0KXGJlZ2lue2FsaWduKn0NClx0ZXh0e1Zhcn0oel8xKSAmPSBcdGV4dHtWYXJ9KFxtYXRoYmZ7d31fMV5UIFxtYXRoYmZ7eX0pIFxcDQogICAgICAgICAgICAgICAgJj0gRVsoXG1hdGhiZnt3fV8xXlQgXG1hdGhiZnt5fSkoXG1hdGhiZnt3fV8xXlQgXG1hdGhiZnt5fSleVF0gXHF1YWQgXHRleHR7KHNpbmNlfSBFW1xtYXRoYmZ7eX1dPVxtYXRoYmZ7MH0pIFxcDQogICAgICAgICAgICAgICAgJj0gRVtcbWF0aGJme3d9XzFeVCBcbWF0aGJme3l9IFxtYXRoYmZ7eX1eVCBcbWF0aGJme3d9XzFdIFxcDQogICAgICAgICAgICAgICAgJj0gXG1hdGhiZnt3fV8xXlQgRVtcbWF0aGJme3l9IFxtYXRoYmZ7eX1eVF0gXG1hdGhiZnt3fV8xIFxcDQogICAgICAgICAgICAgICAgJj0gXG1hdGhiZnt3fV8xXlQgXGJvbGRzeW1ib2x7XFNpZ21hfSBcbWF0aGJme3d9XzENClxlbmR7YWxpZ24qfQ0KJCQNCg0KSW4gcHJhY3RpY2UsIHdlIHVzZSB0aGUgc2FtcGxlIGNvdmFyaWFuY2UgbWF0cml4ICRcbWF0aGJme1N9ID0gXGZyYWN7MX17bi0xfSBcbWF0aGJme1l9XlQgXG1hdGhiZntZfSQuDQoNCldlIHdpc2ggdG8gbWF4aW1pemUgJFxtYXRoYmZ7d31fMV5UIFxtYXRoYmZ7U30gXG1hdGhiZnt3fV8xJCBzdWJqZWN0IHRvIHRoZSBub3JtYWxpemF0aW9uIGNvbnN0cmFpbnQgJFxtYXRoYmZ7d31fMV5UIFxtYXRoYmZ7d31fMSA9IDEkICh0byBwcmV2ZW50IHRoZSB2YXJpYW5jZSBmcm9tIGdyb3dpbmcgYXJiaXRyYXJpbHkgbGFyZ2UpLiBXZSBzb2x2ZSB0aGlzIHVzaW5nIHRoZSBtZXRob2Qgb2YgTGFncmFuZ2UgbXVsdGlwbGllcnMuDQoNClRoZSBMYWdyYW5naWFuIGlzOg0KDQokJA0KXG1hdGhjYWx7TH0oXG1hdGhiZnt3fV8xLCBcbGFtYmRhXzEpID0gXG1hdGhiZnt3fV8xXlQgXG1hdGhiZntTfSBcbWF0aGJme3d9XzEgLSBcbGFtYmRhXzEgKFxtYXRoYmZ7d31fMV5UIFxtYXRoYmZ7d31fMSAtIDEpDQokJA0KDQpUYWtpbmcgdGhlIGdyYWRpZW50IHdpdGggcmVzcGVjdCB0byAkXG1hdGhiZnt3fV8xJCBhbmQgc2V0dGluZyBpdCB0byB6ZXJvOg0KDQokJA0KXGZyYWN7XHBhcnRpYWwgXG1hdGhjYWx7TH19e1xwYXJ0aWFsIFxtYXRoYmZ7d31fMX0gPSAyXG1hdGhiZntTfVxtYXRoYmZ7d31fMSAtIDJcbGFtYmRhXzEgXG1hdGhiZnt3fV8xID0gMA0KJCQNCg0KVGhpcyB5aWVsZHMgdGhlIGtleSBcdGV4dGJme2VpZ2VudmFsdWUgZXF1YXRpb259Og0KDQokJA0KXGJlZ2lue2VxdWF0aW9ufQ0KXG1hdGhiZntTfSBcbWF0aGJme3d9XzEgPSBcbGFtYmRhXzEgXG1hdGhiZnt3fV8xDQpcZW5ke2VxdWF0aW9ufQ0KJCQNCg0KU3Vic3RpdHV0aW5nIHRoZSBhYm92ZSBlcXVhdGlvbiBiYWNrIGludG8gdGhlIHZhcmlhbmNlIGV4cHJlc3Npb246DQoNCiQkDQpcdGV4dHtWYXJ9KHpfMSkgPSBcbWF0aGJme3d9XzFeVCBcbWF0aGJme1N9IFxtYXRoYmZ7d31fMSA9IFxtYXRoYmZ7d31fMV5UIChcbGFtYmRhXzEgXG1hdGhiZnt3fV8xKSA9IFxsYW1iZGFfMSBcbWF0aGJme3d9XzFeVCBcbWF0aGJme3d9XzEgPSBcbGFtYmRhXzENCiQkDQoNClRodXMsIHRoZSB2YXJpYW5jZSBvZiB0aGUgZmlyc3QgcHJpbmNpcGFsIGNvbXBvbmVudCAkel8xJCBpcyB0aGUgZWlnZW52YWx1ZSAkXGxhbWJkYV8xJC4gVG8gbWF4aW1pemUgdGhlIHZhcmlhbmNlLCB3ZSBtdXN0IGNob29zZSB0aGUgXHRleHRiZntlaWdlbnZlY3RvciAkXG1hdGhiZnt3fV8xJCBjb3JyZXNwb25kaW5nIHRvIHRoZSBsYXJnZXN0IGVpZ2VudmFsdWUgb2YgJFxtYXRoYmZ7U30kfS4NCg0KKio1LiBEZXJpdmF0aW9uIG9mIHRoZSBTZWNvbmQgUHJpbmNpcGFsIENvbXBvbmVudCoqDQoNCldlIG5vdyBzZWVrIHRoZSBzZWNvbmQgY29tcG9uZW50ICR6XzIgPSBcbWF0aGJme3d9XzJeVCBcbWF0aGJme3l9JCB0aGF0IGhhcyBtYXhpbXVtIHZhcmlhbmNlLCBzdWJqZWN0IHRvICRcbWF0aGJme3d9XzJeVCBcbWF0aGJme3d9XzIgPSAxJCBhbmQgJFxtYXRoYmZ7d31fMl5UIFxtYXRoYmZ7d31fMSA9IDAkIChlbnN1cmluZyAkel8yJCBpcyB1bmNvcnJlbGF0ZWQgd2l0aCAkel8xJCkuDQoNClRoZSBMYWdyYW5naWFuIGZvciB0aGlzIHByb2JsZW0gaXM6DQoNCiQkDQpcbWF0aGNhbHtMfShcbWF0aGJme3d9XzIsIFxsYW1iZGFfMiwgXHBoaSkgPSBcbWF0aGJme3d9XzJeVCBcbWF0aGJme1N9IFxtYXRoYmZ7d31fMiAtIFxsYW1iZGFfMiAoXG1hdGhiZnt3fV8yXlQgXG1hdGhiZnt3fV8yIC0gMSkgLSBccGhpIChcbWF0aGJme3d9XzJeVCBcbWF0aGJme3d9XzEpDQokJA0KDQpUYWtpbmcgdGhlIGdyYWRpZW50IHdpdGggcmVzcGVjdCB0byAkXG1hdGhiZnt3fV8yJCBhbmQgc2V0dGluZyBpdCB0byB6ZXJvOg0KDQokJA0KXGZyYWN7XHBhcnRpYWwgXG1hdGhjYWx7TH19e1xwYXJ0aWFsIFxtYXRoYmZ7d31fMn0gPSAyXG1hdGhiZntTfVxtYXRoYmZ7d31fMiAtIDJcbGFtYmRhXzIgXG1hdGhiZnt3fV8yIC0gXHBoaSBcbWF0aGJme3d9XzEgPSAwDQokJA0KDQpNdWx0aXBseSB0aGlzIGVxdWF0aW9uIG9uIHRoZSBsZWZ0IGJ5ICRcbWF0aGJme3d9XzFeVCQ6DQoNCiQkDQoyXG1hdGhiZnt3fV8xXlRcbWF0aGJme1N9XG1hdGhiZnt3fV8yIC0gMlxsYW1iZGFfMiBcbWF0aGJme3d9XzFeVFxtYXRoYmZ7d31fMiAtIFxwaGkgXG1hdGhiZnt3fV8xXlRcbWF0aGJme3d9XzEgPSAwDQokJA0KDQpGcm9tIHRoZSBlaWdlbnZhbHVlIGVxdWF0aW9uIGZvciAkXG1hdGhiZnt3fV8xJCwgd2Uga25vdyAkXG1hdGhiZnt3fV8xXlRcbWF0aGJme1N9ID0gXGxhbWJkYV8xIFxtYXRoYmZ7d31fMV5UJC4gVGhlIG9ydGhvZ29uYWxpdHkgY29uc3RyYWludCBnaXZlcyAkXG1hdGhiZnt3fV8xXlRcbWF0aGJme3d9XzI9MCQuIFN1YnN0aXR1dGluZyB0aGVzZToNCg0KJCQNCjJcbGFtYmRhXzEgXG1hdGhiZnt3fV8xXlRcbWF0aGJme3d9XzIgLSAwIC0gXHBoaSAoMSkgPSAwIFxpbXBsaWVzIDJcbGFtYmRhXzEgKDApIC0gXHBoaSA9IDAgXGltcGxpZXMgXHBoaSA9IDANCiQkDQoNCldpdGggJFxwaGk9MCQsIHRoZSBncmFkaWVudCBlcXVhdGlvbiBzaW1wbGlmaWVzIHRvOg0KDQokJA0KMlxtYXRoYmZ7U31cbWF0aGJme3d9XzIgLSAyXGxhbWJkYV8yIFxtYXRoYmZ7d31fMiA9IDAgXGltcGxpZXMgXG1hdGhiZntTfSBcbWF0aGJme3d9XzIgPSBcbGFtYmRhXzIgXG1hdGhiZnt3fV8yDQokJA0KDQpUaGlzIGlzIGFnYWluIGFuIGVpZ2VudmFsdWUgZXF1YXRpb24uIFRoZSB2YXJpYW5jZSBvZiAkel8yJCBpcyAkXGxhbWJkYV8yJC4gVG8gbWF4aW1pemUgdGhlIHZhcmlhbmNlLCB3ZSBjaG9vc2UgdGhlIGVpZ2VudmVjdG9yICRcbWF0aGJme3d9XzIkIGNvcnJlc3BvbmRpbmcgdG8gdGhlIFx0ZXh0YmZ7c2Vjb25kIGxhcmdlc3QgZWlnZW52YWx1ZX0gJFxsYW1iZGFfMiQuIFRoZSBvcnRob2dvbmFsaXR5ICRcbWF0aGJme3d9XzJeVCBcbWF0aGJme3d9XzEgPSAwJCBpcyBhdXRvbWF0aWNhbGx5IHNhdGlzZmllZCBmb3IgZGlzdGluY3QgZWlnZW52YWx1ZXMgc2luY2UgJFxtYXRoYmZ7U30kIGlzIHN5bW1ldHJpYy4NCg0KKio2LiBTdWJzZXF1ZW50IENvbXBvbmVudHMgYW5kIEZ1bGwgU29sdXRpb24qKg0KDQpUaGlzIHByb2Nlc3MgY29udGludWVzIGZvciBhbGwgZm91ciBjb21wb25lbnRzLiBUaGUgc29sdXRpb24gdG8gdGhlIFBDQSBwcm9ibGVtIGlzIGZvdW5kIGJ5IHBlcmZvcm1pbmcgdGhlICoqZWlnZW5kZWNvbXBvc2l0aW9uKiogb2YgdGhlIHNhbXBsZSBjb3ZhcmlhbmNlIG1hdHJpeCAkXG1hdGhiZntTfSQ6DQoNCiQkDQpcbWF0aGJme1N9ID0gXG1hdGhiZntXfSBcYm9sZHN5bWJvbHtcTGFtYmRhfSBcbWF0aGJme1d9XlQNCiQkDQoNCndoZXJlOg0KDQotICAgJFxib2xkc3ltYm9se1xMYW1iZGF9JCBpcyBhIGRpYWdvbmFsIG1hdHJpeCBjb250YWluaW5nIHRoZSBlaWdlbnZhbHVlcyBpbiBkZXNjZW5kaW5nIG9yZGVyOiAkXGxhbWJkYV8xIFxnZSBcbGFtYmRhXzIgXGdlIFxsYW1iZGFfMyBcZ2UgXGxhbWJkYV80IFxnZSAwJC4NCi0gICAkXG1hdGhiZntXfSA9IFtcbWF0aGJme3d9XzEsIFxtYXRoYmZ7d31fMiwgXG1hdGhiZnt3fV8zLCBcbWF0aGJme3d9XzRdJCBpcyBhbiBvcnRob2dvbmFsIG1hdHJpeCB3aG9zZSBjb2x1bW5zIGFyZSB0aGUgY29ycmVzcG9uZGluZyBlaWdlbnZlY3RvcnMuDQoNClRoZSBwcmluY2lwYWwgY29tcG9uZW50cyBmb3IgYW4gaW5kaXZpZHVhbCB3aXRoIGNlbnRlcmVkIHJlc3BvbnNlIHZlY3RvciAkXG1hdGhiZnt5fSQgYXJlIHRoZW4gY29tcHV0ZWQgYXM6DQoNCiQkDQpcbWF0aGJme3p9ID0gXG1hdGhiZntXfV5UIFxtYXRoYmZ7eX0NCiQkDQoNClRoZSAkayQtdGggUEMgc2NvcmUgaXMgJHpfayA9IFxtYXRoYmZ7d31fa15UIFxtYXRoYmZ7eX0kLg0KDQoqKjcuIFZhcmlhbmNlIEV4cGxhaW5lZCoqDQoNClRoZSB0b3RhbCB2YXJpYW5jZSBpbiB0aGUgb3JpZ2luYWwgZGF0YSBpcyB0aGUgc3VtIG9mIHRoZSB2YXJpYW5jZXMgb2YgdGhlIGNlbnRlcmVkIHZhcmlhYmxlcywgd2hpY2ggaXMgdGhlIHRyYWNlIG9mICRcbWF0aGJme1N9JC4NCg0KJCQNClx0ZXh0e1RvdGFsIFZhcmlhbmNlfSA9IFx0ZXh0e3RyfShcbWF0aGJme1N9KSA9IHNfezExfV4yICsgc197MjJ9XjIgKyBzX3szM31eMiArIHNfezQ0fV4yDQokJA0KDQpGb3IgYSBzeW1tZXRyaWMgbWF0cml4LCB0aGlzIGlzIGFsc28gZXF1YWwgdG8gdGhlIHN1bSBvZiBpdHMgZWlnZW52YWx1ZXM6DQoNCiQkDQpcdGV4dHtUb3RhbCBWYXJpYW5jZX0gPSBcbGFtYmRhXzEgKyBcbGFtYmRhXzIgKyBcbGFtYmRhXzMgKyBcbGFtYmRhXzQNCiQkIFRoZSBwcm9wb3J0aW9uIG9mIHRvdGFsIHZhcmlhbmNlIGV4cGxhaW5lZCBieSB0aGUgJGskLXRoIHByaW5jaXBhbCBjb21wb25lbnQgaXM6DQoNCiQkDQpcdGV4dHtQcm9wb3J0aW9ufV9rID0gXGZyYWN7XGxhbWJkYV9rfXtcc3VtX3tpPTF9Xns0fSBcbGFtYmRhX2l9DQokJA0KDQpUaGUgY3VtdWxhdGl2ZSB2YXJpYW5jZSBleHBsYWluZWQgYnkgdGhlIGZpcnN0ICRtJCBjb21wb25lbnRzIGlzOg0KDQokJA0KXHRleHR7Q3VtdWxhdGl2ZX1fbSA9IFxmcmFje1xzdW1fe2k9MX1ee219IFxsYW1iZGFfaX17XHN1bV97aT0xfV57NH0gXGxhbWJkYV9pfQ0KJCQNCg0KKio4LiBJbnRlcnByZXRhdGlvbiBpbiBvdXIgQ29udGV4dCoqDQoNCkluIHRoZSBjb250ZXh0IG9mIG91ciBtYXRoIGV2YWx1YXRpb24gYW54aWV0eSBxdWVzdGlvbm5haXJlOg0KDQotICAgVGhlIGxvYWRpbmcgdmVjdG9yICRcbWF0aGJme3d9XzEgPSBbd197MTF9LCB3X3sxMn0sIHdfezEzfSwgd197MTR9XV5UJCByZXZlYWxzIGhvdyB0aGUgb3JpZ2luYWwgaXRlbXMgY29tYmluZSB0byBmb3JtIHRoZSBwcmltYXJ5IGxhdGVudCBkaW1lbnNpb24gb2YgYW54aWV0eS4gRm9yIGV4YW1wbGUsIGlmIGFsbCBsb2FkaW5ncyBhcmUgcG9zaXRpdmUgYW5kIHNpbWlsYXIsICR6XzEkIG1pZ2h0IHJlcHJlc2VudCAqKmdlbmVyYWwgTWF0aCBFdmFsdWF0aW9uIEFueGlldHkqKi4NCg0KLSAgIFRoZSBzZWNvbmQgY29tcG9uZW50ICRcbWF0aGJme3d9XzIkIG1pZ2h0IGNvbnRyYXN0IGRpZmZlcmVudCB0eXBlcyBvZiBhbnhpZXR5LiBGb3IgaW5zdGFuY2UsIGlmICR3X3syMX0kIGFuZCAkd197MjJ9JCAodGVzdC1yZWxhdGVkKSBhcmUgcG9zaXRpdmUgd2hpbGUgJHdfezIzfSQgYW5kICR3X3syNH0kIChwb3AgcXVpei9ob21ld29yaykgYXJlIG5lZ2F0aXZlLCAkel8yJCBtaWdodCByZXByZXNlbnQgKipUZXN0IEFueGlldHkgdnMuIFNwb250YW5lb3VzIEV2YWx1YXRpb24gQW54aWV0eSoqLg0KDQotICAgQnkgZXhhbWluaW5nIHRoZSBsb2FkaW5ncywgd2UgY2FuIGludGVycHJldCB0aGUgdW5kZXJseWluZyBwc3ljaG9sb2dpY2FsIGNvbnN0cnVjdHMgdGhhdCBkcml2ZSB0aGUgY29ycmVsYXRpb25zIGJldHdlZW4gdGhlIGZvdXIgcXVlc3Rpb25uYWlyZSBpdGVtcy4NCg0KXA0KDQojIyBDb25maXJtYXRpdmUgRmFjdG9yIEFuYWx5c2lzIChDRkEpDQoNClRoaXMgYXBwZW5kaXggcHJvdmlkZXMgYSBkZXRhaWxlZCBtYXRoZW1hdGljYWwgZGVyaXZhdGlvbiBvZiBhIENvbmZpcm1hdG9yeSBGYWN0b3IgQW5hbHlzaXMgKENGQSkgbW9kZWwuIFRoZSBvYnNlcnZlZCB2YXJpYWJsZXMgYXJlIG5pbmUgaXRlbXMgcmVsYXRlZCB0byBtYXRoZW1hdGljYWwgYW54aWV0eSwgd2hpY2ggYXJlIGh5cG90aGVzaXplZCB0byBsb2FkIG9udG8gdHdvIGxhdGVudCBmYWN0b3JzOiAqKlRlc3QgQW54aWV0eSAoVEEpKiogYW5kICoqTGVhcm5pbmcgQW54aWV0eSAoTEEpKiouDQoNCioqMS4gTGF0ZW50IEZhY3RvcnMgYW5kIE9ic2VydmVkIFZhcmlhYmxlcyoqDQoNCldlIGRlZmluZSB0d28gbGF0ZW50IGZhY3RvcnM6DQoNCi0gICAkXGV0YV8xJDogVGVzdCBBbnhpZXR5IChUQSkNCi0gICAkXGV0YV8yJDogTGVhcm5pbmcgQW54aWV0eSAoTEEpDQoNCldlIGhhdmUgbmluZSBvYnNlcnZlZCB2YXJpYWJsZXMgKGl0ZW1zL3F1ZXN0aW9ucyksICR5XzEkIHRvICR5XzkkOg0KDQotICAgJHlfMSQ6IEhhdmluZyB0byB1c2UgdGFibGVzIGluIHRoZSBiYWNrIG9mIGEgbWF0aCBib29rLg0KLSAgICR5XzIkOiBUaGlua2luZyBhYm91dCBhIG1hdGggdGVzdCB0aGUgZGF5IGJlZm9yZSB5b3UgdGFrZSBpdC4NCi0gICAkeV8zJDogV2F0Y2hpbmcgdGhlIHRlYWNoZXIgd29yayBvdXQgYSBtYXRoIHByb2JsZW0gb24gdGhlIGJvYXJkLg0KLSAgICR5XzQkOiBUYWtpbmcgYSBtYXRoIHRlc3QuDQotICAgJHlfNSQ6IEJlaW5nIGdpdmVuIGEgaG9tZXdvcmsgYXNzaWdubWVudCBvZiBtYW55IGRpZmZpY3VsdCBwcm9ibGVtcyB0aGF0IGlzIGR1ZSBmb3IgdGhlIG5leHQgY2xhc3MgbWVldGluZy4NCi0gICAkeV82JDogTGlzdGVuaW5nIHRvIGEgbGVjdHVyZSBpbiBtYXRoIGNsYXNzLg0KLSAgICR5XzckOiBMaXN0ZW5pbmcgdG8gYW5vdGhlciBzdHVkZW50IGV4cGxhaW4gaG93IHRvIGRvIGEgbWF0aCBwcm9ibGVtLg0KLSAgICR5XzgkOiBCZWluZyBnaXZlbiBhIHF1aXogb24gbWF0aCB3aXRob3V0IGtub3dpbmcgaW4gYWR2YW5jZS4NCi0gICAkeV85JDogU3RhcnRpbmcgYSBuZXcgY2hhcHRlciBpbiBhIG1hdGggYm9vay4NCg0KKioyLiBGYWN0b3IgTG9hZGluZ3MgYW5kIE1vZGVsIFN0cnVjdHVyZSoqDQoNCldlIGh5cG90aGVzaXplIHRoZSBmb2xsb3dpbmcgZmFjdG9yIHN0cnVjdHVyZToNCg0KLSAgIEZhY3RvciAkXGV0YV8xJCAoVGVzdCBBbnhpZXR5KSBsb2FkcyBvbiBpdGVtcyAkeV8yJCwgJHlfNCQsICR5XzUkLCBhbmQgJHlfOCQuDQotICAgRmFjdG9yICRcZXRhXzIkIChMZWFybmluZyBBbnhpZXR5KSBsb2FkcyBvbiBpdGVtcyAkeV8xJCwgJHlfMyQsICR5XzYkLCAkeV83JCwgYW5kICR5XzkkLg0KDQpUaGUgZnVuZGFtZW50YWwgZXF1YXRpb24gZm9yIGEgQ0ZBIG1vZGVsIGZvciBhIHNpbmdsZSBvYnNlcnZlZCB2YXJpYWJsZSAkeV9pJCBpczoNCg0KJCQNCnlfaSA9IFxudV9pICsgXGxhbWJkYV97aTF9IFxldGFfMSArIFxsYW1iZGFfe2kyfSBcZXRhXzIgKyBcZXBzaWxvbl9pDQokJA0KDQp3aGVyZToNCg0KLSAgICRcbnVfaSQgaXMgdGhlIGludGVyY2VwdCBmb3Igb2JzZXJ2ZWQgdmFyaWFibGUgJHlfaSQuDQotICAgJFxsYW1iZGFfe2kxfSQgaXMgdGhlIGZhY3RvciBsb2FkaW5nIG9mICR5X2kkIG9uIGxhdGVudCBmYWN0b3IgJFxldGFfMSQuDQotICAgJFxsYW1iZGFfe2kyfSQgaXMgdGhlIGZhY3RvciBsb2FkaW5nIG9mICR5X2kkIG9uIGxhdGVudCBmYWN0b3IgJFxldGFfMiQuDQotICAgJFxlcHNpbG9uX2kkIGlzIHRoZSB1bmlxdWUgZmFjdG9yIChtZWFzdXJlbWVudCBlcnJvcikgZm9yICR5X2kkLg0KDQoqKjMuIFRoZSBNZWFzdXJlbWVudCBNb2RlbCBpbiBNYXRyaXggRm9ybSoqDQoNClRoZSBtb2RlbCBmb3IgYWxsIG5pbmUgb2JzZXJ2ZWQgdmFyaWFibGVzIGNhbiBiZSB3cml0dGVuIGNvbXBhY3RseSBpbiBtYXRyaXggZm9ybS4gV2UgZGVmaW5lIHRoZSBmb2xsb3dpbmcgdmVjdG9ycyBhbmQgbWF0cmljZXM6DQoNCi0gICAkXG1hdGhiZnt5fSA9ICh5XzEsIHlfMiwgXGRvdHMsIHlfOSleVCQgaXMgYSAkOSBcdGltZXMgMSQgdmVjdG9yIG9mIG9ic2VydmVkIHZhcmlhYmxlcy4NCi0gICAkXGJvbGRzeW1ib2x7XG51fSA9IChcbnVfMSwgXG51XzIsIFxkb3RzLCBcbnVfOSleVCQgaXMgYSAkOSBcdGltZXMgMSQgdmVjdG9yIG9mIGludGVyY2VwdHMuDQotICAgJFxib2xkc3ltYm9se1xldGF9ID0gKFxldGFfMSwgXGV0YV8yKV5UJCBpcyBhICQyIFx0aW1lcyAxJCB2ZWN0b3Igb2YgbGF0ZW50IGZhY3RvcnMuDQotICAgJFxib2xkc3ltYm9se1xMYW1iZGF9JCBpcyBhICQ5IFx0aW1lcyAyJCBtYXRyaXggb2YgZmFjdG9yIGxvYWRpbmdzICRcbGFtYmRhX3tpan0kLg0KLSAgICRcYm9sZHN5bWJvbHtcZXBzaWxvbn0gPSAoXGVwc2lsb25fMSwgXGVwc2lsb25fMiwgXGRvdHMsIFxlcHNpbG9uXzkpXlQkIGlzIGEgJDkgXHRpbWVzIDEkIHZlY3RvciBvZiBtZWFzdXJlbWVudCBlcnJvcnMuDQoNClRoZSBmdWxsIG1lYXN1cmVtZW50IG1vZGVsIGlzOg0KDQokJA0KXG1hdGhiZnt5fSA9IFxib2xkc3ltYm9se1xudX0gKyBcYm9sZHN5bWJvbHtcTGFtYmRhfSBcYm9sZHN5bWJvbHtcZXRhfSArIFxib2xkc3ltYm9se1xlcHNpbG9ufQ0KJCQNCg0KR2l2ZW4gb3VyIGh5cG90aGVzaXplZCBmYWN0b3Igc3RydWN0dXJlLCB0aGUgbG9hZGluZyBtYXRyaXggJFxib2xkc3ltYm9se1xMYW1iZGF9JCBoYXMgYSBzcGVjaWZpYyBmb3JtIHdpdGggbWFueSBlbGVtZW50cyBmaXhlZCB0byB6ZXJvLiBUbyBlbnN1cmUgbW9kZWwgaWRlbnRpZmljYXRpb24sIHdlIG5lZWQgdG8gc2V0IHRoZSBzY2FsZSBvZiBlYWNoIGxhdGVudCB2YXJpYWJsZS4gVGhpcyBpcyB0eXBpY2FsbHkgZG9uZSBieSAqKmZhY3RvciBzdGFuZGFyZGl6YXRpb24qKiwgd2hlcmUgdGhlIHZhcmlhbmNlIG9mIHRoZSBsYXRlbnQgZmFjdG9yIGlzIGZpeGVkIHRvIDEsIG9yIGJ5ICoqbWFya2VyIHZhcmlhYmxlKiogbWV0aG9kLCB3aGVyZSBvbmUgbG9hZGluZyBwZXIgZmFjdG9yIGlzIGZpeGVkIHRvIDEuIFdlIHdpbGwgdXNlIHRoZSBsYXR0ZXIuDQoNCkxldCB1cyBkZWZpbmU6DQoNCi0gICAkeV8yJCBhcyB0aGUgbWFya2VyIHZhcmlhYmxlIGZvciAkXGV0YV8xJCAoVGVzdCBBbnhpZXR5KSwgc28gJFxsYW1iZGFfezIxfSA9IDEkLg0KLSAgICR5XzEkIGFzIHRoZSBtYXJrZXIgdmFyaWFibGUgZm9yICRcZXRhXzIkIChMZWFybmluZyBBbnhpZXR5KSwgc28gJFxsYW1iZGFfezEyfSA9IDEkLg0KDQpUaGUgJFxib2xkc3ltYm9se1xMYW1iZGF9JCBtYXRyaXggaXMgdGhlbjoNCg0KJCQNClxib2xkc3ltYm9se1xMYW1iZGF9ID0NClxiZWdpbntibWF0cml4fQ0KMCAmIDEgXFwgICAgICAgICAgICAgICUgeTEgbG9hZHMgb24gZXRhMiAoTEEpDQoxICYgMCBcXCAgICAgICAgICAgICAgJSB5MiBsb2FkcyBvbiBldGExIChUQSkNCjAgJiBcbGFtYmRhX3szMn0gXFwgICAlIHkzIGxvYWRzIG9uIGV0YTIgKExBKQ0KXGxhbWJkYV97NDF9ICYgMCBcXCAgICUgeTQgbG9hZHMgb24gZXRhMSAoVEEpDQpcbGFtYmRhX3s1MX0gJiAwIFxcICAgJSB5NSBsb2FkcyBvbiBldGExIChUQSkNCjAgJiBcbGFtYmRhX3s2Mn0gXFwgICAlIHk2IGxvYWRzIG9uIGV0YTIgKExBKQ0KMCAmIFxsYW1iZGFfezcyfSBcXCAgICUgeTcgbG9hZHMgb24gZXRhMiAoTEEpDQpcbGFtYmRhX3s4MX0gJiAwIFxcICAgJSB5OCBsb2FkcyBvbiBldGExIChUQSkNCjAgJiBcbGFtYmRhX3s5Mn0gXFwgICAlIHk5IGxvYWRzIG9uIGV0YTIgKExBKQ0KXGVuZHtibWF0cml4fQ0KJCQNCg0KKio0LiBNb2RlbCBBc3N1bXB0aW9ucyoqDQoNClRoZSBDRkEgbW9kZWwgcmVsaWVzIG9uIHNldmVyYWwga2V5IGFzc3VtcHRpb25zOg0KDQotICAgVGhlIGxhdGVudCBmYWN0b3JzIGFuZCBlcnJvcnMgYXJlIG11bHRpdmFyaWF0ZSBub3JtYWxseSBkaXN0cmlidXRlZDogJFxib2xkc3ltYm9se1xldGF9IFxzaW0gTihcbWF0aGJmezB9LCBcYm9sZHN5bWJvbHtcUHNpfSkkIGFuZCAkXGJvbGRzeW1ib2x7XGVwc2lsb259IFxzaW0gTihcbWF0aGJmezB9LCBcYm9sZHN5bWJvbHtcVGhldGF9X1xlcHNpbG9uKSQuDQoNCi0gICBUaGUgZXJyb3JzIGFuZCBmYWN0b3JzIGFyZSBpbmRlcGVuZGVudDogJFxtYXRocm17Q292fShcYm9sZHN5bWJvbHtcZXRhfSwgXGJvbGRzeW1ib2x7XGVwc2lsb259KSA9IFxtYXRoYmZ7MH0kLg0KDQotICAgVGhlIG9ic2VydmVkIHZhcmlhYmxlcywgYmVpbmcgbGluZWFyIGNvbWJpbmF0aW9ucyBvZiBub3JtYWwgcmFuZG9tIHZhcmlhYmxlcywgYXJlIHRoZXJlZm9yZSBhbHNvIG11bHRpdmFyaWF0ZSBub3JtYWw6ICRcbWF0aGJme3l9IFxzaW0gTihcYm9sZHN5bWJvbHtcbnV9LCBcYm9sZHN5bWJvbHtcU2lnbWF9KSQuDQoNCioqNS4gRGVyaXZhdGlvbiBvZiB0aGUgSW1wbGllZCBDb3ZhcmlhbmNlIE1hdHJpeCoqDQoNClRoZSBjb3JlIG9mIENGQSBpcyB0byBtb2RlbCB0aGUgcG9wdWxhdGlvbiBjb3ZhcmlhbmNlIG1hdHJpeCBvZiB0aGUgb2JzZXJ2ZWQgdmFyaWFibGVzLCAkXGJvbGRzeW1ib2x7XFNpZ21hfSQuIFRoZSBtb2RlbC1pbXBsaWVkIGNvdmFyaWFuY2UgbWF0cml4LCBkZW5vdGVkICRcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pJCwgaXMgYSBmdW5jdGlvbiBvZiB0aGUgbW9kZWwgcGFyYW1ldGVycyAkXGJvbGRzeW1ib2x7XHRoZXRhfSQgKGxvYWRpbmdzLCBmYWN0b3IgdmFyaWFuY2VzL2NvdmFyaWFuY2VzLCBlcnJvciB2YXJpYW5jZXMpLg0KDQpMZXQgJFxib2xkc3ltYm9se1xQc2l9JCBiZSB0aGUgJDIgXHRpbWVzIDIkIGNvdmFyaWFuY2UgbWF0cml4IG9mIHRoZSBsYXRlbnQgZmFjdG9yczoNCg0KJCQNClxib2xkc3ltYm9se1xQc2l9ID0gXG1hdGhybXtDb3Z9KFxib2xkc3ltYm9se1xldGF9KSA9DQpcYmVnaW57Ym1hdHJpeH0NClxwc2lfezExfSAmIFxwc2lfezEyfSBcXA0KXHBzaV97MjF9ICYgXHBzaV97MjJ9DQpcZW5ke2JtYXRyaXh9DQo9DQpcYmVnaW57Ym1hdHJpeH0NClxtYXRocm17VmFyfShcZXRhXzEpICYgXG1hdGhybXtDb3Z9KFxldGFfMSwgXGV0YV8yKSBcXA0KXG1hdGhybXtDb3Z9KFxldGFfMSwgXGV0YV8yKSAmIFxtYXRocm17VmFyfShcZXRhXzIpDQpcZW5ke2JtYXRyaXh9DQokJA0KDQpUaGUgaW1wbGllZCBjb3ZhcmlhbmNlIG1hdHJpeCAkXGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KSQgaXMgZGVyaXZlZCBhcyBmb2xsb3dzOg0KDQokJA0KXGJlZ2lue2FsaWduKn0NClxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkgJj0gXG1hdGhybXtDb3Z9KFxtYXRoYmZ7eX0pIFxcDQomPSBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XG51fSArIFxib2xkc3ltYm9se1xMYW1iZGF9XGJvbGRzeW1ib2x7XGV0YX0gKyBcYm9sZHN5bWJvbHtcZXBzaWxvbn0pIFxcDQomPSBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XExhbWJkYX1cYm9sZHN5bWJvbHtcZXRhfSArIFxib2xkc3ltYm9se1xlcHNpbG9ufSkgXHF1YWQgXHRleHR7KHNpbmNlIH0gXGJvbGRzeW1ib2x7XG51fSBcdGV4dHsgaXMgYSBjb25zdGFudCl9IFxcDQomPSBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XExhbWJkYX1cYm9sZHN5bWJvbHtcZXRhfSkgKyBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XGVwc2lsb259KSArIFxtYXRocm17Q292fShcYm9sZHN5bWJvbHtcTGFtYmRhfVxib2xkc3ltYm9se1xldGF9LCBcYm9sZHN5bWJvbHtcZXBzaWxvbn0pICsgXG1hdGhybXtDb3Z9KFxib2xkc3ltYm9se1xlcHNpbG9ufSwgXGJvbGRzeW1ib2x7XExhbWJkYX1cYm9sZHN5bWJvbHtcZXRhfSkNClxlbmR7YWxpZ24qfQ0KJCQNCg0KVXNpbmcgYXNzdW1wdGlvbiAyICgkXG1hdGhybXtDb3Z9KFxib2xkc3ltYm9se1xldGF9LCBcYm9sZHN5bWJvbHtcZXBzaWxvbn0pID0gXG1hdGhiZnswfSQpLCB0aGUgY3Jvc3MtdGVybXMgdmFuaXNoOg0KDQokJA0KXG1hdGhybXtDb3Z9KFxib2xkc3ltYm9se1xMYW1iZGF9XGJvbGRzeW1ib2x7XGV0YX0sIFxib2xkc3ltYm9se1xlcHNpbG9ufSkgPSBcYm9sZHN5bWJvbHtcTGFtYmRhfSBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XGV0YX0sIFxib2xkc3ltYm9se1xlcHNpbG9ufSkgPSBcbWF0aGJmezB9LCBccXVhZCBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XGVwc2lsb259LCBcYm9sZHN5bWJvbHtcTGFtYmRhfVxib2xkc3ltYm9se1xldGF9KSA9IFxtYXRoYmZ7MH0NCiQkDQoNClRoZXJlZm9yZSwNCg0KJCQNClxiZWdpbnthbGlnbip9DQpcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pICY9IFxtYXRocm17Q292fShcYm9sZHN5bWJvbHtcTGFtYmRhfVxib2xkc3ltYm9se1xldGF9KSArIFxtYXRocm17Q292fShcYm9sZHN5bWJvbHtcZXBzaWxvbn0pIFxcDQomPSBcYm9sZHN5bWJvbHtcTGFtYmRhfSBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XGV0YX0pIFxib2xkc3ltYm9se1xMYW1iZGF9XlQgKyBcYm9sZHN5bWJvbHtcVGhldGF9X3tcZXBzaWxvbn0gXFwNCiY9IFxib2xkc3ltYm9se1xMYW1iZGF9IFxib2xkc3ltYm9se1xQc2l9IFxib2xkc3ltYm9se1xMYW1iZGF9XlQgKyBcYm9sZHN5bWJvbHtcVGhldGF9X3tcZXBzaWxvbn0NClxlbmR7YWxpZ24qfQ0KJCQNCg0KVGhpcyBpcyB0aGUgZnVuZGFtZW50YWwgZXF1YXRpb24gZm9yIHRoZSBpbXBsaWVkIGNvdmFyaWFuY2UgbWF0cml4IGluIENGQToNCg0KJCQNClxib3hlZHtcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pID0gXGJvbGRzeW1ib2x7XExhbWJkYX0gXGJvbGRzeW1ib2x7XFBzaX0gXGJvbGRzeW1ib2x7XExhbWJkYX1eVCArIFxib2xkc3ltYm9se1xUaGV0YX1fe1xlcHNpbG9ufX0NCiQkDQoNCioqNi4gUGFyYW1ldGVyIEVzdGltYXRpb24gYW5kIE1vZGVsIElkZW50aWZpY2F0aW9uKioNCg0KVGhlIGdvYWwgb2YgZXN0aW1hdGlvbiBpcyB0byBmaW5kIHBhcmFtZXRlciB2YWx1ZXMgJFxoYXR7XGJvbGRzeW1ib2x7XHRoZXRhfX0kIHN1Y2ggdGhhdCAkXGJvbGRzeW1ib2x7XFNpZ21hfShcaGF0e1xib2xkc3ltYm9se1x0aGV0YX19KSQgaXMgYXMgY2xvc2UgYXMgcG9zc2libGUgdG8gdGhlIHNhbXBsZSBjb3ZhcmlhbmNlIG1hdHJpeCAkXG1hdGhiZntTfSQgb2J0YWluZWQgZnJvbSB0aGUgZGF0YS4NCg0KRm9yIGlkZW50aWZpY2F0aW9uLCB0aGUgbnVtYmVyIG9mIGZyZWUgcGFyYW1ldGVycyAkdCQgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIG51bWJlciBvZiBub24tcmVkdW5kYW50IGVsZW1lbnRzIGluICRcbWF0aGJme1N9JCwgd2hpY2ggaXMgJFxmcmFje3AocCsxKX17Mn0kIHdoZXJlICRwJCBpcyB0aGUgbnVtYmVyIG9mIG9ic2VydmVkIHZhcmlhYmxlcyAoJHA9OSQpLg0KDQpMZXQncyBjb3VudCBvdXIgZnJlZSBwYXJhbWV0ZXJzICR0JDoNCg0KLSAgICoqRmFjdG9yIExvYWRpbmdzKiogKCRcYm9sZHN5bWJvbHtcTGFtYmRhfSQpfTogV2UgZml4ZWQgJFxsYW1iZGFfezIxfSQgYW5kICRcbGFtYmRhX3sxMn0kIHRvIDEuIFdlIGhhdmUgNyBmcmVlIGxvYWRpbmdzOiAkXGxhbWJkYV97MzJ9JCwgJFxsYW1iZGFfezQxfSQsICRcbGFtYmRhX3s1MX0kLCAkXGxhbWJkYV97NjJ9JCwgJFxsYW1iZGFfezcyfSQsICRcbGFtYmRhX3s4MX0kLCAkXGxhbWJkYV97OTJ9JC4NCg0KLSAgICoqTGF0ZW50IEZhY3RvciBDb3ZhcmlhbmNlcyoqICgkXGJvbGRzeW1ib2x7XFBzaX0kKX06IFdlIGhhdmUgMyBmcmVlIHBhcmFtZXRlcnM6ICRccHNpX3sxMX0kICh2YXJpYW5jZSBvZiBUQSksICRccHNpX3syMn0kICh2YXJpYW5jZSBvZiBMQSksIGFuZCAkXHBzaV97MTJ9JCAoY292YXJpYW5jZSBiZXR3ZWVuIFRBIGFuZCBMQSkuDQoNCi0gICAqKkVycm9yIFZhcmlhbmNlcyoqICgkXGJvbGRzeW1ib2x7XFRoZXRhfV97XGVwc2lsb259JCl9OiBXZSBoYXZlIDkgZnJlZSBwYXJhbWV0ZXJzOiAkXHRoZXRhX3sxMX0sIFx0aGV0YV97MjJ9LCBcZG90cywgXHRoZXRhX3s5OX0kLg0KDQpUb3RhbCBmcmVlIHBhcmFtZXRlcnM6ICR0ID0gNyArIDMgKyA5ID0gMTkkLg0KDQpUaGUgbnVtYmVyIG9mIG5vbi1yZWR1bmRhbnQgZWxlbWVudHMgaW4gJFxtYXRoYmZ7U30kIGlzICRcZnJhY3s5IFx0aW1lcyAoOSsxKX17Mn0gPSA0NSQuDQoNClNpbmNlICQ0NSA+IDE5JCwgdGhlIG1vZGVsIGlzICoqb3Zlci1pZGVudGlmaWVkKiogd2l0aCAkZGYgPSA0NSAtIDE5ID0gMjYkIGRlZ3JlZXMgb2YgZnJlZWRvbS4gVGhpcyBpcyBhIG5lY2Vzc2FyeSBjb25kaXRpb24gZm9yIGlkZW50aWZpY2F0aW9uLCBhbmQgd2l0aCB0aGUgc2NhbGluZyBjb25zdHJhaW50cyB3ZSBwbGFjZWQsIHRoZSBtb2RlbCBpcyBpZGVudGlmaWVkLg0KDQoqKjcuIE1heGltdW0gTGlrZWxpaG9vZCBFc3RpbWF0aW9uIG9mIFBhcmFtZXRlcnMqKg0KDQpUaGlzIGRlcml2YXRpb24gaGFzIG91dGxpbmVkIHRoZSBjb21wbGV0ZSBtYXRoZW1hdGljYWwgc2V0dXAgZm9yIGEgdHdvLWZhY3RvciBDRkEgbW9kZWwgb2YgbWF0aGVtYXRpY2FsIGFueGlldHkuIFRoZSBtb2RlbCBwb3NpdHMgdGhhdCB0aGUgY292YXJpYXRpb24gYW1vbmcgdGhlIG5pbmUgb2JzZXJ2ZWQgaXRlbXMgY2FuIGJlIGV4cGxhaW5lZCBieSB0d28gY29ycmVsYXRlZCBsYXRlbnQgZmFjdG9ycy4gVGhlIG5leHQgc3RlcCB3b3VsZCBiZSB0byB1c2UgYW4gZXN0aW1hdGlvbiBhbGdvcml0aG0gKGUuZy4sIE1heGltdW0gTGlrZWxpaG9vZCkgdG8gZmluZCB0aGUgcGFyYW1ldGVyIHZhbHVlcyB0aGF0IG1pbmltaXplIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gJFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkkIGFuZCB0aGUgc2FtcGxlIGNvdmFyaWFuY2UgbWF0cml4ICRcbWF0aGJme1N9JCwgYW5kIHRoZW4gYXNzZXNzIHRoZSBtb2RlbCdzIGZpdCB0byB0aGUgZGF0YS4NCg0KVGhlIGdvYWwgaXMgdG8gZmluZCB0aGUgcGFyYW1ldGVyIHZhbHVlcyAkXGhhdHtcYm9sZHN5bWJvbHtcdGhldGF9fSQgdGhhdCBtYWtlIHRoZSBtb2RlbC1pbXBsaWVkIGNvdmFyaWFuY2UgbWF0cml4ICRcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pJCBtb3N0IGxpa2VseSB0byBoYXZlIHByb2R1Y2VkIHRoZSBvYnNlcnZlZCBzYW1wbGUgZGF0YS4NCg0KR2l2ZW4gYSBzYW1wbGUgb2YgJE4kIGluZGVwZW5kZW50IGFuZCBpZGVudGljYWxseSBkaXN0cmlidXRlZCAoaS5pLmQuKSBvYnNlcnZhdGlvbnMgJFxtYXRoYmZ7eX1fMSwgXG1hdGhiZnt5fV8yLCBcZG90cywgXG1hdGhiZnt5fV9OJCwgdGhlIGxpa2VsaWhvb2QgZnVuY3Rpb24gJEwoXGJvbGRzeW1ib2x7XHRoZXRhfSkkIGlzIHRoZSBqb2ludCBwcm9iYWJpbGl0eSBkZW5zaXR5IG9mIG9ic2VydmluZyBhbGwgdGhlIGRhdGEsIGdpdmVuIHRoZSBwYXJhbWV0ZXJzLiBVbmRlciB0aGUgaS5pLmQuIGFzc3VtcHRpb24sIHRoaXMgaXMgdGhlIHByb2R1Y3Qgb2YgdGhlIGluZGl2aWR1YWwgcHJvYmFiaWxpdHkgZGVuc2l0eSBmdW5jdGlvbnMgKFBERnMpOg0KDQokJA0KTChcYm9sZHN5bWJvbHtcdGhldGF9KSA9IFxwcm9kX3tpPTF9XntOfSBmKFxtYXRoYmZ7eX1faSB8IFxib2xkc3ltYm9se1x0aGV0YX0pDQokJA0KDQpXaGVyZSAkZihcbWF0aGJme3l9X2kgfCBcYm9sZHN5bWJvbHtcdGhldGF9KSQgaXMgdGhlIG11bHRpdmFyaWF0ZSBub3JtYWwgUERGIGZvciBhIHNpbmdsZSBvYnNlcnZhdGlvbiB2ZWN0b3IgJFxtYXRoYmZ7eX1faSQ6DQoNCiQkDQpmKFxtYXRoYmZ7eX1faSB8IFxib2xkc3ltYm9se1x0aGV0YX0pID0gXGZyYWN7MX17KDJccGkpXntwLzJ9IHxcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pfF57MS8yfX0gXGV4cFxsZWZ0WyAtXGZyYWN7MX17Mn0gKFxtYXRoYmZ7eX1faSAtIFxib2xkc3ltYm9se1xudX0pXlQgXGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KV57LTF9IChcbWF0aGJme3l9X2kgLSBcYm9sZHN5bWJvbHtcbnV9KSBccmlnaHRdDQokJA0KDQpUaHVzLCB0aGUgZnVsbCBsaWtlbGlob29kIGZ1bmN0aW9uIGlzOg0KDQokJA0KTChcYm9sZHN5bWJvbHtcdGhldGF9KSA9IFxwcm9kX3tpPTF9XntOfSBcbGVmdFsgXGZyYWN7MX17KDJccGkpXntwLzJ9IHxcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pfF57MS8yfX0gXGV4cFxsZWZ0KCAtXGZyYWN7MX17Mn0gKFxtYXRoYmZ7eX1faSAtIFxib2xkc3ltYm9se1xudX0pXlQgXGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KV57LTF9IChcbWF0aGJme3l9X2kgLSBcYm9sZHN5bWJvbHtcbnV9KSBccmlnaHQpIFxyaWdodF0NCiQkDQoNCio3LjEgVGhlIExvZy1MaWtlbGlob29kIEZ1bmN0aW9uKg0KDQpJdCBpcyBjb21wdXRhdGlvbmFsbHkgZWFzaWVyIHRvIHdvcmsgd2l0aCB0aGUgbmF0dXJhbCBsb2dhcml0aG0gb2YgdGhlIGxpa2VsaWhvb2QgZnVuY3Rpb24sIHRoZSBsb2ctbGlrZWxpaG9vZCAkXGVsbChcYm9sZHN5bWJvbHtcdGhldGF9KSA9IFxsbiBMKFxib2xkc3ltYm9se1x0aGV0YX0pJC4gQ29udmVydGluZyB0aGUgcHJvZHVjdCBpbnRvIGEgc3VtIHNpbXBsaWZpZXMgdGhlIGV4cHJlc3Npb246DQoNCiQkDQpcYmVnaW57YWxpZ24qfQ0KXGVsbChcYm9sZHN5bWJvbHtcdGhldGF9KSAmPSBcc3VtX3tpPTF9XntOfSBcbG4gZihcbWF0aGJme3l9X2kgfCBcYm9sZHN5bWJvbHtcdGhldGF9KSBcXA0KJj0gXHN1bV97aT0xfV57Tn0gXGxlZnRbIC1cZnJhY3twfXsyfSBcbG4oMlxwaSkgLSBcZnJhY3sxfXsyfSBcbG4gfFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSl8IC0gXGZyYWN7MX17Mn0gKFxtYXRoYmZ7eX1faSAtIFxib2xkc3ltYm9se1xudX0pXlQgXGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KV57LTF9IChcbWF0aGJme3l9X2kgLSBcYm9sZHN5bWJvbHtcbnV9KSBccmlnaHRdDQpcZW5ke2FsaWduKn0NCiQkDQoNCldlIGNhbiBmYWN0b3Igb3V0IHRoZSB0ZXJtcyB0aGF0IGRvIG5vdCBkZXBlbmQgb24gdGhlIHN1bW1hdGlvbiBpbmRleCAkaSQ6DQoNCiQkDQpcZWxsKFxib2xkc3ltYm9se1x0aGV0YX0pID0gLVxmcmFje05wfXsyfSBcbG4oMlxwaSkgLSBcZnJhY3tOfXsyfSBcbG4gfFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSl8IC0gXGZyYWN7MX17Mn0gXHN1bV97aT0xfV57Tn0gXGxlZnRbIChcbWF0aGJme3l9X2kgLSBcYm9sZHN5bWJvbHtcbnV9KV5UIFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSleey0xfSAoXG1hdGhiZnt5fV9pIC0gXGJvbGRzeW1ib2x7XG51fSkgXHJpZ2h0XQ0KJCQNCg0KKjcuMi4gU2ltcGxpZnlpbmcgd2l0aCB0aGUgU2FtcGxlIENvdmFyaWFuY2UgTWF0cml4Kg0KDQpUaGUgc3VtbWF0aW9uIHRlcm0gaXMgcmVsYXRlZCB0byB0aGUgc2FtcGxlIGNvdmFyaWFuY2UgbWF0cml4LiBMZXQncyBkZWZpbmUgdGhlIHNhbXBsZSBtZWFuIHZlY3RvciBhcyAkXGJhcntcbWF0aGJme3l9fSA9IFxmcmFjezF9e059IFxzdW1fe2k9MX1eTiBcbWF0aGJme3l9X2kkLiBJdCBjYW4gYmUgc2hvd24gdGhhdDoNCg0KJCQNClxzdW1fe2k9MX1ee059IChcbWF0aGJme3l9X2kgLSBcYm9sZHN5bWJvbHtcbnV9KV5UIFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSleey0xfSAoXG1hdGhiZnt5fV9pIC0gXGJvbGRzeW1ib2x7XG51fSkgPSBOIFxjZG90IFxtYXRocm17dHJ9XGxlZnQoIFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSleey0xfSBcbWF0aGJme1N9IFxyaWdodCkgKyBOIChcYmFye1xtYXRoYmZ7eX19IC0gXGJvbGRzeW1ib2x7XG51fSleVCBcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pXnstMX0gKFxiYXJ7XG1hdGhiZnt5fX0gLSBcYm9sZHN5bWJvbHtcbnV9KQ0KJCQNCg0Kd2hlcmUgJFxtYXRoYmZ7U30kIGlzIHRoZSB1bmJpYXNlZCBzYW1wbGUgY292YXJpYW5jZSBtYXRyaXg6DQoNCiQkDQpcbWF0aGJme1N9ID0gXGZyYWN7MX17Ti0xfSBcc3VtX3tpPTF9XntOfSAoXG1hdGhiZnt5fV9pIC0gXGJhcntcbWF0aGJme3l9fSkoXG1hdGhiZnt5fV9pIC0gXGJhcntcbWF0aGJme3l9fSleVA0KJCQNCg0KYW5kICRcbWF0aHJte3RyfShcY2RvdCkkIGlzIHRoZSB0cmFjZSBvcGVyYXRvci4NCg0KSW4gdGhlIHR5cGljYWwgc2V0dXAgd2hlcmUgdGhlIG1vZGVsIGZvciB0aGUgbWVhbnMgaXMgc2F0dXJhdGVkIChpLmUuLCB3ZSBzZXQgJFxib2xkc3ltYm9se1xudX0gPSBcYmFye1xtYXRoYmZ7eX19JCksIHRoZSBsYXN0IHRlcm0gdmFuaXNoZXMuIEZ1cnRoZXJtb3JlLCBmb3Igc2ltcGxpY2l0eSBpbiBkZXJpdmF0aW9uLCBpZiB3ZSB1c2UgdGhlIE1heGltdW0gTGlrZWxpaG9vZCBlc3RpbWF0b3IgZm9yIHRoZSBjb3ZhcmlhbmNlIG1hdHJpeCAkXG1hdGhiZntTfV97TUx9ID0gXGZyYWN7MX17Tn0gXHN1bV97aT0xfV57Tn0gKFxtYXRoYmZ7eX1faSAtIFxiYXJ7XG1hdGhiZnt5fX0pKFxtYXRoYmZ7eX1faSAtIFxiYXJ7XG1hdGhiZnt5fX0pXlQkLCB0aGUgZXhwcmVzc2lvbiBzaW1wbGlmaWVzIHNpZ25pZmljYW50bHkuDQoNCldpdGggJFxib2xkc3ltYm9se1xudX0gPSBcYmFye1xtYXRoYmZ7eX19JCwgd2UgZ2V0Og0KDQokJA0KXHN1bV97aT0xfV57Tn0gKFxtYXRoYmZ7eX1faSAtIFxib2xkc3ltYm9se1xudX0pXlQgXGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KV57LTF9IChcbWF0aGJme3l9X2kgLSBcYm9sZHN5bWJvbHtcbnV9KSA9IE4gXGNkb3QgXG1hdGhybXt0cn1cbGVmdCggXGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KV57LTF9IFxtYXRoYmZ7U31fe01MfSBccmlnaHQpDQokJA0KDQpTdWJzdGl0dXRpbmcgdGhpcyBiYWNrIGludG8gdGhlIGxvZy1saWtlbGlob29kIGZ1bmN0aW9uLCBhbmQgaWdub3JpbmcgdGhlIGNvbnN0YW50IHRlcm0gJC1cZnJhY3tOcH17Mn0gXGxuKDJccGkpJCBhcyBpdCBkb2VzIG5vdCBhZmZlY3Qgb3B0aW1pemF0aW9uLCB3ZSBhcnJpdmUgYXQgdGhlIGNvcmUgZnVuY3Rpb24gbWluaW1pemVkIGluIE1MLUNGQToNCg0KJCQNClxib3hlZHtcZWxsKFxib2xkc3ltYm9se1x0aGV0YX0pID0gLVxmcmFje059ezJ9IFxsZWZ0WyBcbG4gfFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSl8ICsgXG1hdGhybXt0cn1cbGVmdCggXG1hdGhiZntTfV97TUx9IFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSleey0xfSBccmlnaHQpIFxyaWdodF0gKyBcdGV4dHtjb25zdGFudH19DQokJA0KDQoqNy4zLiBNYXhpbXVtIExpa2VsaWhvb2QgRXN0aW1hdGlvbioNCg0KVGhlIE1heGltdW0gTGlrZWxpaG9vZCBlc3RpbWF0ZXMgJFxoYXR7XGJvbGRzeW1ib2x7XHRoZXRhfX0kIGFyZSBmb3VuZCBieSBtYXhpbWl6aW5nIHRoZSBsb2ctbGlrZWxpaG9vZCBmdW5jdGlvbjoNCg0KJCQNClxoYXR7XGJvbGRzeW1ib2x7XHRoZXRhfX1fe01MfSA9IFx1bmRlcnNldHtcYm9sZHN5bWJvbHtcdGhldGF9fXtcYXJnXG1heH0gXCBcZWxsKFxib2xkc3ltYm9se1x0aGV0YX0pDQokJA0KDQpJbiBwcmFjdGljZSwgdGhpcyBpcyBkb25lIHVzaW5nIGl0ZXJhdGl2ZSBudW1lcmljYWwgYWxnb3JpdGhtcyAoZS5nLiwgTmV3dG9uLVJhcGhzb24sIEZpc2hlciBTY29yaW5nKSBiZWNhdXNlIHRoZSBmdW5jdGlvbiAkXGVsbChcYm9sZHN5bWJvbHtcdGhldGF9KSQgaXMgaGlnaGx5IG5vbmxpbmVhciBpbiB0aGUgcGFyYW1ldGVycyAkXGJvbGRzeW1ib2x7XHRoZXRhfSQuDQoNClRoZSB2YWx1ZSBvZiB0aGUgbGlrZWxpaG9vZCBhdCB0aGUgbWF4aW11bSBpcyBhbHNvIHVzZWQgdG8gY29tcHV0ZSBnb29kbmVzcy1vZi1maXQgc3RhdGlzdGljcywgbW9zdCBub3RhYmx5IHRoZSBsaWtlbGlob29kIHJhdGlvIHRlc3QgKG9yIGNoaS1zcXVhcmUgdGVzdCBvZiBtb2RlbCBmaXQpLCB3aGljaCBjb21wYXJlcyB0aGUgZml0dGVkIG1vZGVsIHRvIGEgc2F0dXJhdGVkIG1vZGVsOg0KDQokJA0KXGNoaV4yID0gKE4tMSkgRl97TUx9DQokJA0KDQp3aGVyZSAkRl97TUx9JCBpcyB0aGUgbWluaW11bSB2YWx1ZSBvZiB0aGUgZGlzY3JlcGFuY3kgZnVuY3Rpb24sIGRlcml2ZWQgZnJvbSB0aGUgbG9nLWxpa2VsaWhvb2Q6DQoNCiQkDQpGX3tNTH0gPSBcbG4gfFxib2xkc3ltYm9se1xTaWdtYX0oXGhhdHtcYm9sZHN5bWJvbHtcdGhldGF9fSl8ICsgXG1hdGhybXt0cn1cbGVmdCggXG1hdGhiZntTfSBcYm9sZHN5bWJvbHtcU2lnbWF9KFxoYXR7XGJvbGRzeW1ib2x7XHRoZXRhfX0pXnstMX0gXHJpZ2h0KSAtIFxsbiB8XG1hdGhiZntTfXwgLSBwDQokJA0KDQpcDQoNCiMjIE1hdGhlbWF0aWNhbCBGb3JtdWxhdGlvbiBvZiBTRU0gTW9kZWwNCg0KKioxLiBNb2RlbCBTcGVjaWZpY2F0aW9uKioNCg0KTGV0IHRoZSBtb2RlbCBjb25zaXN0IG9mIHRoZSBmb2xsb3dpbmcgY29tcG9uZW50czoNCg0KLSAgICoqRXhvZ2Vub3VzIGxhdGVudCB2YXJpYWJsZXMqKjogJFxib2xkc3ltYm9se1x4aX0gPSAoXHhpXzEsIFx4aV8yKV5UJCwgd2hlcmU6DQogICAgLSAgICRceGlfMSQ6IFRlYWNoZXItY2VudGVyZWQNCiAgICAtICAgJFx4aV8yJDogU3R1ZGVudC1jZW50ZXJlZA0KLSAgICoqRW5kb2dlbm91cyBsYXRlbnQgdmFyaWFibGVzKio6ICRcYm9sZHN5bWJvbHtcZXRhfSA9IChcZXRhXzEsIFxldGFfMileVCQsIHdoZXJlOg0KICAgIC0gICAkXGV0YV8xJDogTWF0aCBFdmFsdWF0aW9uIEFueGlldHkgKE1FQSkNCiAgICAtICAgJFxldGFfMiQ6IE1hdGggTGVhcm5pbmcgQW54aWV0eSAoTUxBKQ0KLSAgICoqT2JzZXJ2ZWQgaW5kaWNhdG9ycyBmb3IgVGVhY2hlci1jZW50ZXJlZCoqOiAkXG1hdGhiZnt4fV8xID0gKHhfMSwgeF8yLCB4XzMsIHhfNCleVCQgd2hlcmU6DQogICAgLSAgICR4XzEkOiBEZWR1Y3RpdmUNCiAgICAtICAgJHhfMiQ6IExlY3R1cmUNCiAgICAtICAgJHhfMyQ6IERlbW9uc3RyYXRpb24NCiAgICAtICAgJHhfNCQ6IFJlcGV0aXRpdmUNCi0gICAqKk9ic2VydmVkIGluZGljYXRvcnMgZm9yIFN0dWRlbnQtY2VudGVyZWQqKjogJFxtYXRoYmZ7eH1fMiA9ICh4XzUsIHhfNiwgeF83KV5UJCB3aGVyZToNCiAgICAtICAgJHhfNSQ6IENvb3BlcmF0aXZlDQogICAgLSAgICR4XzYkOiBJbmR1Y3RpdmUNCiAgICAtICAgJHhfNyQ6IEludGVncmF0aXZlDQotICAgKipPYnNlcnZlZCBpbmRpY2F0b3JzIGZvciBNRUEqKjogJFxtYXRoYmZ7eX1fMSA9ICh5XzEsIHlfMiwgeV8zLCB5XzQpXlQkIChNRUExLU1FQTQpDQotICAgKipPYnNlcnZlZCBpbmRpY2F0b3JzIGZvciBNTEEqKjogJFxtYXRoYmZ7eX1fMiA9ICh5XzUsIHlfNiwgeV83LCB5XzgsIHlfOSleVCQgKE1MQTEsIE1MQTMsIE1MQTYsIE1MQTcsIE1MQTkpDQotICAgKipFeG9nZW5vdXMgb2JzZXJ2ZWQgdmFyaWFibGVzKio6ICRcbWF0aGJme3d9ID0gKHdfMSwgd18yLCB3XzMsIHdfNCwgd181KV5UJCB3aGVyZToNCiAgICAtICAgJHdfMSQ6IFNlbGYtZWZmaWNhY3kNCiAgICAtICAgJHdfMiQ6IFRlY2hub2xvZ3kNCiAgICAtICAgJHdfMyQ6IEVuZ2FnZW1lbnQNCiAgICAtICAgJHdfNCQ6IEdlbmRlcg0KICAgIC0gICAkd181JDogUmVzb3VyY2UNCg0KKioyLiBNZWFzdXJlbWVudCBNb2RlbHMqKg0KDQoqRm9yIGV4b2dlbm91cyBsYXRlbnQgdmFyaWFibGVzOioNCg0KJCQNClxiZWdpbnthbGlnbip9DQpcbWF0aGJme3h9ICY9IFxib2xkc3ltYm9se1xMYW1iZGF9X3ggXGJvbGRzeW1ib2x7XHhpfSArIFxib2xkc3ltYm9se1xkZWx0YX0gXFwNClxiZWdpbntibWF0cml4fQ0KeF8xIFxcIHhfMiBcXCB4XzMgXFwgeF80IFxcIHhfNSBcXCB4XzYgXFwgeF83DQpcZW5ke2JtYXRyaXh9DQomPQ0KXGJlZ2lue2JtYXRyaXh9DQpcbGFtYmRhX3sxLDF9ICYgMCBcXA0KXGxhbWJkYV97MiwxfSAmIDAgXFwNClxsYW1iZGFfezMsMX0gJiAwIFxcDQpcbGFtYmRhX3s0LDF9ICYgMCBcXA0KMCAmIFxsYW1iZGFfezUsMn0gXFwNCjAgJiBcbGFtYmRhX3s2LDJ9IFxcDQowICYgXGxhbWJkYV97NywyfQ0KXGVuZHtibWF0cml4fQ0KXGJlZ2lue2JtYXRyaXh9DQpceGlfMSBcXCBceGlfMg0KXGVuZHtibWF0cml4fQ0KKw0KXGJlZ2lue2JtYXRyaXh9DQpcZGVsdGFfMSBcXCBcZGVsdGFfMiBcXCBcZGVsdGFfMyBcXCBcZGVsdGFfNCBcXCBcZGVsdGFfNSBcXCBcZGVsdGFfNiBcXCBcZGVsdGFfNw0KXGVuZHtibWF0cml4fQ0KXGVuZHthbGlnbip9DQokJA0KDQoqRm9yIGVuZG9nZW5vdXMgbGF0ZW50IHZhcmlhYmxlczoqDQoNCiQkDQpcYmVnaW57YWxpZ24qfQ0KXG1hdGhiZnt5fSAmPSBcYm9sZHN5bWJvbHtcTGFtYmRhfV95IFxib2xkc3ltYm9se1xldGF9ICsgXGJvbGRzeW1ib2x7XGVwc2lsb259IFxcDQpcYmVnaW57Ym1hdHJpeH0NCnlfMSBcXCB5XzIgXFwgeV8zIFxcIHlfNCBcXCB5XzUgXFwgeV82IFxcIHlfNyBcXCB5XzggXFwgeV85DQpcZW5ke2JtYXRyaXh9DQomPQ0KXGJlZ2lue2JtYXRyaXh9DQpcbGFtYmRhX3sxLDF9XnkgJiAwIFxcDQpcbGFtYmRhX3syLDF9XnkgJiAwIFxcDQpcbGFtYmRhX3szLDF9XnkgJiAwIFxcDQpcbGFtYmRhX3s0LDF9XnkgJiAwIFxcDQowICYgXGxhbWJkYV97NSwyfV55IFxcDQowICYgXGxhbWJkYV97NiwyfV55IFxcDQowICYgXGxhbWJkYV97NywyfV55IFxcDQowICYgXGxhbWJkYV97OCwyfV55IFxcDQowICYgXGxhbWJkYV97OSwyfV55DQpcZW5ke2JtYXRyaXh9DQpcYmVnaW57Ym1hdHJpeH0NClxldGFfMSBcXCBcZXRhXzINClxlbmR7Ym1hdHJpeH0NCisNClxiZWdpbntibWF0cml4fQ0KXGVwc2lsb25fMSBcXCBcZXBzaWxvbl8yIFxcIFxlcHNpbG9uXzMgXFwgXGVwc2lsb25fNCBcXCBcZXBzaWxvbl81IFxcIA0KXGVwc2lsb25fNiBcXCBcZXBzaWxvbl83IFxcIFxlcHNpbG9uXzggXFwgXGVwc2lsb25fOQ0KXGVuZHtibWF0cml4fQ0KXGVuZHthbGlnbip9DQokJA0KDQoqKjMuIFN0cnVjdHVyYWwgTW9kZWwqKg0KDQpUaGUgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIGxhdGVudCBhbmQgb2JzZXJ2ZWQgdmFyaWFibGVzOg0KDQokJA0KXGJlZ2lue2FsaWduKn0NClxib2xkc3ltYm9se1xldGF9ICY9IFxtYXRoYmZ7Qn0gXGJvbGRzeW1ib2x7XGV0YX0gKyBcYm9sZHN5bWJvbHtcR2FtbWF9IFxib2xkc3ltYm9se1x4aX0gKyBcYm9sZHN5bWJvbHtcR2FtbWF9X3cgXG1hdGhiZnt3fSArIFxib2xkc3ltYm9se1x6ZXRhfSBcXA0KXGJlZ2lue2JtYXRyaXh9DQpcZXRhXzEgXFwgXGV0YV8yDQpcZW5ke2JtYXRyaXh9DQomPQ0KXGJlZ2lue2JtYXRyaXh9DQowICYgMCBcXA0KXGJldGFfezIxfSAmIDANClxlbmR7Ym1hdHJpeH0NClxiZWdpbntibWF0cml4fQ0KXGV0YV8xIFxcIFxldGFfMg0KXGVuZHtibWF0cml4fQ0KKw0KXGJlZ2lue2JtYXRyaXh9DQpcZ2FtbWFfezExfSAmIFxnYW1tYV97MTJ9IFxcDQpcZ2FtbWFfezIxfSAmIFxnYW1tYV97MjJ9DQpcZW5ke2JtYXRyaXh9DQpcYmVnaW57Ym1hdHJpeH0NClx4aV8xIFxcIFx4aV8yDQpcZW5ke2JtYXRyaXh9DQorDQpcYmVnaW57Ym1hdHJpeH0NClxnYW1tYV97MTN9ICYgXGdhbW1hX3sxNH0gJiBcZ2FtbWFfezE1fSAmIFxnYW1tYV97MTZ9ICYgXGdhbW1hX3sxN30gXFwNClxnYW1tYV97MjN9ICYgXGdhbW1hX3syNH0gJiBcZ2FtbWFfezI1fSAmIFxnYW1tYV97MjZ9ICYgXGdhbW1hX3syN30NClxlbmR7Ym1hdHJpeH0NClxiZWdpbntibWF0cml4fQ0Kd18xIFxcIHdfMiBcXCB3XzMgXFwgd180IFxcIHdfNQ0KXGVuZHtibWF0cml4fQ0KKw0KXGJlZ2lue2JtYXRyaXh9DQpcemV0YV8xIFxcIFx6ZXRhXzINClxlbmR7Ym1hdHJpeH0NClxlbmR7YWxpZ24qfQ0KJCQNCg0KKio0LiBBc3N1bXB0aW9ucyoqDQoNCi0gICBUaGUgbWVhc3VyZW1lbnQgZXJyb3JzIGFyZSB1bmNvcnJlbGF0ZWQgd2l0aCB0aGUgbGF0ZW50IHZhcmlhYmxlczoNCg0KJCQNCiAgICBcYmVnaW57YWxpZ24qfQ0KICAgIEUoXGJvbGRzeW1ib2x7XGRlbHRhfXxcYm9sZHN5bWJvbHtceGl9KSA9IFxtYXRoYmZ7MH0sIFxxdWFkIEUoXGJvbGRzeW1ib2x7XGVwc2lsb259fFxib2xkc3ltYm9se1xldGF9KSA9IFxtYXRoYmZ7MH0NCiAgICBcZW5ke2FsaWduKn0NCiQkDQoNCi0gICBUaGUgc3RydWN0dXJhbCBkaXN0dXJiYW5jZXMgaGF2ZSB6ZXJvIG1lYW4gYW5kIGFyZSB1bmNvcnJlbGF0ZWQgd2l0aCB0aGUgZXhvZ2Vub3VzIHZhcmlhYmxlczoNCg0KJCQNCiAgICBcYmVnaW57YWxpZ24qfQ0KICAgIEUoXGJvbGRzeW1ib2x7XHpldGF9KSA9IFxtYXRoYmZ7MH0sIFxxdWFkIFx0ZXh0e0Nvdn0oXGJvbGRzeW1ib2x7XHpldGF9LCBcYm9sZHN5bWJvbHtceGl9KSA9IFxtYXRoYmZ7MH0sIFxxdWFkIFx0ZXh0e0Nvdn0oXGJvbGRzeW1ib2x7XHpldGF9LCBcbWF0aGJme3d9KSA9IFxtYXRoYmZ7MH0NCiAgICBcZW5ke2FsaWduKn0NCiQkDQoNCi0gICBUaGUgbWVhc3VyZW1lbnQgZXJyb3JzIGFuZCBzdHJ1Y3R1cmFsIGRpc3R1cmJhbmNlcyBhcmUgbXV0dWFsbHkgdW5jb3JyZWxhdGVkOg0KDQokJA0KICAgIFxiZWdpbnthbGlnbip9DQogICAgXHRleHR7Q292fShcYm9sZHN5bWJvbHtcZGVsdGF9LCBcYm9sZHN5bWJvbHtcZXBzaWxvbn0pID0gXG1hdGhiZnswfSwgXHF1YWQgXHRleHR7Q292fShcYm9sZHN5bWJvbHtcZGVsdGF9LCBcYm9sZHN5bWJvbHtcemV0YX0pID0gXG1hdGhiZnswfSwgXHF1YWQgXHRleHR7Q292fShcYm9sZHN5bWJvbHtcZXBzaWxvbn0sIFxib2xkc3ltYm9se1x6ZXRhfSkgPSBcbWF0aGJmezB9DQogICAgXGVuZHthbGlnbip9DQokJA0KDQotICAgVGhlIG1lYXN1cmVtZW50IGVycm9ycyBhcmUgbXV0dWFsbHkgdW5jb3JyZWxhdGVkOg0KDQokJA0KICAgIFxiZWdpbnthbGlnbip9DQogICAgXHRleHR7Q292fShcYm9sZHN5bWJvbHtcZGVsdGF9KSA9IFxib2xkc3ltYm9se1xUaGV0YX1fe1xkZWx0YX0gPSBcdGV4dHtkaWFnfShcdGhldGFfe1xkZWx0YSwxfSwgXGRvdHMsIFx0aGV0YV97XGRlbHRhLDd9KQ0KICAgIFxlbmR7YWxpZ24qfQ0KJCQNCg0KJCQNCiAgICBcYmVnaW57YWxpZ24qfQ0KICAgIFx0ZXh0e0Nvdn0oXGJvbGRzeW1ib2x7XGVwc2lsb259KSA9IFxib2xkc3ltYm9se1xUaGV0YX1fe1xlcHNpbG9ufSA9IFx0ZXh0e2RpYWd9KFx0aGV0YV97XGVwc2lsb24sMX0sIFxkb3RzLCBcdGhldGFfe1xlcHNpbG9uLDl9KQ0KICAgIFxlbmR7YWxpZ24qfQ0KJCQNCg0KLSAgIFRoZSBzdHJ1Y3R1cmFsIGRpc3R1cmJhbmNlcyBoYXZlIGNvdmFyaWFuY2UgbWF0cml4Og0KDQokJA0KICAgIFxiZWdpbnthbGlnbip9DQogICAgXHRleHR7Q292fShcYm9sZHN5bWJvbHtcemV0YX0pID0gXGJvbGRzeW1ib2x7XFBzaX0gPSANCiAgICBcYmVnaW57Ym1hdHJpeH0NCiAgICBccHNpX3sxMX0gJiBccHNpX3sxMn0gXFwNCiAgICBccHNpX3syMX0gJiBccHNpX3syMn0NCiAgICBcZW5ke2JtYXRyaXh9DQogICAgXGVuZHthbGlnbip9DQokJA0KDQotICAgVGhlIGV4b2dlbm91cyBsYXRlbnQgdmFyaWFibGVzIGhhdmUgY292YXJpYW5jZSBtYXRyaXg6DQoNCiQkDQogICAgXGJlZ2lue2FsaWduKn0NCiAgICBcdGV4dHtDb3Z9KFxib2xkc3ltYm9se1x4aX0pID0gXGJvbGRzeW1ib2x7XFBoaX0gPSANCiAgICBcYmVnaW57Ym1hdHJpeH0NCiAgICBccGhpX3sxMX0gJiBccGhpX3sxMn0gXFwNCiAgICBccGhpX3syMX0gJiBccGhpX3syMn0NCiAgICBcZW5ke2JtYXRyaXh9DQogICAgXGVuZHthbGlnbip9DQokJA0KDQotICAgVGhlIGV4b2dlbm91cyBvYnNlcnZlZCB2YXJpYWJsZXMgaGF2ZSBjb3ZhcmlhbmNlIG1hdHJpeDoNCg0KJCQNCiAgICBcYmVnaW57YWxpZ24qfQ0KICAgIFx0ZXh0e0Nvdn0oXG1hdGhiZnt3fSkgPSBcYm9sZHN5bWJvbHtcUGhpfV93DQogICAgXGVuZHthbGlnbip9DQokJA0KDQotICAgQWxsIHZhcmlhYmxlcyBhcmUgbXVsdGl2YXJpYXRlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLg0KDQoqKjUuIEltcGxpZWQgQ292YXJpYW5jZSBNYXRyaXgqKg0KDQpMZXQgJFxib2xkc3ltYm9se1x0aGV0YX0kIHJlcHJlc2VudCBhbGwgbW9kZWwgcGFyYW1ldGVycy4gVGhlIGltcGxpZWQgY292YXJpYW5jZSBtYXRyaXggb2YgdGhlIG9ic2VydmVkIHZhcmlhYmxlcyAkXG1hdGhiZnt6fSA9IChcbWF0aGJme3h9XlQsIFxtYXRoYmZ7eX1eVCwgXG1hdGhiZnt3fV5UKV5UJCBpczoNCg0KJCQNClxiZWdpbnthbGlnbip9DQpcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pID0gDQpcYmVnaW57Ym1hdHJpeH0NClxib2xkc3ltYm9se1xTaWdtYX1fe3h4fShcYm9sZHN5bWJvbHtcdGhldGF9KSAmIFxib2xkc3ltYm9se1xTaWdtYX1fe3h5fShcYm9sZHN5bWJvbHtcdGhldGF9KSAmIFxib2xkc3ltYm9se1xTaWdtYX1fe3h3fShcYm9sZHN5bWJvbHtcdGhldGF9KSBcXA0KXGJvbGRzeW1ib2x7XFNpZ21hfV97eXh9KFxib2xkc3ltYm9se1x0aGV0YX0pICYgXGJvbGRzeW1ib2x7XFNpZ21hfV97eXl9KFxib2xkc3ltYm9se1x0aGV0YX0pICYgXGJvbGRzeW1ib2x7XFNpZ21hfV97eXd9KFxib2xkc3ltYm9se1x0aGV0YX0pIFxcDQpcYm9sZHN5bWJvbHtcU2lnbWF9X3t3eH0oXGJvbGRzeW1ib2x7XHRoZXRhfSkgJiBcYm9sZHN5bWJvbHtcU2lnbWF9X3t3eX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkgJiBcYm9sZHN5bWJvbHtcU2lnbWF9X3t3d30oXGJvbGRzeW1ib2x7XHRoZXRhfSkNClxlbmR7Ym1hdHJpeH0NClxlbmR7YWxpZ24qfQ0KJCQNCg0Kd2hlcmU6DQoNCiQkDQpcYmVnaW57YWxpZ24qfQ0KXGJvbGRzeW1ib2x7XFNpZ21hfV97eHh9KFxib2xkc3ltYm9se1x0aGV0YX0pICY9IFxib2xkc3ltYm9se1xMYW1iZGF9X3ggXGJvbGRzeW1ib2x7XFBoaX0gXGJvbGRzeW1ib2x7XExhbWJkYX1feF5UICsgXGJvbGRzeW1ib2x7XFRoZXRhfV97XGRlbHRhfSBcXA0KXGJvbGRzeW1ib2x7XFNpZ21hfV97eXl9KFxib2xkc3ltYm9se1x0aGV0YX0pICY9IFxib2xkc3ltYm9se1xMYW1iZGF9X3kgKFxtYXRoYmZ7SX0tXG1hdGhiZntCfSleey0xfSAoXGJvbGRzeW1ib2x7XEdhbW1hfSBcYm9sZHN5bWJvbHtcUGhpfSBcYm9sZHN5bWJvbHtcR2FtbWF9XlQgKyBcYm9sZHN5bWJvbHtcR2FtbWF9X3cgXGJvbGRzeW1ib2x7XFBoaX1fdyBcYm9sZHN5bWJvbHtcR2FtbWF9X3deVCArIFxib2xkc3ltYm9se1xQc2l9KSBbKFxtYXRoYmZ7SX0tXG1hdGhiZntCfSleey0xfV1eVCBcYm9sZHN5bWJvbHtcTGFtYmRhfV95XlQgKyBcYm9sZHN5bWJvbHtcVGhldGF9X3tcZXBzaWxvbn0gXFwNClxib2xkc3ltYm9se1xTaWdtYX1fe3d3fShcYm9sZHN5bWJvbHtcdGhldGF9KSAmPSBcYm9sZHN5bWJvbHtcUGhpfV93IFxcDQpcYm9sZHN5bWJvbHtcU2lnbWF9X3t4eX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkgJj0gXGJvbGRzeW1ib2x7XExhbWJkYX1feCBcYm9sZHN5bWJvbHtcUGhpfSBcYm9sZHN5bWJvbHtcR2FtbWF9XlQgWyhcbWF0aGJme0l9LVxtYXRoYmZ7Qn0pXnstMX1dXlQgXGJvbGRzeW1ib2x7XExhbWJkYX1feV5UIFxcDQpcYm9sZHN5bWJvbHtcU2lnbWF9X3t4d30oXGJvbGRzeW1ib2x7XHRoZXRhfSkgJj0gXGJvbGRzeW1ib2x7XExhbWJkYX1feCBcdGV4dHtDb3Z9KFxib2xkc3ltYm9se1x4aX0sIFxtYXRoYmZ7d30pIFxcDQpcYm9sZHN5bWJvbHtcU2lnbWF9X3t5d30oXGJvbGRzeW1ib2x7XHRoZXRhfSkgJj0gXGJvbGRzeW1ib2x7XExhbWJkYX1feSAoXG1hdGhiZntJfS1cbWF0aGJme0J9KV57LTF9IChcYm9sZHN5bWJvbHtcR2FtbWF9IFx0ZXh0e0Nvdn0oXGJvbGRzeW1ib2x7XHhpfSwgXG1hdGhiZnt3fSkgKyBcYm9sZHN5bWJvbHtcR2FtbWF9X3cgXGJvbGRzeW1ib2x7XFBoaX1fdykNClxlbmR7YWxpZ24qfQ0KJCQNCg0KKio2LiBMaWtlbGlob29kIEZ1bmN0aW9uKioNCg0KQXNzdW1pbmcgbXVsdGl2YXJpYXRlIG5vcm1hbGl0eSBvZiB0aGUgb2JzZXJ2ZWQgdmFyaWFibGVzICRcbWF0aGJme3p9IFxzaW0gTihcYm9sZHN5bWJvbHtcbXV9LCBcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pKSQsIHRoZSBsaWtlbGlob29kIGZ1bmN0aW9uIGZvciBhIHNhbXBsZSBvZiAkbiQgaW5kZXBlbmRlbnQgb2JzZXJ2YXRpb25zIGlzOg0KDQokJA0KXGJlZ2lue2FsaWduKn0NCkwoXGJvbGRzeW1ib2x7XHRoZXRhfSkgJj0gXHByb2Rfe2k9MX1ebiAoMlxwaSleey1wLzJ9IHxcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pfF57LTEvMn0gXGV4cFxsZWZ0Wy1cZnJhY3sxfXsyfShcbWF0aGJme3p9X2kgLSBcYm9sZHN5bWJvbHtcbXV9KV5UIFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSleey0xfSAoXG1hdGhiZnt6fV9pIC0gXGJvbGRzeW1ib2x7XG11fSlccmlnaHRdDQpcZW5ke2FsaWduKn0NCiQkDQoNCndoZXJlICRwID0gNyArIDkgKyA1ID0gMjEkIGlzIHRoZSB0b3RhbCBudW1iZXIgb2Ygb2JzZXJ2ZWQgdmFyaWFibGVzLg0KDQpUaGUgbG9nLWxpa2VsaWhvb2QgZnVuY3Rpb24gaXM6DQoNCiQkDQpcYmVnaW57YWxpZ24qfQ0KXGVsbChcYm9sZHN5bWJvbHtcdGhldGF9KSAmPSAtXGZyYWN7bnB9ezJ9IFxsb2coMlxwaSkgLSBcZnJhY3tufXsyfSBcbG9nfFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSl8IFxcDQomXHF1YWQgLSBcZnJhY3sxfXsyfSBcc3VtX3tpPTF9Xm4gKFxtYXRoYmZ7en1faSAtIFxib2xkc3ltYm9se1xtdX0pXlQgXGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KV57LTF9IChcbWF0aGJme3p9X2kgLSBcYm9sZHN5bWJvbHtcbXV9KQ0KXGVuZHthbGlnbip9DQokJA0KDQpGb3IgZXN0aW1hdGlvbiwgd2UgdHlwaWNhbGx5IHVzZSB0aGUgZGlzY3JlcGFuY3kgZnVuY3Rpb246DQoNCiQkDQpcYmVnaW57YWxpZ24qfQ0KRl97TUx9KFxib2xkc3ltYm9se1x0aGV0YX0pICY9IFxsb2d8XGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KXwgKyBcdGV4dHt0cn0oXG1hdGhiZntTfSBcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pXnstMX0pIC0gXGxvZ3xcbWF0aGJme1N9fCAtIHANClxlbmR7YWxpZ24qfQ0KJCQNCg0Kd2hlcmUgJFxtYXRoYmZ7U30kIGlzIHRoZSBzYW1wbGUgY292YXJpYW5jZSBtYXRyaXguDQoNCioqNy4gUGFyYW1ldGVycyB0byBFc3RpbWF0ZSoqDQoNClRoZSBtb2RlbCBwYXJhbWV0ZXJzIGluY2x1ZGU6DQoNCi0gICBGYWN0b3IgbG9hZGluZ3M6ICRcbGFtYmRhX3tpan0kIGluICRcYm9sZHN5bWJvbHtcTGFtYmRhfV94JCBhbmQgJFxib2xkc3ltYm9se1xMYW1iZGF9X3kkDQotICAgU3RydWN0dXJhbCBjb2VmZmljaWVudHM6ICRcYmV0YV97aWp9JCBpbiAkXG1hdGhiZntCfSQsICRcZ2FtbWFfe2lqfSQgaW4gJFxib2xkc3ltYm9se1xHYW1tYX0kLCAkXGdhbW1hX3tpan1edyQgaW4gJFxib2xkc3ltYm9se1xHYW1tYX1fdyQNCi0gICBWYXJpYW5jZXMgYW5kIGNvdmFyaWFuY2VzOiAkXHBoaV97aWp9JCBpbiAkXGJvbGRzeW1ib2x7XFBoaX0kLCAkXHBzaV97aWp9JCBpbiAkXGJvbGRzeW1ib2x7XFBzaX0kLCAkXHBoaV97dyxpan0kIGluICRcYm9sZHN5bWJvbHtcUGhpfV93JA0KLSAgIE1lYXN1cmVtZW50IGVycm9yIHZhcmlhbmNlczogJFx0aGV0YV97XGRlbHRhLGl9JCBpbiAkXGJvbGRzeW1ib2x7XFRoZXRhfV97XGRlbHRhfSQsICRcdGhldGFfe1xlcHNpbG9uLGl9JCBpbiAkXGJvbGRzeW1ib2x7XFRoZXRhfV97XGVwc2lsb259JA0KDQpUeXBpY2FsbHksIHdlIHNldCBvbmUgbG9hZGluZyBwZXIgbGF0ZW50IHZhcmlhYmxlIHRvIDEgZm9yIGlkZW50aWZpY2F0aW9uLg0KDQoqKjguIE1vZGVsIElkZW50aWZpY2F0aW9uKioNCg0KVGhlIG1vZGVsIGlzIGlkZW50aWZpZWQgaWY6DQoNCi0gICBFYWNoIGxhdGVudCB2YXJpYWJsZSBoYXMgYXQgbGVhc3QgMyBpbmRpY2F0b3JzIChzYXRpc2ZpZWQpDQotICAgVGhlIHNjYWxlIG9mIGVhY2ggbGF0ZW50IHZhcmlhYmxlIGlzIHNldCBieSBmaXhpbmcgb25lIGxvYWRpbmcgdG8gMQ0KLSAgIFRoZSBtb2RlbCBtZWV0cyB0aGUgb3JkZXIgY29uZGl0aW9uIGFuZCByYW5rIGNvbmRpdGlvbiBmb3IgaWRlbnRpZmljYXRpb24NCg0KDQojIyBXTFNNViBmb3IgTGlrZXJ0IERhdGEgaW4gU0VNDQoNCg0KVGhlIFdlaWdodGVkIExlYXN0IFNxdWFyZXMgTWVhbiBhbmQgVmFyaWFuY2UgQWRqdXN0ZWQgKFdMU01WKSBlc3RpbWF0b3IgaXMgYSByb2J1c3QgZXN0aW1hdGlvbiBtZXRob2QgZGVzaWduZWQgc3BlY2lmaWNhbGx5IGZvciBzdHJ1Y3R1cmFsIGVxdWF0aW9uIG1vZGVsaW5nIChTRU0pIHdpdGggY2F0ZWdvcmljYWwgb3Igb3JkaW5hbCBkYXRhLCBwYXJ0aWN1bGFybHkgbXVsdGktaXRlbSBMaWtlcnQgc2NhbGVzLiBXaGVuIHdvcmtpbmcgd2l0aCBvcmRlcmVkIGNhdGVnb3JpY2FsIGluZGljYXRvcnMgKGUuZy4sIExpa2VydC10eXBlIGl0ZW1zIHdpdGggMi03IHJlc3BvbnNlIGNhdGVnb3JpZXMpLCB0cmFkaXRpb25hbCBtYXhpbXVtIGxpa2VsaWhvb2QgKE1MKSBlc3RpbWF0aW9uIGFzc3VtZXMgY29udGludW91cyBub3JtYWxseSBkaXN0cmlidXRlZCB2YXJpYWJsZXMsIHdoaWNoIHZpb2xhdGVzIHRoZSBkaXNjcmV0ZSBuYXR1cmUgb2Ygb3JkaW5hbCBkYXRhLg0KDQojIyMgTWF0aGVtYXRpY2FsIEZvdW5kYXRpb24NCg0KTGV0ICRcbWF0aGJme3h9XiokIHJlcHJlc2VudCB0aGUgbGF0ZW50IGNvbnRpbnVvdXMgdmFyaWFibGVzIHVuZGVybHlpbmcgdGhlIG9ic2VydmVkIG9yZGluYWwgcmVzcG9uc2VzICRcbWF0aGJme3h9JC4gVGhlIG1lYXN1cmVtZW50IG1vZGVsIGNhbiBiZSBleHByZXNzZWQgYXM6DQoNCiQkDQpcbWF0aGJme3h9XiogPSBcYm9sZHN5bWJvbHtcTGFtYmRhfSBcYm9sZHN5bWJvbHtceGl9ICsgXGJvbGRzeW1ib2x7XGRlbHRhfQ0KJCQNCg0Kd2hlcmUgJFxib2xkc3ltYm9se1xMYW1iZGF9JCBpcyB0aGUgZmFjdG9yIGxvYWRpbmcgbWF0cml4LCAkXGJvbGRzeW1ib2x7XHhpfSQgcmVwcmVzZW50cyBsYXRlbnQgdmFyaWFibGVzLCBhbmQgJFxib2xkc3ltYm9se1xkZWx0YX0kIGRlbm90ZXMgbWVhc3VyZW1lbnQgZXJyb3JzLg0KDQpUaGUgV0xTTVYgZXN0aW1hdG9yIG1pbmltaXplcyB0aGUgZGlzY3JlcGFuY3kgZnVuY3Rpb246DQoNCiQkDQpGX3tXTFNNVn0gPSAoXG1hdGhiZntzfSAtIFxib2xkc3ltYm9se1xzaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkpJyBcbWF0aGJme1d9XnstMX0gKFxtYXRoYmZ7c30gLSBcYm9sZHN5bWJvbHtcc2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pKQ0KJCQNCg0KKiAkXG1hdGhiZntzfSQgaXMgdGhlIHZlY3RvciBvZiBzYW1wbGUgcG9seWNob3JpYyBjb3JyZWxhdGlvbnMgYW5kIHRocmVzaG9sZCBlc3RpbWF0ZXMNCiogJFxib2xkc3ltYm9se1xzaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkkIGNvbnRhaW5zIHRoZSBtb2RlbC1pbXBsaWVkIGNvcnJlbGF0aW9ucyBhbmQgdGhyZXNob2xkcw0KKiAkXG1hdGhiZntXfSQgaXMgdGhlIGNvbnNpc3RlbnQgYXN5bXB0b3RpYyBjb3ZhcmlhbmNlIG1hdHJpeCBvZiAkXG1hdGhiZntzfSQNCg0KDQoqKktleSBGZWF0dXJlcyBmb3IgTXVsdGktaXRlbSBMaWtlcnQgRGF0YSoqDQoNCiogKipQb2x5Y2hvcmljIENvcnJlbGF0aW9ucyoqOiBXTFNNViB1dGlsaXplcyBwb2x5Y2hvcmljIGNvcnJlbGF0aW9ucyB0aGF0IGVzdGltYXRlIHRoZSBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gdW5kZXJseWluZyBjb250aW51b3VzIHZhcmlhYmxlcywgcHJvdmlkaW5nIG1vcmUgYWNjdXJhdGUgZXN0aW1hdGVzIHRoYW4gUGVhcnNvbiBjb3JyZWxhdGlvbnMgZm9yIG9yZGluYWwgZGF0YS4NCiogKipUaHJlc2hvbGQgRXN0aW1hdGlvbioqOiBUaGUgbWV0aG9kIGVzdGltYXRlcyB0aHJlc2hvbGRzICRcYm9sZHN5bWJvbHtcdGF1fSQgdGhhdCBkZWZpbmUgdGhlIGJvdW5kYXJpZXMgYmV0d2VlbiByZXNwb25zZSBjYXRlZ29yaWVzOg0KDQokJA0KeF9pID0gayBccXVhZCBcdGV4dHtpZn0gXHF1YWQgXHRhdV97ay0xfSA8IHhfaV4qIFxsZXEgXHRhdV9rDQokJA0KDQoqICoqRGlhZ29uYWwgV2VpZ2h0IE1hdHJpeCoqOiBXTFNNViBlbXBsb3lzIGEgZGlhZ29uYWwgd2VpZ2h0IG1hdHJpeCBjb250YWluaW5nIGFzeW1wdG90aWMgdmFyaWFuY2VzIG9mIHBvbHljaG9yaWMgY29ycmVsYXRpb25zLCBtYWtpbmcgaXQgY29tcHV0YXRpb25hbGx5IGVmZmljaWVudCB3aGlsZSBtYWludGFpbmluZyByb2J1c3RuZXNzLg0KDQoqICoqTWVhbiBhbmQgVmFyaWFuY2UgQWRqdXN0bWVudCoqOiBUaGUgZXN0aW1hdG9yIGluY29ycG9yYXRlcyBzY2FsaW5nIGNvcnJlY3Rpb25zIHRvIHRoZSB0ZXN0IHN0YXRpc3RpY3MsIHByb3ZpZGluZyBiZXR0ZXIgYXBwcm94aW1hdGlvbiB0byAkXGNoaV4yJCBkaXN0cmlidXRpb25zIHdpdGggc21hbGwgdG8gbW9kZXJhdGUgc2FtcGxlIHNpemVzLg0KDQoNCg0KKipJbnRyb2R1Y3Rpb24gdG8gdGhlIEVzdGltYXRvcioqDQoNClRoZSBXZWlnaHRlZCBMZWFzdCBTcXVhcmVzIE1lYW4gYW5kIFZhcmlhbmNlIGFkanVzdGVkIChXTFNNVikgZXN0aW1hdG9yIGlzIGEgcm9idXN0IGVzdGltYXRpb24gbWV0aG9kIGRldmVsb3BlZCBmb3Igc3RydWN0dXJhbCBlcXVhdGlvbiBtb2RlbGluZyAoU0VNKSB3aXRoIGNhdGVnb3JpY2FsLCBhbmQgaW4gcGFydGljdWxhciwgb3JkaW5hbCBvYnNlcnZlZCB2YXJpYWJsZXMuIEl0IGlzIHRoZSByZWNvbW1lbmRlZCBlc3RpbWF0b3IgZm9yIGNvbmZpcm1hdG9yeSBmYWN0b3IgYW5hbHlzaXMgKENGQSkgYW5kIFNFTSB3aGVuIHRoZSBpbmRpY2F0b3JzIGFyZSBtZWFzdXJlZCBvbiBhbiBvcmRpbmFsIHNjYWxlLCBzdWNoIGFzIG11bHRpLWl0ZW0gTGlrZXJ0IHNjYWxlcyBjb21tb24gaW4gc29jaWFsIGFuZCBiZWhhdmlvcmFsIHNjaWVuY2VzIChCcm93biwgMjAxNSwgRmxvcmEsIDIwMjIpLg0KDQpUaGUgbmVlZCBmb3IgV0xTTVYgYXJpc2VzIGZyb20gdGhlIHZpb2xhdGlvbiBvZiBhc3N1bXB0aW9ucyB1bmRlcmx5aW5nIG1heGltdW0gbGlrZWxpaG9vZCAoTUwpIGVzdGltYXRpb24gd2hlbiBvYnNlcnZlZCB2YXJpYWJsZXMgYXJlIG9yZGluYWwuIE1MIGFzc3VtZXMgY29udGludW91cywgbXVsdGl2YXJpYXRlIG5vcm1hbCBkYXRhLiBMaWtlcnQtc2NhbGUgaXRlbXMgYXJlIGRpc2NyZXRlLCBoYXZlIGxpbWl0ZWQgc2NhbGUgcG9pbnRzLCBhbmQgdGhlaXIgZGlzdHJpYnV0aW9ucyBhcmUgb2Z0ZW4gbm9uLW5vcm1hbCwgbGVhZGluZyB0bzoNCg0KKiBJbmZsYXRlZCBDaGktc3F1YXJlICgkXGNoaV4yJCkgdGVzdCBzdGF0aXN0aWNzLg0KKiBCaWFzZWQgc3RhbmRhcmQgZXJyb3JzLg0KKiBJbmNvcnJlY3QgbW9kZWwgZml0IGluZGljZXMgXGNpdGVwe0Zpbm5leTIwMDF9Lg0KDQoNCiMjIyBDb21wdXRhdGlvbmFsIFByb2NlZHVyZQ0KDQpUaGUgV0xTTVYgZXN0aW1hdG9yIGlzIHBhcnQgb2YgYSBmYW1pbHkgb2YgZGlhZ29uYWxseSB3ZWlnaHRlZCBsZWFzdCBzcXVhcmVzIChEV0xTKSBlc3RpbWF0b3JzLiBJdHMgY29tcHV0YXRpb24gaW52b2x2ZXMgYSBzcGVjaWZpYyBzZXF1ZW5jZSBvZiBzdGVwcyB0byBoYW5kbGUgdGhlIGNhdGVnb3JpY2FsIG5hdHVyZSBvZiB0aGUgZGF0YS4NCg0KKipTdGVwIDE6IEVzdGltYXRpb24gb2YgUG9seWNob3JpYyBDb3JyZWxhdGlvbnMqKg0KDQpTaW5jZSB0aGUgb3JkaW5hbCBjYXRlZ29yaWVzIGFyZSBtYW5pZmVzdGF0aW9ucyBvZiBhbiBhc3N1bWVkIGNvbnRpbnVvdXMsIGxhdGVudCByZXNwb25zZSBkaXN0cmlidXRpb24gdW5kZXJseWluZyBlYWNoIGl0ZW0sIHRoZSBmaXJzdCBzdGVwIGludm9sdmVzIGVzdGltYXRpbmcgdGhlICoqcG9seWNob3JpYyBjb3JyZWxhdGlvbioqIG1hdHJpeC4gQSBwb2x5Y2hvcmljIGNvcnJlbGF0aW9uIGVzdGltYXRlcyB0aGUgbGluZWFyIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHR3byBhc3N1bWVkIGNvbnRpbnVvdXMgbGF0ZW50IHJlc3BvbnNlIHZhcmlhYmxlcyBiYXNlZCBvbiB0aGUgb2JzZXJ2ZWQgb3JkaW5hbCBkYXRhIChPbHNzb24sIDE5NzkpLiBGb3IgZWFjaCBwYWlyIG9mIGl0ZW1zLCBhIHR3by1zdGVwIHRocmVzaG9sZCBlc3RpbWF0aW9uIGlzIHBlcmZvcm1lZCwgZm9sbG93ZWQgYnkgdGhlIGVzdGltYXRpb24gb2YgdGhlaXIgY29ycmVsYXRpb24uDQoNCioqU3RlcCAyOiBFc3RpbWF0aW9uIG9mIHRoZSBBc3ltcHRvdGljIENvdmFyaWFuY2UgTWF0cml4KioNCg0KVGhlIG5leHQgc3RlcCBpcyB0byBjb21wdXRlIHRoZSBmdWxsICoqYXN5bXB0b3RpYyBjb3ZhcmlhbmNlIG1hdHJpeCoqIG9mIHRoZSAqcG9seWNob3JpYyBjb3JyZWxhdGlvbiBjb2VmZmljaWVudHMqLiBUaGlzIG1hdHJpeCBjb250YWlucyB0aGUgdmFyaWFuY2VzIGFuZCBjb3ZhcmlhbmNlcyBvZiB0aGUgZXN0aW1hdGVkICpwb2x5Y2hvcmljIGNvcnJlbGF0aW9ucyouIEl0IGlzIGEgbGFyZ2UgbWF0cml4IG9mIGRpbWVuc2lvbiAkcF4qKHBeKi0xKS8yJCAod2hlcmUgJHAkIGlzIHRoZSBudW1iZXIgb2YgaXRlbXMpIGFuZCBhY2NvdW50cyBmb3IgdGhlIHByZWNpc2lvbiBvZiBlYWNoIGNvcnJlbGF0aW9uIGVzdGltYXRlLiBUaGlzIG1hdHJpeCBpcyB1c2VkIGFzIHRoZSB3ZWlnaHQgbWF0cml4IGluIHRoZSBmaXR0aW5nIGZ1bmN0aW9uIChNdXRoZW4sIDE5ODQpLg0KDQoqKlN0ZXAgMzogVGhlIEZpdHRpbmcgRnVuY3Rpb24gYW5kIE1lYW4tVmFyaWFuY2UgQWRqdXN0bWVudCoqDQoNClRoZSBwYXJhbWV0ZXIgZXN0aW1hdGVzIGFyZSBvYnRhaW5lZCBieSBtaW5pbWl6aW5nIHRoZSBEV0xTIGZpdHRpbmcgZnVuY3Rpb246DQoNCiQkDQpGX3tcdGV4dHtEV0xTfX0gPSAoXG1hdGhiZntzfSAtIFxib2xkc3ltYm9se1xzaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkpJyBcbWF0aGJme1d9XnstMX0gKFxtYXRoYmZ7c30gLSBcYm9sZHN5bWJvbHtcc2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pKQ0KJCQNCg0Kd2hlcmUgJFxtYXRoYmZ7c30kIGlzIHRoZSB2ZWN0b3Igb2YgZXN0aW1hdGVkIHBvbHljaG9yaWMgY29ycmVsYXRpb25zLCAkXGJvbGRzeW1ib2x7XHNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KSQgaXMgdGhlIHZlY3RvciBvZiBtb2RlbC1pbXBsaWVkIGNvcnJlbGF0aW9ucywgYW5kICRcbWF0aGJme1d9XnstMX0kIGlzIHRoZSAqKmRpYWdvbmFsKiogb2YgdGhlIGludmVyc2Ugb2YgdGhlIGFzeW1wdG90aWMgY292YXJpYW5jZSBtYXRyaXggZnJvbSBTdGVwIDIuIFVzaW5nIG9ubHkgdGhlIGRpYWdvbmFsIG1ha2VzIHRoZSBjb21wdXRhdGlvbiBtb3JlIHN0YWJsZSBhbmQgZmVhc2libGUgd2l0aCBzbWFsbGVyIHNhbXBsZSBzaXplcyBjb21wYXJlZCB0byB0aGUgZnVsbCBXTFMgZXN0aW1hdG9yIHdoaWNoIHVzZXMgdGhlIGZ1bGwgbWF0cml4Lg0KDQpUaGUgIk1lYW4gYW5kIFZhcmlhbmNlIiBhZGp1c3RtZW50IChNVikgaXMgdGhlIGNydWNpYWwgZmluYWwgc3RlcCB0aGF0IG1ha2VzIFdMU01WIHN1cGVyaW9yIHRvIHBsYWluIFdMUyBvciBEV0xTLiBJbnN0ZWFkIG9mIHVzaW5nIHRoZSAkXGNoaV4yJCBzdGF0aXN0aWMgYW5kIHN0YW5kYXJkIGVycm9ycyBkZXJpdmVkIGRpcmVjdGx5IGZyb20gdGhlIERXTFMgZml0dGluZyBmdW5jdGlvbiwgV0xTTVYgYXBwbGllcyBhIGNvcnJlY3Rpb246DQoNCiogVGhlIHRlc3Qgc3RhdGlzdGljIGlzIHNjYWxlZCAobWVhbi1hZGp1c3RlZCkgYW5kIHNoaWZ0ZWQgKHZhcmlhbmNlLWFkanVzdGVkKSB0byBtb3JlIGNsb3NlbHkgYXBwcm94aW1hdGUgYSBjZW50cmFsICRcY2hpXjIkIGRpc3RyaWJ1dGlvbi4NCiogU3RhbmRhcmQgZXJyb3JzIGZvciBwYXJhbWV0ZXIgZXN0aW1hdGVzIGFyZSBjb21wdXRlZCB1c2luZyBhIHJvYnVzdCBtZXRob2QgKGUuZy4sIHRoZSBzYW5kd2ljaCBlc3RpbWF0b3IpIHRoYXQgZG9lcyBub3QgcmVseSBvbiB0aGUgYXNzdW1wdGlvbiBvZiBjb3JyZWN0IG1vZGVsIHNwZWNpZmljYXRpb24gKEFzcGFyb3Vob3YsIDIwMDUpLg0KDQoNClRoaXMgYWRqdXN0bWVudCBtYWtlcyB0aGUgV0xTTVYgZXN0aW1hdG9yIGZhciBtb3JlIHJvYnVzdCBpbiBzbWFsbCB0byBtb2RlcmF0ZSBzYW1wbGUgc2l6ZXMgYW5kIHdpdGggbGFyZ2UgbW9kZWxzIHdoZXJlIHRoZSBhc3ltcHRvdGljIGFzc3VtcHRpb25zIG9mIHBsYWluIFdMUyBhcmUgbm90IG1ldC4NCg0KIyMjIEFkdmFudGFnZXMgZm9yIE11bHRpLUl0ZW0gTGlrZXJ0IERhdGENCg0KVGhlIFdMU01WIGVzdGltYXRvciBwcm92aWRlcyBzcGVjaWZpYyBhZHZhbnRhZ2VzIGZvciBtb2RlbGluZyBtdWx0aS1pdGVtIExpa2VydCBzY2FsZSBkYXRhOg0KDQoqICoqUmVhbGlzdGljIEFzc3VtcHRpb25zKio6IEl0IGRvZXMgbm90IGFzc3VtZSBjb250aW51b3VzIG5vcm1hbGl0eSBmb3IgdGhlIG9ic2VydmVkIExpa2VydCBpdGVtcywgaW5zdGVhZCBsZXZlcmFnaW5nIHRoZSB1bmRlcmx5aW5nIGNvbnRpbnVvdXMgdmFyaWFibGUgZm9ybXVsYXRpb24uDQoqICoqQWNjdXJhY3kqKjogSXQgZ2VuZXJhbGx5IHByb2R1Y2VzIHRoZSBtb3N0IGFjY3VyYXRlIHBhcmFtZXRlciBlc3RpbWF0ZXMsIG1vZGVsIGZpdCBzdGF0aXN0aWNzLCBhbmQgc3RhbmRhcmQgZXJyb3JzIGZvciBvcmRpbmFsIGRhdGEgY29tcGFyZWQgdG8gTUwgd2l0aCBhIHJvYnVzdCBjb3JyZWN0aW9uIG9yIHBsYWluIERXTFMgKExpLCAyMDE2KS4NCiogKipFZmZpY2llbmN5IHdpdGggQ29tbW9uIFNjYWxlcyoqOiBJdCBwZXJmb3JtcyB3ZWxsIHdpdGggdGhlIHR5cGljYWwgNS0gdG8gNy1wb2ludCBMaWtlcnQgc2NhbGVzIHViaXF1aXRvdXMgaW4gcHN5Y2hvbG9naWNhbCBhbmQgc3VydmV5IHJlc2VhcmNoLg0KKiAqKlJvYnVzdG5lc3MgdG8gU2FtcGxlIFNpemUqKjogV2hpbGUgbGFyZ2VyIHNhbXBsZXMgYXJlIGFsd2F5cyBwcmVmZXJhYmxlLCBXTFNNViBwZXJmb3JtcyBhZGVxdWF0ZWx5IHdpdGggc21hbGxlciBzYW1wbGVzIChlLmcuLCAkTiA+IDIwMCQpIHRoYW4gd2hhdCBpcyByZXF1aXJlZCBmb3IgdGhlIGZ1bGwgV0xTIGVzdGltYXRvciAoQmFuZGFsb3MsIDIwMTQpLg0KDQoNCkluIGNvbmNsdXNpb24sIFdMU01WIGlzIGEgcm9idXN0LCBkaWFnb25hbGx5IHdlaWdodGVkIGxlYXN0IHNxdWFyZXMgZXN0aW1hdG9yIHRoYXQgdXNlcyBhIHBvbHljaG9yaWMgY29ycmVsYXRpb24gbWF0cml4IGFuZCBhcHBsaWVzIGEgbWVhbi0gYW5kIHZhcmlhbmNlLWFkanVzdG1lbnQgdG8gdGhlIHRlc3Qgc3RhdGlzdGljcyBhbmQgc3RhbmRhcmQgZXJyb3JzLCBtYWtpbmcgaXQgdGhlIGdvbGQtc3RhbmRhcmQgY2hvaWNlIGZvciBTRU0gd2l0aCBvcmRpbmFsIG11bHRpLWl0ZW0gTGlrZXJ0IGRhdGEuDQoNCg0KIyMgU3VydmV5IEluc3RydW1lbnRzDQoNCiMjIyBBYmJyZXZpYXRlZCBNYXRoIEFueGlldHkgU2NhbGUgKEFNQVMpDQoNClBsZWFzZSByYXRlIHlvdXIgZmVlbGluZ3MgZHVyaW5nIGRpZmZlcmVudCBhY3Rpdml0aWVzIG9uIGEgc2NhbGUgZnJvbSAxIHRvIDUuIFRyeSBub3QgdG8gc3BlbmQgdG9vIG11Y2ggdGltZSBvbiBhbnkgb25lIGl0ZW0uIFRoZXJlIGFyZSBubyByaWdodCBvciB3cm9uZyBhbnN3ZXJzLg0KDQpgMSA9IE5vIGJhZCBmZWVsaW5ncywgIDIgPSBTb21ld2hhdCBiYWQsICAzID0gbmVydm91cywgNCA9IFZlcnkgYmFkIGZlZWxpbmdzLCA1ID0gV29yc3QgZmVlbGluZ3NgDQoNClwNCg0KMS4JSGF2aW5nIHRvIHVzZSB0YWJsZXMgaW4gdGhlIGJhY2sgb2YgYSBtYXRoIGJvb2suDQoNCjIuCVRoaW5raW5nIGFib3V0IGEgbWF0aCB0ZXN0IHRoZSBkYXkgYmVmb3JlIHlvdSB0YWtlIGl0Lg0KDQozLglXYXRjaGluZyB0aGUgdGVhY2hlciB3b3JrIG91dCBhIG1hdGggcHJvYmxlbSBvbiB0aGUgYm9hcmQuDQoNCjQuCVRha2luZyBhIG1hdGggdGVzdC4NCg0KNS4JQmVpbmcgZ2l2ZW4gYSBob21ld29yayBhc3NpZ25tZW50IG9mIG1hbnkgZGlmZmljdWx0IHByb2JsZW1zIHRoYXQgaXMgZHVlIGZvciB0aGUgbmV4dCBjbGFzcyBtZWV0aW5nLiANCg0KNi4JTGlzdGVuaW5nIHRvIGEgbGVjdHVyZSBpbiBtYXRoIGNsYXNzLiBbTGlzdGVuaW5nIHRvIHRoZSB0ZWFjaGVyIHRhbGsgZm9yIGEgbG9uZyB0aW1lIGluIG1hdGhdIA0KDQo3LglMaXN0ZW5pbmcgdG8gYW5vdGhlciBzdHVkZW50IGV4cGxhaW4gaG93IHRvIGRvIGEgbWF0aCBwcm9ibGVtLiANCg0KOC4JQmVpbmcgZ2l2ZW4gYSBxdWl6IG9uIG1hdGggd2l0aG91dCBrbm93aW5nIGluIGFkdmFuY2UuIA0KDQo5LglTdGFydGluZyBhIG5ldyBjaGFwdGVyIGluIGEgbWF0aCBib29rLiBbU3RhcnRpbmcgYSBuZXcgdG9waWMgaW4gbWF0aF0NCg0KIyMjIE1hdGggU2VsZi1lZmZpY2FjeSBTY2FsZQ0KDQpTZWxlY3QgdGhlIHJlc3BvbnNlIHRoYXQgbWF0Y2hlcyBob3cgbXVjaCB5b3Ugbm93IGFncmVlIHdpdGggZWFjaCBzdGF0ZW1lbnQuIFRyeSBub3QgdG8gc3BlbmQgdG9vIG11Y2ggdGltZSBvbiBhbnkgb25lIGl0ZW0uIFRoZXJlIGFyZSBubyByaWdodCBvciB3cm9uZyBhbnN3ZXJzLg0KDQpgMSA9IFN0cm9uZ2x5IGRpc2FncmVlCTIgPSBkaXNhZ3JlZQkzID0gbmV1dHJhbAk0ID0gYWdyZWUJNSA9IFN0cm9uZ2x5IGFncmVlYA0KDQpcDQoNCjEuCUkgdXN1YWxseSB1bmRlcnN0YW5kIGEgbWF0aGVtYXRpY2FsIGlkZWEgcXVpY2tseS4NCg0KMi4JSSBoYXZlIHRvIHdvcmsgdmVyeSBoYXJkIHRvIHVuZGVyc3RhbmQgbWF0aGVtYXRpY3MuICAgIA0KDQozLglJIGNhbiBjb25uZWN0IHRoZSBtYXRoZW1hdGljYWwgaWRlYXMgdGhhdCBJIGhhdmUgbGVhcm5lZC4NCg0KDQojIyMgVGVhY2hpbmcgU3RyYXRlZ2llcyBRdWVzdGlvbm5haXJlIA0KDQpUaGUgZm9sbG93aW5nIHN0YXRlbWVudHMgYXJlIHRoZSB3YXlzIHlvdXIgdGVhY2hlciB0ZWFjaGVzIG1hdGhlbWF0aWNzLiBSZXNwb25kIHRvIHRoZSBpdGVtcyBsaXN0ZWQgYmVsb3c6IA0KDQpgNSDigJMgQWx3YXlzLCA0IOKAkyBPZnRlbiwgIDMg4oCTIFNvbWV0aW1lcywgIDIg4oCTIFNlbGRvbSwgICAxIOKAkyBOZXZlcmANCg0KDQoqKkNvb3BlcmF0aXZlLUFwcHJvYWNoKioNCg0KMS4JVGhlIHRlYWNoZXIgZW5jb3VyYWdlcyBzdHVkZW50cyB0byB3b3JrIHdpdGggb3RoZXJzIHRvIGdlbmVyYXRlIGFzIG1hbnkgYWx0ZXJuYXRpdmVzIGFzIHRoZXkgY2FuIGZvciB0aGUgcHJvYmxlbSBkaXNjdXNzZWQuIA0KDQoyLglUaGUgdGVhY2hlciBnaXZlcyBzdHVkZW50cyBlbm91Z2ggdGltZSB0byB0aGluayBhbmQgdG8gaW52ZXN0aWdhdGUgd2l0aCBvdGhlcnMgdG8gYWNoaWV2ZSBhIGRlc2lyYWJsZSByZXN1bHQuDQoNCjMuCVRoZSB0ZWFjaGVyIGdpdmVzIHN0dWRlbnRzIGEgY2hhbmNlIHRvIGdlbmVyYXRlIG5ldyBjb25jZXB0cy4gDQoNCjQuCVRoZSB0ZWFjaGVyIGFwcGxpZXMgZ3JvdXAgd29yayBpbiB0aGUgY2xhc3MgdG8gc2VydmUgZGVzaXJlZCBvYmplY3RpdmVzLg0KDQo1LglUaGUgdGVhY2hlciBkaXN0cmlidXRlcyBkaWZmZXJlbnQgdGVhY2hpbmctbGVhcm5pbmcgdGFza3MgdG8gc3R1ZGVudHMuDQoNCjYuCVRoZSB0ZWFjaGVyIGxldHMgc3R1ZGVudHMgaGF2ZSB0aGVpciBvd24gY29udmVyc2F0aW9ucyBwb3NpdGl2ZWx5Lg0KDQoqKkxlY3R1cmUgVHlwZSoqDQoNCjEuCVRoZSB0ZWFjaGVyIHByb3ZpZGVzIHN0dWRlbnRzIHdpdGggZmVlZGJhY2sgcmVnYXJkaW5nIHRoZWlyIGFuc3dlcnMgYXQgYWxsIHRpbWVzLiANCg0KMi4JVGhlIHRlYWNoZXIgZW5kcyB0aGUgdGVhY2hpbmctbGVhcm5pbmcgc2l0dWF0aW9uIGJ5IGNsYXJpZnlpbmcgYW5kIGRpc2N1c3NpbmcgZGlhZ3JhbXMgc3VpdGFibGUgZm9yIHN0dWRlbnRzLiANCg0KMy4JVGhlIHRlYWNoZXIgdHJhaW5zIHN0dWRlbnRzIG9uIGdlbmVyYXRpbmcgc3BlY2lmaWMgYW5zd2VycyB0byB0aGUgcXVlc3Rpb25zIHJhaXNlZCB0byB0aGVtLiANCg0KNC4JVGVhY2hlcnMnIGNvZ25pdGl2ZSB0ZWFjaGluZyBzdHJhdGVnaWVzIGhhcm1vbml6ZSB3aXRoIHN0dWRlbnRzJyBsZWFybmluZyBzdHJhdGVnaWVzLiANCg0KNS4JVGhlIHRlYWNoZXIgYWxsb3dzIHN0dWRlbnRzIHRvIGhhdmUgbW9yZSBjbGFyaWZpY2F0aW9ucyBhbmQgZXhwbGFuYXRpb25zIG9uIGEgY2VydGFpbiB0b3BpYy4gDQoNCjYuCVRoZSB0ZWFjaGVyIHRyYWlucyBzdHVkZW50cyB0byBzb2x2ZSB0aGVpciBwcm9ibGVtcyBpbiBhIGNvbWZvcnRhYmxlIHdheS4gDQoNCjcuCVRoZSB0ZWFjaGVyIG1ha2VzIHN0dWRlbnRzIHRha2UgcGFydCBpbiBkaWZmZXJlbnQgcm9sZXMuDQoNCg0KKipEZWR1Y3RpdmUgQXBwcm9hY2gqKg0KDQoxLglUaGUgdGVhY2hlciB0cmFpbnMgc3R1ZGVudHMgdG8gZGV0ZXJtaW5lIHRoZSB3aG9sZSBpZGVhIG9mIHRoZSB0b3BpYy4gDQoNCjIuCVRoZSB0ZWFjaGVyIHByb3ZpZGVzIHN0dWRlbnRzIHdpdGggYSBjaGFuY2UgdG8gYXBwbHkgbmV3IGtub3dsZWRnZSBpbiBuZXcgcmVhbC1saWZlIHNpdHVhdGlvbnMuIA0KDQozLglUaGUgdGVhY2hlciB0cmFpbnMgc3R1ZGVudHMgb24gbGVhcm5pbmcgdGhlIHdob2xlIGNvbmNlcHQgYmVmb3JlIHRoZSBzcGVjaWZpYyBpZGVhLiANCg0KNC4JU3R1ZGVudHMgdGVuZCB0byBnZW5lcmF0ZSBuZXcgaW5mb3JtYXRpb24gYnkgbWFraW5nIGNvbXBhcmlzb25zIGJldHdlZW4gdGhlaXIgcHJldmlvdXMga25vd2xlZGdlIGFuZCB0aGUgbmV3IGluZm9ybWF0aW9uLiANCg0KNS4JVGhlIHRlYWNoZXIgbW92ZXMgZnJvbSB0aGUgYWJzdHJhY3QgdG8gdGhlIGNvbmNyZXRlIGV4YW1wbGVzLiANCg0KNi4JVGhlIHRlYWNoZXIgYXNrcyBzdHVkZW50cyB0byBkbyB3cml0dGVuIG9yIHZlcmJhbCBzdW1tYXJpZXMgb2YgdGhlIGluZm9ybWF0aW9uIHRoZXkgZ2V0LiANCg0KNy4JVGhlIHRlYWNoZXIgZGlzdHJpYnV0ZXMgZGlmZmVyZW50IHRlYWNoaW5nLWxlYXJuaW5nIHRhc2tzIHRvIHN0dWRlbnRzLiANCg0KDQoqKkluZHVjdGl2ZSBBcHByb2FjaCoqDQoNCjEuCVRoZSB0ZWFjaGVyIHVzZXMgc3BlY2lmaWMgcXVlc3Rpb25zIHRvIGRpc2N1c3MgdGhlIHdob2xlIHRvcGljLiANCg0KMi4JVGhlIHRlYWNoZXIgZGlzYXNzZW1ibGVzIHRoZSB0ZWFjaGluZy1sZWFybmluZyBtYXRlcmlhbCBpbnRvIHNwZWNpZmljIHRhc2tzIHRoYXQgbmVlZCBzcGVjaWZpYyByZXNwb25zZXMuDQoNCjMuCVRoZSB0ZWFjaGVyIHRyYWlucyBoaXMgc3R1ZGVudHMgb24gZGlzdGluZ3Vpc2hpbmcgYmV0d2VlbiBkaWZmZXJlbnQgY2hhcmFjdGVyaXN0aWNzIG9mIHRoZSBzYW1lIGNvbmNlcHQuIA0KDQo0LglUaGUgdGVhY2hlciBiZWdpbnMgYnkgcHJlc2VudGluZyB0aGUgbWFpbiBpZGVhcyBvZiB0aGUgdG9waWMgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgY2xhc3MuIA0KDQo1LglUaGUgdGVhY2hlciB1c2VzIHNwZWNpZmljIHByb2JsZW0tc29sdmluZyBzdHJhdGVnaWVzIGluIHRoZSB0ZWFjaGluZyBwcm9jZXNzLiANCg0KNi4JVGhlIHRlYWNoZXIgYXNzaWducyBzdHVkZW50cyBhIHNwZWNpZmljIHRhc2sgd2l0aGluIGEgZ2VuZXJhbCB0YXNrLiANCg0KNy4JVGhlIHRlYWNoZXIgaGVscHMgc3R1ZGVudHMgdG8gYW5hbHl6ZSB0aGUgbWFpbiBpZGVhIHRvIGJlIHVzZWQgaW4gZGlzY3Vzc2luZyB0aGUgdG9waWMgYXMgYSB3aG9sZS4gDQoNCg0KKipEZW1vbnN0cmF0aW9uKioNCg0KMS4JVGhlIHRlYWNoZXIgdXNlcyBkaXJlY3QgcHJlc2VudGF0aW9uIHRvIHByb3ZpZGUgc3R1ZGVudHMgd2l0aCBpbmZvcm1hdGlvbi4gDQoNCjIuCVRoZSB0ZWFjaGVyIGhlbHBzIGhpcyBzdHVkZW50cyBpbWl0YXRlIGRlc2lyZWQgbW9kZWxzIGJ5IHNob3dpbmcgdGhlbS4gDQoNCjMuCVRoZSB0ZWFjaGVyIGJlZ2lucyB0aGUgdGVhY2hpbmctbGVhcm5pbmcgc2l0dWF0aW9uIGJ5IHByZXNlbnRpbmcgYSBwcm9ibGVtIHRvIHN0dWRlbnRzLiANCg0KNC4JVGhlIHRlYWNoZXIgdHJhaW5zIHN0dWRlbnRzIHRvIHBsYW4sIG9ic2VydmUsIGFuZCBldmFsdWF0ZSB0aGVpciB0ZWFjaGluZyBhY3Rpdml0aWVzLiANCg0KNS4JVGhlIHRlYWNoZXIgc2hvd3Mgc3R1ZGVudHMgaG93IHRvIHZlcmlmeSBpbmZvcm1hdGlvbiBhbmQgZmFjdHMgYmVmb3JlIG1ha2luZyBqdWRnbWVudHMuIA0KDQo2LglUaGUgdGVhY2hlciBiZWdpbnMgd2l0aCBleGFtcGxlcyBvZiB0aGUgY29uY2VwdCBpbiB0aGUgdGVhY2hpbmctbGVhcm5pbmcgc2l0dWF0aW9uLiANCg0KNy4JVGhlIHRlYWNoZXIgdGVhY2hlcyBzdHVkZW50cyB0aGUgd2F5IHRvIGlkZW50aWZ5IHRob3NlIHNpbXBsZSB0cmlja3MgdG8gdW5kZXJzdGFuZCB0aGUgbGVzc29uLg0KDQoqKlJlcGV0aXRpdmUgRXhlcmNpc2VzKioNCg0KMS4JVGhlIHRlYWNoZXIgdGFrZXMgYWR2YW50YWdlIG9mIHByb3ZpZGluZyBkaWZmZXJlbnQgYWN0aXZpdGllcyB0byBzZWN1cmUgdGhlIHRlYWNoaW5nLWxlYXJuaW5nIHByb2Nlc3MuIA0KDQoyLglUaGUgdGVhY2hlciBjYXJlcyBhYm91dCBjb3JyZWN0aW5nIHN0dWRlbnRzIGJ5IHByb3ZpZGluZyBtYW55IHdvcmtzaGVldHMuIA0KDQozLglUaGUgdGVhY2hlciBnaXZlcyBzaW1pbGFyIGV4YW1wbGVzIGR1cmluZyB0aGUgZGlzY3Vzc2lvbiB0byBzZWN1cmUgdGhlIG1hc3Rlcnkgb2YgdGhlIHRvcGljLiANCg0KNC4JVGhlIHRlYWNoZXIgdGFrZXMgcGFydCBpbiB0cmFpbmluZyBzdHVkZW50cyBieSBwcm92aWRpbmcgZGlmZmVyZW50IGxlYXJuaW5nIGFjdGl2aXRpZXMuIA0KDQo1LglUaGUgdGVhY2hlciBoZWxwcyBzdHVkZW50cyBpZGVudGlmeSB0aGVpciBvd24gbWlzdGFrZXMgYnkgZG9pbmcgc2ltaWxhciB3b3Jrc2hlZXRzLiANCg0KNi4JVGhlIHRlYWNoZXIgZ2l2ZXMgc3R1ZGVudHMgdGhlIGNoYW5jZSB0byBjb3JyZWN0IHRoZWlyIG1pc3Rha2VzIGJ5IGFuc3dlcmluZyBzaW1pbGFyIHF1ZXN0aW9ucy4gDQoNCjcuCVRoZSB0ZWFjaGVyIHRyYWlucyBzdHVkZW50cyBieSBwcm92aWRpbmcgZGlmZmVyZW50IHNldHMgb2Ygd29ya3NoZWV0cy4gDQoNCg0KKipJbnRlZ3JhdGl2ZSBBcHByb2FjaCoqDQoNCjEuCVRoZSB0ZWFjaGVyIGF3YXJkcyBzdHVkZW50cyBmb3IgdGhlaXIgY29ycmVjdCBhbnN3ZXIuIA0KDQoyLglUZWFjaGVyIGRlcGVuZHMgb24gY3JpdGVyaWEgaW4gZXZhbHVhdGluZyB0aGVpciBzdHVkZW50cy4gDQoNCjMuCVRoZSB0ZWFjaGVyIG5lZ2xlY3RzIHVuZGVzaXJlZCBiZWhhdmlvcnMgaW4gdGVhY2hpbmctbGVhcm5pbmcgc2l0dWF0aW9ucy4gDQoNCjQuCVRoZSB0ZWFjaGVyIG1ha2VzIHVzZSBvZiBjb25jZXB0IG1hcHMgZHVyaW5nIHRoZSB0ZWFjaGluZy1sZWFybmluZyBwcm9jZXNzLiANCg0KNS4JVGhlIHRlYWNoZXIgZmFjaWxpdGF0ZXMgc3R1ZGVudHMgdG8gbWFrZSB1c2Ugb2YgdGhlIHByb2NlZHVyZXMgdGhhdCBvcmdhbml6ZSBtZW1vcnkgcG90ZW50aWFscyAoc3ltYm9saXppbmcgaW5mb3JtYXRpb24pLiANCg0KNi4JVGhlIHRlYWNoZXIgZ3VpZGVzIHN0dWRlbnRzIHRvIHJlZmVyZW5jZXMgc3VjaCBhcyBkaWN0aW9uYXJpZXMsIGVuY3ljbG9wZWRpYXMsIGludGVybmV0IHNpdGVzLCBldGMuIA0KDQo3LglUaGUgdGVhY2hlciBzdXBwb3J0cyBzdHVkZW50cyBpbiB1c2luZyBkaWZmZXJlbnQgbGVhcm5pbmcgdG9vbHMgZm9yIHRoZSBwdXJwb3NlIG9mIHRlYWNoaW5nIHRoZSBsZWFybmluZyBwcm9jZXNzLiANCg0KDQojIyMgVXNlIG9mIHRlY2hub2xvZ2llcyBTY2FsZQ0KDQpgMTogc3Ryb25nbHkgZGlzYWdyZWUsIDI6IGRpc2FncmVlLCAzLiBOZXV0cmFsLCA0IGFncmVlLCA1LiBTdHJvbmdseSBhZ3JlZWANCg0KXA0KDQoxLiBJIGZlZWwgYXBwcmVoZW5zaXZlIGFib3V0IHVzaW5nIGluZm9ybWF0aW9uIHRlY2hub2xvZ2llcyAoSVRzKQ0KDQoyLiBUZWNobm9sb2dpY2FsIGluZm9ybWF0aW9uIHNvdW5kcyBsaWtlIGNvbmZ1c2luZyBqYXJnb24gdG8gbWUNCg0KMy4gSSBoYXZlIGF2b2lkZWQgSVRzIGJlY2F1c2UgaXQgaXMgdW5mYW1pbGlhciB0byBtZQ0KDQo0LiBJIGhlc2l0YXRlIHRvIHVzZSBJVHMgZm9yIGZlYXIgb2YgbWFraW5nIG1pc3Rha2VzIEkgY2Fubm90IGNvcnJlY3QNCg0KNS4gSVRzIGRvIG5vdCBzY2FyZSBtZSBhdCBhbGwNCg0KNi4gV29ya2luZyB3aXRoIElUcyB3b3VsZCBtYWtlIG1lIHZlcnkgbmVydm91cw0KDQo3LiBJIGRvIG5vdCBmZWVsIHRocmVhdGVuZWQgd2hlbiBvdGhlcnMgdGFsayBhYm91dCBJVHMNCg0KOC4gSSBmZWVsIGFnZ3Jlc3NpdmUgYW5kIGhvc3RpbGUgdG93YXJkIElUcw0KDQo5LiBJVCBtYWtlcyBtZSBmZWVsIHVuY29tZm9ydGFibGUNCg0KMTAuIEkgZ2V0IGEgc2lua2luZyBmZWVsaW5nIHdoZW4gSSB0aGluayBvZiB0cnlpbmcgdG8gdXNlIElUcw0KDQoxMS4gSVQgbWFrZXMgbWUgZmVlbCB1bmVhc3kNCg0KMTIuIElUIG1ha2VzIG1lIGZlZWwgY29uZnVzZWQNCg0KIyMjIExlYXJuaW5nIG1vZGFsaXRpZXMNCg0KMS4JV2hlbiBJIGxpc3RlbiB0byBhIGNsYXNzIGxlY3R1cmXigKYgDQogIGEuIEkgbGlzdGVuIHZlcnkgY2xvc2VseS4gDQogIGIuIEkgdHJ5IHRvIGJlIGNsb3NlIHRvIHRoZSBzcGVha2VyIGFuZCB3YXRjaCB0aGUgc3BlYWtlci4gDQogIGMuIEkgdGFrZSBub3RlcyBkdXJpbmcgdGhlIGxlY3R1cmUuIA0KICANCjIuCUkgbGlrZSB0byBzb2x2ZSB3b3JkIHByb2JsZW1zIGJ54oCmIA0KICBhLiB0YWxraW5nIHRvIGEgZnJpZW5kIG9yIHRvIG15c2VsZi4gDQogIGIuIHVzaW5nIGFuIG9yZ2FuaXplZCBhcHByb2FjaCB3aXRoIGxpc3RzIG9yIGNoYXJ0cy4gDQogIGMuIHdhbGtpbmcsIHBhY2luZywgb3IgZG9pbmcgc29tZXRoaW5nIGFjdGl2ZS4gDQogIA0KMy4JV2hlbiBzb21lb25lIHRlbGxzIG1lIG51bWJlcnMsIGJ1dCBJIGFtIHVuYWJsZSB0byB3cml0ZSB0aGVtIGRvd24sIEnigKYgDQogIGEuIFJlcGVhdCB0aGUgbnVtYmVycyB0byBteXNlbGYgb3V0IGxvdWQuIA0KICBiLiB2aXN1YWxpemUgb3Igc2VlIHRoZSBudW1iZXJzIGluIG15IG1pbmQuIA0KICBjLiBXcml0ZSB0aGUgbnVtYmVycyBpbiB0aGUgYWlyIG9yIG9uIHRoZSB0YWJsZS4gDQogIA0KNC4JSSBsZWFybiBzb21ldGhpbmcgbmV3IGJ54oCmIA0KICBhLiBoYXZpbmcgc29tZW9uZSBleHBsYWluIGl0IHRvIG1lIHdoaWxlIEkgbGlzdGVuLiANCiAgYi4gaGF2aW5nIHNvbWVvbmUgZG8gaXQgZm9yIG1lIHdoaWxlIEkgd2F0Y2guIA0KICBjLiBkb2luZyBpdCBteXNlbGYuIA0KICANCjUuCVdoZW4gSSB3YXRjaCBhIG1vdmllLCBJIHJlbWVtYmVy4oCmIA0KICBhLiBldmVyeXRoaW5nICh3aGF0IHdhcyBzYWlkLCBtdXNpYywgYmFja2dyb3VuZCBub2lzZXMpLiANCiAgYi4gdGhlIGNvc3R1bWVzLCBlbnZpcm9ubWVudCwgYW5kIHNjZW5lcnkuIA0KICBjLiBob3cgaXQgbWFkZSBtZSBmZWVsLiANCiAgDQo2LglXaGVuIEkgYW0gdHJ5aW5nIHRvIHJlbWVtYmVyIHNvbWV0aGluZywgSeKApiANCiAgYS4gaGVhciB3aGF0IHdhcyBzYWlkIG9yIHdoYXQgc291bmRzIHdlcmUgYXJvdW5kIG1lLiANCiAgYi4gdmlzdWFsaXplIGl0IGhhcHBlbmluZyBhZ2FpbiBpbiBteSBtaW5kLiANCiAgYy4gZmVlbCB0aGUgd2F5IEkgZGlkIHdoZW4gaXQgaGFwcGVuZWQuIA0KICANCjcuCVdoZW4gSSBkbyBub3Qga25vdyBob3cgdG8gc3BlbGwgYSB3b3JkLCBJ4oCmIA0KICBhLiBzb3VuZCBpdCBvdXQuIA0KICBiLiBzZWUgdGhlIHdvcmQgaW4gbXkgbWluZC4gDQogIGMuIFdyaXRlIHRoZSB3b3JkIG9uIHBhcGVyIHVudGlsIGl0IGxvb2tzIHJpZ2h0Lg0KICANCjguCUkgZW5qb3kgcmVhZGluZyB3aGVuIHRoZSBzdG9yeSBoYXPigKYgDQogIGEuIGEgbG90IG9mIGRpYWxvZ3VlIChjaGFyYWN0ZXJzIHRhbGtpbmcgdG8gZWFjaCBvdGhlcikuIA0KICBiLiBhIGxvdCBvZiBkZXNjcmlwdGl2ZSB3b3Jkcy4gDQogIGMuIGEgbG90IG9mIGFjdGlvbi4gDQogIA0KOS4JSSByZW1lbWJlciBuZXcgcGVvcGxlIGJ54oCmIA0KICBhLiB0aGVpciBuYW1lcy4gDQogIGIuIHRoZWlyIGZhY2VzLiANCiAgYy4gdGhlaXIgYWN0aW9ucy4NCiAgDQoxMC4JSSBoYXZlIGEgaGFyZCB0aW1lIGNvbmNlbnRyYXRpbmcgd2hlbuKApiANCiAgYS4gVGhlcmUgaXMgYSBsb3Qgb2Ygbm9pc2UuIA0KICBiLiBUaGVyZSBhcmUgYSBsb3Qgb2YgcGVvcGxlLiANCiAgYy4gSSBhbSB1bmNvbWZvcnRhYmxlICh0b28gaG90LCB0b28gY29sZCwgdW5jb21mb3J0YWJsZSBjaGFpciwgZXRjLikuIA0KICANCjExLglXaGVuIGl0IGNvbWVzIHRvIGNsb3RoZXMsIEkgcHJlZmVyIHRvIGRyZXNz4oCmIA0KICBhLiBpbiBhbnkgd2F5LCBzaW5jZSBjbG90aGVzIGFyZSBub3QgdGhhdCBpbXBvcnRhbnQgdG8gbWUuIA0KICBiLiB3ZWxsIOKAkyBhbmQgSSBoYXZlIGEgcGFydGljdWxhciBzdHlsZS4gDQogIGMuIGNvbWZvcnRhYmx5LCBzbyBJIGNhbiBtb3ZlIGFyb3VuZCBlYXNpbHkuIA0KICANCjEyLglJZiBJIGNhbm5vdCByZWFkIGFsb3VkIG9yIGdldCB1cCBhbmQgbW92ZSBhcm91bmQsIEnigKYgDQogIGEuIFRhbGsgd2l0aCBhIGZyaWVuZC4gDQogIGIuIGxvb2sgb3V0IGEgd2luZG93LiANCiAgYy4gcm9jayBpbiBteSBjaGFpciwgdGFwIG15IGZvb3QsIGRydW0gbXkgZmluZ2Vycywgb3IgamlnZ2xlIG15IHBlbmNpbC4NCg0KIyMjIEVuZ2FnZW1lbnQgYW5kIFJlc291cmNlcw0KDQpEdXJpbmcgdGhlIGN1cnJlbnQgc2Nob29sIHllYXIgYXQgc2Nob29sLCBob3cgb2Z0ZW4gaGF2ZSB5b3UgZG9uZSB0aGUgZm9sbG93aW5nOg0KYDEgLSBWZXJ5IG9mdGVuLCAyIC0gT2Z0ZW4sIDMgLSBTb21ldGltZXMsIDQg4oCTIE5ldmVyYA0KDQoqKkVuZ2FnZW1lbnQqKiANCg0KMS4gQXNrZWQgcXVlc3Rpb25zIGluIGNsYXNzLiANCg0KMi4gQW5zd2VyZWQgcXVlc3Rpb25zIGZyb20gcHJvZmVzc29ycyBvciBwZWVycyBpbiBjbGFzcy4NCg0KMy4gQ29udHJpYnV0ZWQgdG8gY2xhc3Mgb3IgZ3JvdXAgZGlzY3Vzc2lvbnMuIA0KDQo0LiBQcmFjdGljZSBleGVyY2lzZXMvZXhhbXBsZXMuDQoNCjUuIFRvb2sgZGV0YWlsZWQgY2xhc3Mgbm90ZXMuDQoNCjYuIFByZXZpZXdlZCB0aGUgY29udGVudCBiZWZvcmUgY2xhc3MuDQoNCjcuIFJldmlld2VkIGNsYXNzIG5vdGVzIGFuZCBvdGhlciByZWNvbW1lbmRlZCBleGVyY2lzZXMNCg0KOC4gV29ya2VkIHdpdGggb3RoZXIgc3R1ZGVudHMgb24gdGhlIGNvdXJzZSBtYXRlcmlhbHMuIA0KDQoqKlVzZSBvZiBSZXNvdXJjZXMqKg0KDQo5LiBHb3QgaGVscCBmcm9tIHByb2Zlc3NvcnMgdmlhIGVtYWlsLg0KDQoxMC4gV2VudCB0byB0aGUgcHJvZmVzc29y4oCZcyBpbi1wZXJzb24vWm9vbSBvZmZpY2UgaG91cnMuIA0KDQoxMS4gVXNlZCBmcmVlIHBlZXIgdHV0b3JpbmcgdGhyb3VnaCB0aGUgTWF0aCBMZWFybmluZyBDZW50ZXIgDQoNCjEyLiBVc2VkIHByaXZhdGUgdHV0b3Jpbmcgc2VydmljZXMuDQoNCg==