Faire des prévisions de données revient à observer les valeurs
passées, déterminer une dynamique, et tenter d’estimer les évolutions
futures à partir du comportement passé de la série temporelle.
Il existe plusieurs moyens d’étudier la dynamique de la série. Tout
d’abord, on peut étudier les cycles de la série, c’est notamment ce qui
est fait pour étudier l’évolution du PIB qui est soumis à des cycles
d’affaires (business cycles) plus ou moins longs. En fonction
de l’état du cycle financier, on peut donc anticiper une hausse du PIB
dans les périodes futures si le cycle est haussier, ou inversement
anticiper une baisse du PIB si le cycle est plutôt baissier. On utilise
ce moyen notamment pour faire des prévisions de long-terme (sur quelques
années) avec des données à faible fréquence (notamment, des données
annuelles ou trimestrielles).
Une méthode plus populaire et efficace (notamment quand on a des
données de haute fréquence) est d’utiliser des modèles spécifiquement
faits pour faire de la prévision. C’est le cas des Random Walks, des ETS
(Exponential Smoothing State-Space) Models, des modèles ARIMA, ou des
modèles (beaucoup) plus compliqués comme les transformations de
Fourier.
On va étudier quelques une de ces méthodes ici.
data_schularick <- read_excel("C:/users/fkraus/Desktop/data_schularick.xlsx")
donnees_france <- data_schularick %>%
filter(country=="France")%>%
select(year, gdp)%>%
mutate(gdp_growth = (log(gdp) - lag(log(gdp)))*100 )%>%
na.omit()%>%
filter(year >= 1950 & year < 2020)
head(donnees_france)
On a retiré 2020 qui est une année exceptionnelle, avec un choc
purement exogène (donc impossible de le relier à des variations passées
du PIB).
donnees_france %>%
ggplot(aes(x=year, y=gdp_growth))+
geom_line()

df <- donnees_france %>% arrange(year)
# Yearly time series
y_ts <- ts(
df$gdp_growth,
start = min(df$year),
frequency = 1 # yearly data
)
Filters
L’un des filtres les plus connus est le filtre Hodrick-Prescott, très
utilisé dans la recherche.
HP <- hpfilter(y_ts,freq=1)
HP
Title:
Hodrick-Prescott Filter
Call:
hpfilter(x = y_ts, freq = 1)
Method:
hpfilter
Filter Type:
lambda
Series:
y_ts
HP_data <- data.frame(
year = donnees_france$year,
gdp_growth = donnees_france$gdp_growth,
trend = HP$trend[,1],
cycle = HP$cycle
)
head(HP_data)
HP_data %>% ggplot(aes(x=year, y=gdp_growth))+
geom_line()+
geom_line(aes(y=trend), color="red", lty=2)

Note : Le filtre HP n’est pas le seul et unique filtre existant.
Il existe les filtres Baxter-King, Butterworth, Christiano-Fitzgerald…
Vous pouvez regarder dans le package mFilter les différents filtres, et
les essayer.
Le filtre HP très critiqué. Notamment, Hamilton (2017) (NBER Working
Paper de “Why you should never use the Hodrick Prescott filter”) défend
l’idée que le filtre HP produit des séries biaisées, notamment au début
et à la fin des observations. Il conseille d’utiliser une autre méthode,
qui existe dans R au sein du package neverhpfilter :
require(neverhpfilter)
donnees_france$date <- as.Date(paste0(donnees_france$year, "-01-01"))
donnees_france_xts <- xts(donnees_france$gdp_growth, order.by=donnees_france$date)
not_hp <- yth_filter(donnees_france_xts, output=c("x", "cycle", "trend"))
Avis : Your xts object doesn't have a dimnames attribute, aka names(your_xts) is NULL, which would've produced an error.
Thus it has been given the name 'y' within the scope, and for the output, of this function.
plot(not_hp)

FORECASTS (ETS & ARIMA)
Prévisions in-sample
require(forecast)
fit_ets <- ets(y_ts)
fit_arima <- auto.arima(y_ts)
out-sample forecast
fitted_ets <- fitted(fit_ets)
fitted_arima <- fitted(fit_arima)
df_in_sample <- cbind(
year = as.numeric(time(y_ts)),
gdp_growth = as.numeric(y_ts),
ets_fitted = as.numeric(fitted_ets),
arima_fitted = as.numeric(fitted_arima)
)
ggplot(df_in_sample, aes(x = year)) +
geom_line(aes(y = gdp_growth), linetype = "solid") +
geom_line(aes(y = ets_fitted), linetype = "dashed", color="red") +
labs(
title = "In-sample: actual vs ETS fitted",
y = "Value"
)

