In addition to selecting existing columns from a table, you can also create new columns based on the exisiting columns.
The SN7577 table has a series of 25 columns (daily1 - daily25) with values of 0 or 1 depending on whether or not a particular newspaper is read.
If you want to know which newspaper is which, they are listed in the Newspapers table.
Example question:
SELECT daily1, daily2, daily3, daily4, daily5, daily6, daily7, daily8,
daily9, daily10, daily11, daily12, daily13, daily14, daily15,
daily16, daily17, daily18, daily19, daily20, daily21, daily22,
daily23, daily24, daily25
FROM SN7577;
But it would be far more efficient to let the SQL
query do that for us.
So instead of selecting 25 columns, we are going to add the numeric values
of the 25 columns into one new colum.
SELECT (daily1 + daily2 + daily3 + daily4 + daily5 + daily6 + daily7 + daily8 +
daily9 + daily10 + daily11 + daily12 + daily13 + daily14 + daily15 +
daily16 + daily17 + daily18 + daily19 + daily20 + daily21 + daily22 +
daily23 + daily24 + daily25)
FROM SN7577;
- Running this query will give the correct answers, but it uses the expression used in creating the new column as the column name.
- This looks very messy, especially with such a long expression.
- It is always the case that if you create a column in the results of the query it won’t have a name by default.
- SQL will create one for it.
Other relational databases take different approaches to the problem and will pseudo-randomly name the new columns for you with such things as _c0
.
SQLite uses the expression you used to create the column name.
Renaming columns using alias
- Given that creating new columns is so commonly done, SQL does provide a mechansim for giving them names of your choice.
- This is done using the
AS
clause
SELECT (daily1 + daily2 + daily3 + daily4 + daily5 + daily6 + daily7 + daily8 +
daily9 + daily10 + daily11 + daily12 + daily13 + daily14 + daily15 +
daily16 + daily17 + daily18 + daily19 + daily20 + daily21 + daily22 +
daily23 + daily24 + daily25) AS Total_dailies
FROM SN7577;
The AS
keyword itself is optional. You can just put the name of the new column, but I think using the AS
keyword adds clarity.
Creating column names in this way is reffered to as adding an alias. This may seem a bit strange for columns which had no real name in the first place, but the point is, you can give any table column name an alias to be used in the output rather than the original.
In the SN7577
table the column names of Q1
, Q5aiv
, etc. are pretty meaningless. You may well decide to change such names with alias’.
Using built-in functions to create new values
In addition to using simple arithmetic operations to create new columns, you can also use some of the SQLite builtin functions.
Full details of the available builtin functions are available from the SQLite.org wbsite here. https://sqlite.org/lang_corefunc.html#instr
We will look at some of the arithmetic and statistical functions when we deal with aggregations in a later lesson. For now we will focus on some text functions.
To do this we will use the SN7577_Text table
. This table has the same information in it as the SN7577 table but many of the numeric values have been replaced with their text equivalents.
To find out how these text equivalents map to the numeric values you need to refer to the SN7577 data dictionary
document which can be downloaded from here. https://data-lessons.github.io/sql-socialsci/data/audit_of_political_engagement_11_ukda_data_dictionary.docx
Example Exercise
From the Browse Data tab
, select the SN7577_text table
from the drop down list at the top.
Notice that a lot of the coluns now contain text, but some are still numbers and some have both numbers and text. Apart from the key_id column
at the beginning, all of the columns are considered to be text
.
There will be some circumstances where a text number
will cause problems, like in arithmetic.
- We can avoid such problems by using the
cast
function.
- This tells SQLite to change the
data type
of a data item.
It is most commonly used in the way we will use it in changing a text string into an integer or real value.
The format of the cast
function is shown in the following example.
SELECT numage,
cast(numage as Integer)
FROM SN7577_Text;
Example Exercise
- Run the example above in the
Execute SQL
tab.
- Notice that there is no way of telling that the data type has changed.
- DB Browser does not right align numbers as you might expect.
- We will now look at a couple of the more
common text functions
.
- These have equivalents in other programming languages or spreadsheet systems, sometimes with different names.
E.g. SQLLite function substr(a,b,c) vs Excel equivalent mid(a,b,c) https://data-lessons.github.io/sql-socialsci/05-creating-new-columns/
The question in Q5axv
asks whether or not you have influenced policies in the last 12 months and required a boolean response yes or no
.
In the SN7577
table the responses are recorded as 0 and 1
and in the SN7577_Text
file they are recorded as no null and null
.
We want to write queries which will create a new column representing the SN7577 values from the SN7577_Text values.
We can do this using either the substr
or the instr
function.
For example shows the use of substr
:
SELECT Q5axv,
NOT (substr(Q5axv, 1,2) = "no" ) as Q5axv_value
FROM SN7577_Text;
Explanation
- The substr function takes 2 characters starting at character 1 from the value in Q5axv.
- This is compare with the string
no
. The result of the comparison is either the boolean value True
or the boolean value False
.
- SQLite represents the boolean values
True and False
as 1 and 0
. However as we want to return 0 if the expression is True we need to NOT
the whole expression.
Exercise:
Try running the query and check the results:
SELECT Q5axv,
NOT (substr(Q5axv, 1,2) = "no" ) as Q5axv_value
FROM SN7577_Text;
Change the query to use the instr function
and check that you get the same results.
Solution:
SELECT Q5axv,
NOT (instr(Q5axv, "no")) as Q5axv_value
FROM SN7577_Text;
Using SQL syntax to conditionally create new values
The SQLite SQL dialect has a progeramming construct called the case
statement.
This is in fact common to many other programming languages as well.
It can be used in two different ways, both of which can be used to create new columns in a queries’ result set.
First we will use the case statement to accomplish what we just did with the substr
and instr
functions.
SELECT Q5axv ,
case Q5axv
when "no null" then 0
when "null" then 1
end as Q5axv_bool
FROM SN7577_Text;
- This format of the
case
statement allows you to check if various values are equal
to the value in the field given after the case
keyword.
- There is a more general form which alows to to perform any kind of test.
Using SQL syntax to create binned
values
- It is often the case that we wish to convert a continous variable into a an discrete factor type variable.
In SN7577 you can see this being done in the numage and the age variables.
We can use a case
statement to create this type of effect.
The example re-creates the age values used in the SN7577_Text table
with the addition of an “Under age” category for those less than 18 years old.
SELECT numage ,
case
when numage between 18 and 24 then "18 - 24"
when numage between 25 and 34 then "25 - 34"
when numage between 35 and 44 then "35 - 44"
when numage between 45 and 54 then "45 - 54"
when numage between 55 and 59 then "55 - 59"
when numage between 60 and 64 then "60 - 64"
when numage >= 65 then "65+"
else
"Under age"
end as numage_range
FROM SN7577;
LS0tCnRpdGxlOiAiQ3JlYXRpbmcgTmV3IENvbHVtbnMiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCiogSW4gYWRkaXRpb24gdG8gc2VsZWN0aW5nIGV4aXN0aW5nIGNvbHVtbnMgZnJvbSBhIHRhYmxlLCB5b3UgY2FuIGFsc28gY3JlYXRlIG5ldyBjb2x1bW5zIGJhc2VkIG9uIHRoZSBleGlzaXRpbmcgY29sdW1ucy4KCiogVGhlIFNONzU3NyB0YWJsZSBoYXMgYSBzZXJpZXMgb2YgMjUgY29sdW1ucyAoZGFpbHkxIC0gZGFpbHkyNSkgd2l0aCB2YWx1ZXMgb2YgMCBvciAxIGRlcGVuZGluZyBvbiB3aGV0aGVyIG9yIG5vdCBhIHBhcnRpY3VsYXIgbmV3c3BhcGVyIGlzIHJlYWQuIAoKKiBJZiB5b3Ugd2FudCB0byBrbm93IHdoaWNoIG5ld3NwYXBlciBpcyB3aGljaCwgdGhleSBhcmUgbGlzdGVkIGluIHRoZSBOZXdzcGFwZXJzIHRhYmxlLgoKCiMjIyMgRXhhbXBsZSBxdWVzdGlvbjoKKiBXaGF0IHdlIHdhbnQgdG8ga25vdyBpcyBob3cgbWFueSBuZXdzcGFwZXJzIGEgZ2l2ZW4gaG91c2Vob2xkIChyb3cgaW4gdGhlIFNONzU3NyB0YWJsZSkgcmVhZHM/CgoqIFdlIGNvdWxkIHJ1biB0aGUgcXVlcnkgYmVsb3cgYW5kIGNvdW50IHVwIHRoZSBvbmVzPwoKYGBgc3FsClNFTEVDVCBkYWlseTEsIGRhaWx5MiwgZGFpbHkzLCBkYWlseTQsIGRhaWx5NSwgZGFpbHk2LCBkYWlseTcsIGRhaWx5OCwKICAgICAgIGRhaWx5OSwgZGFpbHkxMCwgZGFpbHkxMSwgZGFpbHkxMiwgZGFpbHkxMywgZGFpbHkxNCwgZGFpbHkxNSwKICAgICAgIGRhaWx5MTYsIGRhaWx5MTcsIGRhaWx5MTgsIGRhaWx5MTksIGRhaWx5MjAsIGRhaWx5MjEsIGRhaWx5MjIsCiAgICAgICBkYWlseTIzLCBkYWlseTI0LCBkYWlseTI1CkZST00gU043NTc3OwpgYGAKCiogQnV0IGl0IHdvdWxkIGJlIGZhciBtb3JlIGVmZmljaWVudCB0byBsZXQgdGhlIGBTUUxgIHF1ZXJ5IGRvIHRoYXQgZm9yIHVzLiAKCiogU28gaW5zdGVhZCBvZiBzZWxlY3RpbmcgMjUgY29sdW1ucywgd2UgYXJlIGdvaW5nIHRvIGFkZCB0aGUgYG51bWVyaWMgdmFsdWVzYCBvZiB0aGUgMjUgY29sdW1ucyBpbnRvIG9uZSBuZXcgY29sdW0uCgpgYGBzcWwKU0VMRUNUIChkYWlseTEgKyBkYWlseTIgKyBkYWlseTMgKyBkYWlseTQgKyBkYWlseTUgKyBkYWlseTYgKyBkYWlseTcgKyBkYWlseTggKwogICAgICAgIGRhaWx5OSArIGRhaWx5MTAgKyBkYWlseTExICsgZGFpbHkxMiArIGRhaWx5MTMgKyBkYWlseTE0ICsgZGFpbHkxNSArCiAgICAgICAgZGFpbHkxNiArIGRhaWx5MTcgKyBkYWlseTE4ICsgZGFpbHkxOSArIGRhaWx5MjAgKyBkYWlseTIxICsgZGFpbHkyMiArCiAgICAgICAgZGFpbHkyMyArIGRhaWx5MjQgKyBkYWlseTI1KQpGUk9NIFNONzU3NzsKYGBgCgoqIFJ1bm5pbmcgdGhpcyBxdWVyeSB3aWxsIGdpdmUgdGhlIGNvcnJlY3QgYW5zd2VycywgYnV0IGl0IHVzZXMgdGhlIGV4cHJlc3Npb24gdXNlZCBpbiBjcmVhdGluZyB0aGUgbmV3IGNvbHVtbiBhcyB0aGUgY29sdW1uIG5hbWUuIAoqIFRoaXMgbG9va3MgdmVyeSBtZXNzeSwgZXNwZWNpYWxseSB3aXRoIHN1Y2ggYSBsb25nIGV4cHJlc3Npb24uIAoqIEl0IGlzIGFsd2F5cyB0aGUgY2FzZSB0aGF0IGlmIHlvdSBjcmVhdGUgYSBjb2x1bW4gaW4gdGhlIHJlc3VsdHMgb2YgdGhlIHF1ZXJ5IGl0IHdvbuKAmXQgaGF2ZSBhIG5hbWUgYnkgZGVmYXVsdC4gCiogU1FMIHdpbGwgY3JlYXRlIG9uZSBmb3IgaXQuIAoqIE90aGVyIHJlbGF0aW9uYWwgZGF0YWJhc2VzIHRha2UgZGlmZmVyZW50IGFwcHJvYWNoZXMgdG8gdGhlIHByb2JsZW0gYW5kIHdpbGwgcHNldWRvLXJhbmRvbWx5IG5hbWUgdGhlIG5ldyBjb2x1bW5zIGZvciB5b3Ugd2l0aCBzdWNoIHRoaW5ncyBhcyBgX2MwYC4gCgoqIFNRTGl0ZSB1c2VzIHRoZSBleHByZXNzaW9uIHlvdSB1c2VkIHRvIGNyZWF0ZSB0aGUgY29sdW1uIG5hbWUuCgoKIyMjIFJlbmFtaW5nIGNvbHVtbnMgdXNpbmcgYGFsaWFzYAoKKiBHaXZlbiB0aGF0IGNyZWF0aW5nIG5ldyBjb2x1bW5zIGlzIHNvIGNvbW1vbmx5IGRvbmUsIFNRTCBkb2VzIHByb3ZpZGUgYSBtZWNoYW5zaW0gZm9yIGdpdmluZyB0aGVtIG5hbWVzIG9mIHlvdXIgY2hvaWNlLiAKKiBUaGlzIGlzIGRvbmUgdXNpbmcgdGhlIGBBU2AgY2xhdXNlCgpgYGBzcWwKU0VMRUNUIChkYWlseTEgKyBkYWlseTIgKyBkYWlseTMgKyBkYWlseTQgKyBkYWlseTUgKyBkYWlseTYgKyBkYWlseTcgKyBkYWlseTggKwogICAgICAgIGRhaWx5OSArIGRhaWx5MTAgKyBkYWlseTExICsgZGFpbHkxMiArIGRhaWx5MTMgKyBkYWlseTE0ICsgZGFpbHkxNSArCiAgICAgICAgZGFpbHkxNiArIGRhaWx5MTcgKyBkYWlseTE4ICsgZGFpbHkxOSArIGRhaWx5MjAgKyBkYWlseTIxICsgZGFpbHkyMiArCiAgICAgICAgZGFpbHkyMyArIGRhaWx5MjQgKyBkYWlseTI1KSBBUyBUb3RhbF9kYWlsaWVzCkZST00gU043NTc3OwpgYGAKCiogVGhlIGBBU2Aga2V5d29yZCBpdHNlbGYgaXMgb3B0aW9uYWwuIFlvdSBjYW4ganVzdCBwdXQgdGhlIG5hbWUgb2YgdGhlIG5ldyBjb2x1bW4sIGJ1dCBJIHRoaW5rIHVzaW5nIHRoZSBgQVNgIGtleXdvcmQgYWRkcyBjbGFyaXR5LiAKCiogQ3JlYXRpbmcgY29sdW1uIG5hbWVzIGluIHRoaXMgd2F5IGlzIHJlZmZlcmVkIHRvIGFzIGFkZGluZyBhbiBhbGlhcy4gVGhpcyBtYXkgc2VlbSBhIGJpdCBzdHJhbmdlIGZvciBjb2x1bW5zIHdoaWNoIGhhZCBubyByZWFsIG5hbWUgaW4gdGhlIGZpcnN0IHBsYWNlLCBidXQgdGhlIHBvaW50IGlzLCB5b3UgY2FuIGdpdmUgYW55IHRhYmxlIGNvbHVtbiBuYW1lIGFuIGFsaWFzIHRvIGJlIHVzZWQgaW4gdGhlIG91dHB1dCByYXRoZXIgdGhhbiB0aGUgb3JpZ2luYWwuCgoqIEluIHRoZSBgU043NTc3YCB0YWJsZSB0aGUgY29sdW1uIG5hbWVzIG9mIGBRMWAsIGBRNWFpdmAsIGV0Yy4gYXJlIHByZXR0eSBtZWFuaW5nbGVzcy4gWW91IG1heSB3ZWxsIGRlY2lkZSB0byBjaGFuZ2Ugc3VjaCBuYW1lcyB3aXRoIGFsaWFz4oCZLgoKCiMjIyBVc2luZyBidWlsdC1pbiBmdW5jdGlvbnMgdG8gY3JlYXRlIG5ldyB2YWx1ZXMKKiBJbiBhZGRpdGlvbiB0byB1c2luZyBzaW1wbGUgYXJpdGhtZXRpYyBvcGVyYXRpb25zIHRvIGNyZWF0ZSBuZXcgY29sdW1ucywgeW91IGNhbiBhbHNvIHVzZSBzb21lIG9mIHRoZSBTUUxpdGUgYnVpbHRpbiBmdW5jdGlvbnMuIAoKKiBGdWxsIGRldGFpbHMgb2YgdGhlIGF2YWlsYWJsZSBidWlsdGluIGZ1bmN0aW9ucyBhcmUgYXZhaWxhYmxlIGZyb20gdGhlIFNRTGl0ZS5vcmcgd2JzaXRlIGhlcmUuIGh0dHBzOi8vc3FsaXRlLm9yZy9sYW5nX2NvcmVmdW5jLmh0bWwjaW5zdHIKCiogV2Ugd2lsbCBsb29rIGF0IHNvbWUgb2YgdGhlIGFyaXRobWV0aWMgYW5kIHN0YXRpc3RpY2FsIGZ1bmN0aW9ucyB3aGVuIHdlIGRlYWwgd2l0aCBhZ2dyZWdhdGlvbnMgaW4gYSBsYXRlciBsZXNzb24uIEZvciBub3cgd2Ugd2lsbCBmb2N1cyBvbiBzb21lIHRleHQgZnVuY3Rpb25zLgoKKiBUbyBkbyB0aGlzIHdlIHdpbGwgdXNlIHRoZSBgU043NTc3X1RleHQgdGFibGVgLiBUaGlzIHRhYmxlIGhhcyB0aGUgc2FtZSBpbmZvcm1hdGlvbiBpbiBpdCBhcyB0aGUgU043NTc3IHRhYmxlIGJ1dCBtYW55IG9mIHRoZSBudW1lcmljIHZhbHVlcyBoYXZlIGJlZW4gcmVwbGFjZWQgd2l0aCB0aGVpciB0ZXh0IGVxdWl2YWxlbnRzLiAKCiogVG8gZmluZCBvdXQgaG93IHRoZXNlIHRleHQgZXF1aXZhbGVudHMgbWFwIHRvIHRoZSBudW1lcmljIHZhbHVlcyB5b3UgbmVlZCB0byByZWZlciB0byB0aGUgYFNONzU3NyBkYXRhIGRpY3Rpb25hcnlgIGRvY3VtZW50IHdoaWNoIGNhbiBiZSBkb3dubG9hZGVkIGZyb20gaGVyZS4gIGh0dHBzOi8vZGF0YS1sZXNzb25zLmdpdGh1Yi5pby9zcWwtc29jaWFsc2NpL2RhdGEvYXVkaXRfb2ZfcG9saXRpY2FsX2VuZ2FnZW1lbnRfMTFfdWtkYV9kYXRhX2RpY3Rpb25hcnkuZG9jeAoKIyMjIEV4YW1wbGUgRXhlcmNpc2UKKiBGcm9tIHRoZSBgQnJvd3NlIERhdGEgdGFiYCwgc2VsZWN0IHRoZSBgU043NTc3X3RleHQgdGFibGVgIGZyb20gdGhlIGRyb3AgZG93biBsaXN0IGF0IHRoZSB0b3AuIAoKKiBOb3RpY2UgdGhhdCBhIGxvdCBvZiB0aGUgY29sdW5zIG5vdyBjb250YWluIHRleHQsIGJ1dCBzb21lIGFyZSBzdGlsbCBudW1iZXJzIGFuZCBzb21lIGhhdmUgYm90aCBudW1iZXJzIGFuZCB0ZXh0LiAKQXBhcnQgZnJvbSB0aGUgYGtleV9pZCBjb2x1bW5gIGF0IHRoZSBiZWdpbm5pbmcsIGFsbCBvZiB0aGUgY29sdW1ucyBhcmUgY29uc2lkZXJlZCB0byBiZSBgdGV4dGAuCgotLS0KCgoqIFRoZXJlIHdpbGwgYmUgc29tZSBjaXJjdW1zdGFuY2VzIHdoZXJlIGEgYHRleHQgbnVtYmVyYCB3aWxsIGNhdXNlIHByb2JsZW1zLCBsaWtlIGluIGFyaXRobWV0aWMuIAoKKiBXZSBjYW4gYXZvaWQgc3VjaCBwcm9ibGVtcyBieSB1c2luZyB0aGUgYGNhc3RgIGZ1bmN0aW9uLiAKKiBUaGlzIHRlbGxzIFNRTGl0ZSB0byBjaGFuZ2UgdGhlIGBkYXRhIHR5cGVgIG9mIGEgZGF0YSBpdGVtLiAKKiBJdCBpcyBtb3N0IGNvbW1vbmx5IHVzZWQgaW4gdGhlIHdheSB3ZSB3aWxsIHVzZSBpdCBpbiBjaGFuZ2luZyBhIHRleHQgc3RyaW5nIGludG8gYW4gaW50ZWdlciBvciByZWFsIHZhbHVlLgoKVGhlIGZvcm1hdCBvZiB0aGUgYGNhc3RgIGZ1bmN0aW9uIGlzIHNob3duIGluIHRoZSBmb2xsb3dpbmcgZXhhbXBsZS4KCmBgYHNxbApTRUxFQ1QgbnVtYWdlLAogICAgICAgY2FzdChudW1hZ2UgYXMgSW50ZWdlcikKRlJPTSBTTjc1NzdfVGV4dDsKYGBgCgojIyMgRXhhbXBsZSBFeGVyY2lzZQoqIFJ1biB0aGUgZXhhbXBsZSBhYm92ZSBpbiB0aGUgYEV4ZWN1dGUgU1FMYCB0YWIuIAoqIE5vdGljZSB0aGF0IHRoZXJlIGlzIG5vIHdheSBvZiB0ZWxsaW5nIHRoYXQgdGhlIGRhdGEgdHlwZSBoYXMgY2hhbmdlZC4gCiogREIgQnJvd3NlciBkb2VzIG5vdCByaWdodCBhbGlnbiBudW1iZXJzIGFzIHlvdSBtaWdodCBleHBlY3QuCgotLS0KCiogV2Ugd2lsbCBub3cgbG9vayBhdCBhIGNvdXBsZSBvZiB0aGUgbW9yZSBgY29tbW9uIHRleHQgZnVuY3Rpb25zYC4gCiogVGhlc2UgaGF2ZSBlcXVpdmFsZW50cyBpbiBvdGhlciBwcm9ncmFtbWluZyBsYW5ndWFnZXMgb3Igc3ByZWFkc2hlZXQgc3lzdGVtcywgc29tZXRpbWVzIHdpdGggZGlmZmVyZW50IG5hbWVzLgoqICoqRS5nLiBTUUxMaXRlIGZ1bmN0aW9uIHN1YnN0cihhLGIsYykgIHZzIEV4Y2VsIGVxdWl2YWxlbnQgbWlkKGEsYixjKSoqCmh0dHBzOi8vZGF0YS1sZXNzb25zLmdpdGh1Yi5pby9zcWwtc29jaWFsc2NpLzA1LWNyZWF0aW5nLW5ldy1jb2x1bW5zLwoKCgoqIFRoZSBxdWVzdGlvbiBpbiBgUTVheHZgIGFza3Mgd2hldGhlciBvciBub3QgeW91IGhhdmUgaW5mbHVlbmNlZCBwb2xpY2llcyBpbiB0aGUgbGFzdCAxMiBtb250aHMgYW5kIHJlcXVpcmVkIGEgYm9vbGVhbiByZXNwb25zZSBgeWVzIG9yIG5vYC4gCgoqIEluIHRoZSBgU043NTc3YCB0YWJsZSB0aGUgcmVzcG9uc2VzIGFyZSByZWNvcmRlZCBhcyBgMCBhbmQgMWAgYW5kIGluIHRoZSBgU043NTc3X1RleHRgIGZpbGUgdGhleSBhcmUgcmVjb3JkZWQgYXMgYG5vIG51bGwgYW5kIG51bGxgLgoKKiBXZSB3YW50IHRvIHdyaXRlIHF1ZXJpZXMgd2hpY2ggd2lsbCBjcmVhdGUgYSBuZXcgY29sdW1uIHJlcHJlc2VudGluZyB0aGUgU043NTc3IHZhbHVlcyBmcm9tIHRoZSBTTjc1NzdfVGV4dCB2YWx1ZXMuIAoKKiBXZSBjYW4gZG8gdGhpcyB1c2luZyBlaXRoZXIgdGhlIGBzdWJzdHJgIG9yIHRoZSBgaW5zdHJgIGZ1bmN0aW9uLiAKCiogRm9yIGV4YW1wbGUgc2hvd3MgdGhlIHVzZSBvZiBgc3Vic3RyYDoKCmBgYHNxbApTRUxFQ1QgUTVheHYsCiAgIE5PVCAoc3Vic3RyKFE1YXh2LCAxLDIpID0gIm5vIiApIGFzIFE1YXh2X3ZhbHVlCkZST00gU043NTc3X1RleHQ7CgpgYGAKCiMjIyMgRXhwbGFuYXRpb24KKiBUaGUgc3Vic3RyIGZ1bmN0aW9uIHRha2VzIDIgY2hhcmFjdGVycyBzdGFydGluZyBhdCBjaGFyYWN0ZXIgMSBmcm9tIHRoZSB2YWx1ZSBpbiBRNWF4di4gCiogVGhpcyBpcyBjb21wYXJlIHdpdGggdGhlIHN0cmluZyBgbm9gLiAKVGhlIHJlc3VsdCBvZiB0aGUgY29tcGFyaXNvbiBpcyBlaXRoZXIgdGhlIGJvb2xlYW4gdmFsdWUgYFRydWVgIG9yIHRoZSBib29sZWFuIHZhbHVlIGBGYWxzZWAuIAoqIFNRTGl0ZSByZXByZXNlbnRzIHRoZSBib29sZWFuIHZhbHVlcyBgVHJ1ZSBhbmQgRmFsc2VgIGFzIGAxIGFuZCAwYC4gSG93ZXZlciBhcyB3ZSB3YW50IHRvIHJldHVybiAwIGlmIHRoZSBleHByZXNzaW9uIGlzIFRydWUgd2UgbmVlZCB0byBgTk9UYCB0aGUgd2hvbGUgZXhwcmVzc2lvbi4KCgojIyBFeGVyY2lzZToKVHJ5IHJ1bm5pbmcgdGhlIHF1ZXJ5IGFuZCBjaGVjayB0aGUgcmVzdWx0czoKCmBgYHNxbApTRUxFQ1QgUTVheHYsCiAgIE5PVCAoc3Vic3RyKFE1YXh2LCAxLDIpID0gIm5vIiApIGFzIFE1YXh2X3ZhbHVlCkZST00gU043NTc3X1RleHQ7CmBgYAoKQ2hhbmdlIHRoZSBxdWVyeSB0byB1c2UgdGhlIGBpbnN0ciBmdW5jdGlvbmAgYW5kIGNoZWNrIHRoYXQgeW91IGdldCB0aGUgc2FtZSByZXN1bHRzLgoKIyMjIFNvbHV0aW9uOgpgYGBzcWwKU0VMRUNUIFE1YXh2LAogICBOT1QgKGluc3RyKFE1YXh2LCAibm8iKSkgYXMgUTVheHZfdmFsdWUKRlJPTSBTTjc1NzdfVGV4dDsKYGBgCgojIyMgVXNpbmcgU1FMIHN5bnRheCB0byBjb25kaXRpb25hbGx5IGNyZWF0ZSBuZXcgdmFsdWVzCgoqIFRoZSBTUUxpdGUgU1FMIGRpYWxlY3QgaGFzIGEgcHJvZ2VyYW1taW5nIGNvbnN0cnVjdCBjYWxsZWQgdGhlIGBjYXNlYCBzdGF0ZW1lbnQuCgoqIFRoaXMgaXMgaW4gZmFjdCBjb21tb24gdG8gbWFueSBvdGhlciBwcm9ncmFtbWluZyBsYW5ndWFnZXMgYXMgd2VsbC4gCgoqIEl0IGNhbiBiZSB1c2VkIGluIHR3byBkaWZmZXJlbnQgd2F5cywgYm90aCBvZiB3aGljaCBjYW4gYmUgdXNlZCB0byBjcmVhdGUgbmV3IGNvbHVtbnMgaW4gYSBxdWVyaWVz4oCZIHJlc3VsdCBzZXQuCgoqIEZpcnN0IHdlIHdpbGwgdXNlIHRoZSBjYXNlIHN0YXRlbWVudCB0byBhY2NvbXBsaXNoIHdoYXQgd2UganVzdCBkaWQgd2l0aCB0aGUgYHN1YnN0cmAgYW5kIGBpbnN0cmAgZnVuY3Rpb25zLgoKYGBgc3FsClNFTEVDVCBRNWF4diAsCiAgICAgICBjYXNlIFE1YXh2CiAgICAgICAgICAgIHdoZW4gIm5vIG51bGwiIHRoZW4gMAogICAgICAgICAgICB3aGVuICJudWxsIiB0aGVuIDEKICAgICAgIGVuZCBhcyBRNWF4dl9ib29sIApGUk9NIFNONzU3N19UZXh0OwoKYGBgCgoqIFRoaXMgZm9ybWF0IG9mIHRoZSBgY2FzZWAgc3RhdGVtZW50IGFsbG93cyB5b3UgdG8gY2hlY2sgaWYgdmFyaW91cyB2YWx1ZXMgYGFyZSBlcXVhbGAgdG8gdGhlIHZhbHVlIGluIHRoZSBmaWVsZCBnaXZlbiBhZnRlciB0aGUgYGNhc2VgIGtleXdvcmQuIAoqIFRoZXJlIGlzIGEgbW9yZSBnZW5lcmFsIGZvcm0gd2hpY2ggYWxvd3MgdG8gdG8gcGVyZm9ybSBhbnkga2luZCBvZiB0ZXN0LgoKIyMjIFVzaW5nIFNRTCBzeW50YXggdG8gY3JlYXRlIGBiaW5uZWRgIHZhbHVlcwoKKiBJdCBpcyBvZnRlbiB0aGUgY2FzZSB0aGF0IHdlIHdpc2ggdG8gY29udmVydCBhIGNvbnRpbm91cyB2YXJpYWJsZSBpbnRvIGEgYW4gZGlzY3JldGUgZmFjdG9yIHR5cGUgdmFyaWFibGUuIAoqIEluIFNONzU3NyB5b3UgY2FuIHNlZSB0aGlzIGJlaW5nIGRvbmUgaW4gdGhlIG51bWFnZSBhbmQgdGhlIGFnZSB2YXJpYWJsZXMuCgoqIFdlIGNhbiB1c2UgYSBgY2FzZWAgc3RhdGVtZW50IHRvIGNyZWF0ZSB0aGlzIHR5cGUgb2YgZWZmZWN0LiAKCiogVGhlIGV4YW1wbGUgcmUtY3JlYXRlcyB0aGUgYWdlIHZhbHVlcyB1c2VkIGluIHRoZSBgU043NTc3X1RleHQgdGFibGVgIHdpdGggdGhlIGFkZGl0aW9uIG9mIGFuIOKAnFVuZGVyIGFnZeKAnSBjYXRlZ29yeSBmb3IgdGhvc2UgbGVzcyB0aGFuIDE4IHllYXJzIG9sZC4KCmBgYHNxbApTRUxFQ1QgbnVtYWdlICwKICAgICAgICAgICAgICAgY2FzZSAKICAgICAgICAgICAgICAgICAgIHdoZW4gbnVtYWdlIGJldHdlZW4gMTggYW5kIDI0IHRoZW4gIjE4IC0gMjQiCiAgICAgICAgICAgICAgICAgICB3aGVuIG51bWFnZSBiZXR3ZWVuIDI1IGFuZCAzNCB0aGVuICIyNSAtIDM0IgogICAgICAgICAgICAgICAgICAgd2hlbiBudW1hZ2UgYmV0d2VlbiAzNSBhbmQgNDQgdGhlbiAiMzUgLSA0NCIKICAgICAgICAgICAgICAgICAgIHdoZW4gbnVtYWdlIGJldHdlZW4gNDUgYW5kIDU0IHRoZW4gIjQ1IC0gNTQiCiAgICAgICAgICAgICAgICAgICB3aGVuIG51bWFnZSBiZXR3ZWVuIDU1IGFuZCA1OSB0aGVuICI1NSAtIDU5IgogICAgICAgICAgICAgICAgICAgd2hlbiBudW1hZ2UgYmV0d2VlbiA2MCBhbmQgNjQgdGhlbiAiNjAgLSA2NCIKICAgICAgICAgICAgICAgICAgIHdoZW4gbnVtYWdlICAgICAgICAgID49IDY1ICAgICAgICAgICAgICB0aGVuICI2NSsiCiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgIlVuZGVyIGFnZSIKICAgICAgICAgICAgICAgZW5kIGFzIG51bWFnZV9yYW5nZQpGUk9NIFNONzU3NzsKCmBgYAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo=