Summary
This notebook provides a detailed description of the IHDS 2011-12 household dataset and accompanying documentation. It also provides sample code to import the household dataset and use the survey and srvyr packages to perform inference using the dataset
Overview of IHDS data
IHDS is a panel survey led by Sonalde Desai and others at NCAER/UofMd. The first round of the panel was conducted in 2004-05 and the second wave was conducted in 2011-12. In both rounds of the survey they administered a test similar to the ASER test to all children aged 8-11. (The response rate for the ASER survey was not great though. In their publication for the India Policy Forum, Sonalde explains the reasons for this I think.) In addition, the survey asked basic questions about enrollment and education achievement for all household members.
Datasets and documentation
When you download the round 2 data, you get 14 datasets. These are split into folders “DS00X” where X corrresponds to the following:
- Individual
- Household
- Eligible Women
- Birth History 5.Medical Staff
- Medical Facilities
- Non Resident
- School Staff
- School Facilities
- Wage and Salary
- Tracking
- Village
- Village Panchayat
- Village Respondent
Note that, unlike the panel dataset, there is only one version of the files. (For the panel dataset, there are different versions of the files corresponding to different ways of merging/combining the two rounds of data.) More information about each of the datasets, including which variables to use for weighting observations when using each dataset and how to merge the datasets, can be found here. According to documentation, merge on stateid, distid, psuid, hh, hhsplitid
Documentation for the 2012 dataset is saved in the “IHDS/IHDS 2012” folder in my data folder. The user guide contains basic information about the sampling strategy and various constructed variables (e.g. the consumption variables). The data guide seems to just duplicate this information. To figure out which variables to use, go to the codebooks and questionnaires located in each of the
Finding variables in the datasets
The fastest way to find relevant variables in the dataset is to first search for keywords in the questionnaire to find the relevant question number and then search for the question number in the codebook. This can be a bit confusing since the variables in the codebook are organized by subject rather than ordered by question number. (For example, some of the education questions from the household roster are coded as “CS” questions and come later in the roster.)
Note that codebook section “ED5: HQ19 11.5 Education: Enrolled now” refers to variable ED5 in the dataset which comes from question 11.5 which is one page 19 of the household questionnaire.
Key education variables in the individual dataset (DS0001)
I have included a list of some of the key education-related variables (and other basic variables) below. Note that this list might not be comprehensive (i.e. there may be some ed related vars which I have missed).
Identifiers and other vars
- STATEID
- DISTID
- PSUID
- HHID
- HHSPLITID
- PERSONID
- IDPSU - this one might be unique, not sure
- WT - weights
- RO3 - sex
- RO7 - primary activity status
- RO5 - Age
Testing vars for children 8-11 (page 38 of questionnaire)
- TA8A, TA8B, TA9A, TA9B, TA10A, TA10B – Reading, math, and writing test results (vars with suffix “B” contain the results)
- TA* - other vars related to ASER test
Education vars for all members (page 23 of questionnaire)
- ED2-ED12 – ed-related info such as highest grade, current enrollment, etc for all household members.
Education vars all hh members who were enrolled in school in previous 12 months (page 44 of questionnaire)
- CS3 - in school
- CS4 - type of school
- CS5 - distance to school
- CS6 - standard years
- CS8 - medium of instruction
- CS9 - year English taught
- CS10 - school hours per week
- CS11 - homework hours per week
- CS12 - private tuition hours per week
- CS13 - days / months absent
- (and many more)
Education vars for children 8-11 (page 46 of questionnaire)
Sample code to read in key variables
Setup chunk
library(tidyverse)
Registered S3 method overwritten by 'dplyr':
method from
print.rowwise_df
Registered S3 methods overwritten by 'dbplyr':
method from
print.tbl_lazy
print.tbl_sql
[30m-- [1mAttaching packages[22m --------------------------------------- tidyverse 1.3.0 --[39m
[30m[32mv[30m [34mggplot2[30m 3.2.1 [32mv[30m [34mpurrr [30m 0.3.3
[32mv[30m [34mtibble [30m 2.1.3 [32mv[30m [34mdplyr [30m 0.8.3
[32mv[30m [34mtidyr [30m 1.0.0 [32mv[30m [34mstringr[30m 1.4.0
[32mv[30m [34mreadr [30m 1.3.1 [32mv[30m [34mforcats[30m 0.4.0[39m
[30m-- [1mConflicts[22m ------------------------------------------ tidyverse_conflicts() --
[31mx[30m [34mdplyr[30m::[32mfilter()[30m masks [34mstats[30m::filter()
[31mx[30m [34mdplyr[30m::[32mlag()[30m masks [34mstats[30m::lag()[39m
library(haven)
library(survey)
Loading required package: grid
Loading required package: Matrix
Attaching package: 㤼㸱Matrix㤼㸲
The following objects are masked from 㤼㸱package:tidyr㤼㸲:
expand, pack, unpack
Loading required package: survival
Attaching package: 㤼㸱survey㤼㸲
The following object is masked from 㤼㸱package:graphics㤼㸲:
dotchart
library(srvyr)
Attaching package: 㤼㸱srvyr㤼㸲
The following object is masked from 㤼㸱package:stats㤼㸲:
filter
Open the individual dataset (36151-0001) and select key education variables
ihds_ind_dir <- "C:/Users/dougj/Documents/Data/IHDS/IHDS 2012/DS0001"
ind_file <- file.path(ihds_ind_dir, "36151-0001-Data.dta")
# read in just those variables that i need
# this is much faster than reading in everything and then selecting
df <- read_dta(ind_file, col_select = c(STATEID, DISTID, PSUID, HHID, HHSPLITID, PERSONID, IDPSU, WT, RO3, RO7, RO5, starts_with("CS"), starts_with("TA"), starts_with("ED")))
Specify the survey design using the survey package
While the user guide has a short description of the sample, a clearer and more complete description can be found here. The dataset includes no variables for strata or fpc so we only specify a two-stage survey with the appropriate weights
df <- df %>% mutate(psu_expanded = paste(STATEID, DISTID, PSUID, sep ="-"), hh_expanded = paste(STATEID, DISTID, PSUID, HHID, HHSPLITID, sep ="-"))
# there is one row with a missing value for WT and most other variables drop that
df <- df %>% filter(!is.na(WT))
df_svy <- svydesign(id =~ psu_expanded + hh_expanded, weights =~ WT, data = df)
Calculate average ASER reading scores by state without using the survey package (but using weights), using the survey package, and then using the srvyr package. All yield the same answers. Note that the survey package and srvyr are both really slow.
# confirm we are looking at the right variable by looking at the variable label from Stata
attributes(df$TA8B)
$label
[1] "HQ34 26.8 Test: Reading level"
$labels
Cannot read 0 Letters 1 Words 2 Paragraph 3 Story 4
0 1 2 3 4
$class
[1] "haven_labelled"
attributes(df$RO5)$label
[1] "HQ4 2.5 Age"
# look at response rates to TA8B by age --> looks like there are some NAs even for 8 to 11.
# unclear why that is.
df %>%
group_by(RO5) %>%
summarise(non_na_count = sum(!is.na(TA8B)), na_count = sum(is.na(TA8B)) )
# Calculate average reading score DIRECTLY
attributes(df$STATEID)$labels
Jammu & Kashmir 01 Himachal Pradesh 02 Punjab 03 Chandigarh 04
1 2 3 4
Uttarakhand 05 Haryana 06 Delhi 07 Rajasthan 08
5 6 7 8
Uttar Pradesh 09 Bihar 10 Sikkim 11 Arunachal Pradesh 12
9 10 11 12
Nagaland 13 Manipur 14 Mizoram 15 Tripura 16
13 14 15 16
Meghalaya 17 Assam 18 West Bengal 19 Jharkhand 20
17 18 19 20
Orissa 21 Chhattisgarh 22 Madhya Pradesh 23 Gujarat 24
21 22 23 24
Daman & Diu 25 Dadra+Nagar Haveli 26 Maharashtra 27 Andhra Pradesh 28
25 26 27 28
Karnataka 29 Goa 30 Lakshadweep 31 Kerala 32
29 30 31 32
Tamil Nadu 33 Pondicherry 34 Anadman/Nicobar 35
33 34 35
df %>%
group_by(STATEID) %>%
summarise(weighted.mean(TA8B, na.rm = TRUE, w = WT))
# Calculate average reading score USING SURVEY PACKAGE
svyby(~TA8B, ~STATEID, df_svy, svymean, na.rm=TRUE)
# Calculate average reading score USING SRVYR PACKAGE
# note that i can't use a formula to specify the ID var
# also
df_srvyr <- df %>%
as_survey_design(c(psu_expanded, hh_expanded), weights = WT)
Temp - calculate ICC for ASER scores
Argh. This is why R is annoying! Not really sure if this works, but it seems like it should
attributes(VarCorr(fit)$PSUID)$stddev / aser_var
(Intercept)
0.06675789
LS0tDQp0aXRsZTogIk92ZXJ2aWV3IG9mIElIRFMgMjAxMiBFZHVjYXRpb24gRGF0YSINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQNCi0tLQ0KDQojIyBTdW1tYXJ5DQpUaGlzIG5vdGVib29rIHByb3ZpZGVzIGEgZGV0YWlsZWQgZGVzY3JpcHRpb24gb2YgdGhlIElIRFMgMjAxMS0xMiBob3VzZWhvbGQgZGF0YXNldCBhbmQgYWNjb21wYW55aW5nIGRvY3VtZW50YXRpb24uIEl0IGFsc28gcHJvdmlkZXMgc2FtcGxlIGNvZGUgdG8gaW1wb3J0IHRoZSBob3VzZWhvbGQgZGF0YXNldCBhbmQgdXNlIHRoZSBzdXJ2ZXkgYW5kIHNydnlyIHBhY2thZ2VzIHRvIHBlcmZvcm0gaW5mZXJlbmNlIHVzaW5nIHRoZSBkYXRhc2V0DQoNCiMjIE92ZXJ2aWV3IG9mIElIRFMgZGF0YQ0KSUhEUyBpcyBhIHBhbmVsIHN1cnZleSBsZWQgYnkgU29uYWxkZSBEZXNhaSBhbmQgb3RoZXJzIGF0IE5DQUVSL1VvZk1kLiAgVGhlIGZpcnN0IHJvdW5kIG9mIHRoZSBwYW5lbCB3YXMgY29uZHVjdGVkIGluIDIwMDQtMDUgYW5kIHRoZSBzZWNvbmQgd2F2ZSB3YXMgY29uZHVjdGVkIGluIDIwMTEtMTIuICBJbiBib3RoIHJvdW5kcyBvZiB0aGUgc3VydmV5IHRoZXkgYWRtaW5pc3RlcmVkIGEgdGVzdCBzaW1pbGFyIHRvIHRoZSBBU0VSIHRlc3QgdG8gYWxsIGNoaWxkcmVuIGFnZWQgOC0xMS4gKFRoZSByZXNwb25zZSByYXRlIGZvciB0aGUgQVNFUiBzdXJ2ZXkgd2FzIG5vdCBncmVhdCB0aG91Z2guICBJbiB0aGVpciBwdWJsaWNhdGlvbiBmb3IgdGhlIEluZGlhIFBvbGljeSBGb3J1bSwgU29uYWxkZSBleHBsYWlucyB0aGUgcmVhc29ucyBmb3IgdGhpcyBJIHRoaW5rLikgSW4gYWRkaXRpb24sIHRoZSBzdXJ2ZXkgYXNrZWQgYmFzaWMgcXVlc3Rpb25zIGFib3V0IGVucm9sbG1lbnQgYW5kIGVkdWNhdGlvbiBhY2hpZXZlbWVudCBmb3IgYWxsIGhvdXNlaG9sZCBtZW1iZXJzLg0KDQoNCiMjIERhdGFzZXRzIGFuZCBkb2N1bWVudGF0aW9uDQpXaGVuIHlvdSBkb3dubG9hZCB0aGUgcm91bmQgMiBkYXRhLCB5b3UgZ2V0IDE0IGRhdGFzZXRzLiBUaGVzZSBhcmUgc3BsaXQgaW50byBmb2xkZXJzICJEUzAwWCIgd2hlcmUgWCBjb3JycmVzcG9uZHMgdG8gdGhlIGZvbGxvd2luZzoNCg0KMS4gSW5kaXZpZHVhbA0KMi4gSG91c2Vob2xkDQozLiBFbGlnaWJsZSBXb21lbg0KNC4gQmlydGggSGlzdG9yeQ0KNS5NZWRpY2FsIFN0YWZmDQo2LiBNZWRpY2FsIEZhY2lsaXRpZXMNCjcuIE5vbiBSZXNpZGVudA0KOC4gU2Nob29sIFN0YWZmDQo5LiBTY2hvb2wgRmFjaWxpdGllcw0KMTAuIFdhZ2UgYW5kIFNhbGFyeQ0KMTEuIFRyYWNraW5nDQoxMi4gVmlsbGFnZQ0KMTMuIFZpbGxhZ2UgUGFuY2hheWF0DQoxNC4gVmlsbGFnZSBSZXNwb25kZW50DQoNCk5vdGUgdGhhdCwgdW5saWtlIHRoZSBwYW5lbCBkYXRhc2V0LCB0aGVyZSBpcyBvbmx5IG9uZSB2ZXJzaW9uIG9mIHRoZSBmaWxlcy4gKEZvciB0aGUgcGFuZWwgZGF0YXNldCwgdGhlcmUgYXJlIGRpZmZlcmVudCB2ZXJzaW9ucyBvZiB0aGUgZmlsZXMgY29ycmVzcG9uZGluZyB0byBkaWZmZXJlbnQgd2F5cyBvZiBtZXJnaW5nL2NvbWJpbmluZyB0aGUgdHdvIHJvdW5kcyBvZiBkYXRhLikgTW9yZSBpbmZvcm1hdGlvbiBhYm91dCBlYWNoIG9mIHRoZSBkYXRhc2V0cywgaW5jbHVkaW5nIHdoaWNoIHZhcmlhYmxlcyB0byB1c2UgZm9yIHdlaWdodGluZyBvYnNlcnZhdGlvbnMgd2hlbiB1c2luZyBlYWNoIGRhdGFzZXQgYW5kIGhvdyB0byBtZXJnZSB0aGUgZGF0YXNldHMsIGNhbiBiZSBmb3VuZCBbaGVyZV0oaHR0cHM6Ly93d3cuaWNwc3IudW1pY2guZWR1L2ljcHNyd2ViL2NvbnRlbnQvRFNEUi9pZGhzLUlJLWRhdGEtZ3VpZGUuaHRtbCkuIEFjY29yZGluZyB0byBkb2N1bWVudGF0aW9uLCBtZXJnZSBvbiBzdGF0ZWlkLCBkaXN0aWQsIHBzdWlkLCBoaCwgaGhzcGxpdGlkDQoNCkRvY3VtZW50YXRpb24gZm9yIHRoZSAyMDEyIGRhdGFzZXQgaXMgc2F2ZWQgaW4gdGhlICJJSERTL0lIRFMgMjAxMiIgZm9sZGVyIGluIG15IGRhdGEgZm9sZGVyLiBUaGUgdXNlciBndWlkZSBjb250YWlucyBiYXNpYyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc2FtcGxpbmcgc3RyYXRlZ3kgYW5kIHZhcmlvdXMgY29uc3RydWN0ZWQgdmFyaWFibGVzIChlLmcuIHRoZSBjb25zdW1wdGlvbiB2YXJpYWJsZXMpLiBUaGUgZGF0YSBndWlkZSBzZWVtcyB0byBqdXN0IGR1cGxpY2F0ZSB0aGlzIGluZm9ybWF0aW9uLiBUbyBmaWd1cmUgb3V0IHdoaWNoIHZhcmlhYmxlcyB0byB1c2UsIGdvIHRvIHRoZSBjb2RlYm9va3MgYW5kIHF1ZXN0aW9ubmFpcmVzIGxvY2F0ZWQgaW4gZWFjaCBvZiB0aGUgDQoNCiMjIyBGaW5kaW5nIHZhcmlhYmxlcyBpbiB0aGUgZGF0YXNldHMNClRoZSBmYXN0ZXN0IHdheSB0byBmaW5kIHJlbGV2YW50IHZhcmlhYmxlcyBpbiB0aGUgZGF0YXNldCBpcyB0byBmaXJzdCBzZWFyY2ggZm9yIGtleXdvcmRzIGluIHRoZSBxdWVzdGlvbm5haXJlIHRvIGZpbmQgdGhlIHJlbGV2YW50IHF1ZXN0aW9uIG51bWJlciBhbmQgdGhlbiBzZWFyY2ggZm9yIHRoZSBxdWVzdGlvbiBudW1iZXIgaW4gdGhlIGNvZGVib29rLiAgVGhpcyBjYW4gYmUgYSBiaXQgY29uZnVzaW5nIHNpbmNlIHRoZSB2YXJpYWJsZXMgaW4gdGhlIGNvZGVib29rIGFyZSBvcmdhbml6ZWQgYnkgc3ViamVjdCByYXRoZXIgdGhhbiBvcmRlcmVkIGJ5IHF1ZXN0aW9uIG51bWJlci4gKEZvciBleGFtcGxlLCBzb21lIG9mIHRoZSBlZHVjYXRpb24gcXVlc3Rpb25zIGZyb20gdGhlIGhvdXNlaG9sZCByb3N0ZXIgYXJlIGNvZGVkIGFzICJDUyIgcXVlc3Rpb25zIGFuZCBjb21lIGxhdGVyIGluIHRoZSByb3N0ZXIuKQ0KDQpOb3RlIHRoYXQgY29kZWJvb2sgc2VjdGlvbiAqKiJFRDU6IEhRMTkgMTEuNSBFZHVjYXRpb246IEVucm9sbGVkIG5vdyIqKiByZWZlcnMgdG8gdmFyaWFibGUgKipFRDUqKiBpbiB0aGUgZGF0YXNldCB3aGljaCBjb21lcyBmcm9tICoqcXVlc3Rpb24gMTEuNSoqIHdoaWNoIGlzIG9uZSAqKnBhZ2UgMTkqKiBvZiB0aGUgKipob3VzZWhvbGQgcXVlc3Rpb25uYWlyZSoqLg0KDQoNCiMjIEtleSBlZHVjYXRpb24gdmFyaWFibGVzIGluIHRoZSBpbmRpdmlkdWFsIGRhdGFzZXQgKERTMDAwMSkNCkkgaGF2ZSBpbmNsdWRlZCBhIGxpc3Qgb2Ygc29tZSBvZiB0aGUga2V5IGVkdWNhdGlvbi1yZWxhdGVkIHZhcmlhYmxlcyAoYW5kIG90aGVyIGJhc2ljIHZhcmlhYmxlcykgYmVsb3cuIE5vdGUgdGhhdCB0aGlzIGxpc3QgbWlnaHQgbm90IGJlIGNvbXByZWhlbnNpdmUgKGkuZS4gdGhlcmUgbWF5IGJlIHNvbWUgZWQgcmVsYXRlZCB2YXJzIHdoaWNoIEkgaGF2ZSBtaXNzZWQpLg0KDQoNCiMjIyBJZGVudGlmaWVycyBhbmQgb3RoZXIgdmFycw0KKiBTVEFURUlEDQoqIERJU1RJRA0KKiBQU1VJRA0KKiBISElEDQoqIEhIU1BMSVRJRA0KKiBQRVJTT05JRA0KKiBJRFBTVSAtIHRoaXMgb25lIG1pZ2h0IGJlIHVuaXF1ZSwgbm90IHN1cmUNCiogV1QgLSB3ZWlnaHRzDQoqIFJPMyAtIHNleA0KKiBSTzcgLSBwcmltYXJ5IGFjdGl2aXR5IHN0YXR1cw0KKiBSTzUgLSBBZ2UNCg0KDQojIyMgVGVzdGluZyB2YXJzICBmb3IgY2hpbGRyZW4gOC0xMSAocGFnZSAzOCBvZiBxdWVzdGlvbm5haXJlKQ0KKiBUQThBLCBUQThCLCBUQTlBLCBUQTlCLCBUQTEwQSwgVEExMEIgLS0gUmVhZGluZywgbWF0aCwgYW5kIHdyaXRpbmcgdGVzdCByZXN1bHRzICh2YXJzIHdpdGggc3VmZml4ICJCIiBjb250YWluIHRoZSByZXN1bHRzKQ0KKiBUQSogLSBvdGhlciB2YXJzIHJlbGF0ZWQgdG8gQVNFUiB0ZXN0DQoNCiMjIyBFZHVjYXRpb24gdmFycyBmb3IgYWxsIG1lbWJlcnMgKHBhZ2UgMjMgb2YgcXVlc3Rpb25uYWlyZSkNCiogRUQyLUVEMTIgLS0gZWQtcmVsYXRlZCBpbmZvIHN1Y2ggYXMgaGlnaGVzdCBncmFkZSwgY3VycmVudCBlbnJvbGxtZW50LCBldGMgZm9yIGFsbCBob3VzZWhvbGQgbWVtYmVycy4gDQoNCiMjIyBFZHVjYXRpb24gdmFycyBhbGwgaGggbWVtYmVycyB3aG8gd2VyZSBlbnJvbGxlZCBpbiBzY2hvb2wgaW4gcHJldmlvdXMgMTIgbW9udGhzIChwYWdlIDQ0IG9mIHF1ZXN0aW9ubmFpcmUpDQoqIENTMyAtIGluIHNjaG9vbA0KKiBDUzQgLSB0eXBlIG9mIHNjaG9vbA0KKiBDUzUgLSBkaXN0YW5jZSB0byBzY2hvb2wNCiogQ1M2IC0gc3RhbmRhcmQgeWVhcnMNCiogQ1M4IC0gbWVkaXVtIG9mIGluc3RydWN0aW9uDQoqIENTOSAtIHllYXIgRW5nbGlzaCB0YXVnaHQNCiogQ1MxMCAtIHNjaG9vbCBob3VycyBwZXIgd2Vlaw0KKiBDUzExIC0gaG9tZXdvcmsgaG91cnMgcGVyIHdlZWsNCiogQ1MxMiAtIHByaXZhdGUgdHVpdGlvbiBob3VycyBwZXIgd2Vlaw0KKiBDUzEzIC0gZGF5cyAvIG1vbnRocyBhYnNlbnQNCiogKGFuZCBtYW55IG1vcmUpDQoNCiMjIyBFZHVjYXRpb24gdmFycyBmb3IgY2hpbGRyZW4gOC0xMSAocGFnZSA0NiBvZiBxdWVzdGlvbm5haXJlKQ0KKiBDSCogDQoNCiMjIFNhbXBsZSBjb2RlIHRvIHJlYWQgaW4ga2V5IHZhcmlhYmxlcw0KU2V0dXAgY2h1bmsNCmBgYHtyIHNldHVwfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGhhdmVuKQ0KbGlicmFyeShzdXJ2ZXkpDQpsaWJyYXJ5KHNydnlyKQ0KYGBgDQoNCk9wZW4gdGhlIGluZGl2aWR1YWwgZGF0YXNldCAoMzYxNTEtMDAwMSkgYW5kIHNlbGVjdCBrZXkgZWR1Y2F0aW9uIHZhcmlhYmxlcw0KDQpgYGB7cn0NCmloZHNfaW5kX2RpciA8LSAiQzovVXNlcnMvZG91Z2ovRG9jdW1lbnRzL0RhdGEvSUhEUy9JSERTIDIwMTIvRFMwMDAxIg0KaW5kX2ZpbGUgPC0gZmlsZS5wYXRoKGloZHNfaW5kX2RpciwgIjM2MTUxLTAwMDEtRGF0YS5kdGEiKQ0KIyByZWFkIGluIGp1c3QgdGhvc2UgdmFyaWFibGVzIHRoYXQgaSBuZWVkDQojIHRoaXMgaXMgbXVjaCBmYXN0ZXIgdGhhbiByZWFkaW5nIGluIGV2ZXJ5dGhpbmcgYW5kIHRoZW4gc2VsZWN0aW5nDQpkZiA8LSByZWFkX2R0YShpbmRfZmlsZSwgY29sX3NlbGVjdCA9IGMoU1RBVEVJRCwgRElTVElELCBQU1VJRCwgSEhJRCwgSEhTUExJVElELCBQRVJTT05JRCwgSURQU1UsIFdULCBSTzMsIFJPNywgUk81LCBzdGFydHNfd2l0aCgiQ1MiKSwgc3RhcnRzX3dpdGgoIlRBIiksIHN0YXJ0c193aXRoKCJFRCIpKSkNCmBgYA0KDQojIyBTcGVjaWZ5IHRoZSBzdXJ2ZXkgZGVzaWduIHVzaW5nIHRoZSBzdXJ2ZXkgcGFja2FnZQ0KV2hpbGUgdGhlIHVzZXIgZ3VpZGUgaGFzIGEgc2hvcnQgZGVzY3JpcHRpb24gb2YgdGhlIHNhbXBsZSwgYSBjbGVhcmVyIGFuZCBtb3JlIGNvbXBsZXRlIGRlc2NyaXB0aW9uIGNhbiBiZSBmb3VuZCBbaGVyZV0oaHR0cHM6Ly9paGRzLnVtZC5lZHUvc2l0ZXMvZGVmYXVsdC9maWxlcy9wdWJsaWNhdGlvbnMvcGFwZXJzL3RlY2huaWNhbCUyMHBhcGVyJTIwMS5wZGYpLiBUaGUgZGF0YXNldCBpbmNsdWRlcyBubyB2YXJpYWJsZXMgZm9yIHN0cmF0YSBvciBmcGMgc28gd2Ugb25seSBzcGVjaWZ5IGEgdHdvLXN0YWdlIHN1cnZleSB3aXRoIHRoZSBhcHByb3ByaWF0ZSB3ZWlnaHRzDQoNCmBgYHtyfQ0KZGYgPC0gZGYgJT4lIG11dGF0ZShwc3VfZXhwYW5kZWQgPSBwYXN0ZShTVEFURUlELCBESVNUSUQsIFBTVUlELCBzZXAgPSItIiksIGhoX2V4cGFuZGVkID0gcGFzdGUoU1RBVEVJRCwgRElTVElELCBQU1VJRCwgSEhJRCwgSEhTUExJVElELCBzZXAgPSItIikpDQojIHRoZXJlIGlzIG9uZSByb3cgd2l0aCBhIG1pc3NpbmcgdmFsdWUgZm9yIFdUIGFuZCBtb3N0IG90aGVyIHZhcmlhYmxlcyBkcm9wIHRoYXQNCmRmIDwtIGRmICU+JSBmaWx0ZXIoIWlzLm5hKFdUKSkNCmRmX3N2eSA8LSBzdnlkZXNpZ24oaWQgPX4gcHN1X2V4cGFuZGVkICsgaGhfZXhwYW5kZWQsIHdlaWdodHMgPX4gV1QsIGRhdGEgPSBkZikNCmBgYA0KDQpDYWxjdWxhdGUgYXZlcmFnZSBBU0VSIHJlYWRpbmcgc2NvcmVzIGJ5IHN0YXRlIHdpdGhvdXQgdXNpbmcgdGhlIHN1cnZleSBwYWNrYWdlIChidXQgdXNpbmcgd2VpZ2h0cyksIHVzaW5nIHRoZSBzdXJ2ZXkgcGFja2FnZSwgYW5kIHRoZW4gdXNpbmcgdGhlIHNydnlyIHBhY2thZ2UuIEFsbCB5aWVsZCB0aGUgc2FtZSBhbnN3ZXJzLiBOb3RlIHRoYXQgdGhlIHN1cnZleSBwYWNrYWdlIGFuZCBzcnZ5ciBhcmUgYm90aCByZWFsbHkgc2xvdy4gDQoNCmBgYHtyfQ0KIyBjb25maXJtIHdlIGFyZSBsb29raW5nIGF0IHRoZSByaWdodCB2YXJpYWJsZSBieSBsb29raW5nIGF0IHRoZSB2YXJpYWJsZSBsYWJlbCBmcm9tIFN0YXRhDQphdHRyaWJ1dGVzKGRmJFRBOEIpDQphdHRyaWJ1dGVzKGRmJFJPNSkkbGFiZWwNCg0KIyBsb29rIGF0IHJlc3BvbnNlIHJhdGVzIHRvIFRBOEIgYnkgYWdlIC0tPiBsb29rcyBsaWtlIHRoZXJlIGFyZSBzb21lIE5BcyBldmVuIGZvciA4IHRvIDExLiANCiMgdW5jbGVhciB3aHkgdGhhdCBpcy4gIA0KZGYgJT4lDQogIGdyb3VwX2J5KFJPNSkgJT4lDQogIHN1bW1hcmlzZShub25fbmFfY291bnQgPSBzdW0oIWlzLm5hKFRBOEIpKSwgbmFfY291bnQgPSBzdW0oaXMubmEoVEE4QikpICkNCg0KIyBDYWxjdWxhdGUgYXZlcmFnZSByZWFkaW5nIHNjb3JlIERJUkVDVExZDQphdHRyaWJ1dGVzKGRmJFNUQVRFSUQpJGxhYmVscw0KZGYgJT4lDQogIGdyb3VwX2J5KFNUQVRFSUQpICU+JQ0KICBzdW1tYXJpc2Uod2VpZ2h0ZWQubWVhbihUQThCLCBuYS5ybSA9IFRSVUUsIHcgPSBXVCkpDQoNCiMgQ2FsY3VsYXRlIGF2ZXJhZ2UgcmVhZGluZyBzY29yZSBVU0lORyBTVVJWRVkgUEFDS0FHRQ0Kc3Z5YnkoflRBOEIsIH5TVEFURUlELCBkZl9zdnksIHN2eW1lYW4sIG5hLnJtPVRSVUUpDQoNCiMgQ2FsY3VsYXRlIGF2ZXJhZ2UgcmVhZGluZyBzY29yZSBVU0lORyBTUlZZUiBQQUNLQUdFIA0KIyBub3RlIHRoYXQgaSBjYW4ndCB1c2UgYSBmb3JtdWxhIHRvIHNwZWNpZnkgdGhlIElEIHZhcg0KIyBhbHNvIA0KZGZfc3J2eXIgPC0gZGYgJT4lDQogIGFzX3N1cnZleV9kZXNpZ24oYyhwc3VfZXhwYW5kZWQsIGhoX2V4cGFuZGVkKSwgd2VpZ2h0cyA9IFdUKQ0KDQpkZl9zcnZ5ciAlPiUNCiAgZ3JvdXBfYnkoU1RBVEVJRCkgJT4lDQogIHN1bW1hcml6ZShhc2VyX21lYW4gPSBzdXJ2ZXlfbWVhbihUQThCLCBuYS5ybSA9VFJVRSkpDQoNCmBgYA0KDQoNCiMjIFRlbXAgLSBjYWxjdWxhdGUgSUNDIGZvciBBU0VSIHNjb3Jlcw0KQXJnaC4gIFRoaXMgaXMgd2h5IFIgaXMgYW5ub3lpbmchIE5vdCByZWFsbHkgc3VyZSBpZiB0aGlzIHdvcmtzLCBidXQgaXQgc2VlbXMgbGlrZSBpdCBzaG91bGQNCmBgYHtyfQ0KIyBjYWxjdWxhdGUgdmFyaWFuY2Ugb2YgVEE4Qg0KYXNlcl92YXIgPC0gdmFyKGRmJFRBOEIsIG5hLnJtID0gVFJVRSkNCg0KIyBmaXQgYSByYW5kb20gZWZmZWN0cyBtb2RlbCBmb3IgUFNVSUQgYW5kIGdldCB0aGUgdmFyaWFuY2Ugb2YgdGhhdCBjb21wb25lbnQNCmxpYnJhcnkobG1lNCkNCnRlbXAgPC1kZiAlPiUgc2VsZWN0KFRBOEIsUFNVSUQpDQpmaXQgPC0gbG1lcihUQThCIH4oMXxQU1VJRCksIGRhdGEgPSB0ZW1wKQ0KcHJpbnQoIklDQyBpcyIpDQphdHRyaWJ1dGVzKFZhckNvcnIoZml0KSRQU1VJRCkkc3RkZGV2IC8gYXNlcl92YXINCmBgYA0KDQo=