Exports EDA

Mexico exports characteristics

• Mexico’s exports grew strongly between 2015 and 2025, almost doubling in total value. This shows how important international trade is for the Mexican economy.

• Around 90% of exports come from manufactured goods, especially automotive, electronics, and machinery. Mexico is highly specialized in industrial production.

• More than 80% of exports go to the United States. This means Mexico depends heavily on the U.S. market and regional supply chains.

• Even with challenges such as COVID-19 and the renegotiation of NAFTA into USMCA, exports recovered quickly and continued growing.

Contribution of Panel Data Analysis to Understanding Export Performance

• Panel data combines information across states or sectors and across time. This helps us see differences between regions and how exports change each year.

• It allows us to control for characteristics that do not change over time, such as geography or industrial structure. This makes the analysis more accurate.

• Panel models help separate long-term structural factors from short-term shocks, such as temporary tariff changes.

Use of Panel Data for Short‑Term Export Prediction

• We can use past export trends from different states or sectors to estimate what could happen in the next 1–2 years.

• It is possible to include variables like exchange rate, U.S. economic growth, or tariff changes to simulate different scenarios.

• Predictions can be made at the state or sector level, not only for the whole country. This gives more specific and useful results.

Role of Business Intelligence and Predictive Analytics for Identifying Vulnerability During USMCA Negotiations

• Business Intelligence tools can measure how much each state or sector depends on exports to the U.S. This helps identify which ones are more exposed to tariff changes.

• Predictive models can estimate how sensitive exports are to new trade rules. With this, we can classify states or industries by level of risk.

• Dashboards and visual tools allow decision makers to monitor export performance before and after policy changes.

• Machine learning techniques can group states or sectors with similar export structures. This helps identify patterns of vulnerability during trade negotiations.

Exports Data Analysis

Data Cleaning and Transforming

library(readxl)
library(tidyverse)
library(plm)
library(sf)
library(rnaturalearth)
library(dplyr)
library(ggplot2)
library(reshape2)
library(readr)
library(lmtest)
library(sandwich)
library(car)
library(dplyr)
df_expo <- read_excel("C:/Users/Osval/Downloads/inegi_exports_dataset.xlsx", sheet = "exports")
df_ts <- read_excel("C:/Users/Osval/Downloads/inegi_exports_dataset.xlsx", sheet = "ts_exports")
df_data <- read_excel("C:/Users/Osval/Downloads/inegi_exports_dataset.xlsx", sheet = "data")
df_fdi <- read_excel("C:/Users/Osval/Downloads/inegi_exports_dataset.xlsx", sheet = "fdi")

• The original datasets were cleaned and transformed. Export variables were converted from wide format to long format so each row represents one state in one specific year.

df_expolong <- df_expo %>%
  pivot_longer(
    cols = starts_with("real_exports_"),
    names_to = "year",
    names_prefix = "real_exports_",
    values_to = "real_exports"
  )

df_fdilong <- df_fdi %>%
  pivot_longer(
    cols = starts_with("fdi_"),
    names_to = "year",
    names_prefix = "fdi_",
    values_to = "fdi"
  )

• We verified that there were no duplicated observations by state and year before merging the datasets.

df_expolong %>% count(state, year, region) %>% filter(n > 1)
## # A tibble: 0 × 4
## # ℹ 4 variables: state <chr>, year <chr>, region <chr>, n <int>
df_data %>% count(state, year) %>% filter(n > 1)
## # A tibble: 0 × 3
## # ℹ 3 variables: state <chr>, year <dbl>, n <int>
df_fdilong %>% count(state, year, region) %>% filter(n > 1)
## # A tibble: 0 × 4
## # ℹ 4 variables: state <chr>, year <chr>, region <chr>, n <int>

• Different datasets (exports, FDI, macroeconomic variables, and state characteristics) were merged using state and year as key variables.

df_expolong$year <- as.numeric(df_expolong$year)
df_fdilong$year <- as.numeric(df_fdilong$year)
df_data$year <- as.numeric(df_data$year)
panel_full <- df_expolong %>%
  left_join(df_fdilong, by = c("state", "year", "region")) %>%
  left_join(df_data, by = c("state", "year"))

• Missing values were replaced using the average value by state in order to maintain a balanced panel structure.

panel_full <- panel_full %>%
  group_by(state) %>%
  mutate(
    across(
      where(is.numeric), 
      ~ ifelse(is.na(.), mean(., na.rm = TRUE), .)
    )
  ) %>%
  ungroup()

• A panel dataset was created using state and year as indexes, allowing analysis across time and across regions.

panel_data <- pdata.frame(panel_full,
                          index = c("state", "year"))

Exploratory Data Analysis – EDA

Descriptive Statistics

regional_avg <- panel_full %>%
  group_by(region) %>%
  summarise(
    avg_exports = mean(real_exports, na.rm = TRUE),
    avg_fdi = mean(fdi, na.rm = TRUE),
    avg_exchange_rate = mean(exchange_rate, na.rm = TRUE),
    avg_college = mean(college_education, na.rm = TRUE),
    .groups = "drop"
  )
ggplot(regional_avg, aes(x = region, y = avg_exports)) +
  geom_col() +
  labs(title = "Average Exports by Region",
       x = "Region",
       y = "Average Real Exports") +
  theme_minimal()

ggplot(regional_avg, aes(x = region, y = avg_fdi)) +
  geom_col() +
  labs(title = "Average FDI by Region",
       x = "Region",
       y = "Average FDI") +
  theme_minimal()

ggplot(regional_avg, aes(x = region, y = avg_college)) +
  geom_col() +
  labs(title = "Average College Education by Region",
       x = "Region",
       y = "Average College Education") +
  theme_minimal()

ggplot(panel_full, aes(x = real_exports)) +
  geom_histogram(bins = 30) +
  labs(title = "Distribution of Real Exports",
       x = "Real Exports",
       y = "Frequency") +
  theme_minimal()

ggplot(panel_full, aes(x = fdi)) +
  geom_histogram(bins = 30) +
  labs(title = "Distribution of FDI",
       x = "FDI",
       y = "Frequency") +
  theme_minimal()

ggplot(panel_full, aes(x = college_education)) +
  geom_histogram(bins = 30) +
  labs(title = "Distribution of College Education",
       x = "College Education",
       y = "Frequency") +
  theme_minimal()

Statistics of Dispersion

ggplot(panel_full, aes(x = region, y = real_exports)) +
  geom_boxplot() +
  labs(title = "Exports Distribution Across Regions",
       x = "Region",
       y = "Real Exports") +
  theme_minimal()

ggplot(panel_full, aes(x = region, y = fdi)) +
  geom_boxplot() +
  labs(title = "FDI Distribution Across Regions",
       x = "Region",
       y = "FDI") +
  theme_minimal()

ggplot(panel_full, aes(x = region, y = lq_primary)) +
  geom_boxplot() +
  labs(title = "College Education Across Regions",
       x = "Region",
       y = "College Education") +
  theme_minimal()

ggplot(panel_full, aes(x = region, y = lq_secondary)) +
  geom_boxplot() +
  labs(title = "College Education Across Regions",
       x = "Region",
       y = "College Education") +
  theme_minimal()

Visualization across Time

exports_time <- panel_full %>%
  group_by(year) %>%
  summarise(total_exports = sum(real_exports, na.rm = TRUE))

ggplot(exports_time, aes(x = year, y = total_exports)) +
  geom_line(size = 1) +
  labs(title = "Total Exports Inflows in Mexico",
       x = "Year",
       y = "Total Real Exports") +
  theme_minimal()
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

• Total exports show a clear upward trend over the period. There is a temporary decline around the COVID-19 period, but exports recover quickly and continue growing.

exports_region <- panel_full %>%
  group_by(region, year) %>%
  summarise(total_exports = sum(real_exports, na.rm = TRUE),
            .groups = "drop")

ggplot(exports_region, aes(x = year, y = total_exports, color = region)) +
  geom_line(linewidth = 1) +
  labs(title = "Total Exports Inflows by Region",
       x = "Year",
       y = "Total Real Exports",
       color = "Region") +
  theme_minimal()

• Northern regions show higher export levels compared to southern regions.

• The gap between regions remains persistent over time, which suggests structural differences in industrial development.

macro_time <- panel_full %>%
  group_by(year) %>%
  summarise(
    total_exports = sum(real_exports, na.rm = TRUE),
    avg_exchange_rate = mean(exchange_rate, na.rm = TRUE),
    .groups = "drop"
  )
macro_time <- macro_time %>%
  mutate(
    exports_index = total_exports / max(total_exports),
    exchange_index = avg_exchange_rate / max(avg_exchange_rate)
  )
ggplot(macro_time, aes(x = year)) +
  geom_line(aes(y = exports_index, color = "Exports"), linewidth = 1.2) +
  geom_line(aes(y = exchange_index, color = "Exchange Rate"), linewidth = 1.2) +
  labs(title = "Exports Inflows vs Exchange Rate (Indexed)",
       x = "Year",
       y = "Indexed Values",
       color = "") +
  theme_minimal()

• When comparing indexed exports and exchange rate, both variables show similar movements in some years.

• This suggests that exchange rate fluctuations may influence export performance, although the relationship is not perfectly linear.

###Regional Differences

panel_full <- panel_full %>%
  mutate(zone = ifelse(border_distance < 400, "North", "South"))
panel_full <- panel_full %>%
  mutate(zone = ifelse(region %in% c("Noroeste", "Noreste"), 
                       "North", 
                       "South"))
north_south_exports <- panel_full %>%
  group_by(zone) %>%
  summarise(avg_exports = mean(real_exports, na.rm = TRUE),
            .groups = "drop")
ggplot(north_south_exports, aes(x = zone, y = avg_exports)) +
  geom_bar(stat = "identity") +
  labs(title = "Average Exports Inflows: North vs South",
       x = "Region",
       y = "Average Real Exports") +
  theme_minimal()

• States classified as “North” have significantly higher average exports than those in the “South.”

• This confirms the importance of geographic proximity to the U.S. border and industrial concentratio

• Northern states show much higher export volumes. Southern states participate less in international trade.

• Geographic proximity to the U.S. border is a improtant factor. Northern states benefit from lower transportation costs and better access to cross-border infrastructure.

