Licença

This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.

License: CC BY-SA 4.0

Citação

Sugestão de citação: FIGUEIREDO, Adriano Marcos Rodrigues. Econometria: estatísticas descritivas em R e Python. Campo Grande-MS,Brasil: RStudio/Rpubs, 2022. Disponível em http://rpubs.com/amrofi/estat_descritivas_R_Python.

1 Dados de Gujarati e Porter (2011, p.235-236)

Os primeiros passos são criar ou abrir um diretório de trabalho. Se optar por criar um novo projeto, haverá a possibilidade de criar em uma pasta vazia. Em seguida, sugere-se que coloque os dados nesta pasta, se possível em um arquivo MS Excel e chame a planilha de ‘dados’.Neste caso, a planilha chama-se gujarati 5ed p236 frangos tabela7_9.xlsx.

7.19. Demanda por frangos nos Estados Unidos, 1960-1982. Para estudar o consumo per capita de frango nos Estados Unidos, use os dados da Tabela 7.9, em que Y = consumo per capita de frango em libras (peso) X2= renda real disponível per capita, em $ X3= preço real do frango no varejo, em centavos de dólar por libra (peso) ¢ X4= preço real da carne suína no varejo, em centavos de dólar por libra (peso) ¢ X5= preço real da carne bovina no varejo, em centavos de dólar por libra (peso) ¢ X6= preço real dos substitutos da carne de frango, em centavos de dólar por libra (peso), que é uma média ponderada dos preços reais das carnes suína e bovina, usando como pesos o consumo relativo de cada uma dessas carnes em relação ao consumo total delas.

A opção do dput() pode ser obtida abaixo.

dados <- structure(list(YEAR = c(1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967,
    1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980,
    1981, 1982), Y = c(27.8, 29.9, 29.8, 30.8, 31.2, 33.3, 35.6, 36.4, 36.7, 38.4,
    40.4, 40.3, 41.8, 40.4, 40.7, 40.1, 42.7, 44.1, 46.7, 50.6, 50.1, 51.7, 52.9),
    X2 = c(397.5, 413.3, 439.2, 459.7, 492.9, 528.6, 560.3, 624.6, 666.4, 717.8,
        768.2, 843.3, 911.6, 931.1, 1021.5, 1165.9, 1349.6, 1449.4, 1575.5, 1759.1,
        1994.2, 2258.1, 2478.7), X3 = c(42.2, 38.1, 40.3, 39.5, 37.3, 38.1, 39.3,
        37.8, 38.4, 40.1, 38.6, 39.8, 39.7, 52.1, 48.9, 58.3, 57.9, 56.5, 63.7, 61.6,
        58.9, 66.4, 70.4), X4 = c(50.7, 52, 54, 55.3, 54.7, 63.7, 69.8, 65.9, 64.5,
        70, 73.2, 67.8, 79.1, 95.4, 94.2, 123.5, 129.9, 117.6, 130.9, 129.8, 128,
        141, 168.2), X5 = c(78.3, 79.2, 79.2, 79.2, 77.4, 80.2, 80.4, 83.9, 85.5,
        93.7, 106.1, 104.8, 114, 124.1, 127.6, 142.9, 143.6, 139.2, 165.5, 203.3,
        219.6, 221.6, 232.6), X6 = c(65.8, 66.9, 67.8, 69.6, 68.7, 73.6, 76.3, 77.2,
        78.1, 84.7, 93.3, 89.7, 100.7, 113.5, 115.3, 136.7, 139.2, 132, 132.1, 154.4,
        174.9, 180.8, 189.4)), row.names = c(NA, -23L), class = c("tbl_df", "tbl",
    "data.frame"))

attach(dados)

2 Em R

library(tidyverse)

# Transforma em tibble

dados_tbl <- dados %>%
    as_tibble

# Ver a estrutura dos dados

str(dados_tbl)
tibble [23 x 7] (S3: tbl_df/tbl/data.frame)
 $ YEAR: num [1:23] 1960 1961 1962 1963 1964 ...
 $ Y   : num [1:23] 27.8 29.9 29.8 30.8 31.2 33.3 35.6 36.4 36.7 38.4 ...
 $ X2  : num [1:23] 398 413 439 460 493 ...
 $ X3  : num [1:23] 42.2 38.1 40.3 39.5 37.3 38.1 39.3 37.8 38.4 40.1 ...
 $ X4  : num [1:23] 50.7 52 54 55.3 54.7 63.7 69.8 65.9 64.5 70 ...
 $ X5  : num [1:23] 78.3 79.2 79.2 79.2 77.4 80.2 80.4 83.9 85.5 93.7 ...
 $ X6  : num [1:23] 65.8 66.9 67.8 69.6 68.7 73.6 76.3 77.2 78.1 84.7 ...

2.1 Estatísticas descritivas

2.1.1 Medidas de posição (tendência central)

# Média de Y
minhavar <- dados_tbl$Y
mean(minhavar)
[1] 39.66957
# Mediana
median(minhavar)
[1] 40.3
# Moda
table(minhavar) %>%
    sort(decreasing = TRUE)
minhavar
40.4 27.8 29.8 29.9 30.8 31.2 33.3 35.6 36.4 36.7 38.4 40.1 40.3 40.7 41.8 42.7 
   2    1    1    1    1    1    1    1    1    1    1    1    1    1    1    1 
44.1 46.7 50.1 50.6 51.7 52.9 
   1    1    1    1    1    1 

2.1.2 Medidas de dispersão (variabilidade)

# Variância
var(minhavar)
[1] 54.3604
# Desvio padrão
sd(minhavar)
[1] 7.37295

2.1.3 Medidas de relacionamento

# Covariância
minhavar2 <- dados_tbl$X3  # X3
minhavar3 <- dados_tbl$X5  # X5
cov(minhavar2, minhavar3)
[1] 531.5792
cov(dados_tbl)
           YEAR          Y         X2         X3         X4         X5
YEAR   46.00000   48.91818   3935.518   66.55455   226.2727   322.5182
Y      48.91818   54.36040   4314.699   68.84850   236.9505   355.1592
X2   3935.51818 4314.69935 381734.940 6399.46575 20829.9032 31369.5975
X3     66.55455   68.84850   6399.466  123.59225   379.8850   531.5792
X4    226.27273  236.95045  20829.903  379.88500  1240.7082  1706.1977
X5    322.51818  355.15915  31369.597  531.57923  1706.1977  2652.2231
X6    257.46364  275.17907  24175.211  418.07480  1364.5050  2016.3027
             X6
YEAR   257.4636
Y      275.1791
X2   24175.2107
X3     418.0748
X4    1364.5050
X5    2016.3027
X6    1585.2080
# Correlação
cor(minhavar2, minhavar3)
[1] 0.9284689
cor(dados_tbl)
          YEAR         Y        X2        X3        X4        X5        X6
YEAR 1.0000000 0.9782505 0.9391653 0.8826798 0.9471494 0.9233583 0.9534411
Y    0.9782505 1.0000000 0.9471708 0.8399579 0.9123919 0.9353554 0.9374130
X2   0.9391653 0.9471708 1.0000000 0.9316808 0.9571312 0.9858775 0.9827571
X3   0.8826798 0.8399579 0.9316808 1.0000000 0.9701116 0.9284689 0.9445289
X4   0.9471494 0.9123919 0.9571312 0.9701116 1.0000000 0.9405665 0.9729649
X5   0.9233583 0.9353554 0.9858775 0.9284689 0.9405665 1.0000000 0.9833488
X6   0.9534411 0.9374130 0.9827571 0.9445289 0.9729649 0.9833488 1.0000000

2.1.4 Percentis

# Calcula o 25° percentil - 1 Quartil

quantile(minhavar, 0.25)
  25% 
34.45 
# Calcula o 75° percentil - 3 Quartil

quantile(minhavar, 0.75)
 75% 
43.4 

2.1.5 Resumo das estatísticas

summary(dados_tbl)
      YEAR            Y               X2               X3       
 Min.   :1960   Min.   :27.80   Min.   : 397.5   Min.   :37.30  
 1st Qu.:1966   1st Qu.:34.45   1st Qu.: 544.5   1st Qu.:38.95  
 Median :1971   Median :40.30   Median : 843.3   Median :40.30  
 Mean   :1971   Mean   :39.67   Mean   :1035.1   Mean   :48.00  
 3rd Qu.:1976   3rd Qu.:43.40   3rd Qu.:1399.5   3rd Qu.:58.10  
 Max.   :1982   Max.   :52.90   Max.   :2478.7   Max.   :70.40  
       X4              X5              X6        
 Min.   : 50.7   Min.   : 77.4   Min.   : 65.80  
 1st Qu.: 64.1   1st Qu.: 80.3   1st Qu.: 74.95  
 Median : 73.2   Median :106.1   Median : 93.30  
 Mean   : 90.4   Mean   :124.4   Mean   :107.86  
 3rd Qu.:125.8   3rd Qu.:143.2   3rd Qu.:134.40  
 Max.   :168.2   Max.   :232.6   Max.   :189.40  

2.1.6 Resumo com skimr

library(skimr)

# Sumariza os dados com o pacote skimr

skim(dados_tbl)
Data summary
Name dados_tbl
Number of rows 23
Number of columns 7
_______________________
Column type frequency:
numeric 7
________________________
Group variables None

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
YEAR 0 1 1971.00 6.78 1960.0 1965.50 1971.0 1976.50 1982.0 ▇▆▇▆▇
Y 0 1 39.67 7.37 27.8 34.45 40.3 43.40 52.9 ▅▃▇▂▃
X2 0 1 1035.07 617.85 397.5 544.45 843.3 1399.50 2478.7 ▇▃▂▂▂
X3 0 1 48.00 11.12 37.3 38.95 40.3 58.10 70.4 ▇▁▁▃▁
X4 0 1 90.40 35.22 50.7 64.10 73.2 125.75 168.2 ▇▂▁▃▁
X5 0 1 124.43 51.50 77.4 80.30 106.1 143.25 232.6 ▇▂▂▁▂
X6 0 1 107.86 39.81 65.8 74.95 93.3 134.40 189.4 ▇▂▃▁▂

3 Em Python

3.1 Estatísticas descritivas

import numpy as np
import pandas as pd
# Carrega os dados

