Project Background and Objective

Walmart’s senior management suspects that overall sales performance is driven by a limited number of stores, while sales volatility may originate from a different subset of locations. At the same time, the CEO is uncertain whether observed weekly fluctuations can be systematically explained by holiday effects and macroeconomic conditions, or whether they reflect random noise.

The objective of this project is to translate these managerial concerns into data-driven insights using exploratory analysis, regression modeling, and clustering techniques. The ultimate goal is to provide actionable recommendations rather than purely statistical results.

1 Research Questions

The dataset and project brief provide a wide range of potential analytical questions related to sales performance, volatility, holidays, and macroeconomic conditions. To maintain analytical focus and managerial relevance, this study deliberately narrows the scope to a small set of interconnected research questions. These questions are selected based on (i) the CEO’s stated concerns, (ii) feasibility given the available data, and (iii) their ability to support actionable insights rather than purely descriptive findings.

The final research questions guiding this analysis are as follows:

RQ1: Sales Concentration and Volatility
Which stores contribute disproportionately to Walmart’s total sales, and which stores contribute disproportionately to sales volatility?

RQ2: Holiday Effects Beyond a Binary Indicator
How do holiday periods affect weekly sales levels and volatility, and to what extent does a simple holiday flag capture the true heterogeneity of holiday-driven demand?

RQ3: Drivers of Weekly Sales Performance
To what extent can weekly sales variation be explained by holidays, time structure (trend and seasonality), and macroeconomic conditions?

RQ4: Store Segmentation for Managerial Action
Can Walmart stores be segmented into meaningful groups based on sales level, volatility, and holiday sensitivity, and how can these segments inform differentiated managerial strategies?

Together, these research questions structure the analysis from descriptive diagnosis (RQ1), to causal explanation (RQ2–RQ3), and finally to prescriptive insight (RQ4). This progression ensures that the analysis remains both analytically rigorous and managerially relevant.

2 STEP 1 — Data Import & Data Understanding

2.1 Data Import

This step ensures that the dataset is successfully loaded and that the column names and first observations match expectations.

# ------------------------------------------------
# STEP 1.1 – Import Walmart Dataset
# ------------------------------------------------

# The Excel file should be uploaded to Posit Cloud
# and located in the same folder as this RMD file

walmart_raw <- read_excel("WalmartData.xlsx", sheet = "in")

# First look at the data
head(walmart_raw)

2.2 Data Structure & Variable Types

walmart <- walmart_raw %>%
  mutate(
    # Convert these columns explicitly to numeric
    Weekly_Sales = as.numeric(gsub(",", ".", Weekly_Sales)),
    Temperature  = as.numeric(gsub(",", ".", Temperature)),
    Fuel_Price   = as.numeric(gsub(",", ".", Fuel_Price)),
    CPI          = as.numeric(gsub(",", ".", CPI)),
    Unemployment = as.numeric(gsub(",", ".", Unemployment)),
    Holiday_Flag = as.integer(Holiday_Flag),
    Store        = as.integer(Store)
  )

glimpse(walmart)
## Rows: 6,435
## Columns: 8
## $ Store        <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
## $ Date         <chr> "05-02-2010", "12-02-2010", "19-02-2010", "26-02-2010", "…
## $ Weekly_Sales <dbl> 1643691, 1641957, 1611968, 1409728, 1554807, 1439542, 147…
## $ Holiday_Flag <int> 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
## $ Temperature  <dbl> 42.31, 38.51, 39.93, 46.63, 46.50, 57.79, 54.58, 51.45, 6…
## $ Fuel_Price   <dbl> 2.572, 2.548, 2.514, 2.561, 2.625, 2.667, 2.720, 2.732, 2…
## $ CPI          <dbl> 211.0964, 211.2422, 211.2891, 211.3196, 211.3501, 211.380…
## $ Unemployment <dbl> 8.106, 8.106, 8.106, 8.106, 8.106, 8.106, 8.106, 8.106, 7…

2.3 Descriptive Statistics

summary(walmart_raw)
##     Store               Date           Weekly_Sales       Holiday_Flag      
##  Length:6435        Length:6435        Length:6435        Length:6435       
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##  Temperature         Fuel_Price            CPI            Unemployment      
##  Length:6435        Length:6435        Length:6435        Length:6435       
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character

As a result of the initial data audit, the dataset requires preprocessing to ensure correct variable types. This step is necessary to produce valid descriptive insights and reliable statistical models.

2.4 Missing Values Check

The missing values analysis indicates that there are no missing observations across all variables in the dataset. Each column, including sales, holiday indicators, and macroeconomic variables, contains complete information for all time periods and stores. This is a strong advantage for the analysis, as it eliminates the need for imputation or row removal strategies that could otherwise introduce bias or reduce statistical power. Consequently, subsequent exploratory and modeling steps can be conducted on the full dataset without concerns related to data incompleteness.

# ------------------------------------------------
# STEP 1.4 – Missing values
# ------------------------------------------------

missing_summary <- walmart %>%
  summarise(across(everything(), ~ sum(is.na(.))))

missing_summary

2.5 Date Conversion & Feature Engineering

Time effects (trend, seasonality, holidays) cannot be analyzed unless dates are correctly formatted.

# ------------------------------------------------
# STEP 1.5 – Date handling and time variables
# ------------------------------------------------

walmart <- walmart %>%
  mutate(
    Date  = dmy(Date),              # convert text to Date
    Year  = year(Date),
    Month = month(Date, label = TRUE)
  )

summary(walmart$Date)
##         Min.      1st Qu.       Median         Mean      3rd Qu.         Max. 
## "2010-02-05" "2010-10-08" "2011-06-17" "2011-06-17" "2012-02-24" "2012-10-26"

After the data type conversion, all key variables are correctly formatted. Weekly sales and macroeconomic variables are stored as numeric values, the store identifier is an integer, and the date variable has been successfully parsed. This confirms that the dataset is now suitable for aggregation, visualization, and statistical modeling.

3 STEP 2 — Exploratory Analysis: Store Concentration & Volatility

Purpose of Step 2 To empirically test the CEO’s intuition that:

  • a small number of stores drive total sales

  • a different subset drives sales volatility

This step is descriptive but strategic — it defines where to look next.

3.1 Store-Level Sales and Volatility Metrics

# ------------------------------------------------
# STEP 2.1 – Store-level performance metrics
# ------------------------------------------------

# ------------------------------------------------
# Fix: Convert numeric-looking text columns to numeric
# ------------------------------------------------




store_summary <- walmart %>%
  group_by(Store) %>%
  summarise(
    avg_weekly_sales = mean(Weekly_Sales, na.rm = TRUE),
    total_sales      = sum(Weekly_Sales, na.rm = TRUE),
    sd_sales         = sd(Weekly_Sales, na.rm = TRUE),
    cv_sales         = sd_sales / avg_weekly_sales,  # relative volatility
    .groups = "drop"
  ) %>%
  mutate(
    sales_share = total_sales / sum(total_sales),
    volatility_share = sd_sales / sum(sd_sales)
  )

# Inspect top stores
store_summary %>% arrange(desc(total_sales)) %>% head(10)

The store-level summary statistics reveal substantial heterogeneity in performance across Walmart locations. The top-selling stores generate average weekly sales exceeding 2 million, while their coefficients of variation range between approximately 0.10 and 0.16. This indicates that even among the highest-revenue stores, relative sales stability differs meaningfully. Some large stores combine high sales with relatively stable demand, whereas others experience considerable week-to-week fluctuations despite similar revenue levels.

3.2 Sales Concentration: Do a Few Stores Dominate Revenue?

# ------------------------------------------------
# STEP 2.2 – Sales concentration plot
# ------------------------------------------------

top_sales <- store_summary %>%
  arrange(desc(total_sales)) %>%
  mutate(rank = row_number())

ggplot(top_sales, aes(x = rank, y = sales_share)) +
  geom_col() +
  scale_y_continuous(labels = percent_format(accuracy = 1)) +
  labs(
    title = "Store Ranking by Share of Total Sales",
    x = "Store Rank (1 = Highest Total Sales)",
    y = "Share of Total Sales"
  )

The sales concentration analysis shows a pronounced skew in revenue contribution across stores. The highest-ranked stores each account for roughly 4–4.5% of total sales, while the sales share declines steadily across lower-ranked locations. This pattern confirms that Walmart’s overall revenue is not evenly distributed, but instead depends heavily on a relatively small group of high-performing stores. Consequently, changes in performance at these top locations are likely to have a disproportionate impact on total company sales.

3.3 Volatility Concentration: Who Drives Weekly Instability?

# ------------------------------------------------
# STEP 2.3 – Volatility concentration plot
# ------------------------------------------------

top_volatility <- store_summary %>%
  arrange(desc(sd_sales)) %>%
  mutate(rank = row_number())

ggplot(top_volatility, aes(x = rank, y = volatility_share)) +
  geom_col() +
  scale_y_continuous(labels = percent_format(accuracy = 1)) +
  labs(
    title = "Store Ranking by Share of Sales Volatility",
    x = "Store Rank (1 = Most Volatile)",
    y = "Share of Total Volatility"
  )

A similar but distinct concentration pattern emerges when examining sales volatility. A limited number of stores contribute a disproportionately large share of total sales volatility, with the most volatile stores accounting for nearly 5% each. Importantly, volatility declines gradually across the ranking, indicating that instability is concentrated rather than widespread. This suggests that Walmart’s week-to-week sales fluctuations are primarily driven by specific locations rather than by uniform, chain-wide shocks.

3.4 Are High-Sales Stores Also High-Volatility Stores?

# ------------------------------------------------
# STEP 2.4 – Sales rank vs volatility rank
# ------------------------------------------------

store_ranks <- store_summary %>%
  mutate(
    sales_rank = rank(-total_sales, ties.method = "first"),
    vol_rank   = rank(-sd_sales, ties.method = "first")
  )

ggplot(store_ranks, aes(x = sales_rank, y = vol_rank)) +
  geom_point() +
  labs(
    title = "Relationship Between Sales Rank and Volatility Rank",
    x = "Sales Rank (1 = Highest Sales)",
    y = "Volatility Rank (1 = Highest Volatility)"
  )

The comparison between sales rank and volatility rank indicates that high-revenue stores are not systematically the most volatile. While some high-sales locations also exhibit high volatility, many top-selling stores display moderate or low volatility rankings. Conversely, several lower-ranked sales stores appear among the most volatile. This dispersion suggests the presence of distinct store roles within the network, separating revenue-driving locations from volatility-driving ones.

3.5 Step 2 Summary

Overall, the exploratory analysis confirms that Walmart’s sales and volatility are both highly concentrated but not perfectly aligned across stores. A small number of locations drive a large share of total revenue, while a partially different subset drives sales instability. These findings validate the CEO’s initial intuition and demonstrate that aggregate metrics mask important store-level dynamics. As a result, subsequent analyses should focus on identifying the drivers of volatility and sales at a more granular level, particularly examining the role of holidays and temporal effects.

4 STEP 3 — Holiday Analysis

In Step 2, we showed that sales and volatility are concentrated in specific stores. However, store-level patterns alone do not explain why weekly sales fluctuate. One frequently cited explanation is the effect of holidays. While the dataset provides a binary holiday indicator (Holiday_Flag), relying solely on a 0/1 variable may oversimplify the underlying dynamics. Therefore, this step examines holiday effects in a structured but focused manner, without losing sight of the broader analytical objective.

4.1 Holiday vs Non-Holiday: Average Sales Comparison

What we do

We first compare average weekly sales during holiday weeks versus non-holiday weeks. This provides an intuitive benchmark for understanding whether holidays matter at all.

# ------------------------------------------------
# STEP 3.1 – Average sales: Holiday vs Non-Holiday
# ------------------------------------------------

holiday_sales_summary <- walmart %>%
  group_by(Holiday_Flag) %>%
  summarise(
    avg_weekly_sales = mean(Weekly_Sales, na.rm = TRUE),
    sd_weekly_sales  = sd(Weekly_Sales, na.rm = TRUE),
    n_weeks = n(),
    .groups = "drop"
  )

holiday_sales_summary

The comparison of average weekly sales indicates that holiday weeks are associated with a different sales level than non-holiday weeks. The difference in mean sales suggests that holidays are not neutral periods and may systematically shift consumer purchasing behavior. However, this aggregate comparison does not yet indicate whether the observed difference is large enough to be economically meaningful or consistent across stores. “Holiday effect var gibi görünüyor” ama tek başına yeterli değil.

4.2 Visual Comparison: Sales Distribution

Why visualization matters

Averages can hide variability. Therefore, we compare the distribution of weekly sales during holiday and non-holiday weeks.

# ------------------------------------------------
# STEP 3.2 – Sales distribution by holiday status
# ------------------------------------------------

ggplot(walmart, aes(x = factor(Holiday_Flag), y = Weekly_Sales)) +
  geom_boxplot() +
  scale_y_continuous(labels = comma) +
  labs(
    title = "Weekly Sales Distribution: Holiday vs Non-Holiday Weeks",
    x = "Holiday Flag (0 = Non-Holiday, 1 = Holiday)",
    y = "Weekly Sales"
  )

The boxplot comparison shows that holiday weeks tend to shift the sales distribution upward relative to non-holiday weeks. At the same time, the wider spread during holiday periods indicates increased dispersion, suggesting that holidays may amplify not only sales levels but also sales uncertainty. This observation reinforces the need to examine volatility effects in addition to average sales differences.

4.3 Holiday Lift: How Large Is the Effect?

What is “holiday lift”?

Holiday lift measures the percentage difference in average sales between holiday and non-holiday weeks.

# ------------------------------------------------
# STEP 3.3 – Holiday lift calculation
# ------------------------------------------------

holiday_lift <- holiday_sales_summary %>%
  summarise(
    holiday_lift_pct =
      (avg_weekly_sales[Holiday_Flag == 1] -
       avg_weekly_sales[Holiday_Flag == 0]) /
       avg_weekly_sales[Holiday_Flag == 0] * 100
  )

holiday_lift

The holiday lift calculation quantifies the magnitude of the holiday effect in percentage terms. This metric provides a more interpretable measure for managerial decision-making, as it translates raw sales differences into relative performance gains. A modest lift suggests that holidays play a secondary role, whereas a large lift would indicate that holiday-driven demand is a major contributor to overall sales performance. Holiday’i sadece “var/yok” demiyoruz → etki büyüklüğünü ölçüyoruz.

4.4 Holiday and Volatility

Why this matters

The CEO’s concern is not only about sales levels, but also about instability. We therefore compare volatility across holiday and non-holiday weeks.

# ------------------------------------------------
# STEP 3.4 – Volatility comparison
# ------------------------------------------------

holiday_volatility <- walmart %>%
  group_by(Holiday_Flag) %>%
  summarise(
    sd_weekly_sales = sd(Weekly_Sales, na.rm = TRUE),
    .groups = "drop"
  )

holiday_volatility

The volatility comparison reveals that holiday weeks are associated with a different level of sales variability compared to non-holiday periods. This suggests that holidays may contribute not only to higher average sales, but also to increased uncertainty in weekly performance. Such a pattern is consistent with demand spikes that are unevenly distributed across stores and product categories.

4.5 Zoom-in: Major Holiday Weeks (Black Friday–style Insight)

While the binary holiday flag captures whether a week is classified as a holiday, it does not distinguish between routine holidays and peak demand events such as major shopping periods. To better understand this limitation, we examine weekly sales patterns around the most prominent holiday periods.

ggplot(walmart, aes(x = Date, y = Weekly_Sales)) +
  geom_line(alpha = 0.3) +
  geom_point(
    data = walmart %>% filter(Holiday_Flag == 1),
    aes(x = Date, y = Weekly_Sales),
    color = "red",
    alpha = 0.6
  ) +
  scale_y_continuous(labels = comma) +
  labs(
    title = "Weekly Sales Over Time with Holiday Weeks Highlighted",
    x = "Date",
    y = "Weekly Sales"
  )

The time-series visualization reveals that holiday weeks are associated with noticeable sales spikes, but these spikes are not uniform across all holiday periods. While some holiday weeks correspond to exceptionally high sales levels, others remain close to the baseline observed during regular weeks. This heterogeneity indicates that the binary holiday indicator aggregates events with substantially different demand intensities. As a result, treating all holiday weeks as economically equivalent may obscure important variation in sales responses.

ggplot(
  walmart %>% filter(Holiday_Flag == 1),
  aes(x = Weekly_Sales)
) +
  geom_histogram(bins = 30, fill = "grey", color = "white") +
  scale_x_continuous(labels = comma) +
  labs(
    title = "Distribution of Weekly Sales During Holiday Weeks",
    x = "Weekly Sales",
    y = "Frequency"
  )

The distribution of weekly sales during holiday weeks is highly dispersed and right-skewed, with a long upper tail extending toward very high sales values. This pattern suggests that a subset of holiday periods generates disproportionately large sales outcomes, while many holiday weeks exhibit more moderate performance. Such dispersion reinforces the limitation of a simple holiday flag and highlights the need for models that can distinguish between routine holidays and peak demand events.

4.6 Step 3 Summary: What Holidays Explain — and What They Don’t

The extended holiday analysis demonstrates that holiday periods are generally associated with higher average sales and increased variability in weekly performance. However, the time-series and distributional evidence shows that holiday effects are highly heterogeneous: only a subset of holiday weeks generates extreme sales spikes, while others resemble non-holiday periods. This finding confirms that a binary holiday indicator provides an incomplete representation of holiday-driven demand. Consequently, while holidays play an important role in explaining sales fluctuations, they cannot fully account for observed patterns in sales concentration and volatility. This motivates the use of multivariate regression models that incorporate time trends, macroeconomic variables, and store-level heterogeneity to disentangle overlapping effects.

5 STEP 4 — Regression Analysis: What Drives Weekly Sales?

Steps 2 and 3 demonstrated that sales and volatility are unevenly distributed across stores and that holiday effects are heterogeneous. However, descriptive analysis alone cannot isolate the relative importance of holidays, time trends, and macroeconomic conditions. Therefore, this step employs regression models to quantify the drivers of weekly sales while controlling for overlapping effects. The objective is not prediction accuracy, but explanatory clarity for managerial decision-making.

5.1 Model 1 — Baseline: Holiday Effect Only

Why this model?

We begin with the simplest possible specification to establish a benchmark. This model answers the question: If we only consider whether a week is a holiday, how much does that explain sales?

# ------------------------------------------------
# STEP 4.1 – Model 1: Holiday only
# ------------------------------------------------

model_1 <- lm(Weekly_Sales ~ Holiday_Flag, data = walmart)

summary(model_1)
## 
## Call:
## lm(formula = Weekly_Sales ~ Holiday_Flag, data = walmart)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -907529 -493200  -85790  375499 2777430 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   1041256       7291 142.820  < 2e-16 ***
## Holiday_Flag    81632      27570   2.961  0.00308 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 564000 on 6433 degrees of freedom
## Multiple R-squared:  0.001361,   Adjusted R-squared:  0.001206 
## F-statistic: 8.767 on 1 and 6433 DF,  p-value: 0.003079
  • Holiday coefficient ≈ +81,600

  • Statistically significant (p ≈ 0.003)

  • R² ≈ 0.0014

