# 1 Logicals

## 1.1 What do Logicals do?

Logicals are a set of operations that act on raw, logical, and number-like vectors. They ususaly test if the relationship between two vectors is TRUE or FALSE. They can be used for both simple calculations and comparisons and for more complex tasks such as setting up conditions for loops, looking and prescreening data before running tests, etc.

== - tests equality of the two elements

3 == 3 #This will return TRUE
## [1] TRUE
2 == 3 #This will return FALSE
## [1] FALSE

!= - tests ineequality of the two elements

3 != 4 #This will return TRUE
## [1] TRUE
1 != 1 #This will return FALSE
## [1] FALSE

<, >, <=, >= - compare the values

3 < 2 #This will return FALSE
## [1] FALSE
3 > 2 #This will return TRUE
## [1] TRUE
5 <= 4 #This will return FALSE
## [1] FALSE
5 >= 5 #This will return TRUE
## [1] TRUE

### 1.1.1 ! - negation

Reverses the Boolian value. So if your value was TRUE, negation will turn it into FALSE. Putting “!” in fron of the expression, as in the example below, will negate the expression.

(3 < 2) #This alone will return FALSE
## [1] FALSE
!(3 < 2) #But after negation this statement is true
## [1] TRUE

### 1.1.2 AND

Tests if both conditions are true. For simple tests, can use singular & and double &&, both mean AND. & - Returns a vector of logical values for each item in vector z if both conditions are satisfied. && - Tests if all elements in vector satisfy both conditions and returns a single logical value. Thus, for equality testing, either one works fine. For inequality testing, application of & or && depends on your goal.

x <- 1; y <- 2 #Setting up the values
(x == 1) & (y == 2) #This will return TRUE
## [1] TRUE
(x == 1) && (y == 3) #This will return FALSE
## [1] FALSE

Beware using & and && in more complex expressions for the meanings will vary. Test on simple functions first, as in the examples below.

z <- 1:6 #Setting up the vector
z[(z>2) & (z<5)] #Returns elements that satisfy both conditions
## [1] 3 4
(z > 2) & (z < 5) #Returns a vector of logical values for each item in vector z if both conditions are satisfied
## [1] FALSE FALSE  TRUE  TRUE FALSE FALSE
(z > -2) && (z < 50) #Tests if all elements in vector satisfy both conditions and returns a single logical value
## [1] TRUE

#### 1.1.2.1 Example:

We have a vector a that has values 1 - 100. We want to find out what numbers are divisible by 7 and 13.

a <- 1:100 #Setting up the vector
(a %% 7 == 0) && (a %% 13 == 0) #Tests if all elements in vector satisfy both conditions and returns a single logical value. FALSE is returned because not all numbers in the vector are divisible by 7 and 13.
## [1] FALSE
(a %% 7 == 0) & (a %% 13 == 0) #Returns a vector of logical values for each item in vector a if both conditions are satisfied. We can see that there is one TRUE in the sea of FALSE.
##   [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [12] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [23] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [34] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [45] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [56] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [67] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [78] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [89] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [100] FALSE
a[(a %% 7 == 0) & (a %% 13 == 0)] #Returns elements that satisfy both conditions. In this example, it is 91.
## [1] 91

### 1.1.3 OR

Tests if any of the conditions is true. For simple tests, can use singular | and double ||, both mean OR. | - Returns a vector of logical values for each item in vector z if any condition is satisfied. || - Tests if any element in vector satisfy any conditions and returns a single logical value. Thus, for equality testing, either one works fine. For inequality testing, application of | or || depends on your goal.

x <- 1; y <- 2 #Setting up the values
(x == 1) | (y == 2) #This will return TRUE
## [1] TRUE
(x == 1) || (y == 3) #This will return TRUE
## [1] TRUE

Beware using | and || in more complex expressions for the meanings will vary. Test on simple functions first, as in the examples below.

z <- 1:6 #Setting up the vector
z[(z>2) | (z<5)] #Returns elements that satisfy any condition
## [1] 1 2 3 4 5 6
(z > 2) | (z < 5) #Returns a vector of logical values for each item in vector z if any condition is satisfied
## [1] TRUE TRUE TRUE TRUE TRUE TRUE
(z > 2) || (z < 5) #Tests if any element in vector satisfy any conditions and returns a single logical value
## [1] TRUE

#### 1.1.3.1 Example:

We have a vector a that has values 1 - 100. We want to find out what numbers are divisible by 7 or by 13.

a <- 1:100 #Setting up the vector
(a %% 7 == 0) || (a %% 13 == 0) #Tests if any elements in vector satisfy any of the two conditions and returns a single logical value. FALSE is returned because not all numbers in the vector are divisible by either 7 or 13.
## [1] FALSE
(a %% 7 == 0) | (a %% 13 == 0) #Returns a vector of logical values for each item in vector a if at least one condition is satisfied. We can see that there are a couple of TRUE in the sea of FALSE.
##   [1] FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE
##  [12] FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
##  [23] FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE
##  [34] FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE
##  [45] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE
##  [56]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE
##  [67] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE
##  [78]  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE
##  [89] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
## [100] FALSE
a[(a %% 7 == 0) | (a %% 13 == 0)] #Returns elements that satisfy any of the two conditions. In this example, these numbres are 7, 13, 14, 21, 26, 28, 35, 39, 42, 49, 52, 56, 63, 65, 70, 77, 78, 84, 91, 98.
##  [1]  7 13 14 21 26 28 35 39 42 49 52 56 63 65 70 77 78 84 91 98

### 1.1.4 ifelse

Similarly to Excel function if, ifelse tests an argument, and if that argument is true, ifelse will return the 1st specified value, if argument is false it will return the 2nd specified value. Has three inputs: 1 - expression to test, 2 - what to return if true, 3 - what to return if false

ifelse(1 == 0,1,0) #Returns 0 for 1 is not equal to 0
## [1] 0

Note that ifelse can be nested in itself multiple times, like in Excel

ifelse(1 == 0,1, ifelse(1 == 2,2,0)) #Returns 0
## [1] 0

First, the outer ifelse clause is evalueted. 1 == 0 is FALSE, thus R executes the false portion of the outer ifelse that has another nested ifelse clause. 1 == 2 is alse FALSE, thus 0 is returned because it is specified as a result if the expression is false.

### 1.1.5 if … else …

Expanded version of if clause that can be used in more complex ways. If can be used alone or with else.

if(1 < 2) print ('Hello') #Prints 'Hello'
## [1] "Hello"
if(1 > 2) print ('Hello') else print('Bye') #Print 'Bye'
## [1] "Bye"

