In this Notebook, we’ll do compute some summary stats for the attribute table of the Yosemite fire ignition points, then use attribute queries to filter them.

SETUP

Load the packages we’ll need for this notebook (sf, dplyr, and tmap):

library(sf)
library(dplyr)
library(tmap)


Pro-actively resolve any name clashes:

library(conflicted)

# Set conflict preferences
conflict_prefer("filter", "dplyr", quiet = TRUE)
conflict_prefer("count", "dplyr", quiet = TRUE)
conflict_prefer("select", "dplyr", quiet = TRUE)
conflict_prefer("arrange", "dplyr", quiet = TRUE)


Next import fire ignition points layer:

## Define the location of the geodatabase
gdb_fires_fn <- "./data/yose_firehistory.gdb"
file.exists(gdb_fires_fn)
[1] TRUE
## View the layers in this source
st_layers(gdb_fires_fn)
Driver: OpenFileGDB 
Available layers:
## Import the historic fires ignition points
yose_fires_pt <- st_read(gdb_fires_fn, layer="YNP_FireHistoryPoints")
Reading layer `YNP_FireHistoryPoints' from data source 
  `D:\Workshops\R-Spatial\rspatial_mod\outputs\rspatial_bgs23\notebooks\data\yose_firehistory.gdb' 
  using driver `OpenFileGDB'
Simple feature collection with 4432 features and 21 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 243771.7 ymin: 4152632 xmax: 304217.2 ymax: 4227949
Projected CRS: NAD83 / UTM zone 11N
## Preview
glimpse(yose_fires_pt)
Rows: 4,432
Columns: 22
$ OBJECTID  <int> 1, 2, 3, 8, 7, 10, 5, 9, 6, 4, 18, 12, 28, 31, 29, 30, 27, 26, 14, 17, 23, 21, 32, 33, 25, 2…
$ FIRE_ID   <chr> "YNP-2", "YNP-3", "YNP-7", "YNP-10", "YNP-11", "YNP-15", "YNP-19", "YNP-20", "YNP-3", "YNP-5…
$ LINK_ID   <chr> "1930YNP-2", "1930YNP-3", "1930YNP-7", "1931YNP-10", "1931YNP-11", "1931YNP-15", "1931YNP-19…
$ SACS_ID   <chr> "YNP-002", "YNP-003", "YNP-007", "YNP-010", "YNP-011", "YNP-015", "YNP-019", "YNP-020", "YNP…
$ FILE_ID   <chr> " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " …
$ NAME      <chr> " ", " ", " ", "Dog Lake\n", "Rafferty Creek\n", "Cottonwood Cree", "Merced Lake\n", "Onoin …
$ ACRES     <dbl> 0.004, 0.007, 0.870, 0.099, 0.050, 1.989, 0.011, 1.492, 0.994, 0.079, 0.010, 0.010, 5.271, 0…
$ YEAR      <int> 1930, 1930, 1930, 1931, 1931, 1931, 1931, 1931, 1931, 1931, 1932, 1932, 1932, 1932, 1932, 19…
$ TYPE      <chr> "WF", "WF", "WF", "WF", "WF", "WF", "WF", "WF", "WF", "WF", "WF", "WF", "WF", "WF", "WF", "W…
$ CAUSE     <chr> "LTG", "LTG", "LTG", "LTG", "LTG", "LTG", "LTG", "LTG", "LTG", "LTG", "LTG", "LTG", "LTG", "…
$ HECTARES  <dbl> 0.001780549, 0.002750173, 0.352157100, 0.040217169, 0.020073619, 0.804988998, 0.004530046, 0…
$ AREA      <dbl> 17.805, 27.502, 3521.572, 402.172, 200.736, 8049.891, 45.301, 6037.401, 4024.610, 321.289, 3…
$ PERIMETER <dbl> 14.97941, 18.61561, 210.64806, 71.18618, 50.29261, 318.48152, 23.89166, 275.81270, 225.19107…
$ SEQ_NO    <dbl> 157, 156, 155, 150, 151, 148, 153, 149, 152, 154, 140, 146, 130, 127, 129, 128, 131, 132, 14…
$ DECADE    <int> 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930, 19…
$ STARTDATE <dttm> 1899-12-30, 1899-12-30, 1899-12-30, 1899-12-30, 1899-12-30, 1899-12-30, 1899-12-30, 1899-12…
$ OUTDATE   <dttm> 1899-12-30, 1899-12-30, 1899-12-30, 1899-12-30, 1899-12-30, 1899-12-30, 1899-12-30, 1899-12…
$ X_COORD   <dbl> 262412.7, 267727.9, 266014.8, 287444.7, 295170.0, 256659.1, 285626.0, 256657.1, 261539.1, 26…
$ Y_COORD   <dbl> 4163816, 4166016, 4167194, 4197420, 4192392, 4198577, 4178935, 4197587, 4181555, 4171437, 41…
$ ET_ID     <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ ORIG_FID  <int> 1, 2, 3, 8, 7, 10, 5, 9, 6, 4, 18, 12, 28, 31, 29, 30, 27, 26, 14, 17, 23, 21, 32, 33, 25, 2…
$ Shape     <POINT [m]> POINT (262412.7 4163816), POINT (267727.9 4166016), POINT (266014.8 4167194), POINT (2…


Import the park boundary and project it to UTM Zone 11N NAD83 (for plotting):

epsg_utm11n_nad83 <- 26911

yose_bnd_sf <- st_read(dsn="./data", layer="yose_boundary") |> 
  st_transform(epsg_utm11n_nad83)
Reading layer `yose_boundary' from data source 
  `D:\Workshops\R-Spatial\rspatial_mod\outputs\rspatial_bgs23\notebooks\data' using driver `ESRI Shapefile'
