Introduction

This explainer will serve as a basic introduction to R’s for loop function.

What is a loop?

We saw this tweet about loops all the way back at the beginning of the semester, in our “A gentle intro to programming” section of our textbook:

A loop is a function that automates repetitive actions until a particular condition is met.

There are multiple types of loops. Today we’ll focus on the for loop. Other types of loops include while and repeat loops.

A loop is useful for performing certain actions on a very large amount of data quickly. Rather than having to copy and paste or run the same calculations over and over again, a loop lets us make the computer do all the work.

Building a for loop

Here is what a for loop looks like:

for(value in sequence) {
action
}

In this template, a “sequence” is a series of variables. It could be a list, a vector, a matrix — whatever it is you want your loop to work its way through.

“value” represents a single instance in the sequence; it changes as the loop makes its way through the sequence.

Finally, “action” is whatever you want your code to do with each of the values in the sequence.

To help clarify, let’s look at a for loop in action.

Below we have a sequence of values: a vector containing the numbers 1, 2, 4, 6 and 12. To start, I would like my action to be a simple print of each of these values, one after another.

Here’s what that looks like:

numbers <- c(1,2,4,6,12)
# Using the for loop will pull each value from the vector "numbers", one after the other.
for (values in numbers) {
  # This line — the "action" line, will print the value
  print(values)
  # Then we will move on to the next value and do the some thing
}
## [1] 1
## [1] 2
## [1] 4
## [1] 6
## [1] 12

You can assign almost any name to your values. In the above example, we called them “values.” In the below example, I use “i”.

  for (i in numbers) {
    print(i)
  }
## [1] 1
## [1] 2
## [1] 4
## [1] 6
## [1] 12

You can see that the result is the same when I call my values “values” or “i”. That’s because these names are just representations each value contained in our sequence, like a stand-in.

Adding functions

Now that we understand the basic structure of a for loop, we can get creative about our “action.” This code goes between the curly braces {}

Let’s say we want to multiple each value by 3. Here’s how we could do that:

 for (i in numbers) {
   i <- i * 3
   # note that we need to assign i a new value of i * 3 before we print the results
    print(i)
  }
## [1] 3
## [1] 6
## [1] 12
## [1] 18
## [1] 36

Combining for loops with functions we’ve learned

In data journalism, we will want to use R to quickly pull and manipulate large amounts of data.

One way we might manipulate data using a loop is by combining a loop with the if/when function we learned.

In this simple example, we’ll use “paste”, which we briefly learned in our data viz section, and the if/when function to decide what days we need to work, and what days we can party.

Using paste

Here we have a simple vector of the days of the week:

week <- c("Sunday",
           "Monday",
           "Tuesday",
           "Wednesday",
           "Thursday",
           "Friday",
           "Saturday")

In this first example, we combine a loop and the paste function. As a reminder, here’s how the paste function can be constructed:

paste("Some text you want goes in quotes", value, "more text, remember your commas after each piece of your variable!")

In the below example, we’re first going to use paste to combine each day of the week into a sentence, then we will print every sentence.

# To begin our loop, we ask R to evaluate each value ("days") in our vector ("week")
for(days in week) {
  # Next, we create a new variable called "gameplan". This is where we deposit our complete sentence, that we build using the "paste" function.
  gameplan <- paste("It's",days,"today, let's work!")
  # Finally, we print our new variable "gameplan." 
print(gameplan)
}
## [1] "It's Sunday today, let's work!"
## [1] "It's Monday today, let's work!"
## [1] "It's Tuesday today, let's work!"
## [1] "It's Wednesday today, let's work!"
## [1] "It's Thursday today, let's work!"
## [1] "It's Friday today, let's work!"
## [1] "It's Saturday today, let's work!"
# Then the loop repeats. Note in the printout below that each variable is its own value, rather than everything being contained in a vector like the original data.

Now we have a printout of every day of the week, pasted into the sentence “It’s __ today, let’s work!”. But we know what all work and no play does, so let’s add our if/else function.

Combining for loop with if/else

For our next code, we want to let the computer know that Saturday and Sunday are our party days. Below, we’ve combined if/when with paste, and nestled it all within our for loop.

With each iteration of the loop, the code will run through each day of the week and evaluate if it is Saturday or Sunday. If it’s not, it will move on to our else statement, and it will print out that it’s time to work… but if it is Saturday or Sunday, then it will let us know those are party days!

