Nejistoty a chyby měření

Ze zásilky kaprolaktamu bylo odebráno 10 vzorku a byl u nich stanoven bod tání. Vypočítejte průměrnou hodnotu bodu tání v zásilce a její směrodatnou odchylku.

Šíření chyb

Vypočítejte hustotu a její chybu pro látku, u níž byla opakovaným měřením stanovena hmotnost 6.824 (0.008) g a objem 3.03 (0.01) ml.

Na píst o průměru 200 (0.05) mm působí pára tlakem 8.2 (0.1) atm. Jakou silou působí pára na píst?

Vypočítejte koeficient viskozity roztoku glycerinu Stokesovou metodou

Vypočítejte koeficient viskozity roztoku glycerinu pomocí kapilárního viskozimetru.

Součin rozpustnosti stříbrné soli AgX má hodnotu Ks = 4.0 (0.4) x 10^-8. Jaká je chyba vypočtené rovnovážné koncentrace stříbrných iontů ve vode?

Nejistoty a korelace

Import dat

Export dat

Čísla dle Chemical Abstracts Service (CAS)

BCPC Compendium of Pesticide Common Names https://pesticidecompendium.bcpc.org formerly known as Alan Woods Compendium of Pesticide Common Names http://www.alanwood.net/pesticides

ChemicalIdentifierResolver(CIR) http://cactus.nci.nih.gov/chemical/

ChemicalIdentifierResolver(CIR) https://cactus.nci.nih.gov/chemical/structure

The smiles are as following:
          glyphosate 
OC(=O)CNC[P](O)(O)=O 

Chemical Translation Service (CTS) http://cts.fiehnlab.ucdavis.edu/

     XEFQLINVKFYRCS-UHFFFAOYSA-N BSYNRYMUTXBXSQ-UHFFFAOYSA-N
[1,] "C12H7Cl3O2"                "C9H8O4"                   
[2,] "289.54204"                 "180.15777"                

PubChem https://pubchem.ncbi.nlm.nih.gov/ CompoundID (CID) for a search query using PUG-REST https://pubchem.ncbi. nlm.nih.gov/

ETOX: Information System Ecotoxicology and Environmental Quality Targets https:// webetox.uba.de/webETOX/index.do

$Triclosan
[1] NA

$Aspirin
[1] NA

attr(,"class")
[1] "etox_basic" "list"      

Wikidata Item ID

Querying Q408646. OK (HTTP 200).
 Multiple found. Returning all.

Flavor percepts http://www.flavornet.org

Querying 75-07-0. OK (HTTP 200).
Querying 64-17-5. OK (HTTP 200).
Querying 109-66-0. OK (HTTP 200).
Querying 78-94-4. Not Found (HTTP 404).
Querying 78-93-3. OK (HTTP 200).
         75-07-0          64-17-5         109-66-0          78-94-4 
"pungent, ether"          "sweet"         "alkane"               NA 
         78-93-3 
         "ether" 

ChemIDPlus http://chem.sis.nlm.nih.gov/chemidplus http://cts.fiehnlab.ucdavis.edu/

50-00-0 
   0.35 

Query the OPSIN (Open Parser for Systematic IUPAC nomenclature) web service http://opsin.ch.cam.ac.uk/instructions.html

Querying Cyclopropane. OK (HTTP 200).
Querying Octane. OK (HTTP 200).

Acute toxicity data from U.S. EPA ECOTOX

[1] "C:/Program Files/R/R-4.1.1/library/PesticideLoadIndicator/extdata/products.xlsx"
NULL


as.character(3.14)
as.character(pi)

data <- c(-11, 21, 1.5, -31)
as.character(data)


## number of strings
length("BaCrO4")
length("How many characters?")
length(c("How", "many", "characters?"))

## number of charaters
nchar("BaCrO4")
nchar("How many characters?")
nchar(c("How", "many", "characters?"))

library(stringr)
str_length("BaCrO4")
str_length("How many characters?")
str_length(c("How", "many", "characters?"))

some_text = c("one", "two", "three", NA, "five")
str_length(some_text)
nchar(some_text)

some_factor = factor(c(1, 1, 1, 2, 2, 2), labels = c("good", "bad"))
some_factor
str_length(some_factor)
nchar(some_factor)


# Usporadani

set11 = c("today", "produced", "example", "beautiful", "a", "nicely")
# sort (decreasing order)
sort(set11)
# sort (increasing order)
sort(set11, decreasing = TRUE)


library(stringi)
stri_reverse("dna")
stri_reverse(set11)


### Spojovani retezcu

toString(17.04)
toString(c(17.04, 1978))
toString(c("Bonjour", 123, TRUE, NA, log(exp(1))))


## paste

paste("This is",  "out of",   "examples.")
paste0("This is",  "out of",  "examples.") 
paste0("This is",  " out of",  " examples.")

a <- "acetic"
b <- "acid"
c <- "anhydride"

d1 <- paste(a, b, c); d1
d2 <- paste(a, b, c, sep = "-"); d2

paste("I", "love", "R", sep = "-")


str <- paste(c(1:3), "4", sep = ":")
print (str)

str <- paste(c(1:4), c(5:8), sep = "--")
print (str)

paste("X", 1:5, sep = ".")

paste(1:3, c("!", "?", "+"))
paste(1:3, c("!", "?", "+"), sep = "")
paste0(1:3, c("!", "?", "+"))
paste(1:3, c("!", "?", "+"), sep = "", collapse = "")
paste0(1:3, c("!", "?", "+"), collapse = "")

paste("The value of pi is", round(pi,3), "and value of e is", round(exp(1),3),".")


df <- data.frame(cation=c('sodium','mercury','iron','calcium'),
                 anion=c('acetate','sulphate','dioxide','oxalate'),
                 purity=c(0.99, 0.9, 0.999, 0.985))
df
df$name = paste(df$cation, df$anion)
df

library(stringr)
str_c("May", "The", "Force", "Be", "With", "You")


library(stringr)
str_c("May", "The", "Force", NULL, "Be", "With", "You", character(0))
paste("May", "The", "Force", NULL, "Be", "With", "You", character(0))

str_c("May", "The", "Force", "Be", "With", "You", sep = "_")

# str_join("May", "The", "Force", "Be", "With", "You", sep = "-") 
# analogicka fce k predchozi


## cat - pouze vypisuje retezec

cat("learn", "code", "tech", sep = ":")
str <- cat("learn", "code", "tech", sep = ":") # nelze ulozit do promenne
print (str) 

my_string = c("learn", "code", "tech")
cat(my_string, "with R")
cat(my_string, "with R", sep = " =) ")

cat(1:10, sep = "-")
cat(month.name[1:4], sep = " ")

cat(c(1:5), file ='sample.txt')
cat(my_string, "with R", file = "output.txt")
cat(11:20, sep = '\n', file = 'temp.csv')
readLines('temp.csv') # read the file temp.csv

cat("The value of pi is", round(pi,3), "and value of e is", round(exp(1),3),".")


## print - vypisuje vsechny formaty

print(df)
df

my_value <- 8235.675324 
my_value
print(my_value) 
print(my_value, digits = 5) 

print(c("learn", "code", "tech"))
paste(c("learn", "code", "tech"))
paste(c("learn", "code", "tech"), collapse=" ")
cat(c("learn", "code", "tech"))

my_string <- "This is \nthe example string" 
print(my_string)  
cat(my_string) 


### 

library(stringr)

str_dup("hola", 3)
str_dup("adios", 1:3)

words = c("lorem", "ipsum", "dolor", "sit", "amet")
str_dup(words, 2)
str_dup(words, 1:5)


####

format(c("A", "BB", "CCC"), width = 5, justify = "centre")
format(c("A", "BB", "CCC"), width = 5, justify = "left")
format(c("A", "BB", "CCC"), width = 5, justify = "right")
format(c("A", "BB", "CCC"), width = 5, justify = "none")

library(stringr)
str_pad("hola", width = 7)
str_pad("adios", width = 7, side = "both")
str_pad("hashtag", width = 8, pad = "#")
str_pad("hashtag", width = 9, side = "both", pad = "-")


##### editace ciselnych retezcu

## sprintf

# '%f' indicates 'fixed point' decimal notation
sprintf("%f", pi)
sprintf("%f", 123.45)
sprintf("%f", 123.456789)
# decimal notation with 3 decimal digits
sprintf("%.3f", pi)
sprintf("%.3f", 123.456789)
# 1 integer and 0 decimal digits
sprintf("%1.0f", pi)
sprintf("%1.0f", 123.456789)
# decimal notation with 3 decimal digits
sprintf("%5.1f", pi)
sprintf("%05.1f", pi)
sprintf("%6.1f", 123.456789)
sprintf("%06.1f", 123.456789)
# print with sign (positive)
sprintf("%+f", pi)
sprintf("%+f", 123.456789)
# prefix a space
sprintf("% f", pi)
sprintf("% f", 123.456789)
# left adjustment
sprintf("%-10f", pi)
sprintf("%-10f", 123.456)
# exponential decimal notation 'e'
sprintf("%e", pi)
sprintf("%e", 123.456789)
# exponential decimal notation 'E'
sprintf("%E", pi)
sprintf("%E", 123.456789)
# number of significant digits (6 by default)
sprintf("%g", pi)
sprintf("%g", 123.456789)


## format

format(pi)
format(123.45)
format(123.456789)

format(123.45, nsmall = 5)
format(12.3456789, nsmall=2)
format(12.3456789, nsmall=7)
format(12.3, nsmall=3)

format(12.3456789, digits=2)
format(12.3456789, digits=5)
format(c(6, 13.1), digits = 2)

format(12.3456789, digits=5, nsmall = 6)
format(c(6, 13.1), digits = 2, nsmall = 2)

format(1/1:5, digits = 2)
format(format(1/1:5, digits = 2), width = 6, justify = "centre")


format(12345678, big.mark = ",") # oddeleni tisicu
format(1230, big.mark = ",")


## uvozovky ve vypisu retezce

my_string = "programming with data is fun"
print(my_string)
print(my_string, quote = FALSE)

noquote(my_string)

no_quotes = noquote(c("some", "quoted", "text", "!%^(&="))
no_quotes
no_quotes[2:3]

noquote(paste("I", "love", "R", sep = "-"))
noquote(cat("The value of pi is", round(pi,3), "and value of e is", round(exp(1),3),".")
)


dQuote(my_string)
sQuote(my_string)

x <- "2020-05-29 19:18:05"
dQuote(x)
sQuote(x)


########

substr(month.name, 1, 3)

substring(month.name, 1, 3)

strtrim(month.name, 3)


rs <- ("This is First R String Example")
strsplit(rs, split = " ")

rs <- ("This&is&First&R&String&Example")
strsplit(rs, split = "&")

a <- "Alabama-Alaska-Arizona-Arkansas-California"
strsplit(a, split = "-")

str = "Splitting sentence into words"
strsplit(str, " ")
unlist(strsplit(str, " "))


rs <- ("C21H22N2O2") # strychnin

strsplit(rs, split = "[0-9]+")[[1]]

strsplit(rs, split = "[A-Z]+")[[1]][-1]
strsplit(rs, "\\D+")[[1]][-1]
regmatches(rs, gregexpr("[[:digit:]]+", rs))
library(stringr)
str_extract_all(rs,"[0-9]+")[[1]]
library(strex)
str_extract_numbers(rs,decimals = FALSE)

rs <- ("C21H22N2O2")
strsplit(rs, split = "")

string_date<-c("2-07-2020","5-07-2020","6-07-2020",
               "7-07-2020","8-07-2020")
ssp = strsplit(string_date,split = "-"); ssp


# extract 'bcd'
substr("abcdef", start=2, stop=4)

substring("ABCDEF", 2, 4)

# extract each letter
substring("ABCDEF", 1:6, 1:6)


library(stringr)
lorem = "Lorem Ipsum"
substring(lorem, first = 1, last = 5)
str_sub(lorem, start = 1, end = 5)

str_sub("adios", 1:3)

resto = c("brasserie", "bistrot", "creperie", "bouchon")
substring(resto, first = -4, last = -1)
str_sub(resto, start = -4, end = -1)

str_sub(lorem, seq_len(nchar(lorem)))
substring(lorem, seq_len(nchar(lorem)))

str_sub(lorem,-2) 


### orezani mezer na koncich retezce

trimws(" This has trailing spaces.  ")

bad_text = c("This", " example ", "has several   ", "   whitespaces ")
trimws(bad_text)
library(stringr)
str_trim(bad_text, side = "left")
str_trim(bad_text, side = "right")
str_trim(bad_text, side = "both")


## replace
chartr(old = "All", new = "aLL", "All ChaRacterS in Upper Case") 
chartr("a", "A", "This is a boring string")
chartr("a", "0", "This is a bad example")

crazy = c("Here's to the crazy ones", "The misfits", "The rebels")
chartr("aei", "#!?", crazy)


x = c("may", "the", "force", "be", "with", "you")
substr(x, 2, 2) <- "#"
x
y = c("may", "the", "force", "be", "with", "you")
substr(y, 2, 3) <- ":)"
y

z = c("may", "the", "force", "be", "with", "you")
substr(z, 2, 3) <- c("#", "@")
z

text = c("more", "emotions", "are", "better", "than", "less")
substring(text, 1:3) <- c(" ", "zzz")
text


library(stringr)
lorem = "Lorem Ipsum"
str_sub(lorem, -1) <- "Nullam"
lorem

lorem = "Lorem Ipsum"
str_sub(lorem, 1, 5) <- "Nullam"
lorem

lorem = "Lorem Ipsum"
str_sub(lorem, c(1, 7), c(5, 8)) <- c("Nullam", "Enim")
lorem


## to lower case
tolower("BaCrO4")
tolower(c("aLL ChaRacterS in LoweR caSe", "ABCDE"))
casefold("aLL ChaRacterS in LoweR caSe")

## to upper case
toupper("BaCrO4")
toupper(c("All ChaRacterS in Upper Case", "abcde"))
casefold("All ChaRacterS in Upper Case", upper = TRUE)


### filtrovani

startsWith(month.name, "J")
endsWith(month.name, "ember")

myStrings <- paste(1:3, month.name, sep = ". ")
myStrings
# Is a pattern present (returns a logical vector)?
grepl("ember", myStrings)
# In which elements is a pattern present (returns indices)?
grep("ember", myStrings)
# In which elements is a pattern present (returns the values)?
grep("ember", myStrings, value = TRUE)

x1<-c("R is a programming language and programming software environment",
      "R is freely available under the GNU General Public License",
      "This programming language was named R")
grep("programming",x1,fixed=TRUE)


# Srovnani 2 retezcu
message1 <- "Pro"
message2 <- "Pro"
message3 <- "pRO"
message1 == message2
message1 == message3

# Hledani retezce v jinem retezci
str <- "Hello World!"
grepl("H", str)
grepl("Hello", str)
grepl("X", str)
grepl(message1, message2)
grepl(message1, message3)

identical(message1, message2)
identical(message1, message3)
identical(tolower(message1), tolower(message3))

message1[message1 %in% message2]
message1[message1 %in% message3]  
message1[tolower(message1) %in% tolower(message3)] 

vector1 <- c("hey", "hello", "greetings")
vector2 <- c("hey", "hello", "hi")
vector1[vector1 %in% vector2]


###

library(stringr)

change = c("Be the change", "you want to be")
# extract first word
word(change, 1)
# extract second word
word(change, 2)
# extract last word
word(change, -1)
# extract all but the first words
word(change, 2, -1)

word(change,start=1,end=2,sep=fixed(" "))


data <-  c('Ab_Cd-001234.txt','Ab_Cd-001234.txt')

gsub('.*-([0-9]+).*','\\1','Ab_Cd-001234.txt')
x <- c('Ab_Cd-001234.txt','Ab_Cd-001234.txt')
sub('.*-([0-9]+).*','\\1',x)

library(stringr)
regexp <- "[[:digit:]]+"
str_extract(data, regexp)

library(qdap)
genXtract("Ab_Cd-001234.txt", "-", ".txt")
x <- c('Ab_Cd-001234.txt','Ab_Cd-001234.txt')
genXtract(x, "-", ".txt")

library(tools)
sub(".*-", "", file_path_sans_ext(x))

library(gsubfn)
strapplyc(x, "-(\\d+)\\.", simplify = TRUE)
strapply(x, "-(\\d+)\\.", as.numeric, simplify = TRUE)


x <- c("a very nice character string")  
library(stringr)
str_replace(x, "c", "xxx")
str_replace_all(x, "c", "xxx")

x <- "aaabbb" 
sub("a", "c", x)  
gsub("a", "c", x)
sub("a|b", "c", x)
gsub("a|b", "c", x)  

x <- c("d", "a", "c", "abba") 
grep("a", x)
grepl("a", x)
grep("a|c", x)
grepl("a|c", x)

regexpr("a", x)
gregexpr("a", x)
regexec("a", x) 

x <- "example_xxx_string"
library(stringr)
str_sub(string = x, start = 8, end = 12)
str_sub(string = x, start = 8, end = 12) <- " character "  # Replace substring
x  

x <- "xxxxyxxyxaaaaaay"
x 
sub("y", "NEW", x) 
gsub("y", "NEW", x)

library(stringr)
str_replace(x, "y", "NEW")
str_replace_all(x, "y", "NEW")

Kvadraticke a kubicke rovnice

Velikost výslednice dvou navzajem kolmých sil je 34 N. Jaká je velikost skládaných sil, je-li jedna z nich o 14 N větší než druha?

[1] -30

Tlaková láhev s oxidem uhličitým obsahuje 10.0 kg plynu. Jaký objem zaujímá stlačený plyn, když při teplotě 30 °C je tlak v láhvi 13.17e-6 Pa? Výpočet proved’te pomocí van der Waalsovy rovnice.

Jake pH má roztok kyseliny mravenčí o koncentraci 8.5 x 10-4 mol/l?

Soustavy lineárních rovnic

Ze dvou slitin s 60% a 80% obsahem mědi se ma získat 40 kg slitiny se 75% obsahem mědi. Kolik kg každé slitiny je třeba použít? [10 a 30 kg]

library(rootSolve)
model <- function(x){
  F1 <- 0.6*x[1] + 0.8*x[2] - 30
  F2 <- x[1] + x[2] - 40
  c(F1 = F1, F2 = F2)}
ss <- multiroot(f = model, start = c(1, 1))
ss$root
[1]  9.999999 29.999998
### graficke reseni
# 0.6*m1 + 0.8*m2 = 40*0.75 => m1 = 40*0.75/0.6 - 0.8/0.6 * m2  => m1 = 50 - 1.33 * m2 
# m1 + m2 = 40  => m1 = 40 - m2
xx = seq(0,50,0.1)
yy = 50 - 1.33*xx
zz = 40 - xx
plot(xx, yy, type="l",col=2)
points(xx, zz, type="l",col=4)

plot(xx, yy, type="l",col=2,xlim=c(25,35),ylim=c(0,20))
points(xx, zz, type="l",col=4)

Do bazenu natece prutokem A za 3 h a prutokem B za 4 h celkem 2150 hl vody. Prutokem A za 4 h a prutokem B za 2 h by nateklo 1700 hl vody. Kolik hl vody natece prutokem A a kolik prutokem B za 1 hodinu? A 250 hl, B 350 hl

library(rootSolve)
model <- function(x){
  F1 <- 3*x[1] + 4*x[2] - 2150
  F2 <- 4*x[1] + 2*x[2] - 1700
  c(F1 = F1, F2 = F2)}
ss <- multiroot(f = model, start = c(1, 1))
ss$root
[1] 250 350
### graficke reseni
# 3*m1 + 4*m2 = 2150 => m2 = 2150/4 - 3/4 * m1  => m2 = 537.5 - 0.75 * m1
# 4*m1 + 2*m2 = 1700 => m2 = 1700/2 - 4/2 * m1 => m2 = 850 - 2 * m1
xx = seq(0,500,1)
yy = 537.5 - 0.75*xx
zz = 850 - 2*xx
plot(xx, yy, type="l",col=2)
points(xx, zz, type="l",col=4)

plot(xx, yy, type="l",col=2,xlim=c(200,300),ylim=c(300,400))
points(xx, zz, type="l",col=4)

diag(3)
     [,1] [,2] [,3]
[1,]    1    0    0
[2,]    0    1    0
[3,]    0    0    1
MM = diag(x = 1, nrow = 3, ncol = 3, names = TRUE)
diag(MM) <- 2
library(Rfast)
Warning: package ‘Rfast’ was built under R version 4.1.3
Loading required package: RcppZiggurat

Attaching package: ‘Rfast’

The following objects are masked from ‘package:Rfast2’:

    gammareg, gammaregs, multinom.reg

The following object is masked from ‘package:data.table’:

    transpose

The following objects are masked from ‘package:pracma’:

    Norm, Rank, squareform

The following object is masked from ‘package:matlib’:

    cholesky
Diag.matrix(3,v=1)
     [,1] [,2] [,3]
[1,]    1    0    0
[2,]    0    1    0
[3,]    0    0    1
Diag.fill(MM,v=0) 
     [,1] [,2] [,3]
[1,]    0    0    0
[2,]    0    0    0
[3,]    0    0    0
library(Matrix)
Warning: package ‘Matrix’ was built under R version 4.1.3

Attaching package: ‘Matrix’

The following objects are masked from ‘package:tidyr’:

    expand, pack, unpack

The following objects are masked from ‘package:pracma’:

    expm, lu, tril, triu
Diagonal(3, x = 1)
3 x 3 diagonal matrix of class "ddiMatrix"
     [,1] [,2] [,3]
[1,]    1    .    .
[2,]    .    1    .
[3,]    .    .    1
upper.tri(matrix(1, 3, 3))
      [,1]  [,2]  [,3]
[1,] FALSE  TRUE  TRUE
[2,] FALSE FALSE  TRUE
[3,] FALSE FALSE FALSE
round(upper.tri(matrix(1, 3, 3)))
     [,1] [,2] [,3]
[1,]    0    1    1
[2,]    0    0    1
[3,]    0    0    0
upper.tri(MM)
      [,1]  [,2]  [,3]
[1,] FALSE  TRUE  TRUE
[2,] FALSE FALSE  TRUE
[3,] FALSE FALSE FALSE
MM[upper.tri(MM)] <- 0
lower.tri(matrix(1, 3, 3))
      [,1]  [,2]  [,3]
[1,] FALSE FALSE FALSE
[2,]  TRUE FALSE FALSE
[3,]  TRUE  TRUE FALSE
round(lower.tri(matrix(1, 3, 3)))
     [,1] [,2] [,3]
[1,]    0    0    0
[2,]    1    0    0
[3,]    1    1    0
lower.tri(MM)
      [,1]  [,2]  [,3]
[1,] FALSE FALSE FALSE
[2,]  TRUE FALSE FALSE
[3,]  TRUE  TRUE FALSE
MM[lower.tri(MM)] <- 0
library(gdata)
Warning: package ‘gdata’ was built under R version 4.1.3
Registered S3 method overwritten by 'gdata':
  method         from     
  reorder.factor DescTools
Warning in system(cmd, intern = intern, wait = wait | intern, show.output.on.console = wait,  :
  running command 'C:\WINDOWS\system32\cmd.exe /c ftype perl' had status 2
Warning in system(cmd, intern = intern, wait = wait | intern, show.output.on.console = wait,  :
  running command 'C:\WINDOWS\system32\cmd.exe /c ftype perl' had status 2
gdata: read.xls support for 'XLS' (Excel 97-2004) files
gdata: ENABLED.

gdata: Unable to load perl libaries needed by read.xls()
gdata: to support 'XLSX' (Excel 2007+) files.

gdata: Run the function 'installXLSXsupport()'
gdata: to automatically download and install the perl
gdata: libaries needed to support Excel XLS and XLSX formats.

Attaching package: ‘gdata’

The following objects are masked from ‘package:data.table’:

    first, last

The following object is masked from ‘package:sfsmisc’:

    last

The following object is masked from ‘package:stats’:

    nobs

The following object is masked from ‘package:utils’:

    object.size

The following object is masked from ‘package:base’:

    startsWith
upperTriangle(MM, diag=FALSE, byrow=FALSE)
[1] 0 0 0
upperTriangle(MM, diag=TRUE, byrow=FALSE)
[1] 2 0 2 0 0 2
upperTriangle(MM, diag=FALSE, byrow=FALSE) <- 1
MM
     [,1] [,2] [,3]
[1,]    2    1    1
[2,]    0    2    1
[3,]    0    0    2
lowerTriangle(MM, diag=FALSE, byrow=FALSE) 
[1] 0 0 0
lowerTriangle(MM, diag=FALSE, byrow=FALSE) <- 3
MM
     [,1] [,2] [,3]
[1,]    2    1    1
[2,]    3    2    1
[3,]    3    3    2
library(Rfast)
lower_tri(MM, suma = FALSE, diag = FALSE) 
[1] 3 3 3
upper_tri(MM, suma = FALSE, diag = FALSE) 
[1] 1 1 1
lower_tri.assign(MM, 1, diag = FALSE) 
              [,1]          [,2] [,3]
[1,]  2.000000e+00  1.000000e+00    1
[2,]  1.000000e+00  2.000000e+00    1
[3,] 8.753233e-314 1.434111e-311    2
upper_tri.assign(MM, 3, diag = FALSE)
     [,1] [,2]          [,3]
[1,]    2    3 8.753233e-314
[2,]    3    2 1.434111e-311
[3,]    3    3  2.000000e+00
library(Matrix) # v maticovem tvaru
tril(MM) # lower triangular
3 x 3 Matrix of class "dtrMatrix"
     [,1] [,2] [,3]
[1,]    2    .    .
[2,]    3    2    .
[3,]    3    3    2
triu(MM) # upper triangular
3 x 3 Matrix of class "dtrMatrix"
     [,1] [,2] [,3]
[1,]    2    1    1
[2,]    .    2    1
[3,]    .    .    2

Sestavte matici konstitučních koeficientů

Určete počet lineárně nezávislých reakcí v soustavě obsahující dané složky.

Gibbsovo stechiometricke pravidlo: maximální počet lineárně nezávislých reakcí r je menší nebo roven rozdílu počtu složek v systému (n) a hodnosti matice konstitučních koeficientů (h), v n-složkovém systému existuje n - h stechiometrických vztahů.

# pocet linearne nezavisl}ch reakcm
(r = length(form) - qr(M)$rank)
[1] 2
ge1
     [,1]
[1,]  0.5
[2,]  1.0
[3,]  0.5

Vyčíslete rovnici: KMnO4 + MnSO4 + H2O = MnO2 + K2SO4 + H2SO4


K = c(1, 0, 0, 0, -2, 0)
Mn = c(0, 1, 0, -1, 0, 0)
O = c(4, 4, 1, -2, -4, -4)
S = c(0, 1, 0, 0, -1, -1)
H = c(0, 0, 2, 0, 0, -2)

A = as.matrix(rbind(K, Mn, O, S, H))
colnames(A) = c("KMnO4", "MnSO4", "H2O", "MnO2", "K2SO4", "H2SO4")
B = c(rep(0,length(A[,1])))
C = cbind(A,B)
library(matlib)
c(R(A), R(cbind(A,B)))          # show ranks
all.equal(R(A), R(cbind(A,B)))  # consistent?
showEqn(A, B)
matlib::Solve(A, B)
GE2 = gaussianElimination(A, B, tol = sqrt(.Machine$double.eps), verbose = FALSE, latex = FALSE, fractions = TRUE)
as.character(GE2)
# cim nasobit koeficienty
nnv1 = 1/min(abs(as.numeric(GE2[,length(A[1,])])))
nnv = as.numeric(GE2[,length(A[1,])])*nnv1
NN = -1*(as.matrix(GE2)*nnv)[,c(1:(length(A[1,])-1))]
rownames(NN) = rownames(A)
colnames(NN) = colnames(A)[-length(colnames(A))]
apply(NN,2,sum)

Kolik 96% kyseliny sírové a kolik vody je potřeba na pripravu 1 l 78% kyseliny sírové?

GE1 = gaussianElimination(A, B, tol = sqrt(.Machine$double.eps), verbose = FALSE, latex = FALSE, fractions = FALSE)
NN = GE1[,3] # [l]
names(NN) = rownames(A)
NN
 H2SO4    H2O 
0.1875 0.8125 
library(Rlinsolve)
ls = lsolve.gs(A, B, xinit = NA, reltol = 1e-05, maxiter = 1000, adjsym = TRUE, verbose = TRUE)
* lsolve.gs : Initialiszed.
* lsolve.gs : A may not be symmetric.
* lsolve.gs : making it normal equation form via 'adjsym' flag.
* lsolve.gs : computations finished.
ls$x
          [,1]
[1,] 0.1875003
[2,] 0.8125000
library(cmna)
cgmmatrix(A, B, tol = 1e-06, maxiter = 100) # iterativematrix
[1] 0.1874999 0.8125000
solvematrix(A, B) # refmatrix
 H2SO4    H2O 
0.1875 0.8125 

Slitina A obsahuje 1.5 % Si, 1.4 % Mn, 0.4 % P a 0.3 % S. Slitina B obsahuje 0.5 % Si, 1.6 % Mn, 0.2 % P a 0.2 % S. Slitina C obsahuje 3 % Si, 0.5 % Mn, 0.5 % P a 0.05 % S. Kolik každé slitiny A, B, C je třeba na výrobu 100 kg slitiny obsahující 2 % Si, 1 % Mn, 0.4 % P a 0.15 % S?


sl1 = c(0.015, 0.014, 0.004, 0.003)
sl2 = c(0.005,0.016, 0.002, 0.002)
sl3 = c(0.03, 0.005, 0.005, 0.0005)
A = cbind(sl1, sl2, sl3); rownames(A) = c("Si","Mn","P","S")
B = c(0.02, 0.01, 0.004, 0.0015); names(B) = c("Si","Mn","P","S")
# B = c(2, 1, 0.4, 0.15); names(B) = c("Si","Mn","P","S")
library(matlib)
c(R(A), R(cbind(A,B)))          # show ranks, viz Frobeniova veta
all.equal(R(A), R(cbind(A,B)))  # consistent?
showEqn(A, B)
matlib::Solve(A, B)
limSolve::Solve(A, B)
GE1 = gaussianElimination(A, B, tol = sqrt(.Machine$double.eps), verbose = FALSE, latex = FALSE, fractions = FALSE)
GE1[,4]*100 # [kg]
library(Rlinsolve)
ls = lsolve.gs(A, B, xinit = NA, reltol = 1e-05, maxiter = 1000, adjsym = TRUE, verbose = TRUE)
ls$x

Kolik g 60% a kolik g 30% roztoku NaCl je treba smichat pri priprave 100 g 40% roztoku? 20 g 60% a a 80 g 35%

### matice

B = c(0.40*100,100) # [mg]
names(B) = c("60%","30%")
r1 = c(0.60,1) # [mg]
r2 = c(0.30,1) # [mg]
A = cbind(r1,r2)
colnames(A) = c("60%","30%")
rownames(A) = c("r30","r3")
det(A) # matice je regularni n = h
[1] 0.3
library(matlib)
c(R(A), R(cbind(A,B)))          # show ranks
[1] 2 2
all.equal(R(A), R(cbind(A,B)))  # consistent?
[1] TRUE
showEqn(A, B)
0.6*x1 + 0.3*x2  =   40 
  1*x1   + 1*x2  =  100 
matlib::Solve(A, B)
x1    =  33.33333333 
  x2  =  66.66666667 
limSolve::Solve(A, B)
     60%      30% 
33.33333 66.66667 
#
library(limSolve)

Attaching package: ‘limSolve’

The following object is masked from ‘package:matlib’:

    Solve
G <-matrix(ncol = 2, byrow = TRUE, data = c(1, 0, 0, 1)) 
H <- c(0, 0)
ldei(A, B, G = G, H = H)$X
     60%      30% 
33.33333 66.66667 
#
library(cmna) 
gdls(A, B, alpha = 0.05, tol = 1e-06, m = 1e+05) #  least squares with graident descent
        [,1]
60% 33.33405
30% 66.66587
jacobi(A, B, tol = 1e-06, maxiter = 100)  # iterativematrix
[1] 33.33333 66.66667
gaussseidel(A, B, tol = 1e-06, maxiter = 100) # iterativematrix
[1] 33.33333 66.66667
solvematrix(A, B) # refmatrix
     r30       r3 
33.33333 66.66667 

Ze dvou kovu o hustotach 7.4 g/cm3 a 8.2 g/cm3 je treba pripravit 0.5 kg slitiny o hustote 7.6 g/cm3. Kolik g kazdiho z kovu je k tomu potreba? 375 g lehciho a 125 g tezsiho


library(rootSolve)
model <- function(x){
  F1 <- 7.4*x[1] + 8.2*x[2] - 3800
  F2 <- x[1] + x[2] - 500
  c(F1 = F1, F2 = F2)}
ss <- multiroot(f = model, start = c(1, 1))
ss$root  # [kg]

### graficke reseni
# 7.4*m1 + 8.2*m2 = 0.5*7.6 => m1 = 3800/7.4 - 8.2/7.4 * m2  => m1 = 513.5 - 1.108 * m2 
# m1 + m2 = 500  => m1 = 500 - m2
xx = seq(0,500,1)
yy = 513.5 - 1.108*xx
zz = 500 - xx
plot(xx, yy, type="l",col=2)
points(xx, zz, type="l",col=4)
plot(xx, yy, type="l",col=2,xlim=c(100,150),ylim=c(350,400))
points(xx, zz, type="l",col=4)

### matice
B = c(7.6,1) # [mg]
names(B) = c("kov1","kov2")
r1 = c(7.4,1) # [mg]
r2 = c(8.2,1) # [mg]
A = cbind(r1,r2)
colnames(A) = c("kov1","kov2")
rownames(A) = c("7.4","8.2")
det(A) # matice je regularni n = h
library(matlib)
c(R(A), R(cbind(A,B)))          # show ranks
all.equal(R(A), R(cbind(A,B)))  # consistent?
showEqn(A, B)
rr = matlib::Solve(A, B)
read.table(text = rr[1], fill = TRUE)[[3]]*500 # [g]
read.table(text = rr[2], fill = TRUE)[[3]]*500 # [g]
rr = limSolve::Solve(A, B)
rr*500 # [g]
# 
library(limSolve)
G <-matrix(ncol = 2, byrow = TRUE, data = c(1, 0, 0, 1)) 
H <- c(0, 0)
rr = ldei(A, B, G = G, H = H)$X
rr*500 # [g]

V tepelné elektrárne mají zásobu uhlí, která vystací na 24 dní, bude-li v cinnosti pouze první blok, na 30 dní, bude-li v provozu pouze 2. blok a na 20 dní, bude-li v provozu pouze 3. blok. Na jak dloho vystací zásoba, budou-li v provozu vsechny bloky najednou?

library(Ryacas)

Attaching package: ‘Ryacas’

The following object is masked from ‘package:stats’:

    integrate

The following objects are masked from ‘package:base’:

    %*%, diag, diag<-, lower.tri, upper.tri
vr <- ysym("x/24 + x/30 + x/20 - 1") 
solve(vr, "x") 
{x==8} 
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoNCk5lamlzdG90eSBhIGNoeWJ5IG3Em8WZZW7DrQ0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQpsaWJyYXJ5KGVycm9ycykNCnhlIDwtIHNldF9lcnJvcnMoMy42MDIsIDAuMDA4KQ0Kb3B0aW9ucyhlcnJvcnMubm90YXRpb24gPSAicGx1cy1taW51cyIpIA0KcHJpbnQoeGUsIGRpZ2l0cyA9IDIpDQpvcHRpb25zKGVycm9ycy5ub3RhdGlvbiA9ICJwYXJlbnRoZXNpcyIpDQpwcmludCh4ZSwgZGlnaXRzID0gMikNCg0KIyBlbGVtZW50YXJuaSBuYWJvag0KZSA8LSBzZXRfZXJyb3JzKDEuNjAyMTc2NjIwOGUtMTksIDAuMDAwMDAwMDA5OGUtMTkpIA0Kb3B0aW9ucyhlcnJvcnMubm90YXRpb24gPSAicGx1cy1taW51cyIpIA0KcHJpbnQoZSwgZGlnaXRzID0gMikNCm9wdGlvbnMoZXJyb3JzLm5vdGF0aW9uID0gInBhcmVudGhlc2lzIikNCnByaW50KGUsIGRpZ2l0cyA9IDMpDQoNCmBgYA0KDQoNClplIHrDoXNpbGt5IGthcHJvbGFrdGFtdSBieWxvIG9kZWJyw6FubyAxMCB2em9ya3UgYSBieWwgdSBuaWNoIHN0YW5vdmVuIGJvZCB0w6Fuw60uIFZ5cG/EjcOtdGVqdGUgcHLFr23Em3Jub3UgaG9kbm90dSBib2R1IHTDoW7DrSB2IHrDoXNpbGNlIGEgamVqw60gc23Em3JvZGF0bm91IG9kY2h5bGt1Lg0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQp4YyA9IGMoNjguNSwgNjguNywgNjguMywgNjguOCwgNjguNSwgNjguMiwgNjguNiwgNjguNCwgNjguMiwgNjguNykNCm1lYW4oeGMpDQpzZCh4YykgIyBzZA0Kc2QoeGMpL3NxcnQobGVuZ3RoKHhjKSkgIyBzdHIgY2h5YmEgcHJ1bWVydQ0KDQplIDwtIHNldF9lcnJvcnMobWVhbih4YyksIHNkKHhjKS9zcXJ0KGxlbmd0aCh4YykpKSANCm9wdGlvbnMoZXJyb3JzLm5vdGF0aW9uID0gInBsdXMtbWludXMiKTsgcHJpbnQoZSwgZGlnaXRzID0gMikNCg0KYGBgDQoNCg0KxaDDrcWZZW7DrSBjaHliDQoNCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQoNCmxpYnJhcnkocHJvcGFnYXRlKQ0KDQojIHogcHJ1bWVydSBhIG5lamlzdG90eSwgYmV6IHV2ZWRlbsOtIHBvY3R1IHN0dXBudSB2b2xub3N0aSwgcmVzcC4gcG9jdHUgb3Bha292YW5pDQoNCnggPC0gYyg1LCAwLjAxKSANCnkgPC0gYygxLCAwLjAxKSANCg0KRVhQUjEgPC0gZXhwcmVzc2lvbih4L3kpIA0KREYxIDwtIGNiaW5kKHgsIHkpDQpSRVMxIDwtIHByb3BhZ2F0ZShleHByID0gRVhQUjEsIGRhdGEgPSBERjEsIHR5cGUgPSAic3RhdCIsIGRvLnNpbSA9IFRSVUUsIHZlcmJvc2UgPSBUUlVFLCBuc2ltID0gMTAwMDAwKSANClJFUzENClJFUzEkZGF0YQ0KUkVTMSRwcm9wDQpSRVMxJHNpbQ0Kc3VtbWFyeShSRVMxKQ0KcGxvdChSRVMxKQ0KDQpFWFBSIDwtIGV4cHJlc3Npb24oYV5iKngpDQphID0gYyg1LCAwLjEpDQpiID0gYygxMCwgMC4xKQ0KeCA9IGMoMSwgMC4xKQ0KREFUIDwtIGNiaW5kKGEsIGIsIHgpDQoocmVzIDwtIHByb3BhZ2F0ZShFWFBSLCBEQVQpKQ0KcmVzJGRhdGENCnJlcyRwcm9wDQpyZXMkc2ltDQpzdW1tYXJ5KHJlcykNCnBsb3QocmVzKQ0KDQoNCiMgeiBwcnVtZXJ1IGEgbmVqaXN0b3R5LCBzIHV2ZWRlbsOtbSBwb2N0dSBzdHVwbnUgdm9sbm9zdGkNCkVYUFIyIDwtIGV4cHJlc3Npb24oeC95KSANCnggPC0gYyg1LCAwLjAxLCAxMikgDQp5IDwtIGMoMSwgMC4wMSwgNSkgDQpERjIgPC0gY2JpbmQoeCwgeSkgDQpSRVMyIDwtIHByb3BhZ2F0ZShleHByID0gRVhQUjIsIGRhdGEgPSBERjIsIHR5cGUgPSAic3RhdCIsIGRvLnNpbSA9IFRSVUUsIHZlcmJvc2UgPSBUUlVFLCBuc2ltID0gMTAwMDAwKQ0KUkVTMg0KUkVTMiRkYXRhDQpSRVMyJHByb3ANClJFUzIkc2ltDQpzdW1tYXJ5KFJFUzIpDQpwbG90KFJFUzIpDQoNCg0KIyBWw71wb2NldCBwb21vY8OtIGludGVydmFsdSANCg0KRVhQUjMgPC0gZXhwcmVzc2lvbihDICogc3FydCgoNTIwICogSCAqIFApLyhNICoodCArIDQ2MCkpKSkNCkggPC0gYyg2NCwgNjUpDQpNIDwtIGMoMTYsIDE2LjIpDQpQIDwtIGMoMzYxLCAzNjUpDQp0IDwtIGMoMTY1LCAxNzApDQpDIDwtIGMoMzguNCwgMzguNSkNCkRBVDMgPC0gbWFrZURhdChFWFBSMykNCmludGVydmFsKERBVDMsIEVYUFIzLCBzZXEgPSAyKQ0KDQpFWFBSNSA8LSBleHByZXNzaW9uKHheMiAtIHggKyAxKQ0KeCA8LSBjKC0yLCAxKQ0KY3VydmUoeF4yIC0geCArIDEsIC0yLCAxKQ0KREFUNSA8LSBtYWtlRGF0KEVYUFI1KQ0KaW50ZXJ2YWwoREFUNSwgRVhQUjUsIHNlcSA9IDIpDQoNCg0KbGlicmFyeShtZXRSb2xvZ3kpDQoNCmRhdGEoR1VNLkguMSkNCkdVTS5ILjENCg0KIyMgYSBzaW1wbGUgdW5jZXJ0YWludHkgYW5hbHlzaXMgZm9yIHRoZSBwcm9kdWN0IG9mIHR3byBxdWFudGl0aWVzDQpHVU0oYygieDEiLCJ4MiIpLGMoMi4zLDEuMSksYygwLjAzMCwwLjAxNSksYyg1LDk5OTkpLCJ4MSp4MiIpDQoNCiMjIGEgc2ltcGxlIHVuY2VydGFpbnR5IGFuYWx5c2lzIGZvciB0aGUgcHJvZHVjdCBvZiB0d28gcXVhbnRpdGllcw0KR1VNLnZhbGlkYXRlKGMoIngxIiwieDIiKSwgYygyLjMsMS4xKSwgYygwLjAzMCwwLjAxNSksIGMoNSw5OTk5KSwgYygiQSIsIkIiKSxjKCJOb3JtYWwiLCJSZWN0YW5ndWxhciIpLCJ4MSp4MiIpDQoNCg0KZXhwciA8LSBleHByZXNzaW9uKGErYioyK2MqMytkLzIpDQp4IDwtIGxpc3QoYT0xLCBiPTMsIGM9MiwgZD0xMSkNCnUgPC0gbGFwcGx5KHgsIGZ1bmN0aW9uKHgpIHgvMTApICMgbmVqaXN0b3RhIDEwICUNCnUuZXhwcjwtdW5jZXJ0KGV4cHIsIHgsIHUsIG1ldGhvZD0iTlVNIikNCnUuZXhwcg0KIyBmdW5jdGlvbiBtZXRob2QNCmYgPC0gZnVuY3Rpb24oYSxiLGMsZCkgYStiKjIrYyozK2QvMg0KdS5mdW48LXVuY2VydChmLCB4LCB1LCBtZXRob2Q9Ik5VTSIpDQp1LmZ1bg0KIyBmb3JtdWxhIG1ldGhvZA0KdS5mb3JtPC11bmNlcnQofmErYioyK2MqMytkLzIsIHgsIHUsIG1ldGhvZD0iTlVNIikNCnUuZm9ybQ0KDQoNCiMgcyBrb3JlbGFjaQ0KdS5jb3I8LWRpYWcoMSw0KQ0KdS5jb3JbMyw0XTwtdS5jb3JbNCwzXTwtMC41DQp1LmNvcg0KIyBudW0NCnUuZm9ybWM8LXVuY2VydCh+YStiKjIrYyozK2QvMiwgeCwgdSwgbWV0aG9kPSJOVU0iLCBjb3I9dS5jb3IpDQp1LmZvcm1jDQojIE1vbnRlIENhcmxvDQp1LmZvcm1jLk1DPC11bmNlcnQofmErYioyK2MqMytkLzIsIHgsIHUsIG1ldGhvZD0iTUMiLCBjb3I9dS5jb3IsIEI9MjAwKQ0KdS5mb3JtYy5NQw0KDQoNCmV4cHIgPC0gZXhwcmVzc2lvbihhLyhiLWMpKQ0KeCA8LSBsaXN0KGE9MSwgYj0zLCBjPTIpDQp1IDwtIGxhcHBseSh4LCBmdW5jdGlvbih4KSB4LzIwKQ0Kc2V0LnNlZWQoNDAzKQ0KdS5pbnZleHByPC11bmNlcnRNQyhleHByLCB4LCB1LCBkaXN0cmliPXJlcCgibm9ybSIsIDMpLCBCPTk5OSwga2VlcC54PVRSVUUgKQ0KdS5pbnZleHByDQoNCmBgYA0KDQoNClZ5cG/EjcOtdGVqdGUgaHVzdG90dSBhIGplasOtIGNoeWJ1IHBybyBsw6F0a3UsIHUgbsOtxb4gYnlsYSBvcGFrb3ZhbsO9bSBtxJvFmWVuw61tIHN0YW5vdmVuYSBobW90bm9zdCA2LjgyNCAoMC4wMDgpIGcgYSBvYmplbSAzLjAzICgwLjAxKSBtbC4NCg0KYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0KbGlicmFyeShwcm9wYWdhdGUpDQoNCkVYUFIyIDwtIGV4cHJlc3Npb24obS9WKSANCm0gPSBjKDYuODI0LCAwLjAwOCkgI1tnXSANClYgPSBjKDMuMDMsIDAuMDEpICNbbWxdDQpERjIgPC0gY2JpbmQobSwgVikgDQpSRVMyIDwtIHByb3BhZ2F0ZShleHByID0gRVhQUjIsIGRhdGEgPSBERjIsIHR5cGUgPSAic3RhdCIsIGRvLnNpbSA9IFRSVUUsIHZlcmJvc2UgPSBUUlVFLCBuc2ltID0gMTAwMDAwKQ0KUkVTMg0KUkVTMiRkYXRhDQpSRVMyJHByb3ANClJFUzIkc2ltDQpsaWJyYXJ5KGVycm9ycykNCmUgPC0gc2V0X2Vycm9ycyhSRVMyJHNpbVsxXSwgUkVTMiRzaW1bMl0pIA0Kb3B0aW9ucyhlcnJvcnMubm90YXRpb24gPSAicGx1cy1taW51cyIpOyBwcmludChlLCBkaWdpdHMgPSAxKQ0Kb3B0aW9ucyhlcnJvcnMubm90YXRpb24gPSAicGFyZW50aGVzaXMiKTsgcHJpbnQoZSwgZGlnaXRzID0gMSkNCg0KYGBgDQoNCg0KTmEgcMOtc3QgbyBwcsWvbcSbcnUgMjAwICgwLjA1KSBtbSBwxa9zb2LDrSBww6FyYSB0bGFrZW0gOC4yICgwLjEpIGF0bS4gSmFrb3Ugc2lsb3UgcMWvc29iw60gcMOhcmEgbmEgcMOtc3Q/DQoNCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQoNCmxpYnJhcnkocHJvcGFnYXRlKQ0KbGlicmFyeShtZWFzdXJlbWVudHMpDQoNCmQgPSBjKDIwMCwgMC4wNSkgIyBbbW1dIG5hIFttXQ0KZCA9IGFzLnZlY3Rvcihjb252X3VuaXQoYygyMDAsIDAuMDUpLCBmcm9tPSJtbSIsIHRvPSJtIikpDQpwID0gYyg4LjIsIDAuMSkgICMgW2F0bV0gbmEgW1BhXQ0KcCA9IGFzLnZlY3Rvcihjb252X3VuaXQoYyg4LjIsIDAuMSksIGZyb209ImF0bSIsIHRvPSJQYSIpKQ0KcGkNCkVYUFI3IDwtIGV4cHJlc3Npb24ocCozLjE0MTU5MyooZC8yKV4yKQ0KREY3IDwtIGNiaW5kKGQsIHApIA0KUkVTNyA8LSBwcm9wYWdhdGUoZXhwciA9IEVYUFI3LCBkYXRhID0gREY3LCB0eXBlID0gInN0YXQiLCBkby5zaW0gPSBUUlVFLCB2ZXJib3NlID0gVFJVRSwgbnNpbSA9IDEwMDAwMCkNClJFUzcNClJFUzckZGF0YQ0KUkVTNyRwcm9wDQpSRVM3JHNpbQ0KbGlicmFyeShlcnJvcnMpDQplIDwtIHNldF9lcnJvcnMoUkVTNyRzaW1bMV0sIFJFUzckc2ltWzJdKSANCm9wdGlvbnMoZXJyb3JzLm5vdGF0aW9uID0gInBsdXMtbWludXMiKTsgcHJpbnQoZSwgZGlnaXRzID0gMSkNCm9wdGlvbnMoZXJyb3JzLm5vdGF0aW9uID0gInBhcmVudGhlc2lzIik7IHByaW50KGUsIGRpZ2l0cyA9IDEpDQoNCmBgYA0KDQoNClZ5cG/EjcOtdGVqdGUga29lZmljaWVudCB2aXNrb3ppdHkgcm96dG9rdSBnbHljZXJpbnUgU3Rva2Vzb3ZvdSBtZXRvZG91DQoNCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQoNCmxpYnJhcnkocHJvcGFnYXRlKQ0KDQpyID0gYygwLjAxMTIsIDAuMDAwMSkgIyBwb2xvbWVyIGt1bGlja3kgW2NtXQ0KbCA9IGMoMzEuMjMsIDAuMDUpICMgZHJhaGEga3VsaWNreSB6YSBjYXMgdCBbY21dDQp0ID0gYyg2Mi4xLCAwLjIpICMgY2FzIFtzXQ0KZyA9IGMoOTgwLjEsMCkgIyB0aWhvdmUgenJ5Y2hsZW5pIFtjbS9zMl0geiB0YWJ1bGVrDQpkMCA9IGMoMTMuNTUsMCkgIyBodXN0b3RhIGt1bGlja3kgW2cvY20zXSB6IHRhYnVsZWsNCmQgPSBjKDEuMjgsMCkgIyBodXN0b3RhIHJvenRva3UgW2cvY20zXSB6IHRhYnVsZWsNCkVYUFIzIDwtIGV4cHJlc3Npb24oKDIvOSkqZyooKChkMC1kKSpyXjIpL2wpKnQpDQpERjMgPC0gY2JpbmQociwgbCwgdCwgZywgZDAsIGQpIA0KUkVTMyA8LSBwcm9wYWdhdGUoZXhwciA9IEVYUFIzLCBkYXRhID0gREYzLCB0eXBlID0gInN0YXQiLCBkby5zaW0gPSBUUlVFLCB2ZXJib3NlID0gVFJVRSwgbnNpbSA9IDEwMDAwMCkNClJFUzMNClJFUzMkZGF0YQ0KUkVTMyRwcm9wDQpSRVMzJHNpbQ0KRVhQUjQgPC0gZXhwcmVzc2lvbigoMi85KSo5ODAuMSooKCgxMy41NS0xLjI4KSpyXjIpL2wpKnQpDQpERjQgPC0gY2JpbmQociwgbCwgdCkgDQpSRVM0IDwtIHByb3BhZ2F0ZShleHByID0gRVhQUjQsIGRhdGEgPSBERjQsIHR5cGUgPSAic3RhdCIsIGRvLnNpbSA9IFRSVUUsIHZlcmJvc2UgPSBUUlVFLCBuc2ltID0gMTAwMDAwKQ0KUkVTNCRkYXRhDQpSRVM0JHByb3ANClJFUzQkc2ltDQpsaWJyYXJ5KGVycm9ycykNCmUgPC0gc2V0X2Vycm9ycyhSRVM0JHNpbVsxXSwgUkVTNCRzaW1bMl0pIA0Kb3B0aW9ucyhlcnJvcnMubm90YXRpb24gPSAicGx1cy1taW51cyIpOyBwcmludChlLCBkaWdpdHMgPSAxKQ0Kb3B0aW9ucyhlcnJvcnMubm90YXRpb24gPSAicGFyZW50aGVzaXMiKTsgcHJpbnQoZSwgZGlnaXRzID0gMSkNCg0KYGBgDQoNCg0KVnlwb8SNw610ZWp0ZSBrb2VmaWNpZW50IHZpc2tveml0eSByb3p0b2t1IGdseWNlcmludSBwb21vY8OtIGthcGlsw6FybsOtaG8gdmlza296aW1ldHJ1Lg0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQpsaWJyYXJ5KHByb3BhZ2F0ZSkNCmxpYnJhcnkobWVhc3VyZW1lbnRzKQ0KDQpwID0gYygyMC4xMiwgMC4wMSkgIyB0bGFrIG5hIHZ5dG9rdSB6IGthcGlsYXJ5IFttbSBIZ10gdG8gW1BhXQ0KcCA9IGFzLnZlY3Rvcihjb252X3VuaXQoYygyMC4xMiwgMC4wMSksIGZyb209Im1tSGciLCB0bz0iUGEiKSkNCnIgPSBjKDAuNTcwLCAwLjAwMykgIyBwb2xvbWVyIGthcGlsYXJ5IFttbV0gdG8gW21dDQpyID0gY29udl91bml0KGMoMC41NzAsIDAuMDAzKSwgZnJvbT0ibW0iLCB0bz0ibSIpDQpsID0gYygxMC41MjYsIDAuMDA1KSAjIGRlbGthIGthcGlsYXJ5IFttbV0gdG8gW21dDQpsID0gY29udl91bml0KGMoMTAuNTI2LCAwLjAwNSksIGZyb209Im1tIiwgdG89Im0iKQ0KViA9IGMoNS4wMjUsIDAuMDAxKSMgb2JqZW0ga2FwYWxpbnkgdnl0ZWtsZSB6YSBjYXMgdCBbY20zXSB0byBbbTNdDQpWID0gY29udl91bml0KGMoNS4wMjUsIDAuMDAxKSwgZnJvbT0iY20zIiwgdG89Im0zIikNCnQgPSBjKDI3LjM0LCAwLjAyKSAjIGNhcyBbc10NCnBpDQpFWFBSNSA8LSBleHByZXNzaW9uKCgzLjE0MTU5MypwKihyXjQpKnQpLyg4KlYqbCkpDQpERjUgPC0gY2JpbmQocCwgciwgbCwgViwgdCkgDQpSRVM1IDwtIHByb3BhZ2F0ZShleHByID0gRVhQUjUsIGRhdGEgPSBERjUsIHR5cGUgPSAic3RhdCIsIGRvLnNpbSA9IFRSVUUsIHZlcmJvc2UgPSBUUlVFLCBuc2ltID0gMTAwMDAwKQ0KUkVTNSAjIFtrZyAvIG0uc10NClJFUzUkZGF0YQ0KUkVTNSRwcm9wDQpSRVM1JHNpbQ0KIyBjb252X211bHRpdW5pdCh4ID0gUkVTNSRzaW1bMToyXSwgZnJvbT0ia2cgLyBtIiwgdG89ImcgLyBjbSIpDQpsaWJyYXJ5KGVycm9ycykNCmUgPC0gc2V0X2Vycm9ycyhSRVM1JHNpbVsxXSwgUkVTNSRzaW1bMl0pIA0Kb3B0aW9ucyhlcnJvcnMubm90YXRpb24gPSAicGx1cy1taW51cyIpOyBwcmludChlLCBkaWdpdHMgPSAxKQ0Kb3B0aW9ucyhlcnJvcnMubm90YXRpb24gPSAicGFyZW50aGVzaXMiKTsgcHJpbnQoZSwgZGlnaXRzID0gMSkNCg0KYGBgDQoNCg0KU291xI1pbiByb3pwdXN0bm9zdGkgc3TFmcOtYnJuw6kgc29saSBBZ1ggbcOhIGhvZG5vdHUgS3MgPSA0LjAgKDAuNCkgeCAxMF4tOC4gSmFrw6EgamUgY2h5YmEgdnlwb8SNdGVuw6kgcm92bm92w6HFvm7DqSBrb25jZW50cmFjZSBzdMWZw61icm7DvWNoIGlvbnTFryB2ZSB2b2RlPw0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQpsaWJyYXJ5KHByb3BhZ2F0ZSkNCkVYUFIgPC0gZXhwcmVzc2lvbih4XjAuNSkNCnggPSBjKDQuMCwgMC40KQ0KREFUIDwtIGRhdGEuZnJhbWUoeCkNCnJlcyA8LSBwcm9wYWdhdGUoRVhQUixEQVQpDQojIE5FRlVOR1VKRSBwcm8gamVkbnUgcHJvbWVubm91Lg0KDQoNCmxpYnJhcnkobWV0Um9sb2d5KQ0KDQpHVU0oIktzIiw0LjBlLTgsMC40ZS04LDEsInNxcnQoS3MpIixzaWcuZGlnaXRzLlUgPSAyKSANCg0KZXhwciA8LSBleHByZXNzaW9uKGFeMC41KQ0KeCA8LSBsaXN0KGE9NC4wZS04KQ0KdSA8LSBsYXBwbHkoeCwgZnVuY3Rpb24oeCkgeC8xMCkgIyBuZWppc3RvdGEgMTAgJQ0KdS5leHByPC11bmNlcnQoZXhwciwgeCwgdSwgbWV0aG9kPSJOVU0iKQ0KdS5leHByDQojIGZ1bmN0aW9uIG1ldGhvZA0KZiA8LSBmdW5jdGlvbihhKSBhXjAuNQ0KdS5mdW48LXVuY2VydChmLCB4LCB1LCBtZXRob2Q9Ik5VTSIpDQp1LmZ1bg0KIyBmb3JtdWxhIG1ldGhvZA0KdS5mb3JtPC11bmNlcnQofmFeMC41LCB4LCB1LCBtZXRob2Q9Ik5VTSIpDQp1LmZvcm0NCg0KYGBgDQoNCg0KTmVqaXN0b3R5IGEga29yZWxhY2UNCg0KYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0KbGlicmFyeShlcnJvcnMpDQoNCnggPSBjKDAuOTcxOTM3OCwgMS45ODQwMDA2LCAyLjk5NjE4MzAsIDQuMDEyMzM0NiwgNS4wMDEyNzk5KQ0KZXJyb3JzKHgpID0gYygwLjAxLCAwLjAxLCAwLjAxLCAwLjAxLCAwLjAxKQ0KeSA9IGMoMC45NzQ4OTkyLCAxLjk2Mjc4MDUsIDIuOTkzNTgzMSwgMy45OTIxMjM3LCA0Ljk2MTI1NTUpDQplcnJvcnMoeSkgPSBjKDAuMDIsIDAuMDIsIDAuMDIsIDAuMDIsIDAuMDIpDQoNCiMgYmV6IGtvcmVsYWNlDQpjb3JyZWwoeCwgeSkgPSAgYygwLCAwLCAwLCAwLCAwKSANCnogPC0geCAvIHk7IHoNCg0KIyBzIGtvcmVsYWPDrQ0KY29ycmVsKHgsIHkpID0gIGMoMC44ODY0MjgyLCAwLjk3NjE4NDEsIDAuOTE0MDIwOSwgMC45NDk2MjY2LCAwLjk5MTE4MzcpDQp6X2NvcnJlbHAgPC0geCAvIHk7IHpfY29ycmVscA0KDQpjb3JyZWwoeCwgeSkgPSAgYygtMC44ODY0MjgyLCAtMC45NzYxODQxLCAtMC45MTQwMjA5LCAtMC45NDk2MjY2LCAtMC45OTExODM3KQ0Kel9jb3JyZWxuIDwtIHggLyB5OyB6X2NvcnJlbG4NCg0KYGBgDQoNCg0KSW1wb3J0IGRhdA0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQoNCiMgSW1wb3J0IERhdGFzZXQgdiBSU3R1ZGlvDQoNCg0KIyBjbGlwYm9hcmQNCg0KY3ljbGFtYXRlPC0gcmVhZC5kZWxpbSgiY2xpcGJvYXJkIiwgaGVhZGVyPVQpDQoNCg0KIyB0eHQsIGFzY2lpDQoNCmN5Y2xhbWF0ZTE8LSByZWFkLnRhYmxlKCJjOlxcVXNlcnNcXGx1Ym9wXFxEcm9wYm94XFxrdXJzUlxcY3ljbGFtYXRlLnR4dCIsIGhlYWRlcj1UKQ0KDQpjeWNsYW1hdGUyPC0gcmVhZC5kZWxpbSgiYzpcXFVzZXJzXFxsdWJvcFxcRHJvcGJveFxca3Vyc1JcXGN5Y2xhbWF0ZS50eHQiLCBoZWFkZXI9VCkNCg0KDQojIyBjc3YNCg0KZGF0YTEgPC0gcmVhZC5jc3YoImM6XFxVc2Vyc1xcbHVib3BcXERyb3Bib3hcXGt1cnNSXFxDaGVtaWNhbCBDb21wb3Npb24gb2YgQ2VyYW1pYy5jc3YiLCBoZWFkZXI9VFJVRSwgc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSkNCg0KbGlicmFyeShkYXRhLnRhYmxlKQ0KZGF0YTIgPC0gZnJlYWQoImM6XFxVc2Vyc1xcbHVib3BcXERyb3Bib3hcXGt1cnNSXFxDaGVtaWNhbCBDb21wb3Npb24gb2YgQ2VyYW1pYy5jc3YiKQ0KDQpkYXRhMyA8LSByZWFkLmNzdigiaHR0cHM6Ly9hcmNoaXZlLmljcy51Y2kuZWR1L21sL21hY2hpbmUtbGVhcm5pbmctZGF0YWJhc2VzLzAwNTgzL0NoZW1pY2FsIENvbXBvc2lvbiBvZiBDZXJhbWljLmNzdiIpDQoNCg0KbGlicmFyeShyZWFkcikNCg0KDQojIyBFeGNlbA0KDQpsaWJyYXJ5KG9wZW54bHN4KQ0KDQpnZXRTaGVldE5hbWVzKCJjOlxcVXNlcnNcXGx1Ym9wXFxEcm9wYm94XFxrdXJzUlxcemFyb2RreS54bHN4IikNCg0KemFyb2RreTEgPC0gcmVhZC54bHN4KCJjOlxcVXNlcnNcXGx1Ym9wXFxEcm9wYm94XFxrdXJzUlxcemFyb2RreS54bHN4Iiwgc2hlZXQgPSAiemFyb2RreSIsIHN0YXJ0Um93ID0gMSwgY29sTmFtZXMgPSBUUlVFLCByb3dOYW1lcyA9IEZBTFNFLGRldGVjdERhdGVzID0gRkFMU0UsIHNraXBFbXB0eVJvd3MgPSBUUlVFLHJvd3MgPSBOVUxMLCBjb2xzID0gTlVMTCxjaGVjay5uYW1lcyA9IEZBTFNFKQ0KaGVhZCh6YXJvZGt5MSkNCg0KbGlicmFyeShyZWFkeGwpDQp6YXJvZGt5MiA8LSByZWFkX2V4Y2VsKCJjOlxcVXNlcnNcXGx1Ym9wXFxEcm9wYm94XFxrdXJzUlxcemFyb2RreS54bHN4Iiwgc2hlZXQgPSAiemFyb2RreSIpDQpoZWFkKHphcm9ka3kyKQ0KDQoNCnBhdGggPSAiYzpcXFVzZXJzXFxsdWJvcFxcRHJvcGJveFxca3Vyc1JcXCINCmZpbGUubmFtZXMgPC0gZGlyKHBhdGgsIHBhdHRlcm4gPSIudHh0Iik7IGZpbGUubmFtZXMNCg0KUkQgPC0gZnVuY3Rpb24oWCl7TSA8LSByZWFkLmRlbGltKHBhc3RlKCJjOlxcVXNlcnNcXGx1Ym9wXFxEcm9wYm94XFxrdXJzUlxcIixYLHNlcD0iIikpDQpyZXR1cm4oTSl9DQpsaXN0dCA9IGxhcHBseShmaWxlLm5hbWVzLFJEKQ0KbGlzdHRbWzFdXQ0KbGlzdHRbWzJdXQ0KbGlzdHRbWzRdXQ0KbGlzdHRbWzNdXQ0KDQpgYGANCg0KDQpFeHBvcnQgZGF0DQoNCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQoNCiMgdHh0LCBhc2NpaQ0KDQp3cml0ZS50YWJsZShsaXN0dFtbM11dLCBmaWxlPSJjOlxcVXNlcnNcXGx1Ym9wXFxEcm9wYm94XFxrdXJzUlxcc2xpbnV0eXByMi50eHQiLCBzZXA9J1x0JykNCg0KDQojIGNzdg0KDQp3cml0ZS5jc3YobGlzdHRbWzNdXSwgImM6XFxVc2Vyc1xcbHVib3BcXERyb3Bib3hcXGt1cnNSXFxzbGludXR5cHIuY3N2Iiwgcm93Lm5hbWVzPUZBTFNFKQ0KDQpsaWJyYXJ5KHJlYWRyKQ0Kd3JpdGVfY3N2KGxpc3R0W1s0XV0sICJjOlxcVXNlcnNcXGx1Ym9wXFxEcm9wYm94XFxrdXJzUlxcemFyb2RreS5jc3YiKQ0KbGlicmFyeShkYXRhLnRhYmxlKQ0KZndyaXRlKGxpc3R0W1syXV0sICJjOlxcVXNlcnNcXGx1Ym9wXFxEcm9wYm94XFxrdXJzUlxccG5ldS5jc3YiKQ0KDQoNCiMgRXhjZWwNCg0KbGlicmFyeShvcGVueGxzeCkNCndyaXRlLnhsc3gobGlzdHRbWzFdXSwgImM6XFxVc2Vyc1xcbHVib3BcXERyb3Bib3hcXGt1cnNSXFxjeWtsYW1hdHkxLnhsc3giLCBhc1RhYmxlID0gRkFMU0UsIG92ZXJ3cml0ZSA9IFRSVUUpDQoNCmxpYnJhcnkod3JpdGV4bCkNCndyaXRlX3hsc3gobGlzdHRbWzFdXSwgImM6XFxVc2Vyc1xcbHVib3BcXERyb3Bib3hcXGt1cnNSXFxjeWtsYW1hdHkyLnhsc3giKQ0KDQpgYGANCg0KDQrEjMOtc2xhIGRsZSBDaGVtaWNhbCBBYnN0cmFjdHMgU2VydmljZSAoQ0FTKQ0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQpsaWJyYXJ5KGVyYWgpDQoNCmZpbmRDb21wKG5hbWUgPSAiY2FmZmVpbmUiLCBpZC5kYXRhYmFzZSA9IG1zbGliLCBDQVMgPSBOVUxMLGNoZW0uZm9ybSA9IE5VTEwpDQpmaW5kQ29tcChuYW1lID0gInByb2xpbmUiLCBpZC5kYXRhYmFzZSA9IG1zbGliLCBDQVMgPSBOVUxMLGNoZW0uZm9ybSA9IE5VTEwpDQoNCmZpbmRDb21wKG5hbWUgPSBOVUxMLCBpZC5kYXRhYmFzZSA9IG1zbGliLCBDQVMgPSAiNTgtMDgtMiIsY2hlbS5mb3JtID0gTlVMTCkNCmZpbmRDb21wKG5hbWUgPSBOVUxMLCBpZC5kYXRhYmFzZSA9IG1zbGliLCBDQVMgPSAiNTAtNzgtMiIsY2hlbS5mb3JtID0gTlVMTCkNCg0KDQpsaWJyYXJ5KGh0dGspDQoNCmNoZW0ucGh5c2ljYWxfYW5kX2ludml0cm8uZGF0YQ0KDQpDQVMuY2hlY2tzdW0oQ0FTLnN0cmluZz0iNTAtNzgtMiIpICMgQXNwaXJpbg0KQ0FTLmNoZWNrc3VtKENBUy5zdHJpbmc9IjU4LTA4LTIiKSAjIENhZmZlaW5lDQoNCmBgYA0KDQoNCkJDUEMgQ29tcGVuZGl1bSBvZiBQZXN0aWNpZGUgQ29tbW9uIE5hbWVzIGh0dHBzOi8vcGVzdGljaWRlY29tcGVuZGl1bS5iY3BjLm9yZw0KICAgICBmb3JtZXJseSBrbm93biBhcyANCkFsYW4gV29vZHMgQ29tcGVuZGl1bSBvZiBQZXN0aWNpZGUgQ29tbW9uIE5hbWVzDQpodHRwOi8vd3d3LmFsYW53b29kLm5ldC9wZXN0aWNpZGVzDQoNCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQoNCmxpYnJhcnkod2ViY2hlbSkNCg0KIyB1c2UgbmFtZXMNCg0KYmNwY19xdWVyeSgiREVFVCIsIHR5cGUgPSAnY29tbW9ubmFtZScsIHZlcmJvc2UgPSBUUlVFKQ0KDQpiY3BjX3F1ZXJ5KCJGbHVhemluYW0iLCB0eXBlID0gJ2NvbW1vbm5hbWUnLCB2ZXJib3NlID0gVFJVRSkkZmx1YXppbmFtJGZvcm11bGFbMV0NCg0KYmNwY19xdWVyeSgnUGFyYXRoaW9uJywgZnJvbSA9J25hbWUnKQ0KDQpvdXQgPSBiY3BjX3F1ZXJ5KGMoJ0ZsdWF6aW5hbScsJ0RpY2xvZm9wJyksIGZyb20gPSduYW1lJykNCm91dA0KDQoNCiMgdXNlIENBUy1udW1iZXJzDQoNCmJjcGNfcXVlcnkoIjc5NjIyLTU5LTYiLCBmcm9tID0nY2FzJykNCg0KYmNwY19xdWVyeSgiNTEtMDMtNiIsIGZyb20gPSAnY2FzJywgdmVyYm9zZSA9IFRSVUUpDQojIGZyb20gPSBjKCJuYW1lIiwgImNhcyIpDQoNCg0KYGBgDQoNCg0KQ2hlbWljYWxJZGVudGlmaWVyUmVzb2x2ZXIoQ0lSKQ0KaHR0cDovL2NhY3R1cy5uY2kubmloLmdvdi9jaGVtaWNhbC8NCg0KYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0KbGlicmFyeSh3ZWJjaGVtKQ0KDQpjaXJfcXVlcnkoInBpcGVyb255bCBidXRveGlkZSIsIHJlcHJlc2VudGF0aW9uID0gInNtaWxlcyIsIHJlc29sdmVyID0gTlVMTCwgZmlyc3QgPSBGQUxTRSwgdmVyYm9zZSA9IFRSVUUpDQpjaXJfcXVlcnkoIjUxLTAzLTYiLCByZXByZXNlbnRhdGlvbiA9ICJzbWlsZXMiLCByZXNvbHZlciA9IE5VTEwsIGZpcnN0ID0gRkFMU0UsIHZlcmJvc2UgPSBUUlVFKQ0KDQojIFNNSUxFUw0KY2lyX3F1ZXJ5KCdJbWlkYWNsb3ByaWQnLCByZXByZXNlbnRhdGlvbiA9ICdzbWlsZXMnKQ0KY2lyX3F1ZXJ5KCdBc3BpcmluJywgJ3NtaWxlcycpDQpjaXJfcXVlcnkoJ1RyaWNsb3NhbicsICdzbWlsZXMnKQ0KY2lyX3F1ZXJ5KCIzMzgwLTM0LTUiLCAnc21pbGVzJykNCg0KIyBDQVMNCmNpcl9xdWVyeSgnSW1pZGFjbG9wcmlkJywgcmVwcmVzZW50YXRpb24gPSAnY2FzJykNCmNpcl9xdWVyeSgnREVFVCcsICdjYXMnLCBmaXJzdCA9IFRSVUUpDQpjaXJfcXVlcnkoJ1RyaWNsb3NhbicsICdjYXMnKQ0KY2lyX3F1ZXJ5KCIzMzgwLTM0LTUiLCAnY2FzJywgZmlyc3QgPSBUUlVFKQ0KY2lyX3F1ZXJ5KCIzMzgwLTM0LTUiLCAnY2FzJywgcmVzb2x2ZXIgPSAnY2FzX251bWJlcicpDQoNCiMgSW5DaElLZXkNCmNpcl9xdWVyeSgnSW1pZGFjbG9wcmlkJywgcmVwcmVzZW50YXRpb24gPSAnc3RkaW5jaGlrZXknKQ0KDQojIE1vbGVjdWxhciB3ZWlnaHQNCmNpcl9xdWVyeSgnSW1pZGFjbG9wcmlkJywgcmVwcmVzZW50YXRpb24gPSAnbXcnKQ0KDQojIG51bWJlciBvZiByaW5ncw0KY2lyX3F1ZXJ5KCdJbWlkYWNsb3ByaWQnLCByZXByZXNlbnRhdGlvbiA9ICdyaW5nX2NvdW50JykNCg0KIyBmb3JtdWxhDQpjaXJfcXVlcnkoIjMzODAtMzQtNSIsICdmb3JtdWxhJykNCg0KIyBuYW1lDQpjaXJfcXVlcnkoIjMzODAtMzQtNSIsICduYW1lcycpDQoNCg0KY2lyX3F1ZXJ5KCIzMzgwLTM0LTUiLCAncHViY2hlbV9zaWQnKQ0KY2lyX3F1ZXJ5KCIzMzgwLTM0LTUiLCAnY2hlbW5hdmlnYXRvcl9zaWQnKQ0KDQoNCm5hbWUgPSAnVHJpY2xvc2FuJw0KY2lyX3F1ZXJ5KG5hbWUsICdtdycpDQpjaXJfcXVlcnkobmFtZSwgJ2Zvcm11bGEnKQ0KY2lyX3F1ZXJ5KG5hbWUsICdtb25vaXNvdG9waWNfbWFzcycpDQpjaXJfcXVlcnkobmFtZSwgJ2hldGVyb2F0b21fY291bnQnKQ0KY2lyX3F1ZXJ5KG5hbWUsICdoeWRyb2dlbl9hdG9tX2NvdW50JykNCg0KDQpjb21wIDwtIGMoJ1RyaWNsb3NhbicsICdBc3BpcmluJykNCmNpcl9xdWVyeShjb21wLCAnY2FzJykNCmNpcl9xdWVyeShjb21wLCAnY2FzJywgZmlyc3QgPSBUUlVFKQ0KY2lyX3F1ZXJ5KGNvbXAsICdzbWlsZXMnKQ0KY2lyX3F1ZXJ5KGNvbXAsICdtdycpDQoNCg0KY2lyX2ltZygiQ0NPIiwgZGlyID0gImM6XFxVc2Vyc1xcbHVib3BcXERyb3Bib3hcXGt1cnNSXFwiKSAjIFNNSUxFUw0KDQpxdWVyeSA9IGMoIkdseXBob3NhdGUiLCAiSXNvcHJvdHVyb24iLCAiQlNZTlJZTVVUWEJYU1EtVUhGRkZBT1lTQS1OIikNCmNpcl9pbWcocXVlcnksIGRpciA9ICJjOlxcVXNlcnNcXGx1Ym9wXFxEcm9wYm94XFxrdXJzUlxcIiwgYmdjb2xvciA9ICJ0cmFuc3BhcmVudCIsIGFudGlhbGlzaW5nID0gMCkNCg0KcXVlcnkgID0gIlRyaWNsb3NhbiINCmNpcl9pbWcocXVlcnksZGlyID0gImM6XFxVc2Vyc1xcbHVib3BcXERyb3Bib3hcXGt1cnNSXFwiLGZvcm1hdCA9ICJwbmciLHdpZHRoID0gNjAwLGhlaWdodCA9IDYwMCxsaW5ld2lkdGggPSAyLHN5bWJvbGZvbnRzaXplID0gMzAsYmdjb2xvciA9ICJ3aGl0ZSIsYW50aWFsaWFzaW5nID0gRkFMU0UsYXRvbWNvbG9yID0gImJsYWNrIixib25kY29sb3IgPSAiYmxhY2siLGNzeW1ib2wgPSAiYWxsIixoc3ltYm9sID0gImFsbCIsaGNvbG9yID0gImJsYWNrIixoZWFkZXIgPSAiIixmb290ZXIgPSAiIixmcmFtZSA9IDEsdmVyYm9zZSA9IGdldE9wdGlvbigidmVyYm9zZSIpKQ0KDQpgYGANCg0KDQpDaGVtaWNhbElkZW50aWZpZXJSZXNvbHZlcihDSVIpDQpodHRwczovL2NhY3R1cy5uY2kubmloLmdvdi9jaGVtaWNhbC9zdHJ1Y3R1cmUNCg0KYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0KbGlicmFyeShNU2JveCkNCg0KZGVzY3JpYmUoJ1RyaWNsb3NhbicsICJmb3JtdWxhIiwgaW5mbyA9IFRSVUUpIA0KDQpkZXNjcmliZSgnbWFsaWMgYWNpZCcsICJmb3JtdWxhIiwgaW5mbyA9IFRSVUUpIA0KZGVzY3JpYmUoJ21hbGljIGFjaWQnLCAibXciLCBpbmZvID0gRkFMU0UpIA0KZGVzY3JpYmUoJ21hbGljIGFjaWQnLCAiaHlkcm9nZW5fYXRvbV9jb3VudCIsIGluZm8gPSBGQUxTRSkgDQpkZXNjcmliZSgnbWFsaWMgYWNpZCcsICJoZXRlcm9hdG9tX2NvdW50IiwgaW5mbyA9IEZBTFNFKSANCg0KZGVzY3JpYmUoYygnbWFsaWMgYWNpZCcsICdjaXRyaWMgYWNpZCcsICd0YXJ0YXJpYyBhY2lkJyksICJzbWlsZXMiKQ0KDQpkZXNjcmliZSgnZ2x5cGhvc2F0ZScsICJmb3JtdWxhIiwgaW5mbyA9IEZBTFNFKSANCmRlc2NyaWJlKCdnbHlwaG9zYXRlJywgIm13IiwgaW5mbyA9IEZBTFNFKQ0KZGVzY3JpYmUoJ2dseXBob3NhdGUnLCAic21pbGVzIiwgaW5mbyA9IEZBTFNFKSANCmRlc2NyaWJlKCdnbHlwaG9zYXRlJywgInN0ZGluY2hpa2V5IiwgaW5mbyA9IEZBTFNFKSANCg0KYGBgDQoNCg0KQ2hlbWljYWwgVHJhbnNsYXRpb24gU2VydmljZSAoQ1RTKQ0KaHR0cDovL2N0cy5maWVobmxhYi51Y2RhdmlzLmVkdS8NCg0KYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0KbGlicmFyeSh3ZWJjaGVtKQ0KDQpvdXQgPC0gY3RzX2NvbXBpbmZvKCJYRUZRTElOVktGWVJDUy1VSEZGRkFPWVNBLU4iLCB2ZXJib3NlID0gVFJVRSkNCnN0cihvdXQpIA0Kb3V0W1sxXV1bMTo1XQ0KDQppbmNoaWtleXMgPC0gYygiWEVGUUxJTlZLRllSQ1MtVUhGRkZBT1lTQS1OIiwiQlNZTlJZTVVUWEJYU1EtVUhGRkZBT1lTQS1OIiApIA0Kb3V0MiA8LSBjdHNfY29tcGluZm8oaW5jaGlrZXlzKSANCnN0cihvdXQyKQ0KDQpzYXBwbHkob3V0MiwgZnVuY3Rpb24oeSkgYyh5JGZvcm11bGEseSRtb2x3ZWlnaHQpKQ0KDQoNCmN0c19jb252ZXJ0KCdYRUZRTElOVktGWVJDUy1VSEZGRkFPWVNBLU4nLCAnaW5jaGlrZXknLCAnQ2hlbWljYWwgTmFtZScpDQojICdDaGVtaWNhbCBOYW1lJywnSW5DaElLZXknLCdQdWJDaGVtIENJRCcsICdDaGVtU3BpZGVyJywgJ0NBUycNCg0KY29tcCA8LSBjKCdYRUZRTElOVktGWVJDUy1VSEZGRkFPWVNBLU4nLCAnQlNZTlJZTVVUWEJYU1EtVUhGRkZBT1lTQS1OJykgDQpjdHNfY29udmVydChjb21wLCAnaW5jaGlrZXknLCAnQ0FTJykNCg0KIyBjdHNfY29udmVydChxdWVyeSwgZnJvbSwgdG8sIGZpcnN0ID0gRkFMU0UsIHZlcmJvc2UgPSBUUlVFKQ0KDQpgYGANCg0KDQpQdWJDaGVtIA0KaHR0cHM6Ly9wdWJjaGVtLm5jYmkubmxtLm5paC5nb3YvDQpDb21wb3VuZElEIChDSUQpIGZvciBhIHNlYXJjaCBxdWVyeSB1c2luZyBQVUctUkVTVCBodHRwczovL3B1YmNoZW0ubmNiaS4gbmxtLm5paC5nb3YvDQoNCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQoNCiMgZ2V0X2NpZChxdWVyeSwgZnJvbSA9ICJuYW1lIiwgZmlyc3QgPSBGQUxTRSwgdmVyYm9zZSA9IFRSVUUsIGFyZyA9IE5VTEwpDQoNCmNvbXAgPC0gYygnVHJpY2xvc2FuJywgJ0FzcGlyaW4nKSANCmdldF9jaWQoY29tcCkNCiMgZnJvbSA9ICduYW1lJyhkZWZhdWx0KSwnY2lkJywnc2lkJywnYWlkJywnc21pbGVzJywgJ2luY2hpJywgJ2luY2hpa2V5Jw0KDQpwY19wcm9wKDU1NjQsIHByb3BlcnRpZXMgPSBOVUxMLCB2ZXJib3NlID0gVFJVRSkNCg0KDQpwY19zeW5vbnltcygnQXNwaXJpbicpIA0KcGNfc3lub255bXMoYygnQXNwaXJpbicsICdUcmljbG9zYW4nKSkgDQpwY19zeW5vbnltcyg1NTY0LCBmcm9tID0gJ2NpZCcpIA0KIyBmcm9tID0gJ25hbWUnKGRlZmF1bHQpLCdjaWQnLCdzaWQnLCdhaWQnLCdzbWlsZXMnLCAnaW5jaGknLCAnaW5jaGlrZXknDQoNCg0KDQpgYGANCg0KDQpFVE9YOiBJbmZvcm1hdGlvbiBTeXN0ZW0gRWNvdG94aWNvbG9neSBhbmQgRW52aXJvbm1lbnRhbCBRdWFsaXR5IFRhcmdldHMgDQpodHRwczovLyB3ZWJldG94LnViYS5kZS93ZWJFVE9YL2luZGV4LmRvIA0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQpjb21wcyA8LSBjKCdUcmljbG9zYW4nLCdHbHlwaG9zYXRlJywgJ0RFRVQnKSANCmdldF9ldG94aWQoY29tcHMsIG1hdGNoID0gJ2FsbCcpDQoNCmlkcyA8LSBjKCIyMDE3OSIsICI5MDUxIiwgIjIwMDEiKQ0KZXRveF9iYXNpYyhpZHMpDQoNCmNvbXAgPC0gYygnVHJpY2xvc2FuJywgJ0FzcGlyaW4nKSAjIG5lZnVuZ3VqZQ0KZXRveF9iYXNpYyhjb21wKQ0KDQoNCmlkIDwtIGdldF9ldG94aWQoImZsdWF6aW5hbSIsIG1hdGNoID0gJ2Jlc3QnKSANCmV0b3hfdGVzdHMoaWQpDQpldG94X2Jhc2ljKCI5ODk3NiIpDQoNCg0KYGBgDQoNCg0KV2lraWRhdGEgSXRlbSBJRA0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQpnZXRfd2RpZCgnVHJpY2xvc2FuJywgbGFuZ3VhZ2UgPSAnZGUnKSANCmdldF93ZGlkKCdERFQnKSANCmdldF93ZGlkKCdERFQnLCBtYXRjaCA9ICdhbGwnKQ0KIyBtYXRjaCA9IGMoImJlc3QiLCAiZmlyc3QiLCAiYWxsIiwgImFzayIsICJuYSIpDQoNCmNvbXBzIDwtIGMoJ1RyaWNsb3NhbicsICdHbHlwaG9zYXRlJykgDQpnZXRfd2RpZChjb21wcykNCg0KaWQgPC0gYygiUTQwODY0NiIpDQp3ZF9pZGVudChpZCwgdmVyYm9zZSA9IFRSVUUpDQojICdzbWlsZXMnLCAnY2FzJywgJ2NpZCcsICdlaW5lY3MnLCAnY3NpZCcsICdpbmNoaScsICdpbmNoaWtleScsICdkcnVnYmFuaycsICd6dmcnLCAnY2hlYmknLCAnY2hlbWJsJywgJ3VuaWknIGFuZCBzb3VyY2VfdXJsDQoNCmBgYA0KDQoNCkZsYXZvciBwZXJjZXB0cyANCmh0dHA6Ly93d3cuZmxhdm9ybmV0Lm9yZw0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQpmbl9wZXJjZXB0KCIxMjMtMzItMCIsIHZlcmJvc2UgPSBUUlVFKQ0KDQpDQVNzIDwtIGMoIjc1LTA3LTAiLCAiNjQtMTctNSIsICIxMDktNjYtMCIsICI3OC05NC00IiwgIjc4LTkzLTMiKSANCmZuX3BlcmNlcHQoQ0FTcywgdmVyYm9zZSA9IFRSVUUpDQoNCmBgYA0KDQoNCkNoZW1JRFBsdXMNCmh0dHA6Ly9jaGVtLnNpcy5ubG0ubmloLmdvdi9jaGVtaWRwbHVzDQpodHRwOi8vY3RzLmZpZWhubGFiLnVjZGF2aXMuZWR1Lw0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQpsaWJyYXJ5KHdlYmNoZW0pDQoNCmNpX3F1ZXJ5KCdXU0ZTU05VTVZNT09NUi1VSEZGRkFPWVNBLU4nLCBmcm9tID0naW5jaGlrZXknKQ0KDQp5MiA8LSBjaV9xdWVyeSgnV1NGU1NOVU1WTU9PTVItVUhGRkZBT1lTQS1OJywgZnJvbSA9J2luY2hpa2V5JykNCnkyW1sxXV0kbmFtZQ0KDQp5MiA8LSBjaV9xdWVyeSgnNTAtMDAtMCcsIGZyb20gPSdybicpDQp5MltbMV1dJG5hbWUNCg0KY29tcHMgPC0gYygiNTAtMDAtMCIsICI2NC0xNy01IikNCmNpX3F1ZXJ5KGNvbXBzLCBmcm9tID0gInJuIikNCg0KeTIgPC0gY2lfcXVlcnkoJzUwLTAwLTAnLCBmcm9tID0gJ3JuJykgDQp5MltbJzUwLTAwLTAnXV0kaW5jaGlrZXkNCnkyW1snNTAtMDAtMCddXSRuYW1lDQp5MltbJzUwLTAwLTAnXV0kcGh5c3Byb3ANCnkyW1snNTAtMDAtMCddXSRzbWlsZXMNCnkyW1snNTAtMDAtMCddXSRjYXMNCnkyW1snNTAtMDAtMCddXSRzeW5vbnltcw0KeTJbWyc1MC0wMC0wJ11dJHRveGljaXR5DQoNCnkxIDwtIGNpX3F1ZXJ5KCc1MC0wMC0wJywgZnJvbSA9J3JuJykNCnkxW1snNTAtMDAtMCddXSRuYW1lDQojIGV4dHJhY3QgbG9nLVANCnNhcHBseSh5MSwgZnVuY3Rpb24oeSl7aWYgKGxlbmd0aCh5KSA9PSAxICYmIGlzLm5hKHkpKQ0KICByZXR1cm4oTkEpDQogIHkkcGh5c3Byb3AkVmFsdWVbeSRwaHlzcHJvcCRgUGh5c2ljYWwgUHJvcGVydHlgPT0nbG9nIFAgKG9jdGFub2wtd2F0ZXIpJ119KQ0KDQpgYGANCg0KDQpRdWVyeSB0aGUgT1BTSU4gKE9wZW4gUGFyc2VyIGZvciBTeXN0ZW1hdGljIElVUEFDIG5vbWVuY2xhdHVyZSkgd2ViIHNlcnZpY2UgDQpodHRwOi8vb3BzaW4uY2guY2FtLmFjLnVrL2luc3RydWN0aW9ucy5odG1sDQoNCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQoNCmxpYnJhcnkod2ViY2hlbSkNCg0Kb3BzaW5fcXVlcnkoJ0N5Y2xvcHJvcGFuZScsIHZlcmJvc2UgPSBUUlVFKSANCg0Kb3BzaW5fcXVlcnkoYygnQ3ljbG9wcm9wYW5lJywgJ09jdGFuZScpLCB2ZXJib3NlID0gVFJVRSkgDQoNCmBgYA0KDQoNCkFjdXRlIHRveGljaXR5IGRhdGEgZnJvbSBVLlMuIEVQQSBFQ09UT1gNCg0KYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0KbGlicmFyeSh3ZWJjaGVtKQ0KDQpsYzUwDQpsYzUwWywxXQ0KDQp0bm0gPSAiNjc0ODUtMjktNCINCm5hbSA9IGNpcl9xdWVyeSh0bm0sICduYW1lcycsIGZpcnN0ID0gRkFMU0UpDQpsYzUwW3doaWNoKGxjNTBbLDFdPT10bm0pLDJdDQoNCmBgYA0KDQoNCg0KYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0KbGlicmFyeShQZXN0aWNpZGVMb2FkSW5kaWNhdG9yKQ0KDQpwcm9kdWN0cy5wYXRoKCkNCnByb2R1Y3RzID0gcHJvZHVjdHMubG9hZCgpDQpjaGVja19wcm9kdWN0c19jb2x1bW5fbmFtZXMocHJvZHVjdHMpDQoNCnN1YnN0YW5jZXMgPSBzdWJzdGFuY2VzLmxvYWQoKQ0KDQpjb21wdXRlX3Blc3RpY2lkZV9sb2FkX2luZGljYXRvcihzdWJzdGFuY2VzLCBwcm9kdWN0cykNCg0KDQojIE9yZ2FuaWMgcGxhbnQgcHJvdGVjdGlvbiBwcm9kdWN0cyBpbiB0aGUgcml2ZXIgSmFnc3QgKEdlcm1hbnkpIGluIDIwMTMNCmxpYnJhcnkod2ViY2hlbSkNCmphZ3N0DQp1bmlxdWUoamFnc3RbLCJzdWJzdGFuY2UiXSkNCg0KDQpsaWJyYXJ5KENoZW1taW5lUikNCnB1YmNoZW1TbWlsZXNTZWFyY2goc21pbGUpDQoNCg0KbGlicmFyeShDSE5PU1opDQppQ0ggPC0gaW5mbygiU08yIikNCmluZm8oaUNIKQ0KDQpgYGANCg0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQojIGxpYnJhcnkockphdmEpDQpsaWJyYXJ5KHJjZGspDQoNCmZvcm11bGEgPC0gZ2V0LmZvcm11bGEoJ05INCcsIGNoYXJnZSA9IDEpDQpmb3JtdWxhDQpmb3JtdWxhQG1hc3MNCmZvcm11bGFAY2hhcmdlDQpmb3JtdWxhQGlzb3RvcGVzDQpmb3JtdWxhQHN0cmluZw0KDQoNCmFubGUxMzhiID0gcGFyc2Uuc21pbGVzKCJDMU9DMj1DKE8xKUM9QyhDPUMyKUMzPUNDKD1OTjMpQzQ9Q0MoPUNDPUM0KUJyIilbWzFdXQ0KYW5sZTEzOGIgPSBwYXJzZS5zbWlsZXMoImMxY2NjY2MxQ0MoPU8pQyhOKUNDMUNDQ0NPQzEiKVtbMV1dDQoNCg0KZ2V0LmRlcGljdG9yKHdpZHRoID0gNTAwLCBoZWlnaHQgPSA1MDAsIHpvb20gPSAxLjMsIHN0eWxlID0gImNvdyIsIGFubm90YXRlID0gIm9mZiIsIGFiYnIgPSAib24iLCBzdXBwcmVzc2ggPSBUUlVFLCBzaG93VGl0bGUgPSBGQUxTRSwgc21hTGltaXQgPSAxMDAsIHNtYSA9IE5VTEwpIA0KDQpyY2RrcGxvdCA9IGZ1bmN0aW9uKG1vbGVjdWxlKXsNCiAgcGFyKG1hcj1jKDAsMCwwLDApKSAjIHNldCBtYXJnaW5zIHRvIHplcm8gc2luY2UgdGhpcyBpc24ndCBhIHJlYWwgcGxvdA0KICB0ZW1wMSA9IHZpZXcuaW1hZ2UuMmQobW9sZWN1bGUsIGRlcGljdG9yID0gTlVMTCkgIyBnZXQgSmF2YSByZXByZXNlbnRhdGlvbiBpbnRvIGFuIGltYWdlIG1hdHJpeC4gc2V0IG51bWJlciBvZiBwaXhlbHMgeW91IHdhbnQgaG9yaXogYW5kIHZlcnRpY2FsDQogIHBsb3QoTkEsTkEseGxpbT1jKDEsMTApLHlsaW09YygxLDEwKSx4YXh0PSduJyx5YXh0PSduJyx4bGFiPScnLHlsYWI9JycpICMgY3JlYXRlIGFuIGVtcHR5IHBsb3QNCiAgcmFzdGVySW1hZ2UodGVtcDEsMSwxLDEwLDEwKSAjIGJvdW5kYXJpZXMgb2YgcmFzdGVyOiB4bWluLCB5bWluLCB4bWF4LCB5bWF4LiBoZXJlIGkgc2V0IHRoZW0gZXF1YWwgdG8gcGxvdCBib3VuZGFyaWVzDQp9DQpyY2RrcGxvdChhbmxlMTM4YikNCg0KDQp0b2RlcGljdCA8LSBmdW5jdGlvbihtb2wscGF0aHNkKXsjIHJhYWxpemFkZWgsIGh0dHBzOi8vZ2l0aHViLmNvbS9DREstUi9jZGtyL2lzc3Vlcy82MQ0KICByZXN1bHQgPSB0cnlDYXRjaCh7DQogICAgZmFjdG9yeSA8LSAuam5ldygib3JnLm9wZW5zY2llbmNlLmNkay5kZXBpY3QuRGVwaWN0aW9uR2VuZXJhdG9yIikkd2l0aEF0b21Db2xvcnMoKQ0KICAgIGZhY3Rvcnkkd2l0aFNpemUoMTAwMCwxMDAwKSMkZ2V0U3R5bGUoImNvdyIpDQogICAgdGVtcDEgPC0gcGFzdGUwKHBhdGhzZCkNCiAgICByZXN1bHQ8LWZhY3RvcnkkZGVwaWN0KG1vbCkkd3JpdGVUbyh0ZW1wMSkNCiAgfSwgd2FybmluZyA9IGZ1bmN0aW9uKHcpIHsNCiAgICByZXN1bHQ9TlVMTA0KICB9LCBlcnJvciA9IGZ1bmN0aW9uKGUpIHsNCiAgICByZXN1bHQ9TlVMTA0KICB9KQ0KICByZXR1cm4ocmVzdWx0KQ0KfQ0KDQpsaWJyYXJ5KE1TYm94KQ0Kc21pbGUgPC0gYXMuY2hhcmFjdGVyKGRlc2NyaWJlKCdjYW1wdG90aGVjaW4nLCAic21pbGVzIiwgaW5mbyA9IEZBTFNFKSApDQptb2w8LXBhcnNlLnNtaWxlcyhzbWlsZSlbWzFdXQ0KDQp0b2RlcGljdChtb2wsJ2M6XFxVc2Vyc1xcbHVib3BcXERyb3Bib3hcXGt1cnNSXFxjYW1wdG90aGVjaW4ucG5nJykNCg0KYGBgDQoNCg0KDQoNCg0KYGBge3J9DQoNCg0KYXMuY2hhcmFjdGVyKDMuMTQpDQphcy5jaGFyYWN0ZXIocGkpDQoNCmRhdGEgPC0gYygtMTEsIDIxLCAxLjUsIC0zMSkNCmFzLmNoYXJhY3RlcihkYXRhKQ0KDQoNCiMjIG51bWJlciBvZiBzdHJpbmdzDQpsZW5ndGgoIkJhQ3JPNCIpDQpsZW5ndGgoIkhvdyBtYW55IGNoYXJhY3RlcnM/IikNCmxlbmd0aChjKCJIb3ciLCAibWFueSIsICJjaGFyYWN0ZXJzPyIpKQ0KDQojIyBudW1iZXIgb2YgY2hhcmF0ZXJzDQpuY2hhcigiQmFDck80IikNCm5jaGFyKCJIb3cgbWFueSBjaGFyYWN0ZXJzPyIpDQpuY2hhcihjKCJIb3ciLCAibWFueSIsICJjaGFyYWN0ZXJzPyIpKQ0KDQpsaWJyYXJ5KHN0cmluZ3IpDQpzdHJfbGVuZ3RoKCJCYUNyTzQiKQ0Kc3RyX2xlbmd0aCgiSG93IG1hbnkgY2hhcmFjdGVycz8iKQ0Kc3RyX2xlbmd0aChjKCJIb3ciLCAibWFueSIsICJjaGFyYWN0ZXJzPyIpKQ0KDQpzb21lX3RleHQgPSBjKCJvbmUiLCAidHdvIiwgInRocmVlIiwgTkEsICJmaXZlIikNCnN0cl9sZW5ndGgoc29tZV90ZXh0KQ0KbmNoYXIoc29tZV90ZXh0KQ0KDQpzb21lX2ZhY3RvciA9IGZhY3RvcihjKDEsIDEsIDEsIDIsIDIsIDIpLCBsYWJlbHMgPSBjKCJnb29kIiwgImJhZCIpKQ0Kc29tZV9mYWN0b3INCnN0cl9sZW5ndGgoc29tZV9mYWN0b3IpDQpuY2hhcihzb21lX2ZhY3RvcikNCg0KDQojIFVzcG9yYWRhbmkNCg0Kc2V0MTEgPSBjKCJ0b2RheSIsICJwcm9kdWNlZCIsICJleGFtcGxlIiwgImJlYXV0aWZ1bCIsICJhIiwgIm5pY2VseSIpDQojIHNvcnQgKGRlY3JlYXNpbmcgb3JkZXIpDQpzb3J0KHNldDExKQ0KIyBzb3J0IChpbmNyZWFzaW5nIG9yZGVyKQ0Kc29ydChzZXQxMSwgZGVjcmVhc2luZyA9IFRSVUUpDQoNCg0KbGlicmFyeShzdHJpbmdpKQ0Kc3RyaV9yZXZlcnNlKCJkbmEiKQ0Kc3RyaV9yZXZlcnNlKHNldDExKQ0KDQoNCiMjIyBTcG9qb3ZhbmkgcmV0ZXpjdQ0KDQp0b1N0cmluZygxNy4wNCkNCnRvU3RyaW5nKGMoMTcuMDQsIDE5NzgpKQ0KdG9TdHJpbmcoYygiQm9uam91ciIsIDEyMywgVFJVRSwgTkEsIGxvZyhleHAoMSkpKSkNCg0KDQojIyBwYXN0ZQ0KDQpwYXN0ZSgiVGhpcyBpcyIsICAib3V0IG9mIiwgICAiZXhhbXBsZXMuIikNCnBhc3RlMCgiVGhpcyBpcyIsICAib3V0IG9mIiwgICJleGFtcGxlcy4iKSANCnBhc3RlMCgiVGhpcyBpcyIsICAiIG91dCBvZiIsICAiIGV4YW1wbGVzLiIpDQoNCmEgPC0gImFjZXRpYyINCmIgPC0gImFjaWQiDQpjIDwtICJhbmh5ZHJpZGUiDQoNCmQxIDwtIHBhc3RlKGEsIGIsIGMpOyBkMQ0KZDIgPC0gcGFzdGUoYSwgYiwgYywgc2VwID0gIi0iKTsgZDINCg0KcGFzdGUoIkkiLCAibG92ZSIsICJSIiwgc2VwID0gIi0iKQ0KDQoNCnN0ciA8LSBwYXN0ZShjKDE6MyksICI0Iiwgc2VwID0gIjoiKQ0KcHJpbnQgKHN0cikNCg0Kc3RyIDwtIHBhc3RlKGMoMTo0KSwgYyg1OjgpLCBzZXAgPSAiLS0iKQ0KcHJpbnQgKHN0cikNCg0KcGFzdGUoIlgiLCAxOjUsIHNlcCA9ICIuIikNCg0KcGFzdGUoMTozLCBjKCIhIiwgIj8iLCAiKyIpKQ0KcGFzdGUoMTozLCBjKCIhIiwgIj8iLCAiKyIpLCBzZXAgPSAiIikNCnBhc3RlMCgxOjMsIGMoIiEiLCAiPyIsICIrIikpDQpwYXN0ZSgxOjMsIGMoIiEiLCAiPyIsICIrIiksIHNlcCA9ICIiLCBjb2xsYXBzZSA9ICIiKQ0KcGFzdGUwKDE6MywgYygiISIsICI/IiwgIisiKSwgY29sbGFwc2UgPSAiIikNCg0KcGFzdGUoIlRoZSB2YWx1ZSBvZiBwaSBpcyIsIHJvdW5kKHBpLDMpLCAiYW5kIHZhbHVlIG9mIGUgaXMiLCByb3VuZChleHAoMSksMyksIi4iKQ0KDQoNCmRmIDwtIGRhdGEuZnJhbWUoY2F0aW9uPWMoJ3NvZGl1bScsJ21lcmN1cnknLCdpcm9uJywnY2FsY2l1bScpLA0KICAgICAgICAgICAgICAgICBhbmlvbj1jKCdhY2V0YXRlJywnc3VscGhhdGUnLCdkaW94aWRlJywnb3hhbGF0ZScpLA0KICAgICAgICAgICAgICAgICBwdXJpdHk9YygwLjk5LCAwLjksIDAuOTk5LCAwLjk4NSkpDQpkZg0KZGYkbmFtZSA9IHBhc3RlKGRmJGNhdGlvbiwgZGYkYW5pb24pDQpkZg0KDQpsaWJyYXJ5KHN0cmluZ3IpDQpzdHJfYygiTWF5IiwgIlRoZSIsICJGb3JjZSIsICJCZSIsICJXaXRoIiwgIllvdSIpDQoNCg0KbGlicmFyeShzdHJpbmdyKQ0Kc3RyX2MoIk1heSIsICJUaGUiLCAiRm9yY2UiLCBOVUxMLCAiQmUiLCAiV2l0aCIsICJZb3UiLCBjaGFyYWN0ZXIoMCkpDQpwYXN0ZSgiTWF5IiwgIlRoZSIsICJGb3JjZSIsIE5VTEwsICJCZSIsICJXaXRoIiwgIllvdSIsIGNoYXJhY3RlcigwKSkNCg0Kc3RyX2MoIk1heSIsICJUaGUiLCAiRm9yY2UiLCAiQmUiLCAiV2l0aCIsICJZb3UiLCBzZXAgPSAiXyIpDQoNCiMgc3RyX2pvaW4oIk1heSIsICJUaGUiLCAiRm9yY2UiLCAiQmUiLCAiV2l0aCIsICJZb3UiLCBzZXAgPSAiLSIpIA0KIyBhbmFsb2dpY2thIGZjZSBrIHByZWRjaG96aQ0KDQoNCiMjIGNhdCAtIHBvdXplIHZ5cGlzdWplIHJldGV6ZWMNCg0KY2F0KCJsZWFybiIsICJjb2RlIiwgInRlY2giLCBzZXAgPSAiOiIpDQpzdHIgPC0gY2F0KCJsZWFybiIsICJjb2RlIiwgInRlY2giLCBzZXAgPSAiOiIpICMgbmVsemUgdWxveml0IGRvIHByb21lbm5lDQpwcmludCAoc3RyKSANCg0KbXlfc3RyaW5nID0gYygibGVhcm4iLCAiY29kZSIsICJ0ZWNoIikNCmNhdChteV9zdHJpbmcsICJ3aXRoIFIiKQ0KY2F0KG15X3N0cmluZywgIndpdGggUiIsIHNlcCA9ICIgPSkgIikNCg0KY2F0KDE6MTAsIHNlcCA9ICItIikNCmNhdChtb250aC5uYW1lWzE6NF0sIHNlcCA9ICIgIikNCg0KY2F0KGMoMTo1KSwgZmlsZSA9J3NhbXBsZS50eHQnKQ0KY2F0KG15X3N0cmluZywgIndpdGggUiIsIGZpbGUgPSAib3V0cHV0LnR4dCIpDQpjYXQoMTE6MjAsIHNlcCA9ICdcbicsIGZpbGUgPSAndGVtcC5jc3YnKQ0KcmVhZExpbmVzKCd0ZW1wLmNzdicpICMgcmVhZCB0aGUgZmlsZSB0ZW1wLmNzdg0KDQpjYXQoIlRoZSB2YWx1ZSBvZiBwaSBpcyIsIHJvdW5kKHBpLDMpLCAiYW5kIHZhbHVlIG9mIGUgaXMiLCByb3VuZChleHAoMSksMyksIi4iKQ0KDQoNCiMjIHByaW50IC0gdnlwaXN1amUgdnNlY2hueSBmb3JtYXR5DQoNCnByaW50KGRmKQ0KZGYNCg0KbXlfdmFsdWUgPC0gODIzNS42NzUzMjQgDQpteV92YWx1ZQ0KcHJpbnQobXlfdmFsdWUpIA0KcHJpbnQobXlfdmFsdWUsIGRpZ2l0cyA9IDUpIA0KDQpwcmludChjKCJsZWFybiIsICJjb2RlIiwgInRlY2giKSkNCnBhc3RlKGMoImxlYXJuIiwgImNvZGUiLCAidGVjaCIpKQ0KcGFzdGUoYygibGVhcm4iLCAiY29kZSIsICJ0ZWNoIiksIGNvbGxhcHNlPSIgIikNCmNhdChjKCJsZWFybiIsICJjb2RlIiwgInRlY2giKSkNCg0KbXlfc3RyaW5nIDwtICJUaGlzIGlzIFxudGhlIGV4YW1wbGUgc3RyaW5nIiANCnByaW50KG15X3N0cmluZykgIA0KY2F0KG15X3N0cmluZykgDQoNCg0KIyMjIA0KDQpsaWJyYXJ5KHN0cmluZ3IpDQoNCnN0cl9kdXAoImhvbGEiLCAzKQ0Kc3RyX2R1cCgiYWRpb3MiLCAxOjMpDQoNCndvcmRzID0gYygibG9yZW0iLCAiaXBzdW0iLCAiZG9sb3IiLCAic2l0IiwgImFtZXQiKQ0Kc3RyX2R1cCh3b3JkcywgMikNCnN0cl9kdXAod29yZHMsIDE6NSkNCg0KDQojIyMjDQoNCmZvcm1hdChjKCJBIiwgIkJCIiwgIkNDQyIpLCB3aWR0aCA9IDUsIGp1c3RpZnkgPSAiY2VudHJlIikNCmZvcm1hdChjKCJBIiwgIkJCIiwgIkNDQyIpLCB3aWR0aCA9IDUsIGp1c3RpZnkgPSAibGVmdCIpDQpmb3JtYXQoYygiQSIsICJCQiIsICJDQ0MiKSwgd2lkdGggPSA1LCBqdXN0aWZ5ID0gInJpZ2h0IikNCmZvcm1hdChjKCJBIiwgIkJCIiwgIkNDQyIpLCB3aWR0aCA9IDUsIGp1c3RpZnkgPSAibm9uZSIpDQoNCmxpYnJhcnkoc3RyaW5ncikNCnN0cl9wYWQoImhvbGEiLCB3aWR0aCA9IDcpDQpzdHJfcGFkKCJhZGlvcyIsIHdpZHRoID0gNywgc2lkZSA9ICJib3RoIikNCnN0cl9wYWQoImhhc2h0YWciLCB3aWR0aCA9IDgsIHBhZCA9ICIjIikNCnN0cl9wYWQoImhhc2h0YWciLCB3aWR0aCA9IDksIHNpZGUgPSAiYm90aCIsIHBhZCA9ICItIikNCg0KDQojIyMjIyBlZGl0YWNlIGNpc2VsbnljaCByZXRlemN1DQoNCiMjIHNwcmludGYNCg0KIyAnJWYnIGluZGljYXRlcyAnZml4ZWQgcG9pbnQnIGRlY2ltYWwgbm90YXRpb24NCnNwcmludGYoIiVmIiwgcGkpDQpzcHJpbnRmKCIlZiIsIDEyMy40NSkNCnNwcmludGYoIiVmIiwgMTIzLjQ1Njc4OSkNCiMgZGVjaW1hbCBub3RhdGlvbiB3aXRoIDMgZGVjaW1hbCBkaWdpdHMNCnNwcmludGYoIiUuM2YiLCBwaSkNCnNwcmludGYoIiUuM2YiLCAxMjMuNDU2Nzg5KQ0KIyAxIGludGVnZXIgYW5kIDAgZGVjaW1hbCBkaWdpdHMNCnNwcmludGYoIiUxLjBmIiwgcGkpDQpzcHJpbnRmKCIlMS4wZiIsIDEyMy40NTY3ODkpDQojIGRlY2ltYWwgbm90YXRpb24gd2l0aCAzIGRlY2ltYWwgZGlnaXRzDQpzcHJpbnRmKCIlNS4xZiIsIHBpKQ0Kc3ByaW50ZigiJTA1LjFmIiwgcGkpDQpzcHJpbnRmKCIlNi4xZiIsIDEyMy40NTY3ODkpDQpzcHJpbnRmKCIlMDYuMWYiLCAxMjMuNDU2Nzg5KQ0KIyBwcmludCB3aXRoIHNpZ24gKHBvc2l0aXZlKQ0Kc3ByaW50ZigiJStmIiwgcGkpDQpzcHJpbnRmKCIlK2YiLCAxMjMuNDU2Nzg5KQ0KIyBwcmVmaXggYSBzcGFjZQ0Kc3ByaW50ZigiJSBmIiwgcGkpDQpzcHJpbnRmKCIlIGYiLCAxMjMuNDU2Nzg5KQ0KIyBsZWZ0IGFkanVzdG1lbnQNCnNwcmludGYoIiUtMTBmIiwgcGkpDQpzcHJpbnRmKCIlLTEwZiIsIDEyMy40NTYpDQojIGV4cG9uZW50aWFsIGRlY2ltYWwgbm90YXRpb24gJ2UnDQpzcHJpbnRmKCIlZSIsIHBpKQ0Kc3ByaW50ZigiJWUiLCAxMjMuNDU2Nzg5KQ0KIyBleHBvbmVudGlhbCBkZWNpbWFsIG5vdGF0aW9uICdFJw0Kc3ByaW50ZigiJUUiLCBwaSkNCnNwcmludGYoIiVFIiwgMTIzLjQ1Njc4OSkNCiMgbnVtYmVyIG9mIHNpZ25pZmljYW50IGRpZ2l0cyAoNiBieSBkZWZhdWx0KQ0Kc3ByaW50ZigiJWciLCBwaSkNCnNwcmludGYoIiVnIiwgMTIzLjQ1Njc4OSkNCg0KDQojIyBmb3JtYXQNCg0KZm9ybWF0KHBpKQ0KZm9ybWF0KDEyMy40NSkNCmZvcm1hdCgxMjMuNDU2Nzg5KQ0KDQpmb3JtYXQoMTIzLjQ1LCBuc21hbGwgPSA1KQ0KZm9ybWF0KDEyLjM0NTY3ODksIG5zbWFsbD0yKQ0KZm9ybWF0KDEyLjM0NTY3ODksIG5zbWFsbD03KQ0KZm9ybWF0KDEyLjMsIG5zbWFsbD0zKQ0KDQpmb3JtYXQoMTIuMzQ1Njc4OSwgZGlnaXRzPTIpDQpmb3JtYXQoMTIuMzQ1Njc4OSwgZGlnaXRzPTUpDQpmb3JtYXQoYyg2LCAxMy4xKSwgZGlnaXRzID0gMikNCg0KZm9ybWF0KDEyLjM0NTY3ODksIGRpZ2l0cz01LCBuc21hbGwgPSA2KQ0KZm9ybWF0KGMoNiwgMTMuMSksIGRpZ2l0cyA9IDIsIG5zbWFsbCA9IDIpDQoNCmZvcm1hdCgxLzE6NSwgZGlnaXRzID0gMikNCmZvcm1hdChmb3JtYXQoMS8xOjUsIGRpZ2l0cyA9IDIpLCB3aWR0aCA9IDYsIGp1c3RpZnkgPSAiY2VudHJlIikNCg0KDQpmb3JtYXQoMTIzNDU2NzgsIGJpZy5tYXJrID0gIiwiKSAjIG9kZGVsZW5pIHRpc2ljdQ0KZm9ybWF0KDEyMzAsIGJpZy5tYXJrID0gIiwiKQ0KDQoNCiMjIHV2b3pvdmt5IHZlIHZ5cGlzdSByZXRlemNlDQoNCm15X3N0cmluZyA9ICJwcm9ncmFtbWluZyB3aXRoIGRhdGEgaXMgZnVuIg0KcHJpbnQobXlfc3RyaW5nKQ0KcHJpbnQobXlfc3RyaW5nLCBxdW90ZSA9IEZBTFNFKQ0KDQpub3F1b3RlKG15X3N0cmluZykNCg0Kbm9fcXVvdGVzID0gbm9xdW90ZShjKCJzb21lIiwgInF1b3RlZCIsICJ0ZXh0IiwgIiElXigmPSIpKQ0Kbm9fcXVvdGVzDQpub19xdW90ZXNbMjozXQ0KDQpub3F1b3RlKHBhc3RlKCJJIiwgImxvdmUiLCAiUiIsIHNlcCA9ICItIikpDQpub3F1b3RlKGNhdCgiVGhlIHZhbHVlIG9mIHBpIGlzIiwgcm91bmQocGksMyksICJhbmQgdmFsdWUgb2YgZSBpcyIsIHJvdW5kKGV4cCgxKSwzKSwiLiIpDQopDQoNCg0KZFF1b3RlKG15X3N0cmluZykNCnNRdW90ZShteV9zdHJpbmcpDQoNCnggPC0gIjIwMjAtMDUtMjkgMTk6MTg6MDUiDQpkUXVvdGUoeCkNCnNRdW90ZSh4KQ0KDQoNCiMjIyMjIyMjDQoNCnN1YnN0cihtb250aC5uYW1lLCAxLCAzKQ0KDQpzdWJzdHJpbmcobW9udGgubmFtZSwgMSwgMykNCg0Kc3RydHJpbShtb250aC5uYW1lLCAzKQ0KDQoNCnJzIDwtICgiVGhpcyBpcyBGaXJzdCBSIFN0cmluZyBFeGFtcGxlIikNCnN0cnNwbGl0KHJzLCBzcGxpdCA9ICIgIikNCg0KcnMgPC0gKCJUaGlzJmlzJkZpcnN0JlImU3RyaW5nJkV4YW1wbGUiKQ0Kc3Ryc3BsaXQocnMsIHNwbGl0ID0gIiYiKQ0KDQphIDwtICJBbGFiYW1hLUFsYXNrYS1Bcml6b25hLUFya2Fuc2FzLUNhbGlmb3JuaWEiDQpzdHJzcGxpdChhLCBzcGxpdCA9ICItIikNCg0Kc3RyID0gIlNwbGl0dGluZyBzZW50ZW5jZSBpbnRvIHdvcmRzIg0Kc3Ryc3BsaXQoc3RyLCAiICIpDQp1bmxpc3Qoc3Ryc3BsaXQoc3RyLCAiICIpKQ0KDQoNCnJzIDwtICgiQzIxSDIyTjJPMiIpICMgc3RyeWNobmluDQoNCnN0cnNwbGl0KHJzLCBzcGxpdCA9ICJbMC05XSsiKVtbMV1dDQoNCnN0cnNwbGl0KHJzLCBzcGxpdCA9ICJbQS1aXSsiKVtbMV1dWy0xXQ0Kc3Ryc3BsaXQocnMsICJcXEQrIilbWzFdXVstMV0NCnJlZ21hdGNoZXMocnMsIGdyZWdleHByKCJbWzpkaWdpdDpdXSsiLCBycykpDQpsaWJyYXJ5KHN0cmluZ3IpDQpzdHJfZXh0cmFjdF9hbGwocnMsIlswLTldKyIpW1sxXV0NCmxpYnJhcnkoc3RyZXgpDQpzdHJfZXh0cmFjdF9udW1iZXJzKHJzLGRlY2ltYWxzID0gRkFMU0UpDQoNCnJzIDwtICgiQzIxSDIyTjJPMiIpDQpzdHJzcGxpdChycywgc3BsaXQgPSAiIikNCg0Kc3RyaW5nX2RhdGU8LWMoIjItMDctMjAyMCIsIjUtMDctMjAyMCIsIjYtMDctMjAyMCIsDQogICAgICAgICAgICAgICAiNy0wNy0yMDIwIiwiOC0wNy0yMDIwIikNCnNzcCA9IHN0cnNwbGl0KHN0cmluZ19kYXRlLHNwbGl0ID0gIi0iKTsgc3NwDQoNCg0KIyBleHRyYWN0ICdiY2QnDQpzdWJzdHIoImFiY2RlZiIsIHN0YXJ0PTIsIHN0b3A9NCkNCg0Kc3Vic3RyaW5nKCJBQkNERUYiLCAyLCA0KQ0KDQojIGV4dHJhY3QgZWFjaCBsZXR0ZXINCnN1YnN0cmluZygiQUJDREVGIiwgMTo2LCAxOjYpDQoNCg0KbGlicmFyeShzdHJpbmdyKQ0KbG9yZW0gPSAiTG9yZW0gSXBzdW0iDQpzdWJzdHJpbmcobG9yZW0sIGZpcnN0ID0gMSwgbGFzdCA9IDUpDQpzdHJfc3ViKGxvcmVtLCBzdGFydCA9IDEsIGVuZCA9IDUpDQoNCnN0cl9zdWIoImFkaW9zIiwgMTozKQ0KDQpyZXN0byA9IGMoImJyYXNzZXJpZSIsICJiaXN0cm90IiwgImNyZXBlcmllIiwgImJvdWNob24iKQ0Kc3Vic3RyaW5nKHJlc3RvLCBmaXJzdCA9IC00LCBsYXN0ID0gLTEpDQpzdHJfc3ViKHJlc3RvLCBzdGFydCA9IC00LCBlbmQgPSAtMSkNCg0Kc3RyX3N1Yihsb3JlbSwgc2VxX2xlbihuY2hhcihsb3JlbSkpKQ0Kc3Vic3RyaW5nKGxvcmVtLCBzZXFfbGVuKG5jaGFyKGxvcmVtKSkpDQoNCnN0cl9zdWIobG9yZW0sLTIpIA0KDQoNCiMjIyBvcmV6YW5pIG1lemVyIG5hIGtvbmNpY2ggcmV0ZXpjZQ0KDQp0cmltd3MoIiBUaGlzIGhhcyB0cmFpbGluZyBzcGFjZXMuICAiKQ0KDQpiYWRfdGV4dCA9IGMoIlRoaXMiLCAiIGV4YW1wbGUgIiwgImhhcyBzZXZlcmFsICAgIiwgIiAgIHdoaXRlc3BhY2VzICIpDQp0cmltd3MoYmFkX3RleHQpDQpsaWJyYXJ5KHN0cmluZ3IpDQpzdHJfdHJpbShiYWRfdGV4dCwgc2lkZSA9ICJsZWZ0IikNCnN0cl90cmltKGJhZF90ZXh0LCBzaWRlID0gInJpZ2h0IikNCnN0cl90cmltKGJhZF90ZXh0LCBzaWRlID0gImJvdGgiKQ0KDQoNCiMjIHJlcGxhY2UNCmNoYXJ0cihvbGQgPSAiQWxsIiwgbmV3ID0gImFMTCIsICJBbGwgQ2hhUmFjdGVyUyBpbiBVcHBlciBDYXNlIikgDQpjaGFydHIoImEiLCAiQSIsICJUaGlzIGlzIGEgYm9yaW5nIHN0cmluZyIpDQpjaGFydHIoImEiLCAiMCIsICJUaGlzIGlzIGEgYmFkIGV4YW1wbGUiKQ0KDQpjcmF6eSA9IGMoIkhlcmUncyB0byB0aGUgY3Jhenkgb25lcyIsICJUaGUgbWlzZml0cyIsICJUaGUgcmViZWxzIikNCmNoYXJ0cigiYWVpIiwgIiMhPyIsIGNyYXp5KQ0KDQoNCnggPSBjKCJtYXkiLCAidGhlIiwgImZvcmNlIiwgImJlIiwgIndpdGgiLCAieW91IikNCnN1YnN0cih4LCAyLCAyKSA8LSAiIyINCngNCnkgPSBjKCJtYXkiLCAidGhlIiwgImZvcmNlIiwgImJlIiwgIndpdGgiLCAieW91IikNCnN1YnN0cih5LCAyLCAzKSA8LSAiOikiDQp5DQoNCnogPSBjKCJtYXkiLCAidGhlIiwgImZvcmNlIiwgImJlIiwgIndpdGgiLCAieW91IikNCnN1YnN0cih6LCAyLCAzKSA8LSBjKCIjIiwgIkAiKQ0Keg0KDQp0ZXh0ID0gYygibW9yZSIsICJlbW90aW9ucyIsICJhcmUiLCAiYmV0dGVyIiwgInRoYW4iLCAibGVzcyIpDQpzdWJzdHJpbmcodGV4dCwgMTozKSA8LSBjKCIgIiwgInp6eiIpDQp0ZXh0DQoNCg0KbGlicmFyeShzdHJpbmdyKQ0KbG9yZW0gPSAiTG9yZW0gSXBzdW0iDQpzdHJfc3ViKGxvcmVtLCAtMSkgPC0gIk51bGxhbSINCmxvcmVtDQoNCmxvcmVtID0gIkxvcmVtIElwc3VtIg0Kc3RyX3N1Yihsb3JlbSwgMSwgNSkgPC0gIk51bGxhbSINCmxvcmVtDQoNCmxvcmVtID0gIkxvcmVtIElwc3VtIg0Kc3RyX3N1Yihsb3JlbSwgYygxLCA3KSwgYyg1LCA4KSkgPC0gYygiTnVsbGFtIiwgIkVuaW0iKQ0KbG9yZW0NCg0KDQojIyB0byBsb3dlciBjYXNlDQp0b2xvd2VyKCJCYUNyTzQiKQ0KdG9sb3dlcihjKCJhTEwgQ2hhUmFjdGVyUyBpbiBMb3dlUiBjYVNlIiwgIkFCQ0RFIikpDQpjYXNlZm9sZCgiYUxMIENoYVJhY3RlclMgaW4gTG93ZVIgY2FTZSIpDQoNCiMjIHRvIHVwcGVyIGNhc2UNCnRvdXBwZXIoIkJhQ3JPNCIpDQp0b3VwcGVyKGMoIkFsbCBDaGFSYWN0ZXJTIGluIFVwcGVyIENhc2UiLCAiYWJjZGUiKSkNCmNhc2Vmb2xkKCJBbGwgQ2hhUmFjdGVyUyBpbiBVcHBlciBDYXNlIiwgdXBwZXIgPSBUUlVFKQ0KDQoNCiMjIyBmaWx0cm92YW5pDQoNCnN0YXJ0c1dpdGgobW9udGgubmFtZSwgIkoiKQ0KZW5kc1dpdGgobW9udGgubmFtZSwgImVtYmVyIikNCg0KbXlTdHJpbmdzIDwtIHBhc3RlKDE6MywgbW9udGgubmFtZSwgc2VwID0gIi4gIikNCm15U3RyaW5ncw0KIyBJcyBhIHBhdHRlcm4gcHJlc2VudCAocmV0dXJucyBhIGxvZ2ljYWwgdmVjdG9yKT8NCmdyZXBsKCJlbWJlciIsIG15U3RyaW5ncykNCiMgSW4gd2hpY2ggZWxlbWVudHMgaXMgYSBwYXR0ZXJuIHByZXNlbnQgKHJldHVybnMgaW5kaWNlcyk/DQpncmVwKCJlbWJlciIsIG15U3RyaW5ncykNCiMgSW4gd2hpY2ggZWxlbWVudHMgaXMgYSBwYXR0ZXJuIHByZXNlbnQgKHJldHVybnMgdGhlIHZhbHVlcyk/DQpncmVwKCJlbWJlciIsIG15U3RyaW5ncywgdmFsdWUgPSBUUlVFKQ0KDQp4MTwtYygiUiBpcyBhIHByb2dyYW1taW5nIGxhbmd1YWdlIGFuZCBwcm9ncmFtbWluZyBzb2Z0d2FyZSBlbnZpcm9ubWVudCIsDQogICAgICAiUiBpcyBmcmVlbHkgYXZhaWxhYmxlIHVuZGVyIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSIsDQogICAgICAiVGhpcyBwcm9ncmFtbWluZyBsYW5ndWFnZSB3YXMgbmFtZWQgUiIpDQpncmVwKCJwcm9ncmFtbWluZyIseDEsZml4ZWQ9VFJVRSkNCg0KDQojIFNyb3ZuYW5pIDIgcmV0ZXpjdQ0KbWVzc2FnZTEgPC0gIlBybyINCm1lc3NhZ2UyIDwtICJQcm8iDQptZXNzYWdlMyA8LSAicFJPIg0KbWVzc2FnZTEgPT0gbWVzc2FnZTINCm1lc3NhZ2UxID09IG1lc3NhZ2UzDQoNCiMgSGxlZGFuaSByZXRlemNlIHYgamluZW0gcmV0ZXpjaQ0Kc3RyIDwtICJIZWxsbyBXb3JsZCEiDQpncmVwbCgiSCIsIHN0cikNCmdyZXBsKCJIZWxsbyIsIHN0cikNCmdyZXBsKCJYIiwgc3RyKQ0KZ3JlcGwobWVzc2FnZTEsIG1lc3NhZ2UyKQ0KZ3JlcGwobWVzc2FnZTEsIG1lc3NhZ2UzKQ0KDQppZGVudGljYWwobWVzc2FnZTEsIG1lc3NhZ2UyKQ0KaWRlbnRpY2FsKG1lc3NhZ2UxLCBtZXNzYWdlMykNCmlkZW50aWNhbCh0b2xvd2VyKG1lc3NhZ2UxKSwgdG9sb3dlcihtZXNzYWdlMykpDQoNCm1lc3NhZ2UxW21lc3NhZ2UxICVpbiUgbWVzc2FnZTJdDQptZXNzYWdlMVttZXNzYWdlMSAlaW4lIG1lc3NhZ2UzXSAgDQptZXNzYWdlMVt0b2xvd2VyKG1lc3NhZ2UxKSAlaW4lIHRvbG93ZXIobWVzc2FnZTMpXSANCg0KdmVjdG9yMSA8LSBjKCJoZXkiLCAiaGVsbG8iLCAiZ3JlZXRpbmdzIikNCnZlY3RvcjIgPC0gYygiaGV5IiwgImhlbGxvIiwgImhpIikNCnZlY3RvcjFbdmVjdG9yMSAlaW4lIHZlY3RvcjJdDQoNCg0KIyMjDQoNCmxpYnJhcnkoc3RyaW5ncikNCg0KY2hhbmdlID0gYygiQmUgdGhlIGNoYW5nZSIsICJ5b3Ugd2FudCB0byBiZSIpDQojIGV4dHJhY3QgZmlyc3Qgd29yZA0Kd29yZChjaGFuZ2UsIDEpDQojIGV4dHJhY3Qgc2Vjb25kIHdvcmQNCndvcmQoY2hhbmdlLCAyKQ0KIyBleHRyYWN0IGxhc3Qgd29yZA0Kd29yZChjaGFuZ2UsIC0xKQ0KIyBleHRyYWN0IGFsbCBidXQgdGhlIGZpcnN0IHdvcmRzDQp3b3JkKGNoYW5nZSwgMiwgLTEpDQoNCndvcmQoY2hhbmdlLHN0YXJ0PTEsZW5kPTIsc2VwPWZpeGVkKCIgIikpDQoNCg0KZGF0YSA8LSAgYygnQWJfQ2QtMDAxMjM0LnR4dCcsJ0FiX0NkLTAwMTIzNC50eHQnKQ0KDQpnc3ViKCcuKi0oWzAtOV0rKS4qJywnXFwxJywnQWJfQ2QtMDAxMjM0LnR4dCcpDQp4IDwtIGMoJ0FiX0NkLTAwMTIzNC50eHQnLCdBYl9DZC0wMDEyMzQudHh0JykNCnN1YignLiotKFswLTldKykuKicsJ1xcMScseCkNCg0KbGlicmFyeShzdHJpbmdyKQ0KcmVnZXhwIDwtICJbWzpkaWdpdDpdXSsiDQpzdHJfZXh0cmFjdChkYXRhLCByZWdleHApDQoNCmxpYnJhcnkocWRhcCkNCmdlblh0cmFjdCgiQWJfQ2QtMDAxMjM0LnR4dCIsICItIiwgIi50eHQiKQ0KeCA8LSBjKCdBYl9DZC0wMDEyMzQudHh0JywnQWJfQ2QtMDAxMjM0LnR4dCcpDQpnZW5YdHJhY3QoeCwgIi0iLCAiLnR4dCIpDQoNCmxpYnJhcnkodG9vbHMpDQpzdWIoIi4qLSIsICIiLCBmaWxlX3BhdGhfc2Fuc19leHQoeCkpDQoNCmxpYnJhcnkoZ3N1YmZuKQ0Kc3RyYXBwbHljKHgsICItKFxcZCspXFwuIiwgc2ltcGxpZnkgPSBUUlVFKQ0Kc3RyYXBwbHkoeCwgIi0oXFxkKylcXC4iLCBhcy5udW1lcmljLCBzaW1wbGlmeSA9IFRSVUUpDQoNCg0KeCA8LSBjKCJhIHZlcnkgbmljZSBjaGFyYWN0ZXIgc3RyaW5nIikgIA0KbGlicmFyeShzdHJpbmdyKQ0Kc3RyX3JlcGxhY2UoeCwgImMiLCAieHh4IikNCnN0cl9yZXBsYWNlX2FsbCh4LCAiYyIsICJ4eHgiKQ0KDQp4IDwtICJhYWFiYmIiIA0Kc3ViKCJhIiwgImMiLCB4KSAgDQpnc3ViKCJhIiwgImMiLCB4KQ0Kc3ViKCJhfGIiLCAiYyIsIHgpDQpnc3ViKCJhfGIiLCAiYyIsIHgpICANCg0KeCA8LSBjKCJkIiwgImEiLCAiYyIsICJhYmJhIikgDQpncmVwKCJhIiwgeCkNCmdyZXBsKCJhIiwgeCkNCmdyZXAoImF8YyIsIHgpDQpncmVwbCgiYXxjIiwgeCkNCg0KcmVnZXhwcigiYSIsIHgpDQpncmVnZXhwcigiYSIsIHgpDQpyZWdleGVjKCJhIiwgeCkgDQoNCnggPC0gImV4YW1wbGVfeHh4X3N0cmluZyINCmxpYnJhcnkoc3RyaW5ncikNCnN0cl9zdWIoc3RyaW5nID0geCwgc3RhcnQgPSA4LCBlbmQgPSAxMikNCnN0cl9zdWIoc3RyaW5nID0geCwgc3RhcnQgPSA4LCBlbmQgPSAxMikgPC0gIiBjaGFyYWN0ZXIgIiAgIyBSZXBsYWNlIHN1YnN0cmluZw0KeCAgDQoNCnggPC0gInh4eHh5eHh5eGFhYWFhYXkiDQp4IA0Kc3ViKCJ5IiwgIk5FVyIsIHgpIA0KZ3N1YigieSIsICJORVciLCB4KQ0KDQpsaWJyYXJ5KHN0cmluZ3IpDQpzdHJfcmVwbGFjZSh4LCAieSIsICJORVciKQ0Kc3RyX3JlcGxhY2VfYWxsKHgsICJ5IiwgIk5FVyIpDQoNCmBgYA0KDQoNCkt2YWRyYXRpY2tlIGEga3ViaWNrZSByb3ZuaWNlDQoNCg0KVmVsaWtvc3QgdsO9c2xlZG5pY2UgZHZvdSBuYXZ6YWplbSBrb2xtw71jaCBzaWwgamUgMzQgTi4gSmFrw6EgamUgdmVsaWtvc3Qgc2tsw6FkYW7DvWNoIHNpbCwgamUtbGkgamVkbmEgeiBuaWNoIG8gMTQgTiB2xJt0xaHDrSBuZcW+IGRydWhhPw0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQojIFB5dGhhZ29yb3ZhIHZldGE6IHheMiArICh4ICsgMTQpXjIgPSAzNF4yICAgICAgDQpsaWJyYXJ5KFJ5YWNhcykNCmVxIDwtICJ4XjIgKyAoeCArIDE0KV4yIC0gMzReMiIgDQp5YWNfc3RyKHBhc3RlMCgiU2ltcGxpZnkoIiwgZXEsICIpIikpICAjIHpqZWRub2R1c2Vuw60gdsO9cmF6dQ0KDQojIGRpc2tyaW1pbmFudA0KZGMgPSBjKDEsMTQsLTQ4MCkNCkQgPSBkY1syXV4yIC0gNCpkY1sxXSpkY1szXQ0KaWYgKEQgPT0gMCkge2NhdCgiS3ZhZHJhdGlja2Egcm92bmljZSBtYSBkdmEgc29iZSByb3ZuZSByZWFsbmUga29yZW55IChkdm9qbmFzb2JueSBrb3JlbikuIil9DQppZiAoRCA+IDApIHtjYXQoIkt2YWRyYXRpY2thIHJvdm5pY2UgbWEgZHZhIHJ1em5lIHJlYWxuZSBrb3JlbnkuIil9DQppZiAoRCA8IDApIHtjYXQoIkt2YWRyYXRpY2thIHJvdm5pY2UgbmVtYSB6YWRueSBrb3JlbiB2IG9ib3J1IHJlYWxueWNoIGNpc2VsLiBWIG9ib3J1IGtvbXBsZXhuaWNoIGNpc2VsIG1hIGR2YSBpbWFnaW5hcm5pIGtvbXBsZXhuZSBzZHJ1emVuZSBrb3JlbnkuIil9DQoNCiMgRGVzY2FydGVzIHJ1bGUNCnN1bShkaWZmKHNpZ24oZGMpKSAhPSAwKQ0KY2F0KCJQb2NldCBrbGFkbnljaCBrb3JlbnU6Iiwgc3VtKGRpZmYoc2lnbihkYykpICE9IDApKSAjIHBvY2V0IGtsYWRueWNoIGtvcmVudQ0KDQpsaWJyYXJ5KHNmc21pc2MpDQpuci5zaWduLmNoZyhkYykNCmNhdCgiUG9jZXQga2xhZG55Y2gga29yZW51OiIsIG5yLnNpZ24uY2hnKGRjKSkgIyBwb2NldCBrbGFkbnljaCBrb3JlbnUNCg0KIyBIb3JuZXJvdm8gc2NoZW1hDQpsaWJyYXJ5KHNmc21pc2MpDQpwb2x5bi5ldmFsKGRjLCB4KQ0KDQoNCmZ1biA8LSBmdW5jdGlvbiAoeCkge3heMiArICh4ICsgMTQpXjIgLSAzNF4yfQ0KdW5pcm9vdChmdW4sIGMoLTEsIDApLGV4dGVuZEludCA9ICJ5ZXMiLCB0b2wgPSAxZS05KSAgIyBiYXNlDQp1bmlyb290KGZ1biwgYygwLCAxKSxleHRlbmRJbnQgPSAieWVzIiwgdG9sID0gMWUtOSkNCiMgdW5pcm9vdChmdW4sIGMoLTEsIDEpLGV4dGVuZEludCA9ICJ5ZXMiLCB0b2wgPSAxZS05KQ0KRjEgPC0gdW5pcm9vdChmdW4sIGMoMCwgMTAwKSxleHRlbmRJbnQgPSAieWVzIiwgdG9sID0gMWUtOSkgDQpGMSRyb290DQoNCmZ1biA8LSBmdW5jdGlvbih4KXt4XjIgKyAxNCp4IC0gNDgwfQ0KdW5pcm9vdChmdW4sIGMoLTEsIDApLGV4dGVuZEludCA9ICJ5ZXMiLCB0b2wgPSAxZS05KSAgIyBiYXNlDQp1bmlyb290KGZ1biwgYygwLCAxKSxleHRlbmRJbnQgPSAieWVzIiwgdG9sID0gMWUtOSkNCkYxIDwtIHVuaXJvb3QoZnVuLCBjKDAsIDEwMCksZXh0ZW5kSW50ID0gInllcyIsIHRvbCA9IDFlLTkpDQpGMSRyb290IA0KDQoNCnJyID0gcG9seXJvb3QoYygtNDgwLCAxNCwgMSkpICMgYmFzZQ0KUmUocnIpDQoNCg0KbGlicmFyeShwcmFjbWEpDQpyciA9IHJvb3RzKGMoMSwgMTQsIC00ODApKQ0KcnINCkYxID0gcnJbcnI+PTBdDQpGMQ0KRjIgPSBycltycjw9MF0NCkYyDQoNCiMgVmlldG92eSB2em9yY2UNCnVuaXJvb3QoZnVuLCBjKC0xLCAwKSxleHRlbmRJbnQgPSAieWVzIiwgdG9sID0gMWUtOSkkcm9vdA0KKC1kY1syXS9kY1sxXSkgLSBGMQ0KKGRjWzNdL2RjWzFdKS9GMQ0KDQojIGtvZWZpY2llbnR5IGt2YWRyYXRpY2tlIHJvdm5pY2UgeiBrb3JlbnUNCmxpYnJhcnkocHJhY21hKQ0KUG9seShjKDE2LCAtMzApKQ0KDQoNCiMjIGdyYWZpY2tlIHJlc2VuaQ0KeHggPSBzZXEoLTUwLDUwLDEpDQp5eSA9IGFicyh4eF4yICsgKHh4ICsgMTQpXjIgLSAzNF4yKQ0KcGxvdCh4eCx5eSx0eXBlPSJsIikNCmFibGluZShoPTAsY29sPTIpDQp4eFt3aGljaCh5eT09MCldDQp4eFt5eT09MF0NCg0KIyMgZ3JhZmlja2UgcmVzZW5pDQp4eCA9IHNlcSgtNTAsNTAsMSkNCnl5ID0geHheMg0KenogPSAtMTQqeHggKyA0ODANCnBsb3QoeHgseXksdHlwZT0ibCIpDQphYmxpbmUoNDgwLC0xNCxjb2w9MikNCg0KcGxvdCh4eCx5eSx0eXBlPSJsIix4bGltID0gYygxMCwyMCkseWxpbT1jKDAsNTAwKSkNCmFibGluZSg0ODAsLTE0LGNvbD0yKQ0KDQoNCmBgYA0KDQoNClRsYWtvdsOhIGzDoWhldiBzIG94aWRlbSB1aGxpxI1pdMO9bSBvYnNhaHVqZSAxMC4wIGtnIHBseW51LiBKYWvDvSBvYmplbSB6YXVqw61tw6Egc3RsYcSNZW7DvSBwbHluLCBrZHnFviBwxZlpIHRlcGxvdMSbIDMwIMKwQyBqZSB0bGFrIHYgbMOhaHZpIDEzLjE3ZS02IFBhPyBWw71wb8SNZXQgcHJvdmVkJ3RlIHBvbW9jw60gdmFuIGRlciBXYWFsc292eSByb3ZuaWNlLg0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQojIChwICsgYS9WbV4yKShWbSAtIGIpID0gUipUICAgICANCiMgW1ZtID0gMC4wNzUgbTMva21vbCwgbiA9IDAuMjI3MyBrbW9sLCBWID0gMC4wMTcxIG0zXQ0KDQpsaWJyYXJ5KG1lYXN1cmVtZW50cykNCnAgPSAxMy4xN2U2ICMgW1BhXQ0KbSA9IGNvbnZfdW5pdCgxMC4wLCBmcm9tPSJrZyIsIHRvPSJnIikNCnQgPSBjb252X3VuaXQoMzAsIGZyb209IkMiLCB0bz0iSyIpIA0KUiA9IDguMzE0MSAgIyBbSiAvIG1vbCBLXQ0KUiA9IFIqMTAwMCAgIyBbSiAvIGttb2wgS10NCk1yID0gNDQuMDEgICMgW2cvbW9sXQ0KbiA9IG0vTXIgICAgIyBbbW9sXQ0KbiA9IG4vMTAwICAgIyBba21vbF0NCg0KIyB2eXBvY2V0IHBybyBpZGVhbG5pIHBseW4NCiMgcCpWbSAtIFIqVCA9IDAgIA0KVm0gPSBSKnQvcA0KViA9IFZtKm47IFYgICMgW20zXQ0KDQojIHZ5cG9jZXQgcHJvIHJlYWxueSBwbHluDQphID0gMC4zNjVlNiAjIFttNiBQYSAvIGttb2wyXQ0KYiA9IDAuMDQyOCAgIyBbbTMgLyBrbW9sXQ0KIyBWbSoqMyAtIChiICsgUip0L3ApKlZtKioyICsgKGEvcCkqVm0gLSBhKmIvcCANCg0KIyByZWFsbmUgaSBrb21wbGV4bmkga29yZW55DQpsaWJyYXJ5KFJDb25pY3MpIA0KQ0UgPSBjKDEsLShiICsgUip0L3ApLGEvcCwtKGEqYi9wKSkNCngwID0gY3ViaWMoQ0UpOyB4MA0KVm0gPSBSZSh4MFt3aGljaChJbSh4MCk9PTApXSkgICMgW20zIC8ga21vbF0NClZtDQpWID0gVm0qbjsgViAgIyBbbTNdDQoNCiMgamVuIHJlYWxuZSBrb3JlbnkNCmZ1biA8LSBmdW5jdGlvbiAoeCkgQ0VbMV0qeF4zICsgQ0VbMl0qeF4yICsgQ0VbM10qeCArIENFWzRdDQojY3VydmUoZnVuKHgpLC00LDQpDQojYWJsaW5lKGggPSAwLCBsdHkgPSAzKQ0KVm0gPC0gdW5pcm9vdChmdW4sIGMoLTQsIDQpKSRyb290ICAjIGJhc2UNClYgPSBWbSpuOyBWICAjIFttM10NCg0KbGlicmFyeShyb290U29sdmUpDQpWbSA8LSByb290U29sdmU6OnVuaXJvb3QuYWxsKGZ1biwgYygtNCwgNCkpDQpWID0gVm0qbjsgViAgIyBbbTNdDQoNCmxpYnJhcnkoUm1wZnIpDQpWbSA8LSBSbXBmcjo6dW5pcm9vdFIoZnVuLCBsb3dlcj0tNCwgdXBwZXI9NCwgdG9sID0gMWUtOSkkcm9vdA0KViA9IFZtKm47IFYgICMgW20zXQ0KDQojIyBncmFmaWNrZSByZXNlbmkNCiMgQ0UgPSBjKDEsLShiICsgUip0L3ApLGEvcCwtKGEqYi9wKSkNCnh4IDwtIHNlcSgtNCw0LCBieT0wLjAxKQ0KeXkgPC0gQ0VbMV0qeHheMyANCnp6IDwtIC1DRVsyXSp4eF4yIC0gQ0VbM10qeHggLSBDRVs0XQ0KcGxvdCh4eCx5eSx0eXBlPSJsIiwgY29sPTIpDQpwb2ludHMoeHgsenosdHlwZT0ibCIsIGNvbD00KQ0KcGxvdCh4eCwgeXksIHR5cGU9ImwiLGNvbD0yLHhsaW09YygwLjA1LDAuMSkseWxpbT1jKDAsMC4wMDEpKQ0KcG9pbnRzKHh4LCB6eiwgdHlwZT0ibCIsY29sPTQpDQoNCmBgYA0KDQoNCkpha2UgcEggbcOhIHJvenRvayBreXNlbGlueSBtcmF2ZW7EjcOtIG8ga29uY2VudHJhY2kgOC41IHggMTAtNCBtb2wvbD8NCg0KYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0KcEtBID0gMy43NTINCktBID0gMTBeLXBLQTsgS0ENCkt3ID0gMTBeLTE0DQpjQSA9IDguNWUtNCAjIFttb2wvbCBdIA0KDQoNCiMgSCA9IHNxcnQoS0EqY0EpDQpIIDwtIHNxcnQoS0EqY0EpDQpwSCA9IC1sb2cxMChIKTsgcEggDQoNCg0KIyBbSCtdXjIgKyBLQSpbSCtdICsgS0EqY0EgPSAwDQpDRSA9IGMoMSxLQSwtS0EqY0EpDQpmdW4gPC0gZnVuY3Rpb24gKHgpIENFWzFdKnheMiArIENFWzJdKnggKyBDRVszXQ0KdW5pcm9vdChmdW4sIGMoLTFlLTEsIDApLHRvbCA9IDFlLTkpDQp1bmlyb290KGZ1biwgYygwLCAxZS0xKSx0b2wgPSAxZS05KQ0KSCA8LSB1bmlyb290KGZ1biwgYygwLCAxZS0xKSx0b2wgPSAxZS05KSRyb290ICAjIGJhc2UNCnBIID0gLWxvZzEwKEgpOyBwSA0KDQpsaWJyYXJ5KHJvb3RTb2x2ZSkNCnJvb3RTb2x2ZTo6dW5pcm9vdC5hbGwoZnVuLCBjKC0xZS0xLCAwKSwgdG9sID0gMWUtOSkNCnJvb3RTb2x2ZTo6dW5pcm9vdC5hbGwoZnVuLCBjKDAsIDFlLTEpLCB0b2wgPSAxZS05KQ0KSCA8LSByb290U29sdmU6OnVuaXJvb3QuYWxsKGZ1biwgYygtMWUtMSwgMWUtMSksIHRvbCA9IDFlLTkpDQpwSCA9IC1sb2cxMChIKTsgcEggDQoNCmxpYnJhcnkoUm1wZnIpDQpSbXBmcjo6dW5pcm9vdFIoZnVuLCBsb3dlcj0tMWUtMSwgdXBwZXI9MCwgdG9sID0gMWUtOSkNClJtcGZyOjp1bmlyb290UihmdW4sIGxvd2VyPTAsIHVwcGVyPTFlLTEsIHRvbCA9IDFlLTkpDQpIIDwtIFJtcGZyOjp1bmlyb290UihmdW4sIGxvd2VyPTAsIHVwcGVyPTFlLTEsIHRvbCA9IDFlLTkpJHJvb3QNCnBIID0gLWxvZzEwKEgpOyBwSCANCg0KDQojIFtIK11eMyArIEtBKltIK11eMiAtIFtIK10qKEtBKmNBICsgS3cpIC0gS0EqS3cgPSAwDQpDRSA9IGMoMSxLQSwtKEtBKmNBICsgS3cpLC1LQSpLdykNCg0KbGlicmFyeShSQ29uaWNzKSANCngwID0gY3ViaWMoQ0UpOyB4MA0KSCA9IFJlKHgwW3doaWNoKEltKHgwKT09MCldKQ0KSCA9IFJlKHgwW3doaWNoKFJlKHgwKT49MCldKQ0KcEggPSAtbG9nMTAoSCk7IHBIIA0KDQoNCmZ1biA8LSBmdW5jdGlvbiAoeCkgQ0VbMV0qeF4zICsgQ0VbMl0qeF4yICsgQ0VbM10qeCArIENFWzRdDQp1bmlyb290KGZ1biwgYygtMWUtMSwwKSx0b2wgPSAxZS05KQ0KdW5pcm9vdChmdW4sIGMoMCwgMWUtMSksdG9sID0gMWUtOSkNCkggPC0gdW5pcm9vdChmdW4sIGMoMCwgMWUtMSksdG9sID0gMWUtOSkkcm9vdCAgIyBiYXNlDQpwSCA9IC1sb2cxMChIKTsgcEggDQoNCg0KbGlicmFyeShyb290U29sdmUpDQpyb290U29sdmU6OnVuaXJvb3QuYWxsKGZ1biwgYygtMWUtMSwgMCksdG9sID0gMWUtOSkNCnJvb3RTb2x2ZTo6dW5pcm9vdC5hbGwoZnVuLCBjKDAsMWUtMSksdG9sID0gMWUtOSkNCkggPC0gcm9vdFNvbHZlOjp1bmlyb290LmFsbChmdW4sIGMoLTFlLTEsIDFlLTEpLHRvbCA9IDFlLTkpDQpwSCA9IC1sb2cxMChIKTsgcEggDQoNCg0KbGlicmFyeShSbXBmcikNClJtcGZyOjp1bmlyb290UihmdW4sIGxvd2VyPS0xZS0xLCB1cHBlcj0wLCB0b2wgPSAxZS05KQ0KUm1wZnI6OnVuaXJvb3RSKGZ1biwgbG93ZXI9MCwgdXBwZXI9MWUtMSwgdG9sID0gMWUtOSkNCkggPC0gUm1wZnI6OnVuaXJvb3RSKGZ1biwgbG93ZXI9MCwgdXBwZXI9MWUtMSwgdG9sID0gMWUtOSkkcm9vdA0KcEggPSAtbG9nMTAoSCk7IHBIIA0KDQpgYGANCg0KDQoNClNvdXN0YXZ5IGxpbmXDoXJuw61jaCByb3ZuaWMNCg0KDQpaZSBkdm91IHNsaXRpbiBzIDYwJSBhIDgwJSBvYnNhaGVtIG3Em2RpIHNlIG1hIHrDrXNrYXQgNDAga2cgc2xpdGlueSBzZSA3NSUgb2JzYWhlbSBtxJtkaS4gS29saWsga2cga2HFvmTDqSBzbGl0aW55IGplIHTFmWViYSBwb3XFvsOtdD8gIFsxMCBhIDMwIGtnXQ0KDQpgYGB7cn0NCg0KbGlicmFyeShyb290U29sdmUpDQptb2RlbCA8LSBmdW5jdGlvbih4KXsNCiAgRjEgPC0gMC42KnhbMV0gKyAwLjgqeFsyXSAtIDMwDQogIEYyIDwtIHhbMV0gKyB4WzJdIC0gNDANCiAgYyhGMSA9IEYxLCBGMiA9IEYyKX0NCnNzIDwtIG11bHRpcm9vdChmID0gbW9kZWwsIHN0YXJ0ID0gYygxLCAxKSkNCnNzJHJvb3QNCg0KIyMjIGdyYWZpY2tlIHJlc2VuaQ0KIyAwLjYqbTEgKyAwLjgqbTIgPSA0MCowLjc1ID0+IG0xID0gNDAqMC43NS8wLjYgLSAwLjgvMC42ICogbTIgID0+IG0xID0gNTAgLSAxLjMzICogbTIgDQojIG0xICsgbTIgPSA0MCAgPT4gbTEgPSA0MCAtIG0yDQp4eCA9IHNlcSgwLDUwLDAuMSkNCnl5ID0gNTAgLSAxLjMzKnh4DQp6eiA9IDQwIC0geHgNCnBsb3QoeHgsIHl5LCB0eXBlPSJsIixjb2w9MikNCnBvaW50cyh4eCwgenosIHR5cGU9ImwiLGNvbD00KQ0KcGxvdCh4eCwgeXksIHR5cGU9ImwiLGNvbD0yLHhsaW09YygyNSwzNSkseWxpbT1jKDAsMjApKQ0KcG9pbnRzKHh4LCB6eiwgdHlwZT0ibCIsY29sPTQpDQoNCmBgYA0KDQoNCkRvIGJhemVudSBuYXRlY2UgcHJ1dG9rZW0gQSB6YSAzIGggYSBwcnV0b2tlbSBCIHphIDQgaCBjZWxrZW0gMjE1MCBobCB2b2R5LiBQcnV0b2tlbSBBIHphIDQgaCBhIHBydXRva2VtIEIgemEgMiBoIGJ5IG5hdGVrbG8gMTcwMCBobCB2b2R5LiBLb2xpayBobCB2b2R5IG5hdGVjZSBwcnV0b2tlbSBBIGEga29saWsgcHJ1dG9rZW0gQiB6YSAxIGhvZGludT8gICAgICBBIDI1MCBobCwgQiAzNTAgaGwNCg0KYGBge3J9DQoNCmxpYnJhcnkocm9vdFNvbHZlKQ0KbW9kZWwgPC0gZnVuY3Rpb24oeCl7DQogIEYxIDwtIDMqeFsxXSArIDQqeFsyXSAtIDIxNTANCiAgRjIgPC0gNCp4WzFdICsgMip4WzJdIC0gMTcwMA0KICBjKEYxID0gRjEsIEYyID0gRjIpfQ0Kc3MgPC0gbXVsdGlyb290KGYgPSBtb2RlbCwgc3RhcnQgPSBjKDEsIDEpKQ0Kc3Mkcm9vdA0KDQojIyMgZ3JhZmlja2UgcmVzZW5pDQojIDMqbTEgKyA0Km0yID0gMjE1MCA9PiBtMiA9IDIxNTAvNCAtIDMvNCAqIG0xICA9PiBtMiA9IDUzNy41IC0gMC43NSAqIG0xDQojIDQqbTEgKyAyKm0yID0gMTcwMCA9PiBtMiA9IDE3MDAvMiAtIDQvMiAqIG0xID0+IG0yID0gODUwIC0gMiAqIG0xDQp4eCA9IHNlcSgwLDUwMCwxKQ0KeXkgPSA1MzcuNSAtIDAuNzUqeHgNCnp6ID0gODUwIC0gMip4eA0KcGxvdCh4eCwgeXksIHR5cGU9ImwiLGNvbD0yKQ0KcG9pbnRzKHh4LCB6eiwgdHlwZT0ibCIsY29sPTQpDQpwbG90KHh4LCB5eSwgdHlwZT0ibCIsY29sPTIseGxpbT1jKDIwMCwzMDApLHlsaW09YygzMDAsNDAwKSkNCnBvaW50cyh4eCwgenosIHR5cGU9ImwiLGNvbD00KQ0KDQpgYGANCg0KDQoNCg0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQojIyMgc2thbGFybmkgc291Y2luIChpbm5lciBwcm9kdWN0LCBkb3QgcHJvZHVjdCwgc2NhbGFyIHByb2R1Y3QpDQoNCnUgPC0gcmVwKDMsMykNCnYgPC0gMTozDQp1JSoldiAjIHRoZSBpbm5lciBwcm9kdWN0DQpsaWJyYXJ5KHByYWNtYSkNCmRvdCh1LCB2KQ0KZG90KGMoMSwgMiwgMyksIGMoNCwgNSwgNikpDQoNCg0KIyMjIHZla3Rvcm92eSBzb3VjaW4gKG91dGVyIHByb2R1Y3QsIGNyb3NzIHByb2R1Y3QsIHZlY3RvciBwcm9kdWN0KQ0KDQp1IDwtIHJlcCgzLDMpDQp2IDwtIDE6Mw0KdSVvJXYgIyBUaGUgb3V0ZXIgcHJvZHVjdA0KbGlicmFyeShwcmFjbWEpDQpjcm9zcyh1LCB2KQ0KY3Jvc3MoYygxLCAyLCAzKSwgYyg0LCA1LCA2KSkgIA0KQSA8LSBtYXRyaXgoYygxLDAsMCwgMCwxLDApLCBucm93PTIsIG5jb2w9MywgYnlyb3c9VFJVRSkNCmNyb3NzbihBKSAgDQoNCg0KIyMjIEthcnRlenNreSBzb3VjaW4NCg0KZXhwYW5kLmdyaWQodSwgdikNCmV4cGFuZC5ncmlkKGMoMSwgMiwgMyksIGMoNCwgNSwgNikpDQpleHBhbmQuZ3JpZCh4PWMoImEiLCJiIiwiYyIpLHk9YygxLDIsMykpDQpsaWJyYXJ5KGRhdGEudGFibGUpDQpDSih1LCB2KQ0KQ0ooYygxLCAyLCAzKSwgYyg0LCA1LCA2KSkNCkNKKHg9YygiYSIsImIiLCJjIikseT1jKDEsMiwzKSkNCmxpYnJhcnkodGlkeXIpDQp4IDwtIGRhdGEuZnJhbWUoeD1jKCJhIiwiYiIsImMiKSkNCnkgPC0gZGF0YS5mcmFtZSh5PWMoMSwyLDMpKQ0KY3Jvc3NpbmcoeCwgeSkNCg0KYGBgDQoNCg0KDQpgYGB7cn0NCg0KTSA8LSBtYXRyaXgoZGF0YSA9IHJub3JtKDEyKSwgbmNvbCA9IDMpDQoNCiMgdHJhbnNwb25vdmFuYSBtYXRpY2UNCnQoTSkgDQoNCmRpbShNKQ0KbnJvdyhNKSANCm5jb2woTSkNCmxlbmd0aChNKQ0KbGlicmFyeShNYXRyaXgpDQpubnplcm8oTSwgbmEuY291bnRlZCA9IE5BKSAjIHBvY2V0IG5lbnVsb3Z5Y2ggcHJ2a3UgbWF0aWNlDQoNCnJvdW5kKE0sMikNCmxpYnJhcnkoUmZhc3QpDQpSb3VuZChNLGRpZ2l0PTIsbmEucm0gPSBGQUxTRSkNCg0KDQojIyMgcHJldm9kIHN5bWJvbGlja2UgbWF0aWNlIG5hIG51bWVyaWNrb3UNCm1jaCA9IG1hdHJpeCgiMSIsMywzKQ0KbWNoDQphcy5udW1lcmljKG1jaCkgIyBuZWZ1bmd1amUNCm1hdHJpeChhcy5udW1lcmljKG1jaCksbmNvbD1uY29sKG1jaCkpDQpsaWJyYXJ5KGdtcCkNCmFzTnVtZXJpYyhtY2gpDQoNCg0KIyMjIFByZW1lbmEgbWF0aWNlIG5hIHZla3Rvcg0KbGlicmFyeShnZGF0YSkNCnVubWF0cml4KE0sIGJ5cm93PUZBTFNFKQ0KDQojIyMgTWF0aWNlIG5hIHgsIHksIHoNCmxpYnJhcnkoc3F1YXNoKQ0KeHl6bWF0Mnh5eihNKQ0KZXhwYW5kLmdyaWQoYygxLCAyLCAzKSwgYyg0LCA1LCA2KSkNCg0KDQpsaWJyYXJ5KFJmYXN0MikgIyBTcGxpdCB0aGUgbWF0cml4IGluIGxvd2VyLHVwcGVyIHRyaWFuZ3VsYXIgYW5kIGRpYWdvbmFsDQpsdWQoTSkNCg0KDQojIGplZG5vdGtvdmEgbWF0aWNlLCBpZGVudGl0YQ0KZGlhZygzKQ0KTU0gPSBkaWFnKHggPSAxLCBucm93ID0gMywgbmNvbCA9IDMsIG5hbWVzID0gVFJVRSkNCmRpYWcoTU0pIDwtIDINCmxpYnJhcnkoUmZhc3QpDQpEaWFnLm1hdHJpeCgzLHY9MSkNCkRpYWcuZmlsbChNTSx2PTApIA0KbGlicmFyeShNYXRyaXgpDQpEaWFnb25hbCgzLCB4ID0gMSkNCg0KdXBwZXIudHJpKG1hdHJpeCgxLCAzLCAzKSkNCnJvdW5kKHVwcGVyLnRyaShtYXRyaXgoMSwgMywgMykpKQ0KdXBwZXIudHJpKE1NKQ0KTU1bdXBwZXIudHJpKE1NKV0gPC0gMA0KbG93ZXIudHJpKG1hdHJpeCgxLCAzLCAzKSkNCnJvdW5kKGxvd2VyLnRyaShtYXRyaXgoMSwgMywgMykpKQ0KbG93ZXIudHJpKE1NKQ0KTU1bbG93ZXIudHJpKE1NKV0gPC0gMA0KbGlicmFyeShnZGF0YSkNCnVwcGVyVHJpYW5nbGUoTU0sIGRpYWc9RkFMU0UsIGJ5cm93PUZBTFNFKQ0KdXBwZXJUcmlhbmdsZShNTSwgZGlhZz1UUlVFLCBieXJvdz1GQUxTRSkNCnVwcGVyVHJpYW5nbGUoTU0sIGRpYWc9RkFMU0UsIGJ5cm93PUZBTFNFKSA8LSAxDQpNTQ0KbG93ZXJUcmlhbmdsZShNTSwgZGlhZz1GQUxTRSwgYnlyb3c9RkFMU0UpIA0KbG93ZXJUcmlhbmdsZShNTSwgZGlhZz1GQUxTRSwgYnlyb3c9RkFMU0UpIDwtIDMNCk1NDQpsaWJyYXJ5KFJmYXN0KQ0KbG93ZXJfdHJpKE1NLCBzdW1hID0gRkFMU0UsIGRpYWcgPSBGQUxTRSkgDQp1cHBlcl90cmkoTU0sIHN1bWEgPSBGQUxTRSwgZGlhZyA9IEZBTFNFKSANCmxvd2VyX3RyaS5hc3NpZ24oTU0sIDEsIGRpYWcgPSBGQUxTRSkgDQp1cHBlcl90cmkuYXNzaWduKE1NLCAzLCBkaWFnID0gRkFMU0UpDQpsaWJyYXJ5KE1hdHJpeCkgIyB2IG1hdGljb3ZlbSB0dmFydQ0KdHJpbChNTSkgIyBsb3dlciB0cmlhbmd1bGFyDQp0cml1KE1NKSAjIHVwcGVyIHRyaWFuZ3VsYXINCg0KIyBMVSBkZWNvbXBvc2l0aW9uIChkZWNvbXBvc2UgYSBtYXRyaXggaW50byBsb3dlci0gYW5kIHVwcGVyLXRyaWFuZ3VsYXIgbWF0cmljZXMpDQpsaWJyYXJ5KGNtbmEpDQpsdW1hdHJpeChNTSkNCg0KIyMjIG5hc29iZW5pIG1hdGljDQpiIDwtIG1hdHJpeChucm93ID0gMiwgbmNvbCA9IDIsIGMoMSwgMiwgMywgNCkpOyBiDQphIDwtIG1hdHJpeChucm93ID0gMiwgbmNvbCA9IDIsIGMoMSwgMCwgMCwgLTEpKTsgYQ0KYSUqJWINCmIlKiVhDQpsaWJyYXJ5KFJmYXN0KQ0KbWF0Lm11bHQoYSwgYikNCg0KDQojIyMgc3RvcGEgKHRyYWNlKSAtIHNvdWNldCBwcnZrdSBobGF2bmkgZGlhZ29uYWx5DQpsaWJyYXJ5KGZCYXNpY3MpDQp0cihNTSkNCg0KDQojIyBkZXRlcm1pbmFudA0KZGV0KE1bLGMoMTozKV0pDQoNCmxpYnJhcnkobWF0bGliKQ0KRGV0KE1bLGMoMTozKV0sIG1ldGhvZCA9ICJlbGltaW5hdGlvbiIsIHZlcmJvc2UgPSBGQUxTRSwgZnJhY3Rpb25zID0gRkFMU0UpDQojIG1ldGhvZCA9IGMoImVsaW1pbmF0aW9uIiwgImVpZ2VudmFsdWVzIiwgImNvZmFjdG9ycyIpDQoNCg0KIyMjIGplIG1hdGljZSBwb3ppdGl2bmUgZGVmaW5pdG5pDQpsaWJyYXJ5KGZCYXNpY3MpDQppc1Bvc2l0aXZlRGVmaW5pdGUoTU0pIA0KbWFrZVBvc2l0aXZlRGVmaW5pdGUoTU0pDQoNCg0KIyMjIGhvZG5vc3QgbWF0aWNlDQoNCiMgRnJvYmVuaW92YSB2ZXRhOiBzb3VzdGF2YSBsaW5lYXJuaWNoIHJvdm5pYyBtYSByZXNlbmkgdGVoZHkgYSBqZW4gdGVoZHksIG1hamktbGkgbWF0aWNlIGEgcm96c2lyZW5hIG1hdGljZSBzb3VzdGF2eSBzdGVqbm91IGhvZG5vc3QuDQpxcihNKSRyYW5rDQoNCmxpYnJhcnkoTWF0cml4KQ0KcmFua01hdHJpeChNLCB0b2wgPSBOVUxMLCBtZXRob2QgPSAicXIiLCBzdmFsID0gc3ZkKE0sIDAsIDApJGQsIHdhcm4udCA9IFRSVUUpWzFdDQojIG1ldGhvZCA9IGMoInRvbE5vcm0yIiwgInFyLlIiLCAicXJMSU5QQUNLIiwgInFyIiwgInVzZUdyYWQiLCAibWF5YmVHcmFkIikNCg0KbGlicmFyeShmQmFzaWNzKQ0KcmsoTSwgbWV0aG9kID0gInFyIikNCiMgbWV0aG9kID0gYygicXIiLCAiY2hvbCIpDQoNCmxpYnJhcnkobWF0cml4Y2FsYykgIyBKRU4gUFJPIENUVkVSQ09WT1UgTUFUSUNJDQptYXRyaXgucmFuayhNWyxjKDE6MyldLCBtZXRob2QgPSAicXIiKQ0KIyBtZXRob2QgPSBjKCJxciIsICJjaG9sIikNCg0KbGlicmFyeShsaW1Tb2x2ZSkNCnJlc29sdXRpb24oTSkgICMgJG5zb2x2YWJsZSA9IGhvZG5vc3QgbWF0aWNlDQoNCg0KIyMjIEludmVyem5pIG1hdGljZQ0KDQojIyBjdHZlcmNvdmEgbWF0aWNlDQpNMiA8LSBjYmluZChjKDEsMCwxKSxjKDAsMSwyKSxjKDAsMCwxKSkNCnNvbHZlKE0yKQ0Kc29sdmUoTTIpJSolTTIgICMgY2hlY2sNCg0KbGlicmFyeShmQmFzaWNzKQ0KaW52KE0yKQ0KaW52KE0yKSUqJU0yICAjIGNoZWNrDQoNCmxpYnJhcnkoY21uYSkNCmludm1hdHJpeChNMikNCmludm1hdHJpeChNMiklKiVNMiAgIyBjaGVjaw0KDQpsaWJyYXJ5KG1hdGxpYikNCkludmVyc2UoTTIsIHZlcmJvc2U9RkFMU0UsIGZyYWN0aW9ucz1GQUxTRSkNCkludmVyc2UoTTIpJSolTTIgIyBjaGVjaw0KDQojIyB6b2JlY25lbmEgaW52ZXJ6ZQ0KbGlicmFyeShNQVNTKSAgIyAgTW9vcmUtUGVucm9zZSBnZW5lcmFsaXplZCBpbnZlcnNlIA0KZ2ludihNMikNCnJvdW5kKGdpbnYoTTIpLDApDQpnaW52KE0yKSUqJU0yICAgIyBjaGVjaw0Kcm91bmQoZ2ludihNMiklKiVNMiwwKQ0KDQpsaWJyYXJ5KG1hdGxpYikgDQpHaW52KE0yLCBmcmFjdGlvbnM9RkFMU0UpIA0KR2ludihNMikgJSolIE0yICMgY2hlY2sNCg0KbGlicmFyeShsaW1Tb2x2ZSkNCmxpbVNvbHZlOjpTb2x2ZShNMikNClNvbHZlKE0yKSAlKiUgTTIgIyBjaGVjaw0KDQoNCiMjIyBFaWdlbnZhbHVlcywgZWlnZW52ZWN0b3JzDQplaWdlbihNMikNCg0KbGlicmFyeShjbW5hKQ0KbGlicmFyeShnZWlnZW4pDQoNCmxpYnJhcnkobWF0bGliKQ0KRWlnZW4oTTIsdG9sID0gc3FydCguTWFjaGluZSRkb3VibGUuZXBzKSwgbWF4Lml0ZXIgPSAxMDAsIHJldGFpbi56ZXJvZXMgPSBUUlVFKQ0KQyA8LSBtYXRyaXgoYygxLDIsMywyLDUsNiwzLDYsMTApLCAzLCAzKSAjIG5vbnNpbmd1bGFyLCBzeW1tZXRyaWMgQyANCkVDIDwtIEVpZ2VuKEMpICMgZWlnZW5hbmFseXNpcyBvZiBDIA0KRUMkdmVjdG9ycyAlKiUgZGlhZyhFQyR2YWx1ZXMpICUqJSB0KEVDJHZlY3RvcnMpICMgY2hlY2sNCg0KDQoNCg0KYGBgDQoNCg0KU2VzdGF2dGUgbWF0aWNpIGtvbnN0aXR1xI1uw61jaCBrb2VmaWNpZW50xa8NCg0KYGBge3J9DQoNCmZvcm0gPWMoIkNINCIsIkgyTyIsIkNPMiIsIkNPIikNCmZvcm0gPWMoIkNPIiwiQ09TIiwiQ0g0IiwiUzIiLCJIMk8iKQ0KZm9ybSA9IGMoIktNbk80IiwgIk1uU080IiwgIkgyTyIsICJNbk8yIiwgIksyU080IiwgIkgyU080IikNCmZvcm0gPSBjKCJGZTJPMyIsICJBbCIsICJBbDJPMyIsICJGZSIpDQoNCmxpYnJhcnkoQ0hOT1NaKQ0KY2hhcnMgPSBsYXBwbHkoZm9ybSxmdW5jdGlvbih4KXtuYW1lcyhjb3VudC5lbGVtZW50cyh4KSl9KQ0KbnVtcyA9IGxhcHBseShmb3JtLGZ1bmN0aW9uKHgpe2FzLnZlY3Rvcihjb3VudC5lbGVtZW50cyh4KSl9KQ0KdWxjaCA9IHNvcnQodW5pcXVlKHVubGlzdChjaGFycykpKQ0KTXJsID0gYXMuZGF0YS5mcmFtZShtYXRyaXgoMCxsZW5ndGgoY2hhcnMpLGxlbmd0aCh1bGNoKSkpDQpjb2xuYW1lcyhNcmwpPXVsY2gNCmZvcihYIGluIGMoMTpsZW5ndGgoY2hhcnMpKSl7ICANCiAgZm9yKGkgaW4gYygxOmxlbmd0aChjaGFyc1tbWF1dKSkpeyANCiAgICBjbjEgPSB3aGljaCh1bGNoID09IGNoYXJzW1tYXV1baV0pDQogICAgY24yID0gd2hpY2goY2hhcnNbW1hdXSA9PSBjaGFyc1tbWF1dW2ldKQ0KICAgIE1ybFtYLGNuMV0gPSBhcy5udW1lcmljKG51bXNbW1hdXVtjbjJdKQ0KICB9DQp9DQpyb3duYW1lcyhNcmwpPWZvcm0NCk1ybA0KDQpgYGANCg0KDQpVcsSNZXRlIHBvxI1ldCBsaW5lw6FybsSbIG5lesOhdmlzbMO9Y2ggcmVha2PDrSB2IHNvdXN0YXbEmyBvYnNhaHVqw61jw60gZGFuw6kgc2xvxb5reS4NCg0KR2liYnNvdm8gc3RlY2hpb21ldHJpY2tlIHByYXZpZGxvOiBtYXhpbcOhbG7DrSBwb8SNZXQgbGluZcOhcm7EmyBuZXrDoXZpc2zDvWNoIHJlYWtjw60gciBqZSBtZW7FocOtIG5lYm8gcm92ZW4gcm96ZMOtbHUgcG/EjXR1IHNsb8W+ZWsgdiBzeXN0w6ltdSAobikgYSBob2Rub3N0aSBtYXRpY2Uga29uc3RpdHXEjW7DrWNoIGtvZWZpY2llbnTFryAoaCksIHYgbi1zbG/FvmtvdsOpbSBzeXN0w6ltdSBleGlzdHVqZSBuIC0gaCBzdGVjaGlvbWV0cmlja8O9Y2ggdnp0YWjFry4NCg0KYGBge3J9DQoNCmZvcm0gPSBjKCJDSDQiLCJIMk8iLCJDTyIsIkNPMiIsIkgyIikNCmZvcm0gPSBjKCJOSDMiLCJOMiIsIk5PIiwiTk8yIiwiSDJPIiwiTzIiKQ0KDQpsaWJyYXJ5KENITk9TWikNCmNoYXJzID0gbGFwcGx5KGZvcm0sZnVuY3Rpb24oeCl7bmFtZXMoY291bnQuZWxlbWVudHMoeCkpfSkNCm51bXMgPSBsYXBwbHkoZm9ybSxmdW5jdGlvbih4KXthcy52ZWN0b3IoY291bnQuZWxlbWVudHMoeCkpfSkNCnVsY2ggPSBzb3J0KHVuaXF1ZSh1bmxpc3QoY2hhcnMpKSkNCk1ybCA9IGFzLmRhdGEuZnJhbWUobWF0cml4KDAsbGVuZ3RoKGNoYXJzKSxsZW5ndGgodWxjaCkpKQ0KY29sbmFtZXMoTXJsKT11bGNoDQpmb3IoWCBpbiBjKDE6bGVuZ3RoKGNoYXJzKSkpeyAgDQogIGZvcihpIGluIGMoMTpsZW5ndGgoY2hhcnNbW1hdXSkpKXsgDQogICAgY24xID0gd2hpY2godWxjaCA9PSBjaGFyc1tbWF1dW2ldKQ0KICAgIGNuMiA9IHdoaWNoKGNoYXJzW1tYXV0gPT0gY2hhcnNbW1hdXVtpXSkNCiAgICBNcmxbWCxjbjFdID0gYXMubnVtZXJpYyhudW1zW1tYXV1bY24yXSkNCiAgfQ0KfQ0Kcm93bmFtZXMoTXJsKT1mb3JtDQpNcmwNCk0gPSBNcmwNCg0KIyBob2Rub3N0IG1hdGljZQ0KcXIoTSkkcmFuaw0KbGlicmFyeShNYXRyaXgpDQpyYW5rTWF0cml4KE0pWzFdDQoNCiMgcG9jZXQgbGluZWFybmUgbmV6YXZpc2x9Y2ggcmVha2NtDQoociA9IGxlbmd0aChmb3JtKSAtIHFyKE0pJHJhbmspDQoNCmBgYA0KDQoNCmBgYHtyfQ0KDQojIyMgVnljaXNsZXRlIHJvdm5pY2k6IEZlMk8zICsgQWwgPSBBbDJPMyArIEZlDQpGZSA9IGMoMiwgMCwgMCwgLTEpDQpPID0gYygzLCAwLCAtMywgMCkNCkFsID0gYygwLCAxLCAtMiwgMCkNCkEgPSBhcy5tYXRyaXgocmJpbmQoRmUsIE8sIEFsKSkNCmNvbG5hbWVzKEEpID0gYygiRmUyTzMiLCAiQWwiLCAiQWwyTzMiLCAiRmUiKQ0KQiA9IGMocmVwKDAsbGVuZ3RoKEFbLDFdKSkpDQpDID0gY2JpbmQoQSxCKQ0KbGlicmFyeShtYXRsaWIpDQpjKFIoQSksIFIoY2JpbmQoQSxCKSkpICAgICAgICAgICMgc2hvdyByYW5rcw0KYWxsLmVxdWFsKFIoQSksIFIoY2JpbmQoQSxCKSkpICAjIGNvbnNpc3RlbnQ/DQpzaG93RXFuKEEsIEIpDQptYXRsaWI6OlNvbHZlKEEsIEIpDQpHRTEgPSBnYXVzc2lhbkVsaW1pbmF0aW9uKEEsIEIsIHRvbCA9IHNxcnQoLk1hY2hpbmUkZG91YmxlLmVwcyksIHZlcmJvc2UgPSBGQUxTRSwgbGF0ZXggPSBGQUxTRSwgZnJhY3Rpb25zID0gVFJVRSkNCmFzLmNoYXJhY3RlcihHRTEpDQojIGNpbSBuYXNvYml0IGtvZWZpY2llbnR5DQpubnYxID0gMS9taW4oYWJzKGFzLm51bWVyaWMoR0UxWyxsZW5ndGgoQVsxLF0pXSkpKQ0Kbm52ID0gYXMubnVtZXJpYyhHRTFbLGxlbmd0aChBWzEsXSldKSpubnYxDQpOTiA9IC0xKihhcy5tYXRyaXgoR0UxKSpubnYpWyxjKDE6KGxlbmd0aChBWzEsXSktMSkpXQ0Kcm93bmFtZXMoTk4pID0gcm93bmFtZXMoQSkNCmNvbG5hbWVzKE5OKSA9IGNvbG5hbWVzKEEpWy1sZW5ndGgoY29sbmFtZXMoQSkpXQ0KYXBwbHkoTk4sMixzdW0pDQoNCmxpYnJhcnkoTUFTUykNCm5uID0gbGVuZ3RoKEFbMSxdKQ0KYSA9IEFbLC1ubl0NCmIgPSAtQVssbm5dDQpnZTEgPC0gTUFTUzo6Z2ludihhKSAlKiUgYg0KZ2UxKjINCg0KbGlicmFyeShsaW1Tb2x2ZSkNCkxzID0gbGltU29sdmU6OlNvbHZlKEEsIEIgPSBkaWFnKG5yb3cgPSBucm93KEEpKSwgdG9sID0gc3FydCguTWFjaGluZSRkb3VibGUuZXBzKSkNCmxpYnJhcnkoTUFTUykNCmZyYWN0aW9ucyhMcykNCmZyYWN0aW9ucyhMcykqMzANCg0KYGBgDQoNCg0KVnnEjcOtc2xldGUgcm92bmljaTogS01uTzQgKyBNblNPNCArIEgyTyA9IE1uTzIgKyAgSzJTTzQgKyBIMlNPNA0KDQpgYGB7cn0NCg0KSyA9IGMoMSwgMCwgMCwgMCwgLTIsIDApDQpNbiA9IGMoMCwgMSwgMCwgLTEsIDAsIDApDQpPID0gYyg0LCA0LCAxLCAtMiwgLTQsIC00KQ0KUyA9IGMoMCwgMSwgMCwgMCwgLTEsIC0xKQ0KSCA9IGMoMCwgMCwgMiwgMCwgMCwgLTIpDQoNCkEgPSBhcy5tYXRyaXgocmJpbmQoSywgTW4sIE8sIFMsIEgpKQ0KY29sbmFtZXMoQSkgPSBjKCJLTW5PNCIsICJNblNPNCIsICJIMk8iLCAiTW5PMiIsICJLMlNPNCIsICJIMlNPNCIpDQpCID0gYyhyZXAoMCxsZW5ndGgoQVssMV0pKSkNCkMgPSBjYmluZChBLEIpDQpsaWJyYXJ5KG1hdGxpYikNCmMoUihBKSwgUihjYmluZChBLEIpKSkgICAgICAgICAgIyBzaG93IHJhbmtzDQphbGwuZXF1YWwoUihBKSwgUihjYmluZChBLEIpKSkgICMgY29uc2lzdGVudD8NCnNob3dFcW4oQSwgQikNCm1hdGxpYjo6U29sdmUoQSwgQikNCkdFMiA9IGdhdXNzaWFuRWxpbWluYXRpb24oQSwgQiwgdG9sID0gc3FydCguTWFjaGluZSRkb3VibGUuZXBzKSwgdmVyYm9zZSA9IEZBTFNFLCBsYXRleCA9IEZBTFNFLCBmcmFjdGlvbnMgPSBUUlVFKQ0KYXMuY2hhcmFjdGVyKEdFMikNCiMgY2ltIG5hc29iaXQga29lZmljaWVudHkNCm5udjEgPSAxL21pbihhYnMoYXMubnVtZXJpYyhHRTJbLGxlbmd0aChBWzEsXSldKSkpDQpubnYgPSBhcy5udW1lcmljKEdFMlssbGVuZ3RoKEFbMSxdKV0pKm5udjENCk5OID0gLTEqKGFzLm1hdHJpeChHRTIpKm5udilbLGMoMToobGVuZ3RoKEFbMSxdKS0xKSldDQpyb3duYW1lcyhOTikgPSByb3duYW1lcyhBKQ0KY29sbmFtZXMoTk4pID0gY29sbmFtZXMoQSlbLWxlbmd0aChjb2xuYW1lcyhBKSldDQphcHBseShOTiwyLHN1bSkNCg0KYGBgDQoNCg0KS29saWsgOTYlIGt5c2VsaW55IHPDrXJvdsOpIGEga29saWsgdm9keSBqZSBwb3TFmWViYSBuYSBwcmlwcmF2dSAxIGwgNzglIGt5c2VsaW55IHPDrXJvdsOpPw0KDQpgYGB7cn0NCg0KcjEgPSBjKDAsIDEpDQpyMiA9IGMoMC45NiwgMC4wNCkNCkEgPSBjYmluZChyMSwgcjIpOyByb3duYW1lcyhBKSA9IGMoIkgyU080IiwiSDJPIikNCkIgPSBjKDAuNzgsIDAuMjIpOyBuYW1lcyhCKSA9IGMoIkgyU080IiwiSDJPIikNCmxpYnJhcnkobWF0bGliKQ0KYyhSKEEpLCBSKGNiaW5kKEEsQikpKSAgICAgICAgICAjIHNob3cgcmFua3MsIHZpeiBGcm9iZW5pb3ZhIHZldGENCmFsbC5lcXVhbChSKEEpLCBSKGNiaW5kKEEsQikpKSAgIyBjb25zaXN0ZW50Pw0Kc2hvd0VxbihBLCBCKQ0KbWF0bGliOjpTb2x2ZShBLCBCKQ0KbGltU29sdmU6OlNvbHZlKEEsIEIpDQpHRTEgPSBnYXVzc2lhbkVsaW1pbmF0aW9uKEEsIEIsIHRvbCA9IHNxcnQoLk1hY2hpbmUkZG91YmxlLmVwcyksIHZlcmJvc2UgPSBGQUxTRSwgbGF0ZXggPSBGQUxTRSwgZnJhY3Rpb25zID0gRkFMU0UpDQpOTiA9IEdFMVssM10gIyBbbF0NCm5hbWVzKE5OKSA9IHJvd25hbWVzKEEpDQpOTg0KbGlicmFyeShSbGluc29sdmUpDQpscyA9IGxzb2x2ZS5ncyhBLCBCLCB4aW5pdCA9IE5BLCByZWx0b2wgPSAxZS0wNSwgbWF4aXRlciA9IDEwMDAsIGFkanN5bSA9IFRSVUUsIHZlcmJvc2UgPSBUUlVFKQ0KbHMkeA0KbGlicmFyeShjbW5hKQ0KY2dtbWF0cml4KEEsIEIsIHRvbCA9IDFlLTA2LCBtYXhpdGVyID0gMTAwKSAjIGl0ZXJhdGl2ZW1hdHJpeA0Kc29sdmVtYXRyaXgoQSwgQikgIyByZWZtYXRyaXgNCg0KYGBgDQoNCg0KU2xpdGluYSBBIG9ic2FodWplIDEuNSAlIFNpLCAxLjQgJSBNbiwgMC40ICUgUCBhIDAuMyAlIFMuIFNsaXRpbmEgQiBvYnNhaHVqZSAwLjUgJSBTaSwgMS42ICUgTW4sIDAuMiAlIFAgYSAwLjIgJSBTLiBTbGl0aW5hIEMgb2JzYWh1amUgMyAlIFNpLCAwLjUgJSBNbiwgMC41ICUgUCBhIDAuMDUgJSBTLiBLb2xpayBrYcW+ZMOpIHNsaXRpbnkgQSwgQiwgQyBqZSB0xZllYmEgbmEgdsO9cm9idSAxMDAga2cgc2xpdGlueSBvYnNhaHVqw61jw60gMiAlIFNpLCAxICUgTW4sIDAuNCAlIFAgYSAwLjE1ICUgUz8NCg0KYGBge3J9DQoNCnNsMSA9IGMoMC4wMTUsIDAuMDE0LCAwLjAwNCwgMC4wMDMpDQpzbDIgPSBjKDAuMDA1LDAuMDE2LCAwLjAwMiwgMC4wMDIpDQpzbDMgPSBjKDAuMDMsIDAuMDA1LCAwLjAwNSwgMC4wMDA1KQ0KQSA9IGNiaW5kKHNsMSwgc2wyLCBzbDMpOyByb3duYW1lcyhBKSA9IGMoIlNpIiwiTW4iLCJQIiwiUyIpDQpCID0gYygwLjAyLCAwLjAxLCAwLjAwNCwgMC4wMDE1KTsgbmFtZXMoQikgPSBjKCJTaSIsIk1uIiwiUCIsIlMiKQ0KIyBCID0gYygyLCAxLCAwLjQsIDAuMTUpOyBuYW1lcyhCKSA9IGMoIlNpIiwiTW4iLCJQIiwiUyIpDQpsaWJyYXJ5KG1hdGxpYikNCmMoUihBKSwgUihjYmluZChBLEIpKSkgICAgICAgICAgIyBzaG93IHJhbmtzLCB2aXogRnJvYmVuaW92YSB2ZXRhDQphbGwuZXF1YWwoUihBKSwgUihjYmluZChBLEIpKSkgICMgY29uc2lzdGVudD8NCnNob3dFcW4oQSwgQikNCm1hdGxpYjo6U29sdmUoQSwgQikNCmxpbVNvbHZlOjpTb2x2ZShBLCBCKQ0KR0UxID0gZ2F1c3NpYW5FbGltaW5hdGlvbihBLCBCLCB0b2wgPSBzcXJ0KC5NYWNoaW5lJGRvdWJsZS5lcHMpLCB2ZXJib3NlID0gRkFMU0UsIGxhdGV4ID0gRkFMU0UsIGZyYWN0aW9ucyA9IEZBTFNFKQ0KR0UxWyw0XSoxMDAgIyBba2ddDQpsaWJyYXJ5KFJsaW5zb2x2ZSkNCmxzID0gbHNvbHZlLmdzKEEsIEIsIHhpbml0ID0gTkEsIHJlbHRvbCA9IDFlLTA1LCBtYXhpdGVyID0gMTAwMCwgYWRqc3ltID0gVFJVRSwgdmVyYm9zZSA9IFRSVUUpDQpscyR4DQoNCmBgYA0KDQoNCktvbGlrIGcgNjAlIGEga29saWsgZyAzMCUgcm96dG9rdSBOYUNsIGplIHRyZWJhIHNtaWNoYXQgcHJpIHByaXByYXZlIDEwMCBnIDQwJSByb3p0b2t1PyAyMCBnIDYwJSBhIGEgODAgZyAzNSUNCg0KYGBge3J9DQoNCmxpYnJhcnkocm9vdFNvbHZlKQ0KbW9kZWwgPC0gZnVuY3Rpb24oeCl7DQogIEYxIDwtIDAuNip4WzFdICsgMC4zKnhbMl0gLSA0MA0KICBGMiA8LSB4WzFdICsgeFsyXSAtIDEwMA0KICBjKEYxID0gRjEsIEYyID0gRjIpfQ0Kc3MgPC0gbXVsdGlyb290KGYgPSBtb2RlbCwgc3RhcnQgPSBjKDEsIDEpKQ0Kc3Mkcm9vdA0KDQojIyMgZ3JhZmlja2UgcmVzZW5pDQojIDAuNiptMSArIDAuMyptMiA9IDEwMCowLjQgPT4gbTEgPSA0MC8wLjYgLSAwLjMvMC42ICogbTIgID0+IG0xID0gNjYuNjcgLSAwLjUgKiBtMiANCiMgbTEgKyBtMiA9IDEwMCAgPT4gbTEgPSAxMDAgLSBtMg0KeHggPSBzZXEoMCwxMDAsMC4xKQ0KeXkgPSA2Ni42NyAtIDAuNSp4eA0KenogPSAxMDAgLSB4eA0KcGxvdCh4eCwgeXksIHR5cGU9ImwiLGNvbD0yKQ0KcG9pbnRzKHh4LCB6eiwgdHlwZT0ibCIsY29sPTQpDQpwbG90KHh4LCB5eSwgdHlwZT0ibCIsY29sPTIseGxpbT1jKDY1LDcwKSx5bGltPWMoMzAsNDApKQ0KcG9pbnRzKHh4LCB6eiwgdHlwZT0ibCIsY29sPTQpDQoNCiMjIyBtYXRpY2UNCg0KQiA9IGMoMC40MCoxMDAsMTAwKSAjIFttZ10NCm5hbWVzKEIpID0gYygiNjAlIiwiMzAlIikNCnIxID0gYygwLjYwLDEpICMgW21nXQ0KcjIgPSBjKDAuMzAsMSkgIyBbbWddDQpBID0gY2JpbmQocjEscjIpDQpjb2xuYW1lcyhBKSA9IGMoIjYwJSIsIjMwJSIpDQpyb3duYW1lcyhBKSA9IGMoInIzMCIsInIzIikNCmRldChBKSAjIG1hdGljZSBqZSByZWd1bGFybmkgbiA9IGgNCmxpYnJhcnkobWF0bGliKQ0KYyhSKEEpLCBSKGNiaW5kKEEsQikpKSAgICAgICAgICAjIHNob3cgcmFua3MNCmFsbC5lcXVhbChSKEEpLCBSKGNiaW5kKEEsQikpKSAgIyBjb25zaXN0ZW50Pw0Kc2hvd0VxbihBLCBCKQ0KbWF0bGliOjpTb2x2ZShBLCBCKQ0KbGltU29sdmU6OlNvbHZlKEEsIEIpDQojDQpsaWJyYXJ5KGxpbVNvbHZlKQ0KRyA8LW1hdHJpeChuY29sID0gMiwgYnlyb3cgPSBUUlVFLCBkYXRhID0gYygxLCAwLCAwLCAxKSkgDQpIIDwtIGMoMCwgMCkNCmxkZWkoQSwgQiwgRyA9IEcsIEggPSBIKSRYDQojDQpsaWJyYXJ5KGNtbmEpIA0KZ2RscyhBLCBCLCBhbHBoYSA9IDAuMDUsIHRvbCA9IDFlLTA2LCBtID0gMWUrMDUpICMgIGxlYXN0IHNxdWFyZXMgd2l0aCBncmFpZGVudCBkZXNjZW50DQpqYWNvYmkoQSwgQiwgdG9sID0gMWUtMDYsIG1heGl0ZXIgPSAxMDApICAjIGl0ZXJhdGl2ZW1hdHJpeA0KZ2F1c3NzZWlkZWwoQSwgQiwgdG9sID0gMWUtMDYsIG1heGl0ZXIgPSAxMDApICMgaXRlcmF0aXZlbWF0cml4DQpzb2x2ZW1hdHJpeChBLCBCKSAjIHJlZm1hdHJpeA0KDQpgYGANCg0KDQpaZSBkdm91IGtvdnUgbyBodXN0b3RhY2ggNy40IGcvY20zIGEgOC4yIGcvY20zIGplIHRyZWJhIHByaXByYXZpdCAwLjUga2cgc2xpdGlueSBvIGh1c3RvdGUgNy42IGcvY20zLiBLb2xpayBnIGthemRpaG8geiBrb3Z1IGplIGsgdG9tdSBwb3RyZWJhPyAzNzUgZyBsZWhjaWhvIGEgMTI1IGcgdGV6c2lobw0KDQpgYGB7cn0NCg0KbGlicmFyeShyb290U29sdmUpDQptb2RlbCA8LSBmdW5jdGlvbih4KXsNCiAgRjEgPC0gNy40KnhbMV0gKyA4LjIqeFsyXSAtIDM4MDANCiAgRjIgPC0geFsxXSArIHhbMl0gLSA1MDANCiAgYyhGMSA9IEYxLCBGMiA9IEYyKX0NCnNzIDwtIG11bHRpcm9vdChmID0gbW9kZWwsIHN0YXJ0ID0gYygxLCAxKSkNCnNzJHJvb3QgICMgW2tnXQ0KDQojIyMgZ3JhZmlja2UgcmVzZW5pDQojIDcuNCptMSArIDguMiptMiA9IDAuNSo3LjYgPT4gbTEgPSAzODAwLzcuNCAtIDguMi83LjQgKiBtMiAgPT4gbTEgPSA1MTMuNSAtIDEuMTA4ICogbTIgDQojIG0xICsgbTIgPSA1MDAgID0+IG0xID0gNTAwIC0gbTINCnh4ID0gc2VxKDAsNTAwLDEpDQp5eSA9IDUxMy41IC0gMS4xMDgqeHgNCnp6ID0gNTAwIC0geHgNCnBsb3QoeHgsIHl5LCB0eXBlPSJsIixjb2w9MikNCnBvaW50cyh4eCwgenosIHR5cGU9ImwiLGNvbD00KQ0KcGxvdCh4eCwgeXksIHR5cGU9ImwiLGNvbD0yLHhsaW09YygxMDAsMTUwKSx5bGltPWMoMzUwLDQwMCkpDQpwb2ludHMoeHgsIHp6LCB0eXBlPSJsIixjb2w9NCkNCg0KIyMjIG1hdGljZQ0KQiA9IGMoNy42LDEpICMgW21nXQ0KbmFtZXMoQikgPSBjKCJrb3YxIiwia292MiIpDQpyMSA9IGMoNy40LDEpICMgW21nXQ0KcjIgPSBjKDguMiwxKSAjIFttZ10NCkEgPSBjYmluZChyMSxyMikNCmNvbG5hbWVzKEEpID0gYygia292MSIsImtvdjIiKQ0Kcm93bmFtZXMoQSkgPSBjKCI3LjQiLCI4LjIiKQ0KZGV0KEEpICMgbWF0aWNlIGplIHJlZ3VsYXJuaSBuID0gaA0KbGlicmFyeShtYXRsaWIpDQpjKFIoQSksIFIoY2JpbmQoQSxCKSkpICAgICAgICAgICMgc2hvdyByYW5rcw0KYWxsLmVxdWFsKFIoQSksIFIoY2JpbmQoQSxCKSkpICAjIGNvbnNpc3RlbnQ/DQpzaG93RXFuKEEsIEIpDQpyciA9IG1hdGxpYjo6U29sdmUoQSwgQikNCnJlYWQudGFibGUodGV4dCA9IHJyWzFdLCBmaWxsID0gVFJVRSlbWzNdXSo1MDAgIyBbZ10NCnJlYWQudGFibGUodGV4dCA9IHJyWzJdLCBmaWxsID0gVFJVRSlbWzNdXSo1MDAgIyBbZ10NCnJyID0gbGltU29sdmU6OlNvbHZlKEEsIEIpDQpycio1MDAgIyBbZ10NCiMgDQpsaWJyYXJ5KGxpbVNvbHZlKQ0KRyA8LW1hdHJpeChuY29sID0gMiwgYnlyb3cgPSBUUlVFLCBkYXRhID0gYygxLCAwLCAwLCAxKSkgDQpIIDwtIGMoMCwgMCkNCnJyID0gbGRlaShBLCBCLCBHID0gRywgSCA9IEgpJFgNCnJyKjUwMCAjIFtnXQ0KDQpgYGANCg0KDQpWIHRlcGVsbsOpIGVsZWt0csOhcm5lIG1hasOtIHrDoXNvYnUgdWhsw60sIGt0ZXLDoSB2eXN0YWPDrSBuYSAyNCBkbsOtLCBidWRlLWxpIHYgY2lubm9zdGkgcG91emUgcHJ2bsOtIGJsb2ssIG5hIDMwIGRuw60sIGJ1ZGUtbGkgdiBwcm92b3p1IHBvdXplIDIuIGJsb2sgYSBuYSAyMCBkbsOtLCBidWRlLWxpIHYgcHJvdm96dSBwb3V6ZSAzLiBibG9rLiBOYSBqYWsgZGxvaG8gdnlzdGFjw60gesOhc29iYSwgYnVkb3UtbGkgdiBwcm92b3p1IHZzZWNobnkgYmxva3kgbmFqZWRub3U/DQoNCmBgYHtyfQ0KDQojIHgvMjQgKyB4LzMwICsgeC8yMCA9IDENCg0KbGlicmFyeShSeWFjYXMpDQp2ciA8LSB5c3ltKCJ4LzI0ICsgeC8zMCArIHgvMjAgLSAxIikgDQpzb2x2ZSh2ciwgIngiKSANCg0KZnVuIDwtIGZ1bmN0aW9uICh4KSB4LzI0ICsgeC8zMCArIHgvMjAgLSAxDQp1bmlyb290KGZ1biwgYygwLCAxKSxleHRlbmRJbnQgPSAieWVzIiwgdG9sID0gMWUtOSkkcm9vdA0KDQpgYGANCg==