Julius Schmid

In-class activity 5

Good afternoon all! First let us find out what our working directory is.

getwd()
[1] "/cloud/project"

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")
Error in install.packages : Updating loaded packages

We import our new downloaded library sqldf.

library(sqldf)
Loading required package: gsubfn
Loading required package: proto
Warning: couldn't connect to display ":0"Loading required package: RSQLite

We upload the csv file quiz2.csv and import it with the read.csv function. Since in the data file we have headers, we set header = TRUE. The separator in this file is a comma.

data1<-read.csv("quiz2.csv",header = TRUE,sep = ",")

We let us give out a summary of the data frame:

summary(data1)
  subregion            region               pop              income          ipaddr       
 Length:29          Length:29          Min.   :   2311   Min.   :26784   Min.   :    637  
 Class :character   Class :character   1st Qu.:  19005   1st Qu.:37970   1st Qu.:  12294  
 Mode  :character   Mode  :character   Median :  32122   Median :41595   Median :  30418  
                                       Mean   : 135940   Mean   :43858   Mean   : 440130  
                                       3rd Qu.: 101482   3rd Qu.:47469   3rd Qu.: 102104  
                                       Max.   :1554720   Max.   :70821   Max.   :5394949  
    ufo2010         infections  
 Min.   :  0.00   Min.   :  39  
 1st Qu.:  0.00   1st Qu.: 123  
 Median :  2.00   Median : 245  
 Mean   : 16.66   Mean   :1117  
 3rd Qu.:  9.00   3rd Qu.: 672  
 Max.   :169.00   Max.   :6781  

Let us run a query that returns every single record from the table data1.

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 create a query that returns the first 10 records of the data1 table.

sqldf('SELECT * FROM data1 LIMIT 10')

Next, select all columns from the data1 table, order it by the parameter infections (from big to small) and return the first 5 columns.

sqldf("SELECT * FROM data1 ORDER BY infections DESC  LIMIT 5")

Now run a similar query (limit 7) including the attributes ipadddr , ufo2010 ,and infections.

sqldf("SELECT ipaddr, ufo2010, infections FROM data1 ORDER BY infections DESC  LIMIT 7")

In the next step, we return the columns region and infections, filter all the rows where the number of infections is greater than 1000 and sort the rows by infections from highn to low.

sqldf('SELECT region,infections FROM data1 WHERE infections > 1000 order by 2 desc')

Now I would like you to inspect (create a query) income,region and population when the condition is income>=50,000. Make comments.

To do this, we select the columns income, region, and population (pop) from data1 where the income is greater than or equal to 50,000.

sqldf('SELECT income, region, pop FROM data1 WHERE income >= 50000')

These are only six rows, representing Idaho, Colorado, Pennsylvania, Vermont, California, and New York.

Next, we create a query to return the whole rows of data1 where either, income is greater than 50000 and infections greater than 2000 (case 1), or the population is greater than 100000 (case 2). Since we have two conditions for case 1, we use the AND operator and parentheses.

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).

Similarly, let us return all the rows where either, income > 50000 and number of ufos > 40 (case 1), or number of infections > 1000.

sqldf('SELECT * FROM data1 WHERE (income > 50000 AND ufo2010 > 40) OR infections > 1000')

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.

In this query, we return all data of subregions that start with the letter A. This could be useful if we have a loss of data and we are looking for values of a specific subregion which we lost (e.g., NA). But all we remember is that the subregion started with the letter A. We do this with the LIKE command and state LIKE “A%” to filter all the rows where subregion starts with an A.

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")

Let us inspect the new table defined below data2.

data2<-read.csv("finalexam.csv",header = TRUE,sep = ",")

Let us apply summary to data2 and examine the output.

summary(data2)
    region               pop              income          ipaddr       
 Length:29          Min.   :   2311   Min.   :26784   Min.   :    637  
 Class :character   1st Qu.:  19005   1st Qu.:37970   1st Qu.:  12294  
 Mode  :character   Median :  32122   Median :41595   Median :  30418  
                    Mean   : 135940   Mean   :43858   Mean   : 440130  
                    3rd Qu.: 101482   3rd Qu.:47469   3rd Qu.: 102104  
                    Max.   :1554720   Max.   :70821   Max.   :5394949  
    ufo2010         infections  
 Min.   :  0.00   Min.   :  39  
 1st Qu.:  0.00   1st Qu.: 123  
 Median :  2.00   Median : 245  
 Mean   : 16.66   Mean   :1117  
 3rd Qu.:  9.00   3rd Qu.: 672  
 Max.   :169.00   Max.   :6781  

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.

