Carregar pacotes.

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.3     ✔ readr     2.1.4
✔ forcats   1.0.0     ✔ stringr   1.5.0
✔ ggplot2   3.4.3     ✔ tibble    3.2.1
✔ lubridate 1.9.2     ✔ tidyr     1.3.0
✔ purrr     1.0.2     ── Conflicts ────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors

As funcoes filter() e lag() do dplyr apresentam um conflito com as funcoes do mesmo nome no stats. Devo instalar um pacote que tem que resolve conflitos entre funcoes que estao em mais de um pacote.

library(conflicted)

conflict_prefer("filter", "dplyr") 
[conflicted] Will prefer dplyr::filter over any other package.
conflict_prefer("lag", "dplyr")
[conflicted] Will prefer dplyr::lag over any other package.

O codigo acima da prioridade ao dplyr nas funcoes filter e dplyr

library(stats)
library(janitor) #
library(sgeostat)
library(mvoutlier)
library(summarytools)

Importar Dataset.


escola <- read_csv("School_Attendance_by_Student_Group.csv", show_col_types = FALSE) |> 
  janitor::clean_names()

head(escola)

Verificar a Estrutura do Dataset

str(escola)
spc_tbl_ [2,019 × 12] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
 $ district_code                          : chr [1:2019] "00000CT" "00000CT" "00000CT" "00000CT" ...
 $ district_name                          : chr [1:2019] "Connecticut" "Connecticut" "Connecticut" "Connecticut" ...
 $ category                               : chr [1:2019] NA "Homelessness" "Students With Disabilities" "Free/Reduced Lunch" ...
 $ student_group                          : chr [1:2019] "All Students" "Students Experiencing Homelessness" "Students With Disabilities" "Free Meal Eligible" ...
 $ x2021_2022_student_count_year_to_date  : num [1:2019] 500285 1814 78417 168984 29905 ...
 $ x2021_2022_attendance_rate_year_to_date: num [1:2019] 0.917 0.835 0.89 0.885 0.918 ...
 $ x2020_2021_student_count               : num [1:2019] 496092 1735 76487 176225 30886 ...
 $ x2020_2021_attendance_rate             : num [1:2019] 0.929 0.816 0.895 0.886 0.93 ...
 $ x2019_2020_student_count               : num [1:2019] 508346 3916 80365 193706 27507 ...
 $ x2019_2020_attendance_rate             : num [1:2019] 0.948 0.888 0.928 0.931 0.952 ...
 $ reporting_period                       : chr [1:2019] "June 2022" "June 2022" "June 2022" "June 2022" ...
 $ date_update                            : chr [1:2019] "07/22/2022" "07/22/2022" "07/22/2022" "07/22/2022" ...
 - attr(*, "spec")=
  .. cols(
  ..   `District code` = col_character(),
  ..   `District name` = col_character(),
  ..   Category = col_character(),
  ..   `Student group` = col_character(),
  ..   `2021-2022 student count - year to date` = col_double(),
  ..   `2021-2022 attendance rate - year to date` = col_double(),
  ..   `2020-2021 student count` = col_double(),
  ..   `2020-2021 attendance rate` = col_double(),
  ..   `2019-2020 student count` = col_double(),
  ..   `2019-2020 attendance rate` = col_double(),
  ..   `Reporting period` = col_character(),
  ..   `Date update` = col_character()
  .. )
 - attr(*, "problems")=<externalptr> 

Selecionar algumas Variaveis para Analise


escola_sel <- escola |> 
  select(district_name, category, student_group, x2021_2022_student_count_year_to_date, x2021_2022_attendance_rate_year_to_date, x2021_2022_attendance_rate_year_to_date)

head(escola_sel)
NA

O dataset original te varias variaveis, decidi reduzir as variaveis para poder facilitar as minhas analises

Mudar nomes de variaveis

Verificar o dataset

