Turkish Natural Gas Market


        We will start this project by preprocessing the data files so we can eliminate noisy data, correct the data format, remove NA values and clean the data. With this procedure, we will create an RDS file so in the next parts of our project it will be easier to conduct some analyses and create insight.


        Before we start the project, we will begin with loading necessary packages to process the data files which are GRP.xls and TTV.xls.

library(tidyr)
library(dplyr)
library(stringr)
library(lubridate)
library(ggplot2)
library(readxl)
library(tibble)
library(gridExtra)
library(scales)


1-) GRP Data


        This data contains daily gas reference prices between 01/09/2018 and 01/12/2021. The data obtained from here.

        We proceed to read the xls data file.

gas_prices <- read_excel("GRP.xls")


a-) Structure of the Data


        Let’s see the structure of the data file GRP.xls.

str(gas_prices)
tibble [1,188 x 2] (S3: tbl_df/tbl/data.frame)
 $ Gaz Gunu: chr [1:1188] "01/09/2018" "02/09/2018" "03/09/2018" "04/09/2018" ...
 $ GRF     : chr [1:1188] "1.650,00" "1.650,00" "1.656,45" "1.644,23" ...

        As seen above the data type in columns are inappropriate so we have to change them.


        We also see that change the column names since they are in Turkish. We changed Gaz Günü column to Date and GRF column to Gas_Reference_Price. Then take a look if there is any missing values.

names(gas_prices) <- c('Date',
                       'Gas_Reference_Price')

sum(is.na(gas_prices$Gas_Reference_Price))
[1] 0
sum(is.na(gas_prices$Date))
[1] 0

        As seen above there is no missing value.


b-) Processing the Columns

        We then proceed to format the Date column as date format type using lubridate.

gas_prices$Date <- dmy(gas_prices$Date)


        Because dot(.), is used as thousand separator and comma(,) as decimal point we had to deal with it for further processes. We have achieved that by using gsub function. Then we converted it into numeric.

gas_prices$Gas_Reference_Price <- gsub('.',
                                       '',
                                       gas_prices$Gas_Reference_Price,
                                       fixed = TRUE)
gas_prices$Gas_Reference_Price <- as.numeric(gsub(',',
                                                  '.',
                                                  gas_prices$Gas_Reference_Price,
                                                  fixed = TRUE))


        Now if we take a look at the data we will see everything is ready to analysis.

head(gas_prices)


2-) TTV Data


        This data contains daily gas trade volume between 01/09/2018 and 01/12/2021. The data obtained from here.

        Once again, we proceed to read the xls data file.

trade_volume <- read_excel("TTV.xls")


a-) Structure of the Data


        Let’s see the structure of the data file TTV.xls.

str(trade_volume)
tibble [1,188 x 2] (S3: tbl_df/tbl/data.frame)
 $ Gaz Günü          : chr [1:1188] "01.09.2018" "02.09.2018" "03.09.2018" "04.09.2018" ...
 $ Toplam Islem Hacmi: chr [1:1188] "378.501,00" "680.025,00" "1.371.846,25" "1.018.608,25" ...

        As seen above the data types in columns are character so we have to change them.


        We can also see that just like previous data the column names are inappropriate. We changed Gaz Günü column to Date and Toplam Islem Hacmi column to Total_Trade_Volume. Lastly, of course we took a look if there is any missing values.

names(trade_volume) <- c('Date',
                         'Total_Trade_Volume')

sum(is.na(trade_volume$Total_Trade_Volume))
[1] 0
sum(is.na(trade_volume$Date))
[1] 0

        As seen above there is no missing value.


b-) Processing the Columns

        We proceed to format the Date column as date format.

trade_volume$Date <- dmy(trade_volume$Date)


        Just like the previous dataset dot(.), is used as thousand separator and comma(,) as decimal point in this data. We have solved that issue by using gsub function. Then we converted it into numeric.

