1 Carga y Transformación de Datos

file_path <- "Caso Analitica Estrategica.xlsx"

sheet_names <- excel_sheets(file_path)

for (sheet in sheet_names) {

  df_name <- paste0("df_", sheet)
  
  
  assign(df_name, read_excel(file_path, sheet = sheet))
}


ls(pattern = "^df_")
## [1] "df_name"            "df_Production Cost" "df_Raw Material"   
## [4] "df_Sales"           "df_SGA"             "df_Transport Costs"
# Correción de Hora
df_Sales$Date<-as.Date(df_Sales$Date)
df_Sales$Date <- format(df_Sales$Date, "%Y-%m")

1.1 Tabla Ventas

ventas <- df_Sales %>%
  group_by(Product, Region, Date) %>%
  summarise(Price = sum(Price), Volume = sum(Volume))
## `summarise()` has grouped output by 'Product', 'Region'. You can override using
## the `.groups` argument.

1.2 Tabla Raw Material

# Transformar de formato ancho a formato largo
Raw_Material <- `df_Raw Material` %>%
  pivot_longer(cols = `1`:`12`, 
               names_to = "Month", 
               values_to = "Cost") 

# Combinar Año y Mes en una nueva columna Fecha y formatear adecuadamente
Raw_Material <- Raw_Material %>%
  mutate(Date = paste(Year, Month, "01", sep = "-"), 
         Date = as.Date(Date, format = "%Y-%m-%d"),
         Date = format(Date, "%Y-%m")) %>% # 
  select(Product, Date, Cost) 

1.3 Tabla Production Cost

# Transformar de formato ancho a formato largo
Production_Cost <- `df_Production Cost` %>%
  pivot_longer(cols = `1`:`12`, 
               names_to = "Month", 
               values_to = "Cost") 

# Combinar Año y Mes en una nueva columna Fecha y formatear adecuadamente
Production_Cost <- Production_Cost %>%
  mutate(Date = paste(Year, Month, "01", sep = "-"), 
         Date = as.Date(Date, format = "%Y-%m-%d"),
         Date = format(Date, "%Y-%m")) %>% # 
  select(Product, Date, Cost)

1.4 Tabla SGA

# Transformar de formato ancho a formato largo
SGA <- `df_SGA` %>%
  pivot_longer(cols = `1`:`12`, 
               names_to = "Month", 
               values_to = "Cost") 

# Combinar Año y Mes en una nueva columna Fecha y formatear adecuadamente
SGA <- SGA %>%
  mutate(Date = paste(Year, Month, "01", sep = "-"), 
         Date = as.Date(Date, format = "%Y-%m-%d"),
         Date = format(Date, "%Y-%m")) %>% # 
  select(Product, Date, Cost)

1.5 Integración de costos

1.5.1 Raw Material

ventas_con_raw_material <- ventas %>%
  left_join(Raw_Material, by = c("Product", "Date")) %>%
  rename(`Raw Material` = Cost)

ventas_con_volumen_total_rm <- ventas_con_raw_material %>%
  group_by(Product, Date) %>%
  summarise(Volumen_Total = sum(Volume))
## `summarise()` has grouped output by 'Product'. You can override using the
## `.groups` argument.
ventas_con_costo_unitario_rm <- ventas_con_raw_material %>%
  left_join(ventas_con_volumen_total_rm, by = c("Product", "Date")) %>%
  mutate(`Costo Unitario` = `Raw Material` / Volumen_Total)

1.5.2 Product Costs

ventas_con_product_costs <- ventas %>%
  left_join(Production_Cost, by = c("Product", "Date")) %>%
  rename(`Production Cost` = Cost)

ventas_con_volumen_total_pc <- ventas_con_product_costs %>%
  group_by(Product, Date) %>%
  summarise(Volumen_Total = sum(Volume))
## `summarise()` has grouped output by 'Product'. You can override using the
## `.groups` argument.
ventas_con_costo_unitario_pc <- ventas_con_product_costs %>%
  left_join(ventas_con_volumen_total_pc, by = c("Product", "Date")) %>%
  mutate(`Costo Unitario` = `Production Cost` / Volumen_Total)

1.5.3 SGA

ventas_con_sga <- ventas %>%
  left_join(SGA, by = c("Product", "Date")) %>%
  rename(`SGA` = Cost)

ventas_con_volumen_total_sga <- ventas_con_sga %>%
  group_by(Product, Date) %>%
  summarise(Volumen_Total = sum(Volume))
## `summarise()` has grouped output by 'Product'. You can override using the
## `.groups` argument.
ventas_con_costo_unitario_sga <- ventas_con_sga %>%
  left_join(ventas_con_volumen_total_sga, by = c("Product", "Date")) %>%
  mutate(`Costo Unitario` = `SGA` / Volumen_Total)
ventas_completa <- ventas %>%
  left_join(`df_Transport Costs`, by = c("Region" = "Region", "Product" = "Product"))%>%
  mutate(`Transport Cost` = `Transport Cost` / 12)

1.5.4 Implementacion Final

ventas_completa$`Raw Material`<-ventas_con_costo_unitario_rm$`Costo Unitario`*ventas_completa$Volume
ventas_completa$`Production Cost`<-ventas_con_costo_unitario_pc$`Costo Unitario`*ventas_completa$Volume
ventas_completa$SGA<-ventas_con_costo_unitario_sga$`Costo Unitario`*ventas_completa$Volume

1.6 Creación de Excek Final

#wb <- createWorkbook()

#addWorksheet(wb, "Sales")
#writeData(wb, sheet = "Sales", ventas_completa)

#addWorksheet(wb, "Raw Material")
#writeData(wb, sheet = "Raw Material", Raw_Material)

#addWorksheet(wb, "SGA")
#writeData(wb, sheet = "SGA", SGA)

#addWorksheet(wb, "Production Cost")
#writeData(wb, sheet = "Production Cost", Production_Cost)

#addWorksheet(wb, "Transport Cost")
#writeData(wb, sheet = "Transport Cost", `df_Transport Costs`)

#saveWorkbook(wb, "Entregable DE ACERO.xlsx", overwrite = TRUE)

2 Análisis Descriptivo

2.1 Histogramas

plot_histogram(ventas_completa)

## Correlacion

plot_correlation(ventas_completa)
## 1 features with more than 20 categories ignored!
## Date: 36 categories

## Heterogeneidad

2.1.1 Entre Producto

plotmeans(Price~Product, main="Heterogeneidad entre producto",data=ventas_completa)

2.1.2 Entre Años

plotmeans(Price~Date, main="Heterogeneidad entre meses",data=ventas_completa)

Podemos ver que comparando las medias tanto entre los diferentes meses

Debido a la estructura de los datos de la base de ventas, considero que lo más apropiado es trabajar los datos como una modelo de datos panel

3 Modelo de Datos Panel

3.1 Transformación

ventas_pd<-pdata.frame(ventas_completa,index=c("Product","Date"))
## Warning in pdata.frame(ventas_completa, index = c("Product", "Date")): duplicate couples (id-time) in resulting pdata.frame
##  to find out which, use, e.g., table(index(your_pdataframe), useNA = "ifany")
row.names(ventas_pd) <- make.unique(row.names(ventas_pd))

3.2 Especificación de Modelos

3.2.1 Modelo 1. Regresión Agrupada (pooled)

pooled<-plm(log(Price)~Region+Volume+Transport.Cost+Raw.Material+Production.Cost+SGA,
            data = ventas_pd,
            model = "pooling")
summary(pooled)
## Pooling Model
## 
## Call:
## plm(formula = log(Price) ~ Region + Volume + Transport.Cost + 
##     Raw.Material + Production.Cost + SGA, data = ventas_pd, model = "pooling")
## 
## Balanced Panel: n = 4, T = 36, N = 550
## 
## Residuals:
##      Min.   1st Qu.    Median   3rd Qu.      Max. 
## -0.954708 -0.190381  0.006152  0.209539  0.928920 
## 
## Coefficients:
##                    Estimate  Std. Error  t-value  Pr(>|t|)    
## (Intercept)      8.3380e+00  1.4700e-01  56.7210 < 2.2e-16 ***
## RegionNorte     -2.7430e-01  4.6535e-02  -5.8944 6.621e-09 ***
## RegionOccidente -1.3200e+00  1.2109e-01 -10.9009 < 2.2e-16 ***
## RegionSur       -8.5154e-01  8.5184e-02  -9.9965 < 2.2e-16 ***
## Volume           3.1524e-04  1.6695e-05  18.8822 < 2.2e-16 ***
## Transport.Cost   3.4766e-02  3.0410e-03  11.4323 < 2.2e-16 ***
## Raw.Material     1.0050e-05  3.9640e-05   0.2535    0.8000    
## Production.Cost  4.2576e-05  1.5800e-04   0.2695    0.7877    
## SGA             -2.0386e-05  1.4813e-04  -0.1376    0.8906    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    171.86
## Residual Sum of Squares: 56.993
## R-Squared:      0.66837
## Adj. R-Squared: 0.66346
## F-statistic: 136.291 on 8 and 541 DF, p-value: < 2.22e-16

3.2.2 Modelo 2. Efectos Fijos (within)

within<-plm(log(Price)~Region+Volume+Transport.Cost+Raw.Material+Production.Cost+SGA,
            data = ventas_pd,
            model = "within")
summary(within)
## Oneway (individual) effect Within Model
## 
## Call:
## plm(formula = log(Price) ~ Region + Volume + Transport.Cost + 
##     Raw.Material + Production.Cost + SGA, data = ventas_pd, model = "within")
## 
## Balanced Panel: n = 4, T = 36, N = 550
## 
## Residuals:
##       Min.    1st Qu.     Median    3rd Qu.       Max. 
## -0.8882486 -0.1858114  0.0055747  0.2077419  0.8785219 
## 
## Coefficients: (1 dropped because of singularities)
##                    Estimate  Std. Error t-value Pr(>|t|)    
## RegionNorte      1.7665e-02  3.8559e-02  0.4581   0.6470    
## RegionOccidente -1.7114e-02  3.8692e-02 -0.4423   0.6584    
## RegionSur        1.7331e-02  3.8635e-02  0.4486   0.6539    
## Volume           3.3070e-04  1.6792e-05 19.6942   <2e-16 ***
## Raw.Material    -2.9629e-05  3.9848e-05 -0.7436   0.4575    
## Production.Cost  6.2841e-06  1.5544e-04  0.0404   0.9678    
## SGA              9.7336e-05  1.4811e-04  0.6572   0.5113    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    156.37
## Residual Sum of Squares: 54.774
## R-Squared:      0.64972
## Adj. R-Squared: 0.64322
## F-statistic: 142.824 on 7 and 539 DF, p-value: < 2.22e-16

3.2.2.1 Comparación de Modelos

pFtest(within,pooled)
## 
##  F test for individual effects
## 
## data:  log(Price) ~ Region + Volume + Transport.Cost + Raw.Material +  ...
## F = 10.92, df1 = 2, df2 = 539, p-value = 2.244e-05
## alternative hypothesis: significant effects

Una vez planteado los dos modelos y haciendo un pFtest para poder determinar que modelo es mejor pudimos obtener un p-value menor a 0.05. Dado esto rechazamos nuestra Ho concluyendo que nuestro modelo de efectos fijos es mejor al modelo agrupado. Sin embargo aun tenemos otro tipo de modelos de regresion para datos panel que se pueden testear.

3.2.3 Modelo 3. Efectos Aleatorios (Walhus)

walhus<-plm(log(Price)~Region+Volume+Transport.Cost+Raw.Material+Production.Cost+SGA,
            data = ventas_pd,
            model = "random",
            random.method = "walhus")
summary(walhus)
## Oneway (individual) effect Random Effect Model 
##    (Wallace-Hussain's transformation)
## 
## Call:
## plm(formula = log(Price) ~ Region + Volume + Transport.Cost + 
##     Raw.Material + Production.Cost + SGA, data = ventas_pd, model = "random", 
##     random.method = "walhus")
## 
## Balanced Panel: n = 4, T = 36, N = 550
## 
## Effects:
##                   var std.dev share
## idiosyncratic 0.10070 0.31733   0.9
## individual    0.01119 0.10577   0.1
## theta: 0.5528
## 
## Residuals:
##       Min.    1st Qu.     Median    3rd Qu.       Max. 
## -0.9148843 -0.1853130  0.0096639  0.2108817  0.8884935 
## 
## Coefficients:
##                    Estimate  Std. Error z-value  Pr(>|z|)    
## (Intercept)      8.2960e+00  2.9977e-01 27.6747 < 2.2e-16 ***
## RegionNorte     -2.8030e-01  6.4832e-02 -4.3236 1.535e-05 ***
## RegionOccidente -1.3556e+00  2.3843e-01 -5.6855 1.304e-08 ***
## RegionSur       -8.7506e-01  1.6119e-01 -5.4286 5.679e-08 ***
## Volume           3.2734e-04  1.6749e-05 19.5437 < 2.2e-16 ***
## Transport.Cost   3.5698e-02  6.2672e-03  5.6960 1.226e-08 ***
## Raw.Material    -2.1060e-05  3.9752e-05 -0.5298    0.5963    
## Production.Cost  1.4077e-05  1.5577e-04  0.0904    0.9280    
## SGA              7.2032e-05  1.4793e-04  0.4869    0.6263    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    159.47
## Residual Sum of Squares: 55.253
## R-Squared:      0.65352
## Adj. R-Squared: 0.64839
## Chisq: 1020.4 on 8 DF, p-value: < 2.22e-16

3.2.4 Modelo 4. Efectos Aleatorios (Ameniya)

#ameniya<-plm(Price~Region+Volume+Transport.Cost+Raw.Material+Production.Cost+SGA,
            #data = ventas_pd,
            #model = "random",
            #random.method = "ameniya")
#summary(ameniya)

Método no relevante

3.2.5 Modelo 5. Efectos Aleatorios (Nerlove)

nerlove<-plm(log(Price)~Region+Volume+Transport.Cost+Raw.Material+Production.Cost+SGA,
            data = ventas_pd,
            model = "random",
            random.method = "nerlove")
summary(nerlove)
## Oneway (individual) effect Random Effect Model 
##    (Nerlove's transformation)
## 
## Call:
## plm(formula = log(Price) ~ Region + Volume + Transport.Cost + 
##     Raw.Material + Production.Cost + SGA, data = ventas_pd, model = "random", 
##     random.method = "nerlove")
## 
## Balanced Panel: n = 4, T = 36, N = 550
## 
## Effects:
##                   var std.dev share
## idiosyncratic 0.09959 0.31558 0.673
## individual    0.04829 0.21976 0.327
## theta: 0.7672
## 
## Residuals:
##      Min.   1st Qu.    Median   3rd Qu.      Max. 
## -0.901207 -0.183329  0.008965  0.207520  0.884683 
## 
## Coefficients:
##                    Estimate  Std. Error z-value  Pr(>|z|)    
## (Intercept)      8.2876e+00  5.6505e-01 14.6669 < 2.2e-16 ***
## RegionNorte     -2.8152e-01  1.0583e-01 -2.6602  0.007810 ** 
## RegionOccidente -1.3628e+00  4.4576e-01 -3.0572  0.002234 ** 
## RegionSur       -8.7980e-01  2.9837e-01 -2.9487  0.003191 ** 
## Volume           3.2977e-04  1.6758e-05 19.6791 < 2.2e-16 ***
## Transport.Cost   3.5886e-02  1.1839e-02  3.0312  0.002436 ** 
## Raw.Material    -2.7274e-05  3.9769e-05 -0.6858  0.492833    
## Production.Cost  8.4240e-06  1.5532e-04  0.0542  0.956747    
## SGA              9.0386e-05  1.4786e-04  0.6113  0.541009    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    157.21
## Residual Sum of Squares: 54.906
## R-Squared:      0.65075
## Adj. R-Squared: 0.64559
## Chisq: 1008.04 on 8 DF, p-value: < 2.22e-16

3.2.5.1 Comparación de modelos

phtest(walhus,within)
## 
##  Hausman Test
## 
## data:  log(Price) ~ Region + Volume + Transport.Cost + Raw.Material +  ...
## chisq = 6.0576, df = 7, p-value = 0.533
## alternative hypothesis: one model is inconsistent
phtest(nerlove,within)
## 
##  Hausman Test
## 
## data:  log(Price) ~ Region + Volume + Transport.Cost + Raw.Material +  ...
## chisq = 0.24856, df = 7, p-value = 0.9999
## alternative hypothesis: one model is inconsistent

Una vez hecha la comprobación entre los modelos de efectos fijos y aleatorios, podemos concluis que el modelo más adecuado es el modelo de efectos aleatorios (ya sea walhus o nerlove) en lugar del modelo de efectos fijos.

Para poder decidir con que modelo quedarnos entre Walhus o Nerlove usare las métricas del R Squared. Observando en los summary anteriores podemos observar que el modelo que mejor explica la variable dependiente es el metodo walhus

Basados en nuestro modelo seleccionado, podemos ver que las variables estadisticamente significantes son Intercepto, Region, Volumen y Transporte, siendo volumen la cual tiene un nivel de significancia mayor a 99% y el resto de variables mencionadas entre 99% y 99.9%.

Lo interesante viene siendo que el la relacion en cuanto a transporte es positiva, lo que puede significar que aquellas lugares donde se gasta más en transporte generan mejores niveles ventas.

4 Modelos por Producto

ProductoA<-ventas_completa%>%filter(Product == "A")
ProductoB<-ventas_completa%>%filter(Product == "B")
ProductoC<-ventas_completa%>%filter(Product == "C")
ProductoD<-ventas_completa%>%filter(Product == "D")

4.1 Transformacion Datos Panel

A_pd<-pdata.frame(ProductoA,index=c("Region","Date"))
B_pd<-pdata.frame(ProductoB,index=c("Region","Date"))
C_pd<-pdata.frame(ProductoC,index=c("Region","Date"))
D_pd<-pdata.frame(ProductoD,index=c("Region","Date"))

4.2 Histogramas

par(mfrow=c(2, 2))
hist(ProductoA$Price)
hist(ProductoB$Price)
hist(ProductoC$Price)
hist(ProductoD$Price)

4.3 Producto A

4.3.1 Método Pooled

pooled_A<-plm(log(Price)~Volume+Transport.Cost+Raw.Material+Production.Cost+SGA,
            data = A_pd,
            model = "pooling")
summary(pooled_A)
## Pooling Model
## 
## Call:
## plm(formula = log(Price) ~ Volume + Transport.Cost + Raw.Material + 
##     Production.Cost + SGA, data = A_pd, model = "pooling")
## 
## Unbalanced Panel: n = 4, T = 33-35, N = 136
## 
## Residuals:
##      Min.   1st Qu.    Median   3rd Qu.      Max. 
## -0.718451 -0.225426  0.038262  0.188019  0.891902 
## 
## Coefficients:
##                    Estimate  Std. Error t-value Pr(>|t|)    
## (Intercept)      9.7496e+00  1.2404e-01 78.6032   <2e-16 ***
## Volume           3.4566e-04  3.0401e-05 11.3698   <2e-16 ***
## Transport.Cost   1.3229e-03  1.8901e-03  0.6999   0.4852    
## Raw.Material    -6.5596e-05  1.0808e-04 -0.6069   0.5450    
## Production.Cost  2.0538e-05  4.0459e-04  0.0508   0.9596    
## SGA              1.4400e-04  3.5949e-04  0.4006   0.6894    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    42.476
## Residual Sum of Squares: 13.111
## R-Squared:      0.69133
## Adj. R-Squared: 0.67946
## F-statistic: 58.232 on 5 and 130 DF, p-value: < 2.22e-16

4.3.2 Método Within

within_A<-plm(log(Price)~Volume+Transport.Cost+Raw.Material+Production.Cost+SGA,
            data = A_pd,
            model = "within")
summary(within_A)
## Oneway (individual) effect Within Model
## 
## Call:
## plm(formula = log(Price) ~ Volume + Transport.Cost + Raw.Material + 
##     Production.Cost + SGA, data = A_pd, model = "within")
## 
## Unbalanced Panel: n = 4, T = 33-35, N = 136
## 
## Residuals:
##      Min.   1st Qu.    Median   3rd Qu.      Max. 
## -0.699226 -0.220617  0.026781  0.197826  0.869013 
## 
## Coefficients:
##                    Estimate  Std. Error t-value Pr(>|t|)    
## Volume           3.4661e-04  3.0571e-05 11.3378   <2e-16 ***
## Raw.Material    -7.0374e-05  1.0930e-04 -0.6439   0.5208    
## Production.Cost  1.7719e-05  4.0781e-04  0.0434   0.9654    
## SGA              1.5709e-04  3.6188e-04  0.4341   0.6650    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    42.014
## Residual Sum of Squares: 13.037
## R-Squared:      0.6897
## Adj. R-Squared: 0.67274
## F-statistic: 71.1275 on 4 and 128 DF, p-value: < 2.22e-16

4.3.2.1 Comparación

pFtest(within_A,pooled_A)
## 
##  F test for individual effects
## 
## data:  log(Price) ~ Volume + Transport.Cost + Raw.Material + Production.Cost +  ...
## F = 0.36534, df1 = 2, df2 = 128, p-value = 0.6947
## alternative hypothesis: significant effects

Dada esta comprobacion nos quedamos con el metodo de efectos agrupados

Basados en el modelo escogido, las variables estadisticamente significativas son Volumey el intercepto con nivel de confianza mayor 99%

4.4 Producto B

4.4.1 Método Pooled

pooled_B<-plm(log(Price)~Volume+Transport.Cost+Raw.Material+Production.Cost+SGA,
            data = B_pd,
            model = "pooling")
summary(pooled_B)
## Pooling Model
## 
## Call:
## plm(formula = log(Price) ~ Volume + Transport.Cost + Raw.Material + 
##     Production.Cost + SGA, data = B_pd, model = "pooling")
## 
## Unbalanced Panel: n = 4, T = 32-36, N = 136
## 
## Residuals:
##       Min.    1st Qu.     Median    3rd Qu.       Max. 
## -0.7202611 -0.1640933 -0.0042783  0.1849294  0.7399327 
## 
## Coefficients:
##                    Estimate  Std. Error t-value  Pr(>|t|)    
## (Intercept)      9.8102e+00  1.1923e-01 82.2771 < 2.2e-16 ***
## Volume           3.3800e-04  3.8671e-05  8.7403 1.013e-14 ***
## Transport.Cost   1.0370e-04  1.7471e-03  0.0594    0.9528    
## Raw.Material    -3.5747e-05  1.1434e-04 -0.3126    0.7551    
## Production.Cost -3.4812e-04  4.2301e-04 -0.8230    0.4120    
## SGA              3.2620e-04  3.6585e-04  0.8916    0.3743    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    33.815
## Residual Sum of Squares: 11.225
## R-Squared:      0.66804
## Adj. R-Squared: 0.65528
## F-statistic: 52.3237 on 5 and 130 DF, p-value: < 2.22e-16

4.4.2 Método Within

within_B<-plm(log(Price)~Volume+Transport.Cost+Raw.Material+Production.Cost+SGA,
            data = B_pd,
            model = "within")
summary(within_B)
## Oneway (individual) effect Within Model
## 
## Call:
## plm(formula = log(Price) ~ Volume + Transport.Cost + Raw.Material + 
##     Production.Cost + SGA, data = B_pd, model = "within")
## 
## Unbalanced Panel: n = 4, T = 32-36, N = 136
## 
## Residuals:
##       Min.    1st Qu.     Median    3rd Qu.       Max. 
## -0.7533357 -0.1424054  0.0035632  0.1804691  0.7808767 
## 
## Coefficients:
##                    Estimate  Std. Error t-value  Pr(>|t|)    
## Volume           3.3601e-04  3.8874e-05  8.6437 1.904e-14 ***
## Raw.Material    -3.5898e-05  1.1489e-04 -0.3125    0.7552    
## Production.Cost -2.9911e-04  4.2716e-04 -0.7002    0.4851    
## SGA              3.2123e-04  3.6707e-04  0.8751    0.3831    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    32.912
## Residual Sum of Squares: 11.123
## R-Squared:      0.66204
## Adj. R-Squared: 0.64355
## F-statistic: 62.685 on 4 and 128 DF, p-value: < 2.22e-16

4.4.2.1 Comparación

pFtest(within_B,pooled_B)
## 
##  F test for individual effects
## 
## data:  log(Price) ~ Volume + Transport.Cost + Raw.Material + Production.Cost +  ...
## F = 0.58773, df1 = 2, df2 = 128, p-value = 0.5571
## alternative hypothesis: significant effects

Dada esta comprobacion nos quedamos con el metodo de efectos agrupados

Basados en el modelo escogido, las variables estadisticamente significativas son Volume y el intercepto con nivel de confianza mayor 99%

4.5 Producto C

4.5.1 Metodo Pooled

pooled_C<-plm(log(Price)~Volume+Transport.Cost+Raw.Material+Production.Cost+SGA,
            data = C_pd,
            model = "pooling")
summary(pooled_C)
## Pooling Model
## 
## Call:
## plm(formula = log(Price) ~ Volume + Transport.Cost + Raw.Material + 
##     Production.Cost + SGA, data = C_pd, model = "pooling")
## 
## Unbalanced Panel: n = 4, T = 35-36, N = 141
## 
## Residuals:
##      Min.   1st Qu.    Median   3rd Qu.      Max. 
## -0.796882 -0.183194  0.010502  0.198157  0.839158 
## 
## Coefficients:
##                    Estimate  Std. Error t-value  Pr(>|t|)    
## (Intercept)      1.0310e+01  1.4104e-01 73.1008 < 2.2e-16 ***
## Volume           3.5465e-04  5.0497e-05  7.0233 9.645e-11 ***
## Transport.Cost  -1.8529e-03  1.8939e-03 -0.9784   0.32965    
## Raw.Material    -3.2348e-05  6.7488e-05 -0.4793   0.63249    
## Production.Cost  4.9817e-04  2.9349e-04  1.6974   0.09192 .  
## SGA             -3.9967e-04  2.7825e-04 -1.4364   0.15321    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    38.915
## Residual Sum of Squares: 14.306
## R-Squared:      0.63237
## Adj. R-Squared: 0.61875
## F-statistic: 46.4434 on 5 and 135 DF, p-value: < 2.22e-16

4.5.2 Método Within

within_C<-plm(log(Price)~Volume+Transport.Cost+Raw.Material+Production.Cost+SGA,
            data = C_pd,
            model = "within")
summary(within_C)
## Oneway (individual) effect Within Model
## 
## Call:
## plm(formula = log(Price) ~ Volume + Transport.Cost + Raw.Material + 
##     Production.Cost + SGA, data = C_pd, model = "within")
## 
## Unbalanced Panel: n = 4, T = 35-36, N = 141
## 
## Residuals:
##      Min.   1st Qu.    Median   3rd Qu.      Max. 
## -0.808701 -0.175632  0.027536  0.201136  0.824960 
## 
## Coefficients:
##                    Estimate  Std. Error t-value  Pr(>|t|)    
## Volume           3.5501e-04  5.0844e-05  6.9823 1.251e-10 ***
## Raw.Material    -3.4456e-05  6.8082e-05 -0.5061   0.61363    
## Production.Cost  5.0418e-04  2.9580e-04  1.7044   0.09063 .  
## SGA             -3.9862e-04  2.8062e-04 -1.4205   0.15781    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    38.492
## Residual Sum of Squares: 14.28
## R-Squared:      0.62901
## Adj. R-Squared: 0.60948
## F-statistic: 56.3745 on 4 and 133 DF, p-value: < 2.22e-16

4.5.2.1 Comparación

pFtest(within_C,pooled_C)
## 
##  F test for individual effects
## 
## data:  log(Price) ~ Volume + Transport.Cost + Raw.Material + Production.Cost +  ...
## F = 0.12026, df1 = 2, df2 = 133, p-value = 0.8868
## alternative hypothesis: significant effects

Dada esta comprobacion nos quedamos con el metodo de efectos agrupados

Basados en el modelo escogido, las variables estadisticamente significativas son Volume e Intercepto con nivel de confianza mayor 99% de confianza y Production Cost con nivel de confianza de 90% a 95%

4.6 Producto D

4.6.1 Metodo Pooled

pooled_D<-plm(log(Price)~Volume+Transport.Cost+Raw.Material+Production.Cost+SGA,
            data = D_pd,
            model = "pooling")
summary(pooled_D)
## Pooling Model
## 
## Call:
## plm(formula = log(Price) ~ Volume + Transport.Cost + Raw.Material + 
##     Production.Cost + SGA, data = D_pd, model = "pooling")
## 
## Unbalanced Panel: n = 4, T = 32-36, N = 137
## 
## Residuals:
##      Min.   1st Qu.    Median   3rd Qu.      Max. 
## -0.933980 -0.148718  0.030107  0.213680  0.726757 
## 
## Coefficients:
##                    Estimate  Std. Error t-value  Pr(>|t|)    
## (Intercept)      1.0242e+01  1.7024e-01 60.1582 < 2.2e-16 ***
## Volume           3.0681e-04  3.4821e-05  8.8110 6.508e-15 ***
## Transport.Cost  -1.1012e-03  2.0521e-03 -0.5366    0.5924    
## Raw.Material    -2.8760e-05  8.1266e-05 -0.3539    0.7240    
## Production.Cost -1.0130e-04  2.7369e-04 -0.3701    0.7119    
## SGA              2.8273e-04  2.7611e-04  1.0239    0.3077    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    41.166
## Residual Sum of Squares: 15.286
## R-Squared:      0.62867
## Adj. R-Squared: 0.61449
## F-statistic: 44.3568 on 5 and 131 DF, p-value: < 2.22e-16

4.6.2 Método Within

within_D<-plm(log(Price)~Volume+Transport.Cost+Raw.Material+Production.Cost+SGA,
            data = D_pd,
            model = "within")