str(escola_2021_2022) # Verificar a estrutura dos dados
tibble [1,818 × 5] (S3: tbl_df/tbl/data.frame)
 $ nome_distrito            : chr [1:1818] "Connecticut" "Connecticut" "Connecticut" "Connecticut" ...
 $ categoria                : chr [1:1818] "Homelessness" "Students With Disabilities" "Free/Reduced Lunch" "Free/Reduced Lunch" ...
 $ grupo_estudante          : chr [1:1818] "Students Experiencing Homelessness" "Students With Disabilities" "Free Meal Eligible" "Reduced Price Meal Eligible" ...
 $ contagem_anual_estudantes: num [1:1818] 1814 78417 168984 29905 198889 ...
 $ taxa_assiduidade         : num [1:1818] 0.835 0.89 0.885 0.918 0.89 ...
 - attr(*, "na.action")= 'omit' Named int [1:201] 1 14 20 32 41 53 59 71 78 90 ...
  ..- attr(*, "names")= chr [1:201] "1" "14" "20" "32" ...
escola_2021_2022 |> 
  dplyr::distinct()  # Verificar linhas duplicadas
escola_2021_2022 |>
  base::is.na() |>  # Verificar a presenca de NA
  base::data.frame() |> 
  head()
escola_2021_2022 |> 
  summarytools::descr() |>  # Resumo estatistico
  base::data.frame() |>
  head(20)
NA
NA

Limpeza de Dados

escola_clean <- escola_2021_2022 |>
  na.omit() |>  # remocao de NA
  janitor::clean_names() |>    # Padronizar os nomes das colunas
  dplyr::mutate(categoria = factor(categoria)) |> 
  dplyr::mutate(nome_distrito=factor(nome_distrito))
  
head(escola_clean)
NA
agregado_contagem <- escola_clean %>%
  group_by(categoria) %>%
  summarise(total_categoria = sum(contagem_anual_estudantes))
agregado_contagem
options(repr.plot.width = 8, repr.plot.height = 6)


ggplot(agregado_contagem, aes(x = categoria, y = total_categoria, fill = categoria)) +
  geom_bar(stat = "identity") +
  labs(x = "Categoria", y = "Total de Estudantes", title = "Total de Estudantes por Categoria")

library(ggplot2)

# Criar o gráfico de barras horizontal com cores
ggplot(agregado_contagem, aes(x = total_categoria, y = categoria, fill = categoria)) +
  geom_bar(stat = "identity") +
  scale_fill_viridis_d(option = "D") +  # Aplicar as cores manualmente
  labs(title = "Total de Estudantes por Categoria",
       x = "Total de Estudantes",
       y = "Categoria") +
  theme_minimal()

NA
NA

Analide Estatística de Dados

Nesta análise, investigamos o impacto das categorias socioeconômicas e demográficas, incluindo ‘English Learner’, ‘Free/Reduced Lunch’, ‘Homelessness’, ‘Race/Ethnicity’ e ‘Students with Disabilities’, na taxa de assiduidade dos alunos de uma escola secundária. Nosso objetivo é identificar possíveis fatores que afetam a assiduidade dos alunos, fornecendo insights valiosos para aprimorar as políticas educacionais e programas de suporte. A análise combina métodos descritivos e estatísticos para explorar a relação entre essas categorias e a taxa de assiduidade, buscando entender como esses fatores podem influenciar o engajamento dos alunos com a escola.

Utilizarei métodos estatísticos, como ANOVA, regressão linear ou regressão logística, para avaliar a relação entre as categorias e a taxa de assiduidade.

ANOVA

Pressupostos da ANOVA

Analise de Normalidade

  1. Texte de Shapiro Wilk
# Teste de Shapiro Wilk
shapiro_asseduidade <- stats::shapiro.test(escola_clean$taxa_assiduidade)
shapiro_asseduidade

    Shapiro-Wilk normality test

data:  escola_clean$taxa_assiduidade
W = 0.88566, p-value < 2.2e-16

O teste de normalidade de Shapiro-Wilk para a variável taxa_assiduidade resultou em um valor de estatística de teste (W) de aproximadamente 0.886 e um valor p muito pequeno (menor que 2.2e-16). Isso indica que há evidências estatisticamente significativas para rejeitar a hipótese nula de que os dados seguem uma distribuição normal. Ou seja, a taxa_assiduidade não segue uma distribuição normal.

  1. histograma

ggplot(escola_clean, aes(x = taxa_assiduidade)) + geom_histogram(bins = 20,
                                                    fill = "skyblue",
                                                    color = "black") + ggtitle("Distribuição da taxa de asseduidade")

A distribuição assimétrica e concentrada à direita dos seus dados sugere que eles não seguem uma distribuição normal, que é caracterizada por uma forma de sino simétrica.

LS0tDQp0aXRsZTogIkNpZW5jaWFzIGRlIERhZG9zIC0gTGltcGV6YSBkZSBEYWRvcyINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQNCiAgd29yZF9kb2N1bWVudDogZGVmYXVsdA0KLS0tDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyMjICoqKkNhcnJlZ2FyIHBhY290ZXMqKiouDQoNCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpgYGANCg0KQXMgZnVuY29lcyBmaWx0ZXIoKSBlIGxhZygpIGRvIGRwbHlyIGFwcmVzZW50YW0gdW0gY29uZmxpdG8gY29tIGFzIGZ1bmNvZXMgZG8gbWVzbW8gbm9tZSBubyBzdGF0cy4gRGV2byBpbnN0YWxhciB1bSBwYWNvdGUgcXVlIHRlbSBxdWUgcmVzb2x2ZSBjb25mbGl0b3MgZW50cmUgZnVuY29lcyBxdWUgZXN0YW8gZW0gbWFpcyBkZSB1bSBwYWNvdGUuDQoNCmBgYHtyfQ0KbGlicmFyeShjb25mbGljdGVkKQ0KYGBgDQoNCmBgYHtyfQ0KDQpjb25mbGljdF9wcmVmZXIoImZpbHRlciIsICJkcGx5ciIpIA0KY29uZmxpY3RfcHJlZmVyKCJsYWciLCAiZHBseXIiKQ0KDQpgYGANCg0KTyBjb2RpZ28gYWNpbWEgZGEgcHJpb3JpZGFkZSBhbyBkcGx5ciBuYXMgZnVuY29lcyBmaWx0ZXIgZSBkcGx5cg0KDQpgYGB7cn0NCmxpYnJhcnkoc3RhdHMpDQpgYGANCg0KYGBge3J9DQpsaWJyYXJ5KGphbml0b3IpICMNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkoc2dlb3N0YXQpDQpgYGANCg0KYGBge3J9DQpsaWJyYXJ5KG12b3V0bGllcikNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkoc3VtbWFyeXRvb2xzKQ0KYGBgDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyMjICoqKkltcG9ydGFyIERhdGFzZXQqKiouDQoNCmBgYHtyfQ0KDQplc2NvbGEgPC0gcmVhZF9jc3YoIlNjaG9vbF9BdHRlbmRhbmNlX2J5X1N0dWRlbnRfR3JvdXAuY3N2Iiwgc2hvd19jb2xfdHlwZXMgPSBGQUxTRSkgfD4gDQogIGphbml0b3I6OmNsZWFuX25hbWVzKCkNCg0KaGVhZChlc2NvbGEpDQpgYGANCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMjIyMgKioqVmVyaWZpY2FyIGEgRXN0cnV0dXJhIGRvIERhdGFzZXQqKioNCg0KYGBge3J9DQpzdHIoZXNjb2xhKQ0KYGBgDQoNCiMjIyMgKioqU2VsZWNpb25hciBhbGd1bWFzIFZhcmlhdmVpcyBwYXJhIEFuYWxpc2UqKioNCg0KYGBge3J9DQoNCmVzY29sYV9zZWwgPC0gZXNjb2xhIHw+IA0KICBzZWxlY3QoZGlzdHJpY3RfbmFtZSwgY2F0ZWdvcnksIHN0dWRlbnRfZ3JvdXAsIHgyMDIxXzIwMjJfc3R1ZGVudF9jb3VudF95ZWFyX3RvX2RhdGUsIHgyMDIxXzIwMjJfYXR0ZW5kYW5jZV9yYXRlX3llYXJfdG9fZGF0ZSwgeDIwMjFfMjAyMl9hdHRlbmRhbmNlX3JhdGVfeWVhcl90b19kYXRlKQ0KDQpoZWFkKGVzY29sYV9zZWwpDQoNCmBgYA0KDQpPIGRhdGFzZXQgb3JpZ2luYWwgdGUgdmFyaWFzIHZhcmlhdmVpcywgZGVjaWRpIHJlZHV6aXIgYXMgdmFyaWF2ZWlzIHBhcmEgcG9kZXIgZmFjaWxpdGFyIGFzIG1pbmhhcyBhbmFsaXNlcw0KDQojIyMjICoqKk11ZGFyIG5vbWVzIGRlIHZhcmlhdmVpcyoqKg0KDQpgYGB7cn0NCg0KZXNjb2xhXzIwMjFfMjAyMiA8LSBlc2NvbGFfc2VsIHw+IA0KICBkcGx5cjo6cmVuYW1lKG5vbWVfZGlzdHJpdG89ZGlzdHJpY3RfbmFtZSwgDQogICAgICAgICAgICAgICBjYXRlZ29yaWEgPWNhdGVnb3J5LA0KICAgICAgICAgICAgICAgZ3J1cG9fZXN0dWRhbnRlID0gc3R1ZGVudF9ncm91cCwNCiAgICAgICAgICAgIGNvbnRhZ2VtX2FudWFsX2VzdHVkYW50ZXM9eDIwMjFfMjAyMl9zdHVkZW50X2NvdW50X3llYXJfdG9fZGF0ZSwNCiAgICAgICAgICAgICAgdGF4YV9hc3NpZHVpZGFkZT14MjAyMV8yMDIyX2F0dGVuZGFuY2VfcmF0ZV95ZWFyX3RvX2RhdGUpIHw+IA0KDQpoZWFkKGVzY29sYV8yMDIxXzIwMjIpDQpWaWV3KGVzY29sYV8yMDIxXzIwMjIpDQpgYGANCg0KIyMjIyBWZXJpZmljYXIgbyBkYXRhc2V0DQoNCmBgYHtyfQ0Kc3RyKGVzY29sYV8yMDIxXzIwMjIpICMgVmVyaWZpY2FyIGEgZXN0cnV0dXJhIGRvcyBkYWRvcw0KYGBgDQoNCmBgYHtyfQ0KZXNjb2xhXzIwMjFfMjAyMiB8PiANCiAgZHBseXI6OmRpc3RpbmN0KCkgICMgVmVyaWZpY2FyIGxpbmhhcyBkdXBsaWNhZGFzDQpgYGANCg0KYGBge3J9DQplc2NvbGFfMjAyMV8yMDIyIHw+DQogIGJhc2U6OmlzLm5hKCkgfD4gICMgVmVyaWZpY2FyIGEgcHJlc2VuY2EgZGUgTkENCiAgYmFzZTo6ZGF0YS5mcmFtZSgpIHw+IA0KICBoZWFkKCkNCmBgYA0KDQpgYGB7cn0NCmVzY29sYV8yMDIxXzIwMjIgfD4gDQogIHN1bW1hcnl0b29sczo6ZGVzY3IoKSB8PiAgIyBSZXN1bW8gZXN0YXRpc3RpY28NCiAgYmFzZTo6ZGF0YS5mcmFtZSgpIHw+DQogIGhlYWQoMjApDQpgYGANCg0KIyMjIyAqKipMaW1wZXphIGRlIERhZG9zKioqDQoNCmBgYHtyfQ0KZXNjb2xhX2NsZWFuIDwtIGVzY29sYV8yMDIxXzIwMjIgfD4NCiAgbmEub21pdCgpIHw+ICAjIHJlbW9jYW8gZGUgTkENCiAgamFuaXRvcjo6Y2xlYW5fbmFtZXMoKSB8PiAgICAjIFBhZHJvbml6YXIgb3Mgbm9tZXMgZGFzIGNvbHVuYXMNCiAgZHBseXI6Om11dGF0ZShjYXRlZ29yaWEgPSBmYWN0b3IoY2F0ZWdvcmlhKSkgfD4gDQogIGRwbHlyOjptdXRhdGUobm9tZV9kaXN0cml0bz1mYWN0b3Iobm9tZV9kaXN0cml0bykpDQogIA0KaGVhZChlc2NvbGFfY2xlYW4pDQoNCmBgYA0KDQpgYGB7cn0NCmFncmVnYWRvX2NvbnRhZ2VtIDwtIGVzY29sYV9jbGVhbiB8PiANCiAgZ3JvdXBfYnkoY2F0ZWdvcmlhKSB8PiANCiAgc3VtbWFyaXNlKHRvdGFsX2NhdGVnb3JpYSA9IHN1bShjb250YWdlbV9hbnVhbF9lc3R1ZGFudGVzKSkNCmFncmVnYWRvX2NvbnRhZ2VtDQpgYGANCg0KYGBge3J9DQpvcHRpb25zKHJlcHIucGxvdC53aWR0aCA9IDgsIHJlcHIucGxvdC5oZWlnaHQgPSA2KQ0KDQoNCmdncGxvdChhZ3JlZ2Fkb19jb250YWdlbSwgYWVzKHggPSBjYXRlZ29yaWEsIHkgPSB0b3RhbF9jYXRlZ29yaWEsIGZpbGwgPSBjYXRlZ29yaWEpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIGxhYnMoeCA9ICJDYXRlZ29yaWEiLCB5ID0gIlRvdGFsIGRlIEVzdHVkYW50ZXMiLCB0aXRsZSA9ICJUb3RhbCBkZSBFc3R1ZGFudGVzIHBvciBDYXRlZ29yaWEiKQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KDQojIENyaWFyIG8gZ3LDoWZpY28gZGUgYmFycmFzIGhvcml6b250YWwgY29tIGNvcmVzDQpnZ3Bsb3QoYWdyZWdhZG9fY29udGFnZW0sIGFlcyh4ID0gdG90YWxfY2F0ZWdvcmlhLCB5ID0gY2F0ZWdvcmlhLCBmaWxsID0gY2F0ZWdvcmlhKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfZChvcHRpb24gPSAiRCIpICsgICMgQXBsaWNhciBhcyBjb3JlcyBtYW51YWxtZW50ZQ0KICBsYWJzKHRpdGxlID0gIlRvdGFsIGRlIEVzdHVkYW50ZXMgcG9yIENhdGVnb3JpYSIsDQogICAgICAgeCA9ICJUb3RhbCBkZSBFc3R1ZGFudGVzIiwNCiAgICAgICB5ID0gIkNhdGVnb3JpYSIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCg0KYGBgDQoNCmBgYHtyfQ0KYWdyZWdhZG9fYXNzZWR1aWRhZGUgPC0gZXNjb2xhX2NsZWFuIHw+IA0KICBncm91cF9ieShjYXRlZ29yaWEpIHw+IA0KICBzdW1tYXJpc2UodG90YWxfY2F0ZWdvcmlhID0gc3VtKHRheGFfYXNzaWR1aWRhZGUpKQ0KYWdyZWdhZG9fYXNzZWR1aWRhZGUNCmBgYA0KDQpgYGB7cn0NCg0KIyBDcmlhciBvIGdyw6FmaWNvIGRlIGJhcnJhcyBob3Jpem9udGFsIGNvbSBjb3Jlcw0KZ2dwbG90KGFncmVnYWRvX2Fzc2VkdWlkYWRlLCBhZXMoeCA9IHRvdGFsX2NhdGVnb3JpYSwgeSA9IGNhdGVnb3JpYSwgZmlsbCA9IGNhdGVnb3JpYSkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsNCiAgc2NhbGVfZmlsbF92aXJpZGlzX2Qob3B0aW9uID0gIkQiKSArICAjIEFwbGljYXIgYXMgY29yZXMgbWFudWFsbWVudGUNCiAgbGFicyh0aXRsZSA9ICJBc3NlZHVpZGFkZSBkb3MgZXN0dWRhbnRlcyIsDQogICAgICAgeCA9ICJUb3RhbCBkZSBFc3R1ZGFudGVzIiwNCiAgICAgICB5ID0gIkNhdGVnb3JpYSIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KIyMjIyBBbmFsaWRlIEVzdGF0w61zdGljYSBkZSBEYWRvcw0KDQpOZXN0YSBhbsOhbGlzZSwgaW52ZXN0aWdhbW9zIG8gaW1wYWN0byBkYXMgY2F0ZWdvcmlhcyBzb2Npb2Vjb27DtG1pY2FzIGUgZGVtb2dyw6FmaWNhcywgaW5jbHVpbmRvICdFbmdsaXNoIExlYXJuZXInLCAnRnJlZS9SZWR1Y2VkIEx1bmNoJywgJ0hvbWVsZXNzbmVzcycsICdSYWNlL0V0aG5pY2l0eScgZSAnU3R1ZGVudHMgd2l0aCBEaXNhYmlsaXRpZXMnLCBuYSB0YXhhIGRlIGFzc2lkdWlkYWRlIGRvcyBhbHVub3MgZGUgdW1hIGVzY29sYSBzZWN1bmTDoXJpYS4gTm9zc28gb2JqZXRpdm8gw6kgaWRlbnRpZmljYXIgcG9zc8OtdmVpcyBmYXRvcmVzIHF1ZSBhZmV0YW0gYSBhc3NpZHVpZGFkZSBkb3MgYWx1bm9zLCBmb3JuZWNlbmRvIGluc2lnaHRzIHZhbGlvc29zIHBhcmEgYXByaW1vcmFyIGFzIHBvbMOtdGljYXMgZWR1Y2FjaW9uYWlzIGUgcHJvZ3JhbWFzIGRlIHN1cG9ydGUuIEEgYW7DoWxpc2UgY29tYmluYSBtw6l0b2RvcyBkZXNjcml0aXZvcyBlIGVzdGF0w61zdGljb3MgcGFyYSBleHBsb3JhciBhIHJlbGHDp8OjbyBlbnRyZSBlc3NhcyBjYXRlZ29yaWFzIGUgYSB0YXhhIGRlIGFzc2lkdWlkYWRlLCBidXNjYW5kbyBlbnRlbmRlciBjb21vIGVzc2VzIGZhdG9yZXMgcG9kZW0gaW5mbHVlbmNpYXIgbyBlbmdhamFtZW50byBkb3MgYWx1bm9zIGNvbSBhIGVzY29sYS4NCg0KVXRpbGl6YXJlaSBtw6l0b2RvcyBlc3RhdMOtc3RpY29zLCBjb21vIEFOT1ZBLCByZWdyZXNzw6NvIGxpbmVhciBvdSByZWdyZXNzw6NvIGxvZ8Otc3RpY2EsIHBhcmEgYXZhbGlhciBhIHJlbGHDp8OjbyBlbnRyZSBhcyBjYXRlZ29yaWFzIGUgYSB0YXhhIGRlIGFzc2lkdWlkYWRlLg0KDQoqKkFOT1ZBKioNCg0KKipQcmVzc3Vwb3N0b3MgZGEgQU5PVkEqKg0KDQoqKkFuYWxpc2UgZGUgTm9ybWFsaWRhZGUqKg0KDQoxLiAgKlRleHRlIGRlIFNoYXBpcm8gV2lsayoNCg0KLSAgICoqKkhpcMOzdGVzZSBudWxhIChIMCk6KioqIE9zIGRhZG9zIHNlZ3VlbSB1bWEgZGlzdHJpYnVpw6fDo28gbm9ybWFsLiAoUC12YWx1ZSDiiaUgMC41KQ0KDQotICAgKioqSGlww7N0ZXNlIGFsdGVybmF0aXZhIChIMSkqKioqKjoqKiBPcyBkYWRvcyBuw6NvIHNlZ3VlbSB1bWEgZGlzdHJpYnVpw6fDo28gbm9ybWFsLiAoUC12YWx1ZSBcPCAwLjUpDQoNCmBgYHtyfQ0KIyBUZXN0ZSBkZSBTaGFwaXJvIFdpbGsNCnNoYXBpcm9fYXNzZWR1aWRhZGUgPC0gc3RhdHM6OnNoYXBpcm8udGVzdChlc2NvbGFfY2xlYW4kdGF4YV9hc3NpZHVpZGFkZSkNCnNoYXBpcm9fYXNzZWR1aWRhZGUNCmBgYA0KDQpPIHRlc3RlIGRlIG5vcm1hbGlkYWRlIGRlIFNoYXBpcm8tV2lsayBwYXJhIGEgdmFyacOhdmVsICoqYHRheGFfYXNzaWR1aWRhZGVgKiogcmVzdWx0b3UgZW0gdW0gdmFsb3IgZGUgZXN0YXTDrXN0aWNhIGRlIHRlc3RlIChXKSBkZSBhcHJveGltYWRhbWVudGUgMC44ODYgZSB1bSB2YWxvciBwIG11aXRvIHBlcXVlbm8gKG1lbm9yIHF1ZSAyLjJlLTE2KS4gSXNzbyBpbmRpY2EgcXVlIGjDoSBldmlkw6puY2lhcyBlc3RhdGlzdGljYW1lbnRlIHNpZ25pZmljYXRpdmFzIHBhcmEgcmVqZWl0YXIgYSBoaXDDs3Rlc2UgbnVsYSBkZSBxdWUgb3MgZGFkb3Mgc2VndWVtIHVtYSBkaXN0cmlidWnDp8OjbyBub3JtYWwuIE91IHNlamEsIGEgKipgdGF4YV9hc3NpZHVpZGFkZWAqKiBuw6NvIHNlZ3VlIHVtYSBkaXN0cmlidWnDp8OjbyBub3JtYWwuDQoNCjIuICAqaGlzdG9ncmFtYSoNCg0KYGBge3J9DQoNCmdncGxvdChlc2NvbGFfY2xlYW4sIGFlcyh4ID0gdGF4YV9hc3NpZHVpZGFkZSkpICsgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDIwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGwgPSAic2t5Ymx1ZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArIGdndGl0bGUoIkRpc3RyaWJ1acOnw6NvIGRhIHRheGEgZGUgYXNzZWR1aWRhZGUiKQ0KYGBgDQoNCkEgZGlzdHJpYnVpw6fDo28gYXNzaW3DqXRyaWNhIGUgY29uY2VudHJhZGEgw6AgZGlyZWl0YSBkb3Mgc2V1cyBkYWRvcyBzdWdlcmUgcXVlIGVsZXMgbsOjbyBzZWd1ZW0gdW1hIGRpc3RyaWJ1acOnw6NvIG5vcm1hbCwgcXVlIMOpIGNhcmFjdGVyaXphZGEgcG9yIHVtYSBmb3JtYSBkZSBzaW5vIHNpbcOpdHJpY2EuDQo=