Introduction
This is a step-by-step guide to create a new database, user, and
tables for Lake Washington (Seattle, WA, USA) limnological data and the
Pacific Decadal Oscillation (PDO) climate variability index.
Requirements
To begin, you should have PostgreSQL and
pgAdmin installed. (Please note that the following
steps were tested on PostgreSQL v13 and
pgAdmin v4.3 running on macOS Big Sur.)
Getting oriented in pgAdmin
Before we can create anything, we need to connect to
PostgreSQL with our pgAdmin client. It
is important to note that the current version of
pgAdmin runs in your web browser.
The first time you open pgAdmin you will be prompted
to set a password.
The pgAdmin dashboard provides a database object
browser along the left side of the window. In the object brower click on
Servers
. Then click on PostgreSQL 13
. You will
be asked for the postgres
superuser password you set up
when you first installed PostgreSQL. Provide the
password and pgAdmin will connect to the database.
Under PostgreSQL 13
you will then see
Databases
, Login/Group Roles
, and
Tablespaces
.
Databases
Click on Databases
to see one database named
postgres
. The postgres
database is the only
database created automatically when PostgreSQL is
installed.
Click on the postgres
database and then click on
Schemas
at the bottom of the submenu. You will see there is
one schema in the database named public
.
Click on the public
schema to see the long list of
database object types listed alphabetically.
Tablespaces
Tablespaces allow you to control where in the file system you
database objects are stored.
Tablespaces are used for performance and disk space
management.
We are using default tablespaces in this exercise, but you can
learn more about adding and configuring tablespaces in the
PostgreSQL documentation
Create a new user
Right now we’re connected to the database as the
postgres
super user, so we want to set up a new user for
our project and then disconnect as postgres
and sign in as
our new user. To create a new user
right click on Login/Group Roles
click on Create >
click on Login/Group Roles ...
, which will open a
window in pgAdmin to create a new Login/Group
Role
- Under the
General
tab, give the new role a name (here
we use lake_wa
)

- Click on the
Definition
tab at the top of the window
and provide a password for your user


- Click on the SQL tab to see the actual SQL that
pgAdmin is generating for you (note that the SQL view
masks the password you provided). Here’s the SQL to create my new
user:
CREATE ROLE lake_wa WITH
LOGIN
NOSUPERUSER
CREATEDB
NOCREATEROLE
INHERIT
NOREPLICATION
CONNECTION LIMIT -1
PASSWORD 'xxxxxx';

- Click
Save
and then verify that your user now appears
under Login/Group Roles
Switch users
- Right click on
PostgreSQL 13
in the object browser, and
then click Disconnect Server

- A window will pop up asking if you are sure you want to
disconnect–click
Ok
- Right click on
PostgreSQL 13
in the object browser and
then select Properties


Click the blue Save to close the window and save
your changes
Double click on PostgreSQL 13
in the object
browser
A window will pop up asking for the password for the
lake_wa
user
Input the password and click the blue OK
button

- You are now connected to PostgreSQL as your new
user
Creating a new database
[Note: If at any point you feel like you want to
return to this location in the workflow, click
here for instructions on how to do so.]
Next we are going to create a new database to hold our Lake
Washington and PDO data.
- Right click on
Databases
and then select
Create > Database ...
A window will pop up called Create -
Database
Give your new database a name; here we called it
lake_wa
(note that PostgreSQL assumes we
want the current user lake_wa
to own the new database,
which is OK, so there is nothing to change here)

- Click on SQL to see the statement that pgAdmin is
writing for you to create the database.
My create database statement looks like:
CREATE DATABASE lake_wa
WITH
OWNER = lake_wa
ENCODING = 'UTF8'
CONNECTION LIMIT = -1;

Now we have our user and our database, and we can next make the data
tables that will hold our data. But before we start making the data
tables, we need to inspect the data to know what their tables should
look like.
Create a new schema
Before we import our data from the .csv
files, we need
to create a new schema that we’ll use to stage and clean the
Lake Washington limnology data.
- Right-click on Schemas and select
Create > Schema...
- In the dialogue box that opens up, click on the
General
tab and enter staging
in the Name
field

- Click on the
SQL
tab and you should see the following
SQL commands
CREATE SCHEMA staging
AUTHORIZATION lake_wa;

The data
The data for this example are available as two .csv
files
lwa_limno.csv
pdo_data.csv
which can be found in the data
directory here. Download
both data files to your local computer either directly from the repo or
by cloning or forking the repo.
Generally we need to know the field (column) names in the data files
and what type of data are contained in each field before we can set up
the tables. Fortunately for us, some nice people made a free tool that will
give you the SQL for a .csv
file that we
can use to quickstart the process.
Pacific Decadal Oscillation
We’ll begin by bringing in the PDO data located in
pdo_data
.
Lake Washington limnology
Creating the tables
PDO
We now need to create the tables for the data within the database.
We’ll begin with the PDO data.
- In pgAdmin, click the
Tools
tab at the
top and then select Query Tool
A query editor window will open in
pgAdmin
Click on the open folder icon, which will allow you to select the
SQL file we saved above
- Navigate to the location where you saved your
pdo_data.sql
, select it, and then click the blue
Select button

- You will now see the SQL code in the editor window, that begins
with
CREATE TABLE public.pdo(
date INTEGER NOT NULL PRIMARY KEY
,pdo NUMERIC(5,2) NOT NULL
);
INSERT INTO public.pdo(date,pdo) VALUES
(185401,0.11)
,(185402,-0.24)
,(185403,-0.4)
,(185404,-0.44)
,(185405,-0.54)
,(185406,-0.3)
INSERT 0 2004
Query returned successfully in 42 msec.
(Note that the time it took the query to run will depend on your
computer resources.)
In the pgAdmin object browser, click on
Schemas > public > Tables > pdo
to see the
contents of your new table pdo
Right click on the pdo
table and then click
View/Edit Data
and then All Rows
- The query editor will show you the following query used to call all
records for the table in the upper pane and show the result set for that
query in the lower pane.
SELECT * FROM public.pdo
ORDER BY date ASC
Limnology
- In pgAdmin, click the
Tools
tab at the
top and then select Query Tool
A query editor window will open in
pgAdmin
Click on the open folder icon, which will allow you to select the
SQL file we saved above
- Navigate to the location where you saved your
lwa_limno.sql
, select it, and then click the blue
Select button