summary(within_D)
## Oneway (individual) effect Within Model
## 
## Call:
## plm(formula = log(Price) ~ Volume + Transport.Cost + Raw.Material + 
##     Production.Cost + SGA, data = D_pd, model = "within")
## 
## Unbalanced Panel: n = 4, T = 32-36, N = 137
## 
## Residuals:
##      Min.   1st Qu.    Median   3rd Qu.      Max. 
## -0.942963 -0.159131  0.030261  0.211090  0.724040 
## 
## Coefficients:
##                    Estimate  Std. Error t-value  Pr(>|t|)    
## Volume           3.0768e-04  3.5286e-05  8.7198 1.191e-14 ***
## Raw.Material    -2.9046e-05  8.1940e-05 -0.3545    0.7236    
## Production.Cost -1.0180e-04  2.7587e-04 -0.3690    0.7127    
## SGA              2.8047e-04  2.7935e-04  1.0040    0.3173    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    38.507
## Residual Sum of Squares: 15.28
## R-Squared:      0.6032
## Adj. R-Squared: 0.58167
## F-statistic: 49.0256 on 4 and 129 DF, p-value: < 2.22e-16

4.6.2.1 Comparación

pFtest(within_D,pooled_D)
## 
##  F test for individual effects
## 
## data:  log(Price) ~ Volume + Transport.Cost + Raw.Material + Production.Cost +  ...
## F = 0.028547, df1 = 2, df2 = 129, p-value = 0.9719
## alternative hypothesis: significant effects

Dada esta comprobacion nos quedamos con el metodo de efectos agrupados

Basados en el modelo escogido, las variables estadisticamente significativas son Volume y el intercepto con nivel de confianza mayor 99%

5 Series de Tiempo

5.1 Prediccion Producto A

5.1.1 Agrupacion

ProductoA_total<-ProductoA %>% group_by(Date) %>% summarise("Price"=sum(Price))

5.1.2 ADF Test

adf.test(ProductoA_total$Price)
## 
##  Augmented Dickey-Fuller Test
## 
## data:  ProductoA_total$Price
## Dickey-Fuller = -2.8298, Lag order = 3, p-value = 0.2503
## alternative hypothesis: stationary
# Debido a que tenemos una serie no estacionaria buscaremos una forma de hacerla estacionaria 

adf.test(log(ProductoA_total$Price)) # El valor es mayor a 0.05
## 
##  Augmented Dickey-Fuller Test
## 
## data:  log(ProductoA_total$Price)
## Dickey-Fuller = -3.4393, Lag order = 3, p-value = 0.06755
## alternative hypothesis: stationary

Debido a que obtuvimos valores mayores a 0.05, optamos por usar ARIMA ya que este modelo se ocupa de la no estacionaridad en la serie de tiempo

5.1.3 Transformación A

ProductA_ts<-ts(ProductoA_total$Price,frequency=12,start=c(2019,1))
ProductA_dec<-decompose(ProductA_ts)
plot(ProductA_dec)      

### ARIMA

A_Arima<-arima(ProductA_ts,order=c(1,1,1))
summary(A_Arima)
## 
## Call:
## arima(x = ProductA_ts, order = c(1, 1, 1))
## 
## Coefficients:
##           ar1      ma1
##       -0.1992  -0.7505
## s.e.   0.2256   0.2039
## 
## sigma^2 estimated as 3.573e+09:  log likelihood = -435.18,  aic = 876.36
## 
## Training set error measures:
##                     ME     RMSE      MAE       MPE     MAPE      MASE
## Training set -809.9205 58937.09 46878.88 -15.42174 34.91697 0.8034097
##                    ACF1
## Training set 0.03004559

5.1.3.1 Residuales

checkresiduals(A_Arima)

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(1,1,1)
## Q* = 4.5048, df = 5, p-value = 0.4792
## 
## Model df: 2.   Total lags used: 7
adf.test(A_Arima$residuals) 
## 
##  Augmented Dickey-Fuller Test
## 
## data:  A_Arima$residuals
## Dickey-Fuller = -3.821, Lag order = 3, p-value = 0.03023
## alternative hypothesis: stationary

Los residuales del modelo son estacionarios y no muestran autocorrelacion serial

5.1.4 Pronostico

pronosticoA<-forecast(A_Arima,h=6)
pronosticoA
##          Point Forecast    Lo 80    Hi 80     Lo 95    Hi 95
## Jan 2022       203022.6 126420.3 279624.9  85869.47 320175.7
## Feb 2022       217463.6 140764.4 294162.8 100162.34 334764.9
## Mar 2022       214587.3 135725.0 293449.5  93977.85 335196.7
## Apr 2022       215160.2 134797.3 295523.0  92255.78 338064.6
## May 2022       215046.1 133099.6 296992.5  89719.72 340372.4
## Jun 2022       215068.8 131590.6 298547.0  87399.93 342737.6
autoplot(pronosticoA,main = "Pronostico Producto A")

5.2 Prediccion Producto D

5.2.1 Agrupacion

ProductoD_total<-ProductoD %>% group_by(Date) %>% summarise("Price"=sum(Price))

5.2.2 ADF Test

adf.test(ProductoD_total$Price)
## 
##  Augmented Dickey-Fuller Test
## 
## data:  ProductoD_total$Price
## Dickey-Fuller = -4.0222, Lag order = 3, p-value = 0.02002
## alternative hypothesis: stationary

Obtuvimos valores con series estacionarias

5.2.3 Transformación A

ProductD_ts<-ts(ProductoD_total$Price,frequency=12,start=c(2019,1))
ProductD_dec<-decompose(ProductD_ts)
plot(ProductD_dec)      

### ARIMA

D_ARIMA<-arima(ProductD_ts,order=c(1,1,1))
summary(D_ARIMA)
## 
## Call:
## arima(x = ProductD_ts, order = c(1, 1, 1))
## 
## Coefficients:
##           ar1      ma1
##       -0.0252  -0.9999
## s.e.   0.1711   0.0856
## 
## sigma^2 estimated as 5.562e+09:  log likelihood = -444.16,  aic = 894.33
## 
## Training set error measures:
##                     ME    RMSE     MAE       MPE     MAPE      MASE        ACF1
## Training set -3529.927 73536.3 58347.9 -11.56031 27.37968 0.6481655 -0.01538862

5.2.3.1 Residuales

checkresiduals(D_ARIMA)

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(1,1,1)
## Q* = 6.0858, df = 5, p-value = 0.298
## 
## Model df: 2.   Total lags used: 7
adf.test(D_ARIMA$residuals) 
## 
##  Augmented Dickey-Fuller Test
## 
## data:  D_ARIMA$residuals
## Dickey-Fuller = -4.0733, Lag order = 3, p-value = 0.01809
## alternative hypothesis: stationary

Los residuales del modelo son estacionarios y no muestran autocorrelacion serial

5.2.4 Pronostico

pronosticoD<-forecast(D_ARIMA,h=6)
pronosticoD
##          Point Forecast    Lo 80    Hi 80    Lo 95    Hi 95
## Jan 2022       256038.7 159144.2 352933.2 107851.3 404226.0
## Feb 2022       255064.4 158205.2 351923.6 106931.0 403197.7
## Mar 2022       255088.9 158228.1 351949.8 106953.1 403224.8
## Apr 2022       255088.3 158227.5 351949.1 106952.5 403224.1
## May 2022       255088.3 158227.6 351949.1 106952.6 403224.1
## Jun 2022       255088.3 158227.6 351949.1 106952.6 403224.1
autoplot(pronosticoD,main = "Pronostico Producto D")