trade_volume$Total_Trade_Volume <- gsub('.',
                                       '',
                                       trade_volume$Total_Trade_Volume,
                                       fixed = TRUE)
trade_volume$Total_Trade_Volume <- as.numeric(gsub(',',
                                                  '.',
                                                  trade_volume$Total_Trade_Volume,
                                                  fixed = TRUE))


        Let’s take a look at the data, everything should be ready to analysis.

head(trade_volume)


c-) Feature Generation

        In this part we will create multiples columns out of Date so we can deepen our analyses comparing them yearly, monthly, weekly, seasonally and many more.

        We start by creating the weeks column.

trade_volume$week_num <- strftime((trade_volume$Date), format = "%V")
trade_volume$week_num <- as.numeric(trade_volume$week_num)


        Then, the months column.

trade_volume$month_num <- month(trade_volume$Date)
trade_volume$month_num <- as.numeric(trade_volume$month_num)


        Here, we created the day of the week column.

trade_volume$day_of_week <- wday(trade_volume$Date, label = TRUE, abbr = TRUE)


        Also, the year column.

trade_volume$year_num <- isoyear(trade_volume$Date)
trade_volume$year_num <- as.numeric(trade_volume$year_num)


        Lastly, the season column.

seasons <- NULL  # initialize empty vector
for(row in seq_len(nrow(trade_volume["Date"]))){
  if((trade_volume["month_num"][row, 1] == 12) | (trade_volume["month_num"][row, 1] == 1) | (trade_volume["month_num"][row, 1] == 2)){
    seasons <- append(seasons,"Winter")
  }
  else if((trade_volume["month_num"][row, 1] == 3) | (trade_volume["month_num"][row, 1] == 4) | (trade_volume["month_num"][row, 1] == 5)){
    seasons <- append(seasons,"Spring")
  }
  else if((trade_volume["month_num"][row, 1] == 6) | (trade_volume["month_num"][row, 1] == 7) | (trade_volume["month_num"][row, 1] == 8)){
    seasons <- append(seasons,"Summer")
  }
  else {
    seasons <- append(seasons,"Fall")
  }
}
trade_volume["season"] <- seasons


3-) Creating the RDS File


        Two data we will mainly use is ready to merge and go ahead with the further analyses. We merge these two data by Date column and name it as df.

df <- merge(x=trade_volume, y=gas_prices, by='Date')
head(df)


        Then, we saved merged df file as rds file named natural_gas_data so we all can use single and perfect data file.

saveRDS(df, "natural_gas_data.rds")




                                                                                                                                          Thanks for reading…

Division Bell