If the condition inside is false and there is no else, R will do nothing because nothing is specified for this case.

if(1 > 2) print ('Hello') #Runs and does nothing

# 2 Loops and Tools

Loops iterate over a block of code multiple times based on some criteria. There are three loop functions: * Repeat * While * For Tools help shape loops to reach the end goal. There are two tools: * Break * Next

Note: Some loops can be tough on computer RAM, so bevare crushing R or even your computer. Note: Beware of creating an infinite loop, a loop that does not have any exit condition so it will run forever. You will need to press stop button which will lead to you not getting a result.

## 2.1 Repeat

Repeat - used to iterate over a block of code multiple times. There is no check in repeat loop to exit. Must put a condition explitictly into the loop and use break to exit the loop (break and next will be covered later). If no condition is applied, you will create an infinite loop.

i <- 0 #Setting up the counter i
repeat{
print(i) #Code that tells the program what to do
#Next two lines are set up as condition check to exit the loop
i <- i + 1 #Increasing the counter
if( i == 30) break #setting up the condition when to break the loop
}
## [1] 0
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10
## [1] 11
## [1] 12
## [1] 13
## [1] 14
## [1] 15
## [1] 16
## [1] 17
## [1] 18
## [1] 19
## [1] 20
## [1] 21
## [1] 22
## [1] 23
## [1] 24
## [1] 25
## [1] 26
## [1] 27
## [1] 28
## [1] 29

The code results in numbers from 0 to 29 because given the way the code is written, when 29 is reached it is printed, then increased by 1, and then tested in the if clause where i == 30 is true and the loop is stopped. The order in which you write the loop statements matters!

Note that break can be put into curvy parentheses of if statement, but it is not neccessary.

## 2.2 While

While - used to iterate over a block of code multiple times as long as specified condition is met.

#Setting up the starting value
x=0

