About this exercise

An approved solution for this exercise set is a prerequisite for passing the course. To get approved, your submission must fulfil the following requirements in addition to having a satisfactory amount of correctly solved exercises:

Format
R Notebook (a single, self-contained .nb.html file, described in Lecture 3)
Submission method
Send an email with the subject “CSOR-DB handin” to janus@math.aau.dk with your name and study no., and attach the .nb.html file (not the .Rmd file)
Due date
Your submission must be submitted no later than 2019-04-29T08:00

Get started with the R Notebook

Create a file called handin.Rmd and make sure it has the following fields in the YAML frontmatter:

---
title: "CSOR-DB Handin"
author: <your name>
output:
  html_notebook:
    toc: true
---

If you’re using RStudio , you can click File → New File → R Notebook to create one from a minimal template. Alternatively, you can use this notebook as a reference point - click the Code button in the top of the page and select Download Rmd.

In the beginning of your notebook, create an R chunk that defines a connection to the nycflights13 database:

library(DBI)
library(dplyr)

con <- dbConnect(
  drv      = RPostgreSQL::PostgreSQL(),
  dbname   = "nycflights13",
  user     = "csor",
  password = "csor"
)
knitr::opts_chunk$set(connection = "con")

Using R and SQL chunks

In the exercises, you will be asked to show code – some in R, some in SQL, some in both – and sometimes results.

  • When asked to show R code: show the dplyr pipeline used to produce the results in an R code chunk (unless the exercise also involves other things than selecting data (i.e. writing or deleting), because then you also need DBI functions)

  • When asked to show SQL code: show the SQL query used to produce the results in an SQL code chunk
  • When asked to show results: evaluating an R or SQL code chunk that returns a table produces a paginated HTML table
  • When asked for both R and SQL code as well as results: show an R chunk with dplyr code, and an SQL chunk, and evaluate one of them to show the table of results

To help you with this, here is a quick overview of how to use R and SQL code chunk headers in an R Notebook:

  • To show syntax highlighted R code and run it, use the chunk header:

    ```{r}
    
  • To show R code without running it, omit the curly braces:

    ```r
    
  • To show an SQL query and run it, use:

    ```{sql, connection = con}
    
  • To show an SQL query without running it, omit the curly braces:

    ```sql
    

NB: If you use RStudio, even if the chunk option connection = con is set globally, you still have to add it to each individual SQL chunk for it to work properly when evaluating the chunks interactively. Using the button Insert → SQL in the Source pane inserts a template with this option already typed in.

General hint

Remember that for the nycflights13 data, descriptions of all the variables are available in the help files (e.g. ?nycflights13::flights). For some of the exercises, you will need to know the units of certain numerical variables.

Exercise 1

For the exercises in this section, provide the answer as SQL queries together with their results.

  1. Show the carrier code, tail number, and destination for the flights originating from JFK, and limit the output to 10 rows

  2. Show all info for flights where the delay on arrivals were greater than 15 hours

  3. Show the id code and name of all the airports with ‘Island’ in their name

  4. Show the number of airports that do not have ‘Island’ in their name

  5. Show the average temperature for each day of the year where the humidity was higher than 50 the whole day

  6. Show the number of airports in the westmost time zone together with the associated time zone offset

Exercise 2

For the exercises in this section, provide the answer both in R and SQL and show the results once.

  1. Show the id code and name for each New York airport (i.e. the origins)

  2. Show the id code, name, and number of flights for the 5 most popular destinations (i.e. with most flights)

  3. For each of the origins, show the number of flights on the most humid day of the year in New York (defined as the day with the highest average humidity recorded across all three NY airports)

  4. For each origin, show the number of flights departing during hours where pressure wasn’t recorded at that airport

  5. Show the number of flights flown by planes that either have no matching records in the planes table or whose manufacturer is ‘EMBRAER’

  6. Show the id code and name for the carrier with the highest average delay on arrival to the destination for which the flights have the longest average air time among the airports lying between 1000 and 2000 feet in altitude

  7. Mad Maurice, a rich new yorker with too much free time, wishes to travel from EWR to JFK, two New York airports that are 21 miles apart, by flying from EWR to some outside destination and then from that destination to JFK. Assume that all flights listed in the flights table represent a return flight that arrives and returns on the same day. Assume furthermore that you can connect any flights with the same destination, as long as they’re flown on the same day (effectively ignoring the hour and minute variables).

    Suggest a travel date and route for Mad Maurice with the shortest possible distance; that is, show the month, day, connecting destination, and total distance for any such trip (the shortest trip can be flown on any of several days; show just one of these)