# precisei instalar openpyxl (para xlsx) e xlrd (para xls)
df = pd.read_excel (r'gujarati 5ed p236 frangos tabela7_9.xlsx', sheet_name='py')
#data_as_dict= print(df.to_dict())
#df = pd.DataFrame.from_dict(data_as_dict)
import pandas as pd
dados = pd.DataFrame.from_dict({'YEAR': {0: 1960, 1: 1961, 2: 1962, 3: 1963, 4: 1964, 5: 1965, 6: 1966, 7: 1967, 8: 1968, 9: 1969, 10: 1970, 11: 1971, 12: 1972, 13: 1973, 14: 1974, 15: 1975, 16: 1976, 17: 1977, 18: 1978, 19: 1979, 20: 1980, 21: 1981, 22: 1982}, 'Y': {0: 27.8, 1: 29.9, 2: 29.8, 3: 30.8, 4: 31.2, 5: 33.3, 6: 35.6, 7: 36.4, 8: 36.7, 9: 38.4, 10: 40.4, 11: 40.3, 12: 41.8, 13: 40.4, 14: 40.7, 15: 40.1, 16: 42.7, 17: 44.1, 18: 46.7, 19: 50.6, 20: 50.1, 21: 51.7, 22: 52.9}, 'X2': {0: 397.5, 1: 413.3, 2: 439.2, 3: 459.7, 4: 492.9, 5: 528.6, 6: 560.3, 7: 624.6, 8: 666.4, 9: 717.8, 10: 768.2, 11: 843.3, 12: 911.6, 13: 931.1, 14: 1021.5, 15: 1165.9, 16: 1349.6, 17: 1449.4, 18: 1575.5, 19: 1759.1, 20: 1994.2, 21: 2258.1, 22: 2478.7}, 'X3': {0: 42.2, 1: 38.1, 2: 40.3, 3: 39.5, 4: 37.3, 5: 38.1, 6: 39.3, 7: 37.8, 8: 38.4, 9: 40.1, 10: 38.6, 11: 39.8, 12: 39.7, 13: 52.1, 14: 48.9, 15: 58.3, 16: 57.9, 17: 56.5, 18: 63.7, 19: 61.6, 20: 58.9, 21: 66.4, 22: 70.4}, 'X4': {0: 50.7, 1: 52.0, 2: 54.0, 3: 55.3, 4: 54.7, 5: 63.7, 6: 69.8, 7: 65.9, 8: 64.5, 9: 70.0, 10: 73.2, 11: 67.8, 12: 79.1, 13: 95.4, 14: 94.2, 15: 123.5, 16: 129.9, 17: 117.6, 18: 130.9, 19: 129.8, 20: 128.0, 21: 141.0, 22: 168.2}, 'X5': {0: 78.3, 1: 79.2, 2: 79.2, 3: 79.2, 4: 77.4, 5: 80.2, 6: 80.4, 7: 83.9, 8: 85.5, 9: 93.7, 10: 106.1, 11: 104.8, 12: 114.0, 13: 124.1, 14: 127.6, 15: 142.9, 16: 143.6, 17: 139.2, 18: 165.5, 19: 203.3, 20: 219.6, 21: 221.6, 22: 232.6}, 'X6': {0: 65.8, 1: 66.9, 2: 67.8, 3: 69.6, 4: 68.7, 5: 73.6, 6: 76.3, 7: 77.2, 8: 78.1, 9: 84.7, 10: 93.3, 11: 89.7, 12: 100.7, 13: 113.5, 14: 115.3, 15: 136.7, 16: 139.2, 17: 132.0, 18: 132.1, 19: 154.4, 20: 174.9, 21: 180.8, 22: 189.4}})

dados

# Ve a estrutura dos dados
    YEAR     Y      X2    X3     X4     X5     X6
