Objective

WE FINALLY HAVE HEAT FLUX DATA (I am extremely excited by this because downloading data is no fun). But we need to make sure that the data is reasonable and confirm that we have enough heat flux data to continue with the hector calibration project(s).

Heat Flux Data

# Make a table of the cmip info wide by variable with indicator information about whether or not there is 
# data for that variable.
cmip_individual %>% 
    select(year, model, ensemble, variable, experiment) %>% 
    full_join(heat_flux %>%  select(year, model, ensemble, experiment, variable2=variable), 
              by = c("year", "model", "ensemble", "experiment")) %>% 
    gather(vari, name, variable, variable2) %>% 
    mutate(yes = TRUE) %>% 
    select(model, ensemble, experiment, name, yes) %>%  
    na.omit %>% 
    distinct %>% 
    spread(name, yes) -> 
    wide_variables

How many models do we have temp / heat flux data for?

length(unique(wide_variables$model))
[1] 35

So it looks like we have both tas and heat flux data for 35 models. However I am not sure if the historical data will constrain heat flux like we think is will. We are also concerned if the heat flux is too high during the historical period for Hector to be able to emulate.

What do the values look like?

The mean and sd of of the heat flux data for each scenario at 1850, 1900, 1950, and 2010, 2050, 2100.

heat_flux %>% 
    filter(year %in% c(1850, 1900, 1950, 2100, 2010, 2050, 2100)) %>% 
    group_by(experiment, year) %>% 
    summarise(mean = mean(value), 
              sd = sd(value))  %>% 
    na.omit %>% 
    arrange(experiment, year) %>%  
    kable(digits = 3)  %>% 
    kable_styling("striped", full_width = F) %>%
    collapse_rows(columns = 1)
experiment year mean sd
historical 1850 -1.875 23.387
1900 1.183 0.504
1950 1.304 0.608
rcp26 2010 1.945 0.761
2050 2.062 0.867
2100 1.417 0.714
rcp45 2010 1.975 1.307
2050 2.550 1.426
2100 2.334 1.383
rcp60 2010 2.159 0.581
2050 2.835 0.717
2100 3.204 0.734
rcp85 2010 1.631 1.397
2050 2.831 1.347
2100 3.997 1.678

Right off the bat I am surprised to see that the sd is so large in the historical period, I think that means that there is most likely some unrealistic values sneaking in there.

heat_flux %>% 
    ggplot(aes(year, value, color = model)) + 
    geom_point() + 
    facet_wrap('experiment', scales = 'free') + 
    theme(legend.position = 'none')

Right off the bat it looks like there are some questionable values for the historical period, rcp26, rcp45, and rcp85. I wonder if the points that are outlines in the historical and rcp26 are artifacts of numerical instability or if time series that underestimate the heat flux in rcp45 and rcp85 are because some variable is missing, but I thought that my prepossessing code would have taken care of that.

What models have outliers in the historical period?

Let’s define the outlines as heat flux values with a magnitude greater than 10.

heat_flux %>%
    filter(experiment == 'historical') %>%  
    filter(abs(value) > 10) %>%  
    pull(model) %>%
    unique() -> 
    hist_outliers

If we remove these models from do the historical runs look good?

heat_flux %>%  
    filter(!model %in% hist_outliers & experiment == 'historical') %>% 
    ggplot(aes(year, value, color = model, group = interaction(model, ensemble))) + 
    geom_line(alpha = 0.3) + 
    labs(y = 'w/m2')  -> 
    hist_plot
hist_plot

Yes I think so! I think that the models look pretty consistent in noise and trend.


What about the modes that have outlier values? Are they single years or for multiple years?

heat_flux %>% 
    filter(model %in% hist_outliers & experiment == 'historical') %>% 
    ggplot(aes(year, value, color = model, group = interaction(model, ensemble))) + 
    geom_point(alpha = 0.3) + 
    labs(y = 'w/m2') -> 
    hist_outlier_plot
hist_outlier_plot

How many years are outlines? for each ensemble / model?

hist_outlier_plot$data %>%
    filter(abs(value) >= 10) %>% 
    group_by(experiment, ensemble, model) %>% 
    summarise(n_outlier = n_distinct(year)) %>% 
    kable(digits = 3)  %>% 
    kable_styling("striped", full_width = F) %>%
    collapse_rows(columns = 1:2)
experiment ensemble model n_outlier
historical r2i1p1 CCSM4 3
MRI-CGCM3 3
r3i1p1 CCSM4 3
r5i1p1 CCSM4 6

If the outlines were removed what would the time series be more realistic?

hist_outlier_plot + 
    coord_cartesian(ylim = c(-10,10))

    
ggplot() + 
    geom_line(data = hist_plot$data, 
              aes(year, value, color = 'non outlier models', group = interaction(model, ensemble)), 
              alpha = 0.2) + 
    geom_point(data = hist_outlier_plot$data %>% 
                  filter(abs(value) < 10), 
              aes(year, value, color = model, group = interaction(model, ensemble))) + 
    labs(y = 'W/m2')

It looks like there are a few year for CCSM4 and MRI-CGCM3 that fall outside of the CMIP5 range but they don’t seem too drastic. Do we want to exclude the years with the heat Flux values greater than 10 and then keep the rest of the time series? Or do we exclude the heat flux data from our analysis? I thought that may be they had to do with the the models missing data at the end / start of runs or how they save data (some times modeling groups can write out multiple files for a single experiment every 5 years or so) but that was not the case few these models.


What models have outliers in the rcp26?

heat_flux %>%
    filter(experiment == 'rcp26' & abs(value) >= 10)  %>%  
    pull(model) %>%  
    unique() -> 
    outlier_rcp26
outlier_rcp26
[1] "CCSM4"     "MRI-CGCM3"

It looks like the same models have outlines in rcp26.


What models have outliers in rcp 85?

heat_flux %>%
    filter(experiment == 'rcp85' & value > 10) %>% 
    pull(model) %>% 
    unique() -> 
    outliers_rcp85; 
outliers_rcp85
[1] "CESM1-BGC"
heat_flux %>% 
    filter(experiment == 'rcp85' & model == outliers_rcp85) %>%  
    ggplot(aes(year, value, color  = model)) + 
    geom_line(data = heat_flux %>% 
                  filter(experiment == 'rcp85' & model != outliers_rcp85), 
              aes(year, value, color = 'other models', group = interaction(model, ensemble)), alpha = 0.3) + 
    geom_point() + 
    labs(y = 'w/m2') + 
    coord_cartesian(xlim = c(2006, 2100))

Well it loos like from 2990 to 2995 the CESM1-BGC has abnormally high heat flux values but reasonable values for the other years. Once again what do we do when there are only some of the years with suspicious data?

Below Expected Time Series

Both the rcp45 and rcp85 experiments have time series with values that are below.

heat_flux %>% 
    filter(experiment %in% c('rcp45', 'rcp85')) %>% 
    filter(value < -1) %>% 
    pull(model) %>%  
    unique()
[1] "inmcm4"

So it looks like the same model is the has unexpectedly low heat flux values. I wonder what could be causing it. I checked the errata (https://cmip.llnl.gov/cmip5/errata/cmip5errata.html) to see if inmcm4 had reported any problems with the data we used. While it did appear multiple times in the errata it wasn’t for any of the variables we used to calculate the heat flux.

Concluding Thoughts

Well its 5:00 on a Friday and I have brain mush so this look at our heat flux data has not been as thorough as I would like it to be. But it does raise some questions to consider.

  1. When there are cases where heat flux for a handful of year looks funky do we want to remove the outlier years or discard the entire time series?
  2. For inmcm4 what is going on? Is there a problem with one of the netcdf files we used because the trend and spread looks good to me, it is almost like the time series has been off set a bit.
LS0tCnRpdGxlOiAiV2hhdCdzIFVwIFdpdGggdGhlIEhlYXQgRmx1eCBEYXRhPyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyMgT2JqZWN0aXZlIAoKV0UgRklOQUxMWSBIQVZFIEhFQVQgRkxVWCBEQVRBIChJIGFtIGV4dHJlbWVseSBleGNpdGVkIGJ5IHRoaXMgYmVjYXVzZSBkb3dubG9hZGluZyBkYXRhIGlzIG5vIGZ1bikuIEJ1dCB3ZSBuZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSBkYXRhIGlzIHJlYXNvbmFibGUgYW5kIGNvbmZpcm0gdGhhdCB3ZSBoYXZlIGVub3VnaCBoZWF0IGZsdXggZGF0YSB0byBjb250aW51ZSB3aXRoIHRoZSBoZWN0b3IgY2FsaWJyYXRpb24gcHJvamVjdChzKS4KCmBgYHtyLCBlY2hvID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShoZWN0b3JjYWwpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeSh0aWR5cikKbGlicmFyeShrbml0cikKbGlicmFyeShrYWJsZUV4dHJhKQoKQkFTRV9ESVIgIDwtICAiL1VzZXJzL2RvcmgwMTIvRG9jdW1lbnRzLzIwMTkvaGVjdG9yY2FsIgpJTlBVVF9ESVIgPC0gZmlsZS5wYXRoKEJBU0VfRElSLCAnZGF0YS1yYXcnKQoKaGVhdF9mbHV4IDwtIHJlYWQuY3N2KGZpbGUucGF0aChJTlBVVF9ESVIsICdDTUlQNV9oZWF0X2ZsdXguY3N2JyksIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkgJT4lICAKICAgIGZpbHRlcihtb2RlbCAlaW4lIGNtaXBfaW5kaXZpZHVhbCRtb2RlbCkKYGBgCgojIyBIZWF0IEZsdXggRGF0YSAKCmBgYHtyfQojIE1ha2UgYSB0YWJsZSBvZiB0aGUgY21pcCBpbmZvIHdpZGUgYnkgdmFyaWFibGUgd2l0aCBpbmRpY2F0b3IgaW5mb3JtYXRpb24gYWJvdXQgd2hldGhlciBvciBub3QgdGhlcmUgaXMgCiMgZGF0YSBmb3IgdGhhdCB2YXJpYWJsZS4KY21pcF9pbmRpdmlkdWFsICU+JSAKICAgIHNlbGVjdCh5ZWFyLCBtb2RlbCwgZW5zZW1ibGUsIHZhcmlhYmxlLCBleHBlcmltZW50KSAlPiUgCiAgICBmdWxsX2pvaW4oaGVhdF9mbHV4ICU+JSAgc2VsZWN0KHllYXIsIG1vZGVsLCBlbnNlbWJsZSwgZXhwZXJpbWVudCwgdmFyaWFibGUyPXZhcmlhYmxlKSwgCiAgICAgICAgICAgICAgYnkgPSBjKCJ5ZWFyIiwgIm1vZGVsIiwgImVuc2VtYmxlIiwgImV4cGVyaW1lbnQiKSkgJT4lIAogICAgZ2F0aGVyKHZhcmksIG5hbWUsIHZhcmlhYmxlLCB2YXJpYWJsZTIpICU+JSAKICAgIG11dGF0ZSh5ZXMgPSBUUlVFKSAlPiUgCiAgICBzZWxlY3QobW9kZWwsIGVuc2VtYmxlLCBleHBlcmltZW50LCBuYW1lLCB5ZXMpICU+JSAgCiAgICBuYS5vbWl0ICU+JSAKICAgIGRpc3RpbmN0ICU+JSAKICAgIHNwcmVhZChuYW1lLCB5ZXMpIC0+IAogICAgd2lkZV92YXJpYWJsZXMKYGBgCgpIb3cgbWFueSBtb2RlbHMgZG8gd2UgaGF2ZSB0ZW1wIC8gaGVhdCBmbHV4IGRhdGEgZm9yPyAKCmBgYHtyfQpsZW5ndGgodW5pcXVlKHdpZGVfdmFyaWFibGVzJG1vZGVsKSkKYGBgCgpTbyBpdCBsb29rcyBsaWtlIHdlIGhhdmUgYm90aCB0YXMgYW5kIGhlYXQgZmx1eCBkYXRhIGZvciAzNSBtb2RlbHMuIEhvd2V2ZXIgSSBhbSBub3Qgc3VyZSBpZiB0aGUgaGlzdG9yaWNhbCBkYXRhIHdpbGwgY29uc3RyYWluIGhlYXQgZmx1eCBsaWtlIHdlIHRoaW5rIGlzIHdpbGwuIFdlIGFyZSBhbHNvIGNvbmNlcm5lZCBpZiB0aGUgaGVhdCBmbHV4IGlzIHRvbyBoaWdoIGR1cmluZyB0aGUgaGlzdG9yaWNhbCBwZXJpb2QgZm9yIEhlY3RvciB0byBiZSBhYmxlIHRvIGVtdWxhdGUuIAoKCgojIyBXaGF0IGRvIHRoZSB2YWx1ZXMgbG9vayBsaWtlPyAKClRoZSBtZWFuIGFuZCBzZCBvZiBvZiB0aGUgaGVhdCBmbHV4IGRhdGEgZm9yIGVhY2ggc2NlbmFyaW8gYXQgMTg1MCwgMTkwMCwgMTk1MCwgYW5kIDIwMTAsIDIwNTAsIDIxMDAuCgpgYGB7cn0KCmhlYXRfZmx1eCAlPiUgCiAgICBmaWx0ZXIoeWVhciAlaW4lIGMoMTg1MCwgMTkwMCwgMTk1MCwgMjEwMCwgMjAxMCwgMjA1MCwgMjEwMCkpICU+JSAKICAgIGdyb3VwX2J5KGV4cGVyaW1lbnQsIHllYXIpICU+JSAKICAgIHN1bW1hcmlzZShtZWFuID0gbWVhbih2YWx1ZSksIAogICAgICAgICAgICAgIHNkID0gc2QodmFsdWUpKSAgJT4lIAogICAgbmEub21pdCAlPiUgCiAgICBhcnJhbmdlKGV4cGVyaW1lbnQsIHllYXIpICU+JSAgCiAgICBrYWJsZShkaWdpdHMgPSAzKSAgJT4lIAogICAga2FibGVfc3R5bGluZygic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGKSAlPiUKICAgIGNvbGxhcHNlX3Jvd3MoY29sdW1ucyA9IDEpCmBgYAoKUmlnaHQgb2ZmIHRoZSBiYXQgSSBhbSBzdXJwcmlzZWQgdG8gc2VlIHRoYXQgdGhlIHNkIGlzIHNvIGxhcmdlIGluIHRoZSBoaXN0b3JpY2FsIHBlcmlvZCwgSSB0aGluayB0aGF0IG1lYW5zIHRoYXQgdGhlcmUgaXMgbW9zdCBsaWtlbHkgc29tZSB1bnJlYWxpc3RpYyB2YWx1ZXMgc25lYWtpbmcgaW4gdGhlcmUuIAoKYGBge3J9CmhlYXRfZmx1eCAlPiUgCiAgICBnZ3Bsb3QoYWVzKHllYXIsIHZhbHVlLCBjb2xvciA9IG1vZGVsKSkgKyAKICAgIGdlb21fcG9pbnQoKSArIAogICAgZmFjZXRfd3JhcCgnZXhwZXJpbWVudCcsIHNjYWxlcyA9ICdmcmVlJykgKyAKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJykKYGBgCgpSaWdodCBvZmYgdGhlIGJhdCBpdCBsb29rcyBsaWtlIHRoZXJlIGFyZSBzb21lIHF1ZXN0aW9uYWJsZSB2YWx1ZXMgZm9yIHRoZSBoaXN0b3JpY2FsIHBlcmlvZCwgcmNwMjYsIHJjcDQ1LCBhbmQgcmNwODUuIEkgd29uZGVyIGlmIHRoZSBwb2ludHMgdGhhdCBhcmUgb3V0bGluZXMgaW4gdGhlIGhpc3RvcmljYWwgYW5kIHJjcDI2IGFyZSBhcnRpZmFjdHMgb2YgbnVtZXJpY2FsIGluc3RhYmlsaXR5IG9yIGlmIHRpbWUgc2VyaWVzIHRoYXQgdW5kZXJlc3RpbWF0ZSB0aGUgaGVhdCBmbHV4IGluIHJjcDQ1IGFuZCByY3A4NSBhcmUgYmVjYXVzZSBzb21lIHZhcmlhYmxlIGlzIG1pc3NpbmcsIGJ1dCBJIHRob3VnaHQgdGhhdCBteSBwcmVwb3NzZXNzaW5nIGNvZGUgd291bGQgaGF2ZSB0YWtlbiBjYXJlIG9mIHRoYXQuIAoKCgojIyMgV2hhdCBtb2RlbHMgaGF2ZSBvdXRsaWVycyBpbiB0aGUgaGlzdG9yaWNhbCBwZXJpb2Q/IAoKTGV0J3MgZGVmaW5lIHRoZSBvdXRsaW5lcyBhcyBoZWF0IGZsdXggdmFsdWVzIHdpdGggYSBtYWduaXR1ZGUgZ3JlYXRlciB0aGFuIDEwLiAKCmBgYHtyfQpoZWF0X2ZsdXggJT4lCiAgICBmaWx0ZXIoZXhwZXJpbWVudCA9PSAnaGlzdG9yaWNhbCcpICU+JSAgCiAgICBmaWx0ZXIoYWJzKHZhbHVlKSA+IDEwKSAlPiUgIAogICAgcHVsbChtb2RlbCkgJT4lCiAgICB1bmlxdWUoKSAtPiAKICAgIGhpc3Rfb3V0bGllcnMKYGBgCgpJZiB3ZSByZW1vdmUgdGhlc2UgbW9kZWxzIGZyb20gZG8gdGhlIGhpc3RvcmljYWwgcnVucyBsb29rIGdvb2Q/IAoKYGBge3J9CmhlYXRfZmx1eCAlPiUgIAogICAgZmlsdGVyKCFtb2RlbCAlaW4lIGhpc3Rfb3V0bGllcnMgJiBleHBlcmltZW50ID09ICdoaXN0b3JpY2FsJykgJT4lIAogICAgZ2dwbG90KGFlcyh5ZWFyLCB2YWx1ZSwgY29sb3IgPSBtb2RlbCwgZ3JvdXAgPSBpbnRlcmFjdGlvbihtb2RlbCwgZW5zZW1ibGUpKSkgKyAKICAgIGdlb21fbGluZShhbHBoYSA9IDAuMykgKyAKICAgIGxhYnMoeSA9ICd3L20yJykgIC0+IAogICAgaGlzdF9wbG90Cmhpc3RfcGxvdApgYGAKClllcyBJIHRoaW5rIHNvISBJIHRoaW5rIHRoYXQgdGhlIG1vZGVscyBsb29rIHByZXR0eSBjb25zaXN0ZW50IGluIG5vaXNlIGFuZCB0cmVuZC4gCgo8YnI+CgpXaGF0IGFib3V0IHRoZSBtb2RlcyB0aGF0IGhhdmUgb3V0bGllciB2YWx1ZXM/IEFyZSB0aGV5IHNpbmdsZSB5ZWFycyBvciBmb3IgbXVsdGlwbGUgeWVhcnM/IAoKYGBge3J9CmhlYXRfZmx1eCAlPiUgCiAgICBmaWx0ZXIobW9kZWwgJWluJSBoaXN0X291dGxpZXJzICYgZXhwZXJpbWVudCA9PSAnaGlzdG9yaWNhbCcpICU+JSAKICAgIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gbW9kZWwsIGdyb3VwID0gaW50ZXJhY3Rpb24obW9kZWwsIGVuc2VtYmxlKSkpICsgCiAgICBnZW9tX3BvaW50KGFscGhhID0gMC4zKSArIAogICAgbGFicyh5ID0gJ3cvbTInKSAtPiAKICAgIGhpc3Rfb3V0bGllcl9wbG90Cmhpc3Rfb3V0bGllcl9wbG90CmBgYAoKSG93IG1hbnkgeWVhcnMgYXJlIG91dGxpbmVzPyBmb3IgZWFjaCBlbnNlbWJsZSAvIG1vZGVsPyAKCmBgYHtyfQpoaXN0X291dGxpZXJfcGxvdCRkYXRhICU+JQogICAgZmlsdGVyKGFicyh2YWx1ZSkgPj0gMTApICU+JSAKICAgIGdyb3VwX2J5KGV4cGVyaW1lbnQsIGVuc2VtYmxlLCBtb2RlbCkgJT4lIAogICAgc3VtbWFyaXNlKG5fb3V0bGllciA9IG5fZGlzdGluY3QoeWVhcikpICU+JSAKICAgIGthYmxlKGRpZ2l0cyA9IDMpICAlPiUgCiAgICBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEYpICU+JQogICAgY29sbGFwc2Vfcm93cyhjb2x1bW5zID0gMToyKQpgYGAKCgpJZiB0aGUgb3V0bGluZXMgd2VyZSByZW1vdmVkIHdoYXQgd291bGQgdGhlIHRpbWUgc2VyaWVzIGJlIG1vcmUgcmVhbGlzdGljPyAKCgpgYGB7cn0KaGlzdF9vdXRsaWVyX3Bsb3QgKyAKICAgIGNvb3JkX2NhcnRlc2lhbih5bGltID0gYygtMTAsMTApKQogICAgCmdncGxvdCgpICsgCiAgICBnZW9tX2xpbmUoZGF0YSA9IGhpc3RfcGxvdCRkYXRhLCAKICAgICAgICAgICAgICBhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gJ25vbiBvdXRsaWVyIG1vZGVscycsIGdyb3VwID0gaW50ZXJhY3Rpb24obW9kZWwsIGVuc2VtYmxlKSksIAogICAgICAgICAgICAgIGFscGhhID0gMC4yKSArIAogICAgZ2VvbV9wb2ludChkYXRhID0gaGlzdF9vdXRsaWVyX3Bsb3QkZGF0YSAlPiUgCiAgICAgICAgICAgICAgICAgIGZpbHRlcihhYnModmFsdWUpIDwgMTApLCAKICAgICAgICAgICAgICBhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gbW9kZWwsIGdyb3VwID0gaW50ZXJhY3Rpb24obW9kZWwsIGVuc2VtYmxlKSkpICsgCiAgICBsYWJzKHkgPSAnVy9tMicpCmBgYAoKSXQgbG9va3MgbGlrZSB0aGVyZSBhcmUgYSBmZXcgeWVhciBmb3IgQ0NTTTQgYW5kIE1SSS1DR0NNMyB0aGF0IGZhbGwgb3V0c2lkZSBvZiB0aGUgQ01JUDUgcmFuZ2UgYnV0IHRoZXkgZG9uJ3Qgc2VlbSB0b28gZHJhc3RpYy4gRG8gd2Ugd2FudCB0byBleGNsdWRlIHRoZSB5ZWFycyB3aXRoIHRoZSBoZWF0IEZsdXggdmFsdWVzIGdyZWF0ZXIgdGhhbiAxMCBhbmQgdGhlbiBrZWVwIHRoZSByZXN0IG9mIHRoZSB0aW1lIHNlcmllcz8gT3IgZG8gd2UgZXhjbHVkZSB0aGUgaGVhdCBmbHV4IGRhdGEgZnJvbSBvdXIgYW5hbHlzaXM/IEkgdGhvdWdodCB0aGF0IG1heSBiZSB0aGV5IGhhZCB0byBkbyB3aXRoIHRoZSB0aGUgbW9kZWxzIG1pc3NpbmcgZGF0YSBhdCB0aGUgZW5kIC8gc3RhcnQgb2YgcnVucyBvciBob3cgdGhleSBzYXZlIGRhdGEgKHNvbWUgdGltZXMgbW9kZWxpbmcgZ3JvdXBzIGNhbiB3cml0ZSBvdXQgbXVsdGlwbGUgZmlsZXMgZm9yIGEgc2luZ2xlIGV4cGVyaW1lbnQgZXZlcnkgNSB5ZWFycyBvciBzbykgYnV0IHRoYXQgd2FzIG5vdCB0aGUgY2FzZSBmZXcgdGhlc2UgbW9kZWxzLiAKCjxicj4KCiMjIyBXaGF0IG1vZGVscyBoYXZlIG91dGxpZXJzIGluIHRoZSByY3AyNj8gCgoKYGBge3J9CmhlYXRfZmx1eCAlPiUKICAgIGZpbHRlcihleHBlcmltZW50ID09ICdyY3AyNicgJiBhYnModmFsdWUpID49IDEwKSAgJT4lICAKICAgIHB1bGwobW9kZWwpICU+JSAgCiAgICB1bmlxdWUoKSAtPiAKICAgIG91dGxpZXJfcmNwMjYKb3V0bGllcl9yY3AyNgpgYGAKCkl0IGxvb2tzIGxpa2UgdGhlIHNhbWUgbW9kZWxzIGhhdmUgb3V0bGluZXMgaW4gcmNwMjYuIAoKPGJyPgoKIyMjIFdoYXQgbW9kZWxzIGhhdmUgb3V0bGllcnMgaW4gcmNwIDg1PyAKCmBgYHtyfQpoZWF0X2ZsdXggJT4lCiAgICBmaWx0ZXIoZXhwZXJpbWVudCA9PSAncmNwODUnICYgdmFsdWUgPiAxMCkgJT4lIAogICAgcHVsbChtb2RlbCkgJT4lIAogICAgdW5pcXVlKCkgLT4gCiAgICBvdXRsaWVyc19yY3A4NTsgCm91dGxpZXJzX3JjcDg1CmBgYAoKCmBgYHtyfQoKaGVhdF9mbHV4ICU+JSAKICAgIGZpbHRlcihleHBlcmltZW50ID09ICdyY3A4NScgJiBtb2RlbCA9PSBvdXRsaWVyc19yY3A4NSkgJT4lICAKICAgIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbG9yICA9IG1vZGVsKSkgKyAKICAgIGdlb21fbGluZShkYXRhID0gaGVhdF9mbHV4ICU+JSAKICAgICAgICAgICAgICAgICAgZmlsdGVyKGV4cGVyaW1lbnQgPT0gJ3JjcDg1JyAmIG1vZGVsICE9IG91dGxpZXJzX3JjcDg1KSwgCiAgICAgICAgICAgICAgYWVzKHllYXIsIHZhbHVlLCBjb2xvciA9ICdvdGhlciBtb2RlbHMnLCBncm91cCA9IGludGVyYWN0aW9uKG1vZGVsLCBlbnNlbWJsZSkpLCBhbHBoYSA9IDAuMykgKyAKICAgIGdlb21fcG9pbnQoKSArIAogICAgbGFicyh5ID0gJ3cvbTInKSArIAogICAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKDIwMDYsIDIxMDApKQpgYGAKCldlbGwgaXQgbG9vcyBsaWtlIGZyb20gMjk5MCB0byAyOTk1IHRoZSBDRVNNMS1CR0MgaGFzIGFibm9ybWFsbHkgaGlnaCBoZWF0IGZsdXggdmFsdWVzIGJ1dCByZWFzb25hYmxlIHZhbHVlcyBmb3IgdGhlIG90aGVyIHllYXJzLiBPbmNlIGFnYWluIHdoYXQgZG8gd2UgZG8gd2hlbiB0aGVyZSBhcmUgb25seSBzb21lIG9mIHRoZSB5ZWFycyB3aXRoIHN1c3BpY2lvdXMgZGF0YT8KCiMjIyBCZWxvdyBFeHBlY3RlZCBUaW1lIFNlcmllcyAKCkJvdGggdGhlIHJjcDQ1IGFuZCByY3A4NSBleHBlcmltZW50cyBoYXZlIHRpbWUgc2VyaWVzIHdpdGggdmFsdWVzIHRoYXQgYXJlIGJlbG93LiAKCmBgYHtyfQpoZWF0X2ZsdXggJT4lIAogICAgZmlsdGVyKGV4cGVyaW1lbnQgJWluJSBjKCdyY3A0NScsICdyY3A4NScpKSAlPiUgCiAgICBmaWx0ZXIodmFsdWUgPCAtMSkgJT4lIAogICAgcHVsbChtb2RlbCkgJT4lICAKICAgIHVuaXF1ZSgpCmBgYAoKU28gaXQgbG9va3MgbGlrZSB0aGUgc2FtZSBtb2RlbCBpcyB0aGUgaGFzIHVuZXhwZWN0ZWRseSBsb3cgaGVhdCBmbHV4IHZhbHVlcy4gSSB3b25kZXIgd2hhdCBjb3VsZCBiZSBjYXVzaW5nIGl0LiBJIGNoZWNrZWQgdGhlIGVycmF0YSAoaHR0cHM6Ly9jbWlwLmxsbmwuZ292L2NtaXA1L2VycmF0YS9jbWlwNWVycmF0YS5odG1sKSB0byBzZWUgaWYgaW5tY200IGhhZCByZXBvcnRlZCBhbnkgcHJvYmxlbXMgd2l0aCB0aGUgZGF0YSB3ZSB1c2VkLiBXaGlsZSBpdCBkaWQgYXBwZWFyIG11bHRpcGxlIHRpbWVzIGluIHRoZSBlcnJhdGEgaXQgd2Fzbid0IGZvciBhbnkgb2YgdGhlIHZhcmlhYmxlcyB3ZSB1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgaGVhdCBmbHV4LgoKIyMgQ29uY2x1ZGluZyBUaG91Z2h0cwoKV2VsbCBpdHMgNTowMCBvbiBhIEZyaWRheSBhbmQgSSBoYXZlIGJyYWluIG11c2ggc28gdGhpcyBsb29rIGF0IG91ciBoZWF0IGZsdXggZGF0YSBoYXMgbm90IGJlZW4gYXMgdGhvcm91Z2ggYXMgSSB3b3VsZCBsaWtlIGl0IHRvIGJlLiBCdXQgaXQgZG9lcyByYWlzZSBzb21lIHF1ZXN0aW9ucyB0byBjb25zaWRlci4gCgoxLiBXaGVuIHRoZXJlIGFyZSBjYXNlcyB3aGVyZSBoZWF0IGZsdXggZm9yIGEgaGFuZGZ1bCBvZiB5ZWFyIGxvb2tzIGZ1bmt5IGRvIHdlIHdhbnQgdG8gcmVtb3ZlIHRoZSBvdXRsaWVyIHllYXJzIG9yIGRpc2NhcmQgdGhlIGVudGlyZSB0aW1lIHNlcmllcz8gCjIuIEZvciBpbm1jbTQgd2hhdCBpcyBnb2luZyBvbj8gSXMgdGhlcmUgYSBwcm9ibGVtIHdpdGggb25lIG9mIHRoZSBuZXRjZGYgZmlsZXMgd2UgdXNlZCBiZWNhdXNlIHRoZSB0cmVuZCBhbmQgc3ByZWFkIGxvb2tzIGdvb2QgdG8gbWUsIGl0IGlzIGFsbW9zdCBsaWtlIHRoZSB0aW1lIHNlcmllcyBoYXMgYmVlbiBvZmYgc2V0IGEgYml0LiAKCgo=