Fernando Deeke Sasse
CCT - UDESC

  1. Permutação e computação de probabilidades por meio de contagem

Façamos uma permutação (ou arranjo) de 4 números, 3,4,5,6 em grupos de 3 elementos. De modo mais concreto, se temos uma caixa com 4 bolas marcadas com estes números, quais são os possíveis resultados ao selecionarmos 3 bolas aleatóriamente?
m <- permutations(4,3,c(3,4,5,6))
Error in permutations(4, 3, c(3, 4, 5, 6)) : 
  could not find function "permutations"

Notemos que uma ou mais linhas específicas de m podem ser obtidas da seguinte maneira. Por exemplo, selecionemos as linhas 12,13 e 14:

Podemos também usar um vetor de strings:

m <- permutations(4,3,c("branca","preta","azul","vermelha"))
m
      [,1]       [,2]       [,3]      
 [1,] "azul"     "branca"   "preta"   
 [2,] "azul"     "branca"   "vermelha"
 [3,] "azul"     "preta"    "branca"  
 [4,] "azul"     "preta"    "vermelha"
 [5,] "azul"     "vermelha" "branca"  
 [6,] "azul"     "vermelha" "preta"   
 [7,] "branca"   "azul"     "preta"   
 [8,] "branca"   "azul"     "vermelha"
 [9,] "branca"   "preta"    "azul"    
[10,] "branca"   "preta"    "vermelha"
[11,] "branca"   "vermelha" "azul"    
[12,] "branca"   "vermelha" "preta"   
[13,] "preta"    "azul"     "branca"  
[14,] "preta"    "azul"     "vermelha"
[15,] "preta"    "branca"   "azul"    
[16,] "preta"    "branca"   "vermelha"
[17,] "preta"    "vermelha" "azul"    
[18,] "preta"    "vermelha" "branca"  
[19,] "vermelha" "azul"     "branca"  
[20,] "vermelha" "azul"     "preta"   
[21,] "vermelha" "branca"   "azul"    
[22,] "vermelha" "branca"   "preta"   
[23,] "vermelha" "preta"    "azul"    
[24,] "vermelha" "preta"    "branca"  

Como vemos da matriz de saída em qualquer um dos casos acima, o número de modos é 24, que pode ser obtido diretamente contando o número de linhas de m:

n <- nrow(m)
n
[1] 24

Façamos 5 amostragens. Para isso inicialmente escolhemos aleatóriamente 4 números entre os n=24:

indice <- sample(n,4)
indice
[1]  5  4 19  6

Cada uma destas cinco escolhas corresponde a um resultado de um experimento:

m[indice,]
     [,1]       [,2]       [,3]      
[1,] "azul"     "vermelha" "branca"  
[2,] "azul"     "preta"    "vermelha"
[3,] "vermelha" "azul"     "branca"  
[4,] "azul"     "vermelha" "preta"   

A probabilidade de numa amostragem obtermos a bola azul é obviamente 1/4 que corresponde a 6/24 no experimento que consiste em coletar 3 bolas aleatoriamente. S

Suponhamos adicionamos agora mais uma bola branca ao conjunto original de 4 bolas. Verifiquemos agora as possibilidades correspondentes à seleção de 3 bolas:

bolas = c("branca1","preta","azul","vermelha", "branca2")
m <- permutations(5,3,bolas)
m
      [,1]       [,2]       [,3]      
 [1,] "azul"     "branca1"  "branca2" 
 [2,] "azul"     "branca1"  "preta"   
 [3,] "azul"     "branca1"  "vermelha"
 [4,] "azul"     "branca2"  "branca1" 
 [5,] "azul"     "branca2"  "preta"   
 [6,] "azul"     "branca2"  "vermelha"
 [7,] "azul"     "preta"    "branca1" 
 [8,] "azul"     "preta"    "branca2" 
 [9,] "azul"     "preta"    "vermelha"
[10,] "azul"     "vermelha" "branca1" 
[11,] "azul"     "vermelha" "branca2" 
[12,] "azul"     "vermelha" "preta"   
[13,] "branca1"  "azul"     "branca2" 
[14,] "branca1"  "azul"     "preta"   
[15,] "branca1"  "azul"     "vermelha"
[16,] "branca1"  "branca2"  "azul"    
[17,] "branca1"  "branca2"  "preta"   
[18,] "branca1"  "branca2"  "vermelha"
[19,] "branca1"  "preta"    "azul"    
[20,] "branca1"  "preta"    "branca2" 
[21,] "branca1"  "preta"    "vermelha"
[22,] "branca1"  "vermelha" "azul"    
[23,] "branca1"  "vermelha" "branca2" 
[24,] "branca1"  "vermelha" "preta"   
[25,] "branca2"  "azul"     "branca1" 
[26,] "branca2"  "azul"     "preta"   
[27,] "branca2"  "azul"     "vermelha"
[28,] "branca2"  "branca1"  "azul"    
[29,] "branca2"  "branca1"  "preta"   
[30,] "branca2"  "branca1"  "vermelha"
[31,] "branca2"  "preta"    "azul"    
[32,] "branca2"  "preta"    "branca1" 
[33,] "branca2"  "preta"    "vermelha"
[34,] "branca2"  "vermelha" "azul"    
[35,] "branca2"  "vermelha" "branca1" 
[36,] "branca2"  "vermelha" "preta"   
[37,] "preta"    "azul"     "branca1" 
[38,] "preta"    "azul"     "branca2" 
[39,] "preta"    "azul"     "vermelha"
[40,] "preta"    "branca1"  "azul"    
[41,] "preta"    "branca1"  "branca2" 
[42,] "preta"    "branca1"  "vermelha"
[43,] "preta"    "branca2"  "azul"    
[44,] "preta"    "branca2"  "branca1" 
[45,] "preta"    "branca2"  "vermelha"
[46,] "preta"    "vermelha" "azul"    
[47,] "preta"    "vermelha" "branca1" 
[48,] "preta"    "vermelha" "branca2" 
[49,] "vermelha" "azul"     "branca1" 
[50,] "vermelha" "azul"     "branca2" 
[51,] "vermelha" "azul"     "preta"   
[52,] "vermelha" "branca1"  "azul"    
[53,] "vermelha" "branca1"  "branca2" 
[54,] "vermelha" "branca1"  "preta"   
[55,] "vermelha" "branca2"  "azul"    
[56,] "vermelha" "branca2"  "branca1" 
[57,] "vermelha" "branca2"  "preta"   
[58,] "vermelha" "preta"    "azul"    
[59,] "vermelha" "preta"    "branca1" 
[60,] "vermelha" "preta"    "branca2" 

Temos agora 60 possibilidades:

n <- nrow(m)
n
[1] 60

Definimos as colunas:

primeira_bola <- m[,1]
segunda_bola <- m[,2]
terceira_bola <- m[,3]
  1. Em quais casos a primeira bola é azul?
h<-primeira_bola %in% "azul"
h
 [1]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE
[16] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[31] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[46] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

Obviamente isso acontece 12 vezes:

sum(h)
[1] 12
  1. Em quais casos a primeira bola é branca? Note que a primeira bola é branca quando selecionamos a bola branca1 ou a bola branca2, de modo que o número deve ser 24. Para sistematizar isso definimos o vetor:
brancas<- c("branca1", "branca2")

Portanto,

h<-primeira_bola %in% brancas
h
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE
[16]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
[31]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[46] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

Obviamente isso acontece 24 vezes:

sum(h)
[1] 24
  1. Qual é a probabilidade de que a primeira bola seja branca ou azul?
N<-sum((primeira_bola %in% brancas) | primeira_bola %in% "azul")
N
[1] 36

A probabilidade é dada por

p=N/n
p
[1] 0.6
  1. Qual é a probabilidade de que a primeira bola seja branca e a terceira azul?
N<-sum((primeira_bola %in% brancas) & terceira_bola %in% "azul")
N
[1] 6

A probabilidade é dada por

p=N/n
p
[1] 0.1

Exercício 1.1 Em uma caixa temos 2 bolas brancas, 3 azuis, uma preta, uma vermelha e uma amarela. Qual é a probabilidade de que em uma amostragem na qual selecionamos 4 bolas obtenhamos a primeira bola amarela, a segunda branca, a terceira e quarta azuis?

Solução. Definimos nosso conjunto de bolas e exibimos o conjunto de todas as possíveis permutações (arranjos):

bolas = c("branca1", "branca2","preta","azul1","azul2", "azul3", "vermelha", "amarela")
m <- permutations(8,4,bolas)
n <- nrow(m)
n
[1] 1680

Temos portanto 1680 possibilidades. Mostramos abaixo seis delas:

head(m)
     [,1]      [,2]    [,3]    [,4]      
[1,] "amarela" "azul1" "azul2" "azul3"   
[2,] "amarela" "azul1" "azul2" "branca1" 
[3,] "amarela" "azul1" "azul2" "branca2" 
[4,] "amarela" "azul1" "azul2" "preta"   
[5,] "amarela" "azul1" "azul2" "vermelha"
[6,] "amarela" "azul1" "azul3" "azul2"   

Definimos as colunas:

primeira_bola <- m[,1]
segunda_bola <- m[,2]
terceira_bola <- m[,3]
quarta_bola <- m[,4]

Vejamos quantos eventos resultam em “primeira bola amarela, a segunda branca, a terceira ou quarta azuis”. Definimos antes os conjuntos de bolas brancas e azuis:

brancas<- c("branca1", "branca2")
azuis<- c("azul1","azul2", "azul3")

Portanto,

N<-sum((primeira_bola %in% "amarela") & (segunda_bola %in% brancas) & (terceira_bola %in% azuis | quarta_bola %in% azuis))      
N
[1] 48

Portanto, a probabilidade do evento especificado ocorrer é dada por

p <- N/n
p
[1] 0.02857143

Exercício 1.2 Em uma caixa temos 2 bolas brancas, 3 azuis, uma preta, uma vermelha e uma amarela. Qual é a probabilidade de que em uma amostragem na qual selecionamos 2 bolas obtenhamos as duas primeiras bolas azuis?

Solução. Definimos nosso conjunto de bolas e exibimos o conjunto de todas as possíveis permutações (arranjos):

bolas = c("branca1", "branca2","preta","azul1","azul2", "azul3", "vermelha", "amarela")
m <- permutations(8,2,bolas)
n <- nrow(m)
n
[1] 56

Temos portanto 56 possibilidades. Definimos as colunas:

primeira_bola <- m[,1]
segunda_bola <- m[,2]

Vejamos quantos eventos resultam em “primeira bola azul e segunda azul”:

azuis<- c("azul1","azul2", "azul3")

Portanto,

N<-sum((primeira_bola %in% azuis) & (segunda_bola %in% azuis))      
N
[1] 6

Portanto, a probabilidade do evento especificado ocorrer é dada por

p <- N/n
p
[1] 0.1071429

  1. Combinações

Quando num processo de amostragem, no caso dos exemplos acima, a ordem dos eventos não é importante, podemos usar combinações. Notemos a diferença entre permutaçôes, onde a ordem importa,
permutations(3,2)
     [,1] [,2]
[1,]    1    2
[2,]    1    3
[3,]    2    1
[4,]    2    3
[5,]    3    1
[6,]    3    2

e combinações, onde a ordem não importa:

combinations(3,2)
     [,1] [,2]
[1,]    1    2
[2,]    1    3
[3,]    2    3

Exemplo 2.1 Suponhamos que uma caixa temos 2 bolas brancas, 3 azuis, uma preta, uma vermelha e uma amarela. Qual é a probabilidade de que numa seleção de 4 bolas obtenhamos 2 bolas azuis e uma bola amarela?

Solução. Definimos nosso conjunto de bolas e exibimos o conjunto de todas as possíveis combinações:

bolas = c("branca1", "branca2","preta","azul1","azul2", "azul3", "vermelha", "amarela")
m <- combinations(8,4,bolas)
m
      [,1]      [,2]      [,3]      [,4]      
 [1,] "amarela" "azul1"   "azul2"   "azul3"   
 [2,] "amarela" "azul1"   "azul2"   "branca1" 
 [3,] "amarela" "azul1"   "azul2"   "branca2" 
 [4,] "amarela" "azul1"   "azul2"   "preta"   
 [5,] "amarela" "azul1"   "azul2"   "vermelha"
 [6,] "amarela" "azul1"   "azul3"   "branca1" 
 [7,] "amarela" "azul1"   "azul3"   "branca2" 
 [8,] "amarela" "azul1"   "azul3"   "preta"   
 [9,] "amarela" "azul1"   "azul3"   "vermelha"