0   1960  27.8   397.5  42.2   50.7   78.3   65.8
1   1961  29.9   413.3  38.1   52.0   79.2   66.9
2   1962  29.8   439.2  40.3   54.0   79.2   67.8
3   1963  30.8   459.7  39.5   55.3   79.2   69.6
4   1964  31.2   492.9  37.3   54.7   77.4   68.7
5   1965  33.3   528.6  38.1   63.7   80.2   73.6
6   1966  35.6   560.3  39.3   69.8   80.4   76.3
7   1967  36.4   624.6  37.8   65.9   83.9   77.2
8   1968  36.7   666.4  38.4   64.5   85.5   78.1
9   1969  38.4   717.8  40.1   70.0   93.7   84.7
10  1970  40.4   768.2  38.6   73.2  106.1   93.3
11  1971  40.3   843.3  39.8   67.8  104.8   89.7
12  1972  41.8   911.6  39.7   79.1  114.0  100.7
13  1973  40.4   931.1  52.1   95.4  124.1  113.5
14  1974  40.7  1021.5  48.9   94.2  127.6  115.3
15  1975  40.1  1165.9  58.3  123.5  142.9  136.7
16  1976  42.7  1349.6  57.9  129.9  143.6  139.2
17  1977  44.1  1449.4  56.5  117.6  139.2  132.0
18  1978  46.7  1575.5  63.7  130.9  165.5  132.1
19  1979  50.6  1759.1  61.6  129.8  203.3  154.4
20  1980  50.1  1994.2  58.9  128.0  219.6  174.9
21  1981  51.7  2258.1  66.4  141.0  221.6  180.8
22  1982  52.9  2478.7  70.4  168.2  232.6  189.4
dados.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 23 entries, 0 to 22
Data columns (total 7 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   YEAR    23 non-null     int64  
 1   Y       23 non-null     float64
 2   X2      23 non-null     float64
 3   X3      23 non-null     float64
 4   X4      23 non-null     float64
 5   X5      23 non-null     float64
 6   X6      23 non-null     float64
dtypes: float64(6), int64(1)
memory usage: 1.4 KB

3.1.1 Medidas de posição (tendência central)

# Média
dados['Y'].mean()

# Mediana
39.669565217391316
dados['Y'].median()

# Moda
40.3
dados['Y'].mode()
0    40.4
dtype: float64

3.1.2 Medidas de dispersão (variabilidade)

# Variância
dados['Y'].var()


# Desvio padrão
54.36039525691701
dados['Y'].std()
7.372950241044423

3.1.3 Medidas de relacionamento

# Covariância
dados.cov()

# Correlação
             YEAR            Y  ...            X5            X6
YEAR    46.000000    48.918182  ...    322.518182    257.463636
Y       48.918182    54.360395  ...    355.159150    275.179071
X2    3935.518182  4314.699348  ...  31369.597470  24175.210692
X3      66.554545    68.848498  ...    531.579229    418.074802
X4     226.272727   236.950455  ...   1706.197727   1364.505000
X5     322.518182   355.159150  ...   2652.223123   2016.302747
X6     257.463636   275.179071  ...   2016.302747   1585.208024

[7 rows x 7 columns]
dados.corr()
          YEAR         Y        X2        X3        X4        X5        X6
YEAR  1.000000  0.978251  0.939165  0.882680  0.947149  0.923358  0.953441
Y     0.978251  1.000000  0.947171  0.839958  0.912392  0.935355  0.937413
X2    0.939165  0.947171  1.000000  0.931681  0.957131  0.985878  0.982757
X3    0.882680  0.839958  0.931681  1.000000  0.970112  0.928469  0.944529
X4    0.947149  0.912392  0.957131  0.970112  1.000000  0.940567  0.972965
X5    0.923358  0.935355  0.985878  0.928469  0.940567  1.000000  0.983349
X6    0.953441  0.937413  0.982757  0.944529  0.972965  0.983349  1.000000

3.1.4 Percentis

import numpy as np
q1 = np.percentile(dados['Y'], 25) # 25th percentile, ex 1 Quartil.
q1
34.45
q3 = np.percentile(dados['Y'], 75) # 75th percentile, ex 3 Quartil.
q3
43.400000000000006

3.1.5 Resumo das estatísticas

dados.describe()
             YEAR          Y           X2  ...          X4          X5          X6
count    23.00000  23.000000    23.000000  ...   23.000000   23.000000   23.000000
mean   1971.00000  39.669565  1035.065217  ...   90.400000  124.430435  107.856522
std       6.78233   7.372950   617.847020  ...   35.223688   51.499739   39.814671
min    1960.00000  27.800000   397.500000  ...   50.700000   77.400000   65.800000
25%    1965.50000  34.450000   544.450000  ...   64.100000   80.300000   74.950000
50%    1971.00000  40.300000   843.300000  ...   73.200000  106.100000   93.300000
75%    1976.50000  43.400000  1399.500000  ...  125.750000  143.250000  134.400000
max    1982.00000  52.900000  2478.700000  ...  168.200000  232.600000  189.400000

[8 rows x 7 columns]

3.1.6 Resumo com skimpy

library(reticulate)
py_install("skimpy")  # para instalar pacote
# Skim
from skimpy import skim
skim(dados)

4 Referências

GUJARATI, Damodar N.; PORTER, Dawn C. Econometria básica. 5.ed. Porto Alegre: AMGH/Bookman/McGraw-Hill do Brasil, 2011. Número de chamada: 330.015195 G969e.5 (CBC) e recurso online ISBN 9788580550511 (Minha Biblioteca - UFMS).

LS0tDQp0aXRsZTogJ0Vjb25vbWV0cmlhOiBlc3RhdMOtc3RpY2FzIGRlc2NyaXRpdmFzIGVtIFIgZSBQeXRob24nDQphdXRob3I6ICdBZHJpYW5vIE1hcmNvcyBSb2RyaWd1ZXMgRmlndWVpcmVkbywgKmUtbWFpbDogYWRyaWFuby5maWd1ZWlyZWRvQHVmbXMuYnIqJw0KZGF0ZTogImByIGZvcm1hdChTeXMuRGF0ZSgpLCAnJWQgJUIgJVknKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgdGhlbWU6IGRlZmF1bHQNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICBkZl9wcmludDogcGFnZWQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQpsaW5rY29sb3I6IGJsdWUNCmFic3RyYWN0OiBUaGlzIGlzIGFuIHVuZGVyZ3JhZCBzdHVkZW50IGxldmVsIGV4ZXJjaXNlIGZvciBjbGFzcyB1c2UuIA0KZ3JhcGhpY3M6IHllcw0KZWRpdG9yX29wdGlvbnM6IA0KICBtYXJrZG93bjogDQogICAgd3JhcDogNzINCi0tLQ0KDQpgYGB7ciBrbml0cl9pbml0LCBlY2hvPUZBTFNFLCBjYWNoZT1GQUxTRX0NCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KHJtYXJrZG93bikNCmxpYnJhcnkocm1kZm9ybWF0cykNCg0KIyMgR2xvYmFsIG9wdGlvbnMNCm9wdGlvbnMobWF4LnByaW50PSIxMDAiKQ0Kb3B0c19jaHVuayRzZXQoZWNobz1UUlVFLA0KCSAgICAgICAgICAgICBjYWNoZT1UUlVFLA0KICAgICAgICAgICAgICAgcHJvbXB0PUZBTFNFLA0KICAgICAgICAgICAgICAgdGlkeT1UUlVFLA0KICAgICAgICAgICAgICAgY29tbWVudD1OQSwNCiAgICAgICAgICAgICAgIG1lc3NhZ2U9RkFMU0UsDQogICAgICAgICAgICAgICB3YXJuaW5nPUZBTFNFKQ0Kb3B0c19rbml0JHNldCh3aWR0aD0xMDApDQpgYGANCg0KIyBMaWNlbsOnYSB7I0xpY2Vuw6dhIC51bm51bWJlcmVkfQ0KDQpUaGlzIHdvcmsgaXMgbGljZW5zZWQgdW5kZXIgdGhlIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZQ0KNC4wIEludGVybmF0aW9uYWwgTGljZW5zZS4gVG8gdmlldyBhIGNvcHkgb2YgdGhpcyBsaWNlbnNlLCB2aXNpdA0KPGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL2J5LXNhLzQuMC8+IG9yIHNlbmQgYSBsZXR0ZXIgdG8NCkNyZWF0aXZlIENvbW1vbnMsIFBPIEJveCAxODY2LCBNb3VudGFpbiBWaWV3LCBDQSA5NDA0MiwgVVNBLg0KDQohW0xpY2Vuc2U6IENDIEJZLVNBDQo0LjBdKGh0dHBzOi8vbWlycm9ycy5jcmVhdGl2ZWNvbW1vbnMub3JnL3ByZXNza2l0L2J1dHRvbnMvODh4MzEvcG5nL2J5LXNhLnBuZyl7d2lkdGg9IjI1JSJ9DQoNCiMgQ2l0YcOnw6NvIHsjQ2l0YcOnw6NvIC51bm51bWJlcmVkfQ0KDQpTdWdlc3TDo28gZGUgY2l0YcOnw6NvOiBGSUdVRUlSRURPLCBBZHJpYW5vIE1hcmNvcyBSb2RyaWd1ZXMuIEVjb25vbWV0cmlhOg0KZXN0YXTDrXN0aWNhcyBkZXNjcml0aXZhcyBlbSBSIGUgUHl0aG9uLiBDYW1wbyBHcmFuZGUtTVMsQnJhc2lsOg0KUlN0dWRpby9ScHVicywgMjAyMi4gRGlzcG9uw612ZWwgZW0NCjxodHRwOi8vcnB1YnMuY29tL2Ftcm9maS9lc3RhdF9kZXNjcml0aXZhc19SX1B5dGhvbj4uDQoNCiMgRGFkb3MgZGUgR3VqYXJhdGkgZSBQb3J0ZXIgKDIwMTEsIHAuMjM1LTIzNikNCg0KT3MgcHJpbWVpcm9zIHBhc3NvcyBzw6NvIGNyaWFyIG91IGFicmlyIHVtIGRpcmV0w7NyaW8gZGUgdHJhYmFsaG8uIFNlDQpvcHRhciBwb3IgY3JpYXIgdW0gbm92byBwcm9qZXRvLCBoYXZlcsOhIGEgcG9zc2liaWxpZGFkZSBkZSBjcmlhciBlbSB1bWENCnBhc3RhIHZhemlhLiBFbSBzZWd1aWRhLCBzdWdlcmUtc2UgcXVlIGNvbG9xdWUgb3MgZGFkb3MgbmVzdGEgcGFzdGEsIHNlDQpwb3Nzw612ZWwgZW0gdW0gYXJxdWl2byBNUyBFeGNlbCBlIGNoYW1lIGEgcGxhbmlsaGEgZGUgJ2RhZG9zJy5OZXN0ZQ0KY2FzbywgYSBwbGFuaWxoYSBjaGFtYS1zZSBgZ3VqYXJhdGkgNWVkIHAyMzYgZnJhbmdvcyB0YWJlbGE3XzkueGxzeGAuDQoNCj4gNy4xOS4gRGVtYW5kYSBwb3IgZnJhbmdvcyBub3MgRXN0YWRvcyBVbmlkb3MsIDE5NjAtMTk4Mi4gUGFyYSBlc3R1ZGFyDQo+IG8gY29uc3VtbyBwZXIgY2FwaXRhIGRlIGZyYW5nbyBub3MgRXN0YWRvcyBVbmlkb3MsIHVzZSBvcyBkYWRvcyBkYQ0KPiBUYWJlbGEgNy45LCBlbSBxdWUgWSA9IGNvbnN1bW8gcGVyIGNhcGl0YSBkZSBmcmFuZ28gZW0gbGlicmFzIChwZXNvKQ0KPiBYMj0gcmVuZGEgcmVhbCBkaXNwb27DrXZlbCBwZXIgY2FwaXRhLCBlbSBcJCBYMz0gcHJlw6dvIHJlYWwgZG8gZnJhbmdvDQo+IG5vIHZhcmVqbywgZW0gY2VudGF2b3MgZGUgZMOzbGFyIHBvciBsaWJyYSAocGVzbykgwqIgWDQ9IHByZcOnbyByZWFsIGRhDQo+IGNhcm5lIHN1w61uYSBubyB2YXJlam8sIGVtIGNlbnRhdm9zIGRlIGTDs2xhciBwb3IgbGlicmEgKHBlc28pIMKiIFg1PQ0KPiBwcmXDp28gcmVhbCBkYSBjYXJuZSBib3ZpbmEgbm8gdmFyZWpvLCBlbSBjZW50YXZvcyBkZSBkw7NsYXIgcG9yIGxpYnJhDQo+IChwZXNvKSDCoiBYNj0gcHJlw6dvIHJlYWwgZG9zIHN1YnN0aXR1dG9zIGRhIGNhcm5lIGRlIGZyYW5nbywgZW0NCj4gY2VudGF2b3MgZGUgZMOzbGFyIHBvciBsaWJyYSAocGVzbyksIHF1ZSDDqSB1bWEgbcOpZGlhIHBvbmRlcmFkYSBkb3MNCj4gcHJlw6dvcyByZWFpcyBkYXMgY2FybmVzIHN1w61uYSBlIGJvdmluYSwgdXNhbmRvIGNvbW8gcGVzb3MgbyBjb25zdW1vDQo+IHJlbGF0aXZvIGRlIGNhZGEgdW1hIGRlc3NhcyBjYXJuZXMgZW0gcmVsYcOnw6NvIGFvIGNvbnN1bW8gdG90YWwgZGVsYXMuDQoNCkEgb3DDp8OjbyBkbyBkcHV0KCkgcG9kZSBzZXIgb2J0aWRhIGFiYWl4by4NCg0KYGBge3J9DQpkYWRvczwtDQpzdHJ1Y3R1cmUobGlzdChZRUFSID0gYygxOTYwLCAxOTYxLCAxOTYyLCAxOTYzLCAxOTY0LCAxOTY1LCAxOTY2LCANCjE5NjcsIDE5NjgsIDE5NjksIDE5NzAsIDE5NzEsIDE5NzIsIDE5NzMsIDE5NzQsIDE5NzUsIDE5NzYsIDE5NzcsIA0KMTk3OCwgMTk3OSwgMTk4MCwgMTk4MSwgMTk4MiksIFkgPSBjKDI3LjgsIDI5LjksIDI5LjgsIDMwLjgsIA0KMzEuMiwgMzMuMywgMzUuNiwgMzYuNCwgMzYuNywgMzguNCwgNDAuNCwgNDAuMywgNDEuOCwgNDAuNCwgNDAuNywgDQo0MC4xLCA0Mi43LCA0NC4xLCA0Ni43LCA1MC42LCA1MC4xLCA1MS43LCA1Mi45KSwgWDIgPSBjKDM5Ny41LCANCjQxMy4zLCA0MzkuMiwgNDU5LjcsIDQ5Mi45LCA1MjguNiwgNTYwLjMsIDYyNC42LCA2NjYuNCwgNzE3LjgsIA0KNzY4LjIsIDg0My4zLCA5MTEuNiwgOTMxLjEsIDEwMjEuNSwgMTE2NS45LCAxMzQ5LjYsIDE0NDkuNCwgMTU3NS41LCANCjE3NTkuMSwgMTk5NC4yLCAyMjU4LjEsIDI0NzguNyksIFgzID0gYyg0Mi4yLCAzOC4xLCA0MC4zLCAzOS41LCANCjM3LjMsIDM4LjEsIDM5LjMsIDM3LjgsIDM4LjQsIDQwLjEsIDM4LjYsIDM5LjgsIDM5LjcsIDUyLjEsIDQ4LjksIA0KNTguMywgNTcuOSwgNTYuNSwgNjMuNywgNjEuNiwgNTguOSwgNjYuNCwgNzAuNCksIFg0ID0gYyg1MC43LCANCjUyLCA1NCwgNTUuMywgNTQuNywgNjMuNywgNjkuOCwgNjUuOSwgNjQuNSwgNzAsIDczLjIsIDY3LjgsIDc5LjEsIA0KOTUuNCwgOTQuMiwgMTIzLjUsIDEyOS45LCAxMTcuNiwgMTMwLjksIDEyOS44LCAxMjgsIDE0MSwgMTY4LjINCiksIFg1ID0gYyg3OC4zLCA3OS4yLCA3OS4yLCA3OS4yLCA3Ny40LCA4MC4yLCA4MC40LCA4My45LCA4NS41LCANCjkzLjcsIDEwNi4xLCAxMDQuOCwgMTE0LCAxMjQuMSwgMTI3LjYsIDE0Mi45LCAxNDMuNiwgMTM5LjIsIDE2NS41LCANCjIwMy4zLCAyMTkuNiwgMjIxLjYsIDIzMi42KSwgWDYgPSBjKDY1LjgsIDY2LjksIDY3LjgsIDY5LjYsIDY4LjcsIA0KNzMuNiwgNzYuMywgNzcuMiwgNzguMSwgODQuNywgOTMuMywgODkuNywgMTAwLjcsIDExMy41LCAxMTUuMywgDQoxMzYuNywgMTM5LjIsIDEzMiwgMTMyLjEsIDE1NC40LCAxNzQuOSwgMTgwLjgsIDE4OS40KSksIHJvdy5uYW1lcyA9IGMoTkEsIA0KLTIzTCksIGNsYXNzID0gYygidGJsX2RmIiwgInRibCIsICJkYXRhLmZyYW1lIikpDQoNCmF0dGFjaChkYWRvcykNCmBgYA0KDQojIEVtIFINCg0KYGBge3IgZGFkb3N0aWJibGUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCg0KIyBUcmFuc2Zvcm1hIGVtIHRpYmJsZQ0KDQpkYWRvc190YmwgPC0gZGFkb3MgJT4lIA0KICBhc190aWJibGUNCg0KIyBWZXIgYSBlc3RydXR1cmEgZG9zIGRhZG9zDQoNCnN0cihkYWRvc190YmwpDQoNCmBgYA0KDQojIyBFc3RhdMOtc3RpY2FzIGRlc2NyaXRpdmFzDQoNCiMjIyBNZWRpZGFzIGRlIHBvc2nDp8OjbyAodGVuZMOqbmNpYSBjZW50cmFsKQ0KDQpgYGB7cn0NCiMgTcOpZGlhIGRlIFkNCm1pbmhhdmFyPC1kYWRvc190YmwkWQ0KbWVhbihtaW5oYXZhcikNCg0KIyBNZWRpYW5hDQptZWRpYW4obWluaGF2YXIpDQoNCiMgTW9kYQ0KdGFibGUobWluaGF2YXIpICU+JSANCiAgc29ydChkZWNyZWFzaW5nID0gVFJVRSkNCmBgYA0KDQojIyMgTWVkaWRhcyBkZSBkaXNwZXJzw6NvICh2YXJpYWJpbGlkYWRlKQ0KDQpgYGB7cn0NCiMgVmFyacOibmNpYQ0KdmFyKG1pbmhhdmFyKQ0KDQoNCiMgRGVzdmlvIHBhZHLDo28NCnNkKG1pbmhhdmFyKQ0KDQpgYGANCg0KIyMjIE1lZGlkYXMgZGUgcmVsYWNpb25hbWVudG8NCg0KYGBge3J9DQojIENvdmFyacOibmNpYQ0KbWluaGF2YXIyPC1kYWRvc190YmwkWDMgICMgWDMNCm1pbmhhdmFyMzwtZGFkb3NfdGJsJFg1ICAjIFg1DQpjb3YobWluaGF2YXIyLG1pbmhhdmFyMykNCmNvdihkYWRvc190YmwpDQoNCiMgQ29ycmVsYcOnw6NvDQpjb3IobWluaGF2YXIyLG1pbmhhdmFyMykNCmNvcihkYWRvc190YmwpDQpgYGANCg0KIyMjIFBlcmNlbnRpcw0KDQpgYGB7cn0NCiMgQ2FsY3VsYSBvIDI1wrAgcGVyY2VudGlsIC0gMSBRdWFydGlsDQoNCnF1YW50aWxlKG1pbmhhdmFyLCAwLjI1KQ0KIyBDYWxjdWxhIG8gNzXCsCBwZXJjZW50aWwgLSAzIFF1YXJ0aWwNCg0KcXVhbnRpbGUobWluaGF2YXIsIDAuNzUpDQpgYGANCg0KIyMjIFJlc3VtbyBkYXMgZXN0YXTDrXN0aWNhcw0KDQpgYGB7cn0NCnN1bW1hcnkoZGFkb3NfdGJsKQ0KDQpgYGANCg0KIyMjIFJlc3VtbyBjb20gYHNraW1yYA0KDQpgYGB7cn0NCmxpYnJhcnkoc2tpbXIpDQoNCiMgU3VtYXJpemEgb3MgZGFkb3MgY29tIG8gcGFjb3RlIHNraW1yDQoNCnNraW0oZGFkb3NfdGJsKQ0KYGBgDQoNCiMgRW0gUHl0aG9uDQoNCiMjIEVzdGF0w61zdGljYXMgZGVzY3JpdGl2YXMNCg0KYGBge3B5dGhvbiwgZXZhbD1GfQ0KaW1wb3J0IG51bXB5IGFzIG5wDQppbXBvcnQgcGFuZGFzIGFzIHBkDQojIENhcnJlZ2Egb3MgZGFkb3MNCg0KIyBwcmVjaXNlaSBpbnN0YWxhciBvcGVucHl4bCAocGFyYSB4bHN4KSBlIHhscmQgKHBhcmEgeGxzKQ0KZGYgPSBwZC5yZWFkX2V4Y2VsIChyJ2d1amFyYXRpIDVlZCBwMjM2IGZyYW5nb3MgdGFiZWxhN185Lnhsc3gnLCBzaGVldF9uYW1lPSdweScpDQpgYGANCg0KYGBge3B5dGhvbn0NCiNkYXRhX2FzX2RpY3Q9IHByaW50KGRmLnRvX2RpY3QoKSkNCiNkZiA9IHBkLkRhdGFGcmFtZS5mcm9tX2RpY3QoZGF0YV9hc19kaWN0KQ0KaW1wb3J0IHBhbmRhcyBhcyBwZA0KZGFkb3MgPSBwZC5EYXRhRnJhbWUuZnJvbV9kaWN0KHsnWUVBUic6IHswOiAxOTYwLCAxOiAxOTYxLCAyOiAxOTYyLCAzOiAxOTYzLCA0OiAxOTY0LCA1OiAxOTY1LCA2OiAxOTY2LCA3OiAxOTY3LCA4OiAxOTY4LCA5OiAxOTY5LCAxMDogMTk3MCwgMTE6IDE5NzEsIDEyOiAxOTcyLCAxMzogMTk3MywgMTQ6IDE5NzQsIDE1OiAxOTc1LCAxNjogMTk3NiwgMTc6IDE5NzcsIDE4OiAxOTc4LCAxOTogMTk3OSwgMjA6IDE5ODAsIDIxOiAxOTgxLCAyMjogMTk4Mn0sICdZJzogezA6IDI3LjgsIDE6IDI5LjksIDI6IDI5LjgsIDM6IDMwLjgsIDQ6IDMxLjIsIDU6IDMzLjMsIDY6IDM1LjYsIDc6IDM2LjQsIDg6IDM2LjcsIDk6IDM4LjQsIDEwOiA0MC40LCAxMTogNDAuMywgMTI6IDQxLjgsIDEzOiA0MC40LCAxNDogNDAuNywgMTU6IDQwLjEsIDE2OiA0Mi43LCAxNzogNDQuMSwgMTg6IDQ2LjcsIDE5OiA1MC42LCAyMDogNTAuMSwgMjE6IDUxLjcsIDIyOiA1Mi45fSwgJ1gyJzogezA6IDM5Ny41LCAxOiA0MTMuMywgMjogNDM5LjIsIDM6IDQ1OS43LCA0OiA0OTIuOSwgNTogNTI4LjYsIDY6IDU2MC4zLCA3OiA2MjQuNiwgODogNjY2LjQsIDk6IDcxNy44LCAxMDogNzY4LjIsIDExOiA4NDMuMywgMTI6IDkxMS42LCAxMzogOTMxLjEsIDE0OiAxMDIxLjUsIDE1OiAxMTY1LjksIDE2OiAxMzQ5LjYsIDE3OiAxNDQ5LjQsIDE4OiAxNTc1LjUsIDE5OiAxNzU5LjEsIDIwOiAxOTk0LjIsIDIxOiAyMjU4LjEsIDIyOiAyNDc4Ljd9LCAnWDMnOiB7MDogNDIuMiwgMTogMzguMSwgMjogNDAuMywgMzogMzkuNSwgNDogMzcuMywgNTogMzguMSwgNjogMzkuMywgNzogMzcuOCwgODogMzguNCwgOTogNDAuMSwgMTA6IDM4LjYsIDExOiAzOS44LCAxMjogMzkuNywgMTM6IDUyLjEsIDE0OiA0OC45LCAxNTogNTguMywgMTY6IDU3LjksIDE3OiA1Ni41LCAxODogNjMuNywgMTk6IDYxLjYsIDIwOiA1OC45LCAyMTogNjYuNCwgMjI6IDcwLjR9LCAnWDQnOiB7MDogNTAuNywgMTogNTIuMCwgMjogNTQuMCwgMzogNTUuMywgNDogNTQuNywgNTogNjMuNywgNjogNjkuOCwgNzogNjUuOSwgODogNjQuNSwgOTogNzAuMCwgMTA6IDczLjIsIDExOiA2Ny44LCAxMjogNzkuMSwgMTM6IDk1LjQsIDE0OiA5NC4yLCAxNTogMTIzLjUsIDE2OiAxMjkuOSwgMTc6IDExNy42LCAxODogMTMwLjksIDE5OiAxMjkuOCwgMjA6IDEyOC4wLCAyMTogMTQxLjAsIDIyOiAxNjguMn0sICdYNSc6IHswOiA3OC4zLCAxOiA3OS4yLCAyOiA3OS4yLCAzOiA3OS4yLCA0OiA3Ny40LCA1OiA4MC4yLCA2OiA4MC40LCA3OiA4My45LCA4OiA4NS41LCA5OiA5My43LCAxMDogMTA2LjEsIDExOiAxMDQuOCwgMTI6IDExNC4wLCAxMzogMTI0LjEsIDE0OiAxMjcuNiwgMTU6IDE0Mi45LCAxNjogMTQzLjYsIDE3OiAxMzkuMiwgMTg6IDE2NS41LCAxOTogMjAzLjMsIDIwOiAyMTkuNiwgMjE6IDIyMS42LCAyMjogMjMyLjZ9LCAnWDYnOiB7MDogNjUuOCwgMTogNjYuOSwgMjogNjcuOCwgMzogNjkuNiwgNDogNjguNywgNTogNzMuNiwgNjogNzYuMywgNzogNzcuMiwgODogNzguMSwgOTogODQuNywgMTA6IDkzLjMsIDExOiA4OS43LCAxMjogMTAwLjcsIDEzOiAxMTMuNSwgMTQ6IDExNS4zLCAxNTogMTM2LjcsIDE2OiAxMzkuMiwgMTc6IDEzMi4wLCAxODogMTMyLjEsIDE5OiAxNTQuNCwgMjA6IDE3NC45LCAyMTogMTgwLjgsIDIyOiAxODkuNH19KQ0KDQpkYWRvcw0KDQojIFZlIGEgZXN0cnV0dXJhIGRvcyBkYWRvcw0KDQpkYWRvcy5pbmZvKCkNCmBgYA0KDQojIyMgTWVkaWRhcyBkZSBwb3Npw6fDo28gKHRlbmTDqm5jaWEgY2VudHJhbCkNCg0KDQpgYGB7cHl0aG9ufQ0KIyBNw6lkaWENCmRhZG9zWydZJ10ubWVhbigpDQoNCiMgTWVkaWFuYQ0KZGFkb3NbJ1knXS5tZWRpYW4oKQ0KDQojIE1vZGENCmRhZG9zWydZJ10ubW9kZSgpDQoNCmBgYA0KDQoNCiMjIyBNZWRpZGFzIGRlIGRpc3BlcnPDo28gKHZhcmlhYmlsaWRhZGUpDQoNCmBgYHtweXRob259DQojIFZhcmnDom5jaWENCmRhZG9zWydZJ10udmFyKCkNCg0KDQojIERlc3ZpbyBwYWRyw6NvDQpkYWRvc1snWSddLnN0ZCgpDQpgYGANCg0KDQojIyMgTWVkaWRhcyBkZSByZWxhY2lvbmFtZW50bw0KDQpgYGB7cHl0aG9ufQ0KIyBDb3ZhcmnDom5jaWENCmRhZG9zLmNvdigpDQoNCiMgQ29ycmVsYcOnw6NvDQpkYWRvcy5jb3JyKCkNCg0KYGBgDQoNCg0KIyMjIFBlcmNlbnRpcw0KDQpgYGB7cHl0aG9ufQ0KaW1wb3J0IG51bXB5IGFzIG5wDQpxMSA9IG5wLnBlcmNlbnRpbGUoZGFkb3NbJ1knXSwgMjUpICMgMjV0aCBwZXJjZW50aWxlLCBleCAxIFF1YXJ0aWwuDQpxMQ0KcTMgPSBucC5wZXJjZW50aWxlKGRhZG9zWydZJ10sIDc1KSAjIDc1dGggcGVyY2VudGlsZSwgZXggMyBRdWFydGlsLg0KcTMNCmBgYA0KDQojIyMgUmVzdW1vIGRhcyBlc3RhdMOtc3RpY2FzDQoNCmBgYHtweXRob259DQpkYWRvcy5kZXNjcmliZSgpDQpgYGANCg0KIyMjIFJlc3VtbyBjb20gYHNraW1weWANCg0KYGBge3IsIGV2YWw9RkFMU0V9DQpsaWJyYXJ5KHJldGljdWxhdGUpDQpweV9pbnN0YWxsKCJza2ltcHkiKSAjIHBhcmEgaW5zdGFsYXIgcGFjb3RlDQpgYGANCg0KDQpgYGB7cHl0aG9uLCBldmFsPUZ9DQojIFNraW0NCmZyb20gc2tpbXB5IGltcG9ydCBza2ltDQpza2ltKGRhZG9zKQ0KYGBgDQoNCg0KIyBSZWZlcsOqbmNpYXMNCg0KR1VKQVJBVEksIERhbW9kYXIgTi47IFBPUlRFUiwgRGF3biBDLiBFY29ub21ldHJpYSBiw6FzaWNhLiA1LmVkLiBQb3J0bw0KQWxlZ3JlOiBBTUdIL0Jvb2ttYW4vTWNHcmF3LUhpbGwgZG8gQnJhc2lsLCAyMDExLiBOw7ptZXJvIGRlIGNoYW1hZGE6DQozMzAuMDE1MTk1IEc5NjllLjUgKENCQykgZSByZWN1cnNvIG9ubGluZSBJU0JOIDk3ODg1ODA1NTA1MTEgKE1pbmhhDQpCaWJsaW90ZWNhIC0gVUZNUykuDQo=