library(fpp3)
## Registered S3 method overwritten by 'tsibble':
##   method               from 
##   as_tibble.grouped_df dplyr
## ── Attaching packages ──────────────────────────────────────────── fpp3 1.0.1 ──
## ✔ tibble      3.2.1     ✔ tsibble     1.1.6
## ✔ dplyr       1.1.4     ✔ tsibbledata 0.4.1
## ✔ tidyr       1.3.1     ✔ feasts      0.4.1
## ✔ lubridate   1.9.3     ✔ fable       0.4.1
## ✔ ggplot2     3.5.1
## ── Conflicts ───────────────────────────────────────────────── fpp3_conflicts ──
## ✖ lubridate::date()    masks base::date()
## ✖ dplyr::filter()      masks stats::filter()
## ✖ tsibble::intersect() masks base::intersect()
## ✖ tsibble::interval()  masks lubridate::interval()
## ✖ dplyr::lag()         masks stats::lag()
## ✖ tsibble::setdiff()   masks base::setdiff()
## ✖ tsibble::union()     masks base::union()
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats 1.0.0     ✔ readr   2.1.5
## ✔ purrr   1.0.2     ✔ stringr 1.5.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter()     masks stats::filter()
## ✖ tsibble::interval() masks lubridate::interval()
## ✖ dplyr::lag()        masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
Sys.time()
## [1] "2025-03-30 17:09:46 EDT"

1.

Consider the GDP information in data set called global_economy, which is already embedded in fpp3 package (no need to upload externally)

1. Choose a random country by yourself. Then plot the GDP per capita for this country over time? How GDP per capita has changed over time for the series you chose? Explain briefly.

global_economy # see the data.
## # A tsibble: 15,150 x 9 [1Y]
## # Key:       Country [263]
##    Country     Code   Year         GDP Growth   CPI Imports Exports Population
##    <fct>       <fct> <dbl>       <dbl>  <dbl> <dbl>   <dbl>   <dbl>      <dbl>
##  1 Afghanistan AFG    1960  537777811.     NA    NA    7.02    4.13    8996351
##  2 Afghanistan AFG    1961  548888896.     NA    NA    8.10    4.45    9166764
##  3 Afghanistan AFG    1962  546666678.     NA    NA    9.35    4.88    9345868
##  4 Afghanistan AFG    1963  751111191.     NA    NA   16.9     9.17    9533954
##  5 Afghanistan AFG    1964  800000044.     NA    NA   18.1     8.89    9731361
##  6 Afghanistan AFG    1965 1006666638.     NA    NA   21.4    11.3     9938414
##  7 Afghanistan AFG    1966 1399999967.     NA    NA   18.6     8.57   10152331
##  8 Afghanistan AFG    1967 1673333418.     NA    NA   14.2     6.77   10372630
##  9 Afghanistan AFG    1968 1373333367.     NA    NA   15.2     8.90   10604346
## 10 Afghanistan AFG    1969 1408888922.     NA    NA   15.0    10.1    10854428
## # ℹ 15,140 more rows
# 1.Answer:
At_data<-global_economy %>%
  filter(Country =="Austria") 
#Plot the GDP Per Capita 
  
  ggplot(At_data,aes(x = Year, y = GDP/Population )) +
  geom_line() +
  labs(title = "GDP per Capita for Austria over time",
       x = "Year",
       y = "GDP per Capita")

2.

For each of the following series, make a graph of the data. If transforming seems appropriate, do so and describe the effect. Comment below in answer:

2a. Use the series you chose in #1.

# 2a.Answer:
At_data<-global_economy %>%
  filter(Country =="Austria") 
 ggplot(At_data,aes(x = Year, y = GDP/Population )) +
  geom_line() +
  labs(title = "GDP per Capita for Austria over time",
       x = "Year",
       y = "GDP per Capita")

2b.

United States GDP from global_economy.

# 2b.Answer:
global_economy %>% filter(Code=="USA") %>% autoplot(GDP)

2c.

Slaughter of Victorian “Bulls, bullocks and steers” in aus_livestock

# 2c.Answer:
aus_livestock %>% filter(State=="Victoria", Animal=="Bulls, bullocks and steers") %>% autoplot(Count)

2d.

Victorian Electricity Demand from vic_elec.

# 2d.Answer:
vic_elec %>%
  autoplot(Demand)

# transformation 
vic_elec %>% group_by(Date) %>% index_by(Date = yearweek(Time)) %>% summarise(Demand = sum(Demand)) %>% autoplot(Demand)

2e.

Gas production from aus_production.

# 2e.Answer:
aus_production %>%
  autoplot(Gas)

3. Use the canadian_gas data (monthly Canadian gas production in billions of cubic metres, January 1960 – February 2005).

2a. Plot the data using autoplot(), gg_subseries() , gg_season() to look at the effect of the changing seasonality over time. Describe the graphs in your own words. What do you see? What type pf pattern do you observe?

# 3a.Answer:
canadian_gas %>%
  autoplot(Volume)+
  labs(title = "Canadian Gas Production",
       y = "billions of cubic meter")

canadian_gas %>%
  gg_subseries(Volume)+
  labs(title = "Canadian Gas Production",
       y = "billions of cubic meter")

canadian_gas %>%
  gg_season(Volume)+
  labs(title = "Canadian Gas Production",
       y = "billions of cubic meter")

3b.

Do an STL decomposition of the data. You will need to choose a seasonal window to allow for the changing shape of the seasonal component.

# 3b.Answer:
canadian_gas %>%
  model(
    STL(Volume ~ trend(window = 25) +
          season(window = 16),
        robust = TRUE)) %>%
  components() %>%
  autoplot()+
  labs(title = "Canadian Gas STL decomposition ")

3c.

How does the seasonal shape change over time? [Hint: Try plotting the seasonal component using gg_season().]

# 3c.Answer:
canadian_gas  %>% gg_season(Volume)+
labs(title  =  "Canadian  Gas  Production", y  =  "billions  of  cubic  meter")

3d.

produce a plausible seasonally adjusted series? What are these numbers, plot the series.

# 3d.Answer:
canadian_gas %>%
  model(
    STL(Volume ~ trend(window = 21) + season(window = 13), robust = TRUE)
  ) %>%
  components() %>%
  ggplot(aes(x = Month)) +
  geom_line(aes(y = Volume, colour = "Data")) +
  geom_line(aes(y = season_adjust, colour = "Seasonally Adjusted")) +
  geom_line(aes(y = trend, colour = "Trend")) +
  labs(title = "STL decomposition of Canadian Gas Production") +
  scale_colour_manual(
    values = c("red", "green", "purple"),
    breaks = c("Data", "Seasonally Adjusted", "Trend")
  )

4.

For retail time series, use the below code:

# run the code
set.seed(12345678)

myseries <- aus_retail %>%
  filter(`Series ID` == sample(aus_retail$`Series ID`,1))

4a.

Create a training dataset consisting of observations before 2011

myseries_train <- myseries %>%
  filter(year(Month) < 2011)

myseries_train %>% tail()
## # A tsibble: 6 x 5 [1M]
## # Key:       State, Industry [1]
##   State              Industry                      `Series ID`    Month Turnover
##   <chr>              <chr>                         <chr>          <mth>    <dbl>
## 1 Northern Territory Clothing, footwear and perso… A3349767W   2010 Jul     16.1
## 2 Northern Territory Clothing, footwear and perso… A3349767W   2010 Aug     13.8
## 3 Northern Territory Clothing, footwear and perso… A3349767W   2010 Sep     13.6
## 4 Northern Territory Clothing, footwear and perso… A3349767W   2010 Oct     12.3
## 5 Northern Territory Clothing, footwear and perso… A3349767W   2010 Nov     11.7
## 6 Northern Territory Clothing, footwear and perso… A3349767W   2010 Dec     17.9

4b.

Check that your data have been split appropriately by producing the following plot.

autoplot(myseries, Turnover) +
  autolayer(myseries_train, Turnover, colour = "red")

4c.

Fit a seasonal naïve model using SNAIVE() applied to your training data (myseries_train).

 #Answer:
    fit <- myseries_train %>%
      model(SNAIVE(Turnover))

4d.

Check the residuals.

# 4d Answer:

fit %>% gg_tsresiduals()

# Do the residuals appear to be uncorrelated and normally distributed?
# Answ:

4e.

Produce forecasts for the test data with given code below:

# 4e Answer:
fc <- fit %>%  
forecast(new_data = anti_join(myseries, myseries_train))
## Joining with `by = join_by(State, Industry, `Series ID`, Month, Turnover)`
fc %>% autoplot(myseries)

Joining, by = c(“State”, “Industry”, “Series ID”, “Month”, “Turnover”)

4f.

Compare the accuracy of your forecasts against the actual values with given code below:

fit %>% accuracy()
## # A tibble: 1 × 12
##   State    Industry .model .type    ME  RMSE   MAE   MPE  MAPE  MASE RMSSE  ACF1
##   <chr>    <chr>    <chr>  <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Norther… Clothin… SNAIV… Trai… 0.439  1.21 0.915  5.23  12.4     1     1 0.768
fc %>% accuracy(myseries)
## # A tibble: 1 × 12
##   .model    State Industry .type    ME  RMSE   MAE   MPE  MAPE  MASE RMSSE  ACF1
##   <chr>     <chr> <chr>    <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 SNAIVE(T… Nort… Clothin… Test  0.836  1.55  1.24  5.94  9.06  1.36  1.28 0.601
# 4f Answ:
fit %>% accuracy()
## # A tibble: 1 × 12
##   State    Industry .model .type    ME  RMSE   MAE   MPE  MAPE  MASE RMSSE  ACF1
##   <chr>    <chr>    <chr>  <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Norther… Clothin… SNAIV… Trai… 0.439  1.21 0.915  5.23  12.4     1     1 0.768
fc %>% accuracy(myseries)
## # A tibble: 1 × 12
##   .model    State Industry .type    ME  RMSE   MAE   MPE  MAPE  MASE RMSSE  ACF1
##   <chr>     <chr> <chr>    <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 SNAIVE(T… Nort… Clothin… Test  0.836  1.55  1.24  5.94  9.06  1.36  1.28 0.601