Simple feature collection with 1 feature and 11 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: -119.8864 ymin: 37.4947 xmax: -119.1964 ymax: 38.18515
Geodetic CRS:  North_American_Datum_1983


Plot them:

tm_shape(yose_bnd_sf) +
  tm_borders() +
tm_shape(yose_fires_pt) + 
  tm_dots(col = "red", alpha = 0.5, size = 0.05) 


DESCRIPTIVE STATS OF THE ATTRIBUTE TABLE

If you want to compute descriptive stats on the attribute table, without regard to the geometry, you can extract the attribute table as a data frame with st_drop_geometry():

yose_fires_pt |> st_drop_geometry() |> head()


CHALLENGE QUESTIONS

Q01. What is the distribution of acres burned?

TIP: To view the distribution, compute the quantiles or make a histogram plot.

Answer

## Because the 'ACRES' column is numeric, you can compute the quantitles with summary()
summary(yose_fires_pt$ACRES)
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
    0.00     0.10     0.10    92.21     0.99 78892.00 
## Or:
quantile(yose_fires_pt$ACRES)
       0%       25%       50%       75%      100% 
    0.002     0.099     0.100     0.994 78892.000 
## Histogram
hist(yose_fires_pt$ACRES, breaks = 20)


Q02. Compute a frequency table of fire causes.

Answer

table(yose_fires_pt$CAUSE)

  HC  LTG   MI 
 829 3355  248 
#Or 
yose_fires_pt |> st_drop_geometry() |> group_by(CAUSE) |> tally()


Q03. What was the largest fire?

Answer

yose_fires_pt |> st_drop_geometry() |> slice_max(ACRES, n=1)


Or:

yose_fires_pt |> 
  st_drop_geometry() |> 
  arrange(desc(ACRES)) |> 
  slice(1)


Q04. For each decade, compute the number of fires, and the mean fire size.

Answer

yose_fires_pt |> 
  st_drop_geometry() |> 
  group_by(DECADE) |> 
  summarise(count = n(), avg_size_acres = mean(ACRES))


ATTRIBUTE QUERIES

Attribute queries can be performed using dplyr filter().

Example: make a plot of the fire ignition points from the 1930s:

fires30s_sf <- yose_fires_pt |> 
  filter(DECADE == 1930)

head(fires30s_sf)
Simple feature collection with 6 features and 21 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 256659.1 ymin: 4163816 xmax: 295170 ymax: 4198577
Projected CRS: NAD83 / UTM zone 11N
  OBJECTID FIRE_ID    LINK_ID SACS_ID FILE_ID             NAME ACRES YEAR TYPE CAUSE    HECTARES     AREA
1        1   YNP-2  1930YNP-2 YNP-002                          0.004 1930   WF   LTG 0.001780549   17.805
2        2   YNP-3  1930YNP-3 YNP-003                          0.007 1930   WF   LTG 0.002750173   27.502
3        3   YNP-7  1930YNP-7 YNP-007                          0.870 1930   WF   LTG 0.352157100 3521.572
4        8  YNP-10 1931YNP-10 YNP-010               Dog Lake\n 0.099 1931   WF   LTG 0.040217169  402.172
5        7  YNP-11 1931YNP-11 YNP-011         Rafferty Creek\n 0.050 1931   WF   LTG 0.020073619  200.736
6       10  YNP-15 1931YNP-15 YNP-015          Cottonwood Cree 1.989 1931   WF   LTG 0.804988998 8049.891
  PERIMETER SEQ_NO DECADE  STARTDATE    OUTDATE  X_COORD Y_COORD ET_ID ORIG_FID                    Shape
