© 2018 Gede Primahadi Wijaya Rajeg
ORCID iD iconorcid.org/0000-0002-2047-8621

Creative Commons License

Preface

This is an R Markdown Notebook documenting how the codes in the happyr package (Rajeg, 2019a) are used for the statistical analyses in Rajeg’s (2019b) PhD thesis. The study focuses on metaphors for happiness near-synonyms in Indonesian. The underlying R Markdown (.Rmd) file of the notebook also includes the in-line codes to generate numeric results in the chunks of the body-text of the relevant chapters. Thus, not all body-text of the thesis are included in this notebook. Note that there can be some differences in the wordings and arrangement between the narative in this notebook and in the final version of the thesis, but not with the quantitative analysis.

This R notebook is licensed under the Creative Common License CC BY-NC-SA 4.0. To download the raw .Rmd file of the notebook, go to the top right corner of the page (next to the title), click the Code drop-down button, and then click Download Rmd option. To unfold and see the content of the R code chunks, click on the Code button.

How to cite this notebook repository (in “DataCite” style)

Rajeg, Gede Primahadi Wijaya (2019): R Notebook for Metaphorical profiles and near-synonyms: A corpus-based study of Indonesian words for happiness. figshare. Code. doi: https://doi.org/10.26180/5cb65c06b1b17.

Acknowledgement

The thesis is supervised by Associate Professor Alice Gaby (main), Dr. Howard Manns (associate), and Dr. Simon Musgrave (associate). The panel members during the author’s candidature milestones consist of Dr. Anna Margetts, Dr. Réka Benczes, and Prof. John Newman. The thesis is fully funded by Monash University, Australia, through the International Graduate Research Scholarships: (i) Monash International Postgraduate Research Scholarships (MIPRS) and (ii) Monash Graduate Scholarships (MGS). The author also benefits from the generous research funding from the Monash Graduate Education and the Arts Graduate Research of Monash University.

library(happyr)
suppressPackageStartupMessages(library(bookdown))
suppressPackageStartupMessages(library(tidyverse))

1 Codes for Chapter 3 - Interrater Agreement

1.1 Results for constructional patterns

# kappa calculation
irr_cxn <- happyr::kappa_tidy(df = happyr::df_cxn_pattern,
                              var_names = "^pattern",
                              round = "pre_disc")

The Kappa scores in Table @ref(tab:kappa-cxn) for the constructional pattern annotation show high level of agreements for the first round (i.e., the pre-disc[ussion stage]) (\(\mu\)1 = 0.87, \(\sigma\) = 0.03).

# print the result of interrater-agreement for the construction
irr_cxn %>%
  mutate(words = paste("*", words, "*", sep = ""),
         gloss = c("happiness", "joy", "pleasure"),
         kappa = round(kappa, 2L)) %>% 
  select(words, gloss, everything()) %>% 
  knitr::kable(caption = "Cohen's Kappa for the Constructional Patterns identification", row.names = TRUE)
words gloss rater cases kappa round
1 kebahagiaan happiness 2 100 0.85 pre_disc
2 kegembiraan joy 2 100 0.86 pre_disc
3 kesenangan pleasure 2 100 0.91 pre_disc

Figure @ref(fig:kappa-cxn-figure) summarises the distribution of the most frequent constructional patterns for the agreed cases, occurring at least five tokens.

happyr::plot_cxn_interrater(df = happyr::top_cxn_data) +
  labs(title = expression(paste("Distribution of the constructional patterns for the agreed cases (", N["patterns"] >= "5)", sep = "")),
       caption = "The values inside the bars are the patterns' token frequencies")

The values inside the bars represents the token frequency of the patterns. The ‘lex-…’ part in the legend indicates the syntactic, constructional collocates of the target domain words (the ‘T-…’ part) that potentially evoke the metaphorical source frames. The constructional patterns in the legend are in descending order from the most to the least frequent types among these top constructions. These types are exemplified in order below.

  1. Bagi konsumen yang memburu kesenangan sesaat (lex-verb_T-dobj) (ind_newscrawl2011_1M:621419)
  2. kebahagiaan memuncak setelah para penari dan penonton memainkan permainan seremonial kuno (T-subj_lex-verb) (ind_newscrawl2012_1M:910372)
  3. menjadikan manusia sebagai budak kesenangan (lex-noun_T-noun) (ind_newscrawl2012_1M:7767)
  4. dalam kesenangan tentu ada kesusahannya (lex-prep_T-noun) (ind_web2012_1M:302089)
  5. hidup dunia sangatlah penting kalau dijadikan persiapan untuk kebahagiaan akhirat (T-noun_lex-noun) (ind_mixed2012_1M:406885)

1.2 Results for metaphoricity of the patterns

The next task is to identify whether the extracted and agreed constructional patterns of the synonyms evoke metaphorical readings or not. For this task, we expected the agreement would be lower than in the previous task as determining metaphorical usages is more subjective. The results are shown in Table @ref(tab:kappa-metaphor).

# kappa calculation first round
irr_use_1 <- happyr::kappa_tidy(df = happyr::df_meta_use_1st,
                                var_names = "^use_(coder|author)$",
                                round = "pre_disc") %>% 
  mutate(words = paste("*", words, "*", sep = ""),
         gloss = c("happiness", "joy", "pleasure"),
         kappa = round(kappa, 2L)) %>% 
  select(words, gloss, everything())
# kappa calculation second round
irr_use_2 <- happyr::kappa_tidy(df = happyr::df_meta_use_2nd,
                                var_names = "^use_2nd_",
                                round = "post_disc") %>% 
  mutate(words = paste("*", words, "*", sep = ""),
         gloss = c("happiness", "joy", "pleasure"),
         kappa = round(kappa, 2L)) %>% 
  select(words, gloss, everything())
irr_use_2 %>% 
  bind_rows(irr_use_1) %>% 
  knitr::kable(caption = "Cohen's Kappa for the Metaphor Identification (post- and pre-discussion stages)", row.names = TRUE)
words gloss rater cases kappa round
1 kebahagiaan happiness 2 85 0.73 post_disc
2 kegembiraan joy 2 86 0.63 post_disc
3 kesenangan pleasure 2 91 0.75 post_disc
4 kebahagiaan happiness 2 85 0.56 pre_disc
5 kegembiraan joy 2 86 0.35 pre_disc
6 kesenangan pleasure 2 91 0.61 pre_disc

In the first round, as expected, the average agreement across the three synonyms is moderate (\(\mu\) = 0.51, \(\sigma\) = 0.14). Differences were resolved in the discussion round.

One of the prominent differences is that the second coder annotated patterns referring to temporal aspect of the synonyms as metaphorical, while time itself is often understood in metaphorical concepts (e.g., Boroditsky & Ramscar, 2002). The patterns include NPemo abadieternal NPemo’, NPemo ditunda ‘NPemo be delayed/postponed, menunda NPemo ’to delay/postpone NPemo’, NPemo bertahan/berlangsung lama ‘NPemo lasts long’, NPemo berlangsung sesaat ‘NPemo lasts for a while’, and NPemo hanya sementara ‘NPemo is just for a while’.

With the remaining unresolved differences, the second Kappa was calculated, and the mean Kappa increases to substantial agreement (\(\mu\) = 0.7, \(\sigma\) = 0.06).

1.3 Results for conceptual metaphors

Coding for the conceptual metaphors is based on the agreed constructional patterns that have also been agreed to be metaphorical (Shutova, Devereux, & Korhonen, 2013, p. 1275). Table @ref(tab:kappa-cm) presents the results for this classification.

# kappa calculation first round
irr_cm_1 <- happyr::kappa_tidy(df = happyr::df_cm,
                                var_names = "_pre$",
                                round = "pre_disc") %>% 
  mutate(words = paste("*", words, "*", sep = ""),
         gloss = c("happiness", "joy", "pleasure"),
         kappa = round(kappa, 2L)) %>% 
  select(words, gloss, everything())
# kappa calculation second round
irr_cm_2 <- happyr::kappa_tidy(df = happyr::df_cm,
                                var_names = "_post$",
                                round = "post_disc") %>% 
  mutate(words = paste("*", words, "*", sep = ""),
         gloss = c("happiness", "joy", "pleasure"),
         kappa = round(kappa, 2L)) %>% 
  select(words, gloss, everything())
irr_cm_2 %>% 
  bind_rows(irr_cm_1) %>% 
  knitr::kable(caption = "Cohen's Kappa for the Conceptual Metaphor coding (post- and pre-discussion stages)", row.names = TRUE)
words gloss rater cases kappa round
1 kebahagiaan happiness 2 54 0.83 post_disc
2 kegembiraan joy 2 58 0.83 post_disc
3 kesenangan pleasure 2 58 0.92 post_disc
4 kebahagiaan happiness 2 54 0.47 pre_disc
5 kegembiraan joy 2 58 0.56 pre_disc
6 kesenangan pleasure 2 58 0.52 pre_disc

In the first round, the average Kappa is moderate (\(\mu\) = 0.52, \(\sigma\) = 0.05). Discrepancies occur predominantly with regards to determining the level of granularity for the (mnemonic labels of the) metaphors, the decision of which requires subjective interpretation.

With the remaining unresolved disagreement after discussion, the second round Kappas were computed. On average, the agreement level has increased to “nearly perfect” agreement (\(\mu\) = 0.86, \(\sigma\) = 0.05). Despite this increased agreement level after discussion, after all, any metaphor studies are always permeated by certain degree of subjectivity. In practice, it means that CMT analysts/practicioners can have disagreement over certain analyses, be it when determining whether an expression is metaphorical or not, or when grouping a set of metaphorical expressions into certain conceptual metaphor categories.

2 Codes for Chapter 5 - Entrenched metaphors

# calculation for the token, type, and type/token ratios data
ttr_metaphor <- happyr::ttr(df = happyr::phd_data_metaphor,
                            schema_var = "metaphors",
                            lexunit_var = "lu",
                            float_digits = 2)
# Tokens proportion of the discussed metaphors
creative_metaphors_length <- ttr_metaphor %>% 
  arrange(desc(type_per_token_lu)) %>% 
  filter(token >= 3) %>% 
  top_n(10, type_per_token_lu) %>% 
  select(metaphors, token, type_lu, type_per_token_lu) %>% 
  dim() %>% 
  .[1]
creative_metaphors_prop <- ttr_metaphor %>% 
  arrange(desc(type_per_token_lu)) %>% 
  filter(token >= 3) %>% 
  top_n(10, type_per_token_lu) %>% 
  tally(perc_token) %>% 
  .$n
top_token_metaphor <- ttr_metaphor %>% 
  top_n(10, token) %>% 
  .[,1] %>% 
  unlist() %>% 
  unname()
top_type_metaphor <- ttr_metaphor %>% 
  top_n(10, type_lu) %>% 
  .[,1] %>% 
  unlist() %>% 
  unname()
entrenched_metaphors_prop <- ttr_metaphor %>% 
  top_n(10, token) %>% 
  tally(perc_token) %>% 
  .$n
productive_metaphors_length <- setdiff(top_type_metaphor, top_token_metaphor) %>% 
  length()
productive_metaphors_prop <- ttr_metaphor %>% 
  top_n(10, type_lu) %>% 
  arrange(desc(type_lu)) %>% 
  filter(token < 100) %>% 
  tally(perc_token) %>% 
  .$n

2.1 Introduction

For this thesis, I analysed 45802 usage samples of sentences containing words referring to five central members under the generic happiness-like category in Indonesian (cf. Shaver, Murdaya, & Fraley, 2001). The analysis results in the total 3638 tokens of metaphorical linguistic expressions containing 62 metaphor types.

This chapter discusses the top-10 most frequent conceptual metaphors (§@ref(frequentmetaphors)), constituting 68.45% of the total metaphorical tokens; Chapter 6 discusses 4.63% of the total 3638 tokens, consisting of 12 different metaphor types. In total, Chapter 5 and Chapter 6 account for 73.08% of the total 3638 tokens of the metaphorical expressions.

2.2 Top-10 frequent metaphors for happiness in Indonesian

This section discuss which metaphors are relatively entrenched for happiness in Indonesian, based on their token frequency (cf. Hilpert, 2006b, pp. 130–131). I focus on the ten most frequent metaphors as shown in Table @ref(tab:top-10-frequent-metaphors).

ttr_metaphor %>% 
  top_n(10, token) %>% 
  select(metaphors, token, perc_token) %>% 
  mutate(metaphors = happyr::scaps(metaphors)) %>% 
  rename(Metaphors = metaphors,
         Token = token,
         `%Token` = perc_token) %>% 
  knitr::kable(caption = 'Top-10 metaphors sorted in descending order of the token frequency.', row.names = TRUE)
Metaphors Token %Token
1 happiness is a possessable object 749 20.59
2 happiness is a contained entity 358 9.84
3 happiness is a desired goal 293 8.05
4 happiness is an (un)veiled object 211 5.80
5 happiness is a located object 210 5.77
6 happiness is a location 169 4.65
7 happiness is a liquid in a container 156 4.29
8 intensity of happiness is quantity of object 137 3.77
9 happiness is food 108 2.97
10 happiness is a submerged entity 99 2.72

As Table @ref(tab:top-10-frequent-metaphors) shows, happiness is most frequently construed as a possessable object. The following sub-sections elaborate on the submappings and the inferences evoked for construing aspects of happiness. While the discussion begins with the happiness is a possessable object metaphor, it may not fully follow the ranked-order of the metaphors in Table @ref(tab:top-10-frequent-metaphors). Instead, metaphors conveying related themes will follow from one another in the discussion to highlight similarities. For instance, the aspect of intensity is highlighted mainly by contained entity, liquid in a container, and quantity of object metaphors. These three metaphors are accordingly presented in sequence, despite their non-successive ranking in Table @ref(tab:top-10-frequent-metaphors).

2.2.1 Happiness is a possessable object

lu_possessable <- happyr::get_lu_table("possessable",
                                       top_n_only = FALSE,
                                       df = happyr::phd_data_metaphor,
                                       incl_submappings = TRUE,
                                       submapping_perc = TRUE)
possess_frames <- happyr::get_frames("possessable",
                                     df = happyr::phd_data_metaphor)
possess_submappings <- happyr::get_submappings("possessable",
                                               df = happyr::phd_data_metaphor) %>% 
  mutate(aspect = if_else(str_detect(submappings, 'caus'), 'cause', 'existence'),
         aspect = if_else(str_detect(submappings, 'attain'), 'attainment', aspect),
         aspect = if_else(str_detect(submappings, 'change of '), 'ceasing', aspect))
possess_submappings_aspect <- possess_submappings %>% 
  group_by(aspect) %>% 
  summarise(n = sum(n), 
            type = sum(type)) %>% 
  mutate(perc = round(n/sum(n) * 100, 2), 
         type_perc = round(n/sum(n) * 100, 2)) %>% 
  arrange(desc(n))

The cause of happiness is referred to via interrelated frames evoking object transfer. They are (i) the offering frame (1.2% of the total tokens of the possessable object metaphor), which in FrameNet is described as adopting the structure of giving frame; (ii) the giving frame (30.17%); (iii) dispersal, which is related to resource transfer frame in MetaNet (13.62%); and (iv) the generic caused motion frame (15.49%), which includes the bringing frame.

From the perspective of the Recipient, receiving or gaining the transferred possessable object is mapped onto the onset of happiness. This inference is evoked through the gain possession frame (24.3%). The frame is available in the MN frame repository.

The experience of happiness can be expressed as the gaining of a possessabe object, invoked through the possession frame (9.35%).

Table @ref(tab:possessable-object-lu-table) shows the LU types most frequently co-occur with the happiness words to evoke the possessable object metaphor and its frame-based submappings.

happyr::get_lu_table("possessable object", 
                     top_n_only = TRUE,
                     df = happyr::phd_data_metaphor) %>%
  knitr::kable(caption = 'Top-10 most frequent lexical units evoking <span style = "font-variant:small-caps;">happiness is a possessable object</span>.', row.names = TRUE)
Lexical_units Gloss N Perc_overall
1 beri(kan) to give 170 22.70
2 dapat(kan).v to get 120 16.02
3 bawa(kan) to bring 75 10.01
4 berbagi to share 71 9.48
5 peroleh to acquire/earn 43 5.74
6 miliki to have/own 35 4.67
7 kehilangan to lose 22 2.94
8 kembalikan to give back; to return 20 2.67
9 datangkan to bring sth.; to cause to come 16 2.14
10 hadirkan to present sth. 15 2.00

Percentage overall in the LU table indicates the percentage of a given LU from the total tokens of the metaphor.

Beri(kan) ‘to give’, for instance, is the most frequent LU for the giving frame (75.22% of the total tokens of the giving frame), compared to kembalikan ‘to give sth. back; to return sth.’ (8.85 %). For gain possession frame, dapat(kan)3 ‘to get’ (66.3%) is the most frequent LU. Berbagi ‘to share’ is the most common LU (69.61%) for the dispersal frame, while miliki ‘to have/own’ (50%) and kehilangan ‘to lose’ (81.48%) are representative for the possession and lose possession frames respectively. Lastly, bawa(kan) ‘to bring sth. (to sb.)’ (64.66%) is the most frequent LU for the caused motion frame.

Despite its high token frequency, happiness is a possessable object has a low degree of lexical diversity in its linguistic expressions given its token frequency. The metaphor is expressed with different LU types in only 8.41% of the total 749 tokens. The percentage is derived from dividing the type frequency of the metaphor with its token frequency (i.e. the type/token ratio (TTR) measure) and normalising it into percentage (cf. Stefanowitsch, 2017, p. 282). The TTR value of possessable object indicates that it is evoked by a few yet highly frequent and conventional metaphorical expressions.

Overall, the predominant submappings in the possessable object metaphor are those involving (potential) object transfers (60.48% of the total 749 tokens of the metaphor), highlighting the cause for happiness. It is then followed by the receiving of the possessable object, hence the attainment of happiness (24.17%); the possessing, or existence, (9.35%); and lastly the losing, or ceasing, of happiness (6.01%).

2.2.2 Happiness is a desired goal

goal_submappings <- happyr::get_submappings("desired", df = happyr::phd_data_metaphor) %>% 
  mutate(aspect = if_else(str_detect(submappings, 'reaching|capturing|grasping|finding'), 'attaining', 'process'),
         aspect = if_else(str_detect(submappings, 'access|aids'), 'means', aspect),
         aspect = if_else(str_detect(submappings, 'end of a path'), 'goal', aspect),
         aspect = if_else(str_detect(submappings, 'impeding'), 'obstacle', aspect)) %>%
  group_by(aspect) %>%
  mutate(perc_aspect_by_submet = round(n/sum(n) * 100, 2),
         type_perc_aspect_by_submet = round(type/sum(type) * 100, 2)) %>%
  ungroup()
goal_aspect <- goal_submappings %>%
  group_by(aspect) %>%
  summarise(n = sum(n), type = sum(type)) %>%
  mutate(perc = round(n/sum(n) * 100, 2), 
         type_perc = round(type/sum(type) * 100, 2)) %>%
  arrange(desc(n))
# Semantic types of the PURSUIT event
searching_lu <- c("cari", "pencarian", "jemput(lah)", "gali", "pendulang", "sasaran")
searching_lu_token <- dim(filter(happyr::phd_data_metaphor, lu %in% searching_lu))[1]
chasing_lu <- c("kejar", "pengejaran")
chasing_lu_token <- dim(filter(happyr::phd_data_metaphor, lu %in% chasing_lu))[1]
hunting_lu <- c("pemburu", "buruan", "memburu")
hunting_lu_token <- dim(filter(happyr::phd_data_metaphor, lu %in% hunting_lu))[1]
# pursue semantics table
pursue_semantics <- data.frame(semantics = c("searching", "chasing", "hunting"), 
                               n = c(searching_lu_token, chasing_lu_token, hunting_lu_token), 
                               type = c(length(searching_lu), length(chasing_lu), length(hunting_lu))) %>%
  mutate(perc = round(n/sum(n) * 100, 2),
         type_perc = round(type/sum(type) * 100, 2))
# grammatical voice of verbal lexical units for the metaphor
voice_destination <- happyr::phd_data_metaphor %>% 
  filter(str_detect(metaphors, "desired"), 
         lu_phrase_type == "vp") %>% 
  group_by(voice_verbal_lu, submappings) %>% 
  summarise(n = n(), 
            type_per_voice = n_distinct(lu)) %>% 
  arrange(submappings, desc(n)) %>% 
  group_by(submappings) %>% 
  mutate(perc_voice_by_submet = round(n/sum(n) * 100, 2), 
         perc_type = round(type_per_voice/sum(type_per_voice) * 100, 2))
voice_destination_max <- voice_destination %>% 
  filter(n == max(n)) %>% 
  ungroup()
voice_destination_summary <- voice_destination %>% 
  group_by(voice_verbal_lu) %>% 
  summarise(n = sum(n), type_per_voice = sum(type_per_voice)) %>% 
  mutate(perc = round(n/sum(n) * 100, 2),
         perc_type_per_voice = round(type_per_voice/sum(type_per_voice) * 100, 2)) %>% 
  arrange(desc(perc))

In §@ref(possession), happiness is understood as an object caused to move to the Goal, namely the candidate Experiencer, via various kinds of transferring scenes. In this sense, the candidate Experiencer takes a rather passive role in acquiring the possession. In contrast, happiness is a desired goal construes happiness as a location or object towards which the candidate Experiencer moves, reflecting the quest metaphors family proposed by Stefanowitsch (2004) (cf. Lakoff & Johnson, 1999, pp. 196–197).

Happiness is a desired goal consists of submappings built upon structures of the self-propelled motion to a destination frame (cf. Lakoff & Johnson, 1999, pp. 190–191). The submappings provide rich inferences concerning (i) happiness as an aspiration (e.g. a desired object or location), (ii) process and means to achieve the aspiration, as well as (iii) how the process may be halted. Citations (6) to (8) illustrate the mapping of happiness onto the Goal role. The metaphorical expressions are based on lexical units (LUs) that evoke the schematic image of the source-path-goal (SPG) frame.

  1. example for tujuan (ind_newscrawl2012_1M:192777)
  2. example for bermuara ke ujung (ind_newscrawl2011_1M:667627)
  3. example for berujung pada (ind_newscrawl2012_1M:536251)

The SPG frame describes a series of locational roles, namely Source, Path, and Goal, along which an entity, called Trajector, moves, or is conceived as moving4. When the frame is used for designating happiness is a desired goal metaphor, happiness is mapped onto the Goal role. That is, happiness is understood as the Goal-end of a Path, towards which the Trajector may move along from a Source.

Concerning the conceptualisations of the attempt for achieving happiness, there are several relevant frames. Two of these frames indicate the means that are required by the Mover in h(is/er) attempt to reach the Goal; these frames are the access to a location (as in (9) to (11)) and guided motion frames (as in (12) and (13)). When mapped onto the target frame, the inference from these two frames indicates that happiness cannot be directly achieved without certain means, such as access or guidance.

  1. example for kunci (ind_mixed2012_1M:424589)
  2. example for pintu (ind_web2011_300K:108339)
  3. example for ticket (ind_mixed2012_1M:397320)
  4. example for guided motion frame with mengantarkan (ind_web2012_1M:358204)
  5. example for guided motion frame with memimpin ke jalan (ind_newscrawl2012_1M:872312)

Next, the attempt by the candidate Experiencer to achieve happiness is conceptualised via purposeful action is self-propelled motion to a destination metaphor, based on the self-propelled motion to a destination frame5. The metaphor is composed of two more basic metaphors. The first of these is action is self-propelled motion (e.g. She squeezed her way to thinner thighs6), which is grounded on the correlation of doing actions and moving. The metaphor also indicates that the Mover has his/her own control over the direction of its action/motion; yet, as can be seen from examples (12) and (13) above, the movement can also be taken over, or guided, by a co-Mover. The second constituting metaphor is purposes are destination (e.g. We have taken the first step), which is grounded on the correlation of reaching a destination with achieving a purpose (e.g. going to a cafe for a coffee) (Lakoff & Johnson, 1999, pp. 52–53, 187–191).

In the self-propelled motion to a destination frame, the Goal role is profiled as a desirable goal, which is not inferred from its parent frame, namely motion to a location; this parent frame profiles only the goal-oriented motion. The metaphor based on self-propelled motion to a destination frame suggests that becoming happy constitutes a purposeful attempt due to the desirability of the Goal (cf. (14) and (15)). Moreover, the person aiming to be happy needs to take certain action, hence movement, to realise this purpose. Indonesian voice morphology can contribute to the agentive construal of the candidate Experiencer in the metaphor. Agentivity can be inferred from the verbal LUs of the metaphor that most frequently occur in active voice construction that, in Indonesian, can be marked by prefix meN- (80.5% of the total 241 tokens of the verbal LUs for the metaphor) (see, for instance, (14), (16), and (17)).

  1. example with motion to a destination with menuju (ind_web2012_1M:398400)
  2. example with kembali ke (ind_newscrawl2011_1M:451099)

The number of tokens for the self-propelled motion to a destination frame only accounts for (11.02%) of the total 127 tokens referring to the attempt to be happy. This is predominantly expressed by the verb menuju ‘to head to a location’ as in (14) above. A preferable frame for conceptualising the attempt constitutes the subcase of the self-propelled motion to a destination, namely the pursue frame (88.98% of the total frequency for expressions evoking the attempt aspect).

The subcase of relation in MetaNet (MN) indicates that pursue fully incorporates the frame elements and inferential structures of its parent frame (i.e. self-propelled motion to a destination), such as the desirability of the Goal, Self-motion_x-schema/process, and the Mover. In addition, pursue as the child frame may have semantic specification, or elaboration, of the frame role parameters. However, MN repository has not yet provided these detailed specifications that may distinguish the pursue frame from its parent frame. Perhaps, pursue elaborates the semantics of the Self-motion_x-schema with more specific means of action undertaken to achieve the goal, such as searching (16), chasing (17), or hunting (18). Meanwhile, the self-propelled motion to a destination may only profile a self-initiated motion of the Mover-actor until (s)he reaches the destination. No specific means are implied in this frame for how the Goal is reached7 and for whether the Goal is static or moving.

  1. example with mencari (searching) (ind_mixed2012_1M:397221)
  2. example with mengejar (chasing) (ind_mixed2012_1M:504905)
  3. example with pemburu (hunting) (ind_newscrawl2011_1M:79925)

The lexical units (LUs) within pursue represent three categories of semantic type. They are LUs referring to searching (74.34% of the total 113 tokens of expressions evoking pursue), chasing (22.12%), and hunting (3.54%). The preference for the searching process portrays happiness as something hidden and requiring exploration for its attainment. Intuitively, mengejar ‘to chase; run after’ in example (17) may invite an image of (i) a moving, desired Goal, and (ii) having an immediate expectation by the Self-mover when chasing the Goal. In the target frame, this inference maps onto the exigency for experiencing happiness. After all, examples (16) to (18) clearly single out the active role of the Self-mover in achieving the Goal. In the target frame, this inference corresponds to the active responsibility of the candidate Experiencer for h(is/er) own happiness.

A small number (i.e. 0.68%) of the tokens of the happiness is a desired goal metaphor evoke submapping conveying potential inhibition on the attempt to achieve happiness. Example (19) specifies a self-internal inhibition for certain prohibited pleasure.

  1. example with menahan diri dari beragam kesenangan (ind_web2011_300K:118298)

Within the arc of the happiness is a desired goal metaphor, the achievement of happiness is conceptualised as the final stage of the motion. This could be reaching/arriving (20), locating/finding (21), and capturing/grasping (22) the desired goal (cf. Stefanowitsch, 2004, pp. 142–145).

  1. example with mencapai (ind_mixed2012_1M:263518)
  2. example with menemukan (ind_mixed2012_1M:565135)
  3. example with meraih (ind_web2012_1M:152154)

All the source frame LUs conveying the final stage of the motion process indicate that a prior effort is required by the Mover before (s)he can reach or capture h(is/er) desired Goal. This inference maps onto the efforts required for somebody to be happy.

get_lu_table("desired", df = happyr::phd_data_metaphor) %>% 
  knitr::kable(caption = 'Top-10 most frequent lexical units evoking <span style = "font-variant:small-caps;">happiness is a desired goal</span>.', row.names = TRUE)
Lexical_units Gloss N Perc_overall
1 cari to search/look for 74 25.26
2 capai to reach 51 17.41
3 raih to pull/reach sth. towards the body 27 9.22
4 kejar to chase 24 8.19
5 temukan to find 24 8.19
6 tujuan destination/goal 13 4.44
7 menuju to head to 9 3.07
8 jalan way 8 2.73
9 kunci key 8 2.73
10 gapai to reach out 6 2.05

Happiness is a desired goal has little variation in its linguistic expressions, showing only 14.33% variation given its overall token frequency (293 tokens). The percentage of the submapping indicating the attempt to attain happiness is only slightly higher (43.34%) than the attainment (41.64%). This distribution suggests that the process to and the attainment of happiness are relatively equally highlighted in the sample.

2.3 Happiness is a location

location_submappings <- happyr::get_submappings("a location$", df = happyr::phd_data_metaphor) %>% 
  mutate(aspect = if_else(str_detect(submappings, 'motion into'), 'change of state into', 'being in a state'),
         aspect = if_else(str_detect(submappings, '(moving away|being far) from'), 'change of state out', aspect),
         aspect = if_else(str_detect(submappings, 'caused'), 'caused change of state to', aspect),
         aspect = if_else(str_detect(submappings, 'is a (landmark|bounded entity|geographic|source of a path|location$)'), 'location state', aspect))
# get the LU table
location_lu <- happyr::get_lu_table("is a location$",
                                    top_n_only = TRUE,
                                    df = happyr::phd_data_metaphor)

Happiness is a location is a subcase of one of the central metaphors in the Location Event Structure Metaphor (LESM) system, i.e. states are location (Lakoff & Johnson, 1999, pp. 179–180). The metaphor is centred around the location-related frames, such as the being at a location frame. This frame schematically describes a scene where a trajector (i.e. the Located_thing role) occupies a location (i.e. the Current_location role). The use of the frame in happiness is a location sees the role-mappings of (i) the target frame happiness onto the Current_location role of the source frame and (ii) the candidate Experiencer onto the Located_thing role.

The principal inference invited by happiness is a location is that the experience of happiness is expressed as the experiencer’s being located at the happiness-location. The experiencer is thus depicted as the Located_thing. The metaphor tends to be expressed via prepositional phrase whose nominal object slot is filled with the happiness nouns. This nominal object slot is linked to the Current_location role. The most frequent preposition is dalam ‘inside’ (cf. (23)).

  1. example with dalam (ind_newscrawl2011_1M:512071)

Dalam indicates that the Current_location role is a bounded region with interior and exterior. The bounded region frame evokes a more specific inference compared to the unbounded location version (as in (24) and (25) below). Being happy maps onto being in the interior of the bounded region, while unhappy is mapped onto the exterior.

  1. example with di keceriaan (Kompas via WebCorp:40)
  2. example with pada suatu kegembiraan (ind_mixed2012_1M:194551)

The same idea indicated in (23) to (25) can be expressed by the collocation of the prepositions with stative, locational verbs. The verbs add temporal aspect, indicating that the Experiencer is in an ongoing Location-state. The nature of the preposition will tell us whether the location is a bounded region (as in (26) to (27)) or underspecified for its interior-exteriority (as in (28)). The submapping of being happy as being at a location exemplified in (23)-(28) takes up the majority of the metaphor’s token (60.95% out of 169 tokens of happiness is a location).

  1. example with berada dalam NP (IWaC via Sketch Engine:ID77725)
  2. example with berteduh dalam NP (Antara News via WebCorp:11)
  3. example with berada pada NP (ind_web2012_1M:642581)

While being happy is conceptualised as being at a location, being unhappy is conceptualised as being away from the happiness>-location (5.92% of the metaphor’s token) (29)

  1. example with jauh dari (ind_newscrawl2012_1M:26855)

Other submappings built around happiness is a location are related to the change of location as expressed via motion verbs (cf. Dodge, 2016, pp. 274–275). In the motion-related submappings, the Experiencer fills the Mover role and the happiness nouns fill the Location-related role, namely Source-location or Goal-location. The Mover can move (in)to ((34) and (35)) or away from the Location ((30) to (33)). These two change-of-location inferences are mapped onto the change-of-state aspect in the target, resulting in two other submappings. Namely, becoming happy is motion to a location (2.96%) and ceasing happiness is moving away from the location (11.83%).

  1. example with meninggalkan (ind_mixed2012_1M:950273)
  2. example with menghindari (ind_news2012_300K:116280)
  3. example with menjauhi (ind_mixed2012_1M:25946)
  4. example with menjauhkan (ind_web2012_1M:825998)
  5. example with masuk ke dalam (ind_mixed2012_1M:669544)
  6. example with terjerumus dalam (ind_mixed2012_1M:294560)

An interesting example is the use of the downward motion verb terjerumus in (35). The uncontrolled falling movement conveyed by terjerumus suggests some sort of negative harm for the Mover (e.g., harmed face). In the target frame, this construal indicates that experiencing kesenangan ‘pleasure’ can be a negative one. This construal could be motivated by the negative states are low location (David, 2017, p. 579).

Another submapping incorporates a causal structure into the motion frame, such that the motion of the Mover is caused by the Agent role of some kind. This scene represents the caused change of state is caused motion to a location submapping (5.92%). In the target frame, this suggests that there is certain cause for someone’s happiness.

Table @ref(tab:lu-location)8 shows that 42.6% of the tokens for happines is a location is due to one LU type, namely dalam ‘inside sth.’. This proportion indicates that the metaphor is evoked by a conventional linguistic expression. This is further corroborated by the low percentage of variation in the metaphor’s linguistic realisation given the metaphor’s token frequency, that is, only 20.71% of the metaphor’s overall tokens are expressed with different LU types.

# print the LU
location_lu %>%
  knitr::kable(caption = 'Top-10 most frequent lexical units evoking <span style = "font-variant:small-caps;">happiness is a location</span>.', row.names = TRUE)
Lexical_units Gloss N Perc_overall
1 dalam inside sth. 72 42.60
2 tinggalkan to let sth. stay behind; to leave 11 6.51
3 di balik at the reverse/back side of sth. 10 5.92
4 jauh dari to be far away from 10 5.92
5 berada (di) dalam to exist inside 7 4.14
6 hidup dalam to live inside sth. 6 3.55
7 bawa X kepada to bring X towards 5 2.96
8 jauhkan X dari to cause X be far away from 5 2.96
9 pada at 5 2.96
10 di at 3 1.78
11 jauhi to move/stay away from 3 1.78
12 masuk ke dalam to move into; to enter 3 1.78

In sum, happiness is a location metaphor principally foregrounds the nature of how one experiences happiness. This is reflected through the highest proportion of the being happy is being at a location submapping (60.95%). The metaphor also highlights the change of state away from or into happiness; the former has higher proportion than the latter (17.75% vs. 8.88%).

2.4 Happiness is a located object

# submappings
located_submappings <- happyr::get_submappings("located object$", df = happyr::phd_data_metaphor)
# lexical unit table
located_lu <- happyr::get_lu_table("located object$", df = happyr::phd_data_metaphor)
# print the lu
located_lu %>%
  knitr::kable(caption = 'Top-10 most frequent lexical units evoking <span style = "font-variant:small-caps;">happiness is a located object</span>.', row.names = TRUE)
Lexical_units Gloss N Perc_overall
1 ada (di/pada X) to exist (at X) 100 47.62
2 di X (to be) at X 33 15.71
3 hilang to disappear 22 10.48
4 pada X (to be) at X 8 3.81
5 hilangkan to eliminate 6 2.86
6 lenyap to disappear 5 2.38
7 sirna to vanish 5 2.38
8 hilangnya disappearance 4 1.90
9 letak location (of sth.) 3 1.43
10 terletak to be located at 3 1.43

The first one is the existence of happiness is presence of an object at a location, accounting for 77.14% of the total tokens of the metaphor.

The first submapping entails the second one, i.e. inexistence of happiness is absence of an object at a location, representing 19.05% of the total tokens

The second submapping has its causative variant, namely causing happiness to cease is causing an object to be absent (3.81%). This third submapping introduces the Agentive role to the scene via transitivising the LU, such as hilang ‘be gone’, using causative suffix -kan, into hilang-kan ‘cause sth. to be gone’.

Despite its high token frequency, the located object metaphor is less diverse in its linguistic manifestation due to nearly half of its total tokens (47.62%) being evoked by ada (di/pada X) (cf. Table @ref(tab:lu-located-object)). That is, the metaphor’s frequent occurrence is composed of a proportionally limited type of LUs that are frequently repeated, rather than of a proportionally heterogeneous set of LUs (Ronga, 2016, p. 53). Overall, only 12.38% of the metaphor’s tokens are of different LU types; the rest of the tokens is repetition from that proportion (cf. Stefanowitsch, 2017, p. 282).

2.5 Happiness is a contained entity

# CONTAINED ENTITY metaphor data
## frames
contained_entity_frames <- happyr::get_frames(metaphor = "contained entity",
                                              df = happyr::phd_data_metaphor) %>%
  group_by(frames) %>%
  summarise(n = sum(n)) %>%
  mutate(perc = round(n/sum(n) * 100, 2),
         metaphors = "contained entity") %>%
  arrange(desc(n))
## submappings
contained_entity_submappings <- happyr::get_submappings("contained entity",
                                                        df = happyr::phd_data_metaphor) %>% 
  mutate(aspect = if_else(str_detect(submappings, "expression"), "expression", "containment"),
         aspect = if_else(str_detect(submappings, "(high intensity|intensified|intense)"), "increased intensity", aspect),
         aspect = if_else(str_detect(submappings, "regulating"), "regulation", aspect))
## aspect summarised
contained_entity_aspect <- contained_entity_submappings %>% 
  group_by(aspect) %>% 
  summarise(n = sum(n), 
            type = sum(type), 
            perc = sum(perc), 
            type_perc = sum(type_perc)) %>%
  arrange(desc(n))
## lexical unit table
contained_entity_lu <- happyr::get_lu_table("contained entity",
                                            top_n_only = FALSE,
                                            df = happyr::phd_data_metaphor)
contained_entity_lu %>%
  top_n(10, N) %>%
  knitr::kable(caption = 'Top-10 most frequent lexical units evoking <span style = "font-variant:small-caps;">happiness is a contained entity</span>.', row.names = TRUE)
Lexical_units Gloss N Perc_overall
1 penuh to be full 256 71.51
2 (di) dalam X (to be) in X 23 6.42
3 ada (di) dalam X to exist inside X 23 6.42
4 penuhi to fill-up 13 3.63
5 isi.v to fill 10 2.79
6 berisi(kan) to contain 3 0.84
7 di hati in the liver 3 0.84
8 kandung.v to contain 3 0.84
9 letupan explosion 3 0.84
10 meledak to explode 3 0.84

The submappings in the contained entity metaphor involve five source frames: (i) containing (80.73%), (ii) being in a bounded region region (16.2%), (iii) explosion (2.23%), (iv) fragmentation scenario9 (0.56%), and (v) pressure in a container (0.28%).

The most frequent submapping within the contained entity metaphor (i.e. 75.42% of the total 358 tokens of the metaphor) exploits the Fullness_degree role of the containing frame. In other words, most of the lexical units (LUs) refer to the fullness of the Content inside the Container; in the target domain (TD), fullness of the contained entity is mapped onto the high extent of happiness.

The second predominant submapping is evoked by LUs referring to the ‘containment’ scene (21.51%). This is mapped onto the experience/existence of happiness itself.

The Fullness of the Content may produce (i) pressure on the Container (0.28%) that, when it is uncontrollable, may result in (ii) explosion/breaking out of the Container (2.79%). The explosion-related submapping is made up of the explosion and fragmentation scenario frames.

Table XXX shows that 71.51% of the tokens of happiness is a contained entity metaphor is due to one LU, i.e. penuh ‘to be full’. This points to a highly-conventionalised property of the metaphor in its linguistic manifestation, given the high frequency of a single LU compared to the others (cf. Ronga, 2016, p. 53). In other words, the relative entrenchment of the metaphor arises from a conventionalised expression, such as penuh ‘to be full’. This is further supported by the metaphor’s low percentage of the variation for its linguistic realisations (i.e., 7.26%) over its overall token frequency.

2.6 Happiness is a liquid in a container

# LIQUID IN A CONTAINER metaphor data
## frames
contained_liquid_frames <- happyr::get_frames("liquid in a container", df = happyr::phd_data_metaphor) %>% 
  mutate(metaphors = 'liquid in a container') %>%
  arrange(desc(n))
## submappings
contained_liquid_submappings <- happyr::get_submappings("liquid in a container", df = happyr::phd_data_metaphor) %>% 
  mutate(aspect = if_else(str_detect(submappings, "expression"), "expression", "containment"),
         aspect = if_else(str_detect(submappings, "(high intensity|intensified|intense)"), "increased intensity", aspect),
         aspect = if_else(str_detect(submappings, "preventing"), "regulation", aspect),
         aspect = if_else(str_detect(submappings, "accommodating"), "accommodating", aspect))
## aspect summarised
contained_liquid_aspect <- contained_liquid_submappings %>% 
  group_by(aspect) %>% 
  summarise(n = sum(n), 
            type = sum(type), 
            perc = sum(perc), 
            type_perc = sum(type_perc)) %>%
  arrange(desc(n))
## lexical unit table
contained_liquid_lu <- happyr::get_lu_table("liquid in a container",
                                            top_n_only = FALSE,
                                            df = happyr::phd_data_metaphor)
contained_liquid_lu %>%
  top_n(10, N) %>%
  knitr::kable(caption = 'The most frequent lexical units evoking <span style = "font-variant:small-caps;">happiness is a liquid in a container</span>.', row.names = TRUE)
Lexical_units Gloss N Perc_overall
1 terpancar to be spurted out 43 27.56
2 luapan overflow 25 16.03
3 luapkan to boil sth. over 21 13.46
4 pancarkan to spurt sth. 9 5.77
5 meluap(-luap) to boil over 8 5.13
6 limpahkan to brim liquid onto sth. 4 2.56
7 salurkan to funnel sth. 4 2.56
8 bendung to dam up sth. 3 1.92
9 pancaran a spurting-out 3 1.92
10 berlimpah to be brimming/aboundant 2 1.28
11 curahan outpouring 2 1.28
12 limpahi to brim sth. with liquid 2 1.28
13 meruap to boil to froth/bubble 2 1.28
14 sumbat to clog sth. 2 1.28
15 tampung to collect-in (of liquid) 2 1.28
16 tertuang to be poured out 2 1.28
17 tuangkan to pour out sth. 2 1.28

The submappings within happiness is a liquid in a container metaphor make use of structures from five source frames that reflect a range of experiential knowledge concerning the behaviour of a contained liquid. They are (i) release liquid (64.1%), (ii) heating fluid (20.51%), (iii) fluid containment (9.62%), (iv) fluid motion (2.56%), and (v) stop flow of substance (3.21%). These frames are represented in the MetaNet frame repository.

To begin with, the existence of happiness is conceptualised as (i) liquid containment (2.56%)10 and (ii) fluidic motion of the liquid (2.56%). As to the fludic motion submapping, there are two scenarios attested in my sample. First, the liquid may flow inwardly from some source and throughout the body.

Next, there are two submappings that focus on the intense experience of happiness. The first submapping is based on the heated fluid frame, namely intensified happiness is heated liquid (20.51%)).

The second submapping is postulated via the profiling of the fullness of the Fluid_level role in the fluid containment frame, namely intense happiness is brimming liquid in a container (7.05%).

Release liquid is the most frequently evoked frame in the metaphor (i.e., 100 tokens) and it has the highest number of LU types compared to the other frames in the metaphor (i.e., 18 types).

Moreover, among the ten most frequent metaphors discussed in this chapter, happiness is a liquid in a container is the most diverse linguistically: 23.72% of its tokens are of different LU types.

2.7 Intensity of happiness is quantity of object

## submappings
quantity_submapping <- happyr::get_submappings("quantity of object",
                                               df = happyr::phd_data_metaphor)
## LU and submappings
quantity_focus_lu <- happyr::get_lu_table("quantity of object",
                                          submapping_perc = TRUE,
                                          incl_submappings = TRUE,
                                          df = happyr::phd_data_metaphor) %>% 
  mutate(mapping = if_else(str_detect(Submappings, 'more|adding'), 'more', 'less')) %>%
  group_by(mapping) %>%
  mutate(N_by_mapping = sum(N)) %>%
  ungroup() %>%
  mutate(perc_lu_by_mapping = round((N/N_by_mapping) * 100, 2)) %>%
  select(-Submappings)
## aspect
quantity_focus <- quantity_submapping %>%
  mutate(mapping = if_else(str_detect(submappings, 'more|adding'), 'more', 'less')) %>% 
  group_by(mapping) %>% 
  summarise(n = sum(n), 
            type = sum(type)) %>% 
  mutate(perc = round(n/sum(n)*100, 2), 
         type_perc = round(type/sum(type)*100, 2))

Overall, 78.83% of the total 137 tokens of the metaphorical expressions profile the ‘more quantity’ end of the entire quantity frame.

From the linguistic realisation point of view, the quantity metaphor can also be considered less diverse. Only 21.17% out of its 137 tokens are expressed by different LU types. Among the predominant LUs include tambahkan ‘to add sth.’, banyak ‘many/much’, and berlebihan ‘excessive’.

2.8 Happiness is an (un)veiled object

# frames
concealed_frames <- happyr::get_frames("veiled", df = happyr::phd_data_metaphor)
# submapping
concealed_submapping <- happyr::get_submappings("veiled", df = happyr::phd_data_metaphor)
# tokens concerning hiding and abilitative modal
hiding_tokens <- 1:filter(concealed_submapping, str_detect(submappings, "regulating"))[["n"]]
tokens_without_abilitative <- c(3, 10, 19, 21)
tokens_with_abilitative <- setdiff(hiding_tokens, tokens_without_abilitative)
tokens_with_abilitative_positive <- 15
tokens_with_abilitative_negated <- setdiff(tokens_with_abilitative, tokens_with_abilitative_positive)
tokens_without_abilitative_negated <- c(10, 21)
# lexical unit
concealed_lu <- happyr::get_lu_table("veiled", top_n_only = TRUE, df = happyr::phd_data_metaphor)
concealed_lu %>%
  knitr::kable(caption = 'Top-10 most frequent lexical units evoking <span style = "font-variant:small-caps;">happiness is an (un)veiled object</span>.', row.names = TRUE)
Lexical_units Gloss N Perc_overall
1 lihat to see/look at 40 18.96
2 terlihat to be visible 38 18.01
3 (n/t)ampak to be visible 34 16.11
4 tunjukkan to show 27 12.80
5 sembunyikan to hide 17 8.06
6 perlihatkan to show 15 7.11
7 tampakkan to display 8 3.79
8 tampilkan to show 7 3.32
9 saksikan to watch; to witness 6 2.84
10 siratkan to display 3 1.42

These two aspects are captured via three submappings. The most frequent one is the existence of happiness is visibility of an object (58.77%), based on the seeing frame

The second submapping is based on the cause to see frame, namely expressing happiness is showing an object (31.28%).

The third submapping is regulating happiness is hiding an object (9.95%). This mapping is expressed by lexical units (LUs) from the visual obstruction frame. In seventeen tokens of the total 21 citations of this submapping, the LUs co-occur with abilitative modal auxiliaries (i.e. dapat/bisa ‘can’, mampu/sanggup ‘be able to’). Yet, sixteen of these seventeen tokens are negated. Overall, including tokens without the abilitative modals, 85.71% citations of the regulating happiness is hiding an object are negated. This points to the focus on the inability to conceal the emotion.

Linguistically, happiness is an (un)veiled object metaphor also has a low percentage of variation for the evoking LUs (10.9%). It is predominantly evoked by lihat ‘to see/look at’, terlihat, ‘to be visible’, (t/n)ampak ‘to be visible’, and tunjukkan ‘to show’

2.9 Happiness is a submerged entity

## submappings
submerged_submappings <- happyr::get_submappings("submerged", df = happyr::phd_data_metaphor)
## lexical unit table
submerged_lu <- happyr::get_lu_table("submerged", df = happyr::phd_data_metaphor)
submerged_lu %>%
  knitr::kable(caption = 'Top-10 most frequent lexical units evoking the <span style = "font-variant:small-caps;">happiness is a submerged entity</span>.', row.names = TRUE)
Lexical_units Gloss N Perc_overall
1 muncul to emerge 30 30.30
2 timbulkan to cause to surface (from within the water, ground, etc.) 30 30.30
3 timbul to surface (from within the water, ground, etc.) 21 21.21
4 munculkan to bring sth. out to the open 9 9.09
5 timbulnya surfacing/emergence 2 2.02
6 angkat to lift/bring up 1 1.01
7 cuatkan to cause to protrude 1 1.01
8 kemunculan emergence 1 1.01
9 mencuat to protrude; to stick out 1 1.01
10 menyeruak to make way through 1 1.01
11 pancing.v to fish 1 1.01
12 terbitkan to bring sth. to the surface 1 1.01

Linguistically, the metaphor is proportionally less varied in its lexical realisation (12.12% of lexical variation), given its token frequency. The high token frequency of the metaphor is accounted for mostly by the first three LUs in Table @ref(tab:lu-submerged-entity), taking up 90.9% of the metaphor’s token frequency.

In general, all the metaphorical expressions of happiness is a submerged entity indicate the manner through which happiness may exist. Namely, existence of happiness is understood as a surfacing or outward motion of an Entity, be it (i) naturally emerging (56.57%) or (ii) caused to emerge by some agent (43.43%).

2.10 Happiness is food

## submappings
food_submappings <- happyr::get_submappings('food', df = happyr::phd_data_metaphor)
# frames
food_frames <- happyr::get_frames("food", df = happyr::phd_data_metaphor)
# LU by frames
food_lu_frames <- happyr::get_lu_table("food", df = happyr::phd_data_metaphor)
# LU by submappings
food_lu_submappings <- happyr::get_lu_submappings_table("food", df = happyr::phd_data_metaphor)
# frames and submappings
food_frames_submappings <- happyr::phd_data_metaphor %>% 
  filter(metaphors == 'happiness is food') %>% 
  count(source_frames, submappings) %>% 
  ungroup() %>% 
  group_by(source_frames) %>% 
  mutate(perc = round(n/sum(n) * 100, 2)) %>% 
  rename(frames = source_frames) %>% 
  ungroup()
## LU table
happyr::get_lu_table("food", df = happyr::phd_data_metaphor) %>%
  knitr::kable(caption = 'All lexical units evoking <span style = "font-variant:small-caps;">happiness is food</span>.', row.names = TRUE)
Lexical_units Gloss N Perc_overall
1 nikmati to taste-while-enjoying 80 74.07
2 sajikan to serve (of food) 5 4.63
3 kecap to taste 4 3.70
4 cecap to lick and taste 2 1.85
5 cicipi to taste 2 1.85
6 kecapi to taste 2 1.85
7 reguk to gulp down 2 1.85
8 resep recipe 2 1.85
9 bumbui to spice up 1 0.93
10 kenyam to taste 1 0.93
11 makanan food 1 0.93
12 manis sweetness 1 0.93
13 penikmat connoisseur 1 0.93
14 rasai to taste 1 0.93
15 suguhkan to serve (of food) 1 0.93
16 telan to swallow 1 0.93
17 tersaji to be served 1 0.93

Happiness is food metaphor is based on several frames related to gastronomical experience. These include the food frame itself (0.93%), ingestion (2.78%), food preparation11 (9.26%), and, most predominantly, taste (87.04%).

Most of the lexical units (LUs) in this frame profiles the serving stage of the food preparation (70%)

This is indicated especially by a high proportion of one LU, namely nikmati ‘to taste-while-enjoying’, taking up 74.07% of all tokens of the metaphor.

2.11 The co-occurrence of body-part terms and the metaphors

happyr::plot_body_part(df = happyr::phd_data_metaphor)

# body-part gloss
bp_gloss <- tibble(gloss = c('chest/bosom', 'self', 'liver', 'eyes', 'face', 'body', 'face', 'face', 'deepest part of the heart', 'lips', 'mouth', 'body; bodily'), body_part_terms = c('dada', 'diri', 'hati', 'mata', 'muka', 'tubuh', 'wajah', 'paras', 'lubuk kalbu', 'bibir', 'mulut', 'jasmani'))
# generate the table
happyr::phd_data_metaphor %>% 
  filter(body_part_inclusion %in% c('y')) %>% 
  count(body_part_terms, metaphors) %>% 
  arrange(desc(n)) %>% 
  ungroup() %>% 
  left_join(bp_gloss, by = 'body_part_terms') %>%
  select(metaphors, body_part_terms, gloss, n) %>% 
  mutate(metaphors = happyr::scaps(metaphors), 
         body_part_terms = paste("*", body_part_terms, "* '", gloss, "'", sep = "")) %>%
  rename(Body_parts = body_part_terms, Metaphors = metaphors, N = n) %>%
  select(-gloss) %>%
  top_n(10, N) %>%
  knitr::kable(caption = 'The ten most frequent <span style="font-variant:small-caps;">Body-part</span>`*`<span style="font-variant:small-caps;">Metaphors</span> co-occurrence for <span style="font-variant:small-caps;">Happiness</span> in Indonesian.', row.names = TRUE)
Metaphors Body_parts N
1 happiness is an (un)veiled object wajah 'face' 45
2 happiness is a liquid in a container wajah 'face' 27
3 happiness is a contained entity hati 'liver' 17
4 happiness is a contained entity wajah 'face' 12
5 happiness is a located object wajah 'face' 8
6 happiness is an embellishment wajah 'face' 8
7 happiness is light wajah 'face' 8
8 happiness is a contained entity dada 'chest/bosom' 7
9 happiness is a liquid in a container mata 'eyes' 7
10 happiness is a drawing wajah 'face' 7

3 Codes for Chapter 6 - Productive and Creative Metaphors

3.1 Productive metaphors

productive_metaphor <- ttr_metaphor %>% 
  arrange(desc(type_lu)) %>% 
  top_n(10, type_lu)
productive_metaphor %>% 
select(Metaphors = metaphors,
       Token = token,
       `%Token` = perc_token,
       Type = type_lu,
       `%Type` = perc_type_lu) %>% 
  knitr::kable(caption = 'Top-10 metaphors sorted on their type frequency.', row.names = TRUE)
Metaphors Token %Token Type %Type
1 happiness is a possessable object 749 20.59 63 7.84
2 happiness is a desired goal 293 8.05 42 5.22
3 happiness is a liquid in a container 156 4.29 37 4.60
4 happiness is a location 169 4.65 35 4.35
5 intensity of happiness is quantity of object 137 3.77 29 3.61
6 happiness is light 43 1.18 27 3.36
7 happiness is a contained entity 358 9.84 26 3.23
8 happiness is a located object 210 5.77 26 3.23
9 happiness is an (un)veiled object 211 5.80 23 2.86
10 happiness is an imperilled entity 32 0.88 21 2.61

Table @ref(tab:top-type-ttr) shows the reverse ranking of the top-10 metaphors with high type frequency according to their type-per-token ratio.

productive_metaphor %>% 
  arrange(desc(type_per_token_lu)) %>% 
  select(Metaphors = metaphors,
         Token = token,
         Type = type_lu,
         `Type/token ratio (in %)` = type_per_token_lu) %>% 
  knitr::kable(caption = 'Metaphors with high type frequency ordered according their Type/Token Ratio (TTR).', row.names = TRUE)
Metaphors Token Type Type/token ratio (in %)
1 happiness is an imperilled entity 32 21 65.62
2 happiness is light 43 27 62.79
3 happiness is a liquid in a container 156 37 23.72
4 intensity of happiness is quantity of object 137 29 21.17
5 happiness is a location 169 35 20.71
6 happiness is a desired goal 293 42 14.33
7 happiness is a located object 210 26 12.38
8 happiness is an (un)veiled object 211 23 10.90
9 happiness is a possessable object 749 63 8.41
10 happiness is a contained entity 358 26 7.26

3.1.1 Happiness is light

# submapping
light_submapping <- happyr::get_submappings("light", df = happyr::phd_data_metaphor)
# submapping generalised/schematised: (i) emission of light and (ii) darkening
light_submapping_generalised <- light_submapping %>%
  mutate(generalised_submappings = if_else(str_detect(submappings, 'darkening'), 
                                           'darkening_light', 
                                           'emitting_light')) %>%
  group_by(generalised_submappings) %>% 
  summarise(n = sum(n), 
            type_generalised = sum(type)) %>%
  ungroup() %>%
  mutate(perc_type_generalised = round(type_generalised/sum(type_generalised) * 100, 2), 
         perc_generalised = round(n/sum(n) * 100, 2))
# lexical unit and their "emitting" semantics
light_lu_emitting_semantics <- happyr::phd_data_metaphor %>% 
  filter(str_detect(metaphors, "light")) %>% 
  select(lu)
dim_light <- c('pudar', 'kelabu')
brief_light <- c('bayangan', 'membayang', 'terbersit', 'sebersit', 'secercah', 'sekilas', 'terbayang')
bright_light <- c('berkilauan', 'bersinar terang', 'mentari', 'semarakkan', 'semburatkan', 'sinarkan', 'terangi')
light_lu_emitting_semantics <- light_lu_emitting_semantics %>%
  mutate(luminousity = if_else(lu %in% dim_light, 'darkening', 'neutral'),
         luminousity = if_else(lu %in% brief_light, 'brief_light', luminousity),
         luminousity = if_else(lu %in% bright_light, 'shining_light', luminousity))
# tebersit -> radiates suddenly vaguely
# sebersit -> radiates light in small amount
# secercah -> small amount of light
# lexical unit table
light_lu_table <- happyr::get_lu_table("light$", 
                                    top_n_only = TRUE,
                                    df = happyr::phd_data_metaphor)
# number of hapax LU
light_lu_length <- dim(light_lu_table)[1]
light_hapax_length <- dim(filter(light_lu_table, N == 1))[1]
# print the lu table
light_lu_table %>%
  knitr::kable(caption = 'Lexical units evoking <span style = "font-variant:small-caps;">happiness is light</span>', row.names = TRUE)
Lexical_units Gloss N Perc_overall
1 cerminkan to mirror/reflect sth. 5 11.63
2 sinar light 5 11.63
3 binar light 4 9.30
4 bayangan shadow 2 4.65
5 cahaya light 2 4.65
6 membayang to loom on 2 4.65
7 pudar to be dim 2 4.65
8 terbersit to be flashed across 2 4.65
9 berkilauan to be glittering 1 2.33
10 bersinar terang to shine brightly 1 2.33
11 biaskan to refract sth. 1 2.33
12 cerminan reflection 1 2.33
13 kelabu gray 1 2.33
14 lampu lamp 1 2.33
15 membias to refract 1 2.33
16 mentari sun 1 2.33
17 pantulkan to refract (light) 1 2.33
18 pencerahan enlightment 1 2.33
19 sebersit a ray of sth. 1 2.33
20 secercah a ray of sth. 1 2.33
21 sekilas a flash of sth. 1 2.33
22 semarakkan to brighten sth. up 1 2.33
23 semburatkan to cause sth. to shine 1 2.33
24 sinarkan to cause to shine 1 2.33
25 terangi to cast light on sth. 1 2.33
26 terbayang to be loomed on 1 2.33
27 tercermin to be mirrored/reflected 1 2.33

Most of the LUs (70.37% of the total 27 types) are singletons (i.e., occurring only once), which are also termed as hapax legomena or hapaxes (Hilpert, 2014, p. 82).

3.1.2 Happiness is an imperilled entity

# submappings
endangered_submapping <- happyr::get_submappings("imperilled", df = happyr::phd_data_metaphor) %>% 
  mutate(submappings = str_replace(submappings, "destroyed object", "harmed entity"))
# frames
endangered_frame <- happyr::get_frames("imperilled", df = happyr::phd_data_metaphor)
# lexical units table
endangered_lu <- happyr::get_lu_table("imperilled", top_n_only = TRUE, df = happyr::phd_data_metaphor)
endangered_lu_hapax <- dim(filter(endangered_lu, N == 1L))[1]
endangered_lu %>%
  knitr::kable(caption = 'Lexical units evoking <span style = "font-variant:small-caps;">happiness is an imperilled entity</span>', row.names = TRUE)
Lexical_units Gloss N Perc_overall
1 rusak.v-tr to damage 6 18.75
2 hancurkan to destroy sth. 4 12.50
3 pertahankan to defend/protect 3 9.38
4 simpan to keep in a safe place 2 6.25
5 ancam to threaten 1 3.12
6 bahayakan to endanger 1 3.12
7 borbardir to bombard 1 3.12
8 hancur.v-intr to shatter 1 3.12
9 hantam to hit/fist sth. 1 3.12
10 hapus to erase 1 3.12
11 jaga to guard/protect 1 3.12
12 kepingan-kepingan splinters 1 3.12
13 koyak to rip-up 1 3.12
14 luluh to shatter 1 3.12
15 luruh to shatter 1 3.12
16 musnah to be obliterated 1 3.12
17 pelihara to take care 1 3.12
18 perjuangkan to fight/struggle for 1 3.12
19 pulih to be repaired/restored 1 3.12
20 pulihkan to repair/restore 1 3.12
21 rawat to take care/maintain 1 3.12

The happiness is an imperilled entity makes use of elements from several frames that broadly belong to the harm frame family (cf. Dodge, 2016, pp. 282–286) (see also discussion in § XXX below). These frames include destroying (56.25%), protecting (28.12%), danger (6.25%), rejuvenation (6.25%), and impact (3.12%). These frames are available in the MetaNet frame repository, except for rejuvenation which is taken from the FrameNet repository.

Inference from the constituting frames contributes quite rich metaphorical construal related to the above main theme. The predominant submapping, namely negatively affecting happiness is harming an entity (43.75%) makes use of the Harmful_effect_process role of the physical harm frame.

Further inference from this harm metaphor model is that the results of the harmful action can be a complete dysfunction or undesirable condition of the entity (e.g., being destroyed). This knowledge is carried over to the target domain to conceptualise the complete ceasing of happiness. Hence, end of happiness is a harmed entity (15.62%) submapping.

The twists of these negative consequences may include two scenarios that can be recast as two submappings. The first is maintaining happiness is protecting an asset (28.12%); the second is restoring happiness is repairing a harmed entity (6.25%). These scenarios suggest the importance for the experiencer to look after and maintain h(is/er) well-being.

Most of the LUs for happiness is an imperilled entity occur only once (80.95% of the total 21 LU types).

3.2 Creative metaphors

less_thanthree_metaphors <- ttr_metaphor %>% 
  filter(token <= 2L) %>% 
  .$metaphors
min_freq <- 3L
creative_metaphors <- happyr::get_creative_metaphors(ttr_metaphor)
creative_metaphors %>%
  mutate(metaphors = happyr::scaps(metaphors)) %>% 
  select(Metaphors = metaphors,
         Token = token,
         Type = type_lu,
         `Type/token ratio (in%)` = type_per_token_lu) %>% 
  knitr::kable(caption = paste('Top-10 lexically varied metaphors sorted based on the TTR value and occurring at least ', happyr::numbers2words(min_freq), ' tokens.', sep = ""), row.names = TRUE)
Metaphors Token Type Type/token ratio (in%)
1 happiness is a harmful agent 11 11 100.00
2 happiness is drugs 6 6 100.00
3 happiness is a moved entity 4 4 100.00
4 happiness is a treatment tool 3 3 100.00
5 happiness is an accompanied object 3 3 100.00
6 happiness is being soaked 9 8 88.89
7 happiness is a resource 8 7 87.50
8 happiness is impediment to motion 6 5 83.33
9 happiness is a deceiver 20 16 80.00
10 happiness is an adversary 24 19 79.17

3.2.1 Happiness is a harmful agent

# submappings
harmful_submappings <- happyr::get_submappings("harmful agent", df = happyr::phd_data_metaphor)
# frames
harmful_frames <- happyr::get_frames("harmful agent", df = happyr::phd_data_metaphor)
harmful_lu <- happyr::get_lu_table("harmful agent", df = happyr::phd_data_metaphor)
harmful_lu %>% 
  knitr::kable(caption = paste("Lexical units evoking ", happyr::scaps("happiness is a harmful agent"), sep = ""), row.names = TRUE)
Lexical_units Gloss N Perc_overall
1 hapus to erase 1 9.09
2 iris-iris to slice 1 9.09
3 kuat strong 1 9.09
4 landa to run/knock down sth. 1 9.09
5 lebur dalam to be destroyed/deformed 1 9.09
6 luluh to be crushed 1 9.09
7 menguat to become strong 1 9.09
8 menyakitkan hurting; lit. to cause to hurt 1 9.09
9 perkuat to strengthen 1 9.09
10 terkena to get hit 1 9.09
11 torehkan to incise 1 9.09

The predominant submapping is experiencing intense emotion is being harmed or strong emotional effect is physical harm (45.45% of the total 11 tokens of the metaphor).

3.2.2 Negative construal of happiness

3.2.2.1 Happiness is an adversary

# data frame on the opponent type in the adversary metaphor
adversary_df <- tribble(
  ~opponent, ~opponent_lu, ~m_expr,
  #--/--
   "self", "pers_pronoun", "diuji dengan NP",
   "self_impl", NA, "diuji dengan NP",
   "abstract_states_impl", NA, "dominasi NP",
   "abstract_entity", "pramuka", "kalah dengan NP",
   "self", "pers_pronoun", "kelemahan terhadap NP",
   "concrete", "kondom", "melawan NP",
   "self", "proper_name", "menaklukkan rayuan NP",
   "self_impl", NA, "menekan NP",
   "self_impl", NA, "menentang NP",
   "self", "pers_pronoun", "menghadapi NP",
   "self_impl", NA, "NP adalah musuh",
   "self_impl", NA, "NP adalah ujian",
   "abstract_entity", "kehidupan", "NP ancaman kepada kehidupan",
   "abstract_states", "kegetiran", "NP dan kegetiran berebut tempat dalam jiwa",
   "abstract_states", "kepahitan hidup", "NP dikalahkan oleh kepahitan hidup",
   "abstract_states_impl", NA, "NP mendominasi",
   "abstract_states", "kerendahan hati", "NP menekuk kerendahan hati",
   "abstract_states", "keraguan", "NP mengalahkan keraguan",
   "abstract_states", "rasa lelah", "NP mengatasi rasa lelah",
   "self", "pers_pronoun", "NP X hadapi",
   "abstract_states", "kelelahan", "NP yang mengatasi kelelahan",
   "abstract_states", "kebutuhan", "pertentangan antara NP dan kebutuhan",
   "self", "orang", "ujian NP",
   "self_impl", "energy", "NP menyedot energi"
)
# data only for self-opponent of the emotion
self_opponent <- adversary_df %>% 
  filter(str_detect(opponent, 'self')) %>% 
  count(opponent) %>% 
  mutate(perc = round(n/sum(n)*100, 2))
# opponent types all
opponent <- adversary_df %>% 
  count(opponent) %>% 
  arrange(desc(n)) %>% 
  mutate(generic_opponent = if_else(str_detect(opponent, 'abstract'), 
                                    'abstract_entity/states', 'self'), 
         generic_opponent = if_else(str_detect(opponent, 'concrete'), 
                                    'other_concrete_entity', generic_opponent)) %>% 
  group_by(generic_opponent) %>% 
  summarise(n = sum(n)) %>%
  mutate(perc = round(n/sum(n)*100, 2))
# opponent types "self" vs "others"
opponent2 <- opponent %>% 
  mutate(generic_opponent = replace(generic_opponent, !str_detect(generic_opponent, 'self'), 'non-self')) %>% 
  group_by(generic_opponent) %>% 
  summarise(n = sum(n)) %>% 
  mutate(perc = round(n/sum(n)*100, 2))
# print the LU for the adversary metaphor
happyr::get_lu_table("adversary", df = happyr::phd_data_metaphor) %>% 
  knitr::kable(caption = paste("Lexical units evoking ", happyr::scaps("happiness is an adversary"), sep = ""), row.names = TRUE)
Lexical_units Gloss N Perc_overall
1 atasi to overcome 2 8.33
2 hadapi to confront 2 8.33
3 kalahkan to defeat 2 8.33
4 uji.v to challenge/test 2 8.33
5 ujian challenge/test 2 8.33
6 ancaman threat 1 4.17
7 berebut tempat fight for a place 1 4.17
8 dominasi dominance 1 4.17
9 dominasi.v to dominate 1 4.17
10 kalah dengan to be defeated with sth. 1 4.17
11 kelemahan terhadap weakness towards sth. 1 4.17
12 lawan.v to fight sth. 1 4.17
13 musuh enemy 1 4.17
14 pertentangan antara dispute between sth. 1 4.17
15 sedot to suck 1 4.17
16 taklukkan to defeat 1 4.17
17 tekan to hold down 1 4.17
18 tekuk to cause to surrender 1 4.17
19 tentang.v-tr to dispute 1 4.17

However, things are not always as neat as in the theory when looking at the real usage data. From 24 tokens of happiness is an adversary, half of the tokens indicate that the opponent can indeed be understood as the Experiencer.

3.2.2.2 Happiness is a deceiver

# print the LU
happyr::get_lu_table("deceiver", df = happyr::phd_data_metaphor) %>% 
  knitr::kable(caption = paste("All lexical units evoking ", happyr::scaps("happiness is a deceiver"), sep = ""), row.names = TRUE)
Lexical_units Gloss N Perc_overall
1 menipu to deceive 3 15
2 godaan entice/seduction 2 10
3 terlena to be lulled 2 10
4 dilupakan oleh to cause into oblivion 1 5
5 leka dengan to be negligent/engrossed 1 5
6 memanjakan to pamper sb. 1 5
7 meninabobokkan to lull sb. 1 5
8 pesona magic spell 1 5
9 rayuan flaterry/seduction 1 5
10 tergiur to be tempted 1 5
11 tergoda to be seduced/enticed 1 5
12 terpesona to be spellbound 1 5
13 tersesatkan to be misled 1 5
14 tersihir to be bewitched 1 5
15 tertipu to be deceived 1 5
16 tipu muslihat cunning tricks 1 5

3.2.2.3 Happiness is drugs

  • No inline computation code is needed

3.2.2.4 Happiness is impediment to motion

# submapping
motion_imped_submappings <- happyr::get_submappings("impediment to motion$", df = happyr::phd_data_metaphor)

All these inferences express the submapping happiness/being happy is being restrained, which is the most frequent of all cases (66.67% of the total tokens of the metaphor).

The other expressions evoke a submapping based on the burden frame (16.67%) and the motion-affecting properties of the landscape frame (16.67%), the latter of which is the sister frame of the motion-affecting objects frame.

3.2.3 Positive phenomenology of happiness

3.2.3.1 Happiness is being soaked

happyr::get_lu_table("soaked", df = happyr::phd_data_metaphor) %>% 
  knitr::kable(caption = paste("All lexical units evoking ", happyr::scaps("happiness is being soaked"), sep = ""), row.names = TRUE)
Lexical_units Gloss N Perc_overall
1 bergelimang to be smeared (with substance) 2 22.22
2 basuh to wash 1 11.11
3 berkubang to wallow in sth. 1 11.11
4 bermandi to be bathed 1 11.11
5 disimbah to be drenched 1 11.11
6 percikkan to splash/sprinkle 1 11.11
7 selami to dive/plunge 1 11.11
8 siramkan to flash/water/splash sth. 1 11.11

3.2.3.2 Happiness is a treatment tool

  • no inline computation code is needed

3.2.3.3 Happiness is a resource

# submappings
resource_submappings <- happyr::get_submappings("resource$", df = happyr::phd_data_metaphor)
# lexical unit table
resource_lu <- happyr::get_lu_table("resource$", df = happyr::phd_data_metaphor)
# print with `kable()`
resource_lu %>% 
  knitr::kable(caption = paste("All lexical units evoking ", happyr::scaps("happiness is a resource"), sep = ""), row.names = TRUE)
Lexical_units Gloss N Perc_overall
1 tersedia to be available 2 25.0
2 habiskan to use up 1 12.5
3 olah to process (of a raw resource) 1 12.5
4 saklar (electric) switch 1 12.5
5 sediakan to provide 1 12.5
6 sia-siakan to waste 1 12.5
7 suplai supply 1 12.5

3.2.4 Other creative metaphors

3.2.4.1 Happiness is a moved entity

In that forced movement scenario, the happiness is a moved entity metaphor is motivated by the role-mapping of the happiness noun onto the Mover role. There are only four tokens for this mapping.

3.2.4.2 Happiness is an accompanied object

There are only three tokens for happiness is an accompanied object.

4 Codes for Chapter 7 - Distinctive metaphors for happiness near-synonyms in Indonesian

4.1 Multiple distinctive collexeme analysis in action

# MDCA for metaphor * synonyms with concise output
mdca_res <- happyr::mdca(df = happyr::phd_data_metaphor, concise_output = TRUE)
# MDCA for metaphor * synonyms with full output (i.e., include exp_probability, synonyms frequency); this is for the purpose of illustrating the MDCA in the chapter
mdca_res_full <- happyr::mdca(df = happyr::phd_data_metaphor, concise_output = FALSE)
# gloss table for synonyms
syn_gloss <- tribble(~synonyms, ~gloss, ~form, ~source,
                     "riang", "very happy, joyous, glad", "root", "S&ST.2004.p.830",
                     "gembira", "excited, enthusiastic, exuberant, ...", "root", "S&ST.2004.p.311",
                     "ceria", "pure, clean, clear; cheerful", "root", "S&ST.2004.p.198",
                     "bahagia", "(peaceful and) happy; happiness; luck(y), good fortune; welfare", "root", "S&ST.2004.p.75",
                     "senang", "happy, to feel well, contented, satisfied", "root","S&ST.2004.p.909",
                     "keriangan", "cheer(fulness), happiness, joy", "nominalised", "S&ST.2004.p.830",
                     "keceriaan", "purity; cheerfulness", "nominalised","S&ST.2004.p.198",
                     "kebahagiaan", "happiness, prosperity and contentment", "nominalised","S&ST.2004.p.75",
                     "kegembiraan", "joy, cheerfulness, high spirits", "nominalised","S&ST.2004.p.311",
                     "kesenangan", "pleasure, happiness, enjoyment, ...", "nominalised", "S&ST.2004.p.909") %>%
  select(synonyms, form, gloss, source) %>%
  arrange(desc(form), synonyms)
# mdca for window-span collocational data
mdca_colloc <- happyr::mdca(df = happyr::colloc_input_data, coll_var = "collocates")
# retrieve the example table
example_df <- mdca_res %>% 
  filter(str_detect(metaphors, "desired")) %>% 
  select(-metaphors) %>% 
  arrange(desc(assocstr))
# count the freq of the metaphors
metaphor_token <- dplyr::count(happyr::phd_data_metaphor, metaphors, sort = TRUE)
# count the freq of the synonyms
synonym_token <- dplyr::count(happyr::phd_data_metaphor, synonyms, sort = TRUE)
# input data
input_snippet <- mdca_res_full %>% 
  filter(str_detect(metaphors, "desired")) %>% 
  select(synonyms, n, cxn_sum) %>% 
  mutate(others = cxn_sum - n) %>% 
  select(synonyms, n, others, total = cxn_sum)
input_snippet <- input_snippet %>%
  bind_rows(input_snippet %>% 
              summarise_if(is.numeric, sum) %>% 
              mutate(synonyms = "total") %>% 
              select(synonyms, everything()))
# tokens for the examples in the text
obs_bhg <- filter(example_df, synonyms == "kebahagiaan")[["n"]]
sum_bhg <- filter(synonym_token, synonyms == "kebahagiaan")[["n"]]
exp_bhg <- filter(example_df, synonyms == "kebahagiaan")[["exp"]]
meta_destination <- filter(metaphor_token, str_detect(metaphors, "desired goal"))[["n"]]
exp_prob <- exp_bhg/meta_destination
# print out the results for example with 'DESIRED GOAL/DESTINATION'
example_df %>%
  mutate(gloss = c("happiness", 
                   "pleasure", 
                   "(peaceful and) happy; happiness", 
                   "very happy, joyous", 
                   "cheerful; lit. pure, clean", 
                   "happy, to feel well, contented", 
                   "excited, enthusiastic", 
                   "cheer(fulness)", 
                   "purity; cheerfulness", 
                   "joy, cheerfulness"),
         synonyms = paste("*", synonyms, "*", sep = ""),
         exp = round(exp, 3L)) %>%
  select(synonyms, gloss, everything()) %>%
  as.data.frame() %>%
  knitr::kable(caption = '*Observed* frequency (`n`), *expected* frequency (`exp`), and *Association Strength* (`assocstr`) for <span style="font-variant:small-caps";>happiness is a desired goal/destination</span> across the synonyms.', row.names = TRUE)
synonyms gloss n exp assocstr p_binomial p_holm dec
1 kebahagiaan happiness 125 55.169 20.208 6.190e-21 3.838e-18 ***
2 kesenangan pleasure 110 51.625 15.265 5.430e-16 3.351e-13 ***
3 bahagia (peaceful and) happy; happiness 34 28.752 0.758 1.745e-01 1.000e+00 ns
4 riang very happy, joyous 0 0.966 -0.420 3.798e-01 1.000e+00 ns
5 ceria cheerful; lit. pure, clean 0 3.141 -1.371 4.251e-02 1.000e+00 ns
6 senang happy, to feel well, contented 5 15.383 -2.756 1.753e-03 1.000e+00 ns
7 gembira excited, enthusiastic 0 6.363 -2.794 1.608e-03 9.215e-01 ns
8 keriangan cheer(fulness) 3 17.477 -4.729 1.867e-05 1.119e-02 *
9 keceriaan purity; cheerfulness 10 60.082 -16.982 1.042e-17 6.440e-15 ***
10 kegembiraan joy, cheerfulness 6 54.042 -17.855 1.398e-18 8.652e-16 ***

The observed co-occurrence frequency between kebahagiaan and metaphorical patterns evoking the happiness is a desired goal/destination is 125 tokens. In addition to this observed co-occurrence frequency, one also needs the expected frequency for the co-occurrence between happiness is a desired goal/destination and kebahagiaan (column “exp” in Table @ref(tab:example-data-print)). The expected frequency (for a metaphor and a synonym) represents the frequency that one would expect under the null-hypothesis that the proportion of the metaphor were equally distributed across all synonyms under study; in other words, the null-hypothesis states that there are no distributional differences for the metaphor with each synonym (cf. Levshina, 2015, pp. 210–211). The expected frequency for our example is arrived at by multiplying (i) the total frequency of kebahagiaan in the sample, i.e., 685, with (ii) the total frequency of happiness is a desired goal/destination occurring with any synonyms in the sample, i.e., 293, then (iii) dividing the results with the total metaphorical tokens in the sample, i.e., 3638; hence (685*293)/3638 = 55.1690489.

Difference between the observed and expected frequencies allows us to determine the direction of the association between the co-occurring items. The association can be (i) positive, if the observed frequency exceeds the expected frequency, or (ii) negative, if the observed frequency is below the expected frequency. The comparison between the expected and the observed frequency in Table @ref(tab:example-data-print) for happiness is a desired goal/destination with kebahagiaan indicates positive association, or attraction, between the metaphor and the synonym since the observed frequency of 125 is higher than the expected frequency of 55.1690489 (cf. Hilpert, 2006a, p. 247). Additional value required by the Binomial Test in MDCA is the a priori probability that if kebahagiaan is used metaphorically it will occur in metaphorical patterns evoking happiness is a desired goal/destination. This probability is calculated by dividing (i) the expected frequency of kebahagiaan with the metaphor (i.e., 55.1690489) against (ii) the total frequency of the metaphor in the sample (i.e., 293), hence (55.1690489/293) equals 0.1882903 (Hilpert, 2006a, p. 247).

The observed co-occurrence frequency, the total frequency of the metaphor, and the a priori probability then become the inputs for the one-tailed Binomial Test implemented in MDCA. Given our example, the Binomial Test will determine the Binomial p-value indicating the probability that the observed co-occurrence frequency of 125, or even more often, for kebahagiaan and happiness is a desired goal/destination would have come about by chance, given the null-hypothesis of equal distribution for a metaphor with all synonyms. The code-chunk below shows the R code to perform one-tailed Binomial Test for our example:

# For one-tailed test, the *alternative* argument in the code is set to 'greater' 
# when the co-occ.freq is higher than expected; it set to "less" when otherwise.
binom.test(x = 125, # co-occ.freq between "kebahagiaan" and the "desired goal" metaphor
           n = 293, # total tokens of the "desired goal" metaphor
           p = 0.1882903, # a priori probability
           alternative = "greater" 
           )$p.value # retrieve only the binomial p-value
[1] 6.190218e-21

The resulting pBinomial-value here is small (i.e., 6.190131e-21)12. This value indicates that there is a very low probability that we observe this co-occurrence distribution of 125 tokens, or even more, between kebahagiaan and happiness is a desired goal/destination if there is no/neutral association between them. Similar calculation as above is done for the co-occurrence frequencies of each synonyms with the metaphors. The code-chunk below illustrates the computation of the pBinomial-value when the co-occurrence frequency is less than expected, as in between kegembiraan ‘joy’ and the happiness is a desired goal/destination metaphor (cf. Table @ref(tab:example-data-print)).

binom.test(x = 6, # co-occ.freq between "kegembiraan" and the "desired goal" metaphor
           n = 293, # total tokens of the "desired goal" metaphor
           p = 0.184442, # a priori probability
           alternative = "less" 
           )$p.value # retrieve only the binomial p-value
[1] 1.397791e-18

As in most Collostructional Analysis studies, the p-values of the Binomial Test in this case are used directly as the measure for association strength. The small pBinomial-value and the positive deviation of the observed frequency from the expected one for our example with kebahagiaan ‘happiness’ indicates significantly high degree of association (viz. attraction) between kebahagiaan and happiness is a desired goal/destination. For expository reason, Collostructional Analysis log10-transforms the pBinomial-value into the so-called Coll(ostruction) Str(ength) value; in this thesis, it is referred to as the Assoc(iation) Str(ength) value (cf. the "assocstr" column in Table @ref(tab:example-data-print)) (Stefanowitsch & Gries, 2005, p. 7). Positive or negative signs are set in the AssocStr values to indicate the direction of association. Positive AssocStr values indicate attraction (i.e., the observed co-occurrence frequency is higher than the expected frequency); it is derived from the negative log10-transformed pBinomial-value, as shown below for the kebahagiaan ‘happiness’ example.

# get the p-value of the Binomial Test
p_binomial <- binom.test(x = 125, n = 293, p = 0.1882903, alternative = "greater")$p.value
# negative log10 for the p-binom for the *kebahagiaan* data
-log10(x = p_binomial)
[1] 20.20829

Meanwhile, negative AssocStr values indicate repulsion (i.e., the observed co-occurrence frequency is less than expected); it is derived from the positive log10-transformed pBinomial-value, as shown below for the kegembiraan ‘joy’ example.

# get the p-value of the Binomial Test
p_binomial <- binom.test(x = 6, n = 293, p = 0.184442, alternative = "less")$p.value
# positive log10 for the p-binom for the *kegembiraan* data
log10(x = p_binomial)
[1] -17.85456

One can notice from Table @ref(tab:example-data-print) that happiness is a desired goal/destination is also significantly distinctive to kesenangan ‘pleasure’, though in a lower degree compared to kebahagiaan, as reflected in the AssocStr values between the two; qualitatively, it will be shown that kesenangan and kebahagiaan differ in relation to the preferred submappings of the happiness is a desired goal/destination (cf. §@ref(bahagia) and §@ref(senang)). This kind of multiple association of an item (i.e., a metaphor) to more than one construction of interest (i.e., the synonyms) is not uncommon in MDCA, as Gilquin (2010, p. 201, Table 60) has shown in her study of ten periphrastic causative constructions in English. Yet, the AssocStr values of the shared, attracted item with the constructions can be used to assume the relative association strength of the item with the constructions.

In Collostructional Analysis, the commonly used cut-off points in indicating significant association strength is AssocStr > 1.30103, which is equal to pBinomial < 0.05 (Stefanowitsch & Gries, 2005, p. 7). Higher cut-off points can also be used: (i) AssocStr > 2, which is equal to pBinomial < 0.01, and (ii) AssocStr > 3, which is equal to pBinomial < 0.001. These AssocStr threshold values will be marked with negative sign when the co-occurrence frequencies are less than expected. For each synonym, the AssocStr values of the metaphors can be sorted from the highest (positive) to the lowest (down to the negative values). This will rank the metaphors from the most distinctive ones to the most strongly repelled. Table @ref(tab:example-data-print) illustrates that significant repulsion for the metaphor according to the cut-off points can be seen from row number five. That is, starting from ceria ‘cheerful’ (AssocStr = -1.371) down to keceriaan ‘cheerfulness’ (AssocStr = -16.982) and kegembiraan ‘joy, cheerfulness’ (AssocStr = -17.855), the two synonyms showing the strongest dissociation with happiness is a desired goal/destination metaphor.

The AssocStr-based ranked-list of the metaphors for each synonym is a starting point for qualitative discussion concerning the way semantically similar emotion concepts are characterised by, and vary in terms of, certain distinctive and repelled metaphors. In other words, a set of metaphors are strongly distinctive for an emotion compared to its synonyms presumably because these metaphors map conceptual knowledge that best characterises the semantic foci of the emotion. The repelled metaphors may then indicate the less entrenched metaphorical model in conceptualising the given emotion.

In relation to the aim of this chapter, the example in Table @ref(tab:example-data-print) minimally confirms Kövecses’ assumption regarding the existence of principal, or distinctive, metaphors distinguishing near-synonyms of emotions. After all, it is a basic assumption in Cognitive Linguistics, in relation to its usage-based tenet (Evans & Green, 2006, p. 122), that different usage forms (e.g. metaphorical patterns) of a linguistic unit (e.g. an emotion lexeme), have impacts on its meaning (e.g. its metaphorical construal). Nevertheless, given such quantitative method as MDCA, this usage-based assumption can be fleshed out, and the way a set of emotion synonyms differ in their preferred metaphorical conceptualisations can be spelled out more explicitly.

Note that MDCA, and the other members of Collostructional Analysis, involves repeated significance testing on the same data set (Stefanowitsch & Gries, 2005, p. 36, endnote 3, 2009, p. 944). As a rule-of-thumb, the standard threshold for the significance level, that is pBinomial < 0.05, should be corrected for such repeated significance testing, using either the Bonferroni or Holm’s correction methods13 (Gries, 2009, pp. 242–243). The correction is meant to restrict the significance threshold for repeated tests since there can be more chances for “a seemingly significant result has come about by accident” when more significance tests are performed (Stefanowitsch, 2011, p. 275, footnote 5). Consequently, only certain items, whose original pBinomial-values are below the corrected significance threshold, if any, will be strictly considered significant. However, most Collostructional Analysis studies are relaxed regarding such correction. The main reason is that it is the AssocStr-based ranking of the collexemes (or, in our case, the metaphors) that is the most relevant for the Collostructional Analysis, rather than the strict corrected significance level (Stefanowitsch, 2005, p. 178; Stefanowitsch & Gries, 2005, p. 36, endnote 3, 2009, p. 944). Another reason is the tradition in corpus linguistics that considers each significance test as an independence test (Stefanowitsch & Gries, 2009, p. 944). Similar practice is also adopted in the Semantic Profile study by Janda & Lyashevskaya (2013), in which there is no mention of a correction method used for the pFisherYatesExact-values in the paper.

In this chapter, following Stefanowitsch (2011, p. 282), I report the distinctive and repelled metaphors for each synonym that are both significant at the uncorrected significance level, based on their AssocStr values, and at the corrected one, using the Holm method (Gries, 2009, p. 249). The reason for this report structure is that, as Stefanowitsch (2005, p. 178) has shown, collexemes/items that are identified as only marginally, or even not, significant, given a certain significance threshold, may also reveal systematic differences between the contrasted construction. That is amongst the reasons for the primary importance of the ranking in Collostructional Analysis. In Table @ref(tab:example-data-print) above, the column “p.holm” shows the corrected pBinomial-values with the Holm method. The “dec” column indicates the significance threshold of the corrected pHolm-values: *** = pHolm < 0.001; ** = pHolm < 0.01; * = pHolm < 0.05; ms = marginally significant at pHolm > 0.05; and ns = not significant at pHolm > 1. For the AssocStr limit, I present the metaphors with the AssocStr > 2 (for attraction) and AssocStr < -2 (for repulsion).

4.2 Distinctive metaphors for kebahagiaan ‘happiness’ and bahagia ‘happiness’

## submappings for DESIRED GOAL for KEBAHAGIAAN----
# get the submapping of the DESIRED GOAL metaphor for KEBAHAGIAAN
kebahagiaan_submapping_destination <- happyr::get_submappings("desired", "kebahagiaan", df = happyr::phd_data_metaphor)
# determine which submapping highlights the 'attainment' aspect
kebahagiaan_aspect_attainment <- kebahagiaan_submapping_destination %>% filter(str_detect(submappings, "reaching|grasping|finding"))
# determine which submapping highlights the 'pursuing/motion process' aspects
kebahagiaan_aspect_pursuing <- kebahagiaan_submapping_destination %>% filter(str_detect(submappings, "pursuing|aiming"))
# determine which submapping highlights the 'aids for motion' aspect
kebahagiaan_aspect_aids <- kebahagiaan_submapping_destination %>% filter(str_detect(submappings, "aids"))
# determine which submapping highlights the 'goal-end of motion' aspect
kebahagiaan_aspect_goal <- kebahagiaan_submapping_destination %>% filter(str_detect(submappings, "end of a path"))
# get the total proportion of 'attainment' aspect from the total tokens of the DESIRED GOAL metaphors
kebahagiaan_propasp_attaintment <- sum(kebahagiaan_aspect_attainment$perc)
# get the total proportion of 'pursuing/motion process' aspects from the total tokens of the DESIRED GOAL metaphors
kebahagiaan_propasp_pursuing <- sum(kebahagiaan_aspect_pursuing$perc)
# get the total proportion of 'aids' aspect from the total tokens of the DESIRED GOAL metaphors
kebahagiaan_propasp_aids <- sum(kebahagiaan_aspect_aids$perc)
# get the total proportion of 'goal end of a path' aspect from the total tokens of the DESIRED GOAL metaphors
kebahagiaan_propasp_goal <- sum(kebahagiaan_aspect_goal$perc)
## CONTOH UNTUK DESIRED GOAL
#(@reaching_kbhgn) kenapa orang ingin menikah dan **mencapai** *kebahagiaan* harus dihalangi (ind_mixed2012_1M:316902)
#(@grasping_kbhgn) *kebahagiaan* yang telah kita **rengkuh** dapat terlepas dan berganti dengan penderitaan hidup (ind_mixed2012_1M:150246)
#(@finding_kbhgn) di sanalah kita **menemukan** *kebahagiaan* dan motivasi yang kuat dalam bekerja (ind_news2011_300K:162690)
## submappings for POSSESSABLE OBJECT for KEBAHAGIAAN----
# get submapping of POSSESSABLE OBJECT
kbhg_submet_possess <- happyr::get_submappings("possessable", "bahagiaan", df = happyr::phd_data_metaphor)  %>% 
  mutate(aspect = if_else(str_detect(submappings, "(giving|dispersing|offering|caused motion)"), "cause", "others"), 
         aspect = if_else(str_detect(submappings, "gaining"), "gaining", aspect), 
         aspect = if_else(str_detect(submappings, "possessing"), "possessing", aspect), 
         aspect = if_else(str_detect(submappings, "(losing|seized)"), "ceasing/losing", aspect))
# get submapping of 'cause' aspect
kbhg_asp_cause <- kbhg_submet_possess %>% filter(str_detect(submappings, "giving|caused motion|dispersing|offering"))
# get submapping of 'attainment' aspect
kbhg_asp_gain <- kbhg_submet_possess %>% filter(str_detect(submappings, "gaining"))
# get submapping of 'experience' aspect
kbhg_asp_possess <- kbhg_submet_possess %>% filter(str_detect(submappings, "possessing"))
# get submapping of 'losing' aspect
kbhg_asp_losing <- kbhg_submet_possess %>% filter(str_detect(submappings, "losing|seized"))
## submappings for MOVING OBJECT for KEBAHAGIAAN----
# get submapping of MOVING OBJECT
kbhg_submet_movingobject <- happyr::get_submappings("moving object to a goal", "bahagiaan$", df = happyr::phd_data_metaphor)
mdca_res %>%
  happyr::mdca_attr(cxn_type = "kebahagiaan", min_assocstr = 2) %>% 
  mutate(exp = round(exp, 3L),
         metaphors = happyr::scaps(metaphors)) %>% 
  select(-synonyms) %>%
  as.data.frame() %>% 
  knitr::kable(caption = "Distinctive metaphors for *kebahagiaan* 'happiness'", row.names = TRUE)
metaphors n exp assocstr p_binomial p_holm dec
1 happiness is a desired goal 125 55.169 20.208 6.190e-21 3.838e-18 ***
2 intensity of happiness is object's dimension 23 10.733 3.867 1.357e-04 8.032e-02 ms
3 happiness is a possessable object 181 141.029 3.767 1.711e-04 1.011e-01 ns
4 happiness is a moving object to a goal 19 9.979 2.577 2.650e-03 1.000e+00 ns

From Table @ref(tab:distinctive-for-kebahagiaan), the metaphor that is most distinctive for kebahagiaan ‘happiness’ (Nmetaphorical = 68514 tokens), namely happiness is a desired goal/destination metaphor, suggests the aspirative nature of kebahagiaan ‘happiness’.

From the total tokens of the desired goal/destination metaphor occuring with kebahagiaan, most of the metaphorical lexical units (LUs) focus of on the ‘attainment’ rather than on the other aspects, such as the ‘pursuing’. The prominence of ‘attainment’ is reflected in both its token (58.4% of the metaphor’s 125 tokens) and type frequencies (10 different LU types).

In my Indonesian sample, kebahagiaan proportionally more frequently occurs in metaphorical expressions denoting the ‘transferring’ of the possessable object (61.88%), as in memberikan (X) kebahagiaan ‘to give (X) happiness’ (based on the giving frame), membawa kebahagiaan ‘to bring happiness’ (caused motion frame), and berbagi kebahagiaan ‘to share happiness’ (dispersal frame), among the most frequent metaphorical patterns.

In contrast to kebahagiaan, the three most distinctive metaphors at the corrected significance level for its root, namely bahagia ‘happy; happiness’, broadly highlights the experience or feeling aspect of bahagia (Nmetaphorical = 357) (cf. Table @ref(tab:distinctive-for-bahagia)).

mdca_res %>%
  happyr::mdca_attr(cxn_type = "^bahagia$", min_assocstr = 2) %>% 
  mutate(exp = round(exp, 3L),
         metaphors = happyr::scaps(metaphors)) %>% 
  select(-synonyms) %>%
  as.data.frame() %>% 
  knitr::kable(caption = "Distinctive metaphors for *bahagia* 'happy; happiness'", row.names = TRUE)
metaphors n exp assocstr p_binomial p_holm dec
1 happiness is (un)mixed substance 19 5.495 6.092 8.098e-07 4.891e-04 ***
2 happiness is being covered 15 4.121 5.254 5.576e-06 3.351e-03 **
3 happiness is a penetrating entity 5 0.589 4.300 5.013e-05 2.993e-02 *
4 happiness is a life cycle 6 0.981 3.879 1.321e-04 7.833e-02 ms

Table @ref(tab:repelled-by-kebahagiaan) shows the metaphors that are strongly repelled by kebahagiaan ‘happiness’.

mdca_res %>%
  happyr::mdca_repel(cxn_type = "kebahagiaan", min_assocstr = -2) %>% 
  mutate(exp = round(exp, 3L),
         metaphors = happyr::scaps(metaphors)) %>% 
  select(-synonyms) %>%
  knitr::kable(caption = "Repelled metaphors for *kebahagiaan* 'happiness'", row.names = TRUE)
metaphors n exp assocstr p_binomial p_holm dec
1 happiness is an (un)veiled object 14 39.729 -6.440 3.629e-07 2.203e-04 ***
2 happiness is a contained entity 34 67.408 -6.099 7.959e-07 4.815e-04 ***
3 happiness is a submerged entity 5 18.641 -4.183 6.566e-05 3.913e-02 *
4 happiness is (un)mixed substance 3 10.544 -2.427 3.739e-03 1.000e+00 ns
5 happiness is a restrained/tied entity 0 4.896 -2.356 4.410e-03 1.000e+00 ns
6 happiness is a liquid in a container 17 29.373 -2.286 5.171e-03 1.000e+00 ns
7 happiness is a location 20 31.821 -2.001 9.974e-03 1.000e+00 ns

Table @ref(tab:repelled-by-bahagia) shows the metaphors that are strongly repelled by bahagia ‘happiness’.

mdca_res %>%
  happyr::mdca_repel(cxn_type = "^bahagia$", min_assocstr = -2) %>% 
  mutate(exp = round(exp, 3L),
         metaphors = happyr::scaps(metaphors)) %>% 
  select(-synonyms) %>%
  knitr::kable(caption = "Repelled metaphors for *bahagia* 'happy; happiness'", row.names = TRUE)
metaphors n exp assocstr p_binomial p_holm dec
1 happiness is a possessable object 50 73.500 -2.813 1.537e-03 8.825e-01 ns
2 happiness is a physical object 0 4.416 -2.019 9.582e-03 1.000e+00 ns

Next, the results of MDCA for the (window-based) distinctive lexical co-occurrence, or collocates, of kebahagiaan15 reveal further semantic nuances. They indicate what concepts (e.g. other emotions, attitudes, descriptions, or evaluations) are strongly associated with kebahagiaan in the corpus. Theoretically, the concepts evoked by the distinctive collocates can be an operationalisation for Kövecses’ (2015, p. 158) idea regarding related concepts for certain emotions (cf. Oster, 2010, for similar uses of collocation data to reveal conceptual proximity and semantic prosody of an emotion.).

# present the result table for collocational analysis for *kebahagiaan*
happyr::mdca_attr(mdca_colloc, cxn_type = '^kebahagiaan') %>% 
  top_n(20, assocstr) %>% 
  left_join(happyr::dist_colloc_gloss, by = "collocates") %>% # left-join the gloss for the distinctive collocates
  select(-synonyms) %>%
  select(collocates, gloss, everything()) %>%
  mutate(exp = round(exp, 3), 
         collocates = paste("*", collocates, "*", sep = "")) %>%
  knitr::kable(caption="The 20 most distinctive, 4-window span collocates for *kebahagiaan* 'happiness' in the whole Indonesian Leipzig Corpora collection.", row.names = TRUE)
collocates gloss n exp assocstr p_binomial p_holm dec
1 kesejahteraan welfare; well-being 82 32.701 29.646 2.258e-30 1.650e-25 ***
2 sejati true; genuine 89 37.703 26.595 2.538e-27 1.855e-22 ***
3 mencapai to reach 87 42.704 16.944 1.136e-17 8.304e-13 ***
4 akhirat hereafter; afterlife 66 29.624 16.829 1.482e-17 1.083e-12 ***
5 kesuksesan success 42 18.467 11.562 2.745e-12 2.005e-07 ***
6 kedamaian peace 56 27.315 11.358 4.389e-12 3.207e-07 ***
7 menemukan to find; to locate 68 35.394 11.260 5.496e-12 4.016e-07 ***
8 manusia human 87 50.399 10.034 9.257e-11 6.762e-06 ***
9 hidup life 172 116.956 9.889 1.290e-10 9.425e-06 ***
10 abadi eternal 49 24.238 9.626 2.365e-10 1.728e-05 ***
11 tangga stair 37 16.928 9.191 6.447e-10 4.710e-05 ***
12 menuju to head to 45 22.314 8.829 1.483e-09 1.084e-04 ***
13 hakiki true; real; intrinsic 26 10.772 8.610 2.452e-09 1.791e-04 ***
14 dunia the world 132 88.486 8.302 4.992e-09 3.646e-04 ***
15 keselamatan safety 32 14.619 8.049 8.939e-09 6.529e-04 ***
16 kesehatan health 35 16.543 7.982 1.041e-08 7.604e-04 ***
17 meraih to catch-hold of 45 23.853 7.274 5.322e-08 3.887e-03 **
18 umat followers of a religion 26 11.542 7.151 7.063e-08 5.158e-03 **
19 orang people 120 82.331 6.855 1.396e-07 1.019e-02 *
20 merasakan to feel 92 60.017 6.752 1.769e-07 1.292e-02 *

4.3 Distinctive metaphors for kesenangan ‘pleasure; happiness’ and senang ‘happy; happiness; to feel well’

# submapping for POSSESSABLE OBJECT for *kesenangan*----
ksng_submet_possess <- happyr::get_submappings(metaphor = "possessable", word = "kesenangan", df = happyr::phd_data_metaphor) %>% 
  mutate(aspect = if_else(str_detect(submappings, "(giving|dispersing|offering|caused motion)"), "cause", "others"), 
         aspect = if_else(str_detect(submappings, "gaining"), "gaining", aspect), 
         aspect = if_else(str_detect(submappings, "possessing"), "possessing", aspect), 
         aspect = if_else(str_detect(submappings, "(losing|seized)"), "ceasing/losing", aspect))
# submapping for DESIRED OBJECT for *kesenangan*----
pursuing_perc <- happyr::get_submappings(metaphor = "desired goal", word = "kesenangan", df = happyr::phd_data_metaphor) %>% 
  filter(str_detect(submappings, "pursuing|aiming")) %>% 
  tally(perc) %>% 
  unlist()
# total tokens of (UN)MIXED SUBSTANCE overall-----
mixed_substance_tokens <- dim(filter(happyr::phd_data_metaphor, str_detect(metaphors, "mixed")))[1]
## tokens indicating 'pure' substance
mixed_substance_pure_tokens <- dim(filter(happyr::phd_data_metaphor, str_detect(metaphors, "mixed"), str_detect(lu, "murni")))[1] 
## tokens indicating 'mixed' substance
mixed_substance_mixed_tokens <- mixed_substance_tokens - mixed_substance_pure_tokens
mdca_res %>%
  happyr::mdca_attr(cxn_type = "kesenangan", min_assocstr = 2) %>% 
  mutate(exp = round(exp, 3L),
         metaphors = happyr::scaps(metaphors)) %>% 
  select(-synonyms) %>%
  knitr::kable(caption = "Distinctive metaphors for *kesenangan* 'pleasure; happiness'", row.names = TRUE)
metaphors n exp assocstr p_binomial p_holm dec
1 happiness is a desired goal 110 51.625 15.265 5.430e-16 3.351e-13 ***
2 happiness is a deceiver 17 3.524 9.998 1.004e-10 6.166e-08 ***
3 happiness is food 44 19.029 7.815 1.532e-08 9.345e-06 ***
4 happiness is a subjugator 13 3.172 6.256 5.543e-07 3.359e-04 ***
5 happiness is a possessable object 183 131.971 5.776 1.673e-06 1.009e-03 **
6 happiness is a foundation (of an action) 8 1.938 4.036 9.206e-05 5.469e-02 ms
7 happiness is an adversary 12 4.229 3.534 2.923e-04 1.710e-01 ns
8 happiness is impediment to motion 5 1.057 3.061 8.693e-04 5.033e-01 ns
9 happiness is a resource 5 1.410 2.228 5.921e-03 1.000e+00 ns

The first point, as I have mentioned, is that happiness is a desired goal/destination is also the most distinctive metaphor for kesenangan ‘pleasure’ as it is for kebahagiaan ‘happiness’, though the metaphor is most strongly associated with the latter according to its AssocStr values (15.265 for kesenangan vs. 20.208 for kebahagiaan). Despite this similar attraction, a finer grained difference emerges between the two words in relation to the submappings of the metaphor. Kesenangan most frequently occurs with metaphorical patterns denoting the ‘pursuing’ aspect (64.55% of all the tokens) rather than the ‘attainment’, which is more frequent for kebahagiaan.

four out of five tokens for the occurrence of this metaphor with kesenangan evoke the restraints frame. In this frame, kesenangan maps onto the Restraining_entity role (e.g. dikendalikan oleh kesenangan ‘to be reined back by pleasure’, kesenangan mengendalikan/mengikat X ‘pleasure reins back/binds X’, memikat X pada kesenangan ‘to decoy/ensnare X at pleasure’). In this case, the Experiencer comes under restraining control of kesenangan that makes him difficult to take other actions.

For kesenangan, 44.26% of the usage tokens evoke the ‘receiving’ of the Possessable_object (i.e., the ‘onset’ of pleasure), which is based on the gain possession frame.

mdca_res %>%
  happyr::mdca_attr(cxn_type = "^senang$", min_assocstr = 2) %>% 
  mutate(exp = round(exp, 3L),
         metaphors = happyr::scaps(metaphors)) %>% 
  select(-synonyms) %>%
  knitr::kable(caption = "Distinctive metaphors for *senang* 'happy; happiness; to feel well'", row.names = TRUE)
metaphors n exp assocstr p_binomial p_holm dec
1 happiness is a submerged entity 24 5.198 9.612 2.445e-10 1.499e-07 ***
2 happiness is a location 28 8.873 7.136 7.317e-08 4.456e-05 ***
3 happiness is (un)mixed substance 13 2.940 5.289 5.141e-06 3.095e-03 **

Table @ref(tab:repelled-by-kesenangan) shows the strongly repelled metaphors for kesenangan ‘pleasure’.

mdca_res %>%
  happyr::mdca_repel(cxn_type = "kesenangan", min_assocstr = -2) %>% 
  mutate(exp = round(exp, 3L),
         metaphors = happyr::scaps(metaphors)) %>% 
  select(-synonyms) %>%
  knitr::kable(caption = "Repelled metaphors for *kesenangan* 'pleasure; happiness'", row.names = TRUE)
metaphors n exp assocstr p_binomial p_holm dec
1 happiness is a contained entity 16 63.078 -13.354 4.429e-14 2.728e-11 ***
2 happiness is an (un)veiled object 8 37.177 -9.104 7.870e-10 4.817e-07 ***
3 happiness is a liquid in a container 6 27.487 -6.806 1.565e-07 9.514e-05 ***
4 happiness is a colour 0 9.338 -4.461 3.457e-05 2.067e-02 *
5 happiness is a located object 19 37.001 -3.477 3.335e-04 1.947e-01 ns
6 happiness is a sign 1 8.810 -3.141 7.230e-04 4.194e-01 ns
7 happiness is light 1 7.576 -2.611 2.449e-03 1.000e+00 ns
8 happiness is a drawing 1 7.224 -2.461 3.457e-03 1.000e+00 ns
9 happiness is (un)mixed substance 3 9.867 -2.164 6.854e-03 1.000e+00 ns

Table @ref(tab:repelled-by-senang) shows the strongly repelled metaphors for senang ‘happy; happiness; to feel well’.

mdca_res %>%
  happyr::mdca_repel(cxn_type = "senang$", min_assocstr = -2) %>% 
  mutate(exp = round(exp, 3L),
         metaphors = happyr::scaps(metaphors)) %>% 
  select(-synonyms) %>%
  knitr::kable(caption = "Repelled metaphors for *senang* 'happy; happiness; to feel well'", row.names = TRUE)
metaphors n exp assocstr p_binomial p_holm dec
1 happiness is a contained entity 7 18.795 -2.853 1.401e-03 8.058e-01 ns
2 happiness is a desired goal 5 15.383 -2.756 1.753e-03 1.000e+00 ns
3 happiness is a possessable object 24 39.324 -2.300 5.008e-03 1.000e+00 ns

Now I turn to discuss the distinctive collocates for kesenangan ‘pleasure’ shown in Table @ref(tab:colloc-res-kesenangan).

# present the result table for collocational analysis for *kesenangan*
happyr::mdca_attr(mdca_colloc, cxn_type = '^kesenangan') %>% 
  top_n(20, assocstr) %>% 
  left_join(happyr::dist_colloc_gloss, by = "collocates") %>% # left-join the gloss for the distinctive collocates
  select(-synonyms) %>%
  select(collocates, gloss, everything()) %>%
  mutate(exp = round(exp, 3), 
         collocates = paste("*", collocates, "*", sep = "")) %>%
  knitr::kable(caption="The 20 most distinctive, 4-window span collocates for *kesenangan* 'pleasure; happiness' in the whole Indonesian Leipzig Corpora collection.", row.names = TRUE)
collocates gloss n exp assocstr p_binomial p_holm dec
1 duniawi worldly; earthly 52 10.298 28.818 1.520e-29 1.111e-24 ***
2 pribadi personal 30 5.994 16.702 1.985e-17 1.450e-12 ***
3 mencari to search; to look for 55 17.522 15.757 1.748e-16 1.277e-11 ***
4 kenikmatan pleasure; enjoyment 37 11.835 10.789 1.624e-11 1.187e-06 ***
5 hobi hobby 14 2.306 10.278 5.277e-11 3.855e-06 ***
6 nafsu lust 19 3.996 10.114 7.689e-11 5.617e-06 ***
7 semata simply; merely 14 2.613 8.756 1.756e-09 1.282e-04 ***
8 keuntungan profit 12 2.152 7.934 1.165e-08 8.510e-04 ***
9 kepentingan interest; concern 13 2.613 7.464 3.438e-08 2.511e-03 **
10 seksual sexual 10 1.691 7.157 6.964e-08 5.085e-03 **
11 menikmati to taste; to relish 42 18.291 7.136 7.312e-08 5.339e-03 **
12 menunda to delay; to postpone 8 1.230 6.507 3.115e-07 2.274e-02 *
13 kebutuhan needs 10 1.998 5.873 1.341e-06 9.787e-02 ms
14 mengejar to chase; to run after 17 5.072 5.844 1.431e-06 1.045e-01 ns
15 prinsip principle 8 1.383 5.616 2.421e-06 1.767e-01 ns
16 mendapat to get; to receive 22 7.993 5.521 3.016e-06 2.201e-01 ns
17 berdasarkan to be founded/based on 10 2.152 5.394 4.040e-06 2.948e-01 ns
18 hawa air 9 1.844 5.171 6.744e-06 4.921e-01 ns
19 waktu time 18 6.302 4.896 1.270e-05 9.266e-01 ns
20 dosa sin 6 0.922 4.880 1.319e-05 9.619e-01 ns

Some of the distinctive collocates of kesenangan provide further support for arguing the negative contour assigned to kesenangan, as inferred from the distinctive metaphors. To begin with the most distinctive collocate, namely duniawi ‘wordly; earthly’, everything related to it is conceived as mundane and tends to be dispreferred over the divinity, incorporealism, or eternity, which is prescribed by certain religious view. Similar religious-based outlook then gives negavite association to the other ‘mundane’-related collocates, such as nafsu16 ‘lust’, seksual ‘sexual’, kebutuhan ‘needs’, and dosa ‘sin’. This is different from the positive nuances of kebahagiaan as conveyed by its distinctive collocates (cf. Table @ref(tab:colloc-res-kebahagiaan)). Another top collocate for kesenangan is pribadi ‘personal; private’, indicating the self-centred of kesenangan compared to kebahagiaan, which is more about wider audience (e.g. orang ‘person’, manusia ‘human’). This ‘personal/general-audience’ feature will also be shown to be one of the semantic benchmarks distinguishing kesenangan ‘pleasure’ with the remaining happiness concepts.

4.4 Distinctive metaphors for kegembiraan ‘joy; cheerfulness’ and gembira ‘excite(d/ment); enthusias(tic/m)’

# submapping for LIQUID IN A CONTAINER metaphor
kgmb_submet_liquidincontainer <- happyr::get_submappings(metaphor = "liquid in a container$", word = "kegembiraan", df = happyr::phd_data_metaphor)
kgmb_prop_with_liquidincontainer <- mdca_res %>% 
  filter(str_detect(metaphors, "liquid in a container$")) %>% 
  select(1:3) %>% 
  # get the proportion of the LIQUID IN A CONTAINER metaphor across the synonyms
  mutate(perc = round(n/sum(n) * 100, 2)) %>%
  arrange(desc(perc))
# submapping for (UN)VEILED OBJECT metaphor
kgmb_unveiled_submet <- happyr::get_submappings(metaphor = "veiled", word = "(kegembiraan|^gembira)", df = happyr::phd_data_metaphor)
kgmb_unveiled_submet_max <- kgmb_unveiled_submet %>% 
  group_by(synonyms) %>% 
  filter(perc == max(perc)) %>%
  ungroup()
negated_sentences_for_hiding <- (9/10) * 100

Table @ref(tab:distinctive-for-kegembiraan) shows the distinctive metaphors for kegembiraan ‘joy; cheerfulness’.

mdca_res %>%
  happyr::mdca_attr(cxn_type = "kegembiraan", min_assocstr = 2) %>% 
  mutate(exp = round(exp, 3L),
         metaphors = happyr::scaps(metaphors)) %>% 
  select(-synonyms) %>%
  knitr::kable(caption = "Distinctive metaphors for *kegembiraan* 'joy; cheerfulness'", row.names = TRUE)
metaphors n exp assocstr p_binomial p_holm dec
1 happiness is a liquid in a container 67 28.773 11.824 1.501e-12 9.231e-10 ***
2 happiness is a song 6 1.291 3.634 2.320e-04 1.367e-01 ns
3 happiness is an (un)veiled object 60 38.917 3.583 2.611e-04 1.530e-01 ns
4 happiness is a forceful body of water 13 5.349 3.005 9.890e-04 5.717e-01 ns

Two submappings are dominant. First, 56.72% of the tokens consists of expressions evoking the release liquid frame, which is used to convey the expression of uncontrolled internal feeling, hence the submapping expression of happiness is released liquid. This submapping for kegembiraan is also the most productive in comparison to the others since it is expressed by eight different lexical unit (LU) types (66.67% of all types for the metaphor occurring with kegembiraan).

The second dominant submapping is intensified happiness is heated liquid (37.31%), which is based on the heated liquid frame. The most frequent metaphorical pattern is meluapkan kegembiraan ‘to boil over joy; lit. to cause joy to boil over’. Unlike the release liquid frame, the heated fluid-based submapping is only evoked by two distinct LUs: meluapkan ‘to cause to boil over’ (a causative transitive verb) and meluap(-luap) ‘to (keep) boil(ing) over’ (an intransitive verb).

The high frequency of these submappings, and more generally the distinctive association of liquid in a container with kegembiraan, informs the discussion in Chapter 5 that the prominence of the released liquid and heated liquid submappings for the whole happiness domain is contributed by the highest proportion of the metaphor to occur with kegembiraan (42.95%) rather than with the remaining nine synonyms.

Table @ref(tab:distinctive-for-gembira) presents the strongly distinctive metaphors for gembira ‘excite(d/ment); enthusias(tic/m)’, though non of them are significant at the corrected level.

mdca_res %>%
  happyr::mdca_attr(cxn_type = "^gembira$", min_assocstr = 2) %>% 
  mutate(exp = round(exp, 3L),
         metaphors = happyr::scaps(metaphors)) %>% 
  select(-synonyms) %>%
  knitr::kable(caption = "Distinctive metaphors for *gembira* 'excite(d/ment); enthusias(tic/m)'", row.names = TRUE)
metaphors n exp assocstr p_binomial p_holm dec
1 happiness is (un)mixed substance 7 1.216 3.682 2.078e-04 1.226e-01 ns
2 happiness is an (un)veiled object 14 4.582 3.610 2.453e-04 1.442e-01 ns
3 happiness is a disease 3 0.282 2.604 2.487e-03 1.000e+00 ns

Out of the three postulated submappings for happiness is an (un)veiled object, the dominant submapping for the nominalised (61.67% of the metaphor tokens) and root-nominal forms (42.86%) is the same, namely existence of happiness is visibility of an object (e.g. raut gembira tampak dari raut wajah Sri ‘whittle of excitement be visible from Sri’s face’). The inability to held back or conceal the intense feeling is further evidenced by the expressions evoking the least frequent submapping for the two words, namely regulating happiness is hiding an object, which is based on the hiding frame (e.g. menyembunyikan rasa gembira ‘to hide the feeling of excitement’). From the total tokens of the submapping with the two words, all evoked by the verb menyembunyikan ‘to hide’, 90% of the use of the verbal LUs are negated (e.g. tidak dapat menyembunyikan rasa gembira ‘cannot hide X’s feeling of excitement’).

Table @ref(tab:repelled-by-kegembiraan) shows the strongly repelled metaphors for kegembiraan ‘joy; cheerfulness’.

mdca_res %>%
  happyr::mdca_repel(cxn_type = "kegembiraan", min_assocstr = -2) %>% 
  mutate(exp = round(exp, 3L),
         metaphors = happyr::scaps(metaphors)) %>% 
  select(-synonyms) %>%
  knitr::kable(caption = "Repelled metaphors for *kegembiraan* 'joy'", row.names = TRUE)
metaphors n exp assocstr p_binomial p_holm dec
1 happiness is a desired goal 6 54.042 -17.855 1.398e-18 8.652e-16 ***

Table @ref(tab:repelled-by-gembira) shows the strongly repelled metaphors for gembira ‘excite(d/ment); enthusias(tic/m)’.

mdca_res %>%
  happyr::mdca_repel(cxn_type = "gembira$", min_assocstr = -2) %>% 
  mutate(exp = round(exp, 3L),
         metaphors = happyr::scaps(metaphors)) %>% 
  select(-synonyms) %>%
  knitr::kable(caption = "Repelled metaphors for *gembira* 'excite(d/ment); enthusias(tic/m)'", row.names = TRUE)
metaphors n exp assocstr p_binomial p_holm dec
1 happiness is a possessable object 5 16.265 -2.979 1.048e-03 6.049e-01 ns
2 happiness is a desired goal 0 6.363 -2.794 1.608e-03 9.215e-01 ns
# present the result table for collocational analysis for *kegembiraan*
happyr::mdca_attr(mdca_colloc, cxn_type = '^kegembiraan') %>% 
  top_n(20, assocstr) %>% 
  left_join(happyr::dist_colloc_gloss, by = "collocates") %>% # left-join the gloss for the distinctive collocates
  select(-synonyms) %>%
  select(collocates, gloss, everything()) %>%
  mutate(exp = round(exp, 3), 
         collocates = paste("*", collocates, "*", sep = "")) %>%
  knitr::kable(caption="The 20 most distinctive, 4-window span collocates for *kegembiraan* 'joy; cheerfulness' in the whole Indonesian Leipzig Corpora collection.", row.names = TRUE)
collocates gloss n exp assocstr p_binomial p_holm dec
1 luapan an overflow 24 4.756 13.603 2.494e-14 1.823e-09 ***
2 meluapkan to boil sth. over 21 3.835 13.269 5.377e-14 3.929e-09 ***
3 menyatakan to state; to express 17 4.142 7.592 2.559e-08 1.869e-03 **
4 pendukung supporter 15 3.682 6.701 1.993e-07 1.455e-02 *
5 menyambut to receive; to welcome 21 6.904 6.162 6.883e-07 5.025e-02 ms
6 larut be washed-and-drawn away 14 3.682 5.774 1.683e-06 1.229e-01 ns
7 kesedihan sadness 19 6.597 5.197 6.351e-06 4.634e-01 ns
8 terlihat be visible; can be seen 22 8.591 4.907 1.238e-05 9.030e-01 ns
9 menyaksikan to witness 10 2.455 4.628 2.357e-05 1.000e+00 ns
10 masyarakat society 25 11.046 4.402 3.963e-05 1.000e+00 ns
11 kubu camp; party 7 1.381 4.268 5.400e-05 1.000e+00 ns
12 warga residents 16 5.830 4.158 6.955e-05 1.000e+00 ns
13 gol goal 5 0.767 4.071 8.499e-05 1.000e+00 ns
14 tim team 12 3.835 3.910 1.231e-04 1.000e+00 ns
15 dirasakan to be felt 22 9.819 3.875 1.333e-04 1.000e+00 ns
16 paskah Easter 6 1.227 3.560 2.755e-04 1.000e+00 ns
17 pemain player 10 3.068 3.522 3.003e-04 1.000e+00 ns
18 laga war; battle 5 0.921 3.352 4.448e-04 1.000e+00 ns
19 belanda The Netherlands 4 0.614 3.257 5.540e-04 1.000e+00 ns
20 dihati in the liver 4 0.614 3.257 5.540e-04 1.000e+00 ns
21 gawang net/goal (of soccer/footbal) 4 0.614 3.257 5.540e-04 1.000e+00 ns

4.5 Distinctive metaphors for keceriaan ‘cheerfulness’

# submapping of the CONTAINED ENTITY metaphor
kcra_submet_contained <- happyr::get_submappings("contained entity", "keceriaan", df = happyr::phd_data_metaphor)
kcra_submet_contained_lu <- happyr::phd_data_metaphor %>%
  filter(synonyms == "keceriaan",
         str_detect(submappings, "fullness of entity")) %>%
  count(lu, sort = TRUE) %>%
  mutate(perc = round((n/sum(n)) * 100, 2))
# submapping of the COLOUR metaphor
kcra_submet_colour <- happyr::get_submappings("colour$", "keceriaan", df = happyr::phd_data_metaphor)
# submapping of the QUANTITY metaphor
kcra_submet_quantity <- happyr::get_submappings("\\squantity", "keceriaan", df = happyr::phd_data_metaphor) %>% 
  mutate(aspect = if_else(str_detect(submappings, "(adding|more)"), "more", "less"))

Table @ref(tab:distinctive-for-keceriaan) shows the distinctive metaphors for keceriaan ‘cheerfulness; lit. purity’ (Nmetaphorical = 746). The root-nominal ceria ‘cheerful; lit. pure, clean’ (Nmetaphorical = 39) is absent since the AssocStr values of its distinctive metaphors do not reach 2.

mdca_res %>%
  happyr::mdca_attr(cxn_type = "keceriaan", min_assocstr = 2) %>% 
  mutate(exp = round(exp, 3L),
         metaphors = happyr::scaps(metaphors)) %>% 
  select(-synonyms) %>%
  knitr::kable(caption = "Distinctive metaphors for *keceriaan* 'cheerfulness'", row.names = TRUE)
metaphors n exp assocstr p_binomial p_holm dec
1 happiness is a contained entity 122 73.411 8.785 1.640e-09 1.002e-06 ***
2 happiness is an embellishment 9 2.461 4.116 7.659e-05 4.557e-02 *
3 happiness is a colour 22 10.868 3.385 4.117e-04 2.400e-01 ns
4 happiness is an (un)veiled object 64 43.267 3.318 4.809e-04 2.799e-01 ns
5 intensity of happiness is quantity of object 40 28.093 2.005 9.879e-03 1.000e+00 ns

For the contained entity metaphor, 82.79% of the tokens consist of metaphorical patterns referring to the ‘fullness’ of the contained emotion-entity. The patterns are expressed by only three LU types, namely, penuh (dengan) keceriaan ‘to be full with/of cheerfulness’ (96 tokens), keceriaan memenuhi X ‘cheerfulness fills X up’ (4 tokens), and keceriaan menyesaki X ‘X be jam-packed with cheerfulness; cheerfulness fills X up’ (1 tokens). Only 0.82% of the metaphor’s token indicates the ‘exploding’ container, suggesting the inability to held back the feeling, hence its expression (keceriaan yang meledak ‘cheerfulness that explodes’).

Related inference for intensity is indicated by the submappings of the less strongly attracted metaphor, namely intensity of happiness is quantity of object. The predominant submapping broadly indicates more quantity of object (77.5% of the total tokens of the metaphor occurring with keceriaan). This further subsumes two events: (i) ‘adding’ the quantity of an object (62.5%), which could map onto the intensification process of keceriaan, and (ii) the state of an object in ‘large quantity’ (15%), which could map onto the ‘intense’ state of keceriaan. The second of these is expressed by six different lexical unit (LU) types compared to only one for the first (i.e., tambah(kan) keceriaan ‘to add cheerfulness’). The metaphorical patterns containing LUs indicating ‘large quantity’ include berjuta/seribu/banyak keceriaanmillions of/thousands of/many cheerfulness’, keceriaan menumpuk ‘cheerfulness piles-up’, among others. The predominant submapping of quantity metaphor coheres with the ‘fullness’ submapping of the contained entity metaphor in conveying intensity, given the fullness of a content correlates with large amount of content in relation to the capacity of the holding container.

For the colour metaphor, the metaphorical patterns most frequently liken the experience of keceriaan ‘cheerfulness’ as being coloured (59.09% of the total tokens). However, the metaphorical patterns are based on only one type of lexical unit

Similar ‘visual’ tone of keceriaan is argued to be conveyed via different image, namely the embellishment metaphor. Instead of being coloured, experience of keceriaan is conceptualised as being embellished. The most frequent metaphorical pattern (i.e., eight tokens) is keceriaan menghiasi X ‘cheerfulness embellishes X’, with the “X” slot is predominantly filled with the noun wajah ‘face’

Be that as it may, both keceriaan and kegembiraan also equally have strong attraction to the (un)veiled object metaphor (AssocStr = 3.318 for keceriaan and AssocStr = 3.583 for kegembiraan), which also focuses on the idea of ‘expressivity’ and ‘regulation’ of the feeling, though it is not significance for the corrected level.

It should also be mentioned that there are two distinctive metaphors for the nominal root ceria ‘cheerfulness’ that are also distinctive for the nominalised form keceriaan, even though the attraction does not reach the corrected level of significance for ceria (cf. Table @ref(tab:distinctive-for-ceria)). These metaphors are happiness is a colour (N = 3, AssocStr = 1.713, dec = ns) and happiness is a contained entity (N = 9, AssocStr = 1.786, dec = ns). This finding further indicates that, despite the lexical variation denoting the domain, there can be a tendency of similar usages and construal within the same general domain, as already been shown between the root and nominalised forms for gembira in §@ref(gembira).

mdca_res %>%
  happyr::mdca_attr(cxn_type = "^ceria$", min_assocstr = 1.30103) %>% 
  mutate(exp = round(exp, 3L),
         metaphors = happyr::scaps(metaphors)) %>% 
  select(-synonyms) %>%
  knitr::kable(caption = "Distinctive metaphors for *ceria* 'cheerful(ness)'", row.names = TRUE)
metaphors n exp assocstr p_binomial p_holm dec
1 happiness is a contained entity 9 3.838 1.786 1.636e-02 1.000e+00 ns
2 happiness is a colour 3 0.568 1.713 1.938e-02 1.000e+00 ns

Looking at Table @ref(tab:repelled-by-keceriaan) for the repelled metaphors, keceriaan significantly repels the desired goal metaphor, distinguishing it from the distinctive metaphorical construal of kebahagiaan ‘happiness’ and kesenangan ‘pleasure’.

mdca_res %>%
  happyr::mdca_repel(cxn_type = "keceriaan", min_assocstr = -2) %>% 
  mutate(exp = round(exp, 3L),
         metaphors = happyr::scaps(metaphors)) %>% 
  select(-synonyms) %>%
  knitr::kable(caption = "Repelled metaphors for *keceriaan* 'cheerfulness'", row.names = TRUE)
metaphors n exp assocstr p_binomial p_holm dec
1 happiness is a desired goal 10 60.082 -16.982 1.042e-17 6.440e-15 ***
2 intensity of happiness is object's dimension 3 11.688 -2.886 1.301e-03 7.496e-01 ns

Similar repulsion to the desired goal metaphor is also shown by the root nominal ceria ‘cheerful’ (cf. Table @ref(tab:repelled-by-ceria)).

mdca_res %>%
  happyr::mdca_repel(cxn_type = "^ceria$", min_assocstr = -1.30103) %>% 
  mutate(exp = round(exp, 3L),
         metaphors = happyr::scaps(metaphors)) %>% 
  select(-synonyms) %>%
  knitr::kable(caption = "Repelled metaphor(s) for *ceria* 'cheerfulness'", row.names = TRUE)
metaphors n exp assocstr p_binomial p_holm dec
1 happiness is a desired goal 0 3.141 -1.371 4.251e-02 1.000e+00 ns

The fact that keceriaan also repels object’s dimension with ‘intensity’ interpretation does not undermine its association with other metaphors highlighting similar quality. It is argued that the intensity of keceriaan is captured using different form of metaphorical patterns that evoke certain semantic frame, such as object quantity that is distinctive for keceriaan, rather than patterns evoking object’s dimension frame. This is reflected by the most frequent pattern indicating the concept of object quantity, that is menambah keceriaan ‘to add cheerfulness’ (19 tokens), compared to the only three token for object’s dimension occurring with keceriaan. Let us now consider the insight offered by the distinctive collocates of keceriaan as shown in Table @ref(tab:colloc-res-keceriaan).

# present the result table for collocational analysis for *keceriaan*
happyr::mdca_attr(mdca_colloc, cxn_type = '^keceriaan') %>% 
  top_n(20, assocstr) %>% 
  left_join(happyr::dist_colloc_gloss, by = "collocates") %>% # left-join the gloss for the distinctive collocates
  select(-synonyms) %>%
  select(collocates, gloss, everything()) %>%
  mutate(exp = round(exp, 3), 
         collocates = paste("*", collocates, "*", sep = "")) %>%
  knitr::kable(caption = paste("The 20 most distinctive, 4-window span collocates for *keceriaan* 'cheerfulness' in the combined data sets (Indonesian Leipzig Corpora, IWaC Sketch Engine, and WebCorp)^[As explained in `**Chapter 3**`, the nominalised forms for ", happyr::scaps("ceria"), " and ", happyr::scaps("riang"), " occur in a very low frequency in the whole Indonesian Leipzig Corpora compared to the forms for the other concepts. Additional data for these forms are then culled from the *IWaC* of *Sketch Engine* and ten online Indonesian newspapers via *WebCorp*.].", sep = ""), row.names = TRUE)
collocates gloss n exp assocstr p_binomial p_holm dec
1 anak-anak children; kids 91 19.123 42.698 2.003e-43 1.464e-38 ***
2 penuh be full 119 46.831 21.976 1.057e-22 7.727e-18 ***
3 mengembalikan to return; to give back 19 3.122 12.487 3.256e-13 2.379e-08 ***
4 semangat enthusiasm 25 6.374 9.732 1.852e-10 1.353e-05 ***
5 masa period; time 31 9.366 9.502 3.151e-10 2.301e-05 ***
6 wajah the face 37 13.269 8.653 2.222e-09 1.623e-04 ***
7 menambah to add 20 5.203 7.721 1.902e-08 1.389e-03 **
8 sekolah school 13 2.602 7.016 9.638e-08 7.037e-03 **
9 anak child 39 16.391 6.901 1.255e-07 9.166e-03 **
10 kesegaran freshness 7 0.911 6.200 6.304e-07 4.602e-02 *
11 lebanon Lebanon 7 0.911 6.200 6.304e-07 4.602e-02 *
12 warna colour 12 2.602 5.972 1.067e-06 7.785e-02 ms
13 tetap to remain; to keep on 17 5.203 5.412 3.872e-06 2.826e-01 ns
14 suasana situation; atmosphere 22 8.195 5.115 7.672e-06 5.598e-01 ns
15 terpancar be spurted out 22 8.326 4.989 1.026e-05 7.483e-01 ns
16 mewarnai to colour 10 2.342 4.652 2.228e-05 1.000e+00 ns
17 pertunjukan show 5 0.650 4.429 3.725e-05 1.000e+00 ns
18 korban victim 7 1.301 4.278 5.269e-05 1.000e+00 ns
19 lebaran Ramadhan 7 1.301 4.278 5.269e-05 1.000e+00 ns
20 menghiasi to embelish 7 1.301 4.278 5.269e-05 1.000e+00 ns

Among the interesting finding is the distinctiveness of anak(-anak) ‘child(ren)’ to co-occur with keceriaan. This may invoke an ‘innocent’ or ‘pure’ quality of keceriaan. The presence of metaphorical collocate mengembalikan ‘to return/give back’ may relate to korban ‘victims’, who may lose their cheerfulness. Other distinctive collocates also indicate the associated setting for keceriaan, such as sekolah ‘school’, pertunjukan ‘(a) show’, and lebaran ‘Ramadhan’. These settings foreground more of the social characteristics of keceriaan, compared to the more competitive one as for kegembiraan ‘joy’; however, the settings generally converge on the more public/wider scope of these two happiness concepts compared to kesenangan ‘pleasure’, which is more self-centred. Affective-related collocates for keceriaan include kesegaran ‘freshness’ and semangat ‘enthusiasm’, the latter of which can support the proposed argument for the liveliness, intense, and vibrancy of keceriaan ‘cheerfulness’.

4.6 Distinctive metaphors for keriangan ‘cheer(fulness)’

The distinctive metaphors for keriangan are set out in Table @ref(tab:distinctive-for-keriangan). The distinctive metaphors for the root-nominal riang ‘very happy; joyous; glad’ are filtered out given the AssocStr values are below the set threshold of 2 for the discussion. Also, both keriangan and riang have the least metaphorical tokens compared to the other synonyms within their respective morphological forms (Nkeriangan = 217 and Nriang = 12). For this reason, some of the results need to be interpreted with caution.

mdca_res %>%
  happyr::mdca_attr(cxn_type = "keriangan", min_assocstr = 2) %>% 
  mutate(exp = round(exp, 3L),
         metaphors = happyr::scaps(metaphors)) %>% 
  select(-synonyms) %>%
  knitr::kable(caption = "Distinctive metaphors for *keriangan* 'cheer(fulness)'", row.names = TRUE)
metaphors n exp assocstr p_binomial p_holm dec
1 happiness is a contained entity 43 21.354 4.913 1.223e-05 7.338e-03 **
2 happiness is fire 5 0.656 3.590 2.572e-04 1.510e-01 ns
3 happiness is a drawing 9 2.446 3.234 5.830e-04 3.387e-01 ns
4 happiness is a building 5 1.074 2.474 3.356e-03 1.000e+00 ns

The intensity of keriangan can be inferred from its significant association with the contained entity metaphor, which is also distinctive for keceriaan (cf. Table @ref(tab:distinctive-for-keceriaan)). Keriangan most frequently collocates with only one lexical unit (LU) type of the metaphor evoking ‘fullness’ of the Content in the following metaphorical pattern: penuh (dengan) keriangan ‘to be full of(/with) cheer(fullness)’ (40 tokens). This salient pattern reveals that keriangan is prominently talked about in terms of its ‘intense’ state (i.e., being full of it).

mdca_res %>%
  happyr::mdca_attr(cxn_type = "^riang$", min_assocstr = 1.30103) %>% 
  mutate(exp = round(exp, 3L),
         metaphors = happyr::scaps(metaphors)) %>% 
  select(-synonyms) %>%
  knitr::kable(caption = "Distinctive metaphors for *riang* 'very happy; joyous'", row.names = TRUE)
metaphors n exp assocstr p_binomial p_holm dec
1 happiness is a person 2 0.181 1.842 1.439e-02 1.000e+00 ns
2 happiness is a contained entity 4 1.181 1.496 3.188e-02 1.000e+00 ns
3 happiness is an accompany 1 0.046 1.345 4.520e-02 1.000e+00 ns

Table @ref(tab:repelled-by-keriangan) shows the strongly repelled metaphor by keriangan ‘cheer(fulness)’.

mdca_res %>%
  happyr::mdca_repel(cxn_type = "keriangan", min_assocstr = -2) %>% 
  mutate(exp = round(exp, 3L),
         metaphors = happyr::scaps(metaphors)) %>% 
  select(-synonyms) %>%
  knitr::kable(caption = "Repelled metaphors for *keriangan* 'cheer(fulness)'", row.names = TRUE)
metaphors n exp assocstr p_binomial p_holm dec
1 happiness is a desired goal 3 17.477 -4.729 1.867e-05 1.119e-02 *
# present the result table for collocational analysis for *keriangan*
happyr::mdca_attr(mdca_colloc, cxn_type = '^keriangan') %>% 
  top_n(20, assocstr) %>% 
  left_join(happyr::dist_colloc_gloss, by = "collocates") %>% # left-join the gloss for the distinctive collocates
  select(-synonyms) %>%
  select(collocates, gloss, everything()) %>%
  mutate(exp = round(exp, 3), 
         collocates = paste("*", collocates, "*", sep = "")) %>%
  knitr::kable(caption = paste("The 20 most distinctive, 4-window span collocates for *keriangan* 'cheerfulness' in the combined data sets (Indonesian Leipzig Corpora, IWaC Sketch Engine, and WebCorp)^[As explained in `**Chapter 3**`, the nominalised forms for ", happyr::scaps("ceria"), " and ", happyr::scaps("riang"), " occur in a very low frequency in the whole Indonesian Leipzig Corpora compared to the forms for the other concepts. Additional data for these forms are then culled from the *IWaC* of *Sketch Engine* and ten online Indonesian newspapers via *WebCorp*.].", sep = ""), row.names = TRUE)
collocates gloss n exp assocstr p_binomial p_holm dec
1 penuh be full 48 16.579 10.210 6.159e-11 4.499e-06 ***
2 kanak-kanak children; kids 7 0.599 6.230 5.894e-07 4.302e-02 *
3 politik politics 5 0.368 4.986 1.032e-05 7.528e-01 ns
4 terakhir last; final 5 0.368 4.986 1.032e-05 7.528e-01 ns
5 menggambarkan to draw; to depict 8 1.151 4.967 1.079e-05 7.871e-01 ns
6 kehebatannya the grandeur 3 0.138 4.010 9.768e-05 1.000e+00 ns
7 bocah child 4 0.368 3.567 2.711e-04 1.000e+00 ns
8 imajinasi imagination 3 0.184 3.423 3.772e-04 1.000e+00 ns
9 keseronokan delight; pleasure 3 0.184 3.423 3.772e-04 1.000e+00 ns
10 mengajar to teach 3 0.184 3.423 3.772e-04 1.000e+00 ns
11 anak-anak children; kids 17 6.770 3.331 4.665e-04 1.000e+00 ns
12 khas unique 4 0.414 3.328 4.701e-04 1.000e+00 ns
13 empat four 4 0.461 3.122 7.549e-04 1.000e+00 ns
14 kekonyolan foolishness 3 0.230 3.041 9.105e-04 1.000e+00 ns
15 ketulusan sincerity 3 0.230 3.041 9.105e-04 1.000e+00 ns
16 memancarkan to spurt out 4 0.507 2.942 1.143e-03 1.000e+00 ns
17 mendengar to hear 4 0.507 2.942 1.143e-03 1.000e+00 ns
18 hilang to vanish; be gone 6 1.243 2.913 1.222e-03 1.000e+00 ns
19 menunjukkan to show 7 1.704 2.875 1.334e-03 1.000e+00 ns
20 berbalut be bandaged 3 0.276 2.755 1.758e-03 1.000e+00 ns
21 kejayaan victory 3 0.276 2.755 1.758e-03 1.000e+00 ns

R session info

devtools::session_info()
─ Session info ────────────────────────────────────────────────────────────────────────────────

─ Packages ────────────────────────────────────────────────────────────────────────────────────
 package     * version date       lib source        
 assertthat    0.2.0   2017-04-11 [1] CRAN (R 3.4.0)
 backports     1.1.2   2017-12-13 [1] CRAN (R 3.5.0)
 bookdown    * 0.9     2018-12-21 [1] CRAN (R 3.5.0)
 broom         0.5.1   2018-12-05 [1] CRAN (R 3.5.0)
 callr         3.1.1   2018-12-21 [1] CRAN (R 3.5.0)
 cellranger    1.1.0   2016-07-27 [1] CRAN (R 3.4.0)
 cli           1.0.1   2018-09-25 [1] CRAN (R 3.5.0)
 colorspace    1.3-2   2016-12-14 [1] CRAN (R 3.5.0)
 crayon        1.3.4   2017-09-16 [1] CRAN (R 3.4.1)
 desc          1.2.0   2018-05-01 [1] CRAN (R 3.5.0)
 devtools      2.0.1   2018-10-26 [1] CRAN (R 3.5.1)
 digest        0.6.15  2018-01-28 [1] CRAN (R 3.5.0)
 dplyr       * 0.8.0.1 2019-02-15 [1] CRAN (R 3.5.2)
 evaluate      0.11    2018-07-17 [1] CRAN (R 3.5.0)
 forcats     * 0.3.0   2018-02-19 [1] CRAN (R 3.5.0)
 fs            1.2.3   2018-06-08 [1] CRAN (R 3.5.0)
 generics      0.0.2   2018-11-29 [1] CRAN (R 3.5.0)
 ggplot2     * 3.1.0   2018-10-25 [1] CRAN (R 3.5.0)
 glue          1.3.0   2018-07-17 [1] CRAN (R 3.5.0)
 gtable        0.2.0   2016-02-26 [1] CRAN (R 3.4.0)
 happyr      * 0.1.1   2019-04-12 [1] local         
 haven         1.1.2   2018-06-27 [1] CRAN (R 3.5.0)
 highr         0.7     2018-06-09 [1] CRAN (R 3.4.4)
 hms           0.4.2   2018-03-10 [1] CRAN (R 3.4.4)
 htmltools     0.3.6   2017-04-28 [1] CRAN (R 3.5.0)
 httr          1.3.1   2017-08-20 [1] CRAN (R 3.4.1)
 irr           0.84    2012-07-16 [1] CRAN (R 3.5.0)
 jsonlite      1.5     2017-06-01 [1] CRAN (R 3.5.0)
 knitr         1.20    2018-02-20 [1] CRAN (R 3.5.0)
 labeling      0.3     2014-08-23 [1] CRAN (R 3.4.0)
 lattice       0.20-38 2018-11-04 [2] CRAN (R 3.5.3)
 lazyeval      0.2.1   2017-10-29 [1] CRAN (R 3.5.0)
 lpSolve       5.6.13  2015-09-19 [1] CRAN (R 3.5.0)
 lubridate     1.7.4   2018-04-11 [1] CRAN (R 3.5.0)
 magrittr      1.5     2014-11-22 [1] CRAN (R 3.4.0)
 memoise       1.1.0   2017-04-21 [1] CRAN (R 3.4.0)
 modelr        0.1.2   2018-05-11 [1] CRAN (R 3.5.0)
 munsell       0.5.0   2018-06-12 [1] CRAN (R 3.5.0)
 nlme          3.1-137 2018-04-07 [2] CRAN (R 3.5.3)
 pillar        1.3.1   2018-12-15 [1] CRAN (R 3.5.0)
 pkgbuild      1.0.2   2018-10-16 [1] CRAN (R 3.5.0)
 pkgconfig     2.0.2   2018-08-16 [1] CRAN (R 3.5.0)
 pkgload       1.0.2   2018-10-29 [1] CRAN (R 3.5.0)
 plyr          1.8.4   2016-06-08 [1] CRAN (R 3.5.0)
 prettyunits   1.0.2   2015-07-13 [1] CRAN (R 3.5.0)
 processx      3.2.1   2018-12-05 [1] CRAN (R 3.5.0)
 ps            1.3.0   2018-12-21 [1] CRAN (R 3.5.0)
 purrr       * 0.3.0   2019-01-27 [1] CRAN (R 3.5.2)
 R6            2.3.0   2018-10-04 [1] CRAN (R 3.5.0)
 Rcpp          1.0.0   2018-11-07 [1] CRAN (R 3.5.0)
 readr       * 1.3.1   2018-12-21 [1] CRAN (R 3.5.0)
 readxl        1.2.0   2018-12-19 [1] CRAN (R 3.5.0)
 remotes       2.0.2   2018-10-30 [1] CRAN (R 3.5.0)
 rlang         0.3.1   2019-01-08 [1] CRAN (R 3.5.2)
 rmarkdown     1.11    2018-12-08 [1] CRAN (R 3.5.0)
 rprojroot     1.3-2   2018-01-03 [1] CRAN (R 3.4.3)
 rstudioapi    0.7     2017-09-07 [1] CRAN (R 3.4.1)
 rvest         0.3.2   2016-06-17 [1] CRAN (R 3.4.0)
 scales        1.0.0   2018-08-09 [1] CRAN (R 3.5.0)
 sessioninfo   1.1.1   2018-11-05 [1] CRAN (R 3.5.0)
 stringi       1.2.4   2018-07-20 [1] CRAN (R 3.5.0)
 stringr     * 1.4.0   2019-02-10 [1] CRAN (R 3.5.2)
 testthat      2.0.1   2018-10-13 [1] CRAN (R 3.5.0)
 tibble      * 2.0.1   2019-01-12 [1] CRAN (R 3.5.2)
 tidyr       * 0.8.3   2019-03-01 [1] CRAN (R 3.5.2)
 tidyselect    0.2.5   2018-10-11 [1] CRAN (R 3.5.0)
 tidyverse   * 1.2.1   2017-11-14 [1] CRAN (R 3.5.0)
 usethis       1.4.0   2018-08-14 [1] CRAN (R 3.5.0)
 withr         2.1.2   2018-03-15 [1] CRAN (R 3.4.4)
 xfun          0.4     2018-10-23 [1] CRAN (R 3.5.0)
 xml2          1.2.0   2018-01-24 [1] CRAN (R 3.5.0)
 yaml          2.2.0   2018-07-25 [1] CRAN (R 3.5.0)

[1] /Users/Primahadi/Rlibs
[2] /Library/Frameworks/R.framework/Versions/3.5/Resources/library
rmarkdown::pandoc_version()
[1] ‘1.19.2.1’

References

Boroditsky, L., & Ramscar, M. (2002). The roles of body and mind in abstract thought. Psychological Science, 13(2), 185–189. Retrieved from http://pss.sagepub.com/content/13/2/185.short

David, O. (2017). Computational approaches to metaphor: The case of MetaNet. In B. Dancygier (Ed.), The Cambridge handbook of Cognitive Linguistics (pp. 574–589). New York, NY: Cambridge University Press.

Dodge, E. (2016). A deep semantic corpus-based approach to metaphor analysis: A case study of metaphoric conceptualizations of poverty. Constructions and Frames, 8(2), 256–294. doi:10.1075/cf.8.2.05dod

Evans, V., & Green, M. (2006). Cognitive linguistics: An introduction. Edinburgh: Edinburgh University Press.

Gilquin, G. (2010). Corpus, cognition and causative constructions. Amsterdam/Philadelphia: John Benjamins Publishing Company.

Gries, S. T. (2009). Statistics for linguistics with R: A practical introduction. Berlin: Mouton de Gruyter.

Hilpert, M. (2006a). Distinctive collexeme analysis and diachrony. Corpus Linguistics and Linguistic Theory, 2(2), 243–256.

Hilpert, M. (2006b). Keeping an eye on the data: Metonymies and their patterns. In A. Stefanowitsch & S. T. Gries (Eds.), Corpus-based approaches to metaphor and metonymy (pp. 123–151). Berlin: Mouton de Gruyter.

Hilpert, M. (2014). Construction grammar and its application to English. Edinburgh: Edinburgh University Press.

Janda, L. A., & Lyashevskaya, O. (2013). Semantic profiles of five Russian prefixes: Po-, s-, Za-, Na-, Pro-. Journal of Slavic Linguistics, 21(2), 211–258. doi:10.1353/jsl.2013.0012

Kövecses, Z. (2015). Where metaphors come from: Reconsidering context in metaphor. New York, NY: Oxford University Press.

Lakoff, G., & Johnson, M. (1999). Philosophy in the flesh: The embodied mind and its challenge to Western thought. New York: Basic Books.

Levshina, N. (2015). How to do Linguistics with R: Data exploration and statistical analysis. John Benjamins Publishing Company.

Oster, U. (2010). Using corpus methodology for semantic and pragmatic analyses: What can corpora tell us about the linguistic expression of emotions? Cognitive Linguistics, 21(4), 727–763. doi:10.1515/COGL.2010.023

Rajeg, G. P. W. (2019a). Happyr: The accompanying r package for rajeg’s (2019) phd thesis titled “metaphorical profiles and near synonyms: A corpus-based study of indonesian words for happiness”. doi:10.26180/5be404d6336da

Rajeg, G. P. W. (2019b). Metaphorical profiles and near-synonyms: A corpus-based study of indonesian words for happiness (PhD thesis). School of Languages, Literatures, Cultures; Linguistics; Monash University, Australia, Monash University, Australia. doi:/10.26180/5cac231a97fb1

Ronga, I. (2016). Taste synaesthesias: Linguistic features and neurophysiological bases. In E. Gola & F. Ervas (Eds.), Metaphor and communication (pp. 47–60). Amsterdam: John Benjamins Publishing Company. doi:10.1075/milcc.5.03ron

Shaver, P. R., Murdaya, U., & Fraley, R. C. (2001). Structure of the Indonesian emotion lexicon. Asian Journal of Social Psychology, 4(3), 201–224. doi:10.1111/1467-839X.00086

Shutova, E., Devereux, B. J., & Korhonen, A. (2013). Conceptual metaphor theory meets the data: A corpus-based human annotation study. Language Resources & Evaluation, 47(4), 1261–1284. doi:10.1007/s10579-013-9238-z

Stefanowitsch, A. (2004). HAPPINESS in English and German: A metaphorical-pattern analysis. In Michel Achard & Suzanne Kemmer (Eds.), Language, Culture, and Mind (pp. 137–149). Stanford, CA: CSLI.

Stefanowitsch, A. (2005). The function of metaphor: Developing a corpus-based perspective. International Journal of Corpus Linguistics, 10(2), 161–198. doi:10.1075/ijcl.10.2.03ste

Stefanowitsch, A. (2011). Cognitive linguistics meets the corpus. In Mario Brdar, Stefan Th. Gries, & Milena Žic Fuchs (Eds.), Cognitive Linguistics: Convergence and Expansion (pp. 257–289). Amsterdam/Philadelphia: John Benjamins Publishing Company.

Stefanowitsch, A. (2017). Corpus linguistics: A guide to the methodology. Book Manuscript, Freie Universität Berlin: Book manuscript. Retrieved from http://stefanowitsch.net/clm/clmbook-draft.pdf

Stefanowitsch, A., & Gries, S. T. (2005). Covarying collexemes. Corpus Linguistics and Linguistic Theory, 1(1), 1–43.

Stefanowitsch, A., & Gries, S. T. (2009). Corpora and grammar. In A. Lüdeling & M. Kytö (Eds.), Corpus linguistics: An international handbook (Vol. 2, pp. 933–951). Berlin: Mouton de Gruyter.


  1. The Greek symbol “\(\mu\)” stands for ‘mean’ or ‘average’ score, meanwhile “\(\sigma\)” stands for ‘standard deviation’ score.

  2. These are tokens after manual duplicates-removal.

  3. I put the ‘v’ tag for dapat(kan) ‘to get’ since the form dapat has another function as an abilitative modal auxiliary ‘to be able to; can’.

  4. See MetaNet (MN) and FrameNet’s (FN) definition of source-path-goal frame in their respective frame repository.

  5. See https://metaphor.icsi.berkeley.edu/pub/en/index.php/Frame:Self_propelled_motion_to_a_destination (Last access: 15 August 2018).

  6. Taken from https://metaphor.icsi.berkeley.edu/pub/en/index.php/Metaphor:ACTION_IS_SELF-PROPELLED_MOTION_ALONG_A_PATH (Last access: 15 August 2018).

  7. No relevant lexical units are given in the entry of self-propelled motion to a destination frame. See https://metaphor.icsi.berkeley.edu/pub/en/index.php/Frame:Self_propelled_motion_to_a_destination (Last access: 9 September 2018).

  8. The top_n() function of the dplyr package in R will include more rows from the specified ‘n’ number (i.e. ten) if there are ties among the group, i.e. the LUs, based on the variable used for ordering, i.e. their token frequency. Therefore, Table @ref(tab:lu-location) specifically lists twelve items when ten is requested.

  9. The explosion and fragmentation scenario frames are taken from the FrameNet repository; the rest are represented in the MetaNet repository.

  10. The percentage of liquid containment submapping does not correspond to the overall percentage of the fluid containment frame because the other portion of the metaphorical expressions evoking fluid containment do not profile the liquid containment per se, but also include highlighting the Fluid_level role of the frame. I consider the expressions profiling the Fluid_level role of the frame to evoke a separate submapping, viz. indicating the Fullness of the contained fluid. See the discussion on citation XXX below.

  11. The entry for food preparation frame is not represented in the MetaNet frame repository, but is included as the source frame label for a metaphorical entailment of the ideas are foods metaphor, i.e. preparing ideas to be understood is food preparation (cf. https://metaphor.icsi.berkeley.edu/pub/en/index.php/Metaphor:PREPARING_IDEAS_TO_BE_UNDERSTOOD_IS_FOOD_PREPARATION). A related frame whose entry is available in the FrameNet frame repository is cooking_creation.

  12. The alternative representation of this p-value is 0.000000000000000000006190131.

  13. These correction methods are available in R via the p.adjust() built-in function in the {stats} package. The p.adjust() function requires at least two input-arguments: (i) the numeric vector of p-values from each significance testing, and (ii) the names of the correction methods to be used, e.g. “bonferroni” or “holm”. See the following website for examples: http://rcompanion.org/rcompanion/f_01.html.

  14. This value indicates the total tokens of metaphorical patterns for a synonym in the sample.

  15. I limit the scope for the collocation data to the nominalised forms of the happiness synonyms for two reasons. First, they are more frequent than their corresponding root-nominal forms. Second, they are exclusively used as nominals with inherent reference function. Meanwhile, the typical usages of the root forms are attributive and predicative, rather than nominal/reference function.

  16. The word hawa ‘air’ in Table @ref(tab:colloc-res-kesenangan) is part of an established compound in Indonesian with the word nafsu ‘lust’, that is hawa nafsu ‘lust, lit. the air of the lust’. Thus, upon inspecting the full sentences of the nine tokens for which hawa collocates with kesenangan within the span of four words to the left and right, there is only one occasion in which hawa does not collocate with nafsu, but appears alone indicating its homonymy with hawa meaning ‘female’ (the antonym for Adam ‘male; lit. Adam’, hence another common phrase Kaum Adam dan Hawa ‘Male and Female group; lit Adam and Eve group’).

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayBmb3IgZGF0YSBhbmFseXNpcyB3aXRoIF9oYXBweXJfIFIgcGFja2FnZSBpbiBSYWplZyAoMjAxOSkiCmF1dGhvcjogIkdlZGUgUHJpbWFoYWRpIFdpamF5YSBSYWplZyIKZGF0ZTogIkNvbXBpbGVkIDE1IEp1bHksIDIwMTg7IExhc3QgVXBkYXRlIGByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJUIsICVZJylgIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIGZpZ19jYXB0aW9uOiB0cnVlCiAgICBmaWdfcmV0aW5hOiAyCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIGhpZ2hsaWdodDogInRhbmdvIgogICAgdGhlbWU6ICJkZWZhdWx0IgogIGJvb2tkb3duOjp3b3JkX2RvY3VtZW50MjoKICAgIGZpZ19jYXB0aW9uOiB0cnVlCiAgICBmaWdfd2lkdGg6IDYKICAgIGRmX3ByaW50OiBrYWJsZQpsaW5rLWNpdGF0aW9uczogdHJ1ZQpiaWJsaW9ncmFwaHk6IE15X0xpYnJhcnkuYmliCmNzbDogYXBhLW9sZC1kb2ktcHJlZml4LmNzbAotLS0KCjxzdXA+JmNvcHk7PC9zdXA+IDIwMTggW0dlZGUgUHJpbWFoYWRpIFdpamF5YSBSYWplZ10oaHR0cHM6Ly9maWdzaGFyZS5jb20vYXV0aG9ycy9HZWRlX1ByaW1haGFkaV9XaWpheWFfUmFqZWcvMTIzNDc0OSkKPGRpdiBpdGVtc2NvcGUgaXRlbXR5cGU9Imh0dHBzOi8vc2NoZW1hLm9yZy9QZXJzb24iPjxhIGl0ZW1wcm9wPSJzYW1lQXMiIGNvbnRlbnQ9Imh0dHBzOi8vb3JjaWQub3JnLzAwMDAtMDAwMi0yMDQ3LTg2MjEiIGhyZWY9Imh0dHBzOi8vb3JjaWQub3JnLzAwMDAtMDAwMi0yMDQ3LTg2MjEiIHRhcmdldD0ib3JjaWQud2lkZ2V0IiByZWw9Im5vb3BlbmVyIG5vcmVmZXJyZXIiIHN0eWxlPSJ2ZXJ0aWNhbC1hbGlnbjp0b3A7Ij48aW1nIHNyYz0iaHR0cHM6Ly9vcmNpZC5vcmcvc2l0ZXMvZGVmYXVsdC9maWxlcy9pbWFnZXMvb3JjaWRfMTZ4MTYucG5nIiBzdHlsZT0id2lkdGg6MWVtO21hcmdpbi1yaWdodDouNWVtOyIgYWx0PSJPUkNJRCBpRCBpY29uIj5vcmNpZC5vcmcvMDAwMC0wMDAyLTIwNDctODYyMTwvYT48L2Rpdj4KPGEgcmVsPSJsaWNlbnNlIiBocmVmPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9ieS1uYy1zYS80LjAvIj48aW1nIGFsdD0iQ3JlYXRpdmUgQ29tbW9ucyBMaWNlbnNlIiBzdHlsZT0iYm9yZGVyLXdpZHRoOjAiIHNyYz0iaHR0cHM6Ly9pLmNyZWF0aXZlY29tbW9ucy5vcmcvbC9ieS1uYy1zYS80LjAvODh4MzEucG5nIiAvPjwvYT4KCiMgUHJlZmFjZSB7LX0KClRoaXMgaXMgYW4gUiBNYXJrZG93biBOb3RlYm9vayBkb2N1bWVudGluZyBob3cgdGhlIGNvZGVzIGluIHRoZSBbaGFwcHlyXShodHRwczovL2dlZGVyYWplZy5naXRodWIuaW8vaGFwcHlyLykgcGFja2FnZSBbQHJhamVnX2hhcHB5cl8yMDE4XSBhcmUgdXNlZCBmb3IgdGhlIHN0YXRpc3RpY2FsIGFuYWx5c2VzIGluIFJhamVnJ3MgWy1AcmFqZWdfbWV0YXBob3JpY2FsXzIwMThdIFtQaEQgdGhlc2lzXShodHRwOi8vZG9pLm9yZy8xMC4yNjE4MC81Y2FjMjMxYTk3ZmIxKS4gVGhlIHN0dWR5IGZvY3VzZXMgb24gbWV0YXBob3JzIGZvciBgciBoYXBweXI6OnNjYXBzKCJoYXBwaW5lc3MiKWAgbmVhci1zeW5vbnltcyBpbiBJbmRvbmVzaWFuLiBUaGUgdW5kZXJseWluZyBSIE1hcmtkb3duICguUm1kKSBmaWxlIG9mIHRoZSBub3RlYm9vayBhbHNvIGluY2x1ZGVzIHRoZSBpbi1saW5lIGNvZGVzIHRvIGdlbmVyYXRlIG51bWVyaWMgcmVzdWx0cyBpbiB0aGUgY2h1bmtzIG9mIHRoZSBib2R5LXRleHQgb2YgdGhlIHJlbGV2YW50IGNoYXB0ZXJzLiBUaHVzLCBub3QgYWxsIGJvZHktdGV4dCBvZiB0aGUgdGhlc2lzIGFyZSBpbmNsdWRlZCBpbiB0aGlzIG5vdGVib29rLiBOb3RlIHRoYXQgdGhlcmUgY2FuIGJlIHNvbWUgZGlmZmVyZW5jZXMgaW4gdGhlIHdvcmRpbmdzIGFuZCBhcnJhbmdlbWVudCBiZXR3ZWVuIHRoZSBuYXJhdGl2ZSBpbiB0aGlzIG5vdGVib29rIGFuZCBpbiB0aGUgZmluYWwgdmVyc2lvbiBvZiB0aGUgdGhlc2lzLCBidXQgbm90IHdpdGggdGhlIHF1YW50aXRhdGl2ZSBhbmFseXNpcy4gCgpUaGlzIFIgbm90ZWJvb2sgaXMgbGljZW5zZWQgdW5kZXIgdGhlIENyZWF0aXZlIENvbW1vbiBMaWNlbnNlIFtDQyBCWS1OQy1TQSA0LjBdKGh0dHBzOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9ieS1uYy1zYS80LjAvKS4gVG8gZG93bmxvYWQgdGhlIHJhdyAuUm1kIGZpbGUgb2YgdGhlIG5vdGVib29rLCBnbyB0byB0aGUgdG9wIHJpZ2h0IGNvcm5lciBvZiB0aGUgcGFnZSAobmV4dCB0byB0aGUgdGl0bGUpLCBjbGljayB0aGUgYENvZGVgIGRyb3AtZG93biBidXR0b24sIGFuZCB0aGVuIGNsaWNrIGBEb3dubG9hZCBSbWRgIG9wdGlvbi4gVG8gdW5mb2xkIGFuZCBzZWUgdGhlIGNvbnRlbnQgb2YgdGhlIFIgY29kZSBjaHVua3MsIGNsaWNrIG9uIHRoZSBgQ29kZWAgYnV0dG9uLgoKIyMjIEhvdyB0byBjaXRlIHRoaXMgbm90ZWJvb2sgcmVwb3NpdG9yeSAoaW4gIkRhdGFDaXRlIiBzdHlsZSkgey19Cgo+IFJhamVnLCBHZWRlIFByaW1haGFkaSBXaWpheWEgKDIwMTkpOiBSIE5vdGVib29rIGZvciAqTWV0YXBob3JpY2FsIHByb2ZpbGVzIGFuZCBuZWFyLXN5bm9ueW1zOiBBIGNvcnB1cy1iYXNlZCBzdHVkeSBvZiBJbmRvbmVzaWFuIHdvcmRzIGZvciA8c3BhbiBzdHlsZT0iZm9udC12YXJpYW50OnNtYWxsLWNhcHM7Ij5oYXBwaW5lc3M8L3NwYW4+Ki4gZmlnc2hhcmUuIENvZGUuIGRvaTogaHR0cHM6Ly9kb2kub3JnLzEwLjI2MTgwLzVjYjY1YzA2YjFiMTcuCgojIyMgQWNrbm93bGVkZ2VtZW50IHstfQoKVGhlIHRoZXNpcyBpcyBzdXBlcnZpc2VkIGJ5IEFzc29jaWF0ZSBQcm9mZXNzb3IgW0FsaWNlIEdhYnldKGh0dHBzOi8vYml0Lmx5LzJEOTFMcDkpIChtYWluKSwgRHIuIFtIb3dhcmQgTWFubnNdKGh0dHBzOi8vYml0Lmx5LzJVZWxZUFkpIChhc3NvY2lhdGUpLCBhbmQgRHIuIFtTaW1vbiBNdXNncmF2ZV0oaHR0cHM6Ly9iaXQubHkvMloxdENBVikgKGFzc29jaWF0ZSkuIFRoZSBwYW5lbCBtZW1iZXJzIGR1cmluZyB0aGUgYXV0aG9yJ3MgY2FuZGlkYXR1cmUgbWlsZXN0b25lcyBjb25zaXN0IG9mIERyLiBbQW5uYSBNYXJnZXR0c10oaHR0cHM6Ly9yZXNlYXJjaC5tb25hc2guZWR1L2VuL3BlcnNvbnMvYW5uYS1tYXJnZXR0cyksIERyLiBbUsOpa2EgQmVuY3plc10oaHR0cHM6Ly93d3cucmVzZWFyY2hnYXRlLm5ldC9wcm9maWxlL1Jla2FfQmVuY3plcyksIGFuZCBQcm9mLiBbSm9obiBOZXdtYW5dKGh0dHBzOi8vd3d3LmpvaG5uZXdtLm9yZykuIFRoZSB0aGVzaXMgaXMgZnVsbHkgZnVuZGVkIGJ5IFtNb25hc2ggVW5pdmVyc2l0eV0oaHR0cHM6Ly93d3cubW9uYXNoLmVkdSksIEF1c3RyYWxpYSwgdGhyb3VnaCB0aGUgW0ludGVybmF0aW9uYWwgR3JhZHVhdGUgUmVzZWFyY2ggU2Nob2xhcnNoaXBzXShodHRwczovL3d3dy5tb25hc2guZWR1L2dyYWR1YXRlLXJlc2VhcmNoL2Z1dHVyZS1zdHVkZW50cy9zY2hvbGFyc2hpcHMpOiAoaSkgKk1vbmFzaCBJbnRlcm5hdGlvbmFsIFBvc3RncmFkdWF0ZSBSZXNlYXJjaCBTY2hvbGFyc2hpcHMqIChNSVBSUykgYW5kIChpaSkgKk1vbmFzaCBHcmFkdWF0ZSBTY2hvbGFyc2hpcHMqIChNR1MpLiBUaGUgYXV0aG9yIGFsc28gYmVuZWZpdHMgZnJvbSB0aGUgZ2VuZXJvdXMgcmVzZWFyY2ggZnVuZGluZyBmcm9tIHRoZSBNb25hc2ggR3JhZHVhdGUgRWR1Y2F0aW9uIGFuZCB0aGUgQXJ0cyBHcmFkdWF0ZSBSZXNlYXJjaCBvZiBNb25hc2ggVW5pdmVyc2l0eS4KCmBgYHtyIGdsb2JhbF9vcHRpb25zLCBpbmNsdWRlID0gRkFMU0UsIGV2YWwgPSBUUlVFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZmlnLndpZHRoID0gNiwgCiAgICAgICAgICAgICAgICAgICAgICBmaWcuYXNwID0gMC42MTgsIAogICAgICAgICAgICAgICAgICAgICAgZmlnLnJldGluYSA9IDIsCiAgICAgICAgICAgICAgICAgICAgICBvdXQud2lkdGggPSAiNzAlIiwKICAgICAgICAgICAgICAgICAgICAgIGZpZy5hbGlnbiA9ICJjZW50ZXIiLAogICAgICAgICAgICAgICAgICAgICAgZHBpID0gMzAwLAogICAgICAgICAgICAgICAgICAgICAgZWNobyA9IFRSVUUpCnNlY3Rpb24gPC0gIsKnIgpgYGAKCmBgYHtyIGxvYWQtcGFja2FnZSwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0V9CmxpYnJhcnkoaGFwcHlyKQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeShib29rZG93bikpCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KHRpZHl2ZXJzZSkpCgpgYGAKCiMgQ29kZXMgZm9yIENoYXB0ZXIgMyAtIEludGVycmF0ZXIgQWdyZWVtZW50CgojIyBSZXN1bHRzIGZvciAqY29uc3RydWN0aW9uYWwgcGF0dGVybnMqCmBgYHtyIGthcHBhLWN4bi1jb21wdXRhdGlvbn0KIyBrYXBwYSBjYWxjdWxhdGlvbgppcnJfY3huIDwtIGhhcHB5cjo6a2FwcGFfdGlkeShkZiA9IGhhcHB5cjo6ZGZfY3huX3BhdHRlcm4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhcl9uYW1lcyA9ICJecGF0dGVybiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdW5kID0gInByZV9kaXNjIikKYGBgCgoKVGhlIEthcHBhIHNjb3JlcyBpbiBbVGFibGUgXEByZWYodGFiOmthcHBhLWN4bildKCNrYXBwYS1jeG4pIGZvciB0aGUgY29uc3RydWN0aW9uYWwgcGF0dGVybiBhbm5vdGF0aW9uIHNob3cgaGlnaCBsZXZlbCBvZiBhZ3JlZW1lbnRzIGZvciB0aGUgZmlyc3Qgcm91bmQgKGkuZS4sIHRoZSBwcmUtZGlzY1t1c3Npb24gc3RhZ2VdKSAoJFxtdSReW1RoZSBHcmVlayBzeW1ib2wgIiRcbXUkIiBzdGFuZHMgZm9yICdtZWFuJyBvciAnYXZlcmFnZScgc2NvcmUsIG1lYW53aGlsZSAiJFxzaWdtYSQiIHN0YW5kcyBmb3IgJ3N0YW5kYXJkIGRldmlhdGlvbicgc2NvcmUuXSA9IGByIG1lYW4oaXJyX2N4bltbImthcHBhIl1dKSAlPiUgcm91bmQoMkwpYCwgJFxzaWdtYSQgPSBgciBzZChpcnJfY3huW1sia2FwcGEiXV0pICU+JSByb3VuZCgyTClgKS4KCmBgYHtyIGthcHBhLWN4bn0KIyBwcmludCB0aGUgcmVzdWx0IG9mIGludGVycmF0ZXItYWdyZWVtZW50IGZvciB0aGUgY29uc3RydWN0aW9uCmlycl9jeG4gJT4lCiAgbXV0YXRlKHdvcmRzID0gcGFzdGUoIioiLCB3b3JkcywgIioiLCBzZXAgPSAiIiksCiAgICAgICAgIGdsb3NzID0gYygiaGFwcGluZXNzIiwgImpveSIsICJwbGVhc3VyZSIpLAogICAgICAgICBrYXBwYSA9IHJvdW5kKGthcHBhLCAyTCkpICU+JSAKICBzZWxlY3Qod29yZHMsIGdsb3NzLCBldmVyeXRoaW5nKCkpICU+JSAKICBrbml0cjo6a2FibGUoY2FwdGlvbiA9ICJDb2hlbidzIEthcHBhIGZvciB0aGUgQ29uc3RydWN0aW9uYWwgUGF0dGVybnMgaWRlbnRpZmljYXRpb24iLCByb3cubmFtZXMgPSBUUlVFKQpgYGAKCltGaWd1cmUgXEByZWYoZmlnOmthcHBhLWN4bi1maWd1cmUpXSgja2FwcGEtY3huLWZpZ3VyZSkgc3VtbWFyaXNlcyB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBtb3N0IGZyZXF1ZW50IGNvbnN0cnVjdGlvbmFsIHBhdHRlcm5zIGZvciB0aGUgYWdyZWVkIGNhc2VzLCBvY2N1cnJpbmcgYXQgbGVhc3QgZml2ZSB0b2tlbnMuCgpgYGB7ciBrYXBwYS1jeG4tZmlndXJlLCBmaWcud2lkdGg9NywgZmlnLmFzcD0wLjd9CmhhcHB5cjo6cGxvdF9jeG5faW50ZXJyYXRlcihkZiA9IGhhcHB5cjo6dG9wX2N4bl9kYXRhKSArCiAgbGFicyh0aXRsZSA9IGV4cHJlc3Npb24ocGFzdGUoIkRpc3RyaWJ1dGlvbiBvZiB0aGUgY29uc3RydWN0aW9uYWwgcGF0dGVybnMgZm9yIHRoZSBhZ3JlZWQgY2FzZXMgKCIsIE5bInBhdHRlcm5zIl0gPj0gIjUpIiwgc2VwID0gIiIpKSwKICAgICAgIGNhcHRpb24gPSAiVGhlIHZhbHVlcyBpbnNpZGUgdGhlIGJhcnMgYXJlIHRoZSBwYXR0ZXJucycgdG9rZW4gZnJlcXVlbmNpZXMiKQpgYGAKClRoZSB2YWx1ZXMgaW5zaWRlIHRoZSBiYXJzIHJlcHJlc2VudHMgdGhlIHRva2VuIGZyZXF1ZW5jeSBvZiB0aGUgcGF0dGVybnMuIFRoZSAnYHIgaGFwcHlyOjpzY2FwcygibGV4IilgLeKApicgcGFydCBpbiB0aGUgbGVnZW5kIGluZGljYXRlcyB0aGUgc3ludGFjdGljLCBjb25zdHJ1Y3Rpb25hbCBjb2xsb2NhdGVzIG9mIHRoZSB0YXJnZXQgZG9tYWluIHdvcmRzICh0aGUgJ1Qt4oCmJyBwYXJ0KSB0aGF0IHBvdGVudGlhbGx5IGV2b2tlIHRoZSBtZXRhcGhvcmljYWwgc291cmNlIGZyYW1lcy4gVGhlIGNvbnN0cnVjdGlvbmFsIHBhdHRlcm5zIGluIHRoZSBsZWdlbmQgYXJlIGluIGRlc2NlbmRpbmcgb3JkZXIgZnJvbSB0aGUgbW9zdCB0byB0aGUgbGVhc3QgZnJlcXVlbnQgdHlwZXMgYW1vbmcgdGhlc2UgdG9wIGNvbnN0cnVjdGlvbnMuIFRoZXNlIHR5cGVzIGFyZSBleGVtcGxpZmllZCBpbiBvcmRlciBiZWxvdy4KCihAY3huMSkgKkJhZ2kga29uc3VtZW4geWFuZyBfX21lbWJ1cnVfXyBrZXNlbmFuZ2FuIHNlc2FhdCogKGByIGhhcHB5cjo6c2NhcHMoJ2xleCcpYC12ZXJiX1QtZG9iaikgKGluZF9uZXdzY3Jhd2wyMDExXzFNOjYyMTQxOSkgCihAY3huMikgKmtlYmFoYWdpYWFuIF9fbWVtdW5jYWtfXyBzZXRlbGFoIHBhcmEgcGVuYXJpIGRhbiBwZW5vbnRvbiBtZW1haW5rYW4gcGVybWFpbmFuIHNlcmVtb25pYWwga3VubyogKFQtc3Vial9gciBoYXBweXI6OnNjYXBzKCdsZXgnKWAtdmVyYikgKGluZF9uZXdzY3Jhd2wyMDEyXzFNOjkxMDM3MikgCihAY3huMykgKm1lbmphZGlrYW4gbWFudXNpYSBzZWJhZ2FpIF9fYnVkYWtfXyBrZXNlbmFuZ2FuKiAoYHIgaGFwcHlyOjpzY2FwcygnbGV4JylgLW5vdW5fVC1ub3VuKSAoaW5kX25ld3NjcmF3bDIwMTJfMU06Nzc2NykKKEBjeG40KSAqX19kYWxhbV9fIGtlc2VuYW5nYW4gdGVudHUgYWRhIGtlc3VzYWhhbm55YSogKGByIGhhcHB5cjo6c2NhcHMoJ2xleCcpYC1wcmVwX1Qtbm91bikgKGluZF93ZWIyMDEyXzFNOjMwMjA4OSkKKEBjeG41KSAqaGlkdXAgZHVuaWEgc2FuZ2F0bGFoIHBlbnRpbmcga2FsYXUgZGlqYWRpa2FuIHBlcnNpYXBhbiB1bnR1ayBrZWJhaGFnaWFhbiBfX2FraGlyYXRfXyogKFQtbm91bl9gciBoYXBweXI6OnNjYXBzKCdsZXgnKWAtbm91bikgKGluZF9taXhlZDIwMTJfMU06NDA2ODg1KQoKLi4uCgojIyBSZXN1bHRzIGZvciAqbWV0YXBob3JpY2l0eSogb2YgdGhlIHBhdHRlcm5zCgpUaGUgbmV4dCB0YXNrIGlzIHRvIGlkZW50aWZ5IHdoZXRoZXIgdGhlIGV4dHJhY3RlZCBhbmQgX2FncmVlZF8gY29uc3RydWN0aW9uYWwgcGF0dGVybnMgb2YgdGhlIHN5bm9ueW1zIGV2b2tlIG1ldGFwaG9yaWNhbCByZWFkaW5ncyBvciBub3QuIEZvciB0aGlzIHRhc2ssIHdlIGV4cGVjdGVkIHRoZSBhZ3JlZW1lbnQgd291bGQgYmUgbG93ZXIgdGhhbiBpbiB0aGUgcHJldmlvdXMgdGFzayBhcyBkZXRlcm1pbmluZyBtZXRhcGhvcmljYWwgdXNhZ2VzIGlzIG1vcmUgc3ViamVjdGl2ZS4gVGhlIHJlc3VsdHMgYXJlIHNob3duIGluIFtUYWJsZSBcQHJlZih0YWI6a2FwcGEtbWV0YXBob3IpXSgja2FwcGEtbWV0YXBob3IpLgoKYGBge3Iga2FwcGEtbWV0YXBob3J9CiMga2FwcGEgY2FsY3VsYXRpb24gZmlyc3Qgcm91bmQKaXJyX3VzZV8xIDwtIGhhcHB5cjo6a2FwcGFfdGlkeShkZiA9IGhhcHB5cjo6ZGZfbWV0YV91c2VfMXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhcl9uYW1lcyA9ICJedXNlXyhjb2RlcnxhdXRob3IpJCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91bmQgPSAicHJlX2Rpc2MiKSAlPiUgCiAgbXV0YXRlKHdvcmRzID0gcGFzdGUoIioiLCB3b3JkcywgIioiLCBzZXAgPSAiIiksCiAgICAgICAgIGdsb3NzID0gYygiaGFwcGluZXNzIiwgImpveSIsICJwbGVhc3VyZSIpLAogICAgICAgICBrYXBwYSA9IHJvdW5kKGthcHBhLCAyTCkpICU+JSAKICBzZWxlY3Qod29yZHMsIGdsb3NzLCBldmVyeXRoaW5nKCkpCgojIGthcHBhIGNhbGN1bGF0aW9uIHNlY29uZCByb3VuZAppcnJfdXNlXzIgPC0gaGFwcHlyOjprYXBwYV90aWR5KGRmID0gaGFwcHlyOjpkZl9tZXRhX3VzZV8ybmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyX25hbWVzID0gIl51c2VfMm5kXyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91bmQgPSAicG9zdF9kaXNjIikgJT4lIAogIG11dGF0ZSh3b3JkcyA9IHBhc3RlKCIqIiwgd29yZHMsICIqIiwgc2VwID0gIiIpLAogICAgICAgICBnbG9zcyA9IGMoImhhcHBpbmVzcyIsICJqb3kiLCAicGxlYXN1cmUiKSwKICAgICAgICAga2FwcGEgPSByb3VuZChrYXBwYSwgMkwpKSAlPiUgCiAgc2VsZWN0KHdvcmRzLCBnbG9zcywgZXZlcnl0aGluZygpKQoKaXJyX3VzZV8yICU+JSAKICBiaW5kX3Jvd3MoaXJyX3VzZV8xKSAlPiUgCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSAiQ29oZW4ncyBLYXBwYSBmb3IgdGhlIE1ldGFwaG9yIElkZW50aWZpY2F0aW9uIChwb3N0LSBhbmQgcHJlLWRpc2N1c3Npb24gc3RhZ2VzKSIsIHJvdy5uYW1lcyA9IFRSVUUpCmBgYAoKSW4gdGhlIGZpcnN0IHJvdW5kLCBhcyBleHBlY3RlZCwgdGhlIGF2ZXJhZ2UgYWdyZWVtZW50IGFjcm9zcyB0aGUgdGhyZWUgc3lub255bXMgaXMgbW9kZXJhdGUgKCRcbXUkID0gYHIgbWVhbihpcnJfdXNlXzFbWyJrYXBwYSJdXSkgJT4lIHJvdW5kKDJMKWAsICRcc2lnbWEkID0gYHIgc2QoaXJyX3VzZV8xW1sia2FwcGEiXV0pICU+JSByb3VuZCgyTClgKS4gRGlmZmVyZW5jZXMgd2VyZSByZXNvbHZlZCBpbiB0aGUgZGlzY3Vzc2lvbiByb3VuZC4KCk9uZSBvZiB0aGUgcHJvbWluZW50IGRpZmZlcmVuY2VzIGlzIHRoYXQgdGhlIHNlY29uZCBjb2RlciBhbm5vdGF0ZWQgcGF0dGVybnMgcmVmZXJyaW5nIHRvIGByIGhhcHB5cjo6c2NhcHMoJ3RlbXBvcmFsJylgIGFzcGVjdCBvZiB0aGUgc3lub255bXMgYXMgbWV0YXBob3JpY2FsLCB3aGlsZSBgciBoYXBweXI6OnNjYXBzKCd0aW1lJylgIGl0c2VsZiBpcyBvZnRlbiB1bmRlcnN0b29kIGluIG1ldGFwaG9yaWNhbCBjb25jZXB0cyBbZS5nLiwgQGJvcm9kaXRza3lfcm9sZXNfMjAwMl0uIFRoZSBwYXR0ZXJucyBpbmNsdWRlICpOUH5lbW9+IF9fYWJhZGlfXyogJ19ldGVybmFsXyBOUH5lbW9+JywgKk5QfmVtb34gX19kaXR1bmRhX18qICdOUH5lbW9+IF9iZSBkZWxheWVkL3Bvc3Rwb25lZF8sICpfX21lbnVuZGFfXyBOUH5lbW9+KiAndG8gX2RlbGF5L3Bvc3Rwb25lXyBOUH5lbW9+JywgKk5QfmVtb34gX19iZXJ0YWhhbi9iZXJsYW5nc3VuZyBsYW1hX18qICdOUH5lbW9+IF9sYXN0cyBsb25nXycsICpOUH5lbW9+IF9fYmVybGFuZ3N1bmcgc2VzYWF0X18qICdOUH5lbW9+ICpsYXN0cyBmb3IgYSB3aGlsZSonLCBhbmQgKk5QfmVtb34gaGFueWEgX19zZW1lbnRhcmFfXyogJ05QfmVtb34gaXMganVzdCBfZm9yIGEgd2hpbGVfJy4KCi4uLgoKV2l0aCB0aGUgcmVtYWluaW5nIHVucmVzb2x2ZWQgZGlmZmVyZW5jZXMsIHRoZSBzZWNvbmQgS2FwcGEgd2FzIGNhbGN1bGF0ZWQsIGFuZCB0aGUgbWVhbiBLYXBwYSBpbmNyZWFzZXMgdG8gc3Vic3RhbnRpYWwgYWdyZWVtZW50ICgkXG11JCA9IGByIG1lYW4oaXJyX3VzZV8yW1sia2FwcGEiXV0pICU+JSByb3VuZCgyTClgLCAkXHNpZ21hJCA9IGByIHNkKGlycl91c2VfMltbImthcHBhIl1dKSAlPiUgcm91bmQoMkwpYCkuCgojIyBSZXN1bHRzIGZvciAqY29uY2VwdHVhbCBtZXRhcGhvcnMqCgpDb2RpbmcgZm9yIHRoZSBjb25jZXB0dWFsIG1ldGFwaG9ycyBpcyBiYXNlZCBvbiB0aGUgYWdyZWVkIGNvbnN0cnVjdGlvbmFsIHBhdHRlcm5zIHRoYXQgaGF2ZSBhbHNvIGJlZW4gYWdyZWVkIHRvIGJlIG1ldGFwaG9yaWNhbCBbQHNodXRvdmFfY29uY2VwdHVhbF8yMDEzLCBwLiAxMjc1XS4gW1RhYmxlIFxAcmVmKHRhYjprYXBwYS1jbSldKCNrYXBwYS1jbSkgcHJlc2VudHMgdGhlIHJlc3VsdHMgZm9yIHRoaXMgY2xhc3NpZmljYXRpb24uCgpgYGB7ciBrYXBwYS1jbX0KIyBrYXBwYSBjYWxjdWxhdGlvbiBmaXJzdCByb3VuZAppcnJfY21fMSA8LSBoYXBweXI6OmthcHBhX3RpZHkoZGYgPSBoYXBweXI6OmRmX2NtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhcl9uYW1lcyA9ICJfcHJlJCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91bmQgPSAicHJlX2Rpc2MiKSAlPiUgCiAgbXV0YXRlKHdvcmRzID0gcGFzdGUoIioiLCB3b3JkcywgIioiLCBzZXAgPSAiIiksCiAgICAgICAgIGdsb3NzID0gYygiaGFwcGluZXNzIiwgImpveSIsICJwbGVhc3VyZSIpLAogICAgICAgICBrYXBwYSA9IHJvdW5kKGthcHBhLCAyTCkpICU+JSAKICBzZWxlY3Qod29yZHMsIGdsb3NzLCBldmVyeXRoaW5nKCkpCgojIGthcHBhIGNhbGN1bGF0aW9uIHNlY29uZCByb3VuZAppcnJfY21fMiA8LSBoYXBweXI6OmthcHBhX3RpZHkoZGYgPSBoYXBweXI6OmRmX2NtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhcl9uYW1lcyA9ICJfcG9zdCQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdW5kID0gInBvc3RfZGlzYyIpICU+JSAKICBtdXRhdGUod29yZHMgPSBwYXN0ZSgiKiIsIHdvcmRzLCAiKiIsIHNlcCA9ICIiKSwKICAgICAgICAgZ2xvc3MgPSBjKCJoYXBwaW5lc3MiLCAiam95IiwgInBsZWFzdXJlIiksCiAgICAgICAgIGthcHBhID0gcm91bmQoa2FwcGEsIDJMKSkgJT4lIAogIHNlbGVjdCh3b3JkcywgZ2xvc3MsIGV2ZXJ5dGhpbmcoKSkKCmlycl9jbV8yICU+JSAKICBiaW5kX3Jvd3MoaXJyX2NtXzEpICU+JSAKICBrbml0cjo6a2FibGUoY2FwdGlvbiA9ICJDb2hlbidzIEthcHBhIGZvciB0aGUgQ29uY2VwdHVhbCBNZXRhcGhvciBjb2RpbmcgKHBvc3QtIGFuZCBwcmUtZGlzY3Vzc2lvbiBzdGFnZXMpIiwgcm93Lm5hbWVzID0gVFJVRSkKYGBgCgpJbiB0aGUgZmlyc3Qgcm91bmQsIHRoZSBhdmVyYWdlIEthcHBhIGlzIG1vZGVyYXRlICgkXG11JCA9IGByIG1lYW4oaXJyX2NtXzFbWyJrYXBwYSJdXSkgJT4lIHJvdW5kKDJMKWAsICRcc2lnbWEkID0gYHIgc2QoaXJyX2NtXzFbWyJrYXBwYSJdXSkgJT4lIHJvdW5kKDJMKWApLiBEaXNjcmVwYW5jaWVzIG9jY3VyIHByZWRvbWluYW50bHkgd2l0aCByZWdhcmRzIHRvIGRldGVybWluaW5nIHRoZSBsZXZlbCBvZiBncmFudWxhcml0eSBmb3IgdGhlIChtbmVtb25pYyBsYWJlbHMgb2YgdGhlKSBtZXRhcGhvcnMsIHRoZSBkZWNpc2lvbiBvZiB3aGljaCByZXF1aXJlcyBzdWJqZWN0aXZlIGludGVycHJldGF0aW9uLgoKLi4uCgpXaXRoIHRoZSByZW1haW5pbmcgdW5yZXNvbHZlZCBkaXNhZ3JlZW1lbnQgYWZ0ZXIgZGlzY3Vzc2lvbiwgdGhlIHNlY29uZCByb3VuZCBLYXBwYXMgd2VyZSBjb21wdXRlZC4gT24gYXZlcmFnZSwgdGhlIGFncmVlbWVudCBsZXZlbCBoYXMgaW5jcmVhc2VkIHRvICJuZWFybHkgcGVyZmVjdCIgYWdyZWVtZW50ICgkXG11JCA9IGByIG1lYW4oaXJyX2NtXzJbWyJrYXBwYSJdXSkgJT4lIHJvdW5kKDJMKWAsICRcc2lnbWEkID0gYHIgc2QoaXJyX2NtXzJbWyJrYXBwYSJdXSkgJT4lIHJvdW5kKDJMKWApLiBEZXNwaXRlIHRoaXMgaW5jcmVhc2VkIGFncmVlbWVudCBsZXZlbCBhZnRlciBkaXNjdXNzaW9uLCBhZnRlciBhbGwsIGFueSBtZXRhcGhvciBzdHVkaWVzIGFyZSBhbHdheXMgcGVybWVhdGVkIGJ5IGNlcnRhaW4gZGVncmVlIG9mIHN1YmplY3Rpdml0eS4gSW4gcHJhY3RpY2UsIGl0IG1lYW5zIHRoYXQgQ01UIGFuYWx5c3RzL3ByYWN0aWNpb25lcnMgY2FuIGhhdmUgZGlzYWdyZWVtZW50IG92ZXIgY2VydGFpbiBhbmFseXNlcywgYmUgaXQgd2hlbiBkZXRlcm1pbmluZyB3aGV0aGVyIGFuIGV4cHJlc3Npb24gaXMgbWV0YXBob3JpY2FsIG9yIG5vdCwgb3Igd2hlbiBncm91cGluZyBhIHNldCBvZiBtZXRhcGhvcmljYWwgZXhwcmVzc2lvbnMgaW50byBjZXJ0YWluIGNvbmNlcHR1YWwgbWV0YXBob3IgY2F0ZWdvcmllcy4KCiMgQ29kZXMgZm9yIENoYXB0ZXIgNSAtIEVudHJlbmNoZWQgbWV0YXBob3JzCgpgYGB7ciB0dHIsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQojIGNhbGN1bGF0aW9uIGZvciB0aGUgdG9rZW4sIHR5cGUsIGFuZCB0eXBlL3Rva2VuIHJhdGlvcyBkYXRhCnR0cl9tZXRhcGhvciA8LSBoYXBweXI6OnR0cihkZiA9IGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWFfdmFyID0gIm1ldGFwaG9ycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXh1bml0X3ZhciA9ICJsdSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbG9hdF9kaWdpdHMgPSAyKQpgYGAKCmBgYHtyIHBlcmMtb2YtZGlzY3Vzc2VkLW1ldGFwaG9yLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0KIyBUb2tlbnMgcHJvcG9ydGlvbiBvZiB0aGUgZGlzY3Vzc2VkIG1ldGFwaG9ycwpjcmVhdGl2ZV9tZXRhcGhvcnNfbGVuZ3RoIDwtIHR0cl9tZXRhcGhvciAlPiUgCiAgYXJyYW5nZShkZXNjKHR5cGVfcGVyX3Rva2VuX2x1KSkgJT4lIAogIGZpbHRlcih0b2tlbiA+PSAzKSAlPiUgCiAgdG9wX24oMTAsIHR5cGVfcGVyX3Rva2VuX2x1KSAlPiUgCiAgc2VsZWN0KG1ldGFwaG9ycywgdG9rZW4sIHR5cGVfbHUsIHR5cGVfcGVyX3Rva2VuX2x1KSAlPiUgCiAgZGltKCkgJT4lIAogIC5bMV0KCmNyZWF0aXZlX21ldGFwaG9yc19wcm9wIDwtIHR0cl9tZXRhcGhvciAlPiUgCiAgYXJyYW5nZShkZXNjKHR5cGVfcGVyX3Rva2VuX2x1KSkgJT4lIAogIGZpbHRlcih0b2tlbiA+PSAzKSAlPiUgCiAgdG9wX24oMTAsIHR5cGVfcGVyX3Rva2VuX2x1KSAlPiUgCiAgdGFsbHkocGVyY190b2tlbikgJT4lIAogIC4kbgoKdG9wX3Rva2VuX21ldGFwaG9yIDwtIHR0cl9tZXRhcGhvciAlPiUgCiAgdG9wX24oMTAsIHRva2VuKSAlPiUgCiAgLlssMV0gJT4lIAogIHVubGlzdCgpICU+JSAKICB1bm5hbWUoKQoKdG9wX3R5cGVfbWV0YXBob3IgPC0gdHRyX21ldGFwaG9yICU+JSAKICB0b3BfbigxMCwgdHlwZV9sdSkgJT4lIAogIC5bLDFdICU+JSAKICB1bmxpc3QoKSAlPiUgCiAgdW5uYW1lKCkKCmVudHJlbmNoZWRfbWV0YXBob3JzX3Byb3AgPC0gdHRyX21ldGFwaG9yICU+JSAKICB0b3BfbigxMCwgdG9rZW4pICU+JSAKICB0YWxseShwZXJjX3Rva2VuKSAlPiUgCiAgLiRuCgpwcm9kdWN0aXZlX21ldGFwaG9yc19sZW5ndGggPC0gc2V0ZGlmZih0b3BfdHlwZV9tZXRhcGhvciwgdG9wX3Rva2VuX21ldGFwaG9yKSAlPiUgCiAgbGVuZ3RoKCkKCnByb2R1Y3RpdmVfbWV0YXBob3JzX3Byb3AgPC0gdHRyX21ldGFwaG9yICU+JSAKICB0b3BfbigxMCwgdHlwZV9sdSkgJT4lIAogIGFycmFuZ2UoZGVzYyh0eXBlX2x1KSkgJT4lIAogIGZpbHRlcih0b2tlbiA8IDEwMCkgJT4lIAogIHRhbGx5KHBlcmNfdG9rZW4pICU+JSAKICAuJG4KYGBgCgojIyBJbnRyb2R1Y3Rpb24KCi4uLgoKRm9yIHRoaXMgdGhlc2lzLCBJIGFuYWx5c2VkIDQ1ODBeW1RoZXNlIGFyZSB0b2tlbnMgYWZ0ZXIgbWFudWFsIGR1cGxpY2F0ZXMtcmVtb3ZhbC5dIHVzYWdlIHNhbXBsZXMgb2Ygc2VudGVuY2VzIGNvbnRhaW5pbmcgd29yZHMgcmVmZXJyaW5nIHRvIGZpdmUgY2VudHJhbCBtZW1iZXJzIHVuZGVyIHRoZSBnZW5lcmljIGByIGhhcHB5cjo6c2NhcHMoJ2hhcHBpbmVzcycpYC1saWtlIGNhdGVnb3J5IGluIEluZG9uZXNpYW4gW2NmLiBAc2hhdmVyX3N0cnVjdHVyZV8yMDAxXS4gVGhlIGFuYWx5c2lzIHJlc3VsdHMgaW4gdGhlIHRvdGFsIGByIHN1bSh0dHJfbWV0YXBob3IkdG9rZW4pYCB0b2tlbnMgb2YgbWV0YXBob3JpY2FsIGxpbmd1aXN0aWMgZXhwcmVzc2lvbnMgY29udGFpbmluZyBgciBkaW0odHRyX21ldGFwaG9yKVsxXWAgbWV0YXBob3IgdHlwZXMuCgouLi4KClRoaXMgY2hhcHRlciBkaXNjdXNzZXMgdGhlIHRvcC0xMCBtb3N0IGZyZXF1ZW50IGNvbmNlcHR1YWwgbWV0YXBob3JzIChgciBzZWN0aW9uYFtcQHJlZihmcmVxdWVudG1ldGFwaG9ycyldKCNmcmVxdWVudG1ldGFwaG9ycykpLCBjb25zdGl0dXRpbmcgYHIgZW50cmVuY2hlZF9tZXRhcGhvcnNfcHJvcGAlIG9mIHRoZSB0b3RhbCBtZXRhcGhvcmljYWwgdG9rZW5zOyBDaGFwdGVyIDYgZGlzY3Vzc2VzIGByIHByb2R1Y3RpdmVfbWV0YXBob3JzX3Byb3AgKyBjcmVhdGl2ZV9tZXRhcGhvcnNfcHJvcGAlIG9mIHRoZSB0b3RhbCBgciBzdW0odHRyX21ldGFwaG9yJHRva2VuKWAgdG9rZW5zLCBjb25zaXN0aW5nIG9mIGByIHByb2R1Y3RpdmVfbWV0YXBob3JzX2xlbmd0aCtjcmVhdGl2ZV9tZXRhcGhvcnNfbGVuZ3RoYCBkaWZmZXJlbnQgbWV0YXBob3IgdHlwZXMuIEluIHRvdGFsLCBDaGFwdGVyIDUgYW5kIENoYXB0ZXIgNiBhY2NvdW50IGZvciBgciBwcm9kdWN0aXZlX21ldGFwaG9yc19wcm9wICsgY3JlYXRpdmVfbWV0YXBob3JzX3Byb3AgKyBlbnRyZW5jaGVkX21ldGFwaG9yc19wcm9wYCUgb2YgdGhlIHRvdGFsIGByIHN1bSh0dHJfbWV0YXBob3IkdG9rZW4pYCB0b2tlbnMgb2YgdGhlIG1ldGFwaG9yaWNhbCBleHByZXNzaW9ucy4KCi4uLgoKIyMgVG9wLTEwIGZyZXF1ZW50IG1ldGFwaG9ycyBmb3IgYHIgc2NhcHMoImhhcHBpbmVzcyIpYCBpbiBJbmRvbmVzaWFuIHsjZnJlcXVlbnRtZXRhcGhvcnN9CgpUaGlzIHNlY3Rpb24gZGlzY3VzcyB3aGljaCBtZXRhcGhvcnMgYXJlIHJlbGF0aXZlbHkgZW50cmVuY2hlZCBmb3IgYHIgc2NhcHMoImhhcHBpbmVzcyIpYCBpbiBJbmRvbmVzaWFuLCBiYXNlZCBvbiB0aGVpciB0b2tlbiBmcmVxdWVuY3kgW2NmLiBAaGlscGVydF9rZWVwaW5nXzIwMDYsIHBwLiAxMzAtMTMxXS4gSSBmb2N1cyBvbiB0aGUgdGVuIG1vc3QgZnJlcXVlbnQgbWV0YXBob3JzIGFzIHNob3duIGluIFtUYWJsZSBcQHJlZih0YWI6dG9wLTEwLWZyZXF1ZW50LW1ldGFwaG9ycyldKCN0b3AtMTAtZnJlcXVlbnQtbWV0YXBob3JzKS4KCmBgYHtyIHRvcC0xMC1mcmVxdWVudC1tZXRhcGhvcnN9CnR0cl9tZXRhcGhvciAlPiUgCiAgdG9wX24oMTAsIHRva2VuKSAlPiUgCiAgc2VsZWN0KG1ldGFwaG9ycywgdG9rZW4sIHBlcmNfdG9rZW4pICU+JSAKICBtdXRhdGUobWV0YXBob3JzID0gaGFwcHlyOjpzY2FwcyhtZXRhcGhvcnMpKSAlPiUgCiAgcmVuYW1lKE1ldGFwaG9ycyA9IG1ldGFwaG9ycywKICAgICAgICAgVG9rZW4gPSB0b2tlbiwKICAgICAgICAgYCVUb2tlbmAgPSBwZXJjX3Rva2VuKSAlPiUgCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSAnVG9wLTEwIG1ldGFwaG9ycyBzb3J0ZWQgaW4gZGVzY2VuZGluZyBvcmRlciBvZiB0aGUgdG9rZW4gZnJlcXVlbmN5LicsIHJvdy5uYW1lcyA9IFRSVUUpCmBgYAoKQXMgW1RhYmxlIFxAcmVmKHRhYjp0b3AtMTAtZnJlcXVlbnQtbWV0YXBob3JzKV0oI3RvcC0xMC1mcmVxdWVudC1tZXRhcGhvcnMpIHNob3dzLCBgciBzY2FwcygnaGFwcGluZXNzJylgIGlzIG1vc3QgZnJlcXVlbnRseSBjb25zdHJ1ZWQgYXMgYSBgciBzY2FwcygncG9zc2Vzc2FibGUgb2JqZWN0JylgLiBUaGUgZm9sbG93aW5nIHN1Yi1zZWN0aW9ucyBlbGFib3JhdGUgb24gdGhlIHN1Ym1hcHBpbmdzIGFuZCB0aGUgaW5mZXJlbmNlcyBldm9rZWQgZm9yIGNvbnN0cnVpbmcgYXNwZWN0cyBvZiBgciBzY2FwcygnaGFwcGluZXNzJylgLiBXaGlsZSB0aGUgZGlzY3Vzc2lvbiBiZWdpbnMgd2l0aCB0aGUgYHIgc2NhcHMoJ2hhcHBpbmVzcyBpcyBhIHBvc3Nlc3NhYmxlIG9iamVjdCcpYCBtZXRhcGhvciwgaXQgbWF5IG5vdCBmdWxseSBmb2xsb3cgdGhlIHJhbmtlZC1vcmRlciBvZiB0aGUgbWV0YXBob3JzIGluIFtUYWJsZSBcQHJlZih0YWI6dG9wLTEwLWZyZXF1ZW50LW1ldGFwaG9ycyldKCN0b3AtMTAtZnJlcXVlbnQtbWV0YXBob3JzKS4gSW5zdGVhZCwgbWV0YXBob3JzIGNvbnZleWluZyByZWxhdGVkIHRoZW1lcyB3aWxsIGZvbGxvdyBmcm9tIG9uZSBhbm90aGVyIGluIHRoZSBkaXNjdXNzaW9uIHRvIGhpZ2hsaWdodCBzaW1pbGFyaXRpZXMuIEZvciBpbnN0YW5jZSwgdGhlIGFzcGVjdCBvZiBpbnRlbnNpdHkgaXMgaGlnaGxpZ2h0ZWQgbWFpbmx5IGJ5IGByIHNjYXBzKCdjb250YWluZWQgZW50aXR5LCBsaXF1aWQgaW4gYSBjb250YWluZXInKWAsIGFuZCBgciBzY2FwcygncXVhbnRpdHkgb2Ygb2JqZWN0JylgIG1ldGFwaG9ycy4gVGhlc2UgdGhyZWUgbWV0YXBob3JzIGFyZSBhY2NvcmRpbmdseSBwcmVzZW50ZWQgaW4gc2VxdWVuY2UsIGRlc3BpdGUgdGhlaXIgbm9uLXN1Y2Nlc3NpdmUgcmFua2luZyBpbiBbVGFibGUgXEByZWYodGFiOnRvcC0xMC1mcmVxdWVudC1tZXRhcGhvcnMpXSgjdG9wLTEwLWZyZXF1ZW50LW1ldGFwaG9ycykuCgojIyMgSGFwcGluZXNzIGlzIGEgcG9zc2Vzc2FibGUgb2JqZWN0IHsjcG9zc2Vzc2lvbn0KCmBgYHtyIHBvc3Nlc3Npb24tZGF0YS1mb3ItYm9keXRleHR9Cmx1X3Bvc3Nlc3NhYmxlIDwtIGhhcHB5cjo6Z2V0X2x1X3RhYmxlKCJwb3NzZXNzYWJsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvcF9uX29ubHkgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGYgPSBoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmNsX3N1Ym1hcHBpbmdzID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VibWFwcGluZ19wZXJjID0gVFJVRSkKCnBvc3Nlc3NfZnJhbWVzIDwtIGhhcHB5cjo6Z2V0X2ZyYW1lcygicG9zc2Vzc2FibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGYgPSBoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yKQoKcG9zc2Vzc19zdWJtYXBwaW5ncyA8LSBoYXBweXI6OmdldF9zdWJtYXBwaW5ncygicG9zc2Vzc2FibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRmID0gaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvcikgJT4lIAogIG11dGF0ZShhc3BlY3QgPSBpZl9lbHNlKHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICdjYXVzJyksICdjYXVzZScsICdleGlzdGVuY2UnKSwKICAgICAgICAgYXNwZWN0ID0gaWZfZWxzZShzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAnYXR0YWluJyksICdhdHRhaW5tZW50JywgYXNwZWN0KSwKICAgICAgICAgYXNwZWN0ID0gaWZfZWxzZShzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAnY2hhbmdlIG9mICcpLCAnY2Vhc2luZycsIGFzcGVjdCkpCgpwb3NzZXNzX3N1Ym1hcHBpbmdzX2FzcGVjdCA8LSBwb3NzZXNzX3N1Ym1hcHBpbmdzICU+JSAKICBncm91cF9ieShhc3BlY3QpICU+JSAKICBzdW1tYXJpc2UobiA9IHN1bShuKSwgCiAgICAgICAgICAgIHR5cGUgPSBzdW0odHlwZSkpICU+JSAKICBtdXRhdGUocGVyYyA9IHJvdW5kKG4vc3VtKG4pICogMTAwLCAyKSwgCiAgICAgICAgIHR5cGVfcGVyYyA9IHJvdW5kKG4vc3VtKG4pICogMTAwLCAyKSkgJT4lIAogIGFycmFuZ2UoZGVzYyhuKSkKYGBgCgouLi4KClRoZSBjYXVzZSBvZiBgciBzY2FwcygiaGFwcGluZXNzIilgIGlzIHJlZmVycmVkIHRvIHZpYSBpbnRlcnJlbGF0ZWQgZnJhbWVzIGV2b2tpbmcgYHIgc2NhcHMoIm9iamVjdCB0cmFuc2ZlciIpYC4gVGhleSBhcmUgKGkpIHRoZSBgciBzY2Fwcygib2ZmZXJpbmciKWAgZnJhbWUgKGByIHBvc3Nlc3NfZnJhbWVzICU+JSBmaWx0ZXIoZnJhbWVzPT0nb2ZmZXJpbmcnKSAlPiUgc2VsZWN0KHBlcmMpICU+JSB1bmxpc3QoKWAlIG9mIHRoZSB0b3RhbCB0b2tlbnMgb2YgdGhlIGByIHNjYXBzKCJwb3NzZXNzYWJsZSBvYmplY3QiKWAgbWV0YXBob3IpLCB3aGljaCBpbiAqRnJhbWVOZXQqIGlzIGRlc2NyaWJlZCBhcyBhZG9wdGluZyB0aGUgc3RydWN0dXJlIG9mIGByIHNjYXBzKCJnaXZpbmciKWAgZnJhbWU7IChpaSkgdGhlIGByIHNjYXBzKCJnaXZpbmciKWAgZnJhbWUgKGByIHBvc3Nlc3NfZnJhbWVzICU+JSBmaWx0ZXIoZnJhbWVzPT0nZ2l2aW5nJykgJT4lIHNlbGVjdChwZXJjKSAlPiUgdW5saXN0KClgJSk7IChpaWkpIGByIHNjYXBzKCJkaXNwZXJzYWwiKWAsIHdoaWNoIGlzIHJlbGF0ZWQgdG8gYHIgc2NhcHMoInJlc291cmNlIHRyYW5zZmVyIilgIGZyYW1lIGluICpNZXRhTmV0KiAoYHIgcG9zc2Vzc19mcmFtZXMgJT4lIGZpbHRlcihmcmFtZXM9PSdkaXNwZXJzYWwnKSAlPiUgc2VsZWN0KHBlcmMpICU+JSB1bmxpc3QoKWAlKTsgYW5kIChpdikgdGhlIGdlbmVyaWMgYHIgc2NhcHMoImNhdXNlZCBtb3Rpb24iKWAgZnJhbWUgKGByIHBvc3Nlc3NfZnJhbWVzICU+JSBmaWx0ZXIoZnJhbWVzPT0nY2F1c2VkIG1vdGlvbicpICU+JSBzZWxlY3QocGVyYykgJT4lIHVubGlzdCgpYCUpLCB3aGljaCBpbmNsdWRlcyB0aGUgYHIgc2NhcHMoImJyaW5naW5nIilgIGZyYW1lLgoKLi4uCgpGcm9tIHRoZSBwZXJzcGVjdGl2ZSBvZiB0aGUgUmVjaXBpZW50LCByZWNlaXZpbmcgb3IgZ2FpbmluZyB0aGUgdHJhbnNmZXJyZWQgcG9zc2Vzc2FibGUgb2JqZWN0IGlzIG1hcHBlZCBvbnRvIHRoZSBvbnNldCBvZiBgciBzY2FwcygiaGFwcGluZXNzIilgLiBUaGlzIGluZmVyZW5jZSBpcyBldm9rZWQgdGhyb3VnaCB0aGUgYHIgc2NhcHMoImdhaW4gcG9zc2Vzc2lvbiIpYCBmcmFtZSAoYHIgcG9zc2Vzc19mcmFtZXMgJT4lIGZpbHRlcihmcmFtZXM9PSdnYWluIHBvc3Nlc3Npb24nKSAlPiUgc2VsZWN0KHBlcmMpICU+JSB1bmxpc3QoKWAlKS4gVGhlIGZyYW1lIGlzIGF2YWlsYWJsZSBpbiB0aGUgTU4gZnJhbWUgcmVwb3NpdG9yeS4KCi4uLgoKVGhlIGV4cGVyaWVuY2Ugb2YgaGFwcGluZXNzIGNhbiBiZSBleHByZXNzZWQgYXMgdGhlIGdhaW5pbmcgb2YgYSBwb3NzZXNzYWJlIG9iamVjdCwgaW52b2tlZCB0aHJvdWdoIHRoZSBgciBzY2FwcygicG9zc2Vzc2lvbiIpYCBmcmFtZSAoYHIgcG9zc2Vzc19mcmFtZXMgJT4lIGZpbHRlcihmcmFtZXM9PSdwb3NzZXNzaW9uJykgJT4lIHNlbGVjdChwZXJjKSAlPiUgdW5saXN0KClgJSkuCgouLi4KCltUYWJsZSBcQHJlZih0YWI6cG9zc2Vzc2FibGUtb2JqZWN0LWx1LXRhYmxlKV0oI3Bvc3Nlc3NhYmxlLW9iamVjdC1sdS10YWJsZSkgc2hvd3MgdGhlIExVIHR5cGVzIG1vc3QgZnJlcXVlbnRseSBjby1vY2N1ciB3aXRoIHRoZSBgciBzY2FwcygnaGFwcGluZXNzJylgIHdvcmRzIHRvIGV2b2tlIHRoZSBgciBzY2Fwcyh0b2xvd2VyKCdQT1NTRVNTQUJMRSBPQkpFQ1QnKSlgIG1ldGFwaG9yIGFuZCBpdHMgZnJhbWUtYmFzZWQgc3VibWFwcGluZ3MuCgpgYGB7ciBwb3NzZXNzYWJsZS1vYmplY3QtbHUtdGFibGV9CmhhcHB5cjo6Z2V0X2x1X3RhYmxlKCJwb3NzZXNzYWJsZSBvYmplY3QiLCAKICAgICAgICAgICAgICAgICAgICAgdG9wX25fb25seSA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgIGRmID0gaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvcikgJT4lCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSAnVG9wLTEwIG1vc3QgZnJlcXVlbnQgbGV4aWNhbCB1bml0cyBldm9raW5nIDxzcGFuIHN0eWxlID0gImZvbnQtdmFyaWFudDpzbWFsbC1jYXBzOyI+aGFwcGluZXNzIGlzIGEgcG9zc2Vzc2FibGUgb2JqZWN0PC9zcGFuPi4nLCByb3cubmFtZXMgPSBUUlVFKQpgYGAKCgpQZXJjZW50YWdlIG92ZXJhbGwgaW4gdGhlIExVIHRhYmxlIGluZGljYXRlcyB0aGUgcGVyY2VudGFnZSBvZiBhIGdpdmVuIExVIGZyb20gdGhlIHRvdGFsIHRva2VucyBvZiB0aGUgbWV0YXBob3IuCgoqQmVyaShrYW4pKiAndG8gZ2l2ZScsIGZvciBpbnN0YW5jZSwgaXMgdGhlIG1vc3QgZnJlcXVlbnQgTFUgZm9yIHRoZSBgciBzY2FwcygiZ2l2aW5nIilgIGZyYW1lIChgciBsdV9wb3NzZXNzYWJsZVtncmVwKCdiZXJpXFwoa2FuXFwpJywgbHVfcG9zc2Vzc2FibGUkTGV4aWNhbF91bml0cywgcGVybCA9IFQpLCA2XSAlPiUgdW5saXN0KClgJSBvZiB0aGUgdG90YWwgdG9rZW5zIG9mIHRoZSBgciBzY2FwcygiZ2l2aW5nIilgIGZyYW1lKSwgY29tcGFyZWQgdG8gKmtlbWJhbGlrYW4qICd0byBnaXZlIHN0aC4gYmFjazsgdG8gcmV0dXJuIHN0aC4nIChgciBsdV9wb3NzZXNzYWJsZVtncmVwKCdrZW1iYWxpa2FuJywgbHVfcG9zc2Vzc2FibGUkTGV4aWNhbF91bml0cywgcGVybCA9IFQpLCA2XSAlPiUgdW5saXN0KClgICUpLiBGb3IgYHIgc2NhcHMoImdhaW4gcG9zc2Vzc2lvbiIpYCBmcmFtZSwgKmRhcGF0KGthbikqXltJIHB1dCB0aGUgJ3YnIHRhZyBmb3IgKmRhcGF0KGthbikqICd0byBnZXQnIHNpbmNlIHRoZSBmb3JtICpkYXBhdCogaGFzIGFub3RoZXIgZnVuY3Rpb24gYXMgYW4gYWJpbGl0YXRpdmUgbW9kYWwgYXV4aWxpYXJ5ICd0byBiZSBhYmxlIHRvOyBjYW4nLl0gJ3RvIGdldCcgKGByIGx1X3Bvc3Nlc3NhYmxlW2dyZXAoJ2RhcGF0XFwoa2FuXFwpJywgbHVfcG9zc2Vzc2FibGUkTGV4aWNhbF91bml0cywgcGVybCA9IFQpLCA2XSAlPiUgdW5saXN0KClgJSkgaXMgdGhlIG1vc3QgZnJlcXVlbnQgTFUuICpCZXJiYWdpKiAndG8gc2hhcmUnIGlzIHRoZSBtb3N0IGNvbW1vbiBMVSAoYHIgbHVfcG9zc2Vzc2FibGVbZ3JlcCgnYmVyYmFnaScsIGx1X3Bvc3Nlc3NhYmxlJExleGljYWxfdW5pdHMsIHBlcmwgPSBUKSwgNl0gJT4lIHVubGlzdCgpYCUpIGZvciB0aGUgYHIgc2NhcHMoImRpc3BlcnNhbCIpYCBmcmFtZSwgd2hpbGUgKm1pbGlraSogJ3RvIGhhdmUvb3duJyAoYHIgbHVfcG9zc2Vzc2FibGVbZ3JlcCgnbWlsaWtpJywgbHVfcG9zc2Vzc2FibGUkTGV4aWNhbF91bml0cywgcGVybCA9IFQpLCA2XSAlPiUgdW5saXN0KClgJSkgYW5kICprZWhpbGFuZ2FuKiAndG8gbG9zZScgKGByIGx1X3Bvc3Nlc3NhYmxlW2dyZXAoJ2tlaGlsYW5nYW4nLCBsdV9wb3NzZXNzYWJsZSRMZXhpY2FsX3VuaXRzLCBwZXJsID0gVCksIDZdICU+JSB1bmxpc3QoKWAlKSBhcmUgcmVwcmVzZW50YXRpdmUgZm9yIHRoZSBgciBzY2FwcygicG9zc2Vzc2lvbiIpYCBhbmQgYHIgc2NhcHMoImxvc2UgcG9zc2Vzc2lvbiIpYCBmcmFtZXMgcmVzcGVjdGl2ZWx5LiBMYXN0bHksICpiYXdhKGthbikqICd0byBicmluZyBzdGguICh0byBzYi4pJyAoYHIgbHVfcG9zc2Vzc2FibGVbZ3JlcCgnYmF3YVxcKGthblxcKScsIGx1X3Bvc3Nlc3NhYmxlJExleGljYWxfdW5pdHMsIHBlcmwgPSBUKSwgNl0gJT4lIHVubGlzdCgpYCUpIGlzIHRoZSBtb3N0IGZyZXF1ZW50IExVIGZvciB0aGUgYHIgc2NhcHMoImNhdXNlZCBtb3Rpb24iKWAgZnJhbWUuIAoKRGVzcGl0ZSBpdHMgaGlnaCB0b2tlbiBmcmVxdWVuY3ksIGByIHNjYXBzKCJoYXBwaW5lc3MgaXMgYSBwb3NzZXNzYWJsZSBvYmplY3QiKWAgaGFzIGEgbG93IGRlZ3JlZSBvZiBsZXhpY2FsIGRpdmVyc2l0eSBpbiBpdHMgbGluZ3Vpc3RpYyBleHByZXNzaW9ucyBnaXZlbiBpdHMgdG9rZW4gZnJlcXVlbmN5LiBUaGUgbWV0YXBob3IgaXMgZXhwcmVzc2VkIHdpdGggZGlmZmVyZW50IExVIHR5cGVzIGluIG9ubHkgYHIgaGFwcHlyOjpnZXRfbWV0YV9mcmVxX3Byb2ZpbGVzKCdwb3NzZXNzYWJsZScsIHR5cGVfcGVyX3Rva2VuX2x1LCBkZiA9IHR0cl9tZXRhcGhvcikgJT4lIC5bLDJdICU+JSB1bmxpc3QoKWAlIG9mIHRoZSB0b3RhbCBgciBmaWx0ZXIodHRyX21ldGFwaG9yLCBzdHJfZGV0ZWN0KG1ldGFwaG9ycywgInBvc3Nlc3NhYmxlIG9iamVjdCQiKSlbWyJ0b2tlbiJdXWAgdG9rZW5zLiBUaGUgcGVyY2VudGFnZSBpcyBkZXJpdmVkIGZyb20gZGl2aWRpbmcgdGhlIHR5cGUgZnJlcXVlbmN5IG9mIHRoZSBtZXRhcGhvciB3aXRoIGl0cyB0b2tlbiBmcmVxdWVuY3kgKGkuZS4gdGhlICp0eXBlL3Rva2VuIHJhdGlvKiAoVFRSKSBtZWFzdXJlKSBhbmQgbm9ybWFsaXNpbmcgaXQgaW50byBwZXJjZW50YWdlIFtjZi4gQHN0ZWZhbm93aXRzY2hfY29ycHVzXzIwMTcsIHAuIDI4Ml0uIFRoZSBUVFIgdmFsdWUgb2YgYHIgc2NhcHModG9sb3dlcignUE9TU0VTU0FCTEUgT0JKRUNUJykpYCBpbmRpY2F0ZXMgdGhhdCBpdCBpcyBldm9rZWQgYnkgYSBmZXcgeWV0IGhpZ2hseSBmcmVxdWVudCBhbmQgY29udmVudGlvbmFsIG1ldGFwaG9yaWNhbCBleHByZXNzaW9ucy4KCk92ZXJhbGwsIHRoZSBwcmVkb21pbmFudCBzdWJtYXBwaW5ncyBpbiB0aGUgYHIgc2NhcHMoInBvc3Nlc3NhYmxlIG9iamVjdCIpYCBtZXRhcGhvciBhcmUgdGhvc2UgaW52b2x2aW5nIChwb3RlbnRpYWwpIG9iamVjdCB0cmFuc2ZlcnMgKGByIHBvc3Nlc3Nfc3VibWFwcGluZ3NfYXNwZWN0ICU+JSBmaWx0ZXIoYXNwZWN0PT0nY2F1c2UnKSAlPiUgc2VsZWN0KHBlcmMpICU+JSB1bmxpc3QoKWAlIG9mIHRoZSB0b3RhbCBgciBmaWx0ZXIodHRyX21ldGFwaG9yLCBzdHJfZGV0ZWN0KG1ldGFwaG9ycywgInBvc3Nlc3NhYmxlIG9iamVjdCQiKSlbWyJ0b2tlbiJdXWAgdG9rZW5zIG9mIHRoZSBtZXRhcGhvciksIGhpZ2hsaWdodGluZyB0aGUgY2F1c2UgZm9yIGByIHNjYXBzKCJoYXBwaW5lc3MiKWAuIEl0IGlzIHRoZW4gZm9sbG93ZWQgYnkgdGhlIHJlY2VpdmluZyBvZiB0aGUgcG9zc2Vzc2FibGUgb2JqZWN0LCBoZW5jZSB0aGUgYXR0YWlubWVudCBvZiBgciBzY2FwcygiaGFwcGluZXNzIilgIChgciBwb3NzZXNzX3N1Ym1hcHBpbmdzX2FzcGVjdCAlPiUgZmlsdGVyKGFzcGVjdD09J2F0dGFpbm1lbnQnKSAlPiUgc2VsZWN0KHBlcmMpICU+JSB1bmxpc3QoKWAlKTsgdGhlIHBvc3Nlc3NpbmcsIG9yIGV4aXN0ZW5jZSwgKGByIHBvc3Nlc3Nfc3VibWFwcGluZ3NfYXNwZWN0ICU+JSBmaWx0ZXIoYXNwZWN0PT0nZXhpc3RlbmNlJykgJT4lIHNlbGVjdChwZXJjKSAlPiUgdW5saXN0KClgJSk7IGFuZCBsYXN0bHkgdGhlIGxvc2luZywgb3IgY2Vhc2luZywgb2YgYHIgc2NhcHMoImhhcHBpbmVzcyIpYCAoYHIgcG9zc2Vzc19zdWJtYXBwaW5nc19hc3BlY3QgJT4lIGZpbHRlcihhc3BlY3Q9PSdjZWFzaW5nJykgJT4lIHNlbGVjdChwZXJjKSAlPiUgdW5saXN0KClgJSkuCgojIyMgSGFwcGluZXNzIGlzIGEgZGVzaXJlZCBnb2FsIHsjZGVzaXJlZC1nb2FsfQoKYGBge3IgZGVzdGluYXRpb24tZGF0YS1mb3ItYm9keXRleHR9CmdvYWxfc3VibWFwcGluZ3MgPC0gaGFwcHlyOjpnZXRfc3VibWFwcGluZ3MoImRlc2lyZWQiLCBkZiA9IGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IpICU+JSAKICBtdXRhdGUoYXNwZWN0ID0gaWZfZWxzZShzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAncmVhY2hpbmd8Y2FwdHVyaW5nfGdyYXNwaW5nfGZpbmRpbmcnKSwgJ2F0dGFpbmluZycsICdwcm9jZXNzJyksCiAgICAgICAgIGFzcGVjdCA9IGlmX2Vsc2Uoc3RyX2RldGVjdChzdWJtYXBwaW5ncywgJ2FjY2Vzc3xhaWRzJyksICdtZWFucycsIGFzcGVjdCksCiAgICAgICAgIGFzcGVjdCA9IGlmX2Vsc2Uoc3RyX2RldGVjdChzdWJtYXBwaW5ncywgJ2VuZCBvZiBhIHBhdGgnKSwgJ2dvYWwnLCBhc3BlY3QpLAogICAgICAgICBhc3BlY3QgPSBpZl9lbHNlKHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICdpbXBlZGluZycpLCAnb2JzdGFjbGUnLCBhc3BlY3QpKSAlPiUKICBncm91cF9ieShhc3BlY3QpICU+JQogIG11dGF0ZShwZXJjX2FzcGVjdF9ieV9zdWJtZXQgPSByb3VuZChuL3N1bShuKSAqIDEwMCwgMiksCiAgICAgICAgIHR5cGVfcGVyY19hc3BlY3RfYnlfc3VibWV0ID0gcm91bmQodHlwZS9zdW0odHlwZSkgKiAxMDAsIDIpKSAlPiUKICB1bmdyb3VwKCkKCmdvYWxfYXNwZWN0IDwtIGdvYWxfc3VibWFwcGluZ3MgJT4lCiAgZ3JvdXBfYnkoYXNwZWN0KSAlPiUKICBzdW1tYXJpc2UobiA9IHN1bShuKSwgdHlwZSA9IHN1bSh0eXBlKSkgJT4lCiAgbXV0YXRlKHBlcmMgPSByb3VuZChuL3N1bShuKSAqIDEwMCwgMiksIAogICAgICAgICB0eXBlX3BlcmMgPSByb3VuZCh0eXBlL3N1bSh0eXBlKSAqIDEwMCwgMikpICU+JQogIGFycmFuZ2UoZGVzYyhuKSkKCiMgU2VtYW50aWMgdHlwZXMgb2YgdGhlIFBVUlNVSVQgZXZlbnQKc2VhcmNoaW5nX2x1IDwtIGMoImNhcmkiLCAicGVuY2FyaWFuIiwgImplbXB1dChsYWgpIiwgImdhbGkiLCAicGVuZHVsYW5nIiwgInNhc2FyYW4iKQpzZWFyY2hpbmdfbHVfdG9rZW4gPC0gZGltKGZpbHRlcihoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yLCBsdSAlaW4lIHNlYXJjaGluZ19sdSkpWzFdCgpjaGFzaW5nX2x1IDwtIGMoImtlamFyIiwgInBlbmdlamFyYW4iKQpjaGFzaW5nX2x1X3Rva2VuIDwtIGRpbShmaWx0ZXIoaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvciwgbHUgJWluJSBjaGFzaW5nX2x1KSlbMV0KCmh1bnRpbmdfbHUgPC0gYygicGVtYnVydSIsICJidXJ1YW4iLCAibWVtYnVydSIpCmh1bnRpbmdfbHVfdG9rZW4gPC0gZGltKGZpbHRlcihoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yLCBsdSAlaW4lIGh1bnRpbmdfbHUpKVsxXQoKIyBwdXJzdWUgc2VtYW50aWNzIHRhYmxlCnB1cnN1ZV9zZW1hbnRpY3MgPC0gZGF0YS5mcmFtZShzZW1hbnRpY3MgPSBjKCJzZWFyY2hpbmciLCAiY2hhc2luZyIsICJodW50aW5nIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbiA9IGMoc2VhcmNoaW5nX2x1X3Rva2VuLCBjaGFzaW5nX2x1X3Rva2VuLCBodW50aW5nX2x1X3Rva2VuKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gYyhsZW5ndGgoc2VhcmNoaW5nX2x1KSwgbGVuZ3RoKGNoYXNpbmdfbHUpLCBsZW5ndGgoaHVudGluZ19sdSkpKSAlPiUKICBtdXRhdGUocGVyYyA9IHJvdW5kKG4vc3VtKG4pICogMTAwLCAyKSwKICAgICAgICAgdHlwZV9wZXJjID0gcm91bmQodHlwZS9zdW0odHlwZSkgKiAxMDAsIDIpKQoKIyBncmFtbWF0aWNhbCB2b2ljZSBvZiB2ZXJiYWwgbGV4aWNhbCB1bml0cyBmb3IgdGhlIG1ldGFwaG9yCnZvaWNlX2Rlc3RpbmF0aW9uIDwtIGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IgJT4lIAogIGZpbHRlcihzdHJfZGV0ZWN0KG1ldGFwaG9ycywgImRlc2lyZWQiKSwgCiAgICAgICAgIGx1X3BocmFzZV90eXBlID09ICJ2cCIpICU+JSAKICBncm91cF9ieSh2b2ljZV92ZXJiYWxfbHUsIHN1Ym1hcHBpbmdzKSAlPiUgCiAgc3VtbWFyaXNlKG4gPSBuKCksIAogICAgICAgICAgICB0eXBlX3Blcl92b2ljZSA9IG5fZGlzdGluY3QobHUpKSAlPiUgCiAgYXJyYW5nZShzdWJtYXBwaW5ncywgZGVzYyhuKSkgJT4lIAogIGdyb3VwX2J5KHN1Ym1hcHBpbmdzKSAlPiUgCiAgbXV0YXRlKHBlcmNfdm9pY2VfYnlfc3VibWV0ID0gcm91bmQobi9zdW0obikgKiAxMDAsIDIpLCAKICAgICAgICAgcGVyY190eXBlID0gcm91bmQodHlwZV9wZXJfdm9pY2Uvc3VtKHR5cGVfcGVyX3ZvaWNlKSAqIDEwMCwgMikpCgp2b2ljZV9kZXN0aW5hdGlvbl9tYXggPC0gdm9pY2VfZGVzdGluYXRpb24gJT4lIAogIGZpbHRlcihuID09IG1heChuKSkgJT4lIAogIHVuZ3JvdXAoKQoKdm9pY2VfZGVzdGluYXRpb25fc3VtbWFyeSA8LSB2b2ljZV9kZXN0aW5hdGlvbiAlPiUgCiAgZ3JvdXBfYnkodm9pY2VfdmVyYmFsX2x1KSAlPiUgCiAgc3VtbWFyaXNlKG4gPSBzdW0obiksIHR5cGVfcGVyX3ZvaWNlID0gc3VtKHR5cGVfcGVyX3ZvaWNlKSkgJT4lIAogIG11dGF0ZShwZXJjID0gcm91bmQobi9zdW0obikgKiAxMDAsIDIpLAogICAgICAgICBwZXJjX3R5cGVfcGVyX3ZvaWNlID0gcm91bmQodHlwZV9wZXJfdm9pY2Uvc3VtKHR5cGVfcGVyX3ZvaWNlKSAqIDEwMCwgMikpICU+JSAKICBhcnJhbmdlKGRlc2MocGVyYykpCmBgYAoKSW4gYHIgc2VjdGlvbmBbXEByZWYocG9zc2Vzc2lvbildKCNwb3NzZXNzaW9uKSwgYHIgc2NhcHMoImhhcHBpbmVzcyIpYCBpcyB1bmRlcnN0b29kIGFzIGFuIG9iamVjdCBjYXVzZWQgdG8gbW92ZSB0byB0aGUgR29hbCwgbmFtZWx5IHRoZSBjYW5kaWRhdGUgRXhwZXJpZW5jZXIsIHZpYSB2YXJpb3VzIGtpbmRzIG9mIHRyYW5zZmVycmluZyBzY2VuZXMuIEluIHRoaXMgc2Vuc2UsIHRoZSBjYW5kaWRhdGUgRXhwZXJpZW5jZXIgdGFrZXMgYSByYXRoZXIgcGFzc2l2ZSByb2xlIGluIGFjcXVpcmluZyB0aGUgcG9zc2Vzc2lvbi4gSW4gY29udHJhc3QsIGByIHNjYXBzKHRvbG93ZXIoIkhBUFBJTkVTUyBJUyBBIERFU0lSRUQgR09BTCIpKWAgY29uc3RydWVzIGByIHNjYXBzKCJoYXBwaW5lc3MiKWAgYXMgYSBsb2NhdGlvbiBvciBvYmplY3QgdG93YXJkcyB3aGljaCB0aGUgY2FuZGlkYXRlIEV4cGVyaWVuY2VyIG1vdmVzLCByZWZsZWN0aW5nIHRoZSBgciBzY2FwcygicXVlc3QiKWAgbWV0YXBob3JzIGZhbWlseSBwcm9wb3NlZCBieSBTdGVmYW5vd2l0c2NoIFstQHN0ZWZhbm93aXRzY2hfaGFwcGluZXNzXzIwMDRdIFtjZi4gQGxha29mZl9waGlsb3NvcGh5XzE5OTksIHBwLiAxOTYtMTk3XS4KCmByIHNjYXBzKCJIYXBwaW5lc3MgaXMgYSBkZXNpcmVkIGdvYWwiKWAgY29uc2lzdHMgb2Ygc3VibWFwcGluZ3MgYnVpbHQgdXBvbiBzdHJ1Y3R1cmVzIG9mIHRoZSBgciBzY2Fwcygic2VsZi1wcm9wZWxsZWQgbW90aW9uIHRvIGEgZGVzdGluYXRpb24iKWAgZnJhbWUgW2NmLiBAbGFrb2ZmX3BoaWxvc29waHlfMTk5OSwgcHAuIDE5MC0xOTFdLiBUaGUgc3VibWFwcGluZ3MgcHJvdmlkZSByaWNoIGluZmVyZW5jZXMgY29uY2VybmluZyAoaSkgYHIgc2NhcHMoImhhcHBpbmVzcyIpYCBhcyBhbiBhc3BpcmF0aW9uIChlLmcuIGEgZGVzaXJlZCBvYmplY3Qgb3IgbG9jYXRpb24pLCAoaWkpIHByb2Nlc3MgYW5kIG1lYW5zIHRvIGFjaGlldmUgdGhlIGFzcGlyYXRpb24sIGFzIHdlbGwgYXMgKGlpaSkgaG93IHRoZSBwcm9jZXNzIG1heSBiZSBoYWx0ZWQuIENpdGF0aW9ucyAoQHR1anVhbikgdG8gKEBiZXJ1anVuZykgaWxsdXN0cmF0ZSB0aGUgbWFwcGluZyBvZiBgciBzY2FwcygiaGFwcGluZXNzIilgIG9udG8gdGhlIEdvYWwgcm9sZS4gVGhlIG1ldGFwaG9yaWNhbCBleHByZXNzaW9ucyBhcmUgYmFzZWQgb24gbGV4aWNhbCB1bml0cyAoTFVzKSB0aGF0IGV2b2tlIHRoZSBzY2hlbWF0aWMgaW1hZ2Ugb2YgdGhlIDxzcGFuIGByIHNjYXBzKCJzb3VyY2UtcGF0aC1nb2FsIilgIChTUEcpIGZyYW1lLgoKKEB0dWp1YW4pIGV4YW1wbGUgZm9yIF90dWp1YW5fIChpbmRfbmV3c2NyYXdsMjAxMl8xTToxOTI3NzcpCihAYmVybXVhcmEpIGV4YW1wbGUgZm9yIF9iZXJtdWFyYSBrZSB1anVuZ18gKGluZF9uZXdzY3Jhd2wyMDExXzFNOjY2NzYyNykKKEBiZXJ1anVuZykgZXhhbXBsZSBmb3IgX2JlcnVqdW5nIHBhZGFfIChpbmRfbmV3c2NyYXdsMjAxMl8xTTo1MzYyNTEpCgpUaGUgU1BHIGZyYW1lIGRlc2NyaWJlcyBhIHNlcmllcyBvZiBsb2NhdGlvbmFsIHJvbGVzLCBuYW1lbHkgU291cmNlLCBQYXRoLCBhbmQgR29hbCwgYWxvbmcgd2hpY2ggYW4gZW50aXR5LCBjYWxsZWQgVHJhamVjdG9yLCBtb3Zlcywgb3IgaXMgY29uY2VpdmVkIGFzIG1vdmluZ15bU2VlICpNZXRhTmV0KiAoTU4pIGFuZCAqRnJhbWVOZXQqJ3MgKEZOKSBkZWZpbml0aW9uIG9mIGByIHNjYXBzKCdzb3VyY2UtcGF0aC1nb2FsJylgIGZyYW1lIGluIHRoZWlyIHJlc3BlY3RpdmUgZnJhbWUgcmVwb3NpdG9yeS5dLiBXaGVuIHRoZSBmcmFtZSBpcyB1c2VkIGZvciBkZXNpZ25hdGluZyBgciBzY2FwcygiaGFwcGluZXNzIGlzIGEgZGVzaXJlZCBnb2FsIilgIG1ldGFwaG9yLCBgciBzY2FwcygiaGFwcGluZXNzIilgIGlzIG1hcHBlZCBvbnRvIHRoZSBHb2FsIHJvbGUuIFRoYXQgaXMsIGByIHNjYXBzKCJoYXBwaW5lc3MiKWAgaXMgdW5kZXJzdG9vZCBhcyB0aGUgR29hbC1lbmQgb2YgYSBQYXRoLCB0b3dhcmRzIHdoaWNoIHRoZSBUcmFqZWN0b3IgbWF5IG1vdmUgYWxvbmcgZnJvbSBhIFNvdXJjZS4KCkNvbmNlcm5pbmcgdGhlIGNvbmNlcHR1YWxpc2F0aW9ucyBvZiB0aGUgYXR0ZW1wdCBmb3IgYWNoaWV2aW5nIGByIHNjYXBzKCJoYXBwaW5lc3MiKWAsIHRoZXJlIGFyZSBzZXZlcmFsIHJlbGV2YW50IGZyYW1lcy4gVHdvIG9mIHRoZXNlIGZyYW1lcyBpbmRpY2F0ZSB0aGUgbWVhbnMgdGhhdCBhcmUgcmVxdWlyZWQgYnkgdGhlIE1vdmVyIGluIGgoaXMvZXIpIGF0dGVtcHQgdG8gcmVhY2ggdGhlIEdvYWw7IHRoZXNlIGZyYW1lcyBhcmUgdGhlIGByIHNjYXBzKCJhY2Nlc3MgdG8gYSBsb2NhdGlvbiIpYCAoYXMgaW4gKEBrdW5jaSkgdG8gKEB0aWtldCkpIGFuZCBgciBzY2FwcygiZ3VpZGVkIG1vdGlvbiIpYCBmcmFtZXMgKGFzIGluIChAZ3VpZGUpIGFuZCAoQGd1aWRlMSkpLiBXaGVuIG1hcHBlZCBvbnRvIHRoZSB0YXJnZXQgZnJhbWUsIHRoZSBpbmZlcmVuY2UgZnJvbSB0aGVzZSB0d28gZnJhbWVzIGluZGljYXRlcyB0aGF0IGByIHNjYXBzKCdoYXBwaW5lc3MnKWAgY2Fubm90IGJlIGRpcmVjdGx5IGFjaGlldmVkIHdpdGhvdXQgY2VydGFpbiBtZWFucywgc3VjaCBhcyBhY2Nlc3Mgb3IgZ3VpZGFuY2UuCgooQGt1bmNpKSBleGFtcGxlIGZvciBfa3VuY2lfIChpbmRfbWl4ZWQyMDEyXzFNOjQyNDU4OSkKKEBwaW50dSkgZXhhbXBsZSBmb3IgX3BpbnR1XyAoaW5kX3dlYjIwMTFfMzAwSzoxMDgzMzkpCihAdGlrZXQpIGV4YW1wbGUgZm9yIF90aWNrZXRfIChpbmRfbWl4ZWQyMDEyXzFNOjM5NzMyMCkKKEBndWlkZSkgZXhhbXBsZSBmb3IgYHIgc2NhcHMoImd1aWRlZCBtb3Rpb24iKWAgZnJhbWUgd2l0aCBfbWVuZ2FudGFya2FuXyAoaW5kX3dlYjIwMTJfMU06MzU4MjA0KQooQGd1aWRlMSkgZXhhbXBsZSBmb3IgYHIgc2NhcHMoImd1aWRlZCBtb3Rpb24iKWAgZnJhbWUgd2l0aCBfbWVtaW1waW4ga2UgamFsYW5fIChpbmRfbmV3c2NyYXdsMjAxMl8xTTo4NzIzMTIpCgpOZXh0LCB0aGUgYXR0ZW1wdCBieSB0aGUgY2FuZGlkYXRlIEV4cGVyaWVuY2VyIHRvIGFjaGlldmUgYHIgc2NhcHMoImhhcHBpbmVzcyIpYCBpcyBjb25jZXB0dWFsaXNlZCB2aWEgYHIgc2NhcHMoInB1cnBvc2VmdWwgYWN0aW9uIGlzIHNlbGYtcHJvcGVsbGVkIG1vdGlvbiB0byBhIGRlc3RpbmF0aW9uIilgIG1ldGFwaG9yLCBiYXNlZCBvbiB0aGUgYHIgc2NhcHMoJ3NlbGYtcHJvcGVsbGVkIG1vdGlvbiB0byBhIGRlc3RpbmF0aW9uJylgIGZyYW1lXltTZWUgaHR0cHM6Ly9tZXRhcGhvci5pY3NpLmJlcmtlbGV5LmVkdS9wdWIvZW4vaW5kZXgucGhwL0ZyYW1lOlNlbGZfcHJvcGVsbGVkX21vdGlvbl90b19hX2Rlc3RpbmF0aW9uIChMYXN0IGFjY2VzczogMTUgQXVndXN0IDIwMTgpLl0uIFRoZSBtZXRhcGhvciBpcyBjb21wb3NlZCBvZiB0d28gbW9yZSBiYXNpYyBtZXRhcGhvcnMuIFRoZSBmaXJzdCBvZiB0aGVzZSBpcyBgciBzY2FwcygiYWN0aW9uIGlzIHNlbGYtcHJvcGVsbGVkIG1vdGlvbiIpYCAoZS5nLiBTaGUgKnNxdWVlemVkIGhlciB3YXkgdG8qIHRoaW5uZXIgdGhpZ2hzXltUYWtlbiBmcm9tIGh0dHBzOi8vbWV0YXBob3IuaWNzaS5iZXJrZWxleS5lZHUvcHViL2VuL2luZGV4LnBocC9NZXRhcGhvcjpBQ1RJT05fSVNfU0VMRi1QUk9QRUxMRURfTU9USU9OX0FMT05HX0FfUEFUSCAoTGFzdCBhY2Nlc3M6IDE1IEF1Z3VzdCAyMDE4KS5dKSwgd2hpY2ggaXMgZ3JvdW5kZWQgb24gdGhlIGNvcnJlbGF0aW9uIG9mIGRvaW5nIGFjdGlvbnMgYW5kIG1vdmluZy4gVGhlIG1ldGFwaG9yIGFsc28gaW5kaWNhdGVzIHRoYXQgdGhlIE1vdmVyIGhhcyBoaXMvaGVyIG93biBjb250cm9sIG92ZXIgdGhlIGRpcmVjdGlvbiBvZiBpdHMgYWN0aW9uL21vdGlvbjsgeWV0LCBhcyBjYW4gYmUgc2VlbiBmcm9tIGV4YW1wbGVzIChAZ3VpZGUpIGFuZCAoQGd1aWRlMSkgYWJvdmUsIHRoZSBtb3ZlbWVudCBjYW4gYWxzbyBiZSB0YWtlbiBvdmVyLCBvciBndWlkZWQsIGJ5IGEgY28tTW92ZXIuIFRoZSBzZWNvbmQgY29uc3RpdHV0aW5nIG1ldGFwaG9yIGlzIGByIHNjYXBzKCJwdXJwb3NlcyBhcmUgZGVzdGluYXRpb24iKWAgKGUuZy4gV2UgaGF2ZSAqdGFrZW4gdGhlIGZpcnN0IHN0ZXAqKSwgd2hpY2ggaXMgZ3JvdW5kZWQgb24gdGhlIGNvcnJlbGF0aW9uIG9mIHJlYWNoaW5nIGEgZGVzdGluYXRpb24gd2l0aCBhY2hpZXZpbmcgYSBwdXJwb3NlIChlLmcuIGdvaW5nIHRvIGEgY2FmZSBmb3IgYSBjb2ZmZWUpIFtAbGFrb2ZmX3BoaWxvc29waHlfMTk5OSwgcHAuIDUyLTUzLCAxODctMTkxXS4KCgpJbiB0aGUgYHIgc2NhcHMoJ3NlbGYtcHJvcGVsbGVkIG1vdGlvbiB0byBhIGRlc3RpbmF0aW9uJylgIGZyYW1lLCB0aGUgR29hbCByb2xlIGlzIHByb2ZpbGVkIGFzIGEgZGVzaXJhYmxlIGdvYWwsIHdoaWNoIGlzIG5vdCBpbmZlcnJlZCBmcm9tIGl0cyBwYXJlbnQgZnJhbWUsIG5hbWVseSBgciBzY2FwcygibW90aW9uIHRvIGEgbG9jYXRpb24iKWA7IHRoaXMgcGFyZW50IGZyYW1lIHByb2ZpbGVzIG9ubHkgdGhlIGdvYWwtb3JpZW50ZWQgbW90aW9uLiBUaGUgbWV0YXBob3IgYmFzZWQgb24gYHIgc2NhcHMoJ3NlbGYtcHJvcGVsbGVkIG1vdGlvbiB0byBhIGRlc3RpbmF0aW9uJylgIGZyYW1lIHN1Z2dlc3RzIHRoYXQgYmVjb21pbmcgaGFwcHkgY29uc3RpdHV0ZXMgYSBwdXJwb3NlZnVsIGF0dGVtcHQgZHVlIHRvIHRoZSBkZXNpcmFiaWxpdHkgb2YgdGhlIEdvYWwgKGNmLiAoQG1vdGlvbnRvbG9jYXRpb24pIGFuZCAoQGtlbWJhbGkpKS4gTW9yZW92ZXIsIHRoZSBwZXJzb24gYWltaW5nIHRvIGJlIGhhcHB5IG5lZWRzIHRvIHRha2UgY2VydGFpbiBhY3Rpb24sIGhlbmNlIG1vdmVtZW50LCB0byByZWFsaXNlIHRoaXMgcHVycG9zZS4gSW5kb25lc2lhbiB2b2ljZSBtb3JwaG9sb2d5IGNhbiBjb250cmlidXRlIHRvIHRoZSBhZ2VudGl2ZSBjb25zdHJ1YWwgb2YgdGhlIGNhbmRpZGF0ZSBFeHBlcmllbmNlciBpbiB0aGUgbWV0YXBob3IuIEFnZW50aXZpdHkgY2FuIGJlIGluZmVycmVkIGZyb20gdGhlIHZlcmJhbCBMVXMgb2YgdGhlIG1ldGFwaG9yIHRoYXQgbW9zdCBmcmVxdWVudGx5IG9jY3VyIGluIGFjdGl2ZSB2b2ljZSBjb25zdHJ1Y3Rpb24gdGhhdCwgaW4gSW5kb25lc2lhbiwgY2FuIGJlIG1hcmtlZCBieSBwcmVmaXggKm1lTi0qIChgciBkcGx5cjo6ZmlsdGVyKHZvaWNlX2Rlc3RpbmF0aW9uX3N1bW1hcnksIHN0cl9kZXRlY3Qodm9pY2VfdmVyYmFsX2x1LCAnXmFjdGl2ZScpKSRwZXJjYCUgb2YgdGhlIHRvdGFsIGByIHN1bSh2b2ljZV9kZXN0aW5hdGlvbl9zdW1tYXJ5JG4pYCB0b2tlbnMgb2YgdGhlIHZlcmJhbCBMVXMgZm9yIHRoZSBtZXRhcGhvcikgKHNlZSwgZm9yIGluc3RhbmNlLCAoQG1vdGlvbnRvbG9jYXRpb24pLCAoQHNlYXJjaCksIGFuZCAoQGNoYXNlKSkuCgooQG1vdGlvbnRvbG9jYXRpb24pIGV4YW1wbGUgd2l0aCBtb3Rpb24gdG8gYSBkZXN0aW5hdGlvbiB3aXRoICptZW51anUqIChpbmRfd2ViMjAxMl8xTTozOTg0MDApCihAa2VtYmFsaSkgZXhhbXBsZSB3aXRoICprZW1iYWxpIGtlKiAoaW5kX25ld3NjcmF3bDIwMTFfMU06NDUxMDk5KQoKVGhlIG51bWJlciBvZiB0b2tlbnMgZm9yIHRoZSBgciBzY2Fwcygnc2VsZi1wcm9wZWxsZWQgbW90aW9uIHRvIGEgZGVzdGluYXRpb24nKWAgZnJhbWUgb25seSBhY2NvdW50cyBmb3IgKGByIGRwbHlyOjpmaWx0ZXIoZ29hbF9zdWJtYXBwaW5ncywgZ3JlcGwoInByb2Nlc3MiLCBhc3BlY3QpICYgZ3JlcGwoIm1vdGlvbiIsIHN1Ym1hcHBpbmdzKSlbWzddXWAlKSBvZiB0aGUgdG90YWwgYHIgc3VtKGRwbHlyOjpmaWx0ZXIoZ29hbF9zdWJtYXBwaW5ncywgZ3JlcGwoInByb2Nlc3MiLCBhc3BlY3QpKVtbIm4iXV0pYCB0b2tlbnMgcmVmZXJyaW5nIHRvIHRoZSBhdHRlbXB0IHRvIGJlIGhhcHB5LiBUaGlzIGlzIHByZWRvbWluYW50bHkgZXhwcmVzc2VkIGJ5IHRoZSB2ZXJiICptZW51anUqICd0byBoZWFkIHRvIGEgbG9jYXRpb24nIGFzIGluIChAbW90aW9udG9sb2NhdGlvbikgYWJvdmUuIEEgcHJlZmVyYWJsZSBmcmFtZSBmb3IgY29uY2VwdHVhbGlzaW5nIHRoZSBhdHRlbXB0IGNvbnN0aXR1dGVzIHRoZSBzdWJjYXNlIG9mIHRoZSBgciBzY2Fwcygic2VsZi1wcm9wZWxsZWQgbW90aW9uIHRvIGEgZGVzdGluYXRpb24iKWAsIG5hbWVseSB0aGUgYHIgc2NhcHMoInB1cnN1ZSIpYCBmcmFtZSAoYHIgZHBseXI6OmZpbHRlcihnb2FsX3N1Ym1hcHBpbmdzLCBncmVwbCgicHJvY2VzcyIsIGFzcGVjdCkgJiBncmVwbCgicHVyc3UiLCBzdWJtYXBwaW5ncykpW1s3XV1gJSBvZiB0aGUgdG90YWwgZnJlcXVlbmN5IGZvciBleHByZXNzaW9ucyBldm9raW5nIHRoZSBhdHRlbXB0IGFzcGVjdCkuCgpUaGUgKnN1YmNhc2Ugb2YgcmVsYXRpb24qIGluICpNZXRhTmV0KiAoTU4pIGluZGljYXRlcyB0aGF0IGByIHNjYXBzKCJwdXJzdWUiKWAgZnVsbHkgaW5jb3Jwb3JhdGVzIHRoZSBmcmFtZSBlbGVtZW50cyBhbmQgaW5mZXJlbnRpYWwgc3RydWN0dXJlcyBvZiBpdHMgcGFyZW50IGZyYW1lIChpLmUuIGByIHNjYXBzKCJzZWxmLXByb3BlbGxlZCBtb3Rpb24gdG8gYSBkZXN0aW5hdGlvbiIpYCksIHN1Y2ggYXMgdGhlIGRlc2lyYWJpbGl0eSBvZiB0aGUgR29hbCwgU2VsZi1tb3Rpb25feC1zY2hlbWEvcHJvY2VzcywgYW5kIHRoZSBNb3Zlci4gSW4gYWRkaXRpb24sIGByIHNjYXBzKCJwdXJzdWUiKWAgYXMgdGhlIGNoaWxkIGZyYW1lIG1heSBoYXZlIHNlbWFudGljIHNwZWNpZmljYXRpb24sIG9yIGVsYWJvcmF0aW9uLCBvZiB0aGUgZnJhbWUgcm9sZSBwYXJhbWV0ZXJzLiBIb3dldmVyLCBNTiByZXBvc2l0b3J5IGhhcyBub3QgeWV0IHByb3ZpZGVkIHRoZXNlIGRldGFpbGVkIHNwZWNpZmljYXRpb25zIHRoYXQgbWF5IGRpc3Rpbmd1aXNoIHRoZSBgciBzY2FwcygicHVyc3VlIilgIGZyYW1lIGZyb20gaXRzIHBhcmVudCBmcmFtZS4gUGVyaGFwcywgYHIgc2NhcHMoInB1cnN1ZSIpYCBlbGFib3JhdGVzIHRoZSBzZW1hbnRpY3Mgb2YgdGhlIFNlbGYtbW90aW9uX3gtc2NoZW1hIHdpdGggbW9yZSBzcGVjaWZpYyBtZWFucyBvZiBhY3Rpb24gdW5kZXJ0YWtlbiB0byBhY2hpZXZlIHRoZSBnb2FsLCBzdWNoIGFzIHNlYXJjaGluZyAoQHNlYXJjaCksIGNoYXNpbmcgKEBjaGFzZSksIG9yIGh1bnRpbmcgKEBodW50KS4gTWVhbndoaWxlLCB0aGUgYHIgc2NhcHMoInNlbGYtcHJvcGVsbGVkIG1vdGlvbiB0byBhIGRlc3RpbmF0aW9uIilgIG1heSBvbmx5IHByb2ZpbGUgYSBzZWxmLWluaXRpYXRlZCBtb3Rpb24gb2YgdGhlIE1vdmVyLWFjdG9yIHVudGlsIChzKWhlIHJlYWNoZXMgdGhlIGRlc3RpbmF0aW9uLiBObyBzcGVjaWZpYyBtZWFucyBhcmUgaW1wbGllZCBpbiB0aGlzIGZyYW1lIGZvciBob3cgdGhlIEdvYWwgaXMgcmVhY2hlZF5bTm8gcmVsZXZhbnQgbGV4aWNhbCB1bml0cyBhcmUgZ2l2ZW4gaW4gdGhlIGVudHJ5IG9mIGByIHNjYXBzKCJzZWxmLXByb3BlbGxlZCBtb3Rpb24gdG8gYSBkZXN0aW5hdGlvbiIpYCBmcmFtZS4gU2VlIGh0dHBzOi8vbWV0YXBob3IuaWNzaS5iZXJrZWxleS5lZHUvcHViL2VuL2luZGV4LnBocC9GcmFtZTpTZWxmX3Byb3BlbGxlZF9tb3Rpb25fdG9fYV9kZXN0aW5hdGlvbiAoTGFzdCBhY2Nlc3M6IDkgU2VwdGVtYmVyIDIwMTgpLl0gYW5kIGZvciB3aGV0aGVyIHRoZSBHb2FsIGlzIHN0YXRpYyBvciBtb3ZpbmcuCgooQHNlYXJjaCkgZXhhbXBsZSB3aXRoICptZW5jYXJpKiAoc2VhcmNoaW5nKSAoaW5kX21peGVkMjAxMl8xTTozOTcyMjEpCihAY2hhc2UpIGV4YW1wbGUgd2l0aCAqbWVuZ2VqYXIqIChjaGFzaW5nKSAoaW5kX21peGVkMjAxMl8xTTo1MDQ5MDUpCihAaHVudCkgZXhhbXBsZSB3aXRoICpwZW1idXJ1KiAoaHVudGluZykgKGluZF9uZXdzY3Jhd2wyMDExXzFNOjc5OTI1KQoKVGhlIGxleGljYWwgdW5pdHMgKExVcykgd2l0aGluIGByIHNjYXBzKCJwdXJzdWUiKWAgcmVwcmVzZW50IHRocmVlIGNhdGVnb3JpZXMgb2Ygc2VtYW50aWMgdHlwZS4gVGhleSBhcmUgTFVzIHJlZmVycmluZyB0byBgciBzY2Fwcygic2VhcmNoaW5nIilgIChgciBkcGx5cjo6ZmlsdGVyKHB1cnN1ZV9zZW1hbnRpY3MsIHN0cl9kZXRlY3Qoc2VtYW50aWNzLCAic2VhcmNoaW5nIikpW1sicGVyYyJdXWAlIG9mIHRoZSB0b3RhbCBgciBzdW0ocHVyc3VlX3NlbWFudGljcyRuKWAgdG9rZW5zIG9mIGV4cHJlc3Npb25zIGV2b2tpbmcgYHIgaGFwcHlyOjpzY2FwcygicHVyc3VlIilgKSwgYHIgc2NhcHMoImNoYXNpbmciKWAgKGByIGRwbHlyOjpmaWx0ZXIocHVyc3VlX3NlbWFudGljcywgc3RyX2RldGVjdChzZW1hbnRpY3MsICJjaGFzaW5nIikpW1sicGVyYyJdXWAlKSwgYW5kIGByIHNjYXBzKCJodW50aW5nIilgIChgciBkcGx5cjo6ZmlsdGVyKHB1cnN1ZV9zZW1hbnRpY3MsIHN0cl9kZXRlY3Qoc2VtYW50aWNzLCAiaHVudGluZyIpKVtbInBlcmMiXV1gJSkuIFRoZSBwcmVmZXJlbmNlIGZvciB0aGUgc2VhcmNoaW5nIHByb2Nlc3MgcG9ydHJheXMgYHIgc2NhcHMoImhhcHBpbmVzcyIpYCBhcyBzb21ldGhpbmcgaGlkZGVuIGFuZCByZXF1aXJpbmcgZXhwbG9yYXRpb24gZm9yIGl0cyBhdHRhaW5tZW50LiBJbnR1aXRpdmVseSwgX21lbmdlamFyXyAndG8gY2hhc2U7IHJ1biBhZnRlcicgaW4gZXhhbXBsZSAoQGNoYXNlKSBtYXkgaW52aXRlIGFuIGltYWdlIG9mIChpKSBhIG1vdmluZywgZGVzaXJlZCBHb2FsLCBhbmQgKGlpKSBoYXZpbmcgYW4gaW1tZWRpYXRlIGV4cGVjdGF0aW9uIGJ5IHRoZSBTZWxmLW1vdmVyIHdoZW4gY2hhc2luZyB0aGUgR29hbC4gSW4gdGhlIHRhcmdldCBmcmFtZSwgdGhpcyBpbmZlcmVuY2UgbWFwcyBvbnRvIHRoZSBleGlnZW5jeSBmb3IgZXhwZXJpZW5jaW5nIGByIHNjYXBzKCJoYXBwaW5lc3MiKWAuIEFmdGVyIGFsbCwgZXhhbXBsZXMgKEBzZWFyY2gpIHRvIChAaHVudCkgY2xlYXJseSBzaW5nbGUgb3V0IHRoZSBhY3RpdmUgcm9sZSBvZiB0aGUgU2VsZi1tb3ZlciBpbiBhY2hpZXZpbmcgdGhlIEdvYWwuIEluIHRoZSB0YXJnZXQgZnJhbWUsIHRoaXMgaW5mZXJlbmNlIGNvcnJlc3BvbmRzIHRvIHRoZSBhY3RpdmUgcmVzcG9uc2liaWxpdHkgb2YgdGhlIGNhbmRpZGF0ZSBFeHBlcmllbmNlciBmb3IgaChpcy9lcikgb3duIGByIHNjYXBzKCJoYXBwaW5lc3MiKWAuCgpBIHNtYWxsIG51bWJlciAoaS5lLiBgciBkcGx5cjo6ZmlsdGVyKGdvYWxfYXNwZWN0LCBhc3BlY3QgPT0gIm9ic3RhY2xlIikkcGVyY2AlKSBvZiB0aGUgdG9rZW5zIG9mIHRoZSBgciBzY2FwcygiaGFwcGluZXNzIGlzIGEgZGVzaXJlZCBnb2FsIilgIG1ldGFwaG9yIGV2b2tlIHN1Ym1hcHBpbmcgY29udmV5aW5nIHBvdGVudGlhbCBpbmhpYml0aW9uIG9uIHRoZSBhdHRlbXB0IHRvIGFjaGlldmUgYHIgc2NhcHMoImhhcHBpbmVzcyIpYC4gRXhhbXBsZSAoQHRhaGFuKSBzcGVjaWZpZXMgYSBzZWxmLWludGVybmFsIGluaGliaXRpb24gZm9yIGNlcnRhaW4gcHJvaGliaXRlZCBwbGVhc3VyZS4KCihAdGFoYW4pIGV4YW1wbGUgd2l0aCAqbWVuYWhhbiogZGlyaSAqZGFyaSogYmVyYWdhbSBfX2tlc2VuYW5nYW5fXyAoaW5kX3dlYjIwMTFfMzAwSzoxMTgyOTgpCgpXaXRoaW4gdGhlIGFyYyBvZiB0aGUgYHIgc2NhcHMoImhhcHBpbmVzcyBpcyBhIGRlc2lyZWQgZ29hbCIpYCBtZXRhcGhvciwgdGhlIGFjaGlldmVtZW50IG9mIGByIHNjYXBzKCJoYXBwaW5lc3MiKWAgaXMgY29uY2VwdHVhbGlzZWQgYXMgdGhlIGZpbmFsIHN0YWdlIG9mIHRoZSBtb3Rpb24uIFRoaXMgY291bGQgYmUgcmVhY2hpbmcvYXJyaXZpbmcgKEBjYXBhaSksIGxvY2F0aW5nL2ZpbmRpbmcgKEB0ZW11a2FuKSwgYW5kIGNhcHR1cmluZy9ncmFzcGluZyAoQHJhaWgpIHRoZSBkZXNpcmVkIGdvYWwgW2NmLiBAc3RlZmFub3dpdHNjaF9oYXBwaW5lc3NfMjAwNCwgcHAuIDE0Mi0xNDVdLgoKKEBjYXBhaSkgZXhhbXBsZSB3aXRoICptZW5jYXBhaSogKGluZF9taXhlZDIwMTJfMU06MjYzNTE4KQooQHRlbXVrYW4pIGV4YW1wbGUgd2l0aCAqbWVuZW11a2FuKiAoaW5kX21peGVkMjAxMl8xTTo1NjUxMzUpCihAcmFpaCkgZXhhbXBsZSB3aXRoICptZXJhaWgqIChpbmRfd2ViMjAxMl8xTToxNTIxNTQpCgpBbGwgdGhlIHNvdXJjZSBmcmFtZSBMVXMgY29udmV5aW5nIHRoZSBmaW5hbCBzdGFnZSBvZiB0aGUgbW90aW9uIHByb2Nlc3MgaW5kaWNhdGUgdGhhdCBhIHByaW9yIGVmZm9ydCBpcyByZXF1aXJlZCBieSB0aGUgTW92ZXIgYmVmb3JlIChzKWhlIGNhbiByZWFjaCBvciBjYXB0dXJlIGgoaXMvZXIpIGRlc2lyZWQgR29hbC4gVGhpcyBpbmZlcmVuY2UgbWFwcyBvbnRvIHRoZSBlZmZvcnRzIHJlcXVpcmVkIGZvciBzb21lYm9keSB0byBiZSBoYXBweS4KCmBgYHtyIGRlc2lyZWQtZ29hbC1sdS10YWJsZX0KZ2V0X2x1X3RhYmxlKCJkZXNpcmVkIiwgZGYgPSBoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yKSAlPiUgCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSAnVG9wLTEwIG1vc3QgZnJlcXVlbnQgbGV4aWNhbCB1bml0cyBldm9raW5nIDxzcGFuIHN0eWxlID0gImZvbnQtdmFyaWFudDpzbWFsbC1jYXBzOyI+aGFwcGluZXNzIGlzIGEgZGVzaXJlZCBnb2FsPC9zcGFuPi4nLCByb3cubmFtZXMgPSBUUlVFKQpgYGAKCmByIHNjYXBzKCJIYXBwaW5lc3MgaXMgYSBkZXNpcmVkIGdvYWwiKWAgaGFzIGxpdHRsZSB2YXJpYXRpb24gaW4gaXRzIGxpbmd1aXN0aWMgZXhwcmVzc2lvbnMsIHNob3dpbmcgb25seSBgciBoYXBweXI6OmdldF9tZXRhX2ZyZXFfcHJvZmlsZXMoJ2Rlc2lyZWQnLCB0eXBlX3Blcl90b2tlbl9sdSwgZGYgPSB0dHJfbWV0YXBob3IpW1syXV1gJSB2YXJpYXRpb24gZ2l2ZW4gaXRzIG92ZXJhbGwgdG9rZW4gZnJlcXVlbmN5IChgciBoYXBweXI6OmdldF9tZXRhX2ZyZXFfcHJvZmlsZXMoJ2Rlc2lyZWQnLCB0b2tlbiwgZGYgPSB0dHJfbWV0YXBob3IpW1syXV1gIHRva2VucykuIFRoZSBwZXJjZW50YWdlIG9mIHRoZSBzdWJtYXBwaW5nIGluZGljYXRpbmcgdGhlIGF0dGVtcHQgdG8gYXR0YWluIGByIHNjYXBzKCdoYXBwaW5lc3MnKWAgaXMgb25seSBzbGlnaHRseSBoaWdoZXIgKGByIGRwbHlyOjpmaWx0ZXIoZ29hbF9hc3BlY3QsIGFzcGVjdCA9PSAicHJvY2VzcyIpJHBlcmNgJSkgdGhhbiB0aGUgYXR0YWlubWVudCAoYHIgZHBseXI6OmZpbHRlcihnb2FsX2FzcGVjdCwgYXNwZWN0ID09ICJhdHRhaW5pbmciKSRwZXJjYCUpLiBUaGlzIGRpc3RyaWJ1dGlvbiBzdWdnZXN0cyB0aGF0IHRoZSBwcm9jZXNzIHRvIGFuZCB0aGUgYXR0YWlubWVudCBvZiBgciBzY2FwcygiaGFwcGluZXNzIilgIGFyZSByZWxhdGl2ZWx5IGVxdWFsbHkgaGlnaGxpZ2h0ZWQgaW4gdGhlIHNhbXBsZS4KCi4uLgoKIyMgSGFwcGluZXNzIGlzIGEgbG9jYXRpb24geyNsb2NhdGlvbn0KCmBgYHtyIGxvY2F0aW9uLWRhdGEtZm9yLW1haW50ZXh0fQpsb2NhdGlvbl9zdWJtYXBwaW5ncyA8LSBoYXBweXI6OmdldF9zdWJtYXBwaW5ncygiYSBsb2NhdGlvbiQiLCBkZiA9IGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IpICU+JSAKICBtdXRhdGUoYXNwZWN0ID0gaWZfZWxzZShzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAnbW90aW9uIGludG8nKSwgJ2NoYW5nZSBvZiBzdGF0ZSBpbnRvJywgJ2JlaW5nIGluIGEgc3RhdGUnKSwKICAgICAgICAgYXNwZWN0ID0gaWZfZWxzZShzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAnKG1vdmluZyBhd2F5fGJlaW5nIGZhcikgZnJvbScpLCAnY2hhbmdlIG9mIHN0YXRlIG91dCcsIGFzcGVjdCksCiAgICAgICAgIGFzcGVjdCA9IGlmX2Vsc2Uoc3RyX2RldGVjdChzdWJtYXBwaW5ncywgJ2NhdXNlZCcpLCAnY2F1c2VkIGNoYW5nZSBvZiBzdGF0ZSB0bycsIGFzcGVjdCksCiAgICAgICAgIGFzcGVjdCA9IGlmX2Vsc2Uoc3RyX2RldGVjdChzdWJtYXBwaW5ncywgJ2lzIGEgKGxhbmRtYXJrfGJvdW5kZWQgZW50aXR5fGdlb2dyYXBoaWN8c291cmNlIG9mIGEgcGF0aHxsb2NhdGlvbiQpJyksICdsb2NhdGlvbiBzdGF0ZScsIGFzcGVjdCkpCgojIGdldCB0aGUgTFUgdGFibGUKbG9jYXRpb25fbHUgPC0gaGFwcHlyOjpnZXRfbHVfdGFibGUoImlzIGEgbG9jYXRpb24kIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9wX25fb25seSA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRmID0gaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvcikKYGBgCgpgciBzY2FwcygiSGFwcGluZXNzIGlzIGEgbG9jYXRpb24iKWAgaXMgYSBzdWJjYXNlIG9mIG9uZSBvZiB0aGUgY2VudHJhbCBtZXRhcGhvcnMgaW4gdGhlICpMb2NhdGlvbiBFdmVudCBTdHJ1Y3R1cmUgTWV0YXBob3IqIChMRVNNKSBzeXN0ZW0sIGkuZS4gYHIgc2NhcHMoInN0YXRlcyBhcmUgbG9jYXRpb24iKWAgW0BsYWtvZmZfcGhpbG9zb3BoeV8xOTk5LCBwcC4gMTc5LTE4MF0uIFRoZSBtZXRhcGhvciBpcyBjZW50cmVkIGFyb3VuZCB0aGUgYHIgc2NhcHMoJ2xvY2F0aW9uJylgLXJlbGF0ZWQgZnJhbWVzLCBzdWNoIGFzIHRoZSBgciBzY2FwcygiYmVpbmcgYXQgYSBsb2NhdGlvbiIpYCBmcmFtZS4gVGhpcyBmcmFtZSBzY2hlbWF0aWNhbGx5IGRlc2NyaWJlcyBhIHNjZW5lIHdoZXJlIGEgdHJhamVjdG9yIChpLmUuIHRoZSBMb2NhdGVkX3RoaW5nIHJvbGUpIG9jY3VwaWVzIGEgbG9jYXRpb24gKGkuZS4gdGhlIEN1cnJlbnRfbG9jYXRpb24gcm9sZSkuIFRoZSB1c2Ugb2YgdGhlIGZyYW1lIGluIGByIHNjYXBzKCJoYXBwaW5lc3MgaXMgYSBsb2NhdGlvbiIpYCBzZWVzIHRoZSByb2xlLW1hcHBpbmdzIG9mIChpKSB0aGUgdGFyZ2V0IGZyYW1lIGByIHNjYXBzKCdoYXBwaW5lc3MnKWAgb250byB0aGUgQ3VycmVudF9sb2NhdGlvbiByb2xlIG9mIHRoZSBzb3VyY2UgZnJhbWUgYW5kIChpaSkgdGhlIGNhbmRpZGF0ZSBFeHBlcmllbmNlciBvbnRvIHRoZSBMb2NhdGVkX3RoaW5nIHJvbGUuIAoKVGhlIHByaW5jaXBhbCBpbmZlcmVuY2UgaW52aXRlZCBieSBgciBzY2FwcygiaGFwcGluZXNzIGlzIGEgbG9jYXRpb24iKWAgaXMgdGhhdCB0aGUgZXhwZXJpZW5jZSBvZiBgciBzY2FwcygiaGFwcGluZXNzIilgIGlzIGV4cHJlc3NlZCBhcyB0aGUgZXhwZXJpZW5jZXLigJlzIGJlaW5nIGxvY2F0ZWQgYXQgdGhlIGByIHNjYXBzKCJoYXBwaW5lc3MiKWAtbG9jYXRpb24uIFRoZSBleHBlcmllbmNlciBpcyB0aHVzIGRlcGljdGVkIGFzIHRoZSBMb2NhdGVkX3RoaW5nLiBUaGUgbWV0YXBob3IgdGVuZHMgdG8gYmUgZXhwcmVzc2VkIHZpYSBwcmVwb3NpdGlvbmFsIHBocmFzZSB3aG9zZSBub21pbmFsIG9iamVjdCBzbG90IGlzIGZpbGxlZCB3aXRoIHRoZSBgciBzY2FwcygiaGFwcGluZXNzIilgIG5vdW5zLiBUaGlzIG5vbWluYWwgb2JqZWN0IHNsb3QgaXMgbGlua2VkIHRvIHRoZSBDdXJyZW50X2xvY2F0aW9uIHJvbGUuIFRoZSBtb3N0IGZyZXF1ZW50IHByZXBvc2l0aW9uIGlzICpkYWxhbSogJ2luc2lkZScgKGNmLiAoQGRhbGFtKSkuIAoKKEBkYWxhbSkgZXhhbXBsZSB3aXRoICpkYWxhbSogKGluZF9uZXdzY3Jhd2wyMDExXzFNOjUxMjA3MSkKCipEYWxhbSogaW5kaWNhdGVzIHRoYXQgdGhlIEN1cnJlbnRfbG9jYXRpb24gcm9sZSBpcyBhIGJvdW5kZWQgcmVnaW9uIHdpdGggaW50ZXJpb3IgYW5kIGV4dGVyaW9yLiBUaGUgYHIgc2NhcHMoImJvdW5kZWQgcmVnaW9uIilgIGZyYW1lIGV2b2tlcyBhIG1vcmUgc3BlY2lmaWMgaW5mZXJlbmNlIGNvbXBhcmVkIHRvIHRoZSB1bmJvdW5kZWQgbG9jYXRpb24gdmVyc2lvbiAoYXMgaW4gKEBkaSkgYW5kIChAcGFkYSkgYmVsb3cpLiBCZWluZyBoYXBweSBtYXBzIG9udG8gYmVpbmcgaW4gdGhlIGludGVyaW9yIG9mIHRoZSBib3VuZGVkIHJlZ2lvbiwgd2hpbGUgdW5oYXBweSBpcyBtYXBwZWQgb250byB0aGUgZXh0ZXJpb3IuCgooQGRpKSBleGFtcGxlIHdpdGggKmRpIF9fa2VjZXJpYWFuX18qIChLb21wYXMgdmlhIFdlYkNvcnA6NDApCihAcGFkYSkgZXhhbXBsZSB3aXRoICpwYWRhKiBzdWF0dSAqX19rZWdlbWJpcmFhbl9fKiAoaW5kX21peGVkMjAxMl8xTToxOTQ1NTEpCgpUaGUgc2FtZSBpZGVhIGluZGljYXRlZCBpbiAoQGRhbGFtKSB0byAoQHBhZGEpIGNhbiBiZSBleHByZXNzZWQgYnkgdGhlIGNvbGxvY2F0aW9uIG9mIHRoZSBwcmVwb3NpdGlvbnMgd2l0aCBzdGF0aXZlLCBsb2NhdGlvbmFsIHZlcmJzLiBUaGUgdmVyYnMgYWRkIHRlbXBvcmFsIGFzcGVjdCwgaW5kaWNhdGluZyB0aGF0IHRoZSBFeHBlcmllbmNlciBpcyBpbiBhbiBvbmdvaW5nIExvY2F0aW9uLXN0YXRlLiBUaGUgbmF0dXJlIG9mIHRoZSBwcmVwb3NpdGlvbiB3aWxsIHRlbGwgdXMgd2hldGhlciB0aGUgbG9jYXRpb24gaXMgYSBib3VuZGVkIHJlZ2lvbiAoYXMgaW4gKEBiZXJhZGFkYWxhbSkgdG8gKEBiZXJ0ZWR1aGRhbGFtKSkgb3IgdW5kZXJzcGVjaWZpZWQgZm9yIGl0cyBpbnRlcmlvci1leHRlcmlvcml0eSAoYXMgaW4gKEBiZXJhZGFwYWRhKSkuIFRoZSBzdWJtYXBwaW5nIG9mIGByIHNjYXBzKCJiZWluZyBoYXBweSBhcyBiZWluZyBhdCBhIGxvY2F0aW9uIilgIGV4ZW1wbGlmaWVkIGluIChAZGFsYW0pLShAYmVyYWRhcGFkYSkgdGFrZXMgdXAgdGhlIG1ham9yaXR5IG9mIHRoZSBtZXRhcGhvcidzIHRva2VuIChgciBzdW0oZmlsdGVyKGxvY2F0aW9uX3N1Ym1hcHBpbmdzLCBzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAiYmVpbmcgKGlufGF0KSIpKVtbInBlcmMiXV0pYCUgb3V0IG9mIGByIHN1bShsb2NhdGlvbl9zdWJtYXBwaW5ncyRuKWAgdG9rZW5zIG9mIGByIHNjYXBzKCJoYXBwaW5lc3MgaXMgYSBsb2NhdGlvbiIpYCkuIAoKKEBiZXJhZGFkYWxhbSkgZXhhbXBsZSB3aXRoIF9iZXJhZGEgZGFsYW1fIE5QIChJV2FDIHZpYSBTa2V0Y2ggRW5naW5lOklENzc3MjUpCihAYmVydGVkdWhkYWxhbSkgZXhhbXBsZSB3aXRoIF9iZXJ0ZWR1aCBkYWxhbV8gTlAgKEFudGFyYSBOZXdzIHZpYSBXZWJDb3JwOjExKQooQGJlcmFkYXBhZGEpIGV4YW1wbGUgd2l0aCBfYmVyYWRhIHBhZGFfIE5QIChpbmRfd2ViMjAxMl8xTTo2NDI1ODEpCgpXaGlsZSBiZWluZyBoYXBweSBpcyBjb25jZXB0dWFsaXNlZCBhcyBiZWluZyBhdCBhIGxvY2F0aW9uLCBiZWluZyB1bmhhcHB5IGlzIGNvbmNlcHR1YWxpc2VkIGFzIGJlaW5nIGF3YXkgZnJvbSB0aGUgYHIgc2NhcHMoImhhcHBpbmVzcyIpYD4tbG9jYXRpb24gKGByIGZpbHRlcihsb2NhdGlvbl9zdWJtYXBwaW5ncywgc3RyX2RldGVjdChzdWJtYXBwaW5ncywgImJlaW5nIGZhciBmcm9tIikpW1sicGVyYyJdXWAlIG9mIHRoZSBtZXRhcGhvcidzIHRva2VuKSAoQGphdWhkYXJpKQoKKEBqYXVoZGFyaSkgZXhhbXBsZSB3aXRoIF9qYXVoIGRhcmlfIChpbmRfbmV3c2NyYXdsMjAxMl8xTToyNjg1NSkKCk90aGVyIHN1Ym1hcHBpbmdzIGJ1aWx0IGFyb3VuZCBgciBzY2FwcygiaGFwcGluZXNzIGlzIGEgbG9jYXRpb24iKWAgYXJlIHJlbGF0ZWQgdG8gdGhlIGNoYW5nZSBvZiBsb2NhdGlvbiBhcyBleHByZXNzZWQgdmlhIG1vdGlvbiB2ZXJicyBbY2YuIEBkb2RnZV9kZWVwXzIwMTYsIHBwLiAyNzQtMjc1XS4gSW4gdGhlIGByIHNjYXBzKCdtb3Rpb24nKWAtcmVsYXRlZCBzdWJtYXBwaW5ncywgdGhlIEV4cGVyaWVuY2VyIGZpbGxzIHRoZSBNb3ZlciByb2xlIGFuZCB0aGUgYHIgc2NhcHMoImhhcHBpbmVzcyIpYCBub3VucyBmaWxsIHRoZSBMb2NhdGlvbi1yZWxhdGVkIHJvbGUsIG5hbWVseSBTb3VyY2UtbG9jYXRpb24gb3IgR29hbC1sb2NhdGlvbi4gVGhlIE1vdmVyIGNhbiBtb3ZlICooaW4pdG8qICgoQG1hc3Vra2VkYWxhbSkgYW5kIChAdGVyamVydW11cykpIG9yICphd2F5IGZyb20qIHRoZSBMb2NhdGlvbiAoKEB0aW5nZ2Fsa2FuKSB0byAoQGphdWhrYW4pKS4gVGhlc2UgdHdvIGNoYW5nZS1vZi1sb2NhdGlvbiBpbmZlcmVuY2VzIGFyZSBtYXBwZWQgb250byB0aGUgY2hhbmdlLW9mLXN0YXRlIGFzcGVjdCBpbiB0aGUgdGFyZ2V0LCByZXN1bHRpbmcgaW4gdHdvIG90aGVyIHN1Ym1hcHBpbmdzLiBOYW1lbHksIGByIHNjYXBzKCJiZWNvbWluZyBoYXBweSBpcyBtb3Rpb24gdG8gYSBsb2NhdGlvbiIpYCAoYHIgZmlsdGVyKGxvY2F0aW9uX3N1Ym1hcHBpbmdzLCBzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAibW90aW9uIGludG8iKSlbWyJwZXJjIl1dYCUpIGFuZCBgciBzY2FwcygiY2Vhc2luZyBoYXBwaW5lc3MgaXMgbW92aW5nIGF3YXkgZnJvbSB0aGUgbG9jYXRpb24iKWAgKGByIGZpbHRlcihsb2NhdGlvbl9zdWJtYXBwaW5ncywgc3RyX2RldGVjdChzdWJtYXBwaW5ncywgIm1vdmluZyBhd2F5IikpW1sicGVyYyJdXWAlKS4gCgooQHRpbmdnYWxrYW4pIGV4YW1wbGUgd2l0aCBfbWVuaW5nZ2Fsa2FuXyAoaW5kX21peGVkMjAxMl8xTTo5NTAyNzMpCihAaGluZGFyaSkgZXhhbXBsZSB3aXRoIF9tZW5naGluZGFyaV8gKGluZF9uZXdzMjAxMl8zMDBLOjExNjI4MCkKKEBqYXVoaSkgZXhhbXBsZSB3aXRoIF9tZW5qYXVoaV8gKGluZF9taXhlZDIwMTJfMU06MjU5NDYpCihAamF1aGthbikgZXhhbXBsZSB3aXRoIF9tZW5qYXVoa2FuXyAoaW5kX3dlYjIwMTJfMU06ODI1OTk4KQooQG1hc3Vra2VkYWxhbSkgZXhhbXBsZSB3aXRoIF9tYXN1ayBrZSBkYWxhbV8gKGluZF9taXhlZDIwMTJfMU06NjY5NTQ0KQooQHRlcmplcnVtdXMpIGV4YW1wbGUgd2l0aCBfdGVyamVydW11cyBkYWxhbV8gKGluZF9taXhlZDIwMTJfMU06Mjk0NTYwKQoKQW4gaW50ZXJlc3RpbmcgZXhhbXBsZSBpcyB0aGUgdXNlIG9mIHRoZSBkb3dud2FyZCBtb3Rpb24gdmVyYiAqdGVyamVydW11cyogaW4gKEB0ZXJqZXJ1bXVzKS4gVGhlIHVuY29udHJvbGxlZCBmYWxsaW5nIG1vdmVtZW50IGNvbnZleWVkIGJ5ICp0ZXJqZXJ1bXVzKiBzdWdnZXN0cyBzb21lIHNvcnQgb2YgbmVnYXRpdmUgaGFybSBmb3IgdGhlIE1vdmVyIChlLmcuLCBoYXJtZWQgZmFjZSkuIEluIHRoZSB0YXJnZXQgZnJhbWUsIHRoaXMgY29uc3RydWFsIGluZGljYXRlcyB0aGF0IGV4cGVyaWVuY2luZyAqa2VzZW5hbmdhbiogJ3BsZWFzdXJlJyBjYW4gYmUgYSBuZWdhdGl2ZSBvbmUuIFRoaXMgY29uc3RydWFsIGNvdWxkIGJlIG1vdGl2YXRlZCBieSB0aGUgYHIgc2NhcHMoIm5lZ2F0aXZlIHN0YXRlcyBhcmUgbG93IGxvY2F0aW9uIilgIFtAZGFuY3lnaWVyX2NvbXB1dGF0aW9uYWxfMjAxNywgcC4gNTc5XS4KCkFub3RoZXIgc3VibWFwcGluZyBpbmNvcnBvcmF0ZXMgYSBjYXVzYWwgc3RydWN0dXJlIGludG8gdGhlIGByIHNjYXBzKCJtb3Rpb24iKWAgZnJhbWUsIHN1Y2ggdGhhdCB0aGUgbW90aW9uIG9mIHRoZSBNb3ZlciBpcyBjYXVzZWQgYnkgdGhlIEFnZW50IHJvbGUgb2Ygc29tZSBraW5kLiBUaGlzIHNjZW5lIHJlcHJlc2VudHMgdGhlIGByIHNjYXBzKCJjYXVzZWQgY2hhbmdlIG9mIHN0YXRlIGlzIGNhdXNlZCBtb3Rpb24gdG8gYSBsb2NhdGlvbiIpYCBzdWJtYXBwaW5nIChgciBmaWx0ZXIobG9jYXRpb25fc3VibWFwcGluZ3MsIHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICJjYXVzaW5nLio/Y2F1c2VkIG1vdGlvbiB0byIpKVtbInBlcmMiXV1gJSkuIEluIHRoZSB0YXJnZXQgZnJhbWUsIHRoaXMgc3VnZ2VzdHMgdGhhdCB0aGVyZSBpcyBjZXJ0YWluIGNhdXNlIGZvciBzb21lb25lJ3MgYHIgc2NhcHMoImhhcHBpbmVzcyIpYC4gCgouLi4KCltUYWJsZSBcQHJlZih0YWI6bHUtbG9jYXRpb24pXSgjbHUtbG9jYXRpb24pXltUaGUgYHRvcF9uKClgIGZ1bmN0aW9uIG9mIHRoZSAqZHBseXIqIHBhY2thZ2UgaW4gUiB3aWxsIGluY2x1ZGUgbW9yZSByb3dzIGZyb20gdGhlIHNwZWNpZmllZCAnbicgbnVtYmVyIChpLmUuIHRlbikgaWYgdGhlcmUgYXJlIHRpZXMgYW1vbmcgdGhlIGdyb3VwLCBpLmUuIHRoZSBMVXMsIGJhc2VkIG9uIHRoZSB2YXJpYWJsZSB1c2VkIGZvciBvcmRlcmluZywgaS5lLiB0aGVpciB0b2tlbiBmcmVxdWVuY3kuIFRoZXJlZm9yZSwgVGFibGUgW1xAcmVmKHRhYjpsdS1sb2NhdGlvbildKCNsdS1sb2NhdGlvbikgc3BlY2lmaWNhbGx5IGxpc3RzIGByIGxvY2F0aW9uX2x1ICU+JSBkaW0oKSAlPiUgLlsxXSAlPiUgbnVtYmVyczJ3b3Jkc2AgaXRlbXMgd2hlbiB0ZW4gaXMgcmVxdWVzdGVkLl0gc2hvd3MgdGhhdCBgciBsb2NhdGlvbl9sdSAlPiUgZmlsdGVyKHN0cl9kZXRlY3QoTGV4aWNhbF91bml0cywgJ15cXCpkYWxhbScpKSAlPiUgLiRQZXJjX292ZXJhbGxgJSBvZiB0aGUgdG9rZW5zIGZvciBgciBzY2FwcygiaGFwcGluZXMgaXMgYSBsb2NhdGlvbiIpYCBpcyBkdWUgdG8gb25lIExVIHR5cGUsIG5hbWVseSAqZGFsYW0qICdpbnNpZGUgc3RoLicuIFRoaXMgcHJvcG9ydGlvbiBpbmRpY2F0ZXMgdGhhdCB0aGUgbWV0YXBob3IgaXMgZXZva2VkIGJ5IGEgY29udmVudGlvbmFsIGxpbmd1aXN0aWMgZXhwcmVzc2lvbi4gVGhpcyBpcyBmdXJ0aGVyIGNvcnJvYm9yYXRlZCBieSB0aGUgbG93IHBlcmNlbnRhZ2Ugb2YgdmFyaWF0aW9uIGluIHRoZSBtZXRhcGhvcidzIGxpbmd1aXN0aWMgcmVhbGlzYXRpb24gZ2l2ZW4gdGhlIG1ldGFwaG9yJ3MgdG9rZW4gZnJlcXVlbmN5LCB0aGF0IGlzLCBvbmx5IGByIGhhcHB5cjo6Z2V0X21ldGFfZnJlcV9wcm9maWxlcygnaXMgYSBsb2NhdGlvbicsIHR5cGVfcGVyX3Rva2VuX2x1LCBkZiA9IHR0cl9tZXRhcGhvcilbWzJdXWAlIG9mIHRoZSBtZXRhcGhvcidzIG92ZXJhbGwgdG9rZW5zIGFyZSBleHByZXNzZWQgd2l0aCBkaWZmZXJlbnQgTFUgdHlwZXMuCgpgYGB7ciBsb2NhdGlvbi1sdS10YWJsZX0KIyBwcmludCB0aGUgTFUKbG9jYXRpb25fbHUgJT4lCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSAnVG9wLTEwIG1vc3QgZnJlcXVlbnQgbGV4aWNhbCB1bml0cyBldm9raW5nIDxzcGFuIHN0eWxlID0gImZvbnQtdmFyaWFudDpzbWFsbC1jYXBzOyI+aGFwcGluZXNzIGlzIGEgbG9jYXRpb248L3NwYW4+LicsIHJvdy5uYW1lcyA9IFRSVUUpCmBgYAoKSW4gc3VtLCBgciBzY2FwcygiaGFwcGluZXNzIGlzIGEgbG9jYXRpb24iKWAgbWV0YXBob3IgcHJpbmNpcGFsbHkgZm9yZWdyb3VuZHMgdGhlIG5hdHVyZSBvZiBob3cgb25lIGV4cGVyaWVuY2VzIGByIHNjYXBzKCJoYXBwaW5lc3MiKWAuIFRoaXMgaXMgcmVmbGVjdGVkIHRocm91Z2ggdGhlIGhpZ2hlc3QgcHJvcG9ydGlvbiBvZiB0aGUgYHIgc2NhcHMoImJlaW5nIGhhcHB5IGlzIGJlaW5nIGF0IGEgbG9jYXRpb24iKWAgc3VibWFwcGluZyAoYHIgc3VtKGZpbHRlcihsb2NhdGlvbl9zdWJtYXBwaW5ncywgc3RyX2RldGVjdChhc3BlY3QsICJiZWluZyBpbiBhIHN0YXRlIikpW1sicGVyYyJdXSlgJSkuIFRoZSBtZXRhcGhvciBhbHNvIGhpZ2hsaWdodHMgdGhlIGNoYW5nZSBvZiBzdGF0ZSAqYXdheSBmcm9tKiBvciAqaW50byogYHIgc2NhcHMoImhhcHBpbmVzcyIpYDsgdGhlIGZvcm1lciBoYXMgaGlnaGVyIHByb3BvcnRpb24gdGhhbiB0aGUgbGF0dGVyIChgciBzdW0oZmlsdGVyKGxvY2F0aW9uX3N1Ym1hcHBpbmdzLCBzdHJfZGV0ZWN0KGFzcGVjdCwgInN0YXRlIG91dCIpKVtbInBlcmMiXV0pYCUgdnMuIGByIHN1bShmaWx0ZXIobG9jYXRpb25fc3VibWFwcGluZ3MsIHN0cl9kZXRlY3QoYXNwZWN0LCAic3RhdGUgKGluKT90byIpKVtbInBlcmMiXV0pYCUpLgoKLi4uCgojIyBIYXBwaW5lc3MgaXMgYSBsb2NhdGVkIG9iamVjdCB7I2xvY2F0ZWRvYmplY3R9CgpgYGB7ciBsb2NhdGVkLW9iamVjdC1kYXRhLWZvci1tYWludGV4dH0KIyBzdWJtYXBwaW5ncwpsb2NhdGVkX3N1Ym1hcHBpbmdzIDwtIGhhcHB5cjo6Z2V0X3N1Ym1hcHBpbmdzKCJsb2NhdGVkIG9iamVjdCQiLCBkZiA9IGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IpCgojIGxleGljYWwgdW5pdCB0YWJsZQpsb2NhdGVkX2x1IDwtIGhhcHB5cjo6Z2V0X2x1X3RhYmxlKCJsb2NhdGVkIG9iamVjdCQiLCBkZiA9IGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IpCgojIHByaW50IHRoZSBsdQpsb2NhdGVkX2x1ICU+JQogIGtuaXRyOjprYWJsZShjYXB0aW9uID0gJ1RvcC0xMCBtb3N0IGZyZXF1ZW50IGxleGljYWwgdW5pdHMgZXZva2luZyA8c3BhbiBzdHlsZSA9ICJmb250LXZhcmlhbnQ6c21hbGwtY2FwczsiPmhhcHBpbmVzcyBpcyBhIGxvY2F0ZWQgb2JqZWN0PC9zcGFuPi4nLCByb3cubmFtZXMgPSBUUlVFKQpgYGAKClRoZSBmaXJzdCBvbmUgaXMgdGhlIGByIHNjYXBzKCJleGlzdGVuY2Ugb2YgaGFwcGluZXNzIGlzIHByZXNlbmNlIG9mIGFuIG9iamVjdCBhdCBhIGxvY2F0aW9uIilgLCBhY2NvdW50aW5nIGZvciBgciBsb2NhdGVkX3N1Ym1hcHBpbmdzICU+JSBmaWx0ZXIoc3RyX2RldGVjdChzdWJtYXBwaW5ncywgJ15leGlzLio/cHJlc2VuY2UnKSkgJT4lIC4kcGVyY2AlIG9mIHRoZSB0b3RhbCB0b2tlbnMgb2YgdGhlIG1ldGFwaG9yLgoKLi4uCgpUaGUgZmlyc3Qgc3VibWFwcGluZyBlbnRhaWxzIHRoZSBzZWNvbmQgb25lLCBpLmUuIGByIHNjYXBzKCJpbmV4aXN0ZW5jZSBvZiBoYXBwaW5lc3MgaXMgYWJzZW5jZSBvZiBhbiBvYmplY3QgYXQgYSBsb2NhdGlvbiIpYCwgcmVwcmVzZW50aW5nIGByIGxvY2F0ZWRfc3VibWFwcGluZ3MgJT4lIGZpbHRlcihzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAnYWJzZW5jZScpKSAlPiUgLiRwZXJjYCUgb2YgdGhlIHRvdGFsIHRva2VucwoKLi4uCgpUaGUgc2Vjb25kIHN1Ym1hcHBpbmcgaGFzIGl0cyBjYXVzYXRpdmUgdmFyaWFudCwgbmFtZWx5IGByIHNjYXBzKCJjYXVzaW5nIGhhcHBpbmVzcyB0byBjZWFzZSBpcyBjYXVzaW5nIGFuIG9iamVjdCB0byBiZSBhYnNlbnQiKWAgKGByIGxvY2F0ZWRfc3VibWFwcGluZ3MgJT4lIGZpbHRlcihzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAndmFuaXNoaW5nJykpICU+JSAuJHBlcmNgJSkuIFRoaXMgdGhpcmQgc3VibWFwcGluZyBpbnRyb2R1Y2VzIHRoZSBBZ2VudGl2ZSByb2xlIHRvIHRoZSBzY2VuZSB2aWEgdHJhbnNpdGl2aXNpbmcgdGhlIExVLCBzdWNoIGFzICpoaWxhbmcqICdiZSBnb25lJywgdXNpbmcgY2F1c2F0aXZlIHN1ZmZpeCAtKmthbiosIGludG8gKmhpbGFuZy1rYW4qICdjYXVzZSBzdGguIHRvIGJlIGdvbmUnLgoKLi4uCgpEZXNwaXRlIGl0cyBoaWdoIHRva2VuIGZyZXF1ZW5jeSwgdGhlIDxzcGFuIHN0eWxlPSJmb250LXZhcmlhbnQ6c21hbGwtY2FwczsiPmxvY2F0ZWQgb2JqZWN0PC9zcGFuPiBtZXRhcGhvciBpcyBsZXNzIGRpdmVyc2UgaW4gaXRzIGxpbmd1aXN0aWMgbWFuaWZlc3RhdGlvbiBkdWUgdG8gbmVhcmx5IGhhbGYgb2YgaXRzIHRvdGFsIHRva2VucyAoYHIgZmlsdGVyKGxvY2F0ZWRfbHUsIFBlcmNfb3ZlcmFsbCA9PSBtYXgoUGVyY19vdmVyYWxsKSlbWyJQZXJjX292ZXJhbGwiXV1gJSkgYmVpbmcgZXZva2VkIGJ5ICphZGEgKGRpL3BhZGEgWCkqIChjZi4gW1RhYmxlIFxAcmVmKHRhYjpsdS1sb2NhdGVkLW9iamVjdCldKCNsdS1sb2NhdGVkLW9iamVjdCkpLiBUaGF0IGlzLCB0aGUgbWV0YXBob3IncyBmcmVxdWVudCBvY2N1cnJlbmNlIGlzIGNvbXBvc2VkIG9mIGEgcHJvcG9ydGlvbmFsbHkgbGltaXRlZCB0eXBlIG9mIExVcyB0aGF0IGFyZSBmcmVxdWVudGx5IHJlcGVhdGVkLCByYXRoZXIgdGhhbiBvZiBhIHByb3BvcnRpb25hbGx5IGhldGVyb2dlbmVvdXMgc2V0IG9mIExVcyBbQGdvbGFfdGFzdGVfMjAxNiwgcC4gNTNdLiBPdmVyYWxsLCBvbmx5IGByIGhhcHB5cjo6Z2V0X21ldGFfZnJlcV9wcm9maWxlcyhtZXRhcGhvciA9ICJsb2NhdGVkIG9iamVjdCIsIHR5cGVfcGVyX3Rva2VuX2x1LCBkZiA9IHR0cl9tZXRhcGhvcilbWzJdXWAlIG9mIHRoZSBtZXRhcGhvcidzIHRva2VucyBhcmUgb2YgZGlmZmVyZW50IExVIHR5cGVzOyAgdGhlIHJlc3Qgb2YgdGhlIHRva2VucyBpcyByZXBldGl0aW9uIGZyb20gdGhhdCBwcm9wb3J0aW9uIFtjZi4gQHN0ZWZhbm93aXRzY2hfY29ycHVzXzIwMTcsIHAuIDI4Ml0uCgoKIyMgSGFwcGluZXNzIGlzIGEgY29udGFpbmVkIGVudGl0eQoKYGBge3IgY29udGFpbmVkLWVudGl0eS1kYXRhLWZvci1tYWludGV4dH0KIyBDT05UQUlORUQgRU5USVRZIG1ldGFwaG9yIGRhdGEKIyMgZnJhbWVzCmNvbnRhaW5lZF9lbnRpdHlfZnJhbWVzIDwtIGhhcHB5cjo6Z2V0X2ZyYW1lcyhtZXRhcGhvciA9ICJjb250YWluZWQgZW50aXR5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRmID0gaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvcikgJT4lCiAgZ3JvdXBfYnkoZnJhbWVzKSAlPiUKICBzdW1tYXJpc2UobiA9IHN1bShuKSkgJT4lCiAgbXV0YXRlKHBlcmMgPSByb3VuZChuL3N1bShuKSAqIDEwMCwgMiksCiAgICAgICAgIG1ldGFwaG9ycyA9ICJjb250YWluZWQgZW50aXR5IikgJT4lCiAgYXJyYW5nZShkZXNjKG4pKQoKIyMgc3VibWFwcGluZ3MKY29udGFpbmVkX2VudGl0eV9zdWJtYXBwaW5ncyA8LSBoYXBweXI6OmdldF9zdWJtYXBwaW5ncygiY29udGFpbmVkIGVudGl0eSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGYgPSBoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yKSAlPiUgCiAgbXV0YXRlKGFzcGVjdCA9IGlmX2Vsc2Uoc3RyX2RldGVjdChzdWJtYXBwaW5ncywgImV4cHJlc3Npb24iKSwgImV4cHJlc3Npb24iLCAiY29udGFpbm1lbnQiKSwKICAgICAgICAgYXNwZWN0ID0gaWZfZWxzZShzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAiKGhpZ2ggaW50ZW5zaXR5fGludGVuc2lmaWVkfGludGVuc2UpIiksICJpbmNyZWFzZWQgaW50ZW5zaXR5IiwgYXNwZWN0KSwKICAgICAgICAgYXNwZWN0ID0gaWZfZWxzZShzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAicmVndWxhdGluZyIpLCAicmVndWxhdGlvbiIsIGFzcGVjdCkpCgojIyBhc3BlY3Qgc3VtbWFyaXNlZApjb250YWluZWRfZW50aXR5X2FzcGVjdCA8LSBjb250YWluZWRfZW50aXR5X3N1Ym1hcHBpbmdzICU+JSAKICBncm91cF9ieShhc3BlY3QpICU+JSAKICBzdW1tYXJpc2UobiA9IHN1bShuKSwgCiAgICAgICAgICAgIHR5cGUgPSBzdW0odHlwZSksIAogICAgICAgICAgICBwZXJjID0gc3VtKHBlcmMpLCAKICAgICAgICAgICAgdHlwZV9wZXJjID0gc3VtKHR5cGVfcGVyYykpICU+JQogIGFycmFuZ2UoZGVzYyhuKSkKCiMjIGxleGljYWwgdW5pdCB0YWJsZQpjb250YWluZWRfZW50aXR5X2x1IDwtIGhhcHB5cjo6Z2V0X2x1X3RhYmxlKCJjb250YWluZWQgZW50aXR5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3Bfbl9vbmx5ID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGYgPSBoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yKQoKY29udGFpbmVkX2VudGl0eV9sdSAlPiUKICB0b3BfbigxMCwgTikgJT4lCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSAnVG9wLTEwIG1vc3QgZnJlcXVlbnQgbGV4aWNhbCB1bml0cyBldm9raW5nIDxzcGFuIHN0eWxlID0gImZvbnQtdmFyaWFudDpzbWFsbC1jYXBzOyI+aGFwcGluZXNzIGlzIGEgY29udGFpbmVkIGVudGl0eTwvc3Bhbj4uJywgcm93Lm5hbWVzID0gVFJVRSkKYGBgCgpUaGUgc3VibWFwcGluZ3MgaW4gdGhlIDxzcGFuIHN0eWxlPSJmb250LXZhcmlhbnQ6c21hbGwtY2FwczsiPmNvbnRhaW5lZCBlbnRpdHk8L3NwYW4+IG1ldGFwaG9yIGludm9sdmUgYHIgbnVtYmVyczJ3b3JkcyhkaW0oY29udGFpbmVkX2VudGl0eV9mcmFtZXMpWzFdKWAgc291cmNlIGZyYW1lczogKGkpIDxzcGFuIHN0eWxlPSJmb250LXZhcmlhbnQ6c21hbGwtY2FwczsiPmNvbnRhaW5pbmc8L3NwYW4+IChgciBjb250YWluZWRfZW50aXR5X2ZyYW1lcyAlPiUgZmlsdGVyKHN0cl9kZXRlY3QoZnJhbWVzLCAnY29udGFpbmluZycpKSAlPiUgc2VsZWN0KHBlcmMpICU+JSB1bmxpc3QoKWAlKSwgKGlpKSA8c3BhbiBzdHlsZT0iZm9udC12YXJpYW50OnNtYWxsLWNhcHM7Ij5iZWluZyBpbiBhIGJvdW5kZWQgcmVnaW9uIHJlZ2lvbjwvc3Bhbj4gKGByIGNvbnRhaW5lZF9lbnRpdHlfZnJhbWVzICU+JSBmaWx0ZXIoc3RyX2RldGVjdChmcmFtZXMsICdib3VuZGVkIHJlZ2lvbicpKSAlPiUgc2VsZWN0KHBlcmMpICU+JSB1bmxpc3QoKWAlKSwgKGlpaSkgPHNwYW4gc3R5bGU9ImZvbnQtdmFyaWFudDpzbWFsbC1jYXBzOyI+ZXhwbG9zaW9uPC9zcGFuPiAoYHIgY29udGFpbmVkX2VudGl0eV9mcmFtZXMgJT4lIGZpbHRlcihzdHJfZGV0ZWN0KGZyYW1lcywgJ2V4cGxvc2lvbicpKSAlPiUgc2VsZWN0KHBlcmMpICU+JSB1bmxpc3QoKWAlKSwgKGl2KSA8c3BhbiBzdHlsZT0iZm9udC12YXJpYW50OnNtYWxsLWNhcHM7Ij5mcmFnbWVudGF0aW9uIHNjZW5hcmlvPC9zcGFuPl5bVGhlIDxzcGFuIHN0eWxlPSJmb250LXZhcmlhbnQ6c21hbGwtY2FwczsiPmV4cGxvc2lvbjwvc3Bhbj4gYW5kIDxzcGFuIHN0eWxlPSJmb250LXZhcmlhbnQ6c21hbGwtY2FwczsiPmZyYWdtZW50YXRpb24gc2NlbmFyaW88L3NwYW4+IGZyYW1lcyBhcmUgdGFrZW4gZnJvbSB0aGUgKkZyYW1lTmV0KiByZXBvc2l0b3J5OyB0aGUgcmVzdCBhcmUgcmVwcmVzZW50ZWQgaW4gdGhlICpNZXRhTmV0KiByZXBvc2l0b3J5Ll0gKGByIGNvbnRhaW5lZF9lbnRpdHlfZnJhbWVzICU+JSBmaWx0ZXIoc3RyX2RldGVjdChmcmFtZXMsICdmcmFnbWVudGF0aW9uJykpICU+JSBzZWxlY3QocGVyYykgJT4lIHVubGlzdCgpYCUpLCBhbmQgKHYpIDxzcGFuIHN0eWxlPSJmb250LXZhcmlhbnQ6c21hbGwtY2FwczsiPnByZXNzdXJlIGluIGEgY29udGFpbmVyPC9zcGFuPiAoYHIgY29udGFpbmVkX2VudGl0eV9mcmFtZXMgJT4lIGZpbHRlcihzdHJfZGV0ZWN0KGZyYW1lcywgJ3ByZXNzdXJlJykpICU+JSBzZWxlY3QocGVyYykgJT4lIHVubGlzdCgpYCUpLgoKLi4uCgpUaGUgbW9zdCBmcmVxdWVudCBzdWJtYXBwaW5nIHdpdGhpbiB0aGUgPHNwYW4gc3R5bGU9ImZvbnQtdmFyaWFudDpzbWFsbC1jYXBzOyI+Y29udGFpbmVkIGVudGl0eTwvc3Bhbj4gbWV0YXBob3IgKGkuZS4gYHIgZHBseXI6OmZpbHRlcihjb250YWluZWRfZW50aXR5X3N1Ym1hcHBpbmdzLCBzdHJpbmdyOjpzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAiZnVsbG5lc3MiKSlbWyJwZXJjIl1dYCUgb2YgdGhlIHRvdGFsIGByIHRhbGx5KGNvbnRhaW5lZF9lbnRpdHlfZnJhbWVzLCBuKVtbMV1dIGAgdG9rZW5zIG9mIHRoZSBtZXRhcGhvcikgZXhwbG9pdHMgdGhlIEZ1bGxuZXNzX2RlZ3JlZSByb2xlIG9mIHRoZSA8c3BhbiBzdHlsZT0iZm9udC12YXJpYW50OnNtYWxsLWNhcHM7Ij5jb250YWluaW5nPC9zcGFuPiBmcmFtZS4gSW4gb3RoZXIgd29yZHMsIG1vc3Qgb2YgdGhlIGxleGljYWwgdW5pdHMgKExVcykgcmVmZXIgdG8gdGhlIGZ1bGxuZXNzIG9mIHRoZSBDb250ZW50IGluc2lkZSB0aGUgQ29udGFpbmVyOyBpbiB0aGUgdGFyZ2V0IGRvbWFpbiAoVEQpLCBmdWxsbmVzcyBvZiB0aGUgY29udGFpbmVkIGVudGl0eSBpcyBtYXBwZWQgb250byB0aGUgaGlnaCBleHRlbnQgb2YgPHNwYW4gc3R5bGU9ImZvbnQtdmFyaWFudDpzbWFsbC1jYXBzOyI+aGFwcGluZXNzPC9zcGFuPi4KCi4uLgoKVGhlIHNlY29uZCBwcmVkb21pbmFudCBzdWJtYXBwaW5nIGlzIGV2b2tlZCBieSBMVXMgcmVmZXJyaW5nIHRvIHRoZSAnY29udGFpbm1lbnQnIHNjZW5lIChgciBkcGx5cjo6ZmlsdGVyKGNvbnRhaW5lZF9lbnRpdHlfc3VibWFwcGluZ3MsIHN0cmluZ3I6OnN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICJhIGNvbnRhaW5lZCBlbnRpdHkkIikpW1sicGVyYyJdXWAlKS4gVGhpcyBpcyBtYXBwZWQgb250byB0aGUgZXhwZXJpZW5jZS9leGlzdGVuY2Ugb2YgPHNwYW4gc3R5bGU9ImZvbnQtdmFyaWFudDpzbWFsbC1jYXBzOyI+aGFwcGluZXNzPC9zcGFuPiBpdHNlbGYuCgouLi4KClRoZSBGdWxsbmVzcyBvZiB0aGUgQ29udGVudCBtYXkgcHJvZHVjZSAoaSkgcHJlc3N1cmUgb24gdGhlIENvbnRhaW5lciAoYHIgZHBseXI6OmZpbHRlcihjb250YWluZWRfZW50aXR5X3N1Ym1hcHBpbmdzLCBzdHJpbmdyOjpzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAicHJlc3NpbmciKSlbWyJwZXJjIl1dYCUpIHRoYXQsIHdoZW4gaXQgaXMgdW5jb250cm9sbGFibGUsIG1heSByZXN1bHQgaW4gKGlpKSBleHBsb3Npb24vYnJlYWtpbmcgb3V0IG9mIHRoZSBDb250YWluZXIgKGByIGRwbHlyOjpmaWx0ZXIoY29udGFpbmVkX2VudGl0eV9zdWJtYXBwaW5ncywgc3RyaW5ncjo6c3RyX2RldGVjdChzdWJtYXBwaW5ncywgImV4cGxvZGluZyIpKVtbInBlcmMiXV1gJSkuIFRoZSBleHBsb3Npb24tcmVsYXRlZCBzdWJtYXBwaW5nIGlzIG1hZGUgdXAgb2YgdGhlIDxzcGFuIHN0eWxlID0gImZvbnQtdmFyaWFudDpzbWFsbC1jYXBzOyI+ZXhwbG9zaW9uPC9zcGFuPiBhbmQgPHNwYW4gc3R5bGUgPSAiZm9udC12YXJpYW50OnNtYWxsLWNhcHM7Ij5mcmFnbWVudGF0aW9uIHNjZW5hcmlvPC9zcGFuPiBmcmFtZXMuCgouLi4KClRhYmxlIFhYWCBzaG93cyB0aGF0IGByIGZpbHRlcihjb250YWluZWRfZW50aXR5X2x1LCBQZXJjX292ZXJhbGwgPT0gbWF4KFBlcmNfb3ZlcmFsbCkpW1s0XV1gJSBvZiB0aGUgdG9rZW5zIG9mIDxzcGFuIHN0eWxlPSdmb250LXZhcmlhbnQ6c21hbGwtY2FwczsnPmhhcHBpbmVzcyBpcyBhIGNvbnRhaW5lZCBlbnRpdHk8L3NwYW4+IG1ldGFwaG9yIGlzIGR1ZSB0byBvbmUgTFUsIGkuZS4gKnBlbnVoKiAndG8gYmUgZnVsbCcuIFRoaXMgcG9pbnRzIHRvIGEgaGlnaGx5LWNvbnZlbnRpb25hbGlzZWQgcHJvcGVydHkgb2YgdGhlIG1ldGFwaG9yIGluIGl0cyBsaW5ndWlzdGljIG1hbmlmZXN0YXRpb24sIGdpdmVuIHRoZSBoaWdoIGZyZXF1ZW5jeSBvZiBhIHNpbmdsZSBMVSBjb21wYXJlZCB0byB0aGUgb3RoZXJzIFtjZi4gQGdvbGFfdGFzdGVfMjAxNiwgcC4gNTNdLiBJbiBvdGhlciB3b3JkcywgdGhlIHJlbGF0aXZlIGVudHJlbmNobWVudCBvZiB0aGUgbWV0YXBob3IgYXJpc2VzIGZyb20gYSBjb252ZW50aW9uYWxpc2VkIGV4cHJlc3Npb24sIHN1Y2ggYXMgKnBlbnVoKiAndG8gYmUgZnVsbCcuIFRoaXMgaXMgZnVydGhlciBzdXBwb3J0ZWQgYnkgdGhlIG1ldGFwaG9yJ3MgbG93IHBlcmNlbnRhZ2Ugb2YgdGhlIHZhcmlhdGlvbiBmb3IgaXRzIGxpbmd1aXN0aWMgcmVhbGlzYXRpb25zIChpLmUuLCBgciBmaWx0ZXIodHRyX21ldGFwaG9yLCBzdHJfZGV0ZWN0KG1ldGFwaG9ycywgImNvbnRhaW5lZCBlbnRpdHkiKSlbWyJ0eXBlX3Blcl90b2tlbl9sdSJdXWAlKSBvdmVyIGl0cyBvdmVyYWxsIHRva2VuIGZyZXF1ZW5jeS4KCiMjIEhhcHBpbmVzcyBpcyBhIGxpcXVpZCBpbiBhIGNvbnRhaW5lcgoKYGBge3IgbGlxdWlkLWNvbnRhaW5tZW50LWRhdGEtZm9yLW1haW50ZXh0fQojIExJUVVJRCBJTiBBIENPTlRBSU5FUiBtZXRhcGhvciBkYXRhCiMjIGZyYW1lcwpjb250YWluZWRfbGlxdWlkX2ZyYW1lcyA8LSBoYXBweXI6OmdldF9mcmFtZXMoImxpcXVpZCBpbiBhIGNvbnRhaW5lciIsIGRmID0gaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvcikgJT4lIAogIG11dGF0ZShtZXRhcGhvcnMgPSAnbGlxdWlkIGluIGEgY29udGFpbmVyJykgJT4lCiAgYXJyYW5nZShkZXNjKG4pKQoKIyMgc3VibWFwcGluZ3MKY29udGFpbmVkX2xpcXVpZF9zdWJtYXBwaW5ncyA8LSBoYXBweXI6OmdldF9zdWJtYXBwaW5ncygibGlxdWlkIGluIGEgY29udGFpbmVyIiwgZGYgPSBoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yKSAlPiUgCiAgbXV0YXRlKGFzcGVjdCA9IGlmX2Vsc2Uoc3RyX2RldGVjdChzdWJtYXBwaW5ncywgImV4cHJlc3Npb24iKSwgImV4cHJlc3Npb24iLCAiY29udGFpbm1lbnQiKSwKICAgICAgICAgYXNwZWN0ID0gaWZfZWxzZShzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAiKGhpZ2ggaW50ZW5zaXR5fGludGVuc2lmaWVkfGludGVuc2UpIiksICJpbmNyZWFzZWQgaW50ZW5zaXR5IiwgYXNwZWN0KSwKICAgICAgICAgYXNwZWN0ID0gaWZfZWxzZShzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAicHJldmVudGluZyIpLCAicmVndWxhdGlvbiIsIGFzcGVjdCksCiAgICAgICAgIGFzcGVjdCA9IGlmX2Vsc2Uoc3RyX2RldGVjdChzdWJtYXBwaW5ncywgImFjY29tbW9kYXRpbmciKSwgImFjY29tbW9kYXRpbmciLCBhc3BlY3QpKQoKIyMgYXNwZWN0IHN1bW1hcmlzZWQKY29udGFpbmVkX2xpcXVpZF9hc3BlY3QgPC0gY29udGFpbmVkX2xpcXVpZF9zdWJtYXBwaW5ncyAlPiUgCiAgZ3JvdXBfYnkoYXNwZWN0KSAlPiUgCiAgc3VtbWFyaXNlKG4gPSBzdW0obiksIAogICAgICAgICAgICB0eXBlID0gc3VtKHR5cGUpLCAKICAgICAgICAgICAgcGVyYyA9IHN1bShwZXJjKSwgCiAgICAgICAgICAgIHR5cGVfcGVyYyA9IHN1bSh0eXBlX3BlcmMpKSAlPiUKICBhcnJhbmdlKGRlc2MobikpCgojIyBsZXhpY2FsIHVuaXQgdGFibGUKY29udGFpbmVkX2xpcXVpZF9sdSA8LSBoYXBweXI6OmdldF9sdV90YWJsZSgibGlxdWlkIGluIGEgY29udGFpbmVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3Bfbl9vbmx5ID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGYgPSBoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yKQoKY29udGFpbmVkX2xpcXVpZF9sdSAlPiUKICB0b3BfbigxMCwgTikgJT4lCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSAnVGhlIG1vc3QgZnJlcXVlbnQgbGV4aWNhbCB1bml0cyBldm9raW5nIDxzcGFuIHN0eWxlID0gImZvbnQtdmFyaWFudDpzbWFsbC1jYXBzOyI+aGFwcGluZXNzIGlzIGEgbGlxdWlkIGluIGEgY29udGFpbmVyPC9zcGFuPi4nLCByb3cubmFtZXMgPSBUUlVFKQpgYGAKCgpUaGUgc3VibWFwcGluZ3Mgd2l0aGluIDxzcGFuIHN0eWxlPSJmb250LXZhcmlhbnQ6c21hbGwtY2FwczsiPmhhcHBpbmVzcyBpcyBhIGxpcXVpZCBpbiBhIGNvbnRhaW5lcjwvc3Bhbj4gbWV0YXBob3IgbWFrZSB1c2Ugb2Ygc3RydWN0dXJlcyBmcm9tIGByIGRpbShjb250YWluZWRfbGlxdWlkX2ZyYW1lcylbMV0gJT4lIGhhcHB5cjo6bnVtYmVyczJ3b3JkcygpYCBzb3VyY2UgZnJhbWVzIHRoYXQgcmVmbGVjdCBhIHJhbmdlIG9mIGV4cGVyaWVudGlhbCBrbm93bGVkZ2UgY29uY2VybmluZyB0aGUgYmVoYXZpb3VyIG9mIGEgY29udGFpbmVkIGxpcXVpZC4gVGhleSBhcmUgKGkpIDxzcGFuIHN0eWxlPSJmb250LXZhcmlhbnQ6c21hbGwtY2FwczsiPnJlbGVhc2UgbGlxdWlkPC9zcGFuPiAoYHIgY29udGFpbmVkX2xpcXVpZF9mcmFtZXMgJT4lIGZpbHRlcihzdHJfZGV0ZWN0KGZyYW1lcywgJ3JlbGVhc2UnKSkgJT4lIHNlbGVjdChwZXJjKSAlPiUgdW5saXN0KClgJSksIChpaSkgPHNwYW4gc3R5bGU9ImZvbnQtdmFyaWFudDpzbWFsbC1jYXBzOyI+aGVhdGluZyBmbHVpZDwvc3Bhbj4gKGByIGNvbnRhaW5lZF9saXF1aWRfZnJhbWVzICU+JSBmaWx0ZXIoc3RyX2RldGVjdChmcmFtZXMsICdoZWF0aW5nJykpICU+JSBzZWxlY3QocGVyYykgJT4lIHVubGlzdCgpYCUpLCAoaWlpKSA8c3BhbiBzdHlsZT0iZm9udC12YXJpYW50OnNtYWxsLWNhcHM7Ij5mbHVpZCBjb250YWlubWVudDwvc3Bhbj4gKGByIGNvbnRhaW5lZF9saXF1aWRfZnJhbWVzICU+JSBmaWx0ZXIoc3RyX2RldGVjdChmcmFtZXMsICdmbHVpZCBjb250YWlubWVudCcpKSAlPiUgc2VsZWN0KHBlcmMpICU+JSB1bmxpc3QoKWAlKSwgKGl2KSA8c3BhbiBzdHlsZT0iZm9udC12YXJpYW50OnNtYWxsLWNhcHM7Ij5mbHVpZCBtb3Rpb248L3NwYW4+IChgciBjb250YWluZWRfbGlxdWlkX2ZyYW1lcyAlPiUgZmlsdGVyKHN0cl9kZXRlY3QoZnJhbWVzLCAnZmx1aWQgbW90aW9uJykpICU+JSBzZWxlY3QocGVyYykgJT4lIHVubGlzdCgpYCUpLCBhbmQgKHYpIDxzcGFuIHN0eWxlPSJmb250LXZhcmlhbnQ6c21hbGwtY2FwczsiPnN0b3AgZmxvdyBvZiBzdWJzdGFuY2U8L3NwYW4+IChgciBjb250YWluZWRfbGlxdWlkX2ZyYW1lcyAlPiUgZmlsdGVyKHN0cl9kZXRlY3QoZnJhbWVzLCAnc3RvcCBmbG93JykpICU+JSBzZWxlY3QocGVyYykgJT4lIHVubGlzdCgpYCUpLiBUaGVzZSBmcmFtZXMgYXJlIHJlcHJlc2VudGVkIGluIHRoZSAqTWV0YU5ldCogZnJhbWUgcmVwb3NpdG9yeS4KClRvIGJlZ2luIHdpdGgsIHRoZSBleGlzdGVuY2Ugb2YgPHNwYW4gc3R5bGU9ImZvbnQtdmFyaWFudDpzbWFsbC1jYXBzOyI+aGFwcGluZXNzPC9zcGFuPiBpcyBjb25jZXB0dWFsaXNlZCBhcyAoaSkgbGlxdWlkIGNvbnRhaW5tZW50IChgciBjb250YWluZWRfbGlxdWlkX3N1Ym1hcHBpbmdzICU+JSBmaWx0ZXIoc3RyX2RldGVjdChzdWJtYXBwaW5ncywgJ2EgbGlxdWlkIGluIGEnKSkgJT4lIHNlbGVjdChwZXJjKSAlPiUgdW5saXN0KClgJSleW1RoZSBwZXJjZW50YWdlIG9mIGxpcXVpZCBjb250YWlubWVudCBzdWJtYXBwaW5nIGRvZXMgbm90IGNvcnJlc3BvbmQgdG8gdGhlIG92ZXJhbGwgcGVyY2VudGFnZSBvZiB0aGUgPHNwYW4gc3R5bGU9ImZvbnQtdmFyaWFudDpzbWFsbC1jYXBzOyI+Zmx1aWQgY29udGFpbm1lbnQ8L3NwYW4+IGZyYW1lIGJlY2F1c2UgdGhlIG90aGVyIHBvcnRpb24gb2YgdGhlIG1ldGFwaG9yaWNhbCBleHByZXNzaW9ucyBldm9raW5nIDxzcGFuIHN0eWxlPSJmb250LXZhcmlhbnQ6c21hbGwtY2FwczsiPmZsdWlkIGNvbnRhaW5tZW50PC9zcGFuPiBkbyBub3QgcHJvZmlsZSB0aGUgbGlxdWlkIGNvbnRhaW5tZW50ICpwZXIgc2UqLCBidXQgYWxzbyBpbmNsdWRlIGhpZ2hsaWdodGluZyB0aGUgRmx1aWRfbGV2ZWwgcm9sZSBvZiB0aGUgZnJhbWUuIEkgY29uc2lkZXIgdGhlIGV4cHJlc3Npb25zIHByb2ZpbGluZyB0aGUgRmx1aWRfbGV2ZWwgcm9sZSBvZiB0aGUgZnJhbWUgdG8gZXZva2UgYSBzZXBhcmF0ZSBzdWJtYXBwaW5nLCB2aXouIGluZGljYXRpbmcgdGhlIEZ1bGxuZXNzIG9mIHRoZSBjb250YWluZWQgZmx1aWQuIFNlZSB0aGUgZGlzY3Vzc2lvbiBvbiBjaXRhdGlvbiBYWFggYmVsb3cuXSBhbmQgKGlpKSBmbHVpZGljIG1vdGlvbiBvZiB0aGUgbGlxdWlkIChgciBjb250YWluZWRfbGlxdWlkX3N1Ym1hcHBpbmdzICU+JSBmaWx0ZXIoc3RyX2RldGVjdChzdWJtYXBwaW5ncywgJ2lzIGEgZmx1aWRpYyBtb3Rpb24kJykpICU+JSBzZWxlY3QocGVyYykgJT4lIHVubGlzdCgpYCUpLiBBcyB0byB0aGUgPHNwYW4gc3R5bGU9ImZvbnQtdmFyaWFudDpzbWFsbC1jYXBzOyI+Zmx1ZGljIG1vdGlvbjwvc3Bhbj4gc3VibWFwcGluZywgdGhlcmUgYXJlIHR3byBzY2VuYXJpb3MgYXR0ZXN0ZWQgaW4gbXkgc2FtcGxlLiBGaXJzdCwgdGhlIGxpcXVpZCBtYXkgZmxvdyBpbndhcmRseSBmcm9tIHNvbWUgc291cmNlIGFuZCB0aHJvdWdob3V0IHRoZSBib2R5LgoKLi4uCgpOZXh0LCB0aGVyZSBhcmUgdHdvIHN1Ym1hcHBpbmdzIHRoYXQgZm9jdXMgb24gdGhlIGludGVuc2UgZXhwZXJpZW5jZSBvZiA8c3BhbiBzdHlsZT0iZm9udC12YXJpYW50OnNtYWxsLWNhcHM7Ij5oYXBwaW5lc3M8L3NwYW4+LiBUaGUgZmlyc3Qgc3VibWFwcGluZyBpcyBiYXNlZCBvbiB0aGUgPHNwYW4gc3R5bGU9ImZvbnQtdmFyaWFudDpzbWFsbC1jYXBzOyI+aGVhdGVkIGZsdWlkPC9zcGFuPiBmcmFtZSwgbmFtZWx5IDxzcGFuIHN0eWxlPSJmb250LXZhcmlhbnQ6c21hbGwtY2FwczsiPmludGVuc2lmaWVkIGhhcHBpbmVzcyBpcyBoZWF0ZWQgbGlxdWlkPC9zcGFuPiAoYHIgY29udGFpbmVkX2xpcXVpZF9zdWJtYXBwaW5ncyAlPiUgZmlsdGVyKHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICdoZWF0ZWQgbGlxdWlkJykpICU+JSBzZWxlY3QocGVyYykgJT4lIHVubGlzdCgpYCUpKS4KCi4uLgoKVGhlIHNlY29uZCBzdWJtYXBwaW5nIGlzIHBvc3R1bGF0ZWQgdmlhIHRoZSBwcm9maWxpbmcgb2YgdGhlIGZ1bGxuZXNzIG9mIHRoZSBGbHVpZF9sZXZlbCByb2xlIGluIHRoZSA8c3BhbiBzdHlsZT0iZm9udC12YXJpYW50OnNtYWxsLWNhcHM7Ij5mbHVpZCBjb250YWlubWVudDwvc3Bhbj4gZnJhbWUsIG5hbWVseSA8c3BhbiBzdHlsZT0iZm9udC12YXJpYW50OnNtYWxsLWNhcHM7Ij5pbnRlbnNlIGhhcHBpbmVzcyBpcyBicmltbWluZyBsaXF1aWQgaW4gYSBjb250YWluZXI8L3NwYW4+IChgciBjb250YWluZWRfbGlxdWlkX3N1Ym1hcHBpbmdzICU+JSBmaWx0ZXIoc3RyX2RldGVjdChzdWJtYXBwaW5ncywgJ2Z1bGxuZXNzJykpICU+JSBzZWxlY3QocGVyYykgJT4lIHVubGlzdCgpYCUpLgoKLi4uCgo8c3BhbiBzdHlsZSA9ICJmb250LXZhcmlhbnQ6c21hbGwtY2FwczsiPlJlbGVhc2UgbGlxdWlkPC9zcGFuPiBpcyB0aGUgbW9zdCBmcmVxdWVudGx5IGV2b2tlZCBmcmFtZSBpbiB0aGUgbWV0YXBob3IgKGkuZS4sIGByIGZpbHRlcihjb250YWluZWRfbGlxdWlkX2ZyYW1lcywgc3RyX2RldGVjdChmcmFtZXMsICJyZWxlYXNlIikpW1sibiJdXWAgdG9rZW5zKSBhbmQgaXQgaGFzIHRoZSBoaWdoZXN0IG51bWJlciBvZiBMVSB0eXBlcyBjb21wYXJlZCB0byB0aGUgb3RoZXIgZnJhbWVzIGluIHRoZSBtZXRhcGhvciAoaS5lLiwgYHIgZmlsdGVyKGNvbnRhaW5lZF9saXF1aWRfZnJhbWVzLCBzdHJfZGV0ZWN0KGZyYW1lcywgInJlbGVhc2UiKSlbWyJ0eXBlIl1dYCB0eXBlcykuCgouLi4KCk1vcmVvdmVyLCBhbW9uZyB0aGUgdGVuIG1vc3QgZnJlcXVlbnQgbWV0YXBob3JzIGRpc2N1c3NlZCBpbiB0aGlzIGNoYXB0ZXIsIGByIHNjYXBzKCJoYXBwaW5lc3MgaXMgYSBsaXF1aWQgaW4gYSBjb250YWluZXIiKWAgaXMgdGhlIG1vc3QgZGl2ZXJzZSBsaW5ndWlzdGljYWxseTogYHIgZmlsdGVyKHR0cl9tZXRhcGhvciwgc3RyX2RldGVjdChtZXRhcGhvcnMsICJsaXF1aWQgaW4gYSBjb250YWluZXIiKSlbWyJ0eXBlX3Blcl90b2tlbl9sdSJdXWAlIG9mIGl0cyB0b2tlbnMgYXJlIG9mIGRpZmZlcmVudCBMVSB0eXBlcy4KCgojIyBJbnRlbnNpdHkgb2YgaGFwcGluZXNzIGlzIHF1YW50aXR5IG9mIG9iamVjdAoKYGBge3IgcXVhbnRpdHktZGF0YS1mb3ItbWFpbnRleHR9CiMjIHN1Ym1hcHBpbmdzCnF1YW50aXR5X3N1Ym1hcHBpbmcgPC0gaGFwcHlyOjpnZXRfc3VibWFwcGluZ3MoInF1YW50aXR5IG9mIG9iamVjdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGYgPSBoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yKQoKIyMgTFUgYW5kIHN1Ym1hcHBpbmdzCnF1YW50aXR5X2ZvY3VzX2x1IDwtIGhhcHB5cjo6Z2V0X2x1X3RhYmxlKCJxdWFudGl0eSBvZiBvYmplY3QiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJtYXBwaW5nX3BlcmMgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmNsX3N1Ym1hcHBpbmdzID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGYgPSBoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yKSAlPiUgCiAgbXV0YXRlKG1hcHBpbmcgPSBpZl9lbHNlKHN0cl9kZXRlY3QoU3VibWFwcGluZ3MsICdtb3JlfGFkZGluZycpLCAnbW9yZScsICdsZXNzJykpICU+JQogIGdyb3VwX2J5KG1hcHBpbmcpICU+JQogIG11dGF0ZShOX2J5X21hcHBpbmcgPSBzdW0oTikpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUocGVyY19sdV9ieV9tYXBwaW5nID0gcm91bmQoKE4vTl9ieV9tYXBwaW5nKSAqIDEwMCwgMikpICU+JQogIHNlbGVjdCgtU3VibWFwcGluZ3MpCgojIyBhc3BlY3QKcXVhbnRpdHlfZm9jdXMgPC0gcXVhbnRpdHlfc3VibWFwcGluZyAlPiUKICBtdXRhdGUobWFwcGluZyA9IGlmX2Vsc2Uoc3RyX2RldGVjdChzdWJtYXBwaW5ncywgJ21vcmV8YWRkaW5nJyksICdtb3JlJywgJ2xlc3MnKSkgJT4lIAogIGdyb3VwX2J5KG1hcHBpbmcpICU+JSAKICBzdW1tYXJpc2UobiA9IHN1bShuKSwgCiAgICAgICAgICAgIHR5cGUgPSBzdW0odHlwZSkpICU+JSAKICBtdXRhdGUocGVyYyA9IHJvdW5kKG4vc3VtKG4pKjEwMCwgMiksIAogICAgICAgICB0eXBlX3BlcmMgPSByb3VuZCh0eXBlL3N1bSh0eXBlKSoxMDAsIDIpKQpgYGAKCgoKT3ZlcmFsbCwgYHIgZmlsdGVyKHF1YW50aXR5X2ZvY3VzLCBtYXBwaW5nID09ICJtb3JlIilbWyJwZXJjIl1dYCUgb2YgdGhlIHRvdGFsIGByIHRhbGx5KHF1YW50aXR5X2ZvY3VzLCBuKVtbMV1dYCB0b2tlbnMgb2YgdGhlIG1ldGFwaG9yaWNhbCBleHByZXNzaW9ucyBwcm9maWxlIHRoZSAnbW9yZSBxdWFudGl0eScgZW5kIG9mIHRoZSBlbnRpcmUgPHNwYW4gc3R5bGU9ImZvbnQtdmFyaWFudDpzbWFsbC1jYXBzOyI+cXVhbnRpdHk8L3NwYW4+IGZyYW1lLgoKLi4uCgpGcm9tIHRoZSBsaW5ndWlzdGljIHJlYWxpc2F0aW9uIHBvaW50IG9mIHZpZXcsIHRoZSBgciBzY2FwcygncXVhbnRpdHknKWAgbWV0YXBob3IgY2FuIGFsc28gYmUgY29uc2lkZXJlZCBsZXNzIGRpdmVyc2UuIE9ubHkgYHIgZmlsdGVyKHR0cl9tZXRhcGhvciwgc3RyX2RldGVjdChtZXRhcGhvcnMsICJxdWFudGl0eSBvZiBvYmplY3QiKSlbWyJ0eXBlX3Blcl90b2tlbl9sdSJdXWAlIG91dCBvZiBpdHMgYHIgdGFsbHkocXVhbnRpdHlfZm9jdXMsIG4pW1sxXV1gIHRva2VucyBhcmUgZXhwcmVzc2VkIGJ5IGRpZmZlcmVudCBMVSB0eXBlcy4gQW1vbmcgdGhlIHByZWRvbWluYW50IExVcyBpbmNsdWRlICp0YW1iYWhrYW4qICd0byBhZGQgc3RoLicsICpiYW55YWsqICdtYW55L211Y2gnLCBhbmQgKmJlcmxlYmloYW4qICdleGNlc3NpdmUnLgoKIyMgSGFwcGluZXNzIGlzIGFuICh1bil2ZWlsZWQgb2JqZWN0CgpgYGB7ciB1bnZlaWxlZC1vYmplY3QtZGF0YS1mb3ItbWFpbnRleHR9CiMgZnJhbWVzCmNvbmNlYWxlZF9mcmFtZXMgPC0gaGFwcHlyOjpnZXRfZnJhbWVzKCJ2ZWlsZWQiLCBkZiA9IGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IpCgojIHN1Ym1hcHBpbmcKY29uY2VhbGVkX3N1Ym1hcHBpbmcgPC0gaGFwcHlyOjpnZXRfc3VibWFwcGluZ3MoInZlaWxlZCIsIGRmID0gaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvcikKCiMgdG9rZW5zIGNvbmNlcm5pbmcgaGlkaW5nIGFuZCBhYmlsaXRhdGl2ZSBtb2RhbApoaWRpbmdfdG9rZW5zIDwtIDE6ZmlsdGVyKGNvbmNlYWxlZF9zdWJtYXBwaW5nLCBzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAicmVndWxhdGluZyIpKVtbIm4iXV0KdG9rZW5zX3dpdGhvdXRfYWJpbGl0YXRpdmUgPC0gYygzLCAxMCwgMTksIDIxKQp0b2tlbnNfd2l0aF9hYmlsaXRhdGl2ZSA8LSBzZXRkaWZmKGhpZGluZ190b2tlbnMsIHRva2Vuc193aXRob3V0X2FiaWxpdGF0aXZlKQp0b2tlbnNfd2l0aF9hYmlsaXRhdGl2ZV9wb3NpdGl2ZSA8LSAxNQp0b2tlbnNfd2l0aF9hYmlsaXRhdGl2ZV9uZWdhdGVkIDwtIHNldGRpZmYodG9rZW5zX3dpdGhfYWJpbGl0YXRpdmUsIHRva2Vuc193aXRoX2FiaWxpdGF0aXZlX3Bvc2l0aXZlKQp0b2tlbnNfd2l0aG91dF9hYmlsaXRhdGl2ZV9uZWdhdGVkIDwtIGMoMTAsIDIxKQoKIyBsZXhpY2FsIHVuaXQKY29uY2VhbGVkX2x1IDwtIGhhcHB5cjo6Z2V0X2x1X3RhYmxlKCJ2ZWlsZWQiLCB0b3Bfbl9vbmx5ID0gVFJVRSwgZGYgPSBoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yKQpjb25jZWFsZWRfbHUgJT4lCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSAnVG9wLTEwIG1vc3QgZnJlcXVlbnQgbGV4aWNhbCB1bml0cyBldm9raW5nIDxzcGFuIHN0eWxlID0gImZvbnQtdmFyaWFudDpzbWFsbC1jYXBzOyI+aGFwcGluZXNzIGlzIGFuICh1bil2ZWlsZWQgb2JqZWN0PC9zcGFuPi4nLCByb3cubmFtZXMgPSBUUlVFKQpgYGAKClRoZXNlIHR3byBhc3BlY3RzIGFyZSBjYXB0dXJlZCB2aWEgdGhyZWUgc3VibWFwcGluZ3MuIFRoZSBtb3N0IGZyZXF1ZW50IG9uZSBpcyB0aGUgYHIgc2NhcHMoJ2V4aXN0ZW5jZSBvZiBoYXBwaW5lc3MgaXMgdmlzaWJpbGl0eSBvZiBhbiBvYmplY3QnKWAgKGByIGZpbHRlcihjb25jZWFsZWRfc3VibWFwcGluZywgc3RyX2RldGVjdChzdWJtYXBwaW5ncywgInZpc2liaWxpdHkiKSlbWyJwZXJjIl1dYCUpLCBiYXNlZCBvbiB0aGUgPHNwYW4gc3R5bGU9J2ZvbnQtdmFyaWFudDpzbWFsbC1jYXBzOyc+c2VlaW5nPC9zcGFuPiBmcmFtZQoKLi4uCgpUaGUgc2Vjb25kIHN1Ym1hcHBpbmcgaXMgYmFzZWQgb24gdGhlIGByIHNjYXBzKCdjYXVzZSB0byBzZWUnKWAgZnJhbWUsIG5hbWVseSBgciBzY2FwcygnZXhwcmVzc2luZyBoYXBwaW5lc3MgaXMgc2hvd2luZyBhbiBvYmplY3QnKWAgKGByIGZpbHRlcihjb25jZWFsZWRfc3VibWFwcGluZywgc3RyX2RldGVjdChzdWJtYXBwaW5ncywgInNob3dpbmciKSlbWyJwZXJjIl1dYCUpLgoKLi4uCgpUaGUgdGhpcmQgc3VibWFwcGluZyBpcyBgciBzY2FwcygncmVndWxhdGluZyBoYXBwaW5lc3MgaXMgaGlkaW5nIGFuIG9iamVjdCcpYCAoYHIgZmlsdGVyKGNvbmNlYWxlZF9zdWJtYXBwaW5nLCBzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAiaGlkaW5nIikpW1sicGVyYyJdXWAlKS4gVGhpcyBtYXBwaW5nIGlzIGV4cHJlc3NlZCBieSBsZXhpY2FsIHVuaXRzIChMVXMpIGZyb20gdGhlIGByIHNjYXBzKCd2aXN1YWwgb2JzdHJ1Y3Rpb24nKWAgZnJhbWUuIEluIGByIG51bWJlcnMyd29yZHMobGVuZ3RoKHRva2Vuc193aXRoX2FiaWxpdGF0aXZlKSlgIHRva2VucyBvZiB0aGUgdG90YWwgYHIgZmlsdGVyKGNvbmNlYWxlZF9zdWJtYXBwaW5nLCBzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAicmVndWxhdGluZyIpKVtbIm4iXV1gIGNpdGF0aW9ucyBvZiB0aGlzIHN1Ym1hcHBpbmcsIHRoZSBMVXMgY28tb2NjdXIgd2l0aCBhYmlsaXRhdGl2ZSBtb2RhbCBhdXhpbGlhcmllcyAoaS5lLiAqZGFwYXQvYmlzYSogJ2NhbicsICptYW1wdS9zYW5nZ3VwKiAnYmUgYWJsZSB0bycpLiBZZXQsIGByIG51bWJlcnMyd29yZHMobGVuZ3RoKHRva2Vuc193aXRoX2FiaWxpdGF0aXZlX25lZ2F0ZWQpKWAgb2YgdGhlc2UgYHIgbnVtYmVyczJ3b3JkcyhsZW5ndGgodG9rZW5zX3dpdGhfYWJpbGl0YXRpdmUpKWAgdG9rZW5zIGFyZSBuZWdhdGVkLiBPdmVyYWxsLCBpbmNsdWRpbmcgdG9rZW5zIHdpdGhvdXQgdGhlIGFiaWxpdGF0aXZlIG1vZGFscywgYHIgcm91bmQoKGxlbmd0aCh0b2tlbnNfd2l0aG91dF9hYmlsaXRhdGl2ZV9uZWdhdGVkKSArIGxlbmd0aCh0b2tlbnNfd2l0aF9hYmlsaXRhdGl2ZV9uZWdhdGVkKSkvbGVuZ3RoKGhpZGluZ190b2tlbnMpICogMTAwLCAyKWAlIGNpdGF0aW9ucyBvZiB0aGUgYHIgc2NhcHMoJ3JlZ3VsYXRpbmcgaGFwcGluZXNzIGlzIGhpZGluZyBhbiBvYmplY3QnKWAgYXJlIG5lZ2F0ZWQuIFRoaXMgcG9pbnRzIHRvIHRoZSBmb2N1cyBvbiB0aGUgKmluYWJpbGl0eSogdG8gKmNvbmNlYWwqIHRoZSBlbW90aW9uLgoKLi4uCgpMaW5ndWlzdGljYWxseSwgYHIgc2NhcHMoImhhcHBpbmVzcyBpcyBhbiAodW4pdmVpbGVkIG9iamVjdCIpYCBtZXRhcGhvciBhbHNvIGhhcyBhIGxvdyBwZXJjZW50YWdlIG9mIHZhcmlhdGlvbiBmb3IgdGhlIGV2b2tpbmcgTFVzIChgciBoYXBweXI6OmdldF9tZXRhX2ZyZXFfcHJvZmlsZXMoJ3ZlaWxlZCcsIHR5cGVfcGVyX3Rva2VuX2x1LCBkZiA9IHR0cl9tZXRhcGhvcilbWzJdXWAlKS4gSXQgaXMgcHJlZG9taW5hbnRseSBldm9rZWQgYnkgKmxpaGF0KiAndG8gc2VlL2xvb2sgYXQnLCAqdGVybGloYXQqLCAndG8gYmUgdmlzaWJsZScsICoodC9uKWFtcGFrKiAndG8gYmUgdmlzaWJsZScsIGFuZCAqdHVuanVra2FuKiAndG8gc2hvdycKCiMjIEhhcHBpbmVzcyBpcyBhIHN1Ym1lcmdlZCBlbnRpdHkKCmBgYHtyIHN1Ym1lcmdlZC1lbnRpdHktZGF0YS1mb3ItbWFpbnRleHR9CiMjIHN1Ym1hcHBpbmdzCnN1Ym1lcmdlZF9zdWJtYXBwaW5ncyA8LSBoYXBweXI6OmdldF9zdWJtYXBwaW5ncygic3VibWVyZ2VkIiwgZGYgPSBoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yKQoKIyMgbGV4aWNhbCB1bml0IHRhYmxlCnN1Ym1lcmdlZF9sdSA8LSBoYXBweXI6OmdldF9sdV90YWJsZSgic3VibWVyZ2VkIiwgZGYgPSBoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yKQpzdWJtZXJnZWRfbHUgJT4lCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSAnVG9wLTEwIG1vc3QgZnJlcXVlbnQgbGV4aWNhbCB1bml0cyBldm9raW5nIHRoZSA8c3BhbiBzdHlsZSA9ICJmb250LXZhcmlhbnQ6c21hbGwtY2FwczsiPmhhcHBpbmVzcyBpcyBhIHN1Ym1lcmdlZCBlbnRpdHk8L3NwYW4+LicsIHJvdy5uYW1lcyA9IFRSVUUpCmBgYAoKTGluZ3Vpc3RpY2FsbHksIHRoZSBtZXRhcGhvciBpcyBwcm9wb3J0aW9uYWxseSBsZXNzIHZhcmllZCBpbiBpdHMgbGV4aWNhbCByZWFsaXNhdGlvbiAoYHIgaGFwcHlyOjpnZXRfbWV0YV9mcmVxX3Byb2ZpbGVzKCdzdWJtZXJnZWQnLCB0eXBlX3Blcl90b2tlbl9sdSwgZGYgPSB0dHJfbWV0YXBob3IpW1syXV1gJSBvZiBsZXhpY2FsIHZhcmlhdGlvbiksIGdpdmVuIGl0cyB0b2tlbiBmcmVxdWVuY3kuIFRoZSBoaWdoIHRva2VuIGZyZXF1ZW5jeSBvZiB0aGUgbWV0YXBob3IgaXMgYWNjb3VudGVkIGZvciBtb3N0bHkgYnkgdGhlIGZpcnN0IHRocmVlIExVcyBpbiBbVGFibGUgXEByZWYodGFiOmx1LXN1Ym1lcmdlZC1lbnRpdHkpXSgjbHUtc3VibWVyZ2VkLWVudGl0eSksIHRha2luZyB1cCBgciBzdW0oaGFwcHlyOjpnZXRfY2ljX21ldGFfbHUoInN1Ym1lcmdlZCIsIHR0cl9tZXRhcGhvcilbWyJQZXJjX292ZXJhbGwiXV0pYCUgb2YgdGhlIG1ldGFwaG9yJ3MgdG9rZW4gZnJlcXVlbmN5LgoKLi4uCgpJbiBnZW5lcmFsLCBhbGwgdGhlIG1ldGFwaG9yaWNhbCBleHByZXNzaW9ucyBvZiA8c3BhbiBzdHlsZT0nZm9udC12YXJpYW50OnNtYWxsLWNhcHM7Jz5oYXBwaW5lc3MgaXMgYSBzdWJtZXJnZWQgZW50aXR5PC9zcGFuPiBpbmRpY2F0ZSB0aGUgbWFubmVyIHRocm91Z2ggd2hpY2ggPHNwYW4gc3R5bGU9J2ZvbnQtdmFyaWFudDpzbWFsbC1jYXBzOyc+aGFwcGluZXNzPC9zcGFuPiBtYXkgZXhpc3QuIE5hbWVseSwgZXhpc3RlbmNlIG9mIDxzcGFuIHN0eWxlPSdmb250LXZhcmlhbnQ6c21hbGwtY2FwczsnPmhhcHBpbmVzczwvc3Bhbj4gaXMgdW5kZXJzdG9vZCBhcyBhIHN1cmZhY2luZyBvciBvdXR3YXJkIG1vdGlvbiBvZiBhbiBFbnRpdHksIGJlIGl0IChpKSBuYXR1cmFsbHkgZW1lcmdpbmcgKGByIGZpbHRlcihzdWJtZXJnZWRfc3VibWFwcGluZ3MsICFzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAnY2F1c2UnKSlbWyJwZXJjIl1dYCUpIG9yIChpaSkgY2F1c2VkIHRvIGVtZXJnZSBieSBzb21lIGFnZW50IChgciBmaWx0ZXIoc3VibWVyZ2VkX3N1Ym1hcHBpbmdzLCBzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAnY2F1c2UnKSlbWyJwZXJjIl1dYCUpLgoKCiMjIEhhcHBpbmVzcyBpcyBmb29kCgpgYGB7ciBmb29kLWRhdGEtZm9yLW1haW50ZXh0fQojIyBzdWJtYXBwaW5ncwpmb29kX3N1Ym1hcHBpbmdzIDwtIGhhcHB5cjo6Z2V0X3N1Ym1hcHBpbmdzKCdmb29kJywgZGYgPSBoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yKQoKIyBmcmFtZXMKZm9vZF9mcmFtZXMgPC0gaGFwcHlyOjpnZXRfZnJhbWVzKCJmb29kIiwgZGYgPSBoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yKQoKIyBMVSBieSBmcmFtZXMKZm9vZF9sdV9mcmFtZXMgPC0gaGFwcHlyOjpnZXRfbHVfdGFibGUoImZvb2QiLCBkZiA9IGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IpCgojIExVIGJ5IHN1Ym1hcHBpbmdzCmZvb2RfbHVfc3VibWFwcGluZ3MgPC0gaGFwcHlyOjpnZXRfbHVfc3VibWFwcGluZ3NfdGFibGUoImZvb2QiLCBkZiA9IGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IpCgojIGZyYW1lcyBhbmQgc3VibWFwcGluZ3MKZm9vZF9mcmFtZXNfc3VibWFwcGluZ3MgPC0gaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvciAlPiUgCiAgZmlsdGVyKG1ldGFwaG9ycyA9PSAnaGFwcGluZXNzIGlzIGZvb2QnKSAlPiUgCiAgY291bnQoc291cmNlX2ZyYW1lcywgc3VibWFwcGluZ3MpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGdyb3VwX2J5KHNvdXJjZV9mcmFtZXMpICU+JSAKICBtdXRhdGUocGVyYyA9IHJvdW5kKG4vc3VtKG4pICogMTAwLCAyKSkgJT4lIAogIHJlbmFtZShmcmFtZXMgPSBzb3VyY2VfZnJhbWVzKSAlPiUgCiAgdW5ncm91cCgpCgojIyBMVSB0YWJsZQpoYXBweXI6OmdldF9sdV90YWJsZSgiZm9vZCIsIGRmID0gaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvcikgJT4lCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSAnQWxsIGxleGljYWwgdW5pdHMgZXZva2luZyA8c3BhbiBzdHlsZSA9ICJmb250LXZhcmlhbnQ6c21hbGwtY2FwczsiPmhhcHBpbmVzcyBpcyBmb29kPC9zcGFuPi4nLCByb3cubmFtZXMgPSBUUlVFKQpgYGAKCjxzcGFuIHN0eWxlPSdmb250LXZhcmlhbnQ6c21hbGwtY2FwczsnPkhhcHBpbmVzcyBpcyBmb29kPC9zcGFuPiBtZXRhcGhvciBpcyBiYXNlZCBvbiBzZXZlcmFsIGZyYW1lcyByZWxhdGVkIHRvIGdhc3Ryb25vbWljYWwgZXhwZXJpZW5jZS4gVGhlc2UgaW5jbHVkZSB0aGUgPHNwYW4gc3R5bGU9J2ZvbnQtdmFyaWFudDpzbWFsbC1jYXBzJz5mb29kPC9zcGFuPiBmcmFtZSBpdHNlbGYgKGByIGZvb2RfZnJhbWVzICU+JSBmaWx0ZXIoc3RyX2RldGVjdChmcmFtZXMsICdmb29kJCcpKSAlPiUgLiRwZXJjYCUpLCA8c3BhbiBzdHlsZT0nZm9udC12YXJpYW50OnNtYWxsLWNhcHM7Jz5pbmdlc3Rpb248L3NwYW4+IChgciBmb29kX2ZyYW1lcyAlPiUgZmlsdGVyKHN0cl9kZXRlY3QoZnJhbWVzLCAnaW5nZXN0aW9uJykpICU+JSAuJHBlcmNgJSksIDxzcGFuIHN0eWxlPSdmb250LXZhcmlhbnQ6c21hbGwtY2Fwcyc+Zm9vZCBwcmVwYXJhdGlvbjwvc3Bhbj5eW1RoZSBlbnRyeSBmb3IgPHNwYW4gc3R5bGU9J2ZvbnQtdmFyaWFudDpzbWFsbC1jYXBzOyc+Zm9vZCBwcmVwYXJhdGlvbjwvc3Bhbj4gZnJhbWUgaXMgbm90IHJlcHJlc2VudGVkIGluIHRoZSAqTWV0YU5ldCogZnJhbWUgcmVwb3NpdG9yeSwgYnV0IGlzIGluY2x1ZGVkIGFzIHRoZSBzb3VyY2UgZnJhbWUgbGFiZWwgZm9yIGEgbWV0YXBob3JpY2FsIGVudGFpbG1lbnQgb2YgdGhlIDxzcGFuIHN0eWxlPSdmb250LXZhcmlhbnQ6c21hbGwtY2FwczsnPmlkZWFzIGFyZSBmb29kczwvc3Bhbj4gbWV0YXBob3IsIGkuZS4gPHNwYW4gc3R5bGU9J2ZvbnQtdmFyaWFudDpzbWFsbC1jYXBzOyc+cHJlcGFyaW5nIGlkZWFzIHRvIGJlIHVuZGVyc3Rvb2QgaXMgZm9vZCBwcmVwYXJhdGlvbjwvc3Bhbj4gKGNmLiBodHRwczovL21ldGFwaG9yLmljc2kuYmVya2VsZXkuZWR1L3B1Yi9lbi9pbmRleC5waHAvTWV0YXBob3I6UFJFUEFSSU5HX0lERUFTX1RPX0JFX1VOREVSU1RPT0RfSVNfRk9PRF9QUkVQQVJBVElPTikuIEEgcmVsYXRlZCBmcmFtZSB3aG9zZSBlbnRyeSBpcyBhdmFpbGFibGUgaW4gdGhlICpGcmFtZU5ldCogZnJhbWUgcmVwb3NpdG9yeSBpcyA8c3BhbiBzdHlsZT0nZm9udC12YXJpYW50OnNtYWxsLWNhcHM7Jz5jb29raW5nX2NyZWF0aW9uPC9zcGFuPi5dIChgciBmb29kX2ZyYW1lcyAlPiUgZmlsdGVyKHN0cl9kZXRlY3QoZnJhbWVzLCAncHJlcGFyYXRpb24nKSkgJT4lIC4kcGVyY2AlKSwgYW5kLCBtb3N0IHByZWRvbWluYW50bHksIDxzcGFuIHN0eWxlPSdmb250LXZhcmlhbnQ6c21hbGwtY2FwczsnPnRhc3RlPC9zcGFuPiAoYHIgZm9vZF9mcmFtZXMgJT4lIGZpbHRlcihzdHJfZGV0ZWN0KGZyYW1lcywgJ3Rhc3RlJykpICU+JSAuJHBlcmNgJSkuCgouLi4KCk1vc3Qgb2YgdGhlIGxleGljYWwgdW5pdHMgKExVcykgaW4gdGhpcyBmcmFtZSBwcm9maWxlcyB0aGUgc2VydmluZyBzdGFnZSBvZiB0aGUgZm9vZCBwcmVwYXJhdGlvbiAoYHIgZm9vZF9mcmFtZXNfc3VibWFwcGluZ3MgJT4lIGZpbHRlcihzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAnc2VydmluZycpKSAlPiUgLiRwZXJjYCUpCgouLi4KClRoaXMgaXMgaW5kaWNhdGVkIGVzcGVjaWFsbHkgYnkgYSBoaWdoIHByb3BvcnRpb24gb2Ygb25lIExVLCBuYW1lbHkgKm5pa21hdGkqICd0byB0YXN0ZS13aGlsZS1lbmpveWluZycsIHRha2luZyB1cCBgciBmb29kX2x1X3N1Ym1hcHBpbmdzICU+JSBmaWx0ZXIoc3RyX2RldGVjdChsdSwgIm5pa21hdGkkIikpICU+JSAuJHBlcmNfZXhwcl9vdmVyYWxsYCUgb2YgYWxsIHRva2VucyBvZiB0aGUgbWV0YXBob3IuIAoKIyMgVGhlIGNvLW9jY3VycmVuY2Ugb2YgYm9keS1wYXJ0IHRlcm1zIGFuZCB0aGUgbWV0YXBob3JzCgpgYGB7ciBiYXItcGxvdCwgZmlnLmFzcCA9IDAuN30KaGFwcHlyOjpwbG90X2JvZHlfcGFydChkZiA9IGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IpCmBgYAoKYGBge3IgYm9keS1tZXRhcGhvcnMtZnJlcXVlbmN5LXRhYmxlfQojIGJvZHktcGFydCBnbG9zcwpicF9nbG9zcyA8LSB0aWJibGUoZ2xvc3MgPSBjKCdjaGVzdC9ib3NvbScsICdzZWxmJywgJ2xpdmVyJywgJ2V5ZXMnLCAnZmFjZScsICdib2R5JywgJ2ZhY2UnLCAnZmFjZScsICdkZWVwZXN0IHBhcnQgb2YgdGhlIGhlYXJ0JywgJ2xpcHMnLCAnbW91dGgnLCAnYm9keTsgYm9kaWx5JyksIGJvZHlfcGFydF90ZXJtcyA9IGMoJ2RhZGEnLCAnZGlyaScsICdoYXRpJywgJ21hdGEnLCAnbXVrYScsICd0dWJ1aCcsICd3YWphaCcsICdwYXJhcycsICdsdWJ1ayBrYWxidScsICdiaWJpcicsICdtdWx1dCcsICdqYXNtYW5pJykpCgojIGdlbmVyYXRlIHRoZSB0YWJsZQpoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yICU+JSAKICBmaWx0ZXIoYm9keV9wYXJ0X2luY2x1c2lvbiAlaW4lIGMoJ3knKSkgJT4lIAogIGNvdW50KGJvZHlfcGFydF90ZXJtcywgbWV0YXBob3JzKSAlPiUgCiAgYXJyYW5nZShkZXNjKG4pKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBsZWZ0X2pvaW4oYnBfZ2xvc3MsIGJ5ID0gJ2JvZHlfcGFydF90ZXJtcycpICU+JQogIHNlbGVjdChtZXRhcGhvcnMsIGJvZHlfcGFydF90ZXJtcywgZ2xvc3MsIG4pICU+JSAKICBtdXRhdGUobWV0YXBob3JzID0gaGFwcHlyOjpzY2FwcyhtZXRhcGhvcnMpLCAKICAgICAgICAgYm9keV9wYXJ0X3Rlcm1zID0gcGFzdGUoIioiLCBib2R5X3BhcnRfdGVybXMsICIqICciLCBnbG9zcywgIiciLCBzZXAgPSAiIikpICU+JQogIHJlbmFtZShCb2R5X3BhcnRzID0gYm9keV9wYXJ0X3Rlcm1zLCBNZXRhcGhvcnMgPSBtZXRhcGhvcnMsIE4gPSBuKSAlPiUKICBzZWxlY3QoLWdsb3NzKSAlPiUKICB0b3BfbigxMCwgTikgJT4lCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSAnVGhlIHRlbiBtb3N0IGZyZXF1ZW50IDxzcGFuIHN0eWxlPSJmb250LXZhcmlhbnQ6c21hbGwtY2FwczsiPkJvZHktcGFydDwvc3Bhbj5gKmA8c3BhbiBzdHlsZT0iZm9udC12YXJpYW50OnNtYWxsLWNhcHM7Ij5NZXRhcGhvcnM8L3NwYW4+IGNvLW9jY3VycmVuY2UgZm9yIDxzcGFuIHN0eWxlPSJmb250LXZhcmlhbnQ6c21hbGwtY2FwczsiPkhhcHBpbmVzczwvc3Bhbj4gaW4gSW5kb25lc2lhbi4nLCByb3cubmFtZXMgPSBUUlVFKQpgYGAKCgojIENvZGVzIGZvciBDaGFwdGVyIDYgLSBQcm9kdWN0aXZlIGFuZCBDcmVhdGl2ZSBNZXRhcGhvcnMKCiMjIFByb2R1Y3RpdmUgbWV0YXBob3JzCgpgYGB7ciB0b3AtMTAtcHJvZHVjdGl2ZS1tZXRhcGhvcnN9CnByb2R1Y3RpdmVfbWV0YXBob3IgPC0gdHRyX21ldGFwaG9yICU+JSAKICBhcnJhbmdlKGRlc2ModHlwZV9sdSkpICU+JSAKICB0b3BfbigxMCwgdHlwZV9sdSkKCnByb2R1Y3RpdmVfbWV0YXBob3IgJT4lIApzZWxlY3QoTWV0YXBob3JzID0gbWV0YXBob3JzLAogICAgICAgVG9rZW4gPSB0b2tlbiwKICAgICAgIGAlVG9rZW5gID0gcGVyY190b2tlbiwKICAgICAgIFR5cGUgPSB0eXBlX2x1LAogICAgICAgYCVUeXBlYCA9IHBlcmNfdHlwZV9sdSkgJT4lIAogIGtuaXRyOjprYWJsZShjYXB0aW9uID0gJ1RvcC0xMCBtZXRhcGhvcnMgc29ydGVkIG9uIHRoZWlyIHR5cGUgZnJlcXVlbmN5LicsIHJvdy5uYW1lcyA9IFRSVUUpCmBgYAoKW1RhYmxlIFxAcmVmKHRhYjp0b3AtdHlwZS10dHIpXSgjdG9wLXR5cGUtdHRyKSBzaG93cyB0aGUgcmV2ZXJzZSByYW5raW5nIG9mIHRoZSB0b3AtMTAgbWV0YXBob3JzIHdpdGggaGlnaCB0eXBlIGZyZXF1ZW5jeSBhY2NvcmRpbmcgdG8gdGhlaXIgdHlwZS1wZXItdG9rZW4gcmF0aW8uCgpgYGB7ciB0b3AtdHlwZS10dHJ9CnByb2R1Y3RpdmVfbWV0YXBob3IgJT4lIAogIGFycmFuZ2UoZGVzYyh0eXBlX3Blcl90b2tlbl9sdSkpICU+JSAKICBzZWxlY3QoTWV0YXBob3JzID0gbWV0YXBob3JzLAogICAgICAgICBUb2tlbiA9IHRva2VuLAogICAgICAgICBUeXBlID0gdHlwZV9sdSwKICAgICAgICAgYFR5cGUvdG9rZW4gcmF0aW8gKGluICUpYCA9IHR5cGVfcGVyX3Rva2VuX2x1KSAlPiUgCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSAnTWV0YXBob3JzIHdpdGggaGlnaCB0eXBlIGZyZXF1ZW5jeSBvcmRlcmVkIGFjY29yZGluZyB0aGVpciBUeXBlL1Rva2VuIFJhdGlvIChUVFIpLicsIHJvdy5uYW1lcyA9IFRSVUUpCmBgYAoKIyMjIEhhcHBpbmVzcyBpcyBsaWdodAoKYGBge3IgaGFwcGluZXNzLWlzLWxpZ2h0LWRhdGF9CiMgc3VibWFwcGluZwpsaWdodF9zdWJtYXBwaW5nIDwtIGhhcHB5cjo6Z2V0X3N1Ym1hcHBpbmdzKCJsaWdodCIsIGRmID0gaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvcikKCiMgc3VibWFwcGluZyBnZW5lcmFsaXNlZC9zY2hlbWF0aXNlZDogKGkpIGVtaXNzaW9uIG9mIGxpZ2h0IGFuZCAoaWkpIGRhcmtlbmluZwpsaWdodF9zdWJtYXBwaW5nX2dlbmVyYWxpc2VkIDwtIGxpZ2h0X3N1Ym1hcHBpbmcgJT4lCiAgbXV0YXRlKGdlbmVyYWxpc2VkX3N1Ym1hcHBpbmdzID0gaWZfZWxzZShzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAnZGFya2VuaW5nJyksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2RhcmtlbmluZ19saWdodCcsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2VtaXR0aW5nX2xpZ2h0JykpICU+JQogIGdyb3VwX2J5KGdlbmVyYWxpc2VkX3N1Ym1hcHBpbmdzKSAlPiUgCiAgc3VtbWFyaXNlKG4gPSBzdW0obiksIAogICAgICAgICAgICB0eXBlX2dlbmVyYWxpc2VkID0gc3VtKHR5cGUpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlKHBlcmNfdHlwZV9nZW5lcmFsaXNlZCA9IHJvdW5kKHR5cGVfZ2VuZXJhbGlzZWQvc3VtKHR5cGVfZ2VuZXJhbGlzZWQpICogMTAwLCAyKSwgCiAgICAgICAgIHBlcmNfZ2VuZXJhbGlzZWQgPSByb3VuZChuL3N1bShuKSAqIDEwMCwgMikpCgojIGxleGljYWwgdW5pdCBhbmQgdGhlaXIgImVtaXR0aW5nIiBzZW1hbnRpY3MKbGlnaHRfbHVfZW1pdHRpbmdfc2VtYW50aWNzIDwtIGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IgJT4lIAogIGZpbHRlcihzdHJfZGV0ZWN0KG1ldGFwaG9ycywgImxpZ2h0IikpICU+JSAKICBzZWxlY3QobHUpCgpkaW1fbGlnaHQgPC0gYygncHVkYXInLCAna2VsYWJ1JykKYnJpZWZfbGlnaHQgPC0gYygnYmF5YW5nYW4nLCAnbWVtYmF5YW5nJywgJ3RlcmJlcnNpdCcsICdzZWJlcnNpdCcsICdzZWNlcmNhaCcsICdzZWtpbGFzJywgJ3RlcmJheWFuZycpCmJyaWdodF9saWdodCA8LSBjKCdiZXJraWxhdWFuJywgJ2JlcnNpbmFyIHRlcmFuZycsICdtZW50YXJpJywgJ3NlbWFyYWtrYW4nLCAnc2VtYnVyYXRrYW4nLCAnc2luYXJrYW4nLCAndGVyYW5naScpCgpsaWdodF9sdV9lbWl0dGluZ19zZW1hbnRpY3MgPC0gbGlnaHRfbHVfZW1pdHRpbmdfc2VtYW50aWNzICU+JQogIG11dGF0ZShsdW1pbm91c2l0eSA9IGlmX2Vsc2UobHUgJWluJSBkaW1fbGlnaHQsICdkYXJrZW5pbmcnLCAnbmV1dHJhbCcpLAogICAgICAgICBsdW1pbm91c2l0eSA9IGlmX2Vsc2UobHUgJWluJSBicmllZl9saWdodCwgJ2JyaWVmX2xpZ2h0JywgbHVtaW5vdXNpdHkpLAogICAgICAgICBsdW1pbm91c2l0eSA9IGlmX2Vsc2UobHUgJWluJSBicmlnaHRfbGlnaHQsICdzaGluaW5nX2xpZ2h0JywgbHVtaW5vdXNpdHkpKQoKIyB0ZWJlcnNpdCAtPiByYWRpYXRlcyBzdWRkZW5seSB2YWd1ZWx5CiMgc2ViZXJzaXQgLT4gcmFkaWF0ZXMgbGlnaHQgaW4gc21hbGwgYW1vdW50CiMgc2VjZXJjYWggLT4gc21hbGwgYW1vdW50IG9mIGxpZ2h0CgojIGxleGljYWwgdW5pdCB0YWJsZQpsaWdodF9sdV90YWJsZSA8LSBoYXBweXI6OmdldF9sdV90YWJsZSgibGlnaHQkIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvcF9uX29ubHkgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZiA9IGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IpCgojIG51bWJlciBvZiBoYXBheCBMVQpsaWdodF9sdV9sZW5ndGggPC0gZGltKGxpZ2h0X2x1X3RhYmxlKVsxXQpsaWdodF9oYXBheF9sZW5ndGggPC0gZGltKGZpbHRlcihsaWdodF9sdV90YWJsZSwgTiA9PSAxKSlbMV0KCiMgcHJpbnQgdGhlIGx1IHRhYmxlCmxpZ2h0X2x1X3RhYmxlICU+JQogIGtuaXRyOjprYWJsZShjYXB0aW9uID0gJ0xleGljYWwgdW5pdHMgZXZva2luZyA8c3BhbiBzdHlsZSA9ICJmb250LXZhcmlhbnQ6c21hbGwtY2FwczsiPmhhcHBpbmVzcyBpcyBsaWdodDwvc3Bhbj4nLCByb3cubmFtZXMgPSBUUlVFKQoKCmBgYAoKTW9zdCBvZiB0aGUgTFVzIChgciByb3VuZCgobGlnaHRfaGFwYXhfbGVuZ3RoL2xpZ2h0X2x1X2xlbmd0aCkgKiAxMDAsIDIpYCUgb2YgdGhlIHRvdGFsIGByIGxpZ2h0X2x1X2xlbmd0aGAgdHlwZXMpIGFyZSBzaW5nbGV0b25zIChpLmUuLCBvY2N1cnJpbmcgb25seSBvbmNlKSwgd2hpY2ggYXJlIGFsc28gdGVybWVkIGFzICpoYXBheCBsZWdvbWVuYSogb3IgKmhhcGF4ZXMqIFtAaGlscGVydF9jb25zdHJ1Y3Rpb25fMjAxNC0xLCBwLiA4Ml0uCgojIyMgSGFwcGluZXNzIGlzIGFuIGltcGVyaWxsZWQgZW50aXR5CgpgYGB7ciBoYXBwaW5lc3MtaXMtYW4taW1wZXJpbGxlZC1lbnRpdHktZGF0YX0KIyBzdWJtYXBwaW5ncwplbmRhbmdlcmVkX3N1Ym1hcHBpbmcgPC0gaGFwcHlyOjpnZXRfc3VibWFwcGluZ3MoImltcGVyaWxsZWQiLCBkZiA9IGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IpICU+JSAKICBtdXRhdGUoc3VibWFwcGluZ3MgPSBzdHJfcmVwbGFjZShzdWJtYXBwaW5ncywgImRlc3Ryb3llZCBvYmplY3QiLCAiaGFybWVkIGVudGl0eSIpKQoKIyBmcmFtZXMKZW5kYW5nZXJlZF9mcmFtZSA8LSBoYXBweXI6OmdldF9mcmFtZXMoImltcGVyaWxsZWQiLCBkZiA9IGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IpCgojIGxleGljYWwgdW5pdHMgdGFibGUKZW5kYW5nZXJlZF9sdSA8LSBoYXBweXI6OmdldF9sdV90YWJsZSgiaW1wZXJpbGxlZCIsIHRvcF9uX29ubHkgPSBUUlVFLCBkZiA9IGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IpCgplbmRhbmdlcmVkX2x1X2hhcGF4IDwtIGRpbShmaWx0ZXIoZW5kYW5nZXJlZF9sdSwgTiA9PSAxTCkpWzFdCgplbmRhbmdlcmVkX2x1ICU+JQogIGtuaXRyOjprYWJsZShjYXB0aW9uID0gJ0xleGljYWwgdW5pdHMgZXZva2luZyA8c3BhbiBzdHlsZSA9ICJmb250LXZhcmlhbnQ6c21hbGwtY2FwczsiPmhhcHBpbmVzcyBpcyBhbiBpbXBlcmlsbGVkIGVudGl0eTwvc3Bhbj4nLCByb3cubmFtZXMgPSBUUlVFKQpgYGAKClRoZSBgciBoYXBweXI6OnNjYXBzKCJoYXBwaW5lc3MgaXMgYW4gaW1wZXJpbGxlZCBlbnRpdHkiKWAgbWFrZXMgdXNlIG9mIGVsZW1lbnRzIGZyb20gc2V2ZXJhbCBmcmFtZXMgdGhhdCBicm9hZGx5IGJlbG9uZyB0byB0aGUgYHIgaGFwcHlyOjpzY2FwcygiaGFybSIpYCBmcmFtZSBmYW1pbHkgW2NmLiBAZG9kZ2VfZGVlcF8yMDE2LCBwcC4gMjgyLTI4Nl0gKHNlZSBhbHNvIGRpc2N1c3Npb24gaW4gYHIgc2VjdGlvbmAgWFhYIGJlbG93KS4gVGhlc2UgZnJhbWVzIGluY2x1ZGUgYHIgaGFwcHlyOjpzY2FwcygiZGVzdHJveWluZyIpYCAoYHIgZW5kYW5nZXJlZF9mcmFtZSAlPiUgZmlsdGVyKHN0cl9kZXRlY3QoZnJhbWVzLCAnZGVzdHJveScpKSAlPiUgLiRwZXJjYCUpLCBgciBoYXBweXI6OnNjYXBzKCJwcm90ZWN0aW5nIilgIChgciBlbmRhbmdlcmVkX2ZyYW1lICU+JSBmaWx0ZXIoc3RyX2RldGVjdChmcmFtZXMsICdwcm90ZWN0aW5nJykpICU+JSAuJHBlcmNgJSksIGByIGhhcHB5cjo6c2NhcHMoImRhbmdlciIpYCAoYHIgZW5kYW5nZXJlZF9mcmFtZSAlPiUgZmlsdGVyKHN0cl9kZXRlY3QoZnJhbWVzLCAnZGFuZ2VyJykpICU+JSAuJHBlcmNgJSksIGByIGhhcHB5cjo6c2NhcHMoInJlanV2ZW5hdGlvbiIpYCAoYHIgZW5kYW5nZXJlZF9mcmFtZSAlPiUgZmlsdGVyKHN0cl9kZXRlY3QoZnJhbWVzLCAncmVqdXZlJykpICU+JSAuJHBlcmNgJSksIGFuZCBgciBoYXBweXI6OnNjYXBzKCJpbXBhY3QiKWAgKGByIGVuZGFuZ2VyZWRfZnJhbWUgJT4lIGZpbHRlcihzdHJfZGV0ZWN0KGZyYW1lcywgJ2ltcGFjdCcpKSAlPiUgLiRwZXJjYCUpLiBUaGVzZSBmcmFtZXMgYXJlIGF2YWlsYWJsZSBpbiB0aGUgKk1ldGFOZXQqIGZyYW1lIHJlcG9zaXRvcnksIGV4Y2VwdCBmb3IgYHIgaGFwcHlyOjpzY2FwcygicmVqdXZlbmF0aW9uIilgIHdoaWNoIGlzIHRha2VuIGZyb20gdGhlICpGcmFtZU5ldCogcmVwb3NpdG9yeS4KCi4uLgoKSW5mZXJlbmNlIGZyb20gdGhlIGNvbnN0aXR1dGluZyBmcmFtZXMgY29udHJpYnV0ZXMgcXVpdGUgcmljaCBtZXRhcGhvcmljYWwgY29uc3RydWFsIHJlbGF0ZWQgdG8gdGhlIGFib3ZlIG1haW4gdGhlbWUuIFRoZSBwcmVkb21pbmFudCBzdWJtYXBwaW5nLCBuYW1lbHkgYHIgaGFwcHlyOjpzY2FwcygibmVnYXRpdmVseSBhZmZlY3RpbmcgaGFwcGluZXNzIGlzIGhhcm1pbmcgYW4gZW50aXR5IilgIChgciBlbmRhbmdlcmVkX3N1Ym1hcHBpbmcgJT4lIGZpbHRlcihwZXJjID09IG1heChwZXJjKSkgJT4lIC4kcGVyY2AlKSBtYWtlcyB1c2Ugb2YgdGhlIEhhcm1mdWxfZWZmZWN0X3Byb2Nlc3Mgcm9sZSBvZiB0aGUgYHIgaGFwcHlyOjpzY2FwcygicGh5c2ljYWwgaGFybSIpYCBmcmFtZS4KCi4uLgoKRnVydGhlciBpbmZlcmVuY2UgZnJvbSB0aGlzIGByIGhhcHB5cjo6c2NhcHMoImhhcm0iKWAgbWV0YXBob3IgbW9kZWwgaXMgdGhhdCB0aGUgcmVzdWx0cyBvZiB0aGUgaGFybWZ1bCBhY3Rpb24gY2FuIGJlIGEgY29tcGxldGUgZHlzZnVuY3Rpb24gb3IgdW5kZXNpcmFibGUgY29uZGl0aW9uIG9mIHRoZSBlbnRpdHkgKGUuZy4sIGJlaW5nIGRlc3Ryb3llZCkuIFRoaXMga25vd2xlZGdlIGlzIGNhcnJpZWQgb3ZlciB0byB0aGUgdGFyZ2V0IGRvbWFpbiB0byBjb25jZXB0dWFsaXNlIHRoZSBjb21wbGV0ZSBjZWFzaW5nIG9mIGByIGhhcHB5cjo6c2NhcHMoImhhcHBpbmVzcyIpYC4gSGVuY2UsIGByIGVuZGFuZ2VyZWRfc3VibWFwcGluZyAlPiUgZmlsdGVyKHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICdeZW5kIG9mJykpICU+JSAuWywxXSAlPiUgdW5saXN0KCkgJT4lIHVubmFtZSgpICU+JSBoYXBweXI6OnNjYXBzKClgIChgciBlbmRhbmdlcmVkX3N1Ym1hcHBpbmcgJT4lIGZpbHRlcihzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAnZW5kIG9mJykpICU+JSAuJHBlcmNgJSkgc3VibWFwcGluZy4KCi4uLgoKVGhlIHR3aXN0cyBvZiB0aGVzZSBuZWdhdGl2ZSBjb25zZXF1ZW5jZXMgbWF5IGluY2x1ZGUgdHdvIHNjZW5hcmlvcyB0aGF0IGNhbiBiZSByZWNhc3QgYXMgdHdvIHN1Ym1hcHBpbmdzLiBUaGUgZmlyc3QgaXMgYHIgaGFwcHlyOjpzY2FwcygibWFpbnRhaW5pbmcgaGFwcGluZXNzIGlzIHByb3RlY3RpbmcgYW4gYXNzZXQiKWAgKGByIGVuZGFuZ2VyZWRfc3VibWFwcGluZyAlPiUgZmlsdGVyKHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICdebWFpbnRhaW4nKSkgJT4lIC4kcGVyY2AlKTsgdGhlIHNlY29uZCBpcyBgciBoYXBweXI6OnNjYXBzKCJyZXN0b3JpbmcgaGFwcGluZXNzIGlzIHJlcGFpcmluZyBhIGhhcm1lZCBlbnRpdHkiKWAgKGByIGVuZGFuZ2VyZWRfc3VibWFwcGluZyAlPiUgZmlsdGVyKHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICdecmVzdG9yaW5nJykpICU+JSAuJHBlcmNgJSkuIFRoZXNlIHNjZW5hcmlvcyBzdWdnZXN0IHRoZSBpbXBvcnRhbmNlIGZvciB0aGUgZXhwZXJpZW5jZXIgdG8gbG9vayBhZnRlciBhbmQgbWFpbnRhaW4gaChpcy9lcikgd2VsbC1iZWluZy4KCi4uLgoKTW9zdCBvZiB0aGUgTFVzIGZvciBgciBoYXBweXI6OnNjYXBzKCJoYXBwaW5lc3MgaXMgYW4gaW1wZXJpbGxlZCBlbnRpdHkiKWAgb2NjdXIgb25seSBvbmNlIChgciByb3VuZChlbmRhbmdlcmVkX2x1X2hhcGF4L2RpbShlbmRhbmdlcmVkX2x1KVsxXSAqIDEwMCwgMilgJSBvZiB0aGUgdG90YWwgYHIgZGltKGVuZGFuZ2VyZWRfbHUpWzFdYCBMVSB0eXBlcykuCgojIyBDcmVhdGl2ZSBtZXRhcGhvcnMKCmBgYHtyIHRvcC10eXBlLXRva2VuLXJhdGlvLW1ldGFwaG9yc30KbGVzc190aGFudGhyZWVfbWV0YXBob3JzIDwtIHR0cl9tZXRhcGhvciAlPiUgCiAgZmlsdGVyKHRva2VuIDw9IDJMKSAlPiUgCiAgLiRtZXRhcGhvcnMKCm1pbl9mcmVxIDwtIDNMCgpjcmVhdGl2ZV9tZXRhcGhvcnMgPC0gaGFwcHlyOjpnZXRfY3JlYXRpdmVfbWV0YXBob3JzKHR0cl9tZXRhcGhvcikKCmNyZWF0aXZlX21ldGFwaG9ycyAlPiUKICBtdXRhdGUobWV0YXBob3JzID0gaGFwcHlyOjpzY2FwcyhtZXRhcGhvcnMpKSAlPiUgCiAgc2VsZWN0KE1ldGFwaG9ycyA9IG1ldGFwaG9ycywKICAgICAgICAgVG9rZW4gPSB0b2tlbiwKICAgICAgICAgVHlwZSA9IHR5cGVfbHUsCiAgICAgICAgIGBUeXBlL3Rva2VuIHJhdGlvIChpbiUpYCA9IHR5cGVfcGVyX3Rva2VuX2x1KSAlPiUgCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSBwYXN0ZSgnVG9wLTEwIGxleGljYWxseSB2YXJpZWQgbWV0YXBob3JzIHNvcnRlZCBiYXNlZCBvbiB0aGUgVFRSIHZhbHVlIGFuZCBvY2N1cnJpbmcgYXQgbGVhc3QgJywgaGFwcHlyOjpudW1iZXJzMndvcmRzKG1pbl9mcmVxKSwgJyB0b2tlbnMuJywgc2VwID0gIiIpLCByb3cubmFtZXMgPSBUUlVFKQpgYGAKCiMjIyBIYXBwaW5lc3MgaXMgYSBoYXJtZnVsIGFnZW50CgpgYGB7ciBoYXBwaW5lc3MtaXMtYS1oYXJtZnVsLWFnZW50LWRhdGF9CiMgc3VibWFwcGluZ3MKaGFybWZ1bF9zdWJtYXBwaW5ncyA8LSBoYXBweXI6OmdldF9zdWJtYXBwaW5ncygiaGFybWZ1bCBhZ2VudCIsIGRmID0gaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvcikKCiMgZnJhbWVzCmhhcm1mdWxfZnJhbWVzIDwtIGhhcHB5cjo6Z2V0X2ZyYW1lcygiaGFybWZ1bCBhZ2VudCIsIGRmID0gaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvcikKCmhhcm1mdWxfbHUgPC0gaGFwcHlyOjpnZXRfbHVfdGFibGUoImhhcm1mdWwgYWdlbnQiLCBkZiA9IGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IpCgpoYXJtZnVsX2x1ICU+JSAKICBrbml0cjo6a2FibGUoY2FwdGlvbiA9IHBhc3RlKCJMZXhpY2FsIHVuaXRzIGV2b2tpbmcgIiwgaGFwcHlyOjpzY2FwcygiaGFwcGluZXNzIGlzIGEgaGFybWZ1bCBhZ2VudCIpLCBzZXAgPSAiIiksIHJvdy5uYW1lcyA9IFRSVUUpCmBgYAoKVGhlIHByZWRvbWluYW50IHN1Ym1hcHBpbmcgaXMgYHIgaGFwcHlyOjpzY2FwcygiZXhwZXJpZW5jaW5nIGludGVuc2UgZW1vdGlvbiBpcyBiZWluZyBoYXJtZWQiKWAgb3IgYHIgaGFwcHlyOjpzY2Fwcygic3Ryb25nIGVtb3Rpb25hbCBlZmZlY3QgaXMgcGh5c2ljYWwgaGFybSIpYCAoYHIgZmlsdGVyKGhhcm1mdWxfc3VibWFwcGluZ3MsIHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICJiZWluZyBoYXJtZWQiKSlbWyJwZXJjIl1dYCUgb2YgdGhlIHRvdGFsIGByIHN1bShoYXJtZnVsX2ZyYW1lcyRuKWAgdG9rZW5zIG9mIHRoZSBtZXRhcGhvcikuCgojIyMgTmVnYXRpdmUgY29uc3RydWFsIG9mIGByIGhhcHB5cjo6c2NhcHMoImhhcHBpbmVzcyIpYAoKIyMjIyBIYXBwaW5lc3MgaXMgYW4gYWR2ZXJzYXJ5CgpgYGB7ciBoYXBwaW5lc3MtaXMtYW4tYWR2ZXJzYXJ5fQojIGRhdGEgZnJhbWUgb24gdGhlIG9wcG9uZW50IHR5cGUgaW4gdGhlIGFkdmVyc2FyeSBtZXRhcGhvcgphZHZlcnNhcnlfZGYgPC0gdHJpYmJsZSgKICB+b3Bwb25lbnQsIH5vcHBvbmVudF9sdSwgfm1fZXhwciwKICAjLS0vLS0KICAgInNlbGYiLCAicGVyc19wcm9ub3VuIiwgImRpdWppIGRlbmdhbiBOUCIsCiAgICJzZWxmX2ltcGwiLCBOQSwgImRpdWppIGRlbmdhbiBOUCIsCiAgICJhYnN0cmFjdF9zdGF0ZXNfaW1wbCIsIE5BLCAiZG9taW5hc2kgTlAiLAogICAiYWJzdHJhY3RfZW50aXR5IiwgInByYW11a2EiLCAia2FsYWggZGVuZ2FuIE5QIiwKICAgInNlbGYiLCAicGVyc19wcm9ub3VuIiwgImtlbGVtYWhhbiB0ZXJoYWRhcCBOUCIsCiAgICJjb25jcmV0ZSIsICJrb25kb20iLCAibWVsYXdhbiBOUCIsCiAgICJzZWxmIiwgInByb3Blcl9uYW1lIiwgIm1lbmFrbHVra2FuIHJheXVhbiBOUCIsCiAgICJzZWxmX2ltcGwiLCBOQSwgIm1lbmVrYW4gTlAiLAogICAic2VsZl9pbXBsIiwgTkEsICJtZW5lbnRhbmcgTlAiLAogICAic2VsZiIsICJwZXJzX3Byb25vdW4iLCAibWVuZ2hhZGFwaSBOUCIsCiAgICJzZWxmX2ltcGwiLCBOQSwgIk5QIGFkYWxhaCBtdXN1aCIsCiAgICJzZWxmX2ltcGwiLCBOQSwgIk5QIGFkYWxhaCB1amlhbiIsCiAgICJhYnN0cmFjdF9lbnRpdHkiLCAia2VoaWR1cGFuIiwgIk5QIGFuY2FtYW4ga2VwYWRhIGtlaGlkdXBhbiIsCiAgICJhYnN0cmFjdF9zdGF0ZXMiLCAia2VnZXRpcmFuIiwgIk5QIGRhbiBrZWdldGlyYW4gYmVyZWJ1dCB0ZW1wYXQgZGFsYW0gaml3YSIsCiAgICJhYnN0cmFjdF9zdGF0ZXMiLCAia2VwYWhpdGFuIGhpZHVwIiwgIk5QIGRpa2FsYWhrYW4gb2xlaCBrZXBhaGl0YW4gaGlkdXAiLAogICAiYWJzdHJhY3Rfc3RhdGVzX2ltcGwiLCBOQSwgIk5QIG1lbmRvbWluYXNpIiwKICAgImFic3RyYWN0X3N0YXRlcyIsICJrZXJlbmRhaGFuIGhhdGkiLCAiTlAgbWVuZWt1ayBrZXJlbmRhaGFuIGhhdGkiLAogICAiYWJzdHJhY3Rfc3RhdGVzIiwgImtlcmFndWFuIiwgIk5QIG1lbmdhbGFoa2FuIGtlcmFndWFuIiwKICAgImFic3RyYWN0X3N0YXRlcyIsICJyYXNhIGxlbGFoIiwgIk5QIG1lbmdhdGFzaSByYXNhIGxlbGFoIiwKICAgInNlbGYiLCAicGVyc19wcm9ub3VuIiwgIk5QIFggaGFkYXBpIiwKICAgImFic3RyYWN0X3N0YXRlcyIsICJrZWxlbGFoYW4iLCAiTlAgeWFuZyBtZW5nYXRhc2kga2VsZWxhaGFuIiwKICAgImFic3RyYWN0X3N0YXRlcyIsICJrZWJ1dHVoYW4iLCAicGVydGVudGFuZ2FuIGFudGFyYSBOUCBkYW4ga2VidXR1aGFuIiwKICAgInNlbGYiLCAib3JhbmciLCAidWppYW4gTlAiLAogICAic2VsZl9pbXBsIiwgImVuZXJneSIsICJOUCBtZW55ZWRvdCBlbmVyZ2kiCikKCiMgZGF0YSBvbmx5IGZvciBzZWxmLW9wcG9uZW50IG9mIHRoZSBlbW90aW9uCnNlbGZfb3Bwb25lbnQgPC0gYWR2ZXJzYXJ5X2RmICU+JSAKICBmaWx0ZXIoc3RyX2RldGVjdChvcHBvbmVudCwgJ3NlbGYnKSkgJT4lIAogIGNvdW50KG9wcG9uZW50KSAlPiUgCiAgbXV0YXRlKHBlcmMgPSByb3VuZChuL3N1bShuKSoxMDAsIDIpKQoKIyBvcHBvbmVudCB0eXBlcyBhbGwKb3Bwb25lbnQgPC0gYWR2ZXJzYXJ5X2RmICU+JSAKICBjb3VudChvcHBvbmVudCkgJT4lIAogIGFycmFuZ2UoZGVzYyhuKSkgJT4lIAogIG11dGF0ZShnZW5lcmljX29wcG9uZW50ID0gaWZfZWxzZShzdHJfZGV0ZWN0KG9wcG9uZW50LCAnYWJzdHJhY3QnKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdhYnN0cmFjdF9lbnRpdHkvc3RhdGVzJywgJ3NlbGYnKSwgCiAgICAgICAgIGdlbmVyaWNfb3Bwb25lbnQgPSBpZl9lbHNlKHN0cl9kZXRlY3Qob3Bwb25lbnQsICdjb25jcmV0ZScpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ290aGVyX2NvbmNyZXRlX2VudGl0eScsIGdlbmVyaWNfb3Bwb25lbnQpKSAlPiUgCiAgZ3JvdXBfYnkoZ2VuZXJpY19vcHBvbmVudCkgJT4lIAogIHN1bW1hcmlzZShuID0gc3VtKG4pKSAlPiUKICBtdXRhdGUocGVyYyA9IHJvdW5kKG4vc3VtKG4pKjEwMCwgMikpCgojIG9wcG9uZW50IHR5cGVzICJzZWxmIiB2cyAib3RoZXJzIgpvcHBvbmVudDIgPC0gb3Bwb25lbnQgJT4lIAogIG11dGF0ZShnZW5lcmljX29wcG9uZW50ID0gcmVwbGFjZShnZW5lcmljX29wcG9uZW50LCAhc3RyX2RldGVjdChnZW5lcmljX29wcG9uZW50LCAnc2VsZicpLCAnbm9uLXNlbGYnKSkgJT4lIAogIGdyb3VwX2J5KGdlbmVyaWNfb3Bwb25lbnQpICU+JSAKICBzdW1tYXJpc2UobiA9IHN1bShuKSkgJT4lIAogIG11dGF0ZShwZXJjID0gcm91bmQobi9zdW0obikqMTAwLCAyKSkKCiMgcHJpbnQgdGhlIExVIGZvciB0aGUgYWR2ZXJzYXJ5IG1ldGFwaG9yCmhhcHB5cjo6Z2V0X2x1X3RhYmxlKCJhZHZlcnNhcnkiLCBkZiA9IGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IpICU+JSAKICBrbml0cjo6a2FibGUoY2FwdGlvbiA9IHBhc3RlKCJMZXhpY2FsIHVuaXRzIGV2b2tpbmcgIiwgaGFwcHlyOjpzY2FwcygiaGFwcGluZXNzIGlzIGFuIGFkdmVyc2FyeSIpLCBzZXAgPSAiIiksIHJvdy5uYW1lcyA9IFRSVUUpCmBgYAoKSG93ZXZlciwgdGhpbmdzIGFyZSBub3QgYWx3YXlzIGFzIG5lYXQgYXMgaW4gdGhlIHRoZW9yeSB3aGVuIGxvb2tpbmcgYXQgdGhlIHJlYWwgdXNhZ2UgZGF0YS4gRnJvbSBgciBzdW0oaGFwcHlyOjpnZXRfbHVfdGFibGUoImFkdmVyc2FyeSIsIGRmID0gaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvcilbWyJOIl1dKWAgdG9rZW5zIG9mIDxzcGFuIHN0eWxlPSJmb250LXZhcmlhbnQ6c21hbGwtY2FwczsiPmhhcHBpbmVzcyBpcyBhbiBhZHZlcnNhcnk8L3NwYW4+LCBgciBpZl9lbHNlKGZpbHRlcihvcHBvbmVudDIsIGdlbmVyaWNfb3Bwb25lbnQgPT0gInNlbGYiKVtbInBlcmMiXV0gPT0gNTAsICJoYWxmIiwgcGFzdGUoYXMuY2hhcmFjdGVyKGZpbHRlcihvcHBvbmVudDIsIGdlbmVyaWNfb3Bwb25lbnQgPT0gInNlbGYiKVtbInBlcmMiXV0pLCAiJSIsIHNlcCA9ICIiKSlgIG9mIHRoZSB0b2tlbnMgaW5kaWNhdGUgdGhhdCB0aGUgb3Bwb25lbnQgY2FuIGluZGVlZCBiZSB1bmRlcnN0b29kIGFzIHRoZSBFeHBlcmllbmNlci4KCiMjIyMgSGFwcGluZXNzIGlzIGEgZGVjZWl2ZXIKCmBgYHtyIGhhcHBpbmVzcy1pcy1hLWRlY2VpdmVyLWRhdGF9CiMgcHJpbnQgdGhlIExVCmhhcHB5cjo6Z2V0X2x1X3RhYmxlKCJkZWNlaXZlciIsIGRmID0gaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvcikgJT4lIAogIGtuaXRyOjprYWJsZShjYXB0aW9uID0gcGFzdGUoIkFsbCBsZXhpY2FsIHVuaXRzIGV2b2tpbmcgIiwgaGFwcHlyOjpzY2FwcygiaGFwcGluZXNzIGlzIGEgZGVjZWl2ZXIiKSwgc2VwID0gIiIpLCByb3cubmFtZXMgPSBUUlVFKQpgYGAKCgojIyMjIEhhcHBpbmVzcyBpcyBkcnVncwoKLSBObyBpbmxpbmUgY29tcHV0YXRpb24gY29kZSBpcyBuZWVkZWQKCiMjIyMgSGFwcGluZXNzIGlzIGltcGVkaW1lbnQgdG8gbW90aW9uCgpgYGB7ciBtb3Rpb24taW1wZWRpbWVudHMtZGF0YX0KIyBzdWJtYXBwaW5nCm1vdGlvbl9pbXBlZF9zdWJtYXBwaW5ncyA8LSBoYXBweXI6OmdldF9zdWJtYXBwaW5ncygiaW1wZWRpbWVudCB0byBtb3Rpb24kIiwgZGYgPSBoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yKQpgYGAKCkFsbCB0aGVzZSBpbmZlcmVuY2VzIGV4cHJlc3MgdGhlIHN1Ym1hcHBpbmcgYHIgaGFwcHlyOjpzY2FwcygiaGFwcGluZXNzL2JlaW5nIGhhcHB5IGlzIGJlaW5nIHJlc3RyYWluZWQiKWAsIHdoaWNoIGlzIHRoZSBtb3N0IGZyZXF1ZW50IG9mIGFsbCBjYXNlcyAoYHIgZmlsdGVyKG1vdGlvbl9pbXBlZF9zdWJtYXBwaW5ncywgc3RyX2RldGVjdChzdWJtYXBwaW5ncywgInJlc3RyYWluZWQiKSlbWyJwZXJjIl1dYCUgb2YgdGhlIHRvdGFsIHRva2VucyBvZiB0aGUgbWV0YXBob3IpLgoKLi4uCgpUaGUgb3RoZXIgZXhwcmVzc2lvbnMgZXZva2UgYSBzdWJtYXBwaW5nIGJhc2VkIG9uIHRoZSBgciBoYXBweXI6OnNjYXBzKCJidXJkZW4iKWAgZnJhbWUgKGByIGZpbHRlcihtb3Rpb25faW1wZWRfc3VibWFwcGluZ3MsIHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICJidXJkZW4iKSlbWyJwZXJjIl1dYCUpIGFuZCB0aGUgYHIgaGFwcHlyOjpzY2FwcygibW90aW9uLWFmZmVjdGluZyBwcm9wZXJ0aWVzIG9mIHRoZSBsYW5kc2NhcGUiKWAgZnJhbWUgKGByIGZpbHRlcihtb3Rpb25faW1wZWRfc3VibWFwcGluZ3MsIHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICJpbXBlZGluZyIpKVtbInBlcmMiXV1gJSksIHRoZSBsYXR0ZXIgb2Ygd2hpY2ggaXMgdGhlIHNpc3RlciBmcmFtZSBvZiB0aGUgYHIgaGFwcHlyOjpzY2FwcygibW90aW9uLWFmZmVjdGluZyBvYmplY3RzIilgIGZyYW1lLgoKIyMjIFBvc2l0aXZlIHBoZW5vbWVub2xvZ3kgb2YgYHIgaGFwcHlyOjpzY2FwcygiaGFwcGluZXNzIilgCgojIyMjIEhhcHBpbmVzcyBpcyBiZWluZyBzb2FrZWQKCmBgYHtyIGJlaW5nLXNvYWtlZC1kYXRhfQpoYXBweXI6OmdldF9sdV90YWJsZSgic29ha2VkIiwgZGYgPSBoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yKSAlPiUgCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSBwYXN0ZSgiQWxsIGxleGljYWwgdW5pdHMgZXZva2luZyAiLCBoYXBweXI6OnNjYXBzKCJoYXBwaW5lc3MgaXMgYmVpbmcgc29ha2VkIiksIHNlcCA9ICIiKSwgcm93Lm5hbWVzID0gVFJVRSkKYGBgCgojIyMjIEhhcHBpbmVzcyBpcyBhIHRyZWF0bWVudCB0b29sCgotIG5vIGlubGluZSBjb21wdXRhdGlvbiBjb2RlIGlzIG5lZWRlZAoKIyMjIyBIYXBwaW5lc3MgaXMgYSByZXNvdXJjZQoKYGBge3IgaGFwcGluZXNzLWlzLWEtcmVzb3VyY2UtZGF0YX0KIyBzdWJtYXBwaW5ncwpyZXNvdXJjZV9zdWJtYXBwaW5ncyA8LSBoYXBweXI6OmdldF9zdWJtYXBwaW5ncygicmVzb3VyY2UkIiwgZGYgPSBoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yKQoKIyBsZXhpY2FsIHVuaXQgdGFibGUKcmVzb3VyY2VfbHUgPC0gaGFwcHlyOjpnZXRfbHVfdGFibGUoInJlc291cmNlJCIsIGRmID0gaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvcikKCiMgcHJpbnQgd2l0aCBga2FibGUoKWAKcmVzb3VyY2VfbHUgJT4lIAogIGtuaXRyOjprYWJsZShjYXB0aW9uID0gcGFzdGUoIkFsbCBsZXhpY2FsIHVuaXRzIGV2b2tpbmcgIiwgaGFwcHlyOjpzY2FwcygiaGFwcGluZXNzIGlzIGEgcmVzb3VyY2UiKSwgc2VwID0gIiIpLCByb3cubmFtZXMgPSBUUlVFKQpgYGAKCiMjIyBPdGhlciBjcmVhdGl2ZSBtZXRhcGhvcnMKCiMjIyMgSGFwcGluZXNzIGlzIGEgbW92ZWQgZW50aXR5CgouLi4KCkluIHRoYXQgZm9yY2VkIG1vdmVtZW50IHNjZW5hcmlvLCB0aGUgYHIgaGFwcHlyOjpzY2FwcygiaGFwcGluZXNzIGlzIGEgbW92ZWQgZW50aXR5IilgIG1ldGFwaG9yIGlzIG1vdGl2YXRlZCBieSB0aGUgcm9sZS1tYXBwaW5nIG9mIHRoZSBgciBoYXBweXI6OnNjYXBzKCJoYXBwaW5lc3MiKWAgbm91biBvbnRvIHRoZSBNb3ZlciByb2xlLiBUaGVyZSBhcmUgb25seSBgciBoYXBweXI6OmdldF9mcmFtZXMoIm1vdmVkIGVudGl0eSQiLCBkZiA9IGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IpICU+JSAuJG4gJT4lIGhhcHB5cjo6bnVtYmVyczJ3b3JkcygpYCB0b2tlbnMgZm9yIHRoaXMgbWFwcGluZy4KCi4uLgoKIyMjIyBIYXBwaW5lc3MgaXMgYW4gYWNjb21wYW5pZWQgb2JqZWN0CgouLi4KClRoZXJlIGFyZSBvbmx5IGByIHR0cl9tZXRhcGhvciAlPiUgZmlsdGVyKHN0cl9kZXRlY3QobWV0YXBob3JzLCAiYWNjb21wYW5pZWQgb2JqZWN0JCIpKSAlPiUgLiR0b2tlbiAlPiUgaGFwcHlyOjpudW1iZXJzMndvcmRzKClgIHRva2VucyBmb3IgYHIgc2NhcHMoImhhcHBpbmVzcyBpcyBhbiBhY2NvbXBhbmllZCBvYmplY3QiKWAuCgojIENvZGVzIGZvciBDaGFwdGVyIDcgLSBEaXN0aW5jdGl2ZSBtZXRhcGhvcnMgZm9yIGByIGhhcHB5cjo6c2NhcHMoImhhcHBpbmVzcyIpYCBuZWFyLXN5bm9ueW1zIGluIEluZG9uZXNpYW4KCiMjIE11bHRpcGxlIGRpc3RpbmN0aXZlIGNvbGxleGVtZSBhbmFseXNpcyBpbiBhY3Rpb24KCmBgYHtyIG1kY2EtbWV0YXBob3Itc3lub255bXN9CiMgTURDQSBmb3IgbWV0YXBob3IgKiBzeW5vbnltcyB3aXRoIGNvbmNpc2Ugb3V0cHV0Cm1kY2FfcmVzIDwtIGhhcHB5cjo6bWRjYShkZiA9IGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IsIGNvbmNpc2Vfb3V0cHV0ID0gVFJVRSkKCiMgTURDQSBmb3IgbWV0YXBob3IgKiBzeW5vbnltcyB3aXRoIGZ1bGwgb3V0cHV0IChpLmUuLCBpbmNsdWRlIGV4cF9wcm9iYWJpbGl0eSwgc3lub255bXMgZnJlcXVlbmN5KTsgdGhpcyBpcyBmb3IgdGhlIHB1cnBvc2Ugb2YgaWxsdXN0cmF0aW5nIHRoZSBNRENBIGluIHRoZSBjaGFwdGVyCm1kY2FfcmVzX2Z1bGwgPC0gaGFwcHlyOjptZGNhKGRmID0gaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvciwgY29uY2lzZV9vdXRwdXQgPSBGQUxTRSkKCiMgZ2xvc3MgdGFibGUgZm9yIHN5bm9ueW1zCnN5bl9nbG9zcyA8LSB0cmliYmxlKH5zeW5vbnltcywgfmdsb3NzLCB+Zm9ybSwgfnNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgInJpYW5nIiwgInZlcnkgaGFwcHksIGpveW91cywgZ2xhZCIsICJyb290IiwgIlMmU1QuMjAwNC5wLjgzMCIsCiAgICAgICAgICAgICAgICAgICAgICJnZW1iaXJhIiwgImV4Y2l0ZWQsIGVudGh1c2lhc3RpYywgZXh1YmVyYW50LCAuLi4iLCAicm9vdCIsICJTJlNULjIwMDQucC4zMTEiLAogICAgICAgICAgICAgICAgICAgICAiY2VyaWEiLCAicHVyZSwgY2xlYW4sIGNsZWFyOyBjaGVlcmZ1bCIsICJyb290IiwgIlMmU1QuMjAwNC5wLjE5OCIsCiAgICAgICAgICAgICAgICAgICAgICJiYWhhZ2lhIiwgIihwZWFjZWZ1bCBhbmQpIGhhcHB5OyBoYXBwaW5lc3M7IGx1Y2soeSksIGdvb2QgZm9ydHVuZTsgd2VsZmFyZSIsICJyb290IiwgIlMmU1QuMjAwNC5wLjc1IiwKICAgICAgICAgICAgICAgICAgICAgInNlbmFuZyIsICJoYXBweSwgdG8gZmVlbCB3ZWxsLCBjb250ZW50ZWQsIHNhdGlzZmllZCIsICJyb290IiwiUyZTVC4yMDA0LnAuOTA5IiwKICAgICAgICAgICAgICAgICAgICAgImtlcmlhbmdhbiIsICJjaGVlcihmdWxuZXNzKSwgaGFwcGluZXNzLCBqb3kiLCAibm9taW5hbGlzZWQiLCAiUyZTVC4yMDA0LnAuODMwIiwKICAgICAgICAgICAgICAgICAgICAgImtlY2VyaWFhbiIsICJwdXJpdHk7IGNoZWVyZnVsbmVzcyIsICJub21pbmFsaXNlZCIsIlMmU1QuMjAwNC5wLjE5OCIsCiAgICAgICAgICAgICAgICAgICAgICJrZWJhaGFnaWFhbiIsICJoYXBwaW5lc3MsIHByb3NwZXJpdHkgYW5kIGNvbnRlbnRtZW50IiwgIm5vbWluYWxpc2VkIiwiUyZTVC4yMDA0LnAuNzUiLAogICAgICAgICAgICAgICAgICAgICAia2VnZW1iaXJhYW4iLCAiam95LCBjaGVlcmZ1bG5lc3MsIGhpZ2ggc3Bpcml0cyIsICJub21pbmFsaXNlZCIsIlMmU1QuMjAwNC5wLjMxMSIsCiAgICAgICAgICAgICAgICAgICAgICJrZXNlbmFuZ2FuIiwgInBsZWFzdXJlLCBoYXBwaW5lc3MsIGVuam95bWVudCwgLi4uIiwgIm5vbWluYWxpc2VkIiwgIlMmU1QuMjAwNC5wLjkwOSIpICU+JQogIHNlbGVjdChzeW5vbnltcywgZm9ybSwgZ2xvc3MsIHNvdXJjZSkgJT4lCiAgYXJyYW5nZShkZXNjKGZvcm0pLCBzeW5vbnltcykKYGBgCgpgYGB7ciBtZGNhLWNvbGxvY2F0ZXMtc3lub255bXN9CiMgbWRjYSBmb3Igd2luZG93LXNwYW4gY29sbG9jYXRpb25hbCBkYXRhCm1kY2FfY29sbG9jIDwtIGhhcHB5cjo6bWRjYShkZiA9IGhhcHB5cjo6Y29sbG9jX2lucHV0X2RhdGEsIGNvbGxfdmFyID0gImNvbGxvY2F0ZXMiKQpgYGAKCmBgYHtyIGlsbHVzdHJhdGlvbi1kYXRhLWZvci1tZGNhfQojIHJldHJpZXZlIHRoZSBleGFtcGxlIHRhYmxlCmV4YW1wbGVfZGYgPC0gbWRjYV9yZXMgJT4lIAogIGZpbHRlcihzdHJfZGV0ZWN0KG1ldGFwaG9ycywgImRlc2lyZWQiKSkgJT4lIAogIHNlbGVjdCgtbWV0YXBob3JzKSAlPiUgCiAgYXJyYW5nZShkZXNjKGFzc29jc3RyKSkKCiMgY291bnQgdGhlIGZyZXEgb2YgdGhlIG1ldGFwaG9ycwptZXRhcGhvcl90b2tlbiA8LSBkcGx5cjo6Y291bnQoaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvciwgbWV0YXBob3JzLCBzb3J0ID0gVFJVRSkKCiMgY291bnQgdGhlIGZyZXEgb2YgdGhlIHN5bm9ueW1zCnN5bm9ueW1fdG9rZW4gPC0gZHBseXI6OmNvdW50KGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IsIHN5bm9ueW1zLCBzb3J0ID0gVFJVRSkKCiMgaW5wdXQgZGF0YQppbnB1dF9zbmlwcGV0IDwtIG1kY2FfcmVzX2Z1bGwgJT4lIAogIGZpbHRlcihzdHJfZGV0ZWN0KG1ldGFwaG9ycywgImRlc2lyZWQiKSkgJT4lIAogIHNlbGVjdChzeW5vbnltcywgbiwgY3huX3N1bSkgJT4lIAogIG11dGF0ZShvdGhlcnMgPSBjeG5fc3VtIC0gbikgJT4lIAogIHNlbGVjdChzeW5vbnltcywgbiwgb3RoZXJzLCB0b3RhbCA9IGN4bl9zdW0pCgppbnB1dF9zbmlwcGV0IDwtIGlucHV0X3NuaXBwZXQgJT4lCiAgYmluZF9yb3dzKGlucHV0X3NuaXBwZXQgJT4lIAogICAgICAgICAgICAgIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBzdW0pICU+JSAKICAgICAgICAgICAgICBtdXRhdGUoc3lub255bXMgPSAidG90YWwiKSAlPiUgCiAgICAgICAgICAgICAgc2VsZWN0KHN5bm9ueW1zLCBldmVyeXRoaW5nKCkpKQoKIyB0b2tlbnMgZm9yIHRoZSBleGFtcGxlcyBpbiB0aGUgdGV4dApvYnNfYmhnIDwtIGZpbHRlcihleGFtcGxlX2RmLCBzeW5vbnltcyA9PSAia2ViYWhhZ2lhYW4iKVtbIm4iXV0Kc3VtX2JoZyA8LSBmaWx0ZXIoc3lub255bV90b2tlbiwgc3lub255bXMgPT0gImtlYmFoYWdpYWFuIilbWyJuIl1dCmV4cF9iaGcgPC0gZmlsdGVyKGV4YW1wbGVfZGYsIHN5bm9ueW1zID09ICJrZWJhaGFnaWFhbiIpW1siZXhwIl1dCm1ldGFfZGVzdGluYXRpb24gPC0gZmlsdGVyKG1ldGFwaG9yX3Rva2VuLCBzdHJfZGV0ZWN0KG1ldGFwaG9ycywgImRlc2lyZWQgZ29hbCIpKVtbIm4iXV0KZXhwX3Byb2IgPC0gZXhwX2JoZy9tZXRhX2Rlc3RpbmF0aW9uCmBgYAoKYGBge3IgZXhhbXBsZS1kYXRhLXByaW50fQojIHByaW50IG91dCB0aGUgcmVzdWx0cyBmb3IgZXhhbXBsZSB3aXRoICdERVNJUkVEIEdPQUwvREVTVElOQVRJT04nCmV4YW1wbGVfZGYgJT4lCiAgbXV0YXRlKGdsb3NzID0gYygiaGFwcGluZXNzIiwgCiAgICAgICAgICAgICAgICAgICAicGxlYXN1cmUiLCAKICAgICAgICAgICAgICAgICAgICIocGVhY2VmdWwgYW5kKSBoYXBweTsgaGFwcGluZXNzIiwgCiAgICAgICAgICAgICAgICAgICAidmVyeSBoYXBweSwgam95b3VzIiwgCiAgICAgICAgICAgICAgICAgICAiY2hlZXJmdWw7IGxpdC4gcHVyZSwgY2xlYW4iLCAKICAgICAgICAgICAgICAgICAgICJoYXBweSwgdG8gZmVlbCB3ZWxsLCBjb250ZW50ZWQiLCAKICAgICAgICAgICAgICAgICAgICJleGNpdGVkLCBlbnRodXNpYXN0aWMiLCAKICAgICAgICAgICAgICAgICAgICJjaGVlcihmdWxuZXNzKSIsIAogICAgICAgICAgICAgICAgICAgInB1cml0eTsgY2hlZXJmdWxuZXNzIiwgCiAgICAgICAgICAgICAgICAgICAiam95LCBjaGVlcmZ1bG5lc3MiKSwKICAgICAgICAgc3lub255bXMgPSBwYXN0ZSgiKiIsIHN5bm9ueW1zLCAiKiIsIHNlcCA9ICIiKSwKICAgICAgICAgZXhwID0gcm91bmQoZXhwLCAzTCkpICU+JQogIHNlbGVjdChzeW5vbnltcywgZ2xvc3MsIGV2ZXJ5dGhpbmcoKSkgJT4lCiAgYXMuZGF0YS5mcmFtZSgpICU+JQogIGtuaXRyOjprYWJsZShjYXB0aW9uID0gJypPYnNlcnZlZCogZnJlcXVlbmN5IChgbmApLCAqZXhwZWN0ZWQqIGZyZXF1ZW5jeSAoYGV4cGApLCBhbmQgKkFzc29jaWF0aW9uIFN0cmVuZ3RoKiAoYGFzc29jc3RyYCkgZm9yIDxzcGFuIHN0eWxlPSJmb250LXZhcmlhbnQ6c21hbGwtY2FwcyI7PmhhcHBpbmVzcyBpcyBhIGRlc2lyZWQgZ29hbC9kZXN0aW5hdGlvbjwvc3Bhbj4gYWNyb3NzIHRoZSBzeW5vbnltcy4nLCByb3cubmFtZXMgPSBUUlVFKQpgYGAKClRoZSBvYnNlcnZlZCBjby1vY2N1cnJlbmNlIGZyZXF1ZW5jeSBiZXR3ZWVuICprZWJhaGFnaWFhbiogYW5kIG1ldGFwaG9yaWNhbCBwYXR0ZXJucyBldm9raW5nIHRoZSBgciBoYXBweXI6OnNjYXBzKCdoYXBwaW5lc3MgaXMgYSBkZXNpcmVkIGdvYWwvZGVzdGluYXRpb24nKWAgaXMgYHIgb2JzX2JoZ2AgdG9rZW5zLiBJbiBhZGRpdGlvbiB0byB0aGlzIG9ic2VydmVkIGNvLW9jY3VycmVuY2UgZnJlcXVlbmN5LCBvbmUgYWxzbyBuZWVkcyB0aGUgKmV4cGVjdGVkIGZyZXF1ZW5jeSogZm9yIHRoZSBjby1vY2N1cnJlbmNlIGJldHdlZW4gYHIgaGFwcHlyOjpzY2FwcygnaGFwcGluZXNzIGlzIGEgZGVzaXJlZCBnb2FsL2Rlc3RpbmF0aW9uJylgIGFuZCAqa2ViYWhhZ2lhYW4qIChjb2x1bW4gImV4cCIgaW4gW1RhYmxlIFxAcmVmKHRhYjpleGFtcGxlLWRhdGEtcHJpbnQpXSgjZXhhbXBsZS1kYXRhLXByaW50KSkuIFRoZSBleHBlY3RlZCBmcmVxdWVuY3kgKGZvciBhIG1ldGFwaG9yIGFuZCBhIHN5bm9ueW0pIHJlcHJlc2VudHMgdGhlIGZyZXF1ZW5jeSB0aGF0IG9uZSB3b3VsZCBleHBlY3QgdW5kZXIgdGhlIG51bGwtaHlwb3RoZXNpcyB0aGF0IHRoZSBwcm9wb3J0aW9uIG9mIHRoZSBtZXRhcGhvciB3ZXJlIGVxdWFsbHkgZGlzdHJpYnV0ZWQgYWNyb3NzIGFsbCBzeW5vbnltcyB1bmRlciBzdHVkeTsgaW4gb3RoZXIgd29yZHMsIHRoZSBudWxsLWh5cG90aGVzaXMgc3RhdGVzIHRoYXQgdGhlcmUgYXJlIG5vIGRpc3RyaWJ1dGlvbmFsIGRpZmZlcmVuY2VzIGZvciB0aGUgbWV0YXBob3Igd2l0aCBlYWNoIHN5bm9ueW0gW2NmLiBAbGV2c2hpbmFfaG93XzIwMTUsIHBwLiAyMTAtMjExXS4gVGhlIGV4cGVjdGVkIGZyZXF1ZW5jeSBmb3Igb3VyIGV4YW1wbGUgaXMgYXJyaXZlZCBhdCBieSBtdWx0aXBseWluZyAoaSkgdGhlIHRvdGFsIGZyZXF1ZW5jeSBvZiAqa2ViYWhhZ2lhYW4qIGluIHRoZSBzYW1wbGUsIGkuZS4sIGByIHN1bV9iaGdgLCB3aXRoIChpaSkgdGhlIHRvdGFsIGZyZXF1ZW5jeSBvZiBgciBoYXBweXI6OnNjYXBzKCdoYXBwaW5lc3MgaXMgYSBkZXNpcmVkIGdvYWwvZGVzdGluYXRpb24nKWAgb2NjdXJyaW5nIHdpdGggYW55IHN5bm9ueW1zIGluIHRoZSBzYW1wbGUsIGkuZS4sIGByIG1ldGFfZGVzdGluYXRpb25gLCB0aGVuIChpaWkpIGRpdmlkaW5nIHRoZSByZXN1bHRzIHdpdGggdGhlIHRvdGFsIG1ldGFwaG9yaWNhbCB0b2tlbnMgaW4gdGhlIHNhbXBsZSwgaS5lLiwgYHIgZGltKGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IpWzFdYDsgaGVuY2UgKGByIHN1bV9iaGdgYCpgYHIgbWV0YV9kZXN0aW5hdGlvbmApL2ByIGRpbShoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yKVsxXWAgPSBgciBleHBfYmhnYC4gCgpEaWZmZXJlbmNlIGJldHdlZW4gdGhlIG9ic2VydmVkIGFuZCBleHBlY3RlZCBmcmVxdWVuY2llcyBhbGxvd3MgdXMgdG8gZGV0ZXJtaW5lIHRoZSBkaXJlY3Rpb24gb2YgdGhlIGFzc29jaWF0aW9uIGJldHdlZW4gdGhlIGNvLW9jY3VycmluZyBpdGVtcy4gVGhlIGFzc29jaWF0aW9uIGNhbiBiZSAoaSkgKnBvc2l0aXZlKiwgaWYgdGhlIG9ic2VydmVkIGZyZXF1ZW5jeSBleGNlZWRzIHRoZSBleHBlY3RlZCBmcmVxdWVuY3ksIG9yIChpaSkgKm5lZ2F0aXZlKiwgaWYgdGhlIG9ic2VydmVkIGZyZXF1ZW5jeSBpcyBiZWxvdyB0aGUgZXhwZWN0ZWQgZnJlcXVlbmN5LiBUaGUgY29tcGFyaXNvbiBiZXR3ZWVuIHRoZSBleHBlY3RlZCBhbmQgdGhlIG9ic2VydmVkIGZyZXF1ZW5jeSBpbiBbVGFibGUgXEByZWYodGFiOmV4YW1wbGUtZGF0YS1wcmludCldKCNleGFtcGxlLWRhdGEtcHJpbnQpIGZvciBgciBzY2FwcygnaGFwcGluZXNzIGlzIGEgZGVzaXJlZCBnb2FsL2Rlc3RpbmF0aW9uJylgIHdpdGggKmtlYmFoYWdpYWFuKiBpbmRpY2F0ZXMgcG9zaXRpdmUgYXNzb2NpYXRpb24sIG9yICphdHRyYWN0aW9uKiwgYmV0d2VlbiB0aGUgbWV0YXBob3IgYW5kIHRoZSBzeW5vbnltIHNpbmNlIHRoZSBvYnNlcnZlZCBmcmVxdWVuY3kgb2YgYHIgb2JzX2JoZ2AgaXMgaGlnaGVyIHRoYW4gdGhlIGV4cGVjdGVkIGZyZXF1ZW5jeSBvZiBgciBleHBfYmhnYCBbY2YuIEBoaWxwZXJ0X2Rpc3RpbmN0aXZlXzIwMDYsIHAuIDI0N10uIEFkZGl0aW9uYWwgdmFsdWUgcmVxdWlyZWQgYnkgdGhlIEJpbm9taWFsIFRlc3QgaW4gTURDQSBpcyB0aGUgKmEgcHJpb3JpKiBwcm9iYWJpbGl0eSB0aGF0IGlmICprZWJhaGFnaWFhbiogaXMgdXNlZCBtZXRhcGhvcmljYWxseSBpdCB3aWxsIG9jY3VyIGluIG1ldGFwaG9yaWNhbCBwYXR0ZXJucyBldm9raW5nIGByIHNjYXBzKCdoYXBwaW5lc3MgaXMgYSBkZXNpcmVkIGdvYWwvZGVzdGluYXRpb24nKWAuIFRoaXMgcHJvYmFiaWxpdHkgaXMgY2FsY3VsYXRlZCBieSBkaXZpZGluZyAoaSkgdGhlIGV4cGVjdGVkIGZyZXF1ZW5jeSBvZiAqa2ViYWhhZ2lhYW4qIHdpdGggdGhlIG1ldGFwaG9yIChpLmUuLCBgciBleHBfYmhnYCkgYWdhaW5zdCAoaWkpIHRoZSB0b3RhbCBmcmVxdWVuY3kgb2YgdGhlIG1ldGFwaG9yIGluIHRoZSBzYW1wbGUgKGkuZS4sIGByIG1ldGFfZGVzdGluYXRpb25gKSwgaGVuY2UgKGByIGV4cF9iaGdgL2ByIG1ldGFfZGVzdGluYXRpb25gKSBlcXVhbHMgYHIgZXhwX3Byb2JgIFtAaGlscGVydF9kaXN0aW5jdGl2ZV8yMDA2LCBwLiAyNDddLgoKVGhlIG9ic2VydmVkIGNvLW9jY3VycmVuY2UgZnJlcXVlbmN5LCB0aGUgdG90YWwgZnJlcXVlbmN5IG9mIHRoZSBtZXRhcGhvciwgYW5kIHRoZSAqYSBwcmlvcmkqIHByb2JhYmlsaXR5IHRoZW4gYmVjb21lIHRoZSBpbnB1dHMgZm9yIHRoZSBvbmUtdGFpbGVkIEJpbm9taWFsIFRlc3QgaW1wbGVtZW50ZWQgaW4gTURDQS4gR2l2ZW4gb3VyIGV4YW1wbGUsIHRoZSBCaW5vbWlhbCBUZXN0IHdpbGwgZGV0ZXJtaW5lIHRoZSBCaW5vbWlhbCAqcCotdmFsdWUgaW5kaWNhdGluZyB0aGUgcHJvYmFiaWxpdHkgdGhhdCB0aGUgb2JzZXJ2ZWQgY28tb2NjdXJyZW5jZSBmcmVxdWVuY3kgb2YgYHIgb2JzX2JoZ2AsIG9yIGV2ZW4gbW9yZSBvZnRlbiwgZm9yICprZWJhaGFnaWFhbiogYW5kIGByIHNjYXBzKCdoYXBwaW5lc3MgaXMgYSBkZXNpcmVkIGdvYWwvZGVzdGluYXRpb24nKWAgd291bGQgaGF2ZSBjb21lIGFib3V0IGJ5IGNoYW5jZSwgZ2l2ZW4gdGhlIG51bGwtaHlwb3RoZXNpcyBvZiBlcXVhbCBkaXN0cmlidXRpb24gZm9yIGEgbWV0YXBob3Igd2l0aCBhbGwgc3lub255bXMuIFRoZSBjb2RlLWNodW5rIGJlbG93IHNob3dzIHRoZSBSIGNvZGUgdG8gcGVyZm9ybSBvbmUtdGFpbGVkIEJpbm9taWFsIFRlc3QgZm9yIG91ciBleGFtcGxlOgoKYGBge3IgYmlub20tdGVzdC1leGFtcGxlLCBlY2hvID0gVFJVRX0KIyBGb3Igb25lLXRhaWxlZCB0ZXN0LCB0aGUgKmFsdGVybmF0aXZlKiBhcmd1bWVudCBpbiB0aGUgY29kZSBpcyBzZXQgdG8gJ2dyZWF0ZXInIAojIHdoZW4gdGhlIGNvLW9jYy5mcmVxIGlzIGhpZ2hlciB0aGFuIGV4cGVjdGVkOyBpdCBzZXQgdG8gImxlc3MiIHdoZW4gb3RoZXJ3aXNlLgoKYmlub20udGVzdCh4ID0gMTI1LCAjIGNvLW9jYy5mcmVxIGJldHdlZW4gImtlYmFoYWdpYWFuIiBhbmQgdGhlICJkZXNpcmVkIGdvYWwiIG1ldGFwaG9yCiAgICAgICAgICAgbiA9IDI5MywgIyB0b3RhbCB0b2tlbnMgb2YgdGhlICJkZXNpcmVkIGdvYWwiIG1ldGFwaG9yCiAgICAgICAgICAgcCA9IDAuMTg4MjkwMywgIyBhIHByaW9yaSBwcm9iYWJpbGl0eQogICAgICAgICAgIGFsdGVybmF0aXZlID0gImdyZWF0ZXIiIAogICAgICAgICAgICkkcC52YWx1ZSAjIHJldHJpZXZlIG9ubHkgdGhlIGJpbm9taWFsIHAtdmFsdWUKYGBgCgpUaGUgcmVzdWx0aW5nICpwKn5CaW5vbWlhbH4tdmFsdWUgaGVyZSBpcyBzbWFsbCAoaS5lLiwgYHIgYmlub20udGVzdChvYnNfYmhnLCBtZXRhX2Rlc3RpbmF0aW9uLCBleHBfcHJvYiwgJ2dyZWF0ZXInKSRwLnZhbHVlICU+JSBmb3JtYXQoc2NpZW50aWZpYyA9IFRSVUUpYCleW1RoZSBhbHRlcm5hdGl2ZSByZXByZXNlbnRhdGlvbiBvZiB0aGlzICpwKi12YWx1ZSBpcyBgciBiaW5vbS50ZXN0KG9ic19iaGcsIG1ldGFfZGVzdGluYXRpb24sIGV4cF9wcm9iLCAnZ3JlYXRlcicpJHAudmFsdWUgJT4lIGZvcm1hdChzY2llbnRpZmljID0gRkFMU0UpYC5dLiBUaGlzIHZhbHVlIGluZGljYXRlcyB0aGF0IHRoZXJlIGlzIGEgdmVyeSBsb3cgcHJvYmFiaWxpdHkgdGhhdCB3ZSBvYnNlcnZlIHRoaXMgY28tb2NjdXJyZW5jZSBkaXN0cmlidXRpb24gb2YgYHIgb2JzX2JoZ2AgdG9rZW5zLCBvciBldmVuIG1vcmUsIGJldHdlZW4gKmtlYmFoYWdpYWFuKiBhbmQgYHIgaGFwcHlyOjpzY2FwcygnaGFwcGluZXNzIGlzIGEgZGVzaXJlZCBnb2FsL2Rlc3RpbmF0aW9uJylgICppZiogdGhlcmUgaXMgKm5vKi8qbmV1dHJhbCogYXNzb2NpYXRpb24gYmV0d2VlbiB0aGVtLiBTaW1pbGFyIGNhbGN1bGF0aW9uIGFzIGFib3ZlIGlzIGRvbmUgZm9yIHRoZSBjby1vY2N1cnJlbmNlIGZyZXF1ZW5jaWVzIG9mIGVhY2ggc3lub255bXMgd2l0aCB0aGUgbWV0YXBob3JzLiBUaGUgY29kZS1jaHVuayBiZWxvdyBpbGx1c3RyYXRlcyB0aGUgY29tcHV0YXRpb24gb2YgdGhlICpwKn5CaW5vbWlhbH4tdmFsdWUgd2hlbiB0aGUgY28tb2NjdXJyZW5jZSBmcmVxdWVuY3kgaXMgbGVzcyB0aGFuIGV4cGVjdGVkLCBhcyBpbiBiZXR3ZWVuICprZWdlbWJpcmFhbiogJ2pveScgYW5kIHRoZSBgciBoYXBweXI6OnNjYXBzKCdoYXBwaW5lc3MgaXMgYSBkZXNpcmVkIGdvYWwvZGVzdGluYXRpb24nKWAgbWV0YXBob3IgKGNmLiBbVGFibGUgXEByZWYodGFiOmV4YW1wbGUtZGF0YS1wcmludCldKCNleGFtcGxlLWRhdGEtcHJpbnQpKS4KCmBgYHtyIGJpbm9tLXRlc3QtZXhhbXBsZS1rZWdlbWJpcmFhbiwgZWNobyA9IFRSVUV9CmJpbm9tLnRlc3QoeCA9IDYsICMgY28tb2NjLmZyZXEgYmV0d2VlbiAia2VnZW1iaXJhYW4iIGFuZCB0aGUgImRlc2lyZWQgZ29hbCIgbWV0YXBob3IKICAgICAgICAgICBuID0gMjkzLCAjIHRvdGFsIHRva2VucyBvZiB0aGUgImRlc2lyZWQgZ29hbCIgbWV0YXBob3IKICAgICAgICAgICBwID0gMC4xODQ0NDIsICMgYSBwcmlvcmkgcHJvYmFiaWxpdHkKICAgICAgICAgICBhbHRlcm5hdGl2ZSA9ICJsZXNzIiAKICAgICAgICAgICApJHAudmFsdWUgIyByZXRyaWV2ZSBvbmx5IHRoZSBiaW5vbWlhbCBwLXZhbHVlCmBgYAoKQXMgaW4gbW9zdCBDb2xsb3N0cnVjdGlvbmFsIEFuYWx5c2lzIHN0dWRpZXMsIHRoZSAqcCotdmFsdWVzIG9mIHRoZSBCaW5vbWlhbCBUZXN0IGluIHRoaXMgY2FzZSBhcmUgdXNlZCBkaXJlY3RseSBhcyB0aGUgbWVhc3VyZSBmb3IgYXNzb2NpYXRpb24gc3RyZW5ndGguIFRoZSBzbWFsbCAqcCp+Qmlub21pYWx+LXZhbHVlIGFuZCB0aGUgcG9zaXRpdmUgZGV2aWF0aW9uIG9mIHRoZSBvYnNlcnZlZCBmcmVxdWVuY3kgZnJvbSB0aGUgZXhwZWN0ZWQgb25lIGZvciBvdXIgZXhhbXBsZSB3aXRoICprZWJhaGFnaWFhbiogJ2hhcHBpbmVzcycgaW5kaWNhdGVzIHNpZ25pZmljYW50bHkgaGlnaCBkZWdyZWUgb2YgYXNzb2NpYXRpb24gKHZpei4gKmF0dHJhY3Rpb24qKSBiZXR3ZWVuICprZWJhaGFnaWFhbiogYW5kIGByIGhhcHB5cjo6c2NhcHMoJ2hhcHBpbmVzcyBpcyBhIGRlc2lyZWQgZ29hbC9kZXN0aW5hdGlvbicpYC4gRm9yIGV4cG9zaXRvcnkgcmVhc29uLCBDb2xsb3N0cnVjdGlvbmFsIEFuYWx5c2lzIGxvZ34xMH4tdHJhbnNmb3JtcyB0aGUgKnAqfkJpbm9taWFsfi12YWx1ZSBpbnRvIHRoZSBzby1jYWxsZWQgKkNvbGwob3N0cnVjdGlvbikgU3RyKGVuZ3RoKSogdmFsdWU7IGluIHRoaXMgdGhlc2lzLCBpdCBpcyByZWZlcnJlZCB0byBhcyB0aGUgKkFzc29jKGlhdGlvbikgU3RyKGVuZ3RoKSogdmFsdWUgKGNmLiB0aGUgYCJhc3NvY3N0ciJgIGNvbHVtbiBpbiBbVGFibGUgXEByZWYodGFiOmV4YW1wbGUtZGF0YS1wcmludCldKCNleGFtcGxlLWRhdGEtcHJpbnQpKSBbQHN0ZWZhbm93aXRzY2hfY292YXJ5aW5nXzIwMDUsIHAuIDddLiBQb3NpdGl2ZSBvciBuZWdhdGl2ZSBzaWducyBhcmUgc2V0IGluIHRoZSAqQXNzb2NTdHIqIHZhbHVlcyB0byBpbmRpY2F0ZSB0aGUgZGlyZWN0aW9uIG9mIGFzc29jaWF0aW9uLiBQb3NpdGl2ZSAqQXNzb2NTdHIqIHZhbHVlcyBpbmRpY2F0ZSAqYXR0cmFjdGlvbiogKGkuZS4sIHRoZSBvYnNlcnZlZCBjby1vY2N1cnJlbmNlIGZyZXF1ZW5jeSBpcyBoaWdoZXIgdGhhbiB0aGUgZXhwZWN0ZWQgZnJlcXVlbmN5KTsgaXQgaXMgZGVyaXZlZCBmcm9tIHRoZSAqbmVnYXRpdmUqIGxvZ34xMH4tdHJhbnNmb3JtZWQgKnAqfkJpbm9taWFsfi12YWx1ZSwgYXMgc2hvd24gYmVsb3cgZm9yIHRoZSAqa2ViYWhhZ2lhYW4qICdoYXBwaW5lc3MnIGV4YW1wbGUuCgpgYGB7ciBsb2cxMC1rZWJhaGFnaWFhbiwgZWNobyA9IFRSVUV9CiMgZ2V0IHRoZSBwLXZhbHVlIG9mIHRoZSBCaW5vbWlhbCBUZXN0CnBfYmlub21pYWwgPC0gYmlub20udGVzdCh4ID0gMTI1LCBuID0gMjkzLCBwID0gMC4xODgyOTAzLCBhbHRlcm5hdGl2ZSA9ICJncmVhdGVyIikkcC52YWx1ZQoKIyBuZWdhdGl2ZSBsb2cxMCBmb3IgdGhlIHAtYmlub20gZm9yIHRoZSAqa2ViYWhhZ2lhYW4qIGRhdGEKLWxvZzEwKHggPSBwX2Jpbm9taWFsKQpgYGAKCk1lYW53aGlsZSwgbmVnYXRpdmUgKkFzc29jU3RyKiB2YWx1ZXMgaW5kaWNhdGUgKnJlcHVsc2lvbiogKGkuZS4sIHRoZSBvYnNlcnZlZCBjby1vY2N1cnJlbmNlIGZyZXF1ZW5jeSBpcyBsZXNzIHRoYW4gZXhwZWN0ZWQpOyBpdCBpcyBkZXJpdmVkIGZyb20gdGhlICpwb3NpdGl2ZSogbG9nfjEwfi10cmFuc2Zvcm1lZCAqcCp+Qmlub21pYWx+LXZhbHVlLCBhcyBzaG93biBiZWxvdyBmb3IgdGhlICprZWdlbWJpcmFhbiogJ2pveScgZXhhbXBsZS4KCmBgYHtyIGxvZzEwLWtlZ2VtYmlyYWFuLCBlY2hvID0gVFJVRX0KIyBnZXQgdGhlIHAtdmFsdWUgb2YgdGhlIEJpbm9taWFsIFRlc3QKcF9iaW5vbWlhbCA8LSBiaW5vbS50ZXN0KHggPSA2LCBuID0gMjkzLCBwID0gMC4xODQ0NDIsIGFsdGVybmF0aXZlID0gImxlc3MiKSRwLnZhbHVlCgojIHBvc2l0aXZlIGxvZzEwIGZvciB0aGUgcC1iaW5vbSBmb3IgdGhlICprZWdlbWJpcmFhbiogZGF0YQpsb2cxMCh4ID0gcF9iaW5vbWlhbCkKYGBgCgoKT25lIGNhbiBub3RpY2UgZnJvbSBbVGFibGUgXEByZWYodGFiOmV4YW1wbGUtZGF0YS1wcmludCldKCNleGFtcGxlLWRhdGEtcHJpbnQpIHRoYXQgYHIgc2NhcHMoJ2hhcHBpbmVzcyBpcyBhIGRlc2lyZWQgZ29hbC9kZXN0aW5hdGlvbicpYCBpcyBhbHNvIHNpZ25pZmljYW50bHkgZGlzdGluY3RpdmUgdG8gKmtlc2VuYW5nYW4qICdwbGVhc3VyZScsIHRob3VnaCBpbiBhIGxvd2VyIGRlZ3JlZSBjb21wYXJlZCB0byAqa2ViYWhhZ2lhYW4qLCBhcyByZWZsZWN0ZWQgaW4gdGhlIEFzc29jU3RyIHZhbHVlcyBiZXR3ZWVuIHRoZSB0d287IHF1YWxpdGF0aXZlbHksIGl0IHdpbGwgYmUgc2hvd24gdGhhdCAqa2VzZW5hbmdhbiogYW5kICprZWJhaGFnaWFhbiogZGlmZmVyIGluIHJlbGF0aW9uIHRvIHRoZSBwcmVmZXJyZWQgc3VibWFwcGluZ3Mgb2YgdGhlIGByIHNjYXBzKCdoYXBwaW5lc3MgaXMgYSBkZXNpcmVkIGdvYWwvZGVzdGluYXRpb24nKWAgKGNmLiBgciBzZWN0aW9uYFtcQHJlZihiYWhhZ2lhKV0oI2JhaGFnaWEpIGFuZCBgciBzZWN0aW9uYFtcQHJlZihzZW5hbmcpXSgjc2VuYW5nKSkuIFRoaXMga2luZCBvZiBtdWx0aXBsZSBhc3NvY2lhdGlvbiBvZiBhbiBpdGVtIChpLmUuLCBhIG1ldGFwaG9yKSB0byBtb3JlIHRoYW4gb25lIGNvbnN0cnVjdGlvbiBvZiBpbnRlcmVzdCAoaS5lLiwgdGhlIHN5bm9ueW1zKSBpcyBub3QgdW5jb21tb24gaW4gTURDQSwgYXMgR2lscXVpbiBbLUBnaWxxdWluX2NvcnB1c18yMDEwLCBwLiAyMDEsIFRhYmxlIDYwXSBoYXMgc2hvd24gaW4gaGVyIHN0dWR5IG9mIHRlbiBwZXJpcGhyYXN0aWMgY2F1c2F0aXZlIGNvbnN0cnVjdGlvbnMgaW4gRW5nbGlzaC4gWWV0LCB0aGUgQXNzb2NTdHIgdmFsdWVzIG9mIHRoZSBzaGFyZWQsIGF0dHJhY3RlZCBpdGVtIHdpdGggdGhlIGNvbnN0cnVjdGlvbnMgY2FuIGJlIHVzZWQgdG8gYXNzdW1lIHRoZSByZWxhdGl2ZSBhc3NvY2lhdGlvbiBzdHJlbmd0aCBvZiB0aGUgaXRlbSB3aXRoIHRoZSBjb25zdHJ1Y3Rpb25zLgoKSW4gQ29sbG9zdHJ1Y3Rpb25hbCBBbmFseXNpcywgdGhlIGNvbW1vbmx5IHVzZWQgY3V0LW9mZiBwb2ludHMgaW4gaW5kaWNhdGluZyBzaWduaWZpY2FudCBhc3NvY2lhdGlvbiBzdHJlbmd0aCBpcyBBc3NvY1N0ciA+IDEuMzAxMDMsIHdoaWNoIGlzIGVxdWFsIHRvICpwKn5CaW5vbWlhbH4gPCAwLjA1IFtAc3RlZmFub3dpdHNjaF9jb3ZhcnlpbmdfMjAwNSwgcC4gN10uIEhpZ2hlciBjdXQtb2ZmIHBvaW50cyBjYW4gYWxzbyBiZSB1c2VkOiAoaSkgQXNzb2NTdHIgPiAyLCB3aGljaCBpcyBlcXVhbCB0byAqcCp+Qmlub21pYWx+IDwgMC4wMSwgYW5kIChpaSkgQXNzb2NTdHIgPiAzLCB3aGljaCBpcyBlcXVhbCB0byAqcCp+Qmlub21pYWx+IDwgMC4wMDEuIFRoZXNlIEFzc29jU3RyIHRocmVzaG9sZCB2YWx1ZXMgd2lsbCBiZSBtYXJrZWQgd2l0aCBuZWdhdGl2ZSBzaWduIHdoZW4gdGhlIGNvLW9jY3VycmVuY2UgZnJlcXVlbmNpZXMgYXJlIGxlc3MgdGhhbiBleHBlY3RlZC4gRm9yIGVhY2ggc3lub255bSwgdGhlIEFzc29jU3RyIHZhbHVlcyBvZiB0aGUgbWV0YXBob3JzIGNhbiBiZSBzb3J0ZWQgZnJvbSB0aGUgaGlnaGVzdCAocG9zaXRpdmUpIHRvIHRoZSBsb3dlc3QgKGRvd24gdG8gdGhlIG5lZ2F0aXZlIHZhbHVlcykuIFRoaXMgd2lsbCByYW5rIHRoZSBtZXRhcGhvcnMgZnJvbSB0aGUgbW9zdCBkaXN0aW5jdGl2ZSBvbmVzIHRvIHRoZSBtb3N0IHN0cm9uZ2x5IHJlcGVsbGVkLiBbVGFibGUgXEByZWYodGFiOmV4YW1wbGUtZGF0YS1wcmludCldKCNleGFtcGxlLWRhdGEtcHJpbnQpIGlsbHVzdHJhdGVzIHRoYXQgc2lnbmlmaWNhbnQgcmVwdWxzaW9uIGZvciB0aGUgbWV0YXBob3IgYWNjb3JkaW5nIHRvIHRoZSBjdXQtb2ZmIHBvaW50cyBjYW4gYmUgc2VlbiBmcm9tIHJvdyBudW1iZXIgZml2ZS4gVGhhdCBpcywgc3RhcnRpbmcgZnJvbSAqYHIgZXhhbXBsZV9kZiAlPiUgZmlsdGVyKGFzc29jc3RyIDwgLTEuMzAxMDMpICU+JSAuWzEsXSAlPiUgLiRzeW5vbnltc2AqICdjaGVlcmZ1bCcgKEFzc29jU3RyID0gYHIgZXhhbXBsZV9kZiAlPiUgZmlsdGVyKGFzc29jc3RyIDwgLTEuMzAxMDMpICU+JSAuWzEsXSAlPiUgLiRhc3NvY3N0cmApIGRvd24gdG8gKmtlY2VyaWFhbiogJ2NoZWVyZnVsbmVzcycgKEFzc29jU3RyID0gYHIgZXhhbXBsZV9kZiAlPiUgZmlsdGVyKGFzc29jc3RyIDwgLTEuMzAxMDMsIHN0cl9kZXRlY3Qoc3lub255bXMsICdea2VjZXJpYScpKSAlPiUgLiRhc3NvY3N0cmApIGFuZCAqa2VnZW1iaXJhYW4qICdqb3ksIGNoZWVyZnVsbmVzcycgKEFzc29jU3RyID0gYHIgZXhhbXBsZV9kZiAlPiUgZmlsdGVyKGFzc29jc3RyIDwgLTEuMzAxMDMsIHN0cl9kZXRlY3Qoc3lub255bXMsICdea2VnZW1iaXJhJykpICU+JSAuJGFzc29jc3RyYCksIHRoZSB0d28gc3lub255bXMgc2hvd2luZyB0aGUgc3Ryb25nZXN0IGRpc3NvY2lhdGlvbiB3aXRoIGByIGhhcHB5cjo6c2NhcHMoJ2hhcHBpbmVzcyBpcyBhIGRlc2lyZWQgZ29hbC9kZXN0aW5hdGlvbicpYCBtZXRhcGhvci4KClRoZSBBc3NvY1N0ci1iYXNlZCByYW5rZWQtbGlzdCBvZiB0aGUgbWV0YXBob3JzIGZvciBlYWNoIHN5bm9ueW0gaXMgYSBzdGFydGluZyBwb2ludCBmb3IgcXVhbGl0YXRpdmUgZGlzY3Vzc2lvbiBjb25jZXJuaW5nIHRoZSB3YXkgc2VtYW50aWNhbGx5IHNpbWlsYXIgZW1vdGlvbiBjb25jZXB0cyBhcmUgY2hhcmFjdGVyaXNlZCBieSwgYW5kIHZhcnkgaW4gdGVybXMgb2YsIGNlcnRhaW4gZGlzdGluY3RpdmUgYW5kIHJlcGVsbGVkIG1ldGFwaG9ycy4gSW4gb3RoZXIgd29yZHMsIGEgc2V0IG9mIG1ldGFwaG9ycyBhcmUgc3Ryb25nbHkgZGlzdGluY3RpdmUgZm9yIGFuIGVtb3Rpb24gY29tcGFyZWQgdG8gaXRzIHN5bm9ueW1zIHByZXN1bWFibHkgYmVjYXVzZSB0aGVzZSBtZXRhcGhvcnMgbWFwIGNvbmNlcHR1YWwga25vd2xlZGdlIHRoYXQgYmVzdCBjaGFyYWN0ZXJpc2VzIHRoZSBzZW1hbnRpYyBmb2NpIG9mIHRoZSBlbW90aW9uLiBUaGUgcmVwZWxsZWQgbWV0YXBob3JzIG1heSB0aGVuIGluZGljYXRlIHRoZSBsZXNzIGVudHJlbmNoZWQgbWV0YXBob3JpY2FsIG1vZGVsIGluIGNvbmNlcHR1YWxpc2luZyB0aGUgZ2l2ZW4gZW1vdGlvbi4gCgpJbiByZWxhdGlvbiB0byB0aGUgYWltIG9mIHRoaXMgY2hhcHRlciwgdGhlIGV4YW1wbGUgaW4gW1RhYmxlIFxAcmVmKHRhYjpleGFtcGxlLWRhdGEtcHJpbnQpXSgjZXhhbXBsZS1kYXRhLXByaW50KSBtaW5pbWFsbHkgY29uZmlybXMgS8O2dmVjc2VzJyBhc3N1bXB0aW9uIHJlZ2FyZGluZyB0aGUgZXhpc3RlbmNlIG9mIHByaW5jaXBhbCwgb3IgKmRpc3RpbmN0aXZlKiwgbWV0YXBob3JzIGRpc3Rpbmd1aXNoaW5nIG5lYXItc3lub255bXMgb2YgZW1vdGlvbnMuIEFmdGVyIGFsbCwgaXQgaXMgYSBiYXNpYyBhc3N1bXB0aW9uIGluIENvZ25pdGl2ZSBMaW5ndWlzdGljcywgaW4gcmVsYXRpb24gdG8gaXRzIHVzYWdlLWJhc2VkIHRlbmV0IFtAZXZhbnNfY29nbml0aXZlXzIwMDYsIHAuIDEyMl0sIHRoYXQgZGlmZmVyZW50IHVzYWdlIGZvcm1zIChlLmcuIG1ldGFwaG9yaWNhbCBwYXR0ZXJucykgb2YgYSBsaW5ndWlzdGljIHVuaXQgKGUuZy4gYW4gZW1vdGlvbiBsZXhlbWUpLCBoYXZlIGltcGFjdHMgb24gaXRzIG1lYW5pbmcgKGUuZy4gaXRzIG1ldGFwaG9yaWNhbCBjb25zdHJ1YWwpLiBOZXZlcnRoZWxlc3MsIGdpdmVuIHN1Y2ggcXVhbnRpdGF0aXZlIG1ldGhvZCBhcyBNRENBLCB0aGlzIHVzYWdlLWJhc2VkIGFzc3VtcHRpb24gY2FuIGJlIGZsZXNoZWQgb3V0LCBhbmQgdGhlIHdheSBhIHNldCBvZiBlbW90aW9uIHN5bm9ueW1zIGRpZmZlciBpbiB0aGVpciBwcmVmZXJyZWQgbWV0YXBob3JpY2FsIGNvbmNlcHR1YWxpc2F0aW9ucyBjYW4gYmUgc3BlbGxlZCBvdXQgbW9yZSBleHBsaWNpdGx5LiAKCk5vdGUgdGhhdCBNRENBLCBhbmQgdGhlIG90aGVyIG1lbWJlcnMgb2YgQ29sbG9zdHJ1Y3Rpb25hbCBBbmFseXNpcywgaW52b2x2ZXMgcmVwZWF0ZWQgc2lnbmlmaWNhbmNlIHRlc3Rpbmcgb24gdGhlIHNhbWUgZGF0YSBzZXQgW0BzdGVmYW5vd2l0c2NoX2NvdmFyeWluZ18yMDA1LCBwLiAzNiwgZW5kbm90ZSAzOyBAc3RlZmFub3dpdHNjaF9jb3Jwb3JhXzIwMDksIHAuIDk0NF0uIEFzIGEgcnVsZS1vZi10aHVtYiwgdGhlIHN0YW5kYXJkIHRocmVzaG9sZCBmb3IgdGhlIHNpZ25pZmljYW5jZSBsZXZlbCwgdGhhdCBpcyAqcCp+Qmlub21pYWx+IDwgMC4wNSwgc2hvdWxkIGJlIGNvcnJlY3RlZCBmb3Igc3VjaCByZXBlYXRlZCBzaWduaWZpY2FuY2UgdGVzdGluZywgdXNpbmcgZWl0aGVyIHRoZSBCb25mZXJyb25pIG9yIEhvbG0ncyBjb3JyZWN0aW9uIG1ldGhvZHNeW1RoZXNlIGNvcnJlY3Rpb24gbWV0aG9kcyBhcmUgYXZhaWxhYmxlIGluICpSKiB2aWEgdGhlIGBwLmFkanVzdCgpYCBidWlsdC1pbiBmdW5jdGlvbiBpbiB0aGUgYHtzdGF0c31gIHBhY2thZ2UuIFRoZSBgcC5hZGp1c3QoKWAgZnVuY3Rpb24gcmVxdWlyZXMgYXQgbGVhc3QgdHdvIGlucHV0LWFyZ3VtZW50czogKGkpIHRoZSBudW1lcmljIHZlY3RvciBvZiAqcCotdmFsdWVzIGZyb20gZWFjaCBzaWduaWZpY2FuY2UgdGVzdGluZywgYW5kIChpaSkgdGhlIG5hbWVzIG9mIHRoZSBjb3JyZWN0aW9uIG1ldGhvZHMgdG8gYmUgdXNlZCwgZS5nLiAiYm9uZmVycm9uaSIgb3IgImhvbG0iLiBTZWUgdGhlIGZvbGxvd2luZyB3ZWJzaXRlIGZvciBleGFtcGxlczogaHR0cDovL3Jjb21wYW5pb24ub3JnL3Jjb21wYW5pb24vZl8wMS5odG1sLl0gW0Bncmllc19zdGF0aXN0aWNzXzIwMDksIHBwLiAyNDItMjQzXS4gVGhlIGNvcnJlY3Rpb24gaXMgbWVhbnQgdG8gcmVzdHJpY3QgdGhlIHNpZ25pZmljYW5jZSB0aHJlc2hvbGQgZm9yIHJlcGVhdGVkIHRlc3RzIHNpbmNlIHRoZXJlIGNhbiBiZSBtb3JlIGNoYW5jZXMgZm9yICJhIHNlZW1pbmdseSBzaWduaWZpY2FudCByZXN1bHQgaGFzIGNvbWUgYWJvdXQgYnkgYWNjaWRlbnQiIHdoZW4gbW9yZSBzaWduaWZpY2FuY2UgdGVzdHMgYXJlIHBlcmZvcm1lZCBbQHN0ZWZhbm93aXRzY2hfY29nbml0aXZlXzIwMTEsIHAuIDI3NSwgZm9vdG5vdGUgNV0uIENvbnNlcXVlbnRseSwgb25seSBjZXJ0YWluIGl0ZW1zLCB3aG9zZSBvcmlnaW5hbCAqcCp+Qmlub21pYWx+LXZhbHVlcyBhcmUgYmVsb3cgdGhlIGNvcnJlY3RlZCBzaWduaWZpY2FuY2UgdGhyZXNob2xkLCBpZiBhbnksIHdpbGwgYmUgc3RyaWN0bHkgY29uc2lkZXJlZCBzaWduaWZpY2FudC4gSG93ZXZlciwgbW9zdCBDb2xsb3N0cnVjdGlvbmFsIEFuYWx5c2lzIHN0dWRpZXMgYXJlIHJlbGF4ZWQgcmVnYXJkaW5nIHN1Y2ggY29ycmVjdGlvbi4gVGhlIG1haW4gcmVhc29uIGlzIHRoYXQgaXQgaXMgdGhlIEFzc29jU3RyLWJhc2VkICpyYW5raW5nKiBvZiB0aGUgY29sbGV4ZW1lcyAob3IsIGluIG91ciBjYXNlLCB0aGUgbWV0YXBob3JzKSB0aGF0IGlzIHRoZSBtb3N0IHJlbGV2YW50IGZvciB0aGUgQ29sbG9zdHJ1Y3Rpb25hbCBBbmFseXNpcywgcmF0aGVyIHRoYW4gdGhlIHN0cmljdCBjb3JyZWN0ZWQgc2lnbmlmaWNhbmNlIGxldmVsIFtAc3RlZmFub3dpdHNjaF9jb3ZhcnlpbmdfMjAwNSwgcC4gMzYsIGVuZG5vdGUgMzsgQHN0ZWZhbm93aXRzY2hfZnVuY3Rpb25fMjAwNSwgcC4gMTc4OyBAc3RlZmFub3dpdHNjaF9jb3Jwb3JhXzIwMDksIHAuIDk0NF0uIEFub3RoZXIgcmVhc29uIGlzIHRoZSB0cmFkaXRpb24gaW4gY29ycHVzIGxpbmd1aXN0aWNzIHRoYXQgY29uc2lkZXJzIGVhY2ggc2lnbmlmaWNhbmNlIHRlc3QgYXMgYW4gaW5kZXBlbmRlbmNlIHRlc3QgW0BzdGVmYW5vd2l0c2NoX2NvcnBvcmFfMjAwOSwgcC4gOTQ0XS4gU2ltaWxhciBwcmFjdGljZSBpcyBhbHNvIGFkb3B0ZWQgaW4gdGhlICpTZW1hbnRpYyBQcm9maWxlKiBzdHVkeSBieSBKYW5kYSAmIEx5YXNoZXZza2F5YSBbLUBqYW5kYV9zZW1hbnRpY18yMDEzXSwgaW4gd2hpY2ggdGhlcmUgaXMgbm8gbWVudGlvbiBvZiBhIGNvcnJlY3Rpb24gbWV0aG9kIHVzZWQgZm9yIHRoZSAqcCp+RmlzaGVyWWF0ZXNFeGFjdH4tdmFsdWVzIGluIHRoZSBwYXBlci4KCkluIHRoaXMgY2hhcHRlciwgZm9sbG93aW5nIFN0ZWZhbm93aXRzY2ggWy1Ac3RlZmFub3dpdHNjaF9jb2duaXRpdmVfMjAxMSwgcC4gMjgyXSwgSSByZXBvcnQgdGhlIGRpc3RpbmN0aXZlIGFuZCByZXBlbGxlZCBtZXRhcGhvcnMgZm9yIGVhY2ggc3lub255bSB0aGF0IGFyZSAqYm90aCogc2lnbmlmaWNhbnQgYXQgdGhlIHVuY29ycmVjdGVkIHNpZ25pZmljYW5jZSBsZXZlbCwgYmFzZWQgb24gdGhlaXIgQXNzb2NTdHIgdmFsdWVzLCAqYW5kKiBhdCB0aGUgY29ycmVjdGVkIG9uZSwgdXNpbmcgdGhlIEhvbG0gbWV0aG9kIFtAZ3JpZXNfc3RhdGlzdGljc18yMDA5LCBwLiAyNDldLiBUaGUgcmVhc29uIGZvciB0aGlzIHJlcG9ydCBzdHJ1Y3R1cmUgaXMgdGhhdCwgYXMgU3RlZmFub3dpdHNjaCBbLUBzdGVmYW5vd2l0c2NoX2Z1bmN0aW9uXzIwMDUsIHAuIDE3OF0gaGFzIHNob3duLCBjb2xsZXhlbWVzL2l0ZW1zIHRoYXQgYXJlIGlkZW50aWZpZWQgYXMgb25seSAqbWFyZ2luYWxseSosIG9yIGV2ZW4gKm5vdCosIHNpZ25pZmljYW50LCBnaXZlbiBhIGNlcnRhaW4gc2lnbmlmaWNhbmNlIHRocmVzaG9sZCwgbWF5IGFsc28gcmV2ZWFsIHN5c3RlbWF0aWMgZGlmZmVyZW5jZXMgYmV0d2VlbiB0aGUgY29udHJhc3RlZCBjb25zdHJ1Y3Rpb24uIFRoYXQgaXMgYW1vbmdzdCB0aGUgcmVhc29ucyBmb3IgdGhlIHByaW1hcnkgaW1wb3J0YW5jZSBvZiB0aGUgKnJhbmtpbmcqIGluIENvbGxvc3RydWN0aW9uYWwgQW5hbHlzaXMuIEluIFtUYWJsZSBcQHJlZih0YWI6ZXhhbXBsZS1kYXRhLXByaW50KV0oI2V4YW1wbGUtZGF0YS1wcmludCkgYWJvdmUsIHRoZSBjb2x1bW4gInAuaG9sbSIgc2hvd3MgdGhlIGNvcnJlY3RlZCAqcCp+Qmlub21pYWx+LXZhbHVlcyB3aXRoIHRoZSBIb2xtIG1ldGhvZC4gVGhlICJkZWMiIGNvbHVtbiBpbmRpY2F0ZXMgdGhlIHNpZ25pZmljYW5jZSB0aHJlc2hvbGQgb2YgdGhlIGNvcnJlY3RlZCAqcCp+SG9sbX4tdmFsdWVzOiBgKioqYCA9ICpwKn5Ib2xtfiA8IDAuMDAxOyBgKipgID0gKnAqfkhvbG1+IDwgMC4wMTsgYCpgID0gKnAqfkhvbG1+IDwgMC4wNTsgYG1zYCA9IG1hcmdpbmFsbHkgc2lnbmlmaWNhbnQgYXQgKnAqfkhvbG1+ID4gMC4wNTsgYW5kIGBuc2AgPSBub3Qgc2lnbmlmaWNhbnQgYXQgKnAqfkhvbG1+ID4gMS4gRm9yIHRoZSBBc3NvY1N0ciBsaW1pdCwgSSBwcmVzZW50IHRoZSBtZXRhcGhvcnMgd2l0aCB0aGUgQXNzb2NTdHIgPiAyIChmb3IgYXR0cmFjdGlvbikgYW5kIEFzc29jU3RyIDwgLTIgKGZvciByZXB1bHNpb24pLiAKCiMjIERpc3RpbmN0aXZlIG1ldGFwaG9ycyBmb3IgKmtlYmFoYWdpYWFuKiAnaGFwcGluZXNzJyBhbmQgKmJhaGFnaWEqICdoYXBwaW5lc3MnIHsjYmFoYWdpYX0KCmBgYHtyIGtlYmFoYWdpYWFuLWRhdGEtbWFpbnRleHR9CiMjIHN1Ym1hcHBpbmdzIGZvciBERVNJUkVEIEdPQUwgZm9yIEtFQkFIQUdJQUFOLS0tLQojIGdldCB0aGUgc3VibWFwcGluZyBvZiB0aGUgREVTSVJFRCBHT0FMIG1ldGFwaG9yIGZvciBLRUJBSEFHSUFBTgprZWJhaGFnaWFhbl9zdWJtYXBwaW5nX2Rlc3RpbmF0aW9uIDwtIGhhcHB5cjo6Z2V0X3N1Ym1hcHBpbmdzKCJkZXNpcmVkIiwgImtlYmFoYWdpYWFuIiwgZGYgPSBoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yKQoKIyBkZXRlcm1pbmUgd2hpY2ggc3VibWFwcGluZyBoaWdobGlnaHRzIHRoZSAnYXR0YWlubWVudCcgYXNwZWN0CmtlYmFoYWdpYWFuX2FzcGVjdF9hdHRhaW5tZW50IDwtIGtlYmFoYWdpYWFuX3N1Ym1hcHBpbmdfZGVzdGluYXRpb24gJT4lIGZpbHRlcihzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAicmVhY2hpbmd8Z3Jhc3Bpbmd8ZmluZGluZyIpKQoKIyBkZXRlcm1pbmUgd2hpY2ggc3VibWFwcGluZyBoaWdobGlnaHRzIHRoZSAncHVyc3VpbmcvbW90aW9uIHByb2Nlc3MnIGFzcGVjdHMKa2ViYWhhZ2lhYW5fYXNwZWN0X3B1cnN1aW5nIDwtIGtlYmFoYWdpYWFuX3N1Ym1hcHBpbmdfZGVzdGluYXRpb24gJT4lIGZpbHRlcihzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAicHVyc3Vpbmd8YWltaW5nIikpCgojIGRldGVybWluZSB3aGljaCBzdWJtYXBwaW5nIGhpZ2hsaWdodHMgdGhlICdhaWRzIGZvciBtb3Rpb24nIGFzcGVjdAprZWJhaGFnaWFhbl9hc3BlY3RfYWlkcyA8LSBrZWJhaGFnaWFhbl9zdWJtYXBwaW5nX2Rlc3RpbmF0aW9uICU+JSBmaWx0ZXIoc3RyX2RldGVjdChzdWJtYXBwaW5ncywgImFpZHMiKSkKCiMgZGV0ZXJtaW5lIHdoaWNoIHN1Ym1hcHBpbmcgaGlnaGxpZ2h0cyB0aGUgJ2dvYWwtZW5kIG9mIG1vdGlvbicgYXNwZWN0CmtlYmFoYWdpYWFuX2FzcGVjdF9nb2FsIDwtIGtlYmFoYWdpYWFuX3N1Ym1hcHBpbmdfZGVzdGluYXRpb24gJT4lIGZpbHRlcihzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAiZW5kIG9mIGEgcGF0aCIpKQoKIyBnZXQgdGhlIHRvdGFsIHByb3BvcnRpb24gb2YgJ2F0dGFpbm1lbnQnIGFzcGVjdCBmcm9tIHRoZSB0b3RhbCB0b2tlbnMgb2YgdGhlIERFU0lSRUQgR09BTCBtZXRhcGhvcnMKa2ViYWhhZ2lhYW5fcHJvcGFzcF9hdHRhaW50bWVudCA8LSBzdW0oa2ViYWhhZ2lhYW5fYXNwZWN0X2F0dGFpbm1lbnQkcGVyYykKCiMgZ2V0IHRoZSB0b3RhbCBwcm9wb3J0aW9uIG9mICdwdXJzdWluZy9tb3Rpb24gcHJvY2VzcycgYXNwZWN0cyBmcm9tIHRoZSB0b3RhbCB0b2tlbnMgb2YgdGhlIERFU0lSRUQgR09BTCBtZXRhcGhvcnMKa2ViYWhhZ2lhYW5fcHJvcGFzcF9wdXJzdWluZyA8LSBzdW0oa2ViYWhhZ2lhYW5fYXNwZWN0X3B1cnN1aW5nJHBlcmMpCgojIGdldCB0aGUgdG90YWwgcHJvcG9ydGlvbiBvZiAnYWlkcycgYXNwZWN0IGZyb20gdGhlIHRvdGFsIHRva2VucyBvZiB0aGUgREVTSVJFRCBHT0FMIG1ldGFwaG9ycwprZWJhaGFnaWFhbl9wcm9wYXNwX2FpZHMgPC0gc3VtKGtlYmFoYWdpYWFuX2FzcGVjdF9haWRzJHBlcmMpCgojIGdldCB0aGUgdG90YWwgcHJvcG9ydGlvbiBvZiAnZ29hbCBlbmQgb2YgYSBwYXRoJyBhc3BlY3QgZnJvbSB0aGUgdG90YWwgdG9rZW5zIG9mIHRoZSBERVNJUkVEIEdPQUwgbWV0YXBob3JzCmtlYmFoYWdpYWFuX3Byb3Bhc3BfZ29hbCA8LSBzdW0oa2ViYWhhZ2lhYW5fYXNwZWN0X2dvYWwkcGVyYykKCiMjIENPTlRPSCBVTlRVSyBERVNJUkVEIEdPQUwKIyhAcmVhY2hpbmdfa2JoZ24pIGtlbmFwYSBvcmFuZyBpbmdpbiBtZW5pa2FoIGRhbiAqKm1lbmNhcGFpKiogKmtlYmFoYWdpYWFuKiBoYXJ1cyBkaWhhbGFuZ2kgKGluZF9taXhlZDIwMTJfMU06MzE2OTAyKQojKEBncmFzcGluZ19rYmhnbikgKmtlYmFoYWdpYWFuKiB5YW5nIHRlbGFoIGtpdGEgKipyZW5na3VoKiogZGFwYXQgdGVybGVwYXMgZGFuIGJlcmdhbnRpIGRlbmdhbiBwZW5kZXJpdGFhbiBoaWR1cCAoaW5kX21peGVkMjAxMl8xTToxNTAyNDYpCiMoQGZpbmRpbmdfa2JoZ24pIGRpIHNhbmFsYWgga2l0YSAqKm1lbmVtdWthbioqICprZWJhaGFnaWFhbiogZGFuIG1vdGl2YXNpIHlhbmcga3VhdCBkYWxhbSBiZWtlcmphIChpbmRfbmV3czIwMTFfMzAwSzoxNjI2OTApCgojIyBzdWJtYXBwaW5ncyBmb3IgUE9TU0VTU0FCTEUgT0JKRUNUIGZvciBLRUJBSEFHSUFBTi0tLS0KIyBnZXQgc3VibWFwcGluZyBvZiBQT1NTRVNTQUJMRSBPQkpFQ1QKa2JoZ19zdWJtZXRfcG9zc2VzcyA8LSBoYXBweXI6OmdldF9zdWJtYXBwaW5ncygicG9zc2Vzc2FibGUiLCAiYmFoYWdpYWFuIiwgZGYgPSBoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yKSAgJT4lIAogIG11dGF0ZShhc3BlY3QgPSBpZl9lbHNlKHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICIoZ2l2aW5nfGRpc3BlcnNpbmd8b2ZmZXJpbmd8Y2F1c2VkIG1vdGlvbikiKSwgImNhdXNlIiwgIm90aGVycyIpLCAKICAgICAgICAgYXNwZWN0ID0gaWZfZWxzZShzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAiZ2FpbmluZyIpLCAiZ2FpbmluZyIsIGFzcGVjdCksIAogICAgICAgICBhc3BlY3QgPSBpZl9lbHNlKHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICJwb3NzZXNzaW5nIiksICJwb3NzZXNzaW5nIiwgYXNwZWN0KSwgCiAgICAgICAgIGFzcGVjdCA9IGlmX2Vsc2Uoc3RyX2RldGVjdChzdWJtYXBwaW5ncywgIihsb3Npbmd8c2VpemVkKSIpLCAiY2Vhc2luZy9sb3NpbmciLCBhc3BlY3QpKQoKIyBnZXQgc3VibWFwcGluZyBvZiAnY2F1c2UnIGFzcGVjdAprYmhnX2FzcF9jYXVzZSA8LSBrYmhnX3N1Ym1ldF9wb3NzZXNzICU+JSBmaWx0ZXIoc3RyX2RldGVjdChzdWJtYXBwaW5ncywgImdpdmluZ3xjYXVzZWQgbW90aW9ufGRpc3BlcnNpbmd8b2ZmZXJpbmciKSkKCiMgZ2V0IHN1Ym1hcHBpbmcgb2YgJ2F0dGFpbm1lbnQnIGFzcGVjdAprYmhnX2FzcF9nYWluIDwtIGtiaGdfc3VibWV0X3Bvc3Nlc3MgJT4lIGZpbHRlcihzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAiZ2FpbmluZyIpKQoKIyBnZXQgc3VibWFwcGluZyBvZiAnZXhwZXJpZW5jZScgYXNwZWN0CmtiaGdfYXNwX3Bvc3Nlc3MgPC0ga2JoZ19zdWJtZXRfcG9zc2VzcyAlPiUgZmlsdGVyKHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICJwb3NzZXNzaW5nIikpCgojIGdldCBzdWJtYXBwaW5nIG9mICdsb3NpbmcnIGFzcGVjdAprYmhnX2FzcF9sb3NpbmcgPC0ga2JoZ19zdWJtZXRfcG9zc2VzcyAlPiUgZmlsdGVyKHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICJsb3Npbmd8c2VpemVkIikpCgojIyBzdWJtYXBwaW5ncyBmb3IgTU9WSU5HIE9CSkVDVCBmb3IgS0VCQUhBR0lBQU4tLS0tCiMgZ2V0IHN1Ym1hcHBpbmcgb2YgTU9WSU5HIE9CSkVDVAprYmhnX3N1Ym1ldF9tb3ZpbmdvYmplY3QgPC0gaGFwcHlyOjpnZXRfc3VibWFwcGluZ3MoIm1vdmluZyBvYmplY3QgdG8gYSBnb2FsIiwgImJhaGFnaWFhbiQiLCBkZiA9IGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IpCmBgYAoKYGBge3IgZGlzdGluY3RpdmUtZm9yLWtlYmFoYWdpYWFufQptZGNhX3JlcyAlPiUKICBoYXBweXI6Om1kY2FfYXR0cihjeG5fdHlwZSA9ICJrZWJhaGFnaWFhbiIsIG1pbl9hc3NvY3N0ciA9IDIpICU+JSAKICBtdXRhdGUoZXhwID0gcm91bmQoZXhwLCAzTCksCiAgICAgICAgIG1ldGFwaG9ycyA9IGhhcHB5cjo6c2NhcHMobWV0YXBob3JzKSkgJT4lIAogIHNlbGVjdCgtc3lub255bXMpICU+JQogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSAiRGlzdGluY3RpdmUgbWV0YXBob3JzIGZvciAqa2ViYWhhZ2lhYW4qICdoYXBwaW5lc3MnIiwgcm93Lm5hbWVzID0gVFJVRSkKYGBgCgoKRnJvbSBbVGFibGUgXEByZWYodGFiOmRpc3RpbmN0aXZlLWZvci1rZWJhaGFnaWFhbildKCNkaXN0aW5jdGl2ZS1mb3Ita2ViYWhhZ2lhYW4pLCB0aGUgbWV0YXBob3IgdGhhdCBpcyBtb3N0IGRpc3RpbmN0aXZlIGZvciAqa2ViYWhhZ2lhYW4qICdoYXBwaW5lc3MnIChOfm1ldGFwaG9yaWNhbH4gPSBgciBmaWx0ZXIoc3lub255bV90b2tlbiwgc3lub255bXMgPT0gImtlYmFoYWdpYWFuIilbWyJuIl1dYF5bVGhpcyB2YWx1ZSBpbmRpY2F0ZXMgdGhlIHRvdGFsIHRva2VucyBvZiBtZXRhcGhvcmljYWwgcGF0dGVybnMgZm9yIGEgc3lub255bSBpbiB0aGUgc2FtcGxlLl0gdG9rZW5zKSwgbmFtZWx5IGByIGhhcHB5cjo6c2NhcHMoJ2hhcHBpbmVzcyBpcyBhIGRlc2lyZWQgZ29hbC9kZXN0aW5hdGlvbicpYCBtZXRhcGhvciwgc3VnZ2VzdHMgdGhlIGFzcGlyYXRpdmUgbmF0dXJlIG9mICprZWJhaGFnaWFhbiogJ2hhcHBpbmVzcycuCgouLi4KCkZyb20gdGhlIHRvdGFsIHRva2VucyBvZiB0aGUgYHIgc2NhcHMoJ2Rlc2lyZWQgZ29hbC9kZXN0aW5hdGlvbicpYCBtZXRhcGhvciBvY2N1cmluZyB3aXRoICprZWJhaGFnaWFhbiosIG1vc3Qgb2YgdGhlIG1ldGFwaG9yaWNhbCBsZXhpY2FsIHVuaXRzIChMVXMpIGZvY3VzIG9mIG9uIHRoZSAnYXR0YWlubWVudCcgcmF0aGVyIHRoYW4gb24gdGhlIG90aGVyIGFzcGVjdHMsIHN1Y2ggYXMgdGhlICdwdXJzdWluZycuIFRoZSBwcm9taW5lbmNlIG9mICdhdHRhaW5tZW50JyBpcyByZWZsZWN0ZWQgaW4gYm90aCBpdHMgdG9rZW4gKGByIGtlYmFoYWdpYWFuX3Byb3Bhc3BfYXR0YWludG1lbnRgJSBvZiB0aGUgbWV0YXBob3IncyBgciBzdW0oa2ViYWhhZ2lhYW5fc3VibWFwcGluZ19kZXN0aW5hdGlvbiRuKWAgdG9rZW5zKSBhbmQgdHlwZSBmcmVxdWVuY2llcyAoYHIgc3VtKGtlYmFoYWdpYWFuX2FzcGVjdF9hdHRhaW5tZW50JHR5cGUpYCBkaWZmZXJlbnQgTFUgdHlwZXMpLgoKLi4uCgpJbiBteSBJbmRvbmVzaWFuIHNhbXBsZSwgKmtlYmFoYWdpYWFuKiBwcm9wb3J0aW9uYWxseSBtb3JlIGZyZXF1ZW50bHkgb2NjdXJzIGluIG1ldGFwaG9yaWNhbCBleHByZXNzaW9ucyBkZW5vdGluZyB0aGUgJ3RyYW5zZmVycmluZycgb2YgdGhlIHBvc3Nlc3NhYmxlIG9iamVjdCAoYHIgc3VtKGtiaGdfYXNwX2NhdXNlJHBlcmMpYCUpLCBhcyBpbiBfKiptZW1iZXJpa2FuKiogKFgpIGtlYmFoYWdpYWFuXyAndG8gKmdpdmUqIChYKSBoYXBwaW5lc3MnIChiYXNlZCBvbiB0aGUgYHIgaGFwcHlyOjpzY2FwcygnZ2l2aW5nJylgIGZyYW1lKSwgXyoqbWVtYmF3YSoqIGtlYmFoYWdpYWFuXyAndG8gKmJyaW5nKiBoYXBwaW5lc3MnIChgciBoYXBweXI6OnNjYXBzKCdjYXVzZWQgbW90aW9uJylgIGZyYW1lKSwgYW5kIF8qKmJlcmJhZ2kqKiBrZWJhaGFnaWFhbl8gJ3RvICpzaGFyZSogaGFwcGluZXNzJyAoYHIgaGFwcHlyOjpzY2FwcygnZGlzcGVyc2FsJylgIGZyYW1lKSwgYW1vbmcgdGhlIG1vc3QgZnJlcXVlbnQgbWV0YXBob3JpY2FsIHBhdHRlcm5zLgoKLi4uCgpJbiBjb250cmFzdCB0byAqa2ViYWhhZ2lhYW4qLCB0aGUgdGhyZWUgbW9zdCBkaXN0aW5jdGl2ZSBtZXRhcGhvcnMgYXQgdGhlIGNvcnJlY3RlZCBzaWduaWZpY2FuY2UgbGV2ZWwgZm9yIGl0cyByb290LCBuYW1lbHkgKmJhaGFnaWEqICdoYXBweTsgaGFwcGluZXNzJywgYnJvYWRseSBoaWdobGlnaHRzIHRoZSBleHBlcmllbmNlIG9yIGZlZWxpbmcgYXNwZWN0IG9mICpiYWhhZ2lhKiAoTn5tZXRhcGhvcmljYWx+ID0gYHIgZmlsdGVyKHN5bm9ueW1fdG9rZW4sIHN5bm9ueW1zID09ICJiYWhhZ2lhIilbWyJuIl1dYCkgKGNmLiBbVGFibGUgXEByZWYodGFiOmRpc3RpbmN0aXZlLWZvci1iYWhhZ2lhKV0oI2Rpc3RpbmN0aXZlLWZvci1iYWhhZ2lhKSkuCgpgYGB7ciBkaXN0aW5jdGl2ZS1mb3ItYmFoYWdpYX0KbWRjYV9yZXMgJT4lCiAgaGFwcHlyOjptZGNhX2F0dHIoY3huX3R5cGUgPSAiXmJhaGFnaWEkIiwgbWluX2Fzc29jc3RyID0gMikgJT4lIAogIG11dGF0ZShleHAgPSByb3VuZChleHAsIDNMKSwKICAgICAgICAgbWV0YXBob3JzID0gaGFwcHlyOjpzY2FwcyhtZXRhcGhvcnMpKSAlPiUgCiAgc2VsZWN0KC1zeW5vbnltcykgJT4lCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICBrbml0cjo6a2FibGUoY2FwdGlvbiA9ICJEaXN0aW5jdGl2ZSBtZXRhcGhvcnMgZm9yICpiYWhhZ2lhKiAnaGFwcHk7IGhhcHBpbmVzcyciLCByb3cubmFtZXMgPSBUUlVFKQpgYGAKCltUYWJsZSBcQHJlZih0YWI6cmVwZWxsZWQtYnkta2ViYWhhZ2lhYW4pXSgjcmVwZWxsZWQtYnkta2ViYWhhZ2lhYW4pIHNob3dzIHRoZSBtZXRhcGhvcnMgdGhhdCBhcmUgc3Ryb25nbHkgcmVwZWxsZWQgYnkgKmtlYmFoYWdpYWFuKiAnaGFwcGluZXNzJy4KCmBgYHtyIHJlcGVsbGVkLWJ5LWtlYmFoYWdpYWFufQptZGNhX3JlcyAlPiUKICBoYXBweXI6Om1kY2FfcmVwZWwoY3huX3R5cGUgPSAia2ViYWhhZ2lhYW4iLCBtaW5fYXNzb2NzdHIgPSAtMikgJT4lIAogIG11dGF0ZShleHAgPSByb3VuZChleHAsIDNMKSwKICAgICAgICAgbWV0YXBob3JzID0gaGFwcHlyOjpzY2FwcyhtZXRhcGhvcnMpKSAlPiUgCiAgc2VsZWN0KC1zeW5vbnltcykgJT4lCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSAiUmVwZWxsZWQgbWV0YXBob3JzIGZvciAqa2ViYWhhZ2lhYW4qICdoYXBwaW5lc3MnIiwgcm93Lm5hbWVzID0gVFJVRSkKYGBgCgpbVGFibGUgXEByZWYodGFiOnJlcGVsbGVkLWJ5LWJhaGFnaWEpXSgjcmVwZWxsZWQtYnktYmFoYWdpYSkgc2hvd3MgdGhlIG1ldGFwaG9ycyB0aGF0IGFyZSBzdHJvbmdseSByZXBlbGxlZCBieSAqYmFoYWdpYSogJ2hhcHBpbmVzcycuCgpgYGB7ciByZXBlbGxlZC1ieS1iYWhhZ2lhfQptZGNhX3JlcyAlPiUKICBoYXBweXI6Om1kY2FfcmVwZWwoY3huX3R5cGUgPSAiXmJhaGFnaWEkIiwgbWluX2Fzc29jc3RyID0gLTIpICU+JSAKICBtdXRhdGUoZXhwID0gcm91bmQoZXhwLCAzTCksCiAgICAgICAgIG1ldGFwaG9ycyA9IGhhcHB5cjo6c2NhcHMobWV0YXBob3JzKSkgJT4lIAogIHNlbGVjdCgtc3lub255bXMpICU+JQogIGtuaXRyOjprYWJsZShjYXB0aW9uID0gIlJlcGVsbGVkIG1ldGFwaG9ycyBmb3IgKmJhaGFnaWEqICdoYXBweTsgaGFwcGluZXNzJyIsIHJvdy5uYW1lcyA9IFRSVUUpCmBgYAoKTmV4dCwgdGhlIHJlc3VsdHMgb2YgTURDQSBmb3IgdGhlICh3aW5kb3ctYmFzZWQpIGRpc3RpbmN0aXZlIGxleGljYWwgY28tb2NjdXJyZW5jZSwgb3IgY29sbG9jYXRlcywgb2YgKmtlYmFoYWdpYWFuKl5bSSBsaW1pdCB0aGUgc2NvcGUgZm9yIHRoZSBjb2xsb2NhdGlvbiBkYXRhIHRvIHRoZSBub21pbmFsaXNlZCBmb3JtcyBvZiB0aGUgYHIgaGFwcHlyOjpzY2FwcygiaGFwcGluZXNzIilgIHN5bm9ueW1zIGZvciB0d28gcmVhc29ucy4gRmlyc3QsIHRoZXkgYXJlIG1vcmUgZnJlcXVlbnQgdGhhbiB0aGVpciBjb3JyZXNwb25kaW5nIHJvb3Qtbm9taW5hbCBmb3Jtcy4gU2Vjb25kLCB0aGV5IGFyZSBleGNsdXNpdmVseSB1c2VkIGFzIG5vbWluYWxzIHdpdGggaW5oZXJlbnQgcmVmZXJlbmNlIGZ1bmN0aW9uLiBNZWFud2hpbGUsIHRoZSB0eXBpY2FsIHVzYWdlcyBvZiB0aGUgcm9vdCBmb3JtcyBhcmUgYXR0cmlidXRpdmUgYW5kIHByZWRpY2F0aXZlLCByYXRoZXIgdGhhbiBub21pbmFsL3JlZmVyZW5jZSBmdW5jdGlvbi5dIHJldmVhbCBmdXJ0aGVyIHNlbWFudGljIG51YW5jZXMuIFRoZXkgaW5kaWNhdGUgd2hhdCBjb25jZXB0cyAoZS5nLiBvdGhlciBlbW90aW9ucywgYXR0aXR1ZGVzLCBkZXNjcmlwdGlvbnMsIG9yIGV2YWx1YXRpb25zKSBhcmUgc3Ryb25nbHkgYXNzb2NpYXRlZCB3aXRoICprZWJhaGFnaWFhbiogaW4gdGhlIGNvcnB1cy4gVGhlb3JldGljYWxseSwgdGhlIGNvbmNlcHRzIGV2b2tlZCBieSB0aGUgZGlzdGluY3RpdmUgY29sbG9jYXRlcyBjYW4gYmUgYW4gb3BlcmF0aW9uYWxpc2F0aW9uIGZvciBLw7Z2ZWNzZXMnIFstQGtvdmVjc2VzX3doZXJlXzIwMTUsIHAuIDE1OF0gaWRlYSByZWdhcmRpbmcgKnJlbGF0ZWQgY29uY2VwdHMqIGZvciBjZXJ0YWluIGVtb3Rpb25zIFtjZi4gQG9zdGVyX3VzaW5nXzIwMTAsIGZvciBzaW1pbGFyIHVzZXMgb2YgY29sbG9jYXRpb24gZGF0YSB0byByZXZlYWwgY29uY2VwdHVhbCBwcm94aW1pdHkgYW5kIHNlbWFudGljIHByb3NvZHkgb2YgYW4gZW1vdGlvbi5dLgoKYGBge3IgY29sbG9jLXJlcy1rZWJhaGFnaWFhbn0KIyBwcmVzZW50IHRoZSByZXN1bHQgdGFibGUgZm9yIGNvbGxvY2F0aW9uYWwgYW5hbHlzaXMgZm9yICprZWJhaGFnaWFhbioKaGFwcHlyOjptZGNhX2F0dHIobWRjYV9jb2xsb2MsIGN4bl90eXBlID0gJ15rZWJhaGFnaWFhbicpICU+JSAKICB0b3BfbigyMCwgYXNzb2NzdHIpICU+JSAKICBsZWZ0X2pvaW4oaGFwcHlyOjpkaXN0X2NvbGxvY19nbG9zcywgYnkgPSAiY29sbG9jYXRlcyIpICU+JSAjIGxlZnQtam9pbiB0aGUgZ2xvc3MgZm9yIHRoZSBkaXN0aW5jdGl2ZSBjb2xsb2NhdGVzCiAgc2VsZWN0KC1zeW5vbnltcykgJT4lCiAgc2VsZWN0KGNvbGxvY2F0ZXMsIGdsb3NzLCBldmVyeXRoaW5nKCkpICU+JQogIG11dGF0ZShleHAgPSByb3VuZChleHAsIDMpLCAKICAgICAgICAgY29sbG9jYXRlcyA9IHBhc3RlKCIqIiwgY29sbG9jYXRlcywgIioiLCBzZXAgPSAiIikpICU+JQogIGtuaXRyOjprYWJsZShjYXB0aW9uPSJUaGUgMjAgbW9zdCBkaXN0aW5jdGl2ZSwgNC13aW5kb3cgc3BhbiBjb2xsb2NhdGVzIGZvciAqa2ViYWhhZ2lhYW4qICdoYXBwaW5lc3MnIGluIHRoZSB3aG9sZSBJbmRvbmVzaWFuIExlaXB6aWcgQ29ycG9yYSBjb2xsZWN0aW9uLiIsIHJvdy5uYW1lcyA9IFRSVUUpCmBgYAoKIyMgRGlzdGluY3RpdmUgbWV0YXBob3JzIGZvciAqa2VzZW5hbmdhbiogJ3BsZWFzdXJlOyBoYXBwaW5lc3MnIGFuZCAqc2VuYW5nKiAnaGFwcHk7IGhhcHBpbmVzczsgdG8gZmVlbCB3ZWxsJyB7I3NlbmFuZ30KCmBgYHtyIGtlc2VuYW5nYW4tZGF0YS1tYWludGV4dH0KIyBzdWJtYXBwaW5nIGZvciBQT1NTRVNTQUJMRSBPQkpFQ1QgZm9yICprZXNlbmFuZ2FuKi0tLS0Ka3NuZ19zdWJtZXRfcG9zc2VzcyA8LSBoYXBweXI6OmdldF9zdWJtYXBwaW5ncyhtZXRhcGhvciA9ICJwb3NzZXNzYWJsZSIsIHdvcmQgPSAia2VzZW5hbmdhbiIsIGRmID0gaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvcikgJT4lIAogIG11dGF0ZShhc3BlY3QgPSBpZl9lbHNlKHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICIoZ2l2aW5nfGRpc3BlcnNpbmd8b2ZmZXJpbmd8Y2F1c2VkIG1vdGlvbikiKSwgImNhdXNlIiwgIm90aGVycyIpLCAKICAgICAgICAgYXNwZWN0ID0gaWZfZWxzZShzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAiZ2FpbmluZyIpLCAiZ2FpbmluZyIsIGFzcGVjdCksIAogICAgICAgICBhc3BlY3QgPSBpZl9lbHNlKHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICJwb3NzZXNzaW5nIiksICJwb3NzZXNzaW5nIiwgYXNwZWN0KSwgCiAgICAgICAgIGFzcGVjdCA9IGlmX2Vsc2Uoc3RyX2RldGVjdChzdWJtYXBwaW5ncywgIihsb3Npbmd8c2VpemVkKSIpLCAiY2Vhc2luZy9sb3NpbmciLCBhc3BlY3QpKQoKIyBzdWJtYXBwaW5nIGZvciBERVNJUkVEIE9CSkVDVCBmb3IgKmtlc2VuYW5nYW4qLS0tLQpwdXJzdWluZ19wZXJjIDwtIGhhcHB5cjo6Z2V0X3N1Ym1hcHBpbmdzKG1ldGFwaG9yID0gImRlc2lyZWQgZ29hbCIsIHdvcmQgPSAia2VzZW5hbmdhbiIsIGRmID0gaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvcikgJT4lIAogIGZpbHRlcihzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAicHVyc3Vpbmd8YWltaW5nIikpICU+JSAKICB0YWxseShwZXJjKSAlPiUgCiAgdW5saXN0KCkKCiMgdG90YWwgdG9rZW5zIG9mIChVTilNSVhFRCBTVUJTVEFOQ0Ugb3ZlcmFsbC0tLS0tCm1peGVkX3N1YnN0YW5jZV90b2tlbnMgPC0gZGltKGZpbHRlcihoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yLCBzdHJfZGV0ZWN0KG1ldGFwaG9ycywgIm1peGVkIikpKVsxXQoKIyMgdG9rZW5zIGluZGljYXRpbmcgJ3B1cmUnIHN1YnN0YW5jZQptaXhlZF9zdWJzdGFuY2VfcHVyZV90b2tlbnMgPC0gZGltKGZpbHRlcihoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yLCBzdHJfZGV0ZWN0KG1ldGFwaG9ycywgIm1peGVkIiksIHN0cl9kZXRlY3QobHUsICJtdXJuaSIpKSlbMV0gCgojIyB0b2tlbnMgaW5kaWNhdGluZyAnbWl4ZWQnIHN1YnN0YW5jZQptaXhlZF9zdWJzdGFuY2VfbWl4ZWRfdG9rZW5zIDwtIG1peGVkX3N1YnN0YW5jZV90b2tlbnMgLSBtaXhlZF9zdWJzdGFuY2VfcHVyZV90b2tlbnMKYGBgCgpgYGB7ciBkaXN0aW5jdGl2ZS1mb3Ita2VzZW5hbmdhbn0KbWRjYV9yZXMgJT4lCiAgaGFwcHlyOjptZGNhX2F0dHIoY3huX3R5cGUgPSAia2VzZW5hbmdhbiIsIG1pbl9hc3NvY3N0ciA9IDIpICU+JSAKICBtdXRhdGUoZXhwID0gcm91bmQoZXhwLCAzTCksCiAgICAgICAgIG1ldGFwaG9ycyA9IGhhcHB5cjo6c2NhcHMobWV0YXBob3JzKSkgJT4lIAogIHNlbGVjdCgtc3lub255bXMpICU+JQogIGtuaXRyOjprYWJsZShjYXB0aW9uID0gIkRpc3RpbmN0aXZlIG1ldGFwaG9ycyBmb3IgKmtlc2VuYW5nYW4qICdwbGVhc3VyZTsgaGFwcGluZXNzJyIsIHJvdy5uYW1lcyA9IFRSVUUpCmBgYAoKClRoZSBmaXJzdCBwb2ludCwgYXMgSSBoYXZlIG1lbnRpb25lZCwgaXMgdGhhdCBgciBoYXBweXI6OnNjYXBzKHRvbG93ZXIoJ0hBUFBJTkVTUyBJUyBBIERFU0lSRUQgR09BTC9ERVNUSU5BVElPTicpKWAgaXMgYWxzbyB0aGUgbW9zdCBkaXN0aW5jdGl2ZSBtZXRhcGhvciBmb3IgX2tlc2VuYW5nYW5fICdwbGVhc3VyZScgYXMgaXQgaXMgZm9yIF9rZWJhaGFnaWFhbl8gJ2hhcHBpbmVzcycsIHRob3VnaCB0aGUgbWV0YXBob3IgaXMgbW9zdCBzdHJvbmdseSBhc3NvY2lhdGVkIHdpdGggdGhlIGxhdHRlciBhY2NvcmRpbmcgdG8gaXRzIEFzc29jU3RyIHZhbHVlcyAoYHIgZmlsdGVyKGV4YW1wbGVfZGYsIHN5bm9ueW1zID09ICJrZXNlbmFuZ2FuIilbWyJhc3NvY3N0ciJdXWAgZm9yICprZXNlbmFuZ2FuKiB2cy4gYHIgZmlsdGVyKGV4YW1wbGVfZGYsIHN5bm9ueW1zID09ICJrZWJhaGFnaWFhbiIpW1siYXNzb2NzdHIiXV1gIGZvciAqa2ViYWhhZ2lhYW4qKS4gRGVzcGl0ZSB0aGlzIHNpbWlsYXIgYXR0cmFjdGlvbiwgYSBmaW5lciBncmFpbmVkIGRpZmZlcmVuY2UgZW1lcmdlcyBiZXR3ZWVuIHRoZSB0d28gd29yZHMgaW4gcmVsYXRpb24gdG8gdGhlIHN1Ym1hcHBpbmdzIG9mIHRoZSBtZXRhcGhvci4gKktlc2VuYW5nYW4qIG1vc3QgZnJlcXVlbnRseSBvY2N1cnMgd2l0aCBtZXRhcGhvcmljYWwgcGF0dGVybnMgZGVub3RpbmcgdGhlICdwdXJzdWluZycgYXNwZWN0IChgciBwdXJzdWluZ19wZXJjYCUgb2YgYWxsIHRoZSB0b2tlbnMpIHJhdGhlciB0aGFuIHRoZSAnYXR0YWlubWVudCcsIHdoaWNoIGlzIG1vcmUgZnJlcXVlbnQgZm9yICprZWJhaGFnaWFhbiouCgouLi4KCmByIGhhcHB5cjo6Z2V0X2ZyYW1lcyhtZXRhcGhvciA9ICJpbXBlZGltZW50IHRvIG1vdGlvbiQiLCB3b3JkID0gImtlc2VuYW5nYW4iLCBkZiA9IGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IpICU+JSBmaWx0ZXIobiA9PSBtYXgobikpICU+JSAuJG4gJT4lIGhhcHB5cjo6bnVtYmVyczJ3b3JkcygpYCBvdXQgb2YgYHIgaGFwcHlyOjpnZXRfZnJhbWVzKG1ldGFwaG9yID0gImltcGVkaW1lbnQgdG8gbW90aW9uIiwgd29yZCA9ICJrZXNlbmFuZ2FuIiwgZGYgPSBoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yKSAlPiUgLiRuICU+JSBzdW0oKSAlPiUgaGFwcHlyOjpudW1iZXJzMndvcmRzKClgIHRva2VucyBmb3IgdGhlIG9jY3VycmVuY2Ugb2YgdGhpcyBtZXRhcGhvciB3aXRoICprZXNlbmFuZ2FuKiBldm9rZSB0aGUgYHIgaGFwcHlyOjpzY2FwcygicmVzdHJhaW50cyIpYCBmcmFtZS4gSW4gdGhpcyBmcmFtZSwgKmtlc2VuYW5nYW4qIG1hcHMgb250byB0aGUgUmVzdHJhaW5pbmdfZW50aXR5IHJvbGUgKGUuZy4gXyoqZGlrZW5kYWxpa2FuKiogb2xlaCBrZXNlbmFuZ2FuXyAndG8gYmUgKnJlaW5lZCBiYWNrKiBieSBwbGVhc3VyZScsIF9rZXNlbmFuZ2FuICoqbWVuZ2VuZGFsaWthbi9tZW5naWthdCoqIFhfICdwbGVhc3VyZSAqcmVpbnMgYmFjay9iaW5kcyogWCcsIF8qKm1lbWlrYXQqKiBYICoqcGFkYSoqIGtlc2VuYW5nYW5fICd0byAqZGVjb3kvZW5zbmFyZSogWCAqYXQqIHBsZWFzdXJlJykuIEluIHRoaXMgY2FzZSwgdGhlIEV4cGVyaWVuY2VyIGNvbWVzIHVuZGVyIHJlc3RyYWluaW5nIGNvbnRyb2wgb2YgKmtlc2VuYW5nYW4qIHRoYXQgbWFrZXMgaGltIGRpZmZpY3VsdCB0byB0YWtlIG90aGVyIGFjdGlvbnMuIAoKLi4uCgpGb3IgKmtlc2VuYW5nYW4qLCBgciBrc25nX3N1Ym1ldF9wb3NzZXNzICU+JSBmaWx0ZXIoYXNwZWN0ID09ICJnYWluaW5nIikgJT4lIC4kcGVyYyAlPiUgc3VtKClgJSBvZiB0aGUgdXNhZ2UgdG9rZW5zIGV2b2tlIHRoZSAncmVjZWl2aW5nJyBvZiB0aGUgUG9zc2Vzc2FibGVfb2JqZWN0IChpLmUuLCB0aGUgJ29uc2V0JyBvZiBwbGVhc3VyZSksIHdoaWNoIGlzIGJhc2VkIG9uIHRoZSBgciBoYXBweXI6OnNjYXBzKCJnYWluIHBvc3Nlc3Npb24iKWAgZnJhbWUuCgpgYGB7ciBkaXN0aW5jdGl2ZS1mb3Itc2VuYW5nfQptZGNhX3JlcyAlPiUKICBoYXBweXI6Om1kY2FfYXR0cihjeG5fdHlwZSA9ICJec2VuYW5nJCIsIG1pbl9hc3NvY3N0ciA9IDIpICU+JSAKICBtdXRhdGUoZXhwID0gcm91bmQoZXhwLCAzTCksCiAgICAgICAgIG1ldGFwaG9ycyA9IGhhcHB5cjo6c2NhcHMobWV0YXBob3JzKSkgJT4lIAogIHNlbGVjdCgtc3lub255bXMpICU+JQogIGtuaXRyOjprYWJsZShjYXB0aW9uID0gIkRpc3RpbmN0aXZlIG1ldGFwaG9ycyBmb3IgKnNlbmFuZyogJ2hhcHB5OyBoYXBwaW5lc3M7IHRvIGZlZWwgd2VsbCciLCByb3cubmFtZXMgPSBUUlVFKQpgYGAKCltUYWJsZSBcQHJlZih0YWI6cmVwZWxsZWQtYnkta2VzZW5hbmdhbildKCNyZXBlbGxlZC1ieS1rZXNlbmFuZ2FuKSBzaG93cyB0aGUgc3Ryb25nbHkgcmVwZWxsZWQgbWV0YXBob3JzIGZvciAqa2VzZW5hbmdhbiogJ3BsZWFzdXJlJy4KCmBgYHtyIHJlcGVsbGVkLWJ5LWtlc2VuYW5nYW59Cm1kY2FfcmVzICU+JQogIGhhcHB5cjo6bWRjYV9yZXBlbChjeG5fdHlwZSA9ICJrZXNlbmFuZ2FuIiwgbWluX2Fzc29jc3RyID0gLTIpICU+JSAKICBtdXRhdGUoZXhwID0gcm91bmQoZXhwLCAzTCksCiAgICAgICAgIG1ldGFwaG9ycyA9IGhhcHB5cjo6c2NhcHMobWV0YXBob3JzKSkgJT4lIAogIHNlbGVjdCgtc3lub255bXMpICU+JQogIGtuaXRyOjprYWJsZShjYXB0aW9uID0gIlJlcGVsbGVkIG1ldGFwaG9ycyBmb3IgKmtlc2VuYW5nYW4qICdwbGVhc3VyZTsgaGFwcGluZXNzJyIsIHJvdy5uYW1lcyA9IFRSVUUpCmBgYAoKW1RhYmxlIFxAcmVmKHRhYjpyZXBlbGxlZC1ieS1zZW5hbmcpXSgjcmVwZWxsZWQtYnktc2VuYW5nKSBzaG93cyB0aGUgc3Ryb25nbHkgcmVwZWxsZWQgbWV0YXBob3JzIGZvciAqc2VuYW5nKiAnaGFwcHk7IGhhcHBpbmVzczsgdG8gZmVlbCB3ZWxsJy4KCmBgYHtyIHJlcGVsbGVkLWJ5LXNlbmFuZ30KbWRjYV9yZXMgJT4lCiAgaGFwcHlyOjptZGNhX3JlcGVsKGN4bl90eXBlID0gInNlbmFuZyQiLCBtaW5fYXNzb2NzdHIgPSAtMikgJT4lIAogIG11dGF0ZShleHAgPSByb3VuZChleHAsIDNMKSwKICAgICAgICAgbWV0YXBob3JzID0gaGFwcHlyOjpzY2FwcyhtZXRhcGhvcnMpKSAlPiUgCiAgc2VsZWN0KC1zeW5vbnltcykgJT4lCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSAiUmVwZWxsZWQgbWV0YXBob3JzIGZvciAqc2VuYW5nKiAnaGFwcHk7IGhhcHBpbmVzczsgdG8gZmVlbCB3ZWxsJyIsIHJvdy5uYW1lcyA9IFRSVUUpCmBgYAoKTm93IEkgdHVybiB0byBkaXNjdXNzIHRoZSBkaXN0aW5jdGl2ZSBjb2xsb2NhdGVzIGZvciAqa2VzZW5hbmdhbiogJ3BsZWFzdXJlJyBzaG93biBpbiBbVGFibGUgXEByZWYodGFiOmNvbGxvYy1yZXMta2VzZW5hbmdhbildKCNjb2xsb2MtcmVzLWtlc2VuYW5nYW4pLgoKYGBge3IgY29sbG9jLXJlcy1rZXNlbmFuZ2FufQojIHByZXNlbnQgdGhlIHJlc3VsdCB0YWJsZSBmb3IgY29sbG9jYXRpb25hbCBhbmFseXNpcyBmb3IgKmtlc2VuYW5nYW4qCmhhcHB5cjo6bWRjYV9hdHRyKG1kY2FfY29sbG9jLCBjeG5fdHlwZSA9ICdea2VzZW5hbmdhbicpICU+JSAKICB0b3BfbigyMCwgYXNzb2NzdHIpICU+JSAKICBsZWZ0X2pvaW4oaGFwcHlyOjpkaXN0X2NvbGxvY19nbG9zcywgYnkgPSAiY29sbG9jYXRlcyIpICU+JSAjIGxlZnQtam9pbiB0aGUgZ2xvc3MgZm9yIHRoZSBkaXN0aW5jdGl2ZSBjb2xsb2NhdGVzCiAgc2VsZWN0KC1zeW5vbnltcykgJT4lCiAgc2VsZWN0KGNvbGxvY2F0ZXMsIGdsb3NzLCBldmVyeXRoaW5nKCkpICU+JQogIG11dGF0ZShleHAgPSByb3VuZChleHAsIDMpLCAKICAgICAgICAgY29sbG9jYXRlcyA9IHBhc3RlKCIqIiwgY29sbG9jYXRlcywgIioiLCBzZXAgPSAiIikpICU+JQogIGtuaXRyOjprYWJsZShjYXB0aW9uPSJUaGUgMjAgbW9zdCBkaXN0aW5jdGl2ZSwgNC13aW5kb3cgc3BhbiBjb2xsb2NhdGVzIGZvciAqa2VzZW5hbmdhbiogJ3BsZWFzdXJlOyBoYXBwaW5lc3MnIGluIHRoZSB3aG9sZSBJbmRvbmVzaWFuIExlaXB6aWcgQ29ycG9yYSBjb2xsZWN0aW9uLiIsIHJvdy5uYW1lcyA9IFRSVUUpCmBgYAoKU29tZSBvZiB0aGUgZGlzdGluY3RpdmUgY29sbG9jYXRlcyBvZiAqa2VzZW5hbmdhbiogcHJvdmlkZSBmdXJ0aGVyIHN1cHBvcnQgZm9yIGFyZ3VpbmcgdGhlIG5lZ2F0aXZlIGNvbnRvdXIgYXNzaWduZWQgdG8gKmtlc2VuYW5nYW4qLCBhcyBpbmZlcnJlZCBmcm9tIHRoZSBkaXN0aW5jdGl2ZSBtZXRhcGhvcnMuIFRvIGJlZ2luIHdpdGggdGhlIG1vc3QgZGlzdGluY3RpdmUgY29sbG9jYXRlLCBuYW1lbHkgKmR1bmlhd2kqICd3b3JkbHk7IGVhcnRobHknLCBldmVyeXRoaW5nIHJlbGF0ZWQgdG8gaXQgaXMgY29uY2VpdmVkIGFzIG11bmRhbmUgYW5kIHRlbmRzIHRvIGJlIGRpc3ByZWZlcnJlZCBvdmVyIHRoZSBkaXZpbml0eSwgaW5jb3Jwb3JlYWxpc20sIG9yIGV0ZXJuaXR5LCB3aGljaCBpcyBwcmVzY3JpYmVkIGJ5IGNlcnRhaW4gcmVsaWdpb3VzIHZpZXcuIFNpbWlsYXIgcmVsaWdpb3VzLWJhc2VkIG91dGxvb2sgdGhlbiBnaXZlcyBuZWdhdml0ZSBhc3NvY2lhdGlvbiB0byB0aGUgb3RoZXIgJ211bmRhbmUnLXJlbGF0ZWQgY29sbG9jYXRlcywgc3VjaCBhcyAqbmFmc3UqXltUaGUgd29yZCAqaGF3YSogJ2FpcicgaW4gW1RhYmxlIFxAcmVmKHRhYjpjb2xsb2MtcmVzLWtlc2VuYW5nYW4pXSgjY29sbG9jLXJlcy1rZXNlbmFuZ2FuKSBpcyBwYXJ0IG9mIGFuIGVzdGFibGlzaGVkIGNvbXBvdW5kIGluIEluZG9uZXNpYW4gd2l0aCB0aGUgd29yZCAqbmFmc3UqICdsdXN0JywgdGhhdCBpcyAqaGF3YSBuYWZzdSogJ2x1c3QsIGxpdC4gdGhlIGFpciBvZiB0aGUgbHVzdCcuIFRodXMsIHVwb24gaW5zcGVjdGluZyB0aGUgZnVsbCBzZW50ZW5jZXMgb2YgdGhlIGByIGhhcHB5cjo6bnVtYmVyczJ3b3JkcyhmaWx0ZXIobWRjYV9jb2xsb2MsIHN5bm9ueW1zID09ICJrZXNlbmFuZ2FuIiwgY29sbG9jYXRlcyA9PSAiaGF3YSIpW1sibiJdXSlgIHRva2VucyBmb3Igd2hpY2ggKmhhd2EqIGNvbGxvY2F0ZXMgd2l0aCAqa2VzZW5hbmdhbiogd2l0aGluIHRoZSBzcGFuIG9mIGZvdXIgd29yZHMgdG8gdGhlIGxlZnQgYW5kIHJpZ2h0LCB0aGVyZSBpcyBvbmx5IG9uZSBvY2Nhc2lvbiBpbiB3aGljaCAqaGF3YSogZG9lcyBub3QgY29sbG9jYXRlIHdpdGggKm5hZnN1KiwgYnV0IGFwcGVhcnMgYWxvbmUgaW5kaWNhdGluZyBpdHMgaG9tb255bXkgd2l0aCAqaGF3YSogbWVhbmluZyAnZmVtYWxlJyAodGhlIGFudG9ueW0gZm9yICpBZGFtKiAnbWFsZTsgbGl0LiBBZGFtJywgaGVuY2UgYW5vdGhlciBjb21tb24gcGhyYXNlICpLYXVtIEFkYW0gZGFuIEhhd2EqICdNYWxlIGFuZCBGZW1hbGUgZ3JvdXA7IGxpdCBBZGFtIGFuZCBFdmUgZ3JvdXAnKS5dICdsdXN0JywgKnNla3N1YWwqICdzZXh1YWwnLCAqa2VidXR1aGFuKiAnbmVlZHMnLCBhbmQgKmRvc2EqICdzaW4nLiBUaGlzIGlzIGRpZmZlcmVudCBmcm9tIHRoZSBwb3NpdGl2ZSBudWFuY2VzIG9mICprZWJhaGFnaWFhbiogYXMgY29udmV5ZWQgYnkgaXRzIGRpc3RpbmN0aXZlIGNvbGxvY2F0ZXMgKGNmLiBbVGFibGUgXEByZWYodGFiOmNvbGxvYy1yZXMta2ViYWhhZ2lhYW4pXSgjY29sbG9jLXJlcy1rZWJhaGFnaWFhbikpLiBBbm90aGVyIHRvcCBjb2xsb2NhdGUgZm9yICprZXNlbmFuZ2FuKiBpcyAqcHJpYmFkaSogJ3BlcnNvbmFsOyBwcml2YXRlJywgaW5kaWNhdGluZyB0aGUgc2VsZi1jZW50cmVkIG9mICprZXNlbmFuZ2FuKiBjb21wYXJlZCB0byAqa2ViYWhhZ2lhYW4qLCB3aGljaCBpcyBtb3JlIGFib3V0IHdpZGVyIGF1ZGllbmNlIChlLmcuICpvcmFuZyogJ3BlcnNvbicsICptYW51c2lhKiAnaHVtYW4nKS4gVGhpcyAncGVyc29uYWwvZ2VuZXJhbC1hdWRpZW5jZScgZmVhdHVyZSB3aWxsIGFsc28gYmUgc2hvd24gdG8gYmUgb25lIG9mIHRoZSBzZW1hbnRpYyBiZW5jaG1hcmtzIGRpc3Rpbmd1aXNoaW5nICprZXNlbmFuZ2FuKiAncGxlYXN1cmUnIHdpdGggdGhlIHJlbWFpbmluZyBgciBoYXBweXI6OnNjYXBzKCJoYXBwaW5lc3MiKWAgY29uY2VwdHMuCgojIyBEaXN0aW5jdGl2ZSBtZXRhcGhvcnMgZm9yICprZWdlbWJpcmFhbiogJ2pveTsgY2hlZXJmdWxuZXNzJyBhbmQgKmdlbWJpcmEqICdleGNpdGUoZC9tZW50KTsgZW50aHVzaWFzKHRpYy9tKScgeyNnZW1iaXJhfQoKYGBge3Iga2VnZW1iaXJhYW4tZGF0YS1tYWludGV4dH0KIyBzdWJtYXBwaW5nIGZvciBMSVFVSUQgSU4gQSBDT05UQUlORVIgbWV0YXBob3IKa2dtYl9zdWJtZXRfbGlxdWlkaW5jb250YWluZXIgPC0gaGFwcHlyOjpnZXRfc3VibWFwcGluZ3MobWV0YXBob3IgPSAibGlxdWlkIGluIGEgY29udGFpbmVyJCIsIHdvcmQgPSAia2VnZW1iaXJhYW4iLCBkZiA9IGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IpCgprZ21iX3Byb3Bfd2l0aF9saXF1aWRpbmNvbnRhaW5lciA8LSBtZGNhX3JlcyAlPiUgCiAgZmlsdGVyKHN0cl9kZXRlY3QobWV0YXBob3JzLCAibGlxdWlkIGluIGEgY29udGFpbmVyJCIpKSAlPiUgCiAgc2VsZWN0KDE6MykgJT4lIAogICMgZ2V0IHRoZSBwcm9wb3J0aW9uIG9mIHRoZSBMSVFVSUQgSU4gQSBDT05UQUlORVIgbWV0YXBob3IgYWNyb3NzIHRoZSBzeW5vbnltcwogIG11dGF0ZShwZXJjID0gcm91bmQobi9zdW0obikgKiAxMDAsIDIpKSAlPiUKICBhcnJhbmdlKGRlc2MocGVyYykpCgojIHN1Ym1hcHBpbmcgZm9yIChVTilWRUlMRUQgT0JKRUNUIG1ldGFwaG9yCmtnbWJfdW52ZWlsZWRfc3VibWV0IDwtIGhhcHB5cjo6Z2V0X3N1Ym1hcHBpbmdzKG1ldGFwaG9yID0gInZlaWxlZCIsIHdvcmQgPSAiKGtlZ2VtYmlyYWFufF5nZW1iaXJhKSIsIGRmID0gaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvcikKCmtnbWJfdW52ZWlsZWRfc3VibWV0X21heCA8LSBrZ21iX3VudmVpbGVkX3N1Ym1ldCAlPiUgCiAgZ3JvdXBfYnkoc3lub255bXMpICU+JSAKICBmaWx0ZXIocGVyYyA9PSBtYXgocGVyYykpICU+JQogIHVuZ3JvdXAoKQoKbmVnYXRlZF9zZW50ZW5jZXNfZm9yX2hpZGluZyA8LSAoOS8xMCkgKiAxMDAKYGBgCgpbVGFibGUgXEByZWYodGFiOmRpc3RpbmN0aXZlLWZvci1rZWdlbWJpcmFhbildKCNkaXN0aW5jdGl2ZS1mb3Ita2VnZW1iaXJhYW4pIHNob3dzIHRoZSBkaXN0aW5jdGl2ZSBtZXRhcGhvcnMgZm9yICprZWdlbWJpcmFhbiogJ2pveTsgY2hlZXJmdWxuZXNzJy4KCmBgYHtyIGRpc3RpbmN0aXZlLWZvci1rZWdlbWJpcmFhbn0KbWRjYV9yZXMgJT4lCiAgaGFwcHlyOjptZGNhX2F0dHIoY3huX3R5cGUgPSAia2VnZW1iaXJhYW4iLCBtaW5fYXNzb2NzdHIgPSAyKSAlPiUgCiAgbXV0YXRlKGV4cCA9IHJvdW5kKGV4cCwgM0wpLAogICAgICAgICBtZXRhcGhvcnMgPSBoYXBweXI6OnNjYXBzKG1ldGFwaG9ycykpICU+JSAKICBzZWxlY3QoLXN5bm9ueW1zKSAlPiUKICBrbml0cjo6a2FibGUoY2FwdGlvbiA9ICJEaXN0aW5jdGl2ZSBtZXRhcGhvcnMgZm9yICprZWdlbWJpcmFhbiogJ2pveTsgY2hlZXJmdWxuZXNzJyIsIHJvdy5uYW1lcyA9IFRSVUUpCmBgYAoKClR3byBzdWJtYXBwaW5ncyBhcmUgZG9taW5hbnQuIEZpcnN0LCBgciBmaWx0ZXIoa2dtYl9zdWJtZXRfbGlxdWlkaW5jb250YWluZXIsIHBlcmMgPT0gbWF4KHBlcmMpKVtbInBlcmMiXV1gJSBvZiB0aGUgdG9rZW5zIGNvbnNpc3RzIG9mIGV4cHJlc3Npb25zIGV2b2tpbmcgdGhlIGByIGhhcHB5cjo6c2NhcHMoInJlbGVhc2UgbGlxdWlkIilgIGZyYW1lLCB3aGljaCBpcyB1c2VkIHRvIGNvbnZleSB0aGUgZXhwcmVzc2lvbiBvZiB1bmNvbnRyb2xsZWQgaW50ZXJuYWwgZmVlbGluZywgaGVuY2UgdGhlIHN1Ym1hcHBpbmcgYHIgaGFwcHlyOjpzY2FwcyhmaWx0ZXIoa2dtYl9zdWJtZXRfbGlxdWlkaW5jb250YWluZXIsIHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICJyZWxlYXNlZCIpKVtbInN1Ym1hcHBpbmdzIl1dKWAuIFRoaXMgc3VibWFwcGluZyBmb3IgKmtlZ2VtYmlyYWFuKiBpcyBhbHNvIHRoZSBtb3N0IHByb2R1Y3RpdmUgaW4gY29tcGFyaXNvbiB0byB0aGUgb3RoZXJzIHNpbmNlIGl0IGlzIGV4cHJlc3NlZCBieSBgciBoYXBweXI6Om51bWJlcnMyd29yZHMoZmlsdGVyKGtnbWJfc3VibWV0X2xpcXVpZGluY29udGFpbmVyLCBzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAicmVsZWFzZWQiKSlbWyJ0eXBlIl1dKWAgZGlmZmVyZW50IGxleGljYWwgdW5pdCAoTFUpIHR5cGVzIChgciBmaWx0ZXIoa2dtYl9zdWJtZXRfbGlxdWlkaW5jb250YWluZXIsIHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICJyZWxlYXNlZCIpKVtbInR5cGVfcGVyYyJdXWAlIG9mIGFsbCB0eXBlcyBmb3IgdGhlIG1ldGFwaG9yIG9jY3VycmluZyB3aXRoICprZWdlbWJpcmFhbiopLgoKLi4uCgpUaGUgc2Vjb25kIGRvbWluYW50IHN1Ym1hcHBpbmcgaXMgYHIgaGFwcHlyOjpzY2FwcyhmaWx0ZXIoa2dtYl9zdWJtZXRfbGlxdWlkaW5jb250YWluZXIsIHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICJoZWF0ZWQiKSlbWyJzdWJtYXBwaW5ncyJdXSlgIChgciBmaWx0ZXIoa2dtYl9zdWJtZXRfbGlxdWlkaW5jb250YWluZXIsIHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICJoZWF0ZWQiKSlbWyJwZXJjIl1dYCUpLCB3aGljaCBpcyBiYXNlZCBvbiB0aGUgYHIgaGFwcHlyOjpzY2FwcygiaGVhdGVkIGxpcXVpZCIpYCBmcmFtZS4gVGhlIG1vc3QgZnJlcXVlbnQgbWV0YXBob3JpY2FsIHBhdHRlcm4gaXMgXyoqbWVsdWFwa2FuKioga2VnZW1iaXJhYW5fICd0byAqYm9pbCBvdmVyKiBqb3k7IGxpdC4gdG8gKmNhdXNlKiBqb3kgdG8gKmJvaWwgb3ZlcionLiBVbmxpa2UgdGhlIGByIGhhcHB5cjo6c2NhcHMoInJlbGVhc2UgbGlxdWlkIilgIGZyYW1lLCB0aGUgYHIgaGFwcHlyOjpzY2FwcygiaGVhdGVkIGZsdWlkIilgLWJhc2VkIHN1Ym1hcHBpbmcgaXMgb25seSBldm9rZWQgYnkgYHIgaGFwcHlyOjpudW1iZXJzMndvcmRzKGZpbHRlcihrZ21iX3N1Ym1ldF9saXF1aWRpbmNvbnRhaW5lciwgc3RyX2RldGVjdChzdWJtYXBwaW5ncywgImhlYXRlZCIpKVtbInR5cGUiXV0pYCBkaXN0aW5jdCBMVXM6ICptZWx1YXBrYW4qICd0byBjYXVzZSB0byBib2lsIG92ZXInIChhIGNhdXNhdGl2ZSB0cmFuc2l0aXZlIHZlcmIpIGFuZCAqbWVsdWFwKC1sdWFwKSogJ3RvIChrZWVwKSBib2lsKGluZykgb3ZlcicgKGFuIGludHJhbnNpdGl2ZSB2ZXJiKS4gIAoKLi4uCgpUaGUgaGlnaCBmcmVxdWVuY3kgb2YgdGhlc2Ugc3VibWFwcGluZ3MsIGFuZCBtb3JlIGdlbmVyYWxseSB0aGUgZGlzdGluY3RpdmUgYXNzb2NpYXRpb24gb2YgYHIgaGFwcHlyOjpzY2FwcygibGlxdWlkIGluIGEgY29udGFpbmVyIilgIHdpdGggKmtlZ2VtYmlyYWFuKiwgaW5mb3JtcyB0aGUgZGlzY3Vzc2lvbiBpbiBgciAnKipDaGFwdGVyIDUqKidgIHRoYXQgdGhlIHByb21pbmVuY2Ugb2YgdGhlIGByIGhhcHB5cjo6c2NhcHMoInJlbGVhc2VkIGxpcXVpZCIpYCBhbmQgYHIgaGFwcHlyOjpzY2FwcygiaGVhdGVkIGxpcXVpZCIpYCBzdWJtYXBwaW5ncyBmb3IgdGhlIHdob2xlIGByIGhhcHB5cjo6c2NhcHMoImhhcHBpbmVzcyIpYCBkb21haW4gaXMgY29udHJpYnV0ZWQgYnkgdGhlIGhpZ2hlc3QgcHJvcG9ydGlvbiBvZiB0aGUgbWV0YXBob3IgdG8gb2NjdXIgd2l0aCAqa2VnZW1iaXJhYW4qIChgciBmaWx0ZXIoa2dtYl9wcm9wX3dpdGhfbGlxdWlkaW5jb250YWluZXIsIHN5bm9ueW1zID09ICJrZWdlbWJpcmFhbiIpW1sicGVyYyJdXWAlKSByYXRoZXIgdGhhbiB3aXRoIHRoZSByZW1haW5pbmcgYHIgaGFwcHlyOjpudW1iZXJzMndvcmRzKGRpbShmaWx0ZXIoa2dtYl9wcm9wX3dpdGhfbGlxdWlkaW5jb250YWluZXIsIHN5bm9ueW1zICE9ICJrZWdlbWJpcmFhbiIpKVsxXSlgIHN5bm9ueW1zLgoKW1RhYmxlIFxAcmVmKHRhYjpkaXN0aW5jdGl2ZS1mb3ItZ2VtYmlyYSldKCNkaXN0aW5jdGl2ZS1mb3ItZ2VtYmlyYSkgcHJlc2VudHMgdGhlIHN0cm9uZ2x5IGRpc3RpbmN0aXZlIG1ldGFwaG9ycyBmb3IgKmdlbWJpcmEqICdleGNpdGUoZC9tZW50KTsgZW50aHVzaWFzKHRpYy9tKScsIHRob3VnaCBub24gb2YgdGhlbSBhcmUgc2lnbmlmaWNhbnQgYXQgdGhlIGNvcnJlY3RlZCBsZXZlbC4KCmBgYHtyIGRpc3RpbmN0aXZlLWZvci1nZW1iaXJhfQptZGNhX3JlcyAlPiUKICBoYXBweXI6Om1kY2FfYXR0cihjeG5fdHlwZSA9ICJeZ2VtYmlyYSQiLCBtaW5fYXNzb2NzdHIgPSAyKSAlPiUgCiAgbXV0YXRlKGV4cCA9IHJvdW5kKGV4cCwgM0wpLAogICAgICAgICBtZXRhcGhvcnMgPSBoYXBweXI6OnNjYXBzKG1ldGFwaG9ycykpICU+JSAKICBzZWxlY3QoLXN5bm9ueW1zKSAlPiUKICBrbml0cjo6a2FibGUoY2FwdGlvbiA9ICJEaXN0aW5jdGl2ZSBtZXRhcGhvcnMgZm9yICpnZW1iaXJhKiAnZXhjaXRlKGQvbWVudCk7IGVudGh1c2lhcyh0aWMvbSknIiwgcm93Lm5hbWVzID0gVFJVRSkKYGBgCgpPdXQgb2YgdGhlIHRocmVlIHBvc3R1bGF0ZWQgc3VibWFwcGluZ3MgZm9yIGByIGhhcHB5cjo6c2NhcHMoJ2hhcHBpbmVzcyBpcyBhbiAodW4pdmVpbGVkIG9iamVjdCcpYCwgdGhlIGRvbWluYW50IHN1Ym1hcHBpbmcgZm9yIHRoZSBub21pbmFsaXNlZCAoYHIgZmlsdGVyKGtnbWJfdW52ZWlsZWRfc3VibWV0X21heCwgc3lub255bXMgPT0gImtlZ2VtYmlyYWFuIilbWyJwZXJjIl1dYCUgb2YgdGhlIG1ldGFwaG9yIHRva2VucykgYW5kIHJvb3Qtbm9taW5hbCBmb3JtcyAoYHIgZmlsdGVyKGtnbWJfdW52ZWlsZWRfc3VibWV0X21heCwgc3lub255bXMgPT0gImdlbWJpcmEiKVtbInBlcmMiXV1gJSkgaXMgdGhlIHNhbWUsIG5hbWVseSBgciBoYXBweXI6OnNjYXBzKHVuaXF1ZShrZ21iX3VudmVpbGVkX3N1Ym1ldF9tYXgkc3VibWFwcGluZ3MpKWAgKGUuZy4gKnJhdXQgX2dlbWJpcmFfIF9fdGFtcGFrX18gZGFyaSByYXV0IHdhamFoIFNyaSogJ3doaXR0bGUgb2YgZXhjaXRlbWVudCBiZSAqdmlzaWJsZSogZnJvbSBTcmkncyBmYWNlJykuIFRoZSBpbmFiaWxpdHkgdG8gaGVsZCBiYWNrIG9yIGNvbmNlYWwgdGhlIGludGVuc2UgZmVlbGluZyBpcyBmdXJ0aGVyIGV2aWRlbmNlZCBieSB0aGUgZXhwcmVzc2lvbnMgZXZva2luZyB0aGUgbGVhc3QgZnJlcXVlbnQgc3VibWFwcGluZyBmb3IgdGhlIHR3byB3b3JkcywgbmFtZWx5IGByIGhhcHB5cjo6c2NhcHMoJ3JlZ3VsYXRpbmcgaGFwcGluZXNzIGlzIGhpZGluZyBhbiBvYmplY3QnKWAsIHdoaWNoIGlzIGJhc2VkIG9uIHRoZSBgciBoYXBweXI6OnNjYXBzKCdoaWRpbmcnKWAgZnJhbWUgKGUuZy4gXyoqbWVueWVtYnVueWlrYW4qKl8gKnJhc2EgZ2VtYmlyYSogJ3RvICpoaWRlKiB0aGUgZmVlbGluZyBvZiBleGNpdGVtZW50JykuIEZyb20gdGhlIHRvdGFsIGByIGhhcHB5cjo6bnVtYmVyczJ3b3JkcyhzdW0oZmlsdGVyKGtnbWJfdW52ZWlsZWRfc3VibWV0LCBzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAiaGlkaW5nIikpW1sidG9rZW4iXV0pKWAgdG9rZW5zIG9mIHRoZSBzdWJtYXBwaW5nIHdpdGggdGhlIHR3byB3b3JkcywgYWxsIGV2b2tlZCBieSB0aGUgdmVyYiAqbWVueWVtYnVueWlrYW4qICd0byBoaWRlJywgYHIgbmVnYXRlZF9zZW50ZW5jZXNfZm9yX2hpZGluZ2AlIG9mIHRoZSB1c2Ugb2YgdGhlIHZlcmJhbCBMVXMgYXJlIG5lZ2F0ZWQgKGUuZy4gKnRpZGFrKiBkYXBhdCBfKiptZW55ZW1idW55aWthbioqXyAqcmFzYSBnZW1iaXJhKiAnY2FuKm5vdCogKmhpZGUqIFgncyBmZWVsaW5nIG9mIGV4Y2l0ZW1lbnQnKS4KCltUYWJsZSBcQHJlZih0YWI6cmVwZWxsZWQtYnkta2VnZW1iaXJhYW4pXSgjcmVwZWxsZWQtYnkta2VnZW1iaXJhYW4pIHNob3dzIHRoZSBzdHJvbmdseSByZXBlbGxlZCBtZXRhcGhvcnMgZm9yICprZWdlbWJpcmFhbiogJ2pveTsgY2hlZXJmdWxuZXNzJy4KCmBgYHtyIHJlcGVsbGVkLWJ5LWtlZ2VtYmlyYWFufQptZGNhX3JlcyAlPiUKICBoYXBweXI6Om1kY2FfcmVwZWwoY3huX3R5cGUgPSAia2VnZW1iaXJhYW4iLCBtaW5fYXNzb2NzdHIgPSAtMikgJT4lIAogIG11dGF0ZShleHAgPSByb3VuZChleHAsIDNMKSwKICAgICAgICAgbWV0YXBob3JzID0gaGFwcHlyOjpzY2FwcyhtZXRhcGhvcnMpKSAlPiUgCiAgc2VsZWN0KC1zeW5vbnltcykgJT4lCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSAiUmVwZWxsZWQgbWV0YXBob3JzIGZvciAqa2VnZW1iaXJhYW4qICdqb3knIiwgcm93Lm5hbWVzID0gVFJVRSkKYGBgCgpbVGFibGUgXEByZWYodGFiOnJlcGVsbGVkLWJ5LWdlbWJpcmEpXSgjcmVwZWxsZWQtYnktZ2VtYmlyYSkgc2hvd3MgdGhlIHN0cm9uZ2x5IHJlcGVsbGVkIG1ldGFwaG9ycyBmb3IgKmdlbWJpcmEqICdleGNpdGUoZC9tZW50KTsgZW50aHVzaWFzKHRpYy9tKScuCgpgYGB7ciByZXBlbGxlZC1ieS1nZW1iaXJhfQptZGNhX3JlcyAlPiUKICBoYXBweXI6Om1kY2FfcmVwZWwoY3huX3R5cGUgPSAiZ2VtYmlyYSQiLCBtaW5fYXNzb2NzdHIgPSAtMikgJT4lIAogIG11dGF0ZShleHAgPSByb3VuZChleHAsIDNMKSwKICAgICAgICAgbWV0YXBob3JzID0gaGFwcHlyOjpzY2FwcyhtZXRhcGhvcnMpKSAlPiUgCiAgc2VsZWN0KC1zeW5vbnltcykgJT4lCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSAiUmVwZWxsZWQgbWV0YXBob3JzIGZvciAqZ2VtYmlyYSogJ2V4Y2l0ZShkL21lbnQpOyBlbnRodXNpYXModGljL20pJyIsIHJvdy5uYW1lcyA9IFRSVUUpCmBgYAoKYGBge3IgY29sbG9jLXJlcy1rZWdlbWJpcmFhbn0KIyBwcmVzZW50IHRoZSByZXN1bHQgdGFibGUgZm9yIGNvbGxvY2F0aW9uYWwgYW5hbHlzaXMgZm9yICprZWdlbWJpcmFhbioKaGFwcHlyOjptZGNhX2F0dHIobWRjYV9jb2xsb2MsIGN4bl90eXBlID0gJ15rZWdlbWJpcmFhbicpICU+JSAKICB0b3BfbigyMCwgYXNzb2NzdHIpICU+JSAKICBsZWZ0X2pvaW4oaGFwcHlyOjpkaXN0X2NvbGxvY19nbG9zcywgYnkgPSAiY29sbG9jYXRlcyIpICU+JSAjIGxlZnQtam9pbiB0aGUgZ2xvc3MgZm9yIHRoZSBkaXN0aW5jdGl2ZSBjb2xsb2NhdGVzCiAgc2VsZWN0KC1zeW5vbnltcykgJT4lCiAgc2VsZWN0KGNvbGxvY2F0ZXMsIGdsb3NzLCBldmVyeXRoaW5nKCkpICU+JQogIG11dGF0ZShleHAgPSByb3VuZChleHAsIDMpLCAKICAgICAgICAgY29sbG9jYXRlcyA9IHBhc3RlKCIqIiwgY29sbG9jYXRlcywgIioiLCBzZXAgPSAiIikpICU+JQogIGtuaXRyOjprYWJsZShjYXB0aW9uPSJUaGUgMjAgbW9zdCBkaXN0aW5jdGl2ZSwgNC13aW5kb3cgc3BhbiBjb2xsb2NhdGVzIGZvciAqa2VnZW1iaXJhYW4qICdqb3k7IGNoZWVyZnVsbmVzcycgaW4gdGhlIHdob2xlIEluZG9uZXNpYW4gTGVpcHppZyBDb3Jwb3JhIGNvbGxlY3Rpb24uIiwgcm93Lm5hbWVzID0gVFJVRSkKYGBgCgojIyBEaXN0aW5jdGl2ZSBtZXRhcGhvcnMgZm9yICprZWNlcmlhYW4qICdjaGVlcmZ1bG5lc3MnIHsjY2VyaWF9CgpgYGB7ciBrZWNlcmlhYW4tZGF0YS1tYWludGV4dH0KIyBzdWJtYXBwaW5nIG9mIHRoZSBDT05UQUlORUQgRU5USVRZIG1ldGFwaG9yCmtjcmFfc3VibWV0X2NvbnRhaW5lZCA8LSBoYXBweXI6OmdldF9zdWJtYXBwaW5ncygiY29udGFpbmVkIGVudGl0eSIsICJrZWNlcmlhYW4iLCBkZiA9IGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IpCgprY3JhX3N1Ym1ldF9jb250YWluZWRfbHUgPC0gaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvciAlPiUKICBmaWx0ZXIoc3lub255bXMgPT0gImtlY2VyaWFhbiIsCiAgICAgICAgIHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICJmdWxsbmVzcyBvZiBlbnRpdHkiKSkgJT4lCiAgY291bnQobHUsIHNvcnQgPSBUUlVFKSAlPiUKICBtdXRhdGUocGVyYyA9IHJvdW5kKChuL3N1bShuKSkgKiAxMDAsIDIpKQoKIyBzdWJtYXBwaW5nIG9mIHRoZSBDT0xPVVIgbWV0YXBob3IKa2NyYV9zdWJtZXRfY29sb3VyIDwtIGhhcHB5cjo6Z2V0X3N1Ym1hcHBpbmdzKCJjb2xvdXIkIiwgImtlY2VyaWFhbiIsIGRmID0gaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvcikKCiMgc3VibWFwcGluZyBvZiB0aGUgUVVBTlRJVFkgbWV0YXBob3IKa2NyYV9zdWJtZXRfcXVhbnRpdHkgPC0gaGFwcHlyOjpnZXRfc3VibWFwcGluZ3MoIlxcc3F1YW50aXR5IiwgImtlY2VyaWFhbiIsIGRmID0gaGFwcHlyOjpwaGRfZGF0YV9tZXRhcGhvcikgJT4lIAogIG11dGF0ZShhc3BlY3QgPSBpZl9lbHNlKHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICIoYWRkaW5nfG1vcmUpIiksICJtb3JlIiwgImxlc3MiKSkKYGBgCgpbVGFibGUgXEByZWYodGFiOmRpc3RpbmN0aXZlLWZvci1rZWNlcmlhYW4pXSgjZGlzdGluY3RpdmUtZm9yLWtlY2VyaWFhbikgc2hvd3MgdGhlIGRpc3RpbmN0aXZlIG1ldGFwaG9ycyBmb3IgKmtlY2VyaWFhbiogJ2NoZWVyZnVsbmVzczsgbGl0LiBwdXJpdHknIChOfm1ldGFwaG9yaWNhbH4gPSBgciBkcGx5cjo6ZmlsdGVyKHN5bm9ueW1fdG9rZW4sIHN5bm9ueW1zID09ICJrZWNlcmlhYW4iKVtbIm4iXV1gKS4gVGhlIHJvb3Qtbm9taW5hbCAqY2VyaWEqICdjaGVlcmZ1bDsgbGl0LiBwdXJlLCBjbGVhbicgKE5+bWV0YXBob3JpY2FsfiA9IGByIGRwbHlyOjpmaWx0ZXIoc3lub255bV90b2tlbiwgc3lub255bXMgPT0gImNlcmlhIilbWyJuIl1dYCkgaXMgYWJzZW50IHNpbmNlIHRoZSBBc3NvY1N0ciB2YWx1ZXMgb2YgaXRzIGRpc3RpbmN0aXZlIG1ldGFwaG9ycyBkbyBub3QgcmVhY2ggMi4KCmBgYHtyIGRpc3RpbmN0aXZlLWZvci1rZWNlcmlhYW59Cm1kY2FfcmVzICU+JQogIGhhcHB5cjo6bWRjYV9hdHRyKGN4bl90eXBlID0gImtlY2VyaWFhbiIsIG1pbl9hc3NvY3N0ciA9IDIpICU+JSAKICBtdXRhdGUoZXhwID0gcm91bmQoZXhwLCAzTCksCiAgICAgICAgIG1ldGFwaG9ycyA9IGhhcHB5cjo6c2NhcHMobWV0YXBob3JzKSkgJT4lIAogIHNlbGVjdCgtc3lub255bXMpICU+JQogIGtuaXRyOjprYWJsZShjYXB0aW9uID0gIkRpc3RpbmN0aXZlIG1ldGFwaG9ycyBmb3IgKmtlY2VyaWFhbiogJ2NoZWVyZnVsbmVzcyciLCByb3cubmFtZXMgPSBUUlVFKQpgYGAKCkZvciB0aGUgYHIgaGFwcHlyOjpzY2FwcygiY29udGFpbmVkIGVudGl0eSIpYCBtZXRhcGhvciwgYHIgZmlsdGVyKGtjcmFfc3VibWV0X2NvbnRhaW5lZCwgc3RyX2RldGVjdChzdWJtYXBwaW5ncywgImZ1bGxuZXNzIikpW1sicGVyYyJdXWAlIG9mIHRoZSB0b2tlbnMgY29uc2lzdCBvZiBtZXRhcGhvcmljYWwgcGF0dGVybnMgcmVmZXJyaW5nIHRvIHRoZSAnZnVsbG5lc3MnIG9mIHRoZSBjb250YWluZWQgZW1vdGlvbi1lbnRpdHkuIFRoZSBwYXR0ZXJucyBhcmUgZXhwcmVzc2VkIGJ5IG9ubHkgYHIgbnVtYmVyczJ3b3JkcyhmaWx0ZXIoa2NyYV9zdWJtZXRfY29udGFpbmVkLCBzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAiZnVsbG5lc3MiKSlbWyJ0eXBlIl1dKWAgTFUgdHlwZXMsIG5hbWVseSwgKl9fcGVudWhfXyAoZGVuZ2FuKSBrZWNlcmlhYW4qICd0byBiZSAqZnVsbCogd2l0aC9vZiBjaGVlcmZ1bG5lc3MnIChgciBmaWx0ZXIoa2NyYV9zdWJtZXRfY29udGFpbmVkX2x1LCBsdSA9PSAicGVudWgiKVtbIm4iXV1gIHRva2VucyksICprZWNlcmlhYW4gX19tZW1lbnVoaV9fIFgqICdjaGVlcmZ1bG5lc3MgKmZpbGxzKiBYICp1cConIChgciBmaWx0ZXIoa2NyYV9zdWJtZXRfY29udGFpbmVkX2x1LCBsdSA9PSAicGVudWhpIilbWyJuIl1dYCB0b2tlbnMpLCBhbmQgKmtlY2VyaWFhbiBfX21lbnllc2FraV9fIFgqICdYIGJlICpqYW0tcGFja2VkKiB3aXRoIGNoZWVyZnVsbmVzczsgY2hlZXJmdWxuZXNzICpmaWxscyogWCAqdXAqJyAoYHIgZmlsdGVyKGtjcmFfc3VibWV0X2NvbnRhaW5lZF9sdSwgbHUgPT0gInNlc2FraSIpW1sibiJdXWAgdG9rZW5zKS4gT25seSBgciBmaWx0ZXIoa2NyYV9zdWJtZXRfY29udGFpbmVkLCBzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAiZXhwbG9kaW5nIikpW1sicGVyYyJdXWAlIG9mIHRoZSBtZXRhcGhvcidzIHRva2VuIGluZGljYXRlcyB0aGUgJ2V4cGxvZGluZycgY29udGFpbmVyLCBzdWdnZXN0aW5nIHRoZSBpbmFiaWxpdHkgdG8gaGVsZCBiYWNrIHRoZSBmZWVsaW5nLCBoZW5jZSBpdHMgZXhwcmVzc2lvbiAoKmtlY2VyaWFhbiB5YW5nIF9fbWVsZWRha19fKiAnY2hlZXJmdWxuZXNzIHRoYXQgKmV4cGxvZGVzKicpLgoKLi4uCgpSZWxhdGVkIGluZmVyZW5jZSBmb3IgaW50ZW5zaXR5IGlzIGluZGljYXRlZCBieSB0aGUgc3VibWFwcGluZ3Mgb2YgdGhlIGxlc3Mgc3Ryb25nbHkgYXR0cmFjdGVkIG1ldGFwaG9yLCBuYW1lbHkgYHIgaGFwcHlyOjpzY2FwcygiaW50ZW5zaXR5IG9mIGhhcHBpbmVzcyBpcyBxdWFudGl0eSBvZiBvYmplY3QiKWAuIFRoZSBwcmVkb21pbmFudCBzdWJtYXBwaW5nIGJyb2FkbHkgaW5kaWNhdGVzIG1vcmUgcXVhbnRpdHkgb2Ygb2JqZWN0IChgciBzdW0oZHBseXI6OmZpbHRlcihrY3JhX3N1Ym1ldF9xdWFudGl0eSwgc3RyX2RldGVjdChzdWJtYXBwaW5ncywgIihhZGRpbmd8bW9yZSkiKSlbWyJwZXJjIl1dKWAlIG9mIHRoZSB0b3RhbCB0b2tlbnMgb2YgdGhlIG1ldGFwaG9yIG9jY3VycmluZyB3aXRoICprZWNlcmlhYW4qKS4gVGhpcyBmdXJ0aGVyIHN1YnN1bWVzIHR3byBldmVudHM6IChpKSAnYWRkaW5nJyB0aGUgcXVhbnRpdHkgb2YgYW4gb2JqZWN0IChgciBrY3JhX3N1Ym1ldF9xdWFudGl0eSAlPiUgZmlsdGVyKHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICJhZGRpbmciKSkgJT4lIC4kcGVyY2AlKSwgd2hpY2ggY291bGQgbWFwIG9udG8gdGhlIGludGVuc2lmaWNhdGlvbiBwcm9jZXNzIG9mICprZWNlcmlhYW4qLCBhbmQgKGlpKSB0aGUgc3RhdGUgb2YgYW4gb2JqZWN0IGluICdsYXJnZSBxdWFudGl0eScgKGByIGtjcmFfc3VibWV0X3F1YW50aXR5ICU+JSBmaWx0ZXIoc3RyX2RldGVjdChzdWJtYXBwaW5ncywgIm1vcmUgcXVhbnRpdHkiKSkgJT4lIC4kcGVyY2AlKSwgd2hpY2ggY291bGQgbWFwIG9udG8gdGhlICdpbnRlbnNlJyBzdGF0ZSBvZiAqa2VjZXJpYWFuKi4gVGhlIHNlY29uZCBvZiB0aGVzZSBpcyBleHByZXNzZWQgYnkgYHIga2NyYV9zdWJtZXRfcXVhbnRpdHkgJT4lIGZpbHRlcihzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAibW9yZSBxdWFudGl0eSIpKSAlPiUgLiR0eXBlICU+JSBoYXBweXI6Om51bWJlcnMyd29yZHMoKWAgZGlmZmVyZW50IGxleGljYWwgdW5pdCAoTFUpIHR5cGVzIGNvbXBhcmVkIHRvIG9ubHkgYHIga2NyYV9zdWJtZXRfcXVhbnRpdHkgJT4lIGZpbHRlcihzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAiYWRkaW5nIikpICU+JSAuJHR5cGUgJT4lIGhhcHB5cjo6bnVtYmVyczJ3b3JkcygpYCBmb3IgdGhlIGZpcnN0IChpLmUuLCBfKip0YW1iYWgoa2FuKSoqIGtlY2VyaWFhbl8gJ3RvICphZGQqIGNoZWVyZnVsbmVzcycpLiBUaGUgbWV0YXBob3JpY2FsIHBhdHRlcm5zIGNvbnRhaW5pbmcgTFVzIGluZGljYXRpbmcgJ2xhcmdlIHF1YW50aXR5JyBpbmNsdWRlIF8qKmJlcmp1dGEvc2VyaWJ1L2JhbnlhayoqIGtlY2VyaWFhbl8gJyptaWxsaW9ucyBvZi90aG91c2FuZHMgb2YvbWFueSogY2hlZXJmdWxuZXNzJywgX2tlY2VyaWFhbiAqKm1lbnVtcHVrKipfICdjaGVlcmZ1bG5lc3MgKnBpbGVzLXVwKicsIGFtb25nIG90aGVycy4gVGhlIHByZWRvbWluYW50IHN1Ym1hcHBpbmcgb2YgYHIgaGFwcHlyOjpzY2FwcygicXVhbnRpdHkiKWAgbWV0YXBob3IgY29oZXJlcyB3aXRoIHRoZSAnZnVsbG5lc3MnIHN1Ym1hcHBpbmcgb2YgdGhlIGByIGhhcHB5cjo6c2NhcHMoImNvbnRhaW5lZCBlbnRpdHkiKWAgbWV0YXBob3IgaW4gY29udmV5aW5nIGludGVuc2l0eSwgZ2l2ZW4gdGhlIGZ1bGxuZXNzIG9mIGEgY29udGVudCBjb3JyZWxhdGVzIHdpdGggbGFyZ2UgYW1vdW50IG9mIGNvbnRlbnQgaW4gcmVsYXRpb24gdG8gdGhlIGNhcGFjaXR5IG9mIHRoZSBob2xkaW5nIGNvbnRhaW5lci4KCi4uLgoKRm9yIHRoZSBgciBoYXBweXI6OnNjYXBzKCJjb2xvdXIiKWAgbWV0YXBob3IsIHRoZSBtZXRhcGhvcmljYWwgcGF0dGVybnMgbW9zdCBmcmVxdWVudGx5IGxpa2VuIHRoZSBleHBlcmllbmNlIG9mICprZWNlcmlhYW4qICdjaGVlcmZ1bG5lc3MnIGFzIGJlaW5nIGNvbG91cmVkIChgciBrY3JhX3N1Ym1ldF9jb2xvdXIgJT4lIGZpbHRlcihzdHJfZGV0ZWN0KHN1Ym1hcHBpbmdzLCAiYmVpbmcgY29sb3VyZWQiKSkgJT4lIC4kcGVyY2AlIG9mIHRoZSB0b3RhbCB0b2tlbnMpLiBIb3dldmVyLCB0aGUgbWV0YXBob3JpY2FsIHBhdHRlcm5zIGFyZSBiYXNlZCBvbiBvbmx5IGByIGtjcmFfc3VibWV0X2NvbG91ciAlPiUgZmlsdGVyKHN0cl9kZXRlY3Qoc3VibWFwcGluZ3MsICJiZWluZyBjb2xvdXJlZCIpKSAlPiUgLiR0eXBlICU+JSBoYXBweXI6Om51bWJlcnMyd29yZHMoKWAgdHlwZSBvZiBsZXhpY2FsIHVuaXQKCi4uLgoKU2ltaWxhciAndmlzdWFsJyB0b25lIG9mICprZWNlcmlhYW4qIGlzIGFyZ3VlZCB0byBiZSBjb252ZXllZCB2aWEgZGlmZmVyZW50IGltYWdlLCBuYW1lbHkgdGhlIGByIGhhcHB5cjo6c2NhcHMoImVtYmVsbGlzaG1lbnQiKWAgbWV0YXBob3IuIEluc3RlYWQgb2YgYmVpbmcgY29sb3VyZWQsIGV4cGVyaWVuY2Ugb2YgKmtlY2VyaWFhbiogaXMgY29uY2VwdHVhbGlzZWQgYXMgYmVpbmcgZW1iZWxsaXNoZWQuIFRoZSBtb3N0IGZyZXF1ZW50IG1ldGFwaG9yaWNhbCBwYXR0ZXJuIChpLmUuLCBgciBmaWx0ZXIoY291bnQoZmlsdGVyKGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IsIHN0cl9kZXRlY3QobWV0YXBob3JzLCAiZW1iZWxsaXNoIikpLCBtX2V4cHIsIHNvcnQgPSBUUlVFKSwgbiA9PSBtYXgobikpW1sibiJdXSAlPiUgaGFwcHlyOjpudW1iZXJzMndvcmRzKClgIHRva2VucykgaXMgKmtlY2VyaWFhbiBfX21lbmdoaWFzaV9fIFgqICdjaGVlcmZ1bG5lc3MgKmVtYmVsbGlzaGVzKiBYJywgd2l0aCB0aGUgIlgiIHNsb3QgaXMgcHJlZG9taW5hbnRseSBmaWxsZWQgd2l0aCB0aGUgbm91biAqd2FqYWgqICdmYWNlJwoKLi4uCgpCZSB0aGF0IGFzIGl0IG1heSwgYm90aCAqa2VjZXJpYWFuKiBhbmQgKmtlZ2VtYmlyYWFuKiBhbHNvIGVxdWFsbHkgaGF2ZSBzdHJvbmcgYXR0cmFjdGlvbiB0byB0aGUgYHIgaGFwcHlyOjpzY2FwcygiKHVuKXZlaWxlZCBvYmplY3QiKWAgbWV0YXBob3IgKEFzc29jU3RyID0gYHIgZmlsdGVyKG1kY2FfcmVzLCBzdHJfZGV0ZWN0KG1ldGFwaG9ycywgInZlaWxlZCIpLCBzeW5vbnltcyA9PSAia2VjZXJpYWFuIilbWyJhc3NvY3N0ciJdXWAgZm9yICprZWNlcmlhYW4qIGFuZCBBc3NvY1N0ciA9IGByIGZpbHRlcihtZGNhX3Jlcywgc3RyX2RldGVjdChtZXRhcGhvcnMsICJ2ZWlsZWQiKSwgc3lub255bXMgPT0gImtlZ2VtYmlyYWFuIilbWyJhc3NvY3N0ciJdXWAgZm9yICprZWdlbWJpcmFhbiopLCB3aGljaCBhbHNvIGZvY3VzZXMgb24gdGhlIGlkZWEgb2YgJ2V4cHJlc3Npdml0eScgYW5kICdyZWd1bGF0aW9uJyBvZiB0aGUgZmVlbGluZywgdGhvdWdoIGl0IGlzIG5vdCBzaWduaWZpY2FuY2UgZm9yIHRoZSBjb3JyZWN0ZWQgbGV2ZWwuCgouLi4KCkl0IHNob3VsZCBhbHNvIGJlIG1lbnRpb25lZCB0aGF0IHRoZXJlIGFyZSB0d28gZGlzdGluY3RpdmUgbWV0YXBob3JzIGZvciB0aGUgbm9taW5hbCByb290ICpjZXJpYSogJ2NoZWVyZnVsbmVzcycgdGhhdCBhcmUgYWxzbyBkaXN0aW5jdGl2ZSBmb3IgdGhlIG5vbWluYWxpc2VkIGZvcm0gKmtlY2VyaWFhbiosIGV2ZW4gdGhvdWdoIHRoZSBhdHRyYWN0aW9uIGRvZXMgbm90IHJlYWNoIHRoZSBjb3JyZWN0ZWQgbGV2ZWwgb2Ygc2lnbmlmaWNhbmNlIGZvciAqY2VyaWEqIChjZi4gW1RhYmxlIFxAcmVmKHRhYjpkaXN0aW5jdGl2ZS1mb3ItY2VyaWEpXSgjZGlzdGluY3RpdmUtZm9yLWNlcmlhKSkuIFRoZXNlIG1ldGFwaG9ycyBhcmUgYHIgaGFwcHlyOjpzY2FwcygiaGFwcGluZXNzIGlzIGEgY29sb3VyIilgIChOID0gYHIgZmlsdGVyKG1kY2FfcmVzLCBzdHJfZGV0ZWN0KG1ldGFwaG9ycywgImNvbG91ciQiKSwgc3lub255bXMgPT0gImNlcmlhIilbWyJuIl1dYCwgQXNzb2NTdHIgPSBgciBmaWx0ZXIobWRjYV9yZXMsIHN0cl9kZXRlY3QobWV0YXBob3JzLCAiY29sb3VyJCIpLCBzeW5vbnltcyA9PSAiY2VyaWEiKVtbImFzc29jc3RyIl1dYCwgZGVjID0gKmByIGZpbHRlcihtZGNhX3Jlcywgc3RyX2RldGVjdChtZXRhcGhvcnMsICJjb2xvdXIkIiksIHN5bm9ueW1zID09ICJjZXJpYSIpW1siZGVjIl1dYCopIGFuZCBgciBoYXBweXI6OnNjYXBzKCJoYXBwaW5lc3MgaXMgYSBjb250YWluZWQgZW50aXR5IilgIChOID0gYHIgZmlsdGVyKG1kY2FfcmVzLCBzdHJfZGV0ZWN0KG1ldGFwaG9ycywgImNvbnRhaW5lZCBlbnRpdHkiKSwgc3lub255bXMgPT0gImNlcmlhIilbWyJuIl1dYCwgQXNzb2NTdHIgPSBgciBmaWx0ZXIobWRjYV9yZXMsIHN0cl9kZXRlY3QobWV0YXBob3JzLCAiY29udGFpbmVkIGVudGl0eSIpLCBzeW5vbnltcyA9PSAiY2VyaWEiKVtbImFzc29jc3RyIl1dYCwgZGVjID0gKmByIGZpbHRlcihtZGNhX3Jlcywgc3RyX2RldGVjdChtZXRhcGhvcnMsICJjb250YWluZWQgZW50aXR5IiksIHN5bm9ueW1zID09ICJjZXJpYSIpW1siZGVjIl1dYCopLiBUaGlzIGZpbmRpbmcgZnVydGhlciBpbmRpY2F0ZXMgdGhhdCwgZGVzcGl0ZSB0aGUgbGV4aWNhbCB2YXJpYXRpb24gZGVub3RpbmcgdGhlIGRvbWFpbiwgdGhlcmUgY2FuIGJlIGEgdGVuZGVuY3kgb2Ygc2ltaWxhciB1c2FnZXMgYW5kIGNvbnN0cnVhbCB3aXRoaW4gdGhlIHNhbWUgZ2VuZXJhbCBkb21haW4sIGFzIGFscmVhZHkgYmVlbiBzaG93biBiZXR3ZWVuIHRoZSByb290IGFuZCBub21pbmFsaXNlZCBmb3JtcyBmb3IgYHIgaGFwcHlyOjpzY2FwcygiZ2VtYmlyYSIpYCBpbiBgciBzZWN0aW9uYFtcQHJlZihnZW1iaXJhKV0oI2dlbWJpcmEpLgoKYGBge3IgZGlzdGluY3RpdmUtZm9yLWNlcmlhfQptZGNhX3JlcyAlPiUKICBoYXBweXI6Om1kY2FfYXR0cihjeG5fdHlwZSA9ICJeY2VyaWEkIiwgbWluX2Fzc29jc3RyID0gMS4zMDEwMykgJT4lIAogIG11dGF0ZShleHAgPSByb3VuZChleHAsIDNMKSwKICAgICAgICAgbWV0YXBob3JzID0gaGFwcHlyOjpzY2FwcyhtZXRhcGhvcnMpKSAlPiUgCiAgc2VsZWN0KC1zeW5vbnltcykgJT4lCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSAiRGlzdGluY3RpdmUgbWV0YXBob3JzIGZvciAqY2VyaWEqICdjaGVlcmZ1bChuZXNzKSciLCByb3cubmFtZXMgPSBUUlVFKQpgYGAKCkxvb2tpbmcgYXQgW1RhYmxlIFxAcmVmKHRhYjpyZXBlbGxlZC1ieS1rZWNlcmlhYW4pXSgjcmVwZWxsZWQtYnkta2VjZXJpYWFuKSBmb3IgdGhlIHJlcGVsbGVkIG1ldGFwaG9ycywgKmtlY2VyaWFhbiogc2lnbmlmaWNhbnRseSByZXBlbHMgdGhlIGByIGhhcHB5cjo6c2NhcHMoImRlc2lyZWQgZ29hbCIpYCBtZXRhcGhvciwgZGlzdGluZ3Vpc2hpbmcgaXQgZnJvbSB0aGUgZGlzdGluY3RpdmUgbWV0YXBob3JpY2FsIGNvbnN0cnVhbCBvZiAqa2ViYWhhZ2lhYW4qICdoYXBwaW5lc3MnIGFuZCAqa2VzZW5hbmdhbiogJ3BsZWFzdXJlJy4KCmBgYHtyIHJlcGVsbGVkLWJ5LWtlY2VyaWFhbn0KbWRjYV9yZXMgJT4lCiAgaGFwcHlyOjptZGNhX3JlcGVsKGN4bl90eXBlID0gImtlY2VyaWFhbiIsIG1pbl9hc3NvY3N0ciA9IC0yKSAlPiUgCiAgbXV0YXRlKGV4cCA9IHJvdW5kKGV4cCwgM0wpLAogICAgICAgICBtZXRhcGhvcnMgPSBoYXBweXI6OnNjYXBzKG1ldGFwaG9ycykpICU+JSAKICBzZWxlY3QoLXN5bm9ueW1zKSAlPiUKICBrbml0cjo6a2FibGUoY2FwdGlvbiA9ICJSZXBlbGxlZCBtZXRhcGhvcnMgZm9yICprZWNlcmlhYW4qICdjaGVlcmZ1bG5lc3MnIiwgcm93Lm5hbWVzID0gVFJVRSkKYGBgCgpTaW1pbGFyIHJlcHVsc2lvbiB0byB0aGUgYHIgaGFwcHlyOjpzY2FwcygiZGVzaXJlZCBnb2FsIilgIG1ldGFwaG9yIGlzIGFsc28gc2hvd24gYnkgdGhlIHJvb3Qgbm9taW5hbCAqY2VyaWEqICdjaGVlcmZ1bCcgKGNmLiBbVGFibGUgXEByZWYodGFiOnJlcGVsbGVkLWJ5LWNlcmlhKV0oI3JlcGVsbGVkLWJ5LWNlcmlhKSkuCgpgYGB7ciByZXBlbGxlZC1ieS1jZXJpYX0KbWRjYV9yZXMgJT4lCiAgaGFwcHlyOjptZGNhX3JlcGVsKGN4bl90eXBlID0gIl5jZXJpYSQiLCBtaW5fYXNzb2NzdHIgPSAtMS4zMDEwMykgJT4lIAogIG11dGF0ZShleHAgPSByb3VuZChleHAsIDNMKSwKICAgICAgICAgbWV0YXBob3JzID0gaGFwcHlyOjpzY2FwcyhtZXRhcGhvcnMpKSAlPiUgCiAgc2VsZWN0KC1zeW5vbnltcykgJT4lCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSAiUmVwZWxsZWQgbWV0YXBob3IocykgZm9yICpjZXJpYSogJ2NoZWVyZnVsbmVzcyciLCByb3cubmFtZXMgPSBUUlVFKQpgYGAKCgpUaGUgZmFjdCB0aGF0ICprZWNlcmlhYW4qIGFsc28gcmVwZWxzIGByIGhhcHB5cjo6c2NhcHMoIm9iamVjdCdzIGRpbWVuc2lvbiIpYCB3aXRoICdpbnRlbnNpdHknIGludGVycHJldGF0aW9uIGRvZXMgbm90IHVuZGVybWluZSBpdHMgYXNzb2NpYXRpb24gd2l0aCBvdGhlciBtZXRhcGhvcnMgaGlnaGxpZ2h0aW5nIHNpbWlsYXIgcXVhbGl0eS4gSXQgaXMgYXJndWVkIHRoYXQgdGhlIGludGVuc2l0eSBvZiAqa2VjZXJpYWFuKiBpcyBjYXB0dXJlZCB1c2luZyBkaWZmZXJlbnQgZm9ybSBvZiBtZXRhcGhvcmljYWwgcGF0dGVybnMgdGhhdCBldm9rZSBjZXJ0YWluIHNlbWFudGljIGZyYW1lLCBzdWNoIGFzIGByIGhhcHB5cjo6c2NhcHMoIm9iamVjdCBxdWFudGl0eSIpYCB0aGF0IGlzIGRpc3RpbmN0aXZlIGZvciAqa2VjZXJpYWFuKiwgcmF0aGVyIHRoYW4gcGF0dGVybnMgZXZva2luZyBgciBoYXBweXI6OnNjYXBzKCJvYmplY3QncyBkaW1lbnNpb24iKWAgZnJhbWUuIFRoaXMgaXMgcmVmbGVjdGVkIGJ5IHRoZSBtb3N0IGZyZXF1ZW50IHBhdHRlcm4gaW5kaWNhdGluZyB0aGUgY29uY2VwdCBvZiBgciBzY2Fwcygib2JqZWN0IHF1YW50aXR5IilgLCB0aGF0IGlzIF8qKm1lbmFtYmFoKioga2VjZXJpYWFuXyAndG8gKmFkZCogY2hlZXJmdWxuZXNzJyAoYHIgZmlsdGVyKGNvdW50KGZpbHRlcihoYXBweXI6OnBoZF9kYXRhX21ldGFwaG9yLCBzeW5vbnltcyA9PSAia2VjZXJpYWFuIiwgc3RyX2RldGVjdChtZXRhcGhvcnMsICJxdWFudGl0eSIpKSwgbV9leHByLCBzb3J0ID0gVFJVRSksIG4gPT0gbWF4KG4pKVtbIm4iXV1gIHRva2VucyksIGNvbXBhcmVkIHRvIHRoZSBvbmx5IGByIGhhcHB5cjo6bnVtYmVyczJ3b3JkcyhmaWx0ZXIobWRjYV9yZXMsIHN5bm9ueW1zID09ICJrZWNlcmlhYW4iLCBzdHJfZGV0ZWN0KG1ldGFwaG9ycywgImRpbWVuc2lvbiIpKVtbIm4iXV0pYCB0b2tlbiBmb3IgYHIgaGFwcHlyOjpzY2Fwcygib2JqZWN0J3MgZGltZW5zaW9uIilgIG9jY3VycmluZyB3aXRoICprZWNlcmlhYW4qLiBMZXQgdXMgbm93IGNvbnNpZGVyIHRoZSBpbnNpZ2h0IG9mZmVyZWQgYnkgdGhlIGRpc3RpbmN0aXZlIGNvbGxvY2F0ZXMgb2YgKmtlY2VyaWFhbiogYXMgc2hvd24gaW4gW1RhYmxlIFxAcmVmKHRhYjpjb2xsb2MtcmVzLWtlY2VyaWFhbildKCNjb2xsb2MtcmVzLWtlY2VyaWFhbikuCgpgYGB7ciBjb2xsb2MtcmVzLWtlY2VyaWFhbn0KIyBwcmVzZW50IHRoZSByZXN1bHQgdGFibGUgZm9yIGNvbGxvY2F0aW9uYWwgYW5hbHlzaXMgZm9yICprZWNlcmlhYW4qCmhhcHB5cjo6bWRjYV9hdHRyKG1kY2FfY29sbG9jLCBjeG5fdHlwZSA9ICdea2VjZXJpYWFuJykgJT4lIAogIHRvcF9uKDIwLCBhc3NvY3N0cikgJT4lIAogIGxlZnRfam9pbihoYXBweXI6OmRpc3RfY29sbG9jX2dsb3NzLCBieSA9ICJjb2xsb2NhdGVzIikgJT4lICMgbGVmdC1qb2luIHRoZSBnbG9zcyBmb3IgdGhlIGRpc3RpbmN0aXZlIGNvbGxvY2F0ZXMKICBzZWxlY3QoLXN5bm9ueW1zKSAlPiUKICBzZWxlY3QoY29sbG9jYXRlcywgZ2xvc3MsIGV2ZXJ5dGhpbmcoKSkgJT4lCiAgbXV0YXRlKGV4cCA9IHJvdW5kKGV4cCwgMyksIAogICAgICAgICBjb2xsb2NhdGVzID0gcGFzdGUoIioiLCBjb2xsb2NhdGVzLCAiKiIsIHNlcCA9ICIiKSkgJT4lCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSBwYXN0ZSgiVGhlIDIwIG1vc3QgZGlzdGluY3RpdmUsIDQtd2luZG93IHNwYW4gY29sbG9jYXRlcyBmb3IgKmtlY2VyaWFhbiogJ2NoZWVyZnVsbmVzcycgaW4gdGhlIGNvbWJpbmVkIGRhdGEgc2V0cyAoSW5kb25lc2lhbiBMZWlwemlnIENvcnBvcmEsIElXYUMgU2tldGNoIEVuZ2luZSwgYW5kIFdlYkNvcnApXltBcyBleHBsYWluZWQgaW4gYCoqQ2hhcHRlciAzKipgLCB0aGUgbm9taW5hbGlzZWQgZm9ybXMgZm9yICIsIGhhcHB5cjo6c2NhcHMoImNlcmlhIiksICIgYW5kICIsIGhhcHB5cjo6c2NhcHMoInJpYW5nIiksICIgb2NjdXIgaW4gYSB2ZXJ5IGxvdyBmcmVxdWVuY3kgaW4gdGhlIHdob2xlIEluZG9uZXNpYW4gTGVpcHppZyBDb3Jwb3JhIGNvbXBhcmVkIHRvIHRoZSBmb3JtcyBmb3IgdGhlIG90aGVyIGNvbmNlcHRzLiBBZGRpdGlvbmFsIGRhdGEgZm9yIHRoZXNlIGZvcm1zIGFyZSB0aGVuIGN1bGxlZCBmcm9tIHRoZSAqSVdhQyogb2YgKlNrZXRjaCBFbmdpbmUqIGFuZCB0ZW4gb25saW5lIEluZG9uZXNpYW4gbmV3c3BhcGVycyB2aWEgKldlYkNvcnAqLl0uIiwgc2VwID0gIiIpLCByb3cubmFtZXMgPSBUUlVFKQpgYGAKCkFtb25nIHRoZSBpbnRlcmVzdGluZyBmaW5kaW5nIGlzIHRoZSBkaXN0aW5jdGl2ZW5lc3Mgb2YgKmFuYWsoLWFuYWspKiAnY2hpbGQocmVuKScgdG8gY28tb2NjdXIgd2l0aCAqa2VjZXJpYWFuKi4gVGhpcyBtYXkgaW52b2tlIGFuICdpbm5vY2VudCcgb3IgJ3B1cmUnIHF1YWxpdHkgb2YgKmtlY2VyaWFhbiouIFRoZSBwcmVzZW5jZSBvZiBtZXRhcGhvcmljYWwgY29sbG9jYXRlICptZW5nZW1iYWxpa2FuKiAndG8gKnJldHVybi9naXZlIGJhY2sqJyBtYXkgcmVsYXRlIHRvICprb3JiYW4qICd2aWN0aW1zJywgd2hvIG1heSBsb3NlIHRoZWlyIGNoZWVyZnVsbmVzcy4gT3RoZXIgZGlzdGluY3RpdmUgY29sbG9jYXRlcyBhbHNvIGluZGljYXRlIHRoZSBhc3NvY2lhdGVkIHNldHRpbmcgZm9yICprZWNlcmlhYW4qLCBzdWNoIGFzICpzZWtvbGFoKiAnc2Nob29sJywgKnBlcnR1bmp1a2FuKiAnKGEpIHNob3cnLCBhbmQgKmxlYmFyYW4qICdSYW1hZGhhbicuIFRoZXNlIHNldHRpbmdzIGZvcmVncm91bmQgbW9yZSBvZiB0aGUgc29jaWFsIGNoYXJhY3RlcmlzdGljcyBvZiAqa2VjZXJpYWFuKiwgY29tcGFyZWQgdG8gdGhlIG1vcmUgY29tcGV0aXRpdmUgb25lIGFzIGZvciAqa2VnZW1iaXJhYW4qICdqb3knOyBob3dldmVyLCB0aGUgc2V0dGluZ3MgZ2VuZXJhbGx5IGNvbnZlcmdlIG9uIHRoZSBtb3JlIHB1YmxpYy93aWRlciBzY29wZSBvZiB0aGVzZSB0d28gYHIgaGFwcHlyOjpzY2FwcygiaGFwcGluZXNzIilgIGNvbmNlcHRzIGNvbXBhcmVkIHRvICprZXNlbmFuZ2FuKiAncGxlYXN1cmUnLCB3aGljaCBpcyBtb3JlIHNlbGYtY2VudHJlZC4gQWZmZWN0aXZlLXJlbGF0ZWQgY29sbG9jYXRlcyBmb3IgKmtlY2VyaWFhbiogaW5jbHVkZSAqa2VzZWdhcmFuKiAnZnJlc2huZXNzJyBhbmQgKnNlbWFuZ2F0KiAnZW50aHVzaWFzbScsIHRoZSBsYXR0ZXIgb2Ygd2hpY2ggY2FuIHN1cHBvcnQgdGhlIHByb3Bvc2VkIGFyZ3VtZW50IGZvciB0aGUgbGl2ZWxpbmVzcywgaW50ZW5zZSwgYW5kIHZpYnJhbmN5IG9mICprZWNlcmlhYW4qICdjaGVlcmZ1bG5lc3MnLgoKIyMgRGlzdGluY3RpdmUgbWV0YXBob3JzIGZvciAqa2VyaWFuZ2FuKiAnY2hlZXIoZnVsbmVzcyknIHsjcmlhbmd9CgpUaGUgZGlzdGluY3RpdmUgbWV0YXBob3JzIGZvciAqa2VyaWFuZ2FuKiBhcmUgc2V0IG91dCBpbiBbVGFibGUgXEByZWYodGFiOmRpc3RpbmN0aXZlLWZvci1rZXJpYW5nYW4pXSgjZGlzdGluY3RpdmUtZm9yLWtlcmlhbmdhbikuIFRoZSBkaXN0aW5jdGl2ZSBtZXRhcGhvcnMgZm9yIHRoZSByb290LW5vbWluYWwgKnJpYW5nKiAndmVyeSBoYXBweTsgam95b3VzOyBnbGFkJyBhcmUgZmlsdGVyZWQgb3V0IGdpdmVuIHRoZSBBc3NvY1N0ciB2YWx1ZXMgYXJlIGJlbG93IHRoZSBzZXQgdGhyZXNob2xkIG9mIDIgZm9yIHRoZSBkaXNjdXNzaW9uLiBBbHNvLCBib3RoICprZXJpYW5nYW4qIGFuZCAqcmlhbmcqIGhhdmUgdGhlIGxlYXN0IG1ldGFwaG9yaWNhbCB0b2tlbnMgY29tcGFyZWQgdG8gdGhlIG90aGVyIHN5bm9ueW1zIHdpdGhpbiB0aGVpciByZXNwZWN0aXZlIG1vcnBob2xvZ2ljYWwgZm9ybXMgKE5+Kmtlcmlhbmdhbip+ID0gYHIgc3Vic2V0KHN5bm9ueW1fdG9rZW4sIHN5bm9ueW1zID09ICJrZXJpYW5nYW4iKVtbIm4iXV1gIGFuZCBOfipyaWFuZyp+ID0gYHIgc3Vic2V0KHN5bm9ueW1fdG9rZW4sIHN5bm9ueW1zID09ICJyaWFuZyIpW1sibiJdXWApLiBGb3IgdGhpcyByZWFzb24sIHNvbWUgb2YgdGhlIHJlc3VsdHMgbmVlZCB0byBiZSBpbnRlcnByZXRlZCB3aXRoIGNhdXRpb24uCgpgYGB7ciBkaXN0aW5jdGl2ZS1mb3Ita2VyaWFuZ2FufQptZGNhX3JlcyAlPiUKICBoYXBweXI6Om1kY2FfYXR0cihjeG5fdHlwZSA9ICJrZXJpYW5nYW4iLCBtaW5fYXNzb2NzdHIgPSAyKSAlPiUgCiAgbXV0YXRlKGV4cCA9IHJvdW5kKGV4cCwgM0wpLAogICAgICAgICBtZXRhcGhvcnMgPSBoYXBweXI6OnNjYXBzKG1ldGFwaG9ycykpICU+JSAKICBzZWxlY3QoLXN5bm9ueW1zKSAlPiUKICBrbml0cjo6a2FibGUoY2FwdGlvbiA9ICJEaXN0aW5jdGl2ZSBtZXRhcGhvcnMgZm9yICprZXJpYW5nYW4qICdjaGVlcihmdWxuZXNzKSciLCByb3cubmFtZXMgPSBUUlVFKQpgYGAKClRoZSBpbnRlbnNpdHkgb2YgKmtlcmlhbmdhbiogY2FuIGJlIGluZmVycmVkIGZyb20gaXRzIHNpZ25pZmljYW50IGFzc29jaWF0aW9uIHdpdGggdGhlIGByIGhhcHB5cjo6c2NhcHMoImNvbnRhaW5lZCBlbnRpdHkiKWAgbWV0YXBob3IsIHdoaWNoIGlzIGFsc28gZGlzdGluY3RpdmUgZm9yICprZWNlcmlhYW4qIChjZi4gW1RhYmxlIFxAcmVmKHRhYjpkaXN0aW5jdGl2ZS1mb3Ita2VjZXJpYWFuKV0oI2Rpc3RpbmN0aXZlLWZvci1rZWNlcmlhYW4pKS4gKktlcmlhbmdhbiogbW9zdCBmcmVxdWVudGx5IGNvbGxvY2F0ZXMgd2l0aCBvbmx5IG9uZSBsZXhpY2FsIHVuaXQgKExVKSB0eXBlIG9mIHRoZSBtZXRhcGhvciBldm9raW5nICdmdWxsbmVzcycgb2YgdGhlIENvbnRlbnQgaW4gdGhlIGZvbGxvd2luZyBtZXRhcGhvcmljYWwgcGF0dGVybjogXyoqcGVudWgqKiAoZGVuZ2FuKSBrZXJpYW5nYW5fICd0byBiZSAqZnVsbCogb2YoL3dpdGgpIGNoZWVyKGZ1bGxuZXNzKScgKGByIGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IgJT4lIGZpbHRlcihzdHJfZGV0ZWN0KHN5bm9ueW1zLCAia2VyaWFuZ2FuIiksIHN0cl9kZXRlY3QobWV0YXBob3JzLCAiY29udGFpbmVkIGVudGl0eSIpKSAlPiUgY291bnQobV9leHByLCBzb3J0ID0gVFJVRSkgJT4lIGZpbHRlcihuID09IG1heChuKSkgJT4lIC5bWyJuIl1dYCB0b2tlbnMpLiBUaGlzIHNhbGllbnQgcGF0dGVybiByZXZlYWxzIHRoYXQgKmtlcmlhbmdhbiogaXMgcHJvbWluZW50bHkgdGFsa2VkIGFib3V0IGluIHRlcm1zIG9mIGl0cyAnaW50ZW5zZScgc3RhdGUgKGkuZS4sIGJlaW5nIGZ1bGwgb2YgaXQpLgoKYGBge3IgZGlzdGluY3RpdmUtZm9yLXJpYW5nfQptZGNhX3JlcyAlPiUKICBoYXBweXI6Om1kY2FfYXR0cihjeG5fdHlwZSA9ICJecmlhbmckIiwgbWluX2Fzc29jc3RyID0gMS4zMDEwMykgJT4lIAogIG11dGF0ZShleHAgPSByb3VuZChleHAsIDNMKSwKICAgICAgICAgbWV0YXBob3JzID0gaGFwcHlyOjpzY2FwcyhtZXRhcGhvcnMpKSAlPiUgCiAgc2VsZWN0KC1zeW5vbnltcykgJT4lCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSAiRGlzdGluY3RpdmUgbWV0YXBob3JzIGZvciAqcmlhbmcqICd2ZXJ5IGhhcHB5OyBqb3lvdXMnIiwgcm93Lm5hbWVzID0gVFJVRSkKYGBgCgpbVGFibGUgXEByZWYodGFiOnJlcGVsbGVkLWJ5LWtlcmlhbmdhbildKCNyZXBlbGxlZC1ieS1rZXJpYW5nYW4pIHNob3dzIHRoZSBzdHJvbmdseSByZXBlbGxlZCBtZXRhcGhvciBieSAqa2VyaWFuZ2FuKiAnY2hlZXIoZnVsbmVzcyknLgoKYGBge3IgcmVwZWxsZWQtYnkta2VyaWFuZ2FufQptZGNhX3JlcyAlPiUKICBoYXBweXI6Om1kY2FfcmVwZWwoY3huX3R5cGUgPSAia2VyaWFuZ2FuIiwgbWluX2Fzc29jc3RyID0gLTIpICU+JSAKICBtdXRhdGUoZXhwID0gcm91bmQoZXhwLCAzTCksCiAgICAgICAgIG1ldGFwaG9ycyA9IGhhcHB5cjo6c2NhcHMobWV0YXBob3JzKSkgJT4lIAogIHNlbGVjdCgtc3lub255bXMpICU+JQogIGtuaXRyOjprYWJsZShjYXB0aW9uID0gIlJlcGVsbGVkIG1ldGFwaG9ycyBmb3IgKmtlcmlhbmdhbiogJ2NoZWVyKGZ1bG5lc3MpJyIsIHJvdy5uYW1lcyA9IFRSVUUpCmBgYAoKYGBge3IgY29sbG9jLXJlcy1rZXJpYW5nYW59CiMgcHJlc2VudCB0aGUgcmVzdWx0IHRhYmxlIGZvciBjb2xsb2NhdGlvbmFsIGFuYWx5c2lzIGZvciAqa2VyaWFuZ2FuKgpoYXBweXI6Om1kY2FfYXR0cihtZGNhX2NvbGxvYywgY3huX3R5cGUgPSAnXmtlcmlhbmdhbicpICU+JSAKICB0b3BfbigyMCwgYXNzb2NzdHIpICU+JSAKICBsZWZ0X2pvaW4oaGFwcHlyOjpkaXN0X2NvbGxvY19nbG9zcywgYnkgPSAiY29sbG9jYXRlcyIpICU+JSAjIGxlZnQtam9pbiB0aGUgZ2xvc3MgZm9yIHRoZSBkaXN0aW5jdGl2ZSBjb2xsb2NhdGVzCiAgc2VsZWN0KC1zeW5vbnltcykgJT4lCiAgc2VsZWN0KGNvbGxvY2F0ZXMsIGdsb3NzLCBldmVyeXRoaW5nKCkpICU+JQogIG11dGF0ZShleHAgPSByb3VuZChleHAsIDMpLCAKICAgICAgICAgY29sbG9jYXRlcyA9IHBhc3RlKCIqIiwgY29sbG9jYXRlcywgIioiLCBzZXAgPSAiIikpICU+JQogIGtuaXRyOjprYWJsZShjYXB0aW9uID0gcGFzdGUoIlRoZSAyMCBtb3N0IGRpc3RpbmN0aXZlLCA0LXdpbmRvdyBzcGFuIGNvbGxvY2F0ZXMgZm9yICprZXJpYW5nYW4qICdjaGVlcmZ1bG5lc3MnIGluIHRoZSBjb21iaW5lZCBkYXRhIHNldHMgKEluZG9uZXNpYW4gTGVpcHppZyBDb3Jwb3JhLCBJV2FDIFNrZXRjaCBFbmdpbmUsIGFuZCBXZWJDb3JwKV5bQXMgZXhwbGFpbmVkIGluIGAqKkNoYXB0ZXIgMyoqYCwgdGhlIG5vbWluYWxpc2VkIGZvcm1zIGZvciAiLCBoYXBweXI6OnNjYXBzKCJjZXJpYSIpLCAiIGFuZCAiLCBoYXBweXI6OnNjYXBzKCJyaWFuZyIpLCAiIG9jY3VyIGluIGEgdmVyeSBsb3cgZnJlcXVlbmN5IGluIHRoZSB3aG9sZSBJbmRvbmVzaWFuIExlaXB6aWcgQ29ycG9yYSBjb21wYXJlZCB0byB0aGUgZm9ybXMgZm9yIHRoZSBvdGhlciBjb25jZXB0cy4gQWRkaXRpb25hbCBkYXRhIGZvciB0aGVzZSBmb3JtcyBhcmUgdGhlbiBjdWxsZWQgZnJvbSB0aGUgKklXYUMqIG9mICpTa2V0Y2ggRW5naW5lKiBhbmQgdGVuIG9ubGluZSBJbmRvbmVzaWFuIG5ld3NwYXBlcnMgdmlhICpXZWJDb3JwKi5dLiIsIHNlcCA9ICIiKSwgcm93Lm5hbWVzID0gVFJVRSkKYGBgCgpgYGB7ciBwbG90LW1ldGFwaG9yLXR5cGUtZnJlcS1wZXItc3luLCBmaWcuY2FwID0gIkRpc3RyaWJ1dGlvbiBvZiBtZXRhcGhvciB0eXBlcyBwZXIgc3lvbnlueW1zIGFnYWludHMgdGhlaXIgdG9rZW4gZnJlcXVlbmN5IGluIG1ldGFwaG9yaWNhbCBwYXR0ZXJucy4iLCBlY2hvID0gRkFMU0UsIGluY2x1ZGUgPSBGQUxTRX0KCiMgYWRkaXRpb25hbCBjb2RlcyBmb3IgdmlzdWFsaXNpbmcgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSB0b2tlbiBmcmVxdWVuY3kgb2YgdGhlIHN5bm9ueW1zIGluIG1ldGFwaG9yaWNhbCBleHByZXNzaW9ucyBhbmQgdGhlIG51bWJlciBvZiBtZXRhcGhvciB0eXBlcyBldm9rZWQuIFRoaXMgaXMgbm90IHBhcnQgb2YgdGhlIGFuYWx5c2lzIGluIHRoZSB0aGVzaXMuCgojIE5hcnJhdGlvbjoKIyMgW0ZpZ3VyZSBcQHJlZihmaWc6cGxvdC1tZXRhcGhvci10eXBlLWZyZXEtcGVyLXN5bildKCNwbG90LW1ldGFwaG9yLXR5cGUtZnJlcS1wZXItc3luKSB2aXN1YWxpc2VzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgdG9rZW4gZnJlcXVlbmN5IG9mIG1ldGFwaG9yaWNhbCBwYXR0ZXJucyBmb3IgYSBnaXZlbiBzeW5vbnltcyAoKnkqLWF4aXMpIGFuZCB0aGUgbnVtYmVyIG9mIG1ldGFwaG9yIHR5cGVzIGV2b2tlZCBieSB0aGUgbWV0YXBob3JpY2FsIHBhdHRlcm5zICgqeCotYXhpcykuCgptZXRhcGhvcl90eXBlX2RmIDwtIGhhcHB5cjo6cGhkX2RhdGFfbWV0YXBob3IgJT4lIAogIG11dGF0ZShkYXRhX3R5cGUgPSBpZl9lbHNlKCFzdHJfZGV0ZWN0KHN5bm9ueW1zLCAiXmtlLithbiQiKSwgInJvb3QiLCAibm9taW5hbGlzZWQiKSkgJT4lIAogIGdyb3VwX2J5KHN5bm9ueW1zLCBkYXRhX3R5cGUpICU+JSAKICBzdW1tYXJpc2Uoc3lub255bXNfdG9rZW5zID0gbigpLAogICAgICAgICAgICBtZXRhcGhvcl90eXBlc19wZXJfc3lub255bXMgPSBuX2Rpc3RpbmN0KG1ldGFwaG9ycykpICU+JSAKICBhcnJhbmdlKGRhdGFfdHlwZSwgZGVzYyhzeW5vbnltc190b2tlbnMpKQoKbWV0YXBob3JfdHlwZV9kZiAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gbWV0YXBob3JfdHlwZXNfcGVyX3N5bm9ueW1zLAogICAgICAgICAgICAgeSA9IHN5bm9ueW1zX3Rva2VucywKICAgICAgICAgICAgIGNvbG91ciA9IGRhdGFfdHlwZSwKICAgICAgICAgICAgIGdyb3VwID0gZGF0YV90eXBlKSkgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSBzeW5vbnltcykpICsKICB4bGltKGMoMCwgNjApKSArCiAgdGhlbWVfYncoKQpgYGAKCmBgYHtyIGtlbmRhbGwtY29ydGVzdCwgZWNobyA9IEZBTFNFLCBpbmNsdWRlID0gRkFMU0V9CiMgY29kZSBmb3IgY29tcHV0aW5nIGNvcnJlbGF0aW9uIHRlc3QgYmV0d2VlbiB0aGUgdG9rZW4gZnJlcXVlbmN5IG9mIHRoZSBzeW5vbnltcyBpbiB0aGUgbWV0YXBob3JpY2FsIGV4cHJlc3Npb25zIGFuZCB0aGUgbnVtYmVyIG9mIG1ldGFwaG9yIHR5cGVzIGV2b2tlZC4gVGhpcyBpcyBub3QgcGFydCBvZiB0aGUgYW5hbHlzaXMgaW4gdGhlIHRoZXNpcy4Ka2VuZGFsbF9yZXMgPC0gY29yLnRlc3QobWV0YXBob3JfdHlwZV9kZiRzeW5vbnltc190b2tlbnMsIG1ldGFwaG9yX3R5cGVfZGYkbWV0YXBob3JfdHlwZXNfcGVyX3N5bm9ueW1zLCBtZXRob2QgPSAia2VuZGFsbCIsIGNvbmYubGV2ZWwgPSAwLjk5LCBhbHRlcm5hdGl2ZSA9ICJncmVhdGVyIikKYGBgCgojIFIgc2Vzc2lvbiBpbmZvIHstfQoKYGBge3Igc2Vzc2lvbi1pbmZvfQpkZXZ0b29sczo6c2Vzc2lvbl9pbmZvKCkKcm1hcmtkb3duOjpwYW5kb2NfdmVyc2lvbigpCmBgYAoKIyBSZWZlcmVuY2VzIHstfQoKCg==