#The loop
while (x < 42) { #This specifies that the loop will run as long as the condition is met. Once condition is not met (x>42) the loop will stop
x<-1+x #Increasing the counter
print(x) #Code that tells the program what to do
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10
## [1] 11
## [1] 12
## [1] 13
## [1] 14
## [1] 15
## [1] 16
## [1] 17
## [1] 18
## [1] 19
## [1] 20
## [1] 21
## [1] 22
## [1] 23
## [1] 24
## [1] 25
## [1] 26
## [1] 27
## [1] 28
## [1] 29
## [1] 30
## [1] 31
## [1] 32
## [1] 33
## [1] 34
## [1] 35
## [1] 36
## [1] 37
## [1] 38
## [1] 39
## [1] 40
## [1] 41
## [1] 42

The code returns numbers 1 - 42. When 41 is reached, the x is increased by 1 and 42 is displayed. Now x = 42 that makes statement x < 42 false and the loop is stopped. The while loop does not need a break clause to stop because this feature is built in, but it is important to include incremental code so that the loop does not turn into an infinite loop.

## 2.3 For

For - used to iterate over a vector. The statement of the program is repeated for as many times as there are units in the vector.

z <- c(2, 4, 6, 8)
for (i in z) { # The condition inside tells the loop how many times to run it
print(i^2) # Code that tells the program what to do
}
## [1] 4
## [1] 16
## [1] 36
## [1] 64

The code returns 4 numbers, the squared elements of the vector z, because there are only 4 items in z.

Another common use of the for loop is to run some code for the length of the vector.

z <- c(2, 4, 6, 8) #Setting up the vector
for (i in 1:length(z)) { # The condition inside tells the loop how many times to run it
print(z[i]^2) # Code that tells the program what to do
}
## [1] 4
## [1] 16
## [1] 36
## [1] 64

The for loop changes the value of i from 1 to the lenght of the vector z by 1 and does an operation on i-th element of z, in this example it squares it. Thus the result is same as for the previous code, but has a slightly different approach. This gives us the ability to create a calculation that will not have a challenge having a vector of any length as an input. Other common uses of for loop is using 1:seq (1:seq(1, 100)) and 1:range.

## 2.4 Break

A break statement is used inside a loop to stop the iterations and flow the control outside the loop.

x <- 1:5 #Create a vector
for (val in x) { #Set up the loop so that variable "val" takes each value in x in order
#The val is used in the next two lines in the loop statement
if (val == 3) {break} #Compare the val to 3, exit the loop if val equals 3
print(val) #If val is not 3, print the item associated with val in this round of the loop
}
## [1] 1
## [1] 2

R returns values 1 and 2 only for when 3 is reached, the if statement stops the loop and 3, 4, and 5 do not show up.

In case of nested loops, the breaks exits the loop that is being evaluated.

#Set up two different vactors to demonstrate the effect of the nested loops
x <- 1:5
y <- 10:50

for (val in x) { #Setting up the first loop that will repeat the second loop and print the value of val for every item in x
for (val2 in y) { #Setting up the second loop to repeat two statements
if (val2 == 15) {break} # 1. Test if val2 equal 15, exit the loop if yes
print(val2)             # 2. Print the value of val2
}
print(val) #When the nested loop is exited, val from x for which the nested loop was ran is printed
}
## [1] 10
## [1] 11
## [1] 12
## [1] 13
## [1] 14
## [1] 1
## [1] 10
## [1] 11
## [1] 12
## [1] 13
## [1] 14
## [1] 2
## [1] 10
## [1] 11
## [1] 12
## [1] 13
## [1] 14
## [1] 3
## [1] 10
## [1] 11
## [1] 12
## [1] 13
## [1] 14
## [1] 4
## [1] 10
## [1] 11
## [1] 12
## [1] 13
## [1] 14
## [1] 5

The break is used in the nested loop so the result is all values of x and only the values of y below 15. Note the repeated pattern, the nested loop is repeated for each value of the outside loop.

LS0tDQp0aXRsZTogJ0NoYXB0ZXIgMzogTG9naWNhbHMgYW5kIExvb3BzJw0KYXV0aG9yOiAiSWhvciBLb2h1dCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0aGVtZTogY2VydWxlYW4NCiAgICBoaWdobGlnaHQ6IHRleHRtYXRlDQogICAgZm9udHNpemU6IDhwdA0KICAgIHRvYzogdHJ1ZQ0KICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICB0b2NfZmxvYXQ6DQogICAgICBjb2xsYXBzZWQ6IGZhbHNlDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpgYGANCg0KDQojIExvZ2ljYWxzDQojIyBXaGF0IGRvIExvZ2ljYWxzIGRvPw0KTG9naWNhbHMgYXJlIGEgc2V0IG9mIG9wZXJhdGlvbnMgdGhhdCBhY3Qgb24gcmF3LCBsb2dpY2FsLCBhbmQgbnVtYmVyLWxpa2UgdmVjdG9ycy4gVGhleSB1c3VzYWx5IHRlc3QgaWYgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHR3byB2ZWN0b3JzIGlzIFRSVUUgb3IgRkFMU0UuDQpUaGV5IGNhbiBiZSB1c2VkIGZvciBib3RoIHNpbXBsZSBjYWxjdWxhdGlvbnMgYW5kIGNvbXBhcmlzb25zIGFuZCBmb3IgbW9yZSBjb21wbGV4IHRhc2tzIHN1Y2ggYXMgc2V0dGluZyB1cCBjb25kaXRpb25zIGZvciBsb29wcywgbG9va2luZyBhbmQgcHJlc2NyZWVuaW5nIGRhdGEgYmVmb3JlIHJ1bm5pbmcgdGVzdHMsIGV0Yy4NCg0KID09IC0gdGVzdHMgZXF1YWxpdHkgb2YgdGhlIHR3byBlbGVtZW50cw0KYGBgIHtyLCBtZXNzYWdlPUZBTFNFLCBlY2hvPVRSVUV9DQozID09IDMgI1RoaXMgd2lsbCByZXR1cm4gVFJVRQ0KMiA9PSAzICNUaGlzIHdpbGwgcmV0dXJuIEZBTFNFDQpgYGANCg0KICE9IC0gdGVzdHMgaW5lZXF1YWxpdHkgb2YgdGhlIHR3byBlbGVtZW50cw0KYGBgIHtyLCBtZXNzYWdlPUZBTFNFLCBlY2hvPVRSVUV9DQozICE9IDQgI1RoaXMgd2lsbCByZXR1cm4gVFJVRQ0KMSAhPSAxICNUaGlzIHdpbGwgcmV0dXJuIEZBTFNFDQpgYGANCg0KIDwsID4sIDw9LCA+PSAtIGNvbXBhcmUgdGhlIHZhbHVlcw0KYGBgIHtyLCBtZXNzYWdlPUZBTFNFLCBlY2hvPVRSVUV9DQozIDwgMiAjVGhpcyB3aWxsIHJldHVybiBGQUxTRQ0KMyA+IDIgI1RoaXMgd2lsbCByZXR1cm4gVFJVRQ0KNSA8PSA0ICNUaGlzIHdpbGwgcmV0dXJuIEZBTFNFDQo1ID49IDUgI1RoaXMgd2lsbCByZXR1cm4gVFJVRQ0KYGBgDQoNCg0KIyMjICEgLSBuZWdhdGlvbg0KUmV2ZXJzZXMgdGhlIEJvb2xpYW4gdmFsdWUuIFNvIGlmIHlvdXIgdmFsdWUgd2FzIFRSVUUsIG5lZ2F0aW9uIHdpbGwgdHVybiBpdCBpbnRvIEZBTFNFLg0KUHV0dGluZyAiISIgaW4gZnJvbiBvZiB0aGUgZXhwcmVzc2lvbiwgYXMgaW4gdGhlIGV4YW1wbGUgYmVsb3csIHdpbGwgbmVnYXRlIHRoZSBleHByZXNzaW9uLg0KYGBgIHtyLCBtZXNzYWdlPUZBTFNFLCBlY2hvPVRSVUV9DQooMyA8IDIpICNUaGlzIGFsb25lIHdpbGwgcmV0dXJuIEZBTFNFDQohKDMgPCAyKSAjQnV0IGFmdGVyIG5lZ2F0aW9uIHRoaXMgc3RhdGVtZW50IGlzIHRydWUNCmBgYCANCg0KDQojIyMgQU5EDQpUZXN0cyBpZiBib3RoIGNvbmRpdGlvbnMgYXJlIHRydWUuIEZvciBzaW1wbGUgdGVzdHMsIGNhbiB1c2Ugc2luZ3VsYXIgJiBhbmQgZG91YmxlICYmLCBib3RoIG1lYW4gKipBTkQqKi4NCiYgIC0gUmV0dXJucyBhIHZlY3RvciBvZiBsb2dpY2FsIHZhbHVlcyBmb3IgZWFjaCBpdGVtIGluIHZlY3RvciB6IGlmIGJvdGggY29uZGl0aW9ucyBhcmUgc2F0aXNmaWVkLg0KJiYgLSBUZXN0cyBpZiBhbGwgZWxlbWVudHMgaW4gdmVjdG9yIHNhdGlzZnkgYm90aCBjb25kaXRpb25zIGFuZCByZXR1cm5zIGEgc2luZ2xlIGxvZ2ljYWwgdmFsdWUuDQpUaHVzLCBmb3IgZXF1YWxpdHkgdGVzdGluZywgZWl0aGVyIG9uZSB3b3JrcyBmaW5lLiBGb3IgaW5lcXVhbGl0eSB0ZXN0aW5nLCBhcHBsaWNhdGlvbiBvZiAmIG9yICYmIGRlcGVuZHMgb24geW91ciBnb2FsLg0KYGBgIHtyLCBtZXNzYWdlPUZBTFNFLCBlY2hvPVRSVUV9DQp4IDwtIDE7IHkgPC0gMiAjU2V0dGluZyB1cCB0aGUgdmFsdWVzDQooeCA9PSAxKSAmICh5ID09IDIpICNUaGlzIHdpbGwgcmV0dXJuIFRSVUUNCih4ID09IDEpICYmICh5ID09IDMpICNUaGlzIHdpbGwgcmV0dXJuIEZBTFNFDQpgYGANCg0KQmV3YXJlIHVzaW5nICYgYW5kICYmIGluIG1vcmUgY29tcGxleCBleHByZXNzaW9ucyBmb3IgdGhlIG1lYW5pbmdzIHdpbGwgdmFyeS4NClRlc3Qgb24gc2ltcGxlIGZ1bmN0aW9ucyBmaXJzdCwgYXMgaW4gdGhlIGV4YW1wbGVzIGJlbG93Lg0KYGBgIHtyLCBtZXNzYWdlPUZBTFNFLCBlY2hvPVRSVUV9DQp6IDwtIDE6NiAjU2V0dGluZyB1cCB0aGUgdmVjdG9yDQp6Wyh6PjIpICYgKHo8NSldICNSZXR1cm5zIGVsZW1lbnRzIHRoYXQgc2F0aXNmeSBib3RoIGNvbmRpdGlvbnMNCih6ID4gMikgJiAoeiA8IDUpICNSZXR1cm5zIGEgdmVjdG9yIG9mIGxvZ2ljYWwgdmFsdWVzIGZvciBlYWNoIGl0ZW0gaW4gdmVjdG9yIHogaWYgYm90aCBjb25kaXRpb25zIGFyZSBzYXRpc2ZpZWQNCih6ID4gLTIpICYmICh6IDwgNTApICNUZXN0cyBpZiBhbGwgZWxlbWVudHMgaW4gdmVjdG9yIHNhdGlzZnkgYm90aCBjb25kaXRpb25zIGFuZCByZXR1cm5zIGEgc2luZ2xlIGxvZ2ljYWwgdmFsdWUNCmBgYA0KDQojIyMjIEV4YW1wbGU6DQogV2UgaGF2ZSBhIHZlY3RvciBhIHRoYXQgaGFzIHZhbHVlcyAxIC0gMTAwLiBXZSB3YW50IHRvIGZpbmQgb3V0IHdoYXQgbnVtYmVycyBhcmUgZGl2aXNpYmxlIGJ5IDcgYW5kIDEzLg0KIA0KYGBgIHtyLCBtZXNzYWdlPUZBTFNFLCBlY2hvPVRSVUV9DQphIDwtIDE6MTAwICNTZXR0aW5nIHVwIHRoZSB2ZWN0b3INCihhICUlIDcgPT0gMCkgJiYgKGEgJSUgMTMgPT0gMCkgI1Rlc3RzIGlmIGFsbCBlbGVtZW50cyBpbiB2ZWN0b3Igc2F0aXNmeSBib3RoIGNvbmRpdGlvbnMgYW5kIHJldHVybnMgYSBzaW5nbGUgbG9naWNhbCB2YWx1ZS4gRkFMU0UgaXMgcmV0dXJuZWQgYmVjYXVzZSBub3QgYWxsIG51bWJlcnMgaW4gdGhlIHZlY3RvciBhcmUgZGl2aXNpYmxlIGJ5IDcgYW5kIDEzLg0KDQooYSAlJSA3ID09IDApICYgKGEgJSUgMTMgPT0gMCkgI1JldHVybnMgYSB2ZWN0b3Igb2YgbG9naWNhbCB2YWx1ZXMgZm9yIGVhY2ggaXRlbSBpbiB2ZWN0b3IgYSBpZiBib3RoIGNvbmRpdGlvbnMgYXJlIHNhdGlzZmllZC4gV2UgY2FuIHNlZSB0aGF0IHRoZXJlIGlzIG9uZSBUUlVFIGluIHRoZSBzZWEgb2YgRkFMU0UuDQoNCmFbKGEgJSUgNyA9PSAwKSAmIChhICUlIDEzID09IDApXSAjUmV0dXJucyBlbGVtZW50cyB0aGF0IHNhdGlzZnkgYm90aCBjb25kaXRpb25zLiBJbiB0aGlzIGV4YW1wbGUsIGl0IGlzIDkxLg0KYGBgDQoNCg0KIyMjIE9SDQpUZXN0cyBpZiBhbnkgb2YgdGhlIGNvbmRpdGlvbnMgaXMgdHJ1ZS4gRm9yIHNpbXBsZSB0ZXN0cywgY2FuIHVzZSBzaW5ndWxhciB8IGFuZCBkb3VibGUgfHwsIGJvdGggbWVhbiAqKk9SKiouDQp8ICAtIFJldHVybnMgYSB2ZWN0b3Igb2YgbG9naWNhbCB2YWx1ZXMgZm9yIGVhY2ggaXRlbSBpbiB2ZWN0b3IgeiBpZiBhbnkgY29uZGl0aW9uIGlzIHNhdGlzZmllZC4NCnx8IC0gVGVzdHMgaWYgYW55IGVsZW1lbnQgaW4gdmVjdG9yIHNhdGlzZnkgYW55IGNvbmRpdGlvbnMgYW5kIHJldHVybnMgYSBzaW5nbGUgbG9naWNhbCB2YWx1ZS4NClRodXMsIGZvciBlcXVhbGl0eSB0ZXN0aW5nLCBlaXRoZXIgb25lIHdvcmtzIGZpbmUuIEZvciBpbmVxdWFsaXR5IHRlc3RpbmcsIGFwcGxpY2F0aW9uIG9mIHwgb3IgfHwgZGVwZW5kcyBvbiB5b3VyIGdvYWwuDQpgYGAge3IsIG1lc3NhZ2U9RkFMU0UsIGVjaG89VFJVRX0NCnggPC0gMTsgeSA8LSAyICNTZXR0aW5nIHVwIHRoZSB2YWx1ZXMNCih4ID09IDEpIHwgKHkgPT0gMikgI1RoaXMgd2lsbCByZXR1cm4gVFJVRQ0KKHggPT0gMSkgfHwgKHkgPT0gMykgI1RoaXMgd2lsbCByZXR1cm4gVFJVRQ0KYGBgDQoNCkJld2FyZSB1c2luZyB8IGFuZCB8fCBpbiBtb3JlIGNvbXBsZXggZXhwcmVzc2lvbnMgZm9yIHRoZSBtZWFuaW5ncyB3aWxsIHZhcnkuDQpUZXN0IG9uIHNpbXBsZSBmdW5jdGlvbnMgZmlyc3QsIGFzIGluIHRoZSBleGFtcGxlcyBiZWxvdy4NCmBgYCB7ciwgbWVzc2FnZT1GQUxTRSwgZWNobz1UUlVFfQ0KeiA8LSAxOjYgI1NldHRpbmcgdXAgdGhlIHZlY3Rvcg0Kelsoej4yKSB8ICh6PDUpXSAjUmV0dXJucyBlbGVtZW50cyB0aGF0IHNhdGlzZnkgYW55IGNvbmRpdGlvbg0KKHogPiAyKSB8ICh6IDwgNSkgI1JldHVybnMgYSB2ZWN0b3Igb2YgbG9naWNhbCB2YWx1ZXMgZm9yIGVhY2ggaXRlbSBpbiB2ZWN0b3IgeiBpZiBhbnkgY29uZGl0aW9uIGlzIHNhdGlzZmllZA0KKHogPiAyKSB8fCAoeiA8IDUpICNUZXN0cyBpZiBhbnkgZWxlbWVudCBpbiB2ZWN0b3Igc2F0aXNmeSBhbnkgY29uZGl0aW9ucyBhbmQgcmV0dXJucyBhIHNpbmdsZSBsb2dpY2FsIHZhbHVlDQpgYGANCg0KIyMjIyBFeGFtcGxlOg0KIFdlIGhhdmUgYSB2ZWN0b3IgYSB0aGF0IGhhcyB2YWx1ZXMgMSAtIDEwMC4gV2Ugd2FudCB0byBmaW5kIG91dCB3aGF0IG51bWJlcnMgYXJlIGRpdmlzaWJsZSBieSA3IG9yIGJ5IDEzLg0KIA0KYGBgIHtyLCBtZXNzYWdlPUZBTFNFLCBlY2hvPVRSVUV9DQphIDwtIDE6MTAwICNTZXR0aW5nIHVwIHRoZSB2ZWN0b3INCihhICUlIDcgPT0gMCkgfHwgKGEgJSUgMTMgPT0gMCkgI1Rlc3RzIGlmIGFueSBlbGVtZW50cyBpbiB2ZWN0b3Igc2F0aXNmeSBhbnkgb2YgdGhlIHR3byBjb25kaXRpb25zIGFuZCByZXR1cm5zIGEgc2luZ2xlIGxvZ2ljYWwgdmFsdWUuIEZBTFNFIGlzIHJldHVybmVkIGJlY2F1c2Ugbm90IGFsbCBudW1iZXJzIGluIHRoZSB2ZWN0b3IgYXJlIGRpdmlzaWJsZSBieSBlaXRoZXIgNyBvciAxMy4NCg0KKGEgJSUgNyA9PSAwKSB8IChhICUlIDEzID09IDApICNSZXR1cm5zIGEgdmVjdG9yIG9mIGxvZ2ljYWwgdmFsdWVzIGZvciBlYWNoIGl0ZW0gaW4gdmVjdG9yIGEgaWYgYXQgbGVhc3Qgb25lIGNvbmRpdGlvbiBpcyBzYXRpc2ZpZWQuIFdlIGNhbiBzZWUgdGhhdCB0aGVyZSBhcmUgYSBjb3VwbGUgb2YgVFJVRSBpbiB0aGUgc2VhIG9mIEZBTFNFLg0KDQphWyhhICUlIDcgPT0gMCkgfCAoYSAlJSAxMyA9PSAwKV0gI1JldHVybnMgZWxlbWVudHMgdGhhdCBzYXRpc2Z5IGFueSBvZiB0aGUgdHdvIGNvbmRpdGlvbnMuIEluIHRoaXMgZXhhbXBsZSwgdGhlc2UgbnVtYnJlcyBhcmUgNywgMTMsIDE0LCAyMSwgMjYsIDI4LCAzNSwgMzksIDQyLCA0OSwgNTIsIDU2LCA2MywgNjUsIDcwLCA3NywgNzgsIDg0LCA5MSwgOTguDQpgYGANCg0KDQojIyMgaWZlbHNlDQpTaW1pbGFybHkgdG8gRXhjZWwgZnVuY3Rpb24gaWYsIGlmZWxzZSB0ZXN0cyBhbiBhcmd1bWVudCwgYW5kIGlmIHRoYXQgYXJndW1lbnQgaXMgdHJ1ZSwgaWZlbHNlIHdpbGwgcmV0dXJuIHRoZSAxc3Qgc3BlY2lmaWVkIHZhbHVlLCBpZiBhcmd1bWVudCBpcyBmYWxzZSBpdCB3aWxsIHJldHVybiB0aGUgMm5kIHNwZWNpZmllZCB2YWx1ZS4NCkhhcyB0aHJlZSBpbnB1dHM6DQoxIC0gZXhwcmVzc2lvbiB0byB0ZXN0LCAyIC0gd2hhdCB0byByZXR1cm4gaWYgdHJ1ZSwgMyAtIHdoYXQgdG8gcmV0dXJuIGlmIGZhbHNlDQoNCmBgYCB7ciwgbWVzc2FnZT1GQUxTRSwgZWNobz1UUlVFfQ0KaWZlbHNlKDEgPT0gMCwxLDApICNSZXR1cm5zIDAgZm9yIDEgaXMgbm90IGVxdWFsIHRvIDANCmBgYCANCg0KTm90ZSB0aGF0IGlmZWxzZSBjYW4gYmUgbmVzdGVkIGluIGl0c2VsZiBtdWx0aXBsZSB0aW1lcywgbGlrZSBpbiBFeGNlbA0KDQpgYGAge3IsIG1lc3NhZ2U9RkFMU0UsIGVjaG89VFJVRX0NCmlmZWxzZSgxID09IDAsMSwgaWZlbHNlKDEgPT0gMiwyLDApKSAjUmV0dXJucyAwDQpgYGANCg0KRmlyc3QsIHRoZSBvdXRlciBpZmVsc2UgY2xhdXNlIGlzIGV2YWx1ZXRlZC4gMSA9PSAwIGlzIEZBTFNFLCB0aHVzIFIgZXhlY3V0ZXMgdGhlIGZhbHNlIHBvcnRpb24gb2YgdGhlIG91dGVyIGlmZWxzZSB0aGF0IGhhcyBhbm90aGVyIG5lc3RlZCBpZmVsc2UgY2xhdXNlLiAxID09IDIgaXMgYWxzZSBGQUxTRSwgdGh1cyAwIGlzIHJldHVybmVkIGJlY2F1c2UgaXQgaXMgc3BlY2lmaWVkIGFzIGEgcmVzdWx0IGlmIHRoZSBleHByZXNzaW9uIGlzIGZhbHNlLg0KDQoNCiMjIyBpZiAuLi4gZWxzZSAuLi4gDQpFeHBhbmRlZCB2ZXJzaW9uIG9mIGlmIGNsYXVzZSB0aGF0IGNhbiBiZSB1c2VkIGluIG1vcmUgY29tcGxleCB3YXlzLiBJZiBjYW4gYmUgdXNlZCBhbG9uZSBvciB3aXRoIGVsc2UuDQoNCmBgYCB7ciwgbWVzc2FnZT1GQUxTRSwgZWNobz1UUlVFfQ0KaWYoMSA8IDIpIHByaW50ICgnSGVsbG8nKSAjUHJpbnRzICdIZWxsbycNCmlmKDEgPiAyKSBwcmludCAoJ0hlbGxvJykgZWxzZSBwcmludCgnQnllJykgI1ByaW50ICdCeWUnDQpgYGANCg0KSWYgdGhlIGNvbmRpdGlvbiBpbnNpZGUgaXMgZmFsc2UgYW5kIHRoZXJlIGlzIG5vIGVsc2UsIFIgd2lsbCBkbyBub3RoaW5nIGJlY2F1c2Ugbm90aGluZyBpcyBzcGVjaWZpZWQgZm9yIHRoaXMgY2FzZS4NCg0KYGBgIHtyLCBtZXNzYWdlPUZBTFNFLCBlY2hvPVRSVUV9DQppZigxID4gMikgcHJpbnQgKCdIZWxsbycpICNSdW5zIGFuZCBkb2VzIG5vdGhpbmcNCmBgYA0KDQojIExvb3BzIGFuZCBUb29scw0KTG9vcHMgaXRlcmF0ZSBvdmVyIGEgYmxvY2sgb2YgY29kZSBtdWx0aXBsZSB0aW1lcyBiYXNlZCBvbiBzb21lIGNyaXRlcmlhLiBUaGVyZSBhcmUgdGhyZWUgbG9vcCBmdW5jdGlvbnM6DQogKiBSZXBlYXQNCiAqIFdoaWxlDQogKiBGb3INClRvb2xzIGhlbHAgc2hhcGUgbG9vcHMgdG8gcmVhY2ggdGhlIGVuZCBnb2FsLiBUaGVyZSBhcmUgdHdvIHRvb2xzOg0KICogQnJlYWsNCiAqIE5leHQNCg0KTm90ZTogU29tZSBsb29wcyBjYW4gYmUgdG91Z2ggb24gY29tcHV0ZXIgUkFNLCBzbyBiZXZhcmUgY3J1c2hpbmcgUiBvciBldmVuIHlvdXIgY29tcHV0ZXIuDQpOb3RlOiBCZXdhcmUgb2YgY3JlYXRpbmcgYW4gaW5maW5pdGUgbG9vcCwgYSBsb29wIHRoYXQgZG9lcyBub3QgaGF2ZSBhbnkgZXhpdCBjb25kaXRpb24gc28gaXQgd2lsbCBydW4gZm9yZXZlci4gWW91IHdpbGwgbmVlZCB0byBwcmVzcyBzdG9wIGJ1dHRvbiB3aGljaCB3aWxsIGxlYWQgdG8geW91IG5vdCBnZXR0aW5nIGEgcmVzdWx0Lg0KDQoNCiMjIFJlcGVhdA0KDQpSZXBlYXQgLSB1c2VkIHRvIGl0ZXJhdGUgb3ZlciBhIGJsb2NrIG9mIGNvZGUgbXVsdGlwbGUgdGltZXMuIFRoZXJlIGlzIG5vIGNoZWNrIGluIHJlcGVhdCBsb29wIHRvIGV4aXQuDQpNdXN0IHB1dCBhIGNvbmRpdGlvbiBleHBsaXRpY3RseSBpbnRvIHRoZSBsb29wIGFuZCB1c2UgYnJlYWsgdG8gZXhpdCB0aGUgbG9vcCAoYnJlYWsgYW5kIG5leHQgd2lsbCBiZSBjb3ZlcmVkIGxhdGVyKS4gSWYgbm8gY29uZGl0aW9uIGlzIGFwcGxpZWQsIHlvdSB3aWxsIGNyZWF0ZSBhbiBpbmZpbml0ZSBsb29wLg0KDQpgYGAge3IsIG1lc3NhZ2U9RkFMU0UsIGVjaG89VFJVRX0NCmkgPC0gMCAjU2V0dGluZyB1cCB0aGUgY291bnRlciBpDQpyZXBlYXR7DQogIHByaW50KGkpICNDb2RlIHRoYXQgdGVsbHMgdGhlIHByb2dyYW0gd2hhdCB0byBkbw0KICAjTmV4dCB0d28gbGluZXMgYXJlIHNldCB1cCBhcyBjb25kaXRpb24gY2hlY2sgdG8gZXhpdCB0aGUgbG9vcA0KICBpIDwtIGkgKyAxICNJbmNyZWFzaW5nIHRoZSBjb3VudGVyDQogIGlmKCBpID09IDMwKSBicmVhayAjc2V0dGluZyB1cCB0aGUgY29uZGl0aW9uIHdoZW4gdG8gYnJlYWsgdGhlIGxvb3ANCn0NCmBgYA0KDQpUaGUgY29kZSByZXN1bHRzIGluIG51bWJlcnMgZnJvbSAwIHRvIDI5IGJlY2F1c2UgZ2l2ZW4gdGhlIHdheSB0aGUgY29kZSBpcyB3cml0dGVuLCB3aGVuIDI5IGlzIHJlYWNoZWQNCml0IGlzIHByaW50ZWQsIHRoZW4gaW5jcmVhc2VkIGJ5IDEsIGFuZCB0aGVuIHRlc3RlZCBpbiB0aGUgaWYgY2xhdXNlIHdoZXJlIGkgPT0gMzAgaXMgdHJ1ZSBhbmQgdGhlIGxvb3AgaXMgc3RvcHBlZC4gVGhlIG9yZGVyIGluIHdoaWNoIHlvdSB3cml0ZSB0aGUgbG9vcCBzdGF0ZW1lbnRzIG1hdHRlcnMhDQoNCk5vdGUgdGhhdCBicmVhayBjYW4gYmUgcHV0IGludG8gY3VydnkgcGFyZW50aGVzZXMgb2YgaWYgc3RhdGVtZW50LCBidXQgaXQgaXMgbm90IG5lY2Nlc3NhcnkuDQoNCg0KIyMgV2hpbGUNCg0KV2hpbGUgLSB1c2VkIHRvIGl0ZXJhdGUgb3ZlciBhIGJsb2NrIG9mIGNvZGUgbXVsdGlwbGUgdGltZXMgYXMgbG9uZyBhcyBzcGVjaWZpZWQgY29uZGl0aW9uIGlzIG1ldC4NCg0KYGBgIHtyLCBtZXNzYWdlPUZBTFNFLCBlY2hvPVRSVUV9DQojU2V0dGluZyB1cCB0aGUgc3RhcnRpbmcgdmFsdWUgDQp4PTANCg0KI1RoZSBsb29wDQp3aGlsZSAoeCA8IDQyKSB7ICNUaGlzIHNwZWNpZmllcyB0aGF0IHRoZSBsb29wIHdpbGwgcnVuIGFzIGxvbmcgYXMgdGhlIGNvbmRpdGlvbiBpcyBtZXQuIE9uY2UgY29uZGl0aW9uIGlzIG5vdCBtZXQgKHg+NDIpIHRoZSBsb29wIHdpbGwgc3RvcA0KICB4PC0xK3ggI0luY3JlYXNpbmcgdGhlIGNvdW50ZXINCiAgcHJpbnQoeCkgI0NvZGUgdGhhdCB0ZWxscyB0aGUgcHJvZ3JhbSB3aGF0IHRvIGRvDQp9DQpgYGANCg0KVGhlIGNvZGUgcmV0dXJucyBudW1iZXJzIDEgLSA0Mi4gV2hlbiA0MSBpcyByZWFjaGVkLCB0aGUgeCBpcyBpbmNyZWFzZWQgYnkgMSBhbmQgNDIgaXMgZGlzcGxheWVkLg0KTm93IHggPSA0MiB0aGF0IG1ha2VzIHN0YXRlbWVudCB4IDwgNDIgZmFsc2UgYW5kIHRoZSBsb29wIGlzIHN0b3BwZWQuDQpUaGUgd2hpbGUgbG9vcCBkb2VzIG5vdCBuZWVkIGEgYnJlYWsgY2xhdXNlIHRvIHN0b3AgYmVjYXVzZSB0aGlzIGZlYXR1cmUgaXMgYnVpbHQgaW4sIGJ1dCBpdCBpcyBpbXBvcnRhbnQNCnRvIGluY2x1ZGUgaW5jcmVtZW50YWwgY29kZSBzbyB0aGF0IHRoZSBsb29wIGRvZXMgbm90IHR1cm4gaW50byBhbiBpbmZpbml0ZSBsb29wLg0KDQoNCiMjIEZvcg0KRm9yIC0gdXNlZCB0byBpdGVyYXRlIG92ZXIgYSB2ZWN0b3IuIFRoZSBzdGF0ZW1lbnQgb2YgdGhlIHByb2dyYW0gaXMgcmVwZWF0ZWQgZm9yIGFzIG1hbnkgdGltZXMNCmFzIHRoZXJlIGFyZSB1bml0cyBpbiB0aGUgdmVjdG9yLg0KYGBgIHtyLCBtZXNzYWdlPUZBTFNFLCBlY2hvPVRSVUV9DQp6IDwtIGMoMiwgNCwgNiwgOCkNCmZvciAoaSBpbiB6KSB7ICMgVGhlIGNvbmRpdGlvbiBpbnNpZGUgdGVsbHMgdGhlIGxvb3AgaG93IG1hbnkgdGltZXMgdG8gcnVuIGl0DQogIHByaW50KGleMikgIyBDb2RlIHRoYXQgdGVsbHMgdGhlIHByb2dyYW0gd2hhdCB0byBkbw0KfQ0KYGBgDQoNClRoZSBjb2RlIHJldHVybnMgNCBudW1iZXJzLCB0aGUgc3F1YXJlZCBlbGVtZW50cyBvZiB0aGUgdmVjdG9yIHosIGJlY2F1c2UgdGhlcmUgYXJlIG9ubHkgNCBpdGVtcyBpbiB6Lg0KDQpBbm90aGVyIGNvbW1vbiB1c2Ugb2YgdGhlIGZvciBsb29wIGlzIHRvIHJ1biBzb21lIGNvZGUgZm9yIHRoZSBsZW5ndGggb2YgdGhlIHZlY3Rvci4NCg0KYGBgIHtyLCBtZXNzYWdlPUZBTFNFLCBlY2hvPVRSVUV9DQp6IDwtIGMoMiwgNCwgNiwgOCkgI1NldHRpbmcgdXAgdGhlIHZlY3Rvcg0KZm9yIChpIGluIDE6bGVuZ3RoKHopKSB7ICMgVGhlIGNvbmRpdGlvbiBpbnNpZGUgdGVsbHMgdGhlIGxvb3AgaG93IG1hbnkgdGltZXMgdG8gcnVuIGl0DQogIHByaW50KHpbaV1eMikgIyBDb2RlIHRoYXQgdGVsbHMgdGhlIHByb2dyYW0gd2hhdCB0byBkbw0KfQ0KYGBgDQoNClRoZSBmb3IgbG9vcCBjaGFuZ2VzIHRoZSB2YWx1ZSBvZiBpIGZyb20gMSB0byB0aGUgbGVuZ2h0IG9mIHRoZSB2ZWN0b3IgeiBieSAxIGFuZCBkb2VzIGFuIG9wZXJhdGlvbiBvbiBpLXRoIGVsZW1lbnQgb2YgeiwgaW4gdGhpcyBleGFtcGxlIGl0IHNxdWFyZXMgaXQuIFRodXMgdGhlIHJlc3VsdCBpcyBzYW1lIGFzIGZvciB0aGUgcHJldmlvdXMgY29kZSwgYnV0IGhhcyBhIHNsaWdodGx5IGRpZmZlcmVudCBhcHByb2FjaC4gVGhpcyBnaXZlcyB1cyB0aGUgYWJpbGl0eSB0byBjcmVhdGUgYSBjYWxjdWxhdGlvbiB0aGF0IHdpbGwgbm90IGhhdmUgYSBjaGFsbGVuZ2UgaGF2aW5nIGEgdmVjdG9yIG9mIGFueSBsZW5ndGggYXMgYW4gaW5wdXQuDQpPdGhlciBjb21tb24gdXNlcyBvZiBmb3IgbG9vcCBpcyB1c2luZyAxOnNlcSAoMTpzZXEoMSwgMTAwKSkgYW5kIDE6cmFuZ2UuDQoNCg0KIyMgQnJlYWsNCg0KQSBicmVhayBzdGF0ZW1lbnQgaXMgdXNlZCBpbnNpZGUgYSBsb29wIHRvIHN0b3AgdGhlIGl0ZXJhdGlvbnMgYW5kIGZsb3cgdGhlIGNvbnRyb2wgb3V0c2lkZSB0aGUgbG9vcC4NCmBgYCB7ciwgbWVzc2FnZT1GQUxTRSwgZWNobz1UUlVFfQ0KeCA8LSAxOjUgI0NyZWF0ZSBhIHZlY3Rvcg0KZm9yICh2YWwgaW4geCkgeyAjU2V0IHVwIHRoZSBsb29wIHNvIHRoYXQgdmFyaWFibGUgInZhbCIgdGFrZXMgZWFjaCB2YWx1ZSBpbiB4IGluIG9yZGVyDQogICNUaGUgdmFsIGlzIHVzZWQgaW4gdGhlIG5leHQgdHdvIGxpbmVzIGluIHRoZSBsb29wIHN0YXRlbWVudA0KICBpZiAodmFsID09IDMpIHticmVha30gI0NvbXBhcmUgdGhlIHZhbCB0byAzLCBleGl0IHRoZSBsb29wIGlmIHZhbCBlcXVhbHMgMw0KICBwcmludCh2YWwpICNJZiB2YWwgaXMgbm90IDMsIHByaW50IHRoZSBpdGVtIGFzc29jaWF0ZWQgd2l0aCB2YWwgaW4gdGhpcyByb3VuZCBvZiB0aGUgbG9vcA0KfQ0KYGBgDQoNClIgcmV0dXJucyB2YWx1ZXMgMSBhbmQgMiBvbmx5IGZvciB3aGVuIDMgaXMgcmVhY2hlZCwgdGhlIGlmIHN0YXRlbWVudCBzdG9wcyB0aGUgbG9vcCBhbmQgMywgNCwgYW5kIDUgZG8gbm90IHNob3cgdXAuDQoNCkluIGNhc2Ugb2YgbmVzdGVkIGxvb3BzLCB0aGUgYnJlYWtzIGV4aXRzIHRoZSBsb29wIHRoYXQgaXMgYmVpbmcgZXZhbHVhdGVkLg0KDQpgYGAge3IsIG1lc3NhZ2U9RkFMU0UsIGVjaG89VFJVRX0NCiNTZXQgdXAgdHdvIGRpZmZlcmVudCB2YWN0b3JzIHRvIGRlbW9uc3RyYXRlIHRoZSBlZmZlY3Qgb2YgdGhlIG5lc3RlZCBsb29wcw0KeCA8LSAxOjUNCnkgPC0gMTA6NTANCg0KZm9yICh2YWwgaW4geCkgeyAjU2V0dGluZyB1cCB0aGUgZmlyc3QgbG9vcCB0aGF0IHdpbGwgcmVwZWF0IHRoZSBzZWNvbmQgbG9vcCBhbmQgcHJpbnQgdGhlIHZhbHVlIG9mIHZhbCBmb3IgZXZlcnkgaXRlbSBpbiB4DQogIGZvciAodmFsMiBpbiB5KSB7ICNTZXR0aW5nIHVwIHRoZSBzZWNvbmQgbG9vcCB0byByZXBlYXQgdHdvIHN0YXRlbWVudHMNCiAgICBpZiAodmFsMiA9PSAxNSkge2JyZWFrfSAjIDEuIFRlc3QgaWYgdmFsMiBlcXVhbCAxNSwgZXhpdCB0aGUgbG9vcCBpZiB5ZXMNCiAgICBwcmludCh2YWwyKSAgICAgICAgICAgICAjIDIuIFByaW50IHRoZSB2YWx1ZSBvZiB2YWwyDQogIH0NCiAgcHJpbnQodmFsKSAjV2hlbiB0aGUgbmVzdGVkIGxvb3AgaXMgZXhpdGVkLCB2YWwgZnJvbSB4IGZvciB3aGljaCB0aGUgbmVzdGVkIGxvb3Agd2FzIHJhbiBpcyBwcmludGVkDQp9DQpgYGANCg0KVGhlIGJyZWFrIGlzIHVzZWQgaW4gdGhlIG5lc3RlZCBsb29wIHNvIHRoZSByZXN1bHQgaXMgYWxsIHZhbHVlcyBvZiB4IGFuZCBvbmx5IHRoZSB2YWx1ZXMgb2YgeSBiZWxvdyAxNS4NCk5vdGUgdGhlIHJlcGVhdGVkIHBhdHRlcm4sIHRoZSBuZXN0ZWQgbG9vcCBpcyByZXBlYXRlZCBmb3IgZWFjaCB2YWx1ZSBvZiB0aGUgb3V0c2lkZSBsb29wLg0KDQoNCiMjIE5leHQNCg0KQSBuZXh0IHN0YXRlbWVudCBpcyB1c2VkIGluc2lkZSBhIGxvb3AgdG8gc2tpcCB0aGUgaXRlcmF0aW9ucyBvZiBhIGxvb3AgIHdpdGhvdXQgdGVybWluYXRpbmcgaXQuDQoNCmBgYCB7ciwgbWVzc2FnZT1GQUxTRSwgZWNobz1UUlVFfQ0KeCA8LSAxOjUgI1NldHRpZ24gdXAgdGhlIHZlY3Rvcg0KZm9yICh2YWwgaW4geCkgeyAjU2V0dGluZyB1cCB0aGUgbG9vcA0KICBpZiAodmFsID09IDQpIHtuZXh0fSAjQXBwbHlpbmcgdGhlIG5leHQgdG8gc2tpcCB2YWx1ZSBvZiA0DQogIHByaW50KHZhbCkgI1ByaW50IHRoZSB2YWx1ZSBvZiB2YWwNCn0NCmBgYA0KDQpSIHJldHVybnMgMSB0aG91Z2ggNSBidXQgc2tpcHMgNCBiZWNhdXNlIGlmIHN0YXRlbWVudCBpcyB0cnVlIGFuZCBhcHBsaWVzIG5leHQuDQoNCjxzY3JpcHQ+DQogIChmdW5jdGlvbihpLHMsbyxnLHIsYSxtKXtpWydHb29nbGVBbmFseXRpY3NPYmplY3QnXT1yO2lbcl09aVtyXXx8ZnVuY3Rpb24oKXsNCiAgKGlbcl0ucT1pW3JdLnF8fFtdKS5wdXNoKGFyZ3VtZW50cyl9LGlbcl0ubD0xKm5ldyBEYXRlKCk7YT1zLmNyZWF0ZUVsZW1lbnQobyksDQogIG09cy5nZXRFbGVtZW50c0J5VGFnTmFtZShvKVswXTthLmFzeW5jPTE7YS5zcmM9ZzttLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGEsbSkNCiAgfSkod2luZG93LGRvY3VtZW50LCdzY3JpcHQnLCdodHRwczovL3d3dy5nb29nbGUtYW5hbHl0aWNzLmNvbS9hbmFseXRpY3MuanMnLCdnYScpOw0KDQogIGdhKCdjcmVhdGUnLCAnVUEtOTg4Nzg3OTMtMScsICdhdXRvJyk7DQogIGdhKCdzZW5kJywgJ3BhZ2V2aWV3Jyk7DQoNCjwvc2NyaXB0Pg0K