1  14.97941    157   1930 1899-12-30 1899-12-30 262412.7 4163816     0        1 POINT (262412.7 4163816)
2  18.61561    156   1930 1899-12-30 1899-12-30 267727.9 4166016     0        2 POINT (267727.9 4166016)
3 210.64806    155   1930 1899-12-30 1899-12-30 266014.8 4167194     0        3 POINT (266014.8 4167194)
4  71.18618    150   1930 1899-12-30 1899-12-30 287444.7 4197420     0        8 POINT (287444.7 4197420)
5  50.29261    151   1930 1899-12-30 1899-12-30 295170.0 4192392     0        7   POINT (295170 4192392)
6 318.48152    148   1930 1899-12-30 1899-12-30 256659.1 4198577     0       10 POINT (256659.1 4198577)
tm_shape(yose_bnd_sf) +
  tm_borders() +
tm_shape(fires30s_sf) + 
  tm_dots(col = "red", size = 0.2) 


CHALLENGE QUESTIONS

Q05. Make a plot of all the human caused fire ignition points.

Answer

fires_hc_sf <- yose_fires_pt |>  
  filter(CAUSE == 'HC')

tm_shape(yose_bnd_sf) +
  tm_borders() +
tm_shape(fires_hc_sf) + 
  tm_dots(col = "red", size = 0.2)


Q06. Make a plot of all the human caused fire ignition points in the 1980s (only).

Answer

fires_hc80s_sf <- yose_fires_pt |>  
  filter(CAUSE == 'HC', DECADE == 1980)

tm_shape(yose_bnd_sf) +
  tm_borders() +
tm_shape(fires_hc80s_sf) + 
  tm_dots(col = "red", size = 0.2) +
tm_layout(main.title = "Human Caused Fires During the 1980s",
          main.title.size = 1)


Q07. Plot the human caused fires each decade (one plot per decade), for each decade from the 1980s onward:

Tip: See tm_facets()

Answer

fires_hc50s20_sf <- yose_fires_pt |>  
  filter(CAUSE == 'HC', DECADE >= 1980)

tm_shape(yose_bnd_sf) +
  tm_borders() +
tm_shape(fires_hc50s20_sf) + 
  tm_dots(col = "red", size = 0.2) +
tm_facets(by = "DECADE") +
  tm_layout(main.title = "Human Caused Fires Per Decade",
            main.title.size = 1)

