3. Modeling Allele Frequencies Across Generations: Introducing Key
Parameters
The HW principle provides a powerful approach to test whether any
evolutionary forces are impacting a population at any given locus. It
does not tell us, however, what evolutionary forces might be acting on
that particular locus. In the following sections, we will get to know
different evolutionary forces and discover how they impact allele
frequencies across generations.
First, let’s consider how natural selection affects allele
frequencies. Natural selection essentially manifests itself in different
genotypes having a different fitness. Mathematically, we assign a
fitness of 1 to one genotype (e.g., AA), and the fitness of
other genotypes can then be defined relative to AA with the
parameter s (the strength of selection). For example, if the
genotype aa has a 10 % higher fitness than AA
(s=0.1), its fitness would be 1+s = 1.1. If genotype
Aa has a 15 % lower fitness than AA
(s=-0.15), its fitness would be 1+s = 0.85.
It takes just a few key parameters for us to model how selection
affects allele frequencies over time: (1) The strength of selection,
s. (2) The mode of inheritance (dominant/recessive
vs. additive). If an allele at a particular locus is dominant over
another, s for the heterozygote is the same as for the dominant
homozygote. Inheritance, however, may not be dominant/recessive, in
which case you need two values of s to describe how selection
might impact evolution (see textbook
for details).