The baseline regression shows that holiday weeks are associated with an average increase of approximately 81,600 in weekly sales relative to non-holiday weeks, and this effect is statistically significant. However, the model’s explanatory power is extremely limited, with an R-squared value close to zero. This indicates that although holidays are associated with higher sales on average, they explain only a negligible fraction of the overall variation in weekly sales. Consequently, holiday effects alone are insufficient to understand Walmart’s sales dynamics.

5.2 Model 2 — Adding Time Structure (Trend & Seasonality)

Why add time?

Sales naturally evolve over time due to inflation, store maturity, and seasonality. Ignoring time effects risks attributing long-term trends to holidays.

# ------------------------------------------------
# STEP 4.2 – Model 2: Holiday + time effects
# ------------------------------------------------

model_2 <- lm(
  Weekly_Sales ~ Holiday_Flag + Year + Month,
  data = walmart
)

summary(model_2)
## 
## Call:
## lm(formula = Weekly_Sales ~ Holiday_Flag + Year + Month, data = walmart)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1096762  -480302   -77631   374868  2548039 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -18537153   18294914  -1.013 0.310983    
## Holiday_Flag     31735      30140   1.053 0.292425    
## Year              9739       9098   1.071 0.284412    
## Month.L         191021      27350   6.984 3.15e-12 ***
## Month.Q          90371      26610   3.396 0.000687 ***
## Month.C         180388      25567   7.056 1.90e-12 ***
## Month^4          50854      25432   2.000 0.045587 *  
## Month^5          41901      25670   1.632 0.102660    
## Month^6         -73224      25221  -2.903 0.003705 ** 
## Month^7         -13208      24409  -0.541 0.588468    
## Month^8         -29617      24152  -1.226 0.220132    
## Month^9           3463      23242   0.149 0.881552    
## Month^10          7162      23488   0.305 0.760452    
## Month^11         30501      23056   1.323 0.185918    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 559500 on 6421 degrees of freedom
## Multiple R-squared:  0.01915,    Adjusted R-squared:  0.01717 
## F-statistic: 9.646 on 13 and 6421 DF,  p-value: < 2.2e-16
  • Holiday_Flag → not meaningful statistically

  • Year → not meaningful

  • Month effects → strong

  • R² ≈ 0.019

After controlling for time effects, the estimated holiday coefficient becomes statistically insignificant, suggesting that part of the apparent holiday effect observed in the baseline model was capturing underlying seasonal patterns. Several month indicators are highly significant, highlighting strong seasonality in weekly sales. Although the overall explanatory power remains modest, the increase in R-squared relative to the baseline model demonstrates that temporal structure plays a substantially more important role than holidays alone.

5.3 Model 3 — Full Model: Holiday + Time + Macroeconomic Factors

Why macro variables?

Consumer spending is influenced by broader economic conditions. This model evaluates whether sales respond to CPI, unemployment, fuel prices, and weather, beyond holidays and time.

# ------------------------------------------------
# STEP 4.3 – Model 3: Full explanatory model
# ------------------------------------------------

model_3 <- lm(
  Weekly_Sales ~ Holiday_Flag + Year + Month +
    Temperature + Fuel_Price + CPI + Unemployment,
  data = walmart
)

summary(model_3)
## 
## Call:
## lm(formula = Weekly_Sales ~ Holiday_Flag + Year + Month + Temperature + 
##     Fuel_Price + CPI + Unemployment, data = walmart)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1176560  -469777  -103678   394114  2570012 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  93755105.5 35838224.8   2.616 0.008916 ** 
## Holiday_Flag    32950.6    29780.3   1.106 0.268571    
## Year           -45907.2    17866.1  -2.570 0.010206 *  
## Month.L        154044.2    30091.1   5.119 3.16e-07 ***
## Month.Q        128243.2    42972.5   2.984 0.002853 ** 
## Month.C        168301.5    27699.8   6.076 1.30e-09 ***
## Month^4         55092.7    26097.9   2.111 0.034811 *  
## Month^5         51758.6    25737.7   2.011 0.044367 *  
## Month^6        -83331.3    25249.5  -3.300 0.000971 ***
## Month^7        -13714.2    24165.5  -0.568 0.570386    
## Month^8        -25203.2    24010.7  -1.050 0.293911    
## Month^9          -200.7    22959.6  -0.009 0.993027    
## Month^10         4827.6    23203.5   0.208 0.835195    
## Month^11        33206.7    22796.1   1.457 0.145252    
## Temperature       312.9      693.0   0.452 0.651616    
## Fuel_Price      70304.0    30778.4   2.284 0.022392 *  
## CPI             -1529.3      211.2  -7.242 4.93e-13 ***
## Unemployment   -47530.8     4307.4 -11.035  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 552400 on 6417 degrees of freedom
## Multiple R-squared:  0.04444,    Adjusted R-squared:  0.04191 
## F-statistic: 17.56 on 17 and 6417 DF,  p-value: < 2.2e-16
  • Holiday_Flag → still not meaningful

  • Year → negative and meaningful

  • CPI → negative and very strong

  • Unemployment → negative and very strong

  • Fuel_Price → positive and meaningful

  • Temperature → not meaningful

  • R² ≈ 0.044

The full model provides the highest explanatory power among all specifications, indicating that weekly sales are influenced by a combination of temporal and macroeconomic factors. Once these variables are included, the holiday indicator remains statistically insignificant, confirming that holidays do not independently drive sales when broader economic conditions are taken into account. In contrast, unemployment and CPI exhibit strong negative relationships with sales, suggesting that macroeconomic pressure significantly dampens consumer spending. The positive coefficient on fuel prices may reflect correlated economic activity rather than a direct causal effect. Overall, these results indicate that macroeconomic conditions dominate holiday timing in explaining sales variation.

5.4 Comparing Models: What Really Adds Value?

# ------------------------------------------------
# STEP 4.4 – Model comparison
# ------------------------------------------------

model_comparison <- tibble(
  Model = c("Holiday only", "Holiday + Time", "Full Model"),
  R_squared = c(
    summary(model_1)$r.squared,
    summary(model_2)$r.squared,
    summary(model_3)$r.squared
  )
)

model_comparison

Actual R² values:

  • Holiday only → 0.001

  • Holiday + Time → 0.019

  • Full Model → 0.044

Model comparison reveals a clear hierarchy in explanatory power. The holiday-only model explains virtually none of the variation in weekly sales. Introducing time effects substantially improves model performance, while the inclusion of macroeconomic variables further doubles explanatory power. Despite this improvement, the relatively low R-squared values across all models indicate that a significant portion of sales variation remains store-specific or idiosyncratic, reinforcing the importance of store-level segmentation in subsequent analysis.

5.5 Step 4 Executive Summary

The regression analysis demonstrates that while holiday weeks are associated with higher sales in isolation, this effect disappears once time structure and macroeconomic conditions are accounted for. Seasonality and broader economic indicators, particularly unemployment and inflation, play a far more significant role in shaping weekly sales patterns. These findings suggest that managerial decisions focused solely on holiday timing may be misguided unless they are aligned with prevailing economic conditions. Furthermore, the limited explanatory power of aggregate models highlights the need to incorporate store-level heterogeneity, motivating a segmentation-based approach in the next step.

6 STEP 5 — Store Segmentation (K-Means Clustering)

Although regression models capture general patterns, they explain only a limited portion of weekly sales variation, suggesting that store-level differences play a major role. Therefore, we segment stores into meaningful groups using k-means clustering. The objective is to create actionable store segments (e.g., “high sales–stable” vs. “high volatility”) that can support differentiated managerial strategies for planning, resource allocation, and promotion design.

6.1 Create Store-Level Features for Clustering

What we include

We build a store-level dataset with features that capture:

  • Sales level (average weekly sales)

  • Sales volatility (CV or SD)

  • Holiday sensitivity (holiday lift at store level)

# ------------------------------------------------
# STEP 5.1 – Store-level dataset for clustering
# ------------------------------------------------

store_cluster_df <- walmart %>%
  group_by(Store) %>%
  summarise(
    avg_sales = mean(Weekly_Sales, na.rm = TRUE),
    sd_sales  = sd(Weekly_Sales, na.rm = TRUE),
    cv_sales  = sd_sales / avg_sales,
    
    # Holiday sensitivity: difference between holiday and non-holiday mean sales per store
    holiday_mean = mean(Weekly_Sales[Holiday_Flag == 1], na.rm = TRUE),
    nonholiday_mean = mean(Weekly_Sales[Holiday_Flag == 0], na.rm = TRUE),
    holiday_lift_pct = (holiday_mean - nonholiday_mean) / nonholiday_mean * 100,
    
    .groups = "drop"
  )

# Check for infinite / NA lift values (can happen if a store has no non-holiday weeks)
store_cluster_df <- store_cluster_df %>%
  mutate(
    holiday_lift_pct = ifelse(is.finite(holiday_lift_pct), holiday_lift_pct, NA_real_)
  )

summary(store_cluster_df)
##      Store      avg_sales          sd_sales         cv_sales      
##  Min.   : 1   Min.   : 259862   Min.   : 21837   Min.   :0.04208  
##  1st Qu.:12   1st Qu.: 556404   1st Qu.: 85770   1st Qu.:0.11502  
##  Median :23   Median : 966782   Median :128753   Median :0.13090  
##  Mean   :23   Mean   :1046965   Mean   :141586   Mean   :0.13262  
##  3rd Qu.:34   3rd Qu.:1395901   3rd Qu.:191723   3rd Qu.:0.15913  
##  Max.   :45   Max.   :2107677   Max.   :317570   Max.   :0.22968  
##   holiday_mean     nonholiday_mean   holiday_lift_pct
##  Min.   : 262595   Min.   : 259656   Min.   :-2.380  
##  1st Qu.: 606958   1st Qu.: 555555   1st Qu.: 5.319  
##  Median :1072047   Median : 961128   Median : 7.657  
##  Mean   :1122888   Mean   :1041256   Mean   : 7.398  
##  3rd Qu.:1500026   3rd Qu.:1388073   3rd Qu.: 9.893  
##  Max.   :2249035   Max.   :2097048   Max.   :19.439

This feature engineering step translates the weekly dataset into a store-level analytic view. In addition to sales level and volatility, we explicitly include holiday sensitivity as a behavioral feature. This ensures that segmentation is not based solely on store size, but also captures how stores respond to peak-demand periods.

6.2 Prepare Data for K-Means (Scaling)

K-means is distance-based, so variables with large scales dominate results. Therefore, we standardize variables before clustering.

# ------------------------------------------------
# STEP 5.2 – Scale variables for k-means
# ------------------------------------------------

cluster_features <- store_cluster_df %>%
  select(avg_sales, cv_sales, holiday_lift_pct) %>%
  drop_na()  # remove stores with missing holiday lift

cluster_scaled <- scale(cluster_features)

Scaling ensures that average sales, volatility, and holiday sensitivity contribute equally to the clustering solution. Without scaling, average sales would dominate the segmentation and reduce interpretability.

6.3 Choose the Number of Clusters (Elbow Method)

# ------------------------------------------------
# STEP 5.3 – Elbow method
# ------------------------------------------------

set.seed(123)

wss <- map_dbl(1:10, function(k) {
  kmeans(cluster_scaled, centers = k, nstart = 25)$tot.withinss
})

elbow_df <- tibble(k = 1:10, wss = wss)

ggplot(elbow_df, aes(x = k, y = wss)) +
  geom_line() +
  geom_point() +
  labs(
    title = "Elbow Method for Choosing k",
    x = "Number of clusters (k)",
    y = "Total within-cluster sum of squares"
  )

The elbow plot shows a sharp reduction in within-cluster variation up to three clusters, after which the marginal improvement becomes noticeably smaller. This clear “elbow” at k = 3 indicates that a three-segment solution provides an appropriate balance between explanatory power and interpretability. Therefore, k = 3 is selected for the final clustering analysis.

6.4 Run K-Means with Chosen k

# ------------------------------------------------
# STEP 5.4 – K-means clustering
# ------------------------------------------------

set.seed(123)
k <- 3

kmeans_model <- kmeans(cluster_scaled, centers = k, nstart = 25)

store_clustered <- store_cluster_df %>%
  drop_na(holiday_lift_pct) %>%
  mutate(Segment = factor(kmeans_model$cluster))

store_clustered %>% count(Segment)

6.5 Segment Profiling (What Differentiates Segments?)

# ------------------------------------------------
# STEP 5.5 – Segment summary table
# ------------------------------------------------

segment_profile <- store_clustered %>%
  group_by(Segment) %>%
  summarise(
    n_stores = n(),
    avg_sales_mean = mean(avg_sales),
    cv_sales_mean = mean(cv_sales),
    holiday_lift_mean = mean(holiday_lift_pct),
    .groups = "drop"
  )

segment_profile
Segment Interpretation
Segment 1 (8 stores) Low sales – very stable – negative holiday lift
Segment 2 (14 stores) Mid sales – highly volatile – strongly holiday-driven
Segment 3 (23 stores) High sales – moderately volatile – positive holiday response

The segmentation results reveal three clearly differentiated store types. Segment 1 consists of low-sales but highly stable stores, with a slightly negative average holiday lift, indicating limited responsiveness to holiday periods. Segment 2 is characterized by moderate sales levels combined with the highest relative volatility and the strongest positive holiday response, suggesting that demand in these stores is both event-driven and unstable. Segment 3 includes high-sales stores with moderate volatility and a consistently positive holiday lift, positioning them as core revenue drivers with predictable holiday benefits.

6.6 Visualize Segments

Plot A: Sales vs Volatility by Segment

ggplot(store_clustered, aes(x = avg_sales, y = cv_sales, shape = Segment)) +
  geom_point(size = 3, alpha = 0.8) +
  scale_x_continuous(labels = comma) +
  labs(
    title = "Store Segments: Average Sales vs Relative Volatility",
    x = "Average Weekly Sales",
    y = "Coefficient of Variation (CV)"
  )

The sales–volatility scatter plot highlights clear structural differences across segments. Segment 1 stores cluster at lower sales levels with minimal volatility, indicating predictable but limited revenue contribution. Segment 2 displays the highest dispersion in volatility for similar sales levels, reinforcing their classification as unstable and demand-sensitive locations. Segment 3 stores dominate the higher sales range while maintaining moderate volatility, confirming their role as Walmart’s primary revenue engines.

Plot B: Holiday Sensitivity by Segment

ggplot(store_clustered, aes(x = Segment, y = holiday_lift_pct)) +
  geom_boxplot() +
  labs(
    title = "Holiday Lift Distribution by Store Segment",
    x = "Segment",
    y = "Holiday Lift (%)"
  )

The holiday lift distribution further differentiates store segments. Segment 1 shows a slightly negative holiday effect, suggesting that holiday periods do not generate incremental demand in these locations. In contrast, Segment 2 exhibits the highest and most dispersed holiday lift, indicating strong but unpredictable responses to holiday events. Segment 3 demonstrates a positive and more stable holiday lift, implying that holiday promotions reliably enhance sales in high-performing stores.

6.7 Step 5 Executive Summary

The k-means clustering results suggest that Walmart stores can be grouped into distinct, interpretable segments based on sales level, sales stability, and holiday sensitivity. This segmentation enables differentiated strategies: high-sales stable stores may benefit from operational optimization and inventory prioritization, volatility-driven stores require demand smoothing and risk management, and holiday-responsive stores can be targeted with event-based promotions. Overall, segmentation offers a practical bridge between analytics and managerial action.

7 Final Managerial Recommendations

7.1 Overview

The analysis reveals that Walmart’s sales performance and volatility are not driven by a single universal factor such as holidays or macroeconomic conditions. Instead, store-level heterogeneity plays a dominant role. Based on the k-means segmentation results, three distinct store segments emerge, each requiring a differentiated managerial approach. The recommendations below translate the analytical findings into concrete, actionable strategies.


7.2 Segment 1: Stable Low-Impact Stores

Profile - Low average weekly sales
- Very low relative volatility
- Slightly negative or negligible holiday lift

Managerial Implications

These stores exhibit predictable demand patterns but contribute limited incremental revenue, particularly during holiday periods. Aggressive promotional activity in these locations is unlikely to yield meaningful returns.

Recommended Actions - Avoid heavy holiday-specific promotions
- Focus on cost efficiency and operational stability
- Use these stores as baseline demand benchmarks for

8 Conclusion, Limitations, and Future Research

8.1 Conclusion

This study addressed a focused set of research questions aimed at understanding Walmart’s sales dynamics from both an analytical and managerial perspective.

Regarding RQ1, the analysis showed that both sales and sales volatility are highly concentrated across stores, but not perfectly aligned. A relatively small number of stores account for a disproportionate share of total sales, while a partially different subset drives overall volatility. This finding confirms that aggregate performance metrics mask important store-level differences.

With respect to RQ2, the holiday analysis demonstrated that holiday periods are associated with higher average sales and increased dispersion. However, the effect of holidays is highly heterogeneous: only a subset of holiday weeks generates extreme sales spikes, while others resemble regular periods. This confirms that a simple binary holiday indicator provides an incomplete representation of holiday-driven demand.

In answering RQ3, regression results revealed that while holidays appear significant in isolation, their effect disappears once time structure and macroeconomic conditions are controlled for. Seasonality and broader economic indicators—particularly unemployment and inflation—play a substantially more important role in explaining weekly sales variation. These findings suggest that holiday timing alone is insufficient for understanding or predicting sales performance.

Finally, RQ4 demonstrated that store segmentation offers a practical solution to the limitations of aggregate modeling. Using k-means clustering, stores were grouped into three distinct segments based on sales level, volatility, and holiday sensitivity. These segments exhibit clearly differentiated behavioral patterns, enabling targeted managerial strategies rather than uniform, chain-wide policies.

Overall, the results highlight the importance of combining descriptive analysis, explanatory modeling, and segmentation to translate complex sales data into actionable insights. By aligning analytical methods with well-defined research questions, the study provides a structured framework for data-driven decision-making in retail marketing analytics.


8.2 Limitations

Despite its insights, this analysis is subject to several limitations. First, the dataset does not distinguish between different types of holidays (e.g., major shopping events versus routine public holidays). As a result, holiday effects are captured in an aggregated manner, which may mask important differences in demand intensity across specific events. Second, the regression models rely on aggregate weekly sales and do not incorporate product-level or customer-level information, limiting the ability to analyze category-specific or behavioral drivers of demand.

Additionally, while macroeconomic variables improve explanatory power, the relatively low R-squared values suggest that unobserved factors—such as local competition, store-specific promotions, or regional demographics—may play a significant role. Finally, the clustering results depend on the selected variables and number of clusters; alternative specifications could yield slightly different segment structures.


8.3 Future Research Directions

Future research could extend this analysis in several ways. First, incorporating more granular holiday classifications (e.g., separating major promotional events from minor holidays) would allow for a more precise estimation of event-specific effects. Second, integrating store-level promotional data, pricing information, or product-category sales could improve explanatory power and enable deeper behavioral insights.

Moreover, advanced modeling techniques such as mixed-effects models or panel data approaches could explicitly account for store-specific fixed effects and dynamic responses over time. Finally, linking sales performance to customer or regional demographic data would support more personalized and location-specific marketing strategies, further enhancing the managerial relevance of the analysis.