We select all columns (*) of the data2 table and filter the region to “West”.

sqldf('SELECT * FROM data2 WHERE region == "West"')

2 - Run a query that returns full details for every record from the east region where the number of infections is greater than 1500.

We select all columns (*) of the data2 table and add a filter where the region is set to “East” and the infections to greater than 1500 at the same time (AND).

sqldf('SELECT * FROM data2 WHERE region == "East" AND infections > 1500')

3 - Run a few queries that can potentially help us to make the point that:

  1. Region affects the number of infections

Select the columns region and infections, and sort by infections (high to low):

sqldf('SELECT region, infections FROM data2 ORDER BY infections DESC')

The most infections seem to appear in the West region.

  1. Population affects the number of infections

Select the pop and infections columns, order by infections (high to low).

sqldf('SELECT pop, infections FROM data2 ORDER BY infections DESC')
  1. Income affects the number of infections

Select the income and infections columns, order by infections (high to low).

sqldf('SELECT income, infections FROM data2 ORDER BY infections DESC')
  1. ufo2010 affects the number of infections

Select the ufo2010 and infections columns, order by infections (high to low).

sqldf('SELECT ufo2010, infections FROM data2 ORDER BY infections DESC')
  1. The different interactions of region and income, and income and population affects the number of infections.

Select the columns region, income, population, and infections, and order by infections (high to low).