LS0tDQp0aXRsZTogIioqQkRBLTUwMyBEaXZpc2lvbiBCZWxsIEdyb3VwIFByb2plY3QgJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IFByZS1wcm9jZXNzaW5nIHRoZSBEYXRhKioiDQphdXRob3I6ICIgX011cmF0IENhbiBUYcWfYXJfLCBfTmVqYXQgVcSfdXIgQWvEsW5fLCBfWXVudXMgRW1yZSBEb8SfYW5fLCBfRW1pcmhhbiDFnmFoaW5fIg0KZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJUIgJWQsICVZJylgIg0Kb3V0cHV0Og0KICAgIGh0bWxfbm90ZWJvb2s6DQogICAgICAgIHRvYzogdHJ1ZQ0KICAgICAgICB0b2NfZGVwdGg6IDMNCiAgICAgICAgdG9jX2Zsb2F0Og0KICAgICAgICAgICAgY29sbGFwc2VkOiBmYWxzZQ0KLS0tDQo8YnI+DQo8c3R5bGU+DQojVE9DIHsNCiAgICBjb2xvcjogIzQwNDA0MDsNCiAgICBmb250LXNpemU6IDEzcHg7DQogICAgYm9yZGVyLWNvbG9yOiAjMDAwMDAwOw0KICAgIGZvbnQtZmFtaWx5OiAtYXBwbGUtc3lzdGVtLCBzeXN0ZW0tdWksIEJsaW5rTWFjU3lzdGVtRm9udCwgIlNlZ29lIFVJIiwgUm9ib3RvLCBVYnVudHU7DQp9DQpoMS50aXRsZSB7DQogICAgY29sb3I6ICM0MDQwNDA7DQogICAgZm9udC1mYW1pbHk6IC1hcHBsZS1zeXN0ZW0sIHN5c3RlbS11aSwgQmxpbmtNYWNTeXN0ZW1Gb250LCAiU2Vnb2UgVUkiLCBSb2JvdG8sIFVidW50dTsNCn0NCmg0LmF1dGhvciB7DQogICAgY29sb3I6ICM0MDQwNDA7DQogICAgZm9udC1zaXplOiAxMnB4Ow0KICAgIGZvbnQtZmFtaWx5OiAtYXBwbGUtc3lzdGVtLCBzeXN0ZW0tdWksIEJsaW5rTWFjU3lzdGVtRm9udCwgIlNlZ29lIFVJIiwgUm9ib3RvLCBVYnVudHU7DQp9DQpoNC5kYXRlIHsNCiAgICBjb2xvcjogIzQwNDA0MDsNCiAgICBmb250LXNpemU6IDEycHg7DQogICAgZm9udC1mYW1pbHk6IC1hcHBsZS1zeXN0ZW0sIHN5c3RlbS11aSwgQmxpbmtNYWNTeXN0ZW1Gb250LCAiU2Vnb2UgVUkiLCBSb2JvdG8sIFVidW50dTsNCn0NCmJvZHkgew0KICAgIGNvbG9yOiAjNjk2OTY5Ow0KICAgIGZvbnQtZmFtaWx5OiAtYXBwbGUtc3lzdGVtLCBzeXN0ZW0tdWksIEJsaW5rTWFjU3lzdGVtRm9udCwgIlNlZ29lIFVJIiwgUm9ib3RvLCBVYnVudHU7DQogICAgYmFja2dyb3VuZC1jb2xvcjogI0Y1RjVGNTsNCiAgICBmb250LXNpemU6IDE2cHg7DQo8L3N0eWxlPg0KDQojICZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyA8c3BhbiBzdHlsZT0iY29sb3I6IzQwNDA0MCI+KipUdXJraXNoIE5hdHVyYWwgR2FzIE1hcmtldCoqPC9zcGFuPg0KDQo8YnI+DQoNCiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyBXZSB3aWxsIHN0YXJ0IHRoaXMgcHJvamVjdCBieSBwcmVwcm9jZXNzaW5nIHRoZSBkYXRhIGZpbGVzIHNvIHdlIGNhbiBlbGltaW5hdGUgbm9pc3kgZGF0YSwgY29ycmVjdCB0aGUgZGF0YSBmb3JtYXQsIHJlbW92ZSBOQSB2YWx1ZXMgYW5kIGNsZWFuIHRoZSBkYXRhLiBXaXRoIHRoaXMgcHJvY2VkdXJlLCB3ZSB3aWxsIGNyZWF0ZSBhbiBSRFMgZmlsZSBzbyBpbiB0aGUgbmV4dCBwYXJ0cyBvZiBvdXIgcHJvamVjdCBpdCB3aWxsIGJlIGVhc2llciB0byBjb25kdWN0IHNvbWUgYW5hbHlzZXMgYW5kIGNyZWF0ZSBpbnNpZ2h0Lg0KDQo8YnI+DQoNCiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyBCZWZvcmUgd2Ugc3RhcnQgdGhlIHByb2plY3QsIHdlIHdpbGwgYmVnaW4gd2l0aCBsb2FkaW5nIG5lY2Vzc2FyeSBwYWNrYWdlcyB0byBwcm9jZXNzIHRoZSBkYXRhIGZpbGVzIHdoaWNoIGFyZSBbR1JQLnhsc10oaHR0cHM6Ly9wam91cm5hbC5naXRodWIuaW8vbWVmMDVnLWRpdmlzaW9uLWJlbGwvR1JQLnhscykgYW5kIFtUVFYueGxzXShodHRwczovL3Bqb3VybmFsLmdpdGh1Yi5pby9tZWYwNWctZGl2aXNpb24tYmVsbC9UVFYueGxzKS4NCg0KYGBge3IsICBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRX0NCmxpYnJhcnkodGlkeXIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShzdHJpbmdyKQ0KbGlicmFyeShsdWJyaWRhdGUpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHJlYWR4bCkNCmxpYnJhcnkodGliYmxlKQ0KbGlicmFyeShncmlkRXh0cmEpDQpsaWJyYXJ5KHNjYWxlcykNCmBgYA0KDQo8YnI+DQoNCiMjICoqMS0pIEdSUCBEYXRhKioNCg0KPGJyPg0KDQombmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgVGhpcyBkYXRhIGNvbnRhaW5zIGRhaWx5IGdhcyByZWZlcmVuY2UgcHJpY2VzIGJldHdlZW4gMDEvMDkvMjAxOCBhbmQgMDEvMTIvMjAyMS4gVGhlIGRhdGEgb2J0YWluZWQgZnJvbSBbaGVyZV0oaHR0cHM6Ly9zZWZmYWZsaWsuZXBpYXMuY29tLnRyL3RyYW5zcGFyZW5jeS9kb2dhbGdhei9zdHAvc3RwLWdyZi54aHRtbCMpLg0KDQombmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgV2UgcHJvY2VlZCB0byByZWFkIHRoZSB4bHMgZGF0YSBmaWxlLg0KDQpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFfQ0KZ2FzX3ByaWNlcyA8LSByZWFkX2V4Y2VsKCJHUlAueGxzIikNCmBgYA0KDQo8YnI+DQoNCiMjIyAqKmEtKSBTdHJ1Y3R1cmUgb2YgdGhlIERhdGEqKg0KDQo8YnI+DQoNCiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyBMZXQncyBzZWUgdGhlIHN0cnVjdHVyZSBvZiB0aGUgZGF0YSBmaWxlIGBHUlAueGxzYC4NCg0KYGBge3J9DQpzdHIoZ2FzX3ByaWNlcykNCmBgYA0KDQombmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgQXMgc2VlbiBhYm92ZSB0aGUgZGF0YSB0eXBlIGluIGNvbHVtbnMgYXJlIGluYXBwcm9wcmlhdGUgc28gd2UgaGF2ZSB0byBjaGFuZ2UgdGhlbS4NCg0KPGJyPg0KDQombmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgV2UgYWxzbyBzZWUgdGhhdCBjaGFuZ2UgdGhlIGNvbHVtbiBuYW1lcyBzaW5jZSB0aGV5IGFyZSBpbiBUdXJraXNoLiBXZSBjaGFuZ2VkIGBHYXogR8O8bsO8YCBjb2x1bW4gdG8gYERhdGVgIGFuZCBgR1JGYCBjb2x1bW4gdG8gYEdhc19SZWZlcmVuY2VfUHJpY2VgLiAgVGhlbiB0YWtlIGEgbG9vayBpZiB0aGVyZSBpcyBhbnkgbWlzc2luZyB2YWx1ZXMuDQoNCmBgYHtyfQ0KbmFtZXMoZ2FzX3ByaWNlcykgPC0gYygnRGF0ZScsDQogICAgICAgICAgICAgICAgICAgICAgICdHYXNfUmVmZXJlbmNlX1ByaWNlJykNCg0Kc3VtKGlzLm5hKGdhc19wcmljZXMkR2FzX1JlZmVyZW5jZV9QcmljZSkpDQpzdW0oaXMubmEoZ2FzX3ByaWNlcyREYXRlKSkNCmBgYA0KDQombmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgQXMgc2VlbiBhYm92ZSB0aGVyZSBpcyBubyBtaXNzaW5nIHZhbHVlLg0KDQo8YnI+DQoNCiMjIyAqKmItKSBQcm9jZXNzaW5nIHRoZSBDb2x1bW5zKioNCg0KJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7ICBXZSB0aGVuIHByb2NlZWQgdG8gZm9ybWF0IHRoZSBEYXRlIGNvbHVtbiBhcyBkYXRlIGZvcm1hdCB0eXBlIHVzaW5nIGx1YnJpZGF0ZS4NCg0KYGBge3J9DQpnYXNfcHJpY2VzJERhdGUgPC0gZG15KGdhc19wcmljZXMkRGF0ZSkNCmBgYA0KDQo8YnI+DQoNCiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyBCZWNhdXNlIGRvdCgqKmAuYCoqKSwgaXMgdXNlZCBhcyB0aG91c2FuZCBzZXBhcmF0b3IgYW5kIGNvbW1hKCoqYCxgKiopIGFzIGRlY2ltYWwgcG9pbnQgd2UgaGFkIHRvIGRlYWwgd2l0aCBpdCBmb3IgZnVydGhlciBwcm9jZXNzZXMuIFdlIGhhdmUgYWNoaWV2ZWQgdGhhdCBieSB1c2luZyBnc3ViIGZ1bmN0aW9uLiBUaGVuIHdlIGNvbnZlcnRlZCBpdCBpbnRvIG51bWVyaWMuDQoNCmBgYHtyfQ0KZ2FzX3ByaWNlcyRHYXNfUmVmZXJlbmNlX1ByaWNlIDwtIGdzdWIoJy4nLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJycsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnYXNfcHJpY2VzJEdhc19SZWZlcmVuY2VfUHJpY2UsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaXhlZCA9IFRSVUUpDQpnYXNfcHJpY2VzJEdhc19SZWZlcmVuY2VfUHJpY2UgPC0gYXMubnVtZXJpYyhnc3ViKCcsJywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJy4nLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnYXNfcHJpY2VzJEdhc19SZWZlcmVuY2VfUHJpY2UsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpeGVkID0gVFJVRSkpDQpgYGANCg0KPGJyPg0KDQombmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgTm93IGlmIHdlIHRha2UgYSBsb29rIGF0IHRoZSBkYXRhIHdlIHdpbGwgc2VlIGV2ZXJ5dGhpbmcgaXMgcmVhZHkgdG8gYW5hbHlzaXMuDQoNCmBgYHtyfQ0KaGVhZChnYXNfcHJpY2VzKQ0KYGBgDQoNCjxicj4NCg0KIyMgKioyLSkgVFRWIERhdGEqKg0KDQo8YnI+DQoNCiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyBUaGlzIGRhdGEgY29udGFpbnMgZGFpbHkgZ2FzIHRyYWRlIHZvbHVtZSBiZXR3ZWVuIDAxLzA5LzIwMTggYW5kIDAxLzEyLzIwMjEuIFRoZSBkYXRhIG9idGFpbmVkIGZyb20gW2hlcmVdKGh0dHBzOi8vc2VmZmFmbGlrLmVwaWFzLmNvbS50ci90cmFuc3BhcmVuY3kvZG9nYWxnYXovc3RwL3N0cC10b3BsYW0taXNsZW0taGFjbWkueGh0bWwpLg0KDQombmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgT25jZSBhZ2Fpbiwgd2UgcHJvY2VlZCB0byByZWFkIHRoZSB4bHMgZGF0YSBmaWxlLg0KDQpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFfQ0KdHJhZGVfdm9sdW1lIDwtIHJlYWRfZXhjZWwoIlRUVi54bHMiKQ0KYGBgDQoNCjxicj4NCg0KIyMjICoqYS0pIFN0cnVjdHVyZSBvZiB0aGUgRGF0YSoqDQoNCjxicj4NCg0KJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IExldCdzIHNlZSB0aGUgc3RydWN0dXJlIG9mIHRoZSBkYXRhIGZpbGUgYFRUVi54bHNgLg0KDQpgYGB7cn0NCnN0cih0cmFkZV92b2x1bWUpDQpgYGANCg0KJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IEFzIHNlZW4gYWJvdmUgdGhlIGRhdGEgdHlwZXMgaW4gY29sdW1ucyBhcmUgY2hhcmFjdGVyIHNvIHdlIGhhdmUgdG8gY2hhbmdlIHRoZW0uDQoNCjxicj4NCg0KJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IFdlIGNhbiBhbHNvIHNlZSB0aGF0IGp1c3QgbGlrZSBwcmV2aW91cyBkYXRhIHRoZSBjb2x1bW4gbmFtZXMgYXJlIGluYXBwcm9wcmlhdGUuIFdlIGNoYW5nZWQgYEdheiBHw7xuw7xgIGNvbHVtbiB0byBgRGF0ZWAgYW5kIGBUb3BsYW0gSXNsZW0gSGFjbWlgIGNvbHVtbiB0byBgVG90YWxfVHJhZGVfVm9sdW1lYC4gTGFzdGx5LCBvZiBjb3Vyc2Ugd2UgdG9vayBhIGxvb2sgaWYgdGhlcmUgaXMgYW55IG1pc3NpbmcgdmFsdWVzLg0KDQpgYGB7cn0NCm5hbWVzKHRyYWRlX3ZvbHVtZSkgPC0gYygnRGF0ZScsDQogICAgICAgICAgICAgICAgICAgICAgICAgJ1RvdGFsX1RyYWRlX1ZvbHVtZScpDQoNCnN1bShpcy5uYSh0cmFkZV92b2x1bWUkVG90YWxfVHJhZGVfVm9sdW1lKSkNCnN1bShpcy5uYSh0cmFkZV92b2x1bWUkRGF0ZSkpDQpgYGANCg0KJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IEFzIHNlZW4gYWJvdmUgdGhlcmUgaXMgbm8gbWlzc2luZyB2YWx1ZS4NCg0KPGJyPg0KDQojIyMgKipiLSkgUHJvY2Vzc2luZyB0aGUgQ29sdW1ucyoqDQoNCiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyAgV2UgcHJvY2VlZCB0byBmb3JtYXQgdGhlIGBEYXRlYCBjb2x1bW4gYXMgZGF0ZSBmb3JtYXQuDQoNCmBgYHtyfQ0KdHJhZGVfdm9sdW1lJERhdGUgPC0gZG15KHRyYWRlX3ZvbHVtZSREYXRlKQ0KYGBgDQoNCjxicj4NCg0KJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IEp1c3QgbGlrZSB0aGUgcHJldmlvdXMgZGF0YXNldCBkb3QoKipgLmAqKiksIGlzIHVzZWQgYXMgdGhvdXNhbmQgc2VwYXJhdG9yIGFuZCBjb21tYSgqKmAsYCoqKSBhcyBkZWNpbWFsIHBvaW50IGluIHRoaXMgZGF0YS4gV2UgaGF2ZSBzb2x2ZWQgdGhhdCBpc3N1ZSBieSB1c2luZyBnc3ViIGZ1bmN0aW9uLiBUaGVuIHdlIGNvbnZlcnRlZCBpdCBpbnRvIG51bWVyaWMuDQoNCmBgYHtyfQ0KdHJhZGVfdm9sdW1lJFRvdGFsX1RyYWRlX1ZvbHVtZSA8LSBnc3ViKCcuJywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcnLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhZGVfdm9sdW1lJFRvdGFsX1RyYWRlX1ZvbHVtZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpeGVkID0gVFJVRSkNCnRyYWRlX3ZvbHVtZSRUb3RhbF9UcmFkZV9Wb2x1bWUgPC0gYXMubnVtZXJpYyhnc3ViKCcsJywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJy4nLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFkZV92b2x1bWUkVG90YWxfVHJhZGVfVm9sdW1lLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaXhlZCA9IFRSVUUpKQ0KYGBgDQoNCjxicj4NCg0KJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IExldCdzIHRha2UgYSBsb29rIGF0IHRoZSBkYXRhLCBldmVyeXRoaW5nIHNob3VsZCBiZSByZWFkeSB0byBhbmFseXNpcy4NCg0KYGBge3J9DQpoZWFkKHRyYWRlX3ZvbHVtZSkNCmBgYA0KDQo8YnI+DQoNCiMjIyAqKmMtKSBGZWF0dXJlIEdlbmVyYXRpb24qKg0KDQombmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgSW4gdGhpcyBwYXJ0IHdlIHdpbGwgY3JlYXRlIG11bHRpcGxlcyBjb2x1bW5zIG91dCBvZiBgRGF0ZWAgc28gd2UgY2FuIGRlZXBlbiBvdXIgYW5hbHlzZXMgY29tcGFyaW5nIHRoZW0geWVhcmx5LCBtb250aGx5LCB3ZWVrbHksIHNlYXNvbmFsbHkgYW5kIG1hbnkgbW9yZS4NCg0KJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IFdlIHN0YXJ0IGJ5IGNyZWF0aW5nIHRoZSB3ZWVrcyBjb2x1bW4uDQoNCmBgYHtyfQ0KdHJhZGVfdm9sdW1lJHdlZWtfbnVtIDwtIHN0cmZ0aW1lKCh0cmFkZV92b2x1bWUkRGF0ZSksIGZvcm1hdCA9ICIlViIpDQp0cmFkZV92b2x1bWUkd2Vla19udW0gPC0gYXMubnVtZXJpYyh0cmFkZV92b2x1bWUkd2Vla19udW0pDQpgYGANCg0KPGJyPg0KDQombmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgVGhlbiwgdGhlIG1vbnRocyBjb2x1bW4uDQoNCmBgYHtyfQ0KdHJhZGVfdm9sdW1lJG1vbnRoX251bSA8LSBtb250aCh0cmFkZV92b2x1bWUkRGF0ZSkNCnRyYWRlX3ZvbHVtZSRtb250aF9udW0gPC0gYXMubnVtZXJpYyh0cmFkZV92b2x1bWUkbW9udGhfbnVtKQ0KYGBgDQoNCjxicj4NCg0KJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IEhlcmUsIHdlIGNyZWF0ZWQgdGhlIGRheSBvZiB0aGUgd2VlayBjb2x1bW4uDQoNCmBgYHtyfQ0KdHJhZGVfdm9sdW1lJGRheV9vZl93ZWVrIDwtIHdkYXkodHJhZGVfdm9sdW1lJERhdGUsIGxhYmVsID0gVFJVRSwgYWJiciA9IFRSVUUpDQpgYGANCg0KPGJyPg0KDQombmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgQWxzbywgdGhlIHllYXIgY29sdW1uLg0KDQpgYGB7cn0NCnRyYWRlX3ZvbHVtZSR5ZWFyX251bSA8LSBpc295ZWFyKHRyYWRlX3ZvbHVtZSREYXRlKQ0KdHJhZGVfdm9sdW1lJHllYXJfbnVtIDwtIGFzLm51bWVyaWModHJhZGVfdm9sdW1lJHllYXJfbnVtKQ0KYGBgDQoNCjxicj4NCg0KJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IExhc3RseSwgdGhlIHNlYXNvbiBjb2x1bW4uDQoNCmBgYHtyfQ0Kc2Vhc29ucyA8LSBOVUxMICAjIGluaXRpYWxpemUgZW1wdHkgdmVjdG9yDQpmb3Iocm93IGluIHNlcV9sZW4obnJvdyh0cmFkZV92b2x1bWVbIkRhdGUiXSkpKXsNCiAgaWYoKHRyYWRlX3ZvbHVtZVsibW9udGhfbnVtIl1bcm93LCAxXSA9PSAxMikgfCAodHJhZGVfdm9sdW1lWyJtb250aF9udW0iXVtyb3csIDFdID09IDEpIHwgKHRyYWRlX3ZvbHVtZVsibW9udGhfbnVtIl1bcm93LCAxXSA9PSAyKSl7DQogICAgc2Vhc29ucyA8LSBhcHBlbmQoc2Vhc29ucywiV2ludGVyIikNCiAgfQ0KICBlbHNlIGlmKCh0cmFkZV92b2x1bWVbIm1vbnRoX251bSJdW3JvdywgMV0gPT0gMykgfCAodHJhZGVfdm9sdW1lWyJtb250aF9udW0iXVtyb3csIDFdID09IDQpIHwgKHRyYWRlX3ZvbHVtZVsibW9udGhfbnVtIl1bcm93LCAxXSA9PSA1KSl7DQogICAgc2Vhc29ucyA8LSBhcHBlbmQoc2Vhc29ucywiU3ByaW5nIikNCiAgfQ0KICBlbHNlIGlmKCh0cmFkZV92b2x1bWVbIm1vbnRoX251bSJdW3JvdywgMV0gPT0gNikgfCAodHJhZGVfdm9sdW1lWyJtb250aF9udW0iXVtyb3csIDFdID09IDcpIHwgKHRyYWRlX3ZvbHVtZVsibW9udGhfbnVtIl1bcm93LCAxXSA9PSA4KSl7DQogICAgc2Vhc29ucyA8LSBhcHBlbmQoc2Vhc29ucywiU3VtbWVyIikNCiAgfQ0KICBlbHNlIHsNCiAgICBzZWFzb25zIDwtIGFwcGVuZChzZWFzb25zLCJGYWxsIikNCiAgfQ0KfQ0KdHJhZGVfdm9sdW1lWyJzZWFzb24iXSA8LSBzZWFzb25zDQpgYGANCg0KPGJyPg0KDQojIyAqKjMtKSBDcmVhdGluZyB0aGUgUkRTIEZpbGUqKg0KDQo8YnI+DQoNCiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyBUd28gZGF0YSB3ZSB3aWxsIG1haW5seSB1c2UgaXMgcmVhZHkgdG8gbWVyZ2UgYW5kIGdvIGFoZWFkIHdpdGggdGhlIGZ1cnRoZXIgYW5hbHlzZXMuIFdlIG1lcmdlIHRoZXNlIHR3byBkYXRhIGJ5IGBEYXRlYCBjb2x1bW4gYW5kIG5hbWUgaXQgYXMgYGRmYC4NCg0KYGBge3J9DQpkZiA8LSBtZXJnZSh4PXRyYWRlX3ZvbHVtZSwgeT1nYXNfcHJpY2VzLCBieT0nRGF0ZScpDQpoZWFkKGRmKQ0KYGBgDQoNCjxicj4NCg0KJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IFRoZW4sIHdlIHNhdmVkIG1lcmdlZCBkZiBmaWxlIGFzIHJkcyBmaWxlIG5hbWVkIGBuYXR1cmFsX2dhc19kYXRhYCBzbyB3ZSBhbGwgY2FuIHVzZSBzaW5nbGUgYW5kIHBlcmZlY3QgZGF0YSBmaWxlLg0KDQpgYGB7cn0NCnNhdmVSRFMoZGYsICJuYXR1cmFsX2dhc19kYXRhLnJkcyIpDQpgYGANCg0KPGJyPg0KPGJyPg0KPGJyPg0KDQombmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7ICZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwO19fX1RoYW5rcyBmb3IgcmVhZGluZy4uLl9fXw0KPGJyPg0KPGJyPg0KIVtEaXZpc2lvbiBCZWxsXShodHRwczovL2hkd2FsbHBhcGVyaW0uY29tL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDE3LzA4LzI0LzExMDQ2MC1QaW5rX0Zsb3lkLXRoZV9kaXZpc2lvbl9iZWxsLW11c2ljLmpwZylc