LS0tDQp0aXRsZTogIkV4cGxvcmUgdGhlIEZpcmUgSWduaXRpb24gUG9pbnRzIEF0dHJpYnV0ZSBUYWJsZSINCm91dHB1dDogDQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KLS0tDQoNCkluIHRoaXMgTm90ZWJvb2ssIHdlJ2xsIGRvIGNvbXB1dGUgc29tZSBzdW1tYXJ5IHN0YXRzIGZvciB0aGUgYXR0cmlidXRlIHRhYmxlIG9mIHRoZSBZb3NlbWl0ZSBmaXJlIGlnbml0aW9uIHBvaW50cywgdGhlbiB1c2UgYXR0cmlidXRlIHF1ZXJpZXMgdG8gZmlsdGVyIHRoZW0uDQoNCiMgU0VUVVANCg0KTG9hZCB0aGUgcGFja2FnZXMgd2UnbGwgbmVlZCBmb3IgdGhpcyBub3RlYm9vayAoc2YsIGRwbHlyLCBhbmQgdG1hcCk6DQoNCmBgYHtyIGNodW5rMDF9DQpsaWJyYXJ5KHNmKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkodG1hcCkNCmBgYA0KDQpcDQoNClByby1hY3RpdmVseSByZXNvbHZlIGFueSBuYW1lIGNsYXNoZXM6DQoNCmBgYHtyIGNodW5rMDJ9DQpsaWJyYXJ5KGNvbmZsaWN0ZWQpDQoNCiMgU2V0IGNvbmZsaWN0IHByZWZlcmVuY2VzDQpjb25mbGljdF9wcmVmZXIoImZpbHRlciIsICJkcGx5ciIsIHF1aWV0ID0gVFJVRSkNCmNvbmZsaWN0X3ByZWZlcigiY291bnQiLCAiZHBseXIiLCBxdWlldCA9IFRSVUUpDQpjb25mbGljdF9wcmVmZXIoInNlbGVjdCIsICJkcGx5ciIsIHF1aWV0ID0gVFJVRSkNCmNvbmZsaWN0X3ByZWZlcigiYXJyYW5nZSIsICJkcGx5ciIsIHF1aWV0ID0gVFJVRSkNCmBgYA0KDQpcDQoNCk5leHQgaW1wb3J0IGZpcmUgaWduaXRpb24gcG9pbnRzIGxheWVyOg0KDQpgYGB7ciBjaHVuazAzfQ0KIyMgRGVmaW5lIHRoZSBsb2NhdGlvbiBvZiB0aGUgZ2VvZGF0YWJhc2UNCmdkYl9maXJlc19mbiA8LSAiLi9kYXRhL3lvc2VfZmlyZWhpc3RvcnkuZ2RiIg0KZmlsZS5leGlzdHMoZ2RiX2ZpcmVzX2ZuKQ0KDQojIyBWaWV3IHRoZSBsYXllcnMgaW4gdGhpcyBzb3VyY2UNCnN0X2xheWVycyhnZGJfZmlyZXNfZm4pDQoNCiMjIEltcG9ydCB0aGUgaGlzdG9yaWMgZmlyZXMgaWduaXRpb24gcG9pbnRzDQp5b3NlX2ZpcmVzX3B0IDwtIHN0X3JlYWQoZ2RiX2ZpcmVzX2ZuLCBsYXllcj0iWU5QX0ZpcmVIaXN0b3J5UG9pbnRzIikNCg0KIyMgUHJldmlldw0KZ2xpbXBzZSh5b3NlX2ZpcmVzX3B0KQ0KYGBgDQoNClwNCg0KSW1wb3J0IHRoZSBwYXJrIGJvdW5kYXJ5IGFuZCBwcm9qZWN0IGl0IHRvIFVUTSBab25lIDExTiBOQUQ4MyAoZm9yIHBsb3R0aW5nKToNCg0KYGBge3IgY2h1bmswNH0NCmVwc2dfdXRtMTFuX25hZDgzIDwtIDI2OTExDQoNCnlvc2VfYm5kX3NmIDwtIHN0X3JlYWQoZHNuPSIuL2RhdGEiLCBsYXllcj0ieW9zZV9ib3VuZGFyeSIpIHw+IA0KICBzdF90cmFuc2Zvcm0oZXBzZ191dG0xMW5fbmFkODMpDQpgYGANCg0KXA0KDQpQbG90IHRoZW06DQoNCmBgYHtyIGNodW5rMDV9DQp0bV9zaGFwZSh5b3NlX2JuZF9zZikgKw0KICB0bV9ib3JkZXJzKCkgKw0KdG1fc2hhcGUoeW9zZV9maXJlc19wdCkgKyANCiAgdG1fZG90cyhjb2wgPSAicmVkIiwgYWxwaGEgPSAwLjUsIHNpemUgPSAwLjA1KSANCmBgYA0KDQpcDQoNCiMgREVTQ1JJUFRJVkUgU1RBVFMgT0YgVEhFIEFUVFJJQlVURSBUQUJMRQ0KDQpJZiB5b3Ugd2FudCB0byBjb21wdXRlIGRlc2NyaXB0aXZlIHN0YXRzIG9uIHRoZSBhdHRyaWJ1dGUgdGFibGUsIHdpdGhvdXQgcmVnYXJkIHRvIHRoZSBnZW9tZXRyeSwgeW91IGNhbiBleHRyYWN0IHRoZSBhdHRyaWJ1dGUgdGFibGUgYXMgYSBkYXRhIGZyYW1lIHdpdGggYHN0X2Ryb3BfZ2VvbWV0cnkoKWA6DQoNCmBgYHtyIGNodW5rMDZ9DQp5b3NlX2ZpcmVzX3B0IHw+IHN0X2Ryb3BfZ2VvbWV0cnkoKSB8PiBoZWFkKCkNCmBgYA0KDQpcDQoNCiMjIENIQUxMRU5HRSBRVUVTVElPTlMNCg0KUTAxLiBXaGF0IGlzIHRoZSBkaXN0cmlidXRpb24gb2YgYWNyZXMgYnVybmVkPw0KDQpUSVA6IFRvIHZpZXcgdGhlIGRpc3RyaWJ1dGlvbiwgY29tcHV0ZSB0aGUgcXVhbnRpbGVzIG9yIG1ha2UgYSBoaXN0b2dyYW0gcGxvdC4NCg0KW0Fuc3dlcl0oaHR0cDovL2JpdC5seS8za1hWSFpBKQ0KDQpgYGB7ciBjaHVuazA3fQ0KIyMgQmVjYXVzZSB0aGUgJ0FDUkVTJyBjb2x1bW4gaXMgbnVtZXJpYywgeW91IGNhbiBjb21wdXRlIHRoZSBxdWFudGl0bGVzIHdpdGggc3VtbWFyeSgpDQpzdW1tYXJ5KHlvc2VfZmlyZXNfcHQkQUNSRVMpDQoNCiMjIE9yOg0KcXVhbnRpbGUoeW9zZV9maXJlc19wdCRBQ1JFUykNCg0KIyMgSGlzdG9ncmFtDQpoaXN0KHlvc2VfZmlyZXNfcHQkQUNSRVMsIGJyZWFrcyA9IDIwKQ0KYGBgDQoNClwNCg0KUTAyLiBDb21wdXRlIGEgZnJlcXVlbmN5IHRhYmxlIG9mIGZpcmUgY2F1c2VzLg0KDQpbQW5zd2VyXShodHRwOi8vYml0Lmx5LzNaenZUNWEpDQoNCmBgYHtyIGNodW5rMDh9DQp0YWJsZSh5b3NlX2ZpcmVzX3B0JENBVVNFKQ0KDQojT3IgDQp5b3NlX2ZpcmVzX3B0IHw+IHN0X2Ryb3BfZ2VvbWV0cnkoKSB8PiBncm91cF9ieShDQVVTRSkgfD4gdGFsbHkoKQ0KYGBgDQoNClwNCg0KUTAzLiBXaGF0IHdhcyB0aGUgbGFyZ2VzdCBmaXJlPw0KDQpbQW5zd2VyXShodHRwOi8vYml0Lmx5LzNaeDBLMmspDQoNCmBgYHtyIGNodW5rMDl9DQp5b3NlX2ZpcmVzX3B0IHw+IHN0X2Ryb3BfZ2VvbWV0cnkoKSB8PiBzbGljZV9tYXgoQUNSRVMsIG49MSkNCmBgYA0KDQpcDQoNCk9yOg0KDQpgYGB7ciBjaHVuazEwfQ0KeW9zZV9maXJlc19wdCB8PiANCiAgc3RfZHJvcF9nZW9tZXRyeSgpIHw+IA0KICBhcnJhbmdlKGRlc2MoQUNSRVMpKSB8PiANCiAgc2xpY2UoMSkNCmBgYA0KDQpcDQoNClEwNC4gRm9yIGVhY2ggZGVjYWRlLCBjb21wdXRlIHRoZSBudW1iZXIgb2YgZmlyZXMsIGFuZCB0aGUgbWVhbiBmaXJlIHNpemUuDQoNCltBbnN3ZXJdKGh0dHA6Ly9iaXQubHkvM0Y1WmIzZSkNCg0KYGBge3IgY2h1bmsxMX0NCnlvc2VfZmlyZXNfcHQgfD4gDQogIHN0X2Ryb3BfZ2VvbWV0cnkoKSB8PiANCiAgZ3JvdXBfYnkoREVDQURFKSB8PiANCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCBhdmdfc2l6ZV9hY3JlcyA9IG1lYW4oQUNSRVMpKQ0KYGBgDQoNClwNCg0KIyBBVFRSSUJVVEUgUVVFUklFUw0KDQpBdHRyaWJ1dGUgcXVlcmllcyBjYW4gYmUgcGVyZm9ybWVkIHVzaW5nIGRwbHlyIGBmaWx0ZXIoKWAuDQoNCkV4YW1wbGU6IG1ha2UgYSBwbG90IG9mIHRoZSBmaXJlIGlnbml0aW9uIHBvaW50cyBmcm9tIHRoZSAxOTMwczoNCg0KYGBge3IgY2h1bmsxMn0NCmZpcmVzMzBzX3NmIDwtIHlvc2VfZmlyZXNfcHQgfD4gDQogIGZpbHRlcihERUNBREUgPT0gMTkzMCkNCg0KaGVhZChmaXJlczMwc19zZikNCg0KdG1fc2hhcGUoeW9zZV9ibmRfc2YpICsNCiAgdG1fYm9yZGVycygpICsNCnRtX3NoYXBlKGZpcmVzMzBzX3NmKSArIA0KICB0bV9kb3RzKGNvbCA9ICJyZWQiLCBzaXplID0gMC4yKSANCmBgYA0KDQpcDQoNCiMjIENIQUxMRU5HRSBRVUVTVElPTlMNCg0KUTA1LiBNYWtlIGEgcGxvdCBvZiBhbGwgdGhlIGh1bWFuIGNhdXNlZCBmaXJlIGlnbml0aW9uIHBvaW50cy4NCg0KW0Fuc3dlcl0oaHR0cDovL2JpdC5seS8zbDF1TFowKQ0KDQpgYGB7ciBjaHVuazEzfQ0KZmlyZXNfaGNfc2YgPC0geW9zZV9maXJlc19wdCB8PiAgDQogIGZpbHRlcihDQVVTRSA9PSAnSEMnKQ0KDQp0bV9zaGFwZSh5b3NlX2JuZF9zZikgKw0KICB0bV9ib3JkZXJzKCkgKw0KdG1fc2hhcGUoZmlyZXNfaGNfc2YpICsgDQogIHRtX2RvdHMoY29sID0gInJlZCIsIHNpemUgPSAwLjIpDQpgYGANCg0KXA0KDQpRMDYuIE1ha2UgYSBwbG90IG9mIGFsbCB0aGUgaHVtYW4gY2F1c2VkIGZpcmUgaWduaXRpb24gcG9pbnRzIGluIHRoZSAxOTgwcyAob25seSkuDQoNCltBbnN3ZXJdKGh0dHA6Ly9iaXQubHkvM2wwNWlpQikNCg0KYGBge3IgY2h1bmsxNH0NCmZpcmVzX2hjODBzX3NmIDwtIHlvc2VfZmlyZXNfcHQgfD4gIA0KICBmaWx0ZXIoQ0FVU0UgPT0gJ0hDJywgREVDQURFID09IDE5ODApDQoNCnRtX3NoYXBlKHlvc2VfYm5kX3NmKSArDQogIHRtX2JvcmRlcnMoKSArDQp0bV9zaGFwZShmaXJlc19oYzgwc19zZikgKyANCiAgdG1fZG90cyhjb2wgPSAicmVkIiwgc2l6ZSA9IDAuMikgKw0KdG1fbGF5b3V0KG1haW4udGl0bGUgPSAiSHVtYW4gQ2F1c2VkIEZpcmVzIER1cmluZyB0aGUgMTk4MHMiLA0KICAgICAgICAgIG1haW4udGl0bGUuc2l6ZSA9IDEpDQpgYGANCg0KXA0KDQpRMDcuIFBsb3QgdGhlICpodW1hbiBjYXVzZWQgZmlyZXMgZWFjaCBkZWNhZGUqIChvbmUgcGxvdCBwZXIgZGVjYWRlKSwgZm9yIGVhY2ggZGVjYWRlIGZyb20gdGhlIDE5ODBzIG9ud2FyZDoNCg0KVGlwOiBTZWUgYHRtX2ZhY2V0cygpYA0KDQpbQW5zd2VyXShodHRwOi8vYml0Lmx5LzNtR3M3WVkpDQoNCmBgYHtyIGNodW5rMTV9DQpmaXJlc19oYzUwczIwX3NmIDwtIHlvc2VfZmlyZXNfcHQgfD4gIA0KICBmaWx0ZXIoQ0FVU0UgPT0gJ0hDJywgREVDQURFID49IDE5ODApDQoNCnRtX3NoYXBlKHlvc2VfYm5kX3NmKSArDQogIHRtX2JvcmRlcnMoKSArDQp0bV9zaGFwZShmaXJlc19oYzUwczIwX3NmKSArIA0KICB0bV9kb3RzKGNvbCA9ICJyZWQiLCBzaXplID0gMC4yKSArDQp0bV9mYWNldHMoYnkgPSAiREVDQURFIikgKw0KICB0bV9sYXlvdXQobWFpbi50aXRsZSA9ICJIdW1hbiBDYXVzZWQgRmlyZXMgUGVyIERlY2FkZSIsDQogICAgICAgICAgICBtYWluLnRpdGxlLnNpemUgPSAxKQ0KYGBgDQoNCg==