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. Microdados com R: exemplo da PNADCovid de Assuncao (2021). Campo Grande-MS,Brasil: RStudio/Rpubs, 2021. Disponível em http://rpubs.com/amrofi/survey_pnadcovid.

1 Introdução

Este é um script baseado em Assunção (2021). Ele utiliza o pacote COVIDIBGE (ASSUNÇÃO; HIDALGO, 2021) entre outros.

Como exposto nos vídeos mais teóricos, a PNADC apresenta uma amostragem complexa, e portanto o usuário não pode simplesmente usar os microdados sem adotar o devido plano amostral e seus pesos. O pacote COVIDIBGE facilitará o trabalho e O srvyr apresenta algumas vantagens como o de adequar os objetos de dados ao ambiente tidyverse. O usuário deve também olhar Figueiredo (2021) onde coloco mais informações sobre o

Será interessante o usuário já ter instalados os pacotes srvyr, tidyverse, COVIDIBGE, convey e survey.

Como as rotinas levam um certo tempo para baixar da web, rodar e gerar o rmd, fiz em script e salvei os datasets em rds, depois rodei as rotinas e gerei os objetos de saídas para colocar no rmd. Recomendo o leitor que rode cada script colocado, de modo a compreender o procedimento. Para comparar os resultados, olhar o post original de Assunção (2021) em <https://rpubs.com/gabriel-assuncao-ibge/covid>.

2 INSTALAR O PACOTE COVIDIBGE

install.packages("COVIDIBGE")

3 CARREGAR O PACOTE

# PACOTE -----
library(COVIDIBGE)
help("get_covid")

4 DADOS

O pacote puxa os dados, vincula o dicionário e os deflatores e incorpora design amostral.

dadosPNADCOVID19 <- get_covid(year = 2020, month = 5)
class(dadosPNADCOVID19)
# vou salvar para não precisar chamar novamente
saveRDS(dadosPNADCOVID19, file = "dados_2020_05.rds")

Uma vez que os dados estejam salvos em rds, poderei trabalhar a partir deste, de modo offline, que é mais rápido.

# para chamar do rds, fazer:
dadosPNADCOVID_2020_05 <- readRDS("D:/Documentos/disciplinas/econometria microdados/laboratorio microdados R/pnad_covid_gabrielassuncao/dados_2020_05.rds")

É possível chamar apenas algumas variáveis de modo a reduzir o tamanho do arquivo. Ele virá como objeto survey.design, já com deflação e pós-estratificação, o que facilita o trabalho. Da mesma forma, fiz no script separado e salvei rds. O leitor pode carregar o dataset da mesma forma que o chunk anterior, com readRDS, especificando o nome do arquivo “dados_2020_05_srv.rds”. Coloquei o sufixo srv para indicar que é um objeto survey.design.

# se quiser somente algumas variaveis ----
dadosPNADCOVID19 <- get_covid(year = 2020, month = 5, vars = c("C001", "C002"))
# o comando abaixo traz as caracteristicas do plano amostral
dadosPNADCOVID19
# vendo a classe do objeto: 'survey.design2' 'survey.design'
class(dadosPNADCOVID19)  # 'survey.design2' 'survey.design'
# vou salvar para não precisar chamar novamente
saveRDS(dadosPNADCOVID19, file = "dados_2020_05_srv.rds")

5 OPÇÃO DATA.FRAME E LABELS

Neste caso, o leitor pode chamar variáveis específicas (aqui estão “C001”,“C002”), e especificar design = FALSE para retornar um objeto dataframe (classes “tbl_df”,“tbl”,“data.frame”), e depois a opção de não colocar textos das variáveis qualitativas (labels=FALSE), e desta forma, no lugar dos textos teremos os números indicativos de cada categoria. Por exemplo, onde estava UF = Rondônia, aparecerá UF = 11.

# com desing false: retorna tibble design
dadosPNADCOVID19_brutos <- get_covid(year = 2020, month = 5, vars = c("C001", "C002"),
    design = FALSE)
class(dadosPNADCOVID19_brutos)  # 'tbl_df'     'tbl'        'data.frame'
dadosPNADCOVID19_brutos
saveRDS(dadosPNADCOVID19_brutos, file = "dados_2020_05_df.rds")

# sem labels
dadosPNADCOVID19_brutos_sem <- get_covid(year = 2020, month = 5, vars = c("C001",
    "C002"), labels = FALSE, design = FALSE)
# os níveis das categorias são representados por números: UF Rondônia = 11
dadosPNADCOVID19_brutos_sem
saveRDS(dadosPNADCOVID19_brutos_sem, file = "dados_2020_05_df_sem.rds")
dadosPNADCOVID19_brutos
dadosPNADCOVID19_brutos_sem

6 IMPORTAÇÃO OFFLINE

O leitor deve primeiro baixar os arquivos de https://ftp.ibge.gov.br/Trabalho_e_Rendimento/Pesquisa_Nacional_por_Amostra_de_Domicilios_PNAD_COVID19/ e colocar na mesma pasta deste rmarkdown. O .csv dos Microdados estará dentro de Dados e em formato zip: https://ftp.ibge.gov.br/Trabalho_e_Rendimento/Pesquisa_Nacional_por_Amostra_de_Domicilios_PNAD_COVID19/Microdados/Dados/. O arquivo .xls do dicionário estará em https://ftp.ibge.gov.br/Trabalho_e_Rendimento/Pesquisa_Nacional_por_Amostra_de_Domicilios_PNAD_COVID19/Microdados/Documentacao/. Descompactar antes e colocar no mesmo local deste rmd. Cuidado com o nome do arquivo, pois o IBGE costuma atualizar e alterar os nomes constando a identificação da atualização. A rotina covid_labeller já vai associar os dados com o dicionário e depois com o deflator, compondo um objeto tibble.

dadosPNADCOVID19 <- read_covid(microdata = "PNAD_COVID_052020.csv")
#
dadosPNADCOVID19 <- covid_labeller(data_covid = dadosPNADCOVID19, dictionary.file = "Dicionario_PNAD_COVID_052020_20210726.xls")
#
class(dadosPNADCOVID19)  # [1] 'tbl_df'     'tbl'        'data.frame'

Agora vai associar com deflator que foi baixado de https://ftp.ibge.gov.br/Trabalho_e_Rendimento/Pesquisa_Nacional_por_Amostra_de_Domicilios_PNAD_COVID19/Microdados/Documentacao/ e extraído o .zip para o mesmo local do rmd. Cuidado com o nome do arquivo!

dadosPNADCOVID19 <- covid_deflator(data_covid = dadosPNADCOVID19, deflator.file = "Deflator_PNAD_COVID_2020_11.xls")
class(dadosPNADCOVID19)  # 'tbl_df'     'tbl'        'data.frame'

Agora passa para survey.design onde incorpora plano amostral. Agora estamos prontos e o comando covid_design já fez a pós-estratificação. O leitor poderá verificar o design solicitando o objeto dadosPNADCOVID19. Salvarei em .rds para uso futuro, caso deseje.

dadosPNADCOVID19 <- covid_design(data_covid = dadosPNADCOVID19)
class(dadosPNADCOVID19)  # 'survey.design2' 'survey.design' 
#
dadosPNADCOVID19
# Stratified 1 - level Cluster Sampling design (with replacement) With (14906)
# clusters.  survey::postStratify(design = data_prior, strata = ~posest,
# population = popc.types) posso salvar para depois
saveRDS(dadosPNADCOVID19, file = "dados_2020_05_final.rds")

Para construir o dataset selecionando algumas variáveis dentro do dataset completo, posso especificar vars=variaveis_selecionadas. A classe do objeto é idêntica ao procedimento com todas as variáveis.

variaveis_selecionadas <- c("UF", "A002", "A003", "A004", "A005", "C001", "C002",
    "C003", "C008", "C01012")
dadosPNADCOVID19.var <- get_covid(year = 2020, month = 5, vars = variaveis_selecionadas)
class(dadosPNADCOVID19.var)
saveRDS(dadosPNADCOVID19.var, file = "dados_2020_05_var.rds")

7 ALTERNATIVA 2 - srvyr

Uma alternativa 2 é separar as variáveis do objeto completo dadosPNADCOVID19 após design, ou seja, já deflacionado e com pós-estratificação. A funcao get_covid faz tudo isso mas precisa de web estável. Rodar com o dataset completo deixará mais pesado! Para separação das variáveis específicas a partir do dadosPNADCOVID19 completo, preciso das variáveis:

names(dadosPNADCOVID19.var[["variables"]])
# [1] 'Ano' 'V1013' 'UF' 'V1008' [5] 'V1012' 'Estrato' 'UPA' 'V1030' [9]
# 'V1031' 'V1032' 'posest' 'A001' [13] 'A002' 'A003' 'A004' 'A005' [17] 'C001'
# 'C002' 'C003' 'C008' [21] 'C01012' 'ID_DOMICILIO' 'Habitual' 'Efetivo' [25]
# 'CO3'

