In the last 2 etivities, you have learnt how you can represent differential equations in R through the use of the deSolve package. In this etivity you will use this skill to start coding a simplified SIR model within R. Let’s recap first what an SIR model is:

The differential equations for this system are:

\[\begin{align} \frac{dS}{dt} & = -\lambda S \\ \frac{dI}{dt} & = \lambda S - \gamma I \\ \frac{dR}{dt} & = \gamma I \end{align}\]

We can use the SIR model to describe a disease that can be split into 3 states: susceptible (\(S\)), infected (\(I\)), or recovered (R). All those infected are infectious, and all those recovered are immune, so they cannot get the disease again.

One part of this model should already be very familiar to you! The transition from I to R is what we explored in etivity 1. The new addition is the susceptibles in compartment S. As you learnt in the lecture, depending on how many people in the population are infectious, susceptible people experience a force of infection \(\lambda\) (lambda), which is the transition rate at which they become infected.

In this etivity, we are trying to simulate an outbreak of a new infectious disease that our population of 10\(^{6}\) people has not been exposed to before. This means that we are starting with a single case, everyone else is susceptible to the disease, and no one is yet immune or recovered. This can for example reflect a situation where an infected person introduces a new disease into a geographically isolated population, like on an island, or even when an infections “spill over” from other animals into a human population. In terms of the initial conditions for our model, we can define: S = 10\(^{6}\)-1 = 999999, I = 1 and R = 0.

Now it’s your turn to write and solve this model in R, assuming a constant force of infection of 0.2 days\(^{-1}\). Like in the first coding etivity, the infection has an average duration of 10 days, but this time we want to run the model for 60 days. Try to write the whole code by yourself - but if you have trouble remembering how, just go back to the etivity 1 solution to check. We have also added some hints in the cell below, to help you remember which different parts are required. As you go along, it is good practice to add your own comments to every part, explaining what the code is for. When you’re done writing the code and the comments, run it and print the output to double-check that everything works.

1 Solution: SIR model with a constant force of infection

In this etivity, you had the task of writing an SIR model in R from scratch. Compare your code to the solution given below, but note that yours might look slightly different in terms of the names you have chosen for your variables. That’s fine, as long as the code is easy to follow and produces the correct output!

Remember, the differential equations for the simple SIR model with a constant force of infection look like this:

\[\begin{align} \frac{dS}{dt} & = -\lambda S \\ \frac{dI}{dt} & = \lambda S - \gamma I \\ \frac{dR}{dt} & = \gamma I \end{align}\]

1.1 The input data from the instructions were as follows:

Initial number of people in each compartment:
S = 10\(^6\)-1, I = 1 and R = 0
Parameters:
\(\lambda\) = 0.2 days\(^{-1}\) (this represents a force of infection that’s constant at 0.2)
\(\gamma\) = 0.1 days\(^{-1}\) (corresponding to an average duration of infection of 10 days)
We want to run the model for 60 days.

# LOAD THE PACKAGES:
library(deSolve)
library(reshape2)
library(ggplot2)
# MODEL INPUTS:

# Vector storing the initial number of people in each compartment (at timestep 0)

initial_state_values <- c(S = 999999,  # the whole population we are modelling is susceptible to infection
                          I = 1,       # the epidemic starts with a single infected person
                          R = 0)       # there is no prior immunity in the population

# Vector storing the parameters describing the transition rates in units of days^-1
parameters <- c(lambda = 0.2,  # the force of infection, which acts on susceptibles
                gamma = 0.1)   # the rate of recovery, which acts on those infected

# TIMESTEPS:

# Vector storing the sequence of timesteps to solve the model at
times <- seq(from = 0, to = 60, by = 1)   # from 0 to 60 days in daily intervals

# SIR MODEL FUNCTION: 

# The model function takes as input arguments (in the following order): time, state and parameters
sir_model <- function(time, state, parameters) {  

    with(as.list(c(state, parameters)), {  # tell R to unpack variable names from the state and parameters inputs
        
    # The differential equations
      dS <- -lambda * S               # people move out of (-) the S compartment at a rate lambda (force of infection)
      dI <- lambda * S - gamma * I    # people move into (+) the I compartment from S at a rate lambda, 
                                      # and move out of (-) the I compartment at a rate gamma (recovery)
      dR <- gamma * I                 # people move into (+) the R compartment from I at a rate gamma
      
    # Return the number of people in the S, I and R compartments at each timestep 
    # (in the same order as the input state variables)
    return(list(c(dS, dI, dR))) 
    })
  
}