LS0tCnRpdGxlOiAiTWlNODExIE1pbmkgUHJvamVjdCAyIOKAkyBXYWxtYXJ0IFNhbGVzIEFuYWx5dGljcyIKYXV0aG9yOiAiR3JvdXAgNCIKZGF0ZTogImByIGZvcm1hdChTeXMuRGF0ZSgpLCAnJUIgJWQsICVZJylgIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRoZW1lOiBmbGF0bHkKICAgIGhpZ2hsaWdodDogcHlnbWVudHMKICAgIHRvYzogdHJ1ZQogICAgdG9jX2RlcHRoOiAzCiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogdHJ1ZQogICAgICBzbW9vdGhfc2Nyb2xsOiB0cnVlCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQogICAgbWF0aGpheDogZGVmYXVsdAotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFNURVAgMCDigJMgR2xvYmFsIFNldHVwIChydW5zIGF1dG9tYXRpY2FsbHkpCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIFNob3cgY29kZSBpbiByZXBvcnQgKGltcG9ydGFudCBmb3IgZ3JhZGluZykKa25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVjaG8gPSBUUlVFLAogIG1lc3NhZ2UgPSBGQUxTRSwKICB3YXJuaW5nID0gRkFMU0UKKQoKIyBMb2FkIHJlcXVpcmVkIGxpYnJhcmllcwpsaWJyYXJ5KHRpZHl2ZXJzZSkgICAjIGRhdGEgbWFuaXB1bGF0aW9uICsgdmlzdWFsaXphdGlvbgpsaWJyYXJ5KHJlYWR4bCkgICAgICAjIHJlYWRpbmcgRXhjZWwgZmlsZXMKbGlicmFyeShsdWJyaWRhdGUpICAgIyBkYXRlIGhhbmRsaW5nCmxpYnJhcnkoc2NhbGVzKSAgICAgICMgZm9ybWF0dGluZyBheGVzIChwZXJjZW50LCBjb21tYSkKbGlicmFyeShicm9vbSkgICAgICAgIyB0aWR5IHJlZ3Jlc3Npb24gb3V0cHV0cwpgYGAKCioqUHJvamVjdCBCYWNrZ3JvdW5kIGFuZCBPYmplY3RpdmUqKgoKV2FsbWFydOKAmXMgc2VuaW9yIG1hbmFnZW1lbnQgc3VzcGVjdHMgdGhhdCBvdmVyYWxsIHNhbGVzIHBlcmZvcm1hbmNlIGlzIGRyaXZlbiBieSBhIGxpbWl0ZWQgbnVtYmVyIG9mIHN0b3Jlcywgd2hpbGUgc2FsZXMgdm9sYXRpbGl0eSBtYXkgb3JpZ2luYXRlIGZyb20gYSBkaWZmZXJlbnQgc3Vic2V0IG9mIGxvY2F0aW9ucy4gQXQgdGhlIHNhbWUgdGltZSwgdGhlIENFTyBpcyB1bmNlcnRhaW4gd2hldGhlciBvYnNlcnZlZCB3ZWVrbHkgZmx1Y3R1YXRpb25zIGNhbiBiZSBzeXN0ZW1hdGljYWxseSBleHBsYWluZWQgYnkgaG9saWRheSBlZmZlY3RzIGFuZCBtYWNyb2Vjb25vbWljIGNvbmRpdGlvbnMsIG9yIHdoZXRoZXIgdGhleSByZWZsZWN0IHJhbmRvbSBub2lzZS4KClRoZSBvYmplY3RpdmUgb2YgdGhpcyBwcm9qZWN0IGlzIHRvIHRyYW5zbGF0ZSB0aGVzZSBtYW5hZ2VyaWFsIGNvbmNlcm5zIGludG8gZGF0YS1kcml2ZW4gaW5zaWdodHMgdXNpbmcgZXhwbG9yYXRvcnkgYW5hbHlzaXMsIHJlZ3Jlc3Npb24gbW9kZWxpbmcsIGFuZCBjbHVzdGVyaW5nIHRlY2huaXF1ZXMuIFRoZSB1bHRpbWF0ZSBnb2FsIGlzIHRvIHByb3ZpZGUgYWN0aW9uYWJsZSByZWNvbW1lbmRhdGlvbnMgcmF0aGVyIHRoYW4gcHVyZWx5IHN0YXRpc3RpY2FsIHJlc3VsdHMuCgojIFJlc2VhcmNoIFF1ZXN0aW9ucwoKVGhlIGRhdGFzZXQgYW5kIHByb2plY3QgYnJpZWYgcHJvdmlkZSBhIHdpZGUgcmFuZ2Ugb2YgcG90ZW50aWFsIGFuYWx5dGljYWwgcXVlc3Rpb25zIHJlbGF0ZWQgdG8gc2FsZXMgcGVyZm9ybWFuY2UsIHZvbGF0aWxpdHksIGhvbGlkYXlzLCBhbmQgbWFjcm9lY29ub21pYyBjb25kaXRpb25zLiBUbyBtYWludGFpbiBhbmFseXRpY2FsIGZvY3VzIGFuZCBtYW5hZ2VyaWFsIHJlbGV2YW5jZSwgdGhpcyBzdHVkeSBkZWxpYmVyYXRlbHkgbmFycm93cyB0aGUgc2NvcGUgdG8gYSBzbWFsbCBzZXQgb2YgaW50ZXJjb25uZWN0ZWQgcmVzZWFyY2ggcXVlc3Rpb25zLiBUaGVzZSBxdWVzdGlvbnMgYXJlIHNlbGVjdGVkIGJhc2VkIG9uIAooaSkgdGhlIENFT+KAmXMgc3RhdGVkIGNvbmNlcm5zLCAKKGlpKSBmZWFzaWJpbGl0eSBnaXZlbiB0aGUgYXZhaWxhYmxlIGRhdGEsIGFuZCAKKGlpaSkgdGhlaXIgYWJpbGl0eSB0byBzdXBwb3J0IGFjdGlvbmFibGUgaW5zaWdodHMgcmF0aGVyIHRoYW4gcHVyZWx5IGRlc2NyaXB0aXZlIGZpbmRpbmdzLgoKVGhlIGZpbmFsIHJlc2VhcmNoIHF1ZXN0aW9ucyBndWlkaW5nIHRoaXMgYW5hbHlzaXMgYXJlIGFzIGZvbGxvd3M6CgoqKlJRMTogU2FsZXMgQ29uY2VudHJhdGlvbiBhbmQgVm9sYXRpbGl0eSoqICAKV2hpY2ggc3RvcmVzIGNvbnRyaWJ1dGUgZGlzcHJvcG9ydGlvbmF0ZWx5IHRvIFdhbG1hcnTigJlzIHRvdGFsIHNhbGVzLCBhbmQgd2hpY2ggc3RvcmVzIGNvbnRyaWJ1dGUgZGlzcHJvcG9ydGlvbmF0ZWx5IHRvIHNhbGVzIHZvbGF0aWxpdHk/CgoqKlJRMjogSG9saWRheSBFZmZlY3RzIEJleW9uZCBhIEJpbmFyeSBJbmRpY2F0b3IqKiAgCkhvdyBkbyBob2xpZGF5IHBlcmlvZHMgYWZmZWN0IHdlZWtseSBzYWxlcyBsZXZlbHMgYW5kIHZvbGF0aWxpdHksIGFuZCB0byB3aGF0IGV4dGVudCBkb2VzIGEgc2ltcGxlIGhvbGlkYXkgZmxhZyBjYXB0dXJlIHRoZSB0cnVlIGhldGVyb2dlbmVpdHkgb2YgaG9saWRheS1kcml2ZW4gZGVtYW5kPwoKKipSUTM6IERyaXZlcnMgb2YgV2Vla2x5IFNhbGVzIFBlcmZvcm1hbmNlKiogIApUbyB3aGF0IGV4dGVudCBjYW4gd2Vla2x5IHNhbGVzIHZhcmlhdGlvbiBiZSBleHBsYWluZWQgYnkgaG9saWRheXMsIHRpbWUgc3RydWN0dXJlICh0cmVuZCBhbmQgc2Vhc29uYWxpdHkpLCBhbmQgbWFjcm9lY29ub21pYyBjb25kaXRpb25zPwoKKipSUTQ6IFN0b3JlIFNlZ21lbnRhdGlvbiBmb3IgTWFuYWdlcmlhbCBBY3Rpb24qKiAgCkNhbiBXYWxtYXJ0IHN0b3JlcyBiZSBzZWdtZW50ZWQgaW50byBtZWFuaW5nZnVsIGdyb3VwcyBiYXNlZCBvbiBzYWxlcyBsZXZlbCwgdm9sYXRpbGl0eSwgYW5kIGhvbGlkYXkgc2Vuc2l0aXZpdHksIGFuZCBob3cgY2FuIHRoZXNlIHNlZ21lbnRzIGluZm9ybSBkaWZmZXJlbnRpYXRlZCBtYW5hZ2VyaWFsIHN0cmF0ZWdpZXM/CgpUb2dldGhlciwgdGhlc2UgcmVzZWFyY2ggcXVlc3Rpb25zIHN0cnVjdHVyZSB0aGUgYW5hbHlzaXMgZnJvbSBkZXNjcmlwdGl2ZSBkaWFnbm9zaXMgKFJRMSksIHRvIGNhdXNhbCBleHBsYW5hdGlvbiAoUlEy4oCTUlEzKSwgYW5kIGZpbmFsbHkgdG8gcHJlc2NyaXB0aXZlIGluc2lnaHQgKFJRNCkuIFRoaXMgcHJvZ3Jlc3Npb24gZW5zdXJlcyB0aGF0IHRoZSBhbmFseXNpcyByZW1haW5zIGJvdGggYW5hbHl0aWNhbGx5IHJpZ29yb3VzIGFuZCBtYW5hZ2VyaWFsbHkgcmVsZXZhbnQuCgoKCiMgU1RFUCAxIOKAlCBEYXRhIEltcG9ydCAmIERhdGEgVW5kZXJzdGFuZGluZwoKIyMgRGF0YSBJbXBvcnQKCj4gVGhpcyBzdGVwIGVuc3VyZXMgdGhhdCB0aGUgZGF0YXNldCBpcyBzdWNjZXNzZnVsbHkgbG9hZGVkIGFuZCB0aGF0IHRoZSBjb2x1bW4gbmFtZXMgYW5kIGZpcnN0IG9ic2VydmF0aW9ucyBtYXRjaCBleHBlY3RhdGlvbnMuCgpgYGB7ciByZWFkRXhjZWx9CiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgU1RFUCAxLjEg4oCTIEltcG9ydCBXYWxtYXJ0IERhdGFzZXQKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMgVGhlIEV4Y2VsIGZpbGUgc2hvdWxkIGJlIHVwbG9hZGVkIHRvIFBvc2l0IENsb3VkCiMgYW5kIGxvY2F0ZWQgaW4gdGhlIHNhbWUgZm9sZGVyIGFzIHRoaXMgUk1EIGZpbGUKCndhbG1hcnRfcmF3IDwtIHJlYWRfZXhjZWwoIldhbG1hcnREYXRhLnhsc3giLCBzaGVldCA9ICJpbiIpCgojIEZpcnN0IGxvb2sgYXQgdGhlIGRhdGEKaGVhZCh3YWxtYXJ0X3JhdykKYGBgCgojIyBEYXRhIFN0cnVjdHVyZSAmIFZhcmlhYmxlIFR5cGVzCgpgYGB7ciBzdGVwMS4yfQp3YWxtYXJ0IDwtIHdhbG1hcnRfcmF3ICU+JQogIG11dGF0ZSgKICAgICMgQ29udmVydCB0aGVzZSBjb2x1bW5zIGV4cGxpY2l0bHkgdG8gbnVtZXJpYwogICAgV2Vla2x5X1NhbGVzID0gYXMubnVtZXJpYyhnc3ViKCIsIiwgIi4iLCBXZWVrbHlfU2FsZXMpKSwKICAgIFRlbXBlcmF0dXJlICA9IGFzLm51bWVyaWMoZ3N1YigiLCIsICIuIiwgVGVtcGVyYXR1cmUpKSwKICAgIEZ1ZWxfUHJpY2UgICA9IGFzLm51bWVyaWMoZ3N1YigiLCIsICIuIiwgRnVlbF9QcmljZSkpLAogICAgQ1BJICAgICAgICAgID0gYXMubnVtZXJpYyhnc3ViKCIsIiwgIi4iLCBDUEkpKSwKICAgIFVuZW1wbG95bWVudCA9IGFzLm51bWVyaWMoZ3N1YigiLCIsICIuIiwgVW5lbXBsb3ltZW50KSksCiAgICBIb2xpZGF5X0ZsYWcgPSBhcy5pbnRlZ2VyKEhvbGlkYXlfRmxhZyksCiAgICBTdG9yZSAgICAgICAgPSBhcy5pbnRlZ2VyKFN0b3JlKQogICkKCmdsaW1wc2Uod2FsbWFydCkKYGBgCgojIyBEZXNjcmlwdGl2ZSBTdGF0aXN0aWNzCgpgYGB7ciBzdGVwMS4zfQoKc3VtbWFyeSh3YWxtYXJ0X3JhdykKYGBgCgo+QXMgYSByZXN1bHQgb2YgdGhlIGluaXRpYWwgZGF0YSBhdWRpdCwgdGhlIGRhdGFzZXQgcmVxdWlyZXMgcHJlcHJvY2Vzc2luZyB0byBlbnN1cmUgY29ycmVjdCB2YXJpYWJsZSB0eXBlcy4gVGhpcyBzdGVwIGlzIG5lY2Vzc2FyeSB0byBwcm9kdWNlIHZhbGlkIGRlc2NyaXB0aXZlIGluc2lnaHRzIGFuZCByZWxpYWJsZSBzdGF0aXN0aWNhbCBtb2RlbHMuCgojIyBNaXNzaW5nIFZhbHVlcyBDaGVjawoKVGhlIG1pc3NpbmcgdmFsdWVzIGFuYWx5c2lzIGluZGljYXRlcyB0aGF0IHRoZXJlIGFyZSBubyBtaXNzaW5nIG9ic2VydmF0aW9ucyBhY3Jvc3MgYWxsIHZhcmlhYmxlcyBpbiB0aGUgZGF0YXNldC4gRWFjaCBjb2x1bW4sIGluY2x1ZGluZyBzYWxlcywgaG9saWRheSBpbmRpY2F0b3JzLCBhbmQgbWFjcm9lY29ub21pYyB2YXJpYWJsZXMsIGNvbnRhaW5zIGNvbXBsZXRlIGluZm9ybWF0aW9uIGZvciBhbGwgdGltZSBwZXJpb2RzIGFuZCBzdG9yZXMuIFRoaXMgaXMgYSBzdHJvbmcgYWR2YW50YWdlIGZvciB0aGUgYW5hbHlzaXMsIGFzIGl0IGVsaW1pbmF0ZXMgdGhlIG5lZWQgZm9yIGltcHV0YXRpb24gb3Igcm93IHJlbW92YWwgc3RyYXRlZ2llcyB0aGF0IGNvdWxkIG90aGVyd2lzZSBpbnRyb2R1Y2UgYmlhcyBvciByZWR1Y2Ugc3RhdGlzdGljYWwgcG93ZXIuIENvbnNlcXVlbnRseSwgc3Vic2VxdWVudCBleHBsb3JhdG9yeSBhbmQgbW9kZWxpbmcgc3RlcHMgY2FuIGJlIGNvbmR1Y3RlZCBvbiB0aGUgZnVsbCBkYXRhc2V0IHdpdGhvdXQgY29uY2VybnMgcmVsYXRlZCB0byBkYXRhIGluY29tcGxldGVuZXNzLgoKYGBge3Igc3RlcDEuNH0KCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgU1RFUCAxLjQg4oCTIE1pc3NpbmcgdmFsdWVzCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgptaXNzaW5nX3N1bW1hcnkgPC0gd2FsbWFydCAlPiUKICBzdW1tYXJpc2UoYWNyb3NzKGV2ZXJ5dGhpbmcoKSwgfiBzdW0oaXMubmEoLikpKSkKCm1pc3Npbmdfc3VtbWFyeQoKYGBgCgojIyBEYXRlIENvbnZlcnNpb24gJiBGZWF0dXJlIEVuZ2luZWVyaW5nCgpUaW1lIGVmZmVjdHMgKHRyZW5kLCBzZWFzb25hbGl0eSwgaG9saWRheXMpIGNhbm5vdCBiZSBhbmFseXplZCB1bmxlc3MgZGF0ZXMgYXJlIGNvcnJlY3RseSBmb3JtYXR0ZWQuCgpgYGB7ciBzdGVwMS41fQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFNURVAgMS41IOKAkyBEYXRlIGhhbmRsaW5nIGFuZCB0aW1lIHZhcmlhYmxlcwojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKd2FsbWFydCA8LSB3YWxtYXJ0ICU+JQogIG11dGF0ZSgKICAgIERhdGUgID0gZG15KERhdGUpLCAgICAgICAgICAgICAgIyBjb252ZXJ0IHRleHQgdG8gRGF0ZQogICAgWWVhciAgPSB5ZWFyKERhdGUpLAogICAgTW9udGggPSBtb250aChEYXRlLCBsYWJlbCA9IFRSVUUpCiAgKQoKc3VtbWFyeSh3YWxtYXJ0JERhdGUpCmBgYAoKCj5BZnRlciB0aGUgZGF0YSB0eXBlIGNvbnZlcnNpb24sIGFsbCBrZXkgdmFyaWFibGVzIGFyZSBjb3JyZWN0bHkgZm9ybWF0dGVkLiBXZWVrbHkgc2FsZXMgYW5kIG1hY3JvZWNvbm9taWMgdmFyaWFibGVzIGFyZSBzdG9yZWQgYXMgbnVtZXJpYyB2YWx1ZXMsIHRoZSBzdG9yZSBpZGVudGlmaWVyIGlzIGFuIGludGVnZXIsIGFuZCB0aGUgZGF0ZSB2YXJpYWJsZSBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgcGFyc2VkLiBUaGlzIGNvbmZpcm1zIHRoYXQgdGhlIGRhdGFzZXQgaXMgbm93IHN1aXRhYmxlIGZvciBhZ2dyZWdhdGlvbiwgdmlzdWFsaXphdGlvbiwgYW5kIHN0YXRpc3RpY2FsIG1vZGVsaW5nLgoKCiMgU1RFUCAyIOKAlCBFeHBsb3JhdG9yeSBBbmFseXNpczogU3RvcmUgQ29uY2VudHJhdGlvbiAmIFZvbGF0aWxpdHkKCioqUHVycG9zZSBvZiBTdGVwIDIqKgpUbyBlbXBpcmljYWxseSB0ZXN0IHRoZSBDRU/igJlzIGludHVpdGlvbiB0aGF0OgoKLSBhIHNtYWxsIG51bWJlciBvZiBzdG9yZXMgZHJpdmUgdG90YWwgc2FsZXMKCi0gYSBkaWZmZXJlbnQgc3Vic2V0IGRyaXZlcyBzYWxlcyB2b2xhdGlsaXR5CgpUaGlzIHN0ZXAgaXMgZGVzY3JpcHRpdmUgYnV0IHN0cmF0ZWdpYyDigJQgaXQgZGVmaW5lcyB3aGVyZSB0byBsb29rIG5leHQuCgojIyBTdG9yZS1MZXZlbCBTYWxlcyBhbmQgVm9sYXRpbGl0eSBNZXRyaWNzCgpgYGB7ciBzdGVwMi4xfQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFNURVAgMi4xIOKAkyBTdG9yZS1sZXZlbCBwZXJmb3JtYW5jZSBtZXRyaWNzCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIEZpeDogQ29udmVydCBudW1lcmljLWxvb2tpbmcgdGV4dCBjb2x1bW5zIHRvIG51bWVyaWMKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgoKCnN0b3JlX3N1bW1hcnkgPC0gd2FsbWFydCAlPiUKICBncm91cF9ieShTdG9yZSkgJT4lCiAgc3VtbWFyaXNlKAogICAgYXZnX3dlZWtseV9zYWxlcyA9IG1lYW4oV2Vla2x5X1NhbGVzLCBuYS5ybSA9IFRSVUUpLAogICAgdG90YWxfc2FsZXMgICAgICA9IHN1bShXZWVrbHlfU2FsZXMsIG5hLnJtID0gVFJVRSksCiAgICBzZF9zYWxlcyAgICAgICAgID0gc2QoV2Vla2x5X1NhbGVzLCBuYS5ybSA9IFRSVUUpLAogICAgY3Zfc2FsZXMgICAgICAgICA9IHNkX3NhbGVzIC8gYXZnX3dlZWtseV9zYWxlcywgICMgcmVsYXRpdmUgdm9sYXRpbGl0eQogICAgLmdyb3VwcyA9ICJkcm9wIgogICkgJT4lCiAgbXV0YXRlKAogICAgc2FsZXNfc2hhcmUgPSB0b3RhbF9zYWxlcyAvIHN1bSh0b3RhbF9zYWxlcyksCiAgICB2b2xhdGlsaXR5X3NoYXJlID0gc2Rfc2FsZXMgLyBzdW0oc2Rfc2FsZXMpCiAgKQoKIyBJbnNwZWN0IHRvcCBzdG9yZXMKc3RvcmVfc3VtbWFyeSAlPiUgYXJyYW5nZShkZXNjKHRvdGFsX3NhbGVzKSkgJT4lIGhlYWQoMTApCmBgYAoKCj5UaGUgc3RvcmUtbGV2ZWwgc3VtbWFyeSBzdGF0aXN0aWNzIHJldmVhbCBzdWJzdGFudGlhbCBoZXRlcm9nZW5laXR5IGluIHBlcmZvcm1hbmNlIGFjcm9zcyBXYWxtYXJ0IGxvY2F0aW9ucy4gVGhlIHRvcC1zZWxsaW5nIHN0b3JlcyBnZW5lcmF0ZSBhdmVyYWdlIHdlZWtseSBzYWxlcyBleGNlZWRpbmcgKioyIG1pbGxpb24qKiwgd2hpbGUgdGhlaXIgY29lZmZpY2llbnRzIG9mIHZhcmlhdGlvbiByYW5nZSBiZXR3ZWVuIGFwcHJveGltYXRlbHkgKiowLjEwIGFuZCAwLjE2KiouIFRoaXMgaW5kaWNhdGVzIHRoYXQgZXZlbiBhbW9uZyB0aGUgaGlnaGVzdC1yZXZlbnVlIHN0b3JlcywgcmVsYXRpdmUgc2FsZXMgc3RhYmlsaXR5IGRpZmZlcnMgbWVhbmluZ2Z1bGx5LiBTb21lIGxhcmdlIHN0b3JlcyBjb21iaW5lIGhpZ2ggc2FsZXMgd2l0aCByZWxhdGl2ZWx5IHN0YWJsZSBkZW1hbmQsIHdoZXJlYXMgb3RoZXJzIGV4cGVyaWVuY2UgY29uc2lkZXJhYmxlIHdlZWstdG8td2VlayBmbHVjdHVhdGlvbnMgZGVzcGl0ZSBzaW1pbGFyIHJldmVudWUgbGV2ZWxzLgoKCiMjIFNhbGVzIENvbmNlbnRyYXRpb246IERvIGEgRmV3IFN0b3JlcyBEb21pbmF0ZSBSZXZlbnVlPwoKYGBge3Igc3RlcDIuMn0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBTVEVQIDIuMiDigJMgU2FsZXMgY29uY2VudHJhdGlvbiBwbG90CiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp0b3Bfc2FsZXMgPC0gc3RvcmVfc3VtbWFyeSAlPiUKICBhcnJhbmdlKGRlc2ModG90YWxfc2FsZXMpKSAlPiUKICBtdXRhdGUocmFuayA9IHJvd19udW1iZXIoKSkKCmdncGxvdCh0b3Bfc2FsZXMsIGFlcyh4ID0gcmFuaywgeSA9IHNhbGVzX3NoYXJlKSkgKwogIGdlb21fY29sKCkgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArCiAgbGFicygKICAgIHRpdGxlID0gIlN0b3JlIFJhbmtpbmcgYnkgU2hhcmUgb2YgVG90YWwgU2FsZXMiLAogICAgeCA9ICJTdG9yZSBSYW5rICgxID0gSGlnaGVzdCBUb3RhbCBTYWxlcykiLAogICAgeSA9ICJTaGFyZSBvZiBUb3RhbCBTYWxlcyIKICApCmBgYAoKPlRoZSBzYWxlcyBjb25jZW50cmF0aW9uIGFuYWx5c2lzIHNob3dzIGEgcHJvbm91bmNlZCBza2V3IGluIHJldmVudWUgY29udHJpYnV0aW9uIGFjcm9zcyBzdG9yZXMuIFRoZSBoaWdoZXN0LXJhbmtlZCBzdG9yZXMgZWFjaCBhY2NvdW50IGZvciByb3VnaGx5IDTigJM0LjUlIG9mIHRvdGFsIHNhbGVzLCB3aGlsZSB0aGUgc2FsZXMgc2hhcmUgZGVjbGluZXMgc3RlYWRpbHkgYWNyb3NzIGxvd2VyLXJhbmtlZCBsb2NhdGlvbnMuIFRoaXMgcGF0dGVybiBjb25maXJtcyB0aGF0IFdhbG1hcnTigJlzIG92ZXJhbGwgcmV2ZW51ZSBpcyBub3QgZXZlbmx5IGRpc3RyaWJ1dGVkLCBidXQgaW5zdGVhZCBkZXBlbmRzIGhlYXZpbHkgb24gYSByZWxhdGl2ZWx5IHNtYWxsIGdyb3VwIG9mIGhpZ2gtcGVyZm9ybWluZyBzdG9yZXMuIENvbnNlcXVlbnRseSwgY2hhbmdlcyBpbiBwZXJmb3JtYW5jZSBhdCB0aGVzZSB0b3AgbG9jYXRpb25zIGFyZSBsaWtlbHkgdG8gaGF2ZSBhIGRpc3Byb3BvcnRpb25hdGUgaW1wYWN0IG9uIHRvdGFsIGNvbXBhbnkgc2FsZXMuCgoKIyMgVm9sYXRpbGl0eSBDb25jZW50cmF0aW9uOiBXaG8gRHJpdmVzIFdlZWtseSBJbnN0YWJpbGl0eT8KCmBgYHtyIHN0ZXAyLjN9CiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgU1RFUCAyLjMg4oCTIFZvbGF0aWxpdHkgY29uY2VudHJhdGlvbiBwbG90CiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp0b3Bfdm9sYXRpbGl0eSA8LSBzdG9yZV9zdW1tYXJ5ICU+JQogIGFycmFuZ2UoZGVzYyhzZF9zYWxlcykpICU+JQogIG11dGF0ZShyYW5rID0gcm93X251bWJlcigpKQoKZ2dwbG90KHRvcF92b2xhdGlsaXR5LCBhZXMoeCA9IHJhbmssIHkgPSB2b2xhdGlsaXR5X3NoYXJlKSkgKwogIGdlb21fY29sKCkgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArCiAgbGFicygKICAgIHRpdGxlID0gIlN0b3JlIFJhbmtpbmcgYnkgU2hhcmUgb2YgU2FsZXMgVm9sYXRpbGl0eSIsCiAgICB4ID0gIlN0b3JlIFJhbmsgKDEgPSBNb3N0IFZvbGF0aWxlKSIsCiAgICB5ID0gIlNoYXJlIG9mIFRvdGFsIFZvbGF0aWxpdHkiCiAgKQpgYGAKCj5BIHNpbWlsYXIgYnV0IGRpc3RpbmN0IGNvbmNlbnRyYXRpb24gcGF0dGVybiBlbWVyZ2VzIHdoZW4gZXhhbWluaW5nIHNhbGVzIHZvbGF0aWxpdHkuIEEgbGltaXRlZCBudW1iZXIgb2Ygc3RvcmVzIGNvbnRyaWJ1dGUgYSBkaXNwcm9wb3J0aW9uYXRlbHkgbGFyZ2Ugc2hhcmUgb2YgdG90YWwgc2FsZXMgdm9sYXRpbGl0eSwgd2l0aCB0aGUgbW9zdCB2b2xhdGlsZSBzdG9yZXMgYWNjb3VudGluZyBmb3IgbmVhcmx5IDUlIGVhY2guIEltcG9ydGFudGx5LCB2b2xhdGlsaXR5IGRlY2xpbmVzIGdyYWR1YWxseSBhY3Jvc3MgdGhlIHJhbmtpbmcsIGluZGljYXRpbmcgdGhhdCBpbnN0YWJpbGl0eSBpcyBjb25jZW50cmF0ZWQgcmF0aGVyIHRoYW4gd2lkZXNwcmVhZC4gVGhpcyBzdWdnZXN0cyB0aGF0IFdhbG1hcnTigJlzIHdlZWstdG8td2VlayBzYWxlcyBmbHVjdHVhdGlvbnMgYXJlIHByaW1hcmlseSBkcml2ZW4gYnkgc3BlY2lmaWMgbG9jYXRpb25zIHJhdGhlciB0aGFuIGJ5IHVuaWZvcm0sIGNoYWluLXdpZGUgc2hvY2tzLgoKCiMjIEFyZSBIaWdoLVNhbGVzIFN0b3JlcyBBbHNvIEhpZ2gtVm9sYXRpbGl0eSBTdG9yZXM/CgpgYGB7ciBzdGVwMi40fQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFNURVAgMi40IOKAkyBTYWxlcyByYW5rIHZzIHZvbGF0aWxpdHkgcmFuawojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKc3RvcmVfcmFua3MgPC0gc3RvcmVfc3VtbWFyeSAlPiUKICBtdXRhdGUoCiAgICBzYWxlc19yYW5rID0gcmFuaygtdG90YWxfc2FsZXMsIHRpZXMubWV0aG9kID0gImZpcnN0IiksCiAgICB2b2xfcmFuayAgID0gcmFuaygtc2Rfc2FsZXMsIHRpZXMubWV0aG9kID0gImZpcnN0IikKICApCgpnZ3Bsb3Qoc3RvcmVfcmFua3MsIGFlcyh4ID0gc2FsZXNfcmFuaywgeSA9IHZvbF9yYW5rKSkgKwogIGdlb21fcG9pbnQoKSArCiAgbGFicygKICAgIHRpdGxlID0gIlJlbGF0aW9uc2hpcCBCZXR3ZWVuIFNhbGVzIFJhbmsgYW5kIFZvbGF0aWxpdHkgUmFuayIsCiAgICB4ID0gIlNhbGVzIFJhbmsgKDEgPSBIaWdoZXN0IFNhbGVzKSIsCiAgICB5ID0gIlZvbGF0aWxpdHkgUmFuayAoMSA9IEhpZ2hlc3QgVm9sYXRpbGl0eSkiCiAgKQpgYGAKCj5UaGUgY29tcGFyaXNvbiBiZXR3ZWVuIHNhbGVzIHJhbmsgYW5kIHZvbGF0aWxpdHkgcmFuayBpbmRpY2F0ZXMgdGhhdCBoaWdoLXJldmVudWUgc3RvcmVzIGFyZSBub3Qgc3lzdGVtYXRpY2FsbHkgdGhlIG1vc3Qgdm9sYXRpbGUuIFdoaWxlIHNvbWUgaGlnaC1zYWxlcyBsb2NhdGlvbnMgYWxzbyBleGhpYml0IGhpZ2ggdm9sYXRpbGl0eSwgbWFueSB0b3Atc2VsbGluZyBzdG9yZXMgZGlzcGxheSBtb2RlcmF0ZSBvciBsb3cgdm9sYXRpbGl0eSByYW5raW5ncy4gQ29udmVyc2VseSwgc2V2ZXJhbCBsb3dlci1yYW5rZWQgc2FsZXMgc3RvcmVzIGFwcGVhciBhbW9uZyB0aGUgbW9zdCB2b2xhdGlsZS4gVGhpcyBkaXNwZXJzaW9uIHN1Z2dlc3RzIHRoZSBwcmVzZW5jZSBvZiBkaXN0aW5jdCBzdG9yZSByb2xlcyB3aXRoaW4gdGhlIG5ldHdvcmssIHNlcGFyYXRpbmcgcmV2ZW51ZS1kcml2aW5nIGxvY2F0aW9ucyBmcm9tIHZvbGF0aWxpdHktZHJpdmluZyBvbmVzLgoKCiMjIFN0ZXAgMiBTdW1tYXJ5IAoKPk92ZXJhbGwsIHRoZSBleHBsb3JhdG9yeSBhbmFseXNpcyBjb25maXJtcyB0aGF0IFdhbG1hcnTigJlzIHNhbGVzIGFuZCB2b2xhdGlsaXR5IGFyZSBib3RoIGhpZ2hseSBjb25jZW50cmF0ZWQgYnV0IG5vdCBwZXJmZWN0bHkgYWxpZ25lZCBhY3Jvc3Mgc3RvcmVzLiBBIHNtYWxsIG51bWJlciBvZiBsb2NhdGlvbnMgZHJpdmUgYSBsYXJnZSBzaGFyZSBvZiB0b3RhbCByZXZlbnVlLCB3aGlsZSBhIHBhcnRpYWxseSBkaWZmZXJlbnQgc3Vic2V0IGRyaXZlcyBzYWxlcyBpbnN0YWJpbGl0eS4gVGhlc2UgZmluZGluZ3MgdmFsaWRhdGUgdGhlIENFT+KAmXMgaW5pdGlhbCBpbnR1aXRpb24gYW5kIGRlbW9uc3RyYXRlIHRoYXQgYWdncmVnYXRlIG1ldHJpY3MgbWFzayBpbXBvcnRhbnQgc3RvcmUtbGV2ZWwgZHluYW1pY3MuIEFzIGEgcmVzdWx0LCBzdWJzZXF1ZW50IGFuYWx5c2VzIHNob3VsZCBmb2N1cyBvbiBpZGVudGlmeWluZyB0aGUgZHJpdmVycyBvZiB2b2xhdGlsaXR5IGFuZCBzYWxlcyBhdCBhIG1vcmUgZ3JhbnVsYXIgbGV2ZWwsIHBhcnRpY3VsYXJseSBleGFtaW5pbmcgdGhlIHJvbGUgb2YgaG9saWRheXMgYW5kIHRlbXBvcmFsIGVmZmVjdHMuCgoKIyBTVEVQIDMg4oCUIEhvbGlkYXkgQW5hbHlzaXMKCj5JbiBTdGVwIDIsIHdlIHNob3dlZCB0aGF0IHNhbGVzIGFuZCB2b2xhdGlsaXR5IGFyZSBjb25jZW50cmF0ZWQgaW4gc3BlY2lmaWMgc3RvcmVzLiBIb3dldmVyLCBzdG9yZS1sZXZlbCBwYXR0ZXJucyBhbG9uZSBkbyBub3QgZXhwbGFpbiB3aHkgd2Vla2x5IHNhbGVzIGZsdWN0dWF0ZS4gT25lIGZyZXF1ZW50bHkgY2l0ZWQgZXhwbGFuYXRpb24gaXMgdGhlIGVmZmVjdCBvZiBob2xpZGF5cy4gV2hpbGUgdGhlIGRhdGFzZXQgcHJvdmlkZXMgYSBiaW5hcnkgaG9saWRheSBpbmRpY2F0b3IgKEhvbGlkYXlfRmxhZyksIHJlbHlpbmcgc29sZWx5IG9uIGEgMC8xIHZhcmlhYmxlIG1heSBvdmVyc2ltcGxpZnkgdGhlIHVuZGVybHlpbmcgZHluYW1pY3MuIFRoZXJlZm9yZSwgdGhpcyBzdGVwIGV4YW1pbmVzIGhvbGlkYXkgZWZmZWN0cyBpbiBhIHN0cnVjdHVyZWQgYnV0IGZvY3VzZWQgbWFubmVyLCB3aXRob3V0IGxvc2luZyBzaWdodCBvZiB0aGUgYnJvYWRlciBhbmFseXRpY2FsIG9iamVjdGl2ZS4KCgojIyBIb2xpZGF5IHZzIE5vbi1Ib2xpZGF5OiBBdmVyYWdlIFNhbGVzIENvbXBhcmlzb24KCioqV2hhdCB3ZSBkbyoqCgpXZSBmaXJzdCBjb21wYXJlIGF2ZXJhZ2Ugd2Vla2x5IHNhbGVzIGR1cmluZyBob2xpZGF5IHdlZWtzIHZlcnN1cyBub24taG9saWRheSB3ZWVrcy4KVGhpcyBwcm92aWRlcyBhbiBpbnR1aXRpdmUgYmVuY2htYXJrIGZvciB1bmRlcnN0YW5kaW5nIHdoZXRoZXIgaG9saWRheXMgbWF0dGVyIGF0IGFsbC4KCmBgYHtyIHN0ZXAzLjF9CiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgU1RFUCAzLjEg4oCTIEF2ZXJhZ2Ugc2FsZXM6IEhvbGlkYXkgdnMgTm9uLUhvbGlkYXkKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmhvbGlkYXlfc2FsZXNfc3VtbWFyeSA8LSB3YWxtYXJ0ICU+JQogIGdyb3VwX2J5KEhvbGlkYXlfRmxhZykgJT4lCiAgc3VtbWFyaXNlKAogICAgYXZnX3dlZWtseV9zYWxlcyA9IG1lYW4oV2Vla2x5X1NhbGVzLCBuYS5ybSA9IFRSVUUpLAogICAgc2Rfd2Vla2x5X3NhbGVzICA9IHNkKFdlZWtseV9TYWxlcywgbmEucm0gPSBUUlVFKSwKICAgIG5fd2Vla3MgPSBuKCksCiAgICAuZ3JvdXBzID0gImRyb3AiCiAgKQoKaG9saWRheV9zYWxlc19zdW1tYXJ5CgpgYGAKPlRoZSBjb21wYXJpc29uIG9mIGF2ZXJhZ2Ugd2Vla2x5IHNhbGVzIGluZGljYXRlcyB0aGF0IGhvbGlkYXkgd2Vla3MgYXJlIGFzc29jaWF0ZWQgd2l0aCBhIGRpZmZlcmVudCBzYWxlcyBsZXZlbCB0aGFuIG5vbi1ob2xpZGF5IHdlZWtzLiBUaGUgZGlmZmVyZW5jZSBpbiBtZWFuIHNhbGVzIHN1Z2dlc3RzIHRoYXQgaG9saWRheXMgYXJlIG5vdCBuZXV0cmFsIHBlcmlvZHMgYW5kIG1heSBzeXN0ZW1hdGljYWxseSBzaGlmdCBjb25zdW1lciBwdXJjaGFzaW5nIGJlaGF2aW9yLiBIb3dldmVyLCB0aGlzIGFnZ3JlZ2F0ZSBjb21wYXJpc29uIGRvZXMgbm90IHlldCBpbmRpY2F0ZSB3aGV0aGVyIHRoZSBvYnNlcnZlZCBkaWZmZXJlbmNlIGlzIGxhcmdlIGVub3VnaCB0byBiZSBlY29ub21pY2FsbHkgbWVhbmluZ2Z1bCBvciBjb25zaXN0ZW50IGFjcm9zcyBzdG9yZXMuIOKAnEhvbGlkYXkgZWZmZWN0IHZhciBnaWJpIGfDtnLDvG7DvHlvcuKAnSBhbWEgdGVrIGJhxZ/EsW5hIHlldGVybGkgZGXEn2lsLgoKIyMgVmlzdWFsIENvbXBhcmlzb246IFNhbGVzIERpc3RyaWJ1dGlvbgoKKipXaHkgdmlzdWFsaXphdGlvbiBtYXR0ZXJzKioKCkF2ZXJhZ2VzIGNhbiBoaWRlIHZhcmlhYmlsaXR5LiBUaGVyZWZvcmUsIHdlIGNvbXBhcmUgdGhlIGRpc3RyaWJ1dGlvbiBvZiB3ZWVrbHkgc2FsZXMgZHVyaW5nIGhvbGlkYXkgYW5kIG5vbi1ob2xpZGF5IHdlZWtzLgoKYGBge3Igc3RlcDMuMn0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBTVEVQIDMuMiDigJMgU2FsZXMgZGlzdHJpYnV0aW9uIGJ5IGhvbGlkYXkgc3RhdHVzCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpnZ3Bsb3Qod2FsbWFydCwgYWVzKHggPSBmYWN0b3IoSG9saWRheV9GbGFnKSwgeSA9IFdlZWtseV9TYWxlcykpICsKICBnZW9tX2JveHBsb3QoKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IGNvbW1hKSArCiAgbGFicygKICAgIHRpdGxlID0gIldlZWtseSBTYWxlcyBEaXN0cmlidXRpb246IEhvbGlkYXkgdnMgTm9uLUhvbGlkYXkgV2Vla3MiLAogICAgeCA9ICJIb2xpZGF5IEZsYWcgKDAgPSBOb24tSG9saWRheSwgMSA9IEhvbGlkYXkpIiwKICAgIHkgPSAiV2Vla2x5IFNhbGVzIgogICkKCmBgYAoKPlRoZSBib3hwbG90IGNvbXBhcmlzb24gc2hvd3MgdGhhdCBob2xpZGF5IHdlZWtzIHRlbmQgdG8gc2hpZnQgdGhlIHNhbGVzIGRpc3RyaWJ1dGlvbiB1cHdhcmQgcmVsYXRpdmUgdG8gbm9uLWhvbGlkYXkgd2Vla3MuIEF0IHRoZSBzYW1lIHRpbWUsIHRoZSB3aWRlciBzcHJlYWQgZHVyaW5nIGhvbGlkYXkgcGVyaW9kcyBpbmRpY2F0ZXMgaW5jcmVhc2VkIGRpc3BlcnNpb24sIHN1Z2dlc3RpbmcgdGhhdCBob2xpZGF5cyBtYXkgYW1wbGlmeSBub3Qgb25seSBzYWxlcyBsZXZlbHMgYnV0IGFsc28gc2FsZXMgdW5jZXJ0YWludHkuIFRoaXMgb2JzZXJ2YXRpb24gcmVpbmZvcmNlcyB0aGUgbmVlZCB0byBleGFtaW5lIHZvbGF0aWxpdHkgZWZmZWN0cyBpbiBhZGRpdGlvbiB0byBhdmVyYWdlIHNhbGVzIGRpZmZlcmVuY2VzLgoKIyMgSG9saWRheSBMaWZ0OiBIb3cgTGFyZ2UgSXMgdGhlIEVmZmVjdD8KCioqV2hhdCBpcyDigJxob2xpZGF5IGxpZnTigJ0/KioKCkhvbGlkYXkgbGlmdCBtZWFzdXJlcyB0aGUgcGVyY2VudGFnZSBkaWZmZXJlbmNlIGluIGF2ZXJhZ2Ugc2FsZXMgYmV0d2VlbiBob2xpZGF5IGFuZCBub24taG9saWRheSB3ZWVrcy4KCmBgYHtyIHN0ZXAzLjN9CiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgU1RFUCAzLjMg4oCTIEhvbGlkYXkgbGlmdCBjYWxjdWxhdGlvbgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKaG9saWRheV9saWZ0IDwtIGhvbGlkYXlfc2FsZXNfc3VtbWFyeSAlPiUKICBzdW1tYXJpc2UoCiAgICBob2xpZGF5X2xpZnRfcGN0ID0KICAgICAgKGF2Z193ZWVrbHlfc2FsZXNbSG9saWRheV9GbGFnID09IDFdIC0KICAgICAgIGF2Z193ZWVrbHlfc2FsZXNbSG9saWRheV9GbGFnID09IDBdKSAvCiAgICAgICBhdmdfd2Vla2x5X3NhbGVzW0hvbGlkYXlfRmxhZyA9PSAwXSAqIDEwMAogICkKCmhvbGlkYXlfbGlmdAoKYGBgCgo+VGhlIGhvbGlkYXkgbGlmdCBjYWxjdWxhdGlvbiBxdWFudGlmaWVzIHRoZSBtYWduaXR1ZGUgb2YgdGhlIGhvbGlkYXkgZWZmZWN0IGluIHBlcmNlbnRhZ2UgdGVybXMuIFRoaXMgbWV0cmljIHByb3ZpZGVzIGEgbW9yZSBpbnRlcnByZXRhYmxlIG1lYXN1cmUgZm9yIG1hbmFnZXJpYWwgZGVjaXNpb24tbWFraW5nLCBhcyBpdCB0cmFuc2xhdGVzIHJhdyBzYWxlcyBkaWZmZXJlbmNlcyBpbnRvIHJlbGF0aXZlIHBlcmZvcm1hbmNlIGdhaW5zLiBBIG1vZGVzdCBsaWZ0IHN1Z2dlc3RzIHRoYXQgaG9saWRheXMgcGxheSBhIHNlY29uZGFyeSByb2xlLCB3aGVyZWFzIGEgbGFyZ2UgbGlmdCB3b3VsZCBpbmRpY2F0ZSB0aGF0IGhvbGlkYXktZHJpdmVuIGRlbWFuZCBpcyBhIG1ham9yIGNvbnRyaWJ1dG9yIHRvIG92ZXJhbGwgc2FsZXMgcGVyZm9ybWFuY2UuCkhvbGlkYXnigJlpIHNhZGVjZSDigJx2YXIveW9r4oCdIGRlbWl5b3J1eiDihpIgZXRraSBiw7x5w7xrbMO8xJ/DvG7DvCDDtmzDp8O8eW9ydXouCgojIyBIb2xpZGF5IGFuZCBWb2xhdGlsaXR5CgoqKldoeSB0aGlzIG1hdHRlcnMqKgoKVGhlIENFT+KAmXMgY29uY2VybiBpcyBub3Qgb25seSBhYm91dCBzYWxlcyBsZXZlbHMsIGJ1dCBhbHNvIGFib3V0IGluc3RhYmlsaXR5LgpXZSB0aGVyZWZvcmUgY29tcGFyZSB2b2xhdGlsaXR5IGFjcm9zcyBob2xpZGF5IGFuZCBub24taG9saWRheSB3ZWVrcy4KCmBgYHtyIHN0ZXAzLjR9CiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgU1RFUCAzLjQg4oCTIFZvbGF0aWxpdHkgY29tcGFyaXNvbgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKaG9saWRheV92b2xhdGlsaXR5IDwtIHdhbG1hcnQgJT4lCiAgZ3JvdXBfYnkoSG9saWRheV9GbGFnKSAlPiUKICBzdW1tYXJpc2UoCiAgICBzZF93ZWVrbHlfc2FsZXMgPSBzZChXZWVrbHlfU2FsZXMsIG5hLnJtID0gVFJVRSksCiAgICAuZ3JvdXBzID0gImRyb3AiCiAgKQoKaG9saWRheV92b2xhdGlsaXR5CgpgYGAKCj5UaGUgdm9sYXRpbGl0eSBjb21wYXJpc29uIHJldmVhbHMgdGhhdCBob2xpZGF5IHdlZWtzIGFyZSBhc3NvY2lhdGVkIHdpdGggYSBkaWZmZXJlbnQgbGV2ZWwgb2Ygc2FsZXMgdmFyaWFiaWxpdHkgY29tcGFyZWQgdG8gbm9uLWhvbGlkYXkgcGVyaW9kcy4gVGhpcyBzdWdnZXN0cyB0aGF0IGhvbGlkYXlzIG1heSBjb250cmlidXRlIG5vdCBvbmx5IHRvIGhpZ2hlciBhdmVyYWdlIHNhbGVzLCBidXQgYWxzbyB0byBpbmNyZWFzZWQgdW5jZXJ0YWludHkgaW4gd2Vla2x5IHBlcmZvcm1hbmNlLiBTdWNoIGEgcGF0dGVybiBpcyBjb25zaXN0ZW50IHdpdGggZGVtYW5kIHNwaWtlcyB0aGF0IGFyZSB1bmV2ZW5seSBkaXN0cmlidXRlZCBhY3Jvc3Mgc3RvcmVzIGFuZCBwcm9kdWN0IGNhdGVnb3JpZXMuCgojIyBab29tLWluOiBNYWpvciBIb2xpZGF5IFdlZWtzIChCbGFjayBGcmlkYXnigJNzdHlsZSBJbnNpZ2h0KQoKV2hpbGUgdGhlIGJpbmFyeSBob2xpZGF5IGZsYWcgY2FwdHVyZXMgd2hldGhlciBhIHdlZWsgaXMgY2xhc3NpZmllZCBhcyBhIGhvbGlkYXksIGl0IGRvZXMgbm90IGRpc3Rpbmd1aXNoIGJldHdlZW4gcm91dGluZSBob2xpZGF5cyBhbmQgcGVhayBkZW1hbmQgZXZlbnRzIHN1Y2ggYXMgbWFqb3Igc2hvcHBpbmcgcGVyaW9kcy4gVG8gYmV0dGVyIHVuZGVyc3RhbmQgdGhpcyBsaW1pdGF0aW9uLCB3ZSBleGFtaW5lIHdlZWtseSBzYWxlcyBwYXR0ZXJucyBhcm91bmQgdGhlIG1vc3QgcHJvbWluZW50IGhvbGlkYXkgcGVyaW9kcy4KCmBgYHtyIHN0ZXAzLjV9CmdncGxvdCh3YWxtYXJ0LCBhZXMoeCA9IERhdGUsIHkgPSBXZWVrbHlfU2FsZXMpKSArCiAgZ2VvbV9saW5lKGFscGhhID0gMC4zKSArCiAgZ2VvbV9wb2ludCgKICAgIGRhdGEgPSB3YWxtYXJ0ICU+JSBmaWx0ZXIoSG9saWRheV9GbGFnID09IDEpLAogICAgYWVzKHggPSBEYXRlLCB5ID0gV2Vla2x5X1NhbGVzKSwKICAgIGNvbG9yID0gInJlZCIsCiAgICBhbHBoYSA9IDAuNgogICkgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBjb21tYSkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJXZWVrbHkgU2FsZXMgT3ZlciBUaW1lIHdpdGggSG9saWRheSBXZWVrcyBIaWdobGlnaHRlZCIsCiAgICB4ID0gIkRhdGUiLAogICAgeSA9ICJXZWVrbHkgU2FsZXMiCiAgKQoKCmBgYAoKPlRoZSB0aW1lLXNlcmllcyB2aXN1YWxpemF0aW9uIHJldmVhbHMgdGhhdCBob2xpZGF5IHdlZWtzIGFyZSBhc3NvY2lhdGVkIHdpdGggbm90aWNlYWJsZSBzYWxlcyBzcGlrZXMsIGJ1dCB0aGVzZSBzcGlrZXMgYXJlICoqbm90IHVuaWZvcm0gYWNyb3NzIGFsbCBob2xpZGF5IHBlcmlvZHMuKiogV2hpbGUgc29tZSBob2xpZGF5IHdlZWtzIGNvcnJlc3BvbmQgdG8gZXhjZXB0aW9uYWxseSBoaWdoIHNhbGVzIGxldmVscywgb3RoZXJzIHJlbWFpbiBjbG9zZSB0byB0aGUgYmFzZWxpbmUgb2JzZXJ2ZWQgZHVyaW5nIHJlZ3VsYXIgd2Vla3MuIFRoaXMgaGV0ZXJvZ2VuZWl0eSBpbmRpY2F0ZXMgdGhhdCB0aGUgYmluYXJ5IGhvbGlkYXkgaW5kaWNhdG9yIGFnZ3JlZ2F0ZXMgZXZlbnRzIHdpdGggc3Vic3RhbnRpYWxseSBkaWZmZXJlbnQgZGVtYW5kIGludGVuc2l0aWVzLiBBcyBhIHJlc3VsdCwgdHJlYXRpbmcgYWxsIGhvbGlkYXkgd2Vla3MgYXMgZWNvbm9taWNhbGx5IGVxdWl2YWxlbnQgbWF5IG9ic2N1cmUgaW1wb3J0YW50IHZhcmlhdGlvbiBpbiBzYWxlcyByZXNwb25zZXMuCgpgYGB7ciBzdGVwfQpnZ3Bsb3QoCiAgd2FsbWFydCAlPiUgZmlsdGVyKEhvbGlkYXlfRmxhZyA9PSAxKSwKICBhZXMoeCA9IFdlZWtseV9TYWxlcykKKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDMwLCBmaWxsID0gImdyZXkiLCBjb2xvciA9ICJ3aGl0ZSIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gY29tbWEpICsKICBsYWJzKAogICAgdGl0bGUgPSAiRGlzdHJpYnV0aW9uIG9mIFdlZWtseSBTYWxlcyBEdXJpbmcgSG9saWRheSBXZWVrcyIsCiAgICB4ID0gIldlZWtseSBTYWxlcyIsCiAgICB5ID0gIkZyZXF1ZW5jeSIKICApCgpgYGAKCj5UaGUgZGlzdHJpYnV0aW9uIG9mIHdlZWtseSBzYWxlcyBkdXJpbmcgaG9saWRheSB3ZWVrcyBpcyBoaWdobHkgZGlzcGVyc2VkIGFuZCByaWdodC1za2V3ZWQsIHdpdGggYSBsb25nIHVwcGVyIHRhaWwgZXh0ZW5kaW5nIHRvd2FyZCB2ZXJ5IGhpZ2ggc2FsZXMgdmFsdWVzLiBUaGlzIHBhdHRlcm4gc3VnZ2VzdHMgdGhhdCBhIHN1YnNldCBvZiBob2xpZGF5IHBlcmlvZHMgZ2VuZXJhdGVzIGRpc3Byb3BvcnRpb25hdGVseSBsYXJnZSBzYWxlcyBvdXRjb21lcywgd2hpbGUgbWFueSBob2xpZGF5IHdlZWtzIGV4aGliaXQgbW9yZSBtb2RlcmF0ZSBwZXJmb3JtYW5jZS4gU3VjaCBkaXNwZXJzaW9uIHJlaW5mb3JjZXMgdGhlIGxpbWl0YXRpb24gb2YgYSBzaW1wbGUgaG9saWRheSBmbGFnIGFuZCBoaWdobGlnaHRzIHRoZSBuZWVkIGZvciBtb2RlbHMgdGhhdCBjYW4gZGlzdGluZ3Vpc2ggYmV0d2VlbiByb3V0aW5lIGhvbGlkYXlzIGFuZCBwZWFrIGRlbWFuZCBldmVudHMuCgojIyBTdGVwIDMgU3VtbWFyeTogV2hhdCBIb2xpZGF5cyBFeHBsYWluIOKAlCBhbmQgV2hhdCBUaGV5IERvbuKAmXQKClRoZSBleHRlbmRlZCBob2xpZGF5IGFuYWx5c2lzIGRlbW9uc3RyYXRlcyB0aGF0IGhvbGlkYXkgcGVyaW9kcyBhcmUgZ2VuZXJhbGx5IGFzc29jaWF0ZWQgd2l0aCBoaWdoZXIgYXZlcmFnZSBzYWxlcyBhbmQgaW5jcmVhc2VkIHZhcmlhYmlsaXR5IGluIHdlZWtseSBwZXJmb3JtYW5jZS4gSG93ZXZlciwgdGhlIHRpbWUtc2VyaWVzIGFuZCBkaXN0cmlidXRpb25hbCBldmlkZW5jZSBzaG93cyB0aGF0IGhvbGlkYXkgZWZmZWN0cyBhcmUgaGlnaGx5IGhldGVyb2dlbmVvdXM6IG9ubHkgYSBzdWJzZXQgb2YgaG9saWRheSB3ZWVrcyBnZW5lcmF0ZXMgZXh0cmVtZSBzYWxlcyBzcGlrZXMsIHdoaWxlIG90aGVycyByZXNlbWJsZSBub24taG9saWRheSBwZXJpb2RzLiBUaGlzIGZpbmRpbmcgY29uZmlybXMgdGhhdCBhIGJpbmFyeSBob2xpZGF5IGluZGljYXRvciBwcm92aWRlcyBhbiBpbmNvbXBsZXRlIHJlcHJlc2VudGF0aW9uIG9mIGhvbGlkYXktZHJpdmVuIGRlbWFuZC4gQ29uc2VxdWVudGx5LCB3aGlsZSBob2xpZGF5cyBwbGF5IGFuIGltcG9ydGFudCByb2xlIGluIGV4cGxhaW5pbmcgc2FsZXMgZmx1Y3R1YXRpb25zLCB0aGV5IGNhbm5vdCBmdWxseSBhY2NvdW50IGZvciBvYnNlcnZlZCBwYXR0ZXJucyBpbiBzYWxlcyBjb25jZW50cmF0aW9uIGFuZCB2b2xhdGlsaXR5LiBUaGlzIG1vdGl2YXRlcyB0aGUgdXNlIG9mIG11bHRpdmFyaWF0ZSByZWdyZXNzaW9uIG1vZGVscyB0aGF0IGluY29ycG9yYXRlIHRpbWUgdHJlbmRzLCBtYWNyb2Vjb25vbWljIHZhcmlhYmxlcywgYW5kIHN0b3JlLWxldmVsIGhldGVyb2dlbmVpdHkgdG8gZGlzZW50YW5nbGUgb3ZlcmxhcHBpbmcgZWZmZWN0cy4KCiMgU1RFUCA0IOKAlCBSZWdyZXNzaW9uIEFuYWx5c2lzOiBXaGF0IERyaXZlcyBXZWVrbHkgU2FsZXM/CgoqKlN0ZXBzIDIgYW5kIDMqKiBkZW1vbnN0cmF0ZWQgdGhhdCBzYWxlcyBhbmQgdm9sYXRpbGl0eSBhcmUgdW5ldmVubHkgZGlzdHJpYnV0ZWQgYWNyb3NzIHN0b3JlcyBhbmQgdGhhdCBob2xpZGF5IGVmZmVjdHMgYXJlIGhldGVyb2dlbmVvdXMuIEhvd2V2ZXIsIGRlc2NyaXB0aXZlIGFuYWx5c2lzIGFsb25lIGNhbm5vdCBpc29sYXRlIHRoZSByZWxhdGl2ZSBpbXBvcnRhbmNlIG9mIGhvbGlkYXlzLCB0aW1lIHRyZW5kcywgYW5kIG1hY3JvZWNvbm9taWMgY29uZGl0aW9ucy4gVGhlcmVmb3JlLCB0aGlzIHN0ZXAgZW1wbG95cyByZWdyZXNzaW9uIG1vZGVscyB0byBxdWFudGlmeSB0aGUgZHJpdmVycyBvZiB3ZWVrbHkgc2FsZXMgd2hpbGUgY29udHJvbGxpbmcgZm9yIG92ZXJsYXBwaW5nIGVmZmVjdHMuIFRoZSBvYmplY3RpdmUgaXMgbm90IHByZWRpY3Rpb24gYWNjdXJhY3ksIGJ1dCAqKmV4cGxhbmF0b3J5IGNsYXJpdHkqKiBmb3IgbWFuYWdlcmlhbCBkZWNpc2lvbi1tYWtpbmcuCgojIyBNb2RlbCAxIOKAlCBCYXNlbGluZTogSG9saWRheSBFZmZlY3QgT25seQoKKipXaHkgdGhpcyBtb2RlbD8qKgoKV2UgYmVnaW4gd2l0aCB0aGUgc2ltcGxlc3QgcG9zc2libGUgc3BlY2lmaWNhdGlvbiB0byBlc3RhYmxpc2ggYSBiZW5jaG1hcmsuClRoaXMgbW9kZWwgYW5zd2VycyB0aGUgcXVlc3Rpb246IElmIHdlIG9ubHkgY29uc2lkZXIgd2hldGhlciBhIHdlZWsgaXMgYSBob2xpZGF5LCBob3cgbXVjaCBkb2VzIHRoYXQgZXhwbGFpbiBzYWxlcz8KCmBgYHtyIHN0ZXA0LjF9CiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgU1RFUCA0LjEg4oCTIE1vZGVsIDE6IEhvbGlkYXkgb25seQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKbW9kZWxfMSA8LSBsbShXZWVrbHlfU2FsZXMgfiBIb2xpZGF5X0ZsYWcsIGRhdGEgPSB3YWxtYXJ0KQoKc3VtbWFyeShtb2RlbF8xKQoKYGBgCgoKLSBIb2xpZGF5IGNvZWZmaWNpZW50IOKJiCAqKis4MSw2MDAqKgoKLSBTdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50ICoqKHAg4omIIDAuMDAzKSoqCgotIFLCsiDiiYggKiowLjAwMTQqKgoKPlRoZSBiYXNlbGluZSByZWdyZXNzaW9uIHNob3dzIHRoYXQgaG9saWRheSB3ZWVrcyBhcmUgYXNzb2NpYXRlZCB3aXRoIGFuIGF2ZXJhZ2UgaW5jcmVhc2Ugb2YgYXBwcm94aW1hdGVseSA4MSw2MDAgaW4gd2Vla2x5IHNhbGVzIHJlbGF0aXZlIHRvIG5vbi1ob2xpZGF5IHdlZWtzLCBhbmQgdGhpcyBlZmZlY3QgaXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4gSG93ZXZlciwgdGhlIG1vZGVs4oCZcyBleHBsYW5hdG9yeSBwb3dlciBpcyBleHRyZW1lbHkgbGltaXRlZCwgd2l0aCBhbiBSLXNxdWFyZWQgdmFsdWUgY2xvc2UgdG8gemVyby4gVGhpcyBpbmRpY2F0ZXMgdGhhdCBhbHRob3VnaCBob2xpZGF5cyBhcmUgYXNzb2NpYXRlZCB3aXRoIGhpZ2hlciBzYWxlcyBvbiBhdmVyYWdlLCB0aGV5IGV4cGxhaW4gb25seSBhIG5lZ2xpZ2libGUgZnJhY3Rpb24gb2YgdGhlIG92ZXJhbGwgdmFyaWF0aW9uIGluIHdlZWtseSBzYWxlcy4gQ29uc2VxdWVudGx5LCBob2xpZGF5IGVmZmVjdHMgYWxvbmUgYXJlIGluc3VmZmljaWVudCB0byB1bmRlcnN0YW5kIFdhbG1hcnTigJlzIHNhbGVzIGR5bmFtaWNzLgoKIyMgTW9kZWwgMiDigJQgQWRkaW5nIFRpbWUgU3RydWN0dXJlIChUcmVuZCAmIFNlYXNvbmFsaXR5KQoKKipXaHkgYWRkIHRpbWU/KioKClNhbGVzIG5hdHVyYWxseSBldm9sdmUgb3ZlciB0aW1lIGR1ZSB0byBpbmZsYXRpb24sIHN0b3JlIG1hdHVyaXR5LCBhbmQgc2Vhc29uYWxpdHkuCklnbm9yaW5nIHRpbWUgZWZmZWN0cyByaXNrcyBhdHRyaWJ1dGluZyBsb25nLXRlcm0gdHJlbmRzIHRvIGhvbGlkYXlzLgoKYGBge3Igc3RlcDQuMn0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBTVEVQIDQuMiDigJMgTW9kZWwgMjogSG9saWRheSArIHRpbWUgZWZmZWN0cwojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKbW9kZWxfMiA8LSBsbSgKICBXZWVrbHlfU2FsZXMgfiBIb2xpZGF5X0ZsYWcgKyBZZWFyICsgTW9udGgsCiAgZGF0YSA9IHdhbG1hcnQKKQoKc3VtbWFyeShtb2RlbF8yKQoKYGBgCgotIEhvbGlkYXlfRmxhZyDihpIgbm90IG1lYW5pbmdmdWwgc3RhdGlzdGljYWxseQoKLSBZZWFyIOKGkiBub3QgbWVhbmluZ2Z1bAoKLSBNb250aCBlZmZlY3RzIOKGkiBzdHJvbmcKCi0gUsKyIOKJiCAwLjAxOQoKPkFmdGVyIGNvbnRyb2xsaW5nIGZvciB0aW1lIGVmZmVjdHMsIHRoZSBlc3RpbWF0ZWQgaG9saWRheSBjb2VmZmljaWVudCBiZWNvbWVzIHN0YXRpc3RpY2FsbHkgaW5zaWduaWZpY2FudCwgc3VnZ2VzdGluZyB0aGF0IHBhcnQgb2YgdGhlIGFwcGFyZW50IGhvbGlkYXkgZWZmZWN0IG9ic2VydmVkIGluIHRoZSBiYXNlbGluZSBtb2RlbCB3YXMgY2FwdHVyaW5nIHVuZGVybHlpbmcgc2Vhc29uYWwgcGF0dGVybnMuIFNldmVyYWwgbW9udGggaW5kaWNhdG9ycyBhcmUgaGlnaGx5IHNpZ25pZmljYW50LCBoaWdobGlnaHRpbmcgc3Ryb25nIHNlYXNvbmFsaXR5IGluIHdlZWtseSBzYWxlcy4gQWx0aG91Z2ggdGhlIG92ZXJhbGwgZXhwbGFuYXRvcnkgcG93ZXIgcmVtYWlucyBtb2Rlc3QsIHRoZSBpbmNyZWFzZSBpbiBSLXNxdWFyZWQgcmVsYXRpdmUgdG8gdGhlIGJhc2VsaW5lIG1vZGVsIGRlbW9uc3RyYXRlcyB0aGF0IHRlbXBvcmFsIHN0cnVjdHVyZSBwbGF5cyBhIHN1YnN0YW50aWFsbHkgbW9yZSBpbXBvcnRhbnQgcm9sZSB0aGFuIGhvbGlkYXlzIGFsb25lLgoKIyMgTW9kZWwgMyDigJQgRnVsbCBNb2RlbDogSG9saWRheSArIFRpbWUgKyBNYWNyb2Vjb25vbWljIEZhY3RvcnMKCioqV2h5IG1hY3JvIHZhcmlhYmxlcz8qKgoKQ29uc3VtZXIgc3BlbmRpbmcgaXMgaW5mbHVlbmNlZCBieSBicm9hZGVyIGVjb25vbWljIGNvbmRpdGlvbnMuClRoaXMgbW9kZWwgZXZhbHVhdGVzIHdoZXRoZXIgc2FsZXMgcmVzcG9uZCB0byBDUEksIHVuZW1wbG95bWVudCwgZnVlbCBwcmljZXMsIGFuZCB3ZWF0aGVyLCBiZXlvbmQgaG9saWRheXMgYW5kIHRpbWUuCgpgYGB7ciBzdGVwNC4zfQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFNURVAgNC4zIOKAkyBNb2RlbCAzOiBGdWxsIGV4cGxhbmF0b3J5IG1vZGVsCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgptb2RlbF8zIDwtIGxtKAogIFdlZWtseV9TYWxlcyB+IEhvbGlkYXlfRmxhZyArIFllYXIgKyBNb250aCArCiAgICBUZW1wZXJhdHVyZSArIEZ1ZWxfUHJpY2UgKyBDUEkgKyBVbmVtcGxveW1lbnQsCiAgZGF0YSA9IHdhbG1hcnQKKQoKc3VtbWFyeShtb2RlbF8zKQoKYGBgCgotIEhvbGlkYXlfRmxhZyDihpIgc3RpbGwgbm90IG1lYW5pbmdmdWwKCi0gWWVhciDihpIgbmVnYXRpdmUgYW5kIG1lYW5pbmdmdWwKCi0gQ1BJIOKGkiBuZWdhdGl2ZSBhbmQgdmVyeSBzdHJvbmcKCi0gVW5lbXBsb3ltZW50IOKGkiBuZWdhdGl2ZSBhbmQgdmVyeSBzdHJvbmcKCi0gRnVlbF9QcmljZSDihpIgcG9zaXRpdmUgYW5kIG1lYW5pbmdmdWwKCi0gVGVtcGVyYXR1cmUg4oaSIG5vdCBtZWFuaW5nZnVsCgotIFLCsiDiiYggMC4wNDQKCgo+VGhlIGZ1bGwgbW9kZWwgcHJvdmlkZXMgdGhlIGhpZ2hlc3QgZXhwbGFuYXRvcnkgcG93ZXIgYW1vbmcgYWxsIHNwZWNpZmljYXRpb25zLCBpbmRpY2F0aW5nIHRoYXQgd2Vla2x5IHNhbGVzIGFyZSBpbmZsdWVuY2VkIGJ5IGEgY29tYmluYXRpb24gb2YgdGVtcG9yYWwgYW5kIG1hY3JvZWNvbm9taWMgZmFjdG9ycy4gT25jZSB0aGVzZSB2YXJpYWJsZXMgYXJlIGluY2x1ZGVkLCB0aGUgaG9saWRheSBpbmRpY2F0b3IgcmVtYWlucyBzdGF0aXN0aWNhbGx5IGluc2lnbmlmaWNhbnQsIGNvbmZpcm1pbmcgdGhhdCBob2xpZGF5cyBkbyBub3QgaW5kZXBlbmRlbnRseSBkcml2ZSBzYWxlcyB3aGVuIGJyb2FkZXIgZWNvbm9taWMgY29uZGl0aW9ucyBhcmUgdGFrZW4gaW50byBhY2NvdW50LiBJbiBjb250cmFzdCwgdW5lbXBsb3ltZW50IGFuZCBDUEkgZXhoaWJpdCBzdHJvbmcgbmVnYXRpdmUgcmVsYXRpb25zaGlwcyB3aXRoIHNhbGVzLCBzdWdnZXN0aW5nIHRoYXQgbWFjcm9lY29ub21pYyBwcmVzc3VyZSBzaWduaWZpY2FudGx5IGRhbXBlbnMgY29uc3VtZXIgc3BlbmRpbmcuIFRoZSBwb3NpdGl2ZSBjb2VmZmljaWVudCBvbiBmdWVsIHByaWNlcyBtYXkgcmVmbGVjdCBjb3JyZWxhdGVkIGVjb25vbWljIGFjdGl2aXR5IHJhdGhlciB0aGFuIGEgZGlyZWN0IGNhdXNhbCBlZmZlY3QuIE92ZXJhbGwsIHRoZXNlIHJlc3VsdHMgaW5kaWNhdGUgdGhhdCBtYWNyb2Vjb25vbWljIGNvbmRpdGlvbnMgZG9taW5hdGUgaG9saWRheSB0aW1pbmcgaW4gZXhwbGFpbmluZyBzYWxlcyB2YXJpYXRpb24uCgojIyBDb21wYXJpbmcgTW9kZWxzOiBXaGF0IFJlYWxseSBBZGRzIFZhbHVlPwoKYGBge3Igc3RlcDQuNH0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBTVEVQIDQuNCDigJMgTW9kZWwgY29tcGFyaXNvbgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKbW9kZWxfY29tcGFyaXNvbiA8LSB0aWJibGUoCiAgTW9kZWwgPSBjKCJIb2xpZGF5IG9ubHkiLCAiSG9saWRheSArIFRpbWUiLCAiRnVsbCBNb2RlbCIpLAogIFJfc3F1YXJlZCA9IGMoCiAgICBzdW1tYXJ5KG1vZGVsXzEpJHIuc3F1YXJlZCwKICAgIHN1bW1hcnkobW9kZWxfMikkci5zcXVhcmVkLAogICAgc3VtbWFyeShtb2RlbF8zKSRyLnNxdWFyZWQKICApCikKCm1vZGVsX2NvbXBhcmlzb24KCgpgYGAKCioqQWN0dWFsIFLCsiB2YWx1ZXM6KioKCi0gSG9saWRheSBvbmx5IOKGkiAqKjAuMDAxKioKCi0gSG9saWRheSArIFRpbWUg4oaSICoqMC4wMTkqKgoKLSBGdWxsIE1vZGVsIOKGkiAqKjAuMDQ0KioKCgo+TW9kZWwgY29tcGFyaXNvbiByZXZlYWxzIGEgY2xlYXIgaGllcmFyY2h5IGluIGV4cGxhbmF0b3J5IHBvd2VyLiBUaGUgaG9saWRheS1vbmx5IG1vZGVsIGV4cGxhaW5zIHZpcnR1YWxseSBub25lIG9mIHRoZSB2YXJpYXRpb24gaW4gd2Vla2x5IHNhbGVzLiBJbnRyb2R1Y2luZyB0aW1lIGVmZmVjdHMgc3Vic3RhbnRpYWxseSBpbXByb3ZlcyBtb2RlbCBwZXJmb3JtYW5jZSwgd2hpbGUgdGhlIGluY2x1c2lvbiBvZiBtYWNyb2Vjb25vbWljIHZhcmlhYmxlcyBmdXJ0aGVyIGRvdWJsZXMgZXhwbGFuYXRvcnkgcG93ZXIuIERlc3BpdGUgdGhpcyBpbXByb3ZlbWVudCwgdGhlIHJlbGF0aXZlbHkgbG93IFItc3F1YXJlZCB2YWx1ZXMgYWNyb3NzIGFsbCBtb2RlbHMgaW5kaWNhdGUgdGhhdCBhIHNpZ25pZmljYW50IHBvcnRpb24gb2Ygc2FsZXMgdmFyaWF0aW9uIHJlbWFpbnMgc3RvcmUtc3BlY2lmaWMgb3IgaWRpb3N5bmNyYXRpYywgcmVpbmZvcmNpbmcgdGhlIGltcG9ydGFuY2Ugb2Ygc3RvcmUtbGV2ZWwgc2VnbWVudGF0aW9uIGluIHN1YnNlcXVlbnQgYW5hbHlzaXMuCgoKIyMgU3RlcCA0IEV4ZWN1dGl2ZSBTdW1tYXJ5Cgo+VGhlIHJlZ3Jlc3Npb24gYW5hbHlzaXMgZGVtb25zdHJhdGVzIHRoYXQgd2hpbGUgaG9saWRheSB3ZWVrcyBhcmUgYXNzb2NpYXRlZCB3aXRoIGhpZ2hlciBzYWxlcyBpbiBpc29sYXRpb24sIHRoaXMgZWZmZWN0IGRpc2FwcGVhcnMgb25jZSB0aW1lIHN0cnVjdHVyZSBhbmQgbWFjcm9lY29ub21pYyBjb25kaXRpb25zIGFyZSBhY2NvdW50ZWQgZm9yLiBTZWFzb25hbGl0eSBhbmQgYnJvYWRlciBlY29ub21pYyBpbmRpY2F0b3JzLCBwYXJ0aWN1bGFybHkgdW5lbXBsb3ltZW50IGFuZCBpbmZsYXRpb24sIHBsYXkgYSBmYXIgbW9yZSBzaWduaWZpY2FudCByb2xlIGluIHNoYXBpbmcgd2Vla2x5IHNhbGVzIHBhdHRlcm5zLiBUaGVzZSBmaW5kaW5ncyBzdWdnZXN0IHRoYXQgbWFuYWdlcmlhbCBkZWNpc2lvbnMgZm9jdXNlZCBzb2xlbHkgb24gaG9saWRheSB0aW1pbmcgbWF5IGJlIG1pc2d1aWRlZCB1bmxlc3MgdGhleSBhcmUgYWxpZ25lZCB3aXRoIHByZXZhaWxpbmcgZWNvbm9taWMgY29uZGl0aW9ucy4gRnVydGhlcm1vcmUsIHRoZSBsaW1pdGVkIGV4cGxhbmF0b3J5IHBvd2VyIG9mIGFnZ3JlZ2F0ZSBtb2RlbHMgaGlnaGxpZ2h0cyB0aGUgbmVlZCB0byBpbmNvcnBvcmF0ZSBzdG9yZS1sZXZlbCBoZXRlcm9nZW5laXR5LCBtb3RpdmF0aW5nIGEgc2VnbWVudGF0aW9uLWJhc2VkIGFwcHJvYWNoIGluIHRoZSBuZXh0IHN0ZXAuCgojIFNURVAgNSDigJQgU3RvcmUgU2VnbWVudGF0aW9uIChLLU1lYW5zIENsdXN0ZXJpbmcpIAoKQWx0aG91Z2ggcmVncmVzc2lvbiBtb2RlbHMgY2FwdHVyZSBnZW5lcmFsIHBhdHRlcm5zLCB0aGV5IGV4cGxhaW4gb25seSBhIGxpbWl0ZWQgcG9ydGlvbiBvZiB3ZWVrbHkgc2FsZXMgdmFyaWF0aW9uLCBzdWdnZXN0aW5nIHRoYXQgc3RvcmUtbGV2ZWwgZGlmZmVyZW5jZXMgcGxheSBhIG1ham9yIHJvbGUuIFRoZXJlZm9yZSwgd2Ugc2VnbWVudCBzdG9yZXMgaW50byBtZWFuaW5nZnVsIGdyb3VwcyB1c2luZyBrLW1lYW5zIGNsdXN0ZXJpbmcuIFRoZSBvYmplY3RpdmUgaXMgdG8gY3JlYXRlIGFjdGlvbmFibGUgc3RvcmUgc2VnbWVudHMgKGUuZy4sIOKAnGhpZ2ggc2FsZXPigJNzdGFibGXigJ0gdnMuIOKAnGhpZ2ggdm9sYXRpbGl0eeKAnSkgdGhhdCBjYW4gc3VwcG9ydCBkaWZmZXJlbnRpYXRlZCBtYW5hZ2VyaWFsIHN0cmF0ZWdpZXMgZm9yIHBsYW5uaW5nLCByZXNvdXJjZSBhbGxvY2F0aW9uLCBhbmQgcHJvbW90aW9uIGRlc2lnbi4KCiMjIENyZWF0ZSBTdG9yZS1MZXZlbCBGZWF0dXJlcyBmb3IgQ2x1c3RlcmluZwoKKipXaGF0IHdlIGluY2x1ZGUqKgoKV2UgYnVpbGQgYSBzdG9yZS1sZXZlbCBkYXRhc2V0IHdpdGggZmVhdHVyZXMgdGhhdCBjYXB0dXJlOgoKLSAqKlNhbGVzIGxldmVsKiogKGF2ZXJhZ2Ugd2Vla2x5IHNhbGVzKQoKLSAqKlNhbGVzIHZvbGF0aWxpdHkqKiAoQ1Ygb3IgU0QpCgotICoqSG9saWRheSBzZW5zaXRpdml0eSoqIChob2xpZGF5IGxpZnQgYXQgc3RvcmUgbGV2ZWwpCgpgYGB7ciBzdGVwNS4xfQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFNURVAgNS4xIOKAkyBTdG9yZS1sZXZlbCBkYXRhc2V0IGZvciBjbHVzdGVyaW5nCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzdG9yZV9jbHVzdGVyX2RmIDwtIHdhbG1hcnQgJT4lCiAgZ3JvdXBfYnkoU3RvcmUpICU+JQogIHN1bW1hcmlzZSgKICAgIGF2Z19zYWxlcyA9IG1lYW4oV2Vla2x5X1NhbGVzLCBuYS5ybSA9IFRSVUUpLAogICAgc2Rfc2FsZXMgID0gc2QoV2Vla2x5X1NhbGVzLCBuYS5ybSA9IFRSVUUpLAogICAgY3Zfc2FsZXMgID0gc2Rfc2FsZXMgLyBhdmdfc2FsZXMsCiAgICAKICAgICMgSG9saWRheSBzZW5zaXRpdml0eTogZGlmZmVyZW5jZSBiZXR3ZWVuIGhvbGlkYXkgYW5kIG5vbi1ob2xpZGF5IG1lYW4gc2FsZXMgcGVyIHN0b3JlCiAgICBob2xpZGF5X21lYW4gPSBtZWFuKFdlZWtseV9TYWxlc1tIb2xpZGF5X0ZsYWcgPT0gMV0sIG5hLnJtID0gVFJVRSksCiAgICBub25ob2xpZGF5X21lYW4gPSBtZWFuKFdlZWtseV9TYWxlc1tIb2xpZGF5X0ZsYWcgPT0gMF0sIG5hLnJtID0gVFJVRSksCiAgICBob2xpZGF5X2xpZnRfcGN0ID0gKGhvbGlkYXlfbWVhbiAtIG5vbmhvbGlkYXlfbWVhbikgLyBub25ob2xpZGF5X21lYW4gKiAxMDAsCiAgICAKICAgIC5ncm91cHMgPSAiZHJvcCIKICApCgojIENoZWNrIGZvciBpbmZpbml0ZSAvIE5BIGxpZnQgdmFsdWVzIChjYW4gaGFwcGVuIGlmIGEgc3RvcmUgaGFzIG5vIG5vbi1ob2xpZGF5IHdlZWtzKQpzdG9yZV9jbHVzdGVyX2RmIDwtIHN0b3JlX2NsdXN0ZXJfZGYgJT4lCiAgbXV0YXRlKAogICAgaG9saWRheV9saWZ0X3BjdCA9IGlmZWxzZShpcy5maW5pdGUoaG9saWRheV9saWZ0X3BjdCksIGhvbGlkYXlfbGlmdF9wY3QsIE5BX3JlYWxfKQogICkKCnN1bW1hcnkoc3RvcmVfY2x1c3Rlcl9kZikKCmBgYAoKPlRoaXMgZmVhdHVyZSBlbmdpbmVlcmluZyBzdGVwIHRyYW5zbGF0ZXMgdGhlIHdlZWtseSBkYXRhc2V0IGludG8gYSBzdG9yZS1sZXZlbCBhbmFseXRpYyB2aWV3LiBJbiBhZGRpdGlvbiB0byBzYWxlcyBsZXZlbCBhbmQgdm9sYXRpbGl0eSwgd2UgZXhwbGljaXRseSBpbmNsdWRlIGhvbGlkYXkgc2Vuc2l0aXZpdHkgYXMgYSBiZWhhdmlvcmFsIGZlYXR1cmUuIFRoaXMgZW5zdXJlcyB0aGF0IHNlZ21lbnRhdGlvbiBpcyBub3QgYmFzZWQgc29sZWx5IG9uIHN0b3JlIHNpemUsIGJ1dCBhbHNvIGNhcHR1cmVzIGhvdyBzdG9yZXMgcmVzcG9uZCB0byBwZWFrLWRlbWFuZCBwZXJpb2RzLgoKIyMgUHJlcGFyZSBEYXRhIGZvciBLLU1lYW5zIChTY2FsaW5nKQoKSy1tZWFucyBpcyBkaXN0YW5jZS1iYXNlZCwgc28gdmFyaWFibGVzIHdpdGggbGFyZ2Ugc2NhbGVzIGRvbWluYXRlIHJlc3VsdHMuClRoZXJlZm9yZSwgd2Ugc3RhbmRhcmRpemUgdmFyaWFibGVzIGJlZm9yZSBjbHVzdGVyaW5nLgoKYGBge3Igc3RlcDUuMn0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBTVEVQIDUuMiDigJMgU2NhbGUgdmFyaWFibGVzIGZvciBrLW1lYW5zCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpjbHVzdGVyX2ZlYXR1cmVzIDwtIHN0b3JlX2NsdXN0ZXJfZGYgJT4lCiAgc2VsZWN0KGF2Z19zYWxlcywgY3Zfc2FsZXMsIGhvbGlkYXlfbGlmdF9wY3QpICU+JQogIGRyb3BfbmEoKSAgIyByZW1vdmUgc3RvcmVzIHdpdGggbWlzc2luZyBob2xpZGF5IGxpZnQKCmNsdXN0ZXJfc2NhbGVkIDwtIHNjYWxlKGNsdXN0ZXJfZmVhdHVyZXMpCgpgYGAKCj5TY2FsaW5nIGVuc3VyZXMgdGhhdCBhdmVyYWdlIHNhbGVzLCB2b2xhdGlsaXR5LCBhbmQgaG9saWRheSBzZW5zaXRpdml0eSBjb250cmlidXRlIGVxdWFsbHkgdG8gdGhlIGNsdXN0ZXJpbmcgc29sdXRpb24uIFdpdGhvdXQgc2NhbGluZywgYXZlcmFnZSBzYWxlcyB3b3VsZCBkb21pbmF0ZSB0aGUgc2VnbWVudGF0aW9uIGFuZCByZWR1Y2UgaW50ZXJwcmV0YWJpbGl0eS4KCiMjIENob29zZSB0aGUgTnVtYmVyIG9mIENsdXN0ZXJzIChFbGJvdyBNZXRob2QpCgpgYGB7ciBzdGVwNS4zfQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFNURVAgNS4zIOKAkyBFbGJvdyBtZXRob2QKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnNldC5zZWVkKDEyMykKCndzcyA8LSBtYXBfZGJsKDE6MTAsIGZ1bmN0aW9uKGspIHsKICBrbWVhbnMoY2x1c3Rlcl9zY2FsZWQsIGNlbnRlcnMgPSBrLCBuc3RhcnQgPSAyNSkkdG90LndpdGhpbnNzCn0pCgplbGJvd19kZiA8LSB0aWJibGUoayA9IDE6MTAsIHdzcyA9IHdzcykKCmdncGxvdChlbGJvd19kZiwgYWVzKHggPSBrLCB5ID0gd3NzKSkgKwogIGdlb21fbGluZSgpICsKICBnZW9tX3BvaW50KCkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJFbGJvdyBNZXRob2QgZm9yIENob29zaW5nIGsiLAogICAgeCA9ICJOdW1iZXIgb2YgY2x1c3RlcnMgKGspIiwKICAgIHkgPSAiVG90YWwgd2l0aGluLWNsdXN0ZXIgc3VtIG9mIHNxdWFyZXMiCiAgKQoKYGBgCgo+VGhlIGVsYm93IHBsb3Qgc2hvd3MgYSAqKnNoYXJwIHJlZHVjdGlvbioqIGluIHdpdGhpbi1jbHVzdGVyIHZhcmlhdGlvbiB1cCB0byB0aHJlZSBjbHVzdGVycywgYWZ0ZXIgd2hpY2ggdGhlIG1hcmdpbmFsIGltcHJvdmVtZW50IGJlY29tZXMgbm90aWNlYWJseSBzbWFsbGVyLiBUaGlzIGNsZWFyIOKAnGVsYm934oCdIGF0ICoqayA9IDMqKiBpbmRpY2F0ZXMgdGhhdCBhIHRocmVlLXNlZ21lbnQgc29sdXRpb24gcHJvdmlkZXMgYW4gYXBwcm9wcmlhdGUgYmFsYW5jZSBiZXR3ZWVuIGV4cGxhbmF0b3J5IHBvd2VyIGFuZCBpbnRlcnByZXRhYmlsaXR5LiBUaGVyZWZvcmUsIGsgPSAzIGlzIHNlbGVjdGVkIGZvciB0aGUgZmluYWwgY2x1c3RlcmluZyBhbmFseXNpcy4KCiMjIFJ1biBLLU1lYW5zIHdpdGggQ2hvc2VuIGsKCgpgYGB7ciBzdGVwNS40fQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFNURVAgNS40IOKAkyBLLW1lYW5zIGNsdXN0ZXJpbmcKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnNldC5zZWVkKDEyMykKayA8LSAzCgprbWVhbnNfbW9kZWwgPC0ga21lYW5zKGNsdXN0ZXJfc2NhbGVkLCBjZW50ZXJzID0gaywgbnN0YXJ0ID0gMjUpCgpzdG9yZV9jbHVzdGVyZWQgPC0gc3RvcmVfY2x1c3Rlcl9kZiAlPiUKICBkcm9wX25hKGhvbGlkYXlfbGlmdF9wY3QpICU+JQogIG11dGF0ZShTZWdtZW50ID0gZmFjdG9yKGttZWFuc19tb2RlbCRjbHVzdGVyKSkKCnN0b3JlX2NsdXN0ZXJlZCAlPiUgY291bnQoU2VnbWVudCkKCmBgYAoKIyMgU2VnbWVudCBQcm9maWxpbmcgKFdoYXQgRGlmZmVyZW50aWF0ZXMgU2VnbWVudHM/KQoKYGBge3Igc3RlcDUuNX0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBTVEVQIDUuNSDigJMgU2VnbWVudCBzdW1tYXJ5IHRhYmxlCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzZWdtZW50X3Byb2ZpbGUgPC0gc3RvcmVfY2x1c3RlcmVkICU+JQogIGdyb3VwX2J5KFNlZ21lbnQpICU+JQogIHN1bW1hcmlzZSgKICAgIG5fc3RvcmVzID0gbigpLAogICAgYXZnX3NhbGVzX21lYW4gPSBtZWFuKGF2Z19zYWxlcyksCiAgICBjdl9zYWxlc19tZWFuID0gbWVhbihjdl9zYWxlcyksCiAgICBob2xpZGF5X2xpZnRfbWVhbiA9IG1lYW4oaG9saWRheV9saWZ0X3BjdCksCiAgICAuZ3JvdXBzID0gImRyb3AiCiAgKQoKc2VnbWVudF9wcm9maWxlCmBgYAoKfCBTZWdtZW50ICAgICAgICAgICAgICAgICAgIHwgSW50ZXJwcmV0YXRpb24gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKfCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHwgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHwKfCAqKlNlZ21lbnQgMSAoOCBzdG9yZXMpKiogIHwgTG93IHNhbGVzIOKAkyB2ZXJ5IHN0YWJsZSDigJMgbmVnYXRpdmUgaG9saWRheSBsaWZ0ICAgICAgICAgICAgICB8CnwgKipTZWdtZW50IDIgKDE0IHN0b3JlcykqKiB8IE1pZCBzYWxlcyDigJMgaGlnaGx5IHZvbGF0aWxlIOKAkyBzdHJvbmdseSBob2xpZGF5LWRyaXZlbiAgICAgICAgfAp8ICoqU2VnbWVudCAzICgyMyBzdG9yZXMpKiogfCBIaWdoIHNhbGVzIOKAkyBtb2RlcmF0ZWx5IHZvbGF0aWxlIOKAkyBwb3NpdGl2ZSBob2xpZGF5IHJlc3BvbnNlIHwKCgo+VGhlIHNlZ21lbnRhdGlvbiByZXN1bHRzIHJldmVhbCB0aHJlZSBjbGVhcmx5IGRpZmZlcmVudGlhdGVkIHN0b3JlIHR5cGVzLiAKKipTZWdtZW50IDEqKiBjb25zaXN0cyBvZiBsb3ctc2FsZXMgYnV0IGhpZ2hseSBzdGFibGUgc3RvcmVzLCB3aXRoIGEgc2xpZ2h0bHkgbmVnYXRpdmUgYXZlcmFnZSBob2xpZGF5IGxpZnQsIGluZGljYXRpbmcgbGltaXRlZCByZXNwb25zaXZlbmVzcyB0byBob2xpZGF5IHBlcmlvZHMuIAoqKlNlZ21lbnQgMioqIGlzIGNoYXJhY3Rlcml6ZWQgYnkgbW9kZXJhdGUgc2FsZXMgbGV2ZWxzIGNvbWJpbmVkIHdpdGggdGhlIGhpZ2hlc3QgcmVsYXRpdmUgdm9sYXRpbGl0eSBhbmQgdGhlIHN0cm9uZ2VzdCBwb3NpdGl2ZSBob2xpZGF5IHJlc3BvbnNlLCBzdWdnZXN0aW5nIHRoYXQgZGVtYW5kIGluIHRoZXNlIHN0b3JlcyBpcyBib3RoIGV2ZW50LWRyaXZlbiBhbmQgdW5zdGFibGUuIAoqKlNlZ21lbnQgMyoqIGluY2x1ZGVzIGhpZ2gtc2FsZXMgc3RvcmVzIHdpdGggbW9kZXJhdGUgdm9sYXRpbGl0eSBhbmQgYSBjb25zaXN0ZW50bHkgcG9zaXRpdmUgaG9saWRheSBsaWZ0LCBwb3NpdGlvbmluZyB0aGVtIGFzIGNvcmUgcmV2ZW51ZSBkcml2ZXJzIHdpdGggcHJlZGljdGFibGUgaG9saWRheSBiZW5lZml0cy4KCgojIyBWaXN1YWxpemUgU2VnbWVudHMgCgoqKlBsb3QgQTogU2FsZXMgdnMgVm9sYXRpbGl0eSBieSBTZWdtZW50KioKCmBgYHtyIHN0ZXA1LjZ9CmdncGxvdChzdG9yZV9jbHVzdGVyZWQsIGFlcyh4ID0gYXZnX3NhbGVzLCB5ID0gY3Zfc2FsZXMsIHNoYXBlID0gU2VnbWVudCkpICsKICBnZW9tX3BvaW50KHNpemUgPSAzLCBhbHBoYSA9IDAuOCkgKwogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBjb21tYSkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJTdG9yZSBTZWdtZW50czogQXZlcmFnZSBTYWxlcyB2cyBSZWxhdGl2ZSBWb2xhdGlsaXR5IiwKICAgIHggPSAiQXZlcmFnZSBXZWVrbHkgU2FsZXMiLAogICAgeSA9ICJDb2VmZmljaWVudCBvZiBWYXJpYXRpb24gKENWKSIKICApCmBgYAoKPlRoZSBzYWxlc+KAk3ZvbGF0aWxpdHkgc2NhdHRlciBwbG90IGhpZ2hsaWdodHMgY2xlYXIgc3RydWN0dXJhbCBkaWZmZXJlbmNlcyBhY3Jvc3Mgc2VnbWVudHMuCioqU2VnbWVudCAxKiogc3RvcmVzIGNsdXN0ZXIgYXQgbG93ZXIgc2FsZXMgbGV2ZWxzIHdpdGggbWluaW1hbCB2b2xhdGlsaXR5LCBpbmRpY2F0aW5nIHByZWRpY3RhYmxlIGJ1dCBsaW1pdGVkIHJldmVudWUgY29udHJpYnV0aW9uLiAKKipTZWdtZW50IDIqKiBkaXNwbGF5cyB0aGUgaGlnaGVzdCBkaXNwZXJzaW9uIGluIHZvbGF0aWxpdHkgZm9yIHNpbWlsYXIgc2FsZXMgbGV2ZWxzLCByZWluZm9yY2luZyB0aGVpciBjbGFzc2lmaWNhdGlvbiBhcyB1bnN0YWJsZSBhbmQgZGVtYW5kLXNlbnNpdGl2ZSBsb2NhdGlvbnMuIAoqKlNlZ21lbnQgMyoqIHN0b3JlcyBkb21pbmF0ZSB0aGUgaGlnaGVyIHNhbGVzIHJhbmdlIHdoaWxlIG1haW50YWluaW5nIG1vZGVyYXRlIHZvbGF0aWxpdHksIGNvbmZpcm1pbmcgdGhlaXIgcm9sZSBhcyBXYWxtYXJ04oCZcyBwcmltYXJ5IHJldmVudWUgZW5naW5lcy4KCioqUGxvdCBCOiBIb2xpZGF5IFNlbnNpdGl2aXR5IGJ5IFNlZ21lbnQqKgoKYGBge3Igc3RlcDUuNi5ifQpnZ3Bsb3Qoc3RvcmVfY2x1c3RlcmVkLCBhZXMoeCA9IFNlZ21lbnQsIHkgPSBob2xpZGF5X2xpZnRfcGN0KSkgKwogIGdlb21fYm94cGxvdCgpICsKICBsYWJzKAogICAgdGl0bGUgPSAiSG9saWRheSBMaWZ0IERpc3RyaWJ1dGlvbiBieSBTdG9yZSBTZWdtZW50IiwKICAgIHggPSAiU2VnbWVudCIsCiAgICB5ID0gIkhvbGlkYXkgTGlmdCAoJSkiCiAgKQoKYGBgCgo+VGhlIGhvbGlkYXkgbGlmdCBkaXN0cmlidXRpb24gZnVydGhlciBkaWZmZXJlbnRpYXRlcyBzdG9yZSBzZWdtZW50cy4gCioqU2VnbWVudCAxKiogc2hvd3MgYSBzbGlnaHRseSBuZWdhdGl2ZSBob2xpZGF5IGVmZmVjdCwgc3VnZ2VzdGluZyB0aGF0IGhvbGlkYXkgcGVyaW9kcyBkbyBub3QgZ2VuZXJhdGUgaW5jcmVtZW50YWwgZGVtYW5kIGluIHRoZXNlIGxvY2F0aW9ucy4gCioqSW4gY29udHJhc3QsIFNlZ21lbnQgMioqIGV4aGliaXRzIHRoZSBoaWdoZXN0IGFuZCBtb3N0IGRpc3BlcnNlZCBob2xpZGF5IGxpZnQsIGluZGljYXRpbmcgc3Ryb25nIGJ1dCB1bnByZWRpY3RhYmxlIHJlc3BvbnNlcyB0byBob2xpZGF5IGV2ZW50cy4gCioqU2VnbWVudCAzKiogZGVtb25zdHJhdGVzIGEgcG9zaXRpdmUgYW5kIG1vcmUgc3RhYmxlIGhvbGlkYXkgbGlmdCwgaW1wbHlpbmcgdGhhdCBob2xpZGF5IHByb21vdGlvbnMgcmVsaWFibHkgZW5oYW5jZSBzYWxlcyBpbiBoaWdoLXBlcmZvcm1pbmcgc3RvcmVzLgoKIyMgU3RlcCA1IEV4ZWN1dGl2ZSBTdW1tYXJ5Cgo+VGhlIGstbWVhbnMgY2x1c3RlcmluZyByZXN1bHRzIHN1Z2dlc3QgdGhhdCBXYWxtYXJ0IHN0b3JlcyBjYW4gYmUgZ3JvdXBlZCBpbnRvIGRpc3RpbmN0LCBpbnRlcnByZXRhYmxlIHNlZ21lbnRzIGJhc2VkIG9uIHNhbGVzIGxldmVsLCBzYWxlcyBzdGFiaWxpdHksIGFuZCBob2xpZGF5IHNlbnNpdGl2aXR5LiBUaGlzIHNlZ21lbnRhdGlvbiBlbmFibGVzICoqZGlmZmVyZW50aWF0ZWQqKiBzdHJhdGVnaWVzOiAqKmhpZ2gtc2FsZXMgc3RhYmxlIHN0b3JlcyoqIG1heSBiZW5lZml0IGZyb20gb3BlcmF0aW9uYWwgb3B0aW1pemF0aW9uIGFuZCBpbnZlbnRvcnkgcHJpb3JpdGl6YXRpb24sICoqdm9sYXRpbGl0eS1kcml2ZW4gc3RvcmVzKiogcmVxdWlyZSBkZW1hbmQgc21vb3RoaW5nIGFuZCByaXNrIG1hbmFnZW1lbnQsIGFuZCAqKmhvbGlkYXktcmVzcG9uc2l2ZSBzdG9yZXMqKiBjYW4gYmUgdGFyZ2V0ZWQgd2l0aCBldmVudC1iYXNlZCBwcm9tb3Rpb25zLiAKT3ZlcmFsbCwgc2VnbWVudGF0aW9uIG9mZmVycyBhIHByYWN0aWNhbCBicmlkZ2UgYmV0d2VlbiBhbmFseXRpY3MgYW5kIG1hbmFnZXJpYWwgYWN0aW9uLgoKIyBGaW5hbCBNYW5hZ2VyaWFsIFJlY29tbWVuZGF0aW9ucwoKIyMgT3ZlcnZpZXcKClRoZSBhbmFseXNpcyByZXZlYWxzIHRoYXQgV2FsbWFydOKAmXMgc2FsZXMgcGVyZm9ybWFuY2UgYW5kIHZvbGF0aWxpdHkgYXJlIG5vdCBkcml2ZW4gYnkgYSBzaW5nbGUgdW5pdmVyc2FsIGZhY3RvciBzdWNoIGFzIGhvbGlkYXlzIG9yIG1hY3JvZWNvbm9taWMgY29uZGl0aW9ucy4gSW5zdGVhZCwgc3RvcmUtbGV2ZWwgaGV0ZXJvZ2VuZWl0eSBwbGF5cyBhIGRvbWluYW50IHJvbGUuIEJhc2VkIG9uIHRoZSBrLW1lYW5zIHNlZ21lbnRhdGlvbiByZXN1bHRzLCB0aHJlZSBkaXN0aW5jdCBzdG9yZSBzZWdtZW50cyBlbWVyZ2UsIGVhY2ggcmVxdWlyaW5nIGEgZGlmZmVyZW50aWF0ZWQgbWFuYWdlcmlhbCBhcHByb2FjaC4gVGhlIHJlY29tbWVuZGF0aW9ucyBiZWxvdyB0cmFuc2xhdGUgdGhlIGFuYWx5dGljYWwgZmluZGluZ3MgaW50byBjb25jcmV0ZSwgYWN0aW9uYWJsZSBzdHJhdGVnaWVzLgoKLS0tCgojIyBTZWdtZW50IDE6IFN0YWJsZSBMb3ctSW1wYWN0IFN0b3JlcwoKKipQcm9maWxlKioKLSBMb3cgYXZlcmFnZSB3ZWVrbHkgc2FsZXMgIAotIFZlcnkgbG93IHJlbGF0aXZlIHZvbGF0aWxpdHkgIAotIFNsaWdodGx5IG5lZ2F0aXZlIG9yIG5lZ2xpZ2libGUgaG9saWRheSBsaWZ0ICAKCioqTWFuYWdlcmlhbCBJbXBsaWNhdGlvbnMqKgoKVGhlc2Ugc3RvcmVzIGV4aGliaXQgcHJlZGljdGFibGUgZGVtYW5kIHBhdHRlcm5zIGJ1dCBjb250cmlidXRlIGxpbWl0ZWQgaW5jcmVtZW50YWwgcmV2ZW51ZSwgcGFydGljdWxhcmx5IGR1cmluZyBob2xpZGF5IHBlcmlvZHMuIEFnZ3Jlc3NpdmUgcHJvbW90aW9uYWwgYWN0aXZpdHkgaW4gdGhlc2UgbG9jYXRpb25zIGlzIHVubGlrZWx5IHRvIHlpZWxkIG1lYW5pbmdmdWwgcmV0dXJucy4KCioqUmVjb21tZW5kZWQgQWN0aW9ucyoqCi0gQXZvaWQgaGVhdnkgaG9saWRheS1zcGVjaWZpYyBwcm9tb3Rpb25zICAKLSBGb2N1cyBvbiBjb3N0IGVmZmljaWVuY3kgYW5kIG9wZXJhdGlvbmFsIHN0YWJpbGl0eSAgCi0gVXNlIHRoZXNlIHN0b3JlcyBhcyBiYXNlbGluZSBkZW1hbmQgYmVuY2htYXJrcyBmb3IKCgoKIyBDb25jbHVzaW9uLCBMaW1pdGF0aW9ucywgYW5kIEZ1dHVyZSBSZXNlYXJjaAoKIyMgQ29uY2x1c2lvbgoKVGhpcyBzdHVkeSBhZGRyZXNzZWQgYSBmb2N1c2VkIHNldCBvZiByZXNlYXJjaCBxdWVzdGlvbnMgYWltZWQgYXQgdW5kZXJzdGFuZGluZyBXYWxtYXJ04oCZcyBzYWxlcyBkeW5hbWljcyBmcm9tIGJvdGggYW4gYW5hbHl0aWNhbCBhbmQgbWFuYWdlcmlhbCBwZXJzcGVjdGl2ZS4KClJlZ2FyZGluZyAqKlJRMSoqLCB0aGUgYW5hbHlzaXMgc2hvd2VkIHRoYXQgYm90aCBzYWxlcyBhbmQgc2FsZXMgdm9sYXRpbGl0eSBhcmUgaGlnaGx5IGNvbmNlbnRyYXRlZCBhY3Jvc3Mgc3RvcmVzLCBidXQgbm90IHBlcmZlY3RseSBhbGlnbmVkLiBBIHJlbGF0aXZlbHkgc21hbGwgbnVtYmVyIG9mIHN0b3JlcyBhY2NvdW50IGZvciBhIGRpc3Byb3BvcnRpb25hdGUgc2hhcmUgb2YgdG90YWwgc2FsZXMsIHdoaWxlIGEgcGFydGlhbGx5IGRpZmZlcmVudCBzdWJzZXQgZHJpdmVzIG92ZXJhbGwgdm9sYXRpbGl0eS4gVGhpcyBmaW5kaW5nIGNvbmZpcm1zIHRoYXQgYWdncmVnYXRlIHBlcmZvcm1hbmNlIG1ldHJpY3MgbWFzayBpbXBvcnRhbnQgc3RvcmUtbGV2ZWwgZGlmZmVyZW5jZXMuCgpXaXRoIHJlc3BlY3QgdG8gKipSUTIqKiwgdGhlIGhvbGlkYXkgYW5hbHlzaXMgZGVtb25zdHJhdGVkIHRoYXQgaG9saWRheSBwZXJpb2RzIGFyZSBhc3NvY2lhdGVkIHdpdGggaGlnaGVyIGF2ZXJhZ2Ugc2FsZXMgYW5kIGluY3JlYXNlZCBkaXNwZXJzaW9uLiBIb3dldmVyLCB0aGUgZWZmZWN0IG9mIGhvbGlkYXlzIGlzIGhpZ2hseSBoZXRlcm9nZW5lb3VzOiBvbmx5IGEgc3Vic2V0IG9mIGhvbGlkYXkgd2Vla3MgZ2VuZXJhdGVzIGV4dHJlbWUgc2FsZXMgc3Bpa2VzLCB3aGlsZSBvdGhlcnMgcmVzZW1ibGUgcmVndWxhciBwZXJpb2RzLiBUaGlzIGNvbmZpcm1zIHRoYXQgYSBzaW1wbGUgYmluYXJ5IGhvbGlkYXkgaW5kaWNhdG9yIHByb3ZpZGVzIGFuIGluY29tcGxldGUgcmVwcmVzZW50YXRpb24gb2YgaG9saWRheS1kcml2ZW4gZGVtYW5kLgoKSW4gYW5zd2VyaW5nICoqUlEzKiosIHJlZ3Jlc3Npb24gcmVzdWx0cyByZXZlYWxlZCB0aGF0IHdoaWxlIGhvbGlkYXlzIGFwcGVhciBzaWduaWZpY2FudCBpbiBpc29sYXRpb24sIHRoZWlyIGVmZmVjdCBkaXNhcHBlYXJzIG9uY2UgdGltZSBzdHJ1Y3R1cmUgYW5kIG1hY3JvZWNvbm9taWMgY29uZGl0aW9ucyBhcmUgY29udHJvbGxlZCBmb3IuIFNlYXNvbmFsaXR5IGFuZCBicm9hZGVyIGVjb25vbWljIGluZGljYXRvcnPigJRwYXJ0aWN1bGFybHkgdW5lbXBsb3ltZW50IGFuZCBpbmZsYXRpb27igJRwbGF5IGEgc3Vic3RhbnRpYWxseSBtb3JlIGltcG9ydGFudCByb2xlIGluIGV4cGxhaW5pbmcgd2Vla2x5IHNhbGVzIHZhcmlhdGlvbi4gVGhlc2UgZmluZGluZ3Mgc3VnZ2VzdCB0aGF0IGhvbGlkYXkgdGltaW5nIGFsb25lIGlzIGluc3VmZmljaWVudCBmb3IgdW5kZXJzdGFuZGluZyBvciBwcmVkaWN0aW5nIHNhbGVzIHBlcmZvcm1hbmNlLgoKRmluYWxseSwgKipSUTQqKiBkZW1vbnN0cmF0ZWQgdGhhdCBzdG9yZSBzZWdtZW50YXRpb24gb2ZmZXJzIGEgcHJhY3RpY2FsIHNvbHV0aW9uIHRvIHRoZSBsaW1pdGF0aW9ucyBvZiBhZ2dyZWdhdGUgbW9kZWxpbmcuIFVzaW5nIGstbWVhbnMgY2x1c3RlcmluZywgc3RvcmVzIHdlcmUgZ3JvdXBlZCBpbnRvIHRocmVlIGRpc3RpbmN0IHNlZ21lbnRzIGJhc2VkIG9uIHNhbGVzIGxldmVsLCB2b2xhdGlsaXR5LCBhbmQgaG9saWRheSBzZW5zaXRpdml0eS4gVGhlc2Ugc2VnbWVudHMgZXhoaWJpdCBjbGVhcmx5IGRpZmZlcmVudGlhdGVkIGJlaGF2aW9yYWwgcGF0dGVybnMsIGVuYWJsaW5nIHRhcmdldGVkIG1hbmFnZXJpYWwgc3RyYXRlZ2llcyByYXRoZXIgdGhhbiB1bmlmb3JtLCBjaGFpbi13aWRlIHBvbGljaWVzLgoKT3ZlcmFsbCwgdGhlIHJlc3VsdHMgaGlnaGxpZ2h0IHRoZSBpbXBvcnRhbmNlIG9mIGNvbWJpbmluZyBkZXNjcmlwdGl2ZSBhbmFseXNpcywgZXhwbGFuYXRvcnkgbW9kZWxpbmcsIGFuZCBzZWdtZW50YXRpb24gdG8gdHJhbnNsYXRlIGNvbXBsZXggc2FsZXMgZGF0YSBpbnRvIGFjdGlvbmFibGUgaW5zaWdodHMuIEJ5IGFsaWduaW5nIGFuYWx5dGljYWwgbWV0aG9kcyB3aXRoIHdlbGwtZGVmaW5lZCByZXNlYXJjaCBxdWVzdGlvbnMsIHRoZSBzdHVkeSBwcm92aWRlcyBhIHN0cnVjdHVyZWQgZnJhbWV3b3JrIGZvciBkYXRhLWRyaXZlbiBkZWNpc2lvbi1tYWtpbmcgaW4gcmV0YWlsIG1hcmtldGluZyBhbmFseXRpY3MuCgoKLS0tCgojIyBMaW1pdGF0aW9ucwoKRGVzcGl0ZSBpdHMgaW5zaWdodHMsIHRoaXMgYW5hbHlzaXMgaXMgc3ViamVjdCB0byBzZXZlcmFsIGxpbWl0YXRpb25zLiBGaXJzdCwgdGhlIGRhdGFzZXQgZG9lcyBub3QgZGlzdGluZ3Vpc2ggYmV0d2VlbiBkaWZmZXJlbnQgdHlwZXMgb2YgaG9saWRheXMgKGUuZy4sIG1ham9yIHNob3BwaW5nIGV2ZW50cyB2ZXJzdXMgcm91dGluZSBwdWJsaWMgaG9saWRheXMpLiBBcyBhIHJlc3VsdCwgaG9saWRheSBlZmZlY3RzIGFyZSBjYXB0dXJlZCBpbiBhbiBhZ2dyZWdhdGVkIG1hbm5lciwgd2hpY2ggbWF5IG1hc2sgaW1wb3J0YW50IGRpZmZlcmVuY2VzIGluIGRlbWFuZCBpbnRlbnNpdHkgYWNyb3NzIHNwZWNpZmljIGV2ZW50cy4gU2Vjb25kLCB0aGUgcmVncmVzc2lvbiBtb2RlbHMgcmVseSBvbiBhZ2dyZWdhdGUgd2Vla2x5IHNhbGVzIGFuZCBkbyBub3QgaW5jb3Jwb3JhdGUgcHJvZHVjdC1sZXZlbCBvciBjdXN0b21lci1sZXZlbCBpbmZvcm1hdGlvbiwgbGltaXRpbmcgdGhlIGFiaWxpdHkgdG8gYW5hbHl6ZSBjYXRlZ29yeS1zcGVjaWZpYyBvciBiZWhhdmlvcmFsIGRyaXZlcnMgb2YgZGVtYW5kLiAKCkFkZGl0aW9uYWxseSwgd2hpbGUgbWFjcm9lY29ub21pYyB2YXJpYWJsZXMgaW1wcm92ZSBleHBsYW5hdG9yeSBwb3dlciwgdGhlIHJlbGF0aXZlbHkgbG93IFItc3F1YXJlZCB2YWx1ZXMgc3VnZ2VzdCB0aGF0IHVub2JzZXJ2ZWQgZmFjdG9yc+KAlHN1Y2ggYXMgbG9jYWwgY29tcGV0aXRpb24sIHN0b3JlLXNwZWNpZmljIHByb21vdGlvbnMsIG9yIHJlZ2lvbmFsIGRlbW9ncmFwaGljc+KAlG1heSBwbGF5IGEgc2lnbmlmaWNhbnQgcm9sZS4gRmluYWxseSwgdGhlIGNsdXN0ZXJpbmcgcmVzdWx0cyBkZXBlbmQgb24gdGhlIHNlbGVjdGVkIHZhcmlhYmxlcyBhbmQgbnVtYmVyIG9mIGNsdXN0ZXJzOyBhbHRlcm5hdGl2ZSBzcGVjaWZpY2F0aW9ucyBjb3VsZCB5aWVsZCBzbGlnaHRseSBkaWZmZXJlbnQgc2VnbWVudCBzdHJ1Y3R1cmVzLgoKLS0tCgojIyBGdXR1cmUgUmVzZWFyY2ggRGlyZWN0aW9ucwoKRnV0dXJlIHJlc2VhcmNoIGNvdWxkIGV4dGVuZCB0aGlzIGFuYWx5c2lzIGluIHNldmVyYWwgd2F5cy4gRmlyc3QsIGluY29ycG9yYXRpbmcgbW9yZSBncmFudWxhciBob2xpZGF5IGNsYXNzaWZpY2F0aW9ucyAoZS5nLiwgc2VwYXJhdGluZyBtYWpvciBwcm9tb3Rpb25hbCBldmVudHMgZnJvbSBtaW5vciBob2xpZGF5cykgd291bGQgYWxsb3cgZm9yIGEgbW9yZSBwcmVjaXNlIGVzdGltYXRpb24gb2YgZXZlbnQtc3BlY2lmaWMgZWZmZWN0cy4gU2Vjb25kLCBpbnRlZ3JhdGluZyBzdG9yZS1sZXZlbCBwcm9tb3Rpb25hbCBkYXRhLCBwcmljaW5nIGluZm9ybWF0aW9uLCBvciBwcm9kdWN0LWNhdGVnb3J5IHNhbGVzIGNvdWxkIGltcHJvdmUgZXhwbGFuYXRvcnkgcG93ZXIgYW5kIGVuYWJsZSBkZWVwZXIgYmVoYXZpb3JhbCBpbnNpZ2h0cy4gCgpNb3Jlb3ZlciwgYWR2YW5jZWQgbW9kZWxpbmcgdGVjaG5pcXVlcyBzdWNoIGFzIG1peGVkLWVmZmVjdHMgbW9kZWxzIG9yIHBhbmVsIGRhdGEgYXBwcm9hY2hlcyBjb3VsZCBleHBsaWNpdGx5IGFjY291bnQgZm9yIHN0b3JlLXNwZWNpZmljIGZpeGVkIGVmZmVjdHMgYW5kIGR5bmFtaWMgcmVzcG9uc2VzIG92ZXIgdGltZS4gRmluYWxseSwgbGlua2luZyBzYWxlcyBwZXJmb3JtYW5jZSB0byBjdXN0b21lciBvciByZWdpb25hbCBkZW1vZ3JhcGhpYyBkYXRhIHdvdWxkIHN1cHBvcnQgbW9yZSBwZXJzb25hbGl6ZWQgYW5kIGxvY2F0aW9uLXNwZWNpZmljIG1hcmtldGluZyBzdHJhdGVnaWVzLCBmdXJ0aGVyIGVuaGFuY2luZyB0aGUgbWFuYWdlcmlhbCByZWxldmFuY2Ugb2YgdGhlIGFuYWx5c2lzLgoKCg==