ggplot(df_in_sample, aes(x = year)) +
geom_line(aes(y = gdp_growth), linetype = "solid") +
geom_line(aes(y = arima_fitted), linetype = "dashed", color="red") +
labs(
title = "In-sample: actual vs ARIMA fitted",
y = "Value"
)

n <- length(y_ts)
h <- 15
y_train <- window(y_ts, end = time(y_ts)[n - h])
# Série de test = les 15 dernières années
y_test <- window(y_ts, start = time(y_ts)[n - h + 1])
fit_ets_oos <- ets(y_train)
fit_arima_oos <- auto.arima(y_train)
fc_ets_oos <- forecast(fit_ets_oos, h = h, level = c(80, 95))
fc_arima_oos <- forecast(fit_arima_oos, h = h, level = c(80, 95))
years_test <- as.numeric(time(y_test))
ets_insample <- data.frame(
year = years_test,
gdp_growth = as.numeric(y_test),
ets_forecast = as.numeric(fc_ets_oos$mean),
ets_lower_95 = fc_ets_oos$lower[, "95%"],
ets_upper_95 = fc_ets_oos$upper[, "95%"]
)
arima_insample <- data.frame(
year = years_test,
gdp_growth = as.numeric(y_test),
arima_forecast = as.numeric(fc_arima_oos$mean),
arima_lower_95 = fc_arima_oos$lower[, "95%"],
arima_upper_95 = fc_arima_oos$upper[, "95%"]
)
ggplot(ets_insample, aes(x = year)) +
geom_line(aes(y = gdp_growth), linetype = "solid") +
geom_line(aes(y = ets_forecast), linetype = "dashed") +
geom_ribbon(aes(ymin = ets_lower_95, ymax = ets_upper_95),
alpha = 0.2) +
labs(
title = "Out-of-sample: ETS forecast vs actual",
y = "Value"
)

La prévision avec ETS n’est pas très performante. En effet, on voit
que l’évolution du PIB suite à la crise des Subprimes n’a pas pu être
prise en compte par le modèle. Dans un certain sens, ce n’est pas
“grave”, ça signifie que la crise de 2008 provient sûrement d’un choc
exogène au système économique, qui ne peut pas être compris (uniquement)
à partir des données passées. En revanche, comme de nombreux économistes
l’ont défendu, les origines des crises sont souvent endogènes.
Par exemple, Minsky défend le fait que les crises se construisent
dans les périodes de croissance économique prolongée, qui réduisent
l’aversion au risque et poussent les individus à prendre des risques,
jusqu’au “moment Minsky” où la confiance s’érode. Ainsi, un bon modèle
de prévision serait capable de prendre en compte ce risque de
retournement, avec un interval de confiance plus important.
ggplot(arima_insample, aes(x = year)) +
geom_line(aes(y = gdp_growth), linetype = "solid") +
geom_line(aes(y = arima_forecast), linetype = "dashed") +
geom_ribbon(aes(ymin = arima_lower_95, ymax = arima_upper_95),
alpha = 0.2) +
labs(
title = "Out-of-sample: ARIMA forecast vs actual",
y = "Value"
)

C’est le cas de la prévision avec Arima, qui contient l’évolution du
PIB post-subprimes dans l’interval de confiance.
On peut à présent faire les prévisions out-sample, c’est-à-dire au
delà de 2019.
h <- 5
fc_arima <- forecast(fit_arima, h = h)
plot(fc_arima)