# MODEL OUTPUT (solving the differential equations):

# Solving the differential equations using the ode integration algorithm
output <- as.data.frame(ode(y = initial_state_values, 
                            times = times, 
                            func = sir_model,
                            parms = parameters))
# Printing the model output returns a dataframe with columns time (containing the times vector), 
# S (containing the number of susceptible people at each timestep),
# I (containing the number of infected people at each timestep) and 
# R (containing the number of recovered people at each timestep).
output
##    time            S          I          R
## 1     0 9.999990e+05      1.000      0.000
## 2     1 8.187299e+05 172214.061   9056.004
## 3     2 6.703194e+05 296821.937  32858.688
## 4     3 5.488111e+05 384013.528  67175.386
## 5     4 4.493285e+05 441982.410 108689.084
## 6     5 3.678791e+05 477302.608 154818.340
## 7     6 3.011939e+05 495234.957 203571.160
## 8     7 2.465967e+05 499976.743 253426.573
## 9     8 2.018963e+05 494864.916 303238.803
## 10    9 1.652987e+05 482541.541 352159.774
## 11   10 1.353351e+05 465088.345 399576.571
## 12   11 1.108030e+05 444135.873 445061.148
## 13   12 9.071779e+04 420952.533 488329.674
## 14   13 7.427343e+04 396516.440 529210.125
## 15   14 6.080994e+04 371573.802 567616.261
## 16   15 4.978696e+04 346686.177 603526.866
## 17   16 4.076211e+04 322268.614 636969.278
## 18   17 3.337319e+04 298620.488 668006.326
## 19   18 2.732365e+04 275950.307 696726.044
## 20   19 2.237071e+04 254395.666 723233.625
## 21   20 1.831558e+04 234039.257 747645.159
## 22   21 1.499553e+04 214921.669 770082.801
## 23   22 1.227730e+04 197051.601 790671.099
## 24   23 1.005180e+04 180413.979 809534.219
## 25   24 8.229718e+03 164976.376 826793.906
## 26   25 6.737922e+03 150694.067 842568.011
## 27   26 5.516543e+03 137513.992 856969.465
## 28   27 4.516563e+03 125377.829 870105.609
## 29   28 3.697848e+03 114224.364 882077.788
## 30   29 3.027542e+03 103991.298 892981.160
## 31   30 2.478741e+03  94616.601 902904.658
## 32   31 2.029421e+03  86039.514 911931.065
## 33   32 1.661549e+03  78201.265 920137.185
## 34   33 1.360361e+03  71045.572 927594.066
## 35   34 1.113770e+03  64518.965 934367.266
## 36   35 9.118772e+02  58570.980 940517.143
## 37   36 7.465818e+02  53154.252 946099.167
## 38   37 6.112494e+02  48224.527 951164.223
## 39   38 5.004486e+02  43740.622 955758.929
## 40   39 4.097326e+02  39664.335 959925.932
## 41   40 3.354606e+02  35960.336 963704.203
## 42   41 2.746519e+02  32596.029 967129.319
## 43   42 2.248659e+02  29541.405 970233.729
## 44   43 1.841046e+02  26768.894 973047.002
## 45   44 1.507321e+02  24253.202 975596.066
## 46   45 1.234090e+02  21971.163 977905.428
## 47   46 1.010387e+02  19901.583 979997.378
## 48   47 8.272349e+01  18025.097 981892.179
## 49   48 6.772825e+01  16324.028 983608.243
## 50   49 5.545120e+01  14782.255 985162.293
## 51   50 4.539959e+01  13385.087 986569.513
## 52   51 3.717004e+01  12119.146 987843.684
## 53   52 3.043225e+01  10972.258 988997.310
## 54   53 2.491581e+01   9933.350 990041.734
## 55   54 2.039934e+01   8992.358 990987.243
## 56   55 1.670156e+01   8140.135 991843.163
## 57   56 1.367408e+01   7368.375 992617.951
## 58   57 1.119539e+01   6669.536 993319.268
## 59   58 9.166009e+00   6036.774 993954.060
## 60   59 7.504492e+00   5463.877 994528.618
## 61   60 6.144158e+00   4945.213 995048.643
#Plotting the output:

output_long <- melt(as.data.frame(output), id = "time")                  # turn output dataset into long format

ggplot(data = output_long,                                               # specify object containing data to plot
       aes(x = time, y = value, colour = variable, group = variable)) +  # assign columns to axes and groups
  geom_line() +                                                          # represent data as lines
  xlab("Time (days)")+                                                   # add label for x axis
  ylab("Number of people") +                                             # add label for y axis
  labs(colour = "Compartment")                                           # add legend title

In the following cell, plot the number of people in each compartment over time. You should see that at the peak of the epidemic, around 500000 people are infected

1.1.1 Based on the plot, describe the pattern of the epidemic over the 2 month period. How does the number of people in the susceptible, infected and recovered compartment change over time? After how many days does the epidemic reach its peak? After how many days does it end?

The number of infected people quickly increases, reaching a peak of 500000 infected people after around 7 days, before steadily decreasing again. The number of recovered people starts to rise shortly after the first people become infected. It increases steadily (but less sharply than the curve of infected people) until the whole population has become immune - by day 53, 99% are in the R compartment, and nearly no susceptible people remain after 60 days.

LS0tDQp0aXRsZTogIk5vdGVyYm9vayAzIC0gdzE6IFNvbHV0aW9uOiBTSVIgbW9kZWwgd2l0aCBhIGNvbnN0YW50IGZvcmNlIG9mIGluZmVjdGlvbiINCmF1dGhvcjogIkJpbmggVGhhbmcgVHJhbiAoQykgZnJvbSBjb3Vyc2VyYSINCmRhdGU6ICI1LzEwLzIwMjAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0aGVtZTogam91cm5hbA0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgd29yZF9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KLS0tDQoNCkluIHRoZSBsYXN0IDIgZXRpdml0aWVzLCB5b3UgaGF2ZSBsZWFybnQgaG93IHlvdSBjYW4gcmVwcmVzZW50IGRpZmZlcmVudGlhbCBlcXVhdGlvbnMgaW4gUiB0aHJvdWdoIHRoZSB1c2Ugb2YgdGhlIGRlU29sdmUgcGFja2FnZS4gSW4gdGhpcyBldGl2aXR5IHlvdSB3aWxsIHVzZSB0aGlzIHNraWxsIHRvIHN0YXJ0IGNvZGluZyBhIHNpbXBsaWZpZWQgU0lSIG1vZGVsIHdpdGhpbiBSLiBMZXQncyByZWNhcCBmaXJzdCB3aGF0IGFuIFNJUiBtb2RlbCBpczogDQoNCg0KVGhlIGRpZmZlcmVudGlhbCBlcXVhdGlvbnMgZm9yIHRoaXMgc3lzdGVtIGFyZToNCg0KXGJlZ2lue2FsaWdufQ0KXGZyYWN7ZFN9e2R0fSAmID0gLVxsYW1iZGEgUyBcXA0KXGZyYWN7ZEl9e2R0fSAmID0gXGxhbWJkYSBTIC0gXGdhbW1hIEkgXFwNClxmcmFje2RSfXtkdH0gJiA9IFxnYW1tYSBJDQpcZW5ke2FsaWdufQ0KDQpXZSBjYW4gdXNlIHRoZSBTSVIgbW9kZWwgdG8gZGVzY3JpYmUgYSBkaXNlYXNlIHRoYXQgY2FuIGJlIHNwbGl0IGludG8gMyBzdGF0ZXM6IHN1c2NlcHRpYmxlICgkUyQpLCBpbmZlY3RlZCAoJEkkKSwgb3IgcmVjb3ZlcmVkIChSKS4gQWxsIHRob3NlIGluZmVjdGVkIGFyZSBpbmZlY3Rpb3VzLCBhbmQgYWxsIHRob3NlIHJlY292ZXJlZCBhcmUgaW1tdW5lLCBzbyB0aGV5IGNhbm5vdCBnZXQgdGhlIGRpc2Vhc2UgYWdhaW4uDQoNCk9uZSBwYXJ0IG9mIHRoaXMgbW9kZWwgc2hvdWxkIGFscmVhZHkgYmUgdmVyeSBmYW1pbGlhciB0byB5b3UhIFRoZSB0cmFuc2l0aW9uIGZyb20gSSB0byBSIGlzIHdoYXQgd2UgZXhwbG9yZWQgaW4gZXRpdml0eSAxLiBUaGUgbmV3IGFkZGl0aW9uIGlzIHRoZSBzdXNjZXB0aWJsZXMgaW4gY29tcGFydG1lbnQgUy4gQXMgeW91IGxlYXJudCBpbiB0aGUgbGVjdHVyZSwgZGVwZW5kaW5nIG9uIGhvdyBtYW55IHBlb3BsZSBpbiB0aGUgcG9wdWxhdGlvbiBhcmUgaW5mZWN0aW91cywgc3VzY2VwdGlibGUgcGVvcGxlIGV4cGVyaWVuY2UgYSBmb3JjZSBvZiBpbmZlY3Rpb24gJFxsYW1iZGEkICgqbGFtYmRhKiksIHdoaWNoIGlzIHRoZSB0cmFuc2l0aW9uIHJhdGUgYXQgd2hpY2ggdGhleSBiZWNvbWUgaW5mZWN0ZWQuDQoNCkluIHRoaXMgZXRpdml0eSwgd2UgYXJlIHRyeWluZyB0byBzaW11bGF0ZSBhbiBvdXRicmVhayBvZiBhIG5ldyBpbmZlY3Rpb3VzIGRpc2Vhc2UgdGhhdCBvdXIgcG9wdWxhdGlvbiBvZiAxMCReezZ9JCBwZW9wbGUgaGFzIG5vdCBiZWVuIGV4cG9zZWQgdG8gYmVmb3JlLiBUaGlzIG1lYW5zIHRoYXQgd2UgYXJlIHN0YXJ0aW5nIHdpdGggYSBzaW5nbGUgY2FzZSwgZXZlcnlvbmUgZWxzZSBpcyBzdXNjZXB0aWJsZSB0byB0aGUgZGlzZWFzZSwgYW5kIG5vIG9uZSBpcyB5ZXQgaW1tdW5lIG9yIHJlY292ZXJlZC4gVGhpcyBjYW4gZm9yIGV4YW1wbGUgcmVmbGVjdCBhIHNpdHVhdGlvbiB3aGVyZSBhbiBpbmZlY3RlZCBwZXJzb24gaW50cm9kdWNlcyBhIG5ldyBkaXNlYXNlIGludG8gYSBnZW9ncmFwaGljYWxseSBpc29sYXRlZCBwb3B1bGF0aW9uLCBsaWtlIG9uIGFuIGlzbGFuZCwgb3IgZXZlbiB3aGVuIGFuIGluZmVjdGlvbnMgInNwaWxsIG92ZXIiIGZyb20gb3RoZXIgYW5pbWFscyBpbnRvIGEgaHVtYW4gcG9wdWxhdGlvbi4gSW4gdGVybXMgb2YgdGhlIGluaXRpYWwgY29uZGl0aW9ucyBmb3Igb3VyIG1vZGVsLCB3ZSBjYW4gZGVmaW5lOiBTID0gMTAkXns2fSQtMSA9IDk5OTk5OSwgSSA9IDEgYW5kIFIgPSAwLiANCg0KTm93IGl0J3MgeW91ciB0dXJuIHRvIHdyaXRlIGFuZCBzb2x2ZSB0aGlzIG1vZGVsIGluIFIsIGFzc3VtaW5nIGEgY29uc3RhbnQgZm9yY2Ugb2YgaW5mZWN0aW9uIG9mIDAuMiBkYXlzJF57LTF9JC4gTGlrZSBpbiB0aGUgZmlyc3QgY29kaW5nIGV0aXZpdHksIHRoZSBpbmZlY3Rpb24gaGFzIGFuIGF2ZXJhZ2UgZHVyYXRpb24gb2YgMTAgZGF5cywgYnV0IHRoaXMgdGltZSB3ZSB3YW50IHRvIHJ1biB0aGUgbW9kZWwgZm9yIDYwIGRheXMuIFRyeSB0byB3cml0ZSB0aGUgd2hvbGUgY29kZSBieSB5b3Vyc2VsZiAtIGJ1dCBpZiB5b3UgaGF2ZSB0cm91YmxlIHJlbWVtYmVyaW5nIGhvdywganVzdCBnbyBiYWNrIHRvIHRoZSBldGl2aXR5IDEgc29sdXRpb24gdG8gY2hlY2suIFdlIGhhdmUgYWxzbyBhZGRlZCBzb21lIGhpbnRzIGluIHRoZSBjZWxsIGJlbG93LCB0byBoZWxwIHlvdSByZW1lbWJlciB3aGljaCBkaWZmZXJlbnQgcGFydHMgYXJlIHJlcXVpcmVkLiBBcyB5b3UgZ28gYWxvbmcsIGl0IGlzIGdvb2QgcHJhY3RpY2UgdG8gYWRkIHlvdXIgb3duIGNvbW1lbnRzIHRvIGV2ZXJ5IHBhcnQsIGV4cGxhaW5pbmcgd2hhdCB0aGUgY29kZSBpcyBmb3IuIFdoZW4geW91J3JlIGRvbmUgd3JpdGluZyB0aGUgY29kZSBhbmQgdGhlIGNvbW1lbnRzLCBydW4gaXQgYW5kIHByaW50IHRoZSBvdXRwdXQgdG8gZG91YmxlLWNoZWNrIHRoYXQgZXZlcnl0aGluZyB3b3Jrcy4NCg0KDQoNCg0KDQojIFNvbHV0aW9uOiBTSVIgbW9kZWwgd2l0aCBhIGNvbnN0YW50IGZvcmNlIG9mIGluZmVjdGlvbg0KDQpJbiB0aGlzIGV0aXZpdHksIHlvdSBoYWQgdGhlIHRhc2sgb2Ygd3JpdGluZyBhbiBTSVIgbW9kZWwgaW4gUiBmcm9tIHNjcmF0Y2guIENvbXBhcmUgeW91ciBjb2RlIHRvIHRoZSBzb2x1dGlvbiBnaXZlbiBiZWxvdywgYnV0IG5vdGUgdGhhdCB5b3VycyBtaWdodCBsb29rIHNsaWdodGx5IGRpZmZlcmVudCBpbiB0ZXJtcyBvZiB0aGUgbmFtZXMgeW91IGhhdmUgY2hvc2VuIGZvciB5b3VyIHZhcmlhYmxlcy4gVGhhdCdzIGZpbmUsIGFzIGxvbmcgYXMgdGhlIGNvZGUgaXMgZWFzeSB0byBmb2xsb3cgYW5kIHByb2R1Y2VzIHRoZSBjb3JyZWN0IG91dHB1dCEgDQoNClJlbWVtYmVyLCB0aGUgZGlmZmVyZW50aWFsIGVxdWF0aW9ucyBmb3IgdGhlIHNpbXBsZSBTSVIgbW9kZWwgd2l0aCBhIGNvbnN0YW50IGZvcmNlIG9mIGluZmVjdGlvbiBsb29rIGxpa2UgdGhpczoNCg0KXGJlZ2lue2FsaWdufQ0KXGZyYWN7ZFN9e2R0fSAmID0gLVxsYW1iZGEgUyBcXA0KXGZyYWN7ZEl9e2R0fSAmID0gXGxhbWJkYSBTIC0gXGdhbW1hIEkgXFwNClxmcmFje2RSfXtkdH0gJiA9IFxnYW1tYSBJDQpcZW5ke2FsaWdufQ0KDQojIyBUaGUgaW5wdXQgZGF0YSBmcm9tIHRoZSBpbnN0cnVjdGlvbnMgd2VyZSBhcyBmb2xsb3dzOiAgDQoNCioqSW5pdGlhbCBudW1iZXIgb2YgcGVvcGxlIGluIGVhY2ggY29tcGFydG1lbnQqKjogIA0KUyA9IDEwJF42JC0xLCBJID0gMSBhbmQgUiA9IDAgIA0KKipQYXJhbWV0ZXJzKio6ICANCiRcbGFtYmRhJCA9IDAuMiBkYXlzJF57LTF9JCAodGhpcyByZXByZXNlbnRzIGEgZm9yY2Ugb2YgaW5mZWN0aW9uIHRoYXQncyBjb25zdGFudCBhdCAwLjIpICANCiRcZ2FtbWEkID0gMC4xIGRheXMkXnstMX0kIChjb3JyZXNwb25kaW5nIHRvIGFuIGF2ZXJhZ2UgZHVyYXRpb24gb2YgaW5mZWN0aW9uIG9mIDEwIGRheXMpICANCioqV2Ugd2FudCB0byBydW4gdGhlIG1vZGVsIGZvciA2MCBkYXlzKiouIA0KDQpgYGB7cn0NCiMgTE9BRCBUSEUgUEFDS0FHRVM6DQpsaWJyYXJ5KGRlU29sdmUpDQpsaWJyYXJ5KHJlc2hhcGUyKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KYGBgDQoNCg0KYGBge3J9DQoNCiMgTU9ERUwgSU5QVVRTOg0KDQojIFZlY3RvciBzdG9yaW5nIHRoZSBpbml0aWFsIG51bWJlciBvZiBwZW9wbGUgaW4gZWFjaCBjb21wYXJ0bWVudCAoYXQgdGltZXN0ZXAgMCkNCg0KaW5pdGlhbF9zdGF0ZV92YWx1ZXMgPC0gYyhTID0gOTk5OTk5LCAgIyB0aGUgd2hvbGUgcG9wdWxhdGlvbiB3ZSBhcmUgbW9kZWxsaW5nIGlzIHN1c2NlcHRpYmxlIHRvIGluZmVjdGlvbg0KICAgICAgICAgICAgICAgICAgICAgICAgICBJID0gMSwgICAgICAgIyB0aGUgZXBpZGVtaWMgc3RhcnRzIHdpdGggYSBzaW5nbGUgaW5mZWN0ZWQgcGVyc29uDQogICAgICAgICAgICAgICAgICAgICAgICAgIFIgPSAwKSAgICAgICAjIHRoZXJlIGlzIG5vIHByaW9yIGltbXVuaXR5IGluIHRoZSBwb3B1bGF0aW9uDQoNCiMgVmVjdG9yIHN0b3JpbmcgdGhlIHBhcmFtZXRlcnMgZGVzY3JpYmluZyB0aGUgdHJhbnNpdGlvbiByYXRlcyBpbiB1bml0cyBvZiBkYXlzXi0xDQpwYXJhbWV0ZXJzIDwtIGMobGFtYmRhID0gMC4yLCAgIyB0aGUgZm9yY2Ugb2YgaW5mZWN0aW9uLCB3aGljaCBhY3RzIG9uIHN1c2NlcHRpYmxlcw0KICAgICAgICAgICAgICAgIGdhbW1hID0gMC4xKSAgICMgdGhlIHJhdGUgb2YgcmVjb3ZlcnksIHdoaWNoIGFjdHMgb24gdGhvc2UgaW5mZWN0ZWQNCg0KIyBUSU1FU1RFUFM6DQoNCiMgVmVjdG9yIHN0b3JpbmcgdGhlIHNlcXVlbmNlIG9mIHRpbWVzdGVwcyB0byBzb2x2ZSB0aGUgbW9kZWwgYXQNCnRpbWVzIDwtIHNlcShmcm9tID0gMCwgdG8gPSA2MCwgYnkgPSAxKSAgICMgZnJvbSAwIHRvIDYwIGRheXMgaW4gZGFpbHkgaW50ZXJ2YWxzDQoNCiMgU0lSIE1PREVMIEZVTkNUSU9OOiANCg0KIyBUaGUgbW9kZWwgZnVuY3Rpb24gdGFrZXMgYXMgaW5wdXQgYXJndW1lbnRzIChpbiB0aGUgZm9sbG93aW5nIG9yZGVyKTogdGltZSwgc3RhdGUgYW5kIHBhcmFtZXRlcnMNCnNpcl9tb2RlbCA8LSBmdW5jdGlvbih0aW1lLCBzdGF0ZSwgcGFyYW1ldGVycykgeyAgDQoNCiAgICB3aXRoKGFzLmxpc3QoYyhzdGF0ZSwgcGFyYW1ldGVycykpLCB7ICAjIHRlbGwgUiB0byB1bnBhY2sgdmFyaWFibGUgbmFtZXMgZnJvbSB0aGUgc3RhdGUgYW5kIHBhcmFtZXRlcnMgaW5wdXRzDQogICAgICAgIA0KICAgICMgVGhlIGRpZmZlcmVudGlhbCBlcXVhdGlvbnMNCiAgICAgIGRTIDwtIC1sYW1iZGEgKiBTICAgICAgICAgICAgICAgIyBwZW9wbGUgbW92ZSBvdXQgb2YgKC0pIHRoZSBTIGNvbXBhcnRtZW50IGF0IGEgcmF0ZSBsYW1iZGEgKGZvcmNlIG9mIGluZmVjdGlvbikNCiAgICAgIGRJIDwtIGxhbWJkYSAqIFMgLSBnYW1tYSAqIEkgICAgIyBwZW9wbGUgbW92ZSBpbnRvICgrKSB0aGUgSSBjb21wYXJ0bWVudCBmcm9tIFMgYXQgYSByYXRlIGxhbWJkYSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYW5kIG1vdmUgb3V0IG9mICgtKSB0aGUgSSBjb21wYXJ0bWVudCBhdCBhIHJhdGUgZ2FtbWEgKHJlY292ZXJ5KQ0KICAgICAgZFIgPC0gZ2FtbWEgKiBJICAgICAgICAgICAgICAgICAjIHBlb3BsZSBtb3ZlIGludG8gKCspIHRoZSBSIGNvbXBhcnRtZW50IGZyb20gSSBhdCBhIHJhdGUgZ2FtbWENCiAgICAgIA0KICAgICMgUmV0dXJuIHRoZSBudW1iZXIgb2YgcGVvcGxlIGluIHRoZSBTLCBJIGFuZCBSIGNvbXBhcnRtZW50cyBhdCBlYWNoIHRpbWVzdGVwIA0KICAgICMgKGluIHRoZSBzYW1lIG9yZGVyIGFzIHRoZSBpbnB1dCBzdGF0ZSB2YXJpYWJsZXMpDQogICAgcmV0dXJuKGxpc3QoYyhkUywgZEksIGRSKSkpIA0KICAgIH0pDQogIA0KfQ0KDQojIE1PREVMIE9VVFBVVCAoc29sdmluZyB0aGUgZGlmZmVyZW50aWFsIGVxdWF0aW9ucyk6DQoNCiMgU29sdmluZyB0aGUgZGlmZmVyZW50aWFsIGVxdWF0aW9ucyB1c2luZyB0aGUgb2RlIGludGVncmF0aW9uIGFsZ29yaXRobQ0Kb3V0cHV0IDwtIGFzLmRhdGEuZnJhbWUob2RlKHkgPSBpbml0aWFsX3N0YXRlX3ZhbHVlcywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZXMgPSB0aW1lcywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuYyA9IHNpcl9tb2RlbCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJtcyA9IHBhcmFtZXRlcnMpKQ0KIyBQcmludGluZyB0aGUgbW9kZWwgb3V0cHV0IHJldHVybnMgYSBkYXRhZnJhbWUgd2l0aCBjb2x1bW5zIHRpbWUgKGNvbnRhaW5pbmcgdGhlIHRpbWVzIHZlY3RvciksIA0KIyBTIChjb250YWluaW5nIHRoZSBudW1iZXIgb2Ygc3VzY2VwdGlibGUgcGVvcGxlIGF0IGVhY2ggdGltZXN0ZXApLA0KIyBJIChjb250YWluaW5nIHRoZSBudW1iZXIgb2YgaW5mZWN0ZWQgcGVvcGxlIGF0IGVhY2ggdGltZXN0ZXApIGFuZCANCiMgUiAoY29udGFpbmluZyB0aGUgbnVtYmVyIG9mIHJlY292ZXJlZCBwZW9wbGUgYXQgZWFjaCB0aW1lc3RlcCkuDQpvdXRwdXQNCg0KI1Bsb3R0aW5nIHRoZSBvdXRwdXQ6DQoNCm91dHB1dF9sb25nIDwtIG1lbHQoYXMuZGF0YS5mcmFtZShvdXRwdXQpLCBpZCA9ICJ0aW1lIikgICAgICAgICAgICAgICAgICAjIHR1cm4gb3V0cHV0IGRhdGFzZXQgaW50byBsb25nIGZvcm1hdA0KDQpnZ3Bsb3QoZGF0YSA9IG91dHB1dF9sb25nLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBzcGVjaWZ5IG9iamVjdCBjb250YWluaW5nIGRhdGEgdG8gcGxvdA0KICAgICAgIGFlcyh4ID0gdGltZSwgeSA9IHZhbHVlLCBjb2xvdXIgPSB2YXJpYWJsZSwgZ3JvdXAgPSB2YXJpYWJsZSkpICsgICMgYXNzaWduIGNvbHVtbnMgdG8gYXhlcyBhbmQgZ3JvdXBzDQogIGdlb21fbGluZSgpICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyByZXByZXNlbnQgZGF0YSBhcyBsaW5lcw0KICB4bGFiKCJUaW1lIChkYXlzKSIpKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYWRkIGxhYmVsIGZvciB4IGF4aXMNCiAgeWxhYigiTnVtYmVyIG9mIHBlb3BsZSIpICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGFkZCBsYWJlbCBmb3IgeSBheGlzDQogIGxhYnMoY29sb3VyID0gIkNvbXBhcnRtZW50IikgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBhZGQgbGVnZW5kIHRpdGxlDQpgYGANCg0KSW4gdGhlIGZvbGxvd2luZyBjZWxsLCBwbG90IHRoZSBudW1iZXIgb2YgcGVvcGxlIGluIGVhY2ggY29tcGFydG1lbnQgb3ZlciB0aW1lLiBZb3Ugc2hvdWxkIHNlZSB0aGF0IGF0IHRoZSBwZWFrIG9mIHRoZSBlcGlkZW1pYywgYXJvdW5kIDUwMDAwMCBwZW9wbGUgYXJlIGluZmVjdGVkDQoNCg0KIyMjIEJhc2VkIG9uIHRoZSBwbG90LCBkZXNjcmliZSB0aGUgcGF0dGVybiBvZiB0aGUgZXBpZGVtaWMgb3ZlciB0aGUgMiBtb250aCBwZXJpb2QuIEhvdyBkb2VzIHRoZSBudW1iZXIgb2YgcGVvcGxlIGluIHRoZSBzdXNjZXB0aWJsZSwgaW5mZWN0ZWQgYW5kIHJlY292ZXJlZCBjb21wYXJ0bWVudCBjaGFuZ2Ugb3ZlciB0aW1lPyBBZnRlciBob3cgbWFueSBkYXlzIGRvZXMgdGhlIGVwaWRlbWljIHJlYWNoIGl0cyBwZWFrPyBBZnRlciBob3cgbWFueSBkYXlzIGRvZXMgaXQgZW5kPw0KDQpUaGUgbnVtYmVyIG9mIGluZmVjdGVkIHBlb3BsZSBxdWlja2x5IGluY3JlYXNlcywgcmVhY2hpbmcgYSBwZWFrIG9mIDUwMDAwMCBpbmZlY3RlZCBwZW9wbGUgYWZ0ZXIgYXJvdW5kIDcgZGF5cywgYmVmb3JlIHN0ZWFkaWx5IGRlY3JlYXNpbmcgYWdhaW4uIA0KVGhlIG51bWJlciBvZiByZWNvdmVyZWQgcGVvcGxlIHN0YXJ0cyB0byByaXNlIHNob3J0bHkgYWZ0ZXIgdGhlIGZpcnN0IHBlb3BsZSBiZWNvbWUgaW5mZWN0ZWQuIEl0IGluY3JlYXNlcyBzdGVhZGlseSAoYnV0IGxlc3Mgc2hhcnBseSB0aGFuIHRoZSBjdXJ2ZSBvZiBpbmZlY3RlZCBwZW9wbGUpIHVudGlsIHRoZSB3aG9sZSBwb3B1bGF0aW9uIGhhcyBiZWNvbWUgaW1tdW5lIC0gYnkgZGF5IDUzLCA5OSUgYXJlIGluIHRoZSBSIGNvbXBhcnRtZW50LCBhbmQgbmVhcmx5IG5vIHN1c2NlcHRpYmxlIHBlb3BsZSByZW1haW4gYWZ0ZXIgNjAgZGF5cy4NCg==