4g.

How sensitive are the accuracy measures to the amount of training data used?

# 4g Answer:

bind_rows(
     accuracy(fit),
     accuracy(fc, myseries)
   ) %>%
     select(-State, -Industry, -.model)
## # A tibble: 2 × 9
##   .type       ME  RMSE   MAE   MPE  MAPE  MASE RMSSE  ACF1
##   <chr>    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Training 0.439  1.21 0.915  5.23 12.4   1     1    0.768
## 2 Test     0.836  1.55 1.24   5.94  9.06  1.36  1.28 0.601

5.

5a.

Create a training set for Australian takeaway food turnover (aus_retail) by withholding the last four years as a test set.

# 5a.Answer:
set.seed(2100)

takeaway_food_turnover <- 
  aus_retail  %>%
  filter(Industry =="Takeaway food services") %>%
  summarise(Tota_Turnover = sum(Turnover))

takeaway_food_turnover %>% autoplot(Tota_Turnover)

takeaway_train_set <- 
  takeaway_food_turnover %>% 
  filter(year(Month) < 2018) #with hold last 4 years
takeaway_train_set %>% autoplot(Tota_Turnover)

5b.

Fit all the appropriate benchmark methods to the training set and forecast the periods covered by the test set.

# 5b.Answer:
takeaway_dcmp = takeaway_train_set %>% 
  model(stl = STL(Tota_Turnover))

components(takeaway_dcmp) %>% autoplot(show.legend = FALSE)

takeaway_fit <- takeaway_train_set %>%
  model(
    Naive = NAIVE(Tota_Turnover),
    Seasonal_naive = SNAIVE(Tota_Turnover),
    Drift = RW(Tota_Turnover ~ drift())
  )

takeaway_fc <- takeaway_fit %>% forecast(h = 4) 
takeaway_fc  %>% autoplot(takeaway_train_set)

5c.

Compute the accuracy of your forecasts. Which method does best?

# 5c.Answer:
accuracy(takeaway_fc, takeaway_food_turnover)
## # A tibble: 3 × 10
##   .model         .type      ME  RMSE   MAE     MPE  MAPE  MASE RMSSE   ACF1
##   <chr>          <chr>   <dbl> <dbl> <dbl>   <dbl> <dbl> <dbl> <dbl>  <dbl>
## 1 Drift          Test  -244.   253.  244.  -16.8   16.8  5.46  4.47  -0.594
## 2 Naive          Test  -235.   245.  235.  -16.2   16.2  5.26  4.32  -0.552
## 3 Seasonal_naive Test     9.28  26.8  22.8   0.650  1.55 0.511 0.472 -0.153

5d.

Do the residuals from the best method resemble white noise?

# 5d.Answer:
takeaway_Res <- takeaway_train_set %>%
  model(
    Seasonal_naive = SNAIVE(Tota_Turnover)
  )
gg_tsresiduals(takeaway_Res)

6.

Using the code below, get a series (it gets a series randomly by using sample() function):

set.seed(12345678)
myseries <- aus_retail %>%
  filter(`Series ID` == sample(aus_retail$`Series ID`,1))

see head of your series to check it is a tsibble data, and remove NA’s if there is any with these commands:

head(myseries)
## # A tsibble: 6 x 5 [1M]
## # Key:       State, Industry [1]
##   State              Industry                      `Series ID`    Month Turnover
##   <chr>              <chr>                         <chr>          <mth>    <dbl>
## 1 Northern Territory Clothing, footwear and perso… A3349767W   1988 Apr      2.3
## 2 Northern Territory Clothing, footwear and perso… A3349767W   1988 May      2.9
## 3 Northern Territory Clothing, footwear and perso… A3349767W   1988 Jun      2.6
## 4 Northern Territory Clothing, footwear and perso… A3349767W   1988 Jul      2.8
## 5 Northern Territory Clothing, footwear and perso… A3349767W   1988 Aug      2.9
## 6 Northern Territory Clothing, footwear and perso… A3349767W   1988 Sep      3
myseries =  myseries %>% filter(!is.na(`Series ID`))

6a.

What is the name of the series you randomly choose? Write it.

# 6a.Answer:
head(myseries)
## # A tsibble: 6 x 5 [1M]
## # Key:       State, Industry [1]
##   State              Industry                      `Series ID`    Month Turnover
##   <chr>              <chr>                         <chr>          <mth>    <dbl>
## 1 Northern Territory Clothing, footwear and perso… A3349767W   1988 Apr      2.3
## 2 Northern Territory Clothing, footwear and perso… A3349767W   1988 May      2.9
## 3 Northern Territory Clothing, footwear and perso… A3349767W   1988 Jun      2.6
## 4 Northern Territory Clothing, footwear and perso… A3349767W   1988 Jul      2.8
## 5 Northern Territory Clothing, footwear and perso… A3349767W   1988 Aug      2.9
## 6 Northern Territory Clothing, footwear and perso… A3349767W   1988 Sep      3
myseries =  myseries %>% filter(!is.na(`Series ID`))

6b.

Run a linear regression of Turnover on trend.(Hint: use TSLM() and trend() functions)

# 6b.Answer:

myseries_Tslm <- myseries %>% model(trend_model = TSLM(Turnover ~ trend())) %>% report()
## Series: Turnover 
## Model: TSLM 
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -4.0795 -1.1704 -0.1640  0.9683  7.4514 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 3.5313376  0.1983464   17.80   <2e-16 ***
## trend()     0.0307747  0.0009291   33.12   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 1.901 on 367 degrees of freedom
## Multiple R-squared: 0.7493,  Adjusted R-squared: 0.7486
## F-statistic:  1097 on 1 and 367 DF, p-value: < 2.22e-16

6c.

See the regression result by report() command.

# 6c.Answer:

myseries_Tslm <- myseries %>% model(trend_model = TSLM(Turnover ~ trend())) %>% report()
## Series: Turnover 
## Model: TSLM 
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -4.0795 -1.1704 -0.1640  0.9683  7.4514 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 3.5313376  0.1983464   17.80   <2e-16 ***
## trend()     0.0307747  0.0009291   33.12   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 1.901 on 367 degrees of freedom
## Multiple R-squared: 0.7493,  Adjusted R-squared: 0.7486
## F-statistic:  1097 on 1 and 367 DF, p-value: < 2.22e-16

6d.

By using this model, forecast it for the next 3 years. What are the values of the next 3 years, monthly values?

# 6d.Answer:
fc <- myseries_Tslm %>% forecast(h = 3)
fc
## # A fable: 3 x 6 [1M]
## # Key:     State, Industry, .model [1]
##   State              Industry                                    .model    Month
##   <chr>              <chr>                                       <chr>     <mth>
## 1 Northern Territory Clothing, footwear and personal accessory … trend… 2019 Jan
## 2 Northern Territory Clothing, footwear and personal accessory … trend… 2019 Feb
## 3 Northern Territory Clothing, footwear and personal accessory … trend… 2019 Mar
## # ℹ 2 more variables: Turnover <dist>, .mean <dbl>

6d.

Plot the forecast values along with the original data.

# 6d.Answer:

fc %>% autoplot(myseries) + labs(title = "Aus_Retail_Plot", y = "Turnover")

6e.

Get the residuals from the model. And check the residuals to check whether or not it satisfies the requirements for white noise error terms.(hint: augment() and gg_tsresiduals() functions)

# 6e.Answer:
augment(myseries_Tslm)
## # A tsibble: 369 x 8 [1M]
## # Key:       State, Industry, .model [1]
##    State              Industry    .model    Month Turnover .fitted .resid .innov
##    <chr>              <chr>       <chr>     <mth>    <dbl>   <dbl>  <dbl>  <dbl>
##  1 Northern Territory Clothing, … trend… 1988 Apr      2.3    3.56 -1.26  -1.26 
##  2 Northern Territory Clothing, … trend… 1988 May      2.9    3.59 -0.693 -0.693
##  3 Northern Territory Clothing, … trend… 1988 Jun      2.6    3.62 -1.02  -1.02 
##  4 Northern Territory Clothing, … trend… 1988 Jul      2.8    3.65 -0.854 -0.854
##  5 Northern Territory Clothing, … trend… 1988 Aug      2.9    3.69 -0.785 -0.785
##  6 Northern Territory Clothing, … trend… 1988 Sep      3      3.72 -0.716 -0.716
##  7 Northern Territory Clothing, … trend… 1988 Oct      3.1    3.75 -0.647 -0.647
##  8 Northern Territory Clothing, … trend… 1988 Nov      3      3.78 -0.778 -0.778
##  9 Northern Territory Clothing, … trend… 1988 Dec      4.2    3.81  0.392  0.392
## 10 Northern Territory Clothing, … trend… 1989 Jan      2.7    3.84 -1.14  -1.14 
## # ℹ 359 more rows
gg_tsresiduals(myseries_Tslm)

7.

Half-hourly electricity demand for Victoria, Australia is contained in vic_elec. Extract the January 2014 electricity demand, and aggregate this data to daily with daily total demands and maximum temperatures. Run the code below:

jan_vic_elec <- vic_elec %>%
  filter(yearmonth(Time) == yearmonth("2014 Jan")) %>%
  index_by(Date = as_date(Time)) %>%
  summarise(Demand = sum(Demand), Temperature = max(Temperature))

7a.

Plot the data and find the regression model for Demand with temperature as a predictor variable. Why is there a positive relationship?

# 7a.Answer:

jan_vic_elec %>%
  autoplot(Demand)

jan_vic_elec %>%
  autoplot(Temperature)

prediction <- jan_vic_elec %>% 
  model(TSLM(Demand ~ Temperature))

