Características básicas dos dados

Os resumos foram coletados a partir do currículo lattes de 41 pesquisadores do LCNano. A partir dos currículos, foram obtidos 2536 Identificadores Digitais de Objetos (DOIs, do inglês Digital Object Identifiers). Desconsiderando duplicidades, onde dois pesquisadores compartilham publicações, ao todo foram encontrados 1774 DOIs distintos.

Para cada DOI, as bases Scopus e Crossref foram consultadas a fim de obter os resumos de cada publicação. Ao todo foram encontrados 378 resumos distintos.

A distribuição de resumos encontrados por ano de publicação pode ser vista na figura abaixo. Nota-se que a grande maioria dos resumos vêm de publicações a partir de 2009.

O menor e maior ano, bem como a média, mediana, primeiro e segundo quartis são:

      year     
 Min.   :1991  
 1st Qu.:2008  
 Median :2012  
 Mean   :2011  
 3rd Qu.:2015  
 Max.   :2019  

Ainda, considerando as duas épocas relevantes, observamos que 171 são da época <= 2010 e 207 da época >=2011.

Cada resumo foi dividido em palavras (ou tokens) para a análise com mineração de textos. Após isso, 1377 palavras de uso comum (stop words), como the, a, as, etc, foram removidas, pois não agregam informação à análise. Ao todo, são 30940 ocorrências de 5839 palavras distintas.

A distribuição do número de palavras por resumo pode ser vista abaixo.

As características da distribuição (menor, maior, média, mediana e quartis do número de palavras) são mostradas abaixo:

 number of words per abstract
 Min.   : 26.00              
 1st Qu.: 63.00              
 Median : 77.50              
 Mean   : 81.85              
 3rd Qu.: 99.00              
 Max.   :165.00              

Análise das palavras individuais

Nesta seção, são analizadas as palavras individuais dos resumos, sem considerar seu contexto ou posição no texto.

O ranque de palavras mais comuns pode ser visto no gráfico abaixo. As palavras surface, films, temperature e spectroscopy foram as mais frequentes.

As 100 palavras mais comuns também podem ser visualizadas na forma de nuvem de palavras:

Considerando as duas épocas relevantes, as palavras mais frequentes são visualizadas nos gráficos abaixo. Observamos que houve um crescimento no uso da palavra films, acid e water, enquanto que termos como ray e structure não foram tão comuns na época >= 2011.

A nuvem de palavras referente às duas épocas são mostradas nas figuras abaixo:

A figura abaixo compara a frequência de palavras entre as duas épocas. A frequência de uma palavra \(t\) na época \(d \in D\) é dada por \(f_{t,d} / \sum_i f_{t,i}\), onde \(f_{t,d}\) é o número de ocorrências da palavra na época \(d\). A reta pontilhada representa frequências iguais entre as duas épocas.

A correlação de Pearson entre as duas épocas pode ser vista abaixo. A correlação relativamente alta indica que as épocas são similares de acordo com o uso de termos nos resumos.


    Pearson's product-moment correlation

data:  token_frequencies$`<=2010` and token_frequencies$`>=2011`
t = 39.18, df = 1914, p-value < 2.2e-16
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
 0.6415196 0.6912653
sample estimates:
      cor 
0.6671355 

Para analizar a diferença entre as épocas utilizamos a medida de Frequência do Termo–Inverso da Frequência (Tf-idf, do inglês term frequency–inverse document frequency). O Tf-idf mede a importância de um termo dentro de uma coleção de documentos, no caso deste estudo, dentro de uma época. É o resultado da multiplicação da frequência de um termo normalizada (\(tf\)) pelo inverso da frequência, definido como: \(idf = log(N / n_t)\), onde \(N\) é o número de resumos e \(n_t\) é o número de resumos que contém o termo.

A figura abaixo relaciona os termos mais importantes de cada época, considerando a media Tf-idf. Nota-se que PVG, fin e receptors foram importantes na primeira época, enquanto que graphene, biomass e biochar destacam-se em resumos na segunda época.

Selecting by tf_idf

Os termos mais importantes, em termos de Tf-idf, entre os anos 2004 e 2017 são relacionados na figura abaixo:

Selecting by tf_idf

A comparação de núvens de palavras entre as duas épocas é mostrada abaixo. Na figura, o tamanho de uma palavra é proporcional ao maior desvio \(max_d(f_{t,d} - f_{d})\), onde \(f_{d}\) é a média da frequência do termo em todos os documentos (\(\sum_i f_{i,d}\)). Observamos que complex, heat, EPR, oxidation e xray são mais comuns a época <= 2010 em relação à época >= 2011, onde production, time e acid foram mais frequentes

Também é possível visualizar a nuvem de palavras comuns entre as épocas. Na figura abaixo o tamanho de um termo é proporcional ao mínimo de suas frequências nas duas épocas. Como observado anteriormente, spectroscopy, surface, films e temperature são palavras comuns em resumos nas duas épocas.

Análises com duplas de palavras

Nessa seção, são apresentadas análises com duplas de palavras e, dessa forma, devem incluir informações sobre o contexto onde as palavras são utilizadas.

As duplas de palavras mais comuns são apresentadas na figura abaixo. As duplas ray diffraction, electron microscopy e UV vis são mais frequentes.

Outra forma de visualizar duplas de palavras é como um grafo onde cada nó representa um termo e cada aresta conecta termos utilizados em sequência. Na figura abaixo observamos que sequências comuns como fourier transform infrared spectroscopy e uv vis spectroscopy.

Para as duas épocas, <= 2010 e >= 2011, identificamos duplas de palavras comuns na figura abaixo. Observamos que duplas como ray diffraction e uv vis eram comuns na primeira época enquanto que electron microscopy e ray diffraction são mais comuns na segunda época.

Da mesma forma, visualizamos abaixo o grafo com as sequências mais comuns na primeira e segunda época.

Modelos de tópico

Modelos de tópico são frequentemente utilizados para encontrar tópicos emergentes em um conjunto de documentos. De forma geral, um modelo de tópico considera que:

Com isso, dado o número de tópicos, é possível construir o modelo de tópico que melhor se encaixa a um conjunto de documentos.

Modelo com dois tópicos considerando cada resumo como um documento

Abaixo são apresentadas as palavras com maiores probabilidades (beta) de pertencer a cada tópico. Observamos que o primeiro tópico está relacionado com as palavras surface, films e spectroscopy, enquanto que o segundo está relacionado à model, heat e flow.

Abaixo são apresentados os principais resumos associados a cada um dos tópicos, de acordo com a probabilidade gamma.

Modelo com dois tópicos considerando o conjunto de resumos em um ano como documento

Abaixo são apresentados as palavras associadas aos tópicos associados à diferentes anos. O primeiro tópico trata de spectroscopy, ray e films, enquanto que o segundo trata de system, surface e temperature.

Diferentemente do modelo de tópico baseado em resumos, os tópicos baseados em anos possuem bastante intersecção. Isso pode indicar que, apesar de existirem artigos que tratam de assuntos diferentes, os mesmos assuntos são publicados ao longo do período.

Abaixo mostramos como cada ano pode ser relacionado com cada tópico (gamma). Os principais anos de cada tópico são 2014 e 2008, entretando não há uma divisão clara de épocas.

Modelo de dois tópicos considerando cada época como um documento

Considerando palavras em resumos da mesma época como pertencendo ao mesmo documentos, obtemos tópicos onde as palavras mais significantes (beta) são mostradas na figura. As principais palavras são spectroscopy e temperature para o primeiro tópico e films e suface para o segundo tópico.

A figura abaixo mostra a pertinência de cada época em cada tópico (gamma). Observamos que as épocas são bastante similares em relação aos tópicos modelados. Uma pequena diferença mostra que a época <= 2010 está mais relacionada ao tópico 1 (spectroscopy e temperature) e a época >= 2011 ao tópico 2 (films e suface).

Contagens de palavras-chave

Palavras-chave mais comuns em todas as publicações

Palavras-chave mais comuns por época

Palavras-chave mais comuns por grupo Nano e Não-Nano

Palavras-chave mais comuns por grupo Nano e Não-Nano e Época

Redes de palavras-chave agrupadas por publicação

Todas as publicações

Publicações Não-Nano

Publicações Não-Nano Época <= 2010

Publicações Não-Nano Época >= 2011

Publicações Nano

Publicações Nano da Época <=2010

Publicações Nano da Época >=2011

Grafos de palavras chaves agrupados por época

Palavras de publicações Nano e Não-Nano

Palavras de publicações Nano

Palavras de publicações Não-Nano

Palavras de publicações Nano

Redes de colaboração

Todas as publicações

Publicações Não-Nano

Publicações Não-Nano Época <=2010

Publicações Não-Nano Época >=2011

Publicações Nano

Publicações Nano Época <=2010

Publicações Nano Época >=2011