Usarei o pacote srvyr para operar com pipe (ver https://rpubs.com/amrofi/microdados_pnadc_srvyr). Fazendo o as_survey, o objeto que era survey.design agora ficará também tbl_svy. Da mesma forma que anteriormente, salvarei o dataset completo como pnad_srvyr.rds. Ao transformar em tbl_svy, especifico o conjunto de variáveis desejados no objeto de lista variaveis e uso a função select para separar as variáveis de interesse. Salvei o dataset pnad_srvyr_select.rds.

library(srvyr)
#
pnad_srvyr <- srvyr::as_survey(dadosPNADCOVID19)
saveRDS(pnad_srvyr, file = "pnad_srvyr.rds")
class(pnad_srvyr)
# 'tbl_svy' 'survey.design2' 'survey.design' posso selecionar as colunas
# simplesmente fazendo
variaveis <- c("Ano", "V1013", "UF", "V1008", "V1012", "Estrato", "UPA", "V1030",
    "V1031", "V1032", "posest", "A001", "A002", "A003", "A004", "A005", "C001", "C002",
    "C003", "C008", "C01012", "ID_DOMICILIO", "Habitual", "Efetivo", "CO3")
# usar select() in dplyr
pnad_srvyr_select <- pnad_srvyr %>%
    select(variaveis)
class(pnad_srvyr_select)
saveRDS(pnad_srvyr_select, file = "pnad_srvyr_select.rds")

Verifique que estou com mais variáveis em variaveis do que em variaveis_selecionadas, pois a função get_covid contêm variáveis que se referem ao design e não foram incluídas em variaveis_selecionadas.

names(pnad_srvyr_select[["variables"]])
# [1] 'Ano' 'V1013' 'UF' 'V1008' 'V1012' [6] 'Estrato' 'UPA' 'V1030' 'V1031'
# 'V1032' [11] 'posest' 'A001' 'A002' 'A003' 'A004' [16] 'A005' 'C001' 'C002'
# 'C003' 'C008' [21] 'C01012' 'ID_DOMICILIO' 'Habitual' 'Efetivo' 'CO3'
# comparar com o names de pnad_srvyr
names(pnad_srvyr[["variables"]])  # retornam 117 variaveis

7.1 Comparação entre objetos

dadosPNADCOVID19.var <- readRDS("D:/Documentos/disciplinas/econometria microdados/laboratorio microdados R/pnad_covid_gabrielassuncao/dados_2020_05_var.rds")
# Manipulando as variáveis -----
pnad_srvyr_select <- readRDS("D:/Documentos/disciplinas/econometria microdados/laboratorio microdados R/pnad_covid_gabrielassuncao/pnad_srvyr_select.rds")
library(survey)
# compararei as duas abordagens: survey.design x 'tbl_svy'
totalrenda1 <- svytotal(x = ~C01012, design = dadosPNADCOVID19.var, na.rm = TRUE)
totalrenda2 <- svytotal(x = ~C01012, design = pnad_srvyr_select, na.rm = TRUE)
totalrenda1
            total         SE
C01012 1.9216e+11 2298127060
totalrenda2
            total         SE
C01012 1.9216e+11 2298127060
cv(object = totalrenda1)
           C01012
C01012 0.01195936
cv(object = totalrenda2)
           C01012
C01012 0.01195936
confint(object = totalrenda1)
              2.5 %       97.5 %
C01012 187657087758 196665580296
confint(object = totalrenda2)
              2.5 %       97.5 %
C01012 187657087758 196665580296
confint(object = totalrenda1, level = 0.99)
              0.5 %       99.5 %
C01012 186241751004 198080917050
confint(object = totalrenda2, level = 0.99)
              0.5 %       99.5 %
C01012 186241751004 198080917050
# resultados identicos, ok

8 CORINGA

O uso deste coringa auxiliará para a alteração de dados para outro mês, por exemplo. O uso das opções do chunck colocando cache=TRUE em chunks mais lentos, auxilia a otimizar o tempo de procedimento.

# usarei um coringa x para depois compor uma rotina iterativa entre arquivos
x <- dadosPNADCOVID19.var

9 VARIÁVEIS CATEGÓRICAS

Estimação dos totais populacionais de categorias, utilizando variáveis categóricas, como o sexo:

totalsexo <- svytotal(x = ~A003, design = x, na.rm = TRUE)
totalsexo
               total SE
A003Homem  103090474  0
A003Mulher 107778927  0

9.1 Total de mais de uma variável categórica no mesmo código, separando com o operador +:

totalsexoraca <- svytotal(x = ~A003 + A004, design = x, na.rm = TRUE)
totalsexoraca
                 total     SE
A003Homem    103090474      0
A003Mulher   107778927      0
A004Branca    92966520 457236
A004Preta     18485175 227872
A004Amarela    1667234  78960
A004Parda     96989351 423539
A004Indígena    682710  42740
A004Ignorado     78411  17457

9.2 Total resultante do cruzamento de duas ou mais variáveis categóricas, com a função interaction:

totalsexoEraca <- svytotal(x = ~interaction(A003, A004), design = x, na.rm = TRUE)
ftable(x = totalsexoEraca)
                                                  A            B
interaction(A003, A004)Homem.Branca    44608026.970   250154.323
interaction(A003, A004)Mulher.Branca   48358492.853   250845.009
interaction(A003, A004)Homem.Preta      9344035.193   128048.173
interaction(A003, A004)Mulher.Preta     9141139.996   131489.011
interaction(A003, A004)Homem.Amarela     812101.042    45751.346
interaction(A003, A004)Mulher.Amarela    855133.370    42373.693
interaction(A003, A004)Homem.Parda     47948839.576   235865.787
interaction(A003, A004)Mulher.Parda    49040510.903   232020.589
interaction(A003, A004)Homem.Indígena    336751.697    22757.907
interaction(A003, A004)Mulher.Indígena   345958.158    24812.989
interaction(A003, A004)Homem.Ignorado     40719.523     9571.067
interaction(A003, A004)Mulher.Ignorado    37691.720     9879.737

10 ESTIMANDO MÉDIAS

mediarenda <- svymean(x = ~C01012, design = x, na.rm = TRUE)
mediarenda
         mean     SE
C01012 2325.2 25.882

10.1 Cálculo dos coeficientes de variação e intervalos de confiança

cv(object = mediarenda)
           C01012
C01012 0.01113082
confint(object = mediarenda)
          2.5 %   97.5 %
C01012 2274.522 2375.977

11 ESTIMAÇÃO DE PROPORÇÕES

propsexo <- svymean(x = ~A003, design = x, na.rm = TRUE)
propsexo
              mean SE
A003Homem  0.48888  0
A003Mulher 0.51112  0

11.1 Proporção de mais de uma variável:

propsexoraca <- svymean(x = ~A003 + A004, design = x, na.rm = TRUE)
propsexoraca
                   mean     SE
A003Homem    0.48888304 0.0000
A003Mulher   0.51111696 0.0000
A004Branca   0.44087250 0.0022
A004Preta    0.08766172 0.0011
A004Amarela  0.00790648 0.0004
A004Parda    0.45994986 0.0020
A004Indígena 0.00323760 0.0002
A004Ignorado 0.00037185 0.0001

11.2 Cruzamento de duas ou mais variáveis com a função interaction:

propsexoEraca <- svymean(x = ~interaction(A003, A004), design = x, na.rm = TRUE)
ftable(x = propsexoEraca)
                                                  A            B
interaction(A003, A004)Homem.Branca    0.2115433854 0.0011862998
interaction(A003, A004)Mulher.Branca   0.2293291138 0.0011895752
interaction(A003, A004)Homem.Preta     0.0443119540 0.0006072392
interaction(A003, A004)Mulher.Preta    0.0433497698 0.0006235566
interaction(A003, A004)Homem.Amarela   0.0038512038 0.0002169653
interaction(A003, A004)Mulher.Amarela  0.0040552748 0.0002009476
interaction(A003, A004)Homem.Parda     0.2273864266 0.0011185397
interaction(A003, A004)Mulher.Parda    0.2325634287 0.0011003047
interaction(A003, A004)Homem.Indígena  0.0015969681 0.0001079242
interaction(A003, A004)Mulher.Indígena 0.0016406276 0.0001176699
interaction(A003, A004)Homem.Ignorado  0.0001931030 0.0000453886
interaction(A003, A004)Mulher.Ignorado 0.0001787444 0.0000468524

12 ESTIMAÇÃO DE RAZÕES (RATIOS) OU TAXAS

txafastquarentena <- svyratio(numerator = ~(C003 == "Estava em quarentena, isolamento, distanciamento social ou férias coletivas"),
    denominator = ~(C002 == "Sim"), design = x, na.rm = TRUE)
txafastquarentena
Ratio estimator: svyratio.survey.design2(numerator = ~(C003 == "Estava em quarentena, isolamento, distanciamento social ou férias coletivas"), 
    denominator = ~(C002 == "Sim"), design = x, na.rm = TRUE)
Ratios=
                                                                                      C002 == "Sim"
C003 == "Estava em quarentena, isolamento, distanciamento social ou férias coletivas"     0.8196935
SEs=
                                                                                      C002 == "Sim"
C003 == "Estava em quarentena, isolamento, distanciamento social ou férias coletivas"   0.003123121

12.1 Intervalos de confiança e coeficiente de variação:

cv(object = txafastquarentena)
                                                                                      C002 == "Sim"
C003 == "Estava em quarentena, isolamento, distanciamento social ou férias coletivas"   0.003810108
confint(object = txafastquarentena)
                                                                                                        2.5 %
C003 == "Estava em quarentena, isolamento, distanciamento social ou férias coletivas"/C002 == "Sim" 0.8135723
                                                                                                       97.5 %
C003 == "Estava em quarentena, isolamento, distanciamento social ou férias coletivas"/C002 == "Sim" 0.8258147

13 ESTIMAÇÃO DE MEDIANAS E QUANTIS

13.1 Mediana

medianarenda <- svyquantile(x = ~C01012, design = x, quantiles = 0.5, na.rm = TRUE)
medianarenda
$C01012
    quantile ci.2.5 ci.97.5       se
0.5     1500   1500    1597 24.74323

attr(,"hasci")
[1] TRUE
attr(,"class")
[1] "newsvyquantile"

13.2 Intervalo de confiança

medianarenda <- svyquantile(x = ~C01012, design = x, quantiles = 0.5, ci = TRUE,
    na.rm = TRUE)
medianarenda
$C01012
    quantile ci.2.5 ci.97.5       se
0.5     1500   1500    1597 24.74323

attr(,"hasci")
[1] TRUE
attr(,"class")
[1] "newsvyquantile"

13.3 Desvio-padrão e coeficiente de variação

SE(object = medianarenda)
  C01012 
24.74323 
cv(object = medianarenda)
    C01012 
0.01649548 

13.4 Múltiplos quantis

quantisrenda <- svyquantile(x = ~C01012, design = x, quantiles = c(0.1, 0.25, 0.5,
    0.75, 0.9), na.rm = TRUE)
quantisrenda
$C01012
     quantile ci.2.5 ci.97.5         se
0.1       600    600     650  12.754240
0.25     1045   1045    1050   1.275424
0.5      1500   1500    1597  24.743225
0.75     2500   2500    2700  51.016959
0.9      4500   4500    5000 127.542399

attr(,"hasci")
[1] TRUE
attr(,"class")
[1] "newsvyquantile"

14 ESTIMAÇÃO PARA VARIÁVEIS DE RENDIMENTO DEFLACIONADAS

14.1 Criar variável rendimento deflacionada

x$variables <- transform(x$variables, C01012_real = C01012 * Habitual)

14.2 Estimativa do total

totalrenda_real <- svytotal(x = ~C01012_real, design = x, na.rm = TRUE)
totalrenda_real
                 total         SE
C01012_real 1.9849e+11 2372672593

14.3 Média

mediarenda_real <- svymean(x = ~C01012_real, design = x, na.rm = TRUE)
mediarenda_real
              mean     SE
C01012_real 2401.8 26.721

15 ESTIMAÇÃO PARA UM DOMÍNIO

mediarendaM <- svymean(x = ~C01012, design = subset(x, A003 == "Mulher"), na.rm = TRUE)
mediarendaM
       mean     SE
C01012 2074 29.328

15.1 Condicionais com desigualdade

txafastquarentena25 <- svyratio(numerator = ~(C003 == "Estava em quarentena, isolamento, distanciamento social ou férias coletivas"),
    denominator = ~(C002 == "Sim"), design = subset(x, A002 >= 25), na.rm = TRUE)
txafastquarentena25
Ratio estimator: svyratio.survey.design2(numerator = ~(C003 == "Estava em quarentena, isolamento, distanciamento social ou férias coletivas"), 
    denominator = ~(C002 == "Sim"), design = subset(x, A002 >= 
        25), na.rm = TRUE)
Ratios=
                                                                                      C002 == "Sim"
C003 == "Estava em quarentena, isolamento, distanciamento social ou férias coletivas"     0.8131341
SEs=
                                                                                      C002 == "Sim"
C003 == "Estava em quarentena, isolamento, distanciamento social ou férias coletivas"    0.00330684

15.2 Utilizando múltiplas condições com os operadores lógicos & (“e”) e | (“ou”)

Esse caso serve para obter frequências relativas de cada nível (aqui utilizamos para o nível de instrução) para sexo = “Homem” e raça = “Parda”, com Idade (A002) “>30” anos.

nivelinstrHP30 <- svymean(x = ~A005, design = subset(x, A003 == "Homem" & A004 ==
    "Parda" & A002 > 30), na.rm = TRUE)
nivelinstrHP30
                                             mean     SE
A005Sem instrução                        0.070465 0.0014
A005Fundamental incompleto               0.344785 0.0032
A005Fundamental completa                 0.096410 0.0019
A005Médio incompleto                     0.072562 0.0017
A005Médio completo                       0.280868 0.0031
A005Superior incompleto                  0.032775 0.0012
A005Superior completo                    0.082917 0.0020
A005Pós-graduação, mestrado ou doutorado 0.019218 0.0009

15.3 Múltiplas análises em um mesmo domínio

Neste caso, faz-se uma subamostra usando a função subset.

dadosPNADCOVID19_mulheres <- subset(x, A003 == "Mulher")
dadosPNADCOVID19_mulheres
Stratified 1 - level Cluster Sampling design (with replacement)
With (14906) clusters.
subset(x, A003 == "Mulher")

16 ESTIMAÇÕES PARA VÁRIOS DOMÍNIOS

16.1 Estimação de quantidades em vários domínios mutuamente exclusivos

Homem x Mulher em cada nível de instrução:

freqSexoInstr <- svyby(formula = ~A003, by = ~A005, design = x, FUN = svymean, na.rm = TRUE)
freqSexoInstr

16.2 Frequência relativa de cada nível de instrução para cada sexo

freqInstrSexo <- svyby(formula = ~A005, by = ~A003, design = x, FUN = svymean, na.rm = TRUE)
freqInstrSexo

16.3 Renda média normalmente recebida em dinheiro (C01012) por Unidade da Federação (UF)

mediaRendaUF <- svyby(formula = ~C01012, by = ~UF, design = x, FUN = svymean, na.rm = TRUE)
mediaRendaUF
# farei tambem pelo objeto srvyr
library(srvyr)
mediaRendaUF2 <- pnad_srvyr_select %>%
    group_by(UF) %>%
    summarise(media = survey_mean(C01012, na.rm = T, vartype = "ci"))
mediaRendaUF2

16.4 Intervalo de confiança de (C01012) x (UF)

confint(object = mediaRendaUF)
                       2.5 %   97.5 %
Rondônia            1764.308 1974.814
Acre                1719.254 2017.290
Amazonas            1589.647 1926.892
Roraima             1793.859 2296.123
Pará                1622.586 1905.745
Amapá               1498.115 1876.096
Tocantins           1751.628 2043.755
Maranhão            1350.497 1501.071
Piauí               1514.803 1843.733
Ceará               1537.942 1755.738
Rio Grande do Norte 1654.700 2120.327
Paraíba             1623.194 1976.442
Pernambuco          1643.727 1979.794
Alagoas             1424.344 1685.165
Sergipe             1547.314 1930.720
Bahia               1427.324 1707.994
Minas Gerais        1917.897 2090.484
Espírito Santo      1987.506 2271.582
Rio de Janeiro      2632.150 2901.583
São Paulo           2735.098 3095.183
Paraná              2397.803 2659.572
Santa Catarina      2393.512 2551.635
Rio Grande do Sul   2379.729 2609.127
Mato Grosso do Sul  2124.166 2402.514
Mato Grosso         2122.413 2464.428
Goiás               1982.341 2223.232
Distrito Federal    3570.541 4451.600
library(ggplot2)
ggplot(as.data.frame(mediaRendaUF2), aes(x = UF, y = media)) + geom_point() + geom_errorbar(aes(ymin = media_low,
    ymax = media_upp), width = 0.2) + theme(axis.text.x = element_text(angle = 90)) +
    labs(title = "Rendimento Médio Domiciliar Estadual", caption = "Fonte: IBGE-PNADC, elaboração própria.")

16.5 Cruzamentos de variáveis categóricas com a função interaction

txafastquarentenaSexoRaca <- svyby(formula = ~(C003 == "Estava em quarentena, isolamento, distanciamento social ou férias coletivas"),
    denominator = ~(C002 == "Sim"), by = ~interaction(A003, A004), design = x, FUN = svyratio,
    vartype = "cv", na.rm = TRUE)
txafastquarentenaSexoRaca

17 GRÁFICOS PARA DADOS AMOSTRAIS via survey

17.1 Histograma

svyhist(formula = ~as.numeric(C008), design = x, main = "Histograma com densidade",
    xlab = "Número de Horas Normalmente Trabalhadas")

svyhist(formula = ~as.numeric(C008), design = x, freq = TRUE, main = "Histograma com frequências absolutas",
    xlab = "Número de Horas Normalmente Trabalhadas")

17.2 Boxplot

17.2.1 Sem usar grupos

svyboxplot(formula = C008 ~ 1, design = x, main = "Boxplot do Número de Horas Normalmente Trabalhadas")

17.2.2 Com grupos definidos por variável

svyboxplot(formula = C008 ~ A003, design = x, main = "Boxplot do Número de Horas Normalmente Trabalhadas por Sexo")

17.3 Boxplot com todos os outliers

A opção anterior plotava apenas os outliers extremos. Agora têm-se todos os outliers.

svyboxplot(formula = C008 ~ A003, design = x, all.outliers = TRUE, main = "Boxplot do Número de Horas Normalmente Trabalhadas por Sexo")

17.4 Gráficos de dispersão

17.4.1 Estilo bolha

svyplot(formula = C01012 ~ C008, design = x, style = "bubble", xlab = "Número de Horas Normalmente Trabalhadas",
    ylab = "Rendimento Normalmente Recebido em Dinheiro")

17.4.2 Estilo transparente

svyplot(formula = C01012 ~ C008, design = x, style = "transparent", xlab = "Número de Horas Normalmente Trabalhadas",
    ylab = "Rendimento Normalmente Recebido em Dinheiro")

18 MODELAGEM COM PACOTE survey

18.1 Testes de Hipóteses

18.1.1 Teste-t para médias de rendimentos entre sexos

svyttest(formula = C01012 ~ A003, design = x)

    Design-based t-test

data:  C01012 ~ A003
t = -19.732, df = 14078, p-value < 2.2e-16
alternative hypothesis: true difference in mean is not equal to 0
95 percent confidence interval:
 -481.7773 -394.7078
sample estimates:
difference in mean 
         -438.2425 

18.1.2 Teste-t para médias de horas trabalhadas (C008) entre quem trabalhou ou não (C001)

svyttest(formula = as.numeric(C008) ~ C001, design = x)

    Design-based t-test

data:  as.numeric(C008) ~ C001
t = -21.681, df = 14099, p-value < 2.2e-16
alternative hypothesis: true difference in mean is not equal to 0
95 percent confidence interval:
 -2.520826 -2.102821
sample estimates:
difference in mean 
         -2.311824 

18.2 Modelos lineares

18.2.1 Regressão linear

modeloLin <- svyglm(formula = C01012 ~ A005 + A004 + A002, design = x)
summary(object = modeloLin)

Call:
svyglm(formula = C01012 ~ A005 + A004 + A002, design = x)

Survey design:
survey::postStratify(design = data_prior, strata = ~posest, population = popc.types)

Coefficients:
                                          Estimate Std. Error t value Pr(>|t|)
(Intercept)                               -482.700     70.679  -6.830 8.87e-12
A005Fundamental incompleto                 484.605     37.630  12.878  < 2e-16
A005Fundamental completa                   823.335     43.204  19.057  < 2e-16
A005Médio incompleto                       997.392     44.743  22.291  < 2e-16
A005Médio completo                        1219.472     41.736  29.219  < 2e-16
A005Superior incompleto                   1738.514     59.486  29.225  < 2e-16
A005Superior completo                     3240.245     65.525  49.451  < 2e-16
A005Pós-graduação, mestrado ou doutorado  5845.701    228.253  25.611  < 2e-16
A004Preta                                 -549.097     38.149 -14.394  < 2e-16
A004Amarela                                127.499    181.763   0.701  0.48303
A004Parda                                 -510.387     29.768 -17.146  < 2e-16
A004Indígena                              -630.133    110.201  -5.718 1.10e-08
A004Ignorado                             -1235.340    438.179  -2.819  0.00482
A002                                        34.720      1.039  33.404  < 2e-16
                                            
(Intercept)                              ***
A005Fundamental incompleto               ***
A005Fundamental completa                 ***
A005Médio incompleto                     ***
A005Médio completo                       ***
A005Superior incompleto                  ***
A005Superior completo                    ***
A005Pós-graduação, mestrado ou doutorado ***
A004Preta                                ***
A004Amarela                                 
A004Parda                                ***
A004Indígena                             ***
A004Ignorado                             ** 
A002                                     ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

(Dispersion parameter for gaussian family taken to be 3468448)

Number of Fisher Scoring iterations: 2
confint(object = modeloLin)
                                               2.5 %     97.5 %
(Intercept)                               -621.23912 -344.16034
A005Fundamental incompleto                 410.84619  558.36401
A005Fundamental completa                   738.64937  908.02020
A005Médio incompleto                       909.68925 1085.09473
A005Médio completo                        1137.66482 1301.27944
A005Superior incompleto                   1621.91339 1855.11524
A005Superior completo                     3111.80835 3368.68191
A005Pós-graduação, mestrado ou doutorado  5398.29368 6293.10753
A004Preta                                 -623.87349 -474.32110
A004Amarela                               -228.78123  483.77846
A004Parda                                 -568.73569 -452.03814
A004Indígena                              -846.14206 -414.12314
A004Ignorado                             -2094.22933 -376.45146
A002                                        32.68255   36.75731

18.2.2 Regressão Logística

modeloLog <- svyglm(formula = C002 ~ A003 + A004 + A002, design = x, family = "binomial")

summary(object = modeloLog)

Call:
svyglm(formula = C002 ~ A003 + A004 + A002, design = x, family = "binomial")

Survey design:
survey::postStratify(design = data_prior, strata = ~posest, population = popc.types)

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)   1.006666   0.022279  45.185  < 2e-16 ***
A003Mulher    0.297449   0.015164  19.615  < 2e-16 ***
A004Preta    -0.112571   0.031502  -3.573 0.000354 ***
A004Amarela  -0.188918   0.098943  -1.909 0.056235 .  
A004Parda     0.010171   0.018533   0.549 0.583155    
A004Indígena -0.281620   0.136807  -2.059 0.039558 *  
A004Ignorado  2.161287   0.590344   3.661 0.000252 ***
A002          0.006435   0.000298  21.595  < 2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

