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?

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

Tlakova lahev s oxidem uhlicitym obsahuje 10.0 kg plynu. Jaký objem zaujíma stlaceny plyn, kdyz pri teplote 30 °C je tlak v lahvi 13.17e6 Pa? Vypocet provedte pomoci van der Waalsovy rovnice.

soustavy linearnich 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

### 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

### 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)

Ze dvou druhu caje v cene 160 Kc a 220 Kc za 1 kg je treba pripravit 20 kg smesi v cene 205 Kc za 1 kg. Kolik kg kazdeho caje je treba smichat? 5 kg levnejsiho a 15 kg drazsiho


library(rootSolve)   ### opravit zadani
model <- function(x){
  F1 <- 160*x[1] + 220*x[2] - 4100
  F2 <- x[1] + x[2] - 20
  c(F1 = F1, F2 = F2)}
ss <- multiroot(f = model, start = c(1, 1))
ss$root

### graficke reseni
# 160*m1 + 220*m2 = 4100 => m1 = 4100/160 - 220/160 * m2  => m1 = 25.625 - 1.375 * m2
# m1 + m2 = 20 => m1 = 20 - m2
xx = seq(0,20,0.1)
yy = 25.625 - 1.375*xx
zz = 20 - xx
plot(xx, yy, type="l",col=2)
points(xx, zz, type="l",col=4)
plot(xx, yy, type="l",col=2,xlim=c(10,20),ylim=c(0,10))
points(xx, zz, type="l",col=4)

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%


library(rootSolve)
model <- function(x){
  F1 <- 0.6*x[1] + 0.3*x[2] - 40
  F2 <- x[1] + x[2] - 100
  c(F1 = F1, F2 = F2)}
ss <- multiroot(f = model, start = c(1, 1))
ss$root

### graficke reseni
# 0.6*m1 + 0.3*m2 = 100*0.4 => m1 = 40/0.6 - 0.3/0.6 * m2  => m1 = 66.67 - 0.5 * m2 
# m1 + m2 = 100  => m1 = 100 - m2
xx = seq(0,100,0.1)
yy = 66.67 - 0.5*xx
zz = 100 - xx
plot(xx, yy, type="l",col=2)
points(xx, zz, type="l",col=4)
plot(xx, yy, type="l",col=2,xlim=c(65,70),ylim=c(30,40))
points(xx, zz, type="l",col=4)

### 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
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)
limSolve::Solve(A, B)
#
library(limSolve)
G <-matrix(ncol = 2, byrow = TRUE, data = c(1, 0, 0, 1)) 
H <- c(0, 0)
ldei(A, B, G = G, H = H)$X
#
library(cmna) 
gdls(A, B, alpha = 0.05, tol = 1e-06, m = 1e+05) #  least squares with graident descent
jacobi(A, B, tol = 1e-06, maxiter = 100)  # iterativematrix
gaussseidel(A, B, tol = 1e-06, maxiter = 100) # iterativematrix
solvematrix(A, B) # refmatrix

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+IDApIHtjYXQoIkt2YWRyYXRpY2thIHJvdm5pY2UgbWEgZHZhIHJ1em5lIHJlYWxuZSBrb3JlbnkuIil9DQppZiAoRCA8IDApIHtjYXQoIkt2YWRyYXRpY2thIHJvdm5pY2UgbmVtYSB6YWRueSBrb3JlbiB2IG9ib3J1IHJlYWxueWNoIGNpc2VsLiBWIG9ib3J1IGtvbXBsZXhuaWNoIGNpc2VsIG1hIGR2YSBpbWFnaW5hcm5pIGtvbXBsZXhuZSBzZHJ1emVuZSBrb3JlbnkuIil9DQoNCiMgRGVzY2FydGVzIHJ1bGUNCnN1bShkaWZmKHNpZ24oZGMpKSAhPSAwKQ0KY2F0KCJQb2NldCBrbGFkbnljaCBrb3JlbnU6Iiwgc3VtKGRpZmYoc2lnbihkYykpICE9IDApKSAjIHBvY2V0IGtsYWRueWNoIGtvcmVudQ0KDQpsaWJyYXJ5KHNmc21pc2MpDQpuci5zaWduLmNoZyhkYykNCmNhdCgiUG9jZXQga2xhZG55Y2gga29yZW51OiIsIG5yLnNpZ24uY2hnKGRjKSkgIyBwb2NldCBrbGFkbnljaCBrb3JlbnUNCg0KDQpmdW4gPC0gZnVuY3Rpb24gKHgpIHt4XjIgKyAoeCArIDE0KV4yIC0gMzReMn0NCnVuaXJvb3QoZnVuLCBjKC0xLCAwKSxleHRlbmRJbnQgPSAieWVzIiwgdG9sID0gMWUtOSkgICMgYmFzZQ0KdW5pcm9vdChmdW4sIGMoMCwgMSksZXh0ZW5kSW50ID0gInllcyIsIHRvbCA9IDFlLTkpDQojIHVuaXJvb3QoZnVuLCBjKC0xLCAxKSxleHRlbmRJbnQgPSAieWVzIiwgdG9sID0gMWUtOSkNCkYxIDwtIHVuaXJvb3QoZnVuLCBjKDAsIDEwMCksZXh0ZW5kSW50ID0gInllcyIsIHRvbCA9IDFlLTkpIA0KRjEkcm9vdA0KDQpmdW4gPC0gZnVuY3Rpb24oeCl7eF4yICsgMTQqeCAtIDQ4MH0NCnVuaXJvb3QoZnVuLCBjKC0xLCAwKSxleHRlbmRJbnQgPSAieWVzIiwgdG9sID0gMWUtOSkgICMgYmFzZQ0KdW5pcm9vdChmdW4sIGMoMCwgMSksZXh0ZW5kSW50ID0gInllcyIsIHRvbCA9IDFlLTkpDQpGMSA8LSB1bmlyb290KGZ1biwgYygwLCAxMDApLGV4dGVuZEludCA9ICJ5ZXMiLCB0b2wgPSAxZS05KQ0KRjEkcm9vdCANCg0KDQpyciA9IHBvbHlyb290KGMoLTQ4MCwgMTQsIDEpKSAjIGJhc2UNClJlKHJyKQ0KDQoNCmxpYnJhcnkocHJhY21hKQ0KcnIgPSByb290cyhjKDEsIDE0LCAtNDgwKSkNCnJyDQoNCiMjIGdyYWZpY2tlIHJlc2VuaQ0KeHggPSBzZXEoLTUwLDUwLDEpDQp5eSA9IGFicyh4eF4yICsgKHh4ICsgMTQpXjIgLSAzNF4yKQ0KcGxvdCh4eCx5eSx0eXBlPSJsIikNCmFibGluZShoPTAsY29sPTIpDQp4eFt3aGljaCh5eT09MCldDQp4eFt5eT09MF0NCg0KIyMgZ3JhZmlja2UgcmVzZW5pDQp4eCA9IHNlcSgtNTAsNTAsMSkNCnl5ID0geHheMg0KenogPSAtMTQqeHggKyA0ODANCnBsb3QoeHgseXksdHlwZT0ibCIpDQphYmxpbmUoNDgwLC0xNCxjb2w9MikNCg0KcGxvdCh4eCx5eSx0eXBlPSJsIix4bGltID0gYygxMCwyMCkseWxpbT1jKDAsNTAwKSkNCmFibGluZSg0ODAsLTE0LGNvbD0yKQ0KDQoNCmBgYA0KDQoNCkpha2UgcEggbcOhIHJvenRvayBreXNlbGlueSBtcmF2ZW7EjcOtIG8ga29uY2VudHJhY2kgOC41IHggMTAtNCBtb2wvbD8NCg0KYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0KcEtBID0gMy43NTINCktBID0gMTBeLXBLQTsgS0ENCkt3ID0gMTBeLTE0DQpjQSA9IDguNWUtNCAjIFttb2wvbCBdIA0KDQoNCiMgSCA9IHNxcnQoS0EqY0EpDQpIIDwtIHNxcnQoS0EqY0EpDQpwSCA9IC1sb2cxMChIKTsgcEggDQoNCg0KIyBbSCtdXjIgKyBLQSpbSCtdICsgS0EqY0EgPSAwDQpDRSA9IGMoMSxLQSwtS0EqY0EpDQpmdW4gPC0gZnVuY3Rpb24gKHgpIENFWzFdKnheMiArIENFWzJdKnggKyBDRVszXQ0KdW5pcm9vdChmdW4sIGMoLTFlLTEsIDApLHRvbCA9IDFlLTkpDQp1bmlyb290KGZ1biwgYygwLCAxZS0xKSx0b2wgPSAxZS05KQ0KSCA8LSB1bmlyb290KGZ1biwgYygwLCAxZS0xKSx0b2wgPSAxZS05KSRyb290ICAjIGJhc2UNCnBIID0gLWxvZzEwKEgpOyBwSA0KDQpsaWJyYXJ5KHJvb3RTb2x2ZSkNCnJvb3RTb2x2ZTo6dW5pcm9vdC5hbGwoZnVuLCBjKC0xZS0xLCAwKSwgdG9sID0gMWUtOSkNCnJvb3RTb2x2ZTo6dW5pcm9vdC5hbGwoZnVuLCBjKDAsIDFlLTEpLCB0b2wgPSAxZS05KQ0KSCA8LSByb290U29sdmU6OnVuaXJvb3QuYWxsKGZ1biwgYygtMWUtMSwgMWUtMSksIHRvbCA9IDFlLTkpDQpwSCA9IC1sb2cxMChIKTsgcEggDQoNCmxpYnJhcnkoUm1wZnIpDQpSbXBmcjo6dW5pcm9vdFIoZnVuLCBsb3dlcj0tMWUtMSwgdXBwZXI9MCwgdG9sID0gMWUtOSkNClJtcGZyOjp1bmlyb290UihmdW4sIGxvd2VyPTAsIHVwcGVyPTFlLTEsIHRvbCA9IDFlLTkpDQpIIDwtIFJtcGZyOjp1bmlyb290UihmdW4sIGxvd2VyPTAsIHVwcGVyPTFlLTEsIHRvbCA9IDFlLTkpJHJvb3QNCnBIID0gLWxvZzEwKEgpOyBwSCANCg0KDQoNCiMgW0grXV4zICsgS0EqW0grXV4yIC0gW0grXSooS0EqY0EgKyBLdykgLSBLQSpLdyA9IDANCkNFID0gYygxLEtBLC0oS0EqY0EgKyBLdyksLUtBKkt3KQ0KDQpsaWJyYXJ5KFJDb25pY3MpIA0KeDAgPSBjdWJpYyhDRSk7IHgwDQpIID0gUmUoeDBbd2hpY2goSW0oeDApPT0wKV0pDQpIID0gUmUoeDBbd2hpY2goUmUoeDApPj0wKV0pDQpwSCA9IC1sb2cxMChIKTsgcEggDQoNCg0KZnVuIDwtIGZ1bmN0aW9uICh4KSBDRVsxXSp4XjMgKyBDRVsyXSp4XjIgKyBDRVszXSp4ICsgQ0VbNF0NCnVuaXJvb3QoZnVuLCBjKC0xZS0xLDApLHRvbCA9IDFlLTkpDQp1bmlyb290KGZ1biwgYygwLCAxZS0xKSx0b2wgPSAxZS05KQ0KSCA8LSB1bmlyb290KGZ1biwgYygwLCAxZS0xKSx0b2wgPSAxZS05KSRyb290ICAjIGJhc2UNCnBIID0gLWxvZzEwKEgpOyBwSCANCg0KDQpsaWJyYXJ5KHJvb3RTb2x2ZSkNCnJvb3RTb2x2ZTo6dW5pcm9vdC5hbGwoZnVuLCBjKC0xZS0xLCAwKSx0b2wgPSAxZS05KQ0Kcm9vdFNvbHZlOjp1bmlyb290LmFsbChmdW4sIGMoMCwxZS0xKSx0b2wgPSAxZS05KQ0KSCA8LSByb290U29sdmU6OnVuaXJvb3QuYWxsKGZ1biwgYygtMWUtMSwgMWUtMSksdG9sID0gMWUtOSkNCnBIID0gLWxvZzEwKEgpOyBwSCANCg0KDQpsaWJyYXJ5KFJtcGZyKQ0KUm1wZnI6OnVuaXJvb3RSKGZ1biwgbG93ZXI9LTFlLTEsIHVwcGVyPTAsIHRvbCA9IDFlLTkpDQpSbXBmcjo6dW5pcm9vdFIoZnVuLCBsb3dlcj0wLCB1cHBlcj0xZS0xLCB0b2wgPSAxZS05KQ0KSCA8LSBSbXBmcjo6dW5pcm9vdFIoZnVuLCBsb3dlcj0wLCB1cHBlcj0xZS0xLCB0b2wgPSAxZS05KSRyb290DQpwSCA9IC1sb2cxMChIKTsgcEggDQoNCmBgYA0KDQoNClRsYWtvdmEgbGFoZXYgcyBveGlkZW0gdWhsaWNpdHltIG9ic2FodWplIDEwLjAga2cgcGx5bnUuIEpha8O9IG9iamVtIHphdWrDrW1hIHN0bGFjZW55IHBseW4sIGtkeXogcHJpIHRlcGxvdGUgMzAgwrBDIGplIHRsYWsgdiBsYWh2aSAxMy4xN2U2IFBhPyBWeXBvY2V0IHByb3ZlZHRlIHBvbW9jaSB2YW4gZGVyIFdhYWxzb3Z5IHJvdm5pY2UuDQoNCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQoNCiMgKHAgKyBhL1ZtXjIpKFZtIC0gYikgPSBSKlQgICAgIA0KIyBbVm0gPSAwLjA3NSBtMy9rbW9sLCBuID0gMC4yMjczIGttb2wsIFYgPSAwLjAxNzEgbTNdDQoNCmxpYnJhcnkobWVhc3VyZW1lbnRzKQ0KcCA9IDEzLjE3ZTYgIyBbUGFdDQptID0gY29udl91bml0KDEwLjAsIGZyb209ImtnIiwgdG89ImciKQ0KdCA9IGNvbnZfdW5pdCgzMCwgZnJvbT0iQyIsIHRvPSJLIikgDQpSID0gOC4zMTQxICAjIFtKIC8gbW9sIEtdDQpSID0gUioxMDAwICAjIFtKIC8ga21vbCBLXQ0KTXIgPSA0NC4wMSAgIyBbZy9tb2xdDQpuID0gbS9NciAgICAjIFttb2xdDQpuID0gbi8xMDAgICAjIFtrbW9sXQ0KDQoNCiMgdnlwb2NldCBwcm8gaWRlYWxuaSBwbHluDQojIHAqVm0gLSBSKlQgPSAwICANClZtID0gUip0L3ANClYgPSBWbSpuOyBWICAjIFttM10NCg0KDQojIHZ5cG9jZXQgcHJvIHJlYWxueSBwbHluDQphID0gMC4zNjVlNiAjIFttNiBQYSAvIGttb2wyXQ0KYiA9IDAuMDQyOCAgIyBbbTMgLyBrbW9sXQ0KIyBWbSoqMyAtIChiICsgUip0L3ApKlZtKioyICsgKGEvcCkqVm0gLSBhKmIvcCANCg0KIyByZWFsbmUgaSBrb21wbGV4bmkga29yZW55DQpsaWJyYXJ5KFJDb25pY3MpIA0KQ0UgPSBjKDEsLShiICsgUip0L3ApLGEvcCwtKGEqYi9wKSkNCngwID0gY3ViaWMoQ0UpOyB4MA0KVm0gPSBSZSh4MFt3aGljaChJbSh4MCk9PTApXSkgICMgW20zIC8ga21vbF0NClZtDQpWID0gVm0qbjsgViAgIyBbbTNdDQoNCiMgamVuIHJlYWxuZSBrb3JlbnkNCmZ1biA8LSBmdW5jdGlvbiAoeCkgQ0VbMV0qeF4zICsgQ0VbMl0qeF4yICsgQ0VbM10qeCArIENFWzRdDQojY3VydmUoZnVuKHgpLC00LDQpDQojYWJsaW5lKGggPSAwLCBsdHkgPSAzKQ0KVm0gPC0gdW5pcm9vdChmdW4sIGMoLTQsIDQpKSRyb290ICAjIGJhc2UNClYgPSBWbSpuOyBWICAjIFttM10NCg0KbGlicmFyeShyb290U29sdmUpDQpWbSA8LSByb290U29sdmU6OnVuaXJvb3QuYWxsKGZ1biwgYygtNCwgNCkpDQpWID0gVm0qbjsgViAgIyBbbTNdDQoNCmxpYnJhcnkoUm1wZnIpDQpWbSA8LSBSbXBmcjo6dW5pcm9vdFIoZnVuLCBsb3dlcj0tNCwgdXBwZXI9NCwgdG9sID0gMWUtOSkkcm9vdA0KViA9IFZtKm47IFYgICMgW20zXQ0KDQojIyBncmFmaWNrZSByZXNlbmkNCiMgQ0UgPSBjKDEsLShiICsgUip0L3ApLGEvcCwtKGEqYi9wKSkNCnh4IDwtIHNlcSgtNCw0LCBieT0wLjAxKQ0KeXkgPC0gQ0VbMV0qeHheMyANCnp6IDwtIC1DRVsyXSp4eF4yIC0gQ0VbM10qeHggLSBDRVs0XQ0KcGxvdCh4eCx5eSx0eXBlPSJsIiwgY29sPTIpDQpwb2ludHMoeHgsenosdHlwZT0ibCIsIGNvbD00KQ0KcGxvdCh4eCwgeXksIHR5cGU9ImwiLGNvbD0yLHhsaW09YygwLjA1LDAuMSkseWxpbT1jKDAsMC4wMDEpKQ0KcG9pbnRzKHh4LCB6eiwgdHlwZT0ibCIsY29sPTQpDQoNCmBgYA0KDQoNCiMjIyBzb3VzdGF2eSBsaW5lYXJuaWNoIHJvdm5pYyAjIyMNCg0KDQpaZSBkdm91IHNsaXRpbiBzIDYwJSBhIDgwJSBvYnNhaGVtIG3Em2RpIHNlIG1hIHrDrXNrYXQgNDAga2cgc2xpdGlueSBzZSA3NSUgb2JzYWhlbSBtxJtkaS4gS29saWsga2cga2HFvmTDqSBzbGl0aW55IGplIHTFmWViYSBwb3XFvsOtdD8gIFsxMCBhIDMwIGtnXQ0KDQpgYGB7cn0NCg0KbGlicmFyeShyb290U29sdmUpDQptb2RlbCA8LSBmdW5jdGlvbih4KXsNCiAgRjEgPC0gMC42KnhbMV0gKyAwLjgqeFsyXSAtIDMwDQogIEYyIDwtIHhbMV0gKyB4WzJdIC0gNDANCiAgYyhGMSA9IEYxLCBGMiA9IEYyKX0NCnNzIDwtIG11bHRpcm9vdChmID0gbW9kZWwsIHN0YXJ0ID0gYygxLCAxKSkNCnNzJHJvb3QNCg0KIyMjIGdyYWZpY2tlIHJlc2VuaQ0KIyAwLjYqbTEgKyAwLjgqbTIgPSA0MCowLjc1ID0+IG0xID0gNDAqMC43NS8wLjYgLSAwLjgvMC42ICogbTIgID0+IG0xID0gNTAgLSAxLjMzICogbTIgDQojIG0xICsgbTIgPSA0MCAgPT4gbTEgPSA0MCAtIG0yDQp4eCA9IHNlcSgwLDUwLDAuMSkNCnl5ID0gNTAgLSAxLjMzKnh4DQp6eiA9IDQwIC0geHgNCnBsb3QoeHgsIHl5LCB0eXBlPSJsIixjb2w9MikNCnBvaW50cyh4eCwgenosIHR5cGU9ImwiLGNvbD00KQ0KcGxvdCh4eCwgeXksIHR5cGU9ImwiLGNvbD0yLHhsaW09YygyNSwzNSkseWxpbT1jKDAsMjApKQ0KcG9pbnRzKHh4LCB6eiwgdHlwZT0ibCIsY29sPTQpDQoNCmBgYA0KDQoNCkRvIGJhemVudSBuYXRlY2UgcHJ1dG9rZW0gQSB6YSAzIGggYSBwcnV0b2tlbSBCIHphIDQgaCBjZWxrZW0gMjE1MCBobCB2b2R5LiBQcnV0b2tlbSBBIHphIDQgaCBhIHBydXRva2VtIEIgemEgMiBoIGJ5IG5hdGVrbG8gMTcwMCBobCB2b2R5LiBLb2xpayBobCB2b2R5IG5hdGVjZSBwcnV0b2tlbSBBIGEga29saWsgcHJ1dG9rZW0gQiB6YSAxIGhvZGludT8gICAgICBBIDI1MCBobCwgQiAzNTAgaGwNCg0KYGBge3J9DQoNCmxpYnJhcnkocm9vdFNvbHZlKQ0KbW9kZWwgPC0gZnVuY3Rpb24oeCl7DQogIEYxIDwtIDMqeFsxXSArIDQqeFsyXSAtIDIxNTANCiAgRjIgPC0gNCp4WzFdICsgMip4WzJdIC0gMTcwMA0KICBjKEYxID0gRjEsIEYyID0gRjIpfQ0Kc3MgPC0gbXVsdGlyb290KGYgPSBtb2RlbCwgc3RhcnQgPSBjKDEsIDEpKQ0Kc3Mkcm9vdA0KDQojIyMgZ3JhZmlja2UgcmVzZW5pDQojIDMqbTEgKyA0Km0yID0gMjE1MCA9PiBtMiA9IDIxNTAvNCAtIDMvNCAqIG0xICA9PiBtMiA9IDUzNy41IC0gMC43NSAqIG0xDQojIDQqbTEgKyAyKm0yID0gMTcwMCA9PiBtMiA9IDE3MDAvMiAtIDQvMiAqIG0xID0+IG0yID0gODUwIC0gMiAqIG0xDQp4eCA9IHNlcSgwLDUwMCwxKQ0KeXkgPSA1MzcuNSAtIDAuNzUqeHgNCnp6ID0gODUwIC0gMip4eA0KcGxvdCh4eCwgeXksIHR5cGU9ImwiLGNvbD0yKQ0KcG9pbnRzKHh4LCB6eiwgdHlwZT0ibCIsY29sPTQpDQpwbG90KHh4LCB5eSwgdHlwZT0ibCIsY29sPTIseGxpbT1jKDIwMCwzMDApLHlsaW09YygzMDAsNDAwKSkNCnBvaW50cyh4eCwgenosIHR5cGU9ImwiLGNvbD00KQ0KDQpgYGANCg0KDQpaZSBkdm91IGRydWh1IGNhamUgdiBjZW5lIDE2MCBLYyBhIDIyMCBLYyB6YSAxIGtnIGplIHRyZWJhIHByaXByYXZpdCAyMCBrZyBzbWVzaSB2IGNlbmUgMjA1IEtjIHphIDEga2cuIEtvbGlrIGtnIGthemRlaG8gY2FqZSBqZSB0cmViYSBzbWljaGF0PyAgIDUga2cgbGV2bmVqc2lobyBhIDE1IGtnIGRyYXpzaWhvIA0KDQpgYGB7cn0NCg0KbGlicmFyeShyb290U29sdmUpICAgIyMjIG9wcmF2aXQgemFkYW5pDQptb2RlbCA8LSBmdW5jdGlvbih4KXsNCiAgRjEgPC0gMTYwKnhbMV0gKyAyMjAqeFsyXSAtIDQxMDANCiAgRjIgPC0geFsxXSArIHhbMl0gLSAyMA0KICBjKEYxID0gRjEsIEYyID0gRjIpfQ0Kc3MgPC0gbXVsdGlyb290KGYgPSBtb2RlbCwgc3RhcnQgPSBjKDEsIDEpKQ0Kc3Mkcm9vdA0KDQojIyMgZ3JhZmlja2UgcmVzZW5pDQojIDE2MCptMSArIDIyMCptMiA9IDQxMDAgPT4gbTEgPSA0MTAwLzE2MCAtIDIyMC8xNjAgKiBtMiAgPT4gbTEgPSAyNS42MjUgLSAxLjM3NSAqIG0yDQojIG0xICsgbTIgPSAyMCA9PiBtMSA9IDIwIC0gbTINCnh4ID0gc2VxKDAsMjAsMC4xKQ0KeXkgPSAyNS42MjUgLSAxLjM3NSp4eA0KenogPSAyMCAtIHh4DQpwbG90KHh4LCB5eSwgdHlwZT0ibCIsY29sPTIpDQpwb2ludHMoeHgsIHp6LCB0eXBlPSJsIixjb2w9NCkNCnBsb3QoeHgsIHl5LCB0eXBlPSJsIixjb2w9Mix4bGltPWMoMTAsMjApLHlsaW09YygwLDEwKSkNCnBvaW50cyh4eCwgenosIHR5cGU9ImwiLGNvbD00KQ0KDQpgYGANCg0KDQpLb2xpayBnIDYwJSBhIGtvbGlrIGcgMzAlIHJvenRva3UgTmFDbCBqZSB0cmViYSBzbWljaGF0IHByaSBwcmlwcmF2ZSAxMDAgZyA0MCUgcm96dG9rdT8gMjAgZyA2MCUgYSBhIDgwIGcgMzUlDQoNCmBgYHtyfQ0KDQpsaWJyYXJ5KHJvb3RTb2x2ZSkNCm1vZGVsIDwtIGZ1bmN0aW9uKHgpew0KICBGMSA8LSAwLjYqeFsxXSArIDAuMyp4WzJdIC0gNDANCiAgRjIgPC0geFsxXSArIHhbMl0gLSAxMDANCiAgYyhGMSA9IEYxLCBGMiA9IEYyKX0NCnNzIDwtIG11bHRpcm9vdChmID0gbW9kZWwsIHN0YXJ0ID0gYygxLCAxKSkNCnNzJHJvb3QNCg0KIyMjIGdyYWZpY2tlIHJlc2VuaQ0KIyAwLjYqbTEgKyAwLjMqbTIgPSAxMDAqMC40ID0+IG0xID0gNDAvMC42IC0gMC4zLzAuNiAqIG0yICA9PiBtMSA9IDY2LjY3IC0gMC41ICogbTIgDQojIG0xICsgbTIgPSAxMDAgID0+IG0xID0gMTAwIC0gbTINCnh4ID0gc2VxKDAsMTAwLDAuMSkNCnl5ID0gNjYuNjcgLSAwLjUqeHgNCnp6ID0gMTAwIC0geHgNCnBsb3QoeHgsIHl5LCB0eXBlPSJsIixjb2w9MikNCnBvaW50cyh4eCwgenosIHR5cGU9ImwiLGNvbD00KQ0KcGxvdCh4eCwgeXksIHR5cGU9ImwiLGNvbD0yLHhsaW09Yyg2NSw3MCkseWxpbT1jKDMwLDQwKSkNCnBvaW50cyh4eCwgenosIHR5cGU9ImwiLGNvbD00KQ0KDQojIyMgbWF0aWNlDQoNCkIgPSBjKDAuNDAqMTAwLDEwMCkgIyBbbWddDQpuYW1lcyhCKSA9IGMoIjYwJSIsIjMwJSIpDQpyMSA9IGMoMC42MCwxKSAjIFttZ10NCnIyID0gYygwLjMwLDEpICMgW21nXQ0KQSA9IGNiaW5kKHIxLHIyKQ0KY29sbmFtZXMoQSkgPSBjKCI2MCUiLCIzMCUiKQ0Kcm93bmFtZXMoQSkgPSBjKCJyMzAiLCJyMyIpDQpkZXQoQSkgIyBtYXRpY2UgamUgcmVndWxhcm5pIG4gPSBoDQpsaWJyYXJ5KG1hdGxpYikNCmMoUihBKSwgUihjYmluZChBLEIpKSkgICAgICAgICAgIyBzaG93IHJhbmtzDQphbGwuZXF1YWwoUihBKSwgUihjYmluZChBLEIpKSkgICMgY29uc2lzdGVudD8NCnNob3dFcW4oQSwgQikNCm1hdGxpYjo6U29sdmUoQSwgQikNCmxpbVNvbHZlOjpTb2x2ZShBLCBCKQ0KIw0KbGlicmFyeShsaW1Tb2x2ZSkNCkcgPC1tYXRyaXgobmNvbCA9IDIsIGJ5cm93ID0gVFJVRSwgZGF0YSA9IGMoMSwgMCwgMCwgMSkpIA0KSCA8LSBjKDAsIDApDQpsZGVpKEEsIEIsIEcgPSBHLCBIID0gSCkkWA0KIw0KbGlicmFyeShjbW5hKSANCmdkbHMoQSwgQiwgYWxwaGEgPSAwLjA1LCB0b2wgPSAxZS0wNiwgbSA9IDFlKzA1KSAjICBsZWFzdCBzcXVhcmVzIHdpdGggZ3JhaWRlbnQgZGVzY2VudA0KamFjb2JpKEEsIEIsIHRvbCA9IDFlLTA2LCBtYXhpdGVyID0gMTAwKSAgIyBpdGVyYXRpdmVtYXRyaXgNCmdhdXNzc2VpZGVsKEEsIEIsIHRvbCA9IDFlLTA2LCBtYXhpdGVyID0gMTAwKSAjIGl0ZXJhdGl2ZW1hdHJpeA0Kc29sdmVtYXRyaXgoQSwgQikgIyByZWZtYXRyaXgNCg0KYGBgDQoNCg0KWmUgZHZvdSBrb3Z1IG8gaHVzdG90YWNoIDcuNCBnL2NtMyBhIDguMiBnL2NtMyBqZSB0cmViYSBwcmlwcmF2aXQgMC41IGtnIHNsaXRpbnkgbyBodXN0b3RlIDcuNiBnL2NtMy4gS29saWsgZyBrYXpkaWhvIHoga292dSBqZSBrIHRvbXUgcG90cmViYT8gMzc1IGcgbGVoY2lobyBhIDEyNSBnIHRlenNpaG8NCg0KYGBge3J9DQoNCmxpYnJhcnkocm9vdFNvbHZlKQ0KbW9kZWwgPC0gZnVuY3Rpb24oeCl7DQogIEYxIDwtIDcuNCp4WzFdICsgOC4yKnhbMl0gLSAzODAwDQogIEYyIDwtIHhbMV0gKyB4WzJdIC0gNTAwDQogIGMoRjEgPSBGMSwgRjIgPSBGMil9DQpzcyA8LSBtdWx0aXJvb3QoZiA9IG1vZGVsLCBzdGFydCA9IGMoMSwgMSkpDQpzcyRyb290ICAjIFtrZ10NCg0KIyMjIGdyYWZpY2tlIHJlc2VuaQ0KIyA3LjQqbTEgKyA4LjIqbTIgPSAwLjUqNy42ID0+IG0xID0gMzgwMC83LjQgLSA4LjIvNy40ICogbTIgID0+IG0xID0gNTEzLjUgLSAxLjEwOCAqIG0yIA0KIyBtMSArIG0yID0gNTAwICA9PiBtMSA9IDUwMCAtIG0yDQp4eCA9IHNlcSgwLDUwMCwxKQ0KeXkgPSA1MTMuNSAtIDEuMTA4Knh4DQp6eiA9IDUwMCAtIHh4DQpwbG90KHh4LCB5eSwgdHlwZT0ibCIsY29sPTIpDQpwb2ludHMoeHgsIHp6LCB0eXBlPSJsIixjb2w9NCkNCnBsb3QoeHgsIHl5LCB0eXBlPSJsIixjb2w9Mix4bGltPWMoMTAwLDE1MCkseWxpbT1jKDM1MCw0MDApKQ0KcG9pbnRzKHh4LCB6eiwgdHlwZT0ibCIsY29sPTQpDQoNCiMjIyBtYXRpY2UNCkIgPSBjKDcuNiwxKSAjIFttZ10NCm5hbWVzKEIpID0gYygia292MSIsImtvdjIiKQ0KcjEgPSBjKDcuNCwxKSAjIFttZ10NCnIyID0gYyg4LjIsMSkgIyBbbWddDQpBID0gY2JpbmQocjEscjIpDQpjb2xuYW1lcyhBKSA9IGMoImtvdjEiLCJrb3YyIikNCnJvd25hbWVzKEEpID0gYygiNy40IiwiOC4yIikNCmRldChBKSAjIG1hdGljZSBqZSByZWd1bGFybmkgbiA9IGgNCmxpYnJhcnkobWF0bGliKQ0KYyhSKEEpLCBSKGNiaW5kKEEsQikpKSAgICAgICAgICAjIHNob3cgcmFua3MNCmFsbC5lcXVhbChSKEEpLCBSKGNiaW5kKEEsQikpKSAgIyBjb25zaXN0ZW50Pw0Kc2hvd0VxbihBLCBCKQ0KcnIgPSBtYXRsaWI6OlNvbHZlKEEsIEIpDQpyZWFkLnRhYmxlKHRleHQgPSByclsxXSwgZmlsbCA9IFRSVUUpW1szXV0qNTAwICMgW2ddDQpyZWFkLnRhYmxlKHRleHQgPSByclsyXSwgZmlsbCA9IFRSVUUpW1szXV0qNTAwICMgW2ddDQpyciA9IGxpbVNvbHZlOjpTb2x2ZShBLCBCKQ0KcnIqNTAwICMgW2ddDQojIA0KbGlicmFyeShsaW1Tb2x2ZSkNCkcgPC1tYXRyaXgobmNvbCA9IDIsIGJ5cm93ID0gVFJVRSwgZGF0YSA9IGMoMSwgMCwgMCwgMSkpIA0KSCA8LSBjKDAsIDApDQpyciA9IGxkZWkoQSwgQiwgRyA9IEcsIEggPSBIKSRYDQpycio1MDAgIyBbZ10NCg0KYGBgDQoNCg0KViB0ZXBlbG7DqSBlbGVrdHLDoXJuZSBtYWrDrSB6w6Fzb2J1IHVobMOtLCBrdGVyw6EgdnlzdGFjw60gbmEgMjQgZG7DrSwgYnVkZS1saSB2IGNpbm5vc3RpIHBvdXplIHBydm7DrSBibG9rLCBuYSAzMCBkbsOtLCBidWRlLWxpIHYgcHJvdm96dSBwb3V6ZSAyLiBibG9rIGEgbmEgMjAgZG7DrSwgYnVkZS1saSB2IHByb3ZvenUgcG91emUgMy4gYmxvay4gTmEgamFrIGRsb2hvIHZ5c3RhY8OtIHrDoXNvYmEsIGJ1ZG91LWxpIHYgcHJvdm96dSB2c2VjaG55IGJsb2t5IG5hamVkbm91Pw0KDQpgYGB7cn0NCg0KIyB4LzI0ICsgeC8zMCArIHgvMjAgPSAxDQoNCmxpYnJhcnkoUnlhY2FzKQ0KdnIgPC0geXN5bSgieC8yNCArIHgvMzAgKyB4LzIwIC0gMSIpIA0Kc29sdmUodnIsICJ4IikgDQoNCmZ1biA8LSBmdW5jdGlvbiAoeCkgeC8yNCArIHgvMzAgKyB4LzIwIC0gMQ0KdW5pcm9vdChmdW4sIGMoMCwgMSksZXh0ZW5kSW50ID0gInllcyIsIHRvbCA9IDFlLTkpJHJvb3QNCg0KYGBgDQo=