[10,] "amarela" "azul1"   "branca1" "branca2" 
[11,] "amarela" "azul1"   "branca1" "preta"   
[12,] "amarela" "azul1"   "branca1" "vermelha"
[13,] "amarela" "azul1"   "branca2" "preta"   
[14,] "amarela" "azul1"   "branca2" "vermelha"
[15,] "amarela" "azul1"   "preta"   "vermelha"
[16,] "amarela" "azul2"   "azul3"   "branca1" 
[17,] "amarela" "azul2"   "azul3"   "branca2" 
[18,] "amarela" "azul2"   "azul3"   "preta"   
[19,] "amarela" "azul2"   "azul3"   "vermelha"
[20,] "amarela" "azul2"   "branca1" "branca2" 
[21,] "amarela" "azul2"   "branca1" "preta"   
[22,] "amarela" "azul2"   "branca1" "vermelha"
[23,] "amarela" "azul2"   "branca2" "preta"   
[24,] "amarela" "azul2"   "branca2" "vermelha"
[25,] "amarela" "azul2"   "preta"   "vermelha"
[26,] "amarela" "azul3"   "branca1" "branca2" 
[27,] "amarela" "azul3"   "branca1" "preta"   
[28,] "amarela" "azul3"   "branca1" "vermelha"
[29,] "amarela" "azul3"   "branca2" "preta"   
[30,] "amarela" "azul3"   "branca2" "vermelha"
[31,] "amarela" "azul3"   "preta"   "vermelha"
[32,] "amarela" "branca1" "branca2" "preta"   
[33,] "amarela" "branca1" "branca2" "vermelha"
[34,] "amarela" "branca1" "preta"   "vermelha"
[35,] "amarela" "branca2" "preta"   "vermelha"
[36,] "azul1"   "azul2"   "azul3"   "branca1" 
[37,] "azul1"   "azul2"   "azul3"   "branca2" 
[38,] "azul1"   "azul2"   "azul3"   "preta"   
[39,] "azul1"   "azul2"   "azul3"   "vermelha"
[40,] "azul1"   "azul2"   "branca1" "branca2" 
[41,] "azul1"   "azul2"   "branca1" "preta"   
[42,] "azul1"   "azul2"   "branca1" "vermelha"
[43,] "azul1"   "azul2"   "branca2" "preta"   
[44,] "azul1"   "azul2"   "branca2" "vermelha"
[45,] "azul1"   "azul2"   "preta"   "vermelha"
[46,] "azul1"   "azul3"   "branca1" "branca2" 
[47,] "azul1"   "azul3"   "branca1" "preta"   
[48,] "azul1"   "azul3"   "branca1" "vermelha"
[49,] "azul1"   "azul3"   "branca2" "preta"   
[50,] "azul1"   "azul3"   "branca2" "vermelha"
[51,] "azul1"   "azul3"   "preta"   "vermelha"
[52,] "azul1"   "branca1" "branca2" "preta"   
[53,] "azul1"   "branca1" "branca2" "vermelha"
[54,] "azul1"   "branca1" "preta"   "vermelha"
[55,] "azul1"   "branca2" "preta"   "vermelha"
[56,] "azul2"   "azul3"   "branca1" "branca2" 
[57,] "azul2"   "azul3"   "branca1" "preta"   
[58,] "azul2"   "azul3"   "branca1" "vermelha"
[59,] "azul2"   "azul3"   "branca2" "preta"   
[60,] "azul2"   "azul3"   "branca2" "vermelha"
[61,] "azul2"   "azul3"   "preta"   "vermelha"
[62,] "azul2"   "branca1" "branca2" "preta"   
[63,] "azul2"   "branca1" "branca2" "vermelha"
[64,] "azul2"   "branca1" "preta"   "vermelha"
[65,] "azul2"   "branca2" "preta"   "vermelha"
[66,] "azul3"   "branca1" "branca2" "preta"   
[67,] "azul3"   "branca1" "branca2" "vermelha"
[68,] "azul3"   "branca1" "preta"   "vermelha"
[69,] "azul3"   "branca2" "preta"   "vermelha"
[70,] "branca1" "branca2" "preta"   "vermelha"

Todas as 70 possibilidades estão listadas acima. De fato,

n <- nrow(m)
n
[1] 70

Definimos as colunas:

primeira_bola <- m[,1]
segunda_bola <- m[,2]
terceira_bola <- m[,3]
quarta_bola <- m[,4]

No caso de permutações tínhamos um espaço amostral de 1680 eventos. Vejamos quantos eventos resultam em “duas azuis”.

azuis <- c("azul1", "azul2", "azul3")

Para cada linha de um a n verificamos se o número de ocorrências de azul é igual a 2:

for(i in 1:n){
   a[i] <- sum(m[i,] %in% azuis) == 2 
}
print(a[1:n])
 [1] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
[16]  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[31] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
[46]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE
[61]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

Portanto o número de vezes em que temos 2 bolas azuis é dado por

N<-sum(a[1:n])
N
[1] 30

A probabilidade deste evento é dada por

p=N/n
p
[1] 0.4285714

Exemplo 2.2

Qual é a probabilidade no problema anterior, de encontrarmos duas bolas azuis e uma amarela?

Para cada linha de um a n verificamos se o número de ocorrências de azul é igual a 2 e o de amarelas é igual a 1:

for(i in 1:n){
   a[i] <- sum(m[i,] %in% azuis) == 2 & sum(m[i,] %in% "amarela")==1
}
print(a[1:n])
 [1] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
[16]  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[31] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[46] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[61] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

Portanto o número de vezes em que temos 2 bolas azuis e uma amarela é dado por

N<-sum(a[1:n])
N
[1] 12

A probabilidade deste evento é dada por

p=N/n
p
[1] 0.1714286

  1. Simulação de Monte Carlo

3.1 Introdução

Um modo diferente de calcular probabilidades é por meio de experimentos computacionais. Ilustraremos esta ideia usando o chamado método de simulação de Monte Carlo. Para uma abordagem mais detalhada deste assunto veja, por exemplo as referências [1,2,3,4].

Um modelo utilizado frequentemente para ilustrar os conceitos de inferência estatística é o do caixa. Um exemplo simples de variável aleatória é aquele que resulta quando retiramos um ticket de uma caixa (sem olhar ou aleatoriamente). Por exemplo, o lançamento de uma moeda e a determinação do lado que resulta para cima, cara (H) ou coroa (T), pode ser representado pela retirada de um ticket de uma caixa que contém dois tickets, um marcado com H e outro com T. Denotemos a caixa pelo seu conteúdo, [H,T].

Se aleatoriamente apanhamos um ticket da caixa [H,T] o ticket retirado pode ser H ou T com igual probabilidade. Suponhamos que o ticket retirado resultou ser H. Se não devolvemos o ticket original então a caixa será agora [ ,T] e se tirarmos outro ticket da caixa, então ele será T, com certeza. Se devolvermos o ticket H à caixa, então a caixa voltará a ser [H,T] novamente e uma nova retirda poderá resultar em H ou T, com igual probabilidade. Em outras palavras, se não fizermos substituição, a segunda retirada será dependente da primeira. Se fizermos substituição, a segunda retirada será independente da primeira.

O processo de substituição correponde a termos uma caixa com um número muito grande de tickets marcados H e T (em número igual). Se fizermos duas retiradas, a segunda será praticamente independente da primeira.

Criaremos tal caixa em R a seguir:

Caixa <- c("H", "T")
Caixa
[1] "H" "T"

Simulemos a retirada de 5 tickets vezes da caixa, com subtituição. Equivalentemente, poderíamos imaginar o lançamento de uma moeda 5 vezes para observar o resultado cara (H) ou coroa (T).

# Retirada de tickets da caixa
sample(x = Caixa, size = 5, replace = TRUE)
[1] "H" "H" "T" "T" "H"

Cada vez que o comando acima for executado um resultado diferente será obtido.

Os argumentos da função sample são: 1. O objeto a ser amostrado; 2. O tamanho da amostra; 3. Se a amostragem é com substituição ou não.

Ao usarmos replace = TRUE estamos supondo que todas as amostragens são independentes. Isso é equivalente à amostragem de uma população muito grande. Se replace = False (default) as amostragens não são independentes. Neste caso, se o tamanho da amostragem for maior do o número de elementos na caixa teremos um erro.

Embora cada vez que o comando sample seja executado uma diferente sequência de resultados seja gerada, em algumas situações, desejamos que uma dada simulação seja reprodutível, ou seja, que as diferentes sequêncais de resultados sempre sejam as mesmas. Para isso procedemos do seguinto modo:

set.seed(30) # para reproducibilidade
sample(Caixa, 5, replace = TRUE)
[1] "H" "H" "H" "H" "H"

Cada vez que o bloco acima for executado o resultado será o mesmo. O bloco abaixo dará um resultado diferente, mas que será sempre este, caso seja executado do bloco acima.

sample(Caixa, 5, replace = TRUE)
[1] "T" "H" "T" "T" "H"

Em uma simulação estabelecemos as regras de uma processo aleatório. Os números aleatórios gerados no computador resultam numa saída de acordo com tais regras.

Exemplo 3.1

Simulemos o experimento que consiste em retirar de uma caixa uma bola que contém bolas pretas e brancas.

O vetor caixa representa a caixa com as duas bolas, uma preta, outra branca. A função sample() realiza o experimento que consiste em retirar aleatóriamente uma bola da caixa e informar se o resultado é preta ou branca. A opção size=1 indica que só um experimento é realizado. A opção replace = TRUE aqui não faz diferença no caso de um experimento, mas é fundamental se fizermos mais experimentos com o mesmo comando, pois ele nos diz que após um dado experimento a bola selecionada é colocada de volta na caixa. Cada vez que o a função sample é chamada um dos resultado pode aparecer com probabilidade 1/2. Em vez de executarmos o comando diversas vezes podemos simplesmente especificar a quantidade de experimentos em size. Realizemos o experimento 100 vezes:

caixa <- c("preta", "branca")
resultados <- sample(caixa, size = 100, replace = TRUE)
resultados
  [1] "preta"  "branca" "preta"  "preta"  "preta"  "preta"  "preta"  "preta"  "branca" "preta" 
 [11] "branca" "preta"  "preta"  "branca" "preta"  "branca" "preta"  "preta"  "preta"  "preta" 
 [21] "preta"  "branca" "branca" "preta"  "preta"  "branca" "branca" "preta"  "branca" "preta" 
 [31] "preta"  "preta"  "preta"  "preta"  "preta"  "branca" "preta"  "preta"  "branca" "branca"
 [41] "preta"  "preta"  "branca" "branca" "branca" "branca" "preta"  "preta"  "branca" "branca"
 [51] "branca" "preta"  "branca" "branca" "branca" "preta"  "branca" "branca" "preta"  "preta" 
 [61] "preta"  "preta"  "branca" "branca" "preta"  "preta"  "preta"  "preta"  "branca" "branca"
 [71] "preta"  "preta"  "branca" "branca" "preta"  "branca" "preta"  "preta"  "preta"  "preta" 
 [81] "preta"  "branca" "branca" "branca" "preta"  "preta"  "preta"  "branca" "branca" "branca"
 [91] "preta"  "preta"  "branca" "branca" "preta"  "branca" "preta"  "preta"  "branca" "branca"

Para computar o número de bolas pretas e brancas resultantes usamos a função table():

table(resultados)
resultados
branca  preta 
    43     57 

Nos resultados acima fizemos a suposição tácita de que a probabilidade de que seja selecionada coda uma das bolas é a mesma. Este problema poderia ter sido formulado também em termos do lançamento de uma moeda honesta (que ao ser lançada tem probabilidade de resultar cara ou coroa com propabilidade 1/2). Reformulando este problema agora como o do lançamento de uma moeda, suponhamos que moeda seja “desonesta”, ou seja, que tenha probabilidade 60% de resultar cara e 40% de resultar em coroa. Basta que adicionemos o argumento prob à função sample:

moeda <- c("cara", "coroa")
resultados <- sample(moeda, size = 100, replace = TRUE, prob=c(0.6,0.4))
resultados
  [1] "coroa" "cara"  "coroa" "cara"  "coroa" "cara"  "cara"  "cara"  "coroa" "cara"  "coroa"
 [12] "cara"  "cara"  "cara"  "coroa" "cara"  "coroa" "coroa" "coroa" "cara"  "coroa" "coroa"
 [23] "cara"  "cara"  "coroa" "cara"  "cara"  "cara"  "cara"  "cara"  "coroa" "cara"  "cara" 
 [34] "cara"  "coroa" "cara"  "cara"  "coroa" "cara"  "cara"  "coroa" "coroa" "cara"  "cara" 
 [45] "cara"  "coroa" "cara"  "coroa" "coroa" "coroa" "cara"  "coroa" "cara"  "coroa" "coroa"
 [56] "coroa" "cara"  "cara"  "coroa" "cara"  "coroa" "coroa" "cara"  "coroa" "cara"  "coroa"
 [67] "coroa" "cara"  "cara"  "cara"  "coroa" "coroa" "cara"  "cara"  "coroa" "cara"  "cara" 
 [78] "cara"  "cara"  "coroa" "coroa" "cara"  "cara"  "coroa" "coroa" "coroa" "cara"  "cara" 
 [89] "cara"  "coroa" "cara"  "coroa" "cara"  "cara"  "coroa" "coroa" "cara"  "cara"  "cara" 
[100] "cara" 

Contemos os resultados:

table(resultados)
resultados
 cara coroa 
   57    43 

O experimento pode ser replicado quantas vezes quisermos, digamos 5 vezes, usando o comando replicate:

B <- 5
eventos <- replicate(B, sample(moeda, size = 100, replace = TRUE, prob=c(0.6,0.4)))
summary(eventos)
     V1         V2         V3         V4         V5    
 cara :63   cara :68   cara :63   cara :66   cara :58  
 coroa:37   coroa:32   coroa:37   coroa:34   coroa:42  

No total temos:

Exemplo 3.2

Suponhamos que temos uma caixa com 8 bolas iguais, mas com cores diferentes: 2 bolas brancas, 3 azuis, uma preta, uma vermelha e uma amarela.

A caixa com as bolas pode ser representada com ajuda do comando rep do R:

bolas <- rep(c("branca", "azul", "preta", "vermelha", "amarela"),times = c(2,3,1,1,1))
bolas
[1] "branca"   "branca"   "azul"     "azul"     "azul"     "preta"    "vermelha" "amarela" 

Selecionemos aleatoriamente, sem substituição, 4 bolas:

sample(bolas,4)
[1] "branca"   "preta"    "azul"     "vermelha"

Se o comando for repetido, outra conjunto de bolas será obtido:

sample(bolas,4)
[1] "branca"   "vermelha" "branca"   "preta"   

Repliquemos o experimento 10 vezes:

B <- 10
eventos <- replicate(B, sample(bolas,4))
eventos
     [,1]     [,2]       [,3]       [,4]       [,5]      [,6]      [,7]       [,8]     [,9]   
[1,] "branca" "preta"    "azul"     "amarela"  "branca"  "azul"    "vermelha" "azul"   "preta"
[2,] "azul"   "azul"     "azul"     "vermelha" "azul"    "amarela" "azul"     "branca" "azul" 
[3,] "branca" "vermelha" "preta"    "azul"     "azul"    "preta"   "azul"     "azul"   "azul" 
[4,] "preta"  "amarela"  "vermelha" "preta"    "amarela" "branca"  "amarela"  "preta"  "azul" 
     [,10]     
[1,] "amarela" 
[2,] "preta"   
[3,] "branca"  
[4,] "vermelha"

Podemos contar automaticamente o número de bolas de cada tipo obtidas da seguinte forma:

tab <- table(eventos)
tab
eventos
 amarela     azul   branca    preta vermelha 
       6       15        6        8        5 

Se selecionarmos 8 bolas o conjunto original é obtido:

sample(bolas,8)
[1] "branca"   "amarela"  "azul"     "azul"     "preta"    "vermelha" "branca"   "azul"    

Exemplo 3.3

