Question: Customer Service Times (minutes)
The customer service call duration data set originates from a major
telecommunications provider in North America, operating in a highly
competitive market where:
3.2, 5.8, 7.1, 4.5, 10.3, 6.2, 8.7, 5.1, 12.5, 6.9,
9.4, 5.7, 11.8, 4.9, 9.1, 6.5, 13.2, 7.8, 10.6, 6.1,
8.9, 5.4, 12.1, 7.3, 9.8, 5.9, 11.4, 6.8, 10.9, 7.5,
4.2, 8.3, 6.4, 14.1, 5.6, 9.7, 7.9, 11.1, 6.7, 10.2,
5.3, 8.6, 7.2, 12.9, 6.3, 9.3, 8.1, 13.7, 7.6, 10.8
Assuming the data follow a one-parameter Lindley distribution,
construct a \(95\%\) confidence
interval for the parameter \(\theta\)
using the provided data and the specified methods. For each of the
following questions, first describe your reasoning process for the
analysis, then write code to perform the actual analysis. Finally,
summarize the results to conclude the question.
- Construct a 95% asymptotic confidence interval
based on the asymptotic sampling distribution of the maximum likelihood
estimator (MLE) of \(\theta\).
- Describe reasoning process for the analysis
We identify the appropriate confidence interval to be approximated
with a normal distribution with an assumed large sample size through the
asymptotic confidence interval.
Since the variance for the Lindley distribution cannot be directly
assumed/found hence being a combined distribution type, we use the
Fisher Information to learn more about the information the variance can
hold for the Asymptotic Confidence Interval.The use the Fisher
information for calculations for the variance and standard error to
calculate the confidence intervals.
Mathematical Algorithm
Sort and mean the call times dataset
find the length of the dataset
Calulate the predicted theta parameter for the dataset
Calculate the Fisher Information
Calculate the variance treating the fisher information as the theta of interset for the standardization equation assuming normal distrubution
Construct the confidence interval assuming normal distrubution
calltimes= sort(c(3.2, 5.8, 7.1, 4.5, 10.3, 6.2, 8.7, 5.1, 12.5, 6.9,
9.4, 5.7, 11.8, 4.9, 9.1, 6.5, 13.2, 7.8, 10.6, 6.1,
8.9, 5.4, 12.1, 7.3, 9.8, 5.9, 11.4, 6.8, 10.9, 7.5,
4.2, 8.3, 6.4, 14.1, 5.6, 9.7, 7.9, 11.1, 6.7, 10.2,
5.3, 8.6, 7.2, 12.9, 6.3, 9.3, 8.1, 13.7, 7.6, 10.8))
n = length(calltimes)
mean_call = mean(calltimes)
theta_predict = ((1 - mean_call) + sqrt((mean_call^2 + 6*mean_call + 1))) / (2 * mean_call) #Closed form of the MLE for theta
#First we find the asymptotic distribution prediction parameter
#Goal construct CI for theta --> Asymptotic Confidence Intervals
##Calculating the fisher information for MLE theta
##---
###Building the denominator of the STANDARDIZE (theta_hat - theta)/ sqrt(hat.var(theta))
fisherInfo= (2/theta_predict^2)-(1/ (1+ theta_predict)^2) # a measurement to help measure variance
#Calculate the variance of the estimator
theta_variance =1/ (n*fisherInfo)
#Calculate standard error (sqrt(varience))
se_theta = sqrt(theta_variance)
#Calculating the Asymptotic CIs
#Construct CI
#z crit is set to 0.975 bc alpha =0.05 --> (100%-(5%/2) = 97.5% =0.975
z = qnorm(0.975)
lower_ci= theta_predict - z * se_theta
upper_ci = theta_predict + z * se_theta
asym_bounds=c(lower_ci, upper_ci)
width_asym = upper_ci -lower_ci
cat("Asymptotic 95% Confidence Interval: [", asym_bounds, "]")
Asymptotic 95% Confidence Interval: [ 0.1758057 0.2623931 ]
#---------------------------------try
#Find asymptotic distribution:
#qnorm()
#Standardize
#(theta_predict-calltimes)/sqrt(var(calltimes))
#Construct CI
#z crit is set to 0.975 bc alpha =0.05 --> (100%-(5%/2) = 97.5% =0.975
#z = qnorm(0.975)
#theta_predict +
Summarize results for question 1a \ The MLE
parameter \(\theta\) = 0.2190994has a
asymptotic 95%CI [0.1758057, 0.2623931]. The 95%CI bounds include the
predicted parameter within its bounds nor do the bounds contain 0
suggesting some strength to the value of ranges the MLE parameter can
take on. The difference between the confidence interval ( 0.2623931 -
0.1758057) has an width of 0.0865874, which by the naked eye can appear
to be a small number suggesting stronger relevance with statistical
significance. Using the asymptotic distribution the telemarketer call
time is estimated to be 0.2190994 and we are 95% confident the true call
time is between [0.1758057, 0.2623931].
- Construct a 95% likelihood ratio confidence
interval for \(\theta\).
- Describe reasoning process for the analysis
We use likelihood ratio confidence intervals to construct confidence
intervals for parameters in parametric models. Likelihood ratio
confidence intervals present strong accurate interval suited for small
and moderate sample sizes and are even more accurate than asymptotic
normality confidence intervals.
Mathematical Algorithm
Sort and mean of the call times dataset
Find the number of (length) of values in the call times dataset
Calculate the predicted parameter value for the MLE
-In most cases find the derivative in respect to the parameter (not needed with example given)
Find the maximum log likelihood
Use the maximum log likelihood to find the likelihood ratio statistic
Use the chi square distrubution as quantiled to estimate the interval endpoints to define the confidence intervals for theta
Define the 95%CI for the Lindley (Call times) Distrubution
calltimes= sort(c(3.2, 5.8, 7.1, 4.5, 10.3, 6.2, 8.7, 5.1, 12.5, 6.9,
9.4, 5.7, 11.8, 4.9, 9.1, 6.5, 13.2, 7.8, 10.6, 6.1,
8.9, 5.4, 12.1, 7.3, 9.8, 5.9, 11.4, 6.8, 10.9, 7.5,
4.2, 8.3, 6.4, 14.1, 5.6, 9.7, 7.9, 11.1, 6.7, 10.2,
5.3, 8.6, 7.2, 12.9, 6.3, 9.3, 8.1, 13.7, 7.6, 10.8))
n = length(calltimes)
mean_call = mean(calltimes)
#Find the MLE
theta_predict = ((1 - mean_call) + sqrt((mean_call^2 + 6*mean_call + 1))) / (2 * mean_call)
#we dont need to take the derivative in respect to theta & solve for theta
#to find the log likelihood function directly
#Compute the l_max from the log of the parameter
#The maximum log-likelihood:
l_max = n * log(theta_predict^2/(1+theta_predict)) + sum(log(1+calltimes)) -(theta_predict*sum(calltimes))
#Since we have the log likelihood we can find the log likelihood ratio
###Theta_like_ratio = 2 * (l_max - log(theta_predict)) ##REPLACE THIS WITH CODE
#Find the expected crit value for chi square distribution
crit = qchisq(0.95, 1) / 2
thres_height= l_max- crit
####################################################################
log_lik_lindley= function(theta, data)
{
n = length(data)
S = sum(data)
C = sum(log(1+data)) #constant term
return(
n * log(theta^2/(1+theta)) +sum(log(1 + data)) - (theta * sum(data))
)
}
#LR_statistic = 2 * (l_max - log_lik_lindley(theta, calltimes))
#Find bounds and check gaps between curves and target height
bounds = function(theta)
{
return(log_lik_lindley(theta, calltimes)-thres_height)
}
#Using uniroot() to find upper and lower bounds
theta_lower_bound = uniroot(bounds, interval= c(0.01, theta_predict))$root
theta_upper_bound = uniroot(bounds, interval = c(theta_predict, 1.0))$root
width_log= theta_upper_bound - theta_lower_bound
#defining the confidence interval
LR_CI = c(theta_lower_bound, theta_upper_bound)
#print(LR_CI)
cat("Log-Likelihood 95% Confidence Interval: [", LR_CI, "]")
Log-Likelihood 95% Confidence Interval: [ 0.1786338 0.265321 ]
theta_range = seq(0.1, 0.4, length.out = 100) #Data input range to cover the MLE
y_values = sapply(theta_range, bounds) #Calculate the 'height' for each theta using your bounds function #sapply tells R to run your function for every theta in the range
plot(theta_range, y_values, type = "l", lwd = 2, main = "LR Confidence Interval of Lindley Distrubution - Call times",
xlab = "Theta",
ylab = "")
abline(h=0, col = "blue")
theta_lower_bound = uniroot(bounds, interval= c(0.01, theta_predict))$root
theta_upper_bound = uniroot(bounds, interval = c(theta_predict, 1.0))$root
abline(v=c(theta_lower_bound, theta_upper_bound), col = "red")

