Goal

The Goal is to compare the Net Present Value (NPV) of the Defined Benefits and Defined Contribution Plan of the State University Retirement System in Illinois.

Net Present Value is an assessment of a future investment’s current value is.

Only three factors are put under consideration when calculating the returns for the two different pensions: The Rate of Return for the Retirement plan, the Discount Rate for the Pension plan, and the age of separation for both plans.

The age of Enrollment and Separation of service in both plots will be 32 to 62 to represent the national average (CITATION NEEDED)

To better compare the returns on investments for both plans, assume the employee receives $60,000 as an initial salary, and has a 5% annual salary increase for said plans.

Defined Contribution Plan

The Defined Contribution plan for the SURS program is called the Retirement Savings Plan (RSP). In many Defined Contributions Plans, money is put into an account, which an employer then uses to invest in various stock portfolios. For the RSP, 15.6% of a person’s salary is annually put into the account, with 8% being contributed by your paychecks and 7.6% being contributed by your employer. During retirement, the employee gets a lump sum of money from said investments to spend during retirement, with the option of purchasing a retirement-like system.

For the plot, T will range from 1 to 30. It will be the x-axis, since it represent the Years of Consecutive Service under SURS’s Retirement Savings Plan

Parameters

The following Factors are relevant to the Defined Contribution plan:

  • m0: Initial Salary
  • a: Annual Salary Increase
  • contribution: Annual contribution rate (including the matching rate from employer)
  • T: Duration of Service
  • ave.r: Annual Rate of Return

Duration of Service represents the years of Service that an employee stays with a company. This affects for how long you make contributions to your retirement account, affecting the NPV of the investment account at retirement.

The Rate of Return is average return on investments in the Retirement Portfolio over all years of investment. This can range wildly, so 3%, 5%, and 8% return rates are shown in the plot.

For the initial parameters, their values are as shown:

m0 = 60000
a = 0.05
contribution = 15.6/100
T = 30
ave.r = 0.03

Code

  • xValues: Ages of Separation with consecutive years of service

  • yValues: Total Actuarial Value at age 62

For each Age of Separation graphed, there are two time periods to consider: #### Duration of Service The account balance at the start of the Duration of Service is 0. For each month during the duration of service, the new account not only grows monthly with the stock performance, which is represented by ave.r, but also from the monthly contribution.

Monthly Return Rate

The monthly return rate is determined by taking the natural log of the the Rate of Increase (1 + Rate of Return), dividing the total by 12, and then using that total for the exponent of e. This is to represent the natural growth of the portfolio using the rate of return.

Monthly Contribution

The monthly deposit is calculated by taking the normal amount of money that would be received annually from multiplying the salary and the contribution rate, and dividing the total by 12, then adding that amount to the account balance per month.This is so the amount added can also apply to the monthly return rate

Duration Before Retirement

After the Age of Separation, neither the Employee nor Employer make contributions to the retirement account anymore, so the account only grows based on the return rate. This is calculated by taking the current account balance and multiplying it by the return rate raised to the power the remaining years left until the employee reach 62.

BalanceDC = function(T, ave.r){
  xValues = c(1:T) + 32
  yValues = rep (0,T)
  
  for (t in 1:T){
    mT = m0
    AccountBalance = 0
    anualDeposit = mT * contribution
    monthlyDeposit = anualDeposit / 12
    for (j in 1:t){
      M = exp(log(1+ave.r)/12)
      for (m in 1:12){
        AccountBalance = AccountBalance * M + monthlyDeposit
      }
    mT = mT * (1+a)
    }
    
    AccountBalance = AccountBalance * (1+ave.r)^ (T-t)
    yValues[t] = AccountBalance
  }
  return(data.frame(x=xValues, y=yValues))
}

Plot

data3 = BalanceDC(T, 0.03)
data5 = BalanceDC(T, 0.05)
data8 = BalanceDC(T, 0.08)

xDC.min = min(data3$x)
xDC.max = max(data3$x)
yDC.min = 0
yDC.max = max(c(data3$y, data5$y, data8$y))

plot(c(xDC.min, xDC.max), c(yDC.min, yDC.max), type ="n",
     xlab = "Years of Service",
     ylab = "Pension Wealth",
     main = "Net Present Value of DC Benefits at age 62")
lines(data3$x, data3$y, lty=1)
points(data3$x, data3$y)
lines(data5$x, data5$y, lty=2)
points(data5$x, data5$y, pty=2)
lines(data8$x, data8$y, lty=3)
points(data8$x, data8$y, pty=2)

Defined Benefits Plan

The SURS Defined Contribution Plan is known as the Traditional TRD) Plan. This type of plan is also referred to as Pension. In this form of retirement, annual payments from one’s employers is given to the employee every year until they die. The amount paid per year is based on a percentage of the employee’s highest-earning salary during their duration of service. In terms of the TRD Plan, SURS provides 2.2% of your averaged final salary (CITATION TO SURS)

For the NPV plot, T will range from 1 to 30. It will be the x-axis, representing the employee’s consecutive Years of Service under SURS’s Retirement Savings Plan.

Parameters

The following Factors are relevant to the Defined Contribution plan:

  • m0: Initial Salary
  • a: Annual Salary Increase
  • pension: annual pension income
  • T: Duration of Service
  • discount.r: Discount Rate

