Sample Database

This commands below create the SQLite “projectdb2.db” database containing the tables projects, projectmgr, certification and earnedcerts. Inspect the schema creation statements to understand the structure of the database.

library(RSQLite)

# create a new in-memory database
dbcon <- dbConnect(RSQLite::SQLite(), ":memory:")
create table projectmgr (
  pmid integer,
  name text not null,
  primary key (pmid)
)
create table certifications (
  cid integer not null,
  cert text not null,
  body text not null,
  primary key (cid)
)
create table earnedcerts (
  pmid integer,
  cert integer,
  primary key (pmid,cert)
  foreign key (pmid) references projectmgr(pmid)
  foreign key (cert) references certifications(cid)
)
create table projects (
  pid integer,
  pname text default "No Name",
  budget double default 0,
  pmgr integer  not null,
  primary key (pid),
  foreign key (pmgr) references projectmgr(pmid)
)
insert into certifications values
  (1,"PMP","Project Management Institute"),
  (2,"APM","Project Management Institute"),
  (4,"CBAP","International Institute of Business Analysis"),
  (5,"CIPM","American Academy of Project Management")
insert into projectmgr values
  (11,"John Wu"),
  (22,"Ann Molloy"),
  (18,"Sandeep Ranghani"),
  (19,"Alicia Knauss"),
  (38,"Roxanna da Silva"),
  (23,"Wagner Ormond"),
  (47,"Margaret O'Shea"),
  (20,"Alden White")
insert into earnedcerts values
  (11,1),
  (11,4),
  (18,1),
  (22,1),
  (47,1),
  (20,1),
  (20,4),
  (38,5)
insert into projects values
  (100,"GOTAM",350000,11),
  (200,"Data Twist",875000,20),
  (300,"Alpha Launch",12500,18),
  (302,"Alpha Arch Design",38000,18),
  (303,"Alpha Dev",125000,18),
  (305,"Alpha Analytics Dashboard",235000,38),
  (811,"Bootstrap Demo",0,47)

Sample Queries

List all information about project managers

select * from projectmgr
Table 1: 8 records
pmid name
11 John Wu
18 Sandeep Ranghani
19 Alicia Knauss
20 Alden White
22 Ann Molloy
23 Wagner Ormond
38 Roxanna da Silva
47 Margaret O’Shea

List all information about projects

select * from projects
Table 2: 7 records
pid pname budget pmgr
100 GOTAM 350000 11
200 Data Twist 875000 20
300 Alpha Launch 12500 18
302 Alpha Arch Design 38000 18
303 Alpha Dev 125000 18
305 Alpha Analytics Dashboard 235000 38
811 Bootstrap Demo 0 47

List all information about certifications

select * from certifications
Table 3: 4 records
cid cert body
1 PMP Project Management Institute
2 APM Project Management Institute
4 CBAP International Institute of Business Analysis
5 CIPM American Academy of Project Management
select * from earnedcerts
Table 4: 8 records
pmid cert
11 1
11 4
18 1
22 1
47 1
20 1
20 4
38 5

List the names and budgets of all projects with a budget of more than $200,000.

select p.pname, p.budget 
  from projects p
 where p.budget > 200000;
Table 5: 3 records
pname budget
GOTAM 350000
Data Twist 875000
Alpha Analytics Dashboard 235000

How many projects managers are there?

select count(*) as 'NumPMs'
  from projectmgr;
Table 6: 1 records
NumPMs
8

List the names of all project managers who manage at least one project, ordered alphabetically in descending order starting with ‘A’.

select distinct m.name
  from projectmgr m join projects p on (m.pmid = p.pmgr)
 order by m.name;
Table 7: 5 records
name
Alden White
John Wu
Margaret O’Shea
Roxanna da Silva
Sandeep Ranghani

List the names of all project managers who do not manage at least one project.

select name
  from projectmgr
 except
select distinct m.name
  from projectmgr m join projects p on (m.pmid = p.pmgr)
Table 8: 3 records
name
Alicia Knauss
Ann Molloy
Wagner Ormond

List all project names and the name of the project manager.

select p.pname, m.name
  from projects p join projectmgr m on (m.pmid = p.pmgr);
Table 9: 7 records
pname name
GOTAM John Wu
Data Twist Alden White
Alpha Launch Sandeep Ranghani
Alpha Arch Design Sandeep Ranghani
Alpha Dev Sandeep Ranghani
Alpha Analytics Dashboard Roxanna da Silva
Bootstrap Demo Margaret O’Shea

What is the total budget of all projects combined?

select sum(p.budget)
  from projects p;
Table 10: 1 records
sum(p.budget)
1635500

Which project managers have more than one certification?

select m.name, count(*) as 'NumCerts'
  from earnedcerts e join projectmgr m on (e.pmid = m.pmid)
 group by e.pmid
having NumCerts > 1
Table 11: 2 records
name NumCerts
John Wu 2
Alden White 2

List the name of each project manager, the number of projects they manage, and the total combined budget of their projects.

select m.name, count(*) as 'NumProjects', sum(p.budget) as 'TotalBudget'
  from projectmgr m join projects p on (m.pmid = p.pmgr)
 group by p.pmgr
Table 12: 5 records
name NumProjects TotalBudget
John Wu 1 350000
Sandeep Ranghani 3 175500
Alden White 1 875000
Roxanna da Silva 1 235000
Margaret O’Shea 1 0

List all projects that have a project name that contains the text “Alpha”.

select *
  from projects p
 where p.pname like '%Alpha%';
Table 13: 4 records
pid pname budget pmgr
300 Alpha Launch 12500 18
302 Alpha Arch Design 38000 18
303 Alpha Dev 125000 18
305 Alpha Analytics Dashboard 235000 38

What is the average project budget?

select avg(p.budget) from projects p
Table 14: 1 records
avg(p.budget)
233642.9

Which projects are within 10% of the average budget.

select *
  from projects p
 where p.budget > 0.9*(select avg(p.budget) from projects p)
   and p.budget < 1.1*(select avg(p.budget) from projects p);
Table 15: 1 records
pid pname budget pmgr
305 Alpha Analytics Dashboard 235000 38

Which project managers do not have any certifications? List their names.

select p.name
  from projectmgr p
 where p.pmid not in (select distinct e.pmid
                        from earnedcerts e);
Table 16: 2 records
name
Alicia Knauss
Wagner Ormond

Disconnect from Database

dbDisconnect(dbcon)

Conclusion

This tutorial explained the most common SQL query structures using examples.


Files & Resources

All Files for Lesson 70.109

References

No references.

Errata

None collected yet. Let us know.

LS0tCnRpdGxlOiAiUHJhY3RpY2UgUXVlcmllcyBmb3IgU1FMIEkiCnBhcmFtczoKICBjYXRlZ29yeTogNzAKICBudW1iZXI6IDEwOQogIHRpbWU6IDQ1CiAgbGV2ZWw6IGJlZ2lubmVyCiAgdGFnczogInNxbCxqb2lucyxncm91cCBieSIKICBkZXNjcmlwdGlvbjogIlVzZXMgZXhhbXBsZXMgdG8gZXhwbGFpbiB0aGUgYmFzaWMgcXVlcnkgc3RydWN0dXJlIG9mIFNRTAogICAgICAgICAgICAgICAgYW5kIHRoZSBtb3N0IGNvbW1vbiB0eXBlcyBvZiBxdWVyaWVzLiBEZW1vbnN0cmF0ZXMgc2VsZWN0aW9uCiAgICAgICAgICAgICAgICBmcm9tIGEgc2luZ2xlIHRhYmxlLCBhbGlhc2VzLCBmaWx0ZXJpbmcgd2l0aCBXSEVSRSwgaW5uZXIgam9pbnMsCiAgICAgICAgICAgICAgICBncm91cGluZyB3aXRoIEdST1VQIEJZLCBhbmQgYWdncmVnYXRpb24uIgpkYXRlOiAiPHNtYWxsPmByIFN5cy5EYXRlKClgPC9zbWFsbD4iCmF1dGhvcjogIjxzbWFsbD5NYXJ0aW4gU2NoZWRsYmF1ZXI8L3NtYWxsPiIKZW1haWw6ICJtLnNjaGVkbGJhdWVyQG5ldS5lZHUiCmFmZmlsaXRhdGlvbjogIk5vcnRoZWFzdGVybiBVbml2ZXJzaXR5IgpvdXRwdXQ6IAogIGJvb2tkb3duOjpodG1sX2RvY3VtZW50MjoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICB0aGVtZTogc3BhY2VsYWIKICAgIGhpZ2hsaWdodDogdGFuZ28KLS0tCgotLS0KdGl0bGU6ICI8c21hbGw+YHIgcGFyYW1zJGNhdGVnb3J5YC5gciBwYXJhbXMkbnVtYmVyYDwvc21hbGw+PGJyLz48c3BhbiBzdHlsZT0nY29sb3I6ICMyRTQwNTM7IGZvbnQtc2l6ZTogMC45ZW0nPmByIHJtYXJrZG93bjo6bWV0YWRhdGEkdGl0bGVgPC9zcGFuPiIKLS0tCgpgYGB7ciBjb2RlPXhmdW46OnJlYWRfdXRmOChwYXN0ZTAoaGVyZTo6aGVyZSgpLCcvUi9faW5zZXJ0MkRCLlInKSksIGluY2x1ZGUgPSBGQUxTRX0KYGBgCgojIyBTYW1wbGUgRGF0YWJhc2UKClRoaXMgY29tbWFuZHMgYmVsb3cgY3JlYXRlIHRoZSBTUUxpdGUgInByb2plY3RkYjIuZGIiIGRhdGFiYXNlIGNvbnRhaW5pbmcgdGhlIHRhYmxlcyAqKnByb2plY3RzKiosICoqcHJvamVjdG1ncioqLCAqKmNlcnRpZmljYXRpb24qKiBhbmQgKiplYXJuZWRjZXJ0cyoqLiBJbnNwZWN0IHRoZSBzY2hlbWEgY3JlYXRpb24gc3RhdGVtZW50cyB0byB1bmRlcnN0YW5kIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGRhdGFiYXNlLgoKYGBge3J9CmxpYnJhcnkoUlNRTGl0ZSkKCiMgY3JlYXRlIGEgbmV3IGluLW1lbW9yeSBkYXRhYmFzZQpkYmNvbiA8LSBkYkNvbm5lY3QoUlNRTGl0ZTo6U1FMaXRlKCksICI6bWVtb3J5OiIpCmBgYAoKYGBge3NxbCBjb25uZWN0aW9uPWRiY29ufQpjcmVhdGUgdGFibGUgcHJvamVjdG1nciAoCiAgcG1pZCBpbnRlZ2VyLAogIG5hbWUgdGV4dCBub3QgbnVsbCwKICBwcmltYXJ5IGtleSAocG1pZCkKKQpgYGAKCmBgYHtzcWwgY29ubmVjdGlvbj1kYmNvbn0KY3JlYXRlIHRhYmxlIGNlcnRpZmljYXRpb25zICgKICBjaWQgaW50ZWdlciBub3QgbnVsbCwKICBjZXJ0IHRleHQgbm90IG51bGwsCiAgYm9keSB0ZXh0IG5vdCBudWxsLAogIHByaW1hcnkga2V5IChjaWQpCikKYGBgCgpgYGB7c3FsIGNvbm5lY3Rpb249ZGJjb259CmNyZWF0ZSB0YWJsZSBlYXJuZWRjZXJ0cyAoCiAgcG1pZCBpbnRlZ2VyLAogIGNlcnQgaW50ZWdlciwKICBwcmltYXJ5IGtleSAocG1pZCxjZXJ0KQogIGZvcmVpZ24ga2V5IChwbWlkKSByZWZlcmVuY2VzIHByb2plY3RtZ3IocG1pZCkKICBmb3JlaWduIGtleSAoY2VydCkgcmVmZXJlbmNlcyBjZXJ0aWZpY2F0aW9ucyhjaWQpCikKYGBgCgpgYGB7c3FsIGNvbm5lY3Rpb249ZGJjb259CmNyZWF0ZSB0YWJsZSBwcm9qZWN0cyAoCiAgcGlkIGludGVnZXIsCiAgcG5hbWUgdGV4dCBkZWZhdWx0ICJObyBOYW1lIiwKICBidWRnZXQgZG91YmxlIGRlZmF1bHQgMCwKICBwbWdyIGludGVnZXIgIG5vdCBudWxsLAogIHByaW1hcnkga2V5IChwaWQpLAogIGZvcmVpZ24ga2V5IChwbWdyKSByZWZlcmVuY2VzIHByb2plY3RtZ3IocG1pZCkKKQpgYGAKCmBgYHtzcWwgY29ubmVjdGlvbj1kYmNvbn0KaW5zZXJ0IGludG8gY2VydGlmaWNhdGlvbnMgdmFsdWVzCiAgKDEsIlBNUCIsIlByb2plY3QgTWFuYWdlbWVudCBJbnN0aXR1dGUiKSwKICAoMiwiQVBNIiwiUHJvamVjdCBNYW5hZ2VtZW50IEluc3RpdHV0ZSIpLAogICg0LCJDQkFQIiwiSW50ZXJuYXRpb25hbCBJbnN0aXR1dGUgb2YgQnVzaW5lc3MgQW5hbHlzaXMiKSwKICAoNSwiQ0lQTSIsIkFtZXJpY2FuIEFjYWRlbXkgb2YgUHJvamVjdCBNYW5hZ2VtZW50IikKYGBgCgpgYGB7c3FsIGNvbm5lY3Rpb249ZGJjb259Cmluc2VydCBpbnRvIHByb2plY3RtZ3IgdmFsdWVzCiAgKDExLCJKb2huIFd1IiksCiAgKDIyLCJBbm4gTW9sbG95IiksCiAgKDE4LCJTYW5kZWVwIFJhbmdoYW5pIiksCiAgKDE5LCJBbGljaWEgS25hdXNzIiksCiAgKDM4LCJSb3hhbm5hIGRhIFNpbHZhIiksCiAgKDIzLCJXYWduZXIgT3Jtb25kIiksCiAgKDQ3LCJNYXJnYXJldCBPJ1NoZWEiKSwKICAoMjAsIkFsZGVuIFdoaXRlIikKYGBgCgpgYGB7c3FsIGNvbm5lY3Rpb249ZGJjb259Cmluc2VydCBpbnRvIGVhcm5lZGNlcnRzIHZhbHVlcwogICgxMSwxKSwKICAoMTEsNCksCiAgKDE4LDEpLAogICgyMiwxKSwKICAoNDcsMSksCiAgKDIwLDEpLAogICgyMCw0KSwKICAoMzgsNSkKYGBgCgpgYGB7c3FsIGNvbm5lY3Rpb249ZGJjb259Cmluc2VydCBpbnRvIHByb2plY3RzIHZhbHVlcwogICgxMDAsIkdPVEFNIiwzNTAwMDAsMTEpLAogICgyMDAsIkRhdGEgVHdpc3QiLDg3NTAwMCwyMCksCiAgKDMwMCwiQWxwaGEgTGF1bmNoIiwxMjUwMCwxOCksCiAgKDMwMiwiQWxwaGEgQXJjaCBEZXNpZ24iLDM4MDAwLDE4KSwKICAoMzAzLCJBbHBoYSBEZXYiLDEyNTAwMCwxOCksCiAgKDMwNSwiQWxwaGEgQW5hbHl0aWNzIERhc2hib2FyZCIsMjM1MDAwLDM4KSwKICAoODExLCJCb290c3RyYXAgRGVtbyIsMCw0NykKYGBgCgojIyBTYW1wbGUgUXVlcmllcwoKIyMjIExpc3QgYWxsIGluZm9ybWF0aW9uIGFib3V0IHByb2plY3QgbWFuYWdlcnMKCmBgYHtzcWwgY29ubmVjdGlvbj1kYmNvbn0Kc2VsZWN0ICogZnJvbSBwcm9qZWN0bWdyCmBgYAoKIyMjIExpc3QgYWxsIGluZm9ybWF0aW9uIGFib3V0IHByb2plY3RzCgpgYGB7c3FsIGNvbm5lY3Rpb249ZGJjb259CnNlbGVjdCAqIGZyb20gcHJvamVjdHMKYGBgCgojIyMgTGlzdCBhbGwgaW5mb3JtYXRpb24gYWJvdXQgY2VydGlmaWNhdGlvbnMKCmBgYHtzcWwgY29ubmVjdGlvbj1kYmNvbn0Kc2VsZWN0ICogZnJvbSBjZXJ0aWZpY2F0aW9ucwpgYGAKCmBgYHtzcWwgY29ubmVjdGlvbj1kYmNvbn0Kc2VsZWN0ICogZnJvbSBlYXJuZWRjZXJ0cwpgYGAKCiMjIyBMaXN0IHRoZSBuYW1lcyBhbmQgYnVkZ2V0cyBvZiBhbGwgcHJvamVjdHMgd2l0aCBhIGJ1ZGdldCBvZiBtb3JlIHRoYW4gXCQyMDAsMDAwLgoKYGBge3NxbCBjb25uZWN0aW9uPWRiY29ufQpzZWxlY3QgcC5wbmFtZSwgcC5idWRnZXQgCiAgZnJvbSBwcm9qZWN0cyBwCiB3aGVyZSBwLmJ1ZGdldCA+IDIwMDAwMDsKYGBgCgojIyMgSG93IG1hbnkgcHJvamVjdHMgbWFuYWdlcnMgYXJlIHRoZXJlPwoKYGBge3NxbCBjb25uZWN0aW9uPWRiY29ufQpzZWxlY3QgY291bnQoKikgYXMgJ051bVBNcycKICBmcm9tIHByb2plY3RtZ3I7CmBgYAoKIyMjIExpc3QgdGhlIG5hbWVzIG9mIGFsbCBwcm9qZWN0IG1hbmFnZXJzIHdobyBtYW5hZ2UgYXQgbGVhc3Qgb25lIHByb2plY3QsIG9yZGVyZWQgYWxwaGFiZXRpY2FsbHkgaW4gZGVzY2VuZGluZyBvcmRlciBzdGFydGluZyB3aXRoICdBJy4KCmBgYHtzcWwgY29ubmVjdGlvbj1kYmNvbn0Kc2VsZWN0IGRpc3RpbmN0IG0ubmFtZQogIGZyb20gcHJvamVjdG1nciBtIGpvaW4gcHJvamVjdHMgcCBvbiAobS5wbWlkID0gcC5wbWdyKQogb3JkZXIgYnkgbS5uYW1lOwpgYGAKCiMjIyBMaXN0IHRoZSBuYW1lcyBvZiBhbGwgcHJvamVjdCBtYW5hZ2VycyB3aG8gZG8gbm90IG1hbmFnZSBhdCBsZWFzdCBvbmUgcHJvamVjdC4KCmBgYHtzcWwgY29ubmVjdGlvbj1kYmNvbn0Kc2VsZWN0IG5hbWUKICBmcm9tIHByb2plY3RtZ3IKIGV4Y2VwdApzZWxlY3QgZGlzdGluY3QgbS5uYW1lCiAgZnJvbSBwcm9qZWN0bWdyIG0gam9pbiBwcm9qZWN0cyBwIG9uIChtLnBtaWQgPSBwLnBtZ3IpCmBgYAoKIyMjIExpc3QgYWxsIHByb2plY3QgbmFtZXMgYW5kIHRoZSBuYW1lIG9mIHRoZSBwcm9qZWN0IG1hbmFnZXIuCgpgYGB7c3FsIGNvbm5lY3Rpb249ZGJjb259CnNlbGVjdCBwLnBuYW1lLCBtLm5hbWUKICBmcm9tIHByb2plY3RzIHAgam9pbiBwcm9qZWN0bWdyIG0gb24gKG0ucG1pZCA9IHAucG1ncik7CmBgYAoKIyMjIFdoYXQgaXMgdGhlIHRvdGFsIGJ1ZGdldCBvZiBhbGwgcHJvamVjdHMgY29tYmluZWQ/CgpgYGB7c3FsIGNvbm5lY3Rpb249ZGJjb259CnNlbGVjdCBzdW0ocC5idWRnZXQpCiAgZnJvbSBwcm9qZWN0cyBwOwpgYGAKCiMjIyBXaGljaCBwcm9qZWN0IG1hbmFnZXJzIGhhdmUgbW9yZSB0aGFuIG9uZSBjZXJ0aWZpY2F0aW9uPwoKYGBge3NxbCBjb25uZWN0aW9uPWRiY29ufQpzZWxlY3QgbS5uYW1lLCBjb3VudCgqKSBhcyAnTnVtQ2VydHMnCiAgZnJvbSBlYXJuZWRjZXJ0cyBlIGpvaW4gcHJvamVjdG1nciBtIG9uIChlLnBtaWQgPSBtLnBtaWQpCiBncm91cCBieSBlLnBtaWQKaGF2aW5nIE51bUNlcnRzID4gMQpgYGAKCiMjIyBMaXN0IHRoZSBuYW1lIG9mIGVhY2ggcHJvamVjdCBtYW5hZ2VyLCB0aGUgbnVtYmVyIG9mIHByb2plY3RzIHRoZXkgbWFuYWdlLCBhbmQgdGhlIHRvdGFsIGNvbWJpbmVkIGJ1ZGdldCBvZiB0aGVpciBwcm9qZWN0cy4KCmBgYHtzcWwgY29ubmVjdGlvbj1kYmNvbn0Kc2VsZWN0IG0ubmFtZSwgY291bnQoKikgYXMgJ051bVByb2plY3RzJywgc3VtKHAuYnVkZ2V0KSBhcyAnVG90YWxCdWRnZXQnCiAgZnJvbSBwcm9qZWN0bWdyIG0gam9pbiBwcm9qZWN0cyBwIG9uIChtLnBtaWQgPSBwLnBtZ3IpCiBncm91cCBieSBwLnBtZ3IKYGBgCgojIyMgTGlzdCBhbGwgcHJvamVjdHMgdGhhdCBoYXZlIGEgcHJvamVjdCBuYW1lIHRoYXQgY29udGFpbnMgdGhlIHRleHQgIkFscGhhIi4KCmBgYHtzcWwgY29ubmVjdGlvbj1kYmNvbn0Kc2VsZWN0ICoKICBmcm9tIHByb2plY3RzIHAKIHdoZXJlIHAucG5hbWUgbGlrZSAnJUFscGhhJSc7CmBgYAoKIyMjIFdoYXQgaXMgdGhlIGF2ZXJhZ2UgcHJvamVjdCBidWRnZXQ/CgpgYGB7c3FsIGNvbm5lY3Rpb249ZGJjb259CnNlbGVjdCBhdmcocC5idWRnZXQpIGZyb20gcHJvamVjdHMgcApgYGAKCiMjIyBXaGljaCBwcm9qZWN0cyBhcmUgd2l0aGluIDEwJSBvZiB0aGUgYXZlcmFnZSBidWRnZXQuCgpgYGB7c3FsIGNvbm5lY3Rpb249ZGJjb259CnNlbGVjdCAqCiAgZnJvbSBwcm9qZWN0cyBwCiB3aGVyZSBwLmJ1ZGdldCA+IDAuOSooc2VsZWN0IGF2ZyhwLmJ1ZGdldCkgZnJvbSBwcm9qZWN0cyBwKQogICBhbmQgcC5idWRnZXQgPCAxLjEqKHNlbGVjdCBhdmcocC5idWRnZXQpIGZyb20gcHJvamVjdHMgcCk7CmBgYAoKIyMjIFdoaWNoIHByb2plY3QgbWFuYWdlcnMgZG8gbm90IGhhdmUgYW55IGNlcnRpZmljYXRpb25zPyBMaXN0IHRoZWlyIG5hbWVzLgoKYGBge3NxbCBjb25uZWN0aW9uPWRiY29ufQpzZWxlY3QgcC5uYW1lCiAgZnJvbSBwcm9qZWN0bWdyIHAKIHdoZXJlIHAucG1pZCBub3QgaW4gKHNlbGVjdCBkaXN0aW5jdCBlLnBtaWQKICAgICAgICAgICAgICAgICAgICAgICAgZnJvbSBlYXJuZWRjZXJ0cyBlKTsKYGBgCgojIyBEaXNjb25uZWN0IGZyb20gRGF0YWJhc2UKCmBgYHtyfQpkYkRpc2Nvbm5lY3QoZGJjb24pCmBgYAoKIyMgQ29uY2x1c2lvbgoKVGhpcyB0dXRvcmlhbCBleHBsYWluZWQgdGhlIG1vc3QgY29tbW9uIFNRTCBxdWVyeSBzdHJ1Y3R1cmVzIHVzaW5nIGV4YW1wbGVzLgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyBGaWxlcyAmIFJlc291cmNlcwoKYGBge3IgemlwRmlsZXMsIGVjaG89RkFMU0V9CnppcE5hbWUgPSBzcHJpbnRmKCJMZXNzb25GaWxlcy0lcy0lcy56aXAiLCAKICAgICAgICAgICAgICAgICBwYXJhbXMkY2F0ZWdvcnksCiAgICAgICAgICAgICAgICAgcGFyYW1zJG51bWJlcikKCnRleHRBTGluayA9IHBhc3RlMCgiQWxsIEZpbGVzIGZvciBMZXNzb24gIiwgCiAgICAgICAgICAgICAgIHBhcmFtcyRjYXRlZ29yeSwiLiIscGFyYW1zJG51bWJlcikKCiMgZG93bmxvYWRGaWxlc0xpbmsoKSBpcyBpbmNsdWRlZCBmcm9tIF9pbnNlcnQyREIuUgprbml0cjo6cmF3X2h0bWwoZG93bmxvYWRGaWxlc0xpbmsoIi4iLCB6aXBOYW1lLCB0ZXh0QUxpbmspKQpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgUmVmZXJlbmNlcwoKTm8gcmVmZXJlbmNlcy4KCiMjIEVycmF0YQoKTm9uZSBjb2xsZWN0ZWQgeWV0LiBMZXQgdXMga25vdy4KCmBgYHs9aHRtbH0KPHNjcmlwdCBzcmM9Imh0dHBzOi8vZm9ybS5qb3Rmb3JtLmNvbS9zdGF0aWMvZmVlZGJhY2syLmpzIiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPgogIG5ldyBKb3Rmb3JtRmVlZGJhY2soewogICAgZm9ybUlkOiAiMjEyMTg3MDcyNzg0MTU3IiwKICAgIGJ1dHRvblRleHQ6ICJGZWVkYmFjayIsCiAgICBiYXNlOiAiaHR0cHM6Ly9mb3JtLmpvdGZvcm0uY29tLyIsCiAgICBiYWNrZ3JvdW5kOiAiI0Y1OTIwMiIsCiAgICBmb250Q29sb3I6ICIjRkZGRkZGIiwKICAgIGJ1dHRvblNpZGU6ICJsZWZ0IiwKICAgIGJ1dHRvbkFsaWduOiAiY2VudGVyIiwKICAgIHR5cGU6IGZhbHNlLAogICAgd2lkdGg6IDcwMCwKICAgIGhlaWdodDogNTAwLAogICAgaXNDYXJkRm9ybTogZmFsc2UKICB9KTsKPC9zY3JpcHQ+CmBgYApgYGB7ciBjb2RlPXhmdW46OnJlYWRfdXRmOChwYXN0ZTAoaGVyZTo6aGVyZSgpLCcvUi9fZGVwbG95S25pdC5SJykpLCBpbmNsdWRlID0gRkFMU0V9CmBgYAo=