diff --git a/session_4/img/transform-logical.png b/session_4/img/transform-logical.png new file mode 100644 index 0000000000000000000000000000000000000000..43462e6394b8bb292c7ccf6c38ce142ded767059 Binary files /dev/null and b/session_4/img/transform-logical.png differ diff --git a/session_4/slides.Rmd b/session_4/slides.Rmd new file mode 100644 index 0000000000000000000000000000000000000000..f8de0a4aa3a9dc2205b68815dae52d0d6ce80fad --- /dev/null +++ b/session_4/slides.Rmd @@ -0,0 +1,315 @@ +--- +title: "R#4: data transformation" +author: "Laurent Modolo [laurent.modolo@ens-lyon.fr](mailto:laurent.modolo@ens-lyon.fr)" +date: "08 Nov 2019" +output: + slidy_presentation: + highlight: tango + beamer_presentation: + theme: metropolis + slide_level: 3 + fig_caption: no + df_print: tibble + highlight: tango + latex_engine: xelatex +--- +```{r setup, include=FALSE, cache=TRUE} +knitr::opts_chunk$set(echo = FALSE) +library(tidyverse) +``` + +## R#4: data transformation +The goal of this practical is to practices data transformation with `tidyverse`. +The objectives of this session will be to: + +- Filter rows with `filter()` +- Arrange rows with `arrange()` +- Select columns with `select()` +- Add new variables with `mutate()` +- Combining multiple operations with the pipe `%>%` + +## **nycflights13** + +`nycflights13::flights`contains all 336,776 flights that departed from New York City in 2013. The data comes from the US Bureau of Transportation Statistics, and is documented in `?flights` + +```{r load_data, eval=T, message=FALSE, cache=T} +library(nycflights13) +library(tidyverse) +``` + + + +## **nycflights13** + +```{r display_data, eval=F, message=FALSE, cache=T} +flights +``` + +- **int** stands for integers. +- **dbl** stands for doubles, or real numbers. +- **chr** stands for character vectors, or strings. +- **dttm** stands for date-times (a date + a time). +- **lgl** stands for logical, vectors that contain only TRUE or FALSE. +- **fctr** stands for factors, which R uses to represent categorical variables with fixed possible values. +- **date** stands for dates. + +## Filter rows with `filter()` + +`filter()` allows you to subset observations based on their values. + +```{r filter_month_day, eval=T, message=T, cache=T} +filter(flights, month == 1, day == 1) +``` + +## Filter rows with `filter()` + +`dplyr` functions never modify their inputs, so if you want to save the result, you’ll need to use the assignment operator, `<-` + +```{r filter_month_day_sav, eval=T, message=F, cache=T} +jan1 <- filter(flights, month == 1, day == 1) +``` + +R either prints out the results, or saves them to a variable. + +```{r filter_month_day_sav_display, eval=T, message=F, cache=T} +(dec25 <- filter(flights, month == 12, day == 25)) +``` + +## Logical operators + +Multiple arguments to `filter()` are combined with “andâ€: every expression must be true in order for a row to be included in the output. + +```{r logical_operator, echo=FALSE, out.width='100%'} +knitr::include_graphics('img/transform-logical.png') +``` + +## Logical operators + +Test the following operations: + +```{r filter_logical_operators, eval=T, message=F, cache=T} +filter(flights, month == 11 | month == 12) +filter(flights, month %in% c(11, 12)) +filter(flights, !(arr_delay > 120 | dep_delay > 120)) +filter(flights, arr_delay <= 120, dep_delay <= 120) +``` + +## Missing values + +One important feature of R that can make comparison tricky are missing values, or `NA`s (“not availablesâ€). + +```{r filter_logical_operators_NA, eval=T, message=T, cache=T} +NA > 5 +10 == NA +NA + 10 +NA / 2 +``` + +## Missing values + +```{r filter_logical_operators_test_NA, eval=T, message=T, cache=T} +NA == NA +is.na(NA) +``` + +## Filter challenges + +Find all flights that: + +- Had an arrival delay of two or more hours +- Were operated by United, American, or Delta +- Departed between midnight and 6am (inclusive) + +Another useful dplyr filtering helper is `between()`. What does it do? Can you use it to simplify the code needed to answer the previous challenges? + +How many flights have a missing `dep_time`? What other variables are missing? What might these rows represent? + +Why is `NA ^ 0` not `NA`? Why is `NA | TRUE` not `NA`? Why is `FALSE & NA` not `NA`? Can you figure out the general rule? (`NA * 0` is a tricky counter-example!) + + +## Arrange rows with `arrange()` + +`arrange()` works similarly to `filter()` except that instead of selecting rows, it changes their order. + +```{r arrange_ymd, eval=F, message=F, cache=T} +arrange(flights, year, month, day) +``` + +Use `desc()` to re-order by a column in descending order: + +```{r arrange_desc, eval=F, message=F, cache=T} +arrange(flights, desc(dep_delay)) +``` + +Missing values are always sorted at the end: + +```{r arrange_NA, eval=F, message=F, cache=T} +arrange(tibble(x = c(5, 2, NA)), x) +arrange(tibble(x = c(5, 2, NA)), desc(x)) +``` + +## Arrange challenges + +- Sort flights to find the most delayed flights. Find the flights that left earliest. +- Sort flights to find the fastest flights. +- Which flights traveled the longest? Which traveled the shortest? + +## Select columns with `select()` + +`select()` allows you to rapidly zoom in on a useful subset using operations based on the names of the variables. + +```{r select_ymd, eval=F, message=F, cache=T} +select(flights, year, month, day) +select(flights, year:day) +select(flights, -(year:day)) +``` + +## Select columns with `select()` + +here are a number of helper functions you can use within `select()`: + +- `starts_with("abc")`: matches names that begin with “abcâ€. +- `ends_with("xyz")`: matches names that end with “xyzâ€. +- `contains("ijk")`: matches names that contain “ijkâ€. +- `matches("(.)\\1")`: selects variables that match a regular expression. This one matches any variables that contain repeated characters. You’ll learn more about regular expressions in strings. +- `num_range("x", 1:3)`: matches `x1`, `x2` and `x3`. + +See `?select` for more details. + +## Select challenges + +- Brainstorm as many ways as possible to select `dep_time`, `dep_delay`, `arr_time`, and `arr_delay` from `flights`. +- What does the `one_of()` function do? Why might it be helpful in conjunction with this vector? +```{r select_one_of, eval=F, message=F, cache=T} +vars <- c("year", "month", "day", "dep_delay", "arr_delay") +``` +- Does the result of running the following code surprise you? How do the select helpers deal with case by default? How can you change that default? +```{r select_contains, eval=F, message=F, cache=T} +select(flights, contains("TIME")) +``` + +## Add new variables with `mutate()` + +It’s often useful to add new columns that are functions of existing columns. That’s the job of `mutate()`. + +```{r mutate, eval=F, message=F, cache=T} +flights_sml <- select(flights, + year:day, + ends_with("delay"), + distance, + air_time +) +mutate(flights_sml, + gain = dep_delay - arr_delay, + speed = distance / air_time * 60 +) +``` + +**4_a** + +## Add new variables with `mutate()` + +You can refer to columns that you’ve just created: + +```{r mutate_reuse, eval=F, message=F, cache=T} +mutate(flights, + gain = dep_delay - arr_delay, + hours = air_time / 60, + gain_per_hour = gain / hours +) +``` + +## Useful creation functions + +- Offsets: `lead()` and `lag()` allow you to refer to leading or lagging values. This allows you to compute running differences (e.g. `x - lag(x)`) or find when values change (`x != lag(x)`). +- Cumulative and rolling aggregates: R provides functions for running sums, products, mins and maxes: `cumsum()`, `cumprod()`, `cummin()`, `cummax()`; and dplyr provides `cummean()` for cumulative means. +- Logical comparisons, `<`, `<=`, `>`, `>=`, `!=`, and `==` +- Ranking: there are a number of ranking functions, but you should start with `min_rank()`. There is also `row_number()`, `dense_rank()`, `percent_rank()`, `cume_dist()`, `ntile()` + +## Mutate challenges + +- Currently `dep_time` and `sched_dep_time` are convenient to look at, but hard to compute with because they’re not really continuous numbers. Convert them to a more convenient representation of number of minutes since midnight. + +\pause + +```{r mutate_challenges_a, eval=F, message=F, cache=T} +mutate( + flights, + dep_time = (dep_time %/% 100) * 60 + + dep_time %% 100, + sched_dep_time = (sched_dep_time %/% 100) * 60 + + sched_dep_time %% 100 +) +``` + +**4_b** + +## Mutate challenges + +- Compare `dep_time`, `sched_dep_time`, and `dep_delay`. How would you expect those three numbers to be related? + +\pause + +```{r mutate_challenge_b, eval=F, message=F, cache=T} +mutate( + flights, + dep_time = (dep_time %/% 100) * 60 + + dep_time %% 100, + sched_dep_time = (sched_dep_time %/% 100) * 60 + + sched_dep_time %% 100 +) +``` + +**4_c** + +## Mutate challenges + +- Find the 10 most delayed flights using a ranking function. How do you want to handle ties? Carefully read the documentation for `min_rank()` + +\pause + +```{r mutate_challenge_c, eval=F, message=F, cache=T} +flights_md <- mutate(flights, most_delay = min_rank(desc(dep_delay))) +filter(flights_md, most_delay < 10) +``` + +**4_d** + +## Combining multiple operations with the pipe + +We don't want to create useless intermediate variables so we can use the pipe opperator: `%>%` +(`ctrl + shift + M`). + +```{r pipe_example_a, eval=F, message=F, cache=T} +flights_md <- mutate(flights, + most_delay = min_rank(desc(dep_delay))) +flights_md <- filter(flights_md, most_delay < 10) +flights_md <- arrange(flights_md, most_delay) +``` + +## Combining multiple operations with the pipe + +We don't want to create useless intermediate variables so we can use the pipe opperator: `%>%` +(`ctrl + shift + M`). + +```{r pipe_example_b, eval=F, message=F, cache=T} +flights %>% + mutate(most_delay = min_rank(desc(dep_delay))) %>% + filter(most_delay < 10) %>% + arrange(most_delay) +``` + +## Combining multiple operations with the pipe + +Behind the scenes, `x %>% f(y)` turns into `f(x, y)`, and `x %>% f(y) %>% g(z)` turns into `g(f(x, y), z)` and so on. You can use the pipe to rewrite multiple operations in a way that you can read left-to-right, top-to-bottom. + +You can access the transmited variables with `.` + +```{r pipe_example_c, eval=F, message=F, cache=T} +flights %>% + mutate(most_delay = min_rank(desc(dep_delay))) %>% + filter(., most_delay < 10) %>% + arrange(., most_delay) +``` + +Working with the pipe is one of the key criteria for belonging to the `tidyverse`. The only exception is `ggplot2`: it was written before the pipe was discovered. Unfortunately, the next iteration of `ggplot2`, `ggvis`, which does use the pipe, isn’t quite ready for prime time yet. \ No newline at end of file diff --git a/web/4_b b/web/4_b new file mode 100644 index 0000000000000000000000000000000000000000..be9d2def3dc92afa8128fa22f4b4cbd2841f7815 --- /dev/null +++ b/web/4_b @@ -0,0 +1,7 @@ +mutate( + flights, + dep_time = (dep_time %/% 100) * 60 + + dep_time %% 100, + sched_dep_time = (sched_dep_time %/% 100) * 60 + + sched_dep_time %% 100 +) \ No newline at end of file diff --git a/web/4_c b/web/4_c new file mode 100644 index 0000000000000000000000000000000000000000..17749a3403d6cc3b5613b21913502d300d7206e4 --- /dev/null +++ b/web/4_c @@ -0,0 +1,7 @@ +mutate( + flights, + dep_time = (dep_time %/% 100) * 60 + + dep_time %% 100, + sched_dep_time = (sched_dep_time %/% 100) * 60 + + sched_dep_time %% 100 +) \ No newline at end of file diff --git a/web/4_d b/web/4_d new file mode 100644 index 0000000000000000000000000000000000000000..0a3bef6553f330cb4c0cc7ed3bb745103a38b244 --- /dev/null +++ b/web/4_d @@ -0,0 +1,2 @@ +flights_md <- mutate(flights, most_delay = min_rank(desc(dep_delay))) +filter(flights_md, most_delay < 10) \ No newline at end of file diff --git a/web/slides_4.html b/web/slides_4.html new file mode 100644 index 0000000000000000000000000000000000000000..a255f1302fe33393805f078095fce1f548078d83 --- /dev/null +++ b/web/slides_4.html @@ -0,0 +1,650 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> + <meta name="generator" content="pandoc" /> + <meta name="author" content="Laurent Modolo laurent.modolo@ens-lyon.fr" /> + <meta name="date" content="2019-11-08" /> + <title>R#4: data transformation</title> + <style type="text/css">code{white-space: pre;}</style> + <style type="text/css"> +body +{ +margin: 0 0 0 0; +padding: 0 0 0 0; +width: 100%; +height: 100%; +color: black; +background-color: white; +font-family: "Gill Sans MT", "Gill Sans", GillSans, sans-serif; +font-size: 14pt; +} +div.toolbar { +position: fixed; z-index: 200; +top: auto; bottom: 0; left: 0; right: 0; +height: 1.2em; text-align: right; +padding-left: 1em; +padding-right: 1em; font-size: 60%; +color: DimGray; +background-color: rgb(240,240,240); +border-top: solid 1px rgb(180,180,180); +} +div.toolbar span.copyright { +color: DimGray; +margin-left: 0.5em; +} +div.initial_prompt { +position: absolute; +z-index: 1000; +bottom: 1.2em; +width: 100%; +background-color: rgb(200,200,200); +opacity: 0.35; +background-color: rgb(200,200,200, 0.35); +cursor: pointer; +} +div.initial_prompt p.help { +text-align: center; +} +div.initial_prompt p.close { +text-align: right; +font-style: italic; +} +div.slidy_toc { +position: absolute; +z-index: 300; +width: 60%; +max-width: 30em; +height: 30em; +overflow: auto; +top: auto; +right: auto; +left: 4em; +bottom: 4em; +padding: 1em; +background: rgb(240,240,240); +border-style: solid; +border-width: 2px; +font-size: 60%; +} +div.slidy_toc .toc_heading { +text-align: center; +width: 100%; +margin: 0; +margin-bottom: 1em; +border-bottom-style: solid; +border-bottom-color: rgb(180,180,180); +border-bottom-width: 1px; +} +div.slide { +z-index: 20; +margin: 0 0 0 0; +padding-top: 0; +padding-bottom: 0; +padding-left: 20px; +padding-right: 20px; +border-width: 0; +clear: both; +top: 0; +bottom: 0; +left: 0; +right: 0; +line-height: 120%; +background-color: transparent; +} +div.background { +display: none; +} +div.handout { +margin-left: 20px; +margin-right: 20px; +} +div.slide.titlepage { +text-align: center; +} +div.slide.titlepage h1 { +padding-top: 10%; +margin-right: 0; +} +div.slide h1 { +padding-left: 0; +padding-right: 20pt; +padding-top: 4pt; +padding-bottom: 4pt; +margin-top: 0; +margin-left: 0; +margin-right: 60pt; +margin-bottom: 0.5em; +display: block; font-size: 160%; +line-height: 1.2em; +background: transparent; +} +@media screen and (max-device-width: 1024px) +{ +div.slide { font-size: 100%; } +} +@media screen and (max-device-width: 800px) +{ +div.slide { font-size: 200%; } +div.slidy_toc { +top: 1em; +left: 1em; +right: auto; +width: 80%; +font-size: 180%; +} +} +div.toc-heading { +width: 100%; +border-bottom: solid 1px rgb(180,180,180); +margin-bottom: 1em; +text-align: center; +} +img { +image-rendering: optimize-quality; +} +pre { +font-size: 80%; +font-weight: bold; +line-height: 120%; +padding-top: 0.2em; +padding-bottom: 0.2em; +padding-left: 1em; +padding-right: 1em; +border-style: solid; +border-left-width: 1em; +border-top-width: thin; +border-right-width: thin; +border-bottom-width: thin; +border-color: #95ABD0; +color: #00428C; +background-color: #E4E5E7; +} +li pre { margin-left: 0; } +blockquote { font-style: italic } +img { background-color: transparent } +p.copyright { font-size: smaller } +.center { text-align: center } +.footnote { font-size: smaller; margin-left: 2em; } +a img { border-width: 0; border-style: none } +a:visited { color: navy } +a:link { color: navy } +a:hover { color: red; text-decoration: underline } +a:active { color: red; text-decoration: underline } +a {text-decoration: none} +.toolbar a:link {color: blue} +.toolbar a:visited {color: blue} +.toolbar a:active {color: red} +.toolbar a:hover {color: red} +ul { list-style-type: square; } +ul ul { list-style-type: disc; } +ul ul ul { list-style-type: circle; } +ul ul ul ul { list-style-type: disc; } +li { margin-left: 0.5em; margin-top: 0.5em; } +li li { font-size: 85%; font-style: italic } +li li li { font-size: 85%; font-style: normal } +div dt +{ +margin-left: 0; +margin-top: 1em; +margin-bottom: 0.5em; +font-weight: bold; +} +div dd +{ +margin-left: 2em; +margin-bottom: 0.5em; +} +p,pre,ul,ol,blockquote,h2,h3,h4,h5,h6,dl,table { +margin-left: 1em; +margin-right: 1em; +} +p.subhead { font-weight: bold; margin-top: 2em; } +.smaller { font-size: smaller } +.bigger { font-size: 130% } +td,th { padding: 0.2em } +ul { +margin: 0.5em 1.5em 0.5em 1.5em; +padding: 0; +} +ol { +margin: 0.5em 1.5em 0.5em 1.5em; +padding: 0; +} +ul { list-style-type: square; } +ul ul { list-style-type: disc; } +ul ul ul { list-style-type: circle; } +ul ul ul ul { list-style-type: disc; } +ul li { list-style: square; +margin: 0.1em 0em 0.6em 0; +padding: 0 0 0 0; +line-height: 140%; +} +ol li { margin: 0.1em 0em 0.6em 1.5em; +padding: 0 0 0 0px; +line-height: 140%; +list-style-type: decimal; +} +li ul li { font-size: 85%; font-style: italic; +list-style-type: disc; +background: transparent; +padding: 0 0 0 0; +} +li li ul li { font-size: 85%; font-style: normal; +list-style-type: circle; +background: transparent; +padding: 0 0 0 0; +} +li li li ul li { +list-style-type: disc; +background: transparent; +padding: 0 0 0 0; +} +li ol li { +list-style-type: decimal; +} +li li ol li { +list-style-type: decimal; +} + +ol.outline li:hover { cursor: pointer } +ol.outline li.nofold:hover { cursor: default } +ul.outline li:hover { cursor: pointer } +ul.outline li.nofold:hover { cursor: default } +ol.outline { list-style:decimal; } +ol.outline ol { list-style-type:lower-alpha } +ol.outline li.nofold { +padding: 0 0 0 20px; +background: transparent url(data:image/gif;base64,R0lGODdhCQAJAIACAMzMzOvr/ywAAAAACQAJAAACD4SPoRvG614Dctb4MEMcFAA7) no-repeat 0px 0.5em; +} +ol.outline li.unfolded { +padding: 0 0 0 20px; +background: transparent url(data:image/gif;base64,R0lGODdhCQAJAKEDAMPD/8zMzOvr/////ywAAAAACQAJAAACEYyPoivG614LAlg7ZZbxoR8UADs=) no-repeat 0px 0.5em; +} +ol.outline li.folded { +padding: 0 0 0 20px; +background: transparent url(data:image/gif;base64,R0lGODdhCQAJAKEDAMPD/8zMzOvr/////ywAAAAACQAJAAACFIyPoiu2sJyCyoF7W3hxz850CFIAADs=) no-repeat 0px 0.5em; +} +ol.outline li.unfolded:hover { +padding: 0 0 0 20px; +background: transparent url(data:image/gif;base64,R0lGODdhCQAJAKEDAAAAAAAA/8PD/////ywAAAAACQAJAAACEYSPoivG614DIlg7ZZbxoQ8UADs=) no-repeat 0px 0.5em; +} +ol.outline li.folded:hover { +padding: 0 0 0 20px; +background: transparent url(data:image/gif;base64,R0lGODdhCQAJAKEDAAAAAAAA/8PD/////ywAAAAACQAJAAACFISPoiu2sZyCyoV7G3hxz850CFIAADs=) no-repeat 0px 0.5em; +} +ul.outline li.nofold { +padding: 0 0 0 20px; +background: transparent url(data:image/gif;base64,R0lGODdhCQAJAIACAMzMzOvr/ywAAAAACQAJAAACD4SPoRvG614Dctb4MEMcFAA7) no-repeat 0px 0.5em; +} +ul.outline li.unfolded { +padding: 0 0 0 20px; +background: transparent url(data:image/gif;base64,R0lGODdhCQAJAKEDAMPD/8zMzOvr/////ywAAAAACQAJAAACEYyPoivG614LAlg7ZZbxoR8UADs=) no-repeat 0px 0.5em; +} +ul.outline li.folded { +padding: 0 0 0 20px; +background: transparent url(data:image/gif;base64,R0lGODdhCQAJAKEDAMPD/8zMzOvr/////ywAAAAACQAJAAACFIyPoiu2sJyCyoF7W3hxz850CFIAADs=) no-repeat 0px 0.5em; +} +ul.outline li.unfolded:hover { +padding: 0 0 0 20px; +background: transparent url(data:image/gif;base64,R0lGODdhCQAJAKEDAAAAAAAA/8PD/////ywAAAAACQAJAAACEYSPoivG614DIlg7ZZbxoQ8UADs=) no-repeat 0px 0.5em; +} +ul.outline li.folded:hover { +padding: 0 0 0 20px; +background: transparent url(data:image/gif;base64,R0lGODdhCQAJAKEDAAAAAAAA/8PD/////ywAAAAACQAJAAACFISPoiu2sZyCyoV7G3hxz850CFIAADs=) no-repeat 0px 0.5em; +} + +a.titleslide { font-weight: bold; font-style: italic } + +img.hidden { display: none; visibility: hidden } +div.initial_prompt { display: none; visibility: hidden } +div.slide { +visibility: visible; +position: inherit; +} +div.handout { +border-top-style: solid; +border-top-width: thin; +border-top-color: black; +} +@media screen { +.hidden { display: none; visibility: visible } +div.slide.hidden { display: block; visibility: visible } +div.handout.hidden { display: block; visibility: visible } +div.background { display: none; visibility: hidden } +body.single_slide div.initial_prompt { display: block; visibility: visible } +body.single_slide div.background { display: block; visibility: visible } +body.single_slide div.background.hidden { display: none; visibility: hidden } +body.single_slide .invisible { visibility: hidden } +body.single_slide .hidden { display: none; visibility: hidden } +body.single_slide div.slide { position: absolute } +body.single_slide div.handout { display: none; visibility: hidden } +} +@media print { +.hidden { display: block; visibility: visible } +div.slide pre { font-size: 60%; padding-left: 0.5em; } +div.toolbar { display: none; visibility: hidden; } +div.slidy_toc { display: none; visibility: hidden; } +div.background { display: none; visibility: hidden; } +div.slide { page-break-before: always } + +div.slide.first-slide { page-break-before: avoid } +} + + +.jslider table { +margin-left: 0em; +margin-right: 0em; +} + +table.dataTable, .shiny-datatable-output div { +font-size: 14pt; +} + +.dataTables_info, .dataTables_paginate { +font-size: 19px; +} + +pre.sourceCode, code.sourceCode { +font-size: 80%; +} + +label, button, input, select, textarea { +font-size: 14pt; +} + +ul.nav, ul.nav li { +list-style-type: none; +} +</style> + <script src="data:application/javascript;base64,Lyogc2xpZHkuanMKCiAgIENvcHlyaWdodCAoYykgMjAwNS0yMDEzIFczQyAoTUlULCBFUkNJTSwgS2VpbyksIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAgIFczQyBsaWFiaWxpdHksIHRyYWRlbWFyaywgZG9jdW1lbnQgdXNlIGFuZCBzb2Z0d2FyZSBsaWNlbnNpbmcKICAgcnVsZXMgYXBwbHksIHNlZToKCiAgIGh0dHA6Ly93d3cudzMub3JnL0NvbnNvcnRpdW0vTGVnYWwvY29weXJpZ2h0LWRvY3VtZW50cwogICBodHRwOi8vd3d3LnczLm9yZy9Db25zb3J0aXVtL0xlZ2FsL2NvcHlyaWdodC1zb2Z0d2FyZQoKICAgRGVmaW5lcyBzaW5nbGUgbmFtZSAidzNjX3NsaWR5IiBpbiBnbG9iYWwgbmFtZXNwYWNlCiAgIEFkZHMgZXZlbnQgaGFuZGxlcnMgd2l0aG91dCB0cmFtcGxpbmcgb24gYW55IG90aGVycwoqLwoKLy8gdGhlIHNsaWR5IG9iamVjdCBpbXBsZW1lbnRhdGlvbgp2YXIgdzNjX3NsaWR5ID0gewogIC8vIGNsYXNzaWZ5IHdoaWNoIGtpbmQgb2YgYnJvd3NlciB3ZSdyZSBydW5uaW5nIHVuZGVyCiAgbnNfcG9zOiAodHlwZW9mIHdpbmRvdy5wYWdlWU9mZnNldCE9J3VuZGVmaW5lZCcpLAogIGtodG1sOiAoKG5hdmlnYXRvci51c2VyQWdlbnQpLmluZGV4T2YoIktIVE1MIikgPj0gMCA/IHRydWUgOiBmYWxzZSksCiAgb3BlcmE6ICgobmF2aWdhdG9yLnVzZXJBZ2VudCkuaW5kZXhPZigiT3BlcmEiKSA+PSAwID8gdHJ1ZSA6IGZhbHNlKSwKICBpcGFkOiAoKG5hdmlnYXRvci51c2VyQWdlbnQpLmluZGV4T2YoImlQYWQiKSA+PSAwID8gdHJ1ZSA6IGZhbHNlKSwKICBpcGhvbmU6ICgobmF2aWdhdG9yLnVzZXJBZ2VudCkuaW5kZXhPZigiaVBob25lIikgPj0gMCA/IHRydWUgOiBmYWxzZSksCiAgYW5kcm9pZDogKChuYXZpZ2F0b3IudXNlckFnZW50KS5pbmRleE9mKCJBbmRyb2lkIikgPj0gMCA/IHRydWUgOiBmYWxzZSksCiAgaWU6ICh0eXBlb2YgZG9jdW1lbnQuYWxsICE9ICJ1bmRlZmluZWQiICYmICF0aGlzLm9wZXJhKSwKICBpZTY6ICghdGhpcy5uc19wb3MgJiYgbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCJNU0lFIDYiKSAhPSAtMSksCiAgaWU3OiAoIXRoaXMubnNfcG9zICYmIG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigiTVNJRSA3IikgIT0gLTEpLAogIGllODogKCF0aGlzLm5zX3BvcyAmJiBuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoIk1TSUUgOCIpICE9IC0xKSwKICBpZTk6ICghdGhpcy5uc19wb3MgJiYgbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCJNU0lFIDkiKSAhPSAtMSksCgogIC8vIGRhdGEgZm9yIHN3aXBlIGFuZCBkb3VibGUgdGFwIGRldGVjdGlvbiBvbiB0b3VjaCBzY3JlZW5zCiAgbGFzdF90YXA6IDAsCiAgcHJldl90YXA6IDAsCiAgc3RhcnRfeDogMCwKICBzdGFydF95OiAwLAogIGRlbHRhX3g6IDAsCiAgZGVsdGFfeTogMCwKCiAgLy8gYXJlIHdlIHJ1bm5pbmcgYXMgWEhUTUw/IChkb2Vzbid0IHdvcmsgb24gT3BlcmEpCiAgaXNfeGh0bWw6IC94bWwvLnRlc3QoZG9jdW1lbnQuY29udGVudFR5cGUpLAoKICBzbGlkZV9udW1iZXI6IDAsIC8vIGludGVnZXIgc2xpZGUgY291bnQ6IDAsIDEsIDIsIC4uLgogIHNsaWRlX251bWJlcl9lbGVtZW50OiBudWxsLCAvLyBlbGVtZW50IGNvbnRhaW5pbmcgc2xpZGUgbnVtYmVyCiAgc2xpZGVzOiBbXSwgLy8gc2V0IHRvIGFycmF5IG9mIHNsaWRlIGRpdidzCiAgbm90ZXM6IFtdLCAvLyBzZXQgdG8gYXJyYXkgb2YgaGFuZG91dCBkaXYncwogIGJhY2tncm91bmRzOiBbXSwgLy8gc2V0IHRvIGFycmF5IG9mIGJhY2tncm91bmQgZGl2J3MKICBvYnNlcnZlcnM6IFtdLCAvLyBsaXN0IG9mIG9ic2VydmVyIGZ1bmN0aW9ucwogIHRvb2xiYXI6IG51bGwsIC8vIGVsZW1lbnQgY29udGFpbmluZyB0b29sYmFyCiAgdGl0bGU6IG51bGwsIC8vIGRvY3VtZW50IHRpdGxlCiAgbGFzdF9zaG93bjogbnVsbCwgLy8gbGFzdCBpbmNyZW1lbnRhbGx5IHNob3duIGl0ZW0KICBlb3M6IG51bGwsICAvLyBzcGFuIGVsZW1lbnQgZm9yIGVuZCBvZiBzbGlkZSBpbmRpY2F0b3IKICB0b2M6IG51bGwsIC8vIHRhYmxlIG9mIGNvbnRlbnRzCiAgb3V0bGluZTogbnVsbCwgLy8gb3V0bGluZSBlbGVtZW50IHdpdGggdGhlIGZvY3VzCiAgc2VsZWN0ZWRfdGV4dF9sZW46IDAsIC8vIGxlbmd0aCBvZiBkcmFnIHNlbGVjdGlvbiBvbiBkb2N1bWVudAogIHZpZXdfYWxsOiAwLCAgLy8gMSB0byB2aWV3IGFsbCBzbGlkZXMgKyBoYW5kb3V0cwogIHdhbnRfdG9vbGJhcjogdHJ1ZSwgIC8vIHVzZXIgcHJlZmVyZW5jZSB0byBzaG93L2hpZGUgdG9vbGJhcgogIG1vdXNlX2NsaWNrX2VuYWJsZWQ6IHRydWUsIC8vIGVuYWJsZXMgbGVmdCBjbGljayBmb3IgbmV4dCBzbGlkZQogIHNjcm9sbF9oYWNrOiAwLCAvLyBJRSB3b3JrIGFyb3VuZCBmb3IgcG9zaXRpb246IGZpeGVkCiAgZGlzYWJsZV9zbGlkZV9jbGljazogZmFsc2UsICAvLyB1c2VkIGJ5IGNsaWNrZWQgYW5jaG9ycwoKICBsYW5nOiAiZW4iLCAvLyB1cGRhdGVkIHRvIGxhbmd1YWdlIHNwZWNpZmllZCBieSBodG1sIGZpbGUKCiAgaGVscF9hbmNob3I6IG51bGwsIC8vIHVzZWQgZm9yIGtleWJvYXJkIGZvY3VzIGhhY2sgaW4gc2hvd1Rvb2xiYXIoKQogIGhlbHBfcGFnZTogImh0dHA6Ly93d3cudzMub3JnL1RhbGtzL1Rvb2xzL1NsaWR5Mi9oZWxwL2hlbHAuaHRtbCIsCiAgaGVscF90ZXh0OiAiTmF2aWdhdGUgd2l0aCBtb3VzZSBjbGljaywgc3BhY2UgYmFyLCBDdXJzb3IgTGVmdC9SaWdodCwgIiArCiAgICAgICAgICAgICAib3IgUGcgVXAgYW5kIFBnIERuLiBVc2UgUyBhbmQgQiB0byBjaGFuZ2UgZm9udCBzaXplLiIsCgogIHNpemVfaW5kZXg6IDAsCiAgc2l6ZV9hZGp1c3RtZW50OiAwLAogIHNpemVzOiAgbmV3IEFycmF5KCIxMHB0IiwgIjEycHQiLCAiMTRwdCIsICIxNnB0IiwgIjE4cHQiLCAiMjBwdCIsCiAgICAgICAgICAgICAgICAgICAgIjIycHQiLCAiMjRwdCIsICIyNnB0IiwgIjI4cHQiLCAiMzBwdCIsICIzMnB0IiksCgogIC8vIG5lZWRlZCBmb3IgZWZmaWNpZW50IHJlc2l6aW5nCiAgbGFzdF93aWR0aDogMCwKICBsYXN0X2hlaWdodDogMCwKCgogIC8vIE5lZWRlZCBmb3IgY3Jvc3MgYnJvd3NlciBzdXBwb3J0IGZvciByZWxhdGl2ZSB3aWR0aC9oZWlnaHQgb24KICAvLyBvYmplY3QgZWxlbWVudHMuIFRoZSB3b3JrIGFyb3VuZCBpcyB0byBzYXZlIHdpZHRoL2hlaWdodCBhdHRyaWJ1dGVzCiAgLy8gYW5kIHRoZW4gdG8gcmVjb21wdXRlIGFic29sdXRlIHdpZHRoL2hlaWdodCBkaW1lbnNpb25zIG9uIHJlc2l6aW5nCiAgIG9iamVjdHM6IFtdLAoKICAvLyBhdHRhY2ggaW5pdGlhbGlhdGlvbiBldmVudCBoYW5kbGVycwogIHNldF91cDogZnVuY3Rpb24gKCkgewogICAgdmFyIGluaXQgPSBmdW5jdGlvbigpIHsgdzNjX3NsaWR5LmluaXQoKTsgfTsKICAgIGlmICh0eXBlb2Ygd2luZG93LmFkZEV2ZW50TGlzdGVuZXIgIT0gInVuZGVmaW5lZCIpCiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCJsb2FkIiwgaW5pdCwgZmFsc2UpOwogICAgZWxzZQogICAgICB3aW5kb3cuYXR0YWNoRXZlbnQoIm9ubG9hZCIsIGluaXQpOwogIH0sCgogIGhpZGVfc2xpZGVzOiBmdW5jdGlvbiAoKSB7CiAgICBpZiAoZG9jdW1lbnQuYm9keSAmJiAhdzNjX3NsaWR5LmluaXRpYWxpemVkKQogICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLnZpc2liaWxpdHkgPSAiaGlkZGVuIjsKICAgIGVsc2UKICAgICAgc2V0VGltZW91dCh3M2Nfc2xpZHkuaGlkZV9zbGlkZXMsIDUwKTsKICB9LAoKICAvLyBoYWNrIHRvIHBlcnN1YWRlIElFIHRvIGNvbXB1dGUgY29ycmVjdCBkb2N1bWVudCBoZWlnaHQKICAvLyBhcyBuZWVkZWQgZm9yIHNpbXVsYXRpbmcgZml4ZWQgcG9zaXRpb25pbmcgb2YgdG9vbGJhcgogIGllX2hhY2s6IGZ1bmN0aW9uICgpIHsKICAgIHdpbmRvdy5yZXNpemVCeSgwLC0xKTsKICAgIHdpbmRvdy5yZXNpemVCeSgwLCAxKTsKICB9LAoKICBpbml0OiBmdW5jdGlvbiAoKSB7CiAgICAvL2FsZXJ0KCJzbGlkeSBzdGFydGluZyB0ZXN0IDEwIik7CiAgICBkb2N1bWVudC5ib2R5LnN0eWxlLnZpc2liaWxpdHkgPSAidmlzaWJsZSI7CiAgICB0aGlzLmluaXRfbG9jYWxpemF0aW9uKCk7CiAgICB0aGlzLmFkZF90b29sYmFyKCk7CiAgICB0aGlzLndyYXBfaW1wbGljaXRfc2xpZGVzKCk7CiAgICB0aGlzLmNvbGxlY3Rfc2xpZGVzKCk7CiAgICB0aGlzLmNvbGxlY3Rfbm90ZXMoKTsKICAgIHRoaXMuY29sbGVjdF9iYWNrZ3JvdW5kcygpOwogICAgdGhpcy5vYmplY3RzID0gZG9jdW1lbnQuYm9keS5nZXRFbGVtZW50c0J5VGFnTmFtZSgib2JqZWN0Iik7CiAgICB0aGlzLnBhdGNoX2FuY2hvcnMoKTsKICAgIHRoaXMuc2xpZGVfbnVtYmVyID0gdGhpcy5maW5kX3NsaWRlX251bWJlcihsb2NhdGlvbi5ocmVmKTsKICAgIHdpbmRvdy5vZmZzY3JlZW5idWZmZXJpbmcgPSB0cnVlOwogICAgdGhpcy5zaXplX2FkanVzdG1lbnQgPSB0aGlzLmZpbmRfc2l6ZV9hZGp1c3QoKTsKICAgIHRoaXMudGltZV9sZWZ0ID0gdGhpcy5maW5kX2R1cmF0aW9uKCk7CiAgICB0aGlzLmhpZGVfaW1hZ2VfdG9vbGJhcigpOyAgLy8gc3VwcHJlc3MgSUUgaW1hZ2UgdG9vbGJhciBwb3B1cAogICAgdGhpcy5pbml0X291dGxpbmVyKCk7ICAvLyBhY3RpdmF0ZSBmb2xkL3VuZm9sZCBzdXBwb3J0CiAgICB0aGlzLnRpdGxlID0gZG9jdW1lbnQudGl0bGU7CiAgICB0aGlzLmtleWJvYXJkbGVzcyA9ICh0aGlzLmlwYWR8fHRoaXMuaXBob25lfHx0aGlzLmFuZHJvaWQpOwoKICAgIGlmICh0aGlzLmtleWJvYXJkbGVzcykKICAgIHsKICAgICAgdzNjX3NsaWR5LnJlbW92ZV9jbGFzcyh3M2Nfc2xpZHkudG9vbGJhciwgImhpZGRlbiIpCiAgICAgIHRoaXMud2FudF90b29sYmFyID0gMDsKICAgIH0KCiAgICAvLyB3b3JrIGFyb3VuZCBmb3Igb3BlcmEgYnVnCiAgICB0aGlzLmlzX3hodG1sID0gKGRvY3VtZW50LmJvZHkudGFnTmFtZSA9PSAiQk9EWSIgPyBmYWxzZSA6IHRydWUpOwoKICAgIGlmICh0aGlzLnNsaWRlcy5sZW5ndGggPiAwKQogICAgewogICAgICB2YXIgc2xpZGUgPSB0aGlzLnNsaWRlc1t0aGlzLnNsaWRlX251bWJlcl07CiAgIAogICAgICBpZiAodGhpcy5zbGlkZV9udW1iZXIgPiAwKQogICAgICB7CiAgICAgICAgdGhpcy5zZXRfdmlzaWJpbGl0eV9hbGxfaW5jcmVtZW50YWwoInZpc2libGUiKTsKICAgICAgICB0aGlzLmxhc3Rfc2hvd24gPSB0aGlzLnByZXZpb3VzX2luY3JlbWVudGFsX2l0ZW0obnVsbCk7CiAgICAgICAgdGhpcy5zZXRfZW9zX3N0YXR1cyh0cnVlKTsKICAgICAgfQogICAgICBlbHNlCiAgICAgIHsKICAgICAgICB0aGlzLmxhc3Rfc2hvd24gPSBudWxsOwogICAgICAgIHRoaXMuc2V0X3Zpc2liaWxpdHlfYWxsX2luY3JlbWVudGFsKCJoaWRkZW4iKTsKICAgICAgICB0aGlzLnNldF9lb3Nfc3RhdHVzKCF0aGlzLm5leHRfaW5jcmVtZW50YWxfaXRlbSh0aGlzLmxhc3Rfc2hvd24pKTsKICAgICAgfQoKICAgICAgdGhpcy5zZXRfbG9jYXRpb24oKTsKICAgICAgdGhpcy5hZGRfY2xhc3ModGhpcy5zbGlkZXNbMF0sICJmaXJzdC1zbGlkZSIpOwogICAgICB3M2Nfc2xpZHkuc2hvd19zbGlkZShzbGlkZSk7CiAgICB9CgogICAgdGhpcy50b2MgPSB0aGlzLnRhYmxlX29mX2NvbnRlbnRzKCk7CgogICAgdGhpcy5hZGRfaW5pdGlhbF9wcm9tcHQoKTsKCiAgICAvLyBiaW5kIGV2ZW50IGhhbmRsZXJzIHdpdGhvdXQgaW50ZXJmZXJpbmcgd2l0aCBjdXN0b20gcGFnZSBzY3JpcHRzCiAgICAvLyBUYXAgZXZlbnRzIGJlaGF2ZSB0b28gd2VpcmRseSB0byBzdXBwb3J0IGNsaWNrcyByZWxpYWJseSBvbgogICAgLy8gaVBob25lIGFuZCBpUGFkLCBzbyBleGNsdWRlIHRoZXNlIGZyb20gY2xpY2sgaGFuZGxlcgoKICAgIGlmICghdGhpcy5rZXlib2FyZGxlc3MpCiAgICB7CiAgICAgIHRoaXMuYWRkX2xpc3RlbmVyKGRvY3VtZW50LmJvZHksICJjbGljayIsIHRoaXMubW91c2VfYnV0dG9uX2NsaWNrKTsKICAgICAgdGhpcy5hZGRfbGlzdGVuZXIoZG9jdW1lbnQuYm9keSwgIm1vdXNlZG93biIsIHRoaXMubW91c2VfYnV0dG9uX2Rvd24pOwogICAgfQoKICAgIHRoaXMuYWRkX2xpc3RlbmVyKGRvY3VtZW50LCAia2V5ZG93biIsIHRoaXMua2V5X2Rvd24pOwogICAgdGhpcy5hZGRfbGlzdGVuZXIoZG9jdW1lbnQsICJrZXlwcmVzcyIsIHRoaXMua2V5X3ByZXNzKTsKICAgIHRoaXMuYWRkX2xpc3RlbmVyKHdpbmRvdywgInJlc2l6ZSIsIHRoaXMucmVzaXplZCk7CiAgICB0aGlzLmFkZF9saXN0ZW5lcih3aW5kb3csICJzY3JvbGwiLCB0aGlzLnNjcm9sbGVkKTsKICAgIHRoaXMuYWRkX2xpc3RlbmVyKHdpbmRvdywgInVubG9hZCIsIHRoaXMudW5sb2FkZWQpOwoKICAgIHRoaXMuYWRkX2xpc3RlbmVyKGRvY3VtZW50LCAiZ2VzdHVyZWNoYW5nZSIsIGZ1bmN0aW9uICgpCiAgICB7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0pOwoKICAgIHRoaXMuYXR0YWNoX3RvdWNoX2hhbmRlcnModGhpcy5zbGlkZXMpOwoKICAgIC8vIHRoaXMgc2VlbXMgdG8gYmUgYSBkZWJ1Z2dpbmcgaGFjawogICAgLy9pZiAoIWRvY3VtZW50LmJvZHkub25jbGljaykKICAgIC8vICBkb2N1bWVudC5ib2R5Lm9uY2xpY2sgPSBmdW5jdGlvbiAoKSB7IH07CgogICAgdGhpcy5zaW5nbGVfc2xpZGVfdmlldygpOwoKICAgIC8vdGhpcy5zZXRfbG9jYXRpb24oKTsKCiAgICB0aGlzLnJlc2l6ZWQoKTsKCiAgICBpZiAodGhpcy5pZTcpCiAgICAgIHNldFRpbWVvdXQodzNjX3NsaWR5LmllX2hhY2ssIDEwMCk7CgogICAgdGhpcy5zaG93X3Rvb2xiYXIoKTsKCiAgICAvLyBmb3IgYmFjayBidXR0b24gZGV0ZWN0aW9uCiAgICBzZXRJbnRlcnZhbChmdW5jdGlvbiAoKSB7IHczY19zbGlkeS5jaGVja19sb2NhdGlvbigpOyB9LCAyMDApOwogICAgdzNjX3NsaWR5LmluaXRpYWxpemVkID0gdHJ1ZTsKICB9LAoKICAvLyBjcmVhdGUgZGl2IGVsZW1lbnQgd2l0aCBsaW5rcyB0byBlYWNoIHNsaWRlCiAgdGFibGVfb2ZfY29udGVudHM6IGZ1bmN0aW9uICgpIHsKICAgIHZhciB0b2MgPSB0aGlzLmNyZWF0ZV9lbGVtZW50KCJkaXYiKTsKICAgIHRoaXMuYWRkX2NsYXNzKHRvYywgInNsaWR5X3RvYyBoaWRkZW4iKTsKICAgIC8vdG9jLnNldEF0dHJpYnV0ZSgidGFiaW5kZXgiLCAiMCIpOwoKICAgIHZhciBoZWFkaW5nID0gdGhpcy5jcmVhdGVfZWxlbWVudCgiZGl2Iik7CiAgICB0aGlzLmFkZF9jbGFzcyhoZWFkaW5nLCAidG9jLWhlYWRpbmciKTsKICAgIGhlYWRpbmcuaW5uZXJIVE1MID0gdGhpcy5sb2NhbGl6ZSgiVGFibGUgb2YgQ29udGVudHMiKTsKCiAgICB0b2MuYXBwZW5kQ2hpbGQoaGVhZGluZyk7CiAgICB2YXIgcHJldmlvdXMgPSBudWxsOwoKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5zbGlkZXMubGVuZ3RoOyArK2kpCiAgICB7CiAgICAgIHZhciB0aXRsZSA9IHRoaXMuaGFzX2NsYXNzKHRoaXMuc2xpZGVzW2ldLCAidGl0bGUiKTsKICAgICAgdmFyIG51bSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKChpICsgMSkgKyAiLiAiKTsKCiAgICAgIHRvYy5hcHBlbmRDaGlsZChudW0pOwoKICAgICAgdmFyIGEgPSB0aGlzLmNyZWF0ZV9lbGVtZW50KCJhIik7CiAgICAgIGEuc2V0QXR0cmlidXRlKCJocmVmIiwgIiMoIiArIChpKzEpICsgIikiKTsKCiAgICAgIGlmICh0aXRsZSkKICAgICAgICB0aGlzLmFkZF9jbGFzcyhhLCAidGl0bGVzbGlkZSIpOwoKICAgICAgdmFyIG5hbWUgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSh0aGlzLnNsaWRlX25hbWUoaSkpOwogICAgICBhLmFwcGVuZENoaWxkKG5hbWUpOwogICAgICBhLm9uY2xpY2sgPSB3M2Nfc2xpZHkudG9jX2NsaWNrOwogICAgICBhLm9ua2V5ZG93biA9IHczY19zbGlkeS50b2Nfa2V5X2Rvd247CiAgICAgIGEucHJldmlvdXMgPSBwcmV2aW91czsKCiAgICAgIGlmIChwcmV2aW91cykKICAgICAgICBwcmV2aW91cy5uZXh0ID0gYTsKCiAgICAgIHRvYy5hcHBlbmRDaGlsZChhKTsKCiAgICAgIGlmIChpID09IDApCiAgICAgICAgdG9jLmZpcnN0ID0gYTsKCiAgICAgIGlmIChpIDwgdGhpcy5zbGlkZXMubGVuZ3RoIC0gMSkKICAgICAgewogICAgICAgIHZhciBiciA9IHRoaXMuY3JlYXRlX2VsZW1lbnQoImJyIik7CiAgICAgICAgdG9jLmFwcGVuZENoaWxkKGJyKTsKICAgICAgfQoKICAgICAgcHJldmlvdXMgPSBhOwogICAgfQoKICAgIHRvYy5mb2N1cyA9IGZ1bmN0aW9uICgpIHsKICAgICAgaWYgKHRoaXMuZmlyc3QpCiAgICAgICAgdGhpcy5maXJzdC5mb2N1cygpOwogICAgfQoKICAgIHRvYy5vbm1vdXNldXAgPSB3M2Nfc2xpZHkubW91c2VfYnV0dG9uX3VwOwoKICAgIHRvYy5vbmNsaWNrID0gZnVuY3Rpb24gKGUpIHsKICAgICAgZXx8KGU9d2luZG93LmV2ZW50KTsKCiAgICAgIGlmICh3M2Nfc2xpZHkuc2VsZWN0ZWRfdGV4dF9sZW4gPD0gMCkKICAgICAgICAgdzNjX3NsaWR5LmhpZGVfdGFibGVfb2ZfY29udGVudHModHJ1ZSk7CgogICAgICB3M2Nfc2xpZHkuc3RvcF9wcm9wYWdhdGlvbihlKTsKICAgIAogICAgICBpZiAoZS5jYW5jZWwgIT0gdW5kZWZpbmVkKQogICAgICAgIGUuY2FuY2VsID0gdHJ1ZTsKICAgICAgCiAgICAgIGlmIChlLnJldHVyblZhbHVlICE9IHVuZGVmaW5lZCkKICAgICAgICBlLnJldHVyblZhbHVlID0gZmFsc2U7CiAgICAgIAogICAgICByZXR1cm4gZmFsc2U7CiAgICB9OwoKICAgIGRvY3VtZW50LmJvZHkuaW5zZXJ0QmVmb3JlKHRvYywgZG9jdW1lbnQuYm9keS5maXJzdENoaWxkKTsKICAgIHJldHVybiB0b2M7CiAgfSwKCiAgaXNfc2hvd25fdG9jOiBmdW5jdGlvbiAoKSB7CiAgICByZXR1cm4gIXczY19zbGlkeS5oYXNfY2xhc3ModzNjX3NsaWR5LnRvYywgImhpZGRlbiIpOwogIH0sCgogIHNob3dfdGFibGVfb2ZfY29udGVudHM6IGZ1bmN0aW9uICgpIHsKICAgIHczY19zbGlkeS5yZW1vdmVfY2xhc3ModzNjX3NsaWR5LnRvYywgImhpZGRlbiIpOwogICAgdmFyIHRvYyA9IHczY19zbGlkeS50b2M7CiAgICB0b2MuZm9jdXMoKTsKCiAgICBpZiAodzNjX3NsaWR5LmllNyAmJiB3M2Nfc2xpZHkuc2xpZGVfbnVtYmVyID09IDApCiAgICAgIHNldFRpbWVvdXQodzNjX3NsaWR5LmllX2hhY2ssIDEwMCk7CiAgfSwKCiAgaGlkZV90YWJsZV9vZl9jb250ZW50czogZnVuY3Rpb24gKGZvY3VzKSB7CiAgICB3M2Nfc2xpZHkuYWRkX2NsYXNzKHczY19zbGlkeS50b2MsICJoaWRkZW4iKTsKCiAgICBpZiAoZm9jdXMgJiYgIXczY19zbGlkeS5vcGVyYSAmJgogICAgICAgICF3M2Nfc2xpZHkuaGFzX2NsYXNzKHczY19zbGlkeS50b2MsICJoaWRkZW4iKSkKICAgICAgdzNjX3NsaWR5LnNldF9mb2N1cygpOwogIH0sCgogIHRvZ2dsZV90YWJsZV9vZl9jb250ZW50czogZnVuY3Rpb24gKCkgewogICAgaWYgKHczY19zbGlkeS5pc19zaG93bl90b2MoKSkKICAgICAgdzNjX3NsaWR5LmhpZGVfdGFibGVfb2ZfY29udGVudHModHJ1ZSk7CiAgICBlbHNlCiAgICAgIHczY19zbGlkeS5zaG93X3RhYmxlX29mX2NvbnRlbnRzKCk7CiAgfSwKCiAgLy8gY2FsbGVkIG9uIGNsaWNraW5nIHRvYyBlbnRyeQogIHRvY19jbGljazogZnVuY3Rpb24gKGUpIHsKICAgIGlmICghZSkKICAgICAgZSA9IHdpbmRvdy5ldmVudDsKCiAgICB2YXIgdGFyZ2V0ID0gdzNjX3NsaWR5LmdldF90YXJnZXQoZSk7CgogICAgaWYgKHRhcmdldCAmJiB0YXJnZXQubm9kZVR5cGUgPT0gMSkKICAgIHsKICAgICAgdmFyIHVyaSA9IHRhcmdldC5nZXRBdHRyaWJ1dGUoImhyZWYiKTsKCiAgICAgIGlmICh1cmkpCiAgICAgIHsKICAgICAgICAvL2FsZXJ0KCJnb2luZyB0byAiICsgdXJpKTsKICAgICAgICB2YXIgc2xpZGUgPSB3M2Nfc2xpZHkuc2xpZGVzW3czY19zbGlkeS5zbGlkZV9udW1iZXJdOwogICAgICAgIHczY19zbGlkeS5oaWRlX3NsaWRlKHNsaWRlKTsKICAgICAgICB3M2Nfc2xpZHkuc2xpZGVfbnVtYmVyID0gdzNjX3NsaWR5LmZpbmRfc2xpZGVfbnVtYmVyKHVyaSk7CiAgICAgICAgc2xpZGUgPSB3M2Nfc2xpZHkuc2xpZGVzW3czY19zbGlkeS5zbGlkZV9udW1iZXJdOwogICAgICAgIHczY19zbGlkeS5sYXN0X3Nob3duID0gbnVsbDsKICAgICAgICB3M2Nfc2xpZHkuc2V0X2xvY2F0aW9uKCk7CiAgICAgICAgdzNjX3NsaWR5LnNldF92aXNpYmlsaXR5X2FsbF9pbmNyZW1lbnRhbCgiaGlkZGVuIik7CiAgICAgICAgdzNjX3NsaWR5LnNldF9lb3Nfc3RhdHVzKCF3M2Nfc2xpZHkubmV4dF9pbmNyZW1lbnRhbF9pdGVtKHczY19zbGlkeS5sYXN0X3Nob3duKSk7CiAgICAgICAgdzNjX3NsaWR5LnNob3dfc2xpZGUoc2xpZGUpOwogICAgICAgIC8vdGFyZ2V0LmZvY3VzKCk7CgogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgIGlmICghdzNjX3NsaWR5Lm9wZXJhKQogICAgICAgICAgICB3M2Nfc2xpZHkuc2V0X2ZvY3VzKCk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChlKQogICAgICAgIHsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICB3M2Nfc2xpZHkuaGlkZV90YWJsZV9vZl9jb250ZW50cyh0cnVlKTsKICAgIGlmICh3M2Nfc2xpZHkuaWU3KSB3M2Nfc2xpZHkuaWVfaGFjaygpOwogICAgdzNjX3NsaWR5LnN0b3BfcHJvcGFnYXRpb24oZSk7CiAgICByZXR1cm4gdzNjX3NsaWR5LmNhbmNlbChlKTsKICB9LAoKICAvLyBjYWxsZWQgb25rZXlkb3duIGZvciB0b2MgZW50cnkKICB0b2Nfa2V5X2Rvd246IGZ1bmN0aW9uIChldmVudCkgewogICAgdmFyIGtleTsKCiAgICBpZiAoIWV2ZW50KQogICAgICB2YXIgZXZlbnQgPSB3aW5kb3cuZXZlbnQ7CgogICAgLy8ga2x1ZGdlIGFyb3VuZCBOUy9JRSBkaWZmZXJlbmNlcyAKICAgIGlmICh3aW5kb3cuZXZlbnQpCiAgICAgIGtleSA9IHdpbmRvdy5ldmVudC5rZXlDb2RlOwogICAgZWxzZSBpZiAoZXZlbnQud2hpY2gpCiAgICAgIGtleSA9IGV2ZW50LndoaWNoOwogICAgZWxzZQogICAgICByZXR1cm4gdHJ1ZTsgLy8gWWlrZXMhIHVua25vd24gYnJvd3NlcgoKICAgIC8vIGlnbm9yZSBldmVudCBpZiBrZXkgdmFsdWUgaXMgemVybwogICAgLy8gYXMgZm9yIGFsdCBvbiBPcGVyYSBhbmQgS29ucXVlcm9yCiAgICBpZiAoIWtleSkKICAgICAgcmV0dXJuIHRydWU7CgogICAgLy8gY2hlY2sgZm9yIGNvbmN1cnJlbnQgY29udHJvbC9jb21tYW5kL2FsdCBrZXkKICAgIC8vIGJ1dCBhcmUgdGhlc2Ugb25seSBwcmVzZW50IG9uIG1vdXNlIGV2ZW50cz8KCiAgICBpZiAoZXZlbnQuY3RybEtleSB8fCBldmVudC5hbHRLZXkpCiAgICAgIHJldHVybiB0cnVlOwoKICAgIGlmIChrZXkgPT0gMTMpCiAgICB7CiAgICAgIHZhciB1cmkgPSB0aGlzLmdldEF0dHJpYnV0ZSgiaHJlZiIpOwoKICAgICAgaWYgKHVyaSkKICAgICAgewogICAgICAgIC8vYWxlcnQoImdvaW5nIHRvICIgKyB1cmkpOwogICAgICAgdmFyIHNsaWRlID0gdzNjX3NsaWR5LnNsaWRlc1t3M2Nfc2xpZHkuc2xpZGVfbnVtYmVyXTsKICAgICAgICB3M2Nfc2xpZHkuaGlkZV9zbGlkZShzbGlkZSk7CiAgICAgICAgdzNjX3NsaWR5LnNsaWRlX251bWJlciA9IHczY19zbGlkeS5maW5kX3NsaWRlX251bWJlcih1cmkpOwogICAgICAgIHNsaWRlID0gdzNjX3NsaWR5LnNsaWRlc1t3M2Nfc2xpZHkuc2xpZGVfbnVtYmVyXTsKICAgICAgICB3M2Nfc2xpZHkubGFzdF9zaG93biA9IG51bGw7CiAgICAgICAgdzNjX3NsaWR5LnNldF9sb2NhdGlvbigpOwogICAgICAgIHczY19zbGlkeS5zZXRfdmlzaWJpbGl0eV9hbGxfaW5jcmVtZW50YWwoImhpZGRlbiIpOwogICAgICAgIHczY19zbGlkeS5zZXRfZW9zX3N0YXR1cyghdzNjX3NsaWR5Lm5leHRfaW5jcmVtZW50YWxfaXRlbSh3M2Nfc2xpZHkubGFzdF9zaG93bikpOwogICAgICAgIHczY19zbGlkeS5zaG93X3NsaWRlKHNsaWRlKTsKICAgICAgICAvL3RhcmdldC5mb2N1cygpOwoKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICBpZiAoIXczY19zbGlkeS5vcGVyYSkKICAgICAgICAgICAgdzNjX3NsaWR5LnNldF9mb2N1cygpOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoZSkKICAgICAgICB7CiAgICAgICAgfQogICAgICB9CgogICAgICB3M2Nfc2xpZHkuaGlkZV90YWJsZV9vZl9jb250ZW50cyh0cnVlKTsKCiAgICAgIGlmIChzZWxmLmllNykKICAgICAgIHczY19zbGlkeS5pZV9oYWNrKCk7CgogICAgICByZXR1cm4gdzNjX3NsaWR5LmNhbmNlbChldmVudCk7CiAgICB9CgogICAgaWYgKGtleSA9PSA0MCAmJiB0aGlzLm5leHQpCiAgICB7CiAgICAgIHRoaXMubmV4dC5mb2N1cygpOwogICAgICByZXR1cm4gdzNjX3NsaWR5LmNhbmNlbChldmVudCk7CiAgICB9CgogICAgaWYgKGtleSA9PSAzOCAmJiB0aGlzLnByZXZpb3VzKQogICAgewogICAgICB0aGlzLnByZXZpb3VzLmZvY3VzKCk7CiAgICAgIHJldHVybiB3M2Nfc2xpZHkuY2FuY2VsKGV2ZW50KTsKICAgIH0KCiAgICByZXR1cm4gdHJ1ZTsKICB9LAoKICB0b3VjaHN0YXJ0OiBmdW5jdGlvbiAoZSkKICB7CiAgICAvLyBhIGRvdWJsZSB0b3VjaCBvZnRlbiBzdGFydHMgd2l0aCBhCiAgICAvLyBzaW5nbGUgdG91Y2ggZHVlIHRvIGZpbmdlcnMgdG91Y2hpbmcKICAgIC8vIGRvd24gYXQgc2xpZ2h0bHkgZGlmZmVyZW50IHRpbWVzCiAgICAvLyB0aHVzIGF2b2lkIGNhbGxpbmcgcHJldmVudERlZmF1bHQgaGVyZQogICAgdGhpcy5wcmV2X3RhcCA9IHRoaXMubGFzdF90YXA7CiAgICB0aGlzLmxhc3RfdGFwID0gKG5ldyBEYXRlKS5nZXRUaW1lKCk7CgogICAgdmFyIHRhcF9kZWxheSA9IHRoaXMubGFzdF90YXAgLSB0aGlzLnByZXZfdGFwOwoKICAgIGlmICh0YXBfZGVsYXkgPD0gMjAwKQogICAgewogICAgICAvLyBkb3VibGUgdGFwCiAgICB9CgogICAgdmFyIHRvdWNoID0gZS50b3VjaGVzWzBdOwoKICAgIHRoaXMucGFnZVggPSB0b3VjaC5wYWdlWDsKICAgIHRoaXMucGFnZVkgPSB0b3VjaC5wYWdlWTsKICAgIHRoaXMuc2NyZWVuWCA9IHRvdWNoLnNjcmVlblg7CiAgICB0aGlzLnNjcmVlblkgPSB0b3VjaC5zY3JlZW5ZOwogICAgdGhpcy5jbGllbnRYID0gdG91Y2guY2xpZW50WDsKICAgIHRoaXMuY2xpZW50WSA9IHRvdWNoLmNsaWVudFk7CgogICAgdGhpcy5kZWx0YV94ID0gdGhpcy5kZWx0YV95ID0gMDsKICB9LAoKICB0b3VjaG1vdmU6IGZ1bmN0aW9uIChlKQogIHsKICAgIC8vIG92ZXJyaWRlIG5hdGl2ZSBnZXN0dXJlcyBmb3Igc2luZ2xlIHRvdWNoCiAgICBpZiAoZS50b3VjaGVzLmxlbmd0aCA+IDEpCiAgICAgIHJldHVybjsKCiAgICBlLnByZXZlbnREZWZhdWx0KCk7CiAgICB2YXIgdG91Y2ggPSBlLnRvdWNoZXNbMF07CiAgICB0aGlzLmRlbHRhX3ggPSB0b3VjaC5wYWdlWCAtIHRoaXMucGFnZVg7CiAgICB0aGlzLmRlbHRhX3kgPSB0b3VjaC5wYWdlWSAtIHRoaXMucGFnZVk7CiAgfSwKCiAgdG91Y2hlbmQ6IGZ1bmN0aW9uIChlKQogIHsKICAgIC8vIGRlZmF1bHQgYmVoYXZpb3IgZm9yIG11bHRpLXRvdWNoCiAgICBpZiAoZS50b3VjaGVzLmxlbmd0aCA+IDEpCiAgICAgIHJldHVybjsKCiAgICB2YXIgZGVsYXkgPSAobmV3IERhdGUpLmdldFRpbWUoKSAtIHRoaXMubGFzdF90YXA7CiAgICB2YXIgZHggPSB0aGlzLmRlbHRhX3g7CiAgICB2YXIgZHkgPSB0aGlzLmRlbHRhX3k7CiAgICB2YXIgYWJzX2R4ID0gTWF0aC5hYnMoZHgpOwogICAgdmFyIGFic19keSA9IE1hdGguYWJzKGR5KTsKCiAgICBpZiAoZGVsYXkgPCA1MDAgJiYgKGFic19keCA+IDEwMCB8fCBhYnNfZHkgPiAxMDApKQogICAgewogICAgICBpZiAoYWJzX2R4ID4gMC41ICogYWJzX2R5KQogICAgICB7CiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpOwoKICAgICAgICBpZiAoZHggPCAwKQogICAgICAgICAgdzNjX3NsaWR5Lm5leHRfc2xpZGUodHJ1ZSk7CiAgICAgICAgZWxzZQogICAgICAgICAgdzNjX3NsaWR5LnByZXZpb3VzX3NsaWRlKHRydWUpOwogICAgICB9CiAgICAgIGVsc2UgaWYgKGFic19keSA+IDIgKiBhYnNfZHgpCiAgICAgIHsKICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgdzNjX3NsaWR5LnRvZ2dsZV90YWJsZV9vZl9jb250ZW50cygpOwogICAgICB9CiAgICB9CiAgfSwKCiAgLy8gIyMjIE9CU09MRVRFICMjIwogIGJlZm9yZV9wcmludDogZnVuY3Rpb24gKCkgewogICAgdGhpcy5zaG93X2FsbF9zbGlkZXMoKTsKICAgIHRoaXMuaGlkZV90b29sYmFyKCk7CiAgICBhbGVydCgiYmVmb3JlIHByaW50Iik7CiAgfSwKCiAgLy8gIyMjIE9CU09MRVRFICMjIwogIGFmdGVyX3ByaW50OiBmdW5jdGlvbiAoKSB7CiAgICBpZiAoIXRoaXMudmlld19hbGwpCiAgICB7CiAgICAgIHRoaXMuc2luZ2xlX3NsaWRlX3ZpZXcoKTsKICAgICAgdGhpcy5zaG93X3Rvb2xiYXIoKTsKICAgIH0KICAgIGFsZXJ0KCJhZnRlciBwcmludCIpOwogIH0sCgogIC8vICMjIyBPQlNPTEVURSAjIyMKICBwcmludF9zbGlkZXM6IGZ1bmN0aW9uICgpIHsKICAgIHRoaXMuYmVmb3JlX3ByaW50KCk7CiAgICB3aW5kb3cucHJpbnQoKTsKICAgIHRoaXMuYWZ0ZXJfcHJpbnQoKTsKICB9LAoKICAvLyAjIyMgT0JTT0xFVEUgPz8gIyMjCiAgdG9nZ2xlX3ZpZXc6IGZ1bmN0aW9uICgpIHsKICAgIGlmICh0aGlzLnZpZXdfYWxsKQogICAgewogICAgICB0aGlzLnNpbmdsZV9zbGlkZV92aWV3KCk7CiAgICAgIHRoaXMuc2hvd190b29sYmFyKCk7CiAgICAgIHRoaXMudmlld19hbGwgPSAwOwogICAgfQogICAgZWxzZQogICAgewogICAgICB0aGlzLnNob3dfYWxsX3NsaWRlcygpOwogICAgICB0aGlzLmhpZGVfdG9vbGJhcigpOwogICAgICB0aGlzLnZpZXdfYWxsID0gMTsKICAgIH0KICB9LAoKICAvLyBwcmVwYXJlIGZvciBwcmludGluZyAgIyMjIE9CU09MRVRFICMjIwogIHNob3dfYWxsX3NsaWRlczogZnVuY3Rpb24gKCkgewogICAgdGhpcy5yZW1vdmVfY2xhc3MoZG9jdW1lbnQuYm9keSwgInNpbmdsZV9zbGlkZSIpOwogICAgdGhpcy5zZXRfdmlzaWJpbGl0eV9hbGxfaW5jcmVtZW50YWwoInZpc2libGUiKTsKICB9LAoKICAvLyByZXN0b3JlIGFmdGVyIHByaW50aW5nICAjIyMgT0JTT0xFVEUgIyMjCiAgc2luZ2xlX3NsaWRlX3ZpZXc6IGZ1bmN0aW9uICgpIHsKICAgIHRoaXMuYWRkX2NsYXNzKGRvY3VtZW50LmJvZHksICJzaW5nbGVfc2xpZGUiKTsKICAgIHRoaXMuc2V0X3Zpc2liaWxpdHlfYWxsX2luY3JlbWVudGFsKCJ2aXNpYmxlIik7CiAgICB0aGlzLmxhc3Rfc2hvd24gPSB0aGlzLnByZXZpb3VzX2luY3JlbWVudGFsX2l0ZW0obnVsbCk7CiAgfSwKCiAgLy8gc3VwcHJlc3MgSUUncyBpbWFnZSB0b29sYmFyIHBvcCB1cAogIGhpZGVfaW1hZ2VfdG9vbGJhcjogZnVuY3Rpb24gKCkgewogICAgaWYgKCF0aGlzLm5zX3BvcykKICAgIHsKICAgICAgdmFyIGltYWdlcyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJJTUciKTsKCiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaW1hZ2VzLmxlbmd0aDsgKytpKQogICAgICAgIGltYWdlc1tpXS5zZXRBdHRyaWJ1dGUoImdhbGxlcnlpbWciLCAibm8iKTsKICAgIH0KICB9LAoKICB1bmxvYWRlZDogZnVuY3Rpb24gKGUpIHsKICAgIC8vYWxlcnQoInVubG9hZGVkIik7CiAgfSwKCiAgLy8gU2FmYXJpIGFuZCBLb25xdWVyb3IgZG9uJ3QgeWV0IHN1cHBvcnQgZ2V0Q29tcHV0ZWRTdHlsZSgpCiAgLy8gYW5kIHRoZXkgYWx3YXlzIHJlbG9hZCBwYWdlIHdoZW4gbG9jYXRpb24uaHJlZiBpcyB1cGRhdGVkCiAgaXNfS0hUTUw6IGZ1bmN0aW9uICgpIHsKICAgIHZhciBhZ2VudCA9IG5hdmlnYXRvci51c2VyQWdlbnQ7CiAgICByZXR1cm4gKGFnZW50LmluZGV4T2YoIktIVE1MIikgPj0gMCA/IHRydWUgOiBmYWxzZSk7CiAgfSwKCiAgLy8gZmluZCBzbGlkZSBuYW1lIGZyb20gZmlyc3QgaDEgZWxlbWVudAogIC8vIGRlZmF1bHQgdG8gZG9jdW1lbnQgdGl0bGUgKyBzbGlkZSBudW1iZXIKICBzbGlkZV9uYW1lOiBmdW5jdGlvbiAoaW5kZXgpIHsKICAgIHZhciBuYW1lID0gbnVsbDsKICAgIHZhciBzbGlkZSA9IHRoaXMuc2xpZGVzW2luZGV4XTsKCiAgICB2YXIgaGVhZGluZyA9IHRoaXMuZmluZF9oZWFkaW5nKHNsaWRlKTsKCiAgICBpZiAoaGVhZGluZykKICAgICAgbmFtZSA9IHRoaXMuZXh0cmFjdF90ZXh0KGhlYWRpbmcpOwoKICAgIGlmICghbmFtZSkKICAgICAgbmFtZSA9IHRoaXMudGl0bGUgKyAiKCIgKyAoaW5kZXggKyAxKSArICIpIjsKCiAgICBuYW1lLnJlcGxhY2UoL1wmL2csICImYW1wOyIpOwogICAgbmFtZS5yZXBsYWNlKC9cPC9nLCAiJmx0OyIpOwogICAgbmFtZS5yZXBsYWNlKC9cPi9nLCAiJmd0OyIpOwoKICAgIHJldHVybiBuYW1lOwogIH0sCgogIC8vIGZpbmQgZmlyc3QgaDEgZWxlbWVudCBpbiBET00gdHJlZQogIGZpbmRfaGVhZGluZzogZnVuY3Rpb24gKG5vZGUpIHsKICAgIGlmICghbm9kZSB8fCBub2RlLm5vZGVUeXBlICE9IDEpCiAgICAgIHJldHVybiBudWxsOwoKICAgIGlmIChub2RlLm5vZGVOYW1lID09ICJIMSIgfHwgbm9kZS5ub2RlTmFtZSA9PSAiaDEiKQogICAgICByZXR1cm4gbm9kZTsKCiAgICB2YXIgY2hpbGQgPSBub2RlLmZpcnN0Q2hpbGQ7CgogICAgd2hpbGUgKGNoaWxkKQogICAgewogICAgICBub2RlID0gdGhpcy5maW5kX2hlYWRpbmcoY2hpbGQpOwoKICAgICAgaWYgKG5vZGUpCiAgICAgICAgcmV0dXJuIG5vZGU7CgogICAgICBjaGlsZCA9IGNoaWxkLm5leHRTaWJsaW5nOwogICAgfQoKICAgIHJldHVybiBudWxsOwogIH0sCgogIC8vIHJlY3Vyc2l2ZWx5IGV4dHJhY3QgdGV4dCBmcm9tIERPTSB0cmVlCiAgZXh0cmFjdF90ZXh0OiBmdW5jdGlvbiAobm9kZSkgewogICAgaWYgKCFub2RlKQogICAgICByZXR1cm4gIiI7CgogICAgLy8gdGV4dCBub2RlcwogICAgaWYgKG5vZGUubm9kZVR5cGUgPT0gMykKICAgICAgcmV0dXJuIG5vZGUubm9kZVZhbHVlOwoKICAgIC8vIGVsZW1lbnRzCiAgICBpZiAobm9kZS5ub2RlVHlwZSA9PSAxKQogICAgewogICAgICBub2RlID0gbm9kZS5maXJzdENoaWxkOwogICAgICB2YXIgdGV4dCA9ICIiOwoKICAgICAgd2hpbGUgKG5vZGUpCiAgICAgIHsKICAgICAgICB0ZXh0ID0gdGV4dCArIHRoaXMuZXh0cmFjdF90ZXh0KG5vZGUpOwogICAgICAgIG5vZGUgPSBub2RlLm5leHRTaWJsaW5nOwogICAgICB9CgogICAgICByZXR1cm4gdGV4dDsKICAgIH0KCiAgICByZXR1cm4gIiI7CiAgfSwKCiAgLy8gZmluZCBjb3B5cmlnaHQgdGV4dCBmcm9tIG1ldGEgZWxlbWVudAogIGZpbmRfY29weXJpZ2h0OiBmdW5jdGlvbiAoKSB7CiAgICB2YXIgbmFtZSwgY29udGVudDsKICAgIHZhciBtZXRhID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIm1ldGEiKTsKCiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1ldGEubGVuZ3RoOyArK2kpCiAgICB7CiAgICAgIG5hbWUgPSBtZXRhW2ldLmdldEF0dHJpYnV0ZSgibmFtZSIpOwogICAgICBjb250ZW50ID0gbWV0YVtpXS5nZXRBdHRyaWJ1dGUoImNvbnRlbnQiKTsKCiAgICAgIGlmIChuYW1lID09ICJjb3B5cmlnaHQiKQogICAgICAgIHJldHVybiBjb250ZW50OwogICAgfQoKICAgIHJldHVybiBudWxsOwogIH0sCgogIGZpbmRfc2l6ZV9hZGp1c3Q6IGZ1bmN0aW9uICgpIHsKICAgIHZhciBuYW1lLCBjb250ZW50LCBvZmZzZXQ7CiAgICB2YXIgbWV0YSA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJtZXRhIik7CgogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXRhLmxlbmd0aDsgKytpKQogICAgewogICAgICBuYW1lID0gbWV0YVtpXS5nZXRBdHRyaWJ1dGUoIm5hbWUiKTsKICAgICAgY29udGVudCA9IG1ldGFbaV0uZ2V0QXR0cmlidXRlKCJjb250ZW50Iik7CgogICAgICBpZiAobmFtZSA9PSAiZm9udC1zaXplLWFkanVzdG1lbnQiKQogICAgICAgIHJldHVybiAxICogY29udGVudDsKICAgIH0KCiAgICByZXR1cm4gMTsKICB9LAoKICAvLyA8bWV0YSBuYW1lPSJkdXJhdGlvbiIgY29udGVudD0iMjAiIC8+ICBmb3IgMjAgbWludXRlcwogIGZpbmRfZHVyYXRpb246IGZ1bmN0aW9uICgpIHsKICAgIHZhciBuYW1lLCBjb250ZW50LCBvZmZzZXQ7CiAgICB2YXIgbWV0YSA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJtZXRhIik7CgogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXRhLmxlbmd0aDsgKytpKQogICAgewogICAgICBuYW1lID0gbWV0YVtpXS5nZXRBdHRyaWJ1dGUoIm5hbWUiKTsKICAgICAgY29udGVudCA9IG1ldGFbaV0uZ2V0QXR0cmlidXRlKCJjb250ZW50Iik7CgogICAgICBpZiAobmFtZSA9PSAiZHVyYXRpb24iKQogICAgICAgIHJldHVybiA2MDAwMCAqIGNvbnRlbnQ7CiAgICB9CgogICAgcmV0dXJuIG51bGw7CiAgfSwKCiAgcmVwbGFjZV9ieV9ub25fYnJlYWtpbmdfc3BhY2U6IGZ1bmN0aW9uIChzdHIpIHsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKQogICAgICBzdHJbaV0gPSAxNjA7CiAgfSwKCiAgLy8gIyMjIENIRUNLIE1FICMjIyBpcyB1c2Ugb2YgImxpIiBva2F5IGZvciB0ZXh0L2h0bWw/CiAgLy8gZm9yIFhIVE1MIGRvIHdlIGFsc28gbmVlZCB0byBzcGVjaWZ5IG5hbWVzcGFjZT8KICBpbml0X291dGxpbmVyOiBmdW5jdGlvbiAoKSB7CiAgICB2YXIgaXRlbXMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgibGkiKTsKCiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGl0ZW1zLmxlbmd0aDsgKytpKQogICAgewogICAgICB2YXIgdGFyZ2V0ID0gaXRlbXNbaV07CgogICAgICBpZiAoIXRoaXMuaGFzX2NsYXNzKHRhcmdldC5wYXJlbnROb2RlLCAib3V0bGluZSIpKQogICAgICAgIGNvbnRpbnVlOwoKICAgICAgdGFyZ2V0Lm9uY2xpY2sgPSB0aGlzLm91dGxpbmVfY2xpY2s7Ci8qICMjIyBtb3JlIHdvcmsgbmVlZGVkIGZvciBJRTYKICAgICAgaWYgKCF0aGlzLm5zX3BvcykKICAgICAgewogICAgICAgIHRhcmdldC5vbm1vdXNlb3ZlciA9IHRoaXMuaG92ZXJfb3V0bGluZTsKICAgICAgICB0YXJnZXQub25tb3VzZW91dCA9IHRoaXMudW5ob3Zlcl9vdXRsaW5lOwogICAgICB9CiovCiAgICAgIGlmICh0aGlzLmZvbGRhYmxlKHRhcmdldCkpCiAgICAgIHsKICAgICAgICB0YXJnZXQuZm9sZGFibGUgPSB0cnVlOwogICAgICAgIHRhcmdldC5vbmZvY3VzID0gZnVuY3Rpb24gKCkge3czY19zbGlkeS5vdXRsaW5lID0gdGhpczt9OwogICAgICAgIHRhcmdldC5vbmJsdXIgPSBmdW5jdGlvbiAoKSB7dzNjX3NsaWR5Lm91dGxpbmUgPSBudWxsO307CgogICAgICAgIGlmICghdGFyZ2V0LmdldEF0dHJpYnV0ZSgidGFiaW5kZXgiKSkKICAgICAgICAgIHRhcmdldC5zZXRBdHRyaWJ1dGUoInRhYmluZGV4IiwgIjAiKTsKCiAgICAgICAgaWYgKHRoaXMuaGFzX2NsYXNzKHRhcmdldCwgImV4cGFuZCIpKQogICAgICAgICAgdGhpcy51bmZvbGQodGFyZ2V0KTsKICAgICAgICBlbHNlCiAgICAgICAgICB0aGlzLmZvbGQodGFyZ2V0KTsKICAgICAgfQogICAgICBlbHNlCiAgICAgIHsKICAgICAgICB0aGlzLmFkZF9jbGFzcyh0YXJnZXQsICJub2ZvbGQiKTsKICAgICAgICB0YXJnZXQudmlzaWJsZSA9IHRydWU7CiAgICAgICAgdGFyZ2V0LmZvbGRhYmxlID0gZmFsc2U7CiAgICAgIH0KICAgIH0KICB9LAoKICBmb2xkYWJsZTogZnVuY3Rpb24gKGl0ZW0pIHsKICAgIGlmICghaXRlbSB8fCBpdGVtLm5vZGVUeXBlICE9IDEpCiAgICAgIHJldHVybiBmYWxzZTsKCiAgICB2YXIgbm9kZSA9IGl0ZW0uZmlyc3RDaGlsZDsKCiAgICB3aGlsZSAobm9kZSkKICAgIHsKICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT0gMSAmJiB0aGlzLmlzX2Jsb2NrKG5vZGUpKQogICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgbm9kZSA9IG5vZGUubmV4dFNpYmxpbmc7CiAgICB9CgogICAgcmV0dXJuIGZhbHNlOwogIH0sCgogIC8vICMjIyBDSEVDSyBNRSAjIyMgc3dpdGNoIHRvIGFkZC9yZW1vdmUgImhpZGRlbiIgY2xhc3MKICBmb2xkOiBmdW5jdGlvbiAoaXRlbSkgewogICAgaWYgKGl0ZW0pCiAgICB7CiAgICAgIHRoaXMucmVtb3ZlX2NsYXNzKGl0ZW0sICJ1bmZvbGRlZCIpOwogICAgICB0aGlzLmFkZF9jbGFzcyhpdGVtLCAiZm9sZGVkIik7CiAgICB9CgogICAgdmFyIG5vZGUgPSBpdGVtID8gaXRlbS5maXJzdENoaWxkIDogbnVsbDsKCiAgICB3aGlsZSAobm9kZSkKICAgIHsKICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT0gMSAmJiB0aGlzLmlzX2Jsb2NrKG5vZGUpKSAvLyBlbGVtZW50CiAgICAgIHsKICAgICAgICAgdzNjX3NsaWR5LmFkZF9jbGFzcyhub2RlLCAiaGlkZGVuIik7CiAgICAgIH0KCiAgICAgIG5vZGUgPSBub2RlLm5leHRTaWJsaW5nOwogICAgfQoKICAgIGl0ZW0udmlzaWJsZSA9IGZhbHNlOwogIH0sCgogIC8vICMjIyBDSEVDSyBNRSAjIyMgc3dpdGNoIHRvIGFkZC9yZW1vdmUgImhpZGRlbiIgY2xhc3MKICB1bmZvbGQ6IGZ1bmN0aW9uIChpdGVtKSB7CiAgICBpZiAoaXRlbSkKICAgIHsKICAgICAgdGhpcy5hZGRfY2xhc3MoaXRlbSwgInVuZm9sZGVkIik7CiAgICAgIHRoaXMucmVtb3ZlX2NsYXNzKGl0ZW0sICJmb2xkZWQiKTsKICAgIH0KCiAgICB2YXIgbm9kZSA9IGl0ZW0gPyBpdGVtLmZpcnN0Q2hpbGQgOiBudWxsOwoKICAgIHdoaWxlIChub2RlKQogICAgewogICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PSAxICYmIHRoaXMuaXNfYmxvY2sobm9kZSkpIC8vIGVsZW1lbnQKICAgICAgewogICAgICAgIHczY19zbGlkeS5yZW1vdmVfY2xhc3Mobm9kZSwgImhpZGRlbiIpOwogICAgICB9CgogICAgICBub2RlID0gbm9kZS5uZXh0U2libGluZzsKICAgIH0KCiAgICBpdGVtLnZpc2libGUgPSB0cnVlOwogIH0sCgogIG91dGxpbmVfY2xpY2s6IGZ1bmN0aW9uIChlKSB7CiAgICBpZiAoIWUpCiAgICAgIGUgPSB3aW5kb3cuZXZlbnQ7CgogICAgdmFyIHJpZ2h0Y2xpY2sgPSBmYWxzZTsKICAgIHZhciB0YXJnZXQgPSB3M2Nfc2xpZHkuZ2V0X3RhcmdldChlKTsKCiAgICB3aGlsZSAodGFyZ2V0ICYmIHRhcmdldC52aXNpYmxlID09IHVuZGVmaW5lZCkKICAgICAgdGFyZ2V0ID0gdGFyZ2V0LnBhcmVudE5vZGU7CgogICAgaWYgKCF0YXJnZXQpCiAgICAgIHJldHVybiB0cnVlOwoKICAgIGlmIChlLndoaWNoKQogICAgICByaWdodGNsaWNrID0gKGUud2hpY2ggPT0gMyk7CiAgICBlbHNlIGlmIChlLmJ1dHRvbikKICAgICAgcmlnaHRjbGljayA9IChlLmJ1dHRvbiA9PSAyKTsKCiAgICBpZiAoIXJpZ2h0Y2xpY2sgJiYgdGFyZ2V0LnZpc2libGUgIT0gdW5kZWZpbmVkKQogICAgewogICAgICBpZiAodGFyZ2V0LmZvbGRhYmxlKQogICAgICB7CiAgICAgICAgaWYgKHRhcmdldC52aXNpYmxlKQogICAgICAgICAgdzNjX3NsaWR5LmZvbGQodGFyZ2V0KTsKICAgICAgICBlbHNlCiAgICAgICAgICB3M2Nfc2xpZHkudW5mb2xkKHRhcmdldCk7CiAgICAgIH0KCiAgICAgIHczY19zbGlkeS5zdG9wX3Byb3BhZ2F0aW9uKGUpOwogICAgICBlLmNhbmNlbCA9IHRydWU7CiAgICAgIGUucmV0dXJuVmFsdWUgPSBmYWxzZTsKICAgIH0KCiAgICByZXR1cm4gZmFsc2U7CiAgfSwKCiAgYWRkX2luaXRpYWxfcHJvbXB0OiBmdW5jdGlvbiAoKSB7CiAgICB2YXIgcHJvbXB0ID0gdGhpcy5jcmVhdGVfZWxlbWVudCgiZGl2Iik7CiAgICBwcm9tcHQuc2V0QXR0cmlidXRlKCJjbGFzcyIsICJpbml0aWFsX3Byb21wdCIpOwoKICAgIHZhciBwMSA9IHRoaXMuY3JlYXRlX2VsZW1lbnQoInAiKTsKICAgIHByb21wdC5hcHBlbmRDaGlsZChwMSk7CiAgICBwMS5zZXRBdHRyaWJ1dGUoImNsYXNzIiwgImhlbHAiKTsKCiAgICBpZiAodGhpcy5rZXlib2FyZGxlc3MpCiAgICAgIHAxLmlubmVySFRNTCA9ICJzd2lwZSBsZWZ0IHRvIG1vdmUgdG8gbmV4dCBzbGlkZSI7CiAgICBlbHNlCiAgICAgIHAxLmlubmVySFRNTCA9ICJTcGFjZSwgUmlnaHQgQXJyb3cgb3Igc3dpcGUgbGVmdCB0byBtb3ZlIHRvICIgKwogICAgICAgICAgICAgICAgICAgICAibmV4dCBzbGlkZSwgY2xpY2sgaGVscCBiZWxvdyBmb3IgbW9yZSBkZXRhaWxzIjsKCiAgICB0aGlzLmFkZF9saXN0ZW5lcihwcm9tcHQsICJjbGljayIsIGZ1bmN0aW9uIChlKSB7CiAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQocHJvbXB0KTsKICAgICAgdzNjX3NsaWR5LnN0b3BfcHJvcGFnYXRpb24oZSk7CiAgICAKICAgICAgaWYgKGUuY2FuY2VsICE9IHVuZGVmaW5lZCkKICAgICAgICBlLmNhbmNlbCA9IHRydWU7CiAgICAgIAogICAgICBpZiAoZS5yZXR1cm5WYWx1ZSAhPSB1bmRlZmluZWQpCiAgICAgICAgZS5yZXR1cm5WYWx1ZSA9IGZhbHNlOwogICAgICAKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfSk7CgogICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChwcm9tcHQpOwogICAgdGhpcy5pbml0aWFsX3Byb21wdCA9IHByb21wdDsKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7ZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChwcm9tcHQpO30sIDUwMDApOwogIH0sCgogIGFkZF90b29sYmFyOiBmdW5jdGlvbiAoKSB7CiAgICB2YXIgY291bnRlciwgcGFnZTsKCiAgICAgdGhpcy50b29sYmFyID0gdGhpcy5jcmVhdGVfZWxlbWVudCgiZGl2Iik7CiAgICAgdGhpcy50b29sYmFyLnNldEF0dHJpYnV0ZSgiY2xhc3MiLCAidG9vbGJhciIpOwoKICAgICAvLyBhIHJlYXNvbmFibHkgYmVoYXZlZCBicm93c2VyCiAgICAgaWYgKHRoaXMubnNfcG9zIHx8ICF0aGlzLmllNikKICAgICB7CiAgICAgICB2YXIgcmlnaHQgPSB0aGlzLmNyZWF0ZV9lbGVtZW50KCJkaXYiKTsKICAgICAgIHJpZ2h0LnNldEF0dHJpYnV0ZSgic3R5bGUiLCAiZmxvYXQ6IHJpZ2h0OyB0ZXh0LWFsaWduOiByaWdodCIpOwoKICAgICAgIGNvdW50ZXIgPSB0aGlzLmNyZWF0ZV9lbGVtZW50KCJzcGFuIikKICAgICAgIGNvdW50ZXIuaW5uZXJIVE1MID0gdGhpcy5sb2NhbGl6ZSgic2xpZGUiKSArICIgbi9tIjsKICAgICAgIHJpZ2h0LmFwcGVuZENoaWxkKGNvdW50ZXIpOwogICAgICAgdGhpcy50b29sYmFyLmFwcGVuZENoaWxkKHJpZ2h0KTsKCiAgICAgICB2YXIgbGVmdCA9IHRoaXMuY3JlYXRlX2VsZW1lbnQoImRpdiIpOwogICAgICAgbGVmdC5zZXRBdHRyaWJ1dGUoInN0eWxlIiwgInRleHQtYWxpZ246IGxlZnQiKTsKCiAgICAgICAvLyBnbG9iYWwgZW5kIG9mIHNsaWRlIGluZGljYXRvcgogICAgICAgdGhpcy5lb3MgPSB0aGlzLmNyZWF0ZV9lbGVtZW50KCJzcGFuIik7CiAgICAgICB0aGlzLmVvcy5pbm5lckhUTUwgPSAiKiAiOwogICAgICAgbGVmdC5hcHBlbmRDaGlsZCh0aGlzLmVvcyk7CgogICAgICAgdmFyIGhlbHAgPSB0aGlzLmNyZWF0ZV9lbGVtZW50KCJhIik7CiAgICAgICBoZWxwLnNldEF0dHJpYnV0ZSgiaHJlZiIsIHRoaXMuaGVscF9wYWdlKTsKICAgICAgIGhlbHAuc2V0QXR0cmlidXRlKCJ0aXRsZSIsIHRoaXMubG9jYWxpemUodGhpcy5oZWxwX3RleHQpKTsKICAgICAgIGhlbHAuaW5uZXJIVE1MID0gdGhpcy5sb2NhbGl6ZSgiaGVscD8iKTsKICAgICAgIGxlZnQuYXBwZW5kQ2hpbGQoaGVscCk7CiAgICAgICBoZWxwLnN0eWxlLmRpc3BsYXk9Im5vbmUiOyAKICAgICAgIHRoaXMuaGVscF9hbmNob3IgPSBoZWxwOyAgLy8gc2F2ZSBmb3IgZm9jdXMgaGFjawoKICAgICAgIHZhciBnYXAxID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoIiAiKTsKICAgICAgIGxlZnQuYXBwZW5kQ2hpbGQoZ2FwMSk7CgogICAgICAgdmFyIGNvbnRlbnRzID0gdGhpcy5jcmVhdGVfZWxlbWVudCgiYSIpOwogICAgICAgY29udGVudHMuc2V0QXR0cmlidXRlKCJocmVmIiwgImphdmFzY3JpcHQ6dzNjX3NsaWR5LnRvZ2dsZV90YWJsZV9vZl9jb250ZW50cygpIik7CiAgICAgICBjb250ZW50cy5zZXRBdHRyaWJ1dGUoInRpdGxlIiwgdGhpcy5sb2NhbGl6ZSgidGFibGUgb2YgY29udGVudHMiKSk7CiAgICAgICBjb250ZW50cy5pbm5lckhUTUwgPSB0aGlzLmxvY2FsaXplKCJDb250ZW50cyIpOwogICAgICAgbGVmdC5hcHBlbmRDaGlsZChjb250ZW50cyk7CgogICAgICAgdmFyIGdhcDIgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgiICIpOwogICAgICAgbGVmdC5hcHBlbmRDaGlsZChnYXAyKTsKCiAgICAgICB2YXIgY29weXJpZ2h0ID0gdGhpcy5maW5kX2NvcHlyaWdodCgpOwoKICAgICAgIGlmIChjb3B5cmlnaHQpCiAgICAgICB7CiAgICAgICAgIHZhciBzcGFuID0gdGhpcy5jcmVhdGVfZWxlbWVudCgic3BhbiIpOwogICAgICAgICBzcGFuLmNsYXNzTmFtZSA9ICJjb3B5cmlnaHQiOwogICAgICAgICBzcGFuLmlubmVySFRNTCA9IGNvcHlyaWdodDsKICAgICAgICAgbGVmdC5hcHBlbmRDaGlsZChzcGFuKTsKICAgICAgIH0KCiAgICAgICB0aGlzLnRvb2xiYXIuc2V0QXR0cmlidXRlKCJ0YWJpbmRleCIsICIwIik7CiAgICAgICB0aGlzLnRvb2xiYXIuYXBwZW5kQ2hpbGQobGVmdCk7CiAgICAgfQogICAgIGVsc2UgLy8gSUU2IHNvIG5lZWQgdG8gd29yayBhcm91bmQgaXRzIHBvb3IgQ1NTIHN1cHBvcnQKICAgICB7CiAgICAgICB0aGlzLnRvb2xiYXIuc3R5bGUucG9zaXRpb24gPSAodGhpcy5pZTcgPyAiZml4ZWQiIDogImFic29sdXRlIik7CiAgICAgICB0aGlzLnRvb2xiYXIuc3R5bGUuekluZGV4ID0gIjIwMCI7CiAgICAgICB0aGlzLnRvb2xiYXIuc3R5bGUud2lkdGggPSAiOTkuOSUiOwogICAgICAgdGhpcy50b29sYmFyLnN0eWxlLmhlaWdodCA9ICIxLjJlbSI7CiAgICAgICB0aGlzLnRvb2xiYXIuc3R5bGUudG9wID0gImF1dG8iOwogICAgICAgdGhpcy50b29sYmFyLnN0eWxlLmJvdHRvbSA9ICIwIjsKICAgICAgIHRoaXMudG9vbGJhci5zdHlsZS5sZWZ0ID0gIjAiOwogICAgICAgdGhpcy50b29sYmFyLnN0eWxlLnJpZ2h0ID0gIjAiOwogICAgICAgdGhpcy50b29sYmFyLnN0eWxlLnRleHRBbGlnbiA9ICJsZWZ0IjsKICAgICAgIHRoaXMudG9vbGJhci5zdHlsZS5mb250U2l6ZSA9ICI2MCUiOwogICAgICAgdGhpcy50b29sYmFyLnN0eWxlLmNvbG9yID0gInJlZCI7CiAgICAgICB0aGlzLnRvb2xiYXIuYm9yZGVyV2lkdGggPSAwOwogICAgICAgdGhpcy50b29sYmFyLmNsYXNzTmFtZSA9ICJ0b29sYmFyIjsKICAgICAgIHRoaXMudG9vbGJhci5zdHlsZS5iYWNrZ3JvdW5kID0gInJnYigyNDAsMjQwLDI0MCkiOwoKICAgICAgIC8vIHdvdWxkIGxpa2UgdG8gaGF2ZSBoZWxwIHRleHQgbGVmdCBhbGlnbmVkCiAgICAgICAvLyBhbmQgcGFnZSBjb3VudGVyIHJpZ2h0IGFsaWduZWQsIGZsb2F0aW5nCiAgICAgICAvLyBkaXYncyBkb24ndCB3b3JrLCBzbyBpbnN0ZWFkIHVzZSBuZXN0ZWQKICAgICAgIC8vIGFic29sdXRlbHkgcG9zaXRpb25lZCBkaXYncy4KCiAgICAgICB2YXIgc3AgPSB0aGlzLmNyZWF0ZV9lbGVtZW50KCJzcGFuIik7CiAgICAgICBzcC5pbm5lckhUTUwgPSAiJm5ic3A7Jm5ic3A7KiZuYnNwOyI7CiAgICAgICB0aGlzLnRvb2xiYXIuYXBwZW5kQ2hpbGQoc3ApOwogICAgICAgdGhpcy5lb3MgPSBzcDsgIC8vIGVuZCBvZiBzbGlkZSBpbmRpY2F0b3IKCiAgICAgICB2YXIgaGVscCA9IHRoaXMuY3JlYXRlX2VsZW1lbnQoImEiKTsKICAgICAgIGhlbHAuc2V0QXR0cmlidXRlKCJocmVmIiwgdGhpcy5oZWxwX3BhZ2UpOwogICAgICAgaGVscC5zZXRBdHRyaWJ1dGUoInRpdGxlIiwgdGhpcy5sb2NhbGl6ZSh0aGlzLmhlbHBfdGV4dCkpOwogICAgICAgaGVscC5pbm5lckhUTUwgPSB0aGlzLmxvY2FsaXplKCJoZWxwPyIpOwogICAgICAgdGhpcy50b29sYmFyLmFwcGVuZENoaWxkKGhlbHApOwogICAgICAgdGhpcy5oZWxwX2FuY2hvciA9IGhlbHA7ICAvLyBzYXZlIGZvciBmb2N1cyBoYWNrCgogICAgICAgdmFyIGdhcDEgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgiICIpOwogICAgICAgdGhpcy50b29sYmFyLmFwcGVuZENoaWxkKGdhcDEpOwoKICAgICAgIHZhciBjb250ZW50cyA9IHRoaXMuY3JlYXRlX2VsZW1lbnQoImEiKTsKICAgICAgIGNvbnRlbnRzLnNldEF0dHJpYnV0ZSgiaHJlZiIsICJqYXZhc2NyaXB0OnRvZ2dsZVRhYmxlT2ZDb250ZW50cygpIik7CiAgICAgICBjb250ZW50cy5zZXRBdHRyaWJ1dGUoInRpdGxlIiwgdGhpcy5sb2NhbGl6ZSgidGFibGUgb2YgY29udGVudHMiLmxvY2FsaXplKSk7CiAgICAgICBjb250ZW50cy5pbm5lckhUTUwgPSB0aGlzLmxvY2FsaXplKCJjb250ZW50cz8iKTsKICAgICAgIHRoaXMudG9vbGJhci5hcHBlbmRDaGlsZChjb250ZW50cyk7CgogICAgICAgdmFyIGdhcDIgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgiICIpOwogICAgICAgdGhpcy50b29sYmFyLmFwcGVuZENoaWxkKGdhcDIpOwoKICAgICAgIHZhciBjb3B5cmlnaHQgPSB0aGlzLmZpbmRfY29weXJpZ2h0KCk7CgogICAgICAgaWYgKGNvcHlyaWdodCkKICAgICAgIHsKICAgICAgICAgdmFyIHNwYW4gPSB0aGlzLmNyZWF0ZV9lbGVtZW50KCJzcGFuIik7CiAgICAgICAgIHNwYW4uaW5uZXJIVE1MID0gY29weXJpZ2h0OwogICAgICAgICBzcGFuLnN0eWxlLmNvbG9yID0gImJsYWNrIjsKICAgICAgICAgc3Bhbi5zdHlsZS5tYXJnaW5MZWZ0ID0gIjAuNWVtIjsKICAgICAgICAgdGhpcy50b29sYmFyLmFwcGVuZENoaWxkKHNwYW4pOwogICAgICAgfQoKICAgICAgIGNvdW50ZXIgPSB0aGlzLmNyZWF0ZV9lbGVtZW50KCJkaXYiKQogICAgICAgY291bnRlci5zdHlsZS5wb3NpdGlvbiA9ICJhYnNvbHV0ZSI7CiAgICAgICBjb3VudGVyLnN0eWxlLndpZHRoID0gImF1dG8iOyAvLyIyMCUiOwogICAgICAgY291bnRlci5zdHlsZS5oZWlnaHQgPSAiMS4yZW0iOwogICAgICAgY291bnRlci5zdHlsZS50b3AgPSAiYXV0byI7CiAgICAgICBjb3VudGVyLnN0eWxlLmJvdHRvbSA9IDA7CiAgICAgICBjb3VudGVyLnN0eWxlLnJpZ2h0ID0gIjAiOwogICAgICAgY291bnRlci5zdHlsZS50ZXh0QWxpZ24gPSAicmlnaHQiOwogICAgICAgY291bnRlci5zdHlsZS5jb2xvciA9ICJyZWQiOwogICAgICAgY291bnRlci5zdHlsZS5iYWNrZ3JvdW5kID0gInJnYigyNDAsMjQwLDI0MCkiOwoKICAgICAgIGNvdW50ZXIuaW5uZXJIVE1MID0gdGhpcy5sb2NhbGl6ZSgic2xpZGUiKSArICIgbi9tIjsKICAgICAgIHRoaXMudG9vbGJhci5hcHBlbmRDaGlsZChjb3VudGVyKTsKICAgICB9CgogICAgIC8vIGVuc3VyZSB0aGF0IGNsaWNrIGlzbid0IHBhc3NlZCB0aHJvdWdoIHRvIHRoZSBwYWdlCiAgICAgdGhpcy50b29sYmFyLm9uY2xpY2sgPQogICAgICAgICBmdW5jdGlvbiAoZSkgewogICAgICAgICAgIGlmICghZSkKICAgICAgICAgICAgIGUgPSB3aW5kb3cuZXZlbnQ7CgogICAgICAgICAgIHZhciB0YXJnZXQgPSBlLnRhcmdldDsKCiAgICAgICAgICAgaWYgKCF0YXJnZXQgJiYgZS5zcmNFbGVtZW50KQogICAgICAgICAgICAgdGFyZ2V0ID0gZS5zcmNFbGVtZW50OwoKICAgICAgICAgICAvLyB3b3JrIGFyb3VuZCBTYWZhcmkgYnVnCiAgICAgICAgICAgaWYgKHRhcmdldCAmJiB0YXJnZXQubm9kZVR5cGUgPT0gMykKICAgICAgICAgICAgIHRhcmdldCA9IHRhcmdldC5wYXJlbnROb2RlOwoKICAgICAgICAgICB3M2Nfc2xpZHkuc3RvcF9wcm9wYWdhdGlvbihlKTsKCiAgICAgICAgICAgaWYgKHRhcmdldCAmJiB0YXJnZXQubm9kZU5hbWUudG9Mb3dlckNhc2UoKSAhPSAiYSIpCiAgICAgICAgICAgICB3M2Nfc2xpZHkubW91c2VfYnV0dG9uX2NsaWNrKGUpOwogICAgICAgICB9OwoKICAgICB0aGlzLnNsaWRlX251bWJlcl9lbGVtZW50ID0gY291bnRlcjsKICAgICB0aGlzLnNldF9lb3Nfc3RhdHVzKGZhbHNlKTsKICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMudG9vbGJhcik7CiAgfSwKCiAgLy8gd3lzaXd5ZyBlZGl0b3JzIG1ha2UgaXQgaGFyZCB0byB1c2UgZGl2IGVsZW1lbnRzCiAgLy8gZS5nLiBhbWF5YSBsb3NlcyB0aGUgZGl2IHdoZW4geW91IGNvcHkgYW5kIHBhc3RlCiAgLy8gdGhpcyBmdW5jdGlvbiB3cmFwcyBkaXYgZWxlbWVudHMgYXJvdW5kIGltcGxpY2l0CiAgLy8gc2xpZGVzIHdoaWNoIHN0YXJ0IHdpdGggYW4gaDEgZWxlbWVudCBhbmQgY29udGludWUKICAvLyB1cCB0byB0aGUgbmV4dCBoZWFkaW5nIG9yIGRpdiBlbGVtZW50CiAgd3JhcF9pbXBsaWNpdF9zbGlkZXM6IGZ1bmN0aW9uICgpIHsKICAgIHZhciBpLCBoZWFkaW5nLCBub2RlLCBuZXh0LCBkaXY7CiAgICB2YXIgaGVhZGluZ3MgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiaDEiKTsKCiAgICBpZiAoIWhlYWRpbmdzKQogICAgICByZXR1cm47CgogICAgZm9yIChpID0gMDsgaSA8IGhlYWRpbmdzLmxlbmd0aDsgKytpKQogICAgewogICAgICBoZWFkaW5nID0gaGVhZGluZ3NbaV07CgogICAgICBpZiAoaGVhZGluZy5wYXJlbnROb2RlICE9IGRvY3VtZW50LmJvZHkpCiAgICAgICAgY29udGludWU7CgogICAgICBub2RlID0gaGVhZGluZy5uZXh0U2libGluZzsKCiAgICAgIGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpOwogICAgICB0aGlzLmFkZF9jbGFzcyhkaXYsICJzbGlkZSIpOwogICAgICBkb2N1bWVudC5ib2R5LnJlcGxhY2VDaGlsZChkaXYsIGhlYWRpbmcpOwogICAgICBkaXYuYXBwZW5kQ2hpbGQoaGVhZGluZyk7CgogICAgICB3aGlsZSAobm9kZSkKICAgICAgewogICAgICAgIGlmIChub2RlLm5vZGVUeXBlID09IDEpIC8vIGFuIGVsZW1lbnQKICAgICAgICB7CiAgICAgICAgICAgaWYgKG5vZGUubm9kZU5hbWUgPT0gIkgxIiB8fCBub2RlLm5vZGVOYW1lID09ICJoMSIpCiAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgaWYgKG5vZGUubm9kZU5hbWUgPT0gIkRJViIgfHwgbm9kZS5ub2RlTmFtZSA9PSAiZGl2IikKICAgICAgICAgICB7CiAgICAgICAgICAgICBpZiAodGhpcy5oYXNfY2xhc3Mobm9kZSwgInNsaWRlIikpCiAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgIGlmICh0aGlzLmhhc19jbGFzcyhub2RlLCAiaGFuZG91dCIpKQogICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBuZXh0ID0gbm9kZS5uZXh0U2libGluZzsKICAgICAgICBub2RlID0gZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChub2RlKTsKICAgICAgICBkaXYuYXBwZW5kQ2hpbGQobm9kZSk7CiAgICAgICAgbm9kZSA9IG5leHQ7CiAgICAgIH0gCiAgICB9CiAgfSwKCiAgYXR0YWNoX3RvdWNoX2hhbmRlcnM6IGZ1bmN0aW9uKHNsaWRlcykKICB7CiAgICB2YXIgaSwgc2xpZGU7CgogICAgZm9yIChpID0gMDsgaSA8IHNsaWRlcy5sZW5ndGg7ICsraSkKICAgIHsKICAgICAgc2xpZGUgPSBzbGlkZXNbaV07CiAgICAgIHRoaXMuYWRkX2xpc3RlbmVyKHNsaWRlLCAidG91Y2hzdGFydCIsIHRoaXMudG91Y2hzdGFydCk7CiAgICAgIHRoaXMuYWRkX2xpc3RlbmVyKHNsaWRlLCAidG91Y2htb3ZlIiwgdGhpcy50b3VjaG1vdmUpOwogICAgICB0aGlzLmFkZF9saXN0ZW5lcihzbGlkZSwgInRvdWNoZW5kIiwgdGhpcy50b3VjaGVuZCk7CiAgICB9CiAgfSwKCi8vIHJldHVybiBuZXcgYXJyYXkgb2YgYWxsIHNsaWRlcwogIGNvbGxlY3Rfc2xpZGVzOiBmdW5jdGlvbiAoKSB7CiAgICB2YXIgc2xpZGVzID0gbmV3IEFycmF5KCk7CiAgICB2YXIgZGl2cyA9IGRvY3VtZW50LmJvZHkuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImRpdiIpOwoKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGl2cy5sZW5ndGg7ICsraSkKICAgIHsKICAgICAgZGl2ID0gZGl2cy5pdGVtKGkpOwoKICAgICAgaWYgKHRoaXMuaGFzX2NsYXNzKGRpdiwgInNsaWRlIikpCiAgICAgIHsKICAgICAgICAvLyBhZGQgc2xpZGUgdG8gY29sbGVjdGlvbgogICAgICAgIHNsaWRlc1tzbGlkZXMubGVuZ3RoXSA9IGRpdjsKCiAgICAgICAgLy8gaGlkZSBlYWNoIHNsaWRlIGFzIGl0IGlzIGZvdW5kCiAgICAgICAgdGhpcy5hZGRfY2xhc3MoZGl2LCAiaGlkZGVuIik7CgogICAgICAgIC8vIGFkZCBkdW1teSA8YnIvPiBhdCBlbmQgZm9yIHNjcm9sbGluZyBoYWNrCiAgICAgICAgdmFyIG5vZGUxID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYnIiKTsKICAgICAgICBkaXYuYXBwZW5kQ2hpbGQobm9kZTEpOwogICAgICAgIHZhciBub2RlMiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImJyIik7CiAgICAgICAgZGl2LmFwcGVuZENoaWxkKG5vZGUyKTsKICAgICAgfQogICAgICBlbHNlIGlmICh0aGlzLmhhc19jbGFzcyhkaXYsICJiYWNrZ3JvdW5kIikpCiAgICAgIHsgIC8vIHdvcmsgYXJvdW5kIGZvciBGaXJlZm94IFNWRyByZWxvYWQgYnVnCiAgICAgICAgLy8gd2hpY2ggb3RoZXJ3aXNlIHJlcGxhY2VzIDFzdCBTVkcgZ3JhcGhpYyB3aXRoIDJuZAogICAgICAgIGRpdi5zdHlsZS5kaXNwbGF5ID0gImJsb2NrIjsKICAgICAgfQogICAgfQoKICAgIHRoaXMuc2xpZGVzID0gc2xpZGVzOwogIH0sCgogIC8vIHJldHVybiBuZXcgYXJyYXkgb2YgYWxsIDxkaXYgY2xhc3M9ImhhbmRvdXQiPgogIGNvbGxlY3Rfbm90ZXM6IGZ1bmN0aW9uICgpIHsKICAgIHZhciBub3RlcyA9IG5ldyBBcnJheSgpOwogICAgdmFyIGRpdnMgPSBkb2N1bWVudC5ib2R5LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJkaXYiKTsKCiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRpdnMubGVuZ3RoOyArK2kpCiAgICB7CiAgICAgIGRpdiA9IGRpdnMuaXRlbShpKTsKCiAgICAgIGlmICh0aGlzLmhhc19jbGFzcyhkaXYsICJoYW5kb3V0IikpCiAgICAgIHsKICAgICAgICAvLyBhZGQgbm90ZSB0byBjb2xsZWN0aW9uCiAgICAgICAgbm90ZXNbbm90ZXMubGVuZ3RoXSA9IGRpdjsKCiAgICAgICAgLy8gYW5kIGhpZGUgaXQKICAgICAgICB0aGlzLmFkZF9jbGFzcyhkaXYsICJoaWRkZW4iKTsKICAgICAgfQogICAgfQoKICAgIHRoaXMubm90ZXMgPSBub3RlczsKICB9LAoKICAvLyByZXR1cm4gbmV3IGFycmF5IG9mIGFsbCA8ZGl2IGNsYXNzPSJiYWNrZ3JvdW5kIj4KICAvLyBpbmNsdWRpbmcgbmFtZWQgYmFja2dyb3VuZHMgZS5nLiBjbGFzcz0iYmFja2dyb3VuZCB0aXRsZXBhZ2UiCiAgY29sbGVjdF9iYWNrZ3JvdW5kczogZnVuY3Rpb24gKCkgewogICAgdmFyIGJhY2tncm91bmRzID0gbmV3IEFycmF5KCk7CiAgICB2YXIgZGl2cyA9IGRvY3VtZW50LmJvZHkuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImRpdiIpOwoKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGl2cy5sZW5ndGg7ICsraSkKICAgIHsKICAgICAgZGl2ID0gZGl2cy5pdGVtKGkpOwoKICAgICAgaWYgKHRoaXMuaGFzX2NsYXNzKGRpdiwgImJhY2tncm91bmQiKSkKICAgICAgewogICAgICAgIC8vIGFkZCBiYWNrZ3JvdW5kIHRvIGNvbGxlY3Rpb24KICAgICAgICBiYWNrZ3JvdW5kc1tiYWNrZ3JvdW5kcy5sZW5ndGhdID0gZGl2OwoKICAgICAgICAvLyBhbmQgaGlkZSBpdAogICAgICAgIHRoaXMuYWRkX2NsYXNzKGRpdiwgImhpZGRlbiIpOwogICAgICB9CiAgICB9CgogICAgdGhpcy5iYWNrZ3JvdW5kcyA9IGJhY2tncm91bmRzOwogIH0sCgogIC8vIHNldCBjbGljayBoYW5kbGVycyBvbiBhbGwgYW5jaG9ycwogIHBhdGNoX2FuY2hvcnM6IGZ1bmN0aW9uICgpIHsKICAgIHZhciBzZWxmID0gdzNjX3NsaWR5OwogICAgdmFyIGhhbmRsZXIgPSBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgLy8gY29tcGFyZSB0aGlzLmhyZWYgd2l0aCBsb2NhdGlvbi5ocmVmCiAgICAgIC8vIGZvciBsaW5rIHRvIGFub3RoZXIgc2xpZGUgaW4gdGhpcyBkb2MKCiAgICAgIGlmIChzZWxmLnBhZ2VfYWRkcmVzcyh0aGlzLmhyZWYpID09IHNlbGYucGFnZV9hZGRyZXNzKGxvY2F0aW9uLmhyZWYpKQogICAgICB7CiAgICAgICAgLy8geWVzLCBzbyBmaW5kIG5ldyBzbGlkZSBudW1iZXIKICAgICAgICB2YXIgbmV3c2xpZGVudW0gPSBzZWxmLmZpbmRfc2xpZGVfbnVtYmVyKHRoaXMuaHJlZik7CgogICAgICAgIGlmIChuZXdzbGlkZW51bSAhPSBzZWxmLnNsaWRlX251bWJlcikKICAgICAgICB7CiAgICAgICAgICB2YXIgc2xpZGUgPSBzZWxmLnNsaWRlc1tzZWxmLnNsaWRlX251bWJlcl07CiAgICAgICAgICBzZWxmLmhpZGVfc2xpZGUoc2xpZGUpOwogICAgICAgICAgc2VsZi5zbGlkZV9udW1iZXIgPSBuZXdzbGlkZW51bTsKICAgICAgICAgIHNsaWRlID0gc2VsZi5zbGlkZXNbc2VsZi5zbGlkZV9udW1iZXJdOwogICAgICAgICAgc2VsZi5zaG93X3NsaWRlKHNsaWRlKTsKICAgICAgICAgIHNlbGYuc2V0X2xvY2F0aW9uKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIGVsc2UKICAgICAgICB3M2Nfc2xpZHkuc3RvcF9wcm9wYWdhdGlvbihldmVudCk7CgovLyAgICAgIGVsc2UgaWYgKHRoaXMudGFyZ2V0ID09IG51bGwpCi8vICAgICAgICBsb2NhdGlvbi5ocmVmID0gdGhpcy5ocmVmOwoKICAgICAgdGhpcy5ibHVyKCk7CiAgICAgIHNlbGYuZGlzYWJsZV9zbGlkZV9jbGljayA9IHRydWU7CiAgICB9OwoKICAgIHZhciBhbmNob3JzID0gZG9jdW1lbnQuYm9keS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYSIpOwoKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYW5jaG9ycy5sZW5ndGg7ICsraSkKICAgIHsKICAgICAgaWYgKHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKQogICAgICAgIGFuY2hvcnNbaV0uYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLCBoYW5kbGVyLCBmYWxzZSk7CiAgICAgIGVsc2UKICAgICAgICBhbmNob3JzW2ldLmF0dGFjaEV2ZW50KCJvbmNsaWNrIiwgaGFuZGxlcik7CiAgICB9CiAgfSwKCiAgLy8gIyMjIENIRUNLIE1FICMjIyBzZWUgd2hpY2ggZnVuY3Rpb25zIGFyZSBpbnZva2VkIHZpYSBzZXRUaW1lb3V0CiAgLy8gZWl0aGVyIGRpcmVjdGx5IG9yIGluZGlyZWN0bHkgZm9yIHVzZSBvZiB3M2Nfc2xpZHkgdnMgdGhpcwogIHNob3dfc2xpZGVfbnVtYmVyOiBmdW5jdGlvbiAoKSB7CiAgICB2YXIgdGltZXIgPSB3M2Nfc2xpZHkuZ2V0X3RpbWVyKCk7CiAgICB3M2Nfc2xpZHkuc2xpZGVfbnVtYmVyX2VsZW1lbnQuaW5uZXJIVE1MID0gdGltZXIgKyB3M2Nfc2xpZHkubG9jYWxpemUoInNsaWRlIikgKyAiICIgKwogICAgICAgICAgICh3M2Nfc2xpZHkuc2xpZGVfbnVtYmVyICsgMSkgKyAiLyIgKyB3M2Nfc2xpZHkuc2xpZGVzLmxlbmd0aDsKICB9LAoKICAvLyBldmVyeSAyMDBtUyBjaGVjayBpZiB0aGUgbG9jYXRpb24gaGFzIGJlZW4gY2hhbmdlZCBhcyBhCiAgLy8gcmVzdWx0IG9mIHRoZSB1c2VyIGFjdGl2YXRpbmcgdGhlIEJhY2sgYnV0dG9uL21lbnUgaXRlbQogIC8vIGRvZXNuJ3Qgd29yayBmb3IgT3BlcmEgPCA5LjUKICBjaGVja19sb2NhdGlvbjogZnVuY3Rpb24gKCkgewogICAgdmFyIGhhc2ggPSBsb2NhdGlvbi5oYXNoOwoKICAgIGlmICh3M2Nfc2xpZHkuc2xpZGVfbnVtYmVyID4gMCAmJiAoaGFzaCA9PSAiIiB8fCBoYXNoID09ICIjIikpCiAgICAgIHczY19zbGlkeS5nb3RvX3NsaWRlKDApOwogICAgZWxzZSBpZiAoaGFzaC5sZW5ndGggPiAyICYmIGhhc2ggIT0gIiMoIisodzNjX3NsaWR5LnNsaWRlX251bWJlcisxKSsiKSIpCiAgICB7CiAgICAgIHZhciBudW0gPSBwYXJzZUludChsb2NhdGlvbi5oYXNoLnN1YnN0cigyKSk7CgogICAgICBpZiAoIWlzTmFOKG51bSkpCiAgICAgICAgdzNjX3NsaWR5LmdvdG9fc2xpZGUobnVtLTEpOwogICAgfQoKICAgIGlmICh3M2Nfc2xpZHkudGltZV9sZWZ0ICYmIHczY19zbGlkeS5zbGlkZV9udW1iZXIgPiAwKQogICAgewogICAgICB3M2Nfc2xpZHkuc2hvd19zbGlkZV9udW1iZXIoKTsKCiAgICAgIGlmICh3M2Nfc2xpZHkudGltZV9sZWZ0ID4gMCkKICAgICAgICB3M2Nfc2xpZHkudGltZV9sZWZ0IC09IDIwMDsKICAgIH0gCiAgfSwKCiAgZ2V0X3RpbWVyOiBmdW5jdGlvbiAoKSB7CiAgICB2YXIgdGltZXIgPSAiIjsKICAgIGlmICh3M2Nfc2xpZHkudGltZV9sZWZ0KQogICAgewogICAgICB2YXIgbWlucywgc2VjczsKICAgICAgc2VjcyA9IE1hdGguZmxvb3IodzNjX3NsaWR5LnRpbWVfbGVmdC8xMDAwKTsKICAgICAgbWlucyA9IE1hdGguZmxvb3Ioc2VjcyAvIDYwKTsKICAgICAgc2VjcyA9IHNlY3MgJSA2MDsKICAgICAgdGltZXIgPSAobWlucyA/IG1pbnMrIm0iIDogIiIpICsgc2VjcyArICJzICI7CiAgICB9CgogICAgcmV0dXJuIHRpbWVyOwogIH0sCgogIC8vIHRoaXMgZG9lc24ndCBwdXNoIGxvY2F0aW9uIG9udG8gaGlzdG9yeSBzdGFjayBmb3IgSUUKICAvLyBmb3Igd2hpY2ggYSBoaWRkZW4gaWZyYW1lIGhhY2sgaXMgbmVlZGVkOiBsb2FkIHBhZ2UgaW50bwogIC8vIHRoZSBpZnJhbWUgd2l0aCBzY3JpcHQgdGhhdCBzZXQncyBwYXJlbnQncyBsb2NhdGlvbi5oYXNoCiAgLy8gYnV0IHRoYXQgd29uJ3Qgd29yayBmb3Igc3RhbmRhbG9uZSB1c2UgdW5sZXNzIHdlIGNhbgogIC8vIGNyZWF0ZSB0aGUgcGFnZSBkeW5hbWljYWxseSB2aWEgYSBqYXZhc2NyaXB0OiBVUkwKICAvLyAjIyMgdXNlIGhpc3RvcnkucHVzaFN0YXRlIGlmIGF2YWlsYWJsZQogIHNldF9sb2NhdGlvbjogZnVuY3Rpb24gKCkgewogICAgIHZhciB1cmkgPSB3M2Nfc2xpZHkucGFnZV9hZGRyZXNzKGxvY2F0aW9uLmhyZWYpOwogICAgIHZhciBoYXNoID0gIiMoIiArICh3M2Nfc2xpZHkuc2xpZGVfbnVtYmVyKzEpICsgIikiOwoKICAgICBpZiAodzNjX3NsaWR5LnNsaWRlX251bWJlciA+PSAwKQogICAgICAgdXJpID0gdXJpICsgaGFzaDsKCiAgICAgaWYgKHR5cGVvZihoaXN0b3J5LnB1c2hTdGF0ZSkgIT0gInVuZGVmaW5lZCIgJiYgbG9jYXRpb24ucHJvdG9jb2wgIT09ICJmaWxlOiIpCiAgICAgewogICAgICAgZG9jdW1lbnQudGl0bGUgPSB3M2Nfc2xpZHkudGl0bGUgKyAiICgiICsgKHczY19zbGlkeS5zbGlkZV9udW1iZXIrMSkgKyAiKSI7CiAgICAgICBoaXN0b3J5LnB1c2hTdGF0ZSgwLCBkb2N1bWVudC50aXRsZSwgaGFzaCk7CiAgICAgICB3M2Nfc2xpZHkuc2hvd19zbGlkZV9udW1iZXIoKTsKICAgICAgIHczY19zbGlkeS5ub3RpZnlfb2JzZXJ2ZXJzKCk7CiAgICAgICByZXR1cm47CiAgICAgfQoKICAgICBpZiAodzNjX3NsaWR5LmllICYmICh3M2Nfc2xpZHkuaWU2IHx8IHczY19zbGlkeS5pZTcpKQogICAgICAgdzNjX3NsaWR5LnB1c2hfaGFzaChoYXNoKTsKCiAgICAgaWYgKHVyaSAhPSBsb2NhdGlvbi5ocmVmKSAvLyAmJiAha2h0bWwKICAgICAgICBsb2NhdGlvbi5ocmVmID0gdXJpOwoKICAgICBpZiAodGhpcy5raHRtbCkKICAgICAgICBoYXNoID0gIigiICsgKHczY19zbGlkeS5zbGlkZV9udW1iZXIrMSkgKyAiKSI7CgogICAgIGlmICghdGhpcy5pZSAmJiBsb2NhdGlvbi5oYXNoICE9IGhhc2ggJiYgbG9jYXRpb24uaGFzaCAhPSAiIikKICAgICAgIGxvY2F0aW9uLmhhc2ggPSBoYXNoOwoKICAgICBkb2N1bWVudC50aXRsZSA9IHczY19zbGlkeS50aXRsZSArICIgKCIgKyAodzNjX3NsaWR5LnNsaWRlX251bWJlcisxKSArICIpIjsKICAgICB3M2Nfc2xpZHkuc2hvd19zbGlkZV9udW1iZXIoKTsKICAgICB3M2Nfc2xpZHkubm90aWZ5X29ic2VydmVycygpOwogIH0sCgogIG5vdGlmeV9vYnNlcnZlcnM6IGZ1bmN0aW9uICgpCiAgewogICAgdmFyIHNsaWRlID0gdGhpcy5zbGlkZXNbdGhpcy5zbGlkZV9udW1iZXJdOwoKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5vYnNlcnZlcnMubGVuZ3RoOyArK2kpCiAgICAgIHRoaXMub2JzZXJ2ZXJzW2ldKHRoaXMuc2xpZGVfbnVtYmVyKzEsIHRoaXMuZmluZF9oZWFkaW5nKHNsaWRlKS5pbm5lclRleHQsIGxvY2F0aW9uLmhyZWYpOwogIH0sCgogIGFkZF9vYnNlcnZlcjogZnVuY3Rpb24gKG9ic2VydmVyKQogIHsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5vYnNlcnZlcnMubGVuZ3RoOyArK2kpCiAgICB7CiAgICAgIGlmIChvYnNlcnZlciA9PSB0aGlzLm9ic2VydmVyc1tpXSkKICAgICAgICByZXR1cm47CiAgICB9CgogICAgdGhpcy5vYnNlcnZlcnMucHVzaChvYnNlcnZlcik7CiAgfSwKCiAgcmVtb3ZlX29ic2VydmVyOiBmdW5jdGlvbiAobykKICB7CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMub2JzZXJ2ZXJzLmxlbmd0aDsgKytpKQogICAgewogICAgICBpZiAob2JzZXJ2ZXIgPT0gdGhpcy5vYnNlcnZlcnNbaV0pCiAgICAgIHsKICAgICAgICB0aGlzLm9ic2VydmVycy5zcGxpY2UoaSwxKTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogIH0sCgogIHBhZ2VfYWRkcmVzczogZnVuY3Rpb24gKHVyaSkgewogICAgdmFyIGkgPSB1cmkuaW5kZXhPZigiIyIpOwoKICAgIGlmIChpIDwgMCkKICAgICAgaSA9IHVyaS5pbmRleE9mKCIlMjMiKTsKCiAgICAvLyBjaGVjayBpZiBhbmNob3IgaXMgZW50aXJlIHBhZ2UKCiAgICBpZiAoaSA8IDApCiAgICAgIHJldHVybiB1cmk7ICAvLyB5ZXMKCiAgICByZXR1cm4gdXJpLnN1YnN0cigwLCBpKTsKICB9LAoKICAvLyBvbmx5IHVzZWQgZm9yIElFNiBhbmQgSUU3CiAgb25fZnJhbWVfbG9hZGVkOiBmdW5jdGlvbiAoaGFzaCkgewogICAgbG9jYXRpb24uaGFzaCA9IGhhc2g7CiAgICB2YXIgdXJpID0gdzNjX3NsaWR5LnBhZ2VfYWRkcmVzcyhsb2NhdGlvbi5ocmVmKTsKICAgIGxvY2F0aW9uLmhyZWYgPSB1cmkgKyBoYXNoOwogIH0sCgogIC8vIGhpc3RvcnkgaGFjayB3aXRoIHRoYW5rcyB0byBCZXJ0cmFuZCBMZSBSb3kKICBwdXNoX2hhc2g6IGZ1bmN0aW9uIChoYXNoKSB7CiAgICBpZiAoaGFzaCA9PSAiIikgaGFzaCA9ICIjKDEpIjsKICAgICAgd2luZG93LmxvY2F0aW9uLmhhc2ggPSBoYXNoOwoKICAgIHZhciBkb2MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiaGlzdG9yeUZyYW1lIikuY29udGVudFdpbmRvdy5kb2N1bWVudDsKICAgIGRvYy5vcGVuKCJqYXZhc2NyaXB0Oic8aHRtbD48L2h0bWw+JyIpOwogICAgZG9jLndyaXRlKCI8aHRtbD48aGVhZD48c2NyaXB0IHR5cGU9XCJ0ZXh0L2phdmFzY3JpcHRcIj53aW5kb3cucGFyZW50LnczY19zbGlkeS5vbl9mcmFtZV9sb2FkZWQoJyIrCiAgICAgIChoYXNoKSArICInKTs8L3NjcmlwdD48L2hlYWQ+PGJvZHk+aGVsbG8gbXVtPC9ib2R5PjwvaHRtbD4iKTsKICAgICAgZG9jLmNsb3NlKCk7CiAgfSwKCiAgLy8gZmluZCBjdXJyZW50IHNsaWRlIGJhc2VkIHVwb24gbG9jYXRpb24KICAvLyBmaXJzdCBmaW5kIHRhcmdldCBhbmNob3IgYW5kIHRoZW4gbG9vawogIC8vIGZvciBhc3NvY2lhdGVkIGRpdiBlbGVtZW50IGVuY2xvc2luZyBpdAogIC8vIGZpbmFsbHkgbWFwIHRoYXQgdG8gc2xpZGUgbnVtYmVyCiAgZmluZF9zbGlkZV9udW1iZXI6IGZ1bmN0aW9uICh1cmkpIHsKICAgIC8vIGZpcnN0IGdldCBhbmNob3IgZnJvbSBwYWdlIGxvY2F0aW9uCgogICAgdmFyIGkgPSB1cmkuaW5kZXhPZigiIyIpOwoKICAgIC8vIGNoZWNrIGlmIGFuY2hvciBpcyBlbnRpcmUgcGFnZQogICAgaWYgKGkgPCAwKQogICAgICByZXR1cm4gMDsgIC8vIHllcwoKICAgIHZhciBhbmNob3IgPSB1bmVzY2FwZSh1cmkuc3Vic3RyKGkrMSkpOwoKICAgIC8vIG5vdyB1c2UgYW5jaG9yIGFzIFhNTCBJRCB0byBmaW5kIHRhcmdldAogICAgdmFyIHRhcmdldCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGFuY2hvcik7CgogICAgaWYgKCF0YXJnZXQpCiAgICB7CiAgICAgIC8vIGRvZXMgYW5jaG9yIGxvb2sgbGlrZSAiKDIpIiBmb3Igc2xpZGUgMiA/PwogICAgICAvLyB3aGVyZSBmaXJzdCBzbGlkZSBpcyAoMSkKICAgICAgdmFyIHJlID0gL1woKFxkKStcKS87CgogICAgICBpZiAoYW5jaG9yLm1hdGNoKHJlKSkKICAgICAgewogICAgICAgIHZhciBudW0gPSBwYXJzZUludChhbmNob3Iuc3Vic3RyaW5nKDEsIGFuY2hvci5sZW5ndGgtMSkpOwoKICAgICAgICBpZiAobnVtID4gdGhpcy5zbGlkZXMubGVuZ3RoKQogICAgICAgICAgbnVtID0gMTsKCiAgICAgICAgaWYgKC0tbnVtIDwgMCkKICAgICAgICAgIG51bSA9IDA7CgogICAgICAgIHJldHVybiBudW07CiAgICAgIH0KCiAgICAgIC8vIGFjY2VwdCBbMl0gZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5CiAgICAgIHJlID0gL1xbKFxkKStcXS87CgogICAgICBpZiAoYW5jaG9yLm1hdGNoKHJlKSkKICAgICAgewogICAgICAgICB2YXIgbnVtID0gcGFyc2VJbnQoYW5jaG9yLnN1YnN0cmluZygxLCBhbmNob3IubGVuZ3RoLTEpKTsKCiAgICAgICAgIGlmIChudW0gPiB0aGlzLnNsaWRlcy5sZW5ndGgpCiAgICAgICAgICAgIG51bSA9IDE7CgogICAgICAgICBpZiAoLS1udW0gPCAwKQogICAgICAgICAgICBudW0gPSAwOwoKICAgICAgICAgcmV0dXJuIG51bTsKICAgICAgfQoKICAgICAgLy8gb2ggZGVhciB1bmtub3duIGFuY2hvcgogICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvLyBzZWFyY2ggZm9yIGVuY2xvc2luZyBzbGlkZQoKICAgIHdoaWxlICh0cnVlKQogICAgewogICAgICAvLyBicm93c2VyIGNvZXJjZXMgaHRtbCBlbGVtZW50cyB0byB1cHBlcmNhc2UhCiAgICAgIGlmICh0YXJnZXQubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PSAiZGl2IiAmJgogICAgICAgICAgICB0aGlzLmhhc19jbGFzcyh0YXJnZXQsICJzbGlkZSIpKQogICAgICB7CiAgICAgICAgLy8gZm91bmQgdGhlIHNsaWRlIGVsZW1lbnQKICAgICAgICBicmVhazsKICAgICAgfQoKICAgICAgLy8gb3RoZXJ3aXNlIHRyeSBwYXJlbnQgZWxlbWVudCBpZiBhbnkKCiAgICAgIHRhcmdldCA9IHRhcmdldC5wYXJlbnROb2RlOwoKICAgICAgaWYgKCF0YXJnZXQpCiAgICAgIHsKICAgICAgICByZXR1cm4gMDsgICAvLyBubyBsdWNrIQogICAgICB9CiAgICB9OwoKICAgIGZvciAoaSA9IDA7IGkgPCBzbGlkZXMubGVuZ3RoOyArK2kpCiAgICB7CiAgICAgIGlmIChzbGlkZXNbaV0gPT0gdGFyZ2V0KQogICAgICAgIHJldHVybiBpOyAgLy8gc3VjY2VzcwogICAgfQoKICAgIC8vIG9oIGRlYXIgc3RpbGwgbm8gbHVjawogICAgcmV0dXJuIDA7CiAgfSwKCiAgcHJldmlvdXNfc2xpZGU6IGZ1bmN0aW9uIChpbmNyZW1lbnRhbCkgewogICAgaWYgKCF3M2Nfc2xpZHkudmlld19hbGwpCiAgICB7CiAgICAgIHZhciBzbGlkZTsKCiAgICAgIGlmICgoaW5jcmVtZW50YWwgfHwgdzNjX3NsaWR5LnNsaWRlX251bWJlciA9PSAwKSAmJiB3M2Nfc2xpZHkubGFzdF9zaG93biAhPSBudWxsKQogICAgICB7CiAgICAgICAgdzNjX3NsaWR5Lmxhc3Rfc2hvd24gPSB3M2Nfc2xpZHkuaGlkZV9wcmV2aW91c19pdGVtKHczY19zbGlkeS5sYXN0X3Nob3duKTsKICAgICAgICB3M2Nfc2xpZHkuc2V0X2Vvc19zdGF0dXMoZmFsc2UpOwogICAgICB9CiAgICAgIGVsc2UgaWYgKHczY19zbGlkeS5zbGlkZV9udW1iZXIgPiAwKQogICAgICB7CiAgICAgICAgc2xpZGUgPSB3M2Nfc2xpZHkuc2xpZGVzW3czY19zbGlkeS5zbGlkZV9udW1iZXJdOwogICAgICAgIHczY19zbGlkeS5oaWRlX3NsaWRlKHNsaWRlKTsKCiAgICAgICAgdzNjX3NsaWR5LnNsaWRlX251bWJlciA9IHczY19zbGlkeS5zbGlkZV9udW1iZXIgLSAxOwogICAgICAgIHNsaWRlID0gdzNjX3NsaWR5LnNsaWRlc1t3M2Nfc2xpZHkuc2xpZGVfbnVtYmVyXTsKICAgICAgICB3M2Nfc2xpZHkuc2V0X3Zpc2liaWxpdHlfYWxsX2luY3JlbWVudGFsKCJ2aXNpYmxlIik7CiAgICAgICAgdzNjX3NsaWR5Lmxhc3Rfc2hvd24gPSB3M2Nfc2xpZHkucHJldmlvdXNfaW5jcmVtZW50YWxfaXRlbShudWxsKTsKICAgICAgICB3M2Nfc2xpZHkuc2V0X2Vvc19zdGF0dXModHJ1ZSk7CiAgICAgICAgdzNjX3NsaWR5LnNob3dfc2xpZGUoc2xpZGUpOwogICAgICB9CgogICAgICB3M2Nfc2xpZHkuc2V0X2xvY2F0aW9uKCk7CgogICAgICBpZiAoIXczY19zbGlkeS5uc19wb3MpCiAgICAgICAgdzNjX3NsaWR5LnJlZnJlc2hfdG9vbGJhcigyMDApOwogICAgfQogIH0sCgogIG5leHRfc2xpZGU6IGZ1bmN0aW9uIChpbmNyZW1lbnRhbCkgewogICAgaWYgKCF3M2Nfc2xpZHkudmlld19hbGwpCiAgICB7CiAgICAgIHZhciBzbGlkZSwgbGFzdCA9IHczY19zbGlkeS5sYXN0X3Nob3duOwoKICAgICAgaWYgKGluY3JlbWVudGFsIHx8IHczY19zbGlkeS5zbGlkZV9udW1iZXIgPT0gdzNjX3NsaWR5LnNsaWRlcy5sZW5ndGggLSAxKQogICAgICAgICB3M2Nfc2xpZHkubGFzdF9zaG93biA9IHczY19zbGlkeS5yZXZlYWxfbmV4dF9pdGVtKHczY19zbGlkeS5sYXN0X3Nob3duKTsKCiAgICAgIGlmICgoIWluY3JlbWVudGFsIHx8IHczY19zbGlkeS5sYXN0X3Nob3duID09IG51bGwpICYmCiAgICAgICAgICAgICB3M2Nfc2xpZHkuc2xpZGVfbnVtYmVyIDwgdzNjX3NsaWR5LnNsaWRlcy5sZW5ndGggLSAxKQogICAgICB7CiAgICAgICAgIHNsaWRlID0gdzNjX3NsaWR5LnNsaWRlc1t3M2Nfc2xpZHkuc2xpZGVfbnVtYmVyXTsKICAgICAgICAgdzNjX3NsaWR5LmhpZGVfc2xpZGUoc2xpZGUpOwoKICAgICAgICAgdzNjX3NsaWR5LnNsaWRlX251bWJlciA9IHczY19zbGlkeS5zbGlkZV9udW1iZXIgKyAxOwogICAgICAgICBzbGlkZSA9IHczY19zbGlkeS5zbGlkZXNbdzNjX3NsaWR5LnNsaWRlX251bWJlcl07CiAgICAgICAgIHczY19zbGlkeS5sYXN0X3Nob3duID0gbnVsbDsKICAgICAgICAgdzNjX3NsaWR5LnNldF92aXNpYmlsaXR5X2FsbF9pbmNyZW1lbnRhbCgiaGlkZGVuIik7CiAgICAgICAgIHczY19zbGlkeS5zaG93X3NsaWRlKHNsaWRlKTsKICAgICAgfQogICAgICBlbHNlIGlmICghdzNjX3NsaWR5Lmxhc3Rfc2hvd24pCiAgICAgIHsKICAgICAgICAgaWYgKGxhc3QgJiYgaW5jcmVtZW50YWwpCiAgICAgICAgICAgdzNjX3NsaWR5Lmxhc3Rfc2hvd24gPSBsYXN0OwogICAgICB9CgogICAgICB3M2Nfc2xpZHkuc2V0X2xvY2F0aW9uKCk7CgogICAgICB3M2Nfc2xpZHkuc2V0X2Vvc19zdGF0dXMoIXczY19zbGlkeS5uZXh0X2luY3JlbWVudGFsX2l0ZW0odzNjX3NsaWR5Lmxhc3Rfc2hvd24pKTsKCiAgICAgIGlmICghdzNjX3NsaWR5Lm5zX3BvcykKICAgICAgICAgdzNjX3NsaWR5LnJlZnJlc2hfdG9vbGJhcigyMDApOwogICAgIH0KICB9LAoKICAvLyB0byBmaXJzdCBzbGlkZSB3aXRoIG5vdGhpbmcgcmV2ZWFsZWQKICAvLyBpLmUuIHN0YXRlIGF0IHN0YXJ0IG9mIHByZXNlbnRhdGlvbgogIGZpcnN0X3NsaWRlOiBmdW5jdGlvbiAoKSB7CiAgICAgaWYgKCF3M2Nfc2xpZHkudmlld19hbGwpCiAgICAgewogICAgICAgdmFyIHNsaWRlOwoKICAgICAgIGlmICh3M2Nfc2xpZHkuc2xpZGVfbnVtYmVyICE9IDApCiAgICAgICB7CiAgICAgICAgIHNsaWRlID0gdzNjX3NsaWR5LnNsaWRlc1t3M2Nfc2xpZHkuc2xpZGVfbnVtYmVyXTsKICAgICAgICAgdzNjX3NsaWR5LmhpZGVfc2xpZGUoc2xpZGUpOwoKICAgICAgICAgdzNjX3NsaWR5LnNsaWRlX251bWJlciA9IDA7CiAgICAgICAgIHNsaWRlID0gdzNjX3NsaWR5LnNsaWRlc1t3M2Nfc2xpZHkuc2xpZGVfbnVtYmVyXTsKICAgICAgICAgdzNjX3NsaWR5Lmxhc3Rfc2hvd24gPSBudWxsOwogICAgICAgICB3M2Nfc2xpZHkuc2V0X3Zpc2liaWxpdHlfYWxsX2luY3JlbWVudGFsKCJoaWRkZW4iKTsKICAgICAgICAgdzNjX3NsaWR5LnNob3dfc2xpZGUoc2xpZGUpOwogICAgICAgfQoKICAgICAgIHczY19zbGlkeS5zZXRfZW9zX3N0YXR1cygKICAgICAgICAgIXczY19zbGlkeS5uZXh0X2luY3JlbWVudGFsX2l0ZW0odzNjX3NsaWR5Lmxhc3Rfc2hvd24pKTsKICAgICAgIHczY19zbGlkeS5zZXRfbG9jYXRpb24oKTsKICAgICB9CiAgfSwKCiAgLy8gZ290byBsYXN0IHNsaWRlIHdpdGggZXZlcnl0aGluZyByZXZlYWxlZAogIC8vIGkuZS4gc3RhdGUgYXQgZW5kIG9mIHByZXNlbnRhdGlvbgogIGxhc3Rfc2xpZGU6IGZ1bmN0aW9uICgpIHsKICAgIGlmICghdzNjX3NsaWR5LnZpZXdfYWxsKQogICAgewogICAgICB2YXIgc2xpZGU7CgogICAgICB3M2Nfc2xpZHkubGFzdF9zaG93biA9IG51bGw7IC8vcmV2ZWFsTmV4dEl0ZW0obGFzdFNob3duKTsKCiAgICAgIGlmICh3M2Nfc2xpZHkubGFzdF9zaG93biA9PSBudWxsICYmCiAgICAgICAgICB3M2Nfc2xpZHkuc2xpZGVfbnVtYmVyIDwgdzNjX3NsaWR5LnNsaWRlcy5sZW5ndGggLSAxKQogICAgICB7CiAgICAgICAgIHNsaWRlID0gdzNjX3NsaWR5LnNsaWRlc1t3M2Nfc2xpZHkuc2xpZGVfbnVtYmVyXTsKICAgICAgICAgdzNjX3NsaWR5LmhpZGVfc2xpZGUoc2xpZGUpOwogICAgICAgICB3M2Nfc2xpZHkuc2xpZGVfbnVtYmVyID0gdzNjX3NsaWR5LnNsaWRlcy5sZW5ndGggLSAxOwogICAgICAgICBzbGlkZSA9IHczY19zbGlkeS5zbGlkZXNbdzNjX3NsaWR5LnNsaWRlX251bWJlcl07CiAgICAgICAgIHczY19zbGlkeS5zZXRfdmlzaWJpbGl0eV9hbGxfaW5jcmVtZW50YWwoInZpc2libGUiKTsKICAgICAgICAgdzNjX3NsaWR5Lmxhc3Rfc2hvd24gPSB3M2Nfc2xpZHkucHJldmlvdXNfaW5jcmVtZW50YWxfaXRlbShudWxsKTsKCiAgICAgICAgIHczY19zbGlkeS5zaG93X3NsaWRlKHNsaWRlKTsKICAgICAgfQogICAgICBlbHNlCiAgICAgIHsKICAgICAgICAgdzNjX3NsaWR5LnNldF92aXNpYmlsaXR5X2FsbF9pbmNyZW1lbnRhbCgidmlzaWJsZSIpOwogICAgICAgICB3M2Nfc2xpZHkubGFzdF9zaG93biA9IHczY19zbGlkeS5wcmV2aW91c19pbmNyZW1lbnRhbF9pdGVtKG51bGwpOwogICAgICB9CgogICAgICB3M2Nfc2xpZHkuc2V0X2Vvc19zdGF0dXModHJ1ZSk7CiAgICAgIHczY19zbGlkeS5zZXRfbG9jYXRpb24oKTsKICAgIH0KICB9LAoKCiAgLy8gIyMjIGNoZWNrIHRoaXMgYW5kIGNvbnNpZGVyIGFkZC9yZW1vdmUgY2xhc3MKICBzZXRfZW9zX3N0YXR1czogZnVuY3Rpb24gKHN0YXRlKSB7CiAgICBpZiAodGhpcy5lb3MpCiAgICAgIHRoaXMuZW9zLnN0eWxlLmNvbG9yID0gKHN0YXRlID8gInJnYigyNDAsMjQwLDI0MCkiIDogInJlZCIpOwogIH0sCgogIC8vIGZpcnN0IHNsaWRlIGlzIDAKICBnb3RvX3NsaWRlOiBmdW5jdGlvbiAobnVtKSB7CiAgICAvL2FsZXJ0KCJnb2luZyB0byBzbGlkZSAiICsgKG51bSsxKSk7CiAgICB2YXIgc2xpZGUgPSB3M2Nfc2xpZHkuc2xpZGVzW3czY19zbGlkeS5zbGlkZV9udW1iZXJdOwogICAgdzNjX3NsaWR5LmhpZGVfc2xpZGUoc2xpZGUpOwogICAgdzNjX3NsaWR5LnNsaWRlX251bWJlciA9IG51bTsKICAgIHNsaWRlID0gdzNjX3NsaWR5LnNsaWRlc1t3M2Nfc2xpZHkuc2xpZGVfbnVtYmVyXTsKICAgIHczY19zbGlkeS5sYXN0X3Nob3duID0gbnVsbDsKICAgIHczY19zbGlkeS5zZXRfdmlzaWJpbGl0eV9hbGxfaW5jcmVtZW50YWwoImhpZGRlbiIpOwogICAgdzNjX3NsaWR5LnNldF9lb3Nfc3RhdHVzKCF3M2Nfc2xpZHkubmV4dF9pbmNyZW1lbnRhbF9pdGVtKHczY19zbGlkeS5sYXN0X3Nob3duKSk7CiAgICBkb2N1bWVudC50aXRsZSA9IHczY19zbGlkeS50aXRsZSArICIgKCIgKyAodzNjX3NsaWR5LnNsaWRlX251bWJlcisxKSArICIpIjsKICAgIHczY19zbGlkeS5zaG93X3NsaWRlKHNsaWRlKTsKICAgIHczY19zbGlkeS5zaG93X3NsaWRlX251bWJlcigpOwogIH0sCgoKICBzaG93X3NsaWRlOiBmdW5jdGlvbiAoc2xpZGUpIHsKICAgIHRoaXMuc3luY19iYWNrZ3JvdW5kKHNsaWRlKTsKICAgIHRoaXMucmVtb3ZlX2NsYXNzKHNsaWRlLCAiaGlkZGVuIik7CgogICAgLy8gd29yayBhcm91bmQgSUU5IG9iamVjdCByZW5kZXJpbmcgYnVnCiAgICBzZXRUaW1lb3V0KCJ3aW5kb3cuc2Nyb2xsVG8oMCwwKTsiLCAxKTsKICB9LAoKICBoaWRlX3NsaWRlOiBmdW5jdGlvbiAoc2xpZGUpIHsKICAgIHRoaXMuYWRkX2NsYXNzKHNsaWRlLCAiaGlkZGVuIik7CiAgfSwKCiAgc2V0X2ZvY3VzOiBmdW5jdGlvbiAoZWxlbWVudCkKICB7CiAgICBpZiAoZWxlbWVudCkKICAgICAgZWxlbWVudC5mb2N1cygpOwogICAgZWxzZQogICAgewogICAgICB3M2Nfc2xpZHkuaGVscF9hbmNob3IuZm9jdXMoKTsKCiAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7CiAgICAgICAgdzNjX3NsaWR5LmhlbHBfYW5jaG9yLmJsdXIoKTsKICAgICAgfSwgMSk7CiAgICB9CiAgfSwKCiAgLy8gc2hvdyBqdXN0IHRoZSBiYWNrZ3JvdW5kcyBwZXJ0aW5lbnQgdG8gdGhpcyBzbGlkZQogIC8vIHdoZW4gc2xpZGUgYmFja2dyb3VuZC1jb2xvciBpcyB0cmFuc3BhcmVudAogIC8vIHRoaXMgc2hvdWxkIG5vdyB3b3JrIHdpdGggcmdiYSBjb2xvciB2YWx1ZXMKICBzeW5jX2JhY2tncm91bmQ6IGZ1bmN0aW9uIChzbGlkZSkgewogICAgdmFyIGJhY2tncm91bmQ7CiAgICB2YXIgYmdDb2xvcjsKCiAgICBpZiAoc2xpZGUuY3VycmVudFN0eWxlKQogICAgICBiZ0NvbG9yID0gc2xpZGUuY3VycmVudFN0eWxlWyJiYWNrZ3JvdW5kQ29sb3IiXTsKICAgIGVsc2UgaWYgKGRvY3VtZW50LmRlZmF1bHRWaWV3KQogICAgewogICAgICB2YXIgc3R5bGVzID0gZG9jdW1lbnQuZGVmYXVsdFZpZXcuZ2V0Q29tcHV0ZWRTdHlsZShzbGlkZSxudWxsKTsKCiAgICAgIGlmIChzdHlsZXMpCiAgICAgICAgYmdDb2xvciA9IHN0eWxlcy5nZXRQcm9wZXJ0eVZhbHVlKCJiYWNrZ3JvdW5kLWNvbG9yIik7CiAgICAgIGVsc2UgLy8gYnJva2VuIGltcGxlbWVudGF0aW9uIHByb2JhYmx5IGR1ZSBTYWZhcmkgb3IgS29ucXVlcm9yCiAgICAgIHsKICAgICAgICAvL2FsZXJ0KCJkZWZlY3RpdmUgaW1wbGVtZW50YXRpb24gb2YgZ2V0Q29tcHV0ZWRTdHlsZSgpIik7CiAgICAgICAgYmdDb2xvciA9ICJ0cmFuc3BhcmVudCI7CiAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgICAgYmdDb2xvciA9PSAidHJhbnNwYXJlbnQiOwoKICAgIGlmIChiZ0NvbG9yID09ICJ0cmFuc3BhcmVudCIgfHwKICAgICAgICBiZ0NvbG9yLmluZGV4T2YoInJnYmEiKSA+PSAwIHx8CiAgICAgICAgYmdDb2xvci5pbmRleE9mKCJvcGFjaXR5IikgPj0gMCkKICAgIHsKICAgICAgdmFyIHNsaWRlQ2xhc3MgPSB0aGlzLmdldF9jbGFzc19saXN0KHNsaWRlKTsKCiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5iYWNrZ3JvdW5kcy5sZW5ndGg7IGkrKykKICAgICAgewogICAgICAgIGJhY2tncm91bmQgPSB0aGlzLmJhY2tncm91bmRzW2ldOwoKICAgICAgICB2YXIgYmdDbGFzcyA9IHRoaXMuZ2V0X2NsYXNzX2xpc3QoYmFja2dyb3VuZCk7CgogICAgICAgIGlmICh0aGlzLm1hdGNoaW5nX2JhY2tncm91bmQoc2xpZGVDbGFzcywgYmdDbGFzcykpCiAgICAgICAgICB0aGlzLnJlbW92ZV9jbGFzcyhiYWNrZ3JvdW5kLCAiaGlkZGVuIik7CiAgICAgICAgZWxzZQogICAgICAgICAgdGhpcy5hZGRfY2xhc3MoYmFja2dyb3VuZCwgImhpZGRlbiIpOwogICAgICB9CiAgICB9CiAgICBlbHNlIC8vIGZvcmNpYmx5IGhpZGUgYWxsIGJhY2tncm91bmRzCiAgICAgIHRoaXMuaGlkZV9iYWNrZ3JvdW5kcygpOwogIH0sCgogIGhpZGVfYmFja2dyb3VuZHM6IGZ1bmN0aW9uICgpIHsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5iYWNrZ3JvdW5kcy5sZW5ndGg7IGkrKykKICAgIHsKICAgICAgYmFja2dyb3VuZCA9IHRoaXMuYmFja2dyb3VuZHNbaV07CiAgICAgIHRoaXMuYWRkX2NsYXNzKGJhY2tncm91bmQsICJoaWRkZW4iKTsKICAgIH0KICB9LAoKICAvLyBjb21wYXJlIGNsYXNzZXMgZm9yIHNsaWRlIGFuZCBiYWNrZ3JvdW5kCiAgbWF0Y2hpbmdfYmFja2dyb3VuZDogZnVuY3Rpb24gKHNsaWRlQ2xhc3MsIGJnQ2xhc3MpIHsKICAgIHZhciBpLCBjb3VudCwgcGF0dGVybiwgcmVzdWx0OwoKICAgIC8vIGRlZmluZSBwYXR0ZXJuIGFzIHJlZ3VsYXIgZXhwcmVzc2lvbgogICAgcGF0dGVybiA9IC9cdysvZzsKCiAgICAvLyBjaGVjayBiYWNrZ3JvdW5kIGNsYXNzIG5hbWVzCiAgICByZXN1bHQgPSBiZ0NsYXNzLm1hdGNoKHBhdHRlcm4pOwoKICAgIGZvciAoaSA9IGNvdW50ID0gMDsgaSA8IHJlc3VsdC5sZW5ndGg7IGkrKykKICAgIHsKICAgICAgaWYgKHJlc3VsdFtpXSA9PSAiaGlkZGVuIikKICAgICAgICBjb250aW51ZTsKCiAgICAgIGlmIChyZXN1bHRbaV0gPT0gImJhY2tncm91bmQiKQoJY29udGludWU7CgogICAgICArK2NvdW50OwogICAgfQoKICAgIGlmIChjb3VudCA9PSAwKSAgLy8gZGVmYXVsdCBtYXRjaAogICAgICByZXR1cm4gdHJ1ZTsKCiAgICAvLyBjaGVjayBmb3IgbWF0Y2hlcyBhbmQgcGxhY2UgcmVzdWx0IGluIGFycmF5CiAgICByZXN1bHQgPSBzbGlkZUNsYXNzLm1hdGNoKHBhdHRlcm4pOwoKICAgIC8vIG5vdyBjaGVjayBpZiBkZXNpcmVkIG5hbWUgaXMgcHJlc2VudCBmb3IgYmFja2dyb3VuZAogICAgZm9yIChpID0gY291bnQgPSAwOyBpIDwgcmVzdWx0Lmxlbmd0aDsgaSsrKQogICAgewogICAgICBpZiAocmVzdWx0W2ldID09ICJoaWRkZW4iKQogICAgICAgIGNvbnRpbnVlOwoKICAgICAgaWYgKHRoaXMuaGFzX3Rva2VuKGJnQ2xhc3MsIHJlc3VsdFtpXSkpCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgcmV0dXJuIGZhbHNlOwogIH0sCgogIHJlc2l6ZWQ6IGZ1bmN0aW9uICgpIHsKICAgICB2YXIgd2lkdGggPSAwOwoKICAgICBpZiAoIHR5cGVvZiggd2luZG93LmlubmVyV2lkdGggKSA9PSAnbnVtYmVyJyApCiAgICAgICB3aWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoOyAgLy8gTm9uIElFIGJyb3dzZXIKICAgICBlbHNlIGlmIChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoKQogICAgICAgd2lkdGggPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGg7ICAvLyBJRTYKICAgICBlbHNlIGlmIChkb2N1bWVudC5ib2R5ICYmIGRvY3VtZW50LmJvZHkuY2xpZW50V2lkdGgpCiAgICAgICB3aWR0aCA9IGRvY3VtZW50LmJvZHkuY2xpZW50V2lkdGg7IC8vIElFNAoKICAgICB2YXIgaGVpZ2h0ID0gMDsKCiAgICAgaWYgKCB0eXBlb2YoIHdpbmRvdy5pbm5lckhlaWdodCApID09ICdudW1iZXInICkKICAgICAgIGhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodDsgIC8vIE5vbiBJRSBicm93c2VyCiAgICAgZWxzZSBpZiAoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50ICYmIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQpCiAgICAgICBoZWlnaHQgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0OyAgLy8gSUU2CiAgICAgZWxzZSBpZiAoZG9jdW1lbnQuYm9keSAmJiBkb2N1bWVudC5ib2R5LmNsaWVudEhlaWdodCkKICAgICAgIGhlaWdodCA9IGRvY3VtZW50LmJvZHkuY2xpZW50SGVpZ2h0OyAvLyBJRTQKCiAgICAgaWYgKGhlaWdodCAmJiAod2lkdGgvaGVpZ2h0ID4gMS4wNSoxMDI0Lzc2OCkpCiAgICAgewogICAgICAgd2lkdGggPSBoZWlnaHQgKiAxMDI0LjAvNzY4OwogICAgIH0KCiAgICAgLy8gSUUgZmlyZXMgb25yZXNpemUgZXZlbiB3aGVuIG9ubHkgZm9udCBzaXplIGlzIGNoYW5nZWQhCiAgICAgLy8gc28gd2UgZG8gYSBjaGVjayB0byBhdm9pZCBibG9ja2luZyA8IGFuZCA+IGFjdGlvbnMKICAgICBpZiAod2lkdGggIT0gdzNjX3NsaWR5Lmxhc3Rfd2lkdGggfHwgaGVpZ2h0ICE9IHczY19zbGlkeS5sYXN0X2hlaWdodCkKICAgICB7CiAgICAgICBpZiAod2lkdGggPj0gMTEwMCkKICAgICAgICAgdzNjX3NsaWR5LnNpemVfaW5kZXggPSA1OyAgICAvLyA0CiAgICAgICBlbHNlIGlmICh3aWR0aCA+PSAxMDAwKQogICAgICAgICB3M2Nfc2xpZHkuc2l6ZV9pbmRleCA9IDQ7ICAgIC8vIDMKICAgICAgIGVsc2UgaWYgKHdpZHRoID49IDgwMCkKICAgICAgICAgdzNjX3NsaWR5LnNpemVfaW5kZXggPSAzOyAgICAvLyAyCiAgICAgICBlbHNlIGlmICh3aWR0aCA+PSA2MDApCiAgICAgICAgIHczY19zbGlkeS5zaXplX2luZGV4ID0gMjsgICAgLy8gMQogICAgICAgZWxzZSBpZiAod2lkdGgpCiAgICAgICAgIHczY19zbGlkeS5zaXplX2luZGV4ID0gMDsKCiAgICAgICAvLyBhZGQgaW4gZm9udCBzaXplIGFkanVzdG1lbnQgZnJvbSBtZXRhIGVsZW1lbnQgZS5nLgogICAgICAgLy8gPG1ldGEgbmFtZT0iZm9udC1zaXplLWFkanVzdG1lbnQiIGNvbnRlbnQ9Ii0yIiAvPgogICAgICAgLy8gdXNlZnVsIHdoZW4gc2xpZGVzIGhhdmUgdG9vIG11Y2ggY29udGVudCA7LSkKCiAgICAgICBpZiAoMCA8PSB3M2Nfc2xpZHkuc2l6ZV9pbmRleCArIHczY19zbGlkeS5zaXplX2FkanVzdG1lbnQgJiYKICAgICAgICAgICAgIHczY19zbGlkeS5zaXplX2luZGV4ICsgdzNjX3NsaWR5LnNpemVfYWRqdXN0bWVudCA8IHczY19zbGlkeS5zaXplcy5sZW5ndGgpCiAgICAgICAgIHczY19zbGlkeS5zaXplX2luZGV4ID0gdzNjX3NsaWR5LnNpemVfaW5kZXggKyB3M2Nfc2xpZHkuc2l6ZV9hZGp1c3RtZW50OwoKICAgICAgIC8vIGVuYWJsZXMgY3Jvc3MgYnJvd3NlciB1c2Ugb2YgcmVsYXRpdmUgd2lkdGgvaGVpZ2h0CiAgICAgICAvLyBvbiBvYmplY3QgZWxlbWVudHMgZm9yIHVzZSB3aXRoIFNWRyBhbmQgRmxhc2ggbWVkaWEKICAgICAgIHczY19zbGlkeS5hZGp1c3Rfb2JqZWN0X2RpbWVuc2lvbnMod2lkdGgsIGhlaWdodCk7CgogICAgICAgaWYgKGRvY3VtZW50LmJvZHkuc3R5bGUuZm9udFNpemUgIT0gdzNjX3NsaWR5LnNpemVzW3czY19zbGlkeS5zaXplX2luZGV4XSkKICAgICAgIHsKICAgICAgICAgZG9jdW1lbnQuYm9keS5zdHlsZS5mb250U2l6ZSA9IHczY19zbGlkeS5zaXplc1t3M2Nfc2xpZHkuc2l6ZV9pbmRleF07CiAgICAgICB9CgogICAgICAgdzNjX3NsaWR5Lmxhc3Rfd2lkdGggPSB3aWR0aDsKICAgICAgIHczY19zbGlkeS5sYXN0X2hlaWdodCA9IGhlaWdodDsKCiAgICAgICAvLyBmb3JjZSByZWZsb3cgdG8gd29yayBhcm91bmQgTW96aWxsYSBidWcKICAgICAgIGlmICh3M2Nfc2xpZHkubnNfcG9zKQogICAgICAgewogICAgICAgICB2YXIgc2xpZGUgPSB3M2Nfc2xpZHkuc2xpZGVzW3czY19zbGlkeS5zbGlkZV9udW1iZXJdOwogICAgICAgICB3M2Nfc2xpZHkuaGlkZV9zbGlkZShzbGlkZSk7CiAgICAgICAgIHczY19zbGlkeS5zaG93X3NsaWRlKHNsaWRlKTsKICAgICAgIH0KCiAgICAgICAvLyBmb3JjZSBjb3JyZWN0IHBvc2l0aW9uaW5nIG9mIHRvb2xiYXIKICAgICAgIHczY19zbGlkeS5yZWZyZXNoX3Rvb2xiYXIoMjAwKTsKICAgICB9CiAgfSwKCiAgc2Nyb2xsZWQ6IGZ1bmN0aW9uICgpIHsKICAgIGlmICh3M2Nfc2xpZHkudG9vbGJhciAmJiAhdzNjX3NsaWR5Lm5zX3BvcyAmJiAhdzNjX3NsaWR5LmllNykKICAgIHsKICAgICAgdzNjX3NsaWR5LmhhY2tfb2Zmc2V0ID0gdzNjX3NsaWR5LnNjcm9sbF94X29mZnNldCgpOwogICAgICAvLyBoaWRlIHRvb2xiYXIKICAgICAgdzNjX3NsaWR5LnRvb2xiYXIuc3R5bGUuZGlzcGxheSA9ICJub25lIjsKCiAgICAgIC8vIG1ha2UgaXQgcmVhcHBlYXIgbGF0ZXIKICAgICAgaWYgKHczY19zbGlkeS5zY3JvbGxoYWNrID09IDAgJiYgIXczY19zbGlkeS52aWV3X2FsbCkKICAgICAgewogICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge3czY19zbGlkeS5zaG93X3Rvb2xiYXIoKTsgfSwgMTAwMCk7CiAgICAgICAgdzNjX3NsaWR5LnNjcm9sbGhhY2sgPSAxOwogICAgICB9CiAgICB9CiAgfSwKCiAgaGlkZV90b29sYmFyOiBmdW5jdGlvbiAoKSB7CiAgICB3M2Nfc2xpZHkuYWRkX2NsYXNzKHczY19zbGlkeS50b29sYmFyLCAiaGlkZGVuIik7CiAgICB3aW5kb3cuZm9jdXMoKTsKICB9LAoKICAvLyB1c2VkIHRvIGVuc3VyZSBJRSByZWZyZXNoZXMgdG9vbGJhciBpbiBjb3JyZWN0IHBvc2l0aW9uCiAgcmVmcmVzaF90b29sYmFyOiBmdW5jdGlvbiAoaW50ZXJ2YWwpIHsKICAgIGlmICghdzNjX3NsaWR5Lm5zX3BvcyAmJiAhdzNjX3NsaWR5LmllNykKICAgIHsKICAgICAgdzNjX3NsaWR5LmhpZGVfdG9vbGJhcigpOwogICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHt3M2Nfc2xpZHkuc2hvd190b29sYmFyKCk7fSwgaW50ZXJ2YWwpOwogICAgfQogIH0sCgogIC8vIHJlc3RvcmVzIHRvb2xiYXIgYWZ0ZXIgc2hvcnQgZGVsYXkKICBzaG93X3Rvb2xiYXI6IGZ1bmN0aW9uICgpIHsKICAgIGlmICh3M2Nfc2xpZHkud2FudF90b29sYmFyKQogICAgewogICAgICB3M2Nfc2xpZHkudG9vbGJhci5zdHlsZS5kaXNwbGF5ID0gImJsb2NrIjsKCiAgICAgIGlmICghdzNjX3NsaWR5Lm5zX3BvcykKICAgICAgewogICAgICAgIC8vIGFkanVzdCBwb3NpdGlvbiB0byBhbGxvdyBmb3Igc2Nyb2xsaW5nCiAgICAgICAgdmFyIHhvZmZzZXQgPSB3M2Nfc2xpZHkuc2Nyb2xsX3hfb2Zmc2V0KCk7CiAgICAgICAgdzNjX3NsaWR5LnRvb2xiYXIuc3R5bGUubGVmdCA9IHhvZmZzZXQ7CiAgICAgICAgdzNjX3NsaWR5LnRvb2xiYXIuc3R5bGUucmlnaHQgPSB4b2Zmc2V0OwoKICAgICAgICAvLyBkZXRlcm1pbmUgdmVydGljYWwgc2Nyb2xsIG9mZnNldAogICAgICAgIC8vdmFyIHlvZmZzZXQgPSBzY3JvbGxZT2Zmc2V0KCk7CgogICAgICAgIC8vIGJvdHRvbSBpcyBkb2MgaGVpZ2h0IC0gd2luZG93IGhlaWdodCAtIHNjcm9sbCBvZmZzZXQKICAgICAgICAvL3ZhciBib3R0b20gPSBkb2N1bWVudEhlaWdodCgpIC0gbGFzdEhlaWdodCAtIHlvZmZzZXQKCiAgICAgICAgLy9pZiAoeW9mZnNldCA+IDAgfHwgZG9jdW1lbnRIZWlnaHQoKSA+IGxhc3RIZWlnaHQpCiAgICAgICAgLy8gICBib3R0b20gKz0gMTY7ICAvLyBhbGxvdyBmb3IgaGVpZ2h0IG9mIHNjcm9sbGJhcgoKICAgICAgICB3M2Nfc2xpZHkudG9vbGJhci5zdHlsZS5ib3R0b20gPSAwOyAvL2JvdHRvbTsKICAgICAgfQoKICAgICAgdzNjX3NsaWR5LnJlbW92ZV9jbGFzcyh3M2Nfc2xpZHkudG9vbGJhciwgImhpZGRlbiIpOwogICAgfQoKICAgIHczY19zbGlkeS5zY3JvbGxoYWNrID0gMDsKCgogICAgLy8gc2V0IHRoZSBrZXlib2FyZCBmb2N1cyB0byB0aGUgaGVscCBsaW5rIG9uIHRoZQogICAgLy8gdG9vbGJhciB0byBlbnN1cmUgdGhhdCBkb2N1bWVudCBoYXMgdGhlIGZvY3VzCiAgICAvLyBJRSBkb2Vzbid0IGFsd2F5cyB3b3JrIHdpdGggd2luZG93LmZvY3VzKCkKICAgIC8vIGFuZCB0aGlzIGhhY2sgaGFzIGJlbmVmaXQgb2YgRW50ZXIgZm9yIGhlbHAKCiAgICB0cnkKICAgIHsKICAgICAgaWYgKCF3M2Nfc2xpZHkub3BlcmEpCiAgICAgICAgdzNjX3NsaWR5LnNldF9mb2N1cygpOwogICAgfQogICAgY2F0Y2ggKGUpCiAgICB7CiAgICB9CiAgfSwKCi8vIGludm9rZWQgdmlhIEYga2V5CiAgdG9nZ2xlX3Rvb2xiYXI6IGZ1bmN0aW9uICgpIHsKICAgIGlmICghdzNjX3NsaWR5LnZpZXdfYWxsKQogICAgewogICAgICBpZiAodzNjX3NsaWR5Lmhhc19jbGFzcyh3M2Nfc2xpZHkudG9vbGJhciwgImhpZGRlbiIpKQogICAgICB7CiAgICAgICAgdzNjX3NsaWR5LnJlbW92ZV9jbGFzcyh3M2Nfc2xpZHkudG9vbGJhciwgImhpZGRlbiIpCiAgICAgICAgdzNjX3NsaWR5LndhbnRfdG9vbGJhciA9IDE7CiAgICAgIH0KICAgICAgZWxzZQogICAgICB7CiAgICAgICAgdzNjX3NsaWR5LmFkZF9jbGFzcyh3M2Nfc2xpZHkudG9vbGJhciwgImhpZGRlbiIpCiAgICAgICAgdzNjX3NsaWR5LndhbnRfdG9vbGJhciA9IDA7CiAgICAgIH0KICAgIH0KICB9LAoKICBzY3JvbGxfeF9vZmZzZXQ6IGZ1bmN0aW9uICgpIHsKICAgIGlmICh3aW5kb3cucGFnZVhPZmZzZXQpCiAgICAgIHJldHVybiBzZWxmLnBhZ2VYT2Zmc2V0OwoKICAgIGlmIChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgJiYgCiAgICAgICAgICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsTGVmdCkKICAgICAgcmV0dXJuIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0OwoKICAgIGlmIChkb2N1bWVudC5ib2R5KQogICAgICByZXR1cm4gZG9jdW1lbnQuYm9keS5zY3JvbGxMZWZ0OwoKICAgIHJldHVybiAwOwogIH0sCgogIHNjcm9sbF95X29mZnNldDogZnVuY3Rpb24gKCkgewogICAgaWYgKHdpbmRvdy5wYWdlWU9mZnNldCkKICAgICAgcmV0dXJuIHNlbGYucGFnZVlPZmZzZXQ7CgogICAgaWYgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCAmJiAKICAgICAgICAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3ApCiAgICAgIHJldHVybiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsVG9wOwoKICAgIGlmIChkb2N1bWVudC5ib2R5KQogICAgICByZXR1cm4gZG9jdW1lbnQuYm9keS5zY3JvbGxUb3A7CgogICAgcmV0dXJuIDA7CiAgfSwKCiAgLy8gbG9va2luZyBmb3IgYSB3YXkgdG8gZGV0ZXJtaW5lIGhlaWdodCBvZiBzbGlkZSBjb250ZW50CiAgLy8gdGhlIHNsaWRlIGl0c2VsZiBpcyBzZXQgdG8gdGhlIGhlaWdodCBvZiB0aGUgd2luZG93CiAgb3B0aW1pemVfZm9udF9zaXplOiBmdW5jdGlvbiAoKSB7CiAgICB2YXIgc2xpZGUgPSB3M2Nfc2xpZHkuc2xpZGVzW3czY19zbGlkeS5zbGlkZV9udW1iZXJdOwoKICAgIC8vdmFyIGRoID0gZG9jdW1lbnRIZWlnaHQoKTsgLy9nZXREb2NIZWlnaHQoZG9jdW1lbnQpOwogICAgdmFyIGRoID0gc2xpZGUuc2Nyb2xsSGVpZ2h0OwogICAgdmFyIHdoID0gZ2V0V2luZG93SGVpZ2h0KCk7CiAgICB2YXIgdSA9IDEwMCAqIGRoIC8gd2g7CgogICAgYWxlcnQoIndpbmRvdyB1dGlsaXphdGlvbiA9ICIgKyB1ICsgIiUgKGRvYyAiCiAgICAgICsgZGggKyAiIHdpbiAiICsgd2ggKyAiKSIpOwogIH0sCgogIC8vIGZyb20gZG9jdW1lbnQgb2JqZWN0CiAgZ2V0X2RvY19oZWlnaHQ6IGZ1bmN0aW9uIChkb2MpIHsKICAgIGlmICghZG9jKQogICAgICBkb2MgPSBkb2N1bWVudDsKCiAgICBpZiAoZG9jICYmIGRvYy5ib2R5ICYmIGRvYy5ib2R5Lm9mZnNldEhlaWdodCkKICAgICAgcmV0dXJuIGRvYy5ib2R5Lm9mZnNldEhlaWdodDsgIC8vIG5zL2dlY2tvIHN5bnRheAoKICAgIGlmIChkb2MgJiYgZG9jLmJvZHkgJiYgZG9jLmJvZHkuc2Nyb2xsSGVpZ2h0KQogICAgICByZXR1cm4gZG9jLmJvZHkuc2Nyb2xsSGVpZ2h0OwoKICAgIGFsZXJ0KCJjb3VsZG4ndCBkZXRlcm1pbmUgZG9jdW1lbnQgaGVpZ2h0Iik7CiAgfSwKCiAgZ2V0X3dpbmRvd19oZWlnaHQ6IGZ1bmN0aW9uICgpIHsKICAgIGlmICggdHlwZW9mKCB3aW5kb3cuaW5uZXJIZWlnaHQgKSA9PSAnbnVtYmVyJyApCiAgICAgIHJldHVybiB3aW5kb3cuaW5uZXJIZWlnaHQ7ICAvLyBOb24gSUUgYnJvd3NlcgoKICAgIGlmIChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCkKICAgICAgcmV0dXJuIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQ7ICAvLyBJRTYKCiAgICBpZiAoZG9jdW1lbnQuYm9keSAmJiBkb2N1bWVudC5ib2R5LmNsaWVudEhlaWdodCkKICAgICAgcmV0dXJuIGRvY3VtZW50LmJvZHkuY2xpZW50SGVpZ2h0OyAvLyBJRTQKICB9LAoKICBkb2N1bWVudF9oZWlnaHQ6IGZ1bmN0aW9uICgpIHsKICAgIHZhciBzaCwgb2g7CgogICAgc2ggPSBkb2N1bWVudC5ib2R5LnNjcm9sbEhlaWdodDsKICAgIG9oID0gZG9jdW1lbnQuYm9keS5vZmZzZXRIZWlnaHQ7CgogICAgaWYgKHNoICYmIG9oKQogICAgewogICAgICByZXR1cm4gKHNoID4gb2ggPyBzaCA6IG9oKTsKICAgIH0KCiAgICAvLyBubyBpZGVhIQogICAgcmV0dXJuIDA7CiAgfSwKCiAgc21hbGxlcjogZnVuY3Rpb24gKCkgewogICAgaWYgKHczY19zbGlkeS5zaXplX2luZGV4ID4gMCkKICAgIHsKICAgICAgLS13M2Nfc2xpZHkuc2l6ZV9pbmRleDsKICAgIH0KCiAgICB3M2Nfc2xpZHkudG9vbGJhci5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOwogICAgZG9jdW1lbnQuYm9keS5zdHlsZS5mb250U2l6ZSA9IHczY19zbGlkeS5zaXplc1t3M2Nfc2xpZHkuc2l6ZV9pbmRleF07CiAgICB2YXIgc2xpZGUgPSB3M2Nfc2xpZHkuc2xpZGVzW3czY19zbGlkeS5zbGlkZV9udW1iZXJdOwogICAgdzNjX3NsaWR5LmhpZGVfc2xpZGUoc2xpZGUpOwogICAgdzNjX3NsaWR5LnNob3dfc2xpZGUoc2xpZGUpOwogICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7dzNjX3NsaWR5LnNob3dfdG9vbGJhcigpOyB9LCA1MCk7CiAgfSwKCiAgYmlnZ2VyOiBmdW5jdGlvbiAoKSB7CiAgICBpZiAodzNjX3NsaWR5LnNpemVfaW5kZXggPCB3M2Nfc2xpZHkuc2l6ZXMubGVuZ3RoIC0gMSkKICAgIHsKICAgICAgKyt3M2Nfc2xpZHkuc2l6ZV9pbmRleDsKICAgIH0KCiAgICB3M2Nfc2xpZHkudG9vbGJhci5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOwogICAgZG9jdW1lbnQuYm9keS5zdHlsZS5mb250U2l6ZSA9IHczY19zbGlkeS5zaXplc1t3M2Nfc2xpZHkuc2l6ZV9pbmRleF07CiAgICB2YXIgc2xpZGUgPSB3M2Nfc2xpZHkuc2xpZGVzW3czY19zbGlkeS5zbGlkZV9udW1iZXJdOwogICAgdzNjX3NsaWR5LmhpZGVfc2xpZGUoc2xpZGUpOwogICAgdzNjX3NsaWR5LnNob3dfc2xpZGUoc2xpZGUpOwogICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7dzNjX3NsaWR5LnNob3dfdG9vbGJhcigpOyB9LCA1MCk7CiAgfSwKCiAgLy8gZW5hYmxlcyBjcm9zcyBicm93c2VyIHVzZSBvZiByZWxhdGl2ZSB3aWR0aC9oZWlnaHQKICAvLyBvbiBvYmplY3QgZWxlbWVudHMgZm9yIHVzZSB3aXRoIFNWRyBhbmQgRmxhc2ggbWVkaWEKICAvLyB3aXRoIHRoYW5rcyB0byBJdmFuIEhlcm1hbiBmb3IgdGhlIHN1Z2dlc3Rpb24KICBhZGp1c3Rfb2JqZWN0X2RpbWVuc2lvbnM6IGZ1bmN0aW9uICh3aWR0aCwgaGVpZ2h0KSB7CiAgICBmb3IoIHZhciBpID0gMDsgaSA8IHczY19zbGlkeS5vYmplY3RzLmxlbmd0aDsgaSsrICkKICAgIHsKICAgICAgdmFyIG9iaiA9IHRoaXMub2JqZWN0c1tpXTsKICAgICAgdmFyIG1pbWVUeXBlID0gb2JqLmdldEF0dHJpYnV0ZSgidHlwZSIpOwoKICAgICAgaWYgKG1pbWVUeXBlID09ICJpbWFnZS9zdmcreG1sIiB8fCBtaW1lVHlwZSA9PSAiYXBwbGljYXRpb24veC1zaG9ja3dhdmUtZmxhc2giKQogICAgICB7CiAgICAgICAgaWYgKCAhb2JqLmluaXRpYWxXaWR0aCApIAogICAgICAgICAgb2JqLmluaXRpYWxXaWR0aCA9IG9iai5nZXRBdHRyaWJ1dGUoIndpZHRoIik7CgogICAgICAgIGlmICggIW9iai5pbml0aWFsSGVpZ2h0ICkgCiAgICAgICAgICBvYmouaW5pdGlhbEhlaWdodCA9IG9iai5nZXRBdHRyaWJ1dGUoImhlaWdodCIpOwoKICAgICAgICBpZiAoIG9iai5pbml0aWFsV2lkdGggJiYgb2JqLmluaXRpYWxXaWR0aC5jaGFyQXQob2JqLmluaXRpYWxXaWR0aC5sZW5ndGgtMSkgPT0gIiUiICkKICAgICAgICB7CiAgICAgICAgICB2YXIgdyA9IHBhcnNlSW50KG9iai5pbml0aWFsV2lkdGguc2xpY2UoMCwgb2JqLmluaXRpYWxXaWR0aC5sZW5ndGgtMSkpOwogICAgICAgICAgdmFyIG5ld1cgPSB3aWR0aCAqICh3LzEwMC4wKTsKICAgICAgICAgIG9iai5zZXRBdHRyaWJ1dGUoIndpZHRoIixuZXdXKTsKICAgICAgICB9CgogICAgICAgIGlmICggb2JqLmluaXRpYWxIZWlnaHQgJiYKICAgICAgICAgICAgIG9iai5pbml0aWFsSGVpZ2h0LmNoYXJBdChvYmouaW5pdGlhbEhlaWdodC5sZW5ndGgtMSkgPT0gIiUiICkKICAgICAgICB7CiAgICAgICAgICB2YXIgaCA9IHBhcnNlSW50KG9iai5pbml0aWFsSGVpZ2h0LnNsaWNlKDAsIG9iai5pbml0aWFsSGVpZ2h0Lmxlbmd0aC0xKSk7CiAgICAgICAgICB2YXIgbmV3SCA9IGhlaWdodCAqIChoLzEwMC4wKTsKICAgICAgICAgIG9iai5zZXRBdHRyaWJ1dGUoImhlaWdodCIsIG5ld0gpOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0sCgogIC8vIG5lZWRlZCBmb3IgT3BlcmEgdG8gaW5oaWJpdCBkZWZhdWx0IGJlaGF2aW9yCiAgLy8gc2luY2UgT3BlcmEgZGVsaXZlcnMga2V5UHJlc3MgZXZlbiBpZiBrZXlEb3duCiAgLy8gd2FzIGNhbmNlbGxlZAogIGtleV9wcmVzczogZnVuY3Rpb24gKGV2ZW50KSB7CiAgICBpZiAoIWV2ZW50KQogICAgICBldmVudCA9IHdpbmRvdy5ldmVudDsKCiAgICBpZiAoIXczY19zbGlkeS5rZXlfd2FudGVkKQogICAgICByZXR1cm4gdzNjX3NsaWR5LmNhbmNlbChldmVudCk7CgogICAgcmV0dXJuIHRydWU7CiAgfSwKCiAgLy8gIFNlZSBlLmcuIGh0dHA6Ly93d3cucXVpcmtzbW9kZS5vcmcvanMvZXZlbnRzL2tleXMuaHRtbCBmb3Iga2V5Y29kZXMKICBrZXlfZG93bjogZnVuY3Rpb24gKGV2ZW50KSB7CiAgICB2YXIga2V5LCB0YXJnZXQsIHRhZzsKCiAgICB3M2Nfc2xpZHkua2V5X3dhbnRlZCA9IHRydWU7CgogICAgaWYgKCFldmVudCkKICAgICAgZXZlbnQgPSB3aW5kb3cuZXZlbnQ7CgogICAgLy8ga2x1ZGdlIGFyb3VuZCBOUy9JRSBkaWZmZXJlbmNlcyAKICAgIGlmICh3aW5kb3cuZXZlbnQpCiAgICB7CiAgICAgIGtleSA9IHdpbmRvdy5ldmVudC5rZXlDb2RlOwogICAgICB0YXJnZXQgPSB3aW5kb3cuZXZlbnQuc3JjRWxlbWVudDsKICAgIH0KICAgIGVsc2UgaWYgKGV2ZW50LndoaWNoKQogICAgewogICAgICBrZXkgPSBldmVudC53aGljaDsKICAgICAgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0OwogICAgfQogICAgZWxzZQogICAgICByZXR1cm4gdHJ1ZTsgLy8gWWlrZXMhIHVua25vd24gYnJvd3NlcgoKICAgIC8vIGlnbm9yZSBldmVudCBpZiBrZXkgdmFsdWUgaXMgemVybwogICAgLy8gYXMgZm9yIGFsdCBvbiBPcGVyYSBhbmQgS29ucXVlcm9yCiAgICBpZiAoIWtleSkKICAgICAgIHJldHVybiB0cnVlOwoKICAgIC8vIGF2b2lkIGludGVyZmVyaW5nIHdpdGgga2V5c3Ryb2tlCiAgICAvLyBiZWhhdmlvciBmb3Igbm9uLXNsaWR5IGNocm9tZSBlbGVtZW50cwogICAgaWYgKCF3M2Nfc2xpZHkuc2xpZHlfY2hyb21lKHRhcmdldCkgJiYKICAgICAgICB3M2Nfc2xpZHkuc3BlY2lhbF9lbGVtZW50KHRhcmdldCkpCiAgICAgIHJldHVybiB0cnVlOwoKICAgIC8vIGNoZWNrIGZvciBjb25jdXJyZW50IGNvbnRyb2wvY29tbWFuZC9hbHQga2V5CiAgICAvLyBidXQgYXJlIHRoZXNlIG9ubHkgcHJlc2VudCBvbiBtb3VzZSBldmVudHM/CgogICAgaWYgKGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQuYWx0S2V5IHx8IGV2ZW50Lm1ldGFLZXkpCiAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICAvLyBkaXNtaXNzIHRhYmxlIG9mIGNvbnRlbnRzIGlmIHZpc2libGUKICAgIGlmICh3M2Nfc2xpZHkuaXNfc2hvd25fdG9jKCkgJiYga2V5ICE9IDkgJiYga2V5ICE9IDE2ICYmIGtleSAhPSAzOCAmJiBrZXkgIT0gNDApCiAgICB7CiAgICAgIHczY19zbGlkeS5oaWRlX3RhYmxlX29mX2NvbnRlbnRzKHRydWUpOwoKICAgICAgaWYgKGtleSA9PSAyNyB8fCBrZXkgPT0gODQgfHwga2V5ID09IDY3KQogICAgICAgIHJldHVybiB3M2Nfc2xpZHkuY2FuY2VsKGV2ZW50KTsKICAgIH0KCiAgICBpZiAoa2V5ID09IDM0KSAvLyBQYWdlIERvd24KICAgIHsKICAgICAgaWYgKHczY19zbGlkeS52aWV3X2FsbCkKICAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICAgIHczY19zbGlkeS5uZXh0X3NsaWRlKGZhbHNlKTsKICAgICAgcmV0dXJuIHczY19zbGlkeS5jYW5jZWwoZXZlbnQpOwogICAgfQogICAgZWxzZSBpZiAoa2V5ID09IDMzKSAvLyBQYWdlIFVwCiAgICB7CiAgICAgIGlmICh3M2Nfc2xpZHkudmlld19hbGwpCiAgICAgICAgcmV0dXJuIHRydWU7CgogICAgICB3M2Nfc2xpZHkucHJldmlvdXNfc2xpZGUoZmFsc2UpOwogICAgICByZXR1cm4gdzNjX3NsaWR5LmNhbmNlbChldmVudCk7CiAgICB9CiAgICBlbHNlIGlmIChrZXkgPT0gMzIpIC8vIHNwYWNlIGJhcgogICAgewogICAgICB3M2Nfc2xpZHkubmV4dF9zbGlkZSh0cnVlKTsKICAgICAgcmV0dXJuIHczY19zbGlkeS5jYW5jZWwoZXZlbnQpOwogICAgfQogICAgZWxzZSBpZiAoa2V5ID09IDM3KSAvLyBMZWZ0IGFycm93CiAgICB7CiAgICAgIHczY19zbGlkeS5wcmV2aW91c19zbGlkZSghZXZlbnQuc2hpZnRLZXkpOwogICAgICByZXR1cm4gdzNjX3NsaWR5LmNhbmNlbChldmVudCk7CiAgICB9CiAgICBlbHNlIGlmIChrZXkgPT0gMzYpIC8vIEhvbWUKICAgIHsKICAgICAgdzNjX3NsaWR5LmZpcnN0X3NsaWRlKCk7CiAgICAgIHJldHVybiB3M2Nfc2xpZHkuY2FuY2VsKGV2ZW50KTsKICAgIH0KICAgIGVsc2UgaWYgKGtleSA9PSAzNSkgLy8gRW5kCiAgICB7CiAgICAgIHczY19zbGlkeS5sYXN0X3NsaWRlKCk7CiAgICAgIHJldHVybiB3M2Nfc2xpZHkuY2FuY2VsKGV2ZW50KTsKICAgIH0KICAgIGVsc2UgaWYgKGtleSA9PSAzOSkgLy8gUmlnaHQgYXJyb3cKICAgIHsKICAgICAgdzNjX3NsaWR5Lm5leHRfc2xpZGUoIWV2ZW50LnNoaWZ0S2V5KTsKICAgICAgcmV0dXJuIHczY19zbGlkeS5jYW5jZWwoZXZlbnQpOwogICAgfQogICAgZWxzZSBpZiAoa2V5ID09IDEzKSAvLyBFbnRlcgogICAgewogICAgICBpZiAodzNjX3NsaWR5Lm91dGxpbmUpCiAgICAgIHsKICAgICAgICBpZiAodzNjX3NsaWR5Lm91dGxpbmUudmlzaWJsZSkKICAgICAgICAgIHczY19zbGlkeS5mb2xkKHczY19zbGlkeS5vdXRsaW5lKTsKICAgICAgICBlbHNlCiAgICAgICAgICB3M2Nfc2xpZHkudW5mb2xkKHczY19zbGlkeS5vdXRsaW5lKTsKICAgICAgICAgIAogICAgICAgcmV0dXJuIHczY19zbGlkeS5jYW5jZWwoZXZlbnQpOwogICAgICB9CiAgICB9CiAgICBlbHNlIGlmIChrZXkgPT0gMTg4KSAgLy8gPCBmb3Igc21hbGxlciBmb250cwogICAgewogICAgICB3M2Nfc2xpZHkuc21hbGxlcigpOwogICAgICByZXR1cm4gdzNjX3NsaWR5LmNhbmNlbChldmVudCk7CiAgICB9CiAgICBlbHNlIGlmIChrZXkgPT0gMTkwKSAgLy8gPiBmb3IgbGFyZ2VyIGZvbnRzCiAgICB7CiAgICAgIHczY19zbGlkeS5iaWdnZXIoKTsKICAgICAgcmV0dXJuIHczY19zbGlkeS5jYW5jZWwoZXZlbnQpOwogICAgfQogICAgZWxzZSBpZiAoa2V5ID09IDE4OSB8fCBrZXkgPT0gMTA5KSAgLy8gLSBmb3Igc21hbGxlciBmb250cwogICAgewogICAgICB3M2Nfc2xpZHkuc21hbGxlcigpOwogICAgICByZXR1cm4gdzNjX3NsaWR5LmNhbmNlbChldmVudCk7CiAgICB9CiAgICBlbHNlIGlmIChrZXkgPT0gMTg3IHx8IGtleSA9PSAxOTEgfHwga2V5ID09IDEwNykgIC8vID0gKyAgZm9yIGxhcmdlciBmb250cwogICAgewogICAgICB3M2Nfc2xpZHkuYmlnZ2VyKCk7CiAgICAgIHJldHVybiB3M2Nfc2xpZHkuY2FuY2VsKGV2ZW50KTsKICAgIH0KICAgIGVsc2UgaWYgKGtleSA9PSA4MykgIC8vIFMgZm9yIHNtYWxsZXIgZm9udHMKICAgIHsKICAgICAgdzNjX3NsaWR5LnNtYWxsZXIoKTsKICAgICAgcmV0dXJuIHczY19zbGlkeS5jYW5jZWwoZXZlbnQpOwogICAgfQogICAgZWxzZSBpZiAoa2V5ID09IDY2KSAgLy8gQiBmb3IgbGFyZ2VyIGZvbnRzCiAgICB7CiAgICAgIHczY19zbGlkeS5iaWdnZXIoKTsKICAgICAgcmV0dXJuIHczY19zbGlkeS5jYW5jZWwoZXZlbnQpOwogICAgfQogICAgZWxzZSBpZiAoa2V5ID09IDkwKSAgLy8gWiBmb3IgbGFzdCBzbGlkZQogICAgewogICAgICB3M2Nfc2xpZHkubGFzdF9zbGlkZSgpOwogICAgICByZXR1cm4gdzNjX3NsaWR5LmNhbmNlbChldmVudCk7CiAgICB9CiAgICBlbHNlIGlmIChrZXkgPT0gNzApICAvLyBGIGZvciB0b2dnbGUgdG9vbGJhcgogICAgewogICAgICB3M2Nfc2xpZHkudG9nZ2xlX3Rvb2xiYXIoKTsKICAgICAgcmV0dXJuIHczY19zbGlkeS5jYW5jZWwoZXZlbnQpOwogICAgfQogICAgZWxzZSBpZiAoa2V5ID09IDY1KSAgLy8gQSBmb3IgdG9nZ2xlIHZpZXcgc2luZ2xlL2FsbCBzbGlkZXMKICAgIHsKICAgICAgdzNjX3NsaWR5LnRvZ2dsZV92aWV3KCk7CiAgICAgIHJldHVybiB3M2Nfc2xpZHkuY2FuY2VsKGV2ZW50KTsKICAgIH0KICAgIGVsc2UgaWYgKGtleSA9PSA3NSkgIC8vIHRvZ2dsZSBhY3Rpb24gb2YgbGVmdCBjbGljayBmb3IgbmV4dCBwYWdlCiAgICB7CiAgICAgIHczY19zbGlkeS5tb3VzZV9jbGlja19lbmFibGVkID0gIXczY19zbGlkeS5tb3VzZV9jbGlja19lbmFibGVkOwogICAgICB2YXIgYWxlcnRfbXNnID0gKHczY19zbGlkeS5tb3VzZV9jbGlja19lbmFibGVkID8KICAgICAgICAgICAgICAgICJlbmFibGVkIiA6ICJkaXNhYmxlZCIpICsgICIgbW91c2UgY2xpY2sgYWR2YW5jZSI7CgogICAgICBhbGVydCh3M2Nfc2xpZHkubG9jYWxpemUoYWxlcnRfbXNnKSk7CiAgICAgIHJldHVybiB3M2Nfc2xpZHkuY2FuY2VsKGV2ZW50KTsKICAgIH0KICAgIGVsc2UgaWYgKGtleSA9PSA4NCB8fCBrZXkgPT0gNjcpICAvLyBUIG9yIEMgZm9yIHRhYmxlIG9mIGNvbnRlbnRzCiAgICB7CiAgICAgIGlmICh3M2Nfc2xpZHkudG9jKQogICAgICAgIHczY19zbGlkeS50b2dnbGVfdGFibGVfb2ZfY29udGVudHMoKTsKCiAgICAgIHJldHVybiB3M2Nfc2xpZHkuY2FuY2VsKGV2ZW50KTsKICAgIH0KICAgIGVsc2UgaWYgKGtleSA9PSA3MikgLy8gSCBmb3IgaGVscAogICAgewogICAgICB3aW5kb3cubG9jYXRpb24gPSB3M2Nfc2xpZHkuaGVscF9wYWdlOwogICAgICByZXR1cm4gdzNjX3NsaWR5LmNhbmNlbChldmVudCk7CiAgICB9CiAgICAvL2Vsc2UgYWxlcnQoImtleSBjb2RlIGlzICIrIGtleSk7CgogICAgcmV0dXJuIHRydWU7CiAgfSwKCiAgLy8gc2FmZSBmb3IgYm90aCB0ZXh0L2h0bWwgYW5kIGFwcGxpY2F0aW9uL3hodG1sK3htbAogIGNyZWF0ZV9lbGVtZW50OiBmdW5jdGlvbiAobmFtZSkgewogICAgaWYgKHRoaXMueGh0bWwgJiYgKHR5cGVvZiBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMgIT0gJ3VuZGVmaW5lZCcpKQogICAgICByZXR1cm4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiwgbmFtZSkKCiAgICByZXR1cm4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChuYW1lKTsKICB9LAoKICBnZXRfZWxlbWVudF9zdHlsZTogZnVuY3Rpb24gKGVsZW0sIElFU3R5bGVQcm9wLCBDU1NTdHlsZVByb3ApIHsKICAgIGlmIChlbGVtLmN1cnJlbnRTdHlsZSkKICAgIHsKICAgICAgcmV0dXJuIGVsZW0uY3VycmVudFN0eWxlW0lFU3R5bGVQcm9wXTsKICAgIH0KICAgIGVsc2UgaWYgKHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKQogICAgewogICAgICB2YXIgY29tcFN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWxlbSwgIiIpOwogICAgICByZXR1cm4gY29tcFN0eWxlLmdldFByb3BlcnR5VmFsdWUoQ1NTU3R5bGVQcm9wKTsKICAgIH0KICAgIHJldHVybiAiIjsKICB9LAoKICAvLyB0aGUgc3RyaW5nIHN0ciBpcyBhIHdoaXRlc3BhY2Ugc2VwYXJhdGVkIGxpc3Qgb2YgdG9rZW5zCiAgLy8gdGVzdCBpZiBzdHIgY29udGFpbnMgYSBwYXJ0aWN1bGFyIHRva2VuLCBlLmcuICJzbGlkZSIKICBoYXNfdG9rZW46IGZ1bmN0aW9uIChzdHIsIHRva2VuKSB7CiAgICBpZiAoc3RyKQogICAgewogICAgICAvLyBkZWZpbmUgcGF0dGVybiBhcyByZWd1bGFyIGV4cHJlc3Npb24KICAgICAgdmFyIHBhdHRlcm4gPSAvXHcrL2c7CgogICAgICAvLyBjaGVjayBmb3IgbWF0Y2hlcwogICAgICAvLyBwbGFjZSByZXN1bHQgaW4gYXJyYXkKICAgICAgdmFyIHJlc3VsdCA9IHN0ci5tYXRjaChwYXR0ZXJuKTsKCiAgICAgIC8vIG5vdyBjaGVjayBpZiBkZXNpcmVkIHRva2VuIGlzIHByZXNlbnQKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZXN1bHQubGVuZ3RoOyBpKyspCiAgICAgIHsKICAgICAgICBpZiAocmVzdWx0W2ldID09IHRva2VuKQogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gZmFsc2U7CiAgfSwKCiAgZ2V0X2NsYXNzX2xpc3Q6IGZ1bmN0aW9uIChlbGVtZW50KSB7CiAgICBpZiAodHlwZW9mIGVsZW1lbnQuY2xhc3NOYW1lICE9ICd1bmRlZmluZWQnKQogICAgICByZXR1cm4gZWxlbWVudC5jbGFzc05hbWU7CgogICAgcmV0dXJuIGVsZW1lbnQuZ2V0QXR0cmlidXRlKCJjbGFzcyIpOwogIH0sCgogIGhhc19jbGFzczogZnVuY3Rpb24gKGVsZW1lbnQsIG5hbWUpIHsKICAgIGlmIChlbGVtZW50Lm5vZGVUeXBlICE9IDEpCiAgICAgIHJldHVybiBmYWxzZTsKCiAgICB2YXIgcmVnZXhwID0gbmV3IFJlZ0V4cCgiKF58ICkiICsgbmFtZSArICJcVyoiKTsKCiAgICBpZiAodHlwZW9mIGVsZW1lbnQuY2xhc3NOYW1lICE9ICd1bmRlZmluZWQnKQogICAgICByZXR1cm4gcmVnZXhwLnRlc3QoZWxlbWVudC5jbGFzc05hbWUpOwoKICAgIHJldHVybiByZWdleHAudGVzdChlbGVtZW50LmdldEF0dHJpYnV0ZSgiY2xhc3MiKSk7CiAgfSwKCiAgcmVtb3ZlX2NsYXNzOiBmdW5jdGlvbiAoZWxlbWVudCwgbmFtZSkgewogICAgdmFyIHJlZ2V4cCA9IG5ldyBSZWdFeHAoIihefCApIiArIG5hbWUgKyAiXFcqIik7CiAgICB2YXIgY2xzdmFsID0gIiI7CgogICAgaWYgKHR5cGVvZiBlbGVtZW50LmNsYXNzTmFtZSAhPSAndW5kZWZpbmVkJykKICAgIHsKICAgICAgY2xzdmFsID0gZWxlbWVudC5jbGFzc05hbWU7CgogICAgICBpZiAoY2xzdmFsKQogICAgICB7CiAgICAgICAgY2xzdmFsID0gY2xzdmFsLnJlcGxhY2UocmVnZXhwLCAiIik7CiAgICAgICAgZWxlbWVudC5jbGFzc05hbWUgPSBjbHN2YWw7CiAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgY2xzdmFsID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoImNsYXNzIik7CgogICAgICBpZiAoY2xzdmFsKQogICAgICB7CiAgICAgICAgY2xzdmFsID0gY2xzdmFsLnJlcGxhY2UocmVnZXhwLCAiIik7CiAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoImNsYXNzIiwgY2xzdmFsKTsKICAgICAgfQogICAgfQogIH0sCgogIGFkZF9jbGFzczogZnVuY3Rpb24gKGVsZW1lbnQsIG5hbWUpIHsKICAgIGlmICghdGhpcy5oYXNfY2xhc3MoZWxlbWVudCwgbmFtZSkpCiAgICB7CiAgICAgIGlmICh0eXBlb2YgZWxlbWVudC5jbGFzc05hbWUgIT0gJ3VuZGVmaW5lZCcpCiAgICAgICAgZWxlbWVudC5jbGFzc05hbWUgKz0gIiAiICsgbmFtZTsKICAgICAgZWxzZQogICAgICB7CiAgICAgICAgdmFyIGNsc3ZhbCA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCJjbGFzcyIpOwogICAgICAgIGNsc3ZhbCA9IGNsc3ZhbCA/IGNsc3ZhbCArICIgIiArIG5hbWUgOiBuYW1lOwogICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCJjbGFzcyIsIGNsc3ZhbCk7CiAgICAgIH0KICAgIH0KICB9LAoKICAvLyBIVE1MIGVsZW1lbnRzIHRoYXQgY2FuIGJlIHVzZWQgd2l0aCBjbGFzcz0iaW5jcmVtZW50YWwiCiAgLy8gbm90ZSB0aGF0IHlvdSBjYW4gYWxzbyBwdXQgdGhlIGNsYXNzIG9uIGNvbnRhaW5lcnMgbGlrZQogIC8vIHVwLCBvbCwgZGwsIGFuZCBkaXYgdG8gbWFrZSB0aGVpciBjb250ZW50cyBhcHBlYXIKICAvLyBpbmNyZW1lbnRhbGx5LiBVcHBlciBjYXNlIGlzIHVzZWQgc2luY2UgdGhpcyBpcyB3aGF0CiAgLy8gYnJvd3NlcnMgcmVwb3J0IGZvciBIVE1MIG5vZGUgbmFtZXMgKHRleHQvaHRtbCkuCiAgaW5jcmVtZW50YWxfZWxlbWVudHM6IG51bGwsCiAgb2theV9mb3JfaW5jcmVtZW50YWw6IGZ1bmN0aW9uIChuYW1lKSB7CiAgICBpZiAoIXRoaXMuaW5jcmVtZW50YWxfZWxlbWVudHMpCiAgICB7CiAgICAgIHZhciBpbmNsaXN0ID0gbmV3IEFycmF5KCk7CiAgICAgIGluY2xpc3RbInAiXSA9IHRydWU7CiAgICAgIGluY2xpc3RbInByZSJdID0gdHJ1ZTsKICAgICAgaW5jbGlzdFsibGkiXSA9IHRydWU7CiAgICAgIGluY2xpc3RbImJsb2NrcXVvdGUiXSA9IHRydWU7CiAgICAgIGluY2xpc3RbImR0Il0gPSB0cnVlOwogICAgICBpbmNsaXN0WyJkZCJdID0gdHJ1ZTsKICAgICAgaW5jbGlzdFsiaDIiXSA9IHRydWU7CiAgICAgIGluY2xpc3RbImgzIl0gPSB0cnVlOwogICAgICBpbmNsaXN0WyJoNCJdID0gdHJ1ZTsKICAgICAgaW5jbGlzdFsiaDUiXSA9IHRydWU7CiAgICAgIGluY2xpc3RbImg2Il0gPSB0cnVlOwogICAgICBpbmNsaXN0WyJzcGFuIl0gPSB0cnVlOwogICAgICBpbmNsaXN0WyJhZGRyZXNzIl0gPSB0cnVlOwogICAgICBpbmNsaXN0WyJ0YWJsZSJdID0gdHJ1ZTsKICAgICAgaW5jbGlzdFsidHIiXSA9IHRydWU7CiAgICAgIGluY2xpc3RbInRoIl0gPSB0cnVlOwogICAgICBpbmNsaXN0WyJ0ZCJdID0gdHJ1ZTsKICAgICAgaW5jbGlzdFsiaW1nIl0gPSB0cnVlOwogICAgICBpbmNsaXN0WyJvYmplY3QiXSA9IHRydWU7CiAgICAgIHRoaXMuaW5jcmVtZW50YWxfZWxlbWVudHMgPSBpbmNsaXN0OwogICAgfQogICAgcmV0dXJuIHRoaXMuaW5jcmVtZW50YWxfZWxlbWVudHNbbmFtZS50b0xvd2VyQ2FzZSgpXTsKICB9LAoKICBuZXh0X2luY3JlbWVudGFsX2l0ZW06IGZ1bmN0aW9uIChub2RlKSB7CiAgICB2YXIgYnIgPSB0aGlzLmlzX3hodG1sID8gImJyIiA6ICJCUiI7CiAgICB2YXIgc2xpZGUgPSB3M2Nfc2xpZHkuc2xpZGVzW3czY19zbGlkeS5zbGlkZV9udW1iZXJdOwoKICAgIGZvciAoOzspCiAgICB7CiAgICAgIG5vZGUgPSB3M2Nfc2xpZHkubmV4dF9ub2RlKHNsaWRlLCBub2RlKTsKCiAgICAgIGlmIChub2RlID09IG51bGwgfHwgbm9kZS5wYXJlbnROb2RlID09IG51bGwpCiAgICAgICAgYnJlYWs7CgogICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PSAxKSAgLy8gRUxFTUVOVAogICAgICB7CiAgICAgICAgaWYgKG5vZGUubm9kZU5hbWUgPT0gYnIpCiAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgaWYgKHczY19zbGlkeS5oYXNfY2xhc3Mobm9kZSwgImluY3JlbWVudGFsIikKICAgICAgICAgICAgICYmIHczY19zbGlkeS5va2F5X2Zvcl9pbmNyZW1lbnRhbChub2RlLm5vZGVOYW1lKSkKICAgICAgICAgIHJldHVybiBub2RlOwoKICAgICAgICBpZiAodzNjX3NsaWR5Lmhhc19jbGFzcyhub2RlLnBhcmVudE5vZGUsICJpbmNyZW1lbnRhbCIpCiAgICAgICAgICAgICAmJiAhdzNjX3NsaWR5Lmhhc19jbGFzcyhub2RlLCAibm9uLWluY3JlbWVudGFsIikpCiAgICAgICAgICByZXR1cm4gbm9kZTsKICAgICAgfQogICAgfQoKICAgIHJldHVybiBub2RlOwogIH0sCgogIHByZXZpb3VzX2luY3JlbWVudGFsX2l0ZW06IGZ1bmN0aW9uIChub2RlKSB7CiAgICB2YXIgYnIgPSB0aGlzLmlzX3hodG1sID8gImJyIiA6ICJCUiI7CiAgICB2YXIgc2xpZGUgPSB3M2Nfc2xpZHkuc2xpZGVzW3czY19zbGlkeS5zbGlkZV9udW1iZXJdOwoKICAgIGZvciAoOzspCiAgICB7CiAgICAgIG5vZGUgPSB3M2Nfc2xpZHkucHJldmlvdXNfbm9kZShzbGlkZSwgbm9kZSk7CgogICAgICBpZiAobm9kZSA9PSBudWxsIHx8IG5vZGUucGFyZW50Tm9kZSA9PSBudWxsKQogICAgICAgIGJyZWFrOwoKICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT0gMSkKICAgICAgewogICAgICAgIGlmIChub2RlLm5vZGVOYW1lID09IGJyKQogICAgICAgICAgY29udGludWU7CgogICAgICAgIGlmICh3M2Nfc2xpZHkuaGFzX2NsYXNzKG5vZGUsICJpbmNyZW1lbnRhbCIpCiAgICAgICAgICAgICAmJiB3M2Nfc2xpZHkub2theV9mb3JfaW5jcmVtZW50YWwobm9kZS5ub2RlTmFtZSkpCiAgICAgICAgICByZXR1cm4gbm9kZTsKCiAgICAgICAgaWYgKHczY19zbGlkeS5oYXNfY2xhc3Mobm9kZS5wYXJlbnROb2RlLCAiaW5jcmVtZW50YWwiKQogICAgICAgICAgICAgJiYgIXczY19zbGlkeS5oYXNfY2xhc3Mobm9kZSwgIm5vbi1pbmNyZW1lbnRhbCIpKQogICAgICAgICAgcmV0dXJuIG5vZGU7CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gbm9kZTsKICB9LAoKICAvLyBzZXQgdmlzaWJpbGl0eSBmb3IgYWxsIGVsZW1lbnRzIG9uIGN1cnJlbnQgc2xpZGUgd2l0aAogIC8vIGEgcGFyZW50IGVsZW1lbnQgd2l0aCBhdHRyaWJ1dGUgY2xhc3M9ImluY3JlbWVudGFsIgogIHNldF92aXNpYmlsaXR5X2FsbF9pbmNyZW1lbnRhbDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICB2YXIgbm9kZSA9IHRoaXMubmV4dF9pbmNyZW1lbnRhbF9pdGVtKG51bGwpOwoKICAgIGlmICh2YWx1ZSA9PSAiaGlkZGVuIikKICAgIHsKICAgICAgd2hpbGUgKG5vZGUpCiAgICAgIHsKICAgICAgICB3M2Nfc2xpZHkuYWRkX2NsYXNzKG5vZGUsICJpbnZpc2libGUiKTsKICAgICAgICBub2RlID0gdzNjX3NsaWR5Lm5leHRfaW5jcmVtZW50YWxfaXRlbShub2RlKTsKICAgICAgfQogICAgfQogICAgZWxzZSAvLyB2YWx1ZSA9PSAidmlzaWJsZSIKICAgIHsKICAgICAgd2hpbGUgKG5vZGUpCiAgICAgIHsKICAgICAgICB3M2Nfc2xpZHkucmVtb3ZlX2NsYXNzKG5vZGUsICJpbnZpc2libGUiKTsKICAgICAgICBub2RlID0gdzNjX3NsaWR5Lm5leHRfaW5jcmVtZW50YWxfaXRlbShub2RlKTsKICAgICAgfQogICAgfQogIH0sCgogIC8vIHJldmVhbCB0aGUgbmV4dCBoaWRkZW4gaXRlbSBvbiB0aGUgc2xpZGUKICAvLyBub2RlIGlzIG51bGwgb3IgdGhlIG5vZGUgdGhhdCB3YXMgbGFzdCByZXZlYWxlZAogIHJldmVhbF9uZXh0X2l0ZW06IGZ1bmN0aW9uIChub2RlKSB7CiAgICBub2RlID0gdzNjX3NsaWR5Lm5leHRfaW5jcmVtZW50YWxfaXRlbShub2RlKTsKCiAgICBpZiAobm9kZSAmJiBub2RlLm5vZGVUeXBlID09IDEpICAvLyBhbiBlbGVtZW50CiAgICAgIHczY19zbGlkeS5yZW1vdmVfY2xhc3Mobm9kZSwgImludmlzaWJsZSIpOwoKICAgIHJldHVybiBub2RlOwogIH0sCgogIC8vIGV4YWN0IGludmVyc2Ugb2YgcmV2ZWFsTmV4dEl0ZW0obm9kZSkKICBoaWRlX3ByZXZpb3VzX2l0ZW06IGZ1bmN0aW9uIChub2RlKSB7CiAgICBpZiAobm9kZSAmJiBub2RlLm5vZGVUeXBlID09IDEpICAvLyBhbiBlbGVtZW50CiAgICAgIHczY19zbGlkeS5hZGRfY2xhc3Mobm9kZSwgImludmlzaWJsZSIpOwoKICAgIHJldHVybiB0aGlzLnByZXZpb3VzX2luY3JlbWVudGFsX2l0ZW0obm9kZSk7CiAgfSwKCiAgLy8gbGVmdCB0byByaWdodCB0cmF2ZXJzYWwgb2Ygcm9vdCdzIGNvbnRlbnQKICBuZXh0X25vZGU6IGZ1bmN0aW9uIChyb290LCBub2RlKSB7CiAgICBpZiAobm9kZSA9PSBudWxsKQogICAgICByZXR1cm4gcm9vdC5maXJzdENoaWxkOwoKICAgIGlmIChub2RlLmZpcnN0Q2hpbGQpCiAgICAgIHJldHVybiBub2RlLmZpcnN0Q2hpbGQ7CgogICAgaWYgKG5vZGUubmV4dFNpYmxpbmcpCiAgICAgIHJldHVybiBub2RlLm5leHRTaWJsaW5nOwoKICAgIGZvciAoOzspCiAgICB7CiAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7CgogICAgICBpZiAoIW5vZGUgfHwgbm9kZSA9PSByb290KQogICAgICAgIGJyZWFrOwoKICAgICAgaWYgKG5vZGUgJiYgbm9kZS5uZXh0U2libGluZykKICAgICAgICByZXR1cm4gbm9kZS5uZXh0U2libGluZzsKICAgIH0KCiAgICByZXR1cm4gbnVsbDsKICB9LAoKICAvLyByaWdodCB0byBsZWZ0IHRyYXZlcnNhbCBvZiByb290J3MgY29udGVudAogIHByZXZpb3VzX25vZGU6IGZ1bmN0aW9uIChyb290LCBub2RlKSB7CiAgICBpZiAobm9kZSA9PSBudWxsKQogICAgewogICAgICBub2RlID0gcm9vdC5sYXN0Q2hpbGQ7CgogICAgICBpZiAobm9kZSkKICAgICAgewogICAgICAgIHdoaWxlIChub2RlLmxhc3RDaGlsZCkKICAgICAgICAgIG5vZGUgPSBub2RlLmxhc3RDaGlsZDsKICAgICAgfQoKICAgICAgcmV0dXJuIG5vZGU7CiAgICB9CgogICAgaWYgKG5vZGUucHJldmlvdXNTaWJsaW5nKQogICAgewogICAgICBub2RlID0gbm9kZS5wcmV2aW91c1NpYmxpbmc7CgogICAgICB3aGlsZSAobm9kZS5sYXN0Q2hpbGQpCiAgICAgICAgbm9kZSA9IG5vZGUubGFzdENoaWxkOwoKICAgICAgcmV0dXJuIG5vZGU7CiAgICB9CgogICAgaWYgKG5vZGUucGFyZW50Tm9kZSAhPSByb290KQogICAgICByZXR1cm4gbm9kZS5wYXJlbnROb2RlOwoKICAgIHJldHVybiBudWxsOwogIH0sCgogIHByZXZpb3VzX3NpYmxpbmdfZWxlbWVudDogZnVuY3Rpb24gKGVsKSB7CiAgICBlbCA9IGVsLnByZXZpb3VzU2libGluZzsKCiAgICB3aGlsZSAoZWwgJiYgZWwubm9kZVR5cGUgIT0gMSkKICAgICAgZWwgPSBlbC5wcmV2aW91c1NpYmxpbmc7CgogICAgcmV0dXJuIGVsOwogIH0sCgogIG5leHRfc2libGluZ19lbGVtZW50OiBmdW5jdGlvbiAoZWwpIHsKICAgIGVsID0gZWwubmV4dFNpYmxpbmc7CgogICAgd2hpbGUgKGVsICYmIGVsLm5vZGVUeXBlICE9IDEpCiAgICAgIGVsID0gZWwubmV4dFNpYmxpbmc7CgogICAgcmV0dXJuIGVsOwogIH0sCgogIGZpcnN0X2NoaWxkX2VsZW1lbnQ6IGZ1bmN0aW9uIChlbCkgewogICAgdmFyIG5vZGU7CgogICAgZm9yIChub2RlID0gZWwuZmlyc3RDaGlsZDsgbm9kZTsgbm9kZSA9IG5vZGUubmV4dFNpYmxpbmcpCiAgICB7CiAgICAgIGlmIChub2RlLm5vZGVUeXBlID09IDEpCiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgcmV0dXJuIG5vZGU7CiAgfSwKCiAgZmlyc3RfdGFnOiBmdW5jdGlvbiAoZWxlbWVudCwgdGFnKSB7CiAgICB2YXIgbm9kZTsKCiAgICBpZiAoIXRoaXMuaXNfeGh0bWwpCiAgICAgIHRhZyA9IHRhZy50b1VwcGVyQ2FzZSgpOwoKICAgIGZvciAobm9kZSA9IGVsZW1lbnQuZmlyc3RDaGlsZDsgbm9kZTsgbm9kZSA9IG5vZGUubmV4dFNpYmxpbmcpCiAgICB7CiAgICAgIGlmIChub2RlLm5vZGVUeXBlID09IDEgJiYgbm9kZS5ub2RlTmFtZSA9PSB0YWcpCiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgcmV0dXJuIG5vZGU7CiAgfSwKCiAgaGlkZV9zZWxlY3Rpb246IGZ1bmN0aW9uICgpIHsKICAgIGlmICh3aW5kb3cuZ2V0U2VsZWN0aW9uKSAvLyBGaXJlZm94LCBDaHJvbWl1bSwgU2FmYXJpLCBPcGVyYQogICAgewogICAgICB2YXIgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpOwoKICAgICAgaWYgKHNlbGVjdGlvbi5yYW5nZUNvdW50ID4gMCkKICAgICAgewogICAgICAgIHZhciByYW5nZSA9IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApOwogICAgICAgIHJhbmdlLmNvbGxhcHNlIChmYWxzZSk7CiAgICAgIH0KICAgIH0KICAgIGVsc2UgLy8gSW50ZXJuZXQgRXhwbG9yZXIKICAgIHsKICAgICAgdmFyIHRleHRSYW5nZSA9IGRvY3VtZW50LnNlbGVjdGlvbi5jcmVhdGVSYW5nZSAoKTsKICAgICAgdGV4dFJhbmdlLmNvbGxhcHNlIChmYWxzZSk7CiAgICB9CiAgfSwKCiAgZ2V0X3NlbGVjdGVkX3RleHQ6IGZ1bmN0aW9uICgpIHsKICAgIHRyeQogICAgewogICAgICBpZiAod2luZG93LmdldFNlbGVjdGlvbikKICAgICAgICByZXR1cm4gd2luZG93LmdldFNlbGVjdGlvbigpLnRvU3RyaW5nKCk7CgogICAgICBpZiAoZG9jdW1lbnQuZ2V0U2VsZWN0aW9uKQogICAgICAgIHJldHVybiBkb2N1bWVudC5nZXRTZWxlY3Rpb24oKS50b1N0cmluZygpOwoKICAgICAgaWYgKGRvY3VtZW50LnNlbGVjdGlvbikKICAgICAgICByZXR1cm4gZG9jdW1lbnQuc2VsZWN0aW9uLmNyZWF0ZVJhbmdlKCkudGV4dDsKICAgIH0KICAgIGNhdGNoIChlKQogICAgewogICAgfQoKICAgIHJldHVybiAiIjsKICB9LAoKICAvLyBtYWtlIG5vdGUgb2YgbGVuZ3RoIG9mIHNlbGVjdGVkIHRleHQKICAvLyBhcyB0aGlzIGV2YWx1YXRlcyB0byB6ZXJvIGluIGNsaWNrIGV2ZW50CiAgbW91c2VfYnV0dG9uX3VwOiBmdW5jdGlvbiAoZSkgewogICAgdzNjX3NsaWR5LnNlbGVjdGVkX3RleHRfbGVuID0gdzNjX3NsaWR5LmdldF9zZWxlY3RlZF90ZXh0KCkubGVuZ3RoOwogIH0sCgogIG1vdXNlX2J1dHRvbl9kb3duOiBmdW5jdGlvbiAoZSkgewogICAgdzNjX3NsaWR5LnNlbGVjdGVkX3RleHRfbGVuID0gdzNjX3NsaWR5LmdldF9zZWxlY3RlZF90ZXh0KCkubGVuZ3RoOwogICAgdzNjX3NsaWR5Lm1vdXNlX3ggPSBlLmNsaWVudFg7CiAgICB3M2Nfc2xpZHkubW91c2VfeSA9IGUuY2xpZW50WTsKICB9LAoKICAvLyByaWdodCBtb3VzZSBidXR0b24gY2xpY2sgaXMgcmVzZXJ2ZWQgZm9yIGNvbnRleHQgbWVudXMKICAvLyBpdCBpcyBtb3JlIHJlbGlhYmxlIHRvIGRldGVjdCByaWdodGNsaWNrIHRoYW4gbGVmdGNsaWNrCiAgbW91c2VfYnV0dG9uX2NsaWNrOiBmdW5jdGlvbiAoZSkgewogICAgaWYgKCFlKQogICAgICB2YXIgZSA9IHdpbmRvdy5ldmVudDsKCiAgICBpZiAoTWF0aC5hYnMoZS5jbGllbnRYIC13M2Nfc2xpZHkubW91c2VfeCkgKwogICAgICAgIE1hdGguYWJzKGUuY2xpZW50WSAtdzNjX3NsaWR5Lm1vdXNlX3kpID4gMTApCiAgICAgIHJldHVybiB0cnVlOwoKICAgIGlmICh3M2Nfc2xpZHkuc2VsZWN0ZWRfdGV4dF9sZW4gPiAwKQogICAgICByZXR1cm4gdHJ1ZTsKCiAgICB2YXIgcmlnaHRjbGljayA9IGZhbHNlOwogICAgdmFyIGxlZnRjbGljayA9IGZhbHNlOwogICAgdmFyIG1pZGRsZWNsaWNrID0gZmFsc2U7CiAgICB2YXIgdGFyZ2V0OwoKICAgIGlmICghZSkKICAgICAgdmFyIGUgPSB3aW5kb3cuZXZlbnQ7CgogICAgaWYgKGUudGFyZ2V0KQogICAgICB0YXJnZXQgPSBlLnRhcmdldDsKICAgIGVsc2UgaWYgKGUuc3JjRWxlbWVudCkKICAgICAgdGFyZ2V0ID0gZS5zcmNFbGVtZW50OwoKICAgIC8vIHdvcmsgYXJvdW5kIFNhZmFyaSBidWcKICAgIGlmICh0YXJnZXQubm9kZVR5cGUgPT0gMykKICAgICAgdGFyZ2V0ID0gdGFyZ2V0LnBhcmVudE5vZGU7CgogICAgaWYgKGUud2hpY2gpIC8vIGFsbCBicm93c2VycyBleGNlcHQgSUUKICAgIHsKICAgICAgbGVmdGNsaWNrID0gKGUud2hpY2ggPT0gMSk7CiAgICAgIG1pZGRsZWNsaWNrID0gKGUud2hpY2ggPT0gMik7CiAgICAgIHJpZ2h0Y2xpY2sgPSAoZS53aGljaCA9PSAzKTsKICAgIH0KICAgIGVsc2UgaWYgKGUuYnV0dG9uKQogICAgewogICAgICAvLyBLb25xdWVyb3IgZ2l2ZXMgMSBmb3IgbGVmdCwgNCBmb3IgbWlkZGxlCiAgICAgIC8vIElFNiBnaXZlcyAwIGZvciBsZWZ0IGFuZCBub3QgMSBhcyBJIGV4cGVjdGVkCgogICAgICBpZiAoZS5idXR0b24gPT0gNCkKICAgICAgICBtaWRkbGVjbGljayA9IHRydWU7CgogICAgICAvLyBhbGwgYnJvd3NlcnMgYWdyZWUgb24gMiBmb3IgcmlnaHQgYnV0dG9uCiAgICAgIHJpZ2h0Y2xpY2sgPSAoZS5idXR0b24gPT0gMik7CiAgICB9CiAgICBlbHNlCiAgICAgIGxlZnRjbGljayA9IHRydWU7CgogICAgaWYgKHczY19zbGlkeS5zZWxlY3RlZF90ZXh0X2xlbiA+IDApCiAgICB7CiAgICAgIHczY19zbGlkeS5zdG9wX3Byb3BhZ2F0aW9uKGUpOwogICAgICBlLmNhbmNlbCA9IHRydWU7CiAgICAgIGUucmV0dXJuVmFsdWUgPSBmYWxzZTsKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8vIGRpc21pc3MgdGFibGUgb2YgY29udGVudHMKICAgIHczY19zbGlkeS5oaWRlX3RhYmxlX29mX2NvbnRlbnRzKGZhbHNlKTsKCiAgICAvLyBjaGVjayBpZiB0YXJnZXQgaXMgc29tZXRoaW5nIHRoYXQgcHJvYmFibHkgd2FudCdzIGNsaWNrcwogICAgLy8gZS5nLiBhLCBlbWJlZCwgb2JqZWN0LCBpbnB1dCwgdGV4dGFyZWEsIHNlbGVjdCwgb3B0aW9uCiAgICB2YXIgdGFnID0gdGFyZ2V0Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7CgogICAgaWYgKHczY19zbGlkeS5tb3VzZV9jbGlja19lbmFibGVkICYmIGxlZnRjbGljayAmJgogICAgICAgICF3M2Nfc2xpZHkuc3BlY2lhbF9lbGVtZW50KHRhcmdldCkgJiYKICAgICAgICAhdGFyZ2V0Lm9uY2xpY2spCiAgICB7CiAgICAgIHczY19zbGlkeS5uZXh0X3NsaWRlKHRydWUpOwogICAgICB3M2Nfc2xpZHkuc3RvcF9wcm9wYWdhdGlvbihlKTsKICAgICAgZS5jYW5jZWwgPSB0cnVlOwogICAgICBlLnJldHVyblZhbHVlID0gZmFsc2U7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICByZXR1cm4gdHJ1ZTsKICB9LAoKICBzcGVjaWFsX2VsZW1lbnQ6IGZ1bmN0aW9uIChlbGVtZW50KSB7CiAgICBpZiAodGhpcy5oYXNfY2xhc3MoZWxlbWVudCwgIm5vbi1pbnRlcmFjdGl2ZSIpKQogICAgICByZXR1cm4gZmFsc2U7CgogICAgdmFyIHRhZyA9IGVsZW1lbnQubm9kZU5hbWUudG9Mb3dlckNhc2UoKTsKCiAgICByZXR1cm4gZWxlbWVudC5vbmtleWRvd24gfHwKICAgICAgZWxlbWVudC5vbmNsaWNrIHx8CiAgICAgIHRhZyA9PSAiYSIgfHwKICAgICAgdGFnID09ICJlbWJlZCIgfHwKICAgICAgdGFnID09ICJvYmplY3QiIHx8CiAgICAgIHRhZyA9PSAidmlkZW8iIHx8CiAgICAgIHRhZyA9PSAiYXVkaW8iIHx8CiAgICAgIHRhZyA9PSAic3ZnIiB8fAogICAgICB0YWcgPT0gImNhbnZhcyIgfHwKICAgICAgdGFnID09ICJpbnB1dCIgfHwKICAgICAgdGFnID09ICJ0ZXh0YXJlYSIgfHwKICAgICAgdGFnID09ICJzZWxlY3QiIHx8CiAgICAgIHRhZyA9PSAib3B0aW9uIjsKICB9LAoKICBzbGlkeV9jaHJvbWU6IGZ1bmN0aW9uIChlbCkgewogICAgd2hpbGUgKGVsKQogICAgewogICAgICBpZiAoZWwgPT0gdzNjX3NsaWR5LnRvYyB8fAogICAgICAgICAgZWwgPT0gdzNjX3NsaWR5LnRvb2xiYXIgfHwKICAgICAgICAgIHczY19zbGlkeS5oYXNfY2xhc3MoZWwsICJvdXRsaW5lIikpCiAgICAgICAgcmV0dXJuIHRydWU7CgogICAgICBlbCA9IGVsLnBhcmVudE5vZGU7CiAgICB9CgogICAgcmV0dXJuIGZhbHNlOwogIH0sCgogIGdldF9rZXk6IGZ1bmN0aW9uIChlKQogIHsKICAgIHZhciBrZXk7CgogICAgLy8ga2x1ZGdlIGFyb3VuZCBOUy9JRSBkaWZmZXJlbmNlcyAKICAgIGlmICh0eXBlb2Ygd2luZG93LmV2ZW50ICE9ICJ1bmRlZmluZWQiKQogICAgICBrZXkgPSB3aW5kb3cuZXZlbnQua2V5Q29kZTsKICAgIGVsc2UgaWYgKGUud2hpY2gpCiAgICAgIGtleSA9IGUud2hpY2g7CgogICAgcmV0dXJuIGtleTsKICB9LAoKICBnZXRfdGFyZ2V0OiBmdW5jdGlvbiAoZSkgewogICAgdmFyIHRhcmdldDsKCiAgICBpZiAoIWUpCiAgICAgIGUgPSB3aW5kb3cuZXZlbnQ7CgogICAgaWYgKGUudGFyZ2V0KQogICAgICB0YXJnZXQgPSBlLnRhcmdldDsKICAgIGVsc2UgaWYgKGUuc3JjRWxlbWVudCkKICAgICAgdGFyZ2V0ID0gZS5zcmNFbGVtZW50OwoKICAgIGlmICh0YXJnZXQubm9kZVR5cGUgIT0gMSkKICAgICAgdGFyZ2V0ID0gdGFyZ2V0LnBhcmVudE5vZGU7CgogICAgcmV0dXJuIHRhcmdldDsKICB9LAoKICAvLyBkb2VzIGRpc3BsYXkgcHJvcGVydHkgcHJvdmlkZSBjb3JyZWN0IGRlZmF1bHRzPwogIGlzX2Jsb2NrOiBmdW5jdGlvbiAoZWxlbSkgewogICAgdmFyIHRhZyA9IGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTsKCiAgICByZXR1cm4gdGFnID09ICJvbCIgfHwgdGFnID09ICJ1bCIgfHwgdGFnID09ICJwIiB8fCB0YWcgPT0gImRsIiB8fAogICAgICAgICAgIHRhZyA9PSAibGkiIHx8IHRhZyA9PSAidGFibGUiIHx8IHRhZyA9PSAicHJlIiB8fAogICAgICAgICAgIHRhZyA9PSAiaDEiIHx8IHRhZyA9PSAiaDIiIHx8IHRhZyA9PSAiaDMiIHx8CiAgICAgICAgICAgdGFnID09ICJoNCIgfHwgdGFnID09ICJoNSIgfHwgdGFnID09ICJoNiIgfHwKICAgICAgICAgICB0YWcgPT0gImJsb2NrcXVvdGUiIHx8IHRhZyA9PSAiYWRkcmVzcyI7IAogIH0sCgogIGFkZF9saXN0ZW5lcjogZnVuY3Rpb24gKGVsZW1lbnQsIGV2ZW50LCBoYW5kbGVyKSB7CiAgICBpZiAod2luZG93LmFkZEV2ZW50TGlzdGVuZXIpCiAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgaGFuZGxlciwgZmFsc2UpOwogICAgZWxzZQogICAgICBlbGVtZW50LmF0dGFjaEV2ZW50KCJvbiIrZXZlbnQsIGhhbmRsZXIpOwogIH0sCgogIC8vIHVzZWQgdG8gcHJldmVudCBldmVudCBwcm9wYWdhdGlvbiBmcm9tIGZpZWxkIGNvbnRyb2xzCiAgc3RvcF9wcm9wYWdhdGlvbjogZnVuY3Rpb24gKGV2ZW50KSB7CiAgICBldmVudCA9IGV2ZW50ID8gZXZlbnQgOiB3aW5kb3cuZXZlbnQ7CiAgICBldmVudC5jYW5jZWxCdWJibGUgPSB0cnVlOyAgLy8gZm9yIElFCgogICAgaWYgKGV2ZW50LnN0b3BQcm9wYWdhdGlvbikKICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7CgogICAgcmV0dXJuIHRydWU7CiAgfSwKCiAgY2FuY2VsOiBmdW5jdGlvbiAoZXZlbnQpIHsKICAgIGlmIChldmVudCkKICAgIHsKICAgICAgIGV2ZW50LmNhbmNlbCA9IHRydWU7CiAgICAgICBldmVudC5yZXR1cm5WYWx1ZSA9IGZhbHNlOwoKICAgICAgaWYgKGV2ZW50LnByZXZlbnREZWZhdWx0KQogICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICB9CgogICAgdzNjX3NsaWR5LmtleV93YW50ZWQgPSBmYWxzZTsKICAgIHJldHVybiBmYWxzZTsKICB9LAoKLy8gZm9yIGVhY2ggbGFuZ3VhZ2UgZGVmaW5lIGFuIGFzc29jaWF0aXZlIGFycmF5Ci8vIGFuZCBhbHNvIHRoZSBoZWxwIHRleHQgd2hpY2ggaXMgbG9uZ2VyCgogIHN0cmluZ3NfZXM6IHsKICAgICJzbGlkZSI6InDDoWcuIiwKICAgICJoZWxwPyI6IkF5dWRhIiwKICAgICJjb250ZW50cz8iOiLDjW5kaWNlIiwKICAgICJ0YWJsZSBvZiBjb250ZW50cyI6InRhYmxhIGRlIGNvbnRlbmlkb3MiLAogICAgIlRhYmxlIG9mIENvbnRlbnRzIjoiVGFibGEgZGUgQ29udGVuaWRvcyIsCiAgICAicmVzdGFydCBwcmVzZW50YXRpb24iOiJSZWluaWNpYXIgcHJlc2VudGFjacOzbiIsCiAgICAicmVzdGFydD8iOiJJbmljaW8iCiAgfSwKICBoZWxwX2VzOgogICAgIlV0aWxpY2UgZWwgcmF0w7NuLCBiYXJyYSBlc3BhY2lhZG9yYSwgdGVjbGFzIEl6ZGEvRGNoYSwgIiArCiAgICAibyBSZSBww6FnIHkgQXYgcMOhZy4gVXNlIFMgeSBCIHBhcmEgY2FtYmlhciBlbCB0YW1hw7FvIGRlIGZ1ZW50ZS4iLAoKICBzdHJpbmdzX2NhOiB7CiAgICAic2xpZGUiOiJww6BnLi4iLAogICAgImhlbHA/IjoiQWp1ZGEiLAogICAgImNvbnRlbnRzPyI6IsONbmRleCIsCiAgICAidGFibGUgb2YgY29udGVudHMiOiJ0YXVsYSBkZSBjb250aW5ndXRzIiwKICAgICJUYWJsZSBvZiBDb250ZW50cyI6IlRhdWxhIGRlIENvbnRpbmd1dHMiLAogICAgInJlc3RhcnQgcHJlc2VudGF0aW9uIjoiUmVpbmljaWFyIHByZXNlbnRhY2nDsyIsCiAgICAicmVzdGFydD8iOiJJbmljaSIKICB9LAogIGhlbHBfY2E6CiAgICAiVXRpbGl0emkgZWwgcmF0b2zDrSwgYmFycmEgZXNwYWlhZG9yYSwgdGVjbGVzIEVzcS4vRHRhLiAiICsKICAgICJvIFJlIHDDoGcgeSBBdiBww6BnLiBVc2kgUyBpIEIgcGVyIGNhbnZpYXIgZ3JhbmTDoHJpYSBkZSBmb250LiIsCgogIHN0cmluZ3NfY3M6IHsKICAgICJzbGlkZSI6InNuw61tZWsiLAogICAgImhlbHA/IjoibsOhcG92xJtkYSIsCiAgICAiY29udGVudHM/Ijoib2JzYWgiLAogICAgInRhYmxlIG9mIGNvbnRlbnRzIjoib2JzYWggcHJlemVudGFjZSIsCiAgICAiVGFibGUgb2YgQ29udGVudHMiOiJPYnNhaCBwcmV6ZW50YWNlIiwKICAgICJyZXN0YXJ0IHByZXNlbnRhdGlvbiI6Inpub3Z1IHNwdXN0aXQgcHJlemVudGFjaSIsCiAgICAicmVzdGFydD8iOiJyZXN0YXJ0IgogIH0sCiAgaGVscF9jczoKICAgICJQcmV6ZW50YWNpIG3Fr8W+ZXRlIHByb2Now6F6ZXQgcG9tb2PDrSBrbGlrbnV0w60gbXnFoWksIG1lemVybsOta3UsICIgKwogICAgIsWhaXBlayB2bGV2byBhIHZwcmF2byBuZWJvIGtsw6F2ZXMgUGFnZVVwIGEgUGFnZURvd24uIFDDrXNtbyBzZSAiICsKICAgICJkw6EgenbEm3TFoWl0IGEgem1lbsWhaXQgcG9tb2PDrSBrbMOhdmVzIEIgYSBTLiIsCgogIHN0cmluZ3Nfbmw6IHsKICAgICJzbGlkZSI6InBhZ2luYSIsCiAgICAiaGVscD8iOiJIZWxwPyIsCiAgICAiY29udGVudHM/IjoiSW5ob3VkPyIsCiAgICAidGFibGUgb2YgY29udGVudHMiOiJpbmhvdWRzb3BnYXZlIiwKICAgICJUYWJsZSBvZiBDb250ZW50cyI6IkluaG91ZHNvcGdhdmUiLAogICAgInJlc3RhcnQgcHJlc2VudGF0aW9uIjoiaGVyc3RhcnQgcHJlc2VudGF0aWUiLAogICAgInJlc3RhcnQ/IjoiSGVyc3RhcnQ/IgogIH0sCiAgaGVscF9ubDoKICAgICAiTmF2aWdlZXIgZC5tLnYuIGhldCBtdWlzLCBzcGF0aWViYXIsIExpbmtzL1JlY2h0cyB0b2V0c2VuLCAiICsKICAgICAib2YgUGdVcCBlbiBQZ0RuLiBHZWJydWlrIFMgZW4gQiBvbSBkZSBrYXJha3Rlcmdyb290dGUgdGUgdmVyYW5kZXJlbi4iLAoKICBzdHJpbmdzX2RlOiB7CiAgICAic2xpZGUiOiJTZWl0ZSIsCiAgICAiaGVscD8iOiJIaWxmZSIsCiAgICAiY29udGVudHM/Ijoiw5xiZXJzaWNodCIsCiAgICAidGFibGUgb2YgY29udGVudHMiOiJJbmhhbHRzdmVyemVpY2huaXMiLAogICAgIlRhYmxlIG9mIENvbnRlbnRzIjoiSW5oYWx0c3ZlcnplaWNobmlzIiwKICAgICJyZXN0YXJ0IHByZXNlbnRhdGlvbiI6IlByw6RzZW50YXRpb24gbmV1IHN0YXJ0ZW4iLAogICAgInJlc3RhcnQ/IjoiTmV1c3RhcnQiCiAgfSwKICBoZWxwX2RlOgogICAgIkJlbnV0emVuIFNpZSBkaWUgTWF1cywgTGVlcnNjaGxhZywgZGllIEN1cnNvcnRhc3RlbiBsaW5rcy9yZWNodHMgb2RlciAiICsKICAgICJQYWdlIHVwL1BhZ2UgRG93biB6dW0gV2VjaHNlbG4gZGVyIFNlaXRlbiB1bmQgUyB1bmQgQiBmw7xyIGRpZSBTY2hyaWZ0Z3LDtnNzZS4iLAoKICBzdHJpbmdzX3BsOiB7CiAgICAic2xpZGUiOiJzbGFqZCIsCiAgICAiaGVscD8iOiJwb21vYz8iLAogICAgImNvbnRlbnRzPyI6InNwaXMgdHJlxZtjaT8iLAogICAgInRhYmxlIG9mIGNvbnRlbnRzIjoic3BpcyB0cmXFm2NpIiwKICAgICJUYWJsZSBvZiBDb250ZW50cyI6IlNwaXMgVHJlxZtjaSIsCiAgICAicmVzdGFydCBwcmVzZW50YXRpb24iOiJSZXN0YXJ0dWogcHJlemVudGFjasSZIiwKICAgICJyZXN0YXJ0PyI6InJlc3RhcnQ/IgogIH0sCiAgaGVscF9wbDoKICAgICJabWllbmlhaiBzbGFqZHkga2xpa2FqxIVjIG15c3rEhSwgbmFjaXNrYWrEhWMgc3BhY2rEmSwgc3RyemHFgmtpIGxld28vcHJhd28iICsKICAgICJsdWIgUGdVcCAvIFBnRG4uIFXFvHlqIGtsYXdpc3p5IFMgaSBCLCBhYnkgem1pZW5pxIcgcm96bWlhciBjemN6aW9ua2kuIiwKCiAgc3RyaW5nc19mcjogewogICAgInNsaWRlIjoicGFnZSIsCiAgICAiaGVscD8iOiJBaWRlIiwKICAgICJjb250ZW50cz8iOiJJbmRleCIsCiAgICAidGFibGUgb2YgY29udGVudHMiOiJ0YWJsZSBkZXMgbWF0acOocmVzIiwKICAgICJUYWJsZSBvZiBDb250ZW50cyI6IlRhYmxlIGRlcyBtYXRpw6hyZXMiLAogICAgInJlc3RhcnQgcHJlc2VudGF0aW9uIjoiUmVjb21tZW5jZXIgbCdleHBvc8OpIiwKICAgICJyZXN0YXJ0PyI6IkTDqWJ1dCIKICB9LAogIGhlbHBfZnI6CiAgICAiTmF2aWd1ZXogYXZlYyBsYSBzb3VyaXMsIGxhIGJhcnJlIGQnZXNwYWNlLCBsZXMgZmzDqGNoZXMgIiArCiAgICAiZ2F1Y2hlL2Ryb2l0ZSBvdSBsZXMgdG91Y2hlcyBQZyBVcCwgUGcgRG4uIFV0aWxpc2V6ICIgKwogICAgImxlcyB0b3VjaGVzIFMgZXQgQiBwb3VyIG1vZGlmaWVyIGxhIHRhaWxsZSBkZSBsYSBwb2xpY2UuIiwKCiAgc3RyaW5nc19odTogewogICAgInNsaWRlIjoib2xkYWwiLAogICAgImhlbHA/Ijoic2Vnw610c8OpZyIsCiAgICAiY29udGVudHM/IjoidGFydGFsb20iLAogICAgInRhYmxlIG9mIGNvbnRlbnRzIjoidGFydGFsb21qZWd5esOpayIsCiAgICAiVGFibGUgb2YgQ29udGVudHMiOiJUYXJ0YWxvbWplZ3l6w6lrIiwKICAgICJyZXN0YXJ0IHByZXNlbnRhdGlvbiI6ImJlbXV0YXTDsyDDumpyYWluZMOtdMOhc2EiLAogICAgInJlc3RhcnQ/Ijoiw7pqcmFpbmTDrXTDoXMiCiAgfSwKICBoZWxwX2h1OgogICAgIkF6IG9sZGFsYWsga8O2enRpIGzDqXBrZWTDqXNoZXoga2F0dGludHNvbiBheiBlZ8OpcnJlbCwgdmFneSAiICsKICAgICJoYXN6bsOhbGphIGEgc3rDs2vDtnosIGEgYmFsLCB2YWd5IGEgam9iYiBuecOtbCwgaWxsZXR2ZSBhIFBhZ2UgRG93biwgIiArCiAgICAiUGFnZSBVcCBiaWxsZW50ecWxa2V0LiBBeiBTIMOpcyBhIEIgYmlsbGVudHnFsWtrZWwgdsOhbHRvenRhdGhhdGphICIgKwogICAgImEgc3rDtnZlZyBtw6lyZXTDqXQuIiwKCiAgc3RyaW5nc19pdDogewogICAgInNsaWRlIjoicGFnLiIsCiAgICAiaGVscD8iOiJBaXV0byIsCiAgICAiY29udGVudHM/IjoiSW5kaWNlIiwKICAgICJ0YWJsZSBvZiBjb250ZW50cyI6ImluZGljZSIsCiAgICAiVGFibGUgb2YgQ29udGVudHMiOiJJbmRpY2UiLAogICAgInJlc3RhcnQgcHJlc2VudGF0aW9uIjoiUmljb21pbmNpYXJlIGxhIHByZXNlbnRhemlvbmUiLAogICAgInJlc3RhcnQ/IjoiSW5pemlvIgogIH0sCiAgaGVscF9pdDoKICAgICJOYXZpZ2FyZSBjb24gbW91c2UsIGJhcnJhIHNwYXppbywgZnJlY2NlIHNpbmlzdHJhL2Rlc3RyYSBvICIgKwogICAgIlBnVXAgZSBQZ0RuLiBVc2FyZSBTIGUgQiBwZXIgY2FtYmlhcmUgbGEgZGltZW5zaW9uZSBkZWkgY2FyYXR0ZXJpLiIsCgogIHN0cmluZ3NfZWw6IHsKICAgICJzbGlkZSI6Is+DzrXOu86vzrTOsSIsCiAgICAiaGVscD8iOiLOss6/zq7OuM61zrnOsTsiLAogICAgImNvbnRlbnRzPyI6Is+AzrXPgc65zrXPh8+MzrzOtc69zrE7IiwKICAgICJ0YWJsZSBvZiBjb250ZW50cyI6Is+Azq/Ovc6xzrrOsc+CIM+AzrXPgc65zrXPh86/zrzOrc69z4nOvSIsCiAgICAiVGFibGUgb2YgQ29udGVudHMiOiLOoM6vzr3Osc66zrHPgiDOoM61z4HOuc61z4fOv868zq3Ovc+Jzr0iLAogICAgInJlc3RhcnQgcHJlc2VudGF0aW9uIjoizrXPgM6xzr3Otc66zrrOr869zrfPg863IM+AzrHPgc6/z4XPg86vzrHPg863z4IiLAogICAgInJlc3RhcnQ/IjoizrXPgM6xzr3Otc66zrrOr869zrfPg863OyIKICB9LAogIGhlbHBfZWw6CiAgICAizqDOu86/zrfOs863zrjOtc6vz4TOtSDOvM61IM+Ezr8gzrrOu86vzrogz4TOv8+FIM+Azr/Ovc+EzrnOus65zr/PjSwgz4TOvyBzcGFjZSwgz4TOsSDOss6tzrvOtyDOsc+BzrnPg8+EzrXPgc6sL860zrXOvs65zqwsICIgKwogICAgIs6uIFBhZ2UgVXAgzrrOsc65IFBhZ2UgRG93bi4gzqfPgc63z4POuc68zr/PgM6/zrnOrs+Dz4TOtSDPhM6xIM+AzrvOrs66z4TPgc6xIFMgzrrOsc65IEIgzrPOuc6xIM69zrEgzrHOu867zqzOvs61z4TOtSAiICsKICAgICLPhM6/IM68zq3Os861zrjOv8+CIM+EzrfPgiDOs8+BzrHOvM68zrHPhM6/z4POtc65z4HOrM+CLiIsCgogIHN0cmluZ3NfamE6IHsKICAgICJzbGlkZSI6IuOCueODqeOCpOODiSIsCiAgICAiaGVscD8iOiLjg5jjg6vjg5ciLAogICAgImNvbnRlbnRzPyI6IuebruasoSIsCiAgICAidGFibGUgb2YgY29udGVudHMiOiLnm67mrKHjgpLooajnpLoiLAogICAgIlRhYmxlIG9mIENvbnRlbnRzIjoi55uu5qyhIiwKICAgICJyZXN0YXJ0IHByZXNlbnRhdGlvbiI6IuacgOWIneOBi+OCieWGjeeUnyIsCiAgICAicmVzdGFydD8iOiLmnIDliJ3jgYvjgokiCiAgfSwKICBoZWxwX2phOgogICAgICLjg57jgqbjgrnlt6bjgq/jg6rjg4Pjgq8g44O7IOOCueODmuODvOOCuSDjg7sg5bem5Y+z44Kt44O8ICIgKwogICAgICLjgb7jgZ/jga8gUGFnZSBVcCDjg7sgUGFnZSBEb3du44Gn5pON5L2c77yMIFMg44O7IELjgafjg5Xjgqnjg7Pjg4jjgrXjgqTjgrrlpInmm7QiLAoKICBzdHJpbmdzX3poOiB7CiAgICAic2xpZGUiOiLlubvnga/niYciLAogICAgImhlbHA/Ijoi5biu5YqpPyIsCiAgICAiY29udGVudHM/Ijoi5YaF5a65PyIsCiAgICAidGFibGUgb2YgY29udGVudHMiOiLnm67lvZUiLAogICAgIlRhYmxlIG9mIENvbnRlbnRzIjoi55uu5b2VIiwKICAgICJyZXN0YXJ0IHByZXNlbnRhdGlvbiI6IumHjeaWsOWQr+WKqOWxleekuiIsCiAgICAicmVzdGFydD8iOiLph43mlrDlkK/liqg/IgogIH0sCiAgaGVscF96aDoKICAgICLnlKjpvKDmoIfngrnlh7ssIOepuuagvOadoSwg5bem5Y+z566t5aS0LCBQZyBVcCDlkowgUGcgRG4g5a+86IiqLiAiICsKICAgICLnlKggUywgQiDmlLnlj5jlrZfkvZPlpKflsI8uIiwKCiAgc3RyaW5nc19ydTogewogICAgInNsaWRlIjoi0YHQu9Cw0LnQtCIsCiAgICAiaGVscD8iOiLQv9C+0LzQvtGJ0Yw/IiwKICAgICJjb250ZW50cz8iOiLRgdC+0LTQtdGA0LbQsNC90LjQtT8iLAogICAgInRhYmxlIG9mIGNvbnRlbnRzIjoi0L7Qs9C70LDQstC70LXQvdC40LUiLAogICAgIlRhYmxlIG9mIENvbnRlbnRzIjoi0J7Qs9C70LDQstC70LXQvdC40LUiLAogICAgInJlc3RhcnQgcHJlc2VudGF0aW9uIjoi0L/QtdGA0LXQt9Cw0L/Rg9GB0YLQuNGC0Ywg0L/RgNC10LfQtdC90YLQsNGG0LjRjiIsCiAgICAicmVzdGFydD8iOiLQv9C10YDQtdC30LDQv9GD0YHQuj8iCiAgfSwKICBoZWxwX3J1OgogICAgItCf0LXRgNC10LzQtdGJ0LDQudGC0LXRgdGMINC60LvQuNC60LDRjyDQvNGL0YjQutC+0LksINC40YHQv9C+0LvRjNC30YPRjyDQutC70LDQstC40YjRgyDQv9GA0L7QsdC10LssINGB0YLRgNC10LvQutC4IiArCiAgICAi0LLQu9C10LLQvi/QstC/0YDQsNCy0L4g0LjQu9C4IFBnIFVwINC4IFBnIERuLiDQmtC70LDQstC40YjQuCBTINC4IEIg0LzQtdC90Y/RjtGCINGA0LDQt9C80LXRgCDRiNGA0LjRhNGC0LAuIiwKCiAgc3RyaW5nc19zdjogewogICAgInNsaWRlIjoic2lkYSIsCiAgICAiaGVscD8iOiJoasOkbHAiLAogICAgImNvbnRlbnRzPyI6ImlubmVow6VsbCIsCiAgICAidGFibGUgb2YgY29udGVudHMiOiJpbm5laMOlbGxzZsO2cnRlY2tuaW5nIiwKICAgICJUYWJsZSBvZiBDb250ZW50cyI6IklubmVow6VsbHNmw7ZydGVja25pbmciLAogICAgInJlc3RhcnQgcHJlc2VudGF0aW9uIjoidmlzYSBwcmVzZW50YXRpb25lbiBmcsOlbiBiw7ZyamFuIiwKICAgICJyZXN0YXJ0PyI6ImLDtnJqYSBvbSIKICB9LAogIGhlbHBfc3Y6CiAgICAiQmzDpGRkcmEgbWVkIGV0dCBrbGljayBtZWQgdsOkbnN0cmEgbXVza25hcHBlbiwgbWVsbGFuc2xhZ3N0YW5nZW50ZW4sICIgKwogICAgInbDpG5zdGVyLSBvY2ggaMO2Z2VycGlsdGFuZ2VudGVybmEgZWxsZXIgdGFuZ2VudGVybmEgUGcgVXAsIFBnIERuLiAiICsKICAgICJBbnbDpG5kIHRhbmdlbnRlcm5hIFMgb2NoIEIgZsO2ciBhdHQgw6RuZHJhIHRleHRlbnMgc3Rvcmxlay4iLAoKICBzdHJpbmdzOiB7IH0sCgogIGxvY2FsaXplOiBmdW5jdGlvbiAoc3JjKSB7CiAgICBpZiAoc3JjID09ICIiKQogICAgICByZXR1cm4gc3JjOwoKICAgICAvLyB0cnkgZnVsbCBsYW5ndWFnZSBjb2RlLCBlLmcuIGVuLVVTCiAgICAgdmFyIHMsIGxvb2t1cCA9IHczY19zbGlkeS5zdHJpbmdzW3czY19zbGlkeS5sYW5nXTsKCiAgICAgaWYgKGxvb2t1cCkKICAgICB7CiAgICAgICBzID0gbG9va3VwW3NyY107CgogICAgICAgaWYgKHMpCiAgICAgICAgcmV0dXJuIHM7CiAgICAgfQoKICAgICAvLyBzdHJpcCBjb3VudHJ5IGNvZGUgc3VmZml4LCBlLmcuCiAgICAgLy8gdHJ5IGVuIGlmIHVuZGVmaW5lZCBmb3IgZW4tVVMKICAgICB2YXIgbGcgPSB3M2Nfc2xpZHkubGFuZy5zcGxpdCgiLSIpOwoKICAgICBpZiAobGcubGVuZ3RoID4gMSkKICAgICB7CiAgICAgICBsb29rdXAgPSB3M2Nfc2xpZHkuc3RyaW5nc1tsZ1swXV07CgogICAgICAgaWYgKGxvb2t1cCkKICAgICAgIHsKICAgICAgICAgcyA9IGxvb2t1cFtzcmNdOwoKICAgICAgICAgaWYgKHMpCiAgICAgICAgICByZXR1cm4gczsKICAgICAgIH0KICAgICB9CgogICAgIC8vIG90aGVyd2lzZSBzdHJpbmcgYXMgaXMKICAgICByZXR1cm4gc3JjOwogIH0sCgogIGluaXRfbG9jYWxpemF0aW9uOiBmdW5jdGlvbiAoKSB7CiAgICB2YXIgaTE4biA9IHczY19zbGlkeTsKICAgIHZhciBoZWxwX3RleHQgPSB3M2Nfc2xpZHkuaGVscF90ZXh0OwoKICAgIC8vIGVhY2ggc3VjaCBsYW5ndWFnZSBhcnJheSBpcyBkZWNsYXJlZCBpbiB0aGUgbG9jYWxpemUgYXJyYXkKICAgIC8vIHRoaXMgaXMgdXNlZCBhcyBpbiAgdzNjX3NsaWR5LmxvY2FsaXplKCJmb28iKTsKICAgIHRoaXMuc3RyaW5ncyA9IHsKICAgICAgImVzIjp0aGlzLnN0cmluZ3NfZXMsCiAgICAgICJjYSI6dGhpcy5zdHJpbmdzX2NhLAogICAgICAiY3MiOnRoaXMuc3RyaW5nc19jcywKICAgICAgIm5sIjp0aGlzLnN0cmluZ3NfbmwsCiAgICAgICJkZSI6dGhpcy5zdHJpbmdzX2RlLAogICAgICAicGwiOnRoaXMuc3RyaW5nc19wbCwKICAgICAgImZyIjp0aGlzLnN0cmluZ3NfZnIsCiAgICAgICJodSI6dGhpcy5zdHJpbmdzX2h1LAogICAgICAiaXQiOnRoaXMuc3RyaW5nc19pdCwKICAgICAgImVsIjp0aGlzLnN0cmluZ3NfZWwsCiAgICAgICJqcCI6dGhpcy5zdHJpbmdzX2phLAogICAgICAiemgiOnRoaXMuc3RyaW5nc196aCwKICAgICAgInJ1Ijp0aGlzLnN0cmluZ3NfcnUsCiAgICAgICJzdiI6dGhpcy5zdHJpbmdzX3N2CiAgICB9LAoKICAgIGkxOG4uc3RyaW5nc19lc1toZWxwX3RleHRdID0gaTE4bi5oZWxwX2VzOwogICAgaTE4bi5zdHJpbmdzX2NhW2hlbHBfdGV4dF0gPSBpMThuLmhlbHBfY2E7CiAgICBpMThuLnN0cmluZ3NfY3NbaGVscF90ZXh0XSA9IGkxOG4uaGVscF9jczsKICAgIGkxOG4uc3RyaW5nc19ubFtoZWxwX3RleHRdID0gaTE4bi5oZWxwX25sOwogICAgaTE4bi5zdHJpbmdzX2RlW2hlbHBfdGV4dF0gPSBpMThuLmhlbHBfZGU7CiAgICBpMThuLnN0cmluZ3NfcGxbaGVscF90ZXh0XSA9IGkxOG4uaGVscF9wbDsKICAgIGkxOG4uc3RyaW5nc19mcltoZWxwX3RleHRdID0gaTE4bi5oZWxwX2ZyOwogICAgaTE4bi5zdHJpbmdzX2h1W2hlbHBfdGV4dF0gPSBpMThuLmhlbHBfaHU7CiAgICBpMThuLnN0cmluZ3NfaXRbaGVscF90ZXh0XSA9IGkxOG4uaGVscF9pdDsKICAgIGkxOG4uc3RyaW5nc19lbFtoZWxwX3RleHRdID0gaTE4bi5oZWxwX2VsOwogICAgaTE4bi5zdHJpbmdzX2phW2hlbHBfdGV4dF0gPSBpMThuLmhlbHBfamE7CiAgICBpMThuLnN0cmluZ3NfemhbaGVscF90ZXh0XSA9IGkxOG4uaGVscF96aDsKICAgIGkxOG4uc3RyaW5nc19ydVtoZWxwX3RleHRdID0gaTE4bi5oZWxwX3J1OwogICAgaTE4bi5zdHJpbmdzX3N2W2hlbHBfdGV4dF0gPSBpMThuLmhlbHBfc3Y7CgogICAgdzNjX3NsaWR5LmxhbmcgPSBkb2N1bWVudC5ib2R5LnBhcmVudE5vZGUuZ2V0QXR0cmlidXRlKCJsYW5nIik7CgogICAgaWYgKCF3M2Nfc2xpZHkubGFuZykKICAgICAgdzNjX3NsaWR5LmxhbmcgPSBkb2N1bWVudC5ib2R5LnBhcmVudE5vZGUuZ2V0QXR0cmlidXRlKCJ4bWw6bGFuZyIpOwoKICAgIGlmICghdzNjX3NsaWR5LmxhbmcpCiAgICAgIHczY19zbGlkeS5sYW5nID0gImVuIjsKICB9Cn07CgovLyBoYWNrIGZvciBiYWNrIGJ1dHRvbiBiZWhhdmlvcgppZiAodzNjX3NsaWR5LmllNiB8fCB3M2Nfc2xpZHkuaWU3KQp7CiAgZG9jdW1lbnQud3JpdGUoIjxpZnJhbWUgaWQ9J2hpc3RvcnlGcmFtZScgIiArCiAgInNyYz0namF2YXNjcmlwdDpcIjxodG1sIisiPjwvIisiaHRtbD5cIicgIiArCiAgImhlaWdodD0nMScgd2lkdGg9JzEnICIgKwogICJzdHlsZT0ncG9zaXRpb246YWJzb2x1dGU7bGVmdDotODAwcHgnPjwvaWZyYW1lPiIpOwp9CgovLyBhdHRhY2ggZXZlbnQgbGlzdGVuZXJzIGZvciBpbml0aWFsaXphdGlvbgp3M2Nfc2xpZHkuc2V0X3VwKCk7CgovLyBoaWRlIHRoZSBzbGlkZXMgYXMgc29vbiBhcyBib2R5IGVsZW1lbnQgaXMgYXZhaWxhYmxlCi8vIHRvIHJlZHVjZSBhbm5veWluZyBzY3JlZW4gbWVzcyBiZWZvcmUgdGhlIG9ubG9hZCBldmVudApzZXRUaW1lb3V0KHczY19zbGlkeS5oaWRlX3NsaWRlcywgNTApOwoK"></script> +</head> +<body> +<div class="slide titlepage"> + <h1 class="title">R#4: data transformation</h1> + <p class="author"> +Laurent Modolo <a href="mailto:laurent.modolo@ens-lyon.fr">laurent.modolo@ens-lyon.fr</a> + </p> + <p class="date">08 Nov 2019</p> +</div> +<div id="r4-data-transformation" class="slide section level2"> +<h1>R#4: data transformation</h1> +<p>The goal of this practical is to practices data transformation with <code>tidyverse</code>. The objectives of this session will be to:</p> +<ul> +<li>Filter rows with <code>filter()</code></li> +<li>Arrange rows with <code>arrange()</code></li> +<li>Select columns with <code>select()</code></li> +<li>Add new variables with <code>mutate()</code></li> +<li>Combining multiple operations with the pipe <code>%>%</code></li> +</ul> +</div> +<div id="nycflights13" class="slide section level2"> +<h1><strong>nycflights13</strong></h1> +<p><code>nycflights13::flights</code>contains all 336,776 flights that departed from New York City in 2013. The data comes from the US Bureau of Transportation Statistics, and is documented in <code>?flights</code></p> +</div> +<div id="nycflights13-1" class="slide section level2"> +<h1><strong>nycflights13</strong></h1> +<ul> +<li><strong>int</strong> stands for integers.</li> +<li><strong>dbl</strong> stands for doubles, or real numbers.</li> +<li><strong>chr</strong> stands for character vectors, or strings.</li> +<li><strong>dttm</strong> stands for date-times (a date + a time).</li> +<li><strong>lgl</strong> stands for logical, vectors that contain only TRUE or FALSE.</li> +<li><strong>fctr</strong> stands for factors, which R uses to represent categorical variables with fixed possible values.</li> +<li><strong>date</strong> stands for dates.</li> +</ul> +</div> +<div id="filter-rows-with-filter" class="slide section level2"> +<h1>Filter rows with <code>filter()</code></h1> +<p><code>filter()</code> allows you to subset observations based on their values.</p> +<pre><code>## # A tibble: 842 x 19 +## year month day dep_time sched_dep_time dep_delay arr_time +## <int> <int> <int> <int> <int> <dbl> <int> +## 1 2013 1 1 517 515 2 830 +## 2 2013 1 1 533 529 4 850 +## 3 2013 1 1 542 540 2 923 +## 4 2013 1 1 544 545 -1 1004 +## 5 2013 1 1 554 600 -6 812 +## 6 2013 1 1 554 558 -4 740 +## 7 2013 1 1 555 600 -5 913 +## 8 2013 1 1 557 600 -3 709 +## 9 2013 1 1 557 600 -3 838 +## 10 2013 1 1 558 600 -2 753 +## # … with 832 more rows, and 12 more variables: sched_arr_time <int>, +## # arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>, +## # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>, +## # minute <dbl>, time_hour <dttm></code></pre> +</div> +<div id="filter-rows-with-filter-1" class="slide section level2"> +<h1>Filter rows with <code>filter()</code></h1> +<p><code>dplyr</code> functions never modify their inputs, so if you want to save the result, you’ll need to use the assignment operator, <code><-</code></p> +<p>R either prints out the results, or saves them to a variable.</p> +<pre><code>## # A tibble: 719 x 19 +## year month day dep_time sched_dep_time dep_delay arr_time +## <int> <int> <int> <int> <int> <dbl> <int> +## 1 2013 12 25 456 500 -4 649 +## 2 2013 12 25 524 515 9 805 +## 3 2013 12 25 542 540 2 832 +## 4 2013 12 25 546 550 -4 1022 +## 5 2013 12 25 556 600 -4 730 +## 6 2013 12 25 557 600 -3 743 +## 7 2013 12 25 557 600 -3 818 +## 8 2013 12 25 559 600 -1 855 +## 9 2013 12 25 559 600 -1 849 +## 10 2013 12 25 600 600 0 850 +## # … with 709 more rows, and 12 more variables: sched_arr_time <int>, +## # arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>, +## # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>, +## # minute <dbl>, time_hour <dttm></code></pre> +</div> +<div id="logical-operators" class="slide section level2"> +<h1>Logical operators</h1> +<p>Multiple arguments to <code>filter()</code> are combined with “andâ€: every expression must be true in order for a row to be included in the output.</p> +<p><img src="data:image/png;base64,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W/IOx02G1fIDBgGO4IgNbJkGCHY1lOto3dBjHXjggfEp11EKLly40KgVvVpAtljZsNloDWFysWHDhqeeegqaX331VaOBI2Ib7j34nw8XsQYdsm0j/LBn8/GaaFAznHTSSWzYSC8ZNOufioAi4B8BWIwjOJ8lS5aYuxDU2Z5hcTQaOOqgwDM/RXtBKBcnG7gbNmfn9vpAsh7C4LA5sRMZg6I7FHUGt5ifxFApaynSDqoN81O0F6yEH3zwgayl/OvVcdSqVQuaWU65iHZQ7U0RCIBA0XA32tUmTZrIisSmHyt3o4yQFYl/vQZY5e4Ab6BDt1gqPzz33HO33377K6+8wiFe0MSY3rlzZ7YZtuf49uYcMzd//nwUjRm6Rvjz4osv7tixI/EG2BkGDx48ZcoU4/EMAx933HHt27dH1EklvhkNweTJk5988kksKubR0Fb27t379NNPj1WMMcPphSJQHAgQLjlp0qQ777zTewRH03biP58GDRok/5gsj+j/UFg888wz33zzjRCAmfGoo4665JJLWrVqxTcvvvgiayn/mrXU2CRRxKQSKIVehoUUAezzzz83oCH89OnTB+EnPpWQGUsvFIEMBJzm7hdeeMEoK//973+3adOGUweHk1S4+8MPP3z66adZlLxekcrdGe9bcfxpl/yAag0l2aBBg9hgBF80ZOzOKKjYEW3YV+DSN954A/PCE088YeRsOBZqsTwIzYgKUNuhQ4eWLVtackaHpZEi4GqcqoVI5LELL7ywV69eQrx8qf8qAopANgLY6x999FFO4Qjk8is+h2zS8DibtA1ugayc6PXh8WnTpuG4LETC4+St/uGHH+RPvJzbtm3LWsq6ZMNaClVoK1lLJ06caCwSxFog+Zx55plhPL7kefVfRcAPAsXB3Sgr0RewIh1xxBGWcDeqDVYkVBvmpKTc7eeFdKiNLfIDHr0jRoxgh8abX+DDzoA6ik3aznINbNgYSTiC4who5ps97/x/PmFch01vkV8g/GAkeeSRR2BpSRwJweecc07fvn3xbop8OO1QEXAdAZQC99577913323cF4888sizzz778MMPt2STzkCYlPOYQK+77jpDMA1Yjq688kqUBXYeylmLXn755WHDhiH8iBoVC8kF/3xIX5HxgPqnIhAVAsXB3UQycFKyVuSGu1FtPPzwwxhJZOKUu6N6gVPvJ335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" width="100%" /></p> +</div> +<div id="logical-operators-1" class="slide section level2"> +<h1>Logical operators</h1> +<p>Test the following operations:</p> +<pre><code>## # A tibble: 55,403 x 19 +## year month day dep_time sched_dep_time dep_delay arr_time +## <int> <int> <int> <int> <int> <dbl> <int> +## 1 2013 11 1 5 2359 6 352 +## 2 2013 11 1 35 2250 105 123 +## 3 2013 11 1 455 500 -5 641 +## 4 2013 11 1 539 545 -6 856 +## 5 2013 11 1 542 545 -3 831 +## 6 2013 11 1 549 600 -11 912 +## 7 2013 11 1 550 600 -10 705 +## 8 2013 11 1 554 600 -6 659 +## 9 2013 11 1 554 600 -6 826 +## 10 2013 11 1 554 600 -6 749 +## # … with 55,393 more rows, and 12 more variables: sched_arr_time <int>, +## # arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>, +## # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>, +## # minute <dbl>, time_hour <dttm></code></pre> +<pre><code>## # A tibble: 55,403 x 19 +## year month day dep_time sched_dep_time dep_delay arr_time +## <int> <int> <int> <int> <int> <dbl> <int> +## 1 2013 11 1 5 2359 6 352 +## 2 2013 11 1 35 2250 105 123 +## 3 2013 11 1 455 500 -5 641 +## 4 2013 11 1 539 545 -6 856 +## 5 2013 11 1 542 545 -3 831 +## 6 2013 11 1 549 600 -11 912 +## 7 2013 11 1 550 600 -10 705 +## 8 2013 11 1 554 600 -6 659 +## 9 2013 11 1 554 600 -6 826 +## 10 2013 11 1 554 600 -6 749 +## # … with 55,393 more rows, and 12 more variables: sched_arr_time <int>, +## # arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>, +## # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>, +## # minute <dbl>, time_hour <dttm></code></pre> +<pre><code>## # A tibble: 316,050 x 19 +## year month day dep_time sched_dep_time dep_delay arr_time +## <int> <int> <int> <int> <int> <dbl> <int> +## 1 2013 1 1 517 515 2 830 +## 2 2013 1 1 533 529 4 850 +## 3 2013 1 1 542 540 2 923 +## 4 2013 1 1 544 545 -1 1004 +## 5 2013 1 1 554 600 -6 812 +## 6 2013 1 1 554 558 -4 740 +## 7 2013 1 1 555 600 -5 913 +## 8 2013 1 1 557 600 -3 709 +## 9 2013 1 1 557 600 -3 838 +## 10 2013 1 1 558 600 -2 753 +## # … with 316,040 more rows, and 12 more variables: sched_arr_time <int>, +## # arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>, +## # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>, +## # minute <dbl>, time_hour <dttm></code></pre> +<pre><code>## # A tibble: 316,050 x 19 +## year month day dep_time sched_dep_time dep_delay arr_time +## <int> <int> <int> <int> <int> <dbl> <int> +## 1 2013 1 1 517 515 2 830 +## 2 2013 1 1 533 529 4 850 +## 3 2013 1 1 542 540 2 923 +## 4 2013 1 1 544 545 -1 1004 +## 5 2013 1 1 554 600 -6 812 +## 6 2013 1 1 554 558 -4 740 +## 7 2013 1 1 555 600 -5 913 +## 8 2013 1 1 557 600 -3 709 +## 9 2013 1 1 557 600 -3 838 +## 10 2013 1 1 558 600 -2 753 +## # … with 316,040 more rows, and 12 more variables: sched_arr_time <int>, +## # arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>, +## # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>, +## # minute <dbl>, time_hour <dttm></code></pre> +</div> +<div id="missing-values" class="slide section level2"> +<h1>Missing values</h1> +<p>One important feature of R that can make comparison tricky are missing values, or <code>NA</code>s (“not availablesâ€).</p> +<pre><code>## [1] NA</code></pre> +<pre><code>## [1] NA</code></pre> +<pre><code>## [1] NA</code></pre> +<pre><code>## [1] NA</code></pre> +</div> +<div id="missing-values-1" class="slide section level2"> +<h1>Missing values</h1> +<pre><code>## [1] NA</code></pre> +<pre><code>## [1] TRUE</code></pre> +</div> +<div id="filter-challenges" class="slide section level2"> +<h1>Filter challenges</h1> +<p>Find all flights that:</p> +<ul> +<li>Had an arrival delay of two or more hours</li> +<li>Were operated by United, American, or Delta</li> +<li>Departed between midnight and 6am (inclusive)</li> +</ul> +<p>Another useful dplyr filtering helper is <code>between()</code>. What does it do? Can you use it to simplify the code needed to answer the previous challenges?</p> +<p>How many flights have a missing <code>dep_time</code>? What other variables are missing? What might these rows represent?</p> +<p>Why is <code>NA ^ 0</code> not <code>NA</code>? Why is <code>NA | TRUE</code> not <code>NA</code>? Why is <code>FALSE & NA</code> not <code>NA</code>? Can you figure out the general rule? (<code>NA * 0</code> is a tricky counter-example!)</p> +</div> +<div id="arrange-rows-with-arrange" class="slide section level2"> +<h1>Arrange rows with <code>arrange()</code></h1> +<p><code>arrange()</code> works similarly to <code>filter()</code> except that instead of selecting rows, it changes their order.</p> +<p>Use <code>desc()</code> to re-order by a column in descending order:</p> +<p>Missing values are always sorted at the end:</p> +</div> +<div id="arrange-challenges" class="slide section level2"> +<h1>Arrange challenges</h1> +<ul> +<li>Sort flights to find the most delayed flights. Find the flights that left earliest.</li> +<li>Sort flights to find the fastest flights.</li> +<li>Which flights traveled the longest? Which traveled the shortest?</li> +</ul> +</div> +<div id="select-columns-with-select" class="slide section level2"> +<h1>Select columns with <code>select()</code></h1> +<p><code>select()</code> allows you to rapidly zoom in on a useful subset using operations based on the names of the variables.</p> +</div> +<div id="select-columns-with-select-1" class="slide section level2"> +<h1>Select columns with <code>select()</code></h1> +<p>here are a number of helper functions you can use within <code>select()</code>:</p> +<ul> +<li><code>starts_with("abc")</code>: matches names that begin with “abcâ€.</li> +<li><code>ends_with("xyz")</code>: matches names that end with “xyzâ€.</li> +<li><code>contains("ijk")</code>: matches names that contain “ijkâ€.</li> +<li><code>matches("(.)\\1")</code>: selects variables that match a regular expression. This one matches any variables that contain repeated characters. You’ll learn more about regular expressions in strings.</li> +<li><code>num_range("x", 1:3)</code>: matches <code>x1</code>, <code>x2</code> and <code>x3</code>.</li> +</ul> +<p>See <code>?select</code> for more details.</p> +</div> +<div id="select-challenges" class="slide section level2"> +<h1>Select challenges</h1> +<ul> +<li><p>Brainstorm as many ways as possible to select <code>dep_time</code>, <code>dep_delay</code>, <code>arr_time</code>, and <code>arr_delay</code> from <code>flights</code>.</p></li> +<li><p>What does the <code>one_of()</code> function do? Why might it be helpful in conjunction with this vector?</p></li> +<li><p>Does the result of running the following code surprise you? How do the select helpers deal with case by default? How can you change that default?</p></li> +</ul> +</div> +<div id="add-new-variables-with-mutate" class="slide section level2"> +<h1>Add new variables with <code>mutate()</code></h1> +<p>It’s often useful to add new columns that are functions of existing columns. That’s the job of <code>mutate()</code>.</p> +<p><strong>4_a</strong></p> +</div> +<div id="add-new-variables-with-mutate-1" class="slide section level2"> +<h1>Add new variables with <code>mutate()</code></h1> +<p>You can refer to columns that you’ve just created:</p> +</div> +<div id="useful-creation-functions" class="slide section level2"> +<h1>Useful creation functions</h1> +<ul> +<li>Offsets: <code>lead()</code> and <code>lag()</code> allow you to refer to leading or lagging values. This allows you to compute running differences (e.g. <code>x - lag(x)</code>) or find when values change (<code>x != lag(x)</code>).</li> +<li>Cumulative and rolling aggregates: R provides functions for running sums, products, mins and maxes: <code>cumsum()</code>, <code>cumprod()</code>, <code>cummin()</code>, <code>cummax()</code>; and dplyr provides <code>cummean()</code> for cumulative means.</li> +<li>Logical comparisons, <code><</code>, <code><=</code>, <code>></code>, <code>>=</code>, <code>!=</code>, and <code>==</code></li> +<li>Ranking: there are a number of ranking functions, but you should start with <code>min_rank()</code>. There is also <code>row_number()</code>, <code>dense_rank()</code>, <code>percent_rank()</code>, <code>cume_dist()</code>, <code>ntile()</code></li> +</ul> +</div> +<div id="mutate-challenges" class="slide section level2"> +<h1>Mutate challenges</h1> +<ul> +<li>Currently <code>dep_time</code> and <code>sched_dep_time</code> are convenient to look at, but hard to compute with because they’re not really continuous numbers. Convert them to a more convenient representation of number of minutes since midnight.</li> +</ul> + +<p><strong>4_b</strong></p> +</div> +<div id="mutate-challenges-1" class="slide section level2"> +<h1>Mutate challenges</h1> +<ul> +<li>Compare <code>dep_time</code>, <code>sched_dep_time</code>, and <code>dep_delay</code>. How would you expect those three numbers to be related?</li> +</ul> + +<p><strong>4_c</strong></p> +</div> +<div id="mutate-challenges-2" class="slide section level2"> +<h1>Mutate challenges</h1> +<ul> +<li>Find the 10 most delayed flights using a ranking function. How do you want to handle ties? Carefully read the documentation for <code>min_rank()</code></li> +</ul> + +<p><strong>4_d</strong></p> +</div> +<div id="combining-multiple-operations-with-the-pipe" class="slide section level2"> +<h1>Combining multiple operations with the pipe</h1> +<p>We don’t want to create useless intermediate variables so we can use the pipe opperator: <code>%>%</code> (<code>ctrl + shift + M</code>).</p> +</div> +<div id="combining-multiple-operations-with-the-pipe-1" class="slide section level2"> +<h1>Combining multiple operations with the pipe</h1> +<p>We don’t want to create useless intermediate variables so we can use the pipe opperator: <code>%>%</code> (<code>ctrl + shift + M</code>).</p> +</div> +<div id="combining-multiple-operations-with-the-pipe-2" class="slide section level2"> +<h1>Combining multiple operations with the pipe</h1> +<p>Behind the scenes, <code>x %>% f(y)</code> turns into <code>f(x, y)</code>, and <code>x %>% f(y) %>% g(z)</code> turns into <code>g(f(x, y), z)</code> and so on. You can use the pipe to rewrite multiple operations in a way that you can read left-to-right, top-to-bottom.</p> +<p>You can access the transmited variables with <code>.</code></p> +<p>Working with the pipe is one of the key criteria for belonging to the <code>tidyverse</code>. The only exception is <code>ggplot2</code>: it was written before the pipe was discovered. Unfortunately, the next iteration of <code>ggplot2</code>, <code>ggvis</code>, which does use the pipe, isn’t quite ready for prime time yet.</p> +</div> + + <!-- dynamically load mathjax for compatibility with self-contained --> + <script> + (function () { + var script = document.createElement("script"); + script.type = "text/javascript"; + script.src = "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"; + document.getElementsByTagName("head")[0].appendChild(script); + })(); + </script> + +</body> +</html>