<<<<<<< HEAD ======= >>>>>>> 6056c29c711690a9ae14a8e4ec179ee3356985e0 Preliminary Analysis

Importing Packages

library(tidyverse)
library(readxl)
library(corrplot)
library(ggthemes)
theme_set(theme_clean())

Importing and Cleaning Data

district_data <- read_excel("../raw/NHGIS_District_data.xlsx")

Fortunately, there isn’t much initial restructuring required of this data.

names(district_data)
##  [1] "School ID"                                       
##  [2] "State"                                           
##  [3] "Geographic School District"                      
##  [4] "Children 5-17 (SAIPE Estimate)"                  
##  [5] "% Poverty (SAIPE Estimate)"                      
##  [6] "% Single Parent Estimate"                        
##  [7] "Single Parent Margin of Error"                   
##  [8] "% HHs With Vulnerable Job Estimate"              
##  [9] "Vulnerable Job Margin of Error"                  
## [10] "% Crowded Conditions Estimate"                   
## [11] "HH With Crowded Conditions Margin of Error"      
## [12] "% No Computer or Internet Estimate"              
## [13] "No Computer or Internet Margin of Error"         
## [14] "% Children with Disability"                      
## [15] "Children with Disability Margin of Error"        
## [16] "% Linguistically Isolated Children"              
## [17] "Linguistically Isolated Children Margin of Error"

Let’s work on renaming our variables to more R-friendly names.

names_list <- c(
    "school_ID", 
    "state", 
    "dist",  # Geographic School District 
    "children", # Children 5-17 (SAIPE Estimate)
    "pct_pov", # % Poverty (SAIPE Estimate)
    "pct_SP", # % Single Parent Estimate
    "SP_MOE", # Single Parent Margin of Error
    "pct_HHVJ", # % HHs With Vulnerable Job Estimate
    "HHVJ_MOE", # Vulnerable Job Margin of Error
    "pct_CC", # % Crowded Conditions Estimate
    "CC_MOE", # HH With Crowded Conditions Margin of Error
    "pct_NCI", # % No Computer or Internet Estimate
    "nci_MOE", # No Computer or Internet Margin of Error
    "pct_CD", # % Children with Disability
    "CD_MOE", # Children with Disability Margin of Error
    "pct_CLI", # % Linguistically Isolated Children
    "CLI_MOE" # Linguistically Isolated Children Margin of Error
)
names(district_data) <- names_list
district_pcts <- district_data %>%
    select(-ends_with("MOE")) 

We make a new dataset, district_pcts, which contains all the values without any of the margins of error.

We can now do some preliminary analysis on this data. Let’s first see if there’s any NA/missing data:

district_data %>% 
    is.na() %>% 
    colSums()
## school_ID     state      dist  children   pct_pov    pct_SP    SP_MOE  pct_HHVJ 
##         0         0         0         0         0         0         0         0 
##  HHVJ_MOE    pct_CC    CC_MOE   pct_NCI   nci_MOE    pct_CD    CD_MOE   pct_CLI 
##         0         0         0         0         0         0         0         0 
##   CLI_MOE 
##         0

Fortunately, there don’t appear to be any NA values in any of the percentage columns.

Analysis

Variable Correlations

Let’s check out some variable correlations:

district_pcts[,4:ncol(district_pcts)] %>% 
    cor() %>%
    corrplot(method = "number")

Based on the correlations, it might make sense to plot some variables against each other to see some initial trends. We will choose a cutoff correlation value of 0.3 to distinguish variables which may be of interest. This is completely arbitrary, but limits the amount of plots we need to make such that the analysis is not entirely cumbersome.

Additionally, we will only consider school districts which have more than 100 students. This eliminates outlying values which appear for low numbers of students, such as measures equal to 100%. As an example, we can look at the variable pct_pov; there are a few data points at the 100% mark, so let’s look at these values:

district_data %>% 
    filter(pct_pov == 1) %>% 
    arrange(pct_pov) %>%
    select(state, dist, children, pct_pov)
## # A tibble: 2 × 4
##   state      dist                       children pct_pov
##   <chr>      <chr>                         <dbl>   <dbl>
## 1 Maine      Seboeis Plantation               17       1
## 2 New Mexico Wagon Mound Public Schools       59       1

Because of this low number of children affecting the values of the variables so much, we’ll set 100 to be that cutoff value and continue with analysis. Additionally, since we have over 10,000 rows in our dataset, we randomly sample 1000 of these values for each of the following plots.

Correlated Variable Plots

district_filtered <- district_data %>%
    filter(children > 100)
nrow(district_data) - nrow(district_filtered)
## [1] 790
ggplot(district_filtered[sample(1000),],
       aes(x = pct_pov, 
           y = pct_SP
       )) + 
    geom_point(alpha = 0.1) + 
    geom_smooth()
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
<<<<<<< HEAD

=======

>>>>>>> 6056c29c711690a9ae14a8e4ec179ee3356985e0
ggplot(district_filtered[sample(1000),],
       aes(x = pct_pov, 
           y = pct_CC
       )) + 
    geom_point(alpha = 0.1) + 
    geom_smooth()
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
<<<<<<< HEAD

=======

>>>>>>> 6056c29c711690a9ae14a8e4ec179ee3356985e0
ggplot(district_filtered[sample(1000),],
       aes(x = pct_pov, 
           y = pct_NCI
       )) + 
    geom_point(alpha = 0.1) + 
    geom_smooth()
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
<<<<<<< HEAD

=======

>>>>>>> 6056c29c711690a9ae14a8e4ec179ee3356985e0
ggplot(district_filtered[sample(1000),],
       aes(x = pct_SP, 
           y = pct_NCI
       )) + 
    geom_point(alpha = 0.1) + 
    geom_smooth()
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
<<<<<<< HEAD

=======