4. Modeling the Effect of Selection on Allele Frequencies using the
Selection Command
We can model the genotype frequencies in response to selection with
the selection() function. All we need to do is to tell the
function the fitness (w) of the three
genotypes (AA, Aa, aa). If the mode of
inheritance is dominant/recessive, fitness is defined as:
fitness <- c(1, 1, 1+s)
If the mode of inheritance is not dominant/recessive, fitness is
defined as:
fitness <- c(1, 1+s1, 1+s2)
Other parameters that are required are p0 (the starting
allele frequency of p) and time
(the number of generations you want to run the simulation for). We
define these as:
start.freq <- number (between 0 and 1)
gen.time <- number (between 1 and infinity; be
cautious with high numbers, as they can use significant computation
time)
Setting these parameters, we can model the effects of selection with
the selection() function as follows:
result <-selection(w=fitness, time=gen.time, p0=start.freq)
Let’s put this to the test. Let’s model the effect of selection on a
gene with a dominant/recessive mode of inheritance, with the recessive
allele being deleterious (i.e., its fitness is zero). Set the starting
allele frequency at 0.5 and run the simulation for 50 generations.
#Define the fitness of each genotype
fitness <- c(1, 1, 0)
#Define the starting allele frequency p0
start.freq <- 0.5
#Define how many generations you want to simulate
gen.time <- 12
#Model the allele changes and store the results in an object called r
r <- selection(w=fitness, time=gen.time, p0=start.freq)
#By default, the selection() function plots p, but you can also plot q by adding an extra argument
r <- selection(w=fitness, time=gen.time, p0=start.freq, show = "q")
Note that running the selection() function automatically
plots the results of the model. You can also take a look at the numbers
in a table using the following code:
#You can also look at the actual number if you want to
r.table <- data.frame(1:gen.time, r$p)
names(r.table) <- c("Generation", "p")
#Show last part of the table in the results
tail(r.table)
I hope what you can observe is that the frequency of A
(p) increases over time. The speed of change slows as
A gets more common, and it eventually flattens.
4.1. Varying the Strength of Selection
In the coming set of simulations, let’s explore how varying the
strength of selection (s) impacts how allele frequencies change
across generations. We will focus on a single gene with complete
dominance of the A allele. In these first scenarios, the
dominant phenotype has a selective advantage over the recessive one, but
the A allele is starting at a very low frequency in the
population (p0=0.0001). In the first example, the strength
of selection against the recessive homozygotes is s=-0.1. Run the
simulation and record what happens to the allele frequencies of
A and a over 1000 generations.
#Define the fitness of each genotype
fitness1 <- c(?, ?, ?)
#Define the starting allele frequency p0
start.freq1 <- ?
#Define how many generations you want to simulate
gen.time1 <- ?
#Model the allele changes and store the results in an object r1; note that the parameter t just signifies how many generations will be simulated
r1 <- selection(w=fitness1, time=gen.time1, p0=start.freq1)
To truly understand how the strength of selection impacts allele
frequencies, we need to run multiple models with different values of
fitness for our genotypes. Using the same parameters as above, run
multiple models with the selection coefficient against aa
varying between -1 and 0. Rather than visualizing each model separately,
you can actually plot them in together using the add=TRUE
argument.
#Define the fitness of each genotype. Unlike above, you want to vary the strength of selection, so we will define multiple fitness sets (one for each model you want to run)
fitness1 <- c(?)
fitness2 <- c(?)
fitness3 <- c(?)
fitness4 <- c(?)
fitness5 <- c(?)
#Define the starting allele frequency p0. This parameter will will be the same for all models, so you only need to define it once.
start.freq1 <- ?
#Define how many generations you want to simulate. This parameter will will be the same for all models, so you only need to define it once.
gen.time1 <- ?
#Model the allele changes for the different strengths of selection. You need to run one model for each fitness distribution you defined above. Note that you can plot all results in a single graph by adding "add=TRUE" starting at the second model.
r1 <- selection(w=fitness1, time=gen.time1, p0=start.freq1)
r2 <- selection(w=fitness2, time=gen.time1, p0=start.freq1, add=TRUE, color = 'red')
r3 <- selection(w=fitness3, time=gen.time1, p0=start.freq1, add=TRUE, color = 'blue')
r4 <- selection(w=fitness4, time=gen.time1, p0=start.freq1, add=TRUE, color = 'green')
r5 <- selection(w=fitness5, time=gen.time1, p0=start.freq1, add=TRUE, color = 'purple')
Looking at the results of your models, how does varying the strength
of selection affect changes in allele frequencies across
generations?
Your answer goes here.
4.2. Selection on Dominant vs. Recessive phenotypes
Let’s examine what happens when the phenotype with higher fitness is
dominant vs. recessive. First, set the starting frequency of the
A allele to p0=0.01, and give the dominant
phenotype a fitness advantage over the recessive phenotype (s
against the recessive homozygotes is -0.2). Run the simulation for 1000
generations.
#Define the fitness of each genotype
fitness1 <- ?
#Define the starting allele frequency p0
start.freq1 <- ?
#Define how many generations you want to simulate
gen.time1 <- ?
#Model the allele changes and store the results in an object r1; note that the parameter t just signifies how many generations will be simulated
r1 <- selection(w=fitness1, time=gen.time1, p0=start.freq1)
#In this case, it may be useful to look at the actual numbers for p at the end of your simulation
r1.table <- data.frame(1:gen.time1, r1$p)
names(r1.table) <- c("Generation", "p")
tail(r1.table)
Now let’s examine the opposite scenario. Set the starting allele
frequency p0=0.99 but this time give the recessive
phenotype the fitness advantage over the dominant phenotype (same
s as above). Run the simulation for 1000 generations.
#Define the fitness of each genotype
fitness2 <- ?
#Define the starting allele frequency p0
start.freq2 <- ?
#Define how many generations you want to simulate
gen.time2 <- ?
#Model the allele changes and store the results in an object r1; note that the parameter t just signifies how many generations will be simulated
r2 <- selection(w=fitness2, time=gen.time2, p0=start.freq2)
#In this case, it may be useful to look at the actual numbers for p at the end of your simulation
r2.table <- data.frame(1:gen.time2, r2$p)
names(r2.table) <- c("Generation", "p")
tail(r2.table)
Compare and contrast the results of the two simulations? What do you
notice about the pace of change and the final allele frequencies? Why
does the recessive allele persist in a population when selected against,
but the dominant allele does not?
Your answer goes here.
4.3. Selection For Heterozygotes; Symmetrical Fitness between
Homozygotes
So far we have only considered scenarios where fitness was
distributed in a dominant/recessive way. Now we are going to investigate
the consequences of selection for heterozygous individuals (i.e.,
heterozygotes having a fitness advantage over homozygous individuals).
Give the heterozygous genotypes a 1 % fitness advantage over both of the
homozygous genotypes. Run multiple simulations for 1000 generations and
vary the starting allele frequency for values between 0 and 1.
#Define the parameters and set up the models
?
What happens to the allele frequencies in the population? Can you
explain why?
Your answer goes here.
4.4. Selection For Heterozygotes; Asymmetrical Fitness between
Homozygotes
What happens if heterozygous individuals have a fitness advantage,
but selection is stronger against one of the homozygous genotypes? Set
the starting allele frequency to p0=0.1, and give the
aa genotype a fitness of 0.0. Run the simulation with various
fitness values for the AA genotype (between 0 and 1), while
keeping the fitness of the heterozygotes at 1.
#Define the parameters and set up the models
?
How does changing the fitness of AA individuals influence
the final allele frequencies in the population over time? Will the
deleterious allele ever be lost from the population? What are the lowest
and highest frequencies the a allele can reach? Why?
Your answer goes here.
4.5. Selection Against Heterozygotes; Symmetrical Fitness between
Homozygotes
Selection may also act against heterzygotes. How do allele
frequencies change if the two homozygotes have equal fitness, but
heterozgotes have a 50 % reduced fitness? Simulate allele frequency
changes with multiple values of p0 (between 0 and 1).
#Define the parameters and set up the models
?
What happens? Can you explain why?
Your answer goes here.
4.6. Selection Against Heterozygotes; Asymmetrical Fitness between
Homozygotes
Now conduct the same simulation, but the homozygotes have a different
fitness. Again, run the simulation multiple times with different
p0. You can also play with different fitness distributions
to observe additional patterns.
#Define the parameters and set up the models
?
What happens? Can you explain why?
Your answer goes here.
LS0tDQp0aXRsZTogIlNpbXVsYXRpbmcgdGhlIEVmZmVjdHMgb2YgU2VsZWN0aW9uIGFuZCBEcmlmdCINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazoNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDMNCiAgICB0b2NfZmxvYXQ6IHllcw0KLS0tDQoNCiMjIEF1dGhvcjogU2hhZWxhaCBIb2xtZXMgMjQwMDc3NDINCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIDEuIERlcGVuZGVuY2llcw0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFfQ0KI1RoaXMgY29tbWFuZCBsb2FkcyByZXF1aXJlZCBwYWNrYWdlcw0KI05vdGUgdGhhdCB5b3UgbWF5IG5lZWQgdG8gaW5zdGFsbCB0aGUgbGVhcm5Qb3BHZW4gcGFja2FnZSBmaXJzdCENCmxpYnJhcnkobGVhcm5Qb3BHZW4pDQpgYGANCg0KSW1wb3J0YW50IHRpcDogSW4gdGhpcyBhbmQgdGhlIG5leHQgZXhlcmNpc2UsIHdlIHdpbGwgZm9jdXMgZW50aXJlbHkgb24gcnVubmluZyBkaWZmZXJlbnQgZXZvbHV0aW9uYXJ5IG1vZGVscy4gVGhlIHBsb3RzIGZvciB0aGVzZSBtb2RlbHMgYXJlIGdlbmVyYXRlZCBhdXRvbWF0aWNhbGx5LCBhbmQgeW91IGRvIG5vdCBuZWVkIHRvIHVzZSBgZ2dwbG90KClgIHRvIHByb2R1Y2UgdGhlIG91dHB1dHMuDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIDIuIEJlZm9yZSBZb3UgR2V0IFN0YXJ0ZWQuLi4NCg0KSW4gbGVjdHVyZSwgSSBhc2tlZCB5b3UgdG8gcGF1c2UgYW5kIHByZWRpY3Qgd2hhdCBoYXBwZW5zIHRvIHRoZSBhbGxlbGUgZnJlcXVlbmN5IG9mIGEgcmFyZSBhbGxlbGUgKkEqIHRoYXQgcHJvdmlkZXMgYSBmaXRuZXNzIGFkdmFudGFnZSB0byBpdHMgY2FycmllcnMuIFdoYXQgd2FzIHlvdXIgcHJlZGljdGlvbj8NCg0KKllvdXIgYW5zd2VyIGdvZXMgaGVyZSoNCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMgMy4gTW9kZWxpbmcgQWxsZWxlIEZyZXF1ZW5jaWVzIEFjcm9zcyBHZW5lcmF0aW9uczogSW50cm9kdWNpbmcgS2V5IFBhcmFtZXRlcnMNCg0KVGhlIEhXIHByaW5jaXBsZSBwcm92aWRlcyBhIHBvd2VyZnVsIGFwcHJvYWNoIHRvIHRlc3Qgd2hldGhlciBhbnkgZXZvbHV0aW9uYXJ5IGZvcmNlcyBhcmUgaW1wYWN0aW5nIGEgcG9wdWxhdGlvbiBhdCBhbnkgZ2l2ZW4gbG9jdXMuIEl0IGRvZXMgbm90IHRlbGwgdXMsIGhvd2V2ZXIsIHdoYXQgZXZvbHV0aW9uYXJ5IGZvcmNlcyBtaWdodCBiZSBhY3Rpbmcgb24gdGhhdCBwYXJ0aWN1bGFyIGxvY3VzLiBJbiB0aGUgZm9sbG93aW5nIHNlY3Rpb25zLCB3ZSB3aWxsIGdldCB0byBrbm93IGRpZmZlcmVudCBldm9sdXRpb25hcnkgZm9yY2VzIGFuZCBkaXNjb3ZlciBob3cgdGhleSBpbXBhY3QgYWxsZWxlIGZyZXF1ZW5jaWVzIGFjcm9zcyBnZW5lcmF0aW9ucy4NCg0KRmlyc3QsIGxldCdzIGNvbnNpZGVyIGhvdyBuYXR1cmFsIHNlbGVjdGlvbiBhZmZlY3RzIGFsbGVsZSBmcmVxdWVuY2llcy4gTmF0dXJhbCBzZWxlY3Rpb24gZXNzZW50aWFsbHkgbWFuaWZlc3RzIGl0c2VsZiBpbiBkaWZmZXJlbnQgZ2Vub3R5cGVzIGhhdmluZyBhIGRpZmZlcmVudCBmaXRuZXNzLiBNYXRoZW1hdGljYWxseSwgd2UgYXNzaWduIGEgZml0bmVzcyBvZiAxIHRvIG9uZSBnZW5vdHlwZSAoZS5nLiwgKkFBKiksIGFuZCB0aGUgZml0bmVzcyBvZiBvdGhlciBnZW5vdHlwZXMgY2FuIHRoZW4gYmUgZGVmaW5lZCByZWxhdGl2ZSB0byAqQUEqIHdpdGggdGhlIHBhcmFtZXRlciAqcyogKHRoZSBzdHJlbmd0aCBvZiBzZWxlY3Rpb24pLiBGb3IgZXhhbXBsZSwgaWYgdGhlIGdlbm90eXBlICphYSogaGFzIGEgMTAgJSBoaWdoZXIgZml0bmVzcyB0aGFuICpBQSogKCpzKj0wLjEpLCBpdHMgZml0bmVzcyB3b3VsZCBiZSAxKypzKiA9IDEuMS4gSWYgZ2Vub3R5cGUgKkFhKiBoYXMgYSAxNSAlIGxvd2VyIGZpdG5lc3MgdGhhbiAqQUEqICgqcyo9LTAuMTUpLCBpdHMgZml0bmVzcyB3b3VsZCBiZSAxKypzKiA9IDAuODUuDQoNCkl0IHRha2VzIGp1c3QgYSBmZXcga2V5IHBhcmFtZXRlcnMgZm9yIHVzIHRvIG1vZGVsIGhvdyBzZWxlY3Rpb24gYWZmZWN0cyBhbGxlbGUgZnJlcXVlbmNpZXMgb3ZlciB0aW1lOiAoMSkgVGhlIHN0cmVuZ3RoIG9mIHNlbGVjdGlvbiwgKnMqLiAoMikgVGhlIG1vZGUgb2YgaW5oZXJpdGFuY2UgKGRvbWluYW50L3JlY2Vzc2l2ZSB2cy4gYWRkaXRpdmUpLiBJZiBhbiBhbGxlbGUgYXQgYSBwYXJ0aWN1bGFyIGxvY3VzIGlzIGRvbWluYW50IG92ZXIgYW5vdGhlciwgKnMqIGZvciB0aGUgaGV0ZXJvenlnb3RlIGlzIHRoZSBzYW1lIGFzIGZvciB0aGUgZG9taW5hbnQgaG9tb3p5Z290ZS4gSW5oZXJpdGFuY2UsIGhvd2V2ZXIsIG1heSBub3QgYmUgZG9taW5hbnQvcmVjZXNzaXZlLCBpbiB3aGljaCBjYXNlIHlvdSBuZWVkIHR3byB2YWx1ZXMgb2YgKnMqIHRvIGRlc2NyaWJlIGhvdyBzZWxlY3Rpb24gbWlnaHQgaW1wYWN0IGV2b2x1dGlvbiAoc2VlIFt0ZXh0Ym9va10oaHR0cHM6Ly93d3cuay1zdGF0ZS5lZHUvYmlvbG9neS9wMmUvZXZvbHV0aW9uYXJ5LW1lY2hhbmlzbXMtaS1tb2RlbGluZy1zZWxlY3Rpb24uaHRtbCNyZWxhdGl2ZS1maXRuZXNzKSBmb3IgZGV0YWlscykuDQoNCiFbXShkb21pbmFudF9hZGRpdGl2ZS5wbmcpDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIDQuIE1vZGVsaW5nIHRoZSBFZmZlY3Qgb2YgU2VsZWN0aW9uIG9uIEFsbGVsZSBGcmVxdWVuY2llcyB1c2luZyB0aGUgU2VsZWN0aW9uIENvbW1hbmQNCg0KV2UgY2FuIG1vZGVsIHRoZSBnZW5vdHlwZSBmcmVxdWVuY2llcyBpbiByZXNwb25zZSB0byBzZWxlY3Rpb24gd2l0aCB0aGUgYHNlbGVjdGlvbigpYCBmdW5jdGlvbi4gQWxsIHdlIG5lZWQgdG8gZG8gaXMgdG8gdGVsbCB0aGUgZnVuY3Rpb24gdGhlICoqZioqaXRuZXNzICgqdyopIG9mIHRoZSB0aHJlZSBnZW5vdHlwZXMgKCpBQSosICpBYSosICphYSopLiBJZiB0aGUgbW9kZSBvZiBpbmhlcml0YW5jZSBpcyBkb21pbmFudC9yZWNlc3NpdmUsIGZpdG5lc3MgaXMgZGVmaW5lZCBhczoNCg0KYGZpdG5lc3MgPC0gYygxLCAxLCAxK3MpYA0KDQpJZiB0aGUgbW9kZSBvZiBpbmhlcml0YW5jZSBpcyBub3QgZG9taW5hbnQvcmVjZXNzaXZlLCBmaXRuZXNzIGlzIGRlZmluZWQgYXM6DQoNCmBmaXRuZXNzIDwtIGMoMSwgMStzMSwgMStzMilgDQoNCk90aGVyIHBhcmFtZXRlcnMgdGhhdCBhcmUgcmVxdWlyZWQgYXJlIGBwMGAgKHRoZSBzdGFydGluZyBhbGxlbGUgZnJlcXVlbmN5IG9mICpwKikgYW5kICoqYHRpbWVgKiogKHRoZSBudW1iZXIgb2YgZ2VuZXJhdGlvbnMgeW91IHdhbnQgdG8gcnVuIHRoZSBzaW11bGF0aW9uIGZvcikuIFdlIGRlZmluZSB0aGVzZSBhczoNCg0KYHN0YXJ0LmZyZXEgPC1gIG51bWJlciAoYmV0d2VlbiAwIGFuZCAxKQ0KDQpgZ2VuLnRpbWUgPC1gIG51bWJlciAoYmV0d2VlbiAxIGFuZCBpbmZpbml0eTsgYmUgY2F1dGlvdXMgd2l0aCBoaWdoIG51bWJlcnMsIGFzIHRoZXkgY2FuIHVzZSBzaWduaWZpY2FudCBjb21wdXRhdGlvbiB0aW1lKQ0KDQpTZXR0aW5nIHRoZXNlIHBhcmFtZXRlcnMsIHdlIGNhbiBtb2RlbCB0aGUgZWZmZWN0cyBvZiBzZWxlY3Rpb24gd2l0aCB0aGUgYHNlbGVjdGlvbigpYCBmdW5jdGlvbiBhcyBmb2xsb3dzOg0KDQpgcmVzdWx0IDwtc2VsZWN0aW9uKHc9Zml0bmVzcywgdGltZT1nZW4udGltZSwgcDA9c3RhcnQuZnJlcSlgDQoNCkxldCdzIHB1dCB0aGlzIHRvIHRoZSB0ZXN0LiBMZXQncyBtb2RlbCB0aGUgZWZmZWN0IG9mIHNlbGVjdGlvbiBvbiBhIGdlbmUgd2l0aCBhIGRvbWluYW50L3JlY2Vzc2l2ZSBtb2RlIG9mIGluaGVyaXRhbmNlLCB3aXRoIHRoZSByZWNlc3NpdmUgYWxsZWxlIGJlaW5nIGRlbGV0ZXJpb3VzIChpLmUuLCBpdHMgZml0bmVzcyBpcyB6ZXJvKS4gU2V0IHRoZSBzdGFydGluZyBhbGxlbGUgZnJlcXVlbmN5IGF0IDAuNSBhbmQgcnVuIHRoZSBzaW11bGF0aW9uIGZvciA1MCBnZW5lcmF0aW9ucy4NCg0KYGBge3J9DQojRGVmaW5lIHRoZSBmaXRuZXNzIG9mIGVhY2ggZ2Vub3R5cGUNCmZpdG5lc3MgPC0gYygxLCAxLCAwKQ0KDQojRGVmaW5lIHRoZSBzdGFydGluZyBhbGxlbGUgZnJlcXVlbmN5IHAwDQpzdGFydC5mcmVxIDwtIDAuNQ0KDQojRGVmaW5lIGhvdyBtYW55IGdlbmVyYXRpb25zIHlvdSB3YW50IHRvIHNpbXVsYXRlDQpnZW4udGltZSA8LSAxMg0KDQojTW9kZWwgdGhlIGFsbGVsZSBjaGFuZ2VzIGFuZCBzdG9yZSB0aGUgcmVzdWx0cyBpbiBhbiBvYmplY3QgY2FsbGVkIHINCnIgPC0gc2VsZWN0aW9uKHc9Zml0bmVzcywgdGltZT1nZW4udGltZSwgcDA9c3RhcnQuZnJlcSkNCg0KI0J5IGRlZmF1bHQsIHRoZSBzZWxlY3Rpb24oKSBmdW5jdGlvbiBwbG90cyBwLCBidXQgeW91IGNhbiBhbHNvIHBsb3QgcSBieSBhZGRpbmcgYW4gZXh0cmEgYXJndW1lbnQNCnIgPC0gc2VsZWN0aW9uKHc9Zml0bmVzcywgdGltZT1nZW4udGltZSwgcDA9c3RhcnQuZnJlcSwgc2hvdyA9ICJxIikNCmBgYA0KDQpOb3RlIHRoYXQgcnVubmluZyB0aGUgYHNlbGVjdGlvbigpYCBmdW5jdGlvbiBhdXRvbWF0aWNhbGx5IHBsb3RzIHRoZSByZXN1bHRzIG9mIHRoZSBtb2RlbC4gWW91IGNhbiBhbHNvIHRha2UgYSBsb29rIGF0IHRoZSBudW1iZXJzIGluIGEgdGFibGUgdXNpbmcgdGhlIGZvbGxvd2luZyBjb2RlOg0KDQpgYGB7cn0NCiNZb3UgY2FuIGFsc28gbG9vayBhdCB0aGUgYWN0dWFsIG51bWJlciBpZiB5b3Ugd2FudCB0bw0Kci50YWJsZSA8LSBkYXRhLmZyYW1lKDE6Z2VuLnRpbWUsIHIkcCkNCm5hbWVzKHIudGFibGUpIDwtIGMoIkdlbmVyYXRpb24iLCAicCIpDQoNCiNTaG93IGxhc3QgcGFydCBvZiB0aGUgdGFibGUgaW4gdGhlIHJlc3VsdHMNCnRhaWwoci50YWJsZSkNCmBgYA0KDQpJIGhvcGUgd2hhdCB5b3UgY2FuIG9ic2VydmUgaXMgdGhhdCB0aGUgZnJlcXVlbmN5IG9mICpBKiAoKnAqKSBpbmNyZWFzZXMgb3ZlciB0aW1lLiBUaGUgc3BlZWQgb2YgY2hhbmdlIHNsb3dzIGFzICpBKiBnZXRzIG1vcmUgY29tbW9uLCBhbmQgaXQgZXZlbnR1YWxseSBmbGF0dGVucy4NCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMjIDQuMS4gVmFyeWluZyB0aGUgU3RyZW5ndGggb2YgU2VsZWN0aW9uDQoNCkluIHRoZSBjb21pbmcgc2V0IG9mIHNpbXVsYXRpb25zLCBsZXQncyBleHBsb3JlIGhvdyB2YXJ5aW5nIHRoZSBzdHJlbmd0aCBvZiBzZWxlY3Rpb24gKCpzKikgaW1wYWN0cyBob3cgYWxsZWxlIGZyZXF1ZW5jaWVzIGNoYW5nZSBhY3Jvc3MgZ2VuZXJhdGlvbnMuIFdlIHdpbGwgZm9jdXMgb24gYSBzaW5nbGUgZ2VuZSB3aXRoIGNvbXBsZXRlIGRvbWluYW5jZSBvZiB0aGUgKkEqIGFsbGVsZS4gSW4gdGhlc2UgZmlyc3Qgc2NlbmFyaW9zLCB0aGUgZG9taW5hbnQgcGhlbm90eXBlIGhhcyBhIHNlbGVjdGl2ZSBhZHZhbnRhZ2Ugb3ZlciB0aGUgcmVjZXNzaXZlIG9uZSwgYnV0IHRoZSAqQSogYWxsZWxlIGlzIHN0YXJ0aW5nIGF0IGEgdmVyeSBsb3cgZnJlcXVlbmN5IGluIHRoZSBwb3B1bGF0aW9uIChgcDA9MC4wMDAxYCkuIEluIHRoZSBmaXJzdCBleGFtcGxlLCB0aGUgc3RyZW5ndGggb2Ygc2VsZWN0aW9uIGFnYWluc3QgdGhlIHJlY2Vzc2l2ZSBob21venlnb3RlcyBpcyBzPS0wLjEuIFJ1biB0aGUgc2ltdWxhdGlvbiBhbmQgcmVjb3JkIHdoYXQgaGFwcGVucyB0byB0aGUgYWxsZWxlIGZyZXF1ZW5jaWVzIG9mICpBKiBhbmQgYSBvdmVyIDEwMDAgZ2VuZXJhdGlvbnMuDQoNCmBgYHtyfQ0KI0RlZmluZSB0aGUgZml0bmVzcyBvZiBlYWNoIGdlbm90eXBlDQpmaXRuZXNzMSA8LSBjKD8sID8sID8pDQoNCiNEZWZpbmUgdGhlIHN0YXJ0aW5nIGFsbGVsZSBmcmVxdWVuY3kgcDANCnN0YXJ0LmZyZXExIDwtID8NCg0KI0RlZmluZSBob3cgbWFueSBnZW5lcmF0aW9ucyB5b3Ugd2FudCB0byBzaW11bGF0ZQ0KZ2VuLnRpbWUxIDwtID8NCg0KI01vZGVsIHRoZSBhbGxlbGUgY2hhbmdlcyBhbmQgc3RvcmUgdGhlIHJlc3VsdHMgaW4gYW4gb2JqZWN0IHIxOyBub3RlIHRoYXQgdGhlIHBhcmFtZXRlciB0IGp1c3Qgc2lnbmlmaWVzIGhvdyBtYW55IGdlbmVyYXRpb25zIHdpbGwgYmUgc2ltdWxhdGVkDQpyMSA8LSBzZWxlY3Rpb24odz1maXRuZXNzMSwgdGltZT1nZW4udGltZTEsIHAwPXN0YXJ0LmZyZXExKQ0KYGBgDQoNClRvIHRydWx5IHVuZGVyc3RhbmQgaG93IHRoZSBzdHJlbmd0aCBvZiBzZWxlY3Rpb24gaW1wYWN0cyBhbGxlbGUgZnJlcXVlbmNpZXMsIHdlIG5lZWQgdG8gcnVuIG11bHRpcGxlIG1vZGVscyB3aXRoIGRpZmZlcmVudCB2YWx1ZXMgb2YgZml0bmVzcyBmb3Igb3VyIGdlbm90eXBlcy4gVXNpbmcgdGhlIHNhbWUgcGFyYW1ldGVycyBhcyBhYm92ZSwgcnVuIG11bHRpcGxlIG1vZGVscyB3aXRoIHRoZSBzZWxlY3Rpb24gY29lZmZpY2llbnQgYWdhaW5zdCAqYWEqIHZhcnlpbmcgYmV0d2VlbiAtMSBhbmQgMC4gUmF0aGVyIHRoYW4gdmlzdWFsaXppbmcgZWFjaCBtb2RlbCBzZXBhcmF0ZWx5LCB5b3UgY2FuIGFjdHVhbGx5IHBsb3QgdGhlbSBpbiB0b2dldGhlciB1c2luZyB0aGUgYGFkZD1UUlVFYCBhcmd1bWVudC4NCg0KYGBge3J9DQojRGVmaW5lIHRoZSBmaXRuZXNzIG9mIGVhY2ggZ2Vub3R5cGUuIFVubGlrZSBhYm92ZSwgeW91IHdhbnQgdG8gdmFyeSB0aGUgc3RyZW5ndGggb2Ygc2VsZWN0aW9uLCBzbyB3ZSB3aWxsIGRlZmluZSBtdWx0aXBsZSBmaXRuZXNzIHNldHMgKG9uZSBmb3IgZWFjaCBtb2RlbCB5b3Ugd2FudCB0byBydW4pDQpmaXRuZXNzMSA8LSBjKD8pDQpmaXRuZXNzMiA8LSBjKD8pDQpmaXRuZXNzMyA8LSBjKD8pDQpmaXRuZXNzNCA8LSBjKD8pDQpmaXRuZXNzNSA8LSBjKD8pDQoNCiNEZWZpbmUgdGhlIHN0YXJ0aW5nIGFsbGVsZSBmcmVxdWVuY3kgcDAuIFRoaXMgcGFyYW1ldGVyIHdpbGwgd2lsbCBiZSB0aGUgc2FtZSBmb3IgYWxsIG1vZGVscywgc28geW91IG9ubHkgbmVlZCB0byBkZWZpbmUgaXQgb25jZS4NCnN0YXJ0LmZyZXExIDwtID8NCg0KI0RlZmluZSBob3cgbWFueSBnZW5lcmF0aW9ucyB5b3Ugd2FudCB0byBzaW11bGF0ZS4gVGhpcyBwYXJhbWV0ZXIgd2lsbCB3aWxsIGJlIHRoZSBzYW1lIGZvciBhbGwgbW9kZWxzLCBzbyB5b3Ugb25seSBuZWVkIHRvIGRlZmluZSBpdCBvbmNlLg0KZ2VuLnRpbWUxIDwtID8NCg0KI01vZGVsIHRoZSBhbGxlbGUgY2hhbmdlcyBmb3IgdGhlIGRpZmZlcmVudCBzdHJlbmd0aHMgb2Ygc2VsZWN0aW9uLiBZb3UgbmVlZCB0byBydW4gb25lIG1vZGVsIGZvciBlYWNoIGZpdG5lc3MgZGlzdHJpYnV0aW9uIHlvdSBkZWZpbmVkIGFib3ZlLiBOb3RlIHRoYXQgeW91IGNhbiBwbG90IGFsbCByZXN1bHRzIGluIGEgc2luZ2xlIGdyYXBoIGJ5IGFkZGluZyAiYWRkPVRSVUUiIHN0YXJ0aW5nIGF0IHRoZSBzZWNvbmQgbW9kZWwuIA0KcjEgPC0gc2VsZWN0aW9uKHc9Zml0bmVzczEsIHRpbWU9Z2VuLnRpbWUxLCBwMD1zdGFydC5mcmVxMSkNCnIyIDwtIHNlbGVjdGlvbih3PWZpdG5lc3MyLCB0aW1lPWdlbi50aW1lMSwgcDA9c3RhcnQuZnJlcTEsIGFkZD1UUlVFLCBjb2xvciA9ICdyZWQnKQ0KcjMgPC0gc2VsZWN0aW9uKHc9Zml0bmVzczMsIHRpbWU9Z2VuLnRpbWUxLCBwMD1zdGFydC5mcmVxMSwgYWRkPVRSVUUsIGNvbG9yID0gJ2JsdWUnKQ0KcjQgPC0gc2VsZWN0aW9uKHc9Zml0bmVzczQsIHRpbWU9Z2VuLnRpbWUxLCBwMD1zdGFydC5mcmVxMSwgYWRkPVRSVUUsIGNvbG9yID0gJ2dyZWVuJykNCnI1IDwtIHNlbGVjdGlvbih3PWZpdG5lc3M1LCB0aW1lPWdlbi50aW1lMSwgcDA9c3RhcnQuZnJlcTEsIGFkZD1UUlVFLCBjb2xvciA9ICdwdXJwbGUnKQ0KYGBgDQoNCkxvb2tpbmcgYXQgdGhlIHJlc3VsdHMgb2YgeW91ciBtb2RlbHMsIGhvdyBkb2VzIHZhcnlpbmcgdGhlIHN0cmVuZ3RoIG9mIHNlbGVjdGlvbiBhZmZlY3QgY2hhbmdlcyBpbiBhbGxlbGUgZnJlcXVlbmNpZXMgYWNyb3NzIGdlbmVyYXRpb25zPw0KDQoqWW91ciBhbnN3ZXIgZ29lcyBoZXJlLioNCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMjIDQuMi4gU2VsZWN0aW9uIG9uIERvbWluYW50IHZzLiBSZWNlc3NpdmUgcGhlbm90eXBlcw0KDQpMZXQncyBleGFtaW5lIHdoYXQgaGFwcGVucyB3aGVuIHRoZSBwaGVub3R5cGUgd2l0aCBoaWdoZXIgZml0bmVzcyBpcyBkb21pbmFudCB2cy4gcmVjZXNzaXZlLiBGaXJzdCwgc2V0IHRoZSBzdGFydGluZyBmcmVxdWVuY3kgb2YgdGhlICpBKiBhbGxlbGUgdG8gYHAwPTAuMDFgLCBhbmQgZ2l2ZSB0aGUgZG9taW5hbnQgcGhlbm90eXBlIGEgZml0bmVzcyBhZHZhbnRhZ2Ugb3ZlciB0aGUgcmVjZXNzaXZlIHBoZW5vdHlwZSAoKnMqIGFnYWluc3QgdGhlIHJlY2Vzc2l2ZSBob21venlnb3RlcyBpcyAtMC4yKS4gUnVuIHRoZSBzaW11bGF0aW9uIGZvciAxMDAwIGdlbmVyYXRpb25zLg0KDQpgYGB7cn0NCiNEZWZpbmUgdGhlIGZpdG5lc3Mgb2YgZWFjaCBnZW5vdHlwZQ0KZml0bmVzczEgPC0gPw0KDQojRGVmaW5lIHRoZSBzdGFydGluZyBhbGxlbGUgZnJlcXVlbmN5IHAwDQpzdGFydC5mcmVxMSA8LSA/DQoNCiNEZWZpbmUgaG93IG1hbnkgZ2VuZXJhdGlvbnMgeW91IHdhbnQgdG8gc2ltdWxhdGUNCmdlbi50aW1lMSA8LSA/DQoNCiNNb2RlbCB0aGUgYWxsZWxlIGNoYW5nZXMgYW5kIHN0b3JlIHRoZSByZXN1bHRzIGluIGFuIG9iamVjdCByMTsgbm90ZSB0aGF0IHRoZSBwYXJhbWV0ZXIgdCBqdXN0IHNpZ25pZmllcyBob3cgbWFueSBnZW5lcmF0aW9ucyB3aWxsIGJlIHNpbXVsYXRlZA0KcjEgPC0gc2VsZWN0aW9uKHc9Zml0bmVzczEsIHRpbWU9Z2VuLnRpbWUxLCBwMD1zdGFydC5mcmVxMSkNCg0KI0luIHRoaXMgY2FzZSwgaXQgbWF5IGJlIHVzZWZ1bCB0byBsb29rIGF0IHRoZSBhY3R1YWwgbnVtYmVycyBmb3IgcCBhdCB0aGUgZW5kIG9mIHlvdXIgc2ltdWxhdGlvbg0KcjEudGFibGUgPC0gZGF0YS5mcmFtZSgxOmdlbi50aW1lMSwgcjEkcCkNCm5hbWVzKHIxLnRhYmxlKSA8LSBjKCJHZW5lcmF0aW9uIiwgInAiKQ0KdGFpbChyMS50YWJsZSkNCmBgYA0KDQpOb3cgbGV0J3MgZXhhbWluZSB0aGUgb3Bwb3NpdGUgc2NlbmFyaW8uIFNldCB0aGUgc3RhcnRpbmcgYWxsZWxlIGZyZXF1ZW5jeSBgcDA9MC45OWAgYnV0IHRoaXMgdGltZSBnaXZlIHRoZSByZWNlc3NpdmUgcGhlbm90eXBlIHRoZSBmaXRuZXNzIGFkdmFudGFnZSBvdmVyIHRoZSBkb21pbmFudCBwaGVub3R5cGUgKHNhbWUgYHNgIGFzIGFib3ZlKS4gUnVuIHRoZSBzaW11bGF0aW9uIGZvciAxMDAwIGdlbmVyYXRpb25zLg0KDQpgYGB7cn0NCiNEZWZpbmUgdGhlIGZpdG5lc3Mgb2YgZWFjaCBnZW5vdHlwZQ0KZml0bmVzczIgPC0gPw0KDQojRGVmaW5lIHRoZSBzdGFydGluZyBhbGxlbGUgZnJlcXVlbmN5IHAwDQpzdGFydC5mcmVxMiA8LSA/DQoNCiNEZWZpbmUgaG93IG1hbnkgZ2VuZXJhdGlvbnMgeW91IHdhbnQgdG8gc2ltdWxhdGUNCmdlbi50aW1lMiA8LSA/DQoNCiNNb2RlbCB0aGUgYWxsZWxlIGNoYW5nZXMgYW5kIHN0b3JlIHRoZSByZXN1bHRzIGluIGFuIG9iamVjdCByMTsgbm90ZSB0aGF0IHRoZSBwYXJhbWV0ZXIgdCBqdXN0IHNpZ25pZmllcyBob3cgbWFueSBnZW5lcmF0aW9ucyB3aWxsIGJlIHNpbXVsYXRlZA0KcjIgPC0gc2VsZWN0aW9uKHc9Zml0bmVzczIsIHRpbWU9Z2VuLnRpbWUyLCBwMD1zdGFydC5mcmVxMikNCg0KI0luIHRoaXMgY2FzZSwgaXQgbWF5IGJlIHVzZWZ1bCB0byBsb29rIGF0IHRoZSBhY3R1YWwgbnVtYmVycyBmb3IgcCBhdCB0aGUgZW5kIG9mIHlvdXIgc2ltdWxhdGlvbg0KcjIudGFibGUgPC0gZGF0YS5mcmFtZSgxOmdlbi50aW1lMiwgcjIkcCkNCm5hbWVzKHIyLnRhYmxlKSA8LSBjKCJHZW5lcmF0aW9uIiwgInAiKQ0KdGFpbChyMi50YWJsZSkNCmBgYA0KDQpDb21wYXJlIGFuZCBjb250cmFzdCB0aGUgcmVzdWx0cyBvZiB0aGUgdHdvIHNpbXVsYXRpb25zPyBXaGF0IGRvIHlvdSBub3RpY2UgYWJvdXQgdGhlIHBhY2Ugb2YgY2hhbmdlIGFuZCB0aGUgZmluYWwgYWxsZWxlIGZyZXF1ZW5jaWVzPyBXaHkgZG9lcyB0aGUgcmVjZXNzaXZlIGFsbGVsZSBwZXJzaXN0IGluIGEgcG9wdWxhdGlvbiB3aGVuIHNlbGVjdGVkIGFnYWluc3QsIGJ1dCB0aGUgZG9taW5hbnQgYWxsZWxlIGRvZXMgbm90Pw0KDQoqWW91ciBhbnN3ZXIgZ29lcyBoZXJlLioNCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMjIDQuMy4gU2VsZWN0aW9uIEZvciBIZXRlcm96eWdvdGVzOyBTeW1tZXRyaWNhbCBGaXRuZXNzIGJldHdlZW4gSG9tb3p5Z290ZXMNCg0KU28gZmFyIHdlIGhhdmUgb25seSBjb25zaWRlcmVkIHNjZW5hcmlvcyB3aGVyZSBmaXRuZXNzIHdhcyBkaXN0cmlidXRlZCBpbiBhIGRvbWluYW50L3JlY2Vzc2l2ZSB3YXkuIE5vdyB3ZSBhcmUgZ29pbmcgdG8gaW52ZXN0aWdhdGUgdGhlIGNvbnNlcXVlbmNlcyBvZiBzZWxlY3Rpb24gZm9yIGhldGVyb3p5Z291cyBpbmRpdmlkdWFscyAoaS5lLiwgaGV0ZXJvenlnb3RlcyBoYXZpbmcgYSBmaXRuZXNzIGFkdmFudGFnZSBvdmVyIGhvbW96eWdvdXMgaW5kaXZpZHVhbHMpLiBHaXZlIHRoZSBoZXRlcm96eWdvdXMgZ2Vub3R5cGVzIGEgMSAlIGZpdG5lc3MgYWR2YW50YWdlIG92ZXIgYm90aCBvZiB0aGUgaG9tb3p5Z291cyBnZW5vdHlwZXMuIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBmb3IgMTAwMCBnZW5lcmF0aW9ucyBhbmQgdmFyeSB0aGUgc3RhcnRpbmcgYWxsZWxlIGZyZXF1ZW5jeSBmb3IgdmFsdWVzIGJldHdlZW4gMCBhbmQgMS4NCg0KYGBge3J9DQojRGVmaW5lIHRoZSBwYXJhbWV0ZXJzIGFuZCBzZXQgdXAgdGhlIG1vZGVscw0KDQo/DQpgYGANCg0KV2hhdCBoYXBwZW5zIHRvIHRoZSBhbGxlbGUgZnJlcXVlbmNpZXMgaW4gdGhlIHBvcHVsYXRpb24/IENhbiB5b3UgZXhwbGFpbiB3aHk/DQoNCipZb3VyIGFuc3dlciBnb2VzIGhlcmUuKg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyMgNC40LiBTZWxlY3Rpb24gRm9yIEhldGVyb3p5Z290ZXM7IEFzeW1tZXRyaWNhbCBGaXRuZXNzIGJldHdlZW4gSG9tb3p5Z290ZXMNCg0KV2hhdCBoYXBwZW5zIGlmIGhldGVyb3p5Z291cyBpbmRpdmlkdWFscyBoYXZlIGEgZml0bmVzcyBhZHZhbnRhZ2UsIGJ1dCBzZWxlY3Rpb24gaXMgc3Ryb25nZXIgYWdhaW5zdCBvbmUgb2YgdGhlIGhvbW96eWdvdXMgZ2Vub3R5cGVzPyBTZXQgdGhlIHN0YXJ0aW5nIGFsbGVsZSBmcmVxdWVuY3kgdG8gYHAwPTAuMWAsIGFuZCBnaXZlIHRoZSAqYWEqIGdlbm90eXBlIGEgZml0bmVzcyBvZiAwLjAuIFJ1biB0aGUgc2ltdWxhdGlvbiB3aXRoIHZhcmlvdXMgZml0bmVzcyB2YWx1ZXMgZm9yIHRoZSAqQUEqIGdlbm90eXBlIChiZXR3ZWVuIDAgYW5kIDEpLCB3aGlsZSBrZWVwaW5nIHRoZSBmaXRuZXNzIG9mIHRoZSBoZXRlcm96eWdvdGVzIGF0IDEuDQoNCmBgYHtyfQ0KI0RlZmluZSB0aGUgcGFyYW1ldGVycyBhbmQgc2V0IHVwIHRoZSBtb2RlbHMNCg0KPw0KYGBgDQoNCkhvdyBkb2VzIGNoYW5naW5nIHRoZSBmaXRuZXNzIG9mICpBQSogaW5kaXZpZHVhbHMgaW5mbHVlbmNlIHRoZSBmaW5hbCBhbGxlbGUgZnJlcXVlbmNpZXMgaW4gdGhlIHBvcHVsYXRpb24gb3ZlciB0aW1lPyBXaWxsIHRoZSBkZWxldGVyaW91cyBhbGxlbGUgZXZlciBiZSBsb3N0IGZyb20gdGhlIHBvcHVsYXRpb24/IFdoYXQgYXJlIHRoZSBsb3dlc3QgYW5kIGhpZ2hlc3QgZnJlcXVlbmNpZXMgdGhlIGEgYWxsZWxlIGNhbiByZWFjaD8gV2h5Pw0KDQoqWW91ciBhbnN3ZXIgZ29lcyBoZXJlLioNCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMjIDQuNS4gU2VsZWN0aW9uIEFnYWluc3QgSGV0ZXJvenlnb3RlczsgU3ltbWV0cmljYWwgRml0bmVzcyBiZXR3ZWVuIEhvbW96eWdvdGVzDQoNClNlbGVjdGlvbiBtYXkgYWxzbyBhY3QgYWdhaW5zdCBoZXRlcnp5Z290ZXMuIEhvdyBkbyBhbGxlbGUgZnJlcXVlbmNpZXMgY2hhbmdlIGlmIHRoZSB0d28gaG9tb3p5Z290ZXMgaGF2ZSBlcXVhbCBmaXRuZXNzLCBidXQgaGV0ZXJvemdvdGVzIGhhdmUgYSA1MCAlIHJlZHVjZWQgZml0bmVzcz8gU2ltdWxhdGUgYWxsZWxlIGZyZXF1ZW5jeSBjaGFuZ2VzIHdpdGggbXVsdGlwbGUgdmFsdWVzIG9mIGBwMGAgKGJldHdlZW4gMCBhbmQgMSkuDQoNCmBgYHtyfQ0KI0RlZmluZSB0aGUgcGFyYW1ldGVycyBhbmQgc2V0IHVwIHRoZSBtb2RlbHMNCg0KPw0KYGBgDQoNCldoYXQgaGFwcGVucz8gQ2FuIHlvdSBleHBsYWluIHdoeT8NCg0KKllvdXIgYW5zd2VyIGdvZXMgaGVyZS4qDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyA0LjYuIFNlbGVjdGlvbiBBZ2FpbnN0IEhldGVyb3p5Z290ZXM7IEFzeW1tZXRyaWNhbCBGaXRuZXNzIGJldHdlZW4gSG9tb3p5Z290ZXMNCg0KTm93IGNvbmR1Y3QgdGhlIHNhbWUgc2ltdWxhdGlvbiwgYnV0IHRoZSBob21venlnb3RlcyBoYXZlIGEgZGlmZmVyZW50IGZpdG5lc3MuIEFnYWluLCBydW4gdGhlIHNpbXVsYXRpb24gbXVsdGlwbGUgdGltZXMgd2l0aCBkaWZmZXJlbnQgYHAwYC4gWW91IGNhbiBhbHNvIHBsYXkgd2l0aCBkaWZmZXJlbnQgZml0bmVzcyBkaXN0cmlidXRpb25zIHRvIG9ic2VydmUgYWRkaXRpb25hbCBwYXR0ZXJucy4NCg0KYGBge3J9DQojRGVmaW5lIHRoZSBwYXJhbWV0ZXJzIGFuZCBzZXQgdXAgdGhlIG1vZGVscw0KDQo/DQpgYGANCg0KV2hhdCBoYXBwZW5zPyBDYW4geW91IGV4cGxhaW4gd2h5Pw0KDQoqWW91ciBhbnN3ZXIgZ29lcyBoZXJlLioNCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMgNS4gQ2hhbmdpbmcgU2VsZWN0aW9uOiBOZWdhdGl2ZSBGcmVxdWVuY3ktRGVwZW5kZW50IFNlbGVjdGlvbg0KDQpPbmUgYmlnIGFzc3VtcHRpb24gd2UgbWFkZSBpbiB0aGUgc2ltdWxhdGlvbnMgYWJvdmUgaXMgdGhhdCB0aGUgZml0bmVzcyBvZiBnZW5vdHlwZXMgZG9lcyBub3QgY2hhbmdlIGFjcm9zcyBnZW5lcmF0aW9ucy4gT2YgY291cnNlLCB0aGUgc2VsZWN0aW9uIGNvZWZmaWNpZW50ICpzKiBpcyBub3QgYWx3YXlzIGNvbnN0YW50IGFuZCBtYXkgdmFyeSBmb3IgYSBsYXJnZSBudW1iZXIgb2YgcmVhc29ucywgaW5jbHVkaW5nIGNoYW5naW5nIGVudmlyb25tZW50YWwgY29uZGl0aW9ucy4gQSBjYXNlIG9mIGNoYW5naW5nIHNlbGVjdGlvbiB3aXRob3V0IGVudmlyb25tZW50YWwgZmx1Y3R1YXRpb24gaXMgY2FsbGVkIFtuZWdhdGl2ZSBmcmVxdWVuY3ktZGVwZW5kZW50IHNlbGVjdGlvbl0oaHR0cHM6Ly93d3cuay1zdGF0ZS5lZHUvYmlvbG9neS9wMmUvZXZvbHV0aW9uYXJ5LW1lY2hhbmlzbXMtaS1tb2RlbGluZy1zZWxlY3Rpb24uaHRtbCNmcmVxdWVuY3ktZGVwZW5kZW50LXNlbGVjdGlvbiksIHdoZXJlIHRoZSBmaXRuZXNzIG9mIGEgZ2Vub3R5cGUgaXMgZGVwZW5kZW50IG9uIGl0cyBmcmVxdWVuY3ksIGFuZCBjb21tb24gZ2Vub3R5cGVzIGhhdmUgYSBsb3dlciBmaXRuZXNzLiBZb3UgY2FuIHNpbXVsYXRlIG5lZ2F0aXZlIGZyZXF1ZW5jeS1kZXBlbmRlbnQgc2VsZWN0aW9uIHVzaW5nIHRoZSBgZnJlcWRlcCgpYCBmdW5jdGlvbi4gQXMgYmVmb3JlLCB5b3Ugd2lsbCBuZWVkIHRvIHNwZWNpZnkgdGhlIHN0YXJ0aW5nIGFsbGVsZSBmcmVxdWVuY3kgKGBwMGApLCBgc2AgKHdoaWNoIGRldGVybWluZXMgdGhlIHN0cmVuZ3RoIG9mIHNlbGVjdGlvbiBhZ2FpbnN0IGhldGVyb3p5Z290ZXMgd2hlbiB0aGV5IGFyZSBjb21tb24pLCBhbmQgdGhlIG51bWJlciBvZiBnZW5lcmF0aW9ucyB5b3Ugd2FudCB0byBydW4gdGhlIHNpbXVsYXRpb24gZm9yLiBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgdmFyeWluZyBgcDBgIGFuZCBgc2AgKEkgcmVjb21tZW5kIHN0YXJ0aW5nIHdpdGggKnMqPTEpLg0KDQpgYGB7cn0NCnIxIDwtZnJlcWRlcChwMD0wLjYsIHM9MSwgdGltZT0xMDApDQo/DQpgYGANCg0KV2hhdCBkbyB5b3Ugb2JzZXJ2ZT8gV2h5IGRvZXMgbmVpdGhlciBvZiB0aGUgYWxsZWxlcyBnbyB0byBmaXhhdGlvbj8gQ2FuIHlvdSB0aGluayBvZiBhbiBleGFtcGxlIG9mIG5lZ2F0aXZlIGZyZXF1ZW5jeS1kZXBlbmRlbnQgc2VsZWN0aW9uIGluIG5hdHVyZT8NCg0KKllvdXIgYW5zd2VyIGdvZXMgaGVyZS4qDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIDYuIFJlZmxlY3Rpb24NCg0KSWYgeW91IHRoaW5rIGJhY2sgdG8geW91ciBpbml0aWFsIHByZWRpY3Rpb24sIHdoYXQgaGF2ZSB5b3UgbGVhcm5lZCBmcm9tIHJ1bm5pbmcgYWxsIG9mIHRoZXNlIG1vZGVscz8gV2hhdCBhcmUgc29tZSBtaXNjb25jZXB0aW9ucyBhYm91dCBzZWxlY3Rpb24gdGhhdCB5b3Ugd2VyZSBhYmxlIHRvIGNsYXJpZnkgd2l0aCB0aGVzZSBzaW11bGF0aW9ucz8NCg0KKllvdXIgYW5zd2VyIGdvZXMgaGVyZS4qDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIDcuIFJlc291cmNlcw0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyMgNy4xLiBEYXRhIFJlZmVyZW5jZXMNCg0KVGhpcyBleGVyY2lzZSBkb2VzIG5vdCBjb250YWluIG9yaWdpbmFsIGRhdGEsIGJ1dCBrdWRvcyB0byBbTGlhbSBKLiBSZXZlbGxdKGh0dHBzOi8vZmFjdWx0eS51bWIuZWR1L2xpYW0ucmV2ZWxsLykgd2hvIGRldmVsb3BlZCB0aGUgbGVhcm5Qb3BHZW4gcGFja2FnZS4NCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMjIDcuMi4gUmVzb3VyY2VzIFlvdSBDb25zdWx0ZWQNCg0KQ29uc3VsdGluZyBhZGRpdGlvbmFsIHJlc291cmNlcyB0byBzb2x2ZSB0aGlzIGFzc2lnbm1lbnQgaXMgYWJzb2x1dGVseSBhbGxvd2VkLCBidXQgZmFpbHVyZSB0byBkaXNjbG9zZSB0aG9zZSByZXNvdXJjZXMgaXMgcGxhZ2lhcmlzbS4gUGxlYXNlIGxpc3QgYW55IGNvbGxhYm9yYXRvcnMgeW91IHdvcmtlZCB3aXRoIGFuZCByZXNvdXJjZXMgeW91IHVzZWQgYmVsb3cgb3Igc3RhdGUgdGhhdCB5b3UgaGF2ZSBub3QgdXNlZCBhbnkuDQoNCipZb3VyIGFuc3dlciBnb2VzIGhlcmUuKg0K