The formula for pension varies from plan to plan. For the TRD plan, it is determined by the product of two values:

  • ave.m: average salary; average salary over the final 5 years of service.
  • pension.percent: the percentage of ave.m that an employee receives annually as pension for their retirement. Example: With a pension rate of 2.2%, after 16 years of service, an employee gains 35.2% of their ave.m as their retirement pension.

Duration of Service represents the years of Service that an employee stays with a company This affects for how long you make contributions to your retirement account, the worth of the account at retirement.

The Discount Rate is the rate of interest that is applied to future cash flows of an investment to calculate its present value. Essentially, it gives an exact value of what a dollar you’ll in the future is worth to someone currently.

The Discount Rate is a variable between different entities, and so the two plots for DC rate will be 0.00 and 0.04. The discount rate parameter actually represents the difference between the discount rate and the annual salary increase rate. The discount rate represents the rate of return used to discount future profits to calculate the current value of an investment. This rate is offset by the salary increase rate , since (INSERT RESASON HERE).

The initial parameters are as shown.

m0 = 60000
a = 0.03
T = 30
pension.percent = 2.2/100
discount.r = 0

Code

  • xValues: Ages of Separation with consecutive years of service

  • yValues: Account Balance at age 62

Step 1: Compute the annual pension income by taking the product of ave.m and pension.percent

Step 2: compute the (expected) NPV of the stream of pension income from age 63 to age 119 using the Actuarial Life Table from SSA website; we use the complement of death rate, averaged over male and female. The NPV formula is given below \[ \sum_{\text{age} = 63}^{119} ... = \sum_{t = 63-62}^{(119 - 62)} \text{annual-pension-income} \times p_t \times v^{t - 0.5} \] where \(v\) \[ v = \frac{1}{1 + \text{discount.rate}} \] is the discount factor and \[ \begin{aligned} p_t = & \mathbb{P}(\text{still alive at age} (62+t) \mid \text{alive at age } 62) \\ = & \quad \mathbb{P}(\text{surve for a year} \mid \text{alive at age } 62) \\ & \times \mathbb{P}(\text{surve for a year} \mid \text{alive at age } 63) \times \\ & \times \cdots \times \mathbb{P}(\text{surve for a year} \mid \text{alive at age } 62+t-1) \\ = & \prod_{j=1}^t \Big [ 1 - \mathbb{P} \big (\text{die within a year } \mid \text{alive at age } (62 + j-1) \big ) \Big ]. \end{aligned} \] To compute the survival probabilities, I imported the SSA life table into my environment.

data = read.table("mtable.txt", sep="\t")
names(data)
names(data) = c("Age", "m.prob", "m.lives", "m.exp", "f.prob", "f.lives", "f.exp")
head(data)
newdata = data.frame(Age = data$Age,  prob = data$m.prob + data$f.prob)
probs = newdata$prob[newdata$Age >= 62]
rm("data", "newdata")

Then, using the methods listed above, I computed the NPV for the TRD Plan.

BalanceDB = function(T, discount.r){
  xValues = c(1:T) + 32
  yValues = rep(0, T)
  if (T < 6){
    return(data.frame(x=xValues, y=yValues))
    exit
  }
  pension = rep (0,T)
  for(t in 6:T){
    tmp = tail(1:t, 2)
    ave.m = mean(m0*(1+a)^(tmp-0.5))
    pension[t] = ave.m * pension.percent * t
    if (pension.percent * t > 0.8){
      pension[t] = ave.m * 0.8
    }
  }
  
pt = 1
v = 1 / (1+discount.r)
vt = v ^(-0.5)
for(t in 1:length(probs)){
  pt = pt * (1-probs[t])
  vt = vt * v
  yValues = yValues + pension * pt * vt
    
  }
  return(data.frame(x = xValues, y = yValues))
}

###Plot

test = BalanceDB (T, discount.r)
x = test$x
y = test$y
plot(x, y, type="n", yaxt="n",
     xlab = "Years of Service",
     ylab = "Pension Wealth (in Dollars)",
     main = "Net Present Value of DC Benefits at age 62")
lines(x, y, lty = 2)

ytick = (1:15) * 100000
axis(2, at = ytick, las = 2, cex.axis = 0.6,
     labels = formatC(ytick, big.mark = ",", format="f", digits = 0))