report(prediction)
## Series: Demand 
## Model: TSLM 
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -49978.2 -10218.9   -121.3  18533.2  35440.6 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  59083.9    17424.8   3.391  0.00203 ** 
## Temperature   6154.3      601.3  10.235 3.89e-11 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 24540 on 29 degrees of freedom
## Multiple R-squared: 0.7832,  Adjusted R-squared: 0.7757
## F-statistic: 104.7 on 1 and 29 DF, p-value: 3.8897e-11
jan_vic_elec %>%
  ggplot(aes(x=Temperature, y=Demand)) +
  geom_point() +
  geom_smooth(method="lm", se=FALSE) +
  labs(title = "Electricity Demand") +
  theme(plot.title = element_text(hjust = 0.5))
## `geom_smooth()` using formula = 'y ~ x'

7b.

Produce a residual plot. Is the model adequate? Are there any outliers or influential observations?

# 7b.Answer:
library(feasts)
prediction %>%
  gg_tsresiduals()

7c.

Use the model to forecast the electricity demand that you would expect for the next day if the maximum temperature was 15∘C and compare it with the forecast if the with maximum temperature was 35∘C. Do you believe these forecasts?

jan_vic_elec %>%
  model(TSLM(Demand ~ Temperature)) %>%
  forecast(new_data(jan_vic_elec, 1) %>%
      mutate(Temperature = 15)) %>%
  autoplot(jan_vic_elec)

jan_vic_elec %>%
  model(TSLM(Demand ~ Temperature)) %>%
  forecast(new_data(jan_vic_elec, 1) %>%
      mutate(Temperature = 35)) %>%
  autoplot(jan_vic_elec)

# 7c.Answer:

7d.

Do you believe these forecasts? The following R code will get you started:

  jan_vic_elec %>%
  model(TSLM(Demand ~ Temperature)) %>%
  forecast(
    new_data(jan_vic_elec, 1) %>%
      mutate(Temperature = 15)
  ) %>%
  autoplot(jan_vic_elec)

# 7d.Answer:
library(forecast)
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
next_day <- scenarios(
  `Cold day` = new_data(jan_vic_elec, 1) %>% mutate(Temperature = 15),
  `Hot day` = new_data(jan_vic_elec, 1) %>% mutate(Temperature = 35)
)

7e.

Give prediction intervals for your forecasts.

# 7e.Answer:
fc <- prediction %>%
  forecast(new_data = next_day)

# Plot it

autoplot(jan_vic_elec, Demand) + 
  autolayer(fc, series = "Forecast", PI = TRUE, alpha = 0.5) + 
  labs(title = "Demand Forecast for electricity",
       x = "Date",
       y = "Demand")

8.

Read the shampoo data given in excel (Import Dataset as Excel)

#a. View the shampoo sales data. How many variables are there? Find how many rows and columns in the data?
  library(readxl)
shampoo <- read_excel("shampoo-2.xlsx")

head(shampoo)
## # A tibble: 6 × 2
##   Month               sales
##   <dttm>              <dbl>
## 1 1995-01-01 00:00:00  266 
## 2 1995-02-01 00:00:00  146.
## 3 1995-03-01 00:00:00  183.
## 4 1995-04-01 00:00:00  119.
## 5 1995-05-01 00:00:00  180.
## 6 1995-06-01 00:00:00  168.
print("there are 36 rows and 2 columns")
## [1] "there are 36 rows and 2 columns"
str(shampoo)
## tibble [36 × 2] (S3: tbl_df/tbl/data.frame)
##  $ Month: POSIXct[1:36], format: "1995-01-01" "1995-02-01" ...
##  $ sales: num [1:36] 266 146 183 119 180 ...
print("there are two variables one is month and one is sales")
## [1] "there are two variables one is month and one is sales"
#b. Is the data annual, monthly, quarterly?
print("the dataset contains monthly data")
## [1] "the dataset contains monthly data"
#c. Convert the data into tibble , then tsibble 
shampoo$Month <- as_date(shampoo$Month)
shampoo_new<- as_tibble(shampoo)
shampoo_new <- shampoo_new %>%
  mutate(Months = yearmonth(Month)) %>%
  select(-Month) %>%
  as_tsibble(
    index = Months,
    validate = TRUE
  )
#d. Plot the shampoo sales. What do you see from the data pattern? What does x-axis represent? 
# Comment here. Use plot() and autoplot().Put the name for y axis, and a title for the graph.
plot(shampoo_new$sales, type = "l",
     ylab = "Sales",
     main = "Sales_years")

  print("From the plot graph, I don't see any pattern that follows trend or seasonality.")
## [1] "From the plot graph, I don't see any pattern that follows trend or seasonality."
shampoo_new %>%
  autoplot(sales)+
  labs(
    y = "Sales",
    title = "Sales_years"
  )

print("From the autoplot graph, I see that there is a seasonality followed.")
## [1] "From the autoplot graph, I see that there is a seasonality followed."
#e. What is the average, and median of shampoo sales. Put it on a histogram.
x = mean(shampoo_new$sales)
y = median(shampoo_new$sales)
hist(shampoo_new$sales)

abline(v = x,
       col = "green",
       lwd = 3)

abline(v = median(shampoo_new$sales),
       col = "blue",
       lwd = 3)

text(x = x * 1.5,
     y = x * 1.5,
     paste("Mean = ", x),
     col = "green",
     cex = 1)

text(x = y * 1.5,
     y = y * 1.5,
     paste("Median = ", y),
     col = "blue",
     cex = 1)

print("The average sale of shampoo is 312.6 and median of shampoo sale is 280.15.")
## [1] "The average sale of shampoo is 312.6 and median of shampoo sale is 280.15."
#f. Get seasonal plot. What do you see/ is there any pattern, is tehre any seasonality.
shampoo_new %>%
  gg_season(sales)

print("there is no seasonality from the graph.")
## [1] "there is no seasonality from the graph."
#g. Get a linear regression line with trend and dummy for each month (Hint: use trend and season in regression equation).
shampoo_fc <- shampoo_new %>%
  model(TSLM(sales ~ trend() + season()))
report(shampoo_fc)
## Series: sales 
## Model: TSLM 
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -129.60  -62.32   -4.84   53.76  152.72 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)     113.867     55.740   2.043   0.0527 .  
## trend()          11.754      1.534   7.664 8.88e-08 ***
## season()year2   -33.154     73.630  -0.450   0.6567    
## season()year3   -53.808     73.678  -0.730   0.4726    
## season()year4   -24.628     73.757  -0.334   0.7415    
## season()year5   -56.015     73.869  -0.758   0.4560    
## season()year6   -27.802     74.012  -0.376   0.7106    
## season()year7     7.244     74.187   0.098   0.9231    
## season()year8   -37.043     74.393  -0.498   0.6233    
## season()year9    27.536     74.629   0.369   0.7155    
## season()year10  -32.518     74.897  -0.434   0.6682    
## season()year11    9.895     75.194   0.132   0.8964    
## season()year12   -4.259     75.522  -0.056   0.9555    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 90.16 on 23 degrees of freedom
## Multiple R-squared: 0.7592,  Adjusted R-squared: 0.6336
## F-statistic: 6.043 on 12 and 23 DF, p-value: 0.00011612
augment(shampoo_fc) %>%
  ggplot(aes(x = Months)) +
  geom_line(aes(y = sales, colour = "Data")) +
  geom_line(aes(y = .fitted, colour = "Fitted")) +
  labs(y=" Sales",title ="Month Sales") +
  scale_colour_manual(values = c(Data = "brown", Fitted = "#D55E00"))

#h. Comment on each estimated coefficient of the model.Are they statistically significant at 5 % significance level?
report(shampoo_fc)
## Series: sales 
## Model: TSLM 
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -129.60  -62.32   -4.84   53.76  152.72 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)     113.867     55.740   2.043   0.0527 .  
## trend()          11.754      1.534   7.664 8.88e-08 ***
## season()year2   -33.154     73.630  -0.450   0.6567    
## season()year3   -53.808     73.678  -0.730   0.4726    
## season()year4   -24.628     73.757  -0.334   0.7415    
## season()year5   -56.015     73.869  -0.758   0.4560    
## season()year6   -27.802     74.012  -0.376   0.7106    
## season()year7     7.244     74.187   0.098   0.9231    
## season()year8   -37.043     74.393  -0.498   0.6233    
## season()year9    27.536     74.629   0.369   0.7155    
## season()year10  -32.518     74.897  -0.434   0.6682    
## season()year11    9.895     75.194   0.132   0.8964    
## season()year12   -4.259     75.522  -0.056   0.9555    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 90.16 on 23 degrees of freedom
## Multiple R-squared: 0.7592,  Adjusted R-squared: 0.6336
## F-statistic: 6.043 on 12 and 23 DF, p-value: 0.00011612
print("The model is coefficient and  is statistically significant at 5% level.")
## [1] "The model is coefficient and  is statistically significant at 5% level."
#i. Which month has the highest sales?
  
shampoo_new %>%
  mutate(only_months = month(Months)) %>%
  select(-Months) %>%
  index_by(only_months) %>%
  summarise(highest_sales = sum(sales)) %>%
  top_n(1)
## Selecting by highest_sales
## # A tsibble: 1 x 2 [1]
##   only_months highest_sales
##         <dbl>         <dbl>
## 1          11         1182.
print("11th month has highest sale which is total of 1182.")
## [1] "11th month has highest sale which is total of 1182."
#j. Forecast it for the next year. What are the values
forecast_trends <- shampoo_fc %>%
  forecast(h = 12)