Avec le modèle ARIMA, on peut anticiper que la croissance du PIB va
rester entre -3% et 7-8% jusqu’en 2024. Dans la réalité, la crise du
Covid-19 (imprévisible) a plutôt créé une décroissance du PIB en 2020,
et un rebond en 2021. En revanche, ces deux variations sont (plus ou
moins) compris dans l’interval de confiance du modèle.
Aujourd’hui, les prévisions servent essentiellement a -faire des
prévisions macroéconomique (PIB, inflation…) par les institutions
internationales -faire des prévisions de prix d’actifs par les
institutions financières
En revanche, ces institutions se tournent davantage vers des modèles
de Machine Learning, qui vont comprendre la dynamique de la série et
s’entraîner à mesure que les données s’actualisent.
LS0tDQp0aXRsZTogIlPDqWFuY2UgNiDDqWNvbm9tw6l0cmllIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KDQpGYWlyZSBkZXMgcHLDqXZpc2lvbnMgZGUgZG9ubsOpZXMgcmV2aWVudCDDoCBvYnNlcnZlciBsZXMgdmFsZXVycyBwYXNzw6llcywgZMOpdGVybWluZXIgdW5lIGR5bmFtaXF1ZSwgZXQgdGVudGVyIGQnZXN0aW1lciBsZXMgw6l2b2x1dGlvbnMgZnV0dXJlcyDDoCBwYXJ0aXIgZHUgY29tcG9ydGVtZW50IHBhc3PDqSBkZSBsYSBzw6lyaWUgdGVtcG9yZWxsZS4gDQoNCklsIGV4aXN0ZSBwbHVzaWV1cnMgbW95ZW5zIGQnw6l0dWRpZXIgbGEgZHluYW1pcXVlIGRlIGxhIHPDqXJpZS4gVG91dCBkJ2Fib3JkLCBvbiBwZXV0IMOpdHVkaWVyIGxlcyBjeWNsZXMgZGUgbGEgc8OpcmllLCBjJ2VzdCBub3RhbW1lbnQgY2UgcXVpIGVzdCBmYWl0IHBvdXIgw6l0dWRpZXIgbCfDqXZvbHV0aW9uIGR1IFBJQiBxdWkgZXN0IHNvdW1pcyDDoCBkZXMgY3ljbGVzIGQnYWZmYWlyZXMgKCpidXNpbmVzcyBjeWNsZXMqKSBwbHVzIG91IG1vaW5zIGxvbmdzLiBFbiBmb25jdGlvbiBkZSBsJ8OpdGF0IGR1IGN5Y2xlIGZpbmFuY2llciwgb24gcGV1dCBkb25jIGFudGljaXBlciB1bmUgaGF1c3NlIGR1IFBJQiBkYW5zIGxlcyBww6lyaW9kZXMgZnV0dXJlcyBzaSBsZSBjeWNsZSBlc3QgaGF1c3NpZXIsIG91IGludmVyc2VtZW50IGFudGljaXBlciB1bmUgYmFpc3NlIGR1IFBJQiBzaSBsZSBjeWNsZSBlc3QgcGx1dMO0dCBiYWlzc2llci4gT24gdXRpbGlzZSBjZSBtb3llbiBub3RhbW1lbnQgcG91ciBmYWlyZSBkZXMgcHLDqXZpc2lvbnMgZGUgbG9uZy10ZXJtZSAoc3VyIHF1ZWxxdWVzIGFubsOpZXMpIGF2ZWMgZGVzIGRvbm7DqWVzIMOgIGZhaWJsZSBmcsOpcXVlbmNlIChub3RhbW1lbnQsIGRlcyBkb25uw6llcyBhbm51ZWxsZXMgb3UgdHJpbWVzdHJpZWxsZXMpLg0KDQpVbmUgbcOpdGhvZGUgcGx1cyBwb3B1bGFpcmUgZXQgZWZmaWNhY2UgKG5vdGFtbWVudCBxdWFuZCBvbiBhIGRlcyBkb25uw6llcyBkZSBoYXV0ZSBmcsOpcXVlbmNlKSBlc3QgZCd1dGlsaXNlciBkZXMgbW9kw6hsZXMgc3DDqWNpZmlxdWVtZW50IGZhaXRzIHBvdXIgZmFpcmUgZGUgbGEgcHLDqXZpc2lvbi4gQydlc3QgbGUgY2FzIGRlcyBSYW5kb20gV2Fsa3MsIGRlcyBFVFMgKEV4cG9uZW50aWFsIFNtb290aGluZyBTdGF0ZS1TcGFjZSkgTW9kZWxzLCBkZXMgbW9kw6hsZXMgQVJJTUEsIG91IGRlcyBtb2TDqGxlcyAoYmVhdWNvdXApIHBsdXMgY29tcGxpcXXDqXMgY29tbWUgbGVzIHRyYW5zZm9ybWF0aW9ucyBkZSBGb3VyaWVyLg0KDQpPbiB2YSDDqXR1ZGllciBxdWVscXVlcyB1bmUgZGUgY2VzIG3DqXRob2RlcyBpY2kuDQoNCmBgYHtyfQ0KZGF0YV9zY2h1bGFyaWNrIDwtIHJlYWRfZXhjZWwoIkM6L3VzZXJzL2ZrcmF1cy9EZXNrdG9wL2RhdGFfc2NodWxhcmljay54bHN4IikNCmRvbm5lZXNfZnJhbmNlIDwtIGRhdGFfc2NodWxhcmljayAlPiUNCiAgZmlsdGVyKGNvdW50cnk9PSJGcmFuY2UiKSU+JQ0KICBzZWxlY3QoeWVhciwgZ2RwKSU+JQ0KICBtdXRhdGUoZ2RwX2dyb3d0aCA9IChsb2coZ2RwKSAtIGxhZyhsb2coZ2RwKSkpKjEwMCAgICklPiUNCiAgbmEub21pdCgpJT4lDQogIGZpbHRlcih5ZWFyID49IDE5NTAgJiB5ZWFyIDwgMjAyMCkNCmhlYWQoZG9ubmVlc19mcmFuY2UpDQpgYGANCk9uIGEgcmV0aXLDqSAyMDIwIHF1aSBlc3QgdW5lIGFubsOpZSBleGNlcHRpb25uZWxsZSwgYXZlYyB1biBjaG9jIHB1cmVtZW50IGV4b2fDqG5lIChkb25jIGltcG9zc2libGUgZGUgbGUgcmVsaWVyIMOgIGRlcyB2YXJpYXRpb25zIHBhc3PDqWVzIGR1IFBJQikuDQoNCg0KYGBge3J9DQpkb25uZWVzX2ZyYW5jZSAlPiUNCiAgZ2dwbG90KGFlcyh4PXllYXIsIHk9Z2RwX2dyb3d0aCkpKw0KICBnZW9tX2xpbmUoKQ0KYGBgDQoNCmBgYHtyfQ0KZGYgPC0gZG9ubmVlc19mcmFuY2UgJT4lIGFycmFuZ2UoeWVhcikNCg0KIyBZZWFybHkgdGltZSBzZXJpZXMNCnlfdHMgPC0gdHMoDQogIGRmJGdkcF9ncm93dGgsDQogIHN0YXJ0ICAgICA9IG1pbihkZiR5ZWFyKSwNCiAgZnJlcXVlbmN5ID0gMSAgICAgICAgIyB5ZWFybHkgZGF0YQ0KKQ0KYGBgDQoNCg0KIyBGaWx0ZXJzDQoNCkwndW4gZGVzIGZpbHRyZXMgbGVzIHBsdXMgY29ubnVzIGVzdCBsZSBmaWx0cmUgSG9kcmljay1QcmVzY290dCwgdHLDqHMgdXRpbGlzw6kgZGFucyBsYSByZWNoZXJjaGUuDQoNCmBgYHtyfQ0KSFAgPC0gaHBmaWx0ZXIoeV90cyxmcmVxPTEpDQoNCkhQDQpgYGANCmBgYHtyfQ0KSFBfZGF0YSA8LSBkYXRhLmZyYW1lKA0KICB5ZWFyID0gZG9ubmVlc19mcmFuY2UkeWVhciwgDQogIGdkcF9ncm93dGggPSBkb25uZWVzX2ZyYW5jZSRnZHBfZ3Jvd3RoLA0KICB0cmVuZCA9IEhQJHRyZW5kWywxXSwgDQogIGN5Y2xlID0gSFAkY3ljbGUNCiAgKQ0KDQpoZWFkKEhQX2RhdGEpDQpgYGANCg0KDQoNCmBgYHtyfQ0KSFBfZGF0YSAlPiUgZ2dwbG90KGFlcyh4PXllYXIsIHk9Z2RwX2dyb3d0aCkpKw0KICBnZW9tX2xpbmUoKSsNCiAgZ2VvbV9saW5lKGFlcyh5PXRyZW5kKSwgY29sb3I9InJlZCIsIGx0eT0yKQ0KYGBgDQoqTm90ZSA6IExlIGZpbHRyZSBIUCBuJ2VzdCBwYXMgbGUgc2V1bCBldCB1bmlxdWUgZmlsdHJlIGV4aXN0YW50LiBJbCBleGlzdGUgbGVzIGZpbHRyZXMgQmF4dGVyLUtpbmcsIEJ1dHRlcndvcnRoLCBDaHJpc3RpYW5vLUZpdHpnZXJhbGQuLi4gVm91cyBwb3V2ZXogcmVnYXJkZXIgZGFucyBsZSBwYWNrYWdlIG1GaWx0ZXIgbGVzIGRpZmbDqXJlbnRzIGZpbHRyZXMsIGV0IGxlcyBlc3NheWVyLiAqDQoNCkxlIGZpbHRyZSBIUCB0csOocyBjcml0aXF1w6kuIE5vdGFtbWVudCwgSGFtaWx0b24gKDIwMTcpIChOQkVSIFdvcmtpbmcgUGFwZXIgZGUgICJXaHkgeW91IHNob3VsZCBuZXZlciB1c2UgdGhlIEhvZHJpY2sgUHJlc2NvdHQgZmlsdGVyIikgZMOpZmVuZCBsJ2lkw6llIHF1ZSBsZSBmaWx0cmUgSFAgcHJvZHVpdCBkZXMgc8OpcmllcyBiaWFpc8OpZXMsIG5vdGFtbWVudCBhdSBkw6lidXQgZXQgw6AgbGEgZmluIGRlcyBvYnNlcnZhdGlvbnMuIElsIGNvbnNlaWxsZSBkJ3V0aWxpc2VyIHVuZSBhdXRyZSBtw6l0aG9kZSwgcXVpIGV4aXN0ZSBkYW5zIFIgYXUgc2VpbiBkdSBwYWNrYWdlIGBuZXZlcmhwZmlsdGVyYCA6DQoNCmBgYHtyfQ0KcmVxdWlyZShuZXZlcmhwZmlsdGVyKQ0KZG9ubmVlc19mcmFuY2UkZGF0ZSA8LSBhcy5EYXRlKHBhc3RlMChkb25uZWVzX2ZyYW5jZSR5ZWFyLCAiLTAxLTAxIikpDQoNCg0KDQpkb25uZWVzX2ZyYW5jZV94dHMgPC0geHRzKGRvbm5lZXNfZnJhbmNlJGdkcF9ncm93dGgsIG9yZGVyLmJ5PWRvbm5lZXNfZnJhbmNlJGRhdGUpDQogIA0Kbm90X2hwIDwtIHl0aF9maWx0ZXIoZG9ubmVlc19mcmFuY2VfeHRzLCBvdXRwdXQ9YygieCIsICJjeWNsZSIsICJ0cmVuZCIpKSANCg0KcGxvdChub3RfaHApDQoNCmBgYA0KDQogDQogDQogDQojIEZPUkVDQVNUUyAoRVRTICYgQVJJTUEpDQoNCiMgUHLDqXZpc2lvbnMgaW4tc2FtcGxlDQoNCmBgYHtyfQ0KcmVxdWlyZShmb3JlY2FzdCkNCg0KDQpmaXRfZXRzICA8LSBldHMoeV90cykNCg0KZml0X2FyaW1hIDwtIGF1dG8uYXJpbWEoeV90cykNCmBgYA0KDQojIG91dC1zYW1wbGUgZm9yZWNhc3QNCg0KYGBge3J9DQpmaXR0ZWRfZXRzICAgPC0gZml0dGVkKGZpdF9ldHMpDQpmaXR0ZWRfYXJpbWEgPC0gZml0dGVkKGZpdF9hcmltYSkNCmBgYA0KDQoNCmBgYHtyfQ0KZGZfaW5fc2FtcGxlIDwtIGNiaW5kKA0KICB5ZWFyICAgICAgICAgPSBhcy5udW1lcmljKHRpbWUoeV90cykpLA0KICBnZHBfZ3Jvd3RoICAgICAgID0gYXMubnVtZXJpYyh5X3RzKSwNCiAgZXRzX2ZpdHRlZCAgID0gYXMubnVtZXJpYyhmaXR0ZWRfZXRzKSwNCiAgYXJpbWFfZml0dGVkID0gYXMubnVtZXJpYyhmaXR0ZWRfYXJpbWEpDQopDQpgYGANCg0KYGBge3J9DQpnZ3Bsb3QoZGZfaW5fc2FtcGxlLCBhZXMoeCA9IHllYXIpKSArDQogIGdlb21fbGluZShhZXMoeSA9IGdkcF9ncm93dGgpLCBsaW5ldHlwZSA9ICJzb2xpZCIpICsNCiAgZ2VvbV9saW5lKGFlcyh5ID0gZXRzX2ZpdHRlZCksIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yPSJyZWQiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiSW4tc2FtcGxlOiBhY3R1YWwgdnMgRVRTIGZpdHRlZCIsDQogICAgeSA9ICJWYWx1ZSINCiAgKQ0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KGRmX2luX3NhbXBsZSwgYWVzKHggPSB5ZWFyKSkgKw0KICBnZW9tX2xpbmUoYWVzKHkgPSBnZHBfZ3Jvd3RoKSwgbGluZXR5cGUgPSAic29saWQiKSArDQogIGdlb21fbGluZShhZXMoeSA9IGFyaW1hX2ZpdHRlZCksIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yPSJyZWQiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiSW4tc2FtcGxlOiBhY3R1YWwgdnMgQVJJTUEgZml0dGVkIiwNCiAgICB5ID0gIlZhbHVlIg0KICApDQpgYGANCg0KDQpgYGB7cn0NCm4gPC0gbGVuZ3RoKHlfdHMpDQpoIDwtIDE1DQoNCnlfdHJhaW4gPC0gd2luZG93KHlfdHMsIGVuZCA9IHRpbWUoeV90cylbbiAtIGhdKQ0KDQojIFPDqXJpZSBkZSB0ZXN0ID0gbGVzIDE1IGRlcm5pw6hyZXMgYW5uw6llcw0KeV90ZXN0ICA8LSB3aW5kb3coeV90cywgc3RhcnQgPSB0aW1lKHlfdHMpW24gLSBoICsgMV0pDQoNCmZpdF9ldHNfb29zICAgPC0gZXRzKHlfdHJhaW4pDQpmaXRfYXJpbWFfb29zIDwtIGF1dG8uYXJpbWEoeV90cmFpbikNCg0KZmNfZXRzX29vcyAgIDwtIGZvcmVjYXN0KGZpdF9ldHNfb29zLCAgIGggPSBoLCBsZXZlbCA9IGMoODAsIDk1KSkNCmZjX2FyaW1hX29vcyA8LSBmb3JlY2FzdChmaXRfYXJpbWFfb29zLCBoID0gaCwgbGV2ZWwgPSBjKDgwLCA5NSkpDQoNCmBgYA0KDQoNCg0KYGBge3J9DQp5ZWFyc190ZXN0IDwtIGFzLm51bWVyaWModGltZSh5X3Rlc3QpKQ0KDQpldHNfaW5zYW1wbGUgPC0gZGF0YS5mcmFtZSgNCiAgeWVhciAgICAgICAgID0geWVhcnNfdGVzdCwNCiAgZ2RwX2dyb3d0aCAgICAgICA9IGFzLm51bWVyaWMoeV90ZXN0KSwNCiAgZXRzX2ZvcmVjYXN0ID0gYXMubnVtZXJpYyhmY19ldHNfb29zJG1lYW4pLA0KICBldHNfbG93ZXJfOTUgICA9IGZjX2V0c19vb3MkbG93ZXJbLCAiOTUlIl0sDQogIGV0c191cHBlcl85NSAgID0gZmNfZXRzX29vcyR1cHBlclssICI5NSUiXQ0KKQ0KDQphcmltYV9pbnNhbXBsZSA8LSBkYXRhLmZyYW1lKA0KICB5ZWFyICAgICAgICAgPSB5ZWFyc190ZXN0LA0KICBnZHBfZ3Jvd3RoICAgICAgID0gYXMubnVtZXJpYyh5X3Rlc3QpLA0KICBhcmltYV9mb3JlY2FzdCA9IGFzLm51bWVyaWMoZmNfYXJpbWFfb29zJG1lYW4pLA0KICBhcmltYV9sb3dlcl85NSA9IGZjX2FyaW1hX29vcyRsb3dlclssICI5NSUiXSwNCiAgYXJpbWFfdXBwZXJfOTUgPSBmY19hcmltYV9vb3MkdXBwZXJbLCAiOTUlIl0NCikNCg0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KGV0c19pbnNhbXBsZSwgYWVzKHggPSB5ZWFyKSkgKw0KICBnZW9tX2xpbmUoYWVzKHkgPSBnZHBfZ3Jvd3RoKSwgbGluZXR5cGUgPSAic29saWQiKSArDQogIGdlb21fbGluZShhZXMoeSA9IGV0c19mb3JlY2FzdCksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgZ2VvbV9yaWJib24oYWVzKHltaW4gPSBldHNfbG93ZXJfOTUsIHltYXggPSBldHNfdXBwZXJfOTUpLA0KICAgICAgICAgICAgICBhbHBoYSA9IDAuMikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIk91dC1vZi1zYW1wbGU6IEVUUyBmb3JlY2FzdCB2cyBhY3R1YWwiLA0KICAgIHkgPSAiVmFsdWUiDQogICkNCmBgYA0KTGEgcHLDqXZpc2lvbiBhdmVjIEVUUyBuJ2VzdCBwYXMgdHLDqHMgcGVyZm9ybWFudGUuIEVuIGVmZmV0LCBvbiB2b2l0IHF1ZSBsJ8Opdm9sdXRpb24gZHUgUElCIHN1aXRlIMOgIGxhIGNyaXNlIGRlcyBTdWJwcmltZXMgbidhIHBhcyBwdSDDqnRyZSBwcmlzZSBlbiBjb21wdGUgcGFyIGxlIG1vZMOobGUuIERhbnMgdW4gY2VydGFpbiBzZW5zLCBjZSBuJ2VzdCBwYXMgImdyYXZlIiwgw6dhIHNpZ25pZmllIHF1ZSBsYSBjcmlzZSBkZSAyMDA4IHByb3ZpZW50IHPDu3JlbWVudCBkJ3VuIGNob2MgZXhvZ8OobmUgYXUgc3lzdMOobWUgw6ljb25vbWlxdWUsIHF1aSBuZSBwZXV0IHBhcyDDqnRyZSBjb21wcmlzICh1bmlxdWVtZW50KSDDoCBwYXJ0aXIgZGVzIGRvbm7DqWVzIHBhc3PDqWVzLiBFbiByZXZhbmNoZSwgY29tbWUgZGUgbm9tYnJldXggw6ljb25vbWlzdGVzIGwnb250IGTDqWZlbmR1LCBsZXMgb3JpZ2luZXMgZGVzIGNyaXNlcyBzb250IHNvdXZlbnQgZW5kb2fDqG5lcy4gDQoNClBhciBleGVtcGxlLCBNaW5za3kgZMOpZmVuZCBsZSBmYWl0IHF1ZSBsZXMgY3Jpc2VzIHNlIGNvbnN0cnVpc2VudCBkYW5zIGxlcyBww6lyaW9kZXMgZGUgY3JvaXNzYW5jZSDDqWNvbm9taXF1ZSBwcm9sb25nw6llLCBxdWkgcsOpZHVpc2VudCBsJ2F2ZXJzaW9uIGF1IHJpc3F1ZSBldCBwb3Vzc2VudCBsZXMgaW5kaXZpZHVzIMOgIHByZW5kcmUgZGVzIHJpc3F1ZXMsIGp1c3F1J2F1ICJtb21lbnQgTWluc2t5IiBvw7kgbGEgY29uZmlhbmNlIHMnw6lyb2RlLiBBaW5zaSwgdW4gYm9uIG1vZMOobGUgZGUgcHLDqXZpc2lvbiBzZXJhaXQgY2FwYWJsZSBkZSBwcmVuZHJlIGVuIGNvbXB0ZSBjZSByaXNxdWUgZGUgcmV0b3VybmVtZW50LCBhdmVjIHVuIGludGVydmFsIGRlIGNvbmZpYW5jZSBwbHVzIGltcG9ydGFudC4NCg0KDQpgYGB7cn0NCmdncGxvdChhcmltYV9pbnNhbXBsZSwgYWVzKHggPSB5ZWFyKSkgKw0KICBnZW9tX2xpbmUoYWVzKHkgPSBnZHBfZ3Jvd3RoKSwgbGluZXR5cGUgPSAic29saWQiKSArDQogIGdlb21fbGluZShhZXMoeSA9IGFyaW1hX2ZvcmVjYXN0KSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBnZW9tX3JpYmJvbihhZXMoeW1pbiA9IGFyaW1hX2xvd2VyXzk1LCB5bWF4ID0gYXJpbWFfdXBwZXJfOTUpLA0KICAgICAgICAgICAgICBhbHBoYSA9IDAuMikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIk91dC1vZi1zYW1wbGU6IEFSSU1BIGZvcmVjYXN0IHZzIGFjdHVhbCIsDQogICAgeSA9ICJWYWx1ZSINCiAgKQ0KYGBgDQoNCkMnZXN0IGxlIGNhcyBkZSBsYSBwcsOpdmlzaW9uIGF2ZWMgQXJpbWEsIHF1aSBjb250aWVudCBsJ8Opdm9sdXRpb24gZHUgUElCIHBvc3Qtc3VicHJpbWVzIGRhbnMgbCdpbnRlcnZhbCBkZSBjb25maWFuY2UuIA0KDQpPbiBwZXV0IMOgIHByw6lzZW50IGZhaXJlIGxlcyBwcsOpdmlzaW9ucyBvdXQtc2FtcGxlLCBjJ2VzdC3DoC1kaXJlIGF1IGRlbMOgIGRlIDIwMTkuDQoNCmBgYHtyfQ0KaCA8LSA1DQpmY19hcmltYSAgPC0gZm9yZWNhc3QoZml0X2FyaW1hLCBoID0gaCkNCmBgYA0KDQoNCg0KYGBge3J9DQpwbG90KGZjX2FyaW1hKQ0KYGBgDQpBdmVjIGxlIG1vZMOobGUgQVJJTUEsIG9uIHBldXQgYW50aWNpcGVyIHF1ZSBsYSBjcm9pc3NhbmNlIGR1IFBJQiB2YSByZXN0ZXIgZW50cmUgLTMlIGV0IDctOCUganVzcXUnZW4gMjAyNC4gRGFucyBsYSByw6lhbGl0w6ksIGxhIGNyaXNlIGR1IENvdmlkLTE5IChpbXByw6l2aXNpYmxlKSBhIHBsdXTDtHQgY3LDqcOpIHVuZSBkw6ljcm9pc3NhbmNlIGR1IFBJQiBlbiAyMDIwLCBldCB1biByZWJvbmQgZW4gMjAyMS4gRW4gcmV2YW5jaGUsIGNlcyBkZXV4IHZhcmlhdGlvbnMgc29udCAocGx1cyBvdSBtb2lucykgY29tcHJpcyBkYW5zIGwnaW50ZXJ2YWwgZGUgY29uZmlhbmNlIGR1IG1vZMOobGUuDQoNCkF1am91cmQnaHVpLCBsZXMgcHLDqXZpc2lvbnMgc2VydmVudCBlc3NlbnRpZWxsZW1lbnQgYSANCiAgLWZhaXJlIGRlcyBwcsOpdmlzaW9ucyBtYWNyb8OpY29ub21pcXVlIChQSUIsIGluZmxhdGlvbi4uLikgcGFyIGxlcyBpbnN0aXR1dGlvbnMgaW50ZXJuYXRpb25hbGVzDQogIC1mYWlyZSBkZXMgcHLDqXZpc2lvbnMgZGUgcHJpeCBkJ2FjdGlmcyBwYXIgbGVzIGluc3RpdHV0aW9ucyBmaW5hbmNpw6hyZXMNCiAgDQpFbiByZXZhbmNoZSwgY2VzIGluc3RpdHV0aW9ucyBzZSB0b3VybmVudCBkYXZhbnRhZ2UgdmVycyBkZXMgbW9kw6hsZXMgZGUgTWFjaGluZSBMZWFybmluZywgcXVpIHZvbnQgY29tcHJlbmRyZSBsYSBkeW5hbWlxdWUgZGUgbGEgc8OpcmllIGV0IHMnZW50cmHDrm5lciDDoCBtZXN1cmUgcXVlIGxlcyBkb25uw6llcyBzJ2FjdHVhbGlzZW50LiANCg0KDQoNCg0KDQo=