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.
Show the carrier code, tail number, and destination for the flights originating from JFK, and limit the output to 10 rows
Show all info for flights where the delay on arrivals were greater than 15 hours
Show the id code and name of all the airports with ‘Island’ in their name
Show the number of airports that do not have ‘Island’ in their name
Show the average temperature for each day of the year where the humidity was higher than 50 the whole day
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.
Show the id code and name for each New York airport (i.e. the origins)
Show the id code, name, and number of flights for the 5 most popular destinations (i.e. with most flights)
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)
For each origin, show the number of flights departing during hours where pressure wasn’t recorded at that airport
Show the number of flights flown by planes that either have no matching records in the planes
table or whose manufacturer is ‘EMBRAER’
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
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.
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
Show the code needed to populate the pokemon
table with data from pokemon.csv
in both R and SQL
How many Pokémon has a Fairy typing?
Pokémon with no secondary type are called single type Pokémon. Show the most common single type together with the rarest single type
The queries for the previous two exercises can be sped up using indexes. Show the SQL CREATE
script for such indexes
Show the code needed to add the following rows to pokemon
:
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)
Show the code needed to delete the pokemon
table in both R and SQL
LS0tCnRpdGxlOiAiQ1NPUi1EQjogU2VsZiBTdHVkeSBFeGVyY2lzZSIKYXV0aG9yOiAiSmFudXMgVmFsYmVyZy1NYWRzZW4iCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdGhlbWU6IGNvc21vCiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiBmYWxzZQogICAgICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQogICAgbWRfZXh0ZW5zaW9uczogK2RlZmluaXRpb25fbGlzdHMKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgZWNobyA9IFRSVUUsCiAgZXJyb3IgPSBGQUxTRSwKICBtZXNzYWdlID0gRkFMU0UKKQpgYGAKCiMgQWJvdXQgdGhpcyBleGVyY2lzZQoKQW4gYXBwcm92ZWQgc29sdXRpb24gZm9yIHRoaXMgZXhlcmNpc2Ugc2V0IGlzIGEgcHJlcmVxdWlzaXRlIGZvciBwYXNzaW5nIHRoZSBjb3Vyc2UuClRvIGdldCBhcHByb3ZlZCwgeW91ciBzdWJtaXNzaW9uIG11c3QgZnVsZmlsIHRoZSBmb2xsb3dpbmcgcmVxdWlyZW1lbnRzIGluIGFkZGl0aW9uIHRvIGhhdmluZyBhIHNhdGlzZmFjdG9yeSBhbW91bnQgb2YgY29ycmVjdGx5IHNvbHZlZCBleGVyY2lzZXM6CgpGb3JtYXQKOiBSIE5vdGVib29rIChhIHNpbmdsZSwgc2VsZi1jb250YWluZWQgYC5uYi5odG1sYCBmaWxlLCBkZXNjcmliZWQgaW4gTGVjdHVyZSAzKQoKU3VibWlzc2lvbiBtZXRob2QKOiBTZW5kIGFuIGVtYWlsIHdpdGggdGhlIHN1YmplY3QgIkNTT1ItREIgaGFuZGluIiB0byBbamFudXNAbWF0aC5hYXUuZGtdKG1haWx0bzpqYW51c0BtYXRoLmFhdS5kaykgd2l0aCB5b3VyIG5hbWUgYW5kIHN0dWR5IG5vLiwgYW5kIGF0dGFjaCB0aGUgYC5uYi5odG1sYCBmaWxlIChub3QgdGhlIGAuUm1kYCBmaWxlKQoKRHVlIGRhdGUKOiBZb3VyIHN1Ym1pc3Npb24gbXVzdCBiZSBzdWJtaXR0ZWQgbm8gbGF0ZXIgdGhhbiAyMDE5LTA0LTI5VDA4OjAwCgoKIyMgR2V0IHN0YXJ0ZWQgd2l0aCB0aGUgUiBOb3RlYm9vawoKQ3JlYXRlIGEgZmlsZSBjYWxsZWQgYGhhbmRpbi5SbWRgIGFuZCBtYWtlIHN1cmUgaXQgaGFzIHRoZSBmb2xsb3dpbmcgZmllbGRzIGluIHRoZSBZQU1MIGZyb250bWF0dGVyOgoKYGBgeWFtbAotLS0KdGl0bGU6ICJDU09SLURCIEhhbmRpbiIKYXV0aG9yOiA8eW91ciBuYW1lPgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQotLS0KYGBgCgpJZiB5b3UncmUgdXNpbmcgUlN0dWRpbyAsIHlvdSBjYW4gY2xpY2sgKipGaWxlIOKGkiBOZXcgRmlsZSDihpIgUiBOb3RlYm9vayoqIHRvIGNyZWF0ZSBvbmUgZnJvbSBhIG1pbmltYWwgdGVtcGxhdGUuCkFsdGVybmF0aXZlbHksIHlvdSBjYW4gdXNlIHRoaXMgbm90ZWJvb2sgYXMgYSByZWZlcmVuY2UgcG9pbnQgLSBjbGljayB0aGUgKipDb2RlKiogYnV0dG9uIGluIHRoZSB0b3Agb2YgdGhlIHBhZ2UgYW5kIHNlbGVjdCAqKkRvd25sb2FkIFJtZCoqLgoKSW4gdGhlIGJlZ2lubmluZyBvZiB5b3VyIG5vdGVib29rLCBjcmVhdGUgYW4gUiBjaHVuayB0aGF0IGRlZmluZXMgYSBjb25uZWN0aW9uIHRvIHRoZSBgbnljZmxpZ2h0czEzYCBkYXRhYmFzZToKCmBgYHtyIHNldHVwLWNvbn0KbGlicmFyeShEQkkpCmxpYnJhcnkoZHBseXIpCgpjb24gPC0gZGJDb25uZWN0KAogIGRydiAgICAgID0gUlBvc3RncmVTUUw6OlBvc3RncmVTUUwoKSwKICBkYm5hbWUgICA9ICJueWNmbGlnaHRzMTMiLAogIHVzZXIgICAgID0gImNzb3IiLAogIHBhc3N3b3JkID0gImNzb3IiCikKa25pdHI6Om9wdHNfY2h1bmskc2V0KGNvbm5lY3Rpb24gPSAiY29uIikKYGBgCgoKIyMgVXNpbmcgUiBhbmQgU1FMIGNodW5rcwoKSW4gdGhlIGV4ZXJjaXNlcywgeW91IHdpbGwgYmUgYXNrZWQgdG8gc2hvdyBjb2RlIC0tIHNvbWUgaW4gUiwgc29tZSBpbiBTUUwsIHNvbWUgaW4gYm90aCAtLSBhbmQgc29tZXRpbWVzIHJlc3VsdHMuCgogICogKipXaGVuIGFza2VkIHRvIHNob3cgUiBjb2RlKio6IHNob3cgdGhlIGBkcGx5cmAgcGlwZWxpbmUgdXNlZCB0byBwcm9kdWNlIHRoZSByZXN1bHRzIGluIGFuIFIgY29kZSBjaHVuawogICAgICAodW5sZXNzIHRoZSBleGVyY2lzZSBhbHNvIGludm9sdmVzIG90aGVyIHRoaW5ncyB0aGFuIHNlbGVjdGluZyBkYXRhIChpLmUuIHdyaXRpbmcgb3IgZGVsZXRpbmcpLCBiZWNhdXNlIHRoZW4geW91IGFsc28gbmVlZCBgREJJYCBmdW5jdGlvbnMpCgogICogKipXaGVuIGFza2VkIHRvIHNob3cgU1FMIGNvZGUqKjogc2hvdyB0aGUgU1FMIHF1ZXJ5IHVzZWQgdG8gcHJvZHVjZSB0aGUgcmVzdWx0cyBpbiBhbiBTUUwgY29kZSBjaHVuawogICogKipXaGVuIGFza2VkIHRvIHNob3cgcmVzdWx0cyoqOiBldmFsdWF0aW5nIGFuIFIgb3IgU1FMIGNvZGUgY2h1bmsgdGhhdCByZXR1cm5zIGEgdGFibGUgcHJvZHVjZXMgYSBwYWdpbmF0ZWQgSFRNTCB0YWJsZQogICogKipXaGVuIGFza2VkIGZvciBib3RoIFIgYW5kIFNRTCBjb2RlIGFzIHdlbGwgYXMgcmVzdWx0cyoqOiBzaG93IGFuIFIgY2h1bmsgd2l0aCBgZHBseXJgIGNvZGUsIGFuZCBhbiBTUUwgY2h1bmssIGFuZCBldmFsdWF0ZSBfb25lIG9mIHRoZW1fIHRvIHNob3cgdGhlIHRhYmxlIG9mIHJlc3VsdHMKClRvIGhlbHAgeW91IHdpdGggdGhpcywgaGVyZSBpcyBhIHF1aWNrIG92ZXJ2aWV3IG9mIGhvdyB0byB1c2UgUiBhbmQgU1FMIGNvZGUgY2h1bmsgaGVhZGVycyBpbiBhbiBSIE5vdGVib29rOgoKCiAgKiBUbyBzaG93IHN5bnRheCBoaWdobGlnaHRlZCBSIGNvZGUgYW5kIHJ1biBpdCwgdXNlIHRoZSBjaHVuayBoZWFkZXI6CgogICAgPHByZT48Y29kZT5gYGB7cn0KICAgIDwvY29kZT48L3ByZT4KCiAgKiBUbyBzaG93ICBSIGNvZGUgd2l0aG91dCBydW5uaW5nIGl0LCBvbWl0IHRoZSBjdXJseSBicmFjZXM6CgogICAgPHByZT48Y29kZT5gYGByCiAgICA8L2NvZGU+PC9wcmU+CgogICogVG8gc2hvdyBhbiBTUUwgcXVlcnkgYW5kIHJ1biBpdCwgdXNlOgoKICAgIDxwcmU+PGNvZGU+YGBge3NxbCwgY29ubmVjdGlvbiA9IGNvbn0KICAgIDwvY29kZT48L3ByZT4KCiAgKiBUbyBzaG93IGFuIFNRTCBxdWVyeSB3aXRob3V0IHJ1bm5pbmcgaXQsIG9taXQgdGhlIGN1cmx5IGJyYWNlczoKCiAgICA8cHJlPjxjb2RlPmBgYHNxbAogICAgPC9jb2RlPjwvcHJlPgoKKipOQjoqKiBJZiB5b3UgdXNlIFJTdHVkaW8sIGV2ZW4gaWYgdGhlIGNodW5rIG9wdGlvbiBgY29ubmVjdGlvbiA9IGNvbmAgaXMgc2V0IGdsb2JhbGx5LCB5b3Ugc3RpbGwgaGF2ZSB0byBhZGQgaXQgdG8gZWFjaCBpbmRpdmlkdWFsIFNRTCBjaHVuayBmb3IgaXQgdG8gd29yayBwcm9wZXJseSB3aGVuIGV2YWx1YXRpbmcgdGhlIGNodW5rcyBpbnRlcmFjdGl2ZWx5LgpVc2luZyB0aGUgYnV0dG9uICoqSW5zZXJ0IOKGkiBTUUwqKiBpbiB0aGUgU291cmNlIHBhbmUgaW5zZXJ0cyBhIHRlbXBsYXRlIHdpdGggdGhpcyBvcHRpb24gYWxyZWFkeSB0eXBlZCBpbi4KCgojIyBHZW5lcmFsIGhpbnQKClJlbWVtYmVyIHRoYXQgZm9yIHRoZSBgbnljZmxpZ2h0czEzYCBkYXRhLCBkZXNjcmlwdGlvbnMgb2YgYWxsIHRoZSB2YXJpYWJsZXMgYXJlIGF2YWlsYWJsZSBpbiB0aGUgaGVscCBmaWxlcyAoZS5nLiBgP255Y2ZsaWdodHMxMzo6ZmxpZ2h0c2ApLgpGb3Igc29tZSBvZiB0aGUgZXhlcmNpc2VzLCB5b3Ugd2lsbCBuZWVkIHRvIGtub3cgdGhlIHVuaXRzIG9mIGNlcnRhaW4gbnVtZXJpY2FsIHZhcmlhYmxlcy4KCgojIEV4ZXJjaXNlIDEKCkZvciB0aGUgZXhlcmNpc2VzIGluIHRoaXMgc2VjdGlvbiwgcHJvdmlkZSB0aGUgYW5zd2VyIGFzIFNRTCBxdWVyaWVzIHRvZ2V0aGVyIHdpdGggdGhlaXIgcmVzdWx0cy4KCiAgMS4gU2hvdyB0aGUgY2FycmllciBjb2RlLCB0YWlsIG51bWJlciwgYW5kIGRlc3RpbmF0aW9uIGZvciB0aGUgZmxpZ2h0cyBvcmlnaW5hdGluZyBmcm9tIEpGSywgYW5kIGxpbWl0IHRoZSBvdXRwdXQgdG8gMTAgcm93cwoKICAyLiBTaG93IGFsbCBpbmZvIGZvciBmbGlnaHRzIHdoZXJlIHRoZSBkZWxheSBvbiBhcnJpdmFscyB3ZXJlIGdyZWF0ZXIgdGhhbiAxNSBob3VycwoKICAzLiBTaG93IHRoZSBpZCBjb2RlIGFuZCBuYW1lIG9mIGFsbCB0aGUgYWlycG9ydHMgd2l0aCAnSXNsYW5kJyBpbiB0aGVpciBuYW1lCgogIDQuIFNob3cgdGhlIG51bWJlciBvZiBhaXJwb3J0cyB0aGF0IGRvIG5vdCBoYXZlICdJc2xhbmQnIGluIHRoZWlyIG5hbWUKCiAgNS4gU2hvdyB0aGUgYXZlcmFnZSB0ZW1wZXJhdHVyZSBmb3IgZWFjaCBkYXkgb2YgdGhlIHllYXIgd2hlcmUgdGhlIGh1bWlkaXR5IHdhcyBoaWdoZXIgdGhhbiA1MCB0aGUgd2hvbGUgZGF5CgogIDYuIFNob3cgdGhlIG51bWJlciBvZiBhaXJwb3J0cyBpbiB0aGUgd2VzdG1vc3QgdGltZSB6b25lIHRvZ2V0aGVyIHdpdGggdGhlIGFzc29jaWF0ZWQgdGltZSB6b25lIG9mZnNldAoKCiMgRXhlcmNpc2UgMgoKRm9yIHRoZSBleGVyY2lzZXMgaW4gdGhpcyBzZWN0aW9uLCBwcm92aWRlIHRoZSBhbnN3ZXIgYm90aCBpbiBSIGFuZCBTUUwgYW5kIHNob3cgdGhlIHJlc3VsdHMgb25jZS4KCiAgMS4gU2hvdyB0aGUgaWQgY29kZSBhbmQgbmFtZSBmb3IgZWFjaCBOZXcgWW9yayBhaXJwb3J0IChpLmUuIHRoZSBvcmlnaW5zKQoKICAyLiBTaG93IHRoZSBpZCBjb2RlLCBuYW1lLCBhbmQgbnVtYmVyIG9mIGZsaWdodHMgZm9yIHRoZSA1IG1vc3QgcG9wdWxhciBkZXN0aW5hdGlvbnMgKGkuZS4gd2l0aCBtb3N0IGZsaWdodHMpCgogIDMuIEZvciBlYWNoIG9mIHRoZSBvcmlnaW5zLCBzaG93IHRoZSBudW1iZXIgb2YgZmxpZ2h0cyBvbiB0aGUgbW9zdCBodW1pZCBkYXkgb2YgdGhlIHllYXIgaW4gTmV3IFlvcmsgKGRlZmluZWQgYXMgdGhlIGRheSB3aXRoIHRoZSBoaWdoZXN0IGF2ZXJhZ2UgaHVtaWRpdHkgcmVjb3JkZWQgYWNyb3NzIGFsbCB0aHJlZSBOWSBhaXJwb3J0cykKCiAgNC4gRm9yIGVhY2ggb3JpZ2luLCBzaG93IHRoZSBudW1iZXIgb2YgZmxpZ2h0cyBkZXBhcnRpbmcgZHVyaW5nIGhvdXJzIHdoZXJlIHByZXNzdXJlIHdhc24ndCByZWNvcmRlZCBhdCB0aGF0IGFpcnBvcnQKCiAgNS4gU2hvdyB0aGUgbnVtYmVyIG9mIGZsaWdodHMgZmxvd24gYnkgcGxhbmVzIHRoYXQgZWl0aGVyIGhhdmUgbm8gbWF0Y2hpbmcgcmVjb3JkcyBpbiB0aGUgYHBsYW5lc2AgdGFibGUgb3Igd2hvc2UgbWFudWZhY3R1cmVyIGlzICdFTUJSQUVSJwoKICA2LiBTaG93IHRoZSBpZCBjb2RlIGFuZCBuYW1lIGZvciB0aGUgY2FycmllciB3aXRoIHRoZSBoaWdoZXN0IGF2ZXJhZ2UgZGVsYXkgb24gYXJyaXZhbCB0byB0aGUgZGVzdGluYXRpb24gZm9yIHdoaWNoIHRoZSBmbGlnaHRzIGhhdmUgdGhlIGxvbmdlc3QgYXZlcmFnZSBhaXIgdGltZSBhbW9uZyB0aGUgYWlycG9ydHMgbHlpbmcgYmV0d2VlbiAxMDAwIGFuZCAyMDAwIGZlZXQgaW4gYWx0aXR1ZGUKCiAgNy4gTWFkIE1hdXJpY2UsIGEgcmljaCBuZXcgeW9ya2VyIHdpdGggdG9vIG11Y2ggZnJlZSB0aW1lLCB3aXNoZXMgdG8gdHJhdmVsIGZyb20gRVdSIHRvIEpGSywgdHdvIE5ldyBZb3JrIGFpcnBvcnRzIHRoYXQgYXJlIDIxIG1pbGVzIGFwYXJ0LCBieSBmbHlpbmcgZnJvbSBFV1IgdG8gc29tZSBvdXRzaWRlIGRlc3RpbmF0aW9uIGFuZCB0aGVuIGZyb20gdGhhdCBkZXN0aW5hdGlvbiB0byBKRksuCiAgQXNzdW1lIHRoYXQgYWxsIGZsaWdodHMgbGlzdGVkIGluIHRoZSBgZmxpZ2h0c2AgdGFibGUgcmVwcmVzZW50IGEgcmV0dXJuIGZsaWdodCB0aGF0IGFycml2ZXMgYW5kIHJldHVybnMgb24gdGhlIHNhbWUgZGF5LgogIEFzc3VtZSBmdXJ0aGVybW9yZSB0aGF0IHlvdSBjYW4gY29ubmVjdCBhbnkgZmxpZ2h0cyB3aXRoIHRoZSBzYW1lIGRlc3RpbmF0aW9uLCBhcyBsb25nIGFzIHRoZXkncmUgZmxvd24gb24gdGhlIHNhbWUgZGF5IChlZmZlY3RpdmVseSBpZ25vcmluZyB0aGUgYGhvdXJgIGFuZCBgbWludXRlYCB2YXJpYWJsZXMpLgoKICAgIFN1Z2dlc3QgYSB0cmF2ZWwgZGF0ZSBhbmQgcm91dGUgZm9yIE1hZCBNYXVyaWNlIHdpdGggdGhlIHNob3J0ZXN0IHBvc3NpYmxlIGRpc3RhbmNlOwogICAgdGhhdCBpcywgc2hvdyB0aGUgbW9udGgsIGRheSwgY29ubmVjdGluZyBkZXN0aW5hdGlvbiwgYW5kIHRvdGFsIGRpc3RhbmNlIGZvciBfYW55XyBzdWNoIHRyaXAgKHRoZSBzaG9ydGVzdCB0cmlwIGNhbiBiZSBmbG93biBvbiBhbnkgb2Ygc2V2ZXJhbCBkYXlzOyBzaG93IGp1c3Qgb25lIG9mIHRoZXNlKQoKCgojIEV4ZXJjaXNlIDMKCioqTkI6KiogVGhpcyBzZWN0aW9uIGludm9sdmVzIGNyZWF0aW5nIGEgdGFibGUgYW5kIGFkZGluZyBkYXRhIHRvIGl0LgpUbyBhdm9pZCBkdXBsaWNhdGUgZGF0YSBhbmQgZXJyb3JzLCBkbyBfbm90XyBleGVjdXRlIGBDUkVBVEVgLCBgRFJPUGAsIG9yIGBJTlNFUlRgIFNRTCBjb2RlIChvciBlcXVpdmFsZW50IFIgY29kZSkgaW4geW91ciBub3RlYm9vaywgYnV0IGluc3RlYWQgZG8gaXQgc2VwYXJhdGVseSwgb25jZSwgaW4gcHNxbCBvciBwZ0FkbWluLgoKRm9yIGV4ZXJjaXNlcyBhc2tpbmcgdG8gc2hvdyBfZGF0YV8sIHByb3ZpZGUgdGhlIGFuc3dlciBib3RoIGluIFIgYW5kIFNRTCBhbmQgc2hvdyB0aGUgcmVzdWx0cyBvbmNlLgoKICAxLiBEb3dubG9hZCB0aGUgZmlsZSBbYHBva2Vtb24uY3N2YF0ocG9rZW1vbi5jc3YpOyBpdCBpcyBhIHRhYmxlIGNvbnRhaW5pbmcgdmFyaW91cyBpbmZvcm1hdGlvbiBvbiB0aGUgZmlyc3Qgc2l4IGdlbmVyYXRpb25zIG9mIFBva8OpbW9uIHJlbGF0ZWQgdG8gdHlwaW5nIGFuZCBzdGF0cy4KICBTaG93IHRoZSBTUUwgYENSRUFURWAgc2NyaXB0IGZvciBjcmVhdGluZyBhIHRhYmxlIGNhbGxlZCBgcG9rZW1vbmAgd2l0aCBhcHByb3ByaWF0ZSBjb2x1bW4gdHlwZXMKCiAgICAqKk5COioqIFJlbWVtYmVyIHRvIGVpdGhlciBjcmVhdGUgdGhlIHRhYmxlIHdpdGggdGhlIGBjc29yYCB1c2VyIGFzIHRoZSBvd25lciBvciB0byBncmFudCBgU0VMRUNUYCBwcml2aWxlZ2VzIHRvIGBjc29yYCBhZnRlcndhcmRzLCBvciB5b3Ugd29uJ3QgYmUgYWJsZSB0byBxdWVyeSBvbiB0aGUgdGFibGUgd2l0aCB0aGUgZXhpc3RpbmcgY29ubmVjdGlvbgoKICAyLiBTaG93IHRoZSBjb2RlIG5lZWRlZCB0byBwb3B1bGF0ZSB0aGUgYHBva2Vtb25gIHRhYmxlIHdpdGggZGF0YSBmcm9tIGBwb2tlbW9uLmNzdmAgaW4gYm90aCBSIGFuZCBTUUwKCiAgMy4gSG93IG1hbnkgUG9rw6ltb24gaGFzIGEgRmFpcnkgdHlwaW5nPwoKICA0LiBQb2vDqW1vbiB3aXRoIG5vIHNlY29uZGFyeSB0eXBlIGFyZSBjYWxsZWQgX3NpbmdsZSB0eXBlXyBQb2vDqW1vbi4gU2hvdyB0aGUgbW9zdCBjb21tb24gc2luZ2xlIHR5cGUgdG9nZXRoZXIgd2l0aCB0aGUgcmFyZXN0IHNpbmdsZSB0eXBlCgogIDUuIFRoZSBxdWVyaWVzIGZvciB0aGUgcHJldmlvdXMgdHdvIGV4ZXJjaXNlcyBjYW4gYmUgc3BlZCB1cCB1c2luZyBpbmRleGVzLiBTaG93IHRoZSBTUUwgYENSRUFURWAgc2NyaXB0IGZvciBzdWNoIGluZGV4ZXMKCiAgNi4gU2hvdyB0aGUgY29kZSBuZWVkZWQgdG8gYWRkIHRoZSBmb2xsb3dpbmcgcm93cyB0byBgcG9rZW1vbmA6CgogICAgTnVtYmVyIHwgTmFtZSB8IFR5cGUgMSB8IFR5cGUgMiB8IFRvdGFsIHwgSFAgfCBBdHRhY2sgfCBEZWZlbnNlIHwgU3AuIEF0dGFjayB8IFNwLiBEZWZlbnNlIHwgU3BlZWQgfCBHZW5lcmF0aW9uIHwgTGVnZW5kYXJ5CiAgICAtLS0gfCAtLS0gfCAtLS0gfCAtLS0gfCAtLS0gfCAtLS0gfCAtLS0gfCAtLS0gfCAtLS0gfCAtLS0gfCAtLS0gfCAtLS0gfCAtLS0KICAgIDcyMiB8IFJvd2xldCB8IEdyYXNzIHwgRmx5aW5nIHwgMzIwIHwgNjggfCA1NSB8IDU1IHwgNTAgfCA1MCB8IDQyIHwgNyB8IGZhbHNlCiAgICA3MjMgfCBEYXJ0cml4IHwgR3Jhc3MgfCBGbHlpbmcgfCA0MjAgfCA3OCB8IDc1IHwgNzUgfCA3MCB8IDcwIHwgNTIgfCA3IHwgZmFsc2UKICAgIDcyNCB8IERlY2lkdWV5ZSB8IEdyYXNzIHwgR2hvc3QgfCA1MzAgfCA3OCB8IDEwNyB8IDc1IHwgMTAwIHwgMTAwIHwgNzAgfCA3IHwgZmFsc2UKCiAgICBpbiBib3RoIFIgYW5kIFNRTCAoZG8gbm90IHJ1biB0aGUgY29kZSwgbmVpdGhlciBpbiB0aGUgbm90ZWJvb2sgbm9yIHNlcGFyYXRlbHkpCgogIDcuIFNob3cgdGhlIGNvZGUgbmVlZGVkIHRvIGRlbGV0ZSB0aGUgYHBva2Vtb25gIHRhYmxlIGluIGJvdGggUiBhbmQgU1FMCgoKYGBge3IgY2xlYW51cCwgaW5jbHVkZSA9IEZBTFNFfQpkYkRpc2Nvbm5lY3QoY29uKQpgYGAK