Exercise 3

NB: This section involves creating a table and adding data to it. To avoid duplicate data and errors, do not execute CREATE, DROP, or INSERT SQL code (or equivalent R code) in your notebook, but instead do it separately, once, in psql or pgAdmin.

For exercises asking to show data, provide the answer both in R and SQL and show the results once.

  1. Download the file pokemon.csv; it is a table containing various information on the first six generations of Pokémon related to typing and stats. Show the SQL CREATE script for creating a table called pokemon with appropriate column types

    NB: Remember to either create the table with the csor user as the owner or to grant SELECT privileges to csor afterwards, or you won’t be able to query on the table with the existing connection

  2. Show the code needed to populate the pokemon table with data from pokemon.csv in both R and SQL

  3. How many Pokémon has a Fairy typing?

  4. Pokémon with no secondary type are called single type Pokémon. Show the most common single type together with the rarest single type

  5. The queries for the previous two exercises can be sped up using indexes. Show the SQL CREATE script for such indexes

  6. Show the code needed to add the following rows to pokemon:

    Number Name Type 1 Type 2 Total HP Attack Defense Sp. Attack Sp. Defense Speed Generation Legendary
    722 Rowlet Grass Flying 320 68 55 55 50 50 42 7 false
    723 Dartrix Grass Flying 420 78 75 75 70 70 52 7 false
    724 Decidueye Grass Ghost 530 78 107 75 100 100 70 7 false

    in both R and SQL (do not run the code, neither in the notebook nor separately)

  7. Show the code needed to delete the pokemon table in both R and SQL