• Industrial structure is different. Northern states have higher concentration in manufacturing and export-oriented industries, while southern states more on primary activities or services.

• Foreign Direct Investment is more concentrated in the North. Many multinational firms are located in northern states due to their connection with U.S. markets.

• Infrastructure and connectivity are generally stronger in northern states, including highways, industrial parks, and customs facilities, which facilitate international trade.

mexico_map <- ne_states(country = "mexico", returnclass = "sf")

setdiff(mexico_map$name, panel_data$state)
## [1] "Nuevo León"       "Yucatán"          "Michoacán"        NA                
## [5] "México"           "Querétaro"        "San Luis Potosí"  "Distrito Federal"
mexico_map <- ne_states(country = "mexico", returnclass = "sf")

setdiff(panel_data$state, mexico_map$name)
## [1] "Ciudad de Mexico" "Mexico"           "Michoacan"        "Nuevo Leon"      
## [5] "Queretaro"        "San Luis Potosi"  "Yucatan"
panel_full$state <- dplyr::recode(panel_full$state,
  "Ciudad de Mexico" = "Distrito Federal",
  "Michoacan" = "Michoacán",
  "Queretaro" = "Querétaro",
  "Mexico" = "México",
  "San Luis Potosi" = "San Luis Potosí",
  "Yucatan" = "Yucatán",
  "Nuevo Leon" = "Nuevo León"
)

• Border states such as Chihuahua and other northern states show higher export levels.

avg_state_exports <- panel_full %>%
  group_by(state) %>%
  summarise(avg_exports = mean(real_exports, na.rm = TRUE),
            .groups = "drop")
map_data <- mexico_map %>%
  left_join(avg_state_exports, by = c("name" = "state"))
ggplot(map_data) +
  geom_sf(aes(fill = avg_exports)) +
  scale_fill_viridis_c(option = "mako", na.value = "grey90") +
  labs(title = "Average Exports Inflows by Mexican State",
       fill = "Avg Exports") +
  theme_minimal()

Correlation and Relationships

scale_fill_gradient2(
  low = "blue",
  mid = "white",
  high = "red",
  midpoint = 0,
  limits = c(-1, 1)
)
## <ScaleContinuous>
##  Range:  
##  Limits:   -1 --    1
corr_data <- panel_data %>%
  select(real_exports, exchange_rate, pop_density, fdi, border_distance, lq_primary,lq_secondary,lq_tertiary, average_daily_salary, crime_rate) %>%
  drop_na()

corr_matrix <- cor(corr_data)

corr_long <- as.data.frame(as.table(corr_matrix))

ggplot(corr_long, aes(Var1, Var2, fill = Freq)) +
  geom_tile() +
  scale_fill_gradient2(
    low = "blue",
    mid = "white",
    high = "red",
    midpoint = 0,
    limits = c(-1, 1)
  ) +
  geom_text(aes(label = round(Freq, 2)), size = 4) +
  labs(title = "Correlation Matrix",
       x = "",
       y = "",
       fill = "Correlation") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

• Exports show positive correlation with FDI and employment concentration in the secondary sector.

• There is a negative relationship between border distance and exports, meaning that states closer to the U.S. tend to export more.

• Some socioeconomic variables such as salary also show positive association with exports, suggesting that more industrialized states have higher income levels.

ggplot(panel_full, aes(x = border_distance, y = real_exports)) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "lm", se = TRUE, color = "black") +
  labs(title = "Exports Inflows vs Border Disance",
       x = "Border Disance",
       y = "Exports") +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

• The regression line shows a negative slope. States farther from the border tend to have lower export levels.

ggplot(panel_full, aes(x = lq_secondary, y = real_exports)) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "lm", se = TRUE, color = "black") +
  labs(title = "Exports Inflows vs Employment concentration in the secondary sector",
       x = "Employment concentration in the secondary sector",
       y = "Real Exports") +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

• There is a positive relationship. States with stronger industrial specialization export more.

ggplot(panel_full, aes(x = average_daily_salary, y = real_exports)) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "lm", se = TRUE, color = "black") +
  labs(title = "Exports Inflows vs Average Daily Salary",
       x = "Average Daily Salary",
       y = "Real Exports") +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

• The relationship appears positive, suggesting that higher productivity and industrialization are linked to higher wages and exports.

##Hypotheses Statements

• H1: States with higher employment concentration in the secondary (industrial specialization) and third (services) sector have significantly higher export levels.

• H2: Border distance has a negative and significant effect on exports. States closer to the U.S. border export more than states located farther away.

• H3: Higher levels of Foreign Direct Investment (FDI) positively affect export performance at the state level.

• H4: States with higher average wages, as a proxy for productivity and industrial development, show higher export performance.

Main Findings

• Total exports show fluctuations over time, with increases and decreases from one year to another.

• Northern states consistently show higher export levels than southern states.

• The scatter plot of exports versus border distance shows a negative relationship. States closer to the U.S. border tend to export more.

• There is a positive relationship between exports and employment concentration in the secondary sector. States with stronger manufacturing labor tend to achieve higher export levels.

• Exports are positively correlated with FDI and average daily salary. This suggests that more industrialized states perform better in international trade.

#Model ## Differences

• Type of data used o Cross-sectional: Analyzes many individuals (people, firms, countries, etc.) at a single point in time. o Time series: Analyzes one individual or variable over a period of time. o Panel data: Combines both; analyzes multiple individuals across multiple time periods.

• Dimension of analysis o Cross-sectional: Has only an individual dimension (N). o Time series: Has only a time dimension (T). o Panel data: Has both an individual dimension (N) and a time dimension (T) simultaneously.

• Type of variability captured o Cross-sectional: Compares differences between individuals. o Time series: Examines changes over time. o Panel data: Allows analysis of both differences between individuals and changes over time simultaneously.

• Common statistical issues o Cross-sectional: May suffer from heteroskedasticity. o Time series: May suffer from autocorrelation and non-stationarity problems. o Panel data: May involve fixed or random effects, as well as autocorrelation and heteroskedasticity.

• Analytical capacity and depth o Cross-sectional: Simpler, but does not capture time dynamics. o Time series: Allows analysis of trends and cycles over time. o Panel data: More comprehensive because it better controls for individual heterogeneity and improves estimator precision.

model_formula <- real_exports ~ lq_secondary +
                                  average_daily_salary + pop_density + real_public_investment_pc
pooling <- plm(model_formula, data = panel_data, model = "pooling")
summary(pooling)
## Pooling Model
## 
## Call:
## plm(formula = model_formula, data = panel_data, model = "pooling")
## 
## Balanced Panel: n = 32, T = 9, N = 288
## 
## Residuals:
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
## -4.80e+08 -1.11e+08  4.19e+06  0.00e+00  1.09e+08  4.42e+08 
## 
## Coefficients:
##                              Estimate  Std. Error  t-value  Pr(>|t|)    
## (Intercept)               -1004258854    83563782 -12.0179 < 2.2e-16 ***
## lq_secondary                455153589    28339329  16.0608 < 2.2e-16 ***
## average_daily_salary          2449813      259179   9.4522 < 2.2e-16 ***
## pop_density                    -49737       11526  -4.3153 2.205e-05 ***
## real_public_investment_pc      -37243       25461  -1.4627    0.1447    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    2.2278e+19
## Residual Sum of Squares: 8.3902e+18
## R-Squared:      0.62339
## Adj. R-Squared: 0.61807
## F-statistic: 117.11 on 4 and 283 DF, p-value: < 2.22e-16
fe_ind <- plm(model_formula, data = panel_data, model = "within", effect = "individual")
summary(fe_ind)
## Oneway (individual) effect Within Model
## 
## Call:
## plm(formula = model_formula, data = panel_data, effect = "individual", 
##     model = "within")
## 
## Balanced Panel: n = 32, T = 9, N = 288
## 
## Residuals:
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
## -1.20e+08 -1.12e+07 -7.81e+04  0.00e+00  8.88e+06  1.51e+08 
## 
## Coefficients:
##                             Estimate Std. Error t-value Pr(>|t|)
## lq_secondary              25034558.1 29583697.1  0.8462   0.3982
## average_daily_salary        -17708.3   116039.2 -0.1526   0.8788
## pop_density                 -21049.3   271104.2 -0.0776   0.9382
## real_public_investment_pc     7340.4     6973.5  1.0526   0.2935
## 
## Total Sum of Squares:    3.0639e+17
## Residual Sum of Squares: 3.0385e+17
## R-Squared:      0.0082919
## Adj. R-Squared: -0.12945
## F-statistic: 0.526758 on 4 and 252 DF, p-value: 0.71616
fe_time <- plm(model_formula, data = panel_data, model = "within", effect = "time")
summary(fe_time)
## Oneway (time) effect Within Model
## 
## Call:
## plm(formula = model_formula, data = panel_data, effect = "time", 
##     model = "within")
## 
## Balanced Panel: n = 32, T = 9, N = 288
## 
## Residuals:
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
## -3.85e+08 -9.29e+07  1.67e+06  0.00e+00  1.12e+08  4.15e+08 
## 
## Coefficients:
##                            Estimate Std. Error t-value  Pr(>|t|)    
## lq_secondary              435521531   27192797 16.0161 < 2.2e-16 ***
## average_daily_salary        3233824     280159 11.5428 < 2.2e-16 ***
## pop_density                  -63991      11248 -5.6889 3.268e-08 ***
## real_public_investment_pc    -76084      25687 -2.9620  0.003324 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    2.2211e+19
## Residual Sum of Squares: 7.3903e+18
## R-Squared:      0.66727
## Adj. R-Squared: 0.65275
## F-statistic: 137.876 on 4 and 275 DF, p-value: < 2.22e-16
fe_tw <- plm(model_formula, data = panel_data, model = "within", effect = "twoways")
summary(fe_tw)
## Twoways effects Within Model
## 
## Call:
## plm(formula = model_formula, data = panel_data, effect = "twoways", 
##     model = "within")
## 
## Balanced Panel: n = 32, T = 9, N = 288
## 
## Residuals:
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
## -1.04e+08 -1.43e+07 -1.69e+06  0.00e+00  1.59e+07  1.29e+08 
## 
## Coefficients:
##                             Estimate Std. Error t-value Pr(>|t|)  
## lq_secondary              13539301.8 26702971.7  0.5070  0.61259  
## average_daily_salary        -28770.2   229440.3 -0.1254  0.90032  
## pop_density                -286037.4   252623.3 -1.1323  0.25863  
## real_public_investment_pc    13038.5     6598.8  1.9759  0.04929 *
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    2.3933e+17
## Residual Sum of Squares: 2.3375e+17
## R-Squared:      0.023305
## Adj. R-Squared: -0.14882
## F-statistic: 1.4555 on 4 and 244 DF, p-value: 0.21642
re <- plm(model_formula, data = panel_data, model = "random")
summary(re)
## Oneway (individual) effect Random Effect Model 
##    (Swamy-Arora's transformation)
## 
## Call:
## plm(formula = model_formula, data = panel_data, model = "random")
## 
## Balanced Panel: n = 32, T = 9, N = 288
## 
## Effects:
##                     var   std.dev share
## idiosyncratic 1.206e+15 3.472e+07 0.044
## individual    2.602e+16 1.613e+08 0.956
## theta: 0.9284
## 
## Residuals:
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
## -80456012 -18157289  -7849908         0  10480115 203393118 
## 
## Coefficients:
##                              Estimate  Std. Error z-value Pr(>|z|)   
## (Intercept)               139354203.5  56498460.8  2.4665 0.013644 * 
## lq_secondary               86780057.3  30093475.3  2.8837 0.003931 **
## average_daily_salary          31246.0    116089.7  0.2692 0.787811   
## pop_density                  -28431.3     29383.7 -0.9676 0.333251   
## real_public_investment_pc      7097.1      7531.2  0.9424 0.346009   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    4.1893e+17
## Residual Sum of Squares: 4.0313e+17
## R-Squared:      0.037702
## Adj. R-Squared: 0.024101
## Chisq: 11.0878 on 4 DF, p-value: 0.025595
pFtest(fe_ind, pooling)
## 
##  F test for individual effects
## 
## data:  model_formula
## F = 216.34, df1 = 31, df2 = 252, p-value < 2.2e-16
## alternative hypothesis: significant effects
pFtest(fe_time, pooling)
## 
##  F test for time effects
## 
## data:  model_formula
## F = 4.6511, df1 = 8, df2 = 275, p-value = 2.384e-05
## alternative hypothesis: significant effects
pFtest(fe_tw, pooling)
## 
##  F test for twoways effects
## 
## data:  model_formula
## F = 218.31, df1 = 39, df2 = 244, p-value < 2.2e-16
## alternative hypothesis: significant effects
phtest(fe_time, re)
## 
##  Hausman Test
## 
## data:  model_formula
## chisq = 729.9, df = 4, p-value < 2.2e-16
## alternative hypothesis: one model is inconsistent
vif(lm(model_formula, data = panel_data))
##              lq_secondary      average_daily_salary               pop_density 
##                  1.112735                  1.398501                  1.460673 
## real_public_investment_pc 
##                  1.054705
bptest(fe_time)
## 
##  studentized Breusch-Pagan test
## 
## data:  fe_time
## BP = 108.78, df = 4, p-value < 2.2e-16
pbgtest(fe_time)
## 
##  Breusch-Godfrey/Wooldridge test for serial correlation in panel models
## 
## data:  model_formula
## chisq = 187.28, df = 9, p-value < 2.2e-16
## alternative hypothesis: serial correlation in idiosyncratic errors
library(plm)

