library(tidyverse)
library(openintro)
library(FSA)

Intro

Genshin Impact is a Chinese combat role-playing-game (RPG) in which the player explores the world of Teyvat as the Traveler. Along their journey, in-game characters may join the Traveler’s party, thereby becoming playable. One such character is Shenhe, a mysterious woman who wields a polearm and cryo vision. The following are integral terms to the combat system of Genshin Impact:

ER: Energy Recharge, the multiplier that determines how much elemental energy a character gains per particle absorbed.

Elemental energy: used to cast an “Elemental Burst” by filling up a meter with a certain amount of energy. This gives rise to an “energy requirement”, which is the amount of Energy Recharge that a character needs in order to consistently use their elemntal burst.

Elemental Burst: a skill within a character’s kit which costs elemental energy to use. A burst is triggered by clicking the “Q” key on a keyboard. Bursts can be leveled to increase their utilities and damage multipliers.

Particle: units of elemental energy generated by casting an “Elemental Skill” and other methods.

Kit: a characters set of available moves and utilities.

Elemental Skill: A skill within a character’s kit which costs no elemental energy to use. An elemental skill is triggered by clicking the “E” key on a keyboard. Elemental skills can be leveled to increase their utilities and damage multipliers.

Cooldown: the time it takes to be able to re-cast a move such as an Elemental Skill or Elemental Burst.

Artifacts: equipment consisting of a feather, flower, timepiece (sands), goblet, and circlet which provide additional stats to a characters base stats. Due to artifacts having both a main stat and many random substats, artifacts generate variation in character stats. Additionally, set bonuses can be obtained by equipping at least two (2) or four (4) artifacts of the same set, and these grant special effects such as bonus stats.

Adventure Rank: a measure of experience in the game which is calculated using cumulative Adventure Experience points. These points are obtained through completing daily quests, progressing through the story of the game, opening chests and exploring, completing domain challenges, and spending resin.

atk: a character “stat” which is often used to determine the damage dealt by various moves.

HP: a character “stat” which determines how much damage a character can take before falling in battle.

def: a character “stat” which determines how much damage a character takes for any given enemy attack.

RES: similar to def, decreases damage taken from a specific elemental type.

Elemental Mastery: abbreviated as “EM”, determines the damage dealt by elemental reactions.

Crit: a critical strike occurs randomly when landing hits based on a character stat called “crit rate”. Crit rate is equal to the probability of landing a critical strike. Damage from critical strikes is multiplied by (1+cdmg), crit damage. The base value of crit rate is 5%, and the base value of crit damage is 50%.

Character level: characters can be leveled up to unlock passive abilities and additional base stats. The maximum character level is 90.

Polearm: one of the five weapon archetypes in Genshin impact. Different types of polearms can be obtained through exploration and a mechanic called “wishing” (gambling).

Element: there are seven (7) elements in Teyvat, pyro, hydro, cryo, electro, anemo, dendro, and geo.

Elemental damage bonus: a multiplier which increases damage of a specific elemental type. Attacks with no associated element are typically considered “physical” attacks. Physical damage is multiplied by physical damage bonus.

Normal Attack: a skill within every character’s kit which deals physical damage for polearm characters without an elemental infusion. Shenhe herself cannot imbue her polearm with any element, but other characters, such as Chongyun, can enable her to do so. This skill can also be leveled.

Weapon level: similarly to character levels, weapons can have their levels increased up to level 90 in order to maximize their main stat and substat. In the case of a character like Shenhe, having her polearm at level 90 is imperative, as she needs the additional base atk that it provides in order to buff her team’s damage.

Refinement: weapons can be refined up to rank 5, improving their special effects.

DPS: short for “damage per second”, which is both a measurable quantity and a character role. A character that is a “DPS” deals considerable damage, as opposed to solely providing support utilities.

Hypercarry: A character around which a team is centered in order to maximize that specific character’s personal damage.

Passive: An effect or ability of a character or weapon which provides special effects to the character, often under a set of conditions.

Equipment / Gear: In-game items such as weapons and artifacts which provide extra power to your characters.

Main stat: A primary attribute of an artifact or weapon which increases its corresponding character stat (atk, EM, ER, etc.).

Substat: A secondary attribute of an artifact or weapon which increases its corresponding character stat.

Build: The way in which a player decides to gear their character.

Playstyle: The way in which a player decides to play their character, often based upon their build.

Shenhe’s kit is one of the more complicated ones in the character roster. Her damage is disguised through other characters’ damage bonuses and her buffing utilities. This makes her widely misunderstood as a character, and also leads to sub-obtimal builds within the community.

Shenhe’s elemental skill “Spring Spirit Summoning” generates three (3) cryo particles on skill-press and four (4) cryo particles on skill-hold. Her press cooldown is 10 seconds, while her hold cooldown is 15 seconds. This limits her energy generation to a maximum of 0.3 particles per second.

Shenhe’s “Icy Quills” are considered additive damage, which scale on party member’s multiplicative stats (critical rate, critical damage, cryo damage, etc.) and only trigger on non-transformative cryo damage. Her skill-press generates five (5) Icy Quills for each teammate to use, and her skill-hold generates seven (7). Each Icy Quill’s base addition to the damage is calculated using solely Shenhe’s atk stat and skill talent level. This means that Icy Quill damage is optimized by increasing Shenhe’s atk and skill talent level.

Shenhe has multiple sources of utility in her kit. Her 4th ascension passive talent provides characters with 15% skill and burst damage bonus when using her skill-press, and 15% normal and charged attack damage bonus when using her skill-hold. Her 1st ascension passive talent provides characters within the area of effect (AoE) of her elemental burst “Divine Maiden’s Deliverance” a 15% cryo damage bonus. Her elemental burst has a duration of 12 seconds, a cooldown of 20 seconds, and decreases enemies’ physical and cryo RES by a maximum of 15% at talent level 10. One of her choices of artifact sets, the 4-piece Noblesse Oblige provides the entire team with a 20% atk bonus, from which she can also benefit.

Because Shenhe’s Icy Quills scale with atk, increasing the equipped polearm level to its max of 90 will significantly increase Icy Quill damage. Due to many of Shenhe’s buff utilities being restricted to her burst, increasing her burst uptime will increase your team’s damage output, which is dependent on Shenhe’s energy recharge stat. This creates an important balance between ER and atk on Shenhe. This will be one of the main investigations of this study.

Method and Data Description

In this analysis, I wish to observe trends within the character statistics of Shenhes which are fully built. Fully built Shenhes are indicative that the player is what we would call a “Shenhe main”, meaning that they use their Shenhe to clear content within the game. It is important to note that players of unbuilt Shenhes may still be Shenhe mains, but Shenhes with builds-in-progress are not the target population of this study.

Within the game, there is a feature called the “Co-Op Menu”, which generates a list of players online which one can join and play. In the Co-Op Menu, a player can choose to display up to eight (8) of their characters so that others may see. They can also choose whether their “character details” (stats) are visible. To generate this dataset, myself and three friends went through the Co-Op Menus in our games in order from top to bottom, and checked for players who had Shenhe in their display. Those which chose to make their character details visible had their stats recorded.

There are a couple sources of sampling error and other clarifications that must be made. There is no confirmation from the developers that the Co-Op menu is truly random. We never encountered repeats in our data collection, which is promising, but still not confirmation of the randomness or pseudo-randomness of the sample. Another issue is that we did not hold the time at which we searched for players constant, and because the Co-Op menu only displays other players that are online, there may have been some confounding due to the times at which we collected our observations throughout October of 2022. Additionally, the Co-Op Menu is restricted by the player’s server, which in the case of this dataset is solely the America server. It is important to note that players on the America server may or may not be in the western hemisphere, as players can choose to create their account on any server they so choose. The final obvious source of error is that the people who displayed their Shenhes did so voluntarily, and therefore the sample may not be truly representative of all Shenhes in which we are interested.

A couple of variables within the dataset were contrived using other data from the given observation. Particularly, the ER_req_met, describing whether a player had reached KQM’s ER requirement, was quantified on whether their ER stat was greater than 177.5, or in the case of a Shenhe equipping the polearm “Favonius Lance”, if their ER stat was greater than 162.5. The “build_type” variable, similarly was qualified on the following logical structure:

if exclusion criteria met, then gain role “incomplete”
else if constellation == 6, then gain role “whale” else if ER_req_met == 1, then gain role “utility_buffer”
else if set_bonus == “4NO”, then gain role “utility_buffer”
else if polearm_name == “Favonius_Lance” and crit_rate >= 50. then gain role “utility_buffer”
else if cryo_dmg != 0 and phys_dmg != 0, then gain role “hybrid”
else if cryo_dmg != 0, then gain role “cryo_dps”
else if phys_dmg != 0, then gain role “phys_dps”
else, gain role “quill only”

The statistics we will use to describe and analyze the data are the following:

  1. Sample and group means of multiple variables (mostly atk and ER); this will provide information on the average atk and ER of Shenhes in the dataset.

  2. Sample standard deviation; this will provide information on the spread of the distributions of multiple variables such as atk and ER.

  3. Sample proportion; this will provide information on the percentage of users exhibiting a certain characteristic.

  4. Standard Error: this will provide information on the spread of the sampling distributions of multiple variables of the dataset. This will not be reported, rather, it will be used in constructing confidence intervals.

  5. Mean difference: this will provide information on the difference between the centers of the distributions of a common variable between two groups.

  6. Effect Size: this will provide information on the importance of a difference in means.

  7. p-value: this will provide information on the likelihood of a type-I error. in other words, this value describes the chance of rejecting a true null hypothesis.

  8. raw counts: this will provide information on the number of occurrences of a certain condition. These will mostly be used in calculating p-values.

The overarching question which this study attempts to answer is:

How are the factors within a player’s control are correlated with Shenhe’s atk and ER stats? How does the answer to this question compare to KQM’s descriptions and standards for Shenhe?

# load the data

setwd("C:/Users/15857/Downloads")
shenhe_original <- read_csv("shenhe_original_data.csv")
## Rows: 249 Columns: 34
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr  (9): polearm name, refinement, set bonus, flower lvl, feather lvl, sand...
## dbl (24): Adventure Rank, Character lvl, atk, def, EM, crit rate, crit dmg, ...
## num  (1): HP
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Cleaning

Here I cleaned out the dataset to remove observations which were unhelpful for analysis of my target population, and to make it more friendly to use in RStudio. The exclusion criteria for “fully built” Shenhes are as follows:

  1. The sum of all artifact levels is less than 95
  2. The equipped polearm’s level is not 90
  3. The character level is less than 80

Artifact levels are a general metric of investment into a character, and a build is generally considered “complete” when all artifacts are at level 20. In the case of Shenhe, having a max level polearm is necessary, because she will otherwise lose out on a large amount of atk, which is necessary for her role as a partial damage dealer. Lastly, Shenhe also gains base atk from her personal level, which means a character level no less than 80 is necessary to achieve a near-optimal ceiling of damage and support potential.

# Change spaces to underscores, rename some of the variables.  
names(shenhe_original) <- gsub(" ", "_", names(shenhe_original))
names(shenhe_original) <- gsub("Adventure_Rank", "AR", names(shenhe_original))
names(shenhe_original) <- gsub("Character_lvl", "char_lvl", names(shenhe_original))
names(shenhe_original) <- gsub("healing_bonus", "HB", names(shenhe_original))  

# Remove the variables whose values were 0 for all observations.  
shenhe <- shenhe_original %>%
  select(-pyro_dmg, -hydro_dmg, -dendro_dmg, -electro_dmg, -anemo_dmg)

# Allow R to read appropriate variables as numeric.  

shenhe$flower_lvl <- as.numeric(shenhe$flower_lvl)
## Warning: NAs introduced by coercion
shenhe$feather_lvl <- as.numeric(shenhe$feather_lvl)
## Warning: NAs introduced by coercion
shenhe$sands_lvl <- as.numeric(shenhe$sands_lvl)
## Warning: NAs introduced by coercion
shenhe$goblet_lvl <- as.numeric(shenhe$goblet_lvl)
## Warning: NAs introduced by coercion
shenhe$circlet_lvl <- as.numeric(shenhe$circlet_lvl)
## Warning: NAs introduced by coercion
shenhe$refinement <- as.numeric(shenhe$refinement)
## Warning: NAs introduced by coercion
shenhe$ER_req_met <- as.numeric(shenhe$ER_req_met)
shenhe$NA_talent_lvl <- as.numeric(shenhe$NA_talent_lvl)
shenhe$E_talent_lvl <- as.numeric(shenhe$E_talent_lvl)
shenhe$Q_talent_lvl <- as.numeric(shenhe$Q_talent_lvl)

# Filter following the exclusion criteria:  
#     1) Exclude if the sum of the artifact levels is less than 95.  
#     2) Exclude if the polearm level is not 90.  
#     3) Exclude if the character level is less than 80.  

shenhe <- shenhe %>%
  mutate(artifact_total = flower_lvl + feather_lvl + sands_lvl + goblet_lvl + circlet_lvl) %>%
  filter(artifact_total >= 95) %>%
  filter(polearm_lvl == 90) %>%
  filter(char_lvl >= 80)  

# Remove the healing bonus variable as it is uniformly 0 in the new filtered data.  

shenhe <- shenhe %>%
  select(-HB)  

# Sort the set bonuses by the exact effects they provide (some are identical)  
shenhe$set_bonus <- gsub("2BC2PF", "phys-phys", shenhe$set_bonus)  
shenhe$set_bonus <- gsub("2BC2SR", "phys-atk", shenhe$set_bonus)  
shenhe$set_bonus <- gsub("2BS2GF", "cryo-atk", shenhe$set_bonus)  
shenhe$set_bonus <- gsub("2BS2SR", "cryo-atk", shenhe$set_bonus)  
shenhe$set_bonus <- gsub("2Eoa2GF", "atk-atk", shenhe$set_bonus)  
shenhe$set_bonus <- gsub("2EoaO2GF", "atk-atk", shenhe$set_bonus)  
shenhe$set_bonus <- gsub("2EoaO2SR", "atk-atk", shenhe$set_bonus)  
shenhe$set_bonus <- gsub("2GF2BS", "cryo-atk", shenhe$set_bonus)  
shenhe$set_bonus <- gsub("2GF2NO", "atk-noblesse", shenhe$set_bonus)  
shenhe$set_bonus <- gsub("2GF2SR", "atk-atk", shenhe$set_bonus)  
shenhe$set_bonus <- gsub("2GF2VH", "atk-atk", shenhe$set_bonus)  
shenhe$set_bonus <- gsub("2GF2WT", "atk-EM", shenhe$set_bonus)  
shenhe$set_bonus <- gsub("2SR2VH", "atk-atk", shenhe$set_bonus)  
shenhe$set_bonus <- gsub("4BS", "full-blizzard", shenhe$set_bonus)  
shenhe$set_bonus <- gsub("4EoSF", "full-emblem", shenhe$set_bonus)  
shenhe$set_bonus <- gsub("4GF", "full-gladiator", shenhe$set_bonus)  
shenhe$set_bonus <- gsub("4NO", "full-noblesse", shenhe$set_bonus)  
shenhe$set_bonus <- gsub("2BS", "cryo", shenhe$set_bonus)  
shenhe$set_bonus <- gsub("2GF", "atk", shenhe$set_bonus)  
shenhe$set_bonus <- gsub("2SR", "atk", shenhe$set_bonus)  

# And to reduce the length of the largest polearm names
shenhe$polearm_name <- gsub("Primordial_Jade_Winged_Spear", "Jade",
                            shenhe$polearm_name)
shenhe$polearm_name <- gsub("Staff_of_Scarlet_Sands", "Scarlet_Sands",
                            shenhe$polearm_name)
shenhe$polearm_name <- gsub("Prototype_Starglitter", "Starglitter",
                            shenhe$polearm_name)
shenhe$polearm_name <- gsub("Engulfing_Lightning", "Engulfing",
                            shenhe$polearm_name)
shenhe$polearm_name <- gsub("Vortex_Vanquisher", "Vortex",
                            shenhe$polearm_name)
shenhe$polearm_name <- gsub("Missive_Windspear", "Windspear",
                            shenhe$polearm_name)
shenhe$polearm_name <- gsub("Wavebreakers_Fin", "Wavebreaker",
                            shenhe$polearm_name)
shenhe$polearm_name <- gsub("Blackcliff_Pole", "Blackcliff",
                            shenhe$polearm_name)
shenhe$polearm_name <- gsub("Skyward_Spine", "Skyward",
                            shenhe$polearm_name)
shenhe$polearm_name <- gsub("Calamity_Queller", "Calamity",
                            shenhe$polearm_name)
shenhe$polearm_name <- gsub("Favonius_Lance", "Favonius",
                            shenhe$polearm_name)

#* Remove any builds categorized as "incomplete". The one remaining observation 
#* which was "incomplete" after these filtering criteria was equipped with a 
#* geo damage bonus goblet, which Shenhe cannot utilize, and provides
#* sufficient evidence that this user simply had not finished building their
#* Shenhe. Only one observation has shield_strength, and it is due to their
#* equipped polearm "vortex_vanquisher", and since the variable shield_strength
#* is unuseful in the analysis, it can be removed. The observation which used
#* "vortex_vanquisher" is still, however, completely valid and should be
#* included in the dataset. The artifact level and weapon level variables were 
#* simply a means towards filtering the data, and therefore can be removed from
#* the dataset.

shenhe <- shenhe %>%
  filter(build_type != "incomplete")

shenhe <- shenhe %>%
  select(-geo_dmg, -shield_strength, -flower_lvl, -feather_lvl, -sands_lvl,
         -goblet_lvl, -circlet_lvl, -polearm_lvl)

#* After all the filtering, 100/249 observations of Shenhes on display did not
#* meet my criteria of being "fully built", and were removed.

Plotting the Data

The following is a bar graph of the polearms these players had equipped. The most popular choices were:
1) Calamity Queller
2) Favonius Lance
3) Skyward Spine
4) Missive Windspear
5) Wavebreaker’s Fin (tie)
5) Primordial Jade Winged Spear (tie)

polearms_barchart <- shenhe %>%
  ggplot() +
  geom_bar(aes(x = polearm_name)) +
  coord_flip()

polearms_barchart

The following is a bar graph of the set bonuses these players had. The most common set by far was a double atk set bonus (such as 2 gladiator and 2 shimenawa). The next most popular choice was a full noblesse oblige set, which is the KQM recommendation.

setbonus_barchart <- shenhe %>%
  ggplot() +
  geom_bar(aes(x = set_bonus)) +
  coord_flip()

setbonus_barchart

The following is a bar graph of the build types of the Shenhes which met the inclusion criteria. The two most common builds were, in first, full Icy Quill damage builds, and second buffing and utility builds.

buildtype_barchart <- shenhe %>%
  ggplot() +
  geom_bar(aes(x = build_type)) +
  coord_flip()

buildtype_barchart

The following are histograms of all the important quantitative variables in the dataset.

  1. Adventure Rank is highly skewed left. This makes sense because the exclusion criteria made it difficult for low-experience players to get through.
  2. Character level has local maxima at lvl 90 and lvl 80. The distribution could be described as skewed left.
  3. HP appears relatively bell shaped except for a peak between 23k and 24k.
    The Shapiro-Wilks test concludes that there is strong evidence that HP is not normally distributed.
  4. atk appears quite bell shaped, and the Shapiro-Wilks test provides no evidence of non-normality.
  5. def is skewed right, and the Shapiro-Wilks test concludes that there is strong evidence that def is not normally distributed.
  6. EM is highly skewed right, and the Shapiro-Wilks test concludes that there is strong evidence that EM is not normally distributed.
  7. crit rate and crit dmg appear fairly bell shaped with slight right skewing. The Shapiro-Wilks test provides weak evidence that crit rate is not normally distributed, and strong evidence that crit dmg is not normally distributed.
  8. ER is skewed right, and the Shapiro-Wilks test concludes that there is strong evidence that ER is not normally distributed.
  9. cryo and phys dmg are both extremely skewed right, and mostly zero. This makes sense because not many people choose to play Shenhe as an on field DPS or hypercarry.
  10. refinement has two local maxima at 1 and 5. This makes sense because Calamity Queller and Favonius lance were the most common polearm choices, the former being extremely hard to obtain (leading to more r1), and the latter being much easier to obtain (leading to more r5).
  11. constellation is extremely skewed right, which makes sense because most people do not acquire more than a single copy of a limited character like Shenhe.
  12. The talent level histograms were strange, because the variables are discrete and typically between 1-10, but can be increased by constellations. The distributions could certainly be split by build type, and may then appear more understandable, however that could be a focus of a different study.
par(mfrow = c(2,2))

hist(shenhe$AR, col = 'steelblue')

hist(shenhe$char_lvl, col = 'steelblue')

hist(shenhe$HP, col = 'steelblue')
print("normality of HP:")
## [1] "normality of HP:"
shapiro.test(shenhe$HP)
## 
##  Shapiro-Wilk normality test
## 
## data:  shenhe$HP
## W = 0.96788, p-value = 0.001465
hist(shenhe$atk, col = 'steelblue')

print("normality of atk:")
## [1] "normality of atk:"
shapiro.test(shenhe$atk)
## 
##  Shapiro-Wilk normality test
## 
## data:  shenhe$atk
## W = 0.98724, p-value = 0.1885
hist(shenhe$def, col = 'steelblue')
print("normality of def:")
## [1] "normality of def:"
shapiro.test(shenhe$def)
## 
##  Shapiro-Wilk normality test
## 
## data:  shenhe$def
## W = 0.94818, p-value = 2.465e-05
hist(shenhe$EM, col = 'steelblue')
print("normality of EM:")
## [1] "normality of EM:"
shapiro.test(shenhe$EM)
## 
##  Shapiro-Wilk normality test
## 
## data:  shenhe$EM
## W = 0.86292, p-value = 1.884e-10
hist(shenhe$crit_rate, col = 'steelblue')
print("normality of crit_rate:")
## [1] "normality of crit_rate:"
shapiro.test(shenhe$crit_rate)
## 
##  Shapiro-Wilk normality test
## 
## data:  shenhe$crit_rate
## W = 0.98435, p-value = 0.08917
hist(shenhe$crit_dmg, col = 'steelblue')

print("normality of crit_dmg:")
## [1] "normality of crit_dmg:"
shapiro.test(shenhe$crit_dmg)
## 
##  Shapiro-Wilk normality test
## 
## data:  shenhe$crit_dmg
## W = 0.9743, p-value = 0.006763
hist(shenhe$ER, col = 'steelblue')
print("normality of ER:")
## [1] "normality of ER:"
shapiro.test(shenhe$ER)
## 
##  Shapiro-Wilk normality test
## 
## data:  shenhe$ER
## W = 0.96959, p-value = 0.00218
hist(shenhe$cryo_dmg, col = 'steelblue')

hist(shenhe$phys_dmg, col = 'steelblue')

hist(shenhe$refinement, col = 'steelblue')

hist(shenhe$constellation, col = 'steelblue')

hist(shenhe$NA_talent_lvl, col = 'steelblue')

hist(shenhe$E_talent_lvl, col = 'steelblue')

hist(shenhe$Q_talent_lvl, col = 'steelblue')

print("normality of Q_talent_lvl:")
## [1] "normality of Q_talent_lvl:"
shapiro.test(shenhe$Q_talent_lvl)
## 
##  Shapiro-Wilk normality test
## 
## data:  shenhe$Q_talent_lvl
## W = 0.90287, p-value = 2.095e-08
par(mfrow = c(1,1))

t Confidence Intervals

Because much of the data is non-parametric, the only variables which I wish to describe in terms of confidence intervals are atk, ER, and ER_req_met. The following are the interpretations of the confidence intervals of each of those:

  1. We can be 95% confident that the population mean atk of Shenhes on display is between 3129.922 and 3301.716.

  2. We can be 95% confident that the population mean ER of Shenhes on display is between 146.966 and 156.533.

  3. We can be 95% confident that the population proportion of Shenhes on display which meet standard ER requirements is between 0.178 and 0.319.

conf.int <- function(quantvar, n, conf.level = 0.95){
  point_estimate <- mean(quantvar)
  MoE <- qt( 1 - (1 - conf.level)/2 , df = (n - 1)) * ( sd(quantvar)/sqrt(n) )
  
  confidence_interval <- point_estimate + c(-MoE, MoE)
  
  return(confidence_interval)
}

conf.int(shenhe$atk, n = 149)
## [1] 3129.922 3301.716
conf.int(shenhe$ER, n = 149)
## [1] 146.9655 156.5325
conf.int(shenhe$ER_req_met, n = 149)
## [1] 0.1781432 0.3185011

Summary of Reference Groups

Because we will use Noblesse Oblige and Favonius Lance as reference frames for all other gear choices, it is important to understand their individual statistics.

The following are the interpretations of the constructed confidence intervals:

  1. We can be 95% confident that the population mean atk of Shenhes on display with the 4 piece noblesse set is between 2544.744 and 2949.812.

  2. We can be 95% confident that the population mean ER of Shenhes on display with the 4 piece noblesse set is between 149.368 and 180.621.

  3. We can be 95% confident that the population mean atk of Shenhes on display equpping the Favonius Lance is between 2685.836 and 2990.016.

  4. We can be 95% confident that the population mean ER of Shenhes on display equipping the Favonius Lance is between 154.775 and 173.092.

shenhe_noblesse <- shenhe %>%
  filter(set_bonus %in% c("full-noblesse"))



shenhe_favlance <- shenhe %>%
  filter(polearm_name %in% c("Favonius"))

conf.int(shenhe_noblesse$atk, nrow(shenhe_noblesse))
## [1] 2544.744 2949.812
conf.int(shenhe_noblesse$ER, nrow(shenhe_noblesse))
## [1] 149.3676 180.6213
conf.int(shenhe_favlance$atk, nrow(shenhe_favlance))
## [1] 2685.836 2990.016
conf.int(shenhe_favlance$ER, nrow(shenhe_favlance))
## [1] 154.7749 173.0917
# for use only in the conclusion
shenhe_atk_atk <- shenhe %>%
  filter(set_bonus %in% c("atk-atk"))
print("for conclusion only:")
## [1] "for conclusion only:"
conf.int(shenhe_atk_atk$ER, nrow(shenhe_atk_atk))
## [1] 145.8108 156.9070

Inadequacy of ANOVA

I do not believe that analysis of variance is appropriate for this data because there is too little information on the distribution of ER, however, this section intends to demonstrate how one may go about using ANOVA on the data. A non-parametric post-hoc test can work, but ultimately I wish to use bootstrapping to compare group means for this dataset.

The residuals of the model do not have constant variance, and the scale-location plot is noticeably curved, therefore analysis of variance is not an appropriate statistical method.

hist(shenhe$ER)

shapiro.test(shenhe$ER)
## 
##  Shapiro-Wilk normality test
## 
## data:  shenhe$ER
## W = 0.96959, p-value = 0.00218
#* because the distribution of Shenhe's energy recharge is evidently non-normal, 
#* if we wish to do analysis of variance, we must transform the data because 
#* there are subgroups in the data with too few observations to satisfy the 
#* central limit theorem (e.g. sample size of engulfing lightning users = 3).

ER_transformed <- log(shenhe$ER)
hist(ER_transformed)

shapiro.test(ER_transformed)
## 
##  Shapiro-Wilk normality test
## 
## data:  ER_transformed
## W = 0.98956, p-value = 0.3342
ER_anova <- aov(ER_transformed ~ polearm_name, data = shenhe)
summary(ER_anova)
##               Df Sum Sq Mean Sq F value   Pr(>F)    
## polearm_name  18  2.227 0.12374    5.06 1.38e-08 ***
## Residuals    130  3.179 0.02446                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
plot(ER_anova)
## Warning: not plotting observations with leverage one:
##   66, 124, 130, 140, 149

## Warning in sqrt(crit * p * (1 - hh)/hh): NaNs produced
## Warning in sqrt(crit * p * (1 - hh)/hh): NaNs produced

# For post-hoc testing you can use TukeyHSD(ER_anova)

Hypothesis Testing

The variables of interest for hypothesis testing are:

1) atk  

2) ER  

3) polearm name  

4) set bonus  

More specifically, we are interested in how gear (factors which the player has direct control over such as polearm and set bonus) impact atk and ER. The “build type” variable is not of interest, as it was constructed using other data such as polearm and set bonus, and thus must be collinear.

The following are hypotheses for each categorical-quantitative relationship:

ER vs. Polearm:
H0: There is no difference in mean ER between any polearm type.
Ha: There is a difference in mean ER for at least one polearm type.

ER vs. Set Bonus:
H0: There is no difference in mean ER between any set bonuses.
Ha: There is a difference in mean ER for at least one set bonus.

atk vs. Polearm: H0: There is no difference in mean atk between any polearm type.
Ha: There is a difference in mean atk for at least one polearm type.

atk vs. Set Bonus:
H0: There is no difference in mean atk between any set bonuses.
Ha: There is a difference in mean atk for at least one set bonus.

The Kruskal-Wallis test is a non-parametric alternative to ANOVA which we will use to assess these hypotheses. The corresponding non-parametric post-hoc test to the Kruskal-Wallis test which we found was the Dunn Test, however we will not use this test to complete the individual pairwise comparisons. Because the test is non-parametric, the hypotheses must be modified to reflect a shift in distributions rather than a difference in means. The mean difference hypotheses may still apply to the individual pairwise comparisons.

At a significance level of alpha = 0.05, the Kruskal-Wallis returns the following:
1) There is very strong evidence to suggest that at least one of the polearm types has a differing distribution of ER. This result additionally warrants post-hoc testing. 2) There is no evidence to suggest that at any of the set bonuses has a differing distribution of ER. This result does not warrant post-hoc testing.
3) There is very strong evidence to suggest that at least one of the polearm types has a differing distribution of atk. This result additionally warrants post-hoc testing.
4) There is very strong evidence to suggest that at least one of the set bonuses has a differing distribution of atk. This result additionally warrants post-hoc testing.

# Because there are categories with less than 5 observations, a non-parametric
# test is a preferable method.

kruskal.test(ER ~ polearm_name, data = shenhe)
## 
##  Kruskal-Wallis rank sum test
## 
## data:  ER by polearm_name
## Kruskal-Wallis chi-squared = 61.46, df = 18, p-value = 1.186e-06
kruskal.test(ER ~ set_bonus, data = shenhe)
## 
##  Kruskal-Wallis rank sum test
## 
## data:  ER by set_bonus
## Kruskal-Wallis chi-squared = 18.237, df = 12, p-value = 0.1087
kruskal.test(atk ~ polearm_name, data = shenhe)
## 
##  Kruskal-Wallis rank sum test
## 
## data:  atk by polearm_name
## Kruskal-Wallis chi-squared = 59.529, df = 18, p-value = 2.438e-06
kruskal.test(atk ~ set_bonus, data = shenhe)
## 
##  Kruskal-Wallis rank sum test
## 
## data:  atk by set_bonus
## Kruskal-Wallis chi-squared = 59.244, df = 12, p-value = 3.099e-08
#* one of the options for post-hoc testing is the dunnTest under the package
#* "FSA", but as I said earlier, I wish to do bootstrapping. The syntax for
#* the dunnTest is as follows:
#* dunnTest(ER ~ polearm_name, data = shenhe)
#* etc.

The following code is a randomization test which scans through all pairwise combinations of a categorical variable “treatment”, and bootstraps to assess whether there is a difference in means. This is a much preferrable option to the t-test, because the small sample sizes (between 1 and 10) are insufficient to account for the highly skewed nature of the distribution of ER. Unfortunately, because there is very little information on the distribution of ER, it is not simple to create confidence intervals for the difference in means. Point estimates of the population effect size and population mean difference will simply need to be interpreted according to their corresponding p-values.

adi_saidi.RPT <- function(treatment, outcome, n = 1000, plot_dist = "FALSE") {
  treatment_factor_levels <- length(unique(treatment))
  tfl_choose2 <- treatment_factor_levels*(treatment_factor_levels - 1)/2
  treatment_combns <- matrix(, nrow = tfl_choose2, ncol = 2)
  ind <- 1
  
  for (i in 1:(treatment_factor_levels-1)) {
      for (j in (i+1):(treatment_factor_levels)) {
        treatment_combns[ind,1] <- unique(treatment)[i]
        treatment_combns[ind,2] <- unique(treatment)[j]
        ind <- ind+1
      }
    }
  
  TO_data <- data.frame(
      treatment,
      outcome)
  p_value <- c()
  effect_size <- c()
  treatment_1 <- c()
  treatment_2 <- c()
  mean_diff <- c()
  
  for (k in 1:(nrow(treatment_combns))) {
    data_filtering <- TO_data %>%
      filter(treatment %in% c(treatment_combns[k, 1], treatment_combns[k,2]))
    
    treatment_particular <- data_filtering$treatment
    outcome_particular <- data_filtering$outcome
    
    original <- diff(tapply(outcome_particular, treatment_particular, mean))
    mean_diff_dist = c()

    for(l in 1:n) {
      mean_diff_dist[l] = diff(by(outcome_particular, sample(treatment_particular, length(treatment_particular), FALSE), mean))
      }
    
    
    
    group1 <- data_filtering %>%
      filter(treatment %in% c(treatment_combns[k, 1]))
    group2 <- data_filtering %>%
      filter(treatment %in% c(treatment_combns[k, 2]))
    mean1 = mean(group1$outcome)
    mean2 = mean(group2$outcome)
    
    p_value[k] = sum(abs(mean_diff_dist) >= abs(original))/(n)
    mean_diff[k] = mean2 - mean1
    effect_size[k] = (mean2-mean1)/sd(outcome_particular)
    treatment_1[k] <- unique(treatment_particular)[1]
    treatment_2[k] <- unique(treatment_particular)[2]
  
    if (plot_dist == "TRUE") {
        hist(mean_diff_dist, breaks=50, col='grey', main="Randomization Distribution", 
           las=1, xlab=(unique(treatment_particular)))
        original <- diff(tapply(outcome_particular, treatment_particular, mean))
        abline(v=original, lwd=3, col= "red")
        abline(v=-original, lwd=3, col= "red")
      }
  
    
  }
  
  results <- data.frame(cbind(treatment_1, treatment_2, p_value, effect_size, mean_diff))
  
  return(results)
}

KQM uses the Favonius Lance as a reference frame for all other polearm choices, and we will use the same process in order to analyze their recommendations. The following are the results of the post-hoc test:

  1. Favonius Lance vs. Wavebreaker’s Fin:
    There is moderate evidence (p=0.025) to suggest that there is a difference in the mean ER of Shenhes equipping these two polearms. The sample mean difference in ER is a decrease of 18.619 ER. This difference has a medium associated effect size (-0.718), which indicates a relatively important difference in ER. Practically, this difference may be crucial in combat, because a Wavebreaker’s Fin Shenhe having a lack of ER could also limit their ability to utilize the burst damage bonus provided by the Wavebreaker’s passive.

  2. Favonius Lance vs. Skyward Spine:
    There is moderate evidence (p=0.044) to suggest that there is a difference in the mean ER of Shenhes equipping these two polearms. The sample mean difference in ER is an increase of 15.233 ER. This difference has a medium associated effect size (0.630), which indicates a relatively important difference in ER. Practically, this difference may not matter in combat, because the extra particles provided by the Favonius passive typically bridges a gap of about 15 ER. This however, may be a positive of the Skyward Spine, because its higher base atk could link to a higher overall atk, which we will assess in later testing.

  3. Favonius Lance vs. Calamity Queller:
    There is strong evidence (p=0.009) to suggest that there is a difference in the mean ER of Shenhes equipping these two polearms. The sample mean difference in ER is a decrease of 16.861 ER. This difference has a medium associated effect size (0.610), which indicates a relatively important difference in ER. Practically, this difference is hard to assess because many players with Calamity Queller either have constellations on their Shenhe, which decreases her energy requirement, or incorporate modified playstyles.

  4. Favonius Lance vs. Missive Windspear:
    There is strong evidence (p=0.000) to suggest that there is a difference in the mean ER of Shenhes equipping these two polearms. The sample mean difference in ER is a decrease of 27.84 ER. This difference has a large associated effect size (-1.013), which indicates an important difference in ER. Practically, this difference can ruin rotations when left unaddressed.

  5. Favonius Lance vs. Lithic Spear:
    There is moderate evidence (p=0.011) to suggest that there is a difference in the mean ER of Shenhes equipping these two polearms. The sample mean difference in ER is a decrease of 30.253 ER. This difference has a large associated effect size (-1.230), which indicates an important difference in ER. This has the same implications as in the previous case.

  6. Favonius Lance vs. Staff of Homa:
    There is weak evidence (p=0.089) to suggest that there is a difference in the mean ER of Shenhes equipping these two polearms. The sample mean difference in ER is a decrease of 48.433 ER. This difference has a large associated effect size (-1.977), which indicates an important difference in ER. Because of the larger p-value, it is very possible that the difference in population mean ER is closer to 0, so the implications of this case are very similar to the previous two.

  7. Favonius Lance vs. The Catch:
    There is no evidence (p=0.439) to suggest that there is a difference in the mean ER of Shenhes equipping these two polearms.

  8. Favonius Lance vs. Engulfing Lightning There is strong evidence (p=0.008) to suggest that there is a difference in the mean ER of Shenhes equipping these two polearms. The sample mean difference in ER is an increase of 43.433 ER. This difference has a large associated effect size (1.683), which indicates an important difference in ER. Practically, this difference remains the same because of Engulfing Lightning’s personal ER boost after casting a burst. Still, Favonius Lance provides energy for the entire team from its passive, which is an added layer of utility to consider when choosing a polearm for Shenhe.

  9. Favonius Lance vs. Primordial Jade Winged Spear:
    There is strong evidence (p=0.009) to suggest that there is a difference in the mean ER of Shenhes equipping these two polearms. The sample mean difference in ER is a decrease of 20.270 ER. This difference has a large associated effect size (-0.882), which indicates an important difference in ER. This has the same implications as in cases four, five, and six.

  10. Favonius Lance vs. Vortex Vanquisher:
    There is moderate evidence (p=0.046) to suggest that there is a difference in the mean ER of Shenhes equipping these two polearms. The sample mean difference in ER is a decrease of 38.983 ER. This difference has a large associated effect size (-1.573), which indicates an important difference in ER. I would not place much certainty on these values, because there were only two total observations for the Vortex Vanquisher polearm, which I do not believe is sufficient data to make any firm conclusions. The implications of this difference are still the same.

  11. Favonius Lance vs. Deathmatch:
    There is very strong evidence (p=0.000) to suggest that there is a difference in the mean ER of Shenhes equipping these two polearms. The sample mean difference in ER is a decrease of 56.800 ER. This difference has a large associated effect size (-2.028), which indicates an important difference in ER. It is unclear why the difference in mean ER for these two polearms is so large, but one of the contributing factors certainly could be that there were only three (3) observations of Shenhes equipping Deathmatch in the first place. This certainly could have yielded an inappropriate p-value, because there were no combinations within the resampling which produced results of the same magnitude or higher, but that certainly does not mean that those cases do not exist outside of the dataset. This difference, still, has the same implications as the previous.

  12. Favonius Lance vs. Blackcliff Pole:
    There is weak evidence (p=0.066) to suggest that there is a difference in the mean ER of Shenhes equipping these two polearms. The sample mean difference in ER is a decrease of 58.733 ER. This difference has a large associated effect size (-2.323), which indicates an important difference in ER. Because of the larger p-value, it is very possible that the difference in population mean ER is closer to 0, and given that there was only one observation of Blackcliff Pole, these values are not very consequential.

  13. Favonius Lance vs. Dragon’s Bane:
    There is weak evidence (p=0.086) to suggest that there is a difference in the mean ER of Shenhes equipping these two polearms. The sample mean difference in ER is a decrease of 48.433 ER. This difference has a large associated effect size (-1.977), which indicates an important difference in ER. Because of the larger p-value, it is very possible that the difference in population mean ER is closer to 0, and given that there was only one observation of Dragon’s Bane, these values are not very consequential.

  14. Favonius Lance vs. Royal Spear:
    There is no evidence (p=0.618) to suggest that there is a difference in the mean ER of Shenhes equipping these two polearms.

  15. Favonius Lance vs. Prototype Starglitter:
    There is no evidence (p=0.916) to suggest that there is a difference in the mean ER of Shenhes equipping these two polearms.

  16. Favonius Lance vs. Staff of Scarlet Sands:
    There is nearly no evidence (p=0.098) to suggest that there is a difference in the mean ER of Shenhes equipping these two polearms.

  17. Favonius Lance vs. White Tassel:
    There is no evidence (p=0.409) to suggest that there is a difference in the mean ER of Shenhes equipping these two polearms.

  18. Favonius Lance vs. Crescent Pike: There is weak evidence (p=0.075) to suggest that there is a difference in the mean ER fo Shenhes equipping these two polearms. The sample mean difference in ER is a decrease of 44.533 ER. This difference has a large associated effect size (-1.838), which indicates an important difference in ER. Because of the larger p-value, it is very possible that the difference in population mean ER is closer to 0. Additionally, Shenhes using Crescent Pike are usually physical DPS, and do not gain much utility from casting their burst.

set.seed(27)

adi_saidi.RPT(shenhe$polearm_name, shenhe$ER)
##       treatment_1   treatment_2 p_value         effect_size         mean_diff
## 1        Favonius   Wavebreaker   0.025  -0.718283359872518 -18.6190476190476
## 2        Favonius       Skyward   0.044   0.629952648030062  15.2333333333333
## 3        Favonius      Calamity   0.009   -0.61044759851201 -16.8611111111111
## 4        Favonius     Windspear       0   -1.01309602271536            -27.84
## 5        Favonius  Lithic_Spear   0.011   -1.23038500399815 -30.2533333333333
## 6        Favonius Staff_of_Homa   0.089     -1.977424784088 -48.4333333333333
## 7        Favonius     The_Catch   0.439   0.471422269275313              10.5
## 8        Favonius     Engulfing   0.008    1.68261141313218  43.4333333333333
## 9        Favonius          Jade   0.009  -0.881692142189236 -20.2690476190476
## 10       Favonius        Vortex   0.046   -1.57338336609433 -38.9833333333333
## 11       Favonius    Deathmatch       0   -2.02758558055394             -56.8
## 12       Favonius    Blackcliff   0.066   -2.32284465596971 -58.7333333333333
## 13       Favonius  Dragons_Bane   0.082     -1.977424784088 -48.4333333333333
## 14       Favonius   Royal_Spear   0.618  -0.315895971217589 -7.58333333333334
## 15       Favonius   Starglitter   0.916   -0.22135710746494 -5.03333333333333
## 16       Favonius Scarlet_Sands   0.098    -1.7649662815073 -42.5333333333333
## 17       Favonius  White_Tassel   0.409  -0.865582348603339 -19.9333333333333
## 18       Favonius Crescent_Pike   0.076   -1.83814255143607 -44.5333333333333
## 19    Wavebreaker       Skyward   0.001    1.12524351583811  33.8523809523809
## 20    Wavebreaker      Calamity   0.826  0.0625080585260945  1.75793650793651
## 21    Wavebreaker     Windspear   0.369  -0.345769211997543 -9.22095238095238
## 22    Wavebreaker  Lithic_Spear   0.386  -0.466626425696863 -11.6342857142857
## 23    Wavebreaker Staff_of_Homa   0.208   -1.08479593025251 -29.8142857142857
## 24    Wavebreaker     The_Catch   0.104    1.06356792627564  29.1190476190476
## 25    Wavebreaker     Engulfing   0.003    1.77508289823048   62.052380952381
## 26    Wavebreaker          Jade   0.863 -0.0746792764068187 -1.65000000000001
## 27    Wavebreaker        Vortex   0.293  -0.755632924941543 -20.3642857142857
## 28    Wavebreaker    Deathmatch   0.035   -1.31645882496883 -38.1809523809524
## 29    Wavebreaker    Blackcliff   0.149   -1.41527159770657 -40.1142857142857
## 30    Wavebreaker  Dragons_Bane   0.208   -1.08479593025251 -29.8142857142857
## 31    Wavebreaker   Royal_Spear   0.648   0.389336065213161  11.0357142857143
## 32    Wavebreaker   Starglitter   0.743   0.510437105499159  13.5857142857143
## 33    Wavebreaker Scarlet_Sands   0.339  -0.882557391240444 -23.9142857142857
## 34    Wavebreaker  White_Tassel   0.937 -0.0498102314533053 -1.31428571428572
## 35    Wavebreaker Crescent_Pike   0.374  -0.952069631664494 -25.9142857142857
## 36        Skyward      Calamity       0   -1.03843148555682 -32.0944444444444
## 37        Skyward     Windspear       0   -1.32105785233668 -43.0733333333333
## 38        Skyward  Lithic_Spear   0.001   -1.57588548602325 -45.4866666666667
## 39        Skyward Staff_of_Homa   0.057   -2.35753199465594 -63.6666666666667
## 40        Skyward     The_Catch   0.749  -0.217200827736025 -4.73333333333332
## 41        Skyward     Engulfing   0.061    1.16961664255121              28.2
## 42        Skyward          Jade       0     -1.314024363035 -35.5023809523809
## 43        Skyward        Vortex   0.015   -1.92947021908153 -54.2166666666667
## 44        Skyward    Deathmatch   0.001   -2.13617992278428 -72.0333333333333
## 45        Skyward    Blackcliff   0.042   -2.60873868661879 -73.9666666666667
## 46        Skyward  Dragons_Bane   0.065   -2.35753199465594 -63.6666666666667
## 47        Skyward   Royal_Spear   0.269  -0.896122982815997 -22.8166666666667
## 48        Skyward   Starglitter   0.442  -0.874096591302988 -20.2666666666667
## 49        Skyward Scarlet_Sands   0.093   -2.19659968696112 -57.7666666666667
## 50        Skyward  White_Tassel   0.157   -1.45889045186491 -35.1666666666667
## 51        Skyward Crescent_Pike   0.115   -2.25259152565636 -59.7666666666667
## 52       Calamity     Windspear     0.2  -0.389102647056902 -10.9788888888889
## 53       Calamity  Lithic_Spear   0.313  -0.483316138799679 -13.3922222222222
## 54       Calamity Staff_of_Homa   0.246   -1.09463242146087 -31.5722222222222
## 55       Calamity     The_Catch   0.094     0.9548014986409  27.3611111111111
## 56       Calamity     Engulfing       0    1.87392290782206  60.2944444444445
## 57       Calamity          Jade   0.664  -0.132302728838222 -3.40793650793651
## 58       Calamity        Vortex   0.307  -0.772676656277033 -22.1222222222222
## 59       Calamity    Deathmatch   0.019   -1.34498169858253 -39.9388888888889
## 60       Calamity    Blackcliff   0.165   -1.43422392330422 -41.8722222222222
## 61       Calamity  Dragons_Bane   0.227   -1.09463242146087 -31.5722222222222
## 62       Calamity   Royal_Spear   0.744   0.319319257136099  9.27777777777777
## 63       Calamity   Starglitter    0.72   0.415908020529133  11.8277777777778
## 64       Calamity Scarlet_Sands   0.392  -0.894998814664042 -25.6722222222222
## 65       Calamity  White_Tassel   0.949  -0.108266857600666 -3.07222222222222
## 66       Calamity Crescent_Pike   0.305   -0.96303784637736 -27.6722222222222
## 67      Windspear  Lithic_Spear   0.867  -0.102565463182728 -2.41333333333333
## 68      Windspear Staff_of_Homa   0.439  -0.799597533864276 -20.5933333333333
## 69      Windspear     The_Catch   0.018    1.36662105292301             38.34
## 70      Windspear     Engulfing       0    1.95713188309414  71.2733333333333
## 71      Windspear          Jade    0.34   0.346299560885418  7.57095238095238
## 72      Windspear        Vortex     0.6  -0.441461566353428 -11.1433333333333
## 73      Windspear    Deathmatch   0.082   -1.10106998960298            -28.96
## 74      Windspear    Blackcliff   0.382   -1.17063446466263 -30.8933333333333
## 75      Windspear  Dragons_Bane   0.429  -0.799597533864276 -20.5933333333333
## 76      Windspear   Royal_Spear   0.374   0.728549539222166  20.2566666666667
## 77      Windspear   Starglitter   0.457    0.88155621231156  22.8066666666667
## 78      Windspear Scarlet_Sands   0.517  -0.576192019151447 -14.6933333333333
## 79      Windspear  White_Tassel    0.81   0.312367053274414  7.90666666666667
## 80      Windspear Crescent_Pike   0.496  -0.652655214887428 -16.6933333333333
## 81   Lithic_Spear Staff_of_Homa   0.324   -1.16340950926518            -18.18
## 82   Lithic_Spear     The_Catch   0.027    1.66122260143855  40.7533333333333
## 83   Lithic_Spear     Engulfing    0.01    1.82431634482193  73.6866666666667
## 84   Lithic_Spear          Jade   0.249   0.615994263945707   9.9842857142857
## 85   Lithic_Spear        Vortex   0.546  -0.556267538592371             -8.73
## 86   Lithic_Spear    Deathmatch    0.03   -1.44015660703518 -26.5466666666667
## 87   Lithic_Spear    Blackcliff   0.163   -1.58152273208059            -28.48
## 88   Lithic_Spear  Dragons_Bane   0.307   -1.16340950926518            -18.18
## 89   Lithic_Spear   Royal_Spear   0.305   0.904063366225321             22.67
## 90   Lithic_Spear   Starglitter   0.343    1.46809231222432             25.22
## 91   Lithic_Spear Scarlet_Sands   0.843  -0.838983640932466            -12.28
## 92   Lithic_Spear  White_Tassel    0.83    0.71754614430365             10.32
## 93   Lithic_Spear Crescent_Pike   0.814  -0.956070905914138            -14.28
## 94  Staff_of_Homa     The_Catch   0.254     1.9436576787682  58.9333333333333
## 95  Staff_of_Homa     Engulfing    0.27    1.95510857928356  91.8666666666667
## 96  Staff_of_Homa          Jade   0.214     1.6345726595451  28.1642857142857
## 97  Staff_of_Homa        Vortex       1   0.608135305775328              9.45
## 98  Staff_of_Homa    Deathmatch   0.492   -1.13122470024578 -8.36666666666666
## 99  Staff_of_Homa    Blackcliff       1   -1.41421356237309             -10.3
## 100 Staff_of_Homa  Dragons_Bane       1                 NaN                 0
## 101 Staff_of_Homa   Royal_Spear   0.652    1.02036924875696             40.85
## 102 Staff_of_Homa   Starglitter       1     1.4142135623731              43.4
## 103 Staff_of_Homa Scarlet_Sands       1    1.41421356237309  5.90000000000001
## 104 Staff_of_Homa  White_Tassel       1     1.4142135623731              28.5
## 105 Staff_of_Homa Crescent_Pike       1     1.4142135623731  3.90000000000001
## 106     The_Catch     Engulfing   0.107    1.61697666450616  32.9333333333333
## 107     The_Catch          Jade   0.006   -1.60119651080011 -30.7690476190476
## 108     The_Catch        Vortex    0.09   -1.66928495470748 -49.4833333333333
## 109     The_Catch    Deathmatch   0.095   -1.79116756905674             -67.3
## 110     The_Catch    Blackcliff   0.249    -1.9586982375945 -69.2333333333333
## 111     The_Catch  Dragons_Bane   0.229    -1.9436576787682 -58.9333333333333
## 112     The_Catch   Royal_Spear   0.619  -0.704071502839041 -18.0833333333333
## 113     The_Catch   Starglitter   0.489   -1.47177546901411 -15.5333333333333
## 114     The_Catch Scarlet_Sands   0.248   -1.93110078815236 -53.0333333333333
## 115     The_Catch  White_Tassel   0.241   -1.81030302955788 -30.4333333333333
## 116     The_Catch Crescent_Pike    0.26   -1.93578342979566 -55.0333333333333
## 117     Engulfing          Jade   0.003   -2.17415461245749  -63.702380952381
## 118     Engulfing        Vortex   0.112   -1.75033797338594 -82.4166666666667
## 119     Engulfing    Deathmatch   0.085   -1.80165692197293 -100.233333333333
## 120     Engulfing    Blackcliff   0.249   -1.96346993788463 -102.166666666667
## 121     Engulfing  Dragons_Bane   0.242   -1.95510857928356 -91.8666666666667
## 122     Engulfing   Royal_Spear   0.111   -1.37453172521577 -51.0166666666667
## 123     Engulfing   Starglitter   0.278   -1.85146930810048 -48.4666666666667
## 124     Engulfing Scarlet_Sands   0.242   -1.94897716123147 -85.9666666666667
## 125     Engulfing  White_Tassel   0.215    -1.9089845611363 -63.3666666666667
## 126     Engulfing Crescent_Pike   0.239   -1.95118761226109 -87.9666666666667
## 127          Jade        Vortex   0.173   -1.08623611159035 -18.7142857142857
## 128          Jade    Deathmatch   0.003   -1.76880391118146 -36.5309523809524
## 129          Jade    Blackcliff   0.072   -2.07797563969726 -38.4642857142857
## 130          Jade  Dragons_Bane   0.221    -1.6345726595451 -28.1642857142857
## 131          Jade   Royal_Spear   0.441   0.645645713931023  12.6857142857143
## 132          Jade   Starglitter   0.387   0.945827270335678  15.2357142857143
## 133          Jade Scarlet_Sands     0.2   -1.33760987221548 -22.2642857142857
## 134          Jade  White_Tassel       1  0.0214914099283983 0.335714285714289
## 135          Jade Crescent_Pike   0.201   -1.44171498481475 -24.2642857142857
## 136        Vortex    Deathmatch   0.309   -1.17740217665614 -17.8166666666667
## 137        Vortex    Blackcliff   0.665   -1.06838992256549            -19.75
## 138        Vortex  Dragons_Bane       1  -0.608135305775328             -9.45
## 139        Vortex   Royal_Spear   0.679   0.918981530950636              31.4
## 140        Vortex   Starglitter    0.67     1.3907589749183             33.95
## 141        Vortex Scarlet_Sands       1  -0.241600973187231             -3.55
## 142        Vortex  White_Tassel   0.686    1.04445121854127             19.05
## 143        Vortex Crescent_Pike       1  -0.372516781546988             -5.55
## 144    Deathmatch    Blackcliff   0.735  -0.313065617249645 -1.93333333333334
## 145    Deathmatch  Dragons_Bane   0.512    1.13122470024578  8.36666666666666
## 146    Deathmatch   Royal_Spear   0.122     1.3768060563861  49.2166666666667
## 147    Deathmatch   Starglitter   0.254    1.94668052464907  51.7666666666667
## 148    Deathmatch Scarlet_Sands   0.475    1.52008343494161  14.2666666666667
## 149    Deathmatch  White_Tassel   0.237    1.89875511627163  36.8666666666667
## 150    Deathmatch Crescent_Pike    0.52    1.41813544523079  12.2666666666667
## 151    Blackcliff  Dragons_Bane       1    1.41421356237309              10.3
## 152    Blackcliff   Royal_Spear   0.652    1.16775039430952             51.15
## 153    Blackcliff   Starglitter       1    1.41421356237309              53.7
## 154    Blackcliff Scarlet_Sands       1    1.41421356237309              16.2
## 155    Blackcliff  White_Tassel       1    1.41421356237309              38.8
## 156    Blackcliff Crescent_Pike       1     1.4142135623731              14.2
## 157  Dragons_Bane   Royal_Spear   0.653    1.02036924875696             40.85
## 158  Dragons_Bane   Starglitter       1     1.4142135623731              43.4
## 159  Dragons_Bane Scarlet_Sands       1    1.41421356237309  5.90000000000001
## 160  Dragons_Bane  White_Tassel       1     1.4142135623731              28.5
## 161  Dragons_Bane Crescent_Pike       1     1.4142135623731  3.90000000000001
## 162   Royal_Spear   Starglitter       1  0.0787438449717908  2.55000000000001
## 163   Royal_Spear Scarlet_Sands   0.661  -0.916666327925715            -34.95
## 164   Royal_Spear  White_Tassel       1  -0.372813590062281            -12.35
## 165   Royal_Spear Crescent_Pike   0.676  -0.953529071961912            -36.95
## 166   Starglitter Scarlet_Sands       1   -1.41421356237309             -37.5
## 167   Starglitter  White_Tassel       1    -1.4142135623731             -14.9
## 168   Starglitter Crescent_Pike       1   -1.41421356237309             -39.5
## 169 Scarlet_Sands  White_Tassel       1    1.41421356237309              22.6
## 170 Scarlet_Sands Crescent_Pike       1   -1.41421356237309                -2
## 171  White_Tassel Crescent_Pike       1   -1.41421356237309             -24.6

Again, KQM uses the Favonius Lance as a reference frame for all other polearm choices, and we will use the same process in order to analyze their recommendations, this time looking at atk instead of ER. The following are the results of the post-hoc test:

  1. Favonius Lance vs. Wavebreaker’s Fin:
    There is strong evidence (p=0.001) to suggest that there is a difference in the mean atk of Shenhes equipping these two polearms. The sample mean difference in atk is an increase of 423.574 atk. This difference has a large associated effect size (1.009), which indicates an important difference in atk. This atk increase can contribute a large amount of icy quill damage.

  2. Favonius Lance vs. Skyward Spine:
    There is strong evidence (p=0.000) to suggest that there is a difference in the mean atk of Shenhes equipping these two polearms. The sample mean difference in atk is an increase of 566.685 atk. This difference has a large associated effect size (1.303), which indicates an important difference in atk. This atk increase can also contribute a large amount of icy quill damage to the team.

  3. Favonius Lance vs. Calamity Queller:
    There is strong evidence (p=0.000) to suggest that there is a difference in the mean atk of Shenhes equipping these two polearms. The sample mean difference in atk is an increase of 760.713 atk. This difference has a large associated effect size (1.163), which indicates an important difference in atk. This atk increase can also contribute a large amount of icy quill damage to the team.

  4. Favonius Lance vs. Missive Windspear:
    There is strong evidence (p=0.005) to suggest that there is a difference in the mean atk of Shenhes equipping these two polearms. The sample mean difference in atk is an increase of 362.741 atk. This difference has a large associated effect size (0.898), which indicates an important difference in atk. This atk increase can contribute a decent amount of extra icy quill damage.

  5. Favonius Lance vs. Lithic Spear:
    There is no evidence (p=0.330) to suggest that there is a difference in the mean atk of Shenhes equipping these two polearms.

  6. Favonius Lance vs. Staff of Homa: There is no evidence (p=0.326) to suggest that there is a difference in the mean atk of Shenhes equipping these two polearms. It is important to note here, that just because the data we have provides no evidence to suggest that there is any difference, doesn’t mean the data provides evidence to suggest that there is no difference.

  7. Favonius Lance vs. The Catch:
    There is very weak evidence (p=0.094) to suggest that there is a difference in the mean atk of Shenhes equipping these two polearms. Because of the large p-values, the point estimates are not appropriate measures upon which to make numeric conclusions, but they suggest that there is a general decrease in atk, which makes sense because The Catch has a lower base atk than Favonius Lance (510 vs. 565).

  8. Favonius Lance vs. Engulfing Lightning:
    There is no evidence (p=0.268) to suggest that there is a difference in the mean atk of Shenhes equipping these two polearms. The atk might have a true difference when in battle due to Engulfing Lightning’s ER and subsequent atk bonus after casting an elemental burst.

  9. Favonius Lance vs. Primordial Jade Winged Spear:
    There is strong evidence (p=0.002) to suggest that there is a difference in the mean atk of Shenhes equipping these two polearms. The sample mean difference in atk is an increase of 460.431 atk. This difference has a large associated effect size (1.056), which indicates an important difference in atk. This atk increase can contribute a large amount of extra icy quill damage.

  10. Favonius Lance vs. Vortex Vanquisher:
    There is moderate evidence (p=0.017) to suggest that there is a difference in the mean atk of Shenhes equipping these two polearms. The sample mean difference in atk is an increase of 684.074 atk. This difference has a large associated effect size (1.652), which indicates an important difference in atk. This atk increase can contribute a large amount of extra icy quill damage. Practically, this difference may be even larger, because while in battle, the Vortex Vanquisher increases atk when shielded, but as KQM states, this atk buff cannot stack while off field. This could still make Vortex Vanquisher a strong choice for an on-field DPS Shenhe.

  11. Favonius Lance vs. Deathmatch:
    There is no evidence (p=0.822) to suggest that there is a difference in the mean atk of Shenhes equipping these two polearms.

  12. Favonius Lance vs. Blackcliff Pole:
    There is no evidence (p=0.464) to suggest that there is a difference in the mean atk of Shenhes equipping these two polearms.

  13. Favonius Lance vs. Dragon’s Bane:
    There is weak evidence (p=0.076) to suggest that there is a difference in the mean atk of Shenhes equipping these two polearms. The sample mean difference in atk is a decrease of 808.926 atk. This difference has a large associated effect size (-1.987), which indicates an important difference in atk. This atk loss would considerably decrease damage from icy quills.

  14. Favonius Lance vs. Royal Spear:
    There is no evidence (p=0.134) to suggest that there is a difference in the mean atk of Shenhes equipping these two polearms.

  15. Favonius Lance vs. Prototype Starglitter:
    There is no evidence (p=0.165) to suggest that there is a difference in the mean atk of Shenhes equipping these two polearms.

  16. Favonius Lance vs. Staff of Scarlet Sands:
    There is no evidence (p=0.430) to suggest that there is a difference in the mean atk of Shenhes equipping these two polearms.

  17. Favonius Lance vs. White Tassel:
    There is no evidence (p=0.519) to suggest that there is a difference in the mean atk of Shenhes equipping these two polearms. Again, just because the data provides no evidence to indicate a difference in population means, does not mean that one does not actually exist.

  18. Favonius Lance vs. Crescent Pike:
    There is no evidence (p=0.147) to suggest that there is a difference in the mean atk of Shenhes equipping these two polearms.

set.seed(27)

adi_saidi.RPT(shenhe$polearm_name, shenhe$atk)
##       treatment_1   treatment_2 p_value         effect_size         mean_diff
## 1        Favonius   Wavebreaker   0.001    1.00865651372902  423.574074074074
## 2        Favonius       Skyward       0    1.30308029510274  566.685185185185
## 3        Favonius      Calamity       0    1.16271032765533  760.712962962963
## 4        Favonius     Windspear   0.005   0.897519212855634   362.74074074074
## 5        Favonius  Lithic_Spear    0.33    0.45311286451962  179.674074074074
## 6        Favonius Staff_of_Homa   0.326    1.04473927629608  402.074074074074
## 7        Favonius     The_Catch   0.094   -1.00972623935394 -387.592592592593
## 8        Favonius     Engulfing   0.268   0.691127956449755   260.74074074074
## 9        Favonius          Jade   0.002    1.05619054419661  460.431216931217
## 10       Favonius        Vortex   0.017    1.65157651123932  684.074074074074
## 11       Favonius    Deathmatch   0.822   0.141076634775625  51.4074074074074
## 12       Favonius    Blackcliff   0.464  -0.798955515520137 -304.925925925926
## 13       Favonius  Dragons_Bane   0.076    -1.9871647006814 -808.925925925926
## 14       Favonius   Royal_Spear   0.134    1.13553390834645  443.574074074074
## 15       Favonius   Starglitter   0.165   -1.70819872444915 -680.925925925926
## 16       Favonius Scarlet_Sands    0.43   0.812129337660546  310.074074074074
## 17       Favonius  White_Tassel   0.519  -0.739917146188663 -281.925925925926
## 18       Favonius Crescent_Pike   0.147   -1.66078095177597 -659.925925925926
## 19    Wavebreaker       Skyward   0.178   0.482439659764089  143.111111111111
## 20    Wavebreaker      Calamity   0.058    0.58150956127537  337.138888888889
## 21    Wavebreaker     Windspear   0.632  -0.180837844481788 -60.8333333333335
## 22    Wavebreaker  Lithic_Spear   0.251  -0.633180013697155            -243.9
## 23    Wavebreaker Staff_of_Homa   0.922  -0.064468647310798             -21.5
## 24    Wavebreaker     The_Catch   0.004   -1.81197204585276 -811.166666666667
## 25    Wavebreaker     Engulfing   0.431  -0.496203734354942 -162.833333333333
## 26    Wavebreaker          Jade   0.772    0.10432430830593  36.8571428571427
## 27    Wavebreaker        Vortex   0.272   0.759539794671288             260.5
## 28    Wavebreaker    Deathmatch   0.097   -1.08021847824483 -372.166666666667
## 29    Wavebreaker    Blackcliff   0.147   -1.90286589917397            -728.5
## 30    Wavebreaker  Dragons_Bane   0.083   -2.67392705888953           -1232.5
## 31    Wavebreaker   Royal_Spear   0.908   0.060851488836728                20
## 32    Wavebreaker   Starglitter   0.053   -2.51728184434121           -1104.5
## 33    Wavebreaker Scarlet_Sands   0.654  -0.339074663135743            -113.5
## 34    Wavebreaker  White_Tassel   0.125   -1.85676920186933            -705.5
## 35    Wavebreaker Crescent_Pike   0.078   -2.48930397226261           -1083.5
## 36        Skyward      Calamity   0.222   0.361957656904792  194.027777777777
## 37        Skyward     Windspear    0.05  -0.673371831823394 -203.944444444445
## 38        Skyward  Lithic_Spear   0.021   -1.15012664989821 -387.011111111111
## 39        Skyward Staff_of_Homa   0.695  -0.686273930968251 -164.611111111111
## 40        Skyward     The_Catch   0.003   -2.32271695247396 -954.277777777778
## 41        Skyward     Engulfing   0.047   -1.17693148598946 -305.944444444445
## 42        Skyward          Jade   0.374  -0.347233306306028 -106.253968253969
## 43        Skyward        Vortex   0.544   0.482683289618242  117.388888888889
## 44        Skyward    Deathmatch   0.001   -1.77101101544203 -515.277777777778
## 45        Skyward    Blackcliff   0.042   -2.81176278839075 -871.611111111111
## 46        Skyward  Dragons_Bane   0.065   -3.48616196271268 -1375.61111111111
## 47        Skyward   Royal_Spear   0.554  -0.511601578611312 -123.111111111111
## 48        Skyward   Starglitter   0.046   -3.35808517847231 -1247.61111111111
## 49        Skyward Scarlet_Sands   0.377   -1.05135441850938 -256.611111111111
## 50        Skyward  White_Tassel   0.056   -2.76771953577214 -848.611111111111
## 51        Skyward Crescent_Pike    0.06   -3.33476080267313 -1226.61111111111
## 52       Calamity     Windspear    0.02  -0.681915258505033 -397.972222222222
## 53       Calamity  Lithic_Spear   0.043  -0.914566572826051 -581.038888888889
## 54       Calamity Staff_of_Homa   0.677  -0.577311333116889 -358.638888888889
## 55       Calamity     The_Catch   0.001   -1.69484526950833 -1148.30555555556
## 56       Calamity     Engulfing   0.182  -0.807685666234814 -499.972222222222
## 57       Calamity          Jade   0.097  -0.517772786065565 -300.281746031746
## 58       Calamity        Vortex   0.902  -0.125182096361221 -76.6388888888887
## 59       Calamity    Deathmatch   0.047   -1.12293363982969 -709.305555555555
## 60       Calamity    Blackcliff   0.141   -1.65792618320408 -1065.63888888889
## 61       Calamity  Dragons_Bane   0.027   -2.34240645303696 -1569.63888888889
## 62       Calamity   Royal_Spear   0.493  -0.515173625867883 -317.138888888889
## 63       Calamity   Starglitter   0.033   -2.17678794114611 -1441.63888888889
## 64       Calamity Scarlet_Sands   0.549  -0.723522529507911 -450.638888888889
## 65       Calamity  White_Tassel   0.176   -1.62472171063167 -1042.63888888889
## 66       Calamity Crescent_Pike   0.025   -2.14906275657019 -1420.63888888889
## 67      Windspear  Lithic_Spear   0.375  -0.494327818356513 -183.066666666667
## 68      Windspear Staff_of_Homa   0.824   0.120941521697466  39.3333333333335
## 69      Windspear     The_Catch   0.001   -1.78113773104065 -750.333333333333
## 70      Windspear     Engulfing   0.615  -0.321419893073766              -102
## 71      Windspear          Jade    0.46   0.277977774413176  97.6904761904761
## 72      Windspear        Vortex   0.165   0.943368999818142  321.333333333333
## 73      Windspear    Deathmatch   0.122  -0.949474351916982 -311.333333333333
## 74      Windspear    Blackcliff   0.125    -1.8270892441257 -667.666666666667
## 75      Windspear  Dragons_Bane   0.068   -2.67761116975157 -1171.66666666667
## 76      Windspear   Royal_Spear   0.718   0.250980097915848  80.8333333333335
## 77      Windspear   Starglitter   0.116   -2.50377853652322 -1043.66666666667
## 78      Windspear Scarlet_Sands   0.808  -0.161879990617597 -52.6666666666665
## 79      Windspear  White_Tassel   0.125   -1.77674380884935 -644.666666666667
## 80      Windspear Crescent_Pike   0.118   -2.47277343017968 -1022.66666666667
## 81   Lithic_Spear Staff_of_Homa   0.679   0.513961966884409             222.4
## 82   Lithic_Spear     The_Catch   0.076   -1.21629113821899 -567.266666666666
## 83   Lithic_Spear     Engulfing   0.844   0.213609928898917  81.0666666666666
## 84   Lithic_Spear          Jade   0.196   0.688940444583134  280.757142857143
## 85   Lithic_Spear        Vortex   0.139    1.06435476367779             504.4
## 86   Lithic_Spear    Deathmatch   0.696  -0.352619034026566 -128.266666666666
## 87   Lithic_Spear    Blackcliff   0.473   -1.03756661103197            -484.6
## 88   Lithic_Spear  Dragons_Bane   0.169   -1.69074580044328            -988.6
## 89   Lithic_Spear   Royal_Spear   0.669   0.628599463516098             263.9
## 90   Lithic_Spear   Starglitter   0.343   -1.56488514871901            -860.6
## 91   Lithic_Spear Scarlet_Sands       1   0.305801581216363             130.4
## 92   Lithic_Spear  White_Tassel   0.677  -0.996642330981546            -461.6
## 93   Lithic_Spear Crescent_Pike   0.317   -1.54194425907023            -839.6
## 94  Staff_of_Homa     The_Catch   0.254   -1.95002062977218 -789.666666666667
## 95  Staff_of_Homa     Engulfing   0.743  -0.719237306152522 -141.333333333333
## 96  Staff_of_Homa          Jade   0.872   0.162431173179704  58.3571428571427
## 97  Staff_of_Homa        Vortex   0.658    1.05811107026297               282
## 98  Staff_of_Homa    Deathmatch   0.259   -1.99599293316619 -350.666666666667
## 99  Staff_of_Homa    Blackcliff       1    -1.4142135623731              -707
## 100 Staff_of_Homa  Dragons_Bane       1    -1.4142135623731             -1211
## 101 Staff_of_Homa   Royal_Spear       1    0.23170140143526              41.5
## 102 Staff_of_Homa   Starglitter       1   -1.41421356237309             -1083
## 103 Staff_of_Homa Scarlet_Sands       1    -1.4142135623731               -92
## 104 Staff_of_Homa  White_Tassel       1    -1.4142135623731              -684
## 105 Staff_of_Homa Crescent_Pike       1   -1.41421356237309             -1062
## 106     The_Catch     Engulfing   0.107    1.66772447707057  648.333333333333
## 107     The_Catch          Jade   0.001    1.78657781385455  848.023809523809
## 108     The_Catch        Vortex    0.09    1.75501215071629  1071.66666666667
## 109     The_Catch    Deathmatch   0.095    1.75254644648806               439
## 110     The_Catch    Blackcliff   0.758   0.834974239723362  82.6666666666665
## 111     The_Catch  Dragons_Bane   0.229   -1.83930492505842 -421.333333333333
## 112     The_Catch   Royal_Spear   0.096    1.73659903195823  831.166666666667
## 113     The_Catch   Starglitter   0.254   -1.70483098370937 -293.333333333333
## 114     The_Catch Scarlet_Sands   0.248    1.93663161277329  697.666666666667
## 115     The_Catch  White_Tassel    0.74    1.01280410577742  105.666666666667
## 116     The_Catch Crescent_Pike    0.26   -1.66868795320716 -272.333333333333
## 117     Engulfing          Jade    0.38   0.564347417276359  199.690476190476
## 118     Engulfing        Vortex   0.112    1.33048058921521  423.333333333333
## 119     Engulfing    Deathmatch   0.391   -1.14555137775215 -209.333333333333
## 120     Engulfing    Blackcliff   0.249   -1.67819688433243 -565.666666666667
## 121     Engulfing  Dragons_Bane   0.242   -1.89190626920056 -1069.66666666667
## 122     Engulfing   Royal_Spear   0.609   0.809625802064257  182.833333333333
## 123     Engulfing   Starglitter   0.278   -1.86366639913658 -941.666666666667
## 124     Engulfing Scarlet_Sands       1   0.266652383259513  49.3333333333335
## 125     Engulfing  White_Tassel   0.215   -1.65710754027619 -542.666666666667
## 126     Engulfing Crescent_Pike   0.239     -1.858030294952 -920.666666666667
## 127          Jade        Vortex    0.37   0.615483436244735  223.642857142857
## 128          Jade    Deathmatch   0.089   -1.09866864982145 -409.023809523809
## 129          Jade    Blackcliff   0.144   -1.86782773934873 -765.357142857143
## 130          Jade  Dragons_Bane   0.072   -2.61144839844113 -1269.35714285714
## 131          Jade   Royal_Spear    0.94 -0.0477759839858694 -16.8571428571427
## 132          Jade   Starglitter    0.07   -2.45753672643394 -1141.35714285714
## 133          Jade Scarlet_Sands   0.646  -0.416443884940407 -150.357142857143
## 134          Jade  White_Tassel   0.141    -1.8242999162174 -742.357142857143
## 135          Jade Crescent_Pike   0.072   -2.43022379549956 -1120.35714285714
## 136        Vortex    Deathmatch   0.105   -1.67636731716519 -632.666666666667
## 137        Vortex    Blackcliff   0.357   -1.62467404112471              -989
## 138        Vortex  Dragons_Bane   0.344   -1.68238052490271             -1493
## 139        Vortex   Royal_Spear   0.679  -0.909232435461974            -240.5
## 140        Vortex   Starglitter   0.333   -1.67312080531145             -1365
## 141        Vortex Scarlet_Sands   0.647   -1.23880229427833              -374
## 142        Vortex  White_Tassel   0.331    -1.6199915097693              -966
## 143        Vortex Crescent_Pike   0.339   -1.67136127898711             -1344
## 144    Deathmatch    Blackcliff   0.239   -1.99611899848673 -356.333333333333
## 145    Deathmatch  Dragons_Bane    0.25   -1.99933262282615 -860.333333333333
## 146    Deathmatch   Royal_Spear   0.122    1.57517995529201  392.166666666667
## 147    Deathmatch   Starglitter   0.254   -1.99907911662366 -732.333333333333
## 148    Deathmatch Scarlet_Sands   0.232    1.99265412571675  258.666666666667
## 149    Deathmatch  White_Tassel   0.237   -1.99556678373974 -333.333333333333
## 150    Deathmatch Crescent_Pike   0.259   -1.99902398172755 -711.333333333333
## 151    Blackcliff  Dragons_Bane       1    -1.4142135623731              -504
## 152    Blackcliff   Royal_Spear   0.328    1.60216674798478             748.5
## 153    Blackcliff   Starglitter       1    -1.4142135623731              -376
## 154    Blackcliff Scarlet_Sands       1     1.4142135623731               615
## 155    Blackcliff  White_Tassel       1     1.4142135623731                23
## 156    Blackcliff Crescent_Pike       1   -1.41421356237309              -355
## 157  Dragons_Bane   Royal_Spear    0.32    1.68211751129935            1252.5
## 158  Dragons_Bane   Starglitter       1    1.41421356237309               128
## 159  Dragons_Bane Scarlet_Sands       1    1.41421356237309              1119
## 160  Dragons_Bane  White_Tassel       1     1.4142135623731               527
## 161  Dragons_Bane Crescent_Pike       1     1.4142135623731               149
## 162   Royal_Spear   Starglitter   0.323   -1.67073404670671           -1124.5
## 163   Royal_Spear Scarlet_Sands       1  -0.689878722298898            -133.5
## 164   Royal_Spear  White_Tassel   0.336   -1.59476999546345            -725.5
## 165   Royal_Spear Crescent_Pike   0.344     -1.668506174781           -1103.5
## 166   Starglitter Scarlet_Sands       1     1.4142135623731               991
## 167   Starglitter  White_Tassel       1    1.41421356237309               399
## 168   Starglitter Crescent_Pike       1     1.4142135623731                21
## 169 Scarlet_Sands  White_Tassel       1   -1.41421356237309              -592
## 170 Scarlet_Sands Crescent_Pike       1    -1.4142135623731              -970
## 171  White_Tassel Crescent_Pike       1    -1.4142135623731              -378

KQM recommends a full Noblesse Oblige set for Shenhe, and therefore we will use it as a reference frame for analyzing their recommendations. It should be noted that Noblesse Oblige provides a 20% atk bonus after casting an elemental burst, but this will not be reflected in the raw data. The following are the results of the post-hoc test:

  1. Full Noblesse vs. atk-atk:
    There is strong evidence (p=0.000) to suggest that there is a difference in the mean atk of Shenhes with these set bonuses. The sample mean difference in atk is an increase of 659.133 atk. This difference has a large associated effect size (1.368), which indicates an important difference in atk. This difference may not be as large in practice, as the atk provided by the 4-piece Noblesse Oblige set when casting a burst is equal to 20% of the user’s base atk, which when compared to the unconditional 36% atk provided by an atk-atk set is still important.

  2. Full Noblesse vs. Full Gladiator:
    There is no evidence (p=0.773) to suggest that there is a difference in the mean atk of Shenhes with these set bonuses.

  3. Full Noblesse vs. phys-atk:
    There is no evidence (p=0.179) to suggest that there is a difference in the mean atk of Shenhes with these set bonuses.

  4. Full Noblesse vs. atk:
    There is strong evidence (p=0.003) to suggest that there is a difference in the mean atk of Shenhes with these set bonuses. The sample mean difference in atk is an increase of 796.056 atk. This difference has a large associated effect size (1.665), which indicates an important difference in atk. This is an important place to emphasize that these conclusions only describe a correlative relationship, because a single 18% atk bonus is certainly not causative of a larger increase in atk than a 36% atk bonus. It may be that players equipping only a single atk bonus set had much higher substat investment on their other artifacts, leading to a higher overall atk. Observational data cannot answer the question of causation, and unfortunately there are few ways to use an experimental design in game which also includes a broad range of players.

  5. Full Noblesse vs. atk-noblesse:
    There is no evidence (p=0.198) to suggest that there is a difference in the mean atk of Shenhes with these set bonuses.

  6. Full Noblesse vs. cryo-atk:
    There is no evidence (p=0.834) to suggest that there is a difference in the mean atk of Shenhes with these set bonuses.

  7. Full Noblesse vs. Full Blizzard Strayer:
    There is no evidence (p=0.720) to suggest that there is a difference in the mean atk of Shenhes with these set bonuses.

  8. Full Noblesse vs. cryo:
    There is no evidence (p=0.710) to suggest that there is a difference in the mean atk of Shenhes with these set bonuses.

  9. Full Noblesse vs. atk-EM:
    There is no evidence (p=0.213) to suggest that there is a difference in the mean atk of Shenhes with these set bonuses.

  10. Full Noblesse vs. Full Emblem:
    There is no evidence (p=0.838) to suggest that there is a difference in the mean atk of Shenhes with these set bonuses.

  11. Full Noblesse vs. phys-phys: There is no evidence (p=0.195) to suggest that there is a difference in the mean atk of Shenhes with these set bonuses.

set.seed(27)

adi_saidi.RPT(shenhe$set_bonus, shenhe$atk)
##       treatment_1    treatment_2 p_value         effect_size         mean_diff
## 1         atk-atk full-gladiator    0.01   -1.63151630566282 -719.744548286605
## 2         atk-atk  full-noblesse       0   -1.36774477377984 -659.133437175493
## 3         atk-atk       phys-atk   0.022   -3.00455504564809 -1332.41121495327
## 4         atk-atk            atk   0.582   0.324036049654145  136.922118380062
## 5         atk-atk   atk-noblesse   0.003    -2.3898558346056 -1067.41121495327
## 6         atk-atk       cryo-atk   0.002     -1.559559570056 -694.077881619938
## 7         atk-atk  full-blizzard   0.002   -1.64987052854645 -748.161214953271
## 8         atk-atk           cryo   0.075   -1.96699450343337 -850.411214953271
## 9         atk-atk             na   0.015    -3.0971507817742 -1377.41121495327
## 10        atk-atk         atk-EM   0.647   -0.36820636561305 -156.411214953271
## 11        atk-atk    full-emblem   0.216   -1.28195511748045 -548.411214953271
## 12        atk-atk      phys-phys   0.014   -2.78756976386484 -1228.41121495327
## 13 full-gladiator  full-noblesse   0.773   0.150432318797699  60.6111111111113
## 14 full-gladiator       phys-atk   0.527   -1.26926649377371 -612.666666666667
## 15 full-gladiator            atk     0.1    1.49498469000376  856.666666666667
## 16 full-gladiator   atk-noblesse     0.6  -0.907785163808444 -347.666666666667
## 17 full-gladiator       cryo-atk   0.893  0.0951955438199434   25.666666666667
## 18 full-gladiator  full-blizzard   0.947 -0.0550921046384228 -28.4166666666665
## 19 full-gladiator           cryo       1  -0.345030855083062 -130.666666666667
## 20 full-gladiator             na    0.54   -1.32253630415191 -657.666666666667
## 21 full-gladiator         atk-EM   0.223    1.20517651868376  563.333333333333
## 22 full-gladiator    full-emblem       1   0.447646717479208  171.333333333333
## 23 full-gladiator      phys-phys   0.518   -1.12665344514974 -508.666666666667
## 24  full-noblesse       phys-atk   0.179   -1.58465475035136 -673.277777777778
## 25  full-noblesse            atk   0.003    1.66479810753931  796.055555555556
## 26  full-noblesse   atk-noblesse   0.198   -1.00365273652762 -408.277777777778
## 27  full-noblesse       cryo-atk   0.834 -0.0969484486810723 -34.9444444444443
## 28  full-noblesse  full-blizzard    0.72   -0.20339719208541 -89.0277777777778
## 29  full-noblesse           cryo    0.71  -0.480322992443321 -191.277777777778
## 30  full-noblesse             na   0.099   -1.67534405105663 -718.277777777778
## 31  full-noblesse         atk-EM   0.213    1.21942042951149  502.722222222222
## 32  full-noblesse    full-emblem   0.838   0.279166952949236  110.722222222222
## 33  full-noblesse      phys-phys   0.195   -1.36585367195126 -569.277777777778
## 34       phys-atk            atk   0.226    1.92781744001265  1469.33333333333
## 35       phys-atk   atk-noblesse   0.652     1.4063089149045               265
## 36       phys-atk       cryo-atk   0.137    2.18508906922721  638.333333333333
## 37       phys-atk  full-blizzard   0.408   0.970202044313578            584.25
## 38       phys-atk           cryo       1    1.41421356237309               482
## 39       phys-atk             na       1   -1.41421356237309               -45
## 40       phys-atk         atk-EM       1     1.4142135623731              1176
## 41       phys-atk    full-emblem       1    1.41421356237309               784
## 42       phys-atk      phys-phys       1     1.4142135623731               104
## 43            atk   atk-noblesse   0.093   -1.75286947364881 -1204.33333333333
## 44            atk       cryo-atk   0.017   -1.82021190845927              -831
## 45            atk  full-blizzard     0.1   -1.33332337249988 -885.083333333333
## 46            atk           cryo   0.269   -1.84982885127084 -987.333333333333
## 47            atk             na   0.245   -1.93183011190014 -1514.33333333333
## 48            atk         atk-EM   0.532   -1.17159130058758 -293.333333333333
## 49            atk    full-emblem   0.277   -1.72090403776465 -685.333333333333
## 50            atk      phys-phys   0.233   -1.91710261854856 -1365.33333333333
## 51   atk-noblesse       cryo-atk   0.079    1.56953022175938  373.333333333333
## 52   atk-noblesse  full-blizzard   0.665   0.617245826917049            319.25
## 53   atk-noblesse           cryo   0.672    1.30156534974766               217
## 54   atk-noblesse             na   0.641   -1.47563289714275              -310
## 55   atk-noblesse         atk-EM   0.328    1.69537061008148               911
## 56   atk-noblesse    full-emblem   0.334    1.62595293534954               519
## 57   atk-noblesse      phys-phys   0.675   -1.11793875028486              -161
## 58       cryo-atk  full-blizzard    0.85    -0.1397835546614 -54.0833333333335
## 59       cryo-atk           cryo   0.733  -0.893372229297533 -156.333333333333
## 60       cryo-atk             na    0.16    -2.2307196759493 -683.333333333333
## 61       cryo-atk         atk-EM   0.149     2.0553870712599  537.666666666667
## 62       cryo-atk    full-emblem   0.744    0.83874334245226  145.666666666667
## 63       cryo-atk      phys-phys   0.149   -2.05030635394896 -534.333333333333
## 64  full-blizzard           cryo   0.807   -0.18779362727538           -102.25
## 65  full-blizzard             na   0.401   -1.02954052896973           -629.25
## 66  full-blizzard         atk-EM   0.804    0.98027518707541            591.75
## 67  full-blizzard    full-emblem   0.801   0.363272978112371            199.75
## 68  full-blizzard      phys-phys   0.589  -0.823021610394181           -480.25
## 69           cryo             na       1    -1.4142135623731              -527
## 70           cryo         atk-EM       1     1.4142135623731               694
## 71           cryo    full-emblem       1     1.4142135623731               302
## 72           cryo      phys-phys       1    -1.4142135623731              -378
## 73             na         atk-EM       1    1.41421356237309              1221
## 74             na    full-emblem       1     1.4142135623731               829
## 75             na      phys-phys       1     1.4142135623731               149
## 76         atk-EM    full-emblem       1   -1.41421356237309              -392
## 77         atk-EM      phys-phys       1    -1.4142135623731             -1072
## 78    full-emblem      phys-phys       1   -1.41421356237309              -680

General Conclusion

The three most common polearm choices for the sample of fully built Shenhes on display were, in order, Favonius Lance, Calamity Queller, and Skyward Spine, which also arguably fits the ranking of best polearms for Shenhe overall.

The most common set bonus by far was an atk-atk setup, which is generally not recommended by KQM, but proved to contain the highest atk out of all the set bonuses. The second most common set bonus was the four piece Noblesse Oblige, which is KQM’s recommendation for Shenhe.

The data provided evidence for a difference in mean ER and atk by various polearm types, whereas the data only provided evidence for a difference in mean atk by one major set bonus type, using the Favonius Lance and Noblesse Oblige as reference frames in each case.

Quantitative Conclusion

The significant differences within the cleaned dataset are as follows:

atk:  

  1) Favonius Lance vs. Wavebreaker's Fin (p = 0.001, ES = 1.009)  
  
  2) Favonius Lance vs. Skyward Spine (p = 0.000, ES = 1.303)  
  
  3) Favonius Lance vs. Calamity Queller (p = 0.000, ES = 1.163)  
  
  4) Favonius Lance vs. Missive Windspear (p = 0.005, 0.898)  
  
  5) Favonius Lance vs. Primordial Jade Winged Spear (p = 0.002, ES = 1.056)  
  
  6) Favonius Lance vs. Vortex Vanquisher (p = 0.017, ES = 1.652)  
  
  7) Full Noblesse vs. atk-atk (p = 0.000, ES = 1.368)  
  
  8) Full Noblesse vs. atk (p = 0.003, ES = 1.665)  
  
ER:  

  1) Favonius Lance vs. Wavebreaker's Fin (p = 0.025, ES = -0.718)  
  
  2) Favonius Lance vs. Skyward Spine (p = 0.044, ES = 0.630)  
  
  3) Favonius Lance vs. Calamity Queller (p = 0.009, ES = 0.610)  
  
  4) Favonius Lance vs. Missive Windspear (p = 0.000, ES = -1.013)  
  
  5) Favonius Lance vs. Lithic Spear (p = 0.011, ES = -1.230)  
  
  6) Favonius Lance vs. Engulfing Lightning (p = 0.008, ES = 1.683)  
  
  7) Favonius Lance vs. Primordial Jade Winged Spear (p = 0.009, ES = -0.882)  
  
  8) Favonius Lance vs. Vortex Vanquisher (p = 0.046, ES = -1.573)  
  
  9) Favonius Lance vs. Deathmatch (p = 0.000, ES = -2.028)  
  

The confidence intervals are as follows:

1) [full noblesse atk]:  2544.744 2949.812  

2) [full noblesse ER]:   149.3676 180.6213  

3) [Favonius Lance atk]: 2685.836 2990.016  

4) [Favonius Lance ER]:  154.7749 173.0917  

5) [atk-atk set ER]:     145.8108 156.9070  

6) [overall atk]:        3129.922 3301.716  

7) [overall ER]:         146.9655 156.5325  

8) [overall ER_req_met]: 0.178143 0.318501  

Interpretations

The majority of fully built Shenhes on display (between 0.178 and 0.319) do not meet KQM’s energy requirements. This could possibly indicates a severe misunderstanding of Shenhe’s role as a character by the community at large, or could demonstrate a tendency of players to maximize the most seemingly important stats, while neglecting smooth rotations and consistent damage.

With respect to gear in the player’s control, Calamity queller, Skyward Spine, and Vortex Vanquisher were correlated with the largest atk increase from Favonius Lance. An atk-atk set bonus was correlated with a similar increase in atk from the full Noblesse Oblige set. Additionally, Engulfing Lightning, Skyward Spine, and Calamity Queller were correlated with increases in ER. This information can be used to construct a final ranking of gear within the dataset.

Because the upper bound of the confidence interval for the ER of Shenhes equipping the full Noblesse Set includes the lower limit of Shenhe’s ER requirement, it generally places higher in the ranking of gear, despite atk-atk having an overall higher atk stat within the dataset.

As previously discussed, the Calamity Queller’s large extra attack with reference to the Favonius Lance, as well as it having a higher population mean ER stat as deduced from the hypothesis testing results in it placing at the top of the list. Engulfing Lightning is slightly worse than the Favonius Lance overall, because the Favonius Lance provides energy to the whole team from its passive, and there was no evidence from the data to suggest that there is any difference in mean atk between the two. The skyward spine ranks higher than the Engulfing lightning, because it manages to have a higher mean atk while also having a decent bump in ER from the Favonius Lance, and ranks higher than Favonius as well, because the extra atk is comparable to that of Calamity Queller’s. The final ordering of gear is as follows:

For Artifacts:

1) Full Noblesse  

2) atk-atk  

3) All Others

For Polearms:

1) Calamity Queller  

2) Skyward Spine  

3) Favonius Lance  

4) Engulfing Lightning  

Where these rankings apply for Shenhes intended to be build as supports, and not for their own personal damage. Ultimately, these rankings have no standing in practice, because they only describe Shenhes on display, and do not provide any basis for gear recommendations.

Comments on the Analysis

If I could redo this process of data collection and analysis, there would be many things I would change. It goes without saying that if an experimental design were possible for this type of study, then I would much prefer it in order to create a more unequivocal ranking of gear, and also provide concrete recommendations to users. This analysis was helpful in observing patterns from users, but ultimately did not extract any novel information on causation.

Firstly, I wish I had included not only the level, but the ascension rank of the characters and the polearms. This would have provided more detailed information on the stats of the characters, and could have helped to fine tune the exclusion criteria further. This may have also created an opening to perform multiple linear regression for the ER stat, and logistic regression for the ER requirement variable.

Secondly, I wish I had included all possible information from the user’s profile, such as their progression in the Spiral Abyss, because I then could have tried to use logistic regression to create a model predicting whether or not they had cleared the abyss.

Thirdly, I wish I had included a variable which provided a sample damage output given the stats the Shenhe had. This could have been performed using the damage calculator tools available online, and I could have used a formula in an Excel or Google spreadsheet to autofill these values for me. This could have been, for example, a team rotation damage on an Ayaka / Kazuha / Shenhe / Kokomi composition. This quantitative variable could have been used as a response variable to a treatment such as the “polearm_name” or “set_bonus” variables, and I could have thereby conducted direct analysis on the Damage outputs being changed by Shenhe’s stats.

Fourthly, as all researchers hope, I wish I could have obtained a larger sample, especially for rare cases such as Engulfing Lightning, so that I could be more sure of the true mean difference and effect. This would have also allowed me to apply the central limit theorem, and use a t-test or other parametric tests, broadening the tools at my disposal.

I am overall very happy with this project, and I believe I have deepened my understanding of using R for data analysis profoundly, but the sources of error and deficiencies of the data remain, such as the voluntary bias in the sampling, the lack of controls, and the missing data about ascension ranks. I feel that my questions about damage output and correlation of all variables remain unanswered, but perhaps in a future study of Shenhe, or a different character entirely, I could use the content from multiple linear regression and the F- distribution to answer my quantitative-quantitative relationship questions.

References

Co-op mode. Genshin Impact Wiki. (n.d.). Retrieved December 14, 2022, from https://genshin-impact.fandom.com/wiki/Co-Op_Mode

Kazuha EM vs. ER | The GUOBA Project. (n.d.). Guoba.keqingmains.com; Yami#8591. Retrieved December 14, 2022, from https://guoba.keqingmains.com/experiments/kazuha-em-er

Petrov, S. (2021, April 26). Permutation test in R. Medium. Retrieved December 15, 2022, from https://towardsdatascience.com/permutation-test-in-r-77d551a9f891

Shenhe | KQM TCL. (n.d.). Library.keqingmains.com; Yami#8591. Retrieved December 14, 2022, from https://library.keqingmains.com/characters/cryo/shenhe

XenoVX#6150, Zamo#6399, KB#1111, ApolloIV#8177, & Sitri#9504. (2022, February 10). Shenhe Guide: The Divine Damsel of Devastation. KQM; Yami#8591. https://keqingmains.com/shenhe/

Zakharov. (n.d.). Energy Recharge Calculator. Google Docs; Yami#8591. Retrieved December 14, 2022, from https://docs.google.com/spreadsheets/d/1-vkmgp5n0bI9pvhUg110Aza3Emb2puLWdeoCgrxDlu4/edit#gid=651762937

Special Mentions

Thanks to Raizel Davis and Professor Rachel Saidi for helping with the code for the randomization post-hoc test, and for the motivation to apply my intuition for coding to data science. This project has revealed to me how much I love both coding and data science, which were both subjects I previously believed I despised. Now, I am excited to do a project like this all over again, and that wouldn’t be true without either of their support through this process.

LS0tDQp0aXRsZTogIlNoZW5oZSBBbmFseXNpcyINCmF1dGhvcjogIkFkaSBWIg0KZGF0ZTogImByIFN5cy5EYXRlKClgIg0Kb3V0cHV0OiBvcGVuaW50cm86OmxhYl9yZXBvcnQNCi0tLQ0KDQpgYGB7ciBsb2FkLXBhY2thZ2VzLCBtZXNzYWdlPUZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KG9wZW5pbnRybykNCmxpYnJhcnkoRlNBKQ0KYGBgDQoNCiMjIyBJbnRybw0KDQogIEdlbnNoaW4gSW1wYWN0IGlzIGEgQ2hpbmVzZSBjb21iYXQgcm9sZS1wbGF5aW5nLWdhbWUgKFJQRykgaW4gd2hpY2ggdGhlIHBsYXllcg0KZXhwbG9yZXMgdGhlIHdvcmxkIG9mIFRleXZhdCBhcyB0aGUgVHJhdmVsZXIuIEFsb25nIHRoZWlyIGpvdXJuZXksIGluLWdhbWUgDQpjaGFyYWN0ZXJzIG1heSBqb2luIHRoZSBUcmF2ZWxlcidzIHBhcnR5LCB0aGVyZWJ5IGJlY29taW5nIHBsYXlhYmxlLiBPbmUgc3VjaA0KY2hhcmFjdGVyIGlzIFNoZW5oZSwgYSBteXN0ZXJpb3VzIHdvbWFuIHdobyB3aWVsZHMgYSBwb2xlYXJtIGFuZCBjcnlvIHZpc2lvbi4NClRoZSBmb2xsb3dpbmcgYXJlIGludGVncmFsIHRlcm1zIHRvIHRoZSBjb21iYXQgc3lzdGVtIG9mIEdlbnNoaW4gSW1wYWN0OiAgDQoNCkVSOiBFbmVyZ3kgUmVjaGFyZ2UsIHRoZSBtdWx0aXBsaWVyIHRoYXQgZGV0ZXJtaW5lcyBob3cgbXVjaCBlbGVtZW50YWwgZW5lcmd5IGEgDQogICAgY2hhcmFjdGVyIGdhaW5zIHBlciBwYXJ0aWNsZSBhYnNvcmJlZC4gIA0KICAgIA0KRWxlbWVudGFsIGVuZXJneTogdXNlZCB0byBjYXN0IGFuIOKAnEVsZW1lbnRhbCBCdXJzdOKAnSBieSBmaWxsaW5nIHVwIGEgbWV0ZXIgd2l0aCANCiAgICBhIGNlcnRhaW4gYW1vdW50IG9mIGVuZXJneS4gVGhpcyBnaXZlcyByaXNlIHRvIGFuICJlbmVyZ3kgcmVxdWlyZW1lbnQiLCB3aGljaA0KICAgIGlzIHRoZSBhbW91bnQgb2YgRW5lcmd5IFJlY2hhcmdlIHRoYXQgYSBjaGFyYWN0ZXIgbmVlZHMgaW4gb3JkZXIgdG8NCiAgICBjb25zaXN0ZW50bHkgdXNlIHRoZWlyIGVsZW1udGFsIGJ1cnN0LiAgDQogICAgDQpFbGVtZW50YWwgQnVyc3Q6IGEgc2tpbGwgd2l0aGluIGEgY2hhcmFjdGVy4oCZcyBraXQgd2hpY2ggY29zdHMgZWxlbWVudGFsIGVuZXJneSANCiAgICB0byB1c2UuIEEgYnVyc3QgaXMgdHJpZ2dlcmVkIGJ5IGNsaWNraW5nIHRoZSAiUSIga2V5IG9uIGEga2V5Ym9hcmQuIEJ1cnN0cw0KICAgIGNhbiBiZSBsZXZlbGVkIHRvIGluY3JlYXNlIHRoZWlyIHV0aWxpdGllcyBhbmQgZGFtYWdlIG11bHRpcGxpZXJzLiAgDQogICAgDQpQYXJ0aWNsZTogdW5pdHMgb2YgZWxlbWVudGFsIGVuZXJneSBnZW5lcmF0ZWQgYnkgY2FzdGluZyBhbiDigJxFbGVtZW50YWwgU2tpbGzigJ0gDQogICAgYW5kIG90aGVyIG1ldGhvZHMuICANCiAgICANCktpdDogYSBjaGFyYWN0ZXJzIHNldCBvZiBhdmFpbGFibGUgbW92ZXMgYW5kIHV0aWxpdGllcy4gIA0KDQpFbGVtZW50YWwgU2tpbGw6IEEgc2tpbGwgd2l0aGluIGEgY2hhcmFjdGVy4oCZcyBraXQgd2hpY2ggY29zdHMgbm8gZWxlbWVudGFsIGVuZXJneSANCiAgICB0byB1c2UuIEFuIGVsZW1lbnRhbCBza2lsbCBpcyB0cmlnZ2VyZWQgYnkgY2xpY2tpbmcgdGhlICJFIiBrZXkgb24gYSBrZXlib2FyZC4gDQogICAgRWxlbWVudGFsIHNraWxscyBjYW4gYmUgbGV2ZWxlZCB0byBpbmNyZWFzZSB0aGVpciB1dGlsaXRpZXMgYW5kIGRhbWFnZSBtdWx0aXBsaWVycy4NCiAgICANCkNvb2xkb3duOiB0aGUgdGltZSBpdCB0YWtlcyB0byBiZSBhYmxlIHRvIHJlLWNhc3QgYSBtb3ZlIHN1Y2ggYXMgYW4gRWxlbWVudGFsDQogICAgU2tpbGwgb3IgRWxlbWVudGFsIEJ1cnN0LiAgDQogICAgDQpBcnRpZmFjdHM6IGVxdWlwbWVudCBjb25zaXN0aW5nIG9mIGEgZmVhdGhlciwgZmxvd2VyLCB0aW1lcGllY2UgKHNhbmRzKSwgZ29ibGV0LA0KICAgIGFuZCBjaXJjbGV0IHdoaWNoIHByb3ZpZGUgYWRkaXRpb25hbCBzdGF0cyB0byBhIGNoYXJhY3RlcnMgYmFzZSBzdGF0cy4gRHVlDQogICAgdG8gYXJ0aWZhY3RzIGhhdmluZyBib3RoIGEgbWFpbiBzdGF0IGFuZCBtYW55IHJhbmRvbSBzdWJzdGF0cywgYXJ0aWZhY3RzDQogICAgZ2VuZXJhdGUgdmFyaWF0aW9uIGluIGNoYXJhY3RlciBzdGF0cy4gQWRkaXRpb25hbGx5LCBzZXQgYm9udXNlcyBjYW4NCiAgICBiZSBvYnRhaW5lZCBieSBlcXVpcHBpbmcgYXQgbGVhc3QgdHdvICgyKSBvciBmb3VyICg0KSBhcnRpZmFjdHMgb2YgdGhlDQogICAgc2FtZSBzZXQsIGFuZCB0aGVzZSBncmFudCBzcGVjaWFsIGVmZmVjdHMgc3VjaCBhcyBib251cyBzdGF0cy4gIA0KICAgIA0KQWR2ZW50dXJlIFJhbms6IGEgbWVhc3VyZSBvZiBleHBlcmllbmNlIGluIHRoZSBnYW1lIHdoaWNoIGlzIGNhbGN1bGF0ZWQgdXNpbmcNCiAgICBjdW11bGF0aXZlIEFkdmVudHVyZSBFeHBlcmllbmNlIHBvaW50cy4gVGhlc2UgcG9pbnRzIGFyZSBvYnRhaW5lZCB0aHJvdWdoDQogICAgY29tcGxldGluZyBkYWlseSBxdWVzdHMsIHByb2dyZXNzaW5nIHRocm91Z2ggdGhlIHN0b3J5IG9mIHRoZSBnYW1lLCBvcGVuaW5nDQogICAgY2hlc3RzIGFuZCBleHBsb3JpbmcsIGNvbXBsZXRpbmcgZG9tYWluIGNoYWxsZW5nZXMsIGFuZCBzcGVuZGluZyByZXNpbi4gIA0KICAgIA0KYXRrOiBhIGNoYXJhY3RlciDigJxzdGF04oCdIHdoaWNoIGlzIG9mdGVuIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSBkYW1hZ2UgZGVhbHQgYnkgDQogICAgdmFyaW91cyBtb3Zlcy4gIA0KICAgIA0KSFA6IGEgY2hhcmFjdGVyICJzdGF0IiB3aGljaCBkZXRlcm1pbmVzIGhvdyBtdWNoIGRhbWFnZSBhIGNoYXJhY3RlciBjYW4gdGFrZSBiZWZvcmUNCiAgICBmYWxsaW5nIGluIGJhdHRsZS4gIA0KICAgIA0KZGVmOiBhIGNoYXJhY3RlciAic3RhdCIgd2hpY2ggZGV0ZXJtaW5lcyBob3cgbXVjaCBkYW1hZ2UgYSBjaGFyYWN0ZXIgdGFrZXMgZm9yDQogICAgYW55IGdpdmVuIGVuZW15IGF0dGFjay4gIA0KICAgIA0KUkVTOiBzaW1pbGFyIHRvIGRlZiwgZGVjcmVhc2VzIGRhbWFnZSB0YWtlbiBmcm9tIGEgc3BlY2lmaWMgZWxlbWVudGFsIHR5cGUuICANCg0KRWxlbWVudGFsIE1hc3Rlcnk6IGFiYnJldmlhdGVkIGFzICJFTSIsIGRldGVybWluZXMgdGhlIGRhbWFnZSBkZWFsdCBieSBlbGVtZW50YWwNCiAgICByZWFjdGlvbnMuICANCiAgICANCkNyaXQ6IGEgY3JpdGljYWwgc3RyaWtlIG9jY3VycyByYW5kb21seSB3aGVuIGxhbmRpbmcgaGl0cyBiYXNlZCBvbiBhIGNoYXJhY3Rlcg0KICAgIHN0YXQgY2FsbGVkICJjcml0IHJhdGUiLiBDcml0IHJhdGUgaXMgZXF1YWwgdG8gdGhlIHByb2JhYmlsaXR5IG9mIGxhbmRpbmcNCiAgICBhIGNyaXRpY2FsIHN0cmlrZS4gRGFtYWdlIGZyb20gY3JpdGljYWwgc3RyaWtlcyBpcyBtdWx0aXBsaWVkIGJ5ICgxK2NkbWcpLA0KICAgIGNyaXQgZGFtYWdlLiBUaGUgYmFzZSB2YWx1ZSBvZiBjcml0IHJhdGUgaXMgNSUsIGFuZCB0aGUgYmFzZSB2YWx1ZSBvZiBjcml0DQogICAgZGFtYWdlIGlzIDUwJS4gIA0KICAgIA0KQ2hhcmFjdGVyIGxldmVsOiBjaGFyYWN0ZXJzIGNhbiBiZSBsZXZlbGVkIHVwIHRvIHVubG9jayBwYXNzaXZlIGFiaWxpdGllcyBhbmQNCiAgICBhZGRpdGlvbmFsIGJhc2Ugc3RhdHMuIFRoZSBtYXhpbXVtIGNoYXJhY3RlciBsZXZlbCBpcyA5MC4gIA0KICAgIA0KUG9sZWFybTogb25lIG9mIHRoZSBmaXZlIHdlYXBvbiBhcmNoZXR5cGVzIGluIEdlbnNoaW4gaW1wYWN0LiBEaWZmZXJlbnQgdHlwZXMNCiAgICBvZiBwb2xlYXJtcyBjYW4gYmUgb2J0YWluZWQgdGhyb3VnaCBleHBsb3JhdGlvbiBhbmQgYSBtZWNoYW5pYyBjYWxsZWQNCiAgICAid2lzaGluZyIgKGdhbWJsaW5nKS4gIA0KICAgIA0KRWxlbWVudDogdGhlcmUgYXJlIHNldmVuICg3KSBlbGVtZW50cyBpbiBUZXl2YXQsIHB5cm8sIGh5ZHJvLCBjcnlvLCBlbGVjdHJvLA0KICAgIGFuZW1vLCBkZW5kcm8sIGFuZCBnZW8uICANCiAgICANCkVsZW1lbnRhbCBkYW1hZ2UgYm9udXM6IGEgbXVsdGlwbGllciB3aGljaCBpbmNyZWFzZXMgZGFtYWdlIG9mIGEgc3BlY2lmaWMNCiAgICBlbGVtZW50YWwgdHlwZS4gQXR0YWNrcyB3aXRoIG5vIGFzc29jaWF0ZWQgZWxlbWVudCBhcmUgdHlwaWNhbGx5IGNvbnNpZGVyZWQNCiAgICAicGh5c2ljYWwiIGF0dGFja3MuIFBoeXNpY2FsIGRhbWFnZSBpcyBtdWx0aXBsaWVkIGJ5IHBoeXNpY2FsIGRhbWFnZSBib251cy4gIA0KICAgIA0KTm9ybWFsIEF0dGFjazogYSBza2lsbCB3aXRoaW4gZXZlcnkgY2hhcmFjdGVyJ3Mga2l0IHdoaWNoIGRlYWxzIHBoeXNpY2FsDQogICAgZGFtYWdlIGZvciBwb2xlYXJtIGNoYXJhY3RlcnMgd2l0aG91dCBhbiBlbGVtZW50YWwgaW5mdXNpb24uIFNoZW5oZSBoZXJzZWxmDQogICAgY2Fubm90IGltYnVlIGhlciBwb2xlYXJtIHdpdGggYW55IGVsZW1lbnQsIGJ1dCBvdGhlciBjaGFyYWN0ZXJzLCBzdWNoIGFzDQogICAgQ2hvbmd5dW4sIGNhbiBlbmFibGUgaGVyIHRvIGRvIHNvLiBUaGlzIHNraWxsIGNhbiBhbHNvIGJlIGxldmVsZWQuICANCiAgICANCldlYXBvbiBsZXZlbDogc2ltaWxhcmx5IHRvIGNoYXJhY3RlciBsZXZlbHMsIHdlYXBvbnMgY2FuIGhhdmUgdGhlaXIgbGV2ZWxzDQogICAgaW5jcmVhc2VkIHVwIHRvIGxldmVsIDkwIGluIG9yZGVyIHRvIG1heGltaXplIHRoZWlyIG1haW4gc3RhdCBhbmQgc3Vic3RhdC4NCiAgICBJbiB0aGUgY2FzZSBvZiBhIGNoYXJhY3RlciBsaWtlIFNoZW5oZSwgaGF2aW5nIGhlciBwb2xlYXJtIGF0IGxldmVsIDkwIGlzDQogICAgaW1wZXJhdGl2ZSwgYXMgc2hlIG5lZWRzIHRoZSBhZGRpdGlvbmFsIGJhc2UgYXRrIHRoYXQgaXQgcHJvdmlkZXMgaW4gb3JkZXINCiAgICB0byBidWZmIGhlciB0ZWFtJ3MgZGFtYWdlLiAgDQogICAgDQpSZWZpbmVtZW50OiB3ZWFwb25zIGNhbiBiZSByZWZpbmVkIHVwIHRvIHJhbmsgNSwgaW1wcm92aW5nIHRoZWlyIHNwZWNpYWwgZWZmZWN0cy4gIA0KDQpEUFM6IHNob3J0IGZvciAiZGFtYWdlIHBlciBzZWNvbmQiLCB3aGljaCBpcyBib3RoIGEgbWVhc3VyYWJsZSBxdWFudGl0eSBhbmQNCiAgICBhIGNoYXJhY3RlciByb2xlLiBBIGNoYXJhY3RlciB0aGF0IGlzIGEgIkRQUyIgZGVhbHMgY29uc2lkZXJhYmxlIGRhbWFnZSwNCiAgICBhcyBvcHBvc2VkIHRvIHNvbGVseSBwcm92aWRpbmcgc3VwcG9ydCB1dGlsaXRpZXMuICANCiAgICANCkh5cGVyY2Fycnk6IEEgY2hhcmFjdGVyIGFyb3VuZCB3aGljaCBhIHRlYW0gaXMgY2VudGVyZWQgaW4gb3JkZXIgdG8gbWF4aW1pemUNCiAgICB0aGF0IHNwZWNpZmljIGNoYXJhY3RlcidzIHBlcnNvbmFsIGRhbWFnZS4gIA0KICAgIA0KUGFzc2l2ZTogQW4gZWZmZWN0IG9yIGFiaWxpdHkgb2YgYSBjaGFyYWN0ZXIgb3Igd2VhcG9uIHdoaWNoIHByb3ZpZGVzIHNwZWNpYWwNCiAgICBlZmZlY3RzIHRvIHRoZSBjaGFyYWN0ZXIsIG9mdGVuIHVuZGVyIGEgc2V0IG9mIGNvbmRpdGlvbnMuICANCg0KRXF1aXBtZW50IC8gR2VhcjogSW4tZ2FtZSBpdGVtcyBzdWNoIGFzIHdlYXBvbnMgYW5kIGFydGlmYWN0cyB3aGljaCBwcm92aWRlDQogICAgZXh0cmEgcG93ZXIgdG8geW91ciBjaGFyYWN0ZXJzLiAgDQogICAgDQpNYWluIHN0YXQ6IEEgcHJpbWFyeSBhdHRyaWJ1dGUgb2YgYW4gYXJ0aWZhY3Qgb3Igd2VhcG9uIHdoaWNoIGluY3JlYXNlcw0KICAgIGl0cyBjb3JyZXNwb25kaW5nIGNoYXJhY3RlciBzdGF0IChhdGssIEVNLCBFUiwgZXRjLikuICANCg0KU3Vic3RhdDogQSBzZWNvbmRhcnkgYXR0cmlidXRlIG9mIGFuIGFydGlmYWN0IG9yIHdlYXBvbiB3aGljaCBpbmNyZWFzZXMNCiAgICBpdHMgY29ycmVzcG9uZGluZyBjaGFyYWN0ZXIgc3RhdC4gIA0KICAgIA0KQnVpbGQ6IFRoZSB3YXkgaW4gd2hpY2ggYSBwbGF5ZXIgZGVjaWRlcyB0byBnZWFyIHRoZWlyIGNoYXJhY3Rlci4gIA0KDQpQbGF5c3R5bGU6IFRoZSB3YXkgaW4gd2hpY2ggYSBwbGF5ZXIgZGVjaWRlcyB0byBwbGF5IHRoZWlyIGNoYXJhY3RlciwNCiAgICBvZnRlbiBiYXNlZCB1cG9uIHRoZWlyIGJ1aWxkLiAgDQoNCg0KDQoNCiAgU2hlbmhlJ3Mga2l0IGlzIG9uZSBvZiB0aGUgbW9yZSBjb21wbGljYXRlZCBvbmVzIGluIHRoZSBjaGFyYWN0ZXIgcm9zdGVyLiBIZXINCmRhbWFnZSBpcyBkaXNndWlzZWQgdGhyb3VnaCBvdGhlciBjaGFyYWN0ZXJzJyBkYW1hZ2UgYm9udXNlcyBhbmQgaGVyIGJ1ZmZpbmcgDQp1dGlsaXRpZXMuIFRoaXMgbWFrZXMgaGVyIHdpZGVseSBtaXN1bmRlcnN0b29kIGFzIGEgY2hhcmFjdGVyLCBhbmQgYWxzbyBsZWFkcw0KdG8gc3ViLW9idGltYWwgYnVpbGRzIHdpdGhpbiB0aGUgY29tbXVuaXR5LiAgDQoNCiAgU2hlbmhl4oCZcyBlbGVtZW50YWwgc2tpbGwg4oCcU3ByaW5nIFNwaXJpdCBTdW1tb25pbmfigJ0gZ2VuZXJhdGVzIHRocmVlICgzKSBjcnlvIHBhcnRpY2xlcw0Kb24gc2tpbGwtcHJlc3MgYW5kIGZvdXIgKDQpIGNyeW8gcGFydGljbGVzIG9uIHNraWxsLWhvbGQuIEhlciBwcmVzcyBjb29sZG93biBpcyAxMCANCnNlY29uZHMsIHdoaWxlIGhlciBob2xkIGNvb2xkb3duIGlzIDE1IHNlY29uZHMuIFRoaXMgbGltaXRzIGhlciBlbmVyZ3kgZ2VuZXJhdGlvbiB0byANCmEgbWF4aW11bSBvZiAwLjMgcGFydGljbGVzIHBlciBzZWNvbmQuICANCg0KICBTaGVuaGXigJlzICJJY3kgUXVpbGxzIiBhcmUgY29uc2lkZXJlZCBhZGRpdGl2ZSBkYW1hZ2UsIHdoaWNoIHNjYWxlIG9uIHBhcnR5IG1lbWJlcuKAmXMgDQptdWx0aXBsaWNhdGl2ZSBzdGF0cyAoY3JpdGljYWwgcmF0ZSwgY3JpdGljYWwgZGFtYWdlLCBjcnlvIGRhbWFnZSwgZXRjLikgYW5kIG9ubHkgDQp0cmlnZ2VyIG9uIG5vbi10cmFuc2Zvcm1hdGl2ZSBjcnlvIGRhbWFnZS4gSGVyIHNraWxsLXByZXNzIGdlbmVyYXRlcyBmaXZlICg1KSANCkljeSBRdWlsbHMgZm9yIGVhY2ggdGVhbW1hdGUgdG8gdXNlLCBhbmQgaGVyIHNraWxsLWhvbGQgZ2VuZXJhdGVzIHNldmVuICg3KS4gDQpFYWNoIEljeSBRdWlsbOKAmXMgYmFzZSBhZGRpdGlvbiB0byB0aGUgZGFtYWdlIGlzIGNhbGN1bGF0ZWQgdXNpbmcgc29sZWx5IFNoZW5oZeKAmXMgDQphdGsgc3RhdCBhbmQgc2tpbGwgdGFsZW50IGxldmVsLiBUaGlzIG1lYW5zIHRoYXQgSWN5IFF1aWxsIGRhbWFnZSBpcyBvcHRpbWl6ZWQgYnkgDQppbmNyZWFzaW5nIFNoZW5oZeKAmXMgYXRrIGFuZCBza2lsbCB0YWxlbnQgbGV2ZWwuICANCg0KICBTaGVuaGUgaGFzIG11bHRpcGxlIHNvdXJjZXMgb2YgdXRpbGl0eSBpbiBoZXIga2l0LiBIZXIgNHRoIGFzY2Vuc2lvbiBwYXNzaXZlIA0KdGFsZW50IHByb3ZpZGVzIGNoYXJhY3RlcnMgd2l0aCAxNSUgc2tpbGwgYW5kIGJ1cnN0IGRhbWFnZSBib251cyB3aGVuIHVzaW5nIGhlciANCnNraWxsLXByZXNzLCBhbmQgMTUlIG5vcm1hbCBhbmQgY2hhcmdlZCBhdHRhY2sgZGFtYWdlIGJvbnVzIHdoZW4gdXNpbmcgaGVyIHNraWxsLWhvbGQuIA0KSGVyIDFzdCBhc2NlbnNpb24gcGFzc2l2ZSB0YWxlbnQgcHJvdmlkZXMgY2hhcmFjdGVycyB3aXRoaW4gdGhlIGFyZWEgb2YgZWZmZWN0IChBb0UpIA0Kb2YgaGVyIGVsZW1lbnRhbCBidXJzdCDigJxEaXZpbmUgTWFpZGVu4oCZcyBEZWxpdmVyYW5jZeKAnSBhIDE1JSBjcnlvIGRhbWFnZSBib251cy4gDQpIZXIgZWxlbWVudGFsIGJ1cnN0IGhhcyBhIGR1cmF0aW9uIG9mIDEyIHNlY29uZHMsIGEgY29vbGRvd24gb2YgMjAgc2Vjb25kcywgYW5kIA0KZGVjcmVhc2VzIGVuZW1pZXPigJkgcGh5c2ljYWwgYW5kIGNyeW8gUkVTIGJ5IGEgbWF4aW11bSBvZiAxNSUgYXQgdGFsZW50IGxldmVsIDEwLiANCk9uZSBvZiBoZXIgY2hvaWNlcyBvZiBhcnRpZmFjdCBzZXRzLCB0aGUgNC1waWVjZSBOb2JsZXNzZSBPYmxpZ2UgcHJvdmlkZXMgdGhlIGVudGlyZSANCnRlYW0gd2l0aCBhIDIwJSBhdGsgYm9udXMsIGZyb20gd2hpY2ggc2hlIGNhbiBhbHNvIGJlbmVmaXQuICANCg0KICBCZWNhdXNlIFNoZW5oZeKAmXMgSWN5IFF1aWxscyBzY2FsZSB3aXRoIGF0aywgaW5jcmVhc2luZyB0aGUgZXF1aXBwZWQgcG9sZWFybSBsZXZlbCANCnRvIGl0cyBtYXggb2YgOTAgd2lsbCBzaWduaWZpY2FudGx5IGluY3JlYXNlIEljeSBRdWlsbCBkYW1hZ2UuIER1ZSB0byBtYW55IG9mIA0KU2hlbmhl4oCZcyBidWZmIHV0aWxpdGllcyBiZWluZyByZXN0cmljdGVkIHRvIGhlciBidXJzdCwgaW5jcmVhc2luZyBoZXIgYnVyc3QgdXB0aW1lIA0Kd2lsbCBpbmNyZWFzZSB5b3VyIHRlYW3igJlzIGRhbWFnZSBvdXRwdXQsIHdoaWNoIGlzIGRlcGVuZGVudCBvbiBTaGVuaGXigJlzIGVuZXJneSANCnJlY2hhcmdlIHN0YXQuIFRoaXMgY3JlYXRlcyBhbiBpbXBvcnRhbnQgYmFsYW5jZSBiZXR3ZWVuIEVSIGFuZCBhdGsgb24gU2hlbmhlLiANClRoaXMgd2lsbCBiZSBvbmUgb2YgdGhlIG1haW4gaW52ZXN0aWdhdGlvbnMgb2YgdGhpcyBzdHVkeS4gIA0KDQoNCg0KIyMjIE1ldGhvZCBhbmQgRGF0YSBEZXNjcmlwdGlvbg0KDQogIEluIHRoaXMgYW5hbHlzaXMsIEkgd2lzaCB0byBvYnNlcnZlIHRyZW5kcyB3aXRoaW4gdGhlIGNoYXJhY3RlciBzdGF0aXN0aWNzDQpvZiBTaGVuaGVzIHdoaWNoIGFyZSBmdWxseSBidWlsdC4gRnVsbHkgYnVpbHQgU2hlbmhlcyBhcmUgaW5kaWNhdGl2ZSB0aGF0IHRoZQ0KcGxheWVyIGlzIHdoYXQgd2Ugd291bGQgY2FsbCBhICJTaGVuaGUgbWFpbiIsIG1lYW5pbmcgdGhhdCB0aGV5IHVzZSB0aGVpcg0KU2hlbmhlIHRvIGNsZWFyIGNvbnRlbnQgd2l0aGluIHRoZSBnYW1lLiBJdCBpcyBpbXBvcnRhbnQgdG8gbm90ZSB0aGF0IHBsYXllcnMNCm9mIHVuYnVpbHQgU2hlbmhlcyBtYXkgc3RpbGwgYmUgU2hlbmhlIG1haW5zLCBidXQgU2hlbmhlcyB3aXRoIGJ1aWxkcy1pbi1wcm9ncmVzcw0KYXJlIG5vdCB0aGUgdGFyZ2V0IHBvcHVsYXRpb24gb2YgdGhpcyBzdHVkeS4gIA0KDQogIFdpdGhpbiB0aGUgZ2FtZSwgdGhlcmUgaXMgYSBmZWF0dXJlIGNhbGxlZCB0aGUgIkNvLU9wIE1lbnUiLCB3aGljaCBnZW5lcmF0ZXMNCmEgbGlzdCBvZiBwbGF5ZXJzIG9ubGluZSB3aGljaCBvbmUgY2FuIGpvaW4gYW5kIHBsYXkuIEluIHRoZSBDby1PcCBNZW51LCBhDQpwbGF5ZXIgY2FuIGNob29zZSB0byBkaXNwbGF5IHVwIHRvIGVpZ2h0ICg4KSBvZiB0aGVpciBjaGFyYWN0ZXJzIHNvIHRoYXQgb3RoZXJzDQptYXkgc2VlLiBUaGV5IGNhbiBhbHNvIGNob29zZSB3aGV0aGVyIHRoZWlyICJjaGFyYWN0ZXIgZGV0YWlscyIgKHN0YXRzKSBhcmUNCnZpc2libGUuIFRvIGdlbmVyYXRlIHRoaXMgZGF0YXNldCwgbXlzZWxmIGFuZCB0aHJlZSBmcmllbmRzIHdlbnQgdGhyb3VnaCB0aGUNCkNvLU9wIE1lbnVzIGluIG91ciBnYW1lcyBpbiBvcmRlciBmcm9tIHRvcCB0byBib3R0b20sIGFuZCBjaGVja2VkIGZvciBwbGF5ZXJzDQp3aG8gaGFkIFNoZW5oZSBpbiB0aGVpciBkaXNwbGF5LiBUaG9zZSB3aGljaCBjaG9zZSB0byBtYWtlIHRoZWlyIGNoYXJhY3Rlcg0KZGV0YWlscyB2aXNpYmxlIGhhZCB0aGVpciBzdGF0cyByZWNvcmRlZC4gIA0KDQogIFRoZXJlIGFyZSBhIGNvdXBsZSBzb3VyY2VzIG9mIHNhbXBsaW5nIGVycm9yIGFuZCBvdGhlciBjbGFyaWZpY2F0aW9ucyB0aGF0IG11c3QNCmJlIG1hZGUuIFRoZXJlIGlzIG5vIGNvbmZpcm1hdGlvbiBmcm9tIHRoZSBkZXZlbG9wZXJzIHRoYXQgdGhlIENvLU9wIG1lbnUgaXMNCnRydWx5IHJhbmRvbS4gV2UgbmV2ZXIgZW5jb3VudGVyZWQgcmVwZWF0cyBpbiBvdXIgZGF0YSBjb2xsZWN0aW9uLCB3aGljaCBpcw0KcHJvbWlzaW5nLCBidXQgc3RpbGwgbm90IGNvbmZpcm1hdGlvbiBvZiB0aGUgcmFuZG9tbmVzcyBvciBwc2V1ZG8tcmFuZG9tbmVzcyBvZg0KdGhlIHNhbXBsZS4gQW5vdGhlciBpc3N1ZSBpcyB0aGF0IHdlIGRpZCBub3QgaG9sZCB0aGUgdGltZSBhdCB3aGljaCB3ZSBzZWFyY2hlZA0KZm9yIHBsYXllcnMgY29uc3RhbnQsIGFuZCBiZWNhdXNlIHRoZSBDby1PcCBtZW51IG9ubHkgZGlzcGxheXMgb3RoZXIgcGxheWVycyB0aGF0DQphcmUgb25saW5lLCB0aGVyZSBtYXkgaGF2ZSBiZWVuIHNvbWUgY29uZm91bmRpbmcgZHVlIHRvIHRoZSB0aW1lcyBhdCB3aGljaCB3ZQ0KY29sbGVjdGVkIG91ciBvYnNlcnZhdGlvbnMgdGhyb3VnaG91dCBPY3RvYmVyIG9mIDIwMjIuIEFkZGl0aW9uYWxseSwgdGhlIENvLU9wDQpNZW51IGlzIHJlc3RyaWN0ZWQgYnkgdGhlIHBsYXllcidzIHNlcnZlciwgd2hpY2ggaW4gdGhlIGNhc2Ugb2YgdGhpcyBkYXRhc2V0IGlzDQpzb2xlbHkgdGhlIEFtZXJpY2Egc2VydmVyLiBJdCBpcyBpbXBvcnRhbnQgdG8gbm90ZSB0aGF0IHBsYXllcnMgb24gdGhlIEFtZXJpY2ENCnNlcnZlciBtYXkgb3IgbWF5IG5vdCBiZSBpbiB0aGUgd2VzdGVybiBoZW1pc3BoZXJlLCBhcyBwbGF5ZXJzIGNhbiBjaG9vc2UgdG8NCmNyZWF0ZSB0aGVpciBhY2NvdW50IG9uIGFueSBzZXJ2ZXIgdGhleSBzbyBjaG9vc2UuIFRoZSBmaW5hbCBvYnZpb3VzIHNvdXJjZQ0Kb2YgZXJyb3IgaXMgdGhhdCB0aGUgcGVvcGxlIHdobyBkaXNwbGF5ZWQgdGhlaXIgU2hlbmhlcyBkaWQgc28gdm9sdW50YXJpbHksIGFuZA0KdGhlcmVmb3JlIHRoZSBzYW1wbGUgbWF5IG5vdCBiZSB0cnVseSByZXByZXNlbnRhdGl2ZSBvZiBhbGwgU2hlbmhlcyBpbiB3aGljaA0Kd2UgYXJlIGludGVyZXN0ZWQuICANCg0KICBBIGNvdXBsZSBvZiB2YXJpYWJsZXMgd2l0aGluIHRoZSBkYXRhc2V0IHdlcmUgY29udHJpdmVkIHVzaW5nIG90aGVyIGRhdGENCmZyb20gdGhlIGdpdmVuIG9ic2VydmF0aW9uLiBQYXJ0aWN1bGFybHksIHRoZSBFUl9yZXFfbWV0LCBkZXNjcmliaW5nIHdoZXRoZXINCmEgcGxheWVyIGhhZCByZWFjaGVkIEtRTSdzIEVSIHJlcXVpcmVtZW50LCB3YXMgcXVhbnRpZmllZCBvbiB3aGV0aGVyIHRoZWlyIEVSDQpzdGF0IHdhcyBncmVhdGVyIHRoYW4gMTc3LjUsIG9yIGluIHRoZSBjYXNlIG9mIGEgU2hlbmhlIGVxdWlwcGluZyB0aGUgcG9sZWFybQ0KIkZhdm9uaXVzIExhbmNlIiwgaWYgdGhlaXIgRVIgc3RhdCB3YXMgZ3JlYXRlciB0aGFuIDE2Mi41LiBUaGUgImJ1aWxkX3R5cGUiDQp2YXJpYWJsZSwgc2ltaWxhcmx5IHdhcyBxdWFsaWZpZWQgb24gdGhlIGZvbGxvd2luZyBsb2dpY2FsIHN0cnVjdHVyZTogIA0KDQogIGlmIGV4Y2x1c2lvbiBjcml0ZXJpYSBtZXQsIHRoZW4gZ2FpbiByb2xlICJpbmNvbXBsZXRlIiAgDQogIGVsc2UgaWYgY29uc3RlbGxhdGlvbiA9PSA2LCB0aGVuIGdhaW4gcm9sZSAid2hhbGUiDQogIGVsc2UgaWYgRVJfcmVxX21ldCA9PSAxLCB0aGVuIGdhaW4gcm9sZSAidXRpbGl0eV9idWZmZXIiICANCiAgZWxzZSBpZiBzZXRfYm9udXMgPT0gIjROTyIsIHRoZW4gZ2FpbiByb2xlICJ1dGlsaXR5X2J1ZmZlciIgIA0KICBlbHNlIGlmIHBvbGVhcm1fbmFtZSA9PSAiRmF2b25pdXNfTGFuY2UiIGFuZCBjcml0X3JhdGUgPj0gNTAuIHRoZW4gZ2FpbiByb2xlICJ1dGlsaXR5X2J1ZmZlciIgIA0KICBlbHNlIGlmIGNyeW9fZG1nICE9IDAgYW5kIHBoeXNfZG1nICE9IDAsIHRoZW4gZ2FpbiByb2xlICJoeWJyaWQiICANCiAgZWxzZSBpZiBjcnlvX2RtZyAhPSAwLCB0aGVuIGdhaW4gcm9sZSAiY3J5b19kcHMiICANCiAgZWxzZSBpZiBwaHlzX2RtZyAhPSAwLCB0aGVuIGdhaW4gcm9sZSAicGh5c19kcHMiICANCiAgZWxzZSwgZ2FpbiByb2xlICJxdWlsbCBvbmx5IiAgDQogIA0KICANCg0KICBUaGUgc3RhdGlzdGljcyB3ZSB3aWxsIHVzZSB0byBkZXNjcmliZSBhbmQgYW5hbHl6ZSB0aGUgZGF0YSBhcmUgdGhlIGZvbGxvd2luZzogIA0KDQogIDEpIFNhbXBsZSBhbmQgZ3JvdXAgbWVhbnMgb2YgbXVsdGlwbGUgdmFyaWFibGVzIChtb3N0bHkgYXRrIGFuZCBFUik7IHRoaXMgd2lsbA0KICAgICAgcHJvdmlkZSBpbmZvcm1hdGlvbiBvbiB0aGUgYXZlcmFnZSBhdGsgYW5kIEVSIG9mIFNoZW5oZXMgaW4gdGhlIGRhdGFzZXQuICANCiAgDQogIDIpIFNhbXBsZSBzdGFuZGFyZCBkZXZpYXRpb247IHRoaXMgd2lsbCBwcm92aWRlIGluZm9ybWF0aW9uIG9uIHRoZSBzcHJlYWQgb2YNCiAgICAgIHRoZSBkaXN0cmlidXRpb25zIG9mIG11bHRpcGxlIHZhcmlhYmxlcyBzdWNoIGFzIGF0ayBhbmQgRVIuICANCiAgICAgIA0KICAzKSBTYW1wbGUgcHJvcG9ydGlvbjsgdGhpcyB3aWxsIHByb3ZpZGUgaW5mb3JtYXRpb24gb24gdGhlIHBlcmNlbnRhZ2Ugb2YgdXNlcnMNCiAgICAgIGV4aGliaXRpbmcgYSBjZXJ0YWluIGNoYXJhY3RlcmlzdGljLiAgDQogICAgICANCiAgNCkgU3RhbmRhcmQgRXJyb3I6IHRoaXMgd2lsbCBwcm92aWRlIGluZm9ybWF0aW9uIG9uIHRoZSBzcHJlYWQgb2YgdGhlIHNhbXBsaW5nDQogICAgICBkaXN0cmlidXRpb25zIG9mIG11bHRpcGxlIHZhcmlhYmxlcyBvZiB0aGUgZGF0YXNldC4gVGhpcyB3aWxsIG5vdCBiZQ0KICAgICAgcmVwb3J0ZWQsIHJhdGhlciwgaXQgd2lsbCBiZSB1c2VkIGluIGNvbnN0cnVjdGluZyBjb25maWRlbmNlIGludGVydmFscy4gIA0KICAgICAgDQogIDUpIE1lYW4gZGlmZmVyZW5jZTogdGhpcyB3aWxsIHByb3ZpZGUgaW5mb3JtYXRpb24gb24gdGhlIGRpZmZlcmVuY2UgYmV0d2Vlbg0KICAgICAgdGhlIGNlbnRlcnMgb2YgdGhlIGRpc3RyaWJ1dGlvbnMgb2YgYSBjb21tb24gdmFyaWFibGUgYmV0d2VlbiB0d28gZ3JvdXBzLiAgDQogICAgICANCiAgNikgRWZmZWN0IFNpemU6IHRoaXMgd2lsbCBwcm92aWRlIGluZm9ybWF0aW9uIG9uIHRoZSBpbXBvcnRhbmNlIG9mIGEgZGlmZmVyZW5jZQ0KICAgICAgaW4gbWVhbnMuICANCiAgICAgIA0KICA3KSBwLXZhbHVlOiB0aGlzIHdpbGwgcHJvdmlkZSBpbmZvcm1hdGlvbiBvbiB0aGUgbGlrZWxpaG9vZCBvZiBhIHR5cGUtSSBlcnJvci4NCiAgICAgIGluIG90aGVyIHdvcmRzLCB0aGlzIHZhbHVlIGRlc2NyaWJlcyB0aGUgY2hhbmNlIG9mIHJlamVjdGluZyBhIHRydWUgbnVsbA0KICAgICAgaHlwb3RoZXNpcy4gIA0KICAgICAgDQogIDgpIHJhdyBjb3VudHM6IHRoaXMgd2lsbCBwcm92aWRlIGluZm9ybWF0aW9uIG9uIHRoZSBudW1iZXIgb2Ygb2NjdXJyZW5jZXMgb2YNCiAgICAgIGEgY2VydGFpbiBjb25kaXRpb24uIFRoZXNlIHdpbGwgbW9zdGx5IGJlIHVzZWQgaW4gY2FsY3VsYXRpbmcgcC12YWx1ZXMuICANCiAgICAgIA0KICBUaGUgb3ZlcmFyY2hpbmcgcXVlc3Rpb24gd2hpY2ggdGhpcyBzdHVkeSBhdHRlbXB0cyB0byBhbnN3ZXIgaXM6ICANCiAgDQogIEhvdyBhcmUgdGhlIGZhY3RvcnMgd2l0aGluIGEgcGxheWVyJ3MgY29udHJvbCBhcmUgY29ycmVsYXRlZCB3aXRoIFNoZW5oZSdzIGF0ayANCmFuZCBFUiBzdGF0cz8gSG93IGRvZXMgdGhlIGFuc3dlciB0byB0aGlzIHF1ZXN0aW9uIGNvbXBhcmUgdG8gS1FNJ3MgZGVzY3JpcHRpb25zDQphbmQgc3RhbmRhcmRzIGZvciBTaGVuaGU/ICANCiAgICANCg0KYGBge3IgY29kZS1jaHVuay1zdGFydH0NCiMgbG9hZCB0aGUgZGF0YQ0KDQpzZXR3ZCgiQzovVXNlcnMvMTU4NTcvRG93bmxvYWRzIikNCnNoZW5oZV9vcmlnaW5hbCA8LSByZWFkX2Nzdigic2hlbmhlX29yaWdpbmFsX2RhdGEuY3N2IikNCmBgYA0KDQoNCg0KIyMjIENsZWFuaW5nDQoNCiAgSGVyZSBJIGNsZWFuZWQgb3V0IHRoZSBkYXRhc2V0IHRvIHJlbW92ZSBvYnNlcnZhdGlvbnMgd2hpY2ggd2VyZSB1bmhlbHBmdWwgZm9yDQphbmFseXNpcyBvZiBteSB0YXJnZXQgcG9wdWxhdGlvbiwgYW5kIHRvIG1ha2UgaXQgbW9yZSBmcmllbmRseSB0byB1c2UgaW4gUlN0dWRpby4gDQpUaGUgZXhjbHVzaW9uIGNyaXRlcmlhIGZvciAiZnVsbHkgYnVpbHQiIFNoZW5oZXMgYXJlIGFzIGZvbGxvd3M6ICANCg0KICAxKSBUaGUgc3VtIG9mIGFsbCBhcnRpZmFjdCBsZXZlbHMgaXMgbGVzcyB0aGFuIDk1ICANCiAgMikgVGhlIGVxdWlwcGVkIHBvbGVhcm0ncyBsZXZlbCBpcyBub3QgOTAgIA0KICAzKSBUaGUgY2hhcmFjdGVyIGxldmVsIGlzIGxlc3MgdGhhbiA4MCAgDQogIA0KICBBcnRpZmFjdCBsZXZlbHMgYXJlIGEgZ2VuZXJhbCBtZXRyaWMgb2YgaW52ZXN0bWVudCBpbnRvIGEgY2hhcmFjdGVyLCBhbmQgYQ0KYnVpbGQgaXMgZ2VuZXJhbGx5IGNvbnNpZGVyZWQgImNvbXBsZXRlIiB3aGVuIGFsbCBhcnRpZmFjdHMgYXJlIGF0IGxldmVsIDIwLiANCkluIHRoZSBjYXNlIG9mIFNoZW5oZSwgaGF2aW5nIGEgbWF4IGxldmVsIHBvbGVhcm0gaXMgbmVjZXNzYXJ5LCBiZWNhdXNlDQpzaGUgd2lsbCBvdGhlcndpc2UgbG9zZSBvdXQgb24gYSBsYXJnZSBhbW91bnQgb2YgYXRrLCB3aGljaCBpcyBuZWNlc3NhcnkgZm9yDQpoZXIgcm9sZSBhcyBhIHBhcnRpYWwgZGFtYWdlIGRlYWxlci4gTGFzdGx5LCBTaGVuaGUgYWxzbyBnYWlucyBiYXNlIGF0ayBmcm9tDQpoZXIgcGVyc29uYWwgbGV2ZWwsIHdoaWNoIG1lYW5zIGEgY2hhcmFjdGVyIGxldmVsIG5vIGxlc3MgdGhhbiA4MCBpcyBuZWNlc3NhcnkNCnRvIGFjaGlldmUgYSBuZWFyLW9wdGltYWwgY2VpbGluZyBvZiBkYW1hZ2UgYW5kIHN1cHBvcnQgcG90ZW50aWFsLiAgDQoNCg0KYGBge3IgY29kZS1jaHVuay1jbGVhbn0NCiMgQ2hhbmdlIHNwYWNlcyB0byB1bmRlcnNjb3JlcywgcmVuYW1lIHNvbWUgb2YgdGhlIHZhcmlhYmxlcy4gIA0KbmFtZXMoc2hlbmhlX29yaWdpbmFsKSA8LSBnc3ViKCIgIiwgIl8iLCBuYW1lcyhzaGVuaGVfb3JpZ2luYWwpKQ0KbmFtZXMoc2hlbmhlX29yaWdpbmFsKSA8LSBnc3ViKCJBZHZlbnR1cmVfUmFuayIsICJBUiIsIG5hbWVzKHNoZW5oZV9vcmlnaW5hbCkpDQpuYW1lcyhzaGVuaGVfb3JpZ2luYWwpIDwtIGdzdWIoIkNoYXJhY3Rlcl9sdmwiLCAiY2hhcl9sdmwiLCBuYW1lcyhzaGVuaGVfb3JpZ2luYWwpKQ0KbmFtZXMoc2hlbmhlX29yaWdpbmFsKSA8LSBnc3ViKCJoZWFsaW5nX2JvbnVzIiwgIkhCIiwgbmFtZXMoc2hlbmhlX29yaWdpbmFsKSkgIA0KDQojIFJlbW92ZSB0aGUgdmFyaWFibGVzIHdob3NlIHZhbHVlcyB3ZXJlIDAgZm9yIGFsbCBvYnNlcnZhdGlvbnMuICANCnNoZW5oZSA8LSBzaGVuaGVfb3JpZ2luYWwgJT4lDQogIHNlbGVjdCgtcHlyb19kbWcsIC1oeWRyb19kbWcsIC1kZW5kcm9fZG1nLCAtZWxlY3Ryb19kbWcsIC1hbmVtb19kbWcpDQoNCiMgQWxsb3cgUiB0byByZWFkIGFwcHJvcHJpYXRlIHZhcmlhYmxlcyBhcyBudW1lcmljLiAgDQoNCnNoZW5oZSRmbG93ZXJfbHZsIDwtIGFzLm51bWVyaWMoc2hlbmhlJGZsb3dlcl9sdmwpDQpzaGVuaGUkZmVhdGhlcl9sdmwgPC0gYXMubnVtZXJpYyhzaGVuaGUkZmVhdGhlcl9sdmwpDQpzaGVuaGUkc2FuZHNfbHZsIDwtIGFzLm51bWVyaWMoc2hlbmhlJHNhbmRzX2x2bCkNCnNoZW5oZSRnb2JsZXRfbHZsIDwtIGFzLm51bWVyaWMoc2hlbmhlJGdvYmxldF9sdmwpDQpzaGVuaGUkY2lyY2xldF9sdmwgPC0gYXMubnVtZXJpYyhzaGVuaGUkY2lyY2xldF9sdmwpDQpzaGVuaGUkcmVmaW5lbWVudCA8LSBhcy5udW1lcmljKHNoZW5oZSRyZWZpbmVtZW50KQ0Kc2hlbmhlJEVSX3JlcV9tZXQgPC0gYXMubnVtZXJpYyhzaGVuaGUkRVJfcmVxX21ldCkNCnNoZW5oZSROQV90YWxlbnRfbHZsIDwtIGFzLm51bWVyaWMoc2hlbmhlJE5BX3RhbGVudF9sdmwpDQpzaGVuaGUkRV90YWxlbnRfbHZsIDwtIGFzLm51bWVyaWMoc2hlbmhlJEVfdGFsZW50X2x2bCkNCnNoZW5oZSRRX3RhbGVudF9sdmwgPC0gYXMubnVtZXJpYyhzaGVuaGUkUV90YWxlbnRfbHZsKQ0KDQojIEZpbHRlciBmb2xsb3dpbmcgdGhlIGV4Y2x1c2lvbiBjcml0ZXJpYTogIA0KIyAgICAgMSkgRXhjbHVkZSBpZiB0aGUgc3VtIG9mIHRoZSBhcnRpZmFjdCBsZXZlbHMgaXMgbGVzcyB0aGFuIDk1LiAgDQojICAgICAyKSBFeGNsdWRlIGlmIHRoZSBwb2xlYXJtIGxldmVsIGlzIG5vdCA5MC4gIA0KIyAgICAgMykgRXhjbHVkZSBpZiB0aGUgY2hhcmFjdGVyIGxldmVsIGlzIGxlc3MgdGhhbiA4MC4gIA0KDQpzaGVuaGUgPC0gc2hlbmhlICU+JQ0KICBtdXRhdGUoYXJ0aWZhY3RfdG90YWwgPSBmbG93ZXJfbHZsICsgZmVhdGhlcl9sdmwgKyBzYW5kc19sdmwgKyBnb2JsZXRfbHZsICsgY2lyY2xldF9sdmwpICU+JQ0KICBmaWx0ZXIoYXJ0aWZhY3RfdG90YWwgPj0gOTUpICU+JQ0KICBmaWx0ZXIocG9sZWFybV9sdmwgPT0gOTApICU+JQ0KICBmaWx0ZXIoY2hhcl9sdmwgPj0gODApICANCg0KIyBSZW1vdmUgdGhlIGhlYWxpbmcgYm9udXMgdmFyaWFibGUgYXMgaXQgaXMgdW5pZm9ybWx5IDAgaW4gdGhlIG5ldyBmaWx0ZXJlZCBkYXRhLiAgDQoNCnNoZW5oZSA8LSBzaGVuaGUgJT4lDQogIHNlbGVjdCgtSEIpICANCg0KIyBTb3J0IHRoZSBzZXQgYm9udXNlcyBieSB0aGUgZXhhY3QgZWZmZWN0cyB0aGV5IHByb3ZpZGUgKHNvbWUgYXJlIGlkZW50aWNhbCkgIA0Kc2hlbmhlJHNldF9ib251cyA8LSBnc3ViKCIyQkMyUEYiLCAicGh5cy1waHlzIiwgc2hlbmhlJHNldF9ib251cykgIA0Kc2hlbmhlJHNldF9ib251cyA8LSBnc3ViKCIyQkMyU1IiLCAicGh5cy1hdGsiLCBzaGVuaGUkc2V0X2JvbnVzKSAgDQpzaGVuaGUkc2V0X2JvbnVzIDwtIGdzdWIoIjJCUzJHRiIsICJjcnlvLWF0ayIsIHNoZW5oZSRzZXRfYm9udXMpICANCnNoZW5oZSRzZXRfYm9udXMgPC0gZ3N1YigiMkJTMlNSIiwgImNyeW8tYXRrIiwgc2hlbmhlJHNldF9ib251cykgIA0Kc2hlbmhlJHNldF9ib251cyA8LSBnc3ViKCIyRW9hMkdGIiwgImF0ay1hdGsiLCBzaGVuaGUkc2V0X2JvbnVzKSAgDQpzaGVuaGUkc2V0X2JvbnVzIDwtIGdzdWIoIjJFb2FPMkdGIiwgImF0ay1hdGsiLCBzaGVuaGUkc2V0X2JvbnVzKSAgDQpzaGVuaGUkc2V0X2JvbnVzIDwtIGdzdWIoIjJFb2FPMlNSIiwgImF0ay1hdGsiLCBzaGVuaGUkc2V0X2JvbnVzKSAgDQpzaGVuaGUkc2V0X2JvbnVzIDwtIGdzdWIoIjJHRjJCUyIsICJjcnlvLWF0ayIsIHNoZW5oZSRzZXRfYm9udXMpICANCnNoZW5oZSRzZXRfYm9udXMgPC0gZ3N1YigiMkdGMk5PIiwgImF0ay1ub2JsZXNzZSIsIHNoZW5oZSRzZXRfYm9udXMpICANCnNoZW5oZSRzZXRfYm9udXMgPC0gZ3N1YigiMkdGMlNSIiwgImF0ay1hdGsiLCBzaGVuaGUkc2V0X2JvbnVzKSAgDQpzaGVuaGUkc2V0X2JvbnVzIDwtIGdzdWIoIjJHRjJWSCIsICJhdGstYXRrIiwgc2hlbmhlJHNldF9ib251cykgIA0Kc2hlbmhlJHNldF9ib251cyA8LSBnc3ViKCIyR0YyV1QiLCAiYXRrLUVNIiwgc2hlbmhlJHNldF9ib251cykgIA0Kc2hlbmhlJHNldF9ib251cyA8LSBnc3ViKCIyU1IyVkgiLCAiYXRrLWF0ayIsIHNoZW5oZSRzZXRfYm9udXMpICANCnNoZW5oZSRzZXRfYm9udXMgPC0gZ3N1YigiNEJTIiwgImZ1bGwtYmxpenphcmQiLCBzaGVuaGUkc2V0X2JvbnVzKSAgDQpzaGVuaGUkc2V0X2JvbnVzIDwtIGdzdWIoIjRFb1NGIiwgImZ1bGwtZW1ibGVtIiwgc2hlbmhlJHNldF9ib251cykgIA0Kc2hlbmhlJHNldF9ib251cyA8LSBnc3ViKCI0R0YiLCAiZnVsbC1nbGFkaWF0b3IiLCBzaGVuaGUkc2V0X2JvbnVzKSAgDQpzaGVuaGUkc2V0X2JvbnVzIDwtIGdzdWIoIjROTyIsICJmdWxsLW5vYmxlc3NlIiwgc2hlbmhlJHNldF9ib251cykgIA0Kc2hlbmhlJHNldF9ib251cyA8LSBnc3ViKCIyQlMiLCAiY3J5byIsIHNoZW5oZSRzZXRfYm9udXMpICANCnNoZW5oZSRzZXRfYm9udXMgPC0gZ3N1YigiMkdGIiwgImF0ayIsIHNoZW5oZSRzZXRfYm9udXMpICANCnNoZW5oZSRzZXRfYm9udXMgPC0gZ3N1YigiMlNSIiwgImF0ayIsIHNoZW5oZSRzZXRfYm9udXMpICANCg0KIyBBbmQgdG8gcmVkdWNlIHRoZSBsZW5ndGggb2YgdGhlIGxhcmdlc3QgcG9sZWFybSBuYW1lcw0Kc2hlbmhlJHBvbGVhcm1fbmFtZSA8LSBnc3ViKCJQcmltb3JkaWFsX0phZGVfV2luZ2VkX1NwZWFyIiwgIkphZGUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoZW5oZSRwb2xlYXJtX25hbWUpDQpzaGVuaGUkcG9sZWFybV9uYW1lIDwtIGdzdWIoIlN0YWZmX29mX1NjYXJsZXRfU2FuZHMiLCAiU2NhcmxldF9TYW5kcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hlbmhlJHBvbGVhcm1fbmFtZSkNCnNoZW5oZSRwb2xlYXJtX25hbWUgPC0gZ3N1YigiUHJvdG90eXBlX1N0YXJnbGl0dGVyIiwgIlN0YXJnbGl0dGVyIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaGVuaGUkcG9sZWFybV9uYW1lKQ0Kc2hlbmhlJHBvbGVhcm1fbmFtZSA8LSBnc3ViKCJFbmd1bGZpbmdfTGlnaHRuaW5nIiwgIkVuZ3VsZmluZyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hlbmhlJHBvbGVhcm1fbmFtZSkNCnNoZW5oZSRwb2xlYXJtX25hbWUgPC0gZ3N1YigiVm9ydGV4X1ZhbnF1aXNoZXIiLCAiVm9ydGV4IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaGVuaGUkcG9sZWFybV9uYW1lKQ0Kc2hlbmhlJHBvbGVhcm1fbmFtZSA8LSBnc3ViKCJNaXNzaXZlX1dpbmRzcGVhciIsICJXaW5kc3BlYXIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoZW5oZSRwb2xlYXJtX25hbWUpDQpzaGVuaGUkcG9sZWFybV9uYW1lIDwtIGdzdWIoIldhdmVicmVha2Vyc19GaW4iLCAiV2F2ZWJyZWFrZXIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoZW5oZSRwb2xlYXJtX25hbWUpDQpzaGVuaGUkcG9sZWFybV9uYW1lIDwtIGdzdWIoIkJsYWNrY2xpZmZfUG9sZSIsICJCbGFja2NsaWZmIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaGVuaGUkcG9sZWFybV9uYW1lKQ0Kc2hlbmhlJHBvbGVhcm1fbmFtZSA8LSBnc3ViKCJTa3l3YXJkX1NwaW5lIiwgIlNreXdhcmQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoZW5oZSRwb2xlYXJtX25hbWUpDQpzaGVuaGUkcG9sZWFybV9uYW1lIDwtIGdzdWIoIkNhbGFtaXR5X1F1ZWxsZXIiLCAiQ2FsYW1pdHkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoZW5oZSRwb2xlYXJtX25hbWUpDQpzaGVuaGUkcG9sZWFybV9uYW1lIDwtIGdzdWIoIkZhdm9uaXVzX0xhbmNlIiwgIkZhdm9uaXVzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaGVuaGUkcG9sZWFybV9uYW1lKQ0KDQojKiBSZW1vdmUgYW55IGJ1aWxkcyBjYXRlZ29yaXplZCBhcyAiaW5jb21wbGV0ZSIuIFRoZSBvbmUgcmVtYWluaW5nIG9ic2VydmF0aW9uIA0KIyogd2hpY2ggd2FzICJpbmNvbXBsZXRlIiBhZnRlciB0aGVzZSBmaWx0ZXJpbmcgY3JpdGVyaWEgd2FzIGVxdWlwcGVkIHdpdGggYSANCiMqIGdlbyBkYW1hZ2UgYm9udXMgZ29ibGV0LCB3aGljaCBTaGVuaGUgY2Fubm90IHV0aWxpemUsIGFuZCBwcm92aWRlcw0KIyogc3VmZmljaWVudCBldmlkZW5jZSB0aGF0IHRoaXMgdXNlciBzaW1wbHkgaGFkIG5vdCBmaW5pc2hlZCBidWlsZGluZyB0aGVpcg0KIyogU2hlbmhlLiBPbmx5IG9uZSBvYnNlcnZhdGlvbiBoYXMgc2hpZWxkX3N0cmVuZ3RoLCBhbmQgaXQgaXMgZHVlIHRvIHRoZWlyDQojKiBlcXVpcHBlZCBwb2xlYXJtICJ2b3J0ZXhfdmFucXVpc2hlciIsIGFuZCBzaW5jZSB0aGUgdmFyaWFibGUgc2hpZWxkX3N0cmVuZ3RoDQojKiBpcyB1bnVzZWZ1bCBpbiB0aGUgYW5hbHlzaXMsIGl0IGNhbiBiZSByZW1vdmVkLiBUaGUgb2JzZXJ2YXRpb24gd2hpY2ggdXNlZA0KIyogInZvcnRleF92YW5xdWlzaGVyIiBpcyBzdGlsbCwgaG93ZXZlciwgY29tcGxldGVseSB2YWxpZCBhbmQgc2hvdWxkIGJlDQojKiBpbmNsdWRlZCBpbiB0aGUgZGF0YXNldC4gVGhlIGFydGlmYWN0IGxldmVsIGFuZCB3ZWFwb24gbGV2ZWwgdmFyaWFibGVzIHdlcmUgDQojKiBzaW1wbHkgYSBtZWFucyB0b3dhcmRzIGZpbHRlcmluZyB0aGUgZGF0YSwgYW5kIHRoZXJlZm9yZSBjYW4gYmUgcmVtb3ZlZCBmcm9tDQojKiB0aGUgZGF0YXNldC4NCg0Kc2hlbmhlIDwtIHNoZW5oZSAlPiUNCiAgZmlsdGVyKGJ1aWxkX3R5cGUgIT0gImluY29tcGxldGUiKQ0KDQpzaGVuaGUgPC0gc2hlbmhlICU+JQ0KICBzZWxlY3QoLWdlb19kbWcsIC1zaGllbGRfc3RyZW5ndGgsIC1mbG93ZXJfbHZsLCAtZmVhdGhlcl9sdmwsIC1zYW5kc19sdmwsDQogICAgICAgICAtZ29ibGV0X2x2bCwgLWNpcmNsZXRfbHZsLCAtcG9sZWFybV9sdmwpDQoNCiMqIEFmdGVyIGFsbCB0aGUgZmlsdGVyaW5nLCAxMDAvMjQ5IG9ic2VydmF0aW9ucyBvZiBTaGVuaGVzIG9uIGRpc3BsYXkgZGlkIG5vdA0KIyogbWVldCBteSBjcml0ZXJpYSBvZiBiZWluZyAiZnVsbHkgYnVpbHQiLCBhbmQgd2VyZSByZW1vdmVkLg0KDQpgYGANCg0KDQoNCiMjIyBQbG90dGluZyB0aGUgRGF0YQ0KDQpUaGUgZm9sbG93aW5nIGlzIGEgYmFyIGdyYXBoIG9mIHRoZSBwb2xlYXJtcyB0aGVzZSBwbGF5ZXJzIGhhZCBlcXVpcHBlZC4gVGhlIG1vc3QNCnBvcHVsYXIgY2hvaWNlcyB3ZXJlOiAgDQogIDEpIENhbGFtaXR5IFF1ZWxsZXIgIA0KICAyKSBGYXZvbml1cyBMYW5jZSAgDQogIDMpIFNreXdhcmQgU3BpbmUgIA0KICA0KSBNaXNzaXZlIFdpbmRzcGVhciAgDQogIDUpIFdhdmVicmVha2VyJ3MgRmluICh0aWUpICANCiAgNSkgUHJpbW9yZGlhbCBKYWRlIFdpbmdlZCBTcGVhciAodGllKSAgDQoNCmBgYHtyIGNvZGUtY2h1bmstcG9sZWFybV9uYW1lX2Jhcl9jaGFydH0NCg0KcG9sZWFybXNfYmFyY2hhcnQgPC0gc2hlbmhlICU+JQ0KICBnZ3Bsb3QoKSArDQogIGdlb21fYmFyKGFlcyh4ID0gcG9sZWFybV9uYW1lKSkgKw0KICBjb29yZF9mbGlwKCkNCg0KcG9sZWFybXNfYmFyY2hhcnQNCmBgYA0KDQoNCg0KVGhlIGZvbGxvd2luZyBpcyBhIGJhciBncmFwaCBvZiB0aGUgc2V0IGJvbnVzZXMgdGhlc2UgcGxheWVycyBoYWQuIFRoZSBtb3N0DQpjb21tb24gc2V0IGJ5IGZhciB3YXMgYSBkb3VibGUgYXRrIHNldCBib251cyAoc3VjaCBhcyAyIGdsYWRpYXRvciBhbmQgMiBzaGltZW5hd2EpLg0KVGhlIG5leHQgbW9zdCBwb3B1bGFyIGNob2ljZSB3YXMgYSBmdWxsIG5vYmxlc3NlIG9ibGlnZSBzZXQsIHdoaWNoIGlzIHRoZSBLUU0NCnJlY29tbWVuZGF0aW9uLg0KDQpgYGB7ciBjb2RlLWNodW5rLXNldF9ib251c19iYXJfY2hhcnR9DQpzZXRib251c19iYXJjaGFydCA8LSBzaGVuaGUgJT4lDQogIGdncGxvdCgpICsNCiAgZ2VvbV9iYXIoYWVzKHggPSBzZXRfYm9udXMpKSArDQogIGNvb3JkX2ZsaXAoKQ0KDQpzZXRib251c19iYXJjaGFydA0KYGBgDQoNCg0KVGhlIGZvbGxvd2luZyBpcyBhIGJhciBncmFwaCBvZiB0aGUgYnVpbGQgdHlwZXMgb2YgdGhlIFNoZW5oZXMgd2hpY2ggbWV0DQp0aGUgaW5jbHVzaW9uIGNyaXRlcmlhLiBUaGUgdHdvIG1vc3QgY29tbW9uIGJ1aWxkcyB3ZXJlLCBpbiBmaXJzdCwgZnVsbCBJY3kgUXVpbGwNCmRhbWFnZSBidWlsZHMsIGFuZCBzZWNvbmQgYnVmZmluZyBhbmQgdXRpbGl0eSBidWlsZHMuDQoNCmBgYHtyIGNvZGUtY2h1bmstYnVpbGRfdHlwZV9iYXJfY2hhcnR9DQpidWlsZHR5cGVfYmFyY2hhcnQgPC0gc2hlbmhlICU+JQ0KICBnZ3Bsb3QoKSArDQogIGdlb21fYmFyKGFlcyh4ID0gYnVpbGRfdHlwZSkpICsNCiAgY29vcmRfZmxpcCgpDQoNCmJ1aWxkdHlwZV9iYXJjaGFydA0KDQoNCmBgYA0KDQoNCg0KDQpUaGUgZm9sbG93aW5nIGFyZSBoaXN0b2dyYW1zIG9mIGFsbCB0aGUgaW1wb3J0YW50IHF1YW50aXRhdGl2ZSB2YXJpYWJsZXMgaW4gdGhlIA0KZGF0YXNldC4gIA0KDQogIDEpIEFkdmVudHVyZSBSYW5rIGlzIGhpZ2hseSBza2V3ZWQgbGVmdC4gVGhpcyBtYWtlcyBzZW5zZSBiZWNhdXNlIHRoZSBleGNsdXNpb24NCiAgICAgIGNyaXRlcmlhIG1hZGUgaXQgZGlmZmljdWx0IGZvciBsb3ctZXhwZXJpZW5jZSBwbGF5ZXJzIHRvIGdldCB0aHJvdWdoLiAgDQogIDIpIENoYXJhY3RlciBsZXZlbCBoYXMgbG9jYWwgbWF4aW1hIGF0IGx2bCA5MCBhbmQgbHZsIDgwLiBUaGUgZGlzdHJpYnV0aW9uDQogICAgICBjb3VsZCBiZSBkZXNjcmliZWQgYXMgc2tld2VkIGxlZnQuICANCiAgMykgSFAgYXBwZWFycyByZWxhdGl2ZWx5IGJlbGwgc2hhcGVkIGV4Y2VwdCBmb3IgYSBwZWFrIGJldHdlZW4gMjNrIGFuZCAyNGsuICANCiAgICAgIFRoZSBTaGFwaXJvLVdpbGtzIHRlc3QgY29uY2x1ZGVzIHRoYXQgdGhlcmUgaXMgc3Ryb25nIGV2aWRlbmNlIHRoYXQNCiAgICAgIEhQIGlzIG5vdCBub3JtYWxseSBkaXN0cmlidXRlZC4gIA0KICA0KSBhdGsgYXBwZWFycyBxdWl0ZSBiZWxsIHNoYXBlZCwgYW5kIHRoZSBTaGFwaXJvLVdpbGtzIHRlc3QgcHJvdmlkZXMgbm8NCiAgICAgIGV2aWRlbmNlIG9mIG5vbi1ub3JtYWxpdHkuICANCiAgNSkgZGVmIGlzIHNrZXdlZCByaWdodCwgYW5kIHRoZSBTaGFwaXJvLVdpbGtzIHRlc3QgY29uY2x1ZGVzIHRoYXQgdGhlcmUgaXMNCiAgICAgIHN0cm9uZyBldmlkZW5jZSB0aGF0IGRlZiBpcyBub3Qgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuICANCiAgNikgRU0gaXMgaGlnaGx5IHNrZXdlZCByaWdodCwgYW5kIHRoZSBTaGFwaXJvLVdpbGtzIHRlc3QgY29uY2x1ZGVzIHRoYXQgdGhlcmUNCiAgICAgIGlzIHN0cm9uZyBldmlkZW5jZSB0aGF0IEVNIGlzIG5vdCBub3JtYWxseSBkaXN0cmlidXRlZC4gIA0KICA3KSBjcml0IHJhdGUgYW5kIGNyaXQgZG1nIGFwcGVhciBmYWlybHkgYmVsbCBzaGFwZWQgd2l0aCBzbGlnaHQgcmlnaHQgc2tld2luZy4NCiAgICAgIFRoZSBTaGFwaXJvLVdpbGtzIHRlc3QgcHJvdmlkZXMgd2VhayBldmlkZW5jZSB0aGF0IGNyaXQgcmF0ZSBpcyBub3QNCiAgICAgIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLCBhbmQgc3Ryb25nIGV2aWRlbmNlIHRoYXQgY3JpdCBkbWcgaXMgbm90IG5vcm1hbGx5DQogICAgICBkaXN0cmlidXRlZC4gIA0KICA4KSBFUiBpcyBza2V3ZWQgcmlnaHQsIGFuZCB0aGUgU2hhcGlyby1XaWxrcyB0ZXN0IGNvbmNsdWRlcyB0aGF0IHRoZXJlIGlzDQogICAgICBzdHJvbmcgZXZpZGVuY2UgdGhhdCBFUiBpcyBub3Qgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuICANCiAgOSkgY3J5byBhbmQgcGh5cyBkbWcgYXJlIGJvdGggZXh0cmVtZWx5IHNrZXdlZCByaWdodCwgYW5kIG1vc3RseSB6ZXJvLg0KICAgICAgVGhpcyBtYWtlcyBzZW5zZSBiZWNhdXNlIG5vdCBtYW55IHBlb3BsZSBjaG9vc2UgdG8gcGxheSBTaGVuaGUNCiAgICAgIGFzIGFuIG9uIGZpZWxkIERQUyBvciBoeXBlcmNhcnJ5LiAgDQogIDEwKSByZWZpbmVtZW50IGhhcyB0d28gbG9jYWwgbWF4aW1hIGF0IDEgYW5kIDUuIFRoaXMgbWFrZXMgc2Vuc2UgYmVjYXVzZQ0KICAgICAgQ2FsYW1pdHkgUXVlbGxlciBhbmQgRmF2b25pdXMgbGFuY2Ugd2VyZSB0aGUgbW9zdCBjb21tb24gcG9sZWFybQ0KICAgICAgY2hvaWNlcywgdGhlIGZvcm1lciBiZWluZyBleHRyZW1lbHkgaGFyZCB0byBvYnRhaW4gKGxlYWRpbmcgdG8gbW9yZSByMSksDQogICAgICBhbmQgdGhlIGxhdHRlciBiZWluZyBtdWNoIGVhc2llciB0byBvYnRhaW4gKGxlYWRpbmcgdG8gbW9yZSByNSkuICANCiAgMTEpIGNvbnN0ZWxsYXRpb24gaXMgZXh0cmVtZWx5IHNrZXdlZCByaWdodCwgd2hpY2ggbWFrZXMgc2Vuc2UgYmVjYXVzZSBtb3N0DQogICAgICBwZW9wbGUgZG8gbm90IGFjcXVpcmUgbW9yZSB0aGFuIGEgc2luZ2xlIGNvcHkgb2YgYSBsaW1pdGVkIGNoYXJhY3Rlcg0KICAgICAgbGlrZSBTaGVuaGUuICANCiAgMTIpIFRoZSB0YWxlbnQgbGV2ZWwgaGlzdG9ncmFtcyB3ZXJlIHN0cmFuZ2UsIGJlY2F1c2UgdGhlIHZhcmlhYmxlcyBhcmUgZGlzY3JldGUNCiAgICAgIGFuZCB0eXBpY2FsbHkgYmV0d2VlbiAxLTEwLCBidXQgY2FuIGJlIGluY3JlYXNlZCBieSBjb25zdGVsbGF0aW9ucy4gVGhlDQogICAgICBkaXN0cmlidXRpb25zIGNvdWxkIGNlcnRhaW5seSBiZSBzcGxpdCBieSBidWlsZCB0eXBlLCBhbmQgbWF5IHRoZW4gYXBwZWFyDQogICAgICBtb3JlIHVuZGVyc3RhbmRhYmxlLCBob3dldmVyIHRoYXQgY291bGQgYmUgYSBmb2N1cyBvZiBhIGRpZmZlcmVudCBzdHVkeS4gIA0KDQpgYGB7ciBjb2RlLWNodW5rLWhpc3RvZ3JhbXN9DQoNCnBhcihtZnJvdyA9IGMoMiwyKSkNCg0KaGlzdChzaGVuaGUkQVIsIGNvbCA9ICdzdGVlbGJsdWUnKQ0KDQpoaXN0KHNoZW5oZSRjaGFyX2x2bCwgY29sID0gJ3N0ZWVsYmx1ZScpDQoNCmhpc3Qoc2hlbmhlJEhQLCBjb2wgPSAnc3RlZWxibHVlJykNCnByaW50KCJub3JtYWxpdHkgb2YgSFA6IikNCnNoYXBpcm8udGVzdChzaGVuaGUkSFApDQoNCmhpc3Qoc2hlbmhlJGF0aywgY29sID0gJ3N0ZWVsYmx1ZScpDQpwcmludCgibm9ybWFsaXR5IG9mIGF0azoiKQ0Kc2hhcGlyby50ZXN0KHNoZW5oZSRhdGspDQoNCmhpc3Qoc2hlbmhlJGRlZiwgY29sID0gJ3N0ZWVsYmx1ZScpDQpwcmludCgibm9ybWFsaXR5IG9mIGRlZjoiKQ0Kc2hhcGlyby50ZXN0KHNoZW5oZSRkZWYpDQoNCmhpc3Qoc2hlbmhlJEVNLCBjb2wgPSAnc3RlZWxibHVlJykNCnByaW50KCJub3JtYWxpdHkgb2YgRU06IikNCnNoYXBpcm8udGVzdChzaGVuaGUkRU0pDQoNCmhpc3Qoc2hlbmhlJGNyaXRfcmF0ZSwgY29sID0gJ3N0ZWVsYmx1ZScpDQpwcmludCgibm9ybWFsaXR5IG9mIGNyaXRfcmF0ZToiKQ0Kc2hhcGlyby50ZXN0KHNoZW5oZSRjcml0X3JhdGUpDQoNCmhpc3Qoc2hlbmhlJGNyaXRfZG1nLCBjb2wgPSAnc3RlZWxibHVlJykNCnByaW50KCJub3JtYWxpdHkgb2YgY3JpdF9kbWc6IikNCnNoYXBpcm8udGVzdChzaGVuaGUkY3JpdF9kbWcpDQoNCmhpc3Qoc2hlbmhlJEVSLCBjb2wgPSAnc3RlZWxibHVlJykNCnByaW50KCJub3JtYWxpdHkgb2YgRVI6IikNCnNoYXBpcm8udGVzdChzaGVuaGUkRVIpDQoNCmhpc3Qoc2hlbmhlJGNyeW9fZG1nLCBjb2wgPSAnc3RlZWxibHVlJykNCg0KaGlzdChzaGVuaGUkcGh5c19kbWcsIGNvbCA9ICdzdGVlbGJsdWUnKQ0KDQpoaXN0KHNoZW5oZSRyZWZpbmVtZW50LCBjb2wgPSAnc3RlZWxibHVlJykNCg0KaGlzdChzaGVuaGUkY29uc3RlbGxhdGlvbiwgY29sID0gJ3N0ZWVsYmx1ZScpDQoNCmhpc3Qoc2hlbmhlJE5BX3RhbGVudF9sdmwsIGNvbCA9ICdzdGVlbGJsdWUnKQ0KDQpoaXN0KHNoZW5oZSRFX3RhbGVudF9sdmwsIGNvbCA9ICdzdGVlbGJsdWUnKQ0KDQpoaXN0KHNoZW5oZSRRX3RhbGVudF9sdmwsIGNvbCA9ICdzdGVlbGJsdWUnKQ0KcHJpbnQoIm5vcm1hbGl0eSBvZiBRX3RhbGVudF9sdmw6IikNCnNoYXBpcm8udGVzdChzaGVuaGUkUV90YWxlbnRfbHZsKQ0KDQpwYXIobWZyb3cgPSBjKDEsMSkpDQoNCmBgYA0KDQoNCg0KIyMjIHQgQ29uZmlkZW5jZSBJbnRlcnZhbHMNCg0KICBCZWNhdXNlIG11Y2ggb2YgdGhlIGRhdGEgaXMgbm9uLXBhcmFtZXRyaWMsIHRoZSBvbmx5IHZhcmlhYmxlcyB3aGljaCBJIHdpc2ggdG8NCmRlc2NyaWJlIGluIHRlcm1zIG9mIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGFyZSBhdGssIEVSLCBhbmQgRVJfcmVxX21ldC4gVGhlDQpmb2xsb3dpbmcgYXJlIHRoZSBpbnRlcnByZXRhdGlvbnMgb2YgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIG9mIGVhY2ggb2YgdGhvc2U6ICANCg0KICAxKSBXZSBjYW4gYmUgOTUlIGNvbmZpZGVudCB0aGF0IHRoZSBwb3B1bGF0aW9uIG1lYW4gYXRrIG9mIFNoZW5oZXMgb24gZGlzcGxheQ0KICAgIGlzIGJldHdlZW4gMzEyOS45MjIgYW5kIDMzMDEuNzE2LiAgDQogIA0KICAyKSBXZSBjYW4gYmUgOTUlIGNvbmZpZGVudCB0aGF0IHRoZSBwb3B1bGF0aW9uIG1lYW4gRVIgb2YgU2hlbmhlcyBvbiBkaXNwbGF5DQogICAgaXMgYmV0d2VlbiAxNDYuOTY2IGFuZCAxNTYuNTMzLiAgDQogIA0KICAzKSBXZSBjYW4gYmUgOTUlIGNvbmZpZGVudCB0aGF0IHRoZSBwb3B1bGF0aW9uIHByb3BvcnRpb24gb2YgU2hlbmhlcyBvbiBkaXNwbGF5DQogICAgd2hpY2ggbWVldCBzdGFuZGFyZCBFUiByZXF1aXJlbWVudHMgaXMgYmV0d2VlbiAwLjE3OCBhbmQgMC4zMTkuICANCg0KYGBge3IgY29kZS1jaHVuay1jb25mX2ludH0NCmNvbmYuaW50IDwtIGZ1bmN0aW9uKHF1YW50dmFyLCBuLCBjb25mLmxldmVsID0gMC45NSl7DQogIHBvaW50X2VzdGltYXRlIDwtIG1lYW4ocXVhbnR2YXIpDQogIE1vRSA8LSBxdCggMSAtICgxIC0gY29uZi5sZXZlbCkvMiAsIGRmID0gKG4gLSAxKSkgKiAoIHNkKHF1YW50dmFyKS9zcXJ0KG4pICkNCiAgDQogIGNvbmZpZGVuY2VfaW50ZXJ2YWwgPC0gcG9pbnRfZXN0aW1hdGUgKyBjKC1Nb0UsIE1vRSkNCiAgDQogIHJldHVybihjb25maWRlbmNlX2ludGVydmFsKQ0KfQ0KDQpjb25mLmludChzaGVuaGUkYXRrLCBuID0gMTQ5KQ0KY29uZi5pbnQoc2hlbmhlJEVSLCBuID0gMTQ5KQ0KY29uZi5pbnQoc2hlbmhlJEVSX3JlcV9tZXQsIG4gPSAxNDkpDQpgYGANCg0KDQojIyMgU3VtbWFyeSBvZiBSZWZlcmVuY2UgR3JvdXBzDQoNCiAgQmVjYXVzZSB3ZSB3aWxsIHVzZSBOb2JsZXNzZSBPYmxpZ2UgYW5kIEZhdm9uaXVzIExhbmNlIGFzIHJlZmVyZW5jZSBmcmFtZXMNCmZvciBhbGwgb3RoZXIgZ2VhciBjaG9pY2VzLCBpdCBpcyBpbXBvcnRhbnQgdG8gdW5kZXJzdGFuZCB0aGVpciBpbmRpdmlkdWFsDQpzdGF0aXN0aWNzLiAgDQoNCiAgVGhlIGZvbGxvd2luZyBhcmUgdGhlIGludGVycHJldGF0aW9ucyBvZiB0aGUgY29uc3RydWN0ZWQgY29uZmlkZW5jZSBpbnRlcnZhbHM6ICANCiAgDQogIDEpIFdlIGNhbiBiZSA5NSUgY29uZmlkZW50IHRoYXQgdGhlIHBvcHVsYXRpb24gbWVhbiBhdGsgb2YgU2hlbmhlcyBvbiBkaXNwbGF5IA0KICAgIHdpdGggdGhlIDQgcGllY2Ugbm9ibGVzc2Ugc2V0IGlzIGJldHdlZW4gMjU0NC43NDQgYW5kIDI5NDkuODEyLiAgDQogICAgDQogIDIpIFdlIGNhbiBiZSA5NSUgY29uZmlkZW50IHRoYXQgdGhlIHBvcHVsYXRpb24gbWVhbiBFUiBvZiBTaGVuaGVzIG9uIGRpc3BsYXkNCiAgICB3aXRoIHRoZSA0IHBpZWNlIG5vYmxlc3NlIHNldCBpcyBiZXR3ZWVuIDE0OS4zNjggYW5kIDE4MC42MjEuICANCiAgICANCiAgMykgV2UgY2FuIGJlIDk1JSBjb25maWRlbnQgdGhhdCB0aGUgcG9wdWxhdGlvbiBtZWFuIGF0ayBvZiBTaGVuaGVzIG9uIGRpc3BsYXkNCiAgICBlcXVwcGluZyB0aGUgRmF2b25pdXMgTGFuY2UgaXMgYmV0d2VlbiAyNjg1LjgzNiBhbmQgMjk5MC4wMTYuICANCiAgICANCiAgNCkgV2UgY2FuIGJlIDk1JSBjb25maWRlbnQgdGhhdCB0aGUgcG9wdWxhdGlvbiBtZWFuIEVSIG9mIFNoZW5oZXMgb24gZGlzcGxheQ0KICAgIGVxdWlwcGluZyB0aGUgRmF2b25pdXMgTGFuY2UgaXMgYmV0d2VlbiAxNTQuNzc1IGFuZCAxNzMuMDkyLiAgDQoNCmBgYHtyIGNvZGUtY2h1bmstTk9hbmRGYXZMYW5jZX0NCnNoZW5oZV9ub2JsZXNzZSA8LSBzaGVuaGUgJT4lDQogIGZpbHRlcihzZXRfYm9udXMgJWluJSBjKCJmdWxsLW5vYmxlc3NlIikpDQoNCg0KDQpzaGVuaGVfZmF2bGFuY2UgPC0gc2hlbmhlICU+JQ0KICBmaWx0ZXIocG9sZWFybV9uYW1lICVpbiUgYygiRmF2b25pdXMiKSkNCg0KY29uZi5pbnQoc2hlbmhlX25vYmxlc3NlJGF0aywgbnJvdyhzaGVuaGVfbm9ibGVzc2UpKQ0KY29uZi5pbnQoc2hlbmhlX25vYmxlc3NlJEVSLCBucm93KHNoZW5oZV9ub2JsZXNzZSkpDQpjb25mLmludChzaGVuaGVfZmF2bGFuY2UkYXRrLCBucm93KHNoZW5oZV9mYXZsYW5jZSkpDQpjb25mLmludChzaGVuaGVfZmF2bGFuY2UkRVIsIG5yb3coc2hlbmhlX2ZhdmxhbmNlKSkNCg0KIyBmb3IgdXNlIG9ubHkgaW4gdGhlIGNvbmNsdXNpb24NCnNoZW5oZV9hdGtfYXRrIDwtIHNoZW5oZSAlPiUNCiAgZmlsdGVyKHNldF9ib251cyAlaW4lIGMoImF0ay1hdGsiKSkNCnByaW50KCJmb3IgY29uY2x1c2lvbiBvbmx5OiIpDQpjb25mLmludChzaGVuaGVfYXRrX2F0ayRFUiwgbnJvdyhzaGVuaGVfYXRrX2F0aykpDQoNCmBgYA0KDQoNCiMjIyBJbmFkZXF1YWN5IG9mIEFOT1ZBDQoNCkkgZG8gbm90IGJlbGlldmUgdGhhdCBhbmFseXNpcyBvZiB2YXJpYW5jZSBpcyBhcHByb3ByaWF0ZSBmb3IgdGhpcyBkYXRhDQpiZWNhdXNlIHRoZXJlIGlzIHRvbyBsaXR0bGUgaW5mb3JtYXRpb24gb24gdGhlIGRpc3RyaWJ1dGlvbiBvZiBFUiwgaG93ZXZlciwNCnRoaXMgc2VjdGlvbiBpbnRlbmRzIHRvIGRlbW9uc3RyYXRlIGhvdyBvbmUgbWF5IGdvIGFib3V0IHVzaW5nIEFOT1ZBIG9uIHRoZQ0KZGF0YS4gQSBub24tcGFyYW1ldHJpYyBwb3N0LWhvYyB0ZXN0IGNhbiB3b3JrLCBidXQgdWx0aW1hdGVseSBJIHdpc2ggdG8gdXNlIA0KYm9vdHN0cmFwcGluZyB0byBjb21wYXJlIGdyb3VwIG1lYW5zIGZvciB0aGlzIGRhdGFzZXQuICANCg0KVGhlIHJlc2lkdWFscyBvZiB0aGUgbW9kZWwgZG8gbm90IGhhdmUgY29uc3RhbnQgdmFyaWFuY2UsIGFuZCB0aGUgc2NhbGUtbG9jYXRpb24NCnBsb3QgaXMgbm90aWNlYWJseSBjdXJ2ZWQsIHRoZXJlZm9yZSBhbmFseXNpcyBvZiB2YXJpYW5jZSBpcyBub3QgYW4gYXBwcm9wcmlhdGUNCnN0YXRpc3RpY2FsIG1ldGhvZC4gIA0KDQpgYGB7ciBjb2RlLWNodW5rLWFvdn0NCmhpc3Qoc2hlbmhlJEVSKQ0Kc2hhcGlyby50ZXN0KHNoZW5oZSRFUikNCg0KIyogYmVjYXVzZSB0aGUgZGlzdHJpYnV0aW9uIG9mIFNoZW5oZSdzIGVuZXJneSByZWNoYXJnZSBpcyBldmlkZW50bHkgbm9uLW5vcm1hbCwgDQojKiBpZiB3ZSB3aXNoIHRvIGRvIGFuYWx5c2lzIG9mIHZhcmlhbmNlLCB3ZSBtdXN0IHRyYW5zZm9ybSB0aGUgZGF0YSBiZWNhdXNlIA0KIyogdGhlcmUgYXJlIHN1Ymdyb3VwcyBpbiB0aGUgZGF0YSB3aXRoIHRvbyBmZXcgb2JzZXJ2YXRpb25zIHRvIHNhdGlzZnkgdGhlIA0KIyogY2VudHJhbCBsaW1pdCB0aGVvcmVtIChlLmcuIHNhbXBsZSBzaXplIG9mIGVuZ3VsZmluZyBsaWdodG5pbmcgdXNlcnMgPSAzKS4NCg0KRVJfdHJhbnNmb3JtZWQgPC0gbG9nKHNoZW5oZSRFUikNCmhpc3QoRVJfdHJhbnNmb3JtZWQpDQpzaGFwaXJvLnRlc3QoRVJfdHJhbnNmb3JtZWQpDQoNCkVSX2Fub3ZhIDwtIGFvdihFUl90cmFuc2Zvcm1lZCB+IHBvbGVhcm1fbmFtZSwgZGF0YSA9IHNoZW5oZSkNCnN1bW1hcnkoRVJfYW5vdmEpDQpwbG90KEVSX2Fub3ZhKQ0KDQojIEZvciBwb3N0LWhvYyB0ZXN0aW5nIHlvdSBjYW4gdXNlIFR1a2V5SFNEKEVSX2Fub3ZhKQ0KYGBgDQoNCg0KDQojIyMgSHlwb3RoZXNpcyBUZXN0aW5nDQoNCiAgVGhlIHZhcmlhYmxlcyBvZiBpbnRlcmVzdCBmb3IgaHlwb3RoZXNpcyB0ZXN0aW5nIGFyZTogIA0KICANCiAgICAxKSBhdGsgIA0KICAgIA0KICAgIDIpIEVSICANCiAgICANCiAgICAzKSBwb2xlYXJtIG5hbWUgIA0KICAgIA0KICAgIDQpIHNldCBib251cyAgDQoNCiAgTW9yZSBzcGVjaWZpY2FsbHksIHdlIGFyZSBpbnRlcmVzdGVkIGluIGhvdyBnZWFyIChmYWN0b3JzIHdoaWNoIHRoZSBwbGF5ZXIgaGFzDQpkaXJlY3QgY29udHJvbCBvdmVyIHN1Y2ggYXMgcG9sZWFybSBhbmQgc2V0IGJvbnVzKSBpbXBhY3QgYXRrIGFuZCBFUi4gVGhlDQoiYnVpbGQgdHlwZSIgdmFyaWFibGUgaXMgbm90IG9mIGludGVyZXN0LCBhcyBpdCB3YXMgY29uc3RydWN0ZWQgdXNpbmcgb3RoZXINCmRhdGEgc3VjaCBhcyBwb2xlYXJtIGFuZCBzZXQgYm9udXMsIGFuZCB0aHVzIG11c3QgYmUgY29sbGluZWFyLiAgDQoNCiAgVGhlIGZvbGxvd2luZyBhcmUgaHlwb3RoZXNlcyBmb3IgZWFjaCBjYXRlZ29yaWNhbC1xdWFudGl0YXRpdmUgcmVsYXRpb25zaGlwOiAgDQoNCkVSIHZzLiBQb2xlYXJtOiAgDQpIMDogVGhlcmUgaXMgbm8gZGlmZmVyZW5jZSBpbiBtZWFuIEVSIGJldHdlZW4gYW55IHBvbGVhcm0gdHlwZS4gIA0KSGE6IFRoZXJlIGlzIGEgZGlmZmVyZW5jZSBpbiBtZWFuIEVSIGZvciBhdCBsZWFzdCBvbmUgcG9sZWFybSB0eXBlLiAgDQoNCkVSIHZzLiBTZXQgQm9udXM6ICANCkgwOiBUaGVyZSBpcyBubyBkaWZmZXJlbmNlIGluIG1lYW4gRVIgYmV0d2VlbiBhbnkgc2V0IGJvbnVzZXMuICANCkhhOiBUaGVyZSBpcyBhIGRpZmZlcmVuY2UgaW4gbWVhbiBFUiBmb3IgYXQgbGVhc3Qgb25lIHNldCBib251cy4gIA0KDQphdGsgdnMuIFBvbGVhcm06DQpIMDogVGhlcmUgaXMgbm8gZGlmZmVyZW5jZSBpbiBtZWFuIGF0ayBiZXR3ZWVuIGFueSBwb2xlYXJtIHR5cGUuICANCkhhOiBUaGVyZSBpcyBhIGRpZmZlcmVuY2UgaW4gbWVhbiBhdGsgZm9yIGF0IGxlYXN0IG9uZSBwb2xlYXJtIHR5cGUuICANCg0KYXRrIHZzLiBTZXQgQm9udXM6ICANCkgwOiBUaGVyZSBpcyBubyBkaWZmZXJlbmNlIGluIG1lYW4gYXRrIGJldHdlZW4gYW55IHNldCBib251c2VzLiAgDQpIYTogVGhlcmUgaXMgYSBkaWZmZXJlbmNlIGluIG1lYW4gYXRrIGZvciBhdCBsZWFzdCBvbmUgc2V0IGJvbnVzLiAgDQoNCiAgVGhlIEtydXNrYWwtV2FsbGlzIHRlc3QgaXMgYSBub24tcGFyYW1ldHJpYyBhbHRlcm5hdGl2ZSB0byBBTk9WQSB3aGljaA0Kd2Ugd2lsbCB1c2UgdG8gYXNzZXNzIHRoZXNlIGh5cG90aGVzZXMuIFRoZSBjb3JyZXNwb25kaW5nIG5vbi1wYXJhbWV0cmljIHBvc3QtaG9jIA0KdGVzdCB0byB0aGUgS3J1c2thbC1XYWxsaXMgdGVzdCB3aGljaCB3ZSBmb3VuZCB3YXMgdGhlIER1bm4gVGVzdCwgaG93ZXZlciB3ZSB3aWxsIA0Kbm90IHVzZSB0aGlzIHRlc3QgdG8gY29tcGxldGUgdGhlIGluZGl2aWR1YWwgcGFpcndpc2UgY29tcGFyaXNvbnMuIEJlY2F1c2UgdGhlDQp0ZXN0IGlzIG5vbi1wYXJhbWV0cmljLCB0aGUgaHlwb3RoZXNlcyBtdXN0IGJlIG1vZGlmaWVkIHRvIHJlZmxlY3QgYSBzaGlmdCBpbg0KZGlzdHJpYnV0aW9ucyByYXRoZXIgdGhhbiBhIGRpZmZlcmVuY2UgaW4gbWVhbnMuIFRoZSBtZWFuIGRpZmZlcmVuY2UgaHlwb3RoZXNlcw0KbWF5IHN0aWxsIGFwcGx5IHRvIHRoZSBpbmRpdmlkdWFsIHBhaXJ3aXNlIGNvbXBhcmlzb25zLiAgDQoNCkF0IGEgc2lnbmlmaWNhbmNlIGxldmVsIG9mIGFscGhhID0gMC4wNSwgdGhlIEtydXNrYWwtV2FsbGlzIHJldHVybnMgdGhlIGZvbGxvd2luZzogIA0KICAxKSBUaGVyZSBpcyB2ZXJ5IHN0cm9uZyBldmlkZW5jZSB0byBzdWdnZXN0IHRoYXQgYXQgbGVhc3Qgb25lIG9mIHRoZQ0KICAgICAgcG9sZWFybSB0eXBlcyBoYXMgYSBkaWZmZXJpbmcgZGlzdHJpYnV0aW9uIG9mIEVSLiBUaGlzIHJlc3VsdCANCiAgICAgIGFkZGl0aW9uYWxseSB3YXJyYW50cyBwb3N0LWhvYyB0ZXN0aW5nLg0KICAyKSBUaGVyZSBpcyBubyBldmlkZW5jZSB0byBzdWdnZXN0IHRoYXQgYXQgYW55IG9mIHRoZQ0KICAgICAgc2V0IGJvbnVzZXMgaGFzIGEgZGlmZmVyaW5nIGRpc3RyaWJ1dGlvbiBvZiBFUi4NCiAgICAgIFRoaXMgcmVzdWx0IGRvZXMgbm90IHdhcnJhbnQgcG9zdC1ob2MgdGVzdGluZy4gIA0KICAzKSBUaGVyZSBpcyB2ZXJ5IHN0cm9uZyBldmlkZW5jZSB0byBzdWdnZXN0IHRoYXQgYXQgbGVhc3Qgb25lIG9mIHRoZQ0KICAgICAgcG9sZWFybSB0eXBlcyBoYXMgYSBkaWZmZXJpbmcgZGlzdHJpYnV0aW9uIG9mIGF0ay4gVGhpcyByZXN1bHQgDQogICAgICBhZGRpdGlvbmFsbHkgd2FycmFudHMgcG9zdC1ob2MgdGVzdGluZy4gIA0KICA0KSBUaGVyZSBpcyB2ZXJ5IHN0cm9uZyBldmlkZW5jZSB0byBzdWdnZXN0IHRoYXQgYXQgbGVhc3Qgb25lIG9mIHRoZQ0KICAgICAgc2V0IGJvbnVzZXMgaGFzIGEgZGlmZmVyaW5nIGRpc3RyaWJ1dGlvbiBvZiBhdGsuIFRoaXMgcmVzdWx0DQogICAgICBhZGRpdGlvbmFsbHkgd2FycmFudHMgcG9zdC1ob2MgdGVzdGluZy4NCiAgICAgIA0KDQpgYGB7ciBjb2RlLWNodW5rLWtydXNrYWxfdGVzdGluZ30NCg0KIyBCZWNhdXNlIHRoZXJlIGFyZSBjYXRlZ29yaWVzIHdpdGggbGVzcyB0aGFuIDUgb2JzZXJ2YXRpb25zLCBhIG5vbi1wYXJhbWV0cmljDQojIHRlc3QgaXMgYSBwcmVmZXJhYmxlIG1ldGhvZC4NCg0Ka3J1c2thbC50ZXN0KEVSIH4gcG9sZWFybV9uYW1lLCBkYXRhID0gc2hlbmhlKQ0Ka3J1c2thbC50ZXN0KEVSIH4gc2V0X2JvbnVzLCBkYXRhID0gc2hlbmhlKQ0Ka3J1c2thbC50ZXN0KGF0ayB+IHBvbGVhcm1fbmFtZSwgZGF0YSA9IHNoZW5oZSkNCmtydXNrYWwudGVzdChhdGsgfiBzZXRfYm9udXMsIGRhdGEgPSBzaGVuaGUpDQoNCiMqIG9uZSBvZiB0aGUgb3B0aW9ucyBmb3IgcG9zdC1ob2MgdGVzdGluZyBpcyB0aGUgZHVublRlc3QgdW5kZXIgdGhlIHBhY2thZ2UNCiMqICJGU0EiLCBidXQgYXMgSSBzYWlkIGVhcmxpZXIsIEkgd2lzaCB0byBkbyBib290c3RyYXBwaW5nLiBUaGUgc3ludGF4IGZvcg0KIyogdGhlIGR1bm5UZXN0IGlzIGFzIGZvbGxvd3M6DQojKiBkdW5uVGVzdChFUiB+IHBvbGVhcm1fbmFtZSwgZGF0YSA9IHNoZW5oZSkNCiMqIGV0Yy4NCg0KYGBgDQoNCg0KDQogIFRoZSBmb2xsb3dpbmcgY29kZSBpcyBhIHJhbmRvbWl6YXRpb24gdGVzdCB3aGljaCBzY2FucyB0aHJvdWdoIGFsbCBwYWlyd2lzZQ0KY29tYmluYXRpb25zIG9mIGEgY2F0ZWdvcmljYWwgdmFyaWFibGUgInRyZWF0bWVudCIsIGFuZCBib290c3RyYXBzIHRvIGFzc2Vzcw0Kd2hldGhlciB0aGVyZSBpcyBhIGRpZmZlcmVuY2UgaW4gbWVhbnMuIFRoaXMgaXMgYSBtdWNoIHByZWZlcnJhYmxlIG9wdGlvbg0KdG8gdGhlIHQtdGVzdCwgYmVjYXVzZSB0aGUgc21hbGwgc2FtcGxlIHNpemVzIChiZXR3ZWVuIDEgYW5kIDEwKSBhcmUgaW5zdWZmaWNpZW50DQp0byBhY2NvdW50IGZvciB0aGUgaGlnaGx5IHNrZXdlZCBuYXR1cmUgb2YgdGhlIGRpc3RyaWJ1dGlvbiBvZiBFUi4gVW5mb3J0dW5hdGVseSwNCmJlY2F1c2UgdGhlcmUgaXMgdmVyeSBsaXR0bGUgaW5mb3JtYXRpb24gb24gdGhlIGRpc3RyaWJ1dGlvbiBvZiBFUiwgaXQgaXMgbm90DQpzaW1wbGUgdG8gY3JlYXRlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGZvciB0aGUgZGlmZmVyZW5jZSBpbiBtZWFucy4gUG9pbnQNCmVzdGltYXRlcyBvZiB0aGUgcG9wdWxhdGlvbiBlZmZlY3Qgc2l6ZSBhbmQgcG9wdWxhdGlvbiBtZWFuIGRpZmZlcmVuY2Ugd2lsbA0Kc2ltcGx5IG5lZWQgdG8gYmUgaW50ZXJwcmV0ZWQgYWNjb3JkaW5nIHRvIHRoZWlyIGNvcnJlc3BvbmRpbmcgcC12YWx1ZXMuICANCg0KDQpgYGB7ciBjb2RlLWNodW5rLVJQVF9mdW5jdGlvbn0NCmFkaV9zYWlkaS5SUFQgPC0gZnVuY3Rpb24odHJlYXRtZW50LCBvdXRjb21lLCBuID0gMTAwMCwgcGxvdF9kaXN0ID0gIkZBTFNFIikgew0KICB0cmVhdG1lbnRfZmFjdG9yX2xldmVscyA8LSBsZW5ndGgodW5pcXVlKHRyZWF0bWVudCkpDQogIHRmbF9jaG9vc2UyIDwtIHRyZWF0bWVudF9mYWN0b3JfbGV2ZWxzKih0cmVhdG1lbnRfZmFjdG9yX2xldmVscyAtIDEpLzINCiAgdHJlYXRtZW50X2NvbWJucyA8LSBtYXRyaXgoLCBucm93ID0gdGZsX2Nob29zZTIsIG5jb2wgPSAyKQ0KICBpbmQgPC0gMQ0KICANCiAgZm9yIChpIGluIDE6KHRyZWF0bWVudF9mYWN0b3JfbGV2ZWxzLTEpKSB7DQogICAgICBmb3IgKGogaW4gKGkrMSk6KHRyZWF0bWVudF9mYWN0b3JfbGV2ZWxzKSkgew0KICAgICAgICB0cmVhdG1lbnRfY29tYm5zW2luZCwxXSA8LSB1bmlxdWUodHJlYXRtZW50KVtpXQ0KICAgICAgICB0cmVhdG1lbnRfY29tYm5zW2luZCwyXSA8LSB1bmlxdWUodHJlYXRtZW50KVtqXQ0KICAgICAgICBpbmQgPC0gaW5kKzENCiAgICAgIH0NCiAgICB9DQogIA0KICBUT19kYXRhIDwtIGRhdGEuZnJhbWUoDQogICAgICB0cmVhdG1lbnQsDQogICAgICBvdXRjb21lKQ0KICBwX3ZhbHVlIDwtIGMoKQ0KICBlZmZlY3Rfc2l6ZSA8LSBjKCkNCiAgdHJlYXRtZW50XzEgPC0gYygpDQogIHRyZWF0bWVudF8yIDwtIGMoKQ0KICBtZWFuX2RpZmYgPC0gYygpDQogIA0KICBmb3IgKGsgaW4gMToobnJvdyh0cmVhdG1lbnRfY29tYm5zKSkpIHsNCiAgICBkYXRhX2ZpbHRlcmluZyA8LSBUT19kYXRhICU+JQ0KICAgICAgZmlsdGVyKHRyZWF0bWVudCAlaW4lIGModHJlYXRtZW50X2NvbWJuc1trLCAxXSwgdHJlYXRtZW50X2NvbWJuc1trLDJdKSkNCiAgICANCiAgICB0cmVhdG1lbnRfcGFydGljdWxhciA8LSBkYXRhX2ZpbHRlcmluZyR0cmVhdG1lbnQNCiAgICBvdXRjb21lX3BhcnRpY3VsYXIgPC0gZGF0YV9maWx0ZXJpbmckb3V0Y29tZQ0KICAgIA0KICAgIG9yaWdpbmFsIDwtIGRpZmYodGFwcGx5KG91dGNvbWVfcGFydGljdWxhciwgdHJlYXRtZW50X3BhcnRpY3VsYXIsIG1lYW4pKQ0KICAgIG1lYW5fZGlmZl9kaXN0ID0gYygpDQoNCiAgICBmb3IobCBpbiAxOm4pIHsNCiAgICAgIG1lYW5fZGlmZl9kaXN0W2xdID0gZGlmZihieShvdXRjb21lX3BhcnRpY3VsYXIsIHNhbXBsZSh0cmVhdG1lbnRfcGFydGljdWxhciwgbGVuZ3RoKHRyZWF0bWVudF9wYXJ0aWN1bGFyKSwgRkFMU0UpLCBtZWFuKSkNCiAgICAgIH0NCiAgICANCiAgICANCiAgICANCiAgICBncm91cDEgPC0gZGF0YV9maWx0ZXJpbmcgJT4lDQogICAgICBmaWx0ZXIodHJlYXRtZW50ICVpbiUgYyh0cmVhdG1lbnRfY29tYm5zW2ssIDFdKSkNCiAgICBncm91cDIgPC0gZGF0YV9maWx0ZXJpbmcgJT4lDQogICAgICBmaWx0ZXIodHJlYXRtZW50ICVpbiUgYyh0cmVhdG1lbnRfY29tYm5zW2ssIDJdKSkNCiAgICBtZWFuMSA9IG1lYW4oZ3JvdXAxJG91dGNvbWUpDQogICAgbWVhbjIgPSBtZWFuKGdyb3VwMiRvdXRjb21lKQ0KICAgIA0KICAgIHBfdmFsdWVba10gPSBzdW0oYWJzKG1lYW5fZGlmZl9kaXN0KSA+PSBhYnMob3JpZ2luYWwpKS8obikNCiAgICBtZWFuX2RpZmZba10gPSBtZWFuMiAtIG1lYW4xDQogICAgZWZmZWN0X3NpemVba10gPSAobWVhbjItbWVhbjEpL3NkKG91dGNvbWVfcGFydGljdWxhcikNCiAgICB0cmVhdG1lbnRfMVtrXSA8LSB1bmlxdWUodHJlYXRtZW50X3BhcnRpY3VsYXIpWzFdDQogICAgdHJlYXRtZW50XzJba10gPC0gdW5pcXVlKHRyZWF0bWVudF9wYXJ0aWN1bGFyKVsyXQ0KICANCiAgICBpZiAocGxvdF9kaXN0ID09ICJUUlVFIikgew0KICAgICAgICBoaXN0KG1lYW5fZGlmZl9kaXN0LCBicmVha3M9NTAsIGNvbD0nZ3JleScsIG1haW49IlJhbmRvbWl6YXRpb24gRGlzdHJpYnV0aW9uIiwgDQogICAgICAgICAgIGxhcz0xLCB4bGFiPSh1bmlxdWUodHJlYXRtZW50X3BhcnRpY3VsYXIpKSkNCiAgICAgICAgb3JpZ2luYWwgPC0gZGlmZih0YXBwbHkob3V0Y29tZV9wYXJ0aWN1bGFyLCB0cmVhdG1lbnRfcGFydGljdWxhciwgbWVhbikpDQogICAgICAgIGFibGluZSh2PW9yaWdpbmFsLCBsd2Q9MywgY29sPSAicmVkIikNCiAgICAgICAgYWJsaW5lKHY9LW9yaWdpbmFsLCBsd2Q9MywgY29sPSAicmVkIikNCiAgICAgIH0NCiAgDQogICAgDQogIH0NCiAgDQogIHJlc3VsdHMgPC0gZGF0YS5mcmFtZShjYmluZCh0cmVhdG1lbnRfMSwgdHJlYXRtZW50XzIsIHBfdmFsdWUsIGVmZmVjdF9zaXplLCBtZWFuX2RpZmYpKQ0KICANCiAgcmV0dXJuKHJlc3VsdHMpDQp9DQpgYGANCg0KDQoNCiAgS1FNIHVzZXMgdGhlIEZhdm9uaXVzIExhbmNlIGFzIGEgcmVmZXJlbmNlIGZyYW1lIGZvciBhbGwgb3RoZXIgcG9sZWFybSBjaG9pY2VzLA0KYW5kIHdlIHdpbGwgdXNlIHRoZSBzYW1lIHByb2Nlc3MgaW4gb3JkZXIgdG8gYW5hbHl6ZSB0aGVpciByZWNvbW1lbmRhdGlvbnMuIFRoZQ0KZm9sbG93aW5nIGFyZSB0aGUgcmVzdWx0cyBvZiB0aGUgcG9zdC1ob2MgdGVzdDogIA0KDQogIDEpIEZhdm9uaXVzIExhbmNlIHZzLiBXYXZlYnJlYWtlcidzIEZpbjogIA0KICAgICAgVGhlcmUgaXMgbW9kZXJhdGUgZXZpZGVuY2UgKHA9MC4wMjUpIHRvIHN1Z2dlc3QgdGhhdCB0aGVyZSBpcyBhIGRpZmZlcmVuY2UgDQogICAgICBpbiB0aGUgbWVhbiBFUiBvZiBTaGVuaGVzIGVxdWlwcGluZyB0aGVzZSB0d28gcG9sZWFybXMuIFRoZSBzYW1wbGUNCiAgICAgIG1lYW4gZGlmZmVyZW5jZSBpbiBFUiBpcyBhIGRlY3JlYXNlIG9mIDE4LjYxOSBFUi4gVGhpcyBkaWZmZXJlbmNlIGhhcw0KICAgICAgYSBtZWRpdW0gYXNzb2NpYXRlZCBlZmZlY3Qgc2l6ZSAoLTAuNzE4KSwgd2hpY2ggaW5kaWNhdGVzIGEgcmVsYXRpdmVseQ0KICAgICAgaW1wb3J0YW50IGRpZmZlcmVuY2UgaW4gRVIuIFByYWN0aWNhbGx5LCB0aGlzIGRpZmZlcmVuY2UgbWF5IGJlIGNydWNpYWwNCiAgICAgIGluIGNvbWJhdCwgYmVjYXVzZSBhIFdhdmVicmVha2VyJ3MgRmluIFNoZW5oZSBoYXZpbmcgYSBsYWNrIG9mIEVSIGNvdWxkDQogICAgICBhbHNvIGxpbWl0IHRoZWlyIGFiaWxpdHkgdG8gdXRpbGl6ZSB0aGUgYnVyc3QgZGFtYWdlIGJvbnVzIHByb3ZpZGVkDQogICAgICBieSB0aGUgV2F2ZWJyZWFrZXIncyBwYXNzaXZlLiAgDQogICAgICANCiAgMikgRmF2b25pdXMgTGFuY2UgdnMuIFNreXdhcmQgU3BpbmU6ICANCiAgICAgIFRoZXJlIGlzIG1vZGVyYXRlIGV2aWRlbmNlIChwPTAuMDQ0KSB0byBzdWdnZXN0IHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlIA0KICAgICAgaW4gdGhlIG1lYW4gRVIgb2YgU2hlbmhlcyBlcXVpcHBpbmcgdGhlc2UgdHdvIHBvbGVhcm1zLiBUaGUgc2FtcGxlDQogICAgICBtZWFuIGRpZmZlcmVuY2UgaW4gRVIgaXMgYW4gaW5jcmVhc2Ugb2YgMTUuMjMzIEVSLiBUaGlzIGRpZmZlcmVuY2UgaGFzDQogICAgICBhIG1lZGl1bSBhc3NvY2lhdGVkIGVmZmVjdCBzaXplICgwLjYzMCksIHdoaWNoIGluZGljYXRlcyBhIHJlbGF0aXZlbHkNCiAgICAgIGltcG9ydGFudCBkaWZmZXJlbmNlIGluIEVSLiBQcmFjdGljYWxseSwgdGhpcyBkaWZmZXJlbmNlIG1heSBub3QgbWF0dGVyDQogICAgICBpbiBjb21iYXQsIGJlY2F1c2UgdGhlIGV4dHJhIHBhcnRpY2xlcyBwcm92aWRlZCBieSB0aGUgRmF2b25pdXMgcGFzc2l2ZQ0KICAgICAgdHlwaWNhbGx5IGJyaWRnZXMgYSBnYXAgb2YgYWJvdXQgMTUgRVIuIFRoaXMgaG93ZXZlciwgbWF5IGJlIGEgcG9zaXRpdmUNCiAgICAgIG9mIHRoZSBTa3l3YXJkIFNwaW5lLCBiZWNhdXNlIGl0cyBoaWdoZXIgYmFzZSBhdGsgY291bGQgbGluayB0byBhIGhpZ2hlcg0KICAgICAgb3ZlcmFsbCBhdGssIHdoaWNoIHdlIHdpbGwgYXNzZXNzIGluIGxhdGVyIHRlc3RpbmcuICANCiAgICAgIA0KICAzKSBGYXZvbml1cyBMYW5jZSB2cy4gQ2FsYW1pdHkgUXVlbGxlcjogIA0KICAgICAgVGhlcmUgaXMgc3Ryb25nIGV2aWRlbmNlIChwPTAuMDA5KSB0byBzdWdnZXN0IHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlDQogICAgICBpbiB0aGUgbWVhbiBFUiBvZiBTaGVuaGVzIGVxdWlwcGluZyB0aGVzZSB0d28gcG9sZWFybXMuIFRoZSBzYW1wbGUNCiAgICAgIG1lYW4gZGlmZmVyZW5jZSBpbiBFUiBpcyBhIGRlY3JlYXNlIG9mIDE2Ljg2MSBFUi4gVGhpcyBkaWZmZXJlbmNlIGhhcw0KICAgICAgYSBtZWRpdW0gYXNzb2NpYXRlZCBlZmZlY3Qgc2l6ZSAoMC42MTApLCB3aGljaCBpbmRpY2F0ZXMgYSByZWxhdGl2ZWx5DQogICAgICBpbXBvcnRhbnQgZGlmZmVyZW5jZSBpbiBFUi4gUHJhY3RpY2FsbHksIHRoaXMgZGlmZmVyZW5jZSBpcyBoYXJkIHRvIGFzc2Vzcw0KICAgICAgYmVjYXVzZSBtYW55IHBsYXllcnMgd2l0aCBDYWxhbWl0eSBRdWVsbGVyIGVpdGhlciBoYXZlIGNvbnN0ZWxsYXRpb25zIG9uDQogICAgICB0aGVpciBTaGVuaGUsIHdoaWNoIGRlY3JlYXNlcyBoZXIgZW5lcmd5IHJlcXVpcmVtZW50LCBvciBpbmNvcnBvcmF0ZQ0KICAgICAgbW9kaWZpZWQgcGxheXN0eWxlcy4gIA0KICAgICAgDQogIDQpIEZhdm9uaXVzIExhbmNlIHZzLiBNaXNzaXZlIFdpbmRzcGVhcjogIA0KICAgICAgVGhlcmUgaXMgc3Ryb25nIGV2aWRlbmNlIChwPTAuMDAwKSB0byBzdWdnZXN0IHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlDQogICAgICBpbiB0aGUgbWVhbiBFUiBvZiBTaGVuaGVzIGVxdWlwcGluZyB0aGVzZSB0d28gcG9sZWFybXMuIFRoZSBzYW1wbGUNCiAgICAgIG1lYW4gZGlmZmVyZW5jZSBpbiBFUiBpcyBhIGRlY3JlYXNlIG9mIDI3Ljg0IEVSLiBUaGlzIGRpZmZlcmVuY2UgaGFzDQogICAgICBhIGxhcmdlIGFzc29jaWF0ZWQgZWZmZWN0IHNpemUgKC0xLjAxMyksIHdoaWNoIGluZGljYXRlcyBhbg0KICAgICAgaW1wb3J0YW50IGRpZmZlcmVuY2UgaW4gRVIuIFByYWN0aWNhbGx5LCB0aGlzIGRpZmZlcmVuY2UgY2FuIHJ1aW4NCiAgICAgIHJvdGF0aW9ucyB3aGVuIGxlZnQgdW5hZGRyZXNzZWQuICANCiAgICAgIA0KICA1KSBGYXZvbml1cyBMYW5jZSB2cy4gTGl0aGljIFNwZWFyOiAgDQogICAgICBUaGVyZSBpcyBtb2RlcmF0ZSBldmlkZW5jZSAocD0wLjAxMSkgdG8gc3VnZ2VzdCB0aGF0IHRoZXJlIGlzIGEgZGlmZmVyZW5jZQ0KICAgICAgaW4gdGhlIG1lYW4gRVIgb2YgU2hlbmhlcyBlcXVpcHBpbmcgdGhlc2UgdHdvIHBvbGVhcm1zLiBUaGUgc2FtcGxlDQogICAgICBtZWFuIGRpZmZlcmVuY2UgaW4gRVIgIGlzIGEgZGVjcmVhc2Ugb2YgMzAuMjUzIEVSLiBUaGlzIGRpZmZlcmVuY2UgaGFzDQogICAgICBhIGxhcmdlIGFzc29jaWF0ZWQgZWZmZWN0IHNpemUgKC0xLjIzMCksIHdoaWNoIGluZGljYXRlcyBhbiBpbXBvcnRhbnQNCiAgICAgIGRpZmZlcmVuY2UgaW4gRVIuIFRoaXMgaGFzIHRoZSBzYW1lIGltcGxpY2F0aW9ucyBhcyBpbiB0aGUgcHJldmlvdXMgY2FzZS4gIA0KICAgICAgDQogIDYpIEZhdm9uaXVzIExhbmNlIHZzLiBTdGFmZiBvZiBIb21hOiAgDQogICAgICBUaGVyZSBpcyB3ZWFrIGV2aWRlbmNlIChwPTAuMDg5KSB0byBzdWdnZXN0IHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlIGluDQogICAgICB0aGUgbWVhbiBFUiBvZiBTaGVuaGVzIGVxdWlwcGluZyB0aGVzZSB0d28gcG9sZWFybXMuIFRoZSBzYW1wbGUgbWVhbg0KICAgICAgZGlmZmVyZW5jZSBpbiBFUiBpcyBhIGRlY3JlYXNlIG9mIDQ4LjQzMyBFUi4gVGhpcyBkaWZmZXJlbmNlIGhhcyBhIGxhcmdlDQogICAgICBhc3NvY2lhdGVkIGVmZmVjdCBzaXplICgtMS45NzcpLCB3aGljaCBpbmRpY2F0ZXMgYW4gaW1wb3J0YW50IGRpZmZlcmVuY2UNCiAgICAgIGluIEVSLiBCZWNhdXNlIG9mIHRoZSBsYXJnZXIgcC12YWx1ZSwgaXQgaXMgdmVyeSBwb3NzaWJsZSB0aGF0IHRoZQ0KICAgICAgZGlmZmVyZW5jZSBpbiBwb3B1bGF0aW9uIG1lYW4gRVIgaXMgY2xvc2VyIHRvIDAsIHNvIHRoZSBpbXBsaWNhdGlvbnMgb2YgDQogICAgICB0aGlzIGNhc2UgYXJlIHZlcnkgc2ltaWxhciB0byB0aGUgcHJldmlvdXMgdHdvLiAgDQogICAgICANCiAgNykgRmF2b25pdXMgTGFuY2UgdnMuIFRoZSBDYXRjaDogIA0KICAgICAgVGhlcmUgaXMgbm8gZXZpZGVuY2UgKHA9MC40MzkpIHRvIHN1Z2dlc3QgdGhhdCB0aGVyZSBpcyBhIGRpZmZlcmVuY2UgaW4NCiAgICAgIHRoZSBtZWFuIEVSIG9mIFNoZW5oZXMgZXF1aXBwaW5nIHRoZXNlIHR3byBwb2xlYXJtcy4gIA0KICANCiAgOCkgRmF2b25pdXMgTGFuY2UgdnMuIEVuZ3VsZmluZyBMaWdodG5pbmcNCiAgICAgIFRoZXJlIGlzIHN0cm9uZyBldmlkZW5jZSAocD0wLjAwOCkgdG8gc3VnZ2VzdCB0aGF0IHRoZXJlIGlzIGEgZGlmZmVyZW5jZQ0KICAgICAgaW4gdGhlIG1lYW4gRVIgb2YgU2hlbmhlcyBlcXVpcHBpbmcgdGhlc2UgdHdvIHBvbGVhcm1zLiBUaGUgc2FtcGxlIG1lYW4NCiAgICAgIGRpZmZlcmVuY2UgaW4gRVIgaXMgYW4gaW5jcmVhc2Ugb2YgNDMuNDMzIEVSLiBUaGlzIGRpZmZlcmVuY2UgaGFzIGEgbGFyZ2UNCiAgICAgIGFzc29jaWF0ZWQgZWZmZWN0IHNpemUgKDEuNjgzKSwgd2hpY2ggaW5kaWNhdGVzIGFuIGltcG9ydGFudCBkaWZmZXJlbmNlDQogICAgICBpbiBFUi4gUHJhY3RpY2FsbHksIHRoaXMgZGlmZmVyZW5jZSByZW1haW5zIHRoZSBzYW1lIGJlY2F1c2Ugb2YNCiAgICAgIEVuZ3VsZmluZyBMaWdodG5pbmcncyBwZXJzb25hbCBFUiBib29zdCBhZnRlciBjYXN0aW5nIGEgYnVyc3QuIFN0aWxsLA0KICAgICAgRmF2b25pdXMgTGFuY2UgcHJvdmlkZXMgZW5lcmd5IGZvciB0aGUgZW50aXJlIHRlYW0gZnJvbSBpdHMgcGFzc2l2ZSwNCiAgICAgIHdoaWNoIGlzIGFuIGFkZGVkIGxheWVyIG9mIHV0aWxpdHkgdG8gY29uc2lkZXIgd2hlbiBjaG9vc2luZyBhIHBvbGVhcm0NCiAgICAgIGZvciBTaGVuaGUuICANCiAgICAgIA0KICA5KSBGYXZvbml1cyBMYW5jZSB2cy4gUHJpbW9yZGlhbCBKYWRlIFdpbmdlZCBTcGVhcjogIA0KICAgICAgVGhlcmUgaXMgc3Ryb25nIGV2aWRlbmNlIChwPTAuMDA5KSB0byBzdWdnZXN0IHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlDQogICAgICBpbiB0aGUgbWVhbiBFUiBvZiBTaGVuaGVzIGVxdWlwcGluZyB0aGVzZSB0d28gcG9sZWFybXMuIFRoZSBzYW1wbGUgbWVhbg0KICAgICAgZGlmZmVyZW5jZSBpbiBFUiBpcyBhIGRlY3JlYXNlIG9mIDIwLjI3MCBFUi4gVGhpcyBkaWZmZXJlbmNlIGhhcyBhIGxhcmdlDQogICAgICBhc3NvY2lhdGVkIGVmZmVjdCBzaXplICgtMC44ODIpLCB3aGljaCBpbmRpY2F0ZXMgYW4gaW1wb3J0YW50IGRpZmZlcmVuY2UNCiAgICAgIGluIEVSLiBUaGlzIGhhcyB0aGUgc2FtZSBpbXBsaWNhdGlvbnMgYXMgaW4gY2FzZXMgZm91ciwgZml2ZSwgYW5kIHNpeC4gIA0KICAgICAgDQogIDEwKSBGYXZvbml1cyBMYW5jZSB2cy4gVm9ydGV4IFZhbnF1aXNoZXI6ICANCiAgICAgIFRoZXJlIGlzIG1vZGVyYXRlIGV2aWRlbmNlIChwPTAuMDQ2KSB0byBzdWdnZXN0IHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlDQogICAgICBpbiB0aGUgbWVhbiBFUiBvZiBTaGVuaGVzIGVxdWlwcGluZyB0aGVzZSB0d28gcG9sZWFybXMuIFRoZSBzYW1wbGUgbWVhbg0KICAgICAgZGlmZmVyZW5jZSBpbiBFUiBpcyBhIGRlY3JlYXNlIG9mIDM4Ljk4MyBFUi4gVGhpcyBkaWZmZXJlbmNlIGhhcyBhIGxhcmdlDQogICAgICBhc3NvY2lhdGVkIGVmZmVjdCBzaXplICgtMS41NzMpLCB3aGljaCBpbmRpY2F0ZXMgYW4gaW1wb3J0YW50IGRpZmZlcmVuY2UNCiAgICAgIGluIEVSLiBJIHdvdWxkIG5vdCBwbGFjZSBtdWNoIGNlcnRhaW50eSBvbiB0aGVzZSB2YWx1ZXMsIGJlY2F1c2UgdGhlcmUNCiAgICAgIHdlcmUgb25seSB0d28gdG90YWwgb2JzZXJ2YXRpb25zIGZvciB0aGUgVm9ydGV4IFZhbnF1aXNoZXIgcG9sZWFybSwNCiAgICAgIHdoaWNoIEkgZG8gbm90IGJlbGlldmUgaXMgc3VmZmljaWVudCBkYXRhIHRvIG1ha2UgYW55IGZpcm0gY29uY2x1c2lvbnMuDQogICAgICBUaGUgaW1wbGljYXRpb25zIG9mIHRoaXMgZGlmZmVyZW5jZSBhcmUgc3RpbGwgdGhlIHNhbWUuICANCiAgICAgIA0KICAxMSkgRmF2b25pdXMgTGFuY2UgdnMuIERlYXRobWF0Y2g6ICANCiAgICAgIFRoZXJlIGlzIHZlcnkgc3Ryb25nIGV2aWRlbmNlIChwPTAuMDAwKSB0byBzdWdnZXN0IHRoYXQgdGhlcmUgaXMgYQ0KICAgICAgZGlmZmVyZW5jZSBpbiB0aGUgbWVhbiBFUiBvZiBTaGVuaGVzIGVxdWlwcGluZyB0aGVzZSB0d28gcG9sZWFybXMuIFRoZSANCiAgICAgIHNhbXBsZSBtZWFuIGRpZmZlcmVuY2UgaW4gRVIgaXMgYSBkZWNyZWFzZSBvZiA1Ni44MDAgRVIuIFRoaXMgZGlmZmVyZW5jZSANCiAgICAgIGhhcyBhIGxhcmdlIGFzc29jaWF0ZWQgZWZmZWN0IHNpemUgKC0yLjAyOCksIHdoaWNoIGluZGljYXRlcyBhbiBpbXBvcnRhbnQgDQogICAgICBkaWZmZXJlbmNlIGluIEVSLiBJdCBpcyB1bmNsZWFyIHdoeSB0aGUgZGlmZmVyZW5jZSBpbiBtZWFuIEVSIGZvcg0KICAgICAgdGhlc2UgdHdvIHBvbGVhcm1zIGlzIHNvIGxhcmdlLCBidXQgb25lIG9mIHRoZSBjb250cmlidXRpbmcgZmFjdG9ycw0KICAgICAgY2VydGFpbmx5IGNvdWxkIGJlIHRoYXQgdGhlcmUgd2VyZSBvbmx5IHRocmVlICgzKSBvYnNlcnZhdGlvbnMgb2YgU2hlbmhlcw0KICAgICAgZXF1aXBwaW5nIERlYXRobWF0Y2ggaW4gdGhlIGZpcnN0IHBsYWNlLiBUaGlzIGNlcnRhaW5seSBjb3VsZCBoYXZlIHlpZWxkZWQNCiAgICAgIGFuIGluYXBwcm9wcmlhdGUgcC12YWx1ZSwgYmVjYXVzZSB0aGVyZSB3ZXJlIG5vIGNvbWJpbmF0aW9ucyB3aXRoaW4gdGhlDQogICAgICByZXNhbXBsaW5nIHdoaWNoIHByb2R1Y2VkIHJlc3VsdHMgb2YgdGhlIHNhbWUgbWFnbml0dWRlIG9yIGhpZ2hlciwNCiAgICAgIGJ1dCB0aGF0IGNlcnRhaW5seSBkb2VzIG5vdCBtZWFuIHRoYXQgdGhvc2UgY2FzZXMgZG8gbm90IGV4aXN0IG91dHNpZGUNCiAgICAgIG9mIHRoZSBkYXRhc2V0LiBUaGlzIGRpZmZlcmVuY2UsIHN0aWxsLCBoYXMgdGhlIHNhbWUgaW1wbGljYXRpb25zIGFzDQogICAgICB0aGUgcHJldmlvdXMuICANCiAgICAgIA0KICAxMikgRmF2b25pdXMgTGFuY2UgdnMuIEJsYWNrY2xpZmYgUG9sZTogIA0KICAgICAgVGhlcmUgaXMgd2VhayBldmlkZW5jZSAocD0wLjA2NikgdG8gc3VnZ2VzdCB0aGF0IHRoZXJlIGlzIGEgZGlmZmVyZW5jZSBpbg0KICAgICAgdGhlIG1lYW4gRVIgb2YgU2hlbmhlcyBlcXVpcHBpbmcgdGhlc2UgdHdvIHBvbGVhcm1zLiBUaGUgc2FtcGxlIG1lYW4NCiAgICAgIGRpZmZlcmVuY2UgaW4gRVIgaXMgYSBkZWNyZWFzZSBvZiA1OC43MzMgRVIuIFRoaXMgZGlmZmVyZW5jZSBoYXMgYSBsYXJnZQ0KICAgICAgYXNzb2NpYXRlZCBlZmZlY3Qgc2l6ZSAoLTIuMzIzKSwgd2hpY2ggaW5kaWNhdGVzIGFuIGltcG9ydGFudCBkaWZmZXJlbmNlDQogICAgICBpbiBFUi4gQmVjYXVzZSBvZiB0aGUgbGFyZ2VyIHAtdmFsdWUsIGl0IGlzIHZlcnkgcG9zc2libGUgdGhhdCB0aGUNCiAgICAgIGRpZmZlcmVuY2UgaW4gcG9wdWxhdGlvbiBtZWFuIEVSIGlzIGNsb3NlciB0byAwLCBhbmQgZ2l2ZW4gdGhhdCB0aGVyZQ0KICAgICAgd2FzIG9ubHkgb25lIG9ic2VydmF0aW9uIG9mIEJsYWNrY2xpZmYgUG9sZSwgdGhlc2UgdmFsdWVzIGFyZSBub3QgdmVyeQ0KICAgICAgY29uc2VxdWVudGlhbC4gIA0KICAgICAgDQogIDEzKSBGYXZvbml1cyBMYW5jZSB2cy4gRHJhZ29uJ3MgQmFuZTogIA0KICAgICAgVGhlcmUgaXMgd2VhayBldmlkZW5jZSAocD0wLjA4NikgdG8gc3VnZ2VzdCB0aGF0IHRoZXJlIGlzIGEgZGlmZmVyZW5jZSBpbg0KICAgICAgdGhlIG1lYW4gRVIgb2YgU2hlbmhlcyBlcXVpcHBpbmcgdGhlc2UgdHdvIHBvbGVhcm1zLiBUaGUgc2FtcGxlIG1lYW4NCiAgICAgIGRpZmZlcmVuY2UgaW4gRVIgaXMgYSBkZWNyZWFzZSBvZiA0OC40MzMgRVIuIFRoaXMgZGlmZmVyZW5jZSBoYXMgYSBsYXJnZQ0KICAgICAgYXNzb2NpYXRlZCBlZmZlY3Qgc2l6ZSAoLTEuOTc3KSwgd2hpY2ggaW5kaWNhdGVzIGFuIGltcG9ydGFudCBkaWZmZXJlbmNlDQogICAgICBpbiBFUi4gQmVjYXVzZSBvZiB0aGUgbGFyZ2VyIHAtdmFsdWUsIGl0IGlzIHZlcnkgcG9zc2libGUgdGhhdCB0aGUNCiAgICAgIGRpZmZlcmVuY2UgaW4gcG9wdWxhdGlvbiBtZWFuIEVSIGlzIGNsb3NlciB0byAwLCBhbmQgZ2l2ZW4gdGhhdCB0aGVyZQ0KICAgICAgd2FzIG9ubHkgb25lIG9ic2VydmF0aW9uIG9mIERyYWdvbidzIEJhbmUsIHRoZXNlIHZhbHVlcyBhcmUgbm90IHZlcnkNCiAgICAgIGNvbnNlcXVlbnRpYWwuICANCiAgICAgIA0KICAxNCkgRmF2b25pdXMgTGFuY2UgdnMuIFJveWFsIFNwZWFyOiAgDQogICAgICBUaGVyZSBpcyBubyBldmlkZW5jZSAocD0wLjYxOCkgdG8gc3VnZ2VzdCB0aGF0IHRoZXJlIGlzIGEgZGlmZmVyZW5jZSBpbg0KICAgICAgdGhlIG1lYW4gRVIgb2YgU2hlbmhlcyBlcXVpcHBpbmcgdGhlc2UgdHdvIHBvbGVhcm1zLiAgDQogICAgICANCiAgMTUpIEZhdm9uaXVzIExhbmNlIHZzLiBQcm90b3R5cGUgU3RhcmdsaXR0ZXI6ICANCiAgICAgIFRoZXJlIGlzIG5vIGV2aWRlbmNlIChwPTAuOTE2KSB0byBzdWdnZXN0IHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlIGluDQogICAgICB0aGUgbWVhbiBFUiBvZiBTaGVuaGVzIGVxdWlwcGluZyB0aGVzZSB0d28gcG9sZWFybXMuICANCiAgICAgIA0KICAxNikgRmF2b25pdXMgTGFuY2UgdnMuIFN0YWZmIG9mIFNjYXJsZXQgU2FuZHM6ICANCiAgICAgIFRoZXJlIGlzIG5lYXJseSBubyBldmlkZW5jZSAocD0wLjA5OCkgdG8gc3VnZ2VzdCB0aGF0IHRoZXJlIGlzIGEgZGlmZmVyZW5jZQ0KICAgICAgaW4gdGhlIG1lYW4gRVIgb2YgU2hlbmhlcyBlcXVpcHBpbmcgdGhlc2UgdHdvIHBvbGVhcm1zLiAgDQogICAgICANCiAgMTcpIEZhdm9uaXVzIExhbmNlIHZzLiBXaGl0ZSBUYXNzZWw6ICANCiAgICAgIFRoZXJlIGlzIG5vIGV2aWRlbmNlIChwPTAuNDA5KSB0byBzdWdnZXN0IHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlIGluDQogICAgICB0aGUgbWVhbiBFUiBvZiBTaGVuaGVzIGVxdWlwcGluZyB0aGVzZSB0d28gcG9sZWFybXMuICANCiAgICAgIA0KICAxOCkgRmF2b25pdXMgTGFuY2UgdnMuIENyZXNjZW50IFBpa2U6DQogICAgICBUaGVyZSBpcyB3ZWFrIGV2aWRlbmNlIChwPTAuMDc1KSB0byBzdWdnZXN0IHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlIGluDQogICAgICB0aGUgbWVhbiBFUiBmbyBTaGVuaGVzIGVxdWlwcGluZyB0aGVzZSB0d28gcG9sZWFybXMuIFRoZSBzYW1wbGUgbWVhbg0KICAgICAgZGlmZmVyZW5jZSBpbiBFUiBpcyBhIGRlY3JlYXNlIG9mIDQ0LjUzMyBFUi4gVGhpcyBkaWZmZXJlbmNlIGhhcyBhIGxhcmdlDQogICAgICBhc3NvY2lhdGVkIGVmZmVjdCBzaXplICgtMS44MzgpLCB3aGljaCBpbmRpY2F0ZXMgYW4gaW1wb3J0YW50IGRpZmZlcmVuY2UNCiAgICAgIGluIEVSLiBCZWNhdXNlIG9mIHRoZSBsYXJnZXIgcC12YWx1ZSwgaXQgaXMgdmVyeSBwb3NzaWJsZSB0aGF0IHRoZQ0KICAgICAgZGlmZmVyZW5jZSBpbiBwb3B1bGF0aW9uIG1lYW4gRVIgaXMgY2xvc2VyIHRvIDAuIEFkZGl0aW9uYWxseSwgU2hlbmhlcw0KICAgICAgdXNpbmcgQ3Jlc2NlbnQgUGlrZSBhcmUgdXN1YWxseSBwaHlzaWNhbCBEUFMsIGFuZCBkbyBub3QgZ2FpbiBtdWNoIHV0aWxpdHkNCiAgICAgIGZyb20gY2FzdGluZyB0aGVpciBidXJzdC4gIA0KICANCiAgDQoNCmBgYHtyIGNvZGUtY2h1bmstRVJfdl9Qb2xlYXJtfQ0Kc2V0LnNlZWQoMjcpDQoNCmFkaV9zYWlkaS5SUFQoc2hlbmhlJHBvbGVhcm1fbmFtZSwgc2hlbmhlJEVSKQ0KYGBgDQoNCg0KDQogIEFnYWluLCBLUU0gdXNlcyB0aGUgRmF2b25pdXMgTGFuY2UgYXMgYSByZWZlcmVuY2UgZnJhbWUgZm9yIGFsbCBvdGhlciBwb2xlYXJtIA0KY2hvaWNlcywgYW5kIHdlIHdpbGwgdXNlIHRoZSBzYW1lIHByb2Nlc3MgaW4gb3JkZXIgdG8gYW5hbHl6ZSB0aGVpciANCnJlY29tbWVuZGF0aW9ucywgdGhpcyB0aW1lIGxvb2tpbmcgYXQgYXRrIGluc3RlYWQgb2YgRVIuIFRoZSBmb2xsb3dpbmcgYXJlIHRoZSANCnJlc3VsdHMgb2YgdGhlIHBvc3QtaG9jIHRlc3Q6ICANCg0KICAxKSBGYXZvbml1cyBMYW5jZSB2cy4gV2F2ZWJyZWFrZXIncyBGaW46ICANCiAgICAgIFRoZXJlIGlzIHN0cm9uZyBldmlkZW5jZSAocD0wLjAwMSkgdG8gc3VnZ2VzdCB0aGF0IHRoZXJlIGlzIGEgZGlmZmVyZW5jZQ0KICAgICAgaW4gdGhlIG1lYW4gYXRrIG9mIFNoZW5oZXMgZXF1aXBwaW5nIHRoZXNlIHR3byBwb2xlYXJtcy4gVGhlIHNhbXBsZQ0KICAgICAgbWVhbiBkaWZmZXJlbmNlIGluIGF0ayBpcyBhbiBpbmNyZWFzZSBvZiA0MjMuNTc0IGF0ay4gVGhpcyBkaWZmZXJlbmNlIGhhcw0KICAgICAgYSBsYXJnZSBhc3NvY2lhdGVkIGVmZmVjdCBzaXplICgxLjAwOSksIHdoaWNoIGluZGljYXRlcyBhbiBpbXBvcnRhbnQgDQogICAgICBkaWZmZXJlbmNlIGluIGF0ay4gVGhpcyBhdGsgaW5jcmVhc2UgY2FuIGNvbnRyaWJ1dGUgYSBsYXJnZSBhbW91bnQgb2YgaWN5DQogICAgICBxdWlsbCBkYW1hZ2UuICANCiAgICAgIA0KICAyKSBGYXZvbml1cyBMYW5jZSB2cy4gU2t5d2FyZCBTcGluZTogIA0KICAgICAgVGhlcmUgaXMgc3Ryb25nIGV2aWRlbmNlIChwPTAuMDAwKSB0byBzdWdnZXN0IHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlDQogICAgICBpbiB0aGUgbWVhbiBhdGsgb2YgU2hlbmhlcyBlcXVpcHBpbmcgdGhlc2UgdHdvIHBvbGVhcm1zLiBUaGUgc2FtcGxlIG1lYW4NCiAgICAgIGRpZmZlcmVuY2UgaW4gYXRrIGlzIGFuIGluY3JlYXNlIG9mIDU2Ni42ODUgYXRrLiBUaGlzIGRpZmZlcmVuY2UgaGFzDQogICAgICBhIGxhcmdlIGFzc29jaWF0ZWQgZWZmZWN0IHNpemUgKDEuMzAzKSwgd2hpY2ggaW5kaWNhdGVzIGFuIGltcG9ydGFudA0KICAgICAgZGlmZmVyZW5jZSBpbiBhdGsuIFRoaXMgYXRrIGluY3JlYXNlIGNhbiBhbHNvIGNvbnRyaWJ1dGUgYSBsYXJnZSBhbW91bnQgb2YNCiAgICAgIGljeSBxdWlsbCBkYW1hZ2UgdG8gdGhlIHRlYW0uICANCiAgICANCiAgMykgRmF2b25pdXMgTGFuY2UgdnMuIENhbGFtaXR5IFF1ZWxsZXI6ICANCiAgICAgIFRoZXJlIGlzIHN0cm9uZyBldmlkZW5jZSAocD0wLjAwMCkgdG8gc3VnZ2VzdCB0aGF0IHRoZXJlIGlzIGEgZGlmZmVyZW5jZQ0KICAgICAgaW4gdGhlIG1lYW4gYXRrIG9mIFNoZW5oZXMgZXF1aXBwaW5nIHRoZXNlIHR3byBwb2xlYXJtcy4gVGhlIHNhbXBsZSBtZWFuDQogICAgICBkaWZmZXJlbmNlIGluIGF0ayBpcyBhbiBpbmNyZWFzZSBvZiA3NjAuNzEzIGF0ay4gVGhpcyBkaWZmZXJlbmNlIGhhcw0KICAgICAgYSBsYXJnZSBhc3NvY2lhdGVkIGVmZmVjdCBzaXplICgxLjE2MyksIHdoaWNoIGluZGljYXRlcyBhbiBpbXBvcnRhbnQNCiAgICAgIGRpZmZlcmVuY2UgaW4gYXRrLiBUaGlzIGF0ayBpbmNyZWFzZSBjYW4gYWxzbyBjb250cmlidXRlIGEgbGFyZ2UgYW1vdW50IG9mDQogICAgICBpY3kgcXVpbGwgZGFtYWdlIHRvIHRoZSB0ZWFtLiAgDQogICAgDQogIDQpIEZhdm9uaXVzIExhbmNlIHZzLiBNaXNzaXZlIFdpbmRzcGVhcjogIA0KICAgICAgVGhlcmUgaXMgc3Ryb25nIGV2aWRlbmNlIChwPTAuMDA1KSB0byBzdWdnZXN0IHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlDQogICAgICBpbiB0aGUgbWVhbiBhdGsgb2YgU2hlbmhlcyBlcXVpcHBpbmcgdGhlc2UgdHdvIHBvbGVhcm1zLiBUaGUgc2FtcGxlIG1lYW4NCiAgICAgIGRpZmZlcmVuY2UgaW4gYXRrIGlzIGFuIGluY3JlYXNlIG9mIDM2Mi43NDEgYXRrLiBUaGlzIGRpZmZlcmVuY2UgaGFzDQogICAgICBhIGxhcmdlIGFzc29jaWF0ZWQgZWZmZWN0IHNpemUgKDAuODk4KSwgd2hpY2ggaW5kaWNhdGVzIGFuIGltcG9ydGFudA0KICAgICAgZGlmZmVyZW5jZSBpbiBhdGsuIFRoaXMgYXRrIGluY3JlYXNlIGNhbiBjb250cmlidXRlIGEgZGVjZW50IGFtb3VudCBvZg0KICAgICAgZXh0cmEgaWN5IHF1aWxsIGRhbWFnZS4gIA0KICAgICAgDQogIDUpIEZhdm9uaXVzIExhbmNlIHZzLiBMaXRoaWMgU3BlYXI6ICANCiAgICAgIFRoZXJlIGlzIG5vIGV2aWRlbmNlIChwPTAuMzMwKSB0byBzdWdnZXN0IHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlIGluDQogICAgICB0aGUgbWVhbiBhdGsgb2YgU2hlbmhlcyBlcXVpcHBpbmcgdGhlc2UgdHdvIHBvbGVhcm1zLiAgDQogICAgICANCiAgNikgRmF2b25pdXMgTGFuY2UgdnMuIFN0YWZmIG9mIEhvbWE6DQogICAgICBUaGVyZSBpcyBubyBldmlkZW5jZSAocD0wLjMyNikgdG8gc3VnZ2VzdCB0aGF0IHRoZXJlIGlzIGEgZGlmZmVyZW5jZSBpbg0KICAgICAgdGhlIG1lYW4gYXRrIG9mIFNoZW5oZXMgZXF1aXBwaW5nIHRoZXNlIHR3byBwb2xlYXJtcy4gSXQgaXMgaW1wb3J0YW50IHRvDQogICAgICBub3RlIGhlcmUsIHRoYXQganVzdCBiZWNhdXNlIHRoZSBkYXRhIHdlIGhhdmUgcHJvdmlkZXMgbm8gZXZpZGVuY2UgdG8NCiAgICAgIHN1Z2dlc3QgdGhhdCB0aGVyZSBpcyBhbnkgZGlmZmVyZW5jZSwgZG9lc24ndCBtZWFuIHRoZSBkYXRhIHByb3ZpZGVzDQogICAgICBldmlkZW5jZSB0byBzdWdnZXN0IHRoYXQgdGhlcmUgaXMgbm8gZGlmZmVyZW5jZS4gIA0KICAgICAgDQogIDcpIEZhdm9uaXVzIExhbmNlIHZzLiBUaGUgQ2F0Y2g6ICANCiAgICAgIFRoZXJlIGlzIHZlcnkgd2VhayBldmlkZW5jZSAocD0wLjA5NCkgdG8gc3VnZ2VzdCB0aGF0IHRoZXJlIGlzIGENCiAgICAgIGRpZmZlcmVuY2UgaW4gdGhlIG1lYW4gYXRrIG9mIFNoZW5oZXMgZXF1aXBwaW5nIHRoZXNlIHR3byBwb2xlYXJtcy4NCiAgICAgIEJlY2F1c2Ugb2YgdGhlIGxhcmdlIHAtdmFsdWVzLCB0aGUgcG9pbnQgZXN0aW1hdGVzIGFyZSBub3QgYXBwcm9wcmlhdGUNCiAgICAgIG1lYXN1cmVzIHVwb24gd2hpY2ggdG8gbWFrZSBudW1lcmljIGNvbmNsdXNpb25zLCBidXQgdGhleSBzdWdnZXN0IHRoYXQgDQogICAgICB0aGVyZSBpcyBhIGdlbmVyYWwgZGVjcmVhc2UgaW4gYXRrLCB3aGljaCBtYWtlcyBzZW5zZSBiZWNhdXNlIFRoZSBDYXRjaA0KICAgICAgaGFzIGEgbG93ZXIgYmFzZSBhdGsgdGhhbiBGYXZvbml1cyBMYW5jZSAoNTEwIHZzLiA1NjUpLiAgDQogICAgICANCiAgOCkgRmF2b25pdXMgTGFuY2UgdnMuIEVuZ3VsZmluZyBMaWdodG5pbmc6ICANCiAgICAgIFRoZXJlIGlzIG5vIGV2aWRlbmNlIChwPTAuMjY4KSB0byBzdWdnZXN0IHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlIGluDQogICAgICB0aGUgbWVhbiBhdGsgb2YgU2hlbmhlcyBlcXVpcHBpbmcgdGhlc2UgdHdvIHBvbGVhcm1zLiBUaGUgYXRrIG1pZ2h0IGhhdmUNCiAgICAgIGEgdHJ1ZSBkaWZmZXJlbmNlIHdoZW4gaW4gYmF0dGxlIGR1ZSB0byBFbmd1bGZpbmcgTGlnaHRuaW5nJ3MgRVIgYW5kIA0KICAgICAgc3Vic2VxdWVudCBhdGsgYm9udXMgYWZ0ZXIgY2FzdGluZyBhbiBlbGVtZW50YWwgYnVyc3QuICANCiAgICAgIA0KICA5KSBGYXZvbml1cyBMYW5jZSB2cy4gUHJpbW9yZGlhbCBKYWRlIFdpbmdlZCBTcGVhcjogIA0KICAgICAgVGhlcmUgaXMgc3Ryb25nIGV2aWRlbmNlIChwPTAuMDAyKSB0byBzdWdnZXN0IHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlDQogICAgICBpbiB0aGUgbWVhbiBhdGsgb2YgU2hlbmhlcyBlcXVpcHBpbmcgdGhlc2UgdHdvIHBvbGVhcm1zLiBUaGUgc2FtcGxlIG1lYW4NCiAgICAgIGRpZmZlcmVuY2UgaW4gYXRrIGlzIGFuIGluY3JlYXNlIG9mIDQ2MC40MzEgYXRrLiBUaGlzIGRpZmZlcmVuY2UgaGFzDQogICAgICBhIGxhcmdlIGFzc29jaWF0ZWQgZWZmZWN0IHNpemUgKDEuMDU2KSwgd2hpY2ggaW5kaWNhdGVzIGFuIGltcG9ydGFudA0KICAgICAgZGlmZmVyZW5jZSBpbiBhdGsuIFRoaXMgYXRrIGluY3JlYXNlIGNhbiBjb250cmlidXRlIGEgbGFyZ2UgYW1vdW50IG9mDQogICAgICBleHRyYSBpY3kgcXVpbGwgZGFtYWdlLiAgDQogICAgICANCiAgMTApIEZhdm9uaXVzIExhbmNlIHZzLiBWb3J0ZXggVmFucXVpc2hlcjogIA0KICAgICAgVGhlcmUgaXMgbW9kZXJhdGUgZXZpZGVuY2UgKHA9MC4wMTcpIHRvIHN1Z2dlc3QgdGhhdCB0aGVyZSBpcyBhIGRpZmZlcmVuY2UNCiAgICAgIGluIHRoZSBtZWFuIGF0ayBvZiBTaGVuaGVzIGVxdWlwcGluZyB0aGVzZSB0d28gcG9sZWFybXMuIFRoZSBzYW1wbGUgbWVhbg0KICAgICAgZGlmZmVyZW5jZSBpbiBhdGsgaXMgYW4gaW5jcmVhc2Ugb2YgNjg0LjA3NCBhdGsuIFRoaXMgZGlmZmVyZW5jZSBoYXMgYSANCiAgICAgIGxhcmdlIGFzc29jaWF0ZWQgZWZmZWN0IHNpemUgKDEuNjUyKSwgd2hpY2ggaW5kaWNhdGVzIGFuIGltcG9ydGFudA0KICAgICAgZGlmZmVyZW5jZSBpbiBhdGsuIFRoaXMgYXRrIGluY3JlYXNlIGNhbiBjb250cmlidXRlIGEgbGFyZ2UgYW1vdW50IG9mIA0KICAgICAgZXh0cmEgaWN5IHF1aWxsIGRhbWFnZS4gUHJhY3RpY2FsbHksIHRoaXMgZGlmZmVyZW5jZSBtYXkgYmUgZXZlbiBsYXJnZXIsDQogICAgICBiZWNhdXNlIHdoaWxlIGluIGJhdHRsZSwgdGhlIFZvcnRleCBWYW5xdWlzaGVyIGluY3JlYXNlcyBhdGsgd2hlbiBzaGllbGRlZCwNCiAgICAgIGJ1dCBhcyBLUU0gc3RhdGVzLCB0aGlzIGF0ayBidWZmIGNhbm5vdCBzdGFjayB3aGlsZSBvZmYgZmllbGQuIFRoaXMgY291bGQNCiAgICAgIHN0aWxsIG1ha2UgVm9ydGV4IFZhbnF1aXNoZXIgYSBzdHJvbmcgY2hvaWNlIGZvciBhbiBvbi1maWVsZCBEUFMgU2hlbmhlLiAgDQogICAgICANCiAgMTEpIEZhdm9uaXVzIExhbmNlIHZzLiBEZWF0aG1hdGNoOiAgDQogICAgICBUaGVyZSBpcyBubyBldmlkZW5jZSAocD0wLjgyMikgdG8gc3VnZ2VzdCB0aGF0IHRoZXJlIGlzIGEgZGlmZmVyZW5jZSBpbg0KICAgICAgdGhlIG1lYW4gYXRrIG9mIFNoZW5oZXMgZXF1aXBwaW5nIHRoZXNlIHR3byBwb2xlYXJtcy4gIA0KICAgICAgDQogIDEyKSBGYXZvbml1cyBMYW5jZSB2cy4gQmxhY2tjbGlmZiBQb2xlOiAgDQogICAgICBUaGVyZSBpcyBubyBldmlkZW5jZSAocD0wLjQ2NCkgdG8gc3VnZ2VzdCB0aGF0IHRoZXJlIGlzIGEgZGlmZmVyZW5jZSBpbg0KICAgICAgdGhlIG1lYW4gYXRrIG9mIFNoZW5oZXMgZXF1aXBwaW5nIHRoZXNlIHR3byBwb2xlYXJtcy4gIA0KICAgICAgDQogIDEzKSBGYXZvbml1cyBMYW5jZSB2cy4gRHJhZ29uJ3MgQmFuZTogIA0KICAgICAgVGhlcmUgaXMgd2VhayBldmlkZW5jZSAocD0wLjA3NikgdG8gc3VnZ2VzdCB0aGF0IHRoZXJlIGlzIGEgZGlmZmVyZW5jZSBpbg0KICAgICAgdGhlIG1lYW4gYXRrIG9mIFNoZW5oZXMgZXF1aXBwaW5nIHRoZXNlIHR3byBwb2xlYXJtcy4gVGhlIHNhbXBsZSBtZWFuDQogICAgICBkaWZmZXJlbmNlIGluIGF0ayBpcyBhIGRlY3JlYXNlIG9mIDgwOC45MjYgYXRrLiBUaGlzIGRpZmZlcmVuY2UgaGFzIGENCiAgICAgIGxhcmdlIGFzc29jaWF0ZWQgZWZmZWN0IHNpemUgKC0xLjk4NyksIHdoaWNoIGluZGljYXRlcyBhbiBpbXBvcnRhbnQNCiAgICAgIGRpZmZlcmVuY2UgaW4gYXRrLiBUaGlzIGF0ayBsb3NzIHdvdWxkIGNvbnNpZGVyYWJseSBkZWNyZWFzZSBkYW1hZ2UgZnJvbQ0KICAgICAgaWN5IHF1aWxscy4gIA0KICAgIA0KICAxNCkgRmF2b25pdXMgTGFuY2UgdnMuIFJveWFsIFNwZWFyOiAgDQogICAgICBUaGVyZSBpcyBubyBldmlkZW5jZSAocD0wLjEzNCkgdG8gc3VnZ2VzdCB0aGF0IHRoZXJlIGlzIGEgZGlmZmVyZW5jZSBpbg0KICAgICAgdGhlIG1lYW4gYXRrIG9mIFNoZW5oZXMgZXF1aXBwaW5nIHRoZXNlIHR3byBwb2xlYXJtcy4gIA0KICAgIA0KICAxNSkgRmF2b25pdXMgTGFuY2UgdnMuIFByb3RvdHlwZSBTdGFyZ2xpdHRlcjogIA0KICAgICAgVGhlcmUgaXMgbm8gZXZpZGVuY2UgKHA9MC4xNjUpIHRvIHN1Z2dlc3QgdGhhdCB0aGVyZSBpcyBhIGRpZmZlcmVuY2UgaW4NCiAgICAgIHRoZSBtZWFuIGF0ayBvZiBTaGVuaGVzIGVxdWlwcGluZyB0aGVzZSB0d28gcG9sZWFybXMuICANCiAgICAgIA0KICAxNikgRmF2b25pdXMgTGFuY2UgdnMuIFN0YWZmIG9mIFNjYXJsZXQgU2FuZHM6ICANCiAgICAgIFRoZXJlIGlzIG5vIGV2aWRlbmNlIChwPTAuNDMwKSB0byBzdWdnZXN0IHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlIGluDQogICAgICB0aGUgbWVhbiBhdGsgb2YgU2hlbmhlcyBlcXVpcHBpbmcgdGhlc2UgdHdvIHBvbGVhcm1zLiAgDQogICAgICANCiAgMTcpIEZhdm9uaXVzIExhbmNlIHZzLiBXaGl0ZSBUYXNzZWw6ICANCiAgICAgIFRoZXJlIGlzIG5vIGV2aWRlbmNlIChwPTAuNTE5KSB0byBzdWdnZXN0IHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlIGluDQogICAgICB0aGUgbWVhbiBhdGsgb2YgU2hlbmhlcyBlcXVpcHBpbmcgdGhlc2UgdHdvIHBvbGVhcm1zLiBBZ2FpbiwganVzdCBiZWNhdXNlDQogICAgICB0aGUgZGF0YSBwcm92aWRlcyBubyBldmlkZW5jZSB0byBpbmRpY2F0ZSBhIGRpZmZlcmVuY2UgaW4gcG9wdWxhdGlvbiBtZWFucywNCiAgICAgIGRvZXMgbm90IG1lYW4gdGhhdCBvbmUgZG9lcyBub3QgYWN0dWFsbHkgZXhpc3QuICANCiAgICAgIA0KICAxOCkgRmF2b25pdXMgTGFuY2UgdnMuIENyZXNjZW50IFBpa2U6ICANCiAgICAgIFRoZXJlIGlzIG5vIGV2aWRlbmNlIChwPTAuMTQ3KSB0byBzdWdnZXN0IHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlIGluDQogICAgICB0aGUgbWVhbiBhdGsgb2YgU2hlbmhlcyBlcXVpcHBpbmcgdGhlc2UgdHdvIHBvbGVhcm1zLiAgDQoNCg0KDQpgYGB7ciBjb2RlLWNodW5rLWF0a192X1BvbGVhcm19DQpzZXQuc2VlZCgyNykNCg0KYWRpX3NhaWRpLlJQVChzaGVuaGUkcG9sZWFybV9uYW1lLCBzaGVuaGUkYXRrKQ0KYGBgDQoNCg0KDQogIEtRTSByZWNvbW1lbmRzIGEgZnVsbCBOb2JsZXNzZSBPYmxpZ2Ugc2V0IGZvciBTaGVuaGUsIGFuZCB0aGVyZWZvcmUgd2UNCndpbGwgdXNlIGl0IGFzIGEgcmVmZXJlbmNlIGZyYW1lIGZvciBhbmFseXppbmcgdGhlaXIgcmVjb21tZW5kYXRpb25zLiBJdCBzaG91bGQNCmJlIG5vdGVkIHRoYXQgTm9ibGVzc2UgT2JsaWdlIHByb3ZpZGVzIGEgMjAlIGF0ayBib251cyBhZnRlciBjYXN0aW5nIGFuIGVsZW1lbnRhbA0KYnVyc3QsIGJ1dCB0aGlzIHdpbGwgbm90IGJlIHJlZmxlY3RlZCBpbiB0aGUgcmF3IGRhdGEuIFRoZSBmb2xsb3dpbmcgYXJlIHRoZQ0KcmVzdWx0cyBvZiB0aGUgcG9zdC1ob2MgdGVzdDogIA0KDQogIDEpIEZ1bGwgTm9ibGVzc2UgdnMuIGF0ay1hdGs6ICANCiAgICAgIFRoZXJlIGlzIHN0cm9uZyBldmlkZW5jZSAocD0wLjAwMCkgdG8gc3VnZ2VzdCB0aGF0IHRoZXJlIGlzIGEgZGlmZmVyZW5jZQ0KICAgICAgaW4gdGhlIG1lYW4gYXRrIG9mIFNoZW5oZXMgd2l0aCB0aGVzZSBzZXQgYm9udXNlcy4gVGhlIHNhbXBsZSBtZWFuDQogICAgICBkaWZmZXJlbmNlIGluIGF0ayBpcyBhbiBpbmNyZWFzZSBvZiA2NTkuMTMzIGF0ay4gVGhpcyBkaWZmZXJlbmNlIGhhcyBhDQogICAgICBsYXJnZSBhc3NvY2lhdGVkIGVmZmVjdCBzaXplICgxLjM2OCksIHdoaWNoIGluZGljYXRlcyBhbiBpbXBvcnRhbnQNCiAgICAgIGRpZmZlcmVuY2UgaW4gYXRrLiBUaGlzIGRpZmZlcmVuY2UgbWF5IG5vdCBiZSBhcyBsYXJnZSBpbiBwcmFjdGljZSwgYXMNCiAgICAgIHRoZSBhdGsgcHJvdmlkZWQgYnkgdGhlIDQtcGllY2UgTm9ibGVzc2UgT2JsaWdlIHNldCB3aGVuIGNhc3RpbmcgYSBidXJzdA0KICAgICAgaXMgZXF1YWwgdG8gMjAlIG9mIHRoZSB1c2VyJ3MgYmFzZSBhdGssIHdoaWNoIHdoZW4gY29tcGFyZWQgdG8gdGhlDQogICAgICB1bmNvbmRpdGlvbmFsIDM2JSBhdGsgcHJvdmlkZWQgYnkgYW4gYXRrLWF0ayBzZXQgaXMgc3RpbGwgaW1wb3J0YW50LiAgDQogICAgICANCiAgMikgRnVsbCBOb2JsZXNzZSB2cy4gRnVsbCBHbGFkaWF0b3I6ICANCiAgICAgIFRoZXJlIGlzIG5vIGV2aWRlbmNlIChwPTAuNzczKSB0byBzdWdnZXN0IHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlIGluDQogICAgICB0aGUgbWVhbiBhdGsgb2YgU2hlbmhlcyB3aXRoIHRoZXNlIHNldCBib251c2VzLiAgDQogIA0KICAzKSBGdWxsIE5vYmxlc3NlIHZzLiBwaHlzLWF0azogIA0KICAgICAgVGhlcmUgaXMgbm8gZXZpZGVuY2UgKHA9MC4xNzkpIHRvIHN1Z2dlc3QgdGhhdCB0aGVyZSBpcyBhIGRpZmZlcmVuY2UgaW4NCiAgICAgIHRoZSBtZWFuIGF0ayBvZiBTaGVuaGVzIHdpdGggdGhlc2Ugc2V0IGJvbnVzZXMuICANCiAgICAgIA0KICA0KSBGdWxsIE5vYmxlc3NlIHZzLiBhdGs6ICANCiAgICAgIFRoZXJlIGlzIHN0cm9uZyBldmlkZW5jZSAocD0wLjAwMykgdG8gc3VnZ2VzdCB0aGF0IHRoZXJlIGlzIGEgZGlmZmVyZW5jZQ0KICAgICAgaW4gdGhlIG1lYW4gYXRrIG9mIFNoZW5oZXMgd2l0aCB0aGVzZSBzZXQgYm9udXNlcy4gVGhlIHNhbXBsZSBtZWFuDQogICAgICBkaWZmZXJlbmNlIGluIGF0ayBpcyBhbiBpbmNyZWFzZSBvZiA3OTYuMDU2IGF0ay4gVGhpcyBkaWZmZXJlbmNlIGhhcyBhDQogICAgICBsYXJnZSBhc3NvY2lhdGVkIGVmZmVjdCBzaXplICgxLjY2NSksIHdoaWNoIGluZGljYXRlcyBhbiBpbXBvcnRhbnQNCiAgICAgIGRpZmZlcmVuY2UgaW4gYXRrLiBUaGlzIGlzIGFuIGltcG9ydGFudCBwbGFjZSB0byBlbXBoYXNpemUgdGhhdCB0aGVzZQ0KICAgICAgY29uY2x1c2lvbnMgb25seSBkZXNjcmliZSBhIGNvcnJlbGF0aXZlIHJlbGF0aW9uc2hpcCwgYmVjYXVzZSBhIHNpbmdsZQ0KICAgICAgMTglIGF0ayBib251cyBpcyBjZXJ0YWlubHkgbm90IGNhdXNhdGl2ZSBvZiBhIGxhcmdlciBpbmNyZWFzZSBpbiBhdGsNCiAgICAgIHRoYW4gYSAzNiUgYXRrIGJvbnVzLiBJdCBtYXkgYmUgdGhhdCBwbGF5ZXJzIGVxdWlwcGluZyBvbmx5IGEgc2luZ2xlDQogICAgICBhdGsgYm9udXMgc2V0IGhhZCBtdWNoIGhpZ2hlciBzdWJzdGF0IGludmVzdG1lbnQgb24gdGhlaXIgb3RoZXIgYXJ0aWZhY3RzLA0KICAgICAgbGVhZGluZyB0byBhIGhpZ2hlciBvdmVyYWxsIGF0ay4gT2JzZXJ2YXRpb25hbCBkYXRhIGNhbm5vdCBhbnN3ZXIgdGhlIA0KICAgICAgcXVlc3Rpb24gb2YgY2F1c2F0aW9uLCBhbmQgdW5mb3J0dW5hdGVseSB0aGVyZSBhcmUgZmV3IHdheXMgdG8gdXNlIGFuDQogICAgICBleHBlcmltZW50YWwgZGVzaWduIGluIGdhbWUgd2hpY2ggYWxzbyBpbmNsdWRlcyBhIGJyb2FkIHJhbmdlIG9mIHBsYXllcnMuICANCiAgICAgIA0KICA1KSBGdWxsIE5vYmxlc3NlIHZzLiBhdGstbm9ibGVzc2U6ICANCiAgICAgIFRoZXJlIGlzIG5vIGV2aWRlbmNlIChwPTAuMTk4KSB0byBzdWdnZXN0IHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlIGluDQogICAgICB0aGUgbWVhbiBhdGsgb2YgU2hlbmhlcyB3aXRoIHRoZXNlIHNldCBib251c2VzLiAgDQogICAgICANCiAgNikgRnVsbCBOb2JsZXNzZSB2cy4gY3J5by1hdGs6ICANCiAgICAgIFRoZXJlIGlzIG5vIGV2aWRlbmNlIChwPTAuODM0KSB0byBzdWdnZXN0IHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlIGluDQogICAgICB0aGUgbWVhbiBhdGsgb2YgU2hlbmhlcyB3aXRoIHRoZXNlIHNldCBib251c2VzLiAgDQogICAgICANCiAgNykgRnVsbCBOb2JsZXNzZSB2cy4gRnVsbCBCbGl6emFyZCBTdHJheWVyOiAgDQogICAgICBUaGVyZSBpcyBubyBldmlkZW5jZSAocD0wLjcyMCkgdG8gc3VnZ2VzdCB0aGF0IHRoZXJlIGlzIGEgZGlmZmVyZW5jZSBpbg0KICAgICAgdGhlIG1lYW4gYXRrIG9mIFNoZW5oZXMgd2l0aCB0aGVzZSBzZXQgYm9udXNlcy4gIA0KICAgIA0KICA4KSBGdWxsIE5vYmxlc3NlIHZzLiBjcnlvOiAgDQogICAgICBUaGVyZSBpcyBubyBldmlkZW5jZSAocD0wLjcxMCkgdG8gc3VnZ2VzdCB0aGF0IHRoZXJlIGlzIGEgZGlmZmVyZW5jZSBpbg0KICAgICAgdGhlIG1lYW4gYXRrIG9mIFNoZW5oZXMgd2l0aCB0aGVzZSBzZXQgYm9udXNlcy4gIA0KICANCiAgOSkgRnVsbCBOb2JsZXNzZSB2cy4gYXRrLUVNOiAgDQogICAgICBUaGVyZSBpcyBubyBldmlkZW5jZSAocD0wLjIxMykgdG8gc3VnZ2VzdCB0aGF0IHRoZXJlIGlzIGEgZGlmZmVyZW5jZSBpbg0KICAgICAgdGhlIG1lYW4gYXRrIG9mIFNoZW5oZXMgd2l0aCB0aGVzZSBzZXQgYm9udXNlcy4gIA0KICAgICAgDQogIDEwKSBGdWxsIE5vYmxlc3NlIHZzLiBGdWxsIEVtYmxlbTogIA0KICAgICAgVGhlcmUgaXMgbm8gZXZpZGVuY2UgKHA9MC44MzgpIHRvIHN1Z2dlc3QgdGhhdCB0aGVyZSBpcyBhIGRpZmZlcmVuY2UgaW4NCiAgICAgIHRoZSBtZWFuIGF0ayBvZiBTaGVuaGVzIHdpdGggdGhlc2Ugc2V0IGJvbnVzZXMuICANCiAgICAgIA0KICAxMSkgRnVsbCBOb2JsZXNzZSB2cy4gcGh5cy1waHlzOg0KICAgICAgVGhlcmUgaXMgbm8gZXZpZGVuY2UgKHA9MC4xOTUpIHRvIHN1Z2dlc3QgdGhhdCB0aGVyZSBpcyBhIGRpZmZlcmVuY2UgaW4NCiAgICAgIHRoZSBtZWFuIGF0ayBvZiBTaGVuaGVzIHdpdGggdGhlc2Ugc2V0IGJvbnVzZXMuICANCg0KDQpgYGB7ciBjb2RlLWNodW5rLWF0a192X1NldEJvbnVzfQ0Kc2V0LnNlZWQoMjcpDQoNCmFkaV9zYWlkaS5SUFQoc2hlbmhlJHNldF9ib251cywgc2hlbmhlJGF0aykNCmBgYA0KDQoNCg0KIyMjIEdlbmVyYWwgQ29uY2x1c2lvbg0KDQogIFRoZSB0aHJlZSBtb3N0IGNvbW1vbiBwb2xlYXJtIGNob2ljZXMgZm9yIHRoZSBzYW1wbGUgb2YgZnVsbHkgYnVpbHQgU2hlbmhlcyBvbiANCmRpc3BsYXkgd2VyZSwgaW4gb3JkZXIsIEZhdm9uaXVzIExhbmNlLCBDYWxhbWl0eSBRdWVsbGVyLCBhbmQgU2t5d2FyZCBTcGluZSwgDQp3aGljaCBhbHNvIGFyZ3VhYmx5IGZpdHMgdGhlIHJhbmtpbmcgb2YgYmVzdCBwb2xlYXJtcyBmb3IgU2hlbmhlIG92ZXJhbGwuICANCg0KICBUaGUgbW9zdCBjb21tb24gc2V0IGJvbnVzIGJ5IGZhciB3YXMgYW4gYXRrLWF0ayBzZXR1cCwgd2hpY2ggaXMgZ2VuZXJhbGx5IG5vdA0KcmVjb21tZW5kZWQgYnkgS1FNLCBidXQgcHJvdmVkIHRvIGNvbnRhaW4gdGhlIGhpZ2hlc3QgYXRrIG91dCBvZiBhbGwgdGhlIHNldA0KYm9udXNlcy4gVGhlIHNlY29uZCBtb3N0IGNvbW1vbiBzZXQgYm9udXMgd2FzIHRoZSBmb3VyIHBpZWNlIE5vYmxlc3NlIE9ibGlnZSwNCndoaWNoIGlzIEtRTSdzIHJlY29tbWVuZGF0aW9uIGZvciBTaGVuaGUuICANCg0KICBUaGUgZGF0YSBwcm92aWRlZCBldmlkZW5jZSBmb3IgYSBkaWZmZXJlbmNlIGluIG1lYW4gRVIgYW5kIGF0ayBieSB2YXJpb3VzIA0KcG9sZWFybSB0eXBlcywgd2hlcmVhcyB0aGUgZGF0YSBvbmx5IHByb3ZpZGVkIGV2aWRlbmNlIGZvciBhIGRpZmZlcmVuY2UgaW4gbWVhbg0KYXRrIGJ5IG9uZSBtYWpvciBzZXQgYm9udXMgdHlwZSwgdXNpbmcgdGhlIEZhdm9uaXVzIExhbmNlIGFuZCBOb2JsZXNzZSBPYmxpZ2UNCmFzIHJlZmVyZW5jZSBmcmFtZXMgaW4gZWFjaCBjYXNlLiAgDQoNCiMjIyBRdWFudGl0YXRpdmUgQ29uY2x1c2lvbg0KDQogIFRoZSBzaWduaWZpY2FudCBkaWZmZXJlbmNlcyB3aXRoaW4gdGhlIGNsZWFuZWQgZGF0YXNldCBhcmUgYXMgZm9sbG93czogIA0KICANCiAgICBhdGs6ICANCiAgICANCiAgICAgIDEpIEZhdm9uaXVzIExhbmNlIHZzLiBXYXZlYnJlYWtlcidzIEZpbiAocCA9IDAuMDAxLCBFUyA9IDEuMDA5KSAgDQogICAgICANCiAgICAgIDIpIEZhdm9uaXVzIExhbmNlIHZzLiBTa3l3YXJkIFNwaW5lIChwID0gMC4wMDAsIEVTID0gMS4zMDMpICANCiAgICAgIA0KICAgICAgMykgRmF2b25pdXMgTGFuY2UgdnMuIENhbGFtaXR5IFF1ZWxsZXIgKHAgPSAwLjAwMCwgRVMgPSAxLjE2MykgIA0KICAgICAgDQogICAgICA0KSBGYXZvbml1cyBMYW5jZSB2cy4gTWlzc2l2ZSBXaW5kc3BlYXIgKHAgPSAwLjAwNSwgMC44OTgpICANCiAgICAgIA0KICAgICAgNSkgRmF2b25pdXMgTGFuY2UgdnMuIFByaW1vcmRpYWwgSmFkZSBXaW5nZWQgU3BlYXIgKHAgPSAwLjAwMiwgRVMgPSAxLjA1NikgIA0KICAgICAgDQogICAgICA2KSBGYXZvbml1cyBMYW5jZSB2cy4gVm9ydGV4IFZhbnF1aXNoZXIgKHAgPSAwLjAxNywgRVMgPSAxLjY1MikgIA0KICAgICAgDQogICAgICA3KSBGdWxsIE5vYmxlc3NlIHZzLiBhdGstYXRrIChwID0gMC4wMDAsIEVTID0gMS4zNjgpICANCiAgICAgIA0KICAgICAgOCkgRnVsbCBOb2JsZXNzZSB2cy4gYXRrIChwID0gMC4wMDMsIEVTID0gMS42NjUpICANCiAgICAgIA0KICAgIEVSOiAgDQogICAgDQogICAgICAxKSBGYXZvbml1cyBMYW5jZSB2cy4gV2F2ZWJyZWFrZXIncyBGaW4gKHAgPSAwLjAyNSwgRVMgPSAtMC43MTgpICANCiAgICAgIA0KICAgICAgMikgRmF2b25pdXMgTGFuY2UgdnMuIFNreXdhcmQgU3BpbmUgKHAgPSAwLjA0NCwgRVMgPSAwLjYzMCkgIA0KICAgICAgDQogICAgICAzKSBGYXZvbml1cyBMYW5jZSB2cy4gQ2FsYW1pdHkgUXVlbGxlciAocCA9IDAuMDA5LCBFUyA9IDAuNjEwKSAgDQogICAgICANCiAgICAgIDQpIEZhdm9uaXVzIExhbmNlIHZzLiBNaXNzaXZlIFdpbmRzcGVhciAocCA9IDAuMDAwLCBFUyA9IC0xLjAxMykgIA0KICAgICAgDQogICAgICA1KSBGYXZvbml1cyBMYW5jZSB2cy4gTGl0aGljIFNwZWFyIChwID0gMC4wMTEsIEVTID0gLTEuMjMwKSAgDQogICAgICANCiAgICAgIDYpIEZhdm9uaXVzIExhbmNlIHZzLiBFbmd1bGZpbmcgTGlnaHRuaW5nIChwID0gMC4wMDgsIEVTID0gMS42ODMpICANCiAgICAgIA0KICAgICAgNykgRmF2b25pdXMgTGFuY2UgdnMuIFByaW1vcmRpYWwgSmFkZSBXaW5nZWQgU3BlYXIgKHAgPSAwLjAwOSwgRVMgPSAtMC44ODIpICANCiAgICAgIA0KICAgICAgOCkgRmF2b25pdXMgTGFuY2UgdnMuIFZvcnRleCBWYW5xdWlzaGVyIChwID0gMC4wNDYsIEVTID0gLTEuNTczKSAgDQogICAgICANCiAgICAgIDkpIEZhdm9uaXVzIExhbmNlIHZzLiBEZWF0aG1hdGNoIChwID0gMC4wMDAsIEVTID0gLTIuMDI4KSAgDQogICAgICANCiAgVGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGFyZSBhcyBmb2xsb3dzOiAgDQogIA0KICAgIDEpIFtmdWxsIG5vYmxlc3NlIGF0a106ICAyNTQ0Ljc0NCAyOTQ5LjgxMiAgDQogICAgDQogICAgMikgW2Z1bGwgbm9ibGVzc2UgRVJdOiAgIDE0OS4zNjc2IDE4MC42MjEzICANCiAgICANCiAgICAzKSBbRmF2b25pdXMgTGFuY2UgYXRrXTogMjY4NS44MzYgMjk5MC4wMTYgIA0KICAgIA0KICAgIDQpIFtGYXZvbml1cyBMYW5jZSBFUl06ICAxNTQuNzc0OSAxNzMuMDkxNyAgDQogICAgDQogICAgNSkgW2F0ay1hdGsgc2V0IEVSXTogICAgIDE0NS44MTA4IDE1Ni45MDcwICANCiAgICANCiAgICA2KSBbb3ZlcmFsbCBhdGtdOiAgICAgICAgMzEyOS45MjIgMzMwMS43MTYgIA0KICAgIA0KICAgIDcpIFtvdmVyYWxsIEVSXTogICAgICAgICAxNDYuOTY1NSAxNTYuNTMyNSAgDQogICAgDQogICAgOCkgW292ZXJhbGwgRVJfcmVxX21ldF06IDAuMTc4MTQzIDAuMzE4NTAxICANCg0KIyMjIEludGVycHJldGF0aW9ucw0KDQogIFRoZSBtYWpvcml0eSBvZiBmdWxseSBidWlsdCBTaGVuaGVzIG9uIGRpc3BsYXkgKGJldHdlZW4gMC4xNzggYW5kIDAuMzE5KSBkbw0Kbm90IG1lZXQgS1FNJ3MgZW5lcmd5IHJlcXVpcmVtZW50cy4gVGhpcyBjb3VsZCBwb3NzaWJseSBpbmRpY2F0ZXMgYSBzZXZlcmUgDQptaXN1bmRlcnN0YW5kaW5nIG9mIFNoZW5oZSdzIHJvbGUgYXMgYSBjaGFyYWN0ZXIgYnkgdGhlIGNvbW11bml0eSBhdCBsYXJnZSwgb3INCmNvdWxkIGRlbW9uc3RyYXRlIGEgdGVuZGVuY3kgb2YgcGxheWVycyB0byBtYXhpbWl6ZSB0aGUgbW9zdCBzZWVtaW5nbHkgaW1wb3J0YW50DQpzdGF0cywgd2hpbGUgbmVnbGVjdGluZyBzbW9vdGggcm90YXRpb25zIGFuZCBjb25zaXN0ZW50IGRhbWFnZS4gIA0KDQogIFdpdGggcmVzcGVjdCB0byBnZWFyIGluIHRoZSBwbGF5ZXIncyBjb250cm9sLCBDYWxhbWl0eSBxdWVsbGVyLCBTa3l3YXJkIFNwaW5lLA0KYW5kIFZvcnRleCBWYW5xdWlzaGVyIHdlcmUgY29ycmVsYXRlZCB3aXRoIHRoZSBsYXJnZXN0IGF0ayBpbmNyZWFzZSBmcm9tIEZhdm9uaXVzDQpMYW5jZS4gQW4gYXRrLWF0ayBzZXQgYm9udXMgd2FzIGNvcnJlbGF0ZWQgd2l0aCBhIHNpbWlsYXIgaW5jcmVhc2UgaW4gYXRrIGZyb20gDQp0aGUgZnVsbCBOb2JsZXNzZSBPYmxpZ2Ugc2V0LiBBZGRpdGlvbmFsbHksIEVuZ3VsZmluZyBMaWdodG5pbmcsIFNreXdhcmQgU3BpbmUsDQphbmQgQ2FsYW1pdHkgUXVlbGxlciB3ZXJlIGNvcnJlbGF0ZWQgd2l0aCBpbmNyZWFzZXMgaW4gRVIuIFRoaXMgaW5mb3JtYXRpb24gY2FuDQpiZSB1c2VkIHRvIGNvbnN0cnVjdCBhIGZpbmFsIHJhbmtpbmcgb2YgZ2VhciB3aXRoaW4gdGhlIGRhdGFzZXQuICANCg0KICBCZWNhdXNlIHRoZSB1cHBlciBib3VuZCBvZiB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgdGhlIEVSIG9mIFNoZW5oZXMgZXF1aXBwaW5nIA0KdGhlIGZ1bGwgTm9ibGVzc2UgU2V0IGluY2x1ZGVzIHRoZSBsb3dlciBsaW1pdCBvZiBTaGVuaGUncyBFUiByZXF1aXJlbWVudCwgaXQgDQpnZW5lcmFsbHkgcGxhY2VzIGhpZ2hlciBpbiB0aGUgcmFua2luZyBvZiBnZWFyLCBkZXNwaXRlIGF0ay1hdGsgaGF2aW5nIGFuIG92ZXJhbGwgDQpoaWdoZXIgYXRrIHN0YXQgd2l0aGluIHRoZSBkYXRhc2V0LiANCg0KICBBcyBwcmV2aW91c2x5IGRpc2N1c3NlZCwgdGhlIENhbGFtaXR5IFF1ZWxsZXIncyBsYXJnZSBleHRyYSBhdHRhY2sgd2l0aCByZWZlcmVuY2UgDQp0byB0aGUgRmF2b25pdXMgTGFuY2UsIGFzIHdlbGwgYXMgaXQgaGF2aW5nIGEgaGlnaGVyIHBvcHVsYXRpb24gbWVhbiBFUiBzdGF0IGFzIA0KZGVkdWNlZCBmcm9tIHRoZSBoeXBvdGhlc2lzIHRlc3RpbmcgcmVzdWx0cyBpbiBpdCBwbGFjaW5nIGF0IHRoZSB0b3Agb2YgdGhlIGxpc3QuIA0KRW5ndWxmaW5nIExpZ2h0bmluZyBpcyBzbGlnaHRseSB3b3JzZSB0aGFuIHRoZSBGYXZvbml1cyBMYW5jZSBvdmVyYWxsLCBiZWNhdXNlIA0KdGhlIEZhdm9uaXVzIExhbmNlIHByb3ZpZGVzIGVuZXJneSB0byB0aGUgd2hvbGUgdGVhbSBmcm9tIGl0cyBwYXNzaXZlLCBhbmQgdGhlcmUNCndhcyBubyBldmlkZW5jZSBmcm9tIHRoZSBkYXRhIHRvIHN1Z2dlc3QgdGhhdCB0aGVyZSBpcyBhbnkgZGlmZmVyZW5jZSBpbiBtZWFuIGF0ayANCmJldHdlZW4gdGhlIHR3by4gVGhlIHNreXdhcmQgc3BpbmUgcmFua3MgaGlnaGVyIHRoYW4gdGhlIEVuZ3VsZmluZyBsaWdodG5pbmcsDQpiZWNhdXNlIGl0IG1hbmFnZXMgdG8gaGF2ZSBhIGhpZ2hlciBtZWFuIGF0ayB3aGlsZSBhbHNvIGhhdmluZyBhIGRlY2VudCBidW1wIGluDQpFUiBmcm9tIHRoZSBGYXZvbml1cyBMYW5jZSwgYW5kIHJhbmtzIGhpZ2hlciB0aGFuIEZhdm9uaXVzIGFzIHdlbGwsIGJlY2F1c2UgdGhlDQpleHRyYSBhdGsgaXMgY29tcGFyYWJsZSB0byB0aGF0IG9mIENhbGFtaXR5IFF1ZWxsZXIncy4gVGhlIGZpbmFsIG9yZGVyaW5nIG9mIA0KZ2VhciBpcyBhcyBmb2xsb3dzOiAgDQoNCiAgRm9yIEFydGlmYWN0czogIA0KICANCiAgICAxKSBGdWxsIE5vYmxlc3NlICANCiAgICANCiAgICAyKSBhdGstYXRrICANCiAgICANCiAgICAzKSBBbGwgT3RoZXJzDQogICAgDQogIEZvciBQb2xlYXJtczogIA0KICANCiAgICAxKSBDYWxhbWl0eSBRdWVsbGVyICANCiAgICANCiAgICAyKSBTa3l3YXJkIFNwaW5lICANCiAgICANCiAgICAzKSBGYXZvbml1cyBMYW5jZSAgDQogICAgDQogICAgNCkgRW5ndWxmaW5nIExpZ2h0bmluZyAgDQogICAgDQogIFdoZXJlIHRoZXNlIHJhbmtpbmdzIGFwcGx5IGZvciBTaGVuaGVzIGludGVuZGVkIHRvIGJlIGJ1aWxkIGFzIHN1cHBvcnRzLCBhbmQNCm5vdCBmb3IgdGhlaXIgb3duIHBlcnNvbmFsIGRhbWFnZS4gVWx0aW1hdGVseSwgdGhlc2UgcmFua2luZ3MgaGF2ZSBubyBzdGFuZGluZw0KaW4gcHJhY3RpY2UsIGJlY2F1c2UgdGhleSBvbmx5IGRlc2NyaWJlIFNoZW5oZXMgb24gZGlzcGxheSwgYW5kIGRvIG5vdCBwcm92aWRlDQphbnkgYmFzaXMgZm9yIGdlYXIgcmVjb21tZW5kYXRpb25zLiAgDQoNCiMjIyBDb21tZW50cyBvbiB0aGUgQW5hbHlzaXMNCg0KICBJZiBJIGNvdWxkIHJlZG8gdGhpcyBwcm9jZXNzIG9mIGRhdGEgY29sbGVjdGlvbiBhbmQgYW5hbHlzaXMsIHRoZXJlIHdvdWxkIGJlDQptYW55IHRoaW5ncyBJIHdvdWxkIGNoYW5nZS4gSXQgZ29lcyB3aXRob3V0IHNheWluZyB0aGF0IGlmIGFuIGV4cGVyaW1lbnRhbA0KZGVzaWduIHdlcmUgcG9zc2libGUgZm9yIHRoaXMgdHlwZSBvZiBzdHVkeSwgdGhlbiBJIHdvdWxkIG11Y2ggcHJlZmVyIGl0IGluDQpvcmRlciB0byBjcmVhdGUgYSBtb3JlIHVuZXF1aXZvY2FsIHJhbmtpbmcgb2YgZ2VhciwgYW5kIGFsc28gcHJvdmlkZSBjb25jcmV0ZQ0KcmVjb21tZW5kYXRpb25zIHRvIHVzZXJzLiBUaGlzIGFuYWx5c2lzIHdhcyBoZWxwZnVsIGluIG9ic2VydmluZyBwYXR0ZXJucyBmcm9tDQp1c2VycywgYnV0IHVsdGltYXRlbHkgZGlkIG5vdCBleHRyYWN0IGFueSBub3ZlbCBpbmZvcm1hdGlvbiBvbiBjYXVzYXRpb24uICANCg0KICBGaXJzdGx5LCBJIHdpc2ggSSBoYWQgaW5jbHVkZWQgbm90IG9ubHkgdGhlIGxldmVsLCBidXQgdGhlIGFzY2Vuc2lvbiByYW5rIG9mIA0KdGhlIGNoYXJhY3RlcnMgYW5kIHRoZSBwb2xlYXJtcy4gVGhpcyB3b3VsZCBoYXZlIHByb3ZpZGVkIG1vcmUgZGV0YWlsZWQgDQppbmZvcm1hdGlvbiBvbiB0aGUgc3RhdHMgb2YgdGhlIGNoYXJhY3RlcnMsIGFuZCBjb3VsZCBoYXZlIGhlbHBlZCB0byBmaW5lIHR1bmUgDQp0aGUgZXhjbHVzaW9uIGNyaXRlcmlhIGZ1cnRoZXIuIFRoaXMgbWF5IGhhdmUgYWxzbyBjcmVhdGVkIGFuIG9wZW5pbmcgdG8gcGVyZm9ybQ0KbXVsdGlwbGUgbGluZWFyIHJlZ3Jlc3Npb24gZm9yIHRoZSBFUiBzdGF0LCBhbmQgbG9naXN0aWMgcmVncmVzc2lvbiBmb3IgdGhlDQpFUiByZXF1aXJlbWVudCB2YXJpYWJsZS4gIA0KDQogIFNlY29uZGx5LCBJIHdpc2ggSSBoYWQgaW5jbHVkZWQgYWxsIHBvc3NpYmxlIGluZm9ybWF0aW9uIGZyb20gdGhlIHVzZXIncyBwcm9maWxlLA0Kc3VjaCBhcyB0aGVpciBwcm9ncmVzc2lvbiBpbiB0aGUgU3BpcmFsIEFieXNzLCBiZWNhdXNlIEkgdGhlbiBjb3VsZCBoYXZlIHRyaWVkDQp0byB1c2UgbG9naXN0aWMgcmVncmVzc2lvbiB0byBjcmVhdGUgYSBtb2RlbCBwcmVkaWN0aW5nIHdoZXRoZXIgb3Igbm90IHRoZXkgaGFkDQpjbGVhcmVkIHRoZSBhYnlzcy4gIA0KDQogIFRoaXJkbHksIEkgd2lzaCBJIGhhZCBpbmNsdWRlZCBhIHZhcmlhYmxlIHdoaWNoIHByb3ZpZGVkIGEgc2FtcGxlIGRhbWFnZQ0Kb3V0cHV0IGdpdmVuIHRoZSBzdGF0cyB0aGUgU2hlbmhlIGhhZC4gVGhpcyBjb3VsZCBoYXZlIGJlZW4gcGVyZm9ybWVkIHVzaW5nDQp0aGUgZGFtYWdlIGNhbGN1bGF0b3IgdG9vbHMgYXZhaWxhYmxlIG9ubGluZSwgYW5kIEkgY291bGQgaGF2ZSB1c2VkIGEgZm9ybXVsYQ0KaW4gYW4gRXhjZWwgb3IgR29vZ2xlIHNwcmVhZHNoZWV0IHRvIGF1dG9maWxsIHRoZXNlIHZhbHVlcyBmb3IgbWUuIFRoaXMgY291bGQNCmhhdmUgYmVlbiwgZm9yIGV4YW1wbGUsIGEgdGVhbSByb3RhdGlvbiBkYW1hZ2Ugb24gYW4gQXlha2EgLyBLYXp1aGEgLyBTaGVuaGUgLw0KS29rb21pIGNvbXBvc2l0aW9uLiBUaGlzIHF1YW50aXRhdGl2ZSB2YXJpYWJsZSBjb3VsZCBoYXZlIGJlZW4gdXNlZCBhcyBhIHJlc3BvbnNlDQp2YXJpYWJsZSB0byBhIHRyZWF0bWVudCBzdWNoIGFzIHRoZSAicG9sZWFybV9uYW1lIiBvciAic2V0X2JvbnVzIiB2YXJpYWJsZXMsIGFuZA0KSSBjb3VsZCBoYXZlIHRoZXJlYnkgY29uZHVjdGVkIGRpcmVjdCBhbmFseXNpcyBvbiB0aGUgRGFtYWdlIG91dHB1dHMgYmVpbmcgY2hhbmdlZA0KYnkgU2hlbmhlJ3Mgc3RhdHMuICANCg0KICBGb3VydGhseSwgYXMgYWxsIHJlc2VhcmNoZXJzIGhvcGUsIEkgd2lzaCBJIGNvdWxkIGhhdmUgb2J0YWluZWQgYSBsYXJnZXIgc2FtcGxlLA0KZXNwZWNpYWxseSBmb3IgcmFyZSBjYXNlcyBzdWNoIGFzIEVuZ3VsZmluZyBMaWdodG5pbmcsIHNvIHRoYXQgSSBjb3VsZCBiZSBtb3JlDQpzdXJlIG9mIHRoZSB0cnVlIG1lYW4gZGlmZmVyZW5jZSBhbmQgZWZmZWN0LiBUaGlzIHdvdWxkIGhhdmUgYWxzbyBhbGxvd2VkIG1lIHRvDQphcHBseSB0aGUgY2VudHJhbCBsaW1pdCB0aGVvcmVtLCBhbmQgdXNlIGEgdC10ZXN0IG9yIG90aGVyIHBhcmFtZXRyaWMgdGVzdHMsDQpicm9hZGVuaW5nIHRoZSB0b29scyBhdCBteSBkaXNwb3NhbC4gIA0KDQogIEkgYW0gb3ZlcmFsbCB2ZXJ5IGhhcHB5IHdpdGggdGhpcyBwcm9qZWN0LCBhbmQgSSBiZWxpZXZlIEkgaGF2ZSBkZWVwZW5lZCBteQ0KdW5kZXJzdGFuZGluZyBvZiB1c2luZyBSIGZvciBkYXRhIGFuYWx5c2lzIHByb2ZvdW5kbHksIGJ1dCB0aGUgc291cmNlcyBvZiBlcnJvcg0KYW5kIGRlZmljaWVuY2llcyBvZiB0aGUgZGF0YSByZW1haW4sIHN1Y2ggYXMgdGhlIHZvbHVudGFyeSBiaWFzIGluIHRoZSBzYW1wbGluZywNCnRoZSBsYWNrIG9mIGNvbnRyb2xzLCBhbmQgdGhlIG1pc3NpbmcgZGF0YSBhYm91dCBhc2NlbnNpb24gcmFua3MuIEkgZmVlbCB0aGF0DQpteSBxdWVzdGlvbnMgYWJvdXQgZGFtYWdlIG91dHB1dCBhbmQgY29ycmVsYXRpb24gb2YgYWxsIHZhcmlhYmxlcyByZW1haW4NCnVuYW5zd2VyZWQsIGJ1dCBwZXJoYXBzIGluIGEgZnV0dXJlIHN0dWR5IG9mIFNoZW5oZSwgb3IgYSBkaWZmZXJlbnQgY2hhcmFjdGVyDQplbnRpcmVseSwgSSBjb3VsZCB1c2UgdGhlIGNvbnRlbnQgZnJvbSBtdWx0aXBsZSBsaW5lYXIgcmVncmVzc2lvbiBhbmQgdGhlIEYtDQpkaXN0cmlidXRpb24gdG8gYW5zd2VyIG15IHF1YW50aXRhdGl2ZS1xdWFudGl0YXRpdmUgcmVsYXRpb25zaGlwIHF1ZXN0aW9ucy4gIA0KDQojIyMgUmVmZXJlbmNlcw0KDQpDby1vcCBtb2RlLiBHZW5zaGluIEltcGFjdCBXaWtpLiAobi5kLikuIFJldHJpZXZlZCBEZWNlbWJlciAxNCwgMjAyMiwgZnJvbSBodHRwczovL2dlbnNoaW4taW1wYWN0LmZhbmRvbS5jb20vd2lraS9Dby1PcF9Nb2RlICANCg0KS2F6dWhhIEVNIHZzLiBFUiB8IFRoZSBHVU9CQSBQcm9qZWN0LiAobi5kLikuIEd1b2JhLmtlcWluZ21haW5zLmNvbTsgWWFtaSM4NTkxLiBSZXRyaWV2ZWQgRGVjZW1iZXIgMTQsIDIwMjIsIGZyb20gaHR0cHM6Ly9ndW9iYS5rZXFpbmdtYWlucy5jb20vZXhwZXJpbWVudHMva2F6dWhhLWVtLWVyICANCg0KUGV0cm92LCBTLiAoMjAyMSwgQXByaWwgMjYpLiBQZXJtdXRhdGlvbiB0ZXN0IGluIFIuIE1lZGl1bS4gUmV0cmlldmVkIERlY2VtYmVyIDE1LCAyMDIyLCBmcm9tIGh0dHBzOi8vdG93YXJkc2RhdGFzY2llbmNlLmNvbS9wZXJtdXRhdGlvbi10ZXN0LWluLXItNzdkNTUxYTlmODkxICANCg0KU2hlbmhlIHwgS1FNIFRDTC4gKG4uZC4pLiBMaWJyYXJ5LmtlcWluZ21haW5zLmNvbTsgWWFtaSM4NTkxLiBSZXRyaWV2ZWQgRGVjZW1iZXIgMTQsIDIwMjIsIGZyb20gaHR0cHM6Ly9saWJyYXJ5LmtlcWluZ21haW5zLmNvbS9jaGFyYWN0ZXJzL2NyeW8vc2hlbmhlICANCg0KWGVub1ZYIzYxNTAsIFphbW8jNjM5OSwgS0IjMTExMSwgQXBvbGxvSVYjODE3NywgJiBTaXRyaSM5NTA0LiAoMjAyMiwgRmVicnVhcnkgMTApLiBTaGVuaGUgR3VpZGU6IFRoZSBEaXZpbmUgRGFtc2VsIG9mIERldmFzdGF0aW9uLiBLUU07IFlhbWkjODU5MS4gaHR0cHM6Ly9rZXFpbmdtYWlucy5jb20vc2hlbmhlLyAgDQoNClpha2hhcm92LiAobi5kLikuIEVuZXJneSBSZWNoYXJnZSBDYWxjdWxhdG9yLiBHb29nbGUgRG9jczsgWWFtaSM4NTkxLiBSZXRyaWV2ZWQgRGVjZW1iZXIgMTQsIDIwMjIsIGZyb20gaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vc3ByZWFkc2hlZXRzL2QvMS12a21ncDVuMGJJOXB2aFVnMTEwQXphM0VtYjJwdUxXZGVvQ2dyeERsdTQvZWRpdCNnaWQ9NjUxNzYyOTM3ICANCg0KIyMjIFNwZWNpYWwgTWVudGlvbnMNCg0KVGhhbmtzIHRvIFJhaXplbCBEYXZpcyBhbmQgUHJvZmVzc29yIFJhY2hlbCBTYWlkaSBmb3IgaGVscGluZyB3aXRoIHRoZSBjb2RlIGZvcg0KdGhlIHJhbmRvbWl6YXRpb24gcG9zdC1ob2MgdGVzdCwgYW5kIGZvciB0aGUgbW90aXZhdGlvbiB0byBhcHBseSBteSBpbnR1aXRpb24NCmZvciBjb2RpbmcgdG8gZGF0YSBzY2llbmNlLiBUaGlzIHByb2plY3QgaGFzIHJldmVhbGVkIHRvIG1lIGhvdyBtdWNoIEkgbG92ZSBib3RoDQpjb2RpbmcgYW5kIGRhdGEgc2NpZW5jZSwgd2hpY2ggd2VyZSBib3RoIHN1YmplY3RzIEkgcHJldmlvdXNseSBiZWxpZXZlZCBJIGRlc3Bpc2VkLg0KTm93LCBJIGFtIGV4Y2l0ZWQgdG8gZG8gYSBwcm9qZWN0IGxpa2UgdGhpcyBhbGwgb3ZlciBhZ2FpbiwgYW5kIHRoYXQgd291bGRuJ3QNCmJlIHRydWUgd2l0aG91dCBlaXRoZXIgb2YgdGhlaXIgc3VwcG9ydCB0aHJvdWdoIHRoaXMgcHJvY2Vzcy4=