Good afternoon all! First let us find out what our working directory
is.
getwd()
[1] "C:/Users/antho/OneDrive/Documents/School/4.DataSecurity&Governance"
Today we are going to query the table quiz2 by using Transact-SQL
inside the R chunks. First, we are going to need to install the package
sqldf.
#install.packages("sqldf")
library(sqldf)
Above we install and load the sqldf package.
Then we upload our dataset quiz 2 to the data1 dataframe
data1<-read.csv("quiz2.csv",header = TRUE,sep = ",")
Then we do some eda with a statistical summary
summary(data1)
subregion region pop income ipaddr ufo2010
Length:29 Length:29 Min. : 2311 Min. :26784 Min. : 637 Min. : 0.00
Class :character Class :character 1st Qu.: 19005 1st Qu.:37970 1st Qu.: 12294 1st Qu.: 0.00
Mode :character Mode :character Median : 32122 Median :41595 Median : 30418 Median : 2.00
Mean : 135940 Mean :43858 Mean : 440130 Mean : 16.66
3rd Qu.: 101482 3rd Qu.:47469 3rd Qu.: 102104 3rd Qu.: 9.00
Max. :1554720 Max. :70821 Max. :5394949 Max. :169.00
infections
Min. : 39
1st Qu.: 123
Median : 245
Mean :1117
3rd Qu.: 672
Max. :6781
Let us run a query that returns every single record from the table
data1. We use the * in the sql script to signify all columns and the
FROM argument to pull it designate the data1 data frame as the
source.
sqldf("SELECT * FROM data1")
Now I would like you to create a query that returns every single
record (row) for the fields region and population.
Let us now create a query that returns the first 10 records of the
data1 table.
sqldf('SELECT * FROM data1 LIMIT 10')
sqldf("SELECT * FROM data1 ORDER BY infections DESC LIMIT 5")
Interpret the output of the query ran above
It shows everything from the top 5 records who have the highest
infections values, organized by the most to least infections.
run a similar query (limit 7) including the attributes
ipadddr , ufo2010 ,and
infections.
sqldf("SELECT region, infections, ufo2010 FROM data1 ORDER BY infections DESC LIMIT 7")
sqldf('SELECT region,infections FROM data1 WHERE infections > 1000 order by 2 desc')
Above Shows the region and infections where the infections are
greater than 1,000 and then organize those records by infections from
greatest to least.
#Now I would like you to inspect (create a query) income,region and
population when the condition is income>=50,000. Make comments.
we can see that our querys condidtions requires the records that have
income higher or equal to 50,000 and also for infections to be greater
than 2000 if not than the record must have population greater than
100,000. We can see that this only produces 9 records. Alameda,
California with the highest population, income, infection, and ufo
sighting.
sqldf('SELECT * FROM data1 WHERE (income > 50000 AND infections > 2000) OR pop > 100000')
Interpret the query ran above and create a query that recreates a
similar case scenario (one that is critical for the success of this
mini-project).
sqldf('SELECT * FROM data1 WHERE (income > 45000 AND infections > 800) OR pop > 80000')
Let us run a query that returns every region and population with a
number of infections between 1000 and 7000.
sqldf('SELECT region,pop FROM data1 WHERE infections between 1000 and 7000')
Interpret the query below and list a hypothetical case scenario in
which this query would be useful.
This shows us the regions and population where infections are above
1000 none of our infections values passes 7000 so we can use that as our
limit
sqldf('SELECT * FROM data1 WHERE subregion LIKE "A%"')
Last,let us find the average number of infections in our table.
sqldf("SELECT AVG(infections) FROM data1")
We see that the average infections is close to the threshold we used
in the 1000-7000 infections table we did above. Showing that that table
displays the population of regions with above average infections.
Let us inspect the new table defined below data2.
data2<-read.csv("finalexam.csv",header = TRUE,sep = ",")
Above we import the final exam csv with column headers Below we
display the top six records
head(data2)
Notice it is similar to our previous dataset except it doesnt have
subregion and it is region field has been changed to a different
classification of three classes East, West, and Central.
Let us apply summary to data2 and examine the output.
summary(data2)
region pop income ipaddr ufo2010 infections
Length:29 Min. : 2311 Min. :26784 Min. : 637 Min. : 0.00 Min. : 39
Class :character 1st Qu.: 19005 1st Qu.:37970 1st Qu.: 12294 1st Qu.: 0.00 1st Qu.: 123
Mode :character Median : 32122 Median :41595 Median : 30418 Median : 2.00 Median : 245
Mean : 135940 Mean :43858 Mean : 440130 Mean : 16.66 Mean :1117
3rd Qu.: 101482 3rd Qu.:47469 3rd Qu.: 102104 3rd Qu.: 9.00 3rd Qu.: 672
Max. :1554720 Max. :70821 Max. :5394949 Max. :169.00 Max. :6781
summary(data1)
subregion region pop income ipaddr ufo2010
Length:29 Length:29 Min. : 2311 Min. :26784 Min. : 637 Min. : 0.00
Class :character Class :character 1st Qu.: 19005 1st Qu.:37970 1st Qu.: 12294 1st Qu.: 0.00
Mode :character Mode :character Median : 32122 Median :41595 Median : 30418 Median : 2.00
Mean : 135940 Mean :43858 Mean : 440130 Mean : 16.66
3rd Qu.: 101482 3rd Qu.:47469 3rd Qu.: 102104 3rd Qu.: 9.00
Max. :1554720 Max. :70821 Max. :5394949 Max. :169.00
infections
Min. : 39
1st Qu.: 123
Median : 245
Mean :1117
3rd Qu.: 672
Max. :6781
After comparing the summary of data2 to data1 We can see that the
values havent changed from the previous data set, except for what we
know of the region column.
Next, I would like you to complete the following steps:
1-Run a query that returns full details for every record from the
west region.
sqldf('SELECT * FROM data2 WHERE region="West"')
NA
Here we are showing only records in the west region with all of their
attributes.We can see the top value (6781) which we know as california,
amongst those 7 records
2-Run a query that returns full details for every record from the
east region where the number of infections is greater than 1500.
sqldf('SELECT * FROM data2 WHERE region="East" and infections >1500')
NA
we can see that there are only 3 records with infections over 1,500
on the east coast, all their attributes are display with them.
3-Run a few queries that can potentially help us to make the point
that:
a.Region affects the number of infections
sqldf('SELECT region, infections FROM data2 group by region')
Above we focus on each group of regions and infections. West has the
most infections followed by east. We could have orderd by infections
descending.
b.Population affects the number of infections
sqldf('SELECT pop, infections FROM data2 order by pop desc')
Here we focus on the top populations to the least populations along
side their infection count
c.Income affects the number of infections
sqldf('SELECT income, infections FROM data2 order by income desc')
Here we focus on the top income to the least income along side their
infection count
d.ufo2010 affects the number of infections
sqldf('SELECT ufo2010, infections FROM data2 order by ufo2010 desc')
Here we focus on the top ufo sighting to the least ufo sighting along
side their infection count
e. The different interactions of region and income, and income and
population affects the number of infections.
sqldf('SELECT region, income FROM data2 group by region order by income desc')
Now we see how the different regions group in income from highest
icome to lowest income. we can see west leads the regions in this as
well.
sqldf('SELECT pop, income FROM data2 order by income desc')
Finally we see the populations with the most income all the way to
the least.
Explain every single query you include in this part of the
handout.
Lastly
Lets re-run all of these but order the records by the infections
column in descending order so we can see them consistent as the other
values change around it.
sqldf('SELECT region, infections FROM data2 group by region order by infections desc')
sqldf('SELECT pop, infections FROM data2 order by infections desc')
sqldf('SELECT income, infections FROM data2 order by infections desc')
sqldf('SELECT ufo2010, infections FROM data2 order by infections desc')
We can see that re-runing it this way better informs us on the top
infections and least infections. Giving us a better sense of the
distribution of other fields against the infections feature.
LS0tDQp0aXRsZTogIkhhbmRvdXRfTGFzdCINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCkdvb2QgYWZ0ZXJub29uIGFsbCEgRmlyc3QgbGV0IHVzIGZpbmQgb3V0IHdoYXQgb3VyIHdvcmtpbmcgZGlyZWN0b3J5IGlzLg0KDQpgYGB7cn0NCmdldHdkKCkNCmBgYA0KDQoNClRvZGF5IHdlIGFyZSBnb2luZyB0byBxdWVyeSB0aGUgdGFibGUgcXVpejIgYnkgdXNpbmcgVHJhbnNhY3QtU1FMIGluc2lkZSB0aGUgUiBjaHVua3MuIEZpcnN0LCB3ZSBhcmUgZ29pbmcgdG8gbmVlZCB0byBpbnN0YWxsIHRoZSBwYWNrYWdlICoqc3FsZGYqKi4NCg0KYGBge3J9DQojaW5zdGFsbC5wYWNrYWdlcygic3FsZGYiKQ0KYGBgDQoNCg0KYGBge3J9DQpsaWJyYXJ5KHNxbGRmKQ0KYGBgDQpBYm92ZSB3ZSBpbnN0YWxsIGFuZCBsb2FkIHRoZSBzcWxkZiBwYWNrYWdlLiANCg0KVGhlbiB3ZSB1cGxvYWQgb3VyIGRhdGFzZXQgcXVpeiAyIHRvIHRoZSBkYXRhMSBkYXRhZnJhbWUNCmBgYHtyfQ0KZGF0YTE8LXJlYWQuY3N2KCJxdWl6Mi5jc3YiLGhlYWRlciA9IFRSVUUsc2VwID0gIiwiKQ0KYGBgDQoNClRoZW4gd2UgZG8gc29tZSBlZGEgd2l0aCBhIHN0YXRpc3RpY2FsIHN1bW1hcnkNCmBgYHtyfQ0Kc3VtbWFyeShkYXRhMSkNCmBgYA0KDQpMZXQgdXMgcnVuIGEgcXVlcnkgdGhhdCByZXR1cm5zIGV2ZXJ5IHNpbmdsZSByZWNvcmQgZnJvbSB0aGUgdGFibGUgZGF0YTEuDQpXZSB1c2UgdGhlICogaW4gdGhlIHNxbCBzY3JpcHQgdG8gc2lnbmlmeSBhbGwgY29sdW1ucyBhbmQgdGhlIEZST00gYXJndW1lbnQgdG8gcHVsbCBpdCBkZXNpZ25hdGUgdGhlIGRhdGExIGRhdGEgZnJhbWUgYXMgdGhlIHNvdXJjZS4NCmBgYHtyfQ0Kc3FsZGYoIlNFTEVDVCAqIEZST00gZGF0YTEiKQ0KYGBgDQoNCk5vdyBJIHdvdWxkIGxpa2UgeW91IHRvIGNyZWF0ZSBhIHF1ZXJ5IHRoYXQgcmV0dXJucyBldmVyeSBzaW5nbGUgcmVjb3JkIChyb3cpIGZvciB0aGUgZmllbGRzIHJlZ2lvbiBhbmQgcG9wdWxhdGlvbi4NCg0KTGV0IHVzIG5vdyBjcmVhdGUgYSBxdWVyeSB0aGF0IHJldHVybnMgdGhlIGZpcnN0IDEwIHJlY29yZHMgb2YgdGhlIGRhdGExIHRhYmxlLg0KDQpgYGB7cn0NCnNxbGRmKCdTRUxFQ1QgKiBGUk9NIGRhdGExIExJTUlUIDEwJykgIyBUaGUgTGltaXQgYXJndW1lbnQgbGV0cyB1cyBzcGVjaWZ5IGhvdyBtYW55IHJvd3Mgc2hvdy4NCmBgYA0KDQoNCmBgYHtyfQ0Kc3FsZGYoIlNFTEVDVCAqIEZST00gZGF0YTEgT1JERVIgQlkgaW5mZWN0aW9ucyBERVNDICBMSU1JVCA1IikNCmBgYA0KDQpJbnRlcnByZXQgdGhlIG91dHB1dCBvZiB0aGUgcXVlcnkgcmFuIGFib3ZlIA0KDQpJdCBzaG93cyBldmVyeXRoaW5nIGZyb20gdGhlIHRvcCA1IHJlY29yZHMgd2hvIGhhdmUgdGhlIGhpZ2hlc3QgaW5mZWN0aW9ucyB2YWx1ZXMsIG9yZ2FuaXplZCBieSB0aGUgbW9zdCB0byBsZWFzdCBpbmZlY3Rpb25zLiANCg0KDQpydW4gYSBzaW1pbGFyIHF1ZXJ5IChsaW1pdCA3KSBpbmNsdWRpbmcgdGhlIGF0dHJpYnV0ZXMgKippcGFkZGRyKiogLCAqKnVmbzIwMTAqKiAsYW5kICoqaW5mZWN0aW9ucyoqLg0KDQpgYGB7cn0NCnNxbGRmKCJTRUxFQ1QgcmVnaW9uLCBpbmZlY3Rpb25zLCB1Zm8yMDEwIEZST00gZGF0YTEgT1JERVIgQlkgaW5mZWN0aW9ucyBERVNDICBMSU1JVCA3IikNCmBgYA0KDQpgYGB7cn0NCnNxbGRmKCdTRUxFQ1QgcmVnaW9uLGluZmVjdGlvbnMgRlJPTSBkYXRhMSBXSEVSRSBpbmZlY3Rpb25zID4gMTAwMCBvcmRlciBieSAyIGRlc2MnKQ0KYGBgDQpBYm92ZSBTaG93cyB0aGUgcmVnaW9uIGFuZCBpbmZlY3Rpb25zIHdoZXJlIHRoZSBpbmZlY3Rpb25zIGFyZSBncmVhdGVyIHRoYW4gMSwwMDAgYW5kIHRoZW4gb3JnYW5pemUgdGhvc2UgcmVjb3JkcyBieSBpbmZlY3Rpb25zIGZyb20gZ3JlYXRlc3QgdG8gbGVhc3QuDQoNCiNOb3cgSSB3b3VsZCBsaWtlIHlvdSB0byBpbnNwZWN0IChjcmVhdGUgYSBxdWVyeSkgaW5jb21lLHJlZ2lvbiBhbmQgcG9wdWxhdGlvbiB3aGVuIHRoZSBjb25kaXRpb24gaXMgaW5jb21lPj01MCwwMDAuIE1ha2UgY29tbWVudHMuDQoNCndlIGNhbiBzZWUgdGhhdCBvdXIgcXVlcnlzIGNvbmRpZHRpb25zIHJlcXVpcmVzIHRoZSByZWNvcmRzIHRoYXQgaGF2ZSBpbmNvbWUgaGlnaGVyIG9yIGVxdWFsIHRvIDUwLDAwMCBhbmQgYWxzbyBmb3IgIGluZmVjdGlvbnMgdG8gYmUgZ3JlYXRlciB0aGFuIDIwMDAgaWYgbm90IHRoYW4gdGhlIHJlY29yZCBtdXN0IGhhdmUgcG9wdWxhdGlvbiBncmVhdGVyIHRoYW4gMTAwLDAwMC4gDQpXZSBjYW4gc2VlIHRoYXQgdGhpcyBvbmx5IHByb2R1Y2VzIDkgcmVjb3Jkcy4gQWxhbWVkYSwgQ2FsaWZvcm5pYSB3aXRoIHRoZSBoaWdoZXN0IHBvcHVsYXRpb24sIGluY29tZSwgaW5mZWN0aW9uLCBhbmQgdWZvIHNpZ2h0aW5nLiANCg0KYGBge3J9DQpzcWxkZignU0VMRUNUICogRlJPTSBkYXRhMSBXSEVSRSAoaW5jb21lID4gNTAwMDAgQU5EIGluZmVjdGlvbnMgPiAyMDAwKSBPUiBwb3AgPiAxMDAwMDAnKQ0KYGBgDQoNCkludGVycHJldCB0aGUgcXVlcnkgcmFuIGFib3ZlIGFuZCBjcmVhdGUgYSBxdWVyeSB0aGF0IHJlY3JlYXRlcyBhIHNpbWlsYXIgY2FzZSBzY2VuYXJpbyAob25lIHRoYXQgaXMgY3JpdGljYWwgZm9yIHRoZSBzdWNjZXNzIG9mIHRoaXMgbWluaS1wcm9qZWN0KS4NCg0KYGBge3J9DQpzcWxkZignU0VMRUNUICogRlJPTSBkYXRhMSBXSEVSRSAoaW5jb21lID4gNDUwMDAgQU5EIGluZmVjdGlvbnMgPiA4MDApIE9SIHBvcCA+IDgwMDAwJykNCmBgYA0KDQpMZXQgdXMgcnVuIGEgcXVlcnkgdGhhdCByZXR1cm5zIGV2ZXJ5IHJlZ2lvbiBhbmQgcG9wdWxhdGlvbiB3aXRoIGEgbnVtYmVyIG9mIGluZmVjdGlvbnMgYmV0d2VlbiAxMDAwIGFuZCA3MDAwLiANCg0KYGBge3J9DQpzcWxkZignU0VMRUNUIHJlZ2lvbixwb3AgRlJPTSBkYXRhMSBXSEVSRSBpbmZlY3Rpb25zIGJldHdlZW4gIDEwMDAgYW5kIDcwMDAnKQ0KYGBgDQoNCkludGVycHJldCB0aGUgcXVlcnkgYmVsb3cgYW5kIGxpc3QgYSBoeXBvdGhldGljYWwgY2FzZSBzY2VuYXJpbyBpbiB3aGljaCB0aGlzIHF1ZXJ5IHdvdWxkIGJlIHVzZWZ1bC4NCg0KVGhpcyBzaG93cyB1cyB0aGUgcmVnaW9ucyBhbmQgcG9wdWxhdGlvbiB3aGVyZSBpbmZlY3Rpb25zIGFyZSBhYm92ZSAxMDAwIG5vbmUgb2Ygb3VyIGluZmVjdGlvbnMgdmFsdWVzIHBhc3NlcyA3MDAwIHNvIHdlIGNhbiB1c2UgdGhhdCBhcyBvdXIgbGltaXQNCg0KYGBge3J9DQpzcWxkZignU0VMRUNUICogRlJPTSBkYXRhMSBXSEVSRSBzdWJyZWdpb24gTElLRSAiQSUiJykNCmBgYA0KDQpMYXN0LGxldCB1cyBmaW5kIHRoZSBhdmVyYWdlIG51bWJlciBvZiBpbmZlY3Rpb25zIGluIG91ciB0YWJsZS4NCg0KYGBge3J9DQpzcWxkZigiU0VMRUNUIEFWRyhpbmZlY3Rpb25zKSBGUk9NIGRhdGExIikNCmBgYA0KV2Ugc2VlIHRoYXQgdGhlIGF2ZXJhZ2UgaW5mZWN0aW9ucyBpcyBjbG9zZSB0byB0aGUgdGhyZXNob2xkIHdlIHVzZWQgaW4gdGhlIDEwMDAtNzAwMCBpbmZlY3Rpb25zIHRhYmxlIHdlIGRpZCBhYm92ZS4gU2hvd2luZyB0aGF0IHRoYXQgdGFibGUgZGlzcGxheXMgdGhlIHBvcHVsYXRpb24gb2YgcmVnaW9ucyB3aXRoIGFib3ZlIGF2ZXJhZ2UgaW5mZWN0aW9ucy4gDQoNCkxldCB1cyBpbnNwZWN0IHRoZSBuZXcgdGFibGUgZGVmaW5lZCBiZWxvdyBkYXRhMi4NCg0KYGBge3J9DQpkYXRhMjwtcmVhZC5jc3YoImZpbmFsZXhhbS5jc3YiLGhlYWRlciA9IFRSVUUsc2VwID0gIiwiKQ0KYGBgDQoNCkFib3ZlIHdlIGltcG9ydCB0aGUgZmluYWwgZXhhbSBjc3Ygd2l0aCBjb2x1bW4gaGVhZGVycw0KQmVsb3cgd2UgZGlzcGxheSB0aGUgdG9wIHNpeCByZWNvcmRzDQoNCmBgYHtyfQ0KaGVhZChkYXRhMikNCmBgYA0KTm90aWNlIGl0IGlzIHNpbWlsYXIgdG8gb3VyIHByZXZpb3VzIGRhdGFzZXQgZXhjZXB0IGl0IGRvZXNudCBoYXZlIHN1YnJlZ2lvbiBhbmQgaXQgaXMgcmVnaW9uIGZpZWxkIGhhcyBiZWVuIGNoYW5nZWQgdG8gYSBkaWZmZXJlbnQgY2xhc3NpZmljYXRpb24gb2YgdGhyZWUgY2xhc3NlcyBFYXN0LCBXZXN0LCBhbmQgQ2VudHJhbC4NCg0KTGV0IHVzIGFwcGx5IHN1bW1hcnkgdG8gZGF0YTIgYW5kIGV4YW1pbmUgdGhlIG91dHB1dC4NCmBgYHtyfQ0Kc3VtbWFyeShkYXRhMikNCmBgYA0KYGBge3J9DQpzdW1tYXJ5KGRhdGExKQ0KYGBgDQoNCkFmdGVyIGNvbXBhcmluZyB0aGUgc3VtbWFyeSBvZiBkYXRhMiB0byBkYXRhMSBXZSBjYW4gc2VlIHRoYXQgdGhlIHZhbHVlcyBoYXZlbnQgY2hhbmdlZCBmcm9tIHRoZSBwcmV2aW91cyBkYXRhIHNldCwgZXhjZXB0IGZvciB3aGF0IHdlIGtub3cgb2YgdGhlIHJlZ2lvbiBjb2x1bW4uDQoNCk5leHQsIEkgd291bGQgbGlrZSB5b3UgdG8gY29tcGxldGUgdGhlIGZvbGxvd2luZyBzdGVwczoNCg0KIyMgMS1SdW4gYSBxdWVyeSB0aGF0IHJldHVybnMgZnVsbCBkZXRhaWxzIGZvciBldmVyeSByZWNvcmQgZnJvbSB0aGUgd2VzdCByZWdpb24uDQoNCmBgYHtyfQ0Kc3FsZGYoJ1NFTEVDVCAqIEZST00gZGF0YTIgV0hFUkUgcmVnaW9uPSJXZXN0IicpDQoNCmBgYA0KSGVyZSB3ZSBhcmUgc2hvd2luZyBvbmx5IHJlY29yZHMgaW4gdGhlIHdlc3QgcmVnaW9uIHdpdGggYWxsIG9mIHRoZWlyIGF0dHJpYnV0ZXMuV2UgY2FuIHNlZSB0aGUgdG9wIHZhbHVlICg2NzgxKSB3aGljaCB3ZSBrbm93IGFzIGNhbGlmb3JuaWEsIGFtb25nc3QgdGhvc2UgNyByZWNvcmRzIA0KDQojIyAyLVJ1biBhIHF1ZXJ5IHRoYXQgcmV0dXJucyBmdWxsIGRldGFpbHMgZm9yIGV2ZXJ5IHJlY29yZCBmcm9tIHRoZSBlYXN0IHJlZ2lvbiB3aGVyZSB0aGUgbnVtYmVyIG9mIGluZmVjdGlvbnMgaXMgZ3JlYXRlciB0aGFuIDE1MDAuDQoNCmBgYHtyfQ0Kc3FsZGYoJ1NFTEVDVCAqIEZST00gZGF0YTIgV0hFUkUgcmVnaW9uPSJFYXN0IiBhbmQgaW5mZWN0aW9ucyA+MTUwMCcpDQoNCmBgYA0Kd2UgY2FuIHNlZSB0aGF0IHRoZXJlIGFyZSBvbmx5IDMgcmVjb3JkcyB3aXRoIGluZmVjdGlvbnMgb3ZlciAxLDUwMCBvbiB0aGUgZWFzdCBjb2FzdCwgYWxsIHRoZWlyIGF0dHJpYnV0ZXMgYXJlIGRpc3BsYXkgd2l0aCB0aGVtLg0KDQojIyAzLVJ1biBhIGZldyBxdWVyaWVzIHRoYXQgY2FuIHBvdGVudGlhbGx5IGhlbHAgdXMgdG8gbWFrZSB0aGUgcG9pbnQgdGhhdDoNCiAgDQojIyMgIGEuUmVnaW9uIGFmZmVjdHMgdGhlIG51bWJlciBvZiBpbmZlY3Rpb25zDQogIA0KYGBge3J9DQpzcWxkZignU0VMRUNUIHJlZ2lvbiwgaW5mZWN0aW9ucyBGUk9NIGRhdGEyIGdyb3VwIGJ5IHJlZ2lvbicpDQpgYGANCkFib3ZlIHdlIGZvY3VzIG9uIGVhY2ggZ3JvdXAgb2YgcmVnaW9ucyBhbmQgaW5mZWN0aW9ucy4NCldlc3QgaGFzIHRoZSBtb3N0IGluZmVjdGlvbnMgZm9sbG93ZWQgYnkgZWFzdC4NCldlIGNvdWxkIGhhdmUgb3JkZXJkIGJ5IGluZmVjdGlvbnMgZGVzY2VuZGluZy4NCg0KIyMjIGIuUG9wdWxhdGlvbiBhZmZlY3RzIHRoZSBudW1iZXIgb2YgaW5mZWN0aW9ucw0KDQpgYGB7cn0NCnNxbGRmKCdTRUxFQ1QgcG9wLCBpbmZlY3Rpb25zIEZST00gZGF0YTIgb3JkZXIgYnkgcG9wIGRlc2MnKQ0KYGBgDQpIZXJlIHdlIGZvY3VzIG9uIHRoZSB0b3AgcG9wdWxhdGlvbnMgdG8gdGhlIGxlYXN0IHBvcHVsYXRpb25zIGFsb25nIHNpZGUgdGhlaXIgaW5mZWN0aW9uIGNvdW50DQoNCiMjIyAgIGMuSW5jb21lIGFmZmVjdHMgdGhlIG51bWJlciBvZiBpbmZlY3Rpb25zDQoNCmBgYHtyfQ0Kc3FsZGYoJ1NFTEVDVCBpbmNvbWUsIGluZmVjdGlvbnMgRlJPTSBkYXRhMiBvcmRlciBieSBpbmNvbWUgZGVzYycpDQpgYGANCkhlcmUgd2UgZm9jdXMgb24gdGhlIHRvcCBpbmNvbWUgdG8gdGhlIGxlYXN0IGluY29tZSBhbG9uZyBzaWRlIHRoZWlyIGluZmVjdGlvbiBjb3VudA0KDQojIyMgZC51Zm8yMDEwIGFmZmVjdHMgdGhlIG51bWJlciBvZiBpbmZlY3Rpb25zDQogICANCmBgYHtyfQ0Kc3FsZGYoJ1NFTEVDVCB1Zm8yMDEwLCBpbmZlY3Rpb25zIEZST00gZGF0YTIgb3JkZXIgYnkgdWZvMjAxMCBkZXNjJykNCmBgYA0KSGVyZSB3ZSBmb2N1cyBvbiB0aGUgdG9wIHVmbyBzaWdodGluZyB0byB0aGUgbGVhc3QgdWZvIHNpZ2h0aW5nIGFsb25nIHNpZGUgdGhlaXIgaW5mZWN0aW9uIGNvdW50DQoNCg0KIyMjIGUuIFRoZSBkaWZmZXJlbnQgaW50ZXJhY3Rpb25zIG9mIHJlZ2lvbiBhbmQgaW5jb21lLCBhbmQgaW5jb21lIGFuZCBwb3B1bGF0aW9uIGFmZmVjdHMgdGhlIG51bWJlciBvZiBpbmZlY3Rpb25zLg0KICAgDQpgYGB7cn0NCnNxbGRmKCdTRUxFQ1QgcmVnaW9uLCBpbmNvbWUgRlJPTSBkYXRhMiBncm91cCBieSByZWdpb24gb3JkZXIgYnkgaW5jb21lIGRlc2MnKQ0KYGBgICAgDQogIE5vdyB3ZSBzZWUgaG93IHRoZSBkaWZmZXJlbnQgcmVnaW9ucyBncm91cCBpbiBpbmNvbWUgZnJvbSBoaWdoZXN0IGljb21lIHRvIGxvd2VzdCBpbmNvbWUuDQogIHdlIGNhbiBzZWUgd2VzdCBsZWFkcyB0aGUgcmVnaW9ucyBpbiB0aGlzIGFzIHdlbGwuDQoNCiAgDQpgYGB7cn0NCnNxbGRmKCdTRUxFQ1QgcG9wLCBpbmNvbWUgRlJPTSBkYXRhMiBvcmRlciBieSBpbmNvbWUgZGVzYycpDQpgYGAgICANCkZpbmFsbHkgd2Ugc2VlIHRoZSBwb3B1bGF0aW9ucyB3aXRoIHRoZSBtb3N0IGluY29tZSBhbGwgdGhlIHdheSB0byB0aGUgbGVhc3QuIA0KDQojIyMgRXhwbGFpbiBldmVyeSBzaW5nbGUgcXVlcnkgeW91IGluY2x1ZGUgaW4gdGhpcyBwYXJ0IG9mIHRoZSBoYW5kb3V0Lg0KDQojIyBMYXN0bHkNCg0KIyMjIExldHMgcmUtcnVuIGFsbCBvZiB0aGVzZSBidXQgb3JkZXIgdGhlIHJlY29yZHMgYnkgdGhlIGluZmVjdGlvbnMgY29sdW1uIGluIGRlc2NlbmRpbmcgb3JkZXIgc28gd2UgY2FuIHNlZSB0aGVtIGNvbnNpc3RlbnQgYXMgdGhlIG90aGVyIHZhbHVlcyBjaGFuZ2UgYXJvdW5kIGl0LiANCiAgIA0KYGBge3J9DQpzcWxkZignU0VMRUNUIHJlZ2lvbiwgaW5mZWN0aW9ucyBGUk9NIGRhdGEyIGdyb3VwIGJ5IHJlZ2lvbiBvcmRlciBieSBpbmZlY3Rpb25zIGRlc2MnKQ0KYGBgDQogICANCiAgIA0KYGBge3J9DQpzcWxkZignU0VMRUNUIHBvcCwgaW5mZWN0aW9ucyBGUk9NIGRhdGEyIG9yZGVyIGJ5IGluZmVjdGlvbnMgZGVzYycpDQpgYGANCg0KYGBge3J9DQpzcWxkZignU0VMRUNUIGluY29tZSwgaW5mZWN0aW9ucyBGUk9NIGRhdGEyIG9yZGVyIGJ5IGluZmVjdGlvbnMgZGVzYycpDQpgYGANCg0KYGBge3J9DQpzcWxkZignU0VMRUNUIHVmbzIwMTAsIGluZmVjdGlvbnMgRlJPTSBkYXRhMiBvcmRlciBieSBpbmZlY3Rpb25zIGRlc2MnKQ0KYGBgDQpXZSBjYW4gc2VlIHRoYXQgcmUtcnVuaW5nIGl0IHRoaXMgd2F5IGJldHRlciBpbmZvcm1zIHVzIG9uIHRoZSB0b3AgaW5mZWN0aW9ucyBhbmQgbGVhc3QgaW5mZWN0aW9ucy4gR2l2aW5nIHVzIGEgYmV0dGVyIHNlbnNlIG9mIHRoZSBkaXN0cmlidXRpb24gb2Ygb3RoZXIgZmllbGRzIGFnYWluc3QgdGhlIGluZmVjdGlvbnMgZmVhdHVyZS4gDQoNCg0K