LS0tCnRpdGxlOiAiRXN0dWRvIGRvIGltcGFjdG8gZG8gTENOYW5vIGNvbSBiYXNlIGVtIGRhZG9zIGRlIHB1YmxpY2HDp8O1ZXMiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAogIHBkZl9kb2N1bWVudDoKICAgIGxhdGV4X2VuZ2luZTogeGVsYXRleAogIHdvcmRfZG9jdW1lbnQ6IGRlZmF1bHQKLS0tCgpgYGB7ciBzZXR1cCwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkodGlkeXRleHQpCmxpYnJhcnkodG0pCmxpYnJhcnkoc2NhbGVzKQpsaWJyYXJ5KHdvcmRjbG91ZCkKbGlicmFyeSh0bSkKbGlicmFyeSh4dGFibGUpCmxpYnJhcnkodG9waWNtb2RlbHMpCmxpYnJhcnkoaWdyYXBoKQpsaWJyYXJ5KGdncmFwaCkKbGlicmFyeSh3aWR5cikKCmRhdGEoc3RvcF93b3JkcykKCmxvYWQoImRhdGEvZm91bmRfYWJzdHJhY3RzLlJkYXRhIikKCmVwb2NocyA8LSBjKCI8PTIwMTAiLCAiPj0yMDExIikKZm91bmRfYWJzdHJhY3RzIDwtIGZvdW5kX2Fic3RyYWN0cyAlPiUKICBtdXRhdGUoCiAgICBlcG9jaCA9IGNhc2Vfd2hlbigKICAgICAgeWVhciA8PSAyMDEwIH4gZXBvY2hzWzFdLAogICAgICB5ZWFyID49IDIwMTEgfiBlcG9jaHNbMl0KICAgICkKICApCgoKbmFub19hYnN0cmFjdHMgPC0gZm91bmRfYWJzdHJhY3RzICU+JQogIGZpbHRlcihuYW5vKSAlPiUKICBtdXRhdGUoYWJzdHJhY3QgPSBzdHJfcmVwbGFjZV9hbGwoYWJzdHJhY3QsICI8Lio/PiIsICIgIikpCgprZXl3b3JkcyA8LSBmb3VuZF9hYnN0cmFjdHMgJT4lCiAgc2VsZWN0KGRvaSwgeWVhciwgZXBvY2gsIGtleXdvcmRzLCBuYW5vKSAlPiUKICB1bm5lc3QoKSAlPiUKICBtdXRhdGUoCiAgICBrZXl3b3JkcyA9IHN0cl90cmltKGtleXdvcmRzKSwKICAgIGtleXdvcmRzID0gc3RyX3RvX2xvd2VyKGtleXdvcmRzKSwKICAgIGtleXdvcmRzID0gbWFwX2Nocih0b2tlbml6ZXJzOjp0b2tlbml6ZV93b3JkcyhrZXl3b3JkcyksIH5wYXN0ZSgueCwgY29sbGFwc2UgPSAnICcpKQogICkKCgphdXRob3JzX25ldCA8LSBmb3VuZF9hYnN0cmFjdHMgJT4lIAogIG11dGF0ZShhdXRob3JzID0gc3RyX3NwbGl0KGF1dGhvcnMsICc7JykpICU+JQogIGdyb3VwX2J5KHllYXIsIG5hbm8sIGVwb2NoLCBkb2kpICU+JSAKICBuZXN0KCkgJT4lCiAgbXV0YXRlKGF1dGhvcnMgPSBtYXAoZGF0YSwgfnVubGlzdCh1bmlxdWUoLngkYXV0aG9ycykpKSkgJT4lCiAgc2VsZWN0KC1kYXRhKSAlPiUKICB1bm5lc3QoKQpgYGAKCmBgYHtyIHByZXByb2Nlc3MsIGVjaG89RkFMU0V9CgojIyB0b2tlbml6ZSBhbmQgcmVtb3ZlIHN0b3Agd29yZHMKCmV4dHJhX3N0b3Bfd29yZHMgPC0gZGF0YV9mcmFtZSgKICB3b3JkID0gYygKICAgICdhYnN0cmFjdCcsCiAgICAnb2J0YWluZWQnLAogICAgJ3Jlc3VsdHMnLAogICAgJ3Byb3BlcnRpZXMnLAogICAgJ2FuYWx5c2lzJywKICAgICdzYW1wbGVzJywKICAgICdvYnNlcnZlZCcsCiAgICAnY2hhcmFjdGVyaXplZCcsCiAgICAnYmFzZWQnLAogICAgJ2NvbXBhcmVkJywKICAgICdkZXRlY3Rpb24nLAogICAgJ2NvcnJvYm9yYXRlZCcsCiAgICAnc3VjY2Vzc2Z1bGx5JywKICAgICdhY2NvdW50aW5nJywKICAgICdhY3QnLAogICAgJ2FjY29tcGxpc2hlZCcsCiAgICAnYWRkZWQnLAogICAgJ2Ftb3VudCcsCiAgICAnYWN0aXZpdHknLAogICAgJ2FjaGlldmVkJywKICAgICdhY2hpZXZpbmcnLAogICAgJ2FsbG93aW5nJywKICAgICdjaGFuZ2VkJywKICAgICdhYnNlbmNlJywKICAgICdiZWhhdmlvcicsCiAgICBzdG9wd29yZHMoInB0LUJSIikKICApCikKCmFic3RyYWN0X3Rva2VucyA8LSBuYW5vX2Fic3RyYWN0cyAlPiUKICBzZWxlY3QoeWVhciwgZXBvY2gsIGRvaSwgYWJzdHJhY3QpICU+JQogIHVubmVzdF90b2tlbnMod29yZCwgYWJzdHJhY3QpICU+JQogIGFudGlfam9pbihzdG9wX3dvcmRzLCBieSA9ICJ3b3JkIikgJT4lCiAgYW50aV9qb2luKGV4dHJhX3N0b3Bfd29yZHMsIGJ5ID0gIndvcmQiKSAlPiUKICBmaWx0ZXIoIXN0cl9kZXRlY3Qod29yZCwgJ1swLTldJykpCgphbm9fZG9pIDwtIHJlYWRfY3N2KCJhbm9fZG9pLmNzdiIsIGNvbF90eXBlcyA9IGNvbHMoCiAgQU5PID0gY29sX2ludGVnZXIoKSwKICBET0kgPSBjb2xfY2hhcmFjdGVyKCkKKSkKYGBgCgojIyBDYXJhY3RlcsOtc3RpY2FzIGLDoXNpY2FzIGRvcyBkYWRvcwoKT3MgcmVzdW1vcyBmb3JhbSBjb2xldGFkb3MgYSBwYXJ0aXIgZG8gY3VycsOtY3VsbyBsYXR0ZXMgZGUgNDEgcGVzcXVpc2Fkb3JlcyBkbyBMQ05hbm8uIEEgcGFydGlyIGRvcyBjdXJyw61jdWxvcywgZm9yYW0gb2J0aWRvcyBgciBucm93KGFub19kb2kpYCBJZGVudGlmaWNhZG9yZXMgRGlnaXRhaXMgZGUgT2JqZXRvcyAoRE9JcywgZG8gaW5nbMOqcyBfRGlnaXRhbCBPYmplY3QgSWRlbnRpZmllcnNfKS4gRGVzY29uc2lkZXJhbmRvIGR1cGxpY2lkYWRlcywgb25kZSBkb2lzIHBlc3F1aXNhZG9yZXMgY29tcGFydGlsaGFtIHB1YmxpY2HDp8O1ZXMsIGFvIHRvZG8gZm9yYW0gZW5jb250cmFkb3MgYHIgbl9kaXN0aW5jdChhbm9fZG9pJERPSSlgIERPSXMgZGlzdGludG9zLgoKUGFyYSBjYWRhIERPSSwgYXMgYmFzZXMgU2NvcHVzIGUgQ3Jvc3NyZWYgZm9yYW0gY29uc3VsdGFkYXMgYSBmaW0gZGUgb2J0ZXIgb3MgcmVzdW1vcyBkZSBjYWRhIHB1YmxpY2HDp8Ojby4gQW8gdG9kbyBmb3JhbSBlbmNvbnRyYWRvcyBgciBuX2Rpc3RpbmN0KG5hbm9fYWJzdHJhY3RzJGRvaSlgIHJlc3Vtb3MgZGlzdGludG9zLgoKQSBkaXN0cmlidWnDp8OjbyBkZSByZXN1bW9zIGVuY29udHJhZG9zIHBvciBhbm8gZGUgcHVibGljYcOnw6NvIHBvZGUgc2VyIHZpc3RhIG5hIGZpZ3VyYSBhYmFpeG8uIE5vdGEtc2UgcXVlIGEgZ3JhbmRlIG1haW9yaWEgZG9zIHJlc3Vtb3MgdsOqbSBkZSBwdWJsaWNhw6fDtWVzIGEgcGFydGlyIGRlIDIwMDkuCgpgYGB7ciBlY2hvPUZBTFNFfQpuYW5vX2Fic3RyYWN0cyAlPiUgCiAgZ3JvdXBfYnkoeWVhcikgJT4lIAogIGNvdW50KGRvaSkgJT4lIAogIGdncGxvdCgpICsgCiAgZ2VvbV9iYXIoYWVzKHggPSB5ZWFyLCB5ID0gbiksIHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgbGFicyh5ID0gIm51bWJlciBvZiBhYnN0cmFjdHMiKQpgYGAKCk8gbWVub3IgZSBtYWlvciBhbm8sIGJlbSBjb21vIGEgbcOpZGlhLCBtZWRpYW5hLCBwcmltZWlybyBlIHNlZ3VuZG8gcXVhcnRpcyBzw6NvOgoKYGBge3IgZWNobz1GfQphYnN0cmFjdF90b2tlbnMgJT4lCiAgc2VsZWN0KHllYXIpICU+JQogIHN1bW1hcnkoKQpgYGAKCkFpbmRhLCBjb25zaWRlcmFuZG8gYXMgZHVhcyDDqXBvY2FzIHJlbGV2YW50ZXMsIG9ic2VydmFtb3MgcXVlIGByIGFzLmludGVnZXIobmFub19hYnN0cmFjdHMgJT4lIGZpbHRlcihlcG9jaCA9PSBlcG9jaHNbMV0pICU+JSBjb3VudChlcG9jaCkgJT4lIHNlbGVjdChuKSlgIHPDo28gZGEgw6lwb2NhIF88PSAyMDEwXyBlIGByIGFzLmludGVnZXIobmFub19hYnN0cmFjdHMgJT4lIGZpbHRlcihlcG9jaCA9PSBlcG9jaHNbMl0pICU+JSBjb3VudChlcG9jaCkgJT4lIHNlbGVjdChuKSlgIGRhIMOpcG9jYSBfPj0yMDExXy4KCkNhZGEgcmVzdW1vIGZvaSBkaXZpZGlkbyBlbSBwYWxhdnJhcyAob3UgdG9rZW5zKSBwYXJhIGEgYW7DoWxpc2UgY29tIG1pbmVyYcOnw6NvIGRlIHRleHRvcy4gQXDDs3MgaXNzbywgYHIgbGVuZ3RoKHN0b3Bfd29yZHMkd29yZCkgKyBsZW5ndGgoZXh0cmFfc3RvcF93b3JkcyR3b3JkKWAgcGFsYXZyYXMgZGUgdXNvIGNvbXVtIChfc3RvcCB3b3Jkc18pLCBjb21vIF90aGVfLCBfYV8sIF9hc18sIGV0YywgZm9yYW0gcmVtb3ZpZGFzLCBwb2lzIG7Do28gYWdyZWdhbSBpbmZvcm1hw6fDo28gw6AgYW7DoWxpc2UuIEFvIHRvZG8sIHPDo28gYHIgbGVuZ3RoKGFic3RyYWN0X3Rva2VucyR3b3JkKWAgb2NvcnLDqm5jaWFzIGRlIGByIG5fZGlzdGluY3QoYWJzdHJhY3RfdG9rZW5zJHdvcmQpYCBwYWxhdnJhcyBkaXN0aW50YXMuCgpBIGRpc3RyaWJ1acOnw6NvIGRvIG7Dum1lcm8gZGUgcGFsYXZyYXMgcG9yIHJlc3VtbyBwb2RlIHNlciB2aXN0YSBhYmFpeG8uCgpgYGB7ciBlY2hvPUZBTFNFfQphYnN0cmFjdF90b2tlbnMgJT4lCiAgZ3JvdXBfYnkoZG9pKSAlPiUKICBjb3VudChkb2kpICU+JQogIGdncGxvdCgpICsKICBnZW9tX2hpc3RvZ3JhbShhZXMoeCA9IG4pLCBiaW53aWR0aCA9IDEpICsKICBsYWJzKHggPSAiYWJzdHJhY3Qgc2l6ZSIsIHkgPSAibnVtYmVyIG9mIGFic3RyYWN0cyIpCmBgYAoKQXMgY2FyYWN0ZXLDrXN0aWNhcyBkYSBkaXN0cmlidWnDp8OjbyAobWVub3IsIG1haW9yLCBtw6lkaWEsIG1lZGlhbmEgZSBxdWFydGlzIGRvIG7Dum1lcm8gZGUgcGFsYXZyYXMpIHPDo28gbW9zdHJhZGFzIGFiYWl4bzoKCmBgYHtyIGVjaG89Rn0KYWJzdHJhY3RfdG9rZW5zICU+JQogIGdyb3VwX2J5KGRvaSkgJT4lCiAgY291bnQoZG9pKSAlPiUgdW5ncm91cCgpICU+JSAKICBzZWxlY3QobikgJT4lCiAgcmVuYW1lKGBudW1iZXIgb2Ygd29yZHMgcGVyIGFic3RyYWN0YCA9IG4pICU+JQogIHN1bW1hcnkoKQpgYGAKCiMjIEFuw6FsaXNlIGRhcyBwYWxhdnJhcyBpbmRpdmlkdWFpcwoKTmVzdGEgc2XDp8Ojbywgc8OjbyBhbmFsaXphZGFzIGFzIHBhbGF2cmFzIGluZGl2aWR1YWlzIGRvcyByZXN1bW9zLCBzZW0gY29uc2lkZXJhciBzZXUgY29udGV4dG8gb3UgcG9zacOnw6NvIG5vIHRleHRvLgoKTyByYW5xdWUgZGUgcGFsYXZyYXMgbWFpcyBjb211bnMgcG9kZSBzZXIgdmlzdG8gbm8gZ3LDoWZpY28gYWJhaXhvLiBBcyBwYWxhdnJhcyBfc3VyZmFjZV8sIF9maWxtc18sIF90ZW1wZXJhdHVyZV8gZSBfc3BlY3Ryb3Njb3B5XyBmb3JhbSBhcyBtYWlzIGZyZXF1ZW50ZXMuCgpgYGB7ciBlY2hvPUZ9CmFic3RyYWN0X3Rva2VucyAlPiUKICBjb3VudCh3b3JkLCBzb3J0ID0gVFJVRSkgJT4lCiAgdG9wX24oMjAsIHd0ID0gbikgJT4lCiAgbXV0YXRlKHdvcmQgPSByZW9yZGVyKHdvcmQsIG4pKSAlPiUKICBnZ3Bsb3QoYWVzKHdvcmQsIG4sIGZpbGw9bikpICsKICBnZW9tX2NvbCgpICsKICB4bGFiKE5VTEwpICsKICBjb29yZF9mbGlwKCkKYGBgCgpBcyAxMDAgcGFsYXZyYXMgbWFpcyBjb211bnMgdGFtYsOpbSBwb2RlbSBzZXIgdmlzdWFsaXphZGFzIG5hIGZvcm1hIGRlIG51dmVtIGRlIHBhbGF2cmFzOgoKYGBge3IgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgZWNobz1GQUxTRX0KcGx0LmR0IDwtIGFic3RyYWN0X3Rva2VucyAlPiUKICBjb3VudCh3b3JkKQp3b3JkY2xvdWQocGx0LmR0JHdvcmQsIHBsdC5kdCRuLCByYW5kb20ub3JkZXIgPSBGLCBtYXgud29yZHMgPSA1MCkKYGBgCgpDb25zaWRlcmFuZG8gYXMgZHVhcyDDqXBvY2FzIHJlbGV2YW50ZXMsIGFzIHBhbGF2cmFzIG1haXMgZnJlcXVlbnRlcyBzw6NvIHZpc3VhbGl6YWRhcyBub3MgZ3LDoWZpY29zIGFiYWl4by4gT2JzZXJ2YW1vcyBxdWUgaG91dmUgdW0gY3Jlc2NpbWVudG8gbm8gdXNvIGRhIHBhbGF2cmEgX2ZpbG1zXywgX2FjaWRfIGUgX3dhdGVyXywgZW5xdWFudG8gcXVlIHRlcm1vcyBjb21vIF9yYXlfIGUgX3N0cnVjdHVyZV8gbsOjbyBmb3JhbSB0w6NvIGNvbXVucyBuYSDDqXBvY2EgXz49IDIwMTFfLgoKYGBge3IgZWNobz1GfQpwbHQuZHQgPC0gYWJzdHJhY3RfdG9rZW5zICU+JQogIGdyb3VwX2J5KGVwb2NoKSAlPiUKICBjb3VudCh3b3JkKSAlPiUKICB0b3BfbigyMCwgd3QgPSBuKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgYXJyYW5nZShlcG9jaCwgbikgJT4lCiAgbXV0YXRlKG9yZGVyID0gcm93X251bWJlcigpKQoKcGx0LmR0ICU+JSAgCiAgZ2dwbG90KGFlcyhvcmRlciwgbiwgZmlsbCA9IGVwb2NoKSkgKwogIGdlb21fY29sKCkgKwogIGZhY2V0X3dyYXAofmVwb2NoLCBzY2FsZXMgPSAiZnJlZSIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoCiAgICBicmVha3MgPSBwbHQuZHQkb3JkZXIsCiAgICBsYWJlbHMgPSBwbHQuZHQkd29yZCwKICAgIGV4cGFuZCA9IGMoMCwwKQogICkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKwogIGNvb3JkX2ZsaXAoKQpgYGAKCkEgbnV2ZW0gZGUgcGFsYXZyYXMgcmVmZXJlbnRlIMOgcyBkdWFzIMOpcG9jYXMgc8OjbyBtb3N0cmFkYXMgbmFzIGZpZ3VyYXMgYWJhaXhvOgoKYGBge3IgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgZWNobz1GQUxTRX0KcGx0LmR0IDwtIGFic3RyYWN0X3Rva2VucyAlPiUKICBncm91cF9ieShlcG9jaCkgJT4lCiAgY291bnQod29yZCkKCnBsdC5kdDEgPC0gcGx0LmR0ICU+JQogIGZpbHRlcihlcG9jaCA9PSBlcG9jaHNbMV0pCgp3b3JkY2xvdWQocGx0LmR0MSR3b3JkLCBwbHQuZHQxJG4sIHJhbmRvbS5vcmRlciA9IEYsIG1heC53b3JkcyA9IDEwMCkKCnBsdC5kdDIgPC0gcGx0LmR0ICU+JSAKICBmaWx0ZXIoZXBvY2ggPT0gZXBvY2hzWzJdKQoKd29yZGNsb3VkKHBsdC5kdDIkd29yZCwgcGx0LmR0MiRuLCByYW5kb20ub3JkZXIgPSBGLCBtYXgud29yZHMgPSAxMDApCmBgYAoKQSBmaWd1cmEgYWJhaXhvIGNvbXBhcmEgYSBmcmVxdcOqbmNpYSBkZSBwYWxhdnJhcyBlbnRyZSBhcyBkdWFzIMOpcG9jYXMuIEEgZnJlcXXDqm5jaWEgZGUgdW1hIHBhbGF2cmEgJHQkIG5hIMOpcG9jYSAkZCBcaW4gRCQgw6kgZGFkYSBwb3IgJGZfe3QsZH0gLyBcc3VtX2kgZl97dCxpfSQsIG9uZGUgJGZfe3QsZH0kIMOpIG8gbsO6bWVybyBkZSBvY29ycsOqbmNpYXMgZGEgcGFsYXZyYSBuYSDDqXBvY2EgJGQkLiBBIHJldGEgcG9udGlsaGFkYSByZXByZXNlbnRhIGZyZXF1w6puY2lhcyBpZ3VhaXMgZW50cmUgYXMgZHVhcyDDqXBvY2FzLgoKYGBge3IgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgZWNobz1GQUxTRX0KdG9rZW5fZnJlcXVlbmNpZXMgPC0gYWJzdHJhY3RfdG9rZW5zICU+JQogIGNvdW50KGVwb2NoLCB3b3JkLCBzb3J0ID0gVFJVRSkgJT4lCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuIC8gc3VtKG4pKSAlPiUgCiAgc2VsZWN0KC1uKSAlPiUgCiAgc3ByZWFkKGVwb2NoLCBwcm9wb3J0aW9uKQoKdG9rZW5fZnJlcXVlbmNpZXMgJT4lCiAgZ2dwbG90KGFlcyh4ID0gYDw9MjAxMGAsIHkgPSBgPj0yMDExYCkpICsKICBnZW9tX2FibGluZShjb2xvciA9ICJncmF5NDAiLCBsdHkgPSAyKSArCiAgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAwLjEsIHNpemUgPSAyLjUsIHdpZHRoID0gMC4zLCBoZWlnaHQgPSAwLjMpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gd29yZCksIGNoZWNrX292ZXJsYXAgPSBUUlVFKSArCiAgc2NhbGVfeF9sb2cxMChsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdCgpKSArCiAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdCgpKSArCiAgc2NhbGVfY29sb3JfZ3JhZGllbnQobGltaXRzID0gYygwLCAwLjAwMSksIGxvdyA9ICJkYXJrc2xhdGVncmF5NCIsIGhpZ2ggPSAiZ3JheTc1IikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCmBgYAoKQSBjb3JyZWxhw6fDo28gZGUgUGVhcnNvbiBlbnRyZSBhcyBkdWFzIMOpcG9jYXMgcG9kZSBzZXIgdmlzdGEgYWJhaXhvLiBBIGNvcnJlbGHDp8OjbyByZWxhdGl2YW1lbnRlIGFsdGEgaW5kaWNhIHF1ZSBhcyDDqXBvY2FzIHPDo28gc2ltaWxhcmVzIGRlIGFjb3JkbyBjb20gbyB1c28gZGUgdGVybW9zIG5vcyByZXN1bW9zLgoKYGBge3IgZWNobz1GfQpjb3IudGVzdCh0b2tlbl9mcmVxdWVuY2llcyRgPD0yMDEwYCwgdG9rZW5fZnJlcXVlbmNpZXMkYD49MjAxMWApCmBgYAoKUGFyYSBhbmFsaXphciBhIGRpZmVyZW7Dp2EgZW50cmUgYXMgw6lwb2NhcyB1dGlsaXphbW9zIGEgbWVkaWRhIGRlIEZyZXF1w6puY2lhIGRvIFRlcm1v4oCTSW52ZXJzbyBkYSBGcmVxdcOqbmNpYSAoVGYtaWRmLCBkbyBpbmdsw6pzIF90ZXJtIGZyZXF1ZW5jeeKAk2ludmVyc2UgZG9jdW1lbnQgZnJlcXVlbmN5XykuIE8gVGYtaWRmIG1lZGUgYSBpbXBvcnTDom5jaWEgZGUgdW0gdGVybW8gZGVudHJvIGRlIHVtYSBjb2xlw6fDo28gZGUgZG9jdW1lbnRvcywgbm8gY2FzbyBkZXN0ZSBlc3R1ZG8sIGRlbnRybyBkZSB1bWEgw6lwb2NhLiDDiSBvIHJlc3VsdGFkbyBkYSBtdWx0aXBsaWNhw6fDo28gZGEgZnJlcXXDqm5jaWEgZGUgdW0gdGVybW8gbm9ybWFsaXphZGEgKCR0ZiQpIHBlbG8gaW52ZXJzbyBkYSBmcmVxdcOqbmNpYSwgZGVmaW5pZG8gY29tbzogJGlkZiA9IGxvZyhOIC8gbl90KSQsIG9uZGUgJE4kIMOpIG8gbsO6bWVybyBkZSByZXN1bW9zIGUgJG5fdCQgw6kgbyBuw7ptZXJvIGRlIHJlc3Vtb3MgcXVlIGNvbnTDqW0gbyB0ZXJtby4KCkEgZmlndXJhIGFiYWl4byByZWxhY2lvbmEgb3MgdGVybW9zIG1haXMgaW1wb3J0YW50ZXMgZGUgY2FkYSDDqXBvY2EsIGNvbnNpZGVyYW5kbyBhIG1lZGlhIFRmLWlkZi4gTm90YS1zZSBxdWUgX1BWR18sIF9maW5fIGUgX3JlY2VwdG9yc18gZm9yYW0gaW1wb3J0YW50ZXMgbmEgcHJpbWVpcmEgw6lwb2NhLCBlbnF1YW50byBxdWUgX2dyYXBoZW5lXywgX2Jpb21hc3NfIGUgX2Jpb2NoYXJfIGRlc3RhY2FtLXNlIGVtIHJlc3Vtb3MgbmEgc2VndW5kYSDDqXBvY2EuCgpgYGB7ciBlY2hvPUZBTFNFfQphYnN0cmFjdF90b2tlbnMgJT4lCiAgY291bnQoZXBvY2gsIHdvcmQsIHNvcnQgPSBUUlVFKSAlPiUKICBiaW5kX3RmX2lkZih3b3JkLCBlcG9jaCwgbikgJT4lCiAgYXJyYW5nZShkZXNjKHRmX2lkZikpICU+JQogIG11dGF0ZSh3b3JkID0gZmFjdG9yKHdvcmQsIGxldmVscyA9IHJldih1bmlxdWUod29yZCkpKSkgJT4lIAogIGdyb3VwX2J5KGVwb2NoKSAlPiUgCiAgdG9wX24oMjApICU+JSAKICB1bmdyb3VwICU+JQogIGdncGxvdChhZXMod29yZCwgdGZfaWRmLCBmaWxsID0gZXBvY2gpKSArCiAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGxhYnMoeCA9IE5VTEwsIHkgPSAidGYtaWRmIikgKwogIGZhY2V0X3dyYXAofmVwb2NoLCBuY29sID0gMiwgc2NhbGVzID0gImZyZWUiKSArCiAgY29vcmRfZmxpcCgpCmBgYAoKT3MgdGVybW9zIG1haXMgaW1wb3J0YW50ZXMsIGVtIHRlcm1vcyBkZSBUZi1pZGYsIGVudHJlIG9zIGFub3MgMjAwNCBlIDIwMTcgc8OjbyByZWxhY2lvbmFkb3MgbmEgZmlndXJhIGFiYWl4bzoKCmBgYHtyIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD02fQphYnN0cmFjdF90b2tlbnMgJT4lCiAgZmlsdGVyKHllYXIgPj0gMjAwNCwgeWVhciA8PSAyMDE3KSAlPiUKICBjb3VudChlcG9jaCwgeWVhciwgd29yZCwgc29ydCA9IFRSVUUpICU+JQogIGJpbmRfdGZfaWRmKHdvcmQsIHllYXIsIG4pICU+JQogIGFycmFuZ2UoZGVzYyh0Zl9pZGYpKSAlPiUKICBtdXRhdGUod29yZCA9IGZhY3Rvcih3b3JkLCBsZXZlbHMgPSByZXYodW5pcXVlKHdvcmQpKSkpICU+JQogIGdyb3VwX2J5KGVwb2NoLCB5ZWFyKSAlPiUgCiAgdG9wX24oNSkgJT4lIAogIHVuZ3JvdXAoKSAlPiUKICBnZ3Bsb3QoYWVzKHdvcmQsIHRmX2lkZiwgZmlsbCA9IGVwb2NoKSkgKwogIGdlb21fY29sKHNob3cubGVnZW5kID0gRkFMU0UpICsKICBsYWJzKHggPSBOVUxMLCB5ID0gInRmLWlkZiIpICsKICBmYWNldF93cmFwKH55ZWFyLCBuY29sID0gMiwgc2NhbGVzID0gImZyZWVfeSIpICsKICBjb29yZF9mbGlwKCkKYGBgCgpBIGNvbXBhcmHDp8OjbyBkZSBuw7p2ZW5zIGRlIHBhbGF2cmFzIGVudHJlIGFzIGR1YXMgw6lwb2NhcyDDqSBtb3N0cmFkYSBhYmFpeG8uIE5hIGZpZ3VyYSwgbyB0YW1hbmhvIGRlIHVtYSBwYWxhdnJhIMOpIHByb3BvcmNpb25hbCBhbyBtYWlvciBkZXN2aW8gJG1heF9kKGZfe3QsZH0gLSBmX3tkfSkkLCBvbmRlICRmX3tkfSQgw6kgYSBtw6lkaWEgZGEgZnJlcXXDqm5jaWEgZG8gdGVybW8gZW0gdG9kb3Mgb3MgZG9jdW1lbnRvcyAoJFxzdW1faSBmX3tpLGR9JCkuIE9ic2VydmFtb3MgcXVlIF9jb21wbGV4XywgX2hlYXRfLCBfRVBSXywgX294aWRhdGlvbl8gZSBfeHJheV8gc8OjbyBtYWlzIGNvbXVucyBhIMOpcG9jYSBfPD0gMjAxMF8gZW0gcmVsYcOnw6NvIMOgIMOpcG9jYSBfPj0gMjAxMV8sIG9uZGUgX3Byb2R1Y3Rpb25fLCBfdGltZV8gZSBfYWNpZF8gZm9yYW0gbWFpcyBmcmVxdWVudGVzCgpgYGB7ciBlY2hvPUZBTFNFLCBjYWNoZT1UUlVFLCB3YXJuaW5nPUZBTFNFfQpuYW5vX2Fic3RyYWN0c19lcG9jaCA8LSBuYW5vX2Fic3RyYWN0cyAlPiUKICBncm91cF9ieShlcG9jaCkgJT4lCiAgc3VtbWFyaXNlKGFic3RyYWN0ID0gcGFzdGUoYWJzdHJhY3QsIGNvbGxhcHNlID0gIiAiKSkKCmVwb2Noc19jb3JwdXMgPC0gQ29ycHVzKFZlY3RvclNvdXJjZShuYW5vX2Fic3RyYWN0c19lcG9jaCRhYnN0cmFjdCkpICU+JQogIHRtX21hcChyZW1vdmVQdW5jdHVhdGlvbikgJT4lCiAgdG1fbWFwKHJlbW92ZU51bWJlcnMpICU+JQogIHRtX21hcCh0b2xvd2VyKSAgJT4lCiAgdG1fbWFwKHJlbW92ZVdvcmRzLCBjKHN0b3Bfd29yZHMkd29yZCwgZXh0cmFfc3RvcF93b3JkcyR3b3JkKSkgJT4lCiAgdG1fbWFwKHN0cmlwV2hpdGVzcGFjZSkKCmVwb2Noc190ZG0gPC0gVGVybURvY3VtZW50TWF0cml4KGVwb2Noc19jb3JwdXMpICU+JQogIGFzLm1hdHJpeCgpCmNvbG5hbWVzKGVwb2Noc190ZG0pIDwtIGVwb2NocwpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0xMCwgZWNobz1GQUxTRX0KY29tcGFyaXNvbi5jbG91ZChlcG9jaHNfdGRtLCBtYXgud29yZHMgPSAyMDApCmBgYAoKVGFtYsOpbSDDqSBwb3Nzw612ZWwgdmlzdWFsaXphciBhIG51dmVtIGRlIHBhbGF2cmFzIGNvbXVucyBlbnRyZSBhcyDDqXBvY2FzLiBOYSBmaWd1cmEgYWJhaXhvIG8gdGFtYW5obyBkZSB1bSB0ZXJtbyDDqSBwcm9wb3JjaW9uYWwgYW8gbcOtbmltbyBkZSBzdWFzIGZyZXF1w6puY2lhcyBuYXMgZHVhcyDDqXBvY2FzLiBDb21vIG9ic2VydmFkbyBhbnRlcmlvcm1lbnRlLCBfc3BlY3Ryb3Njb3B5XywgX3N1cmZhY2VfLCBfZmlsbXNfIGUgX3RlbXBlcmF0dXJlXyBzw6NvIHBhbGF2cmFzIGNvbXVucyBlbSByZXN1bW9zIG5hcyBkdWFzIMOpcG9jYXMuCgpgYGB7ciBmaWcuaGVpZ2h0PTEwLCBmaWcud2lkdGg9MTAsIGVjaG89RkFMU0V9CmNvbW1vbmFsaXR5LmNsb3VkKGVwb2Noc190ZG0sIHJhbmRvbS5vcmRlciA9IEYsIG1heC53b3Jkcz0yMDApCmBgYAoKIyMgQW7DoWxpc2VzIGNvbSBkdXBsYXMgZGUgcGFsYXZyYXMKCk5lc3NhIHNlw6fDo28sIHPDo28gYXByZXNlbnRhZGFzIGFuw6FsaXNlcyBjb20gZHVwbGFzIGRlIHBhbGF2cmFzIGUsIGRlc3NhIGZvcm1hLCBkZXZlbSBpbmNsdWlyIGluZm9ybWHDp8O1ZXMgc29icmUgbyBjb250ZXh0byBvbmRlIGFzIHBhbGF2cmFzIHPDo28gdXRpbGl6YWRhcy4KCkFzIGR1cGxhcyBkZSBwYWxhdnJhcyBtYWlzIGNvbXVucyBzw6NvIGFwcmVzZW50YWRhcyBuYSBmaWd1cmEgYWJhaXhvLiBBcyBkdXBsYXMgX3JheSBkaWZmcmFjdGlvbl8sIF9lbGVjdHJvbiBtaWNyb3Njb3B5XyBlIF9VViB2aXNfIHPDo28gbWFpcyBmcmVxdWVudGVzLgoKYGBge3IsIGVjaG89RkFMU0V9CmJpZ3JhbXMgPC0gbmFub19hYnN0cmFjdHMgJT4lCiAgc2VsZWN0KHllYXIsIGVwb2NoLCBkb2ksIGFic3RyYWN0KSAlPiUKICB1bm5lc3RfdG9rZW5zKGJpZ3JhbSwgYWJzdHJhY3QsIHRva2VuID0gIm5ncmFtcyIsIG4gPSAyKSAlPiUKICBzZXBhcmF0ZShiaWdyYW0sIGMoIndvcmQxIiwgIndvcmQyIiksIHNlcCA9ICIgIikgJT4lCiAgZmlsdGVyKCF3b3JkMSAlaW4lIGMoc3RvcF93b3JkcyR3b3JkLCBleHRyYV9zdG9wX3dvcmRzKSwKICAgICAgICAgIXdvcmQyICVpbiUgYyhzdG9wX3dvcmRzJHdvcmQsIGV4dHJhX3N0b3Bfd29yZHMpKQoKYmlncmFtcyAlPiUKICBjb3VudCh3b3JkMSwgd29yZDIsIHNvcnQgPSBUUlVFKSAlPiUKICB0b3BfbigyMCwgd3QgPSBuKSAlPiUKICBtdXRhdGUod29yZCA9IHBhc3RlKHdvcmQxLCB3b3JkMiksCiAgICAgICAgIHdvcmQgPSByZW9yZGVyKHdvcmQsIG4pKSAlPiUKICBnZ3Bsb3QoYWVzKHdvcmQsIG4pKSArCiAgZ2VvbV9jb2woKSArCiAgeGxhYihOVUxMKSArCiAgY29vcmRfZmxpcCgpCmBgYAoKT3V0cmEgZm9ybWEgZGUgdmlzdWFsaXphciBkdXBsYXMgZGUgcGFsYXZyYXMgw6kgY29tbyB1bSBncmFmbyBvbmRlIGNhZGEgbsOzIHJlcHJlc2VudGEgdW0gdGVybW8gZSBjYWRhIGFyZXN0YSBjb25lY3RhIHRlcm1vcyB1dGlsaXphZG9zIGVtIHNlcXXDqm5jaWEuIE5hIGZpZ3VyYSBhYmFpeG8gb2JzZXJ2YW1vcyBxdWUgc2VxdcOqbmNpYXMgY29tdW5zIGNvbW8gX2ZvdXJpZXIgdHJhbnNmb3JtIGluZnJhcmVkIHNwZWN0cm9zY29weV8gZSBfdXYgdmlzIHNwZWN0cm9zY29weV8uCgpgYGB7ciBmaWcuaGVpZ2h0PTEwLCBmaWcud2lkdGg9MTAsIGVjaG89RkFMU0V9CnNldC5zZWVkKDIwMTYpCmEgPC0gZ3JpZDo6YXJyb3codHlwZSA9ICJjbG9zZWQiLCBsZW5ndGggPSB1bml0KC4xNSwgImluY2hlcyIpKQogIApiaWdyYW1zICU+JQogIGNvdW50KHdvcmQxLCB3b3JkMiwgc29ydCA9IFRSVUUpICU+JQogIGZpbHRlcihuID4gMjApICU+JQogIGdyYXBoX2Zyb21fZGF0YV9mcmFtZSgpICU+JQogIGdncmFwaChsYXlvdXQgPSAiZnIiKSArCiAgZ2VvbV9lZGdlX2xpbmsoYWVzKGVkZ2VfYWxwaGEgPSBuKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSwgYXJyb3cgPSBhKSArCiAgZ2VvbV9ub2RlX3BvaW50KGNvbG9yID0gImxpZ2h0Ymx1ZSIsIHNpemUgPSA1KSArCiAgZ2VvbV9ub2RlX3RleHQoYWVzKGxhYmVsID0gbmFtZSksIHZqdXN0ID0gMSwgaGp1c3QgPSAxKSArCiAgdGhlbWVfdm9pZCgpCmBgYAoKUGFyYSBhcyBkdWFzIMOpcG9jYXMsIF88PSAyMDEwXyBlIF8+PSAyMDExXywgaWRlbnRpZmljYW1vcyBkdXBsYXMgZGUgcGFsYXZyYXMgY29tdW5zIG5hIGZpZ3VyYSBhYmFpeG8uIE9ic2VydmFtb3MgcXVlIGR1cGxhcyBjb21vIF9yYXkgZGlmZnJhY3Rpb25fIGUgX3V2IHZpc18gZXJhbSBjb211bnMgbmEgcHJpbWVpcmEgw6lwb2NhIGVucXVhbnRvIHF1ZSBfZWxlY3Ryb24gbWljcm9zY29weV8gZSBfcmF5IGRpZmZyYWN0aW9uXyBzw6NvIG1haXMgY29tdW5zIG5hIHNlZ3VuZGEgw6lwb2NhLgoKYGBge3IgZWNobz1GQUxTRX0KcGx0LmR0IDwtIGJpZ3JhbXMgJT4lCiAgZ3JvdXBfYnkoZXBvY2gpICU+JQogIGNvdW50KHdvcmQxLCB3b3JkMiwgc29ydCA9IFRSVUUpICU+JQogIHRvcF9uKDIwLCB3dCA9IG4pICU+JQogIHVuZ3JvdXAoKSAlPiUKICBhcnJhbmdlKGVwb2NoLCBuKSAlPiUKICBtdXRhdGUob3JkZXIgPSByb3dfbnVtYmVyKCksCiAgICAgICAgIHdvcmQgPSBwYXN0ZSh3b3JkMSwgd29yZDIpKQoKcGx0LmR0ICU+JSAgCiAgZ2dwbG90KGFlcyhvcmRlciwgbiwgZmlsbCA9IGVwb2NoKSkgKwogIGdlb21fY29sKCkgKwogIGZhY2V0X3dyYXAofmVwb2NoLCBzY2FsZXMgPSAiZnJlZSIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoCiAgICBicmVha3MgPSBwbHQuZHQkb3JkZXIsCiAgICBsYWJlbHMgPSBwbHQuZHQkd29yZCwKICAgIGV4cGFuZCA9IGMoMCwwKQogICkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKwogIGNvb3JkX2ZsaXAoKQpgYGAKCkRhIG1lc21hIGZvcm1hLCB2aXN1YWxpemFtb3MgYWJhaXhvIG8gZ3JhZm8gY29tIGFzIHNlcXXDqm5jaWFzIG1haXMgY29tdW5zIG5hIHByaW1laXJhIGUgc2VndW5kYSDDqXBvY2EuCgpgYGB7ciBmaWcuaGVpZ2h0PTEwLCBmaWcud2lkdGg9MTAsIGVjaG89RkFMU0V9CnNldC5zZWVkKDIwMTYpCmEgPC0gZ3JpZDo6YXJyb3codHlwZSA9ICJjbG9zZWQiLCBsZW5ndGggPSB1bml0KC4xNSwgImluY2hlcyIpKQogIApiaWdyYW1zICU+JQogIGZpbHRlcihlcG9jaCA9PSBlcG9jaHNbMV0pICU+JQogIGNvdW50KHdvcmQxLCB3b3JkMiwgc29ydCA9IFRSVUUpICU+JQogIGZpbHRlcihuID4gMTApICU+JQogIGdyYXBoX2Zyb21fZGF0YV9mcmFtZSgpICU+JQogIGdncmFwaChsYXlvdXQgPSAiZnIiKSArCiAgZ2VvbV9lZGdlX2xpbmsoYWVzKGVkZ2VfYWxwaGEgPSBuKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSwgYXJyb3cgPSBhKSArCiAgZ2VvbV9ub2RlX3BvaW50KGNvbG9yID0gImxpZ2h0Ymx1ZSIsIHNpemUgPSA1KSArCiAgZ2VvbV9ub2RlX3RleHQoYWVzKGxhYmVsID0gbmFtZSksIHZqdXN0ID0gMSwgaGp1c3QgPSAxKSArCiAgdGhlbWVfdm9pZCgpCiAgCmJpZ3JhbXMgJT4lCiAgZmlsdGVyKGVwb2NoID09IGVwb2Noc1syXSkgJT4lCiAgY291bnQod29yZDEsIHdvcmQyLCBzb3J0ID0gVFJVRSkgJT4lCiAgZmlsdGVyKG4gPiAxMCkgJT4lCiAgZ3JhcGhfZnJvbV9kYXRhX2ZyYW1lKCkgJT4lCiAgZ2dyYXBoKGxheW91dCA9ICJmciIpICsKICBnZW9tX2VkZ2VfbGluayhhZXMoZWRnZV9hbHBoYSA9IG4pLCBzaG93LmxlZ2VuZCA9IEZBTFNFLCBhcnJvdyA9IGEpICsKICBnZW9tX25vZGVfcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIiwgc2l6ZSA9IDUpICsKICBnZW9tX25vZGVfdGV4dChhZXMobGFiZWwgPSBuYW1lKSwgdmp1c3QgPSAxLCBoanVzdCA9IDEpICsKICB0aGVtZV92b2lkKCkKYGBgCgojIyBNb2RlbG9zIGRlIHTDs3BpY28KCk1vZGVsb3MgZGUgdMOzcGljbyBzw6NvIGZyZXF1ZW50ZW1lbnRlIHV0aWxpemFkb3MgcGFyYSBlbmNvbnRyYXIgdMOzcGljb3MgZW1lcmdlbnRlcyBlbSB1bSBjb25qdW50byBkZSBkb2N1bWVudG9zLiBEZSBmb3JtYSBnZXJhbCwgdW0gbW9kZWxvIGRlIHTDs3BpY28gY29uc2lkZXJhIHF1ZToKCi0gQ2FkYSBkb2N1bWVudG8gw6kgY29tcG9zdG8gcG9yIHVtIGNvbmp1dG8gZGUgdMOzcGljb3M6IGNhZGEgZG9jdW1lbnRvIHBvc3N1aSB1bWEgcHJvYmFiaWxpZGFkZSBfZ2FtbWFfIGRlIHBlcnRlbmNlciBhIGNhZGEgdMOzcGljbzsKLSBDYWRhIHTDs3BpY28gw6kgY29tcG9zdG8gcG9yIHVtIGNvbmp1bnRvIGRlIHBhbGF2cmFzOiBjYWRhIHBhbGF2cmEgcG9zc3VpIHVtYSBwcm9iYWJpbGlkYWRlIF9iZXRhXyBkZSBwZXJ0ZW5jZXIgYSB1bSB0w7NwaWNvLgoKQ29tIGlzc28sIGRhZG8gbyBuw7ptZXJvIGRlIHTDs3BpY29zLCDDqSBwb3Nzw612ZWwgY29uc3RydWlyIG8gbW9kZWxvIGRlIHTDs3BpY28gcXVlIG1lbGhvciBzZSBlbmNhaXhhIGEgdW0gY29uanVudG8gZGUgZG9jdW1lbnRvcy4KCmBgYHtyIGNhY2hlPVRSVUUsIGVjaG89RkFMU0V9CmFic3RyYWN0X2R0bSA8LSBhYnN0cmFjdF90b2tlbnMgJT4lCiAgY291bnQoZG9pLCB3b3JkKSAlPiUKICBjYXN0X2R0bShkb2ksIHdvcmQsIG4pCgp0bV8yX2FsbCA8LSBMREEoYWJzdHJhY3RfZHRtLCBrID0gMiwgY29udHJvbCA9IGxpc3Qoc2VlZCA9IDEyMzQpKQp0bV8yX2FsbF9iZXRhIDwtIHRpZHkodG1fMl9hbGwsIG1hdHJpeCA9ICJiZXRhIikKdG1fMl9hbGxfZ2FtbWEgPC0gdGlkeSh0bV8yX2FsbCwgbWF0cml4ID0gImdhbW1hIikKYGBgCgojIyMgTW9kZWxvIGNvbSBkb2lzIHTDs3BpY29zIGNvbnNpZGVyYW5kbyBjYWRhIHJlc3VtbyBjb21vIHVtIGRvY3VtZW50bwoKQWJhaXhvIHPDo28gYXByZXNlbnRhZGFzIGFzIHBhbGF2cmFzIGNvbSBtYWlvcmVzIHByb2JhYmlsaWRhZGVzIChfYmV0YV8pIGRlIHBlcnRlbmNlciBhIGNhZGEgdMOzcGljby4gT2JzZXJ2YW1vcyBxdWUgbyBwcmltZWlybyB0w7NwaWNvIGVzdMOhIHJlbGFjaW9uYWRvIGNvbSBhcyBwYWxhdnJhcyBfc3VyZmFjZV8sIF9maWxtc18gZSBfc3BlY3Ryb3Njb3B5XywgZW5xdWFudG8gcXVlIG8gc2VndW5kbyBlc3TDoSByZWxhY2lvbmFkbyDDoCBfbW9kZWxfLCBfaGVhdF8gZSBfZmxvd18uCgpgYGB7ciBlY2hvPUZBTFNFfQpwbHQuZHQgPC0gdG1fMl9hbGxfYmV0YSAlPiUKICBncm91cF9ieSh0b3BpYykgJT4lCiAgdG9wX24oMTAsIGJldGEpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBhcnJhbmdlKHRvcGljLCAtYmV0YSkKCnBsdC5kdCAlPiUKICBtdXRhdGUodGVybSA9IHJlb3JkZXIodGVybSwgYmV0YSkpICU+JQogIGdncGxvdChhZXModGVybSwgYmV0YSwgZmlsbCA9IGZhY3Rvcih0b3BpYykpKSArCiAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGZhY2V0X3dyYXAofiB0b3BpYywgc2NhbGVzID0gImZyZWUiKSArCiAgY29vcmRfZmxpcCgpCmBgYAoKQWJhaXhvIHPDo28gYXByZXNlbnRhZG9zIG9zIHByaW5jaXBhaXMgcmVzdW1vcyBhc3NvY2lhZG9zIGEgY2FkYSB1bSBkb3MgdMOzcGljb3MsIGRlIGFjb3JkbyBjb20gYSBwcm9iYWJpbGlkYWRlIF9nYW1tYV8uCgpgYGB7ciBlY2hvPUZBTFNFfQpwbHQuZHQgPC0gdG1fMl9hbGxfZ2FtbWEgJT4lCiAgZ3JvdXBfYnkodG9waWMpICU+JQogIHRvcF9uKDUsIGdhbW1hKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgYXJyYW5nZSh0b3BpYywgLWdhbW1hKQoKcGx0LmR0ICU+JQogIG11dGF0ZShkb2N1bWVudCA9IHJlb3JkZXIoZG9jdW1lbnQsIGdhbW1hKSkgJT4lCiAgZ2dwbG90KGFlcyhkb2N1bWVudCwgZ2FtbWEsIGZpbGwgPSBmYWN0b3IodG9waWMpKSkgKwogIGdlb21fY29sKHNob3cubGVnZW5kID0gRkFMU0UpICsKICBmYWNldF93cmFwKH4gdG9waWMsIHNjYWxlcyA9ICJmcmVlIikgKwogIGNvb3JkX2ZsaXAoKQpgYGAKCiMjIyBNb2RlbG8gY29tIGRvaXMgdMOzcGljb3MgY29uc2lkZXJhbmRvIG8gY29uanVudG8gZGUgcmVzdW1vcyBlbSB1bSBhbm8gY29tbyBkb2N1bWVudG8KCkFiYWl4byBzw6NvIGFwcmVzZW50YWRvcyBhcyBwYWxhdnJhcyBhc3NvY2lhZGFzIGFvcyB0w7NwaWNvcyBhc3NvY2lhZG9zIMOgIGRpZmVyZW50ZXMgYW5vcy4gTyBwcmltZWlybyB0w7NwaWNvIHRyYXRhIGRlIF9zcGVjdHJvc2NvcHlfLCBfcmF5XyBlIF9maWxtc18sIGVucXVhbnRvIHF1ZSBvIHNlZ3VuZG8gdHJhdGEgZGUgX3N5c3RlbV8sIF9zdXJmYWNlXyBlIF90ZW1wZXJhdHVyZV8uCgpEaWZlcmVudGVtZW50ZSBkbyBtb2RlbG8gZGUgdMOzcGljbyBiYXNlYWRvIGVtIHJlc3Vtb3MsIG9zIHTDs3BpY29zIGJhc2VhZG9zIGVtIGFub3MgcG9zc3VlbSBiYXN0YW50ZSBpbnRlcnNlY8Onw6NvLiBJc3NvIHBvZGUgaW5kaWNhciBxdWUsIGFwZXNhciBkZSBleGlzdGlyZW0gYXJ0aWdvcyBxdWUgdHJhdGFtIGRlIGFzc3VudG9zIGRpZmVyZW50ZXMsIG9zIG1lc21vcyBhc3N1bnRvcyBzw6NvIHB1YmxpY2Fkb3MgYW8gbG9uZ28gZG8gcGVyw61vZG8uCgpgYGB7ciBjYWNoZT1UUlVFLCBlY2hvPUZBTFNFfQphYnN0cmFjdF9kdG1feWVhciA8LSBhYnN0cmFjdF90b2tlbnMgJT4lCiAgIyBmaWx0ZXIoeWVhciA+PSAyMDAwKSAlPiUKICBjb3VudCh5ZWFyLCB3b3JkKSAlPiUKICBjYXN0X2R0bSh5ZWFyLCB3b3JkLCBuKQoKdG1fMl9hbGxfeWVhciA8LSBMREEoYWJzdHJhY3RfZHRtX3llYXIsIGsgPSAyLCBjb250cm9sID0gbGlzdChzZWVkID0gMTIzNCkpCnRtXzJfYWxsX2JldGFfeWVhciA8LSB0aWR5KHRtXzJfYWxsX3llYXIsIG1hdHJpeCA9ICJiZXRhIikKdG1fMl9hbGxfZ2FtbWFfeWVhciA8LSB0aWR5KHRtXzJfYWxsX3llYXIsIG1hdHJpeCA9ICJnYW1tYSIpCmBgYAoKYGBge3IgZWNobz1GQUxTRX0KcGx0LmR0IDwtIHRtXzJfYWxsX2JldGFfeWVhciAlPiUKICBncm91cF9ieSh0b3BpYykgJT4lCiAgdG9wX24oNSwgYmV0YSkgJT4lCiAgdW5ncm91cCgpICU+JQogIGFycmFuZ2UodG9waWMsIC1iZXRhKQoKcGx0LmR0ICU+JQogIG11dGF0ZSh0ZXJtID0gcmVvcmRlcih0ZXJtLCBiZXRhKSkgJT4lCiAgZ2dwbG90KGFlcyh0ZXJtLCBiZXRhLCBmaWxsID0gZmFjdG9yKHRvcGljKSkpICsKICBnZW9tX2NvbChzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgZmFjZXRfd3JhcCh+IHRvcGljLCBzY2FsZXMgPSAiZnJlZSIpICsKICBjb29yZF9mbGlwKCkKYGBgCgpBYmFpeG8gbW9zdHJhbW9zIGNvbW8gY2FkYSBhbm8gcG9kZSBzZXIgcmVsYWNpb25hZG8gY29tIGNhZGEgdMOzcGljbyAoX2dhbW1hXykuIE9zIHByaW5jaXBhaXMgYW5vcyBkZSBjYWRhIHTDs3BpY28gc8OjbyAyMDE0IGUgMjAwOCwgZW50cmV0YW5kbyBuw6NvIGjDoSB1bWEgZGl2aXPDo28gY2xhcmEgZGUgw6lwb2Nhcy4KCmBgYHtyIGVjaG89RkFMU0V9CnBsdC5kdCA8LSB0bV8yX2FsbF9nYW1tYV95ZWFyICU+JQogIGdyb3VwX2J5KHRvcGljKSAlPiUKICB0b3BfbigxMCwgZ2FtbWEpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBhcnJhbmdlKHRvcGljLCAtZ2FtbWEpCgpwbHQuZHQgJT4lCiAgbXV0YXRlKGRvY3VtZW50ID0gcmVvcmRlcihkb2N1bWVudCwgZ2FtbWEpKSAlPiUKICBnZ3Bsb3QoYWVzKGRvY3VtZW50LCBnYW1tYSwgZmlsbCA9IGZhY3Rvcih0b3BpYykpKSArCiAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGZhY2V0X3dyYXAofiB0b3BpYywgc2NhbGVzID0gImZyZWUiKSArCiAgY29vcmRfZmxpcCgpCmBgYAoKIyMjIE1vZGVsbyBkZSBkb2lzIHTDs3BpY29zIGNvbnNpZGVyYW5kbyBjYWRhIMOpcG9jYSBjb21vIHVtIGRvY3VtZW50bwoKQ29uc2lkZXJhbmRvIHBhbGF2cmFzIGVtIHJlc3Vtb3MgZGEgbWVzbWEgw6lwb2NhIGNvbW8gcGVydGVuY2VuZG8gYW8gbWVzbW8gZG9jdW1lbnRvcywgb2J0ZW1vcyB0w7NwaWNvcyBvbmRlIGFzIHBhbGF2cmFzIG1haXMgc2lnbmlmaWNhbnRlcyAoX2JldGFfKSBzw6NvIG1vc3RyYWRhcyBuYSBmaWd1cmEuIEFzIHByaW5jaXBhaXMgcGFsYXZyYXMgc8OjbyBfc3BlY3Ryb3Njb3B5XyBlIF90ZW1wZXJhdHVyZV8gcGFyYSBvIHByaW1laXJvIHTDs3BpY28gZSBfZmlsbXNfIGUgX3N1ZmFjZV8gcGFyYSBvIHNlZ3VuZG8gdMOzcGljby4KCmBgYHtyIGNhY2hlPVRSVUUsIGVjaG89RkFMU0V9CmFic3RyYWN0X2R0bV9lcG9jaCA8LSBhYnN0cmFjdF90b2tlbnMgJT4lCiAgY291bnQoZXBvY2gsIHdvcmQpICU+JQogIGNhc3RfZHRtKGVwb2NoLCB3b3JkLCBuKQoKdG1fMl9hbGxfZXBvY2ggPC0gTERBKGFic3RyYWN0X2R0bV9lcG9jaCwgayA9IDIsIGNvbnRyb2wgPSBsaXN0KHNlZWQgPSAxMjM0KSkKdG1fMl9hbGxfYmV0YV9lcG9jaCA8LSB0aWR5KHRtXzJfYWxsX2Vwb2NoLCBtYXRyaXggPSAiYmV0YSIpCnRtXzJfYWxsX2dhbW1hX2Vwb2NoIDwtIHRpZHkodG1fMl9hbGxfZXBvY2gsIG1hdHJpeCA9ICJnYW1tYSIpCmBgYAoKYGBge3IgZWNobz1GQUxTRX0KcGx0LmR0IDwtIHRtXzJfYWxsX2JldGFfZXBvY2ggJT4lCiAgZ3JvdXBfYnkodG9waWMpICU+JQogIHRvcF9uKDUsIGJldGEpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBhcnJhbmdlKHRvcGljLCAtYmV0YSkKCnBsdC5kdCAlPiUKICBtdXRhdGUodGVybSA9IHJlb3JkZXIodGVybSwgYmV0YSkpICU+JQogIGdncGxvdChhZXModGVybSwgYmV0YSwgZmlsbCA9IGZhY3Rvcih0b3BpYykpKSArCiAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGZhY2V0X3dyYXAofiB0b3BpYywgc2NhbGVzID0gImZyZWUiKSArCiAgY29vcmRfZmxpcCgpCmBgYAoKQSBmaWd1cmEgYWJhaXhvIG1vc3RyYSBhIHBlcnRpbsOqbmNpYSBkZSBjYWRhIMOpcG9jYSBlbSBjYWRhIHTDs3BpY28gKF9nYW1tYV8pLiBPYnNlcnZhbW9zIHF1ZSBhcyDDqXBvY2FzIHPDo28gYmFzdGFudGUgc2ltaWxhcmVzIGVtIHJlbGHDp8OjbyBhb3MgdMOzcGljb3MgbW9kZWxhZG9zLiBVbWEgcGVxdWVuYSBkaWZlcmVuw6dhIG1vc3RyYSBxdWUgYSDDqXBvY2EgYDw9IDIwMTBgIGVzdMOhIG1haXMgcmVsYWNpb25hZGEgYW8gdMOzcGljbyAxIChfc3BlY3Ryb3Njb3B5XyBlIF90ZW1wZXJhdHVyZV8pIGUgYSDDqXBvY2EgYD49IDIwMTFgIGFvIHTDs3BpY28gMiAoX2ZpbG1zXyBlIF9zdWZhY2VfKS4KCmBgYHtyIGVjaG89RkFMU0V9CnBsdC5kdCA8LSB0bV8yX2FsbF9nYW1tYV9lcG9jaCAlPiUKICBncm91cF9ieSh0b3BpYykgJT4lCiAgdG9wX24oMTAsIGdhbW1hKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgYXJyYW5nZSh0b3BpYywgLWdhbW1hKQoKcGx0LmR0ICU+JQogIG11dGF0ZShkb2N1bWVudCA9IHJlb3JkZXIoZG9jdW1lbnQsIGdhbW1hKSkgJT4lCiAgZ2dwbG90KGFlcyhkb2N1bWVudCwgZ2FtbWEsIGZpbGwgPSBmYWN0b3IodG9waWMpKSkgKwogIGdlb21fY29sKHNob3cubGVnZW5kID0gRkFMU0UpICsKICBmYWNldF93cmFwKH4gdG9waWMsIHNjYWxlcyA9ICJmcmVlIikgKwogIGNvb3JkX2ZsaXAoKQpgYGAKCgoKIyBDb250YWdlbnMgZGUgcGFsYXZyYXMtY2hhdmUKCiMjIFBhbGF2cmFzLWNoYXZlIG1haXMgY29tdW5zIGVtIHRvZGFzIGFzIHB1YmxpY2HDp8O1ZXMKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQprZXl3b3JkcyAlPiUKICBjb3VudChrZXl3b3Jkcywgc29ydCA9IFRSVUUpICU+JQogIHRvcF9uKDIwLCB3dCA9IG4pICU+JQogIG11dGF0ZShrZXl3b3JkcyA9IHJlb3JkZXIoa2V5d29yZHMsIG4pKSAlPiUKICBnZ3Bsb3QoYWVzKGtleXdvcmRzLCBuLCBmaWxsPW4pKSArCiAgZ2VvbV9jb2woKSArCiAgeGxhYihOVUxMKSArCiAgY29vcmRfZmxpcCgpCmBgYAoKCiMjIFBhbGF2cmFzLWNoYXZlIG1haXMgY29tdW5zIHBvciDDqXBvY2EKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpwbHQuZHQgPC0ga2V5d29yZHMgJT4lCiAgZ3JvdXBfYnkoZXBvY2gpICU+JQogIHJlbmFtZShrZXl3b3JkID0ga2V5d29yZHMpICU+JQogIGNvdW50KGtleXdvcmQpICU+JQogIHRvcF9uKDIwLCB3dCA9IG4pICU+JQogIHVuZ3JvdXAoKSAlPiUKICBhcnJhbmdlKGVwb2NoLCBuKSAlPiUKICBtdXRhdGUob3JkZXIgPSByb3dfbnVtYmVyKCkpCgpwbHQuZHQgJT4lICAKICBnZ3Bsb3QoYWVzKG9yZGVyLCBuLCBmaWxsID0gZXBvY2gpKSArCiAgZ2VvbV9jb2woKSArCiAgZmFjZXRfd3JhcCh+ZXBvY2gsIHNjYWxlcyA9ICJmcmVlIikgKwogIHNjYWxlX3hfY29udGludW91cygKICAgIGJyZWFrcyA9IHBsdC5kdCRvcmRlciwKICAgIGxhYmVscyA9IHBsdC5kdCRrZXl3b3JkLAogICAgZXhwYW5kID0gYygwLDApCiAgKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgY29vcmRfZmxpcCgpCmBgYAoKCiMjIFBhbGF2cmFzLWNoYXZlIG1haXMgY29tdW5zIHBvciBncnVwbyBOYW5vIGUgTsOjby1OYW5vCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KcGx0LmR0IDwtIGtleXdvcmRzICU+JQogIG11dGF0ZSgKICAgIG5hbm8gPSBjYXNlX3doZW4obmFubyB+ICJOYW5vIiwgVFJVRSB+ICJOw6NvLU5hbm8iKQogICkgJT4lCiAgZ3JvdXBfYnkobmFubykgJT4lCiAgcmVuYW1lKGtleXdvcmQgPSBrZXl3b3JkcykgJT4lCiAgY291bnQoa2V5d29yZCkgJT4lCiAgdG9wX24oMjAsIHd0ID0gbikgJT4lCiAgdW5ncm91cCgpICU+JQogIGFycmFuZ2UobmFubywgbikgJT4lCiAgbXV0YXRlKG9yZGVyID0gcm93X251bWJlcigpKQoKcGx0LmR0ICU+JSAgCiAgZ2dwbG90KGFlcyhvcmRlciwgbiwgZmlsbCA9IG5hbm8pKSArCiAgZ2VvbV9jb2woKSArCiAgZmFjZXRfd3JhcCh+bmFubywgc2NhbGVzID0gImZyZWUiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKAogICAgYnJlYWtzID0gcGx0LmR0JG9yZGVyLAogICAgbGFiZWxzID0gcGx0LmR0JGtleXdvcmQsCiAgICBleHBhbmQgPSBjKDAsMCkKICApICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICBjb29yZF9mbGlwKCkKYGBgCgoKIyMgUGFsYXZyYXMtY2hhdmUgbWFpcyBjb211bnMgcG9yIGdydXBvIE5hbm8gZSBOw6NvLU5hbm8gZSDDiXBvY2EKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpwbHQuZHQgPC0ga2V5d29yZHMgJT4lCiAgbXV0YXRlKAogICAgbmFubyA9IGNhc2Vfd2hlbihuYW5vIH4gIk5hbm8iLCBUUlVFIH4gIk7Do28tTmFubyIpCiAgKSAlPiUKICBncm91cF9ieShuYW5vLCBlcG9jaCkgJT4lCiAgcmVuYW1lKGtleXdvcmQgPSBrZXl3b3JkcykgJT4lCiAgY291bnQoa2V5d29yZCkgJT4lCiAgdG9wX24oOCwgd3QgPSBuKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgYXJyYW5nZShuYW5vLCBlcG9jaCwgbikgJT4lCiAgbXV0YXRlKG9yZGVyID0gcm93X251bWJlcigpKQoKcGx0LmR0ICU+JSAgCiAgZ2dwbG90KGFlcyhvcmRlciwgbiwgZmlsbCA9IG5hbm8pKSArCiAgZ2VvbV9jb2woKSArCiAgZmFjZXRfd3JhcChuYW5vIH4gZXBvY2gsIHNjYWxlcyA9ICJmcmVlIikgKwogIHNjYWxlX3hfY29udGludW91cygKICAgIGJyZWFrcyA9IHBsdC5kdCRvcmRlciwKICAgIGxhYmVscyA9IHBsdC5kdCRrZXl3b3JkLAogICAgZXhwYW5kID0gYygwLDApCiAgKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgY29vcmRfZmxpcCgpCmBgYAoKCiMgUmVkZXMgZGUgcGFsYXZyYXMtY2hhdmUgYWdydXBhZGFzIHBvciBwdWJsaWNhw6fDo28KCi0gQ2FkYSBuw7MgcmVwcmVzZW50YSB1bWEgcGFsYXZyYSBjaGF2ZTsKLSBBIGZvcsOnYSBkZSB1bWEgY29uZXjDo28gw6kgcHJvcG9yY2lvbmFsIGFvIG7Dum1lcm8gZGUgcHVibGljYcOnw7VlcyAobikgZW0gcXVlIGR1YXMgcGFsYXZyYXMgY2hhdmVzIGFwYXJlY2VtIGp1bnRhcy4KCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpncmFmb1BhbGF2cmFzQ2hhdmVzIDwtIGZ1bmN0aW9uKGR0LCBtYXhuID0gNCkgewogIHNldC5zZWVkKDEyMzQpCiAgZHQgJT4lCiAgICBwYWlyd2lzZV9jb3VudChrZXl3b3JkLCBpZCkgJT4lCiAgICBmaWx0ZXIobiA+PSBtYXhuKSAlPiUKICAgIGdyYXBoX2Zyb21fZGF0YV9mcmFtZSgpICU+JQogICAgZ2dyYXBoKGxheW91dCA9ICJmciIpICsKICAgIGdlb21fZWRnZV9saW5rKGFlcyhlZGdlX2FscGhhID0gbiwgZWRnZV93aWR0aCA9IG4pLCAKICAgICAgICAgICAgICAgICAgIGVkZ2VfY29sb3VyID0gInJveWFsYmx1ZSIpICsKICAgIGdlb21fbm9kZV9wb2ludChzaXplID0gMikgKwogICAgZ2VvbV9ub2RlX3RleHQoYWVzKGxhYmVsID0gbmFtZSksIHJlcGVsID0gVFJVRSwKICAgICAgICAgICAgICAgICAgIHBvaW50LnBhZGRpbmcgPSB1bml0KDAuMiwgImxpbmVzIikpICsKICAgIHRoZW1lX3ZvaWQoKQp9CmBgYAoKIyMgVG9kYXMgYXMgcHVibGljYcOnw7VlcwoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmtleXdvcmRzICU+JQogIHNlbGVjdCgKICAgIGlkID0gZG9pLAogICAga2V5d29yZCA9IGtleXdvcmRzCiAgKSAlPiUKICBncmFmb1BhbGF2cmFzQ2hhdmVzKDYpCmBgYAoKIyMjIFB1YmxpY2HDp8O1ZXMgTsOjby1OYW5vCgpgYGB7ciAsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CnNldC5zZWVkKDEyMzQpCmtleXdvcmRzICU+JQogIGZpbHRlcighbmFubykgJT4lCiAgc2VsZWN0KAogICAgaWQgPSBkb2ksCiAgICBrZXl3b3JkID0ga2V5d29yZHMKICApICU+JQogIGdyYWZvUGFsYXZyYXNDaGF2ZXMoKQpgYGAKCgoKIyMjIyBQdWJsaWNhw6fDtWVzIE7Do28tTmFubyDDiXBvY2EgPD0gMjAxMAoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmtleXdvcmRzICU+JQogIGZpbHRlcighbmFubywgZXBvY2ggPT0gJzw9MjAxMCcpICU+JQogIHNlbGVjdCgKICAgIGlkID0gZG9pLAogICAga2V5d29yZCA9IGtleXdvcmRzCiAgKSAlPiUKICBncmFmb1BhbGF2cmFzQ2hhdmVzKCkKYGBgCgojIyMjIFB1YmxpY2HDp8O1ZXMgTsOjby1OYW5vIMOJcG9jYSA+PSAyMDExCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0Ka2V5d29yZHMgJT4lCiAgZmlsdGVyKCFuYW5vLCBlcG9jaCA9PSAnPj0yMDExJykgJT4lCiAgc2VsZWN0KAogICAgaWQgPSBkb2ksCiAgICBrZXl3b3JkID0ga2V5d29yZHMKICApICU+JQogIGdyYWZvUGFsYXZyYXNDaGF2ZXMoKQpgYGAKCiMjIyBQdWJsaWNhw6fDtWVzIE5hbm8KCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQprZXl3b3JkcyAlPiUKICBmaWx0ZXIobmFubykgJT4lCiAgc2VsZWN0KAogICAgaWQgPSBkb2ksCiAgICBrZXl3b3JkID0ga2V5d29yZHMKICApICU+JQogIGdyYWZvUGFsYXZyYXNDaGF2ZXMoKQpgYGAKCgoKIyMjIyBQdWJsaWNhw6fDtWVzIE5hbm8gZGEgw4lwb2NhIDw9MjAxMAoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmtleXdvcmRzICU+JQogIGZpbHRlcihuYW5vLCBlcG9jaCA9PSAnPD0yMDEwJykgJT4lCiAgc2VsZWN0KAogICAgaWQgPSBkb2ksCiAgICBrZXl3b3JkID0ga2V5d29yZHMKICApICU+JQogIGdyYWZvUGFsYXZyYXNDaGF2ZXMoMykKYGBgCgojIyMjIFB1YmxpY2HDp8O1ZXMgTmFubyBkYSDDiXBvY2EgPj0yMDExCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0Ka2V5d29yZHMgJT4lCiAgZmlsdGVyKG5hbm8sIGVwb2NoID09ICc+PTIwMTEnKSAlPiUKICBzZWxlY3QoCiAgICBpZCA9IGRvaSwKICAgIGtleXdvcmQgPSBrZXl3b3JkcwogICkgJT4lCiAgZ3JhZm9QYWxhdnJhc0NoYXZlcygpCmBgYAoKCiMgR3JhZm9zIGRlIHBhbGF2cmFzIGNoYXZlcyBhZ3J1cGFkb3MgcG9yIMOpcG9jYQoKLSBPIHBlc28gY2FkYSBjb25leMOjbyDDqSBwcm9wb3JjaW9uYWwgYW8gbsO6bWVybyBkZSB2ZXplcyBlbSBxdWUgdW0gcGFyIGRlIHBhbGF2cmFzIGFwYXJlY2Ugbm8gbWVzbW8gYW5vCgojIyBQYWxhdnJhcyBkZSBwdWJsaWNhw6fDtWVzIE5hbm8gZSBOw6NvLU5hbm8KCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQprZXl3b3JkcyAlPiUKICBzZWxlY3QoCiAgICBpZCA9IHllYXIsCiAgICBrZXl3b3JkID0ga2V5d29yZHMKICApICU+JQogICAgZ3JhZm9QYWxhdnJhc0NoYXZlcyhtYXhuID0gNykKYGBgCgojIyBQYWxhdnJhcyBkZSBwdWJsaWNhw6fDtWVzIE5hbm8KCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQprZXl3b3JkcyAlPiUKICBmaWx0ZXIobmFubykgJT4lCiAgc2VsZWN0KAogICAgaWQgPSB5ZWFyLAogICAga2V5d29yZCA9IGtleXdvcmRzCiAgKSAlPiUKICAgIGdyYWZvUGFsYXZyYXNDaGF2ZXMobWF4biA9IDcpCmBgYAoKIyMgUGFsYXZyYXMgZGUgcHVibGljYcOnw7VlcyBOw6NvLU5hbm8KCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQprZXl3b3JkcyAlPiUKICBmaWx0ZXIoIW5hbm8pICU+JQogIHNlbGVjdCgKICAgIGlkID0geWVhciwKICAgIGtleXdvcmQgPSBrZXl3b3JkcwogICkgJT4lCiAgICBncmFmb1BhbGF2cmFzQ2hhdmVzKG1heG4gPSA3KQpgYGAKCiMjIFBhbGF2cmFzIGRlIHB1YmxpY2HDp8O1ZXMgTmFubwoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmtleXdvcmRzICU+JQogIGZpbHRlcihuYW5vKSAlPiUKICBzZWxlY3QoCiAgICBpZCA9IHllYXIsCiAgICBrZXl3b3JkID0ga2V5d29yZHMKICApICU+JQogICAgZ3JhZm9QYWxhdnJhc0NoYXZlcyhtYXhuID0gNykKYGBgCgoKIyBSZWRlcyBkZSBjb2xhYm9yYcOnw6NvCgotIEEgZm9yw6dhIGRlIHVtYSBjb25leOG6vW8gw6kgcHJvcG9yY2lvbmFsIGFvIG7Dum1lcm8gZGUgdmV6ZXMgcXVlIHVtIGF1dG9yIGFwYXJlY2UgZW0gY29uanVudG8gY29tIG91dHJvIG5hIG1lc21hIHB1YmxpY2HDp8Ojby4KCiMjIFRvZGFzIGFzIHB1YmxpY2HDp8O1ZXMKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQphdXRob3JzX25ldCAlPiUKICBzZWxlY3QoCiAgICBpZCA9IGRvaSwKICAgIGtleXdvcmQgPSBhdXRob3JzCiAgKSAlPiUKICAgIGdyYWZvUGFsYXZyYXNDaGF2ZXMobWF4biA9IDEwKQpgYGAKCgojIyMgUHVibGljYcOnw7VlcyBOw6NvLU5hbm8KCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQphdXRob3JzX25ldCAlPiUKICBmaWx0ZXIoIW5hbm8pICU+JQogIHNlbGVjdCgKICAgIGlkID0gZG9pLAogICAga2V5d29yZCA9IGF1dGhvcnMKICApICU+JQogICAgZ3JhZm9QYWxhdnJhc0NoYXZlcyhtYXhuID0gMTApCmBgYAoKIyMjIyBQdWJsaWNhw6fDtWVzIE7Do28tTmFubyDDiXBvY2EgPD0yMDEwCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KYXV0aG9yc19uZXQgJT4lCiAgZmlsdGVyKCFuYW5vLCBlcG9jaCA9PSAnPD0yMDEwJykgJT4lCiAgc2VsZWN0KAogICAgaWQgPSBkb2ksCiAgICBrZXl3b3JkID0gYXV0aG9ycwogICkgJT4lCiAgICBncmFmb1BhbGF2cmFzQ2hhdmVzKG1heG4gPSA3KQpgYGAKCiMjIyMgUHVibGljYcOnw7VlcyBOw6NvLU5hbm8gw4lwb2NhID49MjAxMQoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmF1dGhvcnNfbmV0ICU+JQogIGZpbHRlcighbmFubywgZXBvY2ggPT0gJz49MjAxMScpICU+JQogIHNlbGVjdCgKICAgIGlkID0gZG9pLAogICAga2V5d29yZCA9IGF1dGhvcnMKICApICU+JQogICAgZ3JhZm9QYWxhdnJhc0NoYXZlcyhtYXhuID0gNykKYGBgCgojIyMgUHVibGljYcOnw7VlcyBOYW5vCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KYXV0aG9yc19uZXQgJT4lCiAgZmlsdGVyKG5hbm8pICU+JQogIHNlbGVjdCgKICAgIGlkID0gZG9pLAogICAga2V5d29yZCA9IGF1dGhvcnMKICApICU+JQogICAgZ3JhZm9QYWxhdnJhc0NoYXZlcyhtYXhuID0gNykKYGBgCgojIyMgUHVibGljYcOnw7VlcyBOYW5vIMOJcG9jYSA8PTIwMTAKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQphdXRob3JzX25ldCAlPiUKICBmaWx0ZXIobmFubywgZXBvY2ggPT0gJzw9MjAxMCcpICU+JQogIHNlbGVjdCgKICAgIGlkID0gZG9pLAogICAga2V5d29yZCA9IGF1dGhvcnMKICApICU+JQogICAgZ3JhZm9QYWxhdnJhc0NoYXZlcyhtYXhuID0gNykKYGBgCgojIyMgUHVibGljYcOnw7VlcyBOYW5vIMOJcG9jYSA+PTIwMTEKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQphdXRob3JzX25ldCAlPiUKICBmaWx0ZXIobmFubywgZXBvY2ggPT0gJz49MjAxMScpICU+JQogIHNlbGVjdCgKICAgIGlkID0gZG9pLAogICAga2V5d29yZCA9IGF1dGhvcnMKICApICU+JQogICAgZ3JhZm9QYWxhdnJhc0NoYXZlcyhtYXhuID0gNSkKYGBg