forecast_trends
## # A fable: 12 x 4 [1M]
## # Key:     .model [1]
##    .model                             Months
##    <chr>                               <mth>
##  1 TSLM(sales ~ trend() + season()) 1998 Jan
##  2 TSLM(sales ~ trend() + season()) 1998 Feb
##  3 TSLM(sales ~ trend() + season()) 1998 Mar
##  4 TSLM(sales ~ trend() + season()) 1998 Apr
##  5 TSLM(sales ~ trend() + season()) 1998 May
##  6 TSLM(sales ~ trend() + season()) 1998 Jun
##  7 TSLM(sales ~ trend() + season()) 1998 Jul
##  8 TSLM(sales ~ trend() + season()) 1998 Aug
##  9 TSLM(sales ~ trend() + season()) 1998 Sep
## 10 TSLM(sales ~ trend() + season()) 1998 Oct
## 11 TSLM(sales ~ trend() + season()) 1998 Nov
## 12 TSLM(sales ~ trend() + season()) 1998 Dec
## # ℹ 2 more variables: sales <dist>, .mean <dbl>
#k. Plot the forecast with original data.
shampoo_new %>%
  autoplot(sales) +
  geom_line(data = fitted(shampoo_fc),
            aes(y = .fitted, colour = .model)) +
  autolayer(forecast_trends, alpha = 0.5, level = 95) +
  labs(y = "Sales",
       title = "Monthly Sales")

#l. Check if the residuals of the model is white noise.
  
shampoo_fc %>%
  gg_tsresiduals()

print("Yes,the residuals of the model is white  noise.")
## [1] "Yes,the residuals of the model is white  noise."
#m. By using the regression model, forecast the 1 year ahead, and then check the accuracy of the forecast. What is MSE, RMSE values?
  forecast_trends <- shampoo_fc %>%
  forecast(h = "1 year")
