# For general data science
library(tidyverse)
# For reading and writing data tables and Excel files
library(readxl)
# For data cleaning
library(janitor)
# For spatial joins
library(sf)
# For working with datetime
library(lubridate)
# For pretty tables
library(knitr)
library(gt)
knitr::opts_chunk$set(echo = TRUE)
This notebook contains the analysis of New Mexico’s oil and gas well completion, flaring, venting data for the Howard Center Investigation, “Gaslit”. The analysis relies on four data sets publicly available from the New Mexico Oil Conservation Division (OCD).
The first is flaring and venting data reported by companies to OCD. Oil and gas companies in New Mexico are required to report the volume of gas they flare, vent, lose, and use on lease in addition to the volume of oil and gas they produce at each well on a monthly basis, using the electronic C-115 form. Details regarding the form are available with the OCD here. Reported gas flared or vented is measured in thousand cubic feet (Mcf).
Data from the monthly reports (2014-present) is available at the OCD’s website in various forms. This analysis uses the data set called “C-115 Flaring and Venting Data from 2014. By Operator and Year.”
The second data set we use in our analysis is well history. On the OCD statistics site, there’s a link next to “Well Search by API (history, completions, casing, formation tops, violations, orders and production.)” This will take you to the OCD permitting site’s well search page. Scroll to the bottom and Next to “Report Format,” select “Expanded.” Then click “continue.” At bottom of the page is a button to “Export to Excel.”
The third data set we used is a simple table of yearly drilling permits by type, also available form the OCD statistics site, next to “APDs issued by Type per Year.”
The fourth, and final, data set is of well completions. The Oil Conservation Division releases weekly well activity reports on its permitting website. We manual copied data from each well completion report between Jan. 6, 2019 – when Gov. Grisham entered office – through 2021 to a spreadsheet saved here.
Load Data
We compiled and cleaned all this data from the state regulatory agency and saved it to new data sets available from the Howard Center here. (For more information about our data cleaning, please contact: howardcenter@asu.edu).
# Disposition data
nm_flaring <- read.csv(url("https://cronkitedata.s3.amazonaws.com/howard/gaslit/nm_flaring_and_venting.csv"))
# APDs
nm_apds <- read.csv(url("https://cronkitedata.s3.amazonaws.com/howard/gaslit/nm_apds.csv"))
# Wells
nm_wells <- read.csv(url("https://cronkitedata.s3.amazonaws.com/howard/gaslit/nm_wells.csv"))
# Well completions
nm_completions <- read.csv(url("https://cronkitedata.s3.amazonaws.com/howard/gaslit/nm_well_completions.csv"))
Analysis
FACT: Oil and gas companies in New Mexico reported flaring more than 168 billion cubic feet of natural gas in that time frame.
We calculated this figure using the disposition data reported to state regulators. We filtered for the disposition type “flared,” then aggregated annual totals.
nm_flaring %>%
filter((disposition_type == "Flared" | disposition_type == "Vented")
& (year >= 2012 & year <= 2020)) %>%
group_by(year, disposition_type) %>%
summarise(total = sum(volume, na.rm = TRUE),
.groups = "drop") %>%
pivot_wider(names_from = disposition_type, values_from = total) %>%
rename("Year" = "year") %>%
gt(rowname_col = "Year") %>%
tab_stubhead(label = "Year") %>%
tab_header(title = "Flaring and Venting Volumes Reported to OCD",
subtitle = "Flaring and venting volumes in Mcf (thousand cubic feet)") %>%
fmt_number(column = "Flared":"Vented",
decimals = 2) %>%
grand_summary_rows(fns = list("Total" = "sum"),
columns=("Flared":"Vented"),
formatter=gt::fmt_number,
decimals=0)
Year |
Flared |
Vented |
2014 |
10,355,390.00 |
13,684,421.00 |
2015 |
28,903,038.00 |
9,198,947.00 |
2016 |
21,821,704.00 |
3,361,896.00 |
2017 |
15,274,456.00 |
2,016,186.00 |
2018 |
35,678,946.00 |
784,795.00 |
2019 |
35,724,446.00 |
853,209.00 |
2020 |
20,876,711.00 |
468,006.00 |
Total |
168,634,691 |
30,367,460 |
FACT: In the first three years of Lujan Grisham’s administration, the state issued 6,970 drilling permits — more per year, on average, than her Republican predecessor.
We first created a new data frame with a new column delineating the serving governor for each year. We also filtered for oil and gas permits.
We then grouped by governor to determine the total number of oil and gas APDs issued while they were in office and the annual average. (Note that former Gov. Bill Richardson served for 8 years, but the APD data only goes back to 2004)
nm_apds_gov <- nm_apds %>%
mutate(gov = case_when(year >= 2019 ~ "Grisham (D)",
year < 2019 & year >= 2011 ~ "Martinez (R)",
year < 2011 & year >= 2003 ~ "Richardson (D)")) %>%
filter(well_type == "Oil" | well_type == "Gas")
nm_apds_gov %>%
group_by(gov) %>%
summarise(apds = sum(apds),
years_in_office = n()/2,
avg_apds_per_year = apds/years_in_office,
.groups = "drop")
FACT: There are nearly 51,000 active oil and gas wells in New Mexico.
We have a list of all unplugged wells in New Mexico. We determine the number of active wells by filtering for oil and gas wells, then grouping by status.
nm_wells %>%
filter(type == "Gas" | type == "Oil") %>%
group_by (status) %>%
summarise(n = n())
FACT: San Juan, Rio Arriba, and Sandoval counties in northwest New Mexico are home to nearly 21,000 active wells.
Although the well data we have does not include an associated county, it does include coordinates which we can join to the county shape file we used in our satellite analysis. This shape file comes from the U.S. Census Bureau.
temp_shapefile <- tempfile()
download.file("https://www2.census.gov/geo/tiger/TIGER2020/COUNTY/tl_2020_us_county.zip", temp_shapefile)
unzip(temp_shapefile)
counties <- read_sf("tl_2020_us_county.shp",
options = c("METHOD"="SKIP")) %>%
st_transform(crs=4269) %>%
clean_names()
## Warning in CPL_read_ogr(dsn, layer, query, as.character(options), quiet, : GDAL
## Message 6: open option 'SKIP' is not formatted with the key=value format
# Turn wells into points
point_map <- st_as_sf(nm_wells, coords=c("longitude", "latitude"), crs = 4269)
# Join shapefile and points
county_wells <- st_join( point_map, counties)
# Turn object back into a table
county_wells_table <-
county_wells %>%
as.data.frame()
Now, we can filter for San Juan, Rio Arriba, and Sandoval counties AND filter for oil and gas wells, then group by status.
county_wells_table %>%
filter((name == "San Juan" | name == "Rio Arriba" | name == "Sandoval")
& (type == "Oil" | type == "Gas")) %>%
group_by(status) %>%
summarise(n = n())
FACT: Nearly 2,800 wells were completed during Gov. Grisham’s administration.
To calculate the number of completions during the governor’s administration, we filtered the compl_date
variable, which identifies the date of the completion, for the years 2019 to 2021. To ensure we count unique well completions, we use n_distinct
to count records that were distinct by well number, api
, and the compl_date
.
nm_completions %>%
mutate(year = year(compl_date)) %>%
filter(year >= 2019) %>%
summarise(n = n_distinct(api, compl_date))
LS0tCnRpdGxlOiAiTmV3IE1leGljbyBGbGFyaW5nICYgVmVudGluZyIKYXV0aG9yOiAiTmljb2xlIFNhZGVrLCBKaW1teSBDbG91dGllciwgSXp6eSBLb3lhbWEsIEF5ZGFsaSBDYW1wYSIKb3V0cHV0OgogICAgaHRtbF9kb2N1bWVudDoKICAgICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICAgIGRmX3ByaW50OiBwYWdlZAogICAgICB0b2M6IHRydWUKICAgICAgdG9jX2Zsb2F0OiB0cnVlCiAgICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKLS0tCgoKYGBge3Igc2V0dXAsIG1lc3NhZ2U9RkFMU0UsIGNsYXNzLnNvdXJjZT0iZm9sZC1oaWRlIn0KCiMgRm9yIGdlbmVyYWwgZGF0YSBzY2llbmNlCmxpYnJhcnkodGlkeXZlcnNlKQoKIyBGb3IgcmVhZGluZyBhbmQgd3JpdGluZyBkYXRhIHRhYmxlcyBhbmQgRXhjZWwgZmlsZXMKbGlicmFyeShyZWFkeGwpCgojIEZvciBkYXRhIGNsZWFuaW5nCmxpYnJhcnkoamFuaXRvcikKCiMgRm9yIHNwYXRpYWwgam9pbnMKbGlicmFyeShzZikKCiMgRm9yIHdvcmtpbmcgd2l0aCBkYXRldGltZQpsaWJyYXJ5KGx1YnJpZGF0ZSkKCiMgRm9yIHByZXR0eSB0YWJsZXMKbGlicmFyeShrbml0cikKbGlicmFyeShndCkKCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkKCmBgYAoKClRoaXMgbm90ZWJvb2sgY29udGFpbnMgdGhlIGFuYWx5c2lzIG9mIE5ldyBNZXhpY28ncyBvaWwgYW5kIGdhcyB3ZWxsIGNvbXBsZXRpb24sIGZsYXJpbmcsIHZlbnRpbmcgIGRhdGEgZm9yIHRoZSBIb3dhcmQgQ2VudGVyIEludmVzdGlnYXRpb24sICJHYXNsaXQiLiBUaGUgYW5hbHlzaXMgIHJlbGllcyBvbiBmb3VyIGRhdGEgc2V0cyBwdWJsaWNseSBhdmFpbGFibGUgZnJvbSB0aGUgTmV3IE1leGljbyBPaWwgQ29uc2VydmF0aW9uIERpdmlzaW9uIChPQ0QpLiAKClRoZSBmaXJzdCBpcyBmbGFyaW5nIGFuZCB2ZW50aW5nIGRhdGEgcmVwb3J0ZWQgYnkgY29tcGFuaWVzIHRvIE9DRC4gT2lsIGFuZCBnYXMgY29tcGFuaWVzIGluIE5ldyBNZXhpY28gYXJlIHJlcXVpcmVkIHRvIHJlcG9ydCB0aGUgdm9sdW1lIG9mIGdhcyB0aGV5IGZsYXJlLCB2ZW50LCBsb3NlLCBhbmQgdXNlIG9uIGxlYXNlIGluIGFkZGl0aW9uIHRvIHRoZSB2b2x1bWUgb2Ygb2lsIGFuZCBnYXMgdGhleSBwcm9kdWNlIGF0IGVhY2ggd2VsbCBvbiBhIG1vbnRobHkgYmFzaXMsIHVzaW5nIHRoZSBlbGVjdHJvbmljIEMtMTE1IGZvcm0uIERldGFpbHMgcmVnYXJkaW5nIHRoZSBmb3JtIGFyZSBhdmFpbGFibGUgd2l0aCB0aGUgT0NEIFtoZXJlXShodHRwczovL3d3dy5lbW5yZC5ubS5nb3Yvb2NkL3dwLWNvbnRlbnQvdXBsb2Fkcy9zaXRlcy82L0MxMTVfSW5zdHJ1Y3Rpb25zMjAxOS5wZGYpLiBSZXBvcnRlZCBnYXMgZmxhcmVkIG9yIHZlbnRlZCBpcyBtZWFzdXJlZCBpbiB0aG91c2FuZCBjdWJpYyBmZWV0IChNY2YpLgoKRGF0YSBmcm9tIHRoZSBtb250aGx5IHJlcG9ydHMgKDIwMTQtcHJlc2VudCkgaXMgYXZhaWxhYmxlIGF0IHRoZSBPQ0QncyBbd2Vic2l0ZV0oaHR0cHM6Ly93d3cuZW1ucmQubm0uZ292L29jZC9vY2QtZGF0YS9zdGF0aXN0aWNzLykgaW4gdmFyaW91cyBmb3Jtcy4gVGhpcyBhbmFseXNpcyB1c2VzIHRoZSBkYXRhIHNldCBjYWxsZWQgIltDLTExNSBGbGFyaW5nIGFuZCBWZW50aW5nIERhdGEgZnJvbSAyMDE0LiBCeSBPcGVyYXRvciBhbmQgWWVhcl0oaHR0cHM6Ly93d3cuZW1ucmQubm0uZ292L3dwLWNvbnRlbnQvdXBsb2Fkcy9Db3B5LW9mLUMtMTE1LU5vbi1UcmFuc3BvcnRlZC1Qcm9kdWN0LURpc3Bvc2l0aW9uLUJ5LU9wZXJhdG9yLVZGLUdhcy0yMDIxLTA2MDkueGxzeCkuIgoKVGhlIHNlY29uZCBkYXRhIHNldCB3ZSB1c2UgaW4gb3VyIGFuYWx5c2lzIGlzIHdlbGwgaGlzdG9yeS4gT24gdGhlIE9DRCBzdGF0aXN0aWNzIFtzaXRlXShodHRwczovL3d3dy5lbW5yZC5ubS5nb3Yvb2NkL29jZC1kYXRhL3N0YXRpc3RpY3MvKSwgdGhlcmUncyBhIFtsaW5rXShodHRwczovL3d3d2FwcHMuZW1ucmQuc3RhdGUubm0udXMvb2NkL29jZHBlcm1pdHRpbmcvRGF0YS9XZWxscy5hc3B4KSBuZXh0IHRvICJXZWxsIFNlYXJjaCBieSBBUEkgKGhpc3RvcnksIGNvbXBsZXRpb25zLCBjYXNpbmcsIGZvcm1hdGlvbiB0b3BzLCB2aW9sYXRpb25zLCBvcmRlcnMgYW5kIHByb2R1Y3Rpb24uKSIgVGhpcyB3aWxsIHRha2UgeW91IHRvIHRoZSBPQ0QgcGVybWl0dGluZyBzaXRlJ3Mgd2VsbCBzZWFyY2ggcGFnZS4gU2Nyb2xsIHRvIHRoZSBib3R0b20gYW5kIE5leHQgdG8gIlJlcG9ydCBGb3JtYXQsIiBzZWxlY3QgIkV4cGFuZGVkLiIgVGhlbiBjbGljayAiY29udGludWUuIiBBdCBib3R0b20gb2YgdGhlIHBhZ2UgaXMgYSBidXR0b24gdG8gIkV4cG9ydCB0byBFeGNlbC4iCgpUaGUgdGhpcmQgZGF0YSBzZXQgd2UgdXNlZCBpcyBhIHNpbXBsZSB0YWJsZSBvZiB5ZWFybHkgZHJpbGxpbmcgcGVybWl0cyBieSB0eXBlLCBhbHNvIGF2YWlsYWJsZSBmb3JtIHRoZSBPQ0Qgc3RhdGlzdGljcyBbc2l0ZV0oaHR0cHM6Ly93d3cuZW1ucmQubm0uZ292L29jZC9vY2QtZGF0YS9zdGF0aXN0aWNzLyksIG5leHQgdG8gIkFQRHMgaXNzdWVkIGJ5IFR5cGUgcGVyIFllYXIuIgoKVGhlIGZvdXJ0aCwgYW5kIGZpbmFsLCBkYXRhIHNldCBpcyBvZiB3ZWxsIGNvbXBsZXRpb25zLiBUaGUgT2lsIENvbnNlcnZhdGlvbiBEaXZpc2lvbiByZWxlYXNlcyB3ZWVrbHkgd2VsbCBhY3Rpdml0eSByZXBvcnRzIG9uIGl0cyBwZXJtaXR0aW5nIFt3ZWJzaXRlXShodHRwczovL3d3d2FwcHMuZW1ucmQubm0uZ292L29jZC9vY2RwZXJtaXR0aW5nL1JlcG9ydGluZy9BY3Rpdml0eS9XZWVrbHlBY3Rpdml0eS5hc3B4KS4gV2UgbWFudWFsIGNvcGllZCBkYXRhIGZyb20gZWFjaCB3ZWxsIGNvbXBsZXRpb24gcmVwb3J0IGJldHdlZW4gSmFuLiA2LCAyMDE5IC0tIHdoZW4gR292LiBHcmlzaGFtIGVudGVyZWQgb2ZmaWNlIC0tIHRocm91Z2ggMjAyMSB0byBhIHNwcmVhZHNoZWV0IHNhdmVkIFtoZXJlXShodHRwczovL2RyaXZlLmdvb2dsZS5jb20vZmlsZS9kLzFxc25QY2tsdzhNU19URGJ6UlM2MWxJU1J4SWlsTEpFZi92aWV3P3VzcD1zaGFyaW5nKS4gCgojIExvYWQgRGF0YQoKV2UgY29tcGlsZWQgYW5kIGNsZWFuZWQgYWxsIHRoaXMgZGF0YSBmcm9tIHRoZSBzdGF0ZSByZWd1bGF0b3J5IGFnZW5jeSBhbmQgc2F2ZWQgaXQgdG8gbmV3IGRhdGEgc2V0cyBhdmFpbGFibGUgZnJvbSB0aGUgSG93YXJkIENlbnRlciBbaGVyZV0oaHR0cHM6Ly9kcml2ZS5nb29nbGUuY29tL2RyaXZlL2ZvbGRlcnMvMU1SN0R2V0tGS0JqZDNNTzdVS2tmSVJoV0VwcHhEcFhZP3VzcD1zaGFyaW5nKS4gKEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IG91ciBkYXRhIGNsZWFuaW5nLCBwbGVhc2UgY29udGFjdDogaG93YXJkY2VudGVyQGFzdS5lZHUpLiAKCmBgYHtyfQoKIyBEaXNwb3NpdGlvbiBkYXRhCm5tX2ZsYXJpbmcgPC0gcmVhZC5jc3YodXJsKCJodHRwczovL2Nyb25raXRlZGF0YS5zMy5hbWF6b25hd3MuY29tL2hvd2FyZC9nYXNsaXQvbm1fZmxhcmluZ19hbmRfdmVudGluZy5jc3YiKSkKCiMgQVBEcwpubV9hcGRzIDwtIHJlYWQuY3N2KHVybCgiaHR0cHM6Ly9jcm9ua2l0ZWRhdGEuczMuYW1hem9uYXdzLmNvbS9ob3dhcmQvZ2FzbGl0L25tX2FwZHMuY3N2IikpCgojIFdlbGxzCm5tX3dlbGxzIDwtIHJlYWQuY3N2KHVybCgiaHR0cHM6Ly9jcm9ua2l0ZWRhdGEuczMuYW1hem9uYXdzLmNvbS9ob3dhcmQvZ2FzbGl0L25tX3dlbGxzLmNzdiIpKQoKIyBXZWxsIGNvbXBsZXRpb25zCm5tX2NvbXBsZXRpb25zIDwtIHJlYWQuY3N2KHVybCgiaHR0cHM6Ly9jcm9ua2l0ZWRhdGEuczMuYW1hem9uYXdzLmNvbS9ob3dhcmQvZ2FzbGl0L25tX3dlbGxfY29tcGxldGlvbnMuY3N2IikpCgpgYGAKCiMgQW5hbHlzaXMKCkZBQ1Q6IE9pbCBhbmQgZ2FzIGNvbXBhbmllcyBpbiBOZXcgTWV4aWNvIHJlcG9ydGVkIGZsYXJpbmcgbW9yZSB0aGFuIDE2OCBiaWxsaW9uIGN1YmljIGZlZXQgb2YgbmF0dXJhbCBnYXMgaW4gdGhhdCB0aW1lIGZyYW1lLgoKV2UgY2FsY3VsYXRlZCB0aGlzIGZpZ3VyZSB1c2luZyB0aGUgZGlzcG9zaXRpb24gZGF0YSByZXBvcnRlZCB0byBzdGF0ZSByZWd1bGF0b3JzLiBXZSBmaWx0ZXJlZCBmb3IgdGhlIGRpc3Bvc2l0aW9uIHR5cGUgImZsYXJlZCwiIHRoZW4gYWdncmVnYXRlZCBhbm51YWwgdG90YWxzLiAgCgpgYGB7cn0KCm5tX2ZsYXJpbmcgJT4lCiAgZmlsdGVyKChkaXNwb3NpdGlvbl90eXBlID09ICJGbGFyZWQiIHwgZGlzcG9zaXRpb25fdHlwZSA9PSAiVmVudGVkIikKICAgICAgICAgJiAoeWVhciA+PSAyMDEyICYgeWVhciA8PSAyMDIwKSkgJT4lCiAgZ3JvdXBfYnkoeWVhciwgZGlzcG9zaXRpb25fdHlwZSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsID0gc3VtKHZvbHVtZSwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgLmdyb3VwcyA9ICJkcm9wIikgJT4lCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IGRpc3Bvc2l0aW9uX3R5cGUsIHZhbHVlc19mcm9tID0gdG90YWwpICU+JQogIHJlbmFtZSgiWWVhciIgPSAieWVhciIpICU+JQogIGd0KHJvd25hbWVfY29sID0gIlllYXIiKSAlPiUKICB0YWJfc3R1YmhlYWQobGFiZWwgPSAiWWVhciIpICU+JQogIHRhYl9oZWFkZXIodGl0bGUgPSAiRmxhcmluZyBhbmQgVmVudGluZyBWb2x1bWVzIFJlcG9ydGVkIHRvIE9DRCIsCiAgICAgICAgICAgICBzdWJ0aXRsZSA9ICJGbGFyaW5nIGFuZCB2ZW50aW5nIHZvbHVtZXMgaW4gTWNmICh0aG91c2FuZCBjdWJpYyBmZWV0KSIpICU+JQogIGZtdF9udW1iZXIoY29sdW1uID0gIkZsYXJlZCI6IlZlbnRlZCIsCiAgICAgICAgICAgICBkZWNpbWFscyA9IDIpICU+JQogIGdyYW5kX3N1bW1hcnlfcm93cyhmbnMgPSBsaXN0KCJUb3RhbCIgPSAic3VtIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW5zPSgiRmxhcmVkIjoiVmVudGVkIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXR0ZXI9Z3Q6OmZtdF9udW1iZXIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNpbWFscz0wKQoKCmBgYAoKRkFDVDogSW4gdGhlIGZpcnN0IHRocmVlIHllYXJzIG9mIEx1amFuIEdyaXNoYW3igJlzIGFkbWluaXN0cmF0aW9uLCB0aGUgc3RhdGUgaXNzdWVkIDYsOTcwIGRyaWxsaW5nIHBlcm1pdHMg4oCUIG1vcmUgcGVyIHllYXIsIG9uIGF2ZXJhZ2UsIHRoYW4gaGVyIFJlcHVibGljYW4gcHJlZGVjZXNzb3IuIAoKV2UgZmlyc3QgY3JlYXRlZCBhIG5ldyBkYXRhIGZyYW1lIHdpdGggYSBuZXcgY29sdW1uIGRlbGluZWF0aW5nIHRoZSBzZXJ2aW5nIGdvdmVybm9yIGZvciBlYWNoIHllYXIuIFdlIGFsc28gZmlsdGVyZWQgZm9yIG9pbCBhbmQgZ2FzIHBlcm1pdHMuIAoKV2UgdGhlbiBncm91cGVkIGJ5IGdvdmVybm9yIHRvIGRldGVybWluZSB0aGUgdG90YWwgbnVtYmVyIG9mIG9pbCBhbmQgZ2FzIEFQRHMgaXNzdWVkIHdoaWxlIHRoZXkgd2VyZSBpbiBvZmZpY2UgYW5kIHRoZSBhbm51YWwgYXZlcmFnZS4gKE5vdGUgdGhhdCBmb3JtZXIgR292LiBCaWxsIFJpY2hhcmRzb24gc2VydmVkIGZvciA4IHllYXJzLCBidXQgdGhlIEFQRCBkYXRhIG9ubHkgZ29lcyBiYWNrIHRvIDIwMDQpCgpgYGB7cn0KCm5tX2FwZHNfZ292IDwtIG5tX2FwZHMgJT4lCiAgbXV0YXRlKGdvdiA9IGNhc2Vfd2hlbih5ZWFyID49IDIwMTkgfiAiR3Jpc2hhbSAoRCkiLAogICAgICAgICAgICAgICAgICAgICAgICAgeWVhciA8IDIwMTkgJiB5ZWFyID49IDIwMTEgfiAiTWFydGluZXogKFIpIiwKICAgICAgICAgICAgICAgICAgICAgICAgIHllYXIgPCAyMDExICYgeWVhciA+PSAyMDAzIH4gIlJpY2hhcmRzb24gKEQpIikpICU+JQogIGZpbHRlcih3ZWxsX3R5cGUgPT0gIk9pbCIgfCB3ZWxsX3R5cGUgPT0gIkdhcyIpCgpubV9hcGRzX2dvdiAlPiUKICBncm91cF9ieShnb3YpICU+JQogIHN1bW1hcmlzZShhcGRzID0gc3VtKGFwZHMpLAogICAgICAgICAgICB5ZWFyc19pbl9vZmZpY2UgPSBuKCkvMiwKICAgICAgICAgICAgYXZnX2FwZHNfcGVyX3llYXIgPSBhcGRzL3llYXJzX2luX29mZmljZSwKICAgICAgICAgICAgLmdyb3VwcyA9ICJkcm9wIikKCmBgYAoKRkFDVDogVGhlcmUgYXJlIG5lYXJseSA1MSwwMDAgYWN0aXZlIG9pbCBhbmQgZ2FzIHdlbGxzIGluIE5ldyBNZXhpY28uIAoKV2UgaGF2ZSBhIGxpc3Qgb2YgYWxsIHVucGx1Z2dlZCB3ZWxscyBpbiBOZXcgTWV4aWNvLiBXZSBkZXRlcm1pbmUgdGhlIG51bWJlciBvZiBhY3RpdmUgd2VsbHMgYnkgZmlsdGVyaW5nIGZvciBvaWwgYW5kIGdhcyB3ZWxscywgdGhlbiBncm91cGluZyBieSAgc3RhdHVzLiAKCmBgYHtyfQoKbm1fd2VsbHMgJT4lCiAgZmlsdGVyKHR5cGUgPT0gIkdhcyIgfCB0eXBlID09ICJPaWwiKSAlPiUKICBncm91cF9ieSAoc3RhdHVzKSAlPiUKICBzdW1tYXJpc2UobiA9IG4oKSkKCmBgYAoKRkFDVDogU2FuIEp1YW4sIFJpbyBBcnJpYmEsIGFuZCBTYW5kb3ZhbCBjb3VudGllcyBpbiBub3J0aHdlc3QgTmV3IE1leGljbyBhcmUgaG9tZSB0byBuZWFybHkgMjEsMDAwIGFjdGl2ZSB3ZWxscy4gCgpBbHRob3VnaCB0aGUgd2VsbCBkYXRhIHdlIGhhdmUgZG9lcyBub3QgaW5jbHVkZSBhbiBhc3NvY2lhdGVkIGNvdW50eSwgaXQgZG9lcyBpbmNsdWRlIGNvb3JkaW5hdGVzIHdoaWNoIHdlIGNhbiBqb2luIHRvIHRoZSBjb3VudHkgc2hhcGUgZmlsZSB3ZSB1c2VkIGluIG91ciBzYXRlbGxpdGUgYW5hbHlzaXMuIFRoaXMgc2hhcGUgZmlsZSBjb21lcyBmcm9tIHRoZSBVLlMuIENlbnN1cyBCdXJlYXUuICAKCmBgYHtyfQoKdGVtcF9zaGFwZWZpbGUgPC0gdGVtcGZpbGUoKQpkb3dubG9hZC5maWxlKCJodHRwczovL3d3dzIuY2Vuc3VzLmdvdi9nZW8vdGlnZXIvVElHRVIyMDIwL0NPVU5UWS90bF8yMDIwX3VzX2NvdW50eS56aXAiLCB0ZW1wX3NoYXBlZmlsZSkKdW56aXAodGVtcF9zaGFwZWZpbGUpCgpjb3VudGllcyA8LSByZWFkX3NmKCJ0bF8yMDIwX3VzX2NvdW50eS5zaHAiLCAKICAgICAgICAgICAgICAgICAgICBvcHRpb25zID0gYygiTUVUSE9EIj0iU0tJUCIpKSAlPiUgIAogIHN0X3RyYW5zZm9ybShjcnM9NDI2OSkgJT4lCiAgY2xlYW5fbmFtZXMoKQoKIyBUdXJuIHdlbGxzIGludG8gcG9pbnRzCnBvaW50X21hcCA8LSBzdF9hc19zZihubV93ZWxscywgY29vcmRzPWMoImxvbmdpdHVkZSIsICJsYXRpdHVkZSIpLCBjcnMgPSA0MjY5KQoKIyBKb2luIHNoYXBlZmlsZSBhbmQgcG9pbnRzCmNvdW50eV93ZWxscyA8LSBzdF9qb2luKCBwb2ludF9tYXAsIGNvdW50aWVzKQoKIyBUdXJuIG9iamVjdCBiYWNrIGludG8gYSB0YWJsZQpjb3VudHlfd2VsbHNfdGFibGUgPC0gCiAgY291bnR5X3dlbGxzICU+JQogIGFzLmRhdGEuZnJhbWUoKQoKYGBgCgpOb3csIHdlIGNhbiBmaWx0ZXIgZm9yIFNhbiBKdWFuLCBSaW8gQXJyaWJhLCBhbmQgU2FuZG92YWwgY291bnRpZXMgQU5EIGZpbHRlciBmb3Igb2lsIGFuZCBnYXMgd2VsbHMsIHRoZW4gZ3JvdXAgYnkgc3RhdHVzLiAKCmBgYCB7cn0KCgpjb3VudHlfd2VsbHNfdGFibGUgJT4lCiAgZmlsdGVyKChuYW1lID09ICJTYW4gSnVhbiIgfCBuYW1lID09ICJSaW8gQXJyaWJhIiB8IG5hbWUgPT0gIlNhbmRvdmFsIikgCiAgICAgICAgICYgKHR5cGUgPT0gIk9pbCIgfCB0eXBlID09ICJHYXMiKSkgJT4lCiAgZ3JvdXBfYnkoc3RhdHVzKSAlPiUKICBzdW1tYXJpc2UobiA9IG4oKSkKCmBgYAoKRkFDVDogTmVhcmx5IDIsODAwIHdlbGxzIHdlcmUgY29tcGxldGVkIGR1cmluZyBHb3YuIEdyaXNoYW0ncyBhZG1pbmlzdHJhdGlvbi4gCgpUbyBjYWxjdWxhdGUgdGhlIG51bWJlciBvZiBjb21wbGV0aW9ucyBkdXJpbmcgdGhlIGdvdmVybm9yJ3MgYWRtaW5pc3RyYXRpb24sIHdlIGZpbHRlcmVkIHRoZSBgY29tcGxfZGF0ZWAgdmFyaWFibGUsIHdoaWNoIGlkZW50aWZpZXMgdGhlIGRhdGUgb2YgdGhlIGNvbXBsZXRpb24sIGZvciB0aGUgeWVhcnMgMjAxOSB0byAyMDIxLiBUbyBlbnN1cmUgd2UgY291bnQgdW5pcXVlIHdlbGwgY29tcGxldGlvbnMsIHdlIHVzZSBgbl9kaXN0aW5jdGAgdG8gY291bnQgcmVjb3JkcyB0aGF0IHdlcmUgZGlzdGluY3QgYnkgd2VsbCBudW1iZXIsIGBhcGlgLCBhbmQgdGhlIGBjb21wbF9kYXRlYC4gCgpgYGB7cn0KCm5tX2NvbXBsZXRpb25zICU+JQogIG11dGF0ZSh5ZWFyID0geWVhcihjb21wbF9kYXRlKSkgJT4lCiAgZmlsdGVyKHllYXIgPj0gMjAxOSkgJT4lCiAgc3VtbWFyaXNlKG4gPSBuX2Rpc3RpbmN0KGFwaSwgY29tcGxfZGF0ZSkpCgpgYGAKCg==