sqldf('SELECT region, income, pop, infections FROM data2 ORDER BY infections DESC')
LS0tCnRpdGxlOiAiUiBTUUwiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KSnVsaXVzIFNjaG1pZAoKSW4tY2xhc3MgYWN0aXZpdHkgNSAKCgpHb29kIGFmdGVybm9vbiBhbGwhIEZpcnN0IGxldCB1cyBmaW5kIG91dCB3aGF0IG91ciB3b3JraW5nIGRpcmVjdG9yeSBpcy4KYGBge3J9CmdldHdkKCkKYGBgCgpUb2RheSB3ZSBhcmUgZ29pbmcgdG8gcXVlcnkgdGhlIHRhYmxlIHF1aXoyIGJ5IHVzaW5nIFRyYW5zYWN0LVNRTCBpbnNpZGUgdGhlIFIgY2h1bmtzLiBGaXJzdCwgd2UgYXJlIGdvaW5nIHRvIG5lZWQgdG8gaW5zdGFsbCB0aGUgcGFja2FnZSAqKipzcWxkZioqKi4gCmBgYHtyfQppbnN0YWxsLnBhY2thZ2VzKCJzcWxkZiIpCmBgYAoKV2UgaW1wb3J0IG91ciBuZXcgZG93bmxvYWRlZCBsaWJyYXJ5IHNxbGRmLgpgYGB7cn0KbGlicmFyeShzcWxkZikKYGBgCldlIHVwbG9hZCB0aGUgY3N2IGZpbGUgcXVpejIuY3N2IGFuZCBpbXBvcnQgaXQgd2l0aCB0aGUgcmVhZC5jc3YgZnVuY3Rpb24uIFNpbmNlIGluIHRoZSBkYXRhIGZpbGUgd2UgaGF2ZSBoZWFkZXJzLCB3ZSBzZXQgaGVhZGVyID0gVFJVRS4gVGhlIHNlcGFyYXRvciBpbiB0aGlzIGZpbGUgaXMgYSBjb21tYS4KYGBge3J9CmRhdGExPC1yZWFkLmNzdigicXVpejIuY3N2IixoZWFkZXIgPSBUUlVFLHNlcCA9ICIsIikKYGBgCgpXZSBsZXQgdXMgZ2l2ZSBvdXQgYSBzdW1tYXJ5IG9mIHRoZSBkYXRhIGZyYW1lOgpgYGB7cn0Kc3VtbWFyeShkYXRhMSkKYGBgCgpMZXQgdXMgcnVuIGEgcXVlcnkgdGhhdCByZXR1cm5zIGV2ZXJ5IHNpbmdsZSByZWNvcmQgZnJvbSB0aGUgdGFibGUgZGF0YTEuCmBgYHtyfQpzcWxkZigiU0VMRUNUICogRlJPTSBkYXRhMSIpCmBgYAoKTm93IEkgd291bGQgbGlrZSB5b3UgdG8gY3JlYXRlIGEgcXVlcnkgdGhhdCByZXR1cm5zIGV2ZXJ5IHNpbmdsZSByZWNvcmQgKHJvdykgZm9yIHRoZSBmaWVsZHMgcmVnaW9uIGFuZCBwb3B1bGF0aW9uLgoKTGV0IHVzIGNyZWF0ZSBhIHF1ZXJ5IHRoYXQgcmV0dXJucyB0aGUgZmlyc3QgMTAgcmVjb3JkcyBvZiB0aGUgZGF0YTEgdGFibGUuCmBgYHtyfQpzcWxkZignU0VMRUNUICogRlJPTSBkYXRhMSBMSU1JVCAxMCcpCmBgYAoKTmV4dCwgc2VsZWN0IGFsbCBjb2x1bW5zIGZyb20gdGhlIGRhdGExIHRhYmxlLCBvcmRlciBpdCBieSB0aGUgcGFyYW1ldGVyIGluZmVjdGlvbnMgKGZyb20gYmlnIHRvIHNtYWxsKSBhbmQgcmV0dXJuIHRoZSBmaXJzdCA1IGNvbHVtbnMuCmBgYHtyfQpzcWxkZigiU0VMRUNUICogRlJPTSBkYXRhMSBPUkRFUiBCWSBpbmZlY3Rpb25zIERFU0MgIExJTUlUIDUiKQpgYGAKCk5vdyBydW4gYSBzaW1pbGFyIHF1ZXJ5IChsaW1pdCA3KSBpbmNsdWRpbmcgdGhlIGF0dHJpYnV0ZXMgaXBhZGRkciAsIHVmbzIwMTAgLGFuZCBpbmZlY3Rpb25zLgpgYGB7cn0Kc3FsZGYoIlNFTEVDVCBpcGFkZHIsIHVmbzIwMTAsIGluZmVjdGlvbnMgRlJPTSBkYXRhMSBPUkRFUiBCWSBpbmZlY3Rpb25zIERFU0MgIExJTUlUIDciKQpgYGAKCkluIHRoZSBuZXh0IHN0ZXAsIHdlIHJldHVybiB0aGUgY29sdW1ucyByZWdpb24gYW5kIGluZmVjdGlvbnMsIGZpbHRlciBhbGwgdGhlIHJvd3Mgd2hlcmUgdGhlIG51bWJlciBvZiBpbmZlY3Rpb25zIGlzIGdyZWF0ZXIgdGhhbiAxMDAwIGFuZCBzb3J0IHRoZSByb3dzIGJ5IGluZmVjdGlvbnMgZnJvbSBoaWdobiB0byBsb3cuCmBgYHtyfQpzcWxkZignU0VMRUNUIHJlZ2lvbixpbmZlY3Rpb25zIEZST00gZGF0YTEgV0hFUkUgaW5mZWN0aW9ucyA+IDEwMDAgb3JkZXIgYnkgMiBkZXNjJykKYGBgCgpOb3cgSSB3b3VsZCBsaWtlIHlvdSB0byBpbnNwZWN0IChjcmVhdGUgYSBxdWVyeSkgaW5jb21lLHJlZ2lvbiBhbmQgcG9wdWxhdGlvbiB3aGVuIHRoZSBjb25kaXRpb24gaXMgaW5jb21lPj01MCwwMDAuIE1ha2UgY29tbWVudHMuCgpUbyBkbyB0aGlzLCB3ZSBzZWxlY3QgdGhlIGNvbHVtbnMgaW5jb21lLCByZWdpb24sIGFuZCBwb3B1bGF0aW9uIChwb3ApIGZyb20gZGF0YTEgd2hlcmUgdGhlIGluY29tZSBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gNTAsMDAwLgpgYGB7cn0Kc3FsZGYoJ1NFTEVDVCBpbmNvbWUsIHJlZ2lvbiwgcG9wIEZST00gZGF0YTEgV0hFUkUgaW5jb21lID49IDUwMDAwJykKYGBgClRoZXNlIGFyZSBvbmx5IHNpeCByb3dzLCByZXByZXNlbnRpbmcgSWRhaG8sIENvbG9yYWRvLCBQZW5uc3lsdmFuaWEsIFZlcm1vbnQsIENhbGlmb3JuaWEsIGFuZCBOZXcgWW9yay4KCgpOZXh0LCB3ZSBjcmVhdGUgYSBxdWVyeSB0byByZXR1cm4gdGhlIHdob2xlIHJvd3Mgb2YgZGF0YTEgd2hlcmUgZWl0aGVyLCBpbmNvbWUgaXMgZ3JlYXRlciB0aGFuIDUwMDAwIGFuZCBpbmZlY3Rpb25zIGdyZWF0ZXIgdGhhbiAyMDAwIChjYXNlIDEpLCBvciB0aGUgcG9wdWxhdGlvbiBpcyBncmVhdGVyIHRoYW4gMTAwMDAwIChjYXNlIDIpLiBTaW5jZSB3ZSBoYXZlIHR3byBjb25kaXRpb25zIGZvciBjYXNlIDEsIHdlIHVzZSB0aGUgQU5EIG9wZXJhdG9yIGFuZCBwYXJlbnRoZXNlcy4KYGBge3J9CnNxbGRmKCdTRUxFQ1QgKiBGUk9NIGRhdGExIFdIRVJFIChpbmNvbWUgPiA1MDAwMCBBTkQgaW5mZWN0aW9ucyA+IDIwMDApIE9SIHBvcCA+IDEwMDAwMCcpCmBgYApJbnRlcnByZXQgdGhlIHF1ZXJ5IHJhbiBhYm92ZSBhbmQgY3JlYXRlIGEgcXVlcnkgdGhhdCByZWNyZWF0ZXMgYSBzaW1pbGFyIGNhc2Ugc2NlbmFyaW8gKG9uZSB0aGF0IGlzIGNyaXRpY2FsIGZvciB0aGUgc3VjY2VzcyBvZiB0aGlzIG1pbmktcHJvamVjdCkuCgpTaW1pbGFybHksIGxldCB1cyByZXR1cm4gYWxsIHRoZSByb3dzIHdoZXJlIGVpdGhlciwgaW5jb21lID4gNTAwMDAgYW5kIG51bWJlciBvZiB1Zm9zID4gNDAgKGNhc2UgMSksIG9yIG51bWJlciBvZiBpbmZlY3Rpb25zID4gMTAwMC4KYGBge3J9CnNxbGRmKCdTRUxFQ1QgKiBGUk9NIGRhdGExIFdIRVJFIChpbmNvbWUgPiA1MDAwMCBBTkQgdWZvMjAxMCA+IDQwKSBPUiBpbmZlY3Rpb25zID4gMTAwMCcpCmBgYAoKTGV0IHVzIHJ1biBhIHF1ZXJ5IHRoYXQgcmV0dXJucyBldmVyeSByZWdpb24gYW5kIHBvcHVsYXRpb24gd2l0aCBhIG51bWJlciBvZiBpbmZlY3Rpb25zIGJldHdlZW4gMTAwMCBhbmQgNzAwMC4KYGBge3J9CnNxbGRmKCdTRUxFQ1QgcmVnaW9uLHBvcCBGUk9NIGRhdGExIFdIRVJFIGluZmVjdGlvbnMgYmV0d2VlbiAgMTAwMCBhbmQgNzAwMCcpCmBgYAoKSW50ZXJwcmV0IHRoZSBxdWVyeSBiZWxvdyBhbmQgbGlzdCBhIGh5cG90aGV0aWNhbCBjYXNlIHNjZW5hcmlvIGluIHdoaWNoIHRoaXMgcXVlcnkgd291bGQgYmUgdXNlZnVsLgoKSW4gdGhpcyBxdWVyeSwgd2UgcmV0dXJuIGFsbCBkYXRhIG9mIHN1YnJlZ2lvbnMgdGhhdCBzdGFydCB3aXRoIHRoZSBsZXR0ZXIgQS4gVGhpcyBjb3VsZCBiZSB1c2VmdWwgaWYgd2UgaGF2ZSBhIGxvc3Mgb2YgZGF0YSBhbmQgd2UgYXJlIGxvb2tpbmcgZm9yIHZhbHVlcyBvZiBhIHNwZWNpZmljIHN1YnJlZ2lvbiB3aGljaCB3ZSBsb3N0IChlLmcuLCBOQSkuIEJ1dCBhbGwgd2UgcmVtZW1iZXIgaXMgdGhhdCB0aGUgc3VicmVnaW9uIHN0YXJ0ZWQgd2l0aCB0aGUgbGV0dGVyIEEuIFdlIGRvIHRoaXMgd2l0aCB0aGUgTElLRSBjb21tYW5kIGFuZCBzdGF0ZSBMSUtFICJBJSIgdG8gZmlsdGVyIGFsbCB0aGUgcm93cyB3aGVyZSBzdWJyZWdpb24gc3RhcnRzIHdpdGggYW4gQS4KYGBge3J9CnNxbGRmKCdTRUxFQ1QgKiBGUk9NIGRhdGExIFdIRVJFIHN1YnJlZ2lvbiBMSUtFICJBJSInKQpgYGAKCkxhc3QsIGxldCB1cyBmaW5kIHRoZSBhdmVyYWdlIG51bWJlciBvZiBpbmZlY3Rpb25zIGluIG91ciB0YWJsZS4KYGBge3J9CnNxbGRmKCJTRUxFQ1QgQVZHKGluZmVjdGlvbnMpIEZST00gZGF0YTEiKQpgYGAKCgpMZXQgdXMgaW5zcGVjdCB0aGUgbmV3IHRhYmxlIGRlZmluZWQgYmVsb3cgZGF0YTIuCmBgYHtyfQpkYXRhMjwtcmVhZC5jc3YoImZpbmFsZXhhbS5jc3YiLGhlYWRlciA9IFRSVUUsc2VwID0gIiwiKQpgYGAKCkxldCB1cyBhcHBseSBzdW1tYXJ5IHRvIGRhdGEyIGFuZCBleGFtaW5lIHRoZSBvdXRwdXQuCmBgYHtyfQpzdW1tYXJ5KGRhdGEyKQpgYGAKCk5leHQsIEkgd291bGQgbGlrZSB5b3UgdG8gY29tcGxldGUgdGhlIGZvbGxvd2luZyBzdGVwczoKCjEgLSBSdW4gYSBxdWVyeSB0aGF0IHJldHVybnMgZnVsbCBkZXRhaWxzIGZvciBldmVyeSByZWNvcmQgZnJvbSB0aGUgd2VzdCByZWdpb24uCgpXZSBzZWxlY3QgYWxsIGNvbHVtbnMgKCopIG9mIHRoZSBkYXRhMiB0YWJsZSBhbmQgZmlsdGVyIHRoZSByZWdpb24gdG8gIldlc3QiLgpgYGB7cn0Kc3FsZGYoJ1NFTEVDVCAqIEZST00gZGF0YTIgV0hFUkUgcmVnaW9uID09ICJXZXN0IicpCmBgYAoKMiAtIFJ1biBhIHF1ZXJ5IHRoYXQgcmV0dXJucyBmdWxsIGRldGFpbHMgZm9yIGV2ZXJ5IHJlY29yZCBmcm9tIHRoZSBlYXN0IHJlZ2lvbiB3aGVyZSB0aGUgbnVtYmVyIG9mIGluZmVjdGlvbnMgaXMgZ3JlYXRlciB0aGFuIDE1MDAuCgpXZSBzZWxlY3QgYWxsIGNvbHVtbnMgKCopIG9mIHRoZSBkYXRhMiB0YWJsZSBhbmQgYWRkIGEgZmlsdGVyIHdoZXJlIHRoZSByZWdpb24gaXMgc2V0IHRvICJFYXN0IiBhbmQgdGhlIGluZmVjdGlvbnMgdG8gZ3JlYXRlciB0aGFuIDE1MDAgYXQgdGhlIHNhbWUgdGltZSAoQU5EKS4KYGBge3J9CnNxbGRmKCdTRUxFQ1QgKiBGUk9NIGRhdGEyIFdIRVJFIHJlZ2lvbiA9PSAiRWFzdCIgQU5EIGluZmVjdGlvbnMgPiAxNTAwJykKYGBgCgozIC0gUnVuIGEgZmV3IHF1ZXJpZXMgdGhhdCBjYW4gcG90ZW50aWFsbHkgaGVscCB1cyB0byBtYWtlIHRoZSBwb2ludCB0aGF0OiAKCmEuIFJlZ2lvbiBhZmZlY3RzIHRoZSBudW1iZXIgb2YgaW5mZWN0aW9ucyAKClNlbGVjdCB0aGUgY29sdW1ucyByZWdpb24gYW5kIGluZmVjdGlvbnMsIGFuZCBzb3J0IGJ5IGluZmVjdGlvbnMgKGhpZ2ggdG8gbG93KToKYGBge3J9CnNxbGRmKCdTRUxFQ1QgcmVnaW9uLCBpbmZlY3Rpb25zIEZST00gZGF0YTIgT1JERVIgQlkgaW5mZWN0aW9ucyBERVNDJykKYGBgClRoZSBtb3N0IGluZmVjdGlvbnMgc2VlbSB0byBhcHBlYXIgaW4gdGhlIFdlc3QgcmVnaW9uLgoKYi4gUG9wdWxhdGlvbiBhZmZlY3RzIHRoZSBudW1iZXIgb2YgaW5mZWN0aW9ucyAKClNlbGVjdCB0aGUgcG9wIGFuZCBpbmZlY3Rpb25zIGNvbHVtbnMsIG9yZGVyIGJ5IGluZmVjdGlvbnMgKGhpZ2ggdG8gbG93KS4KYGBge3J9CnNxbGRmKCdTRUxFQ1QgcG9wLCBpbmZlY3Rpb25zIEZST00gZGF0YTIgT1JERVIgQlkgaW5mZWN0aW9ucyBERVNDJykKYGBgCgoKYy4gSW5jb21lIGFmZmVjdHMgdGhlIG51bWJlciBvZiBpbmZlY3Rpb25zCgpTZWxlY3QgdGhlIGluY29tZSBhbmQgaW5mZWN0aW9ucyBjb2x1bW5zLCBvcmRlciBieSBpbmZlY3Rpb25zIChoaWdoIHRvIGxvdykuCmBgYHtyfQpzcWxkZignU0VMRUNUIGluY29tZSwgaW5mZWN0aW9ucyBGUk9NIGRhdGEyIE9SREVSIEJZIGluZmVjdGlvbnMgREVTQycpCmBgYAoKCmQuIHVmbzIwMTAgYWZmZWN0cyB0aGUgbnVtYmVyIG9mIGluZmVjdGlvbnMgCgpTZWxlY3QgdGhlIHVmbzIwMTAgYW5kIGluZmVjdGlvbnMgY29sdW1ucywgb3JkZXIgYnkgaW5mZWN0aW9ucyAoaGlnaCB0byBsb3cpLgpgYGB7cn0Kc3FsZGYoJ1NFTEVDVCB1Zm8yMDEwLCBpbmZlY3Rpb25zIEZST00gZGF0YTIgT1JERVIgQlkgaW5mZWN0aW9ucyBERVNDJykKYGBgCgoKZS4gVGhlIGRpZmZlcmVudCBpbnRlcmFjdGlvbnMgb2YgcmVnaW9uIGFuZCBpbmNvbWUsIGFuZCBpbmNvbWUgYW5kIHBvcHVsYXRpb24gYWZmZWN0cyB0aGUgbnVtYmVyIG9mIGluZmVjdGlvbnMuCgpTZWxlY3QgdGhlIGNvbHVtbnMgcmVnaW9uLCBpbmNvbWUsIHBvcHVsYXRpb24sIGFuZCBpbmZlY3Rpb25zLCBhbmQgb3JkZXIgYnkgaW5mZWN0aW9ucyAoaGlnaCB0byBsb3cpLgpgYGB7cn0Kc3FsZGYoJ1NFTEVDVCByZWdpb24sIGluY29tZSwgcG9wLCBpbmZlY3Rpb25zIEZST00gZGF0YTIgT1JERVIgQlkgaW5mZWN0aW9ucyBERVNDJykKYGBgCg==