models <- list(
  Pooling = pooling,
  FE_Individual = fe_ind,
  FE_TwoWays = fe_tw,
  RE = re,
  FE_Time = fe_time
)

comparison <- data.frame(
  Model = names(models),
  R2 = sapply(models, function(m) summary(m)$r.squared["rsq"]),
  Adj_R2 = sapply(models, function(m) summary(m)$r.squared["adjrsq"])
)

comparison
##                           Model          R2      Adj_R2
## Pooling.rsq             Pooling 0.623389824  0.61806671
## FE_Individual.rsq FE_Individual 0.008291903 -0.12944533
## FE_TwoWays.rsq       FE_TwoWays 0.023304595 -0.14881796
## RE.rsq                       RE 0.037702199  0.02410082
## FE_Time.rsq             FE_Time 0.667272482  0.65275346
LS0tDQp0aXRsZTogIk1leGljbyBFeHBvcnRzIg0KYXV0aG9yOiAiT3N2YWxkbyBMb3BleiwgT3NjYXIgQmFyY2FyY2VsLCBNYXJpZWwgR2FyemEiDQpkYXRlOiAiMjAyNi0wMi0xNiINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiBUUlVFDQogICAgdG9jX2Zsb2F0OiBUUlVFDQogICAgY29kZV9kb3dubG9hZDogVFJVRQ0KICAgIHRoZW1lOiAic3BhY2VsYWIiDQogICAgaGlnaGxpZ2h0OiAia2F0ZSINCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCmBgYA0KDQojIEV4cG9ydHMgRURBDQojIyBNZXhpY28gZXhwb3J0cyBjaGFyYWN0ZXJpc3RpY3MNCuKAoiBNZXhpY2/igJlzIGV4cG9ydHMgZ3JldyBzdHJvbmdseSBiZXR3ZWVuIDIwMTUgYW5kIDIwMjUsIGFsbW9zdCBkb3VibGluZyBpbiB0b3RhbCB2YWx1ZS4gVGhpcyBzaG93cyBob3cgaW1wb3J0YW50IGludGVybmF0aW9uYWwgdHJhZGUgaXMgZm9yIHRoZSBNZXhpY2FuIGVjb25vbXkuDQoNCuKAoiBBcm91bmQgOTAlIG9mIGV4cG9ydHMgY29tZSBmcm9tIG1hbnVmYWN0dXJlZCBnb29kcywgZXNwZWNpYWxseSBhdXRvbW90aXZlLCBlbGVjdHJvbmljcywgYW5kIG1hY2hpbmVyeS4gTWV4aWNvIGlzIGhpZ2hseSBzcGVjaWFsaXplZCBpbiBpbmR1c3RyaWFsIHByb2R1Y3Rpb24uDQoNCuKAoiBNb3JlIHRoYW4gODAlIG9mIGV4cG9ydHMgZ28gdG8gdGhlIFVuaXRlZCBTdGF0ZXMuIFRoaXMgbWVhbnMgTWV4aWNvIGRlcGVuZHMgaGVhdmlseSBvbiB0aGUgVS5TLiBtYXJrZXQgYW5kIHJlZ2lvbmFsIHN1cHBseSBjaGFpbnMuDQoNCuKAoiBFdmVuIHdpdGggY2hhbGxlbmdlcyBzdWNoIGFzIENPVklELTE5IGFuZCB0aGUgcmVuZWdvdGlhdGlvbiBvZiBOQUZUQSBpbnRvIFVTTUNBLCBleHBvcnRzIHJlY292ZXJlZCBxdWlja2x5IGFuZCBjb250aW51ZWQgZ3Jvd2luZy4NCg0KIyMjIENvbnRyaWJ1dGlvbiBvZiBQYW5lbCBEYXRhIEFuYWx5c2lzIHRvIFVuZGVyc3RhbmRpbmcgRXhwb3J0IFBlcmZvcm1hbmNlDQoNCuKAoiBQYW5lbCBkYXRhIGNvbWJpbmVzIGluZm9ybWF0aW9uIGFjcm9zcyBzdGF0ZXMgb3Igc2VjdG9ycyBhbmQgYWNyb3NzIHRpbWUuIFRoaXMgaGVscHMgdXMgc2VlIGRpZmZlcmVuY2VzIGJldHdlZW4gcmVnaW9ucyBhbmQgaG93IGV4cG9ydHMgY2hhbmdlIGVhY2ggeWVhci4NCg0K4oCiIEl0IGFsbG93cyB1cyB0byBjb250cm9sIGZvciBjaGFyYWN0ZXJpc3RpY3MgdGhhdCBkbyBub3QgY2hhbmdlIG92ZXIgdGltZSwgc3VjaCBhcyBnZW9ncmFwaHkgb3IgaW5kdXN0cmlhbCBzdHJ1Y3R1cmUuIFRoaXMgbWFrZXMgdGhlIGFuYWx5c2lzIG1vcmUgYWNjdXJhdGUuDQoNCuKAoiBQYW5lbCBtb2RlbHMgaGVscCBzZXBhcmF0ZSBsb25nLXRlcm0gc3RydWN0dXJhbCBmYWN0b3JzIGZyb20gc2hvcnQtdGVybSBzaG9ja3MsIHN1Y2ggYXMgdGVtcG9yYXJ5IHRhcmlmZiBjaGFuZ2VzLg0KDQojIyMgVXNlIG9mIFBhbmVsIERhdGEgZm9yIFNob3J04oCRVGVybSBFeHBvcnQgUHJlZGljdGlvbg0KDQrigKIgV2UgY2FuIHVzZSBwYXN0IGV4cG9ydCB0cmVuZHMgZnJvbSBkaWZmZXJlbnQgc3RhdGVzIG9yIHNlY3RvcnMgdG8gZXN0aW1hdGUgd2hhdCBjb3VsZCBoYXBwZW4gaW4gdGhlIG5leHQgMeKAkzIgeWVhcnMuDQoNCuKAoiBJdCBpcyBwb3NzaWJsZSB0byBpbmNsdWRlIHZhcmlhYmxlcyBsaWtlIGV4Y2hhbmdlIHJhdGUsIFUuUy4gZWNvbm9taWMgZ3Jvd3RoLCBvciB0YXJpZmYgY2hhbmdlcyB0byBzaW11bGF0ZSBkaWZmZXJlbnQgc2NlbmFyaW9zLg0KDQrigKIgUHJlZGljdGlvbnMgY2FuIGJlIG1hZGUgYXQgdGhlIHN0YXRlIG9yIHNlY3RvciBsZXZlbCwgbm90IG9ubHkgZm9yIHRoZSB3aG9sZSBjb3VudHJ5LiBUaGlzIGdpdmVzIG1vcmUgc3BlY2lmaWMgYW5kIHVzZWZ1bCByZXN1bHRzLg0KDQojIyMgUm9sZSBvZiBCdXNpbmVzcyBJbnRlbGxpZ2VuY2UgYW5kIFByZWRpY3RpdmUgQW5hbHl0aWNzIGZvciBJZGVudGlmeWluZyBWdWxuZXJhYmlsaXR5IER1cmluZyBVU01DQSBOZWdvdGlhdGlvbnMNCg0K4oCiIEJ1c2luZXNzIEludGVsbGlnZW5jZSB0b29scyBjYW4gbWVhc3VyZSBob3cgbXVjaCBlYWNoIHN0YXRlIG9yIHNlY3RvciBkZXBlbmRzIG9uIGV4cG9ydHMgdG8gdGhlIFUuUy4gVGhpcyBoZWxwcyBpZGVudGlmeSB3aGljaCBvbmVzIGFyZSBtb3JlIGV4cG9zZWQgdG8gdGFyaWZmIGNoYW5nZXMuDQoNCuKAoiBQcmVkaWN0aXZlIG1vZGVscyBjYW4gZXN0aW1hdGUgaG93IHNlbnNpdGl2ZSBleHBvcnRzIGFyZSB0byBuZXcgdHJhZGUgcnVsZXMuIFdpdGggdGhpcywgd2UgY2FuIGNsYXNzaWZ5IHN0YXRlcyBvciBpbmR1c3RyaWVzIGJ5IGxldmVsIG9mIHJpc2suDQoNCuKAoiBEYXNoYm9hcmRzIGFuZCB2aXN1YWwgdG9vbHMgYWxsb3cgZGVjaXNpb24gbWFrZXJzIHRvIG1vbml0b3IgZXhwb3J0IHBlcmZvcm1hbmNlIGJlZm9yZSBhbmQgYWZ0ZXIgcG9saWN5IGNoYW5nZXMuDQoNCuKAoiBNYWNoaW5lIGxlYXJuaW5nIHRlY2huaXF1ZXMgY2FuIGdyb3VwIHN0YXRlcyBvciBzZWN0b3JzIHdpdGggc2ltaWxhciBleHBvcnQgc3RydWN0dXJlcy4gVGhpcyBoZWxwcyBpZGVudGlmeSBwYXR0ZXJucyBvZiB2dWxuZXJhYmlsaXR5IGR1cmluZyB0cmFkZSBuZWdvdGlhdGlvbnMuDQoNCiMjIyBFeHBvcnRzIERhdGEgQW5hbHlzaXMgDQojIyMjIERhdGEgQ2xlYW5pbmcgYW5kIFRyYW5zZm9ybWluZw0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkocGxtKQ0KbGlicmFyeShzZikNCmxpYnJhcnkocm5hdHVyYWxlYXJ0aCkNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHJlc2hhcGUyKQ0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkobG10ZXN0KQ0KbGlicmFyeShzYW5kd2ljaCkNCmxpYnJhcnkoY2FyKQ0KbGlicmFyeShkcGx5cikNCg0KYGBgDQoNCg0KYGBge3J9DQpkZl9leHBvIDwtIHJlYWRfZXhjZWwoIkM6L1VzZXJzL09zdmFsL0Rvd25sb2Fkcy9pbmVnaV9leHBvcnRzX2RhdGFzZXQueGxzeCIsIHNoZWV0ID0gImV4cG9ydHMiKQ0KZGZfdHMgPC0gcmVhZF9leGNlbCgiQzovVXNlcnMvT3N2YWwvRG93bmxvYWRzL2luZWdpX2V4cG9ydHNfZGF0YXNldC54bHN4Iiwgc2hlZXQgPSAidHNfZXhwb3J0cyIpDQpkZl9kYXRhIDwtIHJlYWRfZXhjZWwoIkM6L1VzZXJzL09zdmFsL0Rvd25sb2Fkcy9pbmVnaV9leHBvcnRzX2RhdGFzZXQueGxzeCIsIHNoZWV0ID0gImRhdGEiKQ0KZGZfZmRpIDwtIHJlYWRfZXhjZWwoIkM6L1VzZXJzL09zdmFsL0Rvd25sb2Fkcy9pbmVnaV9leHBvcnRzX2RhdGFzZXQueGxzeCIsIHNoZWV0ID0gImZkaSIpDQoNCmBgYA0KDQrigKIgVGhlIG9yaWdpbmFsIGRhdGFzZXRzIHdlcmUgY2xlYW5lZCBhbmQgdHJhbnNmb3JtZWQuIEV4cG9ydCB2YXJpYWJsZXMgd2VyZSBjb252ZXJ0ZWQgZnJvbSB3aWRlIGZvcm1hdCB0byBsb25nIGZvcm1hdCBzbyBlYWNoIHJvdyByZXByZXNlbnRzIG9uZSBzdGF0ZSBpbiBvbmUgc3BlY2lmaWMgeWVhci4NCg0KYGBge3J9DQpkZl9leHBvbG9uZyA8LSBkZl9leHBvICU+JQ0KICBwaXZvdF9sb25nZXIoDQogICAgY29scyA9IHN0YXJ0c193aXRoKCJyZWFsX2V4cG9ydHNfIiksDQogICAgbmFtZXNfdG8gPSAieWVhciIsDQogICAgbmFtZXNfcHJlZml4ID0gInJlYWxfZXhwb3J0c18iLA0KICAgIHZhbHVlc190byA9ICJyZWFsX2V4cG9ydHMiDQogICkNCg0KZGZfZmRpbG9uZyA8LSBkZl9mZGkgJT4lDQogIHBpdm90X2xvbmdlcigNCiAgICBjb2xzID0gc3RhcnRzX3dpdGgoImZkaV8iKSwNCiAgICBuYW1lc190byA9ICJ5ZWFyIiwNCiAgICBuYW1lc19wcmVmaXggPSAiZmRpXyIsDQogICAgdmFsdWVzX3RvID0gImZkaSINCiAgKQ0KDQpgYGANCg0K4oCiIFdlIHZlcmlmaWVkIHRoYXQgdGhlcmUgd2VyZSBubyBkdXBsaWNhdGVkIG9ic2VydmF0aW9ucyBieSBzdGF0ZSBhbmQgeWVhciBiZWZvcmUgbWVyZ2luZyB0aGUgZGF0YXNldHMuDQoNCg0KYGBge3J9DQpkZl9leHBvbG9uZyAlPiUgY291bnQoc3RhdGUsIHllYXIsIHJlZ2lvbikgJT4lIGZpbHRlcihuID4gMSkNCmRmX2RhdGEgJT4lIGNvdW50KHN0YXRlLCB5ZWFyKSAlPiUgZmlsdGVyKG4gPiAxKQ0KZGZfZmRpbG9uZyAlPiUgY291bnQoc3RhdGUsIHllYXIsIHJlZ2lvbikgJT4lIGZpbHRlcihuID4gMSkNCg0KYGBgDQoNCuKAoiBEaWZmZXJlbnQgZGF0YXNldHMgKGV4cG9ydHMsIEZESSwgbWFjcm9lY29ub21pYyB2YXJpYWJsZXMsIGFuZCBzdGF0ZSBjaGFyYWN0ZXJpc3RpY3MpIHdlcmUgbWVyZ2VkIHVzaW5nIHN0YXRlIGFuZCB5ZWFyIGFzIGtleSB2YXJpYWJsZXMuDQoNCmBgYHtyfQ0KZGZfZXhwb2xvbmckeWVhciA8LSBhcy5udW1lcmljKGRmX2V4cG9sb25nJHllYXIpDQpkZl9mZGlsb25nJHllYXIgPC0gYXMubnVtZXJpYyhkZl9mZGlsb25nJHllYXIpDQpkZl9kYXRhJHllYXIgPC0gYXMubnVtZXJpYyhkZl9kYXRhJHllYXIpDQoNCmBgYA0KDQpgYGB7cn0NCnBhbmVsX2Z1bGwgPC0gZGZfZXhwb2xvbmcgJT4lDQogIGxlZnRfam9pbihkZl9mZGlsb25nLCBieSA9IGMoInN0YXRlIiwgInllYXIiLCAicmVnaW9uIikpICU+JQ0KICBsZWZ0X2pvaW4oZGZfZGF0YSwgYnkgPSBjKCJzdGF0ZSIsICJ5ZWFyIikpDQoNCmBgYA0KDQrigKIgTWlzc2luZyB2YWx1ZXMgd2VyZSByZXBsYWNlZCB1c2luZyB0aGUgYXZlcmFnZSB2YWx1ZSBieSBzdGF0ZSBpbiBvcmRlciB0byBtYWludGFpbiBhIGJhbGFuY2VkIHBhbmVsIHN0cnVjdHVyZS4NCg0KYGBge3J9DQpwYW5lbF9mdWxsIDwtIHBhbmVsX2Z1bGwgJT4lDQogIGdyb3VwX2J5KHN0YXRlKSAlPiUNCiAgbXV0YXRlKA0KICAgIGFjcm9zcygNCiAgICAgIHdoZXJlKGlzLm51bWVyaWMpLCANCiAgICAgIH4gaWZlbHNlKGlzLm5hKC4pLCBtZWFuKC4sIG5hLnJtID0gVFJVRSksIC4pDQogICAgKQ0KICApICU+JQ0KICB1bmdyb3VwKCkNCg0KYGBgDQoNCuKAoiBBIHBhbmVsIGRhdGFzZXQgd2FzIGNyZWF0ZWQgdXNpbmcgc3RhdGUgYW5kIHllYXIgYXMgaW5kZXhlcywgYWxsb3dpbmcgYW5hbHlzaXMgYWNyb3NzIHRpbWUgYW5kIGFjcm9zcyByZWdpb25zLg0KDQpgYGB7cn0NCnBhbmVsX2RhdGEgPC0gcGRhdGEuZnJhbWUocGFuZWxfZnVsbCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBjKCJzdGF0ZSIsICJ5ZWFyIikpDQpgYGANCg0KDQojIyBFeHBsb3JhdG9yeSBEYXRhIEFuYWx5c2lzIOKAkyBFREENCg0KIyMjIERlc2NyaXB0aXZlIFN0YXRpc3RpY3MNCg0KYGBge3J9DQpyZWdpb25hbF9hdmcgPC0gcGFuZWxfZnVsbCAlPiUNCiAgZ3JvdXBfYnkocmVnaW9uKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIGF2Z19leHBvcnRzID0gbWVhbihyZWFsX2V4cG9ydHMsIG5hLnJtID0gVFJVRSksDQogICAgYXZnX2ZkaSA9IG1lYW4oZmRpLCBuYS5ybSA9IFRSVUUpLA0KICAgIGF2Z19leGNoYW5nZV9yYXRlID0gbWVhbihleGNoYW5nZV9yYXRlLCBuYS5ybSA9IFRSVUUpLA0KICAgIGF2Z19jb2xsZWdlID0gbWVhbihjb2xsZWdlX2VkdWNhdGlvbiwgbmEucm0gPSBUUlVFKSwNCiAgICAuZ3JvdXBzID0gImRyb3AiDQogICkNCmdncGxvdChyZWdpb25hbF9hdmcsIGFlcyh4ID0gcmVnaW9uLCB5ID0gYXZnX2V4cG9ydHMpKSArDQogIGdlb21fY29sKCkgKw0KICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgRXhwb3J0cyBieSBSZWdpb24iLA0KICAgICAgIHggPSAiUmVnaW9uIiwNCiAgICAgICB5ID0gIkF2ZXJhZ2UgUmVhbCBFeHBvcnRzIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQpgYGB7cn0NCmdncGxvdChyZWdpb25hbF9hdmcsIGFlcyh4ID0gcmVnaW9uLCB5ID0gYXZnX2ZkaSkpICsNCiAgZ2VvbV9jb2woKSArDQogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBGREkgYnkgUmVnaW9uIiwNCiAgICAgICB4ID0gIlJlZ2lvbiIsDQogICAgICAgeSA9ICJBdmVyYWdlIEZESSIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmBgYA0KDQpgYGB7cn0NCmdncGxvdChyZWdpb25hbF9hdmcsIGFlcyh4ID0gcmVnaW9uLCB5ID0gYXZnX2NvbGxlZ2UpKSArDQogIGdlb21fY29sKCkgKw0KICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgQ29sbGVnZSBFZHVjYXRpb24gYnkgUmVnaW9uIiwNCiAgICAgICB4ID0gIlJlZ2lvbiIsDQogICAgICAgeSA9ICJBdmVyYWdlIENvbGxlZ2UgRWR1Y2F0aW9uIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQpgYGB7cn0NCmdncGxvdChwYW5lbF9mdWxsLCBhZXMoeCA9IHJlYWxfZXhwb3J0cykpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDMwKSArDQogIGxhYnModGl0bGUgPSAiRGlzdHJpYnV0aW9uIG9mIFJlYWwgRXhwb3J0cyIsDQogICAgICAgeCA9ICJSZWFsIEV4cG9ydHMiLA0KICAgICAgIHkgPSAiRnJlcXVlbmN5IikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQpgYGB7cn0NCmdncGxvdChwYW5lbF9mdWxsLCBhZXMoeCA9IGZkaSkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDMwKSArDQogIGxhYnModGl0bGUgPSAiRGlzdHJpYnV0aW9uIG9mIEZESSIsDQogICAgICAgeCA9ICJGREkiLA0KICAgICAgIHkgPSAiRnJlcXVlbmN5IikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQpgYGB7cn0NCmdncGxvdChwYW5lbF9mdWxsLCBhZXMoeCA9IGNvbGxlZ2VfZWR1Y2F0aW9uKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMzApICsNCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidXRpb24gb2YgQ29sbGVnZSBFZHVjYXRpb24iLA0KICAgICAgIHggPSAiQ29sbGVnZSBFZHVjYXRpb24iLA0KICAgICAgIHkgPSAiRnJlcXVlbmN5IikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQoNCiMjIyBTdGF0aXN0aWNzIG9mIERpc3BlcnNpb24NCg0KYGBge3J9DQpnZ3Bsb3QocGFuZWxfZnVsbCwgYWVzKHggPSByZWdpb24sIHkgPSByZWFsX2V4cG9ydHMpKSArDQogIGdlb21fYm94cGxvdCgpICsNCiAgbGFicyh0aXRsZSA9ICJFeHBvcnRzIERpc3RyaWJ1dGlvbiBBY3Jvc3MgUmVnaW9ucyIsDQogICAgICAgeCA9ICJSZWdpb24iLA0KICAgICAgIHkgPSAiUmVhbCBFeHBvcnRzIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQpgYGB7cn0NCmdncGxvdChwYW5lbF9mdWxsLCBhZXMoeCA9IHJlZ2lvbiwgeSA9IGZkaSkpICsNCiAgZ2VvbV9ib3hwbG90KCkgKw0KICBsYWJzKHRpdGxlID0gIkZESSBEaXN0cmlidXRpb24gQWNyb3NzIFJlZ2lvbnMiLA0KICAgICAgIHggPSAiUmVnaW9uIiwNCiAgICAgICB5ID0gIkZESSIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmBgYA0KDQpgYGB7cn0NCmdncGxvdChwYW5lbF9mdWxsLCBhZXMoeCA9IHJlZ2lvbiwgeSA9IGxxX3ByaW1hcnkpKSArDQogIGdlb21fYm94cGxvdCgpICsNCiAgbGFicyh0aXRsZSA9ICJDb2xsZWdlIEVkdWNhdGlvbiBBY3Jvc3MgUmVnaW9ucyIsDQogICAgICAgeCA9ICJSZWdpb24iLA0KICAgICAgIHkgPSAiQ29sbGVnZSBFZHVjYXRpb24iKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQpgYGANCmBgYHtyfQ0KZ2dwbG90KHBhbmVsX2Z1bGwsIGFlcyh4ID0gcmVnaW9uLCB5ID0gbHFfc2Vjb25kYXJ5KSkgKw0KICBnZW9tX2JveHBsb3QoKSArDQogIGxhYnModGl0bGUgPSAiQ29sbGVnZSBFZHVjYXRpb24gQWNyb3NzIFJlZ2lvbnMiLA0KICAgICAgIHggPSAiUmVnaW9uIiwNCiAgICAgICB5ID0gIkNvbGxlZ2UgRWR1Y2F0aW9uIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQoNCiMjIyBWaXN1YWxpemF0aW9uIGFjcm9zcyBUaW1lDQoNCg0KYGBge3J9DQpleHBvcnRzX3RpbWUgPC0gcGFuZWxfZnVsbCAlPiUNCiAgZ3JvdXBfYnkoeWVhcikgJT4lDQogIHN1bW1hcmlzZSh0b3RhbF9leHBvcnRzID0gc3VtKHJlYWxfZXhwb3J0cywgbmEucm0gPSBUUlVFKSkNCg0KZ2dwbG90KGV4cG9ydHNfdGltZSwgYWVzKHggPSB5ZWFyLCB5ID0gdG90YWxfZXhwb3J0cykpICsNCiAgZ2VvbV9saW5lKHNpemUgPSAxKSArDQogIGxhYnModGl0bGUgPSAiVG90YWwgRXhwb3J0cyBJbmZsb3dzIGluIE1leGljbyIsDQogICAgICAgeCA9ICJZZWFyIiwNCiAgICAgICB5ID0gIlRvdGFsIFJlYWwgRXhwb3J0cyIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCuKAoiBUb3RhbCBleHBvcnRzIHNob3cgYSBjbGVhciB1cHdhcmQgdHJlbmQgb3ZlciB0aGUgcGVyaW9kLiBUaGVyZSBpcyBhIHRlbXBvcmFyeSBkZWNsaW5lIGFyb3VuZCB0aGUgQ09WSUQtMTkgcGVyaW9kLCBidXQgZXhwb3J0cyByZWNvdmVyIHF1aWNrbHkgYW5kIGNvbnRpbnVlIGdyb3dpbmcuDQoNCg0KYGBge3J9DQpleHBvcnRzX3JlZ2lvbiA8LSBwYW5lbF9mdWxsICU+JQ0KICBncm91cF9ieShyZWdpb24sIHllYXIpICU+JQ0KICBzdW1tYXJpc2UodG90YWxfZXhwb3J0cyA9IHN1bShyZWFsX2V4cG9ydHMsIG5hLnJtID0gVFJVRSksDQogICAgICAgICAgICAuZ3JvdXBzID0gImRyb3AiKQ0KDQpnZ3Bsb3QoZXhwb3J0c19yZWdpb24sIGFlcyh4ID0geWVhciwgeSA9IHRvdGFsX2V4cG9ydHMsIGNvbG9yID0gcmVnaW9uKSkgKw0KICBnZW9tX2xpbmUobGluZXdpZHRoID0gMSkgKw0KICBsYWJzKHRpdGxlID0gIlRvdGFsIEV4cG9ydHMgSW5mbG93cyBieSBSZWdpb24iLA0KICAgICAgIHggPSAiWWVhciIsDQogICAgICAgeSA9ICJUb3RhbCBSZWFsIEV4cG9ydHMiLA0KICAgICAgIGNvbG9yID0gIlJlZ2lvbiIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmBgYA0K4oCiIE5vcnRoZXJuIHJlZ2lvbnMgc2hvdyBoaWdoZXIgZXhwb3J0IGxldmVscyBjb21wYXJlZCB0byBzb3V0aGVybiByZWdpb25zLg0KDQrigKIgVGhlIGdhcCBiZXR3ZWVuIHJlZ2lvbnMgcmVtYWlucyBwZXJzaXN0ZW50IG92ZXIgdGltZSwgd2hpY2ggc3VnZ2VzdHMgc3RydWN0dXJhbCBkaWZmZXJlbmNlcyBpbiBpbmR1c3RyaWFsIGRldmVsb3BtZW50Lg0KYGBge3J9DQptYWNyb190aW1lIDwtIHBhbmVsX2Z1bGwgJT4lDQogIGdyb3VwX2J5KHllYXIpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgdG90YWxfZXhwb3J0cyA9IHN1bShyZWFsX2V4cG9ydHMsIG5hLnJtID0gVFJVRSksDQogICAgYXZnX2V4Y2hhbmdlX3JhdGUgPSBtZWFuKGV4Y2hhbmdlX3JhdGUsIG5hLnJtID0gVFJVRSksDQogICAgLmdyb3VwcyA9ICJkcm9wIg0KICApDQptYWNyb190aW1lIDwtIG1hY3JvX3RpbWUgJT4lDQogIG11dGF0ZSgNCiAgICBleHBvcnRzX2luZGV4ID0gdG90YWxfZXhwb3J0cyAvIG1heCh0b3RhbF9leHBvcnRzKSwNCiAgICBleGNoYW5nZV9pbmRleCA9IGF2Z19leGNoYW5nZV9yYXRlIC8gbWF4KGF2Z19leGNoYW5nZV9yYXRlKQ0KICApDQpnZ3Bsb3QobWFjcm9fdGltZSwgYWVzKHggPSB5ZWFyKSkgKw0KICBnZW9tX2xpbmUoYWVzKHkgPSBleHBvcnRzX2luZGV4LCBjb2xvciA9ICJFeHBvcnRzIiksIGxpbmV3aWR0aCA9IDEuMikgKw0KICBnZW9tX2xpbmUoYWVzKHkgPSBleGNoYW5nZV9pbmRleCwgY29sb3IgPSAiRXhjaGFuZ2UgUmF0ZSIpLCBsaW5ld2lkdGggPSAxLjIpICsNCiAgbGFicyh0aXRsZSA9ICJFeHBvcnRzIEluZmxvd3MgdnMgRXhjaGFuZ2UgUmF0ZSAoSW5kZXhlZCkiLA0KICAgICAgIHggPSAiWWVhciIsDQogICAgICAgeSA9ICJJbmRleGVkIFZhbHVlcyIsDQogICAgICAgY29sb3IgPSAiIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQrigKIgV2hlbiBjb21wYXJpbmcgaW5kZXhlZCBleHBvcnRzIGFuZCBleGNoYW5nZSByYXRlLCBib3RoIHZhcmlhYmxlcyBzaG93IHNpbWlsYXIgbW92ZW1lbnRzIGluIHNvbWUgeWVhcnMuDQoNCuKAoiBUaGlzIHN1Z2dlc3RzIHRoYXQgZXhjaGFuZ2UgcmF0ZSBmbHVjdHVhdGlvbnMgbWF5IGluZmx1ZW5jZSBleHBvcnQgcGVyZm9ybWFuY2UsIGFsdGhvdWdoIHRoZSByZWxhdGlvbnNoaXAgaXMgbm90IHBlcmZlY3RseSBsaW5lYXIuDQoNCiMjI1JlZ2lvbmFsIERpZmZlcmVuY2VzDQoNCmBgYHtyfQ0KcGFuZWxfZnVsbCA8LSBwYW5lbF9mdWxsICU+JQ0KICBtdXRhdGUoem9uZSA9IGlmZWxzZShib3JkZXJfZGlzdGFuY2UgPCA0MDAsICJOb3J0aCIsICJTb3V0aCIpKQ0KcGFuZWxfZnVsbCA8LSBwYW5lbF9mdWxsICU+JQ0KICBtdXRhdGUoem9uZSA9IGlmZWxzZShyZWdpb24gJWluJSBjKCJOb3JvZXN0ZSIsICJOb3Jlc3RlIiksIA0KICAgICAgICAgICAgICAgICAgICAgICAiTm9ydGgiLCANCiAgICAgICAgICAgICAgICAgICAgICAgIlNvdXRoIikpDQpub3J0aF9zb3V0aF9leHBvcnRzIDwtIHBhbmVsX2Z1bGwgJT4lDQogIGdyb3VwX2J5KHpvbmUpICU+JQ0KICBzdW1tYXJpc2UoYXZnX2V4cG9ydHMgPSBtZWFuKHJlYWxfZXhwb3J0cywgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgICAgIC5ncm91cHMgPSAiZHJvcCIpDQpnZ3Bsb3Qobm9ydGhfc291dGhfZXhwb3J0cywgYWVzKHggPSB6b25lLCB5ID0gYXZnX2V4cG9ydHMpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBFeHBvcnRzIEluZmxvd3M6IE5vcnRoIHZzIFNvdXRoIiwNCiAgICAgICB4ID0gIlJlZ2lvbiIsDQogICAgICAgeSA9ICJBdmVyYWdlIFJlYWwgRXhwb3J0cyIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCg0KYGBgDQoNCuKAoiBTdGF0ZXMgY2xhc3NpZmllZCBhcyDigJxOb3J0aOKAnSBoYXZlIHNpZ25pZmljYW50bHkgaGlnaGVyIGF2ZXJhZ2UgZXhwb3J0cyB0aGFuIHRob3NlIGluIHRoZSDigJxTb3V0aC7igJ0NCg0K4oCiIFRoaXMgY29uZmlybXMgdGhlIGltcG9ydGFuY2Ugb2YgZ2VvZ3JhcGhpYyBwcm94aW1pdHkgdG8gdGhlIFUuUy4gYm9yZGVyIGFuZCBpbmR1c3RyaWFsIGNvbmNlbnRyYXRpbw0KDQrigKIgTm9ydGhlcm4gc3RhdGVzIHNob3cgbXVjaCBoaWdoZXIgZXhwb3J0IHZvbHVtZXMuIFNvdXRoZXJuIHN0YXRlcyBwYXJ0aWNpcGF0ZSBsZXNzIGluIGludGVybmF0aW9uYWwgdHJhZGUuDQoNCuKAoiBHZW9ncmFwaGljIHByb3hpbWl0eSB0byB0aGUgVS5TLiBib3JkZXIgaXMgYSBpbXByb3RhbnQgZmFjdG9yLiBOb3J0aGVybiBzdGF0ZXMgYmVuZWZpdCBmcm9tIGxvd2VyIHRyYW5zcG9ydGF0aW9uIGNvc3RzIGFuZCBiZXR0ZXIgYWNjZXNzIHRvIGNyb3NzLWJvcmRlciBpbmZyYXN0cnVjdHVyZS4NCg0K4oCiIEluZHVzdHJpYWwgc3RydWN0dXJlIGlzIGRpZmZlcmVudC4gTm9ydGhlcm4gc3RhdGVzIGhhdmUgaGlnaGVyIGNvbmNlbnRyYXRpb24gaW4gbWFudWZhY3R1cmluZyBhbmQgZXhwb3J0LW9yaWVudGVkIGluZHVzdHJpZXMsIHdoaWxlIHNvdXRoZXJuIHN0YXRlcyBtb3JlIG9uIHByaW1hcnkgYWN0aXZpdGllcyBvciBzZXJ2aWNlcy4NCg0K4oCiIEZvcmVpZ24gRGlyZWN0IEludmVzdG1lbnQgaXMgbW9yZSBjb25jZW50cmF0ZWQgaW4gdGhlIE5vcnRoLiBNYW55IG11bHRpbmF0aW9uYWwgZmlybXMgYXJlIGxvY2F0ZWQgaW4gbm9ydGhlcm4gc3RhdGVzIGR1ZSB0byB0aGVpciBjb25uZWN0aW9uIHdpdGggVS5TLiBtYXJrZXRzLg0KDQrigKIgSW5mcmFzdHJ1Y3R1cmUgYW5kIGNvbm5lY3Rpdml0eSBhcmUgZ2VuZXJhbGx5IHN0cm9uZ2VyIGluIG5vcnRoZXJuIHN0YXRlcywgaW5jbHVkaW5nIGhpZ2h3YXlzLCBpbmR1c3RyaWFsIHBhcmtzLCBhbmQgY3VzdG9tcyBmYWNpbGl0aWVzLCB3aGljaCBmYWNpbGl0YXRlIGludGVybmF0aW9uYWwgdHJhZGUuDQoNCmBgYHtyfQ0KbWV4aWNvX21hcCA8LSBuZV9zdGF0ZXMoY291bnRyeSA9ICJtZXhpY28iLCByZXR1cm5jbGFzcyA9ICJzZiIpDQoNCnNldGRpZmYobWV4aWNvX21hcCRuYW1lLCBwYW5lbF9kYXRhJHN0YXRlKQ0KDQoNCmBgYA0KYGBge3J9DQptZXhpY29fbWFwIDwtIG5lX3N0YXRlcyhjb3VudHJ5ID0gIm1leGljbyIsIHJldHVybmNsYXNzID0gInNmIikNCg0Kc2V0ZGlmZihwYW5lbF9kYXRhJHN0YXRlLCBtZXhpY29fbWFwJG5hbWUpDQpgYGANCg0KYGBge3J9DQoNCnBhbmVsX2Z1bGwkc3RhdGUgPC0gZHBseXI6OnJlY29kZShwYW5lbF9mdWxsJHN0YXRlLA0KICAiQ2l1ZGFkIGRlIE1leGljbyIgPSAiRGlzdHJpdG8gRmVkZXJhbCIsDQogICJNaWNob2FjYW4iID0gIk1pY2hvYWPDoW4iLA0KICAiUXVlcmV0YXJvIiA9ICJRdWVyw6l0YXJvIiwNCiAgIk1leGljbyIgPSAiTcOpeGljbyIsDQogICJTYW4gTHVpcyBQb3Rvc2kiID0gIlNhbiBMdWlzIFBvdG9zw60iLA0KICAiWXVjYXRhbiIgPSAiWXVjYXTDoW4iLA0KICAiTnVldm8gTGVvbiIgPSAiTnVldm8gTGXDs24iDQopDQoNCmBgYA0KDQrigKIgQm9yZGVyIHN0YXRlcyBzdWNoIGFzIENoaWh1YWh1YSBhbmQgb3RoZXIgbm9ydGhlcm4gc3RhdGVzIHNob3cgaGlnaGVyIGV4cG9ydCBsZXZlbHMuDQoNCmBgYHtyfQ0KYXZnX3N0YXRlX2V4cG9ydHMgPC0gcGFuZWxfZnVsbCAlPiUNCiAgZ3JvdXBfYnkoc3RhdGUpICU+JQ0KICBzdW1tYXJpc2UoYXZnX2V4cG9ydHMgPSBtZWFuKHJlYWxfZXhwb3J0cywgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgICAgIC5ncm91cHMgPSAiZHJvcCIpDQptYXBfZGF0YSA8LSBtZXhpY29fbWFwICU+JQ0KICBsZWZ0X2pvaW4oYXZnX3N0YXRlX2V4cG9ydHMsIGJ5ID0gYygibmFtZSIgPSAic3RhdGUiKSkNCmdncGxvdChtYXBfZGF0YSkgKw0KICBnZW9tX3NmKGFlcyhmaWxsID0gYXZnX2V4cG9ydHMpKSArDQogIHNjYWxlX2ZpbGxfdmlyaWRpc19jKG9wdGlvbiA9ICJtYWtvIiwgbmEudmFsdWUgPSAiZ3JleTkwIikgKw0KICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgRXhwb3J0cyBJbmZsb3dzIGJ5IE1leGljYW4gU3RhdGUiLA0KICAgICAgIGZpbGwgPSAiQXZnIEV4cG9ydHMiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQpgYGANCg0KIyMjIENvcnJlbGF0aW9uIGFuZCBSZWxhdGlvbnNoaXBzDQoNCmBgYHtyfQ0Kc2NhbGVfZmlsbF9ncmFkaWVudDIoDQogIGxvdyA9ICJibHVlIiwNCiAgbWlkID0gIndoaXRlIiwNCiAgaGlnaCA9ICJyZWQiLA0KICBtaWRwb2ludCA9IDAsDQogIGxpbWl0cyA9IGMoLTEsIDEpDQopDQpjb3JyX2RhdGEgPC0gcGFuZWxfZGF0YSAlPiUNCiAgc2VsZWN0KHJlYWxfZXhwb3J0cywgZXhjaGFuZ2VfcmF0ZSwgcG9wX2RlbnNpdHksIGZkaSwgYm9yZGVyX2Rpc3RhbmNlLCBscV9wcmltYXJ5LGxxX3NlY29uZGFyeSxscV90ZXJ0aWFyeSwgYXZlcmFnZV9kYWlseV9zYWxhcnksIGNyaW1lX3JhdGUpICU+JQ0KICBkcm9wX25hKCkNCg0KY29ycl9tYXRyaXggPC0gY29yKGNvcnJfZGF0YSkNCg0KY29ycl9sb25nIDwtIGFzLmRhdGEuZnJhbWUoYXMudGFibGUoY29ycl9tYXRyaXgpKQ0KDQpnZ3Bsb3QoY29ycl9sb25nLCBhZXMoVmFyMSwgVmFyMiwgZmlsbCA9IEZyZXEpKSArDQogIGdlb21fdGlsZSgpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudDIoDQogICAgbG93ID0gImJsdWUiLA0KICAgIG1pZCA9ICJ3aGl0ZSIsDQogICAgaGlnaCA9ICJyZWQiLA0KICAgIG1pZHBvaW50ID0gMCwNCiAgICBsaW1pdHMgPSBjKC0xLCAxKQ0KICApICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKEZyZXEsIDIpKSwgc2l6ZSA9IDQpICsNCiAgbGFicyh0aXRsZSA9ICJDb3JyZWxhdGlvbiBNYXRyaXgiLA0KICAgICAgIHggPSAiIiwNCiAgICAgICB5ID0gIiIsDQogICAgICAgZmlsbCA9ICJDb3JyZWxhdGlvbiIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCg0KDQpgYGANCg0K4oCiIEV4cG9ydHMgc2hvdyBwb3NpdGl2ZSBjb3JyZWxhdGlvbiB3aXRoIEZESSBhbmQgZW1wbG95bWVudCBjb25jZW50cmF0aW9uIGluIHRoZSBzZWNvbmRhcnkgc2VjdG9yLg0KDQrigKIgVGhlcmUgaXMgYSBuZWdhdGl2ZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBib3JkZXIgZGlzdGFuY2UgYW5kIGV4cG9ydHMsIG1lYW5pbmcgdGhhdCBzdGF0ZXMgY2xvc2VyIHRvIHRoZSBVLlMuIHRlbmQgdG8gZXhwb3J0IG1vcmUuDQoNCuKAoiBTb21lIHNvY2lvZWNvbm9taWMgdmFyaWFibGVzIHN1Y2ggYXMgc2FsYXJ5IGFsc28gc2hvdyBwb3NpdGl2ZSBhc3NvY2lhdGlvbiB3aXRoIGV4cG9ydHMsIHN1Z2dlc3RpbmcgdGhhdCBtb3JlIGluZHVzdHJpYWxpemVkIHN0YXRlcyBoYXZlIGhpZ2hlciBpbmNvbWUgbGV2ZWxzLg0KDQpgYGB7cn0NCmdncGxvdChwYW5lbF9mdWxsLCBhZXMoeCA9IGJvcmRlcl9kaXN0YW5jZSwgeSA9IHJlYWxfZXhwb3J0cykpICsNCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNikgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IFRSVUUsIGNvbG9yID0gImJsYWNrIikgKw0KICBsYWJzKHRpdGxlID0gIkV4cG9ydHMgSW5mbG93cyB2cyBCb3JkZXIgRGlzYW5jZSIsDQogICAgICAgeCA9ICJCb3JkZXIgRGlzYW5jZSIsDQogICAgICAgeSA9ICJFeHBvcnRzIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQoNCuKAoiBUaGUgcmVncmVzc2lvbiBsaW5lIHNob3dzIGEgbmVnYXRpdmUgc2xvcGUuIFN0YXRlcyBmYXJ0aGVyIGZyb20gdGhlIGJvcmRlciB0ZW5kIHRvIGhhdmUgbG93ZXIgZXhwb3J0IGxldmVscy4NCg0KYGBge3J9DQpnZ3Bsb3QocGFuZWxfZnVsbCwgYWVzKHggPSBscV9zZWNvbmRhcnksIHkgPSByZWFsX2V4cG9ydHMpKSArDQogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjYpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBUUlVFLCBjb2xvciA9ICJibGFjayIpICsNCiAgbGFicyh0aXRsZSA9ICJFeHBvcnRzIEluZmxvd3MgdnMgRW1wbG95bWVudCBjb25jZW50cmF0aW9uIGluIHRoZSBzZWNvbmRhcnkgc2VjdG9yIiwNCiAgICAgICB4ID0gIkVtcGxveW1lbnQgY29uY2VudHJhdGlvbiBpbiB0aGUgc2Vjb25kYXJ5IHNlY3RvciIsDQogICAgICAgeSA9ICJSZWFsIEV4cG9ydHMiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQpgYGANCuKAoiBUaGVyZSBpcyBhIHBvc2l0aXZlIHJlbGF0aW9uc2hpcC4gU3RhdGVzIHdpdGggc3Ryb25nZXIgaW5kdXN0cmlhbCBzcGVjaWFsaXphdGlvbiBleHBvcnQgbW9yZS4NCg0KYGBge3J9DQpnZ3Bsb3QocGFuZWxfZnVsbCwgYWVzKHggPSBhdmVyYWdlX2RhaWx5X3NhbGFyeSwgeSA9IHJlYWxfZXhwb3J0cykpICsNCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNikgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IFRSVUUsIGNvbG9yID0gImJsYWNrIikgKw0KICBsYWJzKHRpdGxlID0gIkV4cG9ydHMgSW5mbG93cyB2cyBBdmVyYWdlIERhaWx5IFNhbGFyeSIsDQogICAgICAgeCA9ICJBdmVyYWdlIERhaWx5IFNhbGFyeSIsDQogICAgICAgeSA9ICJSZWFsIEV4cG9ydHMiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQpgYGANCg0K4oCiIFRoZSByZWxhdGlvbnNoaXAgYXBwZWFycyBwb3NpdGl2ZSwgc3VnZ2VzdGluZyB0aGF0IGhpZ2hlciBwcm9kdWN0aXZpdHkgYW5kIGluZHVzdHJpYWxpemF0aW9uIGFyZSBsaW5rZWQgdG8gaGlnaGVyIHdhZ2VzIGFuZCBleHBvcnRzLg0KDQojI0h5cG90aGVzZXMgU3RhdGVtZW50cw0KDQrigKIgSDE6IFN0YXRlcyB3aXRoIGhpZ2hlciBlbXBsb3ltZW50IGNvbmNlbnRyYXRpb24gaW4gdGhlIHNlY29uZGFyeSAoaW5kdXN0cmlhbCBzcGVjaWFsaXphdGlvbikgIGFuZCB0aGlyZCAoc2VydmljZXMpIHNlY3RvciBoYXZlIHNpZ25pZmljYW50bHkgaGlnaGVyIGV4cG9ydCBsZXZlbHMuDQoNCuKAoiBIMjogQm9yZGVyIGRpc3RhbmNlIGhhcyBhIG5lZ2F0aXZlIGFuZCBzaWduaWZpY2FudCBlZmZlY3Qgb24gZXhwb3J0cy4gU3RhdGVzIGNsb3NlciB0byB0aGUgVS5TLiBib3JkZXIgZXhwb3J0IG1vcmUgdGhhbiBzdGF0ZXMgbG9jYXRlZCBmYXJ0aGVyIGF3YXkuDQoNCuKAoiBIMzogSGlnaGVyIGxldmVscyBvZiBGb3JlaWduIERpcmVjdCBJbnZlc3RtZW50IChGREkpIHBvc2l0aXZlbHkgYWZmZWN0IGV4cG9ydCBwZXJmb3JtYW5jZSBhdCB0aGUgc3RhdGUgbGV2ZWwuDQoNCuKAoiBINDogU3RhdGVzIHdpdGggaGlnaGVyIGF2ZXJhZ2Ugd2FnZXMsIGFzIGEgcHJveHkgZm9yIHByb2R1Y3Rpdml0eSBhbmQgaW5kdXN0cmlhbCBkZXZlbG9wbWVudCwgc2hvdyBoaWdoZXIgZXhwb3J0IHBlcmZvcm1hbmNlLg0KDQoNCiMjIE1haW4gRmluZGluZ3MNCg0K4oCiIFRvdGFsIGV4cG9ydHMgc2hvdyBmbHVjdHVhdGlvbnMgb3ZlciB0aW1lLCB3aXRoIGluY3JlYXNlcyBhbmQgZGVjcmVhc2VzIGZyb20gb25lIHllYXIgdG8gYW5vdGhlci4NCg0K4oCiIE5vcnRoZXJuIHN0YXRlcyBjb25zaXN0ZW50bHkgc2hvdyBoaWdoZXIgZXhwb3J0IGxldmVscyB0aGFuIHNvdXRoZXJuIHN0YXRlcy4NCg0K4oCiIFRoZSBzY2F0dGVyIHBsb3Qgb2YgZXhwb3J0cyB2ZXJzdXMgYm9yZGVyIGRpc3RhbmNlIHNob3dzIGEgbmVnYXRpdmUgcmVsYXRpb25zaGlwLiBTdGF0ZXMgY2xvc2VyIHRvIHRoZSBVLlMuIGJvcmRlciB0ZW5kIHRvIGV4cG9ydCBtb3JlLg0KDQrigKIgVGhlcmUgaXMgYSBwb3NpdGl2ZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBleHBvcnRzIGFuZCBlbXBsb3ltZW50IGNvbmNlbnRyYXRpb24gaW4gdGhlIHNlY29uZGFyeSBzZWN0b3IuIFN0YXRlcyB3aXRoIHN0cm9uZ2VyIG1hbnVmYWN0dXJpbmcgbGFib3IgdGVuZCB0byBhY2hpZXZlIGhpZ2hlciBleHBvcnQgbGV2ZWxzLg0KDQrigKIgRXhwb3J0cyBhcmUgcG9zaXRpdmVseSBjb3JyZWxhdGVkIHdpdGggRkRJIGFuZCBhdmVyYWdlIGRhaWx5IHNhbGFyeS4gVGhpcyBzdWdnZXN0cyB0aGF0IG1vcmUgaW5kdXN0cmlhbGl6ZWQgc3RhdGVzIHBlcmZvcm0gYmV0dGVyIGluIGludGVybmF0aW9uYWwgdHJhZGUuDQoNCiNNb2RlbA0KIyMgRGlmZmVyZW5jZXMNCg0K4oCiIFR5cGUgb2YgZGF0YSB1c2VkDQpvIENyb3NzLXNlY3Rpb25hbDogQW5hbHl6ZXMgbWFueSBpbmRpdmlkdWFscyAocGVvcGxlLCBmaXJtcywgY291bnRyaWVzLCBldGMuKSBhdCBhIHNpbmdsZSBwb2ludCBpbiB0aW1lLg0KbyBUaW1lIHNlcmllczogQW5hbHl6ZXMgb25lIGluZGl2aWR1YWwgb3IgdmFyaWFibGUgb3ZlciBhIHBlcmlvZCBvZiB0aW1lLg0KbyBQYW5lbCBkYXRhOiBDb21iaW5lcyBib3RoOyBhbmFseXplcyBtdWx0aXBsZSBpbmRpdmlkdWFscyBhY3Jvc3MgbXVsdGlwbGUgdGltZSBwZXJpb2RzLg0KDQrigKIgRGltZW5zaW9uIG9mIGFuYWx5c2lzDQpvIENyb3NzLXNlY3Rpb25hbDogSGFzIG9ubHkgYW4gaW5kaXZpZHVhbCBkaW1lbnNpb24gKE4pLg0KbyBUaW1lIHNlcmllczogSGFzIG9ubHkgYSB0aW1lIGRpbWVuc2lvbiAoVCkuDQpvIFBhbmVsIGRhdGE6IEhhcyBib3RoIGFuIGluZGl2aWR1YWwgZGltZW5zaW9uIChOKSBhbmQgYSB0aW1lIGRpbWVuc2lvbiAoVCkgc2ltdWx0YW5lb3VzbHkuDQoNCuKAoiBUeXBlIG9mIHZhcmlhYmlsaXR5IGNhcHR1cmVkDQpvIENyb3NzLXNlY3Rpb25hbDogQ29tcGFyZXMgZGlmZmVyZW5jZXMgYmV0d2VlbiBpbmRpdmlkdWFscy4NCm8gVGltZSBzZXJpZXM6IEV4YW1pbmVzIGNoYW5nZXMgb3ZlciB0aW1lLg0KbyBQYW5lbCBkYXRhOiBBbGxvd3MgYW5hbHlzaXMgb2YgYm90aCBkaWZmZXJlbmNlcyBiZXR3ZWVuIGluZGl2aWR1YWxzIGFuZCBjaGFuZ2VzIG92ZXIgdGltZSBzaW11bHRhbmVvdXNseS4NCg0K4oCiIENvbW1vbiBzdGF0aXN0aWNhbCBpc3N1ZXMNCm8gQ3Jvc3Mtc2VjdGlvbmFsOiBNYXkgc3VmZmVyIGZyb20gaGV0ZXJvc2tlZGFzdGljaXR5Lg0KbyBUaW1lIHNlcmllczogTWF5IHN1ZmZlciBmcm9tIGF1dG9jb3JyZWxhdGlvbiBhbmQgbm9uLXN0YXRpb25hcml0eSBwcm9ibGVtcy4NCm8gUGFuZWwgZGF0YTogTWF5IGludm9sdmUgZml4ZWQgb3IgcmFuZG9tIGVmZmVjdHMsIGFzIHdlbGwgYXMgYXV0b2NvcnJlbGF0aW9uIGFuZCBoZXRlcm9za2VkYXN0aWNpdHkuDQoNCuKAoiBBbmFseXRpY2FsIGNhcGFjaXR5IGFuZCBkZXB0aA0KbyBDcm9zcy1zZWN0aW9uYWw6IFNpbXBsZXIsIGJ1dCBkb2VzIG5vdCBjYXB0dXJlIHRpbWUgZHluYW1pY3MuDQpvIFRpbWUgc2VyaWVzOiBBbGxvd3MgYW5hbHlzaXMgb2YgdHJlbmRzIGFuZCBjeWNsZXMgb3ZlciB0aW1lLg0KbyBQYW5lbCBkYXRhOiBNb3JlIGNvbXByZWhlbnNpdmUgYmVjYXVzZSBpdCBiZXR0ZXIgY29udHJvbHMgZm9yIGluZGl2aWR1YWwgaGV0ZXJvZ2VuZWl0eSBhbmQgaW1wcm92ZXMgZXN0aW1hdG9yIHByZWNpc2lvbi4NCg0KIyMNCg0KYGBge3J9DQptb2RlbF9mb3JtdWxhIDwtIHJlYWxfZXhwb3J0cyB+IGxxX3NlY29uZGFyeSArDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXZlcmFnZV9kYWlseV9zYWxhcnkgKyBwb3BfZGVuc2l0eSArIHJlYWxfcHVibGljX2ludmVzdG1lbnRfcGMNCg0KYGBgDQoNCmBgYHtyfQ0KcG9vbGluZyA8LSBwbG0obW9kZWxfZm9ybXVsYSwgZGF0YSA9IHBhbmVsX2RhdGEsIG1vZGVsID0gInBvb2xpbmciKQ0Kc3VtbWFyeShwb29saW5nKQ0KYGBgDQoNCmBgYHtyfQ0KZmVfaW5kIDwtIHBsbShtb2RlbF9mb3JtdWxhLCBkYXRhID0gcGFuZWxfZGF0YSwgbW9kZWwgPSAid2l0aGluIiwgZWZmZWN0ID0gImluZGl2aWR1YWwiKQ0Kc3VtbWFyeShmZV9pbmQpDQpgYGANCg0KYGBge3J9DQpmZV90aW1lIDwtIHBsbShtb2RlbF9mb3JtdWxhLCBkYXRhID0gcGFuZWxfZGF0YSwgbW9kZWwgPSAid2l0aGluIiwgZWZmZWN0ID0gInRpbWUiKQ0Kc3VtbWFyeShmZV90aW1lKQ0KYGBgDQoNCmBgYHtyfQ0KZmVfdHcgPC0gcGxtKG1vZGVsX2Zvcm11bGEsIGRhdGEgPSBwYW5lbF9kYXRhLCBtb2RlbCA9ICJ3aXRoaW4iLCBlZmZlY3QgPSAidHdvd2F5cyIpDQpzdW1tYXJ5KGZlX3R3KQ0KYGBgDQoNCmBgYHtyfQ0KcmUgPC0gcGxtKG1vZGVsX2Zvcm11bGEsIGRhdGEgPSBwYW5lbF9kYXRhLCBtb2RlbCA9ICJyYW5kb20iKQ0Kc3VtbWFyeShyZSkNCmBgYA0KDQpgYGB7cn0NCnBGdGVzdChmZV9pbmQsIHBvb2xpbmcpDQpwRnRlc3QoZmVfdGltZSwgcG9vbGluZykNCnBGdGVzdChmZV90dywgcG9vbGluZykNCmBgYA0KDQpgYGB7cn0NCnBodGVzdChmZV90aW1lLCByZSkNCmBgYA0KDQpgYGB7cn0NCnZpZihsbShtb2RlbF9mb3JtdWxhLCBkYXRhID0gcGFuZWxfZGF0YSkpDQpgYGANCg0KYGBge3J9DQpicHRlc3QoZmVfdGltZSkNCmBgYA0KDQpgYGB7cn0NCnBiZ3Rlc3QoZmVfdGltZSkNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkocGxtKQ0KDQptb2RlbHMgPC0gbGlzdCgNCiAgUG9vbGluZyA9IHBvb2xpbmcsDQogIEZFX0luZGl2aWR1YWwgPSBmZV9pbmQsDQogIEZFX1R3b1dheXMgPSBmZV90dywNCiAgUkUgPSByZSwNCiAgRkVfVGltZSA9IGZlX3RpbWUNCikNCg0KY29tcGFyaXNvbiA8LSBkYXRhLmZyYW1lKA0KICBNb2RlbCA9IG5hbWVzKG1vZGVscyksDQogIFIyID0gc2FwcGx5KG1vZGVscywgZnVuY3Rpb24obSkgc3VtbWFyeShtKSRyLnNxdWFyZWRbInJzcSJdKSwNCiAgQWRqX1IyID0gc2FwcGx5KG1vZGVscywgZnVuY3Rpb24obSkgc3VtbWFyeShtKSRyLnNxdWFyZWRbImFkanJzcSJdKQ0KKQ0KDQpjb21wYXJpc29uDQpgYGANCg0KDQo=