Introduction
Background & Aims
The NRA imperial meeting is the largest meeting gathering of TR
shooters in the world. Hopefully, you all know what the imperial is…
There are many misconceptions about the imperial, particularly with
squadding (i.e. time, target etc), for example some claim that it is
much easier to get a higher score if you are on the left or Stix, or
that the early details have a much better chance of getting on a
prize-list as there is less wind. However, this is demonstrably
untrue.
This document aims to show that the only factor in
determining how well you do in the imperial is you. I have tried
to include data to dispel the most commonly repeated myths, as well as
some other interesting data from the imperial.
How to use
Three easy steps:
At the very top right of this document there will be a button
that says Code ▼. Hit this button, and click “Hide all Code”.
This removes the code from the document and makes it easier to read
(that is, unless you for some reason want to see the code…)
Read the erudite analysis above each graph.
Enjoy the sublime beauty of the pretty pictures.
Caveats of the dataset
This data set is from the 2023 NRA Imperial Meeting, and as such, the
data is only from one year. Additionally, it only includes those who
shot the grand agg, and as such, the data is not representative of the
entire field. However, it is still a large data set, and as such, the
data is still useful. I am waiting to hear back from the NRA on whether
they can supply me with a full data set.
Where
Some of the most common myths involve where you are on the range. As
shown below, this has little to no effect on your score.
The red line shows the average on each target.
The plethora of tiny points is called “jitter”, and shows each
individual score from from the data-set, but “jiggled” slightly so that
they don’t overlap.
2&10s on Century Range
data <- dbGetQuery(con, "SELECT squadding.target target, imperial.score score from squadding, imperial where squadding.name = imperial.name and imperial.comp=squadding.comp and not distance=1000 and not distance=900 and imperial.toCount=10;")
data$target <- as.factor(data$target)
# Calculate average score for each target
average_scores <- aggregate(score ~ target, data, mean)
# Plot average scores with line
p <- ggplot(average_scores, aes(x=target, y=score, group=1)) + geom_line(color="red")
# Add individual scores with jitter
p <- p + geom_jitter(data=data, aes(x=target, y=score), size=0.1, alpha=0.3)
# Add labels and title
#limit axis to 35-50
#make sure the labels don't overlap
# make plot scale more sensible
p <- p + labs(x="Target", y="Average Score") + ggtitle("Average score by target on Century [all classes]") + ylim(40,50) + theme(axis.text.x = element_text(angle = 90, hjust = 1))
print(p)
Warning: Removed 111 rows containing missing values (`geom_point()`).

As you can see, the average remains generally flat, with the variance
likely being due to natural variance, however there is a slight dent
around targets 62-77. However this dent is less then a point on average,
and is likely due to natural variance.
2&10s on Stickledown Range
data <- dbGetQuery(con, "SELECT squadding.target target, imperial.score score from squadding, imperial where squadding.name = imperial.name and imperial.comp=squadding.comp and (distance=1000 or distance=900) and imperial.toCount=10;")
data$target <- as.factor(data$target)
# Calculate average score for each target
average_scores <- aggregate(score ~ target, data, mean)
# Plot average scores with line
p <- ggplot(average_scores, aes(x=target, y=score, group=1)) + geom_line(color="red")
# Add individual scores with jitter
p <- p + geom_jitter(data=data, aes(x=target, y=score), size=0.1, alpha=0.3)
# Add labels and title
#limit axis to 35-50
#make sure the labels don't overlap
# make plot scale more sensible
p <- p + labs(x="Target", y="Average Score") + ggtitle("Average score by target on Stix [all classes]") + theme(axis.text.x = element_text(angle = 90, hjust = 1)) + ylim(35,50)
print(p)
Warning: Removed 39 rows containing missing values (`geom_point()`).

And as on century, no real difference between targets.
T Class on Century
data <- dbGetQuery(con, "SELECT squadding.target target, imperial.score score from squadding, imperial where imperial.class='T' and squadding.name = imperial.name and imperial.comp=squadding.comp and not distance=1000 and not distance=900 and imperial.toCount=10;")
data$target <- as.factor(data$target)
# Calculate average score for each target
average_scores <- aggregate(score ~ target, data, mean)
# Plot average scores with line
p <- ggplot(average_scores, aes(x=target, y=score, group=1)) + geom_line(color="red")
# Add individual scores with jitter
p <- p + geom_jitter(data=data, aes(x=target, y=score), size=0.1, alpha=0.3)
# Add labels and title
#limit axis to 35-50
#make sure the labels don't overlap
# make plot scale more sensible
p <- p + labs(x="Target", y="Average Score") + ggtitle("Average score by target on Century [T Class]") + theme(axis.text.x = element_text(angle = 90, hjust = 1)) + ylim(40,50)
print(p)
Warning: Removed 16 rows containing missing values (`geom_point()`).

And once more, there is little to no variation between targets,
however it is important to isolate T class, as generally scores are move
affected by wind etc, while O, A and X classes tend to get more
consistent scores.
Obviously this data-set is less useful, as in Imperial 23, the only
2&10 shoots on Stix were in extremely windy conditions. To make this
data more useful, we once again need to use a boxplot to show
distribution more clearly.
data <- dbGetQuery(con, "SELECT squadding.butt target, imperial.score score from squadding, imperial where imperial.class='T' and squadding.name = imperial.name and imperial.comp=squadding.comp and not distance=1000 and not distance=900 and imperial.toCount=10;")
data$target <- as.factor(data$target)
p <- ggplot(data, aes(target, score)) + geom_boxplot() + geom_jitter(alpha=0.5, size=0.5) + ylim(40, 50)
print(p)
Warning: Removed 12 rows containing non-finite values (`stat_boxplot()`).
Warning: Removed 17 rows containing missing values (`geom_point()`).

To make this more readable, I have only displayed the butts of the
targets, as there are far too many targets on century to make this
readable. Interestingly, there seems to be a slight increase in the
median score on butt 14 (Targets 37-48).
T Class on Stickeldown
data <- dbGetQuery(con, "SELECT squadding.target target, imperial.score score from squadding, imperial where imperial.class='T' and squadding.name = imperial.name and imperial.comp=squadding.comp and (distance=1000 or distance=900) and imperial.toCount=10;")
data$target <- as.factor(data$target)
# Calculate average score for each target
average_scores <- aggregate(score ~ target, data, mean)
# Plot average scores with line
p <- ggplot(average_scores, aes(x=target, y=score, group=1)) + geom_line(color="red")
# Add individual scores with jitter
p <- p + geom_jitter(data=data, aes(x=target, y=score), size=0.1, alpha=0.3)
# Add labels and title
#limit axis to 35-50
#make sure the labels don't overlap
# make plot scale more sensible
p <- p + labs(x="Target", y="Average Score") + ggtitle("Average score by target on Stix [T Class]") + theme(axis.text.x = element_text(angle = 90, hjust = 1)) + ylim(35,50)
print(p)
Warning: Removed 11 rows containing missing values (`geom_point()`).

Obviously this dataset is less useful, as in Imperial 23, the only
2&10 shoots on stix were in extremely windy conditions. To make this
data more useful, we once again need to use a boxplot.
data <- dbGetQuery(con, "SELECT squadding.butt target, imperial.score score from squadding, imperial where imperial.class='T' and squadding.name = imperial.name and imperial.comp=squadding.comp and (distance=1000 or distance=900) and imperial.toCount=10;")
data$target <- as.factor(data$target)
p <- ggplot(data, aes(target, score)) + geom_boxplot() + geom_jitter(alpha=0.2, size=0.2) + ylim(32.5, 50)
print(p)
Warning: Removed 5 rows containing non-finite values (`stat_boxplot()`).
Warning: Removed 5 rows containing missing values (`geom_point()`).

As we can see here, there is such a huge variance across scores that
there is not really any point trying to draw any conclusions, other then
that most T classes did shockingly at long range, due to the obscene
wind conditions. Interestingly, shooting seems to be a lot more
consistent on butt 1 (Targets 11-19).
When
Perhaps the biggest myth when it comes to scores is that the timing
of your detail has a huge effect on your score. This is demonstrably
untrue, as shown below with the average scores for each detail on
century.
data <- dbGetQuery(con, "SELECT squadding.target target, squadding.time time, imperial.score score from squadding, imperial where squadding.name = imperial.name and imperial.comp=squadding.comp and not squadding.time='14:30' and not distance=1000 and not distance=900 and imperial.toCount=10;")
# Convert time from HH:MM:SS to HH:MM
data$time <- substr(data$time, 1, 5)
data$time <- as.factor(data$time)
# Boxplot of scores by time
p <- ggplot(data, aes(time, score)) + geom_boxplot() + geom_jitter(size=0.2, alpha=0.5) + ylim(40, 50)
print(p)
Warning: Removed 28 rows containing non-finite values (`stat_boxplot()`).
Warning: Removed 117 rows containing missing values (`geom_point()`).

And now on stix:
data <- dbGetQuery(con, "SELECT squadding.target target, squadding.time time, imperial.score score from squadding, imperial where squadding.name = imperial.name and imperial.comp=squadding.comp and not squadding.time='14:30' and (distance=1000 or distance=900) and imperial.toCount=10;")
data$time <- substr(data$time, 1, 5)
data$time <- as.factor(data$time)
# Boxplot of scores by time
p <- ggplot(data, aes(time, score)) + geom_boxplot() + geom_jitter(size=0.2, alpha=0.5) + ylim(35, 50)
print(p)
Warning: Removed 17 rows containing non-finite values (`stat_boxplot()`).
Warning: Removed 39 rows containing missing values (`geom_point()`).

And now to look specifically at one day, the 16th of July. The red
line is the wind speed for each hour.
coeff <- 2.35
con <- dbConnect(MariaDB(), user='shootmgr', password='DavidNuthall', dbname='stats', host='localhost')
data <- dbGetQuery(con, "SELECT squadding.target target, squadding.time time, imperial.score score from squadding, imperial where squadding.name = imperial.name and imperial.comp=squadding.comp and not squadding.time='14:30' and not distance=1000 and not distance=900 and imperial.toCount=10 and squadding.date='2023-07-16';")
weather <- dbGetQuery(con, "SELECT windspeed, datetime from weather where datetime>'2023-07-16 07:00:00' and datetime<'2023-07-16 19:00:00';")
dbDisconnect(con)
# extract time from datetime
weather$datetime <- substr(weather$datetime, 12, 16)
data$time <- substr(data$time, 1, 5)
# Plot a graph with two x and y axes, with one for the boxplot and one for the wind speed
#`geom_line()`: Each group consists of only one observation.
# ℹ Do you need to adjust the group aesthetic?
weather <- weather[order(weather$datetime), ]
# Plot with ordered data
p <- ggplot(data, aes(time, score)) +
geom_boxplot() +
geom_jitter(size = 0.2, alpha = 0.5) +
theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
geom_point(data = weather, aes(x = datetime, y = windspeed * coeff), color = "red") +
geom_line(data=weather, aes(x=datetime, y= windspeed*coeff, group=1), color = "red") +
scale_y_continuous(name="Scores", sec.axis = sec_axis(~./coeff, name = "Wind Speed (mph)")) + ylim(40, 50)
Scale for y is already present.
Adding another scale for y, which will replace the existing scale.
print(p)
Warning: Removed 11 rows containing non-finite values (`stat_boxplot()`).
Warning: Removed 59 rows containing missing values (`geom_point()`).
Warning: Removed 1 rows containing missing values (`geom_point()`).
Warning: Removed 1 row containing missing values (`geom_line()`).

LS0tDQp0aXRsZTogIk5SQSBJbXBlcmlhbCBNZWV0aW5nIDIwMjMgQW5hbHlzaXMiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBkZl9wcmludDogcGFnZWQNCiAgd29yZF9kb2N1bWVudDogZGVmYXVsdA0KLS0tDQoNCiMgSW50cm9kdWN0aW9uDQoNCiMjIEJhY2tncm91bmQgJiBBaW1zDQoNClRoZSBOUkEgaW1wZXJpYWwgbWVldGluZyBpcyB0aGUgbGFyZ2VzdCBtZWV0aW5nIGdhdGhlcmluZyBvZiBUUiBzaG9vdGVycyBpbiB0aGUgd29ybGQuIEhvcGVmdWxseSwgeW91IGFsbCBrbm93IHdoYXQgdGhlIGltcGVyaWFsIGlzLi4uDQoNClRoZXJlIGFyZSBtYW55IG1pc2NvbmNlcHRpb25zIGFib3V0IHRoZSBpbXBlcmlhbCwgcGFydGljdWxhcmx5IHdpdGggc3F1YWRkaW5nIChpLmUuIHRpbWUsIHRhcmdldCBldGMpLCBmb3IgZXhhbXBsZSBzb21lIGNsYWltIHRoYXQgaXQgaXMgbXVjaCBlYXNpZXIgdG8gZ2V0IGEgaGlnaGVyIHNjb3JlIGlmIHlvdSBhcmUgb24gdGhlIGxlZnQgb3IgU3RpeCwgb3IgdGhhdCB0aGUgZWFybHkgZGV0YWlscyBoYXZlIGEgbXVjaCBiZXR0ZXIgY2hhbmNlIG9mIGdldHRpbmcgb24gYSBwcml6ZS1saXN0IGFzIHRoZXJlIGlzIGxlc3Mgd2luZC4gSG93ZXZlciwgdGhpcyBpcyBkZW1vbnN0cmFibHkgdW50cnVlLg0KDQpUaGlzIGRvY3VtZW50IGFpbXMgdG8gc2hvdyB0aGF0IHRoZSAqKm9ubHkqKiBmYWN0b3IgaW4gZGV0ZXJtaW5pbmcgaG93IHdlbGwgeW91IGRvIGluIHRoZSBpbXBlcmlhbCBpcyBbeW91Ll17LnVuZGVybGluZX0gSSBoYXZlIHRyaWVkIHRvIGluY2x1ZGUgZGF0YSB0byBkaXNwZWwgdGhlIG1vc3QgY29tbW9ubHkgcmVwZWF0ZWQgbXl0aHMsIGFzIHdlbGwgYXMgc29tZSBvdGhlciBpbnRlcmVzdGluZyBkYXRhIGZyb20gdGhlIGltcGVyaWFsLg0KDQojIyBIb3cgdG8gdXNlDQoNClRocmVlIGVhc3kgc3RlcHM6DQoNCjEuICBBdCB0aGUgdmVyeSB0b3AgcmlnaHQgb2YgdGhpcyBkb2N1bWVudCB0aGVyZSB3aWxsIGJlIGEgYnV0dG9uIHRoYXQgc2F5cyBbQ29kZSDilrxdey51bmRlcmxpbmV9LiBIaXQgdGhpcyBidXR0b24sIGFuZCBjbGljayAiSGlkZSBhbGwgQ29kZSIuIFRoaXMgcmVtb3ZlcyB0aGUgY29kZSBmcm9tIHRoZSBkb2N1bWVudCBhbmQgbWFrZXMgaXQgZWFzaWVyIHRvIHJlYWQgKHRoYXQgaXMsIHVubGVzcyB5b3UgZm9yIHNvbWUgcmVhc29uIHdhbnQgdG8gc2VlIHRoZSBjb2RlLi4uKQ0KDQoyLiAgUmVhZCB0aGUgZXJ1ZGl0ZSBhbmFseXNpcyBhYm92ZSBlYWNoIGdyYXBoLg0KDQozLiAgRW5qb3kgdGhlIHN1YmxpbWUgYmVhdXR5IG9mIHRoZSBwcmV0dHkgcGljdHVyZXMuDQoNCiMjIENvbnRhY3QNCg0KSWYgeW91IGRvIGhhdmUgYW55IHF1ZXN0aW9ucyBwbGVhc2UgY29udGFjdCB0aGUgYXV0aG9yIGF0OiBbc3RhdHNcQGxnc2sudGVjaF0obWFpbHRvOnN0YXRzQGxnc2sudGVjaCl7LmVtYWlsfQ0KDQojIyBDYXZlYXRzIG9mIHRoZSBkYXRhc2V0DQoNClRoaXMgZGF0YSBzZXQgaXMgZnJvbSB0aGUgMjAyMyBOUkEgSW1wZXJpYWwgTWVldGluZywgYW5kIGFzIHN1Y2gsIHRoZSBkYXRhIGlzIG9ubHkgZnJvbSBvbmUgeWVhci4gQWRkaXRpb25hbGx5LCBpdCBvbmx5IGluY2x1ZGVzIHRob3NlIHdobyBzaG90IHRoZSBncmFuZCBhZ2csIGFuZCBhcyBzdWNoLCB0aGUgZGF0YSBpcyBub3QgcmVwcmVzZW50YXRpdmUgb2YgdGhlIGVudGlyZSBmaWVsZC4gSG93ZXZlciwgaXQgaXMgc3RpbGwgYSBsYXJnZSBkYXRhIHNldCwgYW5kIGFzIHN1Y2gsIHRoZSBkYXRhIGlzIHN0aWxsIHVzZWZ1bC4gSSBhbSB3YWl0aW5nIHRvIGhlYXIgYmFjayBmcm9tIHRoZSBOUkEgb24gd2hldGhlciB0aGV5IGNhbiBzdXBwbHkgbWUgd2l0aCBhIGZ1bGwgZGF0YSBzZXQuDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShSTWFyaWFEQikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkocGF0Y2h3b3JrKQ0KDQpjb24gPC0gZGJDb25uZWN0KE1hcmlhREIoKSwgdXNlcj0nc2hvb3RtZ3InLCBwYXNzd29yZD0nRGF2aWROdXRoYWxsJywgZGJuYW1lPSdzdGF0cycsIGhvc3Q9J2xvY2FsaG9zdCcpDQoNCmBgYA0KDQojIFdoZXJlDQoNClNvbWUgb2YgdGhlIG1vc3QgY29tbW9uIG15dGhzIGludm9sdmUgd2hlcmUgeW91IGFyZSBvbiB0aGUgcmFuZ2UuIEFzIHNob3duIGJlbG93LCB0aGlzIGhhcyBsaXR0bGUgdG8gbm8gZWZmZWN0IG9uIHlvdXIgc2NvcmUuDQoNCi0gICBUaGUgcmVkIGxpbmUgc2hvd3MgdGhlIGF2ZXJhZ2Ugb24gZWFjaCB0YXJnZXQuDQoNCi0gICBUaGUgcGxldGhvcmEgb2YgdGlueSBwb2ludHMgaXMgY2FsbGVkICJqaXR0ZXIiLCBhbmQgc2hvd3MgZWFjaCBpbmRpdmlkdWFsIHNjb3JlIGZyb20gZnJvbSB0aGUgZGF0YS1zZXQsIGJ1dCAiamlnZ2xlZCIgc2xpZ2h0bHkgc28gdGhhdCB0aGV5IGRvbid0IG92ZXJsYXAuDQoNCiMjIDImMTBzIG9uIENlbnR1cnkgUmFuZ2UNCg0KYGBge3J9DQpkYXRhIDwtIGRiR2V0UXVlcnkoY29uLCAiU0VMRUNUIHNxdWFkZGluZy50YXJnZXQgdGFyZ2V0LCBpbXBlcmlhbC5zY29yZSBzY29yZSBmcm9tIHNxdWFkZGluZywgaW1wZXJpYWwgd2hlcmUgc3F1YWRkaW5nLm5hbWUgPSBpbXBlcmlhbC5uYW1lIGFuZCBpbXBlcmlhbC5jb21wPXNxdWFkZGluZy5jb21wIGFuZCBub3QgZGlzdGFuY2U9MTAwMCBhbmQgbm90IGRpc3RhbmNlPTkwMCBhbmQgaW1wZXJpYWwudG9Db3VudD0xMDsiKQ0KDQpkYXRhJHRhcmdldCA8LSBhcy5mYWN0b3IoZGF0YSR0YXJnZXQpDQoNCiMgQ2FsY3VsYXRlIGF2ZXJhZ2Ugc2NvcmUgZm9yIGVhY2ggdGFyZ2V0DQphdmVyYWdlX3Njb3JlcyA8LSBhZ2dyZWdhdGUoc2NvcmUgfiB0YXJnZXQsIGRhdGEsIG1lYW4pDQoNCiMgUGxvdCBhdmVyYWdlIHNjb3JlcyB3aXRoIGxpbmUNCnAgPC0gZ2dwbG90KGF2ZXJhZ2Vfc2NvcmVzLCBhZXMoeD10YXJnZXQsIHk9c2NvcmUsIGdyb3VwPTEpKSArIGdlb21fbGluZShjb2xvcj0icmVkIikNCg0KIyBBZGQgaW5kaXZpZHVhbCBzY29yZXMgd2l0aCBqaXR0ZXINCnAgPC0gcCArIGdlb21faml0dGVyKGRhdGE9ZGF0YSwgYWVzKHg9dGFyZ2V0LCB5PXNjb3JlKSwgc2l6ZT0wLjEsIGFscGhhPTAuMykNCg0KIyBBZGQgbGFiZWxzIGFuZCB0aXRsZQ0KI2xpbWl0IGF4aXMgdG8gMzUtNTANCiNtYWtlIHN1cmUgdGhlIGxhYmVscyBkb24ndCBvdmVybGFwDQojIG1ha2UgcGxvdCBzY2FsZSBtb3JlIHNlbnNpYmxlDQpwIDwtIHAgKyBsYWJzKHg9IlRhcmdldCIsIHk9IkF2ZXJhZ2UgU2NvcmUiKSArIGdndGl0bGUoIkF2ZXJhZ2Ugc2NvcmUgYnkgdGFyZ2V0IG9uIENlbnR1cnkgW2FsbCBjbGFzc2VzXSIpICsgeWxpbSg0MCw1MCkgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKSANCg0KcHJpbnQocCkNCg0KYGBgDQoNCkFzIHlvdSBjYW4gc2VlLCB0aGUgYXZlcmFnZSByZW1haW5zIGdlbmVyYWxseSBmbGF0LCB3aXRoIHRoZSB2YXJpYW5jZSBsaWtlbHkgYmVpbmcgZHVlIHRvIG5hdHVyYWwgdmFyaWFuY2UsIGhvd2V2ZXIgdGhlcmUgaXMgYSBzbGlnaHQgZGVudCBhcm91bmQgdGFyZ2V0cyA2Mi03Ny4gSG93ZXZlciB0aGlzIGRlbnQgaXMgbGVzcyB0aGVuIGEgcG9pbnQgb24gYXZlcmFnZSwgYW5kIGlzIGxpa2VseSBkdWUgdG8gbmF0dXJhbCB2YXJpYW5jZS4NCg0KIyMgMiYxMHMgb24gU3RpY2tsZWRvd24gUmFuZ2UNCg0KYGBge3J9DQpkYXRhIDwtIGRiR2V0UXVlcnkoY29uLCAiU0VMRUNUIHNxdWFkZGluZy50YXJnZXQgdGFyZ2V0LCBpbXBlcmlhbC5zY29yZSBzY29yZSBmcm9tIHNxdWFkZGluZywgaW1wZXJpYWwgd2hlcmUgc3F1YWRkaW5nLm5hbWUgPSBpbXBlcmlhbC5uYW1lIGFuZCBpbXBlcmlhbC5jb21wPXNxdWFkZGluZy5jb21wIGFuZCAoZGlzdGFuY2U9MTAwMCBvciBkaXN0YW5jZT05MDApIGFuZCBpbXBlcmlhbC50b0NvdW50PTEwOyIpDQoNCmRhdGEkdGFyZ2V0IDwtIGFzLmZhY3RvcihkYXRhJHRhcmdldCkNCg0KIyBDYWxjdWxhdGUgYXZlcmFnZSBzY29yZSBmb3IgZWFjaCB0YXJnZXQNCmF2ZXJhZ2Vfc2NvcmVzIDwtIGFnZ3JlZ2F0ZShzY29yZSB+IHRhcmdldCwgZGF0YSwgbWVhbikNCg0KIyBQbG90IGF2ZXJhZ2Ugc2NvcmVzIHdpdGggbGluZQ0KcCA8LSBnZ3Bsb3QoYXZlcmFnZV9zY29yZXMsIGFlcyh4PXRhcmdldCwgeT1zY29yZSwgZ3JvdXA9MSkpICsgZ2VvbV9saW5lKGNvbG9yPSJyZWQiKQ0KDQojIEFkZCBpbmRpdmlkdWFsIHNjb3JlcyB3aXRoIGppdHRlcg0KcCA8LSBwICsgZ2VvbV9qaXR0ZXIoZGF0YT1kYXRhLCBhZXMoeD10YXJnZXQsIHk9c2NvcmUpLCBzaXplPTAuMSwgYWxwaGE9MC4zKQ0KDQojIEFkZCBsYWJlbHMgYW5kIHRpdGxlDQojbGltaXQgYXhpcyB0byAzNS01MA0KI21ha2Ugc3VyZSB0aGUgbGFiZWxzIGRvbid0IG92ZXJsYXANCiMgbWFrZSBwbG90IHNjYWxlIG1vcmUgc2Vuc2libGUNCnAgPC0gcCArIGxhYnMoeD0iVGFyZ2V0IiwgeT0iQXZlcmFnZSBTY29yZSIpICsgZ2d0aXRsZSgiQXZlcmFnZSBzY29yZSBieSB0YXJnZXQgb24gU3RpeCBbYWxsIGNsYXNzZXNdIikgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKSArIHlsaW0oMzUsNTApDQoNCnByaW50KHApDQoNCmBgYA0KDQpBbmQgYXMgb24gY2VudHVyeSwgbm8gcmVhbCBkaWZmZXJlbmNlIGJldHdlZW4gdGFyZ2V0cy4NCg0KIyMgVCBDbGFzcyBvbiBDZW50dXJ5DQoNCmBgYHtyfQ0KZGF0YSA8LSBkYkdldFF1ZXJ5KGNvbiwgIlNFTEVDVCBzcXVhZGRpbmcudGFyZ2V0IHRhcmdldCwgaW1wZXJpYWwuc2NvcmUgc2NvcmUgZnJvbSBzcXVhZGRpbmcsIGltcGVyaWFsIHdoZXJlIGltcGVyaWFsLmNsYXNzPSdUJyBhbmQgc3F1YWRkaW5nLm5hbWUgPSBpbXBlcmlhbC5uYW1lIGFuZCBpbXBlcmlhbC5jb21wPXNxdWFkZGluZy5jb21wIGFuZCBub3QgZGlzdGFuY2U9MTAwMCBhbmQgbm90IGRpc3RhbmNlPTkwMCBhbmQgaW1wZXJpYWwudG9Db3VudD0xMDsiKQ0KDQpkYXRhJHRhcmdldCA8LSBhcy5mYWN0b3IoZGF0YSR0YXJnZXQpDQoNCiMgQ2FsY3VsYXRlIGF2ZXJhZ2Ugc2NvcmUgZm9yIGVhY2ggdGFyZ2V0DQphdmVyYWdlX3Njb3JlcyA8LSBhZ2dyZWdhdGUoc2NvcmUgfiB0YXJnZXQsIGRhdGEsIG1lYW4pDQoNCiMgUGxvdCBhdmVyYWdlIHNjb3JlcyB3aXRoIGxpbmUNCnAgPC0gZ2dwbG90KGF2ZXJhZ2Vfc2NvcmVzLCBhZXMoeD10YXJnZXQsIHk9c2NvcmUsIGdyb3VwPTEpKSArIGdlb21fbGluZShjb2xvcj0icmVkIikNCg0KIyBBZGQgaW5kaXZpZHVhbCBzY29yZXMgd2l0aCBqaXR0ZXINCnAgPC0gcCArIGdlb21faml0dGVyKGRhdGE9ZGF0YSwgYWVzKHg9dGFyZ2V0LCB5PXNjb3JlKSwgc2l6ZT0wLjEsIGFscGhhPTAuMykNCg0KIyBBZGQgbGFiZWxzIGFuZCB0aXRsZQ0KI2xpbWl0IGF4aXMgdG8gMzUtNTANCiNtYWtlIHN1cmUgdGhlIGxhYmVscyBkb24ndCBvdmVybGFwDQojIG1ha2UgcGxvdCBzY2FsZSBtb3JlIHNlbnNpYmxlDQpwIDwtIHAgKyBsYWJzKHg9IlRhcmdldCIsIHk9IkF2ZXJhZ2UgU2NvcmUiKSArIGdndGl0bGUoIkF2ZXJhZ2Ugc2NvcmUgYnkgdGFyZ2V0IG9uIENlbnR1cnkgW1QgQ2xhc3NdIikgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKSArIHlsaW0oNDAsNTApDQoNCnByaW50KHApDQoNCmBgYA0KDQpBbmQgb25jZSBtb3JlLCB0aGVyZSBpcyBsaXR0bGUgdG8gbm8gdmFyaWF0aW9uIGJldHdlZW4gdGFyZ2V0cywgaG93ZXZlciBpdCBpcyBpbXBvcnRhbnQgdG8gaXNvbGF0ZSBUIGNsYXNzLCBhcyBnZW5lcmFsbHkgc2NvcmVzIGFyZSBtb3ZlIGFmZmVjdGVkIGJ5IHdpbmQgZXRjLCB3aGlsZSBPLCBBIGFuZCBYIGNsYXNzZXMgdGVuZCB0byBnZXQgbW9yZSBjb25zaXN0ZW50IHNjb3Jlcy4NCg0KT2J2aW91c2x5IHRoaXMgZGF0YS1zZXQgaXMgbGVzcyB1c2VmdWwsIGFzIGluIEltcGVyaWFsIDIzLCB0aGUgb25seSAyJjEwIHNob290cyBvbiBTdGl4IHdlcmUgaW4gZXh0cmVtZWx5IHdpbmR5IGNvbmRpdGlvbnMuIFRvIG1ha2UgdGhpcyBkYXRhIG1vcmUgdXNlZnVsLCB3ZSBvbmNlIGFnYWluIG5lZWQgdG8gdXNlIGEgYm94cGxvdCB0byBzaG93IGRpc3RyaWJ1dGlvbiBtb3JlIGNsZWFybHkuDQoNCmBgYHtyfQ0KZGF0YSA8LSBkYkdldFF1ZXJ5KGNvbiwgIlNFTEVDVCBzcXVhZGRpbmcuYnV0dCB0YXJnZXQsIGltcGVyaWFsLnNjb3JlIHNjb3JlIGZyb20gc3F1YWRkaW5nLCBpbXBlcmlhbCB3aGVyZSBpbXBlcmlhbC5jbGFzcz0nVCcgYW5kIHNxdWFkZGluZy5uYW1lID0gaW1wZXJpYWwubmFtZSBhbmQgaW1wZXJpYWwuY29tcD1zcXVhZGRpbmcuY29tcCBhbmQgbm90IGRpc3RhbmNlPTEwMDAgYW5kIG5vdCBkaXN0YW5jZT05MDAgYW5kIGltcGVyaWFsLnRvQ291bnQ9MTA7IikNCg0KZGF0YSR0YXJnZXQgPC0gYXMuZmFjdG9yKGRhdGEkdGFyZ2V0KQ0KDQpwIDwtIGdncGxvdChkYXRhLCBhZXModGFyZ2V0LCBzY29yZSkpICsgZ2VvbV9ib3hwbG90KCkgKyBnZW9tX2ppdHRlcihhbHBoYT0wLjUsIHNpemU9MC41KSArIHlsaW0oNDAsIDUwKQ0KDQpwcmludChwKQ0KDQpgYGANCg0KVG8gbWFrZSB0aGlzIG1vcmUgcmVhZGFibGUsIEkgaGF2ZSBvbmx5IGRpc3BsYXllZCB0aGUgYnV0dHMgb2YgdGhlIHRhcmdldHMsIGFzIHRoZXJlIGFyZSBmYXIgdG9vIG1hbnkgdGFyZ2V0cyBvbiBjZW50dXJ5IHRvIG1ha2UgdGhpcyByZWFkYWJsZS4gSW50ZXJlc3RpbmdseSwgdGhlcmUgc2VlbXMgdG8gYmUgYSBzbGlnaHQgaW5jcmVhc2UgaW4gdGhlIG1lZGlhbiBzY29yZSBvbiBidXR0IDE0IChUYXJnZXRzIDM3LTQ4KS4NCg0KIyMgVCBDbGFzcyBvbiBTdGlja2VsZG93bg0KDQpgYGB7cn0NCmRhdGEgPC0gZGJHZXRRdWVyeShjb24sICJTRUxFQ1Qgc3F1YWRkaW5nLnRhcmdldCB0YXJnZXQsIGltcGVyaWFsLnNjb3JlIHNjb3JlIGZyb20gc3F1YWRkaW5nLCBpbXBlcmlhbCB3aGVyZSBpbXBlcmlhbC5jbGFzcz0nVCcgYW5kIHNxdWFkZGluZy5uYW1lID0gaW1wZXJpYWwubmFtZSBhbmQgaW1wZXJpYWwuY29tcD1zcXVhZGRpbmcuY29tcCBhbmQgKGRpc3RhbmNlPTEwMDAgb3IgZGlzdGFuY2U9OTAwKSBhbmQgaW1wZXJpYWwudG9Db3VudD0xMDsiKQ0KDQpkYXRhJHRhcmdldCA8LSBhcy5mYWN0b3IoZGF0YSR0YXJnZXQpDQoNCiMgQ2FsY3VsYXRlIGF2ZXJhZ2Ugc2NvcmUgZm9yIGVhY2ggdGFyZ2V0DQphdmVyYWdlX3Njb3JlcyA8LSBhZ2dyZWdhdGUoc2NvcmUgfiB0YXJnZXQsIGRhdGEsIG1lYW4pDQoNCiMgUGxvdCBhdmVyYWdlIHNjb3JlcyB3aXRoIGxpbmUNCnAgPC0gZ2dwbG90KGF2ZXJhZ2Vfc2NvcmVzLCBhZXMoeD10YXJnZXQsIHk9c2NvcmUsIGdyb3VwPTEpKSArIGdlb21fbGluZShjb2xvcj0icmVkIikNCg0KIyBBZGQgaW5kaXZpZHVhbCBzY29yZXMgd2l0aCBqaXR0ZXINCnAgPC0gcCArIGdlb21faml0dGVyKGRhdGE9ZGF0YSwgYWVzKHg9dGFyZ2V0LCB5PXNjb3JlKSwgc2l6ZT0wLjEsIGFscGhhPTAuMykNCg0KIyBBZGQgbGFiZWxzIGFuZCB0aXRsZQ0KI2xpbWl0IGF4aXMgdG8gMzUtNTANCiNtYWtlIHN1cmUgdGhlIGxhYmVscyBkb24ndCBvdmVybGFwDQojIG1ha2UgcGxvdCBzY2FsZSBtb3JlIHNlbnNpYmxlDQpwIDwtIHAgKyBsYWJzKHg9IlRhcmdldCIsIHk9IkF2ZXJhZ2UgU2NvcmUiKSArIGdndGl0bGUoIkF2ZXJhZ2Ugc2NvcmUgYnkgdGFyZ2V0IG9uIFN0aXggW1QgQ2xhc3NdIikgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKSArIHlsaW0oMzUsNTApDQoNCnByaW50KHApDQpgYGANCg0KT2J2aW91c2x5IHRoaXMgZGF0YXNldCBpcyBsZXNzIHVzZWZ1bCwgYXMgaW4gSW1wZXJpYWwgMjMsIHRoZSBvbmx5IDImMTAgc2hvb3RzIG9uIHN0aXggd2VyZSBpbiBleHRyZW1lbHkgd2luZHkgY29uZGl0aW9ucy4gVG8gbWFrZSB0aGlzIGRhdGEgbW9yZSB1c2VmdWwsIHdlIG9uY2UgYWdhaW4gbmVlZCB0byB1c2UgYSBib3hwbG90Lg0KDQpgYGB7cn0NCmRhdGEgPC0gZGJHZXRRdWVyeShjb24sICJTRUxFQ1Qgc3F1YWRkaW5nLmJ1dHQgdGFyZ2V0LCBpbXBlcmlhbC5zY29yZSBzY29yZSBmcm9tIHNxdWFkZGluZywgaW1wZXJpYWwgd2hlcmUgaW1wZXJpYWwuY2xhc3M9J1QnIGFuZCBzcXVhZGRpbmcubmFtZSA9IGltcGVyaWFsLm5hbWUgYW5kIGltcGVyaWFsLmNvbXA9c3F1YWRkaW5nLmNvbXAgYW5kIChkaXN0YW5jZT0xMDAwIG9yIGRpc3RhbmNlPTkwMCkgYW5kIGltcGVyaWFsLnRvQ291bnQ9MTA7IikNCg0KZGF0YSR0YXJnZXQgPC0gYXMuZmFjdG9yKGRhdGEkdGFyZ2V0KQ0KDQpwIDwtIGdncGxvdChkYXRhLCBhZXModGFyZ2V0LCBzY29yZSkpICsgZ2VvbV9ib3hwbG90KCkgKyBnZW9tX2ppdHRlcihhbHBoYT0wLjIsIHNpemU9MC4yKSArIHlsaW0oMzIuNSwgNTApDQoNCnByaW50KHApDQpgYGANCg0KQXMgd2UgY2FuIHNlZSBoZXJlLCB0aGVyZSBpcyBzdWNoIGEgaHVnZSB2YXJpYW5jZSBhY3Jvc3Mgc2NvcmVzIHRoYXQgdGhlcmUgaXMgbm90IHJlYWxseSBhbnkgcG9pbnQgdHJ5aW5nIHRvIGRyYXcgYW55IGNvbmNsdXNpb25zLCBvdGhlciB0aGVuIHRoYXQgbW9zdCBUIGNsYXNzZXMgZGlkIHNob2NraW5nbHkgYXQgbG9uZyByYW5nZSwgZHVlIHRvIHRoZSBvYnNjZW5lIHdpbmQgY29uZGl0aW9ucy4gSW50ZXJlc3RpbmdseSwgc2hvb3Rpbmcgc2VlbXMgdG8gYmUgYSBsb3QgbW9yZSBjb25zaXN0ZW50IG9uIGJ1dHQgMSAoVGFyZ2V0cyAxMS0xOSkuDQoNCiMgV2hlbg0KDQpQZXJoYXBzIHRoZSBiaWdnZXN0IG15dGggd2hlbiBpdCBjb21lcyB0byBzY29yZXMgaXMgdGhhdCB0aGUgdGltaW5nIG9mIHlvdXIgZGV0YWlsIGhhcyBhIGh1Z2UgZWZmZWN0IG9uIHlvdXIgc2NvcmUuIFRoaXMgaXMgZGVtb25zdHJhYmx5IHVudHJ1ZSwgYXMgc2hvd24gYmVsb3cgd2l0aCB0aGUgYXZlcmFnZSBzY29yZXMgZm9yIGVhY2ggZGV0YWlsIG9uIGNlbnR1cnkuDQoNCmBgYHtyfQ0KDQpkYXRhIDwtIGRiR2V0UXVlcnkoY29uLCAiU0VMRUNUIHNxdWFkZGluZy50YXJnZXQgdGFyZ2V0LCBzcXVhZGRpbmcudGltZSB0aW1lLCBpbXBlcmlhbC5zY29yZSBzY29yZSBmcm9tIHNxdWFkZGluZywgaW1wZXJpYWwgd2hlcmUgc3F1YWRkaW5nLm5hbWUgPSBpbXBlcmlhbC5uYW1lIGFuZCBpbXBlcmlhbC5jb21wPXNxdWFkZGluZy5jb21wIGFuZCBub3Qgc3F1YWRkaW5nLnRpbWU9JzE0OjMwJyBhbmQgbm90IGRpc3RhbmNlPTEwMDAgYW5kIG5vdCBkaXN0YW5jZT05MDAgYW5kIGltcGVyaWFsLnRvQ291bnQ9MTA7IikNCg0KIyBDb252ZXJ0IHRpbWUgZnJvbSBISDpNTTpTUyB0byBISDpNTQ0KDQpkYXRhJHRpbWUgPC0gc3Vic3RyKGRhdGEkdGltZSwgMSwgNSkNCg0KZGF0YSR0aW1lIDwtIGFzLmZhY3RvcihkYXRhJHRpbWUpDQoNCiMgQm94cGxvdCBvZiBzY29yZXMgYnkgdGltZQ0KDQpwIDwtIGdncGxvdChkYXRhLCBhZXModGltZSwgc2NvcmUpKSArIGdlb21fYm94cGxvdCgpICsgZ2VvbV9qaXR0ZXIoc2l6ZT0wLjIsIGFscGhhPTAuNSkgKyB5bGltKDQwLCA1MCkNCg0KcHJpbnQocCkNCg0KYGBgDQoNCkFuZCBub3cgb24gc3RpeDoNCg0KYGBge3J9DQpkYXRhIDwtIGRiR2V0UXVlcnkoY29uLCAiU0VMRUNUIHNxdWFkZGluZy50YXJnZXQgdGFyZ2V0LCBzcXVhZGRpbmcudGltZSB0aW1lLCBpbXBlcmlhbC5zY29yZSBzY29yZSBmcm9tIHNxdWFkZGluZywgaW1wZXJpYWwgd2hlcmUgc3F1YWRkaW5nLm5hbWUgPSBpbXBlcmlhbC5uYW1lIGFuZCBpbXBlcmlhbC5jb21wPXNxdWFkZGluZy5jb21wIGFuZCBub3Qgc3F1YWRkaW5nLnRpbWU9JzE0OjMwJyBhbmQgKGRpc3RhbmNlPTEwMDAgb3IgZGlzdGFuY2U9OTAwKSBhbmQgaW1wZXJpYWwudG9Db3VudD0xMDsiKQ0KDQpkYXRhJHRpbWUgPC0gc3Vic3RyKGRhdGEkdGltZSwgMSwgNSkNCmRhdGEkdGltZSA8LSBhcy5mYWN0b3IoZGF0YSR0aW1lKQ0KDQojIEJveHBsb3Qgb2Ygc2NvcmVzIGJ5IHRpbWUNCg0KcCA8LSBnZ3Bsb3QoZGF0YSwgYWVzKHRpbWUsIHNjb3JlKSkgKyBnZW9tX2JveHBsb3QoKSArIGdlb21faml0dGVyKHNpemU9MC4yLCBhbHBoYT0wLjUpICsgeWxpbSgzNSwgNTApDQpwcmludChwKQ0KDQpgYGANCg0KQW5kIG5vdyB0byBsb29rIHNwZWNpZmljYWxseSBhdCBvbmUgZGF5LCB0aGUgMTZ0aCBvZiBKdWx5LiBUaGUgcmVkIGxpbmUgaXMgdGhlIHdpbmQgc3BlZWQgZm9yIGVhY2ggaG91ci4NCg0KYGBge3J9DQoNCmNvZWZmIDwtIDIuMzUNCg0KY29uIDwtIGRiQ29ubmVjdChNYXJpYURCKCksIHVzZXI9J3Nob290bWdyJywgcGFzc3dvcmQ9J0RhdmlkTnV0aGFsbCcsIGRibmFtZT0nc3RhdHMnLCBob3N0PSdsb2NhbGhvc3QnKQ0KDQpkYXRhIDwtIGRiR2V0UXVlcnkoY29uLCAiU0VMRUNUIHNxdWFkZGluZy50YXJnZXQgdGFyZ2V0LCBzcXVhZGRpbmcudGltZSB0aW1lLCBpbXBlcmlhbC5zY29yZSBzY29yZSBmcm9tIHNxdWFkZGluZywgaW1wZXJpYWwgd2hlcmUgc3F1YWRkaW5nLm5hbWUgPSBpbXBlcmlhbC5uYW1lIGFuZCBpbXBlcmlhbC5jb21wPXNxdWFkZGluZy5jb21wIGFuZCBub3Qgc3F1YWRkaW5nLnRpbWU9JzE0OjMwJyBhbmQgbm90IGRpc3RhbmNlPTEwMDAgYW5kIG5vdCBkaXN0YW5jZT05MDAgYW5kIGltcGVyaWFsLnRvQ291bnQ9MTAgYW5kIHNxdWFkZGluZy5kYXRlPScyMDIzLTA3LTE2JzsiKQ0KDQp3ZWF0aGVyIDwtIGRiR2V0UXVlcnkoY29uLCAiU0VMRUNUIHdpbmRzcGVlZCwgZGF0ZXRpbWUgZnJvbSB3ZWF0aGVyIHdoZXJlIGRhdGV0aW1lPicyMDIzLTA3LTE2IDA3OjAwOjAwJyBhbmQgZGF0ZXRpbWU8JzIwMjMtMDctMTYgMTk6MDA6MDAnOyIpDQoNCmRiRGlzY29ubmVjdChjb24pDQojIGV4dHJhY3QgdGltZSBmcm9tIGRhdGV0aW1lDQoNCndlYXRoZXIkZGF0ZXRpbWUgPC0gc3Vic3RyKHdlYXRoZXIkZGF0ZXRpbWUsIDEyLCAxNikNCg0KZGF0YSR0aW1lIDwtIHN1YnN0cihkYXRhJHRpbWUsIDEsIDUpDQoNCiMgUGxvdCBhIGdyYXBoIHdpdGggdHdvIHggYW5kIHkgYXhlcywgd2l0aCBvbmUgZm9yIHRoZSBib3hwbG90IGFuZCBvbmUgZm9yIHRoZSB3aW5kIHNwZWVkDQojYGdlb21fbGluZSgpYDogRWFjaCBncm91cCBjb25zaXN0cyBvZiBvbmx5IG9uZSBvYnNlcnZhdGlvbi4NCiMg4oS5IERvIHlvdSBuZWVkIHRvIGFkanVzdCB0aGUgZ3JvdXAgYWVzdGhldGljPw0KDQp3ZWF0aGVyIDwtIHdlYXRoZXJbb3JkZXIod2VhdGhlciRkYXRldGltZSksIF0NCg0KIyBQbG90IHdpdGggb3JkZXJlZCBkYXRhDQpwIDwtIGdncGxvdChkYXRhLCBhZXModGltZSwgc2NvcmUpKSArDQogIGdlb21fYm94cGxvdCgpICsNCiAgZ2VvbV9qaXR0ZXIoc2l6ZSA9IDAuMiwgYWxwaGEgPSAwLjUpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSkgKw0KICBnZW9tX3BvaW50KGRhdGEgPSB3ZWF0aGVyLCBhZXMoeCA9IGRhdGV0aW1lLCB5ID0gd2luZHNwZWVkICogY29lZmYpLCBjb2xvciA9ICJyZWQiKSArDQogIGdlb21fbGluZShkYXRhPXdlYXRoZXIsIGFlcyh4PWRhdGV0aW1lLCB5PSB3aW5kc3BlZWQqY29lZmYsIGdyb3VwPTEpLCBjb2xvciA9ICJyZWQiKSArDQogIHNjYWxlX3lfY29udGludW91cyhuYW1lPSJTY29yZXMiLCBzZWMuYXhpcyA9IHNlY19heGlzKH4uL2NvZWZmLCBuYW1lID0gIldpbmQgU3BlZWQgKG1waCkiKSkgKyB5bGltKDQwLCA1MCkNCg0KcHJpbnQocCkNCg0KYGBgDQo=