LS0tDQp0aXRsZTogIkNhc28gZGUgTmVnb2NpbyBERSBBQ0VSTyINCmF1dGhvcjogIkpvc8OpIEdhYnJpZWwgVXNpw7FhIE1vZ3JvIg0KZGF0ZTogIjIwMjQtMDctMDQiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdGhlbWU6IGZsYXRseQ0KICAgIGhpZ2hsaWdodDogdGFuZ28NCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZGVwdGg6IDMNCiAgICBudW1iZXJfc2VjdGlvbnM6IFRSVUUNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQplZGl0b3Jfb3B0aW9uczogDQogIG1hcmtkb3duOiANCiAgICB3cmFwOiBzZW50ZW5jZQ0KLS0tDQoNCmBgYHtyIGluY2x1ZGU9RkFMU0V9DQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkob3Blbnhsc3gpDQpsaWJyYXJ5KHB1cnJyKQ0KbGlicmFyeShwbG0pDQpsaWJyYXJ5KERhdGFFeHBsb3JlcikNCmxpYnJhcnkoZ3Bsb3RzKQ0KbGlicmFyeShmb3JlY2FzdCkNCmxpYnJhcnkodHNlcmllcykNCmBgYA0KDQojIENhcmdhIHkgVHJhbnNmb3JtYWNpw7NuIGRlIERhdG9zDQpgYGB7cn0NCmZpbGVfcGF0aCA8LSAiQ2FzbyBBbmFsaXRpY2EgRXN0cmF0ZWdpY2EueGxzeCINCg0Kc2hlZXRfbmFtZXMgPC0gZXhjZWxfc2hlZXRzKGZpbGVfcGF0aCkNCg0KZm9yIChzaGVldCBpbiBzaGVldF9uYW1lcykgew0KDQogIGRmX25hbWUgPC0gcGFzdGUwKCJkZl8iLCBzaGVldCkNCiAgDQogIA0KICBhc3NpZ24oZGZfbmFtZSwgcmVhZF9leGNlbChmaWxlX3BhdGgsIHNoZWV0ID0gc2hlZXQpKQ0KfQ0KDQoNCmxzKHBhdHRlcm4gPSAiXmRmXyIpDQoNCiMgQ29ycmVjacOzbiBkZSBIb3JhDQpkZl9TYWxlcyREYXRlPC1hcy5EYXRlKGRmX1NhbGVzJERhdGUpDQpkZl9TYWxlcyREYXRlIDwtIGZvcm1hdChkZl9TYWxlcyREYXRlLCAiJVktJW0iKQ0KYGBgDQoNCiMjIFRhYmxhIFZlbnRhcw0KYGBge3J9DQp2ZW50YXMgPC0gZGZfU2FsZXMgJT4lDQogIGdyb3VwX2J5KFByb2R1Y3QsIFJlZ2lvbiwgRGF0ZSkgJT4lDQogIHN1bW1hcmlzZShQcmljZSA9IHN1bShQcmljZSksIFZvbHVtZSA9IHN1bShWb2x1bWUpKQ0KYGBgDQojIyBUYWJsYSBSYXcgTWF0ZXJpYWwNCg0KYGBge3J9DQojIFRyYW5zZm9ybWFyIGRlIGZvcm1hdG8gYW5jaG8gYSBmb3JtYXRvIGxhcmdvDQpSYXdfTWF0ZXJpYWwgPC0gYGRmX1JhdyBNYXRlcmlhbGAgJT4lDQogIHBpdm90X2xvbmdlcihjb2xzID0gYDFgOmAxMmAsIA0KICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiTW9udGgiLCANCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJDb3N0IikgDQoNCiMgQ29tYmluYXIgQcOxbyB5IE1lcyBlbiB1bmEgbnVldmEgY29sdW1uYSBGZWNoYSB5IGZvcm1hdGVhciBhZGVjdWFkYW1lbnRlDQpSYXdfTWF0ZXJpYWwgPC0gUmF3X01hdGVyaWFsICU+JQ0KICBtdXRhdGUoRGF0ZSA9IHBhc3RlKFllYXIsIE1vbnRoLCAiMDEiLCBzZXAgPSAiLSIpLCANCiAgICAgICAgIERhdGUgPSBhcy5EYXRlKERhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCIpLA0KICAgICAgICAgRGF0ZSA9IGZvcm1hdChEYXRlLCAiJVktJW0iKSkgJT4lICMgDQogIHNlbGVjdChQcm9kdWN0LCBEYXRlLCBDb3N0KSANCg0KYGBgDQoNCiMjIFRhYmxhIFByb2R1Y3Rpb24gQ29zdA0KDQpgYGB7cn0NCiMgVHJhbnNmb3JtYXIgZGUgZm9ybWF0byBhbmNobyBhIGZvcm1hdG8gbGFyZ28NClByb2R1Y3Rpb25fQ29zdCA8LSBgZGZfUHJvZHVjdGlvbiBDb3N0YCAlPiUNCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBgMWA6YDEyYCwgDQogICAgICAgICAgICAgICBuYW1lc190byA9ICJNb250aCIsIA0KICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gIkNvc3QiKSANCg0KIyBDb21iaW5hciBBw7FvIHkgTWVzIGVuIHVuYSBudWV2YSBjb2x1bW5hIEZlY2hhIHkgZm9ybWF0ZWFyIGFkZWN1YWRhbWVudGUNClByb2R1Y3Rpb25fQ29zdCA8LSBQcm9kdWN0aW9uX0Nvc3QgJT4lDQogIG11dGF0ZShEYXRlID0gcGFzdGUoWWVhciwgTW9udGgsICIwMSIsIHNlcCA9ICItIiksIA0KICAgICAgICAgRGF0ZSA9IGFzLkRhdGUoRGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkIiksDQogICAgICAgICBEYXRlID0gZm9ybWF0KERhdGUsICIlWS0lbSIpKSAlPiUgIyANCiAgc2VsZWN0KFByb2R1Y3QsIERhdGUsIENvc3QpDQoNCmBgYA0KDQoNCiMjIFRhYmxhIFNHQQ0KYGBge3J9DQojIFRyYW5zZm9ybWFyIGRlIGZvcm1hdG8gYW5jaG8gYSBmb3JtYXRvIGxhcmdvDQpTR0EgPC0gYGRmX1NHQWAgJT4lDQogIHBpdm90X2xvbmdlcihjb2xzID0gYDFgOmAxMmAsIA0KICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiTW9udGgiLCANCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJDb3N0IikgDQoNCiMgQ29tYmluYXIgQcOxbyB5IE1lcyBlbiB1bmEgbnVldmEgY29sdW1uYSBGZWNoYSB5IGZvcm1hdGVhciBhZGVjdWFkYW1lbnRlDQpTR0EgPC0gU0dBICU+JQ0KICBtdXRhdGUoRGF0ZSA9IHBhc3RlKFllYXIsIE1vbnRoLCAiMDEiLCBzZXAgPSAiLSIpLCANCiAgICAgICAgIERhdGUgPSBhcy5EYXRlKERhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCIpLA0KICAgICAgICAgRGF0ZSA9IGZvcm1hdChEYXRlLCAiJVktJW0iKSkgJT4lICMgDQogIHNlbGVjdChQcm9kdWN0LCBEYXRlLCBDb3N0KQ0KYGBgDQoNCiMjICBJbnRlZ3JhY2nDs24gZGUgY29zdG9zDQoNCg0KIyMjIFJhdyBNYXRlcmlhbA0KYGBge3J9DQp2ZW50YXNfY29uX3Jhd19tYXRlcmlhbCA8LSB2ZW50YXMgJT4lDQogIGxlZnRfam9pbihSYXdfTWF0ZXJpYWwsIGJ5ID0gYygiUHJvZHVjdCIsICJEYXRlIikpICU+JQ0KICByZW5hbWUoYFJhdyBNYXRlcmlhbGAgPSBDb3N0KQ0KDQp2ZW50YXNfY29uX3ZvbHVtZW5fdG90YWxfcm0gPC0gdmVudGFzX2Nvbl9yYXdfbWF0ZXJpYWwgJT4lDQogIGdyb3VwX2J5KFByb2R1Y3QsIERhdGUpICU+JQ0KICBzdW1tYXJpc2UoVm9sdW1lbl9Ub3RhbCA9IHN1bShWb2x1bWUpKQ0KDQp2ZW50YXNfY29uX2Nvc3RvX3VuaXRhcmlvX3JtIDwtIHZlbnRhc19jb25fcmF3X21hdGVyaWFsICU+JQ0KICBsZWZ0X2pvaW4odmVudGFzX2Nvbl92b2x1bWVuX3RvdGFsX3JtLCBieSA9IGMoIlByb2R1Y3QiLCAiRGF0ZSIpKSAlPiUNCiAgbXV0YXRlKGBDb3N0byBVbml0YXJpb2AgPSBgUmF3IE1hdGVyaWFsYCAvIFZvbHVtZW5fVG90YWwpDQpgYGANCg0KDQojIyMgUHJvZHVjdCBDb3N0cw0KYGBge3J9DQp2ZW50YXNfY29uX3Byb2R1Y3RfY29zdHMgPC0gdmVudGFzICU+JQ0KICBsZWZ0X2pvaW4oUHJvZHVjdGlvbl9Db3N0LCBieSA9IGMoIlByb2R1Y3QiLCAiRGF0ZSIpKSAlPiUNCiAgcmVuYW1lKGBQcm9kdWN0aW9uIENvc3RgID0gQ29zdCkNCg0KdmVudGFzX2Nvbl92b2x1bWVuX3RvdGFsX3BjIDwtIHZlbnRhc19jb25fcHJvZHVjdF9jb3N0cyAlPiUNCiAgZ3JvdXBfYnkoUHJvZHVjdCwgRGF0ZSkgJT4lDQogIHN1bW1hcmlzZShWb2x1bWVuX1RvdGFsID0gc3VtKFZvbHVtZSkpDQoNCnZlbnRhc19jb25fY29zdG9fdW5pdGFyaW9fcGMgPC0gdmVudGFzX2Nvbl9wcm9kdWN0X2Nvc3RzICU+JQ0KICBsZWZ0X2pvaW4odmVudGFzX2Nvbl92b2x1bWVuX3RvdGFsX3BjLCBieSA9IGMoIlByb2R1Y3QiLCAiRGF0ZSIpKSAlPiUNCiAgbXV0YXRlKGBDb3N0byBVbml0YXJpb2AgPSBgUHJvZHVjdGlvbiBDb3N0YCAvIFZvbHVtZW5fVG90YWwpDQpgYGANCiMjIyBTR0ENCmBgYHtyfQ0KdmVudGFzX2Nvbl9zZ2EgPC0gdmVudGFzICU+JQ0KICBsZWZ0X2pvaW4oU0dBLCBieSA9IGMoIlByb2R1Y3QiLCAiRGF0ZSIpKSAlPiUNCiAgcmVuYW1lKGBTR0FgID0gQ29zdCkNCg0KdmVudGFzX2Nvbl92b2x1bWVuX3RvdGFsX3NnYSA8LSB2ZW50YXNfY29uX3NnYSAlPiUNCiAgZ3JvdXBfYnkoUHJvZHVjdCwgRGF0ZSkgJT4lDQogIHN1bW1hcmlzZShWb2x1bWVuX1RvdGFsID0gc3VtKFZvbHVtZSkpDQoNCnZlbnRhc19jb25fY29zdG9fdW5pdGFyaW9fc2dhIDwtIHZlbnRhc19jb25fc2dhICU+JQ0KICBsZWZ0X2pvaW4odmVudGFzX2Nvbl92b2x1bWVuX3RvdGFsX3NnYSwgYnkgPSBjKCJQcm9kdWN0IiwgIkRhdGUiKSkgJT4lDQogIG11dGF0ZShgQ29zdG8gVW5pdGFyaW9gID0gYFNHQWAgLyBWb2x1bWVuX1RvdGFsKQ0KYGBgDQpgYGB7cn0NCnZlbnRhc19jb21wbGV0YSA8LSB2ZW50YXMgJT4lDQogIGxlZnRfam9pbihgZGZfVHJhbnNwb3J0IENvc3RzYCwgYnkgPSBjKCJSZWdpb24iID0gIlJlZ2lvbiIsICJQcm9kdWN0IiA9ICJQcm9kdWN0IikpJT4lDQogIG11dGF0ZShgVHJhbnNwb3J0IENvc3RgID0gYFRyYW5zcG9ydCBDb3N0YCAvIDEyKQ0KYGBgDQoNCiMjIyBJbXBsZW1lbnRhY2lvbiBGaW5hbA0KYGBge3J9DQp2ZW50YXNfY29tcGxldGEkYFJhdyBNYXRlcmlhbGA8LXZlbnRhc19jb25fY29zdG9fdW5pdGFyaW9fcm0kYENvc3RvIFVuaXRhcmlvYCp2ZW50YXNfY29tcGxldGEkVm9sdW1lDQp2ZW50YXNfY29tcGxldGEkYFByb2R1Y3Rpb24gQ29zdGA8LXZlbnRhc19jb25fY29zdG9fdW5pdGFyaW9fcGMkYENvc3RvIFVuaXRhcmlvYCp2ZW50YXNfY29tcGxldGEkVm9sdW1lDQp2ZW50YXNfY29tcGxldGEkU0dBPC12ZW50YXNfY29uX2Nvc3RvX3VuaXRhcmlvX3NnYSRgQ29zdG8gVW5pdGFyaW9gKnZlbnRhc19jb21wbGV0YSRWb2x1bWUNCmBgYA0KDQojIyBDcmVhY2nDs24gZGUgRXhjZWsgRmluYWwNCmBgYHtyfQ0KI3diIDwtIGNyZWF0ZVdvcmtib29rKCkNCg0KI2FkZFdvcmtzaGVldCh3YiwgIlNhbGVzIikNCiN3cml0ZURhdGEod2IsIHNoZWV0ID0gIlNhbGVzIiwgdmVudGFzX2NvbXBsZXRhKQ0KDQojYWRkV29ya3NoZWV0KHdiLCAiUmF3IE1hdGVyaWFsIikNCiN3cml0ZURhdGEod2IsIHNoZWV0ID0gIlJhdyBNYXRlcmlhbCIsIFJhd19NYXRlcmlhbCkNCg0KI2FkZFdvcmtzaGVldCh3YiwgIlNHQSIpDQojd3JpdGVEYXRhKHdiLCBzaGVldCA9ICJTR0EiLCBTR0EpDQoNCiNhZGRXb3Jrc2hlZXQod2IsICJQcm9kdWN0aW9uIENvc3QiKQ0KI3dyaXRlRGF0YSh3Yiwgc2hlZXQgPSAiUHJvZHVjdGlvbiBDb3N0IiwgUHJvZHVjdGlvbl9Db3N0KQ0KDQojYWRkV29ya3NoZWV0KHdiLCAiVHJhbnNwb3J0IENvc3QiKQ0KI3dyaXRlRGF0YSh3Yiwgc2hlZXQgPSAiVHJhbnNwb3J0IENvc3QiLCBgZGZfVHJhbnNwb3J0IENvc3RzYCkNCg0KI3NhdmVXb3JrYm9vayh3YiwgIkVudHJlZ2FibGUgREUgQUNFUk8ueGxzeCIsIG92ZXJ3cml0ZSA9IFRSVUUpDQpgYGANCg0KDQojIEFuw6FsaXNpcyBEZXNjcmlwdGl2bw0KDQojIyBIaXN0b2dyYW1hcw0KYGBge3J9DQpwbG90X2hpc3RvZ3JhbSh2ZW50YXNfY29tcGxldGEpDQpgYGANCiMjIENvcnJlbGFjaW9uIA0KYGBge3J9DQpwbG90X2NvcnJlbGF0aW9uKHZlbnRhc19jb21wbGV0YSkNCmBgYA0KIyMgSGV0ZXJvZ2VuZWlkYWQgDQoNCiMjIyBFbnRyZSBQcm9kdWN0bw0KYGBge3J9DQpwbG90bWVhbnMoUHJpY2V+UHJvZHVjdCwgbWFpbj0iSGV0ZXJvZ2VuZWlkYWQgZW50cmUgcHJvZHVjdG8iLGRhdGE9dmVudGFzX2NvbXBsZXRhKQ0KYGBgDQoNCiMjIyBFbnRyZSBBw7FvcyANCg0KYGBge3J9DQpwbG90bWVhbnMoUHJpY2V+RGF0ZSwgbWFpbj0iSGV0ZXJvZ2VuZWlkYWQgZW50cmUgbWVzZXMiLGRhdGE9dmVudGFzX2NvbXBsZXRhKQ0KYGBgDQoNClBvZGVtb3MgdmVyIHF1ZSBjb21wYXJhbmRvIGxhcyBtZWRpYXMgdGFudG8gZW50cmUgbG9zIGRpZmVyZW50ZXMgbWVzZXMNCg0KRGViaWRvIGEgbGEgZXN0cnVjdHVyYSBkZSBsb3MgZGF0b3MgZGUgbGEgYmFzZSBkZSB2ZW50YXMsIGNvbnNpZGVybyBxdWUgbG8gbcOhcyBhcHJvcGlhZG8gZXMgdHJhYmFqYXIgbG9zIGRhdG9zIGNvbW8gdW5hIG1vZGVsbyBkZSBkYXRvcyBwYW5lbA0KDQoNCiMgTW9kZWxvIGRlIERhdG9zIFBhbmVsIA0KDQojIyBUcmFuc2Zvcm1hY2nDs24gDQoNCmBgYHtyfQ0KdmVudGFzX3BkPC1wZGF0YS5mcmFtZSh2ZW50YXNfY29tcGxldGEsaW5kZXg9YygiUHJvZHVjdCIsIkRhdGUiKSkNCnJvdy5uYW1lcyh2ZW50YXNfcGQpIDwtIG1ha2UudW5pcXVlKHJvdy5uYW1lcyh2ZW50YXNfcGQpKQ0KYGBgDQoNCiMjIEVzcGVjaWZpY2FjacOzbiBkZSBNb2RlbG9zIA0KDQojIyMgTW9kZWxvIDEuIFJlZ3Jlc2nDs24gQWdydXBhZGEgKHBvb2xlZCkNCmBgYHtyfQ0KcG9vbGVkPC1wbG0obG9nKFByaWNlKX5SZWdpb24rVm9sdW1lK1RyYW5zcG9ydC5Db3N0K1Jhdy5NYXRlcmlhbCtQcm9kdWN0aW9uLkNvc3QrU0dBLA0KICAgICAgICAgICAgZGF0YSA9IHZlbnRhc19wZCwNCiAgICAgICAgICAgIG1vZGVsID0gInBvb2xpbmciKQ0Kc3VtbWFyeShwb29sZWQpDQpgYGANCiMjIyBNb2RlbG8gMi4gRWZlY3RvcyBGaWpvcyAgKHdpdGhpbikNCg0KYGBge3J9DQp3aXRoaW48LXBsbShsb2coUHJpY2UpflJlZ2lvbitWb2x1bWUrVHJhbnNwb3J0LkNvc3QrUmF3Lk1hdGVyaWFsK1Byb2R1Y3Rpb24uQ29zdCtTR0EsDQogICAgICAgICAgICBkYXRhID0gdmVudGFzX3BkLA0KICAgICAgICAgICAgbW9kZWwgPSAid2l0aGluIikNCnN1bW1hcnkod2l0aGluKQ0KYGBgDQoNCiMjIyMgQ29tcGFyYWNpw7NuIGRlIE1vZGVsb3MNCg0KYGBge3J9DQpwRnRlc3Qod2l0aGluLHBvb2xlZCkNCmBgYA0KDQpVbmEgdmV6IHBsYW50ZWFkbyBsb3MgZG9zIG1vZGVsb3MgeSBoYWNpZW5kbyB1biBwRnRlc3QgcGFyYSBwb2RlciBkZXRlcm1pbmFyIHF1ZSBtb2RlbG8gZXMgbWVqb3IgcHVkaW1vcyBvYnRlbmVyIHVuIHAtdmFsdWUgbWVub3IgYSAwLjA1LiBEYWRvIGVzdG8gcmVjaGF6YW1vcyBudWVzdHJhIEhvIGNvbmNsdXllbmRvIHF1ZSBudWVzdHJvIG1vZGVsbyBkZSBlZmVjdG9zIGZpam9zIGVzIG1lam9yIGFsIG1vZGVsbyBhZ3J1cGFkby4gU2luIGVtYmFyZ28gYXVuIHRlbmVtb3Mgb3RybyB0aXBvIGRlIG1vZGVsb3MgZGUgcmVncmVzaW9uIHBhcmEgZGF0b3MgcGFuZWwgcXVlIHNlIHB1ZWRlbiB0ZXN0ZWFyLiANCg0KIyMjIE1vZGVsbyAzLiAgRWZlY3RvcyBBbGVhdG9yaW9zIChXYWxodXMpDQoNCmBgYHtyfQ0Kd2FsaHVzPC1wbG0obG9nKFByaWNlKX5SZWdpb24rVm9sdW1lK1RyYW5zcG9ydC5Db3N0K1Jhdy5NYXRlcmlhbCtQcm9kdWN0aW9uLkNvc3QrU0dBLA0KICAgICAgICAgICAgZGF0YSA9IHZlbnRhc19wZCwNCiAgICAgICAgICAgIG1vZGVsID0gInJhbmRvbSIsDQogICAgICAgICAgICByYW5kb20ubWV0aG9kID0gIndhbGh1cyIpDQpzdW1tYXJ5KHdhbGh1cykNCmBgYA0KIyMjIE1vZGVsbyA0LiBFZmVjdG9zIEFsZWF0b3Jpb3MgKEFtZW5peWEpDQoNCmBgYHtyfQ0KI2FtZW5peWE8LXBsbShQcmljZX5SZWdpb24rVm9sdW1lK1RyYW5zcG9ydC5Db3N0K1Jhdy5NYXRlcmlhbCtQcm9kdWN0aW9uLkNvc3QrU0dBLA0KICAgICAgICAgICAgI2RhdGEgPSB2ZW50YXNfcGQsDQogICAgICAgICAgICAjbW9kZWwgPSAicmFuZG9tIiwNCiAgICAgICAgICAgICNyYW5kb20ubWV0aG9kID0gImFtZW5peWEiKQ0KI3N1bW1hcnkoYW1lbml5YSkNCmBgYA0KTcOpdG9kbyBubyByZWxldmFudGUNCg0KIyMjIE1vZGVsbyA1LiBFZmVjdG9zIEFsZWF0b3Jpb3MgKE5lcmxvdmUpDQpgYGB7cn0NCm5lcmxvdmU8LXBsbShsb2coUHJpY2UpflJlZ2lvbitWb2x1bWUrVHJhbnNwb3J0LkNvc3QrUmF3Lk1hdGVyaWFsK1Byb2R1Y3Rpb24uQ29zdCtTR0EsDQogICAgICAgICAgICBkYXRhID0gdmVudGFzX3BkLA0KICAgICAgICAgICAgbW9kZWwgPSAicmFuZG9tIiwNCiAgICAgICAgICAgIHJhbmRvbS5tZXRob2QgPSAibmVybG92ZSIpDQpzdW1tYXJ5KG5lcmxvdmUpDQpgYGANCiMjIyMgQ29tcGFyYWNpw7NuIGRlIG1vZGVsb3MgDQoNCmBgYHtyfQ0KcGh0ZXN0KHdhbGh1cyx3aXRoaW4pDQpwaHRlc3QobmVybG92ZSx3aXRoaW4pDQpgYGANClVuYSB2ZXogaGVjaGEgbGEgY29tcHJvYmFjacOzbiBlbnRyZSBsb3MgbW9kZWxvcyBkZSBlZmVjdG9zIGZpam9zIHkgYWxlYXRvcmlvcywgcG9kZW1vcyBjb25jbHVpcyBxdWUgZWwgbW9kZWxvIG3DoXMgYWRlY3VhZG8gZXMgZWwgbW9kZWxvIGRlIGVmZWN0b3MgYWxlYXRvcmlvcyAoeWEgc2VhIHdhbGh1cyBvIG5lcmxvdmUpIGVuIGx1Z2FyIGRlbCBtb2RlbG8gZGUgZWZlY3RvcyBmaWpvcy4gDQoNClBhcmEgcG9kZXIgZGVjaWRpciBjb24gcXVlIG1vZGVsbyBxdWVkYXJub3MgZW50cmUgV2FsaHVzIG8gTmVybG92ZSB1c2FyZSBsYXMgbcOpdHJpY2FzIGRlbCBSIFNxdWFyZWQuIE9ic2VydmFuZG8gZW4gbG9zIHN1bW1hcnkgYW50ZXJpb3JlcyBwb2RlbW9zIG9ic2VydmFyIHF1ZSBlbCBtb2RlbG8gcXVlIG1lam9yIGV4cGxpY2EgbGEgdmFyaWFibGUgZGVwZW5kaWVudGUgZXMgZWwgbWV0b2RvICoqd2FsaHVzKioNCg0KQmFzYWRvcyBlbiBudWVzdHJvIG1vZGVsbyBzZWxlY2Npb25hZG8sIHBvZGVtb3MgdmVyIHF1ZSBsYXMgdmFyaWFibGVzIGVzdGFkaXN0aWNhbWVudGUgc2lnbmlmaWNhbnRlcyBzb24gSW50ZXJjZXB0bywgUmVnaW9uLCBWb2x1bWVuIHkgVHJhbnNwb3J0ZSwgc2llbmRvIHZvbHVtZW4gbGEgY3VhbCB0aWVuZSB1biBuaXZlbCBkZSBzaWduaWZpY2FuY2lhIG1heW9yIGEgOTklIHkgZWwgcmVzdG8gZGUgdmFyaWFibGVzIG1lbmNpb25hZGFzIGVudHJlIDk5JSB5IDk5LjklLg0KDQpMbyBpbnRlcmVzYW50ZSB2aWVuZSBzaWVuZG8gcXVlIGVsIGxhIHJlbGFjaW9uIGVuIGN1YW50byBhIHRyYW5zcG9ydGUgZXMgcG9zaXRpdmEsIGxvIHF1ZSBwdWVkZSBzaWduaWZpY2FyIHF1ZSBhcXVlbGxhcyBsdWdhcmVzIGRvbmRlIHNlIGdhc3RhIG3DoXMgZW4gdHJhbnNwb3J0ZSBnZW5lcmFuIG1lam9yZXMgbml2ZWxlcyB2ZW50YXMuDQoNCiMgTW9kZWxvcyBwb3IgUHJvZHVjdG8gDQoNCmBgYHtyfQ0KUHJvZHVjdG9BPC12ZW50YXNfY29tcGxldGElPiVmaWx0ZXIoUHJvZHVjdCA9PSAiQSIpDQpQcm9kdWN0b0I8LXZlbnRhc19jb21wbGV0YSU+JWZpbHRlcihQcm9kdWN0ID09ICJCIikNClByb2R1Y3RvQzwtdmVudGFzX2NvbXBsZXRhJT4lZmlsdGVyKFByb2R1Y3QgPT0gIkMiKQ0KUHJvZHVjdG9EPC12ZW50YXNfY29tcGxldGElPiVmaWx0ZXIoUHJvZHVjdCA9PSAiRCIpDQpgYGANCg0KIyMgVHJhbnNmb3JtYWNpb24gRGF0b3MgUGFuZWwNCmBgYHtyfQ0KQV9wZDwtcGRhdGEuZnJhbWUoUHJvZHVjdG9BLGluZGV4PWMoIlJlZ2lvbiIsIkRhdGUiKSkNCkJfcGQ8LXBkYXRhLmZyYW1lKFByb2R1Y3RvQixpbmRleD1jKCJSZWdpb24iLCJEYXRlIikpDQpDX3BkPC1wZGF0YS5mcmFtZShQcm9kdWN0b0MsaW5kZXg9YygiUmVnaW9uIiwiRGF0ZSIpKQ0KRF9wZDwtcGRhdGEuZnJhbWUoUHJvZHVjdG9ELGluZGV4PWMoIlJlZ2lvbiIsIkRhdGUiKSkNCmBgYA0KDQojIyBIaXN0b2dyYW1hcw0KYGBge3J9DQpwYXIobWZyb3c9YygyLCAyKSkNCmhpc3QoUHJvZHVjdG9BJFByaWNlKQ0KaGlzdChQcm9kdWN0b0IkUHJpY2UpDQpoaXN0KFByb2R1Y3RvQyRQcmljZSkNCmhpc3QoUHJvZHVjdG9EJFByaWNlKQ0KYGBgDQoNCiMjIFByb2R1Y3RvIEENCg0KIyMjIE3DqXRvZG8gUG9vbGVkDQoNCmBgYHtyfQ0KcG9vbGVkX0E8LXBsbShsb2coUHJpY2UpflZvbHVtZStUcmFuc3BvcnQuQ29zdCtSYXcuTWF0ZXJpYWwrUHJvZHVjdGlvbi5Db3N0K1NHQSwNCiAgICAgICAgICAgIGRhdGEgPSBBX3BkLA0KICAgICAgICAgICAgbW9kZWwgPSAicG9vbGluZyIpDQpzdW1tYXJ5KHBvb2xlZF9BKQ0KYGBgDQoNCiMjIyBNw6l0b2RvIFdpdGhpbg0KDQpgYGB7cn0NCndpdGhpbl9BPC1wbG0obG9nKFByaWNlKX5Wb2x1bWUrVHJhbnNwb3J0LkNvc3QrUmF3Lk1hdGVyaWFsK1Byb2R1Y3Rpb24uQ29zdCtTR0EsDQogICAgICAgICAgICBkYXRhID0gQV9wZCwNCiAgICAgICAgICAgIG1vZGVsID0gIndpdGhpbiIpDQpzdW1tYXJ5KHdpdGhpbl9BKQ0KYGBgDQoNCiMjIyMgQ29tcGFyYWNpw7NuIA0KDQpgYGB7cn0NCnBGdGVzdCh3aXRoaW5fQSxwb29sZWRfQSkNCmBgYA0KRGFkYSBlc3RhIGNvbXByb2JhY2lvbiBub3MgcXVlZGFtb3MgY29uIGVsIG1ldG9kbyBkZSBlZmVjdG9zIGFncnVwYWRvcyANCg0KDQoqKkJhc2Fkb3MgZW4gZWwgbW9kZWxvIGVzY29naWRvLCBsYXMgdmFyaWFibGVzIGVzdGFkaXN0aWNhbWVudGUgc2lnbmlmaWNhdGl2YXMgc29uIFZvbHVtZXkgZWwgaW50ZXJjZXB0byAgY29uIG5pdmVsIGRlIGNvbmZpYW56YSBtYXlvciA5OSUgICoqDQoNCiMjIFByb2R1Y3RvIEIgDQojIyMgTcOpdG9kbyBQb29sZWQNCg0KYGBge3J9DQpwb29sZWRfQjwtcGxtKGxvZyhQcmljZSl+Vm9sdW1lK1RyYW5zcG9ydC5Db3N0K1Jhdy5NYXRlcmlhbCtQcm9kdWN0aW9uLkNvc3QrU0dBLA0KICAgICAgICAgICAgZGF0YSA9IEJfcGQsDQogICAgICAgICAgICBtb2RlbCA9ICJwb29saW5nIikNCnN1bW1hcnkocG9vbGVkX0IpDQpgYGANCg0KIyMjIE3DqXRvZG8gV2l0aGluDQoNCmBgYHtyfQ0Kd2l0aGluX0I8LXBsbShsb2coUHJpY2UpflZvbHVtZStUcmFuc3BvcnQuQ29zdCtSYXcuTWF0ZXJpYWwrUHJvZHVjdGlvbi5Db3N0K1NHQSwNCiAgICAgICAgICAgIGRhdGEgPSBCX3BkLA0KICAgICAgICAgICAgbW9kZWwgPSAid2l0aGluIikNCnN1bW1hcnkod2l0aGluX0IpDQpgYGANCg0KDQojIyMjIENvbXBhcmFjacOzbiANCg0KYGBge3J9DQpwRnRlc3Qod2l0aGluX0IscG9vbGVkX0IpDQpgYGANCkRhZGEgZXN0YSBjb21wcm9iYWNpb24gbm9zIHF1ZWRhbW9zIGNvbiBlbCBtZXRvZG8gZGUgZWZlY3RvcyBhZ3J1cGFkb3MgDQoNCg0KKipCYXNhZG9zIGVuIGVsIG1vZGVsbyBlc2NvZ2lkbywgbGFzIHZhcmlhYmxlcyBlc3RhZGlzdGljYW1lbnRlIHNpZ25pZmljYXRpdmFzIHNvbiBWb2x1bWUgeSBlbCBpbnRlcmNlcHRvICBjb24gbml2ZWwgZGUgY29uZmlhbnphIG1heW9yIDk5JSAgKioNCg0KIyMgUHJvZHVjdG8gQw0KDQojIyMgTWV0b2RvIFBvb2xlZA0KDQpgYGB7cn0NCnBvb2xlZF9DPC1wbG0obG9nKFByaWNlKX5Wb2x1bWUrVHJhbnNwb3J0LkNvc3QrUmF3Lk1hdGVyaWFsK1Byb2R1Y3Rpb24uQ29zdCtTR0EsDQogICAgICAgICAgICBkYXRhID0gQ19wZCwNCiAgICAgICAgICAgIG1vZGVsID0gInBvb2xpbmciKQ0Kc3VtbWFyeShwb29sZWRfQykNCmBgYA0KDQojIyMgTcOpdG9kbyBXaXRoaW4NCg0KYGBge3J9DQp3aXRoaW5fQzwtcGxtKGxvZyhQcmljZSl+Vm9sdW1lK1RyYW5zcG9ydC5Db3N0K1Jhdy5NYXRlcmlhbCtQcm9kdWN0aW9uLkNvc3QrU0dBLA0KICAgICAgICAgICAgZGF0YSA9IENfcGQsDQogICAgICAgICAgICBtb2RlbCA9ICJ3aXRoaW4iKQ0Kc3VtbWFyeSh3aXRoaW5fQykNCmBgYA0KDQoNCiMjIyMgQ29tcGFyYWNpw7NuIA0KDQpgYGB7cn0NCnBGdGVzdCh3aXRoaW5fQyxwb29sZWRfQykNCmBgYA0KRGFkYSBlc3RhIGNvbXByb2JhY2lvbiBub3MgcXVlZGFtb3MgY29uIGVsIG1ldG9kbyBkZSBlZmVjdG9zIGFncnVwYWRvcw0KDQoqKkJhc2Fkb3MgZW4gZWwgbW9kZWxvIGVzY29naWRvLCBsYXMgdmFyaWFibGVzIGVzdGFkaXN0aWNhbWVudGUgc2lnbmlmaWNhdGl2YXMgc29uIFZvbHVtZSBlIEludGVyY2VwdG8gY29uIG5pdmVsIGRlIGNvbmZpYW56YSBtYXlvciA5OSUgIGRlIGNvbmZpYW56YSB5IFByb2R1Y3Rpb24gQ29zdCBjb24gIG5pdmVsIGRlIGNvbmZpYW56YSBkZSA5MCUgYSA5NSUqKg0KDQojIyBQcm9kdWN0byBEDQoNCiMjIyBNZXRvZG8gUG9vbGVkDQpgYGB7cn0NCnBvb2xlZF9EPC1wbG0obG9nKFByaWNlKX5Wb2x1bWUrVHJhbnNwb3J0LkNvc3QrUmF3Lk1hdGVyaWFsK1Byb2R1Y3Rpb24uQ29zdCtTR0EsDQogICAgICAgICAgICBkYXRhID0gRF9wZCwNCiAgICAgICAgICAgIG1vZGVsID0gInBvb2xpbmciKQ0Kc3VtbWFyeShwb29sZWRfRCkNCmBgYA0KDQojIyMgTcOpdG9kbyBXaXRoaW4NCg0KYGBge3J9DQp3aXRoaW5fRDwtcGxtKGxvZyhQcmljZSl+Vm9sdW1lK1RyYW5zcG9ydC5Db3N0K1Jhdy5NYXRlcmlhbCtQcm9kdWN0aW9uLkNvc3QrU0dBLA0KICAgICAgICAgICAgZGF0YSA9IERfcGQsDQogICAgICAgICAgICBtb2RlbCA9ICJ3aXRoaW4iKQ0Kc3VtbWFyeSh3aXRoaW5fRCkNCmBgYA0KDQoNCiMjIyMgQ29tcGFyYWNpw7NuIA0KDQpgYGB7cn0NCnBGdGVzdCh3aXRoaW5fRCxwb29sZWRfRCkNCmBgYA0KRGFkYSBlc3RhIGNvbXByb2JhY2lvbiBub3MgcXVlZGFtb3MgY29uIGVsIG1ldG9kbyBkZSBlZmVjdG9zIGFncnVwYWRvcw0KDQoNCioqQmFzYWRvcyBlbiBlbCBtb2RlbG8gZXNjb2dpZG8sIGxhcyB2YXJpYWJsZXMgZXN0YWRpc3RpY2FtZW50ZSBzaWduaWZpY2F0aXZhcyBzb24gVm9sdW1lIHkgZWwgaW50ZXJjZXB0byAgY29uIG5pdmVsIGRlIGNvbmZpYW56YSBtYXlvciA5OSUgKioNCg0KIyBTZXJpZXMgZGUgVGllbXBvDQoNCiMjIFByZWRpY2Npb24gUHJvZHVjdG8gQSANCg0KIyMjIEFncnVwYWNpb24NCmBgYHtyfQ0KUHJvZHVjdG9BX3RvdGFsPC1Qcm9kdWN0b0EgJT4lIGdyb3VwX2J5KERhdGUpICU+JSBzdW1tYXJpc2UoIlByaWNlIj1zdW0oUHJpY2UpKQ0KYGBgDQoNCiMjIyBBREYgVGVzdA0KYGBge3J9DQphZGYudGVzdChQcm9kdWN0b0FfdG90YWwkUHJpY2UpDQojIERlYmlkbyBhIHF1ZSB0ZW5lbW9zIHVuYSBzZXJpZSBubyBlc3RhY2lvbmFyaWEgYnVzY2FyZW1vcyB1bmEgZm9ybWEgZGUgaGFjZXJsYSBlc3RhY2lvbmFyaWEgDQoNCmFkZi50ZXN0KGxvZyhQcm9kdWN0b0FfdG90YWwkUHJpY2UpKSAjIEVsIHZhbG9yIGVzIG1heW9yIGEgMC4wNQ0KYGBgDQpEZWJpZG8gYSBxdWUgb2J0dXZpbW9zIHZhbG9yZXMgbWF5b3JlcyBhIDAuMDUsIG9wdGFtb3MgcG9yIHVzYXIgQVJJTUEgeWEgcXVlIGVzdGUgbW9kZWxvIHNlIG9jdXBhIGRlIGxhIG5vIGVzdGFjaW9uYXJpZGFkIGVuIGxhIHNlcmllIGRlIHRpZW1wbyANCg0KIyMjIFRyYW5zZm9ybWFjacOzbiBBDQpgYGB7cn0NClByb2R1Y3RBX3RzPC10cyhQcm9kdWN0b0FfdG90YWwkUHJpY2UsZnJlcXVlbmN5PTEyLHN0YXJ0PWMoMjAxOSwxKSkNClByb2R1Y3RBX2RlYzwtZGVjb21wb3NlKFByb2R1Y3RBX3RzKQ0KcGxvdChQcm9kdWN0QV9kZWMpICAgICAgDQpgYGANCiMjIyBBUklNQQ0KYGBge3J9DQpBX0FyaW1hPC1hcmltYShQcm9kdWN0QV90cyxvcmRlcj1jKDEsMSwxKSkNCnN1bW1hcnkoQV9BcmltYSkNCmBgYA0KIyMjIyBSZXNpZHVhbGVzDQpgYGB7cn0NCmNoZWNrcmVzaWR1YWxzKEFfQXJpbWEpDQphZGYudGVzdChBX0FyaW1hJHJlc2lkdWFscykgDQpgYGANCg0KTG9zIHJlc2lkdWFsZXMgZGVsIG1vZGVsbyBzb24gZXN0YWNpb25hcmlvcyB5IG5vIG11ZXN0cmFuIGF1dG9jb3JyZWxhY2lvbiBzZXJpYWwNCg0KDQojIyMgUHJvbm9zdGljbyANCmBgYHtyfQ0KcHJvbm9zdGljb0E8LWZvcmVjYXN0KEFfQXJpbWEsaD02KQ0KcHJvbm9zdGljb0ENCmF1dG9wbG90KHByb25vc3RpY29BLG1haW4gPSAiUHJvbm9zdGljbyBQcm9kdWN0byBBIikNCmBgYA0KDQojIyBQcmVkaWNjaW9uIFByb2R1Y3RvIEQgDQoNCiMjIyBBZ3J1cGFjaW9uDQpgYGB7cn0NClByb2R1Y3RvRF90b3RhbDwtUHJvZHVjdG9EICU+JSBncm91cF9ieShEYXRlKSAlPiUgc3VtbWFyaXNlKCJQcmljZSI9c3VtKFByaWNlKSkNCmBgYA0KDQojIyMgQURGIFRlc3QNCmBgYHtyfQ0KYWRmLnRlc3QoUHJvZHVjdG9EX3RvdGFsJFByaWNlKQ0KYGBgDQpPYnR1dmltb3MgdmFsb3JlcyBjb24gc2VyaWVzIGVzdGFjaW9uYXJpYXMNCg0KIyMjIFRyYW5zZm9ybWFjacOzbiBBDQpgYGB7cn0NClByb2R1Y3REX3RzPC10cyhQcm9kdWN0b0RfdG90YWwkUHJpY2UsZnJlcXVlbmN5PTEyLHN0YXJ0PWMoMjAxOSwxKSkNClByb2R1Y3REX2RlYzwtZGVjb21wb3NlKFByb2R1Y3REX3RzKQ0KcGxvdChQcm9kdWN0RF9kZWMpICAgICAgDQpgYGANCiMjIyBBUklNQQ0KYGBge3J9DQpEX0FSSU1BPC1hcmltYShQcm9kdWN0RF90cyxvcmRlcj1jKDEsMSwxKSkNCnN1bW1hcnkoRF9BUklNQSkNCmBgYA0KDQojIyMjIFJlc2lkdWFsZXMNCmBgYHtyfQ0KY2hlY2tyZXNpZHVhbHMoRF9BUklNQSkNCmFkZi50ZXN0KERfQVJJTUEkcmVzaWR1YWxzKSANCmBgYA0KDQpMb3MgcmVzaWR1YWxlcyBkZWwgbW9kZWxvIHNvbiBlc3RhY2lvbmFyaW9zIHkgbm8gbXVlc3RyYW4gYXV0b2NvcnJlbGFjaW9uIHNlcmlhbA0KDQoNCiMjIyBQcm9ub3N0aWNvIA0KYGBge3J9DQpwcm9ub3N0aWNvRDwtZm9yZWNhc3QoRF9BUklNQSxoPTYpDQpwcm9ub3N0aWNvRA0KYXV0b3Bsb3QocHJvbm9zdGljb0QsbWFpbiA9ICJQcm9ub3N0aWNvIFByb2R1Y3RvIEQiKQ0KYGBgDQoNCg0KDQo=