LS0tDQp0aXRsZTogIlJhZmFlbCdzIFJldGlyZW1lbnQgUGxhbiBDb21wYXJpc29ucyINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazoNCiAgICB0aGVtZTogcmVhZGFibGUNCiAgICB0b2M6IFRSVUUNCiAgICB0b2NfZmxvYXQ6IFRSVUUNCi0tLQ0KDQojIyBHb2FsDQpUaGUgR29hbCBpcyB0byBjb21wYXJlIHRoZSBOZXQgUHJlc2VudCBWYWx1ZSAoTlBWKSBvZiB0aGUgRGVmaW5lZCBCZW5lZml0cyBhbmQgRGVmaW5lZCBDb250cmlidXRpb24gUGxhbiBvZiB0aGUgU3RhdGUgVW5pdmVyc2l0eSBSZXRpcmVtZW50IFN5c3RlbSBpbiBJbGxpbm9pcy4NCg0KTmV0IFByZXNlbnQgVmFsdWUgaXMgYW4gYXNzZXNzbWVudCBvZiBhIGZ1dHVyZSBpbnZlc3RtZW50J3MgY3VycmVudCB2YWx1ZSBpcy4gDQoNCk9ubHkgdGhyZWUgZmFjdG9ycyBhcmUgcHV0IHVuZGVyIGNvbnNpZGVyYXRpb24gd2hlbiBjYWxjdWxhdGluZyB0aGUgcmV0dXJucyBmb3IgdGhlIHR3byBkaWZmZXJlbnQgcGVuc2lvbnM6IFRoZSBSYXRlIG9mIFJldHVybiBmb3IgdGhlIFJldGlyZW1lbnQgcGxhbiwgdGhlIERpc2NvdW50IFJhdGUgZm9yIHRoZSBQZW5zaW9uIHBsYW4sIGFuZCB0aGUgYWdlIG9mIHNlcGFyYXRpb24gZm9yIGJvdGggcGxhbnMuDQoNClRoZSBhZ2Ugb2YgRW5yb2xsbWVudCBhbmQgU2VwYXJhdGlvbiBvZiBzZXJ2aWNlIGluIGJvdGggcGxvdHMgd2lsbCBiZSAzMiB0byA2MiB0byByZXByZXNlbnQgdGhlIG5hdGlvbmFsIGF2ZXJhZ2UgKCoqQ0lUQVRJT04gTkVFREVEKiopDQoNClRvIGJldHRlciBjb21wYXJlIHRoZSByZXR1cm5zIG9uIGludmVzdG1lbnRzIGZvciBib3RoIHBsYW5zLCBhc3N1bWUgdGhlIGVtcGxveWVlIHJlY2VpdmVzICQ2MCwwMDAgYXMgYW4gaW5pdGlhbCBzYWxhcnksIGFuZCBoYXMgYSA1JSBhbm51YWwgc2FsYXJ5IGluY3JlYXNlIGZvciBzYWlkIHBsYW5zLg0KDQojIyBEZWZpbmVkIENvbnRyaWJ1dGlvbiBQbGFuDQogIFRoZSBEZWZpbmVkIENvbnRyaWJ1dGlvbiBwbGFuIGZvciB0aGUgU1VSUyBwcm9ncmFtIGlzIGNhbGxlZCB0aGUgUmV0aXJlbWVudCBTYXZpbmdzIFBsYW4gKFJTUCkuIEluIG1hbnkgRGVmaW5lZCBDb250cmlidXRpb25zIFBsYW5zLCBtb25leSBpcyBwdXQgaW50byBhbiBhY2NvdW50LCB3aGljaCBhbiBlbXBsb3llciB0aGVuIHVzZXMgdG8gaW52ZXN0IGluIHZhcmlvdXMgc3RvY2sgcG9ydGZvbGlvcy4gRm9yIHRoZSBSU1AsIDE1LjYlIG9mIGEgcGVyc29uJ3Mgc2FsYXJ5IGlzIGFubnVhbGx5IHB1dCBpbnRvIHRoZSBhY2NvdW50LCB3aXRoIDglIGJlaW5nIGNvbnRyaWJ1dGVkIGJ5IHlvdXIgcGF5Y2hlY2tzIGFuZCA3LjYlIGJlaW5nIGNvbnRyaWJ1dGVkIGJ5IHlvdXIgZW1wbG95ZXIuIER1cmluZyByZXRpcmVtZW50LCB0aGUgZW1wbG95ZWUgZ2V0cyBhIGx1bXAgc3VtIG9mIG1vbmV5IGZyb20gc2FpZCBpbnZlc3RtZW50cyB0byBzcGVuZCBkdXJpbmcgcmV0aXJlbWVudCwgd2l0aCB0aGUgb3B0aW9uIG9mIHB1cmNoYXNpbmcgYSByZXRpcmVtZW50LWxpa2Ugc3lzdGVtLg0KICANCiAgRm9yIHRoZSBwbG90LCBgVGAgd2lsbCByYW5nZSBmcm9tIDEgdG8gMzAuIEl0IHdpbGwgYmUgdGhlIHgtYXhpcywgc2luY2UgaXQgcmVwcmVzZW50IHRoZSBZZWFycyBvZiBDb25zZWN1dGl2ZSBTZXJ2aWNlIHVuZGVyIFNVUlMncyBSZXRpcmVtZW50IFNhdmluZ3MgUGxhbg0KICANCiMjIyBQYXJhbWV0ZXJzDQogIFRoZSBmb2xsb3dpbmcgRmFjdG9ycyBhcmUgcmVsZXZhbnQgdG8gdGhlIERlZmluZWQgQ29udHJpYnV0aW9uIHBsYW46DQogIA0KLSAgIGBtMGA6IEluaXRpYWwgU2FsYXJ5DQotICAgYGFgOiBBbm51YWwgU2FsYXJ5IEluY3JlYXNlDQotICAgYGNvbnRyaWJ1dGlvbmA6IEFubnVhbCBjb250cmlidXRpb24gcmF0ZSAoaW5jbHVkaW5nIHRoZSBtYXRjaGluZyByYXRlIGZyb20gZW1wbG95ZXIpDQotICAgYFRgOiBEdXJhdGlvbiBvZiBTZXJ2aWNlDQotICAgYGF2ZS5yYDogQW5udWFsIFJhdGUgb2YgUmV0dXJuIA0KDQogIER1cmF0aW9uIG9mIFNlcnZpY2UgcmVwcmVzZW50cyB0aGUgeWVhcnMgb2YgU2VydmljZSB0aGF0IGFuIGVtcGxveWVlIHN0YXlzIHdpdGggYSBjb21wYW55LiBUaGlzIGFmZmVjdHMgZm9yIGhvdyBsb25nIHlvdSBtYWtlICBjb250cmlidXRpb25zIHRvIHlvdXIgcmV0aXJlbWVudCBhY2NvdW50LCBhZmZlY3RpbmcgdGhlIE5QViBvZiB0aGUgaW52ZXN0bWVudCBhY2NvdW50IGF0IHJldGlyZW1lbnQuDQogIA0KICBUaGUgUmF0ZSBvZiBSZXR1cm4gaXMgYXZlcmFnZSByZXR1cm4gb24gaW52ZXN0bWVudHMgaW4gdGhlIFJldGlyZW1lbnQgUG9ydGZvbGlvIG92ZXIgYWxsIHllYXJzIG9mIGludmVzdG1lbnQuIFRoaXMgY2FuIHJhbmdlIHdpbGRseSwgc28gMyUsIDUlLCBhbmQgOCUgcmV0dXJuIHJhdGVzIGFyZSBzaG93biBpbiB0aGUgcGxvdC4NCiAgDQogIEZvciB0aGUgaW5pdGlhbCAgcGFyYW1ldGVycywgdGhlaXIgdmFsdWVzIGFyZSBhcyBzaG93bjogDQpgYGB7cn0NCm0wID0gNjAwMDANCmEgPSAwLjA1DQpjb250cmlidXRpb24gPSAxNS42LzEwMA0KVCA9IDMwDQphdmUuciA9IDAuMDMNCmBgYA0KICANCiAgDQojIyMgQ29kZQ0KLSAgIGB4VmFsdWVzYDogQWdlcyBvZiBTZXBhcmF0aW9uIHdpdGggY29uc2VjdXRpdmUgeWVhcnMgb2Ygc2VydmljZQ0KDQotICAgYHlWYWx1ZXNgOiBUb3RhbCBBY3R1YXJpYWwgVmFsdWUgYXQgYWdlIDYyDQoNCkZvciBlYWNoIEFnZSBvZiBTZXBhcmF0aW9uIGdyYXBoZWQsIHRoZXJlIGFyZSB0d28gdGltZSBwZXJpb2RzIHRvIGNvbnNpZGVyOg0KIyMjIyBEdXJhdGlvbiBvZiBTZXJ2aWNlDQogIFRoZSBhY2NvdW50IGJhbGFuY2UgYXQgdGhlIHN0YXJ0IG9mIHRoZSBEdXJhdGlvbiBvZiBTZXJ2aWNlIGlzIDAuIEZvciBlYWNoIG1vbnRoIGR1cmluZyB0aGUgZHVyYXRpb24gb2Ygc2VydmljZSwgdGhlIG5ldyBhY2NvdW50IG5vdCBvbmx5IGdyb3dzIG1vbnRobHkgd2l0aCB0aGUgc3RvY2sgcGVyZm9ybWFuY2UsIHdoaWNoIGlzIHJlcHJlc2VudGVkIGJ5IGBhdmUucmAsIGJ1dCBhbHNvIGZyb20gdGhlIG1vbnRobHkgYGNvbnRyaWJ1dGlvbmAuDQogIA0KIyMjIyMgTW9udGhseSBSZXR1cm4gUmF0ZQ0KICBUaGUgbW9udGhseSByZXR1cm4gcmF0ZSBpcyBkZXRlcm1pbmVkIGJ5IHRha2luZyB0aGUgbmF0dXJhbCBsb2cgb2YgdGhlIHRoZSBSYXRlIG9mIEluY3JlYXNlICgxICsgUmF0ZSBvZiBSZXR1cm4pLCBkaXZpZGluZyB0aGUgdG90YWwgYnkgMTIsIGFuZCB0aGVuIHVzaW5nIHRoYXQgdG90YWwgZm9yIHRoZSBleHBvbmVudCBvZiBlLiBUaGlzIGlzIHRvIHJlcHJlc2VudCB0aGUgbmF0dXJhbCBncm93dGggb2YgdGhlIHBvcnRmb2xpbyB1c2luZyB0aGUgcmF0ZSBvZiByZXR1cm4uDQogIA0KIyMjIyMgTW9udGhseSBDb250cmlidXRpb24NCiAgVGhlIG1vbnRobHkgZGVwb3NpdCBpcyBjYWxjdWxhdGVkIGJ5IHRha2luZyB0aGUgbm9ybWFsIGFtb3VudCBvZiBtb25leSB0aGF0IHdvdWxkIGJlIHJlY2VpdmVkIGFubnVhbGx5IGZyb20gbXVsdGlwbHlpbmcgdGhlIHNhbGFyeSBhbmQgdGhlIGNvbnRyaWJ1dGlvbiByYXRlLCBhbmQgZGl2aWRpbmcgdGhlIHRvdGFsIGJ5IDEyLCB0aGVuIGFkZGluZyB0aGF0IGFtb3VudCB0byB0aGUgYWNjb3VudCBiYWxhbmNlIHBlciBtb250aC5UaGlzIGlzIHNvIHRoZSBhbW91bnQgYWRkZWQgY2FuIGFsc28gYXBwbHkgdG8gdGhlIG1vbnRobHkgcmV0dXJuIHJhdGUgDQogIA0KIyMjIyBEdXJhdGlvbiBCZWZvcmUgUmV0aXJlbWVudA0KICBBZnRlciB0aGUgQWdlIG9mIFNlcGFyYXRpb24sIG5laXRoZXIgdGhlIEVtcGxveWVlIG5vciBFbXBsb3llciBtYWtlIGNvbnRyaWJ1dGlvbnMgdG8gdGhlIHJldGlyZW1lbnQgYWNjb3VudCBhbnltb3JlLCBzbyB0aGUgYWNjb3VudCBvbmx5IGdyb3dzIGJhc2VkIG9uIHRoZSByZXR1cm4gcmF0ZS4gVGhpcyBpcyBjYWxjdWxhdGVkIGJ5IHRha2luZyB0aGUgY3VycmVudCBhY2NvdW50IGJhbGFuY2UgYW5kIG11bHRpcGx5aW5nIGl0IGJ5IHRoZSByZXR1cm4gcmF0ZSByYWlzZWQgdG8gdGhlIHBvd2VyIHRoZSByZW1haW5pbmcgeWVhcnMgbGVmdCB1bnRpbCB0aGUgZW1wbG95ZWUgcmVhY2ggNjIuDQoNCg0KYGBge3J9DQpCYWxhbmNlREMgPSBmdW5jdGlvbihULCBhdmUucil7DQogIHhWYWx1ZXMgPSBjKDE6VCkgKyAzMg0KICB5VmFsdWVzID0gcmVwICgwLFQpDQogIA0KICBmb3IgKHQgaW4gMTpUKXsNCiAgICBtVCA9IG0wDQogICAgQWNjb3VudEJhbGFuY2UgPSAwDQogICAgYW51YWxEZXBvc2l0ID0gbVQgKiBjb250cmlidXRpb24NCiAgICBtb250aGx5RGVwb3NpdCA9IGFudWFsRGVwb3NpdCAvIDEyDQogICAgZm9yIChqIGluIDE6dCl7DQogICAgICBNID0gZXhwKGxvZygxK2F2ZS5yKS8xMikNCiAgICAgIGZvciAobSBpbiAxOjEyKXsNCiAgICAgICAgQWNjb3VudEJhbGFuY2UgPSBBY2NvdW50QmFsYW5jZSAqIE0gKyBtb250aGx5RGVwb3NpdA0KICAgICAgfQ0KICAgIG1UID0gbVQgKiAoMSthKQ0KICAgIH0NCiAgICANCiAgICBBY2NvdW50QmFsYW5jZSA9IEFjY291bnRCYWxhbmNlICogKDErYXZlLnIpXiAoVC10KQ0KICAgIHlWYWx1ZXNbdF0gPSBBY2NvdW50QmFsYW5jZQ0KICB9DQogIHJldHVybihkYXRhLmZyYW1lKHg9eFZhbHVlcywgeT15VmFsdWVzKSkNCn0NCmBgYA0KDQojIyMgUGxvdA0KDQpgYGB7cn0NCmRhdGEzID0gQmFsYW5jZURDKFQsIDAuMDMpDQpkYXRhNSA9IEJhbGFuY2VEQyhULCAwLjA1KQ0KZGF0YTggPSBCYWxhbmNlREMoVCwgMC4wOCkNCg0KeERDLm1pbiA9IG1pbihkYXRhMyR4KQ0KeERDLm1heCA9IG1heChkYXRhMyR4KQ0KeURDLm1pbiA9IDANCnlEQy5tYXggPSBtYXgoYyhkYXRhMyR5LCBkYXRhNSR5LCBkYXRhOCR5KSkNCg0KcGxvdChjKHhEQy5taW4sIHhEQy5tYXgpLCBjKHlEQy5taW4sIHlEQy5tYXgpLCB0eXBlID0ibiIsDQogICAgIHhsYWIgPSAiWWVhcnMgb2YgU2VydmljZSIsDQogICAgIHlsYWIgPSAiUGVuc2lvbiBXZWFsdGgiLA0KICAgICBtYWluID0gIk5ldCBQcmVzZW50IFZhbHVlIG9mIERDIEJlbmVmaXRzIGF0IGFnZSA2MiIpDQpsaW5lcyhkYXRhMyR4LCBkYXRhMyR5LCBsdHk9MSkNCnBvaW50cyhkYXRhMyR4LCBkYXRhMyR5LCBwY2ggPTE2KQ0KbGluZXMoZGF0YTUkeCwgZGF0YTUkeSwgbHR5PTEpDQpwb2ludHMoZGF0YTUkeCwgZGF0YTUkeSwgcGNoID0xNSkNCmxpbmVzKGRhdGE4JHgsIGRhdGE4JHksIGx0eT0xKQ0KcG9pbnRzKGRhdGE4JHgsIGRhdGE4JHksIHBjaCA9MTcpDQpgYGANCg0KIyMgRGVmaW5lZCBCZW5lZml0cyBQbGFuDQogIFRoZSBTVVJTIERlZmluZWQgQ29udHJpYnV0aW9uIFBsYW4gaXMga25vd24gYXMgdGhlIFRyYWRpdGlvbmFsIFRSRCkgUGxhbi4gVGhpcyB0eXBlIG9mIHBsYW4gaXMgYWxzbyByZWZlcnJlZCB0byBhcyBQZW5zaW9uLiBJbiB0aGlzIGZvcm0gb2YgcmV0aXJlbWVudCwgYW5udWFsIHBheW1lbnRzIGZyb20gb25lJ3MgZW1wbG95ZXJzIGlzIGdpdmVuIHRvIHRoZSBlbXBsb3llZSBldmVyeSB5ZWFyIHVudGlsIHRoZXkgZGllLiBUaGUgYW1vdW50IHBhaWQgcGVyIHllYXIgaXMgYmFzZWQgb24gYSBwZXJjZW50YWdlIG9mIHRoZSBlbXBsb3llZSdzIGhpZ2hlc3QtZWFybmluZyBzYWxhcnkgZHVyaW5nIHRoZWlyIGR1cmF0aW9uIG9mIHNlcnZpY2UuIEluIHRlcm1zIG9mIHRoZSBUUkQgIFBsYW4sIFNVUlMgcHJvdmlkZXMgMi4yJSBvZiB5b3VyIGF2ZXJhZ2VkIGZpbmFsIHNhbGFyeSAoKipDSVRBVElPTiBUTyBTVVJTKiopDQogIA0KICBGb3IgdGhlIE5QViBwbG90LCBgVGAgd2lsbCByYW5nZSBmcm9tIDEgdG8gMzAuIEl0IHdpbGwgYmUgdGhlIHgtYXhpcywgcmVwcmVzZW50aW5nIHRoZSBlbXBsb3llZSdzIGNvbnNlY3V0aXZlIFllYXJzIG9mIFNlcnZpY2UgdW5kZXIgU1VSUydzIFJldGlyZW1lbnQgU2F2aW5ncyBQbGFuLg0KICANCiMjIyBQYXJhbWV0ZXJzDQogIFRoZSBmb2xsb3dpbmcgRmFjdG9ycyBhcmUgcmVsZXZhbnQgdG8gdGhlIERlZmluZWQgQ29udHJpYnV0aW9uIHBsYW46DQogIA0KLSAgIGBtMGA6IEluaXRpYWwgU2FsYXJ5DQotICAgYGFgOiBBbm51YWwgU2FsYXJ5IEluY3JlYXNlDQotICAgYHBlbnNpb25gOiBhbm51YWwgcGVuc2lvbiBpbmNvbWUNCi0gICBgVGA6IER1cmF0aW9uIG9mIFNlcnZpY2UNCi0gICBgZGlzY291bnQucmA6IERpc2NvdW50IFJhdGUgDQoNClRoZSBmb3JtdWxhIGZvciBgcGVuc2lvbmAgdmFyaWVzIGZyb20gcGxhbiB0byBwbGFuLiBGb3IgdGhlIFRSRCBwbGFuLCBpdCBpcyBkZXRlcm1pbmVkIGJ5IHRoZSBwcm9kdWN0IG9mIHR3byB2YWx1ZXM6DQoNCi0gICBgYXZlLm1gOiBhdmVyYWdlIHNhbGFyeTsgYXZlcmFnZSBzYWxhcnkgb3ZlciB0aGUgZmluYWwgKjUqIHllYXJzIG9mIHNlcnZpY2UuDQotICAgYHBlbnNpb24ucGVyY2VudGA6IHRoZSBwZXJjZW50YWdlIG9mIGBhdmUubWAgdGhhdCBhbiBlbXBsb3llZSByZWNlaXZlcyBhbm51YWxseSBhcyBwZW5zaW9uIGZvciB0aGVpciByZXRpcmVtZW50LiBFeGFtcGxlOiBXaXRoIGEgcGVuc2lvbiByYXRlIG9mIDIuMiUsIGFmdGVyIDE2IHllYXJzIG9mIHNlcnZpY2UsIGFuIGVtcGxveWVlIGdhaW5zIDM1LjIlIG9mIHRoZWlyIGBhdmUubWAgYXMgdGhlaXIgcmV0aXJlbWVudCBwZW5zaW9uLg0KDQogIER1cmF0aW9uIG9mIFNlcnZpY2UgcmVwcmVzZW50cyB0aGUgeWVhcnMgb2YgU2VydmljZSB0aGF0IGFuIGVtcGxveWVlIHN0YXlzIHdpdGggYSBjb21wYW55IFRoaXMgYWZmZWN0cyBmb3IgaG93IGxvbmcgeW91IG1ha2UgIGNvbnRyaWJ1dGlvbnMgdG8geW91ciByZXRpcmVtZW50IGFjY291bnQsIHRoZSB3b3J0aCBvZiB0aGUgYWNjb3VudCBhdCByZXRpcmVtZW50Lg0KICANCiAgVGhlIERpc2NvdW50IFJhdGUgaXMgdGhlIHJhdGUgb2YgaW50ZXJlc3QgdGhhdCBpcyBhcHBsaWVkIHRvIGZ1dHVyZSBjYXNoIGZsb3dzIG9mIGFuIGludmVzdG1lbnQgdG8gY2FsY3VsYXRlIGl0cyBwcmVzZW50IHZhbHVlLiBFc3NlbnRpYWxseSwgaXQgZ2l2ZXMgYW4gZXhhY3QgdmFsdWUgb2Ygd2hhdCBhIGRvbGxhciB5b3UnbGwgaW4gdGhlIGZ1dHVyZSBpcyB3b3J0aCB0byBzb21lb25lIGN1cnJlbnRseS4NCiAgDQogIFRoZSBEaXNjb3VudCBSYXRlIGlzIGEgdmFyaWFibGUgYmV0d2VlbiBkaWZmZXJlbnQgZW50aXRpZXMsIGFuZCBzbyB0aGUgdHdvIHBsb3RzIGZvciBEQyByYXRlIHdpbGwgYmUgYDAuMDBgIGFuZCBgMC4wNGAuIFRoZSBkaXNjb3VudCByYXRlIHBhcmFtZXRlciBhY3R1YWxseSByZXByZXNlbnRzIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGRpc2NvdW50IHJhdGUgYW5kIHRoZSBhbm51YWwgc2FsYXJ5IGluY3JlYXNlIHJhdGUuIFRoZSBkaXNjb3VudCByYXRlIHJlcHJlc2VudHMgdGhlIHJhdGUgb2YgcmV0dXJuIHVzZWQgdG8gZGlzY291bnQgZnV0dXJlIHByb2ZpdHMgdG8gY2FsY3VsYXRlIHRoZSBjdXJyZW50IHZhbHVlIG9mIGFuIGludmVzdG1lbnQuIFRoaXMgcmF0ZSBpcyBvZmZzZXQgYnkgdGhlIHNhbGFyeSBpbmNyZWFzZSByYXRlICwgc2luY2UgKCpJTlNFUlQgUkVTQVNPTiBIRVJFKikuDQogIA0KVGhlIGluaXRpYWwgcGFyYW1ldGVycyBhcmUgYXMgc2hvd24uDQpgYGB7cn0NCm0wID0gNjAwMDANCmEgPSAwLjAzDQpUID0gMzANCnBlbnNpb24ucGVyY2VudCA9IDIuMi8xMDANCmRpc2NvdW50LnIgPSAwDQpgYGAgIA0KDQojIyMgQ29kZQ0KLSAgIGB4VmFsdWVzYDogQWdlcyBvZiBTZXBhcmF0aW9uIHdpdGggY29uc2VjdXRpdmUgeWVhcnMgb2Ygc2VydmljZQ0KDQotICAgYHlWYWx1ZXNgOiBBY2NvdW50IEJhbGFuY2UgYXQgYWdlIDYyDQoNClN0ZXAgMTogQ29tcHV0ZSB0aGUgYW5udWFsIHBlbnNpb24gaW5jb21lIGJ5IHRha2luZyB0aGUgcHJvZHVjdCBvZiBgYXZlLm1gIGFuZCBgcGVuc2lvbi5wZXJjZW50YA0KDQpTdGVwIDI6IGNvbXB1dGUgdGhlICgqKmV4cGVjdGVkKiopIE5QViBvZiB0aGUgc3RyZWFtIG9mIHBlbnNpb24gaW5jb21lIGZyb20gYWdlIDYzIHRvIGFnZSAxMTkgdXNpbmcgdGhlIFtBY3R1YXJpYWwgTGlmZSBUYWJsZV0oaHR0cHM6Ly93d3cuc3NhLmdvdi9vYWN0L1NUQVRTL3RhYmxlNGM2Lmh0bWwjZm4xKSBmcm9tIFNTQSB3ZWJzaXRlOyB3ZSB1c2UgdGhlIGNvbXBsZW1lbnQgb2YgZGVhdGggcmF0ZSwgYXZlcmFnZWQgb3ZlciBtYWxlIGFuZCBmZW1hbGUuIFRoZSBOUFYgZm9ybXVsYSBpcyBnaXZlbiBiZWxvdyAkJA0KICAgIFxzdW1fe1x0ZXh0e2FnZX0gPSA2M31eezExOX0gLi4uICA9IFxzdW1fe3QgPSA2My02Mn1eeygxMTkgLSA2Mil9IFx0ZXh0e2FubnVhbC1wZW5zaW9uLWluY29tZX0gXHRpbWVzIHBfdCBcdGltZXMgdl57dCAtIDAuNX0NCiAgICAkJCB3aGVyZSAkdiQgJCQgIA0KICAgIHYgPSBcZnJhY3sxfXsxICsgXHRleHR7ZGlzY291bnQucmF0ZX19DQogICAgJCQgaXMgdGhlIGRpc2NvdW50IGZhY3RvciBhbmQgJCQNCiAgICBcYmVnaW57YWxpZ25lZH0NCiAgICBwX3QgID0gJiBcbWF0aGJie1B9KFx0ZXh0e3N0aWxsIGFsaXZlIGF0IGFnZX0gKDYyK3QpIFxtaWQgXHRleHR7YWxpdmUgYXQgYWdlIH0gNjIpIFxcDQogICAgID0gJiBccXVhZCBcbWF0aGJie1B9KFx0ZXh0e3N1cnZlIGZvciBhIHllYXJ9IFxtaWQgIFx0ZXh0e2FsaXZlIGF0IGFnZSB9IDYyKSBcXA0KICAgICAmIFx0aW1lcyAgXG1hdGhiYntQfShcdGV4dHtzdXJ2ZSBmb3IgYSB5ZWFyfSBcbWlkIFx0ZXh0e2FsaXZlIGF0IGFnZSB9IDYzKSBcdGltZXMgXFwNCiAgICAmIFx0aW1lcyBcY2RvdHMgXHRpbWVzIFxtYXRoYmJ7UH0oXHRleHR7c3VydmUgZm9yIGEgeWVhcn0gXG1pZCBcdGV4dHthbGl2ZSBhdCBhZ2UgfSA2Mit0LTEpIFxcDQogICAgPSAmIFxwcm9kX3tqPTF9XnQgXEJpZyBbIDEgLSAgXG1hdGhiYntQfSBcYmlnIChcdGV4dHtkaWUgd2l0aGluIGEgeWVhciB9IFxtaWQgXHRleHR7YWxpdmUgYXQgYWdlIH0gKDYyICsgai0xKSBcYmlnICkgXEJpZyBdLg0KICAgIFxlbmR7YWxpZ25lZH0NCiAgICAkJA0KVG8gY29tcHV0ZSB0aGUgc3Vydml2YWwgcHJvYmFiaWxpdGllcywgSSBpbXBvcnRlZCB0aGUgU1NBIGxpZmUgdGFibGUgaW50byBteSBlbnZpcm9ubWVudC4NCiANCmBgYHtyfQ0KZGF0YSA9IHJlYWQudGFibGUoIm10YWJsZS50eHQiLCBzZXA9Ilx0IikNCm5hbWVzKGRhdGEpDQpuYW1lcyhkYXRhKSA9IGMoIkFnZSIsICJtLnByb2IiLCAibS5saXZlcyIsICJtLmV4cCIsICJmLnByb2IiLCAiZi5saXZlcyIsICJmLmV4cCIpDQpoZWFkKGRhdGEpDQpuZXdkYXRhID0gZGF0YS5mcmFtZShBZ2UgPSBkYXRhJEFnZSwgIHByb2IgPSBkYXRhJG0ucHJvYiArIGRhdGEkZi5wcm9iKQ0KcHJvYnMgPSBuZXdkYXRhJHByb2JbbmV3ZGF0YSRBZ2UgPj0gNjJdDQpybSgiZGF0YSIsICJuZXdkYXRhIikNCmBgYA0KDQpUaGVuLCB1c2luZyB0aGUgbWV0aG9kcyBsaXN0ZWQgYWJvdmUsIEkgY29tcHV0ZWQgdGhlIE5QViBmb3IgdGhlIFRSRCBQbGFuLg0KDQpgYGB7cn0NCkJhbGFuY2VEQiA9IGZ1bmN0aW9uKFQsIGRpc2NvdW50LnIpew0KICB4VmFsdWVzID0gYygxOlQpICsgMzINCiAgeVZhbHVlcyA9IHJlcCgwLCBUKQ0KICBpZiAoVCA8IDYpew0KICAgIHJldHVybihkYXRhLmZyYW1lKHg9eFZhbHVlcywgeT15VmFsdWVzKSkNCiAgICBleGl0DQogIH0NCiAgcGVuc2lvbiA9IHJlcCAoMCxUKQ0KICBmb3IodCBpbiA2OlQpew0KICAgIHRtcCA9IHRhaWwoMTp0LCAyKQ0KICAgIGF2ZS5tID0gbWVhbihtMCooMSthKV4odG1wLTAuNSkpDQogICAgcGVuc2lvblt0XSA9IGF2ZS5tICogcGVuc2lvbi5wZXJjZW50ICogdA0KICAgIGlmIChwZW5zaW9uLnBlcmNlbnQgKiB0ID4gMC44KXsNCiAgICAgIHBlbnNpb25bdF0gPSBhdmUubSAqIDAuOA0KICAgIH0NCiAgfQ0KICANCnB0ID0gMQ0KdiA9IDEgLyAoMStkaXNjb3VudC5yKQ0KdnQgPSB2IF4oLTAuNSkNCmZvcih0IGluIDE6bGVuZ3RoKHByb2JzKSl7DQogIHB0ID0gcHQgKiAoMS1wcm9ic1t0XSkNCiAgdnQgPSB2dCAqIHYNCiAgeVZhbHVlcyA9IHlWYWx1ZXMgKyBwZW5zaW9uICogcHQgKiB2dA0KICAgIA0KICB9DQogIHJldHVybihkYXRhLmZyYW1lKHggPSB4VmFsdWVzLCB5ID0geVZhbHVlcykpDQp9DQpgYGANCg0KIyMjUGxvdA0KDQpgYGB7cn0NCmRhdGFEQjAgPSBCYWxhbmNlREIoVCwgMCkNCmRhdGFEQjQgPSBCYWxhbmNlREIoVCwgMC4wNCkNCnggPSBkYXRhREIwJHgNCnkgPSBkYXRhREIwJHkNCnBsb3QoeCwgeSwgdHlwZT0ibiIsIHlheHQ9Im4iLA0KICAgICB4bGFiID0gIlllYXJzIG9mIFNlcnZpY2UiLA0KICAgICB5bGFiID0gIlBlbnNpb24gV2VhbHRoIChpbiBEb2xsYXJzKSIsDQogICAgIG1haW4gPSAiTmV0IFByZXNlbnQgVmFsdWUgb2YgREMgQmVuZWZpdHMgYXQgYWdlIDYyIikNCmxpbmVzKGRhdGFEQjAkeCwgZGF0YURCMCR5LCBsdHkgPSA1KQ0KbGluZXMoZGF0YURCNCR4LCBkYXRhREI0JHksIGx0eSA9IDMpDQoNCnl0aWNrID0gKDE6MTUpICogMTAwMDAwDQpheGlzKDIsIGF0ID0geXRpY2ssIGxhcyA9IDIsIGNleC5heGlzID0gMC42LA0KICAgICBsYWJlbHMgPSBmb3JtYXRDKHl0aWNrLCBiaWcubWFyayA9ICIsIiwgZm9ybWF0PSJmIiwgZGlnaXRzID0gMCkpDQpgYGAg