for(days in week) {
  if (days %in% c("Saturday", "Sunday")) {
gameplan <- paste("It's",days,"today, let's party!") }
  else { gameplan <- paste("It's",days,"today, let's work!")}
print(gameplan) }
## [1] "It's Sunday today, let's party!"
## [1] "It's Monday today, let's work!"
## [1] "It's Tuesday today, let's work!"
## [1] "It's Wednesday today, let's work!"
## [1] "It's Thursday today, let's work!"
## [1] "It's Friday today, let's work!"
## [1] "It's Saturday today, let's party!"
LS0tDQp0aXRsZTogIkxvb3BzIEV4cGxhaW5lZCINCmF1dGhvcjogIlR5bGVyIERlZHJpY2siDQpkYXRlOiAiNC8zMC8yMiINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdGhlbWU6IGNlcnVsZWFuDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIGRmX3ByaW50OiBwYWdlZA0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsDQogICAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBUUlVFKQ0KDQoNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShqYW5pdG9yKQ0KbGlicmFyeShsdWJyaWRhdGUpDQoNCg0KYGBgDQoNCiMjIEludHJvZHVjdGlvbg0KDQpUaGlzIGV4cGxhaW5lciB3aWxsIHNlcnZlIGFzIGEgYmFzaWMgaW50cm9kdWN0aW9uIHRvIFIncyBmb3IgbG9vcCBmdW5jdGlvbi4NCg0KIyMjIFdoYXQgaXMgYSBsb29wPw0KDQpXZSBzYXcgdGhpcyB0d2VldCBhYm91dCBsb29wcyBhbGwgdGhlIHdheSBiYWNrIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNlbWVzdGVyLCBpbiBvdXIgWyJBIGdlbnRsZSBpbnRybyB0byBwcm9ncmFtbWluZyJdKGh0dHBzOi8vY3JvbmtpdGVkYXRhLmdpdGh1Yi5pby9kanRleHRib29rL2FwcGVuZGl4LXByb2dyYW0uaHRtbCNhcHBlbmRpeC1wcm9ncmFtKSBzZWN0aW9uIG9mIG91ciB0ZXh0Ym9vazoNCg0KPGJsb2NrcXVvdGUgY2xhc3M9InR3aXR0ZXItdHdlZXQiPjxwIGxhbmc9ImVuIiBkaXI9Imx0ciI+Rm9yIGxvb3BzIGFyZW4mIzM5O3QgYWx3YXlzIHNjYXJ5IG1vbnN0ZXJzLiA8YnI+PGJyPkNvbmNlcHR1YWwgaW50cm8gKG5vLCB0aGlzIGNvZGUgd29uJiMzOTt0IHJ1bi4uLikgdG8gZm9yIGxvb3BzLiBUaGFua3MgPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9DaGVsc2VhUGFybGV0dD9yZWZfc3JjPXR3c3JjJTVFdGZ3Ij5AQ2hlbHNlYVBhcmxldHQ8L2E+IGZvciBicmFpbnN0b3JtaW5nIHcvIG1lIG9uIHRoaXMgb25lISDwn5G+8J+RvvCfkb4gPGEgaHJlZj0iaHR0cHM6Ly90LmNvL1R5U0ZIb2dHMmQiPnBpYy50d2l0dGVyLmNvbS9UeVNGSG9nRzJkPC9hPjwvcD4mbWRhc2g7IEFsbGlzb24gSG9yc3QgKEBhbGxpc29uX2hvcnN0KSA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL2FsbGlzb25faG9yc3Qvc3RhdHVzLzEyOTA3NzQ2MTYwMzg4MDk2MDA/cmVmX3NyYz10d3NyYyU1RXRmdyI+QXVndXN0IDQsIDIwMjA8L2E+PC9ibG9ja3F1b3RlPiA8c2NyaXB0IGFzeW5jIHNyYz0iaHR0cHM6Ly9wbGF0Zm9ybS50d2l0dGVyLmNvbS93aWRnZXRzLmpzIiBjaGFyc2V0PSJ1dGYtOCI+PC9zY3JpcHQ+DQoNCg0KQSBsb29wIGlzIGEgZnVuY3Rpb24gdGhhdCBhdXRvbWF0ZXMgcmVwZXRpdGl2ZSBhY3Rpb25zIHVudGlsIGEgcGFydGljdWxhciBjb25kaXRpb24gaXMgbWV0LiANCg0KVGhlcmUgYXJlIG11bHRpcGxlIHR5cGVzIG9mIGxvb3BzLiBUb2RheSB3ZSdsbCBmb2N1cyBvbiB0aGUgZm9yIGxvb3AuIE90aGVyIHR5cGVzIG9mIGxvb3BzIGluY2x1ZGUgd2hpbGUgYW5kIHJlcGVhdCBsb29wcy4NCg0KQSBsb29wIGlzIHVzZWZ1bCBmb3IgcGVyZm9ybWluZyBjZXJ0YWluIGFjdGlvbnMgb24gYSB2ZXJ5IGxhcmdlIGFtb3VudCBvZiBkYXRhIHF1aWNrbHkuIFJhdGhlciB0aGFuIGhhdmluZyB0byBjb3B5IGFuZCBwYXN0ZSBvciBydW4gdGhlIHNhbWUgY2FsY3VsYXRpb25zIG92ZXIgYW5kIG92ZXIgYWdhaW4sIGEgbG9vcCBsZXRzIHVzIG1ha2UgdGhlIGNvbXB1dGVyIGRvIGFsbCB0aGUgd29yay4NCg0KIyMgQnVpbGRpbmcgYSBmb3IgbG9vcA0KSGVyZSBpcyB3aGF0IGEgZm9yIGxvb3AgbG9va3MgbGlrZToNCg0KYGBge3IsIGV2YWw9RiwgZWNobz1UfQ0KDQpmb3IodmFsdWUgaW4gc2VxdWVuY2UpIHsNCmFjdGlvbg0KfQ0KDQpgYGANCkluIHRoaXMgdGVtcGxhdGUsIGEgInNlcXVlbmNlIiBpcyBhIHNlcmllcyBvZiB2YXJpYWJsZXMuIEl0IGNvdWxkIGJlIGEgbGlzdCwgYSB2ZWN0b3IsIGEgbWF0cml4IOKAlCB3aGF0ZXZlciBpdCBpcyB5b3Ugd2FudCB5b3VyIGxvb3AgdG8gd29yayBpdHMgd2F5IHRocm91Z2guDQoNCiJ2YWx1ZSIgcmVwcmVzZW50cyBhIHNpbmdsZSBpbnN0YW5jZSBpbiB0aGUgc2VxdWVuY2U7IGl0IGNoYW5nZXMgYXMgdGhlIGxvb3AgbWFrZXMgaXRzIHdheSB0aHJvdWdoIHRoZSBzZXF1ZW5jZS4NCg0KRmluYWxseSwgImFjdGlvbiIgaXMgd2hhdGV2ZXIgeW91IHdhbnQgeW91ciBjb2RlIHRvIGRvIHdpdGggZWFjaCBvZiB0aGUgdmFsdWVzIGluIHRoZSBzZXF1ZW5jZS4NCg0KVG8gaGVscCBjbGFyaWZ5LCBsZXQncyBsb29rIGF0IGEgZm9yIGxvb3AgaW4gYWN0aW9uLg0KDQpCZWxvdyB3ZSBoYXZlIGEgc2VxdWVuY2Ugb2YgdmFsdWVzOiBhIHZlY3RvciBjb250YWluaW5nIHRoZSBudW1iZXJzIDEsIDIsIDQsIDYgYW5kIDEyLiBUbyBzdGFydCwgSSB3b3VsZCBsaWtlIG15IGFjdGlvbiB0byBiZSBhIHNpbXBsZSBwcmludCBvZiBlYWNoIG9mIHRoZXNlIHZhbHVlcywgb25lIGFmdGVyIGFub3RoZXIuIA0KDQpIZXJlJ3Mgd2hhdCB0aGF0IGxvb2tzIGxpa2U6DQoNCg0KYGBge3J9DQpudW1iZXJzIDwtIGMoMSwyLDQsNiwxMikNCmBgYA0KDQoNCmBgYHtyfQ0KIyBVc2luZyB0aGUgZm9yIGxvb3Agd2lsbCBwdWxsIGVhY2ggdmFsdWUgZnJvbSB0aGUgdmVjdG9yICJudW1iZXJzIiwgb25lIGFmdGVyIHRoZSBvdGhlci4NCmZvciAodmFsdWVzIGluIG51bWJlcnMpIHsNCiAgIyBUaGlzIGxpbmUg4oCUIHRoZSAiYWN0aW9uIiBsaW5lLCB3aWxsIHByaW50IHRoZSB2YWx1ZQ0KICBwcmludCh2YWx1ZXMpDQogICMgVGhlbiB3ZSB3aWxsIG1vdmUgb24gdG8gdGhlIG5leHQgdmFsdWUgYW5kIGRvIHRoZSBzb21lIHRoaW5nDQp9DQpgYGANCg0KWW91IGNhbiBhc3NpZ24gYWxtb3N0IGFueSBuYW1lIHRvIHlvdXIgdmFsdWVzLiBJbiB0aGUgYWJvdmUgZXhhbXBsZSwgd2UgY2FsbGVkIHRoZW0gInZhbHVlcy4iIEluIHRoZSBiZWxvdyBleGFtcGxlLCBJIHVzZSAiaSIuIA0KDQpgYGB7cn0NCiAgZm9yIChpIGluIG51bWJlcnMpIHsNCiAgICBwcmludChpKQ0KICB9DQoNCg0KYGBgDQpZb3UgY2FuIHNlZSB0aGF0IHRoZSByZXN1bHQgaXMgdGhlIHNhbWUgd2hlbiBJIGNhbGwgbXkgdmFsdWVzICJ2YWx1ZXMiIG9yICJpIi4gVGhhdCdzIGJlY2F1c2UgdGhlc2UgbmFtZXMgYXJlIGp1c3QgcmVwcmVzZW50YXRpb25zIGVhY2ggdmFsdWUgY29udGFpbmVkIGluIG91ciBzZXF1ZW5jZSwgbGlrZSBhIHN0YW5kLWluLg0KDQojIyMgQWRkaW5nIGZ1bmN0aW9ucw0KDQpOb3cgdGhhdCB3ZSB1bmRlcnN0YW5kIHRoZSBiYXNpYyBzdHJ1Y3R1cmUgb2YgYSBmb3IgbG9vcCwgd2UgY2FuIGdldCBjcmVhdGl2ZSBhYm91dCBvdXIgImFjdGlvbi4iIFRoaXMgY29kZSBnb2VzIGJldHdlZW4gdGhlIGN1cmx5IGJyYWNlcyB7fSAgDQoNCkxldCdzIHNheSB3ZSB3YW50IHRvIG11bHRpcGxlIGVhY2ggdmFsdWUgYnkgMy4gSGVyZSdzIGhvdyB3ZSBjb3VsZCBkbyB0aGF0Og0KDQpgYGB7cn0NCiBmb3IgKGkgaW4gbnVtYmVycykgew0KICAgaSA8LSBpICogMw0KICAgIyBub3RlIHRoYXQgd2UgbmVlZCB0byBhc3NpZ24gaSBhIG5ldyB2YWx1ZSBvZiBpICogMyBiZWZvcmUgd2UgcHJpbnQgdGhlIHJlc3VsdHMNCiAgICBwcmludChpKQ0KICB9DQpgYGANCg0KIyMgQ29tYmluaW5nIGZvciBsb29wcyB3aXRoIGZ1bmN0aW9ucyB3ZSd2ZSBsZWFybmVkDQoNCkluIGRhdGEgam91cm5hbGlzbSwgd2Ugd2lsbCB3YW50IHRvIHVzZSBSIHRvIHF1aWNrbHkgcHVsbCBhbmQgbWFuaXB1bGF0ZSBsYXJnZSBhbW91bnRzIG9mIGRhdGEuIA0KDQpPbmUgd2F5IHdlIG1pZ2h0IG1hbmlwdWxhdGUgZGF0YSB1c2luZyBhIGxvb3AgaXMgYnkgY29tYmluaW5nIGEgbG9vcCB3aXRoIHRoZSBpZi93aGVuIGZ1bmN0aW9uIHdlIGxlYXJuZWQuIA0KDQpJbiB0aGlzIHNpbXBsZSBleGFtcGxlLCB3ZSdsbCB1c2UgInBhc3RlIiwgd2hpY2ggd2UgYnJpZWZseSBsZWFybmVkIGluIG91ciBkYXRhIHZpeiBzZWN0aW9uLCBhbmQgdGhlIGlmL3doZW4gZnVuY3Rpb24gdG8gZGVjaWRlIHdoYXQgZGF5cyB3ZSBuZWVkIHRvIHdvcmssIGFuZCB3aGF0IGRheXMgd2UgY2FuIHBhcnR5Lg0KDQojIyMgVXNpbmcgcGFzdGUNCg0KSGVyZSB3ZSBoYXZlIGEgc2ltcGxlIHZlY3RvciBvZiB0aGUgZGF5cyBvZiB0aGUgd2VlazoNCg0KYGBge3J9DQp3ZWVrIDwtIGMoIlN1bmRheSIsDQogICAgICAgICAgICJNb25kYXkiLA0KICAgICAgICAgICAiVHVlc2RheSIsDQogICAgICAgICAgICJXZWRuZXNkYXkiLA0KICAgICAgICAgICAiVGh1cnNkYXkiLA0KICAgICAgICAgICAiRnJpZGF5IiwNCiAgICAgICAgICAgIlNhdHVyZGF5IikNCmBgYA0KDQpJbiB0aGlzIGZpcnN0IGV4YW1wbGUsIHdlIGNvbWJpbmUgYSBsb29wIGFuZCB0aGUgcGFzdGUgZnVuY3Rpb24uIEFzIGEgcmVtaW5kZXIsIGhlcmUncyBob3cgdGhlIHBhc3RlIGZ1bmN0aW9uIGNhbiBiZSBjb25zdHJ1Y3RlZDoNCg0KYGBge3IsIGV2YWw9RiwgZWNobz1UfQ0KcGFzdGUoIlNvbWUgdGV4dCB5b3Ugd2FudCBnb2VzIGluIHF1b3RlcyIsIHZhbHVlLCAibW9yZSB0ZXh0LCByZW1lbWJlciB5b3VyIGNvbW1hcyBhZnRlciBlYWNoIHBpZWNlIG9mIHlvdXIgdmFyaWFibGUhIikNCmBgYA0KSW4gdGhlIGJlbG93IGV4YW1wbGUsIHdlJ3JlIGZpcnN0IGdvaW5nIHRvIHVzZSBwYXN0ZSB0byBjb21iaW5lIGVhY2ggZGF5IG9mIHRoZSB3ZWVrIGludG8gYSBzZW50ZW5jZSwgdGhlbiB3ZSB3aWxsIHByaW50IGV2ZXJ5IHNlbnRlbmNlLg0KDQpgYGB7cn0NCg0KIyBUbyBiZWdpbiBvdXIgbG9vcCwgd2UgYXNrIFIgdG8gZXZhbHVhdGUgZWFjaCB2YWx1ZSAoImRheXMiKSBpbiBvdXIgdmVjdG9yICgid2VlayIpDQpmb3IoZGF5cyBpbiB3ZWVrKSB7DQogICMgTmV4dCwgd2UgY3JlYXRlIGEgbmV3IHZhcmlhYmxlIGNhbGxlZCAiZ2FtZXBsYW4iLiBUaGlzIGlzIHdoZXJlIHdlIGRlcG9zaXQgb3VyIGNvbXBsZXRlIHNlbnRlbmNlLCB0aGF0IHdlIGJ1aWxkIHVzaW5nIHRoZSAicGFzdGUiIGZ1bmN0aW9uLg0KICBnYW1lcGxhbiA8LSBwYXN0ZSgiSXQncyIsZGF5cywidG9kYXksIGxldCdzIHdvcmshIikNCiAgIyBGaW5hbGx5LCB3ZSBwcmludCBvdXIgbmV3IHZhcmlhYmxlICJnYW1lcGxhbi4iIA0KcHJpbnQoZ2FtZXBsYW4pDQp9DQojIFRoZW4gdGhlIGxvb3AgcmVwZWF0cy4gTm90ZSBpbiB0aGUgcHJpbnRvdXQgYmVsb3cgdGhhdCBlYWNoIHZhcmlhYmxlIGlzIGl0cyBvd24gdmFsdWUsIHJhdGhlciB0aGFuIGV2ZXJ5dGhpbmcgYmVpbmcgY29udGFpbmVkIGluIGEgdmVjdG9yIGxpa2UgdGhlIG9yaWdpbmFsIGRhdGEuDQpgYGANCk5vdyB3ZSBoYXZlIGEgcHJpbnRvdXQgb2YgZXZlcnkgZGF5IG9mIHRoZSB3ZWVrLCBwYXN0ZWQgaW50byB0aGUgc2VudGVuY2UgIkl0J3MgX18gdG9kYXksIGxldCdzIHdvcmshIi4gQnV0IHdlIGtub3cgd2hhdCBhbGwgd29yayBhbmQgbm8gcGxheSBkb2VzLCBzbyBsZXQncyBhZGQgb3VyIGlmL2Vsc2UgZnVuY3Rpb24uIA0KDQojIyMgQ29tYmluaW5nIGZvciBsb29wIHdpdGggaWYvZWxzZQ0KDQpGb3Igb3VyIG5leHQgY29kZSwgd2Ugd2FudCB0byBsZXQgdGhlIGNvbXB1dGVyIGtub3cgdGhhdCBTYXR1cmRheSBhbmQgU3VuZGF5IGFyZSBvdXIgcGFydHkgZGF5cy4gQmVsb3csIHdlJ3ZlIGNvbWJpbmVkIGlmL3doZW4gd2l0aCBwYXN0ZSwgYW5kIG5lc3RsZWQgaXQgYWxsIHdpdGhpbiBvdXIgZm9yIGxvb3AuIA0KDQpXaXRoIGVhY2ggaXRlcmF0aW9uIG9mIHRoZSBsb29wLCB0aGUgY29kZSB3aWxsIHJ1biB0aHJvdWdoIGVhY2ggZGF5IG9mIHRoZSB3ZWVrIGFuZCBldmFsdWF0ZSBpZiBpdCBpcyBTYXR1cmRheSBvciBTdW5kYXkuIElmIGl0J3Mgbm90LCBpdCB3aWxsIG1vdmUgb24gdG8gb3VyIGVsc2Ugc3RhdGVtZW50LCBhbmQgaXQgd2lsbCBwcmludCBvdXQgdGhhdCBpdCdzIHRpbWUgdG8gd29yay4uLiBidXQgaWYgaXQgaXMgU2F0dXJkYXkgb3IgU3VuZGF5LCB0aGVuIGl0IHdpbGwgbGV0IHVzIGtub3cgdGhvc2UgYXJlIHBhcnR5IGRheXMhDQoNCmBgYHtyfQ0KDQpmb3IoZGF5cyBpbiB3ZWVrKSB7DQogIGlmIChkYXlzICVpbiUgYygiU2F0dXJkYXkiLCAiU3VuZGF5IikpIHsNCmdhbWVwbGFuIDwtIHBhc3RlKCJJdCdzIixkYXlzLCJ0b2RheSwgbGV0J3MgcGFydHkhIikgfQ0KICBlbHNlIHsgZ2FtZXBsYW4gPC0gcGFzdGUoIkl0J3MiLGRheXMsInRvZGF5LCBsZXQncyB3b3JrISIpfQ0KcHJpbnQoZ2FtZXBsYW4pIH0NCg0KYGBgDQoNCg0KIyMgU291cmNlczoNCi0gW0FkdmFuY2VkIFIgYnkgSGFkbGV5IFdpY2toYW1dKGh0dHA6Ly9hZHYtci5oYWQuY28ubnovRGF0YS1zdHJ1Y3R1cmVzLmh0bWwjOn46dGV4dD1BJTIwdmVjdG9yJTIwd2lsbCUyMGNyZWF0ZSUyMGEsYW5kJTIwcm93cyUyMGFzJTIwdGhlJTIwbWF0cml4LikNCg0KLSBbR2Vla3MgZm9yIEdlZWtzXShodHRwczovL3d3dy5nZWVrc2ZvcmdlZWtzLm9yZy9sb29wcy1pbi1yLWZvci13aGlsZS1yZXBlYXQvKQ0KDQotIFtTY3JhcGluZyB3ZWIgZGF0YSB3aXRoIFIgJiB0aGUgVGlkeXZlcnNlIGJ5IEhhcnJ5IEFuZGVyc29uXShodHRwczovL21lZGl1bS5jb20vZXBmbC1leHRlbnNpb24tc2Nob29sL3NjcmFwaW5nLXdlYi1kYXRhLXdpdGgtci10aGUtdGlkeXZlcnNlLTMwOTQ0Y2E2N2M5MikNCg0KLSBbRGF0YUNhbXAgSW50ZXJtZWRpYXRlIFJdKGh0dHBzOi8vY2FtcHVzLmRhdGFjYW1wLmNvbS9jb3Vyc2VzL2ludGVybWVkaWF0ZS1yL2NoYXB0ZXItMi1sb29wcz9leD0xKQ0KW1IgZm9yIERhdGEgU2NpZW5jZV0oaHR0cHM6Ly9yNGRzLmhhZC5jby5uei9pbmRleC5odG1sKQ0KDQotIEFuZCBvZiBjb3Vyc2UgW0RhdGEgUmVwb3J0aW5nLCBTcHJpbmcgMjAyMl0oaHR0cHM6Ly9jcm9ua2l0ZWRhdGEuZ2l0aHViLmlvL2RqdGV4dGJvb2svaW5kZXguaHRtbCkNCg0K