1. Introdução: Correlação vs. Causalidade
Em análise de dados, frequentemente observamos que duas variáveis se
movem juntas. A isso chamamos correlação. Por exemplo,
as vendas de sorvete e o número de afogamentos em uma cidade são
positivamente correlacionados. No entanto, seria um erro concluir que o
consumo de sorvete causa afogamentos. A verdadeira causa, a
variável oculta, é o calor: dias mais quentes levam a
um aumento em ambas as atividades.
A econometria busca ir além da correlação, tentando estabelecer e
quantificar relações de causalidade com base na teoria
econômica. A ferramenta mais básica e fundamental para isso é a
regressão linear.
Hoje, vamos usar a regressão para testar uma das mais famosas
hipóteses da macroeconomia: a Função Consumo
Keynesiana, que postula que o consumo de uma sociedade é uma
função positiva de sua renda.
2. O Modelo de Regressão Linear Simples
O modelo matemático que descreve uma relação linear entre uma
variável dependente (\(Y\)) e uma
variável independente (\(X\)) é:
\[
Y_i = \beta_0 + \beta_1 X_i + u_i
\]
Onde:
\(Y_i\): é a variável dependente
(o que queremos explicar, ex: Consumo).
\(X_i\): é a variável
independente ou explicativa (o que usamos para explicar, ex:
Renda).
\(\beta_0\): é o intercepto (o
valor de \(Y\) quando \(X=0\)).
\(\beta_1\): é o coeficiente
angular (mede a variação em \(Y\) para
uma variação unitária em \(X\)). Este
é, frequentemente, o nosso principal parâmetro de interesse.
\(u_i\): é o termo de erro
estocástico. Ele captura todos os outros fatores que afetam \(Y\) e que não estão incluídos no
modelo.
O índice \(i\) representa cada
observação (ex: cada mês, cada ano, cada país).
Nosso objetivo é obter estimativas para os parâmetros desconhecidos
\(\beta_0\) e \(\beta_1\) usando os dados que temos de
\(Y\) e \(X\).
3. Estimação por Mínimos Quadrados Ordinários (MQO)
Como encontramos a “melhor” linha que se ajusta aos nossos dados? O
método de MQO (em inglês, OLS - Ordinary Least Squares) define a
“melhor” linha como aquela que minimiza a soma dos quadrados dos
resíduos.
O resíduo (\(\hat{u}_i\)) é a
diferença entre o valor observado de \(Y_i\) e o valor predito pelo modelo, \(\hat{Y}_i\):
\[
\hat{u}_i = Y_i - \hat{Y}_i = Y_i - (\hat{\beta}_0 + \hat{\beta}_1 X_i)
\]
O MQO busca minimizar a Soma dos Quadrados dos Resíduos (SQR):
\[
SQR = \sum_{i=1}^{n} \hat{u}_i^2 = \sum_{i=1}^{n} (Y_i - \hat{\beta}_0 -
\hat{\beta}_1 X_i)^2
\]
Para encontrar os valores de \(\hat{\beta}_0\) e \(\hat{\beta}_1\) que minimizam essa
expressão, usamos cálculo, derivando a SQR em relação a cada parâmetro e
igualando a zero.
Derivando em relação a \(\hat{\beta}_0\): \[
\frac{\partial SQR}{\partial \hat{\beta}_0} = -2 \sum_{i=1}^{n} (Y_i -
\hat{\beta}_0 - \hat{\beta}_1 X_i) = 0
\]
Derivando em relação a \(\hat{\beta}_1\): \[
\frac{\partial SQR}{\partial \hat{\beta}_1} = -2 \sum_{i=1}^{n} X_i(Y_i
- \hat{\beta}_0 - \hat{\beta}_1 X_i) = 0
\]
Resolvendo este sistema de duas equações (conhecidas como equações
normais), chegamos às fórmulas dos estimadores de MQO:
\[
\hat{\beta}_1 = \frac{\sum_{i=1}^{n} (X_i - \bar{X})(Y_i -
\bar{Y})}{\sum_{i=1}^{n} (X_i - \bar{X})^2} = \frac{Cov(X, Y)}{Var(X)}
\]
\[
\hat{\beta}_0 = \bar{Y} - \hat{\beta}_1 \bar{X}
\]
Onde \(\bar{Y}\) e \(\bar{X}\) são as médias amostrais de \(Y\) e \(X\), respectivamente.
4. Aplicação Prática em R
Vamos agora aplicar esses conceitos para analisar a relação entre o
Consumo Pessoal Real (PCEC
) e a
Renda Pessoal Disponível Real (DSPIC96
)
nos Estados Unidos.
4.1. Preparação do Ambiente
Primeiro, instalamos e carregamos os pacotes necessários.
# Instalar pacotes (se necessário)
# install.packages("tidyverse")
# install.packages("plotly")
# install.packages("scales")
# install.packages("fredr")
# install.packages("stargazer")
# Carregar os pacotes
library(tidyverse)
library(plotly)
library(scales)
library(fredr)
library(stargazer)
4.2. Obtenção dos Dados
Usaremos o pacote fredr
para baixar os dados diretamente
do banco de dados do Federal Reserve de St. Louis (FRED). É necessário
configurar uma chave de API (gratuita) do FRED.
# Configure sua chave da API do FRED
fredr_set_key("26ab7fb885e4b3bc387f255728b0a8af")
# 1. Obter os dados de Consumo (PCEC)
dados_consumo <- fredr(
series_id = "PCEC",
observation_start = as.Date("1990-01-01")
)
# 2. Obter os dados de Renda (DSPIC96)
dados_renda <- fredr(
series_id = "DSPIC96",
observation_start = as.Date("1990-01-01")
)
# 3. Juntar os dois dataframes pela data
dados <-
# Seleciona e renomeia a coluna 'value' do df de consumo
select(dados_consumo, date, consumption = value) %>%
# Junta com o df de renda, selecionando e renomeando a coluna 'value'
inner_join(
select(dados_renda, date, income = value),
by = "date"
) %>%
# Garante que não há linhas com dados faltantes
na.omit()
head(dados)
## # A tibble: 6 × 3
## date consumption income
## <date> <dbl> <dbl>
## 1 1990-01-01 3738. 7187.
## 2 1990-04-01 3783. 7253.
## 3 1990-07-01 3847. 7284.
## 4 1990-10-01 3868. 7179.
## 5 1991-01-01 3874. 7206.
## 6 1991-04-01 3927. 7258
4.3. Análise Visual
Antes de estimar o modelo, é fundamental visualizar a relação entre
as variáveis.
# Tooltip amigável (pt-BR) com quebras de linha em HTML
dados_plot <- dados %>%
mutate(
tooltip = paste0(
"Data: ", format(date, "%b/%Y"),
"<br>Renda disp.: ", number(income, accuracy = 0.1, big.mark = ".", decimal.mark = ","), " bi USD",
"<br>Consumo: ", number(consumption, accuracy = 0.1, big.mark = ".", decimal.mark = ","), " bi USD"
)
)
p <- ggplot(dados_plot, aes(x = income, y = consumption)) +
geom_point(aes(text = tooltip), alpha = 0.5, color = "#02023C") +
geom_smooth(method = "lm", se = FALSE, col = "#FEB712") +
labs(
title = "Relação entre Consumo e Renda Disponível nos EUA",
subtitle = "Dados mensais desde 1990",
x = "Renda Pessoal Disponível Real (Bilhões de USD)",
y = "Consumo Pessoal Real (Bilhões de USD)",
caption = "Fonte: FRED"
) +
theme_minimal()
# Converte para plotly usando apenas o 'text' do geom_point no tooltip
ggplotly(p, tooltip = "text")
O gráfico de dispersão mostra uma correlação positiva e forte par
valores menores, quase perfeitamente linear, como esperado pela teoria
Keynesiana. Entretanto, para valores maiores há um descolamento da linha
de fit, o que poderá representar problemas para o modelo
4.4. Estimação do Modelo
Agora, vamos estimar o modelo de regressão linear simples usando a
função lm()
(linear model).
modelo_simples <- lm(consumption ~ income, data = dados)
4.5. Análise dos Resultados
Podemos ver os resultados detalhados com a função
summary()
.
##
## Call:
## lm(formula = consumption ~ income, data = dados)
##
## Residuals:
## Min 1Q Median 3Q Max
## -5196.4 -386.5 -227.1 400.1 2623.0
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -6.786e+03 3.200e+02 -21.21 <2e-16 ***
## income 1.395e+00 2.582e-02 54.03 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 966.1 on 140 degrees of freedom
## Multiple R-squared: 0.9542, Adjusted R-squared: 0.9539
## F-statistic: 2920 on 1 and 140 DF, p-value: < 2.2e-16
Para uma visualização mais limpa e profissional, usamos o pacote
stargazer
.
stargazer(modelo_simples, type = "text",
title = "Resultados da Regressão: Função Consumo",
dep.var.labels = "Consumo Pessoal",
covariate.labels = c("Renda Disponível", "Intercepto"),
align = TRUE)
##
## Resultados da Regressão: Função Consumo
## ===============================================
## Dependent variable:
## ---------------------------
## Consumo Pessoal
## -----------------------------------------------
## Renda Disponível 1.395***
## (0.026)
##
## Intercepto -6,785.883***
## (319.974)
##
## -----------------------------------------------
## Observations 142
## R2 0.954
## Adjusted R2 0.954
## Residual Std. Error 966.128 (df = 140)
## F Statistic 2,919.548*** (df = 1; 140)
## ===============================================
## Note: *p<0.1; **p<0.05; ***p<0.01
Interpretando os Resultados:
- Coeficientes (
Estimate
):
- Intercepto (\(\hat{\beta}_0\)):
-6,785.883
.
Este é o nível de consumo autônomo, ou seja, o consumo que existiria
mesmo com renda zero. Economicamente, pode ser interpretado como o
consumo financiado por poupança ou crédito.
- income (\(\hat{\beta}_1\)):
1.395
. Este
é o coeficiente mais importante. Ele representa a Propensão
Marginal a Consumir (PMgC). A interpretação é: para cada
aumento de $1 bilhão na renda disponível real, espera-se que o consumo
real aumente em aproximadamente $1.395 bilhões, ceteris
paribus.
- P-valor (
Pr(>|t|)
):
- O p-valor para o coeficiente
income
é extremamente
baixo (< 2e-16
, que é essencialmente zero). Isso testa a
hipótese nula de que \(\beta_1 = 0\).
Como o p-valor é menor que qualquer nível de significância convencional
(1%, 5%, 10%), nós rejeitamos a hipótese nula. Isso
significa que há evidência estatística robusta de que a renda tem um
efeito significativo sobre o consumo.
- R-quadrado (
Multiple R-squared
):
- O valor é
0.954
. Isso significa que aproximadamente
95.4% da variação no consumo pessoal pode ser explicada
pela variação na renda pessoal disponível em nosso modelo. É um valor
extremamente alto, indicando um ajuste excelente do modelo aos
dados.
5. Outros Testes Relevantes (Diagnóstico)
Para que nossas estimativas sejam confiáveis (não-viesadas e
eficientes), o modelo precisa atender a certos pressupostos. Vamos
verificar brevemente dois deles:
5.1. Normalidade dos Resíduos
Os resíduos devem seguir uma distribuição normal.
# Extrair resíduos
residuos <- residuals(modelo_simples)
# Histograma dos resíduos
hist(residuos, main = "Histograma dos Resíduos", xlab = "Resíduos", col = "#FEB712", border = "black")

# Teste de Shapiro-Wilk
shapiro.test(residuos)
##
## Shapiro-Wilk normality test
##
## data: residuos
## W = 0.81057, p-value = 2.875e-12
O histograma não parece demonstrar uma distribuição normal. Com
efeito, teste de Shapiro-Wilk rejeita a normalidade
(\(H_0\): Normalidade dos
resíduos)
5.2. Homocedasticidade
A variância dos resíduos deve ser constante (homocedasticidade).
Podemos verificar isso plotando os resíduos contra os valores
ajustados.
plot(fitted(modelo_simples), residuos,
xlab = "Valores Ajustados", ylab = "Resíduos",
main = "Resíduos vs. Valores Ajustados")
abline(h = 0, col = "#02023C", lty = 2)

Neste gráfico, não devemos ver um padrão claro (como um cone ou
funil). No nosso caso, a nuvem de pontos parece relativamente uniforme
ao redor da linha zero para rendas mais baixas, o que é um bom sinal
para a homocedasticidade. Entretanto, para rendas mais altas, a
variância dos resíduos aumenta consideravelmente, formando um funil, o
que é sinal de heterocedasticidade e deverá ser tratado para
conseguirmos estatísticas interpretáveis.
6. Conclusão
Nesta aula, partimos do conceito de correlação vs. causalidade,
apresentamos a matemática por trás do modelo de regressão linear simples
e do método de MQO. Aplicamos esses conceitos para testar a Função
Consumo Keynesiana usando dados reais dos EUA. Nossos resultados tendem
a confirmar em alguma medida a teoria, entretetanto, o dado dos anos
mais recentes impõem dificuldades à análise. Isso foi mostrado com a
introdução dos testes de diagnóstico para validar a robustez do nosso
modelo. Este é o primeiro passo para análises econométricas mais
complexas e poderosas.
LS0tDQp0aXRsZTogIkF1bGEgMzogSW50cm9kdcOnw6NvIMOgIEVjb25vbWV0cmlhIGNvbSBSIg0KYXV0aG9yOiAiQnJ1bm8gTWVsbyBkZSBPbGl2ZWlyYSBTYW50b3MiDQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgdGhlbWU6IGNlcnVsZWFuDQogICAgaGlnaGxpZ2h0OiB0YW5nbw0KICAgIGNvZGVfZm9sZGluZzogc2hvdw0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UpDQpgYGANCg0KIyAxLiBJbnRyb2R1w6fDo286IENvcnJlbGHDp8OjbyB2cy4gQ2F1c2FsaWRhZGUNCg0KRW0gYW7DoWxpc2UgZGUgZGFkb3MsIGZyZXF1ZW50ZW1lbnRlIG9ic2VydmFtb3MgcXVlIGR1YXMgdmFyacOhdmVpcyBzZSBtb3ZlbSBqdW50YXMuIEEgaXNzbyBjaGFtYW1vcyAqKmNvcnJlbGHDp8OjbyoqLiBQb3IgZXhlbXBsbywgYXMgdmVuZGFzIGRlIHNvcnZldGUgZSBvIG7Dum1lcm8gZGUgYWZvZ2FtZW50b3MgZW0gdW1hIGNpZGFkZSBzw6NvIHBvc2l0aXZhbWVudGUgY29ycmVsYWNpb25hZG9zLiBObyBlbnRhbnRvLCBzZXJpYSB1bSBlcnJvIGNvbmNsdWlyIHF1ZSBvIGNvbnN1bW8gZGUgc29ydmV0ZSAqY2F1c2EqIGFmb2dhbWVudG9zLiBBIHZlcmRhZGVpcmEgY2F1c2EsIGEgdmFyacOhdmVsIG9jdWx0YSwgw6kgbyAqKmNhbG9yKio6IGRpYXMgbWFpcyBxdWVudGVzIGxldmFtIGEgdW0gYXVtZW50byBlbSBhbWJhcyBhcyBhdGl2aWRhZGVzLg0KDQpBIGVjb25vbWV0cmlhIGJ1c2NhIGlyIGFsw6ltIGRhIGNvcnJlbGHDp8OjbywgdGVudGFuZG8gZXN0YWJlbGVjZXIgZSBxdWFudGlmaWNhciByZWxhw6fDtWVzIGRlICoqY2F1c2FsaWRhZGUqKiBjb20gYmFzZSBuYSB0ZW9yaWEgZWNvbsO0bWljYS4gQSBmZXJyYW1lbnRhIG1haXMgYsOhc2ljYSBlIGZ1bmRhbWVudGFsIHBhcmEgaXNzbyDDqSBhICoqcmVncmVzc8OjbyBsaW5lYXIqKi4NCg0KSG9qZSwgdmFtb3MgdXNhciBhIHJlZ3Jlc3PDo28gcGFyYSB0ZXN0YXIgdW1hIGRhcyBtYWlzIGZhbW9zYXMgaGlww7N0ZXNlcyBkYSBtYWNyb2Vjb25vbWlhOiBhICoqRnVuw6fDo28gQ29uc3VtbyBLZXluZXNpYW5hKiosIHF1ZSBwb3N0dWxhIHF1ZSBvIGNvbnN1bW8gZGUgdW1hIHNvY2llZGFkZSDDqSB1bWEgZnVuw6fDo28gcG9zaXRpdmEgZGUgc3VhIHJlbmRhLg0KDQojIDIuIE8gTW9kZWxvIGRlIFJlZ3Jlc3PDo28gTGluZWFyIFNpbXBsZXMNCg0KTyBtb2RlbG8gbWF0ZW3DoXRpY28gcXVlIGRlc2NyZXZlIHVtYSByZWxhw6fDo28gbGluZWFyIGVudHJlIHVtYSB2YXJpw6F2ZWwgZGVwZW5kZW50ZSAoJFkkKSBlIHVtYSB2YXJpw6F2ZWwgaW5kZXBlbmRlbnRlICgkWCQpIMOpOg0KDQokJA0KWV9pID0gXGJldGFfMCArIFxiZXRhXzEgWF9pICsgdV9pDQokJA0KDQpPbmRlOg0KDQotICAgJFlfaSQ6IMOpIGEgdmFyacOhdmVsIGRlcGVuZGVudGUgKG8gcXVlIHF1ZXJlbW9zIGV4cGxpY2FyLCBleDogQ29uc3VtbykuDQoNCi0gICAkWF9pJDogw6kgYSB2YXJpw6F2ZWwgaW5kZXBlbmRlbnRlIG91IGV4cGxpY2F0aXZhIChvIHF1ZSB1c2Ftb3MgcGFyYSBleHBsaWNhciwgZXg6IFJlbmRhKS4NCg0KLSAgICRcYmV0YV8wJDogw6kgbyBpbnRlcmNlcHRvIChvIHZhbG9yIGRlICRZJCBxdWFuZG8gJFg9MCQpLg0KDQotICAgJFxiZXRhXzEkOiDDqSBvIGNvZWZpY2llbnRlIGFuZ3VsYXIgKG1lZGUgYSB2YXJpYcOnw6NvIGVtICRZJCBwYXJhIHVtYSB2YXJpYcOnw6NvIHVuaXTDoXJpYSBlbSAkWCQpLiBFc3RlIMOpLCBmcmVxdWVudGVtZW50ZSwgbyBub3NzbyBwcmluY2lwYWwgcGFyw6JtZXRybyBkZSBpbnRlcmVzc2UuDQoNCi0gICAkdV9pJDogw6kgbyB0ZXJtbyBkZSBlcnJvIGVzdG9jw6FzdGljby4gRWxlIGNhcHR1cmEgdG9kb3Mgb3Mgb3V0cm9zIGZhdG9yZXMgcXVlIGFmZXRhbSAkWSQgZSBxdWUgbsOjbyBlc3TDo28gaW5jbHXDrWRvcyBubyBtb2RlbG8uDQoNCi0gICBPIMOtbmRpY2UgJGkkIHJlcHJlc2VudGEgY2FkYSBvYnNlcnZhw6fDo28gKGV4OiBjYWRhIG3DqnMsIGNhZGEgYW5vLCBjYWRhIHBhw61zKS4NCg0KTm9zc28gb2JqZXRpdm8gw6kgb2J0ZXIgZXN0aW1hdGl2YXMgcGFyYSBvcyBwYXLDom1ldHJvcyBkZXNjb25oZWNpZG9zICRcYmV0YV8wJCBlICRcYmV0YV8xJCB1c2FuZG8gb3MgZGFkb3MgcXVlIHRlbW9zIGRlICRZJCBlICRYJC4NCg0KIyAzLiBFc3RpbWHDp8OjbyBwb3IgTcOtbmltb3MgUXVhZHJhZG9zIE9yZGluw6FyaW9zIChNUU8pDQoNCkNvbW8gZW5jb250cmFtb3MgYSAibWVsaG9yIiBsaW5oYSBxdWUgc2UgYWp1c3RhIGFvcyBub3Nzb3MgZGFkb3M/IE8gbcOpdG9kbyBkZSBNUU8gKGVtIGluZ2zDqnMsIE9MUyAtIE9yZGluYXJ5IExlYXN0IFNxdWFyZXMpIGRlZmluZSBhICJtZWxob3IiIGxpbmhhIGNvbW8gYXF1ZWxhIHF1ZSAqKm1pbmltaXphIGEgc29tYSBkb3MgcXVhZHJhZG9zIGRvcyByZXPDrWR1b3MqKi4NCg0KTyByZXPDrWR1byAoJFxoYXR7dX1faSQpIMOpIGEgZGlmZXJlbsOnYSBlbnRyZSBvIHZhbG9yIG9ic2VydmFkbyBkZSAkWV9pJCBlIG8gdmFsb3IgcHJlZGl0byBwZWxvIG1vZGVsbywgJFxoYXR7WX1faSQ6DQoNCiQkDQpcaGF0e3V9X2kgPSBZX2kgLSBcaGF0e1l9X2kgPSBZX2kgLSAoXGhhdHtcYmV0YX1fMCArIFxoYXR7XGJldGF9XzEgWF9pKQ0KJCQNCg0KTyBNUU8gYnVzY2EgbWluaW1pemFyIGEgU29tYSBkb3MgUXVhZHJhZG9zIGRvcyBSZXPDrWR1b3MgKFNRUik6DQoNCiQkDQpTUVIgPSBcc3VtX3tpPTF9XntufSBcaGF0e3V9X2leMiA9IFxzdW1fe2k9MX1ee259IChZX2kgLSBcaGF0e1xiZXRhfV8wIC0gXGhhdHtcYmV0YX1fMSBYX2kpXjINCiQkDQoNClBhcmEgZW5jb250cmFyIG9zIHZhbG9yZXMgZGUgJFxoYXR7XGJldGF9XzAkIGUgJFxoYXR7XGJldGF9XzEkIHF1ZSBtaW5pbWl6YW0gZXNzYSBleHByZXNzw6NvLCB1c2Ftb3MgY8OhbGN1bG8sIGRlcml2YW5kbyBhIFNRUiBlbSByZWxhw6fDo28gYSBjYWRhIHBhcsOibWV0cm8gZSBpZ3VhbGFuZG8gYSB6ZXJvLg0KDQpEZXJpdmFuZG8gZW0gcmVsYcOnw6NvIGEgJFxoYXR7XGJldGF9XzAkOiAkJA0KXGZyYWN7XHBhcnRpYWwgU1FSfXtccGFydGlhbCBcaGF0e1xiZXRhfV8wfSA9IC0yIFxzdW1fe2k9MX1ee259IChZX2kgLSBcaGF0e1xiZXRhfV8wIC0gXGhhdHtcYmV0YX1fMSBYX2kpID0gMA0KJCQNCg0KRGVyaXZhbmRvIGVtIHJlbGHDp8OjbyBhICRcaGF0e1xiZXRhfV8xJDogJCQNClxmcmFje1xwYXJ0aWFsIFNRUn17XHBhcnRpYWwgXGhhdHtcYmV0YX1fMX0gPSAtMiBcc3VtX3tpPTF9XntufSBYX2koWV9pIC0gXGhhdHtcYmV0YX1fMCAtIFxoYXR7XGJldGF9XzEgWF9pKSA9IDANCiQkDQoNClJlc29sdmVuZG8gZXN0ZSBzaXN0ZW1hIGRlIGR1YXMgZXF1YcOnw7VlcyAoY29uaGVjaWRhcyBjb21vIGVxdWHDp8O1ZXMgbm9ybWFpcyksIGNoZWdhbW9zIMOgcyBmw7NybXVsYXMgZG9zIGVzdGltYWRvcmVzIGRlIE1RTzoNCg0KJCQNClxoYXR7XGJldGF9XzEgPSBcZnJhY3tcc3VtX3tpPTF9XntufSAoWF9pIC0gXGJhcntYfSkoWV9pIC0gXGJhcntZfSl9e1xzdW1fe2k9MX1ee259IChYX2kgLSBcYmFye1h9KV4yfSA9IFxmcmFje0NvdihYLCBZKX17VmFyKFgpfQ0KJCQNCg0KJCQNClxoYXR7XGJldGF9XzAgPSBcYmFye1l9IC0gXGhhdHtcYmV0YX1fMSBcYmFye1h9DQokJA0KDQpPbmRlICRcYmFye1l9JCBlICRcYmFye1h9JCBzw6NvIGFzIG3DqWRpYXMgYW1vc3RyYWlzIGRlICRZJCBlICRYJCwgcmVzcGVjdGl2YW1lbnRlLg0KDQojIDQuIEFwbGljYcOnw6NvIFByw6F0aWNhIGVtIFINCg0KVmFtb3MgYWdvcmEgYXBsaWNhciBlc3NlcyBjb25jZWl0b3MgcGFyYSBhbmFsaXNhciBhIHJlbGHDp8OjbyBlbnRyZSBvICoqQ29uc3VtbyBQZXNzb2FsIFJlYWwgKGBQQ0VDYCkqKiBlIGEgKipSZW5kYSBQZXNzb2FsIERpc3BvbsOtdmVsIFJlYWwgKGBEU1BJQzk2YCkqKiBub3MgRXN0YWRvcyBVbmlkb3MuDQoNCiMjIDQuMS4gUHJlcGFyYcOnw6NvIGRvIEFtYmllbnRlDQoNClByaW1laXJvLCBpbnN0YWxhbW9zIGUgY2FycmVnYW1vcyBvcyBwYWNvdGVzIG5lY2Vzc8Ohcmlvcy4NCg0KYGBge3IgbGlic30NCiMgSW5zdGFsYXIgcGFjb3RlcyAoc2UgbmVjZXNzw6FyaW8pDQojIGluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpDQojIGluc3RhbGwucGFja2FnZXMoInBsb3RseSIpDQojIGluc3RhbGwucGFja2FnZXMoInNjYWxlcyIpDQojIGluc3RhbGwucGFja2FnZXMoImZyZWRyIikNCiMgaW5zdGFsbC5wYWNrYWdlcygic3RhcmdhemVyIikNCg0KIyBDYXJyZWdhciBvcyBwYWNvdGVzDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkocGxvdGx5KQ0KbGlicmFyeShzY2FsZXMpDQpsaWJyYXJ5KGZyZWRyKQ0KbGlicmFyeShzdGFyZ2F6ZXIpDQpgYGANCg0KIyMgNC4yLiBPYnRlbsOnw6NvIGRvcyBEYWRvcw0KDQpVc2FyZW1vcyBvIHBhY290ZSBgZnJlZHJgIHBhcmEgYmFpeGFyIG9zIGRhZG9zIGRpcmV0YW1lbnRlIGRvIGJhbmNvIGRlIGRhZG9zIGRvIEZlZGVyYWwgUmVzZXJ2ZSBkZSBTdC4gTG91aXMgKEZSRUQpLiDDiSBuZWNlc3PDoXJpbyBjb25maWd1cmFyIHVtYSBjaGF2ZSBkZSBBUEkgKGdyYXR1aXRhKSBkbyBGUkVELg0KDQpgYGB7ciBkYXRhfQ0KIyBDb25maWd1cmUgc3VhIGNoYXZlIGRhIEFQSSBkbyBGUkVEDQpmcmVkcl9zZXRfa2V5KCIyNmFiN2ZiODg1ZTRiM2JjMzg3ZjI1NTcyOGIwYThhZiIpDQoNCiMgMS4gT2J0ZXIgb3MgZGFkb3MgZGUgQ29uc3VtbyAoUENFQykNCmRhZG9zX2NvbnN1bW8gPC0gZnJlZHIoDQogIHNlcmllc19pZCA9ICJQQ0VDIiwNCiAgb2JzZXJ2YXRpb25fc3RhcnQgPSBhcy5EYXRlKCIxOTkwLTAxLTAxIikNCikNCg0KIyAyLiBPYnRlciBvcyBkYWRvcyBkZSBSZW5kYSAoRFNQSUM5NikNCmRhZG9zX3JlbmRhIDwtIGZyZWRyKA0KICBzZXJpZXNfaWQgPSAiRFNQSUM5NiIsDQogIG9ic2VydmF0aW9uX3N0YXJ0ID0gYXMuRGF0ZSgiMTk5MC0wMS0wMSIpDQopDQoNCiMgMy4gSnVudGFyIG9zIGRvaXMgZGF0YWZyYW1lcyBwZWxhIGRhdGENCmRhZG9zIDwtIA0KICAjIFNlbGVjaW9uYSBlIHJlbm9tZWlhIGEgY29sdW5hICd2YWx1ZScgZG8gZGYgZGUgY29uc3Vtbw0KICBzZWxlY3QoZGFkb3NfY29uc3VtbywgZGF0ZSwgY29uc3VtcHRpb24gPSB2YWx1ZSkgJT4lIA0KICAjIEp1bnRhIGNvbSBvIGRmIGRlIHJlbmRhLCBzZWxlY2lvbmFuZG8gZSByZW5vbWVhbmRvIGEgY29sdW5hICd2YWx1ZScNCiAgaW5uZXJfam9pbigNCiAgICBzZWxlY3QoZGFkb3NfcmVuZGEsIGRhdGUsIGluY29tZSA9IHZhbHVlKSwgDQogICAgYnkgPSAiZGF0ZSINCiAgKSAlPiUNCiAgIyBHYXJhbnRlIHF1ZSBuw6NvIGjDoSBsaW5oYXMgY29tIGRhZG9zIGZhbHRhbnRlcw0KICBuYS5vbWl0KCkNCg0KaGVhZChkYWRvcykNCmBgYA0KDQojIyA0LjMuIEFuw6FsaXNlIFZpc3VhbA0KDQpBbnRlcyBkZSBlc3RpbWFyIG8gbW9kZWxvLCDDqSBmdW5kYW1lbnRhbCB2aXN1YWxpemFyIGEgcmVsYcOnw6NvIGVudHJlIGFzIHZhcmnDoXZlaXMuDQoNCmBgYHtyIHBsb3R9DQojIFRvb2x0aXAgYW1pZ8OhdmVsIChwdC1CUikgY29tIHF1ZWJyYXMgZGUgbGluaGEgZW0gSFRNTA0KZGFkb3NfcGxvdCA8LSBkYWRvcyAlPiUNCiAgbXV0YXRlKA0KICAgIHRvb2x0aXAgPSBwYXN0ZTAoDQogICAgICAiRGF0YTogIiwgZm9ybWF0KGRhdGUsICIlYi8lWSIpLA0KICAgICAgIjxicj5SZW5kYSBkaXNwLjogIiwgbnVtYmVyKGluY29tZSwgYWNjdXJhY3kgPSAwLjEsIGJpZy5tYXJrID0gIi4iLCBkZWNpbWFsLm1hcmsgPSAiLCIpLCAiIGJpIFVTRCIsDQogICAgICAiPGJyPkNvbnN1bW86ICIsIG51bWJlcihjb25zdW1wdGlvbiwgYWNjdXJhY3kgPSAwLjEsIGJpZy5tYXJrID0gIi4iLCBkZWNpbWFsLm1hcmsgPSAiLCIpLCAiIGJpIFVTRCINCiAgICApDQogICkNCg0KcCA8LSBnZ3Bsb3QoZGFkb3NfcGxvdCwgYWVzKHggPSBpbmNvbWUsIHkgPSBjb25zdW1wdGlvbikpICsNCiAgZ2VvbV9wb2ludChhZXModGV4dCA9IHRvb2x0aXApLCBhbHBoYSA9IDAuNSwgY29sb3IgPSAiIzAyMDIzQyIpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSwgY29sID0gIiNGRUI3MTIiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiUmVsYcOnw6NvIGVudHJlIENvbnN1bW8gZSBSZW5kYSBEaXNwb27DrXZlbCBub3MgRVVBIiwNCiAgICBzdWJ0aXRsZSA9ICJEYWRvcyBtZW5zYWlzIGRlc2RlIDE5OTAiLA0KICAgIHggPSAiUmVuZGEgUGVzc29hbCBEaXNwb27DrXZlbCBSZWFsIChCaWxow7VlcyBkZSBVU0QpIiwNCiAgICB5ID0gIkNvbnN1bW8gUGVzc29hbCBSZWFsIChCaWxow7VlcyBkZSBVU0QpIiwNCiAgICBjYXB0aW9uID0gIkZvbnRlOiBGUkVEIg0KICApICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCiMgQ29udmVydGUgcGFyYSBwbG90bHkgdXNhbmRvIGFwZW5hcyBvICd0ZXh0JyBkbyBnZW9tX3BvaW50IG5vIHRvb2x0aXANCmdncGxvdGx5KHAsIHRvb2x0aXAgPSAidGV4dCIpDQpgYGANCg0KTyBncsOhZmljbyBkZSBkaXNwZXJzw6NvIG1vc3RyYSB1bWEgY29ycmVsYcOnw6NvIHBvc2l0aXZhIGUgZm9ydGUgcGFyIHZhbG9yZXMgbWVub3JlcywgcXVhc2UgcGVyZmVpdGFtZW50ZSBsaW5lYXIsIGNvbW8gZXNwZXJhZG8gcGVsYSB0ZW9yaWEgS2V5bmVzaWFuYS4gRW50cmV0YW50bywgcGFyYSB2YWxvcmVzIG1haW9yZXMgaMOhIHVtIGRlc2NvbGFtZW50byBkYSBsaW5oYSBkZSBmaXQsIG8gcXVlIHBvZGVyw6EgcmVwcmVzZW50YXIgcHJvYmxlbWFzIHBhcmEgbyBtb2RlbG8NCg0KIyMgNC40LiBFc3RpbWHDp8OjbyBkbyBNb2RlbG8NCg0KQWdvcmEsIHZhbW9zIGVzdGltYXIgbyBtb2RlbG8gZGUgcmVncmVzc8OjbyBsaW5lYXIgc2ltcGxlcyB1c2FuZG8gYSBmdW7Dp8OjbyBgbG0oKWAgKGxpbmVhciBtb2RlbCkuDQoNCmBgYHtyIG1vZGVsfQ0KbW9kZWxvX3NpbXBsZXMgPC0gbG0oY29uc3VtcHRpb24gfiBpbmNvbWUsIGRhdGEgPSBkYWRvcykNCmBgYA0KDQojIyA0LjUuIEFuw6FsaXNlIGRvcyBSZXN1bHRhZG9zDQoNClBvZGVtb3MgdmVyIG9zIHJlc3VsdGFkb3MgZGV0YWxoYWRvcyBjb20gYSBmdW7Dp8OjbyBgc3VtbWFyeSgpYC4NCg0KYGBge3Igc3VtbWFyeX0NCnN1bW1hcnkobW9kZWxvX3NpbXBsZXMpDQpgYGANCg0KUGFyYSB1bWEgdmlzdWFsaXphw6fDo28gbWFpcyBsaW1wYSBlIHByb2Zpc3Npb25hbCwgdXNhbW9zIG8gcGFjb3RlIGBzdGFyZ2F6ZXJgLg0KDQpgYGB7ciBzdGFyZ2F6ZXJ9DQpzdGFyZ2F6ZXIobW9kZWxvX3NpbXBsZXMsIHR5cGUgPSAidGV4dCIsDQogICAgICAgICAgdGl0bGUgPSAiUmVzdWx0YWRvcyBkYSBSZWdyZXNzw6NvOiBGdW7Dp8OjbyBDb25zdW1vIiwNCiAgICAgICAgICBkZXAudmFyLmxhYmVscyA9ICJDb25zdW1vIFBlc3NvYWwiLA0KICAgICAgICAgIGNvdmFyaWF0ZS5sYWJlbHMgPSBjKCJSZW5kYSBEaXNwb27DrXZlbCIsICJJbnRlcmNlcHRvIiksDQogICAgICAgICAgYWxpZ24gPSBUUlVFKQ0KYGBgDQoNCiMjIyBJbnRlcnByZXRhbmRvIG9zIFJlc3VsdGFkb3M6DQoNCjEuICAqKkNvZWZpY2llbnRlcyAoYEVzdGltYXRlYCk6KioNCiAgICAtICAgKipJbnRlcmNlcHRvICgqKiRcaGF0e1xiZXRhfV8wJCk6IGAtNiw3ODUuODgzYC4gRXN0ZSDDqSBvIG7DrXZlbCBkZSBjb25zdW1vIGF1dMO0bm9tbywgb3Ugc2VqYSwgbyBjb25zdW1vIHF1ZSBleGlzdGlyaWEgbWVzbW8gY29tIHJlbmRhIHplcm8uIEVjb25vbWljYW1lbnRlLCBwb2RlIHNlciBpbnRlcnByZXRhZG8gY29tbyBvIGNvbnN1bW8gZmluYW5jaWFkbyBwb3IgcG91cGFuw6dhIG91IGNyw6lkaXRvLg0KICAgIC0gICAqKmluY29tZSAoKiokXGhhdHtcYmV0YX1fMSQpOiBgMS4zOTVgLiBFc3RlIMOpIG8gY29lZmljaWVudGUgbWFpcyBpbXBvcnRhbnRlLiBFbGUgcmVwcmVzZW50YSBhICoqUHJvcGVuc8OjbyBNYXJnaW5hbCBhIENvbnN1bWlyIChQTWdDKSoqLiBBIGludGVycHJldGHDp8OjbyDDqTogcGFyYSBjYWRhIGF1bWVudG8gZGUgXCQxIGJpbGjDo28gbmEgcmVuZGEgZGlzcG9uw612ZWwgcmVhbCwgZXNwZXJhLXNlIHF1ZSBvIGNvbnN1bW8gcmVhbCBhdW1lbnRlIGVtIGFwcm94aW1hZGFtZW50ZSBcJDEuMzk1IGJpbGjDtWVzLCAqY2V0ZXJpcyBwYXJpYnVzKi4NCjIuICAqKlAtdmFsb3IgKGBQcig+fHR8KWApOioqDQogICAgLSAgIE8gcC12YWxvciBwYXJhIG8gY29lZmljaWVudGUgYGluY29tZWAgw6kgZXh0cmVtYW1lbnRlIGJhaXhvIChgPCAyZS0xNmAsIHF1ZSDDqSBlc3NlbmNpYWxtZW50ZSB6ZXJvKS4gSXNzbyB0ZXN0YSBhIGhpcMOzdGVzZSBudWxhIGRlIHF1ZSAkXGJldGFfMSA9IDAkLiBDb21vIG8gcC12YWxvciDDqSBtZW5vciBxdWUgcXVhbHF1ZXIgbsOtdmVsIGRlIHNpZ25pZmljw6JuY2lhIGNvbnZlbmNpb25hbCAoMSUsIDUlLCAxMCUpLCBuw7NzICoqcmVqZWl0YW1vcyBhIGhpcMOzdGVzZSBudWxhKiouIElzc28gc2lnbmlmaWNhIHF1ZSBow6EgZXZpZMOqbmNpYSBlc3RhdMOtc3RpY2Egcm9idXN0YSBkZSBxdWUgYSByZW5kYSB0ZW0gdW0gZWZlaXRvIHNpZ25pZmljYXRpdm8gc29icmUgbyBjb25zdW1vLg0KMy4gICoqUi1xdWFkcmFkbyAoYE11bHRpcGxlIFItc3F1YXJlZGApOioqDQogICAgLSAgIE8gdmFsb3Igw6kgYDAuOTU0YC4gSXNzbyBzaWduaWZpY2EgcXVlIGFwcm94aW1hZGFtZW50ZSAqKjk1LjQlKiogZGEgdmFyaWHDp8OjbyBubyBjb25zdW1vIHBlc3NvYWwgcG9kZSBzZXIgZXhwbGljYWRhIHBlbGEgdmFyaWHDp8OjbyBuYSByZW5kYSBwZXNzb2FsIGRpc3BvbsOtdmVsIGVtIG5vc3NvIG1vZGVsby4gw4kgdW0gdmFsb3IgZXh0cmVtYW1lbnRlIGFsdG8sIGluZGljYW5kbyB1bSBhanVzdGUgZXhjZWxlbnRlIGRvIG1vZGVsbyBhb3MgZGFkb3MuDQoNCiMgNS4gT3V0cm9zIFRlc3RlcyBSZWxldmFudGVzIChEaWFnbsOzc3RpY28pDQoNClBhcmEgcXVlIG5vc3NhcyBlc3RpbWF0aXZhcyBzZWphbSBjb25macOhdmVpcyAobsOjby12aWVzYWRhcyBlIGVmaWNpZW50ZXMpLCBvIG1vZGVsbyBwcmVjaXNhIGF0ZW5kZXIgYSBjZXJ0b3MgcHJlc3N1cG9zdG9zLiBWYW1vcyB2ZXJpZmljYXIgYnJldmVtZW50ZSBkb2lzIGRlbGVzOg0KDQojIyA1LjEuIE5vcm1hbGlkYWRlIGRvcyBSZXPDrWR1b3MNCg0KT3MgcmVzw61kdW9zIGRldmVtIHNlZ3VpciB1bWEgZGlzdHJpYnVpw6fDo28gbm9ybWFsLg0KDQpgYGB7ciByZXNpZHVhbHNfaGlzdH0NCiMgRXh0cmFpciByZXPDrWR1b3MNCnJlc2lkdW9zIDwtIHJlc2lkdWFscyhtb2RlbG9fc2ltcGxlcykNCg0KIyBIaXN0b2dyYW1hIGRvcyByZXPDrWR1b3MNCmhpc3QocmVzaWR1b3MsIG1haW4gPSAiSGlzdG9ncmFtYSBkb3MgUmVzw61kdW9zIiwgeGxhYiA9ICJSZXPDrWR1b3MiLCBjb2wgPSAiI0ZFQjcxMiIsIGJvcmRlciA9ICJibGFjayIpDQoNCiMgVGVzdGUgZGUgU2hhcGlyby1XaWxrDQpzaGFwaXJvLnRlc3QocmVzaWR1b3MpDQpgYGANCg0KTyBoaXN0b2dyYW1hIG7Do28gcGFyZWNlIGRlbW9uc3RyYXIgdW1hIGRpc3RyaWJ1acOnw6NvIG5vcm1hbC4gQ29tIGVmZWl0bywgdGVzdGUgZGUgU2hhcGlyby1XaWxrIHJlamVpdGEgYSBub3JtYWxpZGFkZQ0KDQooJEhfMCQ6IE5vcm1hbGlkYWRlIGRvcyByZXPDrWR1b3MpDQoNCiMjIDUuMi4gSG9tb2NlZGFzdGljaWRhZGUNCg0KQSB2YXJpw6JuY2lhIGRvcyByZXPDrWR1b3MgZGV2ZSBzZXIgY29uc3RhbnRlIChob21vY2VkYXN0aWNpZGFkZSkuIFBvZGVtb3MgdmVyaWZpY2FyIGlzc28gcGxvdGFuZG8gb3MgcmVzw61kdW9zIGNvbnRyYSBvcyB2YWxvcmVzIGFqdXN0YWRvcy4NCg0KYGBge3IgcmVzaWR1YWxzX3Bsb3R9DQpwbG90KGZpdHRlZChtb2RlbG9fc2ltcGxlcyksIHJlc2lkdW9zLA0KICAgICB4bGFiID0gIlZhbG9yZXMgQWp1c3RhZG9zIiwgeWxhYiA9ICJSZXPDrWR1b3MiLA0KICAgICBtYWluID0gIlJlc8OtZHVvcyB2cy4gVmFsb3JlcyBBanVzdGFkb3MiKQ0KYWJsaW5lKGggPSAwLCBjb2wgPSAiIzAyMDIzQyIsIGx0eSA9IDIpDQpgYGANCg0KTmVzdGUgZ3LDoWZpY28sIG7Do28gZGV2ZW1vcyB2ZXIgdW0gcGFkcsOjbyBjbGFybyAoY29tbyB1bSBjb25lIG91IGZ1bmlsKS4gTm8gbm9zc28gY2FzbywgYSBudXZlbSBkZSBwb250b3MgcGFyZWNlIHJlbGF0aXZhbWVudGUgdW5pZm9ybWUgYW8gcmVkb3IgZGEgbGluaGEgemVybyBwYXJhIHJlbmRhcyBtYWlzIGJhaXhhcywgbyBxdWUgw6kgdW0gYm9tIHNpbmFsIHBhcmEgYSBob21vY2VkYXN0aWNpZGFkZS4gRW50cmV0YW50bywgcGFyYSByZW5kYXMgbWFpcyBhbHRhcywgYSB2YXJpw6JuY2lhIGRvcyByZXPDrWR1b3MgYXVtZW50YSBjb25zaWRlcmF2ZWxtZW50ZSwgZm9ybWFuZG8gdW0gZnVuaWwsIG8gcXVlIMOpIHNpbmFsIGRlIGhldGVyb2NlZGFzdGljaWRhZGUgZSBkZXZlcsOhIHNlciB0cmF0YWRvIHBhcmEgY29uc2VndWlybW9zIGVzdGF0w61zdGljYXMgaW50ZXJwcmV0w6F2ZWlzLg0KDQojIDYuIENvbmNsdXPDo28NCg0KTmVzdGEgYXVsYSwgcGFydGltb3MgZG8gY29uY2VpdG8gZGUgY29ycmVsYcOnw6NvIHZzLiBjYXVzYWxpZGFkZSwgYXByZXNlbnRhbW9zIGEgbWF0ZW3DoXRpY2EgcG9yIHRyw6FzIGRvIG1vZGVsbyBkZSByZWdyZXNzw6NvIGxpbmVhciBzaW1wbGVzIGUgZG8gbcOpdG9kbyBkZSBNUU8uIEFwbGljYW1vcyBlc3NlcyBjb25jZWl0b3MgcGFyYSB0ZXN0YXIgYSBGdW7Dp8OjbyBDb25zdW1vIEtleW5lc2lhbmEgdXNhbmRvIGRhZG9zIHJlYWlzIGRvcyBFVUEuIE5vc3NvcyByZXN1bHRhZG9zIHRlbmRlbSBhIGNvbmZpcm1hciBlbSBhbGd1bWEgbWVkaWRhIGEgdGVvcmlhLCBlbnRyZXRldGFudG8sIG8gZGFkbyBkb3MgYW5vcyBtYWlzIHJlY2VudGVzIGltcMO1ZW0gZGlmaWN1bGRhZGVzIMOgIGFuw6FsaXNlLiBJc3NvIGZvaSBtb3N0cmFkbyBjb20gYSBpbnRyb2R1w6fDo28gZG9zIHRlc3RlcyBkZSBkaWFnbsOzc3RpY28gcGFyYSB2YWxpZGFyIGEgcm9idXN0ZXogZG8gbm9zc28gbW9kZWxvLiBFc3RlIMOpIG8gcHJpbWVpcm8gcGFzc28gcGFyYSBhbsOhbGlzZXMgZWNvbm9tw6l0cmljYXMgbWFpcyBjb21wbGV4YXMgZSBwb2Rlcm9zYXMuDQo=