Isaac Bell Geog 490

For my final project, I’ll be investigating a netCDF file showing Palmer Drought Severity Index in the US. This dataset originally had data from 1980 to 2024, but to make things simpler I’ve decided to only focus on drought in the western states between 2000 and today. Palmer Drought Severity (PDSI) uses data about both temperature and precipitation to quantify how severe a drought is; relative to a region’s normal climate, negative values represent dry, and positive values represent wet. The dataset I’m using has values for the mean PDSI every 5 days, gridded at a resolution of 1/24th degree or about 4km.

I wanted to use R to see what patterns there were to this data, and which areas have been most or least affected by drought. To do this, I’m going to be extracting the gridded data and associating it to Western US states and counties.

First, loading libraries:

library(ncdf4)
library(CFtime)
library(lattice)
library(RColorBrewer)
library(maps)
library(sf)
library(terra)
library(tidyterra)
library(classInt)
library(ggplot2)
library(raster)
library(exactextractr)
library(reshape2)

Getting western states shapefiles:

state_sf <- st_as_sf(map("state", plot = FALSE, fill = TRUE, crs = "+proj=longlat +ellps=WGS84"))
selected_sf <- state_sf[state_sf$ID %in% c("washington","oregon","california","arizona","new mexico","nevada","idaho","utah","colorado","wyoming","montana"),]
state_geom <- st_geometry(selected_sf)
plot(selected_sf)

Getting county shapefiles:

county_sf <- st_as_sf(map("county", plot = FALSE, fill = TRUE))
county_sf$state <- sub(",.*", "", county_sf$ID)
selected_county <- county_sf[county_sf$state %in% c("washington","oregon","california","arizona","new mexico","nevada","idaho","utah","colorado","wyoming","montana"),]
county_geom <- st_geometry(selected_county)
plot(selected_county)

I’ll use these shapefiles to extract data spatially from my raster dataset.

Loading and setting up netCDF file:

ncpath <- "/Users/isaacbell/Documents/geog490/final_proj/data/"
ncname <- "2000to2024"
ncfname <- paste(ncpath, ncname, ".nc", sep="")
ncin <- nc_open(ncfname)
dname <- "daily_mean_palmer_drought_severity_index"
lon <- ncvar_get(ncin,"lon")
nlon <- dim(lon)
lat <- ncvar_get(ncin,"lat")
nlat <- dim(lat)
title <- ncatt_get(ncin,0,"title")
institution <- ncatt_get(ncin,0,"institution")
datasource <- ncatt_get(ncin,0,"source")
references <- ncatt_get(ncin,0,"references")
history <- ncatt_get(ncin,0,"history")
Conventions <- ncatt_get(ncin,0,"Conventions")
pdsi_array <- ncvar_get(ncin,dname)
dlname <- ncatt_get(ncin,dname,"long_name")
dunits <- ncatt_get(ncin,dname,"units")
fillvalue <- ncatt_get(ncin,dname,"_FillValue")
dim(pdsi_array)
[1]  595  585 1753

Getting time from netCDF:

time <- ncvar_get(ncin,"day")
tunits <- ncatt_get(ncin,"day","units")
nt <- dim(time)
cf <- CFtime(tunits$value, calendar = "proleptic_gregorian", time) 
timestamps <- CFtimestamp(cf)
months = CFfactor(cf,"month")
time_cf <- CFparse(cf, timestamps)
head(time_cf)

As you can see, the file contains measurements recurring every 5 days.

Making a raster from netCDF, and applying time values to it:

pdsi_raster <- rast(ncfname)
names(pdsi_raster) <- timestamps
stamps_date <- as.Date(timestamps)
time(pdsi_raster) <- stamps_date

This allows me to parse the raster stack by date.

Getting the overall mean PDSI values for the whole 2000-2024 raster stack:

mean_raster = mean(pdsi_raster)
plot(mean_raster)

Geographic analysis

Now that I have the county and state geometries, I can use the exact_extract() function to pull the data from the raster into the vector. This comes from the exactextratr library, and it allows me to write the average value within each polygon to a new column on the vector data.

selected_sf$mean_alltime <- exact_extract(mean_raster, selected_sf, 'mean')
plot(selected_sf[,'mean_alltime'])

selected_county$mean_alltime <- exact_extract(mean_raster, selected_county, 'mean')
plot(selected_county[,'mean_alltime'])

(note that the scales are different for both plots)

In the state plots, you can see that every state in the west has seen stronger dry conditions than wet conditions since 2000. Montana looks to be the least affected, and Oregon has had the driest average conditions (relative to normal).

Next, I’ll split up the raster stack into individual years, then use exact_extract() to get the means for each year into the state and county shapefiles.

year_li <- seq(2000,2024)
for (i in year_li){
i <- toString(i)
a <- pdsi_raster[i]
selected_sf[, i] <- exact_extract(a, selected_sf, 'mean')
selected_county[, i] <- exact_extract(a, selected_county, 'mean')
}

(This might not be the most efficient method, but it works well enough)

Here’s a quick time series plot of the average PDSI for each state:

states_df <- st_drop_geometry(selected_sf)
drops <- c("ID","mean_alltime")
select_states_df <- states_df[ , !(names(states_df) %in% drops)]
select_states_df$metadata <- row.names(select_states_df)
select_states_df <- melt(select_states_df, "metadata")
ggplot(select_states_df, aes(variable, value, group = metadata, color = metadata)) + 
geom_line()

Let’s plot the average PDSI rasters for a couple of years:

raster_2000 <- mean(pdsi_raster["2000"])
plot(raster_2000,
     breaks=c(-4,-3,-2,-1,0,1,2,3,4),
     col=brewer.pal(9, "RdYlGn"),
     main="Mean PDSI: 2000"
     )

raster_2023 <- mean(pdsi_raster["2023"])
plot(raster_2023,
     breaks=c(-5,-4,-3,-2,-1,0,1,2,3,4,5),
     col=brewer.pal(11, "RdYlGn"),
     main="Mean PDSI: 2023"
     )

For reference, the National Drought Mitigation Center considers PDSI values from -3 to -4 ‘severe drought,’ and values above -4 as ‘extreme drought.’