Summarize results for question 1b \
The log likelihood distribution the telemarketer call time is
estimated to be 0.2190994 and we are 95% confident the true call time is
between [0.1786338, 0.265321]. The width between the confidence interval
is 0.0866872. The interval includes the MLE Parameter 0.2190994,
suggesting some accuracy for the confidence interval.
width_log < width_asym # FALSE log likelihood not a smaller range
[1] FALSE
- Assuming the two confidence intervals above are valid, compare them
in terms of performance and make a recommendation. Justify your
recommendation.
The confidence intervals using both asymptotic and log likelihood are
both comparable ranges that both hold the predicted MLE parameter
0.2190994 without , suggesting significance for both CI types. As the
asymptotic confidence interval are [0.1758057, 0.2623931] with a width
of [0.0865874] this is a slightly more narrow width than the log
likelihood ratio CI at [0.1786338, 0.265321] with a width of
[0.0866872].The slightly more narrow width of the asymptotic CI suggests
the likelihood ratio CI cannot fully capture the true distribution shape
of the Lindley distribution as well as the asymptotic CI can.
It should be noted that The log likelihood CI does not force shape as
strictly as the asymptotic distribution that follow exact distributions
such as standard normal, t or \(chi^2_1\) therefore log likelihood can
better fit the natural distribution of the data set and are often more
accurate than asymptotic normality, especially for a moderate sample
size such as the one we have in this data set. In most cases the log
likelihood CI ratio is more accurate than the asymptotic CI.
Considering the knowledge the log likelihood is usually the more
accurate CI, the wider width in the log likelihood CI may suggest an
balanced CI with more uncertainty rather than a lower quality in the CI
itself. The overall recommendation is to use the log likelihood due to
its resistance to being artificially narrow, unlike the asymptotic CI,
and yield more accurate CI’s. Since the Lindley Distribution holds some
skew in its distribution, using a CI type with the assumption normal or
parametric shape, like the asymptotic CI, may lead to artificial CI
widths due to its stronger reliance on approximation. The overall
recommendation is to use the log-likelihood ratio CI for the call time
data set due to its Lindley Distribution.
LS0tDQp0aXRsZTogIkFzc2lnbm1lbnQgNzogQ29uc3RydWN0aW5nIExpa2VsaWhvb2QgUmF0aW8gQ29uZmlkZW5jZSBJbnRlcnZhbCINCmF1dGhvcjogIkV6YW5hIFJpdmVycyAiDQpkYXRlOiAiIER1ZTogMy0yNCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogbm8NCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICBoaWdobGlnaHQ6IG1vbm9jaHJvbWUNCiAgICB0aGVtZTogc3BhY2VsYWINCiAgcGRmX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIGZpZ193aWR0aDogMw0KICAgIGZpZ19oZWlnaHQ6IDMNCiAgd29yZF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAga2VlcF9tZDogeWVzDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KDQpgYGB7Y3NzLCBlY2hvID0gRkFMU0V9DQojVE9DOjpiZWZvcmUgew0KICBjb250ZW50OiAiVGFibGUgb2YgQ29udGVudHMiOw0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1zaXplOiAxLjJlbTsNCiAgZGlzcGxheTogYmxvY2s7DQogIGNvbG9yOiBuYXZ5Ow0KICBtYXJnaW4tYm90dG9tOiAxMHB4Ow0KfQ0KDQoNCmRpdiNUT0MgbGkgeyAgICAgLyogdGFibGUgb2YgY29udGVudCAgKi8NCiAgICBsaXN0LXN0eWxlOnVwcGVyLXJvbWFuOw0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCn0NCg0KaDEudGl0bGUgeyAgICAvKiBsZXZlbCAxIGhlYWRlciBvZiB0aXRsZSAgKi8NCiAgZm9udC1zaXplOiAyMnB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KfQ0KDQpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE1cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogc3lzdGVtLXVpOw0KICBjb2xvcjogbmF2eTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDEgeyAvKiBIZWFkZXIgMSAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMjBweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmgyIHsgLyogSGVhZGVyIDIgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDMgeyAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTZweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQovKiBBZGQgZG90cyBhZnRlciBudW1iZXJlZCBoZWFkZXJzICovDQouaGVhZGVyLXNlY3Rpb24tbnVtYmVyOjphZnRlciB7DQogIGNvbnRlbnQ6ICIuIjsNCg0KYm9keSB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KLmhpZ2hsaWdodG1lIHsgYmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7IH0NCg0KcCB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KfQ0KYGBgDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBjb2RlIGNodW5rIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBSIGNvZGUsIHdhcm5pbmdzLCBhbmQgb3V0cHV0IA0KIyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZXMuDQppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikNCiAgIGxpYnJhcnkoa25pdHIpDQp9DQppZiAoIXJlcXVpcmUoInBhbmRlciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJwYW5kZXIiKQ0KICAgbGlicmFyeShwYW5kZXIpDQp9DQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikNCiAgbGlicmFyeShnZ3Bsb3QyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQ0KICBsaWJyYXJ5KHRpZHl2ZXJzZSkNCn0NCg0KaWYgKCFyZXF1aXJlKCJwbG90bHkiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJwbG90bHkiKQ0KICBsaWJyYXJ5KHBsb3RseSkNCn0NCg0KaWYgKCFyZXF1aXJlKCJWR0FNIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygiVkdBTSIpDQogIGxpYnJhcnkoVkdBTSkNCn0NCiMjIyMgVkdBTQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICAjIGluY2x1ZGUgY29kZSBjaHVuayBpbiB0aGUgb3V0cHV0IGZpbGUNCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgIyBzb21ldGltZXMsIHlvdSBjb2RlIG1heSBwcm9kdWNlIHdhcm5pbmcgbWVzc2FnZXMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgeW91IGNhbiBjaG9vc2UgdG8gaW5jbHVkZSB0aGUgd2FybmluZyBtZXNzYWdlcyBpbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRoZSBvdXRwdXQgZmlsZS4gDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFRSVUUsICAgICMgeW91IGNhbiBhbHNvIGRlY2lkZSB3aGV0aGVyIHRvIGluY2x1ZGUgdGhlIG91dHB1dA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluIHRoZSBvdXRwdXQgZmlsZS4NCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BDQogICAgICAgICAgICAgICAgICAgICAgKSAgDQpgYGANCiANCiBcDQogDQojIyAqKkFzc2lnbm1lbnQgT2JqZWN0aXZlcyoqIA0KDQoqIFJlaW5mb3JjZSB0aGUgbGlrZWxpaG9vZCBjb25jZXB0cyBhbmQgTUxFLg0KDQoqIFVuZGVyc3RhbmQgdGhlIGNvbmNlcHRzIG9mIGNvbmZpZGVuY2UgaW50ZXJ2YWxzLg0KDQoqIE1hc3RlciB0aGUgcHJvY2VzcyBvZiBmaW5kaW5nIGxpa2VsaWhvb2QgcmF0aW8gY29uZmlkZW5jZSBpbnRlcnZhbCBvZiB1bmtub3duIHBhcmFtZXRlci4NCg0KXA0KDQojIyAqKlBvbGljaWVzIG9mIFVzaW5nIEFJIFRvb2xzKioNCg0KKipQb2xpY3kgb24gQUkgVG9vbCBVc2UqKjogWW91IG11c3QgYWRoZXJlIHRvIHRoZSBBSSB0b29sIHBvbGljeSBzcGVjaWZpZWQgaW4gdGhlIGNvdXJzZSBzeWxsYWJ1cy4gVGhlIGRpcmVjdCBjb3B5aW5nIG9mIEFJLWdlbmVyYXRlZCBjb250ZW50IGlzIHN0cmljdGx5IHByb2hpYml0ZWQuIEFsbCBzdWJtaXR0ZWQgd29yayBtdXN0IHJlZmxlY3QgeW91ciBvd24gdW5kZXJzdGFuZGluZzsgd2hlcmUgZXh0ZXJuYWwgdG9vbHMgYXJlIGNvbnN1bHRlZCwgY29udGVudCBtdXN0IGJlIHRob3JvdWdobHkgcmVwaHJhc2VkIGFuZCBzeW50aGVzaXplZCBpbiB5b3VyIG93biB3b3Jkcy4NCg0KKipDb2RlIEluY2x1c2lvbiBSZXF1aXJlbWVudCoqOiBBbnkgY29kZSBpbmNsdWRlZCBpbiB5b3VyIGVzc2F5IG11c3QgYmUgcHJvcGVybHkgY29tbWVudGVkIHRvIGV4cGxhaW4gdGhlIHB1cnBvc2UgYW5kL29yIGV4cGVjdGVkIG91dHB1dCBvZiBrZXkgY29kZSBsaW5lcy4gU3VibWl0dGluZyBBSS1nZW5lcmF0ZWQgY29kZSB3aXRob3V0IG1lYW5pbmdmdWwsIHN0dWRlbnQtYWRkZWQgY29tbWVudHMgd2lsbCBub3QgYmUgYWNjZXB0ZWQuDQoNClwNCg0KKipPbmUgUGFyYW1ldGVyIExpbmRsZXkgRGlzdHJpYnV0aW9uKioNCg0KVGhlICoqTGluZGxleSBkaXN0cmlidXRpb24qKiBpcyBhICoqY29udGludW91cyBwcm9iYWJpbGl0eSBkaXN0cmlidXRpb24qKiBwcm9wb3NlZCBieSBELlYuIExpbmRsZXkgaW4gMTk1OC4gSXQgcmVwcmVzZW50cyBhICoqd2VpZ2h0ZWQgbWl4dHVyZSoqIG9mIGV4cG9uZW50aWFsIGFuZCBnYW1tYSBkaXN0cmlidXRpb25zLCBwcm92aWRpbmcgYSBmbGV4aWJsZSBzaW5nbGUtcGFyYW1ldGVyIG1vZGVsIGZvciBsaWZldGltZSBkYXRhLiANCg0KJCQNCmYoeDtcdGhldGEpID0gXGZyYWN7XHRoZXRhXjJ9ezErXHRoZXRhfSgxK3gpZV57LVx0aGV0YSB4fSwgXHF1YWQgeCA+IDAsIFxxdWFkIFx0aGV0YSA+IDANCiQkDQoNCndoZXJlICR4JCA9IHJhbmRvbSB2YXJpYWJsZSAoZS5nLiwgdGltZSwgc2l6ZSwgYW1vdW50KSBhbmQgJFx0aGV0YSQgPSBzaGFwZSBwYXJhbWV0ZXIgY29udHJvbGxpbmcgdGhlIGRpc3RyaWJ1dGlvbi4NCg0KR2l2ZW4gYW4gaW5kZXBlbmRlbnQgcmFuZG9tIHNhbXBsZSAkWF8xLCBYXzIsIFxkb3RzLCBYX24kOg0KDQokJA0KTChcdGhldGEpID0gXHByb2Rfe2k9MX1ebiBmKHhfaTtcdGhldGEpID0gXHByb2Rfe2k9MX1ebiBcbGVmdFsgXGZyYWN7XHRoZXRhXjJ9ezErXHRoZXRhfSAoMSArIHhfaSkgZV57LVx0aGV0YSB4X2l9IFxyaWdodF0uDQokJA0KDQpMZXQgJFMgPSBcc3VtX3tpPTF9Xm4geF9pJCwgJFxiYXJ7eH0gPSBTL24kLCAgYW5kICRDID0gXHN1bV97aT0xfV5uIFxsbigxICsgeF9pKSQgKGNvbnN0YW50IHdpdGggcmVzcGVjdCB0byAkXHRoZXRhJCk6DQoNCiQkDQpcZWxsKFx0aGV0YSkgPSBcbG4gTChcdGhldGEpID0gbiBcbG5cbGVmdCggXGZyYWN7XHRoZXRhXjJ9ezErXHRoZXRhfSBccmlnaHQpICsgQyAtIFx0aGV0YSBTLg0KJCQNCg0KQWZ0ZXIgc29tZSBhbGdlYnJhLCB3ZSBvYnRhaW4gdGhlIGNsb3NlZCBmb3JtIG9mIHRoZSBNTEUgb2YgJFx0aGV0YSQgaW4gdGhlIGZvbGxvd2luZw0KDQokJA0KXGJveGVke1xoYXR7XHRoZXRhfSA9IFxmcmFjezEgLSBcYmFye3h9ICsgXHNxcnR7XGJhcnt4fV4yICsgNlxiYXJ7eH0gKyAxfX17MlxiYXJ7eH19fQ0KJCQNCg0KQXMgZ29vZCBleGVyY2lzZSwgd2UgY2FuIGRlcml2ZSB0aGUgZm9sbG93aW5nIEZpc2hlciBpbmZvcm1hdGlvbiBvZiAkXHRoZXRhJDoNCg0KJCQNClxib3hlZHtJKFx0aGV0YSkgPSBcZnJhY3syfXtcdGhldGFeMn0gLSBcZnJhY3sxfXsoMStcdGhldGEpXjJ9fQ0KJCQNCg0KDQpcDQoNCjxmb250IGNvbG9yID0gImJsdWUiPioqVGhpcyBhc3NpZ25tZW50IGZvY3VzZXMgb24gY29uc3RydWN0aW5nIHZhcmlvdXMgY29uZmlkZW5jZSBpbnRlcnZhbHMgb2YgdGhlIHNoYXBlIHBhcmFtZXRlciAkXHRoZXRhJCBpbiB0aGUgTGluZGxleSBkaXN0cmlidXRpb24uKio8L2ZvbnQ+DQoNCg0KXA0KDQojIyAqKlF1ZXN0aW9uOiBDdXN0b21lciBTZXJ2aWNlIFRpbWVzIChtaW51dGVzKSoqDQoNClRoZSBjdXN0b21lciBzZXJ2aWNlIGNhbGwgZHVyYXRpb24gZGF0YSBzZXQgb3JpZ2luYXRlcyBmcm9tIGEgbWFqb3IgdGVsZWNvbW11bmljYXRpb25zIHByb3ZpZGVyIGluIE5vcnRoIEFtZXJpY2EsIG9wZXJhdGluZyBpbiBhIGhpZ2hseSBjb21wZXRpdGl2ZSBtYXJrZXQgd2hlcmU6DQoNCmBgYA0KMy4yLCA1LjgsIDcuMSwgNC41LCAxMC4zLCA2LjIsIDguNywgNS4xLCAxMi41LCA2LjksDQo5LjQsIDUuNywgMTEuOCwgNC45LCA5LjEsIDYuNSwgMTMuMiwgNy44LCAxMC42LCA2LjEsDQo4LjksIDUuNCwgMTIuMSwgNy4zLCA5LjgsIDUuOSwgMTEuNCwgNi44LCAxMC45LCA3LjUsDQo0LjIsIDguMywgNi40LCAxNC4xLCA1LjYsIDkuNywgNy45LCAxMS4xLCA2LjcsIDEwLjIsDQo1LjMsIDguNiwgNy4yLCAxMi45LCA2LjMsIDkuMywgOC4xLCAxMy43LCA3LjYsIDEwLjgNCmBgYA0KDQpBc3N1bWluZyB0aGUgZGF0YSBmb2xsb3cgYSBvbmUtcGFyYW1ldGVyIExpbmRsZXkgZGlzdHJpYnV0aW9uLCBjb25zdHJ1Y3QgYSAkOTVcJSQgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgdGhlIHBhcmFtZXRlciAkXHRoZXRhJCB1c2luZyB0aGUgcHJvdmlkZWQgZGF0YSBhbmQgdGhlIHNwZWNpZmllZCBtZXRob2RzLiBGb3IgZWFjaCBvZiB0aGUgZm9sbG93aW5nIHF1ZXN0aW9ucywgZmlyc3QgZGVzY3JpYmUgeW91ciByZWFzb25pbmcgcHJvY2VzcyBmb3IgdGhlIGFuYWx5c2lzLCB0aGVuIHdyaXRlIGNvZGUgdG8gcGVyZm9ybSB0aGUgYWN0dWFsIGFuYWx5c2lzLiBGaW5hbGx5LCBzdW1tYXJpemUgdGhlIHJlc3VsdHMgdG8gY29uY2x1ZGUgdGhlIHF1ZXN0aW9uLg0KDQoNCmEpIENvbnN0cnVjdCBhICoqOTUlIGFzeW1wdG90aWMgY29uZmlkZW5jZSBpbnRlcnZhbCoqIGJhc2VkIG9uIHRoZSBhc3ltcHRvdGljIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiB0aGUgbWF4aW11bSBsaWtlbGlob29kIGVzdGltYXRvciAoTUxFKSBvZiAkXHRoZXRhJC4NCg0KDQotIERlc2NyaWJlIHJlYXNvbmluZyBwcm9jZXNzIGZvciB0aGUgYW5hbHlzaXMNCg0KV2UgaWRlbnRpZnkgdGhlIGFwcHJvcHJpYXRlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgdG8gYmUgYXBwcm94aW1hdGVkIHdpdGggYSBub3JtYWwgZGlzdHJpYnV0aW9uIHdpdGggYW4gYXNzdW1lZCBsYXJnZSBzYW1wbGUgc2l6ZSB0aHJvdWdoIHRoZSBhc3ltcHRvdGljIGNvbmZpZGVuY2UgaW50ZXJ2YWwuIA0KDQpTaW5jZSB0aGUgdmFyaWFuY2UgZm9yIHRoZSBMaW5kbGV5IGRpc3RyaWJ1dGlvbiBjYW5ub3QgYmUgZGlyZWN0bHkgYXNzdW1lZC9mb3VuZCBoZW5jZSBiZWluZyBhIGNvbWJpbmVkIGRpc3RyaWJ1dGlvbiB0eXBlLCB3ZSB1c2UgdGhlIEZpc2hlciBJbmZvcm1hdGlvbiB0byBsZWFybiBtb3JlIGFib3V0IHRoZSBpbmZvcm1hdGlvbiB0aGUgdmFyaWFuY2UgY2FuIGhvbGQgZm9yIHRoZSBBc3ltcHRvdGljIENvbmZpZGVuY2UgSW50ZXJ2YWwuVGhlIHVzZSB0aGUgRmlzaGVyIGluZm9ybWF0aW9uIGZvciBjYWxjdWxhdGlvbnMgZm9yIHRoZSB2YXJpYW5jZSBhbmQgc3RhbmRhcmQgZXJyb3IgdG8gY2FsY3VsYXRlIHRoZSBjb25maWRlbmNlIGludGVydmFscy4gDQoNCioqTWF0aGVtYXRpY2FsIEFsZ29yaXRobSoqDQpgYGANClNvcnQgYW5kIG1lYW4gdGhlIGNhbGwgdGltZXMgZGF0YXNldA0KZmluZCB0aGUgbGVuZ3RoIG9mIHRoZSBkYXRhc2V0DQpDYWx1bGF0ZSB0aGUgcHJlZGljdGVkIHRoZXRhIHBhcmFtZXRlciBmb3IgdGhlIGRhdGFzZXQNCkNhbGN1bGF0ZSB0aGUgRmlzaGVyIEluZm9ybWF0aW9uDQpDYWxjdWxhdGUgdGhlIHZhcmlhbmNlIHRyZWF0aW5nIHRoZSBmaXNoZXIgaW5mb3JtYXRpb24gYXMgdGhlIHRoZXRhIG9mIGludGVyc2V0IGZvciB0aGUgc3RhbmRhcmRpemF0aW9uIGVxdWF0aW9uIGFzc3VtaW5nIG5vcm1hbCBkaXN0cnVidXRpb24NCkNvbnN0cnVjdCB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCBhc3N1bWluZyBub3JtYWwgZGlzdHJ1YnV0aW9uIA0KDQpgYGANCg0KDQpgYGB7cn0NCg0KY2FsbHRpbWVzPSBzb3J0KGMoMy4yLCA1LjgsIDcuMSwgNC41LCAxMC4zLCA2LjIsIDguNywgNS4xLCAxMi41LCA2LjksDQo5LjQsIDUuNywgMTEuOCwgNC45LCA5LjEsIDYuNSwgMTMuMiwgNy44LCAxMC42LCA2LjEsDQo4LjksIDUuNCwgMTIuMSwgNy4zLCA5LjgsIDUuOSwgMTEuNCwgNi44LCAxMC45LCA3LjUsDQo0LjIsIDguMywgNi40LCAxNC4xLCA1LjYsIDkuNywgNy45LCAxMS4xLCA2LjcsIDEwLjIsDQo1LjMsIDguNiwgNy4yLCAxMi45LCA2LjMsIDkuMywgOC4xLCAxMy43LCA3LjYsIDEwLjgpKQ0KDQpuID0gbGVuZ3RoKGNhbGx0aW1lcykNCg0KbWVhbl9jYWxsID0gbWVhbihjYWxsdGltZXMpDQoNCnRoZXRhX3ByZWRpY3QgPSAoKDEgLSBtZWFuX2NhbGwpICsgc3FydCgobWVhbl9jYWxsXjIgKyA2Km1lYW5fY2FsbCArIDEpKSkgLyAoMiAqIG1lYW5fY2FsbCkgI0Nsb3NlZCBmb3JtIG9mIHRoZSBNTEUgZm9yIHRoZXRhDQoNCiNGaXJzdCB3ZSBmaW5kIHRoZSBhc3ltcHRvdGljIGRpc3RyaWJ1dGlvbiBwcmVkaWN0aW9uIHBhcmFtZXRlcg0KDQojR29hbCBjb25zdHJ1Y3QgQ0kgZm9yIHRoZXRhIC0tPiBBc3ltcHRvdGljIENvbmZpZGVuY2UgSW50ZXJ2YWxzDQoNCiMjQ2FsY3VsYXRpbmcgdGhlIGZpc2hlciBpbmZvcm1hdGlvbiBmb3IgTUxFIHRoZXRhDQoNCiMjLS0tDQojIyNCdWlsZGluZyB0aGUgZGVub21pbmF0b3Igb2YgdGhlIFNUQU5EQVJESVpFICh0aGV0YV9oYXQgLSB0aGV0YSkvICBzcXJ0KGhhdC52YXIodGhldGEpKQ0KDQpmaXNoZXJJbmZvPSAoMi90aGV0YV9wcmVkaWN0XjIpLSgxLyAoMSsgdGhldGFfcHJlZGljdCleMikgIyBhIG1lYXN1cmVtZW50IHRvIGhlbHAgbWVhc3VyZSB2YXJpYW5jZSANCg0KDQoNCiNDYWxjdWxhdGUgdGhlIHZhcmlhbmNlIG9mIHRoZSBlc3RpbWF0b3INCnRoZXRhX3ZhcmlhbmNlID0xLyAobipmaXNoZXJJbmZvKQ0KDQojQ2FsY3VsYXRlIHN0YW5kYXJkIGVycm9yIChzcXJ0KHZhcmllbmNlKSkNCg0Kc2VfdGhldGEgPSBzcXJ0KHRoZXRhX3ZhcmlhbmNlKQ0KDQojQ2FsY3VsYXRpbmcgdGhlIEFzeW1wdG90aWMgQ0lzDQojQ29uc3RydWN0IENJDQojeiBjcml0IGlzIHNldCB0byAwLjk3NSBiYyBhbHBoYSA9MC4wNSAtLT4gKDEwMCUtKDUlLzIpID0gOTcuNSUgPTAuOTc1DQoNCnogPSBxbm9ybSgwLjk3NSkNCmxvd2VyX2NpPSB0aGV0YV9wcmVkaWN0IC0geiAqIHNlX3RoZXRhDQp1cHBlcl9jaSA9IHRoZXRhX3ByZWRpY3QgKyB6ICogc2VfdGhldGENCg0KYXN5bV9ib3VuZHM9Yyhsb3dlcl9jaSwgdXBwZXJfY2kpDQp3aWR0aF9hc3ltID0gdXBwZXJfY2kgLWxvd2VyX2NpDQoNCmNhdCgiQXN5bXB0b3RpYyA5NSUgQ29uZmlkZW5jZSBJbnRlcnZhbDogWyIsIGFzeW1fYm91bmRzLCAiXSIpDQoNCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS10cnkNCiNGaW5kIGFzeW1wdG90aWMgZGlzdHJpYnV0aW9uOg0KI3Fub3JtKCkNCg0KDQojU3RhbmRhcmRpemUNCg0KIyh0aGV0YV9wcmVkaWN0LWNhbGx0aW1lcykvc3FydCh2YXIoY2FsbHRpbWVzKSkNCg0KDQojQ29uc3RydWN0IENJDQojeiBjcml0IGlzIHNldCB0byAwLjk3NSBiYyBhbHBoYSA9MC4wNSAtLT4gKDEwMCUtKDUlLzIpID0gOTcuNSUgPTAuOTc1DQojeiA9IHFub3JtKDAuOTc1KQ0KDQojdGhldGFfcHJlZGljdCArDQoNCmBgYA0KDQoNCioqU3VtbWFyaXplIHJlc3VsdHMgZm9yIHF1ZXN0aW9uIDFhKiogXFwNClRoZSAgTUxFIHBhcmFtZXRlciAkXHRoZXRhJCA9IGByIHRoZXRhX3ByZWRpY3RgaGFzIGEgYXN5bXB0b3RpYyA5NSVDSSBbYHIgYXN5bV9ib3VuZHNgXS4gVGhlIDk1JUNJIGJvdW5kcyBpbmNsdWRlIHRoZSBwcmVkaWN0ZWQgcGFyYW1ldGVyIHdpdGhpbiBpdHMgYm91bmRzIG5vciBkbyB0aGUgYm91bmRzIGNvbnRhaW4gMCBzdWdnZXN0aW5nIHNvbWUgc3RyZW5ndGggdG8gdGhlIHZhbHVlIG9mIHJhbmdlcyB0aGUgTUxFIHBhcmFtZXRlciBjYW4gdGFrZSBvbi4gVGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCAoIDAuMjYyMzkzMSAtIDAuMTc1ODA1NykgaGFzIGFuIHdpZHRoIG9mIDAuMDg2NTg3NCwgd2hpY2ggYnkgdGhlIG5ha2VkIGV5ZSBjYW4gYXBwZWFyIHRvIGJlIGEgc21hbGwgbnVtYmVyIHN1Z2dlc3Rpbmcgc3Ryb25nZXIgcmVsZXZhbmNlIHdpdGggc3RhdGlzdGljYWwgc2lnbmlmaWNhbmNlLiBVc2luZyB0aGUgYXN5bXB0b3RpYyBkaXN0cmlidXRpb24gdGhlIHRlbGVtYXJrZXRlciBjYWxsIHRpbWUgaXMgZXN0aW1hdGVkIHRvIGJlIGByIHRoZXRhX3ByZWRpY3RgIGFuZCB3ZSBhcmUgOTUlIGNvbmZpZGVudCB0aGUgdHJ1ZSBjYWxsIHRpbWUgaXMgYmV0d2VlbiBbYHIgYXN5bV9ib3VuZHNgXS4gDQoNCg0KDQpiKSBDb25zdHJ1Y3QgYSAqKjk1JSBsaWtlbGlob29kIHJhdGlvIGNvbmZpZGVuY2UgaW50ZXJ2YWwqKiBmb3IgJFx0aGV0YSQuDQoNCi0gRGVzY3JpYmUgcmVhc29uaW5nIHByb2Nlc3MgZm9yIHRoZSBhbmFseXNpcw0KDQoNCldlIHVzZSBsaWtlbGlob29kIHJhdGlvIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIHRvIGNvbnN0cnVjdCBjb25maWRlbmNlIGludGVydmFscyBmb3IgcGFyYW1ldGVycyBpbiBwYXJhbWV0cmljIG1vZGVscy4gTGlrZWxpaG9vZCByYXRpbyBjb25maWRlbmNlIGludGVydmFscyBwcmVzZW50IHN0cm9uZyBhY2N1cmF0ZSBpbnRlcnZhbCBzdWl0ZWQgZm9yIHNtYWxsIGFuZCBtb2RlcmF0ZSBzYW1wbGUgc2l6ZXMgYW5kIGFyZSBldmVuIG1vcmUgYWNjdXJhdGUgdGhhbiBhc3ltcHRvdGljIG5vcm1hbGl0eSBjb25maWRlbmNlIGludGVydmFscy4NCg0KKipNYXRoZW1hdGljYWwgQWxnb3JpdGhtKioNCmBgYA0KU29ydCBhbmQgbWVhbiBvZiB0aGUgY2FsbCB0aW1lcyBkYXRhc2V0DQpGaW5kIHRoZSBudW1iZXIgb2YgKGxlbmd0aCkgb2YgdmFsdWVzIGluIHRoZSBjYWxsIHRpbWVzIGRhdGFzZXQNCkNhbGN1bGF0ZSB0aGUgcHJlZGljdGVkIHBhcmFtZXRlciB2YWx1ZSBmb3IgdGhlIE1MRQ0KLUluIG1vc3QgY2FzZXMgZmluZCB0aGUgZGVyaXZhdGl2ZSBpbiByZXNwZWN0IHRvIHRoZSBwYXJhbWV0ZXIgKG5vdCBuZWVkZWQgd2l0aCBleGFtcGxlIGdpdmVuKQ0KRmluZCB0aGUgbWF4aW11bSBsb2cgbGlrZWxpaG9vZA0KVXNlIHRoZSBtYXhpbXVtIGxvZyBsaWtlbGlob29kIHRvIGZpbmQgdGhlIGxpa2VsaWhvb2QgcmF0aW8gc3RhdGlzdGljDQpVc2UgdGhlIGNoaSBzcXVhcmUgZGlzdHJ1YnV0aW9uIGFzIHF1YW50aWxlZCB0byBlc3RpbWF0ZSB0aGUgaW50ZXJ2YWwgZW5kcG9pbnRzIHRvIGRlZmluZSB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbHMgZm9yIHRoZXRhDQpEZWZpbmUgdGhlIDk1JUNJIGZvciB0aGUgTGluZGxleSAoQ2FsbCB0aW1lcykgRGlzdHJ1YnV0aW9uIA0KDQoNCmBgYA0KDQoNCmBgYHtyfQ0KDQpjYWxsdGltZXM9IHNvcnQoYygzLjIsIDUuOCwgNy4xLCA0LjUsIDEwLjMsIDYuMiwgOC43LCA1LjEsIDEyLjUsIDYuOSwNCjkuNCwgNS43LCAxMS44LCA0LjksIDkuMSwgNi41LCAxMy4yLCA3LjgsIDEwLjYsIDYuMSwNCjguOSwgNS40LCAxMi4xLCA3LjMsIDkuOCwgNS45LCAxMS40LCA2LjgsIDEwLjksIDcuNSwNCjQuMiwgOC4zLCA2LjQsIDE0LjEsIDUuNiwgOS43LCA3LjksIDExLjEsIDYuNywgMTAuMiwNCjUuMywgOC42LCA3LjIsIDEyLjksIDYuMywgOS4zLCA4LjEsIDEzLjcsIDcuNiwgMTAuOCkpDQoNCm4gPSBsZW5ndGgoY2FsbHRpbWVzKQ0KDQptZWFuX2NhbGwgPSBtZWFuKGNhbGx0aW1lcykNCg0KI0ZpbmQgdGhlIE1MRQ0KdGhldGFfcHJlZGljdCA9ICgoMSAtIG1lYW5fY2FsbCkgKyBzcXJ0KChtZWFuX2NhbGxeMiArIDYqbWVhbl9jYWxsICsgMSkpKSAvICgyICogbWVhbl9jYWxsKSANCg0KI3dlIGRvbnQgbmVlZCB0byB0YWtlIHRoZSBkZXJpdmF0aXZlIGluIHJlc3BlY3QgdG8gdGhldGEgJiBzb2x2ZSBmb3IgdGhldGENCiN0byBmaW5kIHRoZSBsb2cgbGlrZWxpaG9vZCBmdW5jdGlvbiBkaXJlY3RseQ0KDQoNCiNDb21wdXRlIHRoZSBsX21heCBmcm9tIHRoZSBsb2cgb2YgdGhlIHBhcmFtZXRlcg0KDQojVGhlIG1heGltdW0gbG9nLWxpa2VsaWhvb2Q6DQpsX21heCA9IG4gKiBsb2codGhldGFfcHJlZGljdF4yLygxK3RoZXRhX3ByZWRpY3QpKSArIHN1bShsb2coMStjYWxsdGltZXMpKSAtKHRoZXRhX3ByZWRpY3Qqc3VtKGNhbGx0aW1lcykpDQoNCiNTaW5jZSB3ZSBoYXZlIHRoZSBsb2cgbGlrZWxpaG9vZCB3ZSBjYW4gZmluZCB0aGUgbG9nIGxpa2VsaWhvb2QgcmF0aW8NCg0KIyMjVGhldGFfbGlrZV9yYXRpbyA9IDIgKiAobF9tYXggLSBsb2codGhldGFfcHJlZGljdCkpICAjI1JFUExBQ0UgVEhJUyBXSVRIIENPREUNCg0KI0ZpbmQgdGhlIGV4cGVjdGVkIGNyaXQgdmFsdWUgZm9yIGNoaSBzcXVhcmUgZGlzdHJpYnV0aW9uIA0KY3JpdCA9IHFjaGlzcSgwLjk1LCAxKSAvIDIgDQoNCnRocmVzX2hlaWdodD0gbF9tYXgtIGNyaXQNCg0KDQoNCg0KDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KbG9nX2xpa19saW5kbGV5PSBmdW5jdGlvbih0aGV0YSwgZGF0YSkNCnsNCiAgbiA9IGxlbmd0aChkYXRhKQ0KICBTID0gc3VtKGRhdGEpDQogIEMgPSBzdW0obG9nKDErZGF0YSkpICNjb25zdGFudCB0ZXJtDQogIHJldHVybiggDQogICAgbiAqIGxvZyh0aGV0YV4yLygxK3RoZXRhKSkgK3N1bShsb2coMSArIGRhdGEpKSAtICh0aGV0YSAqIHN1bShkYXRhKSkNCiAgICANCiAgICApDQoNCiAgDQp9DQoNCg0KI0xSX3N0YXRpc3RpYyA9IDIgKiAobF9tYXggLSBsb2dfbGlrX2xpbmRsZXkodGhldGEsIGNhbGx0aW1lcykpDQoNCiNGaW5kIGJvdW5kcyBhbmQgY2hlY2sgZ2FwcyBiZXR3ZWVuIGN1cnZlcyBhbmQgdGFyZ2V0IGhlaWdodA0KDQpib3VuZHMgPSBmdW5jdGlvbih0aGV0YSkNCnsNCiAgDQogIHJldHVybihsb2dfbGlrX2xpbmRsZXkodGhldGEsIGNhbGx0aW1lcyktdGhyZXNfaGVpZ2h0KQ0KICANCn0NCg0KI1VzaW5nIHVuaXJvb3QoKSB0byBmaW5kIHVwcGVyIGFuZCBsb3dlciBib3VuZHMNCg0KdGhldGFfbG93ZXJfYm91bmQgPSB1bmlyb290KGJvdW5kcywgaW50ZXJ2YWw9IGMoMC4wMSwgdGhldGFfcHJlZGljdCkpJHJvb3QNCnRoZXRhX3VwcGVyX2JvdW5kID0gdW5pcm9vdChib3VuZHMsIGludGVydmFsID0gYyh0aGV0YV9wcmVkaWN0LCAxLjApKSRyb290DQoNCndpZHRoX2xvZz0gdGhldGFfdXBwZXJfYm91bmQgLSB0aGV0YV9sb3dlcl9ib3VuZA0KDQojZGVmaW5pbmcgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwNCg0KTFJfQ0kgPSBjKHRoZXRhX2xvd2VyX2JvdW5kLCB0aGV0YV91cHBlcl9ib3VuZCkNCiNwcmludChMUl9DSSkNCg0KY2F0KCJMb2ctTGlrZWxpaG9vZCA5NSUgQ29uZmlkZW5jZSBJbnRlcnZhbDogWyIsIExSX0NJLCAiXSIpDQoNCnRoZXRhX3JhbmdlID0gc2VxKDAuMSwgMC40LCBsZW5ndGgub3V0ID0gMTAwKSAjRGF0YSBpbnB1dCByYW5nZSB0byBjb3ZlciB0aGUgTUxFDQoNCnlfdmFsdWVzID0gc2FwcGx5KHRoZXRhX3JhbmdlLCBib3VuZHMpICNDYWxjdWxhdGUgdGhlICdoZWlnaHQnIGZvciBlYWNoIHRoZXRhIHVzaW5nIHlvdXIgYm91bmRzIGZ1bmN0aW9uICNzYXBwbHkgdGVsbHMgUiB0byBydW4geW91ciBmdW5jdGlvbiBmb3IgZXZlcnkgdGhldGEgaW4gdGhlIHJhbmdlDQoNCg0KcGxvdCh0aGV0YV9yYW5nZSwgeV92YWx1ZXMsIHR5cGUgPSAibCIsIGx3ZCA9IDIsIG1haW4gPSAiTFIgQ29uZmlkZW5jZSBJbnRlcnZhbCBvZiBMaW5kbGV5IERpc3RydWJ1dGlvbiAtIENhbGwgdGltZXMiLA0KICAgICB4bGFiID0gIlRoZXRhIiwNCiAgICAgeWxhYiA9ICIiKQ0KYWJsaW5lKGg9MCwgY29sID0gImJsdWUiKQ0KdGhldGFfbG93ZXJfYm91bmQgPSB1bmlyb290KGJvdW5kcywgaW50ZXJ2YWw9IGMoMC4wMSwgdGhldGFfcHJlZGljdCkpJHJvb3QNCnRoZXRhX3VwcGVyX2JvdW5kID0gdW5pcm9vdChib3VuZHMsIGludGVydmFsID0gYyh0aGV0YV9wcmVkaWN0LCAxLjApKSRyb290DQoNCmFibGluZSh2PWModGhldGFfbG93ZXJfYm91bmQsIHRoZXRhX3VwcGVyX2JvdW5kKSwgY29sID0gInJlZCIpDQoNCmBgYA0KDQoNCioqU3VtbWFyaXplIHJlc3VsdHMgZm9yIHF1ZXN0aW9uIDFiKiogIFxcDQoNCg0KDQpUaGUgbG9nIGxpa2VsaWhvb2QgZGlzdHJpYnV0aW9uIHRoZSB0ZWxlbWFya2V0ZXIgY2FsbCB0aW1lIGlzIGVzdGltYXRlZCB0byBiZSBgciB0aGV0YV9wcmVkaWN0YCBhbmQgd2UgYXJlIDk1JSBjb25maWRlbnQgdGhlIHRydWUgY2FsbCB0aW1lIGlzIGJldHdlZW4gW2ByIExSX0NJIGBdLiBUaGUgd2lkdGggYmV0d2VlbiB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCBpcyBgciB3aWR0aF9sb2dgLiBUaGUgaW50ZXJ2YWwgaW5jbHVkZXMgdGhlIE1MRSBQYXJhbWV0ZXIgYHIgdGhldGFfcHJlZGljdGAsIHN1Z2dlc3Rpbmcgc29tZSBhY2N1cmFjeSBmb3IgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwuIA0KDQpgYGB7cn0NCg0Kd2lkdGhfbG9nIDwgd2lkdGhfYXN5bSAjIEZBTFNFIGxvZyBsaWtlbGlob29kIG5vdCBhIHNtYWxsZXIgcmFuZ2UNCg0KYGBgDQpjKSBBc3N1bWluZyB0aGUgdHdvIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGFib3ZlIGFyZSB2YWxpZCwgY29tcGFyZSB0aGVtIGluIHRlcm1zIG9mIHBlcmZvcm1hbmNlIGFuZCBtYWtlIGEgcmVjb21tZW5kYXRpb24uIEp1c3RpZnkgeW91ciByZWNvbW1lbmRhdGlvbi4NCg0KDQpUaGUgY29uZmlkZW5jZSBpbnRlcnZhbHMgdXNpbmcgYm90aCBhc3ltcHRvdGljIGFuZCBsb2cgbGlrZWxpaG9vZCBhcmUgYm90aCBjb21wYXJhYmxlIHJhbmdlcyB0aGF0IGJvdGggaG9sZCB0aGUgcHJlZGljdGVkIE1MRSBwYXJhbWV0ZXIgYHIgdGhldGFfcHJlZGljdGAgd2l0aG91dCAsIHN1Z2dlc3Rpbmcgc2lnbmlmaWNhbmNlIGZvciBib3RoIENJIHR5cGVzLg0KQXMgdGhlIGFzeW1wdG90aWMgY29uZmlkZW5jZSBpbnRlcnZhbCBhcmUgW2ByIGFzeW1fYm91bmRzYF0gd2l0aCBhIHdpZHRoIG9mIFtgciB3aWR0aF9hc3ltYF0gdGhpcyBpcyBhIHNsaWdodGx5IG1vcmUgbmFycm93IHdpZHRoIHRoYW4gdGhlIGxvZyBsaWtlbGlob29kIHJhdGlvIENJIGF0IFtgciBMUl9DSWBdICB3aXRoIGEgd2lkdGggb2YgW2ByIHdpZHRoX2xvZ2BdLlRoZSBzbGlnaHRseSBtb3JlIG5hcnJvdyB3aWR0aCBvZiB0aGUgYXN5bXB0b3RpYyBDSSBzdWdnZXN0cyB0aGUgbGlrZWxpaG9vZCByYXRpbyBDSSBjYW5ub3QgZnVsbHkgY2FwdHVyZSB0aGUgdHJ1ZSBkaXN0cmlidXRpb24gc2hhcGUgb2YgdGhlIExpbmRsZXkgZGlzdHJpYnV0aW9uIGFzIHdlbGwgYXMgdGhlIGFzeW1wdG90aWMgQ0kgY2FuLiANCg0KDQpJdCBzaG91bGQgYmUgbm90ZWQgdGhhdCBUaGUgbG9nIGxpa2VsaWhvb2QgQ0kgZG9lcyBub3QgZm9yY2Ugc2hhcGUgYXMgc3RyaWN0bHkgYXMgdGhlIGFzeW1wdG90aWMgZGlzdHJpYnV0aW9uIHRoYXQgZm9sbG93IGV4YWN0IGRpc3RyaWJ1dGlvbnMgc3VjaCBhcyBzdGFuZGFyZCBub3JtYWwsIHQgb3IgJGNoaV4yXzEkIHRoZXJlZm9yZSBsb2cgbGlrZWxpaG9vZCBjYW4gYmV0dGVyIGZpdCB0aGUgbmF0dXJhbCBkaXN0cmlidXRpb24gb2YgdGhlIGRhdGEgc2V0IGFuZCBhcmUgb2Z0ZW4gIG1vcmUgYWNjdXJhdGUgdGhhbiBhc3ltcHRvdGljIG5vcm1hbGl0eSwgZXNwZWNpYWxseSBmb3IgYSBtb2RlcmF0ZSBzYW1wbGUgc2l6ZSBzdWNoIGFzIHRoZSBvbmUgd2UgaGF2ZSBpbiB0aGlzIGRhdGEgc2V0LiBJbiBtb3N0IGNhc2VzIHRoZSBsb2cgbGlrZWxpaG9vZCBDSSByYXRpbyBpcyBtb3JlIGFjY3VyYXRlIHRoYW4gdGhlIGFzeW1wdG90aWMgQ0kuDQoNCkNvbnNpZGVyaW5nIHRoZSBrbm93bGVkZ2UgdGhlIGxvZyBsaWtlbGlob29kIGlzIHVzdWFsbHkgdGhlIG1vcmUgYWNjdXJhdGUgQ0ksIHRoZSB3aWRlciB3aWR0aCBpbiB0aGUgbG9nIGxpa2VsaWhvb2QgQ0kgbWF5IHN1Z2dlc3QgYW4gYmFsYW5jZWQgQ0kgIHdpdGggbW9yZSB1bmNlcnRhaW50eSByYXRoZXIgdGhhbiBhIGxvd2VyIHF1YWxpdHkgaW4gdGhlIENJIGl0c2VsZi4NClRoZSBvdmVyYWxsIHJlY29tbWVuZGF0aW9uIGlzIHRvIHVzZSB0aGUgbG9nIGxpa2VsaWhvb2QgZHVlIHRvIGl0cyByZXNpc3RhbmNlIHRvIGJlaW5nIGFydGlmaWNpYWxseSBuYXJyb3csIHVubGlrZSB0aGUgYXN5bXB0b3RpYyBDSSwgYW5kIHlpZWxkIG1vcmUgYWNjdXJhdGUgQ0kncy4gU2luY2UgdGhlIExpbmRsZXkgRGlzdHJpYnV0aW9uIGhvbGRzIHNvbWUgc2tldyBpbiBpdHMgZGlzdHJpYnV0aW9uLCB1c2luZyBhIENJIHR5cGUgd2l0aCB0aGUgYXNzdW1wdGlvbiBub3JtYWwgb3IgcGFyYW1ldHJpYyBzaGFwZSwgbGlrZSB0aGUgYXN5bXB0b3RpYyBDSSwgbWF5IGxlYWQgdG8gYXJ0aWZpY2lhbCBDSSB3aWR0aHMgZHVlIHRvIGl0cyBzdHJvbmdlciByZWxpYW5jZSBvbiBhcHByb3hpbWF0aW9uLiBUaGUgb3ZlcmFsbCByZWNvbW1lbmRhdGlvbiBpcyB0byB1c2UgdGhlIGxvZy1saWtlbGlob29kIHJhdGlvIENJIGZvciB0aGUgY2FsbCB0aW1lIGRhdGEgc2V0IGR1ZSB0byBpdHMgTGluZGxleSBEaXN0cmlidXRpb24uIA0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0K