Use daily precpitation time series from DWD, downloaded here: https://opendata.dwd.de/climate_environment/CDC/observations_germany/climate/daily/more_precip/historical/

Chose station No 6305 Mühlhausen/Thüringen-Görmar

filename_mhlsn = "tageswerte_RR_06305_20041201_20221231_hist/produkt_nieder_tag_20041201_20221231_06305.txt" # Mühlhausen - nearest dwd precip station
There were 50 or more warnings (use warnings() to see the first 50)
data=read.csv(filename_mhlsn, header = TRUE, sep=";" )

Check which period is covered, whether years are complete

data$date <- as.Date(as.character(data$MESS_DATUM),format='%Y%m%d')
years <- as.numeric(unique(format(data$date,'%Y')))


data$year <- as.numeric(format(data$date,'%Y'))

(days_per_year <- rle(data$year))
Run Length Encoding
  lengths: int [1:19] 31 365 365 365 366 365 365 365 366 365 ...
  values : num [1:19] 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 ...

One year is incomplete, start with the first complete year, whcih is 2005

years <- years[-1]
nyears = length(years)

remove Feb 29

ind_feb29<-which(as.character(data$date,'%d%m') == c("2902"))
data<-data[-ind_feb29,]

Basic features of the rainfall dataset

Check whether the distribution of rainfall changed between

I chose two intervals of equal size, therefore not covereing the period before 2014.

There were 14 warnings (use warnings() to see them)
maxP = max(data$RS)

data_2014_2017 <- data[which(data$year>=2014 & data$year<=2017),] 
data_2018_2021 <- data[which(data$year>=2018 & data$year<=2021),] 

bins <- c(0:ceiling(maxP))

h.p_daily.2014_2017 <- hist(data_2014_2017$RS, breaks = bins, plot = FALSE)
h.p_daily.2018_2021 <- hist(data_2018_2021$RS, breaks = bins, plot = FALSE)

plot(h.p_daily.2014_2017$mids, log(h.p_daily.2014_2017$density), 
     xlab = "Daily precipitation in mm/d",
     ylab = "log(occurence frequency")
points(h.p_daily.2018_2021$mids, log(h.p_daily.2018_2021$density), pch = 19)
legend(x = "topright",          # Position
       legend = c("2014-2017", "2018-2021"),  # Legend texts
       pch = c(1, 19))           # point types

It is hard to judge. There is a tendency of smaller events being smaller in 2018-2021 compared to the period 2014-2017. Another look at this allows the QQplot.

q.p_daily.2014_2017 <- quantile(data_2014_2017$RS, seq(0.025,1,0.025))
q.p_daily.2018_2021 <- quantile(data_2018_2021$RS, seq(0.025,1,0.025))

plot(q.p_daily.2014_2017, q.p_daily.2018_2021, 
     xlab = "Quantiles of daily precipitation 2014-2017",
     ylab = "Quantiles of daily precipitation 2018-2021")
abline(a=0, b=1, ':')
NAs introduced by coercion

And zoom in a bit on the small numbers by plotting log(quantile) instead of the quantiles.

plot(log(q.p_daily.2014_2017+1), log(q.p_daily.2018_2021+1), 
     xlab = "log(quantiles of daily precipitation 2014-2017)",
     ylab = "log(quantiles of daily precipitation 2018-2021)")
abline(a=0, b=1, ':')
NAs introduced by coercion

It looks like the small events were less common, but the larger increasingly more common in the later period (2018-2021) compared to the first period (2014-2017). It is a small shift.

Number of days with given rainfall

Check whether certain types of daily precipitation were more or less common along the time series. For this I use the entire time series, to be able to see trends (if applicable).

I will test for

Looking for extreme rainfall requires a dataset in hourly or six hourly resolution, and cannot be done using this daily dataset. But the data is available from DWD.

# intialize
ndays = array(data=NA,dim = nyears, dimnames = NULL)
noraindays = array(data=NA,dim = nyears, dimnames = NULL)
strongraindays = array(data=NA,dim = nyears, dimnames = NULL)
P = array(data=NA,dim = nyears, dimnames = NULL)
P_strong = array(data=NA,dim = nyears, dimnames = NULL)
snowdays= array(data=NA,dim = nyears, dimnames = NULL)
P_snow <- array(data=NA,dim = nyears, dimnames = NULL)

P_thresh = 5

#i=1
for (i in 1:nyears) {
data_yr = subset(data, format(data$date,'%Y') == as.character(years[i]))
noraindays[i] = length(which(data_yr$RS<0.1))
raindays = nrow(data_yr)-noraindays
strongraindays[i] = length(which(data_yr$RS>P_thresh ))
P[i] <- sum(data_yr$RS)
P_strong[i] <- sum(data_yr$RS[which(data_yr$RS>P_thresh )])
ndays[i] = nrow(data_yr)

snowdays[i] <-  length(which(data_yr$RSF==7))
P_snow[i] <- sum(data_yr$RS[which(data_yr$RSF==7 )])

}

Annual precipitation time series


par(mfrow=c(1,3))
plot(years, P,
     ylab = "annual precpitation in mm/a",
     main = "all days")

plot(years, P-P_strong,
     ylab = "annual precpitation < 5 mm in mm/a",
     main = "small precipitation")

plot(years, P_strong,
     ylab = "annual precpitation > 5mm in mm/a",
     main = "precipitation > 5 mm/d")

lm.p_yr <-lm(P~years) # all years
summary(lm.p_yr)

Call:
lm(formula = P ~ years)

Residuals:
     Min       1Q   Median       3Q      Max 
-137.282  -59.227   -8.633   49.602  154.279 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)
(Intercept) 7978.097   7391.305   1.079    0.296
years         -3.713      3.671  -1.011    0.327

Residual standard error: 80.8 on 16 degrees of freedom
Multiple R-squared:  0.06009,   Adjusted R-squared:  0.001346 
F-statistic: 1.023 on 1 and 16 DF,  p-value: 0.3269
yrs_2014_2021 = c(10:17)

lm.p_yr.2014_2021 <-lm(P[yrs_2014_2021]~years[yrs_2014_2021]) # 2014-2021 only
summary(lm.p_yr.2014_2021)

Call:
lm(formula = P[yrs_2014_2021] ~ years[yrs_2014_2021])

Residuals:
     Min       1Q   Median       3Q      Max 
-133.244  -27.769    5.306   32.660  122.169 

Coefficients:
                       Estimate Std. Error t value Pr(>|t|)
(Intercept)           -755.3821 24724.7872  -0.031    0.977
years[yrs_2014_2021]     0.6131    12.2552   0.050    0.962

Residual standard error: 79.42 on 6 degrees of freedom
Multiple R-squared:  0.000417,  Adjusted R-squared:  -0.1662 
F-statistic: 0.002503 on 1 and 6 DF,  p-value: 0.9617

No obvious temporal trend in annual precipitation.

P_weak <- P-P_strong
lm.p_weak_yr <-lm(P_weak~years) # all years
summary(lm.p_weak_yr)

Call:
lm(formula = P_weak ~ years)

Residuals:
    Min      1Q  Median      3Q     Max 
-33.982 -15.370  -3.298  12.281  38.070 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)  
(Intercept) 5295.065   2028.562   2.610   0.0189 *
years         -2.535      1.007  -2.516   0.0229 *
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 22.18 on 16 degrees of freedom
Multiple R-squared:  0.2835,    Adjusted R-squared:  0.2387 
F-statistic:  6.33 on 1 and 16 DF,  p-value: 0.02293
yrs_2014_2018 = c(10:17)

lm.pw_eak_yr.2014_2021 <-lm(P_weak[yrs_2014_2021]~years[yrs_2014_2021]) # 2014-2021 only
summary(lm.pw_eak_yr.2014_2021)

Call:
lm(formula = P_weak[yrs_2014_2021] ~ years[yrs_2014_2021])

Residuals:
    Min      1Q  Median      3Q     Max 
-33.168 -15.161  -8.182  17.986  35.904 

Coefficients:
                     Estimate Std. Error t value Pr(>|t|)
(Intercept)          4647.496   8238.362   0.564    0.593
years[yrs_2014_2021]   -2.214      4.083  -0.542    0.607

Residual standard error: 26.46 on 6 degrees of freedom
Multiple R-squared:  0.04672,   Adjusted R-squared:  -0.1122 
F-statistic: 0.294 on 1 and 6 DF,  p-value: 0.6072

Decrease of low intensity precipitation (P<5 mm/d) part of annual precipitation over the entire period, but not significant over the shorter period.

lm.p_strong_yr <-lm(P_strong~years) # all years
summary(lm.p_strong_yr)

Call:
lm(formula = P_strong ~ years)

Residuals:
     Min       1Q   Median       3Q      Max 
-128.579  -50.189    2.456   32.223  147.444 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)
(Intercept) 2683.033   7128.398   0.376    0.712
years         -1.178      3.540  -0.333    0.744

Residual standard error: 77.93 on 16 degrees of freedom
Multiple R-squared:  0.006871,  Adjusted R-squared:  -0.0552 
F-statistic: 0.1107 on 1 and 16 DF,  p-value: 0.7437
yrs_2014_2018 = c(10:17)

lm.p_strong_yr.2014_2021 <-lm(P_strong[yrs_2014_2021]~years[yrs_2014_2021]) # 2014-2021 only
summary(lm.p_strong_yr.2014_2021)

Call:
lm(formula = P_strong[yrs_2014_2021] ~ years[yrs_2014_2021])

Residuals:
     Min       1Q   Median       3Q      Max 
-100.076  -34.065    3.583   30.440   90.651 

Coefficients:
                      Estimate Std. Error t value Pr(>|t|)
(Intercept)          -5402.879  19812.165  -0.273    0.794
years[yrs_2014_2021]     2.827      9.820   0.288    0.783

Residual standard error: 63.64 on 6 degrees of freedom
Multiple R-squared:  0.01363,   Adjusted R-squared:  -0.1508 
F-statistic: 0.0829 on 1 and 6 DF,  p-value: 0.7831

No trend in strong precipitation.

plot(years, P_strong/P)

plot(years, strongraindays/raindays)

Days per year without precipitation.

plot(years, noraindays)

lm.norain <- lm(noraindays~years) # all years
summary(lm.norain)

Call:
lm(formula = noraindays ~ years)

Residuals:
     Min       1Q   Median       3Q      Max 
-16.4585  -9.8265  -0.5272   6.0900  24.8191 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)  
(Intercept) -2543.7148  1156.9145  -2.199   0.0430 *
years           1.3612     0.5746   2.369   0.0308 *
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 12.65 on 16 degrees of freedom
Multiple R-squared:  0.2597,    Adjusted R-squared:  0.2134 
F-statistic: 5.612 on 1 and 16 DF,  p-value: 0.03075
lm.norain.2014_2021 <- lm(noraindays[yrs_2014_2018]~years[yrs_2014_2018]) # all years
summary(lm.norain.2014_2021)

Call:
lm(formula = noraindays[yrs_2014_2018] ~ years[yrs_2014_2018])

Residuals:
     Min       1Q   Median       3Q      Max 
-15.3333  -8.6786  -0.7143   3.0357  26.9524 

Coefficients:
                      Estimate Std. Error t value Pr(>|t|)
(Intercept)          -6045.143   4394.505  -1.376    0.218
years[yrs_2014_2018]     3.095      2.178   1.421    0.205

Residual standard error: 14.12 on 6 degrees of freedom
Multiple R-squared:  0.2518,    Adjusted R-squared:  0.1271 
F-statistic: 2.019 on 1 and 6 DF,  p-value: 0.2051

There is an increase of rainfree days between 2005 and 2022, but not statistically significant when zooming in to the shorter period of interest 2014-2021.

Days with some rain

weakraindays = raindays - strongraindays
plot(years, weakraindays)

lm.weakrain <- lm(weakraindays~years)
summary(lm.weakrain)

Call:
lm(formula = weakraindays ~ years)

Residuals:
    Min      1Q  Median      3Q     Max 
-14.907  -7.157  -3.376   8.296  18.385 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)   
(Intercept) 2863.2250   957.7131   2.990  0.00866 **
years         -1.3540     0.4756  -2.847  0.01166 * 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 10.47 on 16 degrees of freedom
Multiple R-squared:  0.3362,    Adjusted R-squared:  0.2947 
F-statistic: 8.103 on 1 and 16 DF,  p-value: 0.01166
lm.weakrain.2014_2021 <- lm(weakraindays[yrs_2014_2018]~years[yrs_2014_2018])
summary(lm.weakrain.2014_2021)

Call:
lm(formula = weakraindays[yrs_2014_2018] ~ years[yrs_2014_2018])

Residuals:
     Min       1Q   Median       3Q      Max 
-17.7143  -3.0982   0.9464   4.3036  11.6429 

Coefficients:
                     Estimate Std. Error t value Pr(>|t|)  
(Intercept)          6836.357   3135.137   2.181   0.0720 .
years[yrs_2014_2018]   -3.321      1.554  -2.137   0.0764 .
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 10.07 on 6 degrees of freedom
Multiple R-squared:  0.4323,    Adjusted R-squared:  0.3376 
F-statistic: 4.568 on 1 and 6 DF,  p-value: 0.07643

The number of days with weak rain decreases both over the long period and still a trend remains over the short period.

Substantial rain

plot(years, strongraindays)

lm.strongrain <- lm(strongraindays~years)
summary(lm.strongrain)

Call:
lm(formula = strongraindays ~ years)

Residuals:
    Min      1Q  Median      3Q     Max 
-9.9842 -4.7378 -0.8939  5.0718 12.0230 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)
(Intercept)  45.489852 636.611373   0.071    0.944
years        -0.007224   0.316170  -0.023    0.982

Residual standard error: 6.959 on 16 degrees of freedom
Multiple R-squared:  3.263e-05, Adjusted R-squared:  -0.06247 
F-statistic: 0.000522 on 1 and 16 DF,  p-value: 0.9821

The number of days with substantial precipitation did not change over the years. Note that this is not necessarily saying much, because strong rain can mean anything between 5 mm - 45 mm rainfall per day.

Note however, that the annual precipitation depends a great deal on how many days it rained above 5 mm/day and is also strongly determined by the total precpitation received during those days:

par(mfrow=c(1,2))
plot(P, P_strong/P ,
     xlab = "annual precipitation in mm/a",
     ylab = "total P on days P>5mm / total P")
plot(P,strongraindays/raindays,
     xlab = "annual precipitation in mm/a",
     ylab = "no of days with P>5mm / no precipitation days")

Only 12-24% of the precipitation days have precipitation > 5 mm, but they are responsible for 45 to 70% of the annual precipitation. If they are single events, they also roughly correspond to the event size required to yield any soil moisture response (see Fischer et al. 2023, in print in HESS). Their frequency does not change.

We can use the relation above to calculate the expected strong precipitation each year based on the annual precipitation. This allows a more focussed look on how the strong precipitation changes:

There were 12 warnings (use warnings() to see them)
lm.Pstrong_P <- lm(P_strong~P) # Relation between total annual precipitation and strong events
summary(lm.Pstrong_P)

Call:
lm(formula = P_strong ~ P)

Residuals:
    Min      1Q  Median      3Q     Max 
-59.669 -16.413   3.817  19.657  30.012 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) -136.37471   37.48263  -3.638  0.00221 ** 
P              0.89074    0.07368  12.089 1.85e-09 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 24.56 on 16 degrees of freedom
Multiple R-squared:  0.9013,    Adjusted R-squared:  0.8951 
F-statistic: 146.1 on 1 and 16 DF,  p-value: 1.849e-09
# predict contribution of strong events from annual precipitation as a baseline.
P_strong_lm <- predict(lm.Pstrong_P) # this is the expected contribution of strong events to total P

d.pred.P_strog <- P_strong-P_strong_lm # prediction error of contribution of strong precip days

# check whether there is a trend in over/underprediction
plot(years, d.pred.P_strog,
     ylab = "observed-predicted")

lm.pred_trend <- lm(d.pred.P_strog ~ years)
summary(lm.pred_trend)

Call:
lm(formula = d.pred.P_strog ~ years)

Residuals:
    Min      1Q  Median      3Q     Max 
-47.959 -12.293   4.658  17.718  25.987 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)  
(Intercept) -4286.9821  1974.9825  -2.171   0.0454 *
years           2.1291     0.9809   2.171   0.0454 *
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 21.59 on 16 degrees of freedom
Multiple R-squared:  0.2275,    Adjusted R-squared:  0.1792 
F-statistic: 4.712 on 1 and 16 DF,  p-value: 0.04535
lm.pred_trend.2014_2021 <- lm(d.pred.P_strog[yrs_2014_2021] ~ years[yrs_2014_2021])
summary(lm.pred_trend.2014_2021)

Call:
lm(formula = d.pred.P_strog[yrs_2014_2021] ~ years[yrs_2014_2021])

Residuals:
    Min      1Q  Median      3Q     Max 
-35.600 -11.517   4.437  16.273  20.091 

Coefficients:
                      Estimate Std. Error t value Pr(>|t|)
(Intercept)          -4593.657   6621.710  -0.694    0.514
years[yrs_2014_2021]     2.281      3.282   0.695    0.513

Residual standard error: 21.27 on 6 degrees of freedom
Multiple R-squared:  0.07452,   Adjusted R-squared:  -0.07973 
F-statistic: 0.4831 on 1 and 6 DF,  p-value: 0.513

There is a relation in the prediction error with time. In other words: The contribution of large rainfall events to total rainfall in recent years is higher than expected based on the entire sample (2005-2022). This relation is not at all obvious for the shorter period 2014-2021.

LS0tCnRpdGxlOiAiUHJlY2lwaXRhdGlvbiBhbmFseXNpcyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKClVzZSBkYWlseSBwcmVjcGl0YXRpb24gdGltZSBzZXJpZXMgZnJvbSBEV0QsIGRvd25sb2FkZWQgaGVyZToKaHR0cHM6Ly9vcGVuZGF0YS5kd2QuZGUvY2xpbWF0ZV9lbnZpcm9ubWVudC9DREMvb2JzZXJ2YXRpb25zX2dlcm1hbnkvY2xpbWF0ZS9kYWlseS9tb3JlX3ByZWNpcC9oaXN0b3JpY2FsLwoKQ2hvc2Ugc3RhdGlvbiBObyA2MzA1IE3DvGhsaGF1c2VuL1Row7xyaW5nZW4tR8O2cm1hcgoKYGBge3J9CmZpbGVuYW1lX21obHNuID0gInRhZ2Vzd2VydGVfUlJfMDYzMDVfMjAwNDEyMDFfMjAyMjEyMzFfaGlzdC9wcm9kdWt0X25pZWRlcl90YWdfMjAwNDEyMDFfMjAyMjEyMzFfMDYzMDUudHh0IiAjIE3DvGhsaGF1c2VuIC0gbmVhcmVzdCBkd2QgcHJlY2lwIHN0YXRpb24KZGF0YT1yZWFkLmNzdihmaWxlbmFtZV9taGxzbiwgaGVhZGVyID0gVFJVRSwgc2VwPSI7IiApCmBgYAoKQ2hlY2sgd2hpY2ggcGVyaW9kIGlzIGNvdmVyZWQsIHdoZXRoZXIgeWVhcnMgYXJlIGNvbXBsZXRlCgpgYGB7cn0KZGF0YSRkYXRlIDwtIGFzLkRhdGUoYXMuY2hhcmFjdGVyKGRhdGEkTUVTU19EQVRVTSksZm9ybWF0PSclWSVtJWQnKQp5ZWFycyA8LSBhcy5udW1lcmljKHVuaXF1ZShmb3JtYXQoZGF0YSRkYXRlLCclWScpKSkKCgpkYXRhJHllYXIgPC0gYXMubnVtZXJpYyhmb3JtYXQoZGF0YSRkYXRlLCclWScpKQoKKGRheXNfcGVyX3llYXIgPC0gcmxlKGRhdGEkeWVhcikpCgpgYGAKCgpPbmUgeWVhciBpcyBpbmNvbXBsZXRlLCBzdGFydCB3aXRoIHRoZSBmaXJzdCBjb21wbGV0ZSB5ZWFyLCB3aGNpaCBpcyAyMDA1CgpgYGB7cn0KeWVhcnMgPC0geWVhcnNbLTFdCm55ZWFycyA9IGxlbmd0aCh5ZWFycykKYGBgCgpyZW1vdmUgRmViIDI5CgpgYGB7cn0KaW5kX2ZlYjI5PC13aGljaChhcy5jaGFyYWN0ZXIoZGF0YSRkYXRlLCclZCVtJykgPT0gYygiMjkwMiIpKQpkYXRhPC1kYXRhWy1pbmRfZmViMjksXQpgYGAKCiMjIEJhc2ljIGZlYXR1cmVzIG9mIHRoZSByYWluZmFsbCBkYXRhc2V0CgpDaGVjayB3aGV0aGVyIHRoZSBkaXN0cmlidXRpb24gb2YgcmFpbmZhbGwgY2hhbmdlZCBiZXR3ZWVuIAoKKiAyMDE0LTIwMTcgYW5kIAoKKiAyMDE4LTIwMjEuIAoKSSBjaG9zZSB0d28gaW50ZXJ2YWxzIG9mIGVxdWFsIHNpemUsIHRoZXJlZm9yZSBub3QgY292ZXJlaW5nIHRoZSBwZXJpb2QgYmVmb3JlIDIwMTQuCgpgYGB7cn0KCm1heFAgPSBtYXgoZGF0YSRSUykKCmRhdGFfMjAxNF8yMDE3IDwtIGRhdGFbd2hpY2goZGF0YSR5ZWFyPj0yMDE0ICYgZGF0YSR5ZWFyPD0yMDE3KSxdIApkYXRhXzIwMThfMjAyMSA8LSBkYXRhW3doaWNoKGRhdGEkeWVhcj49MjAxOCAmIGRhdGEkeWVhcjw9MjAyMSksXSAKCmJpbnMgPC0gYygwOmNlaWxpbmcobWF4UCkpCgpoLnBfZGFpbHkuMjAxNF8yMDE3IDwtIGhpc3QoZGF0YV8yMDE0XzIwMTckUlMsIGJyZWFrcyA9IGJpbnMsIHBsb3QgPSBGQUxTRSkKaC5wX2RhaWx5LjIwMThfMjAyMSA8LSBoaXN0KGRhdGFfMjAxOF8yMDIxJFJTLCBicmVha3MgPSBiaW5zLCBwbG90ID0gRkFMU0UpCgpwbG90KGgucF9kYWlseS4yMDE0XzIwMTckbWlkcywgbG9nKGgucF9kYWlseS4yMDE0XzIwMTckZGVuc2l0eSksIAogICAgIHhsYWIgPSAiRGFpbHkgcHJlY2lwaXRhdGlvbiBpbiBtbS9kIiwKICAgICB5bGFiID0gImxvZyhvY2N1cmVuY2UgZnJlcXVlbmN5IikKcG9pbnRzKGgucF9kYWlseS4yMDE4XzIwMjEkbWlkcywgbG9nKGgucF9kYWlseS4yMDE4XzIwMjEkZGVuc2l0eSksIHBjaCA9IDE5KQpsZWdlbmQoeCA9ICJ0b3ByaWdodCIsICAgICAgICAgICMgUG9zaXRpb24KICAgICAgIGxlZ2VuZCA9IGMoIjIwMTQtMjAxNyIsICIyMDE4LTIwMjEiKSwgICMgTGVnZW5kIHRleHRzCiAgICAgICBwY2ggPSBjKDEsIDE5KSkgICAgICAgICAgICMgcG9pbnQgdHlwZXMKYGBgCgpJdCBpcyBoYXJkIHRvIGp1ZGdlLiBUaGVyZSBpcyBhIHRlbmRlbmN5IG9mIHNtYWxsZXIgZXZlbnRzIGJlaW5nIHNtYWxsZXIgaW4gMjAxOC0yMDIxIGNvbXBhcmVkIHRvIHRoZSBwZXJpb2QgMjAxNC0yMDE3LiBBbm90aGVyIGxvb2sgYXQgdGhpcyBhbGxvd3MgdGhlIFFRcGxvdC4KCmBgYHtyfQpxLnBfZGFpbHkuMjAxNF8yMDE3IDwtIHF1YW50aWxlKGRhdGFfMjAxNF8yMDE3JFJTLCBzZXEoMC4wMjUsMSwwLjAyNSkpCnEucF9kYWlseS4yMDE4XzIwMjEgPC0gcXVhbnRpbGUoZGF0YV8yMDE4XzIwMjEkUlMsIHNlcSgwLjAyNSwxLDAuMDI1KSkKCnBsb3QocS5wX2RhaWx5LjIwMTRfMjAxNywgcS5wX2RhaWx5LjIwMThfMjAyMSwgCiAgICAgeGxhYiA9ICJRdWFudGlsZXMgb2YgZGFpbHkgcHJlY2lwaXRhdGlvbiAyMDE0LTIwMTciLAogICAgIHlsYWIgPSAiUXVhbnRpbGVzIG9mIGRhaWx5IHByZWNpcGl0YXRpb24gMjAxOC0yMDIxIikKYWJsaW5lKGE9MCwgYj0xLCAnOicpCgpgYGAKCkFuZCB6b29tIGluIGEgYml0IG9uIHRoZSBzbWFsbCBudW1iZXJzIGJ5IHBsb3R0aW5nIGxvZyhxdWFudGlsZSkgaW5zdGVhZCBvZiB0aGUgcXVhbnRpbGVzLgoKYGBge3J9CnBsb3QobG9nKHEucF9kYWlseS4yMDE0XzIwMTcrMSksIGxvZyhxLnBfZGFpbHkuMjAxOF8yMDIxKzEpLCAKICAgICB4bGFiID0gImxvZyhxdWFudGlsZXMgb2YgZGFpbHkgcHJlY2lwaXRhdGlvbiAyMDE0LTIwMTcpIiwKICAgICB5bGFiID0gImxvZyhxdWFudGlsZXMgb2YgZGFpbHkgcHJlY2lwaXRhdGlvbiAyMDE4LTIwMjEpIikKYWJsaW5lKGE9MCwgYj0xLCAnOicpCmBgYAoKSXQgbG9va3MgbGlrZSB0aGUgc21hbGwgZXZlbnRzIHdlcmUgbGVzcyBjb21tb24sIGJ1dCB0aGUgbGFyZ2VyIGluY3JlYXNpbmdseSBtb3JlIGNvbW1vbiBpbiB0aGUgbGF0ZXIgcGVyaW9kICgyMDE4LTIwMjEpIGNvbXBhcmVkIHRvIHRoZSBmaXJzdCBwZXJpb2QgKDIwMTQtMjAxNykuIEl0IGlzIGEgc21hbGwgc2hpZnQuCgojIyBOdW1iZXIgb2YgZGF5cyB3aXRoIGdpdmVuIHJhaW5mYWxsCgpDaGVjayB3aGV0aGVyIGNlcnRhaW4gdHlwZXMgb2YgZGFpbHkgcHJlY2lwaXRhdGlvbiB3ZXJlIG1vcmUgb3IgbGVzcyBjb21tb24gYWxvbmcgdGhlIHRpbWUgc2VyaWVzLiBGb3IgdGhpcyBJIHVzZSB0aGUgZW50aXJlIHRpbWUgc2VyaWVzLCB0byBiZSBhYmxlIHRvIHNlZSB0cmVuZHMgKGlmIGFwcGxpY2FibGUpLgoKSSB3aWxsIHRlc3QgZm9yCgotIG51bWJlciBvZiBkYXlzIHBlciB5ZWFyIHdpdGhvdXQgcHJlY2lwaXRhdGlvbiAodGhyZXNob2xkIDAuMSBtbSkKCi0gZGF5cyBzdXJwYXNzaW5nIHNtYWxsIHByZWNpcGl0YXRpb24gKHRocmVzaG9sZCBzZXQgdG8gNSBtbSkKCkxvb2tpbmcgZm9yIGV4dHJlbWUgcmFpbmZhbGwgcmVxdWlyZXMgYSBkYXRhc2V0IGluIGhvdXJseSBvciBzaXggaG91cmx5IHJlc29sdXRpb24sIGFuZCBjYW5ub3QgYmUgZG9uZSB1c2luZyB0aGlzIGRhaWx5IGRhdGFzZXQuIEJ1dCB0aGUgZGF0YSBpcyBhdmFpbGFibGUgZnJvbSBEV0QuCgpgYGB7cn0KIyBpbnRpYWxpemUKbmRheXMgPSBhcnJheShkYXRhPU5BLGRpbSA9IG55ZWFycywgZGltbmFtZXMgPSBOVUxMKQpub3JhaW5kYXlzID0gYXJyYXkoZGF0YT1OQSxkaW0gPSBueWVhcnMsIGRpbW5hbWVzID0gTlVMTCkKc3Ryb25ncmFpbmRheXMgPSBhcnJheShkYXRhPU5BLGRpbSA9IG55ZWFycywgZGltbmFtZXMgPSBOVUxMKQpQID0gYXJyYXkoZGF0YT1OQSxkaW0gPSBueWVhcnMsIGRpbW5hbWVzID0gTlVMTCkKUF9zdHJvbmcgPSBhcnJheShkYXRhPU5BLGRpbSA9IG55ZWFycywgZGltbmFtZXMgPSBOVUxMKQpzbm93ZGF5cz0gYXJyYXkoZGF0YT1OQSxkaW0gPSBueWVhcnMsIGRpbW5hbWVzID0gTlVMTCkKUF9zbm93IDwtIGFycmF5KGRhdGE9TkEsZGltID0gbnllYXJzLCBkaW1uYW1lcyA9IE5VTEwpCgpQX3RocmVzaCA9IDUKCiNpPTEKZm9yIChpIGluIDE6bnllYXJzKSB7CmRhdGFfeXIgPSBzdWJzZXQoZGF0YSwgZm9ybWF0KGRhdGEkZGF0ZSwnJVknKSA9PSBhcy5jaGFyYWN0ZXIoeWVhcnNbaV0pKQpub3JhaW5kYXlzW2ldID0gbGVuZ3RoKHdoaWNoKGRhdGFfeXIkUlM8MC4xKSkKcmFpbmRheXMgPSBucm93KGRhdGFfeXIpLW5vcmFpbmRheXMKc3Ryb25ncmFpbmRheXNbaV0gPSBsZW5ndGgod2hpY2goZGF0YV95ciRSUz5QX3RocmVzaCApKQpQW2ldIDwtIHN1bShkYXRhX3lyJFJTKQpQX3N0cm9uZ1tpXSA8LSBzdW0oZGF0YV95ciRSU1t3aGljaChkYXRhX3lyJFJTPlBfdGhyZXNoICldKQpuZGF5c1tpXSA9IG5yb3coZGF0YV95cikKCnNub3dkYXlzW2ldIDwtICBsZW5ndGgod2hpY2goZGF0YV95ciRSU0Y9PTcpKQpQX3Nub3dbaV0gPC0gc3VtKGRhdGFfeXIkUlNbd2hpY2goZGF0YV95ciRSU0Y9PTcgKV0pCgp9CgpgYGAKCiMjIyMgQW5udWFsIHByZWNpcGl0YXRpb24gdGltZSBzZXJpZXMKYGBge3J9CgpwYXIobWZyb3c9YygxLDMpKQpwbG90KHllYXJzLCBQLAogICAgIHlsYWIgPSAiYW5udWFsIHByZWNwaXRhdGlvbiBpbiBtbS9hIiwKICAgICBtYWluID0gImFsbCBkYXlzIikKCnBsb3QoeWVhcnMsIFAtUF9zdHJvbmcsCiAgICAgeWxhYiA9ICJhbm51YWwgcHJlY3BpdGF0aW9uIDwgNSBtbSBpbiBtbS9hIiwKICAgICBtYWluID0gInNtYWxsIHByZWNpcGl0YXRpb24iKQoKcGxvdCh5ZWFycywgUF9zdHJvbmcsCiAgICAgeWxhYiA9ICJhbm51YWwgcHJlY3BpdGF0aW9uID4gNW1tIGluIG1tL2EiLAogICAgIG1haW4gPSAicHJlY2lwaXRhdGlvbiA+IDUgbW0vZCIpCgpgYGAKCmBgYHtyfQpsbS5wX3lyIDwtbG0oUH55ZWFycykgIyBhbGwgeWVhcnMKc3VtbWFyeShsbS5wX3lyKQoKeXJzXzIwMTRfMjAyMSA9IGMoMTA6MTcpCgpsbS5wX3lyLjIwMTRfMjAyMSA8LWxtKFBbeXJzXzIwMTRfMjAyMV1+eWVhcnNbeXJzXzIwMTRfMjAyMV0pICMgMjAxNC0yMDIxIG9ubHkKc3VtbWFyeShsbS5wX3lyLjIwMTRfMjAyMSkKCmBgYApObyBvYnZpb3VzIHRlbXBvcmFsIHRyZW5kIGluIGFubnVhbCBwcmVjaXBpdGF0aW9uLgoKYGBge3J9ClBfd2VhayA8LSBQLVBfc3Ryb25nCmxtLnBfd2Vha195ciA8LWxtKFBfd2Vha355ZWFycykgIyBhbGwgeWVhcnMKc3VtbWFyeShsbS5wX3dlYWtfeXIpCgp5cnNfMjAxNF8yMDE4ID0gYygxMDoxNykKCmxtLnB3X2Vha195ci4yMDE0XzIwMjEgPC1sbShQX3dlYWtbeXJzXzIwMTRfMjAyMV1+eWVhcnNbeXJzXzIwMTRfMjAyMV0pICMgMjAxNC0yMDIxIG9ubHkKc3VtbWFyeShsbS5wd19lYWtfeXIuMjAxNF8yMDIxKQoKYGBgCkRlY3JlYXNlIG9mIGxvdyBpbnRlbnNpdHkgcHJlY2lwaXRhdGlvbiAoUDw1IG1tL2QpIHBhcnQgb2YgYW5udWFsIHByZWNpcGl0YXRpb24gb3ZlciB0aGUgZW50aXJlIHBlcmlvZCwgYnV0IG5vdCBzaWduaWZpY2FudCBvdmVyIHRoZSBzaG9ydGVyIHBlcmlvZC4KCmBgYHtyfQpsbS5wX3N0cm9uZ195ciA8LWxtKFBfc3Ryb25nfnllYXJzKSAjIGFsbCB5ZWFycwpzdW1tYXJ5KGxtLnBfc3Ryb25nX3lyKQoKeXJzXzIwMTRfMjAxOCA9IGMoMTA6MTcpCgpsbS5wX3N0cm9uZ195ci4yMDE0XzIwMjEgPC1sbShQX3N0cm9uZ1t5cnNfMjAxNF8yMDIxXX55ZWFyc1t5cnNfMjAxNF8yMDIxXSkgIyAyMDE0LTIwMjEgb25seQpzdW1tYXJ5KGxtLnBfc3Ryb25nX3lyLjIwMTRfMjAyMSkKYGBgCk5vIHRyZW5kIGluIHN0cm9uZyBwcmVjaXBpdGF0aW9uLgoKCmBgYHtyfQpwbG90KHllYXJzLCBQX3N0cm9uZy9QKQpwbG90KHllYXJzLCBzdHJvbmdyYWluZGF5cy9yYWluZGF5cykKCmBgYAoKCgojIyMjIERheXMgcGVyIHllYXIgd2l0aG91dCBwcmVjaXBpdGF0aW9uLiAKCmBgYHtyfQpwbG90KHllYXJzLCBub3JhaW5kYXlzKQpsbS5ub3JhaW4gPC0gbG0obm9yYWluZGF5c355ZWFycykgIyBhbGwgeWVhcnMKc3VtbWFyeShsbS5ub3JhaW4pCgpsbS5ub3JhaW4uMjAxNF8yMDIxIDwtIGxtKG5vcmFpbmRheXNbeXJzXzIwMTRfMjAxOF1+eWVhcnNbeXJzXzIwMTRfMjAxOF0pICMgYWxsIHllYXJzCnN1bW1hcnkobG0ubm9yYWluLjIwMTRfMjAyMSkKYGBgCgpUaGVyZSBpcyBhbiBpbmNyZWFzZSBvZiByYWluZnJlZSBkYXlzIGJldHdlZW4gMjAwNSBhbmQgMjAyMiwgYnV0IG5vdCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IHdoZW4gem9vbWluZyBpbiB0byB0aGUgc2hvcnRlciBwZXJpb2Qgb2YgaW50ZXJlc3QgMjAxNC0yMDIxLgoKIyMjIyBEYXlzIHdpdGggc29tZSByYWluCgpgYGB7cn0Kd2Vha3JhaW5kYXlzID0gcmFpbmRheXMgLSBzdHJvbmdyYWluZGF5cwpwbG90KHllYXJzLCB3ZWFrcmFpbmRheXMpCmxtLndlYWtyYWluIDwtIGxtKHdlYWtyYWluZGF5c355ZWFycykKc3VtbWFyeShsbS53ZWFrcmFpbikKYGBgCgpgYGB7cn0KbG0ud2Vha3JhaW4uMjAxNF8yMDIxIDwtIGxtKHdlYWtyYWluZGF5c1t5cnNfMjAxNF8yMDE4XX55ZWFyc1t5cnNfMjAxNF8yMDE4XSkKc3VtbWFyeShsbS53ZWFrcmFpbi4yMDE0XzIwMjEpCmBgYApUaGUgbnVtYmVyIG9mIGRheXMgd2l0aCAqKndlYWsgcmFpbioqIGRlY3JlYXNlcyBib3RoIG92ZXIgdGhlIGxvbmcgcGVyaW9kIGFuZCBzdGlsbCBhIHRyZW5kIHJlbWFpbnMgb3ZlciB0aGUgc2hvcnQgcGVyaW9kLgoKIyMjIyBTdWJzdGFudGlhbCByYWluCgpgYGB7cn0KcGxvdCh5ZWFycywgc3Ryb25ncmFpbmRheXMpCmxtLnN0cm9uZ3JhaW4gPC0gbG0oc3Ryb25ncmFpbmRheXN+eWVhcnMpCnN1bW1hcnkobG0uc3Ryb25ncmFpbikKCmBgYApUaGUgbnVtYmVyIG9mIGRheXMgd2l0aCBzdWJzdGFudGlhbCBwcmVjaXBpdGF0aW9uIGRpZCBub3QgY2hhbmdlIG92ZXIgdGhlIHllYXJzLiBOb3RlIHRoYXQgdGhpcyBpcyBub3QgbmVjZXNzYXJpbHkgc2F5aW5nIG11Y2gsIGJlY2F1c2Ugc3Ryb25nIHJhaW4gY2FuIG1lYW4gYW55dGhpbmcgYmV0d2VlbiA1IG1tIC0gNDUgbW0gcmFpbmZhbGwgcGVyIGRheS4KCk5vdGUgaG93ZXZlciwgdGhhdCB0aGUgYW5udWFsIHByZWNpcGl0YXRpb24gZGVwZW5kcyBhIGdyZWF0IGRlYWwgb24gaG93IG1hbnkgZGF5cyBpdCByYWluZWQgYWJvdmUgNSBtbS9kYXkgYW5kIGlzIGFsc28gc3Ryb25nbHkgZGV0ZXJtaW5lZCBieSB0aGUgdG90YWwgcHJlY3BpdGF0aW9uIHJlY2VpdmVkIGR1cmluZyB0aG9zZSBkYXlzOgoKYGBge3J9CnBhcihtZnJvdz1jKDEsMikpCnBsb3QoUCwgUF9zdHJvbmcvUCAsCiAgICAgeGxhYiA9ICJhbm51YWwgcHJlY2lwaXRhdGlvbiBpbiBtbS9hIiwKICAgICB5bGFiID0gInRvdGFsIFAgb24gZGF5cyBQPjVtbSAvIHRvdGFsIFAiKQpwbG90KFAsc3Ryb25ncmFpbmRheXMvcmFpbmRheXMsCiAgICAgeGxhYiA9ICJhbm51YWwgcHJlY2lwaXRhdGlvbiBpbiBtbS9hIiwKICAgICB5bGFiID0gIm5vIG9mIGRheXMgd2l0aCBQPjVtbSAvIG5vIHByZWNpcGl0YXRpb24gZGF5cyIpCmBgYAoKT25seSAxMi0yNCUgb2YgdGhlIHByZWNpcGl0YXRpb24gZGF5cyBoYXZlIHByZWNpcGl0YXRpb24gPiA1IG1tLCBidXQgdGhleSBhcmUgcmVzcG9uc2libGUgZm9yIDQ1IHRvIDcwJSBvZiB0aGUgYW5udWFsIHByZWNpcGl0YXRpb24uIElmIHRoZXkgYXJlIHNpbmdsZSBldmVudHMsIHRoZXkgYWxzbyByb3VnaGx5IGNvcnJlc3BvbmQgdG8gdGhlIGV2ZW50IHNpemUgcmVxdWlyZWQgdG8geWllbGQgYW55IHNvaWwgbW9pc3R1cmUgcmVzcG9uc2UgKHNlZSBGaXNjaGVyIGV0IGFsLiAyMDIzLCBpbiBwcmludCBpbiBIRVNTKS4gVGhlaXIgZnJlcXVlbmN5IGRvZXMgbm90IGNoYW5nZS4gCgpXZSBjYW4gdXNlIHRoZSByZWxhdGlvbiBhYm92ZSB0byBjYWxjdWxhdGUgdGhlIGV4cGVjdGVkIHN0cm9uZyBwcmVjaXBpdGF0aW9uIGVhY2ggeWVhciBiYXNlZCBvbiB0aGUgYW5udWFsIHByZWNpcGl0YXRpb24uIFRoaXMgYWxsb3dzIGEgbW9yZSBmb2N1c3NlZCBsb29rIG9uIGhvdyB0aGUgc3Ryb25nIHByZWNpcGl0YXRpb24gY2hhbmdlczoKCmBgYHtyfQoKbG0uUHN0cm9uZ19QIDwtIGxtKFBfc3Ryb25nflApICMgUmVsYXRpb24gYmV0d2VlbiB0b3RhbCBhbm51YWwgcHJlY2lwaXRhdGlvbiBhbmQgc3Ryb25nIGV2ZW50cwpzdW1tYXJ5KGxtLlBzdHJvbmdfUCkKCiMgcHJlZGljdCBjb250cmlidXRpb24gb2Ygc3Ryb25nIGV2ZW50cyBmcm9tIGFubnVhbCBwcmVjaXBpdGF0aW9uIGFzIGEgYmFzZWxpbmUuClBfc3Ryb25nX2xtIDwtIHByZWRpY3QobG0uUHN0cm9uZ19QKSAjIHRoaXMgaXMgdGhlIGV4cGVjdGVkIGNvbnRyaWJ1dGlvbiBvZiBzdHJvbmcgZXZlbnRzIHRvIHRvdGFsIFAKCmQucHJlZC5QX3N0cm9nIDwtIFBfc3Ryb25nLVBfc3Ryb25nX2xtICMgcHJlZGljdGlvbiBlcnJvciBvZiBjb250cmlidXRpb24gb2Ygc3Ryb25nIHByZWNpcCBkYXlzCgojIGNoZWNrIHdoZXRoZXIgdGhlcmUgaXMgYSB0cmVuZCBpbiBvdmVyL3VuZGVycHJlZGljdGlvbgpwbG90KHllYXJzLCBkLnByZWQuUF9zdHJvZywKICAgICB5bGFiID0gIm9ic2VydmVkLXByZWRpY3RlZCIpCmxtLnByZWRfdHJlbmQgPC0gbG0oZC5wcmVkLlBfc3Ryb2cgfiB5ZWFycykKc3VtbWFyeShsbS5wcmVkX3RyZW5kKQoKCmxtLnByZWRfdHJlbmQuMjAxNF8yMDIxIDwtIGxtKGQucHJlZC5QX3N0cm9nW3lyc18yMDE0XzIwMjFdIH4geWVhcnNbeXJzXzIwMTRfMjAyMV0pCnN1bW1hcnkobG0ucHJlZF90cmVuZC4yMDE0XzIwMjEpCgpgYGAKVGhlcmUgaXMgYSByZWxhdGlvbiBpbiB0aGUgcHJlZGljdGlvbiBlcnJvciB3aXRoIHRpbWUuIEluIG90aGVyIHdvcmRzOiBUaGUgY29udHJpYnV0aW9uIG9mIGxhcmdlIHJhaW5mYWxsIGV2ZW50cyB0byB0b3RhbCByYWluZmFsbCBpbiByZWNlbnQgeWVhcnMgaXMgaGlnaGVyIHRoYW4gZXhwZWN0ZWQgYmFzZWQgb24gdGhlIGVudGlyZSBzYW1wbGUgKDIwMDUtMjAyMikuIFRoaXMgcmVsYXRpb24gaXMgbm90IGF0IGFsbCBvYnZpb3VzIGZvciB0aGUgc2hvcnRlciBwZXJpb2QgMjAxNC0yMDIxLgoK