Introduction
This section will cover basic aspects of data manipulation, such as
recoding a variable, selecting data, and calculating a new variable. At
the end, there is a note about the statistical calculations considering
the design effect.
About the AmericasBarometer datasets
The data that we are going to use should be cited as follows: Source:
AmericasBarometer by the Latin American Public Opinion Project (LAPOP),
wwww.LapopSurveys.org.
In this section a dataset is loaded. This dataset is hosted in the
“materials_edu” repository of LAPOP’s GitHub account. Through the
library rio
and the command import
, this
database can be imported from this repository, using the following code.
The dataset is imported into the object “lapop21”. This dataset has an
extension .RData and when it is imported, variables are defined as type
double (“dbl”), which is a type of variable that allows decimals,
different from type integer, “int”, that only accept integers.
library(rio)
lapop21 = import("https://raw.github.com/lapop-central/materials_edu/main/lapop21.RData")
The dataset for the previous round of the AmericasBarometer is also
in this repository. We can load and call it “lapop18”. It is necessary
to clarify that this dataset, imported from a SPSS file, loads variables
as type numeric (“num”).
lapop18 = import("https://raw.github.com/lapop-central/materials_edu/main/LAPOP_AB_Merge_2018_v1.0.sav")
Recoding a variable
In this section we will use the report “The Pulse of Democracy” that
presents the results for the 2021 round of the AmericasBarometer,
available here.
This report presents the results on support for democracy in the
Americas. These results are based on the variable called ING4 in the
dataset. This variable is worded as follows:
ING4. Changing the subject again, democracy may have problems,
but it is better than any other form of government. To what extent do
you agree or disagree with this statement?
This variable is measured in a 1-7 scale, where 1 means “strongly
disagree” and 7 means “strongly agree”. Then, values from 5 to 7 are
recoded as support for democracy. To see the distribution of responses
to this variable, you can use the table
command.
table(lapop21$ing4)
##
## 1 2 3 4 5 6 7
## 5704 2567 4980 8177 13886 8390 16759
In this way, the observations (absolute frequencies) are calculated
for each value of the variable. To calculate the percentage of people
who support democracy, we have to recode this variable and create a new
one. It means that the original ING4, in a 1-7 scale, has to be recoded
in a new variable following this rule:
- Values between 1-4 of ING4 become 0 in a new variable ing4r
- Values between 5-7 of ING4 become 1 in a new variable ing4r
An example of how this recoded data is presented in the report can be
seen in Graph 1.1. This shows the percentage of citizens who support
democracy by country. That is, the percentage of respondents who
answered between 5 and 7 to the ING4 question in each country is shown.
According to the recoding, this graph would represent the percentage of
respondents who register a 1 in the recoded variable.
In the report The Pulse of Democracy for the 2018/19 round, available
here,
it is presented a similar figure, using the same variable and the same
rule for recoding.
To recode a variable in R there are several ways. One of the most
efficient ways to do this is by using the command recode
from the car
package. The dplyr
package has
also a recode
command that can confuse R. To avoid
confusion we will specify in the syntax car::recode
recoding. The recoded variable is recorded as “lapop21$ing4rec”. Then,
the command table
is used to describe this new
variable.
library(car)
lapop21$ing4rec <- car::recode(lapop21$ing4, "1:4=0; 5:7=1")
table(lapop21$ing4rec)
##
## 0 1
## 21428 39035
If the observations between 1 and 4 of the original variable are
added (1699 + 1470 + 3003 + 6089), we see that it is the result equals
the observations in value 0 of the new variable (12261), as it was
written in the recoding. It should also be noted that the dataset in the
Environment now has one more variable, totaling 1826 variables.
Selection of observations
The Figure 1.1 shows that support for democracy goes from a high of
80% in Uruguay to a low of 46% in Haiti. To replicate result
corresponding to Uruguay, we can select observations from this country.
According to codification of variable “pais”, Uruguay is coded as
14.
Selection of observations in R can be done in several ways. One way
is to use brackets. Other way is to use the command subset
.
With this command, we select observations from this country and we save
this selection in a new dataframe “lapop1”. We have 3009 observations in
Uruguay and 1826 variables.
lapop1 = subset(lapop21, pais==14)
table(lapop1$pais)
##
## 14
## 3009
With this selection of data, you can calculate the percentages
(relative frequencies) using the command prop.table
. This
command gives us the relative frequencies (in values between 0 and 1) of
a frecuency table calculated with table
. These relative
frequencies are multiplied by 100 to reproduce the percentage in each
country. In this case, the brackets […]
are used to make
the selection of cases from each country.
prop.table(table(lapop1$ing4rec[lapop1$pais==14]))*100
##
## 0 1
## 15.47499 84.52501
These results are percentages (between 0 and 100), but include many
decimal places. To round to one decimal, as shown in Graph 1.2, you can
use the command round
, where all the previous syntax is
nested. In this command, you have to specify the number of decimal
places you want, which in this case is 1.
round(prop.table(table(lapop1$ing4rec[lapop1$pais==14]))*100, 1)
##
## 0 1
## 15.5 84.5
According to this result, 84.5% of Uruguayans support democracy. This
result is different from what it is reported in Figure 1.1, where
reported value is 80%. This difference is due to the fact that our
procedures do not include the effect of complex design features, such as
weights, stratification, and cluster sampling. Below, we present
procedures to reproduce precise reported results.
The report for the 2018/19 wave indicates “Figure 1.2 displays the
percent of individuals in each country that expresses support for
democracy in 2018/19. Support for democracy ranges from a low of 45% in
Honduras to a high of 76.2% in Uruguay.” (p. 11).
For replicating these results about Honduras and Uruguay for the
2018/19 round, we can select observations for these two countries.
According to the questionnaire, available HERE, Honduras is coded as 4
and Uruguay as 14 in variable “pais”, that is imported as a numeric
variable.
We include the operator “or”, that is written as “|” in R. In this
way, we can select observations from Honduras or Uruguay using
pais==4 | pais==14
. The description of variable “pais”
shows that it includes only observations for Honduras (2) and Uruguay
(14).
lapop2 = subset(lapop18, pais==4 | pais==14)
table(lapop2$pais)
##
## 4 14
## 1560 1581
The new dataframe “lapop2” has 3141 observations and 84 variables. It
does not include a recoded variable for support for democracy. We
proceed to include it.
lapop2$ing4rec <- car::recode(lapop2$ing4, "1:4=0; 5:7=1")
With this variable, we can follow the same procedures as before:
produce a relative frequency table.
prop.table(table(lapop2$ing4rec[lapop2$pais==4]))*100
##
## 0 1
## 54.98995 45.01005
prop.table(table(lapop2$ing4rec[lapop2$pais==14]))*100
##
## 0 1
## 23.80641 76.19359
And then, we include rounding.
round(prop.table(table(lapop2$ing4rec[lapop2$pais==4]))*100, 1)
##
## 0 1
## 55 45
round(prop.table(table(lapop2$ing4rec[lapop2$pais==14]))*100, 1)
##
## 0 1
## 23.8 76.2
With this code, we have reproduced results for countries in the
extremes of Figure 1.2. In this case, results are similar to the ones
reported in the figure in the report.
Both reports also indicate that the United States and Canada are
excluded from the calculations. The dataset loaded as “lapop18” includes
all the countries in the round. To exclude these two countries, we have
to select the countries that are NOT USA and Canada. This new selection
can be saved in a new dataframe or it can be overwritten in the original
dataframe, as it is done in this case because the exclusion of these
countries is for all the calculations that follow. According to the
questionnaire, USA has the code 40 and Canada, the code 41 in the
variable “pais”. To exclude them, countries with a code of less than 40
(or 35 or less) must be included. For this we can again use the
subset
command.
lapop18 <- subset(lapop18, pais<=35)
It can be observed in the Environment that the observations of the
“lapop18” dataframe are reduced after running this code, since the
observations of repondents in these two countries have been eliminated.
The number of observations goes from 31,050 to 28,042, a number that
coincides with that of the dataset in .RData format that we used in the
previous module and that we indicated that it did not include these
countries.
In the same way, we can proceed in the 2021 wave dataset. After this,
observations decrease to 60,661.
lapop21 = subset(lapop21, pais<=35)
Calculating a variable
A frequent LAPOP practice with the AmericasBarometer data is the
rescaling of variables. The report’s chapter on democratic legitimacy
provides examples of this rescaling with variables related to support
for the system. To calculate this index for system support, we work with
a set of five variables:
B1. To what extent do you think the courts of (country) guarantee a
fair trial? . To what extent do you respect the political institutions
of (country)?
B2. To what extend do you respect the political institutions of
(country)?
B3. To what extent do you think the basic rights of the citizen are
well protected by the political system of (country)?
B4. To what extent are you proud to live under the political system
of (country)?
B6. To what extent do you think the political system of (country)
should be supported?
As the report indicates “For each question, the original scale from 1
(” Not at all “) to 7 (”A lot”) is recoded on a 0-100 scale, in such a
way that 0 indicates the lowest level of support for the political
system and 100 is the highest level of support for the political system.
This new scale follows the typical LAPOP recoding and can be interpreted
as a measure of support in units, or degrees, on a continuous scale
ranging from 0 to 100” (p. 34). To check the original scale of these
variables, we can describe these variables using the table
command.
table(lapop18$b1)
##
## 1 2 3 4 5 6 7
## 4089 4067 5881 6137 4215 1631 1371
table(lapop18$b2)
##
## 1 2 3 4 5 6 7
## 2861 2152 2998 4153 5182 4448 5679
table(lapop18$b3)
##
## 1 2 3 4 5 6 7
## 5080 4096 5153 5349 4219 2061 1491
table(lapop18$b4)
##
## 1 2 3 4 5 6 7
## 5095 3206 3743 4557 4326 3041 3584
table(lapop18$b6)
##
## 1 2 3 4 5 6 7
## 3713 2325 2971 4277 4616 3868 5572
It is observed that all the variables run on a scale from 1 to 7. To
rescale a variable from an original scale from 1 to 7 to another from 0
to 100, the first thing to do is subtract 1 unit, so the variable would
have a scale of 0 to 6, then divide it by 6, with which would vary
between 0 and 1 and, finally, multiply it by 100. this is:
Rescaled variable = ((original variable -1)/6)*100
lapop18$b1rec <- ((lapop18$b1-1)/6)*100
lapop18$b2rec <- ((lapop18$b2-1)/6)*100
lapop18$b3rec <- ((lapop18$b3-1)/6)*100
lapop18$b4rec <- ((lapop18$b4-1)/6)*100
lapop18$b6rec <- ((lapop18$b6-1)/6)*100
table(lapop18$b1rec)
##
## 0 16.6666666666667 33.3333333333333 50
## 4089 4067 5881 6137
## 66.6666666666667 83.3333333333333 100
## 4215 1631 1371
With this transformation, it is observed that the 4,089 interviewees
who scored 1 in question B1 now have a score of 0. The 4,067 who scored
2 now have a score of 16.67, that is 2-1=1/6=0.1667*100=16.67. This same
operation could be done with the car :: recode
command,
following this recoding rule:
- Value of 1 in original variable is recoded as 0 in new variable
- Value of 2 in original variable is recoded as 16.67 in new
variable
- Value of 3 in original variable is recoded as 33.33 in new
variable
- Value of 4 in original variable is recoded as 50 in new
variable
- Value of 5 in original variable is recoded as 66.67 in new
variable
- Value of 6 in original variable is recoded as 83.33 in new
variable
- Value of 7 in original variable is recoded as 100 in new
variable
This way of recoding, however, is not very efficient. It is simpler
to use the formula to calculate the recoding. To calculate the system
support index, the report indicates that “The system support index is
the average of five questions: B1, B2, B3, B4 and B6” (p.46). In other
words, with the rescaled variables, the average of these five variables
has to be calculated for each individual (that is, in each row of the
dataset). This could be done by calculating the average manually.
System support = (b1rec + b2rec + b3rec + b4rec + b6rec)/5
In R we have the command rowMeans
that is used to
calculate averages of certain columns for each row. The syntax
[, 86:90]
indicates that the average calculation will be
performed by rows for all rows and using columns 86 to 90 of the
“lapop18” dataframe (the calculation could be done for some particular
rows by defining [ row_n: row_m, 86:90]
). This average is
saved in a new variable “support”, which is described.
lapop18$apoyo = rowMeans(lapop18[,85:89])
table(lapop18$apoyo)
##
## 0 3.33333333333333 6.66666666666667 10
## 634 368 439 525
## 13.3333333333333 16.6666666666667 20 23.3333333333333
## 527 550 834 745
## 26.6666666666667 30 33.3333333333333 36.6666666666667
## 810 911 1063 1086
## 40 43.3333333333333 46.6666666666667 50
## 1287 1317 1254 1487
## 53.3333333333333 56.6666666666667 60 63.3333333333333
## 1397 1408 1449 1243
## 66.6666666666667 70 73.3333333333333 76.6666666666667
## 1227 1113 988 827
## 80 83.3333333333333 86.6666666666667 90
## 820 572 445 369
## 93.3333333333333 96.6666666666667 100
## 245 131 210
With this index, it is possible to calculate the average support for
the system for the last round of the AmericasBarometer, as well as the
averages for each of the variables that are included in the index. The
mean
command is used for the average and the
na.rm = T
specification is used to tell the command not to
take into account the missing values of these variables. These
statistics will be seen in more detail in other documents.
mean(lapop18$apoyo, na.rm=T) #system support
## [1] 48.79419
mean(lapop18$b1rec, na.rm=T) #courts guarantee fair trial
## [1] 41.06032
mean(lapop18$b2rec, na.rm=T) #Respect for institutions
## [1] 59.23937
mean(lapop18$b3rec, na.rm=T) #Basic rights are protected
## [1] 40.42406
mean(lapop18$b4rec, na.rm=T) #Pride in the political system
## [1] 47.41096
mean(lapop18$b6rec, na.rm=T) #The political system should be supported
## [1] 56.28337
These results are those shown in Figure 2.1 for the 2018/19
round.
Condicionally calculating a variable
Sometimes the calculation of a variable does not only require the
numerical transformation of the original variable, but the values of the
new variable depend on the values of other variables. For example, the
chapter “Social networks and political attitudes” of the report “The
Pulse of Democracy” presents the results for the variables “WhatsApp
user”, “Twitter user” and “Facebook user”. To calculate these variables,
footnote 7 of this chapter indicates: “For each platform, we identify
users with a combination of two sets of survey questions. First, we
identify users as those who respond positively to the questions,
SMEDIA1/SMEDIA4/SMEDIA7. Do you have a Facebook/Twitter/WhatsApp
account? Then, we recode as non-users those who respond”never” to the
follow-up questions, SMEDIA2/SMEDIA5/SMEDIA8. How often do you see
content on Facebook/Twitter/WhatsApp?” (p. 64).
That is, the user is not only the one who has an account (SMEDIA1 =
1), but the one who uses it with a certain frequency (SMEDIA2 = 1, 2, 3,
4). In this way, the non-user can have an account, but never use it.
Therefore, the variable “user” depends on the values of 2 variables. The
rule for coding is:
Facebook user = 1 (he/she is a user) if SMEDIA1 = 1 (he/she has
an account) and SMEDIA2 <= 4 (he/she uses it with some
frequency)
Facebook user = 0 (he/she is not a user) if SMEDIA2 = 2 (he/she
doesn´t have an account) or SMEDIA2 = 5 ( he/she has an account but
never uses it)
This rule transforms into the following R syntax, which uses the
command ìfelse
. This syntax includes the condition to
assign values of 1 to a new variable and assigns all other observations
the value of 0. These new variables are described using the
table
command to generate the absolute frequencies,the
prop.table
command for the relative frequencies and the
round
command to round the decimals. These commands will be
seen in more detail in the following documents.
lapop18$fb_user <- ifelse(lapop18$smedia1==1 & lapop18$smedia2<=4, 1, 0)
lapop18$tw_user <- ifelse(lapop18$smedia4==1 & lapop18$smedia5<=4, 1, 0)
lapop18$wa_user <- ifelse(lapop18$smedia7==1 & lapop18$smedia8<=4, 1, 0)
round(prop.table(table(lapop18$fb_user))*100, 1)
##
## 0 1
## 43.8 56.2
round(prop.table(table(lapop18$tw_user))*100, 1)
##
## 0 1
## 92.1 7.9
round(prop.table(table(lapop18$wa_user))*100, 1)
##
## 0 1
## 35.8 64.2
These results are those presented in Graph 3.1 of the report in the
form of pie charts. These types of graphs will be seen in the next
section.
Design effect observation
Both the results for system support and those of social network users
differ from those that appear in the report for two reasons. First,
about support the system, because “Cross-time values are calculated
including only those countries the AmericasBarometer has surveyed
consistently since 2006: Argentina, Brazil, Bolivia, Chile, Colombia,
Costa Rica , the Dominican Republic, Ecuador, El Salvador, Guatemala,
Honduras, Jamaica, Mexico, Nicaragua, Panama, Paraguay, Peru, Uruguay”
(p.46). The code only filters the last round, which includes countries
that are not on that list, such as the United States or Canada. On the
other hand, the calculations reported in the publication include the use
of survey weights, which have not been included in these calculations,
but which will be incorporated in other documents (see here).
Summary
In this document we have seen the basic elements of data manipulation
and transformation using the AmericasBarometer datasets. A variable has
been recoded using the recode
command, cases have been
selected using subset
and a new variable has been
calculated algebraically and with the ifelse
command.
LS0tCnRpdGxlOiAiRGF0YSBtYW5pcHVsYXRpb24gdXNpbmcgdGhlIEFtZXJpY2FzQmFyb21ldGVyIGRhdGEiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGNvbGxhcHNlZDogZmFsc2UKICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UKICAgIHRvY19kZXB0aDogMQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgdGhlbWU6IGZsYXRseQogICAgI2NvZGVfZm9sZGluZzogaGlkZQplZGl0b3Jfb3B0aW9uczogCiAgbWFya2Rvd246IAogICAgd3JhcDogc2VudGVuY2UKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRSwgY2FjaGU9VFJVRSkKYGBgCgpgYGB7Y3NzIGNvbG9yLCBlY2hvPUZBTFNFfQouY29sdW1ucyB7ZGlzcGxheTogZmxleDt9CmgxIHtjb2xvcjogIzMzNjZDQzt9CmBgYAoKIyBJbnRyb2R1Y3Rpb24KClRoaXMgc2VjdGlvbiB3aWxsIGNvdmVyIGJhc2ljIGFzcGVjdHMgb2YgZGF0YSBtYW5pcHVsYXRpb24sIHN1Y2ggYXMgcmVjb2RpbmcgYSB2YXJpYWJsZSwgc2VsZWN0aW5nIGRhdGEsIGFuZCBjYWxjdWxhdGluZyBhIG5ldyB2YXJpYWJsZS4KQXQgdGhlIGVuZCwgdGhlcmUgaXMgYSBub3RlIGFib3V0IHRoZSBzdGF0aXN0aWNhbCBjYWxjdWxhdGlvbnMgY29uc2lkZXJpbmcgdGhlIGRlc2lnbiBlZmZlY3QuCgojIEFib3V0IHRoZSBBbWVyaWNhc0Jhcm9tZXRlciBkYXRhc2V0cwoKVGhlIGRhdGEgdGhhdCB3ZSBhcmUgZ29pbmcgdG8gdXNlIHNob3VsZCBiZSBjaXRlZCBhcyBmb2xsb3dzOiBTb3VyY2U6IEFtZXJpY2FzQmFyb21ldGVyIGJ5IHRoZSBMYXRpbiBBbWVyaWNhbiBQdWJsaWMgT3BpbmlvbiBQcm9qZWN0IChMQVBPUCksIHd3d3cuTGFwb3BTdXJ2ZXlzLm9yZy4KCkluIHRoaXMgc2VjdGlvbiBhIGRhdGFzZXQgaXMgbG9hZGVkLgpUaGlzIGRhdGFzZXQgaXMgaG9zdGVkIGluIHRoZSAibWF0ZXJpYWxzX2VkdSIgcmVwb3NpdG9yeSBvZiBMQVBPUCdzIEdpdEh1YiBhY2NvdW50LgpUaHJvdWdoIHRoZSBsaWJyYXJ5IGByaW9gIGFuZCB0aGUgY29tbWFuZCBgaW1wb3J0YCwgdGhpcyBkYXRhYmFzZSBjYW4gYmUgaW1wb3J0ZWQgZnJvbSB0aGlzIHJlcG9zaXRvcnksIHVzaW5nIHRoZSBmb2xsb3dpbmcgY29kZS4KVGhlIGRhdGFzZXQgaXMgaW1wb3J0ZWQgaW50byB0aGUgb2JqZWN0ICJsYXBvcDIxIi4KVGhpcyBkYXRhc2V0IGhhcyBhbiBleHRlbnNpb24gLlJEYXRhIGFuZCB3aGVuIGl0IGlzIGltcG9ydGVkLCB2YXJpYWJsZXMgYXJlIGRlZmluZWQgYXMgdHlwZSBkb3VibGUgKCJkYmwiKSwgd2hpY2ggaXMgYSB0eXBlIG9mIHZhcmlhYmxlIHRoYXQgYWxsb3dzIGRlY2ltYWxzLCBkaWZmZXJlbnQgZnJvbSB0eXBlIGludGVnZXIsICJpbnQiLCB0aGF0IG9ubHkgYWNjZXB0IGludGVnZXJzLgoKYGBge3IgYmFzZX0KbGlicmFyeShyaW8pCmxhcG9wMjEgPSBpbXBvcnQoImh0dHBzOi8vcmF3LmdpdGh1Yi5jb20vbGFwb3AtY2VudHJhbC9tYXRlcmlhbHNfZWR1L21haW4vbGFwb3AyMS5SRGF0YSIpCmBgYAoKVGhlIGRhdGFzZXQgZm9yIHRoZSBwcmV2aW91cyByb3VuZCBvZiB0aGUgQW1lcmljYXNCYXJvbWV0ZXIgaXMgYWxzbyBpbiB0aGlzIHJlcG9zaXRvcnkuCldlIGNhbiBsb2FkIGFuZCBjYWxsIGl0ICJsYXBvcDE4Ii4KSXQgaXMgbmVjZXNzYXJ5IHRvIGNsYXJpZnkgdGhhdCB0aGlzIGRhdGFzZXQsIGltcG9ydGVkIGZyb20gYSBTUFNTIGZpbGUsIGxvYWRzIHZhcmlhYmxlcyBhcyB0eXBlIG51bWVyaWMgKCJudW0iKS4KCmBgYHtyIGJhc2UxOH0KbGFwb3AxOCA9IGltcG9ydCgiaHR0cHM6Ly9yYXcuZ2l0aHViLmNvbS9sYXBvcC1jZW50cmFsL21hdGVyaWFsc19lZHUvbWFpbi9MQVBPUF9BQl9NZXJnZV8yMDE4X3YxLjAuc2F2IikKYGBgCgojIFJlY29kaW5nIGEgdmFyaWFibGUKCkluIHRoaXMgc2VjdGlvbiB3ZSB3aWxsIHVzZSB0aGUgcmVwb3J0ICJUaGUgUHVsc2Ugb2YgRGVtb2NyYWN5IiB0aGF0IHByZXNlbnRzIHRoZSByZXN1bHRzIGZvciB0aGUgMjAyMSByb3VuZCBvZiB0aGUgQW1lcmljYXNCYXJvbWV0ZXIsIGF2YWlsYWJsZSBbaGVyZV0oaHR0cHM6Ly93d3cudmFuZGVyYmlsdC5lZHUvbGFwb3AvYWIyMDIxLzIwMjFfTEFQT1BfQW1lcmljYXNCYXJvbWV0ZXJfMjAyMV9QdWxzZV9vZl9EZW1vY3JhY3kucGRmKS4KVGhpcyByZXBvcnQgcHJlc2VudHMgdGhlIHJlc3VsdHMgb24gc3VwcG9ydCBmb3IgZGVtb2NyYWN5IGluIHRoZSBBbWVyaWNhcy4KVGhlc2UgcmVzdWx0cyBhcmUgYmFzZWQgb24gdGhlIHZhcmlhYmxlIGNhbGxlZCBJTkc0IGluIHRoZSBkYXRhc2V0LgpUaGlzIHZhcmlhYmxlIGlzIHdvcmRlZCBhcyBmb2xsb3dzOgoKSU5HNC4KKkNoYW5naW5nIHRoZSBzdWJqZWN0IGFnYWluLCBkZW1vY3JhY3kgbWF5IGhhdmUgcHJvYmxlbXMsIGJ1dCBpdCBpcyBiZXR0ZXIgdGhhbiBhbnkgb3RoZXIgZm9ybSBvZiBnb3Zlcm5tZW50LiBUbyB3aGF0IGV4dGVudCBkbyB5b3UgYWdyZWUgb3IgZGlzYWdyZWUgd2l0aCB0aGlzIHN0YXRlbWVudD8qCgpUaGlzIHZhcmlhYmxlIGlzIG1lYXN1cmVkIGluIGEgMS03IHNjYWxlLCB3aGVyZSAxIG1lYW5zICJzdHJvbmdseSBkaXNhZ3JlZSIgYW5kIDcgbWVhbnMgInN0cm9uZ2x5IGFncmVlIi4KVGhlbiwgdmFsdWVzIGZyb20gNSB0byA3IGFyZSByZWNvZGVkIGFzIHN1cHBvcnQgZm9yIGRlbW9jcmFjeS4KVG8gc2VlIHRoZSBkaXN0cmlidXRpb24gb2YgcmVzcG9uc2VzIHRvIHRoaXMgdmFyaWFibGUsIHlvdSBjYW4gdXNlIHRoZSBgdGFibGVgIGNvbW1hbmQuCgpgYGB7ciBkZXNjcmliaW5nIGluZzR9CnRhYmxlKGxhcG9wMjEkaW5nNCkKYGBgCgpJbiB0aGlzIHdheSwgdGhlIG9ic2VydmF0aW9ucyAoYWJzb2x1dGUgZnJlcXVlbmNpZXMpIGFyZSBjYWxjdWxhdGVkIGZvciBlYWNoIHZhbHVlIG9mIHRoZSB2YXJpYWJsZS4KVG8gY2FsY3VsYXRlIHRoZSBwZXJjZW50YWdlIG9mIHBlb3BsZSB3aG8gc3VwcG9ydCBkZW1vY3JhY3ksIHdlIGhhdmUgdG8gcmVjb2RlIHRoaXMgdmFyaWFibGUgYW5kIGNyZWF0ZSBhIG5ldyBvbmUuCkl0IG1lYW5zIHRoYXQgdGhlIG9yaWdpbmFsIElORzQsIGluIGEgMS03IHNjYWxlLCBoYXMgdG8gYmUgcmVjb2RlZCBpbiBhIG5ldyB2YXJpYWJsZSBmb2xsb3dpbmcgdGhpcyBydWxlOgoKMS4gIFZhbHVlcyBiZXR3ZWVuIDEtNCBvZiBJTkc0IGJlY29tZSAwIGluIGEgbmV3IHZhcmlhYmxlIGluZzRyCjIuICBWYWx1ZXMgYmV0d2VlbiA1LTcgb2YgSU5HNCBiZWNvbWUgMSBpbiBhIG5ldyB2YXJpYWJsZSBpbmc0cgoKQW4gZXhhbXBsZSBvZiBob3cgdGhpcyByZWNvZGVkIGRhdGEgaXMgcHJlc2VudGVkIGluIHRoZSByZXBvcnQgY2FuIGJlIHNlZW4gaW4gR3JhcGggMS4xLgpUaGlzIHNob3dzIHRoZSBwZXJjZW50YWdlIG9mIGNpdGl6ZW5zIHdobyBzdXBwb3J0IGRlbW9jcmFjeSBieSBjb3VudHJ5LgpUaGF0IGlzLCB0aGUgcGVyY2VudGFnZSBvZiByZXNwb25kZW50cyB3aG8gYW5zd2VyZWQgYmV0d2VlbiA1IGFuZCA3IHRvIHRoZSBJTkc0IHF1ZXN0aW9uIGluIGVhY2ggY291bnRyeSBpcyBzaG93bi4KQWNjb3JkaW5nIHRvIHRoZSByZWNvZGluZywgdGhpcyBncmFwaCB3b3VsZCByZXByZXNlbnQgdGhlIHBlcmNlbnRhZ2Ugb2YgcmVzcG9uZGVudHMgd2hvIHJlZ2lzdGVyIGEgMSBpbiB0aGUgcmVjb2RlZCB2YXJpYWJsZS4KCiFbXShGaWd1cmUxLjEucG5nKXt3aWR0aD0iNTYzIn0KCkluIHRoZSByZXBvcnQgVGhlIFB1bHNlIG9mIERlbW9jcmFjeSBmb3IgdGhlIDIwMTgvMTkgcm91bmQsIGF2YWlsYWJsZSBbaGVyZV0oaHR0cHM6Ly93d3cudmFuZGVyYmlsdC5lZHUvbGFwb3AvYWIyMDE4LzIwMTgtMTlfQW1lcmljYXNCYXJvbWV0ZXJfUmVnaW9uYWxfUmVwb3J0XzEwLjEzLjE5LnBkZiksIGl0IGlzIHByZXNlbnRlZCBhIHNpbWlsYXIgZmlndXJlLCB1c2luZyB0aGUgc2FtZSB2YXJpYWJsZSBhbmQgdGhlIHNhbWUgcnVsZSBmb3IgcmVjb2RpbmcuCgohW10oRmlndXJlMS4yLnBuZyl7d2lkdGg9IjQzNSJ9CgpUbyByZWNvZGUgYSB2YXJpYWJsZSBpbiBSIHRoZXJlIGFyZSBzZXZlcmFsIHdheXMuCk9uZSBvZiB0aGUgbW9zdCBlZmZpY2llbnQgd2F5cyB0byBkbyB0aGlzIGlzIGJ5IHVzaW5nIHRoZSBjb21tYW5kIGByZWNvZGVgIGZyb20gdGhlIGBjYXJgIHBhY2thZ2UuClRoZSBgZHBseXJgIHBhY2thZ2UgaGFzIGFsc28gYSBgcmVjb2RlYCBjb21tYW5kIHRoYXQgY2FuIGNvbmZ1c2UgUi4KVG8gYXZvaWQgY29uZnVzaW9uIHdlIHdpbGwgc3BlY2lmeSBpbiB0aGUgc3ludGF4IGBjYXI6OnJlY29kZWAgcmVjb2RpbmcuClRoZSByZWNvZGVkIHZhcmlhYmxlIGlzIHJlY29yZGVkIGFzICJsYXBvcDIxXCRpbmc0cmVjIi4KVGhlbiwgdGhlIGNvbW1hbmQgYHRhYmxlYCBpcyB1c2VkIHRvIGRlc2NyaWJlIHRoaXMgbmV3IHZhcmlhYmxlLgoKYGBge3IgcmVjb2Rpbmd9CmxpYnJhcnkoY2FyKQpsYXBvcDIxJGluZzRyZWMgPC0gY2FyOjpyZWNvZGUobGFwb3AyMSRpbmc0LCAiMTo0PTA7IDU6Nz0xIikKdGFibGUobGFwb3AyMSRpbmc0cmVjKQpgYGAKCklmIHRoZSBvYnNlcnZhdGlvbnMgYmV0d2VlbiAxIGFuZCA0IG9mIHRoZSBvcmlnaW5hbCB2YXJpYWJsZSBhcmUgYWRkZWQgKDE2OTkgKyAxNDcwICsgMzAwMyArIDYwODkpLCB3ZSBzZWUgdGhhdCBpdCBpcyB0aGUgcmVzdWx0IGVxdWFscyB0aGUgb2JzZXJ2YXRpb25zIGluIHZhbHVlIDAgb2YgdGhlIG5ldyB2YXJpYWJsZSAoMTIyNjEpLCBhcyBpdCB3YXMgd3JpdHRlbiBpbiB0aGUgcmVjb2RpbmcuCkl0IHNob3VsZCBhbHNvIGJlIG5vdGVkIHRoYXQgdGhlIGRhdGFzZXQgaW4gdGhlIEVudmlyb25tZW50IG5vdyBoYXMgb25lIG1vcmUgdmFyaWFibGUsIHRvdGFsaW5nIDE4MjYgdmFyaWFibGVzLgoKIyBTZWxlY3Rpb24gb2Ygb2JzZXJ2YXRpb25zCgpUaGUgRmlndXJlIDEuMSBzaG93cyB0aGF0IHN1cHBvcnQgZm9yIGRlbW9jcmFjeSBnb2VzIGZyb20gYSBoaWdoIG9mIDgwJSBpbiBVcnVndWF5IHRvIGEgbG93IG9mIDQ2JSBpbiBIYWl0aS4KVG8gcmVwbGljYXRlIHJlc3VsdCBjb3JyZXNwb25kaW5nIHRvIFVydWd1YXksIHdlIGNhbiBzZWxlY3Qgb2JzZXJ2YXRpb25zIGZyb20gdGhpcyBjb3VudHJ5LgpBY2NvcmRpbmcgdG8gY29kaWZpY2F0aW9uIG9mIHZhcmlhYmxlICJwYWlzIiwgVXJ1Z3VheSBpcyBjb2RlZCBhcyAxNC4KCiFbXShjb3VudHJ5LnBuZyl7d2lkdGg9IjUxNSJ9CgpTZWxlY3Rpb24gb2Ygb2JzZXJ2YXRpb25zIGluIFIgY2FuIGJlIGRvbmUgaW4gc2V2ZXJhbCB3YXlzLgpPbmUgd2F5IGlzIHRvIHVzZSBicmFja2V0cy4KT3RoZXIgd2F5IGlzIHRvIHVzZSB0aGUgY29tbWFuZCBgc3Vic2V0YC4KV2l0aCB0aGlzIGNvbW1hbmQsIHdlIHNlbGVjdCBvYnNlcnZhdGlvbnMgZnJvbSB0aGlzIGNvdW50cnkgYW5kIHdlIHNhdmUgdGhpcyBzZWxlY3Rpb24gaW4gYSBuZXcgZGF0YWZyYW1lICJsYXBvcDEiLgpXZSBoYXZlIDMwMDkgb2JzZXJ2YXRpb25zIGluIFVydWd1YXkgYW5kIDE4MjYgdmFyaWFibGVzLgoKYGBge3IgVXJ1fQpsYXBvcDEgPSBzdWJzZXQobGFwb3AyMSwgcGFpcz09MTQpCnRhYmxlKGxhcG9wMSRwYWlzKQpgYGAKCldpdGggdGhpcyBzZWxlY3Rpb24gb2YgZGF0YSwgeW91IGNhbiBjYWxjdWxhdGUgdGhlIHBlcmNlbnRhZ2VzIChyZWxhdGl2ZSBmcmVxdWVuY2llcykgdXNpbmcgdGhlIGNvbW1hbmQgYHByb3AudGFibGVgLgpUaGlzIGNvbW1hbmQgZ2l2ZXMgdXMgdGhlIHJlbGF0aXZlIGZyZXF1ZW5jaWVzIChpbiB2YWx1ZXMgYmV0d2VlbiAwIGFuZCAxKSBvZiBhIGZyZWN1ZW5jeSB0YWJsZSBjYWxjdWxhdGVkIHdpdGggYHRhYmxlYC4KVGhlc2UgcmVsYXRpdmUgZnJlcXVlbmNpZXMgYXJlIG11bHRpcGxpZWQgYnkgMTAwIHRvIHJlcHJvZHVjZSB0aGUgcGVyY2VudGFnZSBpbiBlYWNoIGNvdW50cnkuCkluIHRoaXMgY2FzZSwgdGhlIGJyYWNrZXRzIGBb4oCmXWAgYXJlIHVzZWQgdG8gbWFrZSB0aGUgc2VsZWN0aW9uIG9mIGNhc2VzIGZyb20gZWFjaCBjb3VudHJ5LgoKYGBge3IgcGVyY2VudH0KcHJvcC50YWJsZSh0YWJsZShsYXBvcDEkaW5nNHJlY1tsYXBvcDEkcGFpcz09MTRdKSkqMTAwCmBgYAoKVGhlc2UgcmVzdWx0cyBhcmUgcGVyY2VudGFnZXMgKGJldHdlZW4gMCBhbmQgMTAwKSwgYnV0IGluY2x1ZGUgbWFueSBkZWNpbWFsIHBsYWNlcy4KVG8gcm91bmQgdG8gb25lIGRlY2ltYWwsIGFzIHNob3duIGluIEdyYXBoIDEuMiwgeW91IGNhbiB1c2UgdGhlIGNvbW1hbmQgYHJvdW5kYCwgd2hlcmUgYWxsIHRoZSBwcmV2aW91cyBzeW50YXggaXMgbmVzdGVkLgpJbiB0aGlzIGNvbW1hbmQsIHlvdSBoYXZlIHRvIHNwZWNpZnkgdGhlIG51bWJlciBvZiBkZWNpbWFsIHBsYWNlcyB5b3Ugd2FudCwgd2hpY2ggaW4gdGhpcyBjYXNlIGlzIDEuCgpgYGB7ciByb3VuZH0Kcm91bmQocHJvcC50YWJsZSh0YWJsZShsYXBvcDEkaW5nNHJlY1tsYXBvcDEkcGFpcz09MTRdKSkqMTAwLCAxKQpgYGAKCkFjY29yZGluZyB0byB0aGlzIHJlc3VsdCwgODQuNSUgb2YgVXJ1Z3VheWFucyBzdXBwb3J0IGRlbW9jcmFjeS4KVGhpcyByZXN1bHQgaXMgZGlmZmVyZW50IGZyb20gd2hhdCBpdCBpcyByZXBvcnRlZCBpbiBGaWd1cmUgMS4xLCB3aGVyZSByZXBvcnRlZCB2YWx1ZSBpcyA4MCUuClRoaXMgZGlmZmVyZW5jZSBpcyBkdWUgdG8gdGhlIGZhY3QgdGhhdCBvdXIgcHJvY2VkdXJlcyBkbyBub3QgaW5jbHVkZSB0aGUgZWZmZWN0IG9mIGNvbXBsZXggZGVzaWduIGZlYXR1cmVzLCBzdWNoIGFzIHdlaWdodHMsIHN0cmF0aWZpY2F0aW9uLCBhbmQgY2x1c3RlciBzYW1wbGluZy4KQmVsb3csIHdlIHByZXNlbnQgcHJvY2VkdXJlcyB0byByZXByb2R1Y2UgcHJlY2lzZSByZXBvcnRlZCByZXN1bHRzLgoKVGhlIHJlcG9ydCBmb3IgdGhlIDIwMTgvMTkgd2F2ZSBpbmRpY2F0ZXMgIkZpZ3VyZSAxLjIgZGlzcGxheXMgdGhlIHBlcmNlbnQgb2YgaW5kaXZpZHVhbHMgaW4gZWFjaCBjb3VudHJ5IHRoYXQgZXhwcmVzc2VzIHN1cHBvcnQgZm9yIGRlbW9jcmFjeSBpbiAyMDE4LzE5LiBTdXBwb3J0IGZvciBkZW1vY3JhY3kgcmFuZ2VzIGZyb20gYSBsb3cgb2YgNDUlIGluIEhvbmR1cmFzIHRvIGEgaGlnaCBvZiA3Ni4yJSBpbiBVcnVndWF5LiIgKHAuIDExKS4KCkZvciByZXBsaWNhdGluZyB0aGVzZSByZXN1bHRzIGFib3V0IEhvbmR1cmFzIGFuZCBVcnVndWF5IGZvciB0aGUgMjAxOC8xOSByb3VuZCwgd2UgY2FuIHNlbGVjdCBvYnNlcnZhdGlvbnMgZm9yIHRoZXNlIHR3byBjb3VudHJpZXMuCkFjY29yZGluZyB0byB0aGUgcXVlc3Rpb25uYWlyZSwgYXZhaWxhYmxlIEhFUkUsIEhvbmR1cmFzIGlzIGNvZGVkIGFzIDQgYW5kIFVydWd1YXkgYXMgMTQgaW4gdmFyaWFibGUgInBhaXMiLCB0aGF0IGlzIGltcG9ydGVkIGFzIGEgbnVtZXJpYyB2YXJpYWJsZS4KCldlIGluY2x1ZGUgdGhlIG9wZXJhdG9yICJvciIsIHRoYXQgaXMgd3JpdHRlbiBhcyAiXHwiIGluIFIuCkluIHRoaXMgd2F5LCB3ZSBjYW4gc2VsZWN0IG9ic2VydmF0aW9ucyBmcm9tIEhvbmR1cmFzIG9yIFVydWd1YXkgdXNpbmcgYHBhaXM9PTQgfCBwYWlzPT0xNGAuClRoZSBkZXNjcmlwdGlvbiBvZiB2YXJpYWJsZSAicGFpcyIgc2hvd3MgdGhhdCBpdCBpbmNsdWRlcyBvbmx5IG9ic2VydmF0aW9ucyBmb3IgSG9uZHVyYXMgKDIpIGFuZCBVcnVndWF5ICgxNCkuCgpgYGB7ciBzZWxlY3R9CmxhcG9wMiA9IHN1YnNldChsYXBvcDE4LCBwYWlzPT00IHwgcGFpcz09MTQpCnRhYmxlKGxhcG9wMiRwYWlzKQpgYGAKClRoZSBuZXcgZGF0YWZyYW1lICJsYXBvcDIiIGhhcyAzMTQxIG9ic2VydmF0aW9ucyBhbmQgODQgdmFyaWFibGVzLgpJdCBkb2VzIG5vdCBpbmNsdWRlIGEgcmVjb2RlZCB2YXJpYWJsZSBmb3Igc3VwcG9ydCBmb3IgZGVtb2NyYWN5LgpXZSBwcm9jZWVkIHRvIGluY2x1ZGUgaXQuCgpgYGB7ciBpbmc0fQpsYXBvcDIkaW5nNHJlYyA8LSBjYXI6OnJlY29kZShsYXBvcDIkaW5nNCwgIjE6ND0wOyA1Ojc9MSIpCmBgYAoKV2l0aCB0aGlzIHZhcmlhYmxlLCB3ZSBjYW4gZm9sbG93IHRoZSBzYW1lIHByb2NlZHVyZXMgYXMgYmVmb3JlOiBwcm9kdWNlIGEgcmVsYXRpdmUgZnJlcXVlbmN5IHRhYmxlLgoKYGBge3IgcmVsYXRpdmV9CnByb3AudGFibGUodGFibGUobGFwb3AyJGluZzRyZWNbbGFwb3AyJHBhaXM9PTRdKSkqMTAwCnByb3AudGFibGUodGFibGUobGFwb3AyJGluZzRyZWNbbGFwb3AyJHBhaXM9PTE0XSkpKjEwMApgYGAKCkFuZCB0aGVuLCB3ZSBpbmNsdWRlIHJvdW5kaW5nLgoKYGBge3Igcm91bmQyfQpyb3VuZChwcm9wLnRhYmxlKHRhYmxlKGxhcG9wMiRpbmc0cmVjW2xhcG9wMiRwYWlzPT00XSkpKjEwMCwgMSkKcm91bmQocHJvcC50YWJsZSh0YWJsZShsYXBvcDIkaW5nNHJlY1tsYXBvcDIkcGFpcz09MTRdKSkqMTAwLCAxKQpgYGAKCldpdGggdGhpcyBjb2RlLCB3ZSBoYXZlIHJlcHJvZHVjZWQgcmVzdWx0cyBmb3IgY291bnRyaWVzIGluIHRoZSBleHRyZW1lcyBvZiBGaWd1cmUgMS4yLgpJbiB0aGlzIGNhc2UsIHJlc3VsdHMgYXJlIHNpbWlsYXIgdG8gdGhlIG9uZXMgcmVwb3J0ZWQgaW4gdGhlIGZpZ3VyZSBpbiB0aGUgcmVwb3J0LgoKQm90aCByZXBvcnRzIGFsc28gaW5kaWNhdGUgdGhhdCB0aGUgVW5pdGVkIFN0YXRlcyBhbmQgQ2FuYWRhIGFyZSBleGNsdWRlZCBmcm9tIHRoZSBjYWxjdWxhdGlvbnMuClRoZSBkYXRhc2V0IGxvYWRlZCBhcyAibGFwb3AxOCIgaW5jbHVkZXMgYWxsIHRoZSBjb3VudHJpZXMgaW4gdGhlIHJvdW5kLgpUbyBleGNsdWRlIHRoZXNlIHR3byBjb3VudHJpZXMsIHdlIGhhdmUgdG8gc2VsZWN0IHRoZSBjb3VudHJpZXMgdGhhdCBhcmUgTk9UIFVTQSBhbmQgQ2FuYWRhLgpUaGlzIG5ldyBzZWxlY3Rpb24gY2FuIGJlIHNhdmVkIGluIGEgbmV3IGRhdGFmcmFtZSBvciBpdCBjYW4gYmUgb3ZlcndyaXR0ZW4gaW4gdGhlIG9yaWdpbmFsIGRhdGFmcmFtZSwgYXMgaXQgaXMgZG9uZSBpbiB0aGlzIGNhc2UgYmVjYXVzZSB0aGUgZXhjbHVzaW9uIG9mIHRoZXNlIGNvdW50cmllcyBpcyBmb3IgYWxsIHRoZSBjYWxjdWxhdGlvbnMgdGhhdCBmb2xsb3cuCkFjY29yZGluZyB0byB0aGUgcXVlc3Rpb25uYWlyZSwgVVNBIGhhcyB0aGUgY29kZSA0MCBhbmQgQ2FuYWRhLCB0aGUgY29kZSA0MSBpbiB0aGUgdmFyaWFibGUgInBhaXMiLgpUbyBleGNsdWRlIHRoZW0sIGNvdW50cmllcyB3aXRoIGEgY29kZSBvZiBsZXNzIHRoYW4gNDAgKG9yIDM1IG9yIGxlc3MpIG11c3QgYmUgaW5jbHVkZWQuCkZvciB0aGlzIHdlIGNhbiBhZ2FpbiB1c2UgdGhlIGBzdWJzZXRgIGNvbW1hbmQuCgpgYGB7ciBkcm9wIFVTQSBDYW5hZGF9CmxhcG9wMTggPC0gc3Vic2V0KGxhcG9wMTgsIHBhaXM8PTM1KQpgYGAKCkl0IGNhbiBiZSBvYnNlcnZlZCBpbiB0aGUgRW52aXJvbm1lbnQgdGhhdCB0aGUgb2JzZXJ2YXRpb25zIG9mIHRoZSAibGFwb3AxOCIgZGF0YWZyYW1lIGFyZSByZWR1Y2VkIGFmdGVyIHJ1bm5pbmcgdGhpcyBjb2RlLCBzaW5jZSB0aGUgb2JzZXJ2YXRpb25zIG9mIHJlcG9uZGVudHMgaW4gdGhlc2UgdHdvIGNvdW50cmllcyBoYXZlIGJlZW4gZWxpbWluYXRlZC4KVGhlIG51bWJlciBvZiBvYnNlcnZhdGlvbnMgZ29lcyBmcm9tIDMxLDA1MCB0byAyOCwwNDIsIGEgbnVtYmVyIHRoYXQgY29pbmNpZGVzIHdpdGggdGhhdCBvZiB0aGUgZGF0YXNldCBpbiAuUkRhdGEgZm9ybWF0IHRoYXQgd2UgdXNlZCBpbiB0aGUgcHJldmlvdXMgbW9kdWxlIGFuZCB0aGF0IHdlIGluZGljYXRlZCB0aGF0IGl0IGRpZCBub3QgaW5jbHVkZSB0aGVzZSBjb3VudHJpZXMuCgpJbiB0aGUgc2FtZSB3YXksIHdlIGNhbiBwcm9jZWVkIGluIHRoZSAyMDIxIHdhdmUgZGF0YXNldC4KQWZ0ZXIgdGhpcywgb2JzZXJ2YXRpb25zIGRlY3JlYXNlIHRvIDYwLDY2MS4KCmBgYHtyIGRyb3AgMjAyMX0KbGFwb3AyMSA9IHN1YnNldChsYXBvcDIxLCBwYWlzPD0zNSkKYGBgCgojIENhbGN1bGF0aW5nIGEgdmFyaWFibGUKCkEgZnJlcXVlbnQgTEFQT1AgcHJhY3RpY2Ugd2l0aCB0aGUgQW1lcmljYXNCYXJvbWV0ZXIgZGF0YSBpcyB0aGUgcmVzY2FsaW5nIG9mIHZhcmlhYmxlcy4KVGhlIHJlcG9ydCdzIGNoYXB0ZXIgb24gZGVtb2NyYXRpYyBsZWdpdGltYWN5IHByb3ZpZGVzIGV4YW1wbGVzIG9mIHRoaXMgcmVzY2FsaW5nIHdpdGggdmFyaWFibGVzIHJlbGF0ZWQgdG8gc3VwcG9ydCBmb3IgdGhlIHN5c3RlbS4KVG8gY2FsY3VsYXRlIHRoaXMgaW5kZXggZm9yIHN5c3RlbSBzdXBwb3J0LCB3ZSB3b3JrIHdpdGggYSBzZXQgb2YgZml2ZSB2YXJpYWJsZXM6CgpCMS4KVG8gd2hhdCBleHRlbnQgZG8geW91IHRoaW5rIHRoZSBjb3VydHMgb2YgKGNvdW50cnkpIGd1YXJhbnRlZSBhIGZhaXIgdHJpYWw/Ci4gVG8gd2hhdCBleHRlbnQgZG8geW91IHJlc3BlY3QgdGhlIHBvbGl0aWNhbCBpbnN0aXR1dGlvbnMgb2YgKGNvdW50cnkpPwoKQjIuClRvIHdoYXQgZXh0ZW5kIGRvIHlvdSByZXNwZWN0IHRoZSBwb2xpdGljYWwgaW5zdGl0dXRpb25zIG9mIChjb3VudHJ5KT8KCkIzLgpUbyB3aGF0IGV4dGVudCBkbyB5b3UgdGhpbmsgdGhlIGJhc2ljIHJpZ2h0cyBvZiB0aGUgY2l0aXplbiBhcmUgd2VsbCBwcm90ZWN0ZWQgYnkgdGhlIHBvbGl0aWNhbCBzeXN0ZW0gb2YgKGNvdW50cnkpPwoKQjQuClRvIHdoYXQgZXh0ZW50IGFyZSB5b3UgcHJvdWQgdG8gbGl2ZSB1bmRlciB0aGUgcG9saXRpY2FsIHN5c3RlbSBvZiAoY291bnRyeSk/CgpCNi4KVG8gd2hhdCBleHRlbnQgZG8geW91IHRoaW5rIHRoZSBwb2xpdGljYWwgc3lzdGVtIG9mIChjb3VudHJ5KSBzaG91bGQgYmUgc3VwcG9ydGVkPwoKQXMgdGhlIHJlcG9ydCBpbmRpY2F0ZXMgIkZvciBlYWNoIHF1ZXN0aW9uLCB0aGUgb3JpZ2luYWwgc2NhbGUgZnJvbSAxICgiIE5vdCBhdCBhbGwgIikgdG8gNyAoIkEgbG90IikgaXMgcmVjb2RlZCBvbiBhIDAtMTAwIHNjYWxlLCBpbiBzdWNoIGEgd2F5IHRoYXQgMCBpbmRpY2F0ZXMgdGhlIGxvd2VzdCBsZXZlbCBvZiBzdXBwb3J0IGZvciB0aGUgcG9saXRpY2FsIHN5c3RlbSBhbmQgMTAwIGlzIHRoZSBoaWdoZXN0IGxldmVsIG9mIHN1cHBvcnQgZm9yIHRoZSBwb2xpdGljYWwgc3lzdGVtLiBUaGlzIG5ldyBzY2FsZSBmb2xsb3dzIHRoZSB0eXBpY2FsIExBUE9QIHJlY29kaW5nIGFuZCBjYW4gYmUgaW50ZXJwcmV0ZWQgYXMgYSBtZWFzdXJlIG9mIHN1cHBvcnQgaW4gdW5pdHMsIG9yIGRlZ3JlZXMsIG9uIGEgY29udGludW91cyBzY2FsZSByYW5naW5nIGZyb20gMCB0byAxMDAiIChwLiAzNCkuClRvIGNoZWNrIHRoZSBvcmlnaW5hbCBzY2FsZSBvZiB0aGVzZSB2YXJpYWJsZXMsIHdlIGNhbiBkZXNjcmliZSB0aGVzZSB2YXJpYWJsZXMgdXNpbmcgdGhlIGB0YWJsZWAgY29tbWFuZC4KCmBgYHtyIGRlc2NyaWJpbmcyfQp0YWJsZShsYXBvcDE4JGIxKQp0YWJsZShsYXBvcDE4JGIyKQp0YWJsZShsYXBvcDE4JGIzKQp0YWJsZShsYXBvcDE4JGI0KQp0YWJsZShsYXBvcDE4JGI2KQpgYGAKCkl0IGlzIG9ic2VydmVkIHRoYXQgYWxsIHRoZSB2YXJpYWJsZXMgcnVuIG9uIGEgc2NhbGUgZnJvbSAxIHRvIDcuClRvIHJlc2NhbGUgYSB2YXJpYWJsZSBmcm9tIGFuIG9yaWdpbmFsIHNjYWxlIGZyb20gMSB0byA3IHRvIGFub3RoZXIgZnJvbSAwIHRvIDEwMCwgdGhlIGZpcnN0IHRoaW5nIHRvIGRvIGlzIHN1YnRyYWN0IDEgdW5pdCwgc28gdGhlIHZhcmlhYmxlIHdvdWxkIGhhdmUgYSBzY2FsZSBvZiAwIHRvIDYsIHRoZW4gZGl2aWRlIGl0IGJ5IDYsIHdpdGggd2hpY2ggd291bGQgdmFyeSBiZXR3ZWVuIDAgYW5kIDEgYW5kLCBmaW5hbGx5LCBtdWx0aXBseSBpdCBieSAxMDAuCnRoaXMgaXM6CgpSZXNjYWxlZCB2YXJpYWJsZSA9ICgob3JpZ2luYWwgdmFyaWFibGUgLTEpLzYpXCoxMDAKCmBgYHtyIGNhbGN1bGF0ZX0KbGFwb3AxOCRiMXJlYyA8LSAoKGxhcG9wMTgkYjEtMSkvNikqMTAwCmxhcG9wMTgkYjJyZWMgPC0gKChsYXBvcDE4JGIyLTEpLzYpKjEwMApsYXBvcDE4JGIzcmVjIDwtICgobGFwb3AxOCRiMy0xKS82KSoxMDAKbGFwb3AxOCRiNHJlYyA8LSAoKGxhcG9wMTgkYjQtMSkvNikqMTAwCmxhcG9wMTgkYjZyZWMgPC0gKChsYXBvcDE4JGI2LTEpLzYpKjEwMAp0YWJsZShsYXBvcDE4JGIxcmVjKQpgYGAKCldpdGggdGhpcyB0cmFuc2Zvcm1hdGlvbiwgaXQgaXMgb2JzZXJ2ZWQgdGhhdCB0aGUgNCwwODkgaW50ZXJ2aWV3ZWVzIHdobyBzY29yZWQgMSBpbiBxdWVzdGlvbiBCMSBub3cgaGF2ZSBhIHNjb3JlIG9mIDAuClRoZSA0LDA2NyB3aG8gc2NvcmVkIDIgbm93IGhhdmUgYSBzY29yZSBvZiAxNi42NywgdGhhdCBpcyAyLTE9MS82PTAuMTY2N1wqMTAwPTE2LjY3LgpUaGlzIHNhbWUgb3BlcmF0aW9uIGNvdWxkIGJlIGRvbmUgd2l0aCB0aGUgYGNhciA6OiByZWNvZGVgIGNvbW1hbmQsIGZvbGxvd2luZyB0aGlzIHJlY29kaW5nIHJ1bGU6CgotICAgVmFsdWUgb2YgMSBpbiBvcmlnaW5hbCB2YXJpYWJsZSBpcyByZWNvZGVkIGFzIDAgaW4gbmV3IHZhcmlhYmxlCi0gICBWYWx1ZSBvZiAyIGluIG9yaWdpbmFsIHZhcmlhYmxlIGlzIHJlY29kZWQgYXMgMTYuNjcgaW4gbmV3IHZhcmlhYmxlCi0gICBWYWx1ZSBvZiAzIGluIG9yaWdpbmFsIHZhcmlhYmxlIGlzIHJlY29kZWQgYXMgMzMuMzMgaW4gbmV3IHZhcmlhYmxlCi0gICBWYWx1ZSBvZiA0IGluIG9yaWdpbmFsIHZhcmlhYmxlIGlzIHJlY29kZWQgYXMgNTAgaW4gbmV3IHZhcmlhYmxlCi0gICBWYWx1ZSBvZiA1IGluIG9yaWdpbmFsIHZhcmlhYmxlIGlzIHJlY29kZWQgYXMgNjYuNjcgaW4gbmV3IHZhcmlhYmxlCi0gICBWYWx1ZSBvZiA2IGluIG9yaWdpbmFsIHZhcmlhYmxlIGlzIHJlY29kZWQgYXMgODMuMzMgaW4gbmV3IHZhcmlhYmxlCi0gICBWYWx1ZSBvZiA3IGluIG9yaWdpbmFsIHZhcmlhYmxlIGlzIHJlY29kZWQgYXMgMTAwIGluIG5ldyB2YXJpYWJsZQoKVGhpcyB3YXkgb2YgcmVjb2RpbmcsIGhvd2V2ZXIsIGlzIG5vdCB2ZXJ5IGVmZmljaWVudC4KSXQgaXMgc2ltcGxlciB0byB1c2UgdGhlIGZvcm11bGEgdG8gY2FsY3VsYXRlIHRoZSByZWNvZGluZy4KVG8gY2FsY3VsYXRlIHRoZSBzeXN0ZW0gc3VwcG9ydCBpbmRleCwgdGhlIHJlcG9ydCBpbmRpY2F0ZXMgdGhhdCAiVGhlIHN5c3RlbSBzdXBwb3J0IGluZGV4IGlzIHRoZSBhdmVyYWdlIG9mIGZpdmUgcXVlc3Rpb25zOiBCMSwgQjIsIEIzLCBCNCBhbmQgQjYiIChwLjQ2KS4KSW4gb3RoZXIgd29yZHMsIHdpdGggdGhlIHJlc2NhbGVkIHZhcmlhYmxlcywgdGhlIGF2ZXJhZ2Ugb2YgdGhlc2UgZml2ZSB2YXJpYWJsZXMgaGFzIHRvIGJlIGNhbGN1bGF0ZWQgZm9yIGVhY2ggaW5kaXZpZHVhbCAodGhhdCBpcywgaW4gZWFjaCByb3cgb2YgdGhlIGRhdGFzZXQpLgpUaGlzIGNvdWxkIGJlIGRvbmUgYnkgY2FsY3VsYXRpbmcgdGhlIGF2ZXJhZ2UgbWFudWFsbHkuCgpTeXN0ZW0gc3VwcG9ydCA9IChiMXJlYyArIGIycmVjICsgYjNyZWMgKyBiNHJlYyArIGI2cmVjKS81CgpJbiBSIHdlIGhhdmUgdGhlIGNvbW1hbmQgYHJvd01lYW5zYCB0aGF0IGlzIHVzZWQgdG8gY2FsY3VsYXRlIGF2ZXJhZ2VzIG9mIGNlcnRhaW4gY29sdW1ucyBmb3IgZWFjaCByb3cuClRoZSBzeW50YXggYFssIDg2OjkwXWAgaW5kaWNhdGVzIHRoYXQgdGhlIGF2ZXJhZ2UgY2FsY3VsYXRpb24gd2lsbCBiZSBwZXJmb3JtZWQgYnkgcm93cyBmb3IgYWxsIHJvd3MgYW5kIHVzaW5nIGNvbHVtbnMgODYgdG8gOTAgb2YgdGhlICJsYXBvcDE4IiBkYXRhZnJhbWUgKHRoZSBjYWxjdWxhdGlvbiBjb3VsZCBiZSBkb25lIGZvciBzb21lIHBhcnRpY3VsYXIgcm93cyBieSBkZWZpbmluZyBgWyByb3dfbjogcm93X20sIDg2OjkwXWApLgpUaGlzIGF2ZXJhZ2UgaXMgc2F2ZWQgaW4gYSBuZXcgdmFyaWFibGUgInN1cHBvcnQiLCB3aGljaCBpcyBkZXNjcmliZWQuCgpgYGB7ciBzeXN0ZW0gc3VwcG9ydH0KbGFwb3AxOCRhcG95byA9IHJvd01lYW5zKGxhcG9wMThbLDg1Ojg5XSkKdGFibGUobGFwb3AxOCRhcG95bykKYGBgCgpXaXRoIHRoaXMgaW5kZXgsIGl0IGlzIHBvc3NpYmxlIHRvIGNhbGN1bGF0ZSB0aGUgYXZlcmFnZSBzdXBwb3J0IGZvciB0aGUgc3lzdGVtIGZvciB0aGUgbGFzdCByb3VuZCBvZiB0aGUgQW1lcmljYXNCYXJvbWV0ZXIsIGFzIHdlbGwgYXMgdGhlIGF2ZXJhZ2VzIGZvciBlYWNoIG9mIHRoZSB2YXJpYWJsZXMgdGhhdCBhcmUgaW5jbHVkZWQgaW4gdGhlIGluZGV4LgpUaGUgYG1lYW5gIGNvbW1hbmQgaXMgdXNlZCBmb3IgdGhlIGF2ZXJhZ2UgYW5kIHRoZSBgbmEucm0gPSBUYCBzcGVjaWZpY2F0aW9uIGlzIHVzZWQgdG8gdGVsbCB0aGUgY29tbWFuZCBub3QgdG8gdGFrZSBpbnRvIGFjY291bnQgdGhlIG1pc3NpbmcgdmFsdWVzIG9mIHRoZXNlIHZhcmlhYmxlcy4KVGhlc2Ugc3RhdGlzdGljcyB3aWxsIGJlIHNlZW4gaW4gbW9yZSBkZXRhaWwgaW4gb3RoZXIgZG9jdW1lbnRzLgoKYGBge3Igc3lzdGVtIHN1cHBvcnQgMjAxOC8xOX0KbWVhbihsYXBvcDE4JGFwb3lvLCBuYS5ybT1UKSAjc3lzdGVtIHN1cHBvcnQKbWVhbihsYXBvcDE4JGIxcmVjLCBuYS5ybT1UKSAjY291cnRzIGd1YXJhbnRlZSBmYWlyIHRyaWFsCm1lYW4obGFwb3AxOCRiMnJlYywgbmEucm09VCkgI1Jlc3BlY3QgZm9yIGluc3RpdHV0aW9ucwptZWFuKGxhcG9wMTgkYjNyZWMsIG5hLnJtPVQpICNCYXNpYyByaWdodHMgYXJlIHByb3RlY3RlZAptZWFuKGxhcG9wMTgkYjRyZWMsIG5hLnJtPVQpICNQcmlkZSBpbiB0aGUgcG9saXRpY2FsIHN5c3RlbQptZWFuKGxhcG9wMTgkYjZyZWMsIG5hLnJtPVQpICNUaGUgcG9saXRpY2FsIHN5c3RlbSBzaG91bGQgYmUgc3VwcG9ydGVkCmBgYAoKVGhlc2UgcmVzdWx0cyBhcmUgdGhvc2Ugc2hvd24gaW4gRmlndXJlIDIuMSBmb3IgdGhlIDIwMTgvMTkgcm91bmQuCgohW10oRmlndXJlMi4xLnBuZyl7d2lkdGg9IjYyMiJ9CgojIENvbmRpY2lvbmFsbHkgY2FsY3VsYXRpbmcgYSB2YXJpYWJsZQoKU29tZXRpbWVzIHRoZSBjYWxjdWxhdGlvbiBvZiBhIHZhcmlhYmxlIGRvZXMgbm90IG9ubHkgcmVxdWlyZSB0aGUgbnVtZXJpY2FsIHRyYW5zZm9ybWF0aW9uIG9mIHRoZSBvcmlnaW5hbCB2YXJpYWJsZSwgYnV0IHRoZSB2YWx1ZXMgb2YgdGhlIG5ldyB2YXJpYWJsZSBkZXBlbmQgb24gdGhlIHZhbHVlcyBvZiBvdGhlciB2YXJpYWJsZXMuCkZvciBleGFtcGxlLCB0aGUgY2hhcHRlciAiU29jaWFsIG5ldHdvcmtzIGFuZCBwb2xpdGljYWwgYXR0aXR1ZGVzIiBvZiB0aGUgcmVwb3J0ICJUaGUgUHVsc2Ugb2YgRGVtb2NyYWN5IiBwcmVzZW50cyB0aGUgcmVzdWx0cyBmb3IgdGhlIHZhcmlhYmxlcyAiV2hhdHNBcHAgdXNlciIsICJUd2l0dGVyIHVzZXIiIGFuZCAiRmFjZWJvb2sgdXNlciIuClRvIGNhbGN1bGF0ZSB0aGVzZSB2YXJpYWJsZXMsIGZvb3Rub3RlIDcgb2YgdGhpcyBjaGFwdGVyIGluZGljYXRlczogIkZvciBlYWNoIHBsYXRmb3JtLCB3ZSBpZGVudGlmeSB1c2VycyB3aXRoIGEgY29tYmluYXRpb24gb2YgdHdvIHNldHMgb2Ygc3VydmV5IHF1ZXN0aW9ucy4gRmlyc3QsIHdlIGlkZW50aWZ5IHVzZXJzIGFzIHRob3NlIHdobyByZXNwb25kIHBvc2l0aXZlbHkgdG8gdGhlIHF1ZXN0aW9ucywgU01FRElBMS9TTUVESUE0L1NNRURJQTcuIERvIHlvdSBoYXZlIGEgRmFjZWJvb2svVHdpdHRlci9XaGF0c0FwcCBhY2NvdW50PyBUaGVuLCB3ZSByZWNvZGUgYXMgbm9uLXVzZXJzIHRob3NlIHdobyByZXNwb25kIm5ldmVyIiB0byB0aGUgZm9sbG93LXVwIHF1ZXN0aW9ucywgU01FRElBMi9TTUVESUE1L1NNRURJQTguIEhvdyBvZnRlbiBkbyB5b3Ugc2VlIGNvbnRlbnQgb24gRmFjZWJvb2svVHdpdHRlci9XaGF0c0FwcD8iIChwLiA2NCkuCgohW10oc21lZGlhLnBuZyl7d2lkdGg9IjUzMSJ9CgpUaGF0IGlzLCB0aGUgdXNlciBpcyBub3Qgb25seSB0aGUgb25lIHdobyBoYXMgYW4gYWNjb3VudCAoU01FRElBMSA9IDEpLCBidXQgdGhlIG9uZSB3aG8gdXNlcyBpdCB3aXRoIGEgY2VydGFpbiBmcmVxdWVuY3kgKFNNRURJQTIgPSAxLCAyLCAzLCA0KS4KSW4gdGhpcyB3YXksIHRoZSBub24tdXNlciBjYW4gaGF2ZSBhbiBhY2NvdW50LCBidXQgbmV2ZXIgdXNlIGl0LgpUaGVyZWZvcmUsIHRoZSB2YXJpYWJsZSAidXNlciIgZGVwZW5kcyBvbiB0aGUgdmFsdWVzIG9mIDIgdmFyaWFibGVzLgpUaGUgcnVsZSBmb3IgY29kaW5nIGlzOgoKLSAgIEZhY2Vib29rIHVzZXIgPSAxIChoZS9zaGUgaXMgYSB1c2VyKSBpZiBTTUVESUExID0gMSAoaGUvc2hlIGhhcyBhbiBhY2NvdW50KSBhbmQgU01FRElBMiBcPD0gNCAoaGUvc2hlIHVzZXMgaXQgd2l0aCBzb21lIGZyZXF1ZW5jeSkKCi0gICBGYWNlYm9vayB1c2VyID0gMCAoaGUvc2hlIGlzIG5vdCBhIHVzZXIpIGlmIFNNRURJQTIgPSAyIChoZS9zaGUgZG9lc27CtHQgaGF2ZSBhbiBhY2NvdW50KSBvciBTTUVESUEyID0gNSAoIGhlL3NoZSBoYXMgYW4gYWNjb3VudCBidXQgbmV2ZXIgdXNlcyBpdCkKClRoaXMgcnVsZSB0cmFuc2Zvcm1zIGludG8gdGhlIGZvbGxvd2luZyBSIHN5bnRheCwgd2hpY2ggdXNlcyB0aGUgY29tbWFuZCBgw6xmZWxzZWAuClRoaXMgc3ludGF4IGluY2x1ZGVzIHRoZSBjb25kaXRpb24gdG8gYXNzaWduIHZhbHVlcyBvZiAxIHRvIGEgbmV3IHZhcmlhYmxlIGFuZCBhc3NpZ25zIGFsbCBvdGhlciBvYnNlcnZhdGlvbnMgdGhlIHZhbHVlIG9mIDAuClRoZXNlIG5ldyB2YXJpYWJsZXMgYXJlIGRlc2NyaWJlZCB1c2luZyB0aGUgYHRhYmxlYCBjb21tYW5kIHRvIGdlbmVyYXRlIHRoZSBhYnNvbHV0ZSBmcmVxdWVuY2llcyx0aGUgYHByb3AudGFibGVgIGNvbW1hbmQgZm9yIHRoZSByZWxhdGl2ZSBmcmVxdWVuY2llcyBhbmQgdGhlIGByb3VuZGAgY29tbWFuZCB0byByb3VuZCB0aGUgZGVjaW1hbHMuClRoZXNlIGNvbW1hbmRzIHdpbGwgYmUgc2VlbiBpbiBtb3JlIGRldGFpbCBpbiB0aGUgZm9sbG93aW5nIGRvY3VtZW50cy4KCmBgYHtyIHVzZXJzLCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxhcG9wMTgkZmJfdXNlciA8LSBpZmVsc2UobGFwb3AxOCRzbWVkaWExPT0xICYgbGFwb3AxOCRzbWVkaWEyPD00LCAxLCAwKQpsYXBvcDE4JHR3X3VzZXIgPC0gaWZlbHNlKGxhcG9wMTgkc21lZGlhND09MSAmIGxhcG9wMTgkc21lZGlhNTw9NCwgMSwgMCkKbGFwb3AxOCR3YV91c2VyIDwtIGlmZWxzZShsYXBvcDE4JHNtZWRpYTc9PTEgJiBsYXBvcDE4JHNtZWRpYTg8PTQsIDEsIDApCnJvdW5kKHByb3AudGFibGUodGFibGUobGFwb3AxOCRmYl91c2VyKSkqMTAwLCAxKQpyb3VuZChwcm9wLnRhYmxlKHRhYmxlKGxhcG9wMTgkdHdfdXNlcikpKjEwMCwgMSkKcm91bmQocHJvcC50YWJsZSh0YWJsZShsYXBvcDE4JHdhX3VzZXIpKSoxMDAsIDEpCmBgYAoKVGhlc2UgcmVzdWx0cyBhcmUgdGhvc2UgcHJlc2VudGVkIGluIEdyYXBoIDMuMSBvZiB0aGUgcmVwb3J0IGluIHRoZSBmb3JtIG9mIHBpZSBjaGFydHMuClRoZXNlIHR5cGVzIG9mIGdyYXBocyB3aWxsIGJlIHNlZW4gaW4gdGhlIG5leHQgc2VjdGlvbi4KCiFbXShGaWd1cmUzLjEucG5nKXt3aWR0aD0iMzA5In0KCiMgRGVzaWduIGVmZmVjdCBvYnNlcnZhdGlvbgoKQm90aCB0aGUgcmVzdWx0cyBmb3Igc3lzdGVtIHN1cHBvcnQgYW5kIHRob3NlIG9mIHNvY2lhbCBuZXR3b3JrIHVzZXJzIGRpZmZlciBmcm9tIHRob3NlIHRoYXQgYXBwZWFyIGluIHRoZSByZXBvcnQgZm9yIHR3byByZWFzb25zLgpGaXJzdCwgYWJvdXQgc3VwcG9ydCB0aGUgc3lzdGVtLCBiZWNhdXNlICJDcm9zcy10aW1lIHZhbHVlcyBhcmUgY2FsY3VsYXRlZCBpbmNsdWRpbmcgb25seSB0aG9zZSBjb3VudHJpZXMgdGhlIEFtZXJpY2FzQmFyb21ldGVyIGhhcyBzdXJ2ZXllZCBjb25zaXN0ZW50bHkgc2luY2UgMjAwNjogQXJnZW50aW5hLCBCcmF6aWwsIEJvbGl2aWEsIENoaWxlLCBDb2xvbWJpYSwgQ29zdGEgUmljYSAsIHRoZSBEb21pbmljYW4gUmVwdWJsaWMsIEVjdWFkb3IsIEVsIFNhbHZhZG9yLCBHdWF0ZW1hbGEsIEhvbmR1cmFzLCBKYW1haWNhLCBNZXhpY28sIE5pY2FyYWd1YSwgUGFuYW1hLCBQYXJhZ3VheSwgUGVydSwgVXJ1Z3VheSIgKHAuNDYpLgpUaGUgY29kZSBvbmx5IGZpbHRlcnMgdGhlIGxhc3Qgcm91bmQsIHdoaWNoIGluY2x1ZGVzIGNvdW50cmllcyB0aGF0IGFyZSBub3Qgb24gdGhhdCBsaXN0LCBzdWNoIGFzIHRoZSBVbml0ZWQgU3RhdGVzIG9yIENhbmFkYS4KT24gdGhlIG90aGVyIGhhbmQsIHRoZSBjYWxjdWxhdGlvbnMgcmVwb3J0ZWQgaW4gdGhlIHB1YmxpY2F0aW9uIGluY2x1ZGUgdGhlIHVzZSBvZiBzdXJ2ZXkgd2VpZ2h0cywgd2hpY2ggaGF2ZSBub3QgYmVlbiBpbmNsdWRlZCBpbiB0aGVzZSBjYWxjdWxhdGlvbnMsIGJ1dCB3aGljaCB3aWxsIGJlIGluY29ycG9yYXRlZCBpbiBvdGhlciBkb2N1bWVudHMgKHNlZSBbaGVyZV0oaHR0cHM6Ly9ycHVicy5jb20vYXJ0dXJvX21hbGRvbmFkby83Mjg2MjYpKS4KCiMgU3VtbWFyeQoKSW4gdGhpcyBkb2N1bWVudCB3ZSBoYXZlIHNlZW4gdGhlIGJhc2ljIGVsZW1lbnRzIG9mIGRhdGEgbWFuaXB1bGF0aW9uIGFuZCB0cmFuc2Zvcm1hdGlvbiB1c2luZyB0aGUgQW1lcmljYXNCYXJvbWV0ZXIgZGF0YXNldHMuCkEgdmFyaWFibGUgaGFzIGJlZW4gcmVjb2RlZCB1c2luZyB0aGUgYHJlY29kZWAgY29tbWFuZCwgY2FzZXMgaGF2ZSBiZWVuIHNlbGVjdGVkIHVzaW5nIGBzdWJzZXRgIGFuZCBhIG5ldyB2YXJpYWJsZSBoYXMgYmVlbiBjYWxjdWxhdGVkIGFsZ2VicmFpY2FsbHkgYW5kIHdpdGggdGhlIGBpZmVsc2VgIGNvbW1hbmQuCg==