forecast_trends
## # A fable: 12 x 4 [1M]
## # Key:     .model [1]
##    .model                             Months
##    <chr>                               <mth>
##  1 TSLM(sales ~ trend() + season()) 1998 Jan
##  2 TSLM(sales ~ trend() + season()) 1998 Feb
##  3 TSLM(sales ~ trend() + season()) 1998 Mar
##  4 TSLM(sales ~ trend() + season()) 1998 Apr
##  5 TSLM(sales ~ trend() + season()) 1998 May
##  6 TSLM(sales ~ trend() + season()) 1998 Jun
##  7 TSLM(sales ~ trend() + season()) 1998 Jul
##  8 TSLM(sales ~ trend() + season()) 1998 Aug
##  9 TSLM(sales ~ trend() + season()) 1998 Sep
## 10 TSLM(sales ~ trend() + season()) 1998 Oct
## 11 TSLM(sales ~ trend() + season()) 1998 Nov
## 12 TSLM(sales ~ trend() + season()) 1998 Dec
## # ℹ 2 more variables: sales <dist>, .mean <dbl>
MSE_fc1 <- mean((shampoo_new$sales - forecast_trends$.mean)^2)
MSE_fc1
## [1] 98031.53
RMSE_fc1 <- sqrt(mean((shampoo_new$sales - forecast_trends$.mean)^2))
RMSE_fc1
## [1] 313.0999
print("MSE = 98031.33
      RMSE = 313.099")
## [1] "MSE = 98031.33\n      RMSE = 313.099"
LS0tCnRpdGxlOiAiRUNPTiA2NjM1IC0gRVhBTSBJIFNwcmluZyAyMDI1ICIKYXV0aG9yOiBLcmlzaG5hdmVuaSBBdnVzYWxpIGFuZCBrYXZ1czFAdW5oLm5ld2hhdmVuLmVkdQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDogb3BlbmludHJvOjpsYWJfcmVwb3J0CiAgCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgd2FybmluZyA9IEZBTFNFKQoKYGBgCgoKYGBge3J9CmxpYnJhcnkoZnBwMykKbGlicmFyeSh0aWR5dmVyc2UpClN5cy50aW1lKCkKYGBgCgojIyMgMS4JCkNvbnNpZGVyIHRoZSBHRFAgaW5mb3JtYXRpb24gaW4gZGF0YSBzZXQgY2FsbGVkIGdsb2JhbF9lY29ub215LCB3aGljaCBpcyBhbHJlYWR5IGVtYmVkZGVkIGluIGZwcDMgcGFja2FnZSAobm8gbmVlZCB0byB1cGxvYWQgZXh0ZXJuYWxseSkgCgojIyMgMS4JQ2hvb3NlIGEgcmFuZG9tIGNvdW50cnkgYnkgeW91cnNlbGYuIFRoZW4gcGxvdCB0aGUgR0RQIHBlciBjYXBpdGEgZm9yIHRoaXMgY291bnRyeSBvdmVyIHRpbWU/IEhvdyBHRFAgcGVyIGNhcGl0YSBoYXMgY2hhbmdlZCBvdmVyIHRpbWUgZm9yIHRoZSBzZXJpZXMgeW91IGNob3NlPyBFeHBsYWluIGJyaWVmbHkuCgpgYGB7cn0KZ2xvYmFsX2Vjb25vbXkgIyBzZWUgdGhlIGRhdGEuCgoKIyAxLkFuc3dlcjoKQXRfZGF0YTwtZ2xvYmFsX2Vjb25vbXkgJT4lCiAgZmlsdGVyKENvdW50cnkgPT0iQXVzdHJpYSIpIAojUGxvdCB0aGUgR0RQIFBlciBDYXBpdGEgCiAgCiAgZ2dwbG90KEF0X2RhdGEsYWVzKHggPSBZZWFyLCB5ID0gR0RQL1BvcHVsYXRpb24gKSkgKwogIGdlb21fbGluZSgpICsKICBsYWJzKHRpdGxlID0gIkdEUCBwZXIgQ2FwaXRhIGZvciBBdXN0cmlhIG92ZXIgdGltZSIsCiAgICAgICB4ID0gIlllYXIiLAogICAgICAgeSA9ICJHRFAgcGVyIENhcGl0YSIpCmBgYAoKIyMjIDIuCQpGb3IgZWFjaCBvZiB0aGUgZm9sbG93aW5nIHNlcmllcywgbWFrZSBhIGdyYXBoIG9mIHRoZSBkYXRhLiBJZiB0cmFuc2Zvcm1pbmcgc2VlbXMgYXBwcm9wcmlhdGUsIGRvIHNvIGFuZCBkZXNjcmliZSB0aGUgZWZmZWN0LiBDb21tZW50IGJlbG93IGluIGFuc3dlcjoKCiMjIyAyYS4gVXNlIHRoZSBzZXJpZXMgeW91IGNob3NlIGluICMxLgpgYGB7cn0KCiMgMmEuQW5zd2VyOgpBdF9kYXRhPC1nbG9iYWxfZWNvbm9teSAlPiUKICBmaWx0ZXIoQ291bnRyeSA9PSJBdXN0cmlhIikgCiBnZ3Bsb3QoQXRfZGF0YSxhZXMoeCA9IFllYXIsIHkgPSBHRFAvUG9wdWxhdGlvbiApKSArCiAgZ2VvbV9saW5lKCkgKwogIGxhYnModGl0bGUgPSAiR0RQIHBlciBDYXBpdGEgZm9yIEF1c3RyaWEgb3ZlciB0aW1lIiwKICAgICAgIHggPSAiWWVhciIsCiAgICAgICB5ID0gIkdEUCBwZXIgQ2FwaXRhIikKYGBgCgojIyMgMmIuCQpVbml0ZWQgU3RhdGVzIEdEUCBmcm9tIGdsb2JhbF9lY29ub215LgpgYGB7cn0KCgojIDJiLkFuc3dlcjoKZ2xvYmFsX2Vjb25vbXkgJT4lIGZpbHRlcihDb2RlPT0iVVNBIikgJT4lIGF1dG9wbG90KEdEUCkKCmBgYAoKIyMjIDJjLgkKU2xhdWdodGVyIG9mIFZpY3RvcmlhbiDigJxCdWxscywgYnVsbG9ja3MgYW5kIHN0ZWVyc+KAnSBpbiBhdXNfbGl2ZXN0b2NrCmBgYHtyfQoKIyAyYy5BbnN3ZXI6CmF1c19saXZlc3RvY2sgJT4lIGZpbHRlcihTdGF0ZT09IlZpY3RvcmlhIiwgQW5pbWFsPT0iQnVsbHMsIGJ1bGxvY2tzIGFuZCBzdGVlcnMiKSAlPiUgYXV0b3Bsb3QoQ291bnQpCgpgYGAKCiMjIyAyZC4KVmljdG9yaWFuIEVsZWN0cmljaXR5IERlbWFuZCBmcm9tIHZpY19lbGVjLgpgYGB7cn0KCgojIDJkLkFuc3dlcjoKdmljX2VsZWMgJT4lCiAgYXV0b3Bsb3QoRGVtYW5kKQoKIyB0cmFuc2Zvcm1hdGlvbiAKdmljX2VsZWMgJT4lIGdyb3VwX2J5KERhdGUpICU+JSBpbmRleF9ieShEYXRlID0geWVhcndlZWsoVGltZSkpICU+JSBzdW1tYXJpc2UoRGVtYW5kID0gc3VtKERlbWFuZCkpICU+JSBhdXRvcGxvdChEZW1hbmQpCgpgYGAKCiMjIyAyZS4JCkdhcyBwcm9kdWN0aW9uIGZyb20gYXVzX3Byb2R1Y3Rpb24uCmBgYHtyfQoKCiMgMmUuQW5zd2VyOgphdXNfcHJvZHVjdGlvbiAlPiUKICBhdXRvcGxvdChHYXMpCmBgYAoKIyMjIDMuCVVzZSB0aGUgY2FuYWRpYW5fZ2FzIGRhdGEgKG1vbnRobHkgQ2FuYWRpYW4gZ2FzIHByb2R1Y3Rpb24gaW4gYmlsbGlvbnMgb2YgY3ViaWMgbWV0cmVzLCBKYW51YXJ5IDE5NjAg4oCTIEZlYnJ1YXJ5IDIwMDUpLgojIyMjIDJhLglQbG90IHRoZSBkYXRhIHVzaW5nIGF1dG9wbG90KCksIGdnX3N1YnNlcmllcygpICwgZ2dfc2Vhc29uKCkgdG8gbG9vayBhdCB0aGUgZWZmZWN0IG9mIHRoZSBjaGFuZ2luZyBzZWFzb25hbGl0eSBvdmVyIHRpbWUuIERlc2NyaWJlIHRoZSBncmFwaHMgaW4geW91ciBvd24gd29yZHMuIFdoYXQgZG8geW91IHNlZT8gV2hhdCB0eXBlIHBmIHBhdHRlcm4gZG8geW91IG9ic2VydmU/CgpgYGB7cn0KCgojIDNhLkFuc3dlcjoKY2FuYWRpYW5fZ2FzICU+JQogIGF1dG9wbG90KFZvbHVtZSkrCiAgbGFicyh0aXRsZSA9ICJDYW5hZGlhbiBHYXMgUHJvZHVjdGlvbiIsCiAgICAgICB5ID0gImJpbGxpb25zIG9mIGN1YmljIG1ldGVyIikKY2FuYWRpYW5fZ2FzICU+JQogIGdnX3N1YnNlcmllcyhWb2x1bWUpKwogIGxhYnModGl0bGUgPSAiQ2FuYWRpYW4gR2FzIFByb2R1Y3Rpb24iLAogICAgICAgeSA9ICJiaWxsaW9ucyBvZiBjdWJpYyBtZXRlciIpCmNhbmFkaWFuX2dhcyAlPiUKICBnZ19zZWFzb24oVm9sdW1lKSsKICBsYWJzKHRpdGxlID0gIkNhbmFkaWFuIEdhcyBQcm9kdWN0aW9uIiwKICAgICAgIHkgPSAiYmlsbGlvbnMgb2YgY3ViaWMgbWV0ZXIiKQoKYGBgCgojIyMgM2IuCkRvIGFuIFNUTCBkZWNvbXBvc2l0aW9uIG9mIHRoZSBkYXRhLiBZb3Ugd2lsbCBuZWVkIHRvIGNob29zZSBhIHNlYXNvbmFsIHdpbmRvdyB0byBhbGxvdyBmb3IgdGhlIGNoYW5naW5nIHNoYXBlIG9mIHRoZSBzZWFzb25hbCBjb21wb25lbnQuCgpgYGB7cn0KCiMgM2IuQW5zd2VyOgpjYW5hZGlhbl9nYXMgJT4lCiAgbW9kZWwoCiAgICBTVEwoVm9sdW1lIH4gdHJlbmQod2luZG93ID0gMjUpICsKICAgICAgICAgIHNlYXNvbih3aW5kb3cgPSAxNiksCiAgICAgICAgcm9idXN0ID0gVFJVRSkpICU+JQogIGNvbXBvbmVudHMoKSAlPiUKICBhdXRvcGxvdCgpKwogIGxhYnModGl0bGUgPSAiQ2FuYWRpYW4gR2FzIFNUTCBkZWNvbXBvc2l0aW9uICIpCgoKYGBgCgojIyMgM2MuCkhvdyBkb2VzIHRoZSBzZWFzb25hbCBzaGFwZSBjaGFuZ2Ugb3ZlciB0aW1lPyBbSGludDogVHJ5IHBsb3R0aW5nIHRoZSBzZWFzb25hbCBjb21wb25lbnQgdXNpbmcgZ2dfc2Vhc29uKCkuXQpgYGB7cn0KCgojIDNjLkFuc3dlcjoKY2FuYWRpYW5fZ2FzICAlPiUgZ2dfc2Vhc29uKFZvbHVtZSkrCmxhYnModGl0bGUgID0gICJDYW5hZGlhbiAgR2FzICBQcm9kdWN0aW9uIiwgeSAgPSAgImJpbGxpb25zICBvZiAgY3ViaWMgIG1ldGVyIikKYGBgCgojIyMgM2QuCQpwcm9kdWNlIGEgcGxhdXNpYmxlIHNlYXNvbmFsbHkgYWRqdXN0ZWQgc2VyaWVzPyBXaGF0IGFyZSB0aGVzZSBudW1iZXJzLCBwbG90IHRoZSBzZXJpZXMuCmBgYHtyfQoKIyAzZC5BbnN3ZXI6CmNhbmFkaWFuX2dhcyAlPiUKICBtb2RlbCgKICAgIFNUTChWb2x1bWUgfiB0cmVuZCh3aW5kb3cgPSAyMSkgKyBzZWFzb24od2luZG93ID0gMTMpLCByb2J1c3QgPSBUUlVFKQogICkgJT4lCiAgY29tcG9uZW50cygpICU+JQogIGdncGxvdChhZXMoeCA9IE1vbnRoKSkgKwogIGdlb21fbGluZShhZXMoeSA9IFZvbHVtZSwgY29sb3VyID0gIkRhdGEiKSkgKwogIGdlb21fbGluZShhZXMoeSA9IHNlYXNvbl9hZGp1c3QsIGNvbG91ciA9ICJTZWFzb25hbGx5IEFkanVzdGVkIikpICsKICBnZW9tX2xpbmUoYWVzKHkgPSB0cmVuZCwgY29sb3VyID0gIlRyZW5kIikpICsKICBsYWJzKHRpdGxlID0gIlNUTCBkZWNvbXBvc2l0aW9uIG9mIENhbmFkaWFuIEdhcyBQcm9kdWN0aW9uIikgKwogIHNjYWxlX2NvbG91cl9tYW51YWwoCiAgICB2YWx1ZXMgPSBjKCJyZWQiLCAiZ3JlZW4iLCAicHVycGxlIiksCiAgICBicmVha3MgPSBjKCJEYXRhIiwgIlNlYXNvbmFsbHkgQWRqdXN0ZWQiLCAiVHJlbmQiKQogICkKYGBgCgojIyMgNC4KRm9yIHJldGFpbCB0aW1lIHNlcmllcywgdXNlIHRoZSBiZWxvdyBjb2RlOgoKYGBge3J9CiMgcnVuIHRoZSBjb2RlCnNldC5zZWVkKDEyMzQ1Njc4KQoKbXlzZXJpZXMgPC0gYXVzX3JldGFpbCAlPiUKICBmaWx0ZXIoYFNlcmllcyBJRGAgPT0gc2FtcGxlKGF1c19yZXRhaWwkYFNlcmllcyBJRGAsMSkpCgoKYGBgCgojIyMjIDRhLiAKQ3JlYXRlIGEgdHJhaW5pbmcgZGF0YXNldCBjb25zaXN0aW5nIG9mIG9ic2VydmF0aW9ucyBiZWZvcmUgMjAxMSAKCmBgYHtyfQpteXNlcmllc190cmFpbiA8LSBteXNlcmllcyAlPiUKICBmaWx0ZXIoeWVhcihNb250aCkgPCAyMDExKQoKbXlzZXJpZXNfdHJhaW4gJT4lIHRhaWwoKQoKYGBgCgojIyMjIDRiLgkKQ2hlY2sgdGhhdCB5b3VyIGRhdGEgaGF2ZSBiZWVuIHNwbGl0IGFwcHJvcHJpYXRlbHkgYnkgcHJvZHVjaW5nIHRoZSBmb2xsb3dpbmcgcGxvdC4KCmBgYHtyfQphdXRvcGxvdChteXNlcmllcywgVHVybm92ZXIpICsKICBhdXRvbGF5ZXIobXlzZXJpZXNfdHJhaW4sIFR1cm5vdmVyLCBjb2xvdXIgPSAicmVkIikKYGBgCgojIyMjIDRjLgkKRml0IGEgc2Vhc29uYWwgbmHDr3ZlIG1vZGVsIHVzaW5nIFNOQUlWRSgpIGFwcGxpZWQgdG8geW91ciB0cmFpbmluZyBkYXRhIChteXNlcmllc190cmFpbikuCmBgYHtyfQogI0Fuc3dlcjoKICAgIGZpdCA8LSBteXNlcmllc190cmFpbiAlPiUKICAgICAgbW9kZWwoU05BSVZFKFR1cm5vdmVyKSkKYGBgCgoKIyMjIyA0ZC4KQ2hlY2sgdGhlIHJlc2lkdWFscy4KYGBge3J9CgojIDRkIEFuc3dlcjoKCmZpdCAlPiUgZ2dfdHNyZXNpZHVhbHMoKQoKIyBEbyB0aGUgcmVzaWR1YWxzIGFwcGVhciB0byBiZSB1bmNvcnJlbGF0ZWQgYW5kIG5vcm1hbGx5IGRpc3RyaWJ1dGVkPwojIEFuc3c6CgpgYGAKCiMjIyMgNGUuClByb2R1Y2UgZm9yZWNhc3RzIGZvciB0aGUgdGVzdCBkYXRhIHdpdGggZ2l2ZW4gY29kZSBiZWxvdzoKCmBgYHtyfQojIDRlIEFuc3dlcjoKZmMgPC0gZml0ICU+JSAgCmZvcmVjYXN0KG5ld19kYXRhID0gYW50aV9qb2luKG15c2VyaWVzLCBteXNlcmllc190cmFpbikpCmZjICU+JSBhdXRvcGxvdChteXNlcmllcykKCmBgYAoKSm9pbmluZywgYnkgPSBjKCJTdGF0ZSIsICJJbmR1c3RyeSIsICJTZXJpZXMgSUQiLCAiTW9udGgiLCAiVHVybm92ZXIiKQoKIyMjIyA0Zi4JCkNvbXBhcmUgdGhlIGFjY3VyYWN5IG9mIHlvdXIgZm9yZWNhc3RzIGFnYWluc3QgdGhlIGFjdHVhbCB2YWx1ZXMgd2l0aCBnaXZlbiBjb2RlIGJlbG93OgpgYGB7cn0KZml0ICU+JSBhY2N1cmFjeSgpCmZjICU+JSBhY2N1cmFjeShteXNlcmllcykKIyA0ZiBBbnN3OgpmaXQgJT4lIGFjY3VyYWN5KCkKZmMgJT4lIGFjY3VyYWN5KG15c2VyaWVzKQoKYGBgCgojIyMjIDRnLgpIb3cgc2Vuc2l0aXZlIGFyZSB0aGUgYWNjdXJhY3kgbWVhc3VyZXMgdG8gdGhlIGFtb3VudCBvZiB0cmFpbmluZyBkYXRhIHVzZWQ/CmBgYHtyfQoKIyA0ZyBBbnN3ZXI6CgpiaW5kX3Jvd3MoCiAgICAgYWNjdXJhY3koZml0KSwKICAgICBhY2N1cmFjeShmYywgbXlzZXJpZXMpCiAgICkgJT4lCiAgICAgc2VsZWN0KC1TdGF0ZSwgLUluZHVzdHJ5LCAtLm1vZGVsKQoKYGBgCgojIyMgNS4JCiMjIyMgNWEuCQpDcmVhdGUgYSB0cmFpbmluZyBzZXQgZm9yIEF1c3RyYWxpYW4gdGFrZWF3YXkgZm9vZCB0dXJub3ZlciAoYXVzX3JldGFpbCkgYnkgd2l0aGhvbGRpbmcgdGhlIGxhc3QgZm91ciB5ZWFycyBhcyBhIHRlc3Qgc2V0LiAKYGBge3J9CgoKIyA1YS5BbnN3ZXI6CnNldC5zZWVkKDIxMDApCgp0YWtlYXdheV9mb29kX3R1cm5vdmVyIDwtIAogIGF1c19yZXRhaWwgICU+JQogIGZpbHRlcihJbmR1c3RyeSA9PSJUYWtlYXdheSBmb29kIHNlcnZpY2VzIikgJT4lCiAgc3VtbWFyaXNlKFRvdGFfVHVybm92ZXIgPSBzdW0oVHVybm92ZXIpKQoKdGFrZWF3YXlfZm9vZF90dXJub3ZlciAlPiUgYXV0b3Bsb3QoVG90YV9UdXJub3ZlcikKdGFrZWF3YXlfdHJhaW5fc2V0IDwtIAogIHRha2Vhd2F5X2Zvb2RfdHVybm92ZXIgJT4lIAogIGZpbHRlcih5ZWFyKE1vbnRoKSA8IDIwMTgpICN3aXRoIGhvbGQgbGFzdCA0IHllYXJzCnRha2Vhd2F5X3RyYWluX3NldCAlPiUgYXV0b3Bsb3QoVG90YV9UdXJub3ZlcikKCmBgYAoKIyMjIyA1Yi4JCkZpdCBhbGwgdGhlIGFwcHJvcHJpYXRlIGJlbmNobWFyayBtZXRob2RzIHRvIHRoZSAgIHRyYWluaW5nIHNldCBhbmQgZm9yZWNhc3QgdGhlIHBlcmlvZHMgY292ZXJlZCBieSB0aGUgdGVzdCBzZXQuCmBgYHtyfQoKCiMgNWIuQW5zd2VyOgp0YWtlYXdheV9kY21wID0gdGFrZWF3YXlfdHJhaW5fc2V0ICU+JSAKICBtb2RlbChzdGwgPSBTVEwoVG90YV9UdXJub3ZlcikpCgpjb21wb25lbnRzKHRha2Vhd2F5X2RjbXApICU+JSBhdXRvcGxvdChzaG93LmxlZ2VuZCA9IEZBTFNFKQp0YWtlYXdheV9maXQgPC0gdGFrZWF3YXlfdHJhaW5fc2V0ICU+JQogIG1vZGVsKAogICAgTmFpdmUgPSBOQUlWRShUb3RhX1R1cm5vdmVyKSwKICAgIFNlYXNvbmFsX25haXZlID0gU05BSVZFKFRvdGFfVHVybm92ZXIpLAogICAgRHJpZnQgPSBSVyhUb3RhX1R1cm5vdmVyIH4gZHJpZnQoKSkKICApCgp0YWtlYXdheV9mYyA8LSB0YWtlYXdheV9maXQgJT4lIGZvcmVjYXN0KGggPSA0KSAKdGFrZWF3YXlfZmMgICU+JSBhdXRvcGxvdCh0YWtlYXdheV90cmFpbl9zZXQpCgpgYGAKCiMjIyMgNWMuCQpDb21wdXRlIHRoZSBhY2N1cmFjeSBvZiB5b3VyIGZvcmVjYXN0cy4gV2hpY2ggbWV0aG9kIGRvZXMgYmVzdD8KYGBge3J9CgoKIyA1Yy5BbnN3ZXI6CmFjY3VyYWN5KHRha2Vhd2F5X2ZjLCB0YWtlYXdheV9mb29kX3R1cm5vdmVyKQoKCmBgYAoKIyMjIyA1ZC4KRG8gdGhlIHJlc2lkdWFscyBmcm9tIHRoZSBiZXN0IG1ldGhvZCByZXNlbWJsZSB3aGl0ZSBub2lzZT8KYGBge3J9CgojIDVkLkFuc3dlcjoKdGFrZWF3YXlfUmVzIDwtIHRha2Vhd2F5X3RyYWluX3NldCAlPiUKICBtb2RlbCgKICAgIFNlYXNvbmFsX25haXZlID0gU05BSVZFKFRvdGFfVHVybm92ZXIpCiAgKQpnZ190c3Jlc2lkdWFscyh0YWtlYXdheV9SZXMpCgpgYGAKCiMjIyA2LgkKVXNpbmcgdGhlIGNvZGUgYmVsb3csIGdldCBhIHNlcmllcyAoaXQgZ2V0cyBhIHNlcmllcyByYW5kb21seSBieSB1c2luZyBzYW1wbGUoKSBmdW5jdGlvbik6CmBgYHtyfQpzZXQuc2VlZCgxMjM0NTY3OCkKbXlzZXJpZXMgPC0gYXVzX3JldGFpbCAlPiUKICBmaWx0ZXIoYFNlcmllcyBJRGAgPT0gc2FtcGxlKGF1c19yZXRhaWwkYFNlcmllcyBJRGAsMSkpCmBgYApzZWUgaGVhZCBvZiB5b3VyIHNlcmllcyB0byBjaGVjayBpdCBpcyBhIHRzaWJibGUgZGF0YSwgYW5kIHJlbW92ZSBOQeKAmXMgaWYgdGhlcmUgaXMgYW55IHdpdGggdGhlc2UgY29tbWFuZHM6CgpgYGB7cn0KaGVhZChteXNlcmllcykKbXlzZXJpZXMgPSAgbXlzZXJpZXMgJT4lIGZpbHRlcighaXMubmEoYFNlcmllcyBJRGApKQpgYGAKCiMjIyMgNmEuCldoYXQgaXMgdGhlIG5hbWUgb2YgdGhlIHNlcmllcyB5b3UgcmFuZG9tbHkgY2hvb3NlPyBXcml0ZSBpdC4KYGBge3J9CgojIDZhLkFuc3dlcjoKaGVhZChteXNlcmllcykKbXlzZXJpZXMgPSAgbXlzZXJpZXMgJT4lIGZpbHRlcighaXMubmEoYFNlcmllcyBJRGApKQoKYGBgCgojIyMjIDZiLiAKUnVuIGEgbGluZWFyIHJlZ3Jlc3Npb24gb2YgVHVybm92ZXIgb24gdHJlbmQuKEhpbnQ6IHVzZSBUU0xNKCkgYW5kIHRyZW5kKCkgZnVuY3Rpb25zKQpgYGB7cn0KIyA2Yi5BbnN3ZXI6CgpteXNlcmllc19Uc2xtIDwtIG15c2VyaWVzICU+JSBtb2RlbCh0cmVuZF9tb2RlbCA9IFRTTE0oVHVybm92ZXIgfiB0cmVuZCgpKSkgJT4lIHJlcG9ydCgpCgoKYGBgCgojIyMjIDZjLiAKU2VlIHRoZSByZWdyZXNzaW9uIHJlc3VsdCBieSByZXBvcnQoKSBjb21tYW5kLgpgYGB7cn0KIyA2Yy5BbnN3ZXI6CgpteXNlcmllc19Uc2xtIDwtIG15c2VyaWVzICU+JSBtb2RlbCh0cmVuZF9tb2RlbCA9IFRTTE0oVHVybm92ZXIgfiB0cmVuZCgpKSkgJT4lIHJlcG9ydCgpCgpgYGAKCgojIyMjIDZkLgkKQnkgdXNpbmcgdGhpcyBtb2RlbCwgZm9yZWNhc3QgaXQgZm9yIHRoZSBuZXh0IDMgeWVhcnMuIFdoYXQgYXJlIHRoZSB2YWx1ZXMgb2YgdGhlIG5leHQgMyB5ZWFycywgbW9udGhseSB2YWx1ZXM/CmBgYHtyfQoKIyA2ZC5BbnN3ZXI6CmZjIDwtIG15c2VyaWVzX1RzbG0gJT4lIGZvcmVjYXN0KGggPSAzKQpmYwoKYGBgCgojIyMjIDZkLgkKUGxvdCB0aGUgZm9yZWNhc3QgdmFsdWVzIGFsb25nIHdpdGggdGhlIG9yaWdpbmFsIGRhdGEuCmBgYHtyfQoKIyA2ZC5BbnN3ZXI6CgpmYyAlPiUgYXV0b3Bsb3QobXlzZXJpZXMpICsgbGFicyh0aXRsZSA9ICJBdXNfUmV0YWlsX1Bsb3QiLCB5ID0gIlR1cm5vdmVyIikKCmBgYAoKIyMjIyA2ZS4JCkdldCB0aGUgcmVzaWR1YWxzIGZyb20gdGhlIG1vZGVsLiBBbmQgY2hlY2sgdGhlIHJlc2lkdWFscyB0byBjaGVjayB3aGV0aGVyIG9yIG5vdCBpdCBzYXRpc2ZpZXMgdGhlIHJlcXVpcmVtZW50cyBmb3Igd2hpdGUgbm9pc2UgZXJyb3IgdGVybXMuKGhpbnQ6IGF1Z21lbnQoKSBhbmQgZ2dfdHNyZXNpZHVhbHMoKSBmdW5jdGlvbnMpCgpgYGB7cn0KCiMgNmUuQW5zd2VyOgphdWdtZW50KG15c2VyaWVzX1RzbG0pCmdnX3RzcmVzaWR1YWxzKG15c2VyaWVzX1RzbG0pCgoKYGBgCgoKIyMjIDcuIApIYWxmLWhvdXJseSBlbGVjdHJpY2l0eSBkZW1hbmQgZm9yIFZpY3RvcmlhLCBBdXN0cmFsaWEgaXMgY29udGFpbmVkIGluIHZpY19lbGVjLiBFeHRyYWN0IHRoZSBKYW51YXJ5IDIwMTQgZWxlY3RyaWNpdHkgZGVtYW5kLCBhbmQgYWdncmVnYXRlIHRoaXMgZGF0YSB0byBkYWlseSB3aXRoICBkYWlseSB0b3RhbCBkZW1hbmRzIGFuZCBtYXhpbXVtIHRlbXBlcmF0dXJlcy4gUnVuIHRoZSBjb2RlIGJlbG93OgoKYGBge3J9Cmphbl92aWNfZWxlYyA8LSB2aWNfZWxlYyAlPiUKICBmaWx0ZXIoeWVhcm1vbnRoKFRpbWUpID09IHllYXJtb250aCgiMjAxNCBKYW4iKSkgJT4lCiAgaW5kZXhfYnkoRGF0ZSA9IGFzX2RhdGUoVGltZSkpICU+JQogIHN1bW1hcmlzZShEZW1hbmQgPSBzdW0oRGVtYW5kKSwgVGVtcGVyYXR1cmUgPSBtYXgoVGVtcGVyYXR1cmUpKQoKYGBgCgojIyMjIDdhLiAKUGxvdCB0aGUgZGF0YSBhbmQgZmluZCB0aGUgcmVncmVzc2lvbiBtb2RlbCBmb3IgRGVtYW5kIHdpdGggdGVtcGVyYXR1cmUgYXMgYSBwcmVkaWN0b3IgdmFyaWFibGUuIFdoeSBpcyB0aGVyZSBhIHBvc2l0aXZlIHJlbGF0aW9uc2hpcD8KYGBge3J9CgojIDdhLkFuc3dlcjoKCmphbl92aWNfZWxlYyAlPiUKICBhdXRvcGxvdChEZW1hbmQpCmphbl92aWNfZWxlYyAlPiUKICBhdXRvcGxvdChUZW1wZXJhdHVyZSkKcHJlZGljdGlvbiA8LSBqYW5fdmljX2VsZWMgJT4lIAogIG1vZGVsKFRTTE0oRGVtYW5kIH4gVGVtcGVyYXR1cmUpKQoKcmVwb3J0KHByZWRpY3Rpb24pCmphbl92aWNfZWxlYyAlPiUKICBnZ3Bsb3QoYWVzKHg9VGVtcGVyYXR1cmUsIHk9RGVtYW5kKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kPSJsbSIsIHNlPUZBTFNFKSArCiAgbGFicyh0aXRsZSA9ICJFbGVjdHJpY2l0eSBEZW1hbmQiKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCgpgYGAKCiMjIyMgN2IuIApQcm9kdWNlIGEgcmVzaWR1YWwgcGxvdC4gSXMgdGhlIG1vZGVsIGFkZXF1YXRlPyBBcmUgdGhlcmUgYW55IG91dGxpZXJzIG9yIGluZmx1ZW50aWFsIG9ic2VydmF0aW9ucz8KCmBgYHtyfQoKIyA3Yi5BbnN3ZXI6CmxpYnJhcnkoZmVhc3RzKQpwcmVkaWN0aW9uICU+JQogIGdnX3RzcmVzaWR1YWxzKCkKCmBgYAoKIyMjIyA3Yy4KVXNlIHRoZSBtb2RlbCB0byBmb3JlY2FzdCB0aGUgZWxlY3RyaWNpdHkgZGVtYW5kIHRoYXQgeW91IHdvdWxkIGV4cGVjdCBmb3IgdGhlIG5leHQgZGF5IGlmIHRoZSBtYXhpbXVtIHRlbXBlcmF0dXJlIHdhcyAxNeKImEMgYW5kIGNvbXBhcmUgaXQgd2l0aCB0aGUgZm9yZWNhc3QgaWYgdGhlIHdpdGggbWF4aW11bSB0ZW1wZXJhdHVyZSB3YXMgMzXiiJhDLiBEbyB5b3UgYmVsaWV2ZSB0aGVzZSBmb3JlY2FzdHM/CgpgYGB7cn0KCmphbl92aWNfZWxlYyAlPiUKICBtb2RlbChUU0xNKERlbWFuZCB+IFRlbXBlcmF0dXJlKSkgJT4lCiAgZm9yZWNhc3QobmV3X2RhdGEoamFuX3ZpY19lbGVjLCAxKSAlPiUKICAgICAgbXV0YXRlKFRlbXBlcmF0dXJlID0gMTUpKSAlPiUKICBhdXRvcGxvdChqYW5fdmljX2VsZWMpCmphbl92aWNfZWxlYyAlPiUKICBtb2RlbChUU0xNKERlbWFuZCB+IFRlbXBlcmF0dXJlKSkgJT4lCiAgZm9yZWNhc3QobmV3X2RhdGEoamFuX3ZpY19lbGVjLCAxKSAlPiUKICAgICAgbXV0YXRlKFRlbXBlcmF0dXJlID0gMzUpKSAlPiUKICBhdXRvcGxvdChqYW5fdmljX2VsZWMpCgojIDdjLkFuc3dlcjoKYGBgCgojIyMjIDdkLgpEbyB5b3UgYmVsaWV2ZSB0aGVzZSBmb3JlY2FzdHM/IFRoZSBmb2xsb3dpbmcgUiBjb2RlIHdpbGwgZ2V0IHlvdSBzdGFydGVkOgpgYGB7cn0KICBqYW5fdmljX2VsZWMgJT4lCiAgbW9kZWwoVFNMTShEZW1hbmQgfiBUZW1wZXJhdHVyZSkpICU+JQogIGZvcmVjYXN0KAogICAgbmV3X2RhdGEoamFuX3ZpY19lbGVjLCAxKSAlPiUKICAgICAgbXV0YXRlKFRlbXBlcmF0dXJlID0gMTUpCiAgKSAlPiUKICBhdXRvcGxvdChqYW5fdmljX2VsZWMpCgogIApgYGAKICAKYGBge3J9CgojIDdkLkFuc3dlcjoKbGlicmFyeShmb3JlY2FzdCkKbmV4dF9kYXkgPC0gc2NlbmFyaW9zKAogIGBDb2xkIGRheWAgPSBuZXdfZGF0YShqYW5fdmljX2VsZWMsIDEpICU+JSBtdXRhdGUoVGVtcGVyYXR1cmUgPSAxNSksCiAgYEhvdCBkYXlgID0gbmV3X2RhdGEoamFuX3ZpY19lbGVjLCAxKSAlPiUgbXV0YXRlKFRlbXBlcmF0dXJlID0gMzUpCikKCmBgYAogCiMjIyMgN2UuIApHaXZlIHByZWRpY3Rpb24gaW50ZXJ2YWxzIGZvciB5b3VyIGZvcmVjYXN0cy4KCmBgYHtyfQoKCiMgN2UuQW5zd2VyOgpmYyA8LSBwcmVkaWN0aW9uICU+JQogIGZvcmVjYXN0KG5ld19kYXRhID0gbmV4dF9kYXkpCgojIFBsb3QgaXQKCmF1dG9wbG90KGphbl92aWNfZWxlYywgRGVtYW5kKSArIAogIGF1dG9sYXllcihmYywgc2VyaWVzID0gIkZvcmVjYXN0IiwgUEkgPSBUUlVFLCBhbHBoYSA9IDAuNSkgKyAKICBsYWJzKHRpdGxlID0gIkRlbWFuZCBGb3JlY2FzdCBmb3IgZWxlY3RyaWNpdHkiLAogICAgICAgeCA9ICJEYXRlIiwKICAgICAgIHkgPSAiRGVtYW5kIikKYGBgCgoKIyMjIDguClJlYWQgdGhlIHNoYW1wb28gZGF0YSBnaXZlbiBpbiBleGNlbCAoSW1wb3J0IERhdGFzZXQgYXMgRXhjZWwpCiAgCmBgYHtyfQojYS4JVmlldyB0aGUgc2hhbXBvbyBzYWxlcyBkYXRhLiBIb3cgbWFueSB2YXJpYWJsZXMgYXJlIHRoZXJlPyBGaW5kIGhvdyBtYW55IHJvd3MgYW5kIGNvbHVtbnMgaW4gdGhlIGRhdGE/CiAgbGlicmFyeShyZWFkeGwpCnNoYW1wb28gPC0gcmVhZF9leGNlbCgic2hhbXBvby0yLnhsc3giKQoKaGVhZChzaGFtcG9vKQpwcmludCgidGhlcmUgYXJlIDM2IHJvd3MgYW5kIDIgY29sdW1ucyIpCnN0cihzaGFtcG9vKQpwcmludCgidGhlcmUgYXJlIHR3byB2YXJpYWJsZXMgb25lIGlzIG1vbnRoIGFuZCBvbmUgaXMgc2FsZXMiKQoKCgojYi4JSXMgdGhlIGRhdGEgYW5udWFsLCBtb250aGx5LCBxdWFydGVybHk/CnByaW50KCJ0aGUgZGF0YXNldCBjb250YWlucyBtb250aGx5IGRhdGEiKQoKI2MuCUNvbnZlcnQgdGhlIGRhdGEgaW50byB0aWJibGUgLCB0aGVuIHRzaWJibGUgCnNoYW1wb28kTW9udGggPC0gYXNfZGF0ZShzaGFtcG9vJE1vbnRoKQpzaGFtcG9vX25ldzwtIGFzX3RpYmJsZShzaGFtcG9vKQpzaGFtcG9vX25ldyA8LSBzaGFtcG9vX25ldyAlPiUKICBtdXRhdGUoTW9udGhzID0geWVhcm1vbnRoKE1vbnRoKSkgJT4lCiAgc2VsZWN0KC1Nb250aCkgJT4lCiAgYXNfdHNpYmJsZSgKICAgIGluZGV4ID0gTW9udGhzLAogICAgdmFsaWRhdGUgPSBUUlVFCiAgKQojZC4JUGxvdCB0aGUgc2hhbXBvbyBzYWxlcy4gV2hhdCBkbyB5b3Ugc2VlIGZyb20gdGhlIGRhdGEgcGF0dGVybj8gV2hhdCBkb2VzIHgtYXhpcyByZXByZXNlbnQ/IAojIENvbW1lbnQgaGVyZS4gVXNlIHBsb3QoKSBhbmQgYXV0b3Bsb3QoKS5QdXQgdGhlIG5hbWUgZm9yIHkgYXhpcywgYW5kIGEgdGl0bGUgZm9yIHRoZSBncmFwaC4KcGxvdChzaGFtcG9vX25ldyRzYWxlcywgdHlwZSA9ICJsIiwKICAgICB5bGFiID0gIlNhbGVzIiwKICAgICBtYWluID0gIlNhbGVzX3llYXJzIikKICBwcmludCgiRnJvbSB0aGUgcGxvdCBncmFwaCwgSSBkb24ndCBzZWUgYW55IHBhdHRlcm4gdGhhdCBmb2xsb3dzIHRyZW5kIG9yIHNlYXNvbmFsaXR5LiIpCnNoYW1wb29fbmV3ICU+JQogIGF1dG9wbG90KHNhbGVzKSsKICBsYWJzKAogICAgeSA9ICJTYWxlcyIsCiAgICB0aXRsZSA9ICJTYWxlc195ZWFycyIKICApCnByaW50KCJGcm9tIHRoZSBhdXRvcGxvdCBncmFwaCwgSSBzZWUgdGhhdCB0aGVyZSBpcyBhIHNlYXNvbmFsaXR5IGZvbGxvd2VkLiIpCgogIAojZS4JV2hhdCBpcyB0aGUgYXZlcmFnZSwgYW5kIG1lZGlhbiBvZiBzaGFtcG9vIHNhbGVzLiBQdXQgaXQgb24gYSBoaXN0b2dyYW0uCnggPSBtZWFuKHNoYW1wb29fbmV3JHNhbGVzKQp5ID0gbWVkaWFuKHNoYW1wb29fbmV3JHNhbGVzKQpoaXN0KHNoYW1wb29fbmV3JHNhbGVzKQoKYWJsaW5lKHYgPSB4LAogICAgICAgY29sID0gImdyZWVuIiwKICAgICAgIGx3ZCA9IDMpCgphYmxpbmUodiA9IG1lZGlhbihzaGFtcG9vX25ldyRzYWxlcyksCiAgICAgICBjb2wgPSAiYmx1ZSIsCiAgICAgICBsd2QgPSAzKQoKdGV4dCh4ID0geCAqIDEuNSwKICAgICB5ID0geCAqIDEuNSwKICAgICBwYXN0ZSgiTWVhbiA9ICIsIHgpLAogICAgIGNvbCA9ICJncmVlbiIsCiAgICAgY2V4ID0gMSkKCnRleHQoeCA9IHkgKiAxLjUsCiAgICAgeSA9IHkgKiAxLjUsCiAgICAgcGFzdGUoIk1lZGlhbiA9ICIsIHkpLAogICAgIGNvbCA9ICJibHVlIiwKICAgICBjZXggPSAxKQpwcmludCgiVGhlIGF2ZXJhZ2Ugc2FsZSBvZiBzaGFtcG9vIGlzIDMxMi42IGFuZCBtZWRpYW4gb2Ygc2hhbXBvbyBzYWxlIGlzIDI4MC4xNS4iKQoKCiNmLglHZXQgc2Vhc29uYWwgcGxvdC4gV2hhdCBkbyB5b3Ugc2VlLyBpcyB0aGVyZSBhbnkgcGF0dGVybiwgaXMgdGVocmUgYW55IHNlYXNvbmFsaXR5LgpzaGFtcG9vX25ldyAlPiUKICBnZ19zZWFzb24oc2FsZXMpCnByaW50KCJ0aGVyZSBpcyBubyBzZWFzb25hbGl0eSBmcm9tIHRoZSBncmFwaC4iKQoKICAKI2cuCUdldCBhIGxpbmVhciByZWdyZXNzaW9uIGxpbmUgd2l0aCB0cmVuZCBhbmQgZHVtbXkgZm9yIGVhY2ggbW9udGggKEhpbnQ6IHVzZSB0cmVuZCBhbmQgc2Vhc29uIGluIHJlZ3Jlc3Npb24gZXF1YXRpb24pLgpzaGFtcG9vX2ZjIDwtIHNoYW1wb29fbmV3ICU+JQogIG1vZGVsKFRTTE0oc2FsZXMgfiB0cmVuZCgpICsgc2Vhc29uKCkpKQpyZXBvcnQoc2hhbXBvb19mYykKYXVnbWVudChzaGFtcG9vX2ZjKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBNb250aHMpKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gc2FsZXMsIGNvbG91ciA9ICJEYXRhIikpICsKICBnZW9tX2xpbmUoYWVzKHkgPSAuZml0dGVkLCBjb2xvdXIgPSAiRml0dGVkIikpICsKICBsYWJzKHk9IiBTYWxlcyIsdGl0bGUgPSJNb250aCBTYWxlcyIpICsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoRGF0YSA9ICJicm93biIsIEZpdHRlZCA9ICIjRDU1RTAwIikpCiNoLglDb21tZW50IG9uIGVhY2ggZXN0aW1hdGVkIGNvZWZmaWNpZW50IG9mIHRoZSBtb2RlbC5BcmUgdGhleSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGF0IDUgJSBzaWduaWZpY2FuY2UgbGV2ZWw/CnJlcG9ydChzaGFtcG9vX2ZjKQpwcmludCgiVGhlIG1vZGVsIGlzIGNvZWZmaWNpZW50IGFuZCAgaXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBhdCA1JSBsZXZlbC4iKQoKI2kuCVdoaWNoIG1vbnRoIGhhcyB0aGUgaGlnaGVzdCBzYWxlcz8KICAKc2hhbXBvb19uZXcgJT4lCiAgbXV0YXRlKG9ubHlfbW9udGhzID0gbW9udGgoTW9udGhzKSkgJT4lCiAgc2VsZWN0KC1Nb250aHMpICU+JQogIGluZGV4X2J5KG9ubHlfbW9udGhzKSAlPiUKICBzdW1tYXJpc2UoaGlnaGVzdF9zYWxlcyA9IHN1bShzYWxlcykpICU+JQogIHRvcF9uKDEpCnByaW50KCIxMXRoIG1vbnRoIGhhcyBoaWdoZXN0IHNhbGUgd2hpY2ggaXMgdG90YWwgb2YgMTE4Mi4iKQoKI2ouCUZvcmVjYXN0IGl0IGZvciB0aGUgbmV4dCB5ZWFyLiBXaGF0IGFyZSB0aGUgdmFsdWVzCmZvcmVjYXN0X3RyZW5kcyA8LSBzaGFtcG9vX2ZjICU+JQogIGZvcmVjYXN0KGggPSAxMikKZm9yZWNhc3RfdHJlbmRzCiAgCiNrLglQbG90IHRoZSBmb3JlY2FzdCB3aXRoIG9yaWdpbmFsIGRhdGEuCnNoYW1wb29fbmV3ICU+JQogIGF1dG9wbG90KHNhbGVzKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBmaXR0ZWQoc2hhbXBvb19mYyksCiAgICAgICAgICAgIGFlcyh5ID0gLmZpdHRlZCwgY29sb3VyID0gLm1vZGVsKSkgKwogIGF1dG9sYXllcihmb3JlY2FzdF90cmVuZHMsIGFscGhhID0gMC41LCBsZXZlbCA9IDk1KSArCiAgbGFicyh5ID0gIlNhbGVzIiwKICAgICAgIHRpdGxlID0gIk1vbnRobHkgU2FsZXMiKQojbC4JQ2hlY2sgaWYgdGhlIHJlc2lkdWFscyBvZiB0aGUgbW9kZWwgaXMgd2hpdGUgbm9pc2UuCiAgCnNoYW1wb29fZmMgJT4lCiAgZ2dfdHNyZXNpZHVhbHMoKQpwcmludCgiWWVzLHRoZSByZXNpZHVhbHMgb2YgdGhlIG1vZGVsIGlzIHdoaXRlICBub2lzZS4iKQoKI20uCUJ5IHVzaW5nIHRoZSByZWdyZXNzaW9uIG1vZGVsLCBmb3JlY2FzdCB0aGUgMSB5ZWFyIGFoZWFkLCBhbmQgdGhlbiBjaGVjayB0aGUgYWNjdXJhY3kgb2YgdGhlIGZvcmVjYXN0LiBXaGF0IGlzIE1TRSwgUk1TRSB2YWx1ZXM/CiAgZm9yZWNhc3RfdHJlbmRzIDwtIHNoYW1wb29fZmMgJT4lCiAgZm9yZWNhc3QoaCA9ICIxIHllYXIiKQpmb3JlY2FzdF90cmVuZHMKTVNFX2ZjMSA8LSBtZWFuKChzaGFtcG9vX25ldyRzYWxlcyAtIGZvcmVjYXN0X3RyZW5kcyQubWVhbileMikKTVNFX2ZjMQpSTVNFX2ZjMSA8LSBzcXJ0KG1lYW4oKHNoYW1wb29fbmV3JHNhbGVzIC0gZm9yZWNhc3RfdHJlbmRzJC5tZWFuKV4yKSkKUk1TRV9mYzEKcHJpbnQoIk1TRSA9IDk4MDMxLjMzCiAgICAgIFJNU0UgPSAzMTMuMDk5IikKCmBgYAogICAgCg==