LS0tCnRpdGxlOiAiQ1NPUi1EQjogU2VsZiBTdHVkeSBFeGVyY2lzZSIKYXV0aG9yOiAiSmFudXMgVmFsYmVyZy1NYWRzZW4iCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdGhlbWU6IGNvc21vCiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiBmYWxzZQogICAgICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQogICAgbWRfZXh0ZW5zaW9uczogK2RlZmluaXRpb25fbGlzdHMKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgZWNobyA9IFRSVUUsCiAgZXJyb3IgPSBGQUxTRSwKICBtZXNzYWdlID0gRkFMU0UKKQpgYGAKCiMgQWJvdXQgdGhpcyBleGVyY2lzZQoKQW4gYXBwcm92ZWQgc29sdXRpb24gZm9yIHRoaXMgZXhlcmNpc2Ugc2V0IGlzIGEgcHJlcmVxdWlzaXRlIGZvciBwYXNzaW5nIHRoZSBjb3Vyc2UuClRvIGdldCBhcHByb3ZlZCwgeW91ciBzdWJtaXNzaW9uIG11c3QgZnVsZmlsIHRoZSBmb2xsb3dpbmcgcmVxdWlyZW1lbnRzIGluIGFkZGl0aW9uIHRvIGhhdmluZyBhIHNhdGlzZmFjdG9yeSBhbW91bnQgb2YgY29ycmVjdGx5IHNvbHZlZCBleGVyY2lzZXM6CgpGb3JtYXQKOiBSIE5vdGVib29rIChhIHNpbmdsZSwgc2VsZi1jb250YWluZWQgYC5uYi5odG1sYCBmaWxlLCBkZXNjcmliZWQgaW4gTGVjdHVyZSAzKQoKU3VibWlzc2lvbiBtZXRob2QKOiBTZW5kIGFuIGVtYWlsIHdpdGggdGhlIHN1YmplY3QgIkNTT1ItREIgaGFuZGluIiB0byBbamFudXNAbWF0aC5hYXUuZGtdKG1haWx0bzpqYW51c0BtYXRoLmFhdS5kaykgd2l0aCB5b3VyIG5hbWUgYW5kIHN0dWR5IG5vLiwgYW5kIGF0dGFjaCB0aGUgYC5uYi5odG1sYCBmaWxlIChub3QgdGhlIGAuUm1kYCBmaWxlKQoKRHVlIGRhdGUKOiBZb3VyIHN1Ym1pc3Npb24gbXVzdCBiZSBzdWJtaXR0ZWQgbm8gbGF0ZXIgdGhhbiAyMDE5LTA0LTI5VDA4OjAwCgoKIyMgR2V0IHN0YXJ0ZWQgd2l0aCB0aGUgUiBOb3RlYm9vawoKQ3JlYXRlIGEgZmlsZSBjYWxsZWQgYGhhbmRpbi5SbWRgIGFuZCBtYWtlIHN1cmUgaXQgaGFzIHRoZSBmb2xsb3dpbmcgZmllbGRzIGluIHRoZSBZQU1MIGZyb250bWF0dGVyOgoKYGBgeWFtbAotLS0KdGl0bGU6ICJDU09SLURCIEhhbmRpbiIKYXV0aG9yOiA8eW91ciBuYW1lPgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQotLS0KYGBgCgpJZiB5b3UncmUgdXNpbmcgUlN0dWRpbyAsIHlvdSBjYW4gY2xpY2sgKipGaWxlIOKGkiBOZXcgRmlsZSDihpIgUiBOb3RlYm9vayoqIHRvIGNyZWF0ZSBvbmUgZnJvbSBhIG1pbmltYWwgdGVtcGxhdGUuCkFsdGVybmF0aXZlbHksIHlvdSBjYW4gdXNlIHRoaXMgbm90ZWJvb2sgYXMgYSByZWZlcmVuY2UgcG9pbnQgLSBjbGljayB0aGUgKipDb2RlKiogYnV0dG9uIGluIHRoZSB0b3Agb2YgdGhlIHBhZ2UgYW5kIHNlbGVjdCAqKkRvd25sb2FkIFJtZCoqLgoKSW4gdGhlIGJlZ2lubmluZyBvZiB5b3VyIG5vdGVib29rLCBjcmVhdGUgYW4gUiBjaHVuayB0aGF0IGRlZmluZXMgYSBjb25uZWN0aW9uIHRvIHRoZSBgbnljZmxpZ2h0czEzYCBkYXRhYmFzZToKCmBgYHtyIHNldHVwLWNvbn0KbGlicmFyeShEQkkpCmxpYnJhcnkoZHBseXIpCgpjb24gPC0gZGJDb25uZWN0KAogIGRydiAgICAgID0gUlBvc3RncmVTUUw6OlBvc3RncmVTUUwoKSwKICBkYm5hbWUgICA9ICJueWNmbGlnaHRzMTMiLAogIHVzZXIgICAgID0gImNzb3IiLAogIHBhc3N3b3JkID0gImNzb3IiCikKa25pdHI6Om9wdHNfY2h1bmskc2V0KGNvbm5lY3Rpb24gPSAiY29uIikKYGBgCgoKIyMgVXNpbmcgUiBhbmQgU1FMIGNodW5rcwoKSW4gdGhlIGV4ZXJjaXNlcywgeW91IHdpbGwgYmUgYXNrZWQgdG8gc2hvdyBjb2RlIC0tIHNvbWUgaW4gUiwgc29tZSBpbiBTUUwsIHNvbWUgaW4gYm90aCAtLSBhbmQgc29tZXRpbWVzIHJlc3VsdHMuCgogICogKipXaGVuIGFza2VkIHRvIHNob3cgUiBjb2RlKio6IHNob3cgdGhlIGBkcGx5cmAgcGlwZWxpbmUgdXNlZCB0byBwcm9kdWNlIHRoZSByZXN1bHRzIGluIGFuIFIgY29kZSBjaHVuawogICAgICAodW5sZXNzIHRoZSBleGVyY2lzZSBhbHNvIGludm9sdmVzIG90aGVyIHRoaW5ncyB0aGFuIHNlbGVjdGluZyBkYXRhIChpLmUuIHdyaXRpbmcgb3IgZGVsZXRpbmcpLCBiZWNhdXNlIHRoZW4geW91IGFsc28gbmVlZCBgREJJYCBmdW5jdGlvbnMpCgogICogKipXaGVuIGFza2VkIHRvIHNob3cgU1FMIGNvZGUqKjogc2hvdyB0aGUgU1FMIHF1ZXJ5IHVzZWQgdG8gcHJvZHVjZSB0aGUgcmVzdWx0cyBpbiBhbiBTUUwgY29kZSBjaHVuawogICogKipXaGVuIGFza2VkIHRvIHNob3cgcmVzdWx0cyoqOiBldmFsdWF0aW5nIGFuIFIgb3IgU1FMIGNvZGUgY2h1bmsgdGhhdCByZXR1cm5zIGEgdGFibGUgcHJvZHVjZXMgYSBwYWdpbmF0ZWQgSFRNTCB0YWJsZQogICogKipXaGVuIGFza2VkIGZvciBib3RoIFIgYW5kIFNRTCBjb2RlIGFzIHdlbGwgYXMgcmVzdWx0cyoqOiBzaG93IGFuIFIgY2h1bmsgd2l0aCBgZHBseXJgIGNvZGUsIGFuZCBhbiBTUUwgY2h1bmssIGFuZCBldmFsdWF0ZSBfb25lIG9mIHRoZW1fIHRvIHNob3cgdGhlIHRhYmxlIG9mIHJlc3VsdHMKClRvIGhlbHAgeW91IHdpdGggdGhpcywgaGVyZSBpcyBhIHF1aWNrIG92ZXJ2aWV3IG9mIGhvdyB0byB1c2UgUiBhbmQgU1FMIGNvZGUgY2h1bmsgaGVhZGVycyBpbiBhbiBSIE5vdGVib29rOgoKCiAgKiBUbyBzaG93IHN5bnRheCBoaWdobGlnaHRlZCBSIGNvZGUgYW5kIHJ1biBpdCwgdXNlIHRoZSBjaHVuayBoZWFkZXI6CgogICAgPHByZT48Y29kZT5gYGB7cn0KICAgIDwvY29kZT48L3ByZT4KCiAgKiBUbyBzaG93ICBSIGNvZGUgd2l0aG91dCBydW5uaW5nIGl0LCBvbWl0IHRoZSBjdXJseSBicmFjZXM6CgogICAgPHByZT48Y29kZT5gYGByCiAgICA8L2NvZGU+PC9wcmU+CgogICogVG8gc2hvdyBhbiBTUUwgcXVlcnkgYW5kIHJ1biBpdCwgdXNlOgoKICAgIDxwcmU+PGNvZGU+YGBge3NxbCwgY29ubmVjdGlvbiA9IGNvbn0KICAgIDwvY29kZT48L3ByZT4KCiAgKiBUbyBzaG93IGFuIFNRTCBxdWVyeSB3aXRob3V0IHJ1bm5pbmcgaXQsIG9taXQgdGhlIGN1cmx5IGJyYWNlczoKCiAgICA8cHJlPjxjb2RlPmBgYHNxbAogICAgPC9jb2RlPjwvcHJlPgoKKipOQjoqKiBJZiB5b3UgdXNlIFJTdHVkaW8sIGV2ZW4gaWYgdGhlIGNodW5rIG9wdGlvbiBgY29ubmVjdGlvbiA9IGNvbmAgaXMgc2V0IGdsb2JhbGx5LCB5b3Ugc3RpbGwgaGF2ZSB0byBhZGQgaXQgdG8gZWFjaCBpbmRpdmlkdWFsIFNRTCBjaHVuayBmb3IgaXQgdG8gd29yayBwcm9wZXJseSB3aGVuIGV2YWx1YXRpbmcgdGhlIGNodW5rcyBpbnRlcmFjdGl2ZWx5LgpVc2luZyB0aGUgYnV0dG9uICoqSW5zZXJ0IOKGkiBTUUwqKiBpbiB0aGUgU291cmNlIHBhbmUgaW5zZXJ0cyBhIHRlbXBsYXRlIHdpdGggdGhpcyBvcHRpb24gYWxyZWFkeSB0eXBlZCBpbi4KCgojIyBHZW5lcmFsIGhpbnQKClJlbWVtYmVyIHRoYXQgZm9yIHRoZSBgbnljZmxpZ2h0czEzYCBkYXRhLCBkZXNjcmlwdGlvbnMgb2YgYWxsIHRoZSB2YXJpYWJsZXMgYXJlIGF2YWlsYWJsZSBpbiB0aGUgaGVscCBmaWxlcyAoZS5nLiBgP255Y2ZsaWdodHMxMzo6ZmxpZ2h0c2ApLgpGb3Igc29tZSBvZiB0aGUgZXhlcmNpc2VzLCB5b3Ugd2lsbCBuZWVkIHRvIGtub3cgdGhlIHVuaXRzIG9mIGNlcnRhaW4gbnVtZXJpY2FsIHZhcmlhYmxlcy4KCgojIEV4ZXJjaXNlIDEKCkZvciB0aGUgZXhlcmNpc2VzIGluIHRoaXMgc2VjdGlvbiwgcHJvdmlkZSB0aGUgYW5zd2VyIGFzIFNRTCBxdWVyaWVzIHRvZ2V0aGVyIHdpdGggdGhlaXIgcmVzdWx0cy4KCiAgMS4gU2hvdyB0aGUgY2FycmllciBjb2RlLCB0YWlsIG51bWJlciwgYW5kIGRlc3RpbmF0aW9uIGZvciB0aGUgZmxpZ2h0cyBvcmlnaW5hdGluZyBmcm9tIEpGSywgYW5kIGxpbWl0IHRoZSBvdXRwdXQgdG8gMTAgcm93cwoKICAyLiBTaG93IGFsbCBpbmZvIGZvciBmbGlnaHRzIHdoZXJlIHRoZSBkZWxheSBvbiBhcnJpdmFscyB3ZXJlIGdyZWF0ZXIgdGhhbiAxNSBob3VycwoKICAzLiBTaG93IHRoZSBpZCBjb2RlIGFuZCBuYW1lIG9mIGFsbCB0aGUgYWlycG9ydHMgd2l0aCAnSXNsYW5kJyBpbiB0aGVpciBuYW1lCgogIDQuIFNob3cgdGhlIG51bWJlciBvZiBhaXJwb3J0cyB0aGF0IGRvIG5vdCBoYXZlICdJc2xhbmQnIGluIHRoZWlyIG5hbWUKCiAgNS4gU2hvdyB0aGUgYXZlcmFnZSB0ZW1wZXJhdHVyZSBmb3IgZWFjaCBkYXkgb2YgdGhlIHllYXIgd2hlcmUgdGhlIGh1bWlkaXR5IHdhcyBoaWdoZXIgdGhhbiA1MCB0aGUgd2hvbGUgZGF5CgogIDYuIFNob3cgdGhlIG51bWJlciBvZiBhaXJwb3J0cyBpbiB0aGUgd2VzdG1vc3QgdGltZSB6b25lIHRvZ2V0aGVyIHdpdGggdGhlIGFzc29jaWF0ZWQgdGltZSB6b25lIG9mZnNldAoKCiMgRXhlcmNpc2UgMgoKRm9yIHRoZSBleGVyY2lzZXMgaW4gdGhpcyBzZWN0aW9uLCBwcm92aWRlIHRoZSBhbnN3ZXIgYm90aCBpbiBSIGFuZCBTUUwgYW5kIHNob3cgdGhlIHJlc3VsdHMgb25jZS4KCiAgMS4gU2hvdyB0aGUgaWQgY29kZSBhbmQgbmFtZSBmb3IgZWFjaCBOZXcgWW9yayBhaXJwb3J0IChpLmUuIHRoZSBvcmlnaW5zKQoKICAyLiBTaG93IHRoZSBpZCBjb2RlLCBuYW1lLCBhbmQgbnVtYmVyIG9mIGZsaWdodHMgZm9yIHRoZSA1IG1vc3QgcG9wdWxhciBkZXN0aW5hdGlvbnMgKGkuZS4gd2l0aCBtb3N0IGZsaWdodHMpCgogIDMuIEZvciBlYWNoIG9mIHRoZSBvcmlnaW5zLCBzaG93IHRoZSBudW1iZXIgb2YgZmxpZ2h0cyBvbiB0aGUgbW9zdCBodW1pZCBkYXkgb2YgdGhlIHllYXIgaW4gTmV3IFlvcmsgKGRlZmluZWQgYXMgdGhlIGRheSB3aXRoIHRoZSBoaWdoZXN0IGF2ZXJhZ2UgaHVtaWRpdHkgcmVjb3JkZWQgYWNyb3NzIGFsbCB0aHJlZSBOWSBhaXJwb3J0cykKCiAgNC4gRm9yIGVhY2ggb3JpZ2luLCBzaG93IHRoZSBudW1iZXIgb2YgZmxpZ2h0cyBkZXBhcnRpbmcgZHVyaW5nIGhvdXJzIHdoZXJlIHByZXNzdXJlIHdhc24ndCByZWNvcmRlZCBhdCB0aGF0IGFpcnBvcnQKCiAgNS4gU2hvdyB0aGUgbnVtYmVyIG9mIGZsaWdodHMgZmxvd24gYnkgcGxhbmVzIHRoYXQgZWl0aGVyIGhhdmUgbm8gbWF0Y2hpbmcgcmVjb3JkcyBpbiB0aGUgYHBsYW5lc2AgdGFibGUgb3Igd2hvc2UgbWFudWZhY3R1cmVyIGlzICdFTUJSQUVSJwoKICA2LiBTaG93IHRoZSBpZCBjb2RlIGFuZCBuYW1lIGZvciB0aGUgY2FycmllciB3aXRoIHRoZSBoaWdoZXN0IGF2ZXJhZ2UgZGVsYXkgb24gYXJyaXZhbCB0byB0aGUgZGVzdGluYXRpb24gZm9yIHdoaWNoIHRoZSBmbGlnaHRzIGhhdmUgdGhlIGxvbmdlc3QgYXZlcmFnZSBhaXIgdGltZSBhbW9uZyB0aGUgYWlycG9ydHMgbHlpbmcgYmV0d2VlbiAxMDAwIGFuZCAyMDAwIGZlZXQgaW4gYWx0aXR1ZGUKCiAgNy4gTWFkIE1hdXJpY2UsIGEgcmljaCBuZXcgeW9ya2VyIHdpdGggdG9vIG11Y2ggZnJlZSB0aW1lLCB3aXNoZXMgdG8gdHJhdmVsIGZyb20gRVdSIHRvIEpGSywgdHdvIE5ldyBZb3JrIGFpcnBvcnRzIHRoYXQgYXJlIDIxIG1pbGVzIGFwYXJ0LCBieSBmbHlpbmcgZnJvbSBFV1IgdG8gc29tZSBvdXRzaWRlIGRlc3RpbmF0aW9uIGFuZCB0aGVuIGZyb20gdGhhdCBkZXN0aW5hdGlvbiB0byBKRksuCiAgQXNzdW1lIHRoYXQgYWxsIGZsaWdodHMgbGlzdGVkIGluIHRoZSBgZmxpZ2h0c2AgdGFibGUgcmVwcmVzZW50IGEgcmV0dXJuIGZsaWdodCB0aGF0IGFycml2ZXMgYW5kIHJldHVybnMgb24gdGhlIHNhbWUgZGF5LgogIEFzc3VtZSBmdXJ0aGVybW9yZSB0aGF0IHlvdSBjYW4gY29ubmVjdCBhbnkgZmxpZ2h0cyB3aXRoIHRoZSBzYW1lIGRlc3RpbmF0aW9uLCBhcyBsb25nIGFzIHRoZXkncmUgZmxvd24gb24gdGhlIHNhbWUgZGF5IChlZmZlY3RpdmVseSBpZ25vcmluZyB0aGUgYGhvdXJgIGFuZCBgbWludXRlYCB2YXJpYWJsZXMpLgoKICAgIFN1Z2dlc3QgYSB0cmF2ZWwgZGF0ZSBhbmQgcm91dGUgZm9yIE1hZCBNYXVyaWNlIHdpdGggdGhlIHNob3J0ZXN0IHBvc3NpYmxlIGRpc3RhbmNlOwogICAgdGhhdCBpcywgc2hvdyB0aGUgbW9udGgsIGRheSwgY29ubmVjdGluZyBkZXN0aW5hdGlvbiwgYW5kIHRvdGFsIGRpc3RhbmNlIGZvciBfYW55XyBzdWNoIHRyaXAgKHRoZSBzaG9ydGVzdCB0cmlwIGNhbiBiZSBmbG93biBvbiBhbnkgb2Ygc2V2ZXJhbCBkYXlzOyBzaG93IGp1c3Qgb25lIG9mIHRoZXNlKQoKCgojIEV4ZXJjaXNlIDMKCioqTkI6KiogVGhpcyBzZWN0aW9uIGludm9sdmVzIGNyZWF0aW5nIGEgdGFibGUgYW5kIGFkZGluZyBkYXRhIHRvIGl0LgpUbyBhdm9pZCBkdXBsaWNhdGUgZGF0YSBhbmQgZXJyb3JzLCBkbyBfbm90XyBleGVjdXRlIGBDUkVBVEVgLCBgRFJPUGAsIG9yIGBJTlNFUlRgIFNRTCBjb2RlIChvciBlcXVpdmFsZW50IFIgY29kZSkgaW4geW91ciBub3RlYm9vaywgYnV0IGluc3RlYWQgZG8gaXQgc2VwYXJhdGVseSwgb25jZSwgaW4gcHNxbCBvciBwZ0FkbWluLgoKRm9yIGV4ZXJjaXNlcyBhc2tpbmcgdG8gc2hvdyBfZGF0YV8sIHByb3ZpZGUgdGhlIGFuc3dlciBib3RoIGluIFIgYW5kIFNRTCBhbmQgc2hvdyB0aGUgcmVzdWx0cyBvbmNlLgoKICAxLiBEb3dubG9hZCB0aGUgZmlsZSBbYHBva2Vtb24uY3N2YF0ocG9rZW1vbi5jc3YpOyBpdCBpcyBhIHRhYmxlIGNvbnRhaW5pbmcgdmFyaW91cyBpbmZvcm1hdGlvbiBvbiB0aGUgZmlyc3Qgc2l4IGdlbmVyYXRpb25zIG9mIFBva8OpbW9uIHJlbGF0ZWQgdG8gdHlwaW5nIGFuZCBzdGF0cy4KICBTaG93IHRoZSBTUUwgYENSRUFURWAgc2NyaXB0IGZvciBjcmVhdGluZyBhIHRhYmxlIGNhbGxlZCBgcG9rZW1vbmAgd2l0aCBhcHByb3ByaWF0ZSBjb2x1bW4gdHlwZXMKCiAgICAqKk5COioqIFJlbWVtYmVyIHRvIGVpdGhlciBjcmVhdGUgdGhlIHRhYmxlIHdpdGggdGhlIGBjc29yYCB1c2VyIGFzIHRoZSBvd25lciBvciB0byBncmFudCBgU0VMRUNUYCBwcml2aWxlZ2VzIHRvIGBjc29yYCBhZnRlcndhcmRzLCBvciB5b3Ugd29uJ3QgYmUgYWJsZSB0byBxdWVyeSBvbiB0aGUgdGFibGUgd2l0aCB0aGUgZXhpc3RpbmcgY29ubmVjdGlvbgoKICAyLiBTaG93IHRoZSBjb2RlIG5lZWRlZCB0byBwb3B1bGF0ZSB0aGUgYHBva2Vtb25gIHRhYmxlIHdpdGggZGF0YSBmcm9tIGBwb2tlbW9uLmNzdmAgaW4gYm90aCBSIGFuZCBTUUwKCiAgMy4gSG93IG1hbnkgUG9rw6ltb24gaGFzIGEgRmFpcnkgdHlwaW5nPwoKICA0LiBQb2vDqW1vbiB3aXRoIG5vIHNlY29uZGFyeSB0eXBlIGFyZSBjYWxsZWQgX3NpbmdsZSB0eXBlXyBQb2vDqW1vbi4gU2hvdyB0aGUgbW9zdCBjb21tb24gc2luZ2xlIHR5cGUgdG9nZXRoZXIgd2l0aCB0aGUgcmFyZXN0IHNpbmdsZSB0eXBlCgogIDUuIFRoZSBxdWVyaWVzIGZvciB0aGUgcHJldmlvdXMgdHdvIGV4ZXJjaXNlcyBjYW4gYmUgc3BlZCB1cCB1c2luZyBpbmRleGVzLiBTaG93IHRoZSBTUUwgYENSRUFURWAgc2NyaXB0IGZvciBzdWNoIGluZGV4ZXMKCiAgNi4gU2hvdyB0aGUgY29kZSBuZWVkZWQgdG8gYWRkIHRoZSBmb2xsb3dpbmcgcm93cyB0byBgcG9rZW1vbmA6CgogICAgTnVtYmVyIHwgTmFtZSB8IFR5cGUgMSB8IFR5cGUgMiB8IFRvdGFsIHwgSFAgfCBBdHRhY2sgfCBEZWZlbnNlIHwgU3AuIEF0dGFjayB8IFNwLiBEZWZlbnNlIHwgU3BlZWQgfCBHZW5lcmF0aW9uIHwgTGVnZW5kYXJ5CiAgICAtLS0gfCAtLS0gfCAtLS0gfCAtLS0gfCAtLS0gfCAtLS0gfCAtLS0gfCAtLS0gfCAtLS0gfCAtLS0gfCAtLS0gfCAtLS0gfCAtLS0KICAgIDcyMiB8IFJvd2xldCB8IEdyYXNzIHwgRmx5aW5nIHwgMzIwIHwgNjggfCA1NSB8IDU1IHwgNTAgfCA1MCB8IDQyIHwgNyB8IGZhbHNlCiAgICA3MjMgfCBEYXJ0cml4IHwgR3Jhc3MgfCBGbHlpbmcgfCA0MjAgfCA3OCB8IDc1IHwgNzUgfCA3MCB8IDcwIHwgNTIgfCA3IHwgZmFsc2UKICAgIDcyNCB8IERlY2lkdWV5ZSB8IEdyYXNzIHwgR2hvc3QgfCA1MzAgfCA3OCB8IDEwNyB8IDc1IHwgMTAwIHwgMTAwIHwgNzAgfCA3IHwgZmFsc2UKCiAgICBpbiBib3RoIFIgYW5kIFNRTCAoZG8gbm90IHJ1biB0aGUgY29kZSwgbmVpdGhlciBpbiB0aGUgbm90ZWJvb2sgbm9yIHNlcGFyYXRlbHkpCgogIDcuIFNob3cgdGhlIGNvZGUgbmVlZGVkIHRvIGRlbGV0ZSB0aGUgYHBva2Vtb25gIHRhYmxlIGluIGJvdGggUiBhbmQgU1FMCgoKYGBge3IgY2xlYW51cCwgaW5jbHVkZSA9IEZBTFNFfQpkYkRpc2Nvbm5lY3QoY29uKQpgYGAK