(Dispersion parameter for binomial family taken to be 0.4859236)

Number of Fisher Scoring iterations: 5
confint(object = modeloLog)
                    2.5 %       97.5 %
(Intercept)   0.962996939  1.050335254
A003Mulher    0.267725574  0.327172653
A004Preta    -0.174319282 -0.050822352
A004Amarela  -0.382858513  0.005022564
A004Parda    -0.026156686  0.046498635
A004Indígena -0.549778851 -0.013461248
A004Ignorado  1.004137360  3.318437522
A002          0.005850794  0.007018923

19 ANÁLISE DE CONCENTRAÇÃO DE RENDA COM O PACOTE convey

O pacote convey requer uso da função convey_prep para adaptar o objeto do plano amostral do survey ao objeto que o pacote convey requer para as estimações (JACOB et al, 2021):

# para fazer o gini, precisa aplicar o convey_prep para usar o convey
library(convey)
dadosPNADCOVID19 <- convey_prep(design = x)
x <- dadosPNADCOVID19  # vou reatribuir
class(x)  # 'convey.design'  'survey.design2' 'survey.design' 
[1] "convey.design"  "survey.design2" "survey.design" 

19.1 Índice de Gini

giniHab <- svygini(formula = ~C01012, design = x, na.rm = TRUE)
giniHab
          gini     SE
C01012 0.47399 0.0043
cv(object = giniHab)
            C01012
C01012 0.009041141

19.2 Índice de Gini da renda normalmente recebida em dinheiro por Unidade da Federação:

giniUF <- svyby(formula = ~C01012, by = ~UF, design = x, FUN = svygini, na.rm = TRUE)
giniUF
confint(object = giniUF)
                        2.5 %    97.5 %
Rondônia            0.3852342 0.4296240
Acre                0.4084939 0.4695756
Amazonas            0.4470538 0.5061581
Roraima             0.4161803 0.5022714
Pará                0.4538041 0.5164472
Amapá               0.4282381 0.4931463
Tocantins           0.4189697 0.4732731
Maranhão            0.4232838 0.4634399
Piauí               0.4523957 0.5177020
Ceará               0.4438874 0.4898357
Rio Grande do Norte 0.4619424 0.5356331
Paraíba             0.4468704 0.5113244
Pernambuco          0.4529214 0.5223176
Alagoas             0.4106529 0.4745413
Sergipe             0.4606127 0.5300124
Bahia               0.4489249 0.5181641
Minas Gerais        0.4155318 0.4501937
Espírito Santo      0.4314812 0.4766895
Rio de Janeiro      0.4609274 0.4933300
São Paulo           0.4530767 0.4977770
Paraná              0.4201416 0.4555347
Santa Catarina      0.3700423 0.3957532
Rio Grande do Sul   0.4253530 0.4609469
Mato Grosso do Sul  0.3940728 0.4404393
Mato Grosso         0.3776868 0.4358869
Goiás               0.3962929 0.4409802
Distrito Federal    0.5073187 0.5414538

19.3 Curva de Lorenz

curvaLorenz <- svylorenz(formula = ~C01012, design = x, quantiles = seq(0, 1, 0.05),
    na.rm = TRUE)

20 REFLEXÕES

O arquivo tbl_svy fica mais pesado que o survey.design puro obtido pela get_covid. Uma vantagem do tbl_svy é que o formato tibble facilita gráficos em ggplot2 e manipulações do ambiente tidyverse. A desvantagem é que o arquivo é mais pesado que o formato survey.design puro. Vou continuar os procedimentos com o objeto dadosPNADCOVID19.var.

REFERÊNCIAS

ASSUNÇÃO, Gabriel. Análise de microdados da PNAD COVID19 Com os Pacotes COVIDIBGE e survey. RStudio/Rpubs, 2021. Disponível em: https://rpubs.com/gabriel-assuncao-ibge/covid.

ASSUNÇÃO, Gabriel; HIDALGO, Luna. COVIDIBGE: Downloading, Reading and Analysing PNAD COVID19 Microdata. 2021. R package version 0.1.7. Disponível em: https://CRAN.R-project.org/package=COVIDIBGE.

BARONE, Leonardo Sangali. PNAD Contínua no R com srvyr. RStudio/Rpubs, 2020. Disponível em: https://rpubs.com/leobarone/pnadc_srvyr.

BARONE, Leonardo Sangali. Cebrap.lab/CETIC - Introdução à Programação em R. Github, 2021. Disponível em: https://github.com/leobarone/cebrap_lab_cetic_programacao_r.

BRAGA, Douglas; ASSUNÇÃO, Gabriel. PNADcIBGE: Downloading, Reading and Analysing PNADC Microdata. R package version 0.6.5. 2021. Disponível em: https://CRAN.R-project.org/package=PNADcIBGE.

ELLIS, Greg Freedman; SCHNEIDER, Ben. srvyr: ‘dplyr’-Like Syntax for Summary Statistics of Survey Data. R package version 1.1.0. 2021. Disponível em: https://CRAN.R-project.org/package=srvyr.

FIGUEIREDO, Adriano Marcos Rodrigues. Econometria com Microdados da PNAD contínua de 2018 com R::PNADcIBGE, de BRAGA (2017). Campo Grande-MS,Brasil: RStudio/Rpubs, 2019. Disponível em http://rpubs.com/amrofi/pnadcibge_survey.

IBGE, PNAD Contínua - Pesquisa Nacional por Amostra de Domicílios Contínua: Microdados. Rio de Janeiro: IBGE, 2021. https://www.ibge.gov.br/estatisticas/downloads-estatisticas.html?caminho=Trabalho_e_Rendimento/Pesquisa_Nacional_por_Amostra_de_Domicilios_continua/Trimestral/Microdados/2021.

JACOB, Guilherme; PESSOA, Djalma; DAMICO, Anthony. Poverty and Inequality with Complex Survey Data. 2021.

LUMLEY, T. Survey: analysis of complex survey samples. R package version 3.35-1. 2019.

LUMLEY, T. Analysis of complex survey samples. Journal of Statistical Software, 9(1): 1-19. 2004.

PESSOA, Djalma; DAMICO, Anthony; JACOB, Guilherme. convey: Income Concentration Analysis with Complex Survey Samples. R package version 0.2.3. 2021.

NOTA:

Coloquei o tempo de execução abaixo, mas usei cache = TRUE em vários chunks de modo que o tempo total parece pequeno mas em vários chunks a rotina demora para executar, conforme seu micro.

end.time <- Sys.time()
time.taken <- end.time - start.time
time.taken
Time difference of 7.077375 secs

O primeiro procedimento levou (Time difference of) 7.640449 minutos, ou seja, considerando que usou os arquivos .rds previamente salvos.

LS0tDQp0aXRsZTogJ01pY3JvZGFkb3MgY29tIFI6IGV4ZW1wbG8gZGEgUE5BRENvdmlkIGRlIEFzc3VuY2FvICgyMDIxKScNCmF1dGhvcjogJ0Fkcmlhbm8gTWFyY29zIFJvZHJpZ3VlcyBGaWd1ZWlyZWRvLCAqZS1tYWlsOiBhZHJpYW5vLmZpZ3VlaXJlZG9AdWZtcy5icionDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy5EYXRlKCksICclZCAlQiAlWScpYCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICB0aGVtZTogZGVmYXVsdA0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IG5vDQogICAgZGZfcHJpbnQ6IHBhZ2VkDQogICAgZmlnX2NhcHRpb246IHllcw0KICBwZGZfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCiAgd29yZF9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KbGlua2NvbG9yOiBibHVlDQphYnN0cmFjdDogVGhpcyBpcyBhbiB1bmRlcmdyYWQgc3R1ZGVudCBsZXZlbCBpbnN0cnVjdGlvbiBmb3IgY2xhc3MgdXNlLg0KZ3JhcGhpY3M6IHllcw0KLS0tDQoNCmBgYHtyIGtuaXRyX2luaXQsIGVjaG89RkFMU0UsIGNhY2hlPUZBTFNFfQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkocm1hcmtkb3duKQ0KbGlicmFyeShybWRmb3JtYXRzKQ0Kc3RhcnQudGltZSA8LSBTeXMudGltZSgpDQojIyBHbG9iYWwgb3B0aW9ucw0Kb3B0aW9ucyhtYXgucHJpbnQ9IjEwMCIpDQpvcHRzX2NodW5rJHNldChlY2hvPVRSVUUsDQoJICAgICAgICAgICAgIGNhY2hlPUYsDQogICAgICAgICAgICAgICBwcm9tcHQ9RkFMU0UsDQogICAgICAgICAgICAgICB0aWR5PVRSVUUsDQogICAgICAgICAgICAgICBjb21tZW50PU5BLA0KICAgICAgICAgICAgICAgbWVzc2FnZT1GQUxTRSwNCiAgICAgICAgICAgICAgIHdhcm5pbmc9RkFMU0UpDQpvcHRzX2tuaXQkc2V0KHdpZHRoPTEwMCkNCmBgYA0KDQojIExpY2Vuw6dhIHsjTGljZW7Dp2EgLnVubnVtYmVyZWR9DQoNClRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQ3JlYXRpdmUgQ29tbW9ucyBBdHRyaWJ1dGlvbi1TaGFyZUFsaWtlIDQuMCBJbnRlcm5hdGlvbmFsIExpY2Vuc2UuIFRvIHZpZXcgYSBjb3B5IG9mIHRoaXMgbGljZW5zZSwgdmlzaXQgPGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL2J5LXNhLzQuMC8+IG9yIHNlbmQgYSBsZXR0ZXIgdG8gQ3JlYXRpdmUgQ29tbW9ucywgUE8gQm94IDE4NjYsIE1vdW50YWluIFZpZXcsIENBIDk0MDQyLCBVU0EuDQoNCiFbTGljZW5zZTogQ0MgQlktU0EgNC4wXShodHRwczovL21pcnJvcnMuY3JlYXRpdmVjb21tb25zLm9yZy9wcmVzc2tpdC9idXR0b25zLzg4eDMxL3BuZy9ieS1zYS5wbmcpe3dpZHRoPSIyNSUifQ0KDQojIENpdGHDp8OjbyB7I0NpdGHDp8OjbyAudW5udW1iZXJlZH0NCg0KU3VnZXN0w6NvIGRlIGNpdGHDp8OjbzogRklHVUVJUkVETywgQWRyaWFubyBNYXJjb3MgUm9kcmlndWVzLiBNaWNyb2RhZG9zIGNvbSBSOiBleGVtcGxvIGRhIFBOQURDb3ZpZCBkZSBBc3N1bmNhbyAoMjAyMSkuIENhbXBvIEdyYW5kZS1NUyxCcmFzaWw6IFJTdHVkaW8vUnB1YnMsIDIwMjEuIERpc3BvbsOtdmVsIGVtIDxodHRwOi8vcnB1YnMuY29tL2Ftcm9maS9zdXJ2ZXlfcG5hZGNvdmlkPi4NCg0KIyBJbnRyb2R1w6fDo28NCg0KRXN0ZSDDqSB1bSBzY3JpcHQgYmFzZWFkbyBlbSBBc3N1bsOnw6NvICgyMDIxKS4gRWxlIHV0aWxpemEgbyBwYWNvdGUgYENPVklESUJHRWAgKEFTU1VOw4fDg087IEhJREFMR08sIDIwMjEpIGVudHJlIG91dHJvcy4NCg0KQ29tbyBleHBvc3RvIG5vcyB2w61kZW9zIG1haXMgdGXDs3JpY29zLCBhIFBOQURDIGFwcmVzZW50YSB1bWEgYW1vc3RyYWdlbSBjb21wbGV4YSwgZSBwb3J0YW50byBvIHVzdcOhcmlvIG7Do28gcG9kZSBzaW1wbGVzbWVudGUgdXNhciBvcyBtaWNyb2RhZG9zIHNlbSBhZG90YXIgbyBkZXZpZG8gcGxhbm8gYW1vc3RyYWwgZSBzZXVzIHBlc29zLiBPIHBhY290ZSBgQ09WSURJQkdFYCBmYWNpbGl0YXLDoSBvIHRyYWJhbGhvIGUgTyBgc3J2eXJgIGFwcmVzZW50YSBhbGd1bWFzIHZhbnRhZ2VucyBjb21vIG8gZGUgYWRlcXVhciBvcyBvYmpldG9zIGRlIGRhZG9zIGFvIGFtYmllbnRlIHRpZHl2ZXJzZS4gTyB1c3XDoXJpbyBkZXZlIHRhbWLDqW0gb2xoYXIgRmlndWVpcmVkbyAoMjAyMSkgb25kZSBjb2xvY28gbWFpcyBpbmZvcm1hw6fDtWVzIHNvYnJlIG8NCg0KU2Vyw6EgaW50ZXJlc3NhbnRlIG8gdXN1w6FyaW8gasOhIHRlciBpbnN0YWxhZG9zIG9zIHBhY290ZXMgYHNydnlyYCwgYHRpZHl2ZXJzZWAsIGBDT1ZJRElCR0VgLCBgY29udmV5YCBlIGBzdXJ2ZXlgLg0KDQpDb21vIGFzIHJvdGluYXMgbGV2YW0gdW0gY2VydG8gdGVtcG8gcGFyYSBiYWl4YXIgZGEgd2ViLCByb2RhciBlIGdlcmFyIG8gcm1kLCBmaXogZW0gc2NyaXB0IGUgc2FsdmVpIG9zIGRhdGFzZXRzIGVtIHJkcywgZGVwb2lzIHJvZGVpIGFzIHJvdGluYXMgZSBnZXJlaSBvcyBvYmpldG9zIGRlIHNhw61kYXMgcGFyYSBjb2xvY2FyIG5vIHJtZC4gUmVjb21lbmRvIG8gbGVpdG9yIHF1ZSByb2RlIGNhZGEgc2NyaXB0IGNvbG9jYWRvLCBkZSBtb2RvIGEgY29tcHJlZW5kZXIgbyBwcm9jZWRpbWVudG8uIFBhcmEgY29tcGFyYXIgb3MgcmVzdWx0YWRvcywgb2xoYXIgbyBwb3N0IG9yaWdpbmFsIGRlIEFzc3Vuw6fDo28gKDIwMjEpIGVtIFw8PGh0dHBzOi8vcnB1YnMuY29tL2dhYnJpZWwtYXNzdW5jYW8taWJnZS9jb3ZpZD5cPi4NCg0KIyBJTlNUQUxBUiBPIFBBQ09URSBgQ09WSURJQkdFYA0KDQpgYGB7ciBJTlNUQUxBUiwgZXZhbD1GQUxTRX0NCmluc3RhbGwucGFja2FnZXMoIkNPVklESUJHRSIpDQpgYGANCg0KIyBDQVJSRUdBUiBPIFBBQ09URQ0KDQpgYGB7ciBjYXJyZWdhcGFjb3RlLGNhY2hlPVRSVUV9DQojIFBBQ09URSAtLS0tLQ0KbGlicmFyeShDT1ZJRElCR0UpDQpoZWxwKCJnZXRfY292aWQiKQ0KYGBgDQoNCiMgREFET1MNCg0KTyBwYWNvdGUgcHV4YSBvcyBkYWRvcywgdmluY3VsYSBvIGRpY2lvbsOhcmlvIGUgb3MgZGVmbGF0b3JlcyBlIGluY29ycG9yYSBkZXNpZ24gYW1vc3RyYWwuDQoNCmBgYHtyIGRhZG9zcGFjb3RlLGV2YWw9RkFMU0V9DQpkYWRvc1BOQURDT1ZJRDE5IDwtIGdldF9jb3ZpZCh5ZWFyPTIwMjAsIG1vbnRoPTUpDQpjbGFzcyhkYWRvc1BOQURDT1ZJRDE5KQ0KIyB2b3Ugc2FsdmFyIHBhcmEgbsOjbyBwcmVjaXNhciBjaGFtYXIgbm92YW1lbnRlDQpzYXZlUkRTKGRhZG9zUE5BRENPVklEMTksZmlsZSA9ICJkYWRvc18yMDIwXzA1LnJkcyIpDQpgYGANCg0KVW1hIHZleiBxdWUgb3MgZGFkb3MgZXN0ZWphbSBzYWx2b3MgZW0gcmRzLCBwb2RlcmVpIHRyYWJhbGhhciBhIHBhcnRpciBkZXN0ZSwgZGUgbW9kbyBvZmZsaW5lLCBxdWUgw6kgbWFpcyByw6FwaWRvLg0KICAgIA0KYGBge3IgY2hhbWFycmRzMSwgZXZhbD1GQUxTRX0NCiMgcGFyYSBjaGFtYXIgZG8gcmRzLCBmYXplcjoNCmRhZG9zUE5BRENPVklEXzIwMjBfMDUgPC0gcmVhZFJEUygiRDovRG9jdW1lbnRvcy9kaXNjaXBsaW5hcy9lY29ub21ldHJpYSBtaWNyb2RhZG9zL2xhYm9yYXRvcmlvIG1pY3JvZGFkb3MgUi9wbmFkX2NvdmlkX2dhYnJpZWxhc3N1bmNhby9kYWRvc18yMDIwXzA1LnJkcyIpDQpgYGANCg0Kw4kgcG9zc8OtdmVsIGNoYW1hciBhcGVuYXMgYWxndW1hcyB2YXJpw6F2ZWlzIGRlIG1vZG8gYSByZWR1emlyIG8gdGFtYW5obyBkbyBhcnF1aXZvLiBFbGUgdmlyw6EgY29tbyBvYmpldG8gc3VydmV5LmRlc2lnbiwgasOhIGNvbSBkZWZsYcOnw6NvIGUgcMOzcy1lc3RyYXRpZmljYcOnw6NvLCBvIHF1ZSBmYWNpbGl0YSBvIHRyYWJhbGhvLiBEYSBtZXNtYSBmb3JtYSwgZml6IG5vIHNjcmlwdCBzZXBhcmFkbyBlIHNhbHZlaSByZHMuIE8gbGVpdG9yIHBvZGUgY2FycmVnYXIgbyBkYXRhc2V0IGRhIG1lc21hIGZvcm1hIHF1ZSBvIGNodW5rIGFudGVyaW9yLCBjb20gYHJlYWRSRFNgLCBlc3BlY2lmaWNhbmRvIG8gbm9tZSBkbyBhcnF1aXZvICJkYWRvc18yMDIwXzA1X3Nydi5yZHMiLiBDb2xvcXVlaSBvIHN1Zml4byBzcnYgcGFyYSBpbmRpY2FyIHF1ZSDDqSB1bSBvYmpldG8gc3VydmV5LmRlc2lnbi4NCg0KYGBge3IsZXZhbD1GQUxTRX0NCiMgc2UgcXVpc2VyIHNvbWVudGUgYWxndW1hcyB2YXJpYXZlaXMgLS0tLQ0KZGFkb3NQTkFEQ09WSUQxOSA8LSBnZXRfY292aWQoeWVhcj0yMDIwLCBtb250aD01LCB2YXJzPWMoIkMwMDEiLCJDMDAyIikpDQojIG8gY29tYW5kbyBhYmFpeG8gdHJheiBhcyBjYXJhY3RlcmlzdGljYXMgZG8gcGxhbm8gYW1vc3RyYWwNCmRhZG9zUE5BRENPVklEMTkNCiMgdmVuZG8gYSBjbGFzc2UgZG8gb2JqZXRvOiAic3VydmV5LmRlc2lnbjIiICJzdXJ2ZXkuZGVzaWduIg0KY2xhc3MoZGFkb3NQTkFEQ09WSUQxOSkgIyAic3VydmV5LmRlc2lnbjIiICJzdXJ2ZXkuZGVzaWduIg0KIyB2b3Ugc2FsdmFyIHBhcmEgbsOjbyBwcmVjaXNhciBjaGFtYXIgbm92YW1lbnRlDQpzYXZlUkRTKGRhZG9zUE5BRENPVklEMTksZmlsZSA9ICJkYWRvc18yMDIwXzA1X3Nydi5yZHMiKQ0KYGBgDQoNCiMgT1DDh8ODTyBEQVRBLkZSQU1FIEUgTEFCRUxTDQoNCk5lc3RlIGNhc28sIG8gbGVpdG9yIHBvZGUgY2hhbWFyIHZhcmnDoXZlaXMgZXNwZWPDrWZpY2FzIChhcXVpIGVzdMOjbyAiQzAwMSIsIkMwMDIiKSwgZSBlc3BlY2lmaWNhciBgZGVzaWduID0gRkFMU0VgIHBhcmEgcmV0b3JuYXIgdW0gb2JqZXRvIGRhdGFmcmFtZSAoY2xhc3NlcyAidGJsX2RmIiwidGJsIiwiZGF0YS5mcmFtZSIpLCBlIGRlcG9pcyBhIG9ww6fDo28gZGUgbsOjbyBjb2xvY2FyIHRleHRvcyBkYXMgdmFyacOhdmVpcyBxdWFsaXRhdGl2YXMgKGBsYWJlbHM9RkFMU0VgKSwgZSBkZXN0YSBmb3JtYSwgbm8gbHVnYXIgZG9zIHRleHRvcyB0ZXJlbW9zIG9zIG7Dum1lcm9zIGluZGljYXRpdm9zIGRlIGNhZGEgY2F0ZWdvcmlhLiBQb3IgZXhlbXBsbywgb25kZSBlc3RhdmEgVUYgPSBSb25kw7RuaWEsIGFwYXJlY2Vyw6EgVUYgPSAxMS4NCg0KYGBge3IgZGZfbGFiZWxzLGNhY2hlPVRSVUUsZXZhbD1GQUxTRX0NCiMgY29tIGRlc2luZyBmYWxzZTogcmV0b3JuYSB0aWJibGUgZGVzaWduDQpkYWRvc1BOQURDT1ZJRDE5X2JydXRvcyA8LSBnZXRfY292aWQoeWVhcj0yMDIwLCBtb250aD01LCB2YXJzPWMoIkMwMDEiLCJDMDAyIiksIGRlc2lnbj1GQUxTRSkNCmNsYXNzKGRhZG9zUE5BRENPVklEMTlfYnJ1dG9zKSAjICJ0YmxfZGYiICAgICAidGJsIiAgICAgICAgImRhdGEuZnJhbWUiDQpkYWRvc1BOQURDT1ZJRDE5X2JydXRvcw0Kc2F2ZVJEUyhkYWRvc1BOQURDT1ZJRDE5X2JydXRvcyxmaWxlID0gImRhZG9zXzIwMjBfMDVfZGYucmRzIikNCg0KIyBzZW0gbGFiZWxzDQpkYWRvc1BOQURDT1ZJRDE5X2JydXRvc19zZW0gPC0gZ2V0X2NvdmlkKHllYXI9MjAyMCwgbW9udGg9NSwgdmFycz1jKCJDMDAxIiwiQzAwMiIpLCBsYWJlbHM9RkFMU0UsIGRlc2lnbj1GQUxTRSkNCiMgb3MgbsOtdmVpcyBkYXMgY2F0ZWdvcmlhcyBzw6NvIHJlcHJlc2VudGFkb3MgcG9yIG7Dum1lcm9zOiBVRiBSb25kw7RuaWEgPSAgMTENCmRhZG9zUE5BRENPVklEMTlfYnJ1dG9zX3NlbQ0Kc2F2ZVJEUyhkYWRvc1BOQURDT1ZJRDE5X2JydXRvc19zZW0sZmlsZSA9ICJkYWRvc18yMDIwXzA1X2RmX3NlbS5yZHMiKQ0KYGBgDQoNCmBgYHtyIGRhZG9zc2VtbGFiZWwsY2FjaGU9VFJVRX0NCmRhZG9zUE5BRENPVklEMTlfYnJ1dG9zDQpkYWRvc1BOQURDT1ZJRDE5X2JydXRvc19zZW0NCmBgYA0KIyBJTVBPUlRBw4fDg08gT0ZGTElORQ0KDQpPIGxlaXRvciBkZXZlIHByaW1laXJvIGJhaXhhciBvcyBhcnF1aXZvcyBkZSA8aHR0cHM6Ly9mdHAuaWJnZS5nb3YuYnIvVHJhYmFsaG9fZV9SZW5kaW1lbnRvL1Blc3F1aXNhX05hY2lvbmFsX3Bvcl9BbW9zdHJhX2RlX0RvbWljaWxpb3NfUE5BRF9DT1ZJRDE5Lz4gZSBjb2xvY2FyIG5hIG1lc21hIHBhc3RhIGRlc3RlIHJtYXJrZG93bi4gTyAuY3N2IGRvcyBNaWNyb2RhZG9zIGVzdGFyw6EgZGVudHJvIGRlIERhZG9zIGUgZW0gZm9ybWF0byB6aXA6IDxodHRwczovL2Z0cC5pYmdlLmdvdi5ici9UcmFiYWxob19lX1JlbmRpbWVudG8vUGVzcXVpc2FfTmFjaW9uYWxfcG9yX0Ftb3N0cmFfZGVfRG9taWNpbGlvc19QTkFEX0NPVklEMTkvTWljcm9kYWRvcy9EYWRvcy8+LiBPIGFycXVpdm8gLnhscyBkbyBkaWNpb27DoXJpbyBlc3RhcsOhIGVtIA0KPGh0dHBzOi8vZnRwLmliZ2UuZ292LmJyL1RyYWJhbGhvX2VfUmVuZGltZW50by9QZXNxdWlzYV9OYWNpb25hbF9wb3JfQW1vc3RyYV9kZV9Eb21pY2lsaW9zX1BOQURfQ09WSUQxOS9NaWNyb2RhZG9zL0RvY3VtZW50YWNhby8+LiBEZXNjb21wYWN0YXIgYW50ZXMgZSBjb2xvY2FyIG5vIG1lc21vIGxvY2FsIGRlc3RlIHJtZC4gQ3VpZGFkbyBjb20gbyBub21lIGRvIGFycXVpdm8sIHBvaXMgbyBJQkdFIGNvc3R1bWEgYXR1YWxpemFyIGUgYWx0ZXJhciBvcyBub21lcyBjb25zdGFuZG8gYSBpZGVudGlmaWNhw6fDo28gZGEgYXR1YWxpemHDp8Ojby4gQSByb3RpbmEgYGNvdmlkX2xhYmVsbGVyYCBqw6EgdmFpIGFzc29jaWFyIG9zIGRhZG9zIGNvbSBvIGRpY2lvbsOhcmlvIGUgZGVwb2lzIGNvbSBvIGRlZmxhdG9yLCBjb21wb25kbyB1bSBvYmpldG8gdGliYmxlLiAgICAgICAgIA0KDQpgYGB7ciwgZXZhbD1GfQ0KZGFkb3NQTkFEQ09WSUQxOSA8LSByZWFkX2NvdmlkKG1pY3JvZGF0YT0iUE5BRF9DT1ZJRF8wNTIwMjAuY3N2IikNCiMgDQpkYWRvc1BOQURDT1ZJRDE5IDwtIGNvdmlkX2xhYmVsbGVyKGRhdGFfY292aWQ9ZGFkb3NQTkFEQ09WSUQxOSwgZGljdGlvbmFyeS5maWxlPSJEaWNpb25hcmlvX1BOQURfQ09WSURfMDUyMDIwXzIwMjEwNzI2LnhscyIpDQojDQpjbGFzcyhkYWRvc1BOQURDT1ZJRDE5KSAjIFsxXSAidGJsX2RmIiAgICAgInRibCIgICAgICAgICJkYXRhLmZyYW1lIg0KYGBgDQoNCkFnb3JhIHZhaSBhc3NvY2lhciBjb20gZGVmbGF0b3IgcXVlIGZvaSBiYWl4YWRvIGRlDQo8aHR0cHM6Ly9mdHAuaWJnZS5nb3YuYnIvVHJhYmFsaG9fZV9SZW5kaW1lbnRvL1Blc3F1aXNhX05hY2lvbmFsX3Bvcl9BbW9zdHJhX2RlX0RvbWljaWxpb3NfUE5BRF9DT1ZJRDE5L01pY3JvZGFkb3MvRG9jdW1lbnRhY2FvLz4gZSBleHRyYcOtZG8gbyAuemlwIHBhcmEgbyBtZXNtbyBsb2NhbCBkbyBybWQuIEN1aWRhZG8gY29tIG8gbm9tZSBkbyBhcnF1aXZvIQ0KDQpgYGB7ciBkZWZsYXRvciwgZXZhbD1GQUxTRX0NCmRhZG9zUE5BRENPVklEMTkgPC0gY292aWRfZGVmbGF0b3IoZGF0YV9jb3ZpZD1kYWRvc1BOQURDT1ZJRDE5LCBkZWZsYXRvci5maWxlPSJEZWZsYXRvcl9QTkFEX0NPVklEXzIwMjBfMTEueGxzIikNCmNsYXNzKGRhZG9zUE5BRENPVklEMTkpICMgInRibF9kZiIgICAgICJ0YmwiICAgICAgICAiZGF0YS5mcmFtZSINCmBgYA0KDQpBZ29yYSBwYXNzYSBwYXJhIGBzdXJ2ZXkuZGVzaWduYCBvbmRlIGluY29ycG9yYSBwbGFubyBhbW9zdHJhbC4gQWdvcmEgZXN0YW1vcyBwcm9udG9zIGUgbyBjb21hbmRvIGBjb3ZpZF9kZXNpZ25gIGrDoSBmZXogYSBww7NzLWVzdHJhdGlmaWNhw6fDo28uIE8gbGVpdG9yIHBvZGVyw6EgdmVyaWZpY2FyIG8gZGVzaWduIHNvbGljaXRhbmRvIG8gb2JqZXRvIGBkYWRvc1BOQURDT1ZJRDE5YC4gU2FsdmFyZWkgZW0gLnJkcyBwYXJhIHVzbyBmdXR1cm8sIGNhc28gZGVzZWplLiAgICAgICANCg0KYGBge3IgZGVzaWduLCBldmFsPUZBTFNFfQ0KZGFkb3NQTkFEQ09WSUQxOSA8LSBjb3ZpZF9kZXNpZ24oZGF0YV9jb3ZpZD1kYWRvc1BOQURDT1ZJRDE5KQ0KY2xhc3MoZGFkb3NQTkFEQ09WSUQxOSkgIyAic3VydmV5LmRlc2lnbjIiICJzdXJ2ZXkuZGVzaWduIiANCiMNCmRhZG9zUE5BRENPVklEMTkNCiMgU3RyYXRpZmllZCAxIC0gbGV2ZWwgQ2x1c3RlciBTYW1wbGluZyBkZXNpZ24gKHdpdGggcmVwbGFjZW1lbnQpDQojIFdpdGggKDE0OTA2KSBjbHVzdGVycy4NCiMgc3VydmV5Ojpwb3N0U3RyYXRpZnkoZGVzaWduID0gZGF0YV9wcmlvciwgc3RyYXRhID0gfnBvc2VzdCwgcG9wdWxhdGlvbiA9IHBvcGMudHlwZXMpDQojDQojIHBvc3NvIHNhbHZhciBwYXJhIGRlcG9pcw0Kc2F2ZVJEUyhkYWRvc1BOQURDT1ZJRDE5LGZpbGUgPSAiZGFkb3NfMjAyMF8wNV9maW5hbC5yZHMiKQ0KYGBgDQoNClBhcmEgY29uc3RydWlyIG8gZGF0YXNldCBzZWxlY2lvbmFuZG8gYWxndW1hcyB2YXJpw6F2ZWlzIGRlbnRybyBkbyBkYXRhc2V0IGNvbXBsZXRvLCBwb3NzbyBlc3BlY2lmaWNhciBgdmFycz12YXJpYXZlaXNfc2VsZWNpb25hZGFzYC4gQSBjbGFzc2UgZG8gb2JqZXRvIMOpIGlkw6pudGljYSBhbyBwcm9jZWRpbWVudG8gY29tIHRvZGFzIGFzIHZhcmnDoXZlaXMuDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KdmFyaWF2ZWlzX3NlbGVjaW9uYWRhcyA8LSBjKCJVRiIsIkEwMDIiLCJBMDAzIiwiQTAwNCIsIkEwMDUiLCJDMDAxIiwiQzAwMiIsIkMwMDMiLCJDMDA4IiwiQzAxMDEyIikNCmRhZG9zUE5BRENPVklEMTkudmFyIDwtIGdldF9jb3ZpZCh5ZWFyPTIwMjAsIG1vbnRoPTUsIHZhcnM9dmFyaWF2ZWlzX3NlbGVjaW9uYWRhcykNCmNsYXNzKGRhZG9zUE5BRENPVklEMTkudmFyKQ0Kc2F2ZVJEUyhkYWRvc1BOQURDT1ZJRDE5LnZhcixmaWxlID0gImRhZG9zXzIwMjBfMDVfdmFyLnJkcyIpDQpgYGANCg0KIyBBTFRFUk5BVElWQSAyICAtIGBzcnZ5cmANCg0KVW1hIGFsdGVybmF0aXZhIDIgw6kgc2VwYXJhciBhcyB2YXJpw6F2ZWlzIGRvIG9iamV0byBjb21wbGV0byBgZGFkb3NQTkFEQ09WSUQxOWAgYXDDs3MgZGVzaWduLCBvdSBzZWphLCBqw6EgZGVmbGFjaW9uYWRvIGUgY29tIHDDs3MtZXN0cmF0aWZpY2HDp8Ojby4gQSBmdW5jYW8gYGdldF9jb3ZpZGAgZmF6IHR1ZG8gaXNzbyBtYXMgcHJlY2lzYSBkZSB3ZWIgZXN0w6F2ZWwuIFJvZGFyIGNvbSBvIGRhdGFzZXQgY29tcGxldG8gZGVpeGFyw6EgbWFpcyBwZXNhZG8hDQpQYXJhIHNlcGFyYcOnw6NvIGRhcyB2YXJpw6F2ZWlzIGVzcGVjw61maWNhcyBhIHBhcnRpciBkbyBgZGFkb3NQTkFEQ09WSUQxOWAgY29tcGxldG8sIHByZWNpc28gZGFzIHZhcmnDoXZlaXM6IA0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCm5hbWVzKGRhZG9zUE5BRENPVklEMTkudmFyW1sidmFyaWFibGVzIl1dKQ0KIyBbMV0gIkFubyIgICAgICAgICAgIlYxMDEzIiAgICAgICAgIlVGIiAgICAgICAgICAgIlYxMDA4IiAgICAgICANCiMgWzVdICJWMTAxMiIgICAgICAgICJFc3RyYXRvIiAgICAgICJVUEEiICAgICAgICAgICJWMTAzMCIgICAgICAgDQojIFs5XSAiVjEwMzEiICAgICAgICAiVjEwMzIiICAgICAgICAicG9zZXN0IiAgICAgICAiQTAwMSIgICAgICAgIA0KIyBbMTNdICJBMDAyIiAgICAgICAgICJBMDAzIiAgICAgICAgICJBMDA0IiAgICAgICAgICJBMDA1IiAgICAgICAgDQojIFsxN10gIkMwMDEiICAgICAgICAgIkMwMDIiICAgICAgICAgIkMwMDMiICAgICAgICAgIkMwMDgiICAgICAgICANCiMgWzIxXSAiQzAxMDEyIiAgICAgICAiSURfRE9NSUNJTElPIiAiSGFiaXR1YWwiICAgICAiRWZldGl2byIgICAgIA0KIyBbMjVdICJDTzMiDQpgYGANCg0KVXNhcmVpIG8gcGFjb3RlIGBzcnZ5cmAgcGFyYSBvcGVyYXIgY29tIHBpcGUgKHZlciA8aHR0cHM6Ly9ycHVicy5jb20vYW1yb2ZpL21pY3JvZGFkb3NfcG5hZGNfc3J2eXI+KS4gRmF6ZW5kbyBvIGBhc19zdXJ2ZXlgLCBvIG9iamV0byBxdWUgZXJhIGBzdXJ2ZXkuZGVzaWduYCBhZ29yYSBmaWNhcsOhIHRhbWLDqW0gYHRibF9zdnlgLiBEYSBtZXNtYSBmb3JtYSBxdWUgYW50ZXJpb3JtZW50ZSwgc2FsdmFyZWkgbyBkYXRhc2V0IGNvbXBsZXRvIGNvbW8gYHBuYWRfc3J2eXIucmRzYC4gQW8gdHJhbnNmb3JtYXIgZW0gIGB0Ymxfc3Z5YCwgZXNwZWNpZmljbyBvIGNvbmp1bnRvIGRlIHZhcmnDoXZlaXMgZGVzZWphZG9zIG5vIG9iamV0byBkZSBsaXN0YSBgdmFyaWF2ZWlzYCBlIHVzbyBhIGZ1bsOnw6NvIGBzZWxlY3RgIHBhcmEgc2VwYXJhciBhcyB2YXJpw6F2ZWlzIGRlIGludGVyZXNzZS4gIFNhbHZlaSBvIGRhdGFzZXQgYHBuYWRfc3J2eXJfc2VsZWN0LnJkc2AuICAgIA0KDQoNCmBgYHtyIHNydnlyLCBldmFsPUZBTFNFfQ0KbGlicmFyeShzcnZ5cikNCiMgDQpwbmFkX3NydnlyIDwtIHNydnlyOjphc19zdXJ2ZXkoZGFkb3NQTkFEQ09WSUQxOSkNCnNhdmVSRFMocG5hZF9zcnZ5cixmaWxlID0gInBuYWRfc3J2eXIucmRzIikNCmNsYXNzKHBuYWRfc3J2eXIpDQojICJ0Ymxfc3Z5IiAgICAgICAgInN1cnZleS5kZXNpZ24yIiAic3VydmV5LmRlc2lnbiIgDQojDQojIHBvc3NvIHNlbGVjaW9uYXIgYXMgY29sdW5hcyBzaW1wbGVzbWVudGUgZmF6ZW5kbw0KdmFyaWF2ZWlzPC1jKCJBbm8iLCJWMTAxMyIsIlVGIiwiVjEwMDgiLCAgICAgICANCiAgICAgICAgICAgICAiVjEwMTIiLCJFc3RyYXRvIiwiVVBBIiwiVjEwMzAiLCAgICAgICANCiAgICAgICAgICAgICAiVjEwMzEiLCJWMTAzMiIsInBvc2VzdCIsIkEwMDEiLCAgICAgICAgDQogICAgICAgICAgICAgIkEwMDIiLCJBMDAzIiwiQTAwNCIsIkEwMDUiLCAgICAgICAgDQogICAgICAgICAgICAgIkMwMDEiLCJDMDAyIiwiQzAwMyIsIkMwMDgiLCAgICAgICAgDQogICAgICAgICAgICAgIkMwMTAxMiIsIklEX0RPTUlDSUxJTyIsIkhhYml0dWFsIiwiRWZldGl2byIsICAgICANCiAgICAgICAgICAgICAiQ08zIikNCiMgdXNhciBzZWxlY3QoKSBpbiBkcGx5cg0KcG5hZF9zcnZ5cl9zZWxlY3Q8LXBuYWRfc3J2eXIlPiVzZWxlY3QodmFyaWF2ZWlzKQ0KY2xhc3MocG5hZF9zcnZ5cl9zZWxlY3QpDQpzYXZlUkRTKHBuYWRfc3J2eXJfc2VsZWN0LGZpbGUgPSAicG5hZF9zcnZ5cl9zZWxlY3QucmRzIikNCmBgYA0KDQpWZXJpZmlxdWUgcXVlIGVzdG91IGNvbSBtYWlzIHZhcmnDoXZlaXMgZW0gYHZhcmlhdmVpc2AgZG8gcXVlIGVtIGB2YXJpYXZlaXNfc2VsZWNpb25hZGFzYCwgcG9pcyBhIGZ1bsOnw6NvIGBnZXRfY292aWRgIGNvbnTDqm0gdmFyacOhdmVpcyBxdWUgc2UgcmVmZXJlbSBhbyBkZXNpZ24gZSBuw6NvIGZvcmFtIGluY2x1w61kYXMgZW0gYHZhcmlhdmVpc19zZWxlY2lvbmFkYXNgLg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCm5hbWVzKHBuYWRfc3J2eXJfc2VsZWN0W1sidmFyaWFibGVzIl1dKQ0KIyBbMV0gIkFubyIgICAgICAgICAgIlYxMDEzIiAgICAgICAgIlVGIiAgICAgICAgICAgIlYxMDA4IiAgICAgICAgIlYxMDEyIiAgICAgICANCiMgWzZdICJFc3RyYXRvIiAgICAgICJVUEEiICAgICAgICAgICJWMTAzMCIgICAgICAgICJWMTAzMSIgICAgICAgICJWMTAzMiIgICAgICAgDQojIFsxMV0gInBvc2VzdCIgICAgICAgIkEwMDEiICAgICAgICAgIkEwMDIiICAgICAgICAgIkEwMDMiICAgICAgICAgIkEwMDQiICAgICAgICANCiMgWzE2XSAiQTAwNSIgICAgICAgICAiQzAwMSIgICAgICAgICAiQzAwMiIgICAgICAgICAiQzAwMyIgICAgICAgICAiQzAwOCIgICAgICAgIA0KIyBbMjFdICJDMDEwMTIiICAgICAgICJJRF9ET01JQ0lMSU8iICJIYWJpdHVhbCIgICAgICJFZmV0aXZvIiAgICAgICJDTzMiIA0KIyBjb21wYXJhciBjb20gbyBuYW1lcyBkZSBwbmFkX3NydnlyDQojDQpuYW1lcyhwbmFkX3NydnlyW1sidmFyaWFibGVzIl1dKSAjIHJldG9ybmFtIDExNyB2YXJpYXZlaXMNCmBgYA0KDQojIyBDb21wYXJhw6fDo28gZW50cmUgb2JqZXRvcw0KDQpgYGB7ciBjb21wYXJhY2FvLCBjYWNoZT1UUlVFfQ0KZGFkb3NQTkFEQ09WSUQxOS52YXI8LSByZWFkUkRTKCJEOi9Eb2N1bWVudG9zL2Rpc2NpcGxpbmFzL2Vjb25vbWV0cmlhIG1pY3JvZGFkb3MvbGFib3JhdG9yaW8gbWljcm9kYWRvcyBSL3BuYWRfY292aWRfZ2FicmllbGFzc3VuY2FvL2RhZG9zXzIwMjBfMDVfdmFyLnJkcyIpDQojIE1hbmlwdWxhbmRvIGFzIHZhcmnDoXZlaXMgLS0tLS0NCnBuYWRfc3J2eXJfc2VsZWN0IDwtIHJlYWRSRFMoIkQ6L0RvY3VtZW50b3MvZGlzY2lwbGluYXMvZWNvbm9tZXRyaWEgbWljcm9kYWRvcy9sYWJvcmF0b3JpbyBtaWNyb2RhZG9zIFIvcG5hZF9jb3ZpZF9nYWJyaWVsYXNzdW5jYW8vcG5hZF9zcnZ5cl9zZWxlY3QucmRzIikNCmxpYnJhcnkoc3VydmV5KQ0KIyBjb21wYXJhcmVpIGFzIGR1YXMgYWJvcmRhZ2Vuczogc3VydmV5LmRlc2lnbiB4ICJ0Ymxfc3Z5Ig0KdG90YWxyZW5kYTEgPC0gc3Z5dG90YWwoeD1+QzAxMDEyLCBkZXNpZ249ZGFkb3NQTkFEQ09WSUQxOS52YXIsIG5hLnJtPVRSVUUpDQp0b3RhbHJlbmRhMiA8LSBzdnl0b3RhbCh4PX5DMDEwMTIsIGRlc2lnbj1wbmFkX3NydnlyX3NlbGVjdCwgbmEucm09VFJVRSkNCnRvdGFscmVuZGExDQp0b3RhbHJlbmRhMg0KY3Yob2JqZWN0PXRvdGFscmVuZGExKQ0KY3Yob2JqZWN0PXRvdGFscmVuZGEyKQ0KY29uZmludChvYmplY3Q9dG90YWxyZW5kYTEpDQpjb25maW50KG9iamVjdD10b3RhbHJlbmRhMikNCmNvbmZpbnQob2JqZWN0PXRvdGFscmVuZGExLCBsZXZlbD0uOTkpDQpjb25maW50KG9iamVjdD10b3RhbHJlbmRhMiwgbGV2ZWw9Ljk5KQ0KIyByZXN1bHRhZG9zIGlkZW50aWNvcywgb2sNCmBgYA0KDQojIENPUklOR0ENCg0KTyB1c28gZGVzdGUgY29yaW5nYSBhdXhpbGlhcsOhIHBhcmEgYSBhbHRlcmHDp8OjbyBkZSBkYWRvcyBwYXJhIG91dHJvIG3DqnMsIHBvciBleGVtcGxvLiBPIHVzbyBkYXMgb3DDp8O1ZXMgZG8gY2h1bmNrIGNvbG9jYW5kbyBjYWNoZT1UUlVFIGVtIGNodW5rcyBtYWlzIGxlbnRvcywgYXV4aWxpYSBhIG90aW1pemFyIG8gdGVtcG8gZGUgcHJvY2VkaW1lbnRvLiANCg0KYGBge3IgY29yaW5nYX0NCiMgdXNhcmVpIHVtIGNvcmluZ2EgeCBwYXJhIGRlcG9pcyBjb21wb3IgdW1hIHJvdGluYSBpdGVyYXRpdmEgZW50cmUgYXJxdWl2b3MNCng8LWRhZG9zUE5BRENPVklEMTkudmFyDQpgYGANCg0KIyBWQVJJw4FWRUlTIENBVEVHw5NSSUNBUw0KDQpFc3RpbWHDp8OjbyBkb3MgdG90YWlzIHBvcHVsYWNpb25haXMgZGUgY2F0ZWdvcmlhcywgdXRpbGl6YW5kbyB2YXJpw6F2ZWlzIGNhdGVnw7NyaWNhcywgY29tbyBvIHNleG86DQoNCmBgYHtyLCBjYWNoZT1UUlVFfQ0KdG90YWxzZXhvIDwtIHN2eXRvdGFsKHg9fkEwMDMsIGRlc2lnbj14LCBuYS5ybT1UUlVFKQ0KdG90YWxzZXhvDQpgYGANCg0KIyMgVG90YWwgZGUgbWFpcyBkZSB1bWEgdmFyacOhdmVsIGNhdGVnw7NyaWNhIG5vIG1lc21vIGPDs2RpZ28sIHNlcGFyYW5kbyBjb20gbyBvcGVyYWRvciBgK2A6DQoNCmBgYHtyLCBjYWNoZT1UUlVFfQ0KdG90YWxzZXhvcmFjYSA8LSBzdnl0b3RhbCh4PX5BMDAzK0EwMDQsIGRlc2lnbj14LCBuYS5ybT1UUlVFKQ0KdG90YWxzZXhvcmFjYQ0KYGBgDQoNCiMjIFRvdGFsIHJlc3VsdGFudGUgZG8gY3J1emFtZW50byBkZSBkdWFzIG91IG1haXMgdmFyacOhdmVpcyBjYXRlZ8OzcmljYXMsIGNvbSBhIGZ1bsOnw6NvIGBpbnRlcmFjdGlvbmA6DQoNCmBgYHtyLCBjYWNoZT1UUlVFfQ0KdG90YWxzZXhvRXJhY2EgPC0gc3Z5dG90YWwoeD1+aW50ZXJhY3Rpb24oQTAwMyxBMDA0KSwgZGVzaWduPXgsIG5hLnJtPVRSVUUpDQpmdGFibGUoeD10b3RhbHNleG9FcmFjYSkNCmBgYA0KDQojIEVTVElNQU5ETyBNw4lESUFTDQoNCmBgYHtyLCBjYWNoZT1UUlVFfQ0KbWVkaWFyZW5kYSA8LSBzdnltZWFuKHg9fkMwMTAxMiwgZGVzaWduPXgsIG5hLnJtPVRSVUUpDQptZWRpYXJlbmRhDQpgYGANCg0KIyMgQ8OhbGN1bG8gZG9zIGNvZWZpY2llbnRlcyBkZSB2YXJpYcOnw6NvIGUgaW50ZXJ2YWxvcyBkZSBjb25maWFuw6dhDQoNCmBgYHtyLCBjYWNoZT1UUlVFfQ0KY3Yob2JqZWN0PW1lZGlhcmVuZGEpDQpgYGANCg0KYGBge3IsIGNhY2hlPVRSVUV9DQpjb25maW50KG9iamVjdD1tZWRpYXJlbmRhKQ0KYGBgDQoNCiMgRVNUSU1Bw4fDg08gREUgUFJPUE9Sw4fDlUVTDQoNCmBgYHtyLCBjYWNoZT1UUlVFfQ0KcHJvcHNleG8gPC0gc3Z5bWVhbih4PX5BMDAzLCBkZXNpZ249eCwgbmEucm09VFJVRSkNCnByb3BzZXhvDQpgYGANCg0KIyMgUHJvcG9yw6fDo28gZGUgbWFpcyBkZSB1bWEgdmFyacOhdmVsOg0KDQpgYGB7ciwgY2FjaGU9VFJVRX0NCnByb3BzZXhvcmFjYSA8LSBzdnltZWFuKHg9fkEwMDMrQTAwNCwgZGVzaWduPXgsIG5hLnJtPVRSVUUpDQpwcm9wc2V4b3JhY2ENCmBgYA0KDQoNCiMjIENydXphbWVudG8gZGUgZHVhcyBvdSBtYWlzIHZhcmnDoXZlaXMgY29tIGEgZnVuw6fDo28gYGludGVyYWN0aW9uYDoNCg0KYGBge3IsIGNhY2hlPVRSVUV9DQpwcm9wc2V4b0VyYWNhIDwtIHN2eW1lYW4oeD1+aW50ZXJhY3Rpb24oQTAwMyxBMDA0KSwgZGVzaWduPXgsIG5hLnJtPVRSVUUpDQpmdGFibGUoeD1wcm9wc2V4b0VyYWNhKQ0KYGBgDQoNCiMgRVNUSU1Bw4fDg08gREUgUkFaw5VFUyAoX1JBVElPU18pIE9VIFRBWEFTDQoNCmBgYHtyLCBjYWNoZT1UUlVFfQ0KdHhhZmFzdHF1YXJlbnRlbmEgPC0gDQogIHN2eXJhdGlvKG51bWVyYXRvcj1+KEMwMDM9PSJFc3RhdmEgZW0gcXVhcmVudGVuYSwgaXNvbGFtZW50bywgZGlzdGFuY2lhbWVudG8gc29jaWFsIG91IGbDqXJpYXMgY29sZXRpdmFzIiksIGRlbm9taW5hdG9yPX4oQzAwMj09IlNpbSIpLCBkZXNpZ249eCwgbmEucm09VFJVRSkNCnR4YWZhc3RxdWFyZW50ZW5hDQpgYGANCg0KIyMgSW50ZXJ2YWxvcyBkZSBjb25maWFuw6dhIGUgY29lZmljaWVudGUgZGUgdmFyaWHDp8OjbzoNCg0KYGBge3IsIGNhY2hlPVRSVUV9DQpjdihvYmplY3Q9dHhhZmFzdHF1YXJlbnRlbmEpDQpgYGANCg0KYGBge3IsIGNhY2hlPVRSVUV9DQpjb25maW50KG9iamVjdD10eGFmYXN0cXVhcmVudGVuYSkNCmBgYA0KDQojIEVTVElNQcOHw4NPIERFIE1FRElBTkFTIEUgUVVBTlRJUw0KDQojIyBNZWRpYW5hDQoNCmBgYHtyLCBjYWNoZT1UUlVFfQ0KbWVkaWFuYXJlbmRhIDwtIHN2eXF1YW50aWxlKHg9fkMwMTAxMiwgZGVzaWduPXgsIHF1YW50aWxlcz0uNSwgbmEucm09VFJVRSkNCm1lZGlhbmFyZW5kYQ0KYGBgDQoNCiMjIEludGVydmFsbyBkZSBjb25maWFuw6dhDQoNCmBgYHtyLCBjYWNoZT1UUlVFfQ0KbWVkaWFuYXJlbmRhIDwtIHN2eXF1YW50aWxlKHg9fkMwMTAxMiwgZGVzaWduPXgsIHF1YW50aWxlcz0uNSwgY2k9VFJVRSwgbmEucm09VFJVRSkNCm1lZGlhbmFyZW5kYQ0KYGBgDQoNCiMjIERlc3Zpby1wYWRyw6NvIGUgY29lZmljaWVudGUgZGUgdmFyaWHDp8Ojbw0KDQpgYGB7ciwgY2FjaGU9VFJVRX0NClNFKG9iamVjdD1tZWRpYW5hcmVuZGEpDQpgYGANCg0KYGBge3IsIGNhY2hlPVRSVUV9DQpjdihvYmplY3Q9bWVkaWFuYXJlbmRhKQ0KYGBgDQoNCiMjIE3Dumx0aXBsb3MgcXVhbnRpcw0KDQpgYGB7ciwgY2FjaGU9VFJVRX0NCnF1YW50aXNyZW5kYSA8LSBzdnlxdWFudGlsZSh4PX5DMDEwMTIsIGRlc2lnbj14LCBxdWFudGlsZXM9YyguMSwuMjUsLjUsLjc1LC45KSwgbmEucm09VFJVRSkNCnF1YW50aXNyZW5kYQ0KYGBgDQoNCiMgRVNUSU1Bw4fDg08gUEFSQSBWQVJJw4FWRUlTIERFIFJFTkRJTUVOVE8gREVGTEFDSU9OQURBUw0KDQojIyBDcmlhciB2YXJpw6F2ZWwgcmVuZGltZW50byBkZWZsYWNpb25hZGENCg0KYGBge3IsIGNhY2hlPVRSVUV9DQp4JHZhcmlhYmxlcyA8LSB0cmFuc2Zvcm0oeCR2YXJpYWJsZXMsIEMwMTAxMl9yZWFsPUMwMTAxMipIYWJpdHVhbCkNCmBgYA0KDQojIyBFc3RpbWF0aXZhIGRvIHRvdGFsDQoNCmBgYHtyLCBjYWNoZT1UUlVFfQ0KdG90YWxyZW5kYV9yZWFsIDwtIHN2eXRvdGFsKHg9fkMwMTAxMl9yZWFsLCBkZXNpZ249eCwgbmEucm09VFJVRSkNCnRvdGFscmVuZGFfcmVhbA0KYGBgDQoNCiMjIE3DqWRpYSANCg0KYGBge3IsIGNhY2hlPVRSVUV9DQptZWRpYXJlbmRhX3JlYWwgPC0gc3Z5bWVhbih4PX5DMDEwMTJfcmVhbCwgZGVzaWduPXgsIG5hLnJtPVRSVUUpDQptZWRpYXJlbmRhX3JlYWwNCmBgYA0KDQojIEVTVElNQcOHw4NPIFBBUkEgVU0gRE9Nw41OSU8NCg0KYGBge3IsIGNhY2hlPVRSVUV9DQptZWRpYXJlbmRhTSA8LSBzdnltZWFuKHg9fkMwMTAxMiwgZGVzaWduPXN1YnNldCh4LCBBMDAzPT0iTXVsaGVyIiksIG5hLnJtPVRSVUUpDQptZWRpYXJlbmRhTQ0KYGBgDQoNCiMjIENvbmRpY2lvbmFpcyBjb20gZGVzaWd1YWxkYWRlDQoNCmBgYHtyLCBjYWNoZT1UUlVFfQ0KdHhhZmFzdHF1YXJlbnRlbmEyNSA8LSBzdnlyYXRpbyhudW1lcmF0b3I9fihDMDAzPT0iRXN0YXZhIGVtIHF1YXJlbnRlbmEsIGlzb2xhbWVudG8sIGRpc3RhbmNpYW1lbnRvIHNvY2lhbCBvdSBmw6lyaWFzIGNvbGV0aXZhcyIpLCBkZW5vbWluYXRvcj1+KEMwMDI9PSJTaW0iKSwgZGVzaWduPXN1YnNldCh4LCBBMDAyPj0yNSksIG5hLnJtPVRSVUUpDQp0eGFmYXN0cXVhcmVudGVuYTI1DQpgYGANCg0KIyMgVXRpbGl6YW5kbyBtw7psdGlwbGFzIGNvbmRpw6fDtWVzIGNvbSBvcyBvcGVyYWRvcmVzIGzDs2dpY29zIGAmYCAo4oCcZeKAnSkgZSBgfGAgKOKAnG914oCdKQ0KDQpFc3NlIGNhc28gc2VydmUgcGFyYSBvYnRlciBmcmVxdcOqbmNpYXMgcmVsYXRpdmFzIGRlIGNhZGEgbsOtdmVsIChhcXVpIHV0aWxpemFtb3MgcGFyYSBvIG7DrXZlbCBkZSBpbnN0cnXDp8OjbykgcGFyYSBzZXhvID0gIkhvbWVtIiBlIHJhw6dhID0gIlBhcmRhIiwgY29tIElkYWRlIChBMDAyKSAiPjMwIiBhbm9zLg0KDQpgYGB7ciwgY2FjaGU9VFJVRX0NCm5pdmVsaW5zdHJIUDMwIDwtIHN2eW1lYW4oeD1+QTAwNSwgZGVzaWduPXN1YnNldCh4LCBBMDAzPT0iSG9tZW0iICYgQTAwND09IlBhcmRhIiAmIEEwMDI+MzApLCBuYS5ybT1UUlVFKQ0Kbml2ZWxpbnN0ckhQMzANCmBgYA0KDQojIyBNw7psdGlwbGFzIGFuw6FsaXNlcyBlbSB1bSBtZXNtbyBkb23DrW5pbw0KDQpOZXN0ZSBjYXNvLCBmYXotc2UgdW1hIHN1YmFtb3N0cmEgdXNhbmRvIGEgZnVuw6fDo28gYHN1YnNldGAuDQoNCmBgYHtyLCBjYWNoZT1UUlVFfQ0KZGFkb3NQTkFEQ09WSUQxOV9tdWxoZXJlcyA8LSBzdWJzZXQoeCwgQTAwMz09Ik11bGhlciIpDQpkYWRvc1BOQURDT1ZJRDE5X211bGhlcmVzDQpgYGANCg0KIyBFU1RJTUHDh8OVRVMgUEFSQSBWw4FSSU9TIERPTcONTklPUw0KDQojIyBFc3RpbWHDp8OjbyBkZSBxdWFudGlkYWRlcyBlbSB2w6FyaW9zIGRvbcOtbmlvcyBtdXR1YW1lbnRlIGV4Y2x1c2l2b3MNCg0KSG9tZW0geCBNdWxoZXIgZW0gY2FkYSBuw612ZWwgZGUgaW5zdHJ1w6fDo286DQoNCmBgYHtyLCBjYWNoZT1UUlVFfQ0KZnJlcVNleG9JbnN0ciA8LSBzdnlieShmb3JtdWxhPX5BMDAzLCBieT1+QTAwNSwgZGVzaWduPXgsIEZVTj1zdnltZWFuLCBuYS5ybT1UUlVFKQ0KZnJlcVNleG9JbnN0cg0KYGBgDQoNCiMjIEZyZXF1w6puY2lhIHJlbGF0aXZhIGRlIGNhZGEgbsOtdmVsIGRlIGluc3RydcOnw6NvIHBhcmEgY2FkYSBzZXhvDQoNCmBgYHtyLCBjYWNoZT1UUlVFfQ0KZnJlcUluc3RyU2V4byA8LSBzdnlieShmb3JtdWxhPX5BMDA1LCBieT1+QTAwMywgZGVzaWduPXgsIEZVTj1zdnltZWFuLCBuYS5ybT1UUlVFKQ0KZnJlcUluc3RyU2V4bw0KYGBgDQoNCiMjIFJlbmRhIG3DqWRpYSBub3JtYWxtZW50ZSByZWNlYmlkYSBlbSBkaW5oZWlybyAoQzAxMDEyKSBwb3IgVW5pZGFkZSBkYSBGZWRlcmHDp8OjbyAoVUYpDQoNCmBgYHtyLCBjYWNoZT1UUlVFfQ0KbWVkaWFSZW5kYVVGIDwtIHN2eWJ5KGZvcm11bGE9fkMwMTAxMiwgYnk9flVGLCBkZXNpZ249eCwgRlVOPXN2eW1lYW4sIG5hLnJtPVRSVUUpDQptZWRpYVJlbmRhVUYNCg0KYGBgDQoNCmBgYHtyLCBjYWNoZT1UUlVFfQ0KIyBmYXJlaSB0YW1iZW0gcGVsbyBvYmpldG8gc3J2eXINCmxpYnJhcnkoc3J2eXIpDQptZWRpYVJlbmRhVUYyIDwtIHBuYWRfc3J2eXJfc2VsZWN0ICU+JQ0KICAgIGdyb3VwX2J5KFVGKSAlPiUNCiAgICBzdW1tYXJpc2UobWVkaWEgPSBzdXJ2ZXlfbWVhbihDMDEwMTIsIG5hLnJtID0gVCwgdmFydHlwZSA9ICJjaSIpKQ0KbWVkaWFSZW5kYVVGMg0KYGBgDQoNCiMjIEludGVydmFsbyBkZSBjb25maWFuw6dhIGRlIChDMDEwMTIpIHggKFVGKQ0KDQpgYGB7ciwgY2FjaGU9VFJVRX0NCmNvbmZpbnQob2JqZWN0PW1lZGlhUmVuZGFVRikNCmBgYA0KDQpgYGB7ciwgY2FjaGU9VFJVRX0NCmxpYnJhcnkoZ2dwbG90MikNCmdncGxvdChhcy5kYXRhLmZyYW1lKG1lZGlhUmVuZGFVRjIpLCBhZXMoeCA9IFVGLCB5ID0gbWVkaWEpKSArIGdlb21fcG9pbnQoKSArIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBtZWRpYV9sb3csDQogICAgeW1heCA9IG1lZGlhX3VwcCksIHdpZHRoID0gMC4yKSArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArDQogICAgbGFicyh0aXRsZSA9ICJSZW5kaW1lbnRvIE3DqWRpbyBEb21pY2lsaWFyIEVzdGFkdWFsIiwgY2FwdGlvbiA9ICJGb250ZTogSUJHRS1QTkFEQywgZWxhYm9yYcOnw6NvIHByw7NwcmlhLiIpDQpgYGANCg0KIyMgQ3J1emFtZW50b3MgZGUgdmFyacOhdmVpcyBjYXRlZ8OzcmljYXMgY29tIGEgZnVuw6fDo28gYGludGVyYWN0aW9uYA0KDQpgYGB7ciwgY2FjaGU9VFJVRX0NCnR4YWZhc3RxdWFyZW50ZW5hU2V4b1JhY2EgPC0gc3Z5YnkoZm9ybXVsYT1+KEMwMDM9PSJFc3RhdmEgZW0gcXVhcmVudGVuYSwgaXNvbGFtZW50bywgZGlzdGFuY2lhbWVudG8gc29jaWFsIG91IGbDqXJpYXMgY29sZXRpdmFzIiksIGRlbm9taW5hdG9yPX4oQzAwMj09IlNpbSIpLCBieT1+aW50ZXJhY3Rpb24oQTAwMyxBMDA0KSwgZGVzaWduPXgsIEZVTj1zdnlyYXRpbywgdmFydHlwZT0iY3YiLCBuYS5ybT1UUlVFKQ0KdHhhZmFzdHF1YXJlbnRlbmFTZXhvUmFjYQ0KYGBgDQoNCiMgR1LDgUZJQ09TIFBBUkEgREFET1MgQU1PU1RSQUlTIHZpYSBgc3VydmV5YA0KDQojIyBIaXN0b2dyYW1hDQoNCmBgYHtyLCBjYWNoZT1UUlVFfQ0Kc3Z5aGlzdChmb3JtdWxhPX5hcy5udW1lcmljKEMwMDgpLCBkZXNpZ249eCwgbWFpbj0iSGlzdG9ncmFtYSBjb20gZGVuc2lkYWRlIiwgeGxhYj0iTsO6bWVybyBkZSBIb3JhcyBOb3JtYWxtZW50ZSBUcmFiYWxoYWRhcyIpDQpgYGANCg0KYGBge3IsIGNhY2hlPVRSVUV9DQpzdnloaXN0KGZvcm11bGE9fmFzLm51bWVyaWMoQzAwOCksIGRlc2lnbj14LCBmcmVxPVRSVUUsIG1haW49Ikhpc3RvZ3JhbWEgY29tIGZyZXF1w6puY2lhcyBhYnNvbHV0YXMiLCB4bGFiPSJOw7ptZXJvIGRlIEhvcmFzIE5vcm1hbG1lbnRlIFRyYWJhbGhhZGFzIikNCmBgYA0KDQojIyBCb3hwbG90DQoNCiMjIyBTZW0gdXNhciBncnVwb3MNCg0KYGBge3IsIGNhY2hlPVRSVUV9DQpzdnlib3hwbG90KGZvcm11bGE9QzAwOH4xLCBkZXNpZ249eCwgbWFpbj0iQm94cGxvdCBkbyBOw7ptZXJvIGRlIEhvcmFzIE5vcm1hbG1lbnRlIFRyYWJhbGhhZGFzIikNCmBgYA0KDQoNCiMjIyBDb20gZ3J1cG9zIGRlZmluaWRvcyBwb3IgdmFyacOhdmVsDQpgYGB7ciwgY2FjaGU9VFJVRX0NCnN2eWJveHBsb3QoZm9ybXVsYT1DMDA4fkEwMDMsIGRlc2lnbj14LCBtYWluPSJCb3hwbG90IGRvIE7Dum1lcm8gZGUgSG9yYXMgTm9ybWFsbWVudGUgVHJhYmFsaGFkYXMgcG9yIFNleG8iKQ0KYGBgDQoNCiMjIEJveHBsb3QgY29tIHRvZG9zIG9zIG91dGxpZXJzDQoNCkEgb3DDp8OjbyBhbnRlcmlvciBwbG90YXZhIGFwZW5hcyBvcyBvdXRsaWVycyBleHRyZW1vcy4gQWdvcmEgdMOqbS1zZSB0b2RvcyBvcyBvdXRsaWVycy4NCg0KYGBge3IsIGNhY2hlPVRSVUV9DQpzdnlib3hwbG90KGZvcm11bGE9QzAwOH5BMDAzLCBkZXNpZ249eCwgYWxsLm91dGxpZXJzPVRSVUUsIG1haW49IkJveHBsb3QgZG8gTsO6bWVybyBkZSBIb3JhcyBOb3JtYWxtZW50ZSBUcmFiYWxoYWRhcyBwb3IgU2V4byIpDQpgYGANCg0KIyMgR3LDoWZpY29zIGRlIGRpc3BlcnPDo28NCg0KIyMjIEVzdGlsbyBib2xoYQ0KDQpgYGB7ciwgY2FjaGU9VFJVRX0NCnN2eXBsb3QoZm9ybXVsYT1DMDEwMTJ+QzAwOCwgZGVzaWduPXgsIHN0eWxlPSJidWJibGUiLCB4bGFiPSJOw7ptZXJvIGRlIEhvcmFzIE5vcm1hbG1lbnRlIFRyYWJhbGhhZGFzIiwgeWxhYj0iUmVuZGltZW50byBOb3JtYWxtZW50ZSBSZWNlYmlkbyBlbSBEaW5oZWlybyIpDQpgYGANCg0KIyMjIEVzdGlsbyB0cmFuc3BhcmVudGUNCg0KYGBge3IsIGNhY2hlPVRSVUV9DQpzdnlwbG90KGZvcm11bGE9QzAxMDEyfkMwMDgsIGRlc2lnbj14LCBzdHlsZT0idHJhbnNwYXJlbnQiLCB4bGFiPSJOw7ptZXJvIGRlIEhvcmFzIE5vcm1hbG1lbnRlIFRyYWJhbGhhZGFzIiwgeWxhYj0iUmVuZGltZW50byBOb3JtYWxtZW50ZSBSZWNlYmlkbyBlbSBEaW5oZWlybyIpDQpgYGANCg0KIyBNT0RFTEFHRU0gQ09NIFBBQ09URSBgc3VydmV5YA0KDQojIyBUZXN0ZXMgZGUgSGlww7N0ZXNlcw0KDQojIyMgVGVzdGUtdCBwYXJhIG3DqWRpYXMgZGUgcmVuZGltZW50b3MgZW50cmUgc2V4b3MNCg0KYGBge3IsIGNhY2hlPVRSVUV9DQpzdnl0dGVzdChmb3JtdWxhPUMwMTAxMn5BMDAzLCBkZXNpZ249eCkNCmBgYA0KDQojIyMgVGVzdGUtdCBwYXJhIG3DqWRpYXMgZGUgaG9yYXMgdHJhYmFsaGFkYXMgKEMwMDgpIGVudHJlIHF1ZW0gdHJhYmFsaG91IG91IG7Do28gKEMwMDEpDQoNCmBgYHtyLCBjYWNoZT1UUlVFfQ0Kc3Z5dHRlc3QoZm9ybXVsYT1hcy5udW1lcmljKEMwMDgpfkMwMDEsIGRlc2lnbj14KQ0KYGBgDQoNCiMjIE1vZGVsb3MgbGluZWFyZXMNCg0KIyMjIFJlZ3Jlc3PDo28gbGluZWFyDQoNCmBgYHtyLCBjYWNoZT1UUlVFfQ0KbW9kZWxvTGluIDwtIHN2eWdsbShmb3JtdWxhPUMwMTAxMn5BMDA1K0EwMDQrQTAwMiwgZGVzaWduPXgpDQpzdW1tYXJ5KG9iamVjdD1tb2RlbG9MaW4pDQpgYGANCg0KYGBge3IsIGNhY2hlPVRSVUV9DQpjb25maW50KG9iamVjdD1tb2RlbG9MaW4pDQpgYGANCg0KIyMjIFJlZ3Jlc3PDo28gTG9nw61zdGljYQ0KDQpgYGB7ciwgY2FjaGU9VFJVRX0NCm1vZGVsb0xvZyA8LSBzdnlnbG0oZm9ybXVsYT1DMDAyfkEwMDMrQTAwNCtBMDAyLCBkZXNpZ249eCwgZmFtaWx5PSJiaW5vbWlhbCIpDQoNCnN1bW1hcnkob2JqZWN0PW1vZGVsb0xvZykNCmBgYA0KDQpgYGB7ciwgY2FjaGU9VFJVRX0NCmNvbmZpbnQob2JqZWN0PW1vZGVsb0xvZykNCmBgYA0KDQojIEFOw4FMSVNFIERFIENPTkNFTlRSQcOHw4NPIERFIFJFTkRBIENPTSBPIFBBQ09URSBgY29udmV5YA0KDQpPIHBhY290ZSBgY29udmV5YCByZXF1ZXIgdXNvIGRhIGZ1bsOnw6NvIGBjb252ZXlfcHJlcGAgcGFyYSBhZGFwdGFyIG8gb2JqZXRvIGRvIHBsYW5vIGFtb3N0cmFsIGRvIGBzdXJ2ZXlgIGFvIG9iamV0byBxdWUgbyBwYWNvdGUgYGNvbnZleWAgcmVxdWVyIHBhcmEgYXMgZXN0aW1hw6fDtWVzIChKQUNPQiBldCBhbCwgMjAyMSk6DQoNCmBgYHtyLCBjYWNoZT1UUlVFfQ0KIyBwYXJhIGZhemVyIG8gZ2luaSwgcHJlY2lzYSBhcGxpY2FyIG8gY29udmV5X3ByZXAgcGFyYSB1c2FyIG8gY29udmV5DQpsaWJyYXJ5KGNvbnZleSkNCmRhZG9zUE5BRENPVklEMTkgPC0gY29udmV5X3ByZXAoZGVzaWduPXgpDQp4PC1kYWRvc1BOQURDT1ZJRDE5ICMgdm91IHJlYXRyaWJ1aXINCmNsYXNzKHgpICMgImNvbnZleS5kZXNpZ24iICAic3VydmV5LmRlc2lnbjIiICJzdXJ2ZXkuZGVzaWduIiANCmBgYA0KDQojIyDDjW5kaWNlIGRlIEdpbmkNCg0KYGBge3IsIGNhY2hlPVRSVUV9DQpnaW5pSGFiIDwtIHN2eWdpbmkoZm9ybXVsYT1+QzAxMDEyLCBkZXNpZ249eCwgbmEucm09VFJVRSkNCmdpbmlIYWINCmBgYA0KDQpgYGB7ciwgY2FjaGU9VFJVRX0NCmN2KG9iamVjdD1naW5pSGFiKQ0KYGBgDQoNCiMjIMONbmRpY2UgZGUgR2luaSBkYSByZW5kYSBub3JtYWxtZW50ZSByZWNlYmlkYSBlbSBkaW5oZWlybyBwb3IgVW5pZGFkZSBkYSBGZWRlcmHDp8OjbzoNCg0KYGBge3IsIGNhY2hlPVRSVUV9DQpnaW5pVUYgPC0gc3Z5YnkoZm9ybXVsYT1+QzAxMDEyLCBieT1+VUYsIGRlc2lnbj14LCBGVU49c3Z5Z2luaSwgbmEucm09VFJVRSkNCmdpbmlVRg0KYGBgDQoNCmBgYHtyLCBjYWNoZT1UUlVFfQ0KY29uZmludChvYmplY3Q9Z2luaVVGKQ0KYGBgDQoNCiMjIEN1cnZhIGRlIExvcmVueg0KDQpgYGB7ciwgY2FjaGU9VFJVRX0NCmN1cnZhTG9yZW56IDwtIHN2eWxvcmVueihmb3JtdWxhPX5DMDEwMTIsIGRlc2lnbj14LCBxdWFudGlsZXM9c2VxKDAsMSwuMDUpLCBuYS5ybT1UUlVFKQ0KYGBgDQoNCiMgUkVGTEVYw5VFUw0KDQpPIGFycXVpdm8gYHRibF9zdnlgIGZpY2EgbWFpcyBwZXNhZG8gcXVlIG8gYHN1cnZleS5kZXNpZ25gIHB1cm8gb2J0aWRvIHBlbGEgYGdldF9jb3ZpZGAuIFVtYSB2YW50YWdlbSBkbyBgdGJsX3N2eWAgw6kgcXVlIG8gZm9ybWF0byB0aWJibGUgZmFjaWxpdGEgZ3LDoWZpY29zIGVtIGdncGxvdDIgZSBtYW5pcHVsYcOnw7VlcyBkbyBhbWJpZW50ZSB0aWR5dmVyc2UuIEEgZGVzdmFudGFnZW0gw6kgcXVlIG8gYXJxdWl2byDDqSBtYWlzIHBlc2FkbyBxdWUgbyBmb3JtYXRvIHN1cnZleS5kZXNpZ24gcHVyby4gVm91IGNvbnRpbnVhciBvcyBwcm9jZWRpbWVudG9zIGNvbSBvIG9iamV0byBgZGFkb3NQTkFEQ09WSUQxOS52YXJgLg0KDQoNCg0KIyBSRUZFUsOKTkNJQVMgeyNSZWZlcsOqbmNpYXMgLnVubnVtYmVyZWR9DQoNCkFTU1VOw4fDg08sIEdhYnJpZWwuIEFuw6FsaXNlIGRlIG1pY3JvZGFkb3MgZGEgUE5BRCBDT1ZJRDE5IENvbSBvcyBQYWNvdGVzIENPVklESUJHRSBlIHN1cnZleS4gUlN0dWRpby9ScHVicywgMjAyMS4gRGlzcG9uw612ZWwgZW06IDxodHRwczovL3JwdWJzLmNvbS9nYWJyaWVsLWFzc3VuY2FvLWliZ2UvY292aWQ+Lg0KDQpBU1NVTsOHw4NPLCBHYWJyaWVsOyBISURBTEdPLCBMdW5hLiBDT1ZJRElCR0U6IERvd25sb2FkaW5nLCBSZWFkaW5nIGFuZCBBbmFseXNpbmcgUE5BRCBDT1ZJRDE5IE1pY3JvZGF0YS4gMjAyMS4gUiBwYWNrYWdlIHZlcnNpb24gMC4xLjcuIERpc3BvbsOtdmVsIGVtOiA8aHR0cHM6Ly9DUkFOLlItcHJvamVjdC5vcmcvcGFja2FnZT1DT1ZJRElCR0U+Lg0KDQpCQVJPTkUsIExlb25hcmRvIFNhbmdhbGkuIFBOQUQgQ29udMOtbnVhIG5vIFIgY29tIHNydnlyLiBSU3R1ZGlvL1JwdWJzLCAyMDIwLiBEaXNwb27DrXZlbCBlbTogPGh0dHBzOi8vcnB1YnMuY29tL2xlb2Jhcm9uZS9wbmFkY19zcnZ5cj4uDQoNCkJBUk9ORSwgTGVvbmFyZG8gU2FuZ2FsaS4gQ2VicmFwLmxhYi9DRVRJQyAtIEludHJvZHXDp8OjbyDDoCBQcm9ncmFtYcOnw6NvIGVtIFIuIEdpdGh1YiwgMjAyMS4gRGlzcG9uw612ZWwgZW06IDxodHRwczovL2dpdGh1Yi5jb20vbGVvYmFyb25lL2NlYnJhcF9sYWJfY2V0aWNfcHJvZ3JhbWFjYW9fcj4uDQoNCkJSQUdBLCBEb3VnbGFzOyBBU1NVTsOHw4NPLCBHYWJyaWVsLiBQTkFEY0lCR0U6IERvd25sb2FkaW5nLCBSZWFkaW5nIGFuZCBBbmFseXNpbmcgUE5BREMgTWljcm9kYXRhLiBSIHBhY2thZ2UgdmVyc2lvbiAwLjYuNS4gMjAyMS4gRGlzcG9uw612ZWwgZW06IDxodHRwczovL0NSQU4uUi1wcm9qZWN0Lm9yZy9wYWNrYWdlPVBOQURjSUJHRT4uDQoNCkVMTElTLCBHcmVnIEZyZWVkbWFuOyBTQ0hORUlERVIsIEJlbi4gc3J2eXI6ICdkcGx5cictTGlrZSBTeW50YXggZm9yIFN1bW1hcnkgU3RhdGlzdGljcyBvZiBTdXJ2ZXkgRGF0YS4gUiBwYWNrYWdlIHZlcnNpb24gMS4xLjAuIDIwMjEuIERpc3BvbsOtdmVsIGVtOiA8aHR0cHM6Ly9DUkFOLlItcHJvamVjdC5vcmcvcGFja2FnZT1zcnZ5cj4uDQoNCkZJR1VFSVJFRE8sIEFkcmlhbm8gTWFyY29zIFJvZHJpZ3Vlcy4gRWNvbm9tZXRyaWEgY29tIE1pY3JvZGFkb3MgZGEgUE5BRCBjb250w61udWEgZGUgMjAxOCBjb20gUjo6UE5BRGNJQkdFLCBkZSBCUkFHQSAoMjAxNykuIENhbXBvIEdyYW5kZS1NUyxCcmFzaWw6IFJTdHVkaW8vUnB1YnMsIDIwMTkuIERpc3BvbsOtdmVsIGVtIDxodHRwOi8vcnB1YnMuY29tL2Ftcm9maS9wbmFkY2liZ2Vfc3VydmV5Pi4NCg0KSUJHRSwgUE5BRCBDb250w61udWEgLSBQZXNxdWlzYSBOYWNpb25hbCBwb3IgQW1vc3RyYSBkZSBEb21pY8OtbGlvcyBDb250w61udWE6IE1pY3JvZGFkb3MuIFJpbyBkZSBKYW5laXJvOiBJQkdFLCAyMDIxLiA8aHR0cHM6Ly93d3cuaWJnZS5nb3YuYnIvZXN0YXRpc3RpY2FzL2Rvd25sb2Fkcy1lc3RhdGlzdGljYXMuaHRtbD9jYW1pbmhvPVRyYWJhbGhvX2VfUmVuZGltZW50by9QZXNxdWlzYV9OYWNpb25hbF9wb3JfQW1vc3RyYV9kZV9Eb21pY2lsaW9zX2NvbnRpbnVhL1RyaW1lc3RyYWwvTWljcm9kYWRvcy8yMDIxPi4NCg0KSkFDT0IsIEd1aWxoZXJtZTsgUEVTU09BLCBEamFsbWE7IERBTUlDTywgQW50aG9ueS4gUG92ZXJ0eSBhbmQgSW5lcXVhbGl0eSB3aXRoIENvbXBsZXggU3VydmV5IERhdGEuIDIwMjEuDQoNCkxVTUxFWSwgVC4gU3VydmV5OiBhbmFseXNpcyBvZiBjb21wbGV4IHN1cnZleSBzYW1wbGVzLiBSIHBhY2thZ2UgdmVyc2lvbiAzLjM1LTEuIDIwMTkuDQoNCkxVTUxFWSwgVC4gQW5hbHlzaXMgb2YgY29tcGxleCBzdXJ2ZXkgc2FtcGxlcy4gSm91cm5hbCBvZiBTdGF0aXN0aWNhbCBTb2Z0d2FyZSwgOSgxKTogMS0xOS4gMjAwNC4NCg0KUEVTU09BLCBEamFsbWE7IERBTUlDTywgQW50aG9ueTsgSkFDT0IsIEd1aWxoZXJtZS4gY29udmV5OiBJbmNvbWUgQ29uY2VudHJhdGlvbiBBbmFseXNpcyB3aXRoIENvbXBsZXggU3VydmV5IFNhbXBsZXMuIFIgcGFja2FnZSB2ZXJzaW9uIDAuMi4zLiAyMDIxLg0KDQojIE5PVEE6IHsjTk9UQSAudW5udW1iZXJlZH0NCg0KQ29sb3F1ZWkgbyB0ZW1wbyBkZSBleGVjdcOnw6NvIGFiYWl4bywgbWFzIHVzZWkgY2FjaGUgPSBUUlVFIGVtIHbDoXJpb3MgY2h1bmtzIGRlIG1vZG8gcXVlIG8gdGVtcG8gdG90YWwgcGFyZWNlIHBlcXVlbm8gbWFzIGVtIHbDoXJpb3MgY2h1bmtzIGEgcm90aW5hIGRlbW9yYSBwYXJhIGV4ZWN1dGFyLCBjb25mb3JtZSBzZXUgbWljcm8uDQoNCmBgYHtyfQ0KZW5kLnRpbWUgPC0gU3lzLnRpbWUoKQ0KdGltZS50YWtlbiA8LSBlbmQudGltZSAtIHN0YXJ0LnRpbWUNCnRpbWUudGFrZW4NCmBgYA0KDQpPIHByaW1laXJvIHByb2NlZGltZW50byBsZXZvdSAoVGltZSBkaWZmZXJlbmNlIG9mKSA3LjY0MDQ0OSBtaW51dG9zLCBvdSBzZWphLCBjb25zaWRlcmFuZG8gcXVlIHVzb3Ugb3MgYXJxdWl2b3MgLnJkcyBwcmV2aWFtZW50ZSBzYWx2b3Mu