LS0tCnRpdGxlOiAiRHJvdWdodCBpbiB0aGUgV2VzdGVybiBVUzogMjAwMC0yMDI0IgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAotLS0KSXNhYWMgQmVsbApHZW9nIDQ5MAoKCkZvciBteSBmaW5hbCBwcm9qZWN0LCBJJ2xsIGJlIGludmVzdGlnYXRpbmcgYSBuZXRDREYgZmlsZSBzaG93aW5nIFBhbG1lciBEcm91Z2h0IFNldmVyaXR5IEluZGV4IGluIHRoZSBVUy4gVGhpcyBkYXRhc2V0IG9yaWdpbmFsbHkgaGFkIGRhdGEgZnJvbSAxOTgwIHRvIDIwMjQsIGJ1dCB0byBtYWtlIHRoaW5ncyBzaW1wbGVyIEkndmUgZGVjaWRlZCB0byBvbmx5IGZvY3VzIG9uIGRyb3VnaHQgaW4gdGhlIHdlc3Rlcm4gc3RhdGVzIGJldHdlZW4gMjAwMCBhbmQgdG9kYXkuIFBhbG1lciBEcm91Z2h0IFNldmVyaXR5IChQRFNJKSB1c2VzIGRhdGEgYWJvdXQgYm90aCB0ZW1wZXJhdHVyZSBhbmQgcHJlY2lwaXRhdGlvbiB0byBxdWFudGlmeSBob3cgc2V2ZXJlIGEgZHJvdWdodCBpczsgcmVsYXRpdmUgdG8gYSByZWdpb24ncyBub3JtYWwgY2xpbWF0ZSwgbmVnYXRpdmUgdmFsdWVzIHJlcHJlc2VudCBkcnksIGFuZCBwb3NpdGl2ZSB2YWx1ZXMgcmVwcmVzZW50IHdldC4gVGhlIGRhdGFzZXQgSSdtIHVzaW5nIGhhcyB2YWx1ZXMgZm9yIHRoZSBtZWFuIFBEU0kgZXZlcnkgNSBkYXlzLCBncmlkZGVkIGF0IGEgcmVzb2x1dGlvbiBvZiAxLzI0dGggZGVncmVlIG9yIGFib3V0IDRrbS4KCkkgd2FudGVkIHRvIHVzZSBSIHRvIHNlZSB3aGF0IHBhdHRlcm5zIHRoZXJlIHdlcmUgdG8gdGhpcyBkYXRhLCBhbmQgd2hpY2ggYXJlYXMgaGF2ZSBiZWVuIG1vc3Qgb3IgbGVhc3QgYWZmZWN0ZWQgYnkgZHJvdWdodC4gVG8gZG8gdGhpcywgSSdtIGdvaW5nIHRvIGJlIGV4dHJhY3RpbmcgdGhlIGdyaWRkZWQgZGF0YSBhbmQgYXNzb2NpYXRpbmcgaXQgdG8gV2VzdGVybiBVUyBzdGF0ZXMgYW5kIGNvdW50aWVzLgoKCkZpcnN0LCBsb2FkaW5nIGxpYnJhcmllczoKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkobmNkZjQpCmxpYnJhcnkoQ0Z0aW1lKQpsaWJyYXJ5KGxhdHRpY2UpCmxpYnJhcnkoUkNvbG9yQnJld2VyKQpsaWJyYXJ5KG1hcHMpCmxpYnJhcnkoc2YpCmxpYnJhcnkodGVycmEpCmxpYnJhcnkodGlkeXRlcnJhKQpsaWJyYXJ5KGNsYXNzSW50KQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkocmFzdGVyKQpsaWJyYXJ5KGV4YWN0ZXh0cmFjdHIpCmxpYnJhcnkocmVzaGFwZTIpCmBgYAoKCkdldHRpbmcgd2VzdGVybiBzdGF0ZXMgc2hhcGVmaWxlczoKCmBgYHtyfQpzdGF0ZV9zZiA8LSBzdF9hc19zZihtYXAoInN0YXRlIiwgcGxvdCA9IEZBTFNFLCBmaWxsID0gVFJVRSwgY3JzID0gIitwcm9qPWxvbmdsYXQgK2VsbHBzPVdHUzg0IikpCnNlbGVjdGVkX3NmIDwtIHN0YXRlX3NmW3N0YXRlX3NmJElEICVpbiUgYygid2FzaGluZ3RvbiIsIm9yZWdvbiIsImNhbGlmb3JuaWEiLCJhcml6b25hIiwibmV3IG1leGljbyIsIm5ldmFkYSIsImlkYWhvIiwidXRhaCIsImNvbG9yYWRvIiwid3lvbWluZyIsIm1vbnRhbmEiKSxdCnN0YXRlX2dlb20gPC0gc3RfZ2VvbWV0cnkoc2VsZWN0ZWRfc2YpCnBsb3Qoc2VsZWN0ZWRfc2YpCmBgYAoKCkdldHRpbmcgY291bnR5IHNoYXBlZmlsZXM6CgpgYGB7cn0KY291bnR5X3NmIDwtIHN0X2FzX3NmKG1hcCgiY291bnR5IiwgcGxvdCA9IEZBTFNFLCBmaWxsID0gVFJVRSkpCmNvdW50eV9zZiRzdGF0ZSA8LSBzdWIoIiwuKiIsICIiLCBjb3VudHlfc2YkSUQpCnNlbGVjdGVkX2NvdW50eSA8LSBjb3VudHlfc2ZbY291bnR5X3NmJHN0YXRlICVpbiUgYygid2FzaGluZ3RvbiIsIm9yZWdvbiIsImNhbGlmb3JuaWEiLCJhcml6b25hIiwibmV3IG1leGljbyIsIm5ldmFkYSIsImlkYWhvIiwidXRhaCIsImNvbG9yYWRvIiwid3lvbWluZyIsIm1vbnRhbmEiKSxdCmNvdW50eV9nZW9tIDwtIHN0X2dlb21ldHJ5KHNlbGVjdGVkX2NvdW50eSkKcGxvdChzZWxlY3RlZF9jb3VudHkpCmBgYApJJ2xsIHVzZSB0aGVzZSBzaGFwZWZpbGVzIHRvIGV4dHJhY3QgZGF0YSBzcGF0aWFsbHkgZnJvbSBteSByYXN0ZXIgZGF0YXNldC4KCkxvYWRpbmcgYW5kIHNldHRpbmcgdXAgbmV0Q0RGIGZpbGU6CgpgYGB7cn0KbmNwYXRoIDwtICIvVXNlcnMvaXNhYWNiZWxsL0RvY3VtZW50cy9nZW9nNDkwL2ZpbmFsX3Byb2ovZGF0YS8iCm5jbmFtZSA8LSAiMjAwMHRvMjAyNCIKbmNmbmFtZSA8LSBwYXN0ZShuY3BhdGgsIG5jbmFtZSwgIi5uYyIsIHNlcD0iIikKbmNpbiA8LSBuY19vcGVuKG5jZm5hbWUpCmRuYW1lIDwtICJkYWlseV9tZWFuX3BhbG1lcl9kcm91Z2h0X3NldmVyaXR5X2luZGV4Igpsb24gPC0gbmN2YXJfZ2V0KG5jaW4sImxvbiIpCm5sb24gPC0gZGltKGxvbikKbGF0IDwtIG5jdmFyX2dldChuY2luLCJsYXQiKQpubGF0IDwtIGRpbShsYXQpCnRpdGxlIDwtIG5jYXR0X2dldChuY2luLDAsInRpdGxlIikKaW5zdGl0dXRpb24gPC0gbmNhdHRfZ2V0KG5jaW4sMCwiaW5zdGl0dXRpb24iKQpkYXRhc291cmNlIDwtIG5jYXR0X2dldChuY2luLDAsInNvdXJjZSIpCnJlZmVyZW5jZXMgPC0gbmNhdHRfZ2V0KG5jaW4sMCwicmVmZXJlbmNlcyIpCmhpc3RvcnkgPC0gbmNhdHRfZ2V0KG5jaW4sMCwiaGlzdG9yeSIpCkNvbnZlbnRpb25zIDwtIG5jYXR0X2dldChuY2luLDAsIkNvbnZlbnRpb25zIikKcGRzaV9hcnJheSA8LSBuY3Zhcl9nZXQobmNpbixkbmFtZSkKZGxuYW1lIDwtIG5jYXR0X2dldChuY2luLGRuYW1lLCJsb25nX25hbWUiKQpkdW5pdHMgPC0gbmNhdHRfZ2V0KG5jaW4sZG5hbWUsInVuaXRzIikKZmlsbHZhbHVlIDwtIG5jYXR0X2dldChuY2luLGRuYW1lLCJfRmlsbFZhbHVlIikKZGltKHBkc2lfYXJyYXkpCmBgYAoKCkdldHRpbmcgdGltZSBmcm9tIG5ldENERjoKCmBgYHtyfQp0aW1lIDwtIG5jdmFyX2dldChuY2luLCJkYXkiKQp0dW5pdHMgPC0gbmNhdHRfZ2V0KG5jaW4sImRheSIsInVuaXRzIikKbnQgPC0gZGltKHRpbWUpCmNmIDwtIENGdGltZSh0dW5pdHMkdmFsdWUsIGNhbGVuZGFyID0gInByb2xlcHRpY19ncmVnb3JpYW4iLCB0aW1lKSAKdGltZXN0YW1wcyA8LSBDRnRpbWVzdGFtcChjZikKbW9udGhzID0gQ0ZmYWN0b3IoY2YsIm1vbnRoIikKdGltZV9jZiA8LSBDRnBhcnNlKGNmLCB0aW1lc3RhbXBzKQpoZWFkKHRpbWVfY2YpCmBgYApBcyB5b3UgY2FuIHNlZSwgdGhlIGZpbGUgY29udGFpbnMgbWVhc3VyZW1lbnRzIHJlY3VycmluZyBldmVyeSA1IGRheXMuCgoKTWFraW5nIGEgcmFzdGVyIGZyb20gbmV0Q0RGLCBhbmQgYXBwbHlpbmcgdGltZSB2YWx1ZXMgdG8gaXQ6CgpgYGB7cn0KcGRzaV9yYXN0ZXIgPC0gcmFzdChuY2ZuYW1lKQpuYW1lcyhwZHNpX3Jhc3RlcikgPC0gdGltZXN0YW1wcwpzdGFtcHNfZGF0ZSA8LSBhcy5EYXRlKHRpbWVzdGFtcHMpCnRpbWUocGRzaV9yYXN0ZXIpIDwtIHN0YW1wc19kYXRlCmBgYApUaGlzIGFsbG93cyBtZSB0byBwYXJzZSB0aGUgcmFzdGVyIHN0YWNrIGJ5IGRhdGUuCgoKR2V0dGluZyB0aGUgb3ZlcmFsbCBtZWFuIFBEU0kgdmFsdWVzIGZvciB0aGUgd2hvbGUgMjAwMC0yMDI0IHJhc3RlciBzdGFjazoKCmBgYHtyfQptZWFuX3Jhc3RlciA9IG1lYW4ocGRzaV9yYXN0ZXIpCnBsb3QobWVhbl9yYXN0ZXIpCmBgYAoKIyMgR2VvZ3JhcGhpYyBhbmFseXNpcwoKTm93IHRoYXQgSSBoYXZlIHRoZSBjb3VudHkgYW5kIHN0YXRlIGdlb21ldHJpZXMsIEkgY2FuIHVzZSB0aGUgYGV4YWN0X2V4dHJhY3QoKWAgZnVuY3Rpb24gdG8gcHVsbCB0aGUgZGF0YSBmcm9tIHRoZSByYXN0ZXIgaW50byB0aGUgdmVjdG9yLiBUaGlzIGNvbWVzIGZyb20gdGhlIGBleGFjdGV4dHJhdHJgIGxpYnJhcnksIGFuZCBpdCBhbGxvd3MgbWUgdG8gd3JpdGUgdGhlIGF2ZXJhZ2UgdmFsdWUgd2l0aGluIGVhY2ggcG9seWdvbiB0byBhIG5ldyBjb2x1bW4gb24gdGhlIHZlY3RvciBkYXRhLgoKYGBge3IgcmVzdWx0cz0naGlkZScsZmlnLmtlZXA9J2FsbCd9CnNlbGVjdGVkX3NmJG1lYW5fYWxsdGltZSA8LSBleGFjdF9leHRyYWN0KG1lYW5fcmFzdGVyLCBzZWxlY3RlZF9zZiwgJ21lYW4nKQpwbG90KHNlbGVjdGVkX3NmWywnbWVhbl9hbGx0aW1lJ10pCmBgYAoKYGBge3IgcmVzdWx0cz0naGlkZScsZmlnLmtlZXA9J2FsbCd9CnNlbGVjdGVkX2NvdW50eSRtZWFuX2FsbHRpbWUgPC0gZXhhY3RfZXh0cmFjdChtZWFuX3Jhc3Rlciwgc2VsZWN0ZWRfY291bnR5LCAnbWVhbicpCnBsb3Qoc2VsZWN0ZWRfY291bnR5WywnbWVhbl9hbGx0aW1lJ10pCmBgYAoobm90ZSB0aGF0IHRoZSBzY2FsZXMgYXJlIGRpZmZlcmVudCBmb3IgYm90aCBwbG90cykKCkluIHRoZSBzdGF0ZSBwbG90cywgeW91IGNhbiBzZWUgdGhhdCBldmVyeSBzdGF0ZSBpbiB0aGUgd2VzdCBoYXMgc2VlbiBzdHJvbmdlciBkcnkgY29uZGl0aW9ucyB0aGFuIHdldCBjb25kaXRpb25zIHNpbmNlIDIwMDAuIE1vbnRhbmEgbG9va3MgdG8gYmUgdGhlIGxlYXN0IGFmZmVjdGVkLCBhbmQgT3JlZ29uIGhhcyBoYWQgdGhlIGRyaWVzdCBhdmVyYWdlIGNvbmRpdGlvbnMgKHJlbGF0aXZlIHRvIG5vcm1hbCkuCgoKTmV4dCwgSSdsbCBzcGxpdCB1cCB0aGUgcmFzdGVyIHN0YWNrIGludG8gaW5kaXZpZHVhbCB5ZWFycywgdGhlbiB1c2UgYGV4YWN0X2V4dHJhY3QoKWAgdG8gZ2V0IHRoZSBtZWFucyBmb3IgZWFjaCB5ZWFyIGludG8gdGhlIHN0YXRlIGFuZCBjb3VudHkgc2hhcGVmaWxlcy4KCmBgYHtyIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KeWVhcl9saSA8LSBzZXEoMjAwMCwyMDI0KQpmb3IgKGkgaW4geWVhcl9saSl7CmkgPC0gdG9TdHJpbmcoaSkKYSA8LSBwZHNpX3Jhc3RlcltpXQpzZWxlY3RlZF9zZlssIGldIDwtIGV4YWN0X2V4dHJhY3QoYSwgc2VsZWN0ZWRfc2YsICdtZWFuJykKc2VsZWN0ZWRfY291bnR5WywgaV0gPC0gZXhhY3RfZXh0cmFjdChhLCBzZWxlY3RlZF9jb3VudHksICdtZWFuJykKfQpgYGAKKFRoaXMgbWlnaHQgbm90IGJlIHRoZSBtb3N0IGVmZmljaWVudCBtZXRob2QsIGJ1dCBpdCB3b3JrcyB3ZWxsIGVub3VnaCkKCgpIZXJlJ3MgYSBxdWljayB0aW1lIHNlcmllcyBwbG90IG9mIHRoZSBhdmVyYWdlIFBEU0kgZm9yIGVhY2ggc3RhdGU6CgpgYGB7ciByZXN1bHRzPSdoaWRlJyxmaWcua2VlcD0nYWxsJ30Kc3RhdGVzX2RmIDwtIHN0X2Ryb3BfZ2VvbWV0cnkoc2VsZWN0ZWRfc2YpCmRyb3BzIDwtIGMoIklEIiwibWVhbl9hbGx0aW1lIikKc2VsZWN0X3N0YXRlc19kZiA8LSBzdGF0ZXNfZGZbICwgIShuYW1lcyhzdGF0ZXNfZGYpICVpbiUgZHJvcHMpXQpzZWxlY3Rfc3RhdGVzX2RmJG1ldGFkYXRhIDwtIHJvdy5uYW1lcyhzZWxlY3Rfc3RhdGVzX2RmKQpzZWxlY3Rfc3RhdGVzX2RmIDwtIG1lbHQoc2VsZWN0X3N0YXRlc19kZiwgIm1ldGFkYXRhIikKZ2dwbG90KHNlbGVjdF9zdGF0ZXNfZGYsIGFlcyh2YXJpYWJsZSwgdmFsdWUsIGdyb3VwID0gbWV0YWRhdGEsIGNvbG9yID0gbWV0YWRhdGEpKSArIApnZW9tX2xpbmUoKQpgYGAKCgpMZXQncyBwbG90IHRoZSBhdmVyYWdlIFBEU0kgcmFzdGVycyBmb3IgYSBjb3VwbGUgb2YgeWVhcnM6CgpgYGB7cn0KcmFzdGVyXzIwMDAgPC0gbWVhbihwZHNpX3Jhc3RlclsiMjAwMCJdKQpwbG90KHJhc3Rlcl8yMDAwLAogICAgIGJyZWFrcz1jKC00LC0zLC0yLC0xLDAsMSwyLDMsNCksCiAgICAgY29sPWJyZXdlci5wYWwoOSwgIlJkWWxHbiIpLAogICAgIG1haW49Ik1lYW4gUERTSTogMjAwMCIKICAgICApCmBgYApgYGB7cn0KcmFzdGVyXzIwMjMgPC0gbWVhbihwZHNpX3Jhc3RlclsiMjAyMyJdKQpwbG90KHJhc3Rlcl8yMDIzLAogICAgIGJyZWFrcz1jKC01LC00LC0zLC0yLC0xLDAsMSwyLDMsNCw1KSwKICAgICBjb2w9YnJld2VyLnBhbCgxMSwgIlJkWWxHbiIpLAogICAgIG1haW49Ik1lYW4gUERTSTogMjAyMyIKICAgICApCmBgYApGb3IgcmVmZXJlbmNlLCB0aGUgTmF0aW9uYWwgRHJvdWdodCBNaXRpZ2F0aW9uIENlbnRlciBjb25zaWRlcnMgUERTSSB2YWx1ZXMgZnJvbSAtMyB0byAtNCAnc2V2ZXJlIGRyb3VnaHQsJyBhbmQgdmFsdWVzIGFib3ZlIC00IGFzICdleHRyZW1lIGRyb3VnaHQuJwo=