>>>>>>> 6056c29c711690a9ae14a8e4ec179ee3356985e0
ggplot(district_filtered[sample(1000),],
       aes(x = pct_CC, 
           y = pct_NCI
       )) + 
    geom_point(alpha = 0.1) + 
    geom_smooth()
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
<<<<<<< HEAD

=======

>>>>>>> 6056c29c711690a9ae14a8e4ec179ee3356985e0
ggplot(district_filtered[sample(1000),],
       aes(x = pct_CC, 
           y = pct_CLI
       )) + 
    geom_point(alpha = 0.1) + 
    geom_smooth()
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
<<<<<<< HEAD

=======

>>>>>>> 6056c29c711690a9ae14a8e4ec179ee3356985e0

Immediately from all of these plots, we can notice that the vast majority of values for any given predictor are below 50%. We can notice that, similar to what our correlation matrix would have us believe, there appears to be a positive correlation between all of these variables.

Distribution of Number of Students

To get a better idea at what sorts of numbers we’re looking at in terms of the number of children in each shcool district, let’s look at a summary of the distribution. We’ll look at all school districts rather than just those with more than 100 students:

summary(district_data$children)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       0     445    1264    4353    3458 1213005

The mean of this distribution is well above the third quartile, implying that this data is heavily right-skewed. This makes sense, given the fact that there are so many small school districts and likely a few very large ones.

Because of the right-skewed nature of this data, let’s look at a log-transformed boxplot

district_data %>% 
    filter(children > 0) %>%
    ggplot(aes(x = children)) + 
    geom_boxplot() + 
    geom_jitter(aes(y = 0), alpha = 0.01, height = 0.05) + 
    scale_x_log10() + 
    geom_density()
<<<<<<< HEAD

=======

>>>>>>> 6056c29c711690a9ae14a8e4ec179ee3356985e0

Interestingly, when the number of children in each district is log-transformed, the density plot seems to be relatively symmetric about the median. Perhaps there’s some sort of log-normal distribution underlying the distribution of children in school districts in the U.S.?

Additionally, let’s see which school district has over a million estimated children aged 5 to 17.

district_data %>% 
    select(state, dist, children) %>%
    arrange(desc(children)) %>%
    head(5)
## # A tibble: 5 × 3
##   state       dist                                  children
##   <chr>       <chr>                                    <dbl>
## 1 New York    New York City Department Of Education  1213005
## 2 California  Los Angeles Unified School District     724446
## 3 Puerto Rico Puerto Rico                             529844
## 4 Illinois    Chicago Public School District 299      399883
## 5 Florida     Dade County School District             396516

Makes sense. Is this actually a school district, or is it a conglomerate of school districts? We’ll assume that the data is good, and that the New York City Department of Education is, in fact, classified as a school district.