- You will now see the SQL code in the editor window, that begins
with
CREATE TABLE staging.limno(
Year INTEGER NOT NULL
,Month INTEGER NOT NULL
INSERT 0 396
Query returned successfully in 58 msec.
(Note that the time it took the query to run will depend on your
computer resources.)
In the pgAdmin object browser, click on
Schemas > staging > Tables > limno
to see your new
table stage_lake_wa
Right click on the limno
table and then click
View/Edit Data
and then All Rows
- The query editor will show you the following query used to call all
records for the table in the upper pane and show the result set for that
query in the lower pane.
SELECT * FROM staging.limno
The Truman options
There can be times when it simply seems easiest to burn it all down
and start over, so don’t feel bad if you find yourself here.
Delete a database
If, for whatever reason, you want to delete a database, do this in
pgAdmin
- Right-click on the
lake_wa
database and select
Delete/Drop

Delete a user
You cannot delete a user while you are logged in as that person. To
remove the lake_wa
user we created here, we’ll have to
first disconnect from the database, and then log back in as the
postgres
super user. To do so in pgAdmin,
follow these steps
- Right-click on PostgreSQL 13 in the object browser
and select
Disconnect Server

- Right-click on PostgreSQL 13 again and select
Properties

- Click on the
Connection
tab and change
username
to postgres
; when you are done, click
the blue Save button

- Right-click on PostgreSQL 13 and select
Connect Server

- When prompted, enter the password you used when you first installed
PostgreSQL and click the blue OK
button

- Under Login/Group Roles in the object browser,
right-click on
lake_wa
and select
Delete/Drop

LS0tCnRpdGxlOiAiU2V0IHVwIGEgUG9zdGdyZVNRTCBkYXRhYmFzZSIKc3VidGl0bGU6ICJQYXJ0IDEiCmRhdGU6ICI8YnI+MjYgRmVicnVhcnkgMjAyNSIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0aGVtZTogc3BhY2VsYWIKICAgIGhpZ2hsaWdodDogdGV4dG1hdGUKICAgIGNzczogLi4vbGVjdHVyZV9pbnN0LmNzcwogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIHRvY19kZXB0aDogMwotLS0KCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAKICAgICAgICAgICAgICAgICAgICAgIGZpZy5hbGlnbiA9ICJjZW50ZXIiLCBvdXQud2lkdGggPSAnNzAlJykKYGBgCgo8YnI+CgojIEludHJvZHVjdGlvbgoKVGhpcyBpcyBhIHN0ZXAtYnktc3RlcCBndWlkZSB0byBjcmVhdGUgYSBuZXcgZGF0YWJhc2UsIHVzZXIsIGFuZCB0YWJsZXMgCmZvciBMYWtlIFdhc2hpbmd0b24gKFNlYXR0bGUsIFdBLCBVU0EpIGxpbW5vbG9naWNhbCBkYXRhIGFuZCB0aGUgUGFjaWZpYyBEZWNhZGFsIE9zY2lsbGF0aW9uIChQRE8pIApjbGltYXRlIHZhcmlhYmlsaXR5IGluZGV4LgoKIyMgUmVxdWlyZW1lbnRzCgpUbyBiZWdpbiwgeW91IHNob3VsZCBoYXZlICoqUG9zdGdyZVNRTCoqIGFuZCAqKnBnQWRtaW4qKiBpbnN0YWxsZWQuIChQbGVhc2Ugbm90ZSB0aGF0IHRoZSBmb2xsb3dpbmcgc3RlcHMgd2VyZSB0ZXN0ZWQgb24gKipQb3N0Z3JlU1FMKiogdjEzIGFuZCAqKnBnQWRtaW4qKiB2NC4zIHJ1bm5pbmcgb24gbWFjT1MgQmlnIFN1ci4pIAoKKioqCgojIEdldHRpbmcgb3JpZW50ZWQgaW4gcGdBZG1pbgoKQmVmb3JlIHdlIGNhbiBjcmVhdGUgYW55dGhpbmcsIHdlIG5lZWQgdG8gY29ubmVjdCB0byAqKlBvc3RncmVTUUwqKiB3aXRoIG91ciAqKnBnQWRtaW4qKiBjbGllbnQuIEl0IGlzIGltcG9ydGFudCB0byBub3RlIHRoYXQgdGhlIGN1cnJlbnQgdmVyc2lvbiBvZiAqKnBnQWRtaW4qKiBydW5zIGluIHlvdXIgd2ViIGJyb3dzZXIuIAoKVGhlIGZpcnN0IHRpbWUgeW91IG9wZW4gKipwZ0FkbWluKiogeW91IHdpbGwgYmUgcHJvbXB0ZWQgdG8gc2V0IGEgcGFzc3dvcmQuIAoKVGhlICoqcGdBZG1pbioqIGRhc2hib2FyZCBwcm92aWRlcyBhIGRhdGFiYXNlIG9iamVjdCBicm93c2VyIGFsb25nIHRoZSBsZWZ0IHNpZGUgb2YgdGhlIHdpbmRvdy4gSW4gdGhlIG9iamVjdCBicm93ZXIgY2xpY2sgb24gYFNlcnZlcnNgLiBUaGVuIGNsaWNrIG9uIGBQb3N0Z3JlU1FMIDEzYC4gWW91IHdpbGwgYmUgYXNrZWQgZm9yIHRoZSBgcG9zdGdyZXNgIHN1cGVydXNlciBwYXNzd29yZCB5b3Ugc2V0IHVwIHdoZW4geW91IGZpcnN0IGluc3RhbGxlZCAqKlBvc3RncmVTUUwqKi4gUHJvdmlkZSB0aGUgcGFzc3dvcmQgYW5kICoqcGdBZG1pbioqIHdpbGwgY29ubmVjdCB0byB0aGUgZGF0YWJhc2UuIAoKVW5kZXIgYFBvc3RncmVTUUwgMTNgIHlvdSB3aWxsIHRoZW4gc2VlIGBEYXRhYmFzZXNgLCBgTG9naW4vR3JvdXAgUm9sZXNgLCBhbmQgYFRhYmxlc3BhY2VzYC4KCiMjIERhdGFiYXNlcwoKLSBDbGljayBvbiBgRGF0YWJhc2VzYCB0byBzZWUgb25lIGRhdGFiYXNlIG5hbWVkIGBwb3N0Z3Jlc2AuIFRoZSBgcG9zdGdyZXNgIGRhdGFiYXNlIGlzIHRoZSBvbmx5IGRhdGFiYXNlIGNyZWF0ZWQgYXV0b21hdGljYWxseSB3aGVuICoqUG9zdGdyZVNRTCoqIGlzIGluc3RhbGxlZC4KICAKLSBDbGljayBvbiB0aGUgYHBvc3RncmVzYCBkYXRhYmFzZSBhbmQgdGhlbiBjbGljayBvbiBgU2NoZW1hc2AgYXQgdGhlIGJvdHRvbSBvZiB0aGUgc3VibWVudS4gWW91IHdpbGwgc2VlIHRoZXJlIGlzIG9uZSBzY2hlbWEgaW4gdGhlIGRhdGFiYXNlIG5hbWVkIGBwdWJsaWNgLiAKICAKLSBDbGljayBvbiB0aGUgYHB1YmxpY2Agc2NoZW1hIHRvIHNlZSB0aGUgbG9uZyBsaXN0IG9mIGRhdGFiYXNlIG9iamVjdCB0eXBlcyBsaXN0ZWQgYWxwaGFiZXRpY2FsbHkuCgojIyBMb2dpbi9Hcm91cCBSb2xlcwoKLSBDbGljayBvbiBgTG9naW4vR3JvdXAgUm9sZXNgIHRvIHNlZSBlaWdodCByb2xlcyB0aGF0IHN0YXJ0IHdpdGggYHBnX2AgYW5kIG9uZSB1c2VyIG5hbWVkIGBwb3N0Z3Jlc2AuIAoKICAtIFJvbGVzIGFuZCB1c2VycyBjYW4gYmUgZGlzdGluZ3Vpc2hlZCBieSB0aGVpciBkaWZmZXJlbnQgaWNvbnMgaW4gdGhlIG9iamVjdCBicm93c2VyLiAKICAKICAtIFRoZSBgcG9zdGdyZXNgIHVzZXIgaXMgdGhlIHN1cGVydXNlciB5b3UgYXJlIHVzaW5nIHRvIGNvbm5lY3QgaW50byB0aGUgZGF0YWJhc2UuIAoKIyMgVGFibGVzcGFjZXMKCiAtIFRhYmxlc3BhY2VzIGFsbG93IHlvdSB0byBjb250cm9sIHdoZXJlIGluIHRoZSBmaWxlIHN5c3RlbSB5b3UgZGF0YWJhc2Ugb2JqZWN0cyBhcmUgc3RvcmVkLiAKIAogLSBUYWJsZXNwYWNlcyBhcmUgdXNlZCBmb3IgcGVyZm9ybWFuY2UgYW5kIGRpc2sgc3BhY2UgbWFuYWdlbWVudC4gCiAKIC0gV2UgYXJlIHVzaW5nIGRlZmF1bHQgdGFibGVzcGFjZXMgaW4gdGhpcyBleGVyY2lzZSwgYnV0IHlvdSBjYW4gbGVhcm4gbW9yZSBhYm91dCBhZGRpbmcgYW5kIGNvbmZpZ3VyaW5nIHRhYmxlc3BhY2VzIGluIHRoZSAqKlBvc3RncmVTUUwqKiBbZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly93d3cuKipQb3N0Z3JlU1FMKioub3JnL2RvY3MvY3VycmVudC9tYW5hZ2UtYWctdGFibGVzcGFjZXMuaHRtbCkKCioqKgoKIyBDcmVhdGUgYSBuZXcgdXNlcgoKUmlnaHQgbm93IHdlJ3JlIGNvbm5lY3RlZCB0byB0aGUgZGF0YWJhc2UgYXMgdGhlIGBwb3N0Z3Jlc2Agc3VwZXIgdXNlciwgc28gd2Ugd2FudCB0byBzZXQgdXAgYSBuZXcgdXNlciBmb3Igb3VyIHByb2plY3QgYW5kIHRoZW4gZGlzY29ubmVjdCBhcyBgcG9zdGdyZXNgIGFuZCBzaWduIGluIGFzIG91ciBuZXcgdXNlci4gVG8gY3JlYXRlIGEgbmV3IHVzZXIgIAoKLSByaWdodCBjbGljayBvbiBgTG9naW4vR3JvdXAgUm9sZXNgICAKCi0gY2xpY2sgb24gYENyZWF0ZSA+YCAgCgotIGNsaWNrIG9uIGBMb2dpbi9Hcm91cCBSb2xlcyAuLi5gLCB3aGljaCB3aWxsIG9wZW4gYSB3aW5kb3cgaW4gKipwZ0FkbWluKiogdG8gY3JlYXRlIGEgbmV3IExvZ2luL0dyb3VwIFJvbGUgIAoKPGJyPgohW10oaW1hZ2VzL25ld191c2VyXzEucG5nKQo8YnI+PGJyPgoKLSBVbmRlciB0aGUgYEdlbmVyYWxgIHRhYiwgZ2l2ZSB0aGUgbmV3IHJvbGUgYSBuYW1lIChoZXJlIHdlIHVzZSBgbGFrZV93YWApCgo8YnI+Cgo8aW1nIHNyYz0iaW1hZ2VzL25ld191c2VyXzIucG5nIiBjbGFzcz0ic21hbGwiPgoKPGJyPgoKLSBDbGljayBvbiB0aGUgYERlZmluaXRpb25gIHRhYiBhdCB0aGUgdG9wIG9mIHRoZSB3aW5kb3cgYW5kIHByb3ZpZGUgYSBwYXNzd29yZCBmb3IgeW91ciB1c2VyCgo8YnI+Cgo8aW1nIHNyYz0iaW1hZ2VzL25ld191c2VyXzMucG5nIiBjbGFzcz0ic21hbGwiPgoKPGJyPgoKLSBDbGljayBvbiB0aGUgYFByaXZpbGVnZXNgIHRhYiBhdCB0aGUgdG9wIG9mIHRoZSB3aW5kb3cgdG8gYXNzaWduIHBlcm1pc3Npb25zIGZvciB0aGUgcm9sZQoKICAtIENoYW5nZSBgQ2FuIGxvZ2luP2AgdG8gIlllcyIgIAogIAogIC0gQ2hhbmdlIGBDcmVhdGUgZGF0YWJhc2VzP2AgdG8gIlllcyIgCgotIENsaWNrIHRoZSBibHVlICoqU2F2ZSoqIGJ1dHRvbiB3aGVuIHlvdSBhcmUgZG9uZQoKPGJyPgoKPGltZyBzcmM9ImltYWdlcy9uZXdfdXNlcl80LnBuZyIgY2xhc3M9InNtYWxsIj4KCjxicj4KCi0gQ2xpY2sgb24gdGhlIFNRTCB0YWIgdG8gc2VlIHRoZSBhY3R1YWwgU1FMIHRoYXQgKipwZ0FkbWluKiogaXMgZ2VuZXJhdGluZyBmb3IgeW91IChub3RlIHRoYXQgdGhlIFNRTCB2aWV3IG1hc2tzIHRoZSBwYXNzd29yZCB5b3UgcHJvdmlkZWQpLiBIZXJlJ3MgdGhlIFNRTCB0byBjcmVhdGUgbXkgbmV3IHVzZXI6CgpgYGAKQ1JFQVRFIFJPTEUgbGFrZV93YSBXSVRICglMT0dJTgoJTk9TVVBFUlVTRVIKCUNSRUFURURCCglOT0NSRUFURVJPTEUKCUlOSEVSSVQKCU5PUkVQTElDQVRJT04KCUNPTk5FQ1RJT04gTElNSVQgLTEKCVBBU1NXT1JEICd4eHh4eHgnOwpgYGAKCjxicj4KCjxpbWcgc3JjPSJpbWFnZXMvbmV3X3VzZXJfNS5wbmciIGNsYXNzPSJzbWFsbCI+Cgo8YnI+CgotIENsaWNrIGBTYXZlYCBhbmQgdGhlbiB2ZXJpZnkgdGhhdCB5b3VyIHVzZXIgbm93IGFwcGVhcnMgdW5kZXIgYExvZ2luL0dyb3VwIFJvbGVzYAoKKioqCgojIFN3aXRjaCB1c2VycwoKLSBSaWdodCBjbGljayBvbiBgUG9zdGdyZVNRTCAxM2AgaW4gdGhlIG9iamVjdCBicm93c2VyLCBhbmQgdGhlbiBjbGljayBgRGlzY29ubmVjdCBTZXJ2ZXJgIAoKPGJyPgoKPGltZyBzcmM9ImltYWdlcy9zd2l0Y2hfdXNlcl9hLnBuZyIgY2xhc3M9InNtYWxsIj4KCjxicj4KCi0gQSB3aW5kb3cgd2lsbCBwb3AgdXAgYXNraW5nIGlmIHlvdSBhcmUgc3VyZSB5b3Ugd2FudCB0byBkaXNjb25uZWN0LS1jbGljayBgT2tgIAotIFJpZ2h0IGNsaWNrIG9uIGBQb3N0Z3JlU1FMIDEzYCBpbiB0aGUgb2JqZWN0IGJyb3dzZXIgYW5kIHRoZW4gc2VsZWN0IGBQcm9wZXJ0aWVzYCAKCjxicj4KCjxpbWcgc3JjPSJpbWFnZXMvc3dpdGNoX3VzZXJfYi5wbmciIGNsYXNzPSJzbWFsbCI+Cgo8YnI+CgotIEEgd2luZG93IHdpbGwgcG9wIHVwIHRpdGxlZCAqKlBvc3RncmVTUUwqKiAxMzsgY2xpY2sgdGhlIGBDb25uZWN0aW9uYCB0YWIgYXQgdGhlIHRvcAoKLSBVbmRlciBgVXNlcm5hbWVgIGNoYW5nZSBgcG9zdGdyZXNgIHRvIGBsYWtlX3dhYCAob3Igd2hhdGV2ZXIgeW91IG5hbWVkIHlvdXIgdXNlcikKCjxicj4KCjxpbWcgc3JjPSJpbWFnZXMvc3dpdGNoX3VzZXJfYy5wbmciIGNsYXNzPSJzbWFsbCI+Cgo8YnI+CgotIENsaWNrIHRoZSBibHVlICoqU2F2ZSoqIHRvIGNsb3NlIHRoZSB3aW5kb3cgYW5kIHNhdmUgeW91ciBjaGFuZ2VzCgotIERvdWJsZSBjbGljayBvbiBgUG9zdGdyZVNRTCAxM2AgaW4gdGhlIG9iamVjdCBicm93c2VyCgotIEEgd2luZG93IHdpbGwgcG9wIHVwIGFza2luZyBmb3IgdGhlIHBhc3N3b3JkIGZvciB0aGUgYGxha2Vfd2FgIHVzZXIKCi0gSW5wdXQgdGhlIHBhc3N3b3JkIGFuZCBjbGljayB0aGUgYmx1ZSAqKk9LKiogYnV0dG9uCgo8YnI+Cgo8aW1nIHNyYz0iaW1hZ2VzL3N3aXRjaF91c2VyX2QucG5nIiBjbGFzcz0ic21hbGwiPgoKPGJyPgoKLSBZb3UgYXJlIG5vdyBjb25uZWN0ZWQgdG8gKipQb3N0Z3JlU1FMKiogYXMgeW91ciBuZXcgdXNlcgoKKioqCgojIENyZWF0aW5nIGEgbmV3IGRhdGFiYXNlCgpbKipOb3RlKio6IElmIGF0IGFueSBwb2ludCB5b3UgZmVlbCBsaWtlIHlvdSB3YW50IHRvIHJldHVybiB0byB0aGlzIGxvY2F0aW9uIGluIHRoZSB3b3JrZmxvdywgW2NsaWNrIGhlcmVdKCN0cnVtYW5fMSkgZm9yIGluc3RydWN0aW9ucyBvbiBob3cgdG8gZG8gc28uXQoKTmV4dCB3ZSBhcmUgZ29pbmcgdG8gY3JlYXRlIGEgbmV3IGRhdGFiYXNlIHRvIGhvbGQgb3VyIExha2UgV2FzaGluZ3RvbiBhbmQgUERPIGRhdGEuIAoKLSBSaWdodCBjbGljayBvbiBgRGF0YWJhc2VzYCBhbmQgdGhlbiBzZWxlY3QgYENyZWF0ZSA+IERhdGFiYXNlIC4uLmAKCjxicj4KIVtdKGltYWdlcy9jcmVhdGVfZGJfMS5wbmcpCjxicj48YnI+CgotIEEgd2luZG93IHdpbGwgcG9wIHVwIGNhbGxlZCAqKkNyZWF0ZSAtIERhdGFiYXNlKioKCi0gR2l2ZSB5b3VyIG5ldyBkYXRhYmFzZSBhIG5hbWU7IGhlcmUgd2UgY2FsbGVkIGl0IGBsYWtlX3dhYCAobm90ZSB0aGF0ICoqUG9zdGdyZVNRTCoqIGFzc3VtZXMgd2Ugd2FudCB0aGUgY3VycmVudCB1c2VyIGBsYWtlX3dhYCB0byBvd24gdGhlIG5ldyBkYXRhYmFzZSwgd2hpY2ggaXMgT0ssIHNvIHRoZXJlIGlzIG5vdGhpbmcgdG8gY2hhbmdlIGhlcmUpIAoKPGJyPgoKPGltZyBzcmM9ImltYWdlcy9jcmVhdGVfZGJfMi5wbmciIGNsYXNzPSJzbWFsbCI+Cgo8YnI+CgotIENsaWNrIG9uIFNRTCB0byBzZWUgdGhlIHN0YXRlbWVudCB0aGF0ICoqcGdBZG1pbioqIGlzIHdyaXRpbmcgZm9yIHlvdSB0byBjcmVhdGUgdGhlIGRhdGFiYXNlLiAKCk15IGNyZWF0ZSBkYXRhYmFzZSBzdGF0ZW1lbnQgbG9va3MgbGlrZToKCmBgYApDUkVBVEUgREFUQUJBU0UgbGFrZV93YQogICAgV0lUSCAKICAgIE9XTkVSID0gbGFrZV93YQogICAgRU5DT0RJTkcgPSAnVVRGOCcKICAgIENPTk5FQ1RJT04gTElNSVQgPSAtMTsKYGBgCgo8YnI+Cgo8aW1nIHNyYz0iaW1hZ2VzL2NyZWF0ZV9kYl8zLnBuZyIgY2xhc3M9InNtYWxsIj4KCjxicj4KCi0gQ2xpY2sgdGhlIGJsdWUgKipTYXZlKiogYnV0dG9uIGFuZCB0aGVuIHZlcmlmeSB5b3Ugbm93IHNlZSBgbGFrZV93YWAgYXMgYSBzZWNvbmQgZGF0YWJhc2UgYmVzaWRlIGBwb3N0Z3Jlc2AgaW4gdGhlIG9iamVjdCBicm93c2VyCgotIENsaWNrIG9uIHRoZSBgbGFrZV93YWAgZGF0YWJhc2UgdG8gY29ubmVjdCB0byBpdAoKPGJyPgohW10oaW1hZ2VzL2NyZWF0ZV9kYl80LnBuZykKPGJyPjxicj4KCk5vdyB3ZSBoYXZlIG91ciB1c2VyIGFuZCBvdXIgZGF0YWJhc2UsIGFuZCB3ZSBjYW4gbmV4dCBtYWtlIHRoZSBkYXRhIHRhYmxlcyB0aGF0IHdpbGwgaG9sZCBvdXIgZGF0YS4gQnV0IGJlZm9yZSB3ZSBzdGFydCBtYWtpbmcgdGhlIGRhdGEgdGFibGVzLCB3ZSBuZWVkIHRvIGluc3BlY3QgdGhlIGRhdGEgdG8ga25vdyB3aGF0IHRoZWlyIHRhYmxlcyBzaG91bGQgbG9vayBsaWtlLiAgCgojIyBDcmVhdGUgYSBuZXcgc2NoZW1hCgpCZWZvcmUgd2UgaW1wb3J0IG91ciBkYXRhIGZyb20gdGhlIGAuY3N2YCBmaWxlcywgd2UgbmVlZCB0byBjcmVhdGUgYSBuZXcgKnNjaGVtYSogdGhhdCB3ZSdsbCB1c2UgdG8gc3RhZ2UgYW5kIGNsZWFuIHRoZSBMYWtlIFdhc2hpbmd0b24gbGltbm9sb2d5IGRhdGEuCgotIFJpZ2h0LWNsaWNrIG9uICoqU2NoZW1hcyoqIGFuZCBzZWxlY3QgYENyZWF0ZSA+IFNjaGVtYS4uLmAKCjxicj4KIVtdKGltYWdlcy9jcmVhdGVfc2NoZW1hXzEucG5nKQo8YnI+PGJyPgoKLSBJbiB0aGUgZGlhbG9ndWUgYm94IHRoYXQgb3BlbnMgdXAsIGNsaWNrIG9uIHRoZSBgR2VuZXJhbGAgdGFiIGFuZCBlbnRlciBgc3RhZ2luZ2AgaW4gdGhlIGBOYW1lYCBmaWVsZAoKPGJyPgoKPGltZyBzcmM9ImltYWdlcy9jcmVhdGVfc2NoZW1hXzIucG5nIiBjbGFzcz0ic21hbGwiPgoKPGJyPgoKLSBDbGljayBvbiB0aGUgYFNRTGAgdGFiIGFuZCB5b3Ugc2hvdWxkIHNlZSB0aGUgZm9sbG93aW5nIFNRTCBjb21tYW5kcwoKYGBgCkNSRUFURSBTQ0hFTUEgc3RhZ2luZwogICAgQVVUSE9SSVpBVElPTiBsYWtlX3dhOwpgYGAKCjxicj4KCjxpbWcgc3JjPSJpbWFnZXMvY3JlYXRlX3NjaGVtYV8zLnBuZyIgY2xhc3M9InNtYWxsIj4KCjxicj4KCgojIFRoZSBkYXRhCgpUaGUgZGF0YSBmb3IgdGhpcyBleGFtcGxlIGFyZSBhdmFpbGFibGUgYXMgdHdvIGAuY3N2YCBmaWxlcwoKMS4gYGx3YV9saW1uby5jc3ZgCgoyLiBgcGRvX2RhdGEuY3N2YAoKd2hpY2ggY2FuIGJlIGZvdW5kIGluIHRoZSBgZGF0YWAgZGlyZWN0b3J5IFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vc3VyZUwvcG9zdGdyZXMtdHV0b3JpYWwpLiBEb3dubG9hZCBib3RoIGRhdGEgZmlsZXMgdG8geW91ciBsb2NhbCBjb21wdXRlciBlaXRoZXIgZGlyZWN0bHkgZnJvbSB0aGUgcmVwbyBvciBieSBjbG9uaW5nIG9yIGZvcmtpbmcgdGhlIHJlcG8uCgpHZW5lcmFsbHkgd2UgbmVlZCB0byBrbm93IHRoZSBmaWVsZCAoY29sdW1uKSBuYW1lcyBpbiB0aGUgZGF0YSBmaWxlcyBhbmQgd2hhdCB0eXBlIG9mIGRhdGEgYXJlIGNvbnRhaW5lZCBpbiBlYWNoIGZpZWxkIGJlZm9yZSB3ZSBjYW4gc2V0IHVwIHRoZSB0YWJsZXMuIEZvcnR1bmF0ZWx5IGZvciB1cywgc29tZSBuaWNlIHBlb3BsZSBtYWRlIGEgW2ZyZWUgdG9vbF0oaHR0cHM6Ly93d3cuY29udmVydGNzdi5jb20vY3N2LXRvLXNxbC5odG0pIHRoYXQgd2lsbCBnaXZlIHlvdSB0aGUgKipTUUwqKiBmb3IgYSBgLmNzdmAgZmlsZSB0aGF0IHdlIGNhbiB1c2UgdG8gcXVpY2tzdGFydCB0aGUgcHJvY2Vzcy4KCiMjIFBhY2lmaWMgRGVjYWRhbCBPc2NpbGxhdGlvbiB7I2NyZWF0ZV9wZG99CgpXZSdsbCBiZWdpbiBieSBicmluZ2luZyBpbiB0aGUgUERPIGRhdGEgbG9jYXRlZCBpbiBgcGRvX2RhdGFgLgoKLSBPcGVuIHVwIHRoZSBbQ29udmVydCBDU1YgdG8gU1FMIHRvb2xdKGh0dHBzOi8vd3d3LmNvbnZlcnRjc3YuY29tL2Nzdi10by1zcWwuaHRtKQoKLSBVbmRlciAqKlN0ZXAgMSoqCgogICAgLSBDaG9vc2UgYW55IG9mIHRoZSAzIGZvbGxvd2luZyBvcHRpb25zIHRvIHNlbGVjdCB0aGUgYHBkb19kYXRhLmNzdmAgZmlsZToKCiAgICAgICAgMSkgIkVudGVyIERhdGEiIGFsbG93cyB5b3UgdG8gY29weS9wYXN0ZSBmcm9tIHRoZSByYXcgY3N2IGZvcm1hdCBbaGVyZV0oaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3N1cmVML3Bvc3RncmVzLXR1dG9yaWFsL21haW4vZGF0YS9wZG9fZGF0YS5jc3YpCiAgICAgICAgCiAgICAgICAgMikgIkNob29zZSBGaWxlIiBhbGxvd3MgeW91IHRvIG5hdmlnYXRlIHRvIGFuZCBzZWxlY3QgdGhlIGxvY2F0aW9uIGZvciB5b3VyIGxvY2FsbHkgc2F2ZWQgYHBkb19kYXRhLmNzdmAgZmlsZQogICAgICAgIAogICAgICAgIDMpICJFbnRlciBVUkwiIGFsbG93cyB5b3UgdG8gY29weSB0aGUgVVJMIGZvciB0aGUgcmF3IGRhdGEgW2hlcmVdKGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9zdXJlTC9wb3N0Z3Jlcy10dXRvcmlhbC9tYWluL2RhdGEvcGRvX2RhdGEuY3N2KSBhbmQgcGFzdGUgaXQgaW50byB0aGUgYm94ICAKCiAgICAtIEFmdGVyIHNlbGVjdGluZyB0aGUgaW5wdXQsIHRoZSBjb252ZXJ0ZXIgd2lsbCByZWFkIGluIHRoZSBgLmNzdmAgZmlsZQoKICAgIDxicj4KICAgICFbXShpbWFnZXMvc3FsX2Nzdl9jb252ZXJ0X3Bkb19zMC5wbmcpCiAgICA8YnI+PGJyPgogICAgCi0gKFlvdSBjYW4gc2tpcCAqKlN0ZXAgMioqKQoKLSBVbmRlciAqKlN0ZXAgMyoqCgogICAgLSBMZWF2ZSBldmVyeXRoaW5nIGFzIGlzIGluIHRoZSAqKkZpZWxkIE5hbWUqKiwgKipLZXkqKiwgYW5kICoqUmVxdWlyZWQqKiBjb2x1bW5zCiAgICAKICAgIDxicj4KICAgICFbXShpbWFnZXMvc3FsX2Nzdl9jb252ZXJ0X3Bkb19zMS5wbmcpCiAgICA8YnI+PGJyPgogICAgCiAgICAtIFVuZGVyIHRoZSBgZmllbGQgbmFtZWAgYW5kIGBkYXRhIHR5cGVgIHNlY3Rpb24sIGxvb2sgZm9yIHRoZSBvcHRpb24gdG8gc3BlY2lmeSB0aGUgYFNjaGVtYS5UYWJsZWAgbmFtZSBhbmQgZW50ZXIgYHB1YmxpYy5wZG9gCgogICAgPGJyPgogICAgIVtdKGltYWdlcy9zcWxfY3N2X2NvbnZlcnRfcGRvX3MyLnBuZykKICAgIDxicj48YnI+CiAgICAKICAgIC0gU2Nyb2xsIGRvd24gZnVydGhlciBhbmQgdW5kZXIgKipGb3IgSU5TRVJUKiosCiAgICAKICAgICAgICAxKSBjaGVjayB0aGUgYm94IG5leHQgdG8gKipVc2Ugb25lIElOU0VSVC9SRVBMQUNFIHN0YXRlbWVudCB3aXRoIG11bHRpcGxlIFZBTFVFUyBjbGF1c2VzKiosIGFuZCAgCiAgICAgICAgMikgZW50ZXIgMjAwNSBmb3IgKipIb3cgbWFueT8qKgoKICAgIDxicj4KICAgICFbXShpbWFnZXMvc3FsX2Nzdl9jb252ZXJ0X3Bkb19zMy5wbmcpCiAgICA8YnI+PGJyPgogICAgCi0gVW5kZXIgKipTdGVwIDQqKgoKICAgIC0gQ2xpY2sgdGhlICoqQ1NWIFRvIFNRTCBJbnNlcnQqKiBidXR0b24gdG8gYnJpbmcgaW4gdGhlIG5ldyBjb25maWd1cmF0aW9uIG9wdGlvbnMgeW91IGp1c3Qgc2V0CgogICAgPGJyPgogICAgIVtdKGltYWdlcy9zcWxfY3N2X2NvbnZlcnRfcGRvX3M0LnBuZykKICAgIDxicj48YnI+CiAgICAKICAgIC0gSW4gdGhlICoqU2F2ZSB5b3VyIHJlc3VsdCoqIGJveCwgZW50ZXIgYHBkb19kYXRhYAoKICAgIC0gRm9yIHRoZSBsaW5lIGVuZGluZ3MsIGNob29zZSBlaXRoZXIgYENSTEZgIGlmIHlvdSBhcmUgb24gYSBXaW5kb3dzIGNvbXB1dGVyIGFuZCBgTEZgIG90aGVyd2lzZQoKICAgIC0gQ2xpY2sgdGhlIGJsdWUgYERvd25sb2FkIFJlc3VsdHNgIGJ1dHRvbiB0byBkb3dubG9hZCB0aGUgYHBkb19kYXRhLnNxbGAgZmlsZSB0byB5b3VyIGNvbXB1dGVyIAoKICAgIDxicj4KICAgICFbXShpbWFnZXMvc3FsX2Nzdl9jb252ZXJ0X3Bkb19zNS5wbmcpCiAgICA8YnI+PGJyPgogICAgCiMjIExha2UgV2FzaGluZ3RvbiBsaW1ub2xvZ3kgeyNjcmVhdGUtbHdhfQoKLSBSZXR1cm4gdG8gKipTdGVwIDEqKiBvZiB0aGUgW0NvbnZlcnQgQ1NWIHRvIFNRTCB0b29sXShodHRwczovL3d3dy5jb252ZXJ0Y3N2LmNvbS9jc3YtdG8tc3FsLmh0bSkKCiAgICAtIENsaWNrIG9uIHRoZSBibHVlICoqQ2xlYXIgSW5wdXQqKiBidXR0b24gdG8gY2xlYXIgYWxsIG9mIHRoZSBpbmZvcm1hdGlvbiBmcm9tIGBwZG9fZGF0YS5jc3ZgCiAgICAKICAgIC0gQ2hvb3NlIGFueSBvZiB0aGUgMyBmb2xsb3dpbmcgb3B0aW9ucyB0byBzZWxlY3QgdGhlIGBsd2FfbGltbm8uY3N2YCBmaWxlOgoKICAgICAgICAxKSAiRW50ZXIgRGF0YSIgYWxsb3dzIHlvdSB0byBjb3B5L3Bhc3RlIGZyb20gdGhlIHJhdyBjc3YgZm9ybWF0IFtoZXJlXShodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vc3VyZUwvcG9zdGdyZXMtdHV0b3JpYWwvbWFpbi9kYXRhL2x3YV9saW1uby5jc3YpCiAgICAgICAgCiAgICAgICAgMikgIkNob29zZSBGaWxlIiBhbGxvd3MgeW91IHRvIG5hdmlnYXRlIHRvIGFuZCBzZWxlY3QgdGhlIGxvY2F0aW9uIGZvciB5b3VyIGxvY2FsbHkgc2F2ZWQgYGx3YV9saW1uby5jc3ZgIGZpbGUKICAgICAgICAKICAgICAgICAzKSAiRW50ZXIgVVJMIiBhbGxvd3MgeW91IHRvIGNvcHkgdGhlIFVSTCBmb3IgdGhlIHJhdyBkYXRhIFtoZXJlXShodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vc3VyZUwvcG9zdGdyZXMtdHV0b3JpYWwvbWFpbi9kYXRhL2x3YV9saW1uby5jc3YpIGFuZCBwYXN0ZSBpdCBpbnRvIHRoZSBib3ggIAoKICAgIC0gQWZ0ZXIgc2VsZWN0aW5nIHRoZSBpbnB1dCwgdGhlIGNvbnZlcnRlciB3aWxsIHJlYWQgaW4gdGhlIGAuY3N2YCBmaWxlCgotIChZb3UgY2FuIHNraXAgKipTdGVwIDIqKikKCi0gVW5kZXIgKipTdGVwIDMqKgoKICAgIC0gYWRkIHVuZGVyc2NvcmVzIChgX2ApIHRvIDMgb2YgdGhlIGZpZWxkIG5hbWVzIHRvIHNlcGFyYXRlIHdvcmRzOgoKICAgICAgICAxKSBgT3RoZXJhbGdhZWAgYmVjb21lcyBgT3RoZXJfYWxnYWVgICAKICAgICAgICAyKSBgTm9uZGFwaG5pZGNsYWRvY2VyYW5zYCBiZWNvbWVzIGBOb25fZGFwaG5pZF9jbGFkb2NlcmFuc2AKICAgICAgICAzKSBgTm9uY29sb25pYWxyb3RpZmVyc2AgYmVjb21lcyBgTm9uX2NvbG9uaWFsX3JvdGlmZXJzYAoKICAgIDxicj4KICAgICFbXShpbWFnZXMvc3FsX2Nzdl9jb252ZXJ0X3MxLnBuZykKICAgIDxicj48YnI+CiAgICAKICAgIC0gSW4gdGhlICoqRmllbGQgTmFtZSoqIGZvciBgWWVhcmAsIHVuY2hlY2sgdGhlIGJveCB1bmRlciAqKktleSoqCiAgICAKICAgIDxicj4KICAgICFbXShpbWFnZXMvc3FsX2Nzdl9jb252ZXJ0X3MyLnBuZykKICAgIDxicj48YnI+CiAgICAKICAgIC0gSW4gdGhlICoqUmVxdWlyZWQqKiBjb2x1bW4sIGxlYXZlIHRoZSBjaGVjayBtYXJrcyBmb3IgYFllYXJgIGFuZCBgTW9udGhgIGFuZCB1bmNoZWNrICoqYWxsKiogb2YgdGhlIHJlc3Qgb2YgdGhlIGZpZWxkcwoKICAgIDxicj4KICAgICFbXShpbWFnZXMvc3FsX2Nzdl9jb252ZXJ0X3MzLnBuZykKICAgIDxicj48YnI+CiAgICAKICAgIC0gVW5kZXIgdGhlIGBmaWVsZCBuYW1lYCBhbmQgYGRhdGEgdHlwZWAgc2VjdGlvbiwgbG9vayBmb3IgdGhlIG9wdGlvbiB0byBzcGVjaWZ5IHRoZSBgU2NoZW1hLlRhYmxlYCBuYW1lIGFuZCBlbnRlciBgc3RhZ2luZy5saW1ub2AKCiAgICA8YnI+CiAgICAhW10oaW1hZ2VzL3NxbF9jc3ZfY29udmVydF9zNC5wbmcpCiAgICA8YnI+PGJyPgogICAgCiAgICAtIFNjcm9sbCBkb3duIGZ1cnRoZXIgYW5kIHVuZGVyICoqRm9yIElOU0VSVCoqLAogICAgCiAgICAgICAgMSkgY2hlY2sgdGhlIGJveCBuZXh0IHRvICoqVXNlIG9uZSBJTlNFUlQvUkVQTEFDRSBzdGF0ZW1lbnQgd2l0aCBtdWx0aXBsZSBWQUxVRVMgY2xhdXNlcyoqLCBhbmQgIAogICAgICAgIDIpIGVudGVyIDQwMCBmb3IgKipIb3cgbWFueT8qKgoKICAgIDxicj4KICAgICFbXShpbWFnZXMvc3FsX2Nzdl9jb252ZXJ0X3M1LnBuZykKICAgIDxicj48YnI+CiAgICAKLSBVbmRlciAqKlN0ZXAgNCoqCgogICAgLSBDbGljayB0aGUgKipDU1YgVG8gU1FMIEluc2VydCoqIGJ1dHRvbiB0byBicmluZyBpbiB0aGUgbmV3IGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB5b3UganVzdCBzZXQKCiAgICA8YnI+CiAgICAhW10oaW1hZ2VzL3NxbF9jc3ZfY29udmVydF9zNi5wbmcpCiAgICA8YnI+PGJyPgogICAgCiAgICAtIEluIHRoZSAqKlNhdmUgeW91ciByZXN1bHQqKiBib3gsIGVudGVyIGBsd2FfbGltbm9gCgogICAgPGJyPgogICAgIVtdKGltYWdlcy9zcWxfY3N2X2NvbnZlcnRfczcucG5nKQogICAgPGJyPjxicj4KICAgIAogICAgLSBGb3IgdGhlIGxpbmUgZW5kaW5ncywgY2hvb3NlIGVpdGhlciBgQ1JMRmAgaWYgeW91IGFyZSBvbiBhIFdpbmRvd3MgY29tcHV0ZXIgYW5kIGBMRmAgb3RoZXJ3aXNlCgogICAgPGJyPgogICAgIVtdKGltYWdlcy9zcWxfY3N2X2NvbnZlcnRfczgucG5nKQogICAgPGJyPjxicj4KICAgIAogICAgLSBDbGljayB0aGUgYmx1ZSBgRG93bmxvYWQgUmVzdWx0c2AgYnV0dG9uIHRvIGRvd25sb2FkIHRoZSBgbHdhX2xpbW5vLnNxbGAgZmlsZSB0byB5b3VyIGNvbXB1dGVyIAoKICAgIDxicj4KICAgICFbXShpbWFnZXMvc3FsX2Nzdl9jb252ZXJ0X3M5LnBuZykKICAgIDxicj48YnI+CiAgICAKKioqCgojIENyZWF0aW5nIHRoZSB0YWJsZXMKCiMjIFBETwoKV2Ugbm93IG5lZWQgdG8gY3JlYXRlIHRoZSB0YWJsZXMgZm9yIHRoZSBkYXRhIHdpdGhpbiB0aGUgZGF0YWJhc2UuIFdlJ2xsIGJlZ2luIHdpdGggdGhlIFBETyBkYXRhLgoKLSBJbiAqKnBnQWRtaW4qKiwgY2xpY2sgdGhlIGBUb29sc2AgdGFiIGF0IHRoZSB0b3AgYW5kIHRoZW4gc2VsZWN0IGBRdWVyeSBUb29sYAoKPGJyPgohW10oaW1hZ2VzL3F1ZXJ5X3Rvb2xfMS5wbmcpCjxicj48YnI+CgotIEEgcXVlcnkgZWRpdG9yIHdpbmRvdyB3aWxsIG9wZW4gaW4gKipwZ0FkbWluKioKCi0gQ2xpY2sgb24gdGhlIG9wZW4gZm9sZGVyIGljb24sIHdoaWNoIHdpbGwgYWxsb3cgeW91IHRvIHNlbGVjdCB0aGUgU1FMIGZpbGUgd2UgW3NhdmVkIGFib3ZlXSgjY3JlYXRlLXBkbykKCjxicj4KIVtdKGltYWdlcy9xdWVyeV90b29sXzIucG5nKQo8YnI+PGJyPgoKLSBOYXZpZ2F0ZSB0byB0aGUgbG9jYXRpb24gd2hlcmUgeW91IHNhdmVkIHlvdXIgYHBkb19kYXRhLnNxbGAsIHNlbGVjdCBpdCwgYW5kIHRoZW4gY2xpY2sgdGhlIGJsdWUgKipTZWxlY3QqKiBidXR0b24KCjxicj4KCjxpbWcgc3JjPSJpbWFnZXMvcXVlcnlfdG9vbF8zYS5wbmciIGNsYXNzPSJzbWFsbCI+Cgo8YnI+CgotIFlvdSB3aWxsIG5vdyBzZWUgdGhlIFNRTCBjb2RlIGluIHRoZSBlZGl0b3Igd2luZG93LCB0aGF0IGJlZ2lucyB3aXRoIAoKYGBgCkNSRUFURSBUQUJMRSBwdWJsaWMucGRvKAogICBkYXRlIElOVEVHRVIgIE5PVCBOVUxMIFBSSU1BUlkgS0VZIAogICxwZG8gIE5VTUVSSUMoNSwyKSBOT1QgTlVMTAopOwpJTlNFUlQgSU5UTyBwdWJsaWMucGRvKGRhdGUscGRvKSBWQUxVRVMKICgxODU0MDEsMC4xMSkKLCgxODU0MDIsLTAuMjQpCiwoMTg1NDAzLC0wLjQpCiwoMTg1NDA0LC0wLjQ0KQosKDE4NTQwNSwtMC41NCkKLCgxODU0MDYsLTAuMykKYGBgCgo8YnI+CiFbXShpbWFnZXMvcnVuX3NxbF8xYS5wbmcpCjxicj48YnI+CgotIENsaWNrIHRoZSB0cmlhbmd1bGFyIHBsYXkgYnV0dG9uIGF0IHRoZSB0b3AgdG8gZXhlY3V0ZSB0aGUgKipTUUwqKgoKLSBUaGUgY29kZSBzaG91bGQgZXhlY3V0ZSBub3cgYW5kICoqcGdBZG1pbioqIHNob3VsZCByZXNwb25kCgpgYGAKSU5TRVJUIDAgMjAwNAoKUXVlcnkgcmV0dXJuZWQgc3VjY2Vzc2Z1bGx5IGluIDQyIG1zZWMuCmBgYAoKKE5vdGUgdGhhdCB0aGUgdGltZSBpdCB0b29rIHRoZSBxdWVyeSB0byBydW4gd2lsbCBkZXBlbmQgb24geW91ciBjb21wdXRlciByZXNvdXJjZXMuKQoKPGJyPgohW10oaW1hZ2VzL3J1bl9zcWxfMmEucG5nKQo8YnI+PGJyPgoKLSBJbiB0aGUgKipwZ0FkbWluKiogb2JqZWN0IGJyb3dzZXIsIGNsaWNrIG9uIGBTY2hlbWFzID4gcHVibGljID4gVGFibGVzID4gcGRvYCB0byBzZWUgdGhlIGNvbnRlbnRzIG9mIHlvdXIgbmV3IHRhYmxlIGBwZG9gCgotIFJpZ2h0IGNsaWNrIG9uIHRoZSBgcGRvYCB0YWJsZSBhbmQgdGhlbiBjbGljayBgVmlldy9FZGl0IERhdGFgIGFuZCB0aGVuIGBBbGwgUm93c2AKCjxicj4KIVtdKGltYWdlcy92aWV3X3RhYmxlXzFhLnBuZykKPGJyPjxicj4KCi0gVGhlIHF1ZXJ5IGVkaXRvciB3aWxsIHNob3cgeW91IHRoZSBmb2xsb3dpbmcgcXVlcnkgdXNlZCB0byBjYWxsIGFsbCByZWNvcmRzIGZvciB0aGUgdGFibGUgaW4gdGhlIHVwcGVyIHBhbmUgYW5kIHNob3cgdGhlIHJlc3VsdCBzZXQgZm9yIHRoYXQgcXVlcnkgaW4gdGhlIGxvd2VyIHBhbmUuIAoKYGBgClNFTEVDVCAqIEZST00gcHVibGljLnBkbwpPUkRFUiBCWSBkYXRlIEFTQwpgYGAKCjxicj4KIVtdKGltYWdlcy92aWV3X3RhYmxlXzJhLnBuZykKPGJyPjxicj4KCiMjIExpbW5vbG9neSAKCi0gSW4gKipwZ0FkbWluKiosIGNsaWNrIHRoZSBgVG9vbHNgIHRhYiBhdCB0aGUgdG9wIGFuZCB0aGVuIHNlbGVjdCBgUXVlcnkgVG9vbGAKCjxicj4KIVtdKGltYWdlcy9xdWVyeV90b29sXzEucG5nKQo8YnI+PGJyPgoKLSBBIHF1ZXJ5IGVkaXRvciB3aW5kb3cgd2lsbCBvcGVuIGluICoqcGdBZG1pbioqCgotIENsaWNrIG9uIHRoZSBvcGVuIGZvbGRlciBpY29uLCB3aGljaCB3aWxsIGFsbG93IHlvdSB0byBzZWxlY3QgdGhlIFNRTCBmaWxlIHdlIFtzYXZlZCBhYm92ZV0oI2NyZWF0ZS1sd2EpCgo8YnI+CiFbXShpbWFnZXMvcXVlcnlfdG9vbF8yLnBuZykKPGJyPjxicj4KCi0gTmF2aWdhdGUgdG8gdGhlIGxvY2F0aW9uIHdoZXJlIHlvdSBzYXZlZCB5b3VyIGBsd2FfbGltbm8uc3FsYCwgc2VsZWN0IGl0LCBhbmQgdGhlbiBjbGljayB0aGUgYmx1ZSAqKlNlbGVjdCoqIGJ1dHRvbgoKPGJyPgoKPGltZyBzcmM9ImltYWdlcy9xdWVyeV90b29sXzMucG5nIiBjbGFzcz0ic21hbGwiPgoKPGJyPgoKLSBZb3Ugd2lsbCBub3cgc2VlIHRoZSBTUUwgY29kZSBpbiB0aGUgZWRpdG9yIHdpbmRvdywgdGhhdCBiZWdpbnMgd2l0aCAKCmBgYApDUkVBVEUgVEFCTEUgc3RhZ2luZy5saW1ubygKICAgWWVhciAgICAgICAgICAgICAgICAgIElOVEVHRVIgIE5PVCBOVUxMCiAgLE1vbnRoICAgICAgICAgICAgICAgICBJTlRFR0VSICBOT1QgTlVMTApgYGAKCjxicj4KIVtdKGltYWdlcy9ydW5fc3FsXzEucG5nKQo8YnI+PGJyPgoKLSBDbGljayB0aGUgdHJpYW5ndWxhciBwbGF5IGJ1dHRvbiBhdCB0aGUgdG9wIHRvIGV4ZWN1dGUgdGhlICoqU1FMKioKCi0gVGhlIGNvZGUgc2hvdWxkIGV4ZWN1dGUgbm93IGFuZCAqKnBnQWRtaW4qKiBzaG91bGQgcmVzcG9uZAoKYGBgCklOU0VSVCAwIDM5NgoKUXVlcnkgcmV0dXJuZWQgc3VjY2Vzc2Z1bGx5IGluIDU4IG1zZWMuCmBgYAoKKE5vdGUgdGhhdCB0aGUgdGltZSBpdCB0b29rIHRoZSBxdWVyeSB0byBydW4gd2lsbCBkZXBlbmQgb24geW91ciBjb21wdXRlciByZXNvdXJjZXMuKQoKPGJyPgohW10oaW1hZ2VzL3J1bl9zcWxfMi5wbmcpCjxicj48YnI+CgotIEluIHRoZSAqKnBnQWRtaW4qKiBvYmplY3QgYnJvd3NlciwgY2xpY2sgb24gYFNjaGVtYXMgPiBzdGFnaW5nID4gVGFibGVzID4gbGltbm9gIHRvIHNlZSB5b3VyIG5ldyB0YWJsZSBgc3RhZ2VfbGFrZV93YWAKCi0gUmlnaHQgY2xpY2sgb24gdGhlIGBsaW1ub2AgdGFibGUgYW5kIHRoZW4gY2xpY2sgYFZpZXcvRWRpdCBEYXRhYCBhbmQgdGhlbiBgQWxsIFJvd3NgCgo8YnI+CiFbXShpbWFnZXMvdmlld190YWJsZV8xLnBuZykKPGJyPjxicj4KCi0gVGhlIHF1ZXJ5IGVkaXRvciB3aWxsIHNob3cgeW91IHRoZSBmb2xsb3dpbmcgcXVlcnkgdXNlZCB0byBjYWxsIGFsbCByZWNvcmRzIGZvciB0aGUgdGFibGUgaW4gdGhlIHVwcGVyIHBhbmUgYW5kIHNob3cgdGhlIHJlc3VsdCBzZXQgZm9yIHRoYXQgcXVlcnkgaW4gdGhlIGxvd2VyIHBhbmUuIAoKYGBgClNFTEVDVCAqIEZST00gc3RhZ2luZy5saW1ubwpgYGAKCjxicj4KIVtdKGltYWdlcy92aWV3X3RhYmxlXzIucG5nKQo8YnI+PGJyPgoKKioqCgojIFRoZSBUcnVtYW4gb3B0aW9ucwoKVGhlcmUgY2FuIGJlIHRpbWVzIHdoZW4gaXQgc2ltcGx5IHNlZW1zIGVhc2llc3QgdG8gYnVybiBpdCBhbGwgZG93biBhbmQgc3RhcnQgb3Zlciwgc28gZG9uJ3QgZmVlbCBiYWQgaWYgeW91IGZpbmQgeW91cnNlbGYgaGVyZS4KCiMjIERlbGV0ZSBhIGRhdGFiYXNleyN0cnVtYW5fMX0KCklmLCBmb3Igd2hhdGV2ZXIgcmVhc29uLCB5b3Ugd2FudCB0byBkZWxldGUgYSBkYXRhYmFzZSwgZG8gdGhpcyBpbiAqKnBnQWRtaW4qKgoKKiBSaWdodC1jbGljayBvbiB0aGUgYGxha2Vfd2FgIGRhdGFiYXNlIGFuZCBzZWxlY3QgYERlbGV0ZS9Ecm9wYAoKPGJyPgoKPGltZyBzcmM9ImltYWdlcy9kYl9kcm9wLnBuZyIgY2xhc3M9InNtYWxsIj4KCjxicj4KCiMjIERlbGV0ZSBhIHVzZXIKCllvdSBjYW5ub3QgZGVsZXRlIGEgdXNlciB3aGlsZSB5b3UgYXJlIGxvZ2dlZCBpbiBhcyB0aGF0IHBlcnNvbi4gVG8gcmVtb3ZlIHRoZSBgbGFrZV93YWAgdXNlciB3ZSBjcmVhdGVkIGhlcmUsIHdlJ2xsIGhhdmUgdG8gZmlyc3QgZGlzY29ubmVjdCBmcm9tIHRoZSBkYXRhYmFzZSwgYW5kIHRoZW4gbG9nIGJhY2sgaW4gYXMgdGhlIGBwb3N0Z3Jlc2Agc3VwZXIgdXNlci4gVG8gZG8gc28gaW4gKipwZ0FkbWluKiosIGZvbGxvdyB0aGVzZSBzdGVwcwoKMSkgUmlnaHQtY2xpY2sgb24gKipQb3N0Z3JlU1FMIDEzKiogaW4gdGhlIG9iamVjdCBicm93c2VyIGFuZCBzZWxlY3QgYERpc2Nvbm5lY3QgU2VydmVyYAoKPGJyPgoKPGltZyBzcmM9ImltYWdlcy9sd2FfdXNlcl9kaXNjb25uZWN0LnBuZyIgY2xhc3M9InNtYWxsIj4KCjxicj4KCjIpIFJpZ2h0LWNsaWNrIG9uICoqUG9zdGdyZVNRTCAxMyoqIGFnYWluIGFuZCBzZWxlY3QgYFByb3BlcnRpZXNgCgo8YnI+Cgo8aW1nIHNyYz0iaW1hZ2VzL3N3aXRjaF91c2VyXzEucG5nIiBjbGFzcz0ic21hbGwiPgoKPGJyPgoKMykgQ2xpY2sgb24gdGhlIGBDb25uZWN0aW9uYCB0YWIgYW5kIGNoYW5nZSBgdXNlcm5hbWVgIHRvIGBwb3N0Z3Jlc2A7IHdoZW4geW91IGFyZSBkb25lLCBjbGljayB0aGUgYmx1ZSAqKlNhdmUqKiBidXR0b24KCjxicj4KCjxpbWcgc3JjPSJpbWFnZXMvc3dpdGNoX3VzZXJfMi5wbmciIGNsYXNzPSJzbWFsbCI+Cgo8YnI+Cgo0KSBSaWdodC1jbGljayBvbiAqKlBvc3RncmVTUUwgMTMqKiBhbmQgc2VsZWN0IGBDb25uZWN0IFNlcnZlcmAKCjxicj4KCjxpbWcgc3JjPSJpbWFnZXMvc3dpdGNoX3VzZXJfMy5wbmciIGNsYXNzPSJzbWFsbCI+Cgo8YnI+Cgo1KSBXaGVuIHByb21wdGVkLCBlbnRlciB0aGUgcGFzc3dvcmQgeW91IHVzZWQgd2hlbiB5b3UgZmlyc3QgaW5zdGFsbGVkICoqUG9zdGdyZVNRTCoqIGFuZCBjbGljayB0aGUgYmx1ZSAqKk9LKiogYnV0dG9uCgo8YnI+Cgo8aW1nIHNyYz0iaW1hZ2VzL3N3aXRjaF91c2VyXzQucG5nIiBjbGFzcz0ic21hbGwiPgoKPGJyPgoKNikgVW5kZXIgKipMb2dpbi9Hcm91cCBSb2xlcyoqIGluIHRoZSBvYmplY3QgYnJvd3NlciwgcmlnaHQtY2xpY2sgb24gYGxha2Vfd2FgIGFuZCBzZWxlY3QgYERlbGV0ZS9Ecm9wYAoKPGJyPgoKPGltZyBzcmM9ImltYWdlcy9kcm9wX2x3YV91c2VyLnBuZyIgY2xhc3M9InNtYWxsIj4KCjxicj4KCg==