Vejamos qual é a probabilidade de que, em duas escolhas, realizadas sem substituição, obtenhamos bolas azuis. Denominemos tal probabilidade por \(Pr(BB)\). É fácil mostrar que \[ Pr(BB)= \frac{3}{8}\cdot \frac{2}{7} = 0.1071429 \] Este resultado è idêntico àquele obtido no Exemplo 1.2. Vejamos como obter este resultado a partir de uma simulação de Monte Carlo. Devemos repetir o seguinte experimento diversas vezes e contar o número de vezes que obtemos “azul” “azul”:

experimento <- sample(bolas,2)
experimento
[1] "vermelha" "branca"  

Façamos o experimento 20 vezes:

B <-20
bolasazuis <- replicate(B,{experimento <- sample(bolas,2) 
(experimento[1]=="azul" & experimento[2]=="azul")})
bolasazuis
 [1] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE
[16] FALSE FALSE FALSE FALSE FALSE

O evento BB ocorreu 2 vezes. Calculemos a proporção de número de TRUE e número de FALSE, que é dada pelo comando mean

mean(bolasazuis)
[1] 0.15

Façamos agora \(10^6\) repetições:

B <-1000000
bolasazuis <- replicate(B,{experimento <- sample(bolas,2) 
(experimento[1]=="azul" & experimento[2]=="azul")})
mean(bolasazuis)
[1] 0.106618

de modo que reobtemos, aproximadamente, o resultado esperado.

Exemplo 3.4

Suponhamos que queremos saber agora qual é a probabilidade \(Pr(RWB)\) (red,white,blue) de obtermos bolas vermelha, branca e azul, respectivamente, ao retirarmos 3 bolas, sem substituição. Sabemos que \[ Pr(RWB)=\frac{1}{8}\frac{2}{7}\frac{3}{6}=\frac{1}{56}= 0.01785714285\,. \] Vejamos como obter este resultado a partir de uma simulação de Monte Carlo, fazendo \(10^6\) repetições:

B <-1000000
bolascoloridas <- replicate(B,{experimento <- sample(bolas,3) 
(experimento[1]=="vermelha" & experimento[2]=="branca" & experimento[3]=="azul")})
mean(bolascoloridas)
[1] 0.017928

que é, aproximadamente, o resultado esperado.

Exemplo 3.5

Suponhamos agora que selecionamos aleatoriamente, sem substituição, 5 bolas e queremos saber qual é a probabilidade de que ao menos 2 bolas sejam azuis. Para resolver este problema pelo método tradicional anterior teríamos que listar muitos eventos \(YRBBW\), \(RWWBB\), etc., calcular a probabilidade de cada evento e somar. Façamos uma simulação de Monte Carlo, usando o comando str_count (pacote stringr) que funciona do seguinte modo:

bolas <- rep(c("branca", "azul", "preta", "vermelha", "amarela"),times = c(2,3,1,1,1))
bolas
[1] "branca"   "branca"   "azul"     "azul"     "azul"     "preta"    "vermelha" "amarela" 
s <- sample(bolas,5)
s
[1] "branca"  "amarela" "azul"    "azul"    "branca" 

Contemos o número de bolas vermelhas na amostra:

library(stringr)
str_count(s, "azul")
[1] 0 0 1 1 0

Ou seja, quando o string é encontrado o valor 1 é atribuído à respectiva componente, caso contrário é 0. Para determinar o número de ocorrências de 1 no vetor usamos o comando:

n <- str_count(s, "azul")
length(which(n==1))
[1] 2

Aplicando este comando ao nosso problema, repetindo o experimento \(10^6\) vezes, a proporção de casos nos quais temos duas ou mais bolas azuis é:

library(stringr)
B <- 1000000
bolasazuis<-replicate(B,{experimento <- sample(bolas,5) 
n <- str_count(experimento, "azul")
length(which(n==1)) >=2})
mean(bolasazuis)
[1] 0.714405

Consideremos novamente o Exemplo 2.2, que agora será resolvido por meio de simulação:

Exemplo 3.6

Suponhamos que uma caixa temos 2 bolas brancas, 3 azuis, uma preta, uma vermelha e uma amarela. Qual é a probabilidade de que numa seleção de 4 bolas obtenhamos 2 bolas azuis e uma bola amarela? Solução. Representemos a caixa de bolas:

bolas <- rep(c("branca", "azul", "preta", "vermelha", "amarela"),times = c(2,3,1,1,1))
bolas
[1] "branca"   "branca"   "azul"     "azul"     "azul"     "preta"    "vermelha" "amarela" 

A proporção de casos nos quais temos duas bolas azuis e uma amarela é:

library(stringr)
B <- 1000000
bolascoloridas<-replicate(B,{experimento <- sample(bolas,4) 
n1 <- str_count(experimento, "azul")
n2 <- str_count(experimento, "amarela")
(length(which(n1==1)) ==2)   & (length(which(n2==1)) ==1)  } ) 
mean(bolascoloridas)
[1] 0.171786

que é similar ao valor 0.1714286 obtido no Exemplo 2.2.

Exemplo 3.7

De uma caixa com 20 bolas, sendo 6 brancas, 4 vermelhas, 7 azuis e 3 verdes são selecionadas 6, sem substituição. (i) Qual é a probabilidade de que a primeira e a última bola da seleção sejam azuis? (ii) Qual é a probabilidade de que ao menos três bolas sejam brancas?

Solução

  1. Definimos a caixa com bolas:
bolas <- rep(c("red", "blue", "white", "green"),times = c(4,7,6,3))
bolas
 [1] "red"   "red"   "red"   "red"   "blue"  "blue"  "blue"  "blue"  "blue"  "blue"  "blue" 
[12] "white" "white" "white" "white" "white" "white" "green" "green" "green"

Selecionamos 6 bolas e repetimos o experimento 900 000 vezes, contando o número de vezes em que a primeira e a sexta bola são azuis:

B <-900000
bolasazuis <- replicate(B,{experimento <- sample(bolas,6) 
(experimento[1]=="blue" & experimento[6]=="blue")})
mean(bolasazuis)
[1] 0.1101756
  1. Devemos agora contabilizar todos os casos em que temos 3 ou mais bolas brancas:
library(stringr)
B <-900000
BolasBrancas <- replicate(B,{experimento <- sample(bolas,6) 
n <- str_count(experimento, "white")
length(which(n==1)) >=3})
mean(BolasBrancas)
[1] 0.2248067

Exemplo 3.8. Jogo de volei

Temos dois times de volei, Brasil e Argentina, que estão jogando uma série de melhor de 7 jogos. O Brasil tem uma equipe melhor e tem 60% de chances de vencer um dado jogo.
(i) Qual é a probabilidade de que a Argentina vença ao menos um jogo?
(ii) Resolva este problema usando simulação de Monte Carlo.
Solução: Notemos que a Argentina precisa vencer ao menos um jogo dos primeiros 4 para que não seja eliminada sem vitórias. A probabililidade de que isso não aconteça é igual à probabilidade do Brasil vencer os 4 primeiros jogos, ou seja,

p_brasil_4v <- 0.6^4
p_brasil_4v
[1] 0.1296

Portanto, a probabilidade a Argentina vença ao menos um jogo entre os 4 primeiros é:

1-p_brasil_4v
[1] 0.8704
  1. Façamos a simulação do experimento 100000 vezes. Agora que as probabilidades dos eventos são diferentes, devemos especificá-las por um vetor. A opção replace = TRUE agora é necessária. A opção any de replicate significa que a condição win é verificada para todos os elementos da amostra.
B = 100000
argentina_vence <- replicate(B,{resultados <- sample(c("lose","win"), 4, replace = TRUE, prob = c(0.6,0.4)) 
any(resultados=="win")})
mean(argentina_vence)
[1] 0.86989

o que está aproximadamente de acordo com o cálculo exato.

Exemplo 3.9. Jogo de volei (2)

Dois times de volei, Brasil e Sérvia, estão jogando uma série de 7 jogos. O primeiro a vencer 4 jogos vence a série. Ambos os times são equilibrados e ambos têm iguais chances de vencer cada jogo. Se o Brasil vencer o primeiro jogo, qual é a chance de que ele vença a série? (i) Calcule exatamente (ii) Faça uma simulação de Monte Carlo.

Solução

  1. O número de jogos restantes é n = 6. Definimos uma variável chamada resultados, que é o vetor de possíveis resultados, sendo 0 uma derrota e 1 uma vitória:
resultados <- c(0,1)

A função list lista o conteúdo do vetor no argumento:

list(resultados)
[[1]]
[1] 0 1

Criamos uma lista L com todos os possíveis resultados dos jogos remanescentes:

L <- replicate(6,list(resultados))
L
[[1]]
[1] 0 1

[[2]]
[1] 0 1

[[3]]
[1] 0 1

[[4]]
[1] 0 1

[[5]]
[1] 0 1

[[6]]
[1] 0 1

Criamos um data frame named possibilidades que contém todas as combinações de todos os possíveis resultados para os jogos remanescentes:

possibilidades <- expand.grid(L)
possibilidades

Criamos um vetor chamado resultados que indica se cada linha no data frame possibilidades contém o número suficiente de vitórias para que o time do Brasil vença a série:

resultados <- rowSums(possibilidades)>3
resultados
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[16]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE  TRUE
[31]  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE
[46]  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE FALSE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE
[61]  TRUE  TRUE  TRUE  TRUE

Calculamos em resultados a proporção de casos (TRUE) em que o Brasil vence a série:

mean(resultados)
[1] 0.34375

Façamos agora uma simulação de Monte Carlo. Criamos um objeto chamado resultados que replica para B = 10000 iterações uma série simulada e determina se a série contém ao menos 4 vitórias, o que daria vitória ao time do Brasil e depois calculemos a proporção de casos TRUE

B <- 10000
resultados <- replicate(B,sum(replicate(6, sample(c(0,1),1)))>3)
mean(resultados)
[1] 0.3453

de modo que obtemos um valor similar aa exato.

Exemplo 3.10 Séries de jogos com diferentes probabilidades

Dois times, A e B jogam uma série de 7 jogos. A probabilidade de A vencer B é p. Determine as probabilidades de que A vença a série para p = 0.5, 0.525, 0.550, … 0.95, e apresente o resultado em um gráfico.

Solução

Definimos o vetor de probabilidades:

p <- seq(0.5, 0.95, 0.025)
p
 [1] 0.500 0.525 0.550 0.575 0.600 0.625 0.650 0.675 0.700 0.725 0.750 0.775 0.800 0.825 0.850
[16] 0.875 0.900 0.925 0.950

Definimos a função:

prob_A_vence <- function(p){
  B <- 10000
  resultado <- replicate(B, {
    A_vence <- sample(c(1,0), 7, replace = TRUE, prob = c(1, 1-p))
    sum(A_vence)>=4
    })
    mean(resultado)
}

Façamos agora a avaliação da função para cada valor de p e o correspondente gráfico:

Pr <- sapply(p,prob_A_vence)
plot(p,Pr)

Podemos calcular uma probabilidade específica. Por exemplo,

prob_win(0.6)
[1] 0.8895

Exemplo 3.11 Diferentes números de jogos em cada série

Consideremos um problema semelhante ao anterior, mas agora com probabilidade de que A vença B em qualquer jogo fixa em p=0.7. A variável agora é o número de jogos da série.

Solução.

Devemos agora deixar o número de jogos N como argumento:

prob_A_vence <- function(N, p=0.7){
      B <- 10000
      resultado <- replicate(B, {
        A_vence <- sample(c(1,0), N, replace = TRUE, prob = c(p, 1-p))
        sum(A_vence)>=(N+1)/2
        })
            mean(resultado)
    }

Definimos os possíveis valores para N como números ímpares de 1 a 19:

N <- seq(1, 20, 2)
N
 [1]  1  3  5  7  9 11 13 15 17 19

Façamos agora a avaliação da função para cada valor de N e o correspondente gráfico:

Pr <- sapply(N,prob_A_vence)
plot(N,Pr)

Referências

  1. Simulations in R, Datacamp, Data Analysis and Statistical Inference https://campus.datacamp.com/courses/statistical-inference-and-data-analysis/lab-2-probability?ex=10

  2. Christian Robert, George Casella. Introducing Monte Carlo Methods with R, Springer, 2010.

  3. Matthias Templ.Simulation for Data Science with R Packt, 2016.

  4. Vikram Dayal. Quantitative Economics with R, Springer, 2020.

LS0tCnRpdGxlOiAiSW50cm9kdcOnw6NvIMOgIFNpbXVsYcOnw6NvIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCjxoNT4gRmVybmFuZG8gRGVla2UgU2Fzc2UgPGJyPiBDQ1QgLSBVREVTQzwvaDU+CjxoND4xLiBQZXJtdXRhw6fDo28gZSBjb21wdXRhw6fDo28gZGUgcHJvYmFiaWxpZGFkZXMgcG9yIG1laW8gZGUgY29udGFnZW08L2g0PgpGYcOnYW1vcyB1bWEgcGVybXV0YcOnw6NvIChvdSBhcnJhbmpvKSBkZSA0IG7Dum1lcm9zLCAzLDQsNSw2IGVtIGdydXBvcyBkZSAzIGVsZW1lbnRvcy4gRGUgbW9kbyBtYWlzIGNvbmNyZXRvLCBzZSB0ZW1vcyB1bWEgY2FpeGEgY29tIDQgYm9sYXMgbWFyY2FkYXMgY29tIGVzdGVzIG7Dum1lcm9zLCBxdWFpcyBzw6NvIG9zIHBvc3PDrXZlaXMgcmVzdWx0YWRvcyBhbyBzZWxlY2lvbmFybW9zIDMgYm9sYXMgYWxlYXTDs3JpYW1lbnRlPyAKYGBge3J9Cm0gPC0gcGVybXV0YXRpb25zKDQsMyxjKDMsNCw1LDYpKQptCmBgYApOb3RlbW9zIHF1ZSB1bWEgb3UgbWFpcyBsaW5oYXMgZXNwZWPDrWZpY2FzIGRlICptKiBwb2RlbSBzZXIgb2J0aWRhcyBkYSBzZWd1aW50ZSBtYW5laXJhLiBQb3IgZXhlbXBsbywgc2VsZWNpb25lbW9zIGFzIGxpbmhhcyAxMiwxMyBlIDE0OiAKYGBge3J9Cm1bMTI6MTQsXQpgYGAKClBvZGVtb3MgdGFtYsOpbSB1c2FyIHVtIHZldG9yIGRlIHN0cmluZ3M6CmBgYHtyfQptIDwtIHBlcm11dGF0aW9ucyg0LDMsYygiYnJhbmNhIiwicHJldGEiLCJhenVsIiwidmVybWVsaGEiKSkKbQpgYGAKQ29tbyB2ZW1vcyBkYSBtYXRyaXogZGUgc2HDrWRhIGVtIHF1YWxxdWVyIHVtIGRvcyBjYXNvcyAgYWNpbWEsIG8gbsO6bWVybyBkZSBtb2RvcyDDqSAyNCwgcXVlIHBvZGUgc2VyIG9idGlkbyBkaXJldGFtZW50ZSBjb250YW5kbyBvIG7Dum1lcm8gZGUgbGluaGFzIGRlICptKjogCmBgYHtyfQpuIDwtIG5yb3cobSkKbgpgYGAKRmHDp2Ftb3MgNSBhbW9zdHJhZ2Vucy4gUGFyYSBpc3NvIGluaWNpYWxtZW50ZSBlc2NvbGhlbW9zIGFsZWF0w7NyaWFtZW50ZSA0IG7Dum1lcm9zIGVudHJlIG9zICpuKj0yNDoKYGBge3J9CmluZGljZSA8LSBzYW1wbGUobiw0KQppbmRpY2UKYGBgCkNhZGEgdW1hIGRlc3RhcyBjaW5jbyBlc2NvbGhhcyBjb3JyZXNwb25kZSBhIHVtIHJlc3VsdGFkbyBkZSB1bSBleHBlcmltZW50bzoKYGBge3J9Cm1baW5kaWNlLF0KYGBgCkEgcHJvYmFiaWxpZGFkZSBkZSBudW1hIGFtb3N0cmFnZW0gb2J0ZXJtb3MgYSBib2xhIGF6dWwgw6kgb2J2aWFtZW50ZSAxLzQgcXVlIGNvcnJlc3BvbmRlIGEgNi8yNCBubyBleHBlcmltZW50byBxdWUgY29uc2lzdGUgZW0gY29sZXRhciAzIGJvbGFzIGFsZWF0b3JpYW1lbnRlLiBTCgpTdXBvbmhhbW9zIGFkaWNpb25hbW9zIGFnb3JhIG1haXMgdW1hIGJvbGEgYnJhbmNhIGFvIGNvbmp1bnRvIG9yaWdpbmFsIGRlIDQgYm9sYXMuIFZlcmlmaXF1ZW1vcyBhZ29yYSBhcyBwb3NzaWJpbGlkYWRlcyBjb3JyZXNwb25kZW50ZXMgw6Agc2VsZcOnw6NvIGRlIDMgYm9sYXM6IAoKYGBge3J9CmJvbGFzID0gYygiYnJhbmNhMSIsInByZXRhIiwiYXp1bCIsInZlcm1lbGhhIiwgImJyYW5jYTIiKQptIDwtIHBlcm11dGF0aW9ucyg1LDMsYm9sYXMpCm0KYGBgClRlbW9zIGFnb3JhIDYwIHBvc3NpYmlsaWRhZGVzOiAKYGBge3J9Cm4gPC0gbnJvdyhtKQpuCmBgYApEZWZpbmltb3MgYXMgY29sdW5hczoKYGBge3J9CnByaW1laXJhX2JvbGEgPC0gbVssMV0Kc2VndW5kYV9ib2xhIDwtIG1bLDJdCnRlcmNlaXJhX2JvbGEgPC0gbVssM10KYGBgCjEuIEVtIHF1YWlzIGNhc29zIGEgcHJpbWVpcmEgYm9sYSDDqSBhenVsPwpgYGB7cn0KaDwtcHJpbWVpcmFfYm9sYSAlaW4lICJhenVsIgpoCmBgYApPYnZpYW1lbnRlIGlzc28gYWNvbnRlY2UgMTIgdmV6ZXM6CmBgYHtyfQpzdW0oaCkKYGBgCgoyLiBFbSBxdWFpcyBjYXNvcyBhIHByaW1laXJhIGJvbGEgw6kgYnJhbmNhPyBOb3RlIHF1ZSBhIHByaW1laXJhIGJvbGEgw6kgYnJhbmNhIHF1YW5kbyBzZWxlY2lvbmFtb3MgYSBib2xhIGJyYW5jYTEgb3UgYSBib2xhIGJyYW5jYTIsIGRlIG1vZG8gcXVlIG8gbsO6bWVybyBkZXZlIHNlciAyNC4gIFBhcmEgc2lzdGVtYXRpemFyIGlzc28gZGVmaW5pbW9zIG8gdmV0b3I6CmBgYHtyfQpicmFuY2FzPC0gYygiYnJhbmNhMSIsICJicmFuY2EyIikKYGBgClBvcnRhbnRvLCAKYGBge3J9Cmg8LXByaW1laXJhX2JvbGEgJWluJSBicmFuY2FzCmgKYGBgCk9idmlhbWVudGUgaXNzbyBhY29udGVjZSAyNCB2ZXplczoKYGBge3J9CnN1bShoKQpgYGAKMy4gUXVhbCDDqSBhIHByb2JhYmlsaWRhZGUgZGUgcXVlIGEgcHJpbWVpcmEgYm9sYSBzZWphIGJyYW5jYSBvdSBhenVsPwpgYGB7cn0KTjwtc3VtKChwcmltZWlyYV9ib2xhICVpbiUgYnJhbmNhcykgfCBwcmltZWlyYV9ib2xhICVpbiUgImF6dWwiKQpOCmBgYApBIHByb2JhYmlsaWRhZGUgw6kgZGFkYSBwb3IKYGBge3J9CnA9Ti9uCnAKYGBgCjQuIFF1YWwgw6kgYSBwcm9iYWJpbGlkYWRlIGRlIHF1ZSBhIHByaW1laXJhIGJvbGEgc2VqYSBicmFuY2EgZSBhIHRlcmNlaXJhICBhenVsPwpgYGB7cn0KTjwtc3VtKChwcmltZWlyYV9ib2xhICVpbiUgYnJhbmNhcykgJiB0ZXJjZWlyYV9ib2xhICVpbiUgImF6dWwiKQpOCmBgYApBIHByb2JhYmlsaWRhZGUgw6kgZGFkYSBwb3IKYGBge3J9CnA9Ti9uCnAKYGBgCgpFeGVyY8OtY2lvIDEuMSBFbSB1bWEgY2FpeGEgdGVtb3MgMiBib2xhcyBicmFuY2FzLCAzIGF6dWlzLCB1bWEgcHJldGEsIHVtYSB2ZXJtZWxoYSBlIHVtYSBhbWFyZWxhLiBRdWFsIMOpIGEgcHJvYmFiaWxpZGFkZSBkZSBxdWUgZW0gdW1hIGFtb3N0cmFnZW0gbmEgcXVhbCBzZWxlY2lvbmFtb3MgNCBib2xhcyBvYnRlbmhhbW9zIGEgcHJpbWVpcmEgYm9sYSBhbWFyZWxhLCBhIHNlZ3VuZGEgYnJhbmNhLCAgYSB0ZXJjZWlyYSBlIHF1YXJ0YSBhenVpcz8KClNvbHXDp8Ojby4gCkRlZmluaW1vcyBub3NzbyBjb25qdW50byBkZSBib2xhcyBlIGV4aWJpbW9zIG8gY29uanVudG8gZGUgdG9kYXMgYXMgcG9zc8OtdmVpcyBwZXJtdXRhw6fDtWVzIChhcnJhbmpvcyk6CmBgYHtyfQpib2xhcyA9IGMoImJyYW5jYTEiLCAiYnJhbmNhMiIsInByZXRhIiwiYXp1bDEiLCJhenVsMiIsICJhenVsMyIsICJ2ZXJtZWxoYSIsICJhbWFyZWxhIikKbSA8LSBwZXJtdXRhdGlvbnMoOCw0LGJvbGFzKQpuIDwtIG5yb3cobSkKbgpgYGAKVGVtb3MgcG9ydGFudG8gMTY4MCBwb3NzaWJpbGlkYWRlcy4gTW9zdHJhbW9zIGFiYWl4byBzZWlzIGRlbGFzOgpgYGB7cn0KaGVhZChtKQpgYGAKRGVmaW5pbW9zIGFzIGNvbHVuYXM6CmBgYHtyfQpwcmltZWlyYV9ib2xhIDwtIG1bLDFdCnNlZ3VuZGFfYm9sYSA8LSBtWywyXQp0ZXJjZWlyYV9ib2xhIDwtIG1bLDNdCnF1YXJ0YV9ib2xhIDwtIG1bLDRdCmBgYAoKVmVqYW1vcyBxdWFudG9zIGV2ZW50b3MgcmVzdWx0YW0gZW0gInByaW1laXJhIGJvbGEgYW1hcmVsYSwgYSBzZWd1bmRhIGJyYW5jYSwgIGEgdGVyY2VpcmEgb3UgcXVhcnRhIGF6dWlzIi4gRGVmaW5pbW9zIGFudGVzIG9zIGNvbmp1bnRvcyBkZSBib2xhcyBicmFuY2FzIGUgYXp1aXM6CmBgYHtyfQpicmFuY2FzPC0gYygiYnJhbmNhMSIsICJicmFuY2EyIikKYXp1aXM8LSBjKCJhenVsMSIsImF6dWwyIiwgImF6dWwzIikKYGBgClBvcnRhbnRvLApgYGB7cn0KTjwtc3VtKChwcmltZWlyYV9ib2xhICVpbiUgImFtYXJlbGEiKSAmIChzZWd1bmRhX2JvbGEgJWluJSBicmFuY2FzKSAmICh0ZXJjZWlyYV9ib2xhICVpbiUgYXp1aXMgfCBxdWFydGFfYm9sYSAlaW4lIGF6dWlzKSkgICAgICAKTgpgYGAKUG9ydGFudG8sIGEgcHJvYmFiaWxpZGFkZSBkbyBldmVudG8gZXNwZWNpZmljYWRvIG9jb3JyZXIgw6kgZGFkYSBwb3IgCmBgYHtyfQpwIDwtIE4vbgpwCmBgYAoKRXhlcmPDrWNpbyAxLjIgRW0gdW1hIGNhaXhhIHRlbW9zIDIgYm9sYXMgYnJhbmNhcywgMyBhenVpcywgdW1hIHByZXRhLCB1bWEgdmVybWVsaGEgZSB1bWEgYW1hcmVsYS4gUXVhbCDDqSBhIHByb2JhYmlsaWRhZGUgZGUgcXVlIGVtIHVtYSBhbW9zdHJhZ2VtIG5hIHF1YWwgc2VsZWNpb25hbW9zIDIgYm9sYXMgb2J0ZW5oYW1vcyBhcyBkdWFzIHByaW1laXJhcyBib2xhcyBhenVpcz8KClNvbHXDp8Ojby4gCkRlZmluaW1vcyBub3NzbyBjb25qdW50byBkZSBib2xhcyBlIGV4aWJpbW9zIG8gY29uanVudG8gZGUgdG9kYXMgYXMgcG9zc8OtdmVpcyBwZXJtdXRhw6fDtWVzIChhcnJhbmpvcyk6CmBgYHtyfQpib2xhcyA9IGMoImJyYW5jYTEiLCAiYnJhbmNhMiIsInByZXRhIiwiYXp1bDEiLCJhenVsMiIsICJhenVsMyIsICJ2ZXJtZWxoYSIsICJhbWFyZWxhIikKbSA8LSBwZXJtdXRhdGlvbnMoOCwyLGJvbGFzKQpuIDwtIG5yb3cobSkKbgpgYGAKVGVtb3MgcG9ydGFudG8gNTYgcG9zc2liaWxpZGFkZXMuIApEZWZpbmltb3MgYXMgY29sdW5hczoKYGBge3J9CnByaW1laXJhX2JvbGEgPC0gbVssMV0Kc2VndW5kYV9ib2xhIDwtIG1bLDJdCmBgYAoKVmVqYW1vcyBxdWFudG9zIGV2ZW50b3MgcmVzdWx0YW0gZW0gInByaW1laXJhIGJvbGEgYXp1bCBlIHNlZ3VuZGEgYXp1bCI6CmBgYHtyfQphenVpczwtIGMoImF6dWwxIiwiYXp1bDIiLCAiYXp1bDMiKQpgYGAKUG9ydGFudG8sCmBgYHtyfQpOPC1zdW0oKHByaW1laXJhX2JvbGEgJWluJSBhenVpcykgJiAoc2VndW5kYV9ib2xhICVpbiUgYXp1aXMpKSAgICAgIApOCmBgYApQb3J0YW50bywgYSBwcm9iYWJpbGlkYWRlIGRvIGV2ZW50byBlc3BlY2lmaWNhZG8gb2NvcnJlciDDqSBkYWRhIHBvciAKYGBge3J9CnAgPC0gTi9uCnAKYGBgCjxoND4yLiBDb21iaW5hw6fDtWVzPC9oND4KUXVhbmRvIG51bSBwcm9jZXNzbyBkZSBhbW9zdHJhZ2VtLCBubyBjYXNvIGRvcyBleGVtcGxvcyBhY2ltYSwgYSBvcmRlbSBkb3MgZXZlbnRvcyBuw6NvIMOpIGltcG9ydGFudGUsIHBvZGVtb3MgdXNhciBjb21iaW5hw6fDtWVzLiBOb3RlbW9zIGEgZGlmZXJlbsOnYSBlbnRyZSBwZXJtdXRhw6fDtGVzLCBvbmRlIGEgb3JkZW0gaW1wb3J0YSwKYGBge3J9CnBlcm11dGF0aW9ucygzLDIpCmBgYAplIGNvbWJpbmHDp8O1ZXMsIG9uZGUgYSBvcmRlbSBuw6NvIGltcG9ydGE6IApgYGB7cn0KY29tYmluYXRpb25zKDMsMikKYGBgCkV4ZW1wbG8gMi4xIFN1cG9uaGFtb3MgcXVlIHVtYSBjYWl4YSB0ZW1vcyAyIGJvbGFzIGJyYW5jYXMsIDMgYXp1aXMsIHVtYSBwcmV0YSwgdW1hIHZlcm1lbGhhIGUgdW1hIGFtYXJlbGEuIFF1YWwgw6kgYSBwcm9iYWJpbGlkYWRlIGRlIHF1ZSBudW1hIHNlbGXDp8OjbyBkZSA0IGJvbGFzIG9idGVuaGFtb3MgMiBib2xhcyBhenVpcyBlIHVtYSBib2xhIGFtYXJlbGE/CgpTb2x1w6fDo28uIApEZWZpbmltb3Mgbm9zc28gY29uanVudG8gZGUgYm9sYXMgZSBleGliaW1vcyBvIGNvbmp1bnRvIGRlIHRvZGFzIGFzIHBvc3PDrXZlaXMgY29tYmluYcOnw7VlczoKYGBge3J9CmJvbGFzID0gYygiYnJhbmNhMSIsICJicmFuY2EyIiwicHJldGEiLCJhenVsMSIsImF6dWwyIiwgImF6dWwzIiwgInZlcm1lbGhhIiwgImFtYXJlbGEiKQptIDwtIGNvbWJpbmF0aW9ucyg4LDQsYm9sYXMpCm0KYGBgClRvZGFzIGFzIDcwIHBvc3NpYmlsaWRhZGVzIGVzdMOjbyBsaXN0YWRhcyBhY2ltYS4gRGUgZmF0bywgCmBgYHtyfQpuIDwtIG5yb3cobSkKbgpgYGAKRGVmaW5pbW9zIGFzIGNvbHVuYXM6CmBgYHtyfQpwcmltZWlyYV9ib2xhIDwtIG1bLDFdCnNlZ3VuZGFfYm9sYSA8LSBtWywyXQp0ZXJjZWlyYV9ib2xhIDwtIG1bLDNdCnF1YXJ0YV9ib2xhIDwtIG1bLDRdCmBgYAoKTm8gY2FzbyBkZSBwZXJtdXRhw6fDtWVzIHTDrW5oYW1vcyB1bSBlc3Bhw6dvIGFtb3N0cmFsIGRlIDE2ODAgZXZlbnRvcy4gVmVqYW1vcyBxdWFudG9zIGV2ZW50b3MgcmVzdWx0YW0gZW0gImR1YXMgYXp1aXMiLiAKYGBge3J9CmF6dWlzIDwtIGMoImF6dWwxIiwgImF6dWwyIiwgImF6dWwzIikKCmBgYApQYXJhIGNhZGEgbGluaGEgZGUgdW0gYSBuIHZlcmlmaWNhbW9zIHNlIG8gbsO6bWVybyBkZSBvY29ycsOqbmNpYXMgZGUgYXp1bCDDqSBpZ3VhbCBhIDI6IApgYGB7cn0KZm9yKGkgaW4gMTpuKXsKICAgYVtpXSA8LSBzdW0obVtpLF0gJWluJSBhenVpcykgPT0gMiAKfQpwcmludChhWzE6bl0pCmBgYApQb3J0YW50byBvIG7Dum1lcm8gZGUgdmV6ZXMgZW0gcXVlIHRlbW9zIDIgYm9sYXMgYXp1aXMgw6kgZGFkbyBwb3IgCmBgYHtyfQpOPC1zdW0oYVsxOm5dKQpOCmBgYApBIHByb2JhYmlsaWRhZGUgZGVzdGUgZXZlbnRvIMOpIGRhZGEgcG9yCmBgYHtyfQpwPU4vbgpwCmBgYAo8aDQ+IEV4ZW1wbG8gMi4yPC9oND4KUXVhbCDDqSBhIHByb2JhYmlsaWRhZGUgbm8gcHJvYmxlbWEgYW50ZXJpb3IsIGRlIGVuY29udHJhcm1vcyBkdWFzIGJvbGFzIGF6dWlzIGUgdW1hIGFtYXJlbGE/IAoKUGFyYSBjYWRhIGxpbmhhIGRlIHVtIGEgbiB2ZXJpZmljYW1vcyBzZSBvIG7Dum1lcm8gZGUgb2NvcnLDqm5jaWFzIGRlIGF6dWwgw6kgaWd1YWwgYSAyIGUgbyBkZSBhbWFyZWxhcyDDqSBpZ3VhbCBhIDE6IApgYGB7cn0KZm9yKGkgaW4gMTpuKXsKICAgYVtpXSA8LSBzdW0obVtpLF0gJWluJSBhenVpcykgPT0gMiAmIHN1bShtW2ksXSAlaW4lICJhbWFyZWxhIik9PTEKfQpwcmludChhWzE6bl0pCmBgYApQb3J0YW50byBvIG7Dum1lcm8gZGUgdmV6ZXMgZW0gcXVlIHRlbW9zIDIgYm9sYXMgYXp1aXMgZSB1bWEgYW1hcmVsYSDDqSBkYWRvIHBvciAKYGBge3J9Ck48LXN1bShhWzE6bl0pCk4KYGBgCkEgcHJvYmFiaWxpZGFkZSBkZXN0ZSBldmVudG8gw6kgZGFkYSBwb3IKYGBge3J9CnA9Ti9uCnAKYGBgCjxoND4zLiBTaW11bGHDp8OjbyBkZSBNb250ZSBDYXJsbzwvaDQ+Cgo8aDQ+My4xIEludHJvZHXDp8OjbyA8L2g0PgpVbSBtb2RvIGRpZmVyZW50ZSBkZSBjYWxjdWxhciBwcm9iYWJpbGlkYWRlcyDDqSBwb3IgbWVpbyBkZSBleHBlcmltZW50b3MgY29tcHV0YWNpb25haXMuIElsdXN0cmFyZW1vcyBlc3RhIGlkZWlhIHVzYW5kbyBvIGNoYW1hZG8gbcOpdG9kbyBkZSBzaW11bGHDp8OjbyBkZSBNb250ZSBDYXJsby4gUGFyYSB1bWEgYWJvcmRhZ2VtIG1haXMgZGV0YWxoYWRhIGRlc3RlIGFzc3VudG8gdmVqYSwgcG9yIGV4ZW1wbG8gYXMgcmVmZXLDqm5jaWFzIFsxLDIsMyw0XS4KClVtIG1vZGVsbyB1dGlsaXphZG8gZnJlcXVlbnRlbWVudGUgcGFyYSBpbHVzdHJhciBvcyBjb25jZWl0b3MgZGUgaW5mZXLDqm5jaWEgZXN0YXTDrXN0aWNhIMOpIG8gZG8gY2FpeGEuIFVtIGV4ZW1wbG8gc2ltcGxlcyBkZSB2YXJpw6F2ZWwgYWxlYXTDs3JpYSDDqSBhcXVlbGUgcXVlIHJlc3VsdGEgcXVhbmRvIHJldGlyYW1vcyB1bSB0aWNrZXQgZGUgdW1hIGNhaXhhIChzZW0gb2xoYXIgb3UgYWxlYXRvcmlhbWVudGUpLiBQb3IgZXhlbXBsbywgbyBsYW7Dp2FtZW50byBkZSB1bWEgbW9lZGEgZSBhIGRldGVybWluYcOnw6NvIGRvIGxhZG8gcXVlIHJlc3VsdGEgcGFyYSBjaW1hLCBjYXJhIChIKSBvdSBjb3JvYSAoVCksIHBvZGUgc2VyIHJlcHJlc2VudGFkbyBwZWxhIHJldGlyYWRhIGRlIHVtIHRpY2tldCBkZSB1bWEgY2FpeGEgcXVlIGNvbnTDqW0gZG9pcyB0aWNrZXRzLCB1bSBtYXJjYWRvIGNvbSBIIGUgb3V0cm8gY29tIFQuIERlbm90ZW1vcyBhIGNhaXhhIHBlbG8gc2V1IGNvbnRlw7pkbywgW0gsVF0uIAoKU2UgYWxlYXRvcmlhbWVudGUgYXBhbmhhbW9zIHVtIHRpY2tldCBkYSBjYWl4YSBbSCxUXSBvIHRpY2tldCByZXRpcmFkbyBwb2RlIHNlciBIIG91IFQgY29tIGlndWFsIHByb2JhYmlsaWRhZGUuIFN1cG9uaGFtb3MgcXVlIG8gdGlja2V0IHJldGlyYWRvIHJlc3VsdG91IHNlciBILiBTZSBuw6NvIGRldm9sdmVtb3MgbyB0aWNrZXQgb3JpZ2luYWwgZW50w6NvIGEgY2FpeGEgc2Vyw6EgYWdvcmEgWyAgLFRdIGUgc2UgdGlyYXJtb3Mgb3V0cm8gdGlja2V0IGRhIGNhaXhhLCBlbnTDo28gZWxlIHNlcsOhIFQsIGNvbSBjZXJ0ZXphLiBTZSBkZXZvbHZlcm1vcyBvIHRpY2tldCBIIMOgIGNhaXhhLCBlbnTDo28gYSBjYWl4YSB2b2x0YXLDoSBhIHNlciBbSCxUXSBub3ZhbWVudGUgZSB1bWEgbm92YSByZXRpcmRhIHBvZGVyw6EgcmVzdWx0YXIgZW0gSCBvdSBULCBjb20gaWd1YWwgcHJvYmFiaWxpZGFkZS4gRW0gb3V0cmFzIHBhbGF2cmFzLCBzZSBuw6NvIGZpemVybW9zIHN1YnN0aXR1acOnw6NvLCBhIHNlZ3VuZGEgcmV0aXJhZGEgc2Vyw6EgKmRlcGVuZGVudGUqIGRhIHByaW1laXJhLiBTZSBmaXplcm1vcyBzdWJzdGl0dWnDp8OjbywgYSBzZWd1bmRhIHJldGlyYWRhIHNlcsOhICppbmRlcGVuZGVudGUqIGRhIHByaW1laXJhLiAKCk8gcHJvY2Vzc28gZGUgc3Vic3RpdHVpw6fDo28gY29ycmVwb25kZSBhIHRlcm1vcyB1bWEgY2FpeGEgY29tIHVtIG7Dum1lcm8gbXVpdG8gZ3JhbmRlIGRlIHRpY2tldHMgbWFyY2Fkb3MgSCBlIFQgKGVtIG7Dum1lcm8gaWd1YWwpLiBTZSBmaXplcm1vcyBkdWFzIHJldGlyYWRhcywgYSBzZWd1bmRhIHNlcsOhIHByYXRpY2FtZW50ZSBpbmRlcGVuZGVudGUgZGEgcHJpbWVpcmEuIAoKQ3JpYXJlbW9zIHRhbCBjYWl4YSBlbSBSIGEgc2VndWlyOiAKYGBge3J9CkNhaXhhIDwtIGMoIkgiLCAiVCIpCkNhaXhhCmBgYApTaW11bGVtb3MgYSByZXRpcmFkYSBkZSA1IHRpY2tldHMgdmV6ZXMgZGEgY2FpeGEsIGNvbSBzdWJ0aXR1acOnw6NvLiBFcXVpdmFsZW50ZW1lbnRlLCBwb2RlcsOtYW1vcyBpbWFnaW5hciBvIGxhbsOnYW1lbnRvIGRlIHVtYSBtb2VkYSA1IHZlemVzIHBhcmEgb2JzZXJ2YXIgbyByZXN1bHRhZG8gY2FyYSAoSCkgb3UgY29yb2EgKFQpLgpgYGB7cn0KIyBSZXRpcmFkYSBkZSB0aWNrZXRzIGRhIGNhaXhhCnNhbXBsZSh4ID0gQ2FpeGEsIHNpemUgPSA1LCByZXBsYWNlID0gVFJVRSkKYGBgCkNhZGEgdmV6IHF1ZSBvIGNvbWFuZG8gYWNpbWEgZm9yIGV4ZWN1dGFkbyB1bSByZXN1bHRhZG8gZGlmZXJlbnRlIHNlcsOhIG9idGlkby4gCgpPcyBhcmd1bWVudG9zIGRhIGZ1bsOnw6NvICpzYW1wbGUqIHPDo286IAoxLiBPIG9iamV0byBhIHNlciBhbW9zdHJhZG87CjIuIE8gdGFtYW5obyBkYSBhbW9zdHJhOwozLiBTZSBhIGFtb3N0cmFnZW0gw6kgY29tIHN1YnN0aXR1acOnw6NvIG91IG7Do28uIAoKQW8gdXNhcm1vcyByZXBsYWNlID0gVFJVRSBlc3RhbW9zIHN1cG9uZG8gcXVlIHRvZGFzIGFzIGFtb3N0cmFnZW5zIHPDo28gaW5kZXBlbmRlbnRlcy4gSXNzbyDDqSBlcXVpdmFsZW50ZSDDoCBhbW9zdHJhZ2VtIGRlIHVtYSBwb3B1bGHDp8OjbyBtdWl0byBncmFuZGUuIFNlIHJlcGxhY2UgPSBGYWxzZSAoZGVmYXVsdCkgYXMgYW1vc3RyYWdlbnMgbsOjbyBzw6NvIGluZGVwZW5kZW50ZXMuIE5lc3RlIGNhc28sIHNlIG8gdGFtYW5obyBkYSBhbW9zdHJhZ2VtIGZvciBtYWlvciBkbyBvIG7Dum1lcm8gZGUgZWxlbWVudG9zIG5hIGNhaXhhIHRlcmVtb3MgdW0gZXJyby4gCgpFbWJvcmEgY2FkYSB2ZXogcXVlIG8gY29tYW5kbyBzYW1wbGUgc2VqYSBleGVjdXRhZG8gdW1hIGRpZmVyZW50ZSBzZXF1w6puY2lhIGRlIHJlc3VsdGFkb3Mgc2VqYSBnZXJhZGEsIGVtIGFsZ3VtYXMgc2l0dWHDp8O1ZXMsIGRlc2VqYW1vcyBxdWUgdW1hIGRhZGEgc2ltdWxhw6fDo28gc2VqYSByZXByb2R1dMOtdmVsLCBvdSBzZWphLCBxdWUgYXMgZGlmZXJlbnRlcyBzZXF1w6puY2FpcyBkZSByZXN1bHRhZG9zIHNlbXByZSBzZWphbSBhcyBtZXNtYXMuIFBhcmEgaXNzbyBwcm9jZWRlbW9zIGRvIHNlZ3VpbnRvIG1vZG86IApgYGB7cn0Kc2V0LnNlZWQoMzApICMgcGFyYSByZXByb2R1Y2liaWxpZGFkZQpzYW1wbGUoQ2FpeGEsIDUsIHJlcGxhY2UgPSBUUlVFKQpgYGAKQ2FkYSB2ZXogcXVlIG8gYmxvY28gYWNpbWEgZm9yIGV4ZWN1dGFkbyBvIHJlc3VsdGFkbyBzZXLDoSBvIG1lc21vLiBPIGJsb2NvIGFiYWl4byBkYXLDoSB1bSByZXN1bHRhZG8gZGlmZXJlbnRlLCBtYXMgcXVlIHNlcsOhIHNlbXByZSBlc3RlLCBjYXNvIHNlamEgZXhlY3V0YWRvIGRvIGJsb2NvIGFjaW1hLgpgYGB7cn0Kc2FtcGxlKENhaXhhLCA1LCByZXBsYWNlID0gVFJVRSkKYGBgCgpFbSB1bWEgc2ltdWxhw6fDo28gZXN0YWJlbGVjZW1vcyBhcyByZWdyYXMgZGUgdW1hIHByb2Nlc3NvIGFsZWF0w7NyaW8uIE9zIG7Dum1lcm9zIGFsZWF0w7NyaW9zIGdlcmFkb3Mgbm8gY29tcHV0YWRvciByZXN1bHRhbSBudW1hIHNhw61kYSBkZSBhY29yZG8gY29tIHRhaXMgcmVncmFzLgoKPGg0PiBFeGVtcGxvIDMuMTwvaDQ+ClNpbXVsZW1vcyBvIGV4cGVyaW1lbnRvIHF1ZSBjb25zaXN0ZSBlbSByZXRpcmFyIGRlIHVtYSBjYWl4YSB1bWEgYm9sYSBxdWUgY29udMOpbSBib2xhcyBwcmV0YXMgZSBicmFuY2FzLiAKYGBge3J9CmNhaXhhIDwtIGMoInByZXRhIiwgImJyYW5jYSIpCnNhbXBsZShjYWl4YSwgc2l6ZSA9IDEsIHJlcGxhY2UgPSBUUlVFKQpgYGAKTyB2ZXRvciAqY2FpeGEqIHJlcHJlc2VudGEgYSBjYWl4YSBjb20gIGFzIGR1YXMgYm9sYXMsIHVtYSBwcmV0YSwgb3V0cmEgYnJhbmNhLiBBIGZ1bsOnw6NvIHNhbXBsZSgpIHJlYWxpemEgbyBleHBlcmltZW50byBxdWUgY29uc2lzdGUgZW0gcmV0aXJhciBhbGVhdMOzcmlhbWVudGUgdW1hIGJvbGEgZGEgY2FpeGEgIGUgaW5mb3JtYXIgc2UgbyByZXN1bHRhZG8gw6kgcHJldGEgb3UgYnJhbmNhLiBBIG9ww6fDo28gKnNpemU9MSogaW5kaWNhIHF1ZSBzw7MgdW0gZXhwZXJpbWVudG8gw6kgcmVhbGl6YWRvLiBBIG9ww6fDo28gKnJlcGxhY2UgPSBUUlVFKiBhcXVpIG7Do28gZmF6IGRpZmVyZW7Dp2Egbm8gY2FzbyBkZSB1bSBleHBlcmltZW50bywgbWFzIMOpIGZ1bmRhbWVudGFsIHNlIGZpemVybW9zIG1haXMgZXhwZXJpbWVudG9zIGNvbSBvIG1lc21vIGNvbWFuZG8sIHBvaXMgZWxlIG5vcyBkaXogcXVlIGFww7NzIHVtIGRhZG8gZXhwZXJpbWVudG8gYSBib2xhIHNlbGVjaW9uYWRhIMOpIGNvbG9jYWRhIGRlIHZvbHRhIG5hIGNhaXhhLiAgQ2FkYSB2ZXogcXVlIG8gYSBmdW7Dp8OjbyAqc2FtcGxlKiDDqSBjaGFtYWRhIHVtIGRvcyByZXN1bHRhZG8gcG9kZSBhcGFyZWNlciBjb20gcHJvYmFiaWxpZGFkZSAxLzIuIEVtIHZleiBkZSBleGVjdXRhcm1vcyBvIGNvbWFuZG8gZGl2ZXJzYXMgdmV6ZXMgcG9kZW1vcyBzaW1wbGVzbWVudGUgZXNwZWNpZmljYXIgYSBxdWFudGlkYWRlIGRlIGV4cGVyaW1lbnRvcyBlbSAqc2l6ZSouIFJlYWxpemVtb3MgbyBleHBlcmltZW50byAxMDAgdmV6ZXM6CmBgYHtyfQpjYWl4YSA8LSBjKCJwcmV0YSIsICJicmFuY2EiKQpyZXN1bHRhZG9zIDwtIHNhbXBsZShjYWl4YSwgc2l6ZSA9IDEwMCwgcmVwbGFjZSA9IFRSVUUpCnJlc3VsdGFkb3MKYGBgClBhcmEgY29tcHV0YXIgbyBuw7ptZXJvIGRlIGJvbGFzIHByZXRhcyBlIGJyYW5jYXMgcmVzdWx0YW50ZXMgdXNhbW9zIGEgZnVuw6fDo28gKnRhYmxlKCkqOgpgYGB7cn0KdGFibGUocmVzdWx0YWRvcykKYGBgCk5vcyByZXN1bHRhZG9zIGFjaW1hIGZpemVtb3MgYSBzdXBvc2nDp8OjbyB0w6FjaXRhIGRlIHF1ZSBhIHByb2JhYmlsaWRhZGUgZGUgcXVlIHNlamEgc2VsZWNpb25hZGEgY29kYSB1bWEgZGFzIGJvbGFzIMOpIGEgbWVzbWEuIEVzdGUgcHJvYmxlbWEgcG9kZXJpYSB0ZXIgc2lkbyBmb3JtdWxhZG8gdGFtYsOpbSBlbSB0ZXJtb3MgZG8gbGFuw6dhbWVudG8gZGUgdW1hIG1vZWRhIGhvbmVzdGEgKHF1ZSBhbyBzZXIgbGFuw6dhZGEgdGVtIHByb2JhYmlsaWRhZGUgZGUgcmVzdWx0YXIgY2FyYSBvdSBjb3JvYSBjb20gcHJvcGFiaWxpZGFkZSAxLzIpLiBSZWZvcm11bGFuZG8gZXN0ZSBwcm9ibGVtYSBhZ29yYSBjb21vIG8gZG8gbGFuw6dhbWVudG8gZGUgdW1hIG1vZWRhLCBzdXBvbmhhbW9zIHF1ZSBtb2VkYSBzZWphICJkZXNvbmVzdGEiLCBvdSBzZWphLCBxdWUgdGVuaGEgcHJvYmFiaWxpZGFkZSA2MCUgZGUgcmVzdWx0YXIgY2FyYSBlIDQwJSBkZSByZXN1bHRhciBlbSBjb3JvYS4gQmFzdGEgcXVlIGFkaWNpb25lbW9zIG8gYXJndW1lbnRvICpwcm9iKiDDoCBmdW7Dp8OjbyAqc2FtcGxlKjoKYGBge3J9Cm1vZWRhIDwtIGMoImNhcmEiLCAiY29yb2EiKQpyZXN1bHRhZG9zIDwtIHNhbXBsZShtb2VkYSwgc2l6ZSA9IDEwMCwgcmVwbGFjZSA9IFRSVUUsIHByb2I9YygwLjYsMC40KSkKcmVzdWx0YWRvcwpgYGAKQ29udGVtb3Mgb3MgcmVzdWx0YWRvczoKYGBge3J9CnRhYmxlKHJlc3VsdGFkb3MpCmBgYApPIGV4cGVyaW1lbnRvIHBvZGUgc2VyIHJlcGxpY2FkbyBxdWFudGFzIHZlemVzIHF1aXNlcm1vcywgZGlnYW1vcyA1IHZlemVzLCAgdXNhbmRvIG8gY29tYW5kbyAqcmVwbGljYXRlKjoKYGBge3J9CkIgPC0gNQpldmVudG9zIDwtIHJlcGxpY2F0ZShCLCBzYW1wbGUobW9lZGEsIHNpemUgPSAxMDAsIHJlcGxhY2UgPSBUUlVFLCBwcm9iPWMoMC42LDAuNCkpKQpzdW1tYXJ5KGV2ZW50b3MpCmBgYApObyB0b3RhbCB0ZW1vczoKYGBge3J9CnRhYmxlKGV2ZW50b3MpCmBgYAo8aDQ+IEV4ZW1wbG8gMy4yPC9oND4KU3Vwb25oYW1vcyBxdWUgdGVtb3MgdW1hIGNhaXhhIGNvbSA4IGJvbGFzIGlndWFpcywgbWFzIGNvbSBjb3JlcyBkaWZlcmVudGVzOiAgMiBib2xhcyBicmFuY2FzLCAzIGF6dWlzLCB1bWEgcHJldGEsIHVtYSB2ZXJtZWxoYSBlIHVtYSBhbWFyZWxhLgoKQSBjYWl4YSBjb20gYXMgYm9sYXMgcG9kZSBzZXIgcmVwcmVzZW50YWRhIGNvbSBhanVkYSBkbyBjb21hbmRvICA8c3BhbiBzdHlsZT0iZm9udC1mYW1pbHk6Q291cmFudDsgZm9udC1zaXplOjFlbTsiPnJlcDwvc3Bhbj4gZG8gUjogCmBgYHtyfQpib2xhcyA8LSByZXAoYygiYnJhbmNhIiwgImF6dWwiLCAicHJldGEiLCAidmVybWVsaGEiLCAiYW1hcmVsYSIpLHRpbWVzID0gYygyLDMsMSwxLDEpKQpib2xhcwpgYGAKU2VsZWNpb25lbW9zIGFsZWF0b3JpYW1lbnRlLCBzZW0gc3Vic3RpdHVpw6fDo28sIDQgYm9sYXM6IApgYGB7cn0Kc2FtcGxlKGJvbGFzLDQpCmBgYApTZSBvIGNvbWFuZG8gZm9yIHJlcGV0aWRvLCBvdXRyYSBjb25qdW50byBkZSBib2xhcyBzZXLDoSBvYnRpZG86IApgYGB7cn0Kc2FtcGxlKGJvbGFzLDQpCmBgYApSZXBsaXF1ZW1vcyBvIGV4cGVyaW1lbnRvIDEwIHZlemVzOgpgYGB7cn0KQiA8LSAxMApldmVudG9zIDwtIHJlcGxpY2F0ZShCLCBzYW1wbGUoYm9sYXMsNCkpCmV2ZW50b3MKYGBgClBvZGVtb3MgY29udGFyIGF1dG9tYXRpY2FtZW50ZSBvIG7Dum1lcm8gZGUgYm9sYXMgZGUgY2FkYSB0aXBvIG9idGlkYXMgZGEgc2VndWludGUgZm9ybWE6IApgYGB7cn0KdGFiIDwtIHRhYmxlKGV2ZW50b3MpCnRhYgpgYGAKClNlIHNlbGVjaW9uYXJtb3MgOCBib2xhcyBvIGNvbmp1bnRvIG9yaWdpbmFsIMOpIG9idGlkbzogCmBgYHtyfQpzYW1wbGUoYm9sYXMsOCkKYGBgCjxoND4gRXhlbXBsbyAzLjM8L2g0PgpWZWphbW9zIHF1YWwgw6kgYSBwcm9iYWJpbGlkYWRlIGRlIHF1ZSwgZW0gZHVhcyAgZXNjb2xoYXMsIHJlYWxpemFkYXMgc2VtIHN1YnN0aXR1acOnw6NvLCBvYnRlbmhhbW9zIGJvbGFzIGF6dWlzLiBEZW5vbWluZW1vcyB0YWwgcHJvYmFiaWxpZGFkZSBwb3IgJFByKEJCKSQuIMOJIGbDoWNpbCBtb3N0cmFyIHF1ZSAKJCQKUHIoQkIpPSBcZnJhY3szfXs4fVxjZG90IFxmcmFjezJ9ezd9ID0gIDAuMTA3MTQyOQokJApFc3RlICByZXN1bHRhZG8gw6ggaWTDqm50aWNvIMOgcXVlbGUgb2J0aWRvIG5vIEV4ZW1wbG8gMS4yLiBWZWphbW9zIGNvbW8gb2J0ZXIgZXN0ZSByZXN1bHRhZG8gYSBwYXJ0aXIgZGUgdW1hIHNpbXVsYcOnw6NvIGRlIE1vbnRlIENhcmxvLiBEZXZlbW9zIHJlcGV0aXIgbyBzZWd1aW50ZSBleHBlcmltZW50byBkaXZlcnNhcyB2ZXplcyBlIGNvbnRhciBvIG7Dum1lcm8gZGUgdmV6ZXMgcXVlIG9idGVtb3MgImF6dWwiICJhenVsIjoKYGBge3J9CmV4cGVyaW1lbnRvIDwtIHNhbXBsZShib2xhcywyKQpleHBlcmltZW50bwpgYGAKRmHDp2Ftb3MgbyBleHBlcmltZW50byAyMCB2ZXplczogCmBgYHtyfQpCIDwtMjAKYm9sYXNhenVpcyA8LSByZXBsaWNhdGUoQix7ZXhwZXJpbWVudG8gPC0gc2FtcGxlKGJvbGFzLDIpIAooZXhwZXJpbWVudG9bMV09PSJhenVsIiAmIGV4cGVyaW1lbnRvWzJdPT0iYXp1bCIpfSkKYm9sYXNhenVpcwpgYGAKTyBldmVudG8gQkIgb2NvcnJldSAyIHZlemVzLgpDYWxjdWxlbW9zIGEgcHJvcG9yw6fDo28gZGUgbsO6bWVybyBkZSBUUlVFIGUgbsO6bWVybyBkZSBGQUxTRSwgcXVlIMOpIGRhZGEgcGVsbyBjb21hbmRvICptZWFuKgpgYGB7cn0KbWVhbihib2xhc2F6dWlzKQpgYGAKRmHDp2Ftb3MgYWdvcmEgJDEwXjYkIHJlcGV0acOnw7VlczogCmBgYHtyfQpCIDwtMTAwMDAwMApib2xhc2F6dWlzIDwtIHJlcGxpY2F0ZShCLHtleHBlcmltZW50byA8LSBzYW1wbGUoYm9sYXMsMikgCihleHBlcmltZW50b1sxXT09ImF6dWwiICYgZXhwZXJpbWVudG9bMl09PSJhenVsIil9KQptZWFuKGJvbGFzYXp1aXMpCmBgYApkZSBtb2RvIHF1ZSByZW9idGVtb3MsIGFwcm94aW1hZGFtZW50ZSwgbyByZXN1bHRhZG8gZXNwZXJhZG8uIAoKPGg0PiBFeGVtcGxvIDMuNDwvaDQ+ClN1cG9uaGFtb3MgcXVlIHF1ZXJlbW9zIHNhYmVyIGFnb3JhIHF1YWwgw6kgYSBwcm9iYWJpbGlkYWRlICRQcihSV0IpJCAocmVkLHdoaXRlLGJsdWUpIGRlIG9idGVybW9zIGJvbGFzIHZlcm1lbGhhLCBicmFuY2EgZSBhenVsLCByZXNwZWN0aXZhbWVudGUsIGFvIHJldGlyYXJtb3MgMyBib2xhcywgc2VtIHN1YnN0aXR1acOnw6NvLiBTYWJlbW9zIHF1ZSAKJCQKUHIoUldCKT1cZnJhY3sxfXs4fVxmcmFjezJ9ezd9XGZyYWN7M317Nn09XGZyYWN7MX17NTZ9PSAwLjAxNzg1NzE0Mjg1XCwuCiQkClZlamFtb3MgY29tbyBvYnRlciBlc3RlIHJlc3VsdGFkbyBhIHBhcnRpciBkZSB1bWEgc2ltdWxhw6fDo28gZGUgTW9udGUgQ2FybG8sIGZhemVuZG8gJDEwXjYkICByZXBldGnDp8O1ZXM6IApgYGB7cn0KQiA8LTEwMDAwMDAKYm9sYXNjb2xvcmlkYXMgPC0gcmVwbGljYXRlKEIse2V4cGVyaW1lbnRvIDwtIHNhbXBsZShib2xhcywzKSAKKGV4cGVyaW1lbnRvWzFdPT0idmVybWVsaGEiICYgZXhwZXJpbWVudG9bMl09PSJicmFuY2EiICYgZXhwZXJpbWVudG9bM109PSJhenVsIil9KQptZWFuKGJvbGFzY29sb3JpZGFzKQpgYGAKcXVlIMOpLCBhcHJveGltYWRhbWVudGUsIG8gcmVzdWx0YWRvIGVzcGVyYWRvLiAKCjxoND4gRXhlbXBsbyAzLjU8L2g0PgpTdXBvbmhhbW9zIGFnb3JhIHF1ZSBzZWxlY2lvbmFtb3MgYWxlYXRvcmlhbWVudGUsIHNlbSBzdWJzdGl0dWnDp8OjbywgNSBib2xhcyBlIHF1ZXJlbW9zIHNhYmVyIHF1YWwgw6kgYSBwcm9iYWJpbGlkYWRlIGRlIHF1ZSBhbyBtZW5vcyAyIGJvbGFzIHNlamFtIGF6dWlzLiBQYXJhIHJlc29sdmVyIGVzdGUgcHJvYmxlbWEgcGVsbyBtw6l0b2RvIHRyYWRpY2lvbmFsIGFudGVyaW9yIHRlcsOtYW1vcyBxdWUgbGlzdGFyIG11aXRvcyBldmVudG9zICRZUkJCVyQsICRSV1dCQiQsIGV0Yy4sIGNhbGN1bGFyIGEgcHJvYmFiaWxpZGFkZSBkZSBjYWRhIGV2ZW50byBlIHNvbWFyLiBGYcOnYW1vcyB1bWEgc2ltdWxhw6fDo28gZGUgTW9udGUgQ2FybG8sIHVzYW5kbyBvIGNvbWFuZG8gPHNwYW4gc3R5bGU9ImZvbnQtZmFtaWx5OkNvdXJhbnQ7IGZvbnQtc2l6ZToxZW07Ij5zdHJfY291bnQ8L3NwYW4+IChwYWNvdGUgc3RyaW5ncikgcXVlIGZ1bmNpb25hIGRvIHNlZ3VpbnRlIG1vZG86IApgYGB7cn0KYm9sYXMgPC0gcmVwKGMoImJyYW5jYSIsICJhenVsIiwgInByZXRhIiwgInZlcm1lbGhhIiwgImFtYXJlbGEiKSx0aW1lcyA9IGMoMiwzLDEsMSwxKSkKYm9sYXMKYGBgCgpgYGB7cn0KcyA8LSBzYW1wbGUoYm9sYXMsNSkKcwpgYGAKQ29udGVtb3MgbyBuw7ptZXJvIGRlIGJvbGFzIHZlcm1lbGhhcyBuYSBhbW9zdHJhOiAKYGBge3J9CmxpYnJhcnkoc3RyaW5ncikKc3RyX2NvdW50KHMsICJhenVsIikKYGBgCk91IHNlamEsIHF1YW5kbyBvIHN0cmluZyDDqSBlbmNvbnRyYWRvIG8gdmFsb3IgMSDDqSBhdHJpYnXDrWRvIMOgIHJlc3BlY3RpdmEgY29tcG9uZW50ZSwgY2FzbyBjb250csOhcmlvIMOpIDAuIFBhcmEgZGV0ZXJtaW5hciBvIG7Dum1lcm8gZGUgb2NvcnLDqm5jaWFzIGRlIDEgbm8gdmV0b3IgdXNhbW9zIG8gY29tYW5kbzoKYGBge3J9Cm4gPC0gc3RyX2NvdW50KHMsICJhenVsIikKbGVuZ3RoKHdoaWNoKG49PTEpKQpgYGAKQXBsaWNhbmRvIGVzdGUgY29tYW5kbyBhbyBub3NzbyBwcm9ibGVtYSwgcmVwZXRpbmRvIG8gZXhwZXJpbWVudG8gJDEwXjYkIHZlemVzLCBhIHByb3BvcsOnw6NvIGRlIGNhc29zIG5vcyBxdWFpcyB0ZW1vcyBkdWFzIG91IG1haXMgYm9sYXMgYXp1aXMgw6k6CmBgYHtyfQpsaWJyYXJ5KHN0cmluZ3IpCkIgPC0gMTAwMDAwMApib2xhc2F6dWlzPC1yZXBsaWNhdGUoQix7ZXhwZXJpbWVudG8gPC0gc2FtcGxlKGJvbGFzLDUpIApuIDwtIHN0cl9jb3VudChleHBlcmltZW50bywgImF6dWwiKQpsZW5ndGgod2hpY2gobj09MSkpID49Mn0pCm1lYW4oYm9sYXNhenVpcykKYGBgCgpDb25zaWRlcmVtb3Mgbm92YW1lbnRlIG8gRXhlbXBsbyAyLjIsIHF1ZSBhZ29yYSBzZXLDoSByZXNvbHZpZG8gcG9yIG1laW8gZGUgc2ltdWxhw6fDo286IAoKPGg0PkV4ZW1wbG8gMy42PC9oND4gU3Vwb25oYW1vcyBxdWUgdW1hIGNhaXhhIHRlbW9zIDIgYm9sYXMgYnJhbmNhcywgMyBhenVpcywgdW1hIHByZXRhLCB1bWEgdmVybWVsaGEgZSB1bWEgYW1hcmVsYS4gUXVhbCDDqSBhIHByb2JhYmlsaWRhZGUgZGUgcXVlIG51bWEgc2VsZcOnw6NvIGRlIDQgYm9sYXMgb2J0ZW5oYW1vcyAyIGJvbGFzIGF6dWlzIGUgdW1hIGJvbGEgYW1hcmVsYT8KU29sdcOnw6NvLiAKUmVwcmVzZW50ZW1vcyBhIGNhaXhhIGRlIGJvbGFzOiAKYGBge3J9CmJvbGFzIDwtIHJlcChjKCJicmFuY2EiLCAiYXp1bCIsICJwcmV0YSIsICJ2ZXJtZWxoYSIsICJhbWFyZWxhIiksdGltZXMgPSBjKDIsMywxLDEsMSkpCmJvbGFzCmBgYAoKQSBwcm9wb3LDp8OjbyBkZSBjYXNvcyBub3MgcXVhaXMgdGVtb3MgZHVhcyBib2xhcyBhenVpcyBlIHVtYSBhbWFyZWxhIMOpOgpgYGB7cn0KbGlicmFyeShzdHJpbmdyKQpCIDwtIDEwMDAwMDAKYm9sYXNjb2xvcmlkYXM8LXJlcGxpY2F0ZShCLHtleHBlcmltZW50byA8LSBzYW1wbGUoYm9sYXMsNCkgCm4xIDwtIHN0cl9jb3VudChleHBlcmltZW50bywgImF6dWwiKQpuMiA8LSBzdHJfY291bnQoZXhwZXJpbWVudG8sICJhbWFyZWxhIikKKGxlbmd0aCh3aGljaChuMT09MSkpID09MikgICAmIChsZW5ndGgod2hpY2gobjI9PTEpKSA9PTEpICB9ICkgCm1lYW4oYm9sYXNjb2xvcmlkYXMpCmBgYApxdWUgw6kgc2ltaWxhciBhbyB2YWxvciAwLjE3MTQyODYgb2J0aWRvIG5vIEV4ZW1wbG8gMi4yLiAKCjxoND4gRXhlbXBsbyAzLjc8L2g0PgpEZSB1bWEgY2FpeGEgY29tIDIwIGJvbGFzLCBzZW5kbyA2IGJyYW5jYXMsICA0IHZlcm1lbGhhcywgIDcgYXp1aXMgZSAzIHZlcmRlcyBzw6NvIHNlbGVjaW9uYWRhcyA2LCBzZW0gc3Vic3RpdHVpw6fDo28uIAooaSkgUXVhbCDDqSBhIHByb2JhYmlsaWRhZGUgZGUgcXVlIGEgcHJpbWVpcmEgZSBhIMO6bHRpbWEgYm9sYSBkYSBzZWxlw6fDo28gc2VqYW0gYXp1aXM/IAooaWkpIFF1YWwgw6kgYSBwcm9iYWJpbGlkYWRlIGRlIHF1ZSBhbyBtZW5vcyB0csOqcyBib2xhcyBzZWphbSBicmFuY2FzPyAKPGg0PlNvbHXDp8OjbzwvaDQ+CihpKSBEZWZpbmltb3MgYSBjYWl4YSBjb20gYm9sYXM6IApgYGB7cn0KYm9sYXMgPC0gcmVwKGMoInJlZCIsICJibHVlIiwgIndoaXRlIiwgImdyZWVuIiksdGltZXMgPSBjKDQsNyw2LDMpKQpib2xhcwpgYGAKU2VsZWNpb25hbW9zIDYgYm9sYXMgZSByZXBldGltb3MgbyBleHBlcmltZW50byA5MDAgMDAwIHZlemVzLCBjb250YW5kbyBvIG7Dum1lcm8gZGUgdmV6ZXMgZW0gcXVlIGEgcHJpbWVpcmEgZSBhIHNleHRhIGJvbGEgc8OjbyBhenVpczoKYGBge3J9CkIgPC05MDAwMDAKYm9sYXNhenVpcyA8LSByZXBsaWNhdGUoQix7ZXhwZXJpbWVudG8gPC0gc2FtcGxlKGJvbGFzLDYpIAooZXhwZXJpbWVudG9bMV09PSJibHVlIiAmIGV4cGVyaW1lbnRvWzZdPT0iYmx1ZSIpfSkKbWVhbihib2xhc2F6dWlzKQpgYGAKKGlpKSBEZXZlbW9zIGFnb3JhIGNvbnRhYmlsaXphciB0b2RvcyBvcyBjYXNvcyBlbSBxdWUgdGVtb3MgMyBvdSBtYWlzIGJvbGFzIGJyYW5jYXM6CmBgYHtyfQpsaWJyYXJ5KHN0cmluZ3IpCkIgPC05MDAwMDAKQm9sYXNCcmFuY2FzIDwtIHJlcGxpY2F0ZShCLHtleHBlcmltZW50byA8LSBzYW1wbGUoYm9sYXMsNikgCm4gPC0gc3RyX2NvdW50KGV4cGVyaW1lbnRvLCAid2hpdGUiKQpsZW5ndGgod2hpY2gobj09MSkpID49M30pCm1lYW4oQm9sYXNCcmFuY2FzKQpgYGAKPGg0PkV4ZW1wbG8gMy44LiBKb2dvIGRlIHZvbGVpIDwvaDQ+ClRlbW9zIGRvaXMgdGltZXMgZGUgdm9sZWksIEJyYXNpbCBlIEFyZ2VudGluYSwgcXVlIGVzdMOjbyBqb2dhbmRvIHVtYSBzw6lyaWUgZGUgbWVsaG9yIGRlIDcgam9nb3MuIE8gQnJhc2lsIHRlbSB1bWEgZXF1aXBlIG1lbGhvciBlIHRlbSA2MCUgZGUgY2hhbmNlcyBkZSB2ZW5jZXIgdW0gZGFkbyBqb2dvLiA8YnI+CihpKSBRdWFsIMOpIGEgcHJvYmFiaWxpZGFkZSBkZSBxdWUgYSBBcmdlbnRpbmEgdmVuw6dhIGFvIG1lbm9zIHVtIGpvZ28/IDxicj4KKGlpKSBSZXNvbHZhIGVzdGUgcHJvYmxlbWEgdXNhbmRvIHNpbXVsYcOnw6NvIGRlIE1vbnRlIENhcmxvLiA8YnI+CioqU29sdcOnw6NvKio6IE5vdGVtb3MgcXVlIGEgQXJnZW50aW5hIHByZWNpc2EgdmVuY2VyIGFvIG1lbm9zIHVtIGpvZ28gZG9zIHByaW1laXJvcyA0IHBhcmEgcXVlIG7Do28gc2VqYSBlbGltaW5hZGEgc2VtIHZpdMOzcmlhcy4gQSBwcm9iYWJpbGlsaWRhZGUgZGUgcXVlIGlzc28gbsOjbyBhY29udGXDp2Egw6kgaWd1YWwgw6AgcHJvYmFiaWxpZGFkZSBkbyBCcmFzaWwgdmVuY2VyIG9zIDQgcHJpbWVpcm9zIGpvZ29zLCBvdSBzZWphLCAKYGBge3J9CnBfYnJhc2lsXzR2IDwtIDAuNl40CnBfYnJhc2lsXzR2CmBgYApQb3J0YW50bywgYSBwcm9iYWJpbGlkYWRlIGEgQXJnZW50aW5hIHZlbsOnYSBhbyBtZW5vcyB1bSBqb2dvIGVudHJlIG9zIDQgcHJpbWVpcm9zIMOpOgpgYGB7cn0KMS1wX2JyYXNpbF80dgpgYGAKKGlpKSBGYcOnYW1vcyBhIHNpbXVsYcOnw6NvIGRvIGV4cGVyaW1lbnRvIDEwMDAwMCB2ZXplcy4gQWdvcmEgcXVlIGFzIHByb2JhYmlsaWRhZGVzIGRvcyBldmVudG9zIHPDo28gZGlmZXJlbnRlcywgZGV2ZW1vcyBlc3BlY2lmaWPDoS1sYXMgcG9yIHVtIHZldG9yLiBBIG9ww6fDo28gcmVwbGFjZSA9IFRSVUUgYWdvcmEgw6kgbmVjZXNzw6FyaWEuIEEgb3DDp8OjbyAqYW55KiBkZSAqcmVwbGljYXRlKiBzaWduaWZpY2EgcXVlIGEgY29uZGnDp8OjbyAqd2luKiDDqSB2ZXJpZmljYWRhIHBhcmEgdG9kb3Mgb3MgZWxlbWVudG9zIGRhIGFtb3N0cmEuIApgYGB7cn0KQiA9IDEwMDAwMAphcmdlbnRpbmFfdmVuY2UgPC0gcmVwbGljYXRlKEIse3Jlc3VsdGFkb3MgPC0gc2FtcGxlKGMoImxvc2UiLCJ3aW4iKSwgNCwgcmVwbGFjZSA9IFRSVUUsIHByb2IgPSBjKDAuNiwwLjQpKSAKYW55KHJlc3VsdGFkb3M9PSJ3aW4iKX0pCm1lYW4oYXJnZW50aW5hX3ZlbmNlKQpgYGAKbyBxdWUgZXN0w6EgYXByb3hpbWFkYW1lbnRlIGRlIGFjb3JkbyBjb20gbyBjw6FsY3VsbyBleGF0by4gCgo8aDQ+RXhlbXBsbyAzLjkuIEpvZ28gZGUgdm9sZWkgKDIpIDwvaDQ+CkRvaXMgdGltZXMgZGUgdm9sZWksIEJyYXNpbCBlIFPDqXJ2aWEsIGVzdMOjbyBqb2dhbmRvIHVtYSBzw6lyaWUgZGUgNyBqb2dvcy4gTyBwcmltZWlybyBhIHZlbmNlciA0IGpvZ29zIHZlbmNlIGEgc8OpcmllLiBBbWJvcyBvcyB0aW1lcyBzw6NvIGVxdWlsaWJyYWRvcyBlIGFtYm9zIHTDqm0gaWd1YWlzIGNoYW5jZXMgZGUgdmVuY2VyIGNhZGEgam9nby4gClNlIG8gQnJhc2lsIHZlbmNlciBvIHByaW1laXJvIGpvZ28sIHF1YWwgw6kgYSBjaGFuY2UgZGUgcXVlIGVsZSB2ZW7Dp2EgYSBzw6lyaWU/IAooaSkgQ2FsY3VsZSBleGF0YW1lbnRlIAooaWkpIEZhw6dhIHVtYSBzaW11bGHDp8OjbyBkZSBNb250ZSBDYXJsby4KPGg0PiBTb2x1w6fDo28gPC9oND4KKGkpICBPIG7Dum1lcm8gZGUgam9nb3MgcmVzdGFudGVzIMOpICpuID0gNiouIERlZmluaW1vcyB1bWEgdmFyacOhdmVsIGNoYW1hZGEgKnJlc3VsdGFkb3MqLCBxdWUgw6kgbyB2ZXRvciBkZSBwb3Nzw612ZWlzIHJlc3VsdGFkb3MsIHNlbmRvIDAgdW1hIGRlcnJvdGEgZSAxIHVtYSB2aXTDs3JpYToKYGBge3J9CnJlc3VsdGFkb3MgPC0gYygwLDEpCmBgYApBIGZ1bsOnw6NvICpsaXN0KiBsaXN0YSBvIGNvbnRlw7pkbyBkbyB2ZXRvciBubyBhcmd1bWVudG86CmBgYHtyfQpsaXN0KHJlc3VsdGFkb3MpCmBgYApDcmlhbW9zIHVtYSBsaXN0YSAqTCogY29tIHRvZG9zIG9zIHBvc3PDrXZlaXMgcmVzdWx0YWRvcyBkb3Mgam9nb3MgcmVtYW5lc2NlbnRlczoKYGBge3J9CkwgPC0gcmVwbGljYXRlKDYsbGlzdChyZXN1bHRhZG9zKSkKTApgYGAKQ3JpYW1vcyB1bSAgZGF0YSBmcmFtZSBuYW1lZCAqcG9zc2liaWxpZGFkZXMqIHF1ZSBjb250w6ltIHRvZGFzIGFzIGNvbWJpbmHDp8O1ZXMgZGUgdG9kb3Mgb3MgcG9zc8OtdmVpcyByZXN1bHRhZG9zIHBhcmEgb3Mgam9nb3MgcmVtYW5lc2NlbnRlczoKYGBge3J9CnBvc3NpYmlsaWRhZGVzIDwtIGV4cGFuZC5ncmlkKEwpCnBvc3NpYmlsaWRhZGVzCmBgYApDcmlhbW9zIHVtIHZldG9yIGNoYW1hZG8gKnJlc3VsdGFkb3MqIHF1ZSBpbmRpY2Egc2UgY2FkYSBsaW5oYSBubyBkYXRhIGZyYW1lICpwb3NzaWJpbGlkYWRlcyogY29udMOpbSBvIG7Dum1lcm8gc3VmaWNpZW50ZSBkZSB2aXTDs3JpYXMgcGFyYSBxdWUgbyB0aW1lIGRvIEJyYXNpbCB2ZW7Dp2EgYSBzw6lyaWU6IApgYGB7cn0KcmVzdWx0YWRvcyA8LSByb3dTdW1zKHBvc3NpYmlsaWRhZGVzKT4zCnJlc3VsdGFkb3MKYGBgCkNhbGN1bGFtb3MgZW0gKnJlc3VsdGFkb3MqIGEgcHJvcG9yw6fDo28gZGUgY2Fzb3MgKCpUUlVFKikgZW0gcXVlIG8gQnJhc2lsIHZlbmNlIGEgc8OpcmllOgpgYGB7cn0KbWVhbihyZXN1bHRhZG9zKQpgYGAKRmHDp2Ftb3MgYWdvcmEgdW1hIHNpbXVsYcOnw6NvIGRlIE1vbnRlIENhcmxvLiBDcmlhbW9zIHVtIG9iamV0byBjaGFtYWRvICpyZXN1bHRhZG9zKiBxdWUgcmVwbGljYSBwYXJhICpCID0gMTAwMDAqIGl0ZXJhw6fDtWVzIHVtYSBzw6lyaWUgc2ltdWxhZGEgZSBkZXRlcm1pbmEgc2UgYSBzw6lyaWUgY29udMOpbSBhbyBtZW5vcyA0IHZpdMOzcmlhcywgbyBxdWUgZGFyaWEgdml0w7NyaWEgYW8gdGltZSBkbyBCcmFzaWwgZSBkZXBvaXMgY2FsY3VsZW1vcyBhIHByb3BvcsOnw6NvIGRlIGNhc29zICpUUlVFKgpgYGB7cn0KQiA8LSAxMDAwMApyZXN1bHRhZG9zIDwtIHJlcGxpY2F0ZShCLHN1bShyZXBsaWNhdGUoNiwgc2FtcGxlKGMoMCwxKSwxKSkpPjMpCm1lYW4ocmVzdWx0YWRvcykKYGBgCmRlIG1vZG8gcXVlIG9idGVtb3MgdW0gdmFsb3Igc2ltaWxhciBhYSBleGF0by4gCgo8aDQ+RXhlbXBsbyAzLjEwIFPDqXJpZXMgZGUgam9nb3MgY29tIGRpZmVyZW50ZXMgcHJvYmFiaWxpZGFkZXM8L2g0PgpEb2lzIHRpbWVzLCAqQSogZSAqQiogam9nYW0gdW1hIHPDqXJpZSBkZSA3IGpvZ29zLiBBIHByb2JhYmlsaWRhZGUgZGUgKkEqIHZlbmNlciAqQiogw6kgKnAqLiAKRGV0ZXJtaW5lIGFzIHByb2JhYmlsaWRhZGVzIGRlIHF1ZSAqQSogdmVuw6dhIGEgc8OpcmllIHBhcmEgKnAqID0gMC41LCAwLjUyNSwgMC41NTAsIC4uLiAgMC45NSwgZSBhcHJlc2VudGUgbyByZXN1bHRhZG8gZW0gdW0gZ3LDoWZpY28uIAo8aDQ+U29sdcOnw6NvPC9oND4KRGVmaW5pbW9zIG8gdmV0b3IgZGUgcHJvYmFiaWxpZGFkZXM6CmBgYHtyfSAKcCA8LSBzZXEoMC41LCAwLjk1LCAwLjAyNSkKcApgYGAKRGVmaW5pbW9zIGEgZnVuw6fDo286IApgYGB7cn0KcHJvYl9BX3ZlbmNlIDwtIGZ1bmN0aW9uKHApewogIEIgPC0gMTAwMDAKICByZXN1bHRhZG8gPC0gcmVwbGljYXRlKEIsIHsKICAgIEFfdmVuY2UgPC0gc2FtcGxlKGMoMSwwKSwgNywgcmVwbGFjZSA9IFRSVUUsIHByb2IgPSBjKDEsIDEtcCkpCiAgICBzdW0oQV92ZW5jZSk+PTQKICAgIH0pCiAgICBtZWFuKHJlc3VsdGFkbykKfQpgYGAKRmHDp2Ftb3MgYWdvcmEgYSBhdmFsaWHDp8OjbyBkYSBmdW7Dp8OjbyBwYXJhIGNhZGEgdmFsb3IgZGUgKnAqIGUgbyBjb3JyZXNwb25kZW50ZSBncsOhZmljbzoKYGBge3J9ClByIDwtIHNhcHBseShwLHByb2JfQV92ZW5jZSkKcGxvdChwLFByKQpgYGAKUG9kZW1vcyBjYWxjdWxhciB1bWEgcHJvYmFiaWxpZGFkZSBlc3BlY8OtZmljYS4gUG9yIGV4ZW1wbG8sIApgYGB7cn0KcHJvYl93aW4oMC42KQpgYGAKPGg0PkV4ZW1wbG8gMy4xMSBEaWZlcmVudGVzIG7Dum1lcm9zIGRlIGpvZ29zIGVtIGNhZGEgc8OpcmllPC9oND4gCkNvbnNpZGVyZW1vcyB1bSBwcm9ibGVtYSBzZW1lbGhhbnRlIGFvIGFudGVyaW9yLCBtYXMgYWdvcmEgY29tIHByb2JhYmlsaWRhZGUgZGUgcXVlICpBKiB2ZW7Dp2EgKkIqIGVtIHF1YWxxdWVyIGpvZ28gZml4YSBlbSAqcD0wLjcqLiBBIHZhcmnDoXZlbCBhZ29yYSDDqSBvICBuw7ptZXJvIGRlIGpvZ29zIGRhIHPDqXJpZS4gCjxoND5Tb2x1w6fDo28uIDwvaDQ+CkRldmVtb3MgYWdvcmEgZGVpeGFyIG8gbsO6bWVybyBkZSBqb2dvcyAqTiogY29tbyBhcmd1bWVudG86IApgYGB7cn0KcHJvYl9BX3ZlbmNlIDwtIGZ1bmN0aW9uKE4sIHA9MC43KXsKICAgICAgQiA8LSAxMDAwMAogICAgICByZXN1bHRhZG8gPC0gcmVwbGljYXRlKEIsIHsKICAgICAgICBBX3ZlbmNlIDwtIHNhbXBsZShjKDEsMCksIE4sIHJlcGxhY2UgPSBUUlVFLCBwcm9iID0gYyhwLCAxLXApKQogICAgICAgIHN1bShBX3ZlbmNlKT49KE4rMSkvMgogICAgICAgIH0pCiAgICAgICAgICAgIG1lYW4ocmVzdWx0YWRvKQogICAgfQpgYGAKRGVmaW5pbW9zIG9zIHBvc3PDrXZlaXMgdmFsb3JlcyBwYXJhICpOKiBjb21vIG7Dum1lcm9zIMOtbXBhcmVzIGRlIDEgYSAxOToKYGBge3J9Ck4gPC0gc2VxKDEsIDIwLCAyKQpOCmBgYApGYcOnYW1vcyBhZ29yYSBhIGF2YWxpYcOnw6NvIGRhIGZ1bsOnw6NvIHBhcmEgY2FkYSB2YWxvciBkZSAqTiogZSBvIGNvcnJlc3BvbmRlbnRlIGdyw6FmaWNvOgpgYGB7cn0KUHIgPC0gc2FwcGx5KE4scHJvYl9BX3ZlbmNlKQpwbG90KE4sUHIpCmBgYAoKCjxoND5SZWZlcsOqbmNpYXM8L2g0PgoKMS4gU2ltdWxhdGlvbnMgaW4gUiwgRGF0YWNhbXAsIERhdGEgQW5hbHlzaXMgYW5kIFN0YXRpc3RpY2FsIEluZmVyZW5jZSBodHRwczovL2NhbXB1cy5kYXRhY2FtcC5jb20vY291cnNlcy9zdGF0aXN0aWNhbC1pbmZlcmVuY2UtYW5kLWRhdGEtYW5hbHlzaXMvbGFiLTItcHJvYmFiaWxpdHk/ZXg9MTAKCjIuIENocmlzdGlhbiBSb2JlcnQsIEdlb3JnZSBDYXNlbGxhLiBJbnRyb2R1Y2luZyBNb250ZSBDYXJsbyBNZXRob2RzIHdpdGggUiwgU3ByaW5nZXIsIDIwMTAuCgozLiBNYXR0aGlhcyBUZW1wbC5TaW11bGF0aW9uIGZvciBEYXRhIFNjaWVuY2Ugd2l0aCBSIFBhY2t0LCAyMDE2LgoKNC4gVmlrcmFtIERheWFsLiBRdWFudGl0YXRpdmUgRWNvbm9taWNzIHdpdGggUiwgU3ByaW5nZXIsIDIwMjAuCg==