<<<<<<< HEAD
LS0tCnRpdGxlOiAiUHJlbGltaW5hcnkgQW5hbHlzaXMiCmF1dGhvcjogIkpvbiBHZWlnZXIsIE5vZWwgR29vZHdpbiwgQWJpZ2FpbCBKb3BwYSIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6IG9wZW5pbnRybzo6bGFiX3JlcG9ydAotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAoKIyBJbXBvcnRpbmcgUGFja2FnZXMKCmBgYHtyLCBtZXNzYWdlPUZ9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHJlYWR4bCkKbGlicmFyeShjb3JycGxvdCkKYGBgCgojIEltcG9ydGluZyBhbmQgQ2xlYW5pbmcgRGF0YQoKYGBge3J9CmRpc3RyaWN0X2RhdGEgPC0gcmVhZF9leGNlbCgiLi4vcmF3L05IR0lTX0Rpc3RyaWN0X2RhdGEueGxzeCIpCmBgYAoKRm9ydHVuYXRlbHksIHRoZXJlIGlzbid0IG11Y2ggaW5pdGlhbCByZXN0cnVjdHVyaW5nIHJlcXVpcmVkIG9mIHRoaXMgZGF0YS4gCgpgYGB7cn0KbmFtZXMoZGlzdHJpY3RfZGF0YSkKYGBgCgpMZXQncyB3b3JrIG9uIHJlbmFtaW5nIG91ciB2YXJpYWJsZXMgdG8gbW9yZSBgUmAtZnJpZW5kbHkgbmFtZXMuIAoKYGBge3J9Cm5hbWVzX2xpc3QgPC0gYygKICAgICJzY2hvb2xfSUQiLCAKICAgICJzdGF0ZSIsIAogICAgImRpc3QiLCAgIyBHZW9ncmFwaGljIFNjaG9vbCBEaXN0cmljdCAKICAgICJjaGlsZHJlbiIsICMgQ2hpbGRyZW4gNS0xNyAoU0FJUEUgRXN0aW1hdGUpCiAgICAicGN0X3BvdiIsICMgJSBQb3ZlcnR5IChTQUlQRSBFc3RpbWF0ZSkKICAgICJwY3RfU1AiLCAjICUgU2luZ2xlIFBhcmVudCBFc3RpbWF0ZQogICAgIlNQX01PRSIsICMgU2luZ2xlIFBhcmVudCBNYXJnaW4gb2YgRXJyb3IKICAgICJwY3RfSEhWSiIsICMgJSBISHMgV2l0aCBWdWxuZXJhYmxlIEpvYiBFc3RpbWF0ZQogICAgIkhIVkpfTU9FIiwgIyBWdWxuZXJhYmxlIEpvYiBNYXJnaW4gb2YgRXJyb3IKICAgICJwY3RfQ0MiLCAjICUgQ3Jvd2RlZCBDb25kaXRpb25zIEVzdGltYXRlCiAgICAiQ0NfTU9FIiwgIyBISCBXaXRoIENyb3dkZWQgQ29uZGl0aW9ucyBNYXJnaW4gb2YgRXJyb3IKICAgICJwY3RfTkNJIiwgIyAlIE5vIENvbXB1dGVyIG9yIEludGVybmV0IEVzdGltYXRlCiAgICAibmNpX01PRSIsICMgTm8gQ29tcHV0ZXIgb3IgSW50ZXJuZXQgTWFyZ2luIG9mIEVycm9yCiAgICAicGN0X0NEIiwgIyAlIENoaWxkcmVuIHdpdGggRGlzYWJpbGl0eQogICAgIkNEX01PRSIsICMgQ2hpbGRyZW4gd2l0aCBEaXNhYmlsaXR5IE1hcmdpbiBvZiBFcnJvcgogICAgInBjdF9DTEkiLCAjICUgTGluZ3Vpc3RpY2FsbHkgSXNvbGF0ZWQgQ2hpbGRyZW4KICAgICJDTElfTU9FIiAjIExpbmd1aXN0aWNhbGx5IElzb2xhdGVkIENoaWxkcmVuIE1hcmdpbiBvZiBFcnJvcgopCm5hbWVzKGRpc3RyaWN0X2RhdGEpIDwtIG5hbWVzX2xpc3QKZGlzdHJpY3RfcGN0cyA8LSBkaXN0cmljdF9kYXRhICU+JQogICAgc2VsZWN0KC1lbmRzX3dpdGgoIk1PRSIpKSAKYGBgCgpXZSBtYWtlIGEgbmV3IGRhdGFzZXQsIGBkaXN0cmljdF9wY3RzYCwgd2hpY2ggY29udGFpbnMgYWxsIHRoZSB2YWx1ZXMgd2l0aG91dCBhbnkgb2YgdGhlIG1hcmdpbnMgb2YgZXJyb3IuIAoKV2UgY2FuIG5vdyBkbyBzb21lIHByZWxpbWluYXJ5IGFuYWx5c2lzIG9uIHRoaXMgZGF0YS4gTGV0J3MgZmlyc3Qgc2VlIGlmIHRoZXJlJ3MgYW55IE5BL21pc3NpbmcgZGF0YToKCmBgYHtyfQpkaXN0cmljdF9kYXRhICU+JSAKICAgIGlzLm5hKCkgJT4lIAogICAgY29sU3VtcygpCmBgYAoKRm9ydHVuYXRlbHksIHRoZXJlIGRvbid0IGFwcGVhciB0byBiZSBhbnkgTkEgdmFsdWVzIGluIGFueSBvZiB0aGUgcGVyY2VudGFnZSBjb2x1bW5zLiAKCiMgQW5hbHlzaXMKCiMjIFZhcmlhYmxlIENvcnJlbGF0aW9ucwoKTGV0J3MgY2hlY2sgb3V0IHNvbWUgdmFyaWFibGUgY29ycmVsYXRpb25zOiAKCmBgYHtyfQpkaXN0cmljdF9wY3RzWyw0Om5jb2woZGlzdHJpY3RfcGN0cyldICU+JSAKICAgIGNvcigpICU+JQogICAgY29ycnBsb3QobWV0aG9kID0gIm51bWJlciIpCmBgYApCYXNlZCBvbiB0aGUgY29ycmVsYXRpb25zLCBpdCBtaWdodCBtYWtlIHNlbnNlIHRvIHBsb3Qgc29tZSB2YXJpYWJsZXMgYWdhaW5zdCBlYWNoIG90aGVyIHRvIHNlZSBzb21lIGluaXRpYWwgdHJlbmRzLiBXZSB3aWxsIGNob29zZSBhIGN1dG9mZiBjb3JyZWxhdGlvbiB2YWx1ZSBvZiAwLjMgdG8gZGlzdGluZ3Vpc2ggdmFyaWFibGVzIHdoaWNoIG1heSBiZSBvZiBpbnRlcmVzdC4gVGhpcyBpcyBjb21wbGV0ZWx5IGFyYml0cmFyeSwgYnV0IGxpbWl0cyB0aGUgYW1vdW50IG9mIHBsb3RzIHdlIG5lZWQgdG8gbWFrZSBzdWNoIHRoYXQgdGhlIGFuYWx5c2lzIGlzIG5vdCBlbnRpcmVseSBjdW1iZXJzb21lLiAKCkFkZGl0aW9uYWxseSwgd2Ugd2lsbCBvbmx5IGNvbnNpZGVyIHNjaG9vbCBkaXN0cmljdHMgd2hpY2ggaGF2ZSBtb3JlIHRoYW4gMTAwIHN0dWRlbnRzLiBUaGlzIGVsaW1pbmF0ZXMgb3V0bHlpbmcgdmFsdWVzIHdoaWNoIGFwcGVhciBmb3IgbG93IG51bWJlcnMgb2Ygc3R1ZGVudHMsIHN1Y2ggYXMgbWVhc3VyZXMgZXF1YWwgdG8gMTAwJS4gQXMgYW4gZXhhbXBsZSwgd2UgY2FuIGxvb2sgYXQgdGhlIHZhcmlhYmxlIGBwY3RfcG92YDsgdGhlcmUgYXJlIGEgZmV3IGRhdGEgcG9pbnRzIGF0IHRoZSAxMDAlIG1hcmssIHNvIGxldCdzIGxvb2sgYXQgdGhlc2UgdmFsdWVzOiAKYGBge3J9CmRpc3RyaWN0X2RhdGEgJT4lIAogICAgZmlsdGVyKHBjdF9wb3YgPT0gMSkgJT4lIAogICAgYXJyYW5nZShwY3RfcG92KSAlPiUKICAgIHNlbGVjdChzdGF0ZSwgZGlzdCwgY2hpbGRyZW4sIHBjdF9wb3YpCmBgYAoKQmVjYXVzZSBvZiB0aGlzIGxvdyBudW1iZXIgb2YgY2hpbGRyZW4gYWZmZWN0aW5nIHRoZSB2YWx1ZXMgb2YgdGhlIHZhcmlhYmxlcyBzbyBtdWNoLCB3ZSdsbCBzZXQgMTAwIHRvIGJlIHRoYXQgY3V0b2ZmIHZhbHVlIGFuZCBjb250aW51ZSB3aXRoIGFuYWx5c2lzLiBBZGRpdGlvbmFsbHksIHNpbmNlIHdlIGhhdmUgb3ZlciAxMCwwMDAgcm93cyBpbiBvdXIgZGF0YXNldCwgd2UgcmFuZG9tbHkgc2FtcGxlIDEwMDAgb2YgdGhlc2UgdmFsdWVzIGZvciBlYWNoIG9mIHRoZSBmb2xsb3dpbmcgcGxvdHMuCgojIyBDb3JyZWxhdGVkIFZhcmlhYmxlIFBsb3RzCgpgYGB7cn0KZGlzdHJpY3RfZmlsdGVyZWQgPC0gZGlzdHJpY3RfZGF0YSAlPiUKICAgIGZpbHRlcihjaGlsZHJlbiA+IDEwMCkKbnJvdyhkaXN0cmljdF9kYXRhKSAtIG5yb3coZGlzdHJpY3RfZmlsdGVyZWQpCgpnZ3Bsb3QoZGlzdHJpY3RfZmlsdGVyZWRbc2FtcGxlKDEwMDApLF0sCiAgICAgICBhZXMoeCA9IHBjdF9wb3YsIAogICAgICAgICAgIHkgPSBwY3RfU1AKICAgICAgICkpICsgCiAgICBnZW9tX3BvaW50KGFscGhhID0gMC4xKSArIAogICAgZ2VvbV9zbW9vdGgoKQoKZ2dwbG90KGRpc3RyaWN0X2ZpbHRlcmVkW3NhbXBsZSgxMDAwKSxdLAogICAgICAgYWVzKHggPSBwY3RfcG92LCAKICAgICAgICAgICB5ID0gcGN0X0NDCiAgICAgICApKSArIAogICAgZ2VvbV9wb2ludChhbHBoYSA9IDAuMSkgKyAKICAgIGdlb21fc21vb3RoKCkKCmdncGxvdChkaXN0cmljdF9maWx0ZXJlZFtzYW1wbGUoMTAwMCksXSwKICAgICAgIGFlcyh4ID0gcGN0X3BvdiwgCiAgICAgICAgICAgeSA9IHBjdF9OQ0kKICAgICAgICkpICsgCiAgICBnZW9tX3BvaW50KGFscGhhID0gMC4xKSArIAogICAgZ2VvbV9zbW9vdGgoKQoKZ2dwbG90KGRpc3RyaWN0X2ZpbHRlcmVkW3NhbXBsZSgxMDAwKSxdLAogICAgICAgYWVzKHggPSBwY3RfU1AsIAogICAgICAgICAgIHkgPSBwY3RfTkNJCiAgICAgICApKSArIAogICAgZ2VvbV9wb2ludChhbHBoYSA9IDAuMSkgKyAKICAgIGdlb21fc21vb3RoKCkKCmdncGxvdChkaXN0cmljdF9maWx0ZXJlZFtzYW1wbGUoMTAwMCksXSwKICAgICAgIGFlcyh4ID0gcGN0X0NDLCAKICAgICAgICAgICB5ID0gcGN0X05DSQogICAgICAgKSkgKyAKICAgIGdlb21fcG9pbnQoYWxwaGEgPSAwLjEpICsgCiAgICBnZW9tX3Ntb290aCgpCgpnZ3Bsb3QoZGlzdHJpY3RfZmlsdGVyZWRbc2FtcGxlKDEwMDApLF0sCiAgICAgICBhZXMoeCA9IHBjdF9DQywgCiAgICAgICAgICAgeSA9IHBjdF9DTEkKICAgICAgICkpICsgCiAgICBnZW9tX3BvaW50KGFscGhhID0gMC4xKSArIAogICAgZ2VvbV9zbW9vdGgoKQpgYGAKCkltbWVkaWF0ZWx5IGZyb20gYWxsIG9mIHRoZXNlIHBsb3RzLCB3ZSBjYW4gbm90aWNlIHRoYXQgdGhlIHZhc3QgbWFqb3JpdHkgb2YgdmFsdWVzIGZvciBhbnkgZ2l2ZW4gcHJlZGljdG9yIGFyZSBiZWxvdyA1MCUuIFdlIGNhbiBub3RpY2UgdGhhdCwgc2ltaWxhciB0byB3aGF0IG91ciBjb3JyZWxhdGlvbiBtYXRyaXggd291bGQgaGF2ZSB1cyBiZWxpZXZlLCB0aGVyZSBhcHBlYXJzIHRvIGJlIGEgcG9zaXRpdmUgY29ycmVsYXRpb24gYmV0d2VlbiBhbGwgb2YgdGhlc2UgdmFyaWFibGVzLgoKIyMgRGlzdHJpYnV0aW9uIG9mIE51bWJlciBvZiBTdHVkZW50cwoKVG8gZ2V0IGEgYmV0dGVyIGlkZWEgYXQgd2hhdCBzb3J0cyBvZiBudW1iZXJzIHdlJ3JlIGxvb2tpbmcgYXQgaW4gdGVybXMgb2YgdGhlIG51bWJlciBvZiBjaGlsZHJlbiBpbiBlYWNoIHNoY29vbCBkaXN0cmljdCwgbGV0J3MgbG9vayBhdCBhIHN1bW1hcnkgb2YgdGhlIGRpc3RyaWJ1dGlvbi4gV2UnbGwgbG9vayBhdCBhbGwgc2Nob29sIGRpc3RyaWN0cyByYXRoZXIgdGhhbiBqdXN0IHRob3NlIHdpdGggbW9yZSB0aGFuIDEwMCBzdHVkZW50czogCmBgYHtyfQpzdW1tYXJ5KGRpc3RyaWN0X2RhdGEkY2hpbGRyZW4pCmBgYApUaGUgbWVhbiBvZiB0aGlzIGRpc3RyaWJ1dGlvbiBpcyB3ZWxsIGFib3ZlIHRoZSB0aGlyZCBxdWFydGlsZSwgaW1wbHlpbmcgdGhhdCB0aGlzIGRhdGEgaXMgaGVhdmlseSByaWdodC1za2V3ZWQuIFRoaXMgbWFrZXMgc2Vuc2UsIGdpdmVuIHRoZSBmYWN0IHRoYXQgdGhlcmUgYXJlIHNvIG1hbnkgc21hbGwgc2Nob29sIGRpc3RyaWN0cyBhbmQgbGlrZWx5IGEgZmV3IHZlcnkgbGFyZ2Ugb25lcy4gCgpCZWNhdXNlIG9mIHRoZSByaWdodC1za2V3ZWQgbmF0dXJlIG9mIHRoaXMgZGF0YSwgbGV0J3MgbG9vayBhdCBhIGxvZy10cmFuc2Zvcm1lZCBib3hwbG90CgpgYGB7cn0KZGlzdHJpY3RfZGF0YSAlPiUgCiAgICBmaWx0ZXIoY2hpbGRyZW4gPiAwKSAlPiUKICAgIGdncGxvdChhZXMoeCA9IGNoaWxkcmVuKSkgKyAKICAgIGdlb21fYm94cGxvdCgpICsgCiAgICBnZW9tX2ppdHRlcihhZXMoeSA9IDApLCBhbHBoYSA9IDAuMDEsIGhlaWdodCA9IDAuMDUpICsgCiAgICBzY2FsZV94X2xvZzEwKCkgKyAKICAgIGdlb21fZGVuc2l0eSgpCmBgYAoKSW50ZXJlc3RpbmdseSwgd2hlbiB0aGUgbnVtYmVyIG9mIGNoaWxkcmVuIGluIGVhY2ggZGlzdHJpY3QgaXMgbG9nLXRyYW5zZm9ybWVkLCB0aGUgZGVuc2l0eSBwbG90IHNlZW1zIHRvIGJlIHJlbGF0aXZlbHkgc3ltbWV0cmljIGFib3V0IHRoZSBtZWRpYW4uIFBlcmhhcHMgdGhlcmUncyBzb21lIHNvcnQgb2YgbG9nLW5vcm1hbCBkaXN0cmlidXRpb24gdW5kZXJseWluZyB0aGUgZGlzdHJpYnV0aW9uIG9mIGNoaWxkcmVuIGluIHNjaG9vbCBkaXN0cmljdHMgaW4gdGhlIFUuUy4/CgpBZGRpdGlvbmFsbHksIGxldCdzIHNlZSB3aGljaCBzY2hvb2wgZGlzdHJpY3QgaGFzIG92ZXIgYSBtaWxsaW9uIGVzdGltYXRlZCBjaGlsZHJlbiBhZ2VkIDUgdG8gMTcuIApgYGB7cn0KZGlzdHJpY3RfZGF0YSAlPiUgCiAgICBzZWxlY3Qoc3RhdGUsIGRpc3QsIGNoaWxkcmVuKSAlPiUKICAgIGFycmFuZ2UoZGVzYyhjaGlsZHJlbikpICU+JQogICAgaGVhZCg1KQpgYGAKTWFrZXMgc2Vuc2UuIElzIHRoaXMgYWN0dWFsbHkgYSBzY2hvb2wgZGlzdHJpY3QsIG9yIGlzIGl0IGEgY29uZ2xvbWVyYXRlIG9mIHNjaG9vbCBkaXN0cmljdHM/IFdlJ2xsIGFzc3VtZSB0aGF0IHRoZSBkYXRhIGlzIGdvb2QsIGFuZCB0aGF0IHRoZSBOZXcgWW9yayBDaXR5IERlcGFydG1lbnQgb2YgRWR1Y2F0aW9uIGlzLCBpbiBmYWN0LCBjbGFzc2lmaWVkIGFzIGEgc2Nob29sIGRpc3RyaWN0LiAKCg==
=======
LS0tCnRpdGxlOiAiUHJlbGltaW5hcnkgQW5hbHlzaXMiCmF1dGhvcjogIkpvbiBHZWlnZXIsIE5vZWwgR29vZHdpbiwgQWJpZ2FpbCBKb3BwYSIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6IG9wZW5pbnRybzo6bGFiX3JlcG9ydAotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAoKIyBJbXBvcnRpbmcgUGFja2FnZXMKCmBgYHtyLCBtZXNzYWdlPUZ9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHJlYWR4bCkKbGlicmFyeShjb3JycGxvdCkKbGlicmFyeShnZ3RoZW1lcykKdGhlbWVfc2V0KHRoZW1lX2NsZWFuKCkpCmBgYAoKIyBJbXBvcnRpbmcgYW5kIENsZWFuaW5nIERhdGEKCmBgYHtyfQpkaXN0cmljdF9kYXRhIDwtIHJlYWRfZXhjZWwoIi4uL3Jhdy9OSEdJU19EaXN0cmljdF9kYXRhLnhsc3giKQpgYGAKCkZvcnR1bmF0ZWx5LCB0aGVyZSBpc24ndCBtdWNoIGluaXRpYWwgcmVzdHJ1Y3R1cmluZyByZXF1aXJlZCBvZiB0aGlzIGRhdGEuIAoKYGBge3J9Cm5hbWVzKGRpc3RyaWN0X2RhdGEpCmBgYAoKTGV0J3Mgd29yayBvbiByZW5hbWluZyBvdXIgdmFyaWFibGVzIHRvIG1vcmUgYFJgLWZyaWVuZGx5IG5hbWVzLiAKCmBgYHtyfQpuYW1lc19saXN0IDwtIGMoCiAgICAic2Nob29sX0lEIiwgCiAgICAic3RhdGUiLCAKICAgICJkaXN0IiwgICMgR2VvZ3JhcGhpYyBTY2hvb2wgRGlzdHJpY3QgCiAgICAiY2hpbGRyZW4iLCAjIENoaWxkcmVuIDUtMTcgKFNBSVBFIEVzdGltYXRlKQogICAgInBjdF9wb3YiLCAjICUgUG92ZXJ0eSAoU0FJUEUgRXN0aW1hdGUpCiAgICAicGN0X1NQIiwgIyAlIFNpbmdsZSBQYXJlbnQgRXN0aW1hdGUKICAgICJTUF9NT0UiLCAjIFNpbmdsZSBQYXJlbnQgTWFyZ2luIG9mIEVycm9yCiAgICAicGN0X0hIVkoiLCAjICUgSEhzIFdpdGggVnVsbmVyYWJsZSBKb2IgRXN0aW1hdGUKICAgICJISFZKX01PRSIsICMgVnVsbmVyYWJsZSBKb2IgTWFyZ2luIG9mIEVycm9yCiAgICAicGN0X0NDIiwgIyAlIENyb3dkZWQgQ29uZGl0aW9ucyBFc3RpbWF0ZQogICAgIkNDX01PRSIsICMgSEggV2l0aCBDcm93ZGVkIENvbmRpdGlvbnMgTWFyZ2luIG9mIEVycm9yCiAgICAicGN0X05DSSIsICMgJSBObyBDb21wdXRlciBvciBJbnRlcm5ldCBFc3RpbWF0ZQogICAgIm5jaV9NT0UiLCAjIE5vIENvbXB1dGVyIG9yIEludGVybmV0IE1hcmdpbiBvZiBFcnJvcgogICAgInBjdF9DRCIsICMgJSBDaGlsZHJlbiB3aXRoIERpc2FiaWxpdHkKICAgICJDRF9NT0UiLCAjIENoaWxkcmVuIHdpdGggRGlzYWJpbGl0eSBNYXJnaW4gb2YgRXJyb3IKICAgICJwY3RfQ0xJIiwgIyAlIExpbmd1aXN0aWNhbGx5IElzb2xhdGVkIENoaWxkcmVuCiAgICAiQ0xJX01PRSIgIyBMaW5ndWlzdGljYWxseSBJc29sYXRlZCBDaGlsZHJlbiBNYXJnaW4gb2YgRXJyb3IKKQpuYW1lcyhkaXN0cmljdF9kYXRhKSA8LSBuYW1lc19saXN0CmRpc3RyaWN0X3BjdHMgPC0gZGlzdHJpY3RfZGF0YSAlPiUKICAgIHNlbGVjdCgtZW5kc193aXRoKCJNT0UiKSkgCmBgYAoKV2UgbWFrZSBhIG5ldyBkYXRhc2V0LCBgZGlzdHJpY3RfcGN0c2AsIHdoaWNoIGNvbnRhaW5zIGFsbCB0aGUgdmFsdWVzIHdpdGhvdXQgYW55IG9mIHRoZSBtYXJnaW5zIG9mIGVycm9yLiAKCldlIGNhbiBub3cgZG8gc29tZSBwcmVsaW1pbmFyeSBhbmFseXNpcyBvbiB0aGlzIGRhdGEuIExldCdzIGZpcnN0IHNlZSBpZiB0aGVyZSdzIGFueSBOQS9taXNzaW5nIGRhdGE6CgpgYGB7cn0KZGlzdHJpY3RfZGF0YSAlPiUgCiAgICBpcy5uYSgpICU+JSAKICAgIGNvbFN1bXMoKQpgYGAKCkZvcnR1bmF0ZWx5LCB0aGVyZSBkb24ndCBhcHBlYXIgdG8gYmUgYW55IE5BIHZhbHVlcyBpbiBhbnkgb2YgdGhlIHBlcmNlbnRhZ2UgY29sdW1ucy4gCgojIEFuYWx5c2lzCgojIyBWYXJpYWJsZSBDb3JyZWxhdGlvbnMKCkxldCdzIGNoZWNrIG91dCBzb21lIHZhcmlhYmxlIGNvcnJlbGF0aW9uczogCgpgYGB7cn0KZGlzdHJpY3RfcGN0c1ssNDpuY29sKGRpc3RyaWN0X3BjdHMpXSAlPiUgCiAgICBjb3IoKSAlPiUKICAgIGNvcnJwbG90KG1ldGhvZCA9ICJudW1iZXIiKQpgYGAKQmFzZWQgb24gdGhlIGNvcnJlbGF0aW9ucywgaXQgbWlnaHQgbWFrZSBzZW5zZSB0byBwbG90IHNvbWUgdmFyaWFibGVzIGFnYWluc3QgZWFjaCBvdGhlciB0byBzZWUgc29tZSBpbml0aWFsIHRyZW5kcy4gV2Ugd2lsbCBjaG9vc2UgYSBjdXRvZmYgY29ycmVsYXRpb24gdmFsdWUgb2YgMC4zIHRvIGRpc3Rpbmd1aXNoIHZhcmlhYmxlcyB3aGljaCBtYXkgYmUgb2YgaW50ZXJlc3QuIFRoaXMgaXMgY29tcGxldGVseSBhcmJpdHJhcnksIGJ1dCBsaW1pdHMgdGhlIGFtb3VudCBvZiBwbG90cyB3ZSBuZWVkIHRvIG1ha2Ugc3VjaCB0aGF0IHRoZSBhbmFseXNpcyBpcyBub3QgZW50aXJlbHkgY3VtYmVyc29tZS4gCgpBZGRpdGlvbmFsbHksIHdlIHdpbGwgb25seSBjb25zaWRlciBzY2hvb2wgZGlzdHJpY3RzIHdoaWNoIGhhdmUgbW9yZSB0aGFuIDEwMCBzdHVkZW50cy4gVGhpcyBlbGltaW5hdGVzIG91dGx5aW5nIHZhbHVlcyB3aGljaCBhcHBlYXIgZm9yIGxvdyBudW1iZXJzIG9mIHN0dWRlbnRzLCBzdWNoIGFzIG1lYXN1cmVzIGVxdWFsIHRvIDEwMCUuIEFzIGFuIGV4YW1wbGUsIHdlIGNhbiBsb29rIGF0IHRoZSB2YXJpYWJsZSBgcGN0X3BvdmA7IHRoZXJlIGFyZSBhIGZldyBkYXRhIHBvaW50cyBhdCB0aGUgMTAwJSBtYXJrLCBzbyBsZXQncyBsb29rIGF0IHRoZXNlIHZhbHVlczogCmBgYHtyfQpkaXN0cmljdF9kYXRhICU+JSAKICAgIGZpbHRlcihwY3RfcG92ID09IDEpICU+JSAKICAgIGFycmFuZ2UocGN0X3BvdikgJT4lCiAgICBzZWxlY3Qoc3RhdGUsIGRpc3QsIGNoaWxkcmVuLCBwY3RfcG92KQpgYGAKCkJlY2F1c2Ugb2YgdGhpcyBsb3cgbnVtYmVyIG9mIGNoaWxkcmVuIGFmZmVjdGluZyB0aGUgdmFsdWVzIG9mIHRoZSB2YXJpYWJsZXMgc28gbXVjaCwgd2UnbGwgc2V0IDEwMCB0byBiZSB0aGF0IGN1dG9mZiB2YWx1ZSBhbmQgY29udGludWUgd2l0aCBhbmFseXNpcy4gQWRkaXRpb25hbGx5LCBzaW5jZSB3ZSBoYXZlIG92ZXIgMTAsMDAwIHJvd3MgaW4gb3VyIGRhdGFzZXQsIHdlIHJhbmRvbWx5IHNhbXBsZSAxMDAwIG9mIHRoZXNlIHZhbHVlcyBmb3IgZWFjaCBvZiB0aGUgZm9sbG93aW5nIHBsb3RzLgoKIyMgQ29ycmVsYXRlZCBWYXJpYWJsZSBQbG90cwoKYGBge3J9CmRpc3RyaWN0X2ZpbHRlcmVkIDwtIGRpc3RyaWN0X2RhdGEgJT4lCiAgICBmaWx0ZXIoY2hpbGRyZW4gPiAxMDApCm5yb3coZGlzdHJpY3RfZGF0YSkgLSBucm93KGRpc3RyaWN0X2ZpbHRlcmVkKQoKZ2dwbG90KGRpc3RyaWN0X2ZpbHRlcmVkW3NhbXBsZSgxMDAwKSxdLAogICAgICAgYWVzKHggPSBwY3RfcG92LCAKICAgICAgICAgICB5ID0gcGN0X1NQCiAgICAgICApKSArIAogICAgZ2VvbV9wb2ludChhbHBoYSA9IDAuMSkgKyAKICAgIGdlb21fc21vb3RoKCkKCmdncGxvdChkaXN0cmljdF9maWx0ZXJlZFtzYW1wbGUoMTAwMCksXSwKICAgICAgIGFlcyh4ID0gcGN0X3BvdiwgCiAgICAgICAgICAgeSA9IHBjdF9DQwogICAgICAgKSkgKyAKICAgIGdlb21fcG9pbnQoYWxwaGEgPSAwLjEpICsgCiAgICBnZW9tX3Ntb290aCgpCgpnZ3Bsb3QoZGlzdHJpY3RfZmlsdGVyZWRbc2FtcGxlKDEwMDApLF0sCiAgICAgICBhZXMoeCA9IHBjdF9wb3YsIAogICAgICAgICAgIHkgPSBwY3RfTkNJCiAgICAgICApKSArIAogICAgZ2VvbV9wb2ludChhbHBoYSA9IDAuMSkgKyAKICAgIGdlb21fc21vb3RoKCkKCmdncGxvdChkaXN0cmljdF9maWx0ZXJlZFtzYW1wbGUoMTAwMCksXSwKICAgICAgIGFlcyh4ID0gcGN0X1NQLCAKICAgICAgICAgICB5ID0gcGN0X05DSQogICAgICAgKSkgKyAKICAgIGdlb21fcG9pbnQoYWxwaGEgPSAwLjEpICsgCiAgICBnZW9tX3Ntb290aCgpCgpnZ3Bsb3QoZGlzdHJpY3RfZmlsdGVyZWRbc2FtcGxlKDEwMDApLF0sCiAgICAgICBhZXMoeCA9IHBjdF9DQywgCiAgICAgICAgICAgeSA9IHBjdF9OQ0kKICAgICAgICkpICsgCiAgICBnZW9tX3BvaW50KGFscGhhID0gMC4xKSArIAogICAgZ2VvbV9zbW9vdGgoKQoKZ2dwbG90KGRpc3RyaWN0X2ZpbHRlcmVkW3NhbXBsZSgxMDAwKSxdLAogICAgICAgYWVzKHggPSBwY3RfQ0MsIAogICAgICAgICAgIHkgPSBwY3RfQ0xJCiAgICAgICApKSArIAogICAgZ2VvbV9wb2ludChhbHBoYSA9IDAuMSkgKyAKICAgIGdlb21fc21vb3RoKCkKYGBgCgpJbW1lZGlhdGVseSBmcm9tIGFsbCBvZiB0aGVzZSBwbG90cywgd2UgY2FuIG5vdGljZSB0aGF0IHRoZSB2YXN0IG1ham9yaXR5IG9mIHZhbHVlcyBmb3IgYW55IGdpdmVuIHByZWRpY3RvciBhcmUgYmVsb3cgNTAlLiBXZSBjYW4gbm90aWNlIHRoYXQsIHNpbWlsYXIgdG8gd2hhdCBvdXIgY29ycmVsYXRpb24gbWF0cml4IHdvdWxkIGhhdmUgdXMgYmVsaWV2ZSwgdGhlcmUgYXBwZWFycyB0byBiZSBhIHBvc2l0aXZlIGNvcnJlbGF0aW9uIGJldHdlZW4gYWxsIG9mIHRoZXNlIHZhcmlhYmxlcy4KCiMjIERpc3RyaWJ1dGlvbiBvZiBOdW1iZXIgb2YgU3R1ZGVudHMKClRvIGdldCBhIGJldHRlciBpZGVhIGF0IHdoYXQgc29ydHMgb2YgbnVtYmVycyB3ZSdyZSBsb29raW5nIGF0IGluIHRlcm1zIG9mIHRoZSBudW1iZXIgb2YgY2hpbGRyZW4gaW4gZWFjaCBzaGNvb2wgZGlzdHJpY3QsIGxldCdzIGxvb2sgYXQgYSBzdW1tYXJ5IG9mIHRoZSBkaXN0cmlidXRpb24uIFdlJ2xsIGxvb2sgYXQgYWxsIHNjaG9vbCBkaXN0cmljdHMgcmF0aGVyIHRoYW4ganVzdCB0aG9zZSB3aXRoIG1vcmUgdGhhbiAxMDAgc3R1ZGVudHM6IApgYGB7cn0Kc3VtbWFyeShkaXN0cmljdF9kYXRhJGNoaWxkcmVuKQpgYGAKVGhlIG1lYW4gb2YgdGhpcyBkaXN0cmlidXRpb24gaXMgd2VsbCBhYm92ZSB0aGUgdGhpcmQgcXVhcnRpbGUsIGltcGx5aW5nIHRoYXQgdGhpcyBkYXRhIGlzIGhlYXZpbHkgcmlnaHQtc2tld2VkLiBUaGlzIG1ha2VzIHNlbnNlLCBnaXZlbiB0aGUgZmFjdCB0aGF0IHRoZXJlIGFyZSBzbyBtYW55IHNtYWxsIHNjaG9vbCBkaXN0cmljdHMgYW5kIGxpa2VseSBhIGZldyB2ZXJ5IGxhcmdlIG9uZXMuIAoKQmVjYXVzZSBvZiB0aGUgcmlnaHQtc2tld2VkIG5hdHVyZSBvZiB0aGlzIGRhdGEsIGxldCdzIGxvb2sgYXQgYSBsb2ctdHJhbnNmb3JtZWQgYm94cGxvdAoKYGBge3J9CmRpc3RyaWN0X2RhdGEgJT4lIAogICAgZmlsdGVyKGNoaWxkcmVuID4gMCkgJT4lCiAgICBnZ3Bsb3QoYWVzKHggPSBjaGlsZHJlbikpICsgCiAgICBnZW9tX2JveHBsb3QoKSArIAogICAgZ2VvbV9qaXR0ZXIoYWVzKHkgPSAwKSwgYWxwaGEgPSAwLjAxLCBoZWlnaHQgPSAwLjA1KSArIAogICAgc2NhbGVfeF9sb2cxMCgpICsgCiAgICBnZW9tX2RlbnNpdHkoKQpgYGAKCkludGVyZXN0aW5nbHksIHdoZW4gdGhlIG51bWJlciBvZiBjaGlsZHJlbiBpbiBlYWNoIGRpc3RyaWN0IGlzIGxvZy10cmFuc2Zvcm1lZCwgdGhlIGRlbnNpdHkgcGxvdCBzZWVtcyB0byBiZSByZWxhdGl2ZWx5IHN5bW1ldHJpYyBhYm91dCB0aGUgbWVkaWFuLiBQZXJoYXBzIHRoZXJlJ3Mgc29tZSBzb3J0IG9mIGxvZy1ub3JtYWwgZGlzdHJpYnV0aW9uIHVuZGVybHlpbmcgdGhlIGRpc3RyaWJ1dGlvbiBvZiBjaGlsZHJlbiBpbiBzY2hvb2wgZGlzdHJpY3RzIGluIHRoZSBVLlMuPwoKQWRkaXRpb25hbGx5LCBsZXQncyBzZWUgd2hpY2ggc2Nob29sIGRpc3RyaWN0IGhhcyBvdmVyIGEgbWlsbGlvbiBlc3RpbWF0ZWQgY2hpbGRyZW4gYWdlZCA1IHRvIDE3LiAKYGBge3J9CmRpc3RyaWN0X2RhdGEgJT4lIAogICAgc2VsZWN0KHN0YXRlLCBkaXN0LCBjaGlsZHJlbikgJT4lCiAgICBhcnJhbmdlKGRlc2MoY2hpbGRyZW4pKSAlPiUKICAgIGhlYWQoNSkKYGBgCk1ha2VzIHNlbnNlLiBJcyB0aGlzIGFjdHVhbGx5IGEgc2Nob29sIGRpc3RyaWN0LCBvciBpcyBpdCBhIGNvbmdsb21lcmF0ZSBvZiBzY2hvb2wgZGlzdHJpY3RzPyBXZSdsbCBhc3N1bWUgdGhhdCB0aGUgZGF0YSBpcyBnb29kLCBhbmQgdGhhdCB0aGUgTmV3IFlvcmsgQ2l0eSBEZXBhcnRtZW50IG9mIEVkdWNhdGlvbiBpcywgaW4gZmFjdCwgY2xhc3NpZmllZCBhcyBhIHNjaG9vbCBkaXN0cmljdC4gCgo=
>>>>>>> 6056c29